diff --git a/lnet/archdep.m4 b/lnet/archdep.m4
index 1a7741bc3a1584c3165d2fd184d309ed3942c8b1..6171555571d89ddbc90206bab5c6047c86747a86 100644
--- a/lnet/archdep.m4
+++ b/lnet/archdep.m4
@@ -225,7 +225,8 @@ fi
 #AC_SUBST(usrprefix)
 
 AC_MSG_CHECKING(if kernel has CPU affinity support)
-if test "$target_cpu" != ia64 ; then
+SET_CPUS_ALLOW="`grep -c set_cpus_allowed $LINUX/kernel/softirq.c`"
+if test "$SET_CPUS_ALLOW" != 0 ; then
   enable_affinity_temp="-DCPU_AFFINITY=1"
   AC_MSG_RESULT(yes)
 else
@@ -285,7 +286,7 @@ if test "${with_gm+set}" = set; then
   if test "${with_gm}" = yes; then
     with_gm="-I/usr/local/gm/include"
   else
-    with_gm=-I"$with_gm/include"
+    with_gm="-I$with_gm/include -I$with_gm/drivers -I$with_gm/drivers/linux/gm"
   fi
   GMNAL="gmnal"
 else
@@ -296,6 +297,28 @@ AC_SUBST(with_gm)
 AC_SUBST(GMNAL)
 
 
+#fixme: where are the default IB includes?
+default_ib_include_dir=/usr/local/ib/include
+an_ib_include_file=vapi.h
+
+AC_ARG_WITH(ib, [ --with-ib=[yes/no/path] Path to IB includes], with_ib=$withval, with_ib=$default_ib)
+AC_MSG_CHECKING(if IB headers are present)
+if test "$with_ib" = yes; then
+    with_ib=$default_ib_include_dir
+fi
+if test "$with_ib" != no -a -f ${with_ib}/${an_ib_include_file}; then
+    AC_MSG_RESULT(yes)
+    IBNAL="ibnal"
+    with_ib="-I${with_ib}"
+else
+    AC_MSG_RESULT(no)
+    IBNAL=""
+    with_ib=""
+fi
+AC_SUBST(IBNAL)
+AC_SUBST(with_ib)
+
+
 def_scamac=/opt/scali/include
 AC_ARG_WITH(scamac, [  --with-scamac=[yes/no/path] Path to ScaMAC includes (default=/opt/scali/include)], with_scamac=$withval, with_scamac=$def_scamac)
 AC_MSG_CHECKING(if ScaMAC headers are present)
@@ -316,7 +339,7 @@ AC_SUBST(with_scamac)
 AC_SUBST(SCIMACNAL)
 
 CFLAGS="$KCFLAGS"
-CPPFLAGS="$KINCFLAGS $KCPPFLAGS $MFLAGS $enable_zerocopy $enable_affinity $with_quadrics $with_gm $with_scamac "
+CPPFLAGS="$KINCFLAGS $KCPPFLAGS $MFLAGS $enable_zerocopy $enable_affinity $with_quadrics $with_gm $with_scamac $with_ib"
 
 AC_SUBST(MOD_LINK)
 AC_SUBST(LINUX25)
diff --git a/lnet/build.m4 b/lnet/build.m4
index 025f243840d8e9ce9e33989f9b579e2a957282ff..8c55b20c130f948e09ee11aabf6e224cb3ec5884 100644
--- a/lnet/build.m4
+++ b/lnet/build.m4
@@ -16,6 +16,9 @@ bindir='${exec_prefix}/usr/bin'
 sbindir='${exec_prefix}/usr/sbin'
 includedir='${prefix}/usr/include'
 
+rootsbindir='${exec_prefix}/sbin'
+AC_SUBST(rootsbindir)
+
 # Directories for documentation and demos.
 docdir='${prefix}/usr/share/doc/$(PACKAGE)'
 AC_SUBST(docdir)
diff --git a/lnet/configure.in b/lnet/configure.in
index 31d349245706b4d38038926f68b0b2d9f13eea9d..44657e06171c788b8d3009c7d0586ea6f19ddc62 100644
--- a/lnet/configure.in
+++ b/lnet/configure.in
@@ -29,6 +29,6 @@ AM_CONFIG_HEADER(include/config.h)
 AC_OUTPUT([Makefile Kernelenv libcfs/Makefile portals/Makefile \
           unals/Makefile knals/Makefile router/Makefile \
 	  knals/socknal/Makefile knals/gmnal/Makefile knals/qswnal/Makefile \
-	  knals/scimacnal/Makefile knals/toenal/Makefile \
+	  knals/scimacnal/Makefile knals/toenal/Makefile knals/ibnal/Makefile\
           utils/Makefile tests/Makefile doc/Makefile ])
 
diff --git a/lnet/include/cygwin-ioctl.h b/lnet/include/cygwin-ioctl.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ecefff056314df652356c33465ee31df502119a
--- /dev/null
+++ b/lnet/include/cygwin-ioctl.h
@@ -0,0 +1,82 @@
+/* $Id: cygwin-ioctl.h,v 1.2 2003/12/03 03:14:43 phil Exp $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASMI386_IOCTL_H
+#define _ASMI386_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#undef _IO
+#undef _IOR
+#undef _IOW
+#undef _IOC
+#undef IOC_IN
+#undef IOC_OUT
+
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASMI386_IOCTL_H */
diff --git a/lnet/include/linux/kp30.h b/lnet/include/linux/kp30.h
index 0a1cc57a78b4e8bec72c552a828ae9583d294ad9..3e6d5e31704c8dd6ba68f7bdf73e15230a5e079c 100644
--- a/lnet/include/linux/kp30.h
+++ b/lnet/include/linux/kp30.h
@@ -19,6 +19,7 @@ extern unsigned int portal_subsystem_debug;
 extern unsigned int portal_stack;
 extern unsigned int portal_debug;
 extern unsigned int portal_printk;
+extern unsigned int portal_cerror;
 /* Debugging subsystems (32 bits, non-overlapping) */
 #define S_UNDEFINED    (1 << 0)
 #define S_MDC          (1 << 1)
@@ -42,6 +43,7 @@ extern unsigned int portal_printk;
 #define S_GMNAL       (1 << 19)
 #define S_PTLROUTER   (1 << 20)
 #define S_COBD        (1 << 21)
+#define S_IBNAL       (1 << 22)
 
 /* If you change these values, please keep portals/utils/debug.c
  * up to date! */
@@ -57,7 +59,7 @@ extern unsigned int portal_printk;
 #define D_IOCTL     (1 << 7) /* ioctl related information */
 #define D_BLOCKS    (1 << 8) /* ext2 block allocation */
 #define D_NET       (1 << 9) /* network communications */
-#define D_WARNING   (1 << 10)
+#define D_WARNING   (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
 #define D_BUFFS     (1 << 11)
 #define D_OTHER     (1 << 12)
 #define D_DENTRY    (1 << 13)
@@ -72,10 +74,14 @@ extern unsigned int portal_printk;
 
 #ifdef __KERNEL__
 # include <linux/sched.h> /* THREAD_SIZE */
-#else
-# define THREAD_SIZE 8192
+#else 
+# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */
+#  define THREAD_SIZE 8192
+# endif
 #endif
 
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
 #ifdef __KERNEL__
 # ifdef  __ia64__
 #  define CDEBUG_STACK (THREAD_SIZE -                                      \
@@ -106,6 +112,8 @@ extern unsigned int portal_printk;
 #if 1
 #define CDEBUG(mask, format, a...)                                            \
 do {                                                                          \
+        if (portal_cerror == 0)                                               \
+                break;                                                        \
         CHECK_STACK(CDEBUG_STACK);                                            \
         if (!(mask) || ((mask) & (D_ERROR | D_EMERG)) ||                      \
             (portal_debug & (mask) &&                                         \
@@ -185,6 +193,7 @@ static inline void our_cond_resched(void)
         if (current->need_resched)
                schedule ();
 }
+#define work_struct_t       struct tq_struct 
 
 #else
 
@@ -200,6 +209,8 @@ static inline void our_cond_resched(void)
 {
         cond_resched();
 }
+#define work_struct_t      struct work_struct
+
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
 
 #ifdef PORTAL_DEBUG
@@ -207,8 +218,22 @@ extern void kportal_assertion_failed(char *expr, char *file, const char *func,
                                      const int line);
 #define LASSERT(e) ((e) ? 0 : kportal_assertion_failed( #e , __FILE__,  \
                                                         __FUNCTION__, __LINE__))
+/* it would be great to dump_stack() here, but some kernels
+ * export it as show_stack() and I can't be bothered to
+ * proprely engage in that dance right now */ 
+#define LASSERTF(cond, fmt...)                                                \
+        do {                                                                  \
+                if (unlikely(!(cond))) {                                      \
+                        portals_debug_msg(0, D_EMERG,  __FILE__, __FUNCTION__,\
+                                          __LINE__,  CDEBUG_STACK,            \
+                                          "ASSERTION(" #cond ") failed:" fmt);\
+                        LBUG();                                               \
+                }                                                             \
+        } while (0)
+                                
 #else
 #define LASSERT(e)
+#define LASSERTF(cond, fmt...) do { } while (0)
 #endif
 
 #ifdef __arch_um__
@@ -254,13 +279,17 @@ do {                                                                          \
 
 #define PORTAL_VMALLOC_SIZE        16384
 
+#ifndef GFP_MEMALLOC
+#define GFP_MEMALLOC 0
+#endif
+
 #define PORTAL_ALLOC(ptr, size)                                           \
 do {                                                                      \
         LASSERT (!in_interrupt());                                        \
         if ((size) > PORTAL_VMALLOC_SIZE)                                 \
                 (ptr) = vmalloc(size);                                    \
         else                                                              \
-                (ptr) = kmalloc((size), GFP_NOFS);                        \
+                (ptr) = kmalloc((size), (GFP_KERNEL | GFP_MEMALLOC));     \
         if ((ptr) == NULL)                                                \
                 CERROR("PORTALS: out of memory at %s:%d (tried to alloc '"\
                        #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));\
@@ -289,10 +318,14 @@ do {                                                                    \
                s, (ptr), atomic_read(&portal_kmemory));                 \
 } while (0)
 
+#ifndef SLAB_MEMALLOC
+#define SLAB_MEMALLOC 0
+#endif
+
 #define PORTAL_SLAB_ALLOC(ptr, slab, size)                                \
 do {                                                                      \
         LASSERT(!in_interrupt());                                         \
-        (ptr) = kmem_cache_alloc((slab), SLAB_KERNEL);                    \
+        (ptr) = kmem_cache_alloc((slab), (SLAB_KERNEL | SLAB_MEMALLOC));  \
         if ((ptr) == NULL) {                                              \
                 CERROR("PORTALS: out of memory at %s:%d (tried to alloc"  \
                        " '" #ptr "' from slab '" #slab "')\n", __FILE__,  \
@@ -575,6 +608,9 @@ extern struct prof_ent prof_ents[MAX_PROFS];
 #endif /* PORTALS_PROFILING */
 
 /* debug.c */
+extern spinlock_t stack_backtrace_lock;
+
+char *portals_debug_dumpstack(void);
 void portals_run_upcall(char **argv);
 void portals_run_lbug_upcall(char * file, const char *fn, const int line);
 void portals_debug_dumplog(void);
@@ -596,7 +632,7 @@ __s32 portals_debug_copy_to_user(char *buf, unsigned long len);
 #endif
 void portals_debug_msg(int subsys, int mask, char *file, const char *fn,
                        const int line, unsigned long stack,
-                       const char *format, ...)
+                       char *format, ...)
         __attribute__ ((format (printf, 7, 8)));
 #else
 void portals_debug_msg(int subsys, int mask, char *file, const char *fn,
@@ -617,6 +653,8 @@ extern void kportal_blockallsigs (void);
 # include <stdlib.h>
 #ifndef __CYGWIN__
 # include <stdint.h>
+#else
+# include <cygwin-ioctl.h>
 #endif
 # include <unistd.h>
 # include <time.h>
@@ -628,8 +666,10 @@ extern void kportal_blockallsigs (void);
 #  undef NDEBUG
 #  include <assert.h>
 #  define LASSERT(e)     assert(e)
+#  define LASSERTF(cond, args...)     assert(cond)
 # else
 #  define LASSERT(e)
+#  define LASSERTF(cond, args...) do { } while (0)
 # endif
 # define printk(format, args...) printf (format, ## args)
 # define PORTAL_ALLOC(ptr, size) do { (ptr) = malloc(size); } while (0);
@@ -640,6 +680,9 @@ extern void kportal_blockallsigs (void);
            getpid() , stack, ## a);
 #endif
 
+/* support decl needed both by kernel and liblustre */
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str);
+
 #ifndef CURRENT_TIME
 # define CURRENT_TIME time(0)
 #endif
@@ -657,6 +700,9 @@ typedef struct {
         long        lwte_p2;
         long        lwte_p3;
         long        lwte_p4;
+#if BITS_PER_LONG > 32
+        long        lwte_pad;
+#endif
 } lwt_event_t;
 
 #if LWT_SUPPORT
@@ -736,6 +782,40 @@ do {                                                                    \
  * USER LEVEL STUFF BELOW
  */
 
+#define PORTALS_CFG_VERSION 0x00010001;
+
+struct portals_cfg {
+        __u32 pcfg_version;
+        __u32 pcfg_command;
+
+        __u32 pcfg_nal;
+        __u32 pcfg_flags;
+
+        __u32 pcfg_gw_nal;
+        __u64 pcfg_nid;
+        __u64 pcfg_nid2;
+        __u64 pcfg_nid3;
+        __u32 pcfg_id;
+        __u32 pcfg_misc;
+        __u32 pcfg_fd;
+        __u32 pcfg_count;
+        __u32 pcfg_size;
+        __u32 pcfg_wait;
+
+        __u32 pcfg_plen1; /* buffers in userspace */
+        char *pcfg_pbuf1;
+        __u32 pcfg_plen2; /* buffers in userspace */
+        char *pcfg_pbuf2;
+};
+
+#define PCFG_INIT(pcfg, cmd)                            \
+do {                                                    \
+        memset(&pcfg, 0, sizeof(pcfg));                 \
+        pcfg.pcfg_version = PORTALS_CFG_VERSION;        \
+        pcfg.pcfg_command = (cmd);                      \
+                                                        \
+} while (0)
+
 #define PORTAL_IOCTL_VERSION 0x00010007
 #define PING_SYNC       0
 #define PING_ASYNC      1
@@ -957,18 +1037,14 @@ static inline int portal_ioctl_getdata(char *buf, char *end, void *arg)
 #define IOC_PORTAL_CLEAR_DEBUG             _IOWR('e', 32, long)
 #define IOC_PORTAL_MARK_DEBUG              _IOWR('e', 33, long)
 #define IOC_PORTAL_PANIC                   _IOWR('e', 34, long)
-#define IOC_PORTAL_ADD_ROUTE               _IOWR('e', 35, long)
-#define IOC_PORTAL_DEL_ROUTE               _IOWR('e', 36, long)
-#define IOC_PORTAL_GET_ROUTE               _IOWR('e', 37, long)
-#define IOC_PORTAL_NAL_CMD	           _IOWR('e', 38, long)
-#define IOC_PORTAL_GET_NID                 _IOWR('e', 39, long)
-#define IOC_PORTAL_FAIL_NID                _IOWR('e', 40, long)
-#define IOC_PORTAL_SET_DAEMON              _IOWR('e', 41, long)
-#define IOC_PORTAL_NOTIFY_ROUTER           _IOWR('e', 42, long)
-#define IOC_PORTAL_LWT_CONTROL             _IOWR('e', 43, long)
-#define IOC_PORTAL_LWT_SNAPSHOT            _IOWR('e', 44, long)
-#define IOC_PORTAL_LWT_LOOKUP_STRING       _IOWR('e', 45, long)
-#define IOC_PORTAL_MAX_NR                             45
+#define IOC_PORTAL_NAL_CMD	           _IOWR('e', 35, long)
+#define IOC_PORTAL_GET_NID                 _IOWR('e', 36, long)
+#define IOC_PORTAL_FAIL_NID                _IOWR('e', 37, long)
+#define IOC_PORTAL_SET_DAEMON              _IOWR('e', 38, long)
+#define IOC_PORTAL_LWT_CONTROL             _IOWR('e', 39, long)
+#define IOC_PORTAL_LWT_SNAPSHOT            _IOWR('e', 40, long)
+#define IOC_PORTAL_LWT_LOOKUP_STRING       _IOWR('e', 41, long)
+#define IOC_PORTAL_MAX_NR                             41
 
 enum {
         QSWNAL  =  1,
@@ -977,6 +1053,8 @@ enum {
         TOENAL,
         TCPNAL,
         SCIMACNAL,
+        ROUTER,
+        IBNAL,
         NAL_ENUM_END_MARKER
 };
 
@@ -985,9 +1063,12 @@ extern ptl_handle_ni_t  kqswnal_ni;
 extern ptl_handle_ni_t  ksocknal_ni;
 extern ptl_handle_ni_t  ktoenal_ni;
 extern ptl_handle_ni_t  kgmnal_ni;
+extern ptl_handle_ni_t  kibnal_ni;
 extern ptl_handle_ni_t  kscimacnal_ni;
 #endif
 
+#define PTL_NALFMT_SIZE         16
+
 #define NAL_MAX_NR (NAL_ENUM_END_MARKER - 1)
 
 #define NAL_CMD_REGISTER_PEER_FD     100
@@ -999,6 +1080,10 @@ extern ptl_handle_ni_t  kscimacnal_ni;
 #define NAL_CMD_ADD_AUTOCONN         106
 #define NAL_CMD_GET_AUTOCONN         107
 #define NAL_CMD_GET_TXDESC           108
+#define NAL_CMD_ADD_ROUTE            109
+#define NAL_CMD_DEL_ROUTE            110
+#define NAL_CMD_GET_ROUTE            111
+#define NAL_CMD_NOTIFY_ROUTER        112
 
 enum {
         DEBUG_DAEMON_START       =  1,
@@ -1013,11 +1098,20 @@ struct lustre_peer {
         ptl_handle_ni_t peer_ni;
 };
 
+
 /* module.c */
-typedef int (*nal_cmd_handler_t)(struct portal_ioctl_data *, void * private);
+typedef int (*nal_cmd_handler_t)(struct portals_cfg *, void * private);
 int kportal_nal_register(int nal, nal_cmd_handler_t handler, void * private);
 int kportal_nal_unregister(int nal);
 
+enum cfg_record_type {
+        PORTALS_CFG_TYPE = 1,
+        LUSTRE_CFG_TYPE = 123,
+};
+
+typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
+int kportal_nal_cmd(struct portals_cfg *);
+
 ptl_handle_ni_t *kportal_get_ni (int nal);
 void kportal_put_ni (int nal);
 
@@ -1031,14 +1125,19 @@ void kportal_put_ni (int nal);
 # endif
 #endif
 
-#if (BITS_PER_LONG == 32 || __WORDSIZE == 32)
+#if defined(__x86_64__)
+# define LPU64 "%Lu"
+# define LPD64 "%Ld"
+# define LPX64 "%#Lx"
+# define LPSZ  "%lu"
+# define LPSSZ "%ld"
+#elif (BITS_PER_LONG == 32 || __WORDSIZE == 32)
 # define LPU64 "%Lu"
 # define LPD64 "%Ld"
 # define LPX64 "%#Lx"
 # define LPSZ  "%u"
 # define LPSSZ "%d"
-#endif
-#if (BITS_PER_LONG == 64 || __WORDSIZE == 64)
+#elif (BITS_PER_LONG == 64 || __WORDSIZE == 64)
 # define LPU64 "%lu"
 # define LPD64 "%ld"
 # define LPX64 "%#lx"
diff --git a/lnet/include/linux/portals_lib.h b/lnet/include/linux/portals_lib.h
index a528a80fb440513929ee310911cb099293dc3b3d..609290ddcb15c383fe0bfbb30405a7d1a55aa908 100644
--- a/lnet/include/linux/portals_lib.h
+++ b/lnet/include/linux/portals_lib.h
@@ -42,6 +42,16 @@ static inline int size_round (int val)
         return (val + 7) & (~0x7);
 }
 
+static inline int size_round16(int val)
+{
+        return (val + 0xf) & (~0xf);
+}
+
+static inline int size_round32(int val)
+{
+        return (val + 0x1f) & (~0x1f);
+}
+
 static inline int size_round0(int val)
 {
         if (!val)
diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
index b623b938b6e76116f53d0257738a47067e9b98f4..55fd720eebe80998306696bddc0f4045b3d2f4dc 100644
--- a/lnet/include/lnet/lib-lnet.h
+++ b/lnet/include/lnet/lib-lnet.h
@@ -30,7 +30,6 @@ static inline int ptl_is_wire_handle_none (ptl_handle_wire_t *wh)
                 wh->wh_object_cookie == PTL_WIRE_HANDLE_NONE.wh_object_cookie);
 }
 
-#ifdef __KERNEL__
 #define state_lock(nal,flagsp)                          \
 do {                                                    \
         CDEBUG(D_PORTALS, "taking state lock\n");       \
@@ -42,20 +41,6 @@ do {                                                    \
         CDEBUG(D_PORTALS, "releasing state lock\n");    \
         nal->cb_sti(nal, flagsp);                       \
 }
-#else
-/* not needed in user space until we thread there */
-#define state_lock(nal,flagsp)                          \
-do {                                                    \
-        CDEBUG(D_PORTALS, "taking state lock\n");       \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-} while (0)
-
-#define state_unlock(nal,flagsp)                        \
-{                                                       \
-        CDEBUG(D_PORTALS, "releasing state lock\n");    \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-}
-#endif /* __KERNEL__ */
 
 #ifndef PTL_USE_SLAB_CACHE
 
@@ -361,6 +346,8 @@ extern char *dispatch_name(int index);
  */
 extern int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private);
 extern int lib_finalize(nal_cb_t * nal, void *private, lib_msg_t * msg);
+extern lib_msg_t *lib_fake_reply_msg (nal_cb_t *nal, ptl_nid_t peer_nid, 
+                                      lib_md_t *getmd);
 extern void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr);
 
 extern ptl_size_t lib_iov_nob (int niov, struct iovec *iov);
diff --git a/lnet/include/lnet/lib-p30.h b/lnet/include/lnet/lib-p30.h
index b623b938b6e76116f53d0257738a47067e9b98f4..55fd720eebe80998306696bddc0f4045b3d2f4dc 100644
--- a/lnet/include/lnet/lib-p30.h
+++ b/lnet/include/lnet/lib-p30.h
@@ -30,7 +30,6 @@ static inline int ptl_is_wire_handle_none (ptl_handle_wire_t *wh)
                 wh->wh_object_cookie == PTL_WIRE_HANDLE_NONE.wh_object_cookie);
 }
 
-#ifdef __KERNEL__
 #define state_lock(nal,flagsp)                          \
 do {                                                    \
         CDEBUG(D_PORTALS, "taking state lock\n");       \
@@ -42,20 +41,6 @@ do {                                                    \
         CDEBUG(D_PORTALS, "releasing state lock\n");    \
         nal->cb_sti(nal, flagsp);                       \
 }
-#else
-/* not needed in user space until we thread there */
-#define state_lock(nal,flagsp)                          \
-do {                                                    \
-        CDEBUG(D_PORTALS, "taking state lock\n");       \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-} while (0)
-
-#define state_unlock(nal,flagsp)                        \
-{                                                       \
-        CDEBUG(D_PORTALS, "releasing state lock\n");    \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-}
-#endif /* __KERNEL__ */
 
 #ifndef PTL_USE_SLAB_CACHE
 
@@ -361,6 +346,8 @@ extern char *dispatch_name(int index);
  */
 extern int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private);
 extern int lib_finalize(nal_cb_t * nal, void *private, lib_msg_t * msg);
+extern lib_msg_t *lib_fake_reply_msg (nal_cb_t *nal, ptl_nid_t peer_nid, 
+                                      lib_md_t *getmd);
 extern void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr);
 
 extern ptl_size_t lib_iov_nob (int niov, struct iovec *iov);
diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h
index 47c0dd247b8ea187d754c88027250bccda9292e6..30e56af8138c89a54a443355727a199f3a972894 100644
--- a/lnet/include/lnet/lib-types.h
+++ b/lnet/include/lnet/lib-types.h
@@ -54,72 +54,68 @@ typedef enum {
         PTL_MSG_HELLO,
 } ptl_msg_type_t;
 
-/* Each of these structs should start with an odd number of
- * __u32, or the compiler could add its own padding and confuse
- * everyone.
- *
- * Also, "length" needs to be at offset 28 of each struct.
- */
+/* The variant fields of the portals message header are aligned on an 8
+ * byte boundary in the message header.  Note that all types used in these
+ * wire structs MUST be fixed size and the smaller types are placed at the
+ * end. */
 typedef struct ptl_ack {
-        ptl_size_t mlength;
-        ptl_handle_wire_t dst_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length (0 for acks) moving out RSN */
+        ptl_handle_wire_t  dst_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_size_t         mlength;
 } WIRE_ATTR ptl_ack_t;
 
 typedef struct ptl_put {
-        ptl_pt_index_t ptl_index;
-        ptl_handle_wire_t ack_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length moving out RSN */
-        ptl_size_t offset;
-        ptl_hdr_data_t hdr_data;
+        ptl_handle_wire_t  ack_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_hdr_data_t     hdr_data;
+        ptl_pt_index_t     ptl_index;
+        ptl_size_t         offset;
 } WIRE_ATTR ptl_put_t;
 
 typedef struct ptl_get {
-        ptl_pt_index_t ptl_index;
-        ptl_handle_wire_t return_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length (0 for gets) moving out RSN */
-        ptl_size_t src_offset;
-        ptl_size_t return_offset;               /* unused: going RSN */
-        ptl_size_t sink_length;
+        ptl_handle_wire_t  return_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_pt_index_t     ptl_index;
+        ptl_size_t         src_offset;
+        ptl_size_t         sink_length;
 } WIRE_ATTR ptl_get_t;
 
 typedef struct ptl_reply {
-        __u32 unused1;                          /* unused fields going RSN */
-        ptl_handle_wire_t dst_wmd;
-        ptl_size_t dst_offset;                  /* unused: going RSN */
-        __u32 unused2;
-        ptl_size_t length;                      /* common length moving out RSN */
+        ptl_handle_wire_t  dst_wmd;
 } WIRE_ATTR ptl_reply_t;
 
+typedef struct ptl_hello {
+        __u64              incarnation;
+        __u32              type;
+} WIRE_ATTR ptl_hello_t;
+
 typedef struct {
-        ptl_nid_t dest_nid;
-        ptl_nid_t src_nid;
-        ptl_pid_t dest_pid;
-        ptl_pid_t src_pid;
-        __u32 type; /* ptl_msg_type_t */
+        ptl_nid_t           dest_nid;
+        ptl_nid_t           src_nid;
+        ptl_pid_t           dest_pid;
+        ptl_pid_t           src_pid;
+        __u32               type;               /* ptl_msg_type_t */
+        __u32               payload_length;     /* payload data to follow */
+        /*<------__u64 aligned------->*/
         union {
-                ptl_ack_t ack;
-                ptl_put_t put;
-                ptl_get_t get;
+                ptl_ack_t   ack;
+                ptl_put_t   put;
+                ptl_get_t   get;
                 ptl_reply_t reply;
+                ptl_hello_t hello;
         } msg;
 } WIRE_ATTR ptl_hdr_t;
 
-/* All length fields in individual unions at same offset */
-/* LASSERT for same in lib-move.c */
-#define PTL_HDR_LENGTH(h) ((h)->msg.ack.length)
-
 /* A HELLO message contains the portals magic number and protocol version
  * code in the header's dest_nid, the peer's NID in the src_nid, and
- * PTL_MSG_HELLO in the type field.  All other fields are zero (including
- * PTL_HDR_LENGTH; i.e. no payload).
+ * PTL_MSG_HELLO in the type field.  All other common fields are zero
+ * (including payload_size; i.e. no payload).  
  * This is for use by byte-stream NALs (e.g. TCP/IP) to check the peer is
  * running the same protocol and to find out its NID, so that hosts with
  * multiple IP interfaces can have a single NID. These NALs should exchange
- * HELLO messages when a connection is first established. */
+ * HELLO messages when a connection is first established. 
+ * Individual NALs can put whatever else they fancy in ptl_hdr_t::msg. 
+ */
 typedef struct {
         __u32	magic;                          /* PORTALS_PROTO_MAGIC */
         __u16   version_major;                  /* increment on incompatible change */
@@ -129,7 +125,7 @@ typedef struct {
 #define PORTALS_PROTO_MAGIC                0xeebc0ded
 
 #define PORTALS_PROTO_VERSION_MAJOR        0
-#define PORTALS_PROTO_VERSION_MINOR        1
+#define PORTALS_PROTO_VERSION_MINOR        3
 
 typedef struct {
         long recv_count, recv_length, send_count, send_length, drop_count,
@@ -137,11 +133,9 @@ typedef struct {
 } lib_counters_t;
 
 /* temporary expedient: limit number of entries in discontiguous MDs */
-#if PTL_LARGE_MTU
-# define PTL_MD_MAX_IOV	64
-#else
-# define PTL_MD_MAX_IOV 16
-#endif
+# define PTL_MTU        (512<<10)
+# define PTL_MD_MAX_IOV 128
+# define PTL_MD_MAX_PAGES min_t(int, PTL_MD_MAX_IOV, PTL_MTU / PAGE_SIZE)
 
 struct lib_msg_t {
         struct list_head  msg_list;
diff --git a/lnet/include/lnet/list.h b/lnet/include/lnet/list.h
index 78a1e2dd31bea8ac1be54cc9aac1636283cded3f..57713cb637ed3c725954ef16a7793a073966d4cf 100644
--- a/lnet/include/lnet/list.h
+++ b/lnet/include/lnet/list.h
@@ -16,6 +16,8 @@ struct list_head {
 	struct list_head *next, *prev;
 };
 
+typedef struct list_head list_t;
+
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
 #define LIST_HEAD(name) \
diff --git a/lnet/include/lnet/lltrace.h b/lnet/include/lnet/lltrace.h
index d389aab4300ed5955a7cd605d1a294104eaf0466..5f266e25b2f74bd207bc8e19e8caf6f7a31f79bc 100644
--- a/lnet/include/lnet/lltrace.h
+++ b/lnet/include/lnet/lltrace.h
@@ -18,8 +18,8 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <portals/types.h>
-#include <portals/ptlctl.h>
 #include <linux/kp30.h>
+#include <portals/ptlctl.h>
 #include <linux/limits.h>
 #include <asm/page.h>
 #include <linux/version.h>
diff --git a/lnet/include/lnet/lnetctl.h b/lnet/include/lnet/lnetctl.h
index 7763f1b548be7333ab117ae02733f89d8bc34ddc..f581e7228beebdf2f92a11894890fabeab92ff1f 100644
--- a/lnet/include/lnet/lnetctl.h
+++ b/lnet/include/lnet/lnetctl.h
@@ -29,6 +29,7 @@
 #define OBD_DEV_PATH "/dev/obd"
 
 int ptl_name2nal(char *str);
+int ptl_parse_ipaddr (__u32 *ipaddrp, char *str);
 int ptl_parse_nid (ptl_nid_t *nidp, char *str);
 char * ptl_nid2str (char *buffer, ptl_nid_t nid);
 
@@ -71,7 +72,11 @@ int jt_dbg_mark_debug_buf(int argc, char **argv);
 int jt_dbg_modules(int argc, char **argv);
 int jt_dbg_panic(int argc, char **argv);
 
+int ptl_set_cfg_record_cb(cfg_record_cb_t cb);
+
 /* l_ioctl.c */
+typedef int (ioc_handler_t)(int dev_id, int opc, void *buf);
+void set_ioc_handler(ioc_handler_t *handler);
 int register_ioc_dev(int dev_id, const char * dev_name);
 void unregister_ioc_dev(int dev_id);
 int set_ioctl_dump(char * file);
diff --git a/lnet/include/lnet/ptlctl.h b/lnet/include/lnet/ptlctl.h
index 7763f1b548be7333ab117ae02733f89d8bc34ddc..f581e7228beebdf2f92a11894890fabeab92ff1f 100644
--- a/lnet/include/lnet/ptlctl.h
+++ b/lnet/include/lnet/ptlctl.h
@@ -29,6 +29,7 @@
 #define OBD_DEV_PATH "/dev/obd"
 
 int ptl_name2nal(char *str);
+int ptl_parse_ipaddr (__u32 *ipaddrp, char *str);
 int ptl_parse_nid (ptl_nid_t *nidp, char *str);
 char * ptl_nid2str (char *buffer, ptl_nid_t nid);
 
@@ -71,7 +72,11 @@ int jt_dbg_mark_debug_buf(int argc, char **argv);
 int jt_dbg_modules(int argc, char **argv);
 int jt_dbg_panic(int argc, char **argv);
 
+int ptl_set_cfg_record_cb(cfg_record_cb_t cb);
+
 /* l_ioctl.c */
+typedef int (ioc_handler_t)(int dev_id, int opc, void *buf);
+void set_ioc_handler(ioc_handler_t *handler);
 int register_ioc_dev(int dev_id, const char * dev_name);
 void unregister_ioc_dev(int dev_id);
 int set_ioctl_dump(char * file);
diff --git a/lnet/include/lnet/socklnd.h b/lnet/include/lnet/socklnd.h
new file mode 100644
index 0000000000000000000000000000000000000000..27e6f8e07f58cb9345296fb9949e0805bcf574fa
--- /dev/null
+++ b/lnet/include/lnet/socklnd.h
@@ -0,0 +1,14 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * <portals/socknal.h>
+ *
+ * #defines shared between socknal implementation and utilities
+ */
+
+#define SOCKNAL_CONN_NONE     (-1)
+#define SOCKNAL_CONN_ANY        0
+#define SOCKNAL_CONN_CONTROL    1
+#define SOCKNAL_CONN_BULK_IN    2
+#define SOCKNAL_CONN_BULK_OUT   3
+#define SOCKNAL_CONN_NTYPES     4
diff --git a/lnet/include/lnet/types.h b/lnet/include/lnet/types.h
index 02692905d03be1cb47f97831f3de66abd0b738e9..e4ccebfdbb5f3d02883736cf3494a9a4416279af 100644
--- a/lnet/include/lnet/types.h
+++ b/lnet/include/lnet/types.h
@@ -104,6 +104,13 @@ typedef enum {
 typedef unsigned PTL_SEQ_BASETYPE ptl_seq_t;
 #define PTL_SEQ_GT(a,b)	(((signed PTL_SEQ_BASETYPE)((a) - (b))) > 0)
 
+/* XXX
+ * cygwin need the pragma line, not clear if it's needed in other places.
+ * checking!!!
+ */
+#ifdef __CYGWIN__
+#pragma pack(push, 4)
+#endif
 typedef struct {
         ptl_event_kind_t type;
         ptl_process_id_t initiator;
@@ -116,6 +123,9 @@ typedef struct {
         struct timeval arrival_time;
         volatile ptl_seq_t sequence;
 } ptl_event_t;
+#ifdef __CYGWIN__
+#pragma pop
+#endif
 
 typedef enum {
         PTL_ACK_REQ,
diff --git a/lnet/klnds/Makefile.am b/lnet/klnds/Makefile.am
index fed2785b5b467bed04c0436f9cbd5ddd6d68206f..25aab9db39ccb5e72d0f45935a974497f24ed321 100644
--- a/lnet/klnds/Makefile.am
+++ b/lnet/klnds/Makefile.am
@@ -3,5 +3,5 @@
 # This code is issued under the GNU General Public License.
 # See the file COPYING in this distribution
 
-DIST_SUBDIRS= socknal toenal qswnal gmnal scimacnal 
-SUBDIRS= socknal toenal	@QSWNAL@ @GMNAL@ @SCIMACNAL@
+DIST_SUBDIRS= socknal toenal qswnal gmnal scimacnal ibnal
+SUBDIRS= socknal toenal	@QSWNAL@ @GMNAL@ @SCIMACNAL@ @IBNAL@
diff --git a/lnet/klnds/gmlnd/Makefile.am b/lnet/klnds/gmlnd/Makefile.am
index 1dc6f4eb083126287ea5936a84e4672766ca1dcf..bac4680c9a17db8874f2c2394c4a1f08415d4d9c 100644
--- a/lnet/klnds/gmlnd/Makefile.am
+++ b/lnet/klnds/gmlnd/Makefile.am
@@ -9,5 +9,5 @@ MODULE = kgmnal
 modulenet_DATA = kgmnal.o
 EXTRA_PROGRAMS = kgmnal
 
-DEFS =
-kgmnal_SOURCES = gmnal.c gmnal_cb.c gmnal.h
+DEFS = -DGM_KERNEL
+kgmnal_SOURCES = gmnal.h gmnal_api.c gmnal_cb.c gmnal_comm.c gmnal_utils.c gmnal_module.c
diff --git a/lustre/portals/knals/lgmnal/Makefile.mk b/lnet/klnds/gmlnd/Makefile.mk
similarity index 63%
rename from lustre/portals/knals/lgmnal/Makefile.mk
rename to lnet/klnds/gmlnd/Makefile.mk
index c8ca67fad856c015acb207c3f2a1a251a95ebe31..b799a47e4db54219178eade8164e38f50e13a755 100644
--- a/lustre/portals/knals/lgmnal/Makefile.mk
+++ b/lnet/klnds/gmlnd/Makefile.mk
@@ -5,6 +5,6 @@
 
 include ../../Kernelenv
 
-obj-y += lgmnal.o
-lgmnal-objs    := lgmnal_api.o lgmnal_cb.o lgmnal_utils.o lgmnal_comm.o lgmnal_module.o
+obj-y += gmnal.o
+gmnal-objs    := gmnal_api.o gmnal_cb.o gmnal_utils.o gmnal_comm.o gmnal_module.o
 
diff --git a/lnet/klnds/gmlnd/gm-1.5.2.1-exports.patch b/lnet/klnds/gmlnd/gm-1.5.2.1-exports.patch
deleted file mode 100644
index 23c80d940806e4b91c75bd7d023b4262ca3b3753..0000000000000000000000000000000000000000
--- a/lnet/klnds/gmlnd/gm-1.5.2.1-exports.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -ru gm-1.5.2.1_Linux/drivers/linux/gm/gm_arch.c gm-1.5.2.1_Linux-cfs/drivers/linux/gm/gm_arch.c
---- gm-1.5.2.1_Linux/drivers/linux/gm/gm_arch.c	Mon Jul  1 10:35:09 2002
-+++ gm-1.5.2.1_Linux-cfs/drivers/linux/gm/gm_arch.c	Thu Sep 19 14:19:38 2002
-@@ -30,6 +30,8 @@
-  *
-  ************************************************************************/
- 
-+#define EXPORT_SYMTAB
-+
- #include <linux/config.h>
- #include <linux/module.h>
- 
-@@ -4075,6 +4077,28 @@
-   return 0;
- }
- 
-+EXPORT_SYMBOL(gm_blocking_receive_no_spin);
-+EXPORT_SYMBOL(gm_close);
-+EXPORT_SYMBOL(gm_dma_free);
-+EXPORT_SYMBOL(gm_dma_malloc);
-+EXPORT_SYMBOL(gm_drop_sends);
-+EXPORT_SYMBOL(gm_finalize);
-+EXPORT_SYMBOL(gm_get_node_id);
-+EXPORT_SYMBOL(gm_init);
-+EXPORT_SYMBOL(gm_initialize_alarm);
-+EXPORT_SYMBOL(gm_max_node_id_in_use);
-+EXPORT_SYMBOL(gm_min_size_for_length);
-+EXPORT_SYMBOL(gm_num_receive_tokens);
-+EXPORT_SYMBOL(gm_num_send_tokens);
-+EXPORT_SYMBOL(gm_open);
-+EXPORT_SYMBOL(gm_provide_receive_buffer);
-+EXPORT_SYMBOL(gm_resume_sending);
-+EXPORT_SYMBOL(gm_send_with_callback);
-+EXPORT_SYMBOL(gm_set_acceptable_sizes);
-+EXPORT_SYMBOL(gm_set_alarm);
-+EXPORT_SYMBOL(gm_unknown);
-+
-+
- /*
-   This file uses GM standard indentation.
- 
-Only in gm-1.5.2.1_Linux-cfs/drivers/linux/gm: gm_arch.c~
-Only in gm-1.5.2.1_Linux-cfs/: trace
diff --git a/lnet/klnds/gmlnd/gmlnd.h b/lnet/klnds/gmlnd/gmlnd.h
index 47e8c3c36f115326e1f6f2c90f293e82a6bebeac..53757ab48de082fe5cb4d58adefec5bf30d14e14 100644
--- a/lnet/klnds/gmlnd/gmlnd.h
+++ b/lnet/klnds/gmlnd/gmlnd.h
@@ -1,101 +1,483 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#ifndef _GMNAL_H
-#define _GMNAL_H
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/locks.h>
-#include <linux/unistd.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/stat.h>
-#include <linux/list.h>
-#include <asm/uaccess.h>
-#include <asm/segment.h>
+
+
+/*
+ *	Portals GM kernel NAL header file
+ *	This file makes all declaration and prototypes 
+ *	for the API side and CB side of the NAL
+ */
+#ifndef __INCLUDE_GMNAL_H__
+#define __INCLUDE_GMNAL_H__
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#include "linux/config.h"
+#include "linux/module.h"
+#include "linux/tty.h"
+#include "linux/kernel.h"
+#include "linux/mm.h"
+#include "linux/string.h"
+#include "linux/stat.h"
+#include "linux/errno.h"
+#include "linux/locks.h"
+#include "linux/unistd.h"
+#include "linux/init.h"
+#include "linux/sem.h"
+#include "linux/vmalloc.h"
 
 #define DEBUG_SUBSYSTEM S_GMNAL
 
-#include <linux/kp30.h>
-#include <portals/p30.h>
-#include <portals/lib-p30.h>
+#include "portals/nal.h"
+#include "portals/api.h"
+#include "portals/errno.h"
+#include "linux/kp30.h"
+#include "portals/p30.h"
+
+#include "portals/lib-nal.h"
+#include "portals/lib-p30.h"
+
+#define GM_STRONG_TYPES 1
+#include "gm.h"
+#include "gm_internal.h"
+
+
+
+/*
+ *	Defines for the API NAL
+ */
+
+/*
+ *	Small message size is configurable
+ *	insmod can set small_msg_size
+ *	which is used to populate nal_data.small_msg_size
+ */
+#define GMNAL_SMALL_MESSAGE		1078
+#define GMNAL_LARGE_MESSAGE_INIT	1079
+#define GMNAL_LARGE_MESSAGE_ACK	1080
+#define GMNAL_LARGE_MESSAGE_FINI	1081
+
+extern  int gmnal_small_msg_size;
+extern  int num_rx_threads;
+extern  int num_stxds;
+#define GMNAL_SMALL_MSG_SIZE(a)		a->small_msg_size
+#define GMNAL_IS_SMALL_MESSAGE(n,a,b,c)	gmnal_is_small_msg(n, a, b, c)
+#define GMNAL_MAGIC				0x1234abcd
+
+
+/*
+ *	Small Transmit Descriptor
+ *	A structre to keep track of a small transmit operation
+ *	This structure has a one-to-one relationship with a small
+ *	transmit buffer (both create by gmnal_stxd_alloc). 
+ *	There are two free list of stxd. One for use by clients of the NAL
+ *	and the other by the NAL rxthreads when doing sends. 
+ *	This helps prevent deadlock caused by stxd starvation.
+ */
+typedef struct _gmnal_stxd_t {
+	void 			*buffer;
+	int			buffer_size;
+	gm_size_t		gm_size;
+	int			msg_size;
+	int			gm_target_node;
+	int			gm_priority;
+	int			type;
+	struct _gmnal_data_t 	*nal_data;
+	lib_msg_t		*cookie;
+	int			niov;
+	struct iovec		iov[PTL_MD_MAX_IOV];
+	struct _gmnal_stxd_t	*next;
+        int                     rxt; 
+        int                     kniov;
+        struct iovec            *iovec_dup;
+} gmnal_stxd_t;
+
+/*
+ *	keeps a transmit token for large transmit (gm_get)
+ *	and a pointer to rxd that is used as context for large receive
+ */
+typedef struct _gmnal_ltxd_t {
+	struct _gmnal_ltxd_t	*next;
+	struct	_gmnal_srxd_t  *srxd;
+} gmnal_ltxd_t;
+
+
+/*
+ *	as for gmnal_stxd_t 
+ *	a hash table in nal_data find srxds from
+ *	the rx buffer address. hash table populated at init time
+ */
+typedef struct _gmnal_srxd_t {
+	void 			*buffer;
+	int			size;
+	gm_size_t		gmsize;
+	unsigned int		gm_source_node;
+	gmnal_stxd_t		*source_stxd;
+	int			type;
+	int			nsiov;
+	int			nriov;
+	struct iovec 		*riov;
+	int			ncallbacks;
+	spinlock_t		callback_lock;
+	int			callback_status;
+	lib_msg_t		*cookie;
+	struct _gmnal_srxd_t	*next;
+	struct _gmnal_data_t	*nal_data;
+} gmnal_srxd_t;
+
+/*
+ *	Header which lmgnal puts at the start of each message
+ */
+typedef struct	_gmnal_msghdr {
+	int		magic;
+	int 		type;
+	unsigned int	sender_node_id;
+	gmnal_stxd_t	*stxd;
+	int		niov;
+	} gmnal_msghdr_t;
+#define GMNAL_MSGHDR_SIZE	sizeof(gmnal_msghdr_t)
+
+/*
+ *	the caretaker thread (ct_thread) gets receive events
+ *	(and other events) from the myrinet device via the GM2 API.
+ *	caretaker thread populates one work entry for each receive event,
+ *	puts it on a Q in nal_data and wakes a receive thread to  
+ *	process the receive.  
+ *	Processing a portals receive can involve a transmit operation. 
+ *	Because of this the caretaker thread cannot process receives 
+ *	as it may get deadlocked when supply of transmit descriptors 
+ *	is exhausted (as caretaker thread is responsible for replacing 
+ *	transmit descriptors on the free list)
+ */
+typedef struct _gmnal_rxtwe {
+	void			*buffer;
+	unsigned		snode;
+	unsigned		sport;
+	unsigned		type;
+	unsigned		length;
+	struct _gmnal_rxtwe	*next;
+} gmnal_rxtwe_t;
+
+/*
+ *	1 receive thread started on each CPU
+ */
+#define NRXTHREADS 10 /* max number of receiver threads */
+
+typedef struct _gmnal_data_t {
+	int		refcnt;
+	spinlock_t	cb_lock;
+	spinlock_t 	stxd_lock;
+	struct semaphore stxd_token;
+	gmnal_stxd_t	*stxd;
+	spinlock_t 	rxt_stxd_lock;
+	struct semaphore rxt_stxd_token;
+	gmnal_stxd_t	*rxt_stxd;
+	spinlock_t 	ltxd_lock;
+	struct semaphore ltxd_token;
+	gmnal_ltxd_t	*ltxd;
+	spinlock_t 	srxd_lock;
+	struct semaphore srxd_token;
+	gmnal_srxd_t	*srxd;
+	struct gm_hash	*srxd_hash;
+	nal_t		*nal;	
+	nal_cb_t	*nal_cb;
+	struct gm_port	*gm_port;
+	unsigned int	gm_local_nid;
+	unsigned int	gm_global_nid;
+	spinlock_t 	gm_lock;
+	long		rxthread_pid[NRXTHREADS];
+	int		rxthread_stop_flag;
+	spinlock_t	rxthread_flag_lock;
+	long		rxthread_flag;
+	long		ctthread_pid;
+	int		ctthread_flag;
+	gm_alarm_t	ctthread_alarm;
+	int		small_msg_size;
+	int		small_msg_gmsize;
+	gmnal_rxtwe_t	*rxtwe_head;
+	gmnal_rxtwe_t	*rxtwe_tail;
+	spinlock_t	rxtwe_lock;
+	struct	semaphore rxtwe_wait;
+} gmnal_data_t;
+
+/*
+ *	Flags to start/stop and check status of threads
+ *	each rxthread sets 1 bit (any bit) of the flag on startup
+ *	and clears 1 bit when exiting
+ */
+#define GMNAL_THREAD_RESET	0
+#define GMNAL_THREAD_STOP	666
+#define GMNAL_CTTHREAD_STARTED	333
+#define GMNAL_RXTHREADS_STARTED ( (1<<num_rx_threads)-1)
+
+
+extern gmnal_data_t	*global_nal_data;
+
+/*
+ *	The gm_port to use for gmnal
+ */
+#define GMNAL_GM_PORT	4
+
+/*
+ * for ioctl get pid
+ */
+#define GMNAL_IOC_GET_GNID 1	
+
+/*
+ *	Return codes
+ */
+#define GMNAL_STATUS_OK	0
+#define GMNAL_STATUS_FAIL	1
+#define GMNAL_STATUS_NOMEM	2
+
+
+/*
+ *	FUNCTION PROTOTYPES
+ */
+
+/*
+ *	Locking macros
+ */
+
+/*
+ *	For the Small tx and rx descriptor lists
+ */
+#define GMNAL_TXD_LOCK_INIT(a)		spin_lock_init(&a->stxd_lock);
+#define GMNAL_TXD_LOCK(a)		spin_lock(&a->stxd_lock);
+#define GMNAL_TXD_UNLOCK(a)		spin_unlock(&a->stxd_lock);
+#define GMNAL_TXD_TOKEN_INIT(a, n)	sema_init(&a->stxd_token, n);
+#define GMNAL_TXD_GETTOKEN(a)		down(&a->stxd_token);
+#define GMNAL_TXD_TRYGETTOKEN(a)	down_trylock(&a->stxd_token)
+#define GMNAL_TXD_RETURNTOKEN(a)	up(&a->stxd_token);
+
+#define GMNAL_RXT_TXD_LOCK_INIT(a)	spin_lock_init(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_LOCK(a)		spin_lock(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_UNLOCK(a)	        spin_unlock(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_TOKEN_INIT(a, n)	sema_init(&a->rxt_stxd_token, n);
+#define GMNAL_RXT_TXD_GETTOKEN(a)	down(&a->rxt_stxd_token);
+#define GMNAL_RXT_TXD_TRYGETTOKEN(a)	down_trylock(&a->rxt_stxd_token)
+#define GMNAL_RXT_TXD_RETURNTOKEN(a)	up(&a->rxt_stxd_token);
+
+#define GMNAL_LTXD_LOCK_INIT(a)		spin_lock_init(&a->ltxd_lock);
+#define GMNAL_LTXD_LOCK(a)		spin_lock(&a->ltxd_lock);
+#define GMNAL_LTXD_UNLOCK(a)		spin_unlock(&a->ltxd_lock);
+#define GMNAL_LTXD_TOKEN_INIT(a, n)	sema_init(&a->ltxd_token, n);
+#define GMNAL_LTXD_GETTOKEN(a)		down(&a->ltxd_token);
+#define GMNAL_LTXD_TRYGETTOKEN(a)	down_trylock(&a->ltxd_token)
+#define GMNAL_LTXD_RETURNTOKEN(a)	up(&a->ltxd_token);
+
+#define GMNAL_RXD_LOCK_INIT(a)		spin_lock_init(&a->srxd_lock);
+#define GMNAL_RXD_LOCK(a)		spin_lock(&a->srxd_lock);
+#define GMNAL_RXD_UNLOCK(a)		spin_unlock(&a->srxd_lock);
+#define GMNAL_RXD_TOKEN_INIT(a, n)	sema_init(&a->srxd_token, n);
+#define GMNAL_RXD_GETTOKEN(a)		down(&a->srxd_token);
+#define GMNAL_RXD_TRYGETTOKEN(a)	down_trylock(&a->srxd_token)
+#define GMNAL_RXD_RETURNTOKEN(a)	up(&a->srxd_token);
+
+#define GMNAL_GM_LOCK_INIT(a)		spin_lock_init(&a->gm_lock);
+#define GMNAL_GM_LOCK(a)		spin_lock(&a->gm_lock);
+#define GMNAL_GM_UNLOCK(a)		spin_unlock(&a->gm_lock);
+#define GMNAL_CB_LOCK_INIT(a)		spin_lock_init(&a->cb_lock);
+
+
+/*
+ *	Memory Allocator
+ */
+
+/*
+ *	API NAL
+ */
+int gmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
+
+int gmnal_api_shutdown(nal_t *, int);
 
-#include <gm.h>
+int gmnal_api_validate(nal_t *, void *, size_t);
+
+void gmnal_api_yield(nal_t *);
+
+void gmnal_api_lock(nal_t *, unsigned long *);
+
+void gmnal_api_unlock(nal_t *, unsigned long *);
+
+
+#define GMNAL_INIT_NAL(a)	do { 	\
+				a->forward = gmnal_api_forward; \
+				a->shutdown = gmnal_api_shutdown; \
+				a->validate = NULL; \
+				a->yield = gmnal_api_yield; \
+				a->lock = gmnal_api_lock; \
+				a->unlock = gmnal_api_unlock; \
+				a->timeout = NULL; \
+				a->refct = 1; \
+				a->nal_data = NULL; \
+				} while (0)
 
 
 /*
- *  Myrinet GM NAL
+ *	CB NAL
  */
-#define NPAGES_LARGE            16
-#define NPAGES_SMALL            1
-#define MSG_LEN_LARGE            NPAGES_LARGE*PAGE_SIZE
-#define MSG_LEN_SMALL            NPAGES_SMALL*PAGE_SIZE
-#define MSG_SIZE_LARGE           (gm_min_size_for_length(MSG_LEN_LARGE))
-#define MSG_SIZE_SMALL           (gm_min_size_for_length(MSG_LEN_SMALL))
 
-#define TXMSGS                  64 /* Number of Transmit Messages */
-#define ENVELOPES               8  /* Number of outstanding receive msgs */
+int gmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
+	int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
+
+int gmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
+	int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
+
+int gmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
+	unsigned int, struct iovec *, size_t, size_t);
+
+int gmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
+	unsigned int, ptl_kiov_t *, size_t, size_t);
+
+int gmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
+
+int gmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
+
+int gmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
+
+void *gmnal_cb_malloc(nal_cb_t *, size_t);
+
+void gmnal_cb_free(nal_cb_t *, void *, size_t);
+
+void gmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
+
+int  gmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
 
-#define KGM_PORT_NUM 3
-#define KGM_HOSTNAME "kgmnal"
+void gmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
 
+void gmnal_cb_cli(nal_cb_t *, unsigned long *);
 
-typedef struct {
-        char *krx_buffer;
-        unsigned long   krx_len;
-        unsigned int   krx_size;
-        unsigned int   krx_priority;
-        struct list_head krx_item;
-}  kgmnal_rx_t;
+void gmnal_cb_sti(nal_cb_t *, unsigned long *);
 
+int gmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
+
+nal_t *gmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
+
+void  gmnal_fini(void);
+
+
+
+#define GMNAL_INIT_NAL_CB(a)	do {	\
+				a->cb_send = gmnal_cb_send; \
+				a->cb_send_pages = gmnal_cb_send_pages; \
+				a->cb_recv = gmnal_cb_recv; \
+				a->cb_recv_pages = gmnal_cb_recv_pages; \
+				a->cb_read = gmnal_cb_read; \
+				a->cb_write = gmnal_cb_write; \
+				a->cb_callback = gmnal_cb_callback; \
+				a->cb_malloc = gmnal_cb_malloc; \
+				a->cb_free = gmnal_cb_free; \
+				a->cb_map = NULL; \
+				a->cb_unmap = NULL; \
+				a->cb_printf = gmnal_cb_printf; \
+				a->cb_cli = gmnal_cb_cli; \
+				a->cb_sti = gmnal_cb_sti; \
+				a->cb_dist = gmnal_cb_dist; \
+				a->nal_data = NULL; \
+				} while (0)
+
+
+/*
+ *	Small and Large Transmit and Receive Descriptor Functions
+ */
+int  		gmnal_alloc_txd(gmnal_data_t *);
+void 		gmnal_free_txd(gmnal_data_t *);
+gmnal_stxd_t* 	gmnal_get_stxd(gmnal_data_t *, int);
+void 		gmnal_return_stxd(gmnal_data_t *, gmnal_stxd_t *);
+gmnal_ltxd_t* 	gmnal_get_ltxd(gmnal_data_t *);
+void 		gmnal_return_ltxd(gmnal_data_t *, gmnal_ltxd_t *);
+
+int  		gmnal_alloc_srxd(gmnal_data_t *);
+void 		gmnal_free_srxd(gmnal_data_t *);
+gmnal_srxd_t* 	gmnal_get_srxd(gmnal_data_t *, int);
+void 		gmnal_return_srxd(gmnal_data_t *, gmnal_srxd_t *);
+
+/*
+ *	general utility functions
+ */
+gmnal_srxd_t	*gmnal_rxbuffer_to_srxd(gmnal_data_t *, void*);
+void		gmnal_stop_rxthread(gmnal_data_t *);
+void		gmnal_stop_ctthread(gmnal_data_t *);
+void		gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
+void		gmnal_drop_sends_callback(gm_port_t *, void *, gm_status_t);
+char		*gmnal_gm_error(gm_status_t);
+char		*gmnal_rxevent(gm_recv_event_t*);
+int		gmnal_is_small_msg(gmnal_data_t*, int, struct iovec*, int);
+void 		gmnal_yield(int);
+int		gmnal_start_kernel_threads(gmnal_data_t *);
+
+
+/*
+ *	Communication functions
+ */
+
+/*
+ *	Receive threads
+ */
+int 		gmnal_ct_thread(void *); /* caretaker thread */
+int 		gmnal_rx_thread(void *); /* receive thread */
+int 		gmnal_pre_receive(gmnal_data_t*, gmnal_rxtwe_t*, int);
+int		gmnal_rx_bad(gmnal_data_t *, gmnal_rxtwe_t *, gmnal_srxd_t*);
+int		gmnal_rx_requeue_buffer(gmnal_data_t *, gmnal_srxd_t *);
+int		gmnal_add_rxtwe(gmnal_data_t *, gm_recv_t *);
+gmnal_rxtwe_t * gmnal_get_rxtwe(gmnal_data_t *);
+void		gmnal_remove_rxtwe(gmnal_data_t *);
+
+
+/*
+ *	Small messages
+ */
+int 		gmnal_small_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
+			        struct iovec *, size_t, size_t);
+int 		gmnal_small_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
+				int, ptl_nid_t, ptl_pid_t, 
+				unsigned int, struct iovec*, int);
+void 		gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
+
+
+
+/*
+ *	Large messages
+ */
+int 		gmnal_large_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
+				struct iovec *, size_t, size_t);
 
-typedef struct {
-        nal_cb_t  *ktx_nal;
-        void      *ktx_private;
-        lib_msg_t *ktx_cookie;
-        char      *ktx_buffer;
-        size_t     ktx_len;
-        unsigned long ktx_size;
-        int        ktx_ndx;
-        unsigned int ktx_priority;
-        unsigned int ktx_tgt_node;
-        unsigned int ktx_tgt_port_id;
-}  kgmnal_tx_t;
+int 		gmnal_large_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
+				int, ptl_nid_t, ptl_pid_t, unsigned int, 
+				struct iovec*, int);
 
+void 		gmnal_large_tx_callback(gm_port_t *, void *, gm_status_t);
 
-typedef struct {
-        char              kgm_init;
-        char              kgm_shuttingdown;
-        struct gm_port   *kgm_port;
-        struct list_head  kgm_list;
-        ptl_nid_t         kgm_nid;
-        nal_cb_t         *kgm_cb;
-        struct kgm_trans *kgm_trans;
-        struct tq_struct  kgm_ready_tq;
-        spinlock_t        kgm_dispatch_lock;
-        spinlock_t        kgm_update_lock;
-        spinlock_t        kgm_send_lock;
-}  kgmnal_data_t;
+int 		gmnal_remote_get(gmnal_srxd_t *, int, struct iovec*, int, 
+				  struct iovec*);
 
-int kgm_init(kgmnal_data_t *kgm_data);
-int kgmnal_recv_thread(void *);
-int gm_return_mynid(void);
-void kgmnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
+void		gmnal_remote_get_callback(gm_port_t *, void *, gm_status_t);
 
-extern kgmnal_data_t      kgmnal_data;
-extern nal_t              kgmnal_api;
-extern nal_cb_t           kgmnal_lib;
+int 		gmnal_copyiov(int, gmnal_srxd_t *, int, struct iovec*, int, 
+			       struct iovec*);
 
-#endif  /* _GMNAL_H */
+void 		gmnal_large_tx_ack(gmnal_data_t *, gmnal_srxd_t *);
+void 		gmnal_large_tx_ack_callback(gm_port_t *, void *, gm_status_t);
+void 		gmnal_large_tx_ack_received(gmnal_data_t *, gmnal_srxd_t *);
 
+#endif /*__INCLUDE_GMNAL_H__*/
diff --git a/lnet/klnds/gmlnd/gmlnd_api.c b/lnet/klnds/gmlnd/gmlnd_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..1cb13178794e6100209ba42cc26e9f9cab406918
--- /dev/null
+++ b/lnet/klnds/gmlnd/gmlnd_api.c
@@ -0,0 +1,465 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *	Implements the API NAL functions
+ */
+
+#include "gmnal.h"
+
+gmnal_data_t	*global_nal_data = NULL;
+/*
+ *	gmnal_api_forward
+ *	This function takes a pack block of arguments from the NAL API
+ *	module and passes them to the NAL CB module. The CB module unpacks
+ *	the args and calls the appropriate function indicated by index.
+ *	Typically this function is used to pass args between kernel and use
+ *	space.
+ *	As lgmanl exists entirely in kernel, just pass the arg block directly 
+ *	to the NAL CB, buy passing the args to lib_dispatch
+ *	Arguments are
+ *	nal_t	nal 	Our nal
+ *	int	index	the api function that initiated this call 
+ *	void 	*args	packed block of function args
+ *	size_t	arg_len	length of args block
+ *	void 	*ret	A return value for the API NAL
+ *	size_t	ret_len	Size of the return value
+ *	
+ */
+
+int
+gmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
+		void *ret, size_t ret_len)
+{
+
+	nal_cb_t	*nal_cb = NULL;
+	gmnal_data_t	*nal_data = NULL;
+
+
+
+
+
+	if (!nal || !args || (index < 0) || (arg_len < 0)) {
+			CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
+		return (PTL_FAIL);
+	}
+
+	if (ret && (ret_len <= 0)) {
+		CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
+		return (PTL_FAIL);
+	}
+
+
+	if (!nal->nal_data) {
+		CDEBUG(D_ERROR, "bad nal, no nal data\n");	
+		return (PTL_FAIL);
+	}
+	
+	nal_data = nal->nal_data;
+	CDEBUG(D_INFO, "nal_data is [%p]\n", nal_data);	
+
+	if (!nal_data->nal_cb) {
+		CDEBUG(D_ERROR, "bad nal_data, no nal_cb\n");	
+		return (PTL_FAIL);
+	}
+	
+	nal_cb = nal_data->nal_cb;
+	CDEBUG(D_INFO, "nal_cb is [%p]\n", nal_cb);	
+	
+	CDEBUG(D_PORTALS, "gmnal_api_forward calling lib_dispatch\n");
+	lib_dispatch(nal_cb, NULL, index, args, ret);
+	CDEBUG(D_PORTALS, "gmnal_api_forward returns from lib_dispatch\n");
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	gmnal_api_shutdown
+ *	Close down this interface and free any resources associated with it
+ *	nal_t	nal	our nal to shutdown
+ */
+int
+gmnal_api_shutdown(nal_t *nal, int interface)
+{
+
+	gmnal_data_t	*nal_data = nal->nal_data;
+
+	CDEBUG(D_TRACE, "gmnal_api_shutdown: nal_data [%p]\n", nal_data);
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	gmnal_api_validate
+ *	validate a user address for use in communications
+ *	There's nothing to be done here
+ */
+int
+gmnal_api_validate(nal_t *nal, void *base, size_t extent)
+{
+
+	return(PTL_OK);
+}
+
+
+
+/*
+ *	gmnal_api_yield
+ *	Give up the processor
+ */
+void
+gmnal_api_yield(nal_t *nal)
+{
+	CDEBUG(D_TRACE, "gmnal_api_yield : nal [%p]\n", nal);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule();
+
+	return;
+}
+
+
+
+/*
+ *	gmnal_api_lock
+ *	Take a threadsafe lock
+ */
+void
+gmnal_api_lock(nal_t *nal, unsigned long *flags)
+{
+
+	gmnal_data_t	*nal_data;
+	nal_cb_t	*nal_cb;
+
+	nal_data = nal->nal_data;
+	nal_cb = nal_data->nal_cb;
+
+	nal_cb->cb_cli(nal_cb, flags);
+
+	return;
+}
+
+/*
+ *	gmnal_api_unlock
+ *	Release a threadsafe lock
+ */
+void
+gmnal_api_unlock(nal_t *nal, unsigned long *flags)
+{
+	gmnal_data_t	*nal_data;
+	nal_cb_t	*nal_cb;
+
+	nal_data = nal->nal_data;
+	nal_cb = nal_data->nal_cb;
+
+	nal_cb->cb_sti(nal_cb, flags);
+
+	return;
+}
+
+
+nal_t *
+gmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, 
+	    ptl_pid_t rpid)
+{
+
+	nal_t		*nal = NULL;
+	nal_cb_t	*nal_cb = NULL;
+	gmnal_data_t	*nal_data = NULL;
+	gmnal_srxd_t	*srxd = NULL;
+	gm_status_t	gm_status;
+	unsigned int	local_nid = 0, global_nid = 0;
+	ptl_nid_t	portals_nid;
+	ptl_pid_t	portals_pid = 0;
+
+
+	CDEBUG(D_TRACE, "gmnal_init : interface [%d], ptl_size [%d], 
+	       ac_size[%d]\n", interface, ptl_size, ac_size);
+
+
+	PORTAL_ALLOC(nal_data, sizeof(gmnal_data_t));
+	if (!nal_data) {
+		CDEBUG(D_ERROR, "can't get memory\n");
+		return(NULL);
+	}	
+	memset(nal_data, 0, sizeof(gmnal_data_t));
+	/*
+ 	 *	set the small message buffer size 
+	 */
+	nal_data->refcnt = 1;
+
+	CDEBUG(D_INFO, "Allocd and reset nal_data[%p]\n", nal_data);
+	CDEBUG(D_INFO, "small_msg_size is [%d]\n", nal_data->small_msg_size);
+
+	PORTAL_ALLOC(nal, sizeof(nal_t));
+	if (!nal) {
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
+		return(NULL);
+	}
+	memset(nal, 0, sizeof(nal_t));
+	CDEBUG(D_INFO, "Allocd and reset nal[%p]\n", nal);
+
+	PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
+	if (!nal_cb) {
+		PORTAL_FREE(nal, sizeof(nal_t));
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
+		return(NULL);
+	}
+	memset(nal_cb, 0, sizeof(nal_cb_t));
+	CDEBUG(D_INFO, "Allocd and reset nal_cb[%p]\n", nal_cb);
+
+	GMNAL_INIT_NAL(nal);
+	GMNAL_INIT_NAL_CB(nal_cb);
+	/*
+	 *	String them all together
+	 */
+	nal->nal_data = (void*)nal_data;
+	nal_cb->nal_data = (void*)nal_data;
+	nal_data->nal = nal;
+	nal_data->nal_cb = nal_cb;
+
+	GMNAL_CB_LOCK_INIT(nal_data);
+	GMNAL_GM_LOCK_INIT(nal_data);
+
+
+	/*
+ 	 *	initialise the interface, 
+	 */
+	CDEBUG(D_INFO, "Calling gm_init\n");
+	if (gm_init() != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "call to gm_init failed\n");
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+
+	CDEBUG(D_NET, "Calling gm_open with interface [%d], port [%d], 
+       	       name [%s], version [%d]\n", interface, GMNAL_GM_PORT, 
+	       "gmnal", GM_API_VERSION);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_open(&nal_data->gm_port, 0, GMNAL_GM_PORT, "gmnal", 
+			    GM_API_VERSION);
+	GMNAL_GM_UNLOCK(nal_data);
+
+	CDEBUG(D_INFO, "gm_open returned [%d]\n", gm_status);
+	if (gm_status == GM_SUCCESS) {
+		CDEBUG(D_INFO, "gm_open succeeded port[%p]\n", 
+		       nal_data->gm_port);
+	} else {
+		switch(gm_status) {
+		case(GM_INVALID_PARAMETER):
+			CDEBUG(D_ERROR, "gm_open Failure. Invalid Parameter\n");
+			break;
+		case(GM_BUSY):
+			CDEBUG(D_ERROR, "gm_open Failure. GM Busy\n");
+			break;
+		case(GM_NO_SUCH_DEVICE):
+			CDEBUG(D_ERROR, "gm_open Failure. No such device\n");
+			break;
+		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+			CDEBUG(D_ERROR, "gm_open Failure. Incompatile lib 
+			       and driver\n");
+			break;
+		case(GM_OUT_OF_MEMORY):
+			CDEBUG(D_ERROR, "gm_open Failure. Out of Memory\n");
+			break;
+		default:
+			CDEBUG(D_ERROR, "gm_open Failure. Unknow error 
+			       code [%d]\n", gm_status);
+			break;
+		}	
+		GMNAL_GM_LOCK(nal_data);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+	
+	nal_data->small_msg_size = gmnal_small_msg_size;
+	nal_data->small_msg_gmsize = 
+			gm_min_size_for_length(gmnal_small_msg_size);
+
+	if (gmnal_alloc_srxd(nal_data) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "Failed to allocate small rx descriptors\n");
+		gmnal_free_txd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+
+	/*
+ 	 *	Hang out a bunch of small receive buffers
+	 *	In fact hang them all out
+	 */
+	while((srxd = gmnal_get_srxd(nal_data, 0))) {
+		CDEBUG(D_NET, "giving [%p] to gm_provide_recvive_buffer\n", 
+		       srxd->buffer);
+		GMNAL_GM_LOCK(nal_data);
+		gm_provide_receive_buffer_with_tag(nal_data->gm_port, 
+						   srxd->buffer, srxd->gmsize, 
+						   GM_LOW_PRIORITY, 0);
+		GMNAL_GM_UNLOCK(nal_data);
+	}
+	
+	/*
+	 *	Allocate pools of small tx buffers and descriptors
+	 */
+	if (gmnal_alloc_txd(nal_data) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "Failed to allocate small tx descriptors\n");
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+	gmnal_start_kernel_threads(nal_data);
+
+	while (nal_data->rxthread_flag != GMNAL_RXTHREADS_STARTED) {
+		gmnal_yield(1);
+		CDEBUG(D_INFO, "Waiting for receive thread signs of life\n");
+	}
+
+	CDEBUG(D_INFO, "receive thread seems to have started\n");
+
+
+	/*
+	 *	Initialise the portals library
+	 */
+	CDEBUG(D_NET, "Getting node id\n");
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		CDEBUG(D_ERROR, "can't determine node id\n");
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+	nal_data->gm_local_nid = local_nid;
+	CDEBUG(D_INFO, "Local node id is [%u]\n", local_nid);
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, 
+					    &global_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "failed to obtain global id\n");
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+	CDEBUG(D_INFO, "Global node id is [%u]\n", global_nid);
+	nal_data->gm_global_nid = global_nid;
+
+/*
+	pid = gm_getpid();
+*/
+	CDEBUG(D_INFO, "portals_pid is [%u]\n", portals_pid);
+	portals_nid = (unsigned long)global_nid;
+	CDEBUG(D_INFO, "portals_nid is ["LPU64"]\n", portals_nid);
+	
+	CDEBUG(D_PORTALS, "calling lib_init\n");
+	if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, 
+		     ac_size) != PTL_OK) {
+		CDEBUG(D_ERROR, "lib_init failed\n");
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+		
+	}
+	
+	CDEBUG(D_INFO, "gmnal_init finished\n");
+	global_nal_data = nal->nal_data;
+	return(nal);
+}
+
+
+
+/*
+ *	Called when module removed
+ */
+void gmnal_fini()
+{
+	gmnal_data_t	*nal_data = global_nal_data;
+	nal_t		*nal = nal_data->nal;
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+
+	CDEBUG(D_TRACE, "gmnal_fini\n");
+
+	PtlNIFini(kgmnal_ni);
+	lib_fini(nal_cb);
+
+	gmnal_stop_rxthread(nal_data);
+	gmnal_stop_ctthread(nal_data);
+	gmnal_free_txd(nal_data);
+	gmnal_free_srxd(nal_data);
+	GMNAL_GM_LOCK(nal_data);
+	gm_close(nal_data->gm_port);
+	gm_finalize();
+	GMNAL_GM_UNLOCK(nal_data);
+	PORTAL_FREE(nal, sizeof(nal_t));	
+	PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+	PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+}
diff --git a/lnet/klnds/gmlnd/gmlnd_cb.c b/lnet/klnds/gmlnd/gmlnd_cb.c
index 3d4c86dac71a98bdd04f38c719b70d4895ea73d3..6ae91dbb44b158707adb0bb0916b9fa9fd669943 100644
--- a/lnet/klnds/gmlnd/gmlnd_cb.c
+++ b/lnet/klnds/gmlnd/gmlnd_cb.c
@@ -1,517 +1,271 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Based on ksocknal and qswnal
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
  *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *  Author: Robert Read  <rread@datarithm.net>
+ *   This file is part of Lustre, http://www.lustre.org/
  *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- *
- *   Portals is free software; you can redistribute it and/or
+ *   Lustre is free software; you can redistribute it and/or
  *   modify it under the terms of version 2 of the GNU General Public
  *   License as published by the Free Software Foundation.
  *
- *   Portals is distributed in the hope that it will be useful,
+ *   Lustre 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 Portals; if not, write to the Free Software
+ *   along with Lustre; if not, write to the Free Software
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* TODO
- * preallocate send buffers, store on list
- * put receive buffers on queue, handle with receive threads
- * use routing
- */
-
-#include "gmnal.h"
-
-extern kgmnal_rx_t *kgm_add_recv(kgmnal_data_t *,int);
-
-static kgmnal_tx_t *
-get_trans(void)
-{
-        kgmnal_tx_t *t;
-        PORTAL_ALLOC(t, (sizeof(kgmnal_tx_t)));
-        return t;
-}
-
-static void
-put_trans(kgmnal_tx_t *t)
-{
-        PORTAL_FREE(t, sizeof(kgmnal_tx_t));
-}
-
-int
-kgmnal_ispeer (ptl_nid_t nid)
-{
-   unsigned int gmnid = (unsigned int)nid;
-   unsigned int nnids;
-
-   gm_max_node_id_in_use(kgmnal_data.kgm_port, &nnids);
-
-   return ((ptl_nid_t)gmnid == nid &&/* didn't lose high bits on conversion ? */
-           gmnid < nnids); /* it's in this machine */
-}
 
 /*
- *  LIB functions follow
- *
+ *	This file implements the nal cb functions
  */
-static int
-kgmnal_read (nal_cb_t *nal, void *private, void *dst_addr, user_ptr src_addr,
-             size_t len)
-{
-        CDEBUG(D_NET, "0x%Lx: reading %ld bytes from %p -> %p\n",
-               nal->ni.nid, (long)len, src_addr, dst_addr );
-        memcpy( dst_addr, src_addr, len );
-        return 0;
-}
-
-static int
-kgmnal_write(nal_cb_t *nal, void *private, user_ptr dst_addr, void *src_addr,
-             size_t len)
-{
-        CDEBUG(D_NET, "0x%Lx: writing %ld bytes from %p -> %p\n",
-               nal->ni.nid, (long)len, src_addr, dst_addr );
-        memcpy( dst_addr, src_addr, len );
-        return 0;
-}
 
-static void *
-kgmnal_malloc(nal_cb_t *nal, size_t len)
-{
-        void *buf;
 
-        PORTAL_ALLOC(buf, len);
-        return buf;
-}
+#include "gmnal.h"
 
-static void
-kgmnal_free(nal_cb_t *nal, void *buf, size_t len)
+int gmnal_cb_recv(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		   unsigned int niov, struct iovec *iov, size_t mlen, 
+		   size_t rlen)
 {
-        PORTAL_FREE(buf, len);
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	int		status = PTL_OK;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_recv nal_cb [%p], private[%p], cookie[%p], 
+	       niov[%d], iov [%p], mlen["LPSZ"], rlen["LPSZ"]\n", 
+	       nal_cb, private, cookie, niov, iov, mlen, rlen);
+
+	switch(srxd->type) {
+	case(GMNAL_SMALL_MESSAGE):
+		CDEBUG(D_INFO, "gmnal_cb_recv got small message\n");
+		status = gmnal_small_rx(nal_cb, private, cookie, niov, 
+				         iov, mlen, rlen);
+	break;
+	case(GMNAL_LARGE_MESSAGE_INIT):
+		CDEBUG(D_INFO, "gmnal_cb_recv got large message init\n");
+		status = gmnal_large_rx(nal_cb, private, cookie, niov, 
+					 iov, mlen, rlen);
+	}
+		
+
+	CDEBUG(D_INFO, "gmnal_cb_recv gmnal_return status [%d]\n", status);
+	return(status);
 }
 
-static void
-kgmnal_printf(nal_cb_t *nal, const char *fmt, ...)
+int gmnal_cb_recv_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+			 unsigned int kniov, ptl_kiov_t *kiov, size_t mlen, 
+			 size_t rlen)
 {
-        va_list                ap;
-        char msg[256];
-
-        if (portal_debug & D_NET) {
-                va_start( ap, fmt );
-                vsnprintf( msg, sizeof(msg), fmt, ap );
-                va_end( ap );
-
-                printk("CPUId: %d %s",smp_processor_id(), msg);
-        }
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	int		status = PTL_OK;
+	struct iovec	*iovec = NULL, *iovec_dup = NULL;
+	int		i = 0;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_recv_pages nal_cb [%p],private[%p], 
+	       cookie[%p], kniov[%d], kiov [%p], mlen["LPSZ"], rlen["LPSZ"]\n",
+	       nal_cb, private, cookie, kniov, kiov, mlen, rlen);
+
+	if (srxd->type == GMNAL_SMALL_MESSAGE) {
+		PORTAL_ALLOC(iovec, sizeof(struct iovec)*kniov);
+		if (!iovec) {
+			CDEBUG(D_ERROR, "Can't malloc\n");
+			return(GMNAL_STATUS_FAIL);
+		}
+                iovec_dup = iovec;
+
+		/*
+		 *	map each page and create an iovec for it
+		 */
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+		 	       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+			iovec->iov_len = kiov->kiov_len;
+			CDEBUG(D_INFO, "Calling kmap[%p]", kiov->kiov_page);
+
+			iovec->iov_base = kmap(kiov->kiov_page) + 
+					          kiov->kiov_offset;
+
+			CDEBUG(D_INFO, "iov_base is [%p]\n", iovec->iov_base);
+                        iovec++;
+                        kiov++;
+		}
+		CDEBUG(D_INFO, "calling gmnal_small_rx\n");
+		status = gmnal_small_rx(nal_cb, private, cookie, kniov, 
+				         iovec_dup, mlen, rlen);
+		PORTAL_FREE(iovec_dup, sizeof(struct iovec)*kniov);
+	}
+		
+
+	CDEBUG(D_INFO, "gmnal_return status [%d]\n", status);
+	return(status);
 }
 
 
-static void
-kgmnal_cli(nal_cb_t *nal, unsigned long *flags)
+int gmnal_cb_send(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		   ptl_hdr_t *hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 
+		   unsigned int niov, struct iovec *iov, size_t len)
 {
-        kgmnal_data_t *data= nal->nal_data;
 
-        spin_lock_irqsave(&data->kgm_dispatch_lock,*flags);
+	gmnal_data_t	*nal_data;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_send niov[%d] len["LPSZ"] nid["LPU64"]\n", 
+	       niov, len, nid);
+	nal_data = nal_cb->nal_data;
+	
+	if (GMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, len)) {
+		CDEBUG(D_INFO, "This is a small message send\n");
+		gmnal_small_tx(nal_cb, private, cookie, hdr, type, nid, pid, 
+			       	niov, iov, len);
+	} else {
+		CDEBUG(D_ERROR, "Large message send it is not supported\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+		gmnal_large_tx(nal_cb, private, cookie, hdr, type, nid, pid, 
+				niov, iov, len);
+	}
+	return(PTL_OK);
 }
 
-
-static void
-kgmnal_sti(nal_cb_t *nal, unsigned long *flags)
+int gmnal_cb_send_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+			 ptl_hdr_t *hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 			 unsigned int kniov, ptl_kiov_t *kiov, size_t len)
 {
-        kgmnal_data_t *data= nal->nal_data;
-
-        spin_unlock_irqrestore(&data->kgm_dispatch_lock,*flags);
-}
-
 
-static int
-kgmnal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
-{
-        /* network distance doesn't mean much for this nal */
-        if ( nal->ni.nid == nid ) {
-                *dist = 0;
-        } else {
-                *dist = 1;
-        }
-
-        return 0;
+	int	i = 0;
+	gmnal_data_t	*nal_data;
+	struct	iovec 	*iovec = NULL, *iovec_dup = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_cb_send_pages nid ["LPU64"] niov[%d] len["LPSZ"]\n", nid, kniov, len);
+	nal_data = nal_cb->nal_data;
+	PORTAL_ALLOC(iovec, kniov*sizeof(struct iovec));
+        iovec_dup = iovec;
+	if (GMNAL_IS_SMALL_MESSAGE(nal_data, 0, NULL, len)) {
+		CDEBUG(D_INFO, "This is a small message send\n");
+		
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+			       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+
+			iovec->iov_base = kmap(kiov->kiov_page) 
+					        + kiov->kiov_offset;
+
+			iovec->iov_len = kiov->kiov_len;
+                        iovec++;
+                        kiov++;
+		}
+		gmnal_small_tx(nal_cb, private, cookie, hdr, type, nid, 
+				pid, kniov, iovec_dup, len);
+	} else {
+		CDEBUG(D_ERROR, "Large message send it is not supported yet\n");
+		return(PTL_FAIL);
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+			       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+
+			iovec->iov_base = kmap(kiov->kiov_page) 
+					         + kiov->kiov_offset;
+			iovec->iov_len = kiov->kiov_len;
+                        iovec++;
+                        kiov++;
+		}
+		gmnal_large_tx(nal_cb, private, cookie, hdr, type, nid, 
+				pid, kniov, iovec, len);
+	}
+	PORTAL_FREE(iovec_dup, kniov*sizeof(struct iovec));
+	return(PTL_OK);
 }
 
-/* FIXME rmr: add rounting code here */
-static void
-kgmnal_tx_done(kgmnal_tx_t  *trans, int error)
-{
-        lib_finalize(trans->ktx_nal, trans->ktx_private, trans->ktx_cookie);
-
-        gm_dma_free(kgmnal_data.kgm_port, trans->ktx_buffer);
-
-        trans->ktx_buffer = NULL;
-        trans->ktx_len = 0;
-
-        put_trans(trans);
-}
-static char * gm_error_strings[GM_NUM_STATUS_CODES] = {
-        [GM_SUCCESS] = "GM_SUCCESS",
-        [GM_SEND_TIMED_OUT] = "GM_SEND_TIMED_OUT",
-        [GM_SEND_REJECTED] = "GM_SEND_REJECTED",
-        [GM_SEND_TARGET_PORT_CLOSED] = "GM_SEND_TARGET_PORT_CLOSED",
-        [GM_SEND_TARGET_NODE_UNREACHABLE] = "GM_SEND_TARGET_NODE_UNREACHABLE",
-        [GM_SEND_DROPPED] = "GM_SEND_DROPPED",
-        [GM_SEND_PORT_CLOSED] = "GM_SEND_PORT_CLOSED",
-};
-
-inline char * get_error(int status)
+int gmnal_cb_read(nal_cb_t *nal_cb, void *private, void *dst, 
+		   user_ptr src, size_t len)
 {
-        if (gm_error_strings[status] != NULL)
-                return gm_error_strings[status];
-        else
-                return "Unknown error";
+	gm_bcopy(src, dst, len);
+	return(PTL_OK);
 }
 
-static void
-kgmnal_errhandler(struct gm_port *p, void *context, gm_status_t status)
+int gmnal_cb_write(nal_cb_t *nal_cb, void *private, user_ptr dst, 
+		    void *src, size_t len)
 {
-        CDEBUG(D_NET,"error callback: ktx %p status %d\n", context, status);
+	gm_bcopy(src, dst, len);
+	return(PTL_OK);
 }
 
-static void
-kgmnal_txhandler(struct gm_port *p, void *context, gm_status_t status)
+int gmnal_cb_callback(nal_cb_t *nal_cb, void *private, lib_eq_t *eq, 
+		       ptl_event_t *ev)
 {
-        kgmnal_tx_t *ktx = (kgmnal_tx_t *)context;
-        int err = 0;
-
-        LASSERT (p != NULL);
-        LASSERT (ktx != NULL);
-
-        CDEBUG(D_NET,"ktx %p status %d nid 0x%x pid %d\n", ktx, status,
-                ktx->ktx_tgt_node, ktx->ktx_tgt_port_id);
-
-        switch((int)status) {
-        case GM_SUCCESS:        /* normal */
-                break;
-        case GM_SEND_TIMED_OUT: /* application error */
-        case GM_SEND_REJECTED:  /* size of msg unacceptable */
-        case GM_SEND_TARGET_PORT_CLOSED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                gm_resume_sending(kgmnal_data.kgm_port, ktx->ktx_priority,
-                                  ktx->ktx_tgt_node, ktx->ktx_tgt_port_id,
-                                  kgmnal_errhandler, NULL);
-                err = -EIO;
-                break;
-        case GM_SEND_TARGET_NODE_UNREACHABLE:
-        case GM_SEND_PORT_CLOSED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                gm_drop_sends(kgmnal_data.kgm_port, ktx->ktx_priority,
-                              ktx->ktx_tgt_node, ktx->ktx_tgt_port_id,
-                              kgmnal_errhandler, NULL);
-                err = -EIO;
-                break;
-        case GM_SEND_DROPPED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                err = -EIO;
-                break;
-        default:
-                CERROR("Unknown status: %d\n", status);
-                err = -EIO;
-                break;
-        }
-
-        kgmnal_tx_done(ktx, err);
-}
-
-/*
- */
 
-static int
-kgmnal_send(nal_cb_t        *nal,
-           void            *private,
-           lib_msg_t       *cookie,
-           ptl_hdr_t       *hdr,
-           int              type,
-           ptl_nid_t        nid,
-           ptl_pid_t        pid,
-           int              options,
-           unsigned int     niov,
-           lib_md_iov_t    *iov,
-           size_t           len)
-{
-        /*
-         * ipnal assumes that this is the private as passed to lib_dispatch..
-         * so do we :/
-         */
-        kgmnal_tx_t *ktx=NULL;
-        int rc=0;
-        void * buf;
-        int buf_len = sizeof(ptl_hdr_t) + len;
-        int buf_size = 0;
-
-        LASSERT ((options & PTL_MD_KIOV) == 0);
-        
-        PROF_START(gmnal_send);
-
-
-        CDEBUG(D_NET, "sending %d bytes from %p to nid: 0x%Lx pid %d\n",
-               len, iov, nid, KGM_PORT_NUM);
-
-        /* ensure there is an available tx handle */
-
-        /* save transaction info to trans for later finalize and cleanup */
-        ktx = get_trans();
-        if (ktx == NULL) {
-                rc = -ENOMEM;
-                goto send_exit;
-        }
-
-        /* hmmm... GM doesn't support vectored write, so need to allocate buffer to coalesce
-           header and data.
-           Also, memory must be dma'able or registered with GM. */
-
-        if (buf_len <= MSG_LEN_SMALL) {
-                buf_size = MSG_SIZE_SMALL;
-        } else if (buf_len <= MSG_LEN_LARGE) {
-                buf_size = MSG_SIZE_LARGE;
-        } else {
-                printk("kgmnal:request exceeds TX MTU size (%d).\n",
-                       MSG_SIZE_LARGE);
-                rc = -1;
-                goto send_exit;
-        }
-
-               buf = gm_dma_malloc(kgmnal_data.kgm_port, buf_len);
-        if (buf == NULL) {
-                rc = -ENOMEM;
-                goto send_exit;
-        }
-        memcpy(buf, hdr, sizeof(ptl_hdr_t));
-
-        if (len != 0)
-                lib_copy_iov2buf(((char *)buf) + sizeof (ptl_hdr_t), 
-                                 options, niov, iov, len);
-
-        ktx->ktx_nal = nal;
-        ktx->ktx_private = private;
-        ktx->ktx_cookie = cookie;
-        ktx->ktx_len = buf_len;
-        ktx->ktx_size = buf_size;
-        ktx->ktx_buffer = buf;
-        ktx->ktx_priority = GM_LOW_PRIORITY;
-        ktx->ktx_tgt_node = nid;
-        ktx->ktx_tgt_port_id = KGM_PORT_NUM;
-
-        CDEBUG(D_NET, "gm_send %d bytes (size %d) from %p to nid: 0x%Lx "
-               "pid %d pri %d\n", buf_len, buf_size, iov, nid, KGM_PORT_NUM,
-               GM_LOW_PRIORITY);
-
-        gm_send_with_callback(kgmnal_data.kgm_port, buf, buf_size,
-                              buf_len, GM_LOW_PRIORITY,
-                              nid, KGM_PORT_NUM,
-                              kgmnal_txhandler, ktx);
-
-        PROF_FINISH(gmnal_send);
- send_exit:
-        return rc;
-}
-void
-kgmnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
-{
-        CERROR ("forwarding not implemented\n");
+	if (eq->event_callback != NULL) {
+		CDEBUG(D_INFO, "found callback\n");
+		eq->event_callback(ev);
+	}
+	
+	return(PTL_OK);
 }
 
-void
-kqswnal_fwd_callback (void *arg, int error)
+void *gmnal_cb_malloc(nal_cb_t *nal_cb, size_t len)
 {
-        CERROR ("forwarding not implemented\n");
+	void *ptr = NULL;
+	CDEBUG(D_TRACE, "gmnal_cb_malloc len["LPSZ"]\n", len);
+	PORTAL_ALLOC(ptr, len);
+	return(ptr);
 }
 
-
-static inline void
-kgmnal_requeue_rx(kgmnal_rx_t *krx)
+void gmnal_cb_free(nal_cb_t *nal_cb, void *buf, size_t len)
 {
-        gm_provide_receive_buffer(kgmnal_data.kgm_port, krx->krx_buffer,
-                                  krx->krx_size, krx->krx_priority);
+	CDEBUG(D_TRACE, "gmnal_cb_free :: buf[%p] len["LPSZ"]\n", buf, len);
+	PORTAL_FREE(buf, len);
+	return;
 }
 
-/* Process a received portals packet */
-
-/* Receive Interrupt Handler */
-static void kgmnal_rx(kgmnal_data_t *kgm, unsigned long len, unsigned int size,
-                      void * buf, unsigned int pri)
+void gmnal_cb_unmap(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, 
+		     void **addrkey)
 {
-        ptl_hdr_t  *hdr = buf;
-        kgmnal_rx_t krx;
-
-        CDEBUG(D_NET,"buf %p, len %ld\n", buf, len);
-
-        if ( len < sizeof( ptl_hdr_t ) ) {
-                /* XXX what's this for? */
-                if (kgm->kgm_shuttingdown)
-                        return;
-                CERROR("kgmnal: did not receive complete portal header, "
-                       "len= %ld", len);
-                gm_provide_receive_buffer(kgm->kgm_port, buf, size, pri);
-                return;
-        }
-
-       /* might want to use seperate threads to handle receive */
-        krx.krx_buffer = buf;
-        krx.krx_len = len;
-        krx.krx_size = size;
-        krx.krx_priority = pri;
-
-        if ( hdr->dest_nid == kgmnal_lib.ni.nid ) {
-                PROF_START(lib_parse);
-                lib_parse(&kgmnal_lib, (ptl_hdr_t *)krx.krx_buffer, &krx);
-                PROF_FINISH(lib_parse);
-        } else if (kgmnal_ispeer(hdr->dest_nid)) {
-                /* should have gone direct to peer */
-                CERROR("dropping packet from 0x%llx to 0x%llx: target is "
-                       "a peer", hdr->src_nid, hdr->dest_nid);
-                kgmnal_requeue_rx(&krx);
-        } else {
-                /* forward to gateway */
-                CERROR("forwarding not implemented yet");
-                kgmnal_requeue_rx(&krx);
-        }
-
-        return;
+	return;
 }
 
-
-static int kgmnal_recv(nal_cb_t     *nal,
-                      void         *private,
-                      lib_msg_t    *cookie,
-                      int           options,
-                      unsigned int  niov,
-                      lib_md_iov_t *iov,
-                      size_t        mlen,
-                      size_t        rlen)
+int  gmnal_cb_map(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, 
+		   void**addrkey)
 {
-        kgmnal_rx_t *krx = private;
-
-        LASSERT ((options & PTL_MD_KIOV) == 0);
-
-        CDEBUG(D_NET,"mlen=%d, rlen=%d\n", mlen, rlen);
-
-        /* What was actually received must be >= what sender claims to
-         * have sent.  This is an LASSERT, since lib-move doesn't
-         * check cb return code yet. */
-        LASSERT (krx->krx_len >= sizeof (ptl_hdr_t) + rlen);
-        LASSERT (mlen <= rlen);
-
-        PROF_START(gmnal_recv);
-
-        if(mlen != 0) {
-                PROF_START(memcpy);
-                lib_copy_buf2iov (options, niov, iov, 
-                                  krx->krx_buffer + sizeof (ptl_hdr_t), mlen);
-                PROF_FINISH(memcpy);
-        }
-
-        PROF_START(lib_finalize);
-        lib_finalize(nal, private, cookie);
-        PROF_FINISH(lib_finalize);
-
-        kgmnal_requeue_rx(krx);
-
-        PROF_FINISH(gmnal_recv);
-
-        return rlen;
+	return(PTL_OK);
 }
 
-
-static void kgmnal_shutdown(void * none)
+void gmnal_cb_printf(nal_cb_t *nal_cb, const char *fmt, ...)
 {
-        CERROR("called\n");
-        return;
+	CDEBUG(D_TRACE, "gmnal_cb_printf\n");
+	printk(fmt);
+	return;
 }
 
-/*
- * Set terminate and use alarm to wake up the recv thread.
- */
-static void  recv_shutdown(kgmnal_data_t *kgm)
+void gmnal_cb_cli(nal_cb_t *nal_cb, unsigned long *flags)
 {
-        gm_alarm_t alarm;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
 
-        kgm->kgm_shuttingdown = 1;
-        gm_initialize_alarm(&alarm);
-        gm_set_alarm(kgm->kgm_port, &alarm, 1, kgmnal_shutdown, NULL);
+	spin_lock_irqsave(&nal_data->cb_lock, *flags);
+	return;
 }
 
-int kgmnal_end(kgmnal_data_t *kgm)
+void gmnal_cb_sti(nal_cb_t *nal_cb, unsigned long *flags)
 {
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
 
-        /* wait for sends to finish ? */
-        /* remove receive buffers */
-        /* shutdown receive thread */
-
-        recv_shutdown(kgm);
-
-        return 0;
+	spin_unlock_irqrestore(&nal_data->cb_lock, *flags);
+	return;
 }
 
-/* Used only for the spinner */
-int kgmnal_recv_thread(void *arg)
+int gmnal_cb_dist(nal_cb_t *nal_cb, ptl_nid_t nid, unsigned long *dist)
 {
-        kgmnal_data_t *kgm = arg;
-
-        LASSERT(kgm != NULL);
-
-        kportal_daemonize("kgmnal_rx");
-        
-        while(1) {
-                gm_recv_event_t *e;
-                int priority = GM_LOW_PRIORITY;
-                if (kgm->kgm_shuttingdown)
-                        break;
-
-                e = gm_blocking_receive_no_spin(kgm->kgm_port);
-                if (e == NULL) {
-                        CERROR("gm_blocking_receive returned NULL\n");
-                        break;
-                }
-
-                switch(gm_ntohc(e->recv.type)) {
-                case GM_HIGH_RECV_EVENT:
-                        priority = GM_HIGH_PRIORITY;
-                        /* fall through */
-                case GM_RECV_EVENT:
-                        kgmnal_rx(kgm, gm_ntohl(e->recv.length),
-                                  gm_ntohc(e->recv.size),
-                                  gm_ntohp(e->recv.buffer), priority);
-                        break;
-                case GM_ALARM_EVENT:
-                        CERROR("received alarm");
-                        gm_unknown(kgm->kgm_port, e);
-                        break;
-                case GM_BAD_SEND_DETECTED_EVENT: /* ?? */
-                        CERROR("received bad send!\n");
-                        break;
-                default:
-                        gm_unknown(kgm->kgm_port, e);
-                }
-        }
-
-        CERROR("shuttting down.\n");
-        return 0;
+	CDEBUG(D_TRACE, "gmnal_cb_dist\n");
+	if (dist)
+		*dist = 27;
+	return(PTL_OK);
 }
-
-nal_cb_t kgmnal_lib = {
-        nal_data: &kgmnal_data,                /* NAL private data */
-        cb_send: kgmnal_send,
-        cb_recv: kgmnal_recv,
-        cb_read: kgmnal_read,
-        cb_write: kgmnal_write,
-        cb_malloc: kgmnal_malloc,
-        cb_free: kgmnal_free,
-        cb_printf: kgmnal_printf,
-        cb_cli: kgmnal_cli,
-        cb_sti: kgmnal_sti,
-        cb_dist: kgmnal_dist
-};
diff --git a/lnet/klnds/gmlnd/gmlnd_comm.c b/lnet/klnds/gmlnd/gmlnd_comm.c
new file mode 100644
index 0000000000000000000000000000000000000000..4171df669f481d76c17b0c742806564d0e21ced7
--- /dev/null
+++ b/lnet/klnds/gmlnd/gmlnd_comm.c
@@ -0,0 +1,1319 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *	This file contains all gmnal send and receive functions
+ */
+
+#include "gmnal.h"
+
+/*
+ *	The caretaker thread
+ *	This is main thread of execution for the NAL side
+ *	This guy waits in gm_blocking_recvive and gets
+ *	woken up when the myrinet adaptor gets an interrupt.
+ *	Hands off receive operations to the receive thread 
+ *	This thread Looks after gm_callbacks etc inline.
+ */
+int
+gmnal_ct_thread(void *arg)
+{
+	gmnal_data_t		*nal_data;
+	gm_recv_event_t		*rxevent = NULL;
+	gm_recv_t		*recv = NULL;
+
+	if (!arg) {
+		CDEBUG(D_TRACE, "NO nal_data. Exiting\n");
+		return(-1);
+	}
+
+	nal_data = (gmnal_data_t*)arg;
+	CDEBUG(D_TRACE, "nal_data is [%p]\n", arg);
+
+	daemonize();
+
+	nal_data->ctthread_flag = GMNAL_CTTHREAD_STARTED;
+
+	GMNAL_GM_LOCK(nal_data);
+	while(nal_data->ctthread_flag == GMNAL_CTTHREAD_STARTED) {
+		CDEBUG(D_NET, "waiting\n");
+		rxevent = gm_blocking_receive_no_spin(nal_data->gm_port);
+		if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+			CDEBUG(D_INFO, "time to exit\n");
+			break;
+		}
+		CDEBUG(D_INFO, "got [%s]\n", gmnal_rxevent(rxevent));
+		switch (GM_RECV_EVENT_TYPE(rxevent)) {
+
+			case(GM_RECV_EVENT):
+				CDEBUG(D_NET, "CTTHREAD:: GM_RECV_EVENT\n");
+				recv = (gm_recv_t*)&rxevent->recv;
+				GMNAL_GM_UNLOCK(nal_data);
+				gmnal_add_rxtwe(nal_data, recv);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_NET, "CTTHREAD:: Added event to Q\n");
+			break;
+			case(_GM_SLEEP_EVENT):
+				/*
+				 *	Blocking receive above just returns
+				 *	immediatly with _GM_SLEEP_EVENT
+				 *	Don't know what this is
+				 */
+				CDEBUG(D_NET, "Sleeping in gm_unknown\n");
+				GMNAL_GM_UNLOCK(nal_data);
+				gm_unknown(nal_data->gm_port, rxevent);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_INFO, "Awake from gm_unknown\n");
+				break;
+				
+			default:
+				/*
+				 *	Don't know what this is
+				 *	gm_unknown will make sense of it
+				 *	Should be able to do something with
+				 *	FAST_RECV_EVENTS here.
+				 */
+				CDEBUG(D_NET, "Passing event to gm_unknown\n");
+				GMNAL_GM_UNLOCK(nal_data);
+				gm_unknown(nal_data->gm_port, rxevent);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_INFO, "Processed unknown event\n");
+		}
+	}
+	GMNAL_GM_UNLOCK(nal_data);
+	nal_data->ctthread_flag = GMNAL_THREAD_RESET;
+	CDEBUG(D_INFO, "thread nal_data [%p] is exiting\n", nal_data);
+	return(GMNAL_STATUS_OK);
+}
+
+
+/*
+ *	process a receive event
+ */
+int gmnal_rx_thread(void *arg)
+{
+	gmnal_data_t		*nal_data;
+	void			*buffer;
+	gmnal_rxtwe_t		*we = NULL;
+
+	if (!arg) {
+		CDEBUG(D_TRACE, "NO nal_data. Exiting\n");
+		return(-1);
+	}
+
+	nal_data = (gmnal_data_t*)arg;
+	CDEBUG(D_TRACE, "nal_data is [%p]\n", arg);
+
+	daemonize();
+	/*
+	 * 	set 1 bit for each thread started
+	 *	doesn't matter which bit
+	 */
+	spin_lock(&nal_data->rxthread_flag_lock);
+	if (nal_data->rxthread_flag)
+		nal_data->rxthread_flag=nal_data->rxthread_flag*2 + 1;
+	else
+		nal_data->rxthread_flag = 1;
+	CDEBUG(D_INFO, "rxthread flag is [%ld]\n", nal_data->rxthread_flag);
+	spin_unlock(&nal_data->rxthread_flag_lock);
+
+	while(nal_data->rxthread_stop_flag != GMNAL_THREAD_STOP) {
+		CDEBUG(D_NET, "RXTHREAD:: Receive thread waiting\n");
+		we = gmnal_get_rxtwe(nal_data);
+		if (!we) {
+			CDEBUG(D_INFO, "Receive thread time to exit\n");
+			break;
+		}
+
+		buffer = we->buffer;
+		switch(((gmnal_msghdr_t*)buffer)->type) {
+		case(GMNAL_SMALL_MESSAGE):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_SMALL_MESSAGE);
+		break;	
+		case(GMNAL_LARGE_MESSAGE_INIT):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_LARGE_MESSAGE_INIT);
+		break;	
+		case(GMNAL_LARGE_MESSAGE_ACK):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_LARGE_MESSAGE_ACK);
+		break;	
+		default:
+			CDEBUG(D_ERROR, "Unsupported message type\n");
+			gmnal_rx_bad(nal_data, we, NULL);
+		}
+		PORTAL_FREE(we, sizeof(gmnal_rxtwe_t));
+	}
+
+	spin_lock(&nal_data->rxthread_flag_lock);
+	nal_data->rxthread_flag/=2;
+	CDEBUG(D_INFO, "rxthread flag is [%ld]\n", nal_data->rxthread_flag);
+	spin_unlock(&nal_data->rxthread_flag_lock);
+	CDEBUG(D_INFO, "thread nal_data [%p] is exiting\n", nal_data);
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	Start processing a small message receive
+ *	Get here from gmnal_receive_thread
+ *	Hand off to lib_parse, which calls cb_recv
+ *	which hands back to gmnal_small_receive
+ *	Deal with all endian stuff here.
+ */
+int
+gmnal_pre_receive(gmnal_data_t *nal_data, gmnal_rxtwe_t *we, int gmnal_type)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	void		*buffer = NULL;
+	unsigned int snode, sport, type, length;
+	gmnal_msghdr_t	*gmnal_msghdr;
+	ptl_hdr_t	*portals_hdr;
+
+	CDEBUG(D_INFO, "nal_data [%p], we[%p] type [%d]\n", 
+	       nal_data, we, gmnal_type);
+
+	buffer = we->buffer;
+	snode = we->snode;
+	sport = we->sport;
+	type = we->type;
+	buffer = we->buffer;
+	length = we->length;
+
+	gmnal_msghdr = (gmnal_msghdr_t*)buffer;
+	portals_hdr = (ptl_hdr_t*)(buffer+GMNAL_MSGHDR_SIZE);
+
+	CDEBUG(D_INFO, "rx_event:: Sender node [%d], Sender Port [%d], 
+	       type [%d], length [%d], buffer [%p]\n",
+	       snode, sport, type, length, buffer);
+	CDEBUG(D_INFO, "gmnal_msghdr:: Sender node [%u], magic [%d], 
+	       gmnal_type [%d]\n", gmnal_msghdr->sender_node_id, 
+	       gmnal_msghdr->magic, gmnal_msghdr->type);
+	CDEBUG(D_INFO, "portals_hdr:: Sender node ["LPD64"], 
+	       dest_node ["LPD64"]\n", portals_hdr->src_nid, 
+	       portals_hdr->dest_nid);
+
+	
+	/*
+ 	 *	Get a receive descriptor for this message
+	 */
+	srxd = gmnal_rxbuffer_to_srxd(nal_data, buffer);
+	CDEBUG(D_INFO, "Back from gmnal_rxbuffer_to_srxd\n");
+	srxd->nal_data = nal_data;
+	if (!srxd) {
+		CDEBUG(D_ERROR, "Failed to get receive descriptor\n");
+		lib_parse(nal_data->nal_cb, portals_hdr, srxd);
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	/*
+ 	 *	no need to bother portals library with this
+	 */
+	if (gmnal_type == GMNAL_LARGE_MESSAGE_ACK) {
+		gmnal_large_tx_ack_received(nal_data, srxd);
+		return(GMNAL_STATUS_OK);
+	}
+
+	srxd->type = gmnal_type;
+	srxd->nsiov = gmnal_msghdr->niov;
+	srxd->gm_source_node = gmnal_msghdr->sender_node_id;
+	
+	CDEBUG(D_PORTALS, "Calling lib_parse buffer is [%p]\n", 
+	       buffer+GMNAL_MSGHDR_SIZE);
+	/*
+ 	 *	control passes to lib, which calls cb_recv 
+	 *	cb_recv is responsible for returning the buffer 
+	 *	for future receive
+	 */
+	lib_parse(nal_data->nal_cb, portals_hdr, srxd);
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	After a receive has been processed, 
+ *	hang out the receive buffer again.
+ *	This implicitly returns a receive token.
+ */
+int
+gmnal_rx_requeue_buffer(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+	CDEBUG(D_TRACE, "gmnal_rx_requeue_buffer\n");
+
+	CDEBUG(D_NET, "requeueing srxd[%p] nal_data[%p]\n", srxd, nal_data);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer,
+					srxd->gmsize, GM_LOW_PRIORITY, 0 );
+	GMNAL_GM_UNLOCK(nal_data);
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+/*
+ *	Handle a bad message
+ *	A bad message is one we don't expect or can't interpret
+ */
+int
+gmnal_rx_bad(gmnal_data_t *nal_data, gmnal_rxtwe_t *we, gmnal_srxd_t *srxd)
+{
+	CDEBUG(D_TRACE, "Can't handle message\n");
+
+	if (!srxd)
+		srxd = gmnal_rxbuffer_to_srxd(nal_data, 
+					       we->buffer);
+	if (srxd) {
+		gmnal_rx_requeue_buffer(nal_data, srxd);
+	} else {
+		CDEBUG(D_ERROR, "Can't find a descriptor for this buffer\n");
+		/*
+		 *	get rid of it ?
+		 */
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	Process a small message receive.
+ *	Get here from gmnal_receive_thread, gmnal_pre_receive
+ *	lib_parse, cb_recv
+ *	Put data from prewired receive buffer into users buffer(s)
+ *	Hang out the receive buffer again for another receive
+ *	Call lib_finalize
+ */
+int
+gmnal_small_rx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		unsigned int niov, struct iovec *iov, size_t mlen, size_t rlen)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	void	*buffer = NULL;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
+
+
+	CDEBUG(D_TRACE, "niov [%d] mlen["LPSZ"]\n", niov, mlen);
+
+	if (!private) {
+		CDEBUG(D_ERROR, "gmnal_small_rx no context\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+	}
+
+	srxd = (gmnal_srxd_t*)private;
+	buffer = srxd->buffer;
+	buffer += sizeof(gmnal_msghdr_t);
+	buffer += sizeof(ptl_hdr_t);
+
+	while(niov--) {
+		CDEBUG(D_INFO, "processing [%p] len ["LPSZ"]\n", iov, 
+		       iov->iov_len);
+		gm_bcopy(buffer, iov->iov_base, iov->iov_len);			
+		buffer += iov->iov_len;
+		iov++;
+	}
+
+
+	/*
+ 	 *	let portals library know receive is complete
+	 */
+	CDEBUG(D_PORTALS, "calling lib_finalize\n");
+	if (lib_finalize(nal_cb, private, cookie) != PTL_OK) {
+		/* TO DO what to do with failed lib_finalise? */
+		CDEBUG(D_INFO, "lib_finalize failed\n");
+	}
+	/*
+	 *	return buffer so it can be used again
+	 */
+	CDEBUG(D_NET, "calling gm_provide_receive_buffer\n");
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
+					   srxd->gmsize, GM_LOW_PRIORITY, 0);	
+	GMNAL_GM_UNLOCK(nal_data);
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	Start a small transmit. 
+ *	Get a send token (and wired transmit buffer).
+ *	Copy data from senders buffer to wired buffer and
+ *	initiate gm_send from the wired buffer.
+ *	The callback function informs when the send is complete.
+ */
+int
+gmnal_small_tx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		ptl_hdr_t *hdr, int type, ptl_nid_t global_nid, ptl_pid_t pid, 
+		unsigned int niov, struct iovec *iov, int size)
+{
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
+	gmnal_stxd_t	*stxd = NULL;
+	void		*buffer = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	int		tot_size = 0;
+	unsigned int	local_nid;
+	gm_status_t	gm_status = GM_SUCCESS;
+
+	CDEBUG(D_TRACE, "gmnal_small_tx nal_cb [%p] private [%p] cookie [%p] 
+	       hdr [%p] type [%d] global_nid ["LPU64"] pid [%d] niov [%d] 
+	       iov [%p] size [%d]\n", nal_cb, private, cookie, hdr, type, 
+	       global_nid, pid, niov, iov, size);
+
+	CDEBUG(D_INFO, "portals_hdr:: dest_nid ["LPU64"], src_nid ["LPU64"]\n",
+	       hdr->dest_nid, hdr->src_nid);
+
+	if (!nal_data) {
+		CDEBUG(D_ERROR, "no nal_data\n");
+		return(GMNAL_STATUS_FAIL);
+	} else {
+		CDEBUG(D_INFO, "nal_data [%p]\n", nal_data);
+	}
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, 
+					    &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%u][%x]\n", local_nid, local_nid);
+
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_INFO, "stxd [%p]\n", stxd);
+
+	stxd->type = GMNAL_SMALL_MESSAGE;
+	stxd->cookie = cookie;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the data in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_SMALL_MESSAGE;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	buffer += sizeof(gmnal_msghdr_t);
+
+	CDEBUG(D_INFO, "processing  portals hdr at [%p]\n", buffer);
+	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
+
+	buffer += sizeof(ptl_hdr_t);
+
+	while(niov--) {
+		CDEBUG(D_INFO, "processing iov [%p] len ["LPSZ"] to [%p]\n", 
+		       iov, iov->iov_len, buffer);
+		gm_bcopy(iov->iov_base, buffer, iov->iov_len);
+		buffer+= iov->iov_len;
+		iov++;
+	}
+
+	CDEBUG(D_INFO, "sending\n");
+	tot_size = size+sizeof(ptl_hdr_t)+sizeof(gmnal_msghdr_t);
+	stxd->msg_size = tot_size;
+
+
+	CDEBUG(D_NET, "Calling gm_send_to_peer port [%p] buffer [%p] 
+   	       gmsize [%lu] msize [%d] global_nid ["LPU64"] local_nid[%d] 
+	       stxd [%p]\n", nal_data->gm_port, stxd->buffer, stxd->gm_size, 
+	       stxd->msg_size, global_nid, local_nid, stxd);
+
+	GMNAL_GM_LOCK(nal_data);
+	stxd->gm_priority = GM_LOW_PRIORITY;
+	stxd->gm_target_node = local_nid;
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, stxd->msg_size, 
+				      GM_LOW_PRIORITY, local_nid, 
+				      gmnal_small_tx_callback, (void*)stxd);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "done\n");
+		
+	return(PTL_OK);
+}
+
+
+/*
+ *	A callback to indicate the small transmit operation is compete
+ *	Check for erros and try to deal with them.
+ *	Call lib_finalise to inform the client application that the send 
+ *	is complete and the memory can be reused.
+ *	Return the stxd when finished with it (returns a send token)
+ */
+void 
+gmnal_small_tx_callback(gm_port_t *gm_port, void *context, gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	lib_msg_t	*cookie = stxd->cookie;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)stxd->nal_data;
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+
+	if (!stxd) {
+		CDEBUG(D_TRACE, "send completion event for unknown stxd\n");
+		return;
+	}
+	if (status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Result of send stxd [%p] is [%s]\n", 
+		       stxd, gmnal_gm_error(status));
+	}
+
+	switch(status) {
+  		case(GM_SUCCESS):
+		break;
+
+
+
+  		case(GM_SEND_DROPPED):
+		/*
+		 *	do a resend on the dropped ones
+		 */
+			CDEBUG(D_ERROR, "send stxd [%p] was dropped 
+			       resending\n", context);
+			GMNAL_GM_LOCK(nal_data);
+			gm_send_to_peer_with_callback(nal_data->gm_port, 
+						      stxd->buffer, 
+						      stxd->gm_size, 
+						      stxd->msg_size, 
+						      stxd->gm_priority, 
+						      stxd->gm_target_node, 
+						      gmnal_small_tx_callback,
+						      context);
+			GMNAL_GM_UNLOCK(nal_data);
+		
+		return;
+  		case(GM_TIMED_OUT):
+  		case(GM_SEND_TIMED_OUT):
+		/*
+		 *	drop these ones
+		 */
+			CDEBUG(D_INFO, "calling gm_drop_sends\n");
+			GMNAL_GM_LOCK(nal_data);
+			gm_drop_sends(nal_data->gm_port, stxd->gm_priority, 
+				      stxd->gm_target_node, GMNAL_GM_PORT, 
+				      gmnal_drop_sends_callback, context);
+			GMNAL_GM_UNLOCK(nal_data);
+
+		return;
+
+
+		/*
+		 *	abort on these ?
+		 */
+  		case(GM_TRY_AGAIN):
+  		case(GM_INTERRUPTED):
+  		case(GM_FAILURE):
+  		case(GM_INPUT_BUFFER_TOO_SMALL):
+  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
+  		case(GM_BUSY):
+  		case(GM_MEMORY_FAULT):
+  		case(GM_INVALID_PARAMETER):
+  		case(GM_OUT_OF_MEMORY):
+  		case(GM_INVALID_COMMAND):
+  		case(GM_PERMISSION_DENIED):
+  		case(GM_INTERNAL_ERROR):
+  		case(GM_UNATTACHED):
+  		case(GM_UNSUPPORTED_DEVICE):
+  		case(GM_SEND_REJECTED):
+  		case(GM_SEND_TARGET_PORT_CLOSED):
+  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
+  		case(GM_SEND_PORT_CLOSED):
+  		case(GM_NODE_ID_NOT_YET_SET):
+  		case(GM_STILL_SHUTTING_DOWN):
+  		case(GM_CLONE_BUSY):
+  		case(GM_NO_SUCH_DEVICE):
+  		case(GM_ABORTED):
+  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
+  		case(GM_ACCESS_DENIED):
+  		case(GM_NO_DRIVER_SUPPORT):
+  		case(GM_PTE_REF_CNT_OVERFLOW):
+  		case(GM_NOT_SUPPORTED_IN_KERNEL):
+  		case(GM_NOT_SUPPORTED_ON_ARCH):
+  		case(GM_NO_MATCH):
+  		case(GM_USER_ERROR):
+  		case(GM_DATA_CORRUPTED):
+  		case(GM_HARDWARE_FAULT):
+  		case(GM_SEND_ORPHANED):
+  		case(GM_MINOR_OVERFLOW):
+  		case(GM_PAGE_TABLE_FULL):
+  		case(GM_UC_ERROR):
+  		case(GM_INVALID_PORT_NUMBER):
+  		case(GM_DEV_NOT_FOUND):
+  		case(GM_FIRMWARE_NOT_RUNNING):
+  		case(GM_YP_NO_MATCH):
+		default:
+			CDEBUG(D_ERROR, "Unknown send error\n");
+	}
+
+	/*
+	 *	TO DO
+	 *	If this is a large message init,
+	 *	we're not finished with the data yet,
+	 *	so can't call lib_finalise.
+	 *	However, we're also holding on to a 
+	 *	stxd here (to keep track of the source
+	 *	iovec only). Should use another structure
+	 *	to keep track of iovec and return stxd to 
+	 *	free list earlier.
+	 */
+	if (stxd->type == GMNAL_LARGE_MESSAGE_INIT) {
+		CDEBUG(D_INFO, "large transmit done\n");
+		return;
+	}
+	gmnal_return_stxd(nal_data, stxd);
+	if (lib_finalize(nal_cb, stxd, cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for stxd [%p]\n", 
+		       stxd);
+	}
+	return;
+}
+
+
+
+void gmnal_drop_sends_callback(struct gm_port *gm_port, void *context, 
+			        gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	gmnal_data_t	*nal_data = stxd->nal_data;
+
+	CDEBUG(D_TRACE, "status is [%d] context is [%p]\n", status, context);
+	if (status == GM_SUCCESS) {
+		GMNAL_GM_LOCK(nal_data);
+		gm_send_to_peer_with_callback(gm_port, stxd->buffer, 
+					      stxd->gm_size, stxd->msg_size, 
+					      stxd->gm_priority, 
+					      stxd->gm_target_node, 
+					      gmnal_small_tx_callback, 
+					      context);
+		GMNAL_GM_LOCK(nal_data);
+	} else {
+		CDEBUG(D_ERROR, "send_to_peer status for stxd [%p] is 
+		       [%d][%s]\n", stxd, status, gmnal_gm_error(status));
+	}
+
+
+	return;
+}
+
+
+/*
+ *	Begine a large transmit.
+ *	Do a gm_register of the memory pointed to by the iovec 
+ *	and send details to the receiver. The receiver does a gm_get
+ *	to pull the data and sends and ack when finished. Upon receipt of
+ *	this ack, deregister the memory. Only 1 send token is required here.
+ */
+int
+gmnal_large_tx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+	        ptl_hdr_t *hdr, int type, ptl_nid_t global_nid, ptl_pid_t pid, 
+		unsigned int niov, struct iovec *iov, int size)
+{
+
+	gmnal_data_t	*nal_data;
+	gmnal_stxd_t	*stxd = NULL;
+	void		*buffer = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	unsigned int	local_nid;
+	int		mlen = 0;	/* the size of the init message data */
+	struct iovec	*iov_dup = NULL;
+	gm_status_t	gm_status;
+	int		niov_dup;
+
+
+	CDEBUG(D_TRACE, "gmnal_large_tx nal_cb [%p] private [%p], cookie [%p] 
+	       hdr [%p], type [%d] global_nid ["LPU64"], pid [%d], niov [%d], 
+	       iov [%p], size [%d]\n", nal_cb, private, cookie, hdr, type, 
+	       global_nid, pid, niov, iov, size);
+
+	if (nal_cb)
+		nal_data = (gmnal_data_t*)nal_cb->nal_data;
+	else  {
+		CDEBUG(D_ERROR, "no nal_cb.\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	
+
+	/*
+	 *	Get stxd and buffer. Put local address of data in buffer, 
+	 *	send local addresses to target, 
+	 *	wait for the target node to suck the data over.
+	 *	The stxd is used to ren
+	 */
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_INFO, "stxd [%p]\n", stxd);
+
+	stxd->type = GMNAL_LARGE_MESSAGE_INIT;
+	stxd->cookie = cookie;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the iov in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_LARGE_MESSAGE_INIT;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	msghdr->stxd = stxd;
+	msghdr->niov = niov ;
+	buffer += sizeof(gmnal_msghdr_t);
+	mlen = sizeof(gmnal_msghdr_t);
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+
+	CDEBUG(D_INFO, "processing  portals hdr at [%p]\n", buffer);
+
+	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
+	buffer += sizeof(ptl_hdr_t);
+	mlen += sizeof(ptl_hdr_t); 
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+	/*
+	 *	copy the iov to the buffer so target knows 
+	 *	where to get the data from
+	 */
+	CDEBUG(D_INFO, "processing iov to [%p]\n", buffer);
+	gm_bcopy(iov, buffer, niov*sizeof(struct iovec));
+	mlen += niov*(sizeof(struct iovec));
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+
+	/*
+	 *	Store the iovs in the stxd for we can get 
+	 *	them later if we need them
+	 */
+	CDEBUG(D_NET, "Copying iov [%p] to [%p]\n", iov, stxd->iov);
+	gm_bcopy(iov, stxd->iov, niov*sizeof(struct iovec));
+	stxd->niov = niov;
+	
+
+	/*
+	 *	register the memory so the NIC can get hold of the data
+	 *	This is a slow process. it'd be good to overlap it 
+	 *	with something else.
+	 */
+	iov_dup = iov;
+	niov_dup = niov;
+	while(niov--) {
+		CDEBUG(D_INFO, "Registering memory [%p] len ["LPSZ"] \n", 
+		       iov->iov_base, iov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, 
+					       iov->iov_base, iov->iov_len);
+		if (gm_status != GM_SUCCESS) {
+			GMNAL_GM_UNLOCK(nal_data);
+			CDEBUG(D_ERROR, "gm_register_memory returns [%d][%s] 
+			       for memory [%p] len ["LPSZ"]\n", 
+			       gm_status, gmnal_gm_error(gm_status), 
+			       iov->iov_base, iov->iov_len);
+			GMNAL_GM_LOCK(nal_data);
+			while (iov_dup != iov) {
+				gm_deregister_memory(nal_data->gm_port, 
+						     iov_dup->iov_base, 
+						     iov_dup->iov_len);
+				iov_dup++;
+			}
+			GMNAL_GM_UNLOCK(nal_data);
+			gmnal_return_stxd(nal_data, stxd);
+			return(PTL_FAIL);
+		}
+
+		GMNAL_GM_UNLOCK(nal_data);
+		iov++;
+	}
+
+	/*
+ 	 *	Send the init message to the target
+	 */
+	CDEBUG(D_INFO, "sending mlen [%d]\n", mlen);
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, 
+					    &local_nid);
+	if (gm_status != GM_SUCCESS) {
+		GMNAL_GM_UNLOCK(nal_data);
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		gmnal_return_stxd(nal_data, stxd);
+		/* TO DO deregister memory on failure */
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%d]\n", local_nid);
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, mlen, GM_LOW_PRIORITY, 
+				      local_nid, gmnal_large_tx_callback, 
+				      (void*)stxd);
+	GMNAL_GM_UNLOCK(nal_data);
+	
+	CDEBUG(D_INFO, "done\n");
+		
+	return(PTL_OK);
+}
+
+/*
+ *	Callback function indicates that send of buffer with 
+ *	large message iovec has completed (or failed).
+ */
+void 
+gmnal_large_tx_callback(gm_port_t *gm_port, void *context, gm_status_t status)
+{
+	gmnal_small_tx_callback(gm_port, context, status);
+
+}
+
+
+
+/*
+ *	Have received a buffer that contains an iovec of the sender. 
+ *	Do a gm_register_memory of the receivers buffer and then do a get
+ *	data from the sender.
+ */
+int
+gmnal_large_rx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		unsigned int nriov, struct iovec *riov, size_t mlen, 
+		size_t rlen)
+{
+	gmnal_data_t	*nal_data = nal_cb->nal_data;
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	void		*buffer = NULL;
+	struct	iovec	*riov_dup;
+	int		nriov_dup;
+	gmnal_msghdr_t	*msghdr = NULL;
+	gm_status_t	gm_status;
+
+	CDEBUG(D_TRACE, "gmnal_large_rx :: nal_cb[%p], private[%p], 
+	       cookie[%p], niov[%d], iov[%p], mlen["LPSZ"], rlen["LPSZ"]\n",
+		nal_cb, private, cookie, nriov, riov, mlen, rlen);
+
+	if (!srxd) {
+		CDEBUG(D_ERROR, "gmnal_large_rx no context\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+	}
+
+	buffer = srxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+	buffer += sizeof(gmnal_msghdr_t);
+	buffer += sizeof(ptl_hdr_t);
+
+	/*
+	 *	Store the senders stxd address in the srxd for this message
+	 *	The gmnal_large_message_ack needs it to notify the sender
+	 *	the pull of data is complete
+	 */
+	srxd->source_stxd = msghdr->stxd;
+
+	/*
+	 *	Register the receivers memory
+	 *	get the data,
+	 *	tell the sender that we got the data
+	 *	then tell the receiver we got the data
+	 *	TO DO
+	 *	If the iovecs match, could interleave 
+	 *	gm_registers and gm_gets for each element
+	 */
+	nriov_dup = nriov;
+	riov_dup = riov;
+	while(nriov--) {
+		CDEBUG(D_INFO, "Registering memory [%p] len ["LPSZ"] \n", 
+		       riov->iov_base, riov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, 
+					       riov->iov_base, riov->iov_len);
+		if (gm_status != GM_SUCCESS) {
+			GMNAL_GM_UNLOCK(nal_data);
+			CDEBUG(D_ERROR, "gm_register_memory returns [%d][%s] 
+			       for memory [%p] len ["LPSZ"]\n", 
+			       gm_status, gmnal_gm_error(gm_status), 
+			       riov->iov_base, riov->iov_len);
+			GMNAL_GM_LOCK(nal_data);
+			while (riov_dup != riov) {
+				gm_deregister_memory(nal_data->gm_port, 
+						     riov_dup->iov_base, 
+						     riov_dup->iov_len);
+				riov_dup++;
+			}
+			GMNAL_GM_LOCK(nal_data);
+			/*
+			 *	give back srxd and buffer. Send NACK to sender
+			 */
+			return(PTL_FAIL);
+		}
+		GMNAL_GM_UNLOCK(nal_data);
+		riov++;
+	}
+	/*
+	 *	do this so the final gm_get callback can deregister the memory
+	 */
+	PORTAL_ALLOC(srxd->riov, nriov_dup*(sizeof(struct iovec)));
+	gm_bcopy(riov_dup, srxd->riov, nriov_dup*(sizeof(struct iovec)));
+	srxd->nriov = nriov_dup;
+
+	/*
+	 *	now do gm_get to get the data
+	 */
+	srxd->cookie = cookie;
+	if (gmnal_remote_get(srxd, srxd->nsiov, (struct iovec*)buffer, 
+			      nriov_dup, riov_dup) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "can't get the data");
+	}
+
+	CDEBUG(D_INFO, "lgmanl_large_rx done\n");
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	Perform a number of remote gets as part of receiving 
+ *	a large message.
+ *	The final one to complete (i.e. the last callback to get called)
+ *	tidies up.
+ *	gm_get requires a send token.
+ */
+int
+gmnal_remote_get(gmnal_srxd_t *srxd, int nsiov, struct iovec *siov, 
+		  int nriov, struct iovec *riov)
+{
+
+	int	ncalls = 0;
+
+	CDEBUG(D_TRACE, "gmnal_remote_get srxd[%p], nriov[%d], riov[%p], 
+	       nsiov[%d], siov[%p]\n", srxd, nriov, riov, nsiov, siov);
+
+
+	ncalls = gmnal_copyiov(0, srxd, nsiov, siov, nriov, riov);
+	if (ncalls < 0) {
+		CDEBUG(D_ERROR, "there's something wrong with the iovecs\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "gmnal_remote_get ncalls [%d]\n", ncalls);
+	spin_lock_init(&srxd->callback_lock);
+	srxd->ncallbacks = ncalls;
+	srxd->callback_status = 0;
+
+	ncalls = gmnal_copyiov(1, srxd, nsiov, siov, nriov, riov);
+	if (ncalls < 0) {
+		CDEBUG(D_ERROR, "there's something wrong with the iovecs\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	return(GMNAL_STATUS_OK);
+
+}
+
+
+/*
+ *	pull data from source node (source iovec) to a local iovec.
+ *	The iovecs may not match which adds the complications below.
+ *	Count the number of gm_gets that will be required to the callbacks
+ *	can determine who is the last one.
+ */	
+int
+gmnal_copyiov(int do_copy, gmnal_srxd_t *srxd, int nsiov, 
+	       struct iovec *siov, int nriov, struct iovec *riov)
+{
+
+	int	ncalls = 0;
+	int	slen = siov->iov_len, rlen = riov->iov_len;
+	char	*sbuf = siov->iov_base, *rbuf = riov->iov_base;	
+	unsigned long	sbuf_long;
+	gm_remote_ptr_t	remote_ptr = 0;
+	unsigned int	source_node;
+	gmnal_ltxd_t	*ltxd = NULL;
+	gmnal_data_t	*nal_data = srxd->nal_data;
+
+	CDEBUG(D_TRACE, "copy[%d] nal_data[%p]\n", do_copy, nal_data);
+	if (do_copy) {
+		if (!nal_data) {
+			CDEBUG(D_ERROR, "Bad args No nal_data\n");
+			return(GMNAL_STATUS_FAIL);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		if (gm_global_id_to_node_id(nal_data->gm_port, 
+					    srxd->gm_source_node, 
+					    &source_node) != GM_SUCCESS) {
+
+			CDEBUG(D_ERROR, "cannot resolve global_id [%u] 
+			       to local node_id\n", srxd->gm_source_node);
+			GMNAL_GM_UNLOCK(nal_data);
+			return(GMNAL_STATUS_FAIL);
+		}
+		GMNAL_GM_UNLOCK(nal_data);
+		/*
+		 *	We need a send token to use gm_get
+		 *	getting an stxd gets us a send token.
+		 *	the stxd is used as the context to the
+	 	 *	callback function (so stxd can be returned).
+		 *	Set pointer in stxd to srxd so callback count in srxd
+		 *	can be decremented to find last callback to complete
+		 */
+		CDEBUG(D_INFO, "gmnal_copyiov source node is G[%u]L[%d]\n", 
+		       srxd->gm_source_node, source_node);
+	}
+
+	do {
+		CDEBUG(D_INFO, "sbuf[%p] slen[%d] rbuf[%p], rlen[%d]\n",
+				sbuf, slen, rbuf, rlen);
+		if (slen > rlen) {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "slen>rlen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				/* 
+				 *	funny business to get rid 
+				 *	of compiler warning 
+				 */
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       rlen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at the end of 1 iov element
+		 	 */
+			sbuf+=rlen;
+			slen-=rlen;
+			riov++;
+			nriov--;
+			rbuf = riov->iov_base;
+			rlen = riov->iov_len;
+		} else if (rlen > slen) {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "slen<rlen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       slen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at end of siov element
+			 */
+			rbuf+=slen;
+			rlen-=slen;
+			siov++;
+			sbuf = siov->iov_base;
+			slen = siov->iov_len;
+		} else {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "rlen=slen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       rlen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at end of siov and riov element
+			 */
+			siov++;
+			sbuf = siov->iov_base;
+			slen = siov->iov_len;
+			riov++;
+			nriov--;
+			rbuf = riov->iov_base;
+			rlen = riov->iov_len;
+		}
+
+	} while (nriov);
+	return(ncalls);
+}
+
+
+/*
+ *	The callback function that is invoked after each gm_get call completes.
+ *	Multiple callbacks may be invoked for 1 transaction, only the final
+ *	callback has work to do.
+ */
+void
+gmnal_remote_get_callback(gm_port_t *gm_port, void *context, 
+			   gm_status_t status)
+{
+
+	gmnal_ltxd_t	*ltxd = (gmnal_ltxd_t*)context;
+	gmnal_srxd_t	*srxd = ltxd->srxd;
+	nal_cb_t	*nal_cb = srxd->nal_data->nal_cb;
+	int		lastone;
+	struct	iovec	*riov;
+	int		nriov;
+	gmnal_data_t	*nal_data;
+
+	CDEBUG(D_TRACE, "called for context [%p]\n", context);
+
+	if (status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "reports error [%d][%s]\n", status, 
+		       gmnal_gm_error(status));
+	}
+
+	spin_lock(&srxd->callback_lock);
+	srxd->ncallbacks--;
+	srxd->callback_status |= status;
+	lastone = srxd->ncallbacks?0:1;
+	spin_unlock(&srxd->callback_lock);
+	nal_data = srxd->nal_data;
+
+	/*
+	 *	everyone returns a send token
+	 */
+	gmnal_return_ltxd(nal_data, ltxd);
+
+	if (!lastone) {
+		CDEBUG(D_ERROR, "NOT final callback context[%p]\n", srxd);
+		return;
+	}
+	
+	/*
+	 *	Let our client application proceed
+	 */	
+	CDEBUG(D_ERROR, "final callback context[%p]\n", srxd);
+	if (lib_finalize(nal_cb, srxd, srxd->cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for srxd [%p]\n", 
+		       srxd);
+	}
+
+	/*
+	 *	send an ack to the sender to let him know we got the data
+	 */
+	gmnal_large_tx_ack(nal_data, srxd);
+
+	/*
+	 *	Unregister the memory that was used
+	 *	This is a very slow business (slower then register)
+	 */
+	nriov = srxd->nriov;
+	riov = srxd->riov;
+	GMNAL_GM_LOCK(nal_data);
+	while (nriov--) {
+		CDEBUG(D_ERROR, "deregister memory [%p]\n", riov->iov_base);
+		if (gm_deregister_memory(srxd->nal_data->gm_port, 
+		    		         riov->iov_base, riov->iov_len)) {
+			CDEBUG(D_ERROR, "failed to deregister memory [%p]\n", 
+			       riov->iov_base);
+		}
+		riov++;
+	}
+	GMNAL_GM_UNLOCK(nal_data);
+	PORTAL_FREE(srxd->riov, sizeof(struct iovec)*nriov);
+
+	/*
+	 *	repost the receive buffer (return receive token)
+	 */
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
+					   srxd->gmsize, GM_LOW_PRIORITY, 0);	
+	GMNAL_GM_UNLOCK(nal_data);
+	
+	return;
+}
+
+
+/*
+ *	Called on target node.
+ *	After pulling data from a source node
+ *	send an ack message to indicate the large transmit is complete.
+ */
+void 
+gmnal_large_tx_ack(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+
+	gmnal_stxd_t	*stxd;
+	gmnal_msghdr_t *msghdr;
+	void		*buffer = NULL;
+	unsigned int	local_nid;
+	gm_status_t	gm_status = GM_SUCCESS;
+
+	CDEBUG(D_TRACE, "srxd[%p] target_node [%u]\n", srxd, 
+	       srxd->gm_source_node);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, 
+					    srxd->gm_source_node, &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		return;
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%u][%x]\n", local_nid, local_nid);
+
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_TRACE, "gmnal_large_tx_ack got stxd[%p]\n", stxd);
+
+	stxd->nal_data = nal_data;
+	stxd->type = GMNAL_LARGE_MESSAGE_ACK;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the data in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	/*
+	 *	Add in the address of the original stxd from the sender node
+	 *	so it knows which thread to notify.
+	 */
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_LARGE_MESSAGE_ACK;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	msghdr->stxd = srxd->source_stxd;
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	CDEBUG(D_INFO, "sending\n");
+	stxd->msg_size= sizeof(gmnal_msghdr_t);
+
+
+	CDEBUG(D_NET, "Calling gm_send_to_peer port [%p] buffer [%p] 
+	       gmsize [%lu] msize [%d] global_nid [%u] local_nid[%d] 
+	       stxd [%p]\n", nal_data->gm_port, stxd->buffer, stxd->gm_size, 
+	       stxd->msg_size, srxd->gm_source_node, local_nid, stxd);
+	GMNAL_GM_LOCK(nal_data);
+	stxd->gm_priority = GM_LOW_PRIORITY;
+	stxd->gm_target_node = local_nid;
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, stxd->msg_size, 
+				      GM_LOW_PRIORITY, local_nid, 
+				      gmnal_large_tx_ack_callback, 
+				      (void*)stxd);
+	
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "gmnal_large_tx_ack :: done\n");
+		
+	return;
+}
+
+
+/*
+ *	A callback to indicate the small transmit operation is compete
+ *	Check for errors and try to deal with them.
+ *	Call lib_finalise to inform the client application that the 
+ *	send is complete and the memory can be reused.
+ *	Return the stxd when finished with it (returns a send token)
+ */
+void 
+gmnal_large_tx_ack_callback(gm_port_t *gm_port, void *context, 
+			     gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)stxd->nal_data;
+
+	if (!stxd) {
+		CDEBUG(D_ERROR, "send completion event for unknown stxd\n");
+		return;
+	}
+	CDEBUG(D_TRACE, "send completion event for stxd [%p] status is [%d]\n",
+	       stxd, status);
+	gmnal_return_stxd(stxd->nal_data, stxd);
+
+	GMNAL_GM_UNLOCK(nal_data);
+	return;
+}
+
+/*
+ *	Indicates the large transmit operation is compete.
+ *	Called on transmit side (means data has been pulled  by receiver 
+ *	or failed).
+ *	Call lib_finalise to inform the client application that the send 
+ *	is complete, deregister the memory and return the stxd. 
+ *	Finally, report the rx buffer that the ack message was delivered in.
+ */
+void 
+gmnal_large_tx_ack_received(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+	gmnal_stxd_t	*stxd = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	void		*buffer = NULL;
+	struct	iovec	*iov;
+
+
+	CDEBUG(D_TRACE, "gmnal_large_tx_ack_received buffer [%p]\n", buffer);
+
+	buffer = srxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+	stxd = msghdr->stxd;
+
+	CDEBUG(D_INFO, "gmnal_large_tx_ack_received stxd [%p]\n", stxd);
+
+	if (lib_finalize(nal_cb, stxd, stxd->cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for stxd [%p]\n", 
+		       stxd);
+	}
+
+	/*
+	 *	extract the iovec from the stxd, deregister the memory.
+	 *	free the space used to store the iovec
+	 */
+	iov = stxd->iov;
+	while(stxd->niov--) {
+		CDEBUG(D_INFO, "deregister memory [%p] size ["LPSZ"]\n",
+		       iov->iov_base, iov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_deregister_memory(nal_data->gm_port, iov->iov_base, 
+				     iov->iov_len);
+		GMNAL_GM_UNLOCK(nal_data);
+		iov++;
+	}
+
+	/*
+	 *	return the send token
+	 *	TO DO It is bad to hold onto the send token so long?
+	 */
+	gmnal_return_stxd(nal_data, stxd);
+
+
+	/*
+	 *	requeue the receive buffer 
+	 */
+	gmnal_rx_requeue_buffer(nal_data, srxd);
+	
+
+	return;
+}
diff --git a/lnet/klnds/gmlnd/gmlnd_module.c b/lnet/klnds/gmlnd/gmlnd_module.c
new file mode 100644
index 0000000000000000000000000000000000000000..126062916ef63ed9095a81afff3625c5c6416d50
--- /dev/null
+++ b/lnet/klnds/gmlnd/gmlnd_module.c
@@ -0,0 +1,147 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gmnal.h"
+
+
+int gmnal_small_msg_size = 525312;
+/*
+ *      -1 indicates default value.
+ *      This is 1 thread per cpu
+ *      See start_kernel_threads
+ */
+int num_rx_threads = -1;
+int num_stxds = 5;
+
+ptl_handle_ni_t	kgmnal_ni;
+
+
+int 
+gmnal_cmd(struct portals_cfg *pcfg, void *private)
+{
+	gmnal_data_t	*nal_data = NULL;
+	char		*name = NULL;
+	int		nid = -2;
+	int		gnid;
+	gm_status_t	gm_status;
+
+
+	CDEBUG(D_TRACE, "gmnal_cmd [%d] private [%p]\n", 
+	       pcfg->pcfg_command, private);
+	nal_data = (gmnal_data_t*)private;
+	switch(pcfg->pcfg_command) {
+	/*
+	 * just reuse already defined GET_NID. Should define GMNAL version
+	 */
+	case(GMNAL_IOC_GET_GNID):
+
+		PORTAL_ALLOC(name, pcfg->pcfg_plen1);
+		copy_from_user(name, pcfg->pcfg_pbuf1, pcfg->pcfg_plen1);
+	
+		GMNAL_GM_LOCK(nal_data);
+		nid = gm_host_name_to_node_id(nal_data->gm_port, name);
+		GMNAL_GM_UNLOCK(nal_data);
+		CDEBUG(D_INFO, "Local node id is [%d]\n", nid);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_node_id_to_global_id(nal_data->gm_port, 
+						    nid, &gnid);
+		GMNAL_GM_UNLOCK(nal_data);
+		if (gm_status != GM_SUCCESS) {
+			CDEBUG(D_INFO, "gm_node_id_to_global_id failed[%d]\n", 
+			       gm_status);
+			return(-1);
+		}
+		CDEBUG(D_INFO, "Global node is is [%u][%x]\n", gnid, gnid);
+		copy_to_user(pcfg->pcfg_pbuf2, &gnid, pcfg->pcfg_plen2);
+	break;
+	default:
+		CDEBUG(D_INFO, "gmnal_cmd UNKNOWN[%d]\n", pcfg->pcfg_command);
+		pcfg->pcfg_nid2 = -1;
+	}
+
+
+	return(0);
+}
+
+
+static int __init
+gmnal_load(void)
+{
+	int	status;
+	CDEBUG(D_TRACE, "This is the gmnal module initialisation routine\n");
+
+
+
+	CDEBUG(D_INFO, "Calling gmnal_init\n");
+	status = PtlNIInit(gmnal_init, 32, 4, 0, &kgmnal_ni);
+	if (status == PTL_OK) {
+		CDEBUG(D_INFO, "Portals GMNAL initialised ok kgmnal_ni\n");
+	} else {
+		CDEBUG(D_INFO, "Portals GMNAL Failed to initialise\n");
+		return(1);
+		
+	}
+
+	CDEBUG(D_INFO, "Calling kportal_nal_register\n");
+	/*
+ 	 *	global_nal_data is set by gmnal_init
+	 */
+	if (kportal_nal_register(GMNAL, &gmnal_cmd, global_nal_data) != 0) {
+		CDEBUG(D_INFO, "kportal_nal_register failed\n");
+		return(1);
+	}
+
+	CDEBUG(D_INFO, "Calling PORTAL_SYMBOL_REGISTER\n");
+	PORTAL_SYMBOL_REGISTER(kgmnal_ni);
+	CDEBUG(D_INFO, "This is the end of the gmnal init routine");
+
+
+	return(0);
+}
+
+
+static void __exit
+gmnal_unload(void)
+{
+
+	kportal_nal_unregister(GMNAL);
+	PORTAL_SYMBOL_UNREGISTER(kgmnal_ni);
+	gmnal_fini();
+	global_nal_data = NULL;
+	return;
+}
+
+
+module_init(gmnal_load);
+
+module_exit(gmnal_unload);
+
+EXPORT_SYMBOL(kgmnal_ni);
+
+MODULE_PARM(gmnal_small_msg_size, "i");
+MODULE_PARM(num_rx_threads, "i");
+MODULE_PARM(num_stxds, "i");
+
+MODULE_AUTHOR("Morgan Doyle");
+
+MODULE_DESCRIPTION("A Portals kernel NAL for Myrinet GM.");
+
+MODULE_LICENSE("GPL");
diff --git a/lnet/klnds/gmlnd/gmlnd_utils.c b/lnet/klnds/gmlnd/gmlnd_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..55606f3cda530f496538506c29e8306c1f12777a
--- /dev/null
+++ b/lnet/klnds/gmlnd/gmlnd_utils.c
@@ -0,0 +1,1073 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ *	All utilities required by lgmanl
+ */
+
+#include "gmnal.h"
+
+/*
+ *	Am I one of the gmnal rxthreads ?
+ */
+int
+gmnal_is_rxthread(gmnal_data_t *nal_data)
+{
+	int i;
+	for (i=0; i<num_rx_threads; i++) {
+		if (nal_data->rxthread_pid[i] == current->pid)
+			return(1);
+	}
+	return(0);
+}
+
+
+/*
+ *	Allocate tx descriptors/tokens (large and small)
+ *	allocate a number of small tx buffers and register with GM
+ *	so they are wired and set up for DMA. This is a costly operation.
+ *	Also allocate a corrosponding descriptor to keep track of 
+ *	the buffer.
+ *	Put all small descriptors on singly linked list to be available to send 
+ *	function.
+ *	Allocate the rest of the available tx tokens for large messages. These will be
+ *	used to do gm_gets in gmnal_copyiov	
+ */
+int
+gmnal_alloc_txd(gmnal_data_t *nal_data)
+{
+	int ntx= 0, nstx= 0, nrxt_stx= 0,
+	    nltx= 0, i = 0;
+	gmnal_stxd_t	*txd = NULL;
+	gmnal_ltxd_t	*ltxd = NULL;
+	void	*txbuffer = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_alloc_small tx\n");
+
+	GMNAL_GM_LOCK(nal_data);
+	/*
+	 *	total number of transmit tokens
+	 */
+	ntx = gm_num_send_tokens(nal_data->gm_port);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "total number of send tokens available is [%d]\n", ntx);
+	
+	/*
+ 	 *	allocate a number for small sends
+	 * 	num_stxds from gmnal_module.c
+	 */
+	nstx = num_stxds;
+	/*
+	 *	give that number plus 1 to the receive threads
+	 */
+        nrxt_stx = nstx + 1;
+
+	/*
+	 *	give the rest for gm_gets
+	 */
+	nltx = ntx - (nrxt_stx + nstx);
+	if (nltx < 1) {
+		CDEBUG(D_ERROR, "No tokens available for large messages\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+
+	/*
+	 * A semaphore is initialised with the 
+	 * number of transmit tokens available.
+	 * To get a stxd, acquire the token semaphore.
+ 	 * this decrements the available token count
+	 * (if no tokens you block here, someone returning a 
+	 * stxd will release the semaphore and wake you)
+	 * When token is obtained acquire the spinlock 
+	 * to manipulate the list
+	 */
+	GMNAL_TXD_TOKEN_INIT(nal_data, nstx);
+	GMNAL_TXD_LOCK_INIT(nal_data);
+	GMNAL_RXT_TXD_TOKEN_INIT(nal_data, nrxt_stx);
+	GMNAL_RXT_TXD_LOCK_INIT(nal_data);
+	GMNAL_LTXD_TOKEN_INIT(nal_data, nltx);
+	GMNAL_LTXD_LOCK_INIT(nal_data);
+	
+	for (i=0; i<=nstx; i++) {
+		PORTAL_ALLOC(txd, sizeof(gmnal_stxd_t));
+		if (!txd) {
+			CDEBUG(D_ERROR, "Failed to malloc txd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		txbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!txbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc txbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(txd, sizeof(gmnal_stxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		txd->buffer = txbuffer;
+		txd->buffer_size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		txd->gm_size = gm_min_size_for_length(txd->buffer_size);
+		txd->nal_data = (struct _gmnal_data_t*)nal_data;
+                txd->rxt = 0;
+
+		txd->next = nal_data->stxd;
+		nal_data->stxd = txd;
+		CDEBUG(D_INFO, "Registered txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+	}
+
+	for (i=0; i<=nrxt_stx; i++) {
+		PORTAL_ALLOC(txd, sizeof(gmnal_stxd_t));
+		if (!txd) {
+			CDEBUG(D_ERROR, "Failed to malloc txd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		txbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!txbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc txbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(txd, sizeof(gmnal_stxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		txd->buffer = txbuffer;
+		txd->buffer_size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		txd->gm_size = gm_min_size_for_length(txd->buffer_size);
+		txd->nal_data = (struct _gmnal_data_t*)nal_data;
+                txd->rxt = 1;
+
+		txd->next = nal_data->rxt_stxd;
+		nal_data->rxt_stxd = txd;
+		CDEBUG(D_INFO, "Registered txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+	}
+
+	/*
+	 *	string together large tokens
+	 */
+	for (i=0; i<=nltx ; i++) {
+		PORTAL_ALLOC(ltxd, sizeof(gmnal_ltxd_t));
+		ltxd->next = nal_data->ltxd;
+		nal_data->ltxd = ltxd;
+	}
+	return(GMNAL_STATUS_OK);
+}
+
+/*	Free the list of wired and gm_registered small tx buffers and 
+ *	the tx descriptors that go along with them.
+ */
+void
+gmnal_free_txd(gmnal_data_t *nal_data)
+{
+	gmnal_stxd_t *txd = nal_data->stxd, *_txd = NULL;
+	gmnal_ltxd_t *ltxd = NULL, *_ltxd = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_free_small tx\n");
+
+	while(txd) {
+		CDEBUG(D_INFO, "Freeing txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+		_txd = txd;
+		txd = txd->next;
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _txd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_txd, sizeof(gmnal_stxd_t));
+	}
+        txd = nal_data->rxt_stxd;
+	while(txd) {
+		CDEBUG(D_INFO, "Freeing txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+		_txd = txd;
+		txd = txd->next;
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _txd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_txd, sizeof(gmnal_stxd_t));
+	}
+	ltxd = nal_data->ltxd;
+	while(txd) {
+		_ltxd = ltxd;
+		ltxd = ltxd->next;
+		PORTAL_FREE(_ltxd, sizeof(gmnal_ltxd_t));
+	}
+	
+	return;
+}
+
+
+/*
+ *	Get a txd from the list
+ *	This get us a wired and gm_registered small tx buffer.
+ *	This implicitly gets us a send token also.
+ */
+gmnal_stxd_t *
+gmnal_get_stxd(gmnal_data_t *nal_data, int block)
+{
+
+	gmnal_stxd_t	*txd = NULL;
+	pid_t		pid = current->pid;
+
+
+	CDEBUG(D_TRACE, "gmnal_get_stxd nal_data [%p] block[%d] pid [%d]\n", 
+	       nal_data, block, pid);
+
+	if (gmnal_is_rxthread(nal_data)) {
+                CDEBUG(D_INFO, "RXTHREAD Attempting to get token\n");
+		GMNAL_RXT_TXD_GETTOKEN(nal_data);
+	        GMNAL_RXT_TXD_LOCK(nal_data);
+	        txd = nal_data->rxt_stxd;
+		nal_data->rxt_stxd = txd->next;
+	        GMNAL_RXT_TXD_UNLOCK(nal_data);
+	        CDEBUG(D_INFO, "RXTHREAD got [%p], head is [%p]\n", 
+		       txd, nal_data->rxt_stxd);
+                txd->kniov = 0;
+                txd->rxt = 1;
+        } else {
+	        if (block) {
+                        CDEBUG(D_INFO, "Attempting to get token\n");
+		        GMNAL_TXD_GETTOKEN(nal_data);
+                        CDEBUG(D_PORTALS, "Got token\n");
+	        } else {
+		        if (GMNAL_TXD_TRYGETTOKEN(nal_data)) {
+			        CDEBUG(D_ERROR, "can't get token\n");
+			        return(NULL);
+		        }
+	        }
+	        GMNAL_TXD_LOCK(nal_data);
+	        txd = nal_data->stxd;
+		nal_data->stxd = txd->next;
+	        GMNAL_TXD_UNLOCK(nal_data);
+	        CDEBUG(D_INFO, "got [%p], head is [%p]\n", txd, 
+		       nal_data->stxd);
+                txd->kniov = 0;
+        }       /* general txd get */
+	return(txd);
+}
+
+/*
+ *	Return a txd to the list
+ */
+void
+gmnal_return_stxd(gmnal_data_t *nal_data, gmnal_stxd_t *txd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], txd[%p] rxt[%d]\n", nal_data, 
+	       txd, txd->rxt);
+
+        /*
+         *      this transmit descriptor is 
+         *      for the rxthread
+         */
+        if (txd->rxt) {
+	        GMNAL_RXT_TXD_LOCK(nal_data);
+	        txd->next = nal_data->rxt_stxd;
+	        nal_data->rxt_stxd = txd;
+	        GMNAL_RXT_TXD_UNLOCK(nal_data);
+	        GMNAL_RXT_TXD_RETURNTOKEN(nal_data);
+                CDEBUG(D_INFO, "Returned stxd to rxthread list\n");
+        } else {
+	        GMNAL_TXD_LOCK(nal_data);
+	        txd->next = nal_data->stxd;
+	        nal_data->stxd = txd;
+	        GMNAL_TXD_UNLOCK(nal_data);
+	        GMNAL_TXD_RETURNTOKEN(nal_data);
+                CDEBUG(D_INFO, "Returned stxd to general list\n");
+        }
+	return;
+}
+
+
+/*
+ *	Get a large transmit descriptor from the free list
+ *	This implicitly gets us a transmit  token .
+ *	always wait for one.
+ */
+gmnal_ltxd_t *
+gmnal_get_ltxd(gmnal_data_t *nal_data)
+{
+
+	gmnal_ltxd_t	*ltxd = NULL;
+
+	CDEBUG(D_TRACE, "nal_data [%p]\n", nal_data);
+
+	GMNAL_LTXD_GETTOKEN(nal_data);
+	GMNAL_LTXD_LOCK(nal_data);
+	ltxd = nal_data->ltxd;
+	nal_data->ltxd = ltxd->next;
+	GMNAL_LTXD_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "got [%p], head is [%p]\n", ltxd, nal_data->ltxd);
+	return(ltxd);
+}
+
+/*
+ *	Return an ltxd to the list
+ */
+void
+gmnal_return_ltxd(gmnal_data_t *nal_data, gmnal_ltxd_t *ltxd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], ltxd[%p]\n", nal_data, ltxd);
+
+	GMNAL_LTXD_LOCK(nal_data);
+	ltxd->next = nal_data->ltxd;
+	nal_data->ltxd = ltxd;
+	GMNAL_LTXD_UNLOCK(nal_data);
+	GMNAL_LTXD_RETURNTOKEN(nal_data);
+	return;
+}
+/*
+ *	allocate a number of small rx buffers and register with GM
+ *	so they are wired and set up for DMA. This is a costly operation.
+ *	Also allocate a corrosponding descriptor to keep track of 
+ *	the buffer.
+ *	Put all descriptors on singly linked list to be available to 
+ *	receive thread.
+ */
+int
+gmnal_alloc_srxd(gmnal_data_t *nal_data)
+{
+	int nrx = 0, nsrx = 0, i = 0;
+	gmnal_srxd_t	*rxd = NULL;
+	void	*rxbuffer = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_alloc_small rx\n");
+
+	GMNAL_GM_LOCK(nal_data);
+	nrx = gm_num_receive_tokens(nal_data->gm_port);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "total number of receive tokens available is [%d]\n", 
+	       nrx);
+	
+	nsrx = nrx/2;
+	nsrx = 12;
+	/*
+	 *	make the number of rxds twice our total
+	 *	number of stxds plus 1
+	 */
+	nsrx = num_stxds*2 + 2;
+
+	CDEBUG(D_INFO, "Allocated [%d] receive tokens to small messages\n", 
+	       nsrx);
+
+
+	GMNAL_GM_LOCK(nal_data);
+	nal_data->srxd_hash = gm_create_hash(gm_hash_compare_ptrs, 
+					     gm_hash_hash_ptr, 0, 0, nsrx, 0);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (!nal_data->srxd_hash) {
+			CDEBUG(D_ERROR, "Failed to create hash table\n");
+			return(GMNAL_STATUS_NOMEM);
+	}
+
+	GMNAL_RXD_TOKEN_INIT(nal_data, nsrx);
+	GMNAL_RXD_LOCK_INIT(nal_data);
+
+	for (i=0; i<=nsrx; i++) {
+		PORTAL_ALLOC(rxd, sizeof(gmnal_srxd_t));
+		if (!rxd) {
+			CDEBUG(D_ERROR, "Failed to malloc rxd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+#if 0
+		PORTAL_ALLOC(rxbuffer, GMNAL_SMALL_MSG_SIZE(nal_data));
+		if (!rxbuffer) {
+			CDEBUG(D_ERROR, "Failed to malloc rxbuffer [%d], 
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(rxd, sizeof(gmnal_srxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		CDEBUG(D_NET, "Calling gm_register_memory with port [%p] 
+		       rxbuffer [%p], size [%d]\n", nal_data->gm_port, 
+		       rxbuffer, GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, rxbuffer, 
+					       GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (gm_status != GM_SUCCESS) {
+			CDEBUG(D_ERROR, "gm_register_memory failed buffer [%p],
+			       index [%d]\n", rxbuffer, i);
+			switch(gm_status) {
+				case(GM_FAILURE):
+					CDEBUG(D_ERROR, "GM_FAILURE\n");
+				break;
+				case(GM_PERMISSION_DENIED):
+					CDEBUG(D_ERROR, "PERMISSION_DENIED\n");
+				break;
+				case(GM_INVALID_PARAMETER):
+					CDEBUG(D_ERROR, "INVALID_PARAMETER\n");
+				break;
+				default:
+					CDEBUG(D_ERROR, "Unknown error[%d]\n", 
+					       gm_status);
+				break;
+				
+			}
+			return(GMNAL_STATUS_FAIL);
+		}
+#else
+		GMNAL_GM_LOCK(nal_data);
+		rxbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!rxbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc rxbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(rxd, sizeof(gmnal_srxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+#endif
+		
+		rxd->buffer = rxbuffer;
+		rxd->size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		rxd->gmsize = gm_min_size_for_length(rxd->size);
+
+		if (gm_hash_insert(nal_data->srxd_hash, 
+				   (void*)rxbuffer, (void*)rxd)) {
+
+			CDEBUG(D_ERROR, "failed to create hash entry rxd[%p] 
+			       for rxbuffer[%p]\n", rxd, rxbuffer);
+			return(GMNAL_STATUS_FAIL);
+		}
+
+		rxd->next = nal_data->srxd;
+		nal_data->srxd = rxd;
+		CDEBUG(D_INFO, "Registered rxd [%p] with buffer [%p], 
+		       size [%d]\n", rxd, rxd->buffer, rxd->size);
+	}
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*	Free the list of wired and gm_registered small rx buffers and the 
+ *	rx descriptors that go along with them.
+ */
+void
+gmnal_free_srxd(gmnal_data_t *nal_data)
+{
+	gmnal_srxd_t *rxd = nal_data->srxd, *_rxd = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_free_small rx\n");
+
+	while(rxd) {
+		CDEBUG(D_INFO, "Freeing rxd [%p] buffer [%p], size [%d]\n",
+		       rxd, rxd->buffer, rxd->size);
+		_rxd = rxd;
+		rxd = rxd->next;
+
+#if 0
+		GMNAL_GM_LOCK(nal_data);
+		gm_deregister_memory(nal_data->gm_port, _rxd->buffer, 
+				     _rxd->size);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_rxd->buffer, GMNAL_SMALL_RXBUFFER_SIZE);
+#else
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _rxd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+#endif
+		PORTAL_FREE(_rxd, sizeof(gmnal_srxd_t));
+	}
+	return;
+}
+
+
+/*
+ *	Get a rxd from the free list
+ *	This get us a wired and gm_registered small rx buffer.
+ *	This implicitly gets us a receive token also.
+ */
+gmnal_srxd_t *
+gmnal_get_srxd(gmnal_data_t *nal_data, int block)
+{
+
+	gmnal_srxd_t	*rxd = NULL;
+	CDEBUG(D_TRACE, "nal_data [%p] block [%d]\n", nal_data, block);
+
+	if (block) {
+		GMNAL_RXD_GETTOKEN(nal_data);
+	} else {
+		if (GMNAL_RXD_TRYGETTOKEN(nal_data)) {
+			CDEBUG(D_INFO, "gmnal_get_srxd Can't get token\n");
+			return(NULL);
+		}
+	}
+	GMNAL_RXD_LOCK(nal_data);
+	rxd = nal_data->srxd;
+	if (rxd)
+		nal_data->srxd = rxd->next;
+	GMNAL_RXD_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "got [%p], head is [%p]\n", rxd, nal_data->srxd);
+	return(rxd);
+}
+
+/*
+ *	Return an rxd to the list
+ */
+void
+gmnal_return_srxd(gmnal_data_t *nal_data, gmnal_srxd_t *rxd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], rxd[%p]\n", nal_data, rxd);
+
+	GMNAL_RXD_LOCK(nal_data);
+	rxd->next = nal_data->srxd;
+	nal_data->srxd = rxd;
+	GMNAL_RXD_UNLOCK(nal_data);
+	GMNAL_RXD_RETURNTOKEN(nal_data);
+	return;
+}
+
+/*
+ *	Given a pointer to a srxd find 
+ *	the relevant descriptor for it
+ *	This is done by searching a hash
+ *	list that is created when the srxd's 
+ *	are created
+ */
+gmnal_srxd_t *
+gmnal_rxbuffer_to_srxd(gmnal_data_t *nal_data, void *rxbuffer)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	CDEBUG(D_TRACE, "nal_data [%p], rxbuffer [%p]\n", nal_data, rxbuffer);
+	srxd = gm_hash_find(nal_data->srxd_hash, rxbuffer);
+	CDEBUG(D_INFO, "srxd is [%p]\n", srxd);
+	return(srxd);
+}
+
+
+void
+gmnal_stop_rxthread(gmnal_data_t *nal_data)
+{
+	int 	delay = 30;
+
+
+
+	CDEBUG(D_TRACE, "Attempting to stop rxthread nal_data [%p]\n", 
+	        nal_data);
+	
+	nal_data->rxthread_stop_flag = GMNAL_THREAD_STOP;
+
+	gmnal_remove_rxtwe(nal_data);
+	/*
+	 *	kick the thread 
+	 */
+	up(&nal_data->rxtwe_wait);
+
+	while(nal_data->rxthread_flag != GMNAL_THREAD_RESET && delay--) {
+		CDEBUG(D_INFO, "gmnal_stop_rxthread sleeping\n");
+                gmnal_yield(1);
+		up(&nal_data->rxtwe_wait);
+	}
+
+	if (nal_data->rxthread_flag != GMNAL_THREAD_RESET) {
+		CDEBUG(D_ERROR, "I don't know how to wake the thread\n");
+	} else {
+		CDEBUG(D_INFO, "rx thread seems to have stopped\n");
+	}
+}
+
+void
+gmnal_stop_ctthread(gmnal_data_t *nal_data)
+{
+	int 	delay = 15;
+
+
+
+	CDEBUG(D_TRACE, "Attempting to stop ctthread nal_data [%p]\n", 
+	       nal_data);
+	
+	nal_data->ctthread_flag = GMNAL_THREAD_STOP;
+	GMNAL_GM_LOCK(nal_data);
+	gm_set_alarm(nal_data->gm_port, &nal_data->ctthread_alarm, 10, 
+		     NULL, NULL);
+	GMNAL_GM_UNLOCK(nal_data);
+
+	while(nal_data->ctthread_flag == GMNAL_THREAD_STOP && delay--) {
+		CDEBUG(D_INFO, "gmnal_stop_ctthread sleeping\n");
+                gmnal_yield(1);
+	}
+
+	if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+		CDEBUG(D_ERROR, "I DON'T KNOW HOW TO WAKE THE THREAD\n");
+	} else {
+		CDEBUG(D_INFO, "CT THREAD SEEMS TO HAVE STOPPED\n");
+	}
+}
+
+
+
+char * 
+gmnal_gm_error(gm_status_t status)
+{
+	switch(status) {
+		case(GM_SUCCESS):
+			return("SUCCESS");
+  		case(GM_FAILURE):
+			return("FAILURE");
+  		case(GM_INPUT_BUFFER_TOO_SMALL):
+			return("INPUT_BUFFER_TOO_SMALL");
+  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
+			return("OUTPUT_BUFFER_TOO_SMALL");
+  		case(GM_TRY_AGAIN ):
+			return("TRY_AGAIN");
+  		case(GM_BUSY):
+			return("BUSY");
+  		case(GM_MEMORY_FAULT):
+			return("MEMORY_FAULT");
+  		case(GM_INTERRUPTED):
+			return("INTERRUPTED");
+  		case(GM_INVALID_PARAMETER):
+			return("INVALID_PARAMETER");
+  		case(GM_OUT_OF_MEMORY):
+			return("OUT_OF_MEMORY");
+  		case(GM_INVALID_COMMAND):
+			return("INVALID_COMMAND");
+  		case(GM_PERMISSION_DENIED):
+			return("PERMISSION_DENIED");
+  		case(GM_INTERNAL_ERROR):
+			return("INTERNAL_ERROR");
+  		case(GM_UNATTACHED):
+			return("UNATTACHED");
+  		case(GM_UNSUPPORTED_DEVICE):
+			return("UNSUPPORTED_DEVICE");
+  		case(GM_SEND_TIMED_OUT):
+			return("GM_SEND_TIMEDOUT");
+  		case(GM_SEND_REJECTED):
+			return("GM_SEND_REJECTED");
+  		case(GM_SEND_TARGET_PORT_CLOSED):
+			return("GM_SEND_TARGET_PORT_CLOSED");
+  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
+			return("GM_SEND_TARGET_NODE_UNREACHABLE");
+  		case(GM_SEND_DROPPED):
+			return("GM_SEND_DROPPED");
+  		case(GM_SEND_PORT_CLOSED):
+			return("GM_SEND_PORT_CLOSED");
+  		case(GM_NODE_ID_NOT_YET_SET):
+			return("GM_NODE_ID_NOT_YET_SET");
+  		case(GM_STILL_SHUTTING_DOWN):
+			return("GM_STILL_SHUTTING_DOWN");
+  		case(GM_CLONE_BUSY):
+			return("GM_CLONE_BUSY");
+  		case(GM_NO_SUCH_DEVICE):
+			return("GM_NO_SUCH_DEVICE");
+  		case(GM_ABORTED):
+			return("GM_ABORTED");
+  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+			return("GM_INCOMPATIBLE_LIB_AND_DRIVER");
+  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
+			return("GM_UNTRANSLATED_SYSTEM_ERROR");
+  		case(GM_ACCESS_DENIED):
+			return("GM_ACCESS_DENIED");
+
+
+/*
+ *	These ones are in the docs but aren't in the header file 
+  		case(GM_DEV_NOT_FOUND):
+			return("GM_DEV_NOT_FOUND");
+  		case(GM_INVALID_PORT_NUMBER):
+			return("GM_INVALID_PORT_NUMBER");
+  		case(GM_UC_ERROR):
+			return("GM_US_ERROR");
+  		case(GM_PAGE_TABLE_FULL):
+			return("GM_PAGE_TABLE_FULL");
+  		case(GM_MINOR_OVERFLOW):
+			return("GM_MINOR_OVERFLOW");
+  		case(GM_SEND_ORPHANED):
+			return("GM_SEND_ORPHANED");
+  		case(GM_HARDWARE_FAULT):
+			return("GM_HARDWARE_FAULT");
+  		case(GM_DATA_CORRUPTED):
+			return("GM_DATA_CORRUPTED");
+  		case(GM_TIMED_OUT):
+			return("GM_TIMED_OUT");
+  		case(GM_USER_ERROR):
+			return("GM_USER_ERROR");
+  		case(GM_NO_MATCH):
+			return("GM_NOMATCH");
+  		case(GM_NOT_SUPPORTED_IN_KERNEL):
+			return("GM_NOT_SUPPORTED_IN_KERNEL");
+  		case(GM_NOT_SUPPORTED_ON_ARCH):
+			return("GM_NOT_SUPPORTED_ON_ARCH");
+  		case(GM_PTE_REF_CNT_OVERFLOW):
+			return("GM_PTR_REF_CNT_OVERFLOW");
+  		case(GM_NO_DRIVER_SUPPORT):
+			return("GM_NO_DRIVER_SUPPORT");
+  		case(GM_FIRMWARE_NOT_RUNNING):
+			return("GM_FIRMWARE_NOT_RUNNING");
+
+ *	These ones are in the docs but aren't in the header file 
+ */
+		default:
+			return("UNKNOWN GM ERROR CODE");
+	}
+}
+
+
+char *
+gmnal_rxevent(gm_recv_event_t	*ev)
+{
+	short	event;
+	event = GM_RECV_EVENT_TYPE(ev);
+	switch(event) {
+  		case(GM_NO_RECV_EVENT):
+			return("GM_NO_RECV_EVENT");
+  		case(GM_SENDS_FAILED_EVENT):
+			return("GM_SEND_FAILED_EVENT");
+  		case(GM_ALARM_EVENT):
+			return("GM_ALARM_EVENT");
+  		case(GM_SENT_EVENT):
+			return("GM_SENT_EVENT");
+  		case(_GM_SLEEP_EVENT):
+			return("_GM_SLEEP_EVENT");
+  		case(GM_RAW_RECV_EVENT):
+			return("GM_RAW_RECV_EVENT");
+  		case(GM_BAD_SEND_DETECTED_EVENT):
+			return("GM_BAD_SEND_DETECTED_EVENT");
+  		case(GM_SEND_TOKEN_VIOLATION_EVENT):
+			return("GM_SEND_TOKEN_VIOLATION_EVENT");
+  		case(GM_RECV_TOKEN_VIOLATION_EVENT):
+			return("GM_RECV_TOKEN_VIOLATION_EVENT");
+  		case(GM_BAD_RECV_TOKEN_EVENT):
+			return("GM_BAD_RECV_TOKEN_EVENT");
+  		case(GM_ALARM_VIOLATION_EVENT):
+			return("GM_ALARM_VIOLATION_EVENT");
+  		case(GM_RECV_EVENT):
+			return("GM_RECV_EVENT");
+  		case(GM_HIGH_RECV_EVENT):
+			return("GM_HIGH_RECV_EVENT");
+  		case(GM_PEER_RECV_EVENT):
+			return("GM_PEER_RECV_EVENT");
+  		case(GM_HIGH_PEER_RECV_EVENT):
+			return("GM_HIGH_PEER_RECV_EVENT");
+  		case(GM_FAST_RECV_EVENT):
+			return("GM_FAST_RECV_EVENT");
+  		case(GM_FAST_HIGH_RECV_EVENT):
+			return("GM_FAST_HIGH_RECV_EVENT");
+  		case(GM_FAST_PEER_RECV_EVENT):
+			return("GM_FAST_PEER_RECV_EVENT");
+  		case(GM_FAST_HIGH_PEER_RECV_EVENT):
+			return("GM_FAST_HIGH_PEER_RECV_EVENT");
+  		case(GM_REJECTED_SEND_EVENT):
+			return("GM_REJECTED_SEND_EVENT");
+  		case(GM_ORPHANED_SEND_EVENT):
+			return("GM_ORPHANED_SEND_EVENT");
+  		case(GM_BAD_RESEND_DETECTED_EVENT):
+			return("GM_BAD_RESEND_DETETED_EVENT");
+  		case(GM_DROPPED_SEND_EVENT):
+			return("GM_DROPPED_SEND_EVENT");
+  		case(GM_BAD_SEND_VMA_EVENT):
+			return("GM_BAD_SEND_VMA_EVENT");
+  		case(GM_BAD_RECV_VMA_EVENT):
+			return("GM_BAD_RECV_VMA_EVENT");
+  		case(_GM_FLUSHED_ALARM_EVENT):
+			return("GM_FLUSHED_ALARM_EVENT");
+  		case(GM_SENT_TOKENS_EVENT):
+			return("GM_SENT_TOKENS_EVENTS");
+  		case(GM_IGNORE_RECV_EVENT):
+			return("GM_IGNORE_RECV_EVENT");
+  		case(GM_ETHERNET_RECV_EVENT):
+			return("GM_ETHERNET_RECV_EVENT");
+  		case(GM_NEW_NO_RECV_EVENT):
+			return("GM_NEW_NO_RECV_EVENT");
+  		case(GM_NEW_SENDS_FAILED_EVENT):
+			return("GM_NEW_SENDS_FAILED_EVENT");
+  		case(GM_NEW_ALARM_EVENT):
+			return("GM_NEW_ALARM_EVENT");
+  		case(GM_NEW_SENT_EVENT):
+			return("GM_NEW_SENT_EVENT");
+  		case(_GM_NEW_SLEEP_EVENT):
+			return("GM_NEW_SLEEP_EVENT");
+  		case(GM_NEW_RAW_RECV_EVENT):
+			return("GM_NEW_RAW_RECV_EVENT");
+  		case(GM_NEW_BAD_SEND_DETECTED_EVENT):
+			return("GM_NEW_BAD_SEND_DETECTED_EVENT");
+  		case(GM_NEW_SEND_TOKEN_VIOLATION_EVENT):
+			return("GM_NEW_SEND_TOKEN_VIOLATION_EVENT");
+  		case(GM_NEW_RECV_TOKEN_VIOLATION_EVENT):
+			return("GM_NEW_RECV_TOKEN_VIOLATION_EVENT");
+  		case(GM_NEW_BAD_RECV_TOKEN_EVENT):
+			return("GM_NEW_BAD_RECV_TOKEN_EVENT");
+  		case(GM_NEW_ALARM_VIOLATION_EVENT):
+			return("GM_NEW_ALARM_VIOLATION_EVENT");
+  		case(GM_NEW_RECV_EVENT):
+			return("GM_NEW_RECV_EVENT");
+  		case(GM_NEW_HIGH_RECV_EVENT):
+			return("GM_NEW_HIGH_RECV_EVENT");
+  		case(GM_NEW_PEER_RECV_EVENT):
+			return("GM_NEW_PEER_RECV_EVENT");
+  		case(GM_NEW_HIGH_PEER_RECV_EVENT):
+			return("GM_NEW_HIGH_PEER_RECV_EVENT");
+  		case(GM_NEW_FAST_RECV_EVENT):
+			return("GM_NEW_FAST_RECV_EVENT");
+  		case(GM_NEW_FAST_HIGH_RECV_EVENT):
+			return("GM_NEW_FAST_HIGH_RECV_EVENT");
+  		case(GM_NEW_FAST_PEER_RECV_EVENT):
+			return("GM_NEW_FAST_PEER_RECV_EVENT");
+  		case(GM_NEW_FAST_HIGH_PEER_RECV_EVENT):
+			return("GM_NEW_FAST_HIGH_PEER_RECV_EVENT");
+  		case(GM_NEW_REJECTED_SEND_EVENT):
+			return("GM_NEW_REJECTED_SEND_EVENT");
+  		case(GM_NEW_ORPHANED_SEND_EVENT):
+			return("GM_NEW_ORPHANED_SEND_EVENT");
+  		case(_GM_NEW_PUT_NOTIFICATION_EVENT):
+			return("_GM_NEW_PUT_NOTIFICATION_EVENT");
+  		case(GM_NEW_FREE_SEND_TOKEN_EVENT):
+			return("GM_NEW_FREE_SEND_TOKEN_EVENT");
+  		case(GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT):
+			return("GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT");
+  		case(GM_NEW_BAD_RESEND_DETECTED_EVENT):
+			return("GM_NEW_BAD_RESEND_DETECTED_EVENT");
+  		case(GM_NEW_DROPPED_SEND_EVENT):
+			return("GM_NEW_DROPPED_SEND_EVENT");
+  		case(GM_NEW_BAD_SEND_VMA_EVENT):
+			return("GM_NEW_BAD_SEND_VMA_EVENT");
+  		case(GM_NEW_BAD_RECV_VMA_EVENT):
+			return("GM_NEW_BAD_RECV_VMA_EVENT");
+  		case(_GM_NEW_FLUSHED_ALARM_EVENT):
+			return("GM_NEW_FLUSHED_ALARM_EVENT");
+  		case(GM_NEW_SENT_TOKENS_EVENT):
+			return("GM_NEW_SENT_TOKENS_EVENT");
+  		case(GM_NEW_IGNORE_RECV_EVENT):
+			return("GM_NEW_IGNORE_RECV_EVENT");
+  		case(GM_NEW_ETHERNET_RECV_EVENT):
+			return("GM_NEW_ETHERNET_RECV_EVENT");
+		default:
+			return("Unknown Recv event");
+#if 0
+  		case(/* _GM_PUT_NOTIFICATION_EVENT */
+  		case(/* GM_FREE_SEND_TOKEN_EVENT */
+  		case(/* GM_FREE_HIGH_SEND_TOKEN_EVENT */
+#endif
+	}
+}
+
+
+void
+gmnal_yield(int delay)
+{
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(delay);
+}
+
+int
+gmnal_is_small_msg(gmnal_data_t *nal_data, int niov, struct iovec *iov, 
+		    int len)
+{
+
+	CDEBUG(D_TRACE, "len [%d] limit[%d]\n", len, 
+	       GMNAL_SMALL_MSG_SIZE(nal_data));
+
+	if ((len + sizeof(ptl_hdr_t) + sizeof(gmnal_msghdr_t)) 
+	             < GMNAL_SMALL_MSG_SIZE(nal_data)) {
+
+		CDEBUG(D_INFO, "Yep, small message\n");
+		return(1);
+	} else {
+		CDEBUG(D_ERROR, "No, not small message\n");
+		/*
+		 *	could be made up of lots of little ones !
+		 */
+		return(0);
+	}
+
+}
+
+/* 
+ *	extract info from the receive event.
+ *	Have to do this before the next call to gm_receive
+ *	Deal with all endian stuff here.
+ *	Then stick work entry on list where rxthreads
+ *	can get it to complete the receive
+ */
+int
+gmnal_add_rxtwe(gmnal_data_t *nal_data, gm_recv_t *recv)
+{
+	gmnal_rxtwe_t	*we = NULL;
+
+	CDEBUG(D_NET, "adding entry to list\n");
+
+	PORTAL_ALLOC(we, sizeof(gmnal_rxtwe_t));
+	if (!we) {
+		CDEBUG(D_ERROR, "failed to malloc\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	we->buffer = gm_ntohp(recv->buffer);
+	we->snode = (int)gm_ntoh_u16(recv->sender_node_id);
+	we->sport = (int)gm_ntoh_u8(recv->sender_port_id);
+	we->type = (int)gm_ntoh_u8(recv->type);
+	we->length = (int)gm_ntohl(recv->length);
+
+	spin_lock(&nal_data->rxtwe_lock);
+	if (nal_data->rxtwe_tail) {
+		nal_data->rxtwe_tail->next = we;
+	} else {
+		nal_data->rxtwe_head = we;
+		nal_data->rxtwe_tail = we;
+	}
+	nal_data->rxtwe_tail = we;
+	spin_unlock(&nal_data->rxtwe_lock);
+
+	up(&nal_data->rxtwe_wait);
+	return(GMNAL_STATUS_OK);
+}
+
+void
+gmnal_remove_rxtwe(gmnal_data_t *nal_data)
+{
+	gmnal_rxtwe_t	*_we, *we = nal_data->rxtwe_head;
+
+	CDEBUG(D_NET, "removing all work list entries\n");
+
+	spin_lock(&nal_data->rxtwe_lock);
+	CDEBUG(D_NET, "Got lock\n");
+	while (we) {
+		_we = we;
+		we = we->next;
+		PORTAL_FREE(_we, sizeof(gmnal_rxtwe_t));
+	}
+	spin_unlock(&nal_data->rxtwe_lock);
+	nal_data->rxtwe_head = NULL;
+	nal_data->rxtwe_tail = NULL;
+}
+
+gmnal_rxtwe_t *
+gmnal_get_rxtwe(gmnal_data_t *nal_data)
+{
+	gmnal_rxtwe_t	*we = NULL;
+
+	CDEBUG(D_NET, "Getting entry to list\n");
+
+	do  {
+		down(&nal_data->rxtwe_wait);
+		if (nal_data->rxthread_stop_flag == GMNAL_THREAD_STOP) {
+			/*
+			 *	time to stop
+			 * 	TO DO some one free the work entries	
+			 */
+			return(NULL);
+		}
+		spin_lock(&nal_data->rxtwe_lock);
+		if (nal_data->rxtwe_head) {
+			CDEBUG(D_WARNING, "Got a work entry\n");
+			we = nal_data->rxtwe_head;
+			nal_data->rxtwe_head = we->next;
+			if (!nal_data->rxtwe_head)
+				nal_data->rxtwe_tail = NULL;
+		} else {
+			CDEBUG(D_WARNING, "woken but no work\n");
+		}
+		spin_unlock(&nal_data->rxtwe_lock);
+	} while (!we);
+
+	CDEBUG(D_WARNING, "Returning we[%p]\n", we);
+	return(we);
+}
+
+
+/*
+ *	Start the caretaker thread and a number of receiver threads
+ *	The caretaker thread gets events from the gm library.
+ *	It passes receive events to the receiver threads via a work list.
+ *	It processes other events itself in gm_unknown. These will be
+ *	callback events or sleeps.
+ */
+int
+gmnal_start_kernel_threads(gmnal_data_t *nal_data)
+{
+
+	int	threads = 0;
+	/*
+ 	 *	the alarm is used to wake the caretaker thread from 
+	 *	gm_unknown call (sleeping) to exit it.
+	 */
+	CDEBUG(D_NET, "Initializing caretaker thread alarm and flag\n");
+	gm_initialize_alarm(&nal_data->ctthread_alarm);
+	nal_data->ctthread_flag = GMNAL_THREAD_RESET;
+
+
+	CDEBUG(D_INFO, "Starting caretaker thread\n");
+	nal_data->ctthread_pid = 
+	         kernel_thread(gmnal_ct_thread, (void*)nal_data, 0);
+	if (nal_data->ctthread_pid <= 0) {
+		CDEBUG(D_ERROR, "Caretaker thread failed to start\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	while (nal_data->rxthread_flag != GMNAL_THREAD_RESET) {
+		gmnal_yield(1);
+		CDEBUG(D_INFO, "Waiting for caretaker thread signs of life\n");
+	}
+
+	CDEBUG(D_INFO, "caretaker thread has started\n");
+
+
+	/*
+ 	 *	Now start a number of receiver threads
+	 *	these treads get work to do from the caretaker (ct) thread
+	 */
+	nal_data->rxthread_flag = GMNAL_THREAD_RESET;
+	nal_data->rxthread_stop_flag = GMNAL_THREAD_RESET;
+
+	for (threads=0; threads<NRXTHREADS; threads++)
+		nal_data->rxthread_pid[threads] = -1;
+	spin_lock_init(&nal_data->rxtwe_lock);
+	spin_lock_init(&nal_data->rxthread_flag_lock);
+	sema_init(&nal_data->rxtwe_wait, 0);
+	nal_data->rxtwe_head = NULL;
+	nal_data->rxtwe_tail = NULL;
+        /*
+         *      If the default number of receive threades isn't
+         *      modified at load time, then start one thread per cpu
+         */
+        if (num_rx_threads == -1)
+                num_rx_threads = smp_num_cpus;
+	CDEBUG(D_INFO, "Starting [%d] receive threads\n", num_rx_threads);
+	for (threads=0; threads<num_rx_threads; threads++) {
+		nal_data->rxthread_pid[threads] = 
+		       kernel_thread(gmnal_rx_thread, (void*)nal_data, 0);
+		if (nal_data->rxthread_pid[threads] <= 0) {
+			CDEBUG(D_ERROR, "Receive thread failed to start\n");
+			gmnal_stop_rxthread(nal_data);
+			gmnal_stop_ctthread(nal_data);
+			return(GMNAL_STATUS_FAIL);
+		}
+	}
+
+	for (;;) {
+		spin_lock(&nal_data->rxthread_flag_lock);
+		if (nal_data->rxthread_flag == GMNAL_RXTHREADS_STARTED) {
+			spin_unlock(&nal_data->rxthread_flag_lock);
+			break;
+		}
+		spin_unlock(&nal_data->rxthread_flag_lock);
+		gmnal_yield(1);
+	}
+
+	CDEBUG(D_INFO, "receive threads seem to have started\n");
+
+	return(GMNAL_STATUS_OK);
+}
diff --git a/lnet/klnds/gmlnd/gmnal.c b/lnet/klnds/gmlnd/gmnal.c
deleted file mode 100644
index 0cffc1587b48367e547bfe0e0dbf3c3d20d98b59..0000000000000000000000000000000000000000
--- a/lnet/klnds/gmlnd/gmnal.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Based on ksocknal and qswnal
- *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *   Author: Robert Read  <rread@datarithm.net>
- *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- *
- *   Portals is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Portals 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 Portals; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "gmnal.h"
-
-ptl_handle_ni_t kgmnal_ni;
-nal_t  kgmnal_api;
-
-kgmnal_data_t kgmnal_data;
-int gmnal_debug = 0;
-
-kpr_nal_interface_t kqswnal_router_interface = {
-        kprni_nalid:        GMNAL,
-        kprni_arg:        NULL,
-        kprni_fwd:          kgmnal_fwd_packet,
-};
-
-static int kgmnal_forward(nal_t   *nal,
-                          int     id,
-                          void    *args,  size_t args_len,
-                          void    *ret,   size_t ret_len)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        lib_dispatch(nal_cb, k, id, args, ret); /* nal needs k */
-        return PTL_OK;
-}
-
-static void kgmnal_lock(nal_t *nal, unsigned long *flags)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        nal_cb->cb_cli(nal_cb,flags);
-}
-
-static void kgmnal_unlock(nal_t *nal, unsigned long *flags)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        nal_cb->cb_sti(nal_cb,flags);
-}
-
-static int kgmnal_shutdown(nal_t *nal, int ni)
-{
-        LASSERT (nal == &kgmnal_api);
-        return 0;
-}
-
-static void kgmnal_yield( nal_t *nal )
-{
-        LASSERT (nal == &kgmnal_api);
-
-        if (current->need_resched)
-                schedule();
-        return;
-}
-
-kgmnal_rx_t *kgm_add_recv(kgmnal_data_t *data,int ndx)
-{
-        kgmnal_rx_t *conn;
-
-        PORTAL_ALLOC(conn, sizeof(kgmnal_rx_t));
-        /* Check for out of mem here */
-        if (conn==NULL) {
-                        printk("kgm_add_recv: memory alloc failed\n");
-                        return NULL;
-        }
-
-        list_add(&conn->krx_item,(struct list_head *)&data->kgm_list);
-        //        conn->ndx=ndx;
-        //        conn->len=conn->ptlhdr_copied=0;
-        //        conn->loopback=0;
-        return conn;
-}
-
-static nal_t *kgmnal_init(int interface, ptl_pt_index_t ptl_size,
-                          ptl_ac_index_t  ac_size, ptl_pid_t requested_pid)
-{
-        unsigned int nnids;
-
-        gm_max_node_id_in_use(kgmnal_data.kgm_port, &nnids);
-
-        CDEBUG(D_NET, "calling lib_init with nid 0x%Lx of %d\n",
-               kgmnal_data.kgm_nid, nnids);
-        lib_init(&kgmnal_lib, kgmnal_data.kgm_nid, 0, nnids,ptl_size, ac_size);
-        return &kgmnal_api;
-}
-
-static void /*__exit*/
-kgmnal_finalize(void)
-{
-        struct list_head *tmp;
-
-        PORTAL_SYMBOL_UNREGISTER (kgmnal_ni);
-        PtlNIFini(kgmnal_ni);
-        lib_fini(&kgmnal_api);
-
-        if (kgmnal_data.kgm_port) {
-                gm_close(kgmnal_data.kgm_port);
-        }
-
-        /* FIXME: free dma buffers */
-        /* FIXME: kill receiver thread */
-
-        PORTAL_FREE (kgmnal_data.kgm_trans, bsizeof(kgmnal_tx_t)*TXMSGS);
-
-        list_for_each(tmp, &kgmnal_data.kgm_list) {
-                kgmnal_rx_t *conn;
-                conn = list_entry(tmp, kgmnal_rx_t, krx_item);
-                CDEBUG(D_IOCTL, "freeing conn %p\n",conn);
-                tmp = tmp->next;
-                list_del(&conn->krx_item);
-                PORTAL_FREE(conn, sizeof(*conn));
-        }
-
-        CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read (&portal_kmemory));
-
-        return;
-}
-
-static int __init
-kgmnal_initialize(void)
-{
-        int rc;
-        int ntok;
-        unsigned long sizemask;
-        unsigned int nid;
-
-        CDEBUG (D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
-
-        kgmnal_api.forward = kgmnal_forward;
-        kgmnal_api.shutdown = kgmnal_shutdown;
-        kgmnal_api.yield = kgmnal_yield;
-        kgmnal_api.validate = NULL;         /* our api validate is a NOOP */
-        kgmnal_api.lock= kgmnal_lock;
-        kgmnal_api.unlock= kgmnal_unlock;
-        kgmnal_api.nal_data = &kgmnal_data;
-
-        kgmnal_lib.nal_data = &kgmnal_data;
-
-        memset(&kgmnal_data, 0, sizeof(kgmnal_data));
-
-        INIT_LIST_HEAD(&kgmnal_data.kgm_list);
-        kgmnal_data.kgm_cb = &kgmnal_lib;
-
-        /* Allocate transmit descriptors */
-        PORTAL_ALLOC (kgmnal_data.kgm_trans, sizeof(kgmnal_tx_t)*TXMSGS);
-        if (kgmnal_data.kgm_trans==NULL) {
-                printk("kgmnal: init: failed to allocate transmit "
-                       "descriptors\n");
-                return -1;
-        }
-        memset(kgmnal_data.kgm_trans,-1,sizeof(kgmnal_tx_t)*(TXMSGS));
-
-        spin_lock_init(&kgmnal_data.kgm_dispatch_lock);
-        spin_lock_init(&kgmnal_data.kgm_update_lock);
-        spin_lock_init(&kgmnal_data.kgm_send_lock);
-
-        /* Do the receiver and xmtr allocation */
-
-        rc = gm_init();
-        if (rc != GM_SUCCESS) {
-                CERROR("gm_init failed: %d\n", rc);
-                return -1;
-        }
-
-        rc = gm_open(&kgmnal_data.kgm_port, 0 , KGM_PORT_NUM, KGM_HOSTNAME,
-                     GM_API_VERSION_1_1);
-        if (rc != GM_SUCCESS) {
-                gm_finalize();
-                kgmnal_data.kgm_port = NULL;
-                CERROR("gm_open failed: %d\n", rc);
-                return -1;
-        }
-        gm_get_node_id(kgmnal_data.kgm_port, &nid);
-        kgmnal_data.kgm_nid = nid;
-        /* Allocate 2 different sizes of buffers. For new, use half
-           the tokens for each. */
-        ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
-        CDEBUG(D_NET, "gmnal_init: creating %d large %d byte recv buffers\n",
-               ntok, MSG_LEN_LARGE);
-        while (ntok-- > 0) {
-                void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
-                                              MSG_LEN_LARGE);
-                if (buffer == NULL) {
-                        CERROR("gm_init failed: %d\n", rc);
-                        return (-ENOMEM);
-                }
-                CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
-                       "pri %d\n ", kgmnal_data.kgm_port, buffer,
-                       MSG_LEN_LARGE, MSG_SIZE_LARGE, GM_LOW_PRIORITY);
-
-                gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
-                                          MSG_SIZE_LARGE, GM_LOW_PRIORITY);
-        }
-
-        ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
-        CDEBUG(D_NET, "gmnal_init: creating %d small %d byte recv buffers\n",
-               ntok, MSG_LEN_SMALL);
-        while (ntok-- > 0) {
-                void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
-                                              MSG_LEN_SMALL);
-                if (buffer == NULL) {
-                        CERROR("gm_init failed: %d\n", rc);
-                        return (-ENOMEM);
-                }
-                CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
-                       "pri %d\n ", kgmnal_data.kgm_port, buffer,
-                       MSG_LEN_SMALL, MSG_SIZE_SMALL, GM_LOW_PRIORITY);
-
-                gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
-                                          MSG_SIZE_SMALL, GM_LOW_PRIORITY);
-
-        }
-        sizemask = (1 << MSG_SIZE_LARGE) | (1 << MSG_SIZE_SMALL);
-        CDEBUG(D_NET, "gm_set_acceptable_sizes port %p pri %d mask 0x%x\n",
-                        kgmnal_data.kgm_port, GM_LOW_PRIORITY, sizemask);
-        gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_LOW_PRIORITY,
-                                sizemask);
-        gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_HIGH_PRIORITY, 0);
-
-        /* Initialize Network Interface */
-        rc = PtlNIInit(kgmnal_init, 32, 4, 0, &kgmnal_ni);
-        if (rc) {
-                CERROR("PtlNIInit failed %d\n", rc);
-                return (-ENOMEM);
-        }
-
-        /* Start receiver thread */
-        kernel_thread(kgmnal_recv_thread, &kgmnal_data, 0);
-
-        PORTAL_SYMBOL_REGISTER(kgmnal_ni);
-
-        kgmnal_data.kgm_init = 1;
-
-        return 0;
-}
-
-MODULE_AUTHOR("Robert Read <rread@datarithm.net>");
-MODULE_DESCRIPTION("Kernel Myrinet GM NAL v0.1");
-MODULE_LICENSE("GPL");
-
-module_init (kgmnal_initialize);
-module_exit (kgmnal_finalize);
-
-EXPORT_SYMBOL (kgmnal_ni);
diff --git a/lnet/klnds/iblnd/.cvsignore b/lnet/klnds/iblnd/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..e9955884756af11fe171e89bf99e459ac44f1a2a
--- /dev/null
+++ b/lnet/klnds/iblnd/.cvsignore
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in
diff --git a/lnet/klnds/iblnd/Makefile.am b/lnet/klnds/iblnd/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..84818dc115cdadc8c42e7c6f4a8d042f7fedf482
--- /dev/null
+++ b/lnet/klnds/iblnd/Makefile.am
@@ -0,0 +1,10 @@
+include ../../Rules.linux
+
+MODULE = kibnal
+modulenet_DATA = kibnal.o
+EXTRA_PROGRAMS = kibnal
+
+
+DEFS =
+CPPFLAGS=@CPPFLAGS@ @with_ib@
+kibnal_SOURCES = ibnal.h ibnal.c ibnal_cb.c
diff --git a/lnet/klnds/iblnd/ibnal.c b/lnet/klnds/iblnd/ibnal.c
new file mode 100644
index 0000000000000000000000000000000000000000..948badf0213a5d90ac81549e01baa5fc18f553b4
--- /dev/null
+++ b/lnet/klnds/iblnd/ibnal.c
@@ -0,0 +1,2146 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Based on ksocknal, qswnal, and gmnal
+ *
+ * Copyright (C) 2003 LANL 
+ *   Author: HB Chen <hbchen@lanl.gov>
+ *   Los Alamos National Lab
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals 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 Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *   
+ */
+
+#include "ibnal.h"
+
+// portal handle ID for this IB-NAL
+ptl_handle_ni_t kibnal_ni;
+
+// message send buffer mutex
+spinlock_t   MSBuf_mutex[NUM_MBUF];
+
+// message recv buffer mutex
+spinlock_t   MRBuf_mutex[NUM_MBUF];
+
+// IB-NAL API information 
+nal_t  kibnal_api; 
+
+// nal's private data 
+kibnal_data_t kibnal_data; 
+
+int ibnal_debug = 0;
+VAPI_pd_hndl_t      Pd_hndl;    
+unsigned int    Num_posted_recv_buf;
+
+// registered send buffer list
+Memory_buffer_info MSbuf_list[NUM_MBUF]; 
+
+// registered recv buffer list 
+Memory_buffer_info MRbuf_list[NUM_MBUF];
+
+//
+// for router 
+// currently there is no need fo IBA  
+//
+kpr_nal_interface_t kibnal_router_interface = {
+        kprni_nalid: IBNAL,
+        kprni_arg:   &kibnal_data,
+        kprni_fwd:   kibnal_fwd_packet, // forward data to router  
+                                        // is router invloving the
+                                        // data transmision 
+};
+
+
+// Queue-pair list 
+QP_info QP_list[NUM_QPS];
+
+// information associated with a HCA 
+HCA_info        Hca_data;
+
+// something about HCA 
+VAPI_hca_hndl_t      Hca_hndl; // assume we only use one HCA now 
+VAPI_hca_vendor_t    Hca_vendor;
+VAPI_hca_cap_t       Hca_cap;
+VAPI_hca_port_t      Hca_port_1_props;
+VAPI_hca_port_t      Hca_port_2_props;
+VAPI_hca_attr_t      Hca_attr;
+VAPI_hca_attr_mask_t Hca_attr_mask;
+VAPI_cq_hndl_t       Cq_RQ_hndl;    // CQ's handle
+VAPI_cq_hndl_t       Cq_SQ_hndl;    // CQ's handle
+VAPI_cq_hndl_t       Cq_hndl;    // CQ's handle
+Remote_QP_Info       L_QP_data;
+Remote_QP_Info       R_QP_data;
+
+
+//
+// forward  API
+//
+int 
+kibnal_forward(nal_t   *nal,
+               int     id,
+               void    *args,  
+               size_t args_len,
+               void    *ret,   
+               size_t ret_len)
+{
+        kibnal_data_t *knal_data = nal->nal_data;
+        nal_cb_t      *nal_cb = knal_data->kib_cb;
+
+        // ASSERT checking 
+        LASSERT (nal == &kibnal_api);
+        LASSERT (knal_data == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // dispatch forward API function 
+        
+        CDEBUG(D_NET,"kibnal_forward: function id = %d\n", id);
+
+        lib_dispatch(nal_cb, knal_data, id, args, ret); 
+
+        CDEBUG(D_TRACE,"IBNAL- Done kibnal_forward\n");
+
+        return PTL_OK; // always return PTL_OK
+}
+
+//
+// lock API  
+//
+void 
+kibnal_lock(nal_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *knal_data = nal->nal_data;
+        nal_cb_t      *nal_cb = knal_data->kib_cb;
+
+        // ASSERT checking 
+        LASSERT (nal == &kibnal_api);
+        LASSERT (knal_data == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // disable logical interrrupt 
+        nal_cb->cb_cli(nal_cb,flags);
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_lock\n");
+
+}
+
+//
+// unlock API
+//
+void 
+kibnal_unlock(nal_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+
+        // ASSERT checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // enable logical interrupt 
+        nal_cb->cb_sti(nal_cb,flags);
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_unlock");
+
+}
+
+//
+// shutdown API 
+//     showdown this network interface 
+//
+int
+kibnal_shutdown(nal_t *nal, int ni)
+{       
+        VAPI_ret_t          vstat;
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+
+        // assert checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // take down this IB network interface 
+        // there is not corresponding cb function to hande this
+        // do we actually need this one 
+        // reference to IB network interface shutdown 
+        //
+        
+        vstat = IB_Close_HCA();
+
+        if (vstat != VAPI_OK) {
+           CERROR("Failed to close HCA  - %s\n",VAPI_strerror(vstat));
+           return (~PTL_OK);
+        }
+
+        CDEBUG(D_TRACE,"IBNAL- Done kibnal_shutdown\n");
+
+        return PTL_OK;
+}
+
+//
+// yield 
+// when do we call this yield function 
+//
+void 
+kibnal_yield( nal_t *nal )
+{
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+        
+        // assert checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k    == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // check under what condition that we need to 
+        // call schedule()
+        // who set this need_resched 
+        if (current->need_resched)
+                schedule();
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_yield");
+
+        return;
+}
+
+//
+// ibnal init 
+//
+nal_t *
+kibnal_init(int             interface, // no use here 
+            ptl_pt_index_t  ptl_size,
+            ptl_ac_index_t  ac_size, 
+            ptl_pid_t       requested_pid // no use here
+           )
+{
+  nal_t         *nal       = NULL;
+  nal_cb_t      *nal_cb    = NULL;
+  kibnal_data_t *nal_data  = NULL;
+  int            rc;
+
+  unsigned int nnids = 1; // number of nids 
+                          // do we know how many nodes are in this
+                          // system related to this kib_nid  
+                          //
+
+  CDEBUG(D_NET, "kibnal_init:calling lib_init with nid 0x%u\n",
+                  kibnal_data.kib_nid);
+
+
+  CDEBUG(D_NET, "kibnal_init: interface [%d], ptl_size [%d], ac_size[%d]\n", 
+                 interface, ptl_size, ac_size);
+  CDEBUG(D_NET, "kibnal_init: &kibnal_lib  0x%X\n", &kibnal_lib);
+  CDEBUG(D_NET, "kibnal_init: kibnal_data.kib_nid  %d\n", kibnal_data.kib_nid);
+
+  rc = lib_init(&kibnal_lib, 
+                kibnal_data.kib_nid, 
+                0, // process id is set as 0  
+                nnids,
+                ptl_size, 
+                ac_size);
+
+  if(rc != PTL_OK) {
+     CERROR("kibnal_init: Failed lib_init with nid 0x%u, rc=%d\n",
+                                  kibnal_data.kib_nid,rc);
+  }
+  else {
+      CDEBUG(D_NET,"kibnal_init: DONE lib_init with nid 0x%x%x\n",
+                                  kibnal_data.kib_nid);
+  }
+
+  return &kibnal_api;
+
+}
+
+
+//
+// called before remove ibnal kernel module 
+//
+void __exit 
+kibnal_finalize(void) 
+{ 
+        struct list_head *tmp;
+
+        inter_module_unregister("kibnal_ni");
+
+        // release resources allocated to this Infiniband network interface 
+        PtlNIFini(kibnal_ni); 
+
+        lib_fini(&kibnal_lib); 
+
+        IB_Close_HCA();
+
+        // how much do we need to do here?
+        list_for_each(tmp, &kibnal_data.kib_list) {
+                kibnal_rx_t *conn;
+                conn = list_entry(tmp, kibnal_rx_t, krx_item);
+                CDEBUG(D_IOCTL, "freeing conn %p\n",conn);
+                tmp = tmp->next;
+                list_del(&conn->krx_item);
+                PORTAL_FREE(conn, sizeof(*conn));
+        }
+
+        CDEBUG(D_MALLOC,"done kmem %d\n",atomic_read(&portal_kmemory));
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_finalize\n");
+
+        return;
+}
+
+
+//
+// * k_server_thread is a kernel thread 
+//   use a shared memory ro exchange HCA's data with a pthread in user 
+//   address space
+// * will be replaced when CM is used to handle communication management 
+//
+
+void k_server_thread(Remote_QP_Info *hca_data)
+{
+  int              segment_id;
+  const int        shared_segment_size = sizeof(Remote_QP_Info); 
+  key_t            key = HCA_EXCHANGE_SHM_KEY;
+  unsigned long    raddr;
+  int exchanged_done = NO;
+  int i;
+
+  Remote_QP_Info  *exchange_hca_data;
+
+  long *n;
+  long *uaddr;
+  long ret = 0;
+ 
+  // create a shared memory with pre-agreement key
+  segment_id =  sys_shmget(key,
+                           shared_segment_size,
+                           IPC_CREAT | 0666);
+
+
+  // attached to shared memoru 
+  // raddr is pointed to an user address space 
+  // use this address to update shared menory content 
+  ret = sys_shmat(segment_id, 0 , SHM_RND, &raddr);
+
+#ifdef IBNAL_DEBUG 
+  if(ret >= 0) {
+    CDEBUG(D_NET,"k_server_thread: Shared memory attach success ret = 0X%d,&raddr"
+                   " 0X%x (*(&raddr))=0x%x \n", ret, &raddr,  (*(&raddr)));
+    printk("k_server_thread: Shared memory attach success ret = 0X%d, &raddr"
+                   " 0X%x (*(&raddr))=0x%x \n", ret, &raddr,  (*(&raddr)));
+  }
+  else {
+    CERROR("k_server_thread: Shared memory attach failed ret = 0x%d \n", ret); 
+    printk("k_server_thread: Shared memory attach failed ret = 0x%d \n", ret); 
+    return;
+  }
+#endif
+
+  n = &raddr;
+  uaddr = *n; // get the U-address 
+  /* cast uaddr to exchange_hca_data */
+  exchange_hca_data = (Remote_QP_Info  *) uaddr; 
+  
+  /* copy data from local HCA to shared memory */
+  exchange_hca_data->opcode  = hca_data->opcode;
+  exchange_hca_data->length  = hca_data->length;
+
+  for(i=0; i < NUM_QPS; i++) {
+    exchange_hca_data->dlid[i]    = hca_data->dlid[i];
+    exchange_hca_data->rqp_num[i] = hca_data->rqp_num[i];
+  }
+
+  // periodically check shared memory until get updated 
+  // remote HCA's data from user mode pthread  
+  while(exchanged_done == NO) {
+    if(exchange_hca_data->opcode == RECV_QP_INFO){
+       exchanged_done = YES;
+       /* copy data to local buffer from shared memory */
+       hca_data->opcode  = exchange_hca_data->opcode;
+       hca_data->length  = exchange_hca_data->length;
+
+       for(i=0; i < NUM_QPS; i++) {
+         hca_data->dlid[i]    = exchange_hca_data->dlid[i];
+         hca_data->rqp_num[i] = exchange_hca_data->rqp_num[i];
+       }
+       break;
+    }
+    else { 
+       schedule_timeout(1000);
+    }
+  }
+  
+  // detached shared memory 
+  sys_shmdt(uaddr);
+
+  CDEBUG(D_NET, "Exit from kernel thread: k_server_thread \n");
+  printk("Exit from kernel thread: k_server_thread \n");
+
+  return;
+
+}
+
+//
+// create QP 
+// 
+VAPI_ret_t 
+create_qp(QP_info *qp, int qp_index)
+{
+
+  VAPI_ret_t          vstat;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_prop_t      qp_prop;
+
+  qp->hca_hndl = Hca_hndl;
+  qp->port     = 1; // default 
+  qp->slid     = Hca_port_1_props.lid;
+  qp->hca_port = Hca_port_1_props;
+
+
+  /* Queue Pair Creation Attributes */
+  qp_init_attr.cap.max_oust_wr_rq = NUM_WQE;
+  qp_init_attr.cap.max_oust_wr_sq = NUM_WQE;
+  qp_init_attr.cap.max_sg_size_rq = NUM_SG;
+  qp_init_attr.cap.max_sg_size_sq = NUM_SG;
+  qp_init_attr.pd_hndl            = qp->pd_hndl;
+  qp_init_attr.rdd_hndl           = 0;
+  qp_init_attr.rq_cq_hndl         = qp->rq_cq_hndl;
+  /* we use here polling */
+  //qp_init_attr.rq_sig_type        = VAPI_SIGNAL_REQ_WR;
+  qp_init_attr.rq_sig_type        = VAPI_SIGNAL_ALL_WR;
+  qp_init_attr.sq_cq_hndl         = qp->sq_cq_hndl;
+  /* we use here polling */
+  //qp_init_attr.sq_sig_type        = VAPI_SIGNAL_REQ_WR;
+  qp_init_attr.sq_sig_type        = VAPI_SIGNAL_ALL_WR;
+  // transport servce - reliable connection
+
+  qp_init_attr.ts_type            = VAPI_TS_RC;
+          
+  vstat = VAPI_create_qp(qp->hca_hndl,   
+                         &qp_init_attr,      
+                         &qp->qp_hndl, &qp_prop); 
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed creating QP. Return Failed - %s\n",VAPI_strerror(vstat));
+     return vstat;
+  }
+  
+  qp->qp_num = qp_prop.qp_num; // the qp number 
+  qp->last_posted_send_id  = 0; // user defined work request ID
+  qp->last_posted_rcv_id   = 0; // user defined work request ID
+  qp->cur_send_outstanding = 0;
+  qp->cur_posted_rcv_bufs  = 0;
+  qp->snd_rcv_balance      = 0;
+  
+  CDEBUG(D_OTHER, "create_qp: qp_num = %d, slid = %d, qp_hndl = 0X%X", 
+                  qp->qp_num, qp->slid, qp->qp_hndl);
+
+  // initialize spin-lock mutex variables
+  spin_lock_init(&(qp->snd_mutex));
+  spin_lock_init(&(qp->rcv_mutex));
+  spin_lock_init(&(qp->bl_mutex));
+  spin_lock_init(&(qp->cln_mutex));
+  // number of outstanding requests on the send Q
+  qp->cur_send_outstanding = 0; 
+  // number of posted receive buffers
+  qp->cur_posted_rcv_bufs  = 0;  
+  qp->snd_rcv_balance      = 0;
+
+  return(VAPI_OK);
+
+}
+
+//
+// initialize a UD qp state to RTR and RTS 
+//
+VAPI_ret_t 
+init_qp_UD(QP_info *qp, int qp_index)
+{
+  VAPI_qp_attr_t      qp_attr;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_attr_mask_t qp_attr_mask;
+  VAPI_qp_cap_t       qp_cap;
+  VAPI_ret_t       vstat;
+
+  /* Move from RST to INIT */
+  /* Change QP to INIT */
+
+  CDEBUG(D_OTHER, "Changing QP state to INIT qp-index = %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state = VAPI_INIT;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix  = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "pkey_ix qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.port     = qp->port;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PORT);
+
+  CDEBUG(D_OTHER, "port qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.qkey = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QKEY);
+
+  CDEBUG(D_OTHER, "qkey qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  /* If I do not set this mask, I get an error from HH. QPM should catch it */
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RST to INIT. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  CDEBUG(D_OTHER, "Modifying QP from RST to INIT.\n");
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Move from INIT to RTR */
+  /* Change QP to RTR */
+  CDEBUG(D_OTHER, "Changing QP state to RTR\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state         = VAPI_RTR;  
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "INIT to RTR- qp_state : qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from INIT to RTR. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+  
+  CDEBUG(D_OTHER, "Modifying QP from INIT to RTR.\n");
+  
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                                      
+  /* RTR to RTS - Change QP to RTS */
+  CDEBUG(D_OTHER, "Changing QP state to RTS\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state        = VAPI_RTS;   
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+  
+  qp_attr.sq_psn          = START_SQ_PSN;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_SQ_PSN);
+  
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RTR to RTS. %s:%s\n",
+                          VAPI_strerror_sym(vstat), 
+                          VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  CDEBUG(D_OTHER, "Modifying QP from RTR to RTS. \n");
+                     
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                        
+  //
+  // a QP is at RTS state NOW
+  //
+ 
+  CDEBUG(D_OTHER, "IBNAL- UD qp is at RTS NOW\n");
+  
+  return(vstat);
+
+}
+
+
+
+//
+// initialize a RC qp state to RTR and RTS 
+// RC transport service 
+//
+VAPI_ret_t 
+init_qp_RC(QP_info *qp, int qp_index)
+{
+  VAPI_qp_attr_t      qp_attr;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_attr_mask_t qp_attr_mask;
+  VAPI_qp_cap_t       qp_cap;
+  VAPI_ret_t       vstat;
+
+  /* Move from RST to INIT */
+  /* Change QP to INIT */
+  
+  CDEBUG(D_OTHER, "Changing QP state to INIT qp-index = %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state = VAPI_INIT;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+   CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix  = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "pkey_ix qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.port     = qp->port;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PORT);
+
+  CDEBUG(D_OTHER, "port qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.remote_atomic_flags = VAPI_EN_REM_WRITE | VAPI_EN_REM_READ;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_REMOTE_ATOMIC_FLAGS);
+
+  CDEBUG(D_OTHER, "remote_atomic_flags qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  /* If I do not set this mask, I get an error from HH. QPM should catch it */
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RST to INIT. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Move from INIT to RTR */
+  /* Change QP to RTR */
+  CDEBUG(D_OTHER, "Changing QP state to RTR qp_indexi %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+  qp_attr.qp_state         = VAPI_RTR;  
+
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.av.sl            = 0;/* RESPONDER_SL */
+  qp_attr.av.grh_flag      = FALSE;
+  qp_attr.av.dlid          = qp->dlid;/*RESPONDER_LID;*/
+  qp_attr.av.static_rate   = 0;
+  qp_attr.av.src_path_bits = 0;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_AV);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.path_mtu         = MTU_2048;// default is MTU_2048             
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PATH_MTU);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.rq_psn           = START_RQ_PSN;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RQ_PSN);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.qp_ous_rd_atom   = NUM_WQE;        
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_OUS_RD_ATOM);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix          = 0;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.min_rnr_timer    = 10;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_MIN_RNR_TIMER);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.dest_qp_num = qp->rqp_num;                   
+
+  CDEBUG(D_OTHER, "remore qp num %d\n",  qp->rqp_num);
+
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_DEST_QP_NUM);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from INIT to RTR. qp_index %d - %s\n",
+                                                qp_index, VAPI_strerror(vstat));
+     return(vstat);
+  }
+  
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                                      
+  /* RTR to RTS - Change QP to RTS */
+  CDEBUG(D_OTHER, "Changing QP state to RTS\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state        = VAPI_RTS;   
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  qp_attr.sq_psn          = START_SQ_PSN;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_SQ_PSN);
+
+  qp_attr.timeout         = 0x18;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_TIMEOUT);
+
+  qp_attr.retry_count     = 10;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RETRY_COUNT);
+
+  qp_attr.rnr_retry       = 14;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RNR_RETRY);
+
+  qp_attr.ous_dst_rd_atom = 100;        
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_OUS_DST_RD_ATOM);
+
+  qp_attr.min_rnr_timer   = 5;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_MIN_RNR_TIMER);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RTR to RTS. %s:%s\n",
+                   VAPI_strerror_sym(vstat), VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                        
+  //
+  // a QP is at RTS state NOW
+  //
+ 
+   CDEBUG(D_OTHER, "IBNAL- RC qp is at RTS NOW\n");
+  
+  return(vstat);
+}
+
+
+
+VAPI_ret_t 
+IB_Open_HCA(kibnal_data_t *kib_data)
+{
+
+  VAPI_ret_t     vstat;
+  VAPI_cqe_num_t cqe_active_num;
+  QP_info        *qp; 
+  int            i;
+  int            Num_posted_recv_buf;
+
+  /* Open HCA */
+  CDEBUG(D_PORTALS, "Opening an HCA\n");
+
+  vstat = VAPI_open_hca(HCA_ID, &Hca_hndl);
+  vstat = EVAPI_get_hca_hndl(HCA_ID, &Hca_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed opening the HCA: %s. %s...\n",HCA_ID,VAPI_strerror(vstat));
+     return(vstat);
+  } 
+
+  /* Get HCA CAP */
+  vstat = VAPI_query_hca_cap(Hca_hndl, &Hca_vendor, &Hca_cap);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query hca cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Get port 1 info */
+  vstat = VAPI_query_hca_port_prop(Hca_hndl, HCA_PORT_1 , &Hca_port_1_props);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query port cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }      
+
+  /* Get port 2 info */
+  vstat = VAPI_query_hca_port_prop(Hca_hndl, HCA_PORT_2, &Hca_port_2_props);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query port cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }      
+
+  // Get a PD 
+  CDEBUG(D_PORTALS, "Allocating PD \n");
+  vstat = VAPI_alloc_pd(Hca_hndl,&Pd_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed allocating a PD. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat = createMemRegion(Hca_hndl, Pd_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed registering a memory region.%s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Create CQ for RQ*/
+  CDEBUG(D_PORTALS, "Creating a send completion queue\n");
+
+  vstat = VAPI_create_cq(Hca_hndl,    
+                         NUM_CQE,    
+                         &Cq_hndl, 
+                         &cqe_active_num);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed creating a CQ. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  if(NUM_CQE == cqe_active_num) {
+    CERROR("VAPI_create_cq: NUM_CQE EQ cqe_active_num \n");
+  }
+  else {
+    CDEBUG(D_NET, "VAPI_create_cq: NUM_CQE %d , actual cqe_active_num %d \n",
+                   NUM_CQE, cqe_active_num);
+  }
+
+  Cq_SQ_hndl     = Cq_hndl;
+  Cq_RQ_hndl     = Cq_hndl;
+
+  //
+  // create  QPs 
+  //
+  for(i=0; i < NUM_QPS; i++) {
+      QP_list[i].pd_hndl    = Pd_hndl;
+      QP_list[i].hca_hndl   = Hca_hndl;
+      // sq rq use the same Cq_hndl 
+      QP_list[i].sq_cq_hndl = Cq_hndl; 
+      QP_list[i].rq_cq_hndl = Cq_hndl;
+      vstat = create_qp(&QP_list[i], i);
+      if (vstat != VAPI_OK) {
+         CERROR("Failed creating a QP %d %s\n",i, VAPI_strerror(vstat));
+         return(vstat);
+      }
+  }      
+
+  //
+  // record HCA data 
+  //
+
+  Hca_data.hca_hndl     = Hca_hndl;      // HCA handle
+  Hca_data.pd_hndl      = Pd_hndl;       // protection domain
+  Hca_data.port         = 1;             // port number
+  Hca_data.num_qp       = NUM_QPS;        // number of qp used
+
+  for(i=0; i < NUM_QPS; i++) {
+    Hca_data.qp_ptr[i]    = &QP_list[i];   // point to QP_list
+  }
+
+  Hca_data.num_cq       = NUM_CQ;        // number of cq used
+  Hca_data.cq_hndl      = Cq_hndl;       // 
+  Hca_data.sq_cq_hndl   = Cq_SQ_hndl;    // 
+  Hca_data.rq_cq_hndl   = Cq_RQ_hndl;    // 
+  Hca_data.kib_data     = kib_data;       //
+  Hca_data.slid         = QP_list[0].slid;//
+
+  // prepare L_QP_data
+
+#ifdef USE_SHARED_MEMORY_AND_SOCKET
+
+  /*
+   *  + use a shared-memory between a user thread and a kernel thread 
+   *    for HCA's data exchange on the same node  
+   *  + use socket in user mode to exhange HCA's data with a remote node 
+   */
+
+  
+  R_QP_data.opcode  = SEND_QP_INFO;
+  R_QP_data.length  = sizeof(L_QP_data);
+
+  for(i=0; i < NUM_QPS; i++) {
+    // my slid  will be used in a remote node as dlid 
+    R_QP_data.dlid[i]    = QP_list[i].slid;
+    // my qp_num will be used in remode node as remote_qp_number 
+    // RC is used here so we need dlid and rqp_num  
+    R_QP_data.rqp_num[i] = QP_list[i].qp_num ;
+  }
+
+  // create a kernel thread for exchanging HCA's data 
+  // R_QP_data will be exchanged with a remoe node
+
+  kernel_thread(k_server_thread, &R_QP_data, 0); // 
+  // check if the HCA'data have been updated by kernel_thread 
+  // loop until the HCA's data is updated 
+  // make sure that uagent is running 
+  
+  // QP info is exchanged with a remote node   
+  while (1) {
+    schedule_timeout(1000);
+    if(R_QP_data.opcode ==  RECV_QP_INFO) {
+       CDEBUG(D_NET, "HCA's data is being updated\n");
+       break;
+   }
+  }
+ 
+#endif
+
+#ifdef USE_SHARED_MEMORY_AND_MULTICAST
+
+  /*
+   *  + use a shared-memory between a user thread and a kernel thread 
+   *    for HCA's data exchange on the same node  
+   *  + use Infinoband UR/multicast in user mode to exhange HCA's data with i
+   *    a remote node 
+   */
+
+  // use CM, opemSM 
+  
+#endif
+
+  // 
+  for(i=0; i < NUM_QPS; i++) {
+     qp = (QP_info *) &QP_list[i];
+     QP_list[i].rqp_num = R_QP_data.rqp_num[i]; // remoter qp number 
+     QP_list[i].dlid    = R_QP_data.dlid[i];    // remote dlid 
+  }
+
+  // already have remote_qp_num adn dlid information
+  // initialize QP to RTR/RTS state 
+  //
+  for(i=0; i < NUM_QPS; i++) {
+    vstat = init_qp_RC(&QP_list[i], i);
+    if (vstat != VAPI_OK) {
+       CERROR("Failed change a QP %d to RTS state%s\n",
+                    i,VAPI_strerror(vstat));
+       return(vstat);
+    }
+  }
+
+  // post receiving buffer before any send happened 
+  
+  Num_posted_recv_buf = post_recv_bufs( (VAPI_wr_id_t ) START_RECV_WRQ_ID); 
+
+  // for irregular completion event or some unexpected failure event 
+  vstat = IB_Set_Async_Event_Handler(Hca_data, &kibnal_data);
+  if (vstat != VAPI_OK) {
+     CERROR("IB_Set_Async_Event_Handler failed: %d\n", vstat);
+     return vstat;
+  }
+
+
+  CDEBUG(D_PORTALS, "IBNAL- done with IB_Open_HCA\n");
+
+  for(i=0;  i < NUM_MBUF; i++) {
+    spin_lock_init(&MSB_mutex[i]);
+  }
+
+  return(VAPI_OK);
+
+}
+
+
+/* 
+  Function:  IB_Set_Event_Handler()
+             
+             IN   Hca_info hca_data
+             IN   kibnal_data_t *kib_data  -- private data      
+             OUT  NONE
+
+        return: VAPI_OK - success
+                else    - fail 
+
+*/
+
+VAPI_ret_t 
+IB_Set_Event_Handler(HCA_info hca_data, kibnal_data_t *kib_data)
+{
+  VAPI_ret_t vstat;
+  EVAPI_compl_handler_hndl_t   comp_handler_hndl;
+
+  // register CQE_Event_Hnadler 
+  // VAPI function 
+  vstat = VAPI_set_comp_event_handler(hca_data.hca_hndl,
+                                      CQE_event_handler,
+                                      &hca_data);
+
+  /*
+  or use extended VAPI function 
+  vstat = EVAPI_set_comp_eventh(hca_data.hca_hndl,
+                                hca_data.cq_hndl,
+                                CQE_event_handler,
+                                &hca_data,
+                                &comp_handler_hndl
+                                );
+  */
+                                    
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Event_Handler: failed EVAPI_set_comp_eventh for"
+             " HCA ID = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+      return vstat;
+  }
+
+  // issue a request for completion ievent notification 
+  vstat = VAPI_req_comp_notif(hca_data.hca_hndl, 
+                              hca_data.cq_hndl,
+                              VAPI_NEXT_COMP); 
+
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Event_Handler: failed VAPI_req_comp_notif for HCA ID"
+             " = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+  }
+
+  return vstat;
+}
+
+
+
+/* 
+  Function:  IB_Set_Async_Event_Handler()
+             
+             IN   HCA_info hca_data
+             IN   kibnal_data_t *kib_data -- private data      
+             OUT  NONE
+
+        return: VAPI_OK - success
+                else    - fail 
+
+*/
+
+
+VAPI_ret_t 
+IB_Set_Async_Event_Handler(HCA_info hca_data, kibnal_data_t *kib_data)
+{
+  VAPI_ret_t    vstat;
+
+  //
+  // register an asynchronous event handler for this HCA 
+  //
+
+  vstat= VAPI_set_async_event_handler(hca_data.hca_hndl,
+                                      async_event_handler, 
+                                      kib_data);
+
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Async_Event_Handler: failed VAPI_set_async_comp_event_handler"
+             " for HCA ID = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+  }
+
+  return vstat;
+}
+
+//
+// IB_Close_HCA
+// close this Infiniband HCA interface 
+// release allocated resources to system 
+//
+VAPI_ret_t 
+IB_Close_HCA(void )
+{
+        
+  VAPI_ret_t  vstat;
+  int         ok = 1;
+  int         i;
+            
+  /* Destroy QP */
+  CDEBUG(D_PORTALS, "Destroying QP\n");
+
+  for(i=0; i < NUM_QPS; i++) {
+     vstat = VAPI_destroy_qp(QP_list[i].hca_hndl, QP_list[i].qp_hndl);
+     if (vstat != VAPI_OK) {
+        CERROR("Failed destroying QP %d. %s\n", i, VAPI_strerror(vstat));
+        ok = 0;
+     }
+  }
+
+  if (ok) {
+     /* Destroy CQ */
+     CDEBUG(D_PORTALS, "Destroying CQ\n");
+     for(i=0; i < NUM_QPS; i++) {
+        // send_cq adn receive_cq are shared the same CQ
+        // so only destroy one of them 
+        vstat = VAPI_destroy_cq(QP_list[i].hca_hndl, QP_list[i].sq_cq_hndl);
+        if (vstat != VAPI_OK) {
+           CERROR("Failed destroying CQ %d. %s\n", i, VAPI_strerror(vstat));
+           ok = 0;
+        }
+     }
+  }
+
+  if (ok) {
+     /* Destroy Memory Region */
+     CDEBUG(D_PORTALS, "Deregistering MR\n");
+     for(i=0; i < NUM_QPS; i++) {
+        vstat = deleteMemRegion(&QP_list[i], i);
+        if (vstat != VAPI_OK) {
+           CERROR("Failed deregister mem reg %d. %s\n",i, VAPI_strerror(vstat));
+           ok = 0;
+           break;
+        }
+     }
+  }
+
+  if (ok) {
+     // finally 
+     /* Close HCA */
+     CDEBUG(D_PORTALS, "Closing HCA\n");
+     vstat = VAPI_close_hca(Hca_hndl);
+     if (vstat != VAPI_OK) {
+        CERROR("Failed to close HCA. %s\n", VAPI_strerror(vstat));
+        ok = 0;
+     }
+  }
+
+  CDEBUG(D_PORTALS, "IBNAL- Done with closing HCA \n");
+  
+  return vstat; 
+}
+
+
+VAPI_ret_t 
+createMemRegion(VAPI_hca_hndl_t hca_hndl, 
+                   VAPI_pd_hndl_t  pd_hndl) 
+{
+  VAPI_ret_t  vstat;
+  VAPI_mrw_t  mrw;
+  VAPI_mrw_t  rep_mr;   
+  VAPI_mr_hndl_t   rep_mr_hndl;
+  int         buf_size;
+  char        *bufptr;
+  int         i;
+
+  // send registered memory region 
+  for(i=0; i < NUM_ENTRY; i++) {
+    MSbuf_list[i].buf_size = KB_32; 
+    PORTAL_ALLOC(bufptr, MSbuf_list[i].buf_size);
+    if(bufptr == NULL) {
+       CDEBUG(D_MALLOC,"Failed to malloc a block of send memory, qix %d size %d\n",
+                                          i, MSbuf_list[i].buf_size);
+       CERROR("Failed to malloc a block of send memory, qix %d size %d\n",
+                                          i, MSbuf_list[i].buf_size);
+       return(VAPI_ENOMEM);
+    }
+
+    mrw.type   = VAPI_MR; 
+    mrw.pd_hndl= pd_hndl;
+    mrw.start  = MSbuf_list[i].buf_addr = (VAPI_virt_addr_t)(MT_virt_addr_t) bufptr;
+    mrw.size   = MSbuf_list[i].buf_size;
+    mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+                 VAPI_EN_REMOTE_WRITE | 
+                 VAPI_EN_REMOTE_READ;
+
+    // register send memory region  
+    vstat = VAPI_register_mr(hca_hndl, 
+                             &mrw, 
+                             &rep_mr_hndl, 
+                             &rep_mr);
+
+    // this memory region is going to be reused until deregister is called 
+    if(vstat != VAPI_OK) {
+       CERROR("Failed registering a mem region qix %d Addr=%p, Len=%d. %s\n",
+                          i, mrw.start, mrw.size, VAPI_strerror(vstat));
+       return(vstat);
+    }
+
+    MSbuf_list[i].mr        = rep_mr;
+    MSbuf_list[i].mr_hndl   = rep_mr_hndl;
+    MSbuf_list[i].bufptr    = bufptr;
+    MSbuf_list[i].buf_addr  = rep_mr.start;
+    MSbuf_list[i].status    = BUF_REGISTERED;
+    MSbuf_list[i].ref_count = 0;
+    MSbuf_list[i].buf_type  = REG_BUF;
+    MSbuf_list[i].raddr     = 0x0;
+    MSbuf_list[i].rkey      = 0x0;
+  }
+
+  // RDAM buffer is not reserved for RDAM WRITE/READ
+  
+  for(i=NUM_ENTRY; i< NUM_MBUF; i++) {
+    MSbuf_list[i].status    = BUF_UNREGISTERED;
+    MSbuf_list[i].buf_type  = RDMA_BUF;
+  }
+
+
+  // recv registered memory region 
+  for(i=0; i < NUM_ENTRY; i++) {
+    MRbuf_list[i].buf_size = KB_32; 
+    PORTAL_ALLOC(bufptr, MRbuf_list[i].buf_size);
+
+    if(bufptr == NULL) {
+       CDEBUG(D_MALLOC, "Failed to malloc a block of send memory, qix %d size %d\n",
+                      i, MRbuf_list[i].buf_size);
+       return(VAPI_ENOMEM);
+    }
+
+    mrw.type   = VAPI_MR; 
+    mrw.pd_hndl= pd_hndl;
+    mrw.start  = (VAPI_virt_addr_t)(MT_virt_addr_t) bufptr;
+    mrw.size   = MRbuf_list[i].buf_size;
+    mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+                 VAPI_EN_REMOTE_WRITE | 
+                 VAPI_EN_REMOTE_READ;
+
+    // register send memory region  
+    vstat = VAPI_register_mr(hca_hndl, 
+                             &mrw, 
+                             &rep_mr_hndl, 
+                             &rep_mr);
+
+    // this memory region is going to be reused until deregister is called 
+    if(vstat != VAPI_OK) {
+       CERROR("Failed registering a mem region qix %d Addr=%p, Len=%d. %s\n",
+                          i, mrw.start, mrw.size, VAPI_strerror(vstat));
+       return(vstat);
+    }
+
+    MRbuf_list[i].mr        = rep_mr;
+    MRbuf_list[i].mr_hndl   = rep_mr_hndl;
+    MRbuf_list[i].bufptr    = bufptr;
+    MRbuf_list[i].buf_addr  = rep_mr.start;
+    MRbuf_list[i].status    = BUF_REGISTERED;
+    MRbuf_list[i].ref_count = 0;
+    MRbuf_list[i].buf_type  = REG_BUF;
+    MRbuf_list[i].raddr     = 0x0;
+    MRbuf_list[i].rkey      = rep_mr.r_key;
+    MRbuf_list[i].lkey      = rep_mr.l_key;
+  
+  }
+ 
+  // keep extra information for a qp 
+  for(i=0; i < NUM_QPS; i++) {
+    QP_list[i].mr_hndl    = MSbuf_list[i].mr_hndl; 
+    QP_list[i].mr         = MSbuf_list[i].mr;
+    QP_list[i].bufptr     = MSbuf_list[i].bufptr;
+    QP_list[i].buf_addr   = MSbuf_list[i].buf_addr;
+    QP_list[i].buf_size   = MSbuf_list[i].buf_size;
+    QP_list[i].raddr      = MSbuf_list[i].raddr;
+    QP_list[i].rkey       = MSbuf_list[i].rkey;
+    QP_list[i].lkey       = MSbuf_list[i].lkey;
+  }
+
+  CDEBUG(D_PORTALS, "IBNAL- done VAPI_ret_t createMemRegion \n");
+
+  return vstat;
+
+} /* createMemRegion */
+
+
+
+VAPI_ret_t  
+deleteMemRegion(QP_info *qp, int qix)
+{
+  VAPI_ret_t  vstat;
+
+  //
+  // free send memory assocaited with this memory region  
+  //
+  PORTAL_FREE(MSbuf_list[qix].bufptr, MSbuf_list[qix].buf_size);
+
+  // de-register it 
+  vstat =  VAPI_deregister_mr(qp->hca_hndl, MSbuf_list[qix].mr_hndl);
+
+  if(vstat != VAPI_OK) {
+     CERROR("Failed deregistering a send mem region qix %d %s\n",
+                         qix, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  //
+  // free recv memory assocaited with this memory region  
+  //
+  PORTAL_FREE(MRbuf_list[qix].bufptr, MRbuf_list[qix].buf_size);
+
+  // de-register it 
+  vstat =  VAPI_deregister_mr(qp->hca_hndl, MRbuf_list[qix].mr_hndl);
+
+  if(vstat != VAPI_OK) {
+     CERROR("Failed deregistering a recv mem region qix %d %s\n",
+                         qix, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  return vstat;
+}
+
+
+//
+// polling based event handling 
+// + a daemon process
+// + poll the CQ and check what is in the CQ 
+// + process incoming CQ event
+// + 
+//
+
+
+RDMA_Info_Exchange   Rdma_info;
+int                  Cts_Message_arrived = NO;
+
+void k_recv_thread(HCA_info *hca_data)
+{
+ VAPI_ret_t       vstat; 
+ VAPI_wc_desc_t   comp_desc;   
+ unsigned long    polling_count = 0;
+ u_int32_t        timeout_usec;
+ unsigned int     priority = 100;
+ unsigned int     length;
+ VAPI_wr_id_t     wrq_id;
+ u_int32_t        transferred_data_length; /* Num. of bytes transferred */
+ void             *bufdata;
+ VAPI_virt_addr_t bufaddr;
+ unsigned long    buf_size = 0;
+ QP_info          *qp;       // point to QP_list
+
+ kportal_daemonize("k_recv_thread"); // make it as a daemon process 
+
+ // tuning variable 
+ timeout_usec = 100; // how is the impact on the performance
+
+ // send Q and receive Q are using the same CQ 
+ // so only poll one CQ for both operations 
+ 
+ CDEBUG(D_NET, "IBNAL- enter kibnal_recv_thread\n");
+ CDEBUG(D_NET, "hca_hndl = 0X%x, cq_hndl=0X%x\n", 
+                         hca_data->hca_hndl,hca_data->cq_hndl); 
+
+ qp = hca_data->qp_ptr;
+ if(qp == NULL) {
+   CDEBUG(D_NET, "in recv_thread qp is NULL\n");
+   CDEBUG(D_NET, "Exit from  recv_thread qp is NULL\n");
+   return; 
+ }
+ else {
+   CDEBUG(D_NET, "in recv_thread qp is 0X%X\n", qp);
+ }
+
+ CDEBUG(D_NET, "kibnal_recv_thread - enter event driver polling loop\n");
+
+ //
+ // use event driver 
+ //
+ 
+
+
+ while(1) {
+    polling_count++;
+
+    //
+    // send Q and receive Q are using the same CQ 
+    // so only poll one CQ for both operations 
+    //
+
+    vstat = VAPI_poll_cq(hca_data->hca_hndl,hca_data->cq_hndl, &comp_desc);                      
+
+    if (vstat == VAPI_CQ_EMPTY) { 
+      // there is no event in CQE 
+      continue;
+    } 
+    else {
+      if (vstat != (VAPI_OK)) {
+        CERROR("error while polling completion queuei vstat %d \n", vstat);
+        return; 
+      }
+    }
+
+    // process the complete event 
+    switch(comp_desc.opcode) {
+      case   VAPI_CQE_SQ_SEND_DATA:
+        // about the Send Q ,POST SEND completion 
+        // who needs this information
+        // get wrq_id
+        // mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+               
+        wrq_id = comp_desc.id;
+
+        if(RDMA_OP_ID < wrq_id) {
+          // this RDMA message id, adjust it to the right entry       
+          wrq_id = wrq_id - RDMA_OP_ID;
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.send_rdma_mr_hndl);
+        }
+        
+        if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_SQ_SEND_DATA: Failed deregistering a RDMAi recv"                   " mem region %s\n", VAPI_strerror(vstat));
+        }
+
+        if((RDMA_CTS_ID <= wrq_id) && (RDMA_OP_ID < wrq_id)) {
+          // RTS or CTS send complete, release send buffer 
+          if(wrq_id >= RDMA_RTS_ID)
+            wrq_id = wrq_id - RDMA_RTS_ID;
+          else 
+            wrq_id = wrq_id - RDMA_CTS_ID;
+        }
+
+        spin_lock(&MSB_mutex[(int) wrq_id]);
+        MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+        spin_unlock(&MSB_mutex[(int) wrq_id]);
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_SEND_DATA\n");  
+        break;
+
+      case   VAPI_CQE_SQ_RDMA_WRITE:
+        // about the Send Q,  RDMA write completion 
+        // who needs this information
+        // data is successfully write from pource to  destionation 
+             
+        //  get wr_id
+        //  mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+        //  de-register  rdma buffer 
+        //
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_RDMA_WRITE\n");  
+        break;
+
+      case   VAPI_CQE_SQ_RDMA_READ:
+        // about the Send Q
+        // RDMA read completion 
+        // who needs this information
+        // data is successfully read from destionation to source 
+        CDEBUG(D_NET, "CQE opcode- VAPI_CQE_SQ_RDMA_READ\n");  
+        break;
+
+      case   VAPI_CQE_SQ_COMP_SWAP:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_COMP_SWAP\n");  
+        break;
+
+      case   VAPI_CQE_SQ_FETCH_ADD:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_FETCH_ADD\n");  
+        break;
+
+      case   VAPI_CQE_SQ_BIND_MRW:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_BIND_MRW\n");  
+        break;
+
+      case   VAPI_CQE_RQ_SEND_DATA:
+        // about the Receive Q
+        // process the incoming data and
+        // forward it to .....
+        // a completion recevie event is arriving at CQ 
+        // issue a recevie to get this arriving data out from CQ 
+        // pass the receiving data for further processing 
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_SEND_DATA\n");  
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if((wrq_id >= RDMA_CTS_ID) && (wrq_id < RDMA_OP_ID)) {
+          // this is RTS/CTS message 
+          // process it locally and don't pass it to portals layer 
+          // adjust wrq_id to get the right entry in MRbfu_list 
+                   
+          if(wrq_id >= RDMA_RTS_ID)
+            wrq_id = wrq_id - RDMA_RTS_ID;
+          else 
+            wrq_id = wrq_id - RDMA_CTS_ID;
+
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[wrq_id].buf_addr; 
+          MRbuf_list[wrq_id].status = BUF_INUSE; 
+          memcpy(&Rdma_info, &bufaddr, sizeof(RDMA_Info_Exchange));    
+        
+          if(Ready_To_send == Rdma_info.opcode) 
+            // an RTS request message from remote node 
+            // prepare local RDMA buffer and send local rdma info to
+            // remote node 
+            CTS_handshaking_protocol(&Rdma_info);
+          else 
+            if((Clear_To_send == Rdma_info.opcode) && 
+                              (RDMA_BUFFER_RESERVED == Rdma_info.flag))
+               Cts_Message_arrived = YES;
+            else 
+              if(RDMA_BUFFER_UNAVAILABLE == Rdma_info.flag) 
+                  CERROR("RDMA operation abort-RDMA_BUFFER_UNAVAILABLE\n");
+        }
+        else {
+          //
+          // this is an incoming mesage for portals layer 
+          // move to PORTALS layer for further processing 
+          //
+                     
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t)
+                                       MRbuf_list[wrq_id].buf_addr; 
+
+          MRbuf_list[wrq_id].status = BUF_INUSE; 
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    MRbuf_list[wrq_id].buf_size, 
+                    priority); 
+        }
+
+        // repost this receiving buffer and makr it at BUF_REGISTERED 
+
+        vstat = repost_recv_buf(qp, wrq_id);
+        if(vstat != (VAPI_OK)) {
+          CERROR("error while polling completion queue\n");
+        }
+        else {
+          MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+        }
+
+        break;
+
+      case   VAPI_CQE_RQ_RDMA_WITH_IMM:
+        // about the Receive Q
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if(wrq_id ==  RDMA_OP_ID) {
+          // this is RDAM op , locate the RDAM memory buffer address   
+               
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) Local_rdma_info.raddr;
+
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    Local_rdma_info.buf_length, 
+                    priority); 
+
+          // de-regiser this RDAM receiving memory buffer
+          // too early ??    test & check 
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.recv_rdma_mr_hndl);
+          if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_RQ_RDMA_WITH_IMM: Failed deregistering a RDMA"
+                   " recv  mem region %s\n", VAPI_strerror(vstat));
+          }
+        }
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+        break;
+
+      case   VAPI_CQE_INVAL_OPCODE:
+        //
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_INVAL_OPCODE\n");  
+        break;
+
+      default :
+        CDEBUG(D_NET, "CQE opcode-unknown opcode\n");  
+             break;
+    } // switch 
+    
+    schedule_timeout(RECEIVING_THREAD_TIMEOUT);//how often do we need to poll CQ 
+
+  }// receiving while loop
+
+
+}
+
+
+void CQE_event_handler(VAPI_hca_hndl_t hca_hndl, 
+                       VAPI_cq_hndl_t  cq_hndl, 
+                       void           *private)
+{
+ VAPI_ret_t       vstat; 
+ VAPI_wc_desc_t   comp_desc;   
+ unsigned long    polling_count = 0;
+ u_int32_t        timeout_usec;
+ unsigned int     priority = 100;
+ unsigned int     length;
+ VAPI_wr_id_t     wrq_id;
+ u_int32_t        transferred_data_length; /* Num. of bytes transferred */
+ void             *bufdata;
+ VAPI_virt_addr_t bufaddr;
+ unsigned long    buf_size = 0;
+ QP_info          *qp;       // point to QP_list
+ HCA_info         *hca_data;
+
+ // send Q and receive Q are using the same CQ 
+ // so only poll one CQ for both operations 
+ 
+ CDEBUG(D_NET, "IBNAL- enter CQE_event_handler\n");
+ printk("IBNAL- enter CQE_event_handler\n");
+
+ hca_data  = (HCA_info *) private; 
+
+ //
+ // use event driven  
+ //
+ 
+
+ vstat = VAPI_poll_cq(hca_data->hca_hndl,hca_data->cq_hndl, &comp_desc);   
+
+ if (vstat == VAPI_CQ_EMPTY) { 
+   CDEBUG(D_NET, "CQE_event_handler: there is no event in CQE, how could"
+                  " this " "happened \n");
+   printk("CQE_event_handler: there is no event in CQE, how could"
+                  " this " "happened \n");
+
+ } 
+ else {
+   if (vstat != (VAPI_OK)) {
+     CDEBUG(D_NET, "error while polling completion queue vstat %d - %s\n", 
+                vstat, VAPI_strerror(vstat));
+     printk("error while polling completion queue vstat %d - %s\n", 
+                                               vstat, VAPI_strerror(vstat));
+     return; 
+   }
+ }
+
+ // process the complete event 
+ switch(comp_desc.opcode) {
+    case   VAPI_CQE_SQ_SEND_DATA:
+      // about the Send Q ,POST SEND completion 
+      // who needs this information
+      // get wrq_id
+      // mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+               
+      wrq_id = comp_desc.id;
+
+#ifdef IBNAL_SELF_TESTING
+      if(wrq_id == SEND_RECV_TEST_ID) {
+        printk("IBNAL_SELF_TESTING - VAPI_CQE_SQ_SEND_DATA \n"); 
+      }
+#else  
+      if(RDMA_OP_ID < wrq_id) {
+        // this RDMA message id, adjust it to the right entry       
+        wrq_id = wrq_id - RDMA_OP_ID;
+        vstat = VAPI_deregister_mr(qp->hca_hndl, 
+                                   Local_rdma_info.send_rdma_mr_hndl);
+      }
+
+      if(vstat != VAPI_OK) {
+        CERROR(" VAPI_CQE_SQ_SEND_DATA: Failed deregistering a RDMA"
+               " recv  mem region %s\n", VAPI_strerror(vstat));
+      }
+
+      if((RDMA_CTS_ID <= wrq_id) && (RDMA_OP_ID < wrq_id)) {
+        // RTS or CTS send complete, release send buffer 
+        if(wrq_id >= RDMA_RTS_ID)
+          wrq_id = wrq_id - RDMA_RTS_ID;
+        else 
+          wrq_id = wrq_id - RDMA_CTS_ID;
+      }
+
+      spin_lock(&MSB_mutex[(int) wrq_id]);
+      MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+      spin_unlock(&MSB_mutex[(int) wrq_id]);
+#endif 
+
+      CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_SEND_DATA\n");  
+
+      break;
+
+    case   VAPI_CQE_SQ_RDMA_WRITE:
+      // about the Send Q,  RDMA write completion 
+      // who needs this information
+      // data is successfully write from pource to  destionation 
+             
+      //  get wr_id
+      //  mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+      //  de-register  rdma buffer 
+      //
+             
+       CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_RDMA_WRITE\n");  
+       break;
+
+      case   VAPI_CQE_SQ_RDMA_READ:
+        // about the Send Q
+        // RDMA read completion 
+        // who needs this information
+        // data is successfully read from destionation to source 
+         CDEBUG(D_NET, "CQE opcode- VAPI_CQE_SQ_RDMA_READ\n");  
+         break;
+
+      case   VAPI_CQE_SQ_COMP_SWAP:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+            
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_COMP_SWAP\n");  
+        break;
+
+      case   VAPI_CQE_SQ_FETCH_ADD:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_FETCH_ADD\n");  
+        break;
+
+      case   VAPI_CQE_SQ_BIND_MRW:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_BIND_MRW\n");  
+        break;
+
+      case   VAPI_CQE_RQ_SEND_DATA:
+        // about the Receive Q
+        // process the incoming data and
+        // forward it to .....
+        // a completion recevie event is arriving at CQ 
+        // issue a recevie to get this arriving data out from CQ 
+        // pass the receiving data for further processing 
+         
+         CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_SEND_DATA\n");  
+          
+         wrq_id = comp_desc.id ;
+
+#ifdef IBNAL_SELF_TESTING
+
+      char        rbuf[KB_32];
+      int i;
+
+      if(wrq_id == SEND_RECV_TEST_ID) {
+        printk("IBNAL_SELF_TESTING - VAPI_CQE_RQ_SEND_DATA\n"); 
+      }
+
+      bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) 
+                       MRbuf_list[ SEND_RECV_TEST_BUF_ID].buf_addr; 
+      MRbuf_list[SEND_RECV_TEST_BUF_ID].status = BUF_INUSE; 
+      memcpy(&rbuf, &bufaddr, KB_32);    
+      
+
+      for(i=0; i < 16; i++)
+              printk("rbuf[%d]=%c, ", rbuf[i]);
+      printk("\n");
+
+      // repost this receiving buffer and makr it at BUF_REGISTERED 
+      vstat = repost_recv_buf(qp,SEND_RECV_TEST_BUF_ID);
+      if(vstat != (VAPI_OK)) {
+        printk("error while polling completion queue\n");
+      }
+      else {
+        MRbuf_list[SEND_RECV_TEST_BUF_ID].status = BUF_REGISTERED; 
+      }
+#else  
+         transferred_data_length = comp_desc.byte_len;
+             
+         if((wrq_id >= RDMA_CTS_ID) && (wrq_id < RDMA_OP_ID)) {
+           // this is RTS/CTS message 
+           // process it locally and don't pass it to portals layer 
+           // adjust wrq_id to get the right entry in MRbfu_list 
+                   
+           if(wrq_id >= RDMA_RTS_ID)
+             wrq_id = wrq_id - RDMA_RTS_ID;
+           else 
+             wrq_id = wrq_id - RDMA_CTS_ID;
+
+           bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) 
+                                           MRbuf_list[wrq_id].buf_addr; 
+           MRbuf_list[wrq_id].status = BUF_INUSE; 
+           memcpy(&Rdma_info, &bufaddr, sizeof(RDMA_Info_Exchange));    
+        
+           if(Ready_To_send == Rdma_info.opcode) 
+             // an RTS request message from remote node 
+             // prepare local RDMA buffer and send local rdma info to
+             // remote node 
+             CTS_handshaking_protocol(&Rdma_info);
+           else 
+             if((Clear_To_send == Rdma_info.opcode) && 
+                                (RDMA_BUFFER_RESERVED == Rdma_info.flag))
+               Cts_Message_arrived = YES;
+             else 
+               if(RDMA_BUFFER_UNAVAILABLE == Rdma_info.flag) 
+                 CERROR("RDMA operation abort-RDMA_BUFFER_UNAVAILABLE\n");
+         }
+         else {
+           //
+           // this is an incoming mesage for portals layer 
+           // move to PORTALS layer for further processing 
+           //
+                     
+           bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t)
+                                MRbuf_list[wrq_id].buf_addr; 
+
+           MRbuf_list[wrq_id].status = BUF_INUSE; 
+           transferred_data_length = comp_desc.byte_len;
+
+           kibnal_rx(hca_data->kib_data, 
+                     bufaddr, 
+                     transferred_data_length, 
+                     MRbuf_list[wrq_id].buf_size, 
+                     priority); 
+         }
+
+         // repost this receiving buffer and makr it at BUF_REGISTERED 
+         vstat = repost_recv_buf(qp, wrq_id);
+         if(vstat != (VAPI_OK)) {
+           CERROR("error while polling completion queue\n");
+         }
+         else {
+           MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+         }
+#endif
+
+         break;
+
+      case   VAPI_CQE_RQ_RDMA_WITH_IMM:
+        // about the Receive Q
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if(wrq_id ==  RDMA_OP_ID) {
+          // this is RDAM op , locate the RDAM memory buffer address   
+              
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) Local_rdma_info.raddr;
+
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    Local_rdma_info.buf_length, 
+                    priority); 
+
+          // de-regiser this RDAM receiving memory buffer
+          // too early ??    test & check 
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.recv_rdma_mr_hndl);
+          if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_RQ_RDMA_WITH_IMM: Failed deregistering a RDMA"
+               " recv  mem region %s\n", VAPI_strerror(vstat));
+          }
+        }
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+        break;
+
+      case   VAPI_CQE_INVAL_OPCODE:
+        //
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_INVAL_OPCODE\n");  
+        break;
+
+      default :
+        CDEBUG(D_NET, "CQE opcode-unknown opcode\n");  
+
+        break;
+    } // switch 
+    
+  // issue a new request for completion ievent notification 
+  vstat = VAPI_req_comp_notif(hca_data->hca_hndl, 
+                              hca_data->cq_hndl,
+                              VAPI_NEXT_COMP); 
+
+
+  if(vstat != VAPI_OK) {
+    CERROR("PI_req_comp_notif: Failed %s\n", VAPI_strerror(vstat));
+  }
+
+  return; // end of event handler 
+
+}
+
+
+
+int
+kibnal_cmd(struct portal_ioctl_data * data, void * private)
+{
+  int rc ;
+
+  CDEBUG(D_NET, "kibnal_cmd \n");  
+
+  return YES;
+}
+
+
+
+void ibnal_send_recv_self_testing(int *my_role)
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+ int                  buf_id;
+ char                 sbuf[KB_32];
+ char                 rbuf[KB_32];
+ int                  i;
+ int                  buf_length = KB_32;
+ VAPI_wc_desc_t       comp_desc;
+ int                  num_send = 1;
+ int                  loop_count = 0;
+
+ // make it as a daemon process 
+ // kportal_daemonize("ibnal_send_recv_self_testing");  
+
+ printk("My role is 0X%X\n", *my_role);
+
+if(*my_role ==  TEST_SEND_MESSAGE)  {
+ printk("Enter ibnal_send_recv_self_testing\n");
+
+ memset(&sbuf, 'a', KB_32);
+ memset(&rbuf, ' ', KB_32);
+ 
+ send_id = SEND_RECV_TEST_ID; 
+ buf_id = SEND_RECV_TEST_BUF_ID;
+
+ qp = &QP_list[buf_id];
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        =  send_id;
+
+ // scatter and gather info
+ sr_sg.len  = KB_32;
+ sr_sg.lkey = MSbuf_list[buf_id].mr.l_key; // use send MR
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[buf_id].buf_addr;
+
+ // copy data to register send buffer
+ memcpy(&sr_sg.addr, &sbuf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ /*
+ // call VAPI_post_sr to send out this data
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+   printk("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ printk("VAPI_post_sr success.\n");
+ */
+
+ }
+else {
+  printk("I am a receiver and doing nothing here\n"); 
+}
+         
+ printk("ibnal_send_recv_self_testing thread exit \n");
+
+ return;
+
+}
+
+
+//
+// ibnal initialize process  
+//
+// 1.  Bring up Infiniband network interface 
+//     * 
+// 2.  Initialize a PORTALS nal interface 
+// 
+//
+int __init 
+kibnal_initialize(void)
+{
+   int           rc;
+   int           ntok;
+   unsigned long sizemask;
+   unsigned int  nid;
+   VAPI_ret_t    vstat;
+
+
+   portals_debug_set_level(IBNAL_DEBUG_LEVEL_1);
+
+   CDEBUG(D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
+
+   CDEBUG(D_PORTALS, "kibnal_initialize: Enter kibnal_initialize\n");
+
+   // set api functional pointers 
+   kibnal_api.forward    = kibnal_forward;
+   kibnal_api.shutdown   = kibnal_shutdown;
+   kibnal_api.yield      = kibnal_yield;
+   kibnal_api.validate   = NULL; /* our api validate is a NOOP */
+   kibnal_api.lock       = kibnal_lock;
+   kibnal_api.unlock     = kibnal_unlock;
+   kibnal_api.nal_data   = &kibnal_data; // this is so called private data 
+   kibnal_api.refct      = 1;
+   kibnal_api.timeout    = NULL;
+   kibnal_lib.nal_data   = &kibnal_data;
+  
+   memset(&kibnal_data, 0, sizeof(kibnal_data));
+
+   // initialize kib_list list data structure 
+   INIT_LIST_HEAD(&kibnal_data.kib_list);
+
+   kibnal_data.kib_cb = &kibnal_lib;
+
+   spin_lock_init(&kibnal_data.kib_dispatch_lock);
+
+
+   //  
+   // bring up the IB inter-connect network interface 
+   // setup QP, CQ 
+   //
+   vstat = IB_Open_HCA(&kibnal_data);
+
+   if(vstat != VAPI_OK) {
+     CERROR("kibnal_initialize: IB_Open_HCA failed: %d- %s\n", 
+                                                vstat, VAPI_strerror(vstat));
+
+     printk("kibnal_initialize: IB_Open_HCA failed: %d- %s\n", 
+                                                vstat, VAPI_strerror(vstat));
+     return NO;
+   }
+
+   kibnal_data.kib_nid = (__u64 )Hca_hndl;//convert Hca_hndl to 64-bit format
+   kibnal_data.kib_init = 1;
+
+   CDEBUG(D_NET, " kibnal_data.kib_nid 0x%x%x\n", kibnal_data.kib_nid);
+   printk(" kibnal_data.kib_nid 0x%x%x\n", kibnal_data.kib_nid);
+
+   /* Network interface ready to initialise */
+   // get an entery in the PORTALS table for this IB protocol 
+
+   CDEBUG(D_PORTALS,"Call PtlNIInit to register this Infiniband Interface\n");
+   printk("Call PtlNIInit to register this Infiniband Interface\n");
+
+   rc = PtlNIInit(kibnal_init, 32, 4, 0, &kibnal_ni);
+
+   if(rc != PTL_OK) {
+     CERROR("kibnal_initialize: PtlNIInit failed %d\n", rc);
+     printk("kibnal_initialize: PtlNIInit failed %d\n", rc);
+     kibnal_finalize();
+     return (-ENOMEM);
+   }
+
+   CDEBUG(D_PORTALS,"kibnal_initialize: PtlNIInit DONE\n");
+   printk("kibnal_initialize: PtlNIInit DONE\n");
+
+
+
+#ifdef  POLL_BASED_CQE_HANDLING 
+   // create a receiving thread: main loopa
+   // this is polling based mail loop   
+   kernel_thread(k_recv_thread, &Hca_data, 0);
+#endif
+
+#ifdef EVENT_BASED_CQE_HANDLING
+  // for completion event handling,  this is event based CQE handling 
+  vstat = IB_Set_Event_Handler(Hca_data, &kibnal_data);
+
+  if (vstat != VAPI_OK) {
+     CERROR("IB_Set_Event_Handler failed: %d - %s \n", 
+                                           vstat, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  CDEBUG(D_PORTALS,"IB_Set_Event_Handler Done \n");
+  printk("IB_Set_Event_Handler Done \n");
+  
+#endif
+
+   PORTAL_SYMBOL_REGISTER(kibnal_ni);
+
+#ifdef IBNAL_SELF_TESTING
+  //
+  // test HCA send recv before normal event handling 
+  //
+  int  my_role;
+  my_role = TEST_SEND_MESSAGE;
+
+  printk("my role is TEST_RECV_MESSAGE\n");
+
+  // kernel_thread(ibnal_send_recv_self_testing, &my_role, 0);
+   
+  ibnal_send_recv_self_testing(&my_role);
+
+#endif 
+
+  return 0;
+
+}
+
+
+
+MODULE_AUTHOR("Hsingbung(HB) Chen <hbchen@lanl.gov>");
+MODULE_DESCRIPTION("Kernel Infiniband NAL v0.1");
+MODULE_LICENSE("GPL");
+
+module_init (kibnal_initialize);
+module_exit (kibnal_finalize);
+
+EXPORT_SYMBOL(kibnal_ni);
+
diff --git a/lnet/klnds/iblnd/ibnal.h b/lnet/klnds/iblnd/ibnal.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff5aeb34a75704ed3b5880e0b24a119046fa69ac
--- /dev/null
+++ b/lnet/klnds/iblnd/ibnal.h
@@ -0,0 +1,564 @@
+#ifndef _IBNAL_H
+#define _IBNAL_H
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <linux/ipc.h>
+#include <linux/shm.h>
+
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/locks.h>
+#include <linux/unistd.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/list.h>
+#include <linux/in.h>
+#include <unistd.h>
+
+#define DEBUG_SUBSYSTEM S_IBNAL
+
+#include <portals/p30.h>
+#include <portals/lib-p30.h>
+#include <linux/kp30.h>
+
+// Infiniband VAPI/EVAPI header files  
+// Mellanox MT23108 VAPI
+#include <vapi.h>
+#include <vapi_types.h>
+#include <vapi_common.h>
+#include <evapi.h>
+
+// pick a port for this RDMA information exhange between two hosts
+#define HOST_PORT           11211 
+#define QUEUE_SIZE          1024
+#define HCA_PORT_1          1
+#define HCA_PORT_2          2 
+#define DEBUG_SUBSYSTEM S_IBNAL
+
+#define START_SEND_WRQ_ID        0
+#define START_RECV_WRQ_ID        0
+#define START_RDMA_WRQ_ID        0  
+
+#define DEFAULT_PRIORITY         100
+
+#define WAIT_FOT_R_RDMA_TIMEOUT 10000
+#define MAX_NUM_TRY      3000 
+
+#define MAX_NUM_POLL     300 
+#define MAX_LOOP_COUNT   500
+
+#define MAX_GID          32 
+#define MCG_BUF_LENGTH   128
+
+#define SHARED_SEGMENT_SIZE   0x10000   
+#define HCA_EXCHANGE_SHM_KEY  999 // shared memory key for HCA data exchange 
+
+// some internals opcodes for IB operations used in IBNAL
+#define SEND_QP_INFO          0X00000001 
+#define RECV_QP_INFO          0X00000010 
+
+// Mellanox InfiniHost MT23108 
+// QP/CQ related information
+//
+
+#define MTU_256     1 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_512     2 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_1024    3 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_2048    4 /* 1-256,2-512,3-1024,4-2048 */
+
+// number of entries for each CQ and WQ 
+// how much do we need ?
+#define NUM_CQE        1024
+#define NUM_WQE        1024 
+#define MAX_OUT_SQ     64 
+#define MAX_OUT_RQ     64
+
+#define NUM_MBUF       256 
+#define NUM_RDMA_RESERVED_ENTRY 128 
+#define NUM_QPS        256 
+
+#define INVALID_WR_ID  ((VAPI_wr_id_t) -1)
+
+
+// for Vector IO 
+// scatter and gather 
+// Portals can support upto 64 IO-Vectors 
+// how much do we need ? 
+#define NUM_SGE        1 
+#define NUM_SG         1 
+#define NUM_CQ	       1	
+
+#define ONE_KB    1024
+#define ONE_MB    1024 * ONE_KB 
+#define ONE_GB    1024 * ONE_MB 
+
+
+#define KB_4      1024 * 4 
+#define KB_8      1024 * 8 
+#define KB_16     1024 * 16
+#define KB_32     1024 * 32
+#define KB_64     1024 * 64
+#define KB_128    1024 * 128 
+#define KB_256    1024 * 256 
+
+// 256 entry in registered buffer list 
+// small size message 
+#define Num_4_KB       64 
+#define Num_8_KB       64 
+#define Num_16_KB      40 
+#define Num_32_KB      40 
+#define Num_64_KB      40 
+#define Num_128_KB     4 
+#define Num_256_KB     4 
+
+#define SMALL_MSG_SIZE KB_32     
+
+#define MAX_MSG_SIZE   ONE_MB * 512   
+
+//   128's  64KB bufer for send
+//   128's  64KB bufer for recv  
+//   used in RDAM operation only 
+
+#define NUM_ENTRY      128 
+
+#define End_4_kb        Num_4_KB 
+#define End_8_kb        End_4_kb  + Num_8_KB 
+#define End_16_kb       End_8_kb  + Num_16_KB
+#define End_32_kb       End_16_kb + Num_32_KB
+#define End_64_kb       End_32_kb + Num_64_KB
+#define End_128_kb      End_64_kb + Num_128_KB
+#define End_256_kb      End_128_kb+ Num_256_KB
+
+
+#define SEND_BUF_SIZE   KB_32
+#define RECV_BUF_SIZE   SEND_BUF_SIZE
+
+// #define POLL_BASED_CQE_HANDLING	1
+#define EVENT_BASED_CQE_HANDLING        1
+#define IBNAL_SELF_TESTING		1
+
+#ifdef  IBNAL_SELF_TESTING
+#undef  IBNAL_SELF_TESTING
+#endif
+
+
+#define MSG_SIZE_SMALL 1 
+#define MSG_SIZE_LARGE 2 
+
+
+
+// some defauly configuration values for early testing 
+#define DEFAULT_DLID   1  // default destination link ID
+#define DEFAULT_QP_NUM 4  // default QP number 
+#define P_KEY          0xFFFF // do we need default value
+#define PKEY_IX        0x0 // do we need default value
+#define Q_KEY          0x012  // do we need default value 
+#define L_KEY          0x12345678 // do we need default value 
+#define R_KEY          0x87654321 // do we need default value 
+#define HCA_ID         "InfiniHost0" // default 
+#define START_PSN      0
+#define START_SQ_PSN   0
+#define START_RQ_PSN   0
+
+
+#define __u_long_long   unsigned long long
+
+#define         IBNAL_DEBUG      1
+
+#define         USE_SHARED_MEMORY_AND_SOCKET 1
+
+// operation type
+#define TRY_SEND_ONLY    1
+
+#define YES     1  
+#define NO      0 
+
+//
+// a common data structure for IB QP's operation
+// each QP is associated with an QP_info structure 
+//
+typedef struct QP_info 
+{
+  VAPI_hca_hndl_t       hca_hndl;      // HCA handle
+  IB_port_t             port;          // port number 
+  VAPI_qp_hndl_t        qp_hndl;       // QP's handle list 
+  VAPI_qp_state_t       qp_state;      // QP's current state 
+  VAPI_pd_hndl_t        pd_hndl;       // protection domain
+  VAPI_cq_hndl_t        cq_hndl;    // send-queue CQ's handle 
+  VAPI_cq_hndl_t        sq_cq_hndl;    // send-queue CQ's handle 
+  VAPI_cq_hndl_t        rq_cq_hndl;    // receive-queue CQ's handle
+  VAPI_ud_av_hndl_t     av_hndl;    // receive-queue CQ's handle
+  VAPI_qp_init_attr_t   qp_init_attr;  // QP's init attribute 
+  VAPI_qp_attr_t        qp_attr;       // QP's attribute - dlid 
+  VAPI_qp_prop_t        qp_prop;       // QP's propertities
+  VAPI_hca_port_t       hca_port;  
+  VAPI_qp_num_t         qp_num;    // QP's number 
+  VAPI_qp_num_t         rqp_num;       // remote QP's number 
+  IB_lid_t              slid;
+  IB_lid_t              dlid;
+  VAPI_gid_t            src_gid;
+
+  u_int32_t 	        buf_size;
+  VAPI_virt_addr_t      buf_addr;
+  char		       *bufptr;
+  VAPI_mrw_t            mr;       
+  VAPI_mr_hndl_t        mr_hndl;
+  VAPI_virt_addr_t      raddr;
+  VAPI_rkey_t           rkey;
+  VAPI_lkey_t           lkey;
+
+  VAPI_wr_id_t          last_posted_send_id; // user defined work request ID 
+  VAPI_wr_id_t          last_posted_rcv_id;  // user defined work request ID
+  VAPI_mw_hndl_t        mw_hndl;       // memory window handle 
+  VAPI_rkey_t           mw_rkey;       // memory window rkey
+  VAPI_sg_lst_entry_t   sg_lst[256];       // scatter and gather list 
+  int                   sg_list_sz;    // set as NUM_SGE
+  VAPI_wr_id_t          wr_id;         //
+  spinlock_t            snd_mutex;
+  spinlock_t            rcv_mutex;
+  spinlock_t            bl_mutex;
+  spinlock_t            cln_mutex;
+  int                   cur_RDMA_outstanding;
+  int                   cur_send_outstanding;
+  int                   cur_posted_rcv_bufs;
+  int                   snd_rcv_balance;
+} QP_info; 
+
+
+// buffer status 
+#define  BUF_REGISTERED   0x10000000 
+#define  BUF_INUSE 	  0x01000000  
+#define  BUF_UNREGISTERED 0x00100000 
+
+// buffer type 
+#define  REG_BUF          0x10000000
+#define  RDMA_BUF         0x01000000 
+
+//
+// IMM data 
+// 
+#define   IMM_000         (0 << 32); 
+#define   IMM_001         (1 << 32); 
+#define   IMM_002         (2 << 32); 
+#define   IMM_003         (3 << 32); 
+#define   IMM_004         (4 << 32); 
+#define   IMM_005         (5 << 32); 
+#define   IMM_006         (6 << 32); 
+#define   IMM_007         (7 << 32); 
+#define   IMM_008         (8 << 32); 
+#define   IMM_009         (9 << 32); 
+#define   IMM_010         (10 << 32); 
+#define   IMM_011         (11 << 32); 
+#define   IMM_012         (12 << 32); 
+#define   IMM_013         (13 << 32); 
+#define   IMM_014         (14 << 32); 
+#define   IMM_015         (15 << 32); 
+#define   IMM_016         (16 << 32); 
+#define   IMM_017         (17 << 32); 
+#define   IMM_018         (18 << 32); 
+#define   IMM_019         (19 << 32); 
+#define   IMM_020         (20 << 32); 
+#define   IMM_021         (21 << 32); 
+#define   IMM_022         (22 << 32); 
+#define   IMM_023         (23 << 32); 
+#define   IMM_024         (24 << 32); 
+#define   IMM_025         (25 << 32); 
+#define   IMM_026         (26 << 32); 
+#define   IMM_027         (27 << 32); 
+#define   IMM_028         (28 << 32); 
+#define   IMM_029         (29 << 32); 
+#define   IMM_030         (30 << 32); 
+#define   IMM_031         (31 << 32); 
+ 
+
+
+typedef struct Memory_buffer_info{
+	u_int32_t 	 buf_size;
+	VAPI_virt_addr_t buf_addr;
+	char		 *bufptr;
+	VAPI_mrw_t       mr;       
+	VAPI_mr_hndl_t   mr_hndl;
+        int              status;
+	int              ref_count;  
+        int              buf_type;
+	VAPI_virt_addr_t raddr;
+	VAPI_rkey_t      rkey;
+	VAPI_lkey_t      lkey;
+} Memory_buffer_info;
+
+typedef struct RDMA_Info_Exchange {
+	int               opcode;
+	int               buf_length;
+	VAPI_mrw_t        recv_rdma_mr;
+	VAPI_mr_hndl_t    recv_rdma_mr_hndl;
+	VAPI_mrw_t        send_rdma_mr;
+	VAPI_mr_hndl_t    send_rdma_mr_hndl;
+	VAPI_virt_addr_t  raddr;
+	VAPI_rkey_t       rkey;
+	int               flag;
+}  RDMA_Info_Exchange;
+
+// opcode for Rdma info exchange RTS/CTS 
+#define  Ready_To_send     0x10000000
+#define  Clear_To_send     0x01000000
+
+#define  RDMA_RTS_ID	   5555 
+#define  RDMA_CTS_ID	   7777 
+#define  RDMA_OP_ID	   9999 
+#define  SEND_RECV_TEST_ID 2222 
+#define  SEND_RECV_TEST_BUF_ID 0 
+
+#define  TEST_SEND_MESSAGE 0x00000001 
+#define  TEST_RECV_MESSAGE 0x00000002
+
+
+#define  RTS_CTS_TIMEOUT           50
+#define  RECEIVING_THREAD_TIMEOUT  50 
+#define  WAIT_FOR_SEND_BUF_TIMEOUT 50
+
+#define  IBNAL_DEBUG_LEVEL_1   0XFFFFFFFF  
+#define  IBNAL_DEBUG_LEVEL_2   D_PORTALS | D_NET   | D_WARNING | D_MALLOC | \ 
+			       D_ERROR   | D_OTHER | D_TRACE   | D_INFO
+			       
+
+// flag for Rdma info exhange 
+#define  RDMA_BUFFER_RESERVED       0x10000000
+#define  RDMA_BUFFER_UNAVAILABLE    0x01000000
+
+
+// receiving data structure 
+typedef struct {
+        ptl_hdr_t         *krx_buffer; // pointer to receiving buffer
+        unsigned long     krx_len;  // length of buffer
+        unsigned int      krx_size; // 
+        unsigned int      krx_priority; // do we need this 
+        struct list_head  krx_item;
+}  kibnal_rx_t;
+
+// transmitting data structure 
+typedef struct {
+        nal_cb_t      *ktx_nal;
+        void          *ktx_private;
+        lib_msg_t     *ktx_cookie;
+        char          *ktx_buffer;
+        size_t         ktx_len;
+        unsigned long  ktx_size;
+        int            ktx_ndx;
+        unsigned int   ktx_priority;
+        unsigned int   ktx_tgt_node;
+        unsigned int   ktx_tgt_port_id;
+}  kibnal_tx_t;
+
+
+typedef struct {
+        char              kib_init;
+        char              kib_shuttingdown;
+        IB_port_t         port_num; // IB port information
+        struct list_head  kib_list;
+        ptl_nid_t         kib_nid;
+        nal_t            *kib_nal; 
+        nal_cb_t         *kib_cb;
+        struct kib_trans *kib_trans; // do I need this 
+        struct tq_struct  kib_ready_tq;
+        spinlock_t        kib_dispatch_lock;
+}  kibnal_data_t;
+
+
+//
+// A data structure for keeping the HCA information in system
+// information related to HCA and hca_handle will be kept here 
+//
+typedef struct HCA_Info 
+{
+  VAPI_hca_hndl_t       hca_hndl;     // HCA handle
+  VAPI_pd_hndl_t        pd_hndl;      // protection domain
+  IB_port_t             port;         // port number 
+  int                   num_qp;       // number of qp used  
+  QP_info               *qp_ptr[NUM_QPS]; // point to QP_list
+  int                   num_cq;       // number of cq used 
+  VAPI_cq_hndl_t        cq_hndl;   
+  VAPI_cq_hndl_t        sq_cq_hndl;   
+  VAPI_cq_hndl_t        rq_cq_hndl;   
+  IB_lid_t              dlid;
+  IB_lid_t              slid;
+  kibnal_data_t         *kib_data; // for PORTALS operations
+} HCA_info;
+
+
+
+
+// Remote HCA Info information 
+typedef struct Remote_HCA_Info {
+        unsigned long     opcode;
+        unsigned long     length; 
+        IB_lid_t          dlid[NUM_QPS];
+        VAPI_qp_num_t     rqp_num[NUM_QPS];
+} Remote_QP_Info;
+
+typedef struct  Bucket_index{
+     int start;
+     int end;
+} Bucket_index;
+
+// functional prototypes 
+// infiniband initialization 
+int kib_init(kibnal_data_t *);
+
+// receiving thread 
+void kibnal_recv_thread(HCA_info *);
+void recv_thread(HCA_info *);
+
+// forward data packet 
+void kibnal_fwd_packet (void *, kpr_fwd_desc_t *);
+
+// global data structures 
+extern kibnal_data_t        kibnal_data;
+extern ptl_handle_ni_t      kibnal_ni;
+extern nal_t                kibnal_api;
+extern nal_cb_t             kibnal_lib;
+extern QP_info              QP_list[];
+extern QP_info              CQ_list[];
+extern HCA_info             Hca_data;
+extern VAPI_hca_hndl_t      Hca_hndl; 
+extern VAPI_pd_hndl_t       Pd_hndl;
+extern VAPI_hca_vendor_t    Hca_vendor;
+extern VAPI_hca_cap_t       Hca_cap;
+extern VAPI_hca_port_t      Hca_port_1_props;
+extern VAPI_hca_port_t      Hca_port_2_props;
+extern VAPI_hca_attr_t      Hca_attr;
+extern VAPI_hca_attr_mask_t Hca_attr_mask;
+extern VAPI_cq_hndl_t       Cq_SQ_hndl;   
+extern VAPI_cq_hndl_t       Cq_RQ_hndl;   
+extern VAPI_cq_hndl_t       Cq_hndl;   
+extern unsigned long        User_Defined_Small_Msg_Size;
+extern Remote_QP_Info      L_HCA_RDMA_Info;  
+extern Remote_QP_Info      R_HCA_RDMA_Info; 
+extern unsigned int         Num_posted_recv_buf;
+extern int                  R_RDMA_DATA_ARRIVED;
+extern Memory_buffer_info   MRbuf_list[];
+extern Memory_buffer_info   MSbuf_list[];
+extern Bucket_index         Bucket[]; 
+extern RDMA_Info_Exchange   Rdma_info;
+extern int                  Cts_Message_arrived;
+extern RDMA_Info_Exchange   Local_rdma_info;
+extern spinlock_t	    MSB_mutex[];
+
+
+
+// kernel NAL API function prototype 
+int  kibnal_forward(nal_t *,int ,void *,size_t ,void *,size_t );
+void kibnal_lock(nal_t *, unsigned long *);
+void kibnal_unlock(nal_t *, unsigned long *);
+int  kibnal_shutdown(nal_t *, int );
+void kibnal_yield( nal_t * );
+void kibnal_invalidate(nal_cb_t *,void *,size_t ,void *);
+int  kibnal_validate(nal_cb_t *,void *,size_t ,void  **);
+
+
+
+nal_t *kibnal_init(int , ptl_pt_index_t , ptl_ac_index_t , ptl_pid_t );
+void __exit kibnal_finalize(void ); 
+VAPI_ret_t create_qp(QP_info *, int );
+VAPI_ret_t init_qp(QP_info *, int );
+VAPI_ret_t IB_Open_HCA(kibnal_data_t *);
+VAPI_ret_t IB_Close_HCA(void );
+VAPI_ret_t createMemRegion(VAPI_hca_hndl_t, VAPI_pd_hndl_t); 
+VAPI_ret_t  deleteMemRegion(QP_info *, int );
+
+void ibnal_send_recv_self_testing(int *);
+
+int  __init kibnal_initialize(void);
+
+
+
+/* CB NAL functions */
+int kibnal_send(nal_cb_t *, 
+                void *, 
+                lib_msg_t *, 
+                ptl_hdr_t *,
+                int, 
+                ptl_nid_t, 
+                ptl_pid_t, 
+                unsigned int, 
+                ptl_kiov_t *, 
+                size_t);
+
+int kibnal_send_pages(nal_cb_t *, 
+                      void *, 
+                      lib_msg_t *, 
+                      ptl_hdr_t *,
+                      int, 
+                      ptl_nid_t, 
+                      ptl_pid_t, 
+                      unsigned int, 
+                      ptl_kiov_t *, 
+                      size_t);
+int kibnal_recv(nal_cb_t *, void *, lib_msg_t *,
+                        unsigned int, struct iovec *, size_t, size_t);
+int kibnal_recv_pages(nal_cb_t *, void *, lib_msg_t *,
+                        unsigned int, ptl_kiov_t *, size_t, size_t);
+int  kibnal_read(nal_cb_t *,void *,void *,user_ptr ,size_t );
+int  kibnal_write(nal_cb_t *,void *,user_ptr ,void *,size_t );
+int  kibnal_callback(nal_cb_t * , void *, lib_eq_t *, ptl_event_t *);
+void *kibnal_malloc(nal_cb_t *,size_t );
+void kibnal_free(nal_cb_t *,void *,size_t );
+int  kibnal_map(nal_cb_t *, unsigned int , struct iovec *, void **);
+void kibnal_unmap(nal_cb_t *, unsigned int , struct iovec *, void **);
+int  kibnal_map_pages(nal_cb_t *, unsigned int , ptl_kiov_t *, void **);
+void kibnal_unmap_pages(nal_cb_t * , unsigned int , ptl_kiov_t *, void **);
+void kibnal_printf(nal_cb_t *, const char *, ...);
+void kibnal_cli(nal_cb_t *,unsigned long *); 
+void kibnal_sti(nal_cb_t *,unsigned long *);
+int  kibnal_dist(nal_cb_t *,ptl_nid_t ,unsigned long *);
+
+void kibnal_fwd_packet (void *, kpr_fwd_desc_t *);
+void kibnal_rx(kibnal_data_t *, 
+               VAPI_virt_addr_t ,
+               u_int32_t,
+               u_int32_t,
+               unsigned int);
+                
+int  kibnal_end(kibnal_data_t *);
+
+void async_event_handler(VAPI_hca_hndl_t , VAPI_event_record_t *,void *);
+
+void CQE_event_handler(VAPI_hca_hndl_t ,VAPI_cq_hndl_t , void  *);
+
+
+VAPI_ret_t Send_Small_Msg(char *, int );
+VAPI_ret_t Send_Large_Msg(char *, int );
+
+VAPI_ret_t repost_recv_buf(QP_info *, VAPI_wr_id_t );
+int post_recv_bufs(VAPI_wr_id_t );
+int  server_listen_thread(void *);
+VAPI_wr_id_t RTS_handshaking_protocol(int );
+VAPI_wr_id_t CTS_handshaking_protocol(RDMA_Info_Exchange *);
+
+VAPI_ret_t createMemRegion_RDMA(VAPI_hca_hndl_t ,
+		                VAPI_pd_hndl_t  ,
+				char         *,
+				int             , 
+	                        VAPI_mr_hndl_t  *,
+		                VAPI_mrw_t      *);
+
+
+VAPI_ret_t IB_Set_Event_Handler(HCA_info , kibnal_data_t *);
+
+VAPI_ret_t IB_Set_Async_Event_Handler(HCA_info ,kibnal_data_t *);
+
+VAPI_wr_id_t find_available_buf(int );
+VAPI_wr_id_t search_send_buf(int );
+VAPI_wr_id_t find_filler_list(int ,int );
+int insert_MRbuf_list(int );
+
+
+#endif  /* _IBNAL_H */
diff --git a/lnet/klnds/iblnd/ibnal_cb.c b/lnet/klnds/iblnd/ibnal_cb.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c07cc4feacaa493fff748be4fe53f3e33a8e36b
--- /dev/null
+++ b/lnet/klnds/iblnd/ibnal_cb.c
@@ -0,0 +1,1288 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Based on ksocknal and qswnal
+ *
+ *  Author: Hsing-bung Chen <hbchen@lanl.gov>
+ *
+ *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals 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 Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "ibnal.h"
+
+
+
+
+RDMA_Info_Exchange   Rdma_nfo;
+int  Cts_Msg_Arrived = NO;
+
+
+/*
+ *  LIB functions follow
+ */
+
+//
+// read
+// copy a block of data from scr_addr to dst_addr 
+// it all happens in kernel space - dst_addr and src_addr 
+//
+// original definition is to read a block od data from a 
+// specified user address  
+// 
+// cb_read
+
+int kibnal_read (nal_cb_t *nal, 
+                 void     *private, 
+                 void     *dst_addr, 
+                 user_ptr src_addr, 
+                 size_t   len)
+{
+        CDEBUG(D_NET, "kibnal_read: 0x%Lx: reading %ld bytes from %p -> %p\n",
+               nal->ni.nid, (long)len, src_addr, dst_addr );
+
+        memcpy( dst_addr, src_addr, len );
+
+        return 0;
+}
+
+//
+// it seems that read and write are doing the same thing
+// because they all happen in kernel space 
+// why do we need two functions like read and write 
+// to make PORTALS API compatable 
+//
+
+//
+// write 
+// copy a block of data from scr_addr to dst_addr 
+// it all happens in kernel space - dst_addr and src_addr 
+//
+// original definition is to write a block od data to a 
+// specified user address  
+// 
+// cb_write
+
+int kibnal_write(nal_cb_t   *nal, 
+                 void       *private, 
+                 user_ptr   dst_addr, 
+                 void       *src_addr, 
+                 size_t     len)
+{
+        CDEBUG(D_NET, "kibnal_write: 0x%Lx: writing %ld bytes from %p -> %p\n",
+               nal->ni.nid, (long)len, src_addr, dst_addr );
+
+
+        memcpy( dst_addr, src_addr, len );
+
+        return 0;
+}
+
+//
+// malloc
+//
+// either vmalloc or kmalloc is used 
+// dynamically allocate a block of memory based on the size of buffer  
+//
+// cb_malloc
+
+void * kibnal_malloc(nal_cb_t *nal, size_t length)
+{
+        void *buffer;
+
+        // PORTAL_ALLOC will do the job 
+        // allocate a buffer with size "length"
+        PORTAL_ALLOC(buffer, length);
+
+        return buffer;
+}
+
+//
+// free
+// release a dynamically allocated memory pointed by buffer pointer 
+//
+// cb_free
+
+void kibnal_free(nal_cb_t *nal, void *buffer, size_t length)
+{
+        //
+        // release allocated buffer to system 
+        //
+        PORTAL_FREE(buffer, length);
+}
+
+//
+// invalidate 
+// because evernthing is in kernel space (LUSTRE)
+// there is no need to mark a piece of user memory as no longer in use by
+// the system
+//
+// cb_invalidate
+
+void kibnal_invalidate(nal_cb_t      *nal, 
+                              void          *base, 
+                              size_t        extent, 
+                              void          *addrkey)
+{
+  // do nothing 
+  CDEBUG(D_NET, "kibnal_invalidate: 0x%Lx: invalidating %p : %d\n", 
+                                        nal->ni.nid, base, extent);
+  return;
+}
+
+
+//
+// validate 
+// because everything is in kernel space (LUSTRE)
+// there is no need to mark a piece of user memory in use by
+// the system
+//
+// cb_validate
+
+int kibnal_validate(nal_cb_t        *nal,  
+                           void            *base, 
+                           size_t          extent, 
+                           void            **addrkey)
+{
+  // do nothing 
+  CDEBUG(D_NET, "kibnal_validate: 0x%Lx: validating %p : %d\n", 
+                                        nal->ni.nid, base, extent);
+
+  return 0;
+}
+
+
+//
+// log messages from kernel space 
+// printk() is used 
+//
+// cb_printf
+
+void kibnal_printf(nal_cb_t *nal, const char *fmt, ...)
+{
+        va_list ap;
+        char    msg[256];
+
+        if (portal_debug & D_NET) {
+                va_start( ap, fmt );
+                vsnprintf( msg, sizeof(msg), fmt, ap );
+                va_end( ap );
+
+                printk("CPUId: %d %s",smp_processor_id(), msg);
+        }
+}
+
+//
+// clear interrupt
+// use spin_lock to lock protected area such as MD, ME...
+// so a process can enter a protected area and do some works
+// this won't physicall disable interrup but use a software 
+// spin-lock to control some protected areas 
+//
+// cb_cli 
+
+void kibnal_cli(nal_cb_t *nal, unsigned long *flags) 
+{ 
+        kibnal_data_t *data= nal->nal_data;
+
+        CDEBUG(D_NET, "kibnal_cli \n");
+
+        spin_lock_irqsave(&data->kib_dispatch_lock,*flags);
+
+}
+
+//
+// set interrupt
+// use spin_lock to unlock protected area such as MD, ME...
+// this won't physicall enable interrup but use a software 
+// spin-lock to control some protected areas 
+//
+// cb_sti
+
+void kibnal_sti(nal_cb_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *data= nal->nal_data;
+
+        CDEBUG(D_NET, "kibnal_sti \n");
+
+        spin_unlock_irqrestore(&data->kib_dispatch_lock,*flags);
+}
+
+
+
+//
+// nic distance 
+// 
+// network distance doesn't mean much for this nal 
+// here we only indicate 
+//      0 - operation is happened on the same node 
+//      1 - operation is happened on different nodes 
+//          router will handle the data routing 
+//
+// cb_dist
+
+int kibnal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
+{
+        CDEBUG(D_NET, "kibnal_dist \n");
+
+        if ( nal->ni.nid == nid ) {
+                *dist = 0;
+        } 
+        else {
+                *dist = 1;
+        }
+
+        return 0; // always retrun 0 
+}
+
+
+//
+// This is the cb_send() on IB based interconnect system
+// prepare a data package and use VAPI_post_sr() to send it
+// down-link out-going message 
+//
+
+
+int
+kibnal_send(nal_cb_t        *nal,
+            void            *private,
+            lib_msg_t       *cookie,
+            ptl_hdr_t       *hdr,
+            int              type,
+            ptl_nid_t        nid,
+            ptl_pid_t        pid,
+            unsigned int     niov,
+            ptl_kiov_t      *iov,
+            size_t           len)
+{
+        
+        int           rc=0;
+        void         *buf = NULL; 
+        unsigned long buf_length = sizeof(ptl_hdr_t) + len;
+        int           expected_buf_size = 0;
+        VAPI_ret_t    vstat;
+
+        PROF_START(kibnal_send); // time stamp send start 
+
+        CDEBUG(D_NET,"kibnal_send: sending %d bytes from %p to nid: 0x%Lx pid %d\n",
+               buf_length, iov, nid, HCA_PORT_1);
+
+
+        // do I need to check the gateway information
+        // do I have problem to send direct 
+        // do I have to forward a data packet to gateway
+        // 
+        // The current connection is back-to-back 
+        // I always know that data will be send from one-side to
+        // the other side
+        //
+        
+        //
+        //  check data buffer size 
+        //
+        //  MSG_SIZE_SMALL 
+        //      regular post send 
+        //  
+        //  MSG_SIZE_LARGE
+        //      rdma write
+        
+        if(buf_length <= SMALL_MSG_SIZE) {  
+           expected_buf_size = MSG_SIZE_SMALL;
+        } 
+        else { 
+          if(buf_length > MAX_MSG_SIZE) { 
+             CERROR("kibnal_send:request exceeds Transmit data size (%d).\n",
+                      MAX_MSG_SIZE);
+             rc = -1;
+             return rc;
+          }
+          else {
+             expected_buf_size = MSG_SIZE_LARGE; // this is a large data package 
+          } 
+        }
+                
+        // prepare data packet for send operation 
+        //
+        // allocate a data buffer "buf" with size of buf_len(header + payload)
+        //                 ---------------
+        //  buf            | hdr         |  size = sizeof(ptl_hdr_t)
+        //                 --------------
+        //                 |payload data |  size = len
+        //                 ---------------
+        
+        // copy header to buf 
+        memcpy(buf, hdr, sizeof(ptl_hdr_t));
+
+        // copy payload data from iov to buf
+        // use portals library function lib_copy_iov2buf()
+        
+        if (len != 0)
+           lib_copy_iov2buf(((char *)buf) + sizeof (ptl_hdr_t),
+                            niov, 
+                            iov, 
+                            len);
+
+        // buf is ready to do a post send 
+        // the send method is base on the buf_size 
+
+        CDEBUG(D_NET,"ib_send %d bytes (size %d) from %p to nid: 0x%Lx "
+               " port %d\n", buf_length, expected_buf_size, iov, nid, HCA_PORT_1);
+
+        switch(expected_buf_size) {
+          case MSG_SIZE_SMALL:
+            // send small message 
+            if((vstat = Send_Small_Msg(buf, buf_length)) != VAPI_OK){
+                CERROR("Send_Small_Msg() is failed\n");
+            } 
+            break;
+
+          case MSG_SIZE_LARGE:
+            // send small message 
+            if((vstat = Send_Large_Msg(buf, buf_length)) != VAPI_OK){
+                CERROR("Send_Large_Msg() is failed\n");
+            } 
+            break;
+
+          default:
+            CERROR("Unknown message size %d\n", expected_buf_size);
+            break;
+        }
+
+        PROF_FINISH(kibnal_send); // time stapm of send operation 
+
+        rc = 1;
+
+        return rc; 
+}
+
+//
+// kibnal_send_pages
+//
+// no support 
+//
+// do you need this 
+//
+int kibnal_send_pages(nal_cb_t * nal, 
+                      void *private, 
+                      lib_msg_t * cookie,
+                      ptl_hdr_t * hdr, 
+                      int type, 
+                      ptl_nid_t nid, 
+                      ptl_pid_t pid,
+                      unsigned int niov, 
+                      ptl_kiov_t *iov, 
+                      size_t mlen)
+{
+   int rc = 1;
+
+   CDEBUG(D_NET, "kibnal_send_pages\n");
+
+   // do nothing now for Infiniband 
+   
+   return rc;
+}
+
+
+
+
+
+//
+// kibnal_fwd_packet 
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
+{
+        CDEBUG(D_NET, "forwarding not implemented\n");
+        return;
+      
+}
+
+//
+// kibnal_callback 
+//
+// no support 
+//
+// do you need this 
+//
+int kibnal_callback(nal_cb_t * nal, 
+                           void *private, 
+                           lib_eq_t *eq,
+                           ptl_event_t *ev)
+{
+        CDEBUG(D_NET,  "callback not implemented\n");
+        return PTL_OK;
+}
+
+
+/* Process a received portals packet */
+//
+//  conver receiving data in to PORTALS header 
+//
+
+void kibnal_rx(kibnal_data_t    *kib, 
+                      VAPI_virt_addr_t buffer_addr,
+                      u_int32_t        buffer_len,
+                      u_int32_t        buffer_size,
+                      unsigned int     priority) 
+{
+        ptl_hdr_t  *hdr = (ptl_hdr_t *)  buffer_addr; // case to ptl header format 
+        kibnal_rx_t krx;
+
+        CDEBUG(D_NET,"kibnal_rx: buf %p, len %ld\n", buffer_addr, buffer_len);
+
+        if ( buffer_len < sizeof( ptl_hdr_t ) ) {
+                /* XXX what's this for? */
+                if (kib->kib_shuttingdown)
+                        return;
+                CERROR("kibnal_rx: did not receive complete portal header, "
+                       "len= %ld", buffer_len);
+
+                return;
+        }
+
+       // typedef struct {
+       //         char             *krx_buffer; // pointer to receiving buffer
+       //         unsigned long     krx_len;  // length of buffer
+       //         unsigned int      krx_size; //
+       //         unsigned int      krx_priority; // do we need this
+       //         struct list_head  krx_item;
+       // } kibnal_rx_t;
+       //
+        krx.krx_buffer    = hdr;
+        krx.krx_len       = buffer_len;
+        krx.krx_size      = buffer_size;
+        krx.krx_priority  = priority;
+
+        if ( hdr->dest_nid == kibnal_lib.ni.nid ) {
+           // this is my data 
+           PROF_START(lib_parse);
+
+           lib_parse(&kibnal_lib, (ptl_hdr_t *)krx.krx_buffer, &krx);
+
+           PROF_FINISH(lib_parse);
+        } else {
+           /* forward to gateway */
+           // Do we expect this happened ?
+           //      
+           CERROR("kibnal_rx: forwarding not implemented yet");
+        }
+
+        return;
+}
+
+
+
+
+//
+// kibnal_recv_pages 
+//
+// no support 
+//
+// do you need this 
+//
+int
+kibnal_recv_pages(nal_cb_t * nal, 
+                  void *private, 
+                  lib_msg_t * cookie,
+                  unsigned int niov, 
+                  ptl_kiov_t *iov, 
+                  size_t mlen,
+                  size_t rlen)
+{
+
+  CDEBUG(D_NET, "recv_pages not implemented\n");
+  return PTL_OK;
+       
+}
+
+
+int 
+kibnal_recv(nal_cb_t     *nal,
+            void         *private,
+            lib_msg_t    *cookie,
+            unsigned int  niov,
+            struct iovec *iov,
+            size_t        mlen,
+            size_t        rlen)
+{
+        kibnal_rx_t *krx = private;
+
+        CDEBUG(D_NET,"kibnal_recv: mlen=%d, rlen=%d\n", mlen, rlen);
+
+        /* What was actually received must be >= what sender claims to
+         * have sent.  This is an LASSERT, since lib-move doesn't
+         * check cb return code yet. */
+        LASSERT (krx->krx_len >= sizeof (ptl_hdr_t) + rlen);
+        LASSERT (mlen <= rlen);
+
+        PROF_START(kibnal_recv);
+
+        if(mlen != 0) {
+                PROF_START(memcpy);
+                lib_copy_buf2iov (niov, iov, krx->krx_buffer +
+                                  sizeof (ptl_hdr_t), mlen);
+                PROF_FINISH(memcpy);
+        }
+
+        PROF_START(lib_finalize);
+        
+        lib_finalize(nal, private, cookie);
+        
+        PROF_FINISH(lib_finalize);
+        PROF_FINISH(kibnal_recv);
+
+        return rlen;
+}
+
+//
+// kibnal_map 
+// no support 
+// do you need this 
+//
+int kibnal_map(nal_cb_t * nal, 
+               unsigned int niov, 
+               struct iovec *iov,
+               void **addrkey)
+{
+  CDEBUG(D_NET, "map not implemented\n");
+  return PTL_OK; 
+}
+
+
+
+//
+// kibnal_unmap
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_unmap(nal_cb_t * nal, 
+                  unsigned int niov, 
+                  struct iovec *iov,
+                  void **addrkey)
+{
+  CDEBUG(D_NET, "unmap not implemented\n");
+  return;
+}
+
+
+
+//
+// kibnal_map_pages 
+// no support 
+// do you need this 
+/* as (un)map, but with a set of page fragments */
+int kibnal_map_pages(nal_cb_t * nal, 
+                     unsigned int niov, 
+                     ptl_kiov_t *iov,
+                     void **addrkey)
+{
+  CDEBUG(D_NET, "map_pages not implemented\n");
+  return PTL_OK;
+}
+
+
+
+//
+// kibnal_unmap_pages 
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_unmap_pages(nal_cb_t * nal, 
+                               unsigned int niov, 
+                               ptl_kiov_t *iov,
+                               void **addrkey)
+{
+  CDEBUG(D_NET, "unmap_pages not implemented\n");
+  return ;
+}
+
+
+int kibnal_end(kibnal_data_t *kib)
+{
+
+  /* wait for sends to finish ? */
+  /* remove receive buffers */
+  /* shutdown receive thread */
+
+  CDEBUG(D_NET, "kibnal_end\n");
+  IB_Close_HCA();
+
+  return 0;
+}
+
+
+//
+//
+//  asynchronous event handler: response to some unexpetced operation errors 
+//    
+//  void async_event_handler(VAPI_hca_hndl_t      hca_hndl,
+//                           VAPI_event_record_t *event_record_p,
+//                           void*                private_data)
+//  the HCA drive will prepare evetn_record_p                        
+//
+//  this handler is registered with VAPI_set_async_event_handler()
+//  VAPI_set_async_event_handler() is issued when an HCA is created 
+//
+//
+void async_event_handler(VAPI_hca_hndl_t      hca_hndl,
+                         VAPI_event_record_t *event_record_p,  
+                         void*                private_data)
+{
+  //
+  // * event_record_p is prepared by the system when an async
+  //   event happened
+  // * what to do with private_data 
+  // * do we expect more async events happened if so what are they 
+  //
+  //   only log ERROR message now 
+
+  switch (event_record_p->type) {
+    case VAPI_PORT_ERROR:
+         printk("Got PORT_ERROR event. port number=%d\n", 
+                 event_record_p->modifier.port_num);
+         break;
+    case VAPI_PORT_ACTIVE:
+         printk("Got PORT_ACTIVE event. port number=%d\n", 
+                 event_record_p->modifier.port_num);
+         break;
+    case VAPI_QP_PATH_MIGRATED:    /*QP*/
+         printk("Got P_PATH_MIGRATED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_EEC_PATH_MIGRATED:   /*EEC*/
+         printk("Got EEC_PATH_MIGRATED event. eec_hndl=%d\n", 
+                 event_record_p->modifier.eec_hndl);
+         break;
+    case VAPI_QP_COMM_ESTABLISHED: /*QP*/
+         printk("Got QP_COMM_ESTABLISHED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_EEC_COMM_ESTABLISHED: /*EEC*/
+         printk("Got EEC_COMM_ESTABLISHED event. eec_hndl=%d\n",
+                 event_record_p->modifier.eec_hndl);
+         break;
+    case VAPI_SEND_QUEUE_DRAINED:  /*QP*/
+         printk("Got SEND_QUEUE_DRAINED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_CQ_ERROR:            /*CQ*/
+         printk("Got CQ_ERROR event. cq_hndl=%lu\n", 
+                 event_record_p->modifier.cq_hndl);
+         break;
+    case VAPI_LOCAL_WQ_INV_REQUEST_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_INV_REQUEST_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_WQ_ACCESS_VIOL_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_ACCESS_VIOL_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_WQ_CATASTROPHIC_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_CATASTROPHIC_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_PATH_MIG_REQ_ERROR:  /*QP*/
+         printk("Got PATH_MIG_REQ_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_CATASTROPHIC_ERROR: /*none*/
+         printk("Got LOCAL_CATASTROPHIC_ERROR event. \n");
+         break;
+    default:
+         printk(":got non-valid event type=%d. IGNORING\n",
+                    event_record_p->type);
+  }
+
+}
+
+
+
+
+VAPI_wr_id_t 
+search_send_buf(int buf_length)
+{
+  VAPI_wr_id_t send_id = -1;
+  u_int32_t    i;
+  int          flag = NO;
+  int          loop_count = 0;  
+
+  CDEBUG(D_NET, "search_send_buf \n");
+  
+  while((flag == NO) && (loop_count < MAX_LOOP_COUNT)) {
+    for(i=0; i < NUM_ENTRY; i++) {
+      // problem about using spinlock
+      spin_lock(&MSB_mutex[i]);
+      if(MSbuf_list[i].status == BUF_REGISTERED)  {
+        MSbuf_list[i].status = BUF_INUSE;// make send buf as inuse
+        flag =  YES;
+        spin_unlock(&MSB_mutex[i]);
+        break;
+      }
+      else
+        spin_unlock(&MSB_mutex[i]); 
+    }
+
+    loop_count++;
+    schedule_timeout(200); // wait for a while 
+  }
+   
+  if(flag == NO)  {
+    CDEBUG(D_NET, "search_send_buf: could not locate an entry in MSbuf_list\n");
+  }
+
+  send_id = (VAPI_wr_id_t ) i;
+
+  return send_id;
+}
+
+
+
+VAPI_wr_id_t 
+search_RDMA_recv_buf(int buf_length)
+{
+  VAPI_wr_id_t recv_id = -1;
+  u_int32_t    i;
+  int          flag = NO;
+  int          loop_count = 0;  
+
+  CDEBUG(D_NET, "search_RDMA_recv_buf\n");
+
+  while((flag == NO) && (loop_count < MAX_LOOP_COUNT)) {
+
+    for(i=NUM_ENTRY; i < NUM_MBUF; i++) {
+
+      spin_lock(&MSB_mutex[i]);
+
+      if((MRbuf_list[i].status == BUF_REGISTERED)  &&
+         (MRbuf_list[i].buf_size >= buf_length)) {
+          MSbuf_list[i].status = BUF_INUSE;// make send buf as inuse
+          flag =  YES;
+          spin_unlock(&MSB_mutex[i]);
+          break;
+      }
+      else
+        spin_unlock(&MSB_mutex[i]);
+    }
+
+    loop_count++;
+
+    schedule_timeout(200); // wait for a while 
+  }
+   
+  if(flag == NO)  {
+    CERROR("search_RDMA_recv_buf: could not locate an entry in MBbuf_list\n");
+  }
+
+  recv_id = (VAPI_wr_id_t ) i;
+
+  return recv_id;
+
+}
+
+
+
+
+
+
+
+VAPI_ret_t Send_Small_Msg(char *buf, int buf_length)
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+
+ CDEBUG(D_NET, "Send_Small_Msg\n");
+
+ send_id = search_send_buf(buf_length); 
+
+ if(send_id < 0){
+   CERROR("Send_Small_Msg: Can not find a QP \n");
+   return(~VAPI_OK);
+ }
+
+ qp = &QP_list[(int) send_id];
+
+ // find a suitable/registered send_buf from MSbuf_list
+ CDEBUG(D_NET, "Send_Small_Msg: current send id  %d \n", send_id);
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        =  send_id;
+
+
+ // scatter and gather info 
+ sr_sg.len  = buf_length;
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, buf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ CDEBUG(D_NET, "VAPI_post_sr success.\n");
+
+ return (vstat);
+
+}
+
+
+
+
+VAPI_wr_id_t
+RTS_handshaking_protocol(int buf_length) 
+{
+
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ VAPI_wr_id_t         send_id;
+
+ RDMA_Info_Exchange   rdma_info;
+
+ rdma_info.opcode     = Ready_To_send;
+ rdma_info.buf_length = buf_length; 
+ rdma_info.raddr      = (VAPI_virt_addr_t) 0;
+ rdma_info.rkey       = (VAPI_rkey_t) 0 ; 
+
+ QP_info              *qp;
+
+ CDEBUG(D_NET, "RTS_handshaking_protocol\n");
+
+ // find a suitable/registered send_buf from MSbuf_list
+ send_id = search_send_buf(sizeof(RDMA_Info_Exchange));   
+
+ qp = &QP_list[(int) send_id];
+
+ CDEBUG(D_NET, "RTS_CTS: current send id  %d \n", send_id);
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        = send_id + RDMA_RTS_ID;// this RTS mesage ID 
+
+ // scatter and gather info 
+ sr_sg.len  = sizeof(RDMA_Info_Exchange);
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, &rdma_info, sizeof(RDMA_Info_Exchange));
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this RTS message data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("RTS: VAPI_post_sr failed (%s).\n",VAPI_strerror_sym(vstat));
+ }
+
+ return send_id;
+
+}
+
+
+
+// create local receiving Memory Region for a HCA
+VAPI_ret_t
+createMemRegion_RDMA(VAPI_hca_hndl_t  hca_hndl,
+                     VAPI_pd_hndl_t   pd_hndl,
+                     char            *bufptr,
+                     int              buf_length,
+                     VAPI_mr_hndl_t   *rep_mr_hndl,
+                     VAPI_mrw_t       *rep_mr)
+{
+  VAPI_ret_t      vstat;
+  VAPI_mrw_t      mrw;
+  
+  CDEBUG(D_NET, "createMemRegion_RDMA\n");
+
+  // memory region address and size of memory region
+  // allocate a block of memory for this HCA 
+  // RDMA data buffer
+  
+  
+  if(bufptr == NULL) {
+    // need to allcate a local buffer to receive data from a
+    // remore VAPI_RDMA_WRITE_IMM
+    PORTAL_ALLOC(bufptr, buf_length);
+  }
+
+  if(bufptr == NULL) {
+    CDEBUG(D_MALLOC, "Failed to malloc a block of RDMA receiving memory, size %d\n",
+                                    buf_length);
+    return(VAPI_ENOMEM);
+  }
+
+  /* Register RDAM data Memory region */
+  CDEBUG(D_NET, "Register a RDMA data memory region\n");
+
+  mrw.type   = VAPI_MR;
+  mrw.pd_hndl= pd_hndl;
+  mrw.start  = (VAPI_virt_addr_t )(MT_virt_addr_t )bufptr;
+  mrw.size   = buf_length;
+  mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+               VAPI_EN_REMOTE_WRITE | 
+               VAPI_EN_REMOTE_READ;
+
+  // register send memory region
+  vstat = VAPI_register_mr(hca_hndl,
+                           &mrw,
+                           rep_mr_hndl,
+                           rep_mr);
+
+  // this memory region is going to be reused until deregister is called
+  if (vstat != VAPI_OK) {
+     CERROR("Failed registering a mem region Addr=%p, Len=%d. %s\n",
+             bufptr, buf_length, VAPI_strerror(vstat));
+  }
+
+  return(vstat);
+
+}
+
+
+
+RDMA_Info_Exchange  Local_rdma_info;
+
+int insert_MRbuf_list(int buf_lenght)
+{
+  int  recv_id = NUM_ENTRY;      
+
+  CDEBUG(D_NET, "insert_MRbuf_list\n");
+
+  for(recv_id= NUM_ENTRY; recv_id < NUM_MBUF; recv_id++){
+       if(BUF_UNREGISTERED == MRbuf_list[recv_id].status)  {
+         MRbuf_list[recv_id].status   = BUF_UNREGISTERED;
+         MRbuf_list[recv_id].buf_size = buf_lenght;
+         break;
+       }
+  }
+
+  return recv_id;
+
+}  
+
+VAPI_wr_id_t
+CTS_handshaking_protocol(RDMA_Info_Exchange *rdma_info) 
+{
+
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info             *qp;
+ VAPI_wr_id_t         send_id;
+ VAPI_mr_hndl_t       rep_mr_hndl;
+ VAPI_mrw_t           rep_mr;
+ int                  recv_id;
+ char                *bufptr = NULL;
+
+ // search MRbuf_list for an available entry that
+ // has registered data buffer with size equal to rdma_info->buf_lenght
+
+ CDEBUG(D_NET, "CTS_handshaking_protocol\n");
+
+ // register memory buffer for RDAM operation
+
+ vstat = createMemRegion_RDMA(Hca_hndl,
+                              Pd_hndl,
+                              bufptr, 
+                              rdma_info->buf_length,
+                              &rep_mr_hndl,
+                              &rep_mr);
+
+
+ Local_rdma_info.opcode            = Clear_To_send;
+ Local_rdma_info.recv_rdma_mr      = rep_mr;
+ Local_rdma_info.recv_rdma_mr_hndl = rep_mr_hndl;
+
+ if (vstat != VAPI_OK) {
+    CERROR("CST_handshaking_protocol: Failed registering a mem region"
+           "Len=%d. %s\n", rdma_info->buf_length, VAPI_strerror(vstat));
+    Local_rdma_info.flag = RDMA_BUFFER_UNAVAILABLE;
+ }
+ else {
+    // successfully allcate reserved RDAM data buffer 
+    recv_id = insert_MRbuf_list(rdma_info->buf_length);   
+
+    if(recv_id >=  NUM_ENTRY) { 
+      MRbuf_list[recv_id].buf_addr     = rep_mr.start;
+      MRbuf_list[recv_id].mr           = rep_mr;
+      MRbuf_list[recv_id].mr_hndl      = rep_mr_hndl;
+      MRbuf_list[recv_id].ref_count    = 0;
+      Local_rdma_info.flag             = RDMA_BUFFER_RESERVED;
+      Local_rdma_info.buf_length       = rdma_info->buf_length; 
+      Local_rdma_info.raddr            = rep_mr.start;
+      Local_rdma_info.rkey             = rep_mr.r_key; 
+    }
+    else {
+      CERROR("Can not find an entry in MRbuf_list - how could this happen\n");  
+    }
+ }
+
+ // find a suitable/registered send_buf from MSbuf_list
+ send_id = search_send_buf(sizeof(RDMA_Info_Exchange)); 
+ CDEBUG(D_NET, "CTS: current send id  %d \n", send_id);
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        = send_id + RDMA_CTS_ID; // this CST message ID 
+
+ // scatter and gather info 
+ sr_sg.len  = sizeof(RDMA_Info_Exchange);
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, &Local_rdma_info, sizeof(RDMA_Info_Exchange));
+
+ sr_desc.sg_lst_p   = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this RTS message data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("CTS: VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+
+}
+
+
+
+VAPI_ret_t Send_Large_Msg(char *buf, int buf_length)
+{
+  VAPI_ret_t           vstat;
+  VAPI_sr_desc_t       sr_desc;
+  VAPI_sg_lst_entry_t  sr_sg;
+  QP_info             *qp;
+  VAPI_mrw_t           rep_mr; 
+  VAPI_mr_hndl_t       rep_mr_hndl;
+  int                  send_id;
+  VAPI_imm_data_t      imm_data = 0XAAAA5555;
+
+
+  CDEBUG(D_NET, "Send_Large_Msg: Enter\n");
+
+  // register this large buf 
+  // don't need to copy this buf to send buffer
+  vstat = createMemRegion_RDMA(Hca_hndl,
+                               Pd_hndl,
+                               buf,
+                               buf_length,
+                               &rep_mr_hndl,
+                               &rep_mr);
+
+  if (vstat != VAPI_OK) {
+    CERROR("Send_Large_M\sg:  createMemRegion_RDMAi() failed (%s).\n",
+                        VAPI_strerror(vstat));
+  }
+  
+
+  Local_rdma_info.send_rdma_mr      = rep_mr;
+  Local_rdma_info.send_rdma_mr_hndl = rep_mr_hndl;
+
+  //
+  //     Prepare descriptor for send queue
+  //
+ 
+  // ask for a remote rdma buffer with size buf_lenght
+  send_id = RTS_handshaking_protocol(buf_length); 
+
+  qp = &QP_list[send_id];
+
+  // wait for CTS message receiving from remote node 
+  while(1){
+     if(YES == Cts_Message_arrived) {
+        // receive CST message from remote node 
+        // Rdma_info is available for use
+        break;
+     }
+     schedule_timeout(RTS_CTS_TIMEOUT);
+  }
+  
+  sr_desc.id        = send_id + RDMA_OP_ID;
+  sr_desc.opcode    = VAPI_RDMA_WRITE_WITH_IMM;
+  sr_desc.comp_type = VAPI_SIGNALED;
+
+  // scatter and gather info 
+  sr_sg.len  = buf_length;
+
+  // rdma mr 
+  sr_sg.lkey = rep_mr.l_key;  
+  sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) rep_mr.start;
+  sr_desc.sg_lst_p = &sr_sg;
+  sr_desc.sg_lst_len = 1; // only 1 entry is used 
+
+  // immediate data - not used here 
+  sr_desc.imm_data = imm_data;
+  sr_desc.fence = TRUE;
+  sr_desc.set_se = FALSE;
+
+  // RDAM operation only
+  // raddr and rkey is receiving from remote node  
+  sr_desc.remote_addr = Rdma_info.raddr;
+  sr_desc.r_key       = Rdma_info.rkey;
+
+  // call VAPI_post_sr to send out this data 
+  vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+  if (vstat != VAPI_OK) {
+     CERROR("VAPI_post_sr failed (%s).\n",VAPI_strerror_sym(vstat));
+  }
+
+}
+
+
+
+
+
+
+//
+//  repost_recv_buf
+//  post a used recv buffer back to recv WQE list 
+//  wrq_id is used to indicate the starting position of recv-buffer 
+//
+VAPI_ret_t 
+repost_recv_buf(QP_info      *qp,
+                VAPI_wr_id_t  wrq_id) 
+{
+  VAPI_rr_desc_t       rr;
+  VAPI_sg_lst_entry_t  sg_entry;
+  VAPI_ret_t           ret;
+
+  CDEBUG(D_NET, "repost_recv_buf\n");
+
+  sg_entry.lkey = MRbuf_list[wrq_id].mr.l_key;
+  sg_entry.len  = MRbuf_list[wrq_id].buf_size;
+  sg_entry.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[wrq_id].buf_addr;
+  rr.opcode     = VAPI_RECEIVE;
+  rr.comp_type  = VAPI_SIGNALED; /* All with CQE (IB compliant) */
+  rr.sg_lst_len = 1; /* single buffers */
+  rr.sg_lst_p   = &sg_entry;
+  rr.id         = wrq_id; /* WQE id used is the index to buffers ptr array */
+
+  ret= VAPI_post_rr(qp->hca_hndl,qp->qp_hndl,&rr);
+     
+  if (ret != VAPI_OK){
+     CERROR("failed reposting RQ WQE (%s) buffer \n",VAPI_strerror_sym(ret));
+     return ret;
+  }
+
+  CDEBUG(D_NET, "Successfully reposting an RQ WQE %d recv bufer \n", wrq_id);
+
+  return ret ;
+}
+			
+//
+// post_recv_bufs
+// 	post "num_o_bufs" for receiving data
+//      each receiving buf (buffer starting address, size of buffer)
+//      each buffer is associated with an id 
+//
+int 
+post_recv_bufs(VAPI_wr_id_t  start_id)
+{
+  int i;
+  VAPI_rr_desc_t       rr;
+  VAPI_sg_lst_entry_t  sg_entry;
+  VAPI_ret_t           ret;
+
+  CDEBUG(D_NET, "post_recv_bufs\n");
+
+  for(i=0; i< NUM_ENTRY; i++) {
+    sg_entry.lkey = MRbuf_list[i].mr.l_key;
+    sg_entry.len  = MRbuf_list[i].buf_size;
+    sg_entry.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[i].buf_addr;
+    rr.opcode     = VAPI_RECEIVE;
+    rr.comp_type  = VAPI_SIGNALED;  /* All with CQE (IB compliant) */
+    rr.sg_lst_len = 1; /* single buffers */
+    rr.sg_lst_p   = &sg_entry;
+    rr.id         = start_id+i; /* WQE id used is the index to buffers ptr array */
+
+    ret= VAPI_post_rr(QP_list[i].hca_hndl,QP_list[i].qp_hndl, &rr);
+    if (ret != VAPI_OK) {
+       CERROR("failed posting RQ WQE (%s)\n",VAPI_strerror_sym(ret));
+       return i;
+    } 
+  }
+
+  return i; /* num of buffers posted */
+}
+			
+int 
+post_RDMA_bufs(QP_info      *qp, 
+               void         *buf_array,
+               unsigned int  num_bufs,
+               unsigned int  buf_size,
+               VAPI_wr_id_t  start_id)
+{
+
+  CDEBUG(D_NET, "post_RDMA_bufs \n");
+  return YES;
+}
+
+
+
+//
+// LIB NAL
+// assign function pointers to theirs corresponding entries
+//
+
+nal_cb_t kibnal_lib = {
+        nal_data:       &kibnal_data,  /* NAL private data */
+        cb_send:        kibnal_send,
+        cb_send_pages:  NULL, // not implemented  
+        cb_recv:        kibnal_recv,
+        cb_recv_pages:  NULL, // not implemented 
+        cb_read:        kibnal_read,
+        cb_write:       kibnal_write,
+        cb_callback:    NULL, // not implemented 
+        cb_malloc:      kibnal_malloc,
+        cb_free:        kibnal_free,
+        cb_map:         NULL, // not implemented 
+        cb_unmap:       NULL, // not implemented 
+        cb_map_pages:   NULL, // not implemented 
+        cb_unmap_pages: NULL, // not implemented 
+        cb_printf:      kibnal_printf,
+        cb_cli:         kibnal_cli,
+        cb_sti:         kibnal_sti,
+        cb_dist:        kibnal_dist // no used at this moment 
+};
diff --git a/lnet/klnds/iblnd/ibnal_send_recv_self_testing.c b/lnet/klnds/iblnd/ibnal_send_recv_self_testing.c
new file mode 100644
index 0000000000000000000000000000000000000000..82defdba876d0bf3ce03f66809031e157bdffaf4
--- /dev/null
+++ b/lnet/klnds/iblnd/ibnal_send_recv_self_testing.c
@@ -0,0 +1,116 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *  *
+ *  * Based on ksocknal, qswnal, and gmnal
+ *  *
+ *  * Copyright (C) 2003 LANL
+ *  *   Author: HB Chen <hbchen@lanl.gov>
+ *  *   Los Alamos National Lab
+ *  *
+ *  *   Portals is free software; you can redistribute it and/or
+ *  *   modify it under the terms of version 2 of the GNU General Public
+ *  *   License as published by the Free Software Foundation.
+ *  *
+ *  *   Portals 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 Portals; if not, write to the Free Software
+ *  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  *
+ *  */
+
+#include "ibnal.h"
+
+
+
+VAPI_ret_t ibnal_send_recv_self_testing()
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+ int                  buf_id;
+ char                 sbuf[KB_32];
+ char                 rbuf[KB_32];
+ int                  i;
+ int                  buf_length = KB_32;
+ VAPI_wc_desc_t       comp_desc;
+ int                  num_send = 1;
+ int                  loop_count = 0;
+
+
+ printk("ibnal_send_recv_self_testing\n");
+
+ memset(&sbuf, 'a', KB_32);
+ memset(&rbuf, ' ', KB_32);
+ 
+ send_id = 2222; 
+ buf_id = 0;
+
+ qp = &QP_list[0];
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+
+ // scatter and gather info
+ sr_sg.len  = KB_32;
+ sr_sg.lkey = MSbuf_list[buf_id].mr.l_key; // use send MR
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[buf_id].buf_addr;
+
+ // copy data to register send buffer
+ memcpy(&sr_sg.addr, &buf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+
+ // call VAPI_post_sr to send out this data
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+   printk("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ printk("VAPI_post_sr success.\n");
+
+ // poll for completion
+
+ while( loop_count < 100 ){
+   vstat = VAPI_poll_cq(qp->hca_hndl, qp->cq_hndl, &comp_desc);
+   if( vstat == VAPI_OK ) {
+       if(comp_desc.opcode == VAPI_CQE_SQ_SEND_DATA ) {
+          /* SEND completion */
+         printk("received SQ completion\n");
+       }
+       else { 
+          if(comp_desc.opcode == VAPI_CQE_RQ_SEND_DATA ) {
+	    /* RECEIVE completion */
+            printk("received RQ completion\n");
+            memcpy(&rbuf, (char *) MRbuf_list[buf_id].buf_addar, KB_32);
+	    
+	    int n;
+
+	    n = memcmp($sbuf, &rbuf, KB_32);
+	    printk("compare sbuf and rbuf  n = %d\n", n); 
+	    
+          }
+       	  else  {
+            printk("unexpected completion opcode %d \n", comp_desc.opcode);
+	  }
+       }
+   }
+
+   loop_count++; 
+   schedule_timeout(500);
+ }
+
+ printk("end of ibnal_self_send_recv_testing\n");
+
+
+}
diff --git a/lnet/klnds/iblnd/uagent.c b/lnet/klnds/iblnd/uagent.c
new file mode 100644
index 0000000000000000000000000000000000000000..d7e939ae97880022db10ed5395cea884375a4191
--- /dev/null
+++ b/lnet/klnds/iblnd/uagent.c
@@ -0,0 +1,391 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+
+#include <linux/shm.h>
+#include <linux/ipc.h>
+#include <linux/stat.h>
+#include <linux/types.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+// Infiniband VAPI/EVAPI header files Mellanox MT23108 VAPI
+#include <vapi.h>
+#include <vapi_types.h>
+#include <vapi_common.h>
+#include <evapi.h>
+
+// Remote HCA Info information
+ typedef struct Remote_HCA_Info {
+       unsigned long     opcode;
+       unsigned long     length;
+       IB_lid_t          dlid[256];
+       VAPI_qp_num_t     rqp_num[256];
+       VAPI_rkey_t       rkey;   // for remote RDAM request
+       unsigned long     vaddr1; // virtual address fisrt 4 bytes
+       unsigned long     vaddr2; // virtual address second 4 bytes
+       u_int32_t         size;   // size of RDMA memory buffer
+       char              dest_ip[256]; //destination server IP address 
+ } Remote_HCA_Info;
+
+#define SHARED_SEGMENT_SIZE  0x10000 // 16KB shared memory between U and K
+
+// some internals opcodes for IB operations used in IBNAL
+#define SEND_QP_INFO          0X00000001
+#define RECV_QP_INFO          0X00000010
+#define DEFAULT_SOCKET_PORT   11211 
+#define LISTEN_QUEUE_SIZE     2048 
+#define DEST_IP		      "10.128.105.26"
+
+// server_thread
+// + wait for an incoming connection from remote node 
+// + receive remote HCA's data 
+//
+//
+//
+//
+// 
+void *server_thread(void *vargp)
+{
+  Remote_HCA_Info   *hca_data;
+  Remote_HCA_Info   hca_data_buffer;
+  
+  int    serverfd;
+  int    infd;
+  struct hostent  *hp;
+  struct sockaddr_in serveraddr;
+  struct sockaddr_in clientaddr;
+  int    sin_size=sizeof(struct sockaddr_in);
+  int	 bytes_recv;
+  int    i;
+
+
+  hca_data = (Remote_HCA_Info *) vargp;
+  
+  if((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    printf("server_thread couldnot create a socket \n");
+    pthread_exit((void *) 0);
+  }
+ 
+  printf("server_thread create a socket \n");
+
+  bzero((char *) &serveraddr, sizeof(serveraddr));
+
+  serveraddr.sin_family = AF_INET;
+  serveraddr.sin_addr.s_addr = htons(INADDR_ANY);
+  serveraddr.sin_port = htons((unsigned short) DEFAULT_SOCKET_PORT);
+  
+  if(bind(serverfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr)) < 0) {
+    printf("server_thread couldnot bind to a socket \n");
+    pthread_exit((void *) 0);
+  }
+
+  printf("server_thread bind to a socket \n");
+
+  if(listen(serverfd, LISTEN_QUEUE_SIZE) < 0) {
+    printf("server_thread couldnot listen to a socket \n");
+    pthread_exit((void *) 0);
+  }
+
+  printf("server_thread listen to a socket \n");
+
+  //
+  // I only expect to receive one HCA data from a remote HCA 
+  //
+  printf("server_thread: Waiting for a connection\n");
+  infd= accept(serverfd,(struct sockaddr*)&clientaddr,&sin_size);
+  printf("server_thread: Got an incoming connection");
+
+  /* receive data from socket into buffer */
+  bytes_recv = recv(infd,
+                    &hca_data_buffer,  
+                    sizeof(Remote_HCA_Info),
+		    0);
+
+  if(bytes_recv > 0) {
+/*	  
+      printf("server_thread receive data\n");
+      printf("opcode is 0x%X\n", hca_data_buffer.opcode);
+      printf("length is 0x%X\n", hca_data_buffer.length);
+
+      for(i=0; i < 256; i++) {
+        printf("dlid %d is 0x%X\n", i, hca_data_buffer.dlid[i]);
+        printf("rqp_num %d is 0x%X\n", hca_data_buffer.rqp_num[i]);
+      }
+
+      printf("rkey is 0x%X\n", hca_data_buffer.rkey);
+      printf("vaddr1 is 0x%X\n", hca_data_buffer.vaddr1);
+      printf("vaddr2 is 0x%X\n", hca_data_buffer.vaddr2);
+      printf("size is 0x%X\n", hca_data_buffer.size);
+      printf("After conversion hton \n");
+      printf("opcode is 0x%X\n", htonl(hca_data_buffer.opcode));
+      printf("length is 0x%X\n", htonl(hca_data_buffer.length));
+
+      for(i=0; i < 256; i++) {
+        printf("dlid %d is 0x%X\n", htons(hca_data_buffer.dlid[i]));
+        printf("rqp_num %d is 0x%X\n", htonl(hca_data_buffer.rqp_num[i]));
+      }
+
+      printf("rkey is 0x%X\n", htonl(hca_data_buffer.rkey));
+      printf("vaddr1 is 0x%X\n", htonl(hca_data_buffer.vaddr1));
+      printf("vaddr2 is 0x%X\n", htonl(hca_data_buffer.vaddr2));
+      printf("size is 0x%X\n", htonl(hca_data_buffer.size));
+*/     
+
+      hca_data->opcode  = ntohl(hca_data_buffer.opcode); // long 
+      hca_data->length  = ntohl(hca_data_buffer.length); // long
+
+      for(i=0; i < 256; i++) {
+        hca_data->dlid[i]    = ntohs(hca_data_buffer.dlid[i]);   // u_int16
+        hca_data->rqp_num[i] = ntohl(hca_data_buffer.rqp_num[i]);// u_int32
+      }
+
+      hca_data->rkey    = ntohl(hca_data_buffer.rkey);   // u_int32
+      hca_data->vaddr1  = ntohl(hca_data_buffer.vaddr1); // first word u_int32
+      hca_data->vaddr2  = ntohl(hca_data_buffer.vaddr2); // second word u_int32
+      hca_data->size    = ntohl(hca_data_buffer.size);   // u_int32
+    }
+    else {
+      printf("server_thread receive ERROR bytes_recv = %d\n", bytes_recv);
+    }
+
+    close(infd);
+    close(serverfd);
+
+  printf("server_thread EXIT \n");
+      
+  pthread_exit((void *) 0);
+
+}
+
+//
+// client_thread 
+// + connect to a remote server_thread
+// + send local HCA's data to remote server_thread
+//
+void *client_thread(void *vargp)
+{
+
+  Remote_HCA_Info   *hca_data;
+  Remote_HCA_Info   hca_data_buffer;
+
+  int    clientfd;
+  struct hostent  *hp;
+  struct sockaddr_in clientaddr;
+  int    bytes_send;
+  int    i;
+  
+  hca_data = (Remote_HCA_Info *) vargp;
+
+  if((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    printf("client_thread couldnot create a socket \n");
+    pthread_exit((void *) 0);
+  }
+ 
+  printf("client_thread create a socket \n");
+  
+  bzero((char *) &clientaddr, sizeof(clientaddr));
+
+  clientaddr.sin_family = AF_INET;
+  clientaddr.sin_addr.s_addr = inet_addr(hca_data->dest_ip);
+  printf("client_thread get server Ip address = %s\n", hca_data->dest_ip);
+  clientaddr.sin_port = htons((unsigned short) DEFAULT_SOCKET_PORT);
+  memset(&(clientaddr.sin_zero), '\0', 8);
+
+  connect(clientfd, (struct sockaddr *) &clientaddr, sizeof(struct sockaddr));
+
+  printf("client_thread connect to  server Ip address = %s\n", hca_data->dest_ip);
+
+  hca_data_buffer.opcode  = htonl(hca_data->opcode); // long 
+  hca_data_buffer.length  = htonl(hca_data->length); // long
+
+  for(i=0; i < 256; i++) {
+    hca_data_buffer.dlid[i]    = htons(hca_data->dlid[i]);   // u_int16
+    hca_data_buffer.rqp_num[i] = htonl(hca_data->rqp_num[i]);// u_int32
+  }
+
+  hca_data_buffer.rkey    = htonl(hca_data->rkey);   // u_int32
+  hca_data_buffer.vaddr1  = htonl(hca_data->vaddr1); // first word u_int32
+  hca_data_buffer.vaddr2  = htonl(hca_data->vaddr2); // second word u_int32
+  hca_data_buffer.size    = htonl(hca_data->size);   // u_int32
+ 
+  bytes_send = send(clientfd, & hca_data_buffer, sizeof(Remote_HCA_Info), 0); 
+  
+  if(bytes_send == sizeof(Remote_HCA_Info)) {
+    printf("client_thread: send successfully \n");
+  }
+  else {
+    printf("client_thread: send failed \n");
+  }
+
+  printf("client_thread EXIT \n");
+
+  pthread_exit((void *) 0);
+}
+
+
+//
+//  main 
+//  + create a shared-memory between this main()/user address and
+//    a kernel thread/kernel address space associated with inbal 
+//    kernel module 
+//  + access local HCA's data through this shared memory 
+//
+//  + create a server_thread for receiving remote HCA's data
+//  + create a client_thread for sending out local HCA's data
+//  + after receiving remote HCA's data update this shared memory
+//
+int  main(int argc , char *argv[])
+{
+  int              segment_id;
+  struct shmid_ds  shmbuffer;
+  int              segment_size;
+  const int        shared_segment_size = sizeof(Remote_HCA_Info);
+  key_t            key = 999;
+  unsigned long    raddr;
+  Remote_HCA_Info  *shared_memory;
+  Remote_HCA_Info  exchange_hca_data;
+  Remote_HCA_Info  remote_hca_data;
+  int i; 
+
+  /* pthread */
+  pthread_t          sid;
+  pthread_t          cid;
+  pthread_attr_t     attr; 
+  int                rc, status;
+
+  char dest_ip[256];
+
+  if(argc != 2) {
+	  printf("USAGE:   uagent   server_ip_address\n");
+	  printf("argc = %d \n", argc);
+	  exit(1);
+  }
+
+  strcpy(&exchange_hca_data.dest_ip[0], argv[1]);
+  printf("the destinational server IP address = %s\n", 
+		                       &exchange_hca_data.dest_ip); 
+
+  segment_id =  shmget(key, shared_segment_size, IPC_CREAT | 0666);
+
+  printf("sys_shmget is done segment_id = %d\n", segment_id);
+
+  shared_memory = (Remote_HCA_Info *) shmat(segment_id, 0, 0);
+
+  if(shared_memory == (char *) -1) {
+    printf("Shared memory attach failed shared_memory=%p\n",shared_memory);
+    exit(0);
+  }
+
+  printf("shared menory attached at address %p\n", shared_memory);
+
+  while (1) {
+    if(shared_memory->opcode ==  SEND_QP_INFO) {
+      printf("Local HCA data received from kernel thread\n");
+      break;
+    }
+    usleep(1000);
+    continue;
+  }
+
+  printf("Local HCA data received from kernel thread\n");
+
+  // save local HCA's data in exchange_hca_data
+  //
+  exchange_hca_data.opcode  = shared_memory->opcode;
+  exchange_hca_data.length  = shared_memory->length;
+
+  for(i=0; i < 256; i++) {
+    exchange_hca_data.dlid[i]    = shared_memory->dlid[i];
+    exchange_hca_data.rqp_num[i] = shared_memory->rqp_num[i];
+  }
+
+  exchange_hca_data.rkey    = shared_memory->rkey;
+  exchange_hca_data.vaddr1  = shared_memory->vaddr1;
+  exchange_hca_data.vaddr2  = shared_memory->vaddr2;
+  exchange_hca_data.size    = shared_memory->size;
+
+  /* Initialize and set thread detached attribute */
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+  /* create a server thread for procsssing incoming remote node socket data */
+  // 
+  pthread_create(&sid, 
+		  &attr, 
+		  server_thread,
+		  (Remote_HCA_Info *) &remote_hca_data);
+
+  printf("Main: created a server thread \n");
+
+  sleep(10);
+  
+  /* create a clint thread to send out local HCA data to remote node */
+  pthread_create(&cid, 
+		  &attr, 
+		  client_thread,
+		  (Remote_HCA_Info *) &exchange_hca_data);
+
+  printf("Main: created a client  thread \n");
+
+  /* synchronization between server_thread and client_thread */
+  pthread_attr_destroy(&attr);
+
+  rc = pthread_join(sid, (void **) &status);
+  if(rc) {
+    printf("Error: return code from pthread_join() is %d\n", rc);
+    exit(-1);
+  }
+
+  printf("completed join with thread %d status = %d\n", sid, status);
+
+  rc = pthread_join(cid, (void **) &status);
+  if(rc) {
+    printf("Error: return code from pthread_join() is %d\n", rc);
+    exit(-1);
+  }
+  printf("completed join with thread %d status = %d\n", cid, status);
+
+  // update shared memory with remote HCA's data 
+
+  shared_memory->opcode = RECV_QP_INFO;
+  shared_memory->length = remote_hca_data.length;
+  for(i=0; i < 256; i++) {
+    shared_memory->dlid[i]   = remote_hca_data.dlid[i];
+    shared_memory->rqp_num[i]= remote_hca_data.rqp_num[i];
+  }
+  shared_memory->rkey   = remote_hca_data.rkey;
+  shared_memory->vaddr1 = remote_hca_data.vaddr1;
+  shared_memory->vaddr2 = remote_hca_data.vaddr2;
+  shared_memory->size   = remote_hca_data.size;
+
+  sleep(5);
+
+  shared_memory->opcode = RECV_QP_INFO;
+  shared_memory->length = remote_hca_data.length;
+  for(i=0; i < 256; i++) {
+    shared_memory->dlid[i]   = remote_hca_data.dlid[i];
+    shared_memory->rqp_num[i]= remote_hca_data.rqp_num[i];
+  }
+  
+  shared_memory->rkey   = remote_hca_data.rkey;
+  shared_memory->vaddr1 = remote_hca_data.vaddr1;
+  shared_memory->vaddr2 = remote_hca_data.vaddr2;
+  shared_memory->size   = remote_hca_data.size;
+
+  sleep(10);
+  
+//  shmdt(shared_memory);
+   
+  printf("uagent is DONE \n");
+  
+ 
+
+  exit(0);
+
+}
+
diff --git a/lnet/klnds/lgmlnd/Makefile.am b/lnet/klnds/lgmlnd/Makefile.am
deleted file mode 100644
index 6794494ecbf180bfb08e6e23da13d9c62fd045ed..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2001  Cluster File Systems, Inc.
-#
-# This code is issued under the GNU General Public License.
-# See the file COPYING in this distribution
-
-include ../../Rules.linux
-
-MODULE = lgmnal
-modulenet_DATA = lgmnal.o
-EXTRA_PROGRAMS = lgmnal
-
-DEFS =
-lgmnal_SOURCES = lgmnal.h lgmnal_api.c lgmnal_cb.c lgmnal_comm.c lgmnal_utils.c lgmnal_module.c
diff --git a/lnet/klnds/lgmlnd/lgmnal.h b/lnet/klnds/lgmlnd/lgmnal.h
deleted file mode 100644
index 8b496ec1880a947c2e65538d835ff6e69ee6a669..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	Portals GM kernel NAL header file
- *	This file makes all declaration and prototypes 
- *	for the API side and CB side of the NAL
- */
-#ifndef __INCLUDE_LGMNAL_H__
-#define __INCLUDE_LGMNAL_H__
-
-#include "linux/config.h"
-#include "linux/module.h"
-#include "linux/tty.h"
-#include "linux/kernel.h"
-#include "linux/mm.h"
-#include "linux/string.h"
-#include "linux/stat.h"
-#include "linux/errno.h"
-#include "linux/locks.h"
-#include "linux/unistd.h"
-#include "linux/init.h"
-#include "linux/sem.h"
-#include "linux/vmalloc.h"
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
-
-
-#include "portals/nal.h"
-#include "portals/api.h"
-#include "portals/errno.h"
-#include "linux/kp30.h"
-#include "portals/p30.h"
-
-#include "portals/lib-nal.h"
-#include "portals/lib-p30.h"
-
-#define GM_STRONG_TYPES 1
-#include "gm.h"
-#include "gm_internal.h"
-
-
-/*
- *	Defines for the API NAL
- */
-
-
-
-/*
- *	Small message size is configurable
- *	insmod can set small_msg_size
- *	which is used to populate nal_data.small_msg_size
- */
-#define LGMNAL_SMALL_MESSAGE		1078
-#define LGMNAL_LARGE_MESSAGE_INIT	1079
-#define LGMNAL_LARGE_MESSAGE_ACK	1080
-#define LGMNAL_LARGE_MESSAGE_FINI	1081
-
-extern  int lgmnal_small_msg_size;
-#define LGMNAL_SMALL_MSG_SIZE(a)	a->small_msg_size
-#define LGMNAL_IS_SMALL_MESSAGE(n,a,b,c)	lgmnal_is_small_message(n, a, b, c)
-#define LGMNAL_MAGIC	0x1234abcd
-
-typedef struct _lgmnal_hash {
-		void *key;
-		void *data;
-		struct _lgmnal_hash	*next;
-	} lgmnal_hash_t;
-
-/*
- *	Small Transmit Descriptor
- *	A structre to keep track of a small transmit operation
- *	This structure has a one-to-one relationship with a small
- *	transmit buffer (both create by lgmnal_stxd_alloc). 
- *	stxd has pointer to txbuffer and the hash table in nal_data
- *	allows us to go the other way.
- */
-typedef struct _lgmnal_stxd_t {
-	void 	*buffer;		/* Address of small wired buffer this decriptor uses */
-	int	size;			/* size (in bytes) of the tx buffer this descripto uses */
-	gm_size_t	gmsize;		/* gmsize of the tx buffer this descripto uses */
-	int	type;			/* large or small message */
-	struct _lgmnal_data_t *nal_data;
-	lib_msg_t	*cookie;	/* the cookie the portals library gave us */
-	int	niov;
-	struct iovec	iov[PTL_MD_MAX_IOV];
-	struct _lgmnal_stxd_t	*next;
-} lgmnal_stxd_t;
-
-/*
- *	as for lgmnal_stxd_t 
- */
-typedef struct _lgmnal_srxd_t {
-	void 	*buffer;
-	int	size;
-	gm_size_t	gmsize;
-	int	type;
-	struct _lgmnal_srxd_t	*next;
-} lgmnal_srxd_t;
-
-/*
- *	Header which lmgnal puts at the start of each message
- */
-typedef struct	_lgmnal_msghdr {
-	int	magic;
-	int 	type;
-	unsigned int	sender_node_id;
-	lgmnal_stxd_t	*stxd;
-	} lgmnal_msghdr_t;
-#define LGMNAL_MSGHDR_SIZE	sizeof(lgmnal_msghdr_t)
-
-/* 
- *	There's one of these for each interface that is initialised
- *	There's a maximum of LGMNAL_NUM_IF lgmnal_data_t
- */
-
-typedef struct _lgmnal_data_t {
-	int	refcnt;
-#ifdef LGMNAL_API_LOCK_SPIN
-	spinlock_t	api_lock;	/* lock provided for api->lock function */
-#else
-	struct semaphore api_lock;
-#endif
-	spinlock_t	cb_lock;	/* lock provided for cb_cli function */
-	char		_cb_file[128];
-	char		_cb_function[128];
-	int		_cb_line;
-	spinlock_t 	stxd_lock;	/* lock to add or remove stxd to/from free list */
-	struct semaphore stxd_token;	/* Don't try to access the list until get a token */
-	lgmnal_stxd_t	*stxd;		/* list of free stxd's */
-#ifdef LGMNAL_USE_GM_HASH
-	struct gm_hash	*stxd_hash;	/* hash to translate txbuffer to stxd. Created in stxd_alloc */
-#else
-	lgmnal_hash_t	*stxd_hash;	/* hash to translate txbuffer to stxd. Created in stxd_alloc */
-#endif
-	spinlock_t 	srxd_lock;
-	struct semaphore srxd_token;
-	lgmnal_srxd_t	*srxd;
-#ifdef LGMNAL_USE_GM_HASH
-	struct gm_hash	*srxd_hash;
-#else
-	lgmnal_hash_t	*srxd_hash;
-#endif
-	nal_t		*nal;		/* our API NAL */
-	nal_cb_t	*nal_cb;	/* our CB nal */
-	struct gm_port	*gm_port;	/* the gm port structure we open in lgmnal_init */
-	unsigned int	gm_local_nid;	/* our gm local node id */
-	unsigned int	gm_global_nid;	/* our gm global node id */
-	spinlock_t 	gm_lock;	/* GM is not threadsage */
-	long		rxthread_pid;	/* thread id of our receiver thread */
-	int		rxthread_flag;	/* stop the thread flag	*/
-	gm_alarm_t	rxthread_alarm;	/* used to wake sleeping rx thread */
-	int		small_msg_size;
-	int		small_msg_gmsize;
-	char		_file[128];
-	char		_function[128];
-	int		_line;
-} lgmnal_data_t;
-
-/*
- *	For nal_data->rxthread_flag
- */
-#define LGMNAL_THREAD_START	444	
-#define LGMNAL_THREAD_STARTED	333
-#define LGMNAL_THREAD_CONTINUE	777
-#define LGMNAL_THREAD_STOP	666
-#define LGMNAL_THREAD_STOPPED	555
-
-#define LGMNAL_NUM_IF 	1
-
-#if 0
-/*
- *	A global structre to maintain 1 nal_data structure for each 
- *	myrinet card that the user initialises (only tested for 1)
- *	To add or remove any nal_data structures from the ifs arrary the 
- *	init_lock must be acquired. This is the only time this lock is acquired
- */
-typedef struct _lgmnal_global_t {
-	int 	debug_level;
-	struct	semaphore	init_lock;
-	lgmnal_data_t		*ifs[LGMNAL_NUM_IF];
-} lgmnal_global_t;
-
-extern lgmnal_data_t	global_nal_data;
-#define LGMNAL_DEBUG_LEVEL	lgmnal_global.debug_level
-#else
-extern lgmnal_data_t	*global_nal_data;
-extern int	lgmnal_debug_level;
-#define LGMNAL_DEBUG_LEVEL	lgmnal_debug_level
-#endif
-
-/*
- *	The gm_port to use for lgmnal
- */
-#define LGMNAL_GM_PORT	4
-
-/*
- * for ioctl get pid
- */
-#define LGMNAL_IOC_GET_GNID 1	
-
-/*
- *	LGMNAL_DEBUG_LEVEL set by module load 0<debug_level<4
- *	Increase it to get more debug info
- */	
-
-#define LGMNAL_DEBUG 1
-#ifdef LGMNAL_DEBUG
-#define LGMNAL_PRINT(level, args)	if (LGMNAL_DEBUG_LEVEL >= level) lgmnal_print args
-#else
-#define LGMNAL_PRINT(level, args)
-#endif
-
-#define LGMNAL_DEBUG_ERR 1	/* only report errors */
-#define LGMNAL_DEBUG_TRACE 2	/* on entering function */
-#define LGMNAL_DEBUG_V 3	/* debug */
-#define LGMNAL_DEBUG_VV 4	/* more debug */
-
-/*
- *	Return codes
- */
-#define LGMNAL_STATUS_OK	0
-#define LGMNAL_STATUS_FAIL	1
-#define LGMNAL_STATUS_NOMEM	2
-
-
-/*
- *	FUNCTION PROTOTYPES
- */
-
-/*
- *	Locking macros
- */
-
-/*
- *	To access the global structure
- *	to add or remove interface (lgmnal_init) or shutdown only
- */
-#define LGMNAL_GLOBAL_LOCK_INIT	sema_init(&(lgmnal_global.init_lock), 1)
-#define LGMNAL_GLOBAL_LOCK	do {	\
-				LGMNAL_PRINT(1, ("Acquiring global mutex\n")); \
-				down(&(lgmnal_global.init_lock)); \
-				LGMNAL_PRINT(1, ("Got global lock\n")); \
-				} while (0)
-#define LGMNAL_GLOBAL_UNLOCK	do {		\
-				LGMNAL_PRINT(1, ("Releasing global mutex\n")); \
-				up(&(lgmnal_global.init_lock)); \
-				LGMNAL_PRINT(1, ("Release global mutex\n")); \
-				} while (0)
-
-/*
- *	For the API lock function
- */
-#ifdef LGMNAL_API_LOCK_SPIN
-#define LGMNAL_API_LOCK_INIT(a)		spin_lock_init(&a->api_lock)
-#define LGMNAL_API_LOCK(a)		spin_lock(&a->api_lock)
-#define LGMNAL_API_UNLOCK(a)		spin_unlock(&a->api_lock)
-#else
-#define LGMNAL_API_LOCK_INIT(a)		sema_init(&a->api_lock, 1)
-#define LGMNAL_API_LOCK(a)		down(&a->api_lock)
-#define LGMNAL_API_UNLOCK(a)		up(&a->api_lock)
-#endif
-
-/*
- *	For the Small tx and rx descriptor lists
- */
-#define LGMNAL_TXD_LOCK_INIT(a)			spin_lock_init(&a->stxd_lock);
-#define LGMNAL_TXD_LOCK(a)			spin_lock(&a->stxd_lock);
-#define LGMNAL_TXD_UNLOCK(a)			spin_unlock(&a->stxd_lock);
-#define LGMNAL_TXD_TOKEN_INIT(a, n)		sema_init(&a->stxd_token, n);
-#define LGMNAL_TXD_GETTOKEN(a)			down(&a->stxd_token);
-#define LGMNAL_TXD_TRYGETTOKEN(a)		down_trylock(&a->stxd_token)
-#define LGMNAL_TXD_RETURNTOKEN(a)		up(&a->stxd_token);
-
-
-#define LGMNAL_RXD_LOCK_INIT(a)			spin_lock_init(&a->srxd_lock);
-#define LGMNAL_RXD_LOCK(a)			spin_lock(&a->srxd_lock);
-#define LGMNAL_RXD_UNLOCK(a)			spin_unlock(&a->srxd_lock);
-#define LGMNAL_RXD_TOKEN_INIT(a, n)		sema_init(&a->srxd_token, n);
-#define LGMNAL_RXD_GETTOKEN(a)			down(&a->srxd_token);
-#define LGMNAL_RXD_TRYGETTOKEN(a)		down_trylock(&a->srxd_token)
-#define LGMNAL_RXD_RETURNTOKEN(a)		up(&a->srxd_token);
-
-#define LGMNAL_GM_LOCK_INIT(a)			spin_lock_init(&a->gm_lock);
-#define LGMNAL_GM_LOCK(a)			do { \
-							while (!spin_trylock(&a->gm_lock)) { \
-								LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("waiting %s:%s:%d holder %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__, nal_data->_function, nal_data->_file, nal_data->_line)); \
-								lgmnal_yield(128); \
-							} \
-								LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Locked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
-								sprintf(nal_data->_function, "%s", __FUNCTION__); \
-								sprintf(nal_data->_file, "%s", __FILE__); \
-								nal_data->_line = __LINE__; \
-						} while (0)
-#define LGMNAL_GM_UNLOCK(a)			do { \
-							spin_unlock(&a->gm_lock); \
-							memset(nal_data->_function, 0, 128); \
-							memset(nal_data->_file, 0, 128); \
-							nal_data->_line = 0; \
-							LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Unlocked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
-						} while(0);
-
-#define LGMNAL_CB_LOCK_INIT(a)			spin_lock_init(&a->cb_lock);
-
-
-/*
- *	API NAL
- */
-int lgmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
-
-int lgmnal_api_shutdown(nal_t *, int);
-
-int lgmnal_api_validate(nal_t *, void *, size_t);
-
-void lgmnal_api_yield(nal_t *);
-
-void lgmnal_api_lock(nal_t *, unsigned long *);
-
-void lgmnal_api_unlock(nal_t *, unsigned long *);
-
-
-#define LGMNAL_INIT_NAL(a)	do { 	\
-				a->forward = lgmnal_api_forward; \
-				a->shutdown = lgmnal_api_shutdown; \
-				a->validate = NULL; \
-				a->yield = lgmnal_api_yield; \
-				a->lock = lgmnal_api_lock; \
-				a->unlock = lgmnal_api_unlock; \
-				a->timeout = NULL; \
-				a->refct = 1; \
-				a->nal_data = NULL; \
-				} while (0)
-
-
-/*
- *	CB NAL
- */
-
-int lgmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
-	int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
-
-int lgmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
-	int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
-
-int lgmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
-	unsigned int, struct iovec *, size_t, size_t);
-
-int lgmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
-	unsigned int, ptl_kiov_t *, size_t, size_t);
-
-int lgmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
-
-int lgmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
-
-int lgmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
-
-void *lgmnal_cb_malloc(nal_cb_t *, size_t);
-
-void lgmnal_cb_free(nal_cb_t *, void *, size_t);
-
-void lgmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
-
-int  lgmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
-
-void lgmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
-
-void lgmnal_cb_cli(nal_cb_t *, unsigned long *);
-
-void lgmnal_cb_sti(nal_cb_t *, unsigned long *);
-
-int lgmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
-
-nal_t *lgmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
-
-void  lgmnal_fini(void);
-
-
-
-#define LGMNAL_INIT_NAL_CB(a)	do {	\
-				a->cb_send = lgmnal_cb_send; \
-				a->cb_send_pages = lgmnal_cb_send_pages; \
-				a->cb_recv = lgmnal_cb_recv; \
-				a->cb_recv_pages = lgmnal_cb_recv_pages; \
-				a->cb_read = lgmnal_cb_read; \
-				a->cb_write = lgmnal_cb_write; \
-				a->cb_callback = lgmnal_cb_callback; \
-				a->cb_malloc = lgmnal_cb_malloc; \
-				a->cb_free = lgmnal_cb_free; \
-				a->cb_map = NULL; \
-				a->cb_unmap = NULL; \
-				a->cb_printf = lgmnal_cb_printf; \
-				a->cb_cli = lgmnal_cb_cli; \
-				a->cb_sti = lgmnal_cb_sti; \
-				a->cb_dist = lgmnal_cb_dist; \
-				a->nal_data = NULL; \
-				} while (0)
-
-/*
- *	lgmnal utilities
- */
-
-void lgmnal_print(const char *, ...);
-
-/*
- *	Small Transmit and Receive Descriptor Functions
- */
-int  lgmnal_alloc_stxd(lgmnal_data_t *);
-void lgmnal_free_stxd(lgmnal_data_t *);
-lgmnal_stxd_t* lgmnal_get_stxd(lgmnal_data_t *, int);
-void lgmnal_return_stxd(lgmnal_data_t *, lgmnal_stxd_t *);
-
-int  lgmnal_alloc_srxd(lgmnal_data_t *);
-void lgmnal_free_srxd(lgmnal_data_t *);
-lgmnal_srxd_t* lgmnal_get_srxd(lgmnal_data_t *, int);
-void lgmnal_return_srxd(lgmnal_data_t *, lgmnal_srxd_t *);
-
-/*
- *	general utility functions
- */
-lgmnal_srxd_t	*lgmnal_rxbuffer_to_srxd(lgmnal_data_t *, void*);
-lgmnal_stxd_t	*lgmnal_txbuffer_to_stxd(lgmnal_data_t *, void*);
-void	lgmnal_stop_rxthread(lgmnal_data_t *);
-void	lgmnal_small_tx_done(gm_port_t *, void *, gm_status_t);
-char	*lgmnal_gm_error(gm_status_t);
-char	*lgmnal_rxevent(gm_recv_event_t*);
-int	lgmnal_is_small_message(lgmnal_data_t*, int, struct iovec*, int);
-
-void *lgmnal_hash_find(lgmnal_hash_t *, void*);
-int lgmnal_hash_add(lgmnal_hash_t**, void*, void*);
-void lgmnal_hash_free(lgmnal_hash_t**);
-
-/*
- *	Communication functions
- */
-int lgmnal_receive_thread(void *);
-int
-lgmnal_small_transmit(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec*, int);
-
-int
-lgmnal_small_receive2(nal_cb_t *, void *, lib_msg_t *, unsigned int, struct iovec *, size_t, size_t);
-
-void lgmnal_yield(int);
-
-#endif /*__INCLUDE_LGMNAL_H__*/
diff --git a/lnet/klnds/lgmlnd/lgmnal_api.c b/lnet/klnds/lgmlnd/lgmnal_api.c
deleted file mode 100644
index 8322e834a603d8a05cb316ec3804e9a18384bdeb..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal_api.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	Implements the API NAL functions
- */
-
-#include "lgmnal.h"
-
-lgmnal_data_t	*global_nal_data = NULL;
-/*
- *	lgmnal_api_forward
- *	This function takes a pack block of arguments from the NAL API
- *	module and passes them to the NAL CB module. The CB module unpacks
- *	the args and calls the appropriate function indicated by index.
- *	Typically this function is used to pass args between kernel and use
- *	space.
- *	As lgmanl exists entirely in kernel, just pass the arg block directly to
- *	the NAL CB, buy passing the args to lib_dispatch
- *	Arguments are
- *	nal_t	nal 	Our nal
- *	int	index	the api function that initiated this call 
- *	void 	*args	packed block of function args
- *	size_t	arg_len	length of args block
- *	void 	*ret	A return value for the API NAL
- *	size_t	ret_len	Size of the return value
- *	
- */
-
-int
-lgmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
-		void *ret, size_t ret_len)
-{
-
-	nal_cb_t	*nal_cb = NULL;
-	lgmnal_data_t	*nal_data = NULL;
-
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_forward: nal [%p], index [%d], args [%p], arglen [%d], ret [%p], retlen [%d]\n", nal, index, args, arg_len, ret, ret_len));
-
-	if (!nal || !args || (index < 0) || (arg_len < 0)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
-#ifdef LGMNAL_DEBUG
-		if (!nal)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No nal specified\n"));
-		if (!args)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No args specified\n"));
-		if (index < 0)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Index is negative[%d]\n", index));
-		if (arg_len < 0)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("arg_len is negative [%d]\n", arg_len));
-#endif
-		return (PTL_FAIL);
-	}
-
-	if (ret && (ret_len <= 0)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
-#ifdef LGMNAL_DEBUG
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("ret_len is [%d]\n", ret_len));
-#endif
-		return (PTL_FAIL);
-	}
-
-
-	if (!nal->nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal, no nal data\n"));	
-		return (PTL_FAIL);
-	}
-	
-	nal_data = nal->nal_data;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_data is [%p]\n", nal_data));	
-
-	if (!nal_data->nal_cb) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal_data, no nal_cb\n"));	
-		return (PTL_FAIL);
-	}
-	
-	nal_cb = nal_data->nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_cb is [%p]\n", nal_cb));	
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward calling lib_dispatch\n"));
-	lib_dispatch(nal_cb, NULL, index, args, ret);
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward returns from lib_dispatch\n"));
-
-	return(PTL_OK);
-}
-
-
-/*
- *	lgmnal_api_shutdown
- *	Close down this interface and free any resources associated with it
- *	nal_t	nal	our nal to shutdown
- */
-int
-lgmnal_api_shutdown(nal_t *nal, int interface)
-{
-
-	lgmnal_data_t	*nal_data = nal->nal_data;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_shutdown: nal_data [%p]\n", nal_data));
-
-	/*
- 	 *	TO DO	lgmnal_api_shutdown what is to be done?
- 	 */
-
-	return(PTL_OK);
-}
-
-
-/*
- *	lgmnal_api_validate
- *	validate a user address for use in communications
- *	There's nothing to be done here
- */
-int
-lgmnal_api_validate(nal_t *nal, void *base, size_t extent)
-{
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_validate : nal [%p], base [%p], extent [%d]\n", nal, base, extent));
-
-	return(PTL_OK);
-}
-
-
-
-/*
- *	lgmnal_api_yield
- *	Give up the processor
- */
-void
-lgmnal_api_yield(nal_t *nal)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_yield : nal [%p]\n", nal));
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule();
-
-	return;
-}
-
-
-
-/*
- *	lgmnal_api_lock
- *	Take a threadsafe lock
- */
-void
-lgmnal_api_lock(nal_t *nal, unsigned long *flags)
-{
-
-	lgmnal_data_t	*nal_data;
-	nal_cb_t	*nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flagsa [%p] flags[%ul]\n", nal, flags, *flags));
-
-	nal_data = nal->nal_data;
-	nal_cb = nal_data->nal_cb;
-
-	nal_cb->cb_cli(nal_cb, flags);
-/*
-	LGMNAL_API_LOCK(nal_data);
-*/
-
-	return;
-}
-
-/*
- *	lgmnal_api_unlock
- *	Release a threadsafe lock
- */
-void
-lgmnal_api_unlock(nal_t *nal, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data;
-	nal_cb_t	*nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flags [%p]\n", nal, flags));
-
-	nal_data = nal->nal_data;
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal, no nal_data\n"));
-	}
-	nal_cb = nal_data->nal_cb;
-	if (!nal_cb) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal_data, no nal_cb\n"));
-	}
-
-	nal_cb->cb_sti(nal_cb, flags);
-/*
-	LGMNAL_API_UNLOCK(nal_data);
-*/
-
-	return;
-}
-
-
-nal_t *
-lgmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, ptl_pid_t rpid)
-{
-
-	nal_t		*nal = NULL;
-	nal_cb_t	*nal_cb = NULL;
-	lgmnal_data_t	*nal_data = NULL;
-	lgmnal_srxd_t	*srxd = NULL;
-	gm_status_t	gm_status;
-	unsigned int	local_nid = 0, global_nid = 0;
-	ptl_nid_t	portals_nid;
-	ptl_pid_t	portals_pid = 0;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_init : interface [%d], ptl_size [%d], ac_size[%d]\n",
-			interface, ptl_size, ac_size));
-
-	if ((interface < 0) || (interface > LGMNAL_NUM_IF) || (ptl_size <= 0) || (ac_size <= 0) ) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad args\n"));
-		return(NULL);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("parameters check out ok\n"));
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Acquired global lock\n"));
-
-
-	PORTAL_ALLOC(nal_data, sizeof(lgmnal_data_t));
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't get memory\n"));
-		return(NULL);
-	}	
-	memset(nal_data, 0, sizeof(lgmnal_data_t));
-	/*
- 	 *	set the small message buffer size 
-	 */
-	nal_data->refcnt = 1;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_data[%p]\n", nal_data));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("small_msg_size is [%d]\n", nal_data->small_msg_size));
-
-	PORTAL_ALLOC(nal, sizeof(nal_t));
-	if (!nal) {
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
-		return(NULL);
-	}
-	memset(nal, 0, sizeof(nal_t));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal[%p]\n", nal));
-
-	PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
-	if (!nal_cb) {
-		PORTAL_FREE(nal, sizeof(nal_t));
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
-		return(NULL);
-	}
-	memset(nal_cb, 0, sizeof(nal_cb_t));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_cb[%p]\n", nal_cb));
-
-	LGMNAL_INIT_NAL(nal);
-	LGMNAL_INIT_NAL_CB(nal_cb);
-	/*
-	 *	String them all together
-	 */
-	nal->nal_data = (void*)nal_data;
-	nal_cb->nal_data = (void*)nal_data;
-	nal_data->nal = nal;
-	nal_data->nal_cb = nal_cb;
-
-	LGMNAL_API_LOCK_INIT(nal_data);
-	LGMNAL_CB_LOCK_INIT(nal_data);
-	LGMNAL_GM_LOCK_INIT(nal_data);
-
-
-	/*
- 	 *	initialise the interface, 
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling gm_init\n"));
-	if (gm_init() != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("call to gm_init failed\n"));
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_open with interface [%d], port [%d], name [%s], version [%d]\n", interface, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION));
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_open(&nal_data->gm_port, 0, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION);
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open returned [%d]\n", gm_status));
-	if (gm_status == GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open succeeded port[%p]\n", nal_data->gm_port));
-	} else {
-		switch(gm_status) {
-		case(GM_INVALID_PARAMETER):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Invalid Parameter\n"));
-			break;
-		case(GM_BUSY):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. GM Busy\n"));
-			break;
-		case(GM_NO_SUCH_DEVICE):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. No such device\n"));
-			break;
-		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Incompatile lib and driver\n"));
-			break;
-		case(GM_OUT_OF_MEMORY):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Out of Memory\n"));
-			break;
-		default:
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Unknow error code [%d]\n", gm_status));
-			break;
-		}	
-		LGMNAL_GM_LOCK(nal_data);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-	
-	nal_data->small_msg_size = lgmnal_small_msg_size;
-	nal_data->small_msg_gmsize = gm_min_size_for_length(lgmnal_small_msg_size);
-
-	if (lgmnal_alloc_srxd(nal_data) != LGMNAL_STATUS_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small rx descriptors\n"));
-		lgmnal_free_stxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-
-	/*
- 	 *	Hang out a bunch of small receive buffers
-	 *	In fact hang them all out
-	 */
-	while((srxd = lgmnal_get_srxd(nal_data, 0))) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("giving [%p] to gm_provide_recvive_buffer\n", srxd->buffer));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
-									srxd->gmsize, GM_LOW_PRIORITY, 0);
-		LGMNAL_GM_UNLOCK(nal_data);
-	}
-	
-	/*
-	 *	Allocate pools of small tx buffers and descriptors
-	 */
-	if (lgmnal_alloc_stxd(nal_data) != LGMNAL_STATUS_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small tx descriptors\n"));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-	/*
- 	 *	Start the recieve thread
-	 *	Initialise the gm_alarm we will use to wake the thread is 
-	 *	it needs to be stopped
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Initializing receive thread alarm and flag\n"));
-	gm_initialize_alarm(&nal_data->rxthread_alarm);
-	nal_data->rxthread_flag = LGMNAL_THREAD_START;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Starting receive thread\n"));
-	nal_data->rxthread_pid = kernel_thread(lgmnal_receive_thread, (void*)nal_data, 0);
-	if (nal_data->rxthread_pid <= 0) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Receive thread failed to start\n"));
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	while (nal_data->rxthread_flag != LGMNAL_THREAD_STARTED) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1024);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Waiting for receive thread signs of life\n"));
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("receive thread seems to have started\n"));
-	nal_data->rxthread_flag = LGMNAL_THREAD_CONTINUE;
-
-
-
-	/*
-	 *	Initialise the portals library
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Getting node id\n"));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		lgmnal_stop_rxthread(nal_data);
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't determine node id\n"));
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	nal_data->gm_local_nid = local_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%u]\n", local_nid));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, &global_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to obtain global id\n"));
-		lgmnal_stop_rxthread(nal_data);
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node id is [%u][%x]\n", global_nid));
-	nal_data->gm_global_nid = global_nid;
-
-/*
-	pid = gm_getpid();
-*/
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_pid is [%u]\n", portals_pid));
-	portals_nid = (unsigned long)global_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_nid is [%lu]\n", portals_nid));
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_init\n"));
-	if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, ac_size) != PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lib_init failed\n"));
-		lgmnal_stop_rxthread(nal_data);
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-		
-	}
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_init finished\n"));
-	global_nal_data = nal->nal_data;
-	return(nal);
-}
-
-
-
-/*
- *	Called when module removed
- */
-void lgmnal_fini()
-{
-	lgmnal_data_t	*nal_data = global_nal_data;
-	nal_t		*nal = nal_data->nal;
-	nal_cb_t	*nal_cb = nal_data->nal_cb;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_fini\n"));
-
-	PtlNIFini(lgmnal_ni);
-	lib_fini(nal_cb);
-
-	lgmnal_stop_rxthread(nal_data);
-	lgmnal_free_stxd(nal_data);
-	lgmnal_free_srxd(nal_data);
-	LGMNAL_GM_LOCK(nal_data);
-	gm_close(nal_data->gm_port);
-	gm_finalize();
-	LGMNAL_GM_UNLOCK(nal_data);
-	PORTAL_FREE(nal, sizeof(nal_t));	
-	PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-	PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-}
-
-EXPORT_SYMBOL(lgmnal_init);
-EXPORT_SYMBOL(lgmnal_fini);
-EXPORT_SYMBOL(lgmnal_api_forward);
-EXPORT_SYMBOL(lgmnal_api_validate);
-EXPORT_SYMBOL(lgmnal_api_yield);
-EXPORT_SYMBOL(lgmnal_api_lock);
-EXPORT_SYMBOL(lgmnal_api_unlock);
-EXPORT_SYMBOL(lgmnal_api_shutdown);
diff --git a/lnet/klnds/lgmlnd/lgmnal_cb.c b/lnet/klnds/lgmlnd/lgmnal_cb.c
deleted file mode 100644
index dcd5446127e425f2595e0bb3b9086659a54f0af1..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal_cb.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- *	This file implements the nal cb functions
- */
-
-
-#include "lgmnal.h"
-
-int lgmnal_cb_recv(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int niov, struct iovec *iov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = (lgmnal_srxd_t*)private;
-	int		status = PTL_OK;
-	lgmnal_data_t	*nal_data = nal_cb->nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_recv nal_cb [%p],private[%p], cookie[%p], niov[%d], iov [%p], mlen[%d], rlen[%d]\n", nal_cb, private, cookie, niov, iov, mlen, rlen));
-
-	if (srxd->type == LGMNAL_SMALL_MESSAGE) {
-		if (!LGMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, mlen)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_cb_recv. This is not a small message\n"));
-		}
-		status = lgmnal_small_receive2(nal_cb, private, cookie, niov, iov, mlen, rlen);
-	}
-		
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_return status [%d]\n", status));
-	return(status);
-}
-
-int lgmnal_cb_recv_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int kniov, ptl_kiov_t *kiov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = (lgmnal_srxd_t*)private;
-	int		status = PTL_OK;
-	struct iovec	*iovec = NULL;
-	int		i = 0;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_recv_pages nal_cb [%p],private[%p], cookie[%p], kniov[%d], kiov [%p], mlen[%d], rlen[%d]\n", nal_cb, private, cookie, kniov, kiov, mlen, rlen));
-
-	if (srxd->type == LGMNAL_SMALL_MESSAGE) {
-		PORTAL_ALLOC(iovec, sizeof(struct iovec)*kniov);
-		if (!iovec) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Can't malloc\n"));
-			return(LGMNAL_STATUS_FAIL);
-		}
-
-		/*
-		 *	map each page and create an iovec for it
-		 */
-		for (i=0; i<kniov; i++) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing kniov [%d] [%p]\n", i, kiov));
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kniov page [%p] len [%d] offset[%d]\n", kiov->kiov_page, kiov->kiov_len, kiov->kiov_offset));
-			iovec->iov_len = kiov->kiov_len;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling kmap", kiov->kiov_page));
-			iovec->iov_base = kmap(kiov->kiov_page) + kiov->kiov_offset;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling iov_base is [%p]", iovec->iov_base));
-			iovec->iov_len = kiov->kiov_len;
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("calling lgmnal_small_receive2\n"));
-		status = lgmnal_small_receive2(nal_cb, private, cookie, kniov, iovec, mlen, rlen);
-		PORTAL_FREE(iovec, sizeof(struct iovec)*kniov);
-	}
-		
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_return status [%d]\n", status));
-	return(status);
-}
-
-
-int lgmnal_cb_send(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr,
-	int type, ptl_nid_t nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, size_t len)
-{
-
-	lgmnal_data_t	*nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_sendnid [%lu] niov[%d] len[%d]\n", nid, niov, len));
-	nal_data = nal_cb->nal_data;
-	
-	if (LGMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, len)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is a small message send\n"));
-		lgmnal_small_transmit(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("This is a large message send it is not supported yet\n"));
-/*
-		lgmnal_large_transmit1(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-*/
-		return(LGMNAL_STATUS_FAIL);
-	}
-	return(PTL_OK);
-}
-
-int lgmnal_cb_send_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr,
-	int type, ptl_nid_t nid, ptl_pid_t pid, unsigned int kniov, ptl_kiov_t *kiov, size_t len)
-{
-
-	int	i = 0;
-	lgmnal_data_t	*nal_data;
-	struct	iovec 	*iovec;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_send_pages nid [%lu] niov[%d] len[%d]\n", nid, kniov, len));
-	nal_data = nal_cb->nal_data;
-	if (LGMNAL_IS_SMALL_MESSAGE(nal_data, 0, NULL, len)) {
-		/* TO DO fix small message for send pages */
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is a small message send\n"));
-		PORTAL_ALLOC(iovec, kniov*sizeof(struct iovec));
-		
-		for (i=0; i<kniov; i++) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing kniov [%d] [%p]\n", i, kiov));
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kniov page [%p] len [%d] offset[%d]\n", kiov->kiov_page, kiov->kiov_len, kiov->kiov_offset));
-			iovec->iov_len = kiov->kiov_len;
-			iovec->iov_base = kmap(kiov->kiov_page) + kiov->kiov_offset;
-			iovec->iov_len = kiov->kiov_len;
-		}
-		lgmnal_small_transmit(nal_cb, private, cookie, hdr, type, nid, pid, kniov, iovec, len);
-		PORTAL_FREE(iovec, kniov*sizeof(struct iovec));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("This is a large message send it is not supported yet\n"));
-/*
-		lgmnal_large_transmit1(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-*/
-		return(LGMNAL_STATUS_FAIL);
-	}
-	return(PTL_OK);
-}
-
-int lgmnal_cb_read(nal_cb_t *nal_cb, void *private, void *dst, user_ptr src, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_read dst [%p] src [%p] len[%d]\n", dst, src, len));
-	gm_bcopy(src, dst, len);
-	return(PTL_OK);
-}
-
-int lgmnal_cb_write(nal_cb_t *nal_cb, void *private, user_ptr dst, void *src, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_write :: dst [%p] src [%p] len[%d]\n", dst, src, len));
-	gm_bcopy(src, dst, len);
-	return(PTL_OK);
-}
-
-int lgmnal_cb_callback(nal_cb_t *nal_cb, void *private, lib_eq_t *eq, ptl_event_t *ev)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_callback nal_cb[%p], private[%p], eq[%p], ev[%p]\n", nal_cb, private, eq, ev));
-
-	if (eq->event_callback != NULL) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("found callback\n"));
-		eq->event_callback(ev);
-	}
-	
-	return(PTL_OK);
-}
-
-void *lgmnal_cb_malloc(nal_cb_t *nal_cb, size_t len)
-{
-	void *ptr = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_malloc len[%d]\n", len));
-	PORTAL_ALLOC(ptr, len);
-	return(ptr);
-}
-
-void lgmnal_cb_free(nal_cb_t *nal_cb, void *buf, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_free :: buf[%p] len[%d]\n", buf, len));
-	PORTAL_FREE(buf, len);
-	return;
-}
-
-void lgmnal_cb_unmap(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, void **addrkey)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_unmap niov[%d] iov[%], addrkey[%p]\n", niov, iov, addrkey));
-	return;
-}
-
-int  lgmnal_cb_map(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, void**addrkey)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_map niov[%d], iov[%p], addrkey[%p], niov, iov, addrkey\n"));
-	return(PTL_OK);
-}
-
-void lgmnal_cb_printf(nal_cb_t *nal_cb, const char *fmt, ...)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_printf\n"));
-	lgmnal_print(fmt);
-	return;
-}
-
-void lgmnal_cb_cli(nal_cb_t *nal_cb, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	spinlock_t	cb_lock = nal_data->cb_lock;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_cli\n"));
-/*
-	local_irq_save(*flags);
-	spin_lock_irqsave(&cb_lock, *flags);
-*/
-	spin_lock(&cb_lock);
-	return;
-}
-
-void lgmnal_cb_sti(nal_cb_t *nal_cb, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	spinlock_t	cb_lock = nal_data->cb_lock;
-
-/*
-	local_irq_restore(*flags);
-	spin_unlock_irqrestore(&cb_lock, *flags);
-*/
-	spin_unlock(&cb_lock);
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_sti\n"));
-	return;
-}
-
-int lgmnal_cb_dist(nal_cb_t *nal_cb, ptl_nid_t nid, unsigned long *dist)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_dist\n"));
-	if (dist)
-		*dist = 27;
-	return(PTL_OK);
-}
-
-
-
-
-EXPORT_SYMBOL(lgmnal_cb_send);
-EXPORT_SYMBOL(lgmnal_cb_send_pages);
-EXPORT_SYMBOL(lgmnal_cb_recv);
-EXPORT_SYMBOL(lgmnal_cb_recv_pages);
-EXPORT_SYMBOL(lgmnal_cb_read);
-EXPORT_SYMBOL(lgmnal_cb_write);
-EXPORT_SYMBOL(lgmnal_cb_cli);
-EXPORT_SYMBOL(lgmnal_cb_sti);
-EXPORT_SYMBOL(lgmnal_cb_dist);
-EXPORT_SYMBOL(lgmnal_cb_printf);
-EXPORT_SYMBOL(lgmnal_cb_map);
-EXPORT_SYMBOL(lgmnal_cb_unmap);
-EXPORT_SYMBOL(lgmnal_cb_callback);
-EXPORT_SYMBOL(lgmnal_cb_free);
-EXPORT_SYMBOL(lgmnal_cb_malloc);
diff --git a/lnet/klnds/lgmlnd/lgmnal_comm.c b/lnet/klnds/lgmlnd/lgmnal_comm.c
deleted file mode 100644
index 4cd1b8384dcdfb21d59b52951fb38e7f2574711f..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal_comm.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-/*
- *	This file contains all lgmnal send and receive functions
- */
-
-#include "lgmnal.h"
-
-int
-lgmnal_requeue_rxbuffer(lgmnal_data_t *nal_data, lgmnal_srxd_t *srxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_requeue_rxbuffer\n"));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("requeueing srxd[%p] nal_data[%p]\n", srxd, nal_data));
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer,
-					srxd->gmsize, GM_LOW_PRIORITY, 0 );
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-/*
- *	Handle a bad message
- *	A bad message is one we don't expect or can't interpret
- */
-int
-lgmnal_badrx_message(lgmnal_data_t *nal_data, gm_recv_t *recv, lgmnal_srxd_t *srxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Can't handle message\n"));
-
-	if (!srxd)
-		srxd = lgmnal_rxbuffer_to_srxd(nal_data, gm_ntohp(recv->buffer));
-	if (srxd) {
-		lgmnal_requeue_rxbuffer(nal_data, srxd);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Can't find a descriptor for this buffer\n"));
-		/*
-		 *	get rid of it ?
-		 */
-		return(LGMNAL_STATUS_FAIL);
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-/*
- *	Start processing a small message receive
- *	Get here from lgmnal_receive_thread
- *	Hand off to lib_parse, which calls cb_recv
- *	which hands back to lgmnal_small_receive2
- *	Deal with all endian stuff here (if we can!)
- */
-int
-lgmnal_small_receive1(lgmnal_data_t *nal_data, gm_recv_t *recv)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	void		*buffer = NULL;
-	unsigned int snode, sport, type, length;
-	lgmnal_msghdr_t	*lgmnal_msghdr;
-	ptl_hdr_t	*portals_hdr;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_receive1 nal_data [%p], recv [%p]\n", nal_data, recv));
-
-	buffer = gm_ntohp(recv->buffer);;
-	snode = (int)gm_ntoh_u16(recv->sender_node_id);
-	sport = (int)gm_ntoh_u8(recv->sender_port_id);
-	type = (int)gm_ntoh_u8(recv->type);
-	buffer = gm_ntohp(recv->buffer);
-	length = (int) gm_ntohl(recv->length);
-
-	lgmnal_msghdr = (lgmnal_msghdr_t*)buffer;
-	portals_hdr = (ptl_hdr_t*)(buffer+LGMNAL_MSGHDR_SIZE);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("rx_event:: Sender node [%d], Sender Port [%d], type [%d], length [%d], buffer [%p]\n",
-				snode, sport, type, length, buffer));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_msghdr:: Sender node [%u], magic [%lx], type [%d]\n",
-				lgmnal_msghdr->sender_node_id, lgmnal_msghdr->magic, lgmnal_msghdr->type));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_hdr:: Sender node [%ul], dest_node [%ul]\n",
-				portals_hdr->src_nid, portals_hdr->dest_nid));
-
-
-	/*
- 	 *	Get a transmit descriptor for this message
-	 */
-	srxd = lgmnal_rxbuffer_to_srxd(nal_data, buffer);
-	LGMNAL_PRINT(LGMNAL_DEBUG, ("Back from lgmnal_rxbuffer_to_srxd\n"));
-	if (!srxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG, ("Failed to get receive descriptor for this buffer\n"));
-		lib_parse(nal_data->nal_cb, portals_hdr, srxd);
-		return(LGMNAL_STATUS_FAIL);
-	}
-	srxd->type = LGMNAL_SMALL_MESSAGE;
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling lib_parse buffer is [%p]\n", buffer+LGMNAL_MSGHDR_SIZE));
-	/*
- 	 *	control passes to lib, which calls cb_recv 
-	 *	cb_recv is responsible for returning the buffer 
-	 *	for future receive
-	 */
-	lib_parse(nal_data->nal_cb, portals_hdr, srxd);
-
-	return(LGMNAL_STATUS_OK);
-}
-
-/*
- *	Get here from lgmnal_receive_thread, lgmnal_small_receive1
- *	lib_parse, cb_recv
- *	Put data from prewired receive buffer into users buffer(s)
- *	Hang out the receive buffer again for another receive
- *	Call lib_finalize
- */
-int
-lgmnal_small_receive2(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int niov, 
-							struct iovec *iov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	void	*buffer = NULL;
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_receive2 niov [%d] mlen[%d]\n", niov, mlen));
-
-	if (!private) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_small_receive2 no context\n"));
-		lib_finalize(nal_cb, private, cookie);
-		return(PTL_FAIL);
-	}
-
-	srxd = (lgmnal_srxd_t*)private;
-	buffer = srxd->buffer;
-	buffer += sizeof(lgmnal_msghdr_t);
-	buffer += sizeof(ptl_hdr_t);
-
-	while(niov--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing [%p] len [%d]\n", iov, iov->iov_len));
-		gm_bcopy(buffer, iov->iov_base, iov->iov_len);			
-		buffer += iov->iov_len;
-		iov++;
-	}
-
-
-	/*
- 	 *	let portals library know receive is complete
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_finalize\n"));
-	if (lib_finalize(nal_cb, private, cookie) != PTL_OK) {
-		/* TO DO what to do with failed lib_finalise? */
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lib_finalize failed\n"));
-	}
-	/*
-	 *	return buffer so it can be used again
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling gm_provide_receive_buffer\n"));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, srxd->gmsize, GM_LOW_PRIORITY, 0);	
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	return(PTL_OK);
-}
-
-
-
-/*
- *	The recevive thread
- *	This guy wait in gm_blocking_recvive and gets
- *	woken up when the myrinet adaptor gets an interrupt.
- *	Hands off processing of small messages and blocks again
- */
-int
-lgmnal_receive_thread(void *arg)
-{
-	lgmnal_data_t		*nal_data;
-	gm_recv_event_t		*rxevent = NULL;
-	gm_recv_t		*recv = NULL;
-	void			*buffer;
-
-	if (!arg) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("RXTHREAD:: This is the lgmnal_receive_thread. NO nal_data. Exiting\n", arg));
-		return(-1);
-	}
-
-	nal_data = (lgmnal_data_t*)arg;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("RXTHREAD:: This is the lgmnal_receive_thread nal_data is [%p]\n", arg));
-
-	nal_data->rxthread_flag = LGMNAL_THREAD_STARTED;
-	while (nal_data->rxthread_flag == LGMNAL_THREAD_STARTED) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: lgmnal_receive_threads waiting for LGMNAL_CONTINUE flag\n"));
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1024);
-		
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: calling daemonize\n"));
-	daemonize();
-	LGMNAL_GM_LOCK(nal_data);
-	while(nal_data->rxthread_flag == LGMNAL_THREAD_CONTINUE) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Receive thread waiting\n"));
-		rxevent = gm_blocking_receive_no_spin(nal_data->gm_port);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: receive thread got [%s]\n", lgmnal_rxevent(rxevent)));
-		if (nal_data->rxthread_flag != LGMNAL_THREAD_CONTINUE) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Receive thread time to exit\n"));
-			break;
-		}
-		switch (GM_RECV_EVENT_TYPE(rxevent)) {
-
-			case(GM_RECV_EVENT):
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: GM_RECV_EVENT\n"));
-				recv = (gm_recv_t*)&(rxevent->recv);
-				buffer = gm_ntohp(recv->buffer);
-				if (((lgmnal_msghdr_t*)buffer)->type == LGMNAL_SMALL_MESSAGE) {
-					LGMNAL_GM_UNLOCK(nal_data);
-					lgmnal_small_receive1(nal_data, recv);
-					LGMNAL_GM_LOCK(nal_data);
-				} else {
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("RXTHREAD:: Unsupported message type\n"));
-					lgmnal_badrx_message(nal_data, recv, NULL);
-				}
-			break;
-			case(_GM_SLEEP_EVENT):
-				/*
-				 *	Blocking receive above just returns
-				 *	immediatly with _GM_SLEEP_EVENT
-				 *	Don't know what this is
-				 */
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Sleeping in gm_unknown\n"));
-				LGMNAL_GM_UNLOCK(nal_data);
-				gm_unknown(nal_data->gm_port, rxevent);
-				LGMNAL_GM_LOCK(nal_data);
-				LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Awake from gm_unknown\n"));
-				break;
-				
-			default:
-				/*
-				 *	Don't know what this is
-				 *	gm_unknown will make sense of it
-				 */
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Passing event to gm_unknown\n"));
-				gm_unknown(nal_data->gm_port, rxevent);
-				LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Processed unknown event\n"));
-				
-		}
-
-		
-	}
-	LGMNAL_GM_UNLOCK(nal_data);
-	nal_data->rxthread_flag = LGMNAL_THREAD_STOPPED;
-	LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("RXTHREAD:: The lgmnal_receive_thread nal_data [%p] is exiting\n", nal_data));
-	return(LGMNAL_STATUS_OK);
-}
-
-
-int
-lgmnal_small_transmit(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr, int type,
-	ptl_nid_t global_nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, int size)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	lgmnal_stxd_t	*stxd = NULL;
-	void		*buffer = NULL;
-	lgmnal_msghdr_t	*msghdr = NULL;
-	int		tot_size = 0;
-	unsigned int	local_nid;
-	gm_status_t	gm_status = GM_SUCCESS;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_transmit nal_cb [%p] private [%p] cookie [%p] hdr [%p] type [%d] global_nid [%u][%x] pid [%d] niov [%d] iov [%p] size [%d]\n", nal_cb, private, cookie, hdr, type, global_nid, global_nid, pid, niov, iov, size));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_hdr:: dest_nid [%lu], src_nid [%lu]\n", hdr->dest_nid, hdr->src_nid));
-
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("no nal_data\n"));
-		return(LGMNAL_STATUS_FAIL);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("nal_data [%p]\n", nal_data));
-	}
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, &local_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to obtain local id\n"));
-		return(LGMNAL_STATUS_FAIL);
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local Node_id is [%u][%x]\n", local_nid, local_nid));
-
-	stxd = lgmnal_get_stxd(nal_data, 1);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("stxd [%p]\n", stxd));
-
-	stxd->type = LGMNAL_SMALL_MESSAGE;
-	stxd->cookie = cookie;
-
-	/*
-	 *	Copy lgmnal_msg_hdr and portals header to the transmit buffer
-	 *	Then copy the data in
-	 */
-	buffer = stxd->buffer;
-	msghdr = (lgmnal_msghdr_t*)buffer;
-
-	msghdr->magic = LGMNAL_MAGIC;
-	msghdr->type = LGMNAL_SMALL_MESSAGE;
-	msghdr->sender_node_id = nal_data->gm_global_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing msghdr at [%p]\n", buffer));
-
-	buffer += sizeof(lgmnal_msghdr_t);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Advancing buffer pointer by [%x] to [%p]\n", sizeof(lgmnal_msghdr_t), buffer));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing  portals hdr at [%p]\n", buffer));
-	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
-
-	buffer += sizeof(ptl_hdr_t);
-
-	while(niov--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing iov [%p] len [%d] to [%p]\n", iov, iov->iov_len, buffer));
-		gm_bcopy(iov->iov_base, buffer, iov->iov_len);
-		buffer+= iov->iov_len;
-		iov++;
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("sending\n"));
-	tot_size = size+sizeof(ptl_hdr_t)+sizeof(lgmnal_msghdr_t);
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_send_to_peer port [%p] buffer [%p] gmsize [%d] msize [%d] global_nid [%u][%x] local_nid[%d] stxd [%p]\n",
-			nal_data->gm_port, stxd->buffer, stxd->gmsize, tot_size, global_nid, global_nid, local_nid, stxd));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, stxd->gmsize, tot_size, GM_LOW_PRIORITY, local_nid, lgmnal_small_tx_done, (void*)stxd);
-	
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("done\n"));
-		
-	return(PTL_OK);
-}
-
-
-void 
-lgmnal_small_tx_done(gm_port_t *gm_port, void *context, gm_status_t status)
-{
-	lgmnal_stxd_t	*stxd = (lgmnal_stxd_t*)context;
-	lib_msg_t	*cookie = stxd->cookie;
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)stxd->nal_data;
-	nal_cb_t	*nal_cb = nal_data->nal_cb;
-
-	if (!stxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("send completion event for unknown stxd\n"));
-		return;
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Result of send stxd [%p] is [%s]\n", stxd, lgmnal_gm_error(status)));
-	/* TO DO figure out which sends are worth retrying and get a send token to retry */
-	if (lib_finalize(nal_cb, stxd, cookie) != PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Call to lib_finalize failed for stxd [%p]\n", stxd));
-	}
-	lgmnal_return_stxd(nal_data, stxd);
-	return;
-}
-
-
-void 
-lgmnal_large_tx1_done(gm_port_t *gm_port, void *context, gm_status_t status)
-{
-
-}
-
-/*
- *	Begin a large transmit
- */
-int
-lgmnal_large_transmit1(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr, int type,
-	ptl_nid_t global_nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, int size)
-{
-
-	lgmnal_data_t	*nal_data;
-	lgmnal_stxd_t	*stxd = NULL;
-	void		*buffer = NULL;
-	lgmnal_msghdr_t	*msghdr = NULL;
-	unsigned int	local_nid;
-	int		mlen = 0;	/* the size of the init message data */
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_large_transmit1 nal_cb [%p] private [%p], cookie [%p] hdr [%p], type [%d] global_nid [%u], pid [%d], 
-					niov [%d], iov [%p], size [%d]\n",
-					nal_cb, private, cookie, hdr, type, global_nid, pid, niov, iov, size));
-
-	if (nal_cb)
-		nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	else  {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("no nal_cb.\n"));
-		return(LGMNAL_STATUS_FAIL);
-	}
-	
-
-	/*
-	 *	TO DO large transmit uses stxd. Should it have control descriptor?
-	 */
-	stxd = lgmnal_get_stxd(nal_data, 1);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("stxd [%p]\n", stxd));
-
-	stxd->type = LGMNAL_LARGE_MESSAGE_INIT;
-	stxd->cookie = cookie;
-
-	/*
-	 *	Copy lgmnal_msg_hdr and portals header to the transmit buffer
-	 *	Then copy the iov in
-	 */
-	buffer = stxd->buffer;
-	msghdr = (lgmnal_msghdr_t*)buffer;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing msghdr at [%p]\n", buffer));
-
-	msghdr->magic = LGMNAL_MAGIC;
-	msghdr->type = LGMNAL_LARGE_MESSAGE_INIT;
-	msghdr->sender_node_id = nal_data->gm_global_nid;
-	msghdr->stxd = stxd;
-	buffer += sizeof(lgmnal_msghdr_t);
-	mlen = sizeof(lgmnal_msghdr_t);
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing  portals hdr at [%p]\n", buffer));
-
-	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
-	buffer += sizeof(ptl_hdr_t);
-	mlen += sizeof(ptl_hdr_t); 
-
-	/*
-	 *	Store the iovs in the stxd for we can get them later
-	 *	in large_transmit2
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Copying iov [%p] to [%p]\n", iov, stxd->iov));
-	gm_bcopy(iov, stxd->iov, niov*sizeof(struct iovec));
-	stxd->niov = niov;
-	
-	/*
- 	 *	Send the init message to the target
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("sending mlen [%d]\n", mlen));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, stxd->gmsize, mlen, GM_LOW_PRIORITY, local_nid, lgmnal_large_tx1_done, (void*)stxd);
-	LGMNAL_GM_UNLOCK(nal_data);
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("done\n"));
-		
-	return(PTL_OK);
-}
-
-
-
-
-EXPORT_SYMBOL(lgmnal_requeue_rxbuffer);
-EXPORT_SYMBOL(lgmnal_badrx_message);
-EXPORT_SYMBOL(lgmnal_large_tx1_done);
-EXPORT_SYMBOL(lgmnal_large_transmit1);
-EXPORT_SYMBOL(lgmnal_small_receive1);
-EXPORT_SYMBOL(lgmnal_small_receive2);
-EXPORT_SYMBOL(lgmnal_receive_thread);
-EXPORT_SYMBOL(lgmnal_small_transmit);
-EXPORT_SYMBOL(lgmnal_small_tx_done);
diff --git a/lnet/klnds/lgmlnd/lgmnal_module.c b/lnet/klnds/lgmlnd/lgmnal_module.c
deleted file mode 100644
index ce870f05c5d5f21fe47160b4d2c2f40a19a00291..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal_module.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include "lgmnal.h"
-
-
-ptl_handle_ni_t	lgmnal_ni;
-
-
-int 
-lgmnal_cmd(struct portal_ioctl_data *data, void *private)
-{
-	lgmnal_data_t	*nal_data = NULL;
-	char		*name = NULL;
-	int		nid = -2;
-	int		gnid;
-	gm_status_t	gm_status;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cmd [d] private [%p]\n", data->ioc_nal_cmd, private));
-	nal_data = (lgmnal_data_t*)private;
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("nal_data is [%p]\n", nal_data));
-	switch(data->ioc_nal_cmd) {
-	/*
-	 * just reuse already defined GET_NID. Should define LGMNAL version
-	 */
-	case(LGMNAL_IOC_GET_GNID):
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_cmd GETNID (Get GM Global Network Id\n"));
-
-		PORTAL_ALLOC(name, data->ioc_plen1);
-		copy_from_user(name, data->ioc_pbuf1, data->ioc_plen1);
-	
-		LGMNAL_GM_LOCK(nal_data);
-		nid = gm_host_name_to_node_id(nal_data->gm_port, name);
-		LGMNAL_GM_UNLOCK(nal_data);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%d]\n", nid));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_node_id_to_global_id(nal_data->gm_port, nid, &gnid);
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_node_id_to_global_id failed\n", gm_status));
-			return(-1);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node is is [%u][%x]\n", gnid, gnid));
-		copy_to_user(data->ioc_pbuf2, &gnid, data->ioc_plen2);
-	break;
-	default:
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_cmd UNKNOWN[%d]\n", data->ioc_nal_cmd));
-		data->ioc_nid2 = -1;
-	}
-
-
-	return(0);
-}
-
-int lgmnal_small_msg_size = 81920;
-int lgmnal_debug_level = 1;
-
-int
-init_module()
-{
-	int	status;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("This is the lgmnal module initialisation routine\n"));
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling lgmnal_init\n"));
-	status = PtlNIInit(lgmnal_init, 32, 4, 0, &lgmnal_ni);
-	if (status == PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Portals LGMNAL initialised ok lgmnal_ni [%lx]\n", lgmnal_ni));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Portals LGMNAL Failed to initialise\n"));
-		return(1);
-		
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling kportal_nal_register\n"));
-	/*
- 	 *	global_nal_data is set by lgmnal_init
-	 */
-	if (kportal_nal_register(LGMNAL, &lgmnal_cmd, global_nal_data) != 0) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kportal_nal_register failed\n"));
-		return(1);
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling PORTAL_SYMBOL_REGISTER\n"));
-	PORTAL_SYMBOL_REGISTER(lgmnal_ni);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is the end of the lgmnal module initialisation routine"));
-
-
-	return(0);
-}
-
-
-void cleanup_module()
-{
-	int interface=0;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Cleaning up lgmnal module"));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Interface [%d] Calling shutdown\n", interface));
-	kportal_nal_unregister(LGMNAL);
-	PORTAL_SYMBOL_UNREGISTER(lgmnal_ni);
-	lgmnal_fini();
-	global_nal_data = NULL;
-	return;
-}
-
-
-EXPORT_SYMBOL(lgmnal_ni);
-EXPORT_SYMBOL(lgmnal_debug_level);
-
-MODULE_PARM(lgmnal_small_msg_size, "i");
-MODULE_PARM(lgmnal_debug_level, "i");
-
-MODULE_AUTHOR("Morgan Doyle. morgan.doyle@hp.com");
-
-MODULE_DESCRIPTION("A Portals kernel NAL for Myrinet GM2. [0<lgmnal_debug_level<4]");
-
-MODULE_LICENSE("GPL");
diff --git a/lnet/klnds/lgmlnd/lgmnal_utils.c b/lnet/klnds/lgmlnd/lgmnal_utils.c
deleted file mode 100644
index 8a91ca45a7c7983a95f54ca680ba3c209d0e23f7..0000000000000000000000000000000000000000
--- a/lnet/klnds/lgmlnd/lgmnal_utils.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	All utilities required by lgmanl
- */
-
-#include "lgmnal.h"
-
-/*
- *	print a console message
- *	the header of each messages specifies
- *	the function, file and line number of the caller
- */
-
-/*
- *	TO DO	lgmnal_print find how to determine the caller function
- */
-
-#define DEFAULT_LEN	64
-void lgmnal_print(const char *fmt, ...)
-{
-	va_list	ap;
-	char	*varbuf = NULL, fixedbuf[DEFAULT_LEN];
-	int	len = 0;
-
-
-	va_start(ap, fmt);
-	sprintf(fixedbuf, "LGMNAL::");
-	len = vsnprintf(fixedbuf+8, DEFAULT_LEN-8, fmt, ap);
-	if ((len+8) >= DEFAULT_LEN) {
-		PORTAL_ALLOC(varbuf, len+1+8);
-		if (!varbuf) {
-			printk("lgmnal_cb_printf Failed to malloc\n");
-			printk("Truncated message is\n");
-			printk(fixedbuf);
-			va_end(ap);
-			return;
-		}
-		sprintf(varbuf, "LGMNAL::");
-		len = vsnprintf(varbuf+8, len+1, fmt, ap);
-	} else {
-		varbuf = fixedbuf;
-	}
-	va_end(ap);
-	printk(varbuf);
-	if (fixedbuf != varbuf)
-		PORTAL_FREE(varbuf, len+1+8);
-	return;
-}
-	
-
-/*
- *	allocate a number of small tx buffers and register with GM
- *	so they are wired and set up for DMA. This is a costly operation.
- *	Also allocate a corrosponding descriptor to keep track of 
- *	the buffer.
- *	Put all descriptors on singly linked list to be available to send function.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the txd spinlock.
- */
-int
-lgmnal_alloc_stxd(lgmnal_data_t *nal_data)
-{
-	int ntx = 0, nstx = 0, i = 0;
-	lgmnal_stxd_t	*txd = NULL;
-	void	*txbuffer = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_alloc_small tx\n"));
-
-	LGMNAL_GM_LOCK(nal_data);
-	ntx = gm_num_send_tokens(nal_data->gm_port);
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("total number of send tokens available is [%d]\n", ntx));
-	
-	nstx = ntx/2;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocated [%d] send tokens to small messages\n", nstx));
-
-
-#ifdef LGMNAL_USE_GM_HASH
-	nal_data->stxd_hash = gm_create_hash(gm_hash_compare_ptrs, gm_hash_hash_ptr, 0, sizeof(void*), nstx, 0);
-	if (!nal_data->srxd_hash) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to create hash table\n\n"));
-			return(LGMNAL_STATUS_NOMEM);
-	}
-#else
-	nal_data->stxd_hash = NULL;
-#endif
-
-	/*
-	 * A semaphore is initialised with the 
-	 * number of transmit tokens available.
-	 * To get a stxd, acquire the token semaphore.
- 	 * this decrements the available token count
-	 * (if no tokens you block here, someone returning a 
-	 * stxd will release the semaphore and wake you)
-	 * When token is obtained acquire the spinlock 
-	 * to manipulate the list
-	 */
-	LGMNAL_TXD_TOKEN_INIT(nal_data, nstx);
-	LGMNAL_TXD_LOCK_INIT(nal_data);
-	
-	for (i=0; i<=nstx; i++) {
-		PORTAL_ALLOC(txd, sizeof(lgmnal_stxd_t));
-		if (!txd) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc txd [%d]\n", i));
-			return(LGMNAL_STATUS_NOMEM);
-		}
-#if 0
-		PORTAL_ALLOC(txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		if (!txbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc txbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(txd, sizeof(lgmnal_stxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_register_memory with port [%p] txbuffer [%p], size [%d]\n",
-				nal_data->gm_port, txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_register_memory(nal_data->gm_port, txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_register_memory failed buffer [%p], index [%d]\n", txbuffer, i));
-			switch(gm_status) {
-				case(GM_FAILURE):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_FAILURE\n"));
-				break;
-				case(GM_PERMISSION_DENIED):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_PERMISSION_DENIED\n"));
-				break;
-				case(GM_INVALID_PARAMETER):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_INVALID_PARAMETER\n"));
-				break;
-				default:
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Unknown error\n"));
-				break;
-			}
-			return(LGMNAL_STATUS_FAIL);
-		} else {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_register_memory ok for buffer [%p], index [%d]\n", txbuffer, i));
-		}
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		txbuffer = gm_dma_malloc(nal_data->gm_port, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (!txbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to gm_dma_malloc txbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(txd, sizeof(lgmnal_stxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-#endif
-		
-		txd->buffer = txbuffer;
-		txd->size = LGMNAL_SMALL_MSG_SIZE(nal_data);
-		txd->gmsize = gm_min_size_for_length(txd->size);
-		txd->nal_data = (struct _lgmnal_data_t*)nal_data;
-
-		if (lgmnal_hash_add(&nal_data->stxd_hash, (void*)txbuffer, (void*)txd)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to create hash entry\n"));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		
-
-		txd->next = nal_data->stxd;
-		nal_data->stxd = txd;
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Registered txd [%p] with buffer [%p], size [%d]\n", txd, txd->buffer, txd->size));
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-/*	Free the list of wired and gm_registered small tx buffers and the tx descriptors
-  	that go along with them.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the txd spinlock.
- */
-void
-lgmnal_free_stxd(lgmnal_data_t *nal_data)
-{
-	lgmnal_stxd_t *txd = nal_data->stxd, *_txd = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_free_small tx\n"));
-
-	while(txd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Freeing txd [%p] with buffer [%p], size [%d]\n", txd, txd->buffer, txd->size));
-		_txd = txd;
-		txd = txd->next;
-#if 0
-		LGMNAL_GM_LOCK(nal_data);
-		gm_deregister_memory(nal_data->gm_port, _txd->buffer, _txd->size);
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(_txd->buffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		gm_dma_free(nal_data->gm_port, _txd->buffer);
-		LGMNAL_GM_UNLOCK(nal_data);
-#endif
-		PORTAL_FREE(_txd, sizeof(lgmnal_stxd_t));
-	}
-	return;
-}
-
-
-/*
- *	Get a txd from the list
- *	This get us a wired and gm_registered small tx buffer.
- *	This implicitly gets us a send token also.
- */
-lgmnal_stxd_t *
-lgmnal_get_stxd(lgmnal_data_t *nal_data, int block)
-{
-
-	lgmnal_stxd_t	*txd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_get_stxd nal_data [%p] block[%d]\n", 
-						nal_data, block));
-
-	if (block) {
-		LGMNAL_TXD_GETTOKEN(nal_data);
-	} else {
-		if (LGMNAL_TXD_TRYGETTOKEN(nal_data)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_get_stxd can't get token\n"));
-			return(NULL);
-		}
-	}
-	LGMNAL_TXD_LOCK(nal_data);
-	txd = nal_data->stxd;
-	if (txd)
-		nal_data->stxd = txd->next;
-	LGMNAL_TXD_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_get_stxd got [%p], head is [%p]\n", txd, nal_data->stxd));
-	return(txd);
-}
-
-/*
- *	Return a txd to the list
- */
-void
-lgmnal_return_stxd(lgmnal_data_t *nal_data, lgmnal_stxd_t *txd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_return_stxd nal_data [%p], txd[%p]\n", nal_data, txd));
-
-	LGMNAL_TXD_LOCK(nal_data);
-	txd->next = nal_data->stxd;
-	nal_data->stxd = txd;
-	LGMNAL_TXD_UNLOCK(nal_data);
-	LGMNAL_TXD_RETURNTOKEN(nal_data);
-	return;
-}
-
-
-/*
- *	allocate a number of small rx buffers and register with GM
- *	so they are wired and set up for DMA. This is a costly operation.
- *	Also allocate a corrosponding descriptor to keep track of 
- *	the buffer.
- *	Put all descriptors on singly linked list to be available to receive thread.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the rxd spinlock.
- */
-int
-lgmnal_alloc_srxd(lgmnal_data_t *nal_data)
-{
-	int nrx = 0, nsrx = 0, i = 0;
-	lgmnal_srxd_t	*rxd = NULL;
-	void	*rxbuffer = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_alloc_small rx\n"));
-
-	LGMNAL_GM_LOCK(nal_data);
-	nrx = gm_num_receive_tokens(nal_data->gm_port);
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("total number of receive tokens available is [%d]\n", nrx));
-	
-	nsrx = nrx/2;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocated [%d] receive tokens to small messages\n", nsrx));
-
-
-#ifdef LGMNAL_USE_GM_HASH
-	LGMNAL_GM_LOCK(nal_data);
-	nal_data->srxd_hash = gm_create_hash(gm_hash_compare_ptrs, gm_hash_hash_ptr, 0, sizeof(void*), nsrx, 0);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (!nal_data->srxd_hash) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to create hash table\n"));
-			return(LGMNAL_STATUS_NOMEM);
-	}
-#else
-	nal_data->srxd_hash = NULL;
-#endif
-
-	LGMNAL_RXD_TOKEN_INIT(nal_data, nsrx);
-	LGMNAL_RXD_LOCK_INIT(nal_data);
-
-	for (i=0; i<=nsrx; i++) {
-		PORTAL_ALLOC(rxd, sizeof(lgmnal_srxd_t));
-		if (!rxd) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc rxd [%d]\n", i));
-			return(LGMNAL_STATUS_NOMEM);
-		}
-#if 0
-		PORTAL_ALLOC(rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		if (!rxbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc rxbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(rxd, sizeof(lgmnal_srxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_register_memory with port [%p] rxbuffer [%p], size [%d]\n",
-				nal_data->gm_port, rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_register_memory(nal_data->gm_port, rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_register_memory failed buffer [%p], index [%d]\n", rxbuffer, i));
-			switch(gm_status) {
-				case(GM_FAILURE):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_FAILURE\n"));
-				break;
-				case(GM_PERMISSION_DENIED):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_PERMISSION_DENIED\n"));
-				break;
-				case(GM_INVALID_PARAMETER):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_INVALID_PARAMETER\n"));
-				break;
-				default:
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Unknown GM error[%d]\n", gm_status));
-				break;
-				
-			}
-			return(LGMNAL_STATUS_FAIL);
-		}
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		rxbuffer = gm_dma_malloc(nal_data->gm_port, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (!rxbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to gm_dma_malloc rxbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(rxd, sizeof(lgmnal_srxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-#endif
-		
-		rxd->buffer = rxbuffer;
-		rxd->size = LGMNAL_SMALL_MSG_SIZE(nal_data);
-		rxd->gmsize = gm_min_size_for_length(rxd->size);
-
-		if (lgmnal_hash_add(&nal_data->srxd_hash, (void*)rxbuffer, (void*)rxd) != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to create hash entry rxd[%p] for rxbuffer[%p]\n", rxd, rxbuffer));
-			return(LGMNAL_STATUS_FAIL);
-		}
-
-		rxd->next = nal_data->srxd;
-		nal_data->srxd = rxd;
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Registered rxd [%p] with buffer [%p], size [%d]\n", rxd, rxd->buffer, rxd->size));
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-
-/*	Free the list of wired and gm_registered small rx buffers and the rx descriptors
- *	that go along with them.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the rxd spinlock.
- */
-void
-lgmnal_free_srxd(lgmnal_data_t *nal_data)
-{
-	lgmnal_srxd_t *rxd = nal_data->srxd, *_rxd = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_free_small rx\n"));
-
-	while(rxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Freeing rxd [%p] with buffer [%p], size [%d]\n", rxd, rxd->buffer, rxd->size));
-		_rxd = rxd;
-		rxd = rxd->next;
-
-#if 0
-		LGMNAL_GM_LOCK(nal_data);
-		gm_deregister_memory(nal_data->gm_port, _rxd->buffer, _rxd->size);
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(_rxd->buffer, LGMNAL_SMALL_RXBUFFER_SIZE);
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		gm_dma_free(nal_data->gm_port, _rxd->buffer);
-		LGMNAL_GM_UNLOCK(nal_data);
-#endif
-		PORTAL_FREE(_rxd, sizeof(lgmnal_srxd_t));
-	}
-	return;
-}
-
-
-/*
- *	Get a rxd from the free list
- *	This get us a wired and gm_registered small rx buffer.
- *	This implicitly gets us a receive token also.
- */
-lgmnal_srxd_t *
-lgmnal_get_srxd(lgmnal_data_t *nal_data, int block)
-{
-
-	lgmnal_srxd_t	*rxd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_get_srxd nal_data [%p] block [%d]\n", nal_data, block));
-
-	if (block) {
-		LGMNAL_RXD_GETTOKEN(nal_data);
-	} else {
-		if (LGMNAL_RXD_TRYGETTOKEN(nal_data)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_get_srxd Can't get token\n"));
-			return(NULL);
-		}
-	}
-	LGMNAL_RXD_LOCK(nal_data);
-	rxd = nal_data->srxd;
-	if (rxd)
-		nal_data->srxd = rxd->next;
-	LGMNAL_RXD_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_get_srxd got [%p], head is [%p]\n", rxd, nal_data->srxd));
-	return(rxd);
-}
-
-/*
- *	Return an rxd to the list
- */
-void
-lgmnal_return_srxd(lgmnal_data_t *nal_data, lgmnal_srxd_t *rxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_return_srxd nal_data [%p], rxd[%p]\n", nal_data, rxd));
-
-	LGMNAL_RXD_LOCK(nal_data);
-	rxd->next = nal_data->srxd;
-	nal_data->srxd = rxd;
-	LGMNAL_RXD_UNLOCK(nal_data);
-	LGMNAL_RXD_RETURNTOKEN(nal_data);
-	return;
-}
-
-/*
- *	Given a pointer to a srxd find 
- *	the relevant descriptor for it
- *	This is done by searching a hash
- *	list that is created when the srxd's 
- *	are created
- */
-lgmnal_srxd_t *
-lgmnal_rxbuffer_to_srxd(lgmnal_data_t *nal_data, void *rxbuffer)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_rxbuffer_to_srxd nal_data [%p], rxbuffer [%p]\n", nal_data, rxbuffer));
-#ifdef LGMNAL_USE_GM_HASH
-	srxd = gm_hash_find(nal_data->srxd_hash, rxbuffer);
-#else
-	srxd = lgmnal_hash_find(nal_data->srxd_hash, rxbuffer);
-#endif
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("srxd is [%p]\n", srxd));
-	return(srxd);
-}
-
-
-void
-lgmnal_stop_rxthread(lgmnal_data_t *nal_data)
-{
-	int 	delay = 15;
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Attempting to stop rxthread nal_data [%p]\n", nal_data));
-	
-	if (nal_data->rxthread_flag != LGMNAL_THREAD_CONTINUE) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("thread flag not correctly set\n"));
-	}	
-
-	nal_data->rxthread_flag = LGMNAL_THREAD_STOP;
-	LGMNAL_GM_LOCK(nal_data);
-	gm_set_alarm(nal_data->gm_port, &nal_data->rxthread_alarm, 10, NULL, NULL);
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	while(nal_data->rxthread_flag == LGMNAL_THREAD_STOP && delay--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_stop_rxthread sleeping\n"));
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1024);
-	}
-
-	if (nal_data->rxthread_flag == LGMNAL_THREAD_STOP) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("I DON'T KNOW HOW TO WAKE THE THREAD\n"));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RX THREAD SEEMS TO HAVE STOPPED\n"));
-	}
-
-}
-
-
-
-char * 
-lgmnal_gm_error(gm_status_t status)
-{
-	switch(status) {
-		case(GM_SUCCESS):
-			return("SUCCESS");
-  		case(GM_FAILURE):
-			return("FAILURE");
-  		case(GM_INPUT_BUFFER_TOO_SMALL):
-			return("INPUT_BUFFER_TOO_SMALL");
-  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
-			return("OUTPUT_BUFFER_TOO_SMALL");
-  		case(GM_TRY_AGAIN ):
-			return("TRY_AGAIN");
-  		case(GM_BUSY):
-			return("BUSY");
-  		case(GM_MEMORY_FAULT):
-			return("MEMORY_FAULT");
-  		case(GM_INTERRUPTED):
-			return("INTERRUPTED");
-  		case(GM_INVALID_PARAMETER):
-			return("INVALID_PARAMETER");
-  		case(GM_OUT_OF_MEMORY):
-			return("OUT_OF_MEMORY");
-  		case(GM_INVALID_COMMAND):
-			return("INVALID_COMMAND");
-  		case(GM_PERMISSION_DENIED):
-			return("PERMISSION_DENIED");
-  		case(GM_INTERNAL_ERROR):
-			return("INTERNAL_ERROR");
-  		case(GM_UNATTACHED):
-			return("UNATTACHED");
-  		case(GM_UNSUPPORTED_DEVICE):
-			return("UNSUPPORTED_DEVICE");
-  		case(GM_SEND_TIMED_OUT):
-			return("GM_SEND_TIMEDOUT");
-  		case(GM_SEND_REJECTED):
-			return("GM_SEND_REJECTED");
-  		case(GM_SEND_TARGET_PORT_CLOSED):
-			return("GM_SEND_TARGET_PORT_CLOSED");
-  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
-			return("GM_SEND_TARGET_NODE_UNREACHABLE");
-  		case(GM_SEND_DROPPED):
-			return("GM_SEND_DROPPED");
-  		case(GM_SEND_PORT_CLOSED):
-			return("GM_SEND_PORT_CLOSED");
-  		case(GM_NODE_ID_NOT_YET_SET):
-			return("GM_NODE_ID_NOT_YET_SET");
-  		case(GM_STILL_SHUTTING_DOWN):
-			return("GM_STILL_SHUTTING_DOWN");
-  		case(GM_CLONE_BUSY):
-			return("GM_CLONE_BUSY");
-  		case(GM_NO_SUCH_DEVICE):
-			return("GM_NO_SUCH_DEVICE");
-  		case(GM_ABORTED):
-			return("GM_ABORTED");
-  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
-			return("GM_INCOMPATIBLE_LIB_AND_DRIVER");
-  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
-			return("GM_UNTRANSLATED_SYSTEM_ERROR");
-  		case(GM_ACCESS_DENIED):
-			return("GM_ACCESS_DENIED");
-
-
-/*
- *	These ones are in the docs but aren't in the header file 
-  		case(GM_DEV_NOT_FOUND):
-			return("GM_DEV_NOT_FOUND");
-  		case(GM_INVALID_PORT_NUMBER):
-			return("GM_INVALID_PORT_NUMBER");
-  		case(GM_UC_ERROR):
-			return("GM_US_ERROR");
-  		case(GM_PAGE_TABLE_FULL):
-			return("GM_PAGE_TABLE_FULL");
-  		case(GM_MINOR_OVERFLOW):
-			return("GM_MINOR_OVERFLOW");
-  		case(GM_SEND_ORPHANED):
-			return("GM_SEND_ORPHANED");
-  		case(GM_HARDWARE_FAULT):
-			return("GM_HARDWARE_FAULT");
-  		case(GM_DATA_CORRUPTED):
-			return("GM_DATA_CORRUPTED");
-  		case(GM_TIMED_OUT):
-			return("GM_TIMED_OUT");
-  		case(GM_USER_ERROR):
-			return("GM_USER_ERROR");
-  		case(GM_NO_MATCH):
-			return("GM_NOMATCH");
-  		case(GM_NOT_SUPPORTED_IN_KERNEL):
-			return("GM_NOT_SUPPORTED_IN_KERNEL");
-  		case(GM_NOT_SUPPORTED_ON_ARCH):
-			return("GM_NOT_SUPPORTED_ON_ARCH");
-  		case(GM_PTE_REF_CNT_OVERFLOW):
-			return("GM_PTR_REF_CNT_OVERFLOW");
-  		case(GM_NO_DRIVER_SUPPORT):
-			return("GM_NO_DRIVER_SUPPORT");
-  		case(GM_FIRMWARE_NOT_RUNNING):
-			return("GM_FIRMWARE_NOT_RUNNING");
-
- *	These ones are in the docs but aren't in the header file 
- */
-		default:
-			return("UNKNOWN GM ERROR CODE");
-	}
-}
-
-
-char *
-lgmnal_rxevent(gm_recv_event_t	*ev)
-{
-	short	event;
-	char	msg[24];
-	event = GM_RECV_EVENT_TYPE(ev);
-	switch(event) {
-  		case(GM_NO_RECV_EVENT):
-			return("GM_NO_RECV_EVENT");
-  		case(GM_SENDS_FAILED_EVENT):
-			return("GM_SEND_FAILED_EVENT");
-  		case(GM_ALARM_EVENT):
-			return("GM_ALARM_EVENT");
-  		case(GM_SENT_EVENT):
-			return("GM_SENT_EVENT");
-  		case(_GM_SLEEP_EVENT):
-			return("_GM_SLEEP_EVENT");
-  		case(GM_RAW_RECV_EVENT):
-			return("GM_RAW_RECV_EVENT");
-  		case(GM_BAD_SEND_DETECTED_EVENT):
-			return("GM_BAD_SEND_DETECTED_EVENT");
-  		case(GM_SEND_TOKEN_VIOLATION_EVENT):
-			return("GM_SEND_TOKEN_VIOLATION_EVENT");
-  		case(GM_RECV_TOKEN_VIOLATION_EVENT):
-			return("GM_RECV_TOKEN_VIOLATION_EVENT");
-  		case(GM_BAD_RECV_TOKEN_EVENT):
-			return("GM_BAD_RECV_TOKEN_EVENT");
-  		case(GM_ALARM_VIOLATION_EVENT):
-			return("GM_ALARM_VIOLATION_EVENT");
-  		case(GM_RECV_EVENT):
-			return("GM_RECV_EVENT");
-  		case(GM_HIGH_RECV_EVENT):
-			return("GM_HIGH_RECV_EVENT");
-  		case(GM_PEER_RECV_EVENT):
-			return("GM_PEER_RECV_EVENT");
-  		case(GM_HIGH_PEER_RECV_EVENT):
-			return("GM_HIGH_PEER_RECV_EVENT");
-  		case(GM_FAST_RECV_EVENT):
-			return("GM_FAST_RECV_EVENT");
-  		case(GM_FAST_HIGH_RECV_EVENT):
-			return("GM_FAST_HIGH_RECV_EVENT");
-  		case(GM_FAST_PEER_RECV_EVENT):
-			return("GM_FAST_PEER_RECV_EVENT");
-  		case(GM_FAST_HIGH_PEER_RECV_EVENT):
-			return("GM_FAST_HIGH_PEER_RECV_EVENT");
-  		case(GM_REJECTED_SEND_EVENT):
-			return("GM_REJECTED_SEND_EVENT");
-  		case(GM_ORPHANED_SEND_EVENT):
-			return("GM_ORPHANED_SEND_EVENT");
-  		case(GM_BAD_RESEND_DETECTED_EVENT):
-			return("GM_BAD_RESEND_DETETED_EVENT");
-  		case(GM_DROPPED_SEND_EVENT):
-			return("GM_DROPPED_SEND_EVENT");
-  		case(GM_BAD_SEND_VMA_EVENT):
-			return("GM_BAD_SEND_VMA_EVENT");
-  		case(GM_BAD_RECV_VMA_EVENT):
-			return("GM_BAD_RECV_VMA_EVENT");
-  		case(_GM_FLUSHED_ALARM_EVENT):
-			return("GM_FLUSHED_ALARM_EVENT");
-  		case(GM_SENT_TOKENS_EVENT):
-			return("GM_SENT_TOKENS_EVENTS");
-  		case(GM_IGNORE_RECV_EVENT):
-			return("GM_IGNORE_RECV_EVENT");
-  		case(GM_ETHERNET_RECV_EVENT):
-			return("GM_ETHERNET_RECV_EVENT");
-  		case(GM_NEW_NO_RECV_EVENT):
-			return("GM_NEW_NO_RECV_EVENT");
-  		case(GM_NEW_SENDS_FAILED_EVENT):
-			return("GM_NEW_SENDS_FAILED_EVENT");
-  		case(GM_NEW_ALARM_EVENT):
-			return("GM_NEW_ALARM_EVENT");
-  		case(GM_NEW_SENT_EVENT):
-			return("GM_NEW_SENT_EVENT");
-  		case(_GM_NEW_SLEEP_EVENT):
-			return("GM_NEW_SLEEP_EVENT");
-  		case(GM_NEW_RAW_RECV_EVENT):
-			return("GM_NEW_RAW_RECV_EVENT");
-  		case(GM_NEW_BAD_SEND_DETECTED_EVENT):
-			return("GM_NEW_BAD_SEND_DETECTED_EVENT");
-  		case(GM_NEW_SEND_TOKEN_VIOLATION_EVENT):
-			return("GM_NEW_SEND_TOKEN_VIOLATION_EVENT");
-  		case(GM_NEW_RECV_TOKEN_VIOLATION_EVENT):
-			return("GM_NEW_RECV_TOKEN_VIOLATION_EVENT");
-  		case(GM_NEW_BAD_RECV_TOKEN_EVENT):
-			return("GM_NEW_BAD_RECV_TOKEN_EVENT");
-  		case(GM_NEW_ALARM_VIOLATION_EVENT):
-			return("GM_NEW_ALARM_VIOLATION_EVENT");
-  		case(GM_NEW_RECV_EVENT):
-			return("GM_NEW_RECV_EVENT");
-  		case(GM_NEW_HIGH_RECV_EVENT):
-			return("GM_NEW_HIGH_RECV_EVENT");
-  		case(GM_NEW_PEER_RECV_EVENT):
-			return("GM_NEW_PEER_RECV_EVENT");
-  		case(GM_NEW_HIGH_PEER_RECV_EVENT):
-			return("GM_NEW_HIGH_PEER_RECV_EVENT");
-  		case(GM_NEW_FAST_RECV_EVENT):
-			return("GM_NEW_FAST_RECV_EVENT");
-  		case(GM_NEW_FAST_HIGH_RECV_EVENT):
-			return("GM_NEW_FAST_HIGH_RECV_EVENT");
-  		case(GM_NEW_FAST_PEER_RECV_EVENT):
-			return("GM_NEW_FAST_PEER_RECV_EVENT");
-  		case(GM_NEW_FAST_HIGH_PEER_RECV_EVENT):
-			return("GM_NEW_FAST_HIGH_PEER_RECV_EVENT");
-  		case(GM_NEW_REJECTED_SEND_EVENT):
-			return("GM_NEW_REJECTED_SEND_EVENT");
-  		case(GM_NEW_ORPHANED_SEND_EVENT):
-			return("GM_NEW_ORPHANED_SEND_EVENT");
-  		case(_GM_NEW_PUT_NOTIFICATION_EVENT):
-			return("_GM_NEW_PUT_NOTIFICATION_EVENT");
-  		case(GM_NEW_FREE_SEND_TOKEN_EVENT):
-			return("GM_NEW_FREE_SEND_TOKEN_EVENT");
-  		case(GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT):
-			return("GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT");
-  		case(GM_NEW_BAD_RESEND_DETECTED_EVENT):
-			return("GM_NEW_BAD_RESEND_DETECTED_EVENT");
-  		case(GM_NEW_DROPPED_SEND_EVENT):
-			return("GM_NEW_DROPPED_SEND_EVENT");
-  		case(GM_NEW_BAD_SEND_VMA_EVENT):
-			return("GM_NEW_BAD_SEND_VMA_EVENT");
-  		case(GM_NEW_BAD_RECV_VMA_EVENT):
-			return("GM_NEW_BAD_RECV_VMA_EVENT");
-  		case(_GM_NEW_FLUSHED_ALARM_EVENT):
-			return("GM_NEW_FLUSHED_ALARM_EVENT");
-  		case(GM_NEW_SENT_TOKENS_EVENT):
-			return("GM_NEW_SENT_TOKENS_EVENT");
-  		case(GM_NEW_IGNORE_RECV_EVENT):
-			return("GM_NEW_IGNORE_RECV_EVENT");
-  		case(GM_NEW_ETHERNET_RECV_EVENT):
-			return("GM_NEW_ETHERNET_RECV_EVENT");
-		default:
-			snprintf(msg, 24,  "Unknown Recv event [%d]", event);
-			return(msg);
-#if 0
-  		case(/* _GM_PUT_NOTIFICATION_EVENT */
-  		case(/* GM_FREE_SEND_TOKEN_EVENT */
-  		case(/* GM_FREE_HIGH_SEND_TOKEN_EVENT */
-#endif
-	}
-}
-
-
-void
-lgmnal_yield(int delay)
-{
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(delay);
-}
-
-int
-lgmnal_is_small_message(lgmnal_data_t *nal_data, int niov, struct iovec *iov, int len)
-{
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_is_small_message len is [%d]\n", len));
-	if (len < LGMNAL_SMALL_MSG_SIZE(nal_data)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Yep, small message]\n"));
-		return(1);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No, not small message]\n"));
-		return(0);
-	}
-}
-
-void *
-lgmnal_hash_find(lgmnal_hash_t *hash, void *key)
-{
-	void 	*data = NULL;
-	int	count = 0;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_find hash [%p] key [%p]\n", hash, key));
-
-	while (hash) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find Stepping [%d]\n", count++));
-		if (hash->key == key) {
-			data = hash->data;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find hash got data[%p]\n", data));
-			return(data);
-		} else
-			hash = hash->next;
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find data not found\n"));
-	return(NULL);
-}
-
-/* 
- *	TO DO hash. figure out why getting bad stuff from gm_hash and thne use it.
- */
-
-int
-lgmnal_hash_add(lgmnal_hash_t **hash, void *key, void *data)
-{
-	
-#ifdef LGMNAL_USE_GM_HASH
-	return(gm_hash_insert(*hash, (void*)key, (void*)data);
-#else
-	lgmnal_hash_t	*new = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_add hash [%p]\n", *hash));
-	PORTAL_ALLOC(new, sizeof(lgmnal_hash_t));
-	memset(new, 0, sizeof(lgmnal_hash_t));
-	if (!new) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_hash_add :: can't get memory\n"));
-		return(-1);
-	}
-	new->data = data;
-	new->key = key;
-	new->next = *hash;
-	*hash = new;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_add hash head [%p]\n", *hash));
-	return(0);
-#endif
-}
-
-void
-lgmnal_hash_free(lgmnal_hash_t **hash)
-{
-	
-	lgmnal_hash_t	*_hash = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_free hash [p%]\n", *hash));
-	
-	while (*hash) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_free freeing hash [p%]\n", _hash));
-		_hash = *hash;
-		*hash = _hash->next;
-		PORTAL_FREE(_hash, sizeof(lgmnal_hash_t));
-	}
-	return;
-}
-
-
-EXPORT_SYMBOL(lgmnal_yield);
-EXPORT_SYMBOL(lgmnal_print);
-EXPORT_SYMBOL(lgmnal_alloc_srxd);
-EXPORT_SYMBOL(lgmnal_get_srxd);
-EXPORT_SYMBOL(lgmnal_return_srxd);
-EXPORT_SYMBOL(lgmnal_free_srxd);
-EXPORT_SYMBOL(lgmnal_alloc_stxd);
-EXPORT_SYMBOL(lgmnal_get_stxd);
-EXPORT_SYMBOL(lgmnal_return_stxd);
-EXPORT_SYMBOL(lgmnal_free_stxd);
-EXPORT_SYMBOL(lgmnal_rxbuffer_to_srxd);
-EXPORT_SYMBOL(lgmnal_rxevent);
-EXPORT_SYMBOL(lgmnal_gm_error);
-EXPORT_SYMBOL(lgmnal_stop_rxthread);
diff --git a/lnet/klnds/qswlnd/qswlnd.c b/lnet/klnds/qswlnd/qswlnd.c
index 0841d641dc3134709c69e280a35b9feb46f74913..70b45c0a61dadac04402f2adcbccd2b2c8a77a30 100644
--- a/lnet/klnds/qswlnd/qswlnd.c
+++ b/lnet/klnds/qswlnd/qswlnd.c
@@ -113,12 +113,12 @@ kqswnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size,
 }
 
 int
-kqswnal_get_tx_desc (struct portal_ioctl_data *data)
+kqswnal_get_tx_desc (struct portals_cfg *pcfg)
 {
 	unsigned long      flags;
 	struct list_head  *tmp;
 	kqswnal_tx_t      *ktx;
-	int                index = data->ioc_count;
+	int                index = pcfg->pcfg_count;
 	int                rc = -ENOENT;
 
 	spin_lock_irqsave (&kqswnal_data.kqn_idletxd_lock, flags);
@@ -126,19 +126,18 @@ kqswnal_get_tx_desc (struct portal_ioctl_data *data)
 	list_for_each (tmp, &kqswnal_data.kqn_activetxds) {
 		if (index-- != 0)
 			continue;
-		
-		ktx = list_entry (tmp, kqswnal_tx_t, ktx_list);
 
-		data->ioc_pbuf1 = (char *)ktx;
-		data->ioc_count = NTOH__u32(ktx->ktx_wire_hdr->type);
-		data->ioc_size  = NTOH__u32(PTL_HDR_LENGTH(ktx->ktx_wire_hdr));
-		data->ioc_nid   = NTOH__u64(ktx->ktx_wire_hdr->dest_nid);
-		data->ioc_nid2  = ktx->ktx_nid;
-		data->ioc_misc  = ktx->ktx_launcher;
-		data->ioc_flags = (list_empty (&ktx->ktx_delayed_list) ? 0 : 1) |
-				  ((!ktx->ktx_forwarding)              ? 0 : 2) |
-				  ((!ktx->ktx_isnblk)                  ? 0 : 4);
+		ktx = list_entry (tmp, kqswnal_tx_t, ktx_list);
 
+		pcfg->pcfg_pbuf1 = (char *)ktx;
+		pcfg->pcfg_count = NTOH__u32(ktx->ktx_wire_hdr->type);
+		pcfg->pcfg_size  = NTOH__u32(ktx->ktx_wire_hdr->payload_length);
+		pcfg->pcfg_nid   = NTOH__u64(ktx->ktx_wire_hdr->dest_nid);
+		pcfg->pcfg_nid2  = ktx->ktx_nid;
+		pcfg->pcfg_misc  = ktx->ktx_launcher;
+		pcfg->pcfg_flags = (list_empty (&ktx->ktx_delayed_list) ? 0 : 1) |
+				  (!ktx->ktx_isnblk                    ? 0 : 2) |
+				  (ktx->ktx_state << 2);
 		rc = 0;
 		break;
 	}
@@ -148,21 +147,21 @@ kqswnal_get_tx_desc (struct portal_ioctl_data *data)
 }
 
 int
-kqswnal_cmd (struct portal_ioctl_data *data, void *private)
+kqswnal_cmd (struct portals_cfg *pcfg, void *private)
 {
-	LASSERT (data != NULL);
+	LASSERT (pcfg != NULL);
 	
-	switch (data->ioc_nal_cmd) {
+	switch (pcfg->pcfg_command) {
 	case NAL_CMD_GET_TXDESC:
-		return (kqswnal_get_tx_desc (data));
+		return (kqswnal_get_tx_desc (pcfg));
 
 	case NAL_CMD_REGISTER_MYNID:
 		CDEBUG (D_IOCTL, "setting NID offset to "LPX64" (was "LPX64")\n",
-			data->ioc_nid - kqswnal_data.kqn_elanid,
+			pcfg->pcfg_nid - kqswnal_data.kqn_elanid,
 			kqswnal_data.kqn_nid_offset);
 		kqswnal_data.kqn_nid_offset =
-			data->ioc_nid - kqswnal_data.kqn_elanid;
-		kqswnal_lib.ni.nid = data->ioc_nid;
+			pcfg->pcfg_nid - kqswnal_data.kqn_elanid;
+		kqswnal_lib.ni.nid = pcfg->pcfg_nid;
 		return (0);
 		
 	default:
@@ -180,6 +179,7 @@ kqswnal_finalise (void)
 
 	case KQN_INIT_ALL:
 		PORTAL_SYMBOL_UNREGISTER (kqswnal_ni);
+                kportal_nal_unregister(QSWNAL);
 		/* fall through */
 
 	case KQN_INIT_PTL:
@@ -188,6 +188,7 @@ kqswnal_finalise (void)
 		/* fall through */
 
 	case KQN_INIT_DATA:
+		LASSERT(list_empty(&kqswnal_data.kqn_activetxds));
 		break;
 
 	case KQN_INIT_NOTHING:
@@ -323,7 +324,7 @@ kqswnal_finalise (void)
 
 	CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read(&portal_kmemory));
 
-	printk (KERN_INFO "Routing QSW NAL unloaded (final mem %d)\n",
+	printk (KERN_INFO "Lustre: Routing QSW NAL unloaded (final mem %d)\n",
                 atomic_read(&portal_kmemory));
 }
 
@@ -423,12 +424,14 @@ kqswnal_initialise (void)
 	}
 
 	/**********************************************************************/
-	/* Reserve Elan address space for transmit buffers */
+	/* Reserve Elan address space for transmit descriptors NB we may
+	 * either send the contents of associated buffers immediately, or
+	 * map them for the peer to suck/blow... */
 
         dmareq.Waitfn   = DDI_DMA_SLEEP;
         dmareq.ElanAddr = (E3_Addr) 0;
         dmareq.Attr     = PTE_LOAD_LITTLE_ENDIAN;
-        dmareq.Perm     = ELAN_PERM_REMOTEREAD;
+        dmareq.Perm     = ELAN_PERM_REMOTEWRITE;
 
 	rc = elan3_dma_reserve(kqswnal_data.kqn_epdev->DmaState,
 			      KQSW_NTXMSGPAGES*(KQSW_NTXMSGS+KQSW_NNBLK_TXMSGS),
@@ -500,6 +503,7 @@ kqswnal_initialise (void)
 
 		INIT_LIST_HEAD (&ktx->ktx_delayed_list);
 
+		ktx->ktx_state = KTX_IDLE;
 		ktx->ktx_isnblk = (i >= KQSW_NTXMSGS);
 		list_add_tail (&ktx->ktx_list, 
 			       ktx->ktx_isnblk ? &kqswnal_data.kqn_nblk_idletxds :
@@ -592,7 +596,7 @@ kqswnal_initialise (void)
 		rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
 				      krx->krx_elanaddr,
 				      krx->krx_npages * PAGE_SIZE, 0);
-		if (rc != 0)
+		if (rc != ESUCCESS)
 		{
 			CERROR ("failed ep_queue_receive %d\n", rc);
 			kqswnal_finalise ();
@@ -628,7 +632,7 @@ kqswnal_initialise (void)
 	PORTAL_SYMBOL_REGISTER(kqswnal_ni);
 	kqswnal_data.kqn_init = KQN_INIT_ALL;
 
-	printk(KERN_INFO "Routing QSW NAL loaded on node %d of %d "
+	printk(KERN_INFO "Lustre: Routing QSW NAL loaded on node %d of %d "
 	       "(Routing %s, initial mem %d)\n", 
 	       kqswnal_data.kqn_elanid, kqswnal_data.kqn_nnodes,
 	       kpr_routing (&kqswnal_data.kqn_router) ? "enabled" : "disabled",
diff --git a/lnet/klnds/qswlnd/qswlnd.h b/lnet/klnds/qswlnd/qswlnd.h
index 0d8e2fa61d59de54787c60beab6f12e81d5aaef1..4cb9ad9f8357c5062156bdd290a4319d576b18ed 100644
--- a/lnet/klnds/qswlnd/qswlnd.h
+++ b/lnet/klnds/qswlnd/qswlnd.h
@@ -24,7 +24,9 @@
 
 #ifndef _QSWNAL_H
 #define _QSWNAL_H
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #ifdef PROPRIETARY_ELAN
 # include <qsw/kernel.h>
@@ -73,6 +75,8 @@
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
 
+#define KQSW_OPTIMIZE_GETS 1
+
 #define KQSW_CHECKSUM   0
 #if KQSW_CHECKSUM
 typedef unsigned long kqsw_csum_t;
@@ -93,12 +97,7 @@ typedef unsigned long kqsw_csum_t;
  * Performance Tuning defines
  * NB no mention of PAGE_SIZE for interoperability
  */
-#if PTL_LARGE_MTU
-# define KQSW_MAXPAYLOAD                (256<<10) /* biggest message this NAL will cope with */
-#else
-# define KQSW_MAXPAYLOAD                (64<<10) /* biggest message this NAL will cope with */
-#endif
-
+#define KQSW_MAXPAYLOAD                 PTL_MTU
 #define KQSW_SMALLPAYLOAD               ((4<<10) - KQSW_HDR_SIZE) /* small/large ep receiver breakpoint */
 
 #define KQSW_TX_MAXCONTIG               (1<<10) /* largest payload that gets made contiguous on transmit */
@@ -134,6 +133,12 @@ typedef unsigned long kqsw_csum_t;
 #define KQSW_NRXMSGBYTES_LARGE  (KQSW_NRXMSGPAGES_LARGE * PAGE_SIZE)
 /* biggest complete packet we can receive (or transmit) */
 
+/* Remote memory descriptor */
+typedef struct
+{
+        __u32            kqrmd_neiov;           /* # frags */
+        EP_IOVEC         kqrmd_eiov[0];         /* actual frags */
+} kqswnal_remotemd_t;
 
 typedef struct 
 {
@@ -143,6 +148,8 @@ typedef struct
         E3_Addr          krx_elanaddr;          /* Elan address of buffer (contiguous in elan vm) */
         int              krx_npages;            /* # pages in receive buffer */
         int              krx_nob;               /* Number Of Bytes received into buffer */
+        atomic_t         krx_refcount;          /* who's using me? */
+        int              krx_rpc_completed;     /* I completed peer's RPC */
         kpr_fwd_desc_t   krx_fwd;               /* embedded forwarding descriptor */
         struct page     *krx_pages[KQSW_NRXMSGPAGES_LARGE]; /* pages allocated */
         struct iovec     krx_iov[KQSW_NRXMSGPAGES_LARGE]; /* iovec for forwarding */
@@ -153,12 +160,10 @@ typedef struct
         struct list_head  ktx_list;             /* enqueue idle/active */
         struct list_head  ktx_delayed_list;     /* enqueue delayedtxds */
         int               ktx_isnblk:1;         /* reserved descriptor? */
-        int               ktx_forwarding:1;     /* forwarding (rather than local send) */
+        int               ktx_state:7;          /* What I'm doing */
         uint32_t          ktx_basepage;         /* page offset in reserved elan tx vaddrs for mapping pages */
         int               ktx_npages;           /* pages reserved for mapping messages */
         int               ktx_nmappedpages;     /* # pages mapped for current message */
-        EP_IOVEC          ktx_iov[EP_MAXFRAG];  /* msg frags (elan vaddrs) */
-        int               ktx_niov;             /* # message frags */
         int               ktx_port;             /* destination ep port */
         ptl_nid_t         ktx_nid;              /* destination node */
         void             *ktx_args[2];          /* completion passthru */
@@ -169,8 +174,19 @@ typedef struct
         /* debug/info fields */
         pid_t             ktx_launcher;         /* pid of launching process */
         ptl_hdr_t        *ktx_wire_hdr;         /* portals header (wire endian) */
+
+        int               ktx_nfrag;            /* # message frags */
+        union {
+                EP_IOVEC   iov[EP_MAXFRAG];     /* msg frags (elan vaddrs) */
+                EP_DATAVEC datav[EP_MAXFRAG];   /* DMA frags (eolan vaddrs) */
+        }                 ktx_frags;
 } kqswnal_tx_t;
 
+#define KTX_IDLE        0                       /* on kqn_(nblk_)idletxds */
+#define KTX_SENDING     1                       /* local send */
+#define KTX_FORWARDING  2                       /* routing a packet */
+#define KTX_GETTING     3                       /* local optimised get */
+
 typedef struct
 {
         char               kqn_init;            /* what's been initialised */
@@ -223,6 +239,8 @@ extern int kqswnal_thread_start (int (*fn)(void *arg), void *arg);
 extern void kqswnal_rxhandler(EP_RXD *rxd);
 extern int kqswnal_scheduler (void *);
 extern void kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
+extern void kqswnal_reply_complete (EP_RXD *rxd);
+extern void kqswnal_requeue_rx (kqswnal_rx_t *krx);
 
 static inline ptl_nid_t
 kqswnal_elanid2nid (int elanid) 
@@ -241,13 +259,6 @@ kqswnal_nid2elanid (ptl_nid_t nid)
         return (nid - kqswnal_data.kqn_nid_offset);
 }
 
-static inline void
-kqswnal_requeue_rx (kqswnal_rx_t *krx)
-{
-        ep_requeue_receive (krx->krx_rxd, kqswnal_rxhandler, krx,
-                            krx->krx_elanaddr, krx->krx_npages * PAGE_SIZE);
-}
-
 static inline int
 kqswnal_pages_spanned (void *base, int nob)
 {
diff --git a/lnet/klnds/qswlnd/qswlnd_cb.c b/lnet/klnds/qswlnd/qswlnd_cb.c
index 9452fafe019ac138201b486cca9cdc4fef6454de..43926c9ac35fc835f483dab95f3af16eff493140 100644
--- a/lnet/klnds/qswlnd/qswlnd_cb.c
+++ b/lnet/klnds/qswlnd/qswlnd_cb.c
@@ -26,11 +26,6 @@
 
 #include "qswnal.h"
 
-atomic_t kqswnal_packets_launched;
-atomic_t kqswnal_packets_transmitted;
-atomic_t kqswnal_packets_received;
-
-
 /*
  *  LIB functions follow
  *
@@ -137,7 +132,7 @@ kqswnal_unmap_tx (kqswnal_tx_t *ktx)
                 return;
 
         CDEBUG (D_NET, "%p[%d] unloading pages %d for %d\n",
-                ktx, ktx->ktx_niov, ktx->ktx_basepage, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_basepage, ktx->ktx_nmappedpages);
 
         LASSERT (ktx->ktx_nmappedpages <= ktx->ktx_npages);
         LASSERT (ktx->ktx_basepage + ktx->ktx_nmappedpages <=
@@ -152,15 +147,14 @@ kqswnal_unmap_tx (kqswnal_tx_t *ktx)
 int
 kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 {
-        int       nfrags    = ktx->ktx_niov;
-        const int maxfrags  = sizeof (ktx->ktx_iov)/sizeof (ktx->ktx_iov[0]);
+        int       nfrags    = ktx->ktx_nfrag;
         int       nmapped   = ktx->ktx_nmappedpages;
         int       maxmapped = ktx->ktx_npages;
         uint32_t  basepage  = ktx->ktx_basepage + nmapped;
         char     *ptr;
         
         LASSERT (nmapped <= maxmapped);
-        LASSERT (nfrags <= maxfrags);
+        LASSERT (nfrags <= EP_MAXFRAG);
         LASSERT (niov > 0);
         LASSERT (nob > 0);
         
@@ -179,9 +173,9 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                         return (-EMSGSIZE);
                 }
 
-                if (nfrags == maxfrags) {
+                if (nfrags == EP_MAXFRAG) {
                         CERROR("Message too fragmented in Elan VM (max %d frags)\n",
-                               maxfrags);
+                               EP_MAXFRAG);
                         return (-EMSGSIZE);
                 }
 
@@ -197,7 +191,7 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                 elan3_dvma_kaddr_load (kqswnal_data.kqn_epdev->DmaState,
                                        kqswnal_data.kqn_eptxdmahandle,
                                        ptr, fraglen,
-                                       basepage, &ktx->ktx_iov[nfrags].Base);
+                                       basepage, &ktx->ktx_frags.iov[nfrags].Base);
 
                 kunmap (kiov->kiov_page);
                 
@@ -205,12 +199,12 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                 ktx->ktx_nmappedpages = nmapped;
 
                 if (nfrags > 0 &&                /* previous frag mapped */
-                    ktx->ktx_iov[nfrags].Base == /* contiguous with this one */
-                    (ktx->ktx_iov[nfrags-1].Base + ktx->ktx_iov[nfrags-1].Len))
+                    ktx->ktx_frags.iov[nfrags].Base == /* contiguous with this one */
+                    (ktx->ktx_frags.iov[nfrags-1].Base + ktx->ktx_frags.iov[nfrags-1].Len))
                         /* just extend previous */
-                        ktx->ktx_iov[nfrags - 1].Len += fraglen;
+                        ktx->ktx_frags.iov[nfrags - 1].Len += fraglen;
                 else {
-                        ktx->ktx_iov[nfrags].Len = fraglen;
+                        ktx->ktx_frags.iov[nfrags].Len = fraglen;
                         nfrags++;                /* new frag */
                 }
 
@@ -224,9 +218,9 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 
         } while (nob > 0);
 
-        ktx->ktx_niov = nfrags;
+        ktx->ktx_nfrag = nfrags;
         CDEBUG (D_NET, "%p got %d frags over %d pages\n",
-                ktx, ktx->ktx_niov, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_nmappedpages);
 
         return (0);
 }
@@ -234,14 +228,13 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 int
 kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
 {
-        int       nfrags    = ktx->ktx_niov;
-        const int maxfrags  = sizeof (ktx->ktx_iov)/sizeof (ktx->ktx_iov[0]);
+        int       nfrags    = ktx->ktx_nfrag;
         int       nmapped   = ktx->ktx_nmappedpages;
         int       maxmapped = ktx->ktx_npages;
         uint32_t  basepage  = ktx->ktx_basepage + nmapped;
 
         LASSERT (nmapped <= maxmapped);
-        LASSERT (nfrags <= maxfrags);
+        LASSERT (nfrags <= EP_MAXFRAG);
         LASSERT (niov > 0);
         LASSERT (nob > 0);
 
@@ -259,9 +252,9 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
                         return (-EMSGSIZE);
                 }
 
-                if (nfrags == maxfrags) {
+                if (nfrags == EP_MAXFRAG) {
                         CERROR("Message too fragmented in Elan VM (max %d frags)\n",
-                               maxfrags);
+                               EP_MAXFRAG);
                         return (-EMSGSIZE);
                 }
 
@@ -273,17 +266,17 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
                 elan3_dvma_kaddr_load (kqswnal_data.kqn_epdev->DmaState,
                                        kqswnal_data.kqn_eptxdmahandle,
                                        iov->iov_base, fraglen,
-                                       basepage, &ktx->ktx_iov[nfrags].Base);
+                                       basepage, &ktx->ktx_frags.iov[nfrags].Base);
                 /* keep in loop for failure case */
                 ktx->ktx_nmappedpages = nmapped;
 
                 if (nfrags > 0 &&                /* previous frag mapped */
-                    ktx->ktx_iov[nfrags].Base == /* contiguous with this one */
-                    (ktx->ktx_iov[nfrags-1].Base + ktx->ktx_iov[nfrags-1].Len))
+                    ktx->ktx_frags.iov[nfrags].Base == /* contiguous with this one */
+                    (ktx->ktx_frags.iov[nfrags-1].Base + ktx->ktx_frags.iov[nfrags-1].Len))
                         /* just extend previous */
-                        ktx->ktx_iov[nfrags - 1].Len += fraglen;
+                        ktx->ktx_frags.iov[nfrags - 1].Len += fraglen;
                 else {
-                        ktx->ktx_iov[nfrags].Len = fraglen;
+                        ktx->ktx_frags.iov[nfrags].Len = fraglen;
                         nfrags++;                /* new frag */
                 }
 
@@ -297,13 +290,14 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
 
         } while (nob > 0);
 
-        ktx->ktx_niov = nfrags;
+        ktx->ktx_nfrag = nfrags;
         CDEBUG (D_NET, "%p got %d frags over %d pages\n",
-                ktx, ktx->ktx_niov, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_nmappedpages);
 
         return (0);
 }
 
+
 void
 kqswnal_put_idle_tx (kqswnal_tx_t *ktx)
 {
@@ -311,6 +305,7 @@ kqswnal_put_idle_tx (kqswnal_tx_t *ktx)
         unsigned long     flags;
 
         kqswnal_unmap_tx (ktx);                 /* release temporary mappings */
+        ktx->ktx_state = KTX_IDLE;
 
         spin_lock_irqsave (&kqswnal_data.kqn_idletxd_lock, flags);
 
@@ -407,18 +402,45 @@ kqswnal_get_idle_tx (kpr_fwd_desc_t *fwd, int may_block)
 
         /* Idle descs can't have any mapped (as opposed to pre-mapped) pages */
         LASSERT (ktx == NULL || ktx->ktx_nmappedpages == 0);
+
         return (ktx);
 }
 
 void
 kqswnal_tx_done (kqswnal_tx_t *ktx, int error)
 {
-        if (ktx->ktx_forwarding)                /* router asked me to forward this packet */
+        lib_msg_t     *msg;
+        lib_msg_t     *repmsg;
+
+        switch (ktx->ktx_state) {
+        case KTX_FORWARDING:       /* router asked me to forward this packet */
                 kpr_fwd_done (&kqswnal_data.kqn_router,
                               (kpr_fwd_desc_t *)ktx->ktx_args[0], error);
-        else                                    /* packet sourced locally */
+                break;
+
+        case KTX_SENDING:          /* packet sourced locally */
                 lib_finalize (&kqswnal_lib, ktx->ktx_args[0],
                               (lib_msg_t *)ktx->ktx_args[1]);
+                break;
+
+        case KTX_GETTING:          /* Peer has DMA-ed direct? */
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                msg = (lib_msg_t *)ktx->ktx_args[1];
+                repmsg = NULL;
+
+                if (error == 0) 
+                        repmsg = lib_fake_reply_msg (&kqswnal_lib, 
+                                                     ktx->ktx_nid, msg->md);
+                
+                lib_finalize (&kqswnal_lib, ktx->ktx_args[0], msg);
+
+                if (repmsg != NULL) 
+                        lib_finalize (&kqswnal_lib, NULL, repmsg);
+                break;
+
+        default:
+                LASSERT (0);
+        }
 
         kqswnal_put_idle_tx (ktx);
 }
@@ -427,15 +449,12 @@ static void
 kqswnal_txhandler(EP_TXD *txd, void *arg, int status)
 {
         kqswnal_tx_t      *ktx = (kqswnal_tx_t *)arg;
-        
+
         LASSERT (txd != NULL);
         LASSERT (ktx != NULL);
 
         CDEBUG(D_NET, "txd %p, arg %p status %d\n", txd, arg, status);
 
-        if (status == EP_SUCCESS)
-                atomic_inc (&kqswnal_packets_transmitted);
-
         if (status != EP_SUCCESS)
         {
                 CERROR ("Tx completion to "LPX64" failed: %d\n", 
@@ -443,6 +462,14 @@ kqswnal_txhandler(EP_TXD *txd, void *arg, int status)
 
                 kqswnal_notify_peer_down(ktx);
                 status = -EIO;
+
+        } else if (ktx->ktx_state == KTX_GETTING) {
+                /* RPC completed OK; what did our peer put in the status
+                 * block? */
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                status = ep_txd_statusblk(txd)->Status;
+        } else {
+                status = 0;
         }
 
         kqswnal_tx_done (ktx, status);
@@ -460,12 +487,19 @@ kqswnal_launch (kqswnal_tx_t *ktx)
         ktx->ktx_launchtime = jiffies;
 
         LASSERT (dest >= 0);                    /* must be a peer */
-        rc = ep_transmit_large(kqswnal_data.kqn_eptx, dest,
-                               ktx->ktx_port, attr, kqswnal_txhandler,
-                               ktx, ktx->ktx_iov, ktx->ktx_niov);
+        if (ktx->ktx_state == KTX_GETTING) {
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                rc = ep_transmit_rpc(kqswnal_data.kqn_eptx, dest,
+                                     ktx->ktx_port, attr, kqswnal_txhandler,
+                                     ktx, NULL, ktx->ktx_frags.iov, ktx->ktx_nfrag);
+        } else {
+                rc = ep_transmit_large(kqswnal_data.kqn_eptx, dest,
+                                       ktx->ktx_port, attr, kqswnal_txhandler,
+                                       ktx, ktx->ktx_frags.iov, ktx->ktx_nfrag);
+        }
+
         switch (rc) {
-        case 0: /* success */
-                atomic_inc (&kqswnal_packets_launched);
+        case ESUCCESS: /* success */
                 return (0);
 
         case ENOMEM: /* can't allocate ep txd => queue for later */
@@ -508,8 +542,9 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
 {
         char *type_str = hdr_type_string (hdr);
 
-        CERROR("P3 Header at %p of type %s\n", hdr, type_str);
-        CERROR("    From nid/pid "LPU64"/%u", NTOH__u64(hdr->src_nid),
+        CERROR("P3 Header at %p of type %s length %d\n", hdr, type_str,
+               NTOH__u32(hdr->payload_length));
+        CERROR("    From nid/pid "LPU64"/%u\n", NTOH__u64(hdr->src_nid),
                NTOH__u32(hdr->src_pid));
         CERROR("    To nid/pid "LPU64"/%u\n", NTOH__u64(hdr->dest_nid),
                NTOH__u32(hdr->dest_pid));
@@ -522,8 +557,7 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
                        hdr->msg.put.ack_wmd.wh_interface_cookie,
                        hdr->msg.put.ack_wmd.wh_object_cookie,
                        NTOH__u64 (hdr->msg.put.match_bits));
-                CERROR("    Length %d, offset %d, hdr data "LPX64"\n",
-                       NTOH__u32(PTL_HDR_LENGTH(hdr)),
+                CERROR("    offset %d, hdr data "LPX64"\n",
                        NTOH__u32(hdr->msg.put.offset),
                        hdr->msg.put.hdr_data);
                 break;
@@ -548,18 +582,148 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
                 break;
 
         case PTL_MSG_REPLY:
-                CERROR("    dst md "LPX64"."LPX64", length %d\n",
+                CERROR("    dst md "LPX64"."LPX64"\n",
                        hdr->msg.reply.dst_wmd.wh_interface_cookie,
-                       hdr->msg.reply.dst_wmd.wh_object_cookie,
-                       NTOH__u32 (PTL_HDR_LENGTH(hdr)));
+                       hdr->msg.reply.dst_wmd.wh_object_cookie);
         }
 
 }                               /* end of print_hdr() */
 
+void
+kqswnal_print_eiov (int how, char *str, int n, EP_IOVEC *iov) 
+{
+        int          i;
+
+        CDEBUG (how, "%s: %d\n", str, n);
+        for (i = 0; i < n; i++) {
+                CDEBUG (how, "   %08x for %d\n", iov[i].Base, iov[i].Len);
+        }
+}
+
+int
+kqswnal_eiovs2datav (int ndv, EP_DATAVEC *dv,
+                     int nsrc, EP_IOVEC *src,
+                     int ndst, EP_IOVEC *dst) 
+{
+        int        count;
+        int        nob;
+
+        LASSERT (ndv > 0);
+        LASSERT (nsrc > 0);
+        LASSERT (ndst > 0);
+
+        for (count = 0; count < ndv; count++, dv++) {
+
+                if (nsrc == 0 || ndst == 0) {
+                        if (nsrc != ndst) {
+                                /* For now I'll barf on any left over entries */
+                                CERROR ("mismatched src and dst iovs\n");
+                                return (-EINVAL);
+                        }
+                        return (count);
+                }
+
+                nob = (src->Len < dst->Len) ? src->Len : dst->Len;
+                dv->Len    = nob;
+                dv->Source = src->Base;
+                dv->Dest   = dst->Base;
+
+                if (nob >= src->Len) {
+                        src++;
+                        nsrc--;
+                } else {
+                        src->Len -= nob;
+                        src->Base += nob;
+                }
+                
+                if (nob >= dst->Len) {
+                        dst++;
+                        ndst--;
+                } else {
+                        src->Len -= nob;
+                        src->Base += nob;
+                }
+        }
+
+        CERROR ("DATAVEC too small\n");
+        return (-E2BIG);
+}
+
+int
+kqswnal_dma_reply (kqswnal_tx_t *ktx, int nfrag, 
+                   struct iovec *iov, ptl_kiov_t *kiov, int nob)
+{
+        kqswnal_rx_t       *krx = (kqswnal_rx_t *)ktx->ktx_args[0];
+        char               *buffer = (char *)page_address(krx->krx_pages[0]);
+        kqswnal_remotemd_t *rmd = (kqswnal_remotemd_t *)(buffer + KQSW_HDR_SIZE);
+        EP_IOVEC            eiov[EP_MAXFRAG];
+        EP_STATUSBLK        blk;
+        int                 rc;
+
+        LASSERT (ep_rxd_isrpc(krx->krx_rxd) && !krx->krx_rpc_completed);
+        LASSERT ((iov == NULL) != (kiov == NULL));
+
+        /* see .*_pack_k?iov comment regarding endian-ness */
+        if (buffer + krx->krx_nob < (char *)(rmd + 1)) {
+                /* msg too small to discover rmd size */
+                CERROR ("Incoming message [%d] too small for RMD (%d needed)\n",
+                        krx->krx_nob, (int)(((char *)(rmd + 1)) - buffer));
+                return (-EINVAL);
+        }
+        
+        if (buffer + krx->krx_nob < (char *)&rmd->kqrmd_eiov[rmd->kqrmd_neiov]) {
+                /* rmd doesn't fit in the incoming message */
+                CERROR ("Incoming message [%d] too small for RMD[%d] (%d needed)\n",
+                        krx->krx_nob, rmd->kqrmd_neiov,
+                        (int)(((char *)&rmd->kqrmd_eiov[rmd->kqrmd_neiov]) - buffer));
+                return (-EINVAL);
+        }
+
+        /* Ghastly hack part 1, uses the existing procedures to map the source data... */
+        ktx->ktx_nfrag = 0;
+        if (kiov != NULL)
+                rc = kqswnal_map_tx_kiov (ktx, nob, nfrag, kiov);
+        else
+                rc = kqswnal_map_tx_iov (ktx, nob, nfrag, iov);
+
+        if (rc != 0) {
+                CERROR ("Can't map source data: %d\n", rc);
+                return (rc);
+        }
+
+        /* Ghastly hack part 2, copy out eiov so we can create the datav; Ugghh... */
+        memcpy (eiov, ktx->ktx_frags.iov, ktx->ktx_nfrag * sizeof (eiov[0]));
+
+        rc = kqswnal_eiovs2datav (EP_MAXFRAG, ktx->ktx_frags.datav,
+                                  ktx->ktx_nfrag, eiov,
+                                  rmd->kqrmd_neiov, rmd->kqrmd_eiov);
+        if (rc < 0) {
+                CERROR ("Can't create datavec: %d\n", rc);
+                return (rc);
+        }
+        ktx->ktx_nfrag = rc;
+
+        memset (&blk, 0, sizeof (blk));         /* zero blk.Status */
+
+        /* Our caller will start to race with kqswnal_rpc_complete... */
+        LASSERT (atomic_read (&krx->krx_refcount) == 1);
+        atomic_set (&krx->krx_refcount, 2);
+
+        rc = ep_complete_rpc (krx->krx_rxd, kqswnal_reply_complete, ktx,
+                              &blk, ktx->ktx_frags.datav, ktx->ktx_nfrag);
+        if (rc == ESUCCESS)
+                return (0);
+
+        /* reset refcount back to 1: we're not going to be racing with
+         * kqswnal_rely_complete. */
+        atomic_set (&krx->krx_refcount, 1);
+        return (-ECONNABORTED);
+}
+
 static int
 kqswnal_sendmsg (nal_cb_t     *nal,
                  void         *private,
-                 lib_msg_t    *cookie,
+                 lib_msg_t    *libmsg,
                  ptl_hdr_t    *hdr,
                  int           type,
                  ptl_nid_t     nid,
@@ -571,7 +735,7 @@ kqswnal_sendmsg (nal_cb_t     *nal,
 {
         kqswnal_tx_t      *ktx;
         int                rc;
-        ptl_nid_t          gatewaynid;
+        ptl_nid_t          targetnid;
 #if KQSW_CHECKSUM
         int                i;
         kqsw_csum_t        csum;
@@ -595,20 +759,20 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 return (PTL_FAIL);
         }
 
+        targetnid = nid;
         if (kqswnal_nid2elanid (nid) < 0) {     /* Can't send direct: find gateway? */
                 rc = kpr_lookup (&kqswnal_data.kqn_router, nid, 
-                                 sizeof (ptl_hdr_t) + payload_nob, &gatewaynid);
+                                 sizeof (ptl_hdr_t) + payload_nob, &targetnid);
                 if (rc != 0) {
                         CERROR("Can't route to "LPX64": router error %d\n",
                                nid, rc);
                         return (PTL_FAIL);
                 }
-                if (kqswnal_nid2elanid (gatewaynid) < 0) {
+                if (kqswnal_nid2elanid (targetnid) < 0) {
                         CERROR("Bad gateway "LPX64" for "LPX64"\n",
-                               gatewaynid, nid);
+                               targetnid, nid);
                         return (PTL_FAIL);
                 }
-                nid = gatewaynid;
         }
 
         /* I may not block for a transmit descriptor if I might block the
@@ -621,6 +785,35 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 return (PTL_NOSPACE);
         }
 
+        ktx->ktx_args[0] = private;
+        ktx->ktx_args[1] = libmsg;
+
+#if KQSW_OPTIMIZE_GETS
+        if (type == PTL_MSG_REPLY &&
+            ep_rxd_isrpc(((kqswnal_rx_t *)private)->krx_rxd)) {
+                if (nid != targetnid ||
+                    kqswnal_nid2elanid(nid) != 
+                    ep_rxd_node(((kqswnal_rx_t *)private)->krx_rxd)) {
+                        CERROR("Optimized reply nid conflict: "
+                               "nid "LPX64" via "LPX64" elanID %d\n",
+                               nid, targetnid,
+                               ep_rxd_node(((kqswnal_rx_t *)private)->krx_rxd));
+                        return(PTL_FAIL);
+                }
+
+                /* peer expects RPC completion with GET data */
+                rc = kqswnal_dma_reply (ktx,
+                                        payload_niov, payload_iov, 
+                                        payload_kiov, payload_nob);
+                if (rc == 0)
+                        return (0);
+                
+                CERROR ("Can't DMA reply to "LPX64": %d\n", nid, rc);
+                kqswnal_put_idle_tx (ktx);
+                return (PTL_FAIL);
+        }
+#endif
+
         memcpy (ktx->ktx_buffer, hdr, sizeof (*hdr)); /* copy hdr from caller's stack */
         ktx->ktx_wire_hdr = (ptl_hdr_t *)ktx->ktx_buffer;
 
@@ -644,13 +837,57 @@ kqswnal_sendmsg (nal_cb_t     *nal,
         }
         memcpy(ktx->ktx_buffer +sizeof(*hdr) +sizeof(csum), &csum,sizeof(csum));
 #endif
-
+        
         /* Set up first frag from pre-mapped buffer (it's at least the
          * portals header) */
-        ktx->ktx_iov[0].Base = ktx->ktx_ebuffer;
-        ktx->ktx_iov[0].Len = KQSW_HDR_SIZE;
-        ktx->ktx_niov = 1;
+        ktx->ktx_frags.iov[0].Base = ktx->ktx_ebuffer;
+        ktx->ktx_frags.iov[0].Len = KQSW_HDR_SIZE;
+        ktx->ktx_nfrag = 1;
+        ktx->ktx_state = KTX_SENDING;   /* => lib_finalize() on completion */
+
+#if KQSW_OPTIMIZE_GETS
+        if (type == PTL_MSG_GET &&              /* doing a GET */
+            nid == targetnid) {                 /* not forwarding */
+                lib_md_t           *md = libmsg->md;
+                kqswnal_remotemd_t *rmd = (kqswnal_remotemd_t *)(ktx->ktx_buffer + KQSW_HDR_SIZE);
+                
+                /* Optimised path: I send over the Elan vaddrs of the get
+                 * sink buffers, and my peer DMAs directly into them.
+                 *
+                 * First I set up ktx as if it was going to send this
+                 * payload, (it needs to map it anyway).  This fills
+                 * ktx_frags.iov[1] and onward with the network addresses
+                 * of the get sink frags.  I copy these into ktx_buffer,
+                 * immediately after the header, and send that as my GET
+                 * message.
+                 *
+                 * Note that the addresses are sent in native endian-ness.
+                 * When EKC copes with different endian nodes, I'll fix
+                 * this (and eat my hat :) */
+
+                if ((libmsg->md->options & PTL_MD_KIOV) != 0) 
+                        rc = kqswnal_map_tx_kiov (ktx, md->length,
+                                                  md->md_niov, md->md_iov.kiov);
+                else
+                        rc = kqswnal_map_tx_iov (ktx, md->length,
+                                                 md->md_niov, md->md_iov.iov);
+
+                if (rc < 0) {
+                        kqswnal_put_idle_tx (ktx);
+                        return (PTL_FAIL);
+                }
+
+                rmd->kqrmd_neiov = ktx->ktx_nfrag - 1;
+                memcpy (&rmd->kqrmd_eiov[0], &ktx->ktx_frags.iov[1],
+                        rmd->kqrmd_neiov * sizeof (EP_IOVEC));
 
+                ktx->ktx_nfrag = 1;
+                ktx->ktx_frags.iov[0].Len += offsetof (kqswnal_remotemd_t,
+                                                       kqrmd_eiov[rmd->kqrmd_neiov]);
+                payload_nob = ktx->ktx_frags.iov[0].Len;
+                ktx->ktx_state = KTX_GETTING;
+        } else 
+#endif
         if (payload_nob > 0) { /* got some payload (something more to do) */
                 /* make a single contiguous message? */
                 if (payload_nob <= KQSW_TX_MAXCONTIG) {
@@ -662,7 +899,7 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                                 lib_copy_iov2buf (ktx->ktx_buffer + KQSW_HDR_SIZE,
                                                   payload_niov, payload_iov, payload_nob);
                         /* first frag includes payload */
-                        ktx->ktx_iov[0].Len += payload_nob;
+                        ktx->ktx_frags.iov[0].Len += payload_nob;
                 } else {
                         if (payload_kiov != NULL)
                                 rc = kqswnal_map_tx_kiov (ktx, payload_nob, 
@@ -677,28 +914,26 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 } 
         }
 
-        ktx->ktx_port       = (payload_nob <= KQSW_SMALLPAYLOAD) ?
-                              EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
-        ktx->ktx_nid        = nid;
-        ktx->ktx_forwarding = 0;   /* => lib_finalize() on completion */
-        ktx->ktx_args[0]    = private;
-        ktx->ktx_args[1]    = cookie;
+        ktx->ktx_nid  = targetnid;
+        ktx->ktx_port = (payload_nob <= KQSW_SMALLPAYLOAD) ?
+                        EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
 
         rc = kqswnal_launch (ktx);
         if (rc != 0) {                    /* failed? */
-                CERROR ("Failed to send packet to "LPX64": %d\n", nid, rc);
+                CERROR ("Failed to send packet to "LPX64": %d\n", targetnid, rc);
                 kqswnal_put_idle_tx (ktx);
                 return (PTL_FAIL);
         }
 
-        CDEBUG(D_NET, "sent "LPSZ" bytes to "LPX64"\n", payload_nob, nid);
+        CDEBUG(D_NET, "sent "LPSZ" bytes to "LPX64" via "LPX64"\n", 
+               payload_nob, nid, targetnid);
         return (PTL_OK);
 }
 
 static int
 kqswnal_send (nal_cb_t     *nal,
               void         *private,
-              lib_msg_t    *cookie,
+              lib_msg_t    *libmsg,
               ptl_hdr_t    *hdr,
               int           type,
               ptl_nid_t     nid,
@@ -707,14 +942,14 @@ kqswnal_send (nal_cb_t     *nal,
               struct iovec *payload_iov,
               size_t        payload_nob)
 {
-        return (kqswnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+        return (kqswnal_sendmsg (nal, private, libmsg, hdr, type, nid, pid,
                                  payload_niov, payload_iov, NULL, payload_nob));
 }
 
 static int
 kqswnal_send_pages (nal_cb_t     *nal,
                     void         *private,
-                    lib_msg_t    *cookie,
+                    lib_msg_t    *libmsg,
                     ptl_hdr_t    *hdr,
                     int           type,
                     ptl_nid_t     nid,
@@ -723,7 +958,7 @@ kqswnal_send_pages (nal_cb_t     *nal,
                     ptl_kiov_t   *payload_kiov,
                     size_t        payload_nob)
 {
-        return (kqswnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+        return (kqswnal_sendmsg (nal, private, libmsg, hdr, type, nid, pid,
                                  payload_niov, NULL, payload_kiov, payload_nob));
 }
 
@@ -775,16 +1010,15 @@ kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
         {
                 /* send from ktx's pre-allocated/mapped contiguous buffer? */
                 lib_copy_iov2buf (ktx->ktx_buffer, niov, iov, nob);
-                ktx->ktx_iov[0].Base = ktx->ktx_ebuffer; /* already mapped */
-                ktx->ktx_iov[0].Len = nob;
-                ktx->ktx_niov = 1;
-
+                ktx->ktx_frags.iov[0].Base = ktx->ktx_ebuffer; /* already mapped */
+                ktx->ktx_frags.iov[0].Len = nob;
+                ktx->ktx_nfrag = 1;
                 ktx->ktx_wire_hdr = (ptl_hdr_t *)ktx->ktx_buffer;
         }
         else
         {
                 /* zero copy */
-                ktx->ktx_niov = 0;        /* no frags mapped yet */
+                ktx->ktx_nfrag = 0;       /* no frags mapped yet */
                 rc = kqswnal_map_tx_iov (ktx, nob, niov, iov);
                 if (rc != 0)
                         goto failed;
@@ -792,11 +1026,11 @@ kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
                 ktx->ktx_wire_hdr = (ptl_hdr_t *)iov[0].iov_base;
         }
 
-        ktx->ktx_port       = (nob <= (sizeof (ptl_hdr_t) + KQSW_SMALLPAYLOAD)) ?
-                              EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
-        ktx->ktx_nid        = nid;
-        ktx->ktx_forwarding = 1;
-        ktx->ktx_args[0]    = fwd;
+        ktx->ktx_port    = (nob <= (sizeof (ptl_hdr_t) + KQSW_SMALLPAYLOAD)) ?
+                        EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
+        ktx->ktx_nid     = nid;
+        ktx->ktx_state   = KTX_FORWARDING; /* kpr_put_packet() on completion */
+        ktx->ktx_args[0] = fwd;
 
         rc = kqswnal_launch (ktx);
         if (rc == 0)
@@ -829,6 +1063,97 @@ kqswnal_fwd_callback (void *arg, int error)
         kqswnal_requeue_rx (krx);
 }
 
+void
+kqswnal_reply_complete (EP_RXD *rxd) 
+{
+        int           status = ep_rxd_status(rxd);
+        kqswnal_tx_t *ktx = (kqswnal_tx_t *)ep_rxd_arg(rxd);
+        kqswnal_rx_t *krx = (kqswnal_rx_t *)ktx->ktx_args[0];
+        lib_msg_t    *msg = (lib_msg_t *)ktx->ktx_args[1];
+        
+        CDEBUG((status == EP_SUCCESS) ? D_NET : D_ERROR,
+               "rxd %p, ktx %p, status %d\n", rxd, ktx, status);
+
+        LASSERT (krx->krx_rxd == rxd);
+
+        krx->krx_rpc_completed = 1;
+        kqswnal_requeue_rx (krx);
+
+        lib_finalize (&kqswnal_lib, NULL, msg);
+        kqswnal_put_idle_tx (ktx);
+}
+
+void
+kqswnal_rpc_complete (EP_RXD *rxd)
+{
+        int           status = ep_rxd_status(rxd);
+        kqswnal_rx_t *krx    = (kqswnal_rx_t *)ep_rxd_arg(rxd);
+        
+        CDEBUG((status == EP_SUCCESS) ? D_NET : D_ERROR,
+               "rxd %p, krx %p, status %d\n", rxd, krx, status);
+
+        LASSERT (krx->krx_rxd == rxd);
+        
+        krx->krx_rpc_completed = 1;
+        kqswnal_requeue_rx (krx);
+}
+
+void
+kqswnal_requeue_rx (kqswnal_rx_t *krx)
+{
+        EP_STATUSBLK  blk;
+        int           rc;
+
+        LASSERT (atomic_read (&krx->krx_refcount) > 0);
+        if (!atomic_dec_and_test (&krx->krx_refcount))
+                return;
+
+        if (!ep_rxd_isrpc(krx->krx_rxd) ||
+            krx->krx_rpc_completed) {
+
+                /* don't actually requeue on shutdown */
+                if (kqswnal_data.kqn_shuttingdown)
+                        return;
+                
+                ep_requeue_receive (krx->krx_rxd, kqswnal_rxhandler, krx,
+                                    krx->krx_elanaddr, krx->krx_npages * PAGE_SIZE);
+                return;
+        }
+
+        /* Sender wanted an RPC, but we didn't complete it (we must have
+         * dropped the sender's message).  We complete it now with
+         * failure... */
+        memset (&blk, 0, sizeof (blk));
+        blk.Status = -ECONNREFUSED;
+
+        atomic_set (&krx->krx_refcount, 1);
+
+        rc = ep_complete_rpc (krx->krx_rxd, 
+                              kqswnal_rpc_complete, krx,
+                              &blk, NULL, 0);
+        if (rc == ESUCCESS) {
+                /* callback will call me again to requeue, having set
+                 * krx_rpc_completed... */
+                return;
+        }
+
+        CERROR("can't complete RPC: %d\n", rc);
+
+        /* we don't actually requeue on shutdown */
+        if (kqswnal_data.kqn_shuttingdown)
+                return;
+
+        /* NB ep_complete_rpc() frees rxd on failure, so we have to requeue
+         * from scratch here... */
+        rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
+                              krx->krx_elanaddr, 
+                              krx->krx_npages * PAGE_SIZE, 0);
+
+        LASSERT (rc == ESUCCESS);
+        /* This needs to be fixed by ep_complete_rpc NOT freeing
+         * krx->krx_rxd on failure so we can just ep_requeue_receive() */
+}
+
 void
 kqswnal_rx (kqswnal_rx_t *krx)
 {
@@ -851,6 +1176,7 @@ kqswnal_rx (kqswnal_rx_t *krx)
         {
                 CERROR("dropping packet from "LPX64" for "LPX64
                        ": target is peer\n", NTOH__u64(hdr->src_nid), dest_nid);
+
                 kqswnal_requeue_rx (krx);
                 return;
         }
@@ -886,21 +1212,26 @@ kqswnal_rxhandler(EP_RXD *rxd)
 
         krx->krx_rxd = rxd;
         krx->krx_nob = nob;
-
+        LASSERT (atomic_read (&krx->krx_refcount) == 0);
+        atomic_set (&krx->krx_refcount, 1);
+        krx->krx_rpc_completed = 0;
+        
         /* must receive a whole header to be able to parse */
         if (status != EP_SUCCESS || nob < sizeof (ptl_hdr_t))
         {
                 /* receives complete with failure when receiver is removed */
-                if (kqswnal_data.kqn_shuttingdown)
-                        return;
+                if (!kqswnal_data.kqn_shuttingdown)
+                        CERROR("receive status failed with status %d nob %d\n",
+                               ep_rxd_status(rxd), nob);
 
-                CERROR("receive status failed with status %d nob %d\n",
-                       ep_rxd_status(rxd), nob);
                 kqswnal_requeue_rx (krx);
                 return;
         }
 
-        atomic_inc (&kqswnal_packets_received);
+        if (!in_interrupt()) {
+                kqswnal_rx (krx);
+                return;
+        }
 
         spin_lock_irqsave (&kqswnal_data.kqn_sched_lock, flags);
 
@@ -960,7 +1291,7 @@ kqswnal_csum_error (kqswnal_rx_t *krx, int ishdr)
 static int
 kqswnal_recvmsg (nal_cb_t     *nal,
                  void         *private,
-                 lib_msg_t    *cookie,
+                 lib_msg_t    *libmsg,
                  unsigned int  niov,
                  struct iovec *iov,
                  ptl_kiov_t   *kiov,
@@ -1084,7 +1415,7 @@ kqswnal_recvmsg (nal_cb_t     *nal,
                        "csum_nob %d\n",
                         hdr_csum, payload_csum, csum_frags, csum_nob);
 #endif
-        lib_finalize(nal, private, cookie);
+        lib_finalize(nal, private, libmsg);
 
         kqswnal_requeue_rx (krx);
 
@@ -1094,25 +1425,25 @@ kqswnal_recvmsg (nal_cb_t     *nal,
 static int
 kqswnal_recv(nal_cb_t     *nal,
              void         *private,
-             lib_msg_t    *cookie,
+             lib_msg_t    *libmsg,
              unsigned int  niov,
              struct iovec *iov,
              size_t        mlen,
              size_t        rlen)
 {
-        return (kqswnal_recvmsg (nal, private, cookie, niov, iov, NULL, mlen, rlen));
+        return (kqswnal_recvmsg (nal, private, libmsg, niov, iov, NULL, mlen, rlen));
 }
 
 static int
 kqswnal_recv_pages (nal_cb_t     *nal,
                     void         *private,
-                    lib_msg_t    *cookie,
+                    lib_msg_t    *libmsg,
                     unsigned int  niov,
                     ptl_kiov_t   *kiov,
                     size_t        mlen,
                     size_t        rlen)
 {
-        return (kqswnal_recvmsg (nal, private, cookie, niov, NULL, kiov, mlen, rlen));
+        return (kqswnal_recvmsg (nal, private, libmsg, niov, NULL, kiov, mlen, rlen));
 }
 
 int
diff --git a/lnet/klnds/scimaclnd/README.scimacnal b/lnet/klnds/scimaclnd/README.scimacnal
index d4c6a492cfc857abedb221895de24c808420dfea..e1ee3b56fbed45f0b9ebbb3fa0469f6a45484451 100644
--- a/lnet/klnds/scimaclnd/README.scimacnal
+++ b/lnet/klnds/scimaclnd/README.scimacnal
@@ -2,13 +2,41 @@
 scimacnal - A NAL for the Scali ScaMAC midlayer.
 
 The ScaMAC midlayer is a simplified API to the SCI high performance
-interconnect.
+interconnect (http://www.scali.com/, http://www.dolphinics.com/).
 
 In order to use this NAL you'll need to tune scimac to use larger buffers.
 See scimac.conf in this directory for an example.
 
-Overall performance and stability isn't great but this can be attributed
-to the scimac driver which apparently is in need of some development.
+You'll also need to edit portals/include/portals/lib-types.h and reduce
+the MTU to 64kB (the limit of scimac), this diff should help:
+
+----------------------8<----------------------------------
+--- portals/include/portals/lib-types.h 27 Jul 2003 02:05:47 -0000      1.1.2.5
++++ portals/include/portals/lib-types.h 14 Aug 2003 08:32:14 -0000
+@@ -137,8 +137,8 @@
+ } lib_counters_t;
+ 
+ /* temporary expedient: limit number of entries in discontiguous MDs */
+-# define PTL_MTU        (512<<10)
+-# define PTL_MD_MAX_IOV 128
++# define PTL_MTU        (64<<10)
++# define PTL_MD_MAX_IOV 16
+ 
+ struct lib_msg_t {
+         struct list_head  msg_list;
+----------------------8<----------------------------------
+
+The NAL itself seems quite stable, though scimac has recovery bugs when
+rebooting nodes at times (confirmed by the fact that the IP driver that
+also uses scimac loses connectivity when scimacnal does).  This is
+solved by unloading lustre and reloading the scimac driver on the
+affected nodes.
+
+Performance isn't great when it comes to latency, scimac seems to have
+problems with per packet latencies (confirmed with the IP driver which
+has similar behaviour). Bandwidth using large packets is pretty OK
+(probably due to the fact that it hides the latency issues).
 
 TODO:
 Routing isn't yet implemented.
+Need some way to inform portals about our MTU.
diff --git a/lnet/klnds/scimaclnd/scimacnal.c b/lnet/klnds/scimaclnd/scimacnal.c
index 479cc2c8930b2cb375ac939b4010641d7354cb5b..5ffba31044af7ad0a9f0dce137cebe4735ea9575 100644
--- a/lnet/klnds/scimaclnd/scimacnal.c
+++ b/lnet/klnds/scimaclnd/scimacnal.c
@@ -38,6 +38,24 @@ kpr_nal_interface_t kscimacnal_router_interface = {
 };
 
 
+int kscimacnal_cmd (struct portal_ioctl_data *data, void *private)
+{
+        LASSERT (data != NULL);
+
+        switch (data->ioc_nal_cmd) {
+                case NAL_CMD_REGISTER_MYNID:
+                        if(kscimacnal_lib.ni.nid == data->ioc_nid) {
+                                break;
+                        }
+                        CDEBUG (D_IOCTL, "Can't change NID from "LPX64" to "LPX64")\n", kscimacnal_lib.ni.nid, data->ioc_nid);
+                        return(-EINVAL);
+                default:
+                        return(-EINVAL);
+        }
+
+        return(0);
+}
+
 static int kscimacnal_forward(nal_t   *nal,
                           int     id,
                           void    *args,  size_t args_len,
@@ -105,7 +123,7 @@ static nal_t *kscimacnal_init(int interface, ptl_pt_index_t  ptl_size,
 {
         int     nnids = 512; /* FIXME: Need ScaMac funktion to get #nodes */
 
-        CDEBUG(D_NET, "calling lib_init with nid 0x%Lx nnids %d\n", kscimacnal_data.ksci_nid, nnids);
+        CDEBUG(D_NET, "calling lib_init with nid "LPX64" nnids %d\n", kscimacnal_data.ksci_nid, nnids);
         lib_init(&kscimacnal_lib, kscimacnal_data.ksci_nid, 0, nnids,ptl_size, ac_size); 
         return &kscimacnal_api;
 }
@@ -200,6 +218,16 @@ kscimacnal_initialize(void)
                 return (-ENOMEM);
         }
 
+        /* Init command interface */
+        rc = kportal_nal_register (SCIMACNAL, &kscimacnal_cmd, NULL);
+        if (rc != 0) {
+                CERROR ("Can't initialise command interface (rc = %d)\n", rc);
+                PtlNIFini(kscimacnal_ni);
+                mac_finish(machandle);
+                return (rc);
+        }
+
+
         PORTAL_SYMBOL_REGISTER(kscimacnal_ni);
 
         /* We're done now, it's OK for the RX callback to do stuff */
@@ -210,7 +238,7 @@ kscimacnal_initialize(void)
 
 
 MODULE_AUTHOR("Niklas Edmundsson <nikke@hpc2n.umu.se>");
-MODULE_DESCRIPTION("Kernel Scali ScaMAC SCI NAL v0.0");
+MODULE_DESCRIPTION("Kernel Scali ScaMAC SCI NAL v0.1");
 MODULE_LICENSE("GPL");
 
 module_init (kscimacnal_initialize);
diff --git a/lnet/klnds/scimaclnd/scimacnal.h b/lnet/klnds/scimaclnd/scimacnal.h
index 1ff180e5ccb4a259c9010647ddfa388bfedea7f9..694955780c338130a73cae4345db61455b22bffb 100644
--- a/lnet/klnds/scimaclnd/scimacnal.h
+++ b/lnet/klnds/scimaclnd/scimacnal.h
@@ -43,10 +43,10 @@
 #define MAC_SAPID_LUSTRE MAC_SAPID_TEST1
 #endif /* MAC_SAPID_LUSTRE */
 
+/* scimac has an annoying MTU limit of 64k */
 #define SCIMACNAL_MTU 65536
-/* FIXME: What is really the MTU of lustre? */
-#if PTL_MD_MAX_IOV*PAGE_SIZE > SCIMACNAL_MTU
-#error Max MTU of ScaMAC is 64k, PTL_MD_MAX_IOV*PAGE_SIZE is bigger.
+#if PTL_MTU > SCIMACNAL_MTU
+#error Max MTU of ScaMAC is 64k, PTL_MTU is bigger.
 #endif
 
 typedef struct {
@@ -62,6 +62,9 @@ typedef struct {
         void            *ktx_private;
         lib_msg_t       *ktx_cookie;
         ptl_hdr_t       ktx_hdr;
+        /* To be able to kunmap() kmap():ed pages */
+        struct page     *ktx_kpages[PTL_MD_MAX_IOV];
+        int              ktx_nmapped;
 }  kscimacnal_tx_t;
 
 
diff --git a/lnet/klnds/scimaclnd/scimacnal_cb.c b/lnet/klnds/scimaclnd/scimacnal_cb.c
index 7e4a2e892debc081f7f1b058a7db1bb36d68b7fa..b31c2eae0e8a024137d1cc1b34bdf3cac4fe4465 100644
--- a/lnet/klnds/scimaclnd/scimacnal_cb.c
+++ b/lnet/klnds/scimaclnd/scimacnal_cb.c
@@ -74,7 +74,7 @@ kscimacnal_printf(nal_cb_t *nal, const char *fmt, ...)
                 vsnprintf( msg, sizeof(msg), fmt, ap );
                 va_end( ap );
 
-                printk("CPUId: %d %s",smp_processor_id(), msg);
+                printk("Lustre: CPUId: %d %s",smp_processor_id(), msg);
         }
 }
 
@@ -156,9 +156,15 @@ static void
 kscimacnal_txrelease(mac_mblk_t *msg, mac_msg_status_t status, void *context)
 {
         kscimacnal_tx_t *ktx = (kscimacnal_tx_t *)context;
-        int err=0;
+        int err=0, i;
         
         LASSERT (ktx != NULL);
+        /* Unmap any mapped pages */
+        for(i=0; i<ktx->ktx_nmapped; i++) {
+                kunmap(ktx->ktx_kpages[i]);
+        }
+
+        CDEBUG(D_NET, "kunmapped %d pages\n", ktx->ktx_nmapped);
 
         /* Euh, there is no feedback when transmission fails?! */
         switch(status) {
@@ -178,17 +184,21 @@ kscimacnal_txrelease(mac_mblk_t *msg, mac_msg_status_t status, void *context)
 
 /* Called by portals when it wants to send a message.
  * Since ScaMAC has it's own TX thread we don't bother setting up our own. */
-static int 
-kscimacnal_send(nal_cb_t        *nal,
-           void            *private,
-           lib_msg_t       *cookie,
-           ptl_hdr_t       *hdr,
-           int              type, 
-           ptl_nid_t        nid,
-           ptl_pid_t        pid,
-           unsigned int     payload_niov,
-           struct iovec    *payload_iov,
-           size_t           payload_len)
+
+/* FIXME: Read comments in qswnal_cb.c for _sendmsg and fix return-on-error
+ *        issues */
+static inline int 
+kscimacnal_sendmsg(nal_cb_t        *nal,
+                   void            *private,
+                   lib_msg_t       *cookie,
+                   ptl_hdr_t       *hdr,
+                   int              type, 
+                   ptl_nid_t        nid,
+                   ptl_pid_t        pid,
+                   unsigned int     payload_niov,
+                   struct iovec    *payload_iov,
+                   ptl_kiov_t      *payload_kiov,
+                   size_t           payload_len)
 {
         kscimacnal_tx_t    *ktx=NULL;
         kscimacnal_data_t  *ksci = nal->nal_data;
@@ -198,12 +208,18 @@ kscimacnal_send(nal_cb_t        *nal,
         unsigned long   physaddr;
         
 
-        CDEBUG(D_NET, "sending %d bytes from %p to nid 0x%Lx niov: %d\n",
-               payload_len, payload_iov, nid, payload_niov);
+        CDEBUG(D_NET, "sending %d bytes from %p/%p to nid "LPX64" niov: %d\n",
+               payload_len, payload_iov, payload_kiov, nid, payload_niov);
 
+        /* Basic sanity checks */
         LASSERT(ksci != NULL);
-
         LASSERT(hdr != NULL);
+        LASSERT (payload_len == 0 || payload_niov > 0);
+        LASSERT (payload_niov <= PTL_MD_MAX_IOV);
+        /* It must be OK to kmap() if required */
+        LASSERT (payload_kiov == NULL || !in_interrupt ());
+        /* payload is either all vaddrs or all pages */
+        LASSERT (!(payload_kiov != NULL && payload_iov != NULL));
 
         /* Do real check if we can send this */
         if (buf_len > mac_get_mtusize(ksci->ksci_machandle)) {
@@ -219,6 +235,8 @@ kscimacnal_send(nal_cb_t        *nal,
                 return -ENOMEM;
         }
 
+        ktx->ktx_nmapped = 0; /* Start with no mapped pages :) */
+
         /* *SIGH* hdr is a stack variable in the calling function, so we
          * need to copy it to a buffer. Zerocopy magic (or is it just
          * deferred memcpy?) is annoying sometimes.  */
@@ -235,19 +253,34 @@ kscimacnal_send(nal_cb_t        *nal,
         lastblk=msg;
 
         /* Allocate additional mblks for each iov as needed.
-         * Essentially lib_copy_iov2buf with a twist or two */
+         * Essentially lib_copy_(k)iov2buf with a twist or two */
         while (payload_len > 0)
         {
-                ptl_size_t nob;
+                ptl_size_t       nob;
+                char            *addr;
 
                 LASSERT (payload_niov > 0);
 
-                nob = MIN (payload_iov->iov_len, payload_len);
+                if(payload_iov != NULL) {
+                        nob = MIN (payload_iov->iov_len, payload_len);
+                        addr = payload_iov->iov_base;
+                }
+                else {
+                        nob = MIN (payload_kiov->kiov_len, payload_len);
+                        /* Bollocks. We need to handle paged IO for things to
+                         * work but there is no good way to do this. We
+                         * do it by kmap():ing all pages and keep them
+                         * mapped until scimac is done with them. */
+                        /* FIXME: kunmap() on error */
+                        addr = kmap(payload_kiov->kiov_page);
+                        ktx->ktx_kpages[ktx->ktx_nmapped++] = 
+                                payload_kiov->kiov_page;
+                }
+                /* We don't need a callback on the additional mblks,
+                 * since all release callbacks seems to be called when
+                 * the entire message has been sent */
+                newblk=mac_alloc_mblk(addr, nob, NULL, NULL);
 
-                /* We don't need a callback on the additional mblks, since
-                 * all release callbacks seems to be called when the entire
-                 * message has been sent */
-                newblk=mac_alloc_mblk(payload_iov->iov_base, nob, NULL, NULL);
                 if(!newblk) {
                         mac_free_msg(msg);
                         PORTAL_FREE(ktx, (sizeof(kscimacnal_tx_t)));
@@ -259,9 +292,16 @@ kscimacnal_send(nal_cb_t        *nal,
 
                 payload_len -= nob;
                 payload_niov--;
-                payload_iov++;
+                if(payload_iov != NULL) {
+                        payload_iov++;
+                }
+                else {
+                        payload_kiov++;
+                }
         }
 
+        CDEBUG(D_NET, "kmapped %d pages\n", ktx->ktx_nmapped);
+
         ktx->ktx_nal = nal;
         ktx->ktx_private = private;
         ktx->ktx_cookie = cookie;
@@ -282,6 +322,39 @@ kscimacnal_send(nal_cb_t        *nal,
 }
 
 
+static int
+kscimacnal_send (nal_cb_t     *nal,
+                 void         *private,
+                 lib_msg_t    *cookie,
+                 ptl_hdr_t    *hdr,
+                 int           type,
+                 ptl_nid_t     nid,
+                 ptl_pid_t     pid,
+                 unsigned int  payload_niov,
+                 struct iovec *payload_iov,
+                 size_t        payload_nob)
+{
+        return (kscimacnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+                                payload_niov, payload_iov, NULL, payload_nob));
+}
+
+static int
+kscimacnal_send_pages (nal_cb_t     *nal,
+                       void         *private,
+                       lib_msg_t    *cookie,
+                       ptl_hdr_t    *hdr,
+                       int           type,
+                       ptl_nid_t     nid,
+                       ptl_pid_t     pid,
+                       unsigned int  payload_niov,
+                       ptl_kiov_t   *payload_kiov,
+                       size_t        payload_nob)
+{
+        return (kscimacnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+                                payload_niov, NULL, payload_kiov, payload_nob));
+}
+
+
 void
 kscimacnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
 {
@@ -366,19 +439,22 @@ kscimacnal_rx(mac_handle_t *handle, mac_mblk_t *msg, mac_msg_type_t type,
 
 
 /* Called by portals to process a recieved packet */
-static int kscimacnal_recv(nal_cb_t     *nal, 
-                      void         *private, 
-                      lib_msg_t    *cookie, 
-                      unsigned int  niov, 
-                      struct iovec *iov, 
-                      size_t        mlen, 
-                      size_t        rlen)
+inline static int 
+kscimacnal_recvmsg(nal_cb_t     *nal, 
+                   void         *private, 
+                   lib_msg_t    *cookie, 
+                   unsigned int  niov, 
+                   struct iovec *iov, 
+                   ptl_kiov_t   *kiov,
+                   size_t        mlen, 
+                   size_t        rlen)
 {
         kscimacnal_rx_t    *krx = private;
         mac_mblk_t      *mblk;
         void            *src;
         mac_size_t       pkt_len;
         ptl_size_t       iovused=0;
+        char            *base=NULL;
 
         LASSERT (krx != NULL);
         LASSERT (krx->msg != NULL);
@@ -393,6 +469,10 @@ static int kscimacnal_recv(nal_cb_t     *nal,
          */
         LASSERT (mlen==0 || mac_msg_size(krx->msg) >= sizeof(ptl_hdr_t)+rlen);
         LASSERT (mlen==0 || mlen <= rlen);
+        /* It must be OK to kmap() if required */
+        LASSERT (kiov == NULL || !in_interrupt ());
+        /* Either all pages or all vaddrs */
+        LASSERT (!(kiov != NULL && iov != NULL));
 
         PROF_START(memcpy);
 
@@ -407,36 +487,59 @@ static int kscimacnal_recv(nal_cb_t     *nal,
 
                 LASSERT(src != NULL);
 
-                /* Essentially lib_copy_buf2iov but with continuation support,
-                 * we "gracefully" thrash the argument vars ;) */
+                /* Essentially lib_copy_buf2(k)iov but with continuation
+                 * support, we "gracefully" thrash the argument vars ;) */
                 while (pkt_len > 0) {
-                        ptl_size_t nob;
+                        ptl_size_t  nob, len;
 
                         LASSERT (niov > 0);
 
-                        LASSERT(iovused < iov->iov_len);
+                        if(iov != NULL) {
+                                LASSERT(iovused < iov->iov_len);
+                                len = iov->iov_len;
+                                base = iov->iov_base;
+                        }
+                        else {
+                                LASSERT(iovused < kiov->kiov_len);
+                                len = kiov->kiov_len;
+                                if(base==NULL) {
+                                        /* New page */
+                                        base = kmap(kiov->kiov_page);
+                                }
+                        }
 
-                        nob = MIN (iov->iov_len-iovused, pkt_len);
-                        CDEBUG(D_NET, "iovbase: %p iovlen: %d src: %p  nob: %d "
+                        nob = MIN (len-iovused, pkt_len);
+                        CDEBUG(D_NET, "base: %p len: %d src: %p  nob: %d "
                                         "iovused: %d\n",
-                                        iov->iov_base, iov->iov_len,
-                                        src, nob, iovused);
+                                        base, len, src, nob, iovused);
 
-                        memcpy (iov->iov_base+iovused, src, nob);
+                        memcpy (base+iovused, src, nob);
                         pkt_len -= nob;
                         src += nob;
 
-                        if(nob+iovused < iov->iov_len) {
+                        if(nob+iovused < len) {
                                 /* We didn't use all of the iov */
                                 iovused+=nob;
                         }
                         else {
                                 niov--;
-                                iov++;
                                 iovused=0;
+                                if(iov != NULL) {
+                                        iov++;
+                                }
+                                else {
+                                        kunmap(kiov->kiov_page);
+                                        base=NULL;
+                                        kiov++;
+                                }
                         }
                 }
         }
+        /* Just to make sure the last page is unmapped */
+        if(kiov!=NULL && base!=NULL) {
+                kunmap(kiov->kiov_page);
+                base=NULL;
+        }
         PROF_FINISH(memcpy);
 
         CDEBUG(D_NET, "Calling lib_finalize.\n");
@@ -451,12 +554,38 @@ static int kscimacnal_recv(nal_cb_t     *nal,
 }
 
 
+static int
+kscimacnal_recv(nal_cb_t     *nal,
+             void         *private,
+             lib_msg_t    *cookie,
+             unsigned int  niov,
+             struct iovec *iov,
+             size_t        mlen,
+             size_t        rlen)
+{
+        return (kscimacnal_recvmsg (nal, private, cookie, niov, iov, NULL, mlen, rlen));
+}
+
+
+static int
+kscimacnal_recv_pages (nal_cb_t     *nal,
+                    void         *private,
+                    lib_msg_t    *cookie,
+                    unsigned int  niov,
+                    ptl_kiov_t   *kiov,
+                    size_t        mlen,
+                    size_t        rlen)
+{
+        return (kscimacnal_recvmsg (nal, private, cookie, niov, NULL, kiov, mlen, rlen));
+}
+
+
 nal_cb_t kscimacnal_lib = {
         nal_data:       &kscimacnal_data,               /* NAL private data */
         cb_send:         kscimacnal_send,
-        cb_send_pages:   NULL,                  /* Ignore for now */
+        cb_send_pages:   kscimacnal_send_pages,
         cb_recv:         kscimacnal_recv,
-        cb_recv_pages:   NULL,
+        cb_recv_pages:   kscimacnal_recv_pages,
         cb_read:         kscimacnal_read,
         cb_write:        kscimacnal_write,
         cb_malloc:       kscimacnal_malloc,
diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c
index 7a02735663cb5ae348cb7e672448ac7323de37ac..6f6fa7ebb5a2fbc3cc83d93e2cd9507d09b2ac1f 100644
--- a/lnet/klnds/socklnd/socklnd.c
+++ b/lnet/klnds/socklnd/socklnd.c
@@ -45,6 +45,8 @@ kpr_nal_interface_t ksocknal_router_interface = {
 #define SOCKNAL_SYSCTL_TIMEOUT     1
 #define SOCKNAL_SYSCTL_EAGER_ACK   2
 #define SOCKNAL_SYSCTL_ZERO_COPY   3
+#define SOCKNAL_SYSCTL_TYPED       4
+#define SOCKNAL_SYSCTL_MIN_BULK    5
 
 static ctl_table ksocknal_ctl_table[] = {
         {SOCKNAL_SYSCTL_TIMEOUT, "timeout", 
@@ -58,6 +60,12 @@ static ctl_table ksocknal_ctl_table[] = {
          &ksocknal_data.ksnd_zc_min_frag, sizeof (int),
          0644, NULL, &proc_dointvec},
 #endif
+        {SOCKNAL_SYSCTL_TYPED, "typed", 
+         &ksocknal_data.ksnd_typed_conns, sizeof (int),
+         0644, NULL, &proc_dointvec},
+        {SOCKNAL_SYSCTL_MIN_BULK, "min_bulk", 
+         &ksocknal_data.ksnd_min_bulk, sizeof (int),
+         0644, NULL, &proc_dointvec},
         { 0 }
 };
 
@@ -86,7 +94,7 @@ ksocknal_api_shutdown(nal_t *nal, int ni)
         CDEBUG (D_NET, "closing all connections\n");
 
         ksocknal_del_route (PTL_NID_ANY, 0, 0, 0);
-        ksocknal_close_conn (PTL_NID_ANY, 0);
+        ksocknal_close_matching_conns (PTL_NID_ANY, 0);
         return PTL_OK;
 }
 
@@ -186,7 +194,7 @@ ksocknal_bind_irq (unsigned int irq)
         snprintf (cmdline, sizeof (cmdline),
                   "echo %d > /proc/irq/%u/smp_affinity", 1 << info->ksni_sched, irq);
 
-        printk (KERN_INFO "Binding irq %u to CPU %d with cmd: %s\n",
+        printk (KERN_INFO "Lustre: Binding irq %u to CPU %d with cmd: %s\n",
                 irq, info->ksni_sched, cmdline);
 
         /* FIXME: Find a better method of setting IRQ affinity...
@@ -198,7 +206,7 @@ ksocknal_bind_irq (unsigned int irq)
 
 ksock_route_t *
 ksocknal_create_route (__u32 ipaddr, int port, int buffer_size,
-                       int nonagel, int xchange_nids, int irq_affinity, int eager)
+                       int nonagel, int irq_affinity, int eager)
 {
         ksock_route_t *route;
 
@@ -215,13 +223,12 @@ ksocknal_create_route (__u32 ipaddr, int port, int buffer_size,
         route->ksnr_port = port;
         route->ksnr_buffer_size = buffer_size;
         route->ksnr_irq_affinity = irq_affinity;
-        route->ksnr_xchange_nids = xchange_nids;
         route->ksnr_nonagel = nonagel;
         route->ksnr_eager = eager;
         route->ksnr_connecting = 0;
+        route->ksnr_connected = 0;
         route->ksnr_deleted = 0;
-        route->ksnr_generation = 0;
-        route->ksnr_conn = NULL;
+        route->ksnr_conn_count = 0;
 
         return (route);
 }
@@ -230,7 +237,6 @@ void
 ksocknal_destroy_route (ksock_route_t *route)
 {
         LASSERT (route->ksnr_sharecount == 0);
-        LASSERT (route->ksnr_conn == NULL);
 
         if (route->ksnr_peer != NULL)
                 ksocknal_put_peer (route->ksnr_peer);
@@ -397,8 +403,7 @@ ksocknal_get_route_by_idx (int index)
 
 int
 ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
-                    int nonagle, int xchange_nids, int bind_irq, 
-                    int share, int eager)
+                    int nonagle, int bind_irq, int share, int eager)
 {
         unsigned long      flags;
         ksock_peer_t      *peer;
@@ -415,8 +420,8 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
         if (peer == NULL)
                 return (-ENOMEM);
 
-        route = ksocknal_create_route (ipaddr, port, bufnob, nonagle,
-                                       xchange_nids, bind_irq, eager);
+        route = ksocknal_create_route (ipaddr, port, bufnob, 
+                                       nonagle, bind_irq, eager);
         if (route == NULL) {
                 ksocknal_put_peer (peer);
                 return (-ENOMEM);
@@ -455,7 +460,7 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
                 route->ksnr_peer = peer;
                 atomic_inc (&peer->ksnp_refcount);
                 /* peer's route list takes existing ref on route */
-                list_add (&route->ksnr_list, &peer->ksnp_routes);
+                list_add_tail (&route->ksnr_list, &peer->ksnp_routes);
         }
         
         route->ksnr_sharecount++;
@@ -468,8 +473,10 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
 void
 ksocknal_del_route_locked (ksock_route_t *route, int share, int keep_conn)
 {
-        ksock_peer_t *peer = route->ksnr_peer;
-        ksock_conn_t *conn = route->ksnr_conn;
+        ksock_peer_t     *peer = route->ksnr_peer;
+        ksock_conn_t     *conn;
+        struct list_head *ctmp;
+        struct list_head *cnxt;
 
         if (!share)
                 route->ksnr_sharecount = 0;
@@ -479,18 +486,22 @@ ksocknal_del_route_locked (ksock_route_t *route, int share, int keep_conn)
                         return;
         }
 
-        if (conn != NULL) {
-                if (!keep_conn)
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry(ctmp, ksock_conn_t, ksnc_list);
+
+                if (conn->ksnc_route != route)
+                        continue;
+                
+                if (!keep_conn) {
                         ksocknal_close_conn_locked (conn, 0);
-                else {
-                        /* keeping the conn; just dissociate it and route... */
-                        conn->ksnc_route = NULL;
-                        route->ksnr_conn = NULL;
-                        ksocknal_put_route (route); /* drop conn's ref on route */
-                        ksocknal_put_conn (conn); /* drop route's ref on conn */
+                        continue;
                 }
+                
+                /* keeping the conn; just dissociate it and route... */
+                conn->ksnc_route = NULL;
+                ksocknal_put_route (route); /* drop conn's ref on route */
         }
-
+        
         route->ksnr_deleted = 1;
         list_del (&route->ksnr_list);
         ksocknal_put_route (route);             /* drop peer's ref */
@@ -669,9 +680,11 @@ ksocknal_choose_scheduler_locked (unsigned int irq)
 }
 
 int
-ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
-                      struct socket *sock, int bind_irq)
+ksocknal_create_conn (ksock_route_t *route, struct socket *sock,
+                      int bind_irq, int type)
 {
+        ptl_nid_t          nid;
+        __u64              incarnation;
         unsigned long      flags;
         ksock_conn_t      *conn;
         ksock_peer_t      *peer;
@@ -692,6 +705,19 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
         if (rc != 0)
                 return (rc);
 
+        if (route == NULL) {
+                /* acceptor or explicit connect */
+                nid = PTL_NID_ANY;
+        } else {
+                LASSERT (type != SOCKNAL_CONN_NONE);
+                /* autoconnect: expect this nid on exchange */
+                nid = route->ksnr_peer->ksnp_nid;
+        }
+
+        rc = ksocknal_hello (sock, &nid, &type, &incarnation);
+        if (rc != 0)
+                return (rc);
+        
         peer = NULL;
         if (route == NULL) {                    /* not autoconnect */
                 /* Assume this socket connects to a brand new peer */
@@ -711,6 +737,8 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
         conn->ksnc_peer = NULL;
         conn->ksnc_route = NULL;
         conn->ksnc_sock = sock;
+        conn->ksnc_type = type;
+        conn->ksnc_incarnation = incarnation;
         conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;
         conn->ksnc_saved_write_space = sock->sk->sk_write_space;
         atomic_set (&conn->ksnc_refcount, 1);    /* 1 ref for me */
@@ -732,7 +760,8 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
 
         if (route != NULL) {
                 /* Autoconnected! */
-                LASSERT (route->ksnr_conn == NULL && route->ksnr_connecting);
+                LASSERT ((route->ksnr_connected & (1 << type)) == 0);
+                LASSERT ((route->ksnr_connecting & (1 << type)) != 0);
 
                 if (route->ksnr_deleted) {
                         /* This conn was autoconnected, but the autoconnect
@@ -745,14 +774,13 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
                 }
 
 
-                /* associate conn/route for auto-reconnect */
-                route->ksnr_conn = conn;
-                atomic_inc (&conn->ksnc_refcount);
+                /* associate conn/route */
                 conn->ksnc_route = route;
                 atomic_inc (&route->ksnr_refcount);
-                route->ksnr_connecting = 0;
 
-                route->ksnr_generation++;
+                route->ksnr_connecting &= ~(1 << type);
+                route->ksnr_connected  |= (1 << type);
+                route->ksnr_conn_count++;
                 route->ksnr_retry_interval = SOCKNAL_MIN_RECONNECT_INTERVAL;
 
                 peer = route->ksnr_peer;
@@ -803,8 +831,13 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
                 ksocknal_queue_tx_locked (tx, conn);
         }
 
+        rc = ksocknal_close_stale_conns_locked (peer, incarnation);
+
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
+        if (rc != 0)
+                CERROR ("Closed %d stale conns to "LPX64"\n", rc, nid);
+
         if (bind_irq)                           /* irq binding required */
                 ksocknal_bind_irq (irq);
 
@@ -836,14 +869,17 @@ ksocknal_close_conn_locked (ksock_conn_t *conn, int error)
         route = conn->ksnc_route;
         if (route != NULL) {
                 /* dissociate conn from route... */
-                LASSERT (!route->ksnr_connecting &&
-                         !route->ksnr_deleted);
+                LASSERT (!route->ksnr_deleted);
+                LASSERT ((route->ksnr_connecting & (1 << conn->ksnc_type)) == 0);
+                LASSERT ((route->ksnr_connected & (1 << conn->ksnc_type)) != 0);
 
-                route->ksnr_conn = NULL;
+                route->ksnr_connected &= ~(1 << conn->ksnc_type);
                 conn->ksnc_route = NULL;
 
+                list_del (&route->ksnr_list);   /* make route least favourite */
+                list_add_tail (&route->ksnr_list, &peer->ksnp_routes);
+                
                 ksocknal_put_route (route);     /* drop conn's ref on route */
-                ksocknal_put_conn (conn);       /* drop route's ref on conn */
         }
 
         /* ksnd_deathrow_conns takes over peer's ref */
@@ -869,24 +905,6 @@ ksocknal_close_conn_locked (ksock_conn_t *conn, int error)
         spin_unlock (&ksocknal_data.ksnd_reaper_lock);
 }
 
-int
-ksocknal_close_conn_unlocked (ksock_conn_t *conn, int why) 
-{
-        unsigned long flags;
-        int           did_it = 0;
-        
-        write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
-                
-        if (!conn->ksnc_closing) {
-                did_it = 1;
-                ksocknal_close_conn_locked (conn, why);
-        }
-        
-        write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
-
-        return (did_it);
-}
-
 void
 ksocknal_terminate_conn (ksock_conn_t *conn)
 {
@@ -896,15 +914,34 @@ ksocknal_terminate_conn (ksock_conn_t *conn)
          * destroy it. */
         unsigned long   flags;
         ksock_peer_t   *peer = conn->ksnc_peer;
+        ksock_sched_t  *sched = conn->ksnc_scheduler;
         struct timeval  now;
         time_t          then = 0;
         int             notify = 0;
 
+        LASSERT(conn->ksnc_closing);
+
+        /* wake up the scheduler to "send" all remaining packets to /dev/null */
+        spin_lock_irqsave(&sched->kss_lock, flags);
+
+        if (!conn->ksnc_tx_scheduled &&
+            !list_empty(&conn->ksnc_tx_queue)){
+                list_add_tail (&conn->ksnc_tx_list,
+                               &sched->kss_tx_conns);
+                /* a closing conn is always ready to tx */
+                conn->ksnc_tx_ready = 1;
+                conn->ksnc_tx_scheduled = 1;
+                /* extra ref for scheduler */
+                atomic_inc (&conn->ksnc_refcount);
+
+                wake_up (&sched->kss_waitq);
+        }
+
+        spin_unlock_irqrestore (&sched->kss_lock, flags);
+
         /* serialise with callbacks */
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
-        LASSERT (conn->ksnc_closing);
-        
         /* Remove conn's network callbacks.
          * NB I _have_ to restore the callback, rather than storing a noop,
          * since the socket could survive past this module being unloaded!! */
@@ -916,6 +953,8 @@ ksocknal_terminate_conn (ksock_conn_t *conn)
          * sk_user_data is NULL. */
         conn->ksnc_sock->sk->sk_user_data = NULL;
 
+        /* OK, so this conn may not be completely disengaged from its
+         * scheduler yet, but it _has_ committed to terminate... */
         conn->ksnc_scheduler->kss_nconns--;
 
         if (peer->ksnp_error != 0) {
@@ -952,26 +991,20 @@ ksocknal_destroy_conn (ksock_conn_t *conn)
         LASSERT (conn->ksnc_route == NULL);
         LASSERT (!conn->ksnc_tx_scheduled);
         LASSERT (!conn->ksnc_rx_scheduled);
-
-        /* complete queued packets */
-        while (!list_empty (&conn->ksnc_tx_queue)) {
-                ksock_tx_t *tx = list_entry (conn->ksnc_tx_queue.next,
-                                             ksock_tx_t, tx_list);
-
-                CERROR ("Deleting packet type %d len %d ("LPX64"->"LPX64")\n",
-                        NTOH__u32 (tx->tx_hdr->type),
-                        NTOH__u32 (PTL_HDR_LENGTH(tx->tx_hdr)),
-                        NTOH__u64 (tx->tx_hdr->src_nid),
-                        NTOH__u64 (tx->tx_hdr->dest_nid));
-
-                list_del (&tx->tx_list);
-                ksocknal_tx_done (tx, 0);
-        }
+        LASSERT (list_empty(&conn->ksnc_tx_queue));
 
         /* complete current receive if any */
         switch (conn->ksnc_rx_state) {
         case SOCKNAL_RX_BODY:
+#if 0
                 lib_finalize (&ksocknal_lib, NULL, conn->ksnc_cookie);
+#else
+                CERROR ("Refusing to complete a partial receive from "
+                        LPX64", ip %08x\n", conn->ksnc_peer->ksnp_nid,
+                        conn->ksnc_ipaddr);
+                CERROR ("This may hang communications and "
+                        "prevent modules from unloading\n");
+#endif
                 break;
         case SOCKNAL_RX_BODY_FWD:
                 ksocknal_fmb_callback (conn->ksnc_cookie, -ECONNABORTED);
@@ -1012,19 +1045,75 @@ ksocknal_put_conn (ksock_conn_t *conn)
 }
 
 int
-ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr)
+ksocknal_close_peer_conns_locked (ksock_peer_t *peer, __u32 ipaddr, int why)
+{
+        ksock_conn_t       *conn;
+        struct list_head   *ctmp;
+        struct list_head   *cnxt;
+        int                 count = 0;
+
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+                if (ipaddr == 0 ||
+                    conn->ksnc_ipaddr == ipaddr) {
+                        count++;
+                        ksocknal_close_conn_locked (conn, why);
+                }
+        }
+
+        return (count);
+}
+
+int
+ksocknal_close_stale_conns_locked (ksock_peer_t *peer, __u64 incarnation)
 {
-        unsigned long       flags;
         ksock_conn_t       *conn;
         struct list_head   *ctmp;
         struct list_head   *cnxt;
+        int                 count = 0;
+
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+                if (conn->ksnc_incarnation == incarnation)
+                        continue;
+                
+                count++;
+                ksocknal_close_conn_locked (conn, -ESTALE);
+        }
+
+        return (count);
+}
+
+int
+ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why) 
+{
+        ksock_peer_t     *peer = conn->ksnc_peer;
+        __u32             ipaddr = conn->ksnc_ipaddr;
+        unsigned long     flags;
+        int               count;
+
+        write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
+
+        count = ksocknal_close_peer_conns_locked (peer, ipaddr, why);
+        
+        write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
+
+        return (count);
+}
+
+int
+ksocknal_close_matching_conns (ptl_nid_t nid, __u32 ipaddr)
+{
+        unsigned long       flags;
         ksock_peer_t       *peer;
         struct list_head   *ptmp;
         struct list_head   *pnxt;
         int                 lo;
         int                 hi;
         int                 i;
-        int                 rc = -ENOENT;
+        int                 count = 0;
 
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
@@ -1043,24 +1132,17 @@ ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr)
                         if (!(nid == PTL_NID_ANY || nid == peer->ksnp_nid))
                                 continue;
 
-                        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
-
-                                conn = list_entry (ctmp, ksock_conn_t,
-                                                   ksnc_list);
-
-                                if (!(ipaddr == 0 ||
-                                      conn->ksnc_ipaddr == ipaddr))
-                                        continue;
-
-                                rc = 0;
-                                ksocknal_close_conn_locked (conn, 0);
-                        }
+                        count += ksocknal_close_peer_conns_locked (peer, ipaddr, 0);
                 }
         }
 
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
-        return (rc);
+        /* wildcards always succeed */
+        if (nid == PTL_NID_ANY || ipaddr == 0)
+                return (0);
+        
+        return (count == 0 ? -ENOENT : 0);
 }
 
 void
@@ -1073,7 +1155,7 @@ ksocknal_notify (void *arg, ptl_nid_t gw_nid, int alive)
 
         if (!alive) {
                 /* If the gateway crashed, close all open connections... */
-                ksocknal_close_conn (gw_nid, 0);
+                ksocknal_close_matching_conns (gw_nid, 0);
                 return;
         }
         
@@ -1216,85 +1298,95 @@ ksocknal_push (ptl_nid_t nid)
 }
 
 int
-ksocknal_cmd(struct portal_ioctl_data * data, void * private)
+ksocknal_cmd(struct portals_cfg *pcfg, void * private)
 {
         int rc = -EINVAL;
 
-        LASSERT (data != NULL);
+        LASSERT (pcfg != NULL);
 
-        switch(data->ioc_nal_cmd) {
+        switch(pcfg->pcfg_command) {
         case NAL_CMD_GET_AUTOCONN: {
-                ksock_route_t *route = ksocknal_get_route_by_idx (data->ioc_count);
+                ksock_route_t *route = ksocknal_get_route_by_idx (pcfg->pcfg_count);
 
                 if (route == NULL)
                         rc = -ENOENT;
                 else {
                         rc = 0;
-                        data->ioc_nid   = route->ksnr_peer->ksnp_nid;
-                        data->ioc_id    = route->ksnr_ipaddr;
-                        data->ioc_misc  = route->ksnr_port;
-                        data->ioc_count = route->ksnr_generation;
-                        data->ioc_size  = route->ksnr_buffer_size;
-                        data->ioc_wait  = route->ksnr_sharecount;
-                        data->ioc_flags = (route->ksnr_nonagel      ? 1 : 0) |
-                                          (route->ksnr_xchange_nids ? 2 : 0) |
-                                          (route->ksnr_irq_affinity ? 4 : 0) |
-                                          (route->ksnr_eager        ? 8 : 0);
+                        pcfg->pcfg_nid   = route->ksnr_peer->ksnp_nid;
+                        pcfg->pcfg_id    = route->ksnr_ipaddr;
+                        pcfg->pcfg_misc  = route->ksnr_port;
+                        pcfg->pcfg_count = route->ksnr_conn_count;
+                        pcfg->pcfg_size  = route->ksnr_buffer_size;
+                        pcfg->pcfg_wait  = route->ksnr_sharecount;
+                        pcfg->pcfg_flags = (route->ksnr_nonagel      ? 1 : 0) |
+                                           (route->ksnr_irq_affinity ? 2 : 0) |
+                                           (route->ksnr_eager        ? 4 : 0);
                         ksocknal_put_route (route);
                 }
                 break;
         }
         case NAL_CMD_ADD_AUTOCONN: {
-                rc = ksocknal_add_route (data->ioc_nid, data->ioc_id,
-                                         data->ioc_misc, data->ioc_size,
-                                         (data->ioc_flags & 0x01) != 0,
-                                         (data->ioc_flags & 0x02) != 0,
-                                         (data->ioc_flags & 0x04) != 0,
-                                         (data->ioc_flags & 0x08) != 0,
-                                         (data->ioc_flags & 0x10) != 0);
+                rc = ksocknal_add_route (pcfg->pcfg_nid, pcfg->pcfg_id,
+                                         pcfg->pcfg_misc, pcfg->pcfg_size,
+                                         (pcfg->pcfg_flags & 0x01) != 0,
+                                         (pcfg->pcfg_flags & 0x02) != 0,
+                                         (pcfg->pcfg_flags & 0x04) != 0,
+                                         (pcfg->pcfg_flags & 0x08) != 0);
                 break;
         }
         case NAL_CMD_DEL_AUTOCONN: {
-                rc = ksocknal_del_route (data->ioc_nid, data->ioc_id, 
-                                         (data->ioc_flags & 1) != 0,
-                                         (data->ioc_flags & 2) != 0);
+                rc = ksocknal_del_route (pcfg->pcfg_nid, pcfg->pcfg_id, 
+                                         (pcfg->pcfg_flags & 1) != 0,
+                                         (pcfg->pcfg_flags & 2) != 0);
                 break;
         }
         case NAL_CMD_GET_CONN: {
-                ksock_conn_t *conn = ksocknal_get_conn_by_idx (data->ioc_count);
+                ksock_conn_t *conn = ksocknal_get_conn_by_idx (pcfg->pcfg_count);
 
                 if (conn == NULL)
                         rc = -ENOENT;
                 else {
                         rc = 0;
-                        data->ioc_nid  = conn->ksnc_peer->ksnp_nid;
-                        data->ioc_id   = conn->ksnc_ipaddr;
-                        data->ioc_misc = conn->ksnc_port;
+                        pcfg->pcfg_nid   = conn->ksnc_peer->ksnp_nid;
+                        pcfg->pcfg_id    = conn->ksnc_ipaddr;
+                        pcfg->pcfg_misc  = conn->ksnc_port;
+                        pcfg->pcfg_flags = conn->ksnc_type;
                         ksocknal_put_conn (conn);
                 }
                 break;
         }
         case NAL_CMD_REGISTER_PEER_FD: {
-                struct socket *sock = sockfd_lookup (data->ioc_fd, &rc);
+                struct socket *sock = sockfd_lookup (pcfg->pcfg_fd, &rc);
+                int            type = pcfg->pcfg_misc;
 
-                if (sock != NULL) {
-                        rc = ksocknal_create_conn (data->ioc_nid, NULL,
-                                                   sock, data->ioc_flags);
-                        if (rc != 0)
-                                fput (sock->file);
+                if (sock == NULL)
+                        break;
+
+                switch (type) {
+                case SOCKNAL_CONN_NONE:
+                case SOCKNAL_CONN_ANY:
+                case SOCKNAL_CONN_CONTROL:
+                case SOCKNAL_CONN_BULK_IN:
+                case SOCKNAL_CONN_BULK_OUT:
+                        rc = ksocknal_create_conn(NULL, sock, pcfg->pcfg_flags, type);
+                default:
+                        break;
                 }
+                if (rc != 0)
+                        fput (sock->file);
                 break;
         }
         case NAL_CMD_CLOSE_CONNECTION: {
-                rc = ksocknal_close_conn (data->ioc_nid, data->ioc_id);
+                rc = ksocknal_close_matching_conns (pcfg->pcfg_nid, 
+                                                    pcfg->pcfg_id);
                 break;
         }
         case NAL_CMD_REGISTER_MYNID: {
-                rc = ksocknal_set_mynid (data->ioc_nid);
+                rc = ksocknal_set_mynid (pcfg->pcfg_nid);
                 break;
         }
         case NAL_CMD_PUSH_CONNECTION: {
-                rc = ksocknal_push (data->ioc_nid);
+                rc = ksocknal_push (pcfg->pcfg_nid);
                 break;
         }
         }
@@ -1337,7 +1429,7 @@ ksocknal_free_buffers (void)
                      ksocknal_data.ksnd_peer_hash_size);
 }
 
-void /*__exit*/
+void
 ksocknal_module_fini (void)
 {
         int   i;
@@ -1416,11 +1508,27 @@ ksocknal_module_fini (void)
         CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
                atomic_read (&portal_kmemory));
 
-        printk(KERN_INFO "Routing socket NAL unloaded (final mem %d)\n",
+        printk(KERN_INFO "Lustre: Routing socket NAL unloaded (final mem %d)\n",
                atomic_read(&portal_kmemory));
 }
 
 
+void __init
+ksocknal_init_incarnation (void)
+{
+        struct timeval tv;
+
+        /* The incarnation number is the time this module loaded and it
+         * identifies this particular instance of the socknal.  Hopefully
+         * we won't be able to reboot more frequently than 1MHz for the
+         * forseeable future :) */
+        
+        do_gettimeofday(&tv);
+        
+        ksocknal_data.ksnd_incarnation = 
+                (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
+}
+
 int __init
 ksocknal_module_init (void)
 {
@@ -1434,7 +1542,9 @@ ksocknal_module_init (void)
         /* the following must be sizeof(int) for proc_dointvec() */
         LASSERT(sizeof (ksocknal_data.ksnd_io_timeout) == sizeof (int));
         LASSERT(sizeof (ksocknal_data.ksnd_eager_ack) == sizeof (int));
-
+        /* check ksnr_connected/connecting field large enough */
+        LASSERT(SOCKNAL_CONN_NTYPES <= 4);
+        
         LASSERT (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING);
 
         ksocknal_api.forward  = ksocknal_api_forward;
@@ -1451,10 +1561,13 @@ ksocknal_module_init (void)
 
         ksocknal_data.ksnd_io_timeout = SOCKNAL_IO_TIMEOUT;
         ksocknal_data.ksnd_eager_ack  = SOCKNAL_EAGER_ACK;
+        ksocknal_data.ksnd_typed_conns = SOCKNAL_TYPED_CONNS;
+        ksocknal_data.ksnd_min_bulk   = SOCKNAL_MIN_BULK;
 #if SOCKNAL_ZC
         ksocknal_data.ksnd_zc_min_frag = SOCKNAL_ZC_MIN_FRAG;
 #endif
-
+        ksocknal_init_incarnation();
+        
         ksocknal_data.ksnd_peer_hash_size = SOCKNAL_PEER_HASH_SIZE;
         PORTAL_ALLOC (ksocknal_data.ksnd_peers,
                       sizeof (struct list_head) * ksocknal_data.ksnd_peer_hash_size);
@@ -1643,9 +1756,9 @@ ksocknal_module_init (void)
 #endif
         /* flag everything initialised */
         ksocknal_data.ksnd_init = SOCKNAL_INIT_ALL;
-        
-        printk(KERN_INFO "Routing socket NAL loaded (Routing %s, initial "
-               "mem %d)\n",
+
+        printk(KERN_INFO "Lustre: Routing socket NAL loaded "
+               "(Routing %s, initial mem %d)\n",
                kpr_routing (&ksocknal_data.ksnd_router) ?
                "enabled" : "disabled", pkmem);
 
diff --git a/lnet/klnds/socklnd/socklnd.h b/lnet/klnds/socklnd/socklnd.h
index abd8e7b718c211e15b35b6f23aafb48f82c2fd2c..227a24ff6fb781341820faac491bb4e557d4f59c 100644
--- a/lnet/klnds/socklnd/socklnd.h
+++ b/lnet/klnds/socklnd/socklnd.h
@@ -25,7 +25,9 @@
  */
 
 #define DEBUG_PORTAL_ALLOC
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -58,9 +60,10 @@
 #include <linux/kp30.h>
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
+#include <portals/socknal.h>
 
 #if CONFIG_SMP
-# define SOCKNAL_N_SCHED        smp_num_cpus    /* # socknal schedulers */
+# define SOCKNAL_N_SCHED       num_online_cpus() /* # socknal schedulers */
 #else
 # define SOCKNAL_N_SCHED        1               /* # socknal schedulers */
 #endif
@@ -71,19 +74,14 @@
 
 /* default vals for runtime tunables */
 #define SOCKNAL_IO_TIMEOUT       50             /* default comms timeout (seconds) */
-#define SOCKNAL_EAGER_ACK        1              /* default eager ack (boolean) */
+#define SOCKNAL_EAGER_ACK        0              /* default eager ack (boolean) */
+#define SOCKNAL_TYPED_CONNS      1              /* unidirectional large, bidirectional small? */
 #define SOCKNAL_ZC_MIN_FRAG     (2<<10)         /* default smallest zerocopy fragment */
-
+#define SOCKNAL_MIN_BULK        (1<<10)         /* smallest "large" message */
 #define SOCKNAL_USE_KEEPALIVES   0              /* use tcp/ip keepalive? */
 
 #define SOCKNAL_PEER_HASH_SIZE   101            /* # peer lists */
 
-#if PTL_LARGE_MTU
-# define SOCKNAL_MAX_FWD_PAYLOAD (256<<10)      /* biggest payload I can forward */
-#else
-# define SOCKNAL_MAX_FWD_PAYLOAD (64<<10)       /* biggest payload I can forward */
-#endif
-
 #define SOCKNAL_NLTXS           128             /* # normal transmit messages */
 #define SOCKNAL_NNBLK_LTXS	128             /* # transmit messages reserved if can't block */
 
@@ -92,7 +90,7 @@
 
 #define SOCKNAL_SMALL_FWD_PAGES	1               /* # pages in a small message fwd buffer */
 
-#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + SOCKNAL_MAX_FWD_PAYLOAD) >> PAGE_SHIFT)
+#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
 						/* # pages in a large message fwd buffer */
 
 #define SOCKNAL_RESCHED         100             /* # scheduler loops before reschedule */
@@ -108,6 +106,10 @@
 # define sk_socket      socket
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# define sk_wmem_queued wmem_queued
+#endif
+
 typedef struct                                  /* pool of forwarding buffers */
 {
         spinlock_t        fmp_lock;             /* serialise */
@@ -138,10 +140,13 @@ typedef struct {
         int               ksnd_init;            /* initialisation state */
         int               ksnd_io_timeout;      /* "stuck" socket timeout (seconds) */
         int               ksnd_eager_ack;       /* make TCP ack eagerly? */
+        int               ksnd_typed_conns;     /* drive sockets by type? */
+        int               ksnd_min_bulk;        /* smallest "large" message */
 #if SOCKNAL_ZC
         unsigned int      ksnd_zc_min_frag;     /* minimum zero copy frag size */
 #endif
         struct ctl_table_header *ksnd_sysctl;   /* sysctl interface */
+        __u64             ksnd_incarnation;     /* my epoch */
         
         rwlock_t          ksnd_global_lock;     /* stabilize peer/conn ops */
         struct list_head *ksnd_peers;           /* hash table of all my known peers */
@@ -296,8 +301,10 @@ typedef struct ksock_conn
         __u32               ksnc_ipaddr;        /* peer's IP */
         int                 ksnc_port;          /* peer's port */
         int                 ksnc_closing;       /* being shut down */
+        int                 ksnc_type;          /* type of connection */
+        __u64               ksnc_incarnation;   /* peer's incarnation */
         
-        /* READER */
+        /* reader */
         struct list_head    ksnc_rx_list;       /* where I enq waiting input or a forwarding descriptor */
         unsigned long       ksnc_rx_deadline;   /* when (in jiffies) receive times out */
         int                 ksnc_rx_started;    /* started receiving a message */
@@ -323,6 +330,10 @@ typedef struct ksock_conn
         int                 ksnc_tx_scheduled;  /* being progressed */
 } ksock_conn_t;
 
+#define KSNR_TYPED_ROUTES   ((1 << SOCKNAL_CONN_CONTROL) |      \
+                             (1 << SOCKNAL_CONN_BULK_IN) |      \
+                             (1 << SOCKNAL_CONN_BULK_OUT))
+
 typedef struct ksock_route
 {
         struct list_head    ksnr_list;          /* chain on peer route list */
@@ -336,13 +347,12 @@ typedef struct ksock_route
         int                 ksnr_port;          /* port to connect to */
         int                 ksnr_buffer_size;   /* size of socket buffers */
         unsigned int        ksnr_irq_affinity:1; /* set affinity? */
-        unsigned int        ksnr_xchange_nids:1; /* do hello protocol? */
         unsigned int        ksnr_nonagel:1;     /* disable nagle? */
         unsigned int        ksnr_eager:1;       /* connect eagery? */
-        unsigned int        ksnr_connecting:1;  /* autoconnect in progress? */
+        unsigned int        ksnr_connecting:4;  /* autoconnects in progress by type */
+        unsigned int        ksnr_connected:4;   /* connections established by type */
         unsigned int        ksnr_deleted:1;     /* been removed from peer? */
-        int                 ksnr_generation;    /* connection incarnation # */
-        ksock_conn_t       *ksnr_conn;          /* NULL/active connection */
+        int                 ksnr_conn_count;    /* # conns established by this route */
 } ksock_route_t;
 
 typedef struct ksock_peer
@@ -397,14 +407,15 @@ extern ksock_peer_t *ksocknal_find_peer_locked (ptl_nid_t nid);
 extern ksock_peer_t *ksocknal_get_peer (ptl_nid_t nid);
 extern int ksocknal_del_route (ptl_nid_t nid, __u32 ipaddr,
                                int single, int keep_conn);
-extern int ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
-                                 struct socket *sock, int bind_irq);
+extern int ksocknal_create_conn (ksock_route_t *route,
+                                 struct socket *sock, int bind_irq, int type);
 extern void ksocknal_close_conn_locked (ksock_conn_t *conn, int why);
-extern int ksocknal_close_conn_unlocked (ksock_conn_t *conn, int why);
 extern void ksocknal_terminate_conn (ksock_conn_t *conn);
 extern void ksocknal_destroy_conn (ksock_conn_t *conn);
 extern void ksocknal_put_conn (ksock_conn_t *conn);
-extern int ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr);
+extern int ksocknal_close_stale_conns_locked (ksock_peer_t *peer, __u64 incarnation);
+extern int ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why);
+extern int ksocknal_close_matching_conns (ptl_nid_t nid, __u32 ipaddr);
 
 extern void ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn);
 extern void ksocknal_tx_done (ksock_tx_t *tx, int asynch);
@@ -419,3 +430,5 @@ extern void ksocknal_write_space(struct sock *sk);
 extern int ksocknal_autoconnectd (void *arg);
 extern int ksocknal_reaper (void *arg);
 extern int ksocknal_setup_sock (struct socket *sock);
+extern int ksocknal_hello (struct socket *sock, 
+                           ptl_nid_t *nid, int *type, __u64 *incarnation);
diff --git a/lnet/klnds/socklnd/socklnd_cb.c b/lnet/klnds/socklnd/socklnd_cb.c
index bc52a5ce2811e158bae957becfb7f7793187da66..6ea4fa8d126f0e1b29220f6c812efc4f23ff08e3 100644
--- a/lnet/klnds/socklnd/socklnd_cb.c
+++ b/lnet/klnds/socklnd/socklnd_cb.c
@@ -218,9 +218,9 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
         struct iovec  *iov = tx->tx_iov;
         int            fragsize = iov->iov_len;
         unsigned long  vaddr = (unsigned long)iov->iov_base;
-        int            more = (!list_empty (&conn->ksnc_tx_queue)) |
-                              (tx->tx_niov > 1) |
-                              (tx->tx_nkiov > 1);
+        int            more = (tx->tx_niov > 1) || 
+                              (tx->tx_nkiov > 0) ||
+                              (!list_empty (&conn->ksnc_tx_queue));
 #if SOCKNAL_ZC
         int            offset = vaddr & (PAGE_SIZE - 1);
         int            zcsize = MIN (fragsize, PAGE_SIZE - offset);
@@ -266,7 +266,7 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
                         .msg_flags      = more ? (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT
                 };
                 mm_segment_t oldmm = get_fs();
-                
+
                 set_fs (KERNEL_DS);
                 rc = sock_sendmsg(sock, &msg, fragsize);
                 set_fs (oldmm);
@@ -298,8 +298,8 @@ ksocknal_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
         int            fragsize = kiov->kiov_len;
         struct page   *page = kiov->kiov_page;
         int            offset = kiov->kiov_offset;
-        int            more = (!list_empty (&conn->ksnc_tx_queue)) |
-                              (tx->tx_nkiov > 1);
+        int            more = (tx->tx_nkiov > 1) ||
+                              (!list_empty (&conn->ksnc_tx_queue));
         int            rc;
 
         /* NB we can't trust socket ops to either consume our iovs
@@ -464,7 +464,7 @@ ksocknal_recv_iov (ksock_conn_t *conn)
          * or leave them alone, so we only receive 1 frag at a time. */
         LASSERT (conn->ksnc_rx_niov > 0);
         LASSERT (fragsize <= conn->ksnc_rx_nob_wanted);
-        
+
         set_fs (KERNEL_DS);
         rc = sock_recvmsg (conn->ksnc_sock, &msg, fragsize, MSG_DONTWAIT);
         /* NB this is just a boolean............................^ */
@@ -521,7 +521,7 @@ ksocknal_recv_kiov (ksock_conn_t *conn)
         LASSERT (fragsize <= conn->ksnc_rx_nob_wanted);
         LASSERT (conn->ksnc_rx_nkiov > 0);
         LASSERT (offset + fragsize <= PAGE_SIZE);
-        
+
         set_fs (KERNEL_DS);
         rc = sock_recvmsg (conn->ksnc_sock, &msg, fragsize, MSG_DONTWAIT);
         /* NB this is just a boolean............................^ */
@@ -597,7 +597,7 @@ ksocknal_recvmsg (ksock_conn_t *conn)
 
                 if (conn->ksnc_rx_nob_wanted == 0) {
                         /* Completed a message segment (header or payload) */
-                        if (ksocknal_data.ksnd_eager_ack &&
+                        if ((ksocknal_data.ksnd_eager_ack & conn->ksnc_type) != 0 &&
                             (conn->ksnc_rx_state ==  SOCKNAL_RX_BODY ||
                              conn->ksnc_rx_state == SOCKNAL_RX_BODY_FWD)) {
                                 /* Remind the socket to ack eagerly... */
@@ -691,71 +691,37 @@ ksocknal_tx_launched (ksock_tx_t *tx)
         ksocknal_tx_done (tx, 0);
 }
 
-void
-ksocknal_process_transmit (ksock_sched_t *sched, unsigned long *irq_flags)
+int
+ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
 {
-        ksock_conn_t  *conn;
-        ksock_tx_t    *tx;
         int            rc;
-        
-        LASSERT (!list_empty (&sched->kss_tx_conns));
-        conn = list_entry(sched->kss_tx_conns.next, ksock_conn_t, ksnc_tx_list);
-        list_del (&conn->ksnc_tx_list);
-
-        LASSERT (conn->ksnc_tx_scheduled);
-        LASSERT (conn->ksnc_tx_ready);
-        LASSERT (!list_empty (&conn->ksnc_tx_queue));
-        tx = list_entry (conn->ksnc_tx_queue.next, ksock_tx_t, tx_list);
-        /* assume transmit will complete now, so dequeue while I've got lock */
-        list_del (&tx->tx_list);
-
-        spin_unlock_irqrestore (&sched->kss_lock, *irq_flags);
-
-        LASSERT (tx->tx_resid > 0);
-
-        conn->ksnc_tx_ready = 0;/* write_space may race with me and set ready */
-        mb();                   /* => clear BEFORE trying to write */
-
+       
         rc = ksocknal_sendmsg (conn, tx);
 
         CDEBUG (D_NET, "send(%d) %d\n", tx->tx_resid, rc);
+        LASSERT (rc != -EAGAIN);
 
-        if (rc != 0) {
-                if (ksocknal_close_conn_unlocked (conn, rc)) {
-                        /* I'm the first to close */
-                        CERROR ("[%p] Error %d on write to "LPX64" ip %08x:%d\n",
-                                conn, rc, conn->ksnc_peer->ksnp_nid,
-                                conn->ksnc_ipaddr, conn->ksnc_port);
+        if (rc == 0) {
+                /* no errors */
+                if (tx->tx_resid != 0) {
+                        /* didn't send everything */
+                        return (-EAGAIN);
                 }
+                
                 ksocknal_tx_launched (tx);
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
+                return (0);
+        }
 
-        } else if (tx->tx_resid == 0) {  
-                /* everything went; assume more can go, and avoid
-                 * write_space locking */
-                conn->ksnc_tx_ready = 1;
+        if (!conn->ksnc_closing)
+                CERROR ("[%p] Error %d on write to "LPX64" ip %08x:%d\n",
+                        conn, rc, conn->ksnc_peer->ksnp_nid,
+                        conn->ksnc_ipaddr, conn->ksnc_port);
 
-                ksocknal_tx_launched (tx);
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-        } else {
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
+        ksocknal_close_conn_and_siblings (conn, rc);
+        ksocknal_tx_launched (tx);
 
-                /* back onto HEAD of tx_queue */
-                list_add (&tx->tx_list, &conn->ksnc_tx_queue);
-        }
-
-        /* no space to write, or nothing to write? */
-        if (!conn->ksnc_tx_ready ||
-            list_empty (&conn->ksnc_tx_queue)) {
-                /* mark not scheduled */
-                conn->ksnc_tx_scheduled = 0;
-                /* drop scheduler's ref */
-                ksocknal_put_conn (conn);
-        } else {
-                /* stay scheduled */
-                list_add_tail (&conn->ksnc_tx_list, &sched->kss_tx_conns);
-        }
-}
+        return (rc);
+} 
 
 void
 ksocknal_launch_autoconnect_locked (ksock_route_t *route)
@@ -764,10 +730,17 @@ ksocknal_launch_autoconnect_locked (ksock_route_t *route)
 
         /* called holding write lock on ksnd_global_lock */
 
-        LASSERT (route->ksnr_conn == NULL);
-        LASSERT (!route->ksnr_deleted && !route->ksnr_connecting);
+        LASSERT (!route->ksnr_deleted);
+        LASSERT ((route->ksnr_connected & (1 << SOCKNAL_CONN_ANY)) == 0);
+        LASSERT ((route->ksnr_connected & KSNR_TYPED_ROUTES) != KSNR_TYPED_ROUTES);
+        LASSERT (!route->ksnr_connecting);
         
-        route->ksnr_connecting = 1;
+        if (ksocknal_data.ksnd_typed_conns)
+                route->ksnr_connecting = 
+                        KSNR_TYPED_ROUTES & ~route->ksnr_connected;
+        else
+                route->ksnr_connecting = (1 << SOCKNAL_CONN_ANY);
+
         atomic_inc (&route->ksnr_refcount);     /* extra ref for asynchd */
         
         spin_lock_irqsave (&ksocknal_data.ksnd_autoconnectd_lock, flags);
@@ -814,21 +787,51 @@ ksock_conn_t *
 ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer) 
 {
         struct list_head *tmp;
-        ksock_conn_t     *conn = NULL;
-
+        ksock_conn_t     *typed = NULL;
+        int               tnob  = 0;
+        ksock_conn_t     *fallback = NULL;
+        int               fnob     = 0;
+        
         /* Find the conn with the shortest tx queue */
         list_for_each (tmp, &peer->ksnp_conns) {
-                ksock_conn_t *c = list_entry (tmp, ksock_conn_t, ksnc_list);
+                ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list);
+                int           nob = atomic_read(&c->ksnc_tx_nob);
 
                 LASSERT (!c->ksnc_closing);
-                
-                if (conn == NULL ||
-                    atomic_read (&conn->ksnc_tx_nob) >
-                    atomic_read (&c->ksnc_tx_nob))
-                        conn = c;
+
+                if (fallback == NULL || nob < fnob) {
+                        fallback = c;
+                        fnob     = nob;
+                }
+
+                if (!ksocknal_data.ksnd_typed_conns)
+                        continue;
+
+                switch (c->ksnc_type) {
+                default:
+                        LBUG();
+                case SOCKNAL_CONN_ANY:
+                        break;
+                case SOCKNAL_CONN_BULK_IN:
+                        continue;
+                case SOCKNAL_CONN_BULK_OUT:
+                        if (tx->tx_nob < ksocknal_data.ksnd_min_bulk)
+                                continue;
+                        break;
+                case SOCKNAL_CONN_CONTROL:
+                        if (tx->tx_nob >= ksocknal_data.ksnd_min_bulk)
+                                continue;
+                        break;
+                }
+
+                if (typed == NULL || nob < tnob) {
+                        typed = c;
+                        tnob  = nob;
+                }
         }
 
-        return (conn);
+        /* prefer the typed selection */
+        return ((typed != NULL) ? typed : fallback);
 }
 
 void
@@ -854,6 +857,10 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
 
         spin_lock_irqsave (&sched->kss_lock, flags);
 
+        conn->ksnc_tx_deadline = jiffies + 
+                                 ksocknal_data.ksnd_io_timeout * HZ;
+        mb();                                   /* order with list_add_tail */
+
         list_add_tail (&tx->tx_list, &conn->ksnc_tx_queue);
                 
         if (conn->ksnc_tx_ready &&      /* able to send */
@@ -870,22 +877,46 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
 }
 
 ksock_route_t *
-ksocknal_find_connectable_route_locked (ksock_peer_t *peer, int eager_only)
+ksocknal_find_connectable_route_locked (ksock_peer_t *peer)
 {
         struct list_head  *tmp;
         ksock_route_t     *route;
+        ksock_route_t     *candidate = NULL;
+        int                found = 0;
+        int                bits;
         
         list_for_each (tmp, &peer->ksnp_routes) {
                 route = list_entry (tmp, ksock_route_t, ksnr_list);
+                bits  = route->ksnr_connected;
+                
+                if ((bits & KSNR_TYPED_ROUTES) == KSNR_TYPED_ROUTES ||
+                    (bits & (1 << SOCKNAL_CONN_ANY)) != 0 ||
+                    route->ksnr_connecting != 0) {
+                        /* All typed connections have been established, or
+                         * an untyped connection has been established, or
+                         * connections are currently being established */
+                        found = 1;
+                        continue;
+                }
+
+                /* too soon to retry this guy? */
+                if (!time_after_eq (jiffies, route->ksnr_timeout))
+                        continue;
                 
-                if (route->ksnr_conn == NULL && /* not connected */
-                    !route->ksnr_connecting &&  /* not connecting */
-                    (!eager_only || route->ksnr_eager) && /* wants to connect */
-                    time_after_eq (jiffies, route->ksnr_timeout)) /* OK to retry */
+                /* always do eager routes */
+                if (route->ksnr_eager)
                         return (route);
+
+                if (candidate == NULL) {
+                        /* If we don't find any other route that is fully
+                         * connected or connecting, the first connectable
+                         * route is returned.  If it fails to connect, it
+                         * will get placed at the end of the list */
+                        candidate = route;
+                }
         }
-        
-        return (NULL);
+ 
+        return (found ? NULL : candidate);
 }
 
 ksock_route_t *
@@ -897,7 +928,7 @@ ksocknal_find_connecting_route_locked (ksock_peer_t *peer)
         list_for_each (tmp, &peer->ksnp_routes) {
                 route = list_entry (tmp, ksock_route_t, ksnr_list);
                 
-                if (route->ksnr_connecting)
+                if (route->ksnr_connecting != 0)
                         return (route);
         }
         
@@ -912,7 +943,7 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         ksock_conn_t     *conn;
         ksock_route_t    *route;
         rwlock_t         *g_lock;
-
+        
         /* Ensure the frags we've been given EXACTLY match the number of
          * bytes we want to send.  Many TCP/IP stacks disregard any total
          * size parameters passed to them and just look at the frags. 
@@ -936,18 +967,17 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         peer = ksocknal_find_target_peer_locked (tx, nid);
         if (peer == NULL) {
                 read_unlock (g_lock);
-                return (PTL_FAIL);
+                return (-EHOSTUNREACH);
         }
 
-        if (ksocknal_find_connectable_route_locked(peer, 1) == NULL) {
+        if (ksocknal_find_connectable_route_locked(peer) == NULL) {
                 conn = ksocknal_find_conn_locked (tx, peer);
                 if (conn != NULL) {
-                        /* I've got no unconnected autoconnect routes that
-                         * need to be connected, and I do have an actual
-                         * connection... */
+                        /* I've got no autoconnect routes that need to be
+                         * connecting and I do have an actual connection... */
                         ksocknal_queue_tx_locked (tx, conn);
                         read_unlock (g_lock);
-                        return (PTL_OK);
+                        return (0);
                 }
         }
         
@@ -960,14 +990,13 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         if (peer->ksnp_closing) {               /* peer deleted as I blocked! */
                 write_unlock_irqrestore (g_lock, flags);
                 ksocknal_put_peer (peer);
-                return (PTL_FAIL);
+                return (-EHOSTUNREACH);
         }
         ksocknal_put_peer (peer);               /* drop ref I got above */
 
-
         for (;;) {
-                /* launch all eager autoconnections */
-                route = ksocknal_find_connectable_route_locked (peer, 1);
+                /* launch any/all autoconnections that need it */
+                route = ksocknal_find_connectable_route_locked (peer);
                 if (route == NULL)
                         break;
 
@@ -979,26 +1008,20 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
                 /* Connection exists; queue message on it */
                 ksocknal_queue_tx_locked (tx, conn);
                 write_unlock_irqrestore (g_lock, flags);
-                return (PTL_OK);
+                return (0);
         }
 
-        if (ksocknal_find_connecting_route_locked (peer) == NULL) {
-                /* no autoconnect routes actually connecting now.  Scrape
-                 * the barrel for non-eager autoconnects */
-                route = ksocknal_find_connectable_route_locked (peer, 0);
-                if (route != NULL) {
-                        ksocknal_launch_autoconnect_locked (route);
-                } else {
-                        write_unlock_irqrestore (g_lock, flags);
-                        return (PTL_FAIL);
-                }
+        route = ksocknal_find_connecting_route_locked (peer);
+        if (route != NULL) {
+                /* At least 1 connection is being established; queue the
+                 * message... */
+                list_add_tail (&tx->tx_list, &peer->ksnp_tx_queue);
+                write_unlock_irqrestore (g_lock, flags);
+                return (0);
         }
-
-        /* At least 1 connection is being established; queue the message... */
-        list_add_tail (&tx->tx_list, &peer->ksnp_tx_queue);
-
+        
         write_unlock_irqrestore (g_lock, flags);
-        return (PTL_OK);
+        return (-EHOSTUNREACH);
 }
 
 ksock_ltx_t *
@@ -1069,10 +1092,11 @@ ksocknal_send (nal_cb_t *nal, void *private, lib_msg_t *cookie,
         ltx->ltx_tx.tx_nob = sizeof (*hdr) + payload_len;
 
         rc = ksocknal_launch_packet (&ltx->ltx_tx, nid);
-        if (rc != PTL_OK)
-                ksocknal_put_ltx (ltx);
+        if (rc == 0)
+                return (PTL_OK);
         
-        return (rc);
+        ksocknal_put_ltx (ltx);
+        return (PTL_FAIL);
 }
 
 int
@@ -1104,10 +1128,11 @@ ksocknal_send_pages (nal_cb_t *nal, void *private, lib_msg_t *cookie,
         ltx->ltx_tx.tx_nob = sizeof (*hdr) + payload_len;
 
         rc = ksocknal_launch_packet (&ltx->ltx_tx, nid);
-        if (rc != PTL_OK) 
-                ksocknal_put_ltx (ltx);
-                
-        return (rc);
+        if (rc == 0)
+                return (PTL_OK);
+
+        ksocknal_put_ltx (ltx);
+        return (PTL_FAIL);
 }
 
 void
@@ -1133,10 +1158,8 @@ ksocknal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
         tx->tx_hdr   = (ptl_hdr_t *)fwd->kprfd_iov[0].iov_base;
 
         rc = ksocknal_launch_packet (tx, nid);
-        if (rc != 0) {
-                /* FIXME, could pass a better completion error */
-                kpr_fwd_done (&ksocknal_data.ksnd_router, fwd, -EHOSTUNREACH);
-        }
+        if (rc != 0)
+                kpr_fwd_done (&ksocknal_data.ksnd_router, fwd, rc);
 }
 
 int
@@ -1353,38 +1376,43 @@ ksocknal_fwd_parse (ksock_conn_t *conn)
 {
         ksock_peer_t *peer;
         ptl_nid_t     dest_nid = NTOH__u64 (conn->ksnc_hdr.dest_nid);
-        int           body_len = NTOH__u32 (PTL_HDR_LENGTH(&conn->ksnc_hdr));
+        ptl_nid_t     src_nid = NTOH__u64 (conn->ksnc_hdr.src_nid);
+        int           body_len = NTOH__u32 (conn->ksnc_hdr.payload_length);
+        char str[PTL_NALFMT_SIZE];
 
         CDEBUG (D_NET, "%p "LPX64"->"LPX64" %d parsing header\n", conn,
-                NTOH__u64 (conn->ksnc_hdr.src_nid),
-                dest_nid, conn->ksnc_rx_nob_left);
+                src_nid, dest_nid, conn->ksnc_rx_nob_left);
 
         LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_HEADER);
         LASSERT (conn->ksnc_rx_scheduled);
 
         if (body_len < 0) {                 /* length corrupt (overflow) */
-                CERROR("dropping packet from "LPX64" for "LPX64": packet "
-                       "size %d illegal\n", NTOH__u64 (conn->ksnc_hdr.src_nid),
-                       dest_nid, body_len);
+                CERROR("dropping packet from "LPX64" (%s) for "LPX64" (%s): "
+                       "packet size %d illegal\n",
+                       src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                       dest_nid, portals_nid2str(TCPNAL, dest_nid, str),
+                       body_len);
 
                 ksocknal_new_packet (conn, 0);  /* on to new packet */
-                ksocknal_close_conn_unlocked (conn, -EINVAL); /* give up on conn */
                 return;
         }
 
         if (ksocknal_data.ksnd_fmbs == NULL) {        /* not forwarding */
-                CERROR("dropping packet from "LPX64" for "LPX64": not "
-                       "forwarding\n", conn->ksnc_hdr.src_nid,
-                       conn->ksnc_hdr.dest_nid);
+                CERROR("dropping packet from "LPX64" (%s) for "LPX64
+                       " (%s): not forwarding\n",
+                       src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                       dest_nid, portals_nid2str(TCPNAL, dest_nid, str));
                 /* on to new packet (skip this one's body) */
                 ksocknal_new_packet (conn, body_len);
                 return;
         }
 
-        if (body_len > SOCKNAL_MAX_FWD_PAYLOAD) {      /* too big to forward */
-                CERROR ("dropping packet from "LPX64" for "LPX64
-                        ": packet size %d too big\n", conn->ksnc_hdr.src_nid,
-                        conn->ksnc_hdr.dest_nid, body_len);
+        if (body_len > PTL_MTU) {      /* too big to forward */
+                CERROR ("dropping packet from "LPX64" (%s) for "LPX64
+                        "(%s): packet size %d too big\n",
+                        src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                        dest_nid, portals_nid2str(TCPNAL, dest_nid, str),
+                        body_len);
                 /* on to new packet (skip this one's body) */
                 ksocknal_new_packet (conn, body_len);
                 return;
@@ -1393,9 +1421,10 @@ ksocknal_fwd_parse (ksock_conn_t *conn)
         /* should have gone direct */
         peer = ksocknal_get_peer (conn->ksnc_hdr.dest_nid);
         if (peer != NULL) {
-                CERROR ("dropping packet from "LPX64" for "LPX64
-                        ": target is a peer\n", conn->ksnc_hdr.src_nid,
-                        conn->ksnc_hdr.dest_nid);
+                CERROR ("dropping packet from "LPX64" (%s) for "LPX64
+                        "(%s): target is a peer\n",
+                        src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                        dest_nid, portals_nid2str(TCPNAL, dest_nid, str));
                 ksocknal_put_peer (peer);  /* drop ref from get above */
 
                 /* on to next packet (skip this one's body) */
@@ -1463,25 +1492,13 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
         return (0);
 }
 
-void
-ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
+int
+ksocknal_process_receive (ksock_conn_t *conn)
 {
-        ksock_conn_t *conn;
         ksock_fmb_t  *fmb;
         int           rc;
-
-        /* NB: sched->ksnc_lock lock held */
-
-        LASSERT (!list_empty (&sched->kss_rx_conns));
-        conn = list_entry(sched->kss_rx_conns.next, ksock_conn_t, ksnc_rx_list);
-        list_del (&conn->ksnc_rx_list);
-
-        spin_unlock_irqrestore (&sched->kss_lock, *irq_flags);
-
-        CDEBUG(D_NET, "sched %p conn %p\n", sched, conn);
+        
         LASSERT (atomic_read (&conn->ksnc_refcount) > 0);
-        LASSERT (conn->ksnc_rx_scheduled);
-        LASSERT (conn->ksnc_rx_ready);
 
         /* doesn't need a forwarding buffer */
         if (conn->ksnc_rx_state != SOCKNAL_RX_GET_FMB)
@@ -1489,13 +1506,15 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
  get_fmb:
         fmb = ksocknal_get_idle_fmb (conn);
-        if (fmb == NULL) {      /* conn descheduled waiting for idle fmb */
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-                return;
+        if (fmb == NULL) {
+                /* conn descheduled waiting for idle fmb */
+                return (0);
         }
 
-        if (ksocknal_init_fmb (conn, fmb)) /* packet forwarded ? */
-                goto out;               /* come back later for next packet */
+        if (ksocknal_init_fmb (conn, fmb)) {
+                /* packet forwarded */
+                return (0);
+        }
 
  try_read:
         /* NB: sched lock NOT held */
@@ -1506,33 +1525,27 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
         LASSERT (conn->ksnc_rx_nob_wanted > 0);
 
-        conn->ksnc_rx_ready = 0;/* data ready may race with me and set ready */
-        mb();                   /* => clear BEFORE trying to read */
-
         rc = ksocknal_recvmsg(conn);
 
         if (rc <= 0) {
-                if (ksocknal_close_conn_unlocked (conn, rc)) {
-                        /* I'm the first to close */
-                        if (rc < 0)
-                                CERROR ("[%p] Error %d on read from "LPX64" ip %08x:%d\n",
-                                        conn, rc, conn->ksnc_peer->ksnp_nid,
-                                        conn->ksnc_ipaddr, conn->ksnc_port);
-                        else
-                                CWARN ("[%p] EOF from "LPX64" ip %08x:%d\n",
-                                       conn, conn->ksnc_peer->ksnp_nid,
-                                       conn->ksnc_ipaddr, conn->ksnc_port);
-                }
-                goto out;
+                if (rc == 0)
+                        CWARN ("[%p] EOF from "LPX64" ip %08x:%d\n",
+                               conn, conn->ksnc_peer->ksnp_nid,
+                               conn->ksnc_ipaddr, conn->ksnc_port);
+                else if (!conn->ksnc_closing)
+                        CERROR ("[%p] Error %d on read from "LPX64" ip %08x:%d\n",
+                                conn, rc, conn->ksnc_peer->ksnp_nid,
+                                conn->ksnc_ipaddr, conn->ksnc_port);
+
+                ksocknal_close_conn_and_siblings (conn, rc);
+                return (rc == 0 ? -ESHUTDOWN : rc);
         }
 
+        if (conn->ksnc_rx_nob_wanted != 0) {
+                /* short read */
+                return (-EAGAIN);
+        }
         
-        if (conn->ksnc_rx_nob_wanted != 0)      /* short read */
-                goto out;                       /* try again later */
-
-        /* got all I wanted, assume there's more - prevent data_ready locking */
-        conn->ksnc_rx_ready = 1;
-
         switch (conn->ksnc_rx_state) {
         case SOCKNAL_RX_HEADER:
                 if (conn->ksnc_hdr.type != HTON__u32(PTL_MSG_HELLO) &&
@@ -1541,7 +1554,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
                         ksocknal_fwd_parse (conn);
                         switch (conn->ksnc_rx_state) {
                         case SOCKNAL_RX_HEADER: /* skipped (zero payload) */
-                                goto out;       /* => come back later */
+                                return (0);     /* => come back later */
                         case SOCKNAL_RX_SLOP:   /* skipping packet's body */
                                 goto try_read;  /* => go read it */
                         case SOCKNAL_RX_GET_FMB: /* forwarding */
@@ -1569,7 +1582,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
         case SOCKNAL_RX_SLOP:
                 /* starting new packet? */
                 if (ksocknal_new_packet (conn, conn->ksnc_rx_nob_left))
-                        goto out;       /* come back later */
+                        return (0);     /* come back later */
                 goto try_read;          /* try to finish reading slop now */
 
         case SOCKNAL_RX_BODY_FWD:
@@ -1588,7 +1601,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
                 LASSERT (conn->ksnc_rx_nob_left == 0);
 
                 ksocknal_new_packet (conn, 0);  /* on to next packet */
-                goto out;                       /* (later) */
+                return (0);                     /* (later) */
 
         default:
                 break;
@@ -1596,20 +1609,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
         /* Not Reached */
         LBUG ();
-
- out:
-        spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-
-        /* no data there to read? */
-        if (!conn->ksnc_rx_ready) {
-                /* let socket callback schedule again */
-                conn->ksnc_rx_scheduled = 0;
-                /* drop scheduler's ref */
-                ksocknal_put_conn (conn);   
-        } else {
-                /* stay scheduled */
-                list_add_tail (&conn->ksnc_rx_list, &sched->kss_rx_conns);
-        }
+        return (-EINVAL);                       /* keep gcc happy */
 }
 
 int
@@ -1667,6 +1667,8 @@ ksocknal_recv_pages (nal_cb_t *nal, void *private, lib_msg_t *msg,
 int ksocknal_scheduler (void *arg)
 {
         ksock_sched_t     *sched = (ksock_sched_t *)arg;
+        ksock_conn_t      *conn;
+        ksock_tx_t        *tx;
         unsigned long      flags;
         int                rc;
         int                nloops = 0;
@@ -1677,6 +1679,8 @@ int ksocknal_scheduler (void *arg)
         kportal_daemonize (name);
         kportal_blockallsigs ();
 
+        current->flags |= PF_MEMALLOC;
+
 #if (CONFIG_SMP && CPU_AFFINITY)
         if ((cpu_online_map & (1 << id)) != 0) {
 #if 1
@@ -1697,15 +1701,96 @@ int ksocknal_scheduler (void *arg)
                 /* Ensure I progress everything semi-fairly */
 
                 if (!list_empty (&sched->kss_rx_conns)) {
+                        conn = list_entry(sched->kss_rx_conns.next,
+                                          ksock_conn_t, ksnc_rx_list);
+                        list_del(&conn->ksnc_rx_list);
+
+                        LASSERT(conn->ksnc_rx_scheduled);
+                        LASSERT(conn->ksnc_rx_ready);
+
+                        /* clear rx_ready in case receive isn't complete.
+                         * Do it BEFORE we call process_recv, since
+                         * data_ready can set it any time after we release
+                         * kss_lock. */
+                        conn->ksnc_rx_ready = 0;
+                        spin_unlock_irqrestore(&sched->kss_lock, flags);
+                        
+                        rc = ksocknal_process_receive(conn);
+                        
+                        spin_lock_irqsave(&sched->kss_lock, flags);
+
+                        /* I'm the only one that can clear this flag */
+                        LASSERT(conn->ksnc_rx_scheduled);
+
+                        /* Did process_receive get everything it wanted? */
+                        if (rc == 0)
+                                conn->ksnc_rx_ready = 1;
+                        
+                        if (conn->ksnc_rx_state == SOCKNAL_RX_FMB_SLEEP ||
+                            conn->ksnc_rx_state == SOCKNAL_RX_GET_FMB) {
+                                /* Conn blocked for a forwarding buffer.
+                                 * It will get queued for my attention when
+                                 * one becomes available (and it might just
+                                 * already have been!).  Meanwhile my ref
+                                 * on it stays put. */
+                        } else if (conn->ksnc_rx_ready) {
+                                /* reschedule for rx */
+                                list_add_tail (&conn->ksnc_rx_list,
+                                               &sched->kss_rx_conns);
+                        } else {
+                                conn->ksnc_rx_scheduled = 0;
+                                /* drop my ref */
+                                ksocknal_put_conn(conn);
+                        }
+
                         did_something = 1;
-                        /* drops & regains kss_lock */
-                        ksocknal_process_receive (sched, &flags);
                 }
 
                 if (!list_empty (&sched->kss_tx_conns)) {
+                        conn = list_entry(sched->kss_tx_conns.next,
+                                          ksock_conn_t, ksnc_tx_list);
+                        list_del (&conn->ksnc_tx_list);
+                        
+                        LASSERT(conn->ksnc_tx_scheduled);
+                        LASSERT(conn->ksnc_tx_ready);
+                        LASSERT(!list_empty(&conn->ksnc_tx_queue));
+                        
+                        tx = list_entry(conn->ksnc_tx_queue.next,
+                                        ksock_tx_t, tx_list);
+                        /* dequeue now so empty list => more to send */
+                        list_del(&tx->tx_list);
+                        
+                        /* Clear tx_ready in case send isn't complete.  Do
+                         * it BEFORE we call process_transmit, since
+                         * write_space can set it any time after we release
+                         * kss_lock. */
+                        conn->ksnc_tx_ready = 0;
+                        spin_unlock_irqrestore (&sched->kss_lock, flags);
+                        
+                        rc = ksocknal_process_transmit(conn, tx);
+                        
+                        spin_lock_irqsave (&sched->kss_lock, flags);
+
+                        if (rc != -EAGAIN) {
+                                /* error or everything went: assume more can go */
+                                conn->ksnc_tx_ready = 1;
+                        } else {
+                                 /* back onto HEAD of tx_queue */
+                                list_add (&tx->tx_list, &conn->ksnc_tx_queue);
+                        }
+                        
+                        if (conn->ksnc_tx_ready &&
+                            !list_empty (&conn->ksnc_tx_queue)) {
+                                /* reschedule for tx */
+                                list_add_tail (&conn->ksnc_tx_list, 
+                                               &sched->kss_tx_conns);
+                        } else {
+                                conn->ksnc_tx_scheduled = 0;
+                                /* drop my ref */
+                                ksocknal_put_conn (conn);
+                        }
+                                
                         did_something = 1;
-                        /* drops and regains kss_lock */
-                        ksocknal_process_transmit (sched, &flags);
                 }
 #if SOCKNAL_ZC
                 if (!list_empty (&sched->kss_zctxdone_list)) {
@@ -1769,18 +1854,11 @@ ksocknal_data_ready (struct sock *sk, int n)
         if (conn == NULL) {             /* raced with ksocknal_close_sock */
                 LASSERT (sk->sk_data_ready != &ksocknal_data_ready);
                 sk->sk_data_ready (sk, n);
-                goto out;
-        }
-
-        if (!conn->ksnc_rx_ready) {        /* new news */
-                /* Set ASAP in case of concurrent calls to me */
-                conn->ksnc_rx_ready = 1;
-
+        } else {
                 sched = conn->ksnc_scheduler;
 
                 spin_lock_irqsave (&sched->kss_lock, flags);
 
-                /* Set again (process_receive may have cleared while I blocked for the lock) */
                 conn->ksnc_rx_ready = 1;
 
                 if (!conn->ksnc_rx_scheduled) {  /* not being progressed */
@@ -1796,7 +1874,6 @@ ksocknal_data_ready (struct sock *sk, int n)
                 spin_unlock_irqrestore (&sched->kss_lock, flags);
         }
 
- out:
         read_unlock (&ksocknal_data.ksnd_global_lock);
 
         EXIT;
@@ -1834,31 +1911,24 @@ ksocknal_write_space (struct sock *sk)
         if (tcp_wspace(sk) >= SOCKNAL_TX_LOW_WATER(sk)) { /* got enough space */
                 clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);
 
-                if (!conn->ksnc_tx_ready) {      /* new news */
-                        /* Set ASAP in case of concurrent calls to me */
-                        conn->ksnc_tx_ready = 1;
-
-                        sched = conn->ksnc_scheduler;
-
-                        spin_lock_irqsave (&sched->kss_lock, flags);
+                sched = conn->ksnc_scheduler;
 
-                        /* Set again (process_transmit may have
-                           cleared while I blocked for the lock) */
-                        conn->ksnc_tx_ready = 1;
+                spin_lock_irqsave (&sched->kss_lock, flags);
 
-                        if (!conn->ksnc_tx_scheduled && // not being progressed
-                            !list_empty(&conn->ksnc_tx_queue)){//packets to send
-                                list_add_tail (&conn->ksnc_tx_list,
-                                               &sched->kss_tx_conns);
-                                conn->ksnc_tx_scheduled = 1;
-                                /* extra ref for scheduler */
-                                atomic_inc (&conn->ksnc_refcount);
+                conn->ksnc_tx_ready = 1;
 
-                                wake_up (&sched->kss_waitq);
-                        }
+                if (!conn->ksnc_tx_scheduled && // not being progressed
+                    !list_empty(&conn->ksnc_tx_queue)){//packets to send
+                        list_add_tail (&conn->ksnc_tx_list,
+                                       &sched->kss_tx_conns);
+                        conn->ksnc_tx_scheduled = 1;
+                        /* extra ref for scheduler */
+                        atomic_inc (&conn->ksnc_refcount);
 
-                        spin_unlock_irqrestore (&sched->kss_lock, flags);
+                        wake_up (&sched->kss_waitq);
                 }
+
+                spin_unlock_irqrestore (&sched->kss_lock, flags);
         }
 
         read_unlock (&ksocknal_data.ksnd_global_lock);
@@ -1943,7 +2013,7 @@ ksocknal_sock_read (struct socket *sock, void *buffer, int nob)
 }
 
 int
-ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
+ksocknal_hello (struct socket *sock, ptl_nid_t *nid, int *type, __u64 *incarnation)
 {
         int                 rc;
         ptl_hdr_t           hdr;
@@ -1958,24 +2028,28 @@ ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
         
         hdr.src_nid = __cpu_to_le64 (ksocknal_lib.ni.nid);
         hdr.type    = __cpu_to_le32 (PTL_MSG_HELLO);
-        
+
+        hdr.msg.hello.type = __cpu_to_le32 (*type);
+        hdr.msg.hello.incarnation = 
+                __cpu_to_le64 (ksocknal_data.ksnd_incarnation);
+
         /* Assume sufficient socket buffering for this message */
         rc = ksocknal_sock_write (sock, &hdr, sizeof (hdr));
         if (rc != 0) {
-                CERROR ("Error %d sending HELLO to "LPX64"\n", rc, nid);
+                CERROR ("Error %d sending HELLO to "LPX64"\n", rc, *nid);
                 return (rc);
         }
 
         rc = ksocknal_sock_read (sock, hmv, sizeof (*hmv));
         if (rc != 0) {
-                CERROR ("Error %d reading HELLO from "LPX64"\n", rc, nid);
+                CERROR ("Error %d reading HELLO from "LPX64"\n", rc, *nid);
                 return (rc);
         }
         
         if (hmv->magic != __le32_to_cpu (PORTALS_PROTO_MAGIC)) {
                 CERROR ("Bad magic %#08x (%#08x expected) from "LPX64"\n",
-                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, nid);
-                return (-EINVAL);
+                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, *nid);
+                return (-EPROTO);
         }
 
         if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
@@ -1986,63 +2060,99 @@ ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
                         __le16_to_cpu (hmv->version_minor),
                         PORTALS_PROTO_VERSION_MAJOR,
                         PORTALS_PROTO_VERSION_MINOR,
-                        nid);
-                return (-EINVAL);
+                        *nid);
+                return (-EPROTO);
         }
 
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
+#if (PORTALS_PROTO_VERSION_MAJOR != 0)
+# error "This code only understands protocol version 0.x"
+#endif
         /* version 0 sends magic/version as the dest_nid of a 'hello' header,
          * so read the rest of it in now... */
 
         rc = ksocknal_sock_read (sock, hmv + 1, sizeof (hdr) - sizeof (*hmv));
         if (rc != 0) {
                 CERROR ("Error %d reading rest of HELLO hdr from "LPX64"\n",
-                        rc, nid);
+                        rc, *nid);
                 return (rc);
         }
 
         /* ...and check we got what we expected */
         if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
-            PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
+            hdr.payload_length != __cpu_to_le32 (0)) {
                 CERROR ("Expecting a HELLO hdr with 0 payload,"
                         " but got type %d with %d payload from "LPX64"\n",
                         __le32_to_cpu (hdr.type),
-                        __le32_to_cpu (PTL_HDR_LENGTH (&hdr)), nid);
-                return (-EINVAL);
+                        __le32_to_cpu (hdr.payload_length), *nid);
+                return (-EPROTO);
         }
-        
-        if (__le64_to_cpu (hdr.src_nid) != nid) {
+
+        if (__le64_to_cpu(hdr.src_nid) == PTL_NID_ANY) {
+                CERROR("Expecting a HELLO hdr with a NID, but got PTL_NID_ANY\n");
+                return (-EPROTO);
+        }
+
+        if (*nid == PTL_NID_ANY) {              /* don't know peer's nid yet */
+                *nid = __le64_to_cpu(hdr.src_nid);
+        } else if (*nid != __le64_to_cpu (hdr.src_nid)) {
                 CERROR ("Connected to nid "LPX64", but expecting "LPX64"\n",
-                        __le64_to_cpu (hdr.src_nid), nid);
-                return (-EINVAL);
+                        __le64_to_cpu (hdr.src_nid), *nid);
+                return (-EPROTO);
+        }
+
+        if (*type == SOCKNAL_CONN_NONE) {
+                /* I've accepted this connection; peer determines type */
+                *type = __le32_to_cpu(hdr.msg.hello.type);
+                switch (*type) {
+                case SOCKNAL_CONN_ANY:
+                case SOCKNAL_CONN_CONTROL:
+                        break;
+                case SOCKNAL_CONN_BULK_IN:
+                        *type = SOCKNAL_CONN_BULK_OUT;
+                        break;
+                case SOCKNAL_CONN_BULK_OUT:
+                        *type = SOCKNAL_CONN_BULK_IN;
+                        break;
+                default:
+                        CERROR ("Unexpected type %d from "LPX64"\n", *type, *nid);
+                        return (-EPROTO);
+                }
+        } else if (__le32_to_cpu(hdr.msg.hello.type) != SOCKNAL_CONN_NONE) {
+                CERROR ("Mismatched types: me %d "LPX64" %d\n",
+                        *type, *nid, __le32_to_cpu(hdr.msg.hello.type));
+                return (-EPROTO);
         }
 
+        *incarnation = __le64_to_cpu(hdr.msg.hello.incarnation);
+
         return (0);
 }
 
 int
-ksocknal_setup_sock (struct socket *sock) 
+ksocknal_setup_sock (struct socket *sock)
 {
         mm_segment_t    oldmm = get_fs ();
         int             rc;
         int             option;
         struct linger   linger;
 
+        sock->sk->allocation = GFP_NOFS;
+
         /* Ensure this socket aborts active sends immediately when we close
          * it. */
-        
+
         linger.l_onoff = 0;
         linger.l_linger = 0;
 
         set_fs (KERNEL_DS);
-        rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER, 
+        rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,
                               (char *)&linger, sizeof (linger));
         set_fs (oldmm);
         if (rc != 0) {
                 CERROR ("Can't set SO_LINGER: %d\n", rc);
                 return (rc);
         }
-        
+
         option = -1;
         set_fs (KERNEL_DS);
         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,
@@ -2101,7 +2211,7 @@ ksocknal_setup_sock (struct socket *sock)
 }
 
 int
-ksocknal_connect_peer (ksock_route_t *route)
+ksocknal_connect_peer (ksock_route_t *route, int type)
 {
         struct sockaddr_in  peer_addr;
         mm_segment_t        oldmm = get_fs();
@@ -2206,14 +2316,7 @@ ksocknal_connect_peer (ksock_route_t *route)
                 goto out;
         }
         
-        if (route->ksnr_xchange_nids) {
-                rc = ksocknal_exchange_nids (sock, route->ksnr_peer->ksnp_nid);
-                if (rc != 0)
-                        goto out;
-        }
-
-        rc = ksocknal_create_conn (route->ksnr_peer->ksnp_nid,
-                                   route, sock, route->ksnr_irq_affinity);
+        rc = ksocknal_create_conn (route, sock, route->ksnr_irq_affinity, type);
         if (rc == 0) {
                 /* Take an extra ref on sock->file to compensate for the
                  * upcoming close which will lose fd's ref on it. */
@@ -2233,20 +2336,36 @@ ksocknal_autoconnect (ksock_route_t *route)
         ksock_peer_t     *peer;
         unsigned long     flags;
         int               rc;
+        int               type;
         
-        rc = ksocknal_connect_peer (route);
-        if (rc == 0) {
+        for (;;) {
+                for (type = 0; type < SOCKNAL_CONN_NTYPES; type++)
+                        if ((route->ksnr_connecting & (1 << type)) != 0)
+                                break;
+                LASSERT (type < SOCKNAL_CONN_NTYPES);
+
+                rc = ksocknal_connect_peer (route, type);
+
+                if (rc != 0)
+                        break;
+                
                 /* successfully autoconnected: create_conn did the
-                 * route/conn binding and scheduled any blocked packets, 
-                 * so there's nothing left to do now. */
-                return;
+                 * route/conn binding and scheduled any blocked packets */
+
+                if (route->ksnr_connecting == 0) {
+                        /* No more connections required */
+                        return;
+                }
         }
 
+        /* Connection attempt failed */
+
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
         peer = route->ksnr_peer;
         route->ksnr_connecting = 0;
 
+        /* This is a retry rather than a new connection */
         LASSERT (route->ksnr_retry_interval != 0);
         route->ksnr_timeout = jiffies + route->ksnr_retry_interval;
         route->ksnr_retry_interval = MIN (route->ksnr_retry_interval * 2,
@@ -2266,6 +2385,12 @@ ksocknal_autoconnect (ksock_route_t *route)
                 } while (!list_empty (&peer->ksnp_tx_queue));
         }
 
+        /* make this route least-favourite for re-selection */
+        if (!route->ksnr_deleted) {
+                list_del(&route->ksnr_list);
+                list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
+        }
+        
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
         while (!list_empty (&zombies)) {
@@ -2273,7 +2398,7 @@ ksocknal_autoconnect (ksock_route_t *route)
                 
                 CERROR ("Deleting packet type %d len %d ("LPX64"->"LPX64")\n",
                         NTOH__u32 (tx->tx_hdr->type),
-                        NTOH__u32 (PTL_HDR_LENGTH(tx->tx_hdr)),
+                        NTOH__u32 (tx->tx_hdr->payload_length),
                         NTOH__u64 (tx->tx_hdr->src_nid),
                         NTOH__u64 (tx->tx_hdr->dest_nid));
 
@@ -2354,7 +2479,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
                 }
                 
                 if ((!list_empty (&conn->ksnc_tx_queue) ||
-                     conn->ksnc_sock->sk->wmem_queued != 0) &&
+                     conn->ksnc_sock->sk->sk_wmem_queued != 0) &&
                     time_after_eq (jiffies, conn->ksnc_tx_deadline)) {
                         /* Timed out messages queued for sending, or
                          * messages buffered in the socket's send buffer */
@@ -2362,7 +2487,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
                         CERROR ("Timed out TX to "LPX64" %s%d %p\n", 
                                 peer->ksnp_nid, 
                                 list_empty (&conn->ksnc_tx_queue) ? "" : "Q ",
-                                conn->ksnc_sock->sk->wmem_queued, conn);
+                                conn->ksnc_sock->sk->sk_wmem_queued, conn);
                         return (conn);
                 }
         }
@@ -2391,13 +2516,11 @@ ksocknal_check_peer_timeouts (int idx)
                 if (conn != NULL) {
                         read_unlock (&ksocknal_data.ksnd_global_lock);
 
-                        if (ksocknal_close_conn_unlocked (conn, -ETIMEDOUT)) {
-                                /* I actually closed... */
-                                CERROR ("Timeout out conn->"LPX64" ip %x:%d\n",
-                                        peer->ksnp_nid, conn->ksnc_ipaddr,
-                                        conn->ksnc_port);
-                        }
-                
+                        CERROR ("Timeout out conn->"LPX64" ip %x:%d\n",
+                                peer->ksnp_nid, conn->ksnc_ipaddr,
+                                conn->ksnc_port);
+                        ksocknal_close_conn_and_siblings (conn, -ETIMEDOUT);
+                        
                         /* NB we won't find this one again, but we can't
                          * just proceed with the next peer, since we dropped
                          * ksnd_global_lock and it might be dead already! */
diff --git a/lnet/klnds/toelnd/toenal.c b/lnet/klnds/toelnd/toenal.c
index 77ee47393ebc660f9ba4a3716bf9380885decc27..07b93cbf8041d6d665bf7ac003a9f956de9c37d9 100644
--- a/lnet/klnds/toelnd/toenal.c
+++ b/lnet/klnds/toelnd/toenal.c
@@ -210,7 +210,7 @@ error:
 int
 ktoenal_close_sock(ptl_nid_t nid)
 {
-        long               flags;
+        unsigned long     flags;
         ksock_conn_t      *conn;
         LIST_HEAD         (death_row);
         struct list_head  *tmp;
@@ -354,23 +354,23 @@ ktoenal_free_buffers (void)
 }
 
 int
-ktoenal_cmd(struct portal_ioctl_data * data, void * private)
+ktoenal_cmd(struct portals_cfg *pcfg, void * private)
 {
         int rc = -EINVAL;
 
-        LASSERT (data != NULL);
+        LASSERT (pcfg != NULL);
 
-        switch(data->ioc_nal_cmd) {
+        switch(pcfg->pcfg_command) {
         case NAL_CMD_REGISTER_PEER_FD: {
-                rc = ktoenal_add_sock(data->ioc_nid, data->ioc_fd);
+                rc = ktoenal_add_sock(pcfg->pcfg_nid, pcfg->pcfg_fd);
                 break;
         }
         case NAL_CMD_CLOSE_CONNECTION: {
-                rc = ktoenal_close_sock(data->ioc_nid);
+                rc = ktoenal_close_sock(pcfg->pcfg_nid);
                 break;
         }
         case NAL_CMD_REGISTER_MYNID: {
-                rc = ktoenal_set_mynid (data->ioc_nid);
+                rc = ktoenal_set_mynid (pcfg->pcfg_nid);
                 break;
         }
         }
@@ -438,7 +438,7 @@ ktoenal_module_fini (void)
         CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
                atomic_read (&portal_kmemory));
 
-        printk(KERN_INFO "Routing socket NAL unloaded (final mem %d)\n",
+        printk(KERN_INFO "Lustre: Routing socket NAL unloaded (final mem %d)\n",
                atomic_read(&portal_kmemory));
 }
 
@@ -612,7 +612,7 @@ ktoenal_module_init (void)
         /* flag everything initialised */
         ktoenal_data.ksnd_init = SOCKNAL_INIT_ALL;
 
-	printk(KERN_INFO"Routing TOE NAL loaded (Routing %s, initial mem %d)\n",
+	printk(KERN_INFO "Lustre: Routing TOE NAL loaded (Routing %s, initial mem %d)\n",
 	       kpr_routing(&ktoenal_data.ksnd_router) ? "enabled" : "disabled",
                pkmem);
 
diff --git a/lnet/klnds/toelnd/toenal.h b/lnet/klnds/toelnd/toenal.h
index f793d3b4b6b400085e9bb132664d85b7e54f2cbe..b211d6c6006c8f46f6b3cec0da78440a5d0c5213 100644
--- a/lnet/klnds/toelnd/toenal.h
+++ b/lnet/klnds/toelnd/toenal.h
@@ -27,7 +27,9 @@
  */
 
 #define DEBUG_PORTAL_ALLOC
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -58,8 +60,6 @@
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
 
-#define SOCKNAL_MAX_FWD_PAYLOAD (64<<10)        /* biggest payload I can forward */
-
 #define SOCKNAL_NLTXS           128             /* # normal transmit messages */
 #define SOCKNAL_NNBLK_LTXS	128             /* # transmit messages reserved if can't block */
 
@@ -68,7 +68,7 @@
 
 #define SOCKNAL_SMALL_FWD_PAGES	1               /* # pages in a small message fwd buffer */
 
-#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + SOCKNAL_MAX_FWD_PAYLOAD) >> PAGE_SHIFT)
+#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
 						/* # pages in a large message fwd buffer */
 
 #define SOCKNAL_RESCHED         100             /* # scheduler loops before reschedule */
diff --git a/lnet/klnds/toelnd/toenal_cb.c b/lnet/klnds/toelnd/toenal_cb.c
index 478f3c1387ed7687adaa710a45b99a960ab42ad3..3af9e3318a5fcc954af472020521986a8630af51 100644
--- a/lnet/klnds/toelnd/toenal_cb.c
+++ b/lnet/klnds/toelnd/toenal_cb.c
@@ -140,7 +140,7 @@ ktoenal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
 ksock_ltx_t *
 ktoenal_get_ltx (int may_block)
 {
-        long	     flags;
+        unsigned long   flags;
         ksock_ltx_t *ltx = NULL;
         
         for (;;)
@@ -268,7 +268,7 @@ ktoenal_recvmsg(struct file *sock, struct iovec *iov, int niov, int toread)
 }
 
 void
-ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
+ktoenal_process_transmit (ksock_conn_t *conn, unsigned long *irq_flags)
 {
         ksock_tx_t *tx = list_entry (conn->ksnc_tx_queue.next, ksock_tx_t, tx_list);
         int         rc;
@@ -300,7 +300,7 @@ ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
                         rc = 0;                 /* nothing sent */
                 else
                 {
-#warning FIXME: handle socket errors properly
+                        //warning FIXME: handle socket errors properly
                         CERROR ("Error socknal send(%d) %p: %d\n", tx->tx_nob, conn, rc);
                         rc = tx->tx_nob;        /* kid on for now whole packet went */
                 }
@@ -358,7 +358,7 @@ ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
 void
 ktoenal_launch_packet (ksock_conn_t *conn, ksock_tx_t *tx)
 {
-        long          flags;
+        unsigned long flags;
         int           nob = tx->tx_nob;
         struct iovec *iov = tx->tx_iov;
         int           niov = 1;
@@ -371,7 +371,6 @@ ktoenal_launch_packet (ksock_conn_t *conn, ksock_tx_t *tx)
         for (;;)
         {
                 LASSERT (niov <= tx->tx_niov);
-                LASSERT (iov->iov_len >= 0);
                 
                 if (iov->iov_len >= nob)
                 {
@@ -542,7 +541,7 @@ ktoenal_fmb_callback (void *arg, int error)
         ksock_fmb_t       *fmb = (ksock_fmb_t *)arg;
         ptl_hdr_t         *hdr = (ptl_hdr_t *) page_address(fmb->fmb_pages[0]);
         ksock_conn_t      *conn;
-        long               flags;
+        unsigned long     flags;
 
         CDEBUG (D_NET, "routed packet from "LPX64" to "LPX64": %d\n", 
                 hdr->src_nid, hdr->dest_nid, error);
@@ -709,26 +708,7 @@ ktoenal_fwd_parse (ksock_conn_t *conn)
         LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_HEADER);
         LASSERT (conn->ksnc_rx_scheduled);
 
-        switch (conn->ksnc_hdr.type)
-        {
-        case PTL_MSG_GET:
-        case PTL_MSG_ACK:
-                body_len = 0;
-                break;
-        case PTL_MSG_PUT:
-                body_len = conn->ksnc_hdr.msg.put.length;
-                break;
-        case PTL_MSG_REPLY:
-                body_len = conn->ksnc_hdr.msg.reply.length;
-                break;
-        default:
-                /* Unrecognised packet type */
-                CERROR ("Unrecognised packet type %d from "LPX64" for "LPX64"\n",
-                        conn->ksnc_hdr.type, conn->ksnc_hdr.src_nid, conn->ksnc_hdr.dest_nid);
-                /* Ignore this header and go back to reading a new packet. */
-                ktoenal_new_packet (conn, 0);
-                return;
-        }
+        body_len = conn->ksnc_hdr.payload_length;
 
         if (body_len < 0)                               /* length corrupt */
         {
@@ -738,7 +718,7 @@ ktoenal_fwd_parse (ksock_conn_t *conn)
                 return;
         }
 
-        if (body_len > SOCKNAL_MAX_FWD_PAYLOAD)         /* too big to forward */
+        if (body_len > PTL_MTU)         /* too big to forward */
         {
                 CERROR ("dropping packet from "LPX64" for "LPX64": packet size %d too big\n",
                         conn->ksnc_hdr.src_nid, conn->ksnc_hdr.dest_nid, body_len);
@@ -810,7 +790,7 @@ ktoenal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 }
 
 void
-ktoenal_process_receive (ksock_conn_t *conn, long *irq_flags)
+ktoenal_process_receive (ksock_conn_t *conn, unsigned long *irq_flags)
 {
         ksock_fmb_t *fmb;
         int          len;
@@ -862,7 +842,7 @@ ktoenal_process_receive (ksock_conn_t *conn, long *irq_flags)
                 if (len != -EAGAIN &&           /* ! nothing to read now */
                     len != 0)                   /* ! nothing to read ever */
                 {
-#warning FIXME: handle socket errors properly
+                        // warning FIXME: handle socket errors properly
                         CERROR ("Error socknal read(%d) %p: %d\n",
                                 conn->ksnc_rx_nob_wanted, conn, len);
                 }
diff --git a/lnet/libcfs/Makefile.mk b/lnet/libcfs/Makefile.mk
index 9aa838f92c571f5ebf45e0b51351242adf526b68..c2014296df33b9bdaab54dd2c6bb58d4acc63486 100644
--- a/lnet/libcfs/Makefile.mk
+++ b/lnet/libcfs/Makefile.mk
@@ -6,4 +6,4 @@
 include fs/lustre/portals/Kernelenv
 
 obj-y += libcfs.o
-libcfs-objs    := module.o proc.o debug.o
+libcfs-objs    := module.o proc.o debug.o lwt.o
diff --git a/lnet/libcfs/debug.c b/lnet/libcfs/debug.c
index 90eb185da7243cced18e3d1186c889e0475f7340..6e2c1ca1d606ba0427db783829706162a46e636b 100644
--- a/lnet/libcfs/debug.c
+++ b/lnet/libcfs/debug.c
@@ -20,14 +20,15 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/notifier.h>
 #include <linux/kernel.h>
-#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/stat.h>
@@ -48,6 +49,7 @@
 # define DEBUG_SUBSYSTEM S_PORTALS
 
 #include <linux/kp30.h>
+#include <linux/portals_compat25.h>
 
 #define DEBUG_OVERFLOW 1024
 static char *debug_buf = NULL;
@@ -233,15 +235,15 @@ int portals_do_debug_dumplog(void *arg)
         reparent_to_init();
         journal_info = current->journal_info;
         current->journal_info = NULL;
-        sprintf(debug_file_name, "%s.%ld", debug_file_path, CURRENT_TIME);
-        file = filp_open(debug_file_name, O_CREAT|O_TRUNC|O_RDWR, 0644);
+        sprintf(debug_file_name, "%s.%ld", debug_file_path, CURRENT_SECONDS);
+        file = filp_open(debug_file_name, O_CREAT|O_EXCL|O_RDWR, 0644);
 
         if (!file || IS_ERR(file)) {
                 CERROR("cannot open %s for dumping: %ld\n", debug_file_name,
                        PTR_ERR(file));
                 GOTO(out, PTR_ERR(file));
         } else {
-                printk(KERN_ALERT "dumping log to %s ... writing ...\n",
+                printk(KERN_ALERT "LustreError: dumping log to %s ... writing ...\n",
                        debug_file_name);
         }
 
@@ -256,7 +258,7 @@ int portals_do_debug_dumplog(void *arg)
         } else {
                 rc = file->f_op->write(file, debug_buf, debug_off,&file->f_pos);
         }
-        printk("wrote %d bytes\n", rc);
+        printk("LustreError: wrote %d bytes\n", rc);
         set_fs(oldfs);
 
         rc = file->f_op->fsync(file, file->f_dentry, 1);
@@ -289,10 +291,8 @@ int portals_debug_daemon(void *arg)
         if (!file || IS_ERR(file)) {
                 CERROR("cannot open %s for logging", debug_daemon_file_path);
                 GOTO(out1, PTR_ERR(file));
-        } else {
-                printk(KERN_ALERT "daemon dumping log to %s ... writing ...\n",
-                       debug_daemon_file_path);
         }
+        printk(KERN_INFO "daemon dumping log to %s\n", debug_daemon_file_path);
 
         debug_daemon_state.overlapped = 0;
         debug_daemon_state.stopped = 0;
@@ -336,8 +336,8 @@ int portals_debug_daemon(void *arg)
                         rc = file->f_op->write(file, debug_buf+start,
                                                size, &file->f_pos);
                         if (rc < 0) {
-                                printk(KERN_ALERT
-                                           "Debug_daemon write error %d\n", rc);
+                                printk(KERN_ALERT "LustreError: Debug_daemon "
+                                       "write error %d\n", rc);
                                 goto out;
                         }
                         start += rc;
@@ -358,16 +358,16 @@ int portals_debug_daemon(void *arg)
                 if (force_flush) {
                         rc = file->f_op->fsync(file, file->f_dentry, 1);
                         if (rc < 0) {
-                                printk(KERN_ALERT
-                                       "Debug_daemon sync error %d\n", rc);
+                                printk(KERN_ALERT "LustreError: Debug_daemon "
+                                       "sync error %d\n", rc);
                                 goto out;
                         }
                         if (debug_daemon_state.stopped)
-                               break;           
+                               break;
                         debug_daemon_state.lctl_event = 1;
                         wake_up(&debug_daemon_state.lctl);
                 }
-                wait_event(debug_daemon_state.daemon, 
+                wait_event(debug_daemon_state.daemon,
                            debug_daemon_state.daemon_event);
                 }
 out:
@@ -403,12 +403,12 @@ void portals_debug_print(void)
 
         while (start1 < end1) {
                 int count = MIN(1024, end1 - start1);
-                printk("%*s", count, start1);
+                printk("LustreError: %*s", count, start1);
                 start1 += 1024;
         }
         while (start2 < end2) {
                 int count = MIN(1024, end2 - start2);
-                printk("%*s", count, start2);
+                printk("LustreError: %*s", count, start2);
                 start2 += 1024;
         }
 }
@@ -423,7 +423,7 @@ void portals_debug_dumplog(void)
         rc = kernel_thread(portals_do_debug_dumplog,
                            NULL, CLONE_VM | CLONE_FS | CLONE_FILES);
         if (rc < 0) {
-                printk(KERN_ERR "cannot start dump thread\n");
+                printk(KERN_ERR "LustreError: cannot start dump thread\n");
                 return;
         }
         sleep_on(&debug_ctlwq);
@@ -447,7 +447,7 @@ int portals_debug_daemon_start(char *file, unsigned int size)
         debug_daemon_state.lctl_event = 0;
         rc = kernel_thread(portals_debug_daemon, NULL, 0);
         if (rc < 0) {
-                printk(KERN_ERR "cannot start debug daemon thread\n");
+                printk(KERN_ERR "LustreError: cannot start debug daemon thread\n");
                 strncpy(debug_daemon_file_path, "\0", 1);
                 return rc;
         }
@@ -633,7 +633,7 @@ int portals_debug_mark_buffer(char *text)
                 return -EINVAL;
 
         CDEBUG(0, "********************************************************\n");
-        CDEBUG(0, "DEBUG MARKER: %s\n", text);
+        CWARN("DEBUG MARKER: %s\n", text);
         CDEBUG(0, "********************************************************\n");
 
         return 0;
@@ -641,39 +641,107 @@ int portals_debug_mark_buffer(char *text)
 #undef DEBUG_SUBSYSTEM
 #define DEBUG_SUBSYSTEM S_PORTALS
 
+/* this copies a snapshot of the debug buffer into an array of pages
+ * before doing the potentially blocking copy into userspace. it could
+ * be warning userspace if things wrap heavily while its off copying. */
 __s32 portals_debug_copy_to_user(char *buf, unsigned long len)
 {
         int rc;
-        unsigned long debug_off;
+        unsigned long total, debug_off, i, off, copied;
         unsigned long flags;
+        struct page *page;
+        LIST_HEAD(my_pages);
+        struct list_head *pos, *n;
 
         if (len < debug_size)
                 return -ENOSPC;
 
-        debug_off = atomic_read(&debug_off_a);
+        for (i = 0 ; i < debug_size; i += PAGE_SIZE) {
+                page = alloc_page(GFP_NOFS);
+                if (page == NULL) {
+                        rc = -ENOMEM;
+                        goto cleanup;
+                }
+                list_add(&page->list, &my_pages);
+        }
+
         spin_lock_irqsave(&portals_debug_lock, flags);
+        debug_off = atomic_read(&debug_off_a);
+
+        /* Sigh. If the buffer is empty, then skip to the end. */
+        if (debug_off == 0 && !debug_wrapped) {
+                spin_unlock_irqrestore(&portals_debug_lock, flags);
+                rc = 0;
+                goto cleanup;
+        }
+
         if (debug_wrapped) {
-                /* All of this juggling with the 1s is to keep the trailing nul
-                 * (which falls at debug_buf + debug_off) at the end of what we
-                 * copy into user space */
-                copy_to_user(buf, debug_buf + debug_off + 1,
-                             debug_size - debug_off - 1);
-                copy_to_user(buf + debug_size - debug_off - 1,
-                             debug_buf, debug_off + 1);
-                rc = debug_size;
+                off = debug_off + 1;
+                total = debug_size;
         } else {
-                copy_to_user(buf, debug_buf, debug_off);
-                rc = debug_off;
+                off = 0;
+                total = debug_off;
+        }
+        copied = 0;
+        list_for_each(pos, &my_pages) {
+                unsigned long to_copy;
+                page = list_entry(pos, struct page, list);
+
+                to_copy = min(total - off, PAGE_SIZE);
+                if (to_copy == 0) {
+                        off = 0;
+                        to_copy = min(debug_size - off, PAGE_SIZE);
+                }
+finish_partial:
+                memcpy(kmap(page), debug_buf + off, to_copy);
+                kunmap(page);
+                copied += to_copy;
+                if (copied >= total)
+                        break;
+
+                off += to_copy;
+                if (off >= debug_size) {
+                        off = 0;
+                        if (to_copy != PAGE_SIZE) {
+                                to_copy = PAGE_SIZE - to_copy;
+                                goto finish_partial;
+                        }
+                }
         }
+
         spin_unlock_irqrestore(&portals_debug_lock, flags);
 
+        off = 0;
+        list_for_each(pos, &my_pages) {
+                unsigned long to_copy;
+                page = list_entry(pos, struct page, list);
+
+                to_copy = min(copied - off, PAGE_SIZE);
+                rc = copy_to_user(buf + off, kmap(page), to_copy);
+                kunmap(page);
+                if (rc) {
+                        rc = -EFAULT;
+                        goto cleanup;
+                }
+                off += to_copy;
+                if (off >= copied)
+                        break;
+        }
+        rc = copied;
+
+cleanup:
+        list_for_each_safe(pos, n, &my_pages) {
+                page = list_entry(pos, struct page, list);
+                list_del(&page->list);
+                __free_page(page);
+        }
         return rc;
 }
 
 /* FIXME: I'm not very smart; someone smarter should make this better. */
 void
 portals_debug_msg(int subsys, int mask, char *file, const char *fn,
-                  const int line, unsigned long stack, const char *format, ...)
+                  const int line, unsigned long stack, char *format, ...)
 {
         va_list       ap;
         unsigned long flags;
@@ -685,7 +753,7 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         unsigned long debug_off;
 
         if (debug_buf == NULL) {
-                printk("portals_debug_msg: debug_buf is NULL!\n");
+                printk("LustreError: portals_debug_msg: debug_buf is NULL!\n");
                 return;
         }
 
@@ -707,8 +775,9 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
                         /* If this is the first time, leave a marker in the
                          * output */
                         debug_daemon_state.overlapped = 1;
-                        ap = NULL;
                         format = "DEBUG MARKER: Debug buffer overlapped\n";
+                        printk(KERN_ERR "LustreError: debug daemon buffer "
+                               "overlapped\n");
                 } else  /* More space just became available */
                         debug_daemon_state.overlapped = 0;
         }
@@ -716,7 +785,8 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         max_nob = debug_size - debug_off + DEBUG_OVERFLOW;
         if (max_nob <= 0) {
                 spin_unlock_irqrestore(&portals_debug_lock, flags);
-                printk("logic error in portals_debug_msg: <0 bytes to write\n");
+                printk("LustreError: logic error in portals_debug_msg: "
+                       "< 0 bytes to write\n");
                 return;
         }
 
@@ -728,27 +798,26 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         do_gettimeofday(&tv);
 
         prefix_nob = snprintf(debug_buf + debug_off, max_nob,
-                              "%06x:%06x:%d:%lu.%06lu ",
+                              "%06x:%06x:%d:%lu.%06lu:%lu:%d:",
                               subsys, mask, smp_processor_id(),
-                              tv.tv_sec, tv.tv_usec);
+                              tv.tv_sec, tv.tv_usec, stack, current->pid);
         max_nob -= prefix_nob;
+        if(*(format + strlen(format) - 1) != '\n')
+                *(format + strlen(format)) = '\n';
 
 #if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d | %d+%lu): ",
-                           file, line, fn, current->pid,
-                           current->thread.extern_pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->thread.extern_pid, file, line, fn);
 #elif defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d | %d+%lu): ",
-                           file, line, fn, current->pid,
-                           current->thread.mode.tt.extern_pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->thread.mode.tt.extern_pid, file, line, fn);
 #else
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d+%lu): ",
-                           file, line, fn, current->pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->pid, file, line, fn);
 #endif
-        max_nob -= msg_nob;
 
         va_start(ap, format);
         msg_nob += vsnprintf(debug_buf + debug_off + prefix_nob + msg_nob,
@@ -759,11 +828,17 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         /* Print to console, while msg is contiguous in debug_buf */
         /* NB safely terminated see above */
         if ((mask & D_EMERG) != 0)
-                printk(KERN_EMERG "%s", debug_buf + debug_off + prefix_nob);
-        if ((mask & D_ERROR) != 0)
-                printk(KERN_ERR   "%s", debug_buf + debug_off + prefix_nob);
+                printk(KERN_EMERG "LustreError: %s",
+                       debug_buf + debug_off + prefix_nob);
+        else if ((mask & D_ERROR) != 0)
+                printk(KERN_ERR "LustreError: %s",
+                       debug_buf + debug_off + prefix_nob);
+        else if ((mask & D_WARNING) != 0)
+                printk(KERN_WARNING "Lustre: %s",
+                       debug_buf + debug_off + prefix_nob);
         else if (portal_printk)
-                printk("<%d>%s", portal_printk, debug_buf+debug_off+prefix_nob);
+                printk("<%d>Lustre: %s", portal_printk,
+                       debug_buf+debug_off+prefix_nob);
         base_offset = debug_off & 0xFFFF;
 
         debug_off += prefix_nob + msg_nob;
@@ -786,7 +861,7 @@ out:
 
 void portals_debug_set_level(unsigned int debug_level)
 {
-        printk("Setting portals debug level to %08x\n", debug_level);
+        printk("Lustre: Setting portals debug level to %08x\n", debug_level);
         portal_debug = debug_level;
 }
 
@@ -806,8 +881,8 @@ void portals_run_upcall(char **argv)
                 argc++;
 
         LASSERT(argc >= 2);
-        
-        rc = call_usermodehelper(argv[0], argv, envp);
+
+        rc = USERMODEHELPER(argv[0], argv, envp);
         if (rc < 0) {
                 CERROR("Error %d invoking portals upcall %s %s%s%s%s%s%s%s%s; "
                        "check /proc/sys/portals/upcall\n",
@@ -843,8 +918,131 @@ void portals_run_lbug_upcall(char *file, const char *fn, const int line)
         portals_run_upcall (argv);
 }
 
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
+{
+        switch(nal){
+        case TCPNAL:
+                /* userspace NAL */
+        case SOCKNAL:
+                sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
+                        HIPQUAD(nid));
+                break;
+        case QSWNAL:
+        case GMNAL:
+        case IBNAL:
+        case TOENAL:
+        case SCIMACNAL:
+                sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
+                break;
+        default:
+                return NULL;
+        }
+        return str;
+}
+
+#ifdef __KERNEL__
+#include <linux/lustre_version.h>
+#if (LUSTRE_KERNEL_VERSION >= 30)
+#warning "FIXME: remove workaround when l30 is widely used"
+char stack_backtrace[LUSTRE_TRACE_SIZE];
+spinlock_t stack_backtrace_lock = SPIN_LOCK_UNLOCKED;
+
+#if defined(__arch_um__)
+
+extern int is_kernel_text_address(unsigned long addr);
+
+char *portals_debug_dumpstack(void)
+{
+        int size;
+        unsigned long addr;
+        char *buf = stack_backtrace;
+        char *pbuf = buf;
+        unsigned long *stack = (unsigned long *)&buf;
+
+        size = sprintf(pbuf, " Call Trace: ");
+        pbuf += size;
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+                addr = *stack++;
+                if (is_kernel_text_address(addr)) {
+                        size = sprintf(pbuf, "[<%08lx>] ", addr);
+                        pbuf += size;
+                        if (buf + LUSTRE_TRACE_SIZE <= pbuf + 12)
+                                break;
+                }
+        }
+
+        return buf;
+}
+
+#elif defined(CONFIG_X86)
+
+extern int is_kernel_text_address(unsigned long addr);
+extern int lookup_symbol(unsigned long address, char *buf, int buflen);
+
+char *portals_debug_dumpstack(void)
+{
+#if defined(__x86_64__)
+        unsigned long esp = current->thread.rsp;
+#else
+        unsigned long esp = current->thread.esp;
+#endif
+        unsigned long *stack = (unsigned long *)&esp;
+        int size;
+        unsigned long addr;
+        char *buf = stack_backtrace;
+        char *pbuf = buf;
+        static char buffer[512];
+        int rc = 0;
+
+        /* User space on another CPU? */
+        if ((esp ^ (unsigned long)current) & (PAGE_MASK<<1)){
+                buf[0] = '\0';
+                goto out;
+        }
+
+        size = sprintf(pbuf, " Call Trace: ");
+        pbuf += size;
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+                addr = *stack++;
+                if (is_kernel_text_address(addr)) {
+                        rc = lookup_symbol(addr, buffer, 512);
+                        if (rc == -ENOSYS) {
+                                if (buf + LUSTRE_TRACE_SIZE <= pbuf + 12)
+                                        break;
+                                size = sprintf(pbuf, "[<%08lx>] ", addr);
+                        } else {
+                                if (buf + LUSTRE_TRACE_SIZE
+                                            /* fix length + sizeof('\0') */
+                                    <= pbuf + strlen(buffer) + 28 + 1)
+                                        break;
+                                size = sprintf(pbuf, "([<%08lx>] %s (0x%p)) ",
+                                               addr, buffer, stack-1);
+                        }
+                        pbuf += size;
+                }
+        }
+out:
+        return buf;
+}
+
+#else /* !__arch_um__ && !__i386__ */
+
+char *portals_debug_dumpstack(void)
+{
+        char *buf = stack_backtrace;
+        buf[0] = '\0';
+        return buf;
+}
+
+#endif /* __arch_um__ */
+EXPORT_SYMBOL(stack_backtrace_lock);
+EXPORT_SYMBOL(portals_debug_dumpstack);
+#endif /* LUSTRE_KERNEL_VERSION < 30 */
+#endif /* __KERNEL__ */
+
 EXPORT_SYMBOL(portals_debug_dumplog);
 EXPORT_SYMBOL(portals_debug_msg);
 EXPORT_SYMBOL(portals_debug_set_level);
 EXPORT_SYMBOL(portals_run_upcall);
 EXPORT_SYMBOL(portals_run_lbug_upcall);
+EXPORT_SYMBOL(portals_nid2str);
diff --git a/lnet/libcfs/lwt.c b/lnet/libcfs/lwt.c
index a40a7ed5127e07b7073fb2b8cd31f7e350b8588a..89fe8f707de5e6c7c87e790e0de6f78a6b3d5f43 100644
--- a/lnet/libcfs/lwt.c
+++ b/lnet/libcfs/lwt.c
@@ -20,7 +20,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -57,6 +59,8 @@ int
 lwt_lookup_string (int *size, char *knl_ptr,
                    char *user_ptr, int user_size)
 {
+        int   maxsize = 128;
+        
         /* knl_ptr was retrieved from an LWT snapshot and the caller wants to
          * turn it into a string.  NB we can crash with an access violation
          * trying to determine the string length, so we're trusting our
@@ -65,12 +69,24 @@ lwt_lookup_string (int *size, char *knl_ptr,
         if (!capable(CAP_SYS_ADMIN))
                 return (-EPERM);
 
-        *size = strlen (knl_ptr) + 1;
-        
-        if (user_ptr != NULL &&
-            copy_to_user (user_ptr, knl_ptr, *size))
-                return (-EFAULT);
+        if (user_size > 0 && 
+            maxsize > user_size)
+                maxsize = user_size;
+
+        *size = strnlen (knl_ptr, maxsize - 1) + 1;
         
+        if (user_ptr != NULL) {
+                if (user_size < 4)
+                        return (-EINVAL);
+                
+                if (copy_to_user (user_ptr, knl_ptr, *size))
+                        return (-EFAULT);
+
+                /* Did I truncate the string?  */
+                if (knl_ptr[*size - 1] != 0)
+                        copy_to_user (user_ptr + *size - 4, "...", 4);
+        }
+
         return (0);
 }
 
@@ -87,11 +103,10 @@ lwt_control (int enable, int clear)
         if (clear)
                 for (i = 0; i < num_online_cpus(); i++) {
                         p = lwt_cpus[i].lwtc_current_page;
-                        
+
                         for (j = 0; j < lwt_pages_per_cpu; j++) {
-                                
                                 memset (p->lwtp_events, 0, PAGE_SIZE);
-                                
+
                                 p = list_entry (p->lwtp_list.next,
                                                 lwt_page_t, lwtp_list);
                         }
@@ -108,8 +123,7 @@ lwt_control (int enable, int clear)
 }
 
 int
-lwt_snapshot (int *ncpu, int *total_size, 
-              void *user_ptr, int user_size) 
+lwt_snapshot (int *ncpu, int *total_size, void *user_ptr, int user_size)
 {
         const int    events_per_page = PAGE_SIZE / sizeof(lwt_event_t);
         const int    bytes_per_page = events_per_page * sizeof(lwt_event_t);
diff --git a/lnet/libcfs/module.c b/lnet/libcfs/module.c
index 586b67548865d9652d00483f9761127f590a1eeb..7c0cafc7817f363619c91730eed88b85dc42de29 100644
--- a/lnet/libcfs/module.c
+++ b/lnet/libcfs/module.c
@@ -210,17 +210,69 @@ kportal_get_route(int index, __u32 *gateway_nalidp, ptl_nid_t *gateway_nidp,
         return (rc);
 }
 
-static int
-kportal_nal_cmd(int nal, struct portal_ioctl_data *data)
+static int 
+kportal_router_cmd(struct portals_cfg *pcfg, void * private)
+{
+        int err = -EINVAL;
+        ENTRY;
+
+        switch(pcfg->pcfg_command) {
+        default:
+                CDEBUG(D_IOCTL, "Inappropriate cmd: %d\n", pcfg->pcfg_command);
+                break;
+                
+        case NAL_CMD_ADD_ROUTE:
+                CDEBUG(D_IOCTL, "Adding route: [%d] "LPU64" : "LPU64" - "LPU64"\n",
+                       pcfg->pcfg_nal, pcfg->pcfg_nid, 
+                       pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                err = kportal_add_route(pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                        pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                break;
+
+        case NAL_CMD_DEL_ROUTE:
+                CDEBUG (D_IOCTL, "Removing routes via [%d] "LPU64" : "LPU64" - "LPU64"\n",
+                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid, 
+                        pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                err = kportal_del_route (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                         pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                break;
+
+        case NAL_CMD_NOTIFY_ROUTER: {
+                CDEBUG (D_IOCTL, "Notifying peer [%d] "LPU64" %s @ %ld\n",
+                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                        pcfg->pcfg_flags ? "Enabling" : "Disabling",
+                        (time_t)pcfg->pcfg_nid3);
+                
+                err = kportal_notify_router (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                             pcfg->pcfg_flags, 
+                                             (time_t)pcfg->pcfg_nid3);
+                break;
+        }
+                
+        case NAL_CMD_GET_ROUTE:
+                CDEBUG (D_IOCTL, "Getting route [%d]\n", pcfg->pcfg_count);
+                err = kportal_get_route(pcfg->pcfg_count, &pcfg->pcfg_gw_nal,
+                                        &pcfg->pcfg_nid, 
+                                        &pcfg->pcfg_nid2, &pcfg->pcfg_nid3,
+                                        &pcfg->pcfg_flags);
+                break;
+        }
+        RETURN(err);
+}
+
+int
+kportal_nal_cmd(struct portals_cfg *pcfg)
 {
+        __u32 nal = pcfg->pcfg_nal;
         int rc = -EINVAL;
 
         ENTRY;
 
         down(&nal_cmd_sem);
         if (nal > 0 && nal <= NAL_MAX_NR && nal_cmd[nal].nch_handler) {
-                CDEBUG(D_IOCTL, "calling handler nal: %d, cmd: %d\n", nal, data->ioc_nal_cmd);
-                rc = nal_cmd[nal].nch_handler(data, nal_cmd[nal].nch_private);
+                CDEBUG(D_IOCTL, "calling handler nal: %d, cmd: %d\n", nal, 
+                       pcfg->pcfg_command);
+                rc = nal_cmd[nal].nch_handler(pcfg, nal_cmd[nal].nch_private);
         }
         up(&nal_cmd_sem);
         RETURN(rc);
@@ -240,6 +292,8 @@ kportal_get_ni (int nal)
                 return  (PORTAL_SYMBOL_GET(ktoenal_ni));
         case GMNAL:
                 return  (PORTAL_SYMBOL_GET(kgmnal_ni));
+        case IBNAL:
+                return  (PORTAL_SYMBOL_GET(kibnal_ni));
         case TCPNAL:
                 /* userspace NAL */
                 return (NULL);
@@ -270,6 +324,9 @@ kportal_put_ni (int nal)
         case GMNAL:
                 PORTAL_SYMBOL_PUT(kgmnal_ni);
                 break;
+        case IBNAL:
+                PORTAL_SYMBOL_PUT(kibnal_ni);
+                break;
         case TCPNAL:
                 /* A lesson to a malicious caller */
                 LBUG ();
@@ -324,9 +381,13 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
         int err = 0;
         char buf[1024];
         struct portal_ioctl_data *data;
+        char str[PTL_NALFMT_SIZE];
 
         ENTRY;
 
+        if (current->fsuid != 0)
+                RETURN(err = -EACCES);
+
         if ( _IOC_TYPE(cmd) != IOC_PORTAL_TYPE ||
              _IOC_NR(cmd) < IOC_PORTAL_MIN_NR  ||
              _IOC_NR(cmd) > IOC_PORTAL_MAX_NR ) {
@@ -377,8 +438,9 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
         case IOC_PORTAL_PING: {
                 void (*ping)(struct portal_ioctl_data *);
 
-                CDEBUG(D_IOCTL, "doing %d pings to nid "LPU64"\n",
-                       data->ioc_count, data->ioc_nid);
+                CDEBUG(D_IOCTL, "doing %d pings to nid "LPX64" (%s)\n",
+                       data->ioc_count, data->ioc_nid,
+                       portals_nid2str(data->ioc_nal, data->ioc_nid, str));
                 ping = PORTAL_SYMBOL_GET(kping_client);
                 if (!ping)
                         CERROR("PORTAL_SYMBOL_GET failed\n");
@@ -389,50 +451,11 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
                 RETURN(0);
         }
 
-        case IOC_PORTAL_ADD_ROUTE:
-                CDEBUG(D_IOCTL, "Adding route: [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                       data->ioc_nal, data->ioc_nid, 
-                       data->ioc_nid2, data->ioc_nid3);
-                err = kportal_add_route(data->ioc_nal, data->ioc_nid,
-                                        data->ioc_nid2, data->ioc_nid3);
-                break;
-
-        case IOC_PORTAL_DEL_ROUTE:
-                CDEBUG (D_IOCTL, "Removing routes via [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                        data->ioc_nal, data->ioc_nid, 
-                        data->ioc_nid2, data->ioc_nid3);
-                err = kportal_del_route (data->ioc_nal, data->ioc_nid,
-                                         data->ioc_nid2, data->ioc_nid3);
-                break;
-
-        case IOC_PORTAL_NOTIFY_ROUTER: {
-                CDEBUG (D_IOCTL, "Notifying peer [%d] "LPU64" %s @ %ld\n",
-                        data->ioc_nal, data->ioc_nid,
-                        data->ioc_flags ? "Enabling" : "Disabling",
-                        (time_t)data->ioc_nid3);
-                
-                err = kportal_notify_router (data->ioc_nal, data->ioc_nid,
-                                             data->ioc_flags, 
-                                             (time_t)data->ioc_nid3);
-                break;
-        }
-                
-        case IOC_PORTAL_GET_ROUTE:
-                CDEBUG (D_IOCTL, "Getting route [%d]\n", data->ioc_count);
-                err = kportal_get_route(data->ioc_count, &data->ioc_nal,
-                                        &data->ioc_nid, 
-                                        &data->ioc_nid2, &data->ioc_nid3,
-                                        &data->ioc_flags);
-                if (err == 0)
-                        if (copy_to_user((char *)arg, data, sizeof (*data)))
-                                err = -EFAULT;
-                break;
-
         case IOC_PORTAL_GET_NID: {
                 const ptl_handle_ni_t *nip;
                 ptl_process_id_t       pid;
 
-                CDEBUG (D_IOCTL, "Getting nid [%d]\n", data->ioc_nal);
+                CDEBUG (D_IOCTL, "Getting nid for nal [%d]\n", data->ioc_nal);
 
                 nip = kportal_get_ni (data->ioc_nal);
                 if (nip == NULL)
@@ -448,15 +471,29 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
                 break;
         }
 
-        case IOC_PORTAL_NAL_CMD:
-                CDEBUG (D_IOCTL, "nal command nal %d cmd %d\n", data->ioc_nal,
-                        data->ioc_nal_cmd);
-                err = kportal_nal_cmd(data->ioc_nal, data);
-                if (err == 0)
+        case IOC_PORTAL_NAL_CMD: {
+                struct portals_cfg pcfg;
+
+                LASSERT (data->ioc_plen1 == sizeof(pcfg));
+                err = copy_from_user(&pcfg, (void *)data->ioc_pbuf1, 
+                                     sizeof(pcfg));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                CDEBUG (D_IOCTL, "nal command nal %d cmd %d\n", pcfg.pcfg_nal,
+                        pcfg.pcfg_command);
+                err = kportal_nal_cmd(&pcfg);
+                if (err == 0) {
+                        if (copy_to_user((char *)data->ioc_pbuf1, &pcfg, 
+                                         sizeof (pcfg)))
+                                err = -EFAULT;
                         if (copy_to_user((char *)arg, data, sizeof (*data)))
                                 err = -EFAULT;
+                }
                 break;
-
+        }
         case IOC_PORTAL_FAIL_NID: {
                 const ptl_handle_ni_t *nip;
 
@@ -526,7 +563,7 @@ static int init_kportals_module(void)
 
         rc = portals_debug_init(5 * 1024 * 1024);
         if (rc < 0) {
-                printk(KERN_ERR "portals_debug_init: %d\n", rc);
+                printk(KERN_ERR "LustreError: portals_debug_init: %d\n", rc);
                 return (rc);
         }
 
@@ -557,9 +594,17 @@ static int init_kportals_module(void)
                 goto cleanup_fini;
         }
 
+        rc = kportal_nal_register(ROUTER, kportal_router_cmd, NULL);
+        if (rc) {
+                CERROR("kportal_nal_registre: ROUTER error %d\n", rc);
+                goto cleanup_proc;
+        }
+
         CDEBUG (D_OTHER, "portals setup OK\n");
         return (0);
 
+ cleanup_proc:
+        remove_proc();
  cleanup_fini:
         PtlFini();
  cleanup_deregister:
@@ -577,6 +622,7 @@ static void exit_kportals_module(void)
 {
         int rc;
 
+        kportal_nal_unregister(ROUTER);
         remove_proc();
         PtlFini();
 
@@ -598,7 +644,7 @@ static void exit_kportals_module(void)
 
         rc = portals_debug_cleanup();
         if (rc)
-                printk(KERN_ERR "portals_debug_cleanup: %d\n", rc);
+                printk(KERN_ERR "LustreError: portals_debug_cleanup: %d\n", rc);
 }
 
 EXPORT_SYMBOL(lib_dispatch);
@@ -620,6 +666,7 @@ EXPORT_SYMBOL(portal_subsystem_debug);
 EXPORT_SYMBOL(portal_debug);
 EXPORT_SYMBOL(portal_stack);
 EXPORT_SYMBOL(portal_printk);
+EXPORT_SYMBOL(portal_cerror);
 EXPORT_SYMBOL(PtlEQWait);
 EXPORT_SYMBOL(PtlEQFree);
 EXPORT_SYMBOL(PtlEQGet);
@@ -633,6 +680,7 @@ EXPORT_SYMBOL(lib_copy_kiov2buf);
 EXPORT_SYMBOL(lib_copy_buf2kiov);
 EXPORT_SYMBOL(lib_finalize);
 EXPORT_SYMBOL(lib_parse);
+EXPORT_SYMBOL(lib_fake_reply_msg);
 EXPORT_SYMBOL(lib_init);
 EXPORT_SYMBOL(lib_fini);
 EXPORT_SYMBOL(portal_kmemory);
@@ -644,6 +692,7 @@ EXPORT_SYMBOL(kportal_assertion_failed);
 EXPORT_SYMBOL(dispatch_name);
 EXPORT_SYMBOL(kportal_get_ni);
 EXPORT_SYMBOL(kportal_put_ni);
+EXPORT_SYMBOL(kportal_nal_cmd);
 
 module_init(init_kportals_module);
 module_exit (exit_kportals_module);
diff --git a/lnet/libcfs/proc.c b/lnet/libcfs/proc.c
index 564a0bd090b203623e536643280cc34d01f8841d..c1b2aecb15bba6d28ccc2162d704c01e378ca176 100644
--- a/lnet/libcfs/proc.c
+++ b/lnet/libcfs/proc.c
@@ -22,7 +22,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -63,11 +65,12 @@ extern char portals_upcall[1024];
 #define PSDEV_DEBUG           1   /* control debugging */
 #define PSDEV_SUBSYSTEM_DEBUG 2   /* control debugging */
 #define PSDEV_PRINTK          3   /* force all errors to console */
-#define PSDEV_DEBUG_PATH      4   /* crashdump log location */
-#define PSDEV_DEBUG_DUMP_PATH 5   /* crashdump tracelog location */
-#define PSDEV_PORTALS_UPCALL  6   /* User mode upcall script  */
+#define PSDEV_CONSOLE         4   /* allow _any_ messages to console */
+#define PSDEV_DEBUG_PATH      5   /* crashdump log location */
+#define PSDEV_DEBUG_DUMP_PATH 6   /* crashdump tracelog location */
+#define PSDEV_PORTALS_UPCALL  7   /* User mode upcall script  */
 
-#define PORTALS_PRIMARY_CTLCNT 6
+#define PORTALS_PRIMARY_CTLCNT 7
 static struct ctl_table portals_table[PORTALS_PRIMARY_CTLCNT + 1] = {
         {PSDEV_DEBUG, "debug", &portal_debug, sizeof(int), 0644, NULL,
          &proc_dointvec},
@@ -75,6 +78,8 @@ static struct ctl_table portals_table[PORTALS_PRIMARY_CTLCNT + 1] = {
          sizeof(int), 0644, NULL, &proc_dointvec},
         {PSDEV_PRINTK, "printk", &portal_printk, sizeof(int), 0644, NULL,
          &proc_dointvec},
+        {PSDEV_CONSOLE, "console", &portal_cerror, sizeof(int), 0644, NULL,
+         &proc_dointvec},
         {PSDEV_DEBUG_PATH, "debug_path", debug_file_path,
          sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string},
         {PSDEV_DEBUG_DUMP_PATH, "debug_daemon_path", debug_daemon_file_path,
diff --git a/lnet/lnet/api-eq.c b/lnet/lnet/api-eq.c
index e066619ab3d9402384ba78ca874a846c066aa946..9bc9c36d84e06fcc616a19c470e6e28712b013e2 100644
--- a/lnet/lnet/api-eq.c
+++ b/lnet/lnet/api-eq.c
@@ -123,13 +123,22 @@ static jmp_buf eq_jumpbuf;
 
 static void eq_timeout(int signal)
 {
+        sigset_t set;
+
+        /* signal will be automatically disabled in sig handler,
+         * must enable it before long jump
+         */
+        sigemptyset(&set);
+        sigaddset(&set, SIGALRM);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+
         longjmp(eq_jumpbuf, -1);
 }
 
 int PtlEQWait_timeout(ptl_handle_eq_t eventq_in, ptl_event_t * event_out,
                       int timeout)
 {
-        static void (*prev) (int);
+        static void (*prev) (int) = NULL;
         static int left_over;
         time_t time_at_start;
         int rc;
@@ -143,7 +152,7 @@ int PtlEQWait_timeout(ptl_handle_eq_t eventq_in, ptl_event_t * event_out,
         left_over = alarm(timeout);
         prev = signal(SIGALRM, eq_timeout);
         time_at_start = time(NULL);
-        if (left_over < timeout)
+        if (left_over && left_over < timeout)
                 alarm(left_over);
 
         rc = PtlEQWait(eventq_in, event_out);
diff --git a/lnet/lnet/api-init.c b/lnet/lnet/api-init.c
index dc1fead5c1a6f134de0d391c0dc885434c6a729f..020a2a9fa21824e30d35795d1a6e27b9b4e5db40 100644
--- a/lnet/lnet/api-init.c
+++ b/lnet/lnet/api-init.c
@@ -26,8 +26,9 @@
 #include <portals/api-support.h>
 
 int ptl_init;
-unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL | S_GMNAL);
+unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL | S_GMNAL | S_IBNAL);
 unsigned int portal_debug = ~0;
+unsigned int portal_cerror = 1;
 unsigned int portal_printk;
 unsigned int portal_stack;
 
diff --git a/lnet/lnet/lib-init.c b/lnet/lnet/lib-init.c
index 99c4d32c3e28e31a524ade40acfbdeb051012a62..ab223d6de670dc2f5435a18c326132086fe7e3ff 100644
--- a/lnet/lnet/lib-init.c
+++ b/lnet/lnet/lib-init.c
@@ -127,6 +127,8 @@ kportal_descriptor_setup (nal_cb_t *nal)
 void
 kportal_descriptor_cleanup (nal_cb_t *nal)
 {
+        int rc;
+
         if (--ptl_slab_users != 0)
                 return;
 
@@ -135,14 +137,26 @@ kportal_descriptor_cleanup (nal_cb_t *nal)
         LASSERT (atomic_read (&eq_in_use_count) == 0);
         LASSERT (atomic_read (&msg_in_use_count) == 0);
 
-        if (ptl_md_slab != NULL)
-                kmem_cache_destroy(ptl_md_slab);
-        if (ptl_msg_slab != NULL)
-                kmem_cache_destroy(ptl_msg_slab);
-        if (ptl_me_slab != NULL)
-                kmem_cache_destroy(ptl_me_slab);
-        if (ptl_eq_slab != NULL)
-                kmem_cache_destroy(ptl_eq_slab);
+        if (ptl_md_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_md_slab);
+                if (rc != 0)
+                        CERROR("unable to free MD slab\n");
+        }
+        if (ptl_msg_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_msg_slab);
+                if (rc != 0)
+                        CERROR("unable to free MSG slab\n");
+        }
+        if (ptl_me_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_me_slab);
+                if (rc != 0)
+                        CERROR("unable to free ME slab\n");
+        }
+        if (ptl_eq_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_eq_slab);
+                if (rc != 0)
+                        CERROR("unable to free EQ slab\n");
+        }
 }
 #else
 
diff --git a/lnet/lnet/lib-md.c b/lnet/lnet/lib-md.c
index a79e2be30bf1506e74abf9dcdcf0957b8935e6a7..be6949c11f982e83f4c61d84a25cd79757137ab8 100644
--- a/lnet/lnet/lib-md.c
+++ b/lnet/lnet/lib-md.c
@@ -396,8 +396,7 @@ int do_PtlMDUpdate_internal(nal_cb_t * nal, void *private, void *v_args,
             test_eq->sequence == args->sequence_in) {
                 lib_me_t *me = md->me;
 
-#warning this does not track eq refcounts properly
-
+                // #warning this does not track eq refcounts properly 
                 ret->rc = lib_md_build(nal, md, private,
                                        new, &new->eventq, md->unlink);
 
diff --git a/lnet/lnet/lib-me.c b/lnet/lnet/lib-me.c
index bd1af5bbdcd06e16d4655e62ab2d7a579391d5b1..31ac21454cd5ebb4b7a2ccc06d3e676e37dcf132 100644
--- a/lnet/lnet/lib-me.c
+++ b/lnet/lnet/lib-me.c
@@ -44,7 +44,7 @@ int do_PtlMEAttach(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         unsigned long flags;
         lib_me_t *me;
 
-        if (args->index_in < 0 || args->index_in >= tbl->size)
+        if (args->index_in >= tbl->size)
                 return ret->rc = PTL_INV_PTINDEX;
 
         /* Should check for valid matchid, but not yet */
diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c
index 691588596fcbc548077b8f1fdffcc0383411da4b..6e904ba7e330ccabc9e40c5bbc0713fb454d5bfd 100644
--- a/lnet/lnet/lib-move.c
+++ b/lnet/lnet/lib-move.c
@@ -305,8 +305,6 @@ lib_extract_iov (struct iovec *dst, lib_md_t *md,
         ptl_size_t      frag_len;
         int             dst_niov;
 
-        LASSERT (len >= 0);
-        LASSERT (offset >= 0);
         LASSERT (offset + len <= md->length);
         
         if (len == 0)                           /* no data => */
@@ -442,8 +440,6 @@ lib_extract_kiov (ptl_kiov_t *dst, lib_md_t *md,
         ptl_size_t      frag_len;
         int             dst_niov;
 
-        LASSERT (len >= 0);
-        LASSERT (offset >= 0);
         LASSERT (offset + len <= md->length);
         
         if (len == 0)                           /* no data => */
@@ -587,7 +583,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         me = lib_find_me(nal, hdr->msg.put.ptl_index, PTL_MD_OP_PUT,
                          hdr->src_nid, hdr->src_pid,
-                         PTL_HDR_LENGTH (hdr), hdr->msg.put.offset,
+                         hdr->payload_length, hdr->msg.put.offset,
                          hdr->msg.put.match_bits,
                          &mlength, &offset, &unlink);
         if (me == NULL)
@@ -596,7 +592,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         md = me->md;
         CDEBUG(D_NET, "Incoming put index %x from "LPU64"/%u of length %d/%d "
                "into md "LPX64" [%d] + %d\n", hdr->msg.put.ptl_index,
-               hdr->src_nid, hdr->src_pid, mlength, PTL_HDR_LENGTH(hdr), 
+               hdr->src_nid, hdr->src_pid, mlength, hdr->payload_length, 
                md->md_lh.lh_cookie, md->md_niov, offset);
 
         msg = get_new_msg (nal, md);
@@ -621,7 +617,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                 msg->ev.initiator.pid = hdr->src_pid;
                 msg->ev.portal = hdr->msg.put.ptl_index;
                 msg->ev.match_bits = hdr->msg.put.match_bits;
-                msg->ev.rlength = PTL_HDR_LENGTH(hdr);
+                msg->ev.rlength = hdr->payload_length;
                 msg->ev.mlength = mlength;
                 msg->ev.offset = offset;
                 msg->ev.hdr_data = hdr->msg.put.hdr_data;
@@ -650,14 +646,14 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         state_unlock(nal, &flags);
 
-        lib_recv (nal, private, msg, md, offset, mlength, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, msg, md, offset, mlength, hdr->payload_length);
         return 0;
 
  drop:
         nal->ni.counters.drop_count++;
-        nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+        nal->ni.counters.drop_length += hdr->payload_length;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -680,11 +676,6 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         hdr->msg.get.sink_length = NTOH__u32 (hdr->msg.get.sink_length);
         hdr->msg.get.src_offset = NTOH__u32 (hdr->msg.get.src_offset);
 
-        /* compatibility check until field is deleted */
-        if (hdr->msg.get.return_offset != 0)
-                CERROR("Unexpected non-zero get.return_offset %x from "
-                       LPU64"\n", hdr->msg.get.return_offset, hdr->src_nid);
-
         state_lock(nal, &flags);
 
         me = lib_find_me(nal, hdr->msg.get.ptl_index, PTL_MD_OP_GET,
@@ -698,7 +689,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         md = me->md;
         CDEBUG(D_NET, "Incoming get index %d from "LPU64".%u of length %d/%d "
                "from md "LPX64" [%d] + %d\n", hdr->msg.get.ptl_index,
-               hdr->src_nid, hdr->src_pid, mlength, PTL_HDR_LENGTH(hdr), 
+               hdr->src_nid, hdr->src_pid, mlength, hdr->payload_length, 
                md->md_lh.lh_cookie, md->md_niov, offset);
 
         msg = get_new_msg (nal, md);
@@ -714,7 +705,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                 msg->ev.initiator.pid = hdr->src_pid;
                 msg->ev.portal = hdr->msg.get.ptl_index;
                 msg->ev.match_bits = hdr->msg.get.match_bits;
-                msg->ev.rlength = PTL_HDR_LENGTH(hdr);
+                msg->ev.rlength = hdr->payload_length;
                 msg->ev.mlength = mlength;
                 msg->ev.offset = offset;
                 msg->ev.hdr_data = 0;
@@ -749,7 +740,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         reply.src_nid  = HTON__u64 (ni->nid);
         reply.dest_pid = HTON__u32 (hdr->src_pid);
         reply.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&reply) = HTON__u32 (mlength);
+        reply.payload_length = HTON__u32 (mlength);
 
         reply.msg.reply.dst_wmd = hdr->msg.get.return_wmd;
 
@@ -767,13 +758,13 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         }
 
         /* Complete the incoming message */
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return (rc);
  drop:
         ni->counters.drop_count++;
         ni->counters.drop_length += hdr->msg.get.sink_length;
         state_unlock(nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -786,11 +777,6 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         lib_msg_t       *msg;
         unsigned long    flags;
 
-        /* compatibility check until field is deleted */
-        if (hdr->msg.reply.dst_offset != 0)
-                CERROR("Unexpected non-zero reply.dst_offset %x from "LPU64"\n",
-                       hdr->msg.reply.dst_offset, hdr->src_nid);
-
         state_lock(nal, &flags);
 
         /* NB handles only looked up by creator (no flips) */
@@ -806,7 +792,7 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         LASSERT (md->offset == 0);
 
-        length = rlength = PTL_HDR_LENGTH(hdr);
+        length = rlength = hdr->payload_length;
 
         if (length > md->length) {
                 if ((md->options & PTL_MD_TRUNCATE) == 0) {
@@ -852,9 +838,9 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
  drop:
         nal->ni.counters.drop_count++;
-        nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+        nal->ni.counters.drop_length += hdr->payload_length;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -905,13 +891,13 @@ static int parse_ack(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         ni->counters.recv_count++;
         state_unlock(nal, &flags);
-        lib_recv (nal, private, msg, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, msg, NULL, 0, 0, hdr->payload_length);
         return 0;
 
  drop:
         nal->ni.counters.drop_count++;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -958,7 +944,7 @@ void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr)
                                hdr->msg.put.match_bits);
                 nal->cb_printf(nal,
                                "    Length %d, offset %d, hdr data "LPX64"\n",
-                               PTL_HDR_LENGTH(hdr), hdr->msg.put.offset,
+                               hdr->payload_length, hdr->msg.put.offset,
                                hdr->msg.put.hdr_data);
                 break;
 
@@ -988,7 +974,7 @@ void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr)
                                "length %d\n",
                                hdr->msg.reply.dst_wmd.wh_interface_cookie,
                                hdr->msg.reply.dst_wmd.wh_object_cookie,
-                               PTL_HDR_LENGTH(hdr));
+                               hdr->payload_length);
         }
 
 }                               /* end of print_hdr() */
@@ -998,21 +984,13 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 {
         unsigned long  flags;
 
-        /* NB static check; optimizer will elide this if it's right */
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.put.length));
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.get.length));
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.reply.length));
-
         /* convert common fields to host byte order */
         hdr->dest_nid = NTOH__u64 (hdr->dest_nid);
         hdr->src_nid = NTOH__u64 (hdr->src_nid);
         hdr->dest_pid = NTOH__u32 (hdr->dest_pid);
         hdr->src_pid = NTOH__u32 (hdr->src_pid);
         hdr->type = NTOH__u32 (hdr->type);
-        PTL_HDR_LENGTH(hdr) = NTOH__u32 (PTL_HDR_LENGTH(hdr));
+        hdr->payload_length = NTOH__u32(hdr->payload_length);
 #if 0
         nal->cb_printf(nal, "%d: lib_parse: nal=%p hdr=%p type=%d\n",
                        nal->ni.nid, nal, hdr, hdr->type);
@@ -1027,7 +1005,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                         nal->ni.nid, mv->magic, 
                         mv->version_major, mv->version_minor,
                         hdr->src_nid);
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
         
@@ -1038,10 +1016,10 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
                 state_lock (nal, &flags);
                 nal->ni.counters.drop_count++;
-                nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+                nal->ni.counters.drop_length += hdr->payload_length;
                 state_unlock (nal, &flags);
 
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
 
@@ -1052,6 +1030,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                        ": simulated failure\n",
                        nal->ni.nid, hdr_type_string (hdr), 
                        hdr->src_nid);
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
         
@@ -1072,7 +1051,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                        ": Bad type=0x%x\n",  nal->ni.nid, hdr->src_nid,
                        hdr->type);
 
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
 }
@@ -1129,7 +1108,7 @@ int do_PtlPut(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         hdr.src_nid  = HTON__u64 (ni->nid);
         hdr.dest_pid = HTON__u32 (id->pid);
         hdr.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&hdr) = HTON__u32 (md->length);
+        hdr.payload_length = HTON__u32 (md->length);
 
         /* NB handles only looked up by creator (no flips) */
         if (args->ack_req_in == PTL_ACK_REQ) {
@@ -1193,6 +1172,68 @@ int do_PtlPut(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         return ret->rc = PTL_OK;
 }
 
+lib_msg_t * lib_fake_reply_msg (nal_cb_t *nal, ptl_nid_t peer_nid, 
+                                lib_md_t *getmd)
+{
+        /* The NAL can DMA direct to the GET md (i.e. no REPLY msg).  This
+         * returns a msg the NAL can pass to lib_finalize() so that a REPLY
+         * event still occurs. 
+         *
+         * CAVEAT EMPTOR: 'getmd' is passed by pointer so it MUST be valid.
+         * This can only be guaranteed while a lib_msg_t holds a reference
+         * on it (ie. pending > 0), so best call this before the
+         * lib_finalize() of the original GET. */
+
+        lib_ni_t        *ni = &nal->ni;
+        lib_msg_t       *msg;
+        unsigned long    flags;
+
+        state_lock(nal, &flags);
+
+        LASSERT (getmd->pending > 0);
+
+        if (getmd->threshold == 0) {
+                CERROR ("Dropping REPLY from "LPU64" for inactive MD %p\n",
+                        peer_nid, getmd);
+                goto drop;
+        }
+
+        LASSERT (getmd->offset == 0);
+
+        CDEBUG(D_NET, "Reply from "LPU64" md %p\n", peer_nid, getmd);
+
+        msg = get_new_msg (nal, getmd);
+        if (msg == NULL) {
+                CERROR("Dropping REPLY from "LPU64" md %p: can't allocate msg\n", 
+                       peer_nid, getmd);
+                goto drop;
+        }
+
+        if (getmd->eq) {
+                msg->ev.type = PTL_EVENT_REPLY;
+                msg->ev.initiator.nid = peer_nid;
+                msg->ev.initiator.pid = 0;      /* XXX FIXME!!! */
+                msg->ev.rlength = msg->ev.mlength = getmd->length;
+                msg->ev.offset = 0;
+
+                lib_md_deconstruct(nal, getmd, &msg->ev.mem_desc);
+        }
+
+        ni->counters.recv_count++;
+        ni->counters.recv_length += getmd->length;
+
+        state_unlock(nal, &flags);
+
+        return msg;
+        
+ drop:
+        nal->ni.counters.drop_count++;
+        nal->ni.counters.drop_length += getmd->length;
+
+        state_unlock (nal, &flags);
+
+        return NULL;
+}
 
 int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 {
@@ -1244,7 +1285,7 @@ int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         hdr.src_nid  = HTON__u64 (ni->nid);
         hdr.dest_pid = HTON__u32 (id->pid);
         hdr.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&hdr) = 0;
+        hdr.payload_length = 0;
 
         /* NB handles only looked up by creator (no flips) */
         hdr.msg.get.return_wmd.wh_interface_cookie = ni->ni_interface_cookie;
@@ -1305,12 +1346,15 @@ int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 
 void lib_assert_wire_constants (void)
 {
-        /* Wire protocol assertions generated by 'wirecheck' */
+        /* Wire protocol assertions generated by 'wirecheck'
+         * running on Linux robert.bartonsoftware.com 2.4.20-18.9 #1 Thu May 29 06:54:41 EDT 2003 i68
+         * with gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) */
+
 
         /* Constants... */
         LASSERT (PORTALS_PROTO_MAGIC == 0xeebc0ded);
         LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        LASSERT (PORTALS_PROTO_VERSION_MINOR == 1);
+        LASSERT (PORTALS_PROTO_VERSION_MINOR == 3);
         LASSERT (PTL_MSG_ACK == 0);
         LASSERT (PTL_MSG_PUT == 1);
         LASSERT (PTL_MSG_GET == 2);
@@ -1318,79 +1362,77 @@ void lib_assert_wire_constants (void)
         LASSERT (PTL_MSG_HELLO == 4);
 
         /* Checks for struct ptl_handle_wire_t */
-        LASSERT (sizeof (ptl_handle_wire_t) == 16);
-        LASSERT (offsetof (ptl_handle_wire_t, wh_interface_cookie) == 0);
-        LASSERT (sizeof (((ptl_handle_wire_t *)0)->wh_interface_cookie) == 8);
-        LASSERT (offsetof (ptl_handle_wire_t, wh_object_cookie) == 8);
-        LASSERT (sizeof (((ptl_handle_wire_t *)0)->wh_object_cookie) == 8);
+        LASSERT ((int)sizeof(ptl_handle_wire_t) == 16);
+        LASSERT (offsetof(ptl_handle_wire_t, wh_interface_cookie) == 0);
+        LASSERT ((int)sizeof(((ptl_handle_wire_t *)0)->wh_interface_cookie) == 8);
+        LASSERT (offsetof(ptl_handle_wire_t, wh_object_cookie) == 8);
+        LASSERT ((int)sizeof(((ptl_handle_wire_t *)0)->wh_object_cookie) == 8);
 
         /* Checks for struct ptl_magicversion_t */
-        LASSERT (sizeof (ptl_magicversion_t) == 8);
-        LASSERT (offsetof (ptl_magicversion_t, magic) == 0);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->magic) == 4);
-        LASSERT (offsetof (ptl_magicversion_t, version_major) == 4);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->version_major) == 2);
-        LASSERT (offsetof (ptl_magicversion_t, version_minor) == 6);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->version_minor) == 2);
+        LASSERT ((int)sizeof(ptl_magicversion_t) == 8);
+        LASSERT (offsetof(ptl_magicversion_t, magic) == 0);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->magic) == 4);
+        LASSERT (offsetof(ptl_magicversion_t, version_major) == 4);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->version_major) == 2);
+        LASSERT (offsetof(ptl_magicversion_t, version_minor) == 6);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->version_minor) == 2);
 
         /* Checks for struct ptl_hdr_t */
-        LASSERT (sizeof (ptl_hdr_t) == 72);
-        LASSERT (offsetof (ptl_hdr_t, dest_nid) == 0);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->dest_nid) == 8);
-        LASSERT (offsetof (ptl_hdr_t, src_nid) == 8);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->src_nid) == 8);
-        LASSERT (offsetof (ptl_hdr_t, dest_pid) == 16);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->dest_pid) == 4);
-        LASSERT (offsetof (ptl_hdr_t, src_pid) == 20);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->src_pid) == 4);
-        LASSERT (offsetof (ptl_hdr_t, type) == 24);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->type) == 4);
+        LASSERT ((int)sizeof(ptl_hdr_t) == 72);
+        LASSERT (offsetof(ptl_hdr_t, dest_nid) == 0);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->dest_nid) == 8);
+        LASSERT (offsetof(ptl_hdr_t, src_nid) == 8);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->src_nid) == 8);
+        LASSERT (offsetof(ptl_hdr_t, dest_pid) == 16);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->dest_pid) == 4);
+        LASSERT (offsetof(ptl_hdr_t, src_pid) == 20);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->src_pid) == 4);
+        LASSERT (offsetof(ptl_hdr_t, type) == 24);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->type) == 4);
+        LASSERT (offsetof(ptl_hdr_t, payload_length) == 28);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->payload_length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg) == 40);
 
         /* Ack */
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.mlength) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.mlength) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.dst_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.dst_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.dst_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.dst_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.mlength) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.mlength) == 4);
 
         /* Put */
-        LASSERT (offsetof (ptl_hdr_t, msg.put.ptl_index) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.ptl_index) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.ack_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.ack_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.length) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.offset) == 60);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.hdr_data) == 64);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.hdr_data) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.ack_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.ack_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.hdr_data) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.hdr_data) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.ptl_index) == 64);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.ptl_index) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.offset) == 68);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.offset) == 4);
 
         /* Get */
-        LASSERT (offsetof (ptl_hdr_t, msg.get.ptl_index) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.ptl_index) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.return_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.return_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.length) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.src_offset) == 60);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.src_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.return_offset) == 64);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.return_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.sink_length) == 68);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.sink_length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.return_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.return_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.ptl_index) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.ptl_index) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.src_offset) == 60);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.src_offset) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.sink_length) == 64);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.sink_length) == 4);
 
         /* Reply */
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.dst_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.dst_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.dst_offset) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.dst_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.reply.dst_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.reply.dst_wmd) == 16);
+
+        /* Hello */
+        LASSERT (offsetof(ptl_hdr_t, msg.hello.incarnation) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.hello.incarnation) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.hello.type) == 40);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.hello.type) == 4);
 }
diff --git a/lnet/lnet/lib-msg.c b/lnet/lnet/lib-msg.c
index 9363251054ae662971c22d04df3919ef43d8337a..9840ff53d086ffd30d162a8d738d48a7bb8915a6 100644
--- a/lnet/lnet/lib-msg.c
+++ b/lnet/lnet/lib-msg.c
@@ -59,7 +59,7 @@ int lib_finalize(nal_cb_t * nal, void *private, lib_msg_t *msg)
                 ack.src_nid  = HTON__u64 (nal->ni.nid);
                 ack.dest_pid = HTON__u32 (msg->pid);
                 ack.src_pid  = HTON__u32 (nal->ni.pid);
-                PTL_HDR_LENGTH(&ack) = 0;
+                ack.payload_length = 0;
 
                 ack.msg.ack.dst_wmd = msg->ack_wmd;
                 ack.msg.ack.match_bits = msg->ev.match_bits;
diff --git a/lnet/lnet/lib-ni.c b/lnet/lnet/lib-ni.c
index aa30329dcd9a06160b4673f8f9d3bd88d2d8cbad..9e90576c29dd9d80ecfa889caa578d8d786c30f8 100644
--- a/lnet/lnet/lib-ni.c
+++ b/lnet/lnet/lib-ni.c
@@ -27,7 +27,7 @@
 #include <portals/lib-p30.h>
 #include <portals/arg-blocks.h>
 
-#define MAX_DIST 18446744073709551615UL
+#define MAX_DIST 18446744073709551615ULL
 
 int do_PtlNIDebug(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 {
diff --git a/lnet/router/router.c b/lnet/router/router.c
index f0824157d5e1c2f14a202bbb8d574cb0df7d8bfd..e29f62877c1dccdd1c6e495aaf793e4d8e0d8a50 100644
--- a/lnet/router/router.c
+++ b/lnet/router/router.c
@@ -126,12 +126,16 @@ kpr_do_upcall (void *arg)
 void
 kpr_upcall (int gw_nalid, ptl_nid_t gw_nid, int alive, time_t when)
 {
+        char str[PTL_NALFMT_SIZE];
+        
         /* May be in arbitrary context */
         kpr_upcall_t  *u = kmalloc (sizeof (kpr_upcall_t), GFP_ATOMIC);
 
         if (u == NULL) {
-                CERROR ("Upcall out of memory: nal %d nid "LPX64" %s\n",
-                        gw_nalid, gw_nid, alive ? "up" : "down");
+                CERROR ("Upcall out of memory: nal %d nid "LPX64" (%s) %s\n",
+                        gw_nalid, gw_nid,
+                        portals_nid2str(gw_nalid, gw_nid, str),
+                        alive ? "up" : "down");
                 return;
         }
 
@@ -155,6 +159,7 @@ kpr_do_notify (int byNal, int gateway_nalid, ptl_nid_t gateway_nid,
         struct timeval       now;
 	struct list_head    *e;
 	struct list_head    *n;
+        char                 str[PTL_NALFMT_SIZE];
 
         CDEBUG (D_NET, "%s notifying [%d] "LPX64": %s\n", 
                 byNal ? "NAL" : "userspace", 
@@ -253,8 +258,9 @@ kpr_do_notify (int byNal, int gateway_nalid, ptl_nid_t gateway_nid,
         
         if (byNal) {
                 /* It wasn't userland that notified me... */
-                CWARN ("Upcall: NAL %d NID "LPX64" is %s\n",
+                CWARN ("Upcall: NAL %d NID "LPX64" (%s) is %s\n",
                        gateway_nalid, gateway_nid,
+                       portals_nid2str(gateway_nalid, gateway_nid, str),
                        alive ? "alive" : "dead");
                 kpr_upcall (gateway_nalid, gateway_nid, alive, when);
         } else {
@@ -580,8 +586,10 @@ kpr_add_route (int gateway_nalid, ptl_nid_t gateway_nid,
         atomic_set (&ge->kpge_weight, 0);
 
         PORTAL_ALLOC (re, sizeof (*re));
-        if (re == NULL)
+        if (re == NULL) {
+                PORTAL_FREE (ge, sizeof (*ge));
                 return (-ENOMEM);
+        }
 
         re->kpre_lo_nid = lo_nid;
         re->kpre_hi_nid = hi_nid;
diff --git a/lnet/router/router.h b/lnet/router/router.h
index c5cc1d3efdfb4a9f8595b9f68db6d4a0942f7b34..ea25439e9229bd61ed5864d05689be5c6a69d79c 100644
--- a/lnet/router/router.h
+++ b/lnet/router/router.h
@@ -23,7 +23,9 @@
 
 #ifndef _KPTLROUTER_H
 #define _KPTLROUTER_H
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -69,7 +71,7 @@ typedef struct
 
 typedef struct
 {
-        struct tq_struct        kpru_tq;
+        work_struct_t           kpru_tq;
         int                     kpru_nal_id;
         ptl_nid_t               kpru_nid;
         int                     kpru_alive;
diff --git a/lnet/tests/ping_cli.c b/lnet/tests/ping_cli.c
index 4d04ffbcbb8bfd8cd773da448ed170f35b7275fb..85c0d71dcd4ba67d0e6215d8fa1ae0c7afb8c778 100644
--- a/lnet/tests/ping_cli.c
+++ b/lnet/tests/ping_cli.c
@@ -91,14 +91,14 @@ static int pingcli_callback(ptl_event_t *ev)
         magic = *(int *)(ev->mem_desc.start + ev->offset);
 
         if(magic != 0xcafebabe) {
-                printk ("Unexpected response \n");
+                printk ("LustreError: Unexpected response \n");
                 return 1;
         }
 
         if((i == count) || !count)
                 wake_up_process (client->tsk);
         else
-                printk ("Received response after timeout for %d\n",i);
+                printk ("LustreError: Received response after timeout for %d\n",i);
         return 1;
 }
 
@@ -111,11 +111,15 @@ pingcli_start(struct portal_ioctl_data *args)
         unsigned ping_bulk_magic = PING_BULK_MAGIC;
         int rc;
         struct timeval tv1, tv2;
+        char str[PTL_NALFMT_SIZE];
+        
         client->tsk = current;
         client->args = args;
-        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64",  \
+        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64" (%s),  \
                         nal %d, size %u, count: %u, timeout: %u\n",
-                        args->ioc_nid, args->ioc_nal, args->ioc_size,
+                        args->ioc_nid,
+                        portals_nid2str(args->ioc_nal, args->ioc_nid, str),
+                        args->ioc_nal, args->ioc_size,
                         args->ioc_count, args->ioc_timeout);
 
 
@@ -229,15 +233,15 @@ pingcli_start(struct portal_ioctl_data *args)
                          pingcli_shutdown (1);
                          return NULL;
                 }
-                printk ("sent msg no %d", count);
+                printk ("Lustre: sent msg no %d", count);
 
                 set_current_state (TASK_INTERRUPTIBLE);
                 rc = schedule_timeout (20 * args->ioc_timeout);
                 if (rc == 0) {
-                        printk ("   ::  timeout .....\n");
+                        printk ("LustreError:   ::  timeout .....\n");
                 } else {
                         do_gettimeofday (&tv2);
-                        printk("   ::  Reply in %u usec\n",
+                        printk("Lustre:   ::  Reply in %u usec\n",
                                 (unsigned)((tv2.tv_sec - tv1.tv_sec)
                                  * 1000000 +  (tv2.tv_usec - tv1.tv_usec)));
                 }
diff --git a/lnet/tests/ping_srv.c b/lnet/tests/ping_srv.c
index 873e11ce312e84981f6eb8312e33dc54bddf09eb..2a96f5531df9636a007acf4fd661534f50495cbd 100644
--- a/lnet/tests/ping_srv.c
+++ b/lnet/tests/ping_srv.c
@@ -121,7 +121,7 @@ int pingsrv_thread(void *arg)
                 
                 
                 if(magic != 0xdeadbeef) {
-                        printk("Unexpected Packet to the server\n");
+                        printk("LustreError: Unexpected Packet to the server\n");
                         
                 } 
                 memcpy (server->in_buf, &ping_bulk_magic, sizeof(ping_bulk_magic));
@@ -183,7 +183,7 @@ static int pingsrv_callback(ptl_event_t *ev)
         }
         server->evnt = *ev;
         
-        printk ("received ping from nid "LPX64" "
+        printk ("Lustre: received ping from nid "LPX64" "
                "(off=%u rlen=%u mlen=%u head=%x seq=%d size=%d)\n",
                ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
                *((int *)(ev->mem_desc.start + ev->offset)),
diff --git a/lnet/tests/sping_cli.c b/lnet/tests/sping_cli.c
index 35e114b6af491e1f74f5aba1f0c752dc7fc219cf..64a1dd2ef660248cd94f2d31e5cd990d18a8129d 100644
--- a/lnet/tests/sping_cli.c
+++ b/lnet/tests/sping_cli.c
@@ -104,14 +104,17 @@ pingcli_start(struct portal_ioctl_data *args)
 {
         const ptl_handle_ni_t *nip;
         unsigned ping_head_magic = PING_HEADER_MAGIC;
+        char str[PTL_NALFMT_SIZE];
         int rc;
 
         client->tsk = current;
         client->args = args;
 
-        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64",  \
+        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64" (%s),  \
                         nal %d, size %u, count: %u, timeout: %u\n",
-                        args->ioc_nid, args->ioc_nal, args->ioc_size,
+                        args->ioc_nid,
+                        portals_nid2str(args->ioc_nid, args->ioc_nal, str),
+                        args->ioc_nal, args->ioc_size,
                         args->ioc_count, args->ioc_timeout);
 
 
@@ -219,11 +222,11 @@ pingcli_start(struct portal_ioctl_data *args)
         set_current_state (TASK_INTERRUPTIBLE);
         rc = schedule_timeout (20 * args->ioc_timeout);
         if (rc == 0) {
-                printk (" Time out on the server\n");
+                printk ("LustreError: Time out on the server\n");
                 pingcli_shutdown (2);
                 return NULL;
         } else
-                printk("Received respose from the server \n");
+                printk("Lustre: Received respose from the server \n");
 
 
         pingcli_shutdown (2);
diff --git a/lnet/tests/sping_srv.c b/lnet/tests/sping_srv.c
index 2b45a46ff7a197d35d2b27e67a58c455b05fd2dc..0d52e1f1020f8ab71c7733e7c69ac2464e2a6099 100644
--- a/lnet/tests/sping_srv.c
+++ b/lnet/tests/sping_srv.c
@@ -175,7 +175,7 @@ static int pingsrv_callback(ptl_event_t *ev)
         }
         server->evnt = *ev;
         
-        printk ("received ping from nid "LPX64" "
+        printk ("Lustre: received ping from nid "LPX64" "
                "(off=%u rlen=%u mlen=%u head=%x)\n",
                ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
                *((int *)(ev->mem_desc.start + ev->offset)));
diff --git a/lnet/tests/startclient.sh b/lnet/tests/startclient.sh
index c9b7c166f3a5664736acd6d0b36402ad2c68e640..de01bc7ac8e040df880afb027feb2d5ce4d02c3d 100644
--- a/lnet/tests/startclient.sh
+++ b/lnet/tests/startclient.sh
@@ -29,9 +29,16 @@ case "$1" in
 		/sbin/insmod ./$PING
 		echo kqswnal > /tmp/nal
 	;;
+
+	gm)
+		/sbin/insmod  portals
+		/sbin/insmod kgmnal
+		/sbin/insmod ./$PING
+		echo kgmnal > /tmp/nal
+	;;
 	
 	*)
-		echo "Usage : ${0} < tcp | toe | elan >"
+		echo "Usage : ${0} < tcp | toe | elan | gm>"
 		exit 1;
 esac
 exit 0;
diff --git a/lnet/tests/startserver.sh b/lnet/tests/startserver.sh
index 942300efadf2aa2e866c9d7d43e6bbc5496e24de..4f66eeb908b0d3013331187c69eeaa918c8aaed0 100644
--- a/lnet/tests/startserver.sh
+++ b/lnet/tests/startserver.sh
@@ -29,9 +29,16 @@ case "$1" in
 		/sbin/insmod ./$PING nal=4
 		echo kqswnal > /tmp/nal
 	;;
+
+	gm)
+		/sbin/insmod  portals
+		/sbin/insmod kgmnal
+		/sbin/insmod ./$PING nal=3
+		echo kgmnal > /tmp/nal
+	;;
 	
 	*)
-		echo "Usage : ${0} < tcp | toe | elan >"
+		echo "Usage : ${0} < tcp | toe | elan | gm>"
 		exit 1;
 esac
 ../utils/acceptor 9999&
diff --git a/lnet/ulnds/connection.c b/lnet/ulnds/connection.c
index edd7c961a31ec21ee4813eb187c932cfb6fa14b4..3e64b330444cb16c7e42f73e48ab88ada1ddb65d 100644
--- a/lnet/ulnds/connection.c
+++ b/lnet/ulnds/connection.c
@@ -34,13 +34,21 @@
 #include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <portals/types.h>
+#include <portals/list.h>
+#include <portals/lib-types.h>
+#include <portals/socknal.h>
+#include <linux/kp30.h>
 #include <connection.h>
+#include <pthread.h>
 #include <errno.h>
-
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* global variable: acceptor port */
 unsigned short tcpnal_acceptor_port = 988;
@@ -55,9 +63,14 @@ unsigned short tcpnal_acceptor_port = 988;
  */
 static int compare_connection(void *arg1, void *arg2)
 {
-        connection c = arg1;
-        unsigned int * id = arg2;
-        return((c->ip==id[0]) && (c->port==id[1]));
+    connection c = arg1;
+    unsigned int * id = arg2;
+#if 0
+    return((c->ip==id[0]) && (c->port==id[1]));
+#else
+    /* CFS specific hacking */
+    return (c->ip == id[0]);
+#endif
 }
 
 
@@ -68,7 +81,12 @@ static int compare_connection(void *arg1, void *arg2)
  */
 static unsigned int connection_key(unsigned int *id)
 {
+#if 0
     return(id[0]^id[1]);
+#else
+    /* CFS specific hacking */
+    return (unsigned int) id[0];
+#endif
 }
 
 
@@ -102,22 +120,27 @@ int read_connection(connection c,
                     unsigned char *dest,
                     int len)
 {
-    int offset=0,rc;
+    int offset = 0,rc;
 
-    if (len){
+    if (len) {
         do {
-            if((rc=syscall(SYS_read, c->fd, dest+offset, len-offset))<=0){
-                if (errno==EINTR) {
-                    rc=0;
+#ifndef __CYGWIN__
+            rc = syscall(SYS_read, c->fd, dest+offset, len-offset);
+#else
+            rc = recv(c->fd, dest+offset, len-offset, 0);
+#endif
+            if (rc <= 0) {
+                if (errno == EINTR) {
+                    rc = 0;
                 } else {
                     remove_connection(c);
-                    return(0);
+                    return (0);
                 }
             }
-            offset+=rc;
-        } while (offset<len);
+            offset += rc;
+        } while (offset < len);
     }
-    return(1);
+    return (1);
 }
 
 static int connection_input(void *d)
@@ -172,10 +195,111 @@ static int new_connection(void *z)
     unsigned int nid=*((unsigned int *)&s.sin_addr);
     /* cfs specific hack */
     //unsigned short pid=s.sin_port;
+    pthread_mutex_lock(&m->conn_lock);
     allocate_connection(m,htonl(nid),0/*pid*/,fd);
+    pthread_mutex_unlock(&m->conn_lock);
     return(1);
 }
 
+/* FIXME assuming little endian, cleanup!! */
+#define __cpu_to_le64(x) ((__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(x))
+#define __cpu_to_le32(x) ((__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(x))
+#define __cpu_to_le16(x) ((__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(x))
+
+extern ptl_nid_t tcpnal_mynid;
+
+int
+tcpnal_hello (int sockfd, ptl_nid_t *nid, int type, __u64 incarnation)
+{
+        int                 rc;
+        ptl_hdr_t           hdr;
+        ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
+
+        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
+
+        memset (&hdr, 0, sizeof (hdr));
+        hmv->magic         = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
+        hmv->version_major = __cpu_to_le32 (PORTALS_PROTO_VERSION_MAJOR);
+        hmv->version_minor = __cpu_to_le32 (PORTALS_PROTO_VERSION_MINOR);
+        
+        hdr.src_nid = __cpu_to_le64 (tcpnal_mynid);
+        hdr.type    = __cpu_to_le32 (PTL_MSG_HELLO);
+
+        hdr.msg.hello.type = __cpu_to_le32 (type);
+        hdr.msg.hello.incarnation = 0;
+
+        /* Assume sufficient socket buffering for this message */
+        rc = syscall(SYS_write, sockfd, &hdr, sizeof(hdr));
+        if (rc <= 0) {
+                CERROR ("Error %d sending HELLO to %llx\n", rc, *nid);
+                return (rc);
+        }
+
+        rc = syscall(SYS_read, sockfd, hmv, sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading HELLO from %llx\n", rc, *nid);
+                return (rc);
+        }
+        
+        if (hmv->magic != __le32_to_cpu (PORTALS_PROTO_MAGIC)) {
+                CERROR ("Bad magic %#08x (%#08x expected) from %llx\n",
+                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, *nid);
+                return (-EPROTO);
+        }
+
+        if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
+            hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
+                CERROR ("Incompatible protocol version %d.%d (%d.%d expected)"
+                        " from %llx\n",
+                        __le16_to_cpu (hmv->version_major),
+                        __le16_to_cpu (hmv->version_minor),
+                        PORTALS_PROTO_VERSION_MAJOR,
+                        PORTALS_PROTO_VERSION_MINOR,
+                        *nid);
+                return (-EPROTO);
+        }
+
+#if (PORTALS_PROTO_VERSION_MAJOR != 0)
+# error "This code only understands protocol version 0.x"
+#endif
+        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
+         * so read the rest of it in now... */
+
+        rc = syscall(SYS_read, sockfd, hmv + 1, sizeof(hdr) - sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading rest of HELLO hdr from %llx\n",
+                        rc, *nid);
+                return (rc);
+        }
+
+        /* ...and check we got what we expected */
+        if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
+            hdr.payload_length != __cpu_to_le32 (0)) {
+                CERROR ("Expecting a HELLO hdr with 0 payload,"
+                        " but got type %d with %d payload from %llx\n",
+                        __le32_to_cpu (hdr.type),
+                        __le32_to_cpu (hdr.payload_length), *nid);
+                return (-EPROTO);
+        }
+
+        if (__le64_to_cpu(hdr.src_nid) == PTL_NID_ANY) {
+                CERROR("Expecting a HELLO hdr with a NID, but got PTL_NID_ANY\n");
+                return (-EPROTO);
+        }
+
+        if (*nid == PTL_NID_ANY) {              /* don't know peer's nid yet */
+                *nid = __le64_to_cpu(hdr.src_nid);
+        } else if (*nid != __le64_to_cpu (hdr.src_nid)) {
+                CERROR ("Connected to nid %llx, but expecting %llx\n",
+                        __le64_to_cpu (hdr.src_nid), *nid);
+                return (-EPROTO);
+        }
+
+        return (0);
+}
 
 /* Function:  force_tcp_connection
  * Arguments: t: tcpnal
@@ -187,17 +311,22 @@ connection force_tcp_connection(manager m,
                                 unsigned int ip,
                                 unsigned short port)
 {
-    connection c;
+    connection conn;
     struct sockaddr_in addr;
     unsigned int id[2];
 
     port = tcpnal_acceptor_port;
 
-    id[0]=ip;
-    id[1]=port;
+    id[0] = ip;
+    id[1] = port;
 
-    if (!(c=hash_table_find(m->connections,id))){
+    pthread_mutex_lock(&m->conn_lock);
+
+    conn = hash_table_find(m->connections, id);
+    if (!conn) {
         int fd;
+        int option;
+        ptl_nid_t peernid = PTL_NID_ANY;
 
         bzero((char *) &addr, sizeof(addr));
         addr.sin_family      = AF_INET;
@@ -208,16 +337,30 @@ connection force_tcp_connection(manager m,
             perror("tcpnal socket failed");
             exit(-1);
         }
-        if (connect(fd,
-                    (struct sockaddr *)&addr,
-                    sizeof(struct sockaddr_in)))
-            {
-                perror("tcpnal connect");
-                return(0);
-            }
-        return(allocate_connection(m,ip,port,fd));
+        if (connect(fd, (struct sockaddr *)&addr,
+                    sizeof(struct sockaddr_in))) {
+            perror("tcpnal connect");
+            return(0);
+        }
+
+#if 1
+        option = 1;
+        setsockopt(fd, SOL_TCP, TCP_NODELAY, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
+#endif
+   
+        /* say hello */
+        if (tcpnal_hello(fd, &peernid, SOCKNAL_CONN_ANY, 0))
+            exit(-1);
+
+        conn = allocate_connection(m, ip, port, fd);
     }
-    return(c);
+
+    pthread_mutex_unlock(&m->conn_lock);
+    return (conn);
 }
 
 
@@ -243,8 +386,8 @@ static int bind_socket(manager m,unsigned short port)
     bzero((char *) &addr, sizeof(addr));
     addr.sin_family      = AF_INET;
     addr.sin_addr.s_addr = 0;
-    addr.sin_port        = port; 
-    
+    addr.sin_port        = htons(port);
+
     if (bind(m->bound,(struct sockaddr *)&addr,alen)<0){
         perror ("tcpnal bind"); 
         return(0);
@@ -284,11 +427,15 @@ manager init_connections(unsigned short pid,
                          int (*input)(void *, void *),
                          void *a)
 {
-    manager m=(manager)malloc(sizeof(struct manager));
-    m->connections=hash_create_table(compare_connection,connection_key);
-    m->handler=input;
-    m->handler_arg=a;
-    if (bind_socket(m,pid)) return(m);
+    manager m = (manager)malloc(sizeof(struct manager));
+    m->connections = hash_create_table(compare_connection,connection_key);
+    m->handler = input;
+    m->handler_arg = a;
+    pthread_mutex_init(&m->conn_lock, 0);
+
+    if (bind_socket(m,pid))
+        return(m);
+
     free(m);
     return(0);
 }
diff --git a/lnet/ulnds/connection.h b/lnet/ulnds/connection.h
index 6f572874a4ebd100a44038f52b6d74b037d87e04..fb1eaabd0e99d4bf1133e601758c7c772c21630e 100644
--- a/lnet/ulnds/connection.h
+++ b/lnet/ulnds/connection.h
@@ -10,6 +10,7 @@
 
 typedef struct manager {
     table connections;
+    pthread_mutex_t conn_lock; /* protect connections table */
     int bound;
     io_handler bound_handler;
     int (*handler)(void *, void *);
diff --git a/lnet/ulnds/procapi.c b/lnet/ulnds/procapi.c
index f4820b26ca38251b71d6f25fb7b0962aaca970c4..2a3fbd881a514ca79f1282250187a700eb108694 100644
--- a/lnet/ulnds/procapi.c
+++ b/lnet/ulnds/procapi.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,7 +32,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <pqtimer.h>
 #include <dispatch.h>
@@ -48,35 +48,22 @@
  * forwards a packaged api call from the 'api' side to the 'library'
  *   side, and collects the result
  */
-#define forward_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(PTL_SEGV);\
-       }
-static int procbridge_forward(nal_t *n, int id, void *args, ptl_size_t args_len,
+static int procbridge_forward(nal_t *n, int id, void *args, size_t args_len,
 			      void *ret, ptl_size_t ret_len)
 {
-    bridge b=(bridge)n->nal_data;
-    procbridge p=(procbridge)b->local;
-    int lib=p->to_lib[1];
-    int k;
+    bridge b = (bridge) n->nal_data;
 
-    forward_failure(write,lib, &id, sizeof(id));
-    forward_failure(write,lib,&args_len, sizeof(args_len));
-    forward_failure(write,lib,&ret_len, sizeof(ret_len));
-    forward_failure(write,lib,args, args_len);
-
-    do {
-        k=syscall(SYS_read, p->from_lib[0], ret, ret_len);
-    } while ((k!=ret_len) && (errno += EINTR));
+    if (id == PTL_FINI) {
+            lib_fini(b->nal_cb);
 
-    if(k!=ret_len){
-        perror("nal: read return block");
-        return PTL_SEGV;
+            if (b->shutdown)
+                (*b->shutdown)(b);
     }
+
+    lib_dispatch(b->nal_cb, NULL, id, args, ret);
+
     return (PTL_OK);
 }
-#undef forward_failure
 
 
 /* Function: shutdown
@@ -90,15 +77,18 @@ static int procbridge_shutdown(nal_t *n, int ni)
 {
     bridge b=(bridge)n->nal_data;
     procbridge p=(procbridge)b->local;
-    int code=PTL_FINI;
 
-    syscall(SYS_write, p->to_lib[1],&code,sizeof(code));
-    syscall(SYS_read, p->from_lib[0],&code,sizeof(code));
+    p->nal_flags |= NAL_FLAG_STOPPING;
 
-    syscall(SYS_close, p->to_lib[0]);
-    syscall(SYS_close, p->to_lib[1]);
-    syscall(SYS_close, p->from_lib[0]);
-    syscall(SYS_close, p->from_lib[1]);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & NAL_FLAG_STOPPED) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
 
     free(p);
     return(0);
@@ -108,7 +98,7 @@ static int procbridge_shutdown(nal_t *n, int ni)
 /* Function: validate
  *    useless stub
  */
-static int procbridge_validate(nal_t *nal, void *base, ptl_size_t extent)
+static int procbridge_validate(nal_t *nal, void *base, size_t extent)
 {
     return(0);
 }
@@ -151,7 +141,9 @@ static nal_t api_nal = {
     unlock:   procbridge_unlock
 };
 
-/* Function: bridge_init
+ptl_nid_t tcpnal_mynid;
+
+/* Function: procbridge_interface
  *
  * Arguments:  pid: requested process id (port offset)
  *                  PTL_ID_ANY not supported.
@@ -165,77 +157,17 @@ static nal_t api_nal = {
  * initializes the tcp nal. we define unix_failure as an
  * error wrapper to cut down clutter.
  */
-#define unix_failure(operand,fd,buffer,length,text)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          perror(text);\
-          return(NULL);\
-       }
-#if 0
-static nal_t *bridge_init(ptl_interface_t nal,
-                          ptl_pid_t pid_request,
-                          ptl_ni_limits_t *desired,
-                          ptl_ni_limits_t *actual,
-                          int *rc)
-{
-    procbridge p;
-    bridge b;
-    static int initialized=0;
-    ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-
-    if(initialized) return (&api_nal);
-
-    init_unix_timer();
-
-    b=(bridge)malloc(sizeof(struct bridge));
-    p=(procbridge)malloc(sizeof(struct procbridge));
-    api_nal.nal_data=b;
-    b->local=p;
-
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
-    if (desired) limits = *desired;
-    unix_failure(write,p->to_lib[1], &pid_request, sizeof(pid_request),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal, sizeof(ptl_interface_t),
-                       "nal_init: write");
-
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
-        perror("nal_init: pthread_create");
-        return(NULL);
-    }
-
-    unix_failure(read,p->from_lib[0], actual, sizeof(ptl_ni_limits_t),
-                 "tcp_init: read");
-    unix_failure(read,p->from_lib[0], rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(*rc) return(NULL);
-
-    initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
-
-    return (&api_nal);
-}
-#endif
-
-ptl_nid_t tcpnal_mynid;
-
 nal_t *procbridge_interface(int num_interface,
                             ptl_pt_index_t ptl_size,
                             ptl_ac_index_t acl_size,
                             ptl_pid_t requested_pid)
 {
+    nal_init_args_t args;
     procbridge p;
     bridge b;
     static int initialized=0;
     ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-    int rc, nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
+    int nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
 
     if(initialized) return (&api_nal);
 
@@ -246,38 +178,42 @@ nal_t *procbridge_interface(int num_interface,
     api_nal.nal_data=b;
     b->local=p;
 
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
     if (ptl_size)
 	    limits.max_ptable_index = ptl_size;
     if (acl_size)
 	    limits.max_atable_index = acl_size;
 
-    unix_failure(write,p->to_lib[1], &requested_pid, sizeof(requested_pid),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal_type, sizeof(nal_type),
-                       "nal_init: write");
+    args.nia_requested_pid = requested_pid;
+    args.nia_limits = &limits;
+    args.nia_nal_type = nal_type;
+    args.nia_bridge = b;
 
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
+    /* init procbridge */
+    pthread_mutex_init(&p->mutex,0);
+    pthread_cond_init(&p->cond, 0);
+    p->nal_flags = 0;
+    pthread_mutex_init(&p->nal_cb_lock, 0);
+
+    if (pthread_create(&p->t, NULL, nal_thread, &args)) {
         perror("nal_init: pthread_create");
         return(NULL);
     }
 
-    unix_failure(read,p->from_lib[0], &rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(rc) return(NULL);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
+
+    if (p->nal_flags & NAL_FLAG_STOPPED)
+        return (NULL);
 
     b->nal_cb->ni.nid = tcpnal_mynid;
     initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
 
     return (&api_nal);
 }
-#undef unix_failure
diff --git a/lnet/ulnds/procbridge.h b/lnet/ulnds/procbridge.h
index 060ae7b2b937ae52a20e88f55165efc9b4dc6be0..317e22f876149687c944521deee997ae523cac43 100644
--- a/lnet/ulnds/procbridge.h
+++ b/lnet/ulnds/procbridge.h
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
  */
@@ -14,14 +15,28 @@
 #include <ipmap.h>
 
 
+#define NAL_FLAG_RUNNING        1
+#define NAL_FLAG_STOPPING       2
+#define NAL_FLAG_STOPPED        4
+
 typedef struct procbridge {
+    /* sync between user threads and nal thread */
     pthread_t t;
     pthread_cond_t cond;
     pthread_mutex_t mutex;
-    int to_lib[2];
-    int from_lib[2];
+
+    int nal_flags;
+
+    pthread_mutex_t nal_cb_lock;
 } *procbridge;
 
+typedef struct nal_init_args {
+    ptl_pid_t        nia_requested_pid;
+    ptl_ni_limits_t *nia_limits;
+    int              nia_nal_type;
+    bridge           nia_bridge;
+} nal_init_args_t;
+
 extern void *nal_thread(void *);
 
 
@@ -33,8 +48,8 @@ extern void *nal_thread(void *);
 
 extern void set_address(bridge t,ptl_pid_t pidrequest);
 extern nal_t *procbridge_interface(int num_interface,
-                            ptl_pt_index_t ptl_size,
-                            ptl_ac_index_t acl_size,
-                            ptl_pid_t requested_pid);
+                                   ptl_pt_index_t ptl_size,
+                                   ptl_ac_index_t acl_size,
+                                   ptl_pid_t requested_pid);
 
 #endif
diff --git a/lnet/ulnds/proclib.c b/lnet/ulnds/proclib.c
index 99afe66ced9535aa39f3485fa7f9c9878cf20343..2627253d51c76f5fd61f11a3afc7952b18009078 100644
--- a/lnet/ulnds/proclib.c
+++ b/lnet/ulnds/proclib.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,14 +32,12 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <errno.h>
 #include <timer.h>
-//#include <util/pqtimer.h>
 #include <dispatch.h>
 
 /* the following functions are stubs to satisfy the nal definition
@@ -48,7 +47,7 @@ static int nal_write(nal_cb_t *nal,
                      void *private,
                      user_ptr dst_addr,
                      void *src_addr,
-                     ptl_size_t len)
+                     size_t len)
 {
     memcpy(dst_addr, src_addr, len);
     return 0;
@@ -65,7 +64,7 @@ static int nal_read(nal_cb_t * nal,
 }
 
 static void *nal_malloc(nal_cb_t *nal,
-                        ptl_size_t len)
+                        size_t len)
 {
     void *buf =  malloc(len);
     return buf;
@@ -73,7 +72,7 @@ static void *nal_malloc(nal_cb_t *nal,
 
 static void nal_free(nal_cb_t *nal,
                      void *buf,
-                     ptl_size_t len)
+                     size_t len)
 {
     free(buf);
 }
@@ -93,12 +92,20 @@ static void nal_printf(nal_cb_t *nal,
 static void nal_cli(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge) nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_lock(&p->nal_cb_lock);
 }
 
 
 static void nal_sti(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge)nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_unlock(&p->nal_cb_lock);
 }
 
 
@@ -108,69 +115,22 @@ static int nal_dist(nal_cb_t *nal,
 {
     return 0;
 }
-    
-
-
-/* Function:  data_from_api
- * Arguments: t: the nal state for this interface
- * Returns: whether to continue reading from the pipe
- *
- *   data_from_api() reads data from the api side in response
- *   to a select.
- *
- *   We define data_failure() for syntactic convenience
- *   of unix error reporting.
- */
-
-#define data_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(0);\
-       }
-static int data_from_api(void *arg)
-{
-        bridge b = arg;
-    procbridge p=(procbridge)b->local;
-    /* where are these two sizes derived from ??*/
-    char arg_block[ 256 ];
-    char ret_block[ 128 ];
-    ptl_size_t arg_len,ret_len;
-    int fd=p->to_lib[0];
-    int index;
-
-    data_failure(read,fd, &index, sizeof(index));
-
-    if (index==PTL_FINI) {
-        lib_fini(b->nal_cb);
-        if (b->shutdown) (*b->shutdown)(b);
-        syscall(SYS_write, p->from_lib[1],&b->alive,sizeof(b->alive));
-
-        /* a heavy-handed but convenient way of shutting down
-           the lower side thread */
-        pthread_exit(0);
-    }
-
-    data_failure(read,fd, &arg_len, sizeof(arg_len));
-    data_failure(read,fd, &ret_len, sizeof(ret_len));
-    data_failure(read,fd, arg_block, arg_len);
-
-    lib_dispatch(b->nal_cb, NULL, index, arg_block, ret_block);
-
-    data_failure(write,p->from_lib[1],ret_block, ret_len);
-    return(1);
-}
-#undef data_failure
-
-
 
 static void wakeup_topside(void *z)
 {
-    bridge b=z;
-    procbridge p=b->local;
+    bridge b = z;
+    procbridge p = b->local;
+    int stop;
 
     pthread_mutex_lock(&p->mutex);
+    stop = p->nal_flags & NAL_FLAG_STOPPING;
+    if (stop)
+        p->nal_flags |= NAL_FLAG_STOPPED;
     pthread_cond_broadcast(&p->cond);
     pthread_mutex_unlock(&p->mutex);
+
+    if (stop)
+        pthread_exit(0);
 }
 
 
@@ -195,7 +155,8 @@ nal_initialize nal_table[PTL_IFACE_MAX]={0,tcpnal_init,0};
 
 void *nal_thread(void *z)
 {
-    bridge b=z;
+    nal_init_args_t *args = (nal_init_args_t *) z;
+    bridge b = args->nia_bridge;
     procbridge p=b->local;
     int rc;
     ptl_pid_t pid_request;
@@ -216,15 +177,9 @@ void *nal_thread(void *z)
     b->nal_cb->cb_sti=nal_sti;
     b->nal_cb->cb_dist=nal_dist;
 
-
-    register_io_handler(p->to_lib[0],READ_HANDLER,data_from_api,(void *)b);
-
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &pid_request, sizeof(pid_request))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &desired, sizeof(ptl_ni_limits_t))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &nal_type, sizeof(nal_type))))
-        perror("procbridge read from api");
+    pid_request = args->nia_requested_pid;
+    desired = *args->nia_limits;
+    nal_type = args->nia_nal_type;
 
     actual = desired;
     LIMIT(desired.max_match_entries,actual.max_match_entries,MAX_MES);
@@ -251,12 +206,12 @@ void *nal_thread(void *z)
      * it is non-zero since something went wrong.
      */
     /* this should perform error checking */
-#if 0
-    write(p->from_lib[1], &actual, sizeof(ptl_ni_limits_t));
-#endif
-    syscall(SYS_write, p->from_lib[1], &rc, sizeof(rc));
-    
-    if(!rc) {
+    pthread_mutex_lock(&p->mutex);
+    p->nal_flags |= rc ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
+    pthread_cond_broadcast(&p->cond);
+    pthread_mutex_unlock(&p->mutex);
+
+    if (!rc) {
         /* the thunk function is called each time the timer loop
            performs an operation and returns to blocking mode. we
            overload this function to inform the api side that
@@ -267,4 +222,3 @@ void *nal_thread(void *z)
     return(0);
 }
 #undef LIMIT
-
diff --git a/lnet/ulnds/select.c b/lnet/ulnds/select.c
index 47adc50490749c24168a043e0fabf48315739853..fe24efcf3cf8066192cd6cc41963969a369ad659 100644
--- a/lnet/ulnds/select.c
+++ b/lnet/ulnds/select.c
@@ -97,9 +97,9 @@ void remove_io_handler (io_handler i)
 
 static void set_flag(io_handler n,fd_set *fds)
 {
-    if (n->type & READ_HANDLER) FD_SET(n->fd,fds);
-    if (n->type & WRITE_HANDLER) FD_SET(n->fd,fds+1);
-    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd,fds+2);
+    if (n->type & READ_HANDLER) FD_SET(n->fd, &fds[0]);
+    if (n->type & WRITE_HANDLER) FD_SET(n->fd,&fds[1]);
+    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd, &fds[2]);
 }
 
 
@@ -126,9 +126,18 @@ void select_timer_block(when until)
         timeout_pointer=&timeout;
     } else timeout_pointer=0;
 
-    FD_ZERO(fds);
-    FD_ZERO(fds+1);
-    FD_ZERO(fds+2);
+
+    /* FIXME
+     * temporarily add timer for endless waiting problem.
+     * FIXME
+     */
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    timeout_pointer=&timeout;
+
+    FD_ZERO(&fds[0]);
+    FD_ZERO(&fds[1]);
+    FD_ZERO(&fds[2]);
     for (k=&io_handlers;*k;){
         if ((*k)->disabled){
             j=*k;
@@ -140,14 +149,15 @@ void select_timer_block(when until)
 	    k=&(*k)->next;
 	}
     }
-    result=select(FD_SETSIZE,fds,fds+1,fds+2,timeout_pointer);
+
+    result=select(FD_SETSIZE, &fds[0], &fds[1], &fds[2], timeout_pointer);
 
     if (result > 0)
         for (j=io_handlers;j;j=j->next){
             if (!(j->disabled) && 
-                ((FD_ISSET(j->fd,fds) && (j->type & READ_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+1) && (j->type & WRITE_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+2) && (j->type & EXCEPTION_HANDLER)))){
+                ((FD_ISSET(j->fd, &fds[0]) && (j->type & READ_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[1]) && (j->type & WRITE_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[2]) && (j->type & EXCEPTION_HANDLER)))){
                 if (!(*j->function)(j->argument))
                     j->disabled=1;
             }
diff --git a/lnet/ulnds/socklnd/connection.c b/lnet/ulnds/socklnd/connection.c
index edd7c961a31ec21ee4813eb187c932cfb6fa14b4..3e64b330444cb16c7e42f73e48ab88ada1ddb65d 100644
--- a/lnet/ulnds/socklnd/connection.c
+++ b/lnet/ulnds/socklnd/connection.c
@@ -34,13 +34,21 @@
 #include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <portals/types.h>
+#include <portals/list.h>
+#include <portals/lib-types.h>
+#include <portals/socknal.h>
+#include <linux/kp30.h>
 #include <connection.h>
+#include <pthread.h>
 #include <errno.h>
-
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* global variable: acceptor port */
 unsigned short tcpnal_acceptor_port = 988;
@@ -55,9 +63,14 @@ unsigned short tcpnal_acceptor_port = 988;
  */
 static int compare_connection(void *arg1, void *arg2)
 {
-        connection c = arg1;
-        unsigned int * id = arg2;
-        return((c->ip==id[0]) && (c->port==id[1]));
+    connection c = arg1;
+    unsigned int * id = arg2;
+#if 0
+    return((c->ip==id[0]) && (c->port==id[1]));
+#else
+    /* CFS specific hacking */
+    return (c->ip == id[0]);
+#endif
 }
 
 
@@ -68,7 +81,12 @@ static int compare_connection(void *arg1, void *arg2)
  */
 static unsigned int connection_key(unsigned int *id)
 {
+#if 0
     return(id[0]^id[1]);
+#else
+    /* CFS specific hacking */
+    return (unsigned int) id[0];
+#endif
 }
 
 
@@ -102,22 +120,27 @@ int read_connection(connection c,
                     unsigned char *dest,
                     int len)
 {
-    int offset=0,rc;
+    int offset = 0,rc;
 
-    if (len){
+    if (len) {
         do {
-            if((rc=syscall(SYS_read, c->fd, dest+offset, len-offset))<=0){
-                if (errno==EINTR) {
-                    rc=0;
+#ifndef __CYGWIN__
+            rc = syscall(SYS_read, c->fd, dest+offset, len-offset);
+#else
+            rc = recv(c->fd, dest+offset, len-offset, 0);
+#endif
+            if (rc <= 0) {
+                if (errno == EINTR) {
+                    rc = 0;
                 } else {
                     remove_connection(c);
-                    return(0);
+                    return (0);
                 }
             }
-            offset+=rc;
-        } while (offset<len);
+            offset += rc;
+        } while (offset < len);
     }
-    return(1);
+    return (1);
 }
 
 static int connection_input(void *d)
@@ -172,10 +195,111 @@ static int new_connection(void *z)
     unsigned int nid=*((unsigned int *)&s.sin_addr);
     /* cfs specific hack */
     //unsigned short pid=s.sin_port;
+    pthread_mutex_lock(&m->conn_lock);
     allocate_connection(m,htonl(nid),0/*pid*/,fd);
+    pthread_mutex_unlock(&m->conn_lock);
     return(1);
 }
 
+/* FIXME assuming little endian, cleanup!! */
+#define __cpu_to_le64(x) ((__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(x))
+#define __cpu_to_le32(x) ((__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(x))
+#define __cpu_to_le16(x) ((__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(x))
+
+extern ptl_nid_t tcpnal_mynid;
+
+int
+tcpnal_hello (int sockfd, ptl_nid_t *nid, int type, __u64 incarnation)
+{
+        int                 rc;
+        ptl_hdr_t           hdr;
+        ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
+
+        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
+
+        memset (&hdr, 0, sizeof (hdr));
+        hmv->magic         = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
+        hmv->version_major = __cpu_to_le32 (PORTALS_PROTO_VERSION_MAJOR);
+        hmv->version_minor = __cpu_to_le32 (PORTALS_PROTO_VERSION_MINOR);
+        
+        hdr.src_nid = __cpu_to_le64 (tcpnal_mynid);
+        hdr.type    = __cpu_to_le32 (PTL_MSG_HELLO);
+
+        hdr.msg.hello.type = __cpu_to_le32 (type);
+        hdr.msg.hello.incarnation = 0;
+
+        /* Assume sufficient socket buffering for this message */
+        rc = syscall(SYS_write, sockfd, &hdr, sizeof(hdr));
+        if (rc <= 0) {
+                CERROR ("Error %d sending HELLO to %llx\n", rc, *nid);
+                return (rc);
+        }
+
+        rc = syscall(SYS_read, sockfd, hmv, sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading HELLO from %llx\n", rc, *nid);
+                return (rc);
+        }
+        
+        if (hmv->magic != __le32_to_cpu (PORTALS_PROTO_MAGIC)) {
+                CERROR ("Bad magic %#08x (%#08x expected) from %llx\n",
+                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, *nid);
+                return (-EPROTO);
+        }
+
+        if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
+            hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
+                CERROR ("Incompatible protocol version %d.%d (%d.%d expected)"
+                        " from %llx\n",
+                        __le16_to_cpu (hmv->version_major),
+                        __le16_to_cpu (hmv->version_minor),
+                        PORTALS_PROTO_VERSION_MAJOR,
+                        PORTALS_PROTO_VERSION_MINOR,
+                        *nid);
+                return (-EPROTO);
+        }
+
+#if (PORTALS_PROTO_VERSION_MAJOR != 0)
+# error "This code only understands protocol version 0.x"
+#endif
+        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
+         * so read the rest of it in now... */
+
+        rc = syscall(SYS_read, sockfd, hmv + 1, sizeof(hdr) - sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading rest of HELLO hdr from %llx\n",
+                        rc, *nid);
+                return (rc);
+        }
+
+        /* ...and check we got what we expected */
+        if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
+            hdr.payload_length != __cpu_to_le32 (0)) {
+                CERROR ("Expecting a HELLO hdr with 0 payload,"
+                        " but got type %d with %d payload from %llx\n",
+                        __le32_to_cpu (hdr.type),
+                        __le32_to_cpu (hdr.payload_length), *nid);
+                return (-EPROTO);
+        }
+
+        if (__le64_to_cpu(hdr.src_nid) == PTL_NID_ANY) {
+                CERROR("Expecting a HELLO hdr with a NID, but got PTL_NID_ANY\n");
+                return (-EPROTO);
+        }
+
+        if (*nid == PTL_NID_ANY) {              /* don't know peer's nid yet */
+                *nid = __le64_to_cpu(hdr.src_nid);
+        } else if (*nid != __le64_to_cpu (hdr.src_nid)) {
+                CERROR ("Connected to nid %llx, but expecting %llx\n",
+                        __le64_to_cpu (hdr.src_nid), *nid);
+                return (-EPROTO);
+        }
+
+        return (0);
+}
 
 /* Function:  force_tcp_connection
  * Arguments: t: tcpnal
@@ -187,17 +311,22 @@ connection force_tcp_connection(manager m,
                                 unsigned int ip,
                                 unsigned short port)
 {
-    connection c;
+    connection conn;
     struct sockaddr_in addr;
     unsigned int id[2];
 
     port = tcpnal_acceptor_port;
 
-    id[0]=ip;
-    id[1]=port;
+    id[0] = ip;
+    id[1] = port;
 
-    if (!(c=hash_table_find(m->connections,id))){
+    pthread_mutex_lock(&m->conn_lock);
+
+    conn = hash_table_find(m->connections, id);
+    if (!conn) {
         int fd;
+        int option;
+        ptl_nid_t peernid = PTL_NID_ANY;
 
         bzero((char *) &addr, sizeof(addr));
         addr.sin_family      = AF_INET;
@@ -208,16 +337,30 @@ connection force_tcp_connection(manager m,
             perror("tcpnal socket failed");
             exit(-1);
         }
-        if (connect(fd,
-                    (struct sockaddr *)&addr,
-                    sizeof(struct sockaddr_in)))
-            {
-                perror("tcpnal connect");
-                return(0);
-            }
-        return(allocate_connection(m,ip,port,fd));
+        if (connect(fd, (struct sockaddr *)&addr,
+                    sizeof(struct sockaddr_in))) {
+            perror("tcpnal connect");
+            return(0);
+        }
+
+#if 1
+        option = 1;
+        setsockopt(fd, SOL_TCP, TCP_NODELAY, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
+#endif
+   
+        /* say hello */
+        if (tcpnal_hello(fd, &peernid, SOCKNAL_CONN_ANY, 0))
+            exit(-1);
+
+        conn = allocate_connection(m, ip, port, fd);
     }
-    return(c);
+
+    pthread_mutex_unlock(&m->conn_lock);
+    return (conn);
 }
 
 
@@ -243,8 +386,8 @@ static int bind_socket(manager m,unsigned short port)
     bzero((char *) &addr, sizeof(addr));
     addr.sin_family      = AF_INET;
     addr.sin_addr.s_addr = 0;
-    addr.sin_port        = port; 
-    
+    addr.sin_port        = htons(port);
+
     if (bind(m->bound,(struct sockaddr *)&addr,alen)<0){
         perror ("tcpnal bind"); 
         return(0);
@@ -284,11 +427,15 @@ manager init_connections(unsigned short pid,
                          int (*input)(void *, void *),
                          void *a)
 {
-    manager m=(manager)malloc(sizeof(struct manager));
-    m->connections=hash_create_table(compare_connection,connection_key);
-    m->handler=input;
-    m->handler_arg=a;
-    if (bind_socket(m,pid)) return(m);
+    manager m = (manager)malloc(sizeof(struct manager));
+    m->connections = hash_create_table(compare_connection,connection_key);
+    m->handler = input;
+    m->handler_arg = a;
+    pthread_mutex_init(&m->conn_lock, 0);
+
+    if (bind_socket(m,pid))
+        return(m);
+
     free(m);
     return(0);
 }
diff --git a/lnet/ulnds/socklnd/connection.h b/lnet/ulnds/socklnd/connection.h
index 6f572874a4ebd100a44038f52b6d74b037d87e04..fb1eaabd0e99d4bf1133e601758c7c772c21630e 100644
--- a/lnet/ulnds/socklnd/connection.h
+++ b/lnet/ulnds/socklnd/connection.h
@@ -10,6 +10,7 @@
 
 typedef struct manager {
     table connections;
+    pthread_mutex_t conn_lock; /* protect connections table */
     int bound;
     io_handler bound_handler;
     int (*handler)(void *, void *);
diff --git a/lnet/ulnds/socklnd/procapi.c b/lnet/ulnds/socklnd/procapi.c
index f4820b26ca38251b71d6f25fb7b0962aaca970c4..2a3fbd881a514ca79f1282250187a700eb108694 100644
--- a/lnet/ulnds/socklnd/procapi.c
+++ b/lnet/ulnds/socklnd/procapi.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,7 +32,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <pqtimer.h>
 #include <dispatch.h>
@@ -48,35 +48,22 @@
  * forwards a packaged api call from the 'api' side to the 'library'
  *   side, and collects the result
  */
-#define forward_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(PTL_SEGV);\
-       }
-static int procbridge_forward(nal_t *n, int id, void *args, ptl_size_t args_len,
+static int procbridge_forward(nal_t *n, int id, void *args, size_t args_len,
 			      void *ret, ptl_size_t ret_len)
 {
-    bridge b=(bridge)n->nal_data;
-    procbridge p=(procbridge)b->local;
-    int lib=p->to_lib[1];
-    int k;
+    bridge b = (bridge) n->nal_data;
 
-    forward_failure(write,lib, &id, sizeof(id));
-    forward_failure(write,lib,&args_len, sizeof(args_len));
-    forward_failure(write,lib,&ret_len, sizeof(ret_len));
-    forward_failure(write,lib,args, args_len);
-
-    do {
-        k=syscall(SYS_read, p->from_lib[0], ret, ret_len);
-    } while ((k!=ret_len) && (errno += EINTR));
+    if (id == PTL_FINI) {
+            lib_fini(b->nal_cb);
 
-    if(k!=ret_len){
-        perror("nal: read return block");
-        return PTL_SEGV;
+            if (b->shutdown)
+                (*b->shutdown)(b);
     }
+
+    lib_dispatch(b->nal_cb, NULL, id, args, ret);
+
     return (PTL_OK);
 }
-#undef forward_failure
 
 
 /* Function: shutdown
@@ -90,15 +77,18 @@ static int procbridge_shutdown(nal_t *n, int ni)
 {
     bridge b=(bridge)n->nal_data;
     procbridge p=(procbridge)b->local;
-    int code=PTL_FINI;
 
-    syscall(SYS_write, p->to_lib[1],&code,sizeof(code));
-    syscall(SYS_read, p->from_lib[0],&code,sizeof(code));
+    p->nal_flags |= NAL_FLAG_STOPPING;
 
-    syscall(SYS_close, p->to_lib[0]);
-    syscall(SYS_close, p->to_lib[1]);
-    syscall(SYS_close, p->from_lib[0]);
-    syscall(SYS_close, p->from_lib[1]);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & NAL_FLAG_STOPPED) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
 
     free(p);
     return(0);
@@ -108,7 +98,7 @@ static int procbridge_shutdown(nal_t *n, int ni)
 /* Function: validate
  *    useless stub
  */
-static int procbridge_validate(nal_t *nal, void *base, ptl_size_t extent)
+static int procbridge_validate(nal_t *nal, void *base, size_t extent)
 {
     return(0);
 }
@@ -151,7 +141,9 @@ static nal_t api_nal = {
     unlock:   procbridge_unlock
 };
 
-/* Function: bridge_init
+ptl_nid_t tcpnal_mynid;
+
+/* Function: procbridge_interface
  *
  * Arguments:  pid: requested process id (port offset)
  *                  PTL_ID_ANY not supported.
@@ -165,77 +157,17 @@ static nal_t api_nal = {
  * initializes the tcp nal. we define unix_failure as an
  * error wrapper to cut down clutter.
  */
-#define unix_failure(operand,fd,buffer,length,text)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          perror(text);\
-          return(NULL);\
-       }
-#if 0
-static nal_t *bridge_init(ptl_interface_t nal,
-                          ptl_pid_t pid_request,
-                          ptl_ni_limits_t *desired,
-                          ptl_ni_limits_t *actual,
-                          int *rc)
-{
-    procbridge p;
-    bridge b;
-    static int initialized=0;
-    ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-
-    if(initialized) return (&api_nal);
-
-    init_unix_timer();
-
-    b=(bridge)malloc(sizeof(struct bridge));
-    p=(procbridge)malloc(sizeof(struct procbridge));
-    api_nal.nal_data=b;
-    b->local=p;
-
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
-    if (desired) limits = *desired;
-    unix_failure(write,p->to_lib[1], &pid_request, sizeof(pid_request),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal, sizeof(ptl_interface_t),
-                       "nal_init: write");
-
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
-        perror("nal_init: pthread_create");
-        return(NULL);
-    }
-
-    unix_failure(read,p->from_lib[0], actual, sizeof(ptl_ni_limits_t),
-                 "tcp_init: read");
-    unix_failure(read,p->from_lib[0], rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(*rc) return(NULL);
-
-    initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
-
-    return (&api_nal);
-}
-#endif
-
-ptl_nid_t tcpnal_mynid;
-
 nal_t *procbridge_interface(int num_interface,
                             ptl_pt_index_t ptl_size,
                             ptl_ac_index_t acl_size,
                             ptl_pid_t requested_pid)
 {
+    nal_init_args_t args;
     procbridge p;
     bridge b;
     static int initialized=0;
     ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-    int rc, nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
+    int nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
 
     if(initialized) return (&api_nal);
 
@@ -246,38 +178,42 @@ nal_t *procbridge_interface(int num_interface,
     api_nal.nal_data=b;
     b->local=p;
 
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
     if (ptl_size)
 	    limits.max_ptable_index = ptl_size;
     if (acl_size)
 	    limits.max_atable_index = acl_size;
 
-    unix_failure(write,p->to_lib[1], &requested_pid, sizeof(requested_pid),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal_type, sizeof(nal_type),
-                       "nal_init: write");
+    args.nia_requested_pid = requested_pid;
+    args.nia_limits = &limits;
+    args.nia_nal_type = nal_type;
+    args.nia_bridge = b;
 
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
+    /* init procbridge */
+    pthread_mutex_init(&p->mutex,0);
+    pthread_cond_init(&p->cond, 0);
+    p->nal_flags = 0;
+    pthread_mutex_init(&p->nal_cb_lock, 0);
+
+    if (pthread_create(&p->t, NULL, nal_thread, &args)) {
         perror("nal_init: pthread_create");
         return(NULL);
     }
 
-    unix_failure(read,p->from_lib[0], &rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(rc) return(NULL);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
+
+    if (p->nal_flags & NAL_FLAG_STOPPED)
+        return (NULL);
 
     b->nal_cb->ni.nid = tcpnal_mynid;
     initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
 
     return (&api_nal);
 }
-#undef unix_failure
diff --git a/lnet/ulnds/socklnd/procbridge.h b/lnet/ulnds/socklnd/procbridge.h
index 060ae7b2b937ae52a20e88f55165efc9b4dc6be0..317e22f876149687c944521deee997ae523cac43 100644
--- a/lnet/ulnds/socklnd/procbridge.h
+++ b/lnet/ulnds/socklnd/procbridge.h
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
  */
@@ -14,14 +15,28 @@
 #include <ipmap.h>
 
 
+#define NAL_FLAG_RUNNING        1
+#define NAL_FLAG_STOPPING       2
+#define NAL_FLAG_STOPPED        4
+
 typedef struct procbridge {
+    /* sync between user threads and nal thread */
     pthread_t t;
     pthread_cond_t cond;
     pthread_mutex_t mutex;
-    int to_lib[2];
-    int from_lib[2];
+
+    int nal_flags;
+
+    pthread_mutex_t nal_cb_lock;
 } *procbridge;
 
+typedef struct nal_init_args {
+    ptl_pid_t        nia_requested_pid;
+    ptl_ni_limits_t *nia_limits;
+    int              nia_nal_type;
+    bridge           nia_bridge;
+} nal_init_args_t;
+
 extern void *nal_thread(void *);
 
 
@@ -33,8 +48,8 @@ extern void *nal_thread(void *);
 
 extern void set_address(bridge t,ptl_pid_t pidrequest);
 extern nal_t *procbridge_interface(int num_interface,
-                            ptl_pt_index_t ptl_size,
-                            ptl_ac_index_t acl_size,
-                            ptl_pid_t requested_pid);
+                                   ptl_pt_index_t ptl_size,
+                                   ptl_ac_index_t acl_size,
+                                   ptl_pid_t requested_pid);
 
 #endif
diff --git a/lnet/ulnds/socklnd/proclib.c b/lnet/ulnds/socklnd/proclib.c
index 99afe66ced9535aa39f3485fa7f9c9878cf20343..2627253d51c76f5fd61f11a3afc7952b18009078 100644
--- a/lnet/ulnds/socklnd/proclib.c
+++ b/lnet/ulnds/socklnd/proclib.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,14 +32,12 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <errno.h>
 #include <timer.h>
-//#include <util/pqtimer.h>
 #include <dispatch.h>
 
 /* the following functions are stubs to satisfy the nal definition
@@ -48,7 +47,7 @@ static int nal_write(nal_cb_t *nal,
                      void *private,
                      user_ptr dst_addr,
                      void *src_addr,
-                     ptl_size_t len)
+                     size_t len)
 {
     memcpy(dst_addr, src_addr, len);
     return 0;
@@ -65,7 +64,7 @@ static int nal_read(nal_cb_t * nal,
 }
 
 static void *nal_malloc(nal_cb_t *nal,
-                        ptl_size_t len)
+                        size_t len)
 {
     void *buf =  malloc(len);
     return buf;
@@ -73,7 +72,7 @@ static void *nal_malloc(nal_cb_t *nal,
 
 static void nal_free(nal_cb_t *nal,
                      void *buf,
-                     ptl_size_t len)
+                     size_t len)
 {
     free(buf);
 }
@@ -93,12 +92,20 @@ static void nal_printf(nal_cb_t *nal,
 static void nal_cli(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge) nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_lock(&p->nal_cb_lock);
 }
 
 
 static void nal_sti(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge)nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_unlock(&p->nal_cb_lock);
 }
 
 
@@ -108,69 +115,22 @@ static int nal_dist(nal_cb_t *nal,
 {
     return 0;
 }
-    
-
-
-/* Function:  data_from_api
- * Arguments: t: the nal state for this interface
- * Returns: whether to continue reading from the pipe
- *
- *   data_from_api() reads data from the api side in response
- *   to a select.
- *
- *   We define data_failure() for syntactic convenience
- *   of unix error reporting.
- */
-
-#define data_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(0);\
-       }
-static int data_from_api(void *arg)
-{
-        bridge b = arg;
-    procbridge p=(procbridge)b->local;
-    /* where are these two sizes derived from ??*/
-    char arg_block[ 256 ];
-    char ret_block[ 128 ];
-    ptl_size_t arg_len,ret_len;
-    int fd=p->to_lib[0];
-    int index;
-
-    data_failure(read,fd, &index, sizeof(index));
-
-    if (index==PTL_FINI) {
-        lib_fini(b->nal_cb);
-        if (b->shutdown) (*b->shutdown)(b);
-        syscall(SYS_write, p->from_lib[1],&b->alive,sizeof(b->alive));
-
-        /* a heavy-handed but convenient way of shutting down
-           the lower side thread */
-        pthread_exit(0);
-    }
-
-    data_failure(read,fd, &arg_len, sizeof(arg_len));
-    data_failure(read,fd, &ret_len, sizeof(ret_len));
-    data_failure(read,fd, arg_block, arg_len);
-
-    lib_dispatch(b->nal_cb, NULL, index, arg_block, ret_block);
-
-    data_failure(write,p->from_lib[1],ret_block, ret_len);
-    return(1);
-}
-#undef data_failure
-
-
 
 static void wakeup_topside(void *z)
 {
-    bridge b=z;
-    procbridge p=b->local;
+    bridge b = z;
+    procbridge p = b->local;
+    int stop;
 
     pthread_mutex_lock(&p->mutex);
+    stop = p->nal_flags & NAL_FLAG_STOPPING;
+    if (stop)
+        p->nal_flags |= NAL_FLAG_STOPPED;
     pthread_cond_broadcast(&p->cond);
     pthread_mutex_unlock(&p->mutex);
+
+    if (stop)
+        pthread_exit(0);
 }
 
 
@@ -195,7 +155,8 @@ nal_initialize nal_table[PTL_IFACE_MAX]={0,tcpnal_init,0};
 
 void *nal_thread(void *z)
 {
-    bridge b=z;
+    nal_init_args_t *args = (nal_init_args_t *) z;
+    bridge b = args->nia_bridge;
     procbridge p=b->local;
     int rc;
     ptl_pid_t pid_request;
@@ -216,15 +177,9 @@ void *nal_thread(void *z)
     b->nal_cb->cb_sti=nal_sti;
     b->nal_cb->cb_dist=nal_dist;
 
-
-    register_io_handler(p->to_lib[0],READ_HANDLER,data_from_api,(void *)b);
-
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &pid_request, sizeof(pid_request))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &desired, sizeof(ptl_ni_limits_t))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &nal_type, sizeof(nal_type))))
-        perror("procbridge read from api");
+    pid_request = args->nia_requested_pid;
+    desired = *args->nia_limits;
+    nal_type = args->nia_nal_type;
 
     actual = desired;
     LIMIT(desired.max_match_entries,actual.max_match_entries,MAX_MES);
@@ -251,12 +206,12 @@ void *nal_thread(void *z)
      * it is non-zero since something went wrong.
      */
     /* this should perform error checking */
-#if 0
-    write(p->from_lib[1], &actual, sizeof(ptl_ni_limits_t));
-#endif
-    syscall(SYS_write, p->from_lib[1], &rc, sizeof(rc));
-    
-    if(!rc) {
+    pthread_mutex_lock(&p->mutex);
+    p->nal_flags |= rc ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
+    pthread_cond_broadcast(&p->cond);
+    pthread_mutex_unlock(&p->mutex);
+
+    if (!rc) {
         /* the thunk function is called each time the timer loop
            performs an operation and returns to blocking mode. we
            overload this function to inform the api side that
@@ -267,4 +222,3 @@ void *nal_thread(void *z)
     return(0);
 }
 #undef LIMIT
-
diff --git a/lnet/ulnds/socklnd/select.c b/lnet/ulnds/socklnd/select.c
index 47adc50490749c24168a043e0fabf48315739853..fe24efcf3cf8066192cd6cc41963969a369ad659 100644
--- a/lnet/ulnds/socklnd/select.c
+++ b/lnet/ulnds/socklnd/select.c
@@ -97,9 +97,9 @@ void remove_io_handler (io_handler i)
 
 static void set_flag(io_handler n,fd_set *fds)
 {
-    if (n->type & READ_HANDLER) FD_SET(n->fd,fds);
-    if (n->type & WRITE_HANDLER) FD_SET(n->fd,fds+1);
-    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd,fds+2);
+    if (n->type & READ_HANDLER) FD_SET(n->fd, &fds[0]);
+    if (n->type & WRITE_HANDLER) FD_SET(n->fd,&fds[1]);
+    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd, &fds[2]);
 }
 
 
@@ -126,9 +126,18 @@ void select_timer_block(when until)
         timeout_pointer=&timeout;
     } else timeout_pointer=0;
 
-    FD_ZERO(fds);
-    FD_ZERO(fds+1);
-    FD_ZERO(fds+2);
+
+    /* FIXME
+     * temporarily add timer for endless waiting problem.
+     * FIXME
+     */
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    timeout_pointer=&timeout;
+
+    FD_ZERO(&fds[0]);
+    FD_ZERO(&fds[1]);
+    FD_ZERO(&fds[2]);
     for (k=&io_handlers;*k;){
         if ((*k)->disabled){
             j=*k;
@@ -140,14 +149,15 @@ void select_timer_block(when until)
 	    k=&(*k)->next;
 	}
     }
-    result=select(FD_SETSIZE,fds,fds+1,fds+2,timeout_pointer);
+
+    result=select(FD_SETSIZE, &fds[0], &fds[1], &fds[2], timeout_pointer);
 
     if (result > 0)
         for (j=io_handlers;j;j=j->next){
             if (!(j->disabled) && 
-                ((FD_ISSET(j->fd,fds) && (j->type & READ_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+1) && (j->type & WRITE_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+2) && (j->type & EXCEPTION_HANDLER)))){
+                ((FD_ISSET(j->fd, &fds[0]) && (j->type & READ_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[1]) && (j->type & WRITE_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[2]) && (j->type & EXCEPTION_HANDLER)))){
                 if (!(*j->function)(j->argument))
                     j->disabled=1;
             }
diff --git a/lnet/ulnds/socklnd/tcplnd.c b/lnet/ulnds/socklnd/tcplnd.c
index d6b5ed08645f135276623ff6ab3ccf25790a8088..1041d1d7870bc6ccaac05b340e881a0bc5547f16 100644
--- a/lnet/ulnds/socklnd/tcplnd.c
+++ b/lnet/ulnds/socklnd/tcplnd.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -27,7 +28,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -36,6 +36,11 @@
 #include <bridge.h>
 #include <ipmap.h>
 #include <connection.h>
+#include <pthread.h>
+#include <errno.h>
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* Function:  tcpnal_send
  * Arguments: nal:     pointer to my nal control block
@@ -50,7 +55,6 @@
  *
  * sends a packet to the peer, after insuring that a connection exists
  */
-#warning FIXME: "param 'type' is newly added, make use of it!!"
 int tcpnal_send(nal_cb_t *n,
 		void *private,
 		lib_msg_t *cookie,
@@ -64,8 +68,11 @@ int tcpnal_send(nal_cb_t *n,
 {
     connection c;
     bridge b=(bridge)n->nal_data;
-    struct iovec tiov[2];
-    int count = 1;
+    struct iovec tiov[257];
+    static pthread_mutex_t send_lock = PTHREAD_MUTEX_INITIALIZER;
+    int   rc;
+    int   total;
+    int i;
 
     if (!(c=force_tcp_connection((manager)b->lower,
                                  PNAL_IP(nid,b),
@@ -83,18 +90,46 @@ int tcpnal_send(nal_cb_t *n,
     LASSERT (niov <= 1);
     if (len) syscall(SYS_write, c->fd,iov[0].iov_base,len);
 #else
-    LASSERT (niov <= 1);
+    LASSERT (niov <= 256);
 
     tiov[0].iov_base = hdr;
     tiov[0].iov_len = sizeof(ptl_hdr_t);
 
-    if (len) {
-            tiov[1].iov_base = iov[0].iov_base;
-            tiov[1].iov_len = len;
-            count++;
+    if (niov > 0)
+            memcpy(&tiov[1], iov, niov * sizeof(struct iovec));
+    pthread_mutex_lock(&send_lock);
+#if 1
+    for (i = total = 0; i <= niov; i++)
+            total += tiov[i].iov_len;
+    
+    rc = syscall(SYS_writev, c->fd, tiov, niov+1);
+    if (rc != total) {
+            fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                     rc, total, errno);
+            abort();
     }
-
-    syscall(SYS_writev, c->fd, tiov, count);
+#else
+    for (i = total = 0; i <= niov; i++) {
+            rc = send(c->fd, tiov[i].iov_base, tiov[i].iov_len, 0);
+            
+            if (rc != tiov[i].iov_len) {
+                    fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                             rc, tiov[i].iov_len, errno);
+                    abort();
+            }
+            total != rc;
+    }
+#endif
+#if 0
+    fprintf (stderr, "sent %s total %d in %d frags\n", 
+             hdr->type == PTL_MSG_ACK ? "ACK" :
+             hdr->type == PTL_MSG_PUT ? "PUT" :
+             hdr->type == PTL_MSG_GET ? "GET" :
+             hdr->type == PTL_MSG_REPLY ? "REPLY" :
+             hdr->type == PTL_MSG_HELLO ? "HELLO" : "UNKNOWN",
+             total, niov + 1);
+#endif
+    pthread_mutex_unlock(&send_lock);
 #endif
     lib_finalize(n, private, cookie);
         
@@ -120,15 +155,29 @@ int tcpnal_recv(nal_cb_t *n,
 		lib_msg_t *cookie,
                 unsigned int niov,
                 struct iovec *iov,
-		ptl_size_t mlen,
-		ptl_size_t rlen)
+		size_t mlen,
+		size_t rlen)
 
 {
-    if (mlen) {
-        LASSERT (niov <= 1);
-        read_connection(private,iov[0].iov_base,mlen);
-        lib_finalize(n, private, cookie);
-    }
+    int i;
+
+    if (!niov)
+            goto finalize;
+
+    LASSERT(mlen);
+    LASSERT(rlen);
+    LASSERT(rlen >= mlen);
+
+    /* FIXME
+     * 1. Is this effecient enough? change to use readv() directly?
+     * 2. need check return from read_connection()
+     * - MeiJia
+     */
+    for (i = 0; i < niov; i++)
+        read_connection(private, iov[i].iov_base, iov[i].iov_len);
+
+finalize:
+    lib_finalize(n, private, cookie);
 
     if (mlen!=rlen){
         char *trash=malloc(rlen-mlen);
@@ -153,15 +202,15 @@ int tcpnal_recv(nal_cb_t *n,
  */
 static int from_connection(void *a, void *d)
 {
-        connection c = d;
-        bridge b=a;
-        ptl_hdr_t hdr;
-
-        if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
-                lib_parse(b->nal_cb, &hdr, c);
-                return(1);
-        }
-        return(0);
+    connection c = d;
+    bridge b = a;
+    ptl_hdr_t hdr;
+
+    if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
+        lib_parse(b->nal_cb, &hdr, c);
+        return(1);
+    }
+    return(0);
 }
 
 
diff --git a/lnet/ulnds/tcplnd.c b/lnet/ulnds/tcplnd.c
index d6b5ed08645f135276623ff6ab3ccf25790a8088..1041d1d7870bc6ccaac05b340e881a0bc5547f16 100644
--- a/lnet/ulnds/tcplnd.c
+++ b/lnet/ulnds/tcplnd.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -27,7 +28,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -36,6 +36,11 @@
 #include <bridge.h>
 #include <ipmap.h>
 #include <connection.h>
+#include <pthread.h>
+#include <errno.h>
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* Function:  tcpnal_send
  * Arguments: nal:     pointer to my nal control block
@@ -50,7 +55,6 @@
  *
  * sends a packet to the peer, after insuring that a connection exists
  */
-#warning FIXME: "param 'type' is newly added, make use of it!!"
 int tcpnal_send(nal_cb_t *n,
 		void *private,
 		lib_msg_t *cookie,
@@ -64,8 +68,11 @@ int tcpnal_send(nal_cb_t *n,
 {
     connection c;
     bridge b=(bridge)n->nal_data;
-    struct iovec tiov[2];
-    int count = 1;
+    struct iovec tiov[257];
+    static pthread_mutex_t send_lock = PTHREAD_MUTEX_INITIALIZER;
+    int   rc;
+    int   total;
+    int i;
 
     if (!(c=force_tcp_connection((manager)b->lower,
                                  PNAL_IP(nid,b),
@@ -83,18 +90,46 @@ int tcpnal_send(nal_cb_t *n,
     LASSERT (niov <= 1);
     if (len) syscall(SYS_write, c->fd,iov[0].iov_base,len);
 #else
-    LASSERT (niov <= 1);
+    LASSERT (niov <= 256);
 
     tiov[0].iov_base = hdr;
     tiov[0].iov_len = sizeof(ptl_hdr_t);
 
-    if (len) {
-            tiov[1].iov_base = iov[0].iov_base;
-            tiov[1].iov_len = len;
-            count++;
+    if (niov > 0)
+            memcpy(&tiov[1], iov, niov * sizeof(struct iovec));
+    pthread_mutex_lock(&send_lock);
+#if 1
+    for (i = total = 0; i <= niov; i++)
+            total += tiov[i].iov_len;
+    
+    rc = syscall(SYS_writev, c->fd, tiov, niov+1);
+    if (rc != total) {
+            fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                     rc, total, errno);
+            abort();
     }
-
-    syscall(SYS_writev, c->fd, tiov, count);
+#else
+    for (i = total = 0; i <= niov; i++) {
+            rc = send(c->fd, tiov[i].iov_base, tiov[i].iov_len, 0);
+            
+            if (rc != tiov[i].iov_len) {
+                    fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                             rc, tiov[i].iov_len, errno);
+                    abort();
+            }
+            total != rc;
+    }
+#endif
+#if 0
+    fprintf (stderr, "sent %s total %d in %d frags\n", 
+             hdr->type == PTL_MSG_ACK ? "ACK" :
+             hdr->type == PTL_MSG_PUT ? "PUT" :
+             hdr->type == PTL_MSG_GET ? "GET" :
+             hdr->type == PTL_MSG_REPLY ? "REPLY" :
+             hdr->type == PTL_MSG_HELLO ? "HELLO" : "UNKNOWN",
+             total, niov + 1);
+#endif
+    pthread_mutex_unlock(&send_lock);
 #endif
     lib_finalize(n, private, cookie);
         
@@ -120,15 +155,29 @@ int tcpnal_recv(nal_cb_t *n,
 		lib_msg_t *cookie,
                 unsigned int niov,
                 struct iovec *iov,
-		ptl_size_t mlen,
-		ptl_size_t rlen)
+		size_t mlen,
+		size_t rlen)
 
 {
-    if (mlen) {
-        LASSERT (niov <= 1);
-        read_connection(private,iov[0].iov_base,mlen);
-        lib_finalize(n, private, cookie);
-    }
+    int i;
+
+    if (!niov)
+            goto finalize;
+
+    LASSERT(mlen);
+    LASSERT(rlen);
+    LASSERT(rlen >= mlen);
+
+    /* FIXME
+     * 1. Is this effecient enough? change to use readv() directly?
+     * 2. need check return from read_connection()
+     * - MeiJia
+     */
+    for (i = 0; i < niov; i++)
+        read_connection(private, iov[i].iov_base, iov[i].iov_len);
+
+finalize:
+    lib_finalize(n, private, cookie);
 
     if (mlen!=rlen){
         char *trash=malloc(rlen-mlen);
@@ -153,15 +202,15 @@ int tcpnal_recv(nal_cb_t *n,
  */
 static int from_connection(void *a, void *d)
 {
-        connection c = d;
-        bridge b=a;
-        ptl_hdr_t hdr;
-
-        if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
-                lib_parse(b->nal_cb, &hdr, c);
-                return(1);
-        }
-        return(0);
+    connection c = d;
+    bridge b = a;
+    ptl_hdr_t hdr;
+
+    if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
+        lib_parse(b->nal_cb, &hdr, c);
+        return(1);
+    }
+    return(0);
 }
 
 
diff --git a/lnet/utils/.cvsignore b/lnet/utils/.cvsignore
index 8e474adcd884083fbc900a3d73f5dc12107a6d35..e2a0d447ef8b2d66b880b1c76c8c02170a27e597 100644
--- a/lnet/utils/.cvsignore
+++ b/lnet/utils/.cvsignore
@@ -6,4 +6,5 @@ ptlctl
 .deps
 routerstat
 wirecheck
+gmnalnid
 .*.cmd
diff --git a/lnet/utils/Makefile.am b/lnet/utils/Makefile.am
index 05af5983f2b3a7572e137e3b7e78e0f572bd071e..f1878df2279c359d0afae30970f37da55fe14318 100644
--- a/lnet/utils/Makefile.am
+++ b/lnet/utils/Makefile.am
@@ -4,10 +4,16 @@
 # See the file COPYING in this distribution
 
 
-COMPILE = gcc -Wall -g -I$(srcdir)/../include 
-LINK = gcc -o $@
+COMPILE = $(CC) -Wall -g -I$(srcdir)/../include
+LINK = $(CC) -o $@
 
-sbin_PROGRAMS = acceptor ptlctl debugctl routerstat wirecheck
+if LIBLUSTRE
+tmp=
+else
+tmp=gmnalnid
+endif
+
+sbin_PROGRAMS = acceptor ptlctl debugctl routerstat wirecheck $(tmp)
 lib_LIBRARIES = libptlctl.a
 
 acceptor_SOURCES = acceptor.c # -lefence
@@ -16,6 +22,8 @@ wirecheck_SOURCES = wirecheck.c
 
 libptlctl_a_SOURCES = portals.c debug.c l_ioctl.c parser.c parser.h
 
+gmnalnid_SOURCES = gmnalnid.c
+
 ptlctl_SOURCES = ptlctl.c
 ptlctl_LDADD =  -L. -lptlctl -lncurses # -lefence
 ptlctl_DEPENDENCIES = libptlctl.a
diff --git a/lnet/utils/acceptor.c b/lnet/utils/acceptor.c
index c6590db7528211f9b2cea603770e6ec9efccad5a..29b8d1e52cfafce441c20357a0d5eb8f0acf1fb0 100644
--- a/lnet/utils/acceptor.c
+++ b/lnet/utils/acceptor.c
@@ -19,6 +19,7 @@
 #include <portals/api-support.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
+#include <portals/socknal.h>
 
 /* should get this from autoconf somehow */
 #ifndef PIDFILE_DIR
@@ -100,7 +101,7 @@ parse_size (int *sizep, char *str)
 }
 
 void
-show_connection (int fd, __u32 net_ip, ptl_nid_t nid)
+show_connection (int fd, __u32 net_ip)
 {
         struct hostent *h = gethostbyaddr ((char *)&net_ip, sizeof net_ip, AF_INET);
         __u32 host_ip = ntohl (net_ip);
@@ -128,136 +129,8 @@ show_connection (int fd, __u32 net_ip, ptl_nid_t nid)
         else
                 snprintf (host, sizeof(host), "%s", h->h_name);
                 
-        syslog (LOG_INFO, "Accepted host: %s NID: "LPX64" snd: %d rcv %d nagle: %s\n", 
-                 host, nid, txmem, rxmem, nonagle ? "disabled" : "enabled");
-}
-
-int
-sock_write (int cfd, void *buffer, int nob)
-{
-        while (nob > 0)
-        {
-                int rc = write (cfd, buffer, nob);
-
-                if (rc < 0)
-                {
-                        if (errno == EINTR)
-                                continue;
-                        
-                        return (rc);
-                }
-
-                if (rc == 0)
-                {
-                        fprintf (stderr, "Unexpected zero sock_write\n");
-                        abort();
-                }
-
-                nob -= rc;
-                buffer = (char *)buffer + nob;
-        }
-        
-        return (0);
-}
-
-int
-sock_read (int cfd, void *buffer, int nob)
-{
-        while (nob > 0)
-        {
-                int rc = read (cfd, buffer, nob);
-                
-                if (rc < 0)
-                {
-                        if (errno == EINTR)
-                                continue;
-                        
-                        return (rc);
-                }
-                
-                if (rc == 0)                    /* EOF */
-                {
-                        errno = ECONNABORTED;
-                        return (-1);
-                }
-                
-                nob -= rc;
-                buffer = (char *)buffer + nob;
-        }
-        
-        return (0);
-}
-
-int
-exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
-{
-        int                      rc;
-        ptl_hdr_t                hdr;
-        ptl_magicversion_t      *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
-
-        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
-
-        memset (&hdr, 0, sizeof (hdr));
-        
-        hmv->magic          = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
-        hmv->version_major  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
-        hmv->version_minor  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
-
-        hdr.src_nid = __cpu_to_le64 (my_nid);
-        hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
-        
-        /* Assume there's sufficient socket buffering for a portals HELLO header */
-        rc = sock_write (cfd, &hdr, sizeof (hdr));
-        if (rc != 0) {
-                perror ("Can't send initial HELLO");
-                return (-1);
-        }
-
-        /* First few bytes down the wire are the portals protocol magic and
-         * version, no matter what protocol version we're running. */
-
-        rc = sock_read (cfd, hmv, sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read from peer");
-                return (-1);
-        }
-
-        if (__cpu_to_le32 (hmv->magic) != PORTALS_PROTO_MAGIC) {
-                fprintf (stderr, "Bad magic %#08x (%#08x expected)\n", 
-                         __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC);
-                return (-1);
-        }
-
-        if (__cpu_to_le16 (hmv->version_major) != PORTALS_PROTO_VERSION_MAJOR ||
-            __cpu_to_le16 (hmv->version_minor) != PORTALS_PROTO_VERSION_MINOR) {
-                fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
-                         __cpu_to_le16 (hmv->version_major),
-                         __cpu_to_le16 (hmv->version_minor),
-                         PORTALS_PROTO_VERSION_MAJOR,
-                         PORTALS_PROTO_VERSION_MINOR);
-        }
-
-        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
-         * so read the rest of it in now... */
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read rest of HELLO hdr");
-                return (-1);
-        }
-
-        /* ...and check we got what we expected */
-        if (__cpu_to_le32 (hdr.type) != PTL_MSG_HELLO ||
-            __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)) != 0) {
-                fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
-                         " but got type %d with %d payload\n",
-                         __cpu_to_le32 (hdr.type),
-                         __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)));
-                return (-1);
-        }
-        
-        *peer_nid = __le64_to_cpu (hdr.src_nid);
-        return (0);
+        syslog (LOG_INFO, "Accepted host: %s snd: %d rcv %d nagle: %s\n", 
+                host, txmem, rxmem, nonagle ? "disabled" : "enabled");
 }
 
 void
@@ -277,10 +150,9 @@ int main(int argc, char **argv)
         int noclose = 0;
         int nonagle = 1;
         int nal = SOCKNAL;
-        int xchg_nids = 0;
         int bind_irq = 0;
         
-        while ((c = getopt (argc, argv, "N:r:s:nlxi")) != -1)
+        while ((c = getopt (argc, argv, "N:r:s:nli")) != -1)
                 switch (c)
                 {
                 case 'r':
@@ -301,10 +173,6 @@ int main(int argc, char **argv)
                         noclose = 1;
                         break;
 
-                case 'x':
-                        xchg_nids = 1;
-                        break;
-
                 case 'i':
                         bind_irq = 1;
                         break;
@@ -409,7 +277,7 @@ int main(int argc, char **argv)
                 int len = sizeof(clntaddr);
                 int cfd;
                 struct portal_ioctl_data data;
-                ptl_nid_t peer_nid;
+                struct portals_cfg pcfg;
                 
                 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
                 if ( cfd < 0 ) {
@@ -418,40 +286,20 @@ int main(int argc, char **argv)
                         continue;
                 }
 
-                if (!xchg_nids)
-                        peer_nid = ntohl (clntaddr.sin_addr.s_addr); /* HOST byte order */
-                else
-                {
-                        PORTAL_IOC_INIT (data);
-                        data.ioc_nal = nal;
-                        rc = ioctl (pfd, IOC_PORTAL_GET_NID, &data);
-                        if (rc < 0)
-                        {
-                                perror ("Can't get my NID");
-                                close (cfd);
-                                continue;
-                        }
-                        
-                        rc = exchange_nids (cfd, data.ioc_nid, &peer_nid);
-                        if (rc != 0)
-                        {
-                                close (cfd);
-                                continue;
-                        }
-                }
+                show_connection (cfd, clntaddr.sin_addr.s_addr);
 
-                show_connection (cfd, clntaddr.sin_addr.s_addr, peer_nid);
+                PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
+                pcfg.pcfg_nal = nal;
+                pcfg.pcfg_fd = cfd;
+                pcfg.pcfg_flags = bind_irq;
+                pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
                 
                 PORTAL_IOC_INIT(data);
-                data.ioc_fd = cfd;
-                data.ioc_nal = nal;
-                data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
-                data.ioc_nid = peer_nid;
-                data.ioc_flags = bind_irq;
+                data.ioc_pbuf1 = (char*)&pcfg;
+                data.ioc_plen1 = sizeof(pcfg);
                 
                 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
                         perror("ioctl failed");
-
                 } else {
                         printf("client registered\n");
                 }
diff --git a/lnet/utils/debug.c b/lnet/utils/debug.c
index 0a009d255117eaa3eb38fe804eb3caeff4c5de07..3f3e69c658468fa9c50e5d38c350d47b186ae699 100644
--- a/lnet/utils/debug.c
+++ b/lnet/utils/debug.c
@@ -31,13 +31,16 @@
 #include <errno.h>
 #include <unistd.h>
 #include <time.h>
-#include <syscall.h>
+#ifndef __CYGWIN__
+# include <syscall.h>
+#endif
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+
 #define BUG()                            /* workaround for module.h includes */
 #include <linux/version.h>
 
@@ -56,6 +59,8 @@ static int max = 8192;
 static int subsystem_mask = ~0;
 static int debug_mask = ~0;
 
+#define MAX_MARK_SIZE 100
+
 static const char *portal_debug_subsystems[] =
         {"undefined", "mdc", "mds", "osc", "ost", "class", "log", "llite",
          "rpc", "mgmt", "portals", "socknal", "qswnal", "pinger", "filter",
@@ -410,13 +415,17 @@ int jt_dbg_debug_file(int argc, char **argv)
                         strerror(errno));
                 return -1;
         }
-#warning FIXME: cleanup fstat issue here
-#ifndef SYS_fstat64
-#define __SYS_fstat__ SYS_fstat
+
+#ifndef __CYGWIN__
+# ifndef SYS_fstat64
+#  define __SYS_fstat__ SYS_fstat
+# else
+#  define __SYS_fstat__ SYS_fstat64
+# endif
+        rc = syscall(__SYS_fstat__, fd, &statbuf);
 #else
-#define __SYS_fstat__ SYS_fstat64
+        rc = fstat(fd, &statbuf);
 #endif
-        rc = syscall(__SYS_fstat__, fd, &statbuf);
         if (rc < 0) {
                 fprintf(stderr, "fstat failed: %s\n", strerror(errno));
                 goto out;
@@ -480,22 +489,29 @@ int jt_dbg_clear_debug_buf(int argc, char **argv)
 
 int jt_dbg_mark_debug_buf(int argc, char **argv)
 {
-        int rc;
+        int rc, max_size = MAX_MARK_SIZE-1;
         struct portal_ioctl_data data;
         char *text;
         time_t now = time(NULL);
 
-        if (argc > 2) {
-                fprintf(stderr, "usage: %s [marker text]\n", argv[0]);
-                return 0;
-        }
-
-        if (argc == 2) {
-                text = argv[1];
+        if (argc > 1) {
+                int counter;
+                text = malloc(MAX_MARK_SIZE);
+                strncpy(text, argv[1], max_size);
+                max_size-=strlen(argv[1]);
+                for(counter = 2; (counter < argc) && (max_size > 0) ; counter++){
+                        strncat(text, " ", 1);
+                        max_size-=1;
+                        strncat(text, argv[counter], max_size);
+                        max_size-=strlen(argv[counter]);
+                }
         } else {
                 text = ctime(&now);
                 text[strlen(text) - 1] = '\0'; /* stupid \n */
         }
+        if (!max_size) {
+                text[MAX_MARK_SIZE - 1] = '\0';
+        }
 
         memset(&data, 0, sizeof(data));
         data.ioc_inllen1 = strlen(text) + 1;
@@ -514,7 +530,6 @@ int jt_dbg_mark_debug_buf(int argc, char **argv)
         return 0;
 }
 
-
 int jt_dbg_modules(int argc, char **argv)
 {
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
@@ -523,7 +538,10 @@ int jt_dbg_modules(int argc, char **argv)
         } *mp, mod_paths[] = {
                 {"portals", "lustre/portals/libcfs"},
                 {"ksocknal", "lustre/portals/knals/socknal"},
+                {"kptlrouter", "lustre/portals/router"},
+                {"lvfs", "lustre/lvfs"},
                 {"obdclass", "lustre/obdclass"},
+                {"llog_test", "lustre/obdclass"},
                 {"ptlrpc", "lustre/ptlrpc"},
                 {"obdext2", "lustre/obdext2"},
                 {"ost", "lustre/ost"},
@@ -536,8 +554,9 @@ int jt_dbg_modules(int argc, char **argv)
                 {"obdfilter", "lustre/obdfilter"},
                 {"extN", "lustre/extN"},
                 {"lov", "lustre/lov"},
-                {"fsfilt_ext3", "lustre/obdclass"},
-                {"fsfilt_extN", "lustre/obdclass"},
+                {"fsfilt_ext3", "lustre/lvfs"},
+                {"fsfilt_extN", "lustre/lvfs"},
+                {"fsfilt_reiserfs", "lustre/lvfs"},
                 {"mds_ext2", "lustre/mds"},
                 {"mds_ext3", "lustre/mds"},
                 {"mds_extN", "lustre/mds"},
diff --git a/lnet/utils/gmlndnid.c b/lnet/utils/gmlndnid.c
new file mode 100644
index 0000000000000000000000000000000000000000..84ac97f55e52577fc0ab65e7b52a75728b41fe28
--- /dev/null
+++ b/lnet/utils/gmlndnid.c
@@ -0,0 +1,119 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+  * vim:expandtab:shiftwidth=8:tabstop=8:
+  *
+  *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+  *
+  *   This file is part of Lustre, http://www.lustre.org/
+  *
+  *   This file is free software; you can redistribute it and/or
+  *   modify it under the terms of version 2.1 of the GNU Lesser General
+  *   Public License as published by the Free Software Foundation.
+  *
+  *   Lustre 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 Lesser General Public License for more details.
+  *
+  *   You should have received a copy of the GNU Lesser General Public
+  *   License along with Portals; if not, write to the Free Software
+  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <asm/byteorder.h>
+#include <syslog.h>
+
+#include <errno.h>
+
+#include <portals/api-support.h>
+#include <portals/list.h>
+#include <portals/lib-types.h>
+
+#define GMNAL_IOC_GET_GNID 1
+
+int
+roundup(int len)
+{
+	return((len+7) & (~0x7));
+}
+
+int main(int argc, char **argv)
+{
+        int rc, pfd;
+        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
+	unsigned int	nid = 0, len;
+	char	*name = NULL;
+	int	c;
+
+
+
+	while ((c = getopt(argc, argv, "n:l")) != -1) {
+		switch(c) {
+		case('n'):
+			name = optarg;	
+		break;
+		case('l'):
+			printf("Get local id not implemented yet!\n");
+			exit(-1);
+		default:
+			printf("usage %s -n nodename [-p]\n", argv[0]);
+		}
+	}
+
+	if (!name) {
+		printf("usage %s -n nodename [-p]\n", argv[0]);
+		exit(-1);
+	}
+
+
+
+
+        PCFG_INIT(pcfg, GMNAL_IOC_GET_GNID);
+        pcfg.pcfg_nal = GMNAL;
+
+	/*
+	 *	set up the inputs
+	 */
+	len = strlen(name) + 1;
+	pcfg.pcfg_pbuf1 = malloc(len);
+	strcpy(pcfg.pcfg_pbuf1, name);
+	pcfg.pcfg_plen1 = len;
+
+	/*
+	 *	set up the outputs
+	 */
+	pcfg.pcfg_pbuf2 = (void*)&nid;
+	pcfg.pcfg_plen2 = sizeof(unsigned int*);
+
+        pfd = open("/dev/portals", O_RDWR);
+        if ( pfd < 0 ) {
+                perror("opening portals device");
+		free(pcfg.pcfg_pbuf1);
+                exit(-1);
+        }
+
+        PORTAL_IOC_INIT(data);
+        data.ioc_pbuf1 = (char*)&pcfg;
+        data.ioc_plen1 = sizeof(pcfg);
+                
+        rc = ioctl (pfd, IOC_PORTAL_NAL_CMD, &data);
+        if (rc < 0)
+        {
+        	perror ("Can't get my NID");
+        }
+                        
+	free(pcfg.pcfg_pbuf1);
+	close(pfd);
+	printf("%u\n", nid);
+        exit(nid);
+}
diff --git a/lnet/utils/l_ioctl.c b/lnet/utils/l_ioctl.c
index 722bb57e24690012388cbaa372f5ffb1661955ff..c6628ff1b374e91197d971101b330126b7db665b 100644
--- a/lnet/utils/l_ioctl.c
+++ b/lnet/utils/l_ioctl.c
@@ -213,7 +213,6 @@ parse_dump(char * dump_file, int (*ioc_func)(int dev_id, int opc, void *))
 	
 	fd = syscall(SYS_open, dump_file, O_RDONLY);
 
-#warning FIXME: cleanup fstat issue here
 #ifndef SYS_fstat64
 #define __SYS_fstat__ SYS_fstat
 #else
diff --git a/lnet/utils/parser.c b/lnet/utils/parser.c
index eccf50704800952aaf7a9f14e3bdabf41d952997..db5292d30db3dfa199283696df783fb630b4b2b3 100644
--- a/lnet/utils/parser.c
+++ b/lnet/utils/parser.c
@@ -80,7 +80,7 @@ static int line2args(char *line, char **argv, int maxargs)
 
     arg = strtok(line, " \t");
     if ( arg ) {
-	argv[i] = arg;
+            argv[i] = arg;
 	i++;
     } else
 	return 0;
@@ -110,7 +110,10 @@ int Parser_execarg(int argc, char **argv, command_t cmds[])
 
         cmd = Parser_findargcmd(argv[0], cmds);
 	if ( cmd ) {
-		return (cmd->pc_func)(argc, argv);
+                int rc = (cmd->pc_func)(argc, argv);
+                if (rc == CMD_HELP)
+                        fprintf(stderr, "%s\n", cmd->pc_help);
+                return rc;
 	} else {
 		printf("Try interactive use without arguments or use one of:\n");
 		for (cmd = cmds; cmd->pc_name; cmd++)
diff --git a/lnet/utils/parser.h b/lnet/utils/parser.h
index dead9f5f1671d2e164c161474f91b1da98d6fe55..44e8f2a4fadfef23ae7f914513ac919ae2f6e475 100644
--- a/lnet/utils/parser.h
+++ b/lnet/utils/parser.h
@@ -2,7 +2,7 @@
 #define _PARSER_H_
 
 #define HISTORY	100		/* Don't let history grow unbounded    */
-#define MAXARGS 100
+#define MAXARGS 512
 
 #define CMD_COMPLETE	0
 #define CMD_INCOMPLETE	1
diff --git a/lnet/utils/portals.c b/lnet/utils/portals.c
index eb53305738fdb5ff7282d7033e49cfa8b77ccbea..3325892ba528a4795db596c8d90bdf7c430fcea9 100644
--- a/lnet/utils/portals.c
+++ b/lnet/utils/portals.c
@@ -40,12 +40,13 @@
 #include <portals/ptlctl.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
+#include <portals/socknal.h>
 #include "parser.h"
 
 unsigned int portal_debug;
 unsigned int portal_printk;
 unsigned int portal_stack;
-
+unsigned int portal_cerror;
 
 static unsigned int g_nal = 0;
 
@@ -65,10 +66,44 @@ static name2num_t nalnames[] = {
         {"toe",		TOENAL},
         {"elan",	QSWNAL},
         {"gm",	        GMNAL},
+        {"ib",	        IBNAL},
         {"scimac",      SCIMACNAL},
         {NULL,		-1}
 };
 
+static cfg_record_cb_t g_record_cb;
+
+int 
+ptl_set_cfg_record_cb(cfg_record_cb_t cb)
+{
+        g_record_cb = cb;
+        return 0;
+}
+
+int 
+pcfg_ioctl(struct portals_cfg *pcfg) 
+{
+        int rc;
+
+        if (pcfg->pcfg_nal ==0)
+                pcfg->pcfg_nal    = g_nal;
+
+        if (g_record_cb) {
+                rc = g_record_cb(PORTALS_CFG_TYPE, sizeof(*pcfg), pcfg);
+        } else {
+                struct portal_ioctl_data data;
+                PORTAL_IOC_INIT (data);
+                data.ioc_pbuf1   = (char*)pcfg;
+                data.ioc_plen1   = sizeof(*pcfg);
+
+                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        }
+
+        return (rc);
+}
+
+
+
 static name2num_t *
 name2num_lookup_name (name2num_t *table, char *str)
 {
@@ -227,8 +262,9 @@ ptl_ipaddr_2_str (__u32 ipaddr, char *str)
 int
 ptl_parse_nid (ptl_nid_t *nidp, char *str)
 {
-        __u32 ipaddr;
-        long  lval;
+        __u32               ipaddr;
+        char               *end;
+        unsigned long long  ullval;
         
         if (!strcmp (str, "_all_")) {
                 *nidp = PTL_NID_ANY;
@@ -240,15 +276,10 @@ ptl_parse_nid (ptl_nid_t *nidp, char *str)
                 return (0);
         }
 
-        if (sscanf (str, "%li", &lval) == 1)
-        {
-                *nidp = (ptl_nid_t)lval;
-                return (0);
-        }
-
-        if (sscanf (str, "%lx", &lval) == 1)
-        {
-                *nidp = (ptl_nid_t)lval;
+        ullval = strtoull(str, &end, 0);
+        if (*end == 0) {
+                /* parsed whole string */
+                *nidp = (ptl_nid_t)ullval;
                 return (0);
         }
 
@@ -391,7 +422,7 @@ int jt_ptl_network(int argc, char **argv)
 int 
 jt_ptl_print_autoconnects (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         char                     buffer[64];
         int                      index;
         int                      rc;
@@ -400,24 +431,21 @@ jt_ptl_print_autoconnects (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_AUTOCONN;
-                data.ioc_count   = index;
-                
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                PCFG_INIT (pcfg, NAL_CMD_GET_AUTOCONN);
+                pcfg.pcfg_count   = index;
+
+                rc = pcfg_ioctl (&pcfg);
                 if (rc != 0)
                         break;
 
-                printf (LPX64"@%s:%d #%d buffer %d nonagle %s xchg %s "
-                        "affinity %s eager %s share %d\n",
-                        data.ioc_nid, ptl_ipaddr_2_str (data.ioc_id, buffer),
-                        data.ioc_misc, data.ioc_count, data.ioc_size, 
-                        (data.ioc_flags & 1) ? "on" : "off",
-                        (data.ioc_flags & 2) ? "on" : "off",
-                        (data.ioc_flags & 4) ? "on" : "off",
-                        (data.ioc_flags & 8) ? "on" : "off",
-                        data.ioc_wait);
+                printf (LPX64"@%s:%d #%d buffer %d "
+                        "nonagle %s affinity %s eager %s share %d\n",
+                        pcfg.pcfg_nid, ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
+                        pcfg.pcfg_misc, pcfg.pcfg_count, pcfg.pcfg_size, 
+                        (pcfg.pcfg_flags & 1) ? "on" : "off",
+                        (pcfg.pcfg_flags & 2) ? "on" : "off",
+                        (pcfg.pcfg_flags & 4) ? "on" : "off",
+                        pcfg.pcfg_wait);
         }
 
         if (index == 0)
@@ -428,18 +456,17 @@ jt_ptl_print_autoconnects (int argc, char **argv)
 int 
 jt_ptl_add_autoconnect (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         ptl_nid_t                nid;
         __u32                    ip;
         int                      port;
-        int                      xchange_nids = 0;
         int                      irq_affinity = 0;
         int                      share = 0;
         int                      eager = 0;
         int                      rc;
 
         if (argc < 4 || argc > 5) {
-                fprintf (stderr, "usage: %s nid ipaddr port [ixse]\n", argv[0]);
+                fprintf (stderr, "usage: %s nid ipaddr port [ise]\n", argv[0]);
                 return 0;
         }
 
@@ -467,9 +494,6 @@ jt_ptl_add_autoconnect (int argc, char **argv)
                 
                 while (*opts != 0)
                         switch (*opts++) {
-                        case 'x':
-                                xchange_nids = 1;
-                                break;
                         case 'i':
                                 irq_affinity = 1;
                                 break;
@@ -486,21 +510,18 @@ jt_ptl_add_autoconnect (int argc, char **argv)
                         }
         }
 
-        PORTAL_IOC_INIT (data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_ADD_AUTOCONN;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ip;
-        data.ioc_misc    = port;
+        PCFG_INIT(pcfg, NAL_CMD_ADD_AUTOCONN);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ip;
+        pcfg.pcfg_misc    = port;
         /* only passing one buffer size! */
-        data.ioc_size    = MAX (g_socket_rxmem, g_socket_txmem);
-        data.ioc_flags   = (g_socket_nonagle ? 0x01 : 0) |
-                           (xchange_nids     ? 0x02 : 0) |
-                           (irq_affinity     ? 0x04 : 0) |
-                           (share            ? 0x08 : 0) |
-                           (eager            ? 0x10 : 0);
-
-        rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        pcfg.pcfg_size    = MAX (g_socket_rxmem, g_socket_txmem);
+        pcfg.pcfg_flags   = (g_socket_nonagle ? 0x01 : 0) |
+                            (irq_affinity     ? 0x02 : 0) |
+                            (share            ? 0x04 : 0) |
+                            (eager            ? 0x08 : 0);
+
+        rc = pcfg_ioctl (&pcfg);
         if (rc != 0) {
                 fprintf (stderr, "failed to enable autoconnect: %s\n",
                          strerror (errno));
@@ -513,7 +534,7 @@ jt_ptl_add_autoconnect (int argc, char **argv)
 int 
 jt_ptl_del_autoconnect (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ip  = 0;
         int                      share = 0;
@@ -559,15 +580,13 @@ jt_ptl_del_autoconnect (int argc, char **argv)
                         }
         }
 
-        PORTAL_IOC_INIT (data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_DEL_AUTOCONN;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ip;
-        data.ioc_flags   = (share     ? 1 : 0) |
+        PCFG_INIT(pcfg, NAL_CMD_DEL_AUTOCONN);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ip;
+        pcfg.pcfg_flags   = (share     ? 1 : 0) |
                            (keep_conn ? 2 : 0);
-        
-        rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+
+        rc = pcfg_ioctl (&pcfg);
         if (rc != 0) {
                 fprintf (stderr, "failed to remove autoconnect route: %s\n",
                          strerror (errno));
@@ -580,7 +599,7 @@ jt_ptl_del_autoconnect (int argc, char **argv)
 int 
 jt_ptl_print_connections (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         char                     buffer[64];
         int                      index;
         int                      rc;
@@ -589,19 +608,21 @@ jt_ptl_print_connections (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_CONN;
-                data.ioc_count   = index;
+                PCFG_INIT (pcfg,  NAL_CMD_GET_CONN);
+                pcfg.pcfg_count   = index;
                 
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                rc = pcfg_ioctl (&pcfg);
                 if (rc != 0)
                         break;
 
-                printf (LPX64"@%s:%d\n",
-                        data.ioc_nid, 
-                        ptl_ipaddr_2_str (data.ioc_id, buffer),
-                        data.ioc_misc);
+                printf (LPX64"@%s:%d:%s\n",
+                        pcfg.pcfg_nid, 
+                        ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
+                        pcfg.pcfg_misc,
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_ANY) ? "A" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_CONTROL) ? "C" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_IN) ? "I" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
         }
 
         if (index == 0)
@@ -609,82 +630,9 @@ jt_ptl_print_connections (int argc, char **argv)
         return 0;
 }
 
-int
-exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
-{
-        int                      rc;
-        ptl_hdr_t                hdr;
-        ptl_magicversion_t      *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
-
-        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
-
-        memset (&hdr, 0, sizeof (hdr));
-        
-        hmv->magic          = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
-        hmv->version_major  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
-        hmv->version_minor  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
-
-        hdr.src_nid = __cpu_to_le64 (my_nid);
-        hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
-        
-        /* Assume there's sufficient socket buffering for a portals HELLO header */
-        rc = sock_write (cfd, &hdr, sizeof (hdr));
-        if (rc != 0) {
-                perror ("Can't send initial HELLO");
-                return (-1);
-        }
-
-        /* First few bytes down the wire are the portals protocol magic and
-         * version, no matter what protocol version we're running. */
-
-        rc = sock_read (cfd, hmv, sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read from peer");
-                return (-1);
-        }
-
-        if (hmv->magic != __cpu_to_le32 (PORTALS_PROTO_MAGIC)) {
-                fprintf (stderr, "Bad magic %#08x (%#08x expected)\n", 
-                         __le32_to_cpu (hmv->magic), PORTALS_PROTO_MAGIC);
-                return (-1);
-        }
-
-        if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
-            hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
-                fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
-                         __le16_to_cpu (hmv->version_major),
-                         __le16_to_cpu (hmv->version_minor),
-                         PORTALS_PROTO_VERSION_MAJOR,
-                         PORTALS_PROTO_VERSION_MINOR);
-        }
-
-        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
-         * so read the rest of it in now... */
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read rest of HELLO hdr");
-                return (-1);
-        }
-
-        /* ...and check we got what we expected */
-        if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
-            PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
-                fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
-                         " but got type %d with %d payload\n",
-                         __le32_to_cpu (hdr.type),
-                         __le32_to_cpu (PTL_HDR_LENGTH (&hdr)));
-                return (-1);
-        }
-        
-        *peer_nid = __le64_to_cpu (hdr.src_nid);
-        return (0);
-}
-
 int jt_ptl_connect(int argc, char **argv)
 {
-        ptl_nid_t peer_nid;
-        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
         struct sockaddr_in srvaddr;
         __u32 ipaddr;
         char *flag;
@@ -693,13 +641,13 @@ int jt_ptl_connect(int argc, char **argv)
         int rxmem = 0;
         int txmem = 0;
         int bind_irq = 0;
-        int xchange_nids = 0;
+        int type = SOCKNAL_CONN_ANY;
         int port;
         int o;
         int olen;
 
         if (argc < 3) {
-                fprintf(stderr, "usage: %s ip port [xi]\n", argv[0]);
+                fprintf(stderr, "usage: %s ip port [xibctr]\n", argv[0]);
                 return 0;
         }
 
@@ -725,8 +673,28 @@ int jt_ptl_connect(int argc, char **argv)
                                 bind_irq = 1;
                                 break;
                                 
-                        case 'x':
-                                xchange_nids = 1;
+                        case 'I':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_BULK_IN;
+                                break;
+
+                        case 'O':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_BULK_OUT;
+                                break;
+
+                        case 'C':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_CONTROL;
                                 break;
                                 
                         default:
@@ -787,36 +755,20 @@ int jt_ptl_connect(int argc, char **argv)
         if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
                 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
 
-        if (!xchange_nids) 
-                peer_nid = ipaddr;
-        else {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal = g_nal;
-                rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
-                if (rc != 0) {
-                        fprintf (stderr, "failed to get my nid: %s\n",
-                                 strerror (errno));
-                        close (fd);
-                        return (-1);
-                }
-
-                rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
-                if (rc != 0) {
-                        close (fd);
-                        return (-1);
-                }
-        } 
-        printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
-               peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
-
-        PORTAL_IOC_INIT(data);
-        data.ioc_fd = fd;
-        data.ioc_nal = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
-        data.ioc_nid = peer_nid;
-        data.ioc_flags = bind_irq;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        printf("Connected host: %s snd: %d rcv: %d nagle: %s type: %s\n", 
+               argv[1], txmem, rxmem, nonagle ? "Disabled" : "Enabled",
+               (type == SOCKNAL_CONN_ANY) ? "A" :
+               (type == SOCKNAL_CONN_CONTROL) ? "C" :
+               (type == SOCKNAL_CONN_BULK_IN) ? "I" :
+               (type == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
+
+        PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
+        pcfg.pcfg_nal = g_nal;
+        pcfg.pcfg_fd = fd;
+        pcfg.pcfg_flags = bind_irq;
+        pcfg.pcfg_misc = type;
+        
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to register fd with portals: %s\n", 
                         strerror(errno));
@@ -824,7 +776,7 @@ int jt_ptl_connect(int argc, char **argv)
                 return -1;
         }
 
-        printf("Connection to "LPX64" registered with socknal\n", peer_nid);
+        printf("Connection to %s registered with socknal\n", argv[1]);
 
         rc = close(fd);
         if (rc)
@@ -835,7 +787,7 @@ int jt_ptl_connect(int argc, char **argv)
 
 int jt_ptl_disconnect(int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ipaddr = 0;
         int                      rc;
@@ -860,13 +812,11 @@ int jt_ptl_disconnect(int argc, char **argv)
                 return -1;
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ipaddr;
+        PCFG_INIT(pcfg, NAL_CMD_CLOSE_CONNECTION);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ipaddr;
         
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to remove connection: %s\n",
                         strerror(errno));
@@ -878,7 +828,7 @@ int jt_ptl_disconnect(int argc, char **argv)
 
 int jt_ptl_push_connection (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         int                      rc;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ipaddr = 0;
@@ -902,13 +852,11 @@ int jt_ptl_push_connection (int argc, char **argv)
                 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ipaddr;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        PCFG_INIT(pcfg, NAL_CMD_PUSH_CONNECTION);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ipaddr;
+        
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to push connection: %s\n",
                         strerror(errno));
@@ -921,7 +869,7 @@ int jt_ptl_push_connection (int argc, char **argv)
 int 
 jt_ptl_print_active_txs (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         int                      index;
         int                      rc;
 
@@ -929,28 +877,26 @@ jt_ptl_print_active_txs (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_TXDESC;
-                data.ioc_count   = index;
-                
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                PCFG_INIT(pcfg, NAL_CMD_GET_TXDESC);
+                pcfg.pcfg_count   = index;
+        
+                rc = pcfg_ioctl(&pcfg);
                 if (rc != 0)
                         break;
 
-                printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s,%s,%s\n",
-                        data.ioc_pbuf1,
-                        data.ioc_count == PTL_MSG_ACK ? "ACK" :
-                        data.ioc_count == PTL_MSG_PUT ? "PUT" :
-                        data.ioc_count == PTL_MSG_GET ? "GET" :
-                        data.ioc_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
-                        data.ioc_size,
-                        data.ioc_nid,
-                        data.ioc_nid2,
-                        data.ioc_misc,
-                        (data.ioc_flags & 1) ? "delayed" : "active",
-                        (data.ioc_flags & 2) ? "forwarding" : "sending",
-                        (data.ioc_flags & 4) ? "nblk" : "normal");
+                printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s, %s, state %d\n",
+                        pcfg.pcfg_pbuf1,
+                        pcfg.pcfg_count == PTL_MSG_ACK ? "ACK" :
+                        pcfg.pcfg_count == PTL_MSG_PUT ? "PUT" :
+                        pcfg.pcfg_count == PTL_MSG_GET ? "GET" :
+                        pcfg.pcfg_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
+                        pcfg.pcfg_size,
+                        pcfg.pcfg_nid,
+                        pcfg.pcfg_nid2,
+                        pcfg.pcfg_misc,
+                        (pcfg.pcfg_flags & 1) ? "delayed" : "immediate",
+                        (pcfg.pcfg_flags & 2) ? "nblk"    : "normal",
+                        pcfg.pcfg_flags >> 2);
         }
 
         if (index == 0)
@@ -1043,7 +989,7 @@ int jt_ptl_mynid(int argc, char **argv)
         int rc;
         char hostname[1024];
         char *nidstr;
-        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
         ptl_nid_t mynid;
         
         if (argc > 2) {
@@ -1071,12 +1017,10 @@ int jt_ptl_mynid(int argc, char **argv)
                 return -1;
         }
         
-        PORTAL_IOC_INIT(data);
-        data.ioc_nid = mynid;
-        data.ioc_nal = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
+        PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
+        pcfg.pcfg_nid = mynid;
 
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc < 0)
                 fprintf(stderr, "setting my NID failed: %s\n",
                        strerror(errno));
@@ -1190,7 +1134,7 @@ jt_ptl_nagle (int argc, char **argv)
 int
 jt_ptl_add_route (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid1;
         ptl_nid_t                nid2;
         ptl_nid_t                gateway_nid;
@@ -1225,16 +1169,17 @@ jt_ptl_add_route (int argc, char **argv)
                 return (-1);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nid = gateway_nid;
-        data.ioc_nal = g_nal;
-        data.ioc_nid2 = MIN (nid1, nid2);
-        data.ioc_nid3 = MAX (nid1, nid2);
+        PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE);
+        pcfg.pcfg_nid = gateway_nid;
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid2 = MIN (nid1, nid2);
+        pcfg.pcfg_nid3 = MAX (nid1, nid2);
 
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
+                fprintf (stderr, "NAL_CMD_ADD_ROUTE failed: %s\n", strerror (errno));
                 return (-1);
         }
         
@@ -1244,7 +1189,7 @@ jt_ptl_add_route (int argc, char **argv)
 int
 jt_ptl_del_route (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid;
         ptl_nid_t                nid1 = PTL_NID_ANY;
         ptl_nid_t                nid2 = PTL_NID_ANY;
@@ -1288,16 +1233,17 @@ jt_ptl_del_route (int argc, char **argv)
                 }
         }
         
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal = g_nal;
-        data.ioc_nid = nid;
-        data.ioc_nid2 = nid1;
-        data.ioc_nid3 = nid2;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
+        PCFG_INIT(pcfg, NAL_CMD_DEL_ROUTE);
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid = nid;
+        pcfg.pcfg_nid2 = nid1;
+        pcfg.pcfg_nid3 = nid2;
+
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
+                fprintf (stderr, "NAL_CMD_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
                 return (-1);
         }
         
@@ -1307,7 +1253,7 @@ jt_ptl_del_route (int argc, char **argv)
 int
 jt_ptl_notify_router (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         int                      enable;
         ptl_nid_t                nid;
         int                      rc;
@@ -1347,17 +1293,18 @@ jt_ptl_notify_router (int argc, char **argv)
                 return (-1);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal = g_nal;
-        data.ioc_nid = nid;
-        data.ioc_flags = enable;
+        PCFG_INIT(pcfg, NAL_CMD_NOTIFY_ROUTER);
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid = nid;
+        pcfg.pcfg_flags = enable;
         /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
-        data.ioc_nid3 = (__u64)when;
+        pcfg.pcfg_nid3 = (__u64)when;
         
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NOTIFY_ROUTER, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_NOTIFY_ROUTER ("LPX64") failed: %s\n",
+                fprintf (stderr, "NAL_CMD_NOTIFY_ROUTER ("LPX64") failed: %s\n",
                          nid, strerror (errno));
                 return (-1);
         }
@@ -1369,7 +1316,7 @@ int
 jt_ptl_print_routes (int argc, char **argv)
 {
         char                      buffer[3][128];
-        struct portal_ioctl_data  data;
+        struct portals_cfg        pcfg;
         int                       rc;
         int                       index;
         int			  gateway_nal;
@@ -1380,18 +1327,19 @@ jt_ptl_print_routes (int argc, char **argv)
 
         for (index = 0;;index++)
         {
-                PORTAL_IOC_INIT(data);
-                data.ioc_count = index;
+                PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE);
+                pcfg.pcfg_nal = ROUTER;
+                pcfg.pcfg_count = index;
                 
-                rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
+                rc = pcfg_ioctl(&pcfg);
                 if (rc != 0)
                         break;
 
-                gateway_nal = data.ioc_nal;
-                gateway_nid = data.ioc_nid;
-                nid1 = data.ioc_nid2;
-                nid2 = data.ioc_nid3;
-                alive = data.ioc_flags;
+                gateway_nal = pcfg.pcfg_gw_nal;
+                gateway_nid = pcfg.pcfg_nid;
+                nid1 = pcfg.pcfg_nid2;
+                nid2 = pcfg.pcfg_nid3;
+                alive = pcfg.pcfg_flags;
 
                 printf ("%8s %18s : %s - %s, %s\n", 
                         nal2name (gateway_nal), 
diff --git a/lnet/utils/ptlctl.c b/lnet/utils/ptlctl.c
index 1a8e637291ee307f49aa58533029d5da234f7f51..c65ecb2443634f00d93f848570ab46c1d46fb101 100644
--- a/lnet/utils/ptlctl.c
+++ b/lnet/utils/ptlctl.c
@@ -31,10 +31,10 @@
 command_t list[] = {
         {"network", jt_ptl_network, 0,"setup the NAL (args: nal name)"},
         {"print_autoconns", jt_ptl_print_autoconnects, 0, "print autoconnect entries (no args)"},
-        {"add_autoconn", jt_ptl_add_autoconnect, 0, "add autoconnect entry (args: nid host [ixse])"},
+        {"add_autoconn", jt_ptl_add_autoconnect, 0, "add autoconnect entry (args: nid host [ise])"},
         {"del_autoconn", jt_ptl_del_autoconnect, 0, "delete autoconnect entry (args: [nid] [host] [ks])"},
         {"print_conns", jt_ptl_print_connections, 0, "print connections (no args)"},
-        {"connect", jt_ptl_connect, 0, "connect to a remote nid (args: host port [xi])"},
+        {"connect", jt_ptl_connect, 0, "connect to a remote nid (args: host port [iIOC])"},
         {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid (args: [nid] [host]"},
         {"push", jt_ptl_push_connection, 0, "flush connection to a remote nid (args: [nid]"},
         {"active_tx", jt_ptl_print_active_txs, 0, "print active transmits (no args)"},
diff --git a/lnet/utils/wirecheck.c b/lnet/utils/wirecheck.c
index 6a4377b300c91510be79ad1ec6abd08c2284e946..77ad126a3e00176cec899accf4fb0119897f7246 100644
--- a/lnet/utils/wirecheck.c
+++ b/lnet/utils/wirecheck.c
@@ -2,10 +2,14 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  */
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <portals/api-support.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
 
+extern size_t strnlen(const char *, size_t);
+
 #define BLANK_LINE()				\
 do {						\
 	printf ("\n");				\
@@ -77,47 +81,109 @@ check_ptl_hdr (void)
 	CHECK_MEMBER (ptl_hdr_t, dest_pid);
 	CHECK_MEMBER (ptl_hdr_t, src_pid);
 	CHECK_MEMBER (ptl_hdr_t, type);
-
+	CHECK_MEMBER (ptl_hdr_t, payload_length);
+        CHECK_MEMBER (ptl_hdr_t, msg);
+        
         BLANK_LINE ();
         COMMENT ("Ack");
-        CHECK_MEMBER (ptl_hdr_t, msg.ack.mlength);
         CHECK_MEMBER (ptl_hdr_t, msg.ack.dst_wmd);
         CHECK_MEMBER (ptl_hdr_t, msg.ack.match_bits);
-        CHECK_MEMBER (ptl_hdr_t, msg.ack.length);
+        CHECK_MEMBER (ptl_hdr_t, msg.ack.mlength);
 
         BLANK_LINE ();
         COMMENT ("Put");
-	CHECK_MEMBER (ptl_hdr_t, msg.put.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.ack_wmd);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.match_bits);
-	CHECK_MEMBER (ptl_hdr_t, msg.put.length);
-	CHECK_MEMBER (ptl_hdr_t, msg.put.offset);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.hdr_data);
+	CHECK_MEMBER (ptl_hdr_t, msg.put.ptl_index);
+	CHECK_MEMBER (ptl_hdr_t, msg.put.offset);
 
         BLANK_LINE ();
         COMMENT ("Get");
-	CHECK_MEMBER (ptl_hdr_t, msg.get.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.return_wmd);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.match_bits);
-	CHECK_MEMBER (ptl_hdr_t, msg.get.length);
+	CHECK_MEMBER (ptl_hdr_t, msg.get.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.src_offset);
-	CHECK_MEMBER (ptl_hdr_t, msg.get.return_offset);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.sink_length);
 
         BLANK_LINE ();
         COMMENT ("Reply");
 	CHECK_MEMBER (ptl_hdr_t, msg.reply.dst_wmd);
-	CHECK_MEMBER (ptl_hdr_t, msg.reply.dst_offset);
-	CHECK_MEMBER (ptl_hdr_t, msg.reply.length);
+
+        BLANK_LINE ();
+        COMMENT ("Hello");
+	CHECK_MEMBER (ptl_hdr_t, msg.hello.incarnation);
+	CHECK_MEMBER (ptl_hdr_t, msg.hello.type);
+}
+
+void
+system_string (char *cmdline, char *str, int len)
+{
+        int   fds[2];
+        int   rc;
+        pid_t pid;
+        
+        rc = pipe (fds);
+        if (rc != 0)
+                abort ();
+        
+        pid = fork ();
+        if (pid == 0) {
+                /* child */
+                int   fd = fileno(stdout);
+
+                rc = dup2(fds[1], fd);
+                if (rc != fd)
+                        abort();
+
+                exit(system(cmdline));
+                /* notreached */
+        } else if ((int)pid < 0) {
+                abort();
+        } else {
+                FILE *f = fdopen (fds[0], "r");
+
+                if (f == NULL)
+                        abort();
+                
+                close(fds[1]);
+                
+                if (fgets(str, len, f) == NULL)
+                        abort();
+                
+                if (waitpid(pid, &rc, 0) != pid)
+                        abort();
+                
+                if (!WIFEXITED(rc) ||
+                    WEXITSTATUS(rc) != 0)
+                        abort();
+
+                if (strnlen(str, len) == len)
+                        str[len - 1] = 0;
+                
+                if (str[strlen(str) - 1] == '\n')
+                        str[strlen(str) - 1] = 0;
+                
+                fclose(f);
+        }
 }
 
 int
 main (int argc, char **argv)
 {
+        char unameinfo[80];
+        char gccinfo[80];
+        
+        system_string("uname -a", unameinfo, sizeof(unameinfo));
+        system_string("gcc -v 2>&1 | tail -1", gccinfo, sizeof(gccinfo));
+        
 	printf ("void lib_assert_wire_constants (void)\n"
-		"{\n");
-
-	COMMENT ("Wire protocol assertions generated by 'wirecheck'");
+		"{\n"
+                "        /* Wire protocol assertions generated by 'wirecheck'\n"
+                "         * running on %s\n"
+                "         * with %s */\n"
+                "\n", unameinfo, gccinfo);
+        
 	BLANK_LINE ();
 	
 	COMMENT ("Constants...");
diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 5d507ffc0523603a972c0a427ccadd8fe45db3ab..b5e4fa9c8991523e0a27d21af3ccfd7ce7c43ded 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -1,9 +1,9 @@
 tbd
        * version v0_8
        * bug fixes
-        - orphans are moved into the PENDING directory for possible recovery
-        - replayed opens now open by fid for orphan/rename safety (1042)
-        - last close of an orphan inode generates a transno (683)
+	- orphans are moved into the PENDING directory for possible recovery
+	- replayed opens now open by fid for orphan/rename safety (1042)
+	- last close of an orphan inode generates a transno (683)
 	- chdir() and mount() now pin the directory entry (1020)
 	- avoid CERROR in normal ll_setattr_raw() error case (1500)
 	- discard very old requests without processing them (1502)
@@ -21,7 +21,36 @@ tbd
 	- exit early from mds_open if we get a lookup error (1749)
 	- partial page read at EOF wouldn't wait for disk before sending (1642)
 	- avoid NULL deref in obdfilter when reading page past EOF (1592)
-	- bug 56: POSIX utime.4 -EPERM on FIFO not owned by user
+	- avoid LASSERT in ll_intent_lock if server failed very early (1090)
+	- fix LBUG in ll_it_open_error with rc = -2 (1861)
+	- write/truncate lock inversion (1639)
+	- Don't auto-load obdclass, portals modules during cleanup (1495)
+	- fix timestamps from jumping to "now" (1763)
+	- extra journal assertions (1648)
+	- add an extra multiunlink test (1771)
+	- fix read_record/write_record API (1776)
+	- fix leak of offset_extent, possible incorrect i_size later (1772)
+	- fix lasserts in mis-matched transnos during open-unlink testing (1541)
+	- Debugging for the kqswnal_get_idle_tx problems (1820)
+	- Allow recovery to be attempted multiple times (1536)
+	- Write out MDS last_rcvd file after it is first created (1600)
+	- Fix tx_descriptor leak in failed transmit situations (1827)
+	- ext3 journaling fixes for assertion failure after IO error (1871)
+	- class_export_put() on freed export after completion AST error (1896)
+	- Fix revalidate looping in VFS (1322)
+	- Don't access a freed export during MDS_REINT timeout (1521)
+	- Add open-unlink recovery support on the MDS (1673,1764)
+	- Return an error if no MDS data was read from last_rcvd (1946)
+	- Fix for lookup "." or ".." crash on error (1932,1931,1935)
+	- Don't setup a disk device that doesn't match exported UUID (317)
+	- Reduce bulk RPC timeout to avoid cascading client/OST failures (1845)
+	- avoid committing NULL handle in force close
+	- local.sh is now a one-stripe LOV configuration
+	- POSIX utime.4 -EPERM on FIFO not owned by user (56)
+	- fix ext3 htree duplicate directory entry corruption (1516)
+	- POSIX creat.13, fstat.1, open.18, stat.3 new file atime/mtime (2020)
+	- update to new LOV EA format (2097)
+	- interoperability for different PAGE_SIZE/wordsize (686,1821,1343,2042)
 
 2003-06-15  Phil Schwan  <phil@clusterfs.com>
        * version v0_7
diff --git a/lustre/Makefile.am b/lustre/Makefile.am
index 425bed2c1babd8735e041f73b8352e4458c1909c..8315ca70f157c0dd7cac6a5da7fabd297db5a303 100644
--- a/lustre/Makefile.am
+++ b/lustre/Makefile.am
@@ -12,17 +12,14 @@ DIRS24 = ptlbd
 endif
 
 if LIBLUSTRE
-SUBDIRS = portals obdclass lov ptlrpc obdecho ldlm osc utils mdc #liblustre
+SUBDIRS = portals obdclass lov ptlrpc obdecho  osc utils mdc lvfs #liblustre
 else
-# NOTE: keep extN before obdclass, mds, and obdfilter.  Keep obdclass as early
-# as possible, to have the best chance at stopping with "wrong kernel version"
-# instead of some related build failure.
-SUBDIRS = portals obdclass $(DIRS24) mds utils ldlm obdfilter mdc osc ost
+SUBDIRS = lvfs portals obdclass include $(DIRS24) mds utils obdfilter mdc osc ost 
 SUBDIRS+= llite obdecho lov cobd tests doc scripts conf ptlrpc
 endif
 
 DIST_SUBDIRS = $(SUBDIRS) liblustre
-EXTRA_DIST = BUGS FDL Rules include kernel_patches
+EXTRA_DIST = BUGS FDL Rules kernel_patches
 
 # We get the version from the spec file.
 CONFIGURE_DEPENDENCIES = scripts/lustre.spec.in
@@ -36,3 +33,19 @@ include $(top_srcdir)/Rules
 rpms: dist Makefile
 	rpmbuild -ta $(distdir).tar.gz
 
+CSTK=/tmp/checkstack
+CSTKO=/tmp/checkstack.orig
+
+checkstack:
+	[ -f ${CSTK} -a ! -s ${CSTKO} ] && mv ${CSTK} ${CSTKO} || true
+	for i in ${SUBDIRS} portals/knals/*; do				     \
+		MOD=$$i/`basename $$i`.o;				     \
+		[ -f $$MOD ] && objdump -d $$MOD | perl tests/checkstack.pl; \
+	done | sort -nr > ${CSTK}
+	[ -f ${CSTKO} ] && ! diff -u ${CSTKO} ${CSTK} || head -30 ${CSTK}
+
+checkstack-update:
+	[ -f ${CSTK} ] && mv ${CSTK} ${CSTKO}
+
+checkstack-clean:
+	rm -f ${CSTK} ${CSTKO}
diff --git a/lustre/Makefile.mk b/lustre/Makefile.mk
index 59178a476dc9ab7c3ce1b8dd8d2b660b7f546796..9d11539a6a09e1f35f135317eff3dcdd94e1bcfc 100644
--- a/lustre/Makefile.mk
+++ b/lustre/Makefile.mk
@@ -16,6 +16,7 @@ obj-y += osc/
 obj-y += ost/
 obj-y += lov/
 obj-y += llite/
+obj-y += lvfs/
 
 # portals needs to be before utils/, which pulls in ptlctl objects
 obj-m += utils/
diff --git a/lustre/README b/lustre/README
index 1a806578e72f7c06fc213260308f8db4a97a55db..c052124dfba17532e0841ef885c8eec489051eca 100644
--- a/lustre/README
+++ b/lustre/README
@@ -1,8 +1,2 @@
-Instructions for building, configuring and running Lustre can be found in
-the file doc/lustre-HOWTO.txt.
-
-If you have checked lustre directly out of CVS, then you either need to
-get lyx to build the lustre-HOWTO.txt from the source file, get the PDF
-version from the lustre.org website, or install the lustre-doc RPM for
-the formatted text version (or read the somewhat cryptic lustre-HOWTO.lin
-file if you are desperate).
+Instructions for building, configuring and running Lustre can be found at:
+    http://projects.clusterfs.com/lustre/LustreHowto.
diff --git a/lustre/Rules b/lustre/Rules
index 0d922465b4b08db21561af4002147743cba1e8c9..b28540a76523d5c01f39243ed9b6a494be33c44b 100644
--- a/lustre/Rules
+++ b/lustre/Rules
@@ -22,12 +22,17 @@ AM_CPPFLAGS=-I$(top_builddir)/include
 
 endif
 
-$(MODULE).o: $($(MODULE)_OBJECTS)
+$(MODULE).o: $($(MODULE)_OBJECTS) $($(MODULE)_DEPENDENCIES)
 	$(LD) -m "`$(LD) --help | awk '/supported emulations/ {print $$4}'`" -r -o $(MODULE).o $($(MODULE)_OBJECTS)
 
 tags:
 	rm -f $(top_srcdir)/TAGS
+	ETAGSF=`etags --version | grep -iq exuberant && \
+		echo "-I __initdata,__exitdata,EXPORT_SYMBOL"`; \
+	find $(top_srcdir) -name '*.[hc]' | xargs etags $$ETAGSF -a
+
 	rm -f $(top_srcdir)/tags
-	find $(top_srcdir) -name '*.[hc]' | grep -v ".orig" | xargs etags -a
-	find $(top_srcdir) -name '*.[hc]' | grep -v ".orig" | xargs ctags -a
+	CTAGSF=`ctags --version | grep -iq exuberant && \
+		echo "-I __initdata,__exitdata,EXPORT_SYMBOL"`; \
+	find $(top_srcdir) -name '*.[hc]' | xargs ctags $$CTAGSF -a
 
diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c
index 2d3549b9a385f8508cabe9d75d927744449c05e3..5c978bffae4e058996d20e90b81a848df0d24ff2 100644
--- a/lustre/cobd/cache_obd.c
+++ b/lustre/cobd/cache_obd.c
@@ -22,9 +22,7 @@
 #define DEBUG_SUBSYSTEM S_COBD
 
 #include <linux/version.h>
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 #include <linux/init.h>
-#endif
 #include <linux/obd_support.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_net.h>
@@ -48,22 +46,23 @@ static int cobd_detach(struct obd_device *dev)
 static int
 cobd_setup (struct obd_device *dev, obd_count len, void *buf)
 {
-        struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
+        struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
         struct cache_obd  *cobd = &dev->u.cobd;
         struct obd_device *target;
         struct obd_device *cache;
         struct obd_uuid target_uuid;
         struct obd_uuid cache_uuid;
+        struct lustre_handle target_conn = {0,}, cache_conn = {0,};
         int                rc;
 
-        if (data->ioc_inlbuf1 == NULL ||
-            data->ioc_inlbuf2 == NULL)
+        if (lcfg->lcfg_inlbuf1 == NULL ||
+            lcfg->lcfg_inlbuf2 == NULL)
                 return (-EINVAL);
 
-        obd_str2uuid(&target_uuid, data->ioc_inlbuf1);
+        obd_str2uuid(&target_uuid, lcfg->lcfg_inlbuf1);
         target = class_uuid2obd (&target_uuid);
 
-        obd_str2uuid(&cache_uuid, data->ioc_inlbuf2);
+        obd_str2uuid(&cache_uuid, lcfg->lcfg_inlbuf2);
         cache  = class_uuid2obd (&cache_uuid);
         if (target == NULL ||
             cache == NULL)
@@ -71,19 +70,19 @@ cobd_setup (struct obd_device *dev, obd_count len, void *buf)
 
         /* don't bother checking attached/setup;
          * obd_connect() should, and it can change underneath us */
-        rc = obd_connect (&cobd->cobd_target, target, &target_uuid);
+        rc = obd_connect(&target_conn, target, &target_uuid);
         if (rc != 0)
                 return (rc);
+        cobd->cobd_target_exp = class_conn2export(&target_conn);
 
-        rc = obd_connect (&cobd->cobd_cache, cache, &cache_uuid);
-        if (rc != 0)
-                goto fail_0;
-
-        return (0);
+        rc = obd_connect(&cache_conn, cache, &cache_uuid);
+        if (rc != 0) {
+                obd_disconnect(cobd->cobd_target_exp, 0);
+                return rc;
+        }
+        cobd->cobd_cache_exp = class_conn2export(&cache_conn);
 
- fail_0:
-        obd_disconnect(&cobd->cobd_target, 0);
-        return (rc);
+        return rc;
 }
 
 static int cobd_cleanup(struct obd_device *dev, int flags)
@@ -94,11 +93,11 @@ static int cobd_cleanup(struct obd_device *dev, int flags)
         if (!list_empty(&dev->obd_exports))
                 return (-EBUSY);
 
-        rc = obd_disconnect(&cobd->cobd_cache, flags);
+        rc = obd_disconnect(cobd->cobd_cache_exp, flags);
         if (rc != 0)
                 CERROR ("error %d disconnecting cache\n", rc);
 
-        rc = obd_disconnect(&cobd->cobd_target, flags);
+        rc = obd_disconnect(cobd->cobd_target_exp, flags);
         if (rc != 0)
                 CERROR ("error %d disconnecting target\n", rc);
 
@@ -115,23 +114,23 @@ cobd_connect (struct lustre_handle *conn, struct obd_device *obd,
         return (rc);
 }
 
-static int cobd_disconnect(struct lustre_handle *conn, int flags)
+static int cobd_disconnect(struct obd_export *exp, int flags)
 {
-        int rc = class_disconnect(conn, flags);
+        int rc = class_disconnect(exp, flags);
 
         CERROR ("rc %d\n", rc);
         return (rc);
 }
 
-static int
-cobd_get_info(struct lustre_handle *conn, obd_count keylen,
-              void *key, __u32 *vallen, void *val)
+static int cobd_get_info(struct obd_export *exp, obd_count keylen,
+                         void *key, __u32 *vallen, void *val)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct cache_obd  *cobd;
 
         if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 return -EINVAL;
         }
 
@@ -139,62 +138,30 @@ cobd_get_info(struct lustre_handle *conn, obd_count keylen,
 
         /* intercept cache utilisation info? */
 
-        return obd_get_info(&cobd->cobd_target, keylen, key, vallen, val);
+        return obd_get_info(cobd->cobd_target_exp, keylen, key, vallen, val);
 }
 
 static int cobd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                        unsigned long max_age)
 {
-        return obd_statfs(class_conn2obd(&obd->u.cobd.cobd_target), osfs,
+        return obd_statfs(class_exp2obd(obd->u.cobd.cobd_target_exp), osfs,
                           max_age);
 }
 
-static int cobd_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int cobd_getattr(struct obd_export *exp, struct obdo *oa,
                         struct lov_stripe_md *lsm)
 {
-        struct obd_device *obd = class_conn2obd(conn);
-        struct cache_obd  *cobd;
-
-        if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
-                return -EINVAL;
-        }
-
-        cobd = &obd->u.cobd;
-        return (obd_getattr (&cobd->cobd_target, oa, lsm));
-}
-
-static int
-cobd_open(struct lustre_handle *conn, struct obdo *oa,
-          struct lov_stripe_md *lsm, struct obd_trans_info *oti,
-          struct obd_client_handle *och)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct cache_obd  *cobd;
-
-        if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
-                return -EINVAL;
-        }
-
-        cobd = &obd->u.cobd;
-        return (obd_open (&cobd->cobd_target, oa, lsm, oti, och));
-}
-
-static int
-cobd_close(struct lustre_handle *conn, struct obdo *oa,
-           struct lov_stripe_md *lsm, struct obd_trans_info *oti)
-{
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct cache_obd  *cobd;
 
         if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                        exp->exp_handle.h_cookie);
                 return -EINVAL;
         }
 
         cobd = &obd->u.cobd;
-        return (obd_close (&cobd->cobd_target, oa, lsm, oti));
+        return obd_getattr(cobd->cobd_target_exp, oa, lsm);
 }
 
 static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
@@ -211,10 +178,9 @@ static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
         if ((cmd & OBD_BRW_WRITE) != 0)
                 return -EOPNOTSUPP;
 
-        cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target);
+        cobd_exp = exp->exp_obd->u.cobd.cobd_target_exp;
         rc = obd_preprw(cmd, cobd_exp, oa, objcount, obj, niocount, nb, res,
                         oti);
-        class_export_put(cobd_exp);
 
         return rc;
 }
@@ -233,21 +199,21 @@ static int cobd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
         if ((cmd & OBD_BRW_WRITE) != 0)
                 return -EOPNOTSUPP;
 
-        cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target);
+        cobd_exp = exp->exp_obd->u.cobd.cobd_target_exp;
         rc = obd_commitrw(cmd, cobd_exp, oa, objcount, obj,niocount,local,oti);
-        class_export_put(cobd_exp);
         return rc;
 }
 
-static int cobd_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int cobd_brw(int cmd, struct obd_export *exp, struct obdo *oa,
                     struct lov_stripe_md *lsm, obd_count oa_bufs,
                     struct brw_page *pga, struct obd_trans_info *oti)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct cache_obd  *cobd;
 
         if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 return -EINVAL;
         }
 
@@ -255,24 +221,25 @@ static int cobd_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 return -EOPNOTSUPP;
 
         cobd = &obd->u.cobd;
-        return (obd_brw(cmd, &cobd->cobd_target, oa, lsm, oa_bufs, pga, oti));
+        return obd_brw(cmd, cobd->cobd_target_exp, oa, lsm, oa_bufs, pga, oti);
 }
 
-static int cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
+static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                           void *karg, void *uarg)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct cache_obd  *cobd;
 
         if (obd == NULL) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 return -EINVAL;
         }
 
         /* intercept? */
 
         cobd = &obd->u.cobd;
-        return (obd_iocontrol(cmd, &cobd->cobd_target, len, karg, uarg));
+        return obd_iocontrol(cmd, cobd->cobd_target_exp, len, karg, uarg);
 }
 
 static struct obd_ops cobd_ops = {
@@ -290,8 +257,6 @@ static struct obd_ops cobd_ops = {
         o_statfs:               cobd_statfs,
 
         o_getattr:              cobd_getattr,
-        o_open:                 cobd_open,
-        o_close:                cobd_close,
         o_preprw:               cobd_preprw,
         o_commitrw:             cobd_commitrw,
         o_brw:                  cobd_brw,
@@ -303,7 +268,7 @@ static int __init cobd_init(void)
         struct lprocfs_static_vars lvars;
         ENTRY;
 
-        printk(KERN_INFO "Lustre Caching OBD driver; info@clusterfs.com\n");
+        printk(KERN_INFO "Lustre: Caching OBD driver; info@clusterfs.com\n");
 
         lprocfs_init_vars(cobd, &lvars);
         RETURN(class_register_type(&cobd_ops, lvars.module_vars,
diff --git a/lustre/cobd/lproc_cache.c b/lustre/cobd/lproc_cache.c
index ba9b9cf5a66c78c2c0ceb31fd722afe1f54e810f..8e698ceb2c8440971e9b27900a56d247aa4459e0 100644
--- a/lustre/cobd/lproc_cache.c
+++ b/lustre/cobd/lproc_cache.c
@@ -21,7 +21,7 @@
  */
 #define DEBUG_SUBSYSTEM S_CLASS
 
-#include <linux/lustre_lite.h>
+#include <linux/obd_class.h>
 #include <linux/lprocfs_status.h>
 
 #ifndef LPROCFS
@@ -41,7 +41,7 @@ static int cobd_rd_target(char *page, char **start, off_t off, int count,
                 rc = snprintf(page, count, "not set up\n");
         } else {
                 struct obd_device *tgt =
-                        class_conn2obd(&cobd->u.cobd.cobd_target);
+                        class_exp2obd(cobd->u.cobd.cobd_target_exp);
                 LASSERT(tgt != NULL);
                 rc = snprintf(page, count, "%s\n", tgt->obd_uuid.uuid);
         }
@@ -60,7 +60,7 @@ static int cobd_rd_cache(char *page, char **start, off_t off, int count,
                 rc = snprintf(page, count, "not set up\n");
         } else {
                 struct obd_device *cache =
-                        class_conn2obd(&cobd->u.cobd.cobd_cache);
+                        class_exp2obd(cobd->u.cobd.cobd_cache_exp);
                 LASSERT(cache != NULL);
                 rc = snprintf(page, count, "%s\n", cache->obd_uuid.uuid);
         }
diff --git a/lustre/conf/modules.conf b/lustre/conf/modules.conf
new file mode 100644
index 0000000000000000000000000000000000000000..0fb0a35d1b640996cb08cd5e74d132a6d1eea908
--- /dev/null
+++ b/lustre/conf/modules.conf
@@ -0,0 +1,6 @@
+# sample modules.conf for autoloading lustre modules on zeroconf clients
+
+add below kptlrouter portals
+add below ptlrpc ksocknal
+add below llite lov osc 
+alias lustre llite
diff --git a/lustre/configure.in b/lustre/configure.in
index 50f82c8e0e60130b80894ff3121b11a045f70d34..3d2fd249f86330ec10be05b6f7034d3e895e8ba5 100644
--- a/lustre/configure.in
+++ b/lustre/configure.in
@@ -26,9 +26,18 @@ if test x$enable_orphans = xyes ; then
   AC_DEFINE(ENABLE_ORPHANS, 1, Compile with orphan support)
 fi
 
-AC_ARG_WITH(obd-buffer-size, [  --with-obd-buffer-size=[size] set lctl ioctl maximum (default=8K)],OBD_BUFFER_SIZE=$with_obd_buffer_size,OBD_BUFFER_SIZE=8192)
+AC_ARG_WITH(obd-buffer-size, [  --with-obd-buffer-size=[size] set lctl ioctl maximum bytes (default=8192)],OBD_BUFFER_SIZE=$with_obd_buffer_size,OBD_BUFFER_SIZE=8192)
 AC_DEFINE_UNQUOTED(OBD_MAX_IOCTL_BUFFER, $OBD_BUFFER_SIZE, [IOCTL Buffer Size])
 
+# specify location of libsysio tree
+AC_ARG_WITH(sysio, [  --with-sysio=[path] set path to libsysio source (default=../libsysio)], sysiodir=$withval)
+if test x$sysiodir = x; then
+	SYSIO='$(top_srcdir)/../libsysio'
+else
+	SYSIO=$sysiodir
+fi
+AC_SUBST(SYSIO)
+
 sinclude(portals/build.m4)
 sinclude(portals/archdep.m4)
 
@@ -39,16 +48,17 @@ fi
 
 AM_CONFIG_HEADER(portals/include/config.h)
 
-AC_OUTPUT([Makefile portals/Makefile portals/Kernelenv \
+AC_OUTPUT([Makefile lvfs/Makefile portals/Makefile portals/Kernelenv \
           portals/libcfs/Makefile portals/portals/Makefile \
           portals/unals/Makefile portals/knals/Makefile \
           portals/router/Makefile portals/knals/socknal/Makefile \
           portals/knals/gmnal/Makefile portals/knals/qswnal/Makefile \
 	  portals/knals/scimacnal/Makefile portals/knals/toenal/Makefile \
+	  portals/knals/ibnal/Makefile \
           portals/utils/Makefile portals/tests/Makefile portals/doc/Makefile \
-          ldlm/Makefile obdecho/Makefile ptlrpc/Makefile liblustre/Makefile \
+          obdecho/Makefile ptlrpc/Makefile liblustre/Makefile \
 	  lov/Makefile osc/Makefile mdc/Makefile mds/Makefile ost/Makefile \
 	  cobd/Makefile ptlbd/Makefile conf/Makefile  tests/Makefile \
 	  utils/Makefile utils/Lustre/Makefile obdfilter/Makefile \
-          obdclass/Makefile llite/Makefile doc/Makefile scripts/Makefile \
+          obdclass/Makefile include/Makefile include/linux/Makefile llite/Makefile doc/Makefile scripts/Makefile \
 	  scripts/lustre.spec])
diff --git a/lustre/doc/lconf.8 b/lustre/doc/lconf.8
new file mode 100644
index 0000000000000000000000000000000000000000..aa16c346c1106cc63ad1163bb3f79ad8e2795b34
--- /dev/null
+++ b/lustre/doc/lconf.8
@@ -0,0 +1,126 @@
+.TH lconf 1 "2003 Oct 8" Lustre "configuration utilities"
+.SH NAME
+lconf \- Lustre filesystem configuration utility
+.SH SYNOPSIS
+.br
+.B lconf
+[--node <node_name>] [-d,--cleanup] [--noexec] [--gdb] [--nosetup] [--nomod] [-n,--noexec] [-v,--verbose] [-h,--help] <XML-config file>
+[options] --add <objecttype> [args]
+.br
+.SH DESCRIPTION
+.B lconf
+, when invoked configures a node following directives in the <XML-config-file>. There will be single configuration file for all the nodes in a single cluster. This file should be distributed to all the nodes in the cluster or kept in a location accessible to all the nodes. One option is to store the cluster configuration information in LDAP format on an LDAP server that can be reached from all the cluster nodes.
+.PP
+The arguments that can be used for lconf are:
+.PP
+.TP
+--config <arg> 
+Cluster configuration name used for LDAP query
+.TP
+--d|--cleanup 
+Unconfigure a node. The same config and --node argument used for configuration needs to be used for cleanup as well. This will attempt to undo all of the configuration steps done by lconf, including unloading the kernel modules.
+.TP
+--dump <file> 
+Dump the kernel debug log to the specified file before portals is unloaded during cleanup.
+.TP
+--dump_path <arg> 
+Path to save debug dumps. Default is /tmp/lustre_log
+.TP
+--failover 
+Used to shutdown without saving state. Default is 0. This will allow the node to give up service to another node for failover purposes. This will not be a clean shutdown.
+.TP
+--force 
+Forced unmounting and/or obd detach during cleanup. Default is 0. 
+.TP
+--gdb 
+Causes lconf to print a message and pause for 5 seconds after creating a gdb module script and before doing any Lustre configuration (the gdb module script is always created, however).
+.TP
+--gdb_script <arg> 
+Full name of gdb debug script. Default is /tmp/ogdb.
+.TP
+--group <arg> 
+The group of devices to cleanup/configure.
+.TP
+-h,--help 
+Print help.
+.TP
+--inactive <UUID> 
+The UUID of the service to be ignored by a client mounting Lustre. Allows the client to mount in the presence of some inactive services. (currently OST only). Multiple UUIDs can be specified by repeating the option. 
+.TP
+--lctl-dump <arg> 
+Dump all ioctls to the specified file
+.TP
+--ldapurl <arg> 
+LDAP server URL 
+.TP
+--lustre_upcall <path> 
+Set the location of the Lustre upcall scripts used by the client for recovery
+.TP
+--lustre=src_dir 
+Specify the base directory for Lustre sources, this parameter will cause lconf to load the lustre modules from this soure tree.
+.TP
+--mds_ost_conn 
+Open connections to OSTs on MDS.
+.TP
+--maxlevel <level> 
+Perform configuration of devices and services up to level given. level can take the values net, dev, svc, fs. When used in conjunction with cleanup, services are torn down up to a certain level. Default is 100.
+.TP
+--minlevel <level> 
+Specify the minimum level of services to configure/cleanup. Default is 0.
+.TP
+--node node_name 
+Specify a specific node to configure. By default, lconf will search for nodes with the local hostname and 'localhost'. When --node is used, only node_name is searched for. If a matching node is not found in the config, then lconf exits with an error.
+.TP
+--noexec,-n 
+Print, but don't execute, the steps lconf will perform. This is useful for debugging a configuration, and when used with --node, can be run on any host.
+.TP
+--nomod 
+Only setup devices and services, do not load modules.
+.TP
+--nosetup 
+Only load modules, do not configure devices or services.
+.TP
+--portals_upcall <path> 
+Specify the location of the Portals upcall scripts used by the client for recovery
+.TP
+--ptldebug debug-level 
+This options can be used to set the required debug level.
+.TP
+--recover <arg> 
+Recover a device.
+.TP
+--reformat 
+Reformat all the devices. This is essential on the first time the file system is brought up.
+.TP
+--select <arg> 
+Select a particular node for a service 
+.TP
+--subsystem <arg> 
+Set the portals debug subsystem.
+.TP
+--timeout <arg> 
+Set the recovery timeout period.
+.TP
+--upcall <path> 
+Set the location of both Lustre and Portals upcall scripts used by the client for recovery
+.TP
+--verbose,-v 
+Be verbose and show actions while going along.
+.TP
+--write_conf 
+Save all client configuration information on the MDS
+.SH EXAMPLES
+.TP
+.B lconf --node client config.xml
+This invokes lconf on the client node.
+.TP
+.B lconf --ptldebug "~(portals | malloc | trace)"
+Used to set the required debug levels (all but these).
+.TP
+.B lconf --ptldebug "ldlm|ha"
+Used to turn-on specific debug types.
+.TP
+.B lconf --inactive OST_ost1_UUID --inactive OST_ost2_UUID config.xml
+A subset of failed OSTs can be ignored during Lustre mount on the clients by using this option. Here OST1 and OST2 have failed and need to be ignored.
+.SH BUGS
+None are known.
diff --git a/lustre/doc/lconf.lyx b/lustre/doc/lconf.lyx
index 0b1416f6b0e4b8894042c24fa2c1f2713dfe83dc..1c6d8788b42c156c8d4e32185e0d9f0c2e52b088 100644
--- a/lustre/doc/lconf.lyx
+++ b/lustre/doc/lconf.lyx
@@ -1,5 +1,5 @@
-#LyX 1.2 created this file. For more info see http://www.lyx.org/
-\lyxformat 220
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
 \textclass amsart
 \language english
 \inputencoding auto
@@ -56,34 +56,10 @@ This program configures a node following directives in the <XML-config-file>.
  on an LDAP server that can be reached from all the cluster nodes.
 \layout Description
 
---ldapurl\SpecialChar ~
-<arg> LDAP server URL 
-\layout Description
-
 --config\SpecialChar ~
 <arg> Cluster configuration name used for LDAP query
 \layout Description
 
---select\SpecialChar ~
-<arg> Select a particular node for a service 
-\layout Description
-
---node\SpecialChar ~
-node_name Specify a specific node to configure.
- By default, lconf will search for nodes with the local hostname and 'localhost'.
- When
-\emph on 
- --node
-\emph default 
- is used, only 
-\emph on 
-node_name
-\emph default 
- is searched for.
- If a matching node is not found in the config, then lconf exits with an
- error.
-\layout Description
-
 --d|--cleanup Unconfigure a node.
  The same config and 
 \emph on 
@@ -94,12 +70,14 @@ node_name
  including unloading the kernel modules.
 \layout Description
 
---force Forced unmounting and/or obd detach during cleanup.
- Default is 0.
- 
+--dump\SpecialChar ~
+<file> Dump the kernel debug log to the specified file before portals
+ is unloaded during cleanup.
 \layout Description
 
---mds_ost_conn Open connections to OSTs on MDS.
+--dump_path\SpecialChar ~
+<arg> Path to save debug dumps.
+ Default is /tmp/lustre_log
 \layout Description
 
 --failover Used to shutdown without saving state.
@@ -109,12 +87,9 @@ node_name
  This will not be a clean shutdown.
 \layout Description
 
---noexec Print, but don't execute, the steps lconf will perform.
- This is useful for debugging a configuration, and when used with 
-\emph on 
---node
-\emph default 
-, can be run on any host.
+--force Forced unmounting and/or obd detach during cleanup.
+ Default is 0.
+ 
 \layout Description
 
 --gdb Causes lconf to print a message and pause for 5 seconds after creating
@@ -127,34 +102,28 @@ node_name
  Default is /tmp/ogdb.
 \layout Description
 
---dump_path\SpecialChar ~
-<arg> Path to save debug dumps.
- Default is /tmp/lustre_log
-\layout Description
-
---recover\SpecialChar ~
-<arg> Recover a device.
-\layout Description
-
---nosetup Only load modules, do not configure devices or services.
-\layout Description
-
 --group\SpecialChar ~
 <arg> The group of devices to cleanup/configure.
 \layout Description
 
---nomod Only setup devices and services, do not load modules.
+-h,--help Print help.
 \layout Description
 
---noexec,-n Don't do anything, but print what would happen.
- Useful for debugging purposes.
+--inactive\SpecialChar ~
+<UUID> The UUID of the service to be ignored by a client mounting
+ Lustre.
+ Allows the client to mount in the presence of some inactive services.
+ (currently OST only).
+ Multiple UUIDs can be specified by repeating the option.
+ 
 \layout Description
 
---verbose,-v Be verbose and show actions while going along.
+--lctl-dump\SpecialChar ~
+<arg> Dump all ioctls to the specified file
 \layout Description
 
---timeout\SpecialChar ~
-<arg> Set the recovery timeout period.
+--ldapurl\SpecialChar ~
+<arg> LDAP server URL 
 \layout Description
 
 --lustre_upcall\SpecialChar ~
@@ -162,30 +131,11 @@ node_name
  by the client for recovery
 \layout Description
 
---portals_upcall\SpecialChar ~
-<path> Specify the location of the Portals upcall scripts
- used by the client for recovery
-\layout Description
-
---upcall\SpecialChar ~
-<path> Set the location of both Lustre and Portals upcall scripts
- used by the client for recovery
-\layout Description
-
---lctl-dump\SpecialChar ~
-<arg> Dump all ioctls to the specified file
-\layout Description
-
---dump\SpecialChar ~
-<file> Dump the kernel debug log to the specified file before portals
- is unloaded during cleanup.
-\layout Description
-
---reformat Reformat all the devices.
- This is essential on the first time the file system is brought up.
+--lustre=src_dir Specify the base directory for Lustre sources, this parameter
+ will cause lconf to load the lustre modules from this soure tree.
 \layout Description
 
--h,--help Print help.
+--mds_ost_conn Open connections to OSTs on MDS.
 \layout Description
 
 --maxlevel\SpecialChar ~
@@ -210,8 +160,39 @@ When used in conjunction with cleanup, services are torn down up to a certain
  Default is 0.
 \layout Description
 
---lustre=src_dir Specify the base directory for Lustre sources, this parameter
- will cause lconf to load the lustre modules from this soure tree.
+--node\SpecialChar ~
+node_name Specify a specific node to configure.
+ By default, lconf will search for nodes with the local hostname and 'localhost'.
+ When
+\emph on 
+ --node
+\emph default 
+ is used, only 
+\emph on 
+node_name
+\emph default 
+ is searched for.
+ If a matching node is not found in the config, then lconf exits with an
+ error.
+\layout Description
+
+--noexec,-n Print, but don't execute, the steps lconf will perform.
+ This is useful for debugging a configuration, and when used with 
+\emph on 
+--node
+\emph default 
+, can be run on any host.
+\layout Description
+
+--nomod Only setup devices and services, do not load modules.
+\layout Description
+
+--nosetup Only load modules, do not configure devices or services.
+\layout Description
+
+--portals_upcall\SpecialChar ~
+<path> Specify the location of the Portals upcall scripts
+ used by the client for recovery
 \layout Description
 
 --ptldebug\SpecialChar ~
@@ -220,8 +201,35 @@ level This options can be used to set the required debug
  level.
 \layout Description
 
+--recover\SpecialChar ~
+<arg> Recover a device.
+\layout Description
+
+--reformat Reformat all the devices.
+ This is essential on the first time the file system is brought up.
+\layout Description
+
+--select\SpecialChar ~
+<arg> Select a particular node for a service 
+\layout Description
+
 --subsystem\SpecialChar ~
 <arg> Set the portals debug subsystem.
+\layout Description
+
+--timeout\SpecialChar ~
+<arg> Set the recovery timeout period.
+\layout Description
+
+--upcall\SpecialChar ~
+<path> Set the location of both Lustre and Portals upcall scripts
+ used by the client for recovery
+\layout Description
+
+--verbose,-v Be verbose and show actions while going along.
+\layout Description
+
+--write_conf Save all client configuration information on the MDS
 \layout Subsection
 
 EXAMPLES
@@ -277,6 +285,16 @@ ldlm|ha
 \end_inset 
 
 
+\layout Standard
+
+A subset of failed OSTs can be ignored during Lustre mount on the clients
+ by using the following option:
+\layout LyX-Code
+
+   lconf --inactive OST_ost1_UUID --inactive OST_ost2_UUID config.xml
+\layout Standard
+
+where OST1 and OST2 have failed and need to be ignored.
 \layout Subsection
 
 BUGS
diff --git a/lustre/doc/lctl.8 b/lustre/doc/lctl.8
new file mode 100644
index 0000000000000000000000000000000000000000..1e112dd58bfa2448a709217cf136260e2ee917fc
--- /dev/null
+++ b/lustre/doc/lctl.8
@@ -0,0 +1,307 @@
+.TH lctl 1 "2003 Oct 8" Lustre "configuration utilities"
+.SH NAME
+lctl \- Low level Lustre filesystem configuration utility
+.SH SYNOPSIS
+.br
+.B lctl
+.br
+.B lctl --device <devno> <command [args]>
+.br
+.B lctl --threads <numthreads> <verbose> <devno> <command [args]>
+.br
+.SH DESCRIPTION
+.B lctl
+can be invoked in interactive mode by issuing lctl command. After that, commands are issued as below. The most common commands in lctl are (in matching pairs) 
+.B device 
+and 
+.B attach
+, 
+.B detach 
+and 
+.B setup
+,
+.B cleanup 
+and
+.B connect
+,
+.B disconnect 
+and
+.B help
+, and
+.B quit.
+
+To get a complete listing of available commands, type help at the lctl prompt.  To get basic help on the meaning and syntax of a command, type help command.  Command completion is activated with the TAB key, and command history is available via the up- and down-arrow keys. 
+
+For non-interactive single-threaded use, one uses the second invocation, which runs command after connecting to the device. 
+
+.B Network Configuration
+.TP 
+network <tcp/elans/myrinet> 
+Indicate what kind of network applies for the configuration commands that follow.
+.TP 
+connect [[<hostname> <port>] | <elan id>] 
+This will establish a connection to a remote network network id given by the hostname/port combination, or the elan id.
+.TP 
+disconnect <nid> 
+Disconnect from a remote nid.
+.TP 
+mynid [nid] 
+Informs the socknal of the local nid. It defaults to hostname for tcp networks and is automatically setup for elan/myrinet networks.
+.TP 
+add_uuid <uuid> <nid> 
+Associate a given UUID with an nid.
+.TP 
+close_uuid <uuid> 
+Disconnect a UUID.
+.TP 
+del_uuid <uuid> 
+Delete a UUID association.
+.TP 
+add_route <gateway> <target> [target] 
+Add an entry to the routing table for the given target.
+.TP 
+del_route <target> 
+Delete an entry for the target from the routing table.
+.TP 
+route_list 
+Print the complete routing table.
+.TP 
+recv_mem [size] 
+Set the socket receive buffer size; if the size is omitted, the default size for the buffer is printed.
+.TP 
+send_mem [size] 
+Set send buffer size for the socket; if size is omitted, the default size for the buffer is printed.
+.TP 
+nagle [on/off] 
+Enable/disable nagle; omitting the argument will cause the default value to be printed.
+.TP 
+fail nid|all [count] 
+Fail/restore communications. Ommiting tha count implies fail indefinitely, count of zero indicates that communication should be restored. A non-zero count indicates the number of portals messages to be dropped after which the communication is restored.
+.PP
+.B Device Selection
+.TP 
+newdev 
+Create a new device.
+.TP 
+name2dev 
+This command can be used to determine a device number for the given device name.
+.TP 
+device 
+This will select the specified OBD device.  All other commands depend on the device being set. 
+.TP 
+device_list 
+Show all the devices.
+.TP 
+lustre_build_version 
+Print the Lustre build version.
+.PP
+.B Device Configuration
+.TP 
+attach type [name [uuid]] 
+Attach a type to the current device (which you need to set using the device command) and give that device a name and UUID.  This allows us to identify the device for use later, and also tells us what type of device we will have.
+.TP 
+setup <args...> 
+Type specific device setup commands. For obdfilter, a setup command tells the driver which block device it should use for storage and what type of filesystem is on that device. 
+.TP 
+cleanup 
+Cleanup a previously setup device.
+.TP 
+detach 
+Remove driver (and name and UUID) from the current device.
+.TP 
+lov_setconfig lov-uuid stripe-count default-stripe-size offset pattern UUID1 [UUID2...] 
+Write LOV configuration to an MDS device.
+.TP 
+lov_getconfig lov-uuid 
+Read LOV configuration from an MDS device. Returns default-stripe-count, default-stripe-size, offset, pattern, and a list of OST UUID's.
+.PP
+.B Device Operations
+.TP 
+probe [timeout] 
+Build a connection handle to a device. This command is used to suspend configuration until the lctl command has ensured that the MDS and OSC services are available. This is to avoid mount failures in a rebooting cluster.
+.TP 
+close 
+Close the connection handle
+.TP 
+getattr <objid> 
+Get attributes for an OST object <objid> .
+.TP 
+setattr <objid> <mode> 
+Set mode attribute for OST object <objid>.
+.TP 
+create [num [mode [verbose]]] 
+Create the specified number <num> of OST objects with the given <mode>.
+.TP 
+destroy <num> 
+Starting at <objid>, destroy <num> number of objects starting from the object with object id <objid>.
+.TP 
+test_getattr <num> [verbose [[t]objid]] 
+Do <num> getattrs on OST object <objid> (objectid+1 on each thread).
+.TP 
+test_brw [t]<num> [write [verbose [npages [[t]objid]]]] 
+Do <num> bulk read/writes on OST object <objid> (<npages> per I/O).
+.TP 
+test_ldlm 
+Perform lock manager test.
+.TP 
+ldlm_regress_start %s [numthreads [refheld [numres [numext]]]] 
+Start lock manager stress test.
+.TP 
+ldlm_regress_stop 
+Stop lock manager stress test.
+.TP 
+dump_ldlm 
+Dump all lock manager state, this is very useful for debugging
+.TP 
+activate 
+Activate an import
+.TP 
+deacttivate 
+De-activate an import
+.TP 
+recover <connection UUID> 
+.TP 
+lookup <directory> <file>
+.TP 
+notransno 
+Disable sending of committed transnumber updates
+.TP 
+readonly 
+Disable writes to the underlying device
+.TP 
+abort_recovery 
+Abort recovery on MDS device
+.TP 
+mount_option 
+Dump mount options to a file
+.TP 
+get_stripe 
+Show stripe info for an echo client object.
+.TP 
+set_stripe <objid>[ width!count[@offset] [:id:id....] 
+Set stripe info for an echo client
+.TP 
+unset_stripe <objid> 
+Unset stripe info for an echo client object.
+.PP
+.B Debug
+.TP 
+debug_daemon 
+Debug daemon control and dump to a file
+.TP 
+debug_kernel [file] [raw] 
+Get debug buffer and dump to a fileusage.
+.TP 
+debug_file <input> [output] [raw] 
+Read debug buffer from input and dump to outputusage.
+.TP 
+clear 
+Clear kernel debug buffer.
+.TP 
+mark <text> 
+Insert marker text in kernel debug buffer.
+.TP 
+filter <subsystem id/debug mask> 
+Filter message type from the kernel debug buffer.
+.TP 
+show <subsystem id/debug mask> 
+Show specific type of messages.
+.TP 
+debug_list <subs/types> 
+List all the subsystem and debug types.
+.TP 
+panic 
+Force the kernel to panic.
+.PP
+.B Control
+.TP 
+help 
+Show a complete list of commands; help <command name> can be used to get help on specific command.
+.TP 
+exit 
+Close the lctl session.
+.TP 
+quit 
+Close the lctl session.
+
+.SH OPTIONS
+The following options can be used to invoke lctl. 
+.TP
+.B --device 
+The device number to be used for the operation. The value of devno is an integer, normally found by calling lctl name2dev on a device name. 
+.TP
+.B --threads 
+How many threads should be forked doing the command specified. The numthreads variable is a strictly positive integer indicating how many threads should be started. The devno option is used as above.
+.TP
+.B --ignore_errors | ignore_errors 
+Ignore errors during script processing
+.TP
+.B dump 
+Save ioctls to a file 
+.SH EXAMPLES
+.B attach
+
+# lctl
+.br
+lctl > newdev
+.br
+lctl > attach obdfilter OBDDEV OBDUUID
+
+.B connect
+
+lctl > name2dev OSCDEV 2 
+.br
+lctl > device 2
+.br
+lctl > connect
+
+.B getattr
+
+lctl > getattr 12
+.br
+id: 12
+.br
+grp: 0
+.br
+atime: 1002663714
+.br
+mtime: 1002663535
+.br
+ctime: 1002663535
+.br
+size: 10
+.br
+blocks: 8
+.br
+blksize: 4096
+.br
+mode: 100644
+.br
+uid: 0
+.br
+gid: 0
+.br
+flags: 0
+.br
+obdflags: 0
+.br
+nlink: 1
+.br
+valid: ffffffff
+.br
+inline:
+.br
+obdmd:
+.br
+lctl > disconnect 
+.br
+Finished (success)
+
+.B setup 
+
+lctl > setup /dev/loop0 extN
+.br
+lctl > quit
+
+.SH BUGS
+None are known.
diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1
new file mode 100644
index 0000000000000000000000000000000000000000..5e676f20bc91e9316631adda2bebc3e80d14ae8e
--- /dev/null
+++ b/lustre/doc/lfs.1
@@ -0,0 +1,53 @@
+.TH lfs 1 "2003 Oct 29" Lustre "configuration utilities"
+.SH NAME
+lfs \- Lustre utility to create a file with specific striping pattern, find the striping pattern of exiting files
+.SH SYNOPSIS
+.br
+.B lfs
+.br
+.B lfs find [--obd <uuid>] [--quiet | --verbose] [--recursive] <dir|file>
+.br
+.B lfs getstripe <file-name> 
+.br
+.B lfs setstripe <filename> <stripe-size> <start-ost> <stripe-cnt>
+.SH DESCRIPTION
+.B lfs
+can be used to create a new file with a specific striping pattern, determine the default striping pattern, gather the extended attributes (object numbers and 
+location) for a specific file. It can be invoked interactively without any 
+arguments or in a non-interactive mode with one of the arguements supported. 
+.SH OPTIONS
+The various options supported by lctl are listed and explained below:
+.TP
+.B setstripe 
+To create a new file with a specific striping pattern
+.TP
+.B find 
+To list the extended attributes for a given filename or files in a directory or recursively for all files in a directory tree. It can also be used to list the files that have objects on a specific OST. 
+.TP
+.B getstripe 
+To list the striping pattern for given filename
+.TP
+.B help 
+Provides brief help on the various arguments
+.TP
+.B exit/quit 
+Quit the interactive lfs session
+
+.SH EXAMPLES
+.TP
+.B $lfs setstripe /mnt/lustre/file1 131072 0 1
+This creats a file striped on one OST
+.TP
+.B $lfs find /mnt/lustre/file1
+Lists the extended attributes of a given file
+.TP
+.B $lfs find /mnt/lustre/
+Lists the extended attributes of all files in a given directory
+.TP
+.B $lfs find -r /mnt/lustre/
+Recursively list the extended attributes of all files in a given directory tree
+.TP
+.B $lfs find -r --obd OST2-UUID /mnt/lustre/
+List all the files that have objects on a specific OST
+.SH BUGS
+None are known.
diff --git a/lustre/doc/lfs.lyx b/lustre/doc/lfs.lyx
new file mode 100644
index 0000000000000000000000000000000000000000..b8568da2cc103901744345a8513365ebf8403421
--- /dev/null
+++ b/lustre/doc/lfs.lyx
@@ -0,0 +1,229 @@
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
+\textclass amsart
+\language english
+\inputencoding auto
+\fontscheme times
+\graphics default
+\paperfontsize default
+\spacing single 
+\papersize letterpaper
+\paperpackage a4
+\use_geometry 0
+\use_amsmath 0
+\use_natbib 0
+\use_numerical_citations 0
+\paperorientation portrait
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation skip
+\defskip medskip
+\quotes_language english
+\quotes_times 2
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+
+\layout Section
+
+LFS
+\layout Subsection
+
+NAME
+\layout Description
+
+lfs Lustre utility to create a file with specific striping pattern
+\layout Subsection
+
+SYNOPSIS
+\layout Standard
+
+
+\series bold 
+lfs
+\layout Standard
+
+
+\series bold 
+lfs\SpecialChar ~
+find [--obd <uuid>] [--quiet | --verbose] [--recursive] <dir|file>
+\layout Standard
+
+
+\series bold 
+lfs\SpecialChar ~
+getstripe <file_name> 
+\layout Standard
+
+
+\series bold 
+lfs\SpecialChar ~
+setstripe <filename> <stripe_size> <start_ost> <stripe_cnt>
+\layout Subsection
+
+DESCRIPTION
+\layout Standard
+
+This utility can be used to create a new file with a specific striping pattern,
+ determine the default striping pattern, gather the extended attributes
+ (object numbers and location) for a specific file.
+ It can be invoked interactively without any arguments or in a non-interactive
+ mode with one of the arguements listed and explained below:
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+setstripe
+\series default 
+ To create a new file with a specific striping pattern
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+find
+\series default 
+ To list the extended attributes for a given filename or files in a directory
+ or recursively for all files in a directory tree.
+ It can also be used to list the files that have objects on a specific OST.
+ 
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+getstripe
+\series default 
+ To list the striping pattern for given filename
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+help
+\series default 
+ Provides brief help on the various arguments
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+exit/quit
+\series default 
+ Quit the interactive lfs session
+\layout Subsection
+
+EXAMPLES
+\layout Description
+
+Creating\SpecialChar ~
+a\SpecialChar ~
+file\SpecialChar ~
+striped\SpecialChar ~
+on\SpecialChar ~
+one\SpecialChar ~
+OST
+\layout LyX-Code
+
+   $lfs setstripe /mnt/lustre/file1 131072 0 1
+\layout Description
+
+Listing
+\series bold 
+\SpecialChar ~
+
+\series default 
+the
+\series bold 
+\SpecialChar ~
+
+\series default 
+extended
+\series bold 
+\SpecialChar ~
+
+\series default 
+attributes
+\series bold 
+\SpecialChar ~
+
+\series default 
+of
+\series bold 
+\SpecialChar ~
+
+\series default 
+a
+\series bold 
+\SpecialChar ~
+
+\series default 
+given
+\series bold 
+\SpecialChar ~
+
+\series default 
+file
+\layout LyX-Code
+
+   $lfs find /mnt/lustre/file1
+\layout Description
+
+Listing\SpecialChar ~
+the\SpecialChar ~
+extended\SpecialChar ~
+attributes\SpecialChar ~
+of\SpecialChar ~
+all\SpecialChar ~
+files\SpecialChar ~
+in\SpecialChar ~
+a\SpecialChar ~
+given\SpecialChar ~
+directory
+\layout LyX-Code
+
+   $lfs find /mnt/lustre/
+\layout Description
+
+Recursively\SpecialChar ~
+list\SpecialChar ~
+the\SpecialChar ~
+extended\SpecialChar ~
+attributes\SpecialChar ~
+of\SpecialChar ~
+all\SpecialChar ~
+files\SpecialChar ~
+in\SpecialChar ~
+a\SpecialChar ~
+given\SpecialChar ~
+directory\SpecialChar ~
+tree
+\layout LyX-Code
+
+   $lfs find -r /mnt/lustre/
+\layout Description
+
+List\SpecialChar ~
+all\SpecialChar ~
+the\SpecialChar ~
+files\SpecialChar ~
+that\SpecialChar ~
+have\SpecialChar ~
+objects\SpecialChar ~
+on\SpecialChar ~
+a\SpecialChar ~
+specific\SpecialChar ~
+OST
+\layout LyX-Code
+
+   $lfs find -r --obd OST2_UUID /mnt/lustre/
+\layout LyX-Code
+
+\layout Subsection
+
+BUGS
+\layout Standard
+
+None are known.
+\the_end
diff --git a/lustre/doc/lmc.1 b/lustre/doc/lmc.1
new file mode 100644
index 0000000000000000000000000000000000000000..c3345e814e89535cd266338398c7329ce65a85c4
--- /dev/null
+++ b/lustre/doc/lmc.1
@@ -0,0 +1,207 @@
+.TH lmc 1 "2003 Oct 8" Lustre "configuration utilities"
+.SH NAME
+lmc \- Lustre configuration maker
+.SH SYNOPSIS
+.br
+.B lmc
+[options] --add <objecttype> [args]
+.br
+.SH DESCRIPTION
+.B lmc 
+, when invoked, adds configuration data to a configuration file. In future, 
+lmc will also be able to remove configuration data or convert its format. 
+A Lustre cluster consists of several components - MDSs, client mount-points, 
+OSTs, LOVs and networks. A single configuration file would be generated for the complete cluster. In the lmc command line interface, each of these components is associated with an objecttype.
+.PP
+The objecttype refers to a collection of related configuration entities and can be one of 
+.B net
+,
+.B MDS
+,
+.B LOV
+,
+.B OST
+,
+.B mtpt
+,
+.B route
+or
+.B echo-client.
+.PP
+We describe the arguments required for the addition of each objecttype. 
+.PP
+To generate configuration data associated with systems in a Lustre cluster:
+.PP
+.B --add node 
+Adds a new node in the cluster configuration.
+The arguements required are:
+.TP 
+--node <node_name>
+This will create a new node with the given name if not already present.
+.TP
+--timeout <num>
+Timeout before going into recovery
+.TP
+--lustre_upcall <path> 
+Set the location of the Lustre upcall scripts used by the client for recovery
+.TP
+--portals_upcall <path> 
+Specify the location of the Portals upcall scripts used by the client for recovery
+.TP
+--upcall <path> 
+Specify the location of both (Lustre and Portals) upcall scripts used by the client for recovery
+.PP
+.B --add net 
+Adds a network device descriptor for the given node, with parameters as indicated.
+The arguments required are:
+.TP 12
+--node <node_name>
+This will create a new node with the given name if not already present. This is also used to specify a specific node for other elements.
+.TP
+--nettype <type> 
+This can be tcp, elan, gm, scimac.
+.TP
+--nid nid 
+The network id, e.g. ElanID or IP address as used by Portals. If nid is '*', then the local address of the interface with specified nettype is will be substituted when the node is configured with lconf. An nid of '*' should be used only for the generic client configuration.
+.TP
+--hostaddr addr
+.TP
+--router 
+Optional flag to mark this node as a router
+.TP
+--port [port] 
+Optional arguement to indicate the tcp port. The default is 988. 
+.TP
+--tcpbuf <size> 
+Optional arguement. The default TCP buffer size is 1MB.
+.TP
+--irq_affinity 0|1 
+Optional arguement. Default is 0.
+.TP
+--nid_exchange 0|1 
+Optional arguement since some OSTs might not have the required support. This is turned off by default, value of 1 will turn it ON. 
+.PP
+.B --add mds
+Specify the MDS configuration
+.TP
+--node <node name> 
+Name of the node on which the MDS resides
+.TP
+--mds <mds_name> 
+Common name of the MDS
+.TP 
+--dev <pathname> 
+Path of device on local system. If the is a file, then a loop device is created and used as the block device.
+.TP
+--size <size> 
+Optional argument indicating the size (in KB) of the device to be created (used typically for loop devices).
+.TP
+--node <nodename> 
+Adds an MDS to the specified node. This requires a --node argument, and it must not be a profile node.
+.TP
+--fstype extN|ext3 
+Optional argument used to specify the file system type. Default is ext3.
+.TP
+--journal_size <size> 
+Optional arguement to specify the journal size for the ext2/ext3 file system. The size should be in the units expected by mkfs, so for ext3 it should be in MB. If this is option is not used, the ext2/ext3 filesystem will be configured with the default journal size.
+.PP
+.B --add lov 
+Creates an LOV with the specified parameters. The mds_name must already exist in the descriptor.
+.TP
+--lov <name>
+Common name for the LOV
+.TP
+--mds <name>
+Common name for the MDS
+.TP
+--stripe_sz <size>
+Stripe size
+.TP
+--stripe_cnt <count> 
+A value of 0 for this means to stripe on all available OSTs. Default is 0.
+.TP
+--stripe_pattern <pattern> 
+Only Pattern 0 (RAID 0) is supported currently.
+.PP
+.B --add ost 
+Creates an OBD, OST, and OSC. The OST and OBD are created on the specified node.
+.TP
+--ost <name> 
+Assign a name to the OST device.
+.TP
+--node <nodename> 
+Node on which the OST service is run, can not be a profile node.
+.TP
+--dev <pathname> 
+Path of device on local system. If this is a file, then a loop device is created and used as the block device.
+.TP
+--size [size] 
+Optional argument indicating the size (in KB) of the device to be created (used typically for loop devices).
+.TP
+--obdtype 
+obdfilter|obdecho 
+.TP
+--lov <name> 
+Optional arguement. Name of LOV to which this OSC will be attached. 
+.TP
+--ostuuid UUID 
+Specify the UUID of the OST device. 
+.TP
+--fstype 
+extN|ext3 Optional arguement used to specify the file system type. Default is ext3.
+.TP
+--journal_size <size> 
+Optional arguement to specify the journal size for the ext2/ext3 file system. The size should be in the units expected by mkfs, so for ext3 it should be in MB. If this is option is not used, the ext2/ext3 filesystem will be configured with the default journal size.
+.PP
+.B --add mtpt 
+Creates a mount-point on the specified node. Either an LOV or OSC name can be used.
+.TP
+--node node 
+Node that will use the mtpt.
+.TP
+--path /mnt/path 
+The mount-point to use to mount Lustre filesystem
+.TP
+--mds mds_name 
+MDS name
+.TP
+--ost ost_name | --lov lov_name
+OST or LOV name as specified earlier in the configuration
+.PP
+.B --add route 
+Creates a static route through a gateway to a specific nid or a range of nid's.
+.TP
+--node node 
+Node to add the route to.
+.TP
+--gw nid 
+The nid of the gateway (must be a local interface or a peer).
+.TP
+--tgt nid 
+For a specific route, this is the target nid.
+.TP
+--lo nid 
+For a range route, this is the lo value nid.
+.TP
+--hi nid 
+For a range route, this is the hi value nid.
+.PP
+.B --add echo-client 
+Used for testing purpose only. 
+.TP
+--node node 
+Name of the node that echo client should run on,
+.TP
+--obd obd_name 
+.SH OPTIONS
+One of the following options should be specified.
+.TP 12
+--output filename 
+Send output to the file. If the file exists, it will be overwritten.
+.TP
+--merge filename 
+Add the new element to an existing file. 
+.SH EXAMPLES
+Real life examples are given in the Lustre-conf manual page.
+.SH BUGS
+None are known.
diff --git a/lustre/doc/lmc.lyx b/lustre/doc/lmc.lyx
index 7a9002359ad2d37557cb4a0e80771868c7bd5307..fb14d0ec2c0d476ab5e65b4f75a1a75a69b6f5ce 100644
--- a/lustre/doc/lmc.lyx
+++ b/lustre/doc/lmc.lyx
@@ -1,5 +1,5 @@
-#LyX 1.2 created this file. For more info see http://www.lyx.org/
-\lyxformat 220
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
 \textclass amsart
 \language english
 \inputencoding auto
@@ -237,19 +237,6 @@ client
 --router Optional flag to mark this node as a router
 \layout Description
 
---profile\SpecialChar ~
-[not\SpecialChar ~
-implemented] Optional flag to mark this node as a profile node.
- This would be very useful to configure several client nodes in large clusters.
- It will allow user to define 
-\series bold 
-profiles
-\series default 
- for the various client configurations, and then load the correct profile
- on the client nodes using lconf.
- 
-\layout Description
-
 --port\SpecialChar ~
 [port] Optional arguement to indicate the tcp port.
  The default is 988.
@@ -294,8 +281,8 @@ name> Name of the node on which the MDS resides
 \layout Description
 
 --size\SpecialChar ~
-<size> Optional arguement indicating the size of the device to be
- created (used typically for loop devices).
+<size> Optional argument indicating the size (in KB) of the device
+ to be created (used typically for loop devices).
 \layout Description
 
 --node\SpecialChar ~
@@ -308,7 +295,7 @@ name> Name of the node on which the MDS resides
 \layout Description
 
 --fstype\SpecialChar ~
-extN|ext3 Optional arguement used to specify the file system type.
+extN|ext3 Optional argument used to specify the file system type.
  Default is ext3.
 \layout Description
 
@@ -380,10 +367,11 @@ ost Creates an OBD, OST, and OSC.
 \layout Description
 
 --size\SpecialChar ~
-[size]
+[size] Optional argument indicating the size (in KB) of the device
+ to be created (used typically for loop devices).
 \layout Description
 
---osdtype\SpecialChar ~
+--obdtype\SpecialChar ~
 obdfilter|obdecho 
 \layout Description
 
@@ -461,7 +449,7 @@ nid
 \layout Description
 
 --node\SpecialChar ~
-node Node or profile node to add the route to.
+node Node to add the route to.
 \layout Description
 
 --gw\SpecialChar ~
diff --git a/lustre/doc/lwizard.1 b/lustre/doc/lwizard.1
new file mode 100644
index 0000000000000000000000000000000000000000..285cfddc65af6a46cd382e4e1837513ce3608f11
--- /dev/null
+++ b/lustre/doc/lwizard.1
@@ -0,0 +1,84 @@
+.TH lwizard 1 "2003 Oct 29" Lustre "Configuration utilities"
+.SH NAME
+lwizard \- Lustre configuration wizard
+.SH SYNOPSIS
+.br
+.B lwizard
+.br
+.B lwizard [--help]
+.br
+.BR lwizard  [-o|--file=CONFIG_FILE][--stripe_size=SIZE][--stripe_cnt=COUNT]
+.SH DESCRIPTION
+The configuration files for Lustre installation are generally created through a series of lmc commands, this generates an XML file which describes the complete cluster. The lwizard eliminates the need to learn lmc to generate configuration files, instead it achieves the same through asking some simple questions. The 
+XML configuration file generated using lwizard will still have to be made accessible to all the cluster nodes either by storing it on an LDAP server, NFS or by copying it over to all the involved nodes and then running lconf on all nodes to start up the various Lustre services, device setups or mounting the filesystem. 
+So, once invoked, lwizard asks a series of questions about the various pieces of the cluster : 
+.TP
+.B MDS hostname 
+.TP
+.B MDS device information 
+.TP
+.B OST hostname 
+This will be asked for every new OST added 
+.TP
+.B OST device information 
+This will be asked for every new OST added 
+.TP
+.B Lustre mount-point 
+This is the Lustre mount-point on the client (default - /mnt/lustre) 
+
+The wizard saves the XML file to the filename specified using the -o or --file option or the default file config.xml. It will also save the lmc commands used to create the XML file in a script config.sh or <specified-file-name>.sh. 
+
+The lwizard tool currently assumes the following defaults: 
+
+.TP
+.B Network type
+tcp 
+.TP
+.B Filesystem type
+ext3 
+.TP
+.B LMC path
+.I /usr/sbin/lmc 
+
+.SH EXAMPLES
+The example below shows a sample session using lwizard.
+.PP
+[username@meghna utils]$ ./lwizard --stripe_size=64 --stripe_cnt=2 
+.br
+This script will help you create a Lustre configuration file. 
+.br
+Creating mds "mds1"...
+.br 
+Please enter the hostname(s) for mds1: meghna 
+.br
+Please enter the device name or loop file name for meghna: /tmp/mds1 
+.br
+Please enter the device size or 0 to use entire device:5000 
+.br
+Creating ost "ost1"... 
+.br
+Please enter the hostname(s) for ost1: meghna 
+.br
+Please enter the device name or loop file name for meghna: /tmp/ost1 
+.br
+Please enter the device size or 0 to use entire device:10000 
+.br
+Creating ost "ost2"... 
+.br
+Please enter the hostname(s) for ost2: 
+.br
+Please enter the clients' mountpoint (/mnt/lustre): 
+.br
+Creating mds "mds2"... 
+.br
+Please enter the hostname(s) for mds2: 
+.br
+ mds1 lov1 ost1 client 
+.br
+Saving configuration to config.xml: 
+.br
+Your configuration has been saved to config.xml. 
+.br
+Your config command has been save to config.sh. 
+.SH BUGS
+None are known.
diff --git a/lustre/include/linux/Makefile b/lustre/include/Makefile.am
similarity index 63%
rename from lustre/include/linux/Makefile
rename to lustre/include/Makefile.am
index c263b40602201d2d7c8c3057e7b4b6c0b845b8c7..d532ab5e50b61008bd8107d3bb71b964b4263b3b 100644
--- a/lustre/include/linux/Makefile
+++ b/lustre/include/Makefile.am
@@ -1,7 +1,9 @@
+
 # Copyright (C) 2001  Cluster File Systems, Inc.
 #
 # This code is issued under the GNU General Public License.
 # See the file COPYING in this distribution
 
-all .DEFAULT: 
-	$(MAKE) -C ../..  $@
+SUBDIRS = linux
+EXTRA_DIST = config.h.in ioctl.h liblustre.h 
+include $(top_srcdir)/Rules
diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h
index 6b94901ef85d6076a55a07772791882b487626ee..770ccf7880d26c0272d6f0b2cbef18b086346fbf 100644
--- a/lustre/include/liblustre.h
+++ b/lustre/include/liblustre.h
@@ -109,8 +109,11 @@ static inline void *kmalloc(int size, int prot)
 #define kfree(a) free(a)
 #define GFP_KERNEL 1
 #define GFP_HIGHUSER 1
+#define GFP_ATOMIC 1
+#define GFP_MEMALLOC 1
 #define IS_ERR(a) (((a) && abs((int)(a)) < 500) ? 1 : 0)
 #define PTR_ERR(a) ((int)(a))
+#define ERR_PTR(a) ((void*)(a))
 
 #define capable(foo) 1
 #define CAP_SYS_ADMIN 1
@@ -120,9 +123,12 @@ typedef struct {
 
 }mm_segment_t;
 
-typedef void *read_proc_t;
-typedef void *write_proc_t;
+typedef int (read_proc_t)(char *page, char **start, off_t off,
+                          int count, int *eof, void *data);
 
+struct file; /* forward ref */
+typedef int (write_proc_t)(struct file *file, const char *buffer,
+                           unsigned long count, void *data);
 
 /* byteorder */
 #define __swab16(x) \
@@ -179,6 +185,24 @@ typedef void *write_proc_t;
 # error "do more check here!!!"
 #endif
 
+#define NIPQUAD(addr) \
+        ((unsigned char *)&addr)[0], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[3]
+                                                                                                                        
+#if defined(__LITTLE_ENDIAN__)
+#define HIPQUAD(addr) \
+        ((unsigned char *)&addr)[3], \
+        ((unsigned char *)&addr)[2], \
+        ((unsigned char *)&addr)[1], \
+        ((unsigned char *)&addr)[0]
+#elif defined(__BIG_ENDIAN__)
+#define HIPQUAD NIPQUAD
+#else
+#error "Please fix asm/byteorder.h"
+#endif /* __LITTLE_ENDIAN__ */
+
 /* bits ops */
 static __inline__ int set_bit(int nr,long * addr)
 {
@@ -211,6 +235,21 @@ static __inline__ int test_bit(int nr, long * addr)
 	return ((mask & *addr) != 0);
 }
 
+static __inline__ int ext2_set_bit(int nr, void *addr)
+{
+        return set_bit(nr, (long*)addr);
+}
+
+static __inline__ int ext2_clear_bit(int nr, void *addr)
+{
+        return clear_bit(nr, (long*)addr);
+}
+
+static __inline__ int ext2_test_bit(int nr, void *addr)
+{
+        return test_bit(nr, (long*)addr);
+}
+
 /* modules */
 
 struct module {
@@ -234,12 +273,23 @@ static inline int misc_register(void *foo)
 {
         return 0;
 }
-#define misc_deregister misc_register
+
+static inline int misc_deregister(void *foo)
+{
+        return 0;
+}
+
+static inline int request_module(char *name)
+{
+        return (-EINVAL);
+}
 
 #define __MOD_INC_USE_COUNT(m)  do {int a = 1; a++; } while (0)
 #define __MOD_DEC_USE_COUNT(m)  do {int a = 1; a++; } while (0)
 #define MOD_INC_USE_COUNT  do {int a = 1; a++; } while (0)
 #define MOD_DEC_USE_COUNT  do {int a = 1; a++; } while (0)
+#define try_module_get                  __MOD_INC_USE_COUNT
+#define module_put                      __MOD_DEC_USE_COUNT
 
 /* module initialization */
 extern int init_obdclass(void);
@@ -261,9 +311,13 @@ typedef int spinlock_t;
 typedef __u64 kdev_t;
 
 #define SPIN_LOCK_UNLOCKED 0
-#define spin_lock(l) do {int a = 1; a++; } while (0)
-#define spin_unlock(l) do {int a= 1; a++; } while (0)
-#define spin_lock_init(l) do {int a= 1; a++; } while (0)
+static inline void spin_lock(spinlock_t *l) {return;}
+static inline void spin_unlock(spinlock_t *l) {return;}
+static inline void spin_lock_init(spinlock_t *l) {return;}
+static inline void local_irq_save(unsigned long flag) {return;}
+static inline void local_irq_restore(unsigned long flag) {return;}
+static inline int spin_is_locked(spinlock_t *l) {return 1;}
+
 static inline void spin_lock_bh(spinlock_t *l)
 {
         return;
@@ -272,20 +326,27 @@ static inline void spin_unlock_bh(spinlock_t *l)
 {
         return;
 }
-static inline void spin_unlock_irqrestore(spinlock_t *a, long b)
+static inline void spin_unlock_irqrestore(spinlock_t *a, unsigned long b)
 {
         return;
 }
-static inline void spin_lock_irqsave(spinlock_t *a, long b)
+static inline void spin_lock_irqsave(spinlock_t *a, unsigned long b)
 {
         return;
 }
 
-#define barrier() do {int a= 1; a++; } while (0)
-
 #define min(x,y) ((x)<(y) ? (x) : (y))
 #define max(x,y) ((x)>(y) ? (x) : (y))
 
+#ifndef min_t
+#define min_t(type,x,y) \
+	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#endif
+#ifndef max_t
+#define max_t(type,x,y) \
+	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+#endif
+
 /* registering symbols */
 
 #define ERESTARTSYS ERESTART
@@ -347,7 +408,6 @@ static inline int kmem_cache_destroy(kmem_cache_t *a)
         free(a);
         return 0;
 }
-#define kmem_cache_validate(a,b) 1
 #define kmem_cache_alloc(cache, prio) malloc(cache->size)
 #define kmem_cache_free(cache, obj) free(obj)
 
@@ -356,8 +416,14 @@ static inline int kmem_cache_destroy(kmem_cache_t *a)
 #define PAGE_CACHE_MASK PAGE_MASK
 
 struct page {
-        void *addr;
-        int index;
+        void   *addr;
+        unsigned long index;
+        struct list_head list;
+        unsigned long private;
+
+        /* internally used by liblustre file i/o */
+        int     _offset;
+        int     _count;
 };
 
 #define kmap(page) (page)->addr
@@ -369,7 +435,7 @@ static inline struct page *alloc_pages(int mask, unsigned long order)
 
         if (!pg)
                 return NULL;
-#ifdef MAP_ANONYMOUS
+#if 0 //#ifdef MAP_ANONYMOUS
         pg->addr = mmap(0, PAGE_SIZE << order, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
 #else
         pg->addr = malloc(PAGE_SIZE << order);
@@ -382,9 +448,11 @@ static inline struct page *alloc_pages(int mask, unsigned long order)
         return pg;
 }
 
+#define alloc_page(mask) alloc_pages((mask), 0)
+
 static inline void __free_pages(struct page *pg, int what)
 {
-#ifdef MAP_ANONYMOUS
+#if 0 //#ifdef MAP_ANONYMOUS
         munmap(pg->addr, PAGE_SIZE);
 #else
         free(pg->addr);
@@ -392,7 +460,9 @@ static inline void __free_pages(struct page *pg, int what)
         free(pg);
 }
 
-static inline struct page* __grab_cache_page(int index)
+#define __free_page(page) __free_pages((page), 0)
+
+static inline struct page* __grab_cache_page(unsigned long index)
 {
         struct page *pg = alloc_pages(0, 0);
 
@@ -441,26 +511,49 @@ struct iattr {
         unsigned int    ia_attr_flags;
 };
 
-/* copy from kernel header */
-#define IT_OPEN     (1)
-#define IT_CREAT    (1<<1)
-#define IT_READDIR  (1<<2)
-#define IT_GETATTR  (1<<3)
-#define IT_LOOKUP   (1<<4)
-#define IT_UNLINK   (1<<5)
-
+#define IT_OPEN     0x0001
+#define IT_CREAT    0x0002
+#define IT_READDIR  0x0004
+#define IT_GETATTR  0x0008
+#define IT_LOOKUP   0x0010
+#define IT_UNLINK   0x0020
+#define IT_GETXATTR 0x0040
+#define IT_EXEC     0x0080
+#define IT_PIN      0x0100
+
+#define IT_FL_LOCKED   0x0001
+#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */
+
+#define INTENT_MAGIC 0x19620323
+
+struct lustre_intent_data {
+        int       it_disposition;
+        int       it_status;
+        __u64     it_lock_handle;
+        void     *it_data;
+        int       it_lock_mode;
+        int it_int_flags;
+};
 struct lookup_intent {
-        int it_op;
-        int it_mode;
-        int it_flags;
-        int it_disposition;
-        int it_status;
-        struct iattr *it_iattr;
-        __u64 it_lock_handle[2];
-        int it_lock_mode;
-        void *it_data;
+        int     it_magic;
+        void    (*it_op_release)(struct lookup_intent *);
+        int     it_op;
+        int     it_flags;
+        int     it_create_mode;
+        union {
+                struct lustre_intent_data lustre;
+        } d;
 };
 
+static inline void intent_init(struct lookup_intent *it, int op, int flags)
+{
+        memset(it, 0, sizeof(*it));
+        it->it_magic = INTENT_MAGIC;
+        it->it_op = op;
+        it->it_flags = flags;
+}
+
+
 struct dentry {
         int d_count;
 };
@@ -471,6 +564,11 @@ struct vfsmount {
 
 #define cpu_to_le32(x) ((__u32)(x))
 
+/* semaphores */
+struct rw_semaphore {
+        int count;
+};
+
 /* semaphores */
 struct semaphore {
         int count;
@@ -478,7 +576,19 @@ struct semaphore {
 
 #define down(a) do {(a)->count++;} while (0)
 #define up(a) do {(a)->count--;} while (0)
+#define down_read(a) do {(a)->count++;} while (0)
+#define up_read(a) do {(a)->count--;} while (0)
+#define down_write(a) do {(a)->count++;} while (0)
+#define up_write(a) do {(a)->count--;} while (0)
 #define sema_init(a,b) do { (a)->count = b; } while (0)
+#define init_rwsem(a) do {} while (0)
+#define DECLARE_MUTEX(name)     \
+        struct semaphore name = { 1 }
+static inline void init_MUTEX (struct semaphore *sem)
+{
+        sema_init(sem, 1);
+}
+
 
 typedef struct  {
         struct list_head sleepers;
@@ -525,6 +635,18 @@ extern struct task_struct *current;
 #define TASK_UNINTERRUPTIBLE 1
 #define TASK_RUNNING 2
 
+#define wait_event_interruptible(wq, condition)                         \
+({                                                                      \
+        struct l_wait_info lwi;                                         \
+        int timeout = 100000000;/* for ever */                          \
+        int ret;                                                        \
+                                                                        \
+        lwi = LWI_TIMEOUT(timeout, NULL, NULL);                         \
+        ret = l_wait_event(NULL, condition, &lwi);                      \
+                                                                        \
+        ret;                                                            \
+})
+
 #define in_interrupt() (0)
 
 #define schedule() do { int a; a++; } while (0)
@@ -537,7 +659,9 @@ static inline int schedule_timeout(signed long t)
 #define daemonize(l) do { int a; a++; } while (0)
 #define sigfillset(l) do { int a; a++; } while (0)
 #define recalc_sigpending(l) do { int a; a++; } while (0)
-#define kernel_thread(l,m,n)
+#define kernel_thread(l,m,n) LBUG()
+
+#define USERMODEHELPER(path, argv, envp) (0)
 
 static inline int call_usermodehelper(char *prog, char **argv, char **evnp, int unknown)
 {
@@ -545,6 +669,7 @@ static inline int call_usermodehelper(char *prog, char **argv, char **evnp, int
 }
 
 
+#define SIGNAL_MASK_ASSERT()
 
 #define KERN_INFO
 
@@ -553,8 +678,8 @@ static inline int call_usermodehelper(char *prog, char **argv, char **evnp, int
 struct timer_list {
         struct list_head tl_list;
         void (*function)(unsigned long unused);
-        void *data;
-        int expires;
+        unsigned long data;
+        long expires;
 };
 
 static inline int timer_pending(struct timer_list *l)
@@ -591,12 +716,53 @@ typedef struct { volatile int counter; } atomic_t;
 #define atomic_add(b,a)  do {(a)->counter += b;} while (0)
 #define atomic_sub(b,a)  do {(a)->counter -= b;} while (0)
 
+#define likely(exp) (exp)
+#define unlikely(exp) (exp)
+
+/* log related */
+static inline int llog_init_commit_master(void) { return 0; }
+static inline int llog_cleanup_commit_master(int force) { return 0; }
+static inline void portals_run_lbug_upcall(char *file, const char *fn,
+                                           const int l){}
+
 #define LBUG()                                                          \
         do {                                                            \
                 printf("!!!LBUG at %s:%d\n", __FILE__, __LINE__);       \
                 sleep(1000000);                                         \
         } while (0)
 
+
+
+/* completion */
+struct completion {
+        unsigned int done;
+        wait_queue_head_t wait;
+};
+
+#define COMPLETION_INITIALIZER(work) \
+        { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
+
+#define DECLARE_COMPLETION(work) \
+        struct completion work = COMPLETION_INITIALIZER(work)
+
+#define INIT_COMPLETION(x)      ((x).done = 0)
+
+static inline void init_completion(struct completion *x)
+{
+        x->done = 0;
+        init_waitqueue_head(&x->wait);
+}
+
+struct liblustre_wait_callback {
+        struct list_head    llwc_list;
+        int               (*llwc_fn)(void *arg);
+        void               *llwc_arg;
+};
+
+void *liblustre_register_wait_callback(int (*fn)(void *arg), void *arg);
+void liblustre_deregister_wait_callback(void *notifier);
+int liblustre_wait_event(int timeout);
+
 #include <linux/obd_support.h>
 #include <linux/lustre_idl.h>
 #include <linux/lustre_lib.h>
diff --git a/lustre/include/linux/Makefile.am b/lustre/include/linux/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..cd614f9d7b381b1032dd643947a3e226e52ad9b5
--- /dev/null
+++ b/lustre/include/linux/Makefile.am
@@ -0,0 +1,14 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+
+pkginclude_HEADERS = lustre_user.h
+
+EXTRA_DIST = lprocfs_status.h lustre_debug.h lustre_ha.h lustre_lib.h \
+  lustre_mgmt.h obd_cache.h obd_lov.h lustre_dlm.h lustre_handles.h \
+  lustre_net.h obd_class.h obd_ost.h obd_support.h lustre_commit_confd.h \
+  lustre_export.h lustre_log.h obd_echo.h obd_ptlbd.h obd_trace.h \
+  lustre_compat25.h lustre_fsfilt.h lustre_import.h lustre_mds.h obd.h \
+  lvfs.h lvfs_linux.h lustre_cfg.h lustre_lite.h  lustre_idl.h
diff --git a/lustre/include/linux/lprocfs_status.h b/lustre/include/linux/lprocfs_status.h
index e6678f8331e8286299cfa1a68dded7cebb43141e..d71995f2cc48fd24b11b0e69c38b90dd945ddaeb 100644
--- a/lustre/include/linux/lprocfs_status.h
+++ b/lustre/include/linux/lprocfs_status.h
@@ -44,10 +44,9 @@
 #endif
 
 
-#ifndef LPROCFS
-#ifdef  CONFIG_PROC_FS  /* Ensure that /proc is configured */
-#define LPROCFS
-#endif
+#undef LPROCFS
+#if (defined(__KERNEL__) && defined(CONFIG_PROC_FS))
+# define LPROCFS
 #endif
 
 struct lprocfs_vars {
@@ -257,6 +256,9 @@ extern int lprocfs_rd_filesfree(char *page, char **start, off_t off,
 extern int lprocfs_rd_filegroups(char *page, char **start, off_t off,
                                  int count, int *eof, void *data);
 
+extern int lprocfs_write_helper(const char *buffer, unsigned long count, 
+                                int *val);
+
 /* lprocfs_status.c: counter read/write functions */
 extern int lprocfs_counter_read(char *page, char **start, off_t off,
                                 int count, int *eof, void *data);
diff --git a/lustre/include/linux/lustre_cfg.h b/lustre/include/linux/lustre_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9a278f3692809c79c95d9c12d74e2dbe666808b
--- /dev/null
+++ b/lustre/include/linux/lustre_cfg.h
@@ -0,0 +1,262 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LUSTRE_CFG_H
+#define _LUSTRE_CFG_H
+
+#define LUSTRE_CFG_VERSION 0x00010001
+
+enum lcfg_command_type {
+        LCFG_ATTACH         = 0x00cf001,
+        LCFG_DETACH         = 0x00cf002,
+        LCFG_SETUP          = 0x00cf003,
+        LCFG_CLEANUP        = 0x00cf004,
+        LCFG_ADD_UUID       = 0x00cf005,
+        LCFG_DEL_UUID       = 0x00cf006,
+        LCFG_MOUNTOPT       = 0x00cf007,
+        LCFG_DEL_MOUNTOPT   = 0x00cf008,
+        LCFG_SET_TIMEOUT    = 0x00cf009,
+        LCFG_SET_UPCALL     = 0x00cf010,
+};
+
+struct lustre_cfg {
+        uint32_t lcfg_version;
+        uint32_t lcfg_command;
+
+        uint32_t lcfg_num; 
+        uint32_t lcfg_flags;
+        uint64_t lcfg_nid;
+        uint32_t lcfg_nal;
+
+        /* inline buffers for various arguments */
+        uint32_t lcfg_dev_namelen;
+        char    *lcfg_dev_name;
+        uint32_t lcfg_inllen1;
+        char    *lcfg_inlbuf1;
+        uint32_t lcfg_inllen2;
+        char    *lcfg_inlbuf2;
+        uint32_t lcfg_inllen3;
+        char    *lcfg_inlbuf3;
+        uint32_t lcfg_inllen4;
+        char    *lcfg_inlbuf4;
+
+        char    lcfg_bulk[0];
+
+};
+
+#define LCFG_INIT(l, cmd, name)                                 \
+do {                                                            \
+        memset(&(l), 0, sizeof(l));                             \
+        (l).lcfg_version = LUSTRE_CFG_VERSION;                  \
+        (l).lcfg_command = (cmd);                               \
+        if (name) {                                             \
+                (l).lcfg_dev_namelen = strlen(name) + 1;        \
+                (l).lcfg_dev_name = name;                       \
+        }                                                       \
+                                                                \
+} while (0)
+
+#ifndef __KERNEL__
+static inline int lustre_cfg_packlen(struct lustre_cfg *lcfg)
+{
+        int len = size_round(sizeof(struct lustre_cfg));
+        len += size_round(lcfg->lcfg_dev_namelen);
+        len += size_round(lcfg->lcfg_inllen1);
+        len += size_round(lcfg->lcfg_inllen2);
+        len += size_round(lcfg->lcfg_inllen3);
+        len += size_round(lcfg->lcfg_inllen4);
+        return size_round(len);
+}
+
+static inline int lustre_cfg_pack(struct lustre_cfg *data, char **pbuf,
+                                 int max, int *plen)
+{
+        char *ptr;
+        struct lustre_cfg *overlay;
+	int len;
+
+        len = lustre_cfg_packlen(data);
+
+        data->lcfg_version = LUSTRE_CFG_VERSION;
+
+        if (*pbuf && len > max)
+                return 1;
+        if (*pbuf == NULL) {
+                *pbuf = malloc(len);
+        }
+        if (!*pbuf)
+                return 1;
+        overlay = (struct lustre_cfg *)*pbuf;
+        memcpy(*pbuf, data, sizeof(*data));
+
+        ptr = overlay->lcfg_bulk;
+        if (data->lcfg_dev_name)
+                LOGL(data->lcfg_dev_name, data->lcfg_dev_namelen, ptr);
+        if (data->lcfg_inlbuf1)
+                LOGL(data->lcfg_inlbuf1, data->lcfg_inllen1, ptr);
+        if (data->lcfg_inlbuf2)
+                LOGL(data->lcfg_inlbuf2, data->lcfg_inllen2, ptr);
+        if (data->lcfg_inlbuf3)
+                LOGL(data->lcfg_inlbuf3, data->lcfg_inllen3, ptr);
+        if (data->lcfg_inlbuf4)
+                LOGL(data->lcfg_inlbuf4, data->lcfg_inllen4, ptr);
+//        if (lustre_cfg_is_invalid(overlay))
+//                return 1;
+
+	*plen = len;
+
+        return 0;
+}
+
+static inline int lustre_cfg_unpack(struct lustre_cfg *data, char *pbuf,
+                                   int max)
+{
+        char *ptr;
+        struct lustre_cfg *overlay;
+
+        if (!pbuf)
+                return 1;
+        overlay = (struct lustre_cfg *)pbuf;
+
+        /* Preserve the caller's buffer pointers */
+        overlay->lcfg_dev_name = data->lcfg_dev_name;
+        overlay->lcfg_inlbuf1 = data->lcfg_inlbuf1;
+        overlay->lcfg_inlbuf2 = data->lcfg_inlbuf2;
+        overlay->lcfg_inlbuf3 = data->lcfg_inlbuf3;
+        overlay->lcfg_inlbuf4 = data->lcfg_inlbuf4;
+
+        memcpy(data, pbuf, sizeof(*data));
+
+        ptr = overlay->lcfg_bulk;
+        if (data->lcfg_dev_name)
+                LOGU(data->lcfg_dev_name, data->lcfg_dev_namelen, ptr);
+        if (data->lcfg_inlbuf1)
+                LOGU(data->lcfg_inlbuf1, data->lcfg_inllen1, ptr);
+        if (data->lcfg_inlbuf2)
+                LOGU(data->lcfg_inlbuf2, data->lcfg_inllen2, ptr);
+        if (data->lcfg_inlbuf3)
+                LOGU(data->lcfg_inlbuf3, data->lcfg_inllen3, ptr);
+        if (data->lcfg_inlbuf4)
+                LOGU(data->lcfg_inlbuf4, data->lcfg_inllen4, ptr);
+
+        return 0;
+}
+#endif
+
+#include <linux/obd_support.h>
+
+static inline int lustre_cfg_getdata(char **buf, int len, void *arg, int kernel)
+{
+        struct lustre_cfg *lcfg;
+        int err;
+	int offset = 0;
+        ENTRY;
+        if (len > OBD_MAX_IOCTL_BUFFER) {
+                CERROR("User buffer len %d exceeds %d max buffer\n",
+                       len, OBD_MAX_IOCTL_BUFFER);
+                return -EINVAL;
+        }
+
+        if (len < sizeof(struct lustre_cfg)) {
+                CERROR("OBD: user buffer too small for lustre_cfg\n");
+                return -EINVAL;
+        }
+
+        /* XXX allocate this more intelligently, using kmalloc when
+         * appropriate */
+        OBD_ALLOC(*buf, len);
+        if (*buf == NULL) {
+                CERROR("Cannot allocate control buffer of len %d\n", len);
+                RETURN(-EINVAL);
+        }
+
+        if (kernel) {
+                memcpy(*buf, (void *)arg, len);
+        } else {
+                err = copy_from_user(*buf, (void *)arg, len);
+                if (err) 
+                        RETURN(err);
+        }
+
+        lcfg = (struct lustre_cfg *)*buf;
+
+        if (lcfg->lcfg_version != LUSTRE_CFG_VERSION) {
+                CERROR("Version mismatch kernel vs application\n");
+                return -EINVAL;
+        }
+
+//        if (lustre_cfg_is_invalid(data)) {
+//                CERROR("ioctl not correctly formatted\n");
+//                return -EINVAL;
+//        }
+
+        if (lcfg->lcfg_dev_name) {
+                lcfg->lcfg_dev_name = &lcfg->lcfg_bulk[0];
+		offset += size_round(lcfg->lcfg_dev_namelen);
+        }
+
+        if (lcfg->lcfg_inllen1) {
+                lcfg->lcfg_inlbuf1 = &lcfg->lcfg_bulk[0] + offset;
+		offset += size_round(lcfg->lcfg_inllen1);
+        }
+
+        if (lcfg->lcfg_inllen2) {
+                lcfg->lcfg_inlbuf2 = &lcfg->lcfg_bulk[0] + offset;
+		offset += size_round(lcfg->lcfg_inllen2);
+        }
+
+        if (lcfg->lcfg_inllen3) {
+                lcfg->lcfg_inlbuf3 = &lcfg->lcfg_bulk[0] + offset;
+		offset += size_round(lcfg->lcfg_inllen3);
+        }
+
+        if (lcfg->lcfg_inllen4) {
+                lcfg->lcfg_inlbuf4 = &lcfg->lcfg_bulk[0] + offset;
+        }
+
+        EXIT;
+        return 0;
+}
+
+static inline void lustre_cfg_freedata(char *buf, int len)
+{
+        ENTRY;
+
+        OBD_FREE(buf, len);
+        EXIT;
+        return;
+}
+
+/* Passed by mount */
+struct lustre_mount_data {
+        uint32_t lmd_version;
+        uint64_t lmd_local_nid;
+        uint64_t lmd_server_nid;
+        uint32_t lmd_nal;
+        uint32_t lmd_server_ipaddr;
+        uint32_t lmd_port;
+        char     lmd_mds[64];
+        char     lmd_profile[64];
+};
+
+
+#endif // _LUSTRE_CFG_H
diff --git a/lustre/include/linux/lustre_commit_confd.h b/lustre/include/linux/lustre_commit_confd.h
index 980e6ced80eb134ddbb3dc73b43004ac2e0ca550..a749911611dcad3cb65122fcbf96795d9945077c 100644
--- a/lustre/include/linux/lustre_commit_confd.h
+++ b/lustre/include/linux/lustre_commit_confd.h
@@ -26,11 +26,12 @@
 
 #include <linux/lustre_log.h>
 
-struct llog_commit_data {
+struct llog_canceld_ctxt {
         struct list_head           llcd_list;  /* free or pending struct list */
         struct obd_import         *llcd_import;
         struct llog_commit_master *llcd_lcm;
         int                        llcd_tries; /* number of tries to send */
+        struct llog_ctxt_gen       llcd_gen; 
         int                        llcd_cookiebytes;
         struct llog_cookie         llcd_cookies[0];
 };
@@ -46,9 +47,9 @@ struct llog_commit_master {
         int                     lcm_flags;
         wait_queue_head_t       lcm_waitq;
 
-        struct list_head        lcm_llcd_pending; /* llog_commit_data to send */
+        struct list_head        lcm_llcd_pending; /* llog_canceld_ctxt to send */
         struct list_head        lcm_llcd_resend;  /* try to resend this data */
-        struct list_head        lcm_llcd_free;    /* free llog_commit_data */
+        struct list_head        lcm_llcd_free;    /* free llog_canceld_ctxt */
         spinlock_t              lcm_llcd_lock;    /* protects llcd_free */
         atomic_t                lcm_llcd_numfree; /* items on llcd_free */
         int                     lcm_llcd_minfree; /* min free on llcd_free */
@@ -67,7 +68,7 @@ struct llog_commit_daemon {
 
 /* ptlrpc/recov_thread.c */
 int llog_start_commit_thread(void);
-struct llog_commit_data *llcd_grab(void);
-void llcd_send(struct llog_commit_data *llcd);
+struct llog_canceld_ctxt *llcd_grab(void);
+void llcd_send(struct llog_canceld_ctxt *llcd);
 
 #endif /* _LUSTRE_COMMIT_CONFD_H */
diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h
index a142e9bddd01f263544711da781020b84dea4cba..fdd1abfca43c8481dadf1b5d817a98f9da05c2cd 100644
--- a/lustre/include/linux/lustre_compat25.h
+++ b/lustre/include/linux/lustre_compat25.h
@@ -32,24 +32,69 @@
 #include <linux/portals_compat25.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-# define PGCACHE_WRLOCK(mapping)          write_lock(&mapping->page_lock)
-# define PGCACHE_WRUNLOCK(mapping)        write_unlock(&mapping->page_lock)
 
-#define KDEVT_INIT(val)                 { .value = val }
+/*
+ * OBD need working random driver, thus all our
+ * initialization routines must be called after device
+ * driver initialization
+ */
+#define module_init(a)     late_initcall(a)
+
+/* XXX our code should be using the 2.6 calls, not the other way around */
+#define TryLockPage(page)                TestSetPageLocked(page)
+#define filemap_fdatasync(mapping)       filemap_fdatawrite(mapping)
+#define Page_Uptodate(page)              PageUptodate(page)
+
+#define KDEVT_INIT(val)                 (val)
+
 #define LTIME_S(time)                   (time.tv_sec)
 #define ll_path_lookup                  path_lookup
-
+#define ll_permission                   permission
 
 #define ll_pgcache_lock(mapping)          spin_lock(&mapping->page_lock)
 #define ll_pgcache_unlock(mapping)        spin_unlock(&mapping->page_lock)
 
+#define ll_vfs_create(a,b,c,d)              vfs_create(a,b,c,d)
+
+#define ll_dev_t                        dev_t
+#define kdev_t                          dev_t
+#define to_kdev_t(dev)                  (dev)
+#define kdev_t_to_nr(dev)               (dev)
+#define val_to_kdev(dev)                (dev)
+#define ILOOKUP(sb, ino, test, data)    ilookup5(sb, ino, test, data);
+
+#include <linux/writeback.h>
+
+static inline void lustre_daemonize_helper(void)
+{
+        LASSERT(current->signal != NULL);
+        current->signal->session = 1;
+        current->signal->pgrp = 1;
+        current->signal->tty = NULL;
+}
+
+#define  rb_node_s rb_node
+#define  rb_root_s rb_root
+typedef struct rb_root_s rb_root_t;
+typedef struct rb_node_s rb_node_t;
+
 #else /* 2.4.. */
 
-# define PGCACHE_WRLOCK(mapping)          spin_lock(&pagecache_lock)
-# define PGCACHE_WRUNLOCK(mapping)        spin_unlock(&pagecache_lock)
+#define ll_vfs_create(a,b,c,d)              vfs_create(a,b,c)
+#define ll_permission(a,b,c)                permission(a,b)
+#define ILOOKUP(sb, ino, test, data)        ilookup4(sb, ino, test, data);
+#define DCACHE_DISCONNECTED                 DCACHE_NFSD_DISCONNECTED
+#define ll_dev_t                            int
+
+static inline void clear_page_dirty(struct page *page)
+{
+        if (PageDirty(page))
+                ClearPageDirty(page); 
+}
 
 /* 2.5 uses hlists for some things, like the d_hash.  we'll treat them
  * as 2.5 and let macros drop back.. */
+#ifndef HLIST_HEAD /* until we get a kernel newer than l28 */
 #define hlist_entry                     list_entry
 #define hlist_head                      list_head
 #define hlist_node                      list_head
@@ -58,8 +103,10 @@
 #define hlist_del_init                  list_del_init
 #define hlist_add_head                  list_add
 #define hlist_for_each_safe             list_for_each_safe
+#endif
 #define KDEVT_INIT(val)                 (val)
 #define ext3_xattr_set_handle           ext3_xattr_set
+#define extN_xattr_set_handle           extN_xattr_set
 #define try_module_get                  __MOD_INC_USE_COUNT
 #define module_put                      __MOD_DEC_USE_COUNT
 #define LTIME_S(time)                   (time)
@@ -75,33 +122,30 @@ static inline int ll_path_lookup(const char *path, unsigned flags,
                 error = path_walk(path, nd);
         return error;
 }
+#define ll_permission(a,b,c)  permission(a,b)
 typedef long sector_t;
 
 #define ll_pgcache_lock(mapping)        spin_lock(&pagecache_lock)
 #define ll_pgcache_unlock(mapping)      spin_unlock(&pagecache_lock)
 
-#endif /* end of 2.4 compat macros */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-# define filemap_fdatasync(mapping)       filemap_fdatawrite(mapping)
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-# define TryLockPage(page)                TestSetPageLocked(page)
-#endif
+static inline void __d_drop(struct dentry *dentry)
+{
+	list_del(&dentry->d_hash);
+	INIT_LIST_HEAD(&dentry->d_hash);
+}
 
+static inline void lustre_daemonize_helper(void)
+{
+        current->session = 1;
+        current->pgrp = 1;
+        current->tty = NULL;
+}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-# define Page_Uptodate(page)              PageUptodate(page)
+#ifndef conditional_schedule
+#define conditional_schedule() if (unlikely(need_resched())) schedule()
 #endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-#define  rb_node_s rb_node
-#define  rb_root_s rb_root
-typedef struct rb_root_s rb_root_t;
-typedef struct rb_node_s rb_node_t;
-#endif
+#endif /* end of 2.4 compat macros */
 
 #endif /* __KERNEL__ */
 #endif /* _COMPAT25_H */
diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h
index 8f8fe8d65337a20eb060978e848a6667783e12b5..331e8f8208d36e581d5602ff9c5b9cd357932297 100644
--- a/lustre/include/linux/lustre_dlm.h
+++ b/lustre/include/linux/lustre_dlm.h
@@ -66,7 +66,10 @@ typedef enum {
 #define LDLM_FL_LOCAL          0x004000 /* local lock (ie, no srv/cli split) */
 #define LDLM_FL_WARN           0x008000 /* see ldlm_cli_cancel_unused */
 #define LDLM_FL_DISCARD_DATA   0x010000 /* discard (no writeback) on cancel */
-#define LDLM_FL_MATCH_DATA     0x020000 /* see ldlm_lock_match */
+
+/* file & record locking */
+#define LDLM_FL_BLOCK_NOWAIT   0x040000 // server told not to wait if blocked
+#define LDLM_FL_TEST_LOCK      0x080000 // return blocking lock
 
 /* These are flags that are mapped into the flags and ASTs of blocking locks */
 #define LDLM_AST_DISCARD_DATA  0x80000000 /* Add FL_DISCARD to blocking ASTs */
@@ -100,10 +103,8 @@ static ldlm_mode_t lck_compat_array[] = {
 
 static inline int lockmode_compat(ldlm_mode_t exist, ldlm_mode_t new)
 {
-       if (exist < LCK_EX || exist > LCK_NL)
-              LBUG();
-       if (new < LCK_EX || new > LCK_NL)
-              LBUG();
+       LASSERT(exist >= LCK_EX && exist <= LCK_NL);
+       LASSERT(new >= LCK_EX && new <= LCK_NL);
 
        return (lck_compat_array[exist] & L2B(new));
 }
@@ -136,7 +137,7 @@ struct ldlm_namespace {
         */
 
         struct list_head       ns_unused_list; /* all root resources in ns */
-        unsigned int           ns_nr_unused;
+        int                    ns_nr_unused;
         unsigned int           ns_max_unused;
 
         spinlock_t             ns_counter_lock;
@@ -180,13 +181,15 @@ struct ldlm_lock {
 
         ldlm_completion_callback l_completion_ast;
         ldlm_blocking_callback   l_blocking_ast;
+        void                    *l_ast_data;
 
         struct obd_export    *l_export;
-        struct lustre_handle *l_connh;
+        /* XXX phil can fix this, I'm sure */
+        struct obd_export    *l_conn_export;
+//        struct lustre_handle *l_connh;
         __u32                 l_flags;
         struct lustre_handle  l_remote_handle;
-        void                 *l_data;
-        struct ldlm_extent    l_extent;
+        ldlm_policy_data_t    l_policy_data;
         __u32                 l_version[RES_VERSION_SIZE];
 
         __u32                 l_readers;
@@ -200,16 +203,16 @@ struct ldlm_lock {
         struct timeval        l_enqueued_time;
 };
 
-typedef int (*ldlm_res_compat)(struct ldlm_lock *child, struct ldlm_lock *new);
 typedef int (*ldlm_res_policy)(struct ldlm_namespace *, struct ldlm_lock **,
                                void *req_cookie, ldlm_mode_t mode, int flags,
                                void *data);
 
 #define LDLM_PLAIN       10
 #define LDLM_EXTENT      11
+#define LDLM_FLOCK       12
 
 #define LDLM_MIN_TYPE 10
-#define LDLM_MAX_TYPE 11
+#define LDLM_MAX_TYPE 12
 
 struct ldlm_resource {
         struct ldlm_namespace *lr_namespace;
@@ -256,19 +259,43 @@ do {                                                                          \
                 CDEBUG(level, "### " format                                   \
                        " ns: \?\? lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "\
                        "res: \?\? rrc=\?\? type: \?\?\? flags: %x remote: "   \
-                       LPX64"\n" , ## a, lock, lock->l_handle.h_cookie,       \
-                       atomic_read(&lock->l_refc),                            \
+                       LPX64" expref: %d\n" , ## a, lock,                     \
+                       lock->l_handle.h_cookie, atomic_read(&lock->l_refc),   \
                        lock->l_readers, lock->l_writers,                      \
                        ldlm_lockname[lock->l_granted_mode],                   \
                        ldlm_lockname[lock->l_req_mode],                       \
-                       lock->l_flags, lock->l_remote_handle.cookie);          \
+                       lock->l_flags, lock->l_remote_handle.cookie,           \
+                       lock->l_export ?                                       \
+                       atomic_read(&lock->l_export->exp_refcount) : -99);     \
                 break;                                                        \
         }                                                                     \
         if (lock->l_resource->lr_type == LDLM_EXTENT) {                       \
                 CDEBUG(level, "### " format                                   \
                        " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "  \
                        "res: "LPU64"/"LPU64" rrc: %d type: %s ["LPU64"->"LPU64\
-                       "] flags: %x remote: "LPX64"\n" , ## a,                \
+                       "] flags: %x remote: "LPX64" expref: %d\n" , ## a,     \
+                       lock->l_resource->lr_namespace->ns_name, lock,         \
+                       lock->l_handle.h_cookie, atomic_read(&lock->l_refc),   \
+                       lock->l_readers, lock->l_writers,                      \
+                       ldlm_lockname[lock->l_granted_mode],                   \
+                       ldlm_lockname[lock->l_req_mode],                       \
+                       lock->l_resource->lr_name.name[0],                     \
+                       lock->l_resource->lr_name.name[1],                     \
+                       atomic_read(&lock->l_resource->lr_refcount),           \
+                       ldlm_typename[lock->l_resource->lr_type],              \
+                       lock->l_policy_data.l_extent.start,                    \
+                       lock->l_policy_data.l_extent.end,                      \
+                       lock->l_flags, lock->l_remote_handle.cookie,           \
+                       lock->l_export ?                                       \
+                       atomic_read(&lock->l_export->exp_refcount) : -99);     \
+                break;                                                        \
+        }                                                                     \
+        if (lock->l_resource->lr_type == LDLM_FLOCK) {                        \
+                CDEBUG(level, "### " format                                   \
+                       " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "  \
+                       "res: "LPU64"/"LPU64" rrc: %d type: %s pid: %d "       \
+                       "["LPU64"->"LPU64"] flags: %x remote: "LPX64           \
+                       " expref: %d\n" , ## a,                                \
                        lock->l_resource->lr_namespace->ns_name, lock,         \
                        lock->l_handle.h_cookie, atomic_read(&lock->l_refc),   \
                        lock->l_readers, lock->l_writers,                      \
@@ -278,15 +305,19 @@ do {                                                                          \
                        lock->l_resource->lr_name.name[1],                     \
                        atomic_read(&lock->l_resource->lr_refcount),           \
                        ldlm_typename[lock->l_resource->lr_type],              \
-                       lock->l_extent.start, lock->l_extent.end,              \
-                       lock->l_flags, lock->l_remote_handle.cookie);          \
+                       lock->l_policy_data.l_flock.pid,                       \
+                       lock->l_policy_data.l_flock.start,                     \
+                       lock->l_policy_data.l_flock.end,                       \
+                       lock->l_flags, lock->l_remote_handle.cookie,           \
+                       lock->l_export ?                                       \
+                       atomic_read(&lock->l_export->exp_refcount) : -99);     \
                 break;                                                        \
         }                                                                     \
         {                                                                     \
                 CDEBUG(level, "### " format                                   \
                        " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "  \
                        "res: "LPU64"/"LPU64" rrc: %d type: %s flags: %x "     \
-                       "remote: "LPX64"\n" , ## a,                            \
+                       "remote: "LPX64" expref: %d\n" , ## a,                 \
                        lock->l_resource->lr_namespace->ns_name,               \
                        lock, lock->l_handle.h_cookie,                         \
                        atomic_read (&lock->l_refc),                           \
@@ -297,7 +328,9 @@ do {                                                                          \
                        lock->l_resource->lr_name.name[1],                     \
                        atomic_read(&lock->l_resource->lr_refcount),           \
                        ldlm_typename[lock->l_resource->lr_type],              \
-                       lock->l_flags, lock->l_remote_handle.cookie);          \
+                       lock->l_flags, lock->l_remote_handle.cookie,           \
+                       lock->l_export ?                                       \
+                       atomic_read(&lock->l_export->exp_refcount) : -99);     \
         }                                                                     \
 } while (0)
 
@@ -329,10 +362,8 @@ int ldlm_replay_locks(struct obd_import *imp);
 void ldlm_change_cbdata(struct ldlm_namespace *, struct ldlm_res_id *,
                         ldlm_iterator_t iter, void *data);
 
-/* ldlm_extent.c */
-int ldlm_extent_compat(struct ldlm_lock *, struct ldlm_lock *);
-int ldlm_extent_policy(struct ldlm_namespace *, struct ldlm_lock **, void *,
-                       ldlm_mode_t, int flags, void *);
+/* ldlm_flock.c */
+int ldlm_flock_completion_ast(struct ldlm_lock *lock, int flags, void *data);
 
 /* ldlm_lockd.c */
 int ldlm_server_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *,
@@ -343,6 +374,8 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req, ldlm_completion_callback,
 int ldlm_handle_convert(struct ptlrpc_request *req);
 int ldlm_handle_cancel(struct ptlrpc_request *req);
 int ldlm_del_waiting_lock(struct ldlm_lock *lock);
+int ldlm_get_ref(void);
+void ldlm_put_ref(int force);
 
 /* ldlm_lock.c */
 void ldlm_register_intent(ldlm_res_policy arg);
@@ -355,6 +388,9 @@ void ldlm_lock_remove_from_lru(struct ldlm_lock *);
 struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *,
                                       struct lustre_handle *);
 
+void *ldlm_put_lock_into_req(struct ptlrpc_request *,
+                                struct lustre_handle *, int);
+
 static inline struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *h)
 {
         return __ldlm_handle2lock(h, 0);
@@ -378,17 +414,15 @@ void ldlm_lock_put(struct ldlm_lock *lock);
 void ldlm_lock_destroy(struct ldlm_lock *lock);
 void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc);
 void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode);
-void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode);
 void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode);
 void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode);
 int ldlm_lock_match(struct ldlm_namespace *ns, int flags, struct ldlm_res_id *,
                     __u32 type, void *cookie, int cookielen, ldlm_mode_t mode,
-                    void *data, struct lustre_handle *);
+                    struct lustre_handle *);
 struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
                                         int *flags);
 void ldlm_lock_cancel(struct ldlm_lock *lock);
 void ldlm_cancel_locks_for_export(struct obd_export *export);
-int ldlm_run_ast_work(struct list_head *rpc_list);
 void ldlm_reprocess_all(struct ldlm_resource *res);
 void ldlm_reprocess_all_ns(struct ldlm_namespace *ns);
 void ldlm_lock_dump(int level, struct ldlm_lock *lock, int pos);
@@ -406,10 +440,10 @@ int ldlm_regression_stop(void);
 
 /* resource.c */
 struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 local);
-int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only);
-int ldlm_namespace_free(struct ldlm_namespace *ns);
-int ldlm_proc_setup(struct obd_device *obd);
-void ldlm_proc_cleanup(struct obd_device *obd);
+int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags);
+int ldlm_namespace_free(struct ldlm_namespace *ns, int force);
+int ldlm_proc_setup(void);
+void ldlm_proc_cleanup(void);
 
 /* resource.c - internal */
 struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
@@ -431,7 +465,7 @@ int ldlm_lock_change_resource(struct ldlm_namespace *, struct ldlm_lock *,
 /* ldlm_request.c */
 int ldlm_expired_completion_wait(void *data);
 int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data);
-int ldlm_cli_enqueue(struct lustre_handle *conn,
+int ldlm_cli_enqueue(struct obd_export *exp,
                      struct ptlrpc_request *req,
                      struct ldlm_namespace *ns,
                      struct lustre_handle *parent_lock_handle,
diff --git a/lustre/include/linux/lustre_export.h b/lustre/include/linux/lustre_export.h
index 677ddc6c917e27dd06282d62a9f245e940e258e3..f8ae03ca7f6adfa0edb7d7349440ab34e8649d19 100644
--- a/lustre/include/linux/lustre_export.h
+++ b/lustre/include/linux/lustre_export.h
@@ -23,25 +23,36 @@ struct mds_export_data {
         int                     med_idx;
 };
 
-struct ldlm_export_data {
-        struct list_head       led_held_locks; /* protected by namespace lock */
-        struct obd_import     *led_import;
+struct osc_creator {
+        spinlock_t              oscc_lock;
+        struct list_head        oscc_list;
+        struct obd_export      *oscc_exp;
+        obd_id                  oscc_last_id;//last available pre-created object
+        obd_id                  oscc_next_id;// what object id to give out next
+        int                     oscc_initial_create_count;
+        int                     oscc_grow_count;
+        int                     oscc_kick_barrier;
+        struct osc_created     *oscc_osccd;
+        struct obdo             oscc_oa;
+        int                     oscc_flags;
+        wait_queue_head_t       oscc_waitq; /* creating procs wait on this */
+};
+
+struct osc_export_data {
+        struct osc_creator      oed_oscc;
 };
 
-struct lov_export_data {
-        spinlock_t       led_lock;
-        struct list_head led_open_head;
+struct ldlm_export_data {
+        struct list_head       led_held_locks; /* protected by namespace lock */
 };
 
 struct ec_export_data { /* echo client */
-        struct list_head eced_open_head;
         struct list_head eced_locks;
 };
 
 /* In-memory access to client data from OST struct */
 struct filter_client_data;
 struct filter_export_data {
-        struct list_head           fed_open_head; //files to close on disconnect
         spinlock_t                 fed_lock;      /* protects fed_open_head */
         struct filter_client_data *fed_fcd;
         loff_t                     fed_lr_off;
@@ -54,7 +65,9 @@ struct obd_export {
         struct obd_uuid           exp_client_uuid;
         struct list_head          exp_obd_chain;
         struct obd_device        *exp_obd;
+        struct obd_import        *exp_imp_reverse;  /* to make rpc's backwards */
         struct ptlrpc_connection *exp_connection;
+        __u32                     exp_conn_cnt;
         struct ldlm_export_data   exp_ldlm_data;
         struct ptlrpc_request    *exp_outstanding_reply;
         time_t                    exp_last_request_time;
@@ -64,14 +77,15 @@ struct obd_export {
         union {
                 struct mds_export_data    eu_mds_data;
                 struct filter_export_data eu_filter_data;
-                struct lov_export_data    eu_lov_data;
-                struct ec_export_data     eu_ec_data;
+                struct ec_export_data     eu_ec_data;         
+                struct osc_export_data    eu_osc_data;
         } u;
 };
 
 #define exp_mds_data    u.eu_mds_data
 #define exp_lov_data    u.eu_lov_data
 #define exp_filter_data u.eu_filter_data
+#define exp_osc_data    u.eu_osc_data
 #define exp_ec_data     u.eu_ec_data
 
 extern struct obd_export *class_conn2export(struct lustre_handle *conn);
diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h
index 72b2292e45a288b3ec284c842b57fc69e206d7b0..8446e5b12527dcdabd787072c7c64df30ed317e7 100644
--- a/lustre/include/linux/lustre_fsfilt.h
+++ b/lustre/include/linux/lustre_fsfilt.h
@@ -46,23 +46,32 @@ struct fsfilt_operations {
         void   *(* fs_brw_start)(int objcount, struct fsfilt_objinfo *fso,
                                  int niocount, void *desc_private);
         int     (* fs_commit)(struct inode *inode, void *handle,int force_sync);
+        int     (* fs_commit_async)(struct inode *inode, void *handle,
+                                        void **wait_handle);
+        int     (* fs_commit_wait)(struct inode *inode, void *handle);
         int     (* fs_setattr)(struct dentry *dentry, void *handle,
                                struct iattr *iattr, int do_trunc);
+        int     (* fs_iocontrol)(struct inode *inode, struct file *file,
+                                 unsigned int cmd, unsigned long arg);
         int     (* fs_set_md)(struct inode *inode, void *handle, void *md,
                               int size);
         int     (* fs_get_md)(struct inode *inode, void *md, int size);
         ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count,
                                 loff_t *offset);
-        int     (* fs_journal_data)(struct file *file);
-        int     (* fs_set_last_rcvd)(struct obd_device *obd, __u64 last_rcvd,
-                                     void *handle, fsfilt_cb_t cb_func,
-                                     void *cb_data);
+        int     (* fs_add_journal_cb)(struct obd_device *obd, __u64 last_rcvd,
+                                      void *handle, fsfilt_cb_t cb_func,
+                                      void *cb_data);
         int     (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs);
         int     (* fs_sync)(struct super_block *sb);
+        int     (* fs_map_inode_page)(struct inode *inode, struct page *page,
+                                      unsigned long *blocks, int *created,
+                                      int create);
         int     (* fs_prep_san_write)(struct inode *inode, long *blocks,
                                       int nblocks, loff_t newsize);
-        int     (* fs_write_record)(struct file *, void *, int size, loff_t *);
+        int     (* fs_write_record)(struct file *, void *, int size, loff_t *,
+                                    int force_sync);
         int     (* fs_read_record)(struct file *, void *, int size, loff_t *);
+        int     (* fs_setup)(struct super_block *sb);
 };
 
 extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops);
@@ -141,6 +150,30 @@ static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode,
         return rc;
 }
 
+static inline int fsfilt_commit_async(struct obd_device *obd,
+                                         struct inode *inode,
+                                         void *handle,
+                                         void **wait_handle)
+{
+        unsigned long now = jiffies;
+        int rc = obd->obd_fsops->fs_commit_async(inode, handle, wait_handle);
+        CDEBUG(D_HA, "committing handle %p (async)\n", *wait_handle);
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+        return rc;
+}
+
+static inline int fsfilt_commit_wait(struct obd_device *obd, struct inode *inode,
+                                        void *handle)
+{
+        unsigned long now = jiffies;
+        int rc = obd->obd_fsops->fs_commit_wait(inode, handle);
+        CDEBUG(D_HA, "waiting for completion %p\n", handle);
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+        return rc;
+}
+
 static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry,
                                  void *handle, struct iattr *iattr,int do_trunc)
 {
@@ -152,6 +185,13 @@ static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry,
         return rc;
 }
 
+static inline int fsfilt_iocontrol(struct obd_device *obd, struct inode *inode,
+                                   struct file *file, unsigned int cmd,
+                                   unsigned long arg)
+{
+        return obd->obd_fsops->fs_iocontrol(inode, file, cmd, arg);
+}
+
 static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode,
                                 void *handle, void *md, int size)
 {
@@ -171,28 +211,32 @@ static inline ssize_t fsfilt_readpage(struct obd_device *obd,
         return obd->obd_fsops->fs_readpage(file, buf, count, offset);
 }
 
-static inline int fsfilt_journal_data(struct obd_device *obd, struct file *file)
+static inline int fsfilt_add_journal_cb(struct obd_device *obd, __u64 last_rcvd,
+                                        void *handle, fsfilt_cb_t cb_func,
+                                        void *cb_data)
 {
-        return obd->obd_fsops->fs_journal_data(file);
+        return obd->obd_fsops->fs_add_journal_cb(obd, last_rcvd, handle,
+                                                 cb_func, cb_data);
 }
 
-static inline int fsfilt_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd,
-                                       void *handle, fsfilt_cb_t cb_func,
-                                       void *cb_data)
+static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *sb,
+                                struct obd_statfs *osfs)
 {
-        return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd, handle,
-                                                cb_func, cb_data);
+        return obd->obd_fsops->fs_statfs(sb, osfs);
 }
 
-static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *fs,
-                                struct obd_statfs *osfs)
+static inline int fsfilt_sync(struct obd_device *obd, struct super_block *sb)
 {
-        return obd->obd_fsops->fs_statfs(fs, osfs);
+        return obd->obd_fsops->fs_sync(sb);
 }
 
-static inline int fsfilt_sync(struct obd_device *obd, struct super_block *fs)
+static inline int fsfilt_map_inode_page(struct obd_device *obd,
+                                        struct inode *inode, struct page *page,
+                                        unsigned long *blocks, int *created,
+                                        int create)
 {
-        return obd->obd_fsops->fs_sync(fs);
+        return obd->obd_fsops->fs_map_inode_page(inode, page, blocks, created,
+                                                 create);
 }
 
 static inline int fs_prep_san_write(struct obd_device *obd,
@@ -212,9 +256,17 @@ static inline int fsfilt_read_record(struct obd_device *obd, struct file *file,
 }
 
 static inline int fsfilt_write_record(struct obd_device *obd, struct file *file,
-                                      void *buf, loff_t size, loff_t *offs)
+                                      void *buf, loff_t size, loff_t *offs,
+                                      int force_sync)
+{
+        return obd->obd_fsops->fs_write_record(file, buf, size,offs,force_sync);
+}
+
+static inline int fsfilt_setup(struct obd_device *obd, struct super_block *fs)
 {
-        return obd->obd_fsops->fs_write_record(file, buf, size, offs);
+        if (obd->obd_fsops->fs_setup)
+                return obd->obd_fsops->fs_setup(fs);
+        return 0;
 }
 
 #endif /* __KERNEL__ */
diff --git a/lustre/include/linux/lustre_ha.h b/lustre/include/linux/lustre_ha.h
index 8493f91212ba1d524a1417864410338d5f459060..4dfc81d92475df15f9bf2589784de49df32f4f0e 100644
--- a/lustre/include/linux/lustre_ha.h
+++ b/lustre/include/linux/lustre_ha.h
@@ -10,9 +10,9 @@ struct obd_export;
 struct obd_device;
 struct ptlrpc_request;
 
+
 void ptlrpc_run_failed_import_upcall(struct obd_import *imp);
 void ptlrpc_run_recovery_over_upcall(struct obd_device *obd);
-int ptlrpc_reconnect_import(struct obd_import *imp);
 int ptlrpc_replay(struct obd_import *imp);
 int ptlrpc_resend(struct obd_import *imp);
 void ptlrpc_free_committed(struct obd_import *imp);
@@ -21,4 +21,5 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid);
 int ptlrpc_set_import_active(struct obd_import *imp, int active);
 void ptlrpc_fail_import(struct obd_import *imp, int generation);
 void ptlrpc_fail_export(struct obd_export *exp);
+
 #endif
diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h
index ffd9f1e6ed71955dfc0be25bdcae539076e04a18..e2e68460a6e38ffc3dd3dd0a1641ea366d8f101d 100644
--- a/lustre/include/linux/lustre_idl.h
+++ b/lustre/include/linux/lustre_idl.h
@@ -20,6 +20,13 @@
  *
  * Lustre wire protocol definitions.
  *
+ * All structs passing over the wire should be declared here (lov_mds_md
+ * being the lone exception).  Structs must be properly aligned to put
+ * 64-bit values on an 8-byte boundary.  Any structs being added here
+ * must also be added to utils/wirecheck.c and "make newwiretest" run
+ * to regenerate the utils/wiretest.c sources.  This allows us to verify
+ * that wire structs have the proper alignment/size on all architectures.
+ *
  * We assume all nodes are either little-endian or big-endian, and we
  * always send messages in the sender's native format.  The receiver
  * detects the message format by checking the 'magic' field of the message
@@ -48,6 +55,7 @@
 # include <linux/list.h>
 # include <linux/string.h> /* for strncpy, below */
 # include <asm/byteorder.h>
+# include <linux/fs.h> /* to check for FMODE_EXEC, lest we redefine */
 #else
 #ifdef __CYGWIN__
 # include <sys/types.h>
@@ -56,7 +64,12 @@
 # include <stdint.h>
 #endif
 # include <portals/list.h>
+# include <string.h>
 #endif
+
+/* Defn's shared with user-space. */
+#include <linux/lustre_user.h>
+
 /*
  * this file contains all data structures used in Lustre interfaces:
  * - obdo and obd_request records
@@ -69,7 +82,7 @@
  *  GENERAL STUFF
  */
 struct obd_uuid {
-        __u8 uuid[37];
+        __u8 uuid[40];
 };
 
 static inline int obd_uuid_equals(struct obd_uuid *u1, struct obd_uuid *u2)
@@ -83,8 +96,6 @@ static inline void obd_str2uuid(struct obd_uuid *uuid, char *tmp)
         uuid->uuid[sizeof(*uuid) - 1] = '\0';
 }
 
-extern struct obd_uuid lctl_fake_uuid;
-
 /* FOO_REQUEST_PORTAL is for incoming requests on the FOO
  * FOO_REPLY_PORTAL   is for incoming replies on the FOO
  * FOO_BULK_PORTAL    is for incoming bulk on the FOO
@@ -96,7 +107,7 @@ extern struct obd_uuid lctl_fake_uuid;
 #define OSC_REPLY_PORTAL                4
 //#define OSC_BULK_PORTAL               5
 #define OST_REQUEST_PORTAL              6
-//#define OST_REPLY_PORTAL              7
+#define OST_CREATE_PORTAL               7
 #define OST_BULK_PORTAL                 8
 //#define MDC_REQUEST_PORTAL            9
 #define MDC_REPLY_PORTAL               10
@@ -125,24 +136,23 @@ extern struct obd_uuid lctl_fake_uuid;
 #define SVC_STOPPING            16
 #define SVC_STOPPED             32
 
-#define LUSTRE_CONN_NEW          1
-#define LUSTRE_CONN_CON          2
-#define LUSTRE_CONN_NOTCONN      3
-#define LUSTRE_CONN_RECOVER      4
-#define LUSTRE_CONN_FULL         5
-
 /* packet types */
 #define PTL_RPC_MSG_REQUEST 4711
 #define PTL_RPC_MSG_ERR     4712
 #define PTL_RPC_MSG_REPLY   4713
 
 #define PTLRPC_MSG_MAGIC    0x0BD00BD0
-#define PTLRPC_MSG_VERSION  0x00040002
+
+
+#define PTLRPC_MSG_VERSION  0x00000003
+#define LUSTRE_MDS_VERSION  (0x00040000|PTLRPC_MSG_VERSION)
+#define LUSTRE_OST_VERSION  (0x00040000|PTLRPC_MSG_VERSION)
+#define LUSTRE_DLM_VERSION  (0x00040000|PTLRPC_MSG_VERSION)
 
 struct lustre_handle {
         __u64 cookie;
 };
-#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabe
+#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabeULL
 
 /* we depend on this structure to be 8-byte aligned */
 /* this type is only endian-adjusted in lustre_unpack_msg() */
@@ -157,15 +167,11 @@ struct lustre_msg {
         __u64 transno;
         __u32 status;
         __u32 flags;
+        __u32 conn_cnt;
         __u32 bufcount;
         __u32 buflens[0];
 };
 
-static inline int lustre_msg_swabbed (struct lustre_msg *msg)
-{
-        return (msg->magic == __swab32(PTLRPC_MSG_MAGIC));
-}
-
 /* Flags that are operation-specific go in the top 16 bits. */
 #define MSG_OP_FLAG_MASK   0xffff0000
 #define MSG_OP_FLAG_SHIFT  16
@@ -191,6 +197,11 @@ static inline void lustre_msg_set_flags(struct lustre_msg *msg, int flags)
         lustre_msg_add_flags(msg, flags);
 }
 
+static inline void lustre_msg_clear_flags(struct lustre_msg *msg, int flags)
+{
+        msg->flags &= ~(MSG_GEN_FLAG_MASK & flags);
+}
+
 static inline int lustre_msg_get_op_flags(struct lustre_msg *msg)
 {
         return (msg->flags >> MSG_OP_FLAG_SHIFT);
@@ -214,7 +225,7 @@ static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags)
 #define MSG_CONNECT_RECOVERING  0x1
 #define MSG_CONNECT_RECONNECT   0x2
 #define MSG_CONNECT_REPLAYABLE  0x4
-#define MSG_CONNECT_PEER        0x8
+//#define MSG_CONNECT_PEER        0x8
 
 /*
  *   OST requests: OBDO & OBD request records
@@ -238,13 +249,11 @@ typedef enum {
         OST_STATFS     = 13,
         OST_SAN_READ   = 14,
         OST_SAN_WRITE  = 15,
-        OST_SYNCFS     = 16,
+        OST_SYNC       = 16,
         OST_SET_INFO   = 17,
         OST_LAST_OPC
 } ost_cmd_t;
 #define OST_FIRST_OPC  OST_REPLY
-/* When adding OST RPC opcodes, please update 
- * LAST/FIRST macros used in ptlrpc/ptlrpc_internals.h */
 
 typedef uint64_t        obd_id;
 typedef uint64_t        obd_gr;
@@ -260,11 +269,13 @@ typedef uint64_t        obd_rdev;
 typedef uint32_t        obd_flag;
 typedef uint32_t        obd_count;
 
-#define OBD_FL_INLINEDATA       (0x00000001)
-#define OBD_FL_OBDMDEXISTS      (0x00000002)
+#define OBD_FL_INLINEDATA   (0x00000001)
+#define OBD_FL_OBDMDEXISTS  (0x00000002)
+#define OBD_FL_DELORPHAN    (0x00000004) /* if set in o_flags delete orphans */
+#define OBD_FL_NORPC        (0x00000008) // if set in o_flags set in OSC not OST
+#define OBD_FL_IDONLY       (0x00000010) // if set in o_flags only adjust obj id
 
-#define OBD_INLINESZ    60
-#define FD_OSTDATA_SIZE sizeof(struct obd_client_handle)
+#define OBD_INLINESZ    64
 
 /* Note: 64-bit types are 64-bit aligned in structure */
 struct obdo {
@@ -285,26 +296,52 @@ struct obdo {
         obd_count               o_generation;
         obd_flag                o_valid;        /* hot fields in this obdo */
         obd_flag                o_obdflags;
-        __u32                   o_easize;
-        char                    o_inline[OBD_INLINESZ];
+        __u32                   o_easize;       /* epoch in ost writes */
+        char                    o_inline[OBD_INLINESZ]; /* fid in ost writes */
 };
 
 extern void lustre_swab_obdo (struct obdo *o);
 
-struct lov_object_id { /* per-child structure */
-        __u64 l_object_id;
+#define LOV_MAGIC_V1      0x0BD10BD0
+#define LOV_MAGIC         LOV_MAGIC_V1
+
+#define LOV_PATTERN_RAID0 0x001   /* stripes are used round-robin */
+#define LOV_PATTERN_RAID1 0x002   /* stripes are mirrors of each other */
+#define LOV_PATTERN_FIRST 0x100   /* first stripe is not in round-robin */
+
+#define lov_ost_data lov_ost_data_v1
+struct lov_ost_data_v1 {          /* per-stripe data structure (little-endian)*/
+        __u64 l_object_id;        /* OST object ID */
+        __u64 l_object_gr;        /* OST object group (creating MDS number) */
+        __u32 l_ost_gen;          /* generation of this l_ost_idx */
+        __u32 l_ost_idx;          /* OST index in LOV (lov_tgt_desc->tgts) */
 };
 
-#define LOV_MAGIC  0x0BD00BD0
+#define lov_mds_md lov_mds_md_v1
+struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
+        __u32 lmm_magic;          /* magic number = LOV_MAGIC_V1 */
+        __u32 lmm_pattern;        /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+        __u64 lmm_object_id;      /* LOV object ID */
+        __u64 lmm_object_gr;      /* LOV object group */
+        __u32 lmm_stripe_size;    /* size of stripe in bytes */
+        __u32 lmm_stripe_count;   /* num stripes in use for this object */
+        struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+};
+
+#define LOV_MAGIC_V0      0x0BD00BD0
+
+struct lov_ost_data_v0 {          /* per-stripe data structure (little-endian)*/
+        __u64 l_object_id;        /* OST object ID */
+};
 
-struct lov_mds_md {
-        __u32 lmm_magic;
-        __u64 lmm_object_id;       /* lov object id */
-        __u32 lmm_stripe_size;     /* size of the stripe */
-        __u32 lmm_stripe_offset;   /* starting stripe offset in lmm_objects */
-        __u16 lmm_stripe_count;    /* number of stipes in use for this object */
-        __u16 lmm_ost_count;       /* how many OST idx are in this LOV md */
-        struct lov_object_id lmm_objects[0];
+struct lov_mds_md_v0 {            /* LOV EA mds/wire data (little-endian) */
+        __u32 lmm_magic;          /* magic number = LOV_MAGIC_V0 */
+        __u64 lmm_object_id;      /* LOV object ID */
+        __u32 lmm_stripe_size;    /* size of the stripe in bytes (not RAID1) */
+        __u32 lmm_stripe_offset;  /* starting stripe offset in lmm_objects */
+        __u16 lmm_stripe_count;   /* number of stipes in use for this object */
+        __u16 lmm_ost_count;      /* how many OST idx are in this LOV md */
+        struct lov_ost_data_v0 lmm_objects[0];
 } __attribute__((packed));
 
 #define OBD_MD_FLALL    (0xffffffff)
@@ -332,10 +369,14 @@ struct lov_mds_md {
 #define OBD_MD_FLQOS    (0x00200000)    /* quality of service stats */
 #define OBD_MD_FLOSCOPQ (0x00400000)    /* osc opaque data */
 #define OBD_MD_FLCOOKIE (0x00800000)    /* log cancellation cookie */
+#define OBD_MD_FLGROUP  (0x01000000)    /* group */
+#define OBD_MD_FLIFID   (0x02000000)    /* ->ost write inline fid */
+#define OBD_MD_FLEPOCH  (0x04000000)    /* ->ost write easize is epoch */
 #define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS | OBD_MD_LINKNAME|\
                            OBD_MD_FLEASIZE | OBD_MD_FLHANDLE | OBD_MD_FLCKSUM|\
                            OBD_MD_FLQOS | OBD_MD_FLOSCOPQ | OBD_MD_FLCOOKIE))
 
+
 static inline struct lustre_handle *obdo_handle(struct obdo *oa)
 {
         return (struct lustre_handle *)oa->o_inline;
@@ -346,6 +387,8 @@ static inline struct llog_cookie *obdo_logcookie(struct obdo *oa)
         return (struct llog_cookie *)(oa->o_inline +
                                       sizeof(struct lustre_handle));
 }
+/* don't forget obdo_fid which is way down at the bottom so it can 
+ * come after the definition of llog_cookie */
 
 struct obd_statfs {
         __u64           os_type;
@@ -371,7 +414,7 @@ extern void lustre_swab_obd_statfs (struct obd_statfs *os);
 #define OBD_BRW_CREATE     0x04
 #define OBD_BRW_SYNC       0x08
 #define OBD_BRW_CHECK      0x10
-#define OBD_BRW_FROM_GRANT 0x20
+#define OBD_BRW_FROM_GRANT 0x20 /* the osc manages this under llite */
 
 #define OBD_OBJECT_EOF 0xffffffffffffffffULL
 
@@ -380,7 +423,7 @@ struct obd_ioobj {
         obd_gr               ioo_gr;
         __u32                ioo_type;
         __u32                ioo_bufcnt;
-} __attribute__((packed));
+};
 
 extern void lustre_swab_obd_ioobj (struct obd_ioobj *ioo);
 
@@ -389,7 +432,7 @@ struct niobuf_remote {
         __u64 offset;
         __u32 len;
         __u32 flags;
-} __attribute__((packed));
+};
 
 extern void lustre_swab_niobuf_remote (struct niobuf_remote *nbr);
 
@@ -402,6 +445,7 @@ struct ost_body {
 };
 
 extern void lustre_swab_ost_body (struct ost_body *b);
+extern void lustre_swab_ost_last_id(obd_id *id);
 
 /*
  *   MDS REQ RECORDS
@@ -418,17 +462,16 @@ typedef enum {
         MDS_DISCONNECT   = 39,
         MDS_GETSTATUS    = 40,
         MDS_STATFS       = 41,
-        MDS_GETLOVINFO   = 42,
-        MDS_PIN          = 43,
-        MDS_UNPIN        = 44,
+        MDS_PIN          = 42,
+        MDS_UNPIN        = 43,
+        MDS_SYNC         = 44,
+        MDS_DONE_WRITING = 45,
         MDS_LAST_OPC
 } mds_cmd_t;
 #define MDS_FIRST_OPC    MDS_GETATTR
-/* When adding MDS RPC opcodes, please update 
- * LAST/FIRST macros used in ptlrpc/ptlrpc_internals.h */
 
 /*
- * Do not exceed 63 
+ * Do not exceed 63
  */
 
 #define REINT_SETATTR  1
@@ -472,12 +515,7 @@ struct mds_status_req {
 
 extern void lustre_swab_mds_status_req (struct mds_status_req *r);
 
-struct mds_fileh_body {
-        struct ll_fid f_fid;
-        struct lustre_handle f_handle;
-};
-
-extern void lustre_swab_mds_fileh_body (struct mds_fileh_body *f);
+#define MDS_BFLAG_UNCOMMITTED_WRITES   0x1
 
 struct mds_body {
         struct ll_fid  fid1;
@@ -485,6 +523,7 @@ struct mds_body {
         struct lustre_handle handle;
         __u64          size;   /* Offset, in the case of MDS_READPAGE */
         __u64          blocks; /* XID, in the case of MDS_READPAGE */
+        __u64          io_epoch;
         __u32          ino;   /* make this a __u64 */
         __u32          valid;
         __u32          fsuid;
@@ -496,18 +535,17 @@ struct mds_body {
         __u32          mtime;
         __u32          ctime;
         __u32          atime;
-        __u32          flags;
+        __u32          flags; /* from vfs for pin/unpin, MDS_BFLAG for close */
         __u32          rdev;
         __u32          nlink; /* #bytes to read in the case of MDS_READPAGE */
         __u32          generation;
         __u32          suppgid;
         __u32          eadatasize;
+        __u32          packing;
 };
 
 extern void lustre_swab_mds_body (struct mds_body *b);
 
-/* This is probably redundant with OBD_MD_FLEASIZE, but we need an audit */
-#define MDS_OPEN_HAS_EA 1 /* this open has an EA, for a delayed create*/
 
 /* MDS update records */
 
@@ -520,7 +558,7 @@ struct mds_rec_setattr {
         __u32           sa_fsuid;
         __u32           sa_fsgid;
         __u32           sa_cap;
-        __u32           sa_reserved;
+        __u32           sa_suppgid;
         __u32           sa_valid;
         struct ll_fid   sa_fid;
         __u32           sa_mode;
@@ -531,7 +569,6 @@ struct mds_rec_setattr {
         __u64           sa_atime;
         __u64           sa_mtime;
         __u64           sa_ctime;
-        __u32           sa_suppgid;
 };
 
 /* Remove this once we declare it in include/linux/fs.h (v21 kernel patch?) */
@@ -541,6 +578,23 @@ struct mds_rec_setattr {
 
 extern void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa);
 
+#ifndef FMODE_READ
+#define FMODE_READ               00000001
+#define FMODE_WRITE              00000002
+#endif
+#ifndef FMODE_EXEC
+#define FMODE_EXEC               00000004
+#endif
+#define MDS_OPEN_CREAT           00000100
+#define MDS_OPEN_EXCL            00000200
+#define MDS_OPEN_TRUNC           00001000
+#define MDS_OPEN_APPEND          00002000
+#define MDS_OPEN_SYNC            00010000
+#define MDS_OPEN_DIRECTORY       00200000
+
+#define MDS_OPEN_DELAY_CREATE  0100000000 /* delay initial object create */
+#define MDS_OPEN_HAS_EA      010000000000 /* specify object create pattern */
+
 struct mds_rec_create {
         __u32           cr_opcode;
         __u32           cr_fsuid;
@@ -550,11 +604,10 @@ struct mds_rec_create {
         __u32           cr_mode;
         struct ll_fid   cr_fid;
         struct ll_fid   cr_replayfid;
-        __u32           cr_uid;
-        __u32           cr_gid;
         __u64           cr_time;
         __u64           cr_rdev;
         __u32           cr_suppgid;
+        __u32           cr_packing;
 };
 
 extern void lustre_swab_mds_rec_create (struct mds_rec_create *cr);
@@ -568,6 +621,7 @@ struct mds_rec_link {
         __u32           lk_suppgid2;
         struct ll_fid   lk_fid1;
         struct ll_fid   lk_fid2;
+        __u64           lk_time;
 };
 
 extern void lustre_swab_mds_rec_link (struct mds_rec_link *lk);
@@ -577,11 +631,11 @@ struct mds_rec_unlink {
         __u32           ul_fsuid;
         __u32           ul_fsgid;
         __u32           ul_cap;
-        __u32           ul_reserved;
-        __u32           ul_mode;
         __u32           ul_suppgid;
+        __u32           ul_mode;
         struct ll_fid   ul_fid1;
         struct ll_fid   ul_fid2;
+        __u64           ul_time;
 };
 
 extern void lustre_swab_mds_rec_unlink (struct mds_rec_unlink *ul);
@@ -595,6 +649,7 @@ struct mds_rec_rename {
         __u32           rn_suppgid2;
         struct ll_fid   rn_fid1;
         struct ll_fid   rn_fid2;
+        __u64           rn_time;
 };
 
 extern void lustre_swab_mds_rec_rename (struct mds_rec_rename *rn);
@@ -603,11 +658,8 @@ extern void lustre_swab_mds_rec_rename (struct mds_rec_rename *rn);
  *  LOV data structures
  */
 
-#define LOV_RAID0   0
-#define LOV_RAIDRR  1
-
 #define LOV_MAX_UUID_BUFFER_SIZE  8192
-/* The size of the buffer the lov/mdc reserves for the 
+/* The size of the buffer the lov/mdc reserves for the
  * array of UUIDs returned by the MDS.  With the current
  * protocol, this will limit the max number of OSTs per LOV */
 
@@ -615,9 +667,9 @@ struct lov_desc {
         __u32 ld_tgt_count;                /* how many OBD's */
         __u32 ld_active_tgt_count;         /* how many active */
         __u32 ld_default_stripe_count;     /* how many objects are used */
+        __u32 ld_pattern;                  /* PATTERN_RAID0, PATTERN_RAID1 */
         __u64 ld_default_stripe_size;      /* in bytes */
         __u64 ld_default_stripe_offset;    /* in bytes */
-        __u32 ld_pattern;                  /* RAID 0,1 etc */
         struct obd_uuid ld_uuid;
 };
 
@@ -636,10 +688,8 @@ typedef enum {
         LDLM_LAST_OPC
 } ldlm_cmd_t;
 #define LDLM_FIRST_OPC LDLM_ENQUEUE
-/* When adding LDLM RPC opcodes, please update 
- * LAST/FIRST macros used in ptlrpc/ptlrpc_internals.h */
 
-#define RES_NAME_SIZE 3
+#define RES_NAME_SIZE 4
 #define RES_VERSION_SIZE 4
 
 struct ldlm_res_id {
@@ -663,7 +713,26 @@ struct ldlm_extent {
         __u64 end;
 };
 
-extern void lustre_swab_ldlm_extent (struct ldlm_extent *e);
+struct ldlm_flock {
+        __u64 start;
+        __u64 end;
+        __u64 blocking_export;
+        pid_t blocking_pid;
+        pid_t pid;
+};
+
+/* it's important that the fields of the ldlm_extent structure match
+ * the first fields of the ldlm_flock structure because there is only
+ * one ldlm_swab routine to process the ldlm_policy_data_t union. if
+ * this ever changes we will need to swab the union differently based
+ * on the resource type. */
+
+typedef union {
+        struct ldlm_extent l_extent;
+        struct ldlm_flock  l_flock;
+} ldlm_policy_data_t;
+
+extern void lustre_swab_ldlm_policy_data (ldlm_policy_data_t *d);
 
 struct ldlm_intent {
         __u64 opc;
@@ -677,7 +746,7 @@ struct ldlm_resource_desc {
         __u32 lr_type;
         struct ldlm_res_id lr_name;
         __u32 lr_version[RES_VERSION_SIZE];
-};
+} __attribute__((packed));
 
 extern void lustre_swab_ldlm_resource_desc (struct ldlm_resource_desc *r);
 
@@ -685,9 +754,9 @@ struct ldlm_lock_desc {
         struct ldlm_resource_desc l_resource;
         ldlm_mode_t l_req_mode;
         ldlm_mode_t l_granted_mode;
-        struct ldlm_extent l_extent;
+        ldlm_policy_data_t l_policy_data;
         __u32 l_version[RES_VERSION_SIZE];
-};
+} __attribute__((packed));
 
 extern void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l);
 
@@ -696,7 +765,7 @@ struct ldlm_request {
         struct ldlm_lock_desc lock_desc;
         struct lustre_handle lock_handle1;
         struct lustre_handle lock_handle2;
-};
+} __attribute__((packed));
 
 extern void lustre_swab_ldlm_request (struct ldlm_request *rq);
 
@@ -705,7 +774,7 @@ struct ldlm_reply {
         __u32 lock_mode;
         struct ldlm_res_id lock_resource_name;
         struct lustre_handle lock_handle;
-        struct ldlm_extent lock_extent;   /* XXX make this policy 1 &2 */
+        ldlm_policy_data_t lock_policy_data;
         __u64  lock_policy_res1;
         __u64  lock_policy_res2;
 };
@@ -725,8 +794,6 @@ typedef enum {
         PTLBD_LAST_OPC
 } ptlbd_cmd_t;
 #define PTLBD_FIRST_OPC PTLBD_QUERY
-/* When adding PTLBD RPC opcodes, please update 
- * LAST/FIRST macros used in ptlrpc/ptlrpc_internals.h */
 
 struct ptlbd_op {
         __u16 op_cmd;
@@ -775,89 +842,152 @@ extern void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r);
 /* Identifier for a single log object */
 struct llog_logid {
         __u64                   lgl_oid;
+        __u64                   lgl_ogr;
         __u32                   lgl_ogen;
-};
+} __attribute__((packed));
 
 /* Log data record types - there is no specific reason that these need to
  * be related to the RPC opcodes, but no reason not to (may be handy later?)
  */
 typedef enum {
-        OST_CREATE_REC = 0x10600000 | (OST_CREATE << 8),
-        OST_ORPHAN_REC = 0x10600000 | (OST_DESTROY << 8),
-        MDS_UNLINK_REC = 0x10610000 | (MDS_REINT << 8) | REINT_UNLINK,
-        LLOG_CATALOG_MAGIC = 0x1062e67d,
-        LLOG_OBJECT_MAGIC = 0x10645539,
+        OST_SZ_REC       = 0x10600000 | (OST_SAN_WRITE << 8),
+        OST_RAID1_REC    = 0x10600000 | ((OST_SAN_WRITE + 1) << 8),
+        MDS_UNLINK_REC   = 0x10610000 | (MDS_REINT << 8) | REINT_UNLINK,
+        OBD_CFG_REC      = 0x10620000,
+        PTL_CFG_REC      = 0x10630000,
+        LLOG_HDR_MAGIC   = 0x10645539,
+        LLOG_LOGID_MAGIC = 0x1064553a,
 } llog_op_type;
 
-/* Log record header - stored in originating host endian order (use magic to
- * check order).
- * Each record must start with this struct, end with a __u32 for the struct
- * length, and be a multiple of 64 bits in size.
+/* Log record header - stored in little endian order.
+ * Each record must start with this struct, end with a llog_rec_tail,
+ * and be a multiple of 256 bits in size.
  */
-struct llog_trans_hdr {
-        __u32                   lth_len;
-        __u32                   lth_type;
+struct llog_rec_hdr {
+        __u32                   lrh_len;
+        __u32                   lrh_index;
+        __u32                   lrh_type;
+        __u32                   padding;
 };
 
+struct llog_rec_tail {
+        __u32 lrt_len;
+        __u32 lrt_index;
+};
+
+struct llog_logid_rec {
+        struct llog_rec_hdr     lid_hdr;
+        struct llog_logid       lid_id;
+        __u32                   padding[5];
+        struct llog_rec_tail    lid_tail;
+} __attribute__((packed));
+
 struct llog_create_rec {
-        struct llog_trans_hdr   lcr_hdr;
+        struct llog_rec_hdr     lcr_hdr;
         struct ll_fid           lcr_fid;
         obd_id                  lcr_oid;
         obd_count               lcr_ogen;
-        __u32                   lcr_end_len;
+        __u32                   padding[3];
+        struct llog_rec_tail    lcr_tail;
 } __attribute__((packed));
 
 struct llog_orphan_rec {
-        struct llog_trans_hdr   lor_hdr;
+        struct llog_rec_hdr     lor_hdr;
         obd_id                  lor_oid;
         obd_count               lor_ogen;
-        __u32                   lor_end_len;
+        __u32                   padding[7];
+        struct llog_rec_tail    lor_tail;
 } __attribute__((packed));
 
 struct llog_unlink_rec {
-        struct llog_trans_hdr   lur_hdr;
+        struct llog_rec_hdr     lur_hdr;
         obd_id                  lur_oid;
         obd_count               lur_ogen;
-        __u32                   lur_end_len;
+        __u32                   padding[7];
+        struct llog_rec_tail    lur_tail;
 } __attribute__((packed));
 
-/* On-disk header structure of each log object - stored in creating host
- * endian order, with the exception of the bitmap - stored in little endian
- * order so that we can use ext2_{clear,set,test}_bit() for proper/optimized
- * little-endian handling of bitmaps (which are otherwise a pain to handle).
- */
+struct llog_size_change_rec {
+        struct llog_rec_hdr     lsc_hdr;
+        struct ll_fid           lsc_fid;
+        __u32                   lsc_io_epoch;
+        __u32                   padding[5];
+        struct llog_rec_tail    lsc_tail;
+} __attribute__((packed));
+
+/* On-disk header structure of each log object, stored in little endian order */
 #define LLOG_CHUNK_SIZE         4096
 #define LLOG_HEADER_SIZE        (96)
 #define LLOG_BITMAP_BYTES       (LLOG_CHUNK_SIZE - LLOG_HEADER_SIZE)
 
-#define LLOG_MIN_REC_SIZE       (16) /* round(struct llog_trans_hdr+end_len) */
+#define LLOG_MIN_REC_SIZE       (32) /* round(struct llog_rec_hdr+end_len) */
+
+/* flags for the logs */
+#define LLOG_F_ZAP_WHEN_EMPTY   0x1
+#define LLOG_F_IS_CAT           0x2
+#define LLOG_F_IS_PLAIN         0x4
 
-struct llog_object_hdr {
-        struct llog_trans_hdr   llh_hdr;
+struct llog_log_hdr {
+        struct llog_rec_hdr     llh_hdr;
         __u64                   llh_timestamp;
         __u32                   llh_count;
-        __u16                   llh_bitmap_offset;
-        __u16                   llh_unused;
+        __u32                   llh_bitmap_offset;
+        __u32                   llh_size;
+        __u32                   llh_flags;
+        __u32                   llh_cat_idx;
         struct obd_uuid         llh_tgtuuid;
-        __u8                    llh_padding[3];
-        __u32                   llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32)-17];
+        __u32                   llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32) - 23];
         __u32                   llh_bitmap[LLOG_BITMAP_BYTES/sizeof(__u32)];
-        __u32                   llh_hdr_end_len;
-};
-
-static inline int llog_log_swabbed(struct llog_object_hdr *hdr)
-{
-        if (hdr->llh_hdr.lth_type == __swab32(LLOG_OBJECT_MAGIC))
-                return 1;
-        if (hdr->llh_hdr.lth_type == LLOG_OBJECT_MAGIC)
-                return 0;
-        return -1;
-}
+        struct llog_rec_tail    llh_tail;
+} __attribute__((packed));
 
 /* log cookies are used to reference a specific log file and a record therein */
 struct llog_cookie {
         struct llog_logid       lgc_lgl;
+        __u32                   lgc_subsys;
         __u32                   lgc_index;
+        __u32                   lgc_padding;
+} __attribute__((packed));
+
+/* llog protocol */
+enum llogd_rpc_ops {
+        LLOG_ORIGIN_HANDLE_CREATE       = 501,
+        LLOG_ORIGIN_HANDLE_NEXT_BLOCK   = 502,
+        LLOG_ORIGIN_HANDLE_READ_HEADER  = 503,
+        LLOG_ORIGIN_HANDLE_WRITE_REC    = 504,
+        LLOG_ORIGIN_HANDLE_CLOSE        = 505,
+        LLOG_ORIGIN_CONNECT             = 506,
+};
+
+struct llogd_body {
+        struct llog_logid  lgd_logid;
+        __u32 lgd_ctxt_idx;
+        __u32 lgd_llh_flags;
+        __u32 lgd_index;
+        __u32 lgd_saved_index;
+        __u32 lgd_len;
+        __u64 lgd_cur_offset;
+} __attribute__((packed));
+
+struct llog_ctxt_gen {
+        __u64 mnt_cnt;
+        __u64 conn_cnt;
 };
 
+struct llogd_conn_body {
+        struct llog_ctxt_gen    lgdc_gen;
+        struct llog_logid       lgdc_logid;
+        __u32                   lgdc_ctxt_idx;
+} __attribute__((packed));
+
+extern void lustre_swab_llogd_body (struct llogd_body *d);
+extern void lustre_swab_llog_hdr (struct llog_log_hdr *h);
+extern void lustre_swab_llogd_conn_body (struct llogd_conn_body *d);
+
+static inline struct ll_fid *obdo_fid(struct obdo *oa)
+{
+        return (struct ll_fid *)(oa->o_inline + sizeof(struct lustre_handle) +
+                                 sizeof(struct llog_cookie));
+}
+
 #endif
diff --git a/lustre/include/linux/lustre_import.h b/lustre/include/linux/lustre_import.h
index 9dc0a9238e5407d4bcfe56d3aef73687d74e9e42..59c21963d52a4430cf7c17582d6b2168b80d57db 100644
--- a/lustre/include/linux/lustre_import.h
+++ b/lustre/include/linux/lustre_import.h
@@ -13,6 +13,18 @@
 #include <linux/lustre_handles.h>
 #include <linux/lustre_idl.h>
 
+enum lustre_imp_state {
+//        LUSTRE_IMP_INVALID    = 1,
+        LUSTRE_IMP_NEW        = 2,
+        LUSTRE_IMP_DISCON     = 3,
+        LUSTRE_IMP_CONNECTING = 4,
+        LUSTRE_IMP_REPLAY     = 5,
+        LUSTRE_IMP_RECOVER    = 6,
+        LUSTRE_IMP_FULL       = 7,
+        LUSTRE_IMP_EVICTED    = 8,
+};
+
+
 struct obd_import {
         struct portals_handle     imp_handle;
         atomic_t                  imp_refcount;
@@ -30,20 +42,22 @@ struct obd_import {
         struct list_head          imp_delayed_list;
 
         struct obd_device        *imp_obd;
-        int                       imp_level;
+        struct semaphore          imp_recovery_sem;
+        enum lustre_imp_state     imp_state;
         int                       imp_generation;
+        __u32                     imp_conn_cnt;
         __u64                     imp_max_transno;
         __u64                     imp_peer_committed_transno;
         struct obd_uuid           imp_target_uuid; /* XXX -> lustre_name */
         struct lustre_handle      imp_remote_handle;
         unsigned long             imp_next_ping;
         
-        /* Protects flags, level, generation, *_list */
+        /* Protects flags, level, generation, conn_cnt, *_list */
         spinlock_t                imp_lock;
 
         /* flags */
         int                       imp_invalid:1, imp_replayable:1,
-                                  imp_dlm_fake:1;
+                                  imp_dlm_fake:1, imp_server_timeout:1;
         __u32                     imp_connect_op;
 };
 
@@ -67,7 +81,8 @@ void class_notify_import_observers(struct obd_import *imp, int event,
 #define IMP_EVENT_INACTIVE 2
 
 /* genops.c */
+struct obd_export;
+extern struct obd_import *class_exp2cliimp(struct obd_export *);
 extern struct obd_import *class_conn2cliimp(struct lustre_handle *);
-extern struct obd_import *class_conn2ldlmimp(struct lustre_handle *);
 
 #endif /* __IMPORT_H */
diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h
index 467132b56e80e8789d68e87931512881eab32d53..2a70b02f20ebbf8b47efeacbed9d780394ae6561 100644
--- a/lustre/include/linux/lustre_lib.h
+++ b/lustre/include/linux/lustre_lib.h
@@ -32,6 +32,7 @@
 # include <sys/types.h>
 #else
 # include <asm/semaphore.h>
+# include <linux/rwsem.h>
 # include <linux/sched.h>
 # include <linux/signal.h>
 # include <linux/types.h>
@@ -39,9 +40,11 @@
 #include <linux/portals_lib.h>
 #include <linux/kp30.h> /* XXX just for LASSERT! */
 #include <linux/lustre_idl.h>
+#include <linux/lustre_cfg.h>
 
 #ifndef LPU64
-#if BITS_PER_LONG > 32
+/* x86_64 has 64bit longs and defines u64 as long long */
+#if BITS_PER_LONG > 32 && !defined(__x86_64__)
 #define LPU64 "%lu"
 #define LPD64 "%ld"
 #define LPX64 "%#lx"
@@ -60,9 +63,11 @@ struct obd_export;
 #include <linux/lustre_ha.h>
 #include <linux/lustre_net.h>
 #include <linux/lustre_compat25.h>
+#include <linux/lvfs.h>
 
 int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler);
 int target_handle_disconnect(struct ptlrpc_request *req);
+void target_destroy_export(struct obd_export *exp);
 int target_handle_reconnect(struct lustre_handle *conn, struct obd_export *exp,
                             struct obd_uuid *cluuid);
 int target_handle_ping(struct ptlrpc_request *req);
@@ -78,25 +83,19 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
 
 /* client.c */
 
-int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf);
 int client_sanobd_setup(struct obd_device *obddev, obd_count len, void *buf);
-int client_obd_cleanup(struct obd_device * obddev, int flags);
 struct client_obd *client_conn2cli(struct lustre_handle *conn);
-struct obd_device *client_tgtuuid2obd(struct obd_uuid *tgtuuid);
 
-/* It is important that och_fh remain the first item in this structure: that
- * way, we don't have to re-pack the obdo's inline data before we send it to
- * the server, we can just send the whole struct unaltered. */
+struct mdc_open_data;
 struct obd_client_handle {
         struct lustre_handle och_fh;
         struct llog_cookie och_cookie;
-        struct ptlrpc_request *och_req;
+        struct mdc_open_data *och_mod;
         __u32 och_magic;
 };
 #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
 
 /* statfs_pack.c */
-struct statfs;
 void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs);
 void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs);
 
@@ -113,94 +112,13 @@ void l_lock(struct lustre_lock *);
 void l_unlock(struct lustre_lock *);
 int l_has_lock(struct lustre_lock *);
 
-/* simple.c */
-struct obd_ucred {
-        __u32 ouc_fsuid;
-        __u32 ouc_fsgid;
-        __u32 ouc_cap;
-        __u32 ouc_suppgid1;
-        __u32 ouc_suppgid2;
-};
-
-#define OBD_RUN_CTXT_MAGIC      0xC0FFEEAA
-#define OBD_CTXT_DEBUG          /* development-only debugging */
-struct obd_run_ctxt {
-        struct vfsmount *pwdmnt;
-        struct dentry   *pwd;
-        mm_segment_t     fs;
-        struct obd_ucred ouc;
-        int              ngroups;
-#ifdef OBD_CTXT_DEBUG
-        __u32            magic;
-#endif
-};
-
-
-#ifdef OBD_CTXT_DEBUG
-#define OBD_SET_CTXT_MAGIC(ctxt) (ctxt)->magic = OBD_RUN_CTXT_MAGIC
-#else
-#define OBD_SET_CTXT_MAGIC(ctxt) do {} while(0)
-#endif
-
-#ifdef __KERNEL__
-
-void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
-               struct obd_ucred *cred);
-void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
-              struct obd_ucred *cred);
-struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode);
-struct dentry *simple_mknod(struct dentry *dir, char *name, int mode);
-int lustre_fread(struct file *file, void *buf, int len, loff_t *off);
-int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off);
-int lustre_fsync(struct file *file);
-
-static inline void l_dput(struct dentry *de)
-{
-        if (!de || IS_ERR(de))
-                return;
-        //shrink_dcache_parent(de);
-        LASSERT(atomic_read(&de->d_count) > 0);
-        dput(de);
-}
-
-/* We need to hold the inode semaphore over the dcache lookup itself, or we
- * run the risk of entering the filesystem lookup path concurrently on SMP
- * systems, and instantiating two inodes for the same entry.  We still
- * protect against concurrent addition/removal races with the DLM locking.
- */
-static inline struct dentry *ll_lookup_one_len(char *fid_name,
-                                               struct dentry *dparent,
-                                               int fid_namelen)
-{
-        struct dentry *dchild;
-
-        down(&dparent->d_inode->i_sem);
-        dchild = lookup_one_len(fid_name, dparent, fid_namelen);
-        up(&dparent->d_inode->i_sem);
-
-        return dchild;
-}
-
-static inline void ll_sleep(int t)
-{
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(t * HZ);
-        set_current_state(TASK_RUNNING);
-}
-#endif
-
-#define LL_FID_NAMELEN         (16 + 1 + 8 + 1)
-static inline int ll_fid2str(char *str, __u64 id, __u32 generation)
-{
-        return sprintf(str, "%llx:%08x", (unsigned long long)id, generation);
-}
 
 #include <linux/portals_lib.h>
 
 /*
  *   OBD IOCTLS
  */
-#define OBD_IOCTL_VERSION 0x00010003
+#define OBD_IOCTL_VERSION 0x00010004
 
 struct obd_ioctl_data {
         uint32_t ioc_len;
@@ -220,6 +138,7 @@ struct obd_ioctl_data {
 
         uint64_t ioc_nid;
         uint32_t ioc_nal;
+        uint32_t ioc_type;
 
         /* buffers the kernel will treat as user pointers */
         uint32_t ioc_plen1;
@@ -259,59 +178,59 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
 static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
 {
         if (data->ioc_len > (1<<30)) {
-                printk("OBD ioctl: ioc_len larger than 1<<30\n");
+                printk("LustreError: OBD ioctl: ioc_len larger than 1<<30\n");
                 return 1;
         }
         if (data->ioc_inllen1 > (1<<30)) {
-                printk("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+                printk("LustreError: OBD ioctl: ioc_inllen1 larger than 1<<30\n");
                 return 1;
         }
         if (data->ioc_inllen2 > (1<<30)) {
-                printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+                printk("LustreError: OBD ioctl: ioc_inllen2 larger than 1<<30\n");
                 return 1;
         }
         if (data->ioc_inllen3 > (1<<30)) {
-                printk("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
+                printk("LustreError: OBD ioctl: ioc_inllen3 larger than 1<<30\n");
                 return 1;
         }
         if (data->ioc_inllen4 > (1<<30)) {
-                printk("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
+                printk("LustreError: OBD ioctl: ioc_inllen4 larger than 1<<30\n");
                 return 1;
         }
         if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
-                printk("OBD ioctl: inlbuf1 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: inlbuf1 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
-                printk("OBD ioctl: inlbuf2 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: inlbuf2 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
-                printk("OBD ioctl: inlbuf3 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: inlbuf3 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_inlbuf4 && !data->ioc_inllen4) {
-                printk("OBD ioctl: inlbuf4 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: inlbuf4 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_pbuf1 && !data->ioc_plen1) {
-                printk("OBD ioctl: pbuf1 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: pbuf1 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_pbuf2 && !data->ioc_plen2) {
-                printk("OBD ioctl: pbuf2 pointer but 0 length\n");
+                printk("LustreError: OBD ioctl: pbuf2 pointer but 0 length\n");
                 return 1;
         }
         if (data->ioc_plen1 && !data->ioc_pbuf1) {
-                printk("OBD ioctl: plen1 set but NULL pointer\n");
+                printk("LustreError: OBD ioctl: plen1 set but NULL pointer\n");
                 return 1;
         }
         if (data->ioc_plen2 && !data->ioc_pbuf2) {
-                printk("OBD ioctl: plen2 set but NULL pointer\n");
+                printk("LustreError: OBD ioctl: plen2 set but NULL pointer\n");
                 return 1;
         }
         if (obd_ioctl_packlen(data) != data->ioc_len) {
-                printk("OBD ioctl: packlen exceeds ioc_len (%d != %d)\n",
+                printk("LustreError: OBD ioctl: packlen exceeds ioc_len (%d != %d)\n",
                        obd_ioctl_packlen(data), data->ioc_len);
                 return 1;
         }
@@ -392,6 +311,7 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg)
         struct obd_ioctl_hdr hdr;
         struct obd_ioctl_data *data;
         int err;
+        int offset = 0;
         ENTRY;
 
         err = copy_from_user(&hdr, (void *)arg, sizeof(hdr));
@@ -412,7 +332,7 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg)
         }
 
         if (hdr.ioc_len < sizeof(struct obd_ioctl_data)) {
-                printk("OBD: user buffer too small for ioctl\n");
+                printk("LustreError: OBD: user buffer too small for ioctl\n");
                 return -EINVAL;
         }
 
@@ -440,24 +360,21 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg)
 
         if (data->ioc_inllen1) {
                 data->ioc_inlbuf1 = &data->ioc_bulk[0];
+                offset += size_round(data->ioc_inllen1);
         }
 
         if (data->ioc_inllen2) {
-                data->ioc_inlbuf2 = &data->ioc_bulk[0] +
-                        size_round(data->ioc_inllen1);
+                data->ioc_inlbuf2 = &data->ioc_bulk[0] + offset;
+                offset += size_round(data->ioc_inllen2);
         }
 
         if (data->ioc_inllen3) {
-                data->ioc_inlbuf3 = &data->ioc_bulk[0] +
-                        size_round(data->ioc_inllen1) +
-                        size_round(data->ioc_inllen2);
+                data->ioc_inlbuf3 = &data->ioc_bulk[0] + offset;
+                offset += size_round(data->ioc_inllen3);
         }
 
         if (data->ioc_inllen4) {
-                data->ioc_inlbuf4 = &data->ioc_bulk[0] +
-                        size_round(data->ioc_inllen1) +
-                        size_round(data->ioc_inllen2) + 
-                        size_round(data->ioc_inllen3) ;
+                data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset;
         }
 
         EXIT;
@@ -474,8 +391,6 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 }
 
 #define OBD_IOC_CREATE                 _IOR ('f', 101, long)
-#define OBD_IOC_SETUP                  _IOW ('f', 102, long)
-#define OBD_IOC_CLEANUP                _IO  ('f', 103      )
 #define OBD_IOC_DESTROY                _IOW ('f', 104, long)
 #define OBD_IOC_PREALLOCATE            _IOWR('f', 105, long)
 
@@ -490,8 +405,6 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 #define OBD_IOC_READ2                  _IOWR('f', 115, long)
 #define OBD_IOC_FORMAT                 _IOWR('f', 116, long)
 #define OBD_IOC_PARTITION              _IOWR('f', 117, long)
-#define OBD_IOC_ATTACH                 _IOWR('f', 118, long)
-#define OBD_IOC_DETACH                 _IOWR('f', 119, long)
 #define OBD_IOC_COPY                   _IOWR('f', 120, long)
 #define OBD_IOC_MIGR                   _IOWR('f', 121, long)
 #define OBD_IOC_PUNCH                  _IOWR('f', 122, long)
@@ -500,17 +413,13 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 #define OBD_IOC_BRW_READ               _IOWR('f', 125, long)
 #define OBD_IOC_BRW_WRITE              _IOWR('f', 126, long)
 #define OBD_IOC_NAME2DEV               _IOWR('f', 127, long)
-#define OBD_IOC_NEWDEV                 _IOWR('f', 128, long)
 #define OBD_IOC_LIST                   _IOWR('f', 129, long)
 #define OBD_IOC_UUID2DEV               _IOWR('f', 130, long)
 
-#define OBD_IOC_LOV_SET_CONFIG         _IOWR('f', 131, long)
 #define OBD_IOC_LOV_GET_CONFIG         _IOWR('f', 132, long)
-#define OBD_IOC_LOV_CONFIG             OBD_IOC_LOV_SET_CONFIG
 #define OBD_IOC_CLIENT_RECOVER         _IOW ('f', 133, long)
 
-#define OBD_IOC_OPEN                   _IOWR('f', 134, long)
-#define OBD_IOC_CLOSE                  _IOWR('f', 135, long)
+#define OBD_IOC_PING                   _IOWR('f', 135, long)
 
 #define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 139      )
 #define OBD_IOC_NO_TRANSNO             _IOW ('f', 140, long)
@@ -519,12 +428,26 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 
 #define OBD_GET_VERSION                _IOWR ('f', 144, long)
 
-#define OBD_IOC_ADD_UUID               _IOWR ('f', 145, long)
-#define OBD_IOC_DEL_UUID               _IOWR ('f', 146, long)
 #define OBD_IOC_CLOSE_UUID             _IOWR ('f', 147, long)
 
+#define OBD_IOC_LOV_SETSTRIPE            _IOW ('f', 154, long)
+#define OBD_IOC_LOV_GETSTRIPE            _IOW ('f', 155, long)
+
 #define OBD_IOC_MOUNTOPT               _IOWR('f', 170, long)
 
+#define OBD_IOC_RECORD                 _IOWR('f', 180, long)
+#define OBD_IOC_ENDRECORD              _IOWR('f', 181, long)
+#define OBD_IOC_PARSE                  _IOWR('f', 182, long)
+#define OBD_IOC_DORECORD               _IOWR('f', 183, long)
+#define OBD_IOC_PROCESS_CFG            _IOWR('f', 184, long)
+#define OBD_IOC_DUMP_LOG               _IOWR('f', 185, long)
+
+#define OBD_IOC_CATLOGLIST             _IOWR('f', 190, long)
+#define OBD_IOC_LLOG_INFO              _IOWR('f', 191, long)
+#define OBD_IOC_LLOG_PRINT             _IOWR('f', 192, long)
+#define OBD_IOC_LLOG_CANCEL            _IOWR('f', 193, long)
+#define OBD_IOC_LLOG_REMOVE            _IOWR('f', 194, long)
+
 #define ECHO_IOC_GET_STRIPE            _IOWR('f', 200, long)
 #define ECHO_IOC_SET_STRIPE            _IOWR('f', 201, long)
 #define ECHO_IOC_ENQUEUE               _IOWR('f', 202, long)
@@ -539,6 +462,7 @@ static inline void obd_ioctl_freedata(char *buf, int len)
 #define LUSTRE_STRIPE_MAXBYTES 0x1fffffff000ULL
 
 #define CHECKSUM_BULK 0
+#define POISON_BULK 0
 
 #if CHECKSUM_BULK
 static inline void ost_checksum(obd_count *cksum, void *addr, int len)
@@ -554,6 +478,17 @@ static inline void ost_checksum(obd_count *cksum, void *addr, int len)
 }
 #endif
 
+static inline int ll_insecure_random_int(void)
+{
+#ifdef __arch_um__
+        struct timeval t;
+        do_gettimeofday(&t);
+        return (int)(t.tv_usec);
+#else
+        return (int)(get_cycles() >> 2);
+#endif
+}
+
 /*
  * l_wait_event is a flexible sleeping function, permitting simple caller
  * configuration of interrupt and timeout sensitivity along with actions to
@@ -622,7 +557,8 @@ struct l_wait_info {
 })
 
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |                \
-                           sigmask(SIGTERM) | sigmask(SIGQUIT))
+                           sigmask(SIGTERM) | sigmask(SIGQUIT) |               \
+                           sigmask(SIGALRM))
 
 #ifdef __KERNEL__
 static inline sigset_t l_w_e_set_sigs(int sigs)
@@ -639,7 +575,7 @@ static inline sigset_t l_w_e_set_sigs(int sigs)
         return old;
 }
 
-#define __l_wait_event(wq, condition, info, ret)                               \
+#define __l_wait_event(wq, condition, info, ret, excl)                         \
 do {                                                                           \
         wait_queue_t __wait;                                                   \
         int __timed_out = 0;                                                   \
@@ -647,7 +583,10 @@ do {                                                                           \
         sigset_t blocked;                                                      \
                                                                                \
         init_waitqueue_entry(&__wait, current);                                \
-        add_wait_queue(&wq, &__wait);                                          \
+        if (excl)                                                              \
+            add_wait_queue_exclusive(&wq, &__wait);                            \
+        else                                                                   \
+            add_wait_queue(&wq, &__wait);                                      \
                                                                                \
         /* Block all signals (just the non-fatal ones if no timeout). */       \
         if (info->lwi_signals && !info->lwi_timeout)                           \
@@ -691,19 +630,45 @@ do {                                                                           \
         remove_wait_queue(&wq, &__wait);                                       \
 } while(0)
 
+#else /* !__KERNEL__ */
+#define __l_wait_event(wq, condition, info, ret, excl)                         \
+do {                                                                           \
+        int __timed_out = 0;                                                   \
+                                                                               \
+        for (;;) {                                                             \
+            if (condition)                                                     \
+                break;                                                         \
+            if (liblustre_wait_event(info->lwi_timeout))                       \
+                continue;                                                      \
+            if (info->lwi_timeout && !__timed_out) {                           \
+                __timed_out = 1;                                               \
+                if (info->lwi_on_timeout == NULL ||                            \
+                    info->lwi_on_timeout(info->lwi_cb_data)) {                 \
+                    ret = -ETIMEDOUT;                                          \
+                    break;                                                     \
+                }                                                              \
+            }                                                                  \
+        }                                                                      \
+} while (0)
+
+#endif /* __KERNEL__ */
+
 #define l_wait_event(wq, condition, info)                                      \
 ({                                                                             \
         int __ret = 0;                                                         \
         struct l_wait_info *__info = (info);                                   \
         if (!(condition))                                                      \
-                __l_wait_event(wq, condition, __info, __ret);                  \
+                __l_wait_event(wq, condition, __info, __ret, 0);               \
         __ret;                                                                 \
 })
-#else
-#define l_wait_event(wq, condition, info)       \
-({                                              \
-        0;                                      \
+
+#define l_wait_event_exclusive(wq, condition, info)                            \
+({                                                                             \
+        int __ret = 0;                                                         \
+        struct l_wait_info *__info = (info);                                   \
+        if (!(condition))                                                      \
+                __l_wait_event(wq, condition, __info, __ret, 1);               \
+        __ret;                                                                 \
 })
-#endif /* __KERNEL__ */
 
 #endif /* _LUSTRE_LIB_H */
diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h
index fa83fb21e0830e1153e20024d27c34dd36bca4bb..330296c4ea7bca37cc270152a6a0217bf72ea618 100644
--- a/lustre/include/linux/lustre_lite.h
+++ b/lustre/include/linux/lustre_lite.h
@@ -24,7 +24,8 @@
 
 #include <linux/fs.h>
 #include <linux/dcache.h>
-#include <linux/ext2_fs.h>
+#include <linux/jbd.h>
+#include <linux/ext3_fs.h>
 #include <linux/proc_fs.h>
 
 #include <linux/obd_class.h>
@@ -42,25 +43,25 @@
 extern kmem_cache_t *ll_file_data_slab;
 struct ll_file_data {
         struct obd_client_handle fd_mds_och;
-        struct obd_client_handle fd_ost_och;
         __u32 fd_flags;
 };
 
+/*
 struct lustre_intent_data {
         __u64 it_lock_handle[2];
         __u32 it_disposition;
         __u32 it_status;
         __u32 it_lock_mode;
-};
+        }; */
 
 #define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0")
 
 static inline struct lookup_intent *ll_nd2it(struct nameidata *nd)
 {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-        return &nd->it;
+        return &nd->intent;
 #else
-        return nd->it;
+        return nd->intent;
 #endif
 }
 
@@ -75,127 +76,32 @@ struct ll_dentry_data {
 
 extern struct file_operations ll_pgcache_seq_fops;
 
-/* 
- * XXX used in obdecho/echo_client.c  must move (pjb)
- *'p' list as its a list of pages linked together
- * by ->private.. 
- */
-struct plist {
-        struct page *pl_head;
-        struct page *pl_tail;
-        int pl_num;
-};
-
-struct ll_dirty_offsets {
-        rb_root_t       do_root;
-        spinlock_t      do_lock;
-        unsigned long   do_num_dirty;
-};
-
-struct ll_writeback_pages {
-        obd_count npgs, max;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-        int rw;
-        struct inode *inode;
-        struct brw_page pga[0];
-#else
-        struct brw_page *pga;
-#endif
-};
-
+#define LLI_F_HAVE_OST_SIZE_LOCK        0
+#define LLI_F_HAVE_MDS_SIZE_LOCK        1
+#define LLI_F_PREFER_EXTENDED_SIZE      2
 struct ll_inode_info {
         struct lov_stripe_md   *lli_smd;
         char                   *lli_symlink_name;
         struct semaphore        lli_open_sem;
-        struct list_head        lli_read_extents;
         __u64                   lli_maxbytes;
-        spinlock_t              lli_read_extent_lock;
+        __u64                   lli_io_epoch;
         unsigned long           lli_flags;
-#define LLI_F_HAVE_SIZE_LOCK    0
 
+        /* this lock protects s_d_w and p_w_ll */
+        spinlock_t              lli_lock;
+        int                     lli_send_done_writing;
+        struct list_head        lli_pending_write_llaps;
+
+        struct list_head        lli_close_item;
+        struct file_operations *ll_save_ifop;
+        struct file_operations *ll_save_ffop;
+        struct file_operations *ll_save_wfop;
+        struct file_operations *ll_save_wrfop;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
         struct inode            lli_vfs_inode;
 #endif
 };
 
-/*
- * this lets ll_file_read tell ll_readpages how far ahead it can read
- * and still be covered by ll_file_read's lock.  2.5 won't need this, but
- * we have the other problem of other readpage callers making sure that
- * they're covered by a lock..  
- */
-struct ll_read_extent {
-        struct list_head re_lli_item;
-        struct task_struct *re_task;
-        struct ldlm_extent re_extent;
-};
-
-#define LL_SUPER_MAGIC 0x0BD00BD0
-
-#define LL_COMMITCBD_STOPPING  0x1
-#define LL_COMMITCBD_STOPPED   0x2
-#define LL_COMMITCBD_RUNNING   0x4
-
-#define LL_SBI_NOLCK   0x1
-
-struct ll_sb_info {
-        struct obd_uuid           ll_sb_uuid;
-        struct lustre_handle      ll_mdc_conn;
-        struct lustre_handle      ll_osc_conn;
-        struct proc_dir_entry*    ll_proc_root;
-        obd_id                    ll_rootino; /* number of root inode */
-
-        int                       ll_flags;
-        wait_queue_head_t         ll_commitcbd_waitq;
-        wait_queue_head_t         ll_commitcbd_ctl_waitq;
-        int                       ll_commitcbd_flags;
-        struct task_struct       *ll_commitcbd_thread;
-        time_t                    ll_commitcbd_waketime;
-        time_t                    ll_commitcbd_timeout;
-        spinlock_t                ll_commitcbd_lock;
-        struct list_head          ll_conn_chain; /* per-conn chain of SBs */
-
-        struct list_head          ll_orphan_dentry_list; /*please don't ask -p*/
-
-        struct lprocfs_stats     *ll_stats; /* lprocfs stats counter */
-};
-
-
-#if  (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-#define    ll_s2sbi(sb)     ((struct ll_sb_info *)((sb)->s_fs_info))
-void __d_rehash(struct dentry * entry, int lock);
-static inline __u64 ll_ts2u64(struct timespec *time)
-{
-        __u64 t = time->tv_sec;
-        return t;
-}
-#else  /* 2.4 here */
-#define    ll_s2sbi(sb)     ((struct ll_sb_info *)((sb)->u.generic_sbp))
-static inline __u64 ll_ts2u64(time_t *time)
-{
-        return *time;
-}
-#endif 
-
-static inline struct lustre_handle *ll_s2obdconn(struct super_block *sb)
-{
-        return &(ll_s2sbi(sb))->ll_osc_conn;
-}
-
-static inline struct client_obd *sbi2mdc(struct ll_sb_info *sbi)
-{
-        struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn);
-        if (obd == NULL)
-                LBUG();
-        return &obd->u.cli;
-}
-
-// FIXME: replace the name of this with LL_SB to conform to kernel stuff
-static inline struct ll_sb_info *ll_i2sbi(struct inode *inode)
-{
-        return ll_s2sbi(inode->i_sb);
-}
-
 // FIXME: replace the name of this with LL_I to conform to kernel stuff
 // static inline struct ll_inode_info *LL_I(struct inode *inode)
 static inline struct ll_inode_info *ll_i2info(struct inode *inode)
@@ -207,44 +113,6 @@ static inline struct ll_inode_info *ll_i2info(struct inode *inode)
 #endif
 }
 
-static inline struct lustre_handle *ll_i2obdconn(struct inode *inode)
-{
-        return ll_s2obdconn(inode->i_sb);
-}
-
-static inline void ll_ino2fid(struct ll_fid *fid, obd_id ino, __u32 generation,
-                              int type);
-
-static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
-{
-        ll_ino2fid(fid, inode->i_ino, inode->i_generation,
-                   inode->i_mode & S_IFMT);
-}
-
-static inline int ll_mds_max_easize(struct super_block *sb)
-{
-        return sbi2mdc(ll_s2sbi(sb))->cl_max_mds_easize;
-}
-
-static inline __u64 ll_file_maxbytes(struct inode *inode)
-{
-        return ll_i2info(inode)->lli_maxbytes;
-}
-
-/* namei.c */
-typedef int (*intent_finish_cb)(struct ptlrpc_request *,
-                                struct inode *parent, struct dentry **, 
-                                struct lookup_intent *, int offset, obd_id ino);
-int ll_intent_lock(struct inode *parent, struct dentry **,
-                   struct lookup_intent *, int, intent_finish_cb);
-int ll_mdc_blocking_ast(struct ldlm_lock *lock,
-                        struct ldlm_lock_desc *desc,
-                        void *data, int flag);
-void ll_mdc_lock_set_inode(struct lustre_handle *lock, struct inode *inode);
-void ll_prepare_mdc_op_data(struct mdc_op_data *data,
-                            struct inode *i1, struct inode *i2,
-                            const char *name, int namelen, int mode);
-
 /* lprocfs.c */
 enum {
          LPROC_LL_DIRTY_HITS = 0,
@@ -263,7 +131,6 @@ enum {
          LPROC_LL_MAP,
          LPROC_LL_LLSEEK,
          LPROC_LL_FSYNC,
-         LPROC_LL_SETATTR_RAW,
          LPROC_LL_SETATTR,
          LPROC_LL_TRUNC,
 
@@ -279,66 +146,11 @@ enum {
          LPROC_LL_DIRECT_WRITE,
          LPROC_LL_FILE_OPCODES
 };
-/* dcache.c */
-int ll_have_md_lock(struct dentry *de);
-
-/* dir.c */
-extern struct file_operations ll_dir_operations;
-extern struct inode_operations ll_dir_inode_operations;
-
-/* file.c */
-extern struct file_operations ll_file_operations;
-extern struct inode_operations ll_file_inode_operations;
-extern struct inode_operations ll_special_inode_operations;
-struct ldlm_lock;
-int ll_extent_lock_no_validate(struct ll_file_data *fd, struct inode *inode,
-                   struct lov_stripe_md *lsm, int mode,
-                   struct ldlm_extent *extent, struct lustre_handle *lockh);
-int ll_extent_lock(struct ll_file_data *fd, struct inode *inode,
-                   struct lov_stripe_md *lsm, int mode,
-                   struct ldlm_extent *extent, struct lustre_handle *lockh);
-int ll_extent_unlock(struct ll_file_data *fd, struct inode *inode,
-                     struct lov_stripe_md *lsm, int mode,
-                     struct lustre_handle *lockh);
-int ll_create_objects(struct super_block *sb, obd_id id, uid_t uid,
-                      gid_t gid, struct lov_stripe_md **lsmp);
-int ll_file_open(struct inode *inode, struct file *file);
-int ll_file_release(struct inode *inode, struct file *file);
-
-
-
-/* super.c */
-void ll_update_inode(struct inode *, struct mds_body *, struct lov_stripe_md *);
-int ll_setattr_raw(struct inode *inode, struct iattr *attr);
-int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
-                       unsigned long maxage);
-
-/* symlink.c */
-extern struct inode_operations ll_fast_symlink_inode_operations;
-extern struct inode_operations ll_symlink_inode_operations;
 
 #else
 #include <linux/lustre_idl.h>
 #endif /* __KERNEL__ */
 
-static inline void ll_ino2fid(struct ll_fid *fid, obd_id ino, __u32 generation,
-                              int type)
-{
-        fid->id = ino;
-        fid->generation = generation;
-        fid->f_type = type;
-}
-
-#include <asm/types.h>
-
-#define LL_IOC_GETFLAGS                 _IOR ('f', 151, long)
-#define LL_IOC_SETFLAGS                 _IOW ('f', 152, long)
-#define LL_IOC_CLRFLAGS                 _IOW ('f', 153, long)
-#define LL_IOC_LOV_SETSTRIPE            _IOW ('f', 154, long)
-#define LL_IOC_LOV_GETSTRIPE            _IOW ('f', 155, long)
-
-#define O_LOV_DELAY_CREATE 0100000000  /* hopefully this does not conflict */
-
-#define LL_FILE_IGNORE_LOCK             0x00000001
+#include <linux/lustre_user.h>
 
 #endif
diff --git a/lustre/include/linux/lustre_log.h b/lustre/include/linux/lustre_log.h
index 2f215839f9fae69960ddd3f5f69818b58f7c3180..4a7b12443a21a9b6bb1e076a260ecf14200a7bfe 100644
--- a/lustre/include/linux/lustre_log.h
+++ b/lustre/include/linux/lustre_log.h
@@ -35,47 +35,350 @@
 #ifndef _LUSTRE_LOG_H
 #define _LUSTRE_LOG_H
 
+#include <linux/obd.h>
 #include <linux/lustre_idl.h>
 
-struct obd_trans_info;
-struct obd_device;
-struct lov_stripe_md;
+#define LOG_NAME_LIMIT(logname, name)                   \
+        snprintf(logname, sizeof(logname), "LOGS/%s", name)
+
+struct plain_handle_data {
+        struct list_head   phd_entry;
+        struct llog_handle     *phd_cat_handle; 
+        struct llog_cookie phd_cookie; /* cookie of this log in its cat */
+        int                phd_last_idx;
+};
+
+struct cat_handle_data {
+        struct list_head        chd_head;
+        struct llog_handle     *chd_current_log; /* currently open log */
+};
 
 /* In-memory descriptor for a log object or log catalog */
 struct llog_handle {
-        struct list_head        lgh_list;
-        struct llog_cookie      lgh_cookie;
-        struct semaphore        lgh_lock;
-        struct obd_device      *lgh_obd;
-        void                   *lgh_hdr;
+        struct rw_semaphore     lgh_lock;
+        struct llog_logid       lgh_id;              /* id of this log */
+        struct llog_log_hdr    *lgh_hdr;
         struct file            *lgh_file;
-        struct obd_uuid        *lgh_tgtuuid;
-        struct llog_handle     *lgh_current;
-        struct llog_handle     *(*lgh_log_create)(struct obd_device *obd);
-        struct llog_handle     *(*lgh_log_open)(struct obd_device *obd,
-                                                struct llog_cookie *logcookie);
-        int                     (*lgh_log_close)(struct llog_handle *cathandle,
-                                                 struct llog_handle *loghandle);
-        int                     lgh_index;
+        int                     lgh_last_idx;
+        struct llog_ctxt       *lgh_ctxt;
+        union {
+                struct plain_handle_data phd;
+                struct cat_handle_data   chd;
+        } u;
 };
 
-extern int llog_add_record(struct llog_handle *cathandle,
-                           struct llog_trans_hdr *rec,
-                           struct llog_cookie *logcookies);
-
-extern int llog_cancel_records(struct llog_handle *cathandle, int count,
-                               struct llog_cookie *cookies);
+#define LLOG_EEMPTY 4711
 
+/* llog.c  -  general API */
+typedef int (*llog_cb_t)(struct llog_handle *, struct llog_rec_hdr *, void *);
+int llog_init_handle(struct llog_handle *handle, int flags, 
+                     struct obd_uuid *uuid);
+int llog_process(struct llog_handle *loghandle, llog_cb_t cb, void *data);
 extern struct llog_handle *llog_alloc_handle(void);
 extern void llog_free_handle(struct llog_handle *handle);
-extern int llog_init_catalog(struct llog_handle *cathandle,
-                             struct obd_uuid *tgtuuid);
-extern int llog_delete_log(struct llog_handle *cathandle,
-                           struct llog_handle *loghandle);
-extern int llog_close_log(struct llog_handle *cathandle,
-                          struct llog_handle *loghandle);
-extern struct llog_handle *llog_new_log(struct llog_handle *cathandle,
-                                        struct obd_uuid *tgtuuid);
+extern int llog_close(struct llog_handle *cathandle);
+extern int llog_cancel_rec(struct llog_handle *loghandle, int index);
+
+/* llog_cat.c   -  catalog api */
+struct llog_process_data {
+        void *lpd_data;
+        llog_cb_t lpd_cb;
+};
+int llog_cat_put(struct llog_handle *cathandle);
+int llog_cat_add_rec(struct llog_handle *cathandle, struct llog_rec_hdr *rec,
+                     struct llog_cookie *reccookie, void *buf);
+int llog_cat_cancel_records(struct llog_handle *cathandle, int count,
+                            struct llog_cookie *cookies);
+int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data);
+
+/* llog_obd.c */
+int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
+               int count,  struct llog_logid *logid, struct llog_operations *op);
+int llog_cleanup(struct llog_ctxt *);
+int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp);
+int llog_add(struct llog_ctxt *ctxt,
+                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                        struct llog_cookie *logcookies, int numcookies);
+int llog_cancel(struct llog_ctxt *, struct lov_stripe_md *lsm,
+                    int count, struct llog_cookie *cookies, int flags);
+
+int llog_obd_origin_setup(struct obd_device *obd, int index, 
+                          struct obd_device *disk_obd, int count, 
+                          struct llog_logid *logid);
+int llog_obd_origin_cleanup(struct llog_ctxt *ctxt);
+int llog_obd_origin_add(struct llog_ctxt *ctxt,
+                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                        struct llog_cookie *logcookies, int numcookies);
+
+int llog_cat_initialize(struct obd_device *obd, int count);
+int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd,
+                  int count, struct llog_logid *logid);
+
+int obd_llog_finish(struct obd_device *obd, int count);
+
+/* llog_ioctl.c */
+int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data);
+int llog_catlog_list(struct obd_device *obd, int count, 
+                     struct obd_ioctl_data *data);
+
+/* llog_net.c */
+int llog_initiator_connect(struct llog_ctxt *ctxt);
+int llog_receptor_accept(struct llog_ctxt *ctxt, struct obd_import *imp);
+int llog_origin_connect(struct llog_ctxt *ctxt, int count,
+                        struct llog_logid *logid, struct llog_ctxt_gen *gen);
+int llog_handle_connect(struct ptlrpc_request *req);
+
+/* recov_thread.c */
+int llog_obd_repl_cancel(struct llog_ctxt *ctxt,
+                         struct lov_stripe_md *lsm, int count,
+                         struct llog_cookie *cookies, int flags);
+int llog_obd_repl_sync(struct llog_ctxt *ctxt, struct obd_export *exp);
+int llog_repl_connect(struct llog_ctxt *ctxt, int count, 
+                      struct llog_logid *logid, struct llog_ctxt_gen *gen);
+
+struct llog_operations {
+        int (*lop_write_rec)(struct llog_handle *loghandle,
+                             struct llog_rec_hdr *rec, 
+                             struct llog_cookie *logcookies, 
+                             int numcookies, 
+                             void *,
+                             int idx);
+        int (*lop_destroy)(struct llog_handle *handle);
+        int (*lop_next_block)(struct llog_handle *h, 
+                              int *curr_idx,  
+                              int next_idx, 
+                              __u64 *offset, 
+                              void *buf, 
+                              int len);
+        int (*lop_create)(struct llog_ctxt *ctxt, struct llog_handle **,
+                          struct llog_logid *logid, char *name);
+        int (*lop_close)(struct llog_handle *handle);
+        int (*lop_read_header)(struct llog_handle *handle);
+
+        int (*lop_setup)(struct obd_device *obd, int ctxt_idx, 
+                         struct obd_device *disk_obd, int count, 
+                         struct llog_logid *logid);
+        int (*lop_sync)(struct llog_ctxt *ctxt, struct obd_export *exp);
+        int (*lop_cleanup)(struct llog_ctxt *ctxt);
+        int (*lop_add)(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, 
+                       struct lov_stripe_md *lsm, 
+                       struct llog_cookie *logcookies, int numcookies);
+        int (*lop_cancel)(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
+                          int count, struct llog_cookie *cookies, int flags);
+        int (*lop_connect)(struct llog_ctxt *ctxt, int count,
+                           struct llog_logid *logid, struct llog_ctxt_gen *gen);
+        /* XXX add 2 more: commit callbacks and llog recovery functions */
+};
+
+extern struct llog_operations llog_lvfs_ops;
+
+
+struct llog_ctxt {
+        int                      loc_idx; /* my index the obd array of ctxt's */
+        struct llog_ctxt_gen     loc_gen; 
+        struct obd_device       *loc_obd; /* points back to the containing obd*/
+        struct obd_export       *loc_exp;
+        struct obd_import       *loc_imp; /* to use in RPC's: can be backward 
+                                             pointing import */
+        struct llog_operations  *loc_logops;
+        struct llog_handle      *loc_handle;
+        struct llog_canceld_ctxt *loc_llcd;
+        struct semaphore         loc_sem; /* protects loc_llcd */
+        void                    *llog_proc_cb;
+};
+
+static inline void log_gen_init(struct llog_ctxt *ctxt)
+{
+        struct obd_device *obd = ctxt->loc_exp->exp_obd;
+
+        if (!strcmp(obd->obd_type->typ_name, "mds"))
+                ctxt->loc_gen.mnt_cnt = obd->u.mds.mds_mount_count;
+        else if (!strstr(obd->obd_type->typ_name, "filter")) {
+                ctxt->loc_gen.mnt_cnt = obd->u.filter.fo_mount_count; 
+        }
+        else
+                ctxt->loc_gen.mnt_cnt = 0; 
+}
+
+static inline int log_gen_lt(struct llog_ctxt_gen a, struct llog_ctxt_gen b)
+{
+        if (a.mnt_cnt < b.mnt_cnt)
+                return 1;
+        if (a.mnt_cnt > b.mnt_cnt)
+                return 0;
+        return(a.conn_cnt < b.conn_cnt ? 1 : 0);
+}
 
-#endif
 
+static inline int llog_obd2ops(struct llog_ctxt *ctxt,
+                               struct llog_operations **lop)
+{
+        if (ctxt == NULL)
+                return -ENOTCONN;
+        *lop = ctxt->loc_logops;
+        if (*lop == NULL)
+                return -EOPNOTSUPP;
+        return 0;
+}
+
+static inline int llog_handle2ops(struct llog_handle *loghandle,
+                                  struct llog_operations **lop)
+{
+        if (loghandle == NULL)
+                return -EINVAL;
+        return llog_obd2ops(loghandle->lgh_ctxt, lop);
+}
+
+static inline int llog_data_len(int len)
+{
+        int mask = LLOG_MIN_REC_SIZE - 1;
+        int remains = LLOG_MIN_REC_SIZE - sizeof(struct llog_rec_hdr) -
+                sizeof(struct llog_rec_tail); 
+        
+        return (len <= remains) ? 
+                remains : (((len + mask) & (~mask)) + remains);
+}
+
+static inline struct llog_ctxt *llog_get_context(struct obd_device *obd,
+                                                 int index)
+{
+        if (index < 0 || index >= LLOG_MAX_CTXTS)
+                return NULL;
+        else
+                return obd->obd_llog_ctxt[index];
+}
+
+static inline int llog_write_rec(struct llog_handle *handle,
+                                 struct llog_rec_hdr *rec,
+                                 struct llog_cookie *logcookies,
+                                 int numcookies, void *buf, int idx)
+{
+        struct llog_operations *lop;
+        int rc, buflen;
+        ENTRY;
+        
+        rc = llog_handle2ops(handle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_write_rec == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        if (buf)
+                buflen = le32_to_cpu(rec->lrh_len) + sizeof(struct llog_rec_hdr)
+                                + sizeof(struct llog_rec_tail);
+        else
+                buflen = le32_to_cpu(rec->lrh_len);
+        LASSERT((buflen % LLOG_MIN_REC_SIZE) == 0);
+
+        rc = lop->lop_write_rec(handle, rec, logcookies, numcookies, buf, idx);
+        RETURN(rc);
+}
+
+static inline int llog_read_header(struct llog_handle *handle)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+        
+        rc = llog_handle2ops(handle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_read_header == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_read_header(handle);
+        RETURN(rc);
+}
+
+static inline int llog_destroy(struct llog_handle *handle)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+        
+        rc = llog_handle2ops(handle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_destroy == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_destroy(handle);
+        RETURN(rc);
+}
+
+#if 0
+static inline int llog_cancel(struct obd_export *exp,
+                              struct lov_stripe_md *lsm, int count,
+                              struct llog_cookie *cookies, int flags)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_handle2ops(loghandle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_cancel == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_cancel(exp, lsm, count, cookies, flags);
+        RETURN(rc);
+}
+#endif 
+
+static inline int llog_next_block(struct llog_handle *loghandle, int *cur_idx,
+                                  int next_idx, __u64 *cur_offset, void *buf,
+                                  int len)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_handle2ops(loghandle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_next_block == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_next_block(loghandle, cur_idx, next_idx, cur_offset, buf,
+                                 len);
+        RETURN(rc);
+}
+
+static inline int llog_create(struct llog_ctxt *ctxt, 
+                              struct llog_handle **res,
+                              struct llog_logid *logid, char *name)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_obd2ops(ctxt, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_create == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_create(ctxt, res, logid, name);
+        RETURN(rc);
+}
+
+static inline int llog_connect(struct llog_ctxt *ctxt, int count,
+                               struct llog_logid *logid,
+                               struct llog_ctxt_gen *gen)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_obd2ops(ctxt, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_connect == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_connect(ctxt, count, logid, gen);
+        RETURN(rc);
+}
+
+#endif
diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h
index e7ee6f0535d1f86d54e7cfe65f4b5c403ac1d508..d16eca9b954de01c89760cc5f672ae2b7bdd73c4 100644
--- a/lustre/include/linux/lustre_mds.h
+++ b/lustre/include/linux/lustre_mds.h
@@ -56,89 +56,14 @@ struct lustre_md {
         struct lov_stripe_md *lsm;
 };
 
-struct mdc_rpc_lock {
-        struct semaphore rpcl_sem;
-        struct lookup_intent *rpcl_it;
-};
-extern struct mdc_rpc_lock mdc_rpc_lock;
-extern struct mdc_rpc_lock mdc_setattr_lock;
-
-static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
-{
-        sema_init(&lck->rpcl_sem, 1);
-        lck->rpcl_it = NULL;
-}
-
-#ifdef __KERNEL__
-/* Compat code for kernel patch v18 users, can be removed when everyone has
- * upgraded --phik 02 June 2003 */
-#ifdef IT_FL_LOCKED
-static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 
-                                    struct lookup_intent *it)
-{
-        down(&lck->rpcl_sem);
-        if (it) { 
-                lck->rpcl_it = it;
-                it->it_int_flags |= IT_FL_LOCKED;
-        }
-}
-
-static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 
-                                    struct lookup_intent *it)
-{
-        if (it == NULL) {
-                LASSERT(it == lck->rpcl_it);
-                up(&lck->rpcl_sem);
-                return;
-        }
-        if (it != NULL && (it->it_int_flags & IT_FL_LOCKED)) {
-                it->it_int_flags &= ~IT_FL_LOCKED;
-                LASSERT(it == lck->rpcl_it);
-                lck->rpcl_it = NULL;
-                up(&lck->rpcl_sem);
-        }
-}
-#else
-static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 
-                                    struct lookup_intent *it)
-{
-        down(&lck->rpcl_sem);
-        if (it) { 
-                lck->rpcl_it = it;
-                it->it_iattr = (void *)1;
-        }
-}
-
-static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 
-                                    struct lookup_intent *it)
-{
-        if (it == NULL) {
-                LASSERT(it == lck->rpcl_it);
-                up(&lck->rpcl_sem);
-                return;
-        }
-        if (it && it->it_iattr) {
-                it->it_iattr = NULL;
-                LASSERT(it == lck->rpcl_it);
-                lck->rpcl_it = NULL;
-                up(&lck->rpcl_sem);
-        }
-}
-#endif
-#endif
-
 struct mdc_op_data {
-        __u64   ino1;
-        __u32   gen1;
-        __u32   typ1;
-        __u32   gid1;
-        __u64   ino2;
-        __u32   gen2;
-        __u32   typ2;
-        __u32   gid2;
+        struct ll_fid fid1;
+        struct ll_fid fid2;
+        struct ll_uctxt ctxt;
+        __u64 mod_time;
         const char *name;
-        int     namelen;
-        int     mode;
+        int namelen;
+        __u32 create_mode;
 };
 
 struct mds_update_record {
@@ -157,8 +82,6 @@ struct mds_update_record {
         struct obd_ucred ur_uc;
         __u64 ur_rdev;
         __u32 ur_mode;
-        __u32 ur_uid;
-        __u32 ur_gid;
         __u64 ur_time;
         __u32 ur_flags;
 };
@@ -170,7 +93,7 @@ struct mds_update_record {
 #define ur_suppgid2 ur_uc.ouc_suppgid2
 
 /* i_attr_flags holds the open count in the inode in 2.4 */
-//Alex implement on 2.4 with i_attr_flags and find soln for 2.5 please
+//XXX Alex implement on 2.4 with i_attr_flags and find soln for 2.5 please
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 # define mds_open_orphan_count(inode)   (0)
 # define mds_open_orphan_inc(inode)  do { } while (0);
@@ -199,14 +122,18 @@ struct mds_update_record {
 
 #define MDS_MOUNT_RECOV 2
 
-/* Data stored per server at the head of the last_rcvd file.  In le32 order. */
+#define MDS_ROCOMPAT_LOVOBJID   0x00000001
+#define MDS_ROCOMPAT_SUPP       (MDS_ROCOMPAT_LOVOBJID)
+
+#define MDS_INCOMPAT_SUPP       (0)
+
+/* Data stored per server at the head of the last_rcvd file.  In le32 order.
+ * Try to keep this the same as fsd_server_data so we might one day merge. */
 struct mds_server_data {
-        __u8  msd_uuid[37];        /* server UUID */
-        __u8  uuid_padding[3];     /* unused */
-//      __u64 msd_last_objid;      /* last created object ID */
+        __u8  msd_uuid[40];        /* server UUID */
         __u64 msd_last_transno;    /* last completed transaction ID */
         __u64 msd_mount_count;     /* MDS incarnation number */
-        __u64 msd_padding_until_last_objid_is_enabled;
+        __u64 msd_unused;
         __u32 msd_feature_compat;  /* compatible feature flags */
         __u32 msd_feature_rocompat;/* read-only compatible feature flags */
         __u32 msd_feature_incompat;/* incompatible feature flags */
@@ -216,15 +143,13 @@ struct mds_server_data {
         __u16 msd_subdir_count;    /* number of subdirectories for objects */
         __u64 msd_catalog_oid;     /* recovery catalog object id */
         __u32 msd_catalog_ogen;    /* recovery catalog inode generation */
-        __u8  msd_peeruuid[37];    /* UUID of LOV/OSC associated with MDS */
-        __u8  peer_padding[3];     /* unused */
+        __u8  msd_peeruuid[40];    /* UUID of LOV/OSC associated with MDS */
         __u8  msd_padding[MDS_LR_SERVER_SIZE - 140];
 };
 
 /* Data stored per client in the last_rcvd file.  In le32 order. */
 struct mds_client_data {
-        __u8 mcd_uuid[37];      /* client UUID */
-        __u8 uuid_padding[3];   /* unused */
+        __u8 mcd_uuid[40];      /* client UUID */
         __u64 mcd_mount_count;  /* MDS incarnation number */
         __u64 mcd_last_transno; /* last completed transaction ID */
         __u64 mcd_last_xid;     /* xid for the last transaction */
@@ -256,15 +181,14 @@ struct dentry *mds_name2locked_dentry(struct obd_device *, struct dentry *dir,
                                       int dir_lock_mode);
 struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid,
                                      struct vfsmount **mnt, int lock_mode,
-                                     struct lustre_handle *lockh);
+                                     struct lustre_handle *lockh,
+                                     char *name, int namelen);
 struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid,
                               struct vfsmount **mnt);
 int mds_reint(struct ptlrpc_request *req, int offset, struct lustre_handle *);
-int mds_pack_md(struct obd_device *mds, struct lustre_msg *msg,
-                int offset, struct mds_body *body, struct inode *inode);
 void mds_steal_ack_locks(struct obd_export *exp,
                          struct ptlrpc_request *req);
-int mds_update_server_data(struct obd_device *);
+int mds_update_server_data(struct obd_device *, int force_sync);
 
 /* mds/mds_fs.c */
 int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt);
@@ -272,59 +196,86 @@ int mds_fs_cleanup(struct obd_device *obddev, int failover);
 #endif
 
 /* mds/mds_lov.c */
-extern int mds_get_lovtgts(struct mds_obd *obd, int tgt_count,
-                           struct obd_uuid *uuidarray);
-extern int mds_get_lovdesc(struct mds_obd  *obd, struct lov_desc *desc);
 
-/* mdc/mdc_request.c */
-int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
-                      struct lustre_handle *obd_import,
-                      struct lustre_md *md);
-int mdc_enqueue(struct lustre_handle *conn, int lock_type,
-                struct lookup_intent *it, int lock_mode,
-                struct mdc_op_data *enq_data,
-                struct lustre_handle *lockh, char *tgt, int tgtlen,
+/* mdc/mdc_locks.c */
+int it_disposition(struct lookup_intent *it, int flag);
+void it_set_disposition(struct lookup_intent *it, int flag);
+int it_open_error(int phase, struct lookup_intent *it);
+void mdc_set_lock_data(__u64 *lockh, void *data);
+int mdc_change_cbdata(struct obd_export *exp, struct ll_fid *fid, 
+                      ldlm_iterator_t it, void *data);
+int mdc_intent_lock(struct obd_export *exp, struct ll_uctxt *, 
+                    struct ll_fid *parent, 
+                    const char *name, int len, void *lmm, int lmmsize,
+                    struct ll_fid *child,
+                    struct lookup_intent *, int, 
+                    struct ptlrpc_request **reqp,
+                    ldlm_blocking_callback cb_blocking);
+int mdc_enqueue(struct obd_export *exp,
+                int lock_type,
+                struct lookup_intent *it,
+                int lock_mode,
+                struct mdc_op_data *data,
+                struct lustre_handle *lockh,
+                void *lmm,
+                int lmmlen,
                 ldlm_completion_callback cb_completion,
                 ldlm_blocking_callback cb_blocking,
                 void *cb_data);
-int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh,
-                   struct ptlrpc_request **request);
-int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid);
-int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
+
+/* mdc/mdc_request.c */
+int mdc_init_ea_size(struct obd_device *obd, char *lov_name);
+int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
+                      struct obd_export *exp,
+                      struct lustre_md *md);
+int mdc_getstatus(struct obd_export *exp, struct ll_fid *rootfid);
+int mdc_getattr(struct obd_export *exp, struct ll_fid *fid,
                 unsigned long valid, unsigned int ea_size,
                 struct ptlrpc_request **request);
-int mdc_getattr_name(struct lustre_handle *conn, struct ll_fid *fid,
+int mdc_getattr_name(struct obd_export *exp, struct ll_fid *fid,
                      char *filename, int namelen, unsigned long valid,
                      unsigned int ea_size, struct ptlrpc_request **request);
-int mdc_setattr(struct lustre_handle *conn,
-                struct mdc_op_data *data,
+int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len,
                 struct ptlrpc_request **request);
-int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags,
+int mdc_open(struct obd_export *exp, obd_id ino, int type, int flags,
              struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh,
              struct ptlrpc_request **);
 struct obd_client_handle;
-void mdc_set_open_replay_data(struct obd_client_handle *och);
-int mdc_close(struct lustre_handle *conn, obd_id ino, int type,
-              struct lustre_handle *fh,  struct ptlrpc_request **req);
-int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset,
+void mdc_set_open_replay_data(struct obd_client_handle *och,
+                              struct ptlrpc_request *open_req);
+void mdc_clear_open_replay_data(struct obd_client_handle *och);
+int mdc_close(struct obd_export *, struct obdo *, struct obd_client_handle *,
+              struct ptlrpc_request **);
+int mdc_readpage(struct obd_export *exp, struct ll_fid *mdc_fid, __u64 offset,
                  struct page *, struct ptlrpc_request **);
-int mdc_create(struct lustre_handle *conn, struct mdc_op_data *op_data,
+int mdc_create(struct obd_export *exp, struct mdc_op_data *op_data,
                const void *data, int datalen, int mode, __u32 uid, __u32 gid,
-               __u64 time, __u64 rdev, struct ptlrpc_request **request);
-int mdc_unlink(struct lustre_handle *conn, struct mdc_op_data *data,
+               __u64 rdev, struct ptlrpc_request **request);
+int mdc_unlink(struct obd_export *exp, struct mdc_op_data *data,
                struct ptlrpc_request **request);
-int mdc_link(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_link(struct obd_export *exp, struct mdc_op_data *data,
              struct ptlrpc_request **);
-int mdc_rename(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_rename(struct obd_export *exp, struct mdc_op_data *data,
                const char *old, int oldlen, const char *new, int newlen,
                struct ptlrpc_request **request);
+int mdc_sync(struct obd_export *exp, struct ll_fid *fid,
+             struct ptlrpc_request **);
 int mdc_create_client(struct obd_uuid uuid, struct ptlrpc_client *cl);
 
 /* Store the generation of a newly-created inode in |req| for replay. */
 void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff,
                                 int repoff);
+int mdc_llog_process(struct obd_export *, char *logname, llog_cb_t, void *data);
+int mdc_done_writing(struct obd_export *exp, struct obdo *);
 
+static inline void mdc_pack_fid(struct ll_fid *fid, obd_id ino, __u32 gen,
+                                int type)
+{
+        fid->id = ino;
+        fid->generation = gen;
+        fid->f_type = type;
+}
 
 /* ioctls for trying requests */
 #define IOC_REQUEST_TYPE                   'f'
diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h
index bc70b9adbf07efe99964b24ce99772d28db72c83..7fe649bb4a4e81e036d062ac3ffadac64aa8e45d 100644
--- a/lustre/include/linux/lustre_net.h
+++ b/lustre/include/linux/lustre_net.h
@@ -35,6 +35,7 @@
 #include <linux/kp30.h>
 // #include <linux/obd.h>
 #include <portals/p30.h>
+#include <portals/lib-types.h>                  /* FIXME (for PTL_MD_MAX_IOV) */
 #include <linux/lustre_idl.h>
 #include <linux/lustre_ha.h>
 #include <linux/lustre_import.h>
@@ -55,18 +56,21 @@
  * is left in them.
  */
 
-#define LDLM_NUM_THREADS        4
+#define LDLM_NUM_THREADS        min(smp_num_cpus * smp_num_cpus * 8, 64)
 #define LDLM_NEVENT_MAX 8192UL
-#define LDLM_NEVENTS    min(num_physpages / 64, LDLM_NEVENT_MAX)
+#define LDLM_NEVENTS    min_t(unsigned long, num_physpages / 64,  \
+                              LDLM_NEVENT_MAX)
 #define LDLM_NBUF_MAX   256UL
 #define LDLM_NBUFS      min(LDLM_NEVENTS / 16, LDLM_NBUF_MAX)
 #define LDLM_BUFSIZE    (8 * 1024)
-#define LDLM_MAXREQSIZE 1024
+#define LDLM_MAXREQSIZE (5 * 1024)
 
 #define MDT_MAX_THREADS 32UL
-#define MDT_NUM_THREADS min(num_physpages / 8192, MDT_MAX_THREADS)
+#define MDT_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \
+                                  MDT_MAX_THREADS), 2UL)
 #define MDS_NEVENT_MAX  8192UL
-#define MDS_NEVENTS     min(num_physpages / 64, MDS_NEVENT_MAX)
+#define MDS_NEVENTS     min_t(unsigned long, num_physpages / 64, \
+                              MDS_NEVENT_MAX)
 #define MDS_NBUF_MAX    512UL
 #define MDS_NBUFS       min(MDS_NEVENTS / 16, MDS_NBUF_MAX)
 #define MDS_BUFSIZE     (8 * 1024)
@@ -87,11 +91,13 @@
 #define MDS_MAXREQSIZE  (5 * 1024)
 
 #define OST_MAX_THREADS 36UL
-#define OST_NUM_THREADS min(num_physpages / 8192, OST_MAX_THREADS)
-#define OST_NEVENT_MAX  32768UL
-#define OST_NEVENTS     min(num_physpages / 16, OST_NEVENT_MAX)
-#define OST_NBUF_MAX    1280UL
-#define OST_NBUFS       min(OST_NEVENTS / 64, OST_NBUF_MAX)
+#define OST_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \
+                                  OST_MAX_THREADS), 2UL)
+#define OST_NEVENT_MAX  16384UL
+#define OST_NEVENTS     min_t(unsigned long, num_physpages / 16, \
+                              OST_NEVENT_MAX)
+#define OST_NBUF_MAX    5000UL
+#define OST_NBUFS       min(OST_NEVENTS / 2, OST_NBUF_MAX)
 #define OST_BUFSIZE     (8 * 1024)
 /* OST_MAXREQSIZE ~= 1640 bytes =
  * lustre_msg + obdo + 16 * obd_ioobj + 64 * niobuf_remote
@@ -107,8 +113,6 @@
 #define PTLBD_BUFSIZE    (32 * 1024)
 #define PTLBD_MAXREQSIZE 1024
 
-#define CONN_INVALID 1
-
 struct ptlrpc_peer {
         ptl_nid_t         peer_nid;
         struct ptlrpc_ni *peer_ni;
@@ -117,30 +121,13 @@ struct ptlrpc_peer {
 struct ptlrpc_connection {
         struct list_head        c_link;
         struct ptlrpc_peer      c_peer;
-        struct obd_uuid         c_local_uuid;  /* XXX do we need this? */
         struct obd_uuid         c_remote_uuid;
-
-        __u32                   c_generation;  /* changes upon new connection */
-        __u32                   c_epoch;       /* changes when peer changes */
-        __u32                   c_bootcount;   /* peer's boot count */
-
-        spinlock_t              c_lock;
-
         atomic_t                c_refcount;
-        __u64                   c_token;
-        __u64                   c_remote_conn;
-        __u64                   c_remote_token;
-
-        __u32                   c_flags; // can we indicate INVALID elsewhere?
 };
 
 struct ptlrpc_client {
         __u32                     cli_request_portal;
         __u32                     cli_reply_portal;
-
-        __u32                     cli_target_devno;
-
-        void                     *cli_data;
         char                     *cli_name;
 };
 
@@ -149,7 +136,7 @@ struct ptlrpc_client {
 #define PTL_RPC_FL_INTR      (1 << 0)  /* reply wait was interrupted by user */
 #define PTL_RPC_FL_TIMEOUT   (1 << 7)  /* request timed out waiting for reply */
 
-#define REQ_MAX_ACK_LOCKS 4
+#define REQ_MAX_ACK_LOCKS 8
 
 #define SWAB_PARANOIA 1
 #if SWAB_PARANOIA
@@ -189,7 +176,7 @@ union ptlrpc_async_args {
          * big enough.  For _tons_ of context, OBD_ALLOC a struct and store
          * a pointer to it here.  The pointer_arg ensures this struct is at
          * least big enough for that. */
-        void      *pointer_arg[5];
+        void      *pointer_arg[9];
         __u64      space[4];
 };
 
@@ -203,6 +190,10 @@ struct ptlrpc_request_set {
         struct list_head  set_requests;
         set_interpreter_func    set_interpret; /* completion callback */
         union ptlrpc_async_args set_args; /* completion context */
+        /* locked so that any old caller can communicate requests to
+         * the set holder who can then fold them into the lock-free set */
+        spinlock_t        set_new_req_lock;
+        struct list_head  set_new_requests;
 };
 
 struct ptlrpc_bulk_desc;
@@ -215,8 +206,7 @@ struct ptlrpc_request {
         spinlock_t rq_lock;
         unsigned int rq_intr:1, rq_replied:1, rq_want_ack:1, rq_err:1,
             rq_timedout:1, rq_resend:1, rq_restart:1, rq_replay:1,
-            rq_no_resend:1, rq_resent:1, rq_no_recov:1, rq_waiting:1,
-            rq_receiving_reply:1;
+            rq_no_resend:1, rq_resent:1, rq_waiting:1, rq_receiving_reply:1;
         int rq_phase;
                 
         atomic_t rq_refcount;
@@ -239,7 +229,7 @@ struct ptlrpc_request {
 #endif
 
         int rq_import_generation;
-        int rq_level;
+        enum lustre_imp_state rq_send_state;
         wait_queue_head_t rq_wait_for_rep; /* XXX also _for_ack */
 
         /* incoming reply */
@@ -256,7 +246,8 @@ struct ptlrpc_request {
         struct ptlrpc_service *rq_svc;
 
         void (*rq_replay_cb)(struct ptlrpc_request *);
-        void  *rq_replay_data;
+        void (*rq_commit_cb)(struct ptlrpc_request *);
+        void  *rq_cb_data;
 
         struct ptlrpc_bulk_desc *rq_bulk;       /* client side bulk */
         time_t rq_sent;                         /* when the request was sent */
@@ -274,6 +265,7 @@ struct ptlrpc_request {
         } rq_ack_locks[REQ_MAX_ACK_LOCKS];
 };
 
+
 #define RQ_PHASE_NEW           0xebc0de00
 #define RQ_PHASE_RPC	       0xebc0de01
 #define RQ_PHASE_BULK          0xebc0de02
@@ -294,16 +286,16 @@ struct ptlrpc_request {
         FLAG(req->rq_timedout, "X") /* eXpired */, FLAG(req->rq_resend, "S"),  \
         FLAG(req->rq_restart, "T"), FLAG(req->rq_replay, "P"),                 \
         FLAG(req->rq_no_resend, "N"), FLAG(req->rq_resent, "s"),               \
-        FLAG(req->rq_no_recov, "n"), FLAG(req->rq_waiting, "W")
+        FLAG(req->rq_waiting, "W")
 
-#define REQ_FLAGS_FMT "%s:%s%s%s%s%s%s%s%s%s%s%s%s"
+#define REQ_FLAGS_FMT "%s:%s%s%s%s%s%s%s%s%s%s%s"
 
 #define DEBUG_REQ(level, req, fmt, args...)                                    \
 do {                                                                           \
 CDEBUG(level, "@@@ " fmt                                                       \
        " req@%p x"LPD64"/t"LPD64" o%d->%s@%s:%d lens %d/%d ref %d fl "         \
        REQ_FLAGS_FMT"/%x/%x rc %x\n" ,  ## args, req, req->rq_xid,             \
-       req->rq_reqmsg ? req->rq_reqmsg->transno : -1,                          \
+       req->rq_transno,                                                        \
        req->rq_reqmsg ? req->rq_reqmsg->opc : -1,                              \
        req->rq_import ? (char *)req->rq_import->imp_target_uuid.uuid : "<?>",  \
        req->rq_connection ?                                                    \
@@ -354,9 +346,9 @@ struct ptlrpc_bulk_desc {
         int bd_callback_count;                  /* server side callbacks */
 
 #ifdef __KERNEL__
-        ptl_kiov_t bd_iov[16];    /* self-sized pre-allocated iov */
+        ptl_kiov_t bd_iov[PTL_MD_MAX_IOV];
 #else
-        struct iovec bd_iov[16];    /* self-sized pre-allocated iov */
+        struct iovec bd_iov[PTL_MD_MAX_IOV];
 #endif
 };
 
@@ -375,8 +367,11 @@ struct ptlrpc_request_buffer_desc {
         char                  *rqbd_buffer;
 };
 
-struct ptlrpc_ni {
-        /* Generic interface state */
+/* event queues are per-ni, because one day we may get a hardware
+ * supported NAL that delivers events asynchonously wrt kernel portals
+ * into the eq.
+ */
+struct ptlrpc_ni { /* Generic interface state */
         char                   *pni_name;
         int                     pni_number;
         ptl_handle_ni_t         pni_ni_h;
@@ -480,14 +475,21 @@ void ptlrpc_restart_req(struct ptlrpc_request *req);
 void ptlrpc_abort_inflight(struct obd_import *imp);
 
 struct ptlrpc_request_set *ptlrpc_prep_set(void);
+int ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
+int ptlrpc_check_set(struct ptlrpc_request_set *set);
 int ptlrpc_set_wait(struct ptlrpc_request_set *);
+int ptlrpc_expired_set(void *data);
+void ptlrpc_interrupted_set(void *data);
 void ptlrpc_set_destroy(struct ptlrpc_request_set *);
 void ptlrpc_set_add_req(struct ptlrpc_request_set *, struct ptlrpc_request *);
+void ptlrpc_set_add_new_req(struct ptlrpc_request_set *,
+                            struct ptlrpc_request *);
 
 struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode,
                                        int count, int *lengths, char **bufs);
 void ptlrpc_free_req(struct ptlrpc_request *request);
 void ptlrpc_req_finished(struct ptlrpc_request *request);
+void ptlrpc_req_finished_with_imp_lock(struct ptlrpc_request *request);
 struct ptlrpc_request *ptlrpc_request_addref(struct ptlrpc_request *req);
 struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_imp (struct ptlrpc_request *req,
                                                int type, int portal);
@@ -501,16 +503,14 @@ void ptlrpc_retain_replayable_request(struct ptlrpc_request *req,
                                       struct obd_import *imp);
 __u64 ptlrpc_next_xid(void);
 
-/* ptlrpc/ptlrpc_module.c */
-void ptlrpc_put_ldlm_hooks(void);
-int ptlrpc_ldlm_hooks_referenced(void);
-
 /* ptlrpc/service.c */
 struct ptlrpc_service *
 ptlrpc_init_svc(__u32 nevents, __u32 nbufs, __u32 bufsize, __u32 max_req_size,
                 int req_portal, int rep_portal, svc_handler_t, char *name,
-                struct obd_device *dev);
+                struct proc_dir_entry *proc_entry);
 void ptlrpc_stop_all_threads(struct ptlrpc_service *svc);
+int ptlrpc_start_n_threads(struct obd_device *dev, struct ptlrpc_service *svc,
+                           int cnt, char *base_name);
 int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc,
                         char *name);
 int ptlrpc_unregister_service(struct ptlrpc_service *service);
@@ -522,9 +522,16 @@ struct ptlrpc_svc_data {
         struct obd_device *dev;
 };
 
+/* ptlrpc/import.c */
+int ptlrpc_connect_import(struct obd_import *imp);
+int ptlrpc_disconnect_import(struct obd_import *imp);
+
 /* ptlrpc/pack_generic.c */
-int lustre_pack_msg(int count, int *lens, char **bufs, int *len,
-                    struct lustre_msg **msg);
+int lustre_msg_swabbed(struct lustre_msg *msg);
+int lustre_pack_request(struct ptlrpc_request *, int count, int *lens,
+                        char **bufs);
+int lustre_pack_reply(struct ptlrpc_request *, int count, int *lens,
+                      char **bufs);
 int lustre_msg_size(int count, int *lengths);
 int lustre_unpack_msg(struct lustre_msg *m, int len);
 void *lustre_msg_buf(struct lustre_msg *m, int n, int minlen);
@@ -535,12 +542,34 @@ void *lustre_swab_repbuf (struct ptlrpc_request *req, int n, int minlen,
                           void *swabber);
 
 /* ldlm/ldlm_lib.c */
-int client_import_connect(struct lustre_handle *conn, struct obd_device *obd,
+int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf);
+int client_obd_cleanup(struct obd_device * obddev, int flags);
+int client_connect_import(struct lustre_handle *conn, struct obd_device *obd,
                           struct obd_uuid *cluuid);
-int client_import_disconnect(struct lustre_handle *conn, int failover);
+int client_disconnect_export(struct obd_export *exp, int failover);
 
 /* ptlrpc/pinger.c */
 int ptlrpc_pinger_add_import(struct obd_import *imp);
 int ptlrpc_pinger_del_import(struct obd_import *imp);
 
+/* ptlrpc/lproc_ptlrpc.c */
+#ifdef __KERNEL__
+void ptlrpc_lprocfs_register_obd(struct obd_device *obddev);
+void ptlrpc_lprocfs_unregister_obd(struct obd_device *obddev);
+#else
+#define ptlrpc_lprocfs_register_obd(param...) do{}while(0)
+#define ptlrpc_lprocfs_unregister_obd(param...) do{}while(0)
+#endif
+
+/* ptlrpc/llog_server.c */
+struct llog_obd_ctxt;
+int llog_origin_handle_create(struct ptlrpc_request *req);
+int llog_origin_handle_next_block(struct ptlrpc_request *req);
+int llog_origin_handle_read_header(struct ptlrpc_request *req);
+int llog_origin_handle_close(struct ptlrpc_request *req);
+int llog_origin_handle_cancel(struct ptlrpc_request *req);
+
+/* ptlrpc/llog_client.c */
+extern struct llog_operations llog_client_ops;
+
 #endif
diff --git a/lustre/include/linux/lustre_otree.h b/lustre/include/linux/lustre_otree.h
deleted file mode 100644
index 3d8d5109cfaa7a734379740f95c9cdc938906fc9..0000000000000000000000000000000000000000
--- a/lustre/include/linux/lustre_otree.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- */
-#ifndef _LUSTRE_OTREE_H
-#define _LUSTRE_OTREE_H
-
-/* XXX ok, I can't make sense of our header nest right now.. */
-#ifdef __KERNEL__
-#include <linux/rbtree.h>
-#include <linux/spinlock.h>
-
-struct otree {
-        rb_root_t       ot_root;
-        spinlock_t      ot_lock;
-        unsigned long   ot_num_marked;
-};
-#else
-struct otree {
-        unsigned long   lalala;
-};
-#endif
-
-int ot_mark_offset(struct otree *ot, unsigned long offset);
-int ot_clear_extent(struct otree *ot, unsigned long start, unsigned long end);
-int ot_find_marked_extent(struct otree *ot, unsigned long *start,
-                          unsigned long *end);
-int ot_last_marked(struct otree *ot, unsigned long *last);
-unsigned long ot_num_marked(struct otree *ot);
-void ot_init(struct otree *ot);
-
-#endif
diff --git a/lustre/include/linux/lustre_user.h b/lustre/include/linux/lustre_user.h
new file mode 100644
index 0000000000000000000000000000000000000000..33a62512140eae62b57ae23a5a5adb0bbf0936ba
--- /dev/null
+++ b/lustre/include/linux/lustre_user.h
@@ -0,0 +1,65 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Lustre public user-space interface definitions.
+ */
+
+#ifndef _LUSTRE_USER_H
+#define _LUSTRE_USER_H
+#include <asm/types.h>
+
+#define LL_IOC_GETFLAGS                 _IOR ('f', 151, long)
+#define LL_IOC_SETFLAGS                 _IOW ('f', 152, long)
+#define LL_IOC_CLRFLAGS                 _IOW ('f', 153, long)
+#define LL_IOC_LOV_SETSTRIPE            _IOW ('f', 154, long)
+#define LL_IOC_LOV_GETSTRIPE            _IOW ('f', 155, long)
+
+#define O_LOV_DELAY_CREATE 0100000000  /* hopefully this does not conflict */
+
+#define LL_FILE_IGNORE_LOCK             0x00000001
+
+#define LOV_USER_MAGIC_V1 0x0BD10BD0
+#define LOV_USER_MAGIC    LOV_USER_MAGIC_V1
+
+#define LOV_PATTERN_RAID0 0x001
+#define LOV_PATTERN_RAID1 0x002
+#define LOV_PATTERN_FIRST 0x100
+
+struct lov_user_ost_data_v1 {     /* per-stripe data structure */
+        __u64 l_object_id;	  /* OST object ID */
+        __u64 l_object_gr;        /* OST object group (creating MDS number) */
+        __u32 l_ost_generation;   /* generation of this OST index */
+        __u16 l_ost_idx;          /* OST index in LOV */
+        __u16 l_reserved2;
+} __attribute__((packed));
+
+#define lov_user_md lov_user_md_v1
+struct lov_user_md_v1 {           /* LOV EA user data (host-endian) */
+        __u32 lmm_magic;          /* magic number = LOV_USER_MAGIC_V1 */
+        __u32 lmm_pattern;        /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+        __u64 lmm_object_id;      /* LOV object ID */
+        __u64 lmm_object_gr;      /* LOV object group */
+        __u32 lmm_stripe_size;    /* size of stripe in bytes */
+        __u16 lmm_stripe_count;   /* num stripes in use for this object */
+        __u16 lmm_stripe_offset;  /* starting stripe offset in lmm_objects */
+        struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+} __attribute__((packed));
+
+#endif /* _LUSTRE_USER_H */
diff --git a/lustre/include/linux/lvfs.h b/lustre/include/linux/lvfs.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e77ee16bab377def2551d409e4178f37c21fb03
--- /dev/null
+++ b/lustre/include/linux/lvfs.h
@@ -0,0 +1,105 @@
+#ifndef __LVFS_H__
+#define __LVFS_H__
+
+#include <linux/kp30.h>
+
+#if defined __KERNEL__
+#include <linux/lvfs_linux.h>
+#endif 
+
+#ifdef LIBLUSTRE
+#include <lvfs_user_fs.h>
+#endif
+
+/* simple.c */
+struct obd_ucred {
+        __u32 ouc_fsuid;
+        __u32 ouc_fsgid;
+        __u32 ouc_cap;
+        __u32 ouc_suppgid1;
+        __u32 ouc_suppgid2;
+};
+
+struct lvfs_callback_ops {
+        struct dentry *(*l_fid2dentry)(__u64 id_ino, __u32 gen, __u64 gr, void *data);
+};
+
+#define OBD_RUN_CTXT_MAGIC      0xC0FFEEAA
+#define OBD_CTXT_DEBUG          /* development-only debugging */
+struct obd_run_ctxt {
+        struct vfsmount *pwdmnt;
+        struct dentry   *pwd;
+        mm_segment_t     fs;
+        struct obd_ucred ouc;
+        int              ngroups;
+        struct lvfs_callback_ops cb_ops;
+#ifdef OBD_CTXT_DEBUG
+        __u32            magic;
+#endif
+};
+
+#ifdef OBD_CTXT_DEBUG
+#define OBD_SET_CTXT_MAGIC(ctxt) (ctxt)->magic = OBD_RUN_CTXT_MAGIC
+#else
+#define OBD_SET_CTXT_MAGIC(ctxt) do {} while(0)
+#endif
+
+/* lvfs_common.c */
+struct dentry *lvfs_fid2dentry(struct obd_run_ctxt *, __u64, __u32, __u64 ,void *data);
+
+void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
+               struct obd_ucred *cred);
+void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
+              struct obd_ucred *cred);
+
+#ifdef __KERNEL__
+
+struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode);
+struct dentry *simple_mknod(struct dentry *dir, char *name, int mode);
+int lustre_fread(struct file *file, void *buf, int len, loff_t *off);
+int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off);
+int lustre_fsync(struct file *file);
+long l_readdir(struct file * file, void * dirent, unsigned int count);
+
+static inline void l_dput(struct dentry *de)
+{
+        if (!de || IS_ERR(de))
+                return;
+        //shrink_dcache_parent(de);
+        LASSERT(atomic_read(&de->d_count) > 0);
+        dput(de);
+}
+
+/* We need to hold the inode semaphore over the dcache lookup itself, or we
+ * run the risk of entering the filesystem lookup path concurrently on SMP
+ * systems, and instantiating two inodes for the same entry.  We still
+ * protect against concurrent addition/removal races with the DLM locking.
+ */
+static inline struct dentry *ll_lookup_one_len(char *fid_name,
+                                               struct dentry *dparent,
+                                               int fid_namelen)
+{
+        struct dentry *dchild;
+
+        down(&dparent->d_inode->i_sem);
+        dchild = lookup_one_len(fid_name, dparent, fid_namelen);
+        up(&dparent->d_inode->i_sem);
+
+        return dchild;
+}
+
+static inline void ll_sleep(int t)
+{
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(t * HZ);
+        set_current_state(TASK_RUNNING);
+}
+#endif
+
+#define LL_FID_NAMELEN         (16 + 1 + 8 + 1)
+static inline int ll_fid2str(char *str, __u64 id, __u32 generation)
+{
+        return sprintf(str, "%llx:%08x", (unsigned long long)id, generation);
+}
+
+#endif
diff --git a/lustre/include/linux/lvfs_linux.h b/lustre/include/linux/lvfs_linux.h
new file mode 100644
index 0000000000000000000000000000000000000000..b38d6f0c3048908e3cde3edf1eee0e7bee8f4232
--- /dev/null
+++ b/lustre/include/linux/lvfs_linux.h
@@ -0,0 +1,38 @@
+#ifndef __LVFS_LINUX_H__
+#define __LVFS_LINUX_H__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/jbd.h>
+
+#include <linux/lvfs.h>
+/* we have made EXT3_IOC_SETFLAGS a Lustre constant */
+#include <linux/ext3_fs.h>
+
+#define l_file file
+#define l_dentry dentry
+#define l_inode inode
+
+#define l_filp_open filp_open
+
+struct obd_run_ctxt;
+struct l_file *l_dentry_open(struct obd_run_ctxt *, struct l_dentry *,
+                             int flags);
+
+struct l_linux_dirent {
+        ino_t           d_ino;
+        unsigned long   d_off;
+        unsigned short  d_reclen;
+        char            d_name[1]; 
+};
+
+struct l_readdir_callback {
+        struct l_linux_dirent *current_dir;
+        struct l_linux_dirent *previous;
+        int count;
+        int error;
+};
+
+#endif
diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h
index f30cbb2fb02ee5582ae3c60a28ee1909c5ebe077..03ea9c9b1cc75ece94d15693bde6c66cec0b425c 100644
--- a/lustre/include/linux/obd.h
+++ b/lustre/include/linux/obd.h
@@ -12,7 +12,6 @@
 
 #define IOC_OSC_TYPE         'h'
 #define IOC_OSC_MIN_NR       20
-#define IOC_OSC_REGISTER_LOV _IOWR(IOC_OSC_TYPE, 20, struct obd_device *)
 #define IOC_OSC_SET_ACTIVE   _IOWR(IOC_OSC_TYPE, 21, struct obd_device *)
 #define IOC_OSC_MAX_NR       50
 
@@ -35,27 +34,50 @@
 #include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
 #include <linux/lustre_export.h>
-#include <linux/lustre_otree.h>
 
-struct lov_oinfo { /* per-child structure */
+/* this is really local to the OSC */
+struct loi_oap_pages {
+        struct list_head        lop_pending;
+        int                     lop_num_pending;
+        struct list_head        lop_urgent;
+        struct list_head        lop_pending_sync;
+};
+
+struct lov_oinfo {                 /* per-stripe data structure */
         __u64 loi_id;              /* object ID on the target OST */
+        __u64 loi_gr;              /* object group on the target OST */
         struct lustre_handle *loi_handle; /* open file handle for obj on OST */
-        int loi_ost_idx;           /* OST stripe index in lmd_objects array */
+        int loi_ost_idx;           /* OST stripe index in lov_tgt_desc->tgts */
+        int loi_ost_gen;           /* generation of this loi_ost_idx */
+
         /* tracking offsets per file, per stripe.. */
-        struct otree *loi_dirty_ot; /* lets lov stack on osc */
-        struct otree loi_dirty_ot_inline;
+        struct loi_oap_pages loi_read_lop;
+        struct loi_oap_pages loi_write_lop;
+        struct list_head loi_cli_item;
 };
 
+static inline void loi_init(struct lov_oinfo *loi)
+{
+        INIT_LIST_HEAD(&loi->loi_read_lop.lop_pending);
+        INIT_LIST_HEAD(&loi->loi_read_lop.lop_urgent);
+        INIT_LIST_HEAD(&loi->loi_read_lop.lop_pending_sync);
+        INIT_LIST_HEAD(&loi->loi_write_lop.lop_pending);
+        INIT_LIST_HEAD(&loi->loi_write_lop.lop_urgent);
+        INIT_LIST_HEAD(&loi->loi_write_lop.lop_pending_sync);
+        INIT_LIST_HEAD(&loi->loi_cli_item);
+}
+
 struct lov_stripe_md {
         /* Public members. */
         __u64 lsm_object_id;        /* lov object id */
+        __u64 lsm_object_gr;        /* lov object id */
         __u64 lsm_maxbytes;
 
         /* LOV-private members start here -- only for use in lov/. */
         __u32 lsm_magic;
         __u32 lsm_stripe_size;      /* size of the stripe */
-        unsigned lsm_stripe_offset; /* offset of first stripe in lmd_objects */
-        unsigned lsm_stripe_count;  /* how many objects are being striped on */
+        __u32 lsm_pattern;          /* striping pattern (RAID0, RAID1) */
+        unsigned lsm_stripe_count;  /* number of objects being striped over */
         struct lov_oinfo lsm_oinfo[0];
 };
 
@@ -74,47 +96,76 @@ struct brw_page {
         obd_flag flag;
 };
 
+enum async_flags {
+        ASYNC_READY = 0x1,
+        ASYNC_URGENT = 0x2,
+        ASYNC_COUNT_STABLE = 0x4,
+};
+
+struct obd_async_page_ops {
+        int  (*ap_make_ready)(void *data, int cmd);
+        int  (*ap_refresh_count)(void *data, int cmd);
+        void (*ap_fill_obdo)(void *data, int cmd, struct obdo *oa);
+        void (*ap_completion)(void *data, int cmd, int rc);
+};
+
+struct obd_sync_io_container {
+        spinlock_t      osic_lock;
+        int             osic_pending;
+        int             osic_rc;
+        wait_queue_head_t osic_waitq;
+};
+
 /* Individual type definitions */
 
 struct ost_server_data;
 
 struct filter_obd {
         const char          *fo_fstype;
-        char                *fo_nspath;
         struct super_block  *fo_sb;
         struct vfsmount     *fo_vfsmnt;
-        struct obd_run_ctxt  fo_ctxt;
         struct dentry       *fo_dentry_O;
-        struct dentry       *fo_dentry_O_mode[16];
+        struct dentry      **fo_dentry_O_groups;
         struct dentry      **fo_dentry_O_sub;
         spinlock_t           fo_objidlock; /* protect fo_lastobjid increment */
         spinlock_t           fo_translock; /* protect fsd_last_rcvd increment */
         struct file         *fo_rcvd_filp;
         struct filter_server_data *fo_fsd;
         unsigned long       *fo_last_rcvd_slots;
+        __u64                fo_mount_count;
 
         struct file_operations *fo_fop;
         struct inode_operations *fo_iop;
         struct address_space_operations *fo_aops;
 
         struct list_head     fo_export_list;
-        spinlock_t           fo_fddlock; /* protect setting dentry->d_fsdata */
         int                  fo_subdir_count;
         spinlock_t           fo_grant_lock;       /* protects tot_granted */
         obd_size             fo_tot_granted;
         obd_size             fo_tot_cached;
 
-        struct llog_handle  *fo_catalog;
         struct obd_import   *fo_mdc_imp;
         struct obd_uuid      fo_mdc_uuid;
         struct lustre_handle fo_mdc_conn;
+#if 0
         struct ptlrpc_client fo_mdc_client;
-        struct llog_commit_data *fo_llcd;
-        struct semaphore     fo_sem; /* protects fo_llcd */
+#endif
+        struct file        **fo_last_objid_files;
+        __u64               *fo_last_objids; //last created object ID for groups
+
+        struct semaphore     fo_alloc_lock;
 };
 
 struct mds_server_data;
 
+/* if we find more consumers this could be generalized */
+#define OSC_HIST_MAX 32
+struct osc_histogram {
+        spinlock_t      oh_lock;
+        unsigned long   oh_buckets[OSC_HIST_MAX];
+};
+
+struct mdc_rpc_lock;
 struct client_obd {
         struct obd_import       *cl_import;
         struct semaphore         cl_sem;
@@ -123,16 +174,16 @@ struct client_obd {
          * call obd_size_wiremd() all the time. */
         int                      cl_max_mds_easize;
         int                      cl_max_mds_cookiesize;
-        /* XXX can we replace cl_containing_lov with mgmt-events? */
-        struct obd_device       *cl_containing_lov;
         kdev_t                   cl_sandev;
 
-        struct llog_commit_data *cl_llcd;
+        //struct llog_canceld_ctxt *cl_llcd; /* it's included by obd_llog_ctxt */
         void                    *cl_llcd_offset;
 
         struct semaphore         cl_dirty_sem;
-        obd_size                 cl_dirty;  /* both in bytes */
-        obd_size                 cl_dirty_granted;
+        obd_size                 cl_dirty;  /* all _dirty_ in bytes */
+        obd_size                 cl_dirty_granted; /* from ost */
+        obd_size                 cl_dirty_max; /* allowed w/o rpc */
+        struct list_head         cl_cache_waiters;
 
         struct obd_device       *cl_mgmtcli_obd;
 
@@ -140,6 +191,25 @@ struct client_obd {
          * clients and OSTs that don't have the grant code in yet.. it can
          * be yanked once everything speaks grants */
         char                     cl_ost_can_grant;
+
+        /* keep track of objects that have lois that contain pages which
+         * have been queued for async brw.  this lock also protects the
+         * lists of obd_client_pages that hang off of the loi */
+        spinlock_t               cl_loi_list_lock;
+        struct list_head         cl_loi_ready_list;
+        int                      cl_brw_in_flight;
+        /* just a sum of the loi/lop pending numbers to be exported by /proc */
+        int                      cl_pending_w_pages;
+        int                      cl_pending_r_pages;
+        int                      cl_max_pages_per_rpc;
+        int                      cl_max_rpcs_in_flight;
+        struct osc_histogram     cl_read_rpc_hist;
+        struct osc_histogram     cl_write_rpc_hist;
+        struct osc_histogram     cl_read_page_hist;
+        struct osc_histogram     cl_write_page_hist;
+
+        struct mdc_rpc_lock     *cl_rpc_lock;
+        struct mdc_rpc_lock     *cl_setattr_lock;
 };
 
 /* Like a client, with some hangers-on.  Keep mc_client_obd first so that we
@@ -147,7 +217,7 @@ struct client_obd {
 struct mgmtcli_obd {
         struct client_obd        mc_client_obd; /* nested */
         struct ptlrpc_thread    *mc_ping_thread;
-        struct lustre_handle     mc_ping_handle; /* XXX single-target */
+        struct obd_export       *mc_ping_exp; /* XXX single-target */
         struct list_head         mc_registered;
         void                    *mc_hammer;
 };
@@ -158,41 +228,36 @@ struct mds_obd {
         struct ptlrpc_service           *mds_service;
         struct ptlrpc_service           *mds_setattr_service;
         struct ptlrpc_service           *mds_readpage_service;
-
         struct super_block              *mds_sb;
         struct vfsmount                 *mds_vfsmnt;
         struct dentry                   *mds_fid_de;
-        struct obd_run_ctxt              mds_ctxt;
-        struct file_operations          *mds_fop;
-        struct inode_operations         *mds_iop;
-        struct address_space_operations *mds_aops;
-
         int                              mds_max_mdsize;
         int                              mds_max_cookiesize;
         struct file                     *mds_rcvd_filp;
         spinlock_t                       mds_transno_lock;
         __u64                            mds_last_transno;
         __u64                            mds_mount_count;
+        __u64                            mds_io_epoch;
+        struct semaphore                 mds_epoch_sem;
         struct ll_fid                    mds_rootfid;
         struct mds_server_data          *mds_server_data;
         struct dentry                   *mds_pending_dir;
         struct dentry                   *mds_logs_dir;
-
-        struct llog_handle              *mds_catalog;
-        struct obd_device               *mds_osc_obd;
-        struct obd_uuid                  mds_osc_uuid;
-        struct lustre_handle             mds_osc_conn;
-
+        struct dentry                   *mds_objects_dir;
+        struct llog_handle              *mds_cfg_llh;
+//        struct llog_handle              *mds_catalog;
+        struct obd_device               *mds_osc_obd; /* XXX lov_obd */
+        struct obd_uuid                  mds_lov_uuid;
+        char                            *mds_profile;
+        struct obd_export               *mds_osc_exp; /* XXX lov_exp */
         int                              mds_has_lov_desc;
         struct lov_desc                  mds_lov_desc;
+        obd_id                          *mds_lov_objids;
+        int                              mds_lov_objids_valid;
+        int                              mds_lov_nextid_set;
+        struct file                     *mds_lov_objid_filp;
         unsigned long                   *mds_client_bitmap;
-};
-
-struct ldlm_obd {
-        struct ptlrpc_service *ldlm_cb_service;
-        struct ptlrpc_service *ldlm_cancel_service;
-        struct ptlrpc_client *ldlm_client;
-        struct ptlrpc_connection *ldlm_server_conn;
+        struct semaphore                 mds_orphan_recovery_sem;
 };
 
 struct echo_obd {
@@ -220,7 +285,7 @@ struct ptlbd_obd {
         struct ptlrpc_client    bd_client;
         struct obd_import       *bd_import;
         struct obd_uuid         bd_server_uuid;
-        struct lustre_handle    bd_connect_handle;
+        struct obd_export       *bd_exp;
         int refcount; /* XXX sigh */
 };
 
@@ -238,32 +303,30 @@ struct recovd_obd {
 
 struct ost_obd {
         struct ptlrpc_service *ost_service;
+        struct ptlrpc_service *ost_create_service;
 };
 
 struct echo_client_obd {
-        struct lustre_handle ec_conn;   /* the local connection to osc/lov */
+        struct obd_export   *ec_exp;   /* the local connection to osc/lov */
         spinlock_t           ec_lock;
         struct list_head     ec_objects;
-        int                  ec_lsmsize;
         int                  ec_nstripes;
         __u64                ec_unique;
 };
 
 struct cache_obd {
-        struct lustre_handle cobd_target;   /* local connection to target obd */
-        struct lustre_handle cobd_cache;    /* local connection to cache obd */
+        struct obd_export *cobd_target_exp;/* local connection to target obd */
+        struct obd_export *cobd_cache_exp; /* local connection to cache obd */
 };
 
 struct lov_tgt_desc {
-        struct obd_uuid uuid;
-        struct lustre_handle conn;
-        struct llog_handle *ltd_cathandle;
-        int active; /* is this target available for requests, etc */
+        struct obd_uuid          uuid;
+        struct obd_export       *ltd_exp;
+        int                      active; /* is this target up for requests */
 };
 
 struct lov_obd {
         spinlock_t lov_lock;
-        struct obd_device *mdcobd;
         struct lov_desc desc;
         int bufsize;
         int refcount;
@@ -275,22 +338,24 @@ struct niobuf_local {
         __u64 offset;
         __u32 len;
         __u32 flags;
-        __u32 rc;
+        int rc;
         struct page *page;
         struct dentry *dentry;
         unsigned long start;
 };
 
+
 /* Don't conflict with on-wire flags OBD_BRW_WRITE, etc */
 #define N_LOCAL_TEMP_PAGE 0x10000000
 
 struct obd_trans_info {
-        __u64                   oti_transno;
+        __u64                    oti_transno;
+        __u64                   *oti_objid;
         /* Only used on the server side for tracking acks. */
         struct oti_req_ack_lock {
                 struct lustre_handle lock;
                 __u32                mode;
-        } oti_ack_locks[4];
+        }                        oti_ack_locks[4];
         void                    *oti_handle;
         struct llog_cookie       oti_onecookie;
         struct llog_cookie      *oti_logcookies;
@@ -325,6 +390,24 @@ static inline void oti_free_cookies(struct obd_trans_info *oti)
         oti->oti_numcookies = 0;
 }
 
+/* llog contexts */
+enum llog_ctxt_id {
+        LLOG_CONFIG_ORIG_CTXT =  0,
+        LLOG_CONFIG_REPL_CTXT =  1,
+        LLOG_UNLINK_ORIG_CTXT =  2,
+        LLOG_UNLINK_REPL_CTXT =  3,
+        LLOG_SIZE_ORIG_CTXT   =  4,
+        LLOG_SIZE_REPL_CTXT   =  5,
+        LLOG_MD_ORIG_CTXT     =  6,
+        LLOG_MD_REPL_CTXT     =  7,
+        LLOG_RD1_ORIG_CTXT    =  8,
+        LLOG_RD1_REPL_CTXT    =  9,
+        LLOG_TEST_ORIG_CTXT   = 10,
+        LLOG_TEST_REPL_CTXT   = 11,
+        LLOG_MAX_CTXTS
+};
+
+
 /* corresponds to one of the obd's */
 struct obd_device {
         struct obd_type *obd_type;
@@ -342,22 +425,29 @@ struct obd_device {
         struct proc_dir_entry *obd_proc_entry;
         struct list_head       obd_exports;
         int                    obd_num_exports;
-        struct list_head       obd_imports;
         struct ldlm_namespace *obd_namespace;
         struct ptlrpc_client   obd_ldlm_client; /* XXX OST/MDS only */
         /* a spinlock is OK for what we do now, may need a semaphore later */
         spinlock_t             obd_dev_lock;
         __u64                  obd_last_committed;
         struct fsfilt_operations *obd_fsops;
-        struct obd_statfs      obd_osfs;
-        unsigned long          obd_osfs_age;
+        struct llog_ctxt        *obd_llog_ctxt[LLOG_MAX_CTXTS];
+        struct obd_statfs       obd_osfs;
+        unsigned long           obd_osfs_age;
+        struct obd_run_ctxt     obd_ctxt;
+        struct obd_device       *obd_observer;
+        struct obd_export       *obd_self_export;
 
         /* XXX encapsulate all this recovery data into one struct */
         svc_handler_t                    obd_recovery_handler;
+        int                              obd_max_recoverable_clients;
+        int                              obd_connected_clients;
         int                              obd_recoverable_clients;
         spinlock_t                       obd_processing_task_lock;
         pid_t                            obd_processing_task;
         __u64                            obd_next_recovery_transno;
+        int                              obd_replayed_requests;
+        int                              obd_requests_queued_for_recovery;
         wait_queue_head_t                obd_next_transno_waitq;
         wait_queue_head_t                obd_commit_waitq;
         struct timer_list                obd_recovery_timer;
@@ -370,7 +460,6 @@ struct obd_device {
                 struct client_obd cli;
                 struct ost_obd ost;
                 struct echo_client_obd echo_client;
-                struct ldlm_obd ldlm;
                 struct echo_obd echo;
                 struct recovd_obd recovd;
                 struct lov_obd lov;
@@ -381,6 +470,8 @@ struct obd_device {
        /* Fields used by LProcFS */
         unsigned int           obd_cntr_base;
         struct lprocfs_stats  *obd_stats;
+        struct proc_dir_entry *obd_svc_procroot;
+        struct lprocfs_stats  *obd_svc_stats;
 };
 
 #define OBD_OPT_FORCE           0x0001
@@ -390,64 +481,88 @@ struct obd_device {
 
 struct obd_ops {
         struct module *o_owner;
-        int (*o_iocontrol)(unsigned int cmd, struct lustre_handle *, int len,
+        int (*o_iocontrol)(unsigned int cmd, struct obd_export *exp, int len,
                            void *karg, void *uarg);
-        int (*o_get_info)(struct lustre_handle *, __u32 keylen, void *key,
+        int (*o_get_info)(struct obd_export *, __u32 keylen, void *key,
                           __u32 *vallen, void *val);
-        int (*o_set_info)(struct lustre_handle *, __u32 keylen, void *key,
+        int (*o_set_info)(struct obd_export *, __u32 keylen, void *key,
                           __u32 vallen, void *val);
         int (*o_attach)(struct obd_device *dev, obd_count len, void *data);
         int (*o_detach)(struct obd_device *dev);
         int (*o_setup) (struct obd_device *dev, obd_count len, void *data);
+        int (*o_postsetup) (struct obd_device *dev);
+        int (*o_precleanup)(struct obd_device *dev, int flags);
         int (*o_cleanup)(struct obd_device *dev, int flags);
+        int (*o_postrecov)(struct obd_device *dev);
         int (*o_connect)(struct lustre_handle *conn, struct obd_device *src,
                          struct obd_uuid *cluuid);
-        int (*o_disconnect)(struct lustre_handle *conn, int flags);
+        int (*o_disconnect)(struct obd_export *exp, int flags);
 
         int (*o_statfs)(struct obd_device *obd, struct obd_statfs *osfs,
                         unsigned long max_age);
-        int (*o_syncfs)(struct obd_export *exp);
-        int (*o_packmd)(struct lustre_handle *, struct lov_mds_md **disk_tgt,
+        int (*o_packmd)(struct obd_export *exp, struct lov_mds_md **disk_tgt,
                         struct lov_stripe_md *mem_src);
-        int (*o_unpackmd)(struct lustre_handle *conn,
-                          struct lov_stripe_md **mem_tgt,
+        int (*o_unpackmd)(struct obd_export *exp,struct lov_stripe_md **mem_tgt,
                           struct lov_mds_md *disk_src, int disk_len);
         int (*o_preallocate)(struct lustre_handle *, obd_count *req,
                              obd_id *ids);
-        int (*o_create)(struct lustre_handle *conn,  struct obdo *oa,
+        int (*o_create)(struct obd_export *exp,  struct obdo *oa,
                         struct lov_stripe_md **ea, struct obd_trans_info *oti);
-        int (*o_destroy)(struct lustre_handle *conn, struct obdo *oa,
+        int (*o_destroy)(struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *ea, struct obd_trans_info *oti);
-        int (*o_setattr)(struct lustre_handle *conn, struct obdo *oa,
+        int (*o_setattr)(struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *ea, struct obd_trans_info *oti);
-        int (*o_getattr)(struct lustre_handle *conn, struct obdo *oa,
+        int (*o_getattr)(struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *ea);
-        int (*o_getattr_async)(struct lustre_handle *conn, struct obdo *oa,
+        int (*o_getattr_async)(struct obd_export *exp, struct obdo *oa,
                                struct lov_stripe_md *ea,
                                struct ptlrpc_request_set *set);
-        int (*o_open)(struct lustre_handle *conn, struct obdo *oa,
-                      struct lov_stripe_md *ea, struct obd_trans_info *oti,
-                      struct obd_client_handle *och);
-        int (*o_close)(struct lustre_handle *conn, struct obdo *oa,
-                       struct lov_stripe_md *ea, struct obd_trans_info *oti);
-        int (*o_brw)(int rw, struct lustre_handle *conn, struct obdo *oa,
+        int (*o_brw)(int rw, struct obd_export *exp, struct obdo *oa,
                      struct lov_stripe_md *ea, obd_count oa_bufs,
                      struct brw_page *pgarr, struct obd_trans_info *oti);
-        int (*o_brw_async)(int rw, struct lustre_handle *conn, struct obdo *oa,
+        int (*o_brw_async)(int rw, struct obd_export *exp, struct obdo *oa,
                            struct lov_stripe_md *ea, obd_count oa_bufs,
                            struct brw_page *pgarr, struct ptlrpc_request_set *,
                            struct obd_trans_info *oti);
-        int (*o_punch)(struct lustre_handle *conn, struct obdo *oa,
-                       struct lov_stripe_md *ea, obd_size count,
-                       obd_off offset, struct obd_trans_info *oti);
-        int (*o_sync)(struct lustre_handle *conn, struct obdo *oa,
-                      obd_size count, obd_off offset);
+        int (*o_prep_async_page)(struct obd_export *exp, 
+                                 struct lov_stripe_md *lsm,
+                                 struct lov_oinfo *loi, 
+                                 struct page *page, obd_off offset, 
+                                 struct obd_async_page_ops *ops, void *data,
+                                 void **res);
+        int (*o_queue_async_io)(struct obd_export *exp, 
+                                struct lov_stripe_md *lsm, 
+                                struct lov_oinfo *loi, void *cookie, 
+                                int cmd, obd_off off, int count, 
+                                obd_flag brw_flags, obd_flag async_flags);
+        int (*o_queue_sync_io)(struct obd_export *exp, 
+                               struct lov_stripe_md *lsm, 
+                               struct lov_oinfo *loi, 
+                               struct obd_sync_io_container *osic, 
+                               void *cookie, int cmd, obd_off off, int count, 
+                               obd_flag brw_flags);
+        int (*o_trigger_sync_io)(struct obd_export *exp, 
+                                 struct lov_stripe_md *lsm, 
+                                 struct lov_oinfo *loi, 
+                                 struct obd_sync_io_container *osic);
+        int (*o_set_async_flags)(struct obd_export *exp,
+                                struct lov_stripe_md *lsm,
+                                struct lov_oinfo *loi, void *cookie,
+                                obd_flag async_flags);
+        int (*o_teardown_async_page)(struct obd_export *exp,
+                                     struct lov_stripe_md *lsm,
+                                     struct lov_oinfo *loi, void *cookie);
+        int (*o_punch)(struct obd_export *exp, struct obdo *oa,
+                       struct lov_stripe_md *ea, obd_size start,
+                       obd_size end, struct obd_trans_info *oti);
+        int (*o_sync)(struct obd_export *exp, struct obdo *oa,
+                      struct lov_stripe_md *ea, obd_size start, obd_size end);
         int (*o_migrate)(struct lustre_handle *conn, struct lov_stripe_md *dst,
-                         struct lov_stripe_md *src, obd_size count,
-                         obd_off offset);
+                         struct lov_stripe_md *src, obd_size start,
+                         obd_size end, struct obd_trans_info *oti);
         int (*o_copy)(struct lustre_handle *dstconn, struct lov_stripe_md *dst,
                       struct lustre_handle *srconn, struct lov_stripe_md *src,
-                      obd_size count, obd_off offset, struct obd_trans_info *);
+                      obd_size start, obd_size end, struct obd_trans_info *);
         int (*o_iterate)(struct lustre_handle *conn,
                          int (*)(obd_id, obd_gr, void *),
                          obd_id *startid, obd_gr group, void *data);
@@ -459,50 +574,56 @@ struct obd_ops {
                           int objcount, struct obd_ioobj *obj,
                           int niocount, struct niobuf_local *local,
                           struct obd_trans_info *oti);
-        int (*o_enqueue)(struct lustre_handle *conn, struct lov_stripe_md *md,
+        int (*o_enqueue)(struct obd_export *exp, struct lov_stripe_md *md,
                          struct lustre_handle *parent_lock,
                          __u32 type, void *cookie, int cookielen, __u32 mode,
                          int *flags, void *cb, void *data,
                          struct lustre_handle *lockh);
-        int (*o_match)(struct lustre_handle *conn, struct lov_stripe_md *md,
+        int (*o_match)(struct obd_export *exp, struct lov_stripe_md *md,
                          __u32 type, void *cookie, int cookielen, __u32 mode,
                          int *flags, void *data, struct lustre_handle *lockh);
-        int (*o_cancel)(struct lustre_handle *, struct lov_stripe_md *md,
+        int (*o_change_cbdata)(struct obd_export *exp,
+                               struct lov_stripe_md *lsm, ldlm_iterator_t it,
+                               void *data);
+        int (*o_cancel)(struct obd_export *, struct lov_stripe_md *md,
                         __u32 mode, struct lustre_handle *);
-        int (*o_cancel_unused)(struct lustre_handle *, struct lov_stripe_md *,
+        int (*o_cancel_unused)(struct obd_export *, struct lov_stripe_md *,
                                int flags, void *opaque);
-        int (*o_log_add)(struct lustre_handle *conn,
-                         struct llog_handle *cathandle,
-                         struct llog_trans_hdr *rec, struct lov_stripe_md *lsm,
-                         struct llog_cookie *logcookies, int numcookies);
-        int (*o_log_cancel)(struct lustre_handle *, struct lov_stripe_md *,
-                            int count, struct llog_cookie *, int flags);
         int (*o_san_preprw)(int cmd, struct obd_export *exp,
                             struct obdo *oa, int objcount,
                             struct obd_ioobj *obj, int niocount,
                             struct niobuf_remote *remote);
-        int (*o_mark_page_dirty)(struct lustre_handle *conn,
-                                 struct lov_stripe_md *ea,
-                                 unsigned long offset);
-        int (*o_clear_dirty_pages)(struct lustre_handle *conn,
-                                   struct lov_stripe_md *ea,
-                                   unsigned long start,
-                                   unsigned long end,
-                                   unsigned long *cleared);
-        int (*o_last_dirty_offset)(struct lustre_handle *conn,
-                                   struct lov_stripe_md *ea,
-                                   unsigned long *offset);
-        void (*o_destroy_export)(struct obd_export *exp);
+        int (*o_init_export)(struct obd_export *exp);
+        int (*o_destroy_export)(struct obd_export *exp);
+
+        /* llog related obd_methods */
+        int (*o_llog_init)(struct obd_device *obd, struct obd_device *disk_obd,
+                           int count, struct llog_logid *logid);
+        int (*o_llog_finish)(struct obd_device *obd, int count);
+
+        /* only until proper file size mechanics arrive */
+        int (*o_lock_contains)(struct obd_export *exp, 
+                               struct lov_stripe_md *lsm, 
+                               struct ldlm_lock *lock, obd_off offset);
 
         /* metadata-only methods */
-        int (*o_pin)(struct lustre_handle *, obd_id ino, __u32 gen, int type,
+        int (*o_pin)(struct obd_export *, obd_id ino, __u32 gen, int type,
                      struct obd_client_handle *, int flag);
-        int (*o_unpin)(struct lustre_handle *, struct obd_client_handle *, int);
+        int (*o_unpin)(struct obd_export *, struct obd_client_handle *, int);
+
+        int (*o_invalidate_import)(struct obd_device *, struct obd_import *);
+
+        int (*o_notify)(struct obd_device *obd, struct obd_device *watched,
+                        int active);
+        /* 
+         * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line
+         * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c.
+         * Also, add a wrapper function in include/linux/obd_class.h.
+         */
 
-        /* If adding ops, also update obdclass/lprocfs_status.c,
-         * and include/linux/obd_class.h */
 };
 
+
 static inline void obd_transno_commit_cb(struct obd_device *obd, __u64 transno,
                                          int error)
 {
diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h
index 2e57d2f111b559f1c14d2bdd372cd6dbfa139c4d..b3a97694cf8cb54c00ee5db804d9a617ae52b597 100644
--- a/lustre/include/linux/obd_class.h
+++ b/lustre/include/linux/obd_class.h
@@ -41,29 +41,82 @@
 #include <linux/obd.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
-#include <linux/lustre_mds.h>
-#include <linux/lustre_dlm.h>
 #include <linux/lprocfs_status.h>
 
-
 /* OBD Device Declarations */
 #define MAX_OBD_DEVICES 128
 extern struct obd_device obd_dev[MAX_OBD_DEVICES];
 
 /* OBD Operations Declarations */
 extern struct obd_device *class_conn2obd(struct lustre_handle *);
+extern struct obd_device *class_exp2obd(struct obd_export *);
 
 /* genops.c */
 struct obd_export *class_conn2export(struct lustre_handle *);
 int class_register_type(struct obd_ops *ops, struct lprocfs_vars *, char *nm);
 int class_unregister_type(char *nm);
+
+struct obd_device *class_newdev(int *dev);
+
 int class_name2dev(char *name);
 struct obd_device *class_name2obd(char *name);
 int class_uuid2dev(struct obd_uuid *uuid);
 struct obd_device *class_uuid2obd(struct obd_uuid *uuid);
+struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid, 
+                                          char * typ_name,
+                                          struct obd_uuid *grp_uuid);
+
+void osic_init(struct obd_sync_io_container *osic);
+void osic_add_one(struct obd_sync_io_container *osic);
+void osic_complete_one(struct obd_sync_io_container *osic, int rc);
+int osic_wait(struct obd_sync_io_container *osic);
+
+/* config.c */
+int class_process_config(struct lustre_cfg *lcfg);
+int class_attach(struct lustre_cfg *lcfg);
+int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
+int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg);
+int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg);
+
+/* Passed as data param to class_config_parse_llog */
+struct config_llog_instance {
+        char * cfg_instance;
+        struct obd_uuid cfg_uuid;
+        ptl_nid_t  cfg_local_nid;
+};
+int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, 
+                            struct config_llog_instance *cfg);
+int class_config_dump_llog(struct llog_ctxt *ctxt, char *name, 
+                           struct config_llog_instance *cfg);
+
+struct lustre_profile {
+        struct list_head lp_list;
+        char * lp_profile;
+        char * lp_osc;
+        char * lp_mdc;
+};
 
-struct obd_export *class_export_get(struct obd_export *);
-void class_export_put(struct obd_export *);
+struct lustre_profile *class_get_profile(char * prof);
+
+#define class_export_get(exp)                                                  \
+({                                                                             \
+        struct obd_export *exp_ = exp;                                         \
+        atomic_inc(&exp_->exp_refcount);                                       \
+        CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp_,          \
+               atomic_read(&exp_->exp_refcount));                              \
+        exp_;                                                                  \
+})
+
+#define class_export_put(exp)                                                  \
+do {                                                                           \
+        LASSERT((exp) != NULL);                                                \
+        CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", (exp),         \
+               atomic_read(&(exp)->exp_refcount) - 1);                         \
+        LASSERT(atomic_read(&(exp)->exp_refcount) > 0);                        \
+        LASSERT(atomic_read(&(exp)->exp_refcount) < 0x5a5a5a);                 \
+        __class_export_put(exp);                                               \
+} while (0)
+void __class_export_put(struct obd_export *);
 struct obd_export *class_new_export(struct obd_device *obddev);
 void class_unlink_export(struct obd_export *exp);
 
@@ -76,7 +129,7 @@ struct obd_type *class_get_type(char *name);
 void class_put_type(struct obd_type *type);
 int class_connect(struct lustre_handle *conn, struct obd_device *obd,
                   struct obd_uuid *cluuid);
-int class_disconnect(struct lustre_handle *conn, int failover);
+int class_disconnect(struct obd_export *exp, int failover);
 void class_disconnect_exports(struct obd_device *obddev, int failover);
 /* generic operations shared by various OBD types */
 int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data);
@@ -92,6 +145,7 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid);
 #endif
 void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid);
 int obdo_cmp_md(struct obdo *dst, struct obdo *src, obd_flag compare);
+void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj);
 
 static inline int obd_check_conn(struct lustre_handle *conn)
 {
@@ -133,6 +187,7 @@ static inline int obd_check_conn(struct lustre_handle *conn)
 
 #define OBT(dev)        (dev)->obd_type
 #define OBP(dev, op)    (dev)->obd_type->typ_ops->o_ ## op
+#define CTXTP(ctxt, op) (ctxt)->loc_logops->lop_##op
 
 /* Ensure obd_setup: used for disconnect which might be called while
    an obd is stopping. */
@@ -236,44 +291,66 @@ do {                                                            \
 #define OBD_COUNTER_INCREMENT(obd, op)
 #endif
 
-#define OBD_CHECK_OP(obd, op)                                   \
+#define OBD_CHECK_OP(obd, op, err)                              \
 do {                                                            \
-        if (!OBP((obd), op)) {                                  \
+        if (!OBT(obd) || !OBP((obd), op)) {\
+                if (err)                                        \
+                        CERROR("obd_" #op ": dev %d no operation\n",    \
+                               obd->obd_minor);                         \
+                RETURN(err);                                    \
+        }                                                       \
+} while (0)
+
+#define EXP_CHECK_OP(exp, op)                                   \
+do {                                                            \
+        if ((exp) == NULL) {                                    \
+                CERROR("obd_" #op ": NULL export\n");           \
+                RETURN(-ENODEV);                                \
+        }                                                       \
+        if ((exp)->exp_obd == NULL || !OBT((exp)->exp_obd)) {   \
+                CERROR("obd_" #op ": cleaned up obd\n");        \
+                RETURN(-EOPNOTSUPP);                            \
+        }                                                       \
+        if (!OBT((exp)->exp_obd) || !OBP((exp)->exp_obd, op)) { \
                 CERROR("obd_" #op ": dev %d no operation\n",    \
-                       obd->obd_minor);                         \
+                       (exp)->exp_obd->obd_minor);              \
                 RETURN(-EOPNOTSUPP);                            \
         }                                                       \
 } while (0)
 
-static inline int obd_get_info(struct lustre_handle *conn, __u32 keylen,
+#define CTXT_CHECK_OP(ctxt, op, err)                                         \
+do {                                                            \
+        if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) {                     \
+                if (err)                                        \
+                        CERROR("lop_" #op ": dev %d no operation\n",    \
+                               ctxt->loc_obd->obd_minor);                         \
+                RETURN(err);                                    \
+        }                                                       \
+} while (0)
+
+static inline int obd_get_info(struct obd_export *exp, __u32 keylen,
                                void *key, __u32 *vallen, void *val)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, get_info);
+        EXP_CHECK_OP(exp, get_info);
         OBD_COUNTER_INCREMENT(exp->exp_obd, get_info);
 
-        rc = OBP(exp->exp_obd, get_info)(conn, keylen, key, vallen, val);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, get_info)(exp, keylen, key, vallen, val);
         RETURN(rc);
 }
 
-static inline int obd_set_info(struct lustre_handle *conn, obd_count keylen,
+static inline int obd_set_info(struct obd_export *exp, obd_count keylen,
                                void *key, obd_count vallen, void *val)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, set_info);
+        EXP_CHECK_OP(exp, set_info);
         OBD_COUNTER_INCREMENT(exp->exp_obd, set_info);
 
-        rc = OBP(exp->exp_obd, set_info)(conn, keylen, key, vallen, val);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, set_info)(exp, keylen, key, vallen, val);
         RETURN(rc);
 }
 
@@ -282,20 +359,45 @@ static inline int obd_setup(struct obd_device *obd, int datalen, void *data)
         int rc;
         ENTRY;
 
-        OBD_CHECK_OP(obd, setup);
+        OBD_CHECK_OP(obd, setup, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(obd, setup);
 
         rc = OBP(obd, setup)(obd, datalen, data);
         RETURN(rc);
 }
 
+static inline int obd_postsetup(struct obd_device *obd)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_DEV_ACTIVE(obd);
+        OBD_CHECK_OP(obd, postsetup, 0);
+        OBD_COUNTER_INCREMENT(obd, postsetup);
+
+        rc = OBP(obd, postsetup)(obd);
+        RETURN(rc);
+}
+
+static inline int obd_precleanup(struct obd_device *obd, int flags)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(obd, precleanup, 0);
+        OBD_COUNTER_INCREMENT(obd, precleanup);
+
+        rc = OBP(obd, precleanup)(obd, flags);
+        RETURN(rc);
+}
+
 static inline int obd_cleanup(struct obd_device *obd, int flags)
 {
         int rc;
         ENTRY;
 
         OBD_CHECK_DEV_STOPPING(obd);
-        OBD_CHECK_OP(obd, cleanup);
+        OBD_CHECK_OP(obd, cleanup, 0);
         OBD_COUNTER_INCREMENT(obd, cleanup);
 
         rc = OBP(obd, cleanup)(obd, flags);
@@ -309,44 +411,41 @@ static inline int obd_cleanup(struct obd_device *obd, int flags)
  * If @*disk_tgt != NULL and @mem_src == NULL, @*disk_tgt will be freed.
  * If @*disk_tgt == NULL, it will be allocated
  */
-static inline int obd_packmd(struct lustre_handle *conn,
+static inline int obd_packmd(struct obd_export *exp,
                              struct lov_mds_md **disk_tgt,
                              struct lov_stripe_md *mem_src)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, packmd);
+        EXP_CHECK_OP(exp, packmd);
         OBD_COUNTER_INCREMENT(exp->exp_obd, packmd);
 
-        rc = OBP(exp->exp_obd, packmd)(conn, disk_tgt, mem_src);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, packmd)(exp, disk_tgt, mem_src);
         RETURN(rc);
 }
 
-static inline int obd_size_diskmd(struct lustre_handle *conn,
+static inline int obd_size_diskmd(struct obd_export *exp,
                                   struct lov_stripe_md *mem_src)
 {
-        return obd_packmd(conn, NULL, mem_src);
+        return obd_packmd(exp, NULL, mem_src);
 }
 
 /* helper functions */
-static inline int obd_alloc_diskmd(struct lustre_handle *conn,
+static inline int obd_alloc_diskmd(struct obd_export *exp,
                                    struct lov_mds_md **disk_tgt)
 {
         LASSERT(disk_tgt);
         LASSERT(*disk_tgt == NULL);
-        return obd_packmd(conn, disk_tgt, NULL);
+        return obd_packmd(exp, disk_tgt, NULL);
 }
 
-static inline int obd_free_diskmd(struct lustre_handle *conn,
+static inline int obd_free_diskmd(struct obd_export *exp,
                                   struct lov_mds_md **disk_tgt)
 {
         LASSERT(disk_tgt);
         LASSERT(*disk_tgt);
-        return obd_packmd(conn, disk_tgt, NULL);
+        return obd_packmd(exp, disk_tgt, NULL);
 }
 
 /* Unpack an MD struct from disk to in-memory format.
@@ -356,163 +455,104 @@ static inline int obd_free_diskmd(struct lustre_handle *conn,
  * If @*mem_tgt != NULL and @disk_src == NULL, @*mem_tgt will be freed.
  * If @*mem_tgt == NULL, it will be allocated
  */
-static inline int obd_unpackmd(struct lustre_handle *conn,
+static inline int obd_unpackmd(struct obd_export *exp,
                                struct lov_stripe_md **mem_tgt,
                                struct lov_mds_md *disk_src,
                                int disk_len)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, unpackmd);
+        EXP_CHECK_OP(exp, unpackmd);
         OBD_COUNTER_INCREMENT(exp->exp_obd, unpackmd);
 
-        rc = OBP(exp->exp_obd, unpackmd)(conn, mem_tgt, disk_src, disk_len);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, unpackmd)(exp, mem_tgt, disk_src, disk_len);
         RETURN(rc);
 }
 
-static inline int obd_size_memmd(struct lustre_handle *conn,
-                                 struct lov_mds_md *disk_src,
-                                 int disk_len)
-{
-        return obd_unpackmd(conn, NULL, disk_src, disk_len);
-}
-
 /* helper functions */
-static inline int obd_alloc_memmd(struct lustre_handle *conn,
+static inline int obd_alloc_memmd(struct obd_export *exp,
                                   struct lov_stripe_md **mem_tgt)
 {
         LASSERT(mem_tgt);
         LASSERT(*mem_tgt == NULL);
-        return obd_unpackmd(conn, mem_tgt, NULL, 0);
+        return obd_unpackmd(exp, mem_tgt, NULL, 0);
 }
 
-static inline int obd_free_memmd(struct lustre_handle *conn,
+static inline int obd_free_memmd(struct obd_export *exp,
                                  struct lov_stripe_md **mem_tgt)
 {
         LASSERT(mem_tgt);
         LASSERT(*mem_tgt);
-        return obd_unpackmd(conn, mem_tgt, NULL, 0);
+        return obd_unpackmd(exp, mem_tgt, NULL, 0);
 }
 
-static inline int obd_create(struct lustre_handle *conn, struct obdo *obdo,
+static inline int obd_create(struct obd_export *exp, struct obdo *obdo,
                              struct lov_stripe_md **ea,
                              struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, create);
+        EXP_CHECK_OP(exp, create);
         OBD_COUNTER_INCREMENT(exp->exp_obd, create);
 
-        rc = OBP(exp->exp_obd, create)(conn, obdo, ea, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, create)(exp, obdo, ea, oti);
         RETURN(rc);
 }
 
-static inline int obd_destroy(struct lustre_handle *conn, struct obdo *obdo,
+static inline int obd_destroy(struct obd_export *exp, struct obdo *obdo,
                               struct lov_stripe_md *ea,
                               struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, destroy);
+        EXP_CHECK_OP(exp, destroy);
         OBD_COUNTER_INCREMENT(exp->exp_obd, destroy);
 
-        rc = OBP(exp->exp_obd, destroy)(conn, obdo, ea, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, destroy)(exp, obdo, ea, oti);
         RETURN(rc);
 }
 
-static inline int obd_getattr(struct lustre_handle *conn, struct obdo *obdo,
+static inline int obd_getattr(struct obd_export *exp, struct obdo *obdo,
                               struct lov_stripe_md *ea)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, getattr);
+        EXP_CHECK_OP(exp, getattr);
         OBD_COUNTER_INCREMENT(exp->exp_obd, getattr);
 
-        rc = OBP(exp->exp_obd, getattr)(conn, obdo, ea);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, getattr)(exp, obdo, ea);
         RETURN(rc);
 }
 
-static inline int obd_getattr_async(struct lustre_handle *conn,
+static inline int obd_getattr_async(struct obd_export *exp,
                                     struct obdo *obdo, struct lov_stripe_md *ea,
                                     struct ptlrpc_request_set *set)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, getattr);
+        EXP_CHECK_OP(exp, getattr);
         OBD_COUNTER_INCREMENT(exp->exp_obd, getattr);
 
-        rc = OBP(exp->exp_obd, getattr_async)(conn, obdo, ea, set);
-        class_export_put(exp);
-        RETURN(rc);
-}
-
-static inline int obd_close(struct lustre_handle *conn, struct obdo *obdo,
-                            struct lov_stripe_md *ea,
-                            struct obd_trans_info *oti)
-{
-        struct obd_export *exp;
-        int rc;
-        ENTRY;
-
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, close);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, close);
-
-        rc = OBP(exp->exp_obd, close)(conn, obdo, ea, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, getattr_async)(exp, obdo, ea, set);
         RETURN(rc);
 }
 
-static inline int obd_open(struct lustre_handle *conn, struct obdo *obdo,
-                           struct lov_stripe_md *ea, struct obd_trans_info *oti,
-                           struct obd_client_handle *och)
-{
-        struct obd_export *exp;
-        int rc;
-        ENTRY;
-
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, open);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, open);
-
-        rc = OBP(exp->exp_obd, open)(conn, obdo, ea, oti, och);
-        class_export_put(exp);
-        RETURN(rc);
-}
-
-static inline int obd_setattr(struct lustre_handle *conn, struct obdo *obdo,
+static inline int obd_setattr(struct obd_export *exp, struct obdo *obdo,
                               struct lov_stripe_md *ea,
                               struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, setattr);
+        EXP_CHECK_OP(exp, setattr);
         OBD_COUNTER_INCREMENT(exp->exp_obd, setattr);
 
-        rc = OBP(exp->exp_obd, setattr)(conn, obdo, ea, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, setattr)(exp, obdo, ea, oti);
         RETURN(rc);
 }
 
@@ -523,34 +563,52 @@ static inline int obd_connect(struct lustre_handle *conn,
         ENTRY;
 
         OBD_CHECK_DEV_ACTIVE(obd);
-        OBD_CHECK_OP(obd, connect);
+        OBD_CHECK_OP(obd, connect, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(obd, connect);
 
         rc = OBP(obd, connect)(conn, obd, cluuid);
         RETURN(rc);
 }
 
-static inline int obd_disconnect(struct lustre_handle *conn, int flags)
+static inline int obd_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, disconnect);
+        EXP_CHECK_OP(exp, disconnect);
         OBD_COUNTER_INCREMENT(exp->exp_obd, disconnect);
 
-        rc = OBP(exp->exp_obd, disconnect)(conn, flags);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, disconnect)(exp, flags);
         RETURN(rc);
 }
 
-static inline void obd_destroy_export(struct obd_export *exp)
+static inline int obd_init_export(struct obd_export *exp)
 {
+        int rc = 0;
+
         ENTRY;
-        if (OBP(exp->exp_obd, destroy_export))
+        if ((exp)->exp_obd != NULL && OBT((exp)->exp_obd) &&
+            OBP((exp)->exp_obd, init_export))
+                rc = OBP(exp->exp_obd, init_export)(exp);
+        RETURN(rc);
+}
+
+static inline int obd_destroy_export(struct obd_export *exp)
+{
+        ENTRY;
+        if ((exp)->exp_obd != NULL && OBT((exp)->exp_obd) &&
+            OBP((exp)->exp_obd, destroy_export))
                 OBP(exp->exp_obd, destroy_export)(exp);
-        EXIT;
+        RETURN(0);
+}
+
+static inline struct dentry *
+obd_lvfs_fid2dentry(struct obd_export *exp, __u64 id_ino, __u32 gen, __u64 gr)
+{
+        LASSERT(exp->exp_obd);
+
+        return lvfs_fid2dentry(&exp->exp_obd->obd_ctxt, id_ino, gen, gr,
+                               exp->exp_obd);
 }
 
 #ifndef time_before
@@ -566,7 +624,7 @@ static inline int obd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         if (obd == NULL)
                 RETURN(-EINVAL);
 
-        OBD_CHECK_OP(obd, statfs);
+        OBD_CHECK_OP(obd, statfs, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(obd, statfs);
 
         CDEBUG(D_SUPER, "osfs %lu, max_age %lu\n", obd->obd_osfs_age, max_age);
@@ -585,45 +643,42 @@ static inline int obd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         RETURN(rc);
 }
 
-static inline int obd_syncfs(struct obd_export *exp)
+static inline int obd_sync(struct obd_export *exp, struct obdo *oa,
+                           struct lov_stripe_md *ea, obd_size start, 
+                           obd_size end)
 {
         int rc;
         ENTRY;
 
-        OBD_CHECK_OP(exp->exp_obd, syncfs);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, syncfs);
+        OBD_CHECK_OP(exp->exp_obd, sync, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, sync);
 
-        rc = OBP(exp->exp_obd, syncfs)(exp);
+        rc = OBP(exp->exp_obd, sync)(exp, oa, ea, start, end);
         RETURN(rc);
 }
 
-static inline int obd_punch(struct lustre_handle *conn, struct obdo *oa,
+static inline int obd_punch(struct obd_export *exp, struct obdo *oa,
                             struct lov_stripe_md *ea, obd_size start,
                             obd_size end, struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, punch);
+        EXP_CHECK_OP(exp, punch);
         OBD_COUNTER_INCREMENT(exp->exp_obd, punch);
 
-        rc = OBP(exp->exp_obd, punch)(conn, oa, ea, start, end, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, punch)(exp, oa, ea, start, end, oti);
         RETURN(rc);
 }
 
-static inline int obd_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static inline int obd_brw(int cmd, struct obd_export *exp, struct obdo *oa,
                           struct lov_stripe_md *ea, obd_count oa_bufs,
                           struct brw_page *pg, struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, brw);
+        EXP_CHECK_OP(exp, brw);
         OBD_COUNTER_INCREMENT(exp->exp_obd, brw);
 
         if (!(cmd & (OBD_BRW_RWMASK | OBD_BRW_CHECK))) {
@@ -632,23 +687,20 @@ static inline int obd_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 LBUG();
         }
 
-        rc = OBP(exp->exp_obd, brw)(cmd, conn, oa, ea, oa_bufs, pg, oti);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, brw)(cmd, exp, oa, ea, oa_bufs, pg, oti);
         RETURN(rc);
 }
 
-static inline int obd_brw_async(int cmd, struct lustre_handle *conn,
+static inline int obd_brw_async(int cmd, struct obd_export *exp,
                                 struct obdo *oa, struct lov_stripe_md *ea,
                                 obd_count oa_bufs, struct brw_page *pg,
                                 struct ptlrpc_request_set *set,
                                 struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, brw_async);
+        EXP_CHECK_OP(exp, brw_async);
         OBD_COUNTER_INCREMENT(exp->exp_obd, brw_async);
 
         if (!(cmd & OBD_BRW_RWMASK)) {
@@ -656,9 +708,108 @@ static inline int obd_brw_async(int cmd, struct lustre_handle *conn,
                 LBUG();
         }
 
-        rc = OBP(exp->exp_obd, brw_async)(cmd, conn, oa, ea, oa_bufs, pg, set,
+        rc = OBP(exp->exp_obd, brw_async)(cmd, exp, oa, ea, oa_bufs, pg, set,
                                           oti);
-        class_export_put(exp);
+        RETURN(rc);
+}
+
+static inline  int obd_prep_async_page(struct obd_export *exp, 
+                                       struct lov_stripe_md *lsm,
+                                       struct lov_oinfo *loi, 
+                                       struct page *page, obd_off offset, 
+                                       struct obd_async_page_ops *ops, 
+                                       void *data, void **res)
+{
+        int ret;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, prep_async_page, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, prep_async_page);
+
+        ret = OBP(exp->exp_obd, prep_async_page)(exp, lsm, loi, page, offset,
+                                                 ops, data, res);
+        RETURN(ret);
+}
+
+static inline int obd_queue_async_io(struct obd_export *exp, 
+                                     struct lov_stripe_md *lsm, 
+                                     struct lov_oinfo *loi, void *cookie, 
+                                     int cmd, obd_off off, int count, 
+                                     obd_flag brw_flags, obd_flag async_flags)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, queue_async_io, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, queue_async_io);
+        LASSERT(cmd & OBD_BRW_RWMASK);
+
+        rc = OBP(exp->exp_obd, queue_async_io)(exp, lsm, loi, cookie, cmd, off,
+                                               count, brw_flags, async_flags);
+        RETURN(rc);
+}
+
+static inline int obd_set_async_flags(struct obd_export *exp,
+                                      struct lov_stripe_md *lsm,
+                                      struct lov_oinfo *loi, void *cookie,
+                                      obd_flag async_flags)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, set_async_flags, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, set_async_flags);
+
+        rc = OBP(exp->exp_obd, set_async_flags)(exp, lsm, loi, cookie, 
+                                                async_flags);
+        RETURN(rc);
+}
+
+static inline int obd_queue_sync_io(struct obd_export *exp, 
+                                    struct lov_stripe_md *lsm, 
+                                    struct lov_oinfo *loi, 
+                                    struct obd_sync_io_container *osic, 
+                                    void *cookie, int cmd, obd_off off, 
+                                    int count, obd_flag brw_flags)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, queue_sync_io, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, queue_sync_io);
+        LASSERT(cmd & OBD_BRW_RWMASK);
+
+        rc = OBP(exp->exp_obd, queue_sync_io)(exp, lsm, loi, osic, cookie, 
+                                              cmd, off, count, brw_flags);
+        RETURN(rc);
+}
+
+static inline int obd_trigger_sync_io(struct obd_export *exp, 
+                                      struct lov_stripe_md *lsm, 
+                                      struct lov_oinfo *loi,
+                                      struct obd_sync_io_container *osic)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, trigger_sync_io, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, trigger_sync_io);
+
+        rc = OBP(exp->exp_obd, trigger_sync_io)(exp, lsm, loi, osic);
+        RETURN(rc);
+}
+
+static inline int obd_teardown_async_page(struct obd_export *exp,
+                                          struct lov_stripe_md *lsm,
+                                          struct lov_oinfo *loi, void *cookie)
+{
+        int rc;
+        ENTRY;
+
+        OBD_CHECK_OP(exp->exp_obd, teardown_async_page, -EOPNOTSUPP);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, teardown_async_page);
+
+        rc = OBP(exp->exp_obd, teardown_async_page)(exp, lsm, loi, cookie);
         RETURN(rc);
 }
 
@@ -671,7 +822,7 @@ static inline int obd_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
         int rc;
         ENTRY;
 
-        OBD_CHECK_OP(exp->exp_obd, preprw);
+        OBD_CHECK_OP(exp->exp_obd, preprw, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(exp->exp_obd, preprw);
 
         rc = OBP(exp->exp_obd, preprw)(cmd, exp, oa, objcount, obj, niocount,
@@ -687,7 +838,7 @@ static inline int obd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
         int rc;
         ENTRY;
 
-        OBD_CHECK_OP(exp->exp_obd, commitrw);
+        OBD_CHECK_OP(exp->exp_obd, commitrw, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(exp->exp_obd, commitrw);
 
         rc = OBP(exp->exp_obd, commitrw)(cmd, exp, oa, objcount, obj, niocount,
@@ -695,135 +846,97 @@ static inline int obd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
         RETURN(rc);
 }
 
-static inline int obd_iocontrol(unsigned int cmd, struct lustre_handle *conn,
+static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp,
                                 int len, void *karg, void *uarg)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, iocontrol);
+        EXP_CHECK_OP(exp, iocontrol);
         OBD_COUNTER_INCREMENT(exp->exp_obd, iocontrol);
 
-        rc = OBP(exp->exp_obd, iocontrol)(cmd, conn, len, karg, uarg);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg);
         RETURN(rc);
 }
 
-static inline int obd_enqueue(struct lustre_handle *conn,
+static inline int obd_enqueue(struct obd_export *exp,
                               struct lov_stripe_md *ea,
                               struct lustre_handle *parent_lock,
                               __u32 type, void *cookie, int cookielen,
                               __u32 mode, int *flags, void *cb, void *data,
                               struct lustre_handle *lockh)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, enqueue);
+        EXP_CHECK_OP(exp, enqueue);
         OBD_COUNTER_INCREMENT(exp->exp_obd, enqueue);
 
-        rc = OBP(exp->exp_obd, enqueue)(conn, ea, parent_lock, type,
+        rc = OBP(exp->exp_obd, enqueue)(exp, ea, parent_lock, type,
                                         cookie, cookielen, mode, flags, cb,
                                         data, lockh);
-        class_export_put(exp);
         RETURN(rc);
 }
 
-static inline int obd_match(struct lustre_handle *conn,
+static inline int obd_match(struct obd_export *exp,
                             struct lov_stripe_md *ea, __u32 type, void *cookie,
                             int cookielen, __u32 mode, int *flags, void *data,
                             struct lustre_handle *lockh)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, match);
+        EXP_CHECK_OP(exp, match);
         OBD_COUNTER_INCREMENT(exp->exp_obd, match);
 
-        rc = OBP(exp->exp_obd, match)(conn, ea, type, cookie, cookielen, mode,
+        rc = OBP(exp->exp_obd, match)(exp, ea, type, cookie, cookielen, mode,
                                       flags, data, lockh);
-        class_export_put(exp);
         RETURN(rc);
 }
 
 
-static inline int obd_cancel(struct lustre_handle *conn,
-                             struct lov_stripe_md *ea, __u32 mode,
-                             struct lustre_handle *lockh)
+static inline int obd_change_cbdata(struct obd_export *exp,
+                                    struct lov_stripe_md *lsm, 
+                                    ldlm_iterator_t it, void *data)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, cancel);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, cancel);
+        EXP_CHECK_OP(exp, change_cbdata);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, change_cbdata);
 
-        rc = OBP(exp->exp_obd, cancel)(conn, ea, mode, lockh);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, change_cbdata)(exp, lsm, it, data);
         RETURN(rc);
 }
 
-static inline int obd_cancel_unused(struct lustre_handle *conn,
-                                    struct lov_stripe_md *ea, int flags,
-                                    void *opaque)
+static inline int obd_cancel(struct obd_export *exp,
+                             struct lov_stripe_md *ea, __u32 mode,
+                             struct lustre_handle *lockh)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, cancel_unused);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, cancel_unused);
+        EXP_CHECK_OP(exp, cancel);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, cancel);
 
-        rc = OBP(exp->exp_obd, cancel_unused)(conn, ea, flags, opaque);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, cancel)(exp, ea, mode, lockh);
         RETURN(rc);
 }
 
-static inline int obd_log_add(struct lustre_handle *conn,
-                              struct llog_handle *cathandle,
-                              struct llog_trans_hdr *rec,
-                              struct lov_stripe_md *lsm,
-                              struct llog_cookie *logcookies,
-                              int numcookies)
+static inline int obd_cancel_unused(struct obd_export *exp,
+                                    struct lov_stripe_md *ea, int flags,
+                                    void *opaque)
 {
-        struct obd_export *exp;
         int rc;
         ENTRY;
 
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, log_add);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, log_add);
+        EXP_CHECK_OP(exp, cancel_unused);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, cancel_unused);
 
-        rc = OBP(exp->exp_obd, log_add)(conn, cathandle, rec, lsm, logcookies,
-                                        numcookies);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, cancel_unused)(exp, ea, flags, opaque);
         RETURN(rc);
 }
 
-static inline int obd_log_cancel(struct lustre_handle *conn,
-                                 struct lov_stripe_md *lsm, int count,
-                                 struct llog_cookie *cookies, int flags)
-{
-        struct obd_export *exp;
-        int rc;
-        ENTRY;
-
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, log_cancel);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, log_cancel);
-
-        rc = OBP(exp->exp_obd, log_cancel)(conn, lsm, count, cookies, flags);
-        class_export_put(exp);
-        RETURN(rc);
-}
 
 static inline int obd_san_preprw(int cmd, struct obd_export *exp,
                                  struct obdo *oa,
@@ -832,7 +945,7 @@ static inline int obd_san_preprw(int cmd, struct obd_export *exp,
 {
         int rc;
 
-        OBD_CHECK_OP(exp->exp_obd, preprw);
+        EXP_CHECK_OP(exp, preprw);
         OBD_COUNTER_INCREMENT(exp->exp_obd, preprw);
 
         rc = OBP(exp->exp_obd, san_preprw)(cmd, exp, oa, objcount, obj,
@@ -841,85 +954,79 @@ static inline int obd_san_preprw(int cmd, struct obd_export *exp,
         return(rc);
 }
 
-static inline int obd_pin(struct lustre_handle *conn, obd_id ino, __u32 gen,
+static inline int obd_pin(struct obd_export *exp, obd_id ino, __u32 gen,
                           int type, struct obd_client_handle *handle, int flag)
 {
-        struct obd_export *exp;
         int rc;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, pin);
+        EXP_CHECK_OP(exp, pin);
         OBD_COUNTER_INCREMENT(exp->exp_obd, pin);
 
-        rc = OBP(exp->exp_obd, pin)(conn, ino, gen, type, handle, flag);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, pin)(exp, ino, gen, type, handle, flag);
         return(rc);
 }
 
-static inline int obd_unpin(struct lustre_handle *conn,
+static inline int obd_unpin(struct obd_export *exp,
                             struct obd_client_handle *handle, int flag)
 {
-        struct obd_export *exp;
         int rc;
 
-        OBD_CHECK_ACTIVE(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, unpin);
+        EXP_CHECK_OP(exp, unpin);
         OBD_COUNTER_INCREMENT(exp->exp_obd, unpin);
 
-        rc = OBP(exp->exp_obd, unpin)(conn, handle, flag);
-        class_export_put(exp);
+        rc = OBP(exp->exp_obd, unpin)(exp, handle, flag);
         return(rc);
 }
 
-static inline int obd_mark_page_dirty(struct lustre_handle *conn,
-                                      struct lov_stripe_md *lsm,
-                                      unsigned long offset)
+static inline int obd_lock_contains(struct obd_export *exp,
+                                    struct lov_stripe_md *lsm, 
+                                    struct ldlm_lock *lock, obd_off offset)
 {
-        struct obd_export *exp;
         int rc;
+        ENTRY;
 
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, mark_page_dirty);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, mark_page_dirty);
+        EXP_CHECK_OP(exp, lock_contains);
+        OBD_COUNTER_INCREMENT(exp->exp_obd, lock_contains);
 
-        rc = OBP(exp->exp_obd, mark_page_dirty)(conn, lsm, offset);
-        class_export_put(exp);
-        return(rc);
+        rc = OBP(exp->exp_obd, lock_contains)(exp, lsm, lock, offset);
+        RETURN(rc);
 }
 
-static inline int obd_clear_dirty_pages(struct lustre_handle *conn,
-                                        struct lov_stripe_md *lsm,
-                                        unsigned long start,
-                                        unsigned long end,
-                                        unsigned long *cleared)
+static inline void obd_invalidate_import(struct obd_device *obd,
+                                         struct obd_import *imp)
 {
-        struct obd_export *exp;
-        int rc;
-
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, clear_dirty_pages);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, clear_dirty_pages);
-
-        rc = OBP(exp->exp_obd, clear_dirty_pages)(conn, lsm, start, end,
-                                                  cleared);
-        class_export_put(exp);
-        return(rc);
+        if (obd->obd_set_up && OBP(obd, invalidate_import)) {
+                OBD_COUNTER_INCREMENT(obd, invalidate_import);
+                OBP(obd, invalidate_import)(obd, imp);
+        }
 }
 
-static inline int obd_last_dirty_offset(struct lustre_handle *conn,
-                                      struct lov_stripe_md *lsm,
-                                      unsigned long *offset)
+static inline int obd_notify(struct obd_device *obd,
+                             struct obd_device *watched,
+                             int active)
 {
-        struct obd_export *exp;
-        int rc;
+        if (!obd->obd_set_up) {
+                CERROR("obd %s not set up\n", obd->obd_name);
+                return -EINVAL;
+        }
 
-        OBD_CHECK_SETUP(conn, exp);
-        OBD_CHECK_OP(exp->exp_obd, last_dirty_offset);
-        OBD_COUNTER_INCREMENT(exp->exp_obd, last_dirty_offset);
+        if (!OBP(obd, notify)) {
+                CERROR("obd %s has no notify handler\n", obd->obd_name);
+                return -ENOSYS;
+        }
 
-        rc = OBP(exp->exp_obd, last_dirty_offset)(conn, lsm, offset);
-        class_export_put(exp);
-        return(rc);
+        OBD_COUNTER_INCREMENT(obd, notify);
+        return OBP(obd, notify)(obd, watched, active);
+}
+
+static inline int obd_register_observer(struct obd_device *obd,
+                                        struct obd_device *observer)
+{
+        ENTRY;
+        if (obd->obd_observer && observer)
+                RETURN(-EALREADY);
+        obd->obd_observer = observer;
+        RETURN(0);
 }
 
 /* OBD Metadata Support */
@@ -927,6 +1034,10 @@ static inline int obd_last_dirty_offset(struct lustre_handle *conn,
 extern int obd_init_caches(void);
 extern void obd_cleanup_caches(void);
 
+/* async page pushing io helpers */
+struct obd_client_page *ocp_alloc(struct page *page);
+void ocp_free(struct page *page);
+
 /* support routines */
 extern kmem_cache_t *obdo_cachep;
 static inline struct obdo *obdo_alloc(void)
@@ -969,7 +1080,7 @@ struct obd_class_user_state {
 
 struct obd_class_user_conn {
         struct list_head       ocuc_chain;
-        struct lustre_handle   ocuc_conn;
+        struct obd_export     *ocuc_exp;
 };
 
 
@@ -988,5 +1099,4 @@ int class_add_uuid(char *uuid, __u64 nid, __u32 nal);
 int class_del_uuid (char *uuid);
 void class_init_uuidlist(void);
 void class_exit_uuidlist(void);
-
 #endif /* __LINUX_OBD_CLASS_H */
diff --git a/lustre/include/linux/obd_echo.h b/lustre/include/linux/obd_echo.h
index c344d8a752f61045a86c494caedee48ac4bfc8f3..68c0d6e6c3275a78130bd4f8b9a2b1b29b8eb487 100644
--- a/lustre/include/linux/obd_echo.h
+++ b/lustre/include/linux/obd_echo.h
@@ -22,14 +22,6 @@ struct ec_object {
         struct lov_stripe_md  *eco_lsm;
 };
 
-struct ec_open_object {
-        struct list_head         ecoo_exp_chain;
-        struct ec_object        *ecoo_object;
-        __u64                    ecoo_cookie;
-        struct obdo              ecoo_oa;
-        struct obd_client_handle ecoo_och;
-};
-
 struct ec_lock {
         struct list_head       ecl_exp_chain;
         struct ec_object      *ecl_object;
diff --git a/lustre/include/linux/obd_ext2.h b/lustre/include/linux/obd_ext2.h
deleted file mode 100644
index 73b4b0b129b99d79a39fe47dfe309ac4f028b68f..0000000000000000000000000000000000000000
--- a/lustre/include/linux/obd_ext2.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _OBD_EXT2
-#define _OBD_EXT2
-/*
- * Copyright (C) 2001  Cluster File Systems, Inc.
- *
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
- */
-
-#define OBD_EXT2_RUNIT           _IOWR('f', 61, long)
-
-#ifndef OBD_EXT2_DEVICENAME
-#define OBD_EXT2_DEVICENAME "obdext2"
-#endif
-
-/* development definitions */
-extern struct obdfs_sb_info *obd_sbi;
-extern struct file_operations *obd_fso;
-
-/* ext2_obd.c */
-extern struct obd_ops ext2_obd_ops;
-
-#include <linux/fs.h>
-#include <linux/ext2_fs.h>
-
-/* super.c */
-#ifdef EXT2_OBD_DEBUG
-#  undef ext2_debug
-#  define ext2_debug(format, a...) CDEBUG(D_EXT2, format, ## a)
-#  define ext2_error ext2_warning
-#  define ext2_panic ext2_warning
-#  define ext2_warning(sb, func, format, a...) CDEBUG(D_WARNING, format, ## a)
-#else
-#  undef ext2_debug
-#  define ext2_debug(format, a...) {}
-#  define ext2_error(sb, func, format, a...) printk(KERN_ERR "%s: " format, func, ## a)
-#  define ext2_panic(sb, func, format, a...) printk(KERN_CRIT "%s: " format, func, ## a)
-#  define ext2_warning(sb, func, format, a...) printk(KERN_WARNING "%s: " format, func, ## a)
-#endif
-
-extern struct super_operations ext2_sops;
-int obd_remount (struct super_block * sb, int * flags, char * data);
-struct super_block * ext2_read_super (struct super_block * sb, void * data,
-                                      int silent);
-/* punch.c */
-void ext2_truncate (struct inode * inode);
-int ext2_punch (struct inode * inode, loff_t start, size_t count);
-
-#endif
diff --git a/lustre/include/linux/obd_lov.h b/lustre/include/linux/obd_lov.h
index 6d68ae9121f266d774a62ac45bf89b12765121cf..cf3ccec2d01e63b9c008a49851e0ffe58f324b40 100644
--- a/lustre/include/linux/obd_lov.h
+++ b/lustre/include/linux/obd_lov.h
@@ -19,6 +19,7 @@ struct lov_getattr_async_args {
         struct lov_stripe_md  *aa_lsm;
         struct obdo           *aa_oa;
         struct obdo           *aa_obdos;
+        struct lov_obd        *aa_lov;
 };
 
 static inline int lov_stripe_md_size(int stripes)
@@ -26,9 +27,17 @@ static inline int lov_stripe_md_size(int stripes)
         return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo);
 }
 
-static inline int lov_mds_md_size(int stripes)
+static inline int lov_mds_md_v0_size(int stripes)
 {
-        return sizeof(struct lov_mds_md) + stripes*sizeof(struct lov_object_id);
+        return sizeof(struct lov_mds_md_v0) +
+                stripes * sizeof(struct lov_ost_data_v0);
+}
+
+#define lov_mds_md_size(stripes) lov_mds_md_v1_size(stripes)
+static inline int lov_mds_md_v1_size(int stripes)
+{
+        return sizeof(struct lov_mds_md_v1) +
+                stripes * sizeof(struct lov_ost_data_v1);
 }
 
 #define IOC_LOV_TYPE                   'g'
diff --git a/lustre/include/linux/obd_ost.h b/lustre/include/linux/obd_ost.h
index ac2e24b68c0131aa72449d07f381deac6750232f..215e8b1d9dea41e1e0cc0fedfc6cbde1114bc751 100644
--- a/lustre/include/linux/obd_ost.h
+++ b/lustre/include/linux/obd_ost.h
@@ -40,6 +40,8 @@ struct osc_brw_async_args {
         int              aa_nio_count;
         obd_count        aa_page_count;
         struct brw_page *aa_pga;
+        struct client_obd *aa_cli;
+        struct list_head aa_oaps;
 };
 
 struct osc_getattr_async_args {
diff --git a/lustre/include/linux/obd_ptlbd.h b/lustre/include/linux/obd_ptlbd.h
index 1e6de5aaaf53e92fb7b40fe5c164d3a88fbdd6e6..c213dac07a5650c0c35aec361dd5c97223808dce 100644
--- a/lustre/include/linux/obd_ptlbd.h
+++ b/lustre/include/linux/obd_ptlbd.h
@@ -1,7 +1,7 @@
 #ifndef _OBD_PTLBD_H
 #define _OBD_PTLBD_H
 
-#include <linux/lustre_idl.h>
+#include <linux/obd.h>
 /*
  * Copyright (C) 2002  Cluster File Systems, Inc.
  *
@@ -25,8 +25,8 @@ extern void ptlbd_sv_exit(void);
 extern int ptlbd_do_connect(struct ptlbd_obd *);
 extern int ptlbd_do_disconnect(struct ptlbd_obd *);
 extern void ptlbd_blk_register(struct ptlbd_obd *ptlbd);
-extern int ptlbd_send_rw_req(struct ptlbd_obd *, ptlbd_cmd_t cmd, 
-		struct buffer_head *);
+extern int ptlbd_send_rw_req(struct ptlbd_obd *, ptlbd_cmd_t cmd,
+			     struct buffer_head *);
 extern int ptlbd_send_flush_req(struct ptlbd_obd *, ptlbd_cmd_t cmd);
 extern int ptlbd_handle(struct ptlrpc_request *req);
 
diff --git a/lustre/include/linux/obd_snap.h b/lustre/include/linux/obd_snap.h
deleted file mode 100644
index b7641d405fbc07574d8012a272be30e156b17808..0000000000000000000000000000000000000000
--- a/lustre/include/linux/obd_snap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _OBD_SNAP
-#define _OBD_SNAP
-/*
- * Copyright (C) 2001  Cluster File Systems, Inc.
- *
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
- */
-
-#include <linux/obd_class.h>
-
-#define OBD_SNAP_MAGIC 0xfffffff3   /* an unlikely block number */
-
-#ifndef OBD_SNAP_DEVICENAME
-#define OBD_SNAP_DEVICENAME "obdsnap"
-#endif
-
-/* ioctls for manipulating snapshots 40 - 60 */
-#define OBD_SNAP_SETTABLE	_IOWR('f', 40, long)
-#define OBD_SNAP_PRINTTABLE	_IOWR('f', 41, long)
-#define OBD_SNAP_DELETE	_IOWR('f', 42, long)
-#define OBD_SNAP_RESTORE	_IOWR('f', 43, long)
-
-void snap_use(int table_no, int snap_index) ;
-void snap_unuse(int table_no, int snap_index) ;
-int snap_is_used(int table_no, int snap_index) ;
-int snap_table_attach(int tableno, int snap_index);
-
-#endif
diff --git a/lustre/include/linux/obd_snap_support.h b/lustre/include/linux/obd_snap_support.h
deleted file mode 100644
index fd8baa4b4cd3ef7eff74e7c70335a73a83b7587c..0000000000000000000000000000000000000000
--- a/lustre/include/linux/obd_snap_support.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __OBD_SNAP_SUPP_H
-#define __OBD_SNAP_SUPP_H
-/*
- * Copyright (C) 2001  Cluster File Systems, Inc.
- *
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
- */
-
-/* What we use to point to IDs in the obdmd data for snapshots.  If we use
- * obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of
- * available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we
- * increase the size of OBD_OBDMDSZ).
- */
-typedef obd_id	snap_id;
-
-/* maximum number of snapshot tables we maintain in the kernel */
-#define SNAP_MAX_TABLES 8
-
-/* maximum number of snapshots per device 
-   must fit in "o_obdmd" area of struct obdo */
-#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id))
-
-struct snap_md {
-	uint32_t m_magic;
-	snap_id	 m_ids[SNAP_MAX];	/* id of snaps; slot 0 has current id */
-};
-
-
-/* if time is 0 this designates the "current" snapshot, i.e.
-   the head of the tree 
-*/
-struct snap {
-	time_t time;
-	int index;
-};
-
-/* snap ioctl data for attach: current always in first slot of this array */
-struct snap_obd_data {
-	int 	     snap_dev;	/* which device contains the data */
-	unsigned int snap_index;/* which snapshot is ours */
-	unsigned int snap_table;/* which table do we use */
-};
-
-
-/* snap ioctl data for table fiddling */
-struct snap_table_data {
-	int 		tblcmd_no;	/* which table */
-	unsigned int 	tblcmd_count;	/* how many snaps */
-	struct snap 	tblcmd_snaps[SNAP_MAX];	/* sorted times! */
-};
-
-
-struct snap_table {
-	spinlock_t          tbl_lock;
-	unsigned int tbl_count; /* how many snapshots exist in this table*/
-	int tbl_used;  /* bitmap of snaps in use by a device */
-	time_t tbl_times[SNAP_MAX];
-	int tbl_index[SNAP_MAX];
-};
-
-struct snap_iterdata {
-	struct lustre_handle *conn;
-	struct lustre_handle *ch_conn;
-	int index;
-	int previndex;
-	int currentindex;
-	int prevslot;
-	time_t prevtime;
-};
-
-inline struct lustre_handle *child_conn(struct lustre_handle *conn);
-int snap_deleteobj(obd_id id, obd_gr group, void *data);
-int snap_restoreobj(obd_id id, obd_gr group, void *data);
-int snap_printobj(obd_id id, obd_gr group, void *data);
-int snap_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, void *karg, void *uarg);
-
-/* In the future, this function may have to deal with offsets into the obdmd.
- * Currently, we assume we have the whole obdmd struct.
- */
-static __inline__ struct snap_md *snap_obdmd(struct obdo *oa)
-{
-	return ((struct snap_md *)(&oa->o_obdmd));
-}
-#endif
diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h
index d738e55025e472f02dea3a1ba5b0bd8c06451f5f..003daad5618735ae2b7106de9c632d4d25c79c15 100644
--- a/lustre/include/linux/obd_support.h
+++ b/lustre/include/linux/obd_support.h
@@ -32,13 +32,13 @@
 
 #endif
 #include <linux/kp30.h>
+#include <linux/lustre_compat25.h>
 
 /* global variables */
 extern atomic_t obd_memory;
 extern int obd_memmax;
 extern unsigned int obd_fail_loc;
 extern unsigned int obd_timeout;
-extern unsigned long obd_max_dirty_pages;
 extern char obd_lustre_upcall[128];
 extern unsigned int obd_sync_filter;
 
@@ -78,6 +78,10 @@ extern unsigned int obd_sync_filter;
 #define OBD_FAIL_MDS_UNPIN_NET           0x121
 #define OBD_FAIL_MDS_ALL_REPLY_NET       0x122
 #define OBD_FAIL_MDS_ALL_REQUEST_NET     0x123
+#define OBD_FAIL_MDS_SYNC_NET            0x124
+#define OBD_FAIL_MDS_SYNC_PACK           0x125
+#define OBD_FAIL_MDS_DONE_WRITING_NET    0x126
+#define OBD_FAIL_MDS_DONE_WRITING_PACK   0x127
 
 #define OBD_FAIL_OST                     0x200
 #define OBD_FAIL_OST_CONNECT_NET         0x201
@@ -95,7 +99,7 @@ extern unsigned int obd_sync_filter;
 #define OBD_FAIL_OST_HANDLE_UNPACK       0x20d
 #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
-#define OBD_FAIL_OST_SYNCFS_NET          0x210
+#define OBD_FAIL_OST_SYNC_NET            0x210
 #define OBD_FAIL_OST_ALL_REPLY_NET       0x211
 #define OBD_FAIL_OST_ALL_REQUESTS_NET    0x212
 #define OBD_FAIL_OST_LDLM_REPLY_NET      0x213
@@ -120,6 +124,7 @@ extern unsigned int obd_sync_filter;
 
 #define OBD_FAIL_OBD_PING_NET            0x600
 #define OBD_FAIL_OBD_LOG_CANCEL_NET      0x601
+#define OBD_FAIL_OBD_LOGD_NET            0x602
 
 /* preparation for a more advanced failure testbed (not functional yet) */
 #define OBD_FAIL_MASK_SYS    0x0000FF00
@@ -174,40 +179,46 @@ do {                                                                         \
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 #define BDEVNAME_DECLARE_STORAGE(foo) char foo[BDEVNAME_SIZE]
-#define ll_bdevname(DEV, STORAGE) __bdevname(DEV, STORAGE)
+#define ll_bdevname(SB, STORAGE) __bdevname(kdev_t_to_nr(SB->s_dev), STORAGE)
 #define ll_lock_kernel lock_kernel()
+#define ll_sbdev(SB)    ((SB)->s_bdev)
+void dev_set_rdonly(struct block_device *, int);
 #else
 #define BDEVNAME_DECLARE_STORAGE(foo) char __unused_##foo
-#define ll_bdevname(DEV, STORAGE) ((void)__unused_##STORAGE, bdevname((DEV)))
+#define ll_sbdev(SB)    (kdev_t_to_nr((SB)->s_dev))
+#define ll_bdevname(SB,STORAGE) ((void)__unused_##STORAGE,bdevname(ll_sbdev(SB)))
 #define ll_lock_kernel
+void dev_set_rdonly(kdev_t, int);
 #endif
 
-void dev_set_rdonly(kdev_t dev, int no_write);
 void dev_clear_rdonly(int);
 
-static inline void OBD_FAIL_WRITE(int id, kdev_t dev)
+static inline void OBD_FAIL_WRITE(int id, struct super_block *sb)
 {
         if (OBD_FAIL_CHECK(id)) {
                 BDEVNAME_DECLARE_STORAGE(tmp);
-#ifdef CONFIG_DEV_RDONLY
                 CERROR("obd_fail_loc=%x, fail write operation on %s\n",
-                       id, ll_bdevname(kdev_t_to_nr(dev), tmp));
-                dev_set_rdonly(dev, 2);
-#else
-                CERROR("obd_fail_loc=%x, can't fail write operation on %s\n",
-                       id, ll_bdevname(kdev_t_to_nr(dev), tmp));
-#endif
+                       id, ll_bdevname(sb, tmp));
+                dev_set_rdonly(ll_sbdev(sb), 2);
                 /* We set FAIL_ONCE because we never "un-fail" a device */
                 obd_fail_loc |= OBD_FAILED | OBD_FAIL_ONCE;
         }
 }
 #else /* !__KERNEL__ */
 #define LTIME_S(time) (time)
+/* for obd_class.h */
+#ifndef ERR_PTR
+# define ERR_PTR(a) ((void *)(a))
+#endif
 #endif  /* __KERNEL__ */
 
+#ifndef GFP_MEMALLOC
+#define GFP_MEMALLOC 0
+#endif
+
 #define OBD_ALLOC_GFP(ptr, size, gfp_mask)                                    \
 do {                                                                          \
-        (ptr) = kmalloc(size, gfp_mask);                                      \
+        (ptr) = kmalloc(size, (gfp_mask));                                    \
         if ((ptr) == NULL) {                                                  \
                 CERROR("kmalloc of '" #ptr "' (%d bytes) failed at %s:%d\n",  \
                        (int)(size), __FILE__, __LINE__);                      \
@@ -222,10 +233,11 @@ do {                                                                          \
 } while (0)
 
 #ifndef OBD_GFP_MASK
-# define OBD_GFP_MASK GFP_KERNEL
+# define OBD_GFP_MASK (GFP_KERNEL | GFP_MEMALLOC)
 #endif
 
 #define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, OBD_GFP_MASK)
+#define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_KERNEL)
 
 #ifdef __arch_um__
 # define OBD_VMALLOC(ptr, size) OBD_ALLOC(ptr, size)
@@ -253,6 +265,13 @@ do {                                                                          \
 #define POISON(ptr, c, s) memset(ptr, c, s)
 #endif
 
+#if POISON_BULK
+#define POISON_PAGE(page, val) do { memset(kmap(page), val, PAGE_SIZE);       \
+                                    kunmap(page); } while (0)
+#else
+#define POISON_PAGE(page, val) do { } while (0)
+#endif
+
 #define OBD_FREE(ptr, size)                                                   \
 do {                                                                          \
         LASSERT(ptr);                                                         \
@@ -279,13 +298,17 @@ do {                                                                          \
 } while (0)
 #endif
 
+#ifndef SLAB_MEMALLOC
+#define SLAB_MEMALLOC 0
+#endif
+
 /* we memset() the slab object to 0 when allocation succeeds, so DO NOT
  * HAVE A CTOR THAT DOES ANYTHING.  its work will be cleared here.  we'd
  * love to assert on that, but slab.c keeps kmem_cache_s all to itself. */
 #define OBD_SLAB_ALLOC(ptr, slab, type, size)                                 \
 do {                                                                          \
         LASSERT(!in_interrupt());                                             \
-        (ptr) = kmem_cache_alloc(slab, type);                                 \
+        (ptr) = kmem_cache_alloc(slab, (type | SLAB_MEMALLOC));               \
         if ((ptr) == NULL) {                                                  \
                 CERROR("slab-alloc of '"#ptr"' (%d bytes) failed at %s:%d\n", \
                        (int)(size), __FILE__, __LINE__);                      \
diff --git a/lustre/include/linux/rbtree.h b/lustre/include/linux/rbtree.h
new file mode 100644
index 0000000000000000000000000000000000000000..e35ddc7b8713d29daaf394bf5ba7db7b317cc7bc
--- /dev/null
+++ b/lustre/include/linux/rbtree.h
@@ -0,0 +1,132 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  
+  This program 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.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/include/linux/rbtree.h
+
+  To use rbtrees you'll have to implement your own insert and search cores.
+  This will avoid us to use callbacks and to drop drammatically performances.
+  I know it's not the cleaner way,  but in C (not in C++) to get
+  performances and genericity...
+
+  Some example of insert and search follows here. The search is a plain
+  normal search over an ordered tree. The insert instead must be implemented
+  int two steps: as first thing the code must insert the element in
+  order as a red leaf in the tree, then the support library function
+  rb_insert_color() must be called. Such function will do the
+  not trivial work to rebalance the rbtree if necessary.
+
+-----------------------------------------------------------------------
+static inline struct page * rb_search_page_cache(struct inode * inode,
+						 unsigned long offset)
+{
+	rb_node_t * n = inode->i_rb_page_cache.rb_node;
+	struct page * page;
+
+	while (n)
+	{
+		page = rb_entry(n, struct page, rb_page_cache);
+
+		if (offset < page->offset)
+			n = n->rb_left;
+		else if (offset > page->offset)
+			n = n->rb_right;
+		else
+			return page;
+	}
+	return NULL;
+}
+
+static inline struct page * __rb_insert_page_cache(struct inode * inode,
+						   unsigned long offset,
+						   rb_node_t * node)
+{
+	rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
+	rb_node_t * parent = NULL;
+	struct page * page;
+
+	while (*p)
+	{
+		parent = *p;
+		page = rb_entry(parent, struct page, rb_page_cache);
+
+		if (offset < page->offset)
+			p = &(*p)->rb_left;
+		else if (offset > page->offset)
+			p = &(*p)->rb_right;
+		else
+			return page;
+	}
+
+	rb_link_node(node, parent, p);
+
+	return NULL;
+}
+
+static inline struct page * rb_insert_page_cache(struct inode * inode,
+						 unsigned long offset,
+						 rb_node_t * node)
+{
+	struct page * ret;
+	if ((ret = __rb_insert_page_cache(inode, offset, node)))
+		goto out;
+	rb_insert_color(node, &inode->i_rb_page_cache);
+ out:
+	return ret;
+}
+-----------------------------------------------------------------------
+*/
+
+#ifndef	_LINUX_RBTREE_H
+#define	_LINUX_RBTREE_H
+
+typedef struct rb_node_s
+{
+	struct rb_node_s * rb_parent;
+	int rb_color;
+#define	RB_RED		0
+#define	RB_BLACK	1
+	struct rb_node_s * rb_right;
+	struct rb_node_s * rb_left;
+}
+rb_node_t;
+
+typedef struct rb_root_s
+{
+	struct rb_node_s * rb_node;
+}
+rb_root_t;
+
+#define RB_ROOT	(rb_root_t) { NULL, }
+#define	rb_entry(ptr, type, member)					\
+	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+extern void rb_insert_color(rb_node_t *, rb_root_t *);
+extern void rb_erase(rb_node_t *, rb_root_t *);
+extern rb_node_t *rb_get_first(rb_root_t *root);
+extern rb_node_t *rb_get_next(rb_node_t *n);
+
+static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+{
+	node->rb_parent = parent;
+	node->rb_color = RB_RED;
+	node->rb_left = node->rb_right = NULL;
+
+	*rb_link = node;
+}
+
+#endif	/* _LINUX_RBTREE_H */
diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-uml b/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-uml
deleted file mode 100644
index bb79c22aa8faabd103c4803645cbba0fc093e122..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-uml
+++ /dev/null
@@ -1,458 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_USERMODE=y
-# CONFIG_ISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_PCI is not set
-CONFIG_UID16=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# General Setup
-#
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSCTL=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-CONFIG_HOSTFS=y
-# CONFIG_HPPFS is not set
-CONFIG_MCONSOLE=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_HOST_2G_2G is not set
-# CONFIG_UML_SMP is not set
-# CONFIG_SMP is not set
-CONFIG_NEST_LEVEL=0
-CONFIG_KERNEL_HALF_GIGS=1
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_KMOD=y
-
-#
-# Character Devices
-#
-CONFIG_STDIO_CONSOLE=y
-CONFIG_SSL=y
-CONFIG_FD_CHAN=y
-# CONFIG_NULL_CHAN is not set
-CONFIG_PORT_CHAN=y
-CONFIG_PTY_CHAN=y
-CONFIG_TTY_CHAN=y
-CONFIG_XTERM_CHAN=y
-CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
-CONFIG_CON_CHAN="xterm"
-CONFIG_SSL_CHAN="pty"
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=2048
-# CONFIG_WATCHDOG is not set
-# CONFIG_UML_SOUND is not set
-# CONFIG_SOUND is not set
-# CONFIG_HOSTAUDIO is not set
-# CONFIG_TTY_LOG is not set
-
-#
-# Block Devices
-#
-CONFIG_BLK_DEV_UBD=y
-# CONFIG_BLK_DEV_UBD_SYNC is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_MMAPPER is not set
-CONFIG_NETDEVICES=y
-
-#
-# Network Devices
-#
-CONFIG_UML_NET=y
-# CONFIG_UML_NET_ETHERTAP is not set
-CONFIG_UML_NET_TUNTAP=y
-CONFIG_UML_NET_SLIP=y
-CONFIG_UML_NET_DAEMON=y
-CONFIG_UML_NET_MCAST=y
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_TUX is not set
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_ROUTE_LARGE_TABLES=y
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=y
-CONFIG_NET_IPGRE=y
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-#   IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=y
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_LOCAL=y
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-
-#
-#   IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=y
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=16
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
-CONFIG_IPV6=y
-
-#
-#   IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-# CONFIG_ATM_CLIP_NO_ICMP is not set
-CONFIG_ATM_LANE=y
-CONFIG_ATM_MPOA=y
-CONFIG_ATM_BR2684=m
-CONFIG_ATM_BR2684_IPFILTER=y
-CONFIG_VLAN_8021Q=m
-
-#
-#  
-#
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-CONFIG_DECNET=m
-CONFIG_DECNET_SIOCGIFCONF=y
-CONFIG_DECNET_ROUTER=y
-CONFIG_DECNET_ROUTE_FWMARK=y
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-CONFIG_NET_DIVERT=y
-# CONFIG_ECONET is not set
-CONFIG_WAN_ROUTER=y
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_CSZ=m
-# CONFIG_NET_SCH_ATM is not set
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# File systems
-#
-CONFIG_QUOTA=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-CONFIG_REISERFS_PROC_INFO=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=m
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=m
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_DEBUG=y
-# CONFIG_JFS_STATISTICS is not set
-CONFIG_MINIX_FS=m
-CONFIG_VXFS_FS=m
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=m
-CONFIG_EXT2_FS=y
-CONFIG_SYSV_FS=m
-CONFIG_UDF_FS=m
-CONFIG_UDF_RW=y
-CONFIG_UFS_FS=m
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-CONFIG_CODA_FS=m
-CONFIG_INTERMEZZO_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-CONFIG_NCP_FS=m
-CONFIG_NCPFS_PACKET_SIGNING=y
-CONFIG_NCPFS_IOCTL_LOCKING=y
-CONFIG_NCPFS_STRONG=y
-CONFIG_NCPFS_NFS_NS=y
-CONFIG_NCPFS_OS2_NS=y
-CONFIG_NCPFS_SMALLDOS=y
-CONFIG_NCPFS_NLS=y
-CONFIG_NCPFS_EXTRAS=y
-CONFIG_ZISOFS_FS=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-CONFIG_OSF_PARTITION=y
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_SUN_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_LVM=m
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUGSYM=y
-CONFIG_PT_PROXY=y
-# CONFIG_GPROF is not set
-# CONFIG_GCOV is not set
-
-#
-# Library routines
-#
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml b/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml
index 2d4a2d5380b4e117cec908106288be4efa5574b3..489ea8bb21f6107f4a459eb8a020f975028e2cfe 100644
--- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml
+++ b/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml
@@ -38,12 +38,12 @@ CONFIG_KERNEL_HALF_GIGS=1
 # CONFIG_HIGHMEM is not set
 # CONFIG_PROC_MM is not set
 CONFIG_KERNEL_STACK_ORDER=2
-CONFIG_MODE_TT=y
+
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 
 #
 # Character Devices
diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i386.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i386.config
new file mode 100644
index 0000000000000000000000000000000000000000..d7fba87c164f2da6c00dd6eac9ad008d2952689e
--- /dev/null
+++ b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i386.config
@@ -0,0 +1,1981 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_X86=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+CONFIG_LOLAT=y
+CONFIG_M386=y
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MELAN is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_X86_CMPXCHG is not set
+# CONFIG_X86_XADD is not set
+CONFIG_X86_L1_CACHE_SHIFT=4
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_X86_PPRO_FENCE=y
+# CONFIG_X86_F00F_WORKS_OK is not set
+CONFIG_X86_MCE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_E820_PROC is not set
+CONFIG_EDD=m
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_MATH_EMULATION=y
+CONFIG_MTRR=y
+# CONFIG_SMP is not set
+# CONFIG_X86_UP_APIC is not set
+# CONFIG_X86_UP_IOAPIC is not set
+# CONFIG_X86_TSC_DISABLE is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_ISA=y
+CONFIG_PCI_NAMES=y
+CONFIG_EISA=y
+# CONFIG_MCA is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+CONFIG_TCIC=y
+CONFIG_I82092=y
+CONFIG_I82365=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_IBM is not set
+# CONFIG_HOTPLUG_PCI_H2999 is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+# CONFIG_ACPI is not set
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play configuration
+#
+CONFIG_PNP=y
+CONFIG_ISAPNP=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_XD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_BLK_DEV_LVM=m
+
+#
+# Cryptography support (CryptoAPI)
+#
+CONFIG_CRYPTO=m
+CONFIG_CIPHERS=m
+
+#
+# 128 bit blocksize
+#
+CONFIG_CIPHER_AES=m
+CONFIG_CIPHER_IDENTITY=m
+CONFIG_CRYPTODEV=m
+CONFIG_CRYPTOLOOP=m
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_TUX=m
+CONFIG_TUX_EXTCGI=y
+# CONFIG_TUX_EXTENDED_LOG is not set
+# CONFIG_TUX_DEBUG is not set
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_LARGE_TABLES=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_COMPAT_IPFWADM=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+# CONFIG_KHTTPD is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_ATM_BR2684_IPFILTER=y
+CONFIG_VLAN_8021Q=m
+
+#
+#  
+#
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+
+#
+# Appletalk devices
+#
+CONFIG_DEV_APPLETALK=y
+CONFIG_LTPC=m
+CONFIG_COPS=m
+CONFIG_COPS_DAYNA=y
+CONFIG_COPS_TANGENT=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_DECNET=m
+CONFIG_DECNET_SIOCGIFCONF=y
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_BRIDGE=m
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_CSZ=m
+# CONFIG_NET_SCH_ATM is not set
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+CONFIG_PHONE=m
+CONFIG_PHONE_IXJ=m
+CONFIG_PHONE_IXJ_PCMCIA=m
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_BLK_DEV_CMD640=y
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+CONFIG_BLK_DEV_ISAPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+CONFIG_BLK_DEV_ADMA100=y
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_AMD74XX_OVERRIDE is not set
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_RZ1000=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_PDC202XX=y
+CONFIG_BLK_DEV_IDE_MODES=y
+CONFIG_BLK_DEV_ATARAID=m
+CONFIG_BLK_DEV_ATARAID_PDC=m
+CONFIG_BLK_DEV_ATARAID_HPT=m
+CONFIG_BLK_DEV_ATARAID_SII=m
+
+#
+# SCSI support
+#
+CONFIG_SCSI=m
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=4
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_7000FASST=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AHA1740=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=253
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+CONFIG_AIC79XX_ENABLE_RD_STRM=y
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y
+CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_OLD_PROC_STATS=y
+CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
+CONFIG_SCSI_AM53C974=m
+CONFIG_SCSI_MEGARAID=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+CONFIG_SCSI_CPQFCTS=m
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_DTC3280=m
+CONFIG_SCSI_EATA=m
+CONFIG_SCSI_EATA_TAGGED_QUEUE=y
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_EATA_DMA=m
+CONFIG_SCSI_EATA_PIO=m
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_GENERIC_NCR5380=m
+# CONFIG_SCSI_GENERIC_NCR53C400 is not set
+CONFIG_SCSI_G_NCR5380_PORT=y
+# CONFIG_SCSI_G_NCR5380_MEM is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_NCR53C406A=m
+CONFIG_SCSI_NCR53C7xx=m
+# CONFIG_SCSI_NCR53C7xx_sync is not set
+CONFIG_SCSI_NCR53C7xx_FAST=y
+CONFIG_SCSI_NCR53C7xx_DISCONNECT=y
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_NCR53C8XX=m
+CONFIG_SCSI_SYM53C8XX=m
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=40
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+CONFIG_SCSI_PAS16=m
+CONFIG_SCSI_PCI2000=m
+CONFIG_SCSI_PCI2220I=m
+CONFIG_SCSI_PSI240I=m
+CONFIG_SCSI_QLOGIC_FAS=m
+CONFIG_SCSI_QLOGIC_ISP=m
+CONFIG_SCSI_QLOGIC_FC=m
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_NEWISP=m
+CONFIG_SCSI_SEAGATE=m
+CONFIG_SCSI_SIM710=m
+CONFIG_SCSI_SYM53C416=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DC390T_NOGENSUPP is not set
+CONFIG_SCSI_T128=m
+CONFIG_SCSI_U14_34F=m
+# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set
+CONFIG_SCSI_U14_34F_MAX_TAGS=8
+CONFIG_SCSI_ULTRASTOR=m
+CONFIG_SCSI_NSP32=m
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_SCSI_PCMCIA=y
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+# CONFIG_FUSION_BOOT is not set
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+CONFIG_NET_FC=y
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+CONFIG_IEEE1394=m
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_SBP2_PHYS_DMA=y
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+CONFIG_I2O_PCI=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_LAN=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+CONFIG_NET_SB1000=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+CONFIG_HAPPYMEAL=m
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+CONFIG_SUNGEM=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL1=m
+CONFIG_EL2=m
+CONFIG_ELPLUS=m
+CONFIG_EL16=m
+CONFIG_EL3=m
+CONFIG_3C515=m
+# CONFIG_ELMC is not set
+# CONFIG_ELMC_II is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+CONFIG_LANCE=m
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_WD80x3=m
+# CONFIG_ULTRAMCA is not set
+CONFIG_ULTRA=m
+CONFIG_ULTRA32=m
+CONFIG_SMC9194=m
+CONFIG_NET_VENDOR_RACAL=y
+CONFIG_NI5010=m
+CONFIG_NI52=m
+CONFIG_NI65=m
+CONFIG_AT1700=m
+CONFIG_DEPCA=m
+CONFIG_HP100=m
+CONFIG_NET_ISA=y
+CONFIG_E2100=m
+CONFIG_EWRK3=m
+CONFIG_EEXPRESS=m
+CONFIG_EEXPRESS_PRO=m
+CONFIG_HPLAN_PLUS=m
+CONFIG_HPLAN=m
+CONFIG_LP486E=m
+CONFIG_ETH16I=m
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_AC3200=m
+CONFIG_APRICOT=m
+CONFIG_CS89x0=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+CONFIG_DE4X5=m
+CONFIG_DGRS=m
+CONFIG_DM9102=m
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_LNE390=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_NE3210=m
+CONFIG_ES3210=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_TC35815=m
+CONFIG_VIA_RHINE=m
+# CONFIG_VIA_RHINE_MMIO is not set
+CONFIG_WINBOND_840=m
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+# CONFIG_MYRI_SBUS is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_SK98LIN=m
+CONFIG_TIGON3=m
+CONFIG_FDDI=y
+CONFIG_DEFXX=m
+CONFIG_SKFP=m
+CONFIG_NETCONSOLE=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_STRIP=m
+CONFIG_WAVELAN=m
+CONFIG_ARLAN=m
+CONFIG_AIRONET4500=m
+CONFIG_AIRONET4500_NONCS=m
+CONFIG_AIRONET4500_PNP=y
+CONFIG_AIRONET4500_PCI=y
+CONFIG_AIRONET4500_ISA=y
+CONFIG_AIRONET4500_I365=y
+CONFIG_AIRONET4500_PROC=m
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_PCI_HERMES=m
+
+#
+# Wireless Pcmcia cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# Wireless Pcmcia cards support
+#
+CONFIG_PCMCIA_HERMES_OLD=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMTR=m
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+CONFIG_TMS380TR=m
+CONFIG_TMSPCI=m
+CONFIG_TMSISA=m
+CONFIG_ABYSS=m
+# CONFIG_MADGEMC is not set
+CONFIG_SMCTR=m
+CONFIG_NET_FC=y
+CONFIG_IPHASE5526=m
+CONFIG_RCPCI=m
+CONFIG_SHAPER=m
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+CONFIG_HOSTESS_SV11=m
+CONFIG_COSA=m
+# CONFIG_COMX is not set
+# CONFIG_DSCC4 is not set
+# CONFIG_LANMEDIA is not set
+CONFIG_ATI_XX20=m
+CONFIG_SEALEVEL_4021=m
+# CONFIG_SYNCLINK_SYNCPPP is not set
+# CONFIG_HDLC is not set
+CONFIG_DLCI=m
+CONFIG_DLCI_COUNT=24
+CONFIG_DLCI_MAX=8
+CONFIG_SDLA=m
+CONFIG_WAN_ROUTER_DRIVERS=y
+CONFIG_VENDOR_SANGOMA=m
+CONFIG_WANPIPE_CHDLC=y
+CONFIG_WANPIPE_FR=y
+CONFIG_WANPIPE_X25=y
+CONFIG_WANPIPE_PPP=y
+CONFIG_WANPIPE_MULTPPP=y
+CONFIG_CYCLADES_SYNC=m
+CONFIG_CYCLOMX_X25=y
+# CONFIG_LAPBETHER is not set
+# CONFIG_X25_ASY is not set
+CONFIG_SBNI=m
+CONFIG_SBNI_MULTILINE=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+# CONFIG_ARCNET_COM20020_CS is not set
+CONFIG_PCMCIA_IBMTR=m
+CONFIG_PCMCIA_XIRCOM=m
+CONFIG_PCMCIA_XIRTULIP=m
+CONFIG_NET_PCMCIA_RADIO=y
+CONFIG_PCMCIA_RAYCS=m
+CONFIG_PCMCIA_NETWAVE=m
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_WVLAN=m
+CONFIG_AIRONET4500_CS=m
+
+#
+# ATM drivers
+#
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+CONFIG_ATM_ZATM=m
+# CONFIG_ATM_ZATM_DEBUG is not set
+CONFIG_ATM_ZATM_EXACT_TS=y
+CONFIG_ATM_NICSTAR=m
+CONFIG_ATM_NICSTAR_USE_SUNI=y
+CONFIG_ATM_NICSTAR_USE_IDT77105=y
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_IA=m
+# CONFIG_ATM_IA_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+CONFIG_ATM_FORE200E_PCA=y
+CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y
+CONFIG_ATM_FORE200E_TX_RETRY=16
+CONFIG_ATM_FORE200E_DEBUG=0
+CONFIG_ATM_FORE200E=m
+
+#
+# Amateur Radio support
+#
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+
+#
+# AX.25 network device drivers
+#
+# CONFIG_MKISS is not set
+# CONFIG_6PACK is not set
+# CONFIG_BPQETHER is not set
+# CONFIG_DMASCC is not set
+# CONFIG_SCC is not set
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+CONFIG_SOUNDMODEM=m
+CONFIG_SOUNDMODEM_SBC=y
+CONFIG_SOUNDMODEM_WSS=y
+CONFIG_SOUNDMODEM_AFSK1200=y
+CONFIG_SOUNDMODEM_AFSK2400_7=y
+CONFIG_SOUNDMODEM_AFSK2400_8=y
+CONFIG_SOUNDMODEM_AFSK2666=y
+CONFIG_SOUNDMODEM_HAPN4800=y
+CONFIG_SOUNDMODEM_PSK4800=y
+CONFIG_SOUNDMODEM_FSK9600=y
+# CONFIG_YAM is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_IRPORT_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+CONFIG_MA600_DONGLE=m
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_OLD=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+CONFIG_ISDN_BOOL=y
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_ISDN_PPP_BSDCOMP=m
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+# CONFIG_ISDN_DIVERSION is not set
+
+#
+# low-level hardware drivers
+#
+
+#
+# Passive ISDN cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+CONFIG_ISDN_HISAX=y
+
+#
+#   D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+# CONFIG_HISAX_NO_SENDCOMPLETE is not set
+# CONFIG_HISAX_NO_LLC is not set
+# CONFIG_HISAX_NO_KEYPAD is not set
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+#   HiSax supported cards
+#
+CONFIG_HISAX_16_0=y
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_AVM_A1=y
+CONFIG_HISAX_IX1MICROR2=y
+CONFIG_HISAX_ASUSCOM=y
+CONFIG_HISAX_TELEINT=y
+CONFIG_HISAX_HFCS=y
+CONFIG_HISAX_SPORTSTER=y
+CONFIG_HISAX_MIC=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+CONFIG_HISAX_DEBUG=y
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_ST5481=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_USB_AUERISDN=m
+
+#
+# Active ISDN cards
+#
+CONFIG_ISDN_DRV_ICN=m
+CONFIG_ISDN_DRV_PCBIT=m
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_ISDN_DRV_EICON=y
+CONFIG_ISDN_DRV_EICON_DIVAS=m
+# CONFIG_ISDN_DRV_EICON_OLD is not set
+CONFIG_ISDN_DRV_TPAM=m
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+CONFIG_ISDN_DRV_AVMB1_B1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+CONFIG_KALLSYMS=y
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=m
+CONFIG_INPUT_KEYBDEV=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_ECC=m
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_SERIAL_EXTENDED=y
+CONFIG_SERIAL_MANY_PORTS=y
+CONFIG_SERIAL_SHARE_IRQ=y
+# CONFIG_SERIAL_DETECT_IRQ is not set
+CONFIG_SERIAL_MULTIPORT=y
+# CONFIG_HUB6 is not set
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_COMPUTONE=m
+CONFIG_ROCKETPORT=m
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+CONFIG_DIGIEPCA=m
+CONFIG_ESPSERIAL=m
+CONFIG_MOXA_INTELLIO=m
+CONFIG_MOXA_SMARTIO=m
+CONFIG_ISI=m
+CONFIG_SYNCLINK=m
+# CONFIG_SYNCLINKMP is not set
+CONFIG_N_HDLC=m
+CONFIG_RISCOM8=m
+CONFIG_SPECIALIX=m
+CONFIG_SPECIALIX_RTSCTS=y
+CONFIG_SX=m
+# CONFIG_RIO is not set
+CONFIG_STALDRV=y
+CONFIG_STALLION=m
+CONFIG_ISTALLION=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=512
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_PHILIPSPAR=m
+CONFIG_I2C_ELV=m
+CONFIG_I2C_VELLEMAN=m
+# CONFIG_SCx200_I2C is not set
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ELEKTOR=m
+CONFIG_I2C_MAINBOARD=y
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_HYDRA=m
+CONFIG_I2C_AMD756=m
+# CONFIG_I2C_TSUNAMI is not set
+CONFIG_I2C_I801=m
+# CONFIG_I2C_I810 is not set
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PROC=m
+
+#
+# Hardware sensors support
+#
+CONFIG_SENSORS=y
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1024=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_FSCSCY=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_MAXILIFE=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_MTP008=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_THMC50=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_OTHER=y
+CONFIG_SENSORS_BT869=m
+CONFIG_SENSORS_DDCMON=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_MATORB=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=m
+CONFIG_ATIXL_BUSMOUSE=m
+CONFIG_LOGIBUSMOUSE=m
+CONFIG_MS_BUSMOUSE=m
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+CONFIG_82C710_MOUSE=m
+CONFIG_PC110_PAD=m
+CONFIG_MK712_MOUSE=m
+
+#
+# Joysticks
+#
+CONFIG_INPUT_GAMEPORT=m
+CONFIG_INPUT_NS558=m
+CONFIG_INPUT_LIGHTNING=m
+CONFIG_INPUT_PCIGAME=m
+CONFIG_INPUT_CS461X=m
+CONFIG_INPUT_EMU10K1=m
+CONFIG_INPUT_SERIO=m
+CONFIG_INPUT_SERPORT=m
+
+#
+# Joysticks
+#
+CONFIG_INPUT_ANALOG=m
+CONFIG_INPUT_A3D=m
+CONFIG_INPUT_ADI=m
+CONFIG_INPUT_COBRA=m
+CONFIG_INPUT_GF2K=m
+CONFIG_INPUT_GRIP=m
+CONFIG_INPUT_INTERACT=m
+CONFIG_INPUT_TMDC=m
+CONFIG_INPUT_SIDEWINDER=m
+CONFIG_INPUT_IFORCE_USB=m
+CONFIG_INPUT_IFORCE_232=m
+CONFIG_INPUT_WARRIOR=m
+CONFIG_INPUT_MAGELLAN=m
+CONFIG_INPUT_SPACEORB=m
+CONFIG_INPUT_SPACEBALL=m
+CONFIG_INPUT_STINGER=m
+CONFIG_INPUT_DB9=m
+CONFIG_INPUT_GAMECON=m
+CONFIG_INPUT_TURBOGRAFX=m
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+CONFIG_ACQUIRE_WDT=m
+CONFIG_ADVANTECH_WDT=m
+CONFIG_ALIM7101_WDT=m
+CONFIG_SC520_WDT=m
+CONFIG_PCWATCHDOG=m
+CONFIG_EUROTECH_WDT=m
+CONFIG_IB700_WDT=m
+CONFIG_WAFER_WDT=m
+CONFIG_I810_TCO=m
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_W83877F_WDT=m
+CONFIG_WDT=m
+CONFIG_WDTPCI=m
+# CONFIG_WDT_501 is not set
+CONFIG_MACHZ_WDT=m
+CONFIG_AMD7XX_TCO=m
+# CONFIG_SCx200_GPIO is not set
+CONFIG_AMD_RNG=m
+CONFIG_INTEL_RNG=m
+CONFIG_AMD_PM768=m
+CONFIG_NVRAM=m
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_FTAPE=m
+CONFIG_ZFTAPE=m
+CONFIG_ZFT_DFLT_BLK_SZ=10240
+
+#
+#   The compressor will be built as a module only!
+#
+CONFIG_ZFT_COMPRESSOR=m
+CONFIG_FT_NR_BUFFERS=3
+# CONFIG_FT_PROC_FS is not set
+CONFIG_FT_NORMAL_DEBUG=y
+# CONFIG_FT_FULL_DEBUG is not set
+# CONFIG_FT_NO_TRACE is not set
+# CONFIG_FT_NO_TRACE_AT_ALL is not set
+
+#
+# Hardware configuration
+#
+CONFIG_FT_STD_FDC=y
+# CONFIG_FT_MACH2 is not set
+# CONFIG_FT_PROBE_FC10 is not set
+# CONFIG_FT_ALT_FDC is not set
+CONFIG_FT_FDC_THR=8
+CONFIG_FT_FDC_MAX_RATE=2000
+CONFIG_FT_ALPHA_CLOCK=0
+CONFIG_AGP=m
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_I810=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD_8151=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_SWORKS=y
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_PCMCIA_SERIAL_CS=m
+CONFIG_SYNCLINK_CS=m
+CONFIG_MWAVE=m
+CONFIG_BATTERY_GERICOM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+CONFIG_I2C_PARPORT=m
+
+#
+# Video Adapters
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZR36120=m
+CONFIG_VIDEO_MEYE=m
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_RADIO_MIROPCM20=m
+CONFIG_RADIO_MIROPCM20_RDS=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+
+#
+# Crypto Hardware support
+#
+CONFIG_CRYPTO=m
+CONFIG_CRYPTO_BROADCOM=m
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+# CONFIG_QIFACE_COMPAT is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_XATTR_SHARING=y
+CONFIG_EXT3_FS_XATTR_USER=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_UMSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_JFS_FS=m
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_MINIX_FS=m
+CONFIG_VXFS_FS=m
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_XATTR_SHARING is not set
+# CONFIG_EXT2_FS_XATTR_USER is not set
+CONFIG_SYSV_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_RW=y
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_CODA_FS=m
+CONFIG_INTERMEZZO_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_FS_MBCACHE=y
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Console drivers
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VIDEO_SELECT=y
+# CONFIG_VIDEO_IGNORE_BAD_MODE is not set
+CONFIG_MDA_CONSOLE=m
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_RIVA=m
+CONFIG_FB_CLGEN=m
+CONFIG_FB_PM2=m
+# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
+CONFIG_FB_PM2_PCI=y
+CONFIG_FB_PM3=m
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_VESA=y
+CONFIG_FB_VGA16=m
+CONFIG_FB_HGA=m
+CONFIG_VIDEO_SELECT=y
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_FB_MATROX_G450 is not set
+CONFIG_FB_MATROX_G100A=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+# CONFIG_FB_MATROX_PROC is not set
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_CT_VAIO_LCD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_ATY128=m
+CONFIG_FB_SIS=m
+CONFIG_FB_SIS_300=y
+CONFIG_FB_SIS_315=y
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_VOODOO1=m
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_MFB=m
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_VGA_PLANES=m
+CONFIG_FBCON_HGA=m
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+CONFIG_SOUND_ALI5455=m
+CONFIG_SOUND_BT878=m
+CONFIG_SOUND_CMPCI=m
+CONFIG_SOUND_CMPCI_FM=y
+CONFIG_SOUND_CMPCI_FMIO=388
+CONFIG_SOUND_CMPCI_FMIO=388
+CONFIG_SOUND_CMPCI_MIDI=y
+CONFIG_SOUND_CMPCI_MPUIO=330
+CONFIG_SOUND_CMPCI_JOYSTICK=y
+CONFIG_SOUND_CMPCI_CM8738=y
+# CONFIG_SOUND_CMPCI_SPDIFINVERSE is not set
+CONFIG_SOUND_CMPCI_SPDIFLOOP=y
+CONFIG_SOUND_CMPCI_SPEAKERS=2
+CONFIG_SOUND_EMU10K1=m
+CONFIG_MIDI_EMU10K1=y
+CONFIG_SOUND_AUDIGY=m
+CONFIG_SOUND_FUSION=m
+CONFIG_SOUND_CS4281=m
+CONFIG_SOUND_ES1370=m
+CONFIG_SOUND_ES1371=m
+CONFIG_SOUND_ESSSOLO1=m
+CONFIG_SOUND_MAESTRO=m
+CONFIG_SOUND_MAESTRO3=m
+CONFIG_SOUND_FORTE=m
+CONFIG_SOUND_ICH=m
+CONFIG_SOUND_RME96XX=m
+CONFIG_SOUND_SONICVIBES=m
+CONFIG_SOUND_TRIDENT=m
+CONFIG_SOUND_MSNDCLAS=m
+# CONFIG_MSNDCLAS_HAVE_BOOT is not set
+CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin"
+CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin"
+CONFIG_SOUND_MSNDPIN=m
+# CONFIG_MSNDPIN_HAVE_BOOT is not set
+CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin"
+CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin"
+CONFIG_SOUND_VIA82CXXX=m
+CONFIG_MIDI_VIA82CXXX=y
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_TRACEINIT is not set
+CONFIG_SOUND_DMAP=y
+CONFIG_SOUND_AD1816=m
+CONFIG_SOUND_AD1889=m
+CONFIG_SOUND_SGALAXY=m
+CONFIG_SOUND_ADLIB=m
+CONFIG_SOUND_ACI_MIXER=m
+CONFIG_SOUND_CS4232=m
+CONFIG_SOUND_SSCAPE=m
+CONFIG_SOUND_GUS=m
+CONFIG_SOUND_GUS16=y
+CONFIG_SOUND_GUSMAX=y
+CONFIG_SOUND_VMIDI=m
+CONFIG_SOUND_TRIX=m
+CONFIG_SOUND_MSS=m
+CONFIG_SOUND_MPU401=m
+CONFIG_SOUND_NM256=m
+CONFIG_SOUND_MAD16=m
+CONFIG_MAD16_OLDCARD=y
+CONFIG_SOUND_PAS=m
+# CONFIG_PAS_JOYSTICK is not set
+CONFIG_SOUND_PSS=m
+# CONFIG_PSS_MIXER is not set
+# CONFIG_PSS_HAVE_BOOT is not set
+CONFIG_SOUND_SB=m
+CONFIG_SOUND_AWE32_SYNTH=m
+CONFIG_SOUND_KAHLUA=m
+CONFIG_SOUND_WAVEFRONT=m
+CONFIG_SOUND_MAUI=m
+CONFIG_SOUND_YM3812=m
+CONFIG_SOUND_OPL3SA1=m
+CONFIG_SOUND_OPL3SA2=m
+CONFIG_SOUND_YMFPCI=m
+CONFIG_SOUND_YMFPCI_LEGACY=y
+CONFIG_SOUND_UART6850=m
+CONFIG_SOUND_AEDSP16=m
+CONFIG_SC6600=y
+CONFIG_SC6600_JOY=y
+CONFIG_SC6600_CDROM=4
+CONFIG_SC6600_CDROMBASE=0
+CONFIG_AEDSP16_SBPRO=y
+CONFIG_AEDSP16_MPU401=y
+CONFIG_SOUND_TVMIXER=m
+
+#
+# USB support
+#
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_UHCI=m
+CONFIG_USB_UHCI_ALT=m
+CONFIG_USB_OHCI=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+# CONFIG_USB_EMI26 is not set
+
+#
+#   USB Bluetooth can only be used with disabled Bluetooth subsystem
+#
+CONFIG_USB_MIDI=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_MDC800=m
+CONFIG_USB_SCANNER=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_PWC=m
+CONFIG_USB_SE401=m
+CONFIG_USB_STV680=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_DABUSB=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_CATC=m
+CONFIG_USB_CDCETHER=m
+CONFIG_USB_USBNET=m
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_RIO500=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_TIGL=m
+CONFIG_USB_BRLVGER=m
+CONFIG_USB_LCD=m
+
+#
+# Additional device driver support
+#
+CONFIG_NET_BROADCOM=m
+CONFIG_CIPE=m
+CONFIG_CRYPTO_AEP=m
+CONFIG_MEGARAC=m
+CONFIG_FC_QLA2200=m
+CONFIG_FC_QLA2300=m
+CONFIG_SCSI_ISCSI=m
+
+#
+# Bluetooth support
+#
+CONFIG_BLUEZ=m
+CONFIG_BLUEZ_L2CAP=m
+CONFIG_BLUEZ_SCO=m
+CONFIG_BLUEZ_RFCOMM=m
+CONFIG_BLUEZ_RFCOMM_TTY=y
+CONFIG_BLUEZ_BNEP=m
+CONFIG_BLUEZ_BNEP_MC_FILTER=y
+CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BLUEZ_HCIUSB=m
+CONFIG_BLUEZ_USB_SCO=y
+CONFIG_BLUEZ_USB_ZERO_PACKET=y
+CONFIG_BLUEZ_HCIUART=m
+CONFIG_BLUEZ_HCIUART_H4=y
+CONFIG_BLUEZ_HCIUART_BCSP=y
+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
+CONFIG_BLUEZ_HCIDTL1=m
+CONFIG_BLUEZ_HCIBT3C=m
+CONFIG_BLUEZ_HCIBLUECARD=m
+CONFIG_BLUEZ_HCIBTUART=m
+CONFIG_BLUEZ_HCIVHCI=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_IOVIRT is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_MCL_COREDUMP is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-i386 b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config
similarity index 89%
rename from lustre/kernel_patches/kernel_configs/config-linux-2.4.18-i386
rename to lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config
index 94ee0ab73bdd356250cb468302eff6c327e593a8..0a077c51c197d70ccefe0f1e47d5e3eeb1bf67f8 100644
--- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-i386
+++ b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config
@@ -2,7 +2,6 @@
 # Automatically generated by make menuconfig: don't edit
 #
 CONFIG_X86=y
-CONFIG_ISA=y
 # CONFIG_SBUS is not set
 CONFIG_UID16=y
 
@@ -22,13 +21,12 @@ CONFIG_KMOD=y
 # Processor type and features
 #
 CONFIG_LOLAT=y
-# CONFIG_LOLAT_SYSCTL is not set
-CONFIG_M386=y
+# CONFIG_M386 is not set
 # CONFIG_M486 is not set
 # CONFIG_M586 is not set
 # CONFIG_M586TSC is not set
 # CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
+CONFIG_M686=y
 # CONFIG_MPENTIUMIII is not set
 # CONFIG_MPENTIUM4 is not set
 # CONFIG_MK6 is not set
@@ -39,49 +37,62 @@ CONFIG_M386=y
 # CONFIG_MWINCHIP2 is not set
 # CONFIG_MWINCHIP3D is not set
 # CONFIG_MCYRIXIII is not set
-# CONFIG_X86_CMPXCHG is not set
-# CONFIG_X86_XADD is not set
-CONFIG_X86_L1_CACHE_SHIFT=4
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_HAS_TSC=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_PGE=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
 CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_WORKS_OK=y
 CONFIG_X86_MCE=y
+
+#
+# CPU Frequency scaling
+#
 # CONFIG_CPU_FREQ is not set
 CONFIG_TOSHIBA=m
 CONFIG_I8K=m
-# CONFIG_MICROCODE is not set
+CONFIG_MICROCODE=m
 CONFIG_X86_MSR=m
 CONFIG_X86_CPUID=m
 # CONFIG_E820_PROC is not set
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
+CONFIG_EDD=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
 # CONFIG_HIGHMEM64G is not set
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
 CONFIG_HIGHIO=y
-CONFIG_MATH_EMULATION=y
+# CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
-# CONFIG_SMP is not set
-CONFIG_X86_UP_APIC=y
-CONFIG_X86_UP_IOAPIC=y
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
+CONFIG_SMP=y
+# CONFIG_X86_NUMA is not set
+# CONFIG_X86_TSC_DISABLE is not set
+CONFIG_X86_TSC=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # General setup
 #
-CONFIG_HZ=100
 CONFIG_NET=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_LOCAL_APIC=y
 CONFIG_PCI=y
 # CONFIG_PCI_GOBIOS is not set
 # CONFIG_PCI_GODIRECT is not set
 CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
+CONFIG_ISA=y
 CONFIG_PCI_NAMES=y
-
-#
-# Performance-monitoring counters support
-#
-# CONFIG_PERFCTR is not set
 CONFIG_EISA=y
 # CONFIG_MCA is not set
 CONFIG_HOTPLUG=y
@@ -98,11 +109,12 @@ CONFIG_I82365=y
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-# CONFIG_HOTPLUG_PCI_IBM is not set
+CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_ACPI is not set
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+# CONFIG_HOTPLUG_PCI_H2999 is not set
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
@@ -111,20 +123,7 @@ CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
-# CONFIG_IKCONFIG is not set
 CONFIG_PM=y
-
-#
-# Additional device driver support
-#
-CONFIG_CIPE=m
-CONFIG_CRYPTO_AEP=m
-CONFIG_MEGARAC=m
-CONFIG_FC_QLA2200=m
-CONFIG_FC_QLA2300=m
-CONFIG_SCSI_ISCSI=m
-# CONFIG_IBMASM is not set
-# CONFIG_IBMSER is not set
 # CONFIG_ACPI is not set
 CONFIG_APM=y
 # CONFIG_APM_IGNORE_USER_SUSPEND is not set
@@ -135,25 +134,6 @@ CONFIG_APM_RTC_IS_GMT=y
 # CONFIG_APM_ALLOW_INTS is not set
 # CONFIG_APM_REAL_MODE_POWER_OFF is not set
 
-#
-# Binary emulation of other systems
-#
-CONFIG_ABI=m
-CONFIG_ABI_SVR4=m
-CONFIG_ABI_UW7=m
-# CONFIG_ABI_SOLARIS is not set
-CONFIG_ABI_IBCS=m
-CONFIG_ABI_ISC=m
-CONFIG_ABI_SCO=m
-# CONFIG_ABI_WYSE is not set
-CONFIG_BINFMT_COFF=m
-CONFIG_BINFMT_XOUT=m
-# CONFIG_BINFMT_XOUT_X286 is not set
-CONFIG_ABI_SPX=y
-CONFIG_ABI_XTI=y
-CONFIG_ABI_TLI_OPTMGMT=y
-# CONFIG_ABI_XTI_OPTMGMT is not set
-
 #
 # Memory Technology Devices (MTD)
 #
@@ -182,7 +162,6 @@ CONFIG_PARPORT_1284=y
 #
 CONFIG_PNP=y
 CONFIG_ISAPNP=y
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -219,10 +198,10 @@ CONFIG_BLK_DEV_DAC960=m
 CONFIG_BLK_DEV_UMEM=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_ENBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_STATS=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -286,19 +265,26 @@ CONFIG_SYN_COOKIES=y
 #
 CONFIG_IP_NF_CONNTRACK=m
 CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
 CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
 CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_UNCLEAN=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_FILTER=m
@@ -308,12 +294,16 @@ CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_AMANDA=m
 CONFIG_IP_NF_NAT_LOCAL=y
 CONFIG_IP_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
@@ -324,22 +314,6 @@ CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_COMPAT_IPFWADM=m
 CONFIG_IP_NF_NAT_NEEDED=y
-
-#
-#   IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=16
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_FTP=m
 CONFIG_IPV6=m
 
 #
@@ -349,9 +323,17 @@ CONFIG_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_LIMIT=m
 CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
 CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_MANGLE=m
@@ -448,15 +430,6 @@ CONFIG_BLK_DEV_IDE=y
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
 CONFIG_BLK_DEV_IDECS=m
 CONFIG_BLK_DEV_IDECD=m
 CONFIG_BLK_DEV_IDETAPE=m
@@ -466,8 +439,8 @@ CONFIG_BLK_DEV_IDESCSI=m
 CONFIG_BLK_DEV_CMD640=y
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 CONFIG_BLK_DEV_ISAPNP=y
-CONFIG_BLK_DEV_RZ1000=y
 CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -476,45 +449,44 @@ CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
-# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-CONFIG_BLK_DEV_ADMA=y
+CONFIG_BLK_DEV_ADMA100=y
 CONFIG_BLK_DEV_AEC62XX=y
-CONFIG_AEC62XX_TUNING=y
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
 CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_CMD680=y
+CONFIG_BLK_DEV_TRIFLEX=y
 CONFIG_BLK_DEV_CY82C693=y
 CONFIG_BLK_DEV_CS5530=y
 CONFIG_BLK_DEV_HPT34X=y
 # CONFIG_HPT34X_AUTODMA is not set
 CONFIG_BLK_DEV_HPT366=y
 CONFIG_BLK_DEV_PIIX=y
-CONFIG_PIIX_TUNING=y
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_ADMA100=y
-CONFIG_BLK_DEV_PDC202XX=y
+CONFIG_BLK_DEV_PDC202XX_OLD=y
 # CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
 CONFIG_PDC202XX_FORCE=y
+CONFIG_BLK_DEV_RZ1000=y
+# CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
 CONFIG_BLK_DEV_SIS5513=y
 CONFIG_BLK_DEV_SLC90E66=y
 # CONFIG_BLK_DEV_TRM290 is not set
 CONFIG_BLK_DEV_VIA82CXXX=y
-CONFIG_BLK_DEV_CENATEK=y
 # CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
 # CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_PDC202XX=y
 CONFIG_BLK_DEV_IDE_MODES=y
 CONFIG_BLK_DEV_ATARAID=m
 CONFIG_BLK_DEV_ATARAID_PDC=m
 CONFIG_BLK_DEV_ATARAID_HPT=m
+CONFIG_BLK_DEV_ATARAID_SII=m
 
 #
 # SCSI support
@@ -627,6 +599,7 @@ CONFIG_SCSI_U14_34F=m
 # CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set
 CONFIG_SCSI_U14_34F_MAX_TAGS=8
 CONFIG_SCSI_ULTRASTOR=m
+CONFIG_SCSI_NSP32=m
 CONFIG_SCSI_DEBUG=m
 
 #
@@ -643,6 +616,7 @@ CONFIG_PCMCIA_QLOGIC=m
 #
 CONFIG_FUSION=m
 # CONFIG_FUSION_BOOT is not set
+CONFIG_FUSION_MAX_SGE=40
 # CONFIG_FUSION_ISENSE is not set
 CONFIG_FUSION_CTL=m
 CONFIG_FUSION_LAN=m
@@ -656,10 +630,12 @@ CONFIG_IEEE1394=m
 CONFIG_IEEE1394_OHCI1394=m
 CONFIG_IEEE1394_VIDEO1394=m
 CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_SBP2_PHYS_DMA=y
 CONFIG_IEEE1394_ETH1394=m
 CONFIG_IEEE1394_DV1394=m
 CONFIG_IEEE1394_RAWIO=m
 CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
 # CONFIG_IEEE1394_VERBOSEDEBUG is not set
 
 #
@@ -707,6 +683,7 @@ CONFIG_3C515=m
 # CONFIG_ELMC is not set
 # CONFIG_ELMC_II is not set
 CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
 CONFIG_LANCE=m
 CONFIG_NET_VENDOR_SMC=y
 CONFIG_WD80x3=m
@@ -723,7 +700,7 @@ CONFIG_DEPCA=m
 CONFIG_HP100=m
 CONFIG_NET_ISA=y
 CONFIG_E2100=m
-CONFIG_EWRK3=m
+# CONFIG_EWRK3 is not set
 CONFIG_EEXPRESS=m
 CONFIG_EEXPRESS_PRO=m
 CONFIG_HPLAN_PLUS=m
@@ -733,23 +710,23 @@ CONFIG_ETH16I=m
 CONFIG_NE2000=m
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_AC3200=m
 CONFIG_APRICOT=m
 CONFIG_CS89x0=m
 CONFIG_TULIP=m
-CONFIG_TC35815=m
 # CONFIG_TULIP_MWI is not set
 CONFIG_TULIP_MMIO=y
 CONFIG_DE4X5=m
 CONFIG_DGRS=m
 CONFIG_DM9102=m
 CONFIG_EEPRO100=m
-CONFIG_NET_E100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
 CONFIG_LNE390=m
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
-# CONFIG_NATSEMI_CABLE_MAGIC is not set
 CONFIG_NE2K_PCI=m
 CONFIG_NE3210=m
 CONFIG_ES3210=m
@@ -758,12 +735,13 @@ CONFIG_8139TOO=m
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 CONFIG_8139TOO_8129=y
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 CONFIG_SIS900=m
-CONFIG_SIS900_OLD=m
 CONFIG_EPIC100=m
 CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
 CONFIG_TLAN=m
+CONFIG_TC35815=m
 CONFIG_VIA_RHINE=m
 # CONFIG_VIA_RHINE_MMIO is not set
 CONFIG_WINBOND_840=m
@@ -778,14 +756,14 @@ CONFIG_DE620=m
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 CONFIG_DL2K=m
+CONFIG_E1000=m
 # CONFIG_MYRI_SBUS is not set
 CONFIG_NS83820=m
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
 CONFIG_SK98LIN=m
-CONFIG_NET_BROADCOM=m
 CONFIG_TIGON3=m
-CONFIG_NET_E1000=m
 CONFIG_FDDI=y
 CONFIG_DEFXX=m
 CONFIG_SKFP=m
@@ -799,7 +777,7 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 # CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
+CONFIG_PPPOE=m
 CONFIG_PPPOATM=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
@@ -856,7 +834,6 @@ CONFIG_HOSTESS_SV11=m
 CONFIG_COSA=m
 # CONFIG_COMX is not set
 # CONFIG_DSCC4 is not set
-CONFIG_FARSYNC=m
 # CONFIG_LANMEDIA is not set
 CONFIG_ATI_XX20=m
 CONFIG_SEALEVEL_4021=m
@@ -903,25 +880,6 @@ CONFIG_PCMCIA_WAVELAN=m
 CONFIG_PCMCIA_WVLAN=m
 CONFIG_AIRONET4500_CS=m
 
-#
-# Quadrics Supercomputers
-#
-
-#
-# QsNet
-#
-CONFIG_QUADRICS=y
-CONFIG_QSNETMOD=m
-CONFIG_ELAN3MOD=m
-CONFIG_EPMOD=m
-CONFIG_EIPMOD=m
-CONFIG_RMSMOD=m
-CONFIG_JTAG=m
-
-#
-# QsNet II
-#
-
 #
 # ATM drivers
 #
@@ -1010,10 +968,14 @@ CONFIG_ACTISYS_DONGLE=m
 CONFIG_TEKRAM_DONGLE=m
 CONFIG_GIRBIL_DONGLE=m
 CONFIG_LITELINK_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
 CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+CONFIG_MA600_DONGLE=m
 CONFIG_USB_IRDA=m
 CONFIG_NSC_FIR=m
 CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_OLD=m
 CONFIG_TOSHIBA_FIR=m
 CONFIG_SMC_IRCC_FIR=m
 CONFIG_ALI_FIR=m
@@ -1052,37 +1014,39 @@ CONFIG_HISAX_NI1=y
 CONFIG_HISAX_MAX_CARDS=8
 CONFIG_HISAX_16_0=y
 CONFIG_HISAX_16_3=y
-CONFIG_HISAX_TELESPCI=y
-CONFIG_HISAX_S0BOX=y
 CONFIG_HISAX_AVM_A1=y
-CONFIG_HISAX_FRITZPCI=y
-CONFIG_HISAX_AVM_A1_PCMCIA=y
-CONFIG_HISAX_ELSA=y
 CONFIG_HISAX_IX1MICROR2=y
-CONFIG_HISAX_DIEHLDIVA=y
 CONFIG_HISAX_ASUSCOM=y
 CONFIG_HISAX_TELEINT=y
 CONFIG_HISAX_HFCS=y
-CONFIG_HISAX_SEDLBAUER=y
 CONFIG_HISAX_SPORTSTER=y
 CONFIG_HISAX_MIC=y
+CONFIG_HISAX_ISURF=y
+CONFIG_HISAX_HSTSAPHIR=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
 CONFIG_HISAX_NETJET=y
 CONFIG_HISAX_NETJET_U=y
 CONFIG_HISAX_NICCY=y
-CONFIG_HISAX_ISURF=y
-CONFIG_HISAX_HSTSAPHIR=y
 CONFIG_HISAX_BKM_A4T=y
 CONFIG_HISAX_SCT_QUADRO=y
 CONFIG_HISAX_GAZEL=y
 CONFIG_HISAX_HFC_PCI=y
 CONFIG_HISAX_W6692=y
 CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
 CONFIG_HISAX_DEBUG=y
 CONFIG_HISAX_SEDLBAUER_CS=m
 CONFIG_HISAX_ELSA_CS=m
 CONFIG_HISAX_AVM_A1_CS=m
 CONFIG_HISAX_ST5481=m
 CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_USB_AUERISDN=m
 
 #
 # Active ISDN cards
@@ -1133,10 +1097,8 @@ CONFIG_INPUT_EVDEV=m
 #
 # Character devices
 #
-CONFIG_ECC=m
-# CONFIG_CHAOSTEST is not set
-# CONFIG_P4THERM is not set
 CONFIG_VT=y
+CONFIG_ECC=m
 CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
@@ -1157,6 +1119,7 @@ CONFIG_MOXA_INTELLIO=m
 CONFIG_MOXA_SMARTIO=m
 CONFIG_ISI=m
 CONFIG_SYNCLINK=m
+# CONFIG_SYNCLINKMP is not set
 CONFIG_N_HDLC=m
 CONFIG_RISCOM8=m
 CONFIG_SPECIALIX=m
@@ -1167,10 +1130,11 @@ CONFIG_STALDRV=y
 CONFIG_STALLION=m
 CONFIG_ISTALLION=m
 CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=512
+CONFIG_UNIX98_PTY_COUNT=2048
 CONFIG_PRINTER=m
 CONFIG_LP_CONSOLE=y
 CONFIG_PPDEV=m
+CONFIG_TIPAR=m
 
 #
 # I2C support
@@ -1180,6 +1144,8 @@ CONFIG_I2C_ALGOBIT=m
 CONFIG_I2C_PHILIPSPAR=m
 CONFIG_I2C_ELV=m
 CONFIG_I2C_VELLEMAN=m
+# CONFIG_SCx200_I2C is not set
+# CONFIG_SCx200_ACB is not set
 CONFIG_I2C_ALGOPCF=m
 CONFIG_I2C_ELEKTOR=m
 CONFIG_I2C_MAINBOARD=y
@@ -1189,7 +1155,7 @@ CONFIG_I2C_HYDRA=m
 CONFIG_I2C_AMD756=m
 # CONFIG_I2C_TSUNAMI is not set
 CONFIG_I2C_I801=m
-CONFIG_I2C_I810=m
+# CONFIG_I2C_I810 is not set
 CONFIG_I2C_PIIX4=m
 CONFIG_I2C_SIS5595=m
 CONFIG_I2C_VIA=m
@@ -1219,15 +1185,21 @@ CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM78=m
 CONFIG_SENSORS_LM80=m
 CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM92=m
 CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
 CONFIG_SENSORS_THMC50=m
 CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
 CONFIG_SENSORS_W83781D=m
 CONFIG_SENSORS_OTHER=y
 CONFIG_SENSORS_BT869=m
 CONFIG_SENSORS_DDCMON=m
 CONFIG_SENSORS_EEPROM=m
 CONFIG_SENSORS_MATORB=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCF8591=m
 
 #
 # Mice
@@ -1273,6 +1245,11 @@ CONFIG_INPUT_DB9=m
 CONFIG_INPUT_GAMECON=m
 CONFIG_INPUT_TURBOGRAFX=m
 # CONFIG_QIC02_TAPE is not set
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_KCS=m
+CONFIG_IPMI_WATCHDOG=m
 
 #
 # Watchdog Cards
@@ -1291,6 +1268,7 @@ CONFIG_I810_TCO=m
 # CONFIG_MIXCOMWD is not set
 # CONFIG_60XX_WDT is not set
 CONFIG_SC1200_WDT=m
+# CONFIG_SCx200_WDT is not set
 CONFIG_SOFT_WATCHDOG=m
 CONFIG_W83877F_WDT=m
 CONFIG_WDT=m
@@ -1298,6 +1276,7 @@ CONFIG_WDTPCI=m
 # CONFIG_WDT_501 is not set
 CONFIG_MACHZ_WDT=m
 CONFIG_AMD7XX_TCO=m
+# CONFIG_SCx200_GPIO is not set
 CONFIG_AMD_RNG=m
 CONFIG_INTEL_RNG=m
 CONFIG_AMD_PM768=m
@@ -1333,10 +1312,21 @@ CONFIG_AGP_INTEL=y
 CONFIG_AGP_I810=y
 CONFIG_AGP_VIA=y
 CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD_8151=y
 CONFIG_AGP_SIS=y
 CONFIG_AGP_ALI=y
 CONFIG_AGP_SWORKS=y
-# CONFIG_DRM is not set
+CONFIG_DRM=y
+# CONFIG_DRM_OLD is not set
+CONFIG_DRM_NEW=y
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+# CONFIG_DRM_I810_XFREE_41 is not set
+CONFIG_DRM_I830=m
+CONFIG_DRM_MGA=m
+# CONFIG_DRM_SIS is not set
 
 #
 # PCMCIA character devices
@@ -1357,8 +1347,6 @@ CONFIG_VIDEO_DEV=m
 CONFIG_VIDEO_PROC_FS=y
 CONFIG_I2C_PARPORT=m
 CONFIG_VIDEO_BT848=m
-# CONFIG_VIDEO_LS220 is not set
-# CONFIG_VIDEO_MARGI is not set
 CONFIG_VIDEO_PMS=m
 CONFIG_VIDEO_BWQCAM=m
 CONFIG_VIDEO_CQCAM=m
@@ -1390,6 +1378,7 @@ CONFIG_RADIO_MAESTRO=m
 CONFIG_RADIO_MIROPCM20=m
 CONFIG_RADIO_MIROPCM20_RDS=m
 CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
 CONFIG_RADIO_TERRATEC=m
 CONFIG_RADIO_TRUST=m
 CONFIG_RADIO_TYPHOON=m
@@ -1406,13 +1395,16 @@ CONFIG_CRYPTO_BROADCOM=m
 # File systems
 #
 CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+# CONFIG_QIFACE_COMPAT is not set
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 CONFIG_REISERFS_PROC_INFO=y
 # CONFIG_ADFS_FS is not set
-# CONFIG_AFS_FS is not set
+CONFIG_AFS_FS=m
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 CONFIG_HFS_FS=m
@@ -1420,6 +1412,9 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_XATTR_SHARING=y
+CONFIG_EXT3_FS_XATTR_USER=y
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=m
@@ -1436,7 +1431,7 @@ CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_JFS_FS=m
-CONFIG_JFS_DEBUG=y
+# CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_MINIX_FS=m
 CONFIG_VXFS_FS=m
@@ -1452,6 +1447,9 @@ CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_RW is not set
 CONFIG_ROMFS_FS=m
 CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_XATTR_SHARING=y
+CONFIG_EXT2_FS_XATTR_USER=y
 CONFIG_SYSV_FS=m
 CONFIG_UDF_FS=m
 CONFIG_UDF_RW=y
@@ -1483,8 +1481,8 @@ CONFIG_NCPFS_OS2_NS=y
 CONFIG_NCPFS_SMALLDOS=y
 CONFIG_NCPFS_NLS=y
 CONFIG_NCPFS_EXTRAS=y
-# CONFIG_PFS_FS is not set
 CONFIG_ZISOFS_FS=y
+CONFIG_FS_MBCACHE=y
 
 #
 # Partition Types
@@ -1504,6 +1502,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
 CONFIG_SMB_NLS=y
 CONFIG_NLS=y
 
@@ -1570,21 +1569,23 @@ CONFIG_FB_PM2_PCI=y
 CONFIG_FB_PM3=m
 # CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_VESA=y
-# CONFIG_FB_VGA16 is not set
+CONFIG_FB_VGA16=m
 CONFIG_FB_HGA=m
 CONFIG_VIDEO_SELECT=y
 CONFIG_FB_MATROX=m
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_FB_MATROX_G450 is not set
+CONFIG_FB_MATROX_G100A=y
 CONFIG_FB_MATROX_G100=y
 CONFIG_FB_MATROX_I2C=m
 CONFIG_FB_MATROX_MAVEN=m
-# CONFIG_FB_MATROX_G450 is not set
 # CONFIG_FB_MATROX_PROC is not set
 CONFIG_FB_MATROX_MULTIHEAD=y
 CONFIG_FB_ATY=m
 CONFIG_FB_ATY_GX=y
 CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_CT_VAIO_LCD=y
 CONFIG_FB_RADEON=m
 CONFIG_FB_ATY128=m
 CONFIG_FB_SIS=m
@@ -1601,30 +1602,18 @@ CONFIG_FBCON_CFB8=y
 CONFIG_FBCON_CFB16=y
 CONFIG_FBCON_CFB24=y
 CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_VGA_PLANES=m
 CONFIG_FBCON_HGA=m
 # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
 # CONFIG_FBCON_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-CONFIG_SPEAKUP=y
-CONFIG_SPEAKUP_ACNTSA=y
-CONFIG_SPEAKUP_ACNTPC=y
-CONFIG_SPEAKUP_APOLO=y
-CONFIG_SPEAKUP_AUDPTR=y
-CONFIG_SPEAKUP_BNS=y
-CONFIG_SPEAKUP_DECTLK=y
-CONFIG_SPEAKUP_DECEXT=y
-CONFIG_SPEAKUP_DTLK=y
-CONFIG_SPEAKUP_LTLK=y
-CONFIG_SPEAKUP_SPKOUT=y
-CONFIG_SPEAKUP_TXPRT=y
-CONFIG_SPEAKUP_DEFAULT="none"
-# CONFIG_SPEAKUP_KEYMAP is not set
 
 #
 # Sound
 #
 CONFIG_SOUND=m
+CONFIG_SOUND_ALI5455=m
 CONFIG_SOUND_BT878=m
 CONFIG_SOUND_CMPCI=m
 CONFIG_SOUND_CMPCI_FM=y
@@ -1647,6 +1636,7 @@ CONFIG_SOUND_ES1371=m
 CONFIG_SOUND_ESSSOLO1=m
 CONFIG_SOUND_MAESTRO=m
 CONFIG_SOUND_MAESTRO3=m
+CONFIG_SOUND_FORTE=m
 CONFIG_SOUND_ICH=m
 CONFIG_SOUND_RME96XX=m
 CONFIG_SOUND_SONICVIBES=m
@@ -1665,6 +1655,7 @@ CONFIG_SOUND_OSS=m
 # CONFIG_SOUND_TRACEINIT is not set
 CONFIG_SOUND_DMAP=y
 CONFIG_SOUND_AD1816=m
+CONFIG_SOUND_AD1889=m
 CONFIG_SOUND_SGALAXY=m
 CONFIG_SOUND_ADLIB=m
 CONFIG_SOUND_ACI_MIXER=m
@@ -1687,6 +1678,7 @@ CONFIG_SOUND_PSS=m
 # CONFIG_PSS_HAVE_BOOT is not set
 CONFIG_SOUND_SB=m
 CONFIG_SOUND_AWE32_SYNTH=m
+CONFIG_SOUND_KAHLUA=m
 CONFIG_SOUND_WAVEFRONT=m
 CONFIG_SOUND_MAUI=m
 CONFIG_SOUND_YM3812=m
@@ -1711,14 +1703,13 @@ CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
-CONFIG_USB_LONG_TIMEOUT=y
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_UHCI=m
 CONFIG_USB_UHCI_ALT=m
 CONFIG_USB_OHCI=m
 CONFIG_USB_AUDIO=m
 # CONFIG_USB_EMI26 is not set
-CONFIG_USB_BLUETOOTH=m
+CONFIG_USB_MIDI=m
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 CONFIG_USB_STORAGE_DATAFAB=y
@@ -1727,6 +1718,7 @@ CONFIG_USB_STORAGE_ISD200=y
 CONFIG_USB_STORAGE_DPCM=y
 CONFIG_USB_STORAGE_HP8200e=y
 CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
@@ -1735,13 +1727,17 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_KBD is not set
 # CONFIG_USB_MOUSE is not set
+CONFIG_USB_AIPTEK=m
 CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
 # CONFIG_USB_DC2XX is not set
 CONFIG_USB_MDC800=m
 CONFIG_USB_SCANNER=m
 CONFIG_USB_MICROTEK=m
 CONFIG_USB_HPUSBSCSI=m
 CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
 CONFIG_USB_OV511=m
 CONFIG_USB_PWC=m
 CONFIG_USB_SE401=m
@@ -1761,6 +1757,7 @@ CONFIG_USB_USS720=m
 # USB Serial Converter support
 #
 CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_DEBUG is not set
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
@@ -1771,6 +1768,7 @@ CONFIG_USB_SERIAL_VISOR=m
 CONFIG_USB_SERIAL_IPAQ=m
 CONFIG_USB_SERIAL_IR=m
 CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
@@ -1779,20 +1777,35 @@ CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
 CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
 # CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
 CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 CONFIG_USB_SERIAL_OMNINET=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_AUERSWALD=m
+CONFIG_USB_TIGL=m
 CONFIG_USB_BRLVGER=m
-CONFIG_USB_USBLCD=m
+CONFIG_USB_LCD=m
+
+#
+# Additional device driver support
+#
+CONFIG_NET_BROADCOM=m
+CONFIG_CIPE=m
+CONFIG_CRYPTO_AEP=m
+CONFIG_MEGARAC=m
+CONFIG_FC_QLA2200=m
+CONFIG_FC_QLA2300=m
+CONFIG_SCSI_ISCSI=m
 
 #
 # Bluetooth support
@@ -1800,32 +1813,46 @@ CONFIG_USB_USBLCD=m
 CONFIG_BLUEZ=m
 CONFIG_BLUEZ_L2CAP=m
 CONFIG_BLUEZ_SCO=m
+CONFIG_BLUEZ_RFCOMM=m
+CONFIG_BLUEZ_RFCOMM_TTY=y
+CONFIG_BLUEZ_BNEP=m
+CONFIG_BLUEZ_BNEP_MC_FILTER=y
+CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
 
 #
 # Bluetooth device drivers
 #
 CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_USB_FW_LOAD=y
+CONFIG_BLUEZ_USB_SCO=y
 CONFIG_BLUEZ_USB_ZERO_PACKET=y
 CONFIG_BLUEZ_HCIUART=m
 CONFIG_BLUEZ_HCIUART_H4=y
+CONFIG_BLUEZ_HCIUART_BCSP=y
+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
 CONFIG_BLUEZ_HCIDTL1=m
+CONFIG_BLUEZ_HCIBT3C=m
+CONFIG_BLUEZ_HCIBLUECARD=m
+CONFIG_BLUEZ_HCIBTUART=m
 CONFIG_BLUEZ_HCIVHCI=m
 
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
 #
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_STACK_TRACE_SCAN is not set
-CONFIG_STACK_TRACE_PARAM_COUNT=4
+CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_HIGHMEM is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_IOVIRT is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_FRAME_POINTER is not set
 # CONFIG_MCL_COREDUMP is not set
-# CONFIG_OPROFILE is not set
 
 #
 # Library routines
diff --git a/lustre/kernel_patches/kernel_configs/kgdb-2.6.0-test6 b/lustre/kernel_patches/kernel_configs/kgdb-2.6.0-test6
deleted file mode 100644
index 201de2cdb0d59718cd3cae6e637039319eb6dfb5..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/kernel_configs/kgdb-2.6.0-test6
+++ /dev/null
@@ -1,1209 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_X86=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_GENERIC_ISA_DMA=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Processor type and features
-#
-CONFIG_X86_PC=y
-# CONFIG_X86_VOYAGER is not set
-# CONFIG_X86_NUMAQ is not set
-# CONFIG_X86_SUMMIT is not set
-# CONFIG_X86_BIGSMP is not set
-# CONFIG_X86_VISWS is not set
-# CONFIG_X86_GENERICARCH is not set
-# CONFIG_X86_ES7000 is not set
-# CONFIG_M386 is not set
-# CONFIG_M486 is not set
-# CONFIG_M586 is not set
-# CONFIG_M586TSC is not set
-# CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
-# CONFIG_MPENTIUMII is not set
-# CONFIG_MPENTIUMIII is not set
-CONFIG_MPENTIUM4=y
-# CONFIG_MK6 is not set
-# CONFIG_MK7 is not set
-# CONFIG_MK8 is not set
-# CONFIG_MELAN is not set
-# CONFIG_MCRUSOE is not set
-# CONFIG_MWINCHIPC6 is not set
-# CONFIG_MWINCHIP2 is not set
-# CONFIG_MWINCHIP3D is not set
-# CONFIG_MCYRIXIII is not set
-# CONFIG_MVIAC3_2 is not set
-# CONFIG_X86_GENERIC is not set
-CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
-CONFIG_X86_L1_CACHE_SHIFT=7
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INVLPG=y
-CONFIG_X86_BSWAP=y
-CONFIG_X86_POPAD_OK=y
-CONFIG_X86_GOOD_APIC=y
-CONFIG_X86_INTEL_USERCOPY=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-# CONFIG_X86_4G is not set
-# CONFIG_X86_SWITCH_PAGETABLES is not set
-# CONFIG_X86_4G_VM_LAYOUT is not set
-# CONFIG_X86_UACCESS_INDIRECT is not set
-# CONFIG_X86_HIGH_ENTRY is not set
-# CONFIG_HPET_TIMER is not set
-# CONFIG_HPET_EMULATE_RTC is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=8
-CONFIG_PREEMPT=y
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
-CONFIG_X86_TSC=y
-CONFIG_X86_MCE=y
-CONFIG_X86_MCE_NONFATAL=y
-CONFIG_X86_MCE_P4THERMAL=y
-# CONFIG_TOSHIBA is not set
-# CONFIG_I8K is not set
-# CONFIG_MICROCODE is not set
-# CONFIG_X86_MSR is not set
-# CONFIG_X86_CPUID is not set
-# CONFIG_EDD is not set
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
-# CONFIG_HIGHMEM64G is not set
-# CONFIG_MATH_EMULATION is not set
-CONFIG_MTRR=y
-CONFIG_HAVE_DEC_LOCK=y
-CONFIG_BOOT_IOREMAP=y
-# CONFIG_KEXEC is not set
-
-#
-# Power management options (ACPI, APM)
-#
-CONFIG_PM=y
-CONFIG_SOFTWARE_SUSPEND=y
-# CONFIG_PM_DISK is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_SLEEP_PROC_FS=y
-CONFIG_ACPI_AC=y
-CONFIG_ACPI_BATTERY=y
-CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_FAN=y
-CONFIG_ACPI_PROCESSOR=y
-CONFIG_ACPI_THERMAL=y
-# CONFIG_ACPI_ASUS is not set
-# CONFIG_ACPI_TOSHIBA is not set
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
-CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_EFI is not set
-# CONFIG_ACPI_RELAXED_AML is not set
-
-#
-# APM (Advanced Power Management) BIOS Support
-#
-# CONFIG_APM is not set
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-CONFIG_PCI=y
-# CONFIG_PCI_GOBIOS is not set
-# CONFIG_PCI_GODIRECT is not set
-CONFIG_PCI_GOANY=y
-CONFIG_PCI_BIOS=y
-CONFIG_PCI_DIRECT=y
-# CONFIG_PCI_USE_VECTOR is not set
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
-CONFIG_ISA=y
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SCx200 is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-CONFIG_PCMCIA_PROBE=y
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
-
-#
-# Generic Driver Options
-#
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_LBD=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_TASKFILE_IO=y
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_BLK_DEV_CMD640=y
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_RZ1000=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SGIIOC4 is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_MAX_SD_DISKS=256
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA2XXX is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
-
-#
-# Device Drivers
-#
-
-#
-# Texas Instruments PCILynx requires I2C bit-banging
-#
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocol Drivers
-#
-# CONFIG_IEEE1394_VIDEO1394 is not set
-# CONFIG_IEEE1394_SBP2 is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-# CONFIG_IEEE1394_DV1394 is not set
-# CONFIG_IEEE1394_RAWIO is not set
-# CONFIG_IEEE1394_CMP is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-CONFIG_E1000=m
-# CONFIG_E1000_NAPI is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SK98LIN is not set
-CONFIG_TIGON3=y
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-CONFIG_NET_POLL_CONTROLLER=y
-CONFIG_NETCONSOLE=y
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-CONFIG_NETPOLL=y
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN_BOOL is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_PS2_SYNAPTICS is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_ACPI is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_PRINTER=y
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
-# CONFIG_TIPAR is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# I2C Algorithms
-#
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-CONFIG_AGP=y
-# CONFIG_AGP_ALI is not set
-# CONFIG_AGP_ATI is not set
-# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_AMD64 is not set
-CONFIG_AGP_INTEL=y
-# CONFIG_AGP_NVIDIA is not set
-# CONFIG_AGP_SIS is not set
-# CONFIG_AGP_SWORKS is not set
-# CONFIG_AGP_VIA is not set
-CONFIG_DRM=y
-# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
-# CONFIG_DRM_R128 is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_I810 is not set
-CONFIG_DRM_I830=y
-# CONFIG_DRM_MGA is not set
-# CONFIG_DRM_SIS is not set
-# CONFIG_MWAVE is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_NFS_DIRECTIO=y
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-CONFIG_LUSTRE_FS=y
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_VESA is not set
-CONFIG_VIDEO_SELECT=y
-# CONFIG_FB_HGA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_I810 is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-CONFIG_FB_VIRTUAL=y
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-# CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ISA devices
-#
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4232 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SSCAPE is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-CONFIG_SND_INTEL8X0=y
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VX222 is not set
-
-#
-# ALSA USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_OHCI_HCD is not set
-CONFIG_USB_UHCI_HCD=y
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=y
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_XPAD is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_BRLVGER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-CONFIG_CRASH_DUMP=y
-CONFIG_CRASH_DUMP_BLOCKDEV=y
-CONFIG_CRASH_DUMP_NETDEV=y
-CONFIG_CRASH_DUMP_MEMDEV=y
-CONFIG_CRASH_DUMP_SOFTBOOT=y
-CONFIG_CRASH_DUMP_COMPRESS_RLE=y
-CONFIG_CRASH_DUMP_COMPRESS_GZIP=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_IOVIRT is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_SPINLOCK=y
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_SPINLINE is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_KGDB=y
-# CONFIG_KGDB_9600BAUD is not set
-# CONFIG_KGDB_19200BAUD is not set
-# CONFIG_KGDB_38400BAUD is not set
-# CONFIG_KGDB_57600BAUD is not set
-CONFIG_KGDB_115200BAUD=y
-CONFIG_KGDB_PORT=0x3f8
-CONFIG_KGDB_IRQ=4
-# CONFIG_KGDB_MORE is not set
-CONFIG_NO_KGDB_CPUS=8
-# CONFIG_KGDB_TS is not set
-# CONFIG_STACK_OVERFLOW_TEST is not set
-# CONFIG_KGDB_CONSOLE is not set
-CONFIG_KGDB_SYSRQ=y
-CONFIG_FRAME_POINTER=y
-CONFIG_X86_EXTRA_IRQS=y
-CONFIG_X86_FIND_SMP_CONFIG=y
-CONFIG_X86_MPPARSE=y
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
-CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_PC=y
diff --git a/lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73 b/lustre/kernel_patches/kernel_configs/kgdb_2.6.0_test1_vmware.config
similarity index 98%
rename from lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73
rename to lustre/kernel_patches/kernel_configs/kgdb_2.6.0_test1_vmware.config
index 4033739d41fc78da5f119def573777759fc35b5d..000cdc2c9eb65b4d595072de41bd2f5f0796a749 100644
--- a/lustre/kernel_patches/kernel_configs/kgdb-vmware-2.5.73
+++ b/lustre/kernel_patches/kernel_configs/kgdb_2.6.0_test1_vmware.config
@@ -20,6 +20,7 @@ CONFIG_SYSVIPC=y
 CONFIG_SYSCTL=y
 CONFIG_LOG_BUF_SHIFT=15
 # CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 
@@ -192,6 +193,7 @@ CONFIG_PNP_NAMES=y
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
@@ -335,6 +337,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA2XXX is not set
 # CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -344,6 +347,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_FERAL_ISP is not set
 
 #
 # PCMCIA SCSI adapter support
@@ -759,6 +763,7 @@ CONFIG_RAMFS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
+CONFIG_NFS_DIRECTIO=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 # CONFIG_EXPORTFS is not set
@@ -859,14 +864,15 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
-# CONFIG_CRASH_DUMP is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_IOVIRT is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_SPINLOCK=y
-CONFIG_KALLSYMS=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_SPINLINE is not set
+# CONFIG_LOCKMETER is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_KGDB=y
 # CONFIG_KGDB_9600BAUD is not set
diff --git a/lustre/kernel_patches/kernel_configs/jdike-2.5.69-uml.config b/lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config
similarity index 91%
rename from lustre/kernel_patches/kernel_configs/jdike-2.5.69-uml.config
rename to lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config
index 4aa8a2ca9da87fedd342f9857e44c8f8489a7a2e..f93318805c6abcfcbb0e26fce9f84744e79c94da 100644
--- a/lustre/kernel_patches/kernel_configs/jdike-2.5.69-uml.config
+++ b/lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config
@@ -6,6 +6,27 @@ CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 
+#
+# UML-specific options
+#
+CONFIG_MODE_TT=y
+# CONFIG_MODE_SKAS is not set
+CONFIG_NET=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_HOSTFS=y
+# CONFIG_HPPFS is not set
+CONFIG_MCONSOLE=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_HOST_2G_2G is not set
+# CONFIG_UML_SMP is not set
+# CONFIG_SMP is not set
+CONFIG_NEST_LEVEL=0
+CONFIG_KERNEL_HALF_GIGS=1
+# CONFIG_HIGHMEM is not set
+# CONFIG_PROC_MM is not set
+CONFIG_KERNEL_STACK_ORDER=2
+
 #
 # Code maturity level options
 #
@@ -19,6 +40,12 @@ CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
 
 #
 # Loadable module support
@@ -26,30 +53,9 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_MODULES is not set
 
 #
-# UML-specific options
-#
-CONFIG_MODE_TT=y
-# CONFIG_MODE_SKAS is not set
-CONFIG_NET=y
-CONFIG_HOSTFS=y
-# CONFIG_HPPFS is not set
-CONFIG_MCONSOLE=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_HOST_2G_2G is not set
-# CONFIG_UML_SMP is not set
-# CONFIG_SMP is not set
-CONFIG_NEST_LEVEL=0
-CONFIG_KERNEL_HALF_GIGS=1
-# CONFIG_HIGHMEM is not set
-# CONFIG_PROC_MM is not set
-CONFIG_KERNEL_STACK_ORDER=3
-
-#
-# Executable file formats
+# Generic Driver Options
 #
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Character Devices
@@ -77,12 +83,25 @@ CONFIG_UNIX98_PTY_COUNT=256
 #
 CONFIG_BLK_DEV_UBD=y
 # CONFIG_BLK_DEV_UBD_SYNC is not set
+CONFIG_BLK_DEV_COW_COMMON=y
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_MMAPPER is not set
 CONFIG_NETDEVICES=y
 
+#
+# UML Network Devices
+#
+CONFIG_UML_NET=y
+CONFIG_UML_NET_ETHERTAP=y
+CONFIG_UML_NET_TUNTAP=y
+CONFIG_UML_NET_SLIP=y
+CONFIG_UML_NET_DAEMON=y
+CONFIG_UML_NET_MCAST=y
+# CONFIG_UML_NET_PCAP is not set
+# CONFIG_UML_NET_SLIRP is not set
+
 #
 # Networking support
 #
@@ -93,7 +112,6 @@ CONFIG_NETDEVICES=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -109,6 +127,9 @@ CONFIG_INET=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_XFRM_USER is not set
 
 #
@@ -119,8 +140,6 @@ CONFIG_IPV6_SCTP__=y
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_NET_DIVERT is not set
@@ -184,18 +203,6 @@ CONFIG_SLIP=y
 #
 # CONFIG_WAN is not set
 
-#
-# UML Network Devices
-#
-CONFIG_UML_NET=y
-CONFIG_UML_NET_ETHERTAP=y
-CONFIG_UML_NET_TUNTAP=y
-CONFIG_UML_NET_SLIP=y
-CONFIG_UML_NET_DAEMON=y
-CONFIG_UML_NET_MCAST=y
-# CONFIG_UML_NET_PCAP is not set
-# CONFIG_UML_NET_SLIRP is not set
-
 #
 # File systems
 #
@@ -204,22 +211,18 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
-CONFIG_QUOTA=y
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
-CONFIG_QUOTACTL=y
+# CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
+# CONFIG_AUTOFS4_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -241,6 +244,7 @@ CONFIG_DEVFS_FS=y
 CONFIG_DEVFS_MOUNT=y
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 CONFIG_RAMFS=y
 
@@ -292,7 +296,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Library routines
 #
-CONFIG_CRC32=y
+# CONFIG_CRC32 is not set
 
 #
 # SCSI support
@@ -313,8 +317,8 @@ CONFIG_CRC32=y
 # Kernel hacking
 #
 CONFIG_DEBUG_SLAB=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUGSYM=y
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_INFO=y
 CONFIG_FRAME_POINTER=y
 CONFIG_PT_PROXY=y
 # CONFIG_GPROF is not set
diff --git a/lustre/kernel_patches/patches/2.6.0-test1-mm2.patch b/lustre/kernel_patches/patches/2.6.0-test1-mm2.patch
deleted file mode 100644
index 9f476e05b64853d2ad8818eadbea286f36fc7537..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/2.6.0-test1-mm2.patch
+++ /dev/null
@@ -1,179799 +0,0 @@
---- linux-2.6.0-test1/arch/alpha/kernel/irq.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/alpha/kernel/irq.c	2003-07-19 17:03:49.000000000 -0700
-@@ -601,7 +601,7 @@ handle_irq(int irq, struct pt_regs * reg
- 	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
- 		irq_err_count++;
- 		illegal_count++;
--		printk(KERN_CRIT "device_interrupt: illegal interrupt %d\n",
-+		printk(KERN_CRIT "device_interrupt: invalid interrupt %d\n",
- 		       irq);
- 		return;
- 	}
---- linux-2.6.0-test1/arch/alpha/kernel/smp.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/arch/alpha/kernel/smp.c	2003-07-19 17:04:06.000000000 -0700
-@@ -71,7 +71,7 @@ static int smp_secondary_alive __initdat
- 
- /* Which cpus ids came online.  */
- unsigned long cpu_present_mask;
--volatile unsigned long cpu_online_map;
-+cpumask_t cpu_online_map;
- 
- /* cpus reported in the hwrpb */
- static unsigned long hwrpb_cpu_present_mask __initdata = 0;
-@@ -132,7 +132,7 @@ smp_callin(void)
- {
- 	int cpuid = hard_smp_processor_id();
- 
--	if (test_and_set_bit(cpuid, &cpu_online_map)) {
-+	if (cpu_test_and_set(cpuid, cpu_online_map)) {
- 		printk("??, cpu 0x%x already present??\n", cpuid);
- 		BUG();
- 	}
-@@ -575,8 +575,8 @@ smp_prepare_boot_cpu(void)
- 	/*
- 	 * Mark the boot cpu (current cpu) as both present and online
- 	 */ 
--	set_bit(smp_processor_id(), &cpu_present_mask);
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_present_mask);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- }
- 
- int __devinit
---- linux-2.6.0-test1/arch/alpha/mm/init.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/alpha/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -20,9 +20,6 @@
- #include <linux/init.h>
- #include <linux/bootmem.h> /* max_low_pfn */
- #include <linux/vmalloc.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
--#endif
- 
- #include <asm/system.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/arch/alpha/mm/remap.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/arch/alpha/mm/remap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -73,7 +73,7 @@ __alpha_remap_area_pages(unsigned long a
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/arm26/kernel/setup.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/arm26/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -14,7 +14,7 @@
- #include <linux/ioport.h>
- #include <linux/delay.h>
- #include <linux/utsname.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/console.h>
- #include <linux/bootmem.h>
- #include <linux/seq_file.h>
---- linux-2.6.0-test1/arch/arm26/mm/init.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/arm26/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -22,7 +22,7 @@
- #include <linux/init.h>
- #include <linux/initrd.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <asm/segment.h>
- #include <asm/mach-types.h>
---- linux-2.6.0-test1/arch/arm26/mm/mm-memc.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/arm26/mm/mm-memc.c	2003-07-19 17:07:16.000000000 -0700
-@@ -79,7 +79,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 		goto no_pgd;
- 
- 	/*
--	 * This lock is here just to satisfy pmd_alloc and pte_lock
-+	 * This lock is here just to satisfy pmd_alloc_kernel() and pte_lock
-          * FIXME: I bet we could avoid taking it pretty much altogether
- 	 */
- 	spin_lock(&mm->page_table_lock);
-@@ -88,7 +88,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 	 * On ARM, first page must always be allocated since it contains
- 	 * the machine vectors.
- 	 */
--	new_pmd = pmd_alloc(mm, new_pgd, 0);
-+	new_pmd = pmd_alloc_kernel(mm, new_pgd, 0);
- 	if (!new_pmd)
- 		goto no_pmd;
- 
---- linux-2.6.0-test1/arch/arm/mach-arc/mm.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/arch/arm/mach-arc/mm.c	2003-07-19 17:07:16.000000000 -0700
-@@ -66,7 +66,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 		goto no_pgd;
- 
- 	/*
--	 * This lock is here just to satisfy pmd_alloc and pte_lock
-+	 * This lock is here just to satisfy pmd_alloc_map() and pte_lock
- 	 */
- 	spin_lock(&mm->page_table_lock);
- 
-@@ -74,13 +74,15 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 	 * On ARM, first page must always be allocated since it contains
- 	 * the machine vectors.
- 	 */
--	new_pmd = pmd_alloc(mm, new_pgd, 0);
-+	new_pmd = pmd_alloc_map(mm, new_pgd, 0);
- 	if (!new_pmd)
- 		goto no_pmd;
- 
--	new_pte = pte_alloc_map(mm, new_pmd, 0);
--	if (!new_pte)
-+	new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0);
-+	if (!new_pte) {
-+		pmd_unmap(new_pmd);
- 		goto no_pte;
-+	}
- 
- 	init_pgd = pgd_offset_k(0);
- 	init_pmd = pmd_offset(init_pgd, 0);
-@@ -88,6 +90,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 	set_pte(new_pte, *init_pte);
- 	pte_unmap_nested(init_pte);
- 	pte_unmap(new_pte);
-+	pmd_unmap(new_pmd);
- 
- 	/*
- 	 * most of the page table entries are zeroed
---- linux-2.6.0-test1/arch/arm/mach-clps711x/autcpu12.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/arch/arm/mach-clps711x/autcpu12.c	2003-07-19 17:03:49.000000000 -0700
-@@ -21,7 +21,6 @@
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/mm.h>
- 
- #include <asm/hardware.h>
---- linux-2.6.0-test1/arch/arm/mm/consistent.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/arm/mm/consistent.c	2003-07-19 17:07:16.000000000 -0700
-@@ -325,7 +325,7 @@ static int __init consistent_init(void)
- 
- 	do {
- 		pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
--		pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
-+		pmd = pmd_alloc_kernel(&init_mm, pgd, CONSISTENT_BASE);
- 		if (!pmd) {
- 			printk(KERN_ERR "consistent_init: out of pmd tables\n");
- 			return -ENOMEM;
---- linux-2.6.0-test1/arch/arm/mm/ioremap.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/arch/arm/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -95,7 +95,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/arm/mm/minicache.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/arch/arm/mm/minicache.c	2003-07-19 17:07:16.000000000 -0700
-@@ -57,7 +57,7 @@ static int __init minicache_init(void)
- 	pmd_t *pmd;
- 
- 	pgd = pgd_offset_k(minicache_address);
--	pmd = pmd_alloc(&init_mm, pgd, minicache_address);
-+	pmd = pmd_alloc_kernel(&init_mm, pgd, minicache_address);
- 	if (!pmd)
- 		BUG();
- 	minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
---- linux-2.6.0-test1/arch/arm/mm/mm-armv.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/arm/mm/mm-armv.c	2003-07-19 17:07:16.000000000 -0700
-@@ -131,7 +131,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 
- 	if (vectors_base() == 0) {
- 		/*
--		 * This lock is here just to satisfy pmd_alloc and pte_lock
-+		 * This lock is here just to satisfy pmd_alloc_map() and pte_lock
- 		 */
- 		spin_lock(&mm->page_table_lock);
- 
-@@ -139,20 +139,22 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
- 		 * On ARM, first page must always be allocated since it
- 		 * contains the machine vectors.
- 		 */
--		new_pmd = pmd_alloc(mm, new_pgd, 0);
-+		new_pmd = pmd_alloc_map(mm, new_pgd, 0);
- 		if (!new_pmd)
- 			goto no_pmd;
- 
--		new_pte = pte_alloc_map(mm, new_pmd, 0);
--		if (!new_pte)
-+		new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0);
-+		if (!new_pte) {
-+			pmd_unmap(new_pmd);
- 			goto no_pte;
-+		}
- 
- 		init_pmd = pmd_offset(init_pgd, 0);
- 		init_pte = pte_offset_map_nested(init_pmd, 0);
- 		set_pte(new_pte, *init_pte);
- 		pte_unmap_nested(init_pte);
- 		pte_unmap(new_pte);
--
-+		pmd_unmap(new_pmd);
- 		spin_unlock(&mm->page_table_lock);
- 	}
- 
---- linux-2.6.0-test1/arch/cris/mm/ioremap.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/cris/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -78,7 +78,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/h8300/kernel/setup.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/h8300/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -35,7 +35,6 @@
- #include <asm/irq.h>
- 
- #ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
- #include <asm/pgtable.h>
- #endif
- 
---- linux-2.6.0-test1/arch/h8300/mm/init.c	2003-06-14 12:18:21.000000000 -0700
-+++ 25/arch/h8300/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -23,9 +23,6 @@
- #include <linux/errno.h>
- #include <linux/string.h>
- #include <linux/types.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- #include <linux/ptrace.h>
- #include <linux/mman.h>
- #include <linux/mm.h>
---- linux-2.6.0-test1/arch/i386/Kconfig	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/i386/Kconfig	2003-07-19 17:07:16.000000000 -0700
-@@ -438,9 +438,9 @@ config SMP
- 	  If you don't know what to do here, say N.
- 
- config NR_CPUS
--	int "Maximum number of CPUs (2-32)"
-+	int "Maximum number of CPUs (2-255)"
- 	depends on SMP
--	default "32"
-+	default "8"
- 	help
- 	  This allows you to specify the maximum number of CPUs which this
- 	  kernel will support.  The maximum supported value is 32 and the
-@@ -723,6 +723,16 @@ config HIGHPTE
- 	  low memory.  Setting this option will put user-space page table
- 	  entries in high memory.
- 
-+config HIGHPMD
-+	bool "Allocate 2nd-level pagetables from highmem"
-+	depends on HIGHMEM64G && HIGHPTE
-+	help
-+	  The VM uses one lowmem-allocated pmd entry for each pagetable
-+	  page of physical memory allocated, and preallocates them all
-+	  for 12KB of per-process lowmem overhead. For systems with
-+	  extreme amounts of highmem, this cannot be tolerated. Setting
-+	  this option will put userspace 2nd-level pagetables in highmem.
-+
- config MATH_EMULATION
- 	bool "Math emulation"
- 	---help---
-@@ -1347,6 +1357,15 @@ config DEBUG_PAGEALLOC
- 	  This results in a large slowdown, but helps to find certain types
- 	  of memory corruptions.
- 
-+config SPINLINE
-+	bool "Spinlock inlining"
-+	depends on DEBUG_KERNEL
-+	help
-+	  This will change spinlocks from out of line to inline, making them
-+	  account cost to the callers in readprofile, rather than the lock
-+	  itself (as ".text.lock.filename"). This can be helpful for finding
-+	  the callers of locks.
-+
- config DEBUG_HIGHMEM
- 	bool "Highmem debugging"
- 	depends on DEBUG_KERNEL && HIGHMEM
-@@ -1354,20 +1373,207 @@ config DEBUG_HIGHMEM
- 	  This options enables addition error checking for high memory systems.
- 	  Disable for production systems.
- 
-+config LOCKMETER
-+	bool "Kernel lock metering"
-+	depends on SMP && !PREEMPT
-+	help
-+	  Say Y to enable kernel lock metering, which adds overhead to SMP locks,
-+	  but allows you to see various statistics using the lockstat command.
-+
- config DEBUG_SPINLOCK_SLEEP
- 	bool "Sleep-inside-spinlock checking"
- 	help
- 	  If you say Y here, various routines which may sleep will become very
- 	  noisy if they are called with a spinlock held.	
- 
-+config KGDB
-+	bool "Include kgdb kernel debugger"
-+	depends on DEBUG_KERNEL
-+	help  
-+	  If you say Y here, the system will be compiled with the debug
-+	  option (-g) and a debugging stub will be included in the
-+	  kernel.  This stub communicates with gdb on another (host)
-+	  computer via a serial port.  The host computer should have
-+	  access to the kernel binary file (vmlinux) and a serial port
-+	  that is connected to the target machine.  Gdb can be made to
-+	  configure the serial port or you can use stty and setserial to
-+	  do this. See the 'target' command in gdb. This option also
-+	  configures in the ability to request a breakpoint early in the
-+	  boot process.  To request the breakpoint just include 'kgdb'
-+	  as a boot option when booting the target machine.  The system
-+	  will then break as soon as it looks at the boot options.  This
-+	  option also installs a breakpoint in panic and sends any
-+	  kernel faults to the debugger. For more information see the
-+	  Documentation/i386/kgdb.txt file.
-+
-+choice
-+	depends on KGDB
-+    	prompt "Debug serial port BAUD" 
-+	default KGDB_115200BAUD
-+	help  
-+	  Gdb and the kernel stub need to agree on the baud rate to be
-+	  used.  Some systems (x86 family at this writing) allow this to
-+	  be configured.
-+
-+config KGDB_9600BAUD
-+	bool "9600"
-+
-+config KGDB_19200BAUD
-+	bool "19200"
-+
-+config KGDB_38400BAUD
-+	bool "38400"
-+
-+config KGDB_57600BAUD
-+	bool "57600"
-+
-+config KGDB_115200BAUD
-+	bool "115200"
-+endchoice
-+
-+config KGDB_PORT
-+	hex "hex I/O port address of the debug serial port"
-+	depends on KGDB
-+	default  3f8
-+	help  
-+	  Some systems (x86 family at this writing) allow the port
-+	  address to be configured.  The number entered is assumed to be
-+	  hex, don't put 0x in front of it.  The standard address are:
-+	  COM1 3f8 , irq 4 and COM2 2f8 irq 3.  Setserial /dev/ttySx
-+	  will tell you what you have.  It is good to test the serial
-+	  connection with a live system before trying to debug.
-+
-+config KGDB_IRQ
-+	int "IRQ of the debug serial port"
-+	depends on KGDB
-+	default 4
-+	help  
-+	  This is the irq for the debug port.  If everything is working
-+	  correctly and the kernel has interrupts on a control C to the
-+	  port should cause a break into the kernel debug stub.
-+
-+config DEBUG_INFO
-+	bool
-+	default y
-+
-+config KGDB_MORE
-+	bool "Add any additional compile options"
-+	depends on KGDB
-+	default n
-+	help  
-+	  Saying yes here turns on the ability to enter additional
-+	  compile options.
-+
-+
-+config KGDB_OPTIONS
-+	depends on KGDB_MORE
-+	string "Additional compile arguments"
-+	default "-O1"
-+	help  
-+	  This option allows you enter additional compile options for
-+	  the whole kernel compile.  Each platform will have a default
-+	  that seems right for it.  For example on PPC "-ggdb -O1", and
-+	  for i386 "-O1".  Note that by configuring KGDB "-g" is already
-+	  turned on.  In addition, on i386 platforms
-+	  "-fomit-frame-pointer" is deleted from the standard compile
-+	  options.
-+
-+config NO_KGDB_CPUS
-+	int "Number of CPUs"
-+	depends on KGDB && SMP
-+	default NR_CPUS
-+	help
-+	  
-+	  This option sets the number of cpus for kgdb ONLY.  It is used
-+	  to prune some internal structures so they look "nice" when
-+	  displayed with gdb.  This is to overcome possibly larger
-+	  numbers that may have been entered above.  Enter the real
-+	  number to get nice clean kgdb_info displays.
-+
-+config KGDB_TS
-+	bool "Enable kgdb time stamp macros?"
-+	depends on KGDB
-+	default n
-+	help	  
-+	  Kgdb event macros allow you to instrument your code with calls
-+	  to the kgdb event recording function.  The event log may be
-+	  examined with gdb at a break point.  Turning on this
-+	  capability also allows you to choose how many events to
-+	  keep. Kgdb always keeps the lastest events.
-+
-+choice 
-+	depends on KGDB_TS
-+	prompt "Max number of time stamps to save?"
-+	default KGDB_TS_128
-+
-+config KGDB_TS_64
-+	bool "64"
-+
-+config KGDB_TS_128
-+	bool "128"
-+
-+config KGDB_TS_256
-+	bool "256"
-+
-+config KGDB_TS_512
-+	bool "512"
-+
-+config KGDB_TS_1024
-+	bool "1024"
-+
-+endchoice
-+
-+config STACK_OVERFLOW_TEST
-+	bool "Turn on kernel stack overflow testing?"
-+	depends on KGDB
-+	default n
-+	help  
-+	  This option enables code in the front line interrupt handlers
-+	  to check for kernel stack overflow on interrupts and system
-+	  calls.  This is part of the kgdb code on x86 systems.
-+
-+config KGDB_CONSOLE
-+	bool "Enable serial console thru kgdb port"
-+	depends on KGDB
-+	default n
-+	help
-+	  This option enables the command line "console=kgdb" option.
-+	  When the system is booted with this option in the command line
-+	  all kernel printk output is sent to gdb (as well as to other
-+	  consoles).  For this to work gdb must be connected.  For this
-+	  reason, this command line option will generate a breakpoint if
-+	  gdb has not yet connected.  After the gdb continue command is
-+	  given all pent up console output will be printed by gdb on the
-+	  host machine.  Neither this option, nor KGDB require the
-+	  serial driver to be configured.
-+
-+config KGDB_SYSRQ
-+	bool "Turn on SysRq 'G' command to do a break?"
-+	depends on KGDB
-+	default y
-+	help
-+	  This option includes an option in the SysRq code that allows
-+	  you to enter SysRq G which generates a breakpoint to the KGDB
-+	  stub.  This will work if the keyboard is alive and can
-+	  interrupt the system.  Because of constraints on when the
-+	  serial port interrupt can be enabled, this code may allow you
-+	  to interrupt the system before the serial port control C is
-+	  available.  Just say yes here.
-+
- config FRAME_POINTER
- 	bool "Compile the kernel with frame pointers"
-+	default KGDB
- 	help
- 	  If you say Y here the resulting kernel image will be slightly larger
- 	  and slower, but it will give very useful debugging information.
- 	  If you don't debug the kernel, you can say N, but we may not be able
- 	  to solve problems without frame pointers.
- 
-+config MAGIC_SYSRQ
-+	bool
-+	depends on KGDB_SYSRQ
-+	default y
-+
- config X86_EXTRA_IRQS
- 	bool
- 	depends on X86_LOCAL_APIC || X86_VOYAGER
---- linux-2.6.0-test1/arch/i386/kernel/apic.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/i386/kernel/apic.c	2003-07-19 17:04:06.000000000 -0700
-@@ -1137,7 +1137,7 @@ int __init APIC_init_uniprocessor (void)
- 
- 	connect_bsp_APIC();
- 
--	phys_cpu_present_map = 1 << boot_cpu_physical_apicid;
-+	phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
- 
- 	setup_local_APIC();
- 
---- linux-2.6.0-test1/arch/i386/kernel/apm.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/arch/i386/kernel/apm.c	2003-07-19 17:04:06.000000000 -0700
-@@ -508,16 +508,16 @@ static void apm_error(char *str, int err
-  
- #ifdef CONFIG_SMP
- 
--static unsigned long apm_save_cpus(void)
-+static cpumask_t apm_save_cpus(void)
- {
--	unsigned long x = current->cpus_allowed;
-+	cpumask_t x = current->cpus_allowed;
- 	/* Some bioses don't like being called from CPU != 0 */
--	set_cpus_allowed(current, 1UL << 0);
-+	set_cpus_allowed(current, cpumask_of_cpu(0));
- 	BUG_ON(smp_processor_id() != 0);
- 	return x;
- }
- 
--static inline void apm_restore_cpus(unsigned long mask)
-+static inline void apm_restore_cpus(cpumask_t mask)
- {
- 	set_cpus_allowed(current, mask);
- }
-@@ -528,7 +528,7 @@ static inline void apm_restore_cpus(unsi
-  *	No CPU lockdown needed on a uniprocessor
-  */
-  
--#define apm_save_cpus()	0
-+#define apm_save_cpus()		(current->cpus_allowed)
- #define apm_restore_cpus(x)	(void)(x)
- 
- #endif
-@@ -593,7 +593,7 @@ static u8 apm_bios_call(u32 func, u32 eb
- {
- 	APM_DECL_SEGS
- 	unsigned long		flags;
--	unsigned long		cpus;
-+	cpumask_t		cpus;
- 	int			cpu;
- 	struct desc_struct	save_desc_40;
- 
-@@ -635,7 +635,7 @@ static u8 apm_bios_call_simple(u32 func,
- 	u8			error;
- 	APM_DECL_SEGS
- 	unsigned long		flags;
--	unsigned long		cpus;
-+	cpumask_t		cpus;
- 	int			cpu;
- 	struct desc_struct	save_desc_40;
- 
-@@ -913,7 +913,7 @@ static void apm_power_off(void)
- 	 */
- #ifdef CONFIG_SMP
- 	/* Some bioses don't like being called from CPU != 0 */
--	set_cpus_allowed(current, 1UL << 0);
-+	set_cpus_allowed(current, cpumask_of_cpu(0));
- 	BUG_ON(smp_processor_id() != 0);
- #endif
- 	if (apm_info.realmode_power_off)
-@@ -1704,7 +1704,7 @@ static int apm(void *unused)
- 	 * Some bioses don't like being called from CPU != 0.
- 	 * Method suggested by Ingo Molnar.
- 	 */
--	set_cpus_allowed(current, 1UL << 0);
-+	set_cpus_allowed(current, cpumask_of_cpu(0));
- 	BUG_ON(smp_processor_id() != 0);
- #endif
- 
---- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2003-07-19 17:04:06.000000000 -0700
-@@ -53,10 +53,9 @@ static int stock_freq;
- static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
- {
- 	u32 l, h;
--	unsigned long cpus_allowed;
-+	cpumask_t cpus_allowed, affected_cpu_map;
- 	struct cpufreq_freqs freqs;
- 	int hyperthreading = 0;
--	int affected_cpu_map = 0;
- 	int sibling = 0;
- 
- 	if (!cpu_online(cpu) || (newstate > DC_DISABLE) || 
-@@ -67,16 +66,16 @@ static int cpufreq_p4_setdc(unsigned int
- 	cpus_allowed = current->cpus_allowed;
- 
- 	/* only run on CPU to be set, or on its sibling */
--	affected_cpu_map = 1 << cpu;
-+       affected_cpu_map = cpumask_of_cpu(cpu);
- #ifdef CONFIG_X86_HT
- 	hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2));
- 	if (hyperthreading) {
- 		sibling = cpu_sibling_map[cpu];
--		affected_cpu_map |= (1 << sibling);
-+                cpu_set(sibling, affected_cpu_map);
- 	}
- #endif
- 	set_cpus_allowed(current, affected_cpu_map);
--	BUG_ON(!(affected_cpu_map & (1 << smp_processor_id())));
-+        BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map));
- 
- 	/* get current state */
- 	rdmsr(MSR_IA32_THERM_CONTROL, l, h);
---- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-07-19 17:05:02.000000000 -0700
-@@ -156,14 +156,15 @@ static struct cpufreq_frequency_table op
- };
- #undef OP
- 
--#define CPU(max)	\
--	{ "Intel(R) Pentium(R) M processor " #max "MHz", (max)*1000, op_##max }
-+#define _CPU(max, name)	\
-+	{ "Intel(R) Pentium(R) M processor " name "MHz", (max)*1000, op_##max }
-+#define CPU(max)	_CPU(max, #max)
- 
- /* CPU models, their operating frequency range, and freq/voltage
-    operating points */
- static const struct cpu_model models[] = 
- {
--	CPU( 900),
-+       _CPU( 900, " 900"),
- 	CPU(1100),
- 	CPU(1200),
- 	CPU(1300),
---- linux-2.6.0-test1/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2003-07-19 17:08:59.000000000 -0700
-@@ -77,15 +77,17 @@ static void speedstep_set_state (unsigne
- 	u8			value;
- 	unsigned long		flags;
- 	struct cpufreq_freqs	freqs;
-+	int			newfreq;
- 
- 	if (!speedstep_chipset_dev || (state > 0x1))
- 		return;
- 
- 	freqs.old = speedstep_get_processor_frequency(speedstep_processor);
--	freqs.new = speedstep_freqs[SPEEDSTEP_LOW].frequency;
-+	freqs.new = speedstep_freqs[state].frequency;
- 	freqs.cpu = 0; /* speedstep.c is UP only driver */
- 	
--	if (notify)
-+	/* make sure we've initialized before calling notify */
-+	if (notify && (freqs.new != 0))
- 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- 
- 	/* get PMBASE */
-@@ -136,13 +138,16 @@ static void speedstep_set_state (unsigne
- 
- 	dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
- 
-+	/* freqs.new may not be set yet - need local copy */
-+	newfreq = speedstep_get_processor_frequency(speedstep_processor);
- 	if (state == (value & 0x1)) {
--		dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (freqs.new / 1000));
-+		dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (newfreq / 1000));
- 	} else {
- 		printk (KERN_ERR "cpufreq: change failed - I/O error\n");
- 	}
- 
--	if (notify)
-+	/* Make sure we're initialized before calling notify */
-+	if (notify && (freqs.new != 0))
- 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- 
- 	return;
-@@ -295,7 +300,7 @@ static int speedstep_cpu_init(struct cpu
- 		return -EIO;
- 
- 	dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 
--		(speed == speedstep_low_freq) ? "low" : "high",
-+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
- 		(speed / 1000));
- 
- 	/* cpuinfo and default policy values */
---- linux-2.6.0-test1/arch/i386/kernel/cpuid.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/arch/i386/kernel/cpuid.c	2003-07-19 17:04:06.000000000 -0700
-@@ -136,7 +136,7 @@ static int cpuid_open(struct inode *inod
-   int cpu = minor(file->f_dentry->d_inode->i_rdev);
-   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
- 
--  if ( !(cpu_online_map & (1UL << cpu)) )
-+  if (!cpu_online(cpu))
-     return -ENXIO;		/* No such CPU */
-   if ( c->cpuid_level < 0 )
-     return -EIO;		/* CPUID not supported */
---- linux-2.6.0-test1/arch/i386/kernel/cpu/mtrr/cyrix.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/mtrr/cyrix.c	2003-07-19 17:03:49.000000000 -0700
-@@ -330,16 +330,16 @@ cyrix_arr_init(void)
- 	set_mtrr_done(&ctxt);	/* flush cache and disable MAPEN */
- 
- 	if (ccrc[5])
--		printk("mtrr: ARR usage was not enabled, enabled manually\n");
-+		printk(KERN_INFO "mtrr: ARR usage was not enabled, enabled manually\n");
- 	if (ccrc[3])
--		printk("mtrr: ARR3 cannot be changed\n");
-+		printk(KERN_INFO "mtrr: ARR3 cannot be changed\n");
- /*
-     if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n");
-     if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n");
-     if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n");
- */
- 	if (ccrc[6])
--		printk("mtrr: ARR3 was write protected, unprotected\n");
-+		printk(KERN_INFO "mtrr: ARR3 was write protected, unprotected\n");
- }
- 
- static struct mtrr_ops cyrix_mtrr_ops = {
---- linux-2.6.0-test1/arch/i386/kernel/cpu/mtrr/main.c	2003-06-26 22:07:22.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/mtrr/main.c	2003-07-19 17:04:57.000000000 -0700
-@@ -64,7 +64,7 @@ __initdata char *mtrr_if_name[] = {
- static void set_mtrr(unsigned int reg, unsigned long base,
- 		     unsigned long size, mtrr_type type);
- 
--static unsigned int arr3_protected;
-+extern int arr3_protected;
- 
- void set_mtrr_ops(struct mtrr_ops * ops)
- {
-@@ -75,23 +75,25 @@ void set_mtrr_ops(struct mtrr_ops * ops)
- /*  Returns non-zero if we have the write-combining memory type  */
- static int have_wrcomb(void)
- {
--	struct pci_dev *dev = NULL;
--
--	/* WTF is this?
--	 * Someone, please shoot me.
--	 */
--
--	/* ServerWorks LE chipsets have problems with write-combining 
--	   Don't allow it and leave room for other chipsets to be tagged */
--
-+	struct pci_dev *dev;
-+	
- 	if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
--		if ((dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
--		    (dev->device == PCI_DEVICE_ID_SERVERWORKS_LE)) {
--			printk(KERN_INFO
--			       "mtrr: Serverworks LE detected. Write-combining disabled.\n");
-+		/* ServerWorks LE chipsets have problems with write-combining 
-+		   Don't allow it and leave room for other chipsets to be tagged */
-+		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
-+		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
-+			printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
- 			return 0;
- 		}
--	}
-+		/* Intel 450NX errata # 23. Non ascending cachline evictions to
-+		   write combining memory may resulting in data corruption */
-+		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
-+		    dev->device == PCI_DEVICE_ID_INTEL_82451NX)
-+		{
-+			printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
-+			return 0;
-+		}
-+	}		
- 	return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
- }
- 
-@@ -121,7 +123,7 @@ static void init_table(void)
- 	max = num_var_ranges;
- 	if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL))
- 	    == NULL) {
--		printk("mtrr: could not allocate\n");
-+		printk(KERN_ERR "mtrr: could not allocate\n");
- 		return;
- 	}
- 	for (i = 0; i < max; i++)
-@@ -310,7 +312,7 @@ int mtrr_add_page(unsigned long base, un
- 		return error;
- 
- 	if (type >= MTRR_NUM_TYPES) {
--		printk("mtrr: type: %u illegal\n", type);
-+		printk(KERN_WARNING "mtrr: type: %u invalid\n", type);
- 		return -EINVAL;
- 	}
- 
-@@ -322,7 +324,7 @@ int mtrr_add_page(unsigned long base, un
- 	}
- 
- 	if (base & size_or_mask || size & size_or_mask) {
--		printk("mtrr: base or size exceeds the MTRR width\n");
-+		printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n");
- 		return -EINVAL;
- 	}
- 
-@@ -348,7 +350,7 @@ int mtrr_add_page(unsigned long base, un
- 		if (ltype != type) {
- 			if (type == MTRR_TYPE_UNCACHABLE)
- 				continue;
--			printk ("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
-+			printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
- 			     base, size, attrib_to_str(ltype),
- 			     attrib_to_str(type));
- 			goto out;
-@@ -364,7 +366,7 @@ int mtrr_add_page(unsigned long base, un
- 		set_mtrr(i, base, size, type);
- 		usage_table[i] = 1;
- 	} else
--		printk("mtrr: no more MTRRs available\n");
-+		printk(KERN_INFO "mtrr: no more MTRRs available\n");
- 	error = i;
-  out:
- 	up(&main_lock);
-@@ -412,8 +414,8 @@ mtrr_add(unsigned long base, unsigned lo
- 	 char increment)
- {
- 	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
--		printk("mtrr: size and base must be multiples of 4 kiB\n");
--		printk("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
-+		printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
-+		printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
- 		return -EINVAL;
- 	}
- 	return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
-@@ -458,28 +460,28 @@ int mtrr_del_page(int reg, unsigned long
- 			}
- 		}
- 		if (reg < 0) {
--			printk("mtrr: no MTRR for %lx000,%lx000 found\n", base,
-+			printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
- 			       size);
- 			goto out;
- 		}
- 	}
- 	if (reg >= max) {
--		printk("mtrr: register: %d too big\n", reg);
-+		printk(KERN_WARNING "mtrr: register: %d too big\n", reg);
- 		goto out;
- 	}
- 	if (is_cpu(CYRIX) && !use_intel()) {
- 		if ((reg == 3) && arr3_protected) {
--			printk("mtrr: ARR3 cannot be changed\n");
-+			printk(KERN_WARNING "mtrr: ARR3 cannot be changed\n");
- 			goto out;
- 		}
- 	}
- 	mtrr_if->get(reg, &lbase, &lsize, &ltype);
- 	if (lsize < 1) {
--		printk("mtrr: MTRR %d not used\n", reg);
-+		printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg);
- 		goto out;
- 	}
- 	if (usage_table[reg] < 1) {
--		printk("mtrr: reg: %d has count=0\n", reg);
-+		printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
- 		goto out;
- 	}
- 	if (--usage_table[reg] < 1)
-@@ -508,8 +510,8 @@ int
- mtrr_del(int reg, unsigned long base, unsigned long size)
- {
- 	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
--		printk("mtrr: size and base must be multiples of 4 kiB\n");
--		printk("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
-+		printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
-+		printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
- 		return -EINVAL;
- 	}
- 	return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
-@@ -677,7 +679,7 @@ static int __init mtrr_init(void)
- 			break;
- 		}
- 	}
--	printk("mtrr: v%s\n",MTRR_VERSION);
-+	printk(KERN_INFO "mtrr: v%s\n",MTRR_VERSION);
- 
- 	if (mtrr_if) {
- 		set_num_var_ranges();
-@@ -701,5 +703,5 @@ char *mtrr_strings[MTRR_NUM_TYPES] =
-     "write-back",               /* 6 */
- };
- 
--subsys_initcall(mtrr_init);
-+core_initcall(mtrr_init);
- 
---- linux-2.6.0-test1/arch/i386/kernel/cpu/proc.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/i386/kernel/cpu/proc.c	2003-07-19 17:04:06.000000000 -0700
-@@ -60,7 +60,7 @@ static int show_cpuinfo(struct seq_file 
- 	int fpu_exception;
- 
- #ifdef CONFIG_SMP
--	if (!(cpu_online_map & (1<<n)))
-+	if (!cpu_online(n))
- 		return 0;
- #endif
- 	seq_printf(m, "processor\t: %d\n"
---- linux-2.6.0-test1/arch/i386/kernel/entry.S	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/i386/kernel/entry.S	2003-07-19 17:06:37.000000000 -0700
-@@ -48,6 +48,18 @@
- #include <asm/smp.h>
- #include <asm/page.h>
- #include "irq_vectors.h"
-+        /* We do not recover from a stack overflow, but at least
-+         * we know it happened and should be able to track it down.
-+         */
-+#ifdef CONFIG_STACK_OVERFLOW_TEST
-+#define STACK_OVERFLOW_TEST \
-+        testl $7680,%esp;    \
-+        jnz   10f;            \
-+        call  stack_overflow; \
-+10:
-+#else
-+#define STACK_OVERFLOW_TEST
-+#endif
- 
- EBX		= 0x00
- ECX		= 0x04
-@@ -98,7 +110,8 @@ TSS_ESP0_OFFSET = (4 - 0x200)
- 	pushl %ebx; \
- 	movl $(__USER_DS), %edx; \
- 	movl %edx, %ds; \
--	movl %edx, %es;
-+	movl %edx, %es; \
-+        STACK_OVERFLOW_TEST
- 
- #define RESTORE_INT_REGS \
- 	popl %ebx;	\
-@@ -298,6 +311,19 @@ syscall_exit:
- 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
- 	jne syscall_exit_work
- restore_all:
-+#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-+	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
-+	movb CS(%esp), %al
-+	testl $(VM_MASK | 3), %eax
-+	jz resume_kernelX		# returning to kernel or vm86-space
-+
-+	cmpl $0,TI_PRE_COUNT(%ebx)	# non-zero preempt_count ?
-+	jz resume_kernelX
-+        
-+        int $3
-+        
-+resume_kernelX:
-+#endif
- 	RESTORE_ALL
- 
- 	# perform work that needs to be done immediately before resumption
-@@ -878,5 +904,6 @@ ENTRY(sys_call_table)
- 	.long sys_fstatfs64	
- 	.long sys_tgkill	/* 270 */
- 	.long sys_utimes
-- 
-+	.long sys_mknod64
-+
- nr_syscalls=(.-sys_call_table)/4
---- linux-2.6.0-test1/arch/i386/kernel/io_apic.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/kernel/io_apic.c	2003-07-19 17:04:06.000000000 -0700
-@@ -249,14 +249,14 @@ static void clear_IO_APIC (void)
- 			clear_IO_APIC_pin(apic, pin);
- }
- 
--static void set_ioapic_affinity (unsigned int irq, unsigned long cpu_mask)
-+static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask)
- {
- 	unsigned long flags;
- 	int pin;
- 	struct irq_pin_list *entry = irq_2_pin + irq;
- 	unsigned int apicid_value;
- 	
--	apicid_value = cpu_mask_to_apicid(cpu_mask);
-+	apicid_value = cpu_mask_to_apicid(mk_cpumask_const(cpumask));
- 	/* Prepare to do the io_apic_write */
- 	apicid_value = apicid_value << 24;
- 	spin_lock_irqsave(&ioapic_lock, flags);
-@@ -286,9 +286,9 @@ static void set_ioapic_affinity (unsigne
- #  define Dprintk(x...) 
- # endif
- 
--extern unsigned long irq_affinity[NR_IRQS];
-+extern cpumask_t irq_affinity[NR_IRQS];
- 
--static int __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
-+static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
- 
- #define IRQBALANCE_CHECK_ARCH -999
- static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
-@@ -307,8 +307,7 @@ struct irq_cpu_info {
- #define IDLE_ENOUGH(cpu,now) \
- 		(idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1))
- 
--#define IRQ_ALLOWED(cpu,allowed_mask) \
--		((1 << cpu) & (allowed_mask))
-+#define IRQ_ALLOWED(cpu, allowed_mask)	cpu_isset(cpu, allowed_mask)
- 
- #define CPU_TO_PACKAGEINDEX(i) \
- 		((physical_balance && i > cpu_sibling_map[i]) ? cpu_sibling_map[i] : i)
-@@ -320,7 +319,7 @@ struct irq_cpu_info {
- 
- long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
- 
--static unsigned long move(int curr_cpu, unsigned long allowed_mask,
-+static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
- 			unsigned long now, int direction)
- {
- 	int search_idle = 1;
-@@ -350,20 +349,20 @@ inside:
- static inline void balance_irq(int cpu, int irq)
- {
- 	unsigned long now = jiffies;
--	unsigned long allowed_mask;
-+	cpumask_t allowed_mask;
- 	unsigned int new_cpu;
- 		
- 	if (irqbalance_disabled)
- 		return; 
- 
--	allowed_mask = cpu_online_map & irq_affinity[irq];
-+	cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]);
- 	new_cpu = move(cpu, allowed_mask, now, 1);
- 	if (cpu != new_cpu) {
- 		irq_desc_t *desc = irq_desc + irq;
- 		unsigned long flags;
- 
- 		spin_lock_irqsave(&desc->lock, flags);
--		pending_irq_balance_cpumask[irq] = 1 << new_cpu;
-+		pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu);
- 		spin_unlock_irqrestore(&desc->lock, flags);
- 	}
- }
-@@ -399,8 +398,7 @@ static void do_irq_balance(void)
- 	int tmp_loaded, first_attempt = 1;
- 	unsigned long tmp_cpu_irq;
- 	unsigned long imbalance = 0;
--	unsigned long allowed_mask;
--	unsigned long target_cpu_mask;
-+	cpumask_t allowed_mask, target_cpu_mask, tmp;
- 
- 	for (i = 0; i < NR_CPUS; i++) {
- 		int package_index;
-@@ -549,10 +547,11 @@ tryanotherirq:
- 					CPU_IRQ(cpu_sibling_map[min_loaded]))
- 		min_loaded = cpu_sibling_map[min_loaded];
- 
--	allowed_mask = cpu_online_map & irq_affinity[selected_irq];
--	target_cpu_mask = 1 << min_loaded;
-+	cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]);
-+	target_cpu_mask = cpumask_of_cpu(min_loaded);
-+	cpus_and(tmp, target_cpu_mask, allowed_mask);
- 
--	if (target_cpu_mask & allowed_mask) {
-+	if (!cpus_empty(tmp)) {
- 		irq_desc_t *desc = irq_desc + selected_irq;
- 		unsigned long flags;
- 
-@@ -560,7 +559,8 @@ tryanotherirq:
- 				selected_irq, min_loaded);
- 		/* mark for change destination */
- 		spin_lock_irqsave(&desc->lock, flags);
--		pending_irq_balance_cpumask[selected_irq] = 1 << min_loaded;
-+		pending_irq_balance_cpumask[selected_irq] =
-+					cpumask_of_cpu(min_loaded);
- 		spin_unlock_irqrestore(&desc->lock, flags);
- 		/* Since we made a change, come back sooner to 
- 		 * check for more variation.
-@@ -591,8 +591,9 @@ int balanced_irq(void *unused)
- 	daemonize("kirqd");
- 	
- 	/* push everything to CPU 0 to give us a starting point.  */
--	for (i = 0 ; i < NR_IRQS ; i++)
--		pending_irq_balance_cpumask[i] = 1;
-+	for (i = 0 ; i < NR_IRQS ; i++) {
-+		pending_irq_balance_cpumask[i] = cpumask_of_cpu(0);
-+	}
- 
- repeat:
- 	set_current_state(TASK_INTERRUPTIBLE);
-@@ -611,7 +612,9 @@ static int __init balanced_irq_init(void
- {
- 	int i;
- 	struct cpuinfo_x86 *c;
-+	cpumask_t tmp;
- 
-+	cpus_shift_right(tmp, cpu_online_map, 2);
-         c = &boot_cpu_data;
- 	/* When not overwritten by the command line ask subarchitecture. */
- 	if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
-@@ -628,7 +631,7 @@ static int __init balanced_irq_init(void
- 	 * Enable physical balance only if more than 1 physical processor
- 	 * is present
- 	 */
--	if (smp_num_siblings > 1 && cpu_online_map >> 2)
-+	if (smp_num_siblings > 1 && !cpus_empty(tmp))
- 		physical_balance = 1;
- 
- 	for (i = 0; i < NR_CPUS; i++) {
-@@ -667,14 +670,14 @@ static int __init irqbalance_disable(cha
- 
- __setup("noirqbalance", irqbalance_disable);
- 
--static void set_ioapic_affinity (unsigned int irq, unsigned long mask);
-+static void set_ioapic_affinity(unsigned int irq, cpumask_t mask);
- 
- static inline void move_irq(int irq)
- {
- 	/* note - we hold the desc->lock */
--	if (unlikely(pending_irq_balance_cpumask[irq])) {
-+	if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) {
- 		set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]);
--		pending_irq_balance_cpumask[irq] = 0;
-+		cpus_clear(pending_irq_balance_cpumask[irq]);
- 	}
- }
- 
-@@ -682,6 +685,21 @@ __initcall(balanced_irq_init);
- 
- #else /* !SMP */
- static inline void move_irq(int irq) { }
-+
-+void send_IPI_self(int vector)
-+{
-+	unsigned int cfg;
-+
-+	/*
-+	 * Wait for idle.
-+	 */
-+	apic_wait_icr_idle();
-+	cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
-+	/*
-+	 * Send the IPI. The write to APIC_ICR fires this off.
-+	 */
-+	apic_write_around(APIC_ICR, cfg);
-+}
- #endif /* defined(CONFIG_SMP) */
- 
- 
-@@ -822,7 +840,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, 
-  * we need to reprogram the ioredtbls to cater for the cpus which have come online
-  * so mask in all cases should simply be TARGET_CPUS
-  */
--void __init setup_ioapic_dest (unsigned long mask)
-+void __init setup_ioapic_dest(cpumask_t mask)
- {
- 	int pin, ioapic, irq, irq_entry;
- 
-@@ -1598,7 +1616,7 @@ void disable_IO_APIC(void)
- static void __init setup_ioapic_ids_from_mpc(void)
- {
- 	union IO_APIC_reg_00 reg_00;
--	unsigned long phys_id_present_map;
-+	physid_mask_t phys_id_present_map;
- 	int apic;
- 	int i;
- 	unsigned char old_id;
-@@ -1608,6 +1626,10 @@ static void __init setup_ioapic_ids_from
- 		/* This gets done during IOAPIC enumeration for ACPI. */
- 		return;
- 
-+	/*
-+	 * This is broken; anything with a real cpu count has to
-+	 * circumvent this idiocy regardless.
-+	 */
- 	phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
- 
- 	/*
-@@ -1639,18 +1661,20 @@ static void __init setup_ioapic_ids_from
- 					mp_ioapics[apic].mpc_apicid)) {
- 			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- 				apic, mp_ioapics[apic].mpc_apicid);
--			for (i = 0; i < 0xf; i++)
--				if (!(phys_id_present_map & (1 << i)))
-+			for (i = 0; i < APIC_BROADCAST_ID; i++)
-+				if (!physid_isset(i, phys_id_present_map))
- 					break;
--			if (i >= 0xf)
-+			if (i >= APIC_BROADCAST_ID)
- 				panic("Max APIC ID exceeded!\n");
- 			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- 				i);
--			phys_id_present_map |= 1 << i;
-+			physid_set(i, phys_id_present_map);
- 			mp_ioapics[apic].mpc_apicid = i;
- 		} else {
-+			physid_mask_t tmp;
-+			tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
- 			printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
--			phys_id_present_map |= apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
-+			physids_or(phys_id_present_map, phys_id_present_map, tmp);
- 		}
- 
- 
-@@ -2220,7 +2244,8 @@ late_initcall(io_apic_bug_finalize);
- int __init io_apic_get_unique_id (int ioapic, int apic_id)
- {
- 	union IO_APIC_reg_00 reg_00;
--	static unsigned long apic_id_map = 0;
-+	static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
-+	physid_mask_t tmp;
- 	unsigned long flags;
- 	int i = 0;
- 
-@@ -2233,8 +2258,8 @@ int __init io_apic_get_unique_id (int io
- 	 *      advantage of new APIC bus architecture.
- 	 */
- 
--	if (!apic_id_map)
--		apic_id_map = phys_cpu_present_map;
-+	if (physids_empty(apic_id_map))
-+		apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
- 
- 	spin_lock_irqsave(&ioapic_lock, flags);
- 	reg_00.raw = io_apic_read(ioapic, 0);
-@@ -2266,7 +2291,8 @@ int __init io_apic_get_unique_id (int io
- 		apic_id = i;
- 	} 
- 
--	apic_id_map |= apicid_to_cpu_present(apic_id);
-+	tmp = apicid_to_cpu_present(apic_id);
-+	physids_or(apic_id_map, apic_id_map, tmp);
- 
- 	if (reg_00.bits.ID != apic_id) {
- 		reg_00.bits.ID = apic_id;
---- linux-2.6.0-test1/arch/i386/kernel/irq.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/kernel/irq.c	2003-07-19 17:04:06.000000000 -0700
-@@ -45,8 +45,6 @@
- #include <asm/desc.h>
- #include <asm/irq.h>
- 
--
--
- /*
-  * Linux has a controller-independent x86 interrupt architecture.
-  * every controller has a 'controller-template', that is used
-@@ -889,13 +887,13 @@ int setup_irq(unsigned int irq, struct i
- static struct proc_dir_entry * root_irq_dir;
- static struct proc_dir_entry * irq_dir [NR_IRQS];
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
--static unsigned int parse_hex_value (const char __user *buffer,
--		unsigned long count, unsigned long *ret)
-+static unsigned int parse_hex_value(const char __user *buffer,
-+		unsigned long count, cpumask_t *ret)
- {
--	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	unsigned char hexnum[HEX_DIGITS];
-+	cpumask_t value = CPU_MASK_NONE;
- 	int i;
- 
- 	if (!count)
-@@ -909,10 +907,10 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
- 
- 	for (i = 0; i < count; i++) {
- 		unsigned int c = hexnum[i];
-+		int k;
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -921,7 +919,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (test_bit(k, (unsigned long *)&c))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -930,22 +931,35 @@ out:
- 
- #ifdef CONFIG_SMP
- 
--static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
-+static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
-+
-+cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
- 
--unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
--static int irq_affinity_read_proc (char *page, char **start, off_t off,
-+static int irq_affinity_read_proc(char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	int k, len;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
-+
-+	len = 0;
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
--static int irq_affinity_write_proc (struct file *file, const char __user *buffer,
-+static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
- 					unsigned long count, void *data)
- {
--	int irq = (long) data, full_count = count, err;
--	unsigned long new_value;
-+	int irq = (long)data, full_count = count, err;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -957,11 +971,13 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
--	irq_desc[irq].handler->set_affinity(irq, new_value);
-+	irq_desc[irq].handler->set_affinity(irq,
-+					cpumask_of_cpu(first_cpu(new_value)));
- 
- 	return full_count;
- }
-@@ -980,8 +996,9 @@ static int prof_cpu_mask_read_proc (char
- static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data;
-+	unsigned long full_count = count, err;
-+	cpumask_t new_value;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/i386/kernel/kgdb_stub.c	2003-07-19 17:04:14.000000000 -0700
-@@ -0,0 +1,2215 @@
-+/*
-+ *
-+ * This program 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, or (at your option) any
-+ * later version.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
-+ * General Public License for more details.
-+ *
-+ */
-+
-+/*
-+ * Copyright (c) 2000 VERITAS Software Corporation.
-+ * 
-+ */
-+/****************************************************************************
-+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
-+ *
-+ *  Module name: remcom.c $
-+ *  Revision: 1.34 $
-+ *  Date: 91/03/09 12:29:49 $
-+ *  Contributor:     Lake Stevens Instrument Division$
-+ *
-+ *  Description:     low level support for gdb debugger. $
-+ *
-+ *  Considerations:  only works on target hardware $
-+ *
-+ *  Written by:	     Glenn Engel $
-+ *  Updated by:	     David Grothe <dave@gcom.com>
-+ *  ModuleState:     Experimental $
-+ *
-+ *  NOTES:	     See Below $
-+ *
-+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
-+ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
-+ *
-+ *  Changes to allow auto initilization.  All that is needed is that it
-+ *  be linked with the kernel and a break point (int 3) be executed.
-+ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
-+ *  this. It should also be possible, once the interrupt system is up, to
-+ *  call putDebugChar("+").  Once this is done, the remote debugger should
-+ *  get our attention by sending a ^C in a packet. George Anzinger 
-+ *  <george@mvista.com>
-+ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
-+ *  Added thread support, support for multiple processors,
-+ *	support for ia-32(x86) hardware debugging.
-+ *	Amit S. Kale ( akale@veritas.com )
-+ *
-+ *
-+ *  To enable debugger support, two things need to happen.  One, a
-+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
-+ *  or error conditions to be properly intercepted and reported to gdb.
-+ *  Two, a breakpoint needs to be generated to begin communication.  This
-+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
-+ *  simulates a breakpoint by executing an int 3.
-+ *
-+ *************
-+ *
-+ *    The following gdb commands are supported:
-+ *
-+ * command	    function				   Return value
-+ *
-+ *    g		    return the value of the CPU registers  hex data or ENN
-+ *    G		    set the value of the CPU registers	   OK or ENN
-+ *
-+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA	   hex data or ENN
-+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA	   OK or ENN
-+ *
-+ *    c		    Resume at current address		   SNN	 ( signal NN)
-+ *    cAA..AA	    Continue at address AA..AA		   SNN
-+ *
-+ *    s		    Step one instruction		   SNN
-+ *    sAA..AA	    Step one instruction from AA..AA	   SNN
-+ *
-+ *    k		    kill
-+ *
-+ *    ?		    What was the last sigval ?		   SNN	 (signal NN)
-+ *
-+ * All commands and responses are sent with a packet which includes a
-+ * checksum.  A packet consists of
-+ *
-+ * $<packet info>#<checksum>.
-+ *
-+ * where
-+ * <packet info> :: <characters representing the command or response>
-+ * <checksum>	 :: < two hex digits computed as modulo 256 sum of <packetinfo>>
-+ *
-+ * When a packet is received, it is first acknowledged with either '+' or '-'.
-+ * '+' indicates a successful transfer.	 '-' indicates a failed transfer.
-+ *
-+ * Example:
-+ *
-+ * Host:		  Reply:
-+ * $m0,10#2a		   +$00010203040506070809101112131415#42
-+ *
-+ ****************************************************************************/
-+#define KGDB_VERSION "<20030530.0126.22>"
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <asm/string.h>		/* for strcpy */
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <asm/vm86.h>
-+#include <asm/system.h>
-+#include <asm/ptrace.h>		/* for linux pt_regs struct */
-+#include <asm/kgdb_local.h>
-+#include <linux/list.h>
-+#include <asm/atomic.h>
-+#include <asm/processor.h>
-+#include <linux/irq.h>
-+#include <asm/desc.h>
-+
-+/************************************************************************
-+ *
-+ * external low-level support routines
-+ */
-+typedef void (*Function) (void);	/* pointer to a function */
-+
-+/* Thread reference */
-+typedef unsigned char threadref[8];
-+
-+extern void putDebugChar(int);	/* write a single character	 */
-+extern int getDebugChar(void);	/* read and return a single char */
-+
-+/************************************************************************/
-+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-+/* at least NUMREGBYTES*2 are needed for register packets */
-+/* Longer buffer is needed to list all threads */
-+#define BUFMAX 1024
-+
-+char *kgdb_version = KGDB_VERSION;
-+
-+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
-+int debug_regs = 0;		/* set to non-zero to print registers */
-+
-+/* filled in by an external module */
-+char *gdb_module_offsets;
-+
-+static const char hexchars[] = "0123456789abcdef";
-+
-+/* Number of bytes of registers.  */
-+#define NUMREGBYTES 64
-+/*
-+ * Note that this register image is in a different order than
-+ * the register image that Linux produces at interrupt time.
-+ *
-+ * Linux's register image is defined by struct pt_regs in ptrace.h.
-+ * Just why GDB uses a different order is a historical mystery.
-+ */
-+enum regnames { _EAX,		/* 0 */
-+	_ECX,			/* 1 */
-+	_EDX,			/* 2 */
-+	_EBX,			/* 3 */
-+	_ESP,			/* 4 */
-+	_EBP,			/* 5 */
-+	_ESI,			/* 6 */
-+	_EDI,			/* 7 */
-+	_PC /* 8 also known as eip */ ,
-+	_PS /* 9 also known as eflags */ ,
-+	_CS,			/* 10 */
-+	_SS,			/* 11 */
-+	_DS,			/* 12 */
-+	_ES,			/* 13 */
-+	_FS,			/* 14 */
-+	_GS			/* 15 */
-+};
-+
-+/***************************  ASSEMBLY CODE MACROS *************************/
-+/*
-+ * Put the error code here just in case the user cares.	
-+ * Likewise, the vector number here (since GDB only gets the signal
-+ * number through the usual means, and that's not very specific). 
-+ * The called_from is the return address so he can tell how we entered kgdb.
-+ * This will allow him to seperate out the various possible entries. 
-+ */
-+#define REMOTE_DEBUG 0		/* set != to turn on printing (also available in info) */
-+
-+#define PID_MAX PID_MAX_DEFAULT
-+
-+#ifdef CONFIG_SMP
-+void smp_send_nmi_allbutself(void);
-+#define IF_SMP(x) x
-+#undef MAX_NO_CPUS
-+#ifndef CONFIG_NO_KGDB_CPUS
-+#define CONFIG_NO_KGDB_CPUS 2
-+#endif
-+#if CONFIG_NO_KGDB_CPUS > NR_CPUS
-+#define MAX_NO_CPUS NR_CPUS
-+#else
-+#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
-+#endif
-+#define hold_init hold_on_sstep: 1,
-+#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
-+#define NUM_CPUS num_online_cpus()
-+#else
-+#define IF_SMP(x)
-+#define hold_init
-+#undef MAX_NO_CPUS
-+#define MAX_NO_CPUS 1
-+#define NUM_CPUS 1
-+#endif
-+#define NOCPU (struct task_struct *)0xbad1fbad
-+/* *INDENT-OFF*	 */
-+struct kgdb_info {
-+	int used_malloc;
-+	void *called_from;
-+	long long entry_tsc;
-+	int errcode;
-+	int vector;
-+	int print_debug_info;
-+#ifdef CONFIG_SMP
-+	int hold_on_sstep;
-+	struct {
-+		volatile struct task_struct *task;
-+		int pid;
-+		int hold;
-+		struct pt_regs *regs;
-+	} cpus_waiting[MAX_NO_CPUS];
-+#endif
-+} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
-+
-+/* *INDENT-ON*	*/
-+
-+#define used_m kgdb_info.used_malloc
-+/*
-+ * This is little area we set aside to contain the stack we 
-+ * need to build to allow gdb to call functions.  We use one
-+ * per cpu to avoid locking issues.  We will do all this work
-+ * with interrupts off so that should take care of the protection
-+ * issues.
-+ */
-+#define LOOKASIDE_SIZE 200	/* should be more than enough */
-+#define MALLOC_MAX   200	/* Max malloc size */
-+struct {
-+	unsigned int esp;
-+	int array[LOOKASIDE_SIZE];
-+} fn_call_lookaside[MAX_NO_CPUS];
-+
-+static int trap_cpu;
-+static unsigned int OLD_esp;
-+
-+#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
-+#define IF_BIT 0x200
-+#define TF_BIT 0x100
-+
-+#define MALLOC_ROUND 8-1
-+
-+static char malloc_array[MALLOC_MAX];
-+IF_SMP(static void to_gdb(const char *mess));
-+void *
-+malloc(int size)
-+{
-+
-+	if (size <= (MALLOC_MAX - used_m)) {
-+		int old_used = used_m;
-+		used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
-+		return &malloc_array[old_used];
-+	} else {
-+		return NULL;
-+	}
-+}
-+
-+/*
-+ * Gdb calls functions by pushing agruments, including a return address 
-+ * on the stack and the adjusting EIP to point to the function.	 The 
-+ * whole assumption in GDB is that we are on a different stack than the
-+ * one the "user" i.e. code that hit the break point, is on.  This, of
-+ * course is not true in the kernel.  Thus various dodges are needed to
-+ * do the call without directly messing with EIP (which we can not change
-+ * as it is just a location and not a register.	 To adjust it would then
-+ * require that we move every thing below EIP up or down as needed.  This
-+ * will not work as we may well have stack relative pointer on the stack
-+ * (such as the pointer to regs, for example).
-+
-+ * So here is what we do:
-+ * We detect gdb attempting to store into the stack area and instead, store
-+ * into the fn_call_lookaside.array at the same relative location as if it 
-+ * were the area ESP pointed at.  We also trap ESP modifications
-+ * and uses these to adjust fn_call_lookaside.esp.  On entry 
-+ * fn_call_lookaside.esp will be set to point at the last entry in
-+ * fn_call_lookaside.array.  This allows us to check if it has changed, and 
-+ * if so, on exit, we add the registers we will use to do the move and a
-+ * trap/ interrupt return exit sequence.  We then adjust the eflags in the
-+ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
-+ * kill the interrupt bit, AND we change EIP to point at our set up stub.
-+ * As part of the register set up we preset the registers to point at the
-+ * begining and end of the fn_call_lookaside.array, so all the stub needs to
-+ * do is move words from the array to the stack until ESP= the desired value
-+ * then do the rti.  This will then transfer to the desired function with 
-+ * all the correct registers.  Nifty huh?
-+ */
-+extern asmlinkage void fn_call_stub(void);
-+extern asmlinkage void fn_rtn_stub(void);
-+/*					   *INDENT-OFF*	 */
-+__asm__("fn_rtn_stub:\n\t"
-+	"movl %eax,%esp\n\t"
-+	"fn_call_stub:\n\t"
-+	"1:\n\t"
-+	"addl $-4,%ebx\n\t"
-+	"movl (%ebx), %eax\n\t"
-+	"pushl %eax\n\t"
-+	"cmpl %esp,%ecx\n\t"
-+	"jne  1b\n\t"
-+	"popl %eax\n\t" 
-+	"popl %ebx\n\t" 
-+	"popl %ecx\n\t" 
-+	"iret \n\t");
-+/*					     *INDENT-ON*  */
-+#define gdb_i386vector	kgdb_info.vector
-+#define gdb_i386errcode kgdb_info.errcode
-+#define waiting_cpus	kgdb_info.cpus_waiting
-+#define remote_debug	kgdb_info.print_debug_info
-+#define hold_cpu(cpu)	kgdb_info.cpus_waiting[cpu].hold
-+/* gdb locks */
-+
-+#ifdef CONFIG_SMP
-+static int in_kgdb_called;
-+static spinlock_t waitlocks[MAX_NO_CPUS] =
-+    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
-+/*
-+ * The following array has the thread pointer of each of the "other"
-+ * cpus.  We make it global so it can be seen by gdb.
-+ */
-+volatile int in_kgdb_entry_log[MAX_NO_CPUS];
-+volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
-+/*
-+static spinlock_t continuelocks[MAX_NO_CPUS];
-+*/
-+spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
-+/* waiters on our spinlock plus us */
-+static atomic_t spinlock_waiters = ATOMIC_INIT(1);
-+static int spinlock_count = 0;
-+static int spinlock_cpu = 0;
-+/*
-+ * Note we use nested spin locks to account for the case where a break
-+ * point is encountered when calling a function by user direction from
-+ * kgdb. Also there is the memory exception recursion to account for.
-+ * Well, yes, but this lets other cpus thru too.  Lets add a
-+ * cpu id to the lock.
-+ */
-+#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
-+			      spinlock_cpu != smp_processor_id()){\
-+				      atomic_inc(&spinlock_waiters); \
-+				      while (! spin_trylock(x)) {\
-+					    in_kgdb(&regs);\
-+				      }\
-+				      atomic_dec(&spinlock_waiters); \
-+				      spinlock_count = 1; \
-+				      spinlock_cpu = smp_processor_id(); \
-+			  }else{  \
-+				      spinlock_count++; \
-+			  }
-+#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
-+#else
-+unsigned kgdb_spinlock = 0;
-+#define KGDB_SPIN_LOCK(x) --*x
-+#define KGDB_SPIN_UNLOCK(x) ++*x
-+#endif
-+
-+int
-+hex(char ch)
-+{
-+	if ((ch >= 'a') && (ch <= 'f'))
-+		return (ch - 'a' + 10);
-+	if ((ch >= '0') && (ch <= '9'))
-+		return (ch - '0');
-+	if ((ch >= 'A') && (ch <= 'F'))
-+		return (ch - 'A' + 10);
-+	return (-1);
-+}
-+
-+/* scan for the sequence $<data>#<checksum>	*/
-+void
-+getpacket(char *buffer)
-+{
-+	unsigned char checksum;
-+	unsigned char xmitcsum;
-+	int i;
-+	int count;
-+	char ch;
-+
-+	do {
-+		/* wait around for the start character, ignore all other characters */
-+		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
-+		checksum = 0;
-+		xmitcsum = -1;
-+
-+		count = 0;
-+
-+		/* now, read until a # or end of buffer is found */
-+		while (count < BUFMAX) {
-+			ch = getDebugChar() & 0x7f;
-+			if (ch == '#')
-+				break;
-+			checksum = checksum + ch;
-+			buffer[count] = ch;
-+			count = count + 1;
-+		}
-+		buffer[count] = 0;
-+
-+		if (ch == '#') {
-+			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
-+			xmitcsum += hex(getDebugChar() & 0x7f);
-+			if ((remote_debug) && (checksum != xmitcsum)) {
-+				printk
-+				    ("bad checksum.	My count = 0x%x, sent=0x%x. buf=%s\n",
-+				     checksum, xmitcsum, buffer);
-+			}
-+
-+			if (checksum != xmitcsum)
-+				putDebugChar('-');	/* failed checksum */
-+			else {
-+				putDebugChar('+');	/* successful transfer */
-+				/* if a sequence char is present, reply the sequence ID */
-+				if (buffer[2] == ':') {
-+					putDebugChar(buffer[0]);
-+					putDebugChar(buffer[1]);
-+					/* remove sequence chars from buffer */
-+					count = strlen(buffer);
-+					for (i = 3; i <= count; i++)
-+						buffer[i - 3] = buffer[i];
-+				}
-+			}
-+		}
-+	} while (checksum != xmitcsum);
-+
-+	if (remote_debug)
-+		printk("R:%s\n", buffer);
-+}
-+
-+/* send the packet in buffer.  */
-+
-+void
-+putpacket(char *buffer)
-+{
-+	unsigned char checksum;
-+	int count;
-+	char ch;
-+
-+	/*  $<packet info>#<checksum>. */
-+	do {
-+		if (remote_debug)
-+			printk("T:%s\n", buffer);
-+		putDebugChar('$');
-+		checksum = 0;
-+		count = 0;
-+
-+		while ((ch = buffer[count])) {
-+			putDebugChar(ch);
-+			checksum += ch;
-+			count += 1;
-+		}
-+
-+		putDebugChar('#');
-+		putDebugChar(hexchars[checksum >> 4]);
-+		putDebugChar(hexchars[checksum % 16]);
-+
-+	} while ((getDebugChar() & 0x7f) != '+');
-+
-+}
-+
-+static char remcomInBuffer[BUFMAX];
-+static char remcomOutBuffer[BUFMAX];
-+static short error;
-+
-+void
-+debug_error(char *format, char *parm)
-+{
-+	if (remote_debug)
-+		printk(format, parm);
-+}
-+
-+static void
-+print_regs(struct pt_regs *regs)
-+{
-+	printk("EAX=%08lx ", regs->eax);
-+	printk("EBX=%08lx ", regs->ebx);
-+	printk("ECX=%08lx ", regs->ecx);
-+	printk("EDX=%08lx ", regs->edx);
-+	printk("\n");
-+	printk("ESI=%08lx ", regs->esi);
-+	printk("EDI=%08lx ", regs->edi);
-+	printk("EBP=%08lx ", regs->ebp);
-+	printk("ESP=%08lx ", (long) &regs->esp);
-+	printk("\n");
-+	printk(" DS=%08x ", regs->xds);
-+	printk(" ES=%08x ", regs->xes);
-+	printk(" SS=%08x ", __KERNEL_DS);
-+	printk(" FL=%08lx ", regs->eflags);
-+	printk("\n");
-+	printk(" CS=%08x ", regs->xcs);
-+	printk(" IP=%08lx ", regs->eip);
-+#if 0
-+	printk(" FS=%08x ", regs->fs);
-+	printk(" GS=%08x ", regs->gs);
-+#endif
-+	printk("\n");
-+
-+}				/* print_regs */
-+
-+#define NEW_esp fn_call_lookaside[trap_cpu].esp
-+
-+static void
-+regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
-+{
-+	gdb_regs[_EAX] = regs->eax;
-+	gdb_regs[_EBX] = regs->ebx;
-+	gdb_regs[_ECX] = regs->ecx;
-+	gdb_regs[_EDX] = regs->edx;
-+	gdb_regs[_ESI] = regs->esi;
-+	gdb_regs[_EDI] = regs->edi;
-+	gdb_regs[_EBP] = regs->ebp;
-+	gdb_regs[_DS] = regs->xds;
-+	gdb_regs[_ES] = regs->xes;
-+	gdb_regs[_PS] = regs->eflags;
-+	gdb_regs[_CS] = regs->xcs;
-+	gdb_regs[_PC] = regs->eip;
-+	/* Note, as we are a debugging the kernel, we will always 
-+	 * trap in kernel code, this means no priviledge change,
-+	 * and so the pt_regs structure is not completely valid.  In a non
-+	 * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
-+	 * SS and ESP are not stacked, this means that the last 2 elements of
-+	 * pt_regs is not valid (they would normally refer to the user stack)
-+	 * also, using regs+1 is no good because you end up will a value that is 
-+	 * 2 longs (8) too high.  This used to cause stepping over functions
-+	 * to fail, so my fix is to use the address of regs->esp, which 
-+	 * should point at the end of the stack frame.	Note I have ignored
-+	 * completely exceptions that cause an error code to be stacked, such
-+	 * as double fault.  Stuart Hughes, Zentropix.
-+	 * original code: gdb_regs[_ESP] =  (int) (regs + 1) ; 
-+
-+	 * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
-+	 */
-+	gdb_regs[_ESP] = NEW_esp;
-+	gdb_regs[_SS] = __KERNEL_DS;
-+	gdb_regs[_FS] = 0xFFFF;
-+	gdb_regs[_GS] = 0xFFFF;
-+}				/* regs_to_gdb_regs */
-+
-+static void
-+gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
-+{
-+	regs->eax = gdb_regs[_EAX];
-+	regs->ebx = gdb_regs[_EBX];
-+	regs->ecx = gdb_regs[_ECX];
-+	regs->edx = gdb_regs[_EDX];
-+	regs->esi = gdb_regs[_ESI];
-+	regs->edi = gdb_regs[_EDI];
-+	regs->ebp = gdb_regs[_EBP];
-+	regs->xds = gdb_regs[_DS];
-+	regs->xes = gdb_regs[_ES];
-+	regs->eflags = gdb_regs[_PS];
-+	regs->xcs = gdb_regs[_CS];
-+	regs->eip = gdb_regs[_PC];
-+	NEW_esp = gdb_regs[_ESP];	/* keep the value */
-+#if 0				/* can't change these */
-+	regs->esp = gdb_regs[_ESP];
-+	regs->xss = gdb_regs[_SS];
-+	regs->fs = gdb_regs[_FS];
-+	regs->gs = gdb_regs[_GS];
-+#endif
-+
-+}				/* gdb_regs_to_regs */
-+extern void scheduling_functions_start_here(void);
-+extern void scheduling_functions_end_here(void);
-+#define first_sched	((unsigned long) scheduling_functions_start_here)
-+#define last_sched	((unsigned long) scheduling_functions_end_here)
-+
-+int thread_list = 0;
-+
-+void
-+get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
-+{
-+	unsigned long stack_page;
-+	int count = 0;
-+	IF_SMP(int i);
-+	if (!p || p == current) {
-+		regs_to_gdb_regs(gdb_regs, regs);
-+		return;
-+	}
-+#ifdef CONFIG_SMP
-+	for (i = 0; i < MAX_NO_CPUS; i++) {
-+		if (p == kgdb_info.cpus_waiting[i].task) {
-+			regs_to_gdb_regs(gdb_regs,
-+					 kgdb_info.cpus_waiting[i].regs);
-+			gdb_regs[_ESP] =
-+			    (int) &kgdb_info.cpus_waiting[i].regs->esp;
-+
-+			return;
-+		}
-+	}
-+#endif
-+	memset(gdb_regs, 0, NUMREGBYTES);
-+	gdb_regs[_ESP] = p->thread.esp;
-+	gdb_regs[_PC] = p->thread.eip;
-+	gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
-+	gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
-+	gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
-+
-+/*
-+ * This code is to give a more informative notion of where a process 
-+ * is waiting.	It is used only when the user asks for a thread info
-+ * list.  If he then switches to the thread, s/he will find the task
-+ * is in schedule, but a back trace should show the same info we come
-+ * up with.  This code was shamelessly purloined from process.c.  It was
-+ * then enhanced to provide more registers than simply the program 
-+ * counter.
-+ */
-+
-+	if (!thread_list) {
-+		return;
-+	}
-+
-+	if (p->state == TASK_RUNNING)
-+		return;
-+	stack_page = (unsigned long) p->thread_info;
-+	if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
-+		return;
-+	/* include/asm-i386/system.h:switch_to() pushes ebp last. */
-+	do {
-+		if (gdb_regs[_EBP] < stack_page ||
-+		    gdb_regs[_EBP] > 8184 + stack_page)
-+			return;
-+		gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
-+		gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
-+		gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
-+		if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
-+			return;
-+	} while (count++ < 16);
-+	return;
-+}
-+
-+/* Indicate to caller of mem2hex or hex2mem that there has been an
-+   error.  */
-+static volatile int mem_err = 0;
-+static volatile int mem_err_expected = 0;
-+static volatile int mem_err_cnt = 0;
-+static int garbage_loc = -1;
-+
-+int
-+get_char(char *addr)
-+{
-+	return *addr;
-+}
-+
-+void
-+set_char(char *addr, int val, int may_fault)
-+{
-+	/*
-+	 * This code traps references to the area mapped to the kernel
-+	 * stack as given by the regs and, instead, stores to the
-+	 * fn_call_lookaside[cpu].array
-+	 */
-+	if (may_fault &&
-+	    (unsigned int) addr < OLD_esp &&
-+	    ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
-+		addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
-+	}
-+	*addr = val;
-+}
-+
-+/* convert the memory pointed to by mem into hex, placing result in buf */
-+/* return a pointer to the last char put in buf (null) */
-+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
-+   a fault; if zero treat a fault like any other fault in the stub.  */
-+char *
-+mem2hex(char *mem, char *buf, int count, int may_fault)
-+{
-+	int i;
-+	unsigned char ch;
-+
-+	if (may_fault) {
-+		mem_err_expected = 1;
-+		mem_err = 0;
-+	}
-+	for (i = 0; i < count; i++) {
-+		/* printk("%lx = ", mem) ; */
-+
-+		ch = get_char(mem++);
-+
-+		/* printk("%02x\n", ch & 0xFF) ; */
-+		if (may_fault && mem_err) {
-+			if (remote_debug)
-+				printk("Mem fault fetching from addr %lx\n",
-+				       (long) (mem - 1));
-+			*buf = 0;	/* truncate buffer */
-+			return (buf);
-+		}
-+		*buf++ = hexchars[ch >> 4];
-+		*buf++ = hexchars[ch % 16];
-+	}
-+	*buf = 0;
-+	if (may_fault)
-+		mem_err_expected = 0;
-+	return (buf);
-+}
-+
-+/* convert the hex array pointed to by buf into binary to be placed in mem */
-+/* return a pointer to the character AFTER the last byte written */
-+/* NOTE: We use the may fault flag to also indicate if the write is to
-+ * the registers (0) or "other" memory (!=0) 
-+ */
-+char *
-+hex2mem(char *buf, char *mem, int count, int may_fault)
-+{
-+	int i;
-+	unsigned char ch;
-+
-+	if (may_fault) {
-+		mem_err_expected = 1;
-+		mem_err = 0;
-+	}
-+	for (i = 0; i < count; i++) {
-+		ch = hex(*buf++) << 4;
-+		ch = ch + hex(*buf++);
-+		set_char(mem++, ch, may_fault);
-+
-+		if (may_fault && mem_err) {
-+			if (remote_debug)
-+				printk("Mem fault storing to addr %lx\n",
-+				       (long) (mem - 1));
-+			return (mem);
-+		}
-+	}
-+	if (may_fault)
-+		mem_err_expected = 0;
-+	return (mem);
-+}
-+
-+/**********************************************/
-+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-+/* RETURN NUMBER OF CHARS PROCESSED	      */
-+/**********************************************/
-+int
-+hexToInt(char **ptr, int *intValue)
-+{
-+	int numChars = 0;
-+	int hexValue;
-+
-+	*intValue = 0;
-+
-+	while (**ptr) {
-+		hexValue = hex(**ptr);
-+		if (hexValue >= 0) {
-+			*intValue = (*intValue << 4) | hexValue;
-+			numChars++;
-+		} else
-+			break;
-+
-+		(*ptr)++;
-+	}
-+
-+	return (numChars);
-+}
-+
-+#define stubhex(h) hex(h)
-+
-+static int
-+stub_unpack_int(char *buff, int fieldlength)
-+{
-+	int nibble;
-+	int retval = 0;
-+
-+	while (fieldlength) {
-+		nibble = stubhex(*buff++);
-+		retval |= nibble;
-+		fieldlength--;
-+		if (fieldlength)
-+			retval = retval << 4;
-+	}
-+	return retval;
-+}
-+
-+static char *
-+pack_hex_byte(char *pkt, int byte)
-+{
-+	*pkt++ = hexchars[(byte >> 4) & 0xf];
-+	*pkt++ = hexchars[(byte & 0xf)];
-+	return pkt;
-+}
-+
-+#define BUF_THREAD_ID_SIZE 16
-+
-+static char *
-+pack_threadid(char *pkt, threadref * id)
-+{
-+	char *limit;
-+	unsigned char *altid;
-+
-+	altid = (unsigned char *) id;
-+	limit = pkt + BUF_THREAD_ID_SIZE;
-+	while (pkt < limit)
-+		pkt = pack_hex_byte(pkt, *altid++);
-+	return pkt;
-+}
-+
-+static char *
-+unpack_byte(char *buf, int *value)
-+{
-+	*value = stub_unpack_int(buf, 2);
-+	return buf + 2;
-+}
-+
-+static char *
-+unpack_threadid(char *inbuf, threadref * id)
-+{
-+	char *altref;
-+	char *limit = inbuf + BUF_THREAD_ID_SIZE;
-+	int x, y;
-+
-+	altref = (char *) id;
-+
-+	while (inbuf < limit) {
-+		x = stubhex(*inbuf++);
-+		y = stubhex(*inbuf++);
-+		*altref++ = (x << 4) | y;
-+	}
-+	return inbuf;
-+}
-+
-+void
-+int_to_threadref(threadref * id, int value)
-+{
-+	unsigned char *scan;
-+
-+	scan = (unsigned char *) id;
-+	{
-+		int i = 4;
-+		while (i--)
-+			*scan++ = 0;
-+	}
-+	*scan++ = (value >> 24) & 0xff;
-+	*scan++ = (value >> 16) & 0xff;
-+	*scan++ = (value >> 8) & 0xff;
-+	*scan++ = (value & 0xff);
-+}
-+
-+static int
-+threadref_to_int(threadref * ref)
-+{
-+	int i, value = 0;
-+	unsigned char *scan;
-+
-+	scan = (char *) ref;
-+	scan += 4;
-+	i = 4;
-+	while (i-- > 0)
-+		value = (value << 8) | ((*scan++) & 0xff);
-+	return value;
-+}
-+
-+#if 1				/* this is a hold over from 2.4 where O(1) was "sometimes" */
-+extern struct task_struct *kgdb_get_idle(int cpu);
-+#define idle_task(cpu) kgdb_get_idle(cpu)
-+#else
-+#define idle_task(cpu) init_tasks[cpu]
-+#endif
-+
-+struct task_struct *
-+getthread(int pid)
-+{
-+	struct task_struct *thread;
-+	if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
-+
-+		return idle_task(pid - PID_MAX);
-+	} else {
-+		/*
-+		 * find_task_by_pid is relatively safe all the time
-+		 * Other pid functions require lock downs which imply
-+		 * that we may be interrupting them (as we get here
-+		 * in the middle of most any lock down)
-+		 */
-+		thread = find_task_by_pid(pid);
-+		if (thread) {
-+			return thread;
-+		}
-+	}
-+	return NULL;
-+}
-+/* *INDENT-OFF*	 */
-+struct hw_breakpoint {
-+	unsigned enabled;
-+	unsigned type;
-+	unsigned len;
-+	unsigned addr;
-+} breakinfo[4] = { {enabled:0}, 
-+		   {enabled:0}, 
-+		   {enabled:0}, 
-+		   {enabled:0}};
-+/* *INDENT-ON*	*/
-+unsigned hw_breakpoint_status;
-+void
-+correct_hw_break(void)
-+{
-+	int breakno;
-+	int correctit;
-+	int breakbit;
-+	unsigned dr7;
-+
-+	asm volatile ("movl %%db7, %0\n":"=r" (dr7)
-+		      :);
-+	/* *INDENT-OFF*	 */
-+	do {
-+		unsigned addr0, addr1, addr2, addr3;
-+		asm volatile ("movl %%db0, %0\n"
-+			      "movl %%db1, %1\n"
-+			      "movl %%db2, %2\n"
-+			      "movl %%db3, %3\n"
-+			      :"=r" (addr0), "=r"(addr1),
-+			      "=r"(addr2), "=r"(addr3)
-+			      :);
-+	} while (0);
-+	/* *INDENT-ON*	*/
-+	correctit = 0;
-+	for (breakno = 0; breakno < 3; breakno++) {
-+		breakbit = 2 << (breakno << 1);
-+		if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
-+			correctit = 1;
-+			dr7 |= breakbit;
-+			dr7 &= ~(0xf0000 << (breakno << 2));
-+			dr7 |= (((breakinfo[breakno].len << 2) |
-+				 breakinfo[breakno].type) << 16) <<
-+			    (breakno << 2);
-+			switch (breakno) {
-+			case 0:
-+				asm volatile ("movl %0, %%dr0\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 1:
-+				asm volatile ("movl %0, %%dr1\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 2:
-+				asm volatile ("movl %0, %%dr2\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 3:
-+				asm volatile ("movl %0, %%dr3\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+			}
-+		} else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
-+			correctit = 1;
-+			dr7 &= ~breakbit;
-+			dr7 &= ~(0xf0000 << (breakno << 2));
-+		}
-+	}
-+	if (correctit) {
-+		asm volatile ("movl %0, %%db7\n"::"r" (dr7));
-+	}
-+}
-+
-+int
-+remove_hw_break(unsigned breakno)
-+{
-+	if (!breakinfo[breakno].enabled) {
-+		return -1;
-+	}
-+	breakinfo[breakno].enabled = 0;
-+	return 0;
-+}
-+
-+int
-+set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
-+{
-+	if (breakinfo[breakno].enabled) {
-+		return -1;
-+	}
-+	breakinfo[breakno].enabled = 1;
-+	breakinfo[breakno].type = type;
-+	breakinfo[breakno].len = len;
-+	breakinfo[breakno].addr = addr;
-+	return 0;
-+}
-+
-+#ifdef CONFIG_SMP
-+static int in_kgdb_console = 0;
-+
-+int
-+in_kgdb(struct pt_regs *regs)
-+{
-+	unsigned flags;
-+	int cpu = smp_processor_id();
-+	in_kgdb_called = 1;
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		if (in_kgdb_here_log[cpu] ||	/* we are holding this cpu */
-+		    in_kgdb_console) {	/* or we are doing slow i/o */
-+			return 1;
-+		}
-+		return 0;
-+	}
-+
-+	/* As I see it the only reason not to let all cpus spin on
-+	 * the same spin_lock is to allow selected ones to proceed.
-+	 * This would be a good thing, so we leave it this way.
-+	 * Maybe someday....  Done !
-+
-+	 * in_kgdb() is called from an NMI so we don't pretend
-+	 * to have any resources, like printk() for example.  
-+	 */
-+
-+	kgdb_local_irq_save(flags);	/* only local here, to avoid hanging */
-+	/*
-+	 * log arival of this cpu
-+	 * The NMI keeps on ticking.  Protect against recurring more
-+	 * than once, and ignor the cpu that has the kgdb lock
-+	 */
-+	in_kgdb_entry_log[cpu]++;
-+	in_kgdb_here_log[cpu] = regs;
-+	if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
-+		goto exit_in_kgdb;
-+	}
-+	/*
-+	 * For protection of the initilization of the spin locks by kgdb
-+	 * it locks the kgdb spinlock before it gets the wait locks set
-+	 * up.	We wait here for the wait lock to be taken.  If the
-+	 * kgdb lock goes away first??	Well, it could be a slow exit
-+	 * sequence where the wait lock is removed prior to the kgdb lock
-+	 * so if kgdb gets unlocked, we just exit.
-+	 */
-+	while (spin_is_locked(&kgdb_spinlock) &&
-+	       !spin_is_locked(waitlocks + cpu)) ;
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		goto exit_in_kgdb;
-+	}
-+	waiting_cpus[cpu].task = current;
-+	waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
-+	waiting_cpus[cpu].regs = regs;
-+
-+	spin_unlock_wait(waitlocks + cpu);
-+	/*
-+	 * log departure of this cpu
-+	 */
-+	waiting_cpus[cpu].task = 0;
-+	waiting_cpus[cpu].pid = 0;
-+	waiting_cpus[cpu].regs = 0;
-+	correct_hw_break();
-+      exit_in_kgdb:
-+	in_kgdb_here_log[cpu] = 0;
-+	kgdb_local_irq_restore(flags);
-+	return 1;
-+	/*
-+	   spin_unlock(continuelocks + smp_processor_id());
-+	 */
-+}
-+
-+void
-+smp__in_kgdb(struct pt_regs regs)
-+{
-+	ack_APIC_irq();
-+	in_kgdb(&regs);
-+}
-+#else
-+int
-+in_kgdb(struct pt_regs *regs)
-+{
-+	return (kgdb_spinlock);
-+}
-+#endif
-+
-+void
-+printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
-+{
-+	unsigned dr6;
-+	int i;
-+	switch (exceptionNo) {
-+	case 1:		/* debug exception */
-+		break;
-+	case 3:		/* breakpoint */
-+		sprintf(buffer, "Software breakpoint");
-+		return;
-+	default:
-+		sprintf(buffer, "Details not available");
-+		return;
-+	}
-+	asm volatile ("movl %%db6, %0\n":"=r" (dr6)
-+		      :);
-+	if (dr6 & 0x4000) {
-+		sprintf(buffer, "Single step");
-+		return;
-+	}
-+	for (i = 0; i < 4; ++i) {
-+		if (dr6 & (1 << i)) {
-+			sprintf(buffer, "Hardware breakpoint %d", i);
-+			return;
-+		}
-+	}
-+	sprintf(buffer, "Unknown trap");
-+	return;
-+}
-+
-+/*
-+ * This function does all command procesing for interfacing to gdb.
-+ *
-+ * NOTE:  The INT nn instruction leaves the state of the interrupt
-+ *	  enable flag UNCHANGED.  That means that when this routine
-+ *	  is entered via a breakpoint (INT 3) instruction from code
-+ *	  that has interrupts enabled, then interrupts will STILL BE
-+ *	  enabled when this routine is entered.	 The first thing that
-+ *	  we do here is disable interrupts so as to prevent recursive
-+ *	  entries and bothersome serial interrupts while we are
-+ *	  trying to run the serial port in polled mode.
-+ *
-+ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
-+ * it is always necessary to do a restore_flags before returning
-+ * so as to let go of that lock.
-+ */
-+int
-+kgdb_handle_exception(int exceptionVector,
-+		      int signo, int err_code, struct pt_regs *linux_regs)
-+{
-+	struct task_struct *usethread = NULL;
-+	struct task_struct *thread_list_start = 0, *thread = NULL;
-+	int addr, length;
-+	int breakno, breaktype;
-+	char *ptr;
-+	int newPC;
-+	threadref thref;
-+	int threadid;
-+	int thread_min = PID_MAX + MAX_NO_CPUS;
-+	int maxthreads;
-+	int nothreads;
-+	unsigned long flags;
-+	int gdb_regs[NUMREGBYTES / 4];
-+	int dr6;
-+	IF_SMP(int entry_state = 0);	/* 0, ok, 1, no nmi, 2 sync failed */
-+#define NO_NMI 1
-+#define NO_SYNC 2
-+#define	regs	(*linux_regs)
-+#define NUMREGS NUMREGBYTES/4
-+	/*
-+	 * If the entry is not from the kernel then return to the Linux
-+	 * trap handler and let it process the interrupt normally.
-+	 */
-+	if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
-+		printk("ignoring non-kernel exception\n");
-+		print_regs(&regs);
-+		return (0);
-+	}
-+
-+	kgdb_local_irq_save(flags);
-+
-+	/* Get kgdb spinlock */
-+
-+	KGDB_SPIN_LOCK(&kgdb_spinlock);
-+	rdtscll(kgdb_info.entry_tsc);
-+	/*
-+	 * We depend on this spinlock and the NMI watch dog to control the 
-+	 * other cpus.	They will arrive at "in_kgdb()" as a result of the
-+	 * NMI and will wait there for the following spin locks to be 
-+	 * released.
-+	 */
-+#ifdef CONFIG_SMP
-+
-+#if 0
-+	if (cpu_callout_map & ~MAX_CPU_MASK) {
-+		printk("kgdb : too many cpus, possibly not mapped"
-+		       " in contiguous space, change MAX_NO_CPUS"
-+		       " in kgdb_stub and make new kernel.\n"
-+		       " cpu_callout_map is %lx\n", cpu_callout_map);
-+		goto exit_just_unlock;
-+	}
-+#endif
-+	if (spinlock_count == 1) {
-+		int time, end_time, dum;
-+		int i;
-+		int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
-+		};
-+		if (remote_debug) {
-+			printk("kgdb : cpu %d entry, syncing others\n",
-+			       smp_processor_id());
-+		}
-+		for (i = 0; i < MAX_NO_CPUS; i++) {
-+			/*
-+			 * Use trylock as we may already hold the lock if
-+			 * we are holding the cpu.  Net result is all
-+			 * locked.
-+			 */
-+			spin_trylock(&waitlocks[i]);
-+		}
-+		for (i = 0; i < MAX_NO_CPUS; i++)
-+			cpu_logged_in[i] = 0;
-+		/*
-+		 * Wait for their arrival.  We know the watch dog is active if 
-+		 * in_kgdb() has ever been called, as it is always called on a 
-+		 * watchdog tick.
-+		 */
-+		rdtsc(dum, time);
-+		end_time = time + 2;	/* Note: we use the High order bits! */
-+		i = 1;
-+		if (num_online_cpus() > 1) {
-+			int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
-+			smp_send_nmi_allbutself();
-+			while (i < num_online_cpus() && time != end_time) {
-+				int j;
-+				for (j = 0; j < MAX_NO_CPUS; j++) {
-+					if (waiting_cpus[j].task &&
-+					    !cpu_logged_in[j]) {
-+						i++;
-+						cpu_logged_in[j] = 1;
-+						if (remote_debug) {
-+							printk
-+							    ("kgdb : cpu %d arrived at kgdb\n",
-+							     j);
-+						}
-+						break;
-+					} else if (!waiting_cpus[j].task &&
-+						   !cpu_online(j)) {
-+						waiting_cpus[j].task = NOCPU;
-+						cpu_logged_in[j] = 1;
-+						waiting_cpus[j].hold = 1;
-+						break;
-+					}
-+					if (!waiting_cpus[j].task &&
-+					    in_kgdb_here_log[j]) {
-+
-+						int wait = 100000;
-+						while (wait--) ;
-+						if (!waiting_cpus[j].task &&
-+						    in_kgdb_here_log[j]) {
-+							printk
-+							    ("kgdb : cpu %d stall"
-+							     " in in_kgdb\n",
-+							     j);
-+							i++;
-+							cpu_logged_in[j] = 1;
-+							waiting_cpus[j].task =
-+							    (struct task_struct
-+							     *) 1;
-+						}
-+					}
-+				}
-+
-+				if (in_kgdb_entry_log[smp_processor_id()] >
-+				    (me_in_kgdb + 10)) {
-+					break;
-+				}
-+
-+				rdtsc(dum, time);
-+			}
-+			if (i < num_online_cpus()) {
-+				printk
-+				    ("kgdb : time out, proceeding without sync\n");
-+#if 0
-+				printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
-+				       waiting_cpus[0].task != 0,
-+				       waiting_cpus[1].task != 0);
-+				printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
-+				       cpu_logged_in[0], cpu_logged_in[1]);
-+				printk
-+				    ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
-+				     in_kgdb_here_log[0] != 0,
-+				     in_kgdb_here_log[1] != 0);
-+#endif
-+				entry_state = NO_SYNC;
-+			} else {
-+#if 0
-+				int ent =
-+				    in_kgdb_entry_log[smp_processor_id()] -
-+				    me_in_kgdb;
-+				printk("kgdb : sync after %d entries\n", ent);
-+#endif
-+			}
-+		} else {
-+			if (remote_debug) {
-+				printk
-+				    ("kgdb : %d cpus, but watchdog not active\n"
-+				     "proceeding without locking down other cpus\n",
-+				     num_online_cpus());
-+				entry_state = NO_NMI;
-+			}
-+		}
-+	}
-+#endif
-+
-+	if (remote_debug) {
-+		unsigned long *lp = (unsigned long *) &linux_regs;
-+
-+		printk("handle_exception(exceptionVector=%d, "
-+		       "signo=%d, err_code=%d, linux_regs=%p)\n",
-+		       exceptionVector, signo, err_code, linux_regs);
-+		if (debug_regs) {
-+			print_regs(&regs);
-+			printk("Stk: %8lx %8lx %8lx %8lx"
-+			       "  %8lx %8lx %8lx %8lx\n",
-+			       lp[0], lp[1], lp[2], lp[3],
-+			       lp[4], lp[5], lp[6], lp[7]);
-+			printk("     %8lx %8lx %8lx %8lx"
-+			       "  %8lx %8lx %8lx %8lx\n",
-+			       lp[8], lp[9], lp[10], lp[11],
-+			       lp[12], lp[13], lp[14], lp[15]);
-+			printk("     %8lx %8lx %8lx %8lx  "
-+			       "%8lx %8lx %8lx %8lx\n",
-+			       lp[16], lp[17], lp[18], lp[19],
-+			       lp[20], lp[21], lp[22], lp[23]);
-+			printk("     %8lx %8lx %8lx %8lx  "
-+			       "%8lx %8lx %8lx %8lx\n",
-+			       lp[24], lp[25], lp[26], lp[27],
-+			       lp[28], lp[29], lp[30], lp[31]);
-+		}
-+	}
-+
-+	/* Disable hardware debugging while we are in kgdb */
-+	/* Get the debug register status register */
-+/*				       *INDENT-OFF*  */
-+      __asm__("movl %0,%%db7"
-+	      :	/* no output */
-+	      :"r"(0));
-+
-+	asm volatile ("movl %%db6, %0\n"
-+		      :"=r" (hw_breakpoint_status)
-+		      :);
-+
-+/*				       *INDENT-ON*  */
-+	switch (exceptionVector) {
-+	case 0:		/* divide error */
-+	case 1:		/* debug exception */
-+	case 2:		/* NMI */
-+	case 3:		/* breakpoint */
-+	case 4:		/* overflow */
-+	case 5:		/* bounds check */
-+	case 6:		/* invalid opcode */
-+	case 7:		/* device not available */
-+	case 8:		/* double fault (errcode) */
-+	case 10:		/* invalid TSS (errcode) */
-+	case 12:		/* stack fault (errcode) */
-+	case 16:		/* floating point error */
-+	case 17:		/* alignment check (errcode) */
-+	default:		/* any undocumented */
-+		break;
-+	case 11:		/* segment not present (errcode) */
-+	case 13:		/* general protection (errcode) */
-+	case 14:		/* page fault (special errcode) */
-+	case 19:		/* cache flush denied */
-+		if (mem_err_expected) {
-+			/*
-+			 * This fault occured because of the
-+			 * get_char or set_char routines.  These
-+			 * two routines use either eax of edx to
-+			 * indirectly reference the location in
-+			 * memory that they are working with.
-+			 * For a page fault, when we return the
-+			 * instruction will be retried, so we
-+			 * have to make sure that these
-+			 * registers point to valid memory. 
-+			 */
-+			mem_err = 1;	/* set mem error flag */
-+			mem_err_expected = 0;
-+			mem_err_cnt++;	/* helps in debugging */
-+			/* make valid address */
-+			regs.eax = (long) &garbage_loc;
-+			/* make valid address */
-+			regs.edx = (long) &garbage_loc;
-+			if (remote_debug)
-+				printk("Return after memory error: "
-+				       "mem_err_cnt=%d\n", mem_err_cnt);
-+			if (debug_regs)
-+				print_regs(&regs);
-+			goto exit_kgdb;
-+		}
-+		break;
-+	}
-+	if (remote_debug)
-+		printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
-+
-+	gdb_i386vector = exceptionVector;
-+	gdb_i386errcode = err_code;
-+	kgdb_info.called_from = __builtin_return_address(0);
-+#ifdef CONFIG_SMP
-+	/*
-+	 * OK, we can now communicate, lets tell gdb about the sync.
-+	 * but only if we had a problem.
-+	 */
-+	switch (entry_state) {
-+	case NO_NMI:
-+		to_gdb("NMI not active, other cpus not stopped\n");
-+		break;
-+	case NO_SYNC:
-+		to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
-+	default:;
-+	}
-+
-+#endif
-+/*
-+ * Set up the gdb function call area.
-+ */
-+	trap_cpu = smp_processor_id();
-+	OLD_esp = NEW_esp = (int) (&linux_regs->esp);
-+
-+      IF_SMP(once_again:)
-+	    /* reply to host that an exception has occurred */
-+	    remcomOutBuffer[0] = 'S';
-+	remcomOutBuffer[1] = hexchars[signo >> 4];
-+	remcomOutBuffer[2] = hexchars[signo % 16];
-+	remcomOutBuffer[3] = 0;
-+
-+	putpacket(remcomOutBuffer);
-+
-+	while (1 == 1) {
-+		error = 0;
-+		remcomOutBuffer[0] = 0;
-+		getpacket(remcomInBuffer);
-+		switch (remcomInBuffer[0]) {
-+		case '?':
-+			remcomOutBuffer[0] = 'S';
-+			remcomOutBuffer[1] = hexchars[signo >> 4];
-+			remcomOutBuffer[2] = hexchars[signo % 16];
-+			remcomOutBuffer[3] = 0;
-+			break;
-+		case 'd':
-+			remote_debug = !(remote_debug);	/* toggle debug flag */
-+			printk("Remote debug %s\n",
-+			       remote_debug ? "on" : "off");
-+			break;
-+		case 'g':	/* return the value of the CPU registers */
-+			get_gdb_regs(usethread, &regs, gdb_regs);
-+			mem2hex((char *) gdb_regs,
-+				remcomOutBuffer, NUMREGBYTES, 0);
-+			break;
-+		case 'G':	/* set the value of the CPU registers - return OK */
-+			hex2mem(&remcomInBuffer[1],
-+				(char *) gdb_regs, NUMREGBYTES, 0);
-+			if (!usethread || usethread == current) {
-+				gdb_regs_to_regs(gdb_regs, &regs);
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "E00");
-+			}
-+			break;
-+
-+		case 'P':{	/* set the value of a single CPU register - 
-+				   return OK */
-+				/*
-+				 * For some reason, gdb wants to talk about psudo
-+				 * registers (greater than 15).	 These may have
-+				 * meaning for ptrace, but for us it is safe to
-+				 * ignor them.	We do this by dumping them into
-+				 * _GS which we also ignor, but do have memory for.
-+				 */
-+				int regno;
-+
-+				ptr = &remcomInBuffer[1];
-+				regs_to_gdb_regs(gdb_regs, &regs);
-+				if ((!usethread || usethread == current) &&
-+				    hexToInt(&ptr, &regno) &&
-+				    *ptr++ == '=' && (regno >= 0)) {
-+					regno =
-+					    (regno >= NUMREGS ? _GS : regno);
-+					hex2mem(ptr, (char *) &gdb_regs[regno],
-+						4, 0);
-+					gdb_regs_to_regs(gdb_regs, &regs);
-+					strcpy(remcomOutBuffer, "OK");
-+					break;
-+				}
-+				strcpy(remcomOutBuffer, "E01");
-+				break;
-+			}
-+
-+			/* mAA..AA,LLLL	 Read LLLL bytes at address AA..AA */
-+		case 'm':
-+			/* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr) &&
-+			    (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
-+				ptr = 0;
-+				/*
-+				 * hex doubles the byte count
-+				 */
-+				if (length > (BUFMAX / 2))
-+					length = BUFMAX / 2;
-+				mem2hex((char *) addr,
-+					remcomOutBuffer, length, 1);
-+				if (mem_err) {
-+					strcpy(remcomOutBuffer, "E03");
-+					debug_error("memory fault\n", NULL);
-+				}
-+			}
-+
-+			if (ptr) {
-+				strcpy(remcomOutBuffer, "E01");
-+				debug_error
-+				    ("malformed read memory command: %s\n",
-+				     remcomInBuffer);
-+			}
-+			break;
-+
-+			/* MAA..AA,LLLL: 
-+			   Write LLLL bytes at address AA.AA return OK */
-+		case 'M':
-+			/* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr) &&
-+			    (*(ptr++) == ',') &&
-+			    (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
-+				hex2mem(ptr, (char *) addr, length, 1);
-+
-+				if (mem_err) {
-+					strcpy(remcomOutBuffer, "E03");
-+					debug_error("memory fault\n", NULL);
-+				} else {
-+					strcpy(remcomOutBuffer, "OK");
-+				}
-+
-+				ptr = 0;
-+			}
-+			if (ptr) {
-+				strcpy(remcomOutBuffer, "E02");
-+				debug_error
-+				    ("malformed write memory command: %s\n",
-+				     remcomInBuffer);
-+			}
-+			break;
-+
-+			/* cAA..AA  Continue at address AA..AA(optional) */
-+			/* sAA..AA  Step one instruction from AA..AA(optional) */
-+			/* D	    detach, reply OK and then continue */
-+		case 'c':
-+		case 's':
-+		case 'D':
-+
-+			/* try to read optional parameter, 
-+			   pc unchanged if no parm */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr)) {
-+				if (remote_debug)
-+					printk("Changing EIP to 0x%x\n", addr);
-+
-+				regs.eip = addr;
-+			}
-+
-+			newPC = regs.eip;
-+
-+			/* clear the trace bit */
-+			regs.eflags &= 0xfffffeff;
-+
-+			/* set the trace bit if we're stepping */
-+			if (remcomInBuffer[0] == 's')
-+				regs.eflags |= 0x100;
-+
-+			/* detach is a friendly version of continue. Note that
-+			   debugging is still enabled (e.g hit control C)
-+			   until the process that issued an ioctl TIOCGDB
-+			   terminates
-+			 */
-+			if (remcomInBuffer[0] == 'D') {
-+				strcpy(remcomOutBuffer, "OK");
-+				putpacket(remcomOutBuffer);
-+			}
-+
-+			if (remote_debug) {
-+				printk("Resuming execution\n");
-+				print_regs(&regs);
-+			}
-+			asm volatile ("movl %%db6, %0\n":"=r" (dr6)
-+				      :);
-+			if (!(dr6 & 0x4000)) {
-+				for (breakno = 0; breakno < 4; ++breakno) {
-+					if (dr6 & (1 << breakno) &&
-+					    (breakinfo[breakno].type == 0)) {
-+						/* Set restore flag */
-+						regs.eflags |= 0x10000;
-+						break;
-+					}
-+				}
-+			}
-+			correct_hw_break();
-+			asm volatile ("movl %0, %%db6\n"::"r" (0));
-+			goto exit_kgdb;
-+
-+			/* kill the program */
-+		case 'k':	/* do nothing */
-+			break;
-+
-+			/* query */
-+		case 'q':
-+			switch (remcomInBuffer[1]) {
-+			case 'L':
-+				/* List threads */
-+				thread_list = 2;
-+				thread_list_start = (usethread ? : current);
-+				unpack_byte(remcomInBuffer + 3, &maxthreads);
-+				unpack_threadid(remcomInBuffer + 5, &thref);
-+				do {
-+					int buf_thread_limit =
-+					    (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
-+					if (maxthreads > buf_thread_limit) {
-+						maxthreads = buf_thread_limit;
-+					}
-+				} while (0);
-+				remcomOutBuffer[0] = 'q';
-+				remcomOutBuffer[1] = 'M';
-+				remcomOutBuffer[4] = '0';
-+				pack_threadid(remcomOutBuffer + 5, &thref);
-+
-+				threadid = threadref_to_int(&thref);
-+				for (nothreads = 0;
-+				     nothreads < maxthreads &&
-+				     threadid < PID_MAX + MAX_NO_CPUS;
-+				     threadid++) {
-+					thread = getthread(threadid);
-+					if (thread) {
-+						int_to_threadref(&thref,
-+								 threadid);
-+						pack_threadid(remcomOutBuffer +
-+							      21 +
-+							      nothreads * 16,
-+							      &thref);
-+						nothreads++;
-+						if (thread_min > threadid)
-+							thread_min = threadid;
-+					}
-+				}
-+
-+				if (threadid == PID_MAX + MAX_NO_CPUS) {
-+					remcomOutBuffer[4] = '1';
-+				}
-+				pack_hex_byte(remcomOutBuffer + 2, nothreads);
-+				remcomOutBuffer[21 + nothreads * 16] = '\0';
-+				break;
-+
-+			case 'C':
-+				/* Current thread id */
-+				remcomOutBuffer[0] = 'Q';
-+				remcomOutBuffer[1] = 'C';
-+				threadid = current->pid;
-+				if (!threadid) {
-+					/*
-+					 * idle thread
-+					 */
-+					for (threadid = PID_MAX;
-+					     threadid < PID_MAX + MAX_NO_CPUS;
-+					     threadid++) {
-+						if (current ==
-+						    idle_task(threadid -
-+							      PID_MAX))
-+							break;
-+					}
-+				}
-+				int_to_threadref(&thref, threadid);
-+				pack_threadid(remcomOutBuffer + 2, &thref);
-+				remcomOutBuffer[18] = '\0';
-+				break;
-+
-+			case 'E':
-+				/* Print exception info */
-+				printexceptioninfo(exceptionVector,
-+						   err_code, remcomOutBuffer);
-+				break;
-+			}
-+			break;
-+
-+			/* task related */
-+		case 'H':
-+			switch (remcomInBuffer[1]) {
-+			case 'g':
-+				ptr = &remcomInBuffer[2];
-+				hexToInt(&ptr, &threadid);
-+				thread = getthread(threadid);
-+				if (!thread) {
-+					remcomOutBuffer[0] = 'E';
-+					remcomOutBuffer[1] = '\0';
-+					break;
-+				}
-+				/*
-+				 * Just in case I forget what this is all about,
-+				 * the "thread info" command to gdb causes it
-+				 * to ask for a thread list.  It then switches
-+				 * to each thread and asks for the registers.
-+				 * For this (and only this) usage, we want to
-+				 * fudge the registers of tasks not on the run
-+				 * list (i.e. waiting) to show the routine that
-+				 * called schedule. Also, gdb, is a minimalist
-+				 * in that if the current thread is the last
-+				 * it will not re-read the info when done.
-+				 * This means that in this case we must show
-+				 * the real registers. So here is how we do it:
-+				 * Each entry we keep track of the min
-+				 * thread in the list (the last that gdb will)
-+				 * get info for.  We also keep track of the
-+				 * starting thread.
-+				 * "thread_list" is cleared when switching back
-+				 * to the min thread if it is was current, or
-+				 * if it was not current, thread_list is set 
-+				 * to 1.  When the switch to current comes,
-+				 * if thread_list is 1, clear it, else do 
-+				 * nothing.
-+				 */
-+				usethread = thread;
-+				if ((thread_list == 1) &&
-+				    (thread == thread_list_start)) {
-+					thread_list = 0;
-+				}
-+				if (thread_list && (threadid == thread_min)) {
-+					if (thread == thread_list_start) {
-+						thread_list = 0;
-+					} else {
-+						thread_list = 1;
-+					}
-+				}
-+				/* follow through */
-+			case 'c':
-+				remcomOutBuffer[0] = 'O';
-+				remcomOutBuffer[1] = 'K';
-+				remcomOutBuffer[2] = '\0';
-+				break;
-+			}
-+			break;
-+
-+			/* Query thread status */
-+		case 'T':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &threadid);
-+			thread = getthread(threadid);
-+			if (thread) {
-+				remcomOutBuffer[0] = 'O';
-+				remcomOutBuffer[1] = 'K';
-+				remcomOutBuffer[2] = '\0';
-+				if (thread_min > threadid)
-+					thread_min = threadid;
-+			} else {
-+				remcomOutBuffer[0] = 'E';
-+				remcomOutBuffer[1] = '\0';
-+			}
-+			break;
-+
-+		case 'Y':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &breakno);
-+			ptr++;
-+			hexToInt(&ptr, &breaktype);
-+			ptr++;
-+			hexToInt(&ptr, &length);
-+			ptr++;
-+			hexToInt(&ptr, &addr);
-+			if (set_hw_break(breakno & 0x3,
-+					 breaktype & 0x3,
-+					 length & 0x3, addr) == 0) {
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "ERROR");
-+			}
-+			break;
-+
-+			/* Remove hardware breakpoint */
-+		case 'y':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &breakno);
-+			if (remove_hw_break(breakno & 0x3) == 0) {
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "ERROR");
-+			}
-+			break;
-+
-+		case 'r':	/* reboot */
-+			strcpy(remcomOutBuffer, "OK");
-+			putpacket(remcomOutBuffer);
-+			/*to_gdb("Rebooting\n"); */
-+			/* triplefault	 no return from here */
-+			{
-+				static long no_idt[2];
-+				__asm__ __volatile__("lidt %0"::"m"(no_idt));
-+				BREAKPOINT;
-+			}
-+
-+		}		/* switch */
-+
-+		/* reply to the request */
-+		putpacket(remcomOutBuffer);
-+	}			/* while(1==1) */
-+	/*
-+	 *  reached by goto only.
-+	 */
-+      exit_kgdb:
-+	/*
-+	 * Here is where we set up to trap a gdb function call.	 NEW_esp
-+	 * will be changed if we are trying to do this.	 We handle both
-+	 * adding and subtracting, thus allowing gdb to put grung on 
-+	 * the stack which it removes later.
-+	 */
-+	if (NEW_esp != OLD_esp) {
-+		int *ptr = END_OF_LOOKASIDE;
-+		if (NEW_esp < OLD_esp)
-+			ptr -= (OLD_esp - NEW_esp) / sizeof (int);
-+		*--ptr = linux_regs->eflags;
-+		*--ptr = linux_regs->xcs;
-+		*--ptr = linux_regs->eip;
-+		*--ptr = linux_regs->ecx;
-+		*--ptr = linux_regs->ebx;
-+		*--ptr = linux_regs->eax;
-+		linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
-+		linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
-+		if (NEW_esp < OLD_esp) {
-+			linux_regs->eip = (unsigned int) fn_call_stub;
-+		} else {
-+			linux_regs->eip = (unsigned int) fn_rtn_stub;
-+			linux_regs->eax = NEW_esp;
-+		}
-+		linux_regs->eflags &= ~(IF_BIT | TF_BIT);
-+	}
-+#ifdef CONFIG_SMP
-+	/*
-+	 * Release gdb wait locks 
-+	 * Sanity check time.  Must have at least one cpu to run.  Also single
-+	 * step must not be done if the current cpu is on hold.
-+	 */
-+	if (spinlock_count == 1) {
-+		int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
-+		int cpu_avail = 0;
-+		int i;
-+
-+		for (i = 0; i < MAX_NO_CPUS; i++) {
-+			if (!cpu_online(i))
-+				break;
-+			if (!hold_cpu(i)) {
-+				cpu_avail = 1;
-+			}
-+		}
-+		/*
-+		 * Early in the bring up there will be NO cpus on line...
-+		 */
-+		if (!cpu_avail && !cpus_empty(cpu_online_map)) {
-+			to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
-+			goto once_again;
-+		}
-+		if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
-+			to_gdb
-+			    ("Current cpu must be unblocked to single step\n");
-+			goto once_again;
-+		}
-+		if (!(ss_hold)) {
-+			int i;
-+			for (i = 0; i < MAX_NO_CPUS; i++) {
-+				if (!hold_cpu(i)) {
-+					spin_unlock(&waitlocks[i]);
-+				}
-+			}
-+		} else {
-+			spin_unlock(&waitlocks[smp_processor_id()]);
-+		}
-+		/* Release kgdb spinlock */
-+		KGDB_SPIN_UNLOCK(&kgdb_spinlock);
-+		/*
-+		 * If this cpu is on hold, this is where we
-+		 * do it.  Note, the NMI will pull us out of here,
-+		 * but will return as the above lock is not held.
-+		 * We will stay here till another cpu releases the lock for us.
-+		 */
-+		spin_unlock_wait(waitlocks + smp_processor_id());
-+		kgdb_local_irq_restore(flags);
-+		return (0);
-+	}
-+#if 0
-+exit_just_unlock:
-+#endif
-+#endif
-+	/* Release kgdb spinlock */
-+	KGDB_SPIN_UNLOCK(&kgdb_spinlock);
-+	kgdb_local_irq_restore(flags);
-+	return (0);
-+}
-+
-+/* this function is used to set up exception handlers for tracing and
-+ * breakpoints. 
-+ * This function is not needed as the above line does all that is needed.
-+ * We leave it for backward compatitability...
-+ */
-+void
-+set_debug_traps(void)
-+{
-+	/*
-+	 * linux_debug_hook is defined in traps.c.  We store a pointer
-+	 * to our own exception handler into it.
-+
-+	 * But really folks, every hear of labeled common, an old Fortran
-+	 * concept.  Lots of folks can reference it and it is define if 
-+	 * anyone does.	 Only one can initialize it at link time.  We do 
-+	 * this with the hook.	See the statement above.  No need for any
-+	 * executable code and it is ready as soon as the kernel is
-+	 * loaded.  Very desirable in kernel debugging.
-+
-+	 linux_debug_hook = handle_exception ;
-+	 */
-+
-+	/* In case GDB is started before us, ack any packets (presumably
-+	   "$?#xx") sitting there. 
-+	   putDebugChar ('+');
-+
-+	   initialized = 1;
-+	 */
-+}
-+
-+/* This function will generate a breakpoint exception.	It is used at the
-+   beginning of a program to sync up with a debugger and can be used
-+   otherwise as a quick means to stop program execution and "break" into
-+   the debugger. */
-+/* But really, just use the BREAKPOINT macro.  We will handle the int stuff
-+ */
-+
-+#ifdef later
-+/*
-+ * possibly we should not go thru the traps.c code at all?  Someday.
-+ */
-+void
-+do_kgdb_int3(struct pt_regs *regs, long error_code)
-+{
-+	kgdb_handle_exception(3, 5, error_code, regs);
-+	return;
-+}
-+#endif
-+#undef regs
-+#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-+asmlinkage void
-+bad_sys_call_exit(int stuff)
-+{
-+	struct pt_regs *regs = (struct pt_regs *) &stuff;
-+	printk("Sys call %d return with %x preempt_count\n",
-+	       (int) regs->orig_eax, preempt_count());
-+}
-+#endif
-+#ifdef CONFIG_STACK_OVERFLOW_TEST
-+#include <asm/kgdb.h>
-+asmlinkage void
-+stack_overflow(void)
-+{
-+#ifdef BREAKPOINT
-+	BREAKPOINT;
-+#else
-+	printk("Kernel stack overflow, looping forever\n");
-+#endif
-+	while (1) {
-+	}
-+}
-+#endif
-+
-+#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
-+char gdbconbuf[BUFMAX];
-+
-+static void
-+kgdb_gdb_message(const char *s, unsigned count)
-+{
-+	int i;
-+	int wcount;
-+	char *bufptr;
-+	/*
-+	 * This takes care of NMI while spining out chars to gdb
-+	 */
-+	IF_SMP(in_kgdb_console = 1);
-+	gdbconbuf[0] = 'O';
-+	bufptr = gdbconbuf + 1;
-+	while (count > 0) {
-+		if ((count << 1) > (BUFMAX - 2)) {
-+			wcount = (BUFMAX - 2) >> 1;
-+		} else {
-+			wcount = count;
-+		}
-+		count -= wcount;
-+		for (i = 0; i < wcount; i++) {
-+			bufptr = pack_hex_byte(bufptr, s[i]);
-+		}
-+		*bufptr = '\0';
-+		s += wcount;
-+
-+		putpacket(gdbconbuf);
-+
-+	}
-+	IF_SMP(in_kgdb_console = 0);
-+}
-+#endif
-+#ifdef CONFIG_SMP
-+static void
-+to_gdb(const char *s)
-+{
-+	int count = 0;
-+	while (s[count] && (count++ < BUFMAX)) ;
-+	kgdb_gdb_message(s, count);
-+}
-+#endif
-+#ifdef CONFIG_KGDB_CONSOLE
-+#include <linux/console.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+void
-+kgdb_console_write(struct console *co, const char *s, unsigned count)
-+{
-+
-+	if (gdb_i386vector == -1) {
-+		/*
-+		 * We have not yet talked to gdb.  What to do...
-+		 * lets break, on continue we can do the write.
-+		 * But first tell him whats up. Uh, well no can do,
-+		 * as this IS the console.  Oh well...
-+		 * We do need to wait or the messages will be lost.
-+		 * Other option would be to tell the above code to
-+		 * ignore this breakpoint and do an auto return, 
-+		 * but that might confuse gdb.	Also this happens 
-+		 * early enough in boot up that we don't have the traps
-+		 * set up yet, so...
-+		 */
-+		breakpoint();
-+	}
-+	kgdb_gdb_message(s, count);
-+}
-+
-+/*
-+ * ------------------------------------------------------------
-+ * Serial KGDB driver 
-+ * ------------------------------------------------------------
-+ */
-+
-+static struct console kgdbcons = {
-+	name:"kgdb",
-+	write:kgdb_console_write,
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+	device:kgdb_console_device,
-+#endif
-+	flags:CON_PRINTBUFFER | CON_ENABLED,
-+	index:-1,
-+};
-+
-+/*
-+ * The trick here is that this file gets linked before printk.o
-+ * That means we get to peer at the console info in the command
-+ * line before it does.	 If we are up, we register, otherwise,
-+ * do nothing.	By returning 0, we allow printk to look also.
-+ */
-+static int kgdb_console_enabled;
-+
-+int __init
-+kgdb_console_init(char *str)
-+{
-+	if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
-+		register_console(&kgdbcons);
-+		kgdb_console_enabled = 1;
-+	}
-+	return 0;		/* let others look at the string */
-+}
-+
-+__setup("console=", kgdb_console_init);
-+
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+static kdev_t kgdb_console_device(struct console *c);
-+/* This stuff sort of works, but it knocks out telnet devices  
-+ * we are leaving it here in case we (or you) find time to figure it out
-+ * better..
-+ */
-+
-+/*
-+ * We need a real char device as well for when the console is opened for user
-+ * space activities.
-+ */
-+
-+static int
-+kgdb_consdev_open(struct inode *inode, struct file *file)
-+{
-+	return 0;
-+}
-+
-+static ssize_t
-+kgdb_consdev_write(struct file *file, const char *buf,
-+		   size_t count, loff_t * ppos)
-+{
-+	int size, ret = 0;
-+	static char kbuf[128];
-+	static DECLARE_MUTEX(sem);
-+
-+	/* We are not reentrant... */
-+	if (down_interruptible(&sem))
-+		return -ERESTARTSYS;
-+
-+	while (count > 0) {
-+		/* need to copy the data from user space */
-+		size = count;
-+		if (size > sizeof (kbuf))
-+			size = sizeof (kbuf);
-+		if (copy_from_user(kbuf, buf, size)) {
-+			ret = -EFAULT;
-+			break;;
-+		}
-+		kgdb_console_write(&kgdbcons, kbuf, size);
-+		count -= size;
-+		ret += size;
-+		buf += size;
-+	}
-+
-+	up(&sem);
-+
-+	return ret;
-+}
-+
-+struct file_operations kgdb_consdev_fops = {
-+	open:kgdb_consdev_open,
-+	write:kgdb_consdev_write
-+};
-+static kdev_t
-+kgdb_console_device(struct console *c)
-+{
-+	return MKDEV(TTYAUX_MAJOR, 1);
-+}
-+
-+/*
-+ * This routine gets called from the serial stub in the i386/lib 
-+ * This is so it is done late in bring up (just before the console open).
-+ */
-+void
-+kgdb_console_finit(void)
-+{
-+	if (kgdb_console_enabled) {
-+		char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
-+		char *cp = cptr;
-+		while (*cptr && *cptr != '(')
-+			cptr++;
-+		*cptr = 0;
-+		unregister_chrdev(TTYAUX_MAJOR, cp);
-+		register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
-+	}
-+}
-+#endif
-+#endif
-+#ifdef CONFIG_KGDB_TS
-+#include <asm/msr.h>		/* time stamp code */
-+#include <asm/hardirq.h>	/* in_interrupt */
-+#ifdef CONFIG_KGDB_TS_64
-+#define DATA_POINTS 64
-+#endif
-+#ifdef CONFIG_KGDB_TS_128
-+#define DATA_POINTS 128
-+#endif
-+#ifdef CONFIG_KGDB_TS_256
-+#define DATA_POINTS 256
-+#endif
-+#ifdef CONFIG_KGDB_TS_512
-+#define DATA_POINTS 512
-+#endif
-+#ifdef CONFIG_KGDB_TS_1024
-+#define DATA_POINTS 1024
-+#endif
-+#ifndef DATA_POINTS
-+#define DATA_POINTS 128		/* must be a power of two */
-+#endif
-+#define INDEX_MASK (DATA_POINTS - 1)
-+#if (INDEX_MASK & DATA_POINTS)
-+#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
-+#endif
-+struct kgdb_and_then_struct {
-+#ifdef CONFIG_SMP
-+	int on_cpu;
-+#endif
-+	struct task_struct *task;
-+	long long at_time;
-+	int from_ln;
-+	char *in_src;
-+	void *from;
-+	int *with_shpf;
-+	int data0;
-+	int data1;
-+};
-+struct kgdb_and_then_struct2 {
-+#ifdef CONFIG_SMP
-+	int on_cpu;
-+#endif
-+	struct task_struct *task;
-+	long long at_time;
-+	int from_ln;
-+	char *in_src;
-+	void *from;
-+	int *with_shpf;
-+	struct task_struct *t1;
-+	struct task_struct *t2;
-+};
-+struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
-+
-+struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
-+int kgdb_and_then_count;
-+
-+void
-+kgdb_tstamp(int line, char *source, int data0, int data1)
-+{
-+	static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
-+	int flags;
-+	kgdb_local_irq_save(flags);
-+	spin_lock(&ts_spin);
-+	rdtscll(kgdb_and_then->at_time);
-+#ifdef CONFIG_SMP
-+	kgdb_and_then->on_cpu = smp_processor_id();
-+#endif
-+	kgdb_and_then->task = current;
-+	kgdb_and_then->from_ln = line;
-+	kgdb_and_then->in_src = source;
-+	kgdb_and_then->from = __builtin_return_address(0);
-+	kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
-+					    (preempt_count() << 8));
-+	kgdb_and_then->data0 = data0;
-+	kgdb_and_then->data1 = data1;
-+	kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
-+	spin_unlock(&ts_spin);
-+	kgdb_local_irq_restore(flags);
-+#ifdef CONFIG_PREEMPT
-+
-+#endif
-+	return;
-+}
-+#endif
-+typedef int gdb_debug_hook(int exceptionVector,
-+			   int signo, int err_code, struct pt_regs *linux_regs);
-+gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;	/* histerical reasons... */
---- linux-2.6.0-test1/arch/i386/kernel/ldt.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/arch/i386/kernel/ldt.c	2003-07-19 17:04:06.000000000 -0700
-@@ -56,9 +56,11 @@ static int alloc_ldt(mm_context_t *pc, i
- 
- 	if (reload) {
- #ifdef CONFIG_SMP
-+		cpumask_t mask;
- 		preempt_disable();
- 		load_LDT(pc);
--		if (current->mm->cpu_vm_mask != (1 << smp_processor_id()))
-+		mask = cpumask_of_cpu(smp_processor_id());
-+		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, 0, 1, 1);
- 		preempt_enable();
- #else
---- linux-2.6.0-test1/arch/i386/kernel/Makefile	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/i386/kernel/Makefile	2003-07-19 17:04:02.000000000 -0700
-@@ -14,6 +14,7 @@ obj-y				+= timers/
- obj-$(CONFIG_ACPI)		+= acpi/
- obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
- obj-$(CONFIG_MCA)		+= mca.o
-+obj-$(CONFIG_KGDB)		+= kgdb_stub.o 
- obj-$(CONFIG_X86_MSR)		+= msr.o
- obj-$(CONFIG_X86_CPUID)		+= cpuid.o
- obj-$(CONFIG_MICROCODE)		+= microcode.o
---- linux-2.6.0-test1/arch/i386/kernel/mpparse.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/i386/kernel/mpparse.c	2003-07-19 17:04:06.000000000 -0700
-@@ -71,7 +71,7 @@ unsigned int boot_cpu_logical_apicid = -
- static unsigned int __initdata num_processors;
- 
- /* Bitmask of physically existing CPUs */
--unsigned long phys_cpu_present_map;
-+physid_mask_t phys_cpu_present_map;
- 
- u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
- 
-@@ -106,6 +106,7 @@ static struct mpc_config_translation *tr
- void __init MP_processor_info (struct mpc_config_processor *m)
- {
-  	int ver, apicid;
-+	physid_mask_t tmp;
-  	
- 	if (!(m->mpc_cpuflag & CPU_ENABLED))
- 		return;
-@@ -176,7 +177,8 @@ void __init MP_processor_info (struct mp
- 	}
- 	ver = m->mpc_apicver;
- 
--	phys_cpu_present_map |= apicid_to_cpu_present(apicid);
-+	tmp = apicid_to_cpu_present(apicid);
-+	physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
- 	
- 	/*
- 	 * Validate version
---- linux-2.6.0-test1/arch/i386/kernel/msr.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/arch/i386/kernel/msr.c	2003-07-19 17:04:06.000000000 -0700
-@@ -242,7 +242,7 @@ static int msr_open(struct inode *inode,
-   int cpu = minor(file->f_dentry->d_inode->i_rdev);
-   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
-   
--  if ( !(cpu_online_map & (1UL << cpu)) )
-+  if (!cpu_online(cpu))
-     return -ENXIO;		/* No such CPU */
-   if ( !cpu_has(c, X86_FEATURE_MSR) )
-     return -EIO;		/* MSR not supported */
---- linux-2.6.0-test1/arch/i386/kernel/nmi.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/kernel/nmi.c	2003-07-19 17:04:02.000000000 -0700
-@@ -31,7 +31,17 @@
- #include <asm/mpspec.h>
- #include <asm/nmi.h>
- 
-+#ifdef CONFIG_KGDB
-+#include <asm/kgdb.h>
-+#ifdef CONFIG_SMP
-+unsigned int nmi_watchdog = NMI_IO_APIC;
-+#else
-+unsigned int nmi_watchdog = NMI_LOCAL_APIC;
-+#endif
-+#else
- unsigned int nmi_watchdog = NMI_NONE;
-+#endif
-+
- static unsigned int nmi_hz = HZ;
- unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
- extern void show_registers(struct pt_regs *regs);
-@@ -396,6 +406,9 @@ void touch_nmi_watchdog (void)
- 	for (i = 0; i < NR_CPUS; i++)
- 		alert_counter[i] = 0;
- }
-+#ifdef CONFIG_KGDB
-+int tune_watchdog = 5*HZ;
-+#endif
- 
- void nmi_watchdog_tick (struct pt_regs * regs)
- {
-@@ -409,12 +422,24 @@ void nmi_watchdog_tick (struct pt_regs *
- 
- 	sum = irq_stat[cpu].apic_timer_irqs;
- 
-+#ifdef CONFIG_KGDB
-+ 	if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
-+  
-+#else
- 	if (last_irq_sums[cpu] == sum) {
-+#endif
- 		/*
- 		 * Ayiee, looks like this CPU is stuck ...
- 		 * wait a few IRQs (5 seconds) before doing the oops ...
- 		 */
- 		alert_counter[cpu]++;
-+#ifdef CONFIG_KGDB
-+                if (alert_counter[cpu] == tune_watchdog) {                      
-+                        kgdb_handle_exception(2, SIGPWR, 0, regs);
-+                        last_irq_sums[cpu] = sum;
-+                        alert_counter[cpu] = 0;
-+                }
-+#endif
- 		if (alert_counter[cpu] == 5*nmi_hz) {
- 			spin_lock(&nmi_print_lock);
- 			/*
---- linux-2.6.0-test1/arch/i386/kernel/reboot.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/arch/i386/kernel/reboot.c	2003-07-19 17:04:06.000000000 -0700
-@@ -226,7 +226,7 @@ void machine_restart(char * __unused)
- 		   if its not, default to the BSP */
- 		if ((reboot_cpu == -1) ||  
- 		      (reboot_cpu > (NR_CPUS -1))  || 
--		      !(phys_cpu_present_map & (1<<cpuid))) 
-+		      !cpu_isset(cpuid, phys_cpu_present_map))
- 			reboot_cpu = boot_cpu_physical_apicid;
- 
- 		reboot_smp = 0;  /* use this as a flag to only go through this once*/
---- linux-2.6.0-test1/arch/i386/kernel/setup.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/i386/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -42,6 +42,7 @@
- #include <asm/edd.h>
- #include <asm/setup.h>
- #include <asm/arch_hooks.h>
-+#include <asm/sections.h>
- #include "setup_arch_pre.h"
- #include "mach_resources.h"
- 
-@@ -100,7 +101,7 @@ extern void early_cpu_init(void);
- extern void dmi_scan_machine(void);
- extern void generic_apic_probe(char *);
- extern int root_mountflags;
--extern char _text, _etext, _edata, _end;
-+extern char _end[];
- 
- unsigned long saved_videomode;
- 
-@@ -520,7 +521,7 @@ static void __init parse_cmdline_early (
- 			acpi_disabled = 1;
- 
- 		/* "acpismp=force" turns on ACPI again */
--		else if (!memcmp(from, "acpismp=force", 14))
-+		if (c == ' ' && !memcmp(from, "acpismp=force", 13))
- 			acpi_disabled = 0;
- 
- 		/*
-@@ -676,7 +677,7 @@ static unsigned long __init setup_memory
- 	 * partially used pages are not usable - thus
- 	 * we are rounding upwards:
- 	 */
--	start_pfn = PFN_UP(__pa(&_end));
-+	start_pfn = PFN_UP(__pa(_end));
- 
- 	find_max_pfn();
- 
-@@ -947,15 +948,15 @@ void __init setup_arch(char **cmdline_p)
- 
- 	if (!MOUNT_ROOT_RDONLY)
- 		root_mountflags &= ~MS_RDONLY;
--	init_mm.start_code = (unsigned long) &_text;
--	init_mm.end_code = (unsigned long) &_etext;
--	init_mm.end_data = (unsigned long) &_edata;
--	init_mm.brk = (unsigned long) &_end;
--
--	code_resource.start = virt_to_phys(&_text);
--	code_resource.end = virt_to_phys(&_etext)-1;
--	data_resource.start = virt_to_phys(&_etext);
--	data_resource.end = virt_to_phys(&_edata)-1;
-+	init_mm.start_code = (unsigned long) _text;
-+	init_mm.end_code = (unsigned long) _etext;
-+	init_mm.end_data = (unsigned long) _edata;
-+	init_mm.brk = (unsigned long) _end;
-+
-+	code_resource.start = virt_to_phys(_text);
-+	code_resource.end = virt_to_phys(_etext)-1;
-+	data_resource.start = virt_to_phys(_etext);
-+	data_resource.end = virt_to_phys(_edata)-1;
- 
- 	parse_cmdline_early(cmdline_p);
- 
-@@ -977,7 +978,7 @@ void __init setup_arch(char **cmdline_p)
- 	generic_apic_probe(*cmdline_p);
- #endif	
- 
--#ifdef CONFIG_ACPI_BOOT
-+#ifdef CONFIG_ACPI
- 	/*
- 	 * Parse the ACPI tables for possible boot-time SMP configuration.
- 	 */
---- linux-2.6.0-test1/arch/i386/kernel/smpboot.c	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/kernel/smpboot.c	2003-07-19 17:04:06.000000000 -0700
-@@ -61,12 +61,12 @@ static int __initdata smp_b_stepping;
- int smp_num_siblings = 1;
- int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
- 
--/* Bitmask of currently online CPUs */
--unsigned long cpu_online_map;
-+/* bitmap of online cpus */
-+cpumask_t cpu_online_map;
- 
--static volatile unsigned long cpu_callin_map;
--volatile unsigned long cpu_callout_map;
--static unsigned long smp_commenced_mask;
-+static cpumask_t cpu_callin_map;
-+cpumask_t cpu_callout_map;
-+static cpumask_t smp_commenced_mask;
- 
- /* Per CPU bogomips and other parameters */
- struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-@@ -268,7 +268,7 @@ static void __init synchronize_tsc_bp (v
- 
- 	sum = 0;
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (test_bit(i, &cpu_callout_map)) {
-+		if (cpu_isset(i, cpu_callout_map)) {
- 			t0 = tsc_values[i];
- 			sum += t0;
- 		}
-@@ -277,7 +277,7 @@ static void __init synchronize_tsc_bp (v
- 
- 	sum = 0;
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (!test_bit(i, &cpu_callout_map))
-+		if (!cpu_isset(i, cpu_callout_map))
- 			continue;
- 		delta = tsc_values[i] - avg;
- 		if (delta < 0)
-@@ -353,7 +353,7 @@ void __init smp_callin(void)
- 	 */
- 	phys_id = GET_APIC_ID(apic_read(APIC_ID));
- 	cpuid = smp_processor_id();
--	if (test_bit(cpuid, &cpu_callin_map)) {
-+	if (cpu_isset(cpuid, cpu_callin_map)) {
- 		printk("huh, phys CPU#%d, CPU#%d already present??\n",
- 					phys_id, cpuid);
- 		BUG();
-@@ -376,7 +376,7 @@ void __init smp_callin(void)
- 		/*
- 		 * Has the boot CPU finished it's STARTUP sequence?
- 		 */
--		if (test_bit(cpuid, &cpu_callout_map))
-+		if (cpu_isset(cpuid, cpu_callout_map))
- 			break;
- 		rep_nop();
- 	}
-@@ -417,7 +417,7 @@ void __init smp_callin(void)
- 	/*
- 	 * Allow the master to continue.
- 	 */
--	set_bit(cpuid, &cpu_callin_map);
-+	cpu_set(cpuid, cpu_callin_map);
- 
- 	/*
- 	 *      Synchronize the TSC with the BP
-@@ -442,7 +442,7 @@ int __init start_secondary(void *unused)
- 	 */
- 	cpu_init();
- 	smp_callin();
--	while (!test_bit(smp_processor_id(), &smp_commenced_mask))
-+	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
- 		rep_nop();
- 	setup_secondary_APIC_clock();
- 	if (nmi_watchdog == NMI_IO_APIC) {
-@@ -456,7 +456,7 @@ int __init start_secondary(void *unused)
- 	 * the local TLBs too.
- 	 */
- 	local_flush_tlb();
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- 	wmb();
- 	return cpu_idle();
- }
-@@ -499,16 +499,16 @@ static struct task_struct * __init fork_
- #ifdef CONFIG_NUMA
- 
- /* which logical CPUs are on which nodes */
--volatile unsigned long node_2_cpu_mask[MAX_NR_NODES] = 
--						{ [0 ... MAX_NR_NODES-1] = 0 };
-+cpumask_t node_2_cpu_mask[MAX_NR_NODES] =
-+				{ [0 ... MAX_NR_NODES-1] = CPU_MASK_NONE };
- /* which node each logical CPU is on */
--volatile int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
-+int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
- 
- /* set up a mapping between cpu and node. */
- static inline void map_cpu_to_node(int cpu, int node)
- {
- 	printk("Mapping cpu %d to node %d\n", cpu, node);
--	node_2_cpu_mask[node] |= (1 << cpu);
-+	cpu_set(cpu, node_2_cpu_mask[node]);
- 	cpu_2_node[cpu] = node;
- }
- 
-@@ -519,7 +519,7 @@ static inline void unmap_cpu_to_node(int
- 
- 	printk("Unmapping cpu %d from all nodes\n", cpu);
- 	for (node = 0; node < MAX_NR_NODES; node ++)
--		node_2_cpu_mask[node] &= ~(1 << cpu);
-+		cpu_clear(cpu, node_2_cpu_mask[node]);
- 	cpu_2_node[cpu] = -1;
- }
- #else /* !CONFIG_NUMA */
-@@ -529,7 +529,7 @@ static inline void unmap_cpu_to_node(int
- 
- #endif /* CONFIG_NUMA */
- 
--volatile u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
- 
- void map_cpu_to_logical_apicid(void)
- {
-@@ -770,7 +770,7 @@ wakeup_secondary_cpu(int phys_apicid, un
- }
- #endif	/* WAKE_SECONDARY_VIA_INIT */
- 
--extern unsigned long cpu_initialized;
-+extern cpumask_t cpu_initialized;
- 
- static int __init do_boot_cpu(int apicid)
- /*
-@@ -836,19 +836,19 @@ static int __init do_boot_cpu(int apicid
- 		 * allow APs to start initializing.
- 		 */
- 		Dprintk("Before Callout %d.\n", cpu);
--		set_bit(cpu, &cpu_callout_map);
-+		cpu_set(cpu, cpu_callout_map);
- 		Dprintk("After Callout %d.\n", cpu);
- 
- 		/*
- 		 * Wait 5s total for a response
- 		 */
- 		for (timeout = 0; timeout < 50000; timeout++) {
--			if (test_bit(cpu, &cpu_callin_map))
-+			if (cpu_isset(cpu, cpu_callin_map))
- 				break;	/* It has booted */
- 			udelay(100);
- 		}
- 
--		if (test_bit(cpu, &cpu_callin_map)) {
-+		if (cpu_isset(cpu, cpu_callin_map)) {
- 			/* number CPUs logically, starting from 1 (BSP is 0) */
- 			Dprintk("OK.\n");
- 			printk("CPU%d: ", cpu);
-@@ -869,8 +869,8 @@ static int __init do_boot_cpu(int apicid
- 	if (boot_error) {
- 		/* Try to put things back the way they were before ... */
- 		unmap_cpu_to_logical_apicid(cpu);
--		clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */
--		clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
-+		cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
-+		cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
- 		cpucount--;
- 	}
- 
-@@ -957,7 +957,7 @@ static void __init smp_boot_cpus(unsigne
- 	if (!smp_found_config) {
- 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
- 		smpboot_clear_io_apic_irqs();
--		phys_cpu_present_map = 1;
-+		phys_cpu_present_map = physid_mask_of_physid(0);
- 		if (APIC_init_uniprocessor())
- 			printk(KERN_NOTICE "Local APIC not detected."
- 					   " Using dummy APIC emulation.\n");
-@@ -973,7 +973,7 @@ static void __init smp_boot_cpus(unsigne
- 	if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
- 		printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
- 				boot_cpu_physical_apicid);
--		phys_cpu_present_map |= (1 << hard_smp_processor_id());
-+		cpu_set(hard_smp_processor_id(), phys_cpu_present_map);
- 	}
- 
- 	/*
-@@ -984,7 +984,7 @@ static void __init smp_boot_cpus(unsigne
- 			boot_cpu_physical_apicid);
- 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
- 		smpboot_clear_io_apic_irqs();
--		phys_cpu_present_map = 1;
-+		phys_cpu_present_map = physid_mask_of_physid(0);
- 		return;
- 	}
- 
-@@ -997,7 +997,7 @@ static void __init smp_boot_cpus(unsigne
- 		smp_found_config = 0;
- 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
- 		smpboot_clear_io_apic_irqs();
--		phys_cpu_present_map = 1;
-+		phys_cpu_present_map = physid_mask_of_physid(0);
- 		return;
- 	}
- 
-@@ -1017,10 +1017,10 @@ static void __init smp_boot_cpus(unsigne
- 	 * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the 
- 	 * clustered apic ID.
- 	 */
--	Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
-+	Dprintk("CPU present map: %lx\n", cpus_coerce(phys_cpu_present_map));
- 
- 	kicked = 1;
--	for (bit = 0; kicked < NR_CPUS && bit < BITS_PER_LONG; bit++) {
-+	for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) {
- 		apicid = cpu_present_to_apicid(bit);
- 		/*
- 		 * Don't even attempt to start the boot CPU!
-@@ -1055,7 +1055,7 @@ static void __init smp_boot_cpus(unsigne
- 	} else {
- 		unsigned long bogosum = 0;
- 		for (cpu = 0; cpu < NR_CPUS; cpu++)
--			if (cpu_callout_map & (1<<cpu))
-+			if (cpu_isset(cpu, cpu_callout_map))
- 				bogosum += cpu_data[cpu].loops_per_jiffy;
- 		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
- 			cpucount+1,
-@@ -1087,10 +1087,11 @@ static void __init smp_boot_cpus(unsigne
- 		
- 		for (cpu = 0; cpu < NR_CPUS; cpu++) {
- 			int 	i;
--			if (!test_bit(cpu, &cpu_callout_map)) continue;
-+			if (!cpu_isset(cpu, cpu_callout_map))
-+				continue;
- 
- 			for (i = 0; i < NR_CPUS; i++) {
--				if (i == cpu || !test_bit(i, &cpu_callout_map))
-+				if (i == cpu || !cpu_isset(i, cpu_callout_map))
- 					continue;
- 				if (phys_proc_id[cpu] == phys_proc_id[i]) {
- 					cpu_sibling_map[cpu] = i;
-@@ -1125,28 +1126,28 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_callout_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_callout_map);
- }
- 
- int __devinit __cpu_up(unsigned int cpu)
- {
- 	/* This only works at boot for x86.  See "rewrite" above. */
--	if (test_bit(cpu, &smp_commenced_mask)) {
-+	if (cpu_isset(cpu, smp_commenced_mask)) {
- 		local_irq_enable();
- 		return -ENOSYS;
- 	}
- 
- 	/* In case one didn't come up */
--	if (!test_bit(cpu, &cpu_callin_map)) {
-+	if (!cpu_isset(cpu, cpu_callin_map)) {
- 		local_irq_enable();
- 		return -EIO;
- 	}
- 
- 	local_irq_enable();
- 	/* Unleash the CPU! */
--	set_bit(cpu, &smp_commenced_mask);
--	while (!test_bit(cpu, &cpu_online_map))
-+	cpu_set(cpu, smp_commenced_mask);
-+	while (!cpu_isset(cpu, cpu_online_map))
- 		mb();
- 	return 0;
- }
-@@ -1154,7 +1155,8 @@ int __devinit __cpu_up(unsigned int cpu)
- void __init smp_cpus_done(unsigned int max_cpus)
- {
- #ifdef CONFIG_X86_IO_APIC
--	setup_ioapic_dest(TARGET_CPUS);
-+	cpumask_t targets = CPU_MASK_ALL;
-+	setup_ioapic_dest(targets);
- #endif
- 	zap_low_mappings();
- }
---- linux-2.6.0-test1/arch/i386/kernel/smp.c	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/kernel/smp.c	2003-07-19 17:04:06.000000000 -0700
-@@ -155,8 +155,12 @@ void send_IPI_self(int vector)
- 	__send_IPI_shortcut(APIC_DEST_SELF, vector);
- }
- 
--inline void send_IPI_mask_bitmask(int mask, int vector)
-+/*
-+ * This is only used on smaller machines.
-+ */
-+inline void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
- {
-+	unsigned long mask = cpus_coerce(cpumask);
- 	unsigned long cfg;
- 	unsigned long flags;
- 
-@@ -186,10 +190,10 @@ inline void send_IPI_mask_bitmask(int ma
- 	local_irq_restore(flags);
- }
- 
--inline void send_IPI_mask_sequence(int mask, int vector)
-+inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
- {
- 	unsigned long cfg, flags;
--	unsigned int query_cpu, query_mask;
-+	unsigned int query_cpu;
- 
- 	/*
- 	 * Hack. The clustered APIC addressing mode doesn't allow us to send 
-@@ -200,8 +204,7 @@ inline void send_IPI_mask_sequence(int m
- 	local_irq_save(flags);
- 
- 	for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
--		query_mask = 1 << query_cpu;
--		if (query_mask & mask) {
-+		if (cpu_isset(query_cpu, mask)) {
- 		
- 			/*
- 			 * Wait for idle.
-@@ -238,7 +241,7 @@ inline void send_IPI_mask_sequence(int m
-  *	Optimizations Manfred Spraul <manfred@colorfullife.com>
-  */
- 
--static volatile unsigned long flush_cpumask;
-+static cpumask_t flush_cpumask;
- static struct mm_struct * flush_mm;
- static unsigned long flush_va;
- static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
-@@ -255,7 +258,7 @@ static inline void leave_mm (unsigned lo
- {
- 	if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
- 		BUG();
--	clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
-+	cpu_clear(cpu, cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
- 	load_cr3(swapper_pg_dir);
- }
- 
-@@ -265,7 +268,7 @@ static inline void leave_mm (unsigned lo
-  * [cpu0: the cpu that switches]
-  * 1) switch_mm() either 1a) or 1b)
-  * 1a) thread switch to a different mm
-- * 1a1) clear_bit(cpu, &old_mm->cpu_vm_mask);
-+ * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
-  * 	Stop ipi delivery for the old mm. This is not synchronized with
-  * 	the other cpus, but smp_invalidate_interrupt ignore flush ipis
-  * 	for the wrong mm, and in the worst case we perform a superflous
-@@ -275,7 +278,7 @@ static inline void leave_mm (unsigned lo
-  *	was in lazy tlb mode.
-  * 1a3) update cpu_tlbstate[].active_mm
-  * 	Now cpu0 accepts tlb flushes for the new mm.
-- * 1a4) set_bit(cpu, &new_mm->cpu_vm_mask);
-+ * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
-  * 	Now the other cpus will send tlb flush ipis.
-  * 1a4) change cr3.
-  * 1b) thread switch without mm change
-@@ -311,7 +314,7 @@ asmlinkage void smp_invalidate_interrupt
- 
- 	cpu = get_cpu();
- 
--	if (!test_bit(cpu, &flush_cpumask))
-+	if (!cpu_isset(cpu, flush_cpumask))
- 		goto out;
- 		/* 
- 		 * This was a BUG() but until someone can quote me the
-@@ -332,15 +335,17 @@ asmlinkage void smp_invalidate_interrupt
- 			leave_mm(cpu);
- 	}
- 	ack_APIC_irq();
--	clear_bit(cpu, &flush_cpumask);
--
-+	smp_mb__before_clear_bit();
-+	cpu_clear(cpu, flush_cpumask);
-+	smp_mb__after_clear_bit();
- out:
- 	put_cpu_no_resched();
- }
- 
--static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
-+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
- 						unsigned long va)
- {
-+	cpumask_t tmp;
- 	/*
- 	 * A couple of (to be removed) sanity checks:
- 	 *
-@@ -348,14 +353,12 @@ static void flush_tlb_others (unsigned l
- 	 * - current CPU must not be in mask
- 	 * - mask must exist :)
- 	 */
--	if (!cpumask)
--		BUG();
--	if ((cpumask & cpu_online_map) != cpumask)
--		BUG();
--	if (cpumask & (1 << smp_processor_id()))
--		BUG();
--	if (!mm)
--		BUG();
-+	BUG_ON(cpus_empty(cpumask));
-+
-+	cpus_and(tmp, cpumask, cpu_online_map);
-+	BUG_ON(!cpus_equal(cpumask, tmp));
-+	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
-+	BUG_ON(!mm);
- 
- 	/*
- 	 * i'm not happy about this global shared spinlock in the
-@@ -367,15 +370,26 @@ static void flush_tlb_others (unsigned l
- 	
- 	flush_mm = mm;
- 	flush_va = va;
-+#if NR_CPUS <= BITS_PER_LONG
- 	atomic_set_mask(cpumask, &flush_cpumask);
-+#else
-+	{
-+		int k;
-+		unsigned long *flush_mask = (unsigned long *)&flush_cpumask;
-+		unsigned long *cpu_mask = (unsigned long *)&cpumask;
-+		for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k)
-+			atomic_set_mask(cpu_mask[k], &flush_mask[k]);
-+	}
-+#endif
- 	/*
- 	 * We have to send the IPI only to
- 	 * CPUs affected.
- 	 */
- 	send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
- 
--	while (flush_cpumask)
--		/* nothing. lockup detection does not belong here */;
-+	while (!cpus_empty(flush_cpumask))
-+		/* nothing. lockup detection does not belong here */
-+		mb();
- 
- 	flush_mm = NULL;
- 	flush_va = 0;
-@@ -385,23 +399,25 @@ static void flush_tlb_others (unsigned l
- void flush_tlb_current_task(void)
- {
- 	struct mm_struct *mm = current->mm;
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	local_flush_tlb();
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
- 	preempt_enable();
- }
- 
- void flush_tlb_mm (struct mm_struct * mm)
- {
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	if (current->active_mm == mm) {
- 		if (current->mm)
-@@ -409,7 +425,7 @@ void flush_tlb_mm (struct mm_struct * mm
- 		else
- 			leave_mm(smp_processor_id());
- 	}
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
- 
- 	preempt_enable();
-@@ -418,10 +434,11 @@ void flush_tlb_mm (struct mm_struct * mm
- void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
- {
- 	struct mm_struct *mm = vma->vm_mm;
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	if (current->active_mm == mm) {
- 		if(current->mm)
-@@ -430,7 +447,7 @@ void flush_tlb_page(struct vm_area_struc
- 		 	leave_mm(smp_processor_id());
- 	}
- 
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, va);
- 
- 	preempt_enable();
-@@ -457,9 +474,19 @@ void flush_tlb_all(void)
-  */
- void smp_send_reschedule(int cpu)
- {
--	send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
-+	send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
- }
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * By using the NMI code instead of a vector we just sneak thru the 
-+ * word generator coming out with just what we want.  AND it does
-+ * not matter if clustered_apic_mode is set or not.
-+ */
-+void smp_send_nmi_allbutself(void)
-+{
-+	send_IPI_allbutself(APIC_DM_NMI);
-+}
-+#endif
- /*
-  * Structure and data for smp_call_function(). This is designed to minimise
-  * static memory requirements. It also looks cleaner.
-@@ -533,7 +560,7 @@ static void stop_this_cpu (void * dummy)
- 	/*
- 	 * Remove this CPU:
- 	 */
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_disable();
- 	disable_local_APIC();
- 	if (cpu_data[smp_processor_id()].hlt_works_ok)
---- linux-2.6.0-test1/arch/i386/kernel/traps.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/i386/kernel/traps.c	2003-07-19 17:06:40.000000000 -0700
-@@ -90,6 +90,42 @@ asmlinkage void alignment_check(void);
- asmlinkage void spurious_interrupt_bug(void);
- asmlinkage void machine_check(void);
- 
-+#ifdef CONFIG_KGDB
-+extern void sysenter_entry(void);
-+#include <asm/kgdb.h>
-+#include <linux/init.h>
-+extern void int3(void);
-+extern void debug(void);
-+void set_intr_gate(unsigned int n, void *addr);
-+static void set_intr_usr_gate(unsigned int n, void *addr);
-+/*
-+ * Should be able to call this breakpoint() very early in
-+ * bring up.  Just hard code the call where needed.
-+ * The breakpoint() code is here because set_?_gate() functions
-+ * are local (static) to trap.c.  They need be done only once,
-+ * but it does not hurt to do them over.
-+ */
-+void breakpoint(void)
-+{
-+        set_intr_usr_gate(3,&int3); /* disable ints on trap */
-+	set_intr_gate(1,&debug);
-+	set_intr_gate(14,&page_fault);
-+       
-+        BREAKPOINT;
-+}
-+#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)		\
-+    {									\
-+	if (!user_mode(regs)  ) \
-+	{								\
-+		kgdb_handle_exception(trapnr, signr, error_code, regs);	\
-+		after;							\
-+	} else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
-+    }
-+#else
-+#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)	
-+#endif
-+
-+
- static int kstack_depth_to_print = 24;
- 
- void show_trace(struct task_struct *task, unsigned long * stack)
-@@ -172,8 +208,9 @@ void show_registers(struct pt_regs *regs
- 		ss = regs->xss & 0xffff;
- 	}
- 	print_modules();
--	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
--		smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
-+	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\nEFLAGS: %08lx\n",
-+		smp_processor_id(), 0xffff & regs->xcs,
-+		regs->eip, print_tainted(), regs->eflags);
- 
- 	print_symbol("EIP is at %s\n", regs->eip);
- 	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-@@ -189,23 +226,25 @@ void show_registers(struct pt_regs *regs
- 	 * time of the fault..
- 	 */
- 	if (in_kernel) {
-+		u8 *eip;
- 
- 		printk("\nStack: ");
- 		show_stack(NULL, (unsigned long*)esp);
- 
- 		printk("Code: ");
--		if(regs->eip < PAGE_OFFSET)
--			goto bad;
- 
--		for(i=0;i<20;i++)
--		{
-+		eip = (u8 *)regs->eip - 43;
-+		for (i = 0; i < 64; i++, eip++) {
- 			unsigned char c;
--			if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
--bad:
-+
-+			if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) {
- 				printk(" Bad EIP value.");
- 				break;
- 			}
--			printk("%02x ", c);
-+			if (eip == (u8 *)regs->eip)
-+				printk("<%02x> ", c);
-+			else
-+				printk("%02x ", c);
- 		}
- 	}
- 	printk("\n");
-@@ -252,12 +291,36 @@ spinlock_t die_lock = SPIN_LOCK_UNLOCKED
- void die(const char * str, struct pt_regs * regs, long err)
- {
- 	static int die_counter;
-+	int nl = 0;
- 
- 	console_verbose();
- 	spin_lock_irq(&die_lock);
- 	bust_spinlocks(1);
- 	handle_BUG(regs);
- 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-+#ifdef CONFIG_PREEMPT
-+	printk("PREEMPT ");
-+	nl = 1;
-+#endif
-+#ifdef CONFIG_SMP
-+	printk("SMP ");
-+	nl = 1;
-+#endif
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+	printk("DEBUG_PAGEALLOC");
-+	nl = 1;
-+#endif
-+	if (nl)
-+		printk("\n");
-+#ifdef CONFIG_KGDB
-+	/* This is about the only place we want to go to kgdb even if in 
-+	 * user mode.  But we must go in via a trap so within kgdb we will
-+	 * always be in kernel mode.
-+	 */
-+	if (user_mode(regs))
-+		BREAKPOINT;
-+#endif
-+ 	CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
- 	show_registers(regs);
- 	bust_spinlocks(0);
- 	spin_unlock_irq(&die_lock);
-@@ -327,6 +390,7 @@ static inline void do_trap(int trapnr, i
- #define DO_ERROR(trapnr, signr, str, name) \
- asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
- { \
-+	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
- 	do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
- }
- 
-@@ -344,7 +408,9 @@ asmlinkage void do_##name(struct pt_regs
- #define DO_VM86_ERROR(trapnr, signr, str, name) \
- asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
- { \
-+	CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
- 	do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
-+	return; \
- }
- 
- #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-@@ -387,8 +453,10 @@ gp_in_vm86:
- 	return;
- 
- gp_in_kernel:
--	if (!fixup_exception(regs))
-+	if (!fixup_exception(regs)){
-+ 		CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
- 		die("general protection fault", regs, error_code);
-+	}
- }
- 
- static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
-@@ -550,8 +618,18 @@ asmlinkage void do_debug(struct pt_regs 
- 		 * allowing programs to debug themselves without the ptrace()
- 		 * interface.
- 		 */
--		if ((regs->xcs & 3) == 0)
-+#ifdef CONFIG_KGDB
-+		/*
-+		 * I think this is the only "real" case of a TF in the kernel
-+		 * that really belongs to user space.  Others are
-+		 * "Ours all ours!"
-+		 */
-+		if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
-+			goto clear_TF_reenable;
-+#else
-+		if ((regs->xcs & 3) == 0)	
- 			goto clear_TF_reenable;
-+#endif
- 		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
- 			goto clear_TF;
- 	}
-@@ -563,6 +641,17 @@ asmlinkage void do_debug(struct pt_regs 
- 	info.si_errno = 0;
- 	info.si_code = TRAP_BRKPT;
- 	
-+#ifdef CONFIG_KGDB
-+        /*
-+	 * If this is a kernel mode trap, we need to reset db7 to allow us
-+	 * to continue sanely ALSO skip the signal delivery 
-+         */
-+	if ((regs->xcs & 3) == 0)
-+		goto clear_dr7;
-+
-+        /* if not kernel, allow ints but only if they were on */ 
-+       if ( regs->eflags & 0x200) local_irq_enable(); 
-+#endif
- 	/* If this is a kernel mode trap, save the user PC on entry to 
- 	 * the kernel, that's what the debugger can make sense of.
- 	 */
-@@ -577,6 +666,7 @@ clear_dr7:
- 	__asm__("movl %0,%%db7"
- 		: /* no output */
- 		: "r" (0));
-+	CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
- 	return;
- 
- debug_vm86:
-@@ -823,6 +913,12 @@ static void __init set_call_gate(void *a
- {
- 	_set_gate(a,12,3,addr,__KERNEL_CS);
- }
-+#ifdef CONFIG_KGDB
-+void set_intr_usr_gate(unsigned int n, void *addr)
-+{
-+	_set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
-+}
-+#endif
- 
- static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
- {
-@@ -849,7 +945,11 @@ void __init trap_init(void)
- 	set_trap_gate(0,&divide_error);
- 	set_intr_gate(1,&debug);
- 	set_intr_gate(2,&nmi);
-+#ifndef CONFIG_KGDB
- 	set_system_gate(3,&int3);	/* int3-5 can be called from all */
-+#else
-+	set_intr_usr_gate(3,&int3);	/* int3-5 can be called from all */
-+#endif
- 	set_system_gate(4,&overflow);
- 	set_system_gate(5,&bounds);
- 	set_trap_gate(6,&invalid_op);
---- linux-2.6.0-test1/arch/i386/kernel/vm86.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/i386/kernel/vm86.c	2003-07-19 17:07:16.000000000 -0700
-@@ -144,12 +144,14 @@ static void mark_screen_rdonly(struct ta
- 		pgd_clear(pgd);
- 		goto out;
- 	}
--	pmd = pmd_offset(pgd, 0xA0000);
--	if (pmd_none(*pmd))
-+	pmd = pmd_offset_map(pgd, 0xA0000);
-+	if (pmd_none(*pmd)) {
-+		pmd_unmap(pmd);
- 		goto out;
--	if (pmd_bad(*pmd)) {
-+	} else if (pmd_bad(*pmd)) {
- 		pmd_ERROR(*pmd);
- 		pmd_clear(pmd);
-+		pmd_unmap(pmd);
- 		goto out;
- 	}
- 	pte = mapped = pte_offset_map(pmd, 0xA0000);
-@@ -159,6 +161,7 @@ static void mark_screen_rdonly(struct ta
- 		pte++;
- 	}
- 	pte_unmap(mapped);
-+	pmd_unmap(pmd);
- out:
- 	spin_unlock(&tsk->mm->page_table_lock);
- 	preempt_enable();
---- linux-2.6.0-test1/arch/i386/lib/dec_and_lock.c	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/lib/dec_and_lock.c	2003-07-19 17:06:40.000000000 -0700
-@@ -10,6 +10,7 @@
- #include <linux/spinlock.h>
- #include <asm/atomic.h>
- 
-+#ifndef ATOMIC_DEC_AND_LOCK
- int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
- {
- 	int counter;
-@@ -38,3 +39,5 @@ slow_path:
- 	spin_unlock(lock);
- 	return 0;
- }
-+#endif
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/i386/lib/kgdb_serial.c	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,485 @@
-+/*
-+ * Serial interface GDB stub
-+ *
-+ * Written (hacked together) by David Grothe (dave@gcom.com)
-+ * Modified to allow invokation early in boot see also
-+ * kgdb.h for instructions by George Anzinger(george@mvista.com)
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <linux/config.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/highmem.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/segment.h>
-+#include <asm/bitops.h>
-+#include <asm/system.h>
-+#include <asm/kgdb_local.h>
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+extern void kgdb_console_finit(void);
-+#endif
-+#define PRNT_off
-+#define TEST_EXISTANCE
-+#ifdef PRNT
-+#define dbprintk(s) printk s
-+#else
-+#define dbprintk(s)
-+#endif
-+#define TEST_INTERRUPT_off
-+#ifdef TEST_INTERRUPT
-+#define intprintk(s) printk s
-+#else
-+#define intprintk(s)
-+#endif
-+
-+#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
-+
-+#define	GDB_BUF_SIZE	512	/* power of 2, please */
-+
-+static char gdb_buf[GDB_BUF_SIZE];
-+static int gdb_buf_in_inx;
-+static atomic_t gdb_buf_in_cnt;
-+static int gdb_buf_out_inx;
-+
-+struct async_struct *gdb_async_info;
-+static int gdb_async_irq;
-+
-+#define outb_px(a,b) outb_p(b,a)
-+
-+static void program_uart(struct async_struct *info);
-+static void write_char(struct async_struct *info, int chr);
-+/*
-+ * Get a byte from the hardware data buffer and return it
-+ */
-+static int
-+read_data_bfr(struct async_struct *info)
-+{
-+	char it = inb_p(info->port + UART_LSR);
-+
-+	if (it & UART_LSR_DR)
-+		return (inb_p(info->port + UART_RX));
-+	/*
-+	 * If we have a framing error assume somebody messed with
-+	 * our uart.  Reprogram it and send '-' both ways...
-+	 */
-+	if (it & 0xc) {
-+		program_uart(info);
-+		write_char(info, '-');
-+		return ('-');
-+	}
-+	return (-1);
-+
-+}				/* read_data_bfr */
-+
-+/*
-+ * Get a char if available, return -1 if nothing available.
-+ * Empty the receive buffer first, then look at the interface hardware.
-+
-+ * Locking here is a bit of a problem.	We MUST not lock out communication
-+ * if we are trying to talk to gdb about a kgdb entry.	ON the other hand
-+ * we can loose chars in the console pass thru if we don't lock.  It is also
-+ * possible that we could hold the lock or be waiting for it when kgdb
-+ * NEEDS to talk.  Since kgdb locks down the world, it does not need locks.
-+ * We do, of course have possible issues with interrupting a uart operation,
-+ * but we will just depend on the uart status to help keep that straight.
-+
-+ */
-+static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
-+#ifdef CONFIG_SMP
-+extern spinlock_t kgdb_spinlock;
-+#endif
-+
-+static int
-+read_char(struct async_struct *info)
-+{
-+	int chr;
-+	unsigned long flags;
-+	local_irq_save(flags);
-+#ifdef CONFIG_SMP
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		spin_lock(&uart_interrupt_lock);
-+	}
-+#endif
-+	if (atomic_read(&gdb_buf_in_cnt) != 0) {	/* intr routine has q'd chars */
-+		chr = gdb_buf[gdb_buf_out_inx++];
-+		gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
-+		atomic_dec(&gdb_buf_in_cnt);
-+	} else {
-+		chr = read_data_bfr(info);
-+	}
-+#ifdef CONFIG_SMP
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		spin_unlock(&uart_interrupt_lock);
-+	}
-+#endif
-+	local_irq_restore(flags);
-+	return (chr);
-+}
-+
-+/*
-+ * Wait until the interface can accept a char, then write it.
-+ */
-+static void
-+write_char(struct async_struct *info, int chr)
-+{
-+	while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
-+
-+	outb_p(chr, info->port + UART_TX);
-+
-+}				/* write_char */
-+
-+/*
-+ * Mostly we don't need a spinlock, but since the console goes
-+ * thru here with interrutps on, well, we need to catch those
-+ * chars.
-+ */
-+/*
-+ * This is the receiver interrupt routine for the GDB stub.
-+ * It will receive a limited number of characters of input
-+ * from the gdb  host machine and save them up in a buffer.
-+ *
-+ * When the gdb stub routine getDebugChar() is called it
-+ * draws characters out of the buffer until it is empty and
-+ * then reads directly from the serial port.
-+ *
-+ * We do not attempt to write chars from the interrupt routine
-+ * since the stubs do all of that via putDebugChar() which
-+ * writes one byte after waiting for the interface to become
-+ * ready.
-+ *
-+ * The debug stubs like to run with interrupts disabled since,
-+ * after all, they run as a consequence of a breakpoint in
-+ * the kernel.
-+ *
-+ * Perhaps someone who knows more about the tty driver than I
-+ * care to learn can make this work for any low level serial
-+ * driver.
-+ */
-+static irqreturn_t
-+gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+	struct async_struct *info;
-+	unsigned long flags;
-+
-+	info = gdb_async_info;
-+	if (!info || !info->tty || irq != gdb_async_irq)
-+		return IRQ_NONE;
-+
-+	local_irq_save(flags);
-+	spin_lock(&uart_interrupt_lock);
-+	do {
-+		int chr = read_data_bfr(info);
-+		intprintk(("Debug char on int: %x hex\n", chr));
-+		if (chr < 0)
-+			continue;
-+
-+		if (chr == 3) {	/* Ctrl-C means remote interrupt */
-+			BREAKPOINT;
-+			continue;
-+		}
-+
-+		if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
-+			/* buffer overflow tosses early char */
-+			read_char(info);
-+		}
-+		gdb_buf[gdb_buf_in_inx++] = chr;
-+		gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
-+	} while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
-+	spin_unlock(&uart_interrupt_lock);
-+	local_irq_restore(flags);
-+	return IRQ_HANDLED;
-+}				/* gdb_interrupt */
-+
-+/*
-+ * Just a NULL routine for testing.
-+ */
-+void
-+gdb_null(void)
-+{
-+}				/* gdb_null */
-+
-+/* These structure are filled in with values defined in asm/kgdb_local.h
-+ */
-+static struct serial_state state = SB_STATE;
-+static struct async_struct local_info = SB_INFO;
-+static int ok_to_enable_ints = 0;
-+static void kgdb_enable_ints_now(void);
-+
-+extern char *kgdb_version;
-+/*
-+ * Hook an IRQ for KGDB.
-+ *
-+ * This routine is called from putDebugChar, below.
-+ */
-+static int ints_disabled = 1;
-+int
-+gdb_hook_interrupt(struct async_struct *info, int verb)
-+{
-+	struct serial_state *state = info->state;
-+	unsigned long flags;
-+	int port;
-+#ifdef TEST_EXISTANCE
-+	int scratch, scratch2;
-+#endif
-+
-+	/* The above fails if memory managment is not set up yet. 
-+	 * Rather than fail the set up, just keep track of the fact
-+	 * and pick up the interrupt thing later.
-+	 */
-+	gdb_async_info = info;
-+	port = gdb_async_info->port;
-+	gdb_async_irq = state->irq;
-+	if (verb) {
-+		printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
-+		       kgdb_version,
-+		       port,
-+		       gdb_async_irq, gdb_async_info->state->custom_divisor);
-+	}
-+	local_irq_save(flags);
-+#ifdef TEST_EXISTANCE
-+	/* Existance test */
-+	/* Should not need all this, but just in case.... */
-+
-+	scratch = inb_p(port + UART_IER);
-+	outb_px(port + UART_IER, 0);
-+	outb_px(0xff, 0x080);
-+	scratch2 = inb_p(port + UART_IER);
-+	outb_px(port + UART_IER, scratch);
-+	if (scratch2) {
-+		printk
-+		    ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
-+		local_irq_restore(flags);
-+		return 1;	/* We failed; there's nothing here */
-+	}
-+	scratch2 = inb_p(port + UART_LCR);
-+	outb_px(port + UART_LCR, 0xBF);	/* set up for StarTech test */
-+	outb_px(port + UART_EFR, 0);	/* EFR is the same as FCR */
-+	outb_px(port + UART_LCR, 0);
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
-+	scratch = inb_p(port + UART_IIR) >> 6;
-+	if (scratch == 1) {
-+		printk("gdb_hook_interrupt: Undefined UART type!"
-+		       "  Not a UART! \n");
-+		local_irq_restore(flags);
-+		return 1;
-+	} else {
-+		dbprintk(("gdb_hook_interrupt: UART type "
-+			  "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
-+	}
-+	scratch = inb_p(port + UART_MCR);
-+	outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
-+	outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
-+	scratch2 = inb_p(port + UART_MSR) & 0xF0;
-+	outb_px(port + UART_MCR, scratch);
-+	if (scratch2 != 0x90) {
-+		printk("gdb_hook_interrupt: "
-+		       "Loop back test failed! Not a UART!\n");
-+		local_irq_restore(flags);
-+		return scratch2 + 1000;	/* force 0 to fail */
-+	}
-+#endif				/* test existance */
-+	program_uart(info);
-+	local_irq_restore(flags);
-+
-+	return (0);
-+
-+}				/* gdb_hook_interrupt */
-+
-+static void
-+program_uart(struct async_struct *info)
-+{
-+	int port = info->port;
-+
-+	(void) inb_p(port + UART_RX);
-+	outb_px(port + UART_IER, 0);
-+
-+	(void) inb_p(port + UART_RX);	/* serial driver comments say */
-+	(void) inb_p(port + UART_IIR);	/* this clears the interrupt regs */
-+	(void) inb_p(port + UART_MSR);
-+	outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
-+	outb_px(port + UART_DLL, info->state->custom_divisor & 0xff);	/* LS */
-+	outb_px(port + UART_DLM, info->state->custom_divisor >> 8);	/* MS  */
-+	outb_px(port + UART_MCR, info->MCR);
-+
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);	/* set fcr */
-+	outb_px(port + UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1);	/* set fcr */
-+	if (!ints_disabled) {
-+		intprintk(("KGDB: Sending %d to port %x offset %d\n",
-+			   gdb_async_info->IER,
-+			   (int) gdb_async_info->port, UART_IER));
-+		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
-+	}
-+	return;
-+}
-+
-+/*
-+ * getDebugChar
-+ *
-+ * This is a GDB stub routine.	It waits for a character from the
-+ * serial interface and then returns it.  If there is no serial
-+ * interface connection then it returns a bogus value which will
-+ * almost certainly cause the system to hang.  In the 
-+ */
-+int kgdb_in_isr = 0;
-+int kgdb_in_lsr = 0;
-+extern spinlock_t kgdb_spinlock;
-+
-+/* Caller takes needed protections */
-+
-+int
-+getDebugChar(void)
-+{
-+	volatile int chr, dum, time, end_time;
-+
-+	dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
-+
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 0);
-+	}
-+	/* 
-+	 * This trick says if we wait a very long time and get
-+	 * no char, return the -1 and let the upper level deal
-+	 * with it.
-+	 */
-+	rdtsc(dum, time);
-+	end_time = time + 2;
-+	while (((chr = read_char(gdb_async_info)) == -1) &&
-+	       (end_time - time) > 0) {
-+		rdtsc(dum, time);
-+	};
-+	/*
-+	 * This covers our butts if some other code messes with
-+	 * our uart, hay, it happens :o)
-+	 */
-+	if (chr == -1)
-+		program_uart(gdb_async_info);
-+
-+	dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
-+	return (chr);
-+
-+}				/* getDebugChar */
-+
-+static int count = 3;
-+static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
-+
-+static int __init
-+kgdb_enable_ints(void)
-+{
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 1);
-+	}
-+	ok_to_enable_ints = 1;
-+	kgdb_enable_ints_now();
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+	kgdb_console_finit();
-+#endif
-+	return 0;
-+}
-+
-+#ifdef CONFIG_SERIAL_8250
-+void shutdown_for_kgdb(struct async_struct *gdb_async_info);
-+#endif
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+static inline int kgdb_mem_init_done(void)
-+{
-+	return highmem_start_page != NULL;
-+}
-+#else
-+static inline int kgdb_mem_init_done(void)
-+{
-+	return max_mapnr != 0;
-+}
-+#endif
-+
-+static void
-+kgdb_enable_ints_now(void)
-+{
-+	if (!spin_trylock(&one_at_atime))
-+		return;
-+	if (!ints_disabled)
-+		goto exit;
-+	if (kgdb_mem_init_done() &&
-+			ints_disabled) {	/* don't try till mem init */
-+#ifdef CONFIG_SERIAL_8250
-+		/*
-+		 * The ifdef here allows the system to be configured
-+		 * without the serial driver.
-+		 * Don't make it a module, however, it will steal the port
-+		 */
-+		shutdown_for_kgdb(gdb_async_info);
-+#endif
-+		ints_disabled = request_irq(gdb_async_info->state->irq,
-+					    gdb_interrupt,
-+					    IRQ_T(gdb_async_info),
-+					    "KGDB-stub", NULL);
-+		intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
-+	}
-+	if (!ints_disabled) {
-+		intprintk(("KGDB: Sending %d to port %x offset %d\n",
-+			   gdb_async_info->IER,
-+			   (int) gdb_async_info->port, UART_IER));
-+		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
-+	}
-+      exit:
-+	spin_unlock(&one_at_atime);
-+}
-+
-+/*
-+ * putDebugChar
-+ *
-+ * This is a GDB stub routine.	It waits until the interface is ready
-+ * to transmit a char and then sends it.  If there is no serial
-+ * interface connection then it simply returns to its caller, having
-+ * pretended to send the char.	Caller takes needed protections.
-+ */
-+void
-+putDebugChar(int chr)
-+{
-+	dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
-+		  gdb_async_info->port,
-+		  chr,
-+		  chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
-+
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 0);
-+	}
-+
-+	write_char(gdb_async_info, chr);	/* this routine will wait */
-+	count = (chr == '#') ? 0 : count + 1;
-+	if ((count == 2)) {	/* try to enable after */
-+		if (ints_disabled & ok_to_enable_ints)
-+			kgdb_enable_ints_now();	/* try to enable after */
-+
-+		/* We do this a lot because, well we really want to get these
-+		 * interrupts.	The serial driver will clear these bits when it
-+		 * initializes the chip.  Every thing else it does is ok, 
-+		 * but this.
-+		 */
-+		if (!ints_disabled) {
-+			outb_px(gdb_async_info->port + UART_IER,
-+				gdb_async_info->IER);
-+		}
-+	}
-+
-+}				/* putDebugChar */
-+
-+module_init(kgdb_enable_ints);
---- linux-2.6.0-test1/arch/i386/lib/Makefile	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/lib/Makefile	2003-07-19 17:04:02.000000000 -0700
-@@ -9,4 +9,5 @@ lib-y = checksum.o delay.o \
- 
- lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
- lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
-+lib-$(CONFIG_KGDB) += kgdb_serial.o
- lib-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
---- linux-2.6.0-test1/arch/i386/mach-generic/bigsmp.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/arch/i386/mach-generic/bigsmp.c	2003-07-19 17:04:13.000000000 -0700
-@@ -3,6 +3,10 @@
-  * Drives the local APIC in "clustered mode".
-  */
- #define APIC_DEFINITION 1
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <asm/mpspec.h>
- #include <asm/genapic.h>
- #include <asm/fixmap.h>
- #include <asm/apicdef.h>
---- linux-2.6.0-test1/arch/i386/mach-generic/default.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/arch/i386/mach-generic/default.c	2003-07-19 17:04:13.000000000 -0700
-@@ -2,6 +2,10 @@
-  * Default generic APIC driver. This handles upto 8 CPUs.
-  */
- #define APIC_DEFINITION 1
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <asm/mpspec.h>
- #include <asm/mach-default/mach_apicdef.h>
- #include <asm/genapic.h>
- #include <asm/fixmap.h>
---- linux-2.6.0-test1/arch/i386/mach-generic/probe.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/arch/i386/mach-generic/probe.c	2003-07-19 17:04:13.000000000 -0700
-@@ -3,11 +3,15 @@
-  * 
-  * Generic x86 APIC driver probe layer.
-  */  
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <linux/string.h>
- #include <linux/kernel.h>
- #include <linux/ctype.h>
- #include <linux/init.h>
- #include <asm/fixmap.h>
-+#include <asm/mpspec.h>
- #include <asm/apicdef.h>
- #include <asm/genapic.h>
- 
---- linux-2.6.0-test1/arch/i386/mach-generic/summit.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/i386/mach-generic/summit.c	2003-07-19 17:04:13.000000000 -0700
-@@ -2,6 +2,10 @@
-  * APIC driver for the IBM "Summit" chipset.
-  */
- #define APIC_DEFINITION 1
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <asm/mpspec.h>
- #include <asm/genapic.h>
- #include <asm/fixmap.h>
- #include <asm/apicdef.h>
---- linux-2.6.0-test1/arch/i386/mach-visws/mpparse.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/arch/i386/mach-visws/mpparse.c	2003-07-19 17:04:06.000000000 -0700
-@@ -26,7 +26,7 @@ unsigned int boot_cpu_physical_apicid = 
- unsigned int boot_cpu_logical_apicid = -1U;
- 
- /* Bitmask of physically existing CPUs */
--unsigned long phys_cpu_present_map;
-+cpumask_t phys_cpu_present_map;
- 
- 
- /*
-@@ -38,6 +38,7 @@ unsigned long phys_cpu_present_map;
- void __init MP_processor_info (struct mpc_config_processor *m)
- {
-  	int ver, logical_apicid;
-+	cpumask_t apic_cpus;
-  	
- 	if (!(m->mpc_cpuflag & CPU_ENABLED))
- 		return;
-@@ -62,7 +63,8 @@ void __init MP_processor_info (struct mp
- 	}
- 	ver = m->mpc_apicver;
- 
--	phys_cpu_present_map |= apicid_to_cpu_present(m->mpc_apicid);
-+	apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
-+	cpus_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
- 	/*
- 	 * Validate version
- 	 */
---- linux-2.6.0-test1/arch/i386/mach-voyager/voyager_smp.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/arch/i386/mach-voyager/voyager_smp.c	2003-07-19 17:04:06.000000000 -0700
-@@ -75,15 +75,15 @@ static int voyager_extended_cpus = 1;
- int smp_found_config = 0;
- 
- /* Used for the invalidate map that's also checked in the spinlock */
--volatile unsigned long smp_invalidate_needed;
-+static volatile unsigned long smp_invalidate_needed;
- 
- /* Bitmask of currently online CPUs - used by setup.c for
-    /proc/cpuinfo, visible externally but still physical */
--unsigned long cpu_online_map = 0;
-+cpumask_t cpu_online_map = CPU_MASK_NONE;
- 
- /* Bitmask of CPUs present in the system - exported by i386_syms.c, used
-  * by scheduler but indexed physically */
--unsigned long phys_cpu_present_map = 0;
-+cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
- 
- /* estimate of time used to flush the SMP-local cache - used in
-  * processor affinity calculations */
-@@ -108,7 +108,7 @@ static void enable_local_vic_irq(unsigne
- static void disable_local_vic_irq(unsigned int irq);
- static void before_handle_vic_irq(unsigned int irq);
- static void after_handle_vic_irq(unsigned int irq);
--static void set_vic_irq_affinity(unsigned int irq, unsigned long mask);
-+static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask);
- static void ack_vic_irq(unsigned int irq);
- static void vic_enable_cpi(void);
- static void do_boot_cpu(__u8 cpuid);
-@@ -128,13 +128,12 @@ send_one_QIC_CPI(__u8 cpu, __u8 cpi)
- static inline void
- send_QIC_CPI(__u32 cpuset, __u8 cpi)
- {
--	int mask;
--	__u8 cpu;
-+	int cpu;
- 
--	for_each_cpu(cpu, mask) {
-+	for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
- 		if(cpuset & (1<<cpu)) {
- #ifdef VOYAGER_DEBUG
--			if(!test_bit(cpu, cpu_online_map))
-+			if(!cpu_isset(cpu, cpu_online_map))
- 				VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu));
- #endif
- 			send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
-@@ -155,7 +154,7 @@ static inline void
- send_CPI_allbutself(__u8 cpi)
- {
- 	__u8 cpu = smp_processor_id();
--	__u32 mask = (cpu_online_map & (~(1<<cpu)));
-+	__u32 mask = cpus_coerce(cpu_online_map) & ~(1 << cpu);
- 	send_CPI(mask, cpi);
- }
- 
-@@ -243,11 +242,11 @@ static __u32 cpu_booted_map;
- 
- /* the synchronize flag used to hold all secondary CPUs spinning in
-  * a tight loop until the boot sequence is ready for them */
--static unsigned long smp_commenced_mask = 0;
-+static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
- 
- /* This is for the new dynamic CPU boot code */
--volatile unsigned long cpu_callin_map = 0;
--volatile unsigned long cpu_callout_map = 0;
-+volatile cpumask_t cpu_callin_map = CPU_MASK_NONE;
-+volatile cpumask_t cpu_callout_map = CPU_MASK_NONE;
- 
- /* The per processor IRQ masks (these are usually kept in sync) */
- static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
-@@ -395,7 +394,7 @@ find_smp_config(void)
- 	for(i=0; i<NR_CPUS; i++) {
- 		cpu_irq_affinity[i] = ~0;
- 	}
--	cpu_online_map = (1<<boot_cpu_id);
-+	cpu_online_map = cpumask_of_cpu(boot_cpu_id);
- 
- 	/* The boot CPU must be extended */
- 	voyager_extended_vic_processors = 1<<boot_cpu_id;
-@@ -404,11 +403,11 @@ find_smp_config(void)
- 	/* set up everything for just this CPU, we can alter
- 	 * this as we start the other CPUs later */
- 	/* now get the CPU disposition from the extended CMOS */
--	phys_cpu_present_map = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
--	phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
--	phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
--	phys_cpu_present_map |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
--	printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", phys_cpu_present_map);
-+	phys_cpu_present_map = cpus_promote(voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK));
-+	cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
-+	cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
-+	cpus_coerce(phys_cpu_present_map) |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
-+	printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_coerce(phys_cpu_present_map));
- 	/* Here we set up the VIC to enable SMP */
- 	/* enable the CPIs by writing the base vector to their register */
- 	outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
-@@ -509,18 +508,18 @@ start_secondary(void *unused)
- 	 * permission to proceed.  Without this, the new per CPU stuff
- 	 * in the softirqs will fail */
- 	local_irq_disable();
--	set_bit(cpuid, &cpu_callin_map);
-+	cpu_set(cpuid, cpu_callin_map);
- 
- 	/* signal that we're done */
- 	cpu_booted_map = 1;
- 
--	while (!test_bit(cpuid, &smp_commenced_mask))
-+	while (!cpu_isset(cpuid, smp_commenced_mask))
- 		rep_nop();
- 	local_irq_enable();
- 
- 	local_flush_tlb();
- 
--	set_bit(cpuid, &cpu_online_map);
-+	cpu_set(cpuid, cpu_online_map);
- 	wmb();
- 	return cpu_idle();
- }
-@@ -674,14 +673,14 @@ do_boot_cpu(__u8 cpu)
- 	free_page((unsigned long)page_table_copies);
- #endif
- 	  
--	if(cpu_booted_map) {
-+	if (cpu_booted_map) {
- 		VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
- 			cpu, smp_processor_id()));
- 	
- 		printk("CPU%d: ", cpu);
- 		print_cpu_info(&cpu_data[cpu]);
- 		wmb();
--		set_bit(cpu, &cpu_callout_map);
-+		cpu_set(cpu, cpu_callout_map);
- 	}
- 	else {
- 		printk("CPU%d FAILED TO BOOT: ", cpu);
-@@ -708,13 +707,12 @@ smp_boot_cpus(void)
- 		/* now that the cat has probed the Voyager System Bus, sanity
- 		 * check the cpu map */
- 		if( ((voyager_quad_processors | voyager_extended_vic_processors)
--		     & phys_cpu_present_map) != phys_cpu_present_map) {
-+		     & cpus_coerce(phys_cpu_present_map)) != cpus_coerce(phys_cpu_present_map)) {
- 			/* should panic */
- 			printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n");
- 		}
--	} else if(voyager_level == 4) {
--		voyager_extended_vic_processors = phys_cpu_present_map;
--	}
-+	} else if(voyager_level == 4)
-+		voyager_extended_vic_processors = cpus_coerce(phys_cpu_present_map);
- 
- 	/* this sets up the idle task to run on the current cpu */
- 	voyager_extended_cpus = 1;
-@@ -740,13 +738,13 @@ smp_boot_cpus(void)
- 	/* enable our own CPIs */
- 	vic_enable_cpi();
- 
--	set_bit(boot_cpu_id, &cpu_online_map);
--	set_bit(boot_cpu_id, &cpu_callout_map);
-+	cpu_set(boot_cpu_id, cpu_online_map);
-+	cpu_set(boot_cpu_id, cpu_callout_map);
- 	
- 	/* loop over all the extended VIC CPUs and boot them.  The 
- 	 * Quad CPUs must be bootstrapped by their extended VIC cpu */
- 	for(i = 0; i < NR_CPUS; i++) {
--		if( i == boot_cpu_id || ((1<<i) & (phys_cpu_present_map) ) == 0)
-+		if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
- 			continue;
- 		do_boot_cpu(i);
- 		/* This udelay seems to be needed for the Quad boots
-@@ -758,7 +756,7 @@ smp_boot_cpus(void)
- 	{
- 		unsigned long bogosum = 0;
- 		for (i = 0; i < NR_CPUS; i++)
--			if (cpu_online_map & (1<<i))
-+			if (cpu_isset(i, cpu_online_map))
- 				bogosum += cpu_data[i].loops_per_jiffy;
- 		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
- 			cpucount+1,
-@@ -865,7 +863,7 @@ leave_mm (unsigned long cpu)
- {
- 	if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
- 		BUG();
--	clear_bit(cpu,  &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
-+	cpu_clear(cpu,  cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
- 	load_cr3(swapper_pg_dir);
- }
- 
-@@ -878,7 +876,7 @@ smp_invalidate_interrupt(void)
- {
- 	__u8 cpu = get_cpu();
- 
--	if(!test_bit(cpu, &smp_invalidate_needed))
-+	if (!(smp_invalidate_needed & (1UL << cpu)))
- 		goto out;
- 	/* This will flood messages.  Don't uncomment unless you see
- 	 * Problems with cross cpu invalidation
-@@ -895,7 +893,7 @@ smp_invalidate_interrupt(void)
- 		} else
- 			leave_mm(cpu);
- 	}
--	clear_bit(cpu, &smp_invalidate_needed);
-+	smp_invalidate_needed |= 1UL << cpu;
-  out:
- 	put_cpu_no_resched();
- }
-@@ -912,7 +910,7 @@ flush_tlb_others (unsigned long cpumask,
- 
- 	if (!cpumask)
- 		BUG();
--	if ((cpumask & cpu_online_map) != cpumask)
-+	if ((cpumask & cpus_coerce(cpu_online_map)) != cpumask)
- 		BUG();
- 	if (cpumask & (1 << smp_processor_id()))
- 		BUG();
-@@ -954,7 +952,7 @@ flush_tlb_current_task(void)
- 
- 	preempt_disable();
- 
--	cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+	cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
- 	local_flush_tlb();
- 	if (cpu_mask)
- 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-@@ -970,7 +968,7 @@ flush_tlb_mm (struct mm_struct * mm)
- 
- 	preempt_disable();
- 
--	cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+	cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
- 
- 	if (current->active_mm == mm) {
- 		if (current->mm)
-@@ -991,7 +989,7 @@ void flush_tlb_page(struct vm_area_struc
- 
- 	preempt_disable();
- 
--	cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+	cpu_mask = cpus_coerce(mm->cpu_vm_mask) & ~(1 << smp_processor_id());
- 	if (current->active_mm == mm) {
- 		if(current->mm)
- 			__flush_tlb_one(va);
-@@ -1033,7 +1031,7 @@ static void
- smp_stop_cpu_function(void *dummy)
- {
- 	VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_disable();
- 	for(;;)
- 	       __asm__("hlt");
-@@ -1100,7 +1098,7 @@ smp_call_function (void (*func) (void *i
- 		   int wait)
- {
- 	struct call_data_struct data;
--	__u32 mask = cpu_online_map;
-+	__u32 mask = cpus_coerce(cpu_online_map);
- 
- 	mask &= ~(1<<smp_processor_id());
- 
-@@ -1451,8 +1449,7 @@ smp_intr_init(void)
- static void
- send_CPI(__u32 cpuset, __u8 cpi)
- {
--	int mask;
--	__u8 cpu;
-+	int cpu;
- 	__u32 quad_cpuset = (cpuset & voyager_quad_processors);
- 
- 	if(cpi < VIC_START_FAKE_CPI) {
-@@ -1467,7 +1464,7 @@ send_CPI(__u32 cpuset, __u8 cpi)
- 	cpuset &= 0xff;		/* only first 8 CPUs vaild for VIC CPI */
- 	if(cpuset == 0)
- 		return;
--	for_each_cpu(cpu, mask) {
-+	for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
- 		if(cpuset & (1<<cpu))
- 			set_bit(cpi, &vic_cpi_mailbox[cpu]);
- 	}
-@@ -1571,10 +1568,9 @@ startup_vic_irq(unsigned int irq)
- static void
- enable_vic_irq(unsigned int irq)
- {
--	int tmpmask;
- 	/* linux doesn't to processor-irq affinity, so enable on
- 	 * all CPUs we know about */
--	__u8 cpu = smp_processor_id(), real_cpu;
-+	int cpu = smp_processor_id(), real_cpu;
- 	__u16 mask = (1<<irq);
- 	__u32 processorList = 0;
- 	unsigned long flags;
-@@ -1582,7 +1578,7 @@ enable_vic_irq(unsigned int irq)
- 	VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n",
- 		irq, cpu, cpu_irq_affinity[cpu]));
- 	spin_lock_irqsave(&vic_irq_lock, flags);
--	for_each_cpu(real_cpu, tmpmask) {
-+	for_each_cpu(real_cpu, mk_cpumask_const(cpu_online_map)) {
- 		if(!(voyager_extended_vic_processors & (1<<real_cpu)))
- 			continue;
- 		if(!(cpu_irq_affinity[real_cpu] & mask)) {
-@@ -1727,7 +1723,7 @@ after_handle_vic_irq(unsigned int irq)
- 
- 			printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
- 			       cpu, irq);
--			for_each_cpu(real_cpu, mask) {
-+			for_each_cpu(real_cpu, mk_cpumask_const(mask)) {
- 
- 				outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
- 				     VIC_PROCESSOR_ID);
-@@ -1783,15 +1779,16 @@ after_handle_vic_irq(unsigned int irq)
-  * the selected processors */
- 
- void
--set_vic_irq_affinity(unsigned int irq, unsigned long mask) 
-+set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
- {
- 	/* Only extended processors handle interrupts */
--	unsigned long real_mask = mask & voyager_extended_vic_processors;
--	unsigned long irq_mask = (1<<irq);
--	int tmpmask;
--	__u8 cpu;
-+	unsigned long real_mask;
-+	unsigned long irq_mask = 1 << irq;
-+	int cpu;
-+
-+	real_mask = cpus_coerce(mask) & voyager_extended_vic_processors;
- 	
--	if(mask == 0)
-+	if(cpus_coerce(mask) == 0)
- 		/* can't have no cpu's to accept the interrupt -- extremely
- 		 * bad things will happen */
- 		return;
-@@ -1811,8 +1808,8 @@ set_vic_irq_affinity(unsigned int irq, u
- 		 * bus) */
- 		return;
- 
--	for_each_cpu(cpu, tmpmask) {
--		unsigned long cpu_mask = (1<<cpu);
-+	for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
-+		unsigned long cpu_mask = 1 << cpu;
- 		
- 		if(cpu_mask & real_mask) {
- 			/* enable the interrupt for this cpu */
-@@ -1874,11 +1871,10 @@ vic_enable_cpi(void)
- void
- voyager_smp_dump()
- {
--	int mask;
--	__u8 old_cpu = smp_processor_id(), cpu;
-+	int old_cpu = smp_processor_id(), cpu;
- 
- 	/* dump the interrupt masks of each processor */
--	for_each_cpu(cpu, mask) {
-+	for_each_cpu(cpu, mk_cpumask_const(cpu_online_map)) {
- 		__u16 imr, isr, irr;
- 		unsigned long flags;
- 
-@@ -1936,23 +1932,23 @@ smp_prepare_cpus(unsigned int max_cpus)
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_callout_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_callout_map);
- }
- 
- int __devinit
- __cpu_up(unsigned int cpu)
- {
- 	/* This only works at boot for x86.  See "rewrite" above. */
--	if (test_bit(cpu, &smp_commenced_mask))
-+	if (cpu_isset(cpu, smp_commenced_mask))
- 		return -ENOSYS;
- 
- 	/* In case one didn't come up */
--	if (!test_bit(cpu, &cpu_callin_map))
-+	if (!cpu_isset(cpu, cpu_callin_map))
- 		return -EIO;
- 	/* Unleash the CPU! */
--	set_bit(cpu, &smp_commenced_mask);
--	while (!test_bit(cpu, &cpu_online_map))
-+	cpu_set(cpu, smp_commenced_mask);
-+	while (!cpu_isset(cpu, cpu_online_map))
- 		mb();
- 	return 0;
- }
---- linux-2.6.0-test1/arch/i386/Makefile	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/Makefile	2003-07-19 17:04:05.000000000 -0700
-@@ -85,6 +85,9 @@ mcore-$(CONFIG_X86_ES7000)	:= mach-es700
- # default subarch .h files
- mflags-y += -Iinclude/asm-i386/mach-default
- 
-+mflags-$(CONFIG_KGDB) += -ggdb
-+mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
-+
- head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
- 
- libs-y 					+= arch/i386/lib/
---- linux-2.6.0-test1/arch/i386/mm/fault.c	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/mm/fault.c	2003-07-19 17:07:16.000000000 -0700
-@@ -236,6 +236,12 @@ no_context:
-  * Oops. The kernel tried to access some bad page. We'll have to
-  * terminate things with extreme prejudice.
-  */
-+#ifdef CONFIG_KGDB
-+        if (!user_mode(regs)){
-+                kgdb_handle_exception(14,SIGBUS, error_code, regs);
-+                return;
-+        }
-+#endif
- 
- 	bust_spinlocks(1);
- 
-@@ -247,6 +253,13 @@ no_context:
- 	printk(" printing eip:\n");
- 	printk("%08lx\n", regs->eip);
- 	asm("movl %%cr3,%0":"=r" (page));
-+#ifdef CONFIG_HIGHPMD /* Oh boy. Error reporting is going to blow major goats. */
-+	printk(KERN_ALERT "%%cr3 = 0x%lx\n", page);
-+	/* Mask off flag bits. It should end up 32B-aligned. */
-+	page &= ~(PTRS_PER_PGD*sizeof(pgd_t) - 1);
-+	printk(KERN_ALERT "*pdpte = 0x%Lx\n",
-+			pgd_val(((pgd_t *)__va(page))[address >> PGDIR_SHIFT]));
-+#else /* !CONFIG_HIGHPMD */
- 	page = ((unsigned long *) __va(page))[address >> 22];
- 	printk(KERN_ALERT "*pde = %08lx\n", page);
- 	/*
-@@ -262,7 +275,8 @@ no_context:
- 		page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
- 		printk(KERN_ALERT "*pte = %08lx\n", page);
- 	}
--#endif
-+#endif /* !CONFIG_HIGHPTE */
-+#endif /* CONFIG_HIGHPMD */
- 	die("Oops", regs, error_code);
- 	bust_spinlocks(0);
- 	do_exit(SIGKILL);
-@@ -330,8 +344,8 @@ vmalloc_fault:
- 		 * and redundant with the set_pmd() on non-PAE.
- 		 */
- 
--		pmd = pmd_offset(pgd, address);
--		pmd_k = pmd_offset(pgd_k, address);
-+		pmd = pmd_offset_kernel(pgd, address);
-+		pmd_k = pmd_offset_kernel(pgd_k, address);
- 		if (!pmd_present(*pmd_k))
- 			goto no_context;
- 		set_pmd(pmd, *pmd_k);
---- linux-2.6.0-test1/arch/i386/mm/hugetlbpage.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/i386/mm/hugetlbpage.c	2003-07-19 17:07:16.000000000 -0700
-@@ -87,8 +87,8 @@ static pte_t *huge_pte_alloc(struct mm_s
- 	pmd_t *pmd = NULL;
- 
- 	pgd = pgd_offset(mm, addr);
--	pmd = pmd_alloc(mm, pgd, addr);
--	return (pte_t *) pmd;
-+	pmd = pmd_alloc_map(mm, pgd, addr);
-+	return (pte_t *)pmd;
- }
- 
- static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
-@@ -97,8 +97,8 @@ static pte_t *huge_pte_offset(struct mm_
- 	pmd_t *pmd = NULL;
- 
- 	pgd = pgd_offset(mm, addr);
--	pmd = pmd_offset(pgd, addr);
--	return (pte_t *) pmd;
-+	pmd = pmd_offset_map_nested(pgd, addr);
-+	return (pte_t *)pmd;
- }
- 
- static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access)
-@@ -145,6 +145,8 @@ int copy_hugetlb_page_range(struct mm_st
- 		ptepage = pte_page(entry);
- 		get_page(ptepage);
- 		set_pte(dst_pte, entry);
-+		pmd_unmap(dst_pte);
-+		pmd_unmap_nested(src_pte);
- 		dst->rss += (HPAGE_SIZE / PAGE_SIZE);
- 		addr += HPAGE_SIZE;
- 	}
-@@ -182,6 +184,7 @@ follow_hugetlb_page(struct mm_struct *mm
- 
- 			get_page(page);
- 			pages[i] = page;
-+			pmd_unmap_nested(pte);
- 		}
- 
- 		if (vmas)
-@@ -271,6 +274,7 @@ follow_huge_pmd(struct mm_struct *mm, un
- 		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
- 		get_page(page);
- 	}
-+	pmd_unmap(pmd);
- 	return page;
- }
- #endif
-@@ -314,6 +318,7 @@ void unmap_hugepage_range(struct vm_area
- 		page = pte_page(*pte);
- 		huge_page_release(page);
- 		pte_clear(pte);
-+		pmd_unmap_nested(pte);
- 	}
- 	mm->rss -= (end - start) >> PAGE_SHIFT;
- 	flush_tlb_range(vma, start, end);
-@@ -348,8 +353,10 @@ int hugetlb_prefault(struct address_spac
- 			ret = -ENOMEM;
- 			goto out;
- 		}
--		if (!pte_none(*pte))
-+		if (!pte_none(*pte)) {
-+			pmd_unmap(pte);
- 			continue;
-+		}
- 
- 		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
- 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-@@ -358,16 +365,19 @@ int hugetlb_prefault(struct address_spac
- 			page = alloc_hugetlb_page();
- 			if (!page) {
- 				ret = -ENOMEM;
-+				pmd_unmap(pte);
- 				goto out;
- 			}
- 			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
- 			unlock_page(page);
- 			if (ret) {
- 				free_huge_page(page);
-+				pmd_unmap(pte);
- 				goto out;
- 			}
- 		}
- 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
-+		pmd_unmap(pte);
- 	}
- out:
- 	spin_unlock(&mm->page_table_lock);
---- linux-2.6.0-test1/arch/i386/mm/init.c	2003-06-26 22:07:23.000000000 -0700
-+++ 25/arch/i386/mm/init.c	2003-07-19 17:07:16.000000000 -0700
-@@ -20,9 +20,6 @@
- #include <linux/swap.h>
- #include <linux/smp.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
--#endif
- #include <linux/highmem.h>
- #include <linux/pagemap.h>
- #include <linux/bootmem.h>
-@@ -59,10 +56,10 @@ static pmd_t * __init one_md_table_init(
- #ifdef CONFIG_X86_PAE
- 	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- 	set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
--	if (pmd_table != pmd_offset(pgd, 0)) 
-+	if (pmd_table != pmd_offset_kernel(pgd, 0))
- 		BUG();
- #else
--	pmd_table = pmd_offset(pgd, 0);
-+	pmd_table = pmd_offset_kernel(pgd, 0);
- #endif
- 
- 	return pmd_table;
-@@ -113,7 +110,7 @@ static void __init page_table_range_init
- 		if (pgd_none(*pgd)) 
- 			one_md_table_init(pgd);
- 
--		pmd = pmd_offset(pgd, vaddr);
-+		pmd = pmd_offset_kernel(pgd, vaddr);
- 		for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
- 			if (pmd_none(*pmd)) 
- 				one_page_table_init(pmd);
-@@ -194,7 +191,7 @@ pte_t *kmap_pte;
- pgprot_t kmap_prot;
- 
- #define kmap_get_fixmap_pte(vaddr)					\
--	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
-+	pte_offset_kernel(pmd_offset_kernel(pgd_offset_k(vaddr), (vaddr)), (vaddr))
- 
- void __init kmap_init(void)
- {
-@@ -218,7 +215,7 @@ void __init permanent_kmaps_init(pgd_t *
- 	page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
- 
- 	pgd = swapper_pg_dir + pgd_index(vaddr);
--	pmd = pmd_offset(pgd, vaddr);
-+	pmd = pmd_offset_kernel(pgd, vaddr);
- 	pte = pte_offset_kernel(pmd, vaddr);
- 	pkmap_page_table = pte;	
- }
-@@ -512,20 +509,19 @@ void __init mem_init(void)
- #endif
- }
- 
--#ifdef CONFIG_X86_PAE
--struct kmem_cache_s *pae_pgd_cachep;
-+kmem_cache_t *pgd_cache;
- 
- void __init pgtable_cache_init(void)
- {
--        /*
--         * PAE pgds must be 16-byte aligned:
--         */
--        pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
--                SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
--        if (!pae_pgd_cachep)
--                panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
-+	pgd_cache = kmem_cache_create("pgd",
-+				PTRS_PER_PGD*sizeof(pgd_t),
-+				0,
-+				SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
-+				pgd_ctor,
-+				PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
-+	if (!pgd_cache)
-+		panic("pgtable_cache_init(): Cannot create pgd cache");
- }
--#endif
- 
- /*
-  * This function cannot be __init, since exceptions don't work in that
-@@ -565,7 +561,7 @@ void free_initmem(void)
- 		free_page(addr);
- 		totalram_pages++;
- 	}
--	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
-+	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
- }
- 
- #ifdef CONFIG_BLK_DEV_INITRD
---- linux-2.6.0-test1/arch/i386/mm/ioremap.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/arch/i386/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -82,7 +82,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/i386/mm/pageattr.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/mm/pageattr.c	2003-07-19 17:07:16.000000000 -0700
-@@ -23,7 +23,7 @@ static inline pte_t *lookup_address(unsi
- 	pmd_t *pmd;
- 	if (pgd_none(*pgd))
- 		return NULL;
--	pmd = pmd_offset(pgd, address); 	       
-+	pmd = pmd_offset_kernel(pgd, address);
- 	if (pmd_none(*pmd))
- 		return NULL;
- 	if (pmd_large(*pmd))
-@@ -67,19 +67,22 @@ static void flush_kernel_map(void *dummy
- 
- static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) 
- { 
-+	struct page *page;
-+	unsigned long flags;
-+
- 	set_pte_atomic(kpte, pte); 	/* change init_mm */
--#ifndef CONFIG_X86_PAE
--	{
--		struct list_head *l;
--		spin_lock(&mmlist_lock);
--		list_for_each(l, &init_mm.mmlist) { 
--			struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
--			pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
--			set_pte_atomic((pte_t *)pmd, pte);
--		} 
--		spin_unlock(&mmlist_lock);
-+	if (PTRS_PER_PMD > 1)
-+		return;
-+
-+	spin_lock_irqsave(&pgd_lock, flags);
-+	list_for_each_entry(page, &pgd_list, lru) {
-+		pgd_t *pgd;
-+		pmd_t *pmd;
-+		pgd = (pgd_t *)page_address(page) + pgd_index(address);
-+		pmd = pmd_offset_kernel(pgd, address);
-+		set_pte_atomic((pte_t *)pmd, pte);
- 	}
--#endif
-+	spin_unlock_irqrestore(&pgd_lock, flags);
- }
- 
- /* 
-@@ -89,7 +92,7 @@ static void set_pmd_pte(pte_t *kpte, uns
- static inline void revert_page(struct page *kpte_page, unsigned long address)
- {
- 	pte_t *linear = (pte_t *) 
--		pmd_offset(pgd_offset(&init_mm, address), address);
-+		pmd_offset_kernel(pgd_offset_k(address), address);
- 	set_pmd_pte(linear,  address,
- 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
- 			    PAGE_KERNEL_LARGE));
---- linux-2.6.0-test1/arch/i386/mm/pgtable.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/mm/pgtable.c	2003-07-19 17:07:16.000000000 -0700
-@@ -12,6 +12,7 @@
- #include <linux/highmem.h>
- #include <linux/slab.h>
- #include <linux/pagemap.h>
-+#include <linux/spinlock.h>
- 
- #include <asm/system.h>
- #include <asm/pgtable.h>
-@@ -69,7 +70,7 @@ static void set_pte_pfn(unsigned long va
- 		BUG();
- 		return;
- 	}
--	pmd = pmd_offset(pgd, vaddr);
-+	pmd = pmd_offset_kernel(pgd, vaddr);
- 	if (pmd_none(*pmd)) {
- 		BUG();
- 		return;
-@@ -109,7 +110,7 @@ void set_pmd_pfn(unsigned long vaddr, un
- 		printk ("set_pmd_pfn: pgd_none\n");
- 		return; /* BUG(); */
- 	}
--	pmd = pmd_offset(pgd, vaddr);
-+	pmd = pmd_offset_kernel(pgd, vaddr);
- 	set_pmd(pmd, pfn_pmd(pfn, flags));
- 	/*
- 	 * It's enough to flush this one mapping.
-@@ -151,61 +152,89 @@ struct page *pte_alloc_one(struct mm_str
- 	return pte;
- }
- 
--#ifdef CONFIG_X86_PAE
-+/*
-+ * List of all pgd's needed for non-PAE so it can invalidate entries
-+ * in both cached and uncached pgd's; not needed for PAE since the
-+ * kernel pmd is shared. If PAE were not to share the pmd a similar
-+ * tactic would be needed. This is essentially codepath-based locking
-+ * against pageattr.c; it is the unique case in which a valid change
-+ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
-+ * vmalloc faults work because attached pagetables are never freed.
-+ * If the locking proves to be non-performant, a ticketing scheme with
-+ * checks at dup_mmap(), exec(), and other mmlist addition points
-+ * could be used. The locking scheme was chosen on the basis of
-+ * manfred's recommendations and having no core impact whatsoever.
-+ * -- wli
-+ */
-+spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
-+LIST_HEAD(pgd_list);
- 
--pgd_t *pgd_alloc(struct mm_struct *mm)
-+void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
- {
--	int i;
--	pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
-+	unsigned long flags;
- 
--	if (pgd) {
--		for (i = 0; i < USER_PTRS_PER_PGD; i++) {
--			unsigned long pmd = __get_free_page(GFP_KERNEL);
--			if (!pmd)
--				goto out_oom;
--			clear_page(pmd);
--			set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
--		}
--		memcpy(pgd + USER_PTRS_PER_PGD,
-+	if (PTRS_PER_PMD == 1)
-+		spin_lock_irqsave(&pgd_lock, flags);
-+
-+	memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
- 			swapper_pg_dir + USER_PTRS_PER_PGD,
- 			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
--	}
--	return pgd;
--out_oom:
--	for (i--; i >= 0; i--)
--		free_page((unsigned long)__va(pgd_val(pgd[i])-1));
--	kmem_cache_free(pae_pgd_cachep, pgd);
--	return NULL;
-+
-+	if (PTRS_PER_PMD > 1)
-+		return;
-+
-+	list_add(&virt_to_page(pgd)->lru, &pgd_list);
-+	spin_unlock_irqrestore(&pgd_lock, flags);
-+	memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
- }
- 
--void pgd_free(pgd_t *pgd)
-+/* never called when PTRS_PER_PMD > 1 */
-+void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
- {
--	int i;
-+	unsigned long flags; /* can be called from interrupt context */
- 
--	for (i = 0; i < USER_PTRS_PER_PGD; i++)
--		free_page((unsigned long)__va(pgd_val(pgd[i])-1));
--	kmem_cache_free(pae_pgd_cachep, pgd);
-+	spin_lock_irqsave(&pgd_lock, flags);
-+	list_del(&virt_to_page(pgd)->lru);
-+	spin_unlock_irqrestore(&pgd_lock, flags);
- }
- 
--#else
--
- pgd_t *pgd_alloc(struct mm_struct *mm)
- {
--	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
-+	int i;
-+	pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
- 
--	if (pgd) {
--		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
--		memcpy(pgd + USER_PTRS_PER_PGD,
--			swapper_pg_dir + USER_PTRS_PER_PGD,
--			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-+	if (PTRS_PER_PMD == 1 || !pgd)
-+		return pgd;
-+
-+	for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-+		struct page *pmd;
-+#ifdef CONFIG_HIGHPMD
-+		pmd = alloc_page(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT);
-+#else
-+		pmd = alloc_page(GFP_KERNEL|__GFP_REPEAT);
-+#endif
-+		if (!pmd)
-+			goto out_oom;
-+		clear_highpage(pmd);
-+		set_pgd(&pgd[i], __pgd(1ULL | (u64)page_to_pfn(pmd) << PAGE_SHIFT));
- 	}
- 	return pgd;
-+
-+out_oom:
-+	for (i--; i >= 0; i--)
-+		__free_page(pgd_page(pgd[i]));
-+	kmem_cache_free(pgd_cache, pgd);
-+	return NULL;
- }
- 
- void pgd_free(pgd_t *pgd)
- {
--	free_page((unsigned long)pgd);
--}
--
--#endif /* CONFIG_X86_PAE */
-+	int i;
- 
-+	/* in the PAE case user pgd entries are overwritten before usage */
-+	if (PTRS_PER_PMD > 1)
-+		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
-+			__free_page(pgd_page(pgd[i]));
-+	/* in the non-PAE case, clear_page_tables() clears user pgd entries */
-+	kmem_cache_free(pgd_cache, pgd);
-+}
---- linux-2.6.0-test1/arch/i386/pci/legacy.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/i386/pci/legacy.c	2003-07-19 17:03:49.000000000 -0700
-@@ -24,7 +24,7 @@ static void __devinit pcibios_fixup_peer
- 		for (devfn = 0; devfn < 256; devfn += 8) {
- 			if (!raw_pci_ops->read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
- 			    l != 0x0000 && l != 0xffff) {
--				DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
-+				DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
- 				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
- 				pci_scan_bus(n, &pci_root_ops, NULL);
- 				break;
---- linux-2.6.0-test1/arch/i386/pci/visws.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/i386/pci/visws.c	2003-07-19 17:03:49.000000000 -0700
-@@ -17,7 +17,7 @@
- 
- int broken_hp_bios_irq9;
- 
--extern struct pci_ops pci_direct_conf1;
-+extern struct pci_raw_ops pci_direct_conf1;
- 
- static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
- 
-@@ -101,8 +101,9 @@ static int __init pcibios_init(void)
- 	printk(KERN_INFO "PCI: Lithium bridge A bus: %u, "
- 		"bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0);
- 
--	pci_scan_bus(pci_bus0, &pci_direct_conf1, NULL);
--	pci_scan_bus(pci_bus1, &pci_direct_conf1, NULL);
-+	raw_pci_ops = &pci_direct_conf1;
-+	pci_scan_bus(pci_bus0, &pci_root_ops, NULL);
-+	pci_scan_bus(pci_bus1, &pci_root_ops, NULL);
- 	pci_fixup_irqs(visws_swizzle, visws_map_irq);
- 	pcibios_resource_survey();
- 	return 0;
---- linux-2.6.0-test1/arch/ia64/hp/sim/simscsi.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/hp/sim/simscsi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -9,7 +9,7 @@
-  * 99/12/18 David Mosberger	Added support for READ10/WRITE10 needed by linux v2.3.33
-  */
- #include <linux/config.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/kernel.h>
---- linux-2.6.0-test1/arch/ia64/ia32/ia32_ioctl.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/ia64/ia32/ia32_ioctl.c	2003-07-19 17:03:49.000000000 -0700
-@@ -52,7 +52,7 @@
- #include <linux/raw.h>
- #include <linux/smb_fs.h>
- #include <linux/blkpg.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/elevator.h>
- #include <linux/rtc.h>
- #include <linux/pci.h>
---- linux-2.6.0-test1/arch/ia64/kernel/acpi.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/acpi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -720,7 +720,7 @@ acpi_register_irq (u32 gsi, u32 polarity
- {
- 	int vector = 0;
- 
--	if (acpi_madt->flags.pcat_compat && (gsi < 16))
-+	if (has_8259 && (gsi < 16))
- 		return isa_irq_to_vector(gsi);
- 
- 	if (!iosapic_register_intr)
---- linux-2.6.0-test1/arch/ia64/kernel/entry.S	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/kernel/entry.S	2003-07-19 17:03:49.000000000 -0700
-@@ -61,7 +61,17 @@ ENTRY(ia64_execve)
- 	mov out2=in2			// envp
- 	add out3=16,sp			// regs
- 	br.call.sptk.many rp=sys_execve
--.ret0:	cmp4.ge p6,p7=r8,r0
-+.ret0:
-+#ifdef CONFIG_IA32_SUPPORT
-+	/*
-+	 * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers
-+	 * from pt_regs.
-+	 */
-+	adds r16=PT(CR_IPSR)+16,sp
-+	;;
-+	ld8 r16=[r16]
-+#endif
-+	cmp4.ge p6,p7=r8,r0
- 	mov ar.pfs=loc1			// restore ar.pfs
- 	sxt4 r8=r8			// return 64-bit result
- 	;;
-@@ -89,6 +99,12 @@ ENTRY(ia64_execve)
- 	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
- 	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
- 	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
-+#ifdef CONFIG_IA32_SUPPORT
-+	tbit.nz p6,p0=r16, IA64_PSR_IS_BIT
-+	movl loc0=ia64_ret_from_ia32_execve
-+	;;
-+(p6)	mov rp=loc0
-+#endif
- 	br.ret.sptk.many rp
- END(ia64_execve)
- 
-@@ -688,7 +704,7 @@ GLOBAL_ENTRY(ia64_leave_syscall)
- 	mov b7=r0		// clear b7
- 	;;
- (pUStk) st1 [r14]=r3
--	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
-+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
- 	;;
- 	mov r16=ar.bsp		// get existing backing store pointer
- 	srlz.i			// ensure interruption collection is off
-@@ -701,6 +717,19 @@ GLOBAL_ENTRY(ia64_leave_syscall)
- 	br.cond.sptk.many rbs_switch
- END(ia64_leave_syscall)
- 
-+#ifdef CONFIG_IA32_SUPPORT
-+GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
-+	PT_REGS_UNWIND_INFO(0)
-+	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
-+	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
-+	;;
-+	.mem.offset 0,0
-+	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
-+	.mem.offset 8,0
-+	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
-+END(ia64_ret_from_ia32_execve_syscall)
-+	// fall through
-+#endif /* CONFIG_IA32_SUPPORT */
- GLOBAL_ENTRY(ia64_leave_kernel)
- 	PT_REGS_UNWIND_INFO(0)
- 	/*
-@@ -841,7 +870,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
- 	shr.u r18=r19,16	// get byte size of existing "dirty" partition
- 	;;
- 	mov r16=ar.bsp		// get existing backing store pointer
--	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
-+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
- 	;;
- 	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
- (pKStk)	br.cond.dpnt skip_rbs_switch
---- linux-2.6.0-test1/arch/ia64/kernel/fsys.S	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/kernel/fsys.S	2003-07-19 17:03:49.000000000 -0700
-@@ -165,7 +165,7 @@ ENTRY(fsys_gettimeofday)
- 	.altrp b6
- 	.body
- 	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
--	movl r3=THIS_CPU(cpu_info)
-+	addl r3=THIS_CPU(cpu_info),r0
- 
- 	mov.m r31=ar.itc		// put time stamp into r31 (ITC) == now		(35 cyc)
- #ifdef CONFIG_SMP
-@@ -177,7 +177,7 @@ ENTRY(fsys_gettimeofday)
- 	movl r19=xtime			// xtime is a timespec struct
- 
- 	ld8 r10=[r10]			// r10 <- __per_cpu_offset[0]
--	movl r21=THIS_CPU(cpu_info)
-+	addl r21=THIS_CPU(cpu_info),r0
- 	;;
- 	add r10=r21, r10		// r10 <- &cpu_data(time_keeper_id)
- 	tbit.nz p8,p0 = r2, IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT
---- linux-2.6.0-test1/arch/ia64/kernel/ia64_ksyms.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/ia64/kernel/ia64_ksyms.c	2003-07-19 17:03:49.000000000 -0700
-@@ -64,9 +64,10 @@ EXPORT_SYMBOL(ia64_pfn_valid);
- #endif
- 
- #include <asm/processor.h>
--EXPORT_SYMBOL(cpu_info__per_cpu);
-+EXPORT_SYMBOL(per_cpu__cpu_info);
- #ifdef CONFIG_SMP
- EXPORT_SYMBOL(__per_cpu_offset);
-+EXPORT_SYMBOL(per_cpu__local_per_cpu_offset);
- #endif
- EXPORT_SYMBOL(kernel_thread);
- 
---- linux-2.6.0-test1/arch/ia64/kernel/init_task.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/init_task.c	2003-07-19 17:03:49.000000000 -0700
-@@ -2,7 +2,7 @@
-  * This is where we statically allocate and initialize the initial
-  * task.
-  *
-- * Copyright (C) 1999, 2002 Hewlett-Packard Co
-+ * Copyright (C) 1999, 2002-2003 Hewlett-Packard Co
-  *	David Mosberger-Tang <davidm@hpl.hp.com>
-  */
- 
-@@ -34,7 +34,7 @@ static union {
- 		struct thread_info thread_info;
- 	} s;
- 	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
--} init_task_mem __attribute__((section(".data.init_task"))) = {{
-+} init_task_mem asm ("init_task_mem") __attribute__((section(".data.init_task"))) = {{
- 	.task =		INIT_TASK(init_task_mem.s.task),
- 	.thread_info =	INIT_THREAD_INFO(init_task_mem.s.task)
- }};
---- linux-2.6.0-test1/arch/ia64/kernel/iosapic.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/iosapic.c	2003-07-19 17:04:06.000000000 -0700
-@@ -274,7 +274,7 @@ unmask_irq (unsigned int irq)
- 
- 
- static void
--iosapic_set_affinity (unsigned int irq, unsigned long mask)
-+iosapic_set_affinity (unsigned int irq, cpumask_t mask)
- {
- #ifdef CONFIG_SMP
- 	unsigned long flags;
-@@ -287,12 +287,10 @@ iosapic_set_affinity (unsigned int irq, 
- 	irq &= (~IA64_IRQ_REDIRECTED);
- 	vec = irq_to_vector(irq);
- 
--	mask &= cpu_online_map;
--
--	if (!mask || vec >= IA64_NUM_VECTORS)
-+	if (cpus_empty(mask) || vec >= IA64_NUM_VECTORS)
- 		return;
- 
--	dest = cpu_physical_id(ffz(~mask));
-+	dest = cpu_physical_id(first_cpu(mask));
- 
- 	rte_index = iosapic_intr_info[vec].rte_index;
- 	addr = iosapic_intr_info[vec].addr;
-@@ -717,6 +715,7 @@ iosapic_parse_prt (void)
- 			register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
- 				      IOSAPIC_LEVEL);
- 		}
-+		entry->irq = vector;
- 		snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
- 			 entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
- 
---- linux-2.6.0-test1/arch/ia64/kernel/irq.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/irq.c	2003-07-19 17:04:06.000000000 -0700
-@@ -898,13 +898,14 @@ int setup_irq(unsigned int irq, struct i
- static struct proc_dir_entry * root_irq_dir;
- static struct proc_dir_entry * irq_dir [NR_IRQS];
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
--static unsigned int parse_hex_value (const char *buffer,
--		unsigned long count, unsigned long *ret)
-+static unsigned int parse_hex_value(const char *buffer,
-+		unsigned long count, cpumask_t *ret)
- {
--	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value, i;
-+	unsigned char hexnum[HEX_DIGITS];
-+	cpumask_t value = CPU_MASK_NONE;
-+	unsigned long i;
- 
- 	if (!count)
- 		return -EINVAL;
-@@ -917,10 +918,9 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
--
- 	for (i = 0; i < count; i++) {
- 		unsigned int c = hexnum[i];
-+		int k;
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -929,7 +929,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (test_bit(k, (unsigned long *)&c))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -940,12 +943,15 @@ out:
- 
- static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
- 
--static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-+static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-+
- static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
- 
- void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
- {
--	unsigned long mask = 1UL<<cpu_logical_id(hwid);
-+	cpumask_t mask = CPU_MASK_NONE;
-+
-+	cpu_set(cpu_logical_id(hwid), mask);
- 
- 	if (irq < NR_IRQS) {
- 		irq_affinity[irq] = mask;
-@@ -956,10 +962,21 @@ void set_irq_affinity_info (unsigned int
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	if (count < HEX_DIGITS+3)
-+	int k, len;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
-+	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%s%08lx\n", irq_redir[(unsigned long)data] ? "r " : "",
--			irq_affinity[(unsigned long)data]);
-+
-+	len = 0;
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int irq_affinity_write_proc (struct file *file, const char *buffer,
-@@ -967,7 +984,7 @@ static int irq_affinity_write_proc (stru
- {
- 	unsigned int irq = (unsigned long) data;
- 	int full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 	const char *buf = buffer;
- 	irq_desc_t *desc = irq_descp(irq);
- 	int redir;
-@@ -991,7 +1008,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	desc->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value);
-@@ -1003,18 +1021,28 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	cpumask_t *mask = (cpumask_t *)data;
-+	int k, len = 0;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(unsigned long); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(*mask));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(*mask, *mask, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
--	int full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data;
-+	unsigned long full_count = count, err;
-+	cpumask_t new_value;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
-@@ -1058,7 +1086,7 @@ static void register_irq_proc (unsigned 
- #endif
- }
- 
--unsigned long prof_cpu_mask = -1;
-+cpumask_t prof_cpu_mask = CPU_MASK_ALL;
- 
- void init_irq_proc (void)
- {
---- linux-2.6.0-test1/arch/ia64/kernel/module.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/ia64/kernel/module.c	2003-07-19 17:03:49.000000000 -0700
-@@ -164,7 +164,7 @@ static int
- apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
- {
- 	if (slot(insn) != 2) {
--		printk(KERN_ERR "%s: illegal slot number %d for IMM64\n",
-+		printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
- 		       mod->name, slot(insn));
- 		return 0;
- 	}
-@@ -176,7 +176,7 @@ static int
- apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
- {
- 	if (slot(insn) != 2) {
--		printk(KERN_ERR "%s: illegal slot number %d for IMM60\n",
-+		printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
- 		       mod->name, slot(insn));
- 		return 0;
- 	}
---- linux-2.6.0-test1/arch/ia64/kernel/perfmon.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/perfmon.c	2003-07-19 17:04:06.000000000 -0700
-@@ -221,14 +221,6 @@
- 
- #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
- 
--#ifdef CONFIG_SMP
--#define PFM_CPU_ONLINE_MAP	cpu_online_map
--#define cpu_is_online(i)	(PFM_CPU_ONLINE_MAP & (1UL << i))
--#else
--#define PFM_CPU_ONLINE_MAP	 1UL
--#define cpu_is_online(i)	(i==0)
--#endif
--
- /*
-  * cmp0 must be the value of pmc0
-  */
-@@ -566,7 +558,7 @@ static struct vm_operations_struct pfm_v
- 
- 
- #define pfm_wait_task_inactive(t)	wait_task_inactive(t)
--#define pfm_get_cpu_var(v)		__get_cpu_var(v)
-+#define pfm_get_cpu_var(v)		__ia64_per_cpu_var(v)
- #define pfm_get_cpu_data(a,b)		per_cpu(a, b)
- typedef	irqreturn_t	pfm_irq_handler_t;
- #define PFM_IRQ_HANDLER_RET(v)	do {  \
-@@ -5354,7 +5346,7 @@ pfm_proc_info(char *page)
- 		p += sprintf(p, "ovfl_mask                 : 0x%lx\n", pmu_conf.ovfl_val);
- 
- 	for(i=0; i < NR_CPUS; i++) {
--		if (cpu_is_online(i) == 0) continue;
-+		if (cpu_online(i) == 0) continue;
- 		p += sprintf(p, "CPU%-2d overflow intrs      : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
- 		p += sprintf(p, "CPU%-2d overflow cycles     : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles);
- 		p += sprintf(p, "CPU%-2d overflow min        : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_min);
-@@ -5372,7 +5364,7 @@ pfm_proc_info(char *page)
- 		p += sprintf(p, "CPU%-2d activations         : %lu\n", i, pfm_get_cpu_data(pmu_activation_number,i));
- 	}
- 
--	if (hweight64(PFM_CPU_ONLINE_MAP) == 1)
-+	if (num_online_cpus() == 1)
- 	{
- 		psr = pfm_get_psr();
- 		ia64_srlz_d();
---- linux-2.6.0-test1/arch/ia64/kernel/ptrace.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/kernel/ptrace.c	2003-07-19 17:03:49.000000000 -0700
-@@ -42,7 +42,7 @@
- 	(IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
- #define IPSR_READ_MASK	IPSR_WRITE_MASK
- 
--#define PTRACE_DEBUG	1
-+#define PTRACE_DEBUG	0
- 
- #if PTRACE_DEBUG
- # define dprintk(format...)	printk(format)
---- linux-2.6.0-test1/arch/ia64/kernel/setup.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/ia64/kernel/setup.c	2003-07-19 17:04:07.000000000 -0700
-@@ -56,6 +56,7 @@ unsigned long __per_cpu_offset[NR_CPUS];
- #endif
- 
- DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
-+DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
- DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
- unsigned long ia64_cycles_per_usec;
- struct ia64_boot_param *ia64_boot_param;
-@@ -558,7 +559,7 @@ static void *
- c_start (struct seq_file *m, loff_t *pos)
- {
- #ifdef CONFIG_SMP
--	while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
-+	while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
- 		++*pos;
- #endif
- 	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
-@@ -709,6 +710,8 @@ cpu_init (void)
- 			memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
- 			__per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
- 			cpu_data += PERCPU_PAGE_SIZE;
-+
-+			per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
- 		}
- 	}
- 	cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-@@ -716,19 +719,18 @@ cpu_init (void)
- 	cpu_data = __phys_per_cpu_start;
- #endif /* !CONFIG_SMP */
- 
--	cpu_info = cpu_data + ((char *) &__get_cpu_var(cpu_info) - __per_cpu_start);
--#ifdef CONFIG_NUMA
--	cpu_info->node_data = get_node_data_ptr();
--#endif
--
- 	get_max_cacheline_size();
- 
- 	/*
- 	 * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
- 	 * ia64_mmu_init() yet.  And we can't call ia64_mmu_init() first because it
- 	 * depends on the data returned by identify_cpu().  We break the dependency by
--	 * accessing cpu_data() the old way, through identity mapped space.
-+	 * accessing cpu_data() through the canonical per-CPU address.
- 	 */
-+	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
-+#ifdef CONFIG_NUMA
-+	cpu_info->node_data = get_node_data_ptr();
-+#endif
- 	identify_cpu(cpu_info);
- 
- #ifdef CONFIG_MCKINLEY
---- linux-2.6.0-test1/arch/ia64/kernel/smpboot.c	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/kernel/smpboot.c	2003-07-19 17:04:07.000000000 -0700
-@@ -79,13 +79,13 @@ int cpucount;
- task_t *task_for_booting_cpu;
- 
- /* Bitmask of currently online CPUs */
--volatile unsigned long cpu_online_map;
--unsigned long phys_cpu_present_map;
-+cpumask_t cpu_online_map;
-+cpumask_t phys_cpu_present_map;
- 
- /* which logical CPU number maps to which CPU (physical APIC ID) */
- volatile int ia64_cpu_to_sapicid[NR_CPUS];
- 
--static volatile unsigned long cpu_callin_map;
-+static volatile cpumask_t cpu_callin_map;
- 
- struct smp_boot_data smp_boot_data __initdata;
- 
-@@ -282,7 +282,7 @@ smp_callin (void)
- 	cpuid = smp_processor_id();
- 	phys_id = hard_smp_processor_id();
- 
--	if (test_and_set_bit(cpuid, &cpu_online_map)) {
-+	if (cpu_test_and_set(cpuid, cpu_online_map)) {
- 		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
- 		       phys_id, cpuid);
- 		BUG();
-@@ -327,7 +327,7 @@ smp_callin (void)
- 	/*
- 	 * Allow the master to continue.
- 	 */
--	set_bit(cpuid, &cpu_callin_map);
-+	cpu_set(cpuid, cpu_callin_map);
- 	Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
- }
- 
-@@ -391,19 +391,19 @@ do_boot_cpu (int sapicid, int cpu)
- 	 */
- 	Dprintk("Waiting on callin_map ...");
- 	for (timeout = 0; timeout < 100000; timeout++) {
--		if (test_bit(cpu, &cpu_callin_map))
-+		if (cpu_isset(cpu, cpu_callin_map))
- 			break;  /* It has booted */
- 		udelay(100);
- 	}
- 	Dprintk("\n");
- 
--	if (test_bit(cpu, &cpu_callin_map)) {
-+	if (cpu_isset(cpu, cpu_callin_map)) {
- 		/* number CPUs logically, starting from 1 (BSP is 0) */
- 		printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu);
- 	} else {
- 		printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
- 		ia64_cpu_to_sapicid[cpu] = -1;
--		clear_bit(cpu, &cpu_online_map);  /* was set in smp_callin() */
-+		cpu_clear(cpu, cpu_online_map);  /* was set in smp_callin() */
- 		return -EINVAL;
- 	}
- 	return 0;
-@@ -446,13 +446,14 @@ smp_build_cpu_map (void)
- 		ia64_cpu_to_sapicid[cpu] = -1;
- 
- 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
--	phys_cpu_present_map = 1;
-+	cpus_clear(phys_cpu_present_map);
-+	cpu_set(0, phys_cpu_present_map);
- 
- 	for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
- 		sapicid = smp_boot_data.cpu_phys_id[i];
- 		if (sapicid == boot_cpu_id)
- 			continue;
--		phys_cpu_present_map |= (1UL << cpu);
-+		cpu_set(cpu, phys_cpu_present_map);
- 		ia64_cpu_to_sapicid[cpu] = sapicid;
- 		cpu++;
- 	}
-@@ -463,7 +464,7 @@ smp_build_cpu_map (void)
- /* on which node is each logical CPU (one cacheline even for 64 CPUs) */
- volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
- /* which logical CPUs are on which nodes */
--volatile unsigned long node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
-+volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
- 
- /*
-  * Build cpu to node mapping and initialize the per node cpu masks.
-@@ -474,7 +475,7 @@ build_cpu_to_node_map (void)
- 	int cpu, i, node;
- 
- 	for(node=0; node<MAX_NUMNODES; node++)
--		node_to_cpu_mask[node] = 0;
-+		cpus_clear(node_to_cpu_mask[node]);
- 	for(cpu = 0; cpu < NR_CPUS; ++cpu) {
- 		/*
- 		 * All Itanium NUMA platforms I know use ACPI, so maybe we
-@@ -492,7 +493,7 @@ build_cpu_to_node_map (void)
- #endif
- 		cpu_to_node_map[cpu] = node;
- 		if (node >= 0)
--			node_to_cpu_mask[node] |= (1UL << cpu);
-+			cpu_set(cpu, node_to_cpu_mask[node]);
- 	}
- }
- 
-@@ -515,8 +516,8 @@ smp_prepare_cpus (unsigned int max_cpus)
- 	/*
- 	 * We have the boot CPU online for sure.
- 	 */
--	set_bit(0, &cpu_online_map);
--	set_bit(0, &cpu_callin_map);
-+	cpu_set(0, cpu_online_map);
-+	cpu_set(0, cpu_callin_map);
- 
- 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
- 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
-@@ -531,15 +532,18 @@ smp_prepare_cpus (unsigned int max_cpus)
- 	 */
- 	if (!max_cpus) {
- 		printk(KERN_INFO "SMP mode deactivated.\n");
--		cpu_online_map = phys_cpu_present_map = 1;
-+		cpus_clear(cpu_online_map);
-+		cpus_clear(phys_cpu_present_map);
-+		cpu_set(1, cpu_online_map);
-+		cpu_set(1, phys_cpu_present_map);
- 		return;
- 	}
- }
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_callin_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_callin_map);
- }
- 
- void
---- linux-2.6.0-test1/arch/ia64/kernel/smp.c	2003-06-14 12:18:50.000000000 -0700
-+++ 25/arch/ia64/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -72,7 +72,7 @@ static volatile struct call_data_struct 
- #define IPI_CPU_STOP		1
- 
- /* This needs to be cacheline aligned because it is written to by *other* CPUs.  */
--static DEFINE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned;
-+static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
- 
- static void
- stop_this_cpu (void)
-@@ -81,7 +81,7 @@ stop_this_cpu (void)
- 	/*
- 	 * Remove this CPU:
- 	 */
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	max_xtp();
- 	local_irq_disable();
- 	cpu_halt();
-@@ -91,7 +91,7 @@ irqreturn_t
- handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
- {
- 	int this_cpu = get_cpu();
--	unsigned long *pending_ipis = &__get_cpu_var(ipi_operation);
-+	unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
- 	unsigned long ops;
- 
- 	/* Count this now; we may make a call that never returns. */
---- linux-2.6.0-test1/arch/ia64/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/ia64/kernel/time.c	2003-07-19 17:04:07.000000000 -0700
-@@ -40,13 +40,13 @@ unsigned long last_cli_ip;
- static void
- do_profile (unsigned long ip)
- {
--	extern unsigned long prof_cpu_mask;
-+	extern cpumask_t prof_cpu_mask;
- 	extern char _stext;
- 
- 	if (!prof_buffer)
- 		return;
- 
--	if (!((1UL << smp_processor_id()) & prof_cpu_mask))
-+	if (!cpu_isset(smp_processor_id(), prof_cpu_mask))
- 		return;
- 
- 	ip -= (unsigned long) &_stext;
-@@ -83,12 +83,11 @@ unsigned long
- itc_get_offset (void)
- {
- 	unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
--	unsigned long now, last_tick;
-+	unsigned long now = ia64_get_itc(), last_tick;
- 
- 	last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next
- 		     - (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta);
- 
--	now = ia64_get_itc();
- 	if (unlikely((long) (now - last_tick) < 0)) {
- 		printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
- 		       smp_processor_id(), now, last_tick);
---- linux-2.6.0-test1/arch/ia64/Makefile	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -66,8 +66,7 @@ core-$(CONFIG_IA64_SGI_SN2)	+= arch/ia64
- drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
- drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
- drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
--drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ \
--				   arch/ia64/sn/
-+drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
- 
- boot := arch/ia64/boot
- 
---- linux-2.6.0-test1/arch/ia64/mm/hugetlbpage.c	2003-06-22 12:04:43.000000000 -0700
-+++ 25/arch/ia64/mm/hugetlbpage.c	2003-07-19 17:07:16.000000000 -0700
-@@ -60,9 +60,9 @@ huge_pte_alloc (struct mm_struct *mm, un
- 	pte_t *pte = NULL;
- 
- 	pgd = pgd_offset(mm, taddr);
--	pmd = pmd_alloc(mm, pgd, taddr);
-+	pmd = pmd_alloc_map(mm, pgd, taddr);
- 	if (pmd)
--		pte = pte_alloc_map(mm, pmd, taddr);
-+		pte = pte_alloc_map(mm, pgd, &pmd, taddr);
- 	return pte;
- }
- 
---- linux-2.6.0-test1/arch/ia64/mm/init.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/mm/init.c	2003-07-19 17:07:16.000000000 -0700
-@@ -286,10 +286,10 @@ put_kernel_page (struct page *page, unsi
- 
- 	spin_lock(&init_mm.page_table_lock);
- 	{
--		pmd = pmd_alloc(&init_mm, pgd, address);
-+		pmd = pmd_alloc_kernel(&init_mm, pgd, address);
- 		if (!pmd)
- 			goto out;
--		pte = pte_alloc_map(&init_mm, pmd, address);
-+		pte = pte_alloc_map(&init_mm, pgd, &pmd, address);
- 		if (!pte)
- 			goto out;
- 		if (!pte_none(*pte)) {
---- linux-2.6.0-test1/arch/ia64/pci/pci.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ia64/pci/pci.c	2003-07-19 17:03:49.000000000 -0700
-@@ -124,7 +124,7 @@ subsys_initcall(pci_acpi_init);
- 
- /* Called by ACPI when it finds a new root bus.  */
- 
--static struct pci_controller *
-+static struct pci_controller * __devinit
- alloc_pci_controller (int seg)
- {
- 	struct pci_controller *controller;
-@@ -138,7 +138,7 @@ alloc_pci_controller (int seg)
- 	return controller;
- }
- 
--static int
-+static int __devinit
- alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, unsigned long flags)
- {
- 	struct resource *res;
-@@ -159,7 +159,7 @@ alloc_resource (char *name, struct resou
- 	return 0;
- }
- 
--static u64
-+static u64 __devinit
- add_io_space (struct acpi_resource_address64 *addr)
- {
- 	u64 offset;
-@@ -190,7 +190,7 @@ add_io_space (struct acpi_resource_addre
- 	return IO_SPACE_BASE(i);
- }
- 
--static acpi_status
-+static acpi_status __devinit
- count_window (struct acpi_resource *resource, void *data)
- {
- 	unsigned int *windows = (unsigned int *) data;
-@@ -211,7 +211,7 @@ struct pci_root_info {
- 	char *name;
- };
- 
--static acpi_status
-+static acpi_status __devinit
- add_window (struct acpi_resource *res, void *data)
- {
- 	struct pci_root_info *info = (struct pci_root_info *) data;
-@@ -252,7 +252,7 @@ add_window (struct acpi_resource *res, v
- 	return AE_OK;
- }
- 
--struct pci_bus *
-+struct pci_bus * __devinit
- pci_acpi_scan_root (struct acpi_device *device, int domain, int bus)
- {
- 	struct pci_root_info info;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/ia64/scripts/check-model.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1 @@
-+int __attribute__ ((__model__ (__small__))) x;
---- linux-2.6.0-test1/arch/ia64/scripts/toolchain-flags	2003-07-02 14:53:12.000000000 -0700
-+++ 25/arch/ia64/scripts/toolchain-flags	2003-07-19 17:03:49.000000000 -0700
-@@ -2,6 +2,7 @@
- #
- # Check whether linker can handle cross-segment @segrel():
- #
-+CPPFLAGS=""
- CC=$1
- OBJDUMP=$2
- dir=$(dirname $0)
-@@ -11,10 +12,17 @@ $CC -nostdlib -static -Wl,-T$dir/check-s
- res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
- rm -f $out
- if [ $res != 00000a00 ]; then
--    echo " -DHAVE_BUGGY_SEGREL"
-+    CPPFLAGS="$CPPFLAGS -DHAVE_BUGGY_SEGREL"
-     cat >&2 <<EOF
- warning: your linker cannot handle cross-segment segment-relative relocations.
-          please upgrade to a newer version (it is safe to use this linker, but
-          the kernel will be bigger than strictly necessary).
- EOF
- fi
-+
-+if ! $CC -c $dir/check-model.c -o $out | grep -q 'attribute directive ignored'
-+then
-+    CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
-+fi
-+rm -f $out
-+echo $CPPFLAGS
---- linux-2.6.0-test1/arch/m68k/apollo/dn_ints.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/arch/m68k/apollo/dn_ints.c	2003-07-19 17:03:49.000000000 -0700
-@@ -46,7 +46,7 @@ void dn_init_IRQ(void) {
- int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) {
- 
-   if((irq<0) || (irq>15)) {
--    printk("Trying to request illegal IRQ\n");
-+    printk("Trying to request invalid IRQ\n");
-     return -ENXIO;
-   }
- 
-@@ -72,7 +72,7 @@ int dn_request_irq(unsigned int irq, irq
- void dn_free_irq(unsigned int irq, void *dev_id) {
- 
-   if((irq<0) || (irq>15)) {
--    printk("Trying to free illegal IRQ\n");
-+    printk("Trying to free invalid IRQ\n");
-     return ;
-   }
- 
---- linux-2.6.0-test1/arch/m68k/atari/stram.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/m68k/atari/stram.c	2003-07-19 17:03:49.000000000 -0700
-@@ -37,7 +37,6 @@
- #define MAJOR_NR    Z2RAM_MAJOR
- #define do_z2_request do_stram_request
- #define DEVICE_NR(device) (minor(device))
--#include <linux/blk.h>
- #endif
- 
- #undef DEBUG
---- linux-2.6.0-test1/arch/m68k/kernel/head.S	2003-06-14 12:18:51.000000000 -0700
-+++ 25/arch/m68k/kernel/head.S	2003-07-19 17:07:16.000000000 -0700
-@@ -110,7 +110,7 @@
-  * 
-  *	These routines are used by other mmu routines to get a pointer into
-  * a table, if necessary a new table is allocated. These routines are working
-- * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root
-+ * basically like pmd_alloc_map() and pte_alloc_map() in <asm/pgtable.h>. The root
-  * table needs of course only to be allocated once in mmu_get_root_table_entry,
-  * so that here also some mmu specific initialization is done. The second page
-  * at the start of the kernel (the first page is unmapped later) is used for
---- linux-2.6.0-test1/arch/m68k/mm/init.c	2003-06-14 12:18:32.000000000 -0700
-+++ 25/arch/m68k/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -17,9 +17,6 @@
- #include <linux/types.h>
- #include <linux/init.h>
- #include <linux/bootmem.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- 
- #include <asm/setup.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/arch/m68k/mm/kmap.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/arch/m68k/mm/kmap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -189,7 +189,7 @@ void *__ioremap(unsigned long physaddr, 
- 			printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
- #endif
- 		pgd_dir = pgd_offset_k(virtaddr);
--		pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
-+		pmd_dir = pmd_alloc_kernel(&init_mm, pgd_dir, virtaddr);
- 		if (!pmd_dir) {
- 			printk("ioremap: no mem for pmd_dir\n");
- 			return NULL;
---- linux-2.6.0-test1/arch/m68k/mm/motorola.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/arch/m68k/mm/motorola.c	2003-07-19 17:03:49.000000000 -0700
-@@ -18,9 +18,6 @@
- #include <linux/types.h>
- #include <linux/init.h>
- #include <linux/bootmem.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- 
- #include <asm/setup.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/arch/m68k/mm/sun3mmu.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/arch/m68k/mm/sun3mmu.c	2003-07-19 17:03:49.000000000 -0700
-@@ -16,9 +16,6 @@
- #include <linux/string.h>
- #include <linux/types.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- #include <linux/bootmem.h>
- 
- #include <asm/setup.h>
---- linux-2.6.0-test1/arch/m68knommu/kernel/setup.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/m68knommu/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -37,7 +37,6 @@
- #include <asm/machdep.h>
- 
- #ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
- #include <asm/pgtable.h>
- #endif
- 
---- linux-2.6.0-test1/arch/m68knommu/mm/init.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/arch/m68knommu/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -27,9 +27,6 @@
- #include <linux/mm.h>
- #include <linux/swap.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- #include <linux/highmem.h>
- #include <linux/pagemap.h>
- #include <linux/bootmem.h>
---- linux-2.6.0-test1/arch/m68k/q40/q40ints.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/m68k/q40/q40ints.c	2003-07-19 17:03:49.000000000 -0700
-@@ -171,7 +171,7 @@ void q40_free_irq(unsigned int irq, void
- 	  {
- 	  case 1: case 2: case 8: case 9:
- 	  case 12: case 13:
--	    printk("%s: ISA IRQ %d from %x illegal\n", __FUNCTION__, irq, (unsigned)dev_id);
-+	    printk("%s: ISA IRQ %d from %x invalid\n", __FUNCTION__, irq, (unsigned)dev_id);
- 	    return;
- 	  case 11: irq=10;
- 	  default:
---- linux-2.6.0-test1/arch/m68k/sun3x/dvma.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/arch/m68k/sun3x/dvma.c	2003-07-19 17:07:16.000000000 -0700
-@@ -102,7 +102,7 @@ inline int dvma_map_cpu(unsigned long ka
- 		pmd_t *pmd;
- 		unsigned long end2;
- 
--		if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) {
-+		if((pmd = pmd_alloc_kernel(&init_mm, pgd, vaddr)) == NULL) {
- 			ret = -ENOMEM;
- 			goto out;
- 		}
---- linux-2.6.0-test1/arch/mips64/kernel/irq.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips64/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -818,13 +818,13 @@ EXPORT_SYMBOL(probe_irq_mask);
- static struct proc_dir_entry * root_irq_dir;
- static struct proc_dir_entry * irq_dir [NR_IRQS];
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
- static unsigned int parse_hex_value (const char *buffer,
--		unsigned long count, unsigned long *ret)
-+		unsigned long count, cpumask_t *ret)
- {
- 	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	cpumask_t value = CPU_MASK_NONE;
- 	int i;
- 
- 	if (!count)
-@@ -838,10 +838,9 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
- 
- 	for (i = 0; i < count; i++) {
--		unsigned int c = hexnum[i];
-+		unsigned int k, c = hexnum[i];
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -850,7 +849,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (c & (1 << k))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -861,20 +863,31 @@ out:
- 
- static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
- 
--static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-+static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	int k, len = 0;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int irq_affinity_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
- 	int irq = (long) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -886,7 +899,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
-@@ -900,17 +914,28 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	int k, len = 0;
-+	cpumask_t *mask = (cpumask_t *)data, tmp;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+
-+	tmp = *mask;
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	unsigned long full_count = count, err;
-+	cpumask_t new_value, *mask = (cpumask_t *)data;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- linux-2.6.0-test1/arch/mips64/kernel/proc.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips64/kernel/proc.c	2003-07-19 17:04:07.000000000 -0700
-@@ -81,7 +81,7 @@ static int show_cpuinfo(struct seq_file 
- 	char fmt [64];
- 
- #ifdef CONFIG_SMP
--	if (!CPUMASK_TSTB(cpu_online_map, n))
-+	if (!cpu_isset(n, cpu_online_map))
- 		return 0;
- #endif
- 
---- linux-2.6.0-test1/arch/mips64/kernel/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips64/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -28,9 +28,6 @@
- #include <linux/a.out.h>
- #include <linux/tty.h>
- #include <linux/bootmem.h>
--#ifdef CONFIG_BLK_DEV_RAM
--#include <linux/blk.h>
--#endif
- #include <linux/major.h>
- #include <linux/kdev_t.h>
- #include <linux/root_dev.h>
---- linux-2.6.0-test1/arch/mips64/kernel/smp.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips64/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -146,7 +146,7 @@ asmlinkage void start_secondary(void)
- 	cpu_data[cpu].udelay_val = loops_per_jiffy;
- 	prom_smp_finish();
- 	printk("Slave cpu booted successfully\n");
--	CPUMASK_SETB(cpu_online_map, cpu);
-+	cpu_set(cpu, cpu_online_map);
- 	atomic_inc(&cpus_booted);
- 	cpu_idle();
- }
-@@ -250,7 +250,7 @@ static void stop_this_cpu(void *dummy)
- 	/*
- 	 * Remove this CPU:
- 	 */
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_enable();	/* May need to service _machine_restart IPI */
- 	for (;;);		/* Wait if available. */
- }
---- linux-2.6.0-test1/arch/mips/kernel/irq.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -861,20 +861,30 @@ out:
- 
- static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
- 
--static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-+static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	int len, k;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int irq_affinity_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
- 	int irq = (long) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -886,7 +896,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, tmp, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
-@@ -900,17 +911,28 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	int len, k;
-+	cpumask_t *mask = (cpumask_t *)data, tmp;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+	tmp = *mask;
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data, new_value;
-+	unsigned long full_count = count, err;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- linux-2.6.0-test1/arch/mips/kernel/proc.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/kernel/proc.c	2003-07-19 17:04:07.000000000 -0700
-@@ -81,7 +81,7 @@ static int show_cpuinfo(struct seq_file 
- 	char fmt [64];
- 
- #ifdef CONFIG_SMP
--	if (!CPUMASK_TSTB(cpu_online_map, n))
-+	if (!cpu_isset(n, cpu_online_map))
- 		return 0;
- #endif
- 
---- linux-2.6.0-test1/arch/mips/kernel/smp.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -146,7 +146,7 @@ asmlinkage void start_secondary(void)
- 	cpu_data[cpu].udelay_val = loops_per_jiffy;
- 	prom_smp_finish();
- 	printk("Slave cpu booted successfully\n");
--	CPUMASK_SETB(cpu_online_map, cpu);
-+	cpu_set(cpu, cpu_online_map);
- 	atomic_inc(&cpus_booted);
- 	cpu_idle();
- }
-@@ -250,7 +250,7 @@ static void stop_this_cpu(void *dummy)
- 	/*
- 	 * Remove this CPU:
- 	 */
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_enable();	/* May need to service _machine_restart IPI */
- 	for (;;);		/* Wait if available. */
- }
---- linux-2.6.0-test1/arch/mips/mm/fault.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/mm/fault.c	2003-07-19 17:03:49.000000000 -0700
-@@ -162,7 +162,7 @@ bad_area:
- 		tsk->thread.cp0_badvaddr = address;
- 		tsk->thread.error_code = write;
- #if 0
--		printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
-+		printk("do_page_fault() #2: sending SIGSEGV to %s for invalid %s\n"
- 		       "%08lx (epc == %08lx, ra == %08lx)\n",
- 		       tsk->comm,
- 		       write ? "write access to" : "read access from",
---- linux-2.6.0-test1/arch/mips/mm/init.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -24,7 +24,7 @@
- #include <linux/bootmem.h>
- #include <linux/highmem.h>
- #include <linux/swap.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <asm/bootinfo.h>
- #include <asm/cacheflush.h>
---- linux-2.6.0-test1/arch/mips/mm/ioremap.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -81,7 +81,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/mips/momentum/ocelot_c/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/momentum/ocelot_c/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -63,7 +63,7 @@
- #include <asm/mc146818rtc.h>
- #include <linux/version.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/mv64340.h>
- #include "ocelot_c_fpga.h"
- 
---- linux-2.6.0-test1/arch/mips/momentum/ocelot_g/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/momentum/ocelot_g/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -64,7 +64,7 @@
- #include <asm/mc146818rtc.h>
- #include <linux/version.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "gt64240.h"
- #include "ocelot_pld.h"
- 
---- linux-2.6.0-test1/arch/mips/ramdisk/Makefile	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/ramdisk/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -2,7 +2,7 @@
- # Makefile for a ramdisk image
- #
- 
--O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
-+O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
- img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE)
- ramdisk.o: $(subst ",,$(img)) ld.script
- 	echo "O_FORMAT:  " $(O_FORMAT)
---- linux-2.6.0-test1/arch/mips/sgi-ip27/ip27-init.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sgi-ip27/ip27-init.c	2003-07-19 17:04:07.000000000 -0700
-@@ -481,7 +481,7 @@ static int __init do_boot_cpu(int cpu, i
- 	 */
- 	__cpu_number_map[cpu] = num_cpus;
- 	__cpu_logical_map[num_cpus] = cpu;
--	CPUMASK_SETB(cpu_online_map, cpu);
-+	cpu_set(cpu, cpu_online_map);
- 
- 	/*
- 	 * Wait this cpu to start up and initialize its hub,
---- linux-2.6.0-test1/arch/mips/sibyte/cfe/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sibyte/cfe/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -20,7 +20,7 @@
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/bootmem.h>
- #include <linux/smp.h>
- 
---- linux-2.6.0-test1/arch/mips/sibyte/cfe/smp.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sibyte/cfe/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -63,7 +63,7 @@ void prom_setup_smp(void)
- 	/* Use CFE to find out how many CPUs are available */
- 	for (i=1; i<NR_CPUS; i++) {
- 		if (cfe_cpu_stop(i) == 0) {
--			CPUMASK_SETB(cpu_online_map, i);
-+			cpu_set(i, cpu_online_map);
- 		}
- 	}
- 	printk("Detected %i available CPU(s)\n", num_online_cpus());
---- linux-2.6.0-test1/arch/mips/sibyte/sb1250/prom.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sibyte/sb1250/prom.c	2003-07-19 17:03:49.000000000 -0700
-@@ -20,7 +20,7 @@
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/bootmem.h>
- #include <linux/smp.h>
- 
---- linux-2.6.0-test1/arch/mips/sibyte/sb1250/smp.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sibyte/sb1250/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -107,8 +107,8 @@ void __init smp_boot_cpus(void)
- 	current_thread_info()->cpu = 0;
- 	cpu_data[0].udelay_val = loops_per_jiffy;
- 	cpu_data[0].asid_cache = ASID_FIRST_VERSION;
--	CPUMASK_CLRALL(cpu_online_map);
--	CPUMASK_SETB(cpu_online_map, 0);
-+	cpus_clear(cpu_online_map);
-+	cpu_set(0, cpu_online_map);
- 	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
- 	smp_tune_scheduling();
- 
---- linux-2.6.0-test1/arch/mips/sibyte/swarm/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/sibyte/swarm/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -23,7 +23,7 @@
- #include <linux/spinlock.h>
- #include <linux/mm.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/ide.h>
- #include <linux/console.h>
---- linux-2.6.0-test1/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2003-07-19 17:03:49.000000000 -0700
-@@ -134,7 +134,7 @@ JP7 is not bus master -- do NOT use -- o
- #include <asm/time.h>
- #include <linux/version.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #ifdef CONFIG_RTC_DS1742
- #include <asm/rtc_ds1742.h>
- #endif
---- linux-2.6.0-test1/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -62,7 +62,7 @@
- #include <asm/time.h>
- #include <linux/version.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/console.h>
- #ifdef CONFIG_RTC_DS1742
- #include <asm/rtc_ds1742.h>
---- linux-2.6.0-test1/arch/mips/vr41xx/tanbac-tb0229/setup.c	2003-07-02 14:53:13.000000000 -0700
-+++ 25/arch/mips/vr41xx/tanbac-tb0229/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -18,7 +18,7 @@
-  *  option) any later version.
-  */
- #include <linux/config.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/console.h>
- #include <linux/init.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/arch/parisc/kernel/ioctl32.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/parisc/kernel/ioctl32.c	2003-07-19 17:03:49.000000000 -0700
-@@ -48,7 +48,6 @@
- #include <linux/raw.h>
- #include <linux/smb_fs.h>
- #include <linux/blkpg.h>
--#include <linux/blk.h>
- #include <linux/elevator.h>
- #include <linux/rtc.h>
- #include <linux/pci.h>
---- linux-2.6.0-test1/arch/parisc/kernel/pci-dma.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/parisc/kernel/pci-dma.c	2003-07-19 17:07:16.000000000 -0700
-@@ -133,7 +133,7 @@ static inline int map_uncached_pages(uns
- 	do {
- 		pmd_t *pmd;
- 		
--		pmd = pmd_alloc(NULL, dir, vaddr);
-+		pmd = pmd_alloc_kernel(NULL, dir, vaddr);
- 		if (!pmd)
- 			return -ENOMEM;
- 		if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
---- linux-2.6.0-test1/arch/parisc/kernel/smp.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/parisc/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -62,14 +62,14 @@ volatile struct task_struct *smp_init_cu
- 
- static volatile int smp_commenced = 0;   /* Set when the idlers are all forked */
- static volatile int cpu_now_booting = 0;      /* track which CPU is booting */
--volatile unsigned long cpu_online_map = 0;   /* Bitmap of online CPUs */
--#define IS_LOGGED_IN(cpunum) (test_bit(cpunum, (atomic_t *)&cpu_online_map))
-+cpumask_t cpu_online_map = CPU_MASK_NONE;   /* Bitmap of online CPUs */
-+#define IS_LOGGED_IN(cpunum) (cpu_isset(cpunum, cpu_online_map))
- 
- int smp_num_cpus = 1;
- int smp_threads_ready = 0;
- unsigned long cache_decay_ticks;
- static int max_cpus = -1;			     /* Command line */
--unsigned long cpu_present_mask;
-+cpumask_t cpu_present_mask;
- 
- struct smp_call_struct {
- 	void (*func) (void *info);
-@@ -139,7 +139,7 @@ halt_processor(void) 
- #else
- 	/* REVISIT : redirect I/O Interrupts to another CPU? */
- 	/* REVISIT : does PM *know* this CPU isn't available? */
--	clear_bit(smp_processor_id(), (void *)&cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_disable();
- 	for (;;)
- 		;
-@@ -443,7 +443,7 @@ smp_cpu_init(int cpunum)
- 	mb();
- 
- 	/* Well, support 2.4 linux scheme as well. */
--	if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map)))
-+	if (cpu_test_and_set(cpunum, cpu_online_map))
- 	{
- 		extern void machine_halt(void); /* arch/parisc.../process.c */
- 
-@@ -624,13 +624,14 @@ void __init smp_boot_cpus(void)
- 	printk(KERN_DEBUG "SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
- 	init_task.thread_info->cpu = bootstrap_processor; 
- 	current->thread_info->cpu = bootstrap_processor;
--	cpu_online_map = 1 << bootstrap_processor; /* Mark Boostrap processor as present */
-+	/* Mark Boostrap processor as present */
-+	cpu_online_map = cpumask_of_cpu(bootstrap_processor);
- 	current->active_mm = &init_mm;
- 
- #ifdef ENTRY_SYS_CPUS
- 	cpu_data[0].state = STATE_RUNNING;
- #endif
--	cpu_present_mask = 1UL << bootstrap_processor;
-+	cpu_present_mask = cpumask_of_cpu(bootstrap_processor);
- 
- 	/* Nothing to do when told not to.  */
- 	if (max_cpus == 0) {
-@@ -709,8 +710,8 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_present_mask);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_present_mask);
- }
- 
- int __devinit __cpu_up(unsigned int cpu)
---- linux-2.6.0-test1/arch/parisc/mm/ioremap.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/arch/parisc/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -77,7 +77,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(dir, address);
-+		pmd = pmd_alloc_kernel(dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/ppc64/boot/Makefile	2003-06-14 12:18:32.000000000 -0700
-+++ 25/arch/ppc64/boot/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -118,7 +118,7 @@ $(obj)/imagesize.c: vmlinux
- 	ls -l vmlinux | \
- 	awk '{printf "/* generated -- do not edit! */\n" \
- 		"unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
--	$(CROSS_COMPILE)nm -n vmlinux | tail -1 | \
-+	$(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
- 	awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
- 		>> $(obj)/imagesize.c
- 
---- linux-2.6.0-test1/arch/ppc64/Kconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/ppc64/Kconfig	2003-07-19 17:04:07.000000000 -0700
-@@ -93,7 +93,7 @@ config IRQ_ALL_CPUS
- 	  CPU.
- 
- config NR_CPUS
--	int "Maximum number of CPUs (2-64)"
-+	int "Maximum number of CPUs (2-128)"
- 	depends on SMP
- 	default "32"
- 
---- linux-2.6.0-test1/arch/ppc64/kernel/htab.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/arch/ppc64/kernel/htab.c	2003-07-19 17:04:07.000000000 -0700
-@@ -377,6 +377,7 @@ int hash_page(unsigned long ea, unsigned
- 	int ret;
- 	int user_region = 0;
- 	int local = 0;
-+	cpumask_t tmp;
- 
- 	/* Check for invalid addresses. */
- 	if (!IS_VALID_EA(ea))
-@@ -431,7 +432,8 @@ int hash_page(unsigned long ea, unsigned
- 	 */
- 	spin_lock(&mm->page_table_lock);
- 
--	if (user_region && (mm->cpu_vm_mask == (1 << smp_processor_id())))
-+	tmp = cpumask_of_cpu(smp_processor_id());
-+	if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
- 		local = 1;
- 
- 	ptep = find_linux_pte(pgdir, ea);
---- linux-2.6.0-test1/arch/ppc64/kernel/irq.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/arch/ppc64/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -603,26 +603,37 @@ static struct proc_dir_entry * irq_dir [
- static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
- 
- #ifdef CONFIG_IRQ_ALL_CPUS
--unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = -1UL};
-+cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
- #else  /* CONFIG_IRQ_ALL_CPUS */
--unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x0};
-+cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_NONE };
- #endif /* CONFIG_IRQ_ALL_CPUS */
- 
--#define HEX_DIGITS 16
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	int k, len;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf(page, "%16lx\n", irq_affinity[(long)data]);
-+
-+	for (k = 0; k < sizeof(cpumask_t) / sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static unsigned int parse_hex_value (const char *buffer,
--		unsigned long count, unsigned long *ret)
-+		unsigned long count, cpumask_t *ret)
- {
- 	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	cpumask_t value = CPU_MASK_NONE;
- 	int i;
- 
- 	if (!count)
-@@ -636,10 +647,10 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 16 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
- 
- 	for (i = 0; i < count; i++) {
- 		unsigned int c = hexnum[i];
-+		int k;
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -648,7 +659,11 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (test_bit(k, (unsigned long *)&c))
-+				cpu_set(k, value);
-+
- 	}
- out:
- 	*ret = value;
-@@ -659,7 +674,7 @@ static int irq_affinity_write_proc (stru
- 					unsigned long count, void *data)
- {
- 	int irq = (long)data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -671,7 +686,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
-@@ -692,8 +708,9 @@ static int prof_cpu_mask_read_proc (char
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data;
-+	unsigned long full_count = count, err;
-+	cpumask_t new_value;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- linux-2.6.0-test1/arch/ppc64/kernel/iSeries_irq.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/ppc64/kernel/iSeries_irq.c	2003-07-19 17:03:49.000000000 -0700
-@@ -29,7 +29,6 @@
- #include <linux/param.h>
- #include <linux/string.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
- #include <linux/ide.h>
- 
- #include <linux/irq.h>
---- linux-2.6.0-test1/arch/ppc64/kernel/open_pic.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/arch/ppc64/kernel/open_pic.c	2003-07-19 17:04:07.000000000 -0700
-@@ -46,7 +46,7 @@ static int broken_ipi_registers;
- OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU];
- 
- static void openpic_end_irq(unsigned int irq_nr);
--static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask);
-+static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
- 
- struct hw_interrupt_type open_pic = {
- 	" OpenPIC  ",
-@@ -505,7 +505,7 @@ static void openpic_set_spurious(u_int v
- void openpic_init_processor(u_int cpumask)
- {
- 	openpic_write(&OpenPIC->Global.Processor_Initialization,
--		      cpumask & cpu_online_map);
-+		      cpumask & cpus_coerce(cpu_online_map));
- }
- 
- #ifdef CONFIG_SMP
-@@ -539,7 +539,7 @@ void openpic_cause_IPI(u_int ipi, u_int 
- 	CHECK_THIS_CPU;
- 	check_arg_ipi(ipi);
- 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
--		      cpumask & cpu_online_map);
-+		      cpumask & cpus_coerce(cpu_online_map));
- }
- 
- void openpic_request_IPIs(void)
-@@ -625,7 +625,7 @@ static void __init openpic_maptimer(u_in
- {
- 	check_arg_timer(timer);
- 	openpic_write(&OpenPIC->Global.Timer[timer].Destination,
--		      cpumask & cpu_online_map);
-+		      cpumask & cpus_coerce(cpu_online_map));
- }
- 
- 
-@@ -746,9 +746,12 @@ static void openpic_end_irq(unsigned int
- 		openpic_eoi();
- }
- 
--static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
-+static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask)
- {
--	openpic_mapirq(irq_nr - open_pic_irq_offset, cpumask & cpu_online_map);
-+	cpumask_t tmp;
-+
-+	cpus_and(tmp, cpumask, cpu_online_map);
-+	openpic_mapirq(irq_nr - open_pic_irq_offset, cpus_coerce(tmp));
- }
- 
- #ifdef CONFIG_SMP
---- linux-2.6.0-test1/arch/ppc64/kernel/open_pic.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/ppc64/kernel/open_pic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -13,6 +13,7 @@
- #define _PPC64_KERNEL_OPEN_PIC_H
- 
- #include <linux/config.h>
-+#include <linux/cpumask.h>
- 
- #define OPENPIC_SIZE	0x40000
- 
---- linux-2.6.0-test1/arch/ppc64/kernel/pacaData.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/ppc64/kernel/pacaData.c	2003-07-19 17:04:07.000000000 -0700
-@@ -134,5 +134,71 @@ struct paca_struct paca[NR_CPUS] __page_
- 	PACAINITDATA(61, 0, 0, 0, 0),
- 	PACAINITDATA(62, 0, 0, 0, 0),
- 	PACAINITDATA(63, 0, 0, 0, 0),
-+#if NR_CPUS > 64
-+	PACAINITDATA(64, 0, 0, 0, 0),
-+	PACAINITDATA(65, 0, 0, 0, 0),
-+	PACAINITDATA(66, 0, 0, 0, 0),
-+	PACAINITDATA(67, 0, 0, 0, 0),
-+	PACAINITDATA(68, 0, 0, 0, 0),
-+	PACAINITDATA(69, 0, 0, 0, 0),
-+	PACAINITDATA(70, 0, 0, 0, 0),
-+	PACAINITDATA(71, 0, 0, 0, 0),
-+	PACAINITDATA(72, 0, 0, 0, 0),
-+	PACAINITDATA(73, 0, 0, 0, 0),
-+	PACAINITDATA(74, 0, 0, 0, 0),
-+	PACAINITDATA(75, 0, 0, 0, 0),
-+	PACAINITDATA(76, 0, 0, 0, 0),
-+	PACAINITDATA(77, 0, 0, 0, 0),
-+	PACAINITDATA(78, 0, 0, 0, 0),
-+	PACAINITDATA(79, 0, 0, 0, 0),
-+	PACAINITDATA(80, 0, 0, 0, 0),
-+	PACAINITDATA(81, 0, 0, 0, 0),
-+	PACAINITDATA(82, 0, 0, 0, 0),
-+	PACAINITDATA(83, 0, 0, 0, 0),
-+	PACAINITDATA(84, 0, 0, 0, 0),
-+	PACAINITDATA(85, 0, 0, 0, 0),
-+	PACAINITDATA(86, 0, 0, 0, 0),
-+	PACAINITDATA(87, 0, 0, 0, 0),
-+	PACAINITDATA(88, 0, 0, 0, 0),
-+	PACAINITDATA(89, 0, 0, 0, 0),
-+	PACAINITDATA(90, 0, 0, 0, 0),
-+	PACAINITDATA(91, 0, 0, 0, 0),
-+	PACAINITDATA(92, 0, 0, 0, 0),
-+	PACAINITDATA(93, 0, 0, 0, 0),
-+	PACAINITDATA(94, 0, 0, 0, 0),
-+	PACAINITDATA(95, 0, 0, 0, 0),
-+	PACAINITDATA(96, 0, 0, 0, 0),
-+	PACAINITDATA(97, 0, 0, 0, 0),
-+	PACAINITDATA(98, 0, 0, 0, 0),
-+	PACAINITDATA(99, 0, 0, 0, 0),
-+	PACAINITDATA(100, 0, 0, 0, 0),
-+	PACAINITDATA(101, 0, 0, 0, 0),
-+	PACAINITDATA(102, 0, 0, 0, 0),
-+	PACAINITDATA(103, 0, 0, 0, 0),
-+	PACAINITDATA(104, 0, 0, 0, 0),
-+	PACAINITDATA(105, 0, 0, 0, 0),
-+	PACAINITDATA(106, 0, 0, 0, 0),
-+	PACAINITDATA(107, 0, 0, 0, 0),
-+	PACAINITDATA(108, 0, 0, 0, 0),
-+	PACAINITDATA(109, 0, 0, 0, 0),
-+	PACAINITDATA(110, 0, 0, 0, 0),
-+	PACAINITDATA(111, 0, 0, 0, 0),
-+	PACAINITDATA(112, 0, 0, 0, 0),
-+	PACAINITDATA(113, 0, 0, 0, 0),
-+	PACAINITDATA(114, 0, 0, 0, 0),
-+	PACAINITDATA(115, 0, 0, 0, 0),
-+	PACAINITDATA(116, 0, 0, 0, 0),
-+	PACAINITDATA(117, 0, 0, 0, 0),
-+	PACAINITDATA(118, 0, 0, 0, 0),
-+	PACAINITDATA(119, 0, 0, 0, 0),
-+	PACAINITDATA(120, 0, 0, 0, 0),
-+	PACAINITDATA(121, 0, 0, 0, 0),
-+	PACAINITDATA(122, 0, 0, 0, 0),
-+	PACAINITDATA(123, 0, 0, 0, 0),
-+	PACAINITDATA(124, 0, 0, 0, 0),
-+	PACAINITDATA(125, 0, 0, 0, 0),
-+	PACAINITDATA(126, 0, 0, 0, 0),
-+	PACAINITDATA(127, 0, 0, 0, 0),
-+#endif
- #endif
- };
---- linux-2.6.0-test1/arch/ppc64/kernel/prom.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/ppc64/kernel/prom.c	2003-07-19 17:04:07.000000000 -0700
-@@ -27,7 +27,6 @@
- #include <linux/version.h>
- #include <linux/threads.h>
- #include <linux/spinlock.h>
--#include <linux/blk.h>
- #include <linux/types.h>
- #include <linux/pci.h>
- #include <asm/prom.h>
-@@ -1134,7 +1133,7 @@ prom_init(unsigned long r3, unsigned lon
- 	_prom->cpu = (int)(unsigned long)getprop_rval;
- 	_xPaca[_prom->cpu].active = 1;
- #ifdef CONFIG_SMP
--	RELOC(cpu_online_map) = 1UL << _prom->cpu;
-+	cpu_set(_prom->cpu, RELOC(cpu_online_map));
- #endif
- 	RELOC(boot_cpuid) = _prom->cpu;
- 
---- linux-2.6.0-test1/arch/ppc64/kernel/rtasd.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/arch/ppc64/kernel/rtasd.c	2003-07-19 17:04:07.000000000 -0700
-@@ -225,7 +225,7 @@ repeat:
- 			continue;
- 
- 		DEBUG("scheduling on %d\n", cpu);
--		set_cpus_allowed(current, 1UL << cpu);
-+		set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 		DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
- 
- 		do {
---- linux-2.6.0-test1/arch/ppc64/kernel/semaphore.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/arch/ppc64/kernel/semaphore.c	2003-07-19 17:04:51.000000000 -0700
-@@ -21,6 +21,7 @@
- #include <asm/semaphore.h>
- #include <asm/errno.h>
- 
-+#if 0
- /*
-  * Atomically update sem->count.
-  * This does the equivalent of the following:
-@@ -129,3 +130,140 @@ int __down_interruptible(struct semaphor
- 	wake_up(&sem->wait);
- 	return retval;
- }
-+#else
-+
-+static __inline__ int atomic_add_negative(int i, atomic_t *v)
-+{
-+	if (atomic_add_return(i, v) < 0)
-+		return 1;
-+	else
-+		return 0;
-+}
-+
-+void __up(struct semaphore *sem)
-+{
-+	wake_up(&sem->wait);
-+}
-+
-+void __down(struct semaphore * sem)
-+{
-+	struct task_struct *tsk = current;
-+	DECLARE_WAITQUEUE(wait, tsk);
-+	unsigned long flags;
-+
-+	tsk->state = TASK_UNINTERRUPTIBLE;
-+	spin_lock_irqsave(&sem->wait.lock, flags);
-+	add_wait_queue_exclusive_locked(&sem->wait, &wait);
-+
-+	sem->sleepers++;
-+	for (;;) {
-+		int sleepers = sem->sleepers;
-+
-+		/*
-+		 * Add "everybody else" into it. They aren't
-+		 * playing, because we own the spinlock in
-+		 * the wait_queue_head.
-+		 */
-+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
-+			sem->sleepers = 0;
-+			break;
-+		}
-+		sem->sleepers = 1;	/* us - see -1 above */
-+		spin_unlock_irqrestore(&sem->wait.lock, flags);
-+
-+		schedule();
-+
-+		spin_lock_irqsave(&sem->wait.lock, flags);
-+		tsk->state = TASK_UNINTERRUPTIBLE;
-+	}
-+	remove_wait_queue_locked(&sem->wait, &wait);
-+	wake_up_locked(&sem->wait);
-+	spin_unlock_irqrestore(&sem->wait.lock, flags);
-+	tsk->state = TASK_RUNNING;
-+}
-+
-+int __down_interruptible(struct semaphore * sem)
-+{
-+	int retval = 0;
-+	struct task_struct *tsk = current;
-+	DECLARE_WAITQUEUE(wait, tsk);
-+	unsigned long flags;
-+
-+	tsk->state = TASK_INTERRUPTIBLE;
-+	spin_lock_irqsave(&sem->wait.lock, flags);
-+	add_wait_queue_exclusive_locked(&sem->wait, &wait);
-+
-+	sem->sleepers++;
-+	for (;;) {
-+		int sleepers = sem->sleepers;
-+
-+		/*
-+		 * With signals pending, this turns into
-+		 * the trylock failure case - we won't be
-+		 * sleeping, and we* can't get the lock as
-+		 * it has contention. Just correct the count
-+		 * and exit.
-+		 */
-+		if (signal_pending(current)) {
-+			retval = -EINTR;
-+			sem->sleepers = 0;
-+			atomic_add(sleepers, &sem->count);
-+			break;
-+		}
-+
-+		/*
-+		 * Add "everybody else" into it. They aren't
-+		 * playing, because we own the spinlock in
-+		 * wait_queue_head. The "-1" is because we're
-+		 * still hoping to get the semaphore.
-+		 */
-+		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
-+			sem->sleepers = 0;
-+			break;
-+		}
-+		sem->sleepers = 1;	/* us - see -1 above */
-+		spin_unlock_irqrestore(&sem->wait.lock, flags);
-+
-+		schedule();
-+
-+		spin_lock_irqsave(&sem->wait.lock, flags);
-+		tsk->state = TASK_INTERRUPTIBLE;
-+	}
-+	remove_wait_queue_locked(&sem->wait, &wait);
-+	wake_up_locked(&sem->wait);
-+	spin_unlock_irqrestore(&sem->wait.lock, flags);
-+
-+	tsk->state = TASK_RUNNING;
-+	return retval;
-+}
-+
-+/*
-+ * Trylock failed - make sure we correct for
-+ * having decremented the count.
-+ *
-+ * We could have done the trylock with a
-+ * single "cmpxchg" without failure cases,
-+ * but then it wouldn't work on a 386.
-+ */
-+int __down_trylock(struct semaphore * sem)
-+{
-+	int sleepers;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&sem->wait.lock, flags);
-+	sleepers = sem->sleepers + 1;
-+	sem->sleepers = 0;
-+
-+	/*
-+	 * Add "everybody else" and us into it. They aren't
-+	 * playing, because we own the spinlock in the
-+	 * wait_queue_head.
-+	 */
-+	if (!atomic_add_negative(sleepers, &sem->count)) {
-+		wake_up_locked(&sem->wait);
-+	}
-+
-+	spin_unlock_irqrestore(&sem->wait.lock, flags);
-+	return 1;
-+}
-+#endif
---- linux-2.6.0-test1/arch/ppc64/kernel/setup.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/arch/ppc64/kernel/setup.c	2003-07-19 17:04:07.000000000 -0700
-@@ -256,7 +256,7 @@ static int show_cpuinfo(struct seq_file 
- 		return 0;
- 	}
- 
--	if (!(cpu_online_map & (1UL << cpu_id)))
-+	if (!cpu_online(cpu_id))
- 		return 0;
- 
- #ifdef CONFIG_SMP
---- linux-2.6.0-test1/arch/ppc64/kernel/smp.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/ppc64/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -53,7 +53,7 @@ int smp_threads_ready;
- unsigned long cache_decay_ticks;
- 
- /* initialised so it doesn't end up in bss */
--unsigned long cpu_online_map = 0;
-+cpumask_t cpu_online_map = CPU_MASK_NONE;
- 
- static struct smp_ops_t *smp_ops;
- 
-@@ -570,7 +570,7 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- 	/* FIXME: what about cpu_possible()? */
- }
- 
-@@ -631,7 +631,7 @@ int __devinit __cpu_up(unsigned int cpu)
- 
- 	if (smp_ops->give_timebase)
- 		smp_ops->give_timebase();
--	set_bit(cpu, &cpu_online_map);
-+	cpu_set(cpu, cpu_online_map);
- 	return 0;
- }
- 
---- linux-2.6.0-test1/arch/ppc64/kernel/xics.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/arch/ppc64/kernel/xics.c	2003-07-19 17:04:07.000000000 -0700
-@@ -33,7 +33,7 @@ void xics_enable_irq(u_int irq);
- void xics_disable_irq(u_int irq);
- void xics_mask_and_ack_irq(u_int irq);
- void xics_end_irq(u_int irq);
--void xics_set_affinity(unsigned int irq_nr, unsigned long cpumask);
-+void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
- 
- struct hw_interrupt_type xics_pic = {
- 	" XICS     ",
-@@ -508,7 +508,7 @@ nextnode:
- 	ppc64_boot_msg(0x21, "XICS Done");
- }
- 
--void xics_set_affinity(unsigned int virq, unsigned long cpumask)
-+void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
- {
-         irq_desc_t *desc = irq_desc + virq;
- 	unsigned int irq;
-@@ -516,6 +516,8 @@ void xics_set_affinity(unsigned int virq
- 	long status;
- 	unsigned long xics_status[2];
- 	unsigned long newmask;
-+	cpumask_t allcpus = CPU_MASK_ALL;
-+	cpumask_t tmp = CPU_MASK_NONE;
- 
- 	virq -= XICS_IRQ_OFFSET;
- 	irq = virt_irq_to_real(virq);
-@@ -533,12 +535,13 @@ void xics_set_affinity(unsigned int virq
- 	}
- 
- 	/* For the moment only implement delivery to all cpus or one cpu */
--	if (cpumask == -1UL) {
-+	if (cpus_equal(cpumask, allcpus)) {
- 		newmask = default_distrib_server;
- 	} else {
--		if (!(cpumask & cpu_online_map))
-+		cpus_and(tmp, cpu_online_map, cpumask);
-+		if (cpus_empty(tmp))
- 			goto out;
--		newmask = find_first_bit(&cpumask, 8*sizeof(unsigned long));
-+		newmask = first_cpu(cpumask);
- 	}
- 
- 	status = rtas_call(ibm_set_xive, 3, 1, NULL,
---- linux-2.6.0-test1/arch/ppc64/kernel/XmPciLpEvent.c	2003-06-14 12:18:21.000000000 -0700
-+++ 25/arch/ppc64/kernel/XmPciLpEvent.c	2003-07-19 17:03:49.000000000 -0700
-@@ -12,7 +12,6 @@
- #include <linux/param.h>
- #include <linux/string.h>
- #include <linux/bootmem.h>
--#include <linux/blk.h>
- #include <linux/ide.h>
- 
- #include <asm/iSeries/HvTypes.h>
---- linux-2.6.0-test1/arch/ppc64/mm/init.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ppc64/mm/init.c	2003-07-19 17:07:16.000000000 -0700
-@@ -37,9 +37,6 @@
- #include <linux/bootmem.h>
- #include <linux/highmem.h>
- #include <linux/proc_fs.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>		/* for initrd_* */
--#endif
- 
- #include <asm/pgalloc.h>
- #include <asm/page.h>
-@@ -211,7 +208,7 @@ static void map_io_page(unsigned long ea
- 	if (mem_init_done) {
- 		spin_lock(&ioremap_mm.page_table_lock);
- 		pgdp = pgd_offset_i(ea);
--		pmdp = pmd_alloc(&ioremap_mm, pgdp, ea);
-+		pmdp = pmd_alloc_kernel(&ioremap_mm, pgdp, ea);
- 		ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
- 
- 		pa = absolute_to_phys(pa);
-@@ -253,7 +250,7 @@ flush_tlb_mm(struct mm_struct *mm)
- 		__flush_tlb_range(mm, mp->vm_start, mp->vm_end);
- 
- 	/* XXX are there races with checking cpu_vm_mask? - Anton */
--	mm->cpu_vm_mask = 0;
-+	cpus_clear(mm->cpu_vm_mask);
- 
- 	spin_unlock(&mm->page_table_lock);
- }
-@@ -270,6 +267,7 @@ flush_tlb_page(struct vm_area_struct *vm
- 	pte_t *ptep;
- 	pte_t pte;
- 	int local = 0;
-+	cpumask_t tmp;
- 
- 	switch( REGION_ID(vmaddr) ) {
- 	case VMALLOC_REGION_ID:
-@@ -283,7 +281,8 @@ flush_tlb_page(struct vm_area_struct *vm
- 		context = vma->vm_mm->context;
- 
- 		/* XXX are there races with checking cpu_vm_mask? - Anton */
--		if (vma->vm_mm->cpu_vm_mask == (1 << smp_processor_id()))
-+		tmp = cpumask_of_cpu(smp_processor_id());
-+		if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
- 			local = 1;
- 
- 		break;
-@@ -319,6 +318,7 @@ __flush_tlb_range(struct mm_struct *mm, 
- 	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[smp_processor_id()];
- 	unsigned long i = 0;
- 	int local = 0;
-+	cpumask_t tmp;
- 
- 	switch(REGION_ID(start)) {
- 	case VMALLOC_REGION_ID:
-@@ -332,7 +332,8 @@ __flush_tlb_range(struct mm_struct *mm, 
- 		context = mm->context;
- 
- 		/* XXX are there races with checking cpu_vm_mask? - Anton */
--		if (mm->cpu_vm_mask == (1 << smp_processor_id()))
-+		tmp = cpumask_of_cpu(smp_processor_id());
-+		if (cpus_equal(mm->cpu_vm_mask, tmp))
- 			local = 1;
- 
- 		break;
-@@ -698,6 +699,7 @@ void update_mmu_cache(struct vm_area_str
- 	void *pgdir;
- 	pte_t *ptep;
- 	int local = 0;
-+	cpumask_t tmp;
- 
- 	/* handle i-cache coherency */
- 	if (!(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) {
-@@ -723,7 +725,8 @@ void update_mmu_cache(struct vm_area_str
- 	ptep = find_linux_pte(pgdir, ea);
- 	vsid = get_vsid(vma->vm_mm->context, ea);
- 
--	if (vma->vm_mm->cpu_vm_mask == (1 << smp_processor_id()))
-+	tmp = cpumask_of_cpu(smp_processor_id());
-+	if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
- 		local = 1;
- 
- 	__hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep,
---- linux-2.6.0-test1/arch/ppc/kernel/irq.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/ppc/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -44,6 +44,7 @@
- #include <linux/proc_fs.h>
- #include <linux/random.h>
- #include <linux/seq_file.h>
-+#include <linux/cpumask.h>
- 
- #include <asm/uaccess.h>
- #include <asm/bitops.h>
-@@ -420,10 +421,9 @@ void ppc_irq_dispatch_handler(struct pt_
- {
- 	int status;
- 	struct irqaction *action;
--	int cpu = smp_processor_id();
- 	irq_desc_t *desc = irq_desc + irq;
- 
--	kstat_cpu(cpu).irqs[irq]++;
-+	kstat_this_cpu.irqs[irq]++;
- 	spin_lock(&desc->lock);
- 	ack_irq(irq);	
- 	/*
-@@ -565,29 +565,41 @@ static struct proc_dir_entry *irq_dir[NR
- static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
- 
- #ifdef CONFIG_IRQ_ALL_CPUS
--#define DEFAULT_CPU_AFFINITY 0xffffffff
-+#define DEFAULT_CPU_AFFINITY CPU_MASK_ALL
- #else
--#define DEFAULT_CPU_AFFINITY 0x00000001
-+#define DEFAULT_CPU_AFFINITY cpumask_of_cpu(0)
- #endif
- 
--unsigned int irq_affinity [NR_IRQS] =
-+cpumask_t irq_affinity [NR_IRQS] =
- 	{ [0 ... NR_IRQS-1] = DEFAULT_CPU_AFFINITY };
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	cpumask_t tmp = irq_affinity[(long)data];
-+	int k, len = 0;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08x\n", irq_affinity[(int)data]);
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static unsigned int parse_hex_value (const char __user *buffer,
--		unsigned long count, unsigned long *ret)
-+		unsigned long count, cpumask_t *ret)
- {
- 	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	cpumask_t value = CPU_MASK_NONE;
- 	int i;
- 
- 	if (!count)
-@@ -601,10 +613,9 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
--
- 	for (i = 0; i < count; i++) {
- 		unsigned int c = hexnum[i];
-+		int k;
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -613,7 +624,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (c & (1 << k))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -624,7 +638,7 @@ static int irq_affinity_write_proc (stru
- 					unsigned long count, void *data)
- {
- 	int irq = (int) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -641,7 +655,8 @@ static int irq_affinity_write_proc (stru
- 	 * are actually logical cpu #'s then we have no problem.
- 	 *  -- Cort <cort@fsmlabs.com>
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
-@@ -653,17 +668,27 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	cpumask_t mask = *(cpumask_t *)data;
-+	int k, len = 0;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(mask));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(mask, mask, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data, full_count = count, err;
-+	cpumask_t new_value;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- linux-2.6.0-test1/arch/ppc/kernel/misc.S	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/ppc/kernel/misc.S	2003-07-19 17:03:49.000000000 -0700
-@@ -1375,3 +1375,8 @@ _GLOBAL(sys_call_table)
- 	.long sys_clock_gettime
- 	.long sys_clock_getres
- 	.long sys_clock_nanosleep
-+	.long sys_ni_syscall	/* reserved for swapcontext */
-+	.long sys_tgkill	/* 250 */
-+	.long sys_utimes
-+	.long sys_statfs64
-+	.long sys_fstatfs64
---- linux-2.6.0-test1/arch/ppc/kernel/setup.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/ppc/kernel/setup.c	2003-07-19 17:04:07.000000000 -0700
-@@ -159,7 +159,7 @@ int show_cpuinfo(struct seq_file *m, voi
- 	}
- 
- #ifdef CONFIG_SMP
--	if (!(cpu_online_map & (1 << i)))
-+	if (!cpu_online(i))
- 		return 0;
- 	pvr = cpu_data[i].pvr;
- 	lpj = cpu_data[i].loops_per_jiffy;
---- linux-2.6.0-test1/arch/ppc/kernel/smp.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/ppc/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -47,7 +47,7 @@ atomic_t ipi_sent;
- DEFINE_PER_CPU(unsigned int, prof_multiplier);
- DEFINE_PER_CPU(unsigned int, prof_counter);
- unsigned long cache_decay_ticks = HZ/100;
--unsigned long cpu_online_map = 1UL;
-+unsigned long cpu_online_map = cpumask_of_cpu(0);
- unsigned long cpu_possible_map = 1UL;
- int smp_hw_index[NR_CPUS];
- struct thread_info *secondary_ti;
-@@ -361,8 +361,8 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_possible_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_possible_map);
- }
- 
- int __init setup_profiling_timer(unsigned int multiplier)
-@@ -444,7 +444,7 @@ int __cpu_up(unsigned int cpu)
- 	printk("Processor %d found.\n", cpu);
- 
- 	smp_ops->give_timebase();
--	set_bit(cpu, &cpu_online_map);
-+	cpu_set(cpu, cpu_online_map);
- 	return 0;
- }
- 
---- linux-2.6.0-test1/arch/ppc/kernel/syscalls.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/ppc/kernel/syscalls.c	2003-07-19 17:03:49.000000000 -0700
-@@ -20,7 +20,6 @@
-  *
-  */
- 
--#include <linux/config.h>
- #include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/mm.h>
-@@ -59,10 +58,15 @@ sys_ipc (uint call, int first, int secon
- 	version = call >> 16; /* hack for backward compatibility */
- 	call &= 0xffff;
- 
--	ret = -EINVAL;
-+	ret = -ENOSYS;
- 	switch (call) {
- 	case SEMOP:
--		ret = sys_semop (first, (struct sembuf __user *)ptr, second);
-+		ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
-+				      second, NULL);
-+		break;
-+	case SEMTIMEDOP:
-+		ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
-+				      second, (const struct timespec *) fifth);
- 		break;
- 	case SEMGET:
- 		ret = sys_semget (first, second, third);
-@@ -258,6 +262,4 @@ int sys_olduname(struct oldold_utsname _
- 	return error;
- }
- 
--cond_syscall(sys_pciconfig_read);
--cond_syscall(sys_pciconfig_write);
- cond_syscall(sys_pciconfig_iobase);
---- linux-2.6.0-test1/arch/ppc/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/ppc/kernel/time.c	2003-07-19 17:03:49.000000000 -0700
-@@ -244,7 +244,7 @@ int do_settimeofday(struct timespec *tv)
- 	time_t wtm_sec, new_sec = tv->tv_sec;
- 	long wtm_nsec, new_nsec = tv->tv_nsec;
- 	unsigned long flags;
--	int tb_delta, new_nsec, new_sec;
-+	int tb_delta;
- 
- 	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- 		return -EINVAL;
---- linux-2.6.0-test1/arch/ppc/mm/mem_pieces.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/arch/ppc/mm/mem_pieces.c	2003-07-19 17:03:49.000000000 -0700
-@@ -17,7 +17,6 @@
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/stddef.h>
--#include <linux/blk.h>
- #include <linux/init.h>
- 
- #include "mem_pieces.h"
---- linux-2.6.0-test1/arch/ppc/platforms/4xx/beech.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/arch/ppc/platforms/4xx/beech.c	2003-07-19 17:03:49.000000000 -0700
-@@ -25,7 +25,6 @@
-  *
-  */
- 
--#include <linux/blk.h>
- #include <linux/config.h>
- #include <linux/init.h>
- #include <linux/module.h>
---- linux-2.6.0-test1/arch/ppc/platforms/4xx/sycamore.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/arch/ppc/platforms/4xx/sycamore.c	2003-07-19 17:03:49.000000000 -0700
-@@ -17,7 +17,6 @@
- #include <linux/threads.h>
- #include <linux/param.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/pci.h>
- #include <linux/rtc.h>
- 
---- linux-2.6.0-test1/arch/ppc/platforms/4xx/walnut.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/arch/ppc/platforms/4xx/walnut.c	2003-07-19 17:03:49.000000000 -0700
-@@ -19,7 +19,6 @@
- #include <linux/threads.h>
- #include <linux/param.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/pci.h>
- #include <linux/rtc.h>
- 
---- linux-2.6.0-test1/arch/ppc/platforms/pmac_cpufreq.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/arch/ppc/platforms/pmac_cpufreq.c	2003-07-19 17:03:49.000000000 -0700
-@@ -176,7 +176,7 @@ do_set_cpu_speed(int speed_mode)
- 	
- 	freqs.old = cur_freq;
- 	freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
--	freqs.cpu = CPUFREQ_ALL_CPUS;
-+	freqs.cpu = smp_processor_id();
- 
- 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- 	if (cpufreq_uses_pmu)
---- linux-2.6.0-test1/arch/ppc/platforms/residual.c	2003-06-14 12:18:00.000000000 -0700
-+++ 25/arch/ppc/platforms/residual.c	2003-07-19 17:03:49.000000000 -0700
-@@ -36,7 +36,6 @@
- #include <linux/interrupt.h>
- #include <linux/reboot.h>
- #include <linux/init.h>
--#include <linux/blk.h>
- #include <linux/ioport.h>
- #include <linux/pci.h>
- #include <linux/ide.h>
---- linux-2.6.0-test1/arch/s390/defconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/defconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -20,6 +20,7 @@ CONFIG_SYSVIPC=y
- CONFIG_SYSCTL=y
- CONFIG_LOG_BUF_SHIFT=17
- # CONFIG_EMBEDDED is not set
-+# CONFIG_KALLSYMS is not set
- CONFIG_FUTEX=y
- CONFIG_EPOLL=y
- 
-@@ -169,7 +170,7 @@ CONFIG_IP_MULTICAST=y
- # CONFIG_INET_AH is not set
- # CONFIG_INET_ESP is not set
- # CONFIG_INET_IPCOMP is not set
--CONFIG_IPV6=m
-+CONFIG_IPV6=y
- # CONFIG_IPV6_PRIVACY is not set
- # CONFIG_INET6_AH is not set
- # CONFIG_INET6_ESP is not set
-@@ -180,7 +181,7 @@ CONFIG_IPV6=m
- #
- # SCTP Configuration (EXPERIMENTAL)
- #
--CONFIG_IPV6_SCTP__=m
-+CONFIG_IPV6_SCTP__=y
- # CONFIG_IP_SCTP is not set
- # CONFIG_ATM is not set
- # CONFIG_VLAN_8021Q is not set
-@@ -383,7 +384,6 @@ CONFIG_IBM_PARTITION=y
- CONFIG_DEBUG_KERNEL=y
- CONFIG_MAGIC_SYSRQ=y
- # CONFIG_DEBUG_SLAB is not set
--# CONFIG_KALLSYMS is not set
- # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
- 
- #
---- linux-2.6.0-test1/arch/s390/kernel/compat_ioctl.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/kernel/compat_ioctl.c	2003-07-19 17:03:49.000000000 -0700
-@@ -23,7 +23,6 @@
- #include <asm/types.h>
- #include <asm/uaccess.h>
- 
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- #include <linux/cdrom.h>
- #include <linux/dm-ioctl.h>
---- linux-2.6.0-test1/arch/s390/kernel/compat_linux.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/kernel/compat_linux.c	2003-07-19 17:03:49.000000000 -0700
-@@ -250,14 +250,14 @@ asmlinkage long sys32_getegid16(void)
- static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
- {
- 	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
--		(__get_user(o->tv_sec, &i->tv_sec) |
-+		(__get_user(o->tv_sec, &i->tv_sec) ||
- 		 __get_user(o->tv_usec, &i->tv_usec)));
- }
- 
- static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
- {
- 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
--		(__put_user(i->tv_sec, &o->tv_sec) |
-+		(__put_user(i->tv_sec, &o->tv_sec) ||
- 		 __put_user(i->tv_usec, &o->tv_usec)));
- }
- 
---- linux-2.6.0-test1/arch/s390/kernel/entry64.S	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/kernel/entry64.S	2003-07-19 17:03:49.000000000 -0700
-@@ -637,6 +637,7 @@ io_sigpending:     
- ext_int_handler:
-         SAVE_ALL __LC_EXT_OLD_PSW,0
-         GET_THREAD_INFO                # load pointer to task_struct to R9
-+	brasl   %r14,do_extint
- 	llgh	%r6,__LC_EXT_INT_CODE  # get interruption code
- 	lgr	%r1,%r6		       # calculate index = code & 0xff
- 	nill	%r1,0xff
---- linux-2.6.0-test1/arch/s390/kernel/entry.S	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/kernel/entry.S	2003-07-19 17:03:49.000000000 -0700
-@@ -606,6 +606,8 @@ ext_int_handler:
- 	SAVE_ALL_BASE
-         SAVE_ALL __LC_EXT_OLD_PSW,0
-         GET_THREAD_INFO                # load pointer to task_struct to R9
-+	l	%r1,BASED(.Ldo_extint)
-+	basr	%r14,%r1
- 	lh	%r6,__LC_EXT_INT_CODE  # get interruption code
- 	lr	%r1,%r6		       # calculate index = code & 0xff
- 	n	%r1,BASED(.Lc0xff)
-@@ -694,6 +696,7 @@ restart_go:
-  */
- .Ls390_mcck:   .long  s390_do_machine_check
- .Ldo_IRQ:      .long  do_IRQ
-+.Ldo_extint:   .long  do_extint
- .Ldo_signal:   .long  do_signal
- .Ldo_softirq:  .long  do_softirq
- .Lentry_base:  .long  entry_base
---- linux-2.6.0-test1/arch/s390/kernel/s390_ext.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/arch/s390/kernel/s390_ext.c	2003-07-19 17:03:49.000000000 -0700
-@@ -11,8 +11,11 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/errno.h>
-+#include <linux/kernel_stat.h>
-+
- #include <asm/lowcore.h>
- #include <asm/s390_ext.h>
-+#include <asm/irq.h>
- 
- /*
-  * Simple hash strategy: index = code & 0xff;
-@@ -98,6 +101,11 @@ int unregister_early_external_interrupt(
- 	return 0;
- }
- 
-+void do_extint(void)
-+{
-+	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
-+}
-+
- EXPORT_SYMBOL(register_external_interrupt);
- EXPORT_SYMBOL(unregister_external_interrupt);
- 
---- linux-2.6.0-test1/arch/s390/kernel/setup.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/s390/kernel/setup.c	2003-07-19 17:04:07.000000000 -0700
-@@ -34,12 +34,15 @@
- #include <linux/root_dev.h>
- #include <linux/console.h>
- #include <linux/seq_file.h>
-+#include <linux/kernel_stat.h>
-+
- #include <asm/uaccess.h>
- #include <asm/system.h>
- #include <asm/smp.h>
- #include <asm/mmu_context.h>
- #include <asm/cpcmd.h>
- #include <asm/lowcore.h>
-+#include <asm/irq.h>
- 
- /*
-  * Machine setup..
-@@ -53,7 +56,7 @@ struct { unsigned long addr, size, type;
- #define CHUNK_READ_WRITE 0
- #define CHUNK_READ_ONLY 1
- int cpus_initialized = 0;
--unsigned long cpu_initialized = 0;
-+static cpumask_t cpu_initialized;
- volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
- 
- /*
-@@ -83,7 +86,7 @@ void __devinit cpu_init (void)
-         int nr = smp_processor_id();
-         int addr = hard_smp_processor_id();
- 
--        if (test_and_set_bit(nr,&cpu_initialized)) {
-+        if (cpu_test_and_set(nr,cpu_initialized)) {
-                 printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr);
-                 for (;;) local_irq_enable();
-         }
-@@ -562,7 +565,7 @@ static int show_cpuinfo(struct seq_file 
- 			       num_online_cpus(), loops_per_jiffy/(500000/HZ),
- 			       (loops_per_jiffy/(5000/HZ))%100);
- 	}
--	if (cpu_online_map & (1 << n)) {
-+	if (cpu_online(n)) {
- #ifdef CONFIG_SMP
- 		if (smp_processor_id() == n)
- 			cpuinfo = &S390_lowcore.cpu_data;
-@@ -600,3 +603,40 @@ struct seq_operations cpuinfo_op = {
- 	.stop	= c_stop,
- 	.show	= show_cpuinfo,
- };
-+
-+/*
-+ * show_interrupts is needed by /proc/interrupts.
-+ */
-+
-+static const char *intrclass_names[] = {
-+	"EXT",
-+	"I/O",
-+};
-+
-+int show_interrupts(struct seq_file *p, void *v)
-+{
-+        int i, j;
-+	
-+        seq_puts(p, "           ");
-+	
-+        for (j=0; j<NR_CPUS; j++)
-+                if (cpu_online(j))
-+                        seq_printf(p, "CPU%d       ",j);
-+	
-+        seq_putc(p, '\n');
-+	
-+        for (i = 0 ; i < NR_IRQS ; i++) {
-+		seq_printf(p, "%s: ", intrclass_names[i]);
-+#ifndef CONFIG_SMP
-+		seq_printf(p, "%10u ", kstat_irqs(i));
-+#else
-+		for (j = 0; j < NR_CPUS; j++)
-+			if (cpu_online(j))
-+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-+#endif
-+                seq_putc(p, '\n');
-+		
-+        }
-+	
-+        return 0;
-+}
---- linux-2.6.0-test1/arch/s390/kernel/smp.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/s390/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -51,8 +51,8 @@ struct _lowcore *lowcore_ptr[NR_CPUS];
- cycles_t         cacheflush_time=0;
- int              smp_threads_ready=0;      /* Set when the idlers are all forked. */
- 
--volatile unsigned long cpu_online_map;
--volatile unsigned long cpu_possible_map;
-+cpumask_t cpu_online_map;
-+cpumask_t cpu_possible_map;
- unsigned long    cache_decay_ticks = 0;
- 
- /*
-@@ -200,14 +200,14 @@ void smp_send_stop(void)
- /*
-  * Reboot, halt and power_off routines for SMP.
-  */
--static volatile unsigned long cpu_restart_map;
-+static cpumask_t cpu_restart_map;
- 
- static void do_machine_restart(void * __unused)
- {
--	clear_bit(smp_processor_id(), &cpu_restart_map);
-+	cpu_clear(smp_processor_id(), cpu_restart_map);
- 	if (smp_processor_id() == 0) {
- 		/* Wait for all other cpus to enter do_machine_restart. */
--		while (cpu_restart_map != 0);
-+		while (!cpus_empty(cpu_restart_map));
- 		/* Store status of other cpus. */
- 		do_store_status();
- 		/*
-@@ -427,7 +427,7 @@ void __init smp_check_cpus(unsigned int 
-                 if (signal_processor(num_cpus, sigp_sense) ==
-                     sigp_not_operational)
-                         continue;
--		set_bit(num_cpus, &cpu_possible_map);
-+		cpu_set(num_cpus, cpu_possible_map);
-                 num_cpus++;
-         }
-         printk("Detected %d CPU's\n",(int) num_cpus);
-@@ -452,7 +452,7 @@ int __devinit start_secondary(void *cpuv
- 	pfault_init();
- #endif
- 	/* Mark this cpu as online */
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- 	/* Switch on interrupts */
- 	local_irq_enable();
-         /* Print info about this processor */
-@@ -558,8 +558,8 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_possible_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_possible_map);
- }
- 
- void smp_cpus_done(unsigned int max_cpus)
---- linux-2.6.0-test1/arch/s390/mm/init.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/s390/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -22,9 +22,6 @@
- #include <linux/swap.h>
- #include <linux/smp.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
--#endif
- #include <linux/pagemap.h>
- #include <linux/bootmem.h>
- 
---- linux-2.6.0-test1/arch/s390/mm/ioremap.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/s390/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -83,7 +83,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/sh/mm/init.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/sh/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -22,9 +22,6 @@
- #include <linux/swap.h>
- #include <linux/smp.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
--#endif
- #include <linux/highmem.h>
- #include <linux/bootmem.h>
- 
---- linux-2.6.0-test1/arch/sh/mm/ioremap.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/sh/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -45,7 +45,7 @@ static inline void remap_area_pte(pte_t 
- 	} while (address && (address < end));
- }
- 
--static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
-+static inline int remap_area_pmd(pgd_t *pgd, pmd_t * pmd, unsigned long address,
- 	unsigned long size, unsigned long phys_addr, unsigned long flags)
- {
- 	unsigned long end;
-@@ -83,11 +83,11 @@ int remap_area_pages(unsigned long addre
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_map(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
--		if (remap_area_pmd(pmd, address, end - address,
-+		if (remap_area_pmd(dir, pmd, address, end - address,
- 					phys_addr + address, flags))
- 			break;
- 		error = 0;
---- linux-2.6.0-test1/arch/sparc64/kernel/devices.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/arch/sparc64/kernel/devices.c	2003-07-19 17:06:40.000000000 -0700
-@@ -31,6 +31,8 @@ int linux_num_cpus = 0;
- extern void cpu_probe(void);
- extern void central_probe(void);
- 
-+unsigned long cpu_hz;
-+
- void __init device_scan(void)
- {
- 	char node_str[128];
-@@ -68,6 +70,8 @@ void __init device_scan(void)
- 					prom_getproperty(scan, "portid",
- 							 (char *) &thismid, sizeof(thismid));
- 				}
-+				if (!cpu_hz)
-+					cpu_hz = prom_getint(scan, "clock-frequency");
- 				linux_cpus[cpu_ctr].mid = thismid;
- 				printk("Found CPU %d (node=%08x,mid=%d)\n",
- 				       cpu_ctr, (unsigned) scan, thismid);
---- linux-2.6.0-test1/arch/sparc64/kernel/head.S	2003-06-14 12:18:07.000000000 -0700
-+++ 25/arch/sparc64/kernel/head.S	2003-07-19 17:03:49.000000000 -0700
-@@ -66,7 +66,7 @@ sparc_ramdisk_image:
- sparc_ramdisk_size:
-         .word   0
-         .xword  reboot_command
--	.xword	bootstr_len
-+	.xword	bootstr_info
- 	.word	_end
- 
- 	/* We must be careful, 32-bit OpenBOOT will get confused if it
-@@ -740,8 +740,9 @@ swapper_pg_dir:
- 
- 	.data
- 	.align	8
--	.globl	prom_tba
-+	.globl	prom_tba, tlb_type
- prom_tba:	.xword	0
-+tlb_type:	.word	0	/* Must NOT end up in BSS */
- 	.section	".fixup",#alloc,#execinstr
- 	.globl	__ret_efault
- __ret_efault:
---- linux-2.6.0-test1/arch/sparc64/kernel/irq.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/sparc64/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -110,6 +110,10 @@ static void register_irq_proc (unsigned 
- 		action->flags |= __irq_ino(irq) << 48;
- #define get_ino_in_irqaction(action)	(action->flags >> 48)
- 
-+#if NR_CPUS > 64
-+#error irqaction embedded smp affinity does not work with > 64 cpus, FIXME
-+#endif
-+
- #define put_smpaff_in_irqaction(action, smpaff)	(action)->mask = (smpaff)
- #define get_smpaff_in_irqaction(action) 	((action)->mask)
- 
-@@ -658,11 +662,11 @@ static inline void redirect_intr(int cpu
- 	 *    Just Do It.
- 	 */
- 	struct irqaction *ap = bp->irq_info;
--	unsigned long cpu_mask = get_smpaff_in_irqaction(ap);
-+	cpumask_t cpu_mask = { .mask[0] = get_smpaff_in_irqaction(ap) };
- 	unsigned int buddy, ticks;
- 
--	cpu_mask &= cpu_online_map;
--	if (cpu_mask == 0)
-+	cpus_and(cpu_mask, cpu_mask, cpu_online_map);
-+	if (cpus_empty(cpu_mask))
- 		cpu_mask = cpu_online_map;
- 
- 	if (this_is_starfire != 0 ||
-@@ -677,7 +681,7 @@ static inline void redirect_intr(int cpu
- 		buddy = 0;
- 
- 	ticks = 0;
--	while ((cpu_mask & (1UL << buddy)) == 0) {
-+	while (!cpu_isset(buddy, cpu_mask)) {
- 		if (++buddy >= NR_CPUS)
- 			buddy = 0;
- 		if (++ticks > NR_CPUS) {
---- linux-2.6.0-test1/arch/sparc64/kernel/pci.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/arch/sparc64/kernel/pci.c	2003-07-19 17:03:49.000000000 -0700
-@@ -804,25 +804,20 @@ int pci_mmap_page_range(struct pci_dev *
- 
- /* Return the domain nuber for this pci bus */
- 
--int pci_domain_nr(struct pci_bus *bus)
-+int pci_domain_nr(struct pci_bus *pbus)
- {
--	struct pcidev_cookie *cookie = bus->sysdata;
-+	struct pci_pbm_info *pbm = pbus->sysdata;
- 	int ret;
- 
--	if (cookie != NULL) {
--		struct pci_pbm_info *pbm = cookie->pbm;
--		if (pbm == NULL || pbm->parent == NULL) {
--			ret = -ENXIO;
--		} else {
--			struct pci_controller_info *p = pbm->parent;
--
--			ret = p->index;
--			if (p->pbms_same_domain == 0)
--				ret = ((ret << 1) +
--				       ((pbm == &pbm->parent->pbm_B) ? 1 : 0));
--		}
--	} else {
-+	if (pbm == NULL || pbm->parent == NULL) {
- 		ret = -ENXIO;
-+	} else {
-+		struct pci_controller_info *p = pbm->parent;
-+
-+		ret = p->index;
-+		if (p->pbms_same_domain == 0)
-+			ret = ((ret << 1) +
-+			       ((pbm == &pbm->parent->pbm_B) ? 1 : 0));
- 	}
- 
- 	return ret;
---- linux-2.6.0-test1/arch/sparc64/kernel/setup.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/arch/sparc64/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -24,7 +24,6 @@
- #include <linux/kdev_t.h>
- #include <linux/major.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/init.h>
- #include <linux/inet.h>
- #include <linux/console.h>
---- linux-2.6.0-test1/arch/sparc64/kernel/smp.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/sparc64/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -46,12 +46,11 @@ cpuinfo_sparc cpu_data[NR_CPUS];
- /* Please don't make this stuff initdata!!!  --DaveM */
- static unsigned char boot_cpu_id;
- 
--atomic_t sparc64_num_cpus_online = ATOMIC_INIT(0);
--unsigned long cpu_online_map = 0;
-+cpumask_t cpu_online_map = CPU_MASK_NONE;
- atomic_t sparc64_num_cpus_possible = ATOMIC_INIT(0);
--unsigned long phys_cpu_present_map = 0;
--static unsigned long smp_commenced_mask;
--static unsigned long cpu_callout_map;
-+cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
-+static cpumask_t smp_commenced_mask;
-+static cpumask_t cpu_callout_map;
- 
- void smp_info(struct seq_file *m)
- {
-@@ -151,11 +150,10 @@ void __init smp_callin(void)
- 	atomic_inc(&init_mm.mm_count);
- 	current->active_mm = &init_mm;
- 
--	while (!test_bit(cpuid, &smp_commenced_mask))
-+	while (!cpu_isset(cpuid, smp_commenced_mask))
- 		membar("#LoadLoad");
- 
--	set_bit(cpuid, &cpu_online_map);
--	atomic_inc(&sparc64_num_cpus_online);
-+	cpu_set(cpuid, cpu_online_map);
- }
- 
- void cpu_panic(void)
-@@ -334,7 +332,7 @@ static int __devinit smp_boot_one_cpu(un
- 		if (linux_cpus[no].mid == cpu)
- 			break;
- 	cpu_new_thread = p->thread_info;
--	set_bit(cpu, &cpu_callout_map);
-+	cpu_set(cpu, cpu_callout_map);
- 	prom_startcpu(linux_cpus[no].prom_node, entry, cookie);
- 	for (timeout = 0; timeout < 5000000; timeout++) {
- 		if (callin_flag)
-@@ -346,7 +344,7 @@ static int __devinit smp_boot_one_cpu(un
- 		ret = 0;
- 	} else {
- 		printk("Processor %d is stuck.\n", cpu);
--		clear_bit(cpu, &cpu_callout_map);
-+		cpu_clear(cpu, cpu_callout_map);
- 		ret = -ENODEV;
- 	}
- 	cpu_new_thread = NULL;
-@@ -420,17 +418,17 @@ again:
- 	}
- }
- 
--static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask)
-+static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
- {
- 	u64 pstate;
- 	int i;
- 
- 	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (mask & (1UL << i)) {
-+		if (cpu_isset(i, mask)) {
- 			spitfire_xcall_helper(data0, data1, data2, pstate, i);
--			mask &= ~(1UL << i);
--			if (!mask)
-+			cpu_clear(i, mask);
-+			if (cpus_empty(mask))
- 				break;
- 		}
- 	}
-@@ -443,12 +441,12 @@ static __inline__ void spitfire_xcall_de
- #if NR_CPUS > 32
- #error Fixup cheetah_xcall_deliver Dave...
- #endif
--static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask)
-+static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
- {
- 	u64 pstate;
- 	int nack_busy_id;
- 
--	if (!mask)
-+	if (cpus_empty(mask))
- 		return;
- 
- 	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
-@@ -469,11 +467,11 @@ retry:
- 
- 	nack_busy_id = 0;
- 	{
--		unsigned long work_mask = mask;
-+		cpumask_t work_mask = mask;
- 		int i;
- 
- 		for (i = 0; i < NR_CPUS; i++) {
--			if (work_mask & (1UL << i)) {
-+			if (cpu_isset(i, work_mask)) {
- 				u64 target = (i << 14) | 0x70;
- 
- 				target |= (nack_busy_id++ << 24);
-@@ -482,8 +480,8 @@ retry:
- 					"membar	#Sync\n\t"
- 					: /* no outputs */
- 					: "r" (target), "i" (ASI_INTR_W));
--				work_mask &= ~(1UL << i);
--				if (!work_mask)
-+				cpu_clear(i, work_mask);
-+				if (cpus_empty(work_mask))
- 					break;
- 			}
- 		}
-@@ -518,7 +516,7 @@ retry:
- 			printk("CPU[%d]: mondo stuckage result[%016lx]\n",
- 			       smp_processor_id(), dispatch_stat);
- 		} else {
--			unsigned long work_mask = mask;
-+			cpumask_t work_mask = mask;
- 			int i, this_busy_nack = 0;
- 
- 			/* Delay some random time with interrupts enabled
-@@ -530,13 +528,13 @@ retry:
- 			 * NACK us.
- 			 */
- 			for (i = 0; i < NR_CPUS; i++) {
--				if (work_mask & (1UL << i)) {
-+				if (cpu_isset(i, work_mask)) {
- 					if ((dispatch_stat &
- 					     (0x2 << this_busy_nack)) == 0)
--						mask &= ~(1UL << i);
-+						cpu_clear(i, mask);
- 					this_busy_nack += 2;
--					work_mask &= ~(1UL << i);
--					if (!work_mask)
-+					cpu_clear(i, work_mask);
-+					if (cpus_empty(work_mask))
- 						break;
- 				}
- 			}
-@@ -549,12 +547,12 @@ retry:
- /* Send cross call to all processors mentioned in MASK
-  * except self.
-  */
--static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, unsigned long mask)
-+static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, cpumask_t mask)
- {
- 	u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
- 
--	mask &= cpu_online_map;
--	mask &= ~(1UL<<smp_processor_id());
-+	cpus_and(mask, mask, cpu_online_map);
-+	cpu_clear(smp_processor_id(), mask);
- 
- 	if (tlb_type == spitfire)
- 		spitfire_xcall_deliver(data0, data1, data2, mask);
-@@ -567,9 +565,10 @@ extern unsigned long xcall_sync_tick;
- 
- static void smp_start_sync_tick_client(int cpu)
- {
-+	cpumask_t mask = cpumask_of_cpu(cpu);
-+
- 	smp_cross_call_masked(&xcall_sync_tick,
--			      0, 0, 0,
--			      (1UL << cpu));
-+			      0, 0, 0, mask);
- }
- 
- /* Send cross call to all processors except self. */
-@@ -685,14 +684,14 @@ static __inline__ void __local_flush_dca
- 
- void smp_flush_dcache_page_impl(struct page *page, int cpu)
- {
--	unsigned long mask = 1UL << cpu;
-+	cpumask_t mask = cpumask_of_cpu(cpu);
- 
- #ifdef CONFIG_DEBUG_DCFLUSH
- 	atomic_inc(&dcpage_flushes);
- #endif
- 	if (cpu == smp_processor_id()) {
- 		__local_flush_dcache_page(page);
--	} else if ((cpu_online_map & mask) != 0) {
-+	} else if (cpu_online(cpu)) {
- 		u64 data0;
- 
- 		if (tlb_type == spitfire) {
-@@ -719,13 +718,14 @@ void smp_flush_dcache_page_impl(struct p
- 
- void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
- {
--	unsigned long mask = cpu_online_map & ~(1UL << smp_processor_id());
-+	cpumask_t mask = cpu_online_map;
-+	cpu_clear(smp_processor_id(), mask);
- 	u64 data0;
- 
- #ifdef CONFIG_DEBUG_DCFLUSH
- 	atomic_inc(&dcpage_flushes);
- #endif
--	if (mask == 0UL)
-+	if (cpus_empty(mask))
- 		goto flush_self;
- 	if (tlb_type == spitfire) {
- 		data0 = ((u64)&xcall_flush_dcache_page_spitfire);
-@@ -750,9 +750,9 @@ void flush_dcache_page_all(struct mm_str
- 
- void smp_receive_signal(int cpu)
- {
--	unsigned long mask = 1UL << cpu;
-+	cpumask_t mask = cpumask_of_cpu(cpu);
- 
--	if ((cpu_online_map & mask) != 0) {
-+	if (cpu_online(cpu)) {
- 		u64 data0 = (((u64)&xcall_receive_signal) & 0xffffffff);
- 
- 		if (tlb_type == spitfire)
-@@ -854,7 +854,7 @@ void smp_flush_tlb_mm(struct mm_struct *
- 
- 		if (atomic_read(&mm->mm_users) == 1) {
- 			/* See smp_flush_tlb_page for info about this. */
--			mm->cpu_vm_mask = (1UL << cpu);
-+			mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- 			goto local_flush_and_out;
- 		}
- 
-@@ -877,7 +877,7 @@ void smp_flush_tlb_range(struct mm_struc
- 	end    = PAGE_ALIGN(end);
- 
- 	if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
--		mm->cpu_vm_mask = (1UL << cpu);
-+		mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- 		goto local_flush_and_out;
- 	}
- 
-@@ -921,14 +921,16 @@ void smp_flush_tlb_page(struct mm_struct
- 			 * is almost certain that all TLB entries for this
- 			 * context will be replaced by the time that happens.
- 			 */
--			mm->cpu_vm_mask = (1UL << cpu);
-+			mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- 			goto local_flush_and_out;
- 		} else {
-+			cpumask_t this_cpu_mask = cpumask_of_cpu(cpu);
-+
- 			/* By virtue of running under the mm->page_table_lock,
- 			 * and mmu_context.h:switch_mm doing the same, the
- 			 * following operation is safe.
- 			 */
--			if (mm->cpu_vm_mask == (1UL << cpu))
-+			if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask))
- 				goto local_flush_and_out;
- 		}
- 
-@@ -939,7 +941,7 @@ void smp_flush_tlb_page(struct mm_struct
- 		smp_cross_call_masked(&xcall_flush_tlb_page,
- 				      ctx, page, 0,
- 				      mm->cpu_vm_mask);
--		if (!(mm->cpu_vm_mask & (1UL << cpu)))
-+		if (!cpu_isset(cpu, mm->cpu_vm_mask))
- 			return;
- 
- 	local_flush_and_out:
-@@ -1122,8 +1124,7 @@ void __init smp_tick_init(void)
- 		prom_halt();
- 	}
- 
--	atomic_inc(&sparc64_num_cpus_online);
--	set_bit(boot_cpu_id, &cpu_online_map);
-+	cpu_set(boot_cpu_id, cpu_online_map);
- 	prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node;
- 	prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1;
- }
-@@ -1241,16 +1242,14 @@ void __init smp_prepare_cpus(unsigned in
- 
- 	for (i = 0; i < linux_num_cpus; i++) {
- 		if (linux_cpus[i].mid < max_cpus) {
--			set_bit(linux_cpus[i].mid,
--				&phys_cpu_present_map);
-+			cpu_set(linux_cpus[i].mid, phys_cpu_present_map);
- 			atomic_inc(&sparc64_num_cpus_possible);
- 		}
- 	}
- 	if (atomic_read(&sparc64_num_cpus_possible) > max_cpus) {
- 		for (i = linux_num_cpus - 1; i >= 0; i--) {
- 			if (linux_cpus[i].mid != boot_cpu_id) {
--				clear_bit(linux_cpus[i].mid,
--					  &phys_cpu_present_map);
-+				cpu_clear(linux_cpus[i].mid, phys_cpu_present_map);
- 				atomic_dec(&sparc64_num_cpus_possible);
- 				if (atomic_read(&sparc64_num_cpus_possible) <= max_cpus)
- 					break;
-@@ -1263,8 +1262,8 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &phys_cpu_present_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), phys_cpu_present_map);
- }
- 
- int __devinit __cpu_up(unsigned int cpu)
-@@ -1272,10 +1271,10 @@ int __devinit __cpu_up(unsigned int cpu)
- 	int ret = smp_boot_one_cpu(cpu);
- 
- 	if (!ret) {
--		set_bit(cpu, &smp_commenced_mask);
--		while (!test_bit(cpu, &cpu_online_map))
-+		cpu_set(cpu, smp_commenced_mask);
-+		while (!cpu_isset(cpu, cpu_online_map))
- 			mb();
--		if (!test_bit(cpu, &cpu_online_map)) {
-+		if (!cpu_isset(cpu, cpu_online_map)) {
- 			ret = -ENODEV;
- 		} else {
- 			smp_synchronize_one_tick(cpu);
---- linux-2.6.0-test1/arch/sparc64/kernel/sparc64_ksyms.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/sparc64/kernel/sparc64_ksyms.c	2003-07-19 17:04:07.000000000 -0700
-@@ -147,7 +147,6 @@ EXPORT_SYMBOL(cpu_data);
- 
- /* CPU online map and active count.  */
- EXPORT_SYMBOL(cpu_online_map);
--EXPORT_SYMBOL(sparc64_num_cpus_online);
- EXPORT_SYMBOL(phys_cpu_present_map);
- EXPORT_SYMBOL(sparc64_num_cpus_possible);
- 
-@@ -176,6 +175,8 @@ EXPORT_SYMBOL(up);
- /* Atomic counter implementation. */
- EXPORT_SYMBOL(__atomic_add);
- EXPORT_SYMBOL(__atomic_sub);
-+EXPORT_SYMBOL(__atomic64_add);
-+EXPORT_SYMBOL(__atomic64_sub);
- #ifdef CONFIG_SMP
- EXPORT_SYMBOL(atomic_dec_and_lock);
- #endif
---- linux-2.6.0-test1/arch/sparc64/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/sparc64/kernel/time.c	2003-07-19 17:03:49.000000000 -0700
-@@ -41,6 +41,7 @@
- #include <asm/isa.h>
- #include <asm/starfire.h>
- #include <asm/smp.h>
-+#include <asm/sections.h>
- 
- spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
- spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
-@@ -449,7 +450,6 @@ void sparc64_do_profile(struct pt_regs *
- 		return;
- 
- 	{
--		extern int _stext;
- 		extern int rwlock_impl_begin, rwlock_impl_end;
- 		extern int atomic_impl_begin, atomic_impl_end;
- 		extern int __memcpy_begin, __memcpy_end;
-@@ -468,7 +468,7 @@ void sparc64_do_profile(struct pt_regs *
- 		     pc < (unsigned long) &__bitops_end))
- 			pc = o7;
- 
--		pc -= (unsigned long) &_stext;
-+		pc -= (unsigned long) _stext;
- 		pc >>= prof_shift;
- 
- 		if(pc >= prof_len)
---- linux-2.6.0-test1/arch/sparc64/kernel/us2e_cpufreq.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/sparc64/kernel/us2e_cpufreq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -232,15 +232,16 @@ static unsigned long estar_to_divisor(un
- 
- static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
- {
--	unsigned long new_bits, new_freq, cpus_allowed;
-+	unsigned long new_bits, new_freq;
- 	unsigned long clock_tick, divisor, old_divisor, estar;
-+	cpumask_t cpus_allowed;
- 	struct cpufreq_freqs freqs;
- 
- 	if (!cpu_online(cpu))
- 		return;
- 
- 	cpus_allowed = current->cpus_allowed;
--	set_cpus_allowed(current, (1UL << cpu));
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 
- 	new_freq = clock_tick = sparc64_get_clock_tick(cpu);
- 	new_bits = index_to_estar_mode(index);
---- linux-2.6.0-test1/arch/sparc64/kernel/us3_cpufreq.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/arch/sparc64/kernel/us3_cpufreq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -78,14 +78,15 @@ static unsigned long get_current_freq(un
- 
- static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
- {
--	unsigned long new_bits, new_freq, reg, cpus_allowed;
-+	unsigned long new_bits, new_freq, reg;
-+	cpumask_t cpus_allowed;
- 	struct cpufreq_freqs freqs;
- 
- 	if (!cpu_online(cpu))
- 		return;
- 
- 	cpus_allowed = current->cpus_allowed;
--	set_cpus_allowed(current, (1UL << cpu));
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 
- 	new_freq = sparc64_get_clock_tick(cpu);
- 	switch (index) {
---- linux-2.6.0-test1/arch/sparc64/lib/atomic.S	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/sparc64/lib/atomic.S	2003-07-19 17:03:49.000000000 -0700
-@@ -33,4 +33,27 @@ __atomic_sub: /* %o0 = increment, %o1 = 
- 	 membar	#StoreLoad | #StoreStore
- 	retl
- 	 sub	%g7, %o0, %o0
-+
-+	.globl	__atomic64_add
-+__atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
-+	ldx	[%o1], %g5
-+	add	%g5, %o0, %g7
-+	casx	[%o1], %g5, %g7
-+	cmp	%g5, %g7
-+	bne,pn	%xcc, __atomic64_add
-+	 membar	#StoreLoad | #StoreStore
-+	retl
-+	 add	%g7, %o0, %o0
-+
-+	.globl	__atomic64_sub
-+__atomic64_sub: /* %o0 = increment, %o1 = atomic_ptr */
-+	ldx	[%o1], %g5
-+	sub	%g5, %o0, %g7
-+	casx	[%o1], %g5, %g7
-+	cmp	%g5, %g7
-+	bne,pn	%xcc, __atomic64_sub
-+	 membar	#StoreLoad | #StoreStore
-+	retl
-+	 sub	%g7, %o0, %o0
-+
- atomic_impl_end:
---- linux-2.6.0-test1/arch/sparc64/lib/rwlock.S	2003-06-26 22:07:24.000000000 -0700
-+++ 25/arch/sparc64/lib/rwlock.S	2003-07-19 17:06:40.000000000 -0700
-@@ -63,5 +63,33 @@ __write_lock: /* %o0 = lock_ptr */
- 	be,pt		%icc, 99b
- 	 membar		#StoreLoad | #StoreStore
- 	ba,a,pt		%xcc, 1b
-+
-+	.globl	__read_trylock
-+__read_trylock: /* %o0 = lock_ptr */
-+	ldsw		[%o0], %g5
-+	brlz,pn		%g5, 100f
-+	 add		%g5, 1, %g7
-+	cas		[%o0], %g5, %g7
-+	cmp		%g5, %g7
-+	bne,pn		%icc, __read_trylock
-+	 membar		#StoreLoad | #StoreStore
-+	retl
-+	 mov		1, %o0
-+
-+	.globl		__write_trylock
-+__write_trylock: /* %o0 = lock_ptr */
-+	sethi		%hi(0x80000000), %g2
-+1:	lduw		[%o0], %g5
-+4:	brnz,pn		%g5, 100f
-+	 or		%g5, %g2, %g7
-+	cas		[%o0], %g5, %g7
-+	cmp		%g5, %g7
-+	bne,pn		%icc, 1b
-+	 membar		#StoreLoad | #StoreStore
-+	retl
-+	 mov		1, %o0
-+100:	retl
-+	 mov		0, %o0
-+
- rwlock_impl_end:
- 
---- linux-2.6.0-test1/arch/sparc64/mm/fault.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/sparc64/mm/fault.c	2003-07-19 17:03:49.000000000 -0700
-@@ -26,6 +26,7 @@
- #include <asm/uaccess.h>
- #include <asm/asi.h>
- #include <asm/lsu.h>
-+#include <asm/sections.h>
- 
- #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
- 
-@@ -320,10 +321,9 @@ asmlinkage void do_sparc64_fault(struct 
- 
- 	if (regs->tstate & TSTATE_PRIV) {
- 		unsigned long tpc = regs->tpc;
--		extern unsigned int _etext;
- 
- 		/* Sanity check the PC. */
--		if ((tpc >= KERNBASE && tpc < (unsigned long) &_etext) ||
-+		if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
- 		    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
- 			/* Valid, no problems... */
- 		} else {
---- linux-2.6.0-test1/arch/sparc64/mm/generic.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/sparc64/mm/generic.c	2003-07-19 17:07:16.000000000 -0700
-@@ -85,7 +85,7 @@ static inline void io_remap_pte_range(pt
- 	} while (address < end);
- }
- 
--static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size,
-+static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size,
- 	unsigned long offset, pgprot_t prot, int space)
- {
- 	unsigned long end;
-@@ -96,7 +96,7 @@ static inline int io_remap_pmd_range(pmd
- 		end = PGDIR_SIZE;
- 	offset -= address;
- 	do {
--		pte_t * pte = pte_alloc_map(current->mm, pmd, address);
-+		pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address);
- 		if (!pte)
- 			return -ENOMEM;
- 		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
-@@ -122,11 +122,11 @@ int io_remap_page_range(struct vm_area_s
- 
- 	spin_lock(&mm->page_table_lock);
- 	while (from < end) {
--		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
-+		pmd_t *pmd = pmd_alloc_map(current->mm, dir, from);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
--		error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space);
-+		error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space);
- 		if (error)
- 			break;
- 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
---- linux-2.6.0-test1/arch/sparc64/mm/hugetlbpage.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/arch/sparc64/mm/hugetlbpage.c	2003-07-19 17:07:16.000000000 -0700
-@@ -107,9 +107,11 @@ static pte_t *huge_pte_alloc_map(struct 
- 
- 	pgd = pgd_offset(mm, addr);
- 	if (pgd) {
--		pmd = pmd_alloc(mm, pgd, addr);
--		if (pmd)
--			pte = pte_alloc_map(mm, pmd, addr);
-+		pmd = pmd_alloc_map(mm, pgd, addr);
-+		if (pmd) {
-+			pte = pte_alloc_map(mm, pgd, &pmd, addr);
-+			pmd_unmap(pmd);
-+		}
- 	}
- 	return pte;
- }
-@@ -122,9 +124,11 @@ static pte_t *huge_pte_offset_map(struct
- 
- 	pgd = pgd_offset(mm, addr);
- 	if (pgd) {
--		pmd = pmd_offset(pgd, addr);
--		if (pmd)
-+		pmd = pmd_offset_map(pgd, addr);
-+		if (pmd) {
- 			pte = pte_offset_map(pmd, addr);
-+			pmd_unmap(pmd);
-+		}
- 	}
- 	return pte;
- }
---- linux-2.6.0-test1/arch/sparc64/mm/init.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/arch/sparc64/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -35,6 +35,7 @@
- #include <asm/starfire.h>
- #include <asm/tlb.h>
- #include <asm/spitfire.h>
-+#include <asm/sections.h>
- 
- DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
- 
-@@ -48,16 +49,14 @@ unsigned long *sparc64_valid_addr_bitmap
- unsigned long phys_base;
- unsigned long pfn_base;
- 
--enum ultra_tlb_layout tlb_type = spitfire;
--
- /* get_new_mmu_context() uses "cache + 1".  */
- spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED;
- unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
- #define CTX_BMAP_SLOTS (1UL << (CTX_VERSION_SHIFT - 6))
- unsigned long mmu_context_bmap[CTX_BMAP_SLOTS];
- 
--/* References to section boundaries */
--extern char __init_begin, __init_end, _start, _end, etext, edata;
-+/* References to special section boundaries */
-+extern char  _start[], _end[];
- 
- /* Initial ramdisk setup */
- extern unsigned int sparc_ramdisk_image;
-@@ -1333,7 +1332,7 @@ unsigned long __init bootmem_init(unsign
- 	 * image.  The kernel is hard mapped below PAGE_OFFSET in a
- 	 * 4MB locked TLB translation.
- 	 */
--	start_pfn  = PAGE_ALIGN((unsigned long) &_end) -
-+	start_pfn  = PAGE_ALIGN((unsigned long) _end) -
- 		((unsigned long) KERNBASE);
- 
- 	/* Adjust up to the physical address where the kernel begins. */
-@@ -1349,7 +1348,7 @@ unsigned long __init bootmem_init(unsign
- #ifdef CONFIG_BLK_DEV_INITRD
- 	/* Now have to check initial ramdisk, so that bootmap does not overwrite it */
- 	if (sparc_ramdisk_image) {
--		if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE)
-+		if (sparc_ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE)
- 			sparc_ramdisk_image -= KERNBASE;
- 		initrd_start = sparc_ramdisk_image + phys_base;
- 		initrd_end = initrd_start + sparc_ramdisk_size;
-@@ -1426,7 +1425,7 @@ void __init paging_init(void)
- 
- 	set_bit(0, mmu_context_bmap);
- 
--	real_end = (unsigned long)&_end;
-+	real_end = (unsigned long)_end;
- 	if ((real_end > ((unsigned long)KERNBASE + 0x400000)))
- 		bigkernel = 1;
- #ifdef CONFIG_BLK_DEV_INITRD
-@@ -1718,7 +1717,7 @@ void __init mem_init(void)
- 	memset(sparc64_valid_addr_bitmap, 0, i << 3);
- 
- 	addr = PAGE_OFFSET + phys_base;
--	last = PAGE_ALIGN((unsigned long)&_end) -
-+	last = PAGE_ALIGN((unsigned long)_end) -
- 		((unsigned long) KERNBASE);
- 	last += PAGE_OFFSET + phys_base;
- 	while (addr < last) {
-@@ -1745,11 +1744,11 @@ void __init mem_init(void)
- 	SetPageReserved(mem_map_zero);
- 	clear_page(page_address(mem_map_zero));
- 
--	codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
-+	codepages = (((unsigned long) _etext) - ((unsigned long) _start));
- 	codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
--	datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
-+	datapages = (((unsigned long) _edata) - ((unsigned long) _etext));
- 	datapages = PAGE_ALIGN(datapages) >> PAGE_SHIFT;
--	initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin));
-+	initpages = (((unsigned long) __init_end) - ((unsigned long) __init_begin));
- 	initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
- 
- #ifndef CONFIG_SMP
-@@ -1812,8 +1811,8 @@ void free_initmem (void)
- 	/*
- 	 * The init section is aligned to 8k in vmlinux.lds. Page align for >8k pagesizes.
- 	 */
--	addr = PAGE_ALIGN((unsigned long)(&__init_begin));
--	initend = (unsigned long)(&__init_end) & PAGE_MASK;
-+	addr = PAGE_ALIGN((unsigned long)(__init_begin));
-+	initend = (unsigned long)(__init_end) & PAGE_MASK;
- 	for (; addr < initend; addr += PAGE_SIZE) {
- 		unsigned long page;
- 		struct page *p;
---- linux-2.6.0-test1/arch/sparc64/prom/bootstr.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/sparc64/prom/bootstr.c	2003-07-19 17:03:49.000000000 -0700
-@@ -15,16 +15,22 @@
-  */
- 
- #define BARG_LEN  256
--int bootstr_len = BARG_LEN;
--static int bootstr_valid = 0;
--static char bootstr_buf[BARG_LEN] = { 0 };
-+struct {
-+	int bootstr_len;
-+	int bootstr_valid;
-+	char bootstr_buf[BARG_LEN];
-+} bootstr_info = {
-+	.bootstr_len = BARG_LEN,
-+};
- 
- char * __init
- prom_getbootargs(void)
- {
- 	/* This check saves us from a panic when bootfd patches args. */
--	if (bootstr_valid) return bootstr_buf;
--	prom_getstring(prom_chosen_node, "bootargs", bootstr_buf, BARG_LEN);
--	bootstr_valid = 1;
--	return bootstr_buf;
-+	if (bootstr_info.bootstr_valid)
-+		return bootstr_info.bootstr_buf;
-+	prom_getstring(prom_chosen_node, "bootargs",
-+		       bootstr_info.bootstr_buf, BARG_LEN);
-+	bootstr_info.bootstr_valid = 1;
-+	return bootstr_info.bootstr_buf;
- }
---- linux-2.6.0-test1/arch/sparc/kernel/process.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/sparc/kernel/process.c	2003-07-19 17:03:49.000000000 -0700
-@@ -590,16 +590,20 @@ int dump_fpu (struct pt_regs * regs, elf
- 		put_psr(get_psr() | PSR_EF);
- 		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
- 		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
--		regs->psr &= ~(PSR_EF);
--		current->flags &= ~(PF_USEDFPU);
-+		if (regs != NULL) {
-+			regs->psr &= ~(PSR_EF);
-+			current->flags &= ~(PF_USEDFPU);
-+		}
- 	}
- #else
- 	if (current == last_task_used_math) {
- 		put_psr(get_psr() | PSR_EF);
- 		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
- 		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
--		last_task_used_math = 0;
--		regs->psr &= ~(PSR_EF);
-+		if (regs != NULL) {
-+			regs->psr &= ~(PSR_EF);
-+			last_task_used_math = 0;
-+		}
- 	}
- #endif
- 	memcpy(&fpregs->pr_fr.pr_regs[0],
---- linux-2.6.0-test1/arch/sparc/kernel/setup.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/arch/sparc/kernel/setup.c	2003-07-19 17:03:49.000000000 -0700
-@@ -25,7 +25,6 @@
- #include <linux/kdev_t.h>
- #include <linux/major.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/console.h>
---- linux-2.6.0-test1/arch/sparc/mm/generic.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/sparc/mm/generic.c	2003-07-19 17:07:16.000000000 -0700
-@@ -67,7 +67,7 @@ static inline void io_remap_pte_range(pt
- 	} while (address < end);
- }
- 
--static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size,
-+static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size,
- 	unsigned long offset, pgprot_t prot, int space)
- {
- 	unsigned long end;
-@@ -78,7 +78,7 @@ static inline int io_remap_pmd_range(pmd
- 		end = PGDIR_SIZE;
- 	offset -= address;
- 	do {
--		pte_t * pte = pte_alloc_map(current->mm, pmd, address);
-+		pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address);
- 		if (!pte)
- 			return -ENOMEM;
- 		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
-@@ -103,11 +103,11 @@ int io_remap_page_range(struct vm_area_s
- 
- 	spin_lock(&mm->page_table_lock);
- 	while (from < end) {
--		pmd_t *pmd = pmd_alloc(current->mm, dir, from);
-+		pmd_t *pmd = pmd_alloc_map(current->mm, dir, from);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
--		error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space);
-+		error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space);
- 		if (error)
- 			break;
- 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
---- linux-2.6.0-test1/arch/sparc/mm/srmmu.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/sparc/mm/srmmu.c	2003-07-19 17:07:16.000000000 -0700
-@@ -15,7 +15,6 @@
- #include <linux/vmalloc.h>
- #include <linux/pagemap.h>
- #include <linux/init.h>
--#include <linux/blk.h>
- #include <linux/spinlock.h>
- #include <linux/bootmem.h>
- #include <linux/fs.h>
-@@ -2188,7 +2187,7 @@ void __init ld_mmu_srmmu(void)
- 
- 	BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
--	BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM);
-+	BTFIXUPSET_CALL(__pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM);
- 
- 	BTFIXUPSET_SETHI(none_mask, 0xF0000000);
- 
-@@ -2220,7 +2219,7 @@ void __init ld_mmu_srmmu(void)
- 	BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(free_pmd_fast, srmmu_pmd_free, BTFIXUPCALL_NORM);
--	BTFIXUPSET_CALL(pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM);
-+	BTFIXUPSET_CALL(__pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM);
- 
---- linux-2.6.0-test1/arch/sparc/mm/sun4c.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/arch/sparc/mm/sun4c.c	2003-07-19 17:07:16.000000000 -0700
-@@ -2211,7 +2211,7 @@ void __init ld_mmu_sun4c(void)
- 	BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP);
--	BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0);
-+	BTFIXUPSET_CALL(__pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0);
- 	BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);
- 	BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM);
- 
-@@ -2252,5 +2252,5 @@ void __init ld_mmu_sun4c(void)
- 
- 	/* These should _never_ get called with two level tables. */
- 	BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);
--	BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0);
-+	BTFIXUPSET_CALL(__pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0);
- }
---- linux-2.6.0-test1/arch/um/drivers/ubd_kern.c	2003-06-14 12:18:20.000000000 -0700
-+++ 25/arch/um/drivers/ubd_kern.c	2003-07-19 17:03:49.000000000 -0700
-@@ -15,7 +15,6 @@
- 
- #include "linux/config.h"
- #include "linux/module.h"
--#include "linux/blk.h"
- #include "linux/blkdev.h"
- #include "linux/hdreg.h"
- #include "linux/init.h"
---- linux-2.6.0-test1/arch/um/kernel/irq.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/um/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -565,9 +565,9 @@ static struct proc_dir_entry * smp_affin
- /* These are read and written as longs, so a read won't see a partial write
-  * even during a race.
-  */
--static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-+static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
-@@ -578,10 +578,10 @@ static int irq_affinity_read_proc (char 
- }
- 
- static unsigned int parse_hex_value (const char *buffer,
--		unsigned long count, unsigned long *ret)
-+		unsigned long count, cpumask_t *ret)
- {
- 	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	cpumask_t value = CPU_MASK_NONE;
- 	int i;
- 
- 	if (!count)
-@@ -595,10 +595,9 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
- 
- 	for (i = 0; i < count; i++) {
--		unsigned int c = hexnum[i];
-+		unsigned int k, c = hexnum[i];
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -607,7 +606,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 16);
-+		for (k = 0; k < 4; ++k)
-+			if (c & (1 << k))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -618,7 +620,7 @@ static int irq_affinity_write_proc (stru
- 					unsigned long count, void *data)
- {
- 	int irq = (long) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t new_value, tmp;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -631,7 +633,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- #endif
- 
-@@ -644,17 +647,27 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	cpumask_t tmp, *mask = (cpumask_t *) data;
-+	int k, len = 0;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+	tmp = *mask;
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t *mask = (cpumask_t *)data, new_value;
-+	unsigned long full_count = count, err;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
-@@ -693,7 +706,7 @@ static void register_irq_proc (unsigned 
- }
- 
- /* Read and written as a long */
--unsigned long prof_cpu_mask = -1;
-+cpumask_t prof_cpu_mask = CPU_MASK_ALL;
- 
- void __init init_irq_proc (void)
- {
---- linux-2.6.0-test1/arch/um/kernel/skas/process_kern.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/arch/um/kernel/skas/process_kern.c	2003-07-19 17:04:07.000000000 -0700
-@@ -152,7 +152,7 @@ static int start_kernel_proc(void *unuse
- 	cpu_tasks[0].pid = pid;
- 	cpu_tasks[0].task = current;
- #ifdef CONFIG_SMP
-- 	cpu_online_map = 1;
-+ 	cpu_online_map = cpumask_of_cpu(0);
- #endif
- 	start_kernel();
- 	return(0);
---- linux-2.6.0-test1/arch/um/kernel/smp.c	2003-06-14 12:18:03.000000000 -0700
-+++ 25/arch/um/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -5,9 +5,6 @@
- 
- #include "linux/config.h"
- 
--/* CPU online map, set by smp_boot_cpus */
--unsigned long cpu_online_map = 1;
--
- #ifdef CONFIG_SMP
- 
- #include "linux/sched.h"
-@@ -24,6 +21,9 @@ unsigned long cpu_online_map = 1;
- #include "irq_user.h"
- #include "os.h"
- 
-+/* CPU online map, set by smp_boot_cpus */
-+unsigned long cpu_online_map = cpumask_of_cpu(0);
-+
- /* Per CPU bogomips and other parameters
-  * The only piece used here is the ipi pipe, which is set before SMP is
-  * started and never changed.
-@@ -104,8 +104,8 @@ void smp_send_stop(void)
- 	printk("done\n");
- }
- 
--static unsigned long smp_commenced_mask;
--static volatile unsigned long smp_callin_map = 0;
-+static cpumask_t smp_commenced_mask;
-+static cpumask_t smp_callin_map = CPU_MASK_NONE;
- 
- static int idle_proc(void *cpup)
- {
-@@ -120,15 +120,15 @@ static int idle_proc(void *cpup)
- 		     current->thread.mode.tt.extern_pid);
-  
- 	wmb();
--	if (test_and_set_bit(cpu, &smp_callin_map)) {
-+	if (cpu_test_and_set(cpu, &smp_callin_map)) {
- 		printk("huh, CPU#%d already present??\n", cpu);
- 		BUG();
- 	}
- 
--	while (!test_bit(cpu, &smp_commenced_mask))
-+	while (!cpu_isset(cpu, &smp_commenced_mask))
- 		cpu_relax();
- 
--	set_bit(cpu, &cpu_online_map);
-+	cpu_set(cpu, cpu_online_map);
- 	default_idle();
- 	return(0);
- }
-@@ -159,8 +159,8 @@ void smp_prepare_cpus(unsigned int maxcp
- 	unsigned long waittime;
- 	int err, cpu;
- 
--	set_bit(0, &cpu_online_map);
--	set_bit(0, &smp_callin_map);
-+	cpu_set(0, cpu_online_map);
-+	cpu_set(0, smp_callin_map);
- 
- 	err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
- 	if(err)	panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
-@@ -177,10 +177,10 @@ void smp_prepare_cpus(unsigned int maxcp
- 		unhash_process(idle);
- 
- 		waittime = 200000000;
--		while (waittime-- && !test_bit(cpu, &smp_callin_map))
-+		while (waittime-- && !cpu_isset(cpu, smp_callin_map))
- 			cpu_relax();
- 
--		if (test_bit(cpu, &smp_callin_map))
-+		if (cpu_isset(cpu, smp_callin_map))
- 			printk("done\n");
- 		else printk("failed\n");
- 	}
-@@ -188,13 +188,13 @@ void smp_prepare_cpus(unsigned int maxcp
- 
- void smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- }
- 
- int __cpu_up(unsigned int cpu)
- {
--	set_bit(cpu, &smp_commenced_mask);
--	while (!test_bit(cpu, &cpu_online_map))
-+	cpu_set(cpu, smp_commenced_mask);
-+	while (!cpu_isset(cpu, cpu_online_map))
- 		mb();
- 	return(0);
- }
-@@ -271,7 +271,7 @@ int smp_call_function(void (*_func)(void
- 
- 	for (i=0;i<NR_CPUS;i++)
- 		if((i != current->thread_info->cpu) && 
--		   test_bit(i, &cpu_online_map))
-+		   cpu_isset(i, cpu_online_map))
- 			write(cpu_data[i].ipi_pipe[1], "C", 1);
- 
- 	while (atomic_read(&scf_started) != cpus)
---- linux-2.6.0-test1/arch/um/kernel/tt/process_kern.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/um/kernel/tt/process_kern.c	2003-07-19 17:04:07.000000000 -0700
-@@ -419,7 +419,7 @@ static int start_kernel_proc(void *unuse
- 	cpu_tasks[0].pid = pid;
- 	cpu_tasks[0].task = current;
- #ifdef CONFIG_SMP
-- 	cpu_online_map = 1;
-+ 	cpu_online_map = cpumask_of_cpu(0);
- #endif
- 	if(debug) os_stop_process(pid);
- 	start_kernel();
---- linux-2.6.0-test1/arch/um/kernel/um_arch.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/um/kernel/um_arch.c	2003-07-19 17:04:07.000000000 -0700
-@@ -57,7 +57,7 @@ static int show_cpuinfo(struct seq_file 
- 
- 	index = (struct cpuinfo_um *)v - cpu_data;
- #ifdef CONFIG_SMP
--	if (!(cpu_online_map & (1 << index)))
-+	if (!cpu_online(index))
- 		return 0;
- #endif
- 
---- linux-2.6.0-test1/arch/v850/Kconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/v850/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -48,20 +48,24 @@ menu "Processor type and features"
-    choice
- 	  prompt "Platform"
- 	  default GDB
-+      config V850E_SIM
-+      	     bool "GDB"
-       config RTE_CB_MA1
-       	     bool "RTE-V850E/MA1-CB"
-       config RTE_CB_NB85E
-       	     bool "RTE-V850E/NB85E-CB"
--      config V850E_SIM
--      	     bool "GDB"
-+      config RTE_CB_ME2
-+      	     bool "RTE-V850E/ME2-CB"
-+      config V850E_AS85EP1
-+      	     bool "AS85EP1"
-       config V850E2_SIM85E2C
-       	     bool "sim85e2c"
-+      config V850E2_SIM85E2S
-+      	     bool "sim85e2s"
-       config V850E2_FPGA85E2C
-       	     bool "NA85E2C-FPGA"
-       config V850E2_ANNA
-       	     bool "Anna"
--      config V850E_AS85EP1
--      	     bool "AS85EP1"
-    endchoice
- 
- 
-@@ -78,41 +82,32 @@ menu "Processor type and features"
-    	  bool
- 	  depends RTE_CB_MA1
- 	  default y
--   # Similarly for the RTE-V850E/MA1-CB - V850E/TEG
-+   # Similarly for the RTE-V850E/NB85E-CB - V850E/TEG
-    config V850E_TEG
-    	  bool
- 	  depends RTE_CB_NB85E
- 	  default y
--
--   # NB85E processor core
--   config V850E_NB85E
-+   # ... and the RTE-V850E/ME2-CB - V850E/ME2
-+   config V850E_ME2
-    	  bool
--	  depends V850E_MA1 || V850E_TEG
-+	  depends RTE_CB_ME2
- 	  default y
- 
--   config V850E_MA1_HIGHRES_TIMER
--   	  bool "High resolution timer support"
--  	  depends V850E_MA1
--
- 
--   #### V850E2 processor-specific config
-+   #### sim85e2-specific config
- 
--   # V850E2 processors
--   config V850E2
-+   config V850E2_SIM85E2
-    	  bool
--	  depends V850E2_SIM85E2C || V850E2_FPGA85E2C || V850E2_ANNA
-+	  depends V850E2_SIM85E2C || V850E2_SIM85E2S
- 	  default y
- 
--   # Processors based on the NA85E2A core
--   config V850E2_NA85E2A
--   	  bool
--	  depends V850E2_ANNA
--	  default y
- 
--   # Processors based on the NA85E2C core
--   config V850E2_NA85E2C
-+   #### V850E2 processor-specific config
-+
-+   # V850E2 processors
-+   config V850E2
-    	  bool
--	  depends V850E2_SIM85E2C || V850E2_FPGA85E2C
-+	  depends V850E2_SIM85E2 || V850E2_FPGA85E2C || V850E2_ANNA
- 	  default y
- 
- 
-@@ -121,7 +116,7 @@ menu "Processor type and features"
-    # Boards in the RTE-x-CB series
-    config RTE_CB
-    	  bool
--	  depends RTE_CB_MA1 || RTE_CB_NB85E
-+	  depends RTE_CB_MA1 || RTE_CB_NB85E || RTE_CB_ME2
- 	  default y
- 
-    config RTE_CB_MULTI
-@@ -129,7 +124,7 @@ menu "Processor type and features"
- 	  # RTE_CB_NB85E can either have multi ROM support or not, but
- 	  # other platforms (currently only RTE_CB_MA1) require it.
- 	  prompt "Multi monitor ROM support" if RTE_CB_NB85E
--	  depends RTE_CB
-+	  depends RTE_CB_MA1 || RTE_CB_NB85E
- 	  default y
- 
-    config RTE_CB_MULTI_DBTRAP
-@@ -156,14 +151,42 @@ menu "Processor type and features"
-    # The only PCI bus we support is on the RTE-MOTHER-A board
-    config PCI
-    	  bool
--	  default y if RTE_MB_A_PCI
-+	  default RTE_MB_A_PCI
-+
-+
-+   #### Some feature-specific configs
-+
-+   # Everything except for the GDB simulator uses the same interrupt controller
-+   config V850E_INTC
-+   	  bool
-+	  default !V850E_SIM
-+
-+   # Everything except for the various simulators uses the "Timer D" unit
-+   config V850E_TIMER_D
-+   	  bool
-+	  default !V850E_SIM && !V850E2_SIM85E2
-+
-+   # Cache control used on some v850e1 processors
-+   config V850E_CACHE
-+          bool
-+	  default V850E_TEG || V850E_ME2
-+
-+   # Cache control used on v850e2 processors; I think this should
-+   # actually apply to more, but currently only the SIM85E2S uses it
-+   config V850E2_CACHE
-+   	  bool
-+	  default V850E2_SIM85E2S
-+
-+   config NO_CACHE
-+   	  bool
-+	  default !V850E_CACHE && !V850E2_CACHE
- 
- 
-    #### Misc config
- 
-    config ROM_KERNEL
-    	  bool "Kernel in ROM"
--	  depends V850E2_ANNA || (RTE_CB && !RTE_CB_MULTI)
-+	  depends V850E2_ANNA || V850E_AS85EP1 || RTE_CB_ME2
- 
-    # Some platforms pre-zero memory, in which case the kernel doesn't need to
-    config ZERO_BSS
-@@ -177,9 +200,12 @@ menu "Processor type and features"
-    	  int
- 	  default 8 if V850E2_SIM85E2C || V850E2_FPGA85E2C
- 
-+   config V850E_HIGHRES_TIMER
-+   	  bool "High resolution timer support"
-+	  depends V850E_TIMER_D
-    config TIME_BOOTUP
-    	  bool "Time bootup"
--	  depends V850E_MA1_HIGHRES_TIMER
-+	  depends V850E_HIGHRES_TIMER
- 
-    config RESET_GUARD
-    	  bool "Reset Guard"
-@@ -241,6 +267,7 @@ config KCORE_AOUT
- 	default y
- 
- config KCORE_ELF
-+	bool
- 	default y
- 
- source "fs/Kconfig.binfmt"
---- linux-2.6.0-test1/arch/v850/kernel/anna.c	2003-06-14 12:18:21.000000000 -0700
-+++ 25/arch/v850/kernel/anna.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * arch/v850/kernel/anna.c -- Anna V850E2 evaluation chip/board
-  *
-- *  Copyright (C) 2002  NEC Corporation
-- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -21,8 +21,8 @@
- #include <asm/machdep.h>
- #include <asm/atomic.h>
- #include <asm/page.h>
--#include <asm/nb85e_timer_d.h>
--#include <asm/nb85e_uart.h>
-+#include <asm/v850e_timer_d.h>
-+#include <asm/v850e_uart.h>
- 
- #include "mach.h"
- 
-@@ -41,32 +41,34 @@ static void anna_led_tick (void);
- 
- void __init mach_early_init (void)
- {
--	ANNA_ILBEN  = 0;
--	ANNA_CSC(0) = 0x402F;
--	ANNA_CSC(1) = 0x4000;
--	ANNA_BPC    = 0;
--	ANNA_BSC    = 0xAAAA;
--	ANNA_BEC    = 0;
--	ANNA_BHC    = 0xFFFF;	/* icache all memory, dcache all */
--	ANNA_BCT(0) = 0xB088;
--	ANNA_BCT(1) = 0x0008;
--	ANNA_DWC(0) = 0x0027;
--	ANNA_DWC(1) = 0;
--	ANNA_BCC    = 0x0006;
--	ANNA_ASC    = 0;
--	ANNA_LBS    = 0x0089;
--	ANNA_SCR3   = 0x21A9;
--	ANNA_RFS3   = 0x8121;
-+	ANNA_ILBEN    = 0;
- 
--	nb85e_intc_disable_irqs ();
-+	V850E2_CSC(0) = 0x402F;
-+	V850E2_CSC(1) = 0x4000;
-+	V850E2_BPC    = 0;
-+	V850E2_BSC    = 0xAAAA;
-+	V850E2_BEC    = 0;
-+
-+#if 0
-+	V850E2_BHC    = 0xFFFF;	/* icache all memory, dcache all */
-+#else
-+	V850E2_BHC    = 0;	/* cache no memory */
-+#endif
-+	V850E2_BCT(0) = 0xB088;
-+	V850E2_BCT(1) = 0x0008;
-+	V850E2_DWC(0) = 0x0027;
-+	V850E2_DWC(1) = 0;
-+	V850E2_BCC    = 0x0006;
-+	V850E2_ASC    = 0;
-+	V850E2_LBS    = 0x0089;
-+	V850E2_SCR(3) = 0x21A9;
-+	V850E2_RFS(3) = 0x8121;
-+
-+	v850e_intc_disable_irqs ();
- }
- 
- void __init mach_setup (char **cmdline)
- {
--#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
--	nb85e_uart_cons_init (1);
--#endif
--
- 	ANNA_PORT_PM (LEDS_PORT) = 0;	/* Make all LED pins output pins.  */
- 	mach_tick = anna_led_tick;
- }
-@@ -95,12 +97,12 @@ void mach_gettimeofday (struct timespec 
- void __init mach_sched_init (struct irqaction *timer_action)
- {
- 	/* Start hardware timer.  */
--	nb85e_timer_d_configure (0, HZ);
-+	v850e_timer_d_configure (0, HZ);
- 	/* Install timer interrupt handler.  */
- 	setup_irq (IRQ_INTCMD(0), timer_action);
- }
- 
--static struct nb85e_intc_irq_init irq_inits[] = {
-+static struct v850e_intc_irq_init irq_inits[] = {
- 	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
- 	{ "PIN", IRQ_INTP(0),   IRQ_INTP_NUM,   1, 4 },
- 	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
-@@ -118,7 +120,7 @@ static struct hw_interrupt_type hw_itype
- 
- void __init mach_init_irqs (void)
- {
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- 
- void machine_restart (char *__unused)
---- linux-2.6.0-test1/arch/v850/kernel/as85ep1.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/v850/kernel/as85ep1.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * arch/v850/kernel/as85ep1.c -- AS85EP1 V850E evaluation chip/board
-  *
-- *  Copyright (C) 2002  NEC Corporation
-- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -21,8 +21,8 @@
- #include <asm/machdep.h>
- #include <asm/atomic.h>
- #include <asm/page.h>
--#include <asm/nb85e_timer_d.h>
--#include <asm/nb85e_uart.h>
-+#include <asm/v850e_timer_d.h>
-+#include <asm/v850e_uart.h>
- 
- #include "mach.h"
- 
-@@ -90,20 +90,14 @@ void __init mach_early_init (void)
- 	AS85EP1_IRAMM = 0x0;	/* $BFbB"L?Na(BRAM$B$O!V(Bread-mode$B!W$K$J$j$^$9(B */
- #endif /* !CONFIG_ROM_KERNEL */
- 
--	nb85e_intc_disable_irqs ();
-+	v850e_intc_disable_irqs ();
- }
- 
- void __init mach_setup (char **cmdline)
- {
--#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
--	nb85e_uart_cons_init (1);
--#endif
--
- 	AS85EP1_PORT_PMC (LEDS_PORT) = 0; /* Make the LEDs port an I/O port. */
- 	AS85EP1_PORT_PM (LEDS_PORT) = 0; /* Make all the bits output pins.  */
- 	mach_tick = as85ep1_led_tick;
--
--	ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
- }
- 
- void __init mach_get_physical_ram (unsigned long *ram_start,
-@@ -137,21 +131,21 @@ void __init mach_reserve_bootmem ()
- 				 root_fs_image_end - root_fs_image_start);
- }
- 
--void mach_gettimeofday (struct timeval *tv)
-+void mach_gettimeofday (struct timespec *tv)
- {
- 	tv->tv_sec = 0;
--	tv->tv_usec = 0;
-+	tv->tv_nsec = 0;
- }
- 
- void __init mach_sched_init (struct irqaction *timer_action)
- {
- 	/* Start hardware timer.  */
--	nb85e_timer_d_configure (0, HZ);
-+	v850e_timer_d_configure (0, HZ);
- 	/* Install timer interrupt handler.  */
- 	setup_irq (IRQ_INTCMD(0), timer_action);
- }
- 
--static struct nb85e_intc_irq_init irq_inits[] = {
-+static struct v850e_intc_irq_init irq_inits[] = {
- 	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
- 	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
- 	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
-@@ -166,7 +160,7 @@ static struct hw_interrupt_type hw_itype
- 
- void __init mach_init_irqs (void)
- {
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- 
- void machine_restart (char *__unused)
---- linux-2.6.0-test1/arch/v850/kernel/fpga85e2c.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/arch/v850/kernel/fpga85e2c.c	2003-07-19 17:03:49.000000000 -0700
-@@ -2,8 +2,8 @@
-  * arch/v850/kernel/fpga85e2c.h -- Machine-dependent defs for
-  *	FPGA implementation of V850E2/NA85E2C
-  *
-- *  Copyright (C) 2002  NEC Corporation
-- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -46,7 +46,7 @@ void __init mach_early_init (void)
- 
- 	/* Set bus sizes: CS0 32-bit, CS1 16-bit, CS7 8-bit,
- 	   everything else 32-bit.  */
--	BSC = 0x2AA6;
-+	V850E2_BSC = 0x2AA6;
- 	for (i = 2; i <= 6; i++)
- 		CSDEV(i) = 0;	/* 32 bit */
- 
-@@ -134,7 +134,7 @@ void machine_power_off (void)
- 
- /* Interrupts */
- 
--struct nb85e_intc_irq_init irq_inits[] = {
-+struct v850e_intc_irq_init irq_inits[] = {
- 	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
- 	{ "RPU", IRQ_RPU(0),	IRQ_RPU_NUM,	1, 6 },
- 	{ 0 }
-@@ -146,7 +146,7 @@ struct hw_interrupt_type hw_itypes[NUM_I
- /* Initialize interrupts.  */
- void __init mach_init_irqs (void)
- {
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- 
- 
---- linux-2.6.0-test1/arch/v850/kernel/gbus_int.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/arch/v850/kernel/gbus_int.c	2003-07-19 17:03:49.000000000 -0700
-@@ -113,9 +113,7 @@ static irqreturn_t gbus_int_handle_irq (
- 		/* Only pay attention to enabled interrupts.  */
- 		status &= enable;
- 		if (status) {
--			unsigned base_irq
--				= IRQ_GBUS_INT (w * GBUS_INT_BITS_PER_WORD);
--			irq = base_irq;
-+			irq = IRQ_GBUS_INT (w * GBUS_INT_BITS_PER_WORD);
- 			do {
- 				/* There's an active interrupt in word
- 				   W, find out which one, and call its
-@@ -247,7 +245,7 @@ void __init gbus_int_init_irqs (void)
- 	/* First initialize the shared gint interrupts.  */
- 	for (i = 0; i < NUM_USED_GINTS; i++) {
- 		unsigned gint = used_gint[i].gint;
--		struct nb85e_intc_irq_init gint_irq_init[2];
-+		struct v850e_intc_irq_init gint_irq_init[2];
- 
- 		/* We initialize one GINT interrupt at a time.  */
- 		gint_irq_init[0].name = "GINT";
-@@ -258,7 +256,7 @@ void __init gbus_int_init_irqs (void)
- 
- 		gint_irq_init[1].name = 0; /* Terminate the vector.  */
- 
--		nb85e_intc_init_irq_types (gint_irq_init, gint_hw_itypes);
-+		v850e_intc_init_irq_types (gint_irq_init, gint_hw_itypes);
- 	}
- 
- 	/* Then the GBUS interrupts.  */
---- linux-2.6.0-test1/arch/v850/kernel/head.S	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/v850/kernel/head.S	2003-07-19 17:03:49.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * arch/v850/kernel/head.S -- Lowest-level startup code
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -115,7 +115,14 @@ C_ENTRY(start):
- 	jarl	CSYM(memset), lp
- #endif
- 
--	// Start Linux kernel.
-+	// What happens if the main kernel function returns (it shouldn't)
- 	mov	hilo(CSYM(machine_halt)), lp
--	jr	CSYM(start_kernel)
-+
-+	// Start the linux kernel.  We use an indirect jump to get extra
-+	// range, because on some platforms this initial startup code
-+	// (and the associated platform-specific code in mach_early_init)
-+	// are located far away from the main kernel, e.g. so that they
-+	// can initialize RAM first and copy the kernel or something.
-+	mov	hilo(CSYM(start_kernel)), r12
-+	jmp	[r12]
- C_END(start)
---- linux-2.6.0-test1/arch/v850/kernel/highres_timer.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/arch/v850/kernel/highres_timer.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * arch/v850/kernel/highres_timer.c -- High resolution timing routines
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -12,7 +12,7 @@
-  */
- 
- #include <asm/system.h>
--#include <asm/nb85e_timer_d.h>
-+#include <asm/v850e_timer_d.h>
- #include <asm/highres_timer.h>
- 
- #define HIGHRES_TIMER_USEC_SHIFT   12
-@@ -42,7 +42,7 @@ void highres_timer_slow_tick_irq (void)
- 
- void highres_timer_reset (void)
- {
--	NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT) = 0;
-+	V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT) = 0;
- 	HIGHRES_TIMER_SLOW_TICKS = 0;
- }
- 
-@@ -51,12 +51,12 @@ void highres_timer_start (void)
- 	u32 fast_tick_rate;
- 
- 	/* Start hardware timer.  */
--	nb85e_timer_d_configure (HIGHRES_TIMER_TIMER_D_UNIT,
-+	v850e_timer_d_configure (HIGHRES_TIMER_TIMER_D_UNIT,
- 				 HIGHRES_TIMER_SLOW_TICK_RATE);
- 
- 	fast_tick_rate =
--		(NB85E_TIMER_D_BASE_FREQ
--		 >> NB85E_TIMER_D_DIVLOG2 (HIGHRES_TIMER_TIMER_D_UNIT));
-+		(V850E_TIMER_D_BASE_FREQ
-+		 >> V850E_TIMER_D_DIVLOG2 (HIGHRES_TIMER_TIMER_D_UNIT));
- 
- 	/* The obvious way of calculating microseconds from fast ticks
- 	   is to do:
-@@ -77,16 +77,16 @@ void highres_timer_start (void)
- 
- 	/* Enable the interrupt (which is hardwired to this use), and
- 	   give it the highest priority.  */
--	NB85E_INTC_IC (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)) = 0;
-+	V850E_INTC_IC (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)) = 0;
- }
- 
- void highres_timer_stop (void)
- {
- 	/* Stop the timer.  */
--	NB85E_TIMER_D_TMCD (HIGHRES_TIMER_TIMER_D_UNIT) =
--		NB85E_TIMER_D_TMCD_CAE;
-+	V850E_TIMER_D_TMCD (HIGHRES_TIMER_TIMER_D_UNIT) =
-+		V850E_TIMER_D_TMCD_CAE;
- 	/* Disable its interrupt, just in case.  */
--	nb85e_intc_disable_irq (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT));
-+	v850e_intc_disable_irq (IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT));
- }
- 
- inline void highres_timer_read_ticks (u32 *slow_ticks, u32 *fast_ticks)
-@@ -95,9 +95,9 @@ inline void highres_timer_read_ticks (u3
- 	u32 fast_ticks_1, fast_ticks_2, _slow_ticks;
- 
- 	local_irq_save (flags);
--	fast_ticks_1 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
-+	fast_ticks_1 = V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
- 	_slow_ticks = HIGHRES_TIMER_SLOW_TICKS;
--	fast_ticks_2 = NB85E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
-+	fast_ticks_2 = V850E_TIMER_D_TMD (HIGHRES_TIMER_TIMER_D_UNIT);
- 	local_irq_restore (flags);
- 
- 	if (fast_ticks_2 < fast_ticks_1)
---- linux-2.6.0-test1/arch/v850/kernel/intv.S	2003-06-14 12:18:22.000000000 -0700
-+++ 25/arch/v850/kernel/intv.S	2003-07-19 17:03:49.000000000 -0700
-@@ -16,7 +16,7 @@
- #include <asm/machdep.h>
- #include <asm/entry.h>
- 
--#ifdef CONFIG_V850E_MA1_HIGHRES_TIMER
-+#ifdef CONFIG_V850E_HIGHRES_TIMER
- #include <asm/highres_timer.h>
- #endif
- 
-@@ -59,7 +59,7 @@
- 	.section	.intv.mach, "ax"
- 	.org	0x0
- 
--#if defined (CONFIG_V850E_MA1_HIGHRES_TIMER) && defined (IRQ_INTCMD)
-+#if defined (CONFIG_V850E_HIGHRES_TIMER) && defined (IRQ_INTCMD)
- 
- 	/* Interrupts before the highres timer interrupt.  */
- 	.rept	IRQ_INTCMD (HIGHRES_TIMER_TIMER_D_UNIT)
---- linux-2.6.0-test1/arch/v850/kernel/ma.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/arch/v850/kernel/ma.c	2003-07-19 17:03:49.000000000 -0700
-@@ -22,19 +22,19 @@
- #include <asm/atomic.h>
- #include <asm/page.h>
- #include <asm/machdep.h>
--#include <asm/nb85e_timer_d.h>
-+#include <asm/v850e_timer_d.h>
- 
- #include "mach.h"
- 
- void __init mach_sched_init (struct irqaction *timer_action)
- {
- 	/* Start hardware timer.  */
--	nb85e_timer_d_configure (0, HZ);
-+	v850e_timer_d_configure (0, HZ);
- 	/* Install timer interrupt handler.  */
- 	setup_irq (IRQ_INTCMD(0), timer_action);
- }
- 
--static struct nb85e_intc_irq_init irq_inits[] = {
-+static struct v850e_intc_irq_init irq_inits[] = {
- 	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
- 	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
- 	{ "DMA", IRQ_INTDMA(0), IRQ_INTDMA_NUM,	1, 2 },
-@@ -51,7 +51,7 @@ static struct hw_interrupt_type hw_itype
- /* Initialize MA chip interrupts.  */
- void __init ma_init_irqs (void)
- {
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- 
- /* Called before configuring an on-chip UART.  */
---- linux-2.6.0-test1/arch/v850/kernel/Makefile	2003-06-14 12:18:51.000000000 -0700
-+++ 25/arch/v850/kernel/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -15,24 +15,26 @@ obj-y += intv.o entry.o process.o syscal
- 	 signal.o irq.o mach.o ptrace.o bug.o
- obj-$(CONFIG_MODULES)		+= module.o v850_ksyms.o
- # chip-specific code
--obj-$(CONFIG_V850E_NB85E)	+= nb85e_intc.o
--obj-$(CONFIG_V850E_MA1)		+= ma.o nb85e_utils.o nb85e_timer_d.o
--obj-$(CONFIG_V850E_TEG)		+= teg.o nb85e_utils.o nb85e_cache.o \
--				   nb85e_timer_d.o
--obj-$(CONFIG_V850E2_ANNA)	+= anna.o nb85e_intc.o nb85e_utils.o \
--				   nb85e_timer_d.o
--obj-$(CONFIG_V850E_AS85EP1)	+= as85ep1.o nb85e_intc.o nb85e_utils.o \
--				   nb85e_timer_d.o
-+obj-$(CONFIG_V850E_MA1)		+= ma.o
-+obj-$(CONFIG_V850E_ME2)		+= me2.o
-+obj-$(CONFIG_V850E_TEG)		+= teg.o
-+obj-$(CONFIG_V850E_AS85EP1)	+= as85ep1.o
-+obj-$(CONFIG_V850E2_ANNA)	+= anna.o
- # platform-specific code
- obj-$(CONFIG_V850E_SIM)		+= sim.o simcons.o
--obj-$(CONFIG_V850E2_SIM85E2C)	+= sim85e2c.o nb85e_intc.o memcons.o
--obj-$(CONFIG_V850E2_FPGA85E2C)	+= fpga85e2c.o nb85e_intc.o memcons.o
-+obj-$(CONFIG_V850E2_SIM85E2)	+= sim85e2.o memcons.o
-+obj-$(CONFIG_V850E2_FPGA85E2C)	+= fpga85e2c.o memcons.o
- obj-$(CONFIG_RTE_CB)		+= rte_cb.o rte_cb_leds.o
- obj-$(CONFIG_RTE_CB_MA1)	+= rte_ma1_cb.o
-+obj-$(CONFIG_RTE_CB_ME2)	+= rte_me2_cb.o
- obj-$(CONFIG_RTE_CB_NB85E)	+= rte_nb85e_cb.o
- obj-$(CONFIG_RTE_CB_MULTI)	+= rte_cb_multi.o
- obj-$(CONFIG_RTE_MB_A_PCI)	+= rte_mb_a_pci.o
- obj-$(CONFIG_RTE_GBUS_INT)	+= gbus_int.o
- # feature-specific code
--obj-$(CONFIG_V850E_MA1_HIGHRES_TIMER)	+= highres_timer.o
-+obj-$(CONFIG_V850E_INTC)	+= v850e_intc.o
-+obj-$(CONFIG_V850E_TIMER_D)	+= v850e_timer_d.o v850e_utils.o
-+obj-$(CONFIG_V850E_CACHE)	+= v850e_cache.o
-+obj-$(CONFIG_V850E2_CACHE)	+= v850e2_cache.o
-+obj-$(CONFIG_V850E_HIGHRES_TIMER) += highres_timer.o
- obj-$(CONFIG_PROC_FS)		+= procfs.o
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/me2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,74 @@
-+/*
-+ * arch/v850/kernel/me2.c -- V850E/ME2 chip-specific support
-+ *
-+ *  Copyright (C) 2003  NEC Corporation
-+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mm.h>
-+#include <linux/swap.h>
-+#include <linux/bootmem.h>
-+#include <linux/irq.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/page.h>
-+#include <asm/machdep.h>
-+#include <asm/v850e_timer_d.h>
-+
-+#include "mach.h"
-+
-+void __init mach_sched_init (struct irqaction *timer_action)
-+{
-+	/* Start hardware timer.  */
-+	v850e_timer_d_configure (0, HZ);
-+	/* Install timer interrupt handler.  */
-+	setup_irq (IRQ_INTCMD(0), timer_action);
-+}
-+
-+static struct v850e_intc_irq_init irq_inits[] = {
-+	{ "IRQ",    0,                NUM_CPU_IRQS,      1, 7 },
-+	{ "INTP",   IRQ_INTP(0),      IRQ_INTP_NUM,      1, 5 },
-+	{ "CMD",    IRQ_INTCMD(0),    IRQ_INTCMD_NUM,    1, 3 },
-+	{ "UBTIRE", IRQ_INTUBTIRE(0), IRQ_INTUBTIRE_NUM, 5, 4 },
-+	{ "UBTIR",  IRQ_INTUBTIR(0),  IRQ_INTUBTIR_NUM,  5, 4 },
-+	{ "UBTIT",  IRQ_INTUBTIT(0),  IRQ_INTUBTIT_NUM,  5, 4 },
-+	{ "UBTIF",  IRQ_INTUBTIF(0),  IRQ_INTUBTIF_NUM,  5, 4 },
-+	{ "UBTITO", IRQ_INTUBTITO(0), IRQ_INTUBTITO_NUM, 5, 4 },
-+	{ 0 }
-+};
-+#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
-+
-+static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
-+
-+/* Initialize V850E/ME2 chip interrupts.  */
-+void __init me2_init_irqs (void)
-+{
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
-+}
-+
-+/* Called before configuring an on-chip UART.  */
-+void me2_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
-+{
-+	if (chan == 0) {
-+		/* Specify that the relevent pins on the chip should do
-+		   serial I/O, not direct I/O.  */
-+		ME2_PORT1_PMC |= 0xC;
-+		/* Specify that we're using the UART, not the CSI device. */
-+		ME2_PORT1_PFC |= 0xC;
-+	} else if (chan == 1) {
-+		/* Specify that the relevent pins on the chip should do
-+		   serial I/O, not direct I/O.  */
-+		ME2_PORT2_PMC |= 0x6;
-+		/* Specify that we're using the UART, not the CSI device. */
-+		ME2_PORT2_PFC |= 0x6;
-+	}
-+}
---- linux-2.6.0-test1/arch/v850/kernel/nb85e_cache.c	2003-06-14 12:18:25.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,178 +0,0 @@
--/*
-- * arch/v850/kernel/nb85e_cache.c -- Cache control for NB85E_CACHE212 and
-- * 	NB85E_CACHE213 cache memories
-- *
-- *  Copyright (C) 2003  NEC Electronics Corporation
-- *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#include <asm/entry.h>
--#include <asm/nb85e_cache.h>
--
--#define WAIT_UNTIL_CLEAR(value) while (value) {}
--
--/* Set caching params via the BHC and DCC registers.  */
--void nb85e_cache_enable (u16 bhc, u16 dcc)
--{
--	unsigned long *r0_ram = (unsigned long *)R0_RAM_ADDR;
--	register u16 bhc_val asm ("r6") = bhc;
--
--	/* Configure data-cache.  */
--	NB85E_CACHE_DCC = dcc;
--
--	/* Configure caching for various memory regions by writing the BHC
--	   register.  The documentation says that an instruction _cannot_
--	   enable/disable caching for the memory region in which the
--	   instruction itself exists; to work around this, we store
--	   appropriate instructions into the on-chip RAM area (which is never
--	   cached), and briefly jump there to do the work.  */
--	r0_ram[0] = 0xf0720760;	/* st.h r0, 0xfffff072[r0] */
--	r0_ram[1] = 0xf06a3760;	/* st.h r6, 0xfffff06a[r0] */
--	r0_ram[2] = 0x5640006b;	/* jmp [r11] */
--	asm ("mov hilo(1f), r11; jmp [%1]; 1:;"
--	     :: "r" (bhc_val), "r" (R0_RAM_ADDR) : "r11");
--}
--
--static void clear_icache (void)
--{
--	/* 1. Read the instruction cache control register (ICC) and confirm
--	      that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_ICC & 0x3);
--
--	/* 2. Read the ICC register and confirm that bit 12 (LOCK0) is
--  	      cleared.  Bit 13 of the ICC register is always cleared.  */
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_ICC & 0x1000);
--
--	/* 3. Set the TCLR0 and TCLR1 bits of the ICC register as follows,
--	      when clearing way 0 and way 1 at the same time:
--	        (a) Set the TCLR0 and TCLR1 bits.
--		(b) Read the TCLR0 and TCLR1 bits to confirm that these bits
--		    are cleared.
--		(c) Perform (a) and (b) above again.  */
--	NB85E_CACHE_ICC |= 0x3;
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_ICC & 0x3);
--	/* Do it again.  */
--	NB85E_CACHE_ICC |= 0x3;
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_ICC & 0x3);
--}
--
--/* Flush or clear (or both) the data cache, depending on the value of FLAGS;
--   the procedure is the same for both, just the control bits used differ (and
--   both may be performed simultaneously).  */
--static void dcache_op (unsigned short flags)
--{
--	/* 1. Read the data cache control register (DCC) and confirm that bits
--	      0, 1, 4, and 5 (DC00, DC01, DC04, DC05) are all cleared.  */
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_DCC & 0x33);
--
--	/* 2. Clear DCC register bit 12 (DC12), bit 13 (DC13), or both
--	      depending on the way for which tags are to be cleared.  */
--	NB85E_CACHE_DCC &= ~0xC000;
--
--	/* 3. Set DCC register bit 0 (DC00), bit 1 (DC01) or both depending on
--	      the way for which tags are to be cleared.
--	      ...
--	      Set DCC register bit 4 (DC04), bit 5 (DC05), or both depending
--	      on the way to be data flushed.  */
--	NB85E_CACHE_DCC |= flags;
--
--	/* 4. Read DCC register bit DC00, DC01 [DC04, DC05], or both depending
--	      on the way for which tags were cleared [flushed] and confirm
--	      that that bit is cleared.  */
--	WAIT_UNTIL_CLEAR (NB85E_CACHE_DCC & flags);
--}
--
--/* Flushes the contents of the dcache to memory.  */
--static inline void flush_dcache (void)
--{
--	/* We only need to do something if in write-back mode.  */
--	if (NB85E_CACHE_DCC & 0x0400)
--		dcache_op (0x30);
--}
--
--/* Flushes the contents of the dcache to memory, and then clears it.  */
--static inline void clear_dcache (void)
--{
--	/* We only need to do something if the dcache is enabled.  */
--	if (NB85E_CACHE_DCC & 0x0C00)
--		dcache_op (0x33);
--}
--
--/* Clears the dcache without flushing to memory first.  */
--static inline void clear_dcache_no_flush (void)
--{
--	/* We only need to do something if the dcache is enabled.  */
--	if (NB85E_CACHE_DCC & 0x0C00)
--		dcache_op (0x3);
--}
--
--static inline void cache_exec_after_store (void)
--{
--	flush_dcache ();
--	clear_icache ();
--}
--
--
--/* Exported functions.  */
--
--void inline nb85e_cache_flush_all (void)
--{
--	clear_icache ();
--	clear_dcache ();
--}
--
--void nb85e_cache_flush_mm (struct mm_struct *mm)
--{
--	/* nothing */
--}
--
--void nb85e_cache_flush_range (struct mm_struct *mm,
--			      unsigned long start, unsigned long end)
--{
--	/* nothing */
--}
--
--void nb85e_cache_flush_page (struct vm_area_struct *vma,
--			     unsigned long page_addr)
--{
--	/* nothing */
--}
--
--void nb85e_cache_flush_dcache_page (struct page *page)
--{
--	/* nothing */
--}
--
--void nb85e_cache_flush_icache (void)
--{
--	cache_exec_after_store ();
--}
--
--void nb85e_cache_flush_icache_range (unsigned long start, unsigned long end)
--{
--	cache_exec_after_store ();
--}
--
--void nb85e_cache_flush_icache_page (struct vm_area_struct *vma,
--				    struct page *page)
--{
--	cache_exec_after_store ();
--}
--
--void nb85e_cache_flush_icache_user_range (struct vm_area_struct *vma,
--					  struct page *page,
--					  unsigned long adr, int len)
--{
--	cache_exec_after_store ();
--}
--
--void nb85e_cache_flush_sigtramp (unsigned long addr)
--{
--	cache_exec_after_store ();
--}
---- linux-2.6.0-test1/arch/v850/kernel/nb85e_intc.c	2003-06-14 12:18:06.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,104 +0,0 @@
--/*
-- * arch/v850/kernel/nb85e_intc.c -- NB85E cpu core interrupt controller (INTC)
-- *
-- *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/irq.h>
--
--#include <asm/nb85e_intc.h>
--
--static void irq_nop (unsigned irq) { }
--
--static unsigned nb85e_intc_irq_startup (unsigned irq)
--{
--	nb85e_intc_clear_pending_irq (irq);
--	nb85e_intc_enable_irq (irq);
--	return 0;
--}
--
--static void nb85e_intc_end_irq (unsigned irq)
--{
--	unsigned long psw, temp;
--
--	/* Clear the highest-level bit in the In-service priority register
--	   (ISPR), to allow this interrupt (or another of the same or
--	   lesser priority) to happen again.
--
--	   The `reti' instruction normally does this automatically when the
--	   PSW bits EP and NP are zero, but we can't always rely on reti
--	   being used consistently to return after an interrupt (another
--	   process can be scheduled, for instance, which can delay the
--	   associated reti for a long time, or this process may be being
--	   single-stepped, which uses the `dbret' instruction to return
--	   from the kernel).
--
--	   We also set the PSW EP bit, which prevents reti from also
--	   trying to modify the ISPR itself.  */
--
--	/* Get PSW and disable interrupts.  */
--	asm volatile ("stsr psw, %0; di" : "=r" (psw));
--	/* We don't want to do anything for NMIs (they don't use the ISPR).  */
--	if (! (psw & 0xC0)) {
--		/* Transition to `trap' state, so that an eventual real
--		   reti instruction won't modify the ISPR.  */
--		psw |= 0x40;
--		/* Fake an interrupt return, which automatically clears the
--		   appropriate bit in the ISPR.  */
--		asm volatile ("mov hilo(1f), %0;"
--			      "ldsr %0, eipc; ldsr %1, eipsw;"
--			      "reti;"
--			      "1:"
--			      : "=&r" (temp) : "r" (psw));
--	}
--}
--
--/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
--   INITS (which is terminated by an entry with the name field == 0).  */
--void __init nb85e_intc_init_irq_types (struct nb85e_intc_irq_init *inits,
--				       struct hw_interrupt_type *hw_irq_types)
--{
--	struct nb85e_intc_irq_init *init;
--	for (init = inits; init->name; init++) {
--		unsigned i;
--		struct hw_interrupt_type *hwit = hw_irq_types++;
--
--		hwit->typename = init->name;
--
--		hwit->startup  = nb85e_intc_irq_startup;
--		hwit->shutdown = nb85e_intc_disable_irq;
--		hwit->enable   = nb85e_intc_enable_irq;
--		hwit->disable  = nb85e_intc_disable_irq;
--		hwit->ack      = irq_nop;
--		hwit->end      = nb85e_intc_end_irq;
--		
--		/* Initialize kernel IRQ infrastructure for this interrupt.  */
--		init_irq_handlers(init->base, init->num, init->interval, hwit);
--
--		/* Set the interrupt priorities.  */
--		for (i = 0; i < init->num; i++) {
--			unsigned irq = init->base + i * init->interval;
--
--			/* If the interrupt is currently enabled (all
--			   interrupts are initially disabled), then
--			   assume whoever enabled it has set things up
--			   properly, and avoid messing with it.  */
--			if (! nb85e_intc_irq_enabled (irq))
--				/* This write also (1) disables the
--				   interrupt, and (2) clears any pending
--				   interrupts.  */
--				NB85E_INTC_IC (irq)
--					= (NB85E_INTC_IC_PR (init->priority)
--					   | NB85E_INTC_IC_MK);
--		}
--	}
--}
---- linux-2.6.0-test1/arch/v850/kernel/nb85e_timer_d.c	2003-06-14 12:18:21.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,54 +0,0 @@
--/*
-- * include/asm-v850/nb85e_timer_d.c -- `Timer D' component often used
-- *	with the NB85E cpu core
-- *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#include <linux/kernel.h>
--
--#include <asm/nb85e_utils.h>
--#include <asm/nb85e_timer_d.h>
--
--/* Start interval timer TIMER (0-3).  The timer will issue the
--   corresponding INTCMD interrupt RATE times per second.
--   This function does not enable the interrupt.  */
--void nb85e_timer_d_configure (unsigned timer, unsigned rate)
--{
--	unsigned divlog2, count;
--
--	/* Calculate params for timer.  */
--	if (! calc_counter_params (
--		    NB85E_TIMER_D_BASE_FREQ, rate,
--		    NB85E_TIMER_D_TMCD_CS_MIN, NB85E_TIMER_D_TMCD_CS_MAX, 16,
--		    &divlog2, &count))
--		printk (KERN_WARNING
--			"Cannot find interval timer %d setting suitable"
--			" for rate of %dHz.\n"
--			"Using rate of %dHz instead.\n",
--			timer, rate,
--			(NB85E_TIMER_D_BASE_FREQ >> divlog2) >> 16);
--
--	/* Do the actual hardware timer initialization:  */
--
--	/* Enable timer.  */
--	NB85E_TIMER_D_TMCD(timer) = NB85E_TIMER_D_TMCD_CAE;
--	/* Set clock divider.  */
--	NB85E_TIMER_D_TMCD(timer)
--		= NB85E_TIMER_D_TMCD_CAE
--		| NB85E_TIMER_D_TMCD_CS(divlog2);
--	/* Set timer compare register.  */
--	NB85E_TIMER_D_CMD(timer) = count;
--	/* Start counting.  */
--	NB85E_TIMER_D_TMCD(timer)
--		= NB85E_TIMER_D_TMCD_CAE
--		| NB85E_TIMER_D_TMCD_CS(divlog2)
--		| NB85E_TIMER_D_TMCD_CE;
--}
---- linux-2.6.0-test1/arch/v850/kernel/nb85e_utils.c	2003-06-14 12:17:59.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,65 +0,0 @@
--/*
-- * include/asm-v850/nb85e_utils.h -- Utility functions associated with
-- *	the NB85E cpu core
-- *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--/* Note: these functions are often associated with the N85E cpu core,
--   but not always, which is why they're not in `nb85e.c'.  */
--
--#include <asm/nb85e_utils.h>
--
--/* Calculate counter clock-divider and count values to attain the
--   desired frequency RATE from the base frequency BASE_FREQ.  The
--   counter is expected to have a clock-divider, which can divide the
--   system cpu clock by a power of two value from MIN_DIVLOG2 to
--   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
--   counts up and resets whenever it's equal to the compare register,
--   generating an interrupt or whatever when it does so).  The returned
--   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
--   -- the counter compare value to use.  Returns true if it was possible
--   to find a reasonable value, otherwise false (and the other return
--   values will be set to be as good as possible).  */
--int calc_counter_params (unsigned long base_freq,
--			 unsigned long rate,
--			 unsigned min_divlog2, unsigned max_divlog2,
--			 unsigned counter_size,
--			 unsigned *divlog2, unsigned *count)
--{
--	unsigned _divlog2;
--	int ok = 0;
--
--	/* Find the lowest clock divider setting that can represent RATE.  */
--	for (_divlog2 = min_divlog2; _divlog2 <= max_divlog2; _divlog2++) {
--		/* Minimum interrupt rate possible using this divider.  */
--		unsigned min_int_rate
--			= (base_freq >> _divlog2) >> counter_size;
--
--		if (min_int_rate <= rate) {
--			/* This setting is the highest resolution
--			   setting that's slow enough enough to attain
--			   RATE interrupts per second, so use it.  */
--			ok = 1;
--			break;
--		}
--	}
--
--	if (_divlog2 > max_divlog2)
--		/* Can't find correct setting.  */
--		_divlog2 = max_divlog2;
--
--	if (divlog2)
--		*divlog2 = _divlog2;
--	if (count)
--		*count = ((base_freq >> _divlog2) + rate/2) / rate;
--
--	return ok;
--}
---- linux-2.6.0-test1/arch/v850/kernel/rte_cb.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/arch/v850/kernel/rte_cb.c	2003-07-19 17:03:49.000000000 -0700
-@@ -17,7 +17,7 @@
- #include <linux/fs.h>
- 
- #include <asm/machdep.h>
--#include <asm/nb85e_uart.h>
-+#include <asm/v850e_uart.h>
- 
- #include "mach.h"
- 
-@@ -34,7 +34,7 @@ extern void multi_init (void);
- 
- void __init rte_cb_early_init (void)
- {
--	nb85e_intc_disable_irqs ();
-+	v850e_intc_disable_irqs ();
- 
- #ifdef CONFIG_RTE_CB_MULTI
- 	multi_init ();
-@@ -43,6 +43,7 @@ void __init rte_cb_early_init (void)
- 
- void __init mach_setup (char **cmdline)
- {
-+#ifdef CONFIG_RTE_MB_A_PCI
- 	/* Probe for Mother-A, and print a message if we find it.  */
- 	*(volatile unsigned long *)MB_A_SRAM_ADDR = 0xDEADBEEF;
- 	if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0xDEADBEEF) {
-@@ -52,23 +53,11 @@ void __init mach_setup (char **cmdline)
- 				"          NEC SolutionGear/Midas lab"
- 				" RTE-MOTHER-A motherboard\n");
- 	}
--
--#if defined (CONFIG_V850E_NB85E_UART_CONSOLE) && !defined (CONFIG_TIME_BOOTUP)
--	nb85e_uart_cons_init (0);
--#endif
-+#endif /* CONFIG_RTE_MB_A_PCI */
- 
- 	mach_tick = led_tick;
- }
- 
--#ifdef CONFIG_TIME_BOOTUP
--void initial_boot_done (void)
--{
--#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
--	nb85e_uart_cons_init (0);
--#endif
--}
--#endif
--
- void machine_restart (char *__unused)
- {
- #ifdef CONFIG_RESET_GUARD
-@@ -194,6 +183,7 @@ static struct hw_interrupt_type gbus_hw_
- 
- #endif /* CONFIG_RTE_GBUS_INT */
- 
-+
- void __init rte_cb_init_irqs (void)
- {
- #ifdef CONFIG_RTE_GBUS_INT
---- linux-2.6.0-test1/arch/v850/kernel/rte_ma1_cb.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/v850/kernel/rte_ma1_cb.c	2003-07-19 17:03:49.000000000 -0700
-@@ -20,7 +20,7 @@
- #include <asm/page.h>
- #include <asm/ma1.h>
- #include <asm/rte_ma1_cb.h>
--#include <asm/nb85e_timer_c.h>
-+#include <asm/v850e_timer_c.h>
- 
- #include "mach.h"
- 
-@@ -89,14 +89,14 @@ void __init mach_init_irqs (void)
- 	rte_cb_init_irqs ();
- 
- 	/* Use falling-edge-sensitivity for interrupts .  */
--	NB85E_TIMER_C_SESC (0) &= ~0xC;
--	NB85E_TIMER_C_SESC (1) &= ~0xF;
-+	V850E_TIMER_C_SESC (0) &= ~0xC;
-+	V850E_TIMER_C_SESC (1) &= ~0xF;
- 
- 	/* INTP000-INTP011 are shared with `Timer C', so we have to set
- 	   up Timer C to pass them through as raw interrupts.  */
- 	for (tc = 0; tc < 2; tc++)
- 		/* Turn on the timer.  */
--		NB85E_TIMER_C_TMCC0 (tc) |= NB85E_TIMER_C_TMCC0_CAE;
-+		V850E_TIMER_C_TMCC0 (tc) |= V850E_TIMER_C_TMCC0_CAE;
- 
- 	/* Make sure the relevant port0/port1 pins are assigned
- 	   interrupt duty.  We used INTP001-INTP011 (don't screw with
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/rte_me2_cb.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,308 @@
-+/*
-+ * arch/v850/kernel/rte_me2_cb.c -- Midas labs RTE-V850E/ME2-CB board
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/bootmem.h>
-+#include <linux/irq.h>
-+#include <linux/fs.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/page.h>
-+#include <asm/me2.h>
-+#include <asm/rte_me2_cb.h>
-+#include <asm/machdep.h>
-+#include <asm/v850e_intc.h>
-+#include <asm/v850e_cache.h>
-+#include <asm/irq.h>
-+
-+#include "mach.h"
-+
-+extern unsigned long *_intv_start;
-+extern unsigned long *_intv_end;
-+
-+/* LED access routines.  */
-+extern unsigned read_leds (int pos, char *buf, int len);
-+extern unsigned write_leds (int pos, const char *buf, int len);
-+
-+
-+/* SDRAM are almost contiguous (with a small hole in between;
-+   see mach_reserve_bootmem for details), so just use both as one big area.  */
-+#define RAM_START 	SDRAM_ADDR
-+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
-+
-+
-+void __init mach_get_physical_ram (unsigned long *ram_start,
-+				   unsigned long *ram_len)
-+{
-+	*ram_start = RAM_START;
-+	*ram_len = RAM_END - RAM_START;
-+}
-+
-+void __init mach_reserve_bootmem ()
-+{
-+	extern char _root_fs_image_start, _root_fs_image_end;
-+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
-+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
-+
-+	/* Reserve the memory used by the root filesystem image if it's
-+	   in RAM.  */
-+	if (root_fs_image_start >= RAM_START && root_fs_image_start < RAM_END)
-+		reserve_bootmem (root_fs_image_start,
-+				 root_fs_image_end - root_fs_image_start);
-+}
-+
-+void mach_gettimeofday (struct timespec *tv)
-+{
-+	tv->tv_sec = 0;
-+	tv->tv_nsec = 0;
-+}
-+
-+/* Called before configuring an on-chip UART.  */
-+void rte_me2_cb_uart_pre_configure (unsigned chan,
-+				    unsigned cflags, unsigned baud)
-+{
-+	/* The RTE-V850E/ME2-CB connects some general-purpose I/O
-+	   pins on the CPU to the RTS/CTS lines of UARTB channel 0's
-+	   serial connection.
-+	   I/O pins P21 and P22 are RTS and CTS respectively.  */
-+	if (chan == 0) {
-+		/* Put P21 & P22 in I/O port mode.  */
-+		ME2_PORT2_PMC &= ~0x6;
-+		/* Make P21 and output, and P22 an input.  */
-+		ME2_PORT2_PM = (ME2_PORT2_PM & ~0xC) | 0x4;
-+	}
-+
-+	me2_uart_pre_configure (chan, cflags, baud);
-+}
-+
-+void __init mach_init_irqs (void)
-+{
-+	/* Initialize interrupts.  */
-+	me2_init_irqs ();
-+	rte_me2_cb_init_irqs ();
-+}
-+
-+#ifdef CONFIG_ROM_KERNEL
-+/* Initialization for kernel in ROM.  */
-+static inline rom_kernel_init (void)
-+{
-+	/* If the kernel is in ROM, we have to copy any initialized data
-+	   from ROM into RAM.  */
-+	extern unsigned long _data_load_start, _sdata, _edata;
-+	register unsigned long *src = &_data_load_start;
-+	register unsigned long *dst = &_sdata, *end = &_edata;
-+
-+	while (dst != end)
-+		*dst++ = *src++;
-+}
-+#endif /* CONFIG_ROM_KERNEL */
-+
-+static void install_interrupt_vectors (void)
-+{
-+	unsigned long *p1, *p2;
-+
-+	ME2_IRAMM = 0x03; /* V850E/ME2 iRAM write mode */
-+
-+	/* vector copy to iRAM */
-+	p1 = (unsigned long *)0; /* v85x vector start */
-+	p2 = (unsigned long *)&_intv_start;
-+	while (p2 < (unsigned long *)&_intv_end)
-+		*p1++ = *p2++;
-+
-+	ME2_IRAMM = 0x00; /* V850E/ME2 iRAM read mode */
-+}
-+
-+/* CompactFlash */
-+
-+static void cf_power_on (void)
-+{
-+	/* CF card detected? */
-+	if (CB_CF_STS0 & 0x0030)
-+		return;
-+
-+	CB_CF_REG0 = 0x0002; /* reest on */
-+	mdelay (10);
-+	CB_CF_REG0 = 0x0003; /* power on */
-+	mdelay (10);
-+	CB_CF_REG0 = 0x0001; /* reset off */
-+	mdelay (10);
-+}
-+
-+static void cf_power_off (void)
-+{
-+	CB_CF_REG0 = 0x0003; /* power on */
-+	mdelay (10);
-+	CB_CF_REG0 = 0x0002; /* reest on */
-+	mdelay (10);
-+}
-+
-+void __init mach_early_init (void)
-+{
-+	install_interrupt_vectors ();
-+
-+	/* CS1 SDRAM instruction cache enable */
-+	v850e_cache_enable (0x04, 0x03, 0);
-+
-+	rte_cb_early_init ();
-+
-+	/* CompactFlash power on */
-+	cf_power_on ();
-+
-+#if defined (CONFIG_ROM_KERNEL)
-+	rom_kernel_init ();
-+#endif
-+}
-+
-+
-+/* RTE-V850E/ME2-CB Programmable Interrupt Controller.  */
-+
-+static struct cb_pic_irq_init cb_pic_irq_inits[] = {
-+	{ "CB_EXTTM0",       IRQ_CB_EXTTM0,       1, 1, 6 },
-+	{ "CB_EXTSIO",       IRQ_CB_EXTSIO,       1, 1, 6 },
-+	{ "CB_TOVER",        IRQ_CB_TOVER,        1, 1, 6 },
-+	{ "CB_GINT0",        IRQ_CB_GINT0,        1, 1, 6 },
-+	{ "CB_USB",          IRQ_CB_USB,          1, 1, 6 },
-+	{ "CB_LANC",         IRQ_CB_LANC,         1, 1, 6 },
-+	{ "CB_USB_VBUS_ON",  IRQ_CB_USB_VBUS_ON,  1, 1, 6 },
-+	{ "CB_USB_VBUS_OFF", IRQ_CB_USB_VBUS_OFF, 1, 1, 6 },
-+	{ "CB_EXTTM1",       IRQ_CB_EXTTM1,       1, 1, 6 },
-+	{ "CB_EXTTM2",       IRQ_CB_EXTTM2,       1, 1, 6 },
-+	{ 0 }
-+};
-+#define NUM_CB_PIC_IRQ_INITS  \
-+   ((sizeof cb_pic_irq_inits / sizeof cb_pic_irq_inits[0]) - 1)
-+
-+static struct hw_interrupt_type cb_pic_hw_itypes[NUM_CB_PIC_IRQ_INITS];
-+static unsigned char cb_pic_active_irqs = 0;
-+
-+void __init rte_me2_cb_init_irqs (void)
-+{
-+	cb_pic_init_irq_types (cb_pic_irq_inits, cb_pic_hw_itypes);
-+
-+	/* Initalize on board PIC1 (not PIC0) enable */
-+	CB_PIC_INT0M  = 0x0000;
-+	CB_PIC_INT1M  = 0x0000;
-+	CB_PIC_INTR   = 0x0000;
-+	CB_PIC_INTEN |= CB_PIC_INT1EN;
-+
-+	ME2_PORT2_PMC 	 |= 0x08;	/* INTP23/SCK1 mode */
-+	ME2_PORT2_PFC 	 &= ~0x08;	/* INTP23 mode */
-+	ME2_INTR(2) 	 &= ~0x08;	/* INTP23 falling-edge detect */
-+	ME2_INTF(2) 	 &= ~0x08;	/*   " */
-+
-+	rte_cb_init_irqs ();	/* gbus &c */
-+}
-+
-+
-+/* Enable interrupt handling for interrupt IRQ.  */
-+void cb_pic_enable_irq (unsigned irq)
-+{
-+	CB_PIC_INT1M |= 1 << (irq - CB_PIC_BASE_IRQ);
-+}
-+
-+void cb_pic_disable_irq (unsigned irq)
-+{
-+	CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
-+}
-+
-+void cb_pic_shutdown_irq (unsigned irq)
-+{
-+	cb_pic_disable_irq (irq);
-+
-+	if (--cb_pic_active_irqs == 0)
-+		free_irq (IRQ_CB_PIC, 0);
-+
-+	CB_PIC_INT1M &= ~(1 << (irq - CB_PIC_BASE_IRQ));
-+}
-+
-+static void cb_pic_handle_irq (int irq, void *dev_id, struct pt_regs *regs)
-+{
-+	unsigned status = CB_PIC_INTR;
-+	unsigned enable = CB_PIC_INT1M;
-+
-+	/* Only pay attention to enabled interrupts.  */
-+	status &= enable;
-+
-+	CB_PIC_INTEN &= ~CB_PIC_INT1EN;
-+
-+	if (status) {
-+		unsigned mask = 1;
-+
-+		irq = CB_PIC_BASE_IRQ;
-+		do {
-+			/* There's an active interrupt, find out which one,
-+			   and call its handler.  */
-+			while (! (status & mask)) {
-+				irq++;
-+				mask <<= 1;
-+			}
-+			status &= ~mask;
-+
-+			CB_PIC_INTR = mask;
-+
-+			/* Recursively call handle_irq to handle it. */
-+			handle_irq (irq, regs);
-+		} while (status);
-+	}
-+
-+	CB_PIC_INTEN |= CB_PIC_INT1EN;
-+}
-+
-+
-+static void irq_nop (unsigned irq) { }
-+
-+static unsigned cb_pic_startup_irq (unsigned irq)
-+{
-+	int rval;
-+
-+	if (cb_pic_active_irqs == 0) {
-+		rval = request_irq (IRQ_CB_PIC, cb_pic_handle_irq,
-+				    SA_INTERRUPT, "cb_pic_handler", 0);
-+		if (rval != 0)
-+			return rval;
-+	}
-+
-+	cb_pic_active_irqs++;
-+
-+	cb_pic_enable_irq (irq);
-+
-+	return 0;
-+}
-+
-+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
-+   INITS (which is terminated by an entry with the name field == 0).  */
-+void __init cb_pic_init_irq_types (struct cb_pic_irq_init *inits,
-+				   struct hw_interrupt_type *hw_irq_types)
-+{
-+	struct cb_pic_irq_init *init;
-+	for (init = inits; init->name; init++) {
-+		struct hw_interrupt_type *hwit = hw_irq_types++;
-+
-+		hwit->typename = init->name;
-+
-+		hwit->startup  = cb_pic_startup_irq;
-+		hwit->shutdown = cb_pic_shutdown_irq;
-+		hwit->enable   = cb_pic_enable_irq;
-+		hwit->disable  = cb_pic_disable_irq;
-+		hwit->ack      = irq_nop;
-+		hwit->end      = irq_nop;
-+
-+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
-+		init_irq_handlers(init->base, init->num, init->interval, hwit);
-+	}
-+}
---- linux-2.6.0-test1/arch/v850/kernel/rte_nb85e_cb.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/v850/kernel/rte_nb85e_cb.c	2003-07-19 17:03:49.000000000 -0700
-@@ -21,7 +21,7 @@
- 
- #include <asm/atomic.h>
- #include <asm/page.h>
--#include <asm/nb85e.h>
-+#include <asm/v850e.h>
- #include <asm/rte_nb85e_cb.h>
- 
- #include "mach.h"
-@@ -41,7 +41,7 @@ void __init mach_early_init (void)
- 
- 	   Unfortunately, the dcache seems to be buggy, so we only use the
- 	   icache for now.  */
--	nb85e_cache_enable (0x0040 /* BHC */, 0x0000 /* DCC */);
-+	v850e_cache_enable (0x0040 /*BHC*/, 0x0003 /*ICC*/, 0x0000 /*DCC*/);
- 
- 	rte_cb_early_init ();
- }
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/sim85e2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,211 @@
-+/*
-+ * arch/v850/kernel/sim85e2.c -- Machine-specific stuff for
-+ *	V850E2 RTL simulator
-+ *
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mm.h>
-+#include <linux/swap.h>
-+#include <linux/bootmem.h>
-+#include <linux/irq.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/page.h>
-+#include <asm/machdep.h>
-+
-+#include "mach.h"
-+
-+
-+/* There are 4 possible areas we can use:
-+
-+     IRAM (1MB) is fast for instruction fetches, but slow for data
-+     DRAM (1020KB) is fast for data, but slow for instructions
-+     ERAM is cached, so should be fast for both insns and data
-+     SDRAM is external DRAM, similar to ERAM
-+*/
-+
-+#define INIT_MEMC_FOR_SDRAM
-+#define USE_SDRAM_AREA
-+#define KERNEL_IN_SDRAM_AREA
-+
-+#define DCACHE_MODE	V850E2_CACHE_BTSC_DCM_WT
-+/*#define DCACHE_MODE	V850E2_CACHE_BTSC_DCM_WB_ALLOC*/
-+
-+#ifdef USE_SDRAM_AREA
-+#define RAM_START 	SDRAM_ADDR
-+#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
-+#else
-+/* When we use DRAM, we need to account for the fact that the end of it is
-+   used for R0_RAM.  */
-+#define RAM_START	DRAM_ADDR
-+#define RAM_END		R0_RAM_ADDR
-+#endif
-+
-+
-+extern void memcons_setup (void);
-+
-+
-+#ifdef KERNEL_IN_SDRAM_AREA
-+#define EARLY_INIT_SECTION_ATTR __attribute__ ((section (".early.text")))
-+#else
-+#define EARLY_INIT_SECTION_ATTR __init
-+#endif
-+
-+void EARLY_INIT_SECTION_ATTR mach_early_init (void)
-+{
-+	extern int panic_timeout;
-+
-+	/* The sim85e2 simulator tracks `undefined' values, so to make
-+	   debugging easier, we begin by zeroing out all otherwise
-+	   undefined registers.  This is not strictly necessary.
-+
-+	   The registers we zero are:
-+	       Every GPR except:
-+	           stack-pointer (r3)
-+		   task-pointer (r16)
-+		   our return addr (r31)
-+	       Every system register (SPR) that we know about except for
-+	       the PSW (SPR 5), which we zero except for the
-+	       disable-interrupts bit.
-+	*/
-+
-+	/* GPRs */
-+	asm volatile ("             mov r0, r1 ; mov r0, r2              ");
-+	asm volatile ("mov r0, r4 ; mov r0, r5 ; mov r0, r6 ; mov r0, r7 ");
-+	asm volatile ("mov r0, r8 ; mov r0, r9 ; mov r0, r10; mov r0, r11");
-+	asm volatile ("mov r0, r12; mov r0, r13; mov r0, r14; mov r0, r15");
-+	asm volatile ("             mov r0, r17; mov r0, r18; mov r0, r19");
-+	asm volatile ("mov r0, r20; mov r0, r21; mov r0, r22; mov r0, r23");
-+	asm volatile ("mov r0, r24; mov r0, r25; mov r0, r26; mov r0, r27");
-+	asm volatile ("mov r0, r28; mov r0, r29; mov r0, r30");
-+
-+	/* SPRs */
-+	asm volatile ("ldsr r0, 0;  ldsr r0, 1;  ldsr r0, 2;  ldsr r0, 3");
-+	asm volatile ("ldsr r0, 4");
-+	asm volatile ("addi 0x20, r0, r1; ldsr r1, 5"); /* PSW */
-+	asm volatile ("ldsr r0, 16; ldsr r0, 17; ldsr r0, 18; ldsr r0, 19");
-+	asm volatile ("ldsr r0, 20");
-+
-+
-+#ifdef INIT_MEMC_FOR_SDRAM
-+	/* Settings for SDRAM controller.  */
-+	V850E2_VSWC   = 0x0042;
-+	V850E2_BSC    = 0x9286;
-+	V850E2_BCT(0) = 0xb000;	/* was: 0 */
-+	V850E2_BCT(1) = 0x000b;
-+	V850E2_ASC    = 0;
-+	V850E2_LBS    = 0xa9aa;	/* was: 0xaaaa */
-+	V850E2_LBC(0) = 0;
-+	V850E2_LBC(1) = 0;	/* was: 0x3 */
-+	V850E2_BCC    = 0;
-+	V850E2_RFS(4) = 0x800a;	/* was: 0xf109 */
-+	V850E2_SCR(4) = 0x2091;	/* was: 0x20a1 */
-+	V850E2_RFS(3) = 0x800c;
-+	V850E2_SCR(3) = 0x20a1;
-+	V850E2_DWC(0) = 0;
-+	V850E2_DWC(1) = 0;
-+#endif
-+
-+#if 0
-+#ifdef CONFIG_V850E2_SIM85E2S
-+	/* Turn on the caches.  */
-+	V850E2_CACHE_BTSC = V850E2_CACHE_BTSC_ICM | DCACHE_MODE;
-+	V850E2_BHC  = 0x1010;
-+#elif CONFIG_V850E2_SIM85E2C
-+	V850E2_CACHE_BTSC |= (V850E2_CACHE_BTSC_ICM | V850E2_CACHE_BTSC_DCM0);
-+	V850E2_BUSM_BHC = 0xFFFF;
-+#endif
-+#else
-+	V850E2_BHC  = 0;
-+#endif
-+
-+	/* Don't stop the simulator at `halt' instructions.  */
-+	SIM85E2_NOTHAL = 1;
-+
-+	/* Ensure that the simulator halts on a panic, instead of going
-+	   into an infinite loop inside the panic function.  */
-+	panic_timeout = -1;
-+}
-+
-+void __init mach_setup (char **cmdline)
-+{
-+	memcons_setup ();
-+}
-+
-+void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
-+{
-+	*ram_start = RAM_START;
-+	*ram_len = RAM_END - RAM_START;
-+}
-+
-+void __init mach_reserve_bootmem ()
-+{
-+	extern char _root_fs_image_start, _root_fs_image_end;
-+	u32 root_fs_image_start = (u32)&_root_fs_image_start;
-+	u32 root_fs_image_end = (u32)&_root_fs_image_end;
-+
-+	/* Reserve the memory used by the root filesystem image if it's
-+	   in RAM.  */
-+	if (root_fs_image_end > root_fs_image_start
-+	    && root_fs_image_start >= RAM_START
-+	    && root_fs_image_start < RAM_END)
-+		reserve_bootmem (root_fs_image_start,
-+				 root_fs_image_end - root_fs_image_start);
-+}
-+
-+void __init mach_sched_init (struct irqaction *timer_action)
-+{
-+	/* The simulator actually cycles through all interrupts
-+	   periodically.  We just pay attention to IRQ0, which gives us
-+	   1/64 the rate of the periodic interrupts.  */
-+	setup_irq (0, timer_action);
-+}
-+
-+void mach_gettimeofday (struct timespec *tv)
-+{
-+	tv->tv_sec = 0;
-+	tv->tv_nsec = 0;
-+}
-+
-+/* Interrupts */
-+
-+struct v850e_intc_irq_init irq_inits[] = {
-+	{ "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
-+	{ 0 }
-+};
-+struct hw_interrupt_type hw_itypes[1];
-+
-+/* Initialize interrupts.  */
-+void __init mach_init_irqs (void)
-+{
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
-+}
-+
-+
-+void machine_halt (void) __attribute__ ((noreturn));
-+void machine_halt (void)
-+{
-+	SIM85E2_SIMFIN = 0;	/* Halt immediately.  */
-+	for (;;) {}
-+}
-+
-+void machine_restart (char *__unused)
-+{
-+	machine_halt ();
-+}
-+
-+void machine_power_off (void)
-+{
-+	machine_halt ();
-+}
---- linux-2.6.0-test1/arch/v850/kernel/sim85e2c.c	2003-06-14 12:18:22.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,145 +0,0 @@
--/*
-- * arch/v850/kernel/sim85e2c.c -- Machine-specific stuff for
-- *	V850E2 RTL simulator
-- *
-- *  Copyright (C) 2002  NEC Corporation
-- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#include <linux/config.h>
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/mm.h>
--#include <linux/swap.h>
--#include <linux/bootmem.h>
--#include <linux/irq.h>
--
--#include <asm/atomic.h>
--#include <asm/page.h>
--#include <asm/machdep.h>
--
--#include "mach.h"
--
--extern void memcons_setup (void);
--
--
--void __init mach_early_init (void)
--{
--	extern int panic_timeout;
--
--	/* Don't stop the simulator at `halt' instructions.  */
--	NOTHAL = 1;
--
--	/* The sim85e2c simulator tracks `undefined' values, so to make
--	   debugging easier, we begin by zeroing out all otherwise
--	   undefined registers.  This is not strictly necessary.
--
--	   The registers we zero are:
--	       Every GPR except:
--	           stack-pointer (r3)
--		   task-pointer (r16)
--		   our return addr (r31)
--	       Every system register (SPR) that we know about except for
--	       the PSW (SPR 5), which we zero except for the
--	       disable-interrupts bit.
--	*/
--
--	/* GPRs */
--	asm volatile ("             mov r0, r1 ; mov r0, r2              ");
--	asm volatile ("mov r0, r4 ; mov r0, r5 ; mov r0, r6 ; mov r0, r7 ");
--	asm volatile ("mov r0, r8 ; mov r0, r9 ; mov r0, r10; mov r0, r11");
--	asm volatile ("mov r0, r12; mov r0, r13; mov r0, r14; mov r0, r15");
--	asm volatile ("             mov r0, r17; mov r0, r18; mov r0, r19");
--	asm volatile ("mov r0, r20; mov r0, r21; mov r0, r22; mov r0, r23");
--	asm volatile ("mov r0, r24; mov r0, r25; mov r0, r26; mov r0, r27");
--	asm volatile ("mov r0, r28; mov r0, r29; mov r0, r30");
--
--	/* SPRs */
--	asm volatile ("ldsr r0, 0;  ldsr r0, 1;  ldsr r0, 2;  ldsr r0, 3");
--	asm volatile ("ldsr r0, 4");
--	asm volatile ("addi 0x20, r0, r1; ldsr r1, 5"); /* PSW */
--	asm volatile ("ldsr r0, 16; ldsr r0, 17; ldsr r0, 18; ldsr r0, 19");
--	asm volatile ("ldsr r0, 20");
--
--	/* Turn on the caches.  */
--	NA85E2C_CACHE_BTSC
--		|= (NA85E2C_CACHE_BTSC_ICM | NA85E2C_CACHE_BTSC_DCM0);
--	NA85E2C_BUSM_BHC = 0xFFFF;
--
--	/* Ensure that the simulator halts on a panic, instead of going
--	   into an infinite loop inside the panic function.  */
--	panic_timeout = -1;
--}
--
--void __init mach_setup (char **cmdline)
--{
--	memcons_setup ();
--}
--
--void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
--{
--	/* There are 3 possible areas we can use:
--	     IRAM (1MB) is fast for instruction fetches, but slow for data
--	     DRAM (1020KB) is fast for data, but slow for instructions
--	     ERAM is cached, so should be fast for both insns and data,
--	          _but_ currently only supports write-through caching, so
--		  writes are slow.
--	   Since there's really no area that's good for general kernel
--	   use, we use DRAM -- it won't be good for user programs
--	   (which will be loaded into kernel allocated memory), but
--	   currently we're more concerned with testing the kernel.  */
--	*ram_start = DRAM_ADDR;
--	*ram_len = R0_RAM_ADDR - DRAM_ADDR;
--}
--
--void __init mach_sched_init (struct irqaction *timer_action)
--{
--	/* The simulator actually cycles through all interrupts
--	   periodically.  We just pay attention to IRQ0, which gives us
--	   1/64 the rate of the periodic interrupts.  */
--	setup_irq (0, timer_action);
--}
--
--void mach_gettimeofday (struct timespec *tv)
--{
--	tv->tv_sec = 0;
--	tv->tv_nsec = 0;
--}
--
--/* Interrupts */
--
--struct nb85e_intc_irq_init irq_inits[] = {
--	{ "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
--	{ 0 }
--};
--struct hw_interrupt_type hw_itypes[1];
--
--/* Initialize interrupts.  */
--void __init mach_init_irqs (void)
--{
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
--}
--
--
--void machine_halt (void) __attribute__ ((noreturn));
--void machine_halt (void)
--{
--	SIMFIN = 0;		/* Halt immediately.  */
--	for (;;) {}
--}
--
--void machine_restart (char *__unused)
--{
--	machine_halt ();
--}
--
--void machine_power_off (void)
--{
--	machine_halt ();
--}
---- linux-2.6.0-test1/arch/v850/kernel/teg.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/arch/v850/kernel/teg.c	2003-07-19 17:03:49.000000000 -0700
-@@ -22,7 +22,7 @@
- #include <asm/atomic.h>
- #include <asm/page.h>
- #include <asm/machdep.h>
--#include <asm/nb85e_timer_d.h>
-+#include <asm/v850e_timer_d.h>
- 
- #include "mach.h"
- 
-@@ -31,12 +31,12 @@ void __init mach_sched_init (struct irqa
- 	/* Select timer interrupt instead of external pin.  */
- 	TEG_ISS |= 0x1;
- 	/* Start hardware timer.  */
--	nb85e_timer_d_configure (0, HZ);
-+	v850e_timer_d_configure (0, HZ);
- 	/* Install timer interrupt handler.  */
- 	setup_irq (IRQ_INTCMD(0), timer_action);
- }
- 
--static struct nb85e_intc_irq_init irq_inits[] = {
-+static struct v850e_intc_irq_init irq_inits[] = {
- 	{ "IRQ", 0,		NUM_CPU_IRQS,	1, 7 },
- 	{ "CMD", IRQ_INTCMD(0),	IRQ_INTCMD_NUM,	1, 5 },
- 	{ "SER", IRQ_INTSER(0),	IRQ_INTSER_NUM,	1, 3 },
-@@ -51,7 +51,7 @@ static struct hw_interrupt_type hw_itype
- /* Initialize MA chip interrupts.  */
- void __init teg_init_irqs (void)
- {
--	nb85e_intc_init_irq_types (irq_inits, hw_itypes);
-+	v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- 
- /* Called before configuring an on-chip UART.  */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/v850e2_cache.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,127 @@
-+/*
-+ * arch/v850/kernel/v850e2_cache.c -- Cache control for V850E2 cache
-+ * 	memories
-+ *
-+ *  Copyright (C) 2003  NEC Electronics Corporation
-+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/mm.h>
-+
-+#include <asm/v850e2_cache.h>
-+
-+/* Cache operations we can do.  The encoding corresponds directly to the
-+   value we need to write into the COPR register.  */
-+enum cache_op {
-+	OP_SYNC_IF_DIRTY 	   = V850E2_CACHE_COPR_CFC(0), /* 000 */
-+	OP_SYNC_IF_VALID 	   = V850E2_CACHE_COPR_CFC(1), /* 001 */
-+	OP_SYNC_IF_VALID_AND_CLEAR = V850E2_CACHE_COPR_CFC(3), /* 011 */
-+	OP_WAY_CLEAR 		   = V850E2_CACHE_COPR_CFC(4), /* 100 */
-+	OP_FILL 		   = V850E2_CACHE_COPR_CFC(5), /* 101 */
-+	OP_CLEAR 		   = V850E2_CACHE_COPR_CFC(6), /* 110 */
-+	OP_CREATE_DIRTY 	   = V850E2_CACHE_COPR_CFC(7)  /* 111 */
-+};
-+
-+/* Which cache to use.  This encoding also corresponds directly to the
-+   value we need to write into the COPR register. */
-+enum cache {
-+	ICACHE = 0,
-+	DCACHE = V850E2_CACHE_COPR_LBSL
-+};
-+
-+/* Returns ADDR rounded down to the beginning of its cache-line.  */
-+#define CACHE_LINE_ADDR(addr)  \
-+   ((addr) & ~(V850E2_CACHE_LINE_SIZE - 1))
-+/* Returns END_ADDR rounded up to the `limit' of its cache-line.  */
-+#define CACHE_LINE_END_ADDR(end_addr)  \
-+   CACHE_LINE_ADDR(end_addr + (V850E2_CACHE_LINE_SIZE - 1))
-+
-+
-+/* Low-level cache ops.  */
-+
-+/* Apply cache-op OP to all entries in CACHE.  */
-+static inline void cache_op_all (enum cache_op op, enum cache cache)
-+{
-+	int cmd = op | cache | V850E2_CACHE_COPR_WSLE | V850E2_CACHE_COPR_STRT;
-+
-+	if (op != OP_WAY_CLEAR) {
-+		/* The WAY_CLEAR operation does the whole way, but other
-+		   ops take begin-index and count params; we just indicate
-+		   the entire cache.  */
-+		V850E2_CACHE_CADL = 0;
-+		V850E2_CACHE_CADH = 0;
-+		V850E2_CACHE_CCNT = V850E2_CACHE_WAY_SIZE - 1;
-+	}
-+
-+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(0); /* way 0 */
-+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(1); /* way 1 */
-+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(2); /* way 2 */
-+	V850E2_CACHE_COPR = cmd | V850E2_CACHE_COPR_WSL(3); /* way 3 */
-+}
-+
-+/* Apply cache-op OP to all entries in CACHE covering addresses ADDR
-+   through ADDR+LEN.  */
-+static inline void cache_op_range (enum cache_op op, u32 addr, u32 len,
-+				   enum cache cache)
-+{
-+	u32 start = CACHE_LINE_ADDR (addr);
-+	u32 end = CACHE_LINE_END_ADDR (addr + len);
-+	u32 num_lines = (end - start) >> V850E2_CACHE_LINE_SIZE_BITS;
-+
-+	V850E2_CACHE_CADL = start & 0xFFFF;
-+	V850E2_CACHE_CADH = start >> 16;
-+	V850E2_CACHE_CCNT = num_lines - 1;
-+
-+	V850E2_CACHE_COPR = op | cache | V850E2_CACHE_COPR_STRT;
-+}
-+
-+
-+/* High-level ops.  */
-+
-+static void cache_exec_after_store_all (void)
-+{
-+	cache_op_all (OP_SYNC_IF_DIRTY, DCACHE);
-+	cache_op_all (OP_WAY_CLEAR, ICACHE);
-+}
-+
-+static void cache_exec_after_store_range (u32 start, u32 len)
-+{
-+	cache_op_range (OP_SYNC_IF_DIRTY, start, len, DCACHE);
-+	cache_op_range (OP_CLEAR, start, len, ICACHE);
-+}
-+
-+
-+/* Exported functions.  */
-+
-+void flush_icache (void)
-+{
-+	cache_exec_after_store_all ();
-+}
-+
-+void flush_icache_range (unsigned long start, unsigned long end)
-+{
-+	cache_exec_after_store_range (start, end - start);
-+}
-+
-+void flush_icache_page (struct vm_area_struct *vma, struct page *page)
-+{
-+	cache_exec_after_store_range (page_to_virt (page), PAGE_SIZE);
-+}
-+
-+void flush_icache_user_range (struct vm_area_struct *vma, struct page *page,
-+			      unsigned long addr, int len)
-+{
-+	cache_exec_after_store_range (addr, len);
-+}
-+
-+void flush_cache_sigtramp (unsigned long addr)
-+{
-+	/* For the exact size, see signal.c, but 16 bytes should be enough.  */
-+	cache_exec_after_store_range (addr, 16);
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/v850e_cache.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,173 @@
-+/*
-+ * arch/v850/kernel/v850e_cache.c -- Cache control for V850E cache memories
-+ *
-+ *  Copyright (C) 2003  NEC Electronics Corporation
-+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* This file implements cache control for the rather simple cache used on
-+   some V850E CPUs, specifically the NB85E/TEG CPU-core and the V850E/ME2
-+   CPU.  V850E2 processors have their own (better) cache
-+   implementation.  */
-+
-+#include <asm/entry.h>
-+#include <asm/v850e_cache.h>
-+
-+#define WAIT_UNTIL_CLEAR(value) while (value) {}
-+
-+/* Set caching params via the BHC and DCC registers.  */
-+void v850e_cache_enable (u16 bhc, u16 icc, u16 dcc)
-+{
-+	unsigned long *r0_ram = (unsigned long *)R0_RAM_ADDR;
-+	register u16 bhc_val asm ("r6") = bhc;
-+
-+	/* Read the instruction cache control register (ICC) and confirm
-+	   that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
-+	V850E_CACHE_ICC = icc;
-+
-+#ifdef V850E_CACHE_DCC
-+	/* Configure data-cache.  */
-+	V850E_CACHE_DCC = dcc;
-+#endif /* V850E_CACHE_DCC */
-+
-+	/* Configure caching for various memory regions by writing the BHC
-+	   register.  The documentation says that an instruction _cannot_
-+	   enable/disable caching for the memory region in which the
-+	   instruction itself exists; to work around this, we store
-+	   appropriate instructions into the on-chip RAM area (which is never
-+	   cached), and briefly jump there to do the work.  */
-+#ifdef V850E_CACHE_WRITE_IBS
-+	*r0_ram++ 	= 0xf0720760;	/* st.h r0, 0xfffff072[r0] */
-+#endif
-+	*r0_ram++ 	= 0xf06a3760;	/* st.h r6, 0xfffff06a[r0] */
-+	*r0_ram 	= 0x5640006b;	/* jmp [r11] */
-+
-+	asm ("mov hilo(1f), r11; jmp [%1]; 1:;"
-+	     :: "r" (bhc_val), "r" (R0_RAM_ADDR) : "r11");
-+}
-+
-+static void clear_icache (void)
-+{
-+	/* 1. Read the instruction cache control register (ICC) and confirm
-+	      that bits 0 and 1 (TCLR0, TCLR1) are all cleared.  */
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
-+
-+	/* 2. Read the ICC register and confirm that bit 12 (LOCK0) is
-+  	      cleared.  Bit 13 of the ICC register is always cleared.  */
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x1000);
-+
-+	/* 3. Set the TCLR0 and TCLR1 bits of the ICC register as follows,
-+	      when clearing way 0 and way 1 at the same time:
-+	        (a) Set the TCLR0 and TCLR1 bits.
-+		(b) Read the TCLR0 and TCLR1 bits to confirm that these bits
-+		    are cleared.
-+		(c) Perform (a) and (b) above again.  */
-+	V850E_CACHE_ICC |= 0x3;
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
-+
-+#ifdef V850E_CACHE_REPEAT_ICC_WRITE
-+	/* Do it again.  */
-+	V850E_CACHE_ICC |= 0x3;
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_ICC & 0x3);
-+#endif
-+}
-+
-+#ifdef V850E_CACHE_DCC
-+/* Flush or clear (or both) the data cache, depending on the value of FLAGS;
-+   the procedure is the same for both, just the control bits used differ (and
-+   both may be performed simultaneously).  */
-+static void dcache_op (unsigned short flags)
-+{
-+	/* 1. Read the data cache control register (DCC) and confirm that bits
-+	      0, 1, 4, and 5 (DC00, DC01, DC04, DC05) are all cleared.  */
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & 0x33);
-+
-+	/* 2. Clear DCC register bit 12 (DC12), bit 13 (DC13), or both
-+	      depending on the way for which tags are to be cleared.  */
-+	V850E_CACHE_DCC &= ~0xC000;
-+
-+	/* 3. Set DCC register bit 0 (DC00), bit 1 (DC01) or both depending on
-+	      the way for which tags are to be cleared.
-+	      ...
-+	      Set DCC register bit 4 (DC04), bit 5 (DC05), or both depending
-+	      on the way to be data flushed.  */
-+	V850E_CACHE_DCC |= flags;
-+
-+	/* 4. Read DCC register bit DC00, DC01 [DC04, DC05], or both depending
-+	      on the way for which tags were cleared [flushed] and confirm
-+	      that that bit is cleared.  */
-+	WAIT_UNTIL_CLEAR (V850E_CACHE_DCC & flags);
-+}
-+#endif /* V850E_CACHE_DCC */
-+
-+/* Flushes the contents of the dcache to memory.  */
-+static inline void flush_dcache (void)
-+{
-+#ifdef V850E_CACHE_DCC
-+	/* We only need to do something if in write-back mode.  */
-+	if (V850E_CACHE_DCC & 0x0400)
-+		dcache_op (0x30);
-+#endif /* V850E_CACHE_DCC */
-+}
-+
-+/* Flushes the contents of the dcache to memory, and then clears it.  */
-+static inline void clear_dcache (void)
-+{
-+#ifdef V850E_CACHE_DCC
-+	/* We only need to do something if the dcache is enabled.  */
-+	if (V850E_CACHE_DCC & 0x0C00)
-+		dcache_op (0x33);
-+#endif /* V850E_CACHE_DCC */
-+}
-+
-+/* Clears the dcache without flushing to memory first.  */
-+static inline void clear_dcache_no_flush (void)
-+{
-+#ifdef V850E_CACHE_DCC
-+	/* We only need to do something if the dcache is enabled.  */
-+	if (V850E_CACHE_DCC & 0x0C00)
-+		dcache_op (0x3);
-+#endif /* V850E_CACHE_DCC */
-+}
-+
-+static inline void cache_exec_after_store (void)
-+{
-+	flush_dcache ();
-+	clear_icache ();
-+}
-+
-+
-+/* Exported functions.  */
-+
-+void flush_icache (void)
-+{
-+	cache_exec_after_store ();
-+}
-+
-+void flush_icache_range (unsigned long start, unsigned long end)
-+{
-+	cache_exec_after_store ();
-+}
-+
-+void flush_icache_page (struct vm_area_struct *vma, struct page *page)
-+{
-+	cache_exec_after_store ();
-+}
-+
-+void flush_icache_user_range (struct vm_area_struct *vma, struct page *page,
-+			      unsigned long adr, int len)
-+{
-+	cache_exec_after_store ();
-+}
-+
-+void flush_cache_sigtramp (unsigned long addr)
-+{
-+	cache_exec_after_store ();
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/v850e_intc.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,104 @@
-+/*
-+ * arch/v850/kernel/v850e_intc.c -- V850E interrupt controller (INTC)
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/irq.h>
-+
-+#include <asm/v850e_intc.h>
-+
-+static void irq_nop (unsigned irq) { }
-+
-+static unsigned v850e_intc_irq_startup (unsigned irq)
-+{
-+	v850e_intc_clear_pending_irq (irq);
-+	v850e_intc_enable_irq (irq);
-+	return 0;
-+}
-+
-+static void v850e_intc_end_irq (unsigned irq)
-+{
-+	unsigned long psw, temp;
-+
-+	/* Clear the highest-level bit in the In-service priority register
-+	   (ISPR), to allow this interrupt (or another of the same or
-+	   lesser priority) to happen again.
-+
-+	   The `reti' instruction normally does this automatically when the
-+	   PSW bits EP and NP are zero, but we can't always rely on reti
-+	   being used consistently to return after an interrupt (another
-+	   process can be scheduled, for instance, which can delay the
-+	   associated reti for a long time, or this process may be being
-+	   single-stepped, which uses the `dbret' instruction to return
-+	   from the kernel).
-+
-+	   We also set the PSW EP bit, which prevents reti from also
-+	   trying to modify the ISPR itself.  */
-+
-+	/* Get PSW and disable interrupts.  */
-+	asm volatile ("stsr psw, %0; di" : "=r" (psw));
-+	/* We don't want to do anything for NMIs (they don't use the ISPR).  */
-+	if (! (psw & 0xC0)) {
-+		/* Transition to `trap' state, so that an eventual real
-+		   reti instruction won't modify the ISPR.  */
-+		psw |= 0x40;
-+		/* Fake an interrupt return, which automatically clears the
-+		   appropriate bit in the ISPR.  */
-+		asm volatile ("mov hilo(1f), %0;"
-+			      "ldsr %0, eipc; ldsr %1, eipsw;"
-+			      "reti;"
-+			      "1:"
-+			      : "=&r" (temp) : "r" (psw));
-+	}
-+}
-+
-+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
-+   INITS (which is terminated by an entry with the name field == 0).  */
-+void __init v850e_intc_init_irq_types (struct v850e_intc_irq_init *inits,
-+				       struct hw_interrupt_type *hw_irq_types)
-+{
-+	struct v850e_intc_irq_init *init;
-+	for (init = inits; init->name; init++) {
-+		unsigned i;
-+		struct hw_interrupt_type *hwit = hw_irq_types++;
-+
-+		hwit->typename = init->name;
-+
-+		hwit->startup  = v850e_intc_irq_startup;
-+		hwit->shutdown = v850e_intc_disable_irq;
-+		hwit->enable   = v850e_intc_enable_irq;
-+		hwit->disable  = v850e_intc_disable_irq;
-+		hwit->ack      = irq_nop;
-+		hwit->end      = v850e_intc_end_irq;
-+		
-+		/* Initialize kernel IRQ infrastructure for this interrupt.  */
-+		init_irq_handlers(init->base, init->num, init->interval, hwit);
-+
-+		/* Set the interrupt priorities.  */
-+		for (i = 0; i < init->num; i++) {
-+			unsigned irq = init->base + i * init->interval;
-+
-+			/* If the interrupt is currently enabled (all
-+			   interrupts are initially disabled), then
-+			   assume whoever enabled it has set things up
-+			   properly, and avoid messing with it.  */
-+			if (! v850e_intc_irq_enabled (irq))
-+				/* This write also (1) disables the
-+				   interrupt, and (2) clears any pending
-+				   interrupts.  */
-+				V850E_INTC_IC (irq)
-+					= (V850E_INTC_IC_PR (init->priority)
-+					   | V850E_INTC_IC_MK);
-+		}
-+	}
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/v850e_timer_d.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,54 @@
-+/*
-+ * include/asm-v850/v850e_timer_d.c -- `Timer D' component often used
-+ *	with V850E CPUs
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <linux/kernel.h>
-+
-+#include <asm/v850e_utils.h>
-+#include <asm/v850e_timer_d.h>
-+
-+/* Start interval timer TIMER (0-3).  The timer will issue the
-+   corresponding INTCMD interrupt RATE times per second.
-+   This function does not enable the interrupt.  */
-+void v850e_timer_d_configure (unsigned timer, unsigned rate)
-+{
-+	unsigned divlog2, count;
-+
-+	/* Calculate params for timer.  */
-+	if (! calc_counter_params (
-+		    V850E_TIMER_D_BASE_FREQ, rate,
-+		    V850E_TIMER_D_TMCD_CS_MIN, V850E_TIMER_D_TMCD_CS_MAX, 16,
-+		    &divlog2, &count))
-+		printk (KERN_WARNING
-+			"Cannot find interval timer %d setting suitable"
-+			" for rate of %dHz.\n"
-+			"Using rate of %dHz instead.\n",
-+			timer, rate,
-+			(V850E_TIMER_D_BASE_FREQ >> divlog2) >> 16);
-+
-+	/* Do the actual hardware timer initialization:  */
-+
-+	/* Enable timer.  */
-+	V850E_TIMER_D_TMCD(timer) = V850E_TIMER_D_TMCD_CAE;
-+	/* Set clock divider.  */
-+	V850E_TIMER_D_TMCD(timer)
-+		= V850E_TIMER_D_TMCD_CAE
-+		| V850E_TIMER_D_TMCD_CS(divlog2);
-+	/* Set timer compare register.  */
-+	V850E_TIMER_D_CMD(timer) = count;
-+	/* Start counting.  */
-+	V850E_TIMER_D_TMCD(timer)
-+		= V850E_TIMER_D_TMCD_CAE
-+		| V850E_TIMER_D_TMCD_CS(divlog2)
-+		| V850E_TIMER_D_TMCD_CE;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/kernel/v850e_utils.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,62 @@
-+/*
-+ * include/asm-v850/v850e_utils.h -- Utility functions associated with
-+ *	V850E CPUs
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#include <asm/v850e_utils.h>
-+
-+/* Calculate counter clock-divider and count values to attain the
-+   desired frequency RATE from the base frequency BASE_FREQ.  The
-+   counter is expected to have a clock-divider, which can divide the
-+   system cpu clock by a power of two value from MIN_DIVLOG2 to
-+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
-+   counts up and resets whenever it's equal to the compare register,
-+   generating an interrupt or whatever when it does so).  The returned
-+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
-+   -- the counter compare value to use.  Returns true if it was possible
-+   to find a reasonable value, otherwise false (and the other return
-+   values will be set to be as good as possible).  */
-+int calc_counter_params (unsigned long base_freq,
-+			 unsigned long rate,
-+			 unsigned min_divlog2, unsigned max_divlog2,
-+			 unsigned counter_size,
-+			 unsigned *divlog2, unsigned *count)
-+{
-+	unsigned _divlog2;
-+	int ok = 0;
-+
-+	/* Find the lowest clock divider setting that can represent RATE.  */
-+	for (_divlog2 = min_divlog2; _divlog2 <= max_divlog2; _divlog2++) {
-+		/* Minimum interrupt rate possible using this divider.  */
-+		unsigned min_int_rate
-+			= (base_freq >> _divlog2) >> counter_size;
-+
-+		if (min_int_rate <= rate) {
-+			/* This setting is the highest resolution
-+			   setting that's slow enough enough to attain
-+			   RATE interrupts per second, so use it.  */
-+			ok = 1;
-+			break;
-+		}
-+	}
-+
-+	if (_divlog2 > max_divlog2)
-+		/* Can't find correct setting.  */
-+		_divlog2 = max_divlog2;
-+
-+	if (divlog2)
-+		*divlog2 = _divlog2;
-+	if (count)
-+		*count = ((base_freq >> _divlog2) + rate/2) / rate;
-+
-+	return ok;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/rte_me2_cb.ld	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,30 @@
-+/* Linker script for the Midas labs RTE-V850E/ME2-CB evaluation board
-+   (CONFIG_RTE_CB_ME2), with kernel in SDRAM.  */
-+
-+MEMORY {
-+	/* 128Kbyte of IRAM */
-+	IRAM : ORIGIN = 0x00000000, LENGTH = 0x00020000
-+	
-+	/* 32MB of SDRAM.  */
-+	SDRAM : ORIGIN = 0x00800000, LENGTH = 0x02000000
-+}
-+
-+#define KRAM SDRAM
-+
-+SECTIONS {
-+	.text : {
-+		__kram_start = . ;
-+		TEXT_CONTENTS
-+		INTV_CONTENTS	/* copy to iRAM (0x0-0x620) */
-+	} > KRAM
-+
-+	.data : {
-+		DATA_CONTENTS
-+		BSS_CONTENTS
-+		RAMK_INIT_CONTENTS
-+		__kram_end = . ;
-+		BOOTMAP_CONTENTS
-+	} > KRAM
-+	
-+	.root ALIGN (4096) : { ROOT_FS_CONTENTS } > SDRAM
-+}
---- linux-2.6.0-test1/arch/v850/sim85e2c.ld	2003-06-14 12:18:34.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,44 +0,0 @@
--/* Linker script for the sim85e2c simulator, which is a verilog simulation of
--   the V850E2 NA85E2C cpu core (CONFIG_V850E2_SIM85E2C).  */
--
--MEMORY {
--	/* 1MB of `instruction RAM', starting at 0.
--	   Instruction fetches are much faster from IRAM than from DRAM.
--	   This should match IRAM_ADDR in "include/asm-v580/sim85e2c.h".    */
--	IRAM	: ORIGIN = 0x00000000, LENGTH = 0x00100000
--
--	/* 1MB of `data RAM', below and contiguous with the I/O space.
--	   Data fetches are much faster from DRAM than from IRAM.
--	   This should match DRAM_ADDR in "include/asm-v580/sim85e2c.h".  */
--	DRAM	: ORIGIN = 0xfff00000, LENGTH = 0x000ff000
--	/* We have to load DRAM at a mirror-address of 0x1ff00000,
--	   because the simulator's preprocessing script isn't smart
--	   enough to deal with the above LMA.  */
--	DRAM_LOAD : ORIGIN = 0x1ff00000, LENGTH = 0x000ff000
--
--	/* `external ram' (CS1 area), comes after IRAM.
--	   This should match ERAM_ADDR in "include/asm-v580/sim85e2c.h".  */
--	ERAM	: ORIGIN = 0x00100000, LENGTH = 0x07f00000
--}
--
--SECTIONS {
--	.iram : {
--		INTV_CONTENTS
--		TEXT_CONTENTS
--		RAMK_INIT_CONTENTS
--	} > IRAM
--	.data : {
--		__kram_start = . ;
--		DATA_CONTENTS
--		BSS_CONTENTS
--		ROOT_FS_CONTENTS
--
--		/* We stick console output into a buffer here.  */
--		_memcons_output = . ;
--		. = . + 0x8000 ;
--		_memcons_output_end = . ;
--
--		__kram_end = . ;
--		BOOTMAP_CONTENTS
--	} > DRAM  AT> DRAM_LOAD
--}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/arch/v850/sim85e2.ld	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,44 @@
-+/* Linker script for the sim85e2c simulator, which is a verilog simulation of
-+   the V850E2 NA85E2C cpu core (CONFIG_V850E2_SIM85E2C).  */
-+
-+MEMORY {
-+	/* 1MB of `instruction RAM', starting at 0.
-+	   Instruction fetches are much faster from IRAM than from DRAM.
-+	   This should match IRAM_ADDR in "include/asm-v580/sim85e2c.h".    */
-+	IRAM		: ORIGIN = 0x00000000, LENGTH = 0x00100000
-+
-+	/* 1MB of `data RAM', below and contiguous with the I/O space.
-+	   Data fetches are much faster from DRAM than from IRAM.
-+	   This should match DRAM_ADDR in "include/asm-v580/sim85e2c.h".  */
-+	DRAM		: ORIGIN = 0xfff00000, LENGTH = 0x000ff000
-+	/* We have to load DRAM at a mirror-address of 0x1ff00000,
-+	   because the simulator's preprocessing script isn't smart
-+	   enough to deal with the above LMA.  */
-+	DRAM_LOAD 	: ORIGIN = 0x1ff00000, LENGTH = 0x000ff000
-+
-+	/* `external ram' (CS1 area), comes after IRAM.
-+	   This should match ERAM_ADDR in "include/asm-v580/sim85e2c.h".  */
-+	ERAM		: ORIGIN = 0x00100000, LENGTH = 0x07f00000
-+
-+	/* Dynamic RAM; uses memory controller.  */
-+	/* SDRAM	: ORIGIN = 0x10000000, LENGTH = 0x01000000 */
-+	SDRAM		: ORIGIN = 0x10000000, LENGTH = 0x00200000/*use 2MB*/
-+}
-+
-+SECTIONS {
-+	.iram : {
-+		INTV_CONTENTS
-+		*arch/v850/kernel/head.o
-+		*(.early.text)
-+	} > IRAM
-+	.dram : {
-+		_memcons_output = . ;
-+		. = . + 0x8000 ;
-+		_memcons_output_end = . ;
-+	} > DRAM
-+	.sdram : {
-+		/* We stick console output into a buffer here.  */
-+		RAMK_KRAM_CONTENTS
-+		ROOT_FS_CONTENTS
-+	} > SDRAM
-+}
---- linux-2.6.0-test1/arch/v850/vmlinux.lds.S	2003-06-22 12:04:44.000000000 -0700
-+++ 25/arch/v850/vmlinux.lds.S	2003-07-19 17:03:49.000000000 -0700
-@@ -206,8 +206,8 @@ _jiffies = _jiffies_64 ;
- # include "sim.ld"
- #endif
- 
--#ifdef CONFIG_V850E2_SIM85E2C
--# include "sim85e2c.ld"
-+#ifdef CONFIG_V850E2_SIM85E2
-+# include "sim85e2.ld"
- #endif
- 
- #ifdef CONFIG_V850E2_FPGA85E2C
-@@ -247,3 +247,8 @@ _jiffies = _jiffies_64 ;
- #  include "rte_nb85e_cb.ld"
- # endif
- #endif
-+
-+#ifdef CONFIG_RTE_CB_ME2
-+#  include "rte_me2_cb.ld"
-+#endif
-+
---- linux-2.6.0-test1/arch/x86_64/boot/compressed/head.S	2003-06-26 22:07:24.000000000 -0700
-+++ 25/arch/x86_64/boot/compressed/head.S	2003-07-19 17:04:53.000000000 -0700
-@@ -26,6 +26,7 @@
- .code32
- .text
- 
-+#define IN_BOOTLOADER
- #include <linux/linkage.h>
- #include <asm/segment.h>
- 
---- linux-2.6.0-test1/arch/x86_64/boot/compressed/misc.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/arch/x86_64/boot/compressed/misc.c	2003-07-19 17:04:53.000000000 -0700
-@@ -9,6 +9,7 @@
-  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
-  */
- 
-+#define IN_BOOTLOADER
- #include "miscsetup.h"
- #include <asm/io.h>
- 
---- linux-2.6.0-test1/arch/x86_64/ia32/syscall32.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/arch/x86_64/ia32/syscall32.c	2003-07-19 17:07:16.000000000 -0700
-@@ -29,12 +29,15 @@ char *syscall32_page; 
-    and let it be handled by generic VM */ 
- int map_syscall32(struct mm_struct *mm, unsigned long address) 
- { 
-+	pgd_t *pgd;
-+	pmd_t *pmd;
- 	pte_t *pte;
- 	int err = 0;
- 	down_read(&mm->mmap_sem);
- 	spin_lock(&mm->page_table_lock); 
--	pmd_t *pmd = pmd_alloc(mm, pgd_offset(mm, address), address); 
--	if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { 
-+	pgd = pgd_offset(mm, address);
-+	pmd = pmd_alloc_map(mm, pgd, address);
-+	if (pmd && (pte = pte_alloc_map(mm, pgd, &pmd, address)) != NULL) {
- 		if (pte_none(*pte)) { 
- 			set_pte(pte, 
- 				mk_pte(virt_to_page(syscall32_page), 
---- linux-2.6.0-test1/arch/x86_64/kernel/apic.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/x86_64/kernel/apic.c	2003-07-19 17:04:07.000000000 -0700
-@@ -298,8 +298,8 @@ void __init setup_local_APIC (void)
- 	 * Double-check whether this APIC is really registered.
- 	 * This is meaningless in clustered apic mode, so we skip it.
- 	 */
--	if (!clustered_apic_mode && 
--	    !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
-+	if (!clustered_apic_mode &&
-+		!cpu_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map))
- 		BUG();
- 
- 	/*
-@@ -997,7 +997,7 @@ int __init APIC_init_uniprocessor (void)
- 
- 	connect_bsp_APIC();
- 
--	phys_cpu_present_map = 1;
-+	phys_cpu_present_map = cpumask_of_cpu(0);
- 	apic_write_around(APIC_ID, boot_cpu_id);
- 
- 	setup_local_APIC();
---- linux-2.6.0-test1/arch/x86_64/kernel/io_apic.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/x86_64/kernel/io_apic.c	2003-07-19 17:04:07.000000000 -0700
-@@ -1014,7 +1014,7 @@ void disable_IO_APIC(void)
- static void __init setup_ioapic_ids_from_mpc (void)
- {
- 	union IO_APIC_reg_00 reg_00;
--	unsigned long phys_id_present_map = phys_cpu_present_map;
-+	cpumask_t phys_id_present_map = phys_cpu_present_map;
- 	int apic;
- 	int i;
- 	unsigned char old_id;
-@@ -1047,22 +1047,22 @@ static void __init setup_ioapic_ids_from
- 		 * system must have a unique ID or we get lots of nice
- 		 * 'stuck on smp_invalidate_needed IPI wait' messages.
- 	 	 */
--		if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
-+		if (cpu_isset(mp_ioapics[apic].mpc_apicid, phys_id_present_map)) {
- 			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- 				apic, mp_ioapics[apic].mpc_apicid);
- 			for (i = 0; i < 0xf; i++)
--				if (!(phys_id_present_map & (1 << i)))
-+				if (!cpu_isset(i, phys_id_present_map))
- 					break;
- 			if (i >= 0xf)
- 				panic("Max APIC ID exceeded!\n");
- 			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- 				i);
--			phys_id_present_map |= 1 << i;
-+			cpu_set(i, phys_id_present_map);
- 			mp_ioapics[apic].mpc_apicid = i;
- 		} else {
- 			printk(KERN_INFO 
- 			       "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
--			phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
-+			cpu_set(mp_ioapics[apic].mpc_apicid, phys_id_present_map);
- 		}
- 
- 
-@@ -1638,7 +1638,7 @@ void __init mp_config_ioapic_for_sci(int
- int __init io_apic_get_unique_id (int ioapic, int apic_id)
- {
- 	union IO_APIC_reg_00 reg_00;
--	static unsigned long apic_id_map = 0;
-+	static cpumask_t apic_id_map;
- 	unsigned long flags;
- 	int i = 0;
- 
-@@ -1651,7 +1651,7 @@ int __init io_apic_get_unique_id (int io
- 	 *      advantage of new APIC bus architecture.
- 	 */
- 
--	if (!apic_id_map)
-+	if (!cpus_empty(apic_id_map))
- 		apic_id_map = phys_cpu_present_map;
- 
- 	spin_lock_irqsave(&ioapic_lock, flags);
-@@ -1668,10 +1668,10 @@ int __init io_apic_get_unique_id (int io
- 	 * Every APIC in a system must have a unique ID or we get lots of nice 
- 	 * 'stuck on smp_invalidate_needed IPI wait' messages.
- 	 */
--	if (apic_id_map & (1 << apic_id)) {
-+	if (cpu_isset(apic_id, apic_id_map)) {
- 
- 		for (i = 0; i < IO_APIC_MAX_ID; i++) {
--			if (!(apic_id_map & (1 << i)))
-+			if (!cpu_isset(i, apic_id_map))
- 				break;
- 		}
- 
-@@ -1684,7 +1684,7 @@ int __init io_apic_get_unique_id (int io
- 		apic_id = i;
- 	} 
- 
--	apic_id_map |= (1 << apic_id);
-+	cpu_set(apic_id, apic_id_map);
- 
- 	if (reg_00.bits.ID != apic_id) {
- 		reg_00.bits.ID = apic_id;
---- linux-2.6.0-test1/arch/x86_64/kernel/irq.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/arch/x86_64/kernel/irq.c	2003-07-19 17:04:07.000000000 -0700
-@@ -792,13 +792,13 @@ int setup_irq(unsigned int irq, struct i
- static struct proc_dir_entry * root_irq_dir;
- static struct proc_dir_entry * irq_dir [NR_IRQS];
- 
--#define HEX_DIGITS 8
-+#define HEX_DIGITS (2*sizeof(cpumask_t))
- 
- static unsigned int parse_hex_value (const char *buffer,
--		unsigned long count, unsigned long *ret)
-+		unsigned long count, cpumask_t *ret)
- {
- 	unsigned char hexnum [HEX_DIGITS];
--	unsigned long value;
-+	cpumask_t value = CPU_MASK_NONE;
- 	unsigned i;
- 
- 	if (!count)
-@@ -812,10 +812,9 @@ static unsigned int parse_hex_value (con
- 	 * Parse the first 8 characters as a hex string, any non-hex char
- 	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- 	 */
--	value = 0;
- 
- 	for (i = 0; i < count; i++) {
--		unsigned int c = hexnum[i];
-+		unsigned int k, c = hexnum[i];
- 
- 		switch (c) {
- 			case '0' ... '9': c -= '0'; break;
-@@ -824,7 +823,10 @@ static unsigned int parse_hex_value (con
- 		default:
- 			goto out;
- 		}
--		value = (value << 4) | c;
-+		cpus_shift_left(value, value, 4);
-+		for (k = 0; k < 4; ++k)
-+			if (c & (1 << k))
-+				cpu_set(k, value);
- 	}
- out:
- 	*ret = value;
-@@ -835,20 +837,31 @@ out:
- 
- static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
- 
--static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
-+static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
- static int irq_affinity_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
-+	int k, len;
-+	cpumask_t tmp = irq_affinity[(long)data];
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
-+
-+	for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int irq_affinity_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
- 	int irq = (long) data, full_count = count, err;
--	unsigned long new_value;
-+	cpumask_t tmp, new_value;
- 
- 	if (!irq_desc[irq].handler->set_affinity)
- 		return -EIO;
-@@ -860,7 +873,8 @@ static int irq_affinity_write_proc (stru
- 	 * way to make the system unusable accidentally :-) At least
- 	 * one online CPU still has to be targeted.
- 	 */
--	if (!(new_value & cpu_online_map))
-+	cpus_and(tmp, new_value, cpu_online_map);
-+	if (cpus_empty(tmp))
- 		return -EINVAL;
- 
- 	irq_affinity[irq] = new_value;
-@@ -874,17 +888,28 @@ static int irq_affinity_write_proc (stru
- static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- 			int count, int *eof, void *data)
- {
--	unsigned long *mask = (unsigned long *) data;
-+	cpumask_t tmp, *mask = (cpumask_t *) data;
-+	int k, len;
-+
- 	if (count < HEX_DIGITS+1)
- 		return -EINVAL;
--	return sprintf (page, "%08lx\n", *mask);
-+
-+	tmp = *mask;
-+	for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		page += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+	len += sprintf(page, "\n");
-+	return len;
- }
- 
- static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- 					unsigned long count, void *data)
- {
--	unsigned long *mask = (unsigned long *) data, full_count = count, err;
--	unsigned long new_value;
-+	unsigned long full_count = count, err;
-+	cpumask_t new_value, *mask = (cpumask_t *)data;
- 
- 	err = parse_hex_value(buffer, count, &new_value);
- 	if (err)
---- linux-2.6.0-test1/arch/x86_64/kernel/ldt.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/x86_64/kernel/ldt.c	2003-07-19 17:04:07.000000000 -0700
-@@ -60,9 +60,12 @@ static int alloc_ldt(mm_context_t *pc, u
- 	wmb();
- 	if (reload) {
- #ifdef CONFIG_SMP
-+		cpumask_t mask;
-+
- 		preempt_disable();
-+		mask = cpumask_of_cpu(smp_processor_id());
- 		load_LDT(pc);
--		if (current->mm->cpu_vm_mask != (1UL<<smp_processor_id()))
-+		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, 0, 1, 1);
- 		preempt_enable();
- #else
---- linux-2.6.0-test1/arch/x86_64/kernel/mpparse.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/arch/x86_64/kernel/mpparse.c	2003-07-19 17:04:07.000000000 -0700
-@@ -65,7 +65,7 @@ unsigned int boot_cpu_id = -1U;
- static unsigned int num_processors = 0;
- 
- /* Bitmask of physically existing CPUs */
--unsigned long phys_cpu_present_map = 0;
-+cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
- 
- /* ACPI MADT entry parsing functions */
- #ifdef CONFIG_ACPI_BOOT
-@@ -124,7 +124,7 @@ static void __init MP_processor_info (st
- 	}
- 	ver = m->mpc_apicver;
- 
--	phys_cpu_present_map |= 1 << m->mpc_apicid;
-+	cpu_set(m->mpc_apicid, phys_cpu_present_map);
- 	/*
- 	 * Validate version
- 	 */
---- linux-2.6.0-test1/arch/x86_64/kernel/msr.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/x86_64/kernel/msr.c	2003-07-19 17:04:07.000000000 -0700
-@@ -242,7 +242,7 @@ static int msr_open(struct inode *inode,
-   int cpu = minor(file->f_dentry->d_inode->i_rdev);
-   struct cpuinfo_x86 *c = &(cpu_data)[cpu];
-   
--  if ( !(cpu_online_map & (1UL << cpu)) )
-+  if (!cpu_online(cpu))
-     return -ENXIO;		/* No such CPU */
-   if ( !cpu_has(c, X86_FEATURE_MSR) )
-     return -EIO;		/* MSR not supported */
---- linux-2.6.0-test1/arch/x86_64/kernel/reboot.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/arch/x86_64/kernel/reboot.c	2003-07-19 17:04:07.000000000 -0700
-@@ -110,7 +110,7 @@ static void smp_halt(void)
- 	}
- 
- 	/* Wait for all other CPUs to have run smp_stop_cpu */
--	while (cpu_online_map) 
-+	while (!cpus_empty(cpu_online_map))
- 		rep_nop(); 
- }
- #endif
---- linux-2.6.0-test1/arch/x86_64/kernel/setup.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/arch/x86_64/kernel/setup.c	2003-07-19 17:04:07.000000000 -0700
-@@ -643,7 +643,7 @@ static int show_cpuinfo(struct seq_file 
- 
- 
- #ifdef CONFIG_SMP
--	if (!(cpu_online_map & (1<<(c-cpu_data))))
-+	if (!cpu_online(c-cpu_data))
- 		return 0;
- #endif
- 
---- linux-2.6.0-test1/arch/x86_64/kernel/smpboot.c	2003-06-16 22:32:20.000000000 -0700
-+++ 25/arch/x86_64/kernel/smpboot.c	2003-07-19 17:04:07.000000000 -0700
-@@ -54,11 +54,11 @@
- #include <asm/proto.h>
- 
- /* Bitmask of currently online CPUs */
--unsigned long cpu_online_map = 1;
-+cpumask_t cpu_online_map;
- 
--static volatile unsigned long cpu_callin_map;
--volatile unsigned long cpu_callout_map;
--static unsigned long smp_commenced_mask;
-+static cpumask_t cpu_callin_map;
-+cpumask_t cpu_callout_map;
-+static cpumask_t smp_commenced_mask;
- 
- /* Per CPU bogomips and other parameters */
- struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-@@ -174,7 +174,7 @@ static void __init synchronize_tsc_bp (v
- 
- 	sum = 0;
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (test_bit(i, &cpu_callout_map)) {
-+		if (cpu_isset(i, cpu_callout_map)) {
- 		t0 = tsc_values[i];
- 		sum += t0;
- 	}
-@@ -183,7 +183,7 @@ static void __init synchronize_tsc_bp (v
- 
- 	sum = 0;
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (!test_bit(i, &cpu_callout_map))
-+		if (!cpu_isset(i, cpu_callout_map))
- 			continue;
- 
- 		delta = tsc_values[i] - avg;
-@@ -258,7 +258,7 @@ void __init smp_callin(void)
- 	 */
- 	phys_id = GET_APIC_ID(apic_read(APIC_ID));
- 	cpuid = smp_processor_id();
--	if (test_and_set_bit(cpuid, &cpu_callin_map)) {
-+	if (cpu_test_and_set(cpuid, cpu_callin_map)) {
- 		panic("smp_callin: phys CPU#%d, CPU#%d already present??\n",
- 					phys_id, cpuid);
- 	}
-@@ -280,7 +280,7 @@ void __init smp_callin(void)
- 		/*
- 		 * Has the boot CPU finished it's STARTUP sequence?
- 		 */
--		if (test_bit(cpuid, &cpu_callout_map))
-+		if (cpu_isset(cpuid, cpu_callout_map))
- 			break;
- 		rep_nop();
- 	}
-@@ -320,7 +320,7 @@ void __init smp_callin(void)
- 	/*
- 	 * Allow the master to continue.
- 	 */
--	set_bit(cpuid, &cpu_callin_map);
-+	cpu_set(cpuid, cpu_callin_map);
- 
- 	/*
- 	 *      Synchronize the TSC with the BP
-@@ -348,7 +348,7 @@ void __init start_secondary(void)
- 	barrier();
- 
- 	Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); 
--	while (!test_bit(smp_processor_id(), &smp_commenced_mask))
-+	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
- 		rep_nop();
- 
- 	Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); 	
-@@ -372,7 +372,7 @@ void __init start_secondary(void)
- 	local_flush_tlb();
- 
- 	Dprintk("cpu %d eSetting cpu_online_map\n", smp_processor_id()); 
--	set_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
- 	wmb();
- 	
- 	cpu_idle();
-@@ -630,19 +630,19 @@ static void __init do_boot_cpu (int apic
- 		 * allow APs to start initializing.
- 		 */
- 		Dprintk("Before Callout %d.\n", cpu);
--		set_bit(cpu, &cpu_callout_map);
-+		cpu_set(cpu, cpu_callout_map);
- 		Dprintk("After Callout %d.\n", cpu);
- 
- 		/*
- 		 * Wait 5s total for a response
- 		 */
- 		for (timeout = 0; timeout < 50000; timeout++) {
--			if (test_bit(cpu, &cpu_callin_map))
-+			if (cpu_isset(cpu, cpu_callin_map))
- 				break;	/* It has booted */
- 			udelay(100);
- 		}
- 
--		if (test_bit(cpu, &cpu_callin_map)) {
-+		if (cpu_isset(cpu, cpu_callin_map)) {
- 			/* number CPUs logically, starting from 1 (BSP is 0) */
- 			Dprintk("OK.\n");
- 			printk(KERN_INFO "CPU%d: ", cpu);
-@@ -663,7 +663,7 @@ static void __init do_boot_cpu (int apic
- 		}
- 	}
- 	if (boot_error) {
--		clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */
-+		cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
- 		clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
- 		cpucount--;
- 	}
-@@ -734,10 +734,10 @@ static void __init smp_boot_cpus(unsigne
- 	current_thread_info()->cpu = 0;
- 	smp_tune_scheduling();
- 
--	if (!test_bit(hard_smp_processor_id(), &phys_cpu_present_map)) {
-+	if (!cpu_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
- 		printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
- 		       hard_smp_processor_id());
--		phys_cpu_present_map |= (1 << hard_smp_processor_id());
-+		cpu_set(hard_smp_processor_id(), phys_cpu_present_map);
- 	}
- 
- 	/*
-@@ -747,8 +747,8 @@ static void __init smp_boot_cpus(unsigne
- 	if (!smp_found_config) {
- 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
- 		io_apic_irqs = 0;
--		cpu_online_map = phys_cpu_present_map = 1;
--		phys_cpu_present_map = 1;
-+		cpu_online_map = cpumask_of_cpu(0);
-+		phys_cpu_present_map = cpumask_of_cpu(0);
- 		if (APIC_init_uniprocessor())
- 			printk(KERN_NOTICE "Local APIC not detected."
- 					   " Using dummy APIC emulation.\n");
-@@ -759,10 +759,10 @@ static void __init smp_boot_cpus(unsigne
- 	 * Should not be necessary because the MP table should list the boot
- 	 * CPU too, but we do it for the sake of robustness anyway.
- 	 */
--	if (!test_bit(boot_cpu_id, &phys_cpu_present_map)) {
-+	if (!cpu_isset(boot_cpu_id, phys_cpu_present_map)) {
- 		printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n",
- 								 boot_cpu_id);
--		phys_cpu_present_map |= (1 << hard_smp_processor_id());
-+		cpu_set(hard_smp_processor_id(), phys_cpu_present_map);
- 	}
- 
- 	/*
-@@ -773,8 +773,8 @@ static void __init smp_boot_cpus(unsigne
- 			boot_cpu_id);
- 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
- 		io_apic_irqs = 0;
--		cpu_online_map = phys_cpu_present_map = 1;
--		phys_cpu_present_map = 1;
-+		cpu_online_map = cpumask_of_cpu(0);
-+		phys_cpu_present_map = cpumask_of_cpu(0);
- 		disable_apic = 1;
- 		goto smp_done;
- 	}
-@@ -788,8 +788,8 @@ static void __init smp_boot_cpus(unsigne
- 		smp_found_config = 0;
- 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
- 		io_apic_irqs = 0;
--		cpu_online_map = phys_cpu_present_map = 1;
--		phys_cpu_present_map = 1;
-+		cpu_online_map = cpumask_of_cpu(0);
-+		phys_cpu_present_map = cpumask_of_cpu(0);
- 		disable_apic = 1;
- 		goto smp_done;
- 	}
-@@ -812,7 +812,7 @@ static void __init smp_boot_cpus(unsigne
- 		if (apicid == boot_cpu_id)
- 			continue;
- 
--		if (!(phys_cpu_present_map & (1 << apicid)))
-+		if (!cpu_isset(apicid, phys_cpu_present_map))
- 			continue;
- 		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
- 			continue;
-@@ -848,7 +848,7 @@ static void __init smp_boot_cpus(unsigne
- 	} else {
- 		unsigned long bogosum = 0;
- 		for (cpu = 0; cpu < NR_CPUS; cpu++)
--			if (cpu_callout_map & (1<<cpu))
-+			if (cpu_isset(cpu, cpu_callout_map))
- 				bogosum += cpu_data[cpu].loops_per_jiffy;
- 		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
- 			cpucount+1,
-@@ -889,20 +889,20 @@ void __init smp_prepare_cpus(unsigned in
- 
- void __devinit smp_prepare_boot_cpu(void)
- {
--	set_bit(smp_processor_id(), &cpu_online_map);
--	set_bit(smp_processor_id(), &cpu_callout_map);
-+	cpu_set(smp_processor_id(), cpu_online_map);
-+	cpu_set(smp_processor_id(), cpu_callout_map);
- }
- 
- int __devinit __cpu_up(unsigned int cpu)
- {
- 	/* This only works at boot for x86.  See "rewrite" above. */
--	if (test_bit(cpu, &smp_commenced_mask)) { 
-+	if (cpu_isset(cpu, smp_commenced_mask)) {
- 		local_irq_enable();
- 		return -ENOSYS;
- 	}
- 
- 	/* In case one didn't come up */
--	if (!test_bit(cpu, &cpu_callin_map)) { 
-+	if (!cpu_isset(cpu, cpu_callin_map)) {
- 		local_irq_enable();
- 		return -EIO;
- 	}
-@@ -911,8 +911,8 @@ int __devinit __cpu_up(unsigned int cpu)
- 	/* Unleash the CPU! */
- 	Dprintk("waiting for cpu %d\n", cpu);
- 
--	set_bit(cpu, &smp_commenced_mask);
--	while (!test_bit(cpu, &cpu_online_map))
-+	cpu_set(cpu, smp_commenced_mask);
-+	while (!cpu_isset(cpu, cpu_online_map))
- 		mb();
- 	return 0;
- }
---- linux-2.6.0-test1/arch/x86_64/kernel/smp.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/arch/x86_64/kernel/smp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -92,8 +92,9 @@ void send_IPI_self(int vector)
- 	__send_IPI_shortcut(APIC_DEST_SELF, vector);
- }
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t cpumask, int vector)
- {
-+	unsigned long mask = cpus_coerce(cpumask);
- 	unsigned long cfg;
- 	unsigned long flags;
- 
-@@ -133,7 +134,7 @@ static inline void send_IPI_mask(int mas
-  *	Optimizations Manfred Spraul <manfred@colorfullife.com>
-  */
- 
--static volatile unsigned long flush_cpumask;
-+static volatile cpumask_t flush_cpumask;
- static struct mm_struct * flush_mm;
- static unsigned long flush_va;
- static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
-@@ -203,7 +204,7 @@ asmlinkage void smp_invalidate_interrupt
- 
- 	cpu = get_cpu();
- 
--	if (!test_bit(cpu, &flush_cpumask))
-+	if (!cpu_isset(cpu, flush_cpumask))
- 		goto out;
- 		/* 
- 		 * This was a BUG() but until someone can quote me the
-@@ -224,15 +225,16 @@ asmlinkage void smp_invalidate_interrupt
- 			leave_mm(cpu);
- 	}
- 	ack_APIC_irq();
--	clear_bit(cpu, &flush_cpumask);
-+	cpu_clear(cpu, flush_cpumask);
- 
- out:
- 	put_cpu_no_resched();
- }
- 
--static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
-+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
- 						unsigned long va)
- {
-+	cpumask_t tmp;
- 	/*
- 	 * A couple of (to be removed) sanity checks:
- 	 *
-@@ -240,12 +242,10 @@ static void flush_tlb_others (unsigned l
- 	 * - current CPU must not be in mask
- 	 * - mask must exist :)
- 	 */
--	if (!cpumask)
--		BUG();
--	if ((cpumask & cpu_online_map) != cpumask)
--		BUG();
--	if (cpumask & (1 << smp_processor_id()))
--		BUG();
-+	BUG_ON(cpus_empty(cpumask));
-+	cpus_and(tmp, cpumask, cpu_online_map);
-+	BUG_ON(!cpus_equal(tmp, cpumask));
-+	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
- 	if (!mm)
- 		BUG();
- 
-@@ -259,14 +259,15 @@ static void flush_tlb_others (unsigned l
- 	
- 	flush_mm = mm;
- 	flush_va = va;
--	atomic_set_mask(cpumask, &flush_cpumask);
-+	cpus_or(flush_cpumask, cpumask, flush_cpumask);
-+
- 	/*
- 	 * We have to send the IPI only to
- 	 * CPUs affected.
- 	 */
- 	send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
- 
--	while (flush_cpumask)
-+	while (!cpus_empty(flush_cpumask))
- 		/* nothing. lockup detection does not belong here */;
- 
- 	flush_mm = NULL;
-@@ -277,23 +278,25 @@ static void flush_tlb_others (unsigned l
- void flush_tlb_current_task(void)
- {
- 	struct mm_struct *mm = current->mm;
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	local_flush_tlb();
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
- 	preempt_enable();
- }
- 
- void flush_tlb_mm (struct mm_struct * mm)
- {
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	if (current->active_mm == mm) {
- 		if (current->mm)
-@@ -301,7 +304,7 @@ void flush_tlb_mm (struct mm_struct * mm
- 		else
- 			leave_mm(smp_processor_id());
- 	}
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
- 
- 	preempt_enable();
-@@ -310,10 +313,11 @@ void flush_tlb_mm (struct mm_struct * mm
- void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
- {
- 	struct mm_struct *mm = vma->vm_mm;
--	unsigned long cpu_mask;
-+	cpumask_t cpu_mask;
- 
- 	preempt_disable();
--	cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
-+	cpu_mask = mm->cpu_vm_mask;
-+	cpu_clear(smp_processor_id(), cpu_mask);
- 
- 	if (current->active_mm == mm) {
- 		if(current->mm)
-@@ -322,7 +326,7 @@ void flush_tlb_page(struct vm_area_struc
- 		 	leave_mm(smp_processor_id());
- 	}
- 
--	if (cpu_mask)
-+	if (!cpus_empty(cpu_mask))
- 		flush_tlb_others(cpu_mask, mm, va);
- 
- 	preempt_enable();
-@@ -355,7 +359,7 @@ void smp_kdb_stop(void)
- 
- void smp_send_reschedule(int cpu)
- {
--	send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
-+	send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
- }
- 
- /*
-@@ -430,7 +434,7 @@ void smp_stop_cpu(void)
- 	/*
- 	 * Remove this CPU:
- 	 */
--	clear_bit(smp_processor_id(), &cpu_online_map);
-+	cpu_clear(smp_processor_id(), cpu_online_map);
- 	local_irq_disable();
- 	disable_local_APIC();
- 	local_irq_enable(); 
-@@ -491,8 +495,8 @@ int slow_smp_processor_id(void)
- 	unsigned long sp = (unsigned long)&stack_location; 
- 	int offset = 0, cpu;
- 
--	for (offset = 0; (cpu_online_map >> offset); offset = cpu + 1) { 
--		cpu = ffz(~(cpu_online_map >> offset));
-+	for (offset = 0; next_cpu(offset, cpu_online_map) < NR_CPUS; offset = cpu + 1) {
-+		cpu = next_cpu(offset, cpu_online_map);
- 
- 		if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && 
- 		    sp <= (u64)cpu_pda[cpu].irqstackptr)
---- linux-2.6.0-test1/arch/x86_64/mm/init.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/x86_64/mm/init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -19,9 +19,6 @@
- #include <linux/swap.h>
- #include <linux/smp.h>
- #include <linux/init.h>
--#ifdef CONFIG_BLK_DEV_INITRD
--#include <linux/blk.h>
--#endif
- #include <linux/pagemap.h>
- #include <linux/bootmem.h>
- #include <linux/proc_fs.h>
---- linux-2.6.0-test1/arch/x86_64/mm/ioremap.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/arch/x86_64/mm/ioremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -82,7 +82,7 @@ static int remap_area_pages(unsigned lon
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
- 		pmd_t *pmd;
--		pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
---- linux-2.6.0-test1/arch/x86_64/mm/numa.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/arch/x86_64/mm/numa.c	2003-07-19 17:03:49.000000000 -0700
-@@ -8,7 +8,6 @@
- #include <linux/init.h>
- #include <linux/bootmem.h>
- #include <linux/mmzone.h>
--#include <linux/blk.h>
- #include <linux/ctype.h>
- #include <asm/e820.h>
- #include <asm/proto.h>
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/fb/neofb.txt	2003-07-19 17:04:55.000000000 -0700
-@@ -0,0 +1,27 @@
-+the neofb framebuffer driver supports the following Neomagic chipsets:
-+
-+NM2070 MagicGraph 128
-+NM2090 MagicGraph 128V
-+NM2093 MagicGraph 128ZV
-+NM2097 MagicGraph 128ZV+
-+NM2160 MagicGraph 128XD
-+NM2200 MagicGraph 256AV
-+NM2230 MagicGraph 256AV+
-+NM2360 MagicGraph 256ZX
-+NM2380 MagicGraph 256XL+
-+
-+with the following options:
-+
-+disabled	Disable this driver's initialization.
-+internal	Enable output on internal LCD Display.
-+external	Enable output on external CRT.
-+nostretch	Disable stretching of modes smaller than LCD.
-+nopciburst	Disable PCI burst mode.
-+libretto	Force Libretto 100/110 800x480 LCD.
-+picturebook	Force Picturebook 1024x480 LCD.
-+
-+at the boot prompt:
-+	video=neofb:picturebook
-+
-+as a module:
-+	modprobe neofb picturebook=1
---- linux-2.6.0-test1/Documentation/filesystems/proc.txt	2003-06-26 22:07:24.000000000 -0700
-+++ 25/Documentation/filesystems/proc.txt	2003-07-19 17:04:56.000000000 -0700
-@@ -222,6 +222,7 @@ Table 1-3: Kernel info in /proc 
-  partitions  Table of partitions known to the system           
-  pci	     Depreciated info of PCI bus (new way -> /proc/bus/pci/, 
-              decoupled by lspci					(2.4)
-+ rcu	     Read-Copy Update information			(2.5)
-  rtc         Real time clock                                   
-  scsi        SCSI info (see text)                              
-  slabinfo    Slab pool info                                    
-@@ -346,6 +347,9 @@ available.  In this case, there are 0 ch
- ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE 
- available in ZONE_NORMAL, etc... 
- 
-+The rcu file gives information about Read-Copy Update synchronization
-+primitive. It indicates the number for RCU requests and actual
-+updates for every CPU.
- 
- 1.3 IDE devices in /proc/ide
- ----------------------------
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/andthen	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,100 @@
-+
-+define	set_andthen
-+	set var $thp=0
-+	set var $thp=(struct kgdb_and_then_struct *)&kgdb_data[0]
-+	set var $at_size = (sizeof kgdb_data)/(sizeof *$thp)
-+	set var $at_oc=kgdb_and_then_count
-+	set var $at_cc=$at_oc
-+end
-+
-+define andthen_next
-+	set var $at_cc=$arg0
-+end
-+
-+define andthen
-+	andthen_set_edge
-+	if ($at_cc >= $at_oc)
-+		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
-+	else
-+		printf "%d: ",$at_cc
-+		output *($thp+($at_cc++ % $at_size ))
-+		printf "\n"
-+	end
-+end
-+define andthen_set_edge
-+	set var $at_oc=kgdb_and_then_count
-+	set var $at_low = $at_oc - $at_size
-+	if ($at_low < 0 )
-+		set var $at_low = 0
-+	end
-+	if (( $at_cc > $at_oc) || ($at_cc < $at_low))
-+		printf "Count outside of window, setting count to "
-+		if ($at_cc >= $at_oc)
-+			set var $at_cc = $at_oc
-+		else
-+			set var $at_cc = $at_low
-+		end
-+		printf "%d\n",$at_cc
-+	end
-+end
-+
-+define beforethat
-+	andthen_set_edge
-+	if ($at_cc <= $at_low)
-+		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
-+	else
-+		printf "%d: ",$at_cc-1
-+		output *($thp+(--$at_cc % $at_size ))
-+		printf "\n"
-+	end
-+end
-+
-+document andthen_next
-+	andthen_next <count>
-+	.	sets the number of the event to display next. If this event
-+	.	is not in the event pool, either andthen or beforethat will
-+	.	correct it to the nearest event pool edge.  The event pool
-+	.	ends at the last event recorded and begins <number of events>
-+	.	prior to that.  If beforethat is used next, it will display
-+	.	event <count> -1.
-+.
-+	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+	
-+			
-+document andthen
-+	andthen 
-+.	displays the next event in the list.  <set_andthen> sets up to display
-+.	the oldest saved event first. 
-+.	<count> (optional) count of the event to display.
-+.	note the number of events saved is specified at configure time.
-+.	if events are saved between calls to andthen the index will change
-+.	but the displayed event will be the next one (unless the event buffer
-+.	is overrun).
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+
-+document set_andthen
-+	set_andthen
-+.	sets up to use the <andthen> and <beforethat> commands. 
-+.		if you have defined your own struct, use the above and
-+.		then enter the following:
-+.		p $thp=(struct kgdb_and_then_structX *)&kgdb_data[0]
-+.		where <kgdb_and_then_structX> is the name of your structure.
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+
-+document beforethat
-+	beforethat 
-+.	displays the next prior event in the list. <set_andthen> sets up to
-+.	display the last occuring event first.
-+.
-+.	note the number of events saved is specified at configure time.
-+.	if events are saved between calls to beforethat the index will change
-+.	but the displayed event will be the next one (unless the event buffer
-+.	is overrun).
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/debug-nmi.txt	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,37 @@
-+Subject: Debugging with NMI
-+Date: Mon, 12 Jul 1999 11:28:31 -0500
-+From: David Grothe <dave@gcom.com>
-+Organization: Gcom, Inc
-+To: David Grothe <dave@gcom.com>
-+
-+Kernel hackers:
-+
-+Maybe this is old hat, but it is new to me --
-+
-+On an ISA bus machine, if you short out the A1 and B1 pins of an ISA
-+slot you will generate an NMI to the CPU.  This interrupts even a
-+machine that is hung in a loop with interrupts disabled.  Used in
-+conjunction with kgdb <
-+ftp://ftp.gcom.com/pub/linux/src/kgdb-2.3.35/kgdb-2.3.35.tgz > you can
-+gain debugger control of a machine that is hung in the kernel!  Even
-+without kgdb the kernel will print a stack trace so you can find out
-+where it was hung.
-+
-+The A1/B1 pins are directly opposite one another and the farthest pins
-+towards the bracket end of the ISA bus socket.  You can stick a paper
-+clip or multi-meter probe between them to short them out.
-+
-+I had a spare ISA bus to PC104 bus adapter around.  The PC104 end of the
-+board consists of two rows of wire wrap pins.  So I wired a push button
-+between the A1/B1 pins and now have an ISA board that I can stick into
-+any ISA bus slot for debugger entry.
-+
-+Microsoft has a circuit diagram of a PCI card at
-+http://www.microsoft.com/hwdev/DEBUGGING/DMPSW.HTM.  If you want to
-+build one you will have to mail them and ask for the PAL equations.
-+Nobody makes one comercially.
-+
-+[THIS TIP COMES WITH NO WARRANTY WHATSOEVER.  It works for me, but if
-+your machine catches fire, it is your problem, not mine.]
-+
-+-- Dave (the kgdb guy)
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/gdb-globals.txt	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,71 @@
-+Sender: akale@veritas.com
-+Date: Fri, 23 Jun 2000 19:26:35 +0530
-+From: "Amit S. Kale" <akale@veritas.com>
-+Organization: Veritas Software (India)
-+To: Dave Grothe <dave@gcom.com>, linux-kernel@vger.rutgers.edu
-+CC: David Milburn <dmilburn@wirespeed.com>,
-+        "Edouard G. Parmelan" <Edouard.Parmelan@quadratec.fr>,
-+        ezannoni@cygnus.com, Keith Owens <kaos@ocs.com.au>
-+Subject: Re: Module debugging using kgdb
-+
-+Dave Grothe wrote:
-+> 
-+> Amit:
-+> 
-+> There is a 2.4.0 version of kgdb on our ftp site:
-+> ftp://ftp.gcom.com/pub/linux/src/kgdb.  I mirrored your version of gdb
-+> and loadmodule.sh there.
-+> 
-+> Have a look at the README file and see if I go it right.  If not, send
-+> me some corrections and I will update it.
-+> 
-+> Does your version of gdb solve the global variable problem?
-+
-+Yes. 
-+Thanks to Elena Zanoni, gdb (developement version) can now calculate 
-+correctly addresses  of dynamically loaded object files. I have not been 
-+following gdb developement for sometime and am not sure when symbol
-+address calculation fix is going to appear in a gdb stable version.
-+
-+Elena, any idea when the fix will make it to a prebuilt gdb from a
-+redhat release?
-+
-+For the time being I have built a gdb developement version. It can be
-+used for module debugging with loadmodule.sh script.
-+
-+The problem with calculating of module addresses with previous versions
-+of gdb was as follows:
-+gdb did not use base address of a section while calculating address of
-+a symbol in the section in an object file loaded via 'add-symbol-file'. 
-+It used address of .text segment instead. Due to this addresses of
-+symbols in .data, .bss etc. (e.g. global variables) were calculated incorrectly.
-+
-+Above mentioned fix allow gdb to use base address of a segment while
-+calculating address of a symbol in it. It adds a parameter '-s' to
-+'add-symbol-file' command for specifying base address of a segment.
-+
-+loadmodule.sh script works as follows.
-+
-+1. Copy a module file to target machine.
-+2. Load the module on the target machine using insmod with -m parameter.
-+insmod produces a module load map which contains base addresses of all
-+sections in the module and addresses of symbols in the module file.
-+3. Find all sections and their base addresses in the module from 
-+the module map.
-+4. Generate a script that loads the module file. The script uses
-+'add-symbol-file' and specifies address of text segment followed by
-+addresses of all segments in the module.
-+
-+Here is an example gdb script produced by loadmodule.sh script.
-+
-+add-symbol-file foo 0xd082c060 -s .text.lock 0xd08cbfb5 
-+-s .fixup 0xd08cfbdf -s .rodata 0xd08cfde0 -s __ex_table 0xd08e3b38 
-+-s .data 0xd08e3d00 -s .bss 0xd08ec8c0 -s __ksymtab 0xd08ee838
-+
-+With this command gdb can calculate addresses of symbols in ANY segment
-+in a module file.
-+
-+Regards.
-+-- 
-+Amit Kale
-+Veritas Software ( http://www.veritas.com )
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/gdbinit	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,14 @@
-+shell echo -e "\003" >/dev/ttyS0
-+set remotebaud 38400
-+target remote /dev/ttyS0
-+define si
-+stepi
-+printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
-+printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
-+x/i $eip
-+end
-+define ni
-+nexti
-+printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
-+printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
-+x/i $eip
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/gdbinit.hw	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,117 @@
-+
-+#Using ia-32 hardware breakpoints.
-+#
-+#4 hardware breakpoints are available in ia-32 processors. These breakpoints
-+#do not need code modification. They are set using debug registers.
-+#
-+#Each hardware breakpoint can be of one of the
-+#three types: execution, write, access.
-+#1. An Execution breakpoint is triggered when code at the breakpoint address is
-+#executed.
-+#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
-+#at the breakpoint address is written.
-+#3. An access breakpoint is triggered when memory location at the breakpoint
-+#address is either read or written.
-+#
-+#As hardware breakpoints are available in limited number, use software
-+#breakpoints ( br command in gdb ) instead of execution hardware breakpoints.
-+#
-+#Length of an access or a write breakpoint defines length of the datatype to
-+#be watched. Length is 1 for char, 2 short , 3 int.
-+#
-+#For placing execution, write and access breakpoints, use commands
-+#hwebrk, hwwbrk, hwabrk
-+#To remove a breakpoint use hwrmbrk command.
-+#
-+#These commands take following types of arguments. For arguments associated
-+#with each command, use help command.
-+#1. breakpointno: 0 to 3
-+#2. length: 1 to 3
-+#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
-+#
-+#Use the command exinfo to find which hardware breakpoint occured.
-+
-+#hwebrk breakpointno address
-+define hwebrk
-+	maintenance packet Y$arg0,0,0,$arg1
-+end
-+document hwebrk
-+	hwebrk <breakpointno> <address>
-+	Places a hardware execution breakpoint
-+	<breakpointno> = 0 - 3
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwwbrk breakpointno length address
-+define hwwbrk
-+	maintenance packet Y$arg0,1,$arg1,$arg2
-+end
-+document hwwbrk
-+	hwwbrk <breakpointno> <length> <address>
-+	Places a hardware write breakpoint
-+	<breakpointno> = 0 - 3
-+	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwabrk breakpointno length address
-+define hwabrk
-+	maintenance packet Y$arg0,1,$arg1,$arg2
-+end
-+document hwabrk
-+	hwabrk <breakpointno> <length> <address>
-+	Places a hardware access breakpoint
-+	<breakpointno> = 0 - 3
-+	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwrmbrk breakpointno
-+define hwrmbrk
-+	maintenance packet y$arg0
-+end
-+document hwrmbrk
-+	hwrmbrk <breakpointno>
-+	<breakpointno> = 0 - 3
-+	Removes a hardware breakpoint
-+end
-+
-+define reboot
-+        maintenance packet r
-+end
-+#exinfo 
-+define exinfo
-+	maintenance packet qE
-+end
-+document exinfo
-+	exinfo 
-+	Gives information about a breakpoint.
-+end
-+define get_th
-+	p $th=(struct thread_info *)((int)$esp & ~8191)
-+end
-+document get_th
-+	get_tu
-+	Gets and prints the current thread_info pointer, Defines th to be it.
-+end
-+define get_cu
-+	p $cu=(struct thread_info *)((int)$esp & ~8191)->task
-+end
-+document get_cu
-+	get_cu
-+	Gets and print the "current" value.  Defines $cu to be it.
-+end
-+define int_off
-+	set var $flags=$eflags
-+	set $eflags=$eflags&~0x200
-+	end
-+define int_on
-+	set var $eflags|=$flags&0x200
-+	end
-+document int_off
-+	saves the current interrupt state and clears the processor interrupt 
-+	flag.  Use int_on to restore the saved flag.
-+end
-+document int_on
-+	Restores the interrupt flag saved by int_off.
-+end
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/gdbinit-modules	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,146 @@
-+#
-+# Usefull GDB user-command to debug Linux Kernel Modules with gdbstub.
-+#
-+# This don't work for Linux-2.0 or older.
-+#
-+# Author Edouard G. Parmelan <Edouard.Parmelan@quadratec.fr>
-+#
-+#
-+# Fri Apr 30 20:33:29 CEST 1999
-+#   First public release.
-+#
-+#   Major cleanup after experiment Linux-2.0 kernel without success.
-+#   Symbols of a module are not in the correct order, I can't explain
-+#   why :(
-+#
-+# Fri Mar 19 15:41:40 CET 1999
-+#   Initial version.
-+#
-+# Thu Jan  6 16:29:03 CST 2000
-+#   A little fixing by Dave Grothe <dave@gcom.com>
-+#
-+# Mon Jun 19 09:33:13 CDT 2000
-+#   Alignment changes from Edouard Parmelan
-+#
-+# The basic idea is to find where insmod load the module and inform
-+# GDB to load the symbol table of the module with the GDB command 
-+# ``add-symbol-file <object> <address>''.
-+#
-+# The Linux kernel holds the list of all loaded modules in module_list,
-+# this list end with &kernel_module (exactly with module->next == NULL,
-+# but the last module is not a real module).
-+#
-+# Insmod allocates the struct module before the object file.  Since
-+# Linux-2.1, this structure contain his size.  The real address of
-+# the object file is then (char*)module + module->size_of_struct.
-+#
-+# You can use three user functions ``mod-list'', ``mod-print-symbols''
-+# and ``add-module-symbols''.
-+#
-+# mod-list list all loaded modules with the format:
-+#    <module-address> <module-name>
-+#
-+# As soon as you have found the address of your module, you can
-+# print its exported symbols (mod-print-symbols) or inform GDB to add
-+# symbols from your module file (mod-add-symbols).
-+#
-+# The argument that you give to mod-print-symbols or mod-add-symbols
-+# is the <module-address> from the mod-list command.
-+#
-+# When using the mod-add-symbols command you must also give the full
-+# pathname of the modules object code file.
-+#
-+# The command mod-add-lis is an example of how to make this easier.
-+# You can edit this macro to contain the path name of your own
-+# favorite module and then use it as a shorthand to load it.  You
-+# still need the module-address, however.
-+#
-+# The internal function ``mod-validate'' set the GDB variable $mod
-+# as a ``struct module*'' if the kernel known the module otherwise
-+# $mod is set to NULL.  This ensure to not add symbols for a wrong
-+# address.
-+# 
-+# Have a nice hacking day !
-+#
-+#
-+define mod-list
-+    set $mod = (struct module*)module_list
-+    # the last module is the kernel, ignore it
-+    while $mod != &kernel_module
-+    	printf "%p\t%s\n", (long)$mod, ($mod)->name
-+	set $mod = $mod->next
-+    end
-+end
-+document mod-list
-+List all modules in the form: <module-address> <module-name>
-+Use the <module-address> as the argument for the other
-+mod-commands: mod-print-symbols, mod-add-symbols.
-+end
-+
-+define mod-validate
-+    set $mod = (struct module*)module_list
-+    while ($mod != $arg0) && ($mod != &kernel_module)
-+    	set $mod = $mod->next
-+    end
-+    if $mod == &kernel_module
-+	set $mod = 0
-+    	printf "%p is not a module\n", $arg0
-+    end
-+end
-+document mod-validate
-+mod-validate <module-address>
-+Internal user-command used to validate the module parameter.
-+If <module> is a real loaded module, set $mod to it otherwise set $mod to 0.
-+end
-+
-+
-+define mod-print-symbols
-+    mod-validate $arg0
-+    if $mod != 0
-+	set $i = 0
-+	while $i < $mod->nsyms
-+	    set $sym = $mod->syms[$i]
-+	    printf "%p\t%s\n", $sym->value, $sym->name
-+	    set $i = $i + 1
-+	end
-+    end
-+end
-+document mod-print-symbols
-+mod-print-symbols <module-address>
-+Print all exported symbols of the module.  see mod-list
-+end
-+
-+
-+define mod-add-symbols-align
-+    mod-validate $arg0
-+    if $mod != 0
-+	set $mod_base = ($mod->size_of_struct + (long)$mod)
-+	if ($arg2 != 0) && (($mod_base & ($arg2 - 1)) != 0)
-+	    set $mod_base = ($mod_base | ($arg2 - 1)) + 1
-+	end
-+	add-symbol-file $arg1 $mod_base
-+    end
-+end
-+document mod-add-symbols-align
-+mod-add-symbols-align <module-address> <object file path name> <align>
-+Load the symbols table of the module from the object file where
-+first section aligment is <align>.
-+To retreive alignment, use `objdump -h <object file path name>'.
-+end
-+
-+define mod-add-symbols
-+    mod-add-symbols-align $arg0 $arg1 sizeof(long)
-+end
-+document mod-add-symbols
-+mod-add-symbols <module-address> <object file path name>
-+Load the symbols table of the module from the object file.
-+Default alignment is 4.  See mod-add-symbols-align.
-+end
-+
-+define mod-add-lis
-+    mod-add-symbols-align $arg0 /usr/src/LiS/streams.o 16
-+end
-+document mod-add-lis
-+mod-add-lis <module-address>
-+Does mod-add-symbols <module-address> /usr/src/LiS/streams.o
-+end
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/kgdb.txt	2003-07-19 17:04:05.000000000 -0700
-@@ -0,0 +1,716 @@
-+Last edit: <20030506.1615.42>
-+This file has information specific to the i386 kgdb option.  Other
-+platforms with the kgdb option may behave in a similar fashion.
-+
-+New features: 
-+============
-+20030505.1827.27
-+We are starting to align with the sourceforge version, at least in 
-+commands.  To this end, the boot command string to start kgdb at
-+boot time has been changed from "kgdb" to "gdb".
-+
-+Andrew Morton sent a couple of patches which are now included as follows:
-+1.) We now return a flag to the interrupt handler.
-+2.) We no longer use smp_num_cpus (a conflict with the lock meter).
-+3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
-+    sure high-mem is set up before we attempt to register our interrupt
-+    handler.
-+We now include asm/kgdb.h from config.h so you will most likely never
-+have to include it.  It also 'NULLS' the kgdb macros you might have in
-+your code when CONFIG_KGDB is not defined.  This allows you to just
-+turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
-+This include is conditioned on the machine being an x86 so as to not
-+mess with other archs.
-+
-+20020801.1129.03
-+This is currently the version for the 2.4.18 (and beyond?) kernel.
-+
-+We have several new "features" beginning with this version:
-+ 
-+1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI.  No more
-+    waiting and it will pull that guy out of an IRQ off spin lock :)
-+
-+2.) We doctored up the code that tells where a task is waiting and
-+    included it so that the "info thread" command will show a bit more
-+    than "schedule()".  Try it...
-+
-+3.) Added the ability to call a function from gdb.  All the standard gdb
-+    issues apply, i.e. if you hit a breakpoint in the function, you are
-+    not allowed to call another (gdb limitation, not kgdb).  To help
-+    this capability we added a memory allocation function.  Gdb does not
-+    return this memory (it is used for strings that you pass to that function
-+    you are calling from gdb) so we fixed up a way to allow you to
-+    manually return the memory (see below).
-+
-+4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
-+    interrupt flag to now also include the preemption count and the
-+    "in_interrupt" info.  The flag is now called "with_pif" to indicate
-+    the order, preempt_count, in_interrupt, flag.  The preempt_count is
-+    shifted left by 4 bits so you can read the count in hex by dropping
-+    the low order digit.  In_interrupt is in bit 1, and the flag is in
-+    bit 0.
-+
-+5.) The command: "p kgdb_info" is now expanded and prints something
-+    like:
-+(gdb) p kgdb_info
-+$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259, 
-+  errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1, 
-+  cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0, 
-+      regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
-+    
-+    Things to note here: a.) used_malloc is the amount of memory that
-+    has been malloc'ed to do calls from gdb.  You can reclaim this
-+    memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
-+    cpus_waiting is now "sized" by the number of CPUs you enter at
-+    configure time in the kgdb configure section.  This is NOT used
-+    anywhere else in the system, but it is "nice" here.  c.)  The task's
-+    "pid" is now in the structure.  This is the pid you will need to use
-+    to decode to the thread id to get gdb to look at that thread.
-+    Remember that the "info thread" command prints a list of threads
-+    wherein it numbers each thread with its reference number followed
-+    by the thread's pid.  Note that the per-CPU idle threads actually
-+    have pids of 0 (yes, there is more than one pid 0 in an SMP system).
-+    To avoid confusion, kgdb numbers these threads with numbers beyond
-+    the MAX_PID.  That is why you see 32768 and above.
-+
-+6.) A subtle change, we now provide the complete register set for tasks
-+    that are active on the other CPUs.  This allows better trace back on
-+    those tasks.
-+
-+    And, let's mention what we could not fix.  Back-trace from all but the
-+    thread that we trapped will, most likely, have a bogus entry in it.
-+    The problem is that gdb does not recognize the entry code for
-+    functions that use "current" near (at all?) the entry.  The compiler
-+    is putting the "current" decode as the first two instructions of the
-+    function where gdb expects to find %ebp changing code.  Back trace
-+    also has trouble with interrupt frames.  I am talking with Daniel
-+    Jacobowitz about some way to fix this, but don't hold your breath.
-+
-+20011220.0050.35
-+Major enhancement with this version is the ability to hold one or more
-+CPUs in an SMP system while allowing the others to continue.  Also, by
-+default only the current CPU is enabled on single-step commands (please
-+note that gdb issues single-step commands at times other than when you
-+use the si command).
-+ 
-+Another change is to collect some useful information in
-+a global structure called "kgdb_info".  You should be able to just:
-+
-+p kgdb_info
-+
-+although I have seen cases where the first time this is done gdb just
-+prints the first member but prints the whole structure if you then enter
-+CR (carriage return or enter).  This also works:
-+
-+p *&kgdb_info
-+
-+Here is a sample:
-+(gdb) p kgdb_info
-+$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0, 
-+  vector = 3, print_debug_info = 0}
-+
-+"Called_from" is the return address from the current entry into kgdb.  
-+Sometimes it is useful to know why you are in kgdb, for example, was 
-+it an NMI or a real breakpoint?  The simple way to interrogate this
-+return address is:
-+
-+l *0xc010732c
-+
-+which will print the surrounding few lines of source code.
-+
-+"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
-+kgdb_ts entries).
-+
-+"errcode" and "vector" are other entry parameters which may be helpful on
-+some traps.
-+
-+"print_debug_info" is the internal debugging kgdb print enable flag.  Yes,
-+you can modify it.
-+
-+In SMP systems kgdb_info also includes the "cpus_waiting" structure and
-+"hold_on_step": 
-+
-+(gdb) p kgdb_info
-+$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0, 
-+  vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
-+      task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0, 
-+      regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}}}
-+
-+"Cpus_waiting" has an entry for each CPU other than the current one that
-+has been stopped.  Each entry contains the task_struct address for that
-+CPU, the address of the regs for that task and a hold flag.  All these
-+have the proper typing so that, for example:
-+
-+p *kgdb_info.cpus_waiting[1].regs
-+
-+will print the registers for CPU 1.
-+
-+"Hold_on_sstep" is a new feature with this version and comes up set or
-+true.  What this means is that whenever kgdb is asked to single-step all
-+other CPUs are held (i.e. not allowed to execute).  The flag applies to
-+all but the current CPU and, again, can be changed:
-+
-+p kgdb_info.hold_on_sstep=0
-+
-+restores the old behavior of letting all CPUs run during single-stepping.
-+
-+Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
-+of execution.  Note that this has some risk in cases where the CPUs need
-+to communicate with each other.  If kgdb finds no CPU available on exit,
-+it will push a message thru gdb and stay in kgdb.  Note that it is legal
-+to hold the current CPU as long as at least one CPU can execute.
-+
-+20010621.1117.09
-+This version implements an event queue.  Events are signaled by calling
-+a function in the kgdb stub and may be examined from gdb.  See EVENTS 
-+below for details.  This version also tightens up the interrupt and SMP
-+handling to not allow interrupts on the way to kgdb from a breakpoint 
-+trap.  It is fine to allow these interrupts for user code, but not
-+system debugging.
-+
-+Version
-+=======
-+
-+This version of the kgdb package was developed and tested on
-+kernel version 2.4.16.  It will not install on any earlier kernels.  
-+It is possible that it will continue to work on later versions
-+of 2.4 and then versions of 2.5 (I hope).
-+
-+
-+Debugging Setup
-+===============
-+
-+Designate one machine as the "development" machine.  This is the
-+machine on which you run your compiles and which has your source
-+code for the kernel.  Designate a second machine as the "target"
-+machine.  This is the machine that will run your experimental
-+kernel.
-+
-+The two machines will be connected together via a serial line out
-+one or the other of the COM ports of the PC.  You will need the
-+appropriate modem eliminator (null modem) cable(s) for this.
-+
-+Decide on which tty port you want the machines to communicate, then
-+connect them up back-to-back using the null modem cable.  COM1 is
-+/dev/ttyS0 and COM2 is /dev/ttyS1. You should test this connection
-+with the two machines prior to trying to debug a kernel.  Once you
-+have it working, on the TARGET machine, enter:
-+
-+setserial /dev/ttyS0 (or what ever tty you are using)
-+
-+and record the port address and the IRQ number.
-+
-+On the DEVELOPMENT machine you need to apply the patch for the kgdb
-+hooks.  You have probably already done that if you are reading this
-+file.
-+
-+On your DEVELOPMENT machine, go to your kernel source directory and do
-+"make Xconfig" where X is one of "x", "menu", or "".  If you are
-+configuring in the standard serial driver, it must not be a module.
-+Either yes or no is ok, but making the serial driver a module means it
-+will initialize after kgdb has set up the UART interrupt code and may
-+cause a failure of the control-C option discussed below.  The configure
-+question for the serial driver is under the "Character devices" heading
-+and is:
-+
-+"Standard/generic (8250/16550 and compatible UARTs) serial support"
-+
-+Go down to the kernel debugging menu item and open it up.  Enable the
-+kernel kgdb stub code by selecting that item.  You can also choose to
-+turn on the "-ggdb -O1" compile options.  The -ggdb causes the compiler
-+to put more debug info (like local symbols) in the object file.  On the
-+i386 -g and -ggdb are the same so this option just reduces to "O1".  The
-+-O1 reduces the optimization level.  This may be helpful in some cases,
-+be aware, however, that this may also mask the problem you are looking
-+for.
-+
-+The baud rate.  Default is 115200.  What ever you choose be sure that
-+the host machine is set to the same speed.  I recommend the default.
-+
-+The port.  This is the I/O address of the serial UART that you should
-+have gotten using setserial as described above.  The standard COM1 port
-+(3f8) using IRQ 4 is default.  COM2 is 2f8 which by convention uses IRQ
-+3.
-+
-+The port IRQ (see above).
-+
-+Stack overflow test.  This option makes a minor change in the trap,
-+system call and interrupt code to detect stack overflow and transfer
-+control to kgdb if it happens.  (Some platforms have this in the
-+baseline code, but the i386 does not.)
-+
-+You can also configure the system to recognize the boot option
-+"console=kgdb" which if given will cause all console output during
-+booting to be put thru gdb as well as other consoles.  This option
-+requires that gdb and kgdb be connected prior to sending console output
-+so, if they are not, a breakpoint is executed to force the connection.
-+This will happen before any kernel output (it is going thru gdb, right),
-+and will stall the boot until the connection is made.
-+
-+You can also configure in a patch to SysRq to enable the kGdb SysRq.
-+This request generates a breakpoint.  Since the serial port IRQ line is
-+set up after any serial drivers, it is possible that this command will
-+work when the control-C will not.
-+
-+Save and exit the Xconfig program.  Then do "make clean" , "make dep"
-+and "make bzImage" (or whatever target you want to make).  This gets the
-+kernel compiled with the "-g" option set -- necessary for debugging.
-+
-+You have just built the kernel on your DEVELOPMENT machine that you
-+intend to run on your TARGET machine.
-+
-+To install this new kernel, use the following installation procedure.
-+Remember, you are on the DEVELOPMENT machine patching the kernel source
-+for the kernel that you intend to run on the TARGET machine.
-+
-+Copy this kernel to your target machine using your usual procedures.  I
-+usually arrange to copy development:
-+/usr/src/linux/arch/i386/boot/bzImage to /vmlinuz on the TARGET machine
-+via a LAN based NFS access.  That is, I run the cp command on the target
-+and copy from the development machine via the LAN.  Run Lilo (see "man
-+lilo" for details on how to set this up) on the new kernel on the target
-+machine so that it will boot!  Then boot the kernel on the target
-+machine.
-+
-+On the DEVELOPMENT machine, create a file called .gdbinit in the
-+directory /usr/src/linux.  An example .gdbinit file looks like this:
-+
-+shell echo -e "\003" >/dev/ttyS0
-+set remotebaud 38400 (or what ever speed you have chosen)
-+target remote /dev/ttyS0
-+
-+
-+Change the "echo" and "target" definition so that it specifies the tty
-+port that you intend to use.  Change the "remotebaud" definition to
-+match the data rate that you are going to use for the com line.
-+
-+You are now ready to try it out.
-+
-+Boot your target machine with "kgdb" in the boot command i.e. something
-+like:
-+
-+lilo> test kgdb
-+
-+or if you also want console output thru gdb:
-+
-+lilo> test kgdb console=kgdb
-+
-+You should see the lilo message saying it has loaded the kernel and then
-+all output stops.  The kgdb stub is trying to connect with gdb.  Start
-+gdb something like this:
-+
-+
-+On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux".
-+When gdb gets the symbols loaded it will read your .gdbinit file and, if
-+everything is working correctly, you should see gdb print out a few
-+lines indicating that a breakpoint has been taken.  It will actually
-+show a line of code in the target kernel inside the kgdb activation
-+code.
-+
-+The gdb interaction should look something like this:
-+
-+    linux-dev:/usr/src/linux# gdb vmlinux
-+    GDB is free software and you are welcome to distribute copies of it
-+     under certain conditions; type "show copying" to see the conditions.
-+    There is absolutely no warranty for GDB; type "show warranty" for details.
-+    GDB 4.15.1 (i486-slackware-linux), 
-+    Copyright 1995 Free Software Foundation, Inc...
-+    breakpoint () at i386-stub.c:750
-+    750     }
-+    (gdb) 
-+
-+You can now use whatever gdb commands you like to set breakpoints.
-+Enter "continue" to start your target machine executing again.  At this
-+point the target system will run at full speed until it encounters
-+your breakpoint or gets a segment violation in the kernel, or whatever.
-+
-+If you have the kgdb console enabled when you continue, gdb will print
-+out all the console messages.
-+
-+The above example caused a breakpoint relatively early in the boot
-+process.  For the i386 kgdb it is possible to code a break instruction
-+as the first C-language point in init/main.c, i.e. as the first instruction
-+in start_kernel().  This could be done as follows:
-+
-+#include <asm/kgdb.h>
-+	 breakpoint();
-+
-+This breakpoint() is really a function that sets up the breakpoint and
-+single-step hardware trap cells and then executes a breakpoint.  Any
-+early hard coded breakpoint will need to use this function.  Once the
-+trap cells are set up they need not be set again, but doing it again
-+does not hurt anything, so you don't need to be concerned about which
-+breakpoint is hit first.  Once the trap cells are set up (and the kernel
-+sets them up in due course even if breakpoint() is never called) the
-+macro:
-+
-+BREAKPOINT;
-+
-+will generate an inline breakpoint.  This may be more useful as it stops
-+the processor at the instruction instead of in a function a step removed
-+from the location of interest.  In either case <asm/kgdb.h> must be
-+included to define both breakpoint() and BREAKPOINT.
-+
-+Triggering kgdbstub at other times
-+==================================
-+
-+Often you don't need to enter the debugger until much later in the boot
-+or even after the machine has been running for some time.  Once the
-+kernel is booted and interrupts are on, you can force the system to
-+enter the debugger by sending a control-C to the debug port. This is
-+what the first line of the recommended .gdbinit file does.  This allows
-+you to start gdb any time after the system is up as well as when the
-+system is already at a breakpoint.  (In the case where the system is
-+already at a breakpoint the control-C is not needed, however, it will
-+be ignored by the target so no harm is done.  Also note the the echo
-+command assumes that the port speed is already set.  This will be true
-+once gdb has connected, but it is best to set the port speed before you
-+run gdb.)
-+
-+Another simple way to do this is to put the following file in you ~/bin
-+directory:
-+
-+#!/bin/bash
-+echo  -e "\003"  > /dev/ttyS0 
-+
-+Here, the ttyS0 should be replaced with what ever port you are using.
-+The "\003" is control-C.  Once you are connected with gdb, you can enter
-+control-C at the command prompt.
-+
-+An alternative way to get control to the debugger is to enable the kGdb
-+SysRq command.  Then you would enter Alt-SysRq-g (all three keys at the
-+same time, but push them down in the order given).  To refresh your
-+memory of the available SysRq commands try Alt-SysRq-=.  Actually any
-+undefined command could replace the "=", but I like to KNOW that what I
-+am pushing will never be defined.
-+ 
-+Debugging hints
-+===============
-+
-+You can break into the target machine at any time from the development
-+machine by typing ^C (see above paragraph).  If the target machine has
-+interrupts enabled this will stop it in the kernel and enter the
-+debugger.
-+
-+There is unfortunately no way of breaking into the kernel if it is
-+in a loop with interrupts disabled, so if this happens to you then
-+you need to place exploratory breakpoints or printk's into the kernel
-+to find out where it is looping.  The exploratory breakpoints can be
-+entered either thru gdb or hard coded into the source.  This is very
-+handy if you do something like:
-+
-+if (<it hurts>) BREAKPOINT;
-+
-+
-+There is a copy of an e-mail in the Documentation/i386/kgdb/ directory
-+(debug-nmi.txt) which describes how to create an NMI on an ISA bus
-+machine using a paper clip.  I have a sophisticated version of this made
-+by wiring a push button switch into a PC104/ISA bus adapter card.  The
-+adapter card nicely furnishes wire wrap pins for all the ISA bus
-+signals.
-+
-+When you are done debugging the kernel on the target machine it is a
-+good idea to leave it in a running state.  This makes reboots faster,
-+bypassing the fsck.  So do a gdb "continue" as the last gdb command if
-+this is possible.  To terminate gdb itself on the development machine
-+and leave the target machine running, first clear all breakpoints and
-+continue, then type ^Z to suspend gdb and then kill it with "kill %1" or
-+something similar.
-+
-+If gdbstub Does Not Work
-+========================
-+
-+If it doesn't work, you will have to troubleshoot it.  Do the easy
-+things first like double checking your cabling and data rates.  You
-+might try some non-kernel based programs to see if the back-to-back
-+connection works properly.  Just something simple like cat /etc/hosts
-+>/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
-+if you can send data from one machine to the other.  Make sure it works
-+in both directions.  There is no point in tearing out your hair in the
-+kernel if the line doesn't work.
-+
-+All of the real action takes place in the file
-+/usr/src/linux/arch/i386/kernel/kgdb_stub.c.  That is the code on the target
-+machine that interacts with gdb on the development machine.  In gdb you can
-+turn on a debug switch with the following command:
-+
-+	set remotedebug
-+
-+This will print out the protocol messages that gdb is exchanging with
-+the target machine.
-+
-+Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c. This is
-+the code that talks to the serial port on the target side.  There might
-+be a problem there.  In particular there is a section of this code that
-+tests the UART which will tell you what UART you have if you define
-+"PRNT" (just remove "_off" from the #define PRNT_off).  To view this
-+report you will need to boot the system without any beakpoints.  This
-+allows the kernel to run to the point where it calls kgdb to set up
-+interrupts.  At this time kgdb will test the UART and print out the type
-+it finds.  (You need to wait so that the printks are actually being
-+printed.  Early in the boot they are cached, waiting for the console to
-+be enabled.  Also, if kgdb is entered thru a breakpoint it is possible
-+to cause a dead lock by calling printk when the console is locked.  The
-+stub thus avoids doing printks from breakpoints, especially in the
-+serial code.)  At this time, if the UART fails to do the expected thing,
-+kgdb will print out (using printk) information on what failed.  (These
-+messages will be buried in all the other boot up messages.  Look for
-+lines that start with "gdb_hook_interrupt:".  You may want to use dmesg
-+once the system is up to view the log.  If this fails or if you still
-+don't connect, review your answers for the port address.  Use:
-+
-+setserial /dev/ttyS0 
-+
-+to get the current port and IRQ information.  This command will also
-+tell you what the system found for the UART type. The stub recognizes
-+the following UART types:
-+
-+16450, 16550, and 16550A
-+
-+If you are really desperate you can use printk debugging in the
-+kgdbstub code in the target kernel until you get it working.  In particular,
-+there is a global variable in /usr/src/linux/arch/i386/kernel/kgdb_stub.c
-+named "remote_debug".  Compile your kernel with this set to 1, rather
-+than 0 and the debug stub will print out lots of stuff as it does
-+what it does.  Likewise there are debug printks in the kgdb_serial.c
-+code that can be turned on with simple changes in the macro defines.
-+
-+
-+Debugging Loadable Modules
-+==========================
-+
-+This technique comes courtesy of Edouard Parmelan
-+<Edouard.Parmelan@quadratec.fr>
-+
-+When you run gdb, enter the command
-+
-+source gdbinit-modules
-+
-+This will read in a file of gdb macros that was installed in your
-+kernel source directory when kgdb was installed.  This file implements
-+the following commands:
-+
-+mod-list
-+    Lists the loaded modules in the form <module-address> <module-name>
-+
-+mod-print-symbols <module-address>
-+    Prints all the symbols in the indicated module.
-+
-+mod-add-symbols <module-address> <object-file-path-name>
-+    Loads the symbols from the object file and associates them
-+    with the indicated module.
-+
-+After you have loaded the module that you want to debug, use the command
-+mod-list to find the <module-address> of your module.  Then use that
-+address in the mod-add-symbols command to load your module's symbols.
-+From that point onward you can debug your module as if it were a part
-+of the kernel.
-+
-+The file gdbinit-modules also contains a command named mod-add-lis as
-+an example of how to construct a command of your own to load your
-+favorite module.  The idea is to "can" the pathname of the module
-+in the command so you don't have to type so much.
-+
-+Threads
-+=======
-+
-+Each process in a target machine is seen as a gdb thread. gdb thread
-+related commands (info threads, thread n) can be used.
-+
-+ia-32 hardware breakpoints
-+==========================
-+
-+kgdb stub contains support for hardware breakpoints using debugging features
-+of ia-32(x86) processors. These breakpoints do not need code modification.
-+They use debugging registers. 4 hardware breakpoints are available in ia-32
-+processors.
-+
-+Each hardware breakpoint can be of one of the following three types.
-+
-+1. Execution breakpoint - An Execution breakpoint is triggered when code
-+	at the breakpoint address is executed.
-+
-+	As limited number of hardware breakpoints are available, it is
-+	advisable to use software breakpoints ( break command ) instead
-+	of execution hardware breakpoints, unless modification of code
-+	is to be avoided.
-+
-+2. Write breakpoint - A write breakpoint is triggered when memory
-+	location at the breakpoint address is written.
-+
-+	A write or can be placed for data of variable length. Length of
-+	a write breakpoint indicates length of the datatype to be
-+	watched. Length is 1 for 1 byte data , 2 for 2 byte data, 3 for
-+	4 byte data.
-+
-+3. Access breakpoint - An access breakpoint is triggered when memory
-+	location at the breakpoint address is either read or written.
-+
-+	Access breakpoints also have lengths similar to write breakpoints.
-+
-+IO breakpoints in ia-32 are not supported.
-+
-+Since gdb stub at present does not use the protocol used by gdb for hardware
-+breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros
-+for hardware breakpoints are described below.
-+
-+hwebrk	- Places an execution breakpoint
-+	hwebrk breakpointno address
-+hwwbrk	- Places a write breakpoint
-+	hwwbrk breakpointno length address
-+hwabrk	- Places an access breakpoint
-+	hwabrk breakpointno length address
-+hwrmbrk	- Removes a breakpoint
-+	hwrmbrk breakpointno
-+exinfo	- Tells whether a software or hardware breakpoint has occurred.
-+	Prints number of the hardware breakpoint if a hardware breakpoint has
-+	occurred.
-+
-+Arguments required by these commands are as follows
-+breakpointno	- 0 to 3
-+length		- 1 to 3
-+address		- Memory location in hex digits ( without 0x ) e.g c015e9bc
-+
-+SMP support
-+==========
-+
-+When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb
-+client, all the processors are forced to enter the debugger. Current
-+thread corresponds to the thread running on the processor where
-+breakpoint occurred.  Threads running on other processor(s) appear
-+similar to other non-running threads in the 'info threads' output.
-+Within the kgdb stub there is a structure "waiting_cpus" in which kgdb
-+records the values of "current" and "regs" for each CPU other than the
-+one that hit the breakpoint.  "current" is a pointer to the task
-+structure for the task that CPU is running, while "regs" points to the
-+saved registers for the task.  This structure can be examined with the
-+gdb "p" command.
-+
-+ia-32 hardware debugging registers on all processors are set to same
-+values.  Hence any hardware breakpoints may occur on any processor.
-+
-+gdb troubleshooting
-+===================
-+
-+1. gdb hangs
-+Kill it. restart gdb. Connect to target machine.
-+
-+2. gdb cannot connect to target machine (after killing a gdb and
-+restarting another) If the target machine was not inside debugger when
-+you killed gdb, gdb cannot connect because the target machine won't
-+respond.  In this case echo "Ctrl+C"(ASCII 3) to the serial line.
-+e.g. echo -e "\003" > /dev/ttyS1
-+This forces that target machine into the debugger, after which you
-+can connect.
-+
-+3. gdb cannot connect even after echoing Ctrl+C into serial line
-+Try changing serial line settings min to 1 and time to 0
-+e.g. stty min 1 time 0 < /dev/ttyS1
-+Try echoing again
-+
-+Check serial line speed and set it to correct value if required
-+e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
-+
-+EVENTS
-+======
-+
-+Ever want to know the order of things happening?  Which CPU did what and
-+when?  How did the spinlock get the way it is?  Then events are for
-+you.  Events are defined by calls to an event collection interface and
-+saved for later examination.  In this case, kgdb events are saved by a
-+very fast bit of code in kgdb which is fully SMP and interrupt protected
-+and they are examined by using gdb to display them.  Kgdb keeps only
-+the last N events, where N must be a power of two and is defined at
-+configure time.
-+
-+
-+Events are signaled to kgdb by calling:
-+
-+kgdb_ts(data0,data1)
-+
-+For each call kgdb records each call in an array along with other info.
-+Here is the array definition:
-+
-+struct kgdb_and_then_struct {
-+#ifdef CONFIG_SMP
-+	int	on_cpu;
-+#endif
-+	long long at_time;
-+	int  	from_ln;
-+	char	* in_src;
-+	void	*from;
-+        int     with_if;
-+	int	data0;
-+	int	data1;
-+};
-+
-+For SMP machines the CPU is recorded, for all machines the TSC is
-+recorded (gets a time stamp) as well as the line number and source file
-+the call was made from.  The address of the (from), the "if" (interrupt
-+flag) and the two data items are also recorded.  The macro kgdb_ts casts
-+the types to int, so you can put any 32-bit values here.  There is a
-+configure option to select the number of events you want to keep.  A
-+nice number might be 128, but you can keep up to 1024 if you want.  The
-+number must be a power of two.  An "andthen" macro library is provided
-+for gdb to help you look at these events.  It is also possible to define
-+a different structure for the event storage and cast the data to this
-+structure.  For example the following structure is defined in kgdb:
-+
-+struct kgdb_and_then_struct2 {
-+#ifdef CONFIG_SMP
-+	int	on_cpu;
-+#endif
-+	long long at_time;
-+	int  	from_ln;
-+	char	* in_src;
-+	void	*from;
-+        int     with_if;
-+	struct task_struct *t1;
-+	struct task_struct *t2;
-+};
-+
-+If you use this for display, the data elements will be displayed as
-+pointers to task_struct entries.  You may want to define your own
-+structure to use in casting.  You should only change the last two items
-+and you must keep the structure size the same.  Kgdb will handle these
-+as 32-bit ints, but within that constraint you can define a structure to
-+cast to any 32-bit quantity.  This need only be available to gdb and is
-+only used for casting in the display code.
-+
-+Final Items
-+===========
-+
-+I picked up this code from Amit S. Kale and enhanced it.
-+
-+If you make some really cool modification to this stuff, or if you 
-+fix a bug, please let me know.
-+
-+George Anzinger
-+<george@mvista.com>
-+
-+Amit S. Kale
-+<akale@veritas.com>
-+
-+(First kgdb by David Grothe <dave@gcom.com>)
-+
-+(modified by Tigran Aivazian <tigran@sco.com>)
-+    Putting gdbstub into the kernel config menu.
-+
-+(modified by Scott Foehner <sfoehner@engr.sgi.com>)
-+    Hooks for entering gdbstub at boot time.
-+
-+(modified by Amit S. Kale <akale@veritas.com>)
-+    Threads, ia-32 hw debugging, mp support, console support,
-+    nmi watchdog handling.
-+
-+(modified by George Anzinger <george@mvista.com>)
-+    Extended threads to include the idle threads.
-+    Enhancements to allow breakpoint() at first C code.
-+    Use of module_init() and __setup() to automate the configure.
-+    Enhanced the cpu "collection" code to work in early bring-up.
-+    Added ability to call functions from gdb
-+    Print info thread stuff without going back to schedule()
-+    Now collect the "other" cpus with an IPI/ NMI.
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/Documentation/i386/kgdb/loadmodule.sh	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,78 @@
-+#/bin/sh
-+# This script loads a module on a target machine and generates a gdb script.
-+# source generated gdb script to load the module file at appropriate addresses
-+# in gdb.
-+#
-+# Usage: 
-+# Loading the module on target machine and generating gdb script)
-+#	[foo]$ loadmodule.sh <modulename>
-+#
-+# Loading the module file into gdb
-+#	(gdb) source <gdbscriptpath>
-+#
-+# Modify following variables according to your setup. 
-+#	TESTMACHINE - Name of the target machine
-+#	GDBSCRIPTS - The directory where a gdb script will be generated
-+#
-+# Author: Amit S. Kale (akale@veritas.com).
-+#
-+# If you run into problems, please check files pointed to by following
-+# variables.
-+#	ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
-+#	MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
-+#	GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
-+
-+TESTMACHINE=foo
-+GDBSCRIPTS=/home/bar
-+
-+if [ $# -lt 1 ] ; then {
-+	echo Usage: $0 modulefile
-+	exit
-+} ; fi
-+
-+MODULEFILE=$1
-+MODULEFILEBASENAME=`basename $1`
-+
-+if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
-+	MODULEFILE=`pwd`/$MODULEFILE
-+} fi
-+
-+ERRFILE=/tmp/$MODULEFILEBASENAME.errs
-+MAPFILE=/tmp/$MODULEFILEBASENAME.map
-+GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
-+
-+function findaddr() {
-+	local ADDR=0x$(echo "$SEGMENTS" | \
-+		grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
-+		sed 's/[ ]*[^ ]*$//')
-+	echo $ADDR
-+}
-+
-+function checkerrs() {
-+	if [ "`cat $ERRFILE`" != "" ] ; then {
-+		cat $ERRFILE
-+		exit
-+	} fi
-+}
-+
-+#load the module
-+echo Copying $MODULEFILE to $TESTMACHINE
-+rcp $MODULEFILE root@${TESTMACHINE}:
-+
-+echo Loading module $MODULEFILE
-+rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
-+	> $MAPFILE 2> $ERRFILE
-+checkerrs
-+
-+SEGMENTS=`head -n 11 $MAPFILE | tail -n 10`
-+TEXTADDR=$(findaddr "\\.text[^.]")
-+LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
-+SEGADDRS=`echo "$SEGMENTS" | awk '//{
-+	if ($1 != ".text" && $1 != ".this" &&
-+	    $1 != ".kstrtab" && $1 != ".kmodtab") {
-+		print " -s " $1 " 0x" $3 " "
-+	}
-+}'`
-+LOADSTRING="$LOADSTRING $SEGADDRS"
-+echo Generating script $GDBSCRIPT
-+echo $LOADSTRING > $GDBSCRIPT
---- linux-2.6.0-test1/Documentation/magic-number.txt	2003-06-14 12:18:23.000000000 -0700
-+++ 25/Documentation/magic-number.txt	2003-07-19 17:03:49.000000000 -0700
-@@ -51,6 +51,13 @@ kernel before 2.6.x yet.
- 					<pasky@ucw.cz>
- 					03 Nov 2002
- 
-+Updated the magic table to Linux 2.5.74.
-+
-+					Fabian Frederick
-+					<ffrederick@users.sourceforge.net>
-+					09 Jul 2003
-+
-+
- Magic Name            Number      Structure            File
- ===========================================================================
- PG_MAGIC              'P'         pg_{read,write}_hdr include/linux/pg.h
-@@ -62,10 +69,12 @@ AURORA_MAGIC          0x0A18      Aurora
- HDLC_MAGIC            0x239e      n_hdlc            drivers/char/n_hdlc.c
- APM_BIOS_MAGIC        0x4101      apm_user          arch/i386/kernel/apm.c
- CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
-+DB_MAGIC              0x4442      fc_info           drivers/net/iph5526_novram.c
-+DL_MAGIC              0x444d      fc_info           drivers/net/iph5526_novram.c
- FASYNC_MAGIC          0x4601      fasync_struct     include/linux/fs.h
-+FF_MAGIC              0x4646      fc_info           drivers/net/iph5526_novram.c
- ISICOM_MAGIC          0x4d54      isi_port          include/linux/isicom.h
--PTY_MAGIC             0x5001      (none at the moment)
--                                                    drivers/char/pty.c
-+PTY_MAGIC             0x5001                        drivers/char/pty.c
- PPP_MAGIC             0x5002      ppp               include/linux/if_pppvar.h
- SERIAL_MAGIC          0x5301      async_struct      include/linux/serial.h
- SSTATE_MAGIC          0x5302      serial_state      include/linux/serial.h
-@@ -81,9 +90,9 @@ TTY_DRIVER_MAGIC      0x5402      tty_dr
- MGSLPC_MAGIC          0x5402      mgslpc_info       drivers/char/pcmcia/synclink_cs.c
- TTY_LDISC_MAGIC       0x5403      tty_ldisc         include/linux/tty_ldisc.h
- USB_SERIAL_MAGIC      0x6702      usb_serial        drivers/usb/serial/usb-serial.h
-+FULL_DUPLEX_MAGIC     0x6969                        drivers/net/tulip/de2104x.c
- USB_BLUETOOTH_MAGIC   0x6d02      usb_bluetooth     drivers/usb/class/bluetty.c
--RFCOMM_TTY_MAGIC      0x6d02      (note at the moment)
--                                                    net/bluetooth/rfcomm/tty.c
-+RFCOMM_TTY_MAGIC      0x6d02                        net/bluetooth/rfcomm/tty.c
- USB_SERIAL_PORT_MAGIC 0x7301      usb_serial_port   drivers/usb/serial/usb-serial.h
- CG_MAGIC              0x00090255  ufs_cylinder_group include/linux/ufs_fs.h
- A2232_MAGIC           0x000a2232  gs_port           drivers/char/ser_a2232.h
-@@ -91,6 +100,7 @@ SOLARIS_SOCKET_MAGIC  0x000ADDED  sol_so
- RPORT_MAGIC           0x00525001  r_port            drivers/char/rocket_int.h
- LSEMAGIC              0x05091998  lse               drivers/fc4/fc.c
- GDTIOCTL_MAGIC        0x06030f07  gdth_iowr_str     drivers/scsi/gdth_ioctl.h
-+RIEBL_MAGIC           0x09051990                    drivers/net/atarilance.c
- RIO_MAGIC             0x12345678  gs_port           drivers/char/rio/rio_linux.c
- SX_MAGIC              0x12345678  gs_port           drivers/char/sx.h
- NBD_REQUEST_MAGIC     0x12560953  nbd_request       include/linux/nbd.h
-@@ -120,6 +130,7 @@ SAVEKMSG_MAGIC1       0x53415645  savekm
- GDA_MAGIC             0x58464552  gda               include/asm-mips64/sn/gda.h
- RED_MAGIC1            0x5a2cf071  (any)             mm/slab.c
- STL_PORTMAGIC         0x5a7182c9  stlport           include/linux/stallion.h
-+EEPROM_MAGIC_VALUE    0X5ab478d2  lanai_dev         drivers/atm/lanai.c
- HDLCDRV_MAGIC         0x5ac6e778  hdlcdrv_state     include/linux/hdlcdrv.h
- EPCA_MAGIC            0x5c6df104  channel           include/linux/epca.h
- PCXX_MAGIC            0x5c6df104  channel           drivers/char/pcxx.h
-@@ -127,9 +138,11 @@ KV_MAGIC              0x5f4b565f  kernel
- I810_STATE_MAGIC      0x63657373  i810_state        sound/oss/i810_audio.c
- TRIDENT_STATE_MAGIC   0x63657373  trient_state      sound/oss/trident.c
- M3_CARD_MAGIC         0x646e6f50  m3_card           sound/oss/maestro3.c
-+FW_HEADER_MAGIC       0x65726F66  fw_header         drivers/atm/fore200e.h
- SLOT_MAGIC            0x67267321  slot              drivers/hotplug/cpqphp.h
- SLOT_MAGIC            0x67267322  slot              drivers/hotplug/acpiphp.h
- LO_MAGIC              0x68797548  nbd_device        include/linux/nbd.h
-+OPROFILE_MAGIC        0x6f70726f  super_block       drivers/oprofile/oprofilefs.h
- M3_STATE_MAGIC        0x734d724d  m3_state          sound/oss/maestro3.c
- STL_PANELMAGIC        0x7ef621a1  stlpanel          include/linux/stallion.h
- VMALLOC_MAGIC         0x87654320  snd_alloc_track   sound/core/memory.c
-@@ -137,11 +150,15 @@ KMALLOC_MAGIC         0x87654321  snd_al
- PWC_MAGIC             0x89DC10AB  pwc_device        drivers/usb/media/pwc.h
- NBD_REPLY_MAGIC       0x96744668  nbd_reply         include/linux/nbd.h
- STL_BOARDMAGIC        0xa2267f52  stlbrd            include/linux/stallion.h
-+ENI155_MAGIC          0xa54b872d  midway_eprom	    drivers/atm/eni.h
- SCI_MAGIC             0xbabeface  gs_port           drivers/char/sh-sci.h
- CODA_MAGIC            0xC0DAC0DA  coda_file_info    include/linux/coda_fs_i.h
-+DPMEM_MAGIC           0xc0ffee11  gdt_pci_sram      drivers/scsi/gdth.h
- STLI_PORTMAGIC        0xe671c7a1  stliport          include/linux/istallion.h
- YAM_MAGIC             0xF10A7654  yam_port          drivers/net/hamradio/yam.c
- CCB_MAGIC             0xf2691ad2  ccb               drivers/scsi/ncr53c8xx.c
-+QUEUE_MAGIC_FREE      0xf7e1c9a3  queue_entry       drivers/scsi/arm/queue.c
-+QUEUE_MAGIC_USED      0xf7e1cc33  queue_entry       drivers/scsi/arm/queue.c
- HTB_CMAGIC            0xFEFAFEF1  htb_class         net/sched/sch_htb.c
- NMI_MAGIC             0x48414d4d455201 nmi_s        include/asm-mips64/sn/nmi.h
- 
---- linux-2.6.0-test1/Documentation/networking/vortex.txt	2003-06-14 12:18:00.000000000 -0700
-+++ 25/Documentation/networking/vortex.txt	2003-07-19 17:05:08.000000000 -0700
-@@ -216,19 +216,6 @@ watchdog=N
-   to increase this value on LANs which have very high collision rates.
-   The default value is 5000 (5.0 seconds).
- 
--enable_wol=N1,N2,N3,...
--
--  Enable Wake-on-LAN support for the relevant interface.  Donald
--  Becker's `ether-wake' application may be used to wake suspended
--  machines.
--
--  Also enables the NIC's power management support.
--
--global_enable_wol=N
--
--  Sets enable_wol mode for all 3c59x NICs in the machine.  Entries in
--  the `enable_wol' array above will override any setting of this.
--
- Media selection
- ---------------
- 
---- linux-2.6.0-test1/Documentation/pnp.txt	2003-06-14 12:17:58.000000000 -0700
-+++ 25/Documentation/pnp.txt	2003-07-19 17:03:49.000000000 -0700
-@@ -22,7 +22,7 @@ user interface is integrated into driver
- In addition to the standard driverfs file the following are created in each 
- device's directory:
- id - displays a list of support EISA IDs
--possible - displays possible resource configurations
-+options - displays possible resource configurations
- resources - displays currently allocated resources and allows resource changes
- 
- -activating a device
-@@ -60,7 +60,7 @@ DISABLED
- - Notice the string "DISABLED".  THis means the device is not active.
- 
- 3.) check the device's possible configurations (optional)
--# cat possible
-+# cat options
- Dependent: 01 - Priority acceptable
-     port 0x3f0-0x3f0, align 0x7, size 0x6, 16-bit address decoding
-     port 0x3f7-0x3f7, align 0x0, size 0x1, 16-bit address decoding
---- linux-2.6.0-test1/drivers/acorn/block/fd1772.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/drivers/acorn/block/fd1772.c	2003-07-19 17:03:49.000000000 -0700
-@@ -152,8 +152,6 @@
- #include <asm/uaccess.h>
- 
- 
--#include <linux/blk.h>
--
- /* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
-  * little additional rework in this file). But I'm not yet sure if
-  * some other code depends on the number of floppies... (It is defined
---- linux-2.6.0-test1/drivers/acorn/block/mfmhd.c	2003-06-14 12:18:01.000000000 -0700
-+++ 25/drivers/acorn/block/mfmhd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -111,7 +111,6 @@
- #include <linux/major.h>
- #include <linux/ioport.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- 
- #include <asm/system.h>
---- linux-2.6.0-test1/drivers/acpi/executer/exutils.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/acpi/executer/exutils.c	2003-07-19 17:03:49.000000000 -0700
-@@ -290,7 +290,7 @@ acpi_ex_digits_needed (
- 	 * acpi_integer is unsigned, so we don't worry about a '-'
- 	 */
- 	if ((current_value = value) == 0) {
--	    return_VALUE (1);
-+		return_VALUE (1);
- 	}
- 
- 	num_digits = 0;
---- linux-2.6.0-test1/drivers/acpi/hardware/hwregs.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/acpi/hardware/hwregs.c	2003-07-19 17:03:49.000000000 -0700
-@@ -357,9 +357,9 @@ acpi_set_register (
- 
- 	/*
- 	 * Decode the Register ID
--	 * Register id = Register block id | bit id
-+	 * Register ID = [Register block ID] | [bit ID]
- 	 *
--	 * Check bit id to fine locate Register offset.
-+	 * Check bit ID to fine locate Register offset.
- 	 * Check Mask to determine Register offset, and then read-write.
- 	 */
- 	switch (bit_reg_info->parent_register) {
-@@ -367,9 +367,9 @@ acpi_set_register (
- 
- 		/*
- 		 * Status Registers are different from the rest.  Clear by
--		 * writing 1, writing 0 has no effect.  So, the only relevant
-+		 * writing 1, and writing 0 has no effect.  So, the only relevant
- 		 * information is the single bit we're interested in, all others should
--		 * be written as 0 so they will be left unchanged
-+		 * be written as 0 so they will be left unchanged.
- 		 */
- 		value = ACPI_REGISTER_PREPARE_BITS (value,
- 				 bit_reg_info->bit_position, bit_reg_info->access_bit_mask);
-@@ -394,17 +394,17 @@ acpi_set_register (
- 	case ACPI_REGISTER_PM1_CONTROL:
- 
- 		/*
--		 * Read the PM1 Control register.
-+		 * Write the PM1 Control register.
- 		 * Note that at this level, the fact that there are actually TWO
--		 * registers (A and B - and that B may not exist) is abstracted.
-+		 * registers (A and B - and B may not exist) is abstracted.
- 		 */
- 		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", register_value));
- 
- 		ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
- 				bit_reg_info->access_bit_mask, value);
- 
--		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id,
--				(u16) register_value);
-+		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-+				  ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
- 		break;
- 
- 
-@@ -724,7 +724,7 @@ acpi_hw_low_level_read (
- 
- 	/*
- 	 * Three address spaces supported:
--	 * Memory, Io, or PCI config.
-+	 * Memory, IO, or PCI_Config.
- 	 */
- 	switch (reg->address_space_id) {
- 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-@@ -808,9 +808,10 @@ acpi_hw_low_level_write (
- 		(!reg->address)) {
- 		return (AE_OK);
- 	}
-+
- 	/*
- 	 * Three address spaces supported:
--	 * Memory, Io, or PCI config.
-+	 * Memory, IO, or PCI_Config.
- 	 */
- 	switch (reg->address_space_id) {
- 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
---- linux-2.6.0-test1/drivers/acpi/osl.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/acpi/osl.c	2003-07-19 17:03:49.000000000 -0700
-@@ -35,6 +35,7 @@
- #include <linux/kmod.h>
- #include <linux/delay.h>
- #include <linux/workqueue.h>
-+#include <linux/nmi.h>
- #include <acpi/acpi.h>
- #include <asm/io.h>
- #include <acpi/acpi_bus.h>
-@@ -291,11 +292,14 @@ acpi_os_sleep(u32 sec, u32 ms)
- void
- acpi_os_stall(u32 us)
- {
--	if (us > 10000) {
--		mdelay(us / 1000);
--	}
--	else {
--		udelay(us);
-+	while (us) {
-+		u32 delay = 1000;
-+
-+		if (delay > us)
-+			delay = us;
-+		udelay(delay);
-+		touch_nmi_watchdog();
-+		us -= delay;
- 	}
- }
- 
---- linux-2.6.0-test1/drivers/acpi/processor.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/acpi/processor.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1351,7 +1351,7 @@ static int acpi_processor_throttling_ope
- 						PDE(inode)->data);
- }
- 
--static int
-+static ssize_t
- acpi_processor_write_throttling (
-         struct file		*file,
-         const char		*buffer,
-@@ -1414,7 +1414,7 @@ static int acpi_processor_limit_open_fs(
- 						PDE(inode)->data);
- }
- 
--static int
-+static ssize_t
- acpi_processor_write_limit (
- 	struct file		*file,
- 	const char		*buffer,
---- linux-2.6.0-test1/drivers/acpi/tables.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/acpi/tables.c	2003-07-19 17:03:49.000000000 -0700
-@@ -33,6 +33,7 @@
- #include <linux/irq.h>
- #include <linux/errno.h>
- #include <linux/acpi.h>
-+#include <linux/bootmem.h>
- 
- #define PREFIX			"ACPI: "
- 
-@@ -61,16 +62,14 @@ static char *acpi_table_signatures[ACPI_
- 
- /* System Description Table (RSDT/XSDT) */
- struct acpi_table_sdt {
--	unsigned long		pa;		/* Physical Address */
--	unsigned long		count;		/* Table count */
--	struct {
--		unsigned long		pa;
--		enum acpi_table_id	id;
--		unsigned long		size;
--	}			entry[ACPI_MAX_TABLES];
-+	unsigned long		pa;
-+	enum acpi_table_id	id;
-+	unsigned long		size;
- } __attribute__ ((packed));
- 
--static struct acpi_table_sdt	sdt;
-+static unsigned long		sdt_pa;		/* Physical Address */
-+static unsigned long		sdt_count;	/* Table count */
-+static struct acpi_table_sdt	*sdt_entry;
- 
- void
- acpi_table_print (
-@@ -236,11 +235,11 @@ acpi_get_table_header_early (
- 
- 	/* Locate the table. */
- 
--	for (i = 0; i < sdt.count; i++) {
--		if (sdt.entry[i].id != temp_id)
-+	for (i = 0; i < sdt_count; i++) {
-+		if (sdt_entry[i].id != temp_id)
- 			continue;
- 		*header = (void *)
--			__acpi_map_table(sdt.entry[i].pa, sdt.entry[i].size);
-+			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
- 		if (!*header) {
- 			printk(KERN_WARNING PREFIX "Unable to map %s\n",
- 			       acpi_table_signatures[temp_id]);
-@@ -289,11 +288,11 @@ acpi_table_parse_madt_family (
- 
- 	/* Locate the MADT (if exists). There should only be one. */
- 
--	for (i = 0; i < sdt.count; i++) {
--		if (sdt.entry[i].id != id)
-+	for (i = 0; i < sdt_count; i++) {
-+		if (sdt_entry[i].id != id)
- 			continue;
- 		madt = (void *)
--			__acpi_map_table(sdt.entry[i].pa, sdt.entry[i].size);
-+			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
- 		if (!madt) {
- 			printk(KERN_WARNING PREFIX "Unable to map %s\n",
- 			       acpi_table_signatures[id]);
-@@ -308,7 +307,7 @@ acpi_table_parse_madt_family (
- 		return -ENODEV;
- 	}
- 
--	madt_end = (unsigned long) madt + sdt.entry[i].size;
-+	madt_end = (unsigned long) madt + sdt_entry[i].size;
- 
- 	/* Parse all entries looking for a match. */
- 
-@@ -349,10 +348,10 @@ acpi_table_parse (
- 	if (!handler)
- 		return -EINVAL;
- 
--	for (i = 0; i < sdt.count; i++) {
--		if (sdt.entry[i].id != id)
-+	for (i = 0; i < sdt_count; i++) {
-+		if (sdt_entry[i].id != id)
- 			continue;
--		handler(sdt.entry[i].pa, sdt.entry[i].size);
-+		handler(sdt_entry[i].pa, sdt_entry[i].size);
- 		count++;
- 	}
- 
-@@ -377,11 +376,11 @@ acpi_table_get_sdt (
- 			
- 		struct acpi_table_xsdt	*mapped_xsdt = NULL;
- 
--		sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
-+		sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
- 
- 		/* map in just the header */
- 		header = (struct acpi_table_header *)
--			__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
-+			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
- 
- 		if (!header) {
- 			printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
-@@ -390,7 +389,7 @@ acpi_table_get_sdt (
- 
- 		/* remap in the entire table before processing */
- 		mapped_xsdt = (struct acpi_table_xsdt *)
--			__acpi_map_table(sdt.pa, header->length);
-+			__acpi_map_table(sdt_pa, header->length);
- 		if (!mapped_xsdt) {
- 			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
- 			return -ENODEV;
-@@ -407,15 +406,21 @@ acpi_table_get_sdt (
- 			return -ENODEV;
- 		}
- 
--		sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3;
--		if (sdt.count > ACPI_MAX_TABLES) {
-+		sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
-+		if (sdt_count > ACPI_MAX_TABLES) {
- 			printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
--				(sdt.count - ACPI_MAX_TABLES));
--			sdt.count = ACPI_MAX_TABLES;
-+				(sdt_count - ACPI_MAX_TABLES));
-+			sdt_count = ACPI_MAX_TABLES;
- 		}
- 
--		for (i = 0; i < sdt.count; i++)
--			sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
-+		sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
-+		if (!sdt_entry) {
-+			printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
-+			return -ENOMEM;
-+		}
-+
-+		for (i = 0; i < sdt_count; i++)
-+			sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
- 	}
- 
- 	/* Then check RSDT */
-@@ -424,11 +429,11 @@ acpi_table_get_sdt (
- 
- 		struct acpi_table_rsdt	*mapped_rsdt = NULL;
- 
--		sdt.pa = rsdp->rsdt_address;
-+		sdt_pa = rsdp->rsdt_address;
- 
- 		/* map in just the header */
- 		header = (struct acpi_table_header *)
--			__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
-+			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
- 		if (!header) {
- 			printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
- 			return -ENODEV;
-@@ -436,7 +441,7 @@ acpi_table_get_sdt (
- 
- 		/* remap in the entire table before processing */
- 		mapped_rsdt = (struct acpi_table_rsdt *)
--			__acpi_map_table(sdt.pa, header->length);
-+			__acpi_map_table(sdt_pa, header->length);
- 		if (!mapped_rsdt) {
- 			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
- 			return -ENODEV;
-@@ -453,15 +458,21 @@ acpi_table_get_sdt (
- 			return -ENODEV;
- 		}
- 
--		sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 2;
--		if (sdt.count > ACPI_MAX_TABLES) {
-+		sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2;
-+		if (sdt_count > ACPI_MAX_TABLES) {
- 			printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n",
--				(sdt.count - ACPI_TABLE_COUNT));
--			sdt.count = ACPI_MAX_TABLES;
-+				(sdt_count - ACPI_MAX_TABLES));
-+			sdt_count = ACPI_MAX_TABLES;
- 		}
- 
--		for (i = 0; i < sdt.count; i++)
--			sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
-+		sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
-+		if (!sdt_entry) {
-+			printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
-+			return -ENOMEM;
-+		}
-+
-+		for (i = 0; i < sdt_count; i++)
-+			sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
- 	}
- 
- 	else {
-@@ -469,38 +480,38 @@ acpi_table_get_sdt (
- 		return -ENODEV;
- 	}
- 
--	acpi_table_print(header, sdt.pa);
-+	acpi_table_print(header, sdt_pa);
- 
--	for (i = 0; i < sdt.count; i++) {
-+	for (i = 0; i < sdt_count; i++) {
- 
- 		/* map in just the header */
- 		header = (struct acpi_table_header *)
--			__acpi_map_table(sdt.entry[i].pa,
-+			__acpi_map_table(sdt_entry[i].pa,
- 				sizeof(struct acpi_table_header));
- 		if (!header)
- 			continue;
- 
- 		/* remap in the entire table before processing */
- 		header = (struct acpi_table_header *)
--			__acpi_map_table(sdt.entry[i].pa,
-+			__acpi_map_table(sdt_entry[i].pa,
- 				header->length);
- 		if (!header)
- 			continue;
- 	               
--		acpi_table_print(header, sdt.entry[i].pa);
-+		acpi_table_print(header, sdt_entry[i].pa);
- 
- 		if (acpi_table_compute_checksum(header, header->length)) {
- 			printk(KERN_WARNING "  >>> ERROR: Invalid checksum\n");
- 			continue;
- 		}
- 
--		sdt.entry[i].size = header->length;
-+		sdt_entry[i].size = header->length;
- 
- 		for (id = 0; id < ACPI_TABLE_COUNT; id++) {
- 			if (!strncmp((char *) &header->signature,
- 				acpi_table_signatures[id],
- 				sizeof(header->signature))) {
--				sdt.entry[i].id = id;
-+				sdt_entry[i].id = id;
- 			}
- 		}
- 	}
-@@ -525,8 +536,6 @@ acpi_table_init (void)
- 	unsigned long		rsdp_phys = 0;
- 	int			result = 0;
- 
--	memset(&sdt, 0, sizeof(struct acpi_table_sdt));
--
- 	/* Locate and map the Root System Description Table (RSDP) */
- 
- 	rsdp_phys = acpi_find_rsdp();
---- linux-2.6.0-test1/drivers/acpi/tables/tbconvrt.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/acpi/tables/tbconvrt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -75,14 +75,10 @@ acpi_tb_get_table_count (
- 	ACPI_FUNCTION_ENTRY ();
- 
- 
--#if ACPI_MACHINE_WIDTH != 64
--
- 	if (RSDP->revision < 2) {
- 		pointer_size = sizeof (u32);
- 	}
--	else
--#endif
--	{
-+	else {
- 		pointer_size = sizeof (u64);
- 	}
- 
---- linux-2.6.0-test1/drivers/acpi/tables/tbget.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/acpi/tables/tbget.c	2003-07-19 17:03:49.000000000 -0700
-@@ -145,7 +145,7 @@ acpi_tb_get_table_header (
- 		/* Create a logical address for the physical pointer*/
- 
- 		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
--				  (void **) &header);
-+				  (void *) &header);
- 		if (ACPI_FAILURE (status)) {
- 			ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
- 				ACPI_HIDWORD (address->pointer.physical),
-@@ -361,7 +361,7 @@ acpi_tb_get_this_table (
- 		 * into our address space.
- 		 */
- 		status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
--				  (void **) &full_table);
-+				  (void *) &full_table);
- 		if (ACPI_FAILURE (status)) {
- 			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
- 				header->signature,
---- linux-2.6.0-test1/drivers/acpi/tables/tbinstal.c	2003-06-14 12:18:03.000000000 -0700
-+++ 25/drivers/acpi/tables/tbinstal.c	2003-07-19 17:03:49.000000000 -0700
-@@ -271,22 +271,40 @@ acpi_tb_init_table_descriptor (
- 		if (list_head->next) {
- 			return_ACPI_STATUS (AE_ALREADY_EXISTS);
- 		}
--	}
- 
--	/*
--	 * Link the new table in to the list of tables of this type.
--	 * Just insert at the start of the list, order unimportant.
--	 *
--	 * table_desc->Prev is already NULL from calloc()
--	 */
--	table_desc->next = list_head->next;
--	list_head->next = table_desc;
-+		table_desc->next = list_head->next;
-+		list_head->next = table_desc;
- 
--	if (table_desc->next) {
--		table_desc->next->prev = table_desc;
-+		if (table_desc->next) {
-+			table_desc->next->prev = table_desc;
-+		}
-+
-+		list_head->count++;
- 	}
-+	else {
-+		/*
-+		 * Link the new table in to the list of tables of this type.
-+		 * Insert at the end of the list, order IS IMPORTANT.
-+		 *
-+		 * table_desc->Prev & Next are already NULL from calloc()
-+		 */
-+		list_head->count++;
-+
-+		if (!list_head->next) {
-+			list_head->next = table_desc;
-+		}
-+		else {
-+			table_desc->next = list_head->next;
- 
--	list_head->count++;
-+			while (table_desc->next->next) {
-+				table_desc->next = table_desc->next->next;
-+			}
-+
-+			table_desc->next->next = table_desc;
-+			table_desc->prev = table_desc->next;
-+			table_desc->next = NULL;
-+		}
-+	}
- 
- 	/* Finish initialization of the table descriptor */
- 
---- linux-2.6.0-test1/drivers/acpi/tables/tbrsdt.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/acpi/tables/tbrsdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -85,7 +85,7 @@ acpi_tb_verify_rsdp (
- 		 * Obtain access to the RSDP structure
- 		 */
- 		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
--				  (void **) &rsdp);
-+				  (void *) &rsdp);
- 		if (ACPI_FAILURE (status)) {
- 			return_ACPI_STATUS (status);
- 		}
---- linux-2.6.0-test1/drivers/acpi/tables/tbxfroot.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/acpi/tables/tbxfroot.c	2003-07-19 17:03:49.000000000 -0700
-@@ -179,7 +179,7 @@ acpi_get_firmware_table (
- 
- 		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
- 			status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor),
--					  (void **) &acpi_gbl_RSDP);
-+					  (void *) &acpi_gbl_RSDP);
- 			if (ACPI_FAILURE (status)) {
- 				return_ACPI_STATUS (status);
- 			}
-@@ -423,7 +423,7 @@ acpi_tb_find_rsdp (
- 		 * 1) Search EBDA (low memory) paragraphs
- 		 */
- 		status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE,
--				  (void **) &table_ptr);
-+				  (void *) &table_ptr);
- 		if (ACPI_FAILURE (status)) {
- 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
- 				ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE));
-@@ -447,7 +447,7 @@ acpi_tb_find_rsdp (
- 		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
- 		 */
- 		status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE,
--				  (void **) &table_ptr);
-+				  (void *) &table_ptr);
- 		if (ACPI_FAILURE (status)) {
- 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
- 				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
---- linux-2.6.0-test1/drivers/acpi/thermal.c	2003-06-14 12:18:32.000000000 -0700
-+++ 25/drivers/acpi/thermal.c	2003-07-19 17:03:49.000000000 -0700
-@@ -84,11 +84,11 @@ static int acpi_thermal_remove (struct a
- static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
- static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
- static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
--static int acpi_thermal_write_trip_points (struct file*,const char *,size_t,loff_t *);
-+static ssize_t acpi_thermal_write_trip_points (struct file*,const char *,size_t,loff_t *);
- static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
--static int acpi_thermal_write_cooling_mode (struct file*,const char *,size_t,loff_t *);
-+static ssize_t acpi_thermal_write_cooling_mode (struct file*,const char *,size_t,loff_t *);
- static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
--static int acpi_thermal_write_polling(struct file*,const char *,size_t,loff_t *);
-+static ssize_t acpi_thermal_write_polling(struct file*,const char *,size_t,loff_t *);
- 
- static struct acpi_driver acpi_thermal_driver = {
- 	.name =		ACPI_THERMAL_DRIVER_NAME,
-@@ -881,7 +881,7 @@ static int acpi_thermal_trip_open_fs(str
- 	return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
- }
- 
--static int
-+static ssize_t
- acpi_thermal_write_trip_points (
-         struct file		*file,
-         const char		*buffer,
-@@ -950,7 +950,7 @@ static int acpi_thermal_cooling_open_fs(
- 							PDE(inode)->data);
- }
- 
--static int
-+static ssize_t
- acpi_thermal_write_cooling_mode (
- 	struct file		*file,
- 	const char		*buffer,
-@@ -1011,7 +1011,7 @@ static int acpi_thermal_polling_open_fs(
- 							PDE(inode)->data);
- }
- 
--static int
-+static ssize_t
- acpi_thermal_write_polling (
- 	struct file		*file,
- 	const char		*buffer,
---- linux-2.6.0-test1/drivers/acpi/utilities/utglobal.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/acpi/utilities/utglobal.c	2003-07-19 17:03:49.000000000 -0700
-@@ -307,9 +307,9 @@ struct acpi_table_support           acpi
- 	/***********    Name,   Signature, Global typed pointer     Signature size,      Type                  How many allowed?,    Contains valid AML? */
- 
- 	/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL,                    sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT     | ACPI_TABLE_SINGLE},
--	/* DSDT 1 */ {DSDT_SIG,  DSDT_SIG, (void **) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE  | ACPI_TABLE_EXECUTABLE},
--	/* FADT 2 */ {FADT_SIG,  FADT_SIG, (void **) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
--	/* FACS 3 */ {FACS_SIG,  FACS_SIG, (void **) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
-+	/* DSDT 1 */ {DSDT_SIG,  DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE  | ACPI_TABLE_EXECUTABLE},
-+	/* FADT 2 */ {FADT_SIG,  FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
-+	/* FACS 3 */ {FACS_SIG,  FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
- 	/* PSDT 4 */ {PSDT_SIG,  PSDT_SIG, NULL,                    sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY  | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
- 	/* SSDT 5 */ {SSDT_SIG,  SSDT_SIG, NULL,                    sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY  | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
- 	/* XSDT 6 */ {XSDT_SIG,  XSDT_SIG, NULL,                    sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT     | ACPI_TABLE_SINGLE},
---- linux-2.6.0-test1/drivers/atm/atmtcp.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/atm/atmtcp.c	2003-07-19 17:03:49.000000000 -0700
-@@ -66,7 +66,7 @@ static int atmtcp_send_control(struct at
- 	*(struct atm_vcc **) &new_msg->vcc = vcc;
- 	old_test = test_bit(flag,&vcc->flags);
- 	out_vcc->push(out_vcc,skb);
--	add_wait_queue(&vcc->sleep,&wait);
-+	add_wait_queue(vcc->sk->sk_sleep, &wait);
- 	while (test_bit(flag,&vcc->flags) == old_test) {
- 		mb();
- 		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-@@ -78,7 +78,7 @@ static int atmtcp_send_control(struct at
- 		schedule();
- 	}
- 	current->state = TASK_RUNNING;
--	remove_wait_queue(&vcc->sleep,&wait);
-+	remove_wait_queue(vcc->sk->sk_sleep, &wait);
- 	return error;
- }
- 
-@@ -90,7 +90,7 @@ static int atmtcp_recv_control(const str
- 	vcc->vpi = msg->addr.sap_addr.vpi;
- 	vcc->vci = msg->addr.sap_addr.vci;
- 	vcc->qos = msg->qos;
--	vcc->reply = msg->result;
-+	vcc->sk->sk_err = -msg->result;
- 	switch (msg->type) {
- 	    case ATMTCP_CTRL_OPEN:
- 		change_bit(ATM_VF_READY,&vcc->flags);
-@@ -103,7 +103,7 @@ static int atmtcp_recv_control(const str
- 		    msg->type);
- 		return -EINVAL;
- 	}
--	wake_up(&vcc->sleep);
-+	wake_up(vcc->sk->sk_sleep);
- 	return 0;
- }
- 
-@@ -134,7 +134,7 @@ static int atmtcp_v_open(struct atm_vcc 
- 	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
- 	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
- 	if (error) return error;
--	return vcc->reply;
-+	return -vcc->sk->sk_err;
- }
- 
- 
-@@ -257,7 +257,7 @@ static void atmtcp_c_close(struct atm_vc
- 		walk = atm_sk(s);
- 		if (walk->dev != atmtcp_dev)
- 			continue;
--		wake_up(&walk->sleep);
-+		wake_up(walk->sk->sk_sleep);
- 	}
- 	read_unlock(&vcc_sklist_lock);
- }
---- linux-2.6.0-test1/drivers/base/node.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/base/node.c	2003-07-19 17:04:07.000000000 -0700
-@@ -7,6 +7,7 @@
- #include <linux/init.h>
- #include <linux/mm.h>
- #include <linux/node.h>
-+#include <linux/cpumask.h>
- #include <linux/topology.h>
- 
- static struct sysdev_class node_class = {
-@@ -17,7 +18,17 @@ static struct sysdev_class node_class = 
- static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
- {
- 	struct node *node_dev = to_node(dev);
--        return sprintf(buf,"%lx\n",node_dev->cpumap);
-+	cpumask_t tmp = node_dev->cpumap;
-+	int k, len = 0;
-+
-+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
-+		int j = sprintf(buf, "%04hx", (u16)cpus_coerce(tmp));
-+		len += j;
-+		buf += j;
-+		cpus_shift_right(tmp, tmp, 16);
-+	}
-+        len += sprintf(buf, "\n");
-+	return len;
- }
- static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
- 
---- linux-2.6.0-test1/drivers/block/acsi.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/block/acsi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -55,7 +55,6 @@
- #include <linux/delay.h>
- #include <linux/mm.h>
- #include <linux/major.h>
--#include <linux/blk.h>
- #include <linux/slab.h>
- #include <linux/interrupt.h>
- #include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
---- linux-2.6.0-test1/drivers/block/amiflop.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/block/amiflop.c	2003-07-19 17:03:49.000000000 -0700
-@@ -79,7 +79,6 @@
- #include <asm/amigahw.h>
- #include <asm/amigaints.h>
- #include <asm/irq.h>
--#include <linux/blk.h>
- 
- #undef DEBUG /* print _LOTS_ of infos */
- 
---- linux-2.6.0-test1/drivers/block/as-iosched.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/as-iosched.c	2003-07-19 17:03:49.000000000 -0700
-@@ -12,7 +12,6 @@
- #include <linux/blkdev.h>
- #include <linux/elevator.h>
- #include <linux/bio.h>
--#include <linux/blk.h>
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/slab.h>
-@@ -834,10 +833,11 @@ static void as_update_iohist(struct as_i
- 							+ 2*1024*64);
- 
- 		aic->seek_samples += 256;
--		aic->seek_total += 256*seek_dist;
-+		aic->seek_total += (u64)256*seek_dist;
- 		if (aic->seek_samples) {
--			aic->seek_mean = aic->seek_total + 128;
--			sector_div(aic->seek_mean, aic->seek_samples);
-+			u64 total = aic->seek_total + (aic->seek_samples>>1);
-+			do_div(total, aic->seek_samples);
-+			aic->seek_mean = (sector_t)total;
- 		}
- 		aic->seek_samples = (aic->seek_samples>>1)
- 					+ (aic->seek_samples>>2);
-@@ -1306,6 +1306,15 @@ static void as_add_request(struct as_dat
- 	as_update_arq(ad, arq); /* keep state machine up to date */
- }
- 
-+/*
-+ * FIXME: HACK for AS requeue problems
-+ */
-+static void as_requeue_request(request_queue_t *q, struct request *rq)
-+{
-+	elv_completed_request(q, rq);
-+	__elv_add_request(q, rq, 0, 0);
-+}
-+
- static void
- as_insert_request(request_queue_t *q, struct request *rq,
- 			struct list_head *insert_here)
-@@ -1821,6 +1830,7 @@ elevator_t iosched_as = {
- 	.elevator_next_req_fn =		as_next_request,
- 	.elevator_add_req_fn =		as_insert_request,
- 	.elevator_remove_req_fn =	as_remove_request,
-+	.elevator_requeue_req_fn = 	as_requeue_request,
- 	.elevator_queue_empty_fn =	as_queue_empty,
- 	.elevator_completed_req_fn =	as_completed_request,
- 	.elevator_former_req_fn =	as_former_request,
---- linux-2.6.0-test1/drivers/block/ataflop.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/block/ataflop.c	2003-07-19 17:03:49.000000000 -0700
-@@ -91,7 +91,6 @@
- #include <asm/atariints.h>
- #include <asm/atari_stdma.h>
- #include <asm/atari_stram.h>
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- 
- #define	FD_MAX_UNITS 2
---- linux-2.6.0-test1/drivers/block/cciss.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/drivers/block/cciss.c	2003-07-19 17:03:49.000000000 -0700
-@@ -41,7 +41,6 @@
- #include <asm/uaccess.h>
- #include <asm/io.h>
- 
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/genhd.h>
- #include <linux/completion.h>
---- linux-2.6.0-test1/drivers/block/cciss_scsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/block/cciss_scsi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -712,7 +712,8 @@ cciss_scsi_detect(int ctlr)
- 	sh->hostdata[0] = (unsigned long) hba[ctlr];
- 	sh->irq = hba[ctlr]->intr;
- 	sh->unique_id = sh->irq;
--	scsi_add_host(sh, &hba[ctlr]->pdev->dev);
-+	scsi_add_host(sh, &hba[ctlr]->pdev->dev); /* XXX handle failure */
-+	scsi_scan_host(sh);
- 
- 	return 1;
- }
---- linux-2.6.0-test1/drivers/block/cpqarray.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/block/cpqarray.c	2003-07-19 17:03:49.000000000 -0700
-@@ -38,7 +38,6 @@
- #include <linux/init.h>
- #include <linux/hdreg.h>
- #include <linux/spinlock.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/genhd.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/drivers/block/cryptoloop.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/cryptoloop.c	2003-07-19 17:03:49.000000000 -0700
-@@ -26,7 +26,6 @@
- #include <linux/crypto.h>
- #include <linux/blkdev.h>
- #include <linux/loop.h>
--#include <linux/blk.h>
- #include <asm/semaphore.h>
- #include <asm/uaccess.h>
- 
---- linux-2.6.0-test1/drivers/block/DAC960.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/block/DAC960.c	2003-07-19 17:03:49.000000000 -0700
-@@ -23,7 +23,6 @@
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/types.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/bio.h>
- #include <linux/completion.h>
---- linux-2.6.0-test1/drivers/block/deadline-iosched.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/block/deadline-iosched.c	2003-07-19 17:03:49.000000000 -0700
-@@ -10,7 +10,6 @@
- #include <linux/blkdev.h>
- #include <linux/elevator.h>
- #include <linux/bio.h>
--#include <linux/blk.h>
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/slab.h>
---- linux-2.6.0-test1/drivers/block/elevator.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/drivers/block/elevator.c	2003-07-19 17:03:49.000000000 -0700
-@@ -29,7 +29,6 @@
- #include <linux/blkdev.h>
- #include <linux/elevator.h>
- #include <linux/bio.h>
--#include <linux/blk.h>
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/slab.h>
-@@ -214,6 +213,18 @@ void elv_merge_requests(request_queue_t 
- 		e->elevator_merge_req_fn(q, rq, next);
- }
- 
-+void elv_requeue_request(request_queue_t *q, struct request *rq)
-+{
-+	/*
-+	 * if iosched has an explicit requeue hook, then use that. otherwise
-+	 * just put the request at the front of the queue
-+	 */
-+	if (q->elevator.elevator_requeue_req_fn)
-+		q->elevator.elevator_requeue_req_fn(q, rq);
-+	else
-+		__elv_add_request(q, rq, 0, 0);
-+}
-+
- void __elv_add_request(request_queue_t *q, struct request *rq, int at_end,
- 		       int plug)
- {
-@@ -417,6 +428,7 @@ EXPORT_SYMBOL(elevator_noop);
- 
- EXPORT_SYMBOL(elv_add_request);
- EXPORT_SYMBOL(__elv_add_request);
-+EXPORT_SYMBOL(elv_requeue_request);
- EXPORT_SYMBOL(elv_next_request);
- EXPORT_SYMBOL(elv_remove_request);
- EXPORT_SYMBOL(elv_queue_empty);
---- linux-2.6.0-test1/drivers/block/floppy98.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/floppy98.c	2003-07-19 17:03:49.000000000 -0700
-@@ -277,7 +277,6 @@ static int irqdma_allocated;
- #define LOCAL_END_REQUEST
- #define DEVICE_NAME "floppy"
- 
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- #include <linux/cdrom.h> /* for the compatibility eject ioctl */
- #include <linux/completion.h>
---- linux-2.6.0-test1/drivers/block/floppy.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/drivers/block/floppy.c	2003-07-19 17:15:21.000000000 -0700
-@@ -242,7 +242,7 @@ static int irqdma_allocated;
- #define LOCAL_END_REQUEST
- #define DEVICE_NAME "floppy"
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <linux/cdrom.h> /* for the compatibility eject ioctl */
- #include <linux/completion.h>
-@@ -4261,6 +4261,7 @@ int __init floppy_init(void)
- 			floppy_sizes[i] = MAX_DISK_SIZE << 1;
- 
- 	blk_init_queue(&floppy_queue, do_fd_request, &floppy_lock);
-+	blk_queue_max_hw_segments(&floppy_queue, 1);
- 	reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
- 	config_types();
- 
---- linux-2.6.0-test1/drivers/block/genhd.c	2003-07-10 18:50:30.000000000 -0700
-+++ 25/drivers/block/genhd.c	2003-07-19 17:06:13.000000000 -0700
-@@ -7,7 +7,7 @@
- #include <linux/fs.h>
- #include <linux/genhd.h>
- #include <linux/kernel.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/spinlock.h>
- #include <linux/seq_file.h>
-@@ -336,7 +336,7 @@ static struct sysfs_ops disk_sysfs_ops =
- static ssize_t disk_dev_read(struct gendisk * disk, char *page)
- {
- 	dev_t base = MKDEV(disk->major, disk->first_minor); 
--	return sprintf(page, "%04x\n", (unsigned)base);
-+	return print_dev_t(page, base);
- }
- static ssize_t disk_range_read(struct gendisk * disk, char *page)
- {
---- linux-2.6.0-test1/drivers/block/ioctl.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/block/ioctl.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,5 +1,5 @@
- #include <linux/sched.h>		/* for capable() */
--#include <linux/blk.h>			/* for set_device_ro() */
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <linux/backing-dev.h>
- #include <linux/buffer_head.h>
-@@ -166,13 +166,11 @@ int blkdev_ioctl(struct inode *inode, st
- 			return -EINVAL;
- 		if (get_user(n, (int *) arg))
- 			return -EFAULT;
--		if (n > PAGE_SIZE || n < 512 || (n & (n - 1)))
--			return -EINVAL;
- 		if (bd_claim(bdev, &holder) < 0)
- 			return -EBUSY;
--		set_blocksize(bdev, n);
-+		ret = set_blocksize(bdev, n);
- 		bd_release(bdev);
--		return 0;
-+		return ret;
- 	case BLKPG:
- 		return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg);
- 	case BLKRRPART:
---- linux-2.6.0-test1/drivers/block/Kconfig	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -264,6 +264,7 @@ config BLK_DEV_LOOP
- 
- config BLK_DEV_CRYPTOLOOP
- 	tristate "Cryptoloop Support"
-+	select CRYPTO
- 	depends on BLK_DEV_LOOP
- 	---help---
- 	  Say Y here if you want to be able to use the ciphers that are 
-@@ -339,7 +340,7 @@ config BLK_DEV_INITRD
- 
- config LBD
- 	bool "Support for Large Block Devices"
--	depends on X86
-+	depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH
- 	help
- 	  Say Y here if you want to attach large (bigger than 2TB) discs to
- 	  your machine, or if you want to have a raid or loopback device
---- linux-2.6.0-test1/drivers/block/ll_rw_blk.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/ll_rw_blk.c	2003-07-19 17:06:49.000000000 -0700
-@@ -17,7 +17,7 @@
- #include <linux/module.h>
- #include <linux/backing-dev.h>
- #include <linux/bio.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/highmem.h>
- #include <linux/mm.h>
- #include <linux/kernel_stat.h>
-@@ -371,6 +371,20 @@ void blk_queue_hardsect_size(request_que
- }
- 
- /**
-+ * blk_queue_stack_limits - inherit underlying queue limits for stacked drivers
-+ * @t:	the stacking driver (top)
-+ * @b:  the underlying device (bottom)
-+ **/
-+void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
-+{
-+	t->max_sectors = min(t->max_sectors,b->max_sectors);
-+	t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
-+	t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
-+	t->max_segment_size = min(t->max_segment_size,b->max_segment_size);
-+	t->hardsect_size = max(t->hardsect_size,b->hardsect_size);
-+}
-+
-+/**
-  * blk_queue_segment_boundary - set boundary rules for segment merging
-  * @q:  the request queue for the device
-  * @mask:  the memory boundary mask
-@@ -1494,6 +1508,23 @@ struct request *blk_get_request(request_
- 
- 	return rq;
- }
-+/**
-+ * blk_requeue_request - put a request back on queue
-+ * @q:		request queue where request should be inserted
-+ * @rq:		request to be inserted
-+ *
-+ * Description:
-+ *    Drivers often keep queueing requests until the hardware cannot accept
-+ *    more, when that condition happens we need to put the request back
-+ *    on the queue. Must be called with queue lock held.
-+ */
-+void blk_requeue_request(request_queue_t *q, struct request *rq)
-+{
-+	if (blk_rq_tagged(rq))
-+		blk_queue_end_tag(q, rq);
-+
-+	elv_requeue_request(q, rq);
-+}
- 
- /**
-  * blk_insert_request - insert a special request in to a request queue
-@@ -1659,25 +1690,50 @@ void blk_put_request(struct request *req
- }
- 
- /**
-- * blk_congestion_wait - wait for a queue to become uncongested
-+ * blk_congestion_wait_wq - wait for a queue to become uncongested,
-  * @rw: READ or WRITE
-  * @timeout: timeout in jiffies
-+ * @wait : wait queue entry to use for waiting or async notification
-+ * (NULL defaults to synchronous behaviour)
-  *
-  * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
-  * If no queues are congested then just wait for the next request to be
-  * returned.
-+ *
-+ * If the wait queue parameter specifies an async i/o callback,
-+ * then instead of blocking, just register the callback on the wait
-+ * queue for async notification when the queue gets uncongested.
-  */
--void blk_congestion_wait(int rw, long timeout)
-+int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait)
- {
--	DEFINE_WAIT(wait);
- 	wait_queue_head_t *wqh = &congestion_wqh[rw];
-+	DEFINE_WAIT(local_wait);
-+
-+	if (!wait)
-+		wait = &local_wait;
- 
- 	blk_run_queues();
--	prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-+	prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
-+	if (!is_sync_wait(wait)) {
-+		/*
-+		 * if we've queued an async wait queue
-+		 * callback do not block; just tell the
-+		 * caller to return and retry later when
-+		 * the callback is notified
-+		 */
-+		return -EIOCBRETRY;
-+	}
- 	io_schedule_timeout(timeout);
--	finish_wait(wqh, &wait);
-+	finish_wait(wqh, wait);
-+	return 0;
-+}
-+
-+void blk_congestion_wait(int rw, long timeout)
-+{
-+	blk_congestion_wait_wq(rw, timeout, NULL);
- }
- 
-+
- /*
-  * Has to be called with the request spinlock acquired
-  */
-@@ -2720,6 +2776,7 @@ EXPORT_SYMBOL(blk_queue_max_phys_segment
- EXPORT_SYMBOL(blk_queue_max_hw_segments);
- EXPORT_SYMBOL(blk_queue_max_segment_size);
- EXPORT_SYMBOL(blk_queue_hardsect_size);
-+EXPORT_SYMBOL(blk_queue_stack_limits);
- EXPORT_SYMBOL(blk_queue_segment_boundary);
- EXPORT_SYMBOL(blk_queue_dma_alignment);
- EXPORT_SYMBOL(blk_rq_map_sg);
-@@ -2730,6 +2787,7 @@ EXPORT_SYMBOL(blk_hw_contig_segment);
- EXPORT_SYMBOL(blk_get_request);
- EXPORT_SYMBOL(blk_put_request);
- EXPORT_SYMBOL(blk_insert_request);
-+EXPORT_SYMBOL(blk_requeue_request);
- 
- EXPORT_SYMBOL(blk_queue_prep_rq);
- EXPORT_SYMBOL(blk_queue_merge_bvec);
---- linux-2.6.0-test1/drivers/block/nbd.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/block/nbd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -44,7 +44,6 @@
- 
- #include <linux/major.h>
- 
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/module.h>
- #include <linux/init.h>
-@@ -55,8 +54,6 @@
- #include <linux/errno.h>
- #include <linux/file.h>
- #include <linux/ioctl.h>
--#include <linux/blkdev.h>
--#include <linux/blk.h>
- #include <net/sock.h>
- 
- #include <linux/devfs_fs_kernel.h>
-@@ -261,7 +258,8 @@ void nbd_send_req(struct nbd_device *lo,
- 	dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%luB)\n",
- 			lo->disk->disk_name, req,
- 			nbdcmd_to_ascii(nbd_cmd(req)),
--			req->sector << 9, req->nr_sectors << 9);
-+			(unsigned long long)req->sector << 9,
-+			req->nr_sectors << 9);
- 	result = sock_xmit(sock, 1, &request, sizeof(request),
- 			(nbd_cmd(req) == NBD_CMD_WRITE)? MSG_MORE: 0);
- 	if (result <= 0) {
---- linux-2.6.0-test1/drivers/block/paride/pcd.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/block/paride/pcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -137,7 +137,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV,
- #include <linux/delay.h>
- #include <linux/cdrom.h>
- #include <linux/spinlock.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/uaccess.h>
- 
- static spinlock_t pcd_lock;
---- linux-2.6.0-test1/drivers/block/paride/pd.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/block/paride/pd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -150,7 +150,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO,
- #include <linux/delay.h>
- #include <linux/hdreg.h>
- #include <linux/cdrom.h>	/* for the eject ioctl */
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <asm/uaccess.h>
- 
---- linux-2.6.0-test1/drivers/block/paride/pf.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/block/paride/pf.c	2003-07-19 17:03:49.000000000 -0700
-@@ -150,7 +150,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV,
- #include <linux/hdreg.h>
- #include <linux/cdrom.h>
- #include <linux/spinlock.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <asm/uaccess.h>
- 
-@@ -222,9 +222,6 @@ MODULE_PARM(drive3, "1-7i");
- #define ATAPI_READ_10		0x28
- #define ATAPI_WRITE_10		0x2a
- 
--#ifdef MODULE
--void cleanup_module(void);
--#endif
- static int pf_open(struct inode *inode, struct file *file);
- static void do_pf_request(request_queue_t * q);
- static int pf_ioctl(struct inode *inode, struct file *file,
---- linux-2.6.0-test1/drivers/block/ps2esdi.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/block/ps2esdi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -38,7 +38,7 @@
- #include <linux/kernel.h>
- #include <linux/genhd.h>
- #include <linux/ps2esdi.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/mca.h>
- #include <linux/init.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/block/swim3.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/block/swim3.c	2003-07-19 17:03:49.000000000 -0700
-@@ -24,7 +24,6 @@
- #include <linux/delay.h>
- #include <linux/fd.h>
- #include <linux/ioctl.h>
--#include <linux/blk.h>
- #include <linux/devfs_fs_kernel.h>
- #include <asm/io.h>
- #include <asm/dbdma.h>
---- linux-2.6.0-test1/drivers/block/swim_iop.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/block/swim_iop.c	2003-07-19 17:03:49.000000000 -0700
-@@ -30,7 +30,6 @@
- #include <linux/timer.h>
- #include <linux/delay.h>
- #include <linux/fd.h>
--#include <linux/blk.h>
- #include <linux/ioctl.h>
- #include <asm/io.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/drivers/block/umem.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/block/umem.c	2003-07-19 17:03:49.000000000 -0700
-@@ -99,7 +99,7 @@ static int pci_cmds;
- 
- static int major_nr;
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- 
- struct cardinfo {
---- linux-2.6.0-test1/drivers/block/xd.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/block/xd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -46,7 +46,7 @@
- #include <linux/init.h>
- #include <linux/wait.h>
- #include <linux/devfs_fs_kernel.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- 
- #include <asm/system.h>
---- linux-2.6.0-test1/drivers/block/z2ram.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/block/z2ram.c	2003-07-19 17:03:49.000000000 -0700
-@@ -30,7 +30,6 @@
- #include <linux/major.h>
- #include <linux/slab.h>
- #include <linux/vmalloc.h>
--#include <linux/blk.h>
- #include <linux/init.h>
- #include <linux/module.h>
- 
---- linux-2.6.0-test1/drivers/cdrom/aztcd.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/cdrom/aztcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -166,7 +166,7 @@
- */
- 
- #include <linux/version.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "aztcd.h"
- 
- #include <linux/module.h>
---- linux-2.6.0-test1/drivers/cdrom/cdrom.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/cdrom/cdrom.c	2003-07-19 17:03:49.000000000 -0700
-@@ -268,6 +268,7 @@
- #include <linux/init.h>
- #include <linux/fcntl.h>
- #include <linux/blkdev.h>
-+#include <linux/times.h>
- 
- #include <asm/uaccess.h>
- 
-@@ -2171,6 +2172,7 @@ static int mmc_ioctl(struct cdrom_device
- 			return -ENOSYS;
- 		cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKET\n"); 
- 		IOCTL_IN(arg, struct cdrom_generic_command, cgc);
-+		cgc.timeout = clock_t_to_jiffies(cgc.timeout);
- 		return cdrom_do_cmd(cdi, &cgc);
- 		}
- 	case CDROM_NEXT_WRITABLE: {
---- linux-2.6.0-test1/drivers/cdrom/cdu31a.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/cdrom/cdu31a.c	2003-07-19 17:03:49.000000000 -0700
-@@ -177,7 +177,7 @@
- #include "cdu31a.h"
- 
- #define MAJOR_NR CDU31A_CDROM_MAJOR
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #define CDU31A_READAHEAD 4	/* 128 sector, 64kB, 32 reads read-ahead */
- #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
---- linux-2.6.0-test1/drivers/cdrom/cm206.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/drivers/cdrom/cm206.c	2003-07-19 17:03:49.000000000 -0700
-@@ -199,7 +199,7 @@ History:
- 
- #define MAJOR_NR CM206_CDROM_MAJOR
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #undef DEBUG
- #define STATISTICS		/* record times and frequencies of events */
---- linux-2.6.0-test1/drivers/cdrom/gscd.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/cdrom/gscd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -69,7 +69,7 @@
- #include <asm/uaccess.h>
- 
- #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #define gscd_port gscd		/* for compatible parameter passing with "insmod" */
- #include "gscd.h"
- 
---- linux-2.6.0-test1/drivers/cdrom/mcd.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/cdrom/mcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -101,7 +101,7 @@
- #include <asm/io.h>
- #include <asm/current.h>
- #include <asm/uaccess.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #define mcd_port mcd		/* for compatible parameter passing with "insmod" */
- #include "mcd.h"
---- linux-2.6.0-test1/drivers/cdrom/mcdx.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/cdrom/mcdx.c	2003-07-19 17:03:49.000000000 -0700
-@@ -74,7 +74,7 @@ static const char *mcdx_c_version
- 
- #include <linux/major.h>
- #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/devfs_fs_kernel.h>
- 
- /* for compatible parameter passing with "insmod" */
---- linux-2.6.0-test1/drivers/cdrom/optcd.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/drivers/cdrom/optcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -73,7 +73,7 @@
- #include <linux/init.h>
- 
- #include <asm/io.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <linux/cdrom.h>
- #include "optcd.h"
---- linux-2.6.0-test1/drivers/cdrom/sbpcd.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/cdrom/sbpcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -387,7 +387,7 @@
- #include "sbpcd.h"
- 
- #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- /*==========================================================================*/
- #if SBPCD_DIS_IRQ
---- linux-2.6.0-test1/drivers/cdrom/sjcd.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/cdrom/sjcd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -74,7 +74,7 @@
- #include <asm/system.h>
- #include <asm/io.h>
- #include <asm/uaccess.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "sjcd.h"
- 
- static int sjcd_present = 0;
---- linux-2.6.0-test1/drivers/cdrom/sonycd535.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/cdrom/sonycd535.c	2003-07-19 17:03:49.000000000 -0700
-@@ -134,7 +134,7 @@
- #include <linux/cdrom.h>
- 
- #define MAJOR_NR CDU535_CDROM_MAJOR
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
- #include "sonycd535.h"
---- linux-2.6.0-test1/drivers/char/agp/i460-agp.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/char/agp/i460-agp.c	2003-07-19 17:03:49.000000000 -0700
-@@ -608,7 +608,7 @@ static struct pci_driver agp_intel_i460_
- 	.name		= "agpgart-intel-i460",
- 	.id_table	= agp_intel_i460_pci_table,
- 	.probe		= agp_intel_i460_probe,
--	.remove		= agp_intel_i460_remove,
-+	.remove		= __devexit_p(agp_intel_i460_remove),
- };
- 
- static int __init agp_intel_i460_init(void)
---- linux-2.6.0-test1/drivers/char/busmouse.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/char/busmouse.c	2003-07-19 17:03:49.000000000 -0700
-@@ -357,25 +357,23 @@ int register_busmouse(struct busmouse *o
- {
- 	unsigned int msedev = MINOR_TO_MOUSE(ops->minor);
- 	struct busmouse_data *mse;
--	int ret;
-+	int ret = -EINVAL;
- 
- 	if (msedev >= NR_MICE) {
- 		printk(KERN_ERR "busmouse: trying to allocate mouse on minor %d\n",
- 		       ops->minor);
--		return -EINVAL;
-+		goto out;
- 	}
- 
-+	ret = -ENOMEM;
- 	mse = kmalloc(sizeof(*mse), GFP_KERNEL);
- 	if (!mse)
--		return -ENOMEM;
-+		goto out;
- 
- 	down(&mouse_sem);
-+	ret = -EBUSY;
- 	if (busmouse_data[msedev])
--	{
--		up(&mouse_sem);
--		kfree(mse);
--		return -EBUSY;
--	}
-+		goto freemem;
- 
- 	memset(mse, 0, sizeof(*mse));
- 
-@@ -386,14 +384,22 @@ int register_busmouse(struct busmouse *o
- 	mse->lock = (spinlock_t)SPIN_LOCK_UNLOCKED;
- 	init_waitqueue_head(&mse->wait);
- 
--	busmouse_data[msedev] = mse;
- 
- 	ret = misc_register(&mse->miscdev);
--	if (!ret)
--		ret = msedev;
-+
-+	if (ret < 0) 
-+		goto freemem;
-+
-+	busmouse_data[msedev] = mse;
-+	ret = msedev;
-+out:
- 	up(&mouse_sem);
--	
- 	return ret;
-+
-+
-+freemem:
-+	kfree(mse);
-+	goto out;
- }
- 
- /**
---- linux-2.6.0-test1/drivers/char/drm/drm_memory.h	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/char/drm/drm_memory.h	2003-07-19 17:07:16.000000000 -0700
-@@ -128,7 +128,7 @@ static inline unsigned long
- drm_follow_page (void *vaddr)
- {
- 	pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
--	pmd_t *pmd = pmd_offset(pgd, (unsigned long) vaddr);
-+	pmd_t *pmd = pmd_offset_kernel(pgd, (unsigned long)vaddr);
- 	pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
- 	return pte_pfn(*ptep) << PAGE_SHIFT;
- }
---- linux-2.6.0-test1/drivers/char/ftape/lowlevel/fdc-io.c	2003-06-14 12:18:04.000000000 -0700
-+++ 25/drivers/char/ftape/lowlevel/fdc-io.c	2003-07-19 17:03:49.000000000 -0700
-@@ -66,6 +66,7 @@ int ft_mach2             = CONFIG_FT_MAC
- 
- /*      Local vars.
-  */
-+static spinlock_t fdc_io_lock; 
- static unsigned int fdc_calibr_count;
- static unsigned int fdc_calibr_time;
- static int fdc_status;
-@@ -89,14 +90,13 @@ void fdc_catch_stray_interrupts(int coun
- {
- 	unsigned long flags;
- 
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 	if (count == 0) {
- 		ft_expected_stray_interrupts = 0;
- 	} else {
- 		ft_expected_stray_interrupts += count;
- 	}
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- }
- 
- /*  Wait during a timeout period for a given FDC status.
-@@ -194,8 +194,7 @@ int fdc_command(const __u8 * cmd_data, i
- 	TRACE_FUN(ft_t_any);
- 
- 	fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 	if (!in_interrupt())
- 		/* Yes, I know, too much comments inside this function
- 		 * ...
-@@ -242,12 +241,11 @@ int fdc_command(const __u8 * cmd_data, i
- 
- 			}
- 			fdc_usec_wait(FT_RQM_DELAY);	/* wait for valid RQM status */
--			save_flags(flags);
--			cli();
-+			spin_lock_irqsave(&fdc_io_lock, flags);
- 		}
- 	fdc_status = inb(fdc.msr);
- 	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
--		restore_flags(flags);
-+		spin_unlock_irqrestore(&fdc_io_lock, flags);
- 		TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
- 	} 
- 	fdc_mode = *cmd_data;	/* used by isr */
-@@ -289,7 +287,7 @@ int fdc_command(const __u8 * cmd_data, i
- 		last_time = ftape_timestamp();
- 	}
- #endif
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- 	TRACE_EXIT result;
- }
- 
-@@ -305,15 +303,14 @@ int fdc_result(__u8 * res_data, int res_
- 	int retry = 0;
- 	TRACE_FUN(ft_t_any);
- 
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 	fdc_status = inb(fdc.msr);
- 	if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
- 		TRACE(ft_t_err, "fdc not ready");
- 		result = -EBUSY;
- 	} else while (count) {
- 		if (!(fdc_status & FDC_BUSY)) {
--			restore_flags(flags);
-+			spin_unlock_irqrestore(&fdc_io_lock, flags);
- 			TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
- 		}
- 		result = fdc_read(res_data);
-@@ -336,7 +333,7 @@ int fdc_result(__u8 * res_data, int res_
- 			++res_data;
- 		}
- 	}
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- 	fdc_usec_wait(FT_RQM_DELAY);	/* allow FDC to negate BSY */
- 	TRACE_EXIT result;
- }
-@@ -609,8 +606,7 @@ void fdc_reset(void)
- 	unsigned long flags;
- 	TRACE_FUN(ft_t_any);
- 
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 
- 	fdc_dor_reset(1); /* keep unit selected */
- 
-@@ -629,7 +625,7 @@ void fdc_reset(void)
- 	 */
- 	fdc_update_dsr();               /* restore data rate and precomp */
- 
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- 
-         /*
-          *	Wait for first polling cycle to complete
-@@ -928,8 +924,7 @@ int fdc_setup_formatting(buffer_struct *
- 	 */
-         TRACE(ft_t_fdc_dma,
- 	      "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
--	save_flags(flags);
--	cli();			/* could be called from ISR ! */
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 	fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
- 	/* Issue FDC command to start reading/writing.
- 	 */
-@@ -937,7 +932,7 @@ int fdc_setup_formatting(buffer_struct *
- 	out[4] = buff->gap3;
- 	TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
- 		    restore_flags(flags); fdc_mode = fdc_idle);
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- 	TRACE_EXIT 0;
- }
- 
-@@ -977,11 +972,10 @@ int fdc_setup_read_write(buffer_struct *
- 		break;
- 	default:
- 		TRACE_ABORT(-EIO,
--			    ft_t_bug, "bug: illegal operation parameter");
-+			    ft_t_bug, "bug: invalid operation parameter");
- 	}
- 	TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
--	save_flags(flags);
--	cli();			/* could be called from ISR ! */
-+	spin_lock_irqsave(&fdc_io_lock, flags);
- 	if (operation != FDC_VERIFY) {
- 		fdc_setup_dma(dma_mode, buff->ptr,
- 			      FT_SECTOR_SIZE * buff->sector_count);
-@@ -999,7 +993,7 @@ int fdc_setup_read_write(buffer_struct *
- 	out[8] = 0xff;		/* No limit to transfer size. */
- 	TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
- 		out[2], out[3], out[4], out[6] - out[4] + 1);
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&fdc_io_lock, flags);
- 	TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
- 	TRACE_EXIT 0;
- }
---- linux-2.6.0-test1/drivers/char/ftape/lowlevel/ftape-calibr.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/char/ftape/lowlevel/ftape-calibr.c	2003-07-19 17:03:49.000000000 -0700
-@@ -49,6 +49,8 @@
- static unsigned long ps_per_cycle = 0;
- #endif
- 
-+static spinlock_t calibr_lock;
-+
- /*
-  * Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is
-  * too slow for certain timeouts (and that clock doesn't even tick
-@@ -75,13 +77,12 @@ unsigned int ftape_timestamp(void)
- 	__u16 lo;
- 	__u16 hi;
- 
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&calibr_lock, flags);
- 	outb_p(0x00, 0x43);	/* latch the count ASAP */
- 	lo = inb_p(0x40);	/* read the latched count */
- 	lo |= inb(0x40) << 8;
- 	hi = jiffies;
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&calibr_lock, flags);
- 	return ((hi + 1) * (unsigned int) LATCH) - lo;  /* downcounter ! */
- #endif
- }
-@@ -94,12 +95,11 @@ static unsigned int short_ftape_timestam
- 	unsigned int count;
-  	unsigned long flags;
-  
-- 	save_flags(flags);
-- 	cli();
-+	spin_lock_irqsave(&calibr_lock, flags);
-  	outb_p(0x00, 0x43);	/* latch the count ASAP */
- 	count = inb_p(0x40);	/* read the latched count */
- 	count |= inb(0x40) << 8;
-- 	restore_flags(flags);
-+	spin_unlock_irqrestore(&calibr_lock, flags);
- 	return (LATCH - count);	/* normal: downcounter */
- #endif
- }
-@@ -150,14 +150,13 @@ static void time_inb(void)
- 	int status;
- 	TRACE_FUN(ft_t_any);
- 
--	save_flags(flags);
--	cli();
-+	spin_lock_irqsave(&calibr_lock, flags);
- 	t0 = short_ftape_timestamp();
- 	for (i = 0; i < 1000; ++i) {
- 		status = inb(fdc.msr);
- 	}
- 	t1 = short_ftape_timestamp();
--	restore_flags(flags);
-+	spin_unlock_irqrestore(&calibr_lock, flags);
- 	TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1));
- 	TRACE_EXIT;
- }
-@@ -241,8 +240,7 @@ void ftape_calibrate(char *name,
- 
- 		*calibr_count =
- 		*calibr_time = count;	/* set TC to 1 */
--		save_flags(flags);
--		cli();
-+		spin_lock_irqsave(&calibr_lock, flags);
- 		fun(0);		/* dummy, get code into cache */
- 		t0 = short_ftape_timestamp();
- 		fun(0);		/* overhead + one test */
-@@ -252,7 +250,7 @@ void ftape_calibrate(char *name,
- 		fun(count);		/* overhead + count tests */
- 		t1 = short_ftape_timestamp();
- 		multiple = diff(t0, t1);
--		restore_flags(flags);
-+		spin_unlock_irqrestore(&calibr_lock, flags);
- 		time = ftape_timediff(0, multiple - once);
- 		tc = (1000 * time) / (count - 1);
- 		TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns",
---- linux-2.6.0-test1/drivers/char/ftape/lowlevel/ftape-format.c	2003-06-14 12:18:21.000000000 -0700
-+++ 25/drivers/char/ftape/lowlevel/ftape-format.c	2003-07-19 17:03:49.000000000 -0700
-@@ -44,6 +44,8 @@
- #define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT))
- #endif
- 
-+static spinlock_t ftape_format_lock;
-+
- /*
-  *  first segment of the new buffer
-  */
-@@ -129,9 +131,9 @@ int ftape_format_track(const unsigned in
- 	head->status = formatting;
- 	TRACE_CATCH(ftape_seek_head_to_track(track),);
- 	TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),);
--	save_flags(flags); cli();
-+	spin_lock_irqsave(&ftape_format_lock, flags);
- 	TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags));
--	restore_flags(flags);	
-+	spin_unlock_irqrestore(&ftape_format_lock, flags);
- 	TRACE_EXIT 0;
- }
- 
---- linux-2.6.0-test1/drivers/char/ftape/zftape/zftape-init.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/char/ftape/zftape/zftape-init.c	2003-07-19 17:03:49.000000000 -0700
-@@ -118,7 +118,7 @@ static int zft_open(struct inode *ino, s
- 	     > 
- 	    FTAPE_SEL_D) {
- 		clear_bit(0,&busy_flag);
--		TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr");
-+		TRACE_ABORT(-ENXIO, ft_t_err, "failed: invalid unit nr");
- 	}
- 	orig_sigmask = current->blocked;
- 	sigfillset(&current->blocked);
---- linux-2.6.0-test1/drivers/char/ip2.c	2003-06-14 12:18:20.000000000 -0700
-+++ 25/drivers/char/ip2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -38,16 +38,14 @@ static int irq[IP2_MAX_BOARDS] = { -1, -
- 
- static int poll_only = 0;
- 
--#	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--		MODULE_AUTHOR("Doug McNash");
--		MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
--		MODULE_PARM(irq,"1-"__MODULE_STRING(IP2_MAX_BOARDS) "i");
--		MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards");
--		MODULE_PARM(io,"1-"__MODULE_STRING(IP2_MAX_BOARDS) "i");
--		MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards");
--		MODULE_PARM(poll_only,"1i");
--		MODULE_PARM_DESC(poll_only,"Do not use card interrupts");
--#	endif	/* LINUX_VERSION */
-+MODULE_AUTHOR("Doug McNash");
-+MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
-+MODULE_PARM(irq,"1-"__MODULE_STRING(IP2_MAX_BOARDS) "i");
-+MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards");
-+MODULE_PARM(io,"1-"__MODULE_STRING(IP2_MAX_BOARDS) "i");
-+MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards");
-+MODULE_PARM(poll_only,"1i");
-+MODULE_PARM_DESC(poll_only,"Do not use card interrupts");
- 
- 
- //======================================================================
---- linux-2.6.0-test1/drivers/char/ip2/i2lib.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/char/ip2/i2lib.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1089,7 +1089,7 @@ i2Output(i2ChanStrPtr pCh, const char *p
- 
- 			// Move the data
- 			if ( user ) {
--				COPY_FROM_USER(rc, (char*)(DATA_OF(pInsert)), pSource,
-+				rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
- 						amountToMove );
- 			} else {
- 				memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
---- linux-2.6.0-test1/drivers/char/ip2/i2os.h	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/char/ip2/i2os.h	2003-07-19 17:03:49.000000000 -0700
-@@ -19,8 +19,6 @@
- #ifndef I2OS_H    /* To prevent multiple includes */
- #define I2OS_H 1
- 
--#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
--
- //-------------------------------------------------
- // Required Includes
- //-------------------------------------------------
-@@ -46,22 +44,6 @@
- // Interrupt control
- //--------------------------------------------
- 
--#if LINUX_VERSION_CODE < 0x00020100
--typedef int spinlock_t;
--#define spin_lock_init() 
--#define spin_lock(a)
--#define spin_unlock(a)
--#define spin_lock_irqsave(a,b)			{save_flags((b));cli();}
--#define spin_unlock_irqrestore(a,b)		{restore_flags((b));}
--#define write_lock_irqsave(a,b)			spin_lock_irqsave(a,b)
--#define write_unlock_irqrestore(a,b)	spin_unlock_irqrestore(a,b)
--#define read_lock_irqsave(a,b)			spin_lock_irqsave(a,b)
--#define read_unlock_irqrestore(a,b)		spin_unlock_irqrestore(a,b)
--#endif
--
--//#define SAVE_AND_DISABLE_INTS(a,b)	spin_lock_irqsave(a,b)
--//#define RESTORE_INTS(a,b)         	spin_unlock_irqrestore(a,b)
--
- #define LOCK_INIT(a)	rwlock_init(a)
- 
- #define SAVE_AND_DISABLE_INTS(a,b) { \
---- linux-2.6.0-test1/drivers/char/ip2main.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/char/ip2main.c	2003-07-19 17:03:49.000000000 -0700
-@@ -83,7 +83,6 @@
- /* Includes */
- /************/
- #include <linux/config.h>
--// Uncomment the following if you want it compiled with modversions
- 
- #include <linux/version.h>
- 
-@@ -120,82 +119,11 @@
- #include <asm/irq.h>
- #include <asm/bitops.h>
- 
--#ifndef KERNEL_VERSION
--#define KERNEL_VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
--#endif
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--#	include <linux/vmalloc.h>
--#	include <linux/init.h>
--#	include <asm/serial.h>
--#else
--#	include <linux/bios32.h>
--#endif
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
-+#include <asm/serial.h>
- 
--// These VERSION switches maybe inexact because I simply don't know
--// when the various features appeared in the 2.1.XX kernels.
--// They are good enough for 2.0 vs 2.2 and if you are fooling with
--// the 2.1.XX stuff then it would be trivial for you to fix.
--// Most of these macros were stolen from some other drivers
--// so blame them.
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,4)
--#	define GET_USER(error,value,addr) error = get_user(value,addr)
--#	define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
--#	define PUT_USER(error,value,addr) error = put_user(value,addr)
--#	define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
--
--#	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,5)
--#		include <asm/uaccess.h>
--#		define		pcibios_strerror(status)	\
--					printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
--#	endif
--
--#else  /* 2.0.x and 2.1.x before 2.1.4 */
--
--#	define		proc_register_dynamic(a,b) proc_register(a,b) 
--
--#	define GET_USER(error,value,addr)					  \
--	do {									  \
--		error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \
--		if (error == 0)							  \
--			value = get_user(addr);					  \
--	} while (0)
--
--#	define COPY_FROM_USER(error,dest,src,size)				  \
--	do {									  \
--		error = verify_area (VERIFY_READ, (void *) src, size);		  \
--		if (error == 0)							  \
--			memcpy_fromfs (dest, src, size);			  \
--	} while (0)
--
--#	define PUT_USER(error,value,addr)					   \
--	do {									   \
--		error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \
--		if (error == 0)							   \
--			put_user (value, addr);					   \
--	} while (0)
--
--#	define COPY_TO_USER(error,dest,src,size)				  \
--	do {									  \
--		error = verify_area (VERIFY_WRITE, (void *) dest, size);		  \
--		if (error == 0)							  \
--			memcpy_tofs (dest, src, size);				  \
--	} while (0)
--
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
--#define __init
--#define __initfunc(a) a
--#define __initdata
--#define ioremap(a,b) vremap((a),(b))
--#define iounmap(a) vfree((a))
--#define SERIAL_TYPE_NORMAL	1
--#define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}
--#define signal_pending(a) ((a)->signal & ~(a)->blocked)
--#define in_interrupt()	intr_count
--#endif
-+#include <asm/uaccess.h>
- 
- #include "./ip2/ip2types.h"
- #include "./ip2/ip2trace.h"
-@@ -276,11 +204,7 @@ static int set_modem_info(i2ChanStrPtr, 
- static int get_serial_info(i2ChanStrPtr, struct serial_struct *);
- static int set_serial_info(i2ChanStrPtr, struct serial_struct *);
- 
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
--static int     ip2_ipl_read(struct inode *, char *, size_t , loff_t *);
--#else
--static ssize_t ip2_ipl_read(struct file *, char *, size_t, loff_t *) ;
--#endif
-+static ssize_t ip2_ipl_read(struct file *, char *, size_t, loff_t *);
- static ssize_t ip2_ipl_write(struct file *, const char *, size_t, loff_t *);
- static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
- static int ip2_ipl_open(struct inode *, struct file *);
-@@ -354,9 +278,6 @@ static int tracewrap;
- #define DBG_CNT(s)
- #endif
- 
--#define MIN(a,b)	( ( (a) < (b) ) ? (a) : (b) )
--#define MAX(a,b)	( ( (a) > (b) ) ? (a) : (b) )
--
- /********/
- /* Code */
- /********/
-@@ -366,12 +287,9 @@ static int tracewrap;
- #include "./ip2/i2lib.c"      /* High level interface services */
- 
- /* Configuration area for modprobe */
--#ifdef MODULE
--#	if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--		MODULE_AUTHOR("Doug McNash");
--		MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
--#	endif	/* LINUX_VERSION */
--#endif	/* MODULE */
-+
-+MODULE_AUTHOR("Doug McNash");
-+MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
- 
- static int poll_only = 0;
- 
-@@ -660,53 +578,6 @@ ip2_loadmain(int *iop, int *irqp, unsign
- 			break;
- 		case PCI:
- #ifdef CONFIG_PCI
--#if (LINUX_VERSION_CODE < 0x020163) /* 2.1.99 */
--			if (pcibios_present()) {
--				unsigned char pci_bus, pci_devfn;
--				int Pci_index = 0;
--				status = pcibios_find_device(PCI_VENDOR_ID_COMPUTONE,
--							  PCI_DEVICE_ID_COMPUTONE_IP2EX, Pci_index,
--							  &pci_bus, &pci_devfn);
--				if (status == 0) {
--					unsigned int addr;
--					unsigned char pci_irq;
--
--					ip2config.type[i] = PCI;
--					/* 
--					 * Update Pci_index, so that the next time we go
--					 * searching for a PCI board we find a different
--					 * one.
--					 */
--					++Pci_index;
--
--					pcibios_read_config_dword(pci_bus, pci_devfn,
--								  PCI_BASE_ADDRESS_1, &addr);
--					if ( addr & 1 ) {
--						ip2config.addr[i]=(USHORT)(addr&0xfffe);
--					} else {
--						printk( KERN_ERR "IP2: PCI I/O address error\n");
--					}
--					pcibios_read_config_byte(pci_bus, pci_devfn,
--								  PCI_INTERRUPT_LINE, &pci_irq);
--
--//		If the PCI BIOS assigned it, lets try and use it.  If we
--//		can't acquire it or it screws up, deal with it then.
--
--//					if (!is_valid_irq(pci_irq)) {
--//						printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
--//						pci_irq = 0;
--//					}
--					ip2config.irq[i] = pci_irq;
--				} else {	// ann error
--					ip2config.addr[i] = 0;
--					if (status == PCIBIOS_DEVICE_NOT_FOUND) {
--						printk( KERN_ERR "IP2: PCI board %d not found\n", i );
--					} else {
--						pcibios_strerror(status);
--					}
--				} 
--			} 
--#else /* LINUX_VERSION_CODE > 2.1.99 */
- 			{
- 				struct pci_dev *pci_dev_i = NULL;
- 				pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
-@@ -739,11 +610,10 @@ ip2_loadmain(int *iop, int *irqp, unsign
- 					if (status == PCIBIOS_DEVICE_NOT_FOUND) {
- 						printk( KERN_ERR "IP2: PCI board %d not found\n", i );
- 					} else {
--						pcibios_strerror(status);
-+						printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
- 					}
- 				} 
- 			}
--#endif	/* ! 2_0_X */
- #else
- 			printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
- 			printk( KERN_ERR "IP2: configured in this kernel.\n");
-@@ -2193,7 +2063,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile
- 
- 		ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
- 
--			PUT_USER(rc,C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
-+			rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
- 		if (rc)	
- 			return rc;
- 	break;
-@@ -2202,7 +2072,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile
- 
- 		ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
- 
--		GET_USER(rc,arg,(unsigned long *) arg);
-+		rc = get_user(arg,(unsigned long *) arg);
- 		if (rc) 
- 			return rc;
- 		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
-@@ -2243,7 +2113,7 @@ ip2_ioctl ( PTTY tty, struct file *pFile
- 			return -EINTR;
- 		}
- #endif
--		PUT_USER(rc,
-+		rc = put_user(
- 				    ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
- 				  | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
- 				  | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
-@@ -2333,17 +2203,17 @@ ip2_ioctl ( PTTY tty, struct file *pFile
- 		cnow = pCh->icount;
- 		restore_flags(flags);
- 		p_cuser = (struct serial_icounter_struct *) arg;
--		PUT_USER(rc,cnow.cts, &p_cuser->cts);
--		PUT_USER(rc,cnow.dsr, &p_cuser->dsr);
--		PUT_USER(rc,cnow.rng, &p_cuser->rng);
--		PUT_USER(rc,cnow.dcd, &p_cuser->dcd);
--		PUT_USER(rc,cnow.rx, &p_cuser->rx);
--		PUT_USER(rc,cnow.tx, &p_cuser->tx);
--		PUT_USER(rc,cnow.frame, &p_cuser->frame);
--		PUT_USER(rc,cnow.overrun, &p_cuser->overrun);
--		PUT_USER(rc,cnow.parity, &p_cuser->parity);
--		PUT_USER(rc,cnow.brk, &p_cuser->brk);
--		PUT_USER(rc,cnow.buf_overrun, &p_cuser->buf_overrun);
-+		rc = put_user(cnow.cts, &p_cuser->cts);
-+		rc = put_user(cnow.dsr, &p_cuser->dsr);
-+		rc = put_user(cnow.rng, &p_cuser->rng);
-+		rc = put_user(cnow.dcd, &p_cuser->dcd);
-+		rc = put_user(cnow.rx, &p_cuser->rx);
-+		rc = put_user(cnow.tx, &p_cuser->tx);
-+		rc = put_user(cnow.frame, &p_cuser->frame);
-+		rc = put_user(cnow.overrun, &p_cuser->overrun);
-+		rc = put_user(cnow.parity, &p_cuser->parity);
-+		rc = put_user(cnow.brk, &p_cuser->brk);
-+		rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
- 		break;
- 
- 	/*
-@@ -2387,7 +2257,7 @@ set_modem_info(i2ChanStrPtr pCh, unsigne
- 	int rc;
- 	unsigned int arg;
- 
--	GET_USER(rc,arg,value);
-+	rc = get_user(arg,value);
- 	if (rc)
- 		return rc;
- 	switch(cmd) {
-@@ -2469,7 +2339,7 @@ get_serial_info ( i2ChanStrPtr pCh, stru
- 	tmp.close_delay = pCh->ClosingDelay;
- 	tmp.closing_wait = pCh->ClosingWaitTime;
- 	tmp.custom_divisor = pCh->BaudDivisor;
--   	COPY_TO_USER(rc,retinfo,&tmp,sizeof(*retinfo));
-+   	rc = copy_to_user(retinfo,&tmp,sizeof(*retinfo));
-    return rc;
- }
- 
-@@ -2489,15 +2359,15 @@ set_serial_info( i2ChanStrPtr pCh, struc
- {
- 	struct serial_struct ns;
- 	int   old_flags, old_baud_divisor;
--	int     rc = 0;
- 
- 	if ( !new_info ) {
- 		return -EFAULT;
- 	}
--	COPY_FROM_USER(rc, &ns, new_info, sizeof (ns) );
--	if (rc) {
--		return rc;
-+
-+	if (copy_from_user(&ns, new_info, sizeof (ns))) {
-+		return -EFAULT;
- 	}
-+
- 	/*
- 	 * We don't allow setserial to change IRQ, board address, type or baud
- 	 * base. Also line nunber as such is meaningless but we use it for our
-@@ -2537,7 +2407,7 @@ set_serial_info( i2ChanStrPtr pCh, struc
- 		set_params( pCh, NULL );
- 	}
- 
--	return rc;
-+	return 0;
- }
- 
- /******************************************************************************/
-@@ -2860,16 +2730,10 @@ service_it:
- /******************************************************************************/
- 
- static 
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
--int
--ip2_ipl_read(struct inode *pInode, char *pData, size_t count, loff_t *off )
--	unsigned int minor = minor( pInode->i_rdev );
--#else
- ssize_t
- ip2_ipl_read(struct file *pFile, char *pData, size_t count, loff_t *off )
- {
- 	unsigned int minor = minor( pFile->f_dentry->d_inode->i_rdev );
--#endif
- 	int rc = 0;
- 
- #ifdef IP2DEBUG_IPL
-@@ -2904,7 +2768,7 @@ DumpFifoBuffer ( char *pData, int count 
- {
- #ifdef DEBUG_FIFO
- 	int rc;
--	COPY_TO_USER(rc, pData, DBGBuf, count);
-+	rc = copy_to_user(pData, DBGBuf, count);
- 
- 	printk(KERN_DEBUG "Last index %d\n", I );
- 
-@@ -2925,10 +2789,10 @@ DumpTraceBuffer ( char *pData, int count
- 	if ( count < (sizeof(int) * 6) ) {
- 		return -EIO;
- 	}
--	PUT_USER(rc, tracewrap, pIndex );
--	PUT_USER(rc, TRACEMAX, ++pIndex );
--	PUT_USER(rc, tracestrip, ++pIndex );
--	PUT_USER(rc, tracestuff, ++pIndex );
-+	rc = put_user(tracewrap, pIndex );
-+	rc = put_user(TRACEMAX, ++pIndex );
-+	rc = put_user(tracestrip, ++pIndex );
-+	rc = put_user(tracestuff, ++pIndex );
- 	pData += sizeof(int) * 6;
- 	count -= sizeof(int) * 6;
- 
-@@ -2941,7 +2805,7 @@ DumpTraceBuffer ( char *pData, int count
- 	}
- 	chunk = TRACEMAX - tracestrip;
- 	if ( dumpcount > chunk ) {
--		COPY_TO_USER(rc, pData, &tracebuf[tracestrip],
-+		rc = copy_to_user(pData, &tracebuf[tracestrip],
- 			      chunk * sizeof(tracebuf[0]) );
- 		pData += chunk * sizeof(tracebuf[0]);
- 		tracestrip = 0;
-@@ -2949,13 +2813,13 @@ DumpTraceBuffer ( char *pData, int count
- 	} else {
- 		chunk = dumpcount;
- 	}
--	COPY_TO_USER(rc, pData, &tracebuf[tracestrip],
-+	rc = copy_to_user(pData, &tracebuf[tracestrip],
- 		      chunk * sizeof(tracebuf[0]) );
- 	tracestrip += chunk;
- 	tracewrap = 0;
- 
--	PUT_USER(rc, tracestrip, ++pIndex );
--	PUT_USER(rc, tracestuff, ++pIndex );
-+	rc = put_user(tracestrip, ++pIndex );
-+	rc = put_user(tracestuff, ++pIndex );
- 
- 	return dumpcount;
- #else
-@@ -3019,15 +2883,15 @@ ip2_ipl_ioctl ( struct inode *pInode, st
- 	case 13:
- 		switch ( cmd ) {
- 		case 64:	/* Driver - ip2stat */
--			PUT_USER(rc, ip2_tty_driver->refcount, pIndex++ );
--			PUT_USER(rc, irq_counter, pIndex++  );
--			PUT_USER(rc, bh_counter, pIndex++  );
-+			rc = put_user(ip2_tty_driver->refcount, pIndex++ );
-+			rc = put_user(irq_counter, pIndex++  );
-+			rc = put_user(bh_counter, pIndex++  );
- 			break;
- 
- 		case 65:	/* Board  - ip2stat */
- 			if ( pB ) {
--				COPY_TO_USER(rc, (char*)arg, (char*)pB, sizeof(i2eBordStr) );
--				PUT_USER(rc, INB(pB->i2eStatus),
-+				rc = copy_to_user((char*)arg, (char*)pB, sizeof(i2eBordStr) );
-+				rc = put_user(INB(pB->i2eStatus),
- 					(ULONG*)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
- 			} else {
- 				rc = -ENODEV;
-@@ -3039,7 +2903,7 @@ ip2_ipl_ioctl ( struct inode *pInode, st
- 				pCh = DevTable[cmd];
- 				if ( pCh )
- 				{
--					COPY_TO_USER(rc, (char*)arg, (char*)pCh, sizeof(i2ChanStr) );
-+					rc = copy_to_user((char*)arg, (char*)pCh, sizeof(i2ChanStr) );
- 				} else {
- 					rc = -ENODEV;
- 				}
-@@ -3054,60 +2918,60 @@ ip2_ipl_ioctl ( struct inode *pInode, st
- 		break;
- 	case 3:	    // Trace device
- 		if ( cmd == 1 ) {
--			PUT_USER(rc, iiSendPendingMail, pIndex++ );
--			PUT_USER(rc, i2InitChannels, pIndex++ );
--			PUT_USER(rc, i2QueueNeeds, pIndex++ );
--			PUT_USER(rc, i2QueueCommands, pIndex++ );
--			PUT_USER(rc, i2GetStatus, pIndex++ );
--			PUT_USER(rc, i2Input, pIndex++ );
--			PUT_USER(rc, i2InputFlush, pIndex++ );
--			PUT_USER(rc, i2Output, pIndex++ );
--			PUT_USER(rc, i2FlushOutput, pIndex++ );
--			PUT_USER(rc, i2DrainWakeup, pIndex++ );
--			PUT_USER(rc, i2DrainOutput, pIndex++ );
--			PUT_USER(rc, i2OutputFree, pIndex++ );
--			PUT_USER(rc, i2StripFifo, pIndex++ );
--			PUT_USER(rc, i2StuffFifoBypass, pIndex++ );
--			PUT_USER(rc, i2StuffFifoFlow, pIndex++ );
--			PUT_USER(rc, i2StuffFifoInline, pIndex++ );
--			PUT_USER(rc, i2ServiceBoard, pIndex++ );
--			PUT_USER(rc, serviceOutgoingFifo, pIndex++ );
--			// PUT_USER(rc, ip2_init, pIndex++ );
--			PUT_USER(rc, ip2_init_board, pIndex++ );
--			PUT_USER(rc, find_eisa_board, pIndex++ );
--			PUT_USER(rc, set_irq, pIndex++ );
--			PUT_USER(rc, ip2_interrupt, pIndex++ );
--			PUT_USER(rc, ip2_poll, pIndex++ );
--			PUT_USER(rc, service_all_boards, pIndex++ );
--			PUT_USER(rc, do_input, pIndex++ );
--			PUT_USER(rc, do_status, pIndex++ );
-+			rc = put_user(iiSendPendingMail, pIndex++ );
-+			rc = put_user(i2InitChannels, pIndex++ );
-+			rc = put_user(i2QueueNeeds, pIndex++ );
-+			rc = put_user(i2QueueCommands, pIndex++ );
-+			rc = put_user(i2GetStatus, pIndex++ );
-+			rc = put_user(i2Input, pIndex++ );
-+			rc = put_user(i2InputFlush, pIndex++ );
-+			rc = put_user(i2Output, pIndex++ );
-+			rc = put_user(i2FlushOutput, pIndex++ );
-+			rc = put_user(i2DrainWakeup, pIndex++ );
-+			rc = put_user(i2DrainOutput, pIndex++ );
-+			rc = put_user(i2OutputFree, pIndex++ );
-+			rc = put_user(i2StripFifo, pIndex++ );
-+			rc = put_user(i2StuffFifoBypass, pIndex++ );
-+			rc = put_user(i2StuffFifoFlow, pIndex++ );
-+			rc = put_user(i2StuffFifoInline, pIndex++ );
-+			rc = put_user(i2ServiceBoard, pIndex++ );
-+			rc = put_user(serviceOutgoingFifo, pIndex++ );
-+			// rc = put_user(ip2_init, pIndex++ );
-+			rc = put_user(ip2_init_board, pIndex++ );
-+			rc = put_user(find_eisa_board, pIndex++ );
-+			rc = put_user(set_irq, pIndex++ );
-+			rc = put_user(ip2_interrupt, pIndex++ );
-+			rc = put_user(ip2_poll, pIndex++ );
-+			rc = put_user(service_all_boards, pIndex++ );
-+			rc = put_user(do_input, pIndex++ );
-+			rc = put_user(do_status, pIndex++ );
- #ifndef IP2DEBUG_OPEN
--			PUT_USER(rc, 0, pIndex++ );
-+			rc = put_user(0, pIndex++ );
- #else
--			PUT_USER(rc, open_sanity_check, pIndex++ );
-+			rc = put_user(open_sanity_check, pIndex++ );
- #endif
--			PUT_USER(rc, ip2_open, pIndex++ );
--			PUT_USER(rc, ip2_close, pIndex++ );
--			PUT_USER(rc, ip2_hangup, pIndex++ );
--			PUT_USER(rc, ip2_write, pIndex++ );
--			PUT_USER(rc, ip2_putchar, pIndex++ );
--			PUT_USER(rc, ip2_flush_chars, pIndex++ );
--			PUT_USER(rc, ip2_write_room, pIndex++ );
--			PUT_USER(rc, ip2_chars_in_buf, pIndex++ );
--			PUT_USER(rc, ip2_flush_buffer, pIndex++ );
--
--			//PUT_USER(rc, ip2_wait_until_sent, pIndex++ );
--			PUT_USER(rc, 0, pIndex++ );
--
--			PUT_USER(rc, ip2_throttle, pIndex++ );
--			PUT_USER(rc, ip2_unthrottle, pIndex++ );
--			PUT_USER(rc, ip2_ioctl, pIndex++ );
--			PUT_USER(rc, set_modem_info, pIndex++ );
--			PUT_USER(rc, get_serial_info, pIndex++ );
--			PUT_USER(rc, set_serial_info, pIndex++ );
--			PUT_USER(rc, ip2_set_termios, pIndex++ );
--			PUT_USER(rc, ip2_set_line_discipline, pIndex++ );
--			PUT_USER(rc, set_params, pIndex++ );
-+			rc = put_user(ip2_open, pIndex++ );
-+			rc = put_user(ip2_close, pIndex++ );
-+			rc = put_user(ip2_hangup, pIndex++ );
-+			rc = put_user(ip2_write, pIndex++ );
-+			rc = put_user(ip2_putchar, pIndex++ );
-+			rc = put_user(ip2_flush_chars, pIndex++ );
-+			rc = put_user(ip2_write_room, pIndex++ );
-+			rc = put_user(ip2_chars_in_buf, pIndex++ );
-+			rc = put_user(ip2_flush_buffer, pIndex++ );
-+
-+			//rc = put_user(ip2_wait_until_sent, pIndex++ );
-+			rc = put_user(0, pIndex++ );
-+
-+			rc = put_user(ip2_throttle, pIndex++ );
-+			rc = put_user(ip2_unthrottle, pIndex++ );
-+			rc = put_user(ip2_ioctl, pIndex++ );
-+			rc = put_user(set_modem_info, pIndex++ );
-+			rc = put_user(get_serial_info, pIndex++ );
-+			rc = put_user(set_serial_info, pIndex++ );
-+			rc = put_user(ip2_set_termios, pIndex++ );
-+			rc = put_user(ip2_set_line_discipline, pIndex++ );
-+			rc = put_user(set_params, pIndex++ );
- 		} else {
- 			rc = -EINVAL;
- 		}
---- linux-2.6.0-test1/drivers/char/istallion.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/char/istallion.c	2003-07-19 17:03:49.000000000 -0700
-@@ -650,8 +650,6 @@ static unsigned int	stli_baudrates[] = {
-  */
- 
- #ifdef MODULE
--int		init_module(void);
--void		cleanup_module(void);
- static void	stli_argbrds(void);
- static int	stli_parsebrd(stlconf_t *confp, char **argp);
- 
---- linux-2.6.0-test1/drivers/char/keyboard.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/drivers/char/keyboard.c	2003-07-19 17:04:02.000000000 -0700
-@@ -1055,6 +1055,9 @@ void kbd_keycode(unsigned int keycode, i
- 	}
- 	if (sysrq_down && down && !rep) {
- 		handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
-+#ifdef CONFIG_KGDB_SYSRQ
-+                sysrq_down = 0;        /* in case we miss the "up" event */
-+#endif
- 		return;
- 	}
- #endif
---- linux-2.6.0-test1/drivers/char/moxa.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/char/moxa.c	2003-07-19 17:03:49.000000000 -0700
-@@ -216,10 +216,7 @@ static struct timer_list moxaEmptyTimer[
- static struct semaphore moxaBuffSem;
- 
- int moxa_init(void);
--#ifdef MODULE
--int init_module(void);
--void cleanup_module(void);
--#endif
-+
- /*
-  * static functions:
-  */
---- linux-2.6.0-test1/drivers/char/nwbutton.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/drivers/char/nwbutton.h	2003-07-19 17:03:49.000000000 -0700
-@@ -32,10 +32,6 @@ int button_init (void);
- int button_add_callback (void (*callback) (void), int count);
- int button_del_callback (void (*callback) (void));
- static void button_consume_callbacks (int bpcount);
--#ifdef MODULE
--int init_module (void);
--void cleanup_module (void);
--#endif /* MODULE */
- 
- #else /* Not compiling the driver itself */
- 
---- linux-2.6.0-test1/drivers/char/pcxx.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/char/pcxx.c	2003-07-19 17:03:49.000000000 -0700
-@@ -209,17 +209,9 @@ static void cleanup_board_resources(void
- 
- #ifdef MODULE
- 
--/*
-- * pcxe_init() is our init_module():
-- */
--#define pcxe_init init_module
--
--void	cleanup_module(void);
--
--
- /*****************************************************************************/
- 
--void cleanup_module()
-+static void pcxe_cleanup()
- {
- 
- 	unsigned long	flags;
-@@ -240,6 +232,12 @@ void cleanup_module()
- 	kfree(digi_channels);
- 	restore_flags(flags);
- }
-+
-+/*
-+ * pcxe_init() is our init_module():
-+ */
-+module_init(pcxe_init);
-+module_cleanup(pcxe_cleanup);
- #endif
- 
- static inline struct channel *chan(register struct tty_struct *tty)
---- linux-2.6.0-test1/drivers/char/stallion.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/char/stallion.c	2003-07-19 17:03:49.000000000 -0700
-@@ -472,8 +472,6 @@ static unsigned int	stl_baudrates[] = {
-  */
- 
- #ifdef MODULE
--int		init_module(void);
--void		cleanup_module(void);
- static void	stl_argbrds(void);
- static int	stl_parsebrd(stlconf_t *confp, char **argp);
- 
---- linux-2.6.0-test1/drivers/char/sysrq.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/drivers/char/sysrq.c	2003-07-19 17:04:02.000000000 -0700
-@@ -35,6 +35,19 @@
- #include <linux/spinlock.h>
- 
- #include <asm/ptrace.h>
-+#ifdef CONFIG_KGDB_SYSRQ
-+
-+#define  GDB_OP &kgdb_op
-+static struct sysrq_key_op kgdb_op={
-+	handler:	(void*)breakpoint,
-+	help_msg:	"kGdb ",
-+	action_msg:	"Debug breakpoint\n",
-+};
-+
-+#else
-+#define  GDB_OP NULL
-+#endif
-+
- 
- extern void reset_vc(unsigned int);
- extern struct list_head super_blocks;
-@@ -240,7 +253,7 @@ static struct sysrq_key_op *sysrq_key_ta
- /* d */	NULL,
- /* e */	&sysrq_term_op,
- /* f */	NULL,
--/* g */	NULL,
-+/* g */	GDB_OP,
- /* h */	NULL,
- /* i */	&sysrq_kill_op,
- /* j */	NULL,
---- linux-2.6.0-test1/drivers/char/tty_io.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/char/tty_io.c	2003-07-19 17:06:13.000000000 -0700
-@@ -2106,7 +2106,7 @@ static spinlock_t tty_dev_list_lock = SP
- static ssize_t show_dev(struct class_device *class_dev, char *buf)
- {
- 	struct tty_dev *tty_dev = to_tty_dev(class_dev);
--	return sprintf(buf, "%04lx\n", (unsigned long)tty_dev->dev);
-+	return print_dev_t(buf, tty_dev->dev);
- }
- static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
- 
---- linux-2.6.0-test1/drivers/char/watchdog/acquirewdt.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/char/watchdog/acquirewdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -143,7 +143,7 @@ static int acq_open(struct inode *inode,
- 			return -EBUSY;
- 		}
- 		if (nowayout)
--			MOD_INC_USE_COUNT;
-+			__module_get(THIS_MODULE);
- 
- 		/* Activate */
- 		acq_is_open=1;
---- linux-2.6.0-test1/drivers/char/watchdog/i810-tco.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/char/watchdog/i810-tco.c	2003-07-19 17:03:49.000000000 -0700
-@@ -25,7 +25,8 @@
-  *	82801AA & 82801AB  chip : document number 290655-003, 290677-004,
-  *	82801BA & 82801BAM chip : document number 290687-002, 298242-005,
-  *	82801CA & 82801CAM chip : document number 290716-001, 290718-001,
-- *	82801DB & 82801E   chip : document number 290744-001, 273599-001
-+ *	82801DB & 82801E   chip : document number 290744-001, 273599-001,
-+ *	82801EB & 82801ER  chip : document number 252516-001
-  *
-  *  20000710 Nils Faerber
-  *	Initial Version 0.01
-@@ -42,9 +43,11 @@
-  *	     clean up ioctls (WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and
-  *	     WDIOC_SETOPTIONS), made i810tco_getdevice __init,
-  *	     removed boot_status, removed tco_timer_read,
-- *	     added support for 82801DB and 82801E chipset, general cleanup.
-+ *	     added support for 82801DB and 82801E chipset,
-+ *	     added support for 82801EB and 8280ER chipset,
-+ *	     general cleanup.
-  */
-- 
-+
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/miscdevice.h>
-@@ -164,7 +167,7 @@ static int tco_timer_settimer (unsigned 
-  * Reload (trigger) the timer. Lock is needed so we don't reload it during
-  * a reprogramming event
-  */
-- 
-+
- static void tco_timer_reload (void)
- {
- 	spin_lock(&tco_lock);
-@@ -307,6 +310,7 @@ static struct pci_device_id i810tco_pci_
- 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,	PCI_ANY_ID, PCI_ANY_ID, },
- 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,	PCI_ANY_ID, PCI_ANY_ID, },
- 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,	PCI_ANY_ID, PCI_ANY_ID, },
-+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,	PCI_ANY_ID, PCI_ANY_ID, },
- 	{ 0, },
- };
- MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl);
---- linux-2.6.0-test1/drivers/char/watchdog/i810-tco.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/char/watchdog/i810-tco.h	2003-07-19 17:03:49.000000000 -0700
-@@ -1,5 +1,5 @@
- /*
-- *	i810-tco 0.05:	TCO timer driver for i8xx chipsets
-+ *	i810-tco:	TCO timer driver for i8xx chipsets
-  *
-  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
-  *				http://www.kernelconcepts.de
-@@ -8,7 +8,7 @@
-  *	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.
-- *	
-+ *
-  *	Neither kernel concepts nor Nils Faerber admit liability nor provide
-  *	warranty for any of this software. This material is provided
-  *	"AS-IS" and at no charge.
---- linux-2.6.0-test1/drivers/char/watchdog/ib700wdt.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/drivers/char/watchdog/ib700wdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -230,7 +230,7 @@ ibwdt_open(struct inode *inode, struct f
- 			return -EBUSY;
- 		}
- 		if (nowayout)
--			MOD_INC_USE_COUNT;
-+			__module_get(THIS_MODULE);
- 
- 		/* Activate */
- 		ibwdt_is_open = 1;
---- linux-2.6.0-test1/drivers/char/watchdog/indydog.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/char/watchdog/indydog.c	2003-07-19 17:03:49.000000000 -0700
-@@ -54,7 +54,7 @@ static int indydog_open(struct inode *in
- 		return -EBUSY;
- 
- 	if (nowayout)
--		MOD_INC_USE_COUNT;
-+		__module_get(THIS_MODULE);
- 
- 	/*
- 	 *	Activate timer
---- linux-2.6.0-test1/drivers/char/watchdog/machzwd.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/char/watchdog/machzwd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -392,7 +392,7 @@ static int zf_open(struct inode *inode, 
- 			}
- 
- 			if (nowayout)
--				MOD_INC_USE_COUNT;
-+				__module_get(THIS_MODULE);
- 
- 			zf_is_open = 1;
- 
---- linux-2.6.0-test1/drivers/char/watchdog/pcwd.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/char/watchdog/pcwd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -431,7 +431,7 @@ static int pcwd_open(struct inode *ino, 
- 			atomic_inc( &open_allowed );
- 			return -EBUSY;
- 		}
--		MOD_INC_USE_COUNT;
-+		__module_get(THIS_MODULE);
- 		/*  Enable the port  */
- 		if (revision == PCWD_REVISION_C) {
- 			spin_lock(&io_lock);
---- linux-2.6.0-test1/drivers/char/watchdog/sbc60xxwdt.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/char/watchdog/sbc60xxwdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -207,9 +207,8 @@ static int fop_open(struct inode * inode
- 			/* Just in case we're already talking to someone... */
- 			if(wdt_is_open)
- 				return -EBUSY;
--			if (nowayout) {
--				MOD_INC_USE_COUNT;
--			}
-+			if (nowayout) 
-+				__module_get(THIS_MODULE);
- 			/* Good, fire up the show */
- 			wdt_is_open = 1;
- 			wdt_startup();
---- linux-2.6.0-test1/drivers/char/watchdog/sc520_wdt.c	2003-06-14 12:18:20.000000000 -0700
-+++ 25/drivers/char/watchdog/sc520_wdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -231,7 +231,7 @@ static int fop_open(struct inode * inode
- 			/* Good, fire up the show */
- 			wdt_startup();
- 			if (nowayout)
--				MOD_INC_USE_COUNT;
-+				__module_get(THIS_MODULE);
- 
- 			return 0;
- 		default:
---- linux-2.6.0-test1/drivers/char/watchdog/shwdt.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/drivers/char/watchdog/shwdt.c	2003-07-19 17:03:49.000000000 -0700
-@@ -3,7 +3,7 @@
-  *
-  * Watchdog driver for integrated watchdog in the SuperH processors.
-  *
-- * Copyright (C) 2001, 2002 Paul Mundt <lethal@0xd6.org>
-+ * Copyright (C) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org>
-  *
-  * This program is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU General Public License as published by the
-@@ -12,6 +12,10 @@
-  *
-  * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
-  *     Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
-+ *
-+ * 19-Apr-2002 Rob Radez <rob@osinvestor.com>
-+ *     Added expect close support, made emulated timeout runtime changeable
-+ *     general cleanups, add some ioctls
-  */
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -22,76 +26,50 @@
- #include <linux/reboot.h>
- #include <linux/notifier.h>
- #include <linux/ioport.h>
-+#include <linux/fs.h>
- 
- #include <asm/io.h>
- #include <asm/uaccess.h>
--
--#if defined(CONFIG_CPU_SH5)
--  #define WTCNT		CPRC_BASE + 0x10
--  #define WTCSR		CPRC_BASE + 0x18
--#elif defined(CONFIG_CPU_SH4)
--  #define WTCNT		0xffc00008
--  #define WTCSR		0xffc0000c
--#elif defined(CONFIG_CPU_SH3)
--  #define WTCNT		0xffffff84
--  #define WTCSR		0xffffff86
--#else
--  #error "Can't use SuperH watchdog on this platform"
--#endif
--
--#define WTCNT_HIGH	0x5a00
--#define WTCSR_HIGH	0xa500
--
--#define WTCSR_TME	0x80
--#define WTCSR_WT	0x40
--#define WTCSR_RSTS	0x20
--#define WTCSR_WOVF	0x10
--#define WTCSR_IOVF	0x08
--#define WTCSR_CKS2	0x04
--#define WTCSR_CKS1	0x02
--#define WTCSR_CKS0	0x01
--
--/*
-- * CKS0-2 supports a number of clock division ratios. At the time the watchdog
-- * is enabled, it defaults to a 41 usec overflow period .. we overload this to
-- * something a little more reasonable, and really can't deal with anything
-- * lower than WTCSR_CKS_1024, else we drop back into the usec range.
-- *
-- * Clock Division Ratio         Overflow Period
-- * --------------------------------------------
-- *     1/32 (initial value)       41 usecs
-- *     1/64                       82 usecs
-- *     1/128                     164 usecs
-- *     1/256                     328 usecs
-- *     1/512                     656 usecs
-- *     1/1024                   1.31 msecs
-- *     1/2048                   2.62 msecs
-- *     1/4096                   5.25 msecs
-- */
--#define WTCSR_CKS_32	0x00
--#define WTCSR_CKS_64	0x01
--#define WTCSR_CKS_128	0x02
--#define WTCSR_CKS_256	0x03
--#define WTCSR_CKS_512	0x04
--#define WTCSR_CKS_1024	0x05
--#define WTCSR_CKS_2048	0x06
--#define WTCSR_CKS_4096	0x07
-+#include <asm/watchdog.h>
- 
- /*
-- * Default clock division ratio is 5.25 msecs. Overload this at module load
-- * time. Any value not in the msec range will default to a timeout of one
-- * jiffy, which exceeds the usec overflow periods.
-+ * Default clock division ratio is 5.25 msecs. For an additional table of
-+ * values, consult the asm-sh/watchdog.h. Overload this at module load
-+ * time. 
-+ *
-+ * In order for this to work reliably we need to have HZ set to 1000 or
-+ * something quite higher than 100 (or we need a proper high-res timer
-+ * implementation that will deal with this properly), otherwise the 10ms
-+ * resolution of a jiffy is enough to trigger the overflow. For things like
-+ * the SH-4 and SH-5, this isn't necessarily that big of a problem, though
-+ * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely
-+ * necssary.
-+ *
-+ * As a result of this timing problem, the only modes that are particularly
-+ * feasible are the 4096 and the 2048 divisors, which yeild 5.25 and 2.62ms
-+ * overflow periods respectively.
-+ *
-+ * Also, since we can't really expect userspace to be responsive enough
-+ * before the overflow happens, we maintain two seperate timers .. One in
-+ * the kernel for clearing out WOVF every 2ms or so (again, this depends on
-+ * HZ == 1000), and another for monitoring userspace writes to the WDT device.
-+ *
-+ * As such, we currently use a configurable heartbeat interval which defaults
-+ * to 30s. In this case, the userspace daemon is only responsible for periodic
-+ * writes to the device before the next heartbeat is scheduled. If the daemon
-+ * misses its deadline, the kernel timer will allow the WDT to overflow.
-  */
- static int clock_division_ratio = WTCSR_CKS_4096;
- 
--#define msecs_to_jiffies(msecs)	(jiffies + ((HZ * msecs + 999) / 1000))
-+#define msecs_to_jiffies(msecs)	(jiffies + (HZ * msecs + 9999) / 10000)
- #define next_ping_period(cks)	msecs_to_jiffies(cks - 4)
--#define user_ping_period(cks)	(next_ping_period(cks) * 10)
- 
--static unsigned long sh_is_open = 0;
-+static unsigned long shwdt_is_open;
- static struct watchdog_info sh_wdt_info;
-+static char shwdt_expect_close;
- static struct timer_list timer;
- static unsigned long next_heartbeat;
-+static int heartbeat = 30;
- 
- #ifdef CONFIG_WATCHDOG_NOWAYOUT
- static int nowayout = 1;
-@@ -99,35 +77,6 @@ static int nowayout = 1;
- static int nowayout = 0;
- #endif
- 
--MODULE_PARM(nowayout,"i");
--MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
--
--/**
-- *	sh_wdt_write_cnt - Write to Counter
-- *
-- *	@val: Value to write
-- *
-- *	Writes the given value @val to the lower byte of the timer counter.
-- *	The upper byte is set manually on each write.
-- */
--static void sh_wdt_write_cnt(__u8 val)
--{
--	ctrl_outw(WTCNT_HIGH | (__u16)val, WTCNT);
--}
--
--/**
-- * 	sh_wdt_write_csr - Write to Control/Status Register
-- *
-- * 	@val: Value to write
-- *
-- * 	Writes the given value @val to the lower byte of the control/status
-- * 	register. The upper byte is set manually on each write.
-- */
--static void sh_wdt_write_csr(__u8 val)
--{
--	ctrl_outw(WTCSR_HIGH | (__u16)val, WTCSR);
--}
--
- /**
-  * 	sh_wdt_start - Start the Watchdog
-  *
-@@ -135,13 +84,44 @@ static void sh_wdt_write_csr(__u8 val)
-  */
- static void sh_wdt_start(void)
- {
--	timer.expires = next_ping_period(clock_division_ratio);
--	next_heartbeat = user_ping_period(clock_division_ratio);
--	add_timer(&timer);
-+	__u8 csr;
-+
-+	mod_timer(&timer, next_ping_period(clock_division_ratio));
-+	next_heartbeat = jiffies + (heartbeat * HZ);
-+
-+	csr = sh_wdt_read_csr();
-+	csr |= WTCSR_WT | clock_division_ratio;
-+	sh_wdt_write_csr(csr);
- 
--	sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096);
- 	sh_wdt_write_cnt(0);
--	sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME));
-+
-+	/*
-+	 * These processors have a bit of an inconsistent initialization
-+	 * process.. starting with SH-3, RSTS was moved to WTCSR, and the
-+	 * RSTCSR register was removed.
-+	 *
-+	 * On the SH-2 however, in addition with bits being in different
-+	 * locations, we must deal with RSTCSR outright..
-+	 */
-+	csr = sh_wdt_read_csr();
-+	csr |= WTCSR_TME;
-+	csr &= ~WTCSR_RSTS;
-+	sh_wdt_write_csr(csr);
-+
-+#ifdef CONFIG_CPU_SH2
-+	/*
-+	 * Whoever came up with the RSTCSR semantics must've been smoking
-+	 * some of the good stuff, since in addition to the WTCSR/WTCNT write
-+	 * brain-damage, it's managed to fuck things up one step further..
-+	 *
-+	 * If we need to clear the WOVF bit, the upper byte has to be 0xa5..
-+	 * but if we want to touch RSTE or RSTS, the upper byte has to be
-+	 * 0x5a..
-+	 */
-+	csr = sh_wdt_read_rstcsr();
-+	csr &= ~RSTCSR_RSTS;
-+	sh_wdt_write_rstcsr(csr);
-+#endif	
- }
- 
- /**
-@@ -151,9 +131,13 @@ static void sh_wdt_start(void)
-  */
- static void sh_wdt_stop(void)
- {
-+	__u8 csr;
-+
- 	del_timer(&timer);
- 
--	sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME));
-+	csr = sh_wdt_read_csr();
-+	csr &= ~WTCSR_TME;
-+	sh_wdt_write_csr(csr);
- }
- 
- /**
-@@ -166,11 +150,15 @@ static void sh_wdt_stop(void)
- static void sh_wdt_ping(unsigned long data)
- {
- 	if (time_before(jiffies, next_heartbeat)) {
--		sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
-+		__u8 csr;
-+
-+		csr = sh_wdt_read_csr();
-+		csr &= ~WTCSR_IOVF;
-+		sh_wdt_write_csr(csr);
-+
- 		sh_wdt_write_cnt(0);
- 
--		timer.expires = next_ping_period(clock_division_ratio);
--		add_timer(&timer);
-+		mod_timer(&timer, next_ping_period(clock_division_ratio));
- 	}
- }
- 
-@@ -184,21 +172,12 @@ static void sh_wdt_ping(unsigned long da
-  */
- static int sh_wdt_open(struct inode *inode, struct file *file)
- {
--	switch (minor(inode->i_rdev)) {
--		case WATCHDOG_MINOR:
--			if (test_and_set_bit(0, &sh_is_open))
--				return -EBUSY;
-+	if (test_and_set_bit(0, &shwdt_is_open))
-+		return -EBUSY;
-+	if (nowayout)
-+		__module_get(THIS_MODULE);
- 
--			if (nowayout) {
--				MOD_INC_USE_COUNT;
--			}
--
--			sh_wdt_start();
--
--			break;
--		default:
--			return -ENODEV;
--	}
-+	sh_wdt_start();
- 
- 	return 0;
- }
-@@ -213,33 +192,20 @@ static int sh_wdt_open(struct inode *ino
-  */
- static int sh_wdt_close(struct inode *inode, struct file *file)
- {
--	if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
--		if (!nowayout) {
--			sh_wdt_stop();
--		}
--		clear_bit(0, &sh_is_open);
-+	if (!nowayout && shwdt_expect_close == 42) {
-+		sh_wdt_stop();
-+	} else {
-+		printk(KERN_CRIT "shwdt: Unexpected close, not stopping watchdog!\n");
-+		next_heartbeat = jiffies + (heartbeat * HZ);
- 	}
-+
-+	clear_bit(0, &shwdt_is_open);
-+	shwdt_expect_close = 0;
- 	
- 	return 0;
- }
- 
- /**
-- * 	sh_wdt_read - Read from Device
-- *
-- * 	@file: file handle of device
-- * 	@buf: buffer to write to
-- * 	@count: length of buffer
-- * 	@ppos: offset
-- *
-- * 	Unsupported.
-- */
--static ssize_t sh_wdt_read(struct file *file, char *buf,
--			   size_t count, loff_t *ppos)
--{
--	return -EINVAL;
--}
--
--/**
-  * 	sh_wdt_write - Write to Device
-  *
-  * 	@file: file handle of device
-@@ -257,11 +223,21 @@ static ssize_t sh_wdt_write(struct file 
- 		return -ESPIPE;
- 
- 	if (count) {
--		next_heartbeat = user_ping_period(clock_division_ratio);
--		return 1;
-+		size_t i;
-+
-+		shwdt_expect_close = 0;
-+
-+		for (i = 0; i != count; i++) {
-+			char c;
-+			if (get_user(c, buf + i))
-+				return -EFAULT;
-+			if (c == 'V')
-+				shwdt_expect_close = 42;
-+		}
-+		next_heartbeat = jiffies + (heartbeat * HZ);
- 	}
- 
--	return 0;
-+	return count;
- }
- 
- /**
-@@ -278,6 +254,8 @@ static ssize_t sh_wdt_write(struct file 
- static int sh_wdt_ioctl(struct inode *inode, struct file *file,
- 			unsigned int cmd, unsigned long arg)
- {
-+	int new_timeout;
-+
- 	switch (cmd) {
- 		case WDIOC_GETSUPPORT:
- 			if (copy_to_user((struct watchdog_info *)arg,
-@@ -288,17 +266,41 @@ static int sh_wdt_ioctl(struct inode *in
- 			
- 			break;
- 		case WDIOC_GETSTATUS:
--			if (copy_to_user((int *)arg,
--					 &sh_is_open,
--					 sizeof(int))) {
-+		case WDIOC_GETBOOTSTATUS:
-+			return put_user(0, (int *)arg);
-+		case WDIOC_KEEPALIVE:
-+			next_heartbeat = jiffies + (heartbeat * HZ);
-+
-+			break;
-+		case WDIOC_SETTIMEOUT:
-+			if (get_user(new_timeout, (int *)arg))
- 				return -EFAULT;
-+			if (new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
-+				return -EINVAL;
-+			heartbeat = new_timeout;
-+			next_heartbeat = jiffies + (heartbeat * HZ);
-+			/* Fall */
-+		case WDIOC_GETTIMEOUT:
-+			return put_user(heartbeat, (int *)arg);
-+		case WDIOC_SETOPTIONS:
-+		{
-+			int options, retval = -EINVAL;
-+
-+			if (get_user(options, (int *)arg))
-+				return -EFAULT;
-+
-+			if (options & WDIOS_DISABLECARD) {
-+				sh_wdt_stop();
-+				retval = 0;
- 			}
- 
--			break;
--		case WDIOC_KEEPALIVE:
--			next_heartbeat = user_ping_period(clock_division_ratio);
-+			if (options & WDIOS_ENABLECARD) {
-+				sh_wdt_start();
-+				retval = 0;
-+			}
- 			
--			break;
-+			return retval;
-+		}
- 		default:
- 			return -ENOTTY;
- 	}
-@@ -328,7 +330,7 @@ static int sh_wdt_notify_sys(struct noti
- 
- static struct file_operations sh_wdt_fops = {
- 	.owner		= THIS_MODULE,
--	.read		= sh_wdt_read,
-+	.llseek		= no_llseek,
- 	.write		= sh_wdt_write,
- 	.ioctl		= sh_wdt_ioctl,
- 	.open		= sh_wdt_open,
-@@ -336,21 +338,20 @@ static struct file_operations sh_wdt_fop
- };
- 
- static struct watchdog_info sh_wdt_info = {
--	.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
--	.firmware_version = 1,
--	.identity = "SH WDT",
-+	.options		= WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
-+	.firmware_version	= 1,
-+	.identity		= "SH WDT",
- };
- 
- static struct notifier_block sh_wdt_notifier = {
--	.notifier_call = sh_wdt_notify_sys,
--	.next = NULL,
--	.priority = 0
-+	.notifier_call		= sh_wdt_notify_sys,
-+	.priority		= 0,
- };
- 
- static struct miscdevice sh_wdt_miscdev = {
--	.minor = WATCHDOG_MINOR,
--	.name = "watchdog",
--	.fops &sh_wdt_fops,
-+	.minor		= WATCHDOG_MINOR,
-+	.name		= "watchdog",
-+	.fops		= &sh_wdt_fops,
- };
- 
- /**
-@@ -366,23 +367,8 @@ static int __init sh_wdt_init(void)
- 		return -EINVAL;
- 	}
- 
--	if (!request_region(WTCNT, 1, "shwdt")) {
--		printk(KERN_ERR "shwdt: Can't request WTCNT region\n");
--		misc_deregister(&sh_wdt_miscdev);
--		return -ENXIO;
--	}
--
--	if (!request_region(WTCSR, 1, "shwdt")) {
--		printk(KERN_ERR "shwdt: Can't request WTCSR region\n");
--		release_region(WTCNT, 1);
--		misc_deregister(&sh_wdt_miscdev);
--		return -ENXIO;
--	}
--
- 	if (register_reboot_notifier(&sh_wdt_notifier)) {
- 		printk(KERN_ERR "shwdt: Can't register reboot notifier\n");
--		release_region(WTCSR, 1);
--		release_region(WTCNT, 1);
- 		misc_deregister(&sh_wdt_miscdev);
- 		return -EINVAL;
- 	}
-@@ -403,16 +389,16 @@ static int __init sh_wdt_init(void)
- static void __exit sh_wdt_exit(void)
- {
- 	unregister_reboot_notifier(&sh_wdt_notifier);
--	release_region(WTCSR, 1);
--	release_region(WTCNT, 1);
- 	misc_deregister(&sh_wdt_miscdev);
- }
- 
--MODULE_AUTHOR("Paul Mundt <lethal@0xd6.org>");
-+MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
- MODULE_DESCRIPTION("SuperH watchdog driver");
- MODULE_LICENSE("GPL");
- MODULE_PARM(clock_division_ratio, "i");
- MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). Defaults to 0x7.");
-+MODULE_PARM(nowayout,"i");
-+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
- 
- module_init(sh_wdt_init);
- module_exit(sh_wdt_exit);
---- linux-2.6.0-test1/drivers/char/watchdog/softdog.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/char/watchdog/softdog.c	2003-07-19 17:03:49.000000000 -0700
-@@ -104,9 +104,8 @@ static int softdog_open(struct inode *in
- {
- 	if(test_and_set_bit(0, &timer_alive))
- 		return -EBUSY;
--	if (nowayout) {
--		MOD_INC_USE_COUNT;
--	}
-+	if (nowayout) 
-+		__module_get(THIS_MODULE);
- 	/*
- 	 *	Activate timer
- 	 */
---- linux-2.6.0-test1/drivers/char/watchdog/wdt977.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/char/watchdog/wdt977.c	2003-07-19 17:03:49.000000000 -0700
-@@ -16,6 +16,8 @@
-  *	19-Dec-2001 Woody Suwalski: Netwinder fixes, ioctl interface
-  *	06-Jan-2002 Woody Suwalski: For compatibility, convert all timeouts
-  *				    from minutes to seconds.
-+ *      07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
-+ *                                    nwwatchdog_init.
-  */
- 
- #include <linux/module.h>
-@@ -99,7 +101,7 @@ static int wdt977_open(struct inode *ino
- 
- 	if (nowayout)
- 	{
--		MOD_INC_USE_COUNT;
-+		__module_get(THIS_MODULE);
- 
- 		/* do not permit disabling the watchdog by writing 0 to reg. 0xF2 */
- 		if (!timeoutM) timeoutM = DEFAULT_TIMEOUT;
-@@ -343,12 +345,14 @@ static struct miscdevice wdt977_miscdev=
- 
- static int __init nwwatchdog_init(void)
- {
-+	int retval;
- 	if (!machine_is_netwinder())
- 		return -ENODEV;
- 
--	misc_register(&wdt977_miscdev);
--	printk(KERN_INFO "Wdt977 Watchdog sleeping.\n");
--	return 0;
-+	retval = misc_register(&wdt977_miscdev);
-+	if (!retval)
-+		printk(KERN_INFO "Wdt977 Watchdog sleeping.\n");
-+	return retval;
- }
- 
- static void __exit nwwatchdog_exit(void)
---- linux-2.6.0-test1/drivers/char/watchdog/wdt_pci.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/char/watchdog/wdt_pci.c	2003-07-19 17:03:49.000000000 -0700
-@@ -367,7 +367,7 @@ static int wdtpci_open(struct inode *ino
- 				return -EBUSY;
- 
- 			if (nowayout) {
--				MOD_INC_USE_COUNT;
-+				__module_get(THIS_MODULE);
- 			}
- 			/*
- 			 *	Activate 
---- linux-2.6.0-test1/drivers/fc4/fc.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/fc4/fc.c	2003-07-19 17:03:49.000000000 -0700
-@@ -33,7 +33,6 @@
- #include <linux/slab.h>
- #include <linux/string.h>
- #include <linux/init.h>
--#include <linux/blk.h>
- 
- #include <asm/pgtable.h>
- #include <asm/irq.h>
---- linux-2.6.0-test1/drivers/fc4/fcp_impl.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/fc4/fcp_impl.h	2003-07-19 17:03:49.000000000 -0700
-@@ -8,7 +8,6 @@
- #define _FCP_SCSI_H
- 
- #include <linux/types.h>
--#include <linux/blk.h>
- #include "../scsi/scsi.h"
- 
- #include "fc.h"
---- linux-2.6.0-test1/drivers/i2c/i2c-dev.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/i2c/i2c-dev.c	2003-07-19 17:06:13.000000000 -0700
-@@ -118,7 +118,7 @@ static void return_i2c_dev(struct i2c_de
- static ssize_t show_dev(struct class_device *class_dev, char *buf)
- {
- 	struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
--	return sprintf(buf, "%04x\n", MKDEV(I2C_MAJOR, i2c_dev->minor));
-+	return print_dev_t(buf, MKDEV(I2C_MAJOR, i2c_dev->minor));
- }
- static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
- 
---- linux-2.6.0-test1/drivers/ide/ide-disk.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/drivers/ide/ide-disk.c	2003-07-19 17:07:19.000000000 -0700
-@@ -1665,6 +1665,10 @@ static void idedisk_setup (ide_drive_t *
- 	drive->no_io_32bit = id->dword_io ? 1 : 0;
- 	if (drive->id->cfs_enable_2 & 0x3000)
- 		write_cache(drive, (id->cfs_enable_2 & 0x3000));
-+
-+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-+	HWIF(drive)->ide_dma_queued_on(drive);
-+#endif
- }
- 
- static int idedisk_cleanup (ide_drive_t *drive)
---- linux-2.6.0-test1/drivers/ide/ide-dma.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/ide/ide-dma.c	2003-07-19 17:07:19.000000000 -0700
-@@ -442,9 +442,10 @@ static int config_drive_for_dma (ide_dri
-  *	the driver to resolve the problem, if a DMA transfer is still
-  *	in progress we continue to wait (arguably we need to add a 
-  *	secondary 'I don't care what the drive thinks' timeout here)
-- *	Finally if we have an interrupt but for some reason got the
-- *	timeout first we complete the I/O. This can occur if an 
-- *	interrupt is lost or due to bugs.
-+ *	Finally if we have an interrupt we let it complete the I/O.
-+ *	But only one time - we clear expiry and if it's still not
-+ *	completed after WAIT_CMD, we error and retry in PIO.
-+ *	This can occur if an interrupt is lost or due to hang or bugs.
-  */
-  
- static int dma_timer_expiry (ide_drive_t *drive)
-@@ -461,19 +462,16 @@ static int dma_timer_expiry (ide_drive_t
- 	HWGROUP(drive)->expiry = NULL;	/* one free ride for now */
- 
- 	/* 1 dmaing, 2 error, 4 intr */
--	
--	if (dma_stat & 2) {	/* ERROR */
--		(void) hwif->ide_dma_end(drive);
--		return DRIVER(drive)->error(drive,
--			"dma_timer_expiry", hwif->INB(IDE_STATUS_REG));
--	}
-+	if (dma_stat & 2)	/* ERROR */
-+		return -1;
-+
- 	if (dma_stat & 1)	/* DMAing */
- 		return WAIT_CMD;
- 
- 	if (dma_stat & 4)	/* Got an Interrupt */
--		HWGROUP(drive)->handler(drive);
-+		return WAIT_CMD;
- 
--	return 0;
-+	return 0;	/* Status is unknown -- reset the bus */
- }
- 
- /**
-@@ -572,10 +570,6 @@ int __ide_dma_on (ide_drive_t *drive)
- 	if (HWIF(drive)->ide_dma_host_on(drive))
- 		return 1;
- 
--#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
--	HWIF(drive)->ide_dma_queued_on(drive);
--#endif
--
- 	return 0;
- }
- 
---- linux-2.6.0-test1/drivers/ide/ide-io.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/ide/ide-io.c	2003-07-19 17:03:49.000000000 -0700
-@@ -949,14 +949,14 @@ queue_next:
- 		 * happens anyway when any interrupt comes in, IDE or otherwise
- 		 *  -- the kernel masks the IRQ while it is being handled.
- 		 */
--		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
-+		if (hwif->irq != masked_irq)
- 			disable_irq_nosync(hwif->irq);
- 		spin_unlock(&ide_lock);
- 		local_irq_enable();
- 			/* allow other IRQs while we start this request */
- 		startstop = start_request(drive, rq);
- 		spin_lock_irq(&ide_lock);
--		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
-+		if (hwif->irq != masked_irq)
- 			enable_irq(hwif->irq);
- 		if (startstop == ide_released)
- 			goto queue_next;
-@@ -980,21 +980,25 @@ void do_ide_request(request_queue_t *q)
-  * retry the current request in pio mode instead of risking tossing it
-  * all away
-  */
--void ide_dma_timeout_retry(ide_drive_t *drive)
-+static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
- {
- 	ide_hwif_t *hwif = HWIF(drive);
- 	struct request *rq;
-+	ide_startstop_t ret = ide_stopped;
- 
- 	/*
- 	 * end current dma transaction
- 	 */
--	(void) hwif->ide_dma_end(drive);
- 
--	/*
--	 * complain a little, later we might remove some of this verbosity
--	 */
--	printk(KERN_WARNING "%s: timeout waiting for DMA\n", drive->name);
--	(void) hwif->ide_dma_timeout(drive);
-+	if (error < 0) {
-+		printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
-+		(void)HWIF(drive)->ide_dma_end(drive);
-+		ret = DRIVER(drive)->error(drive, "dma timeout error",
-+						hwif->INB(IDE_STATUS_REG));
-+	} else {
-+		printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
-+		(void) hwif->ide_dma_timeout(drive);
-+	}
- 
- 	/*
- 	 * disable dma for now, but remember that we did so because of
-@@ -1018,9 +1022,9 @@ void ide_dma_timeout_retry(ide_drive_t *
- 	rq->hard_cur_sectors = rq->current_nr_sectors;
- 	if (rq->bio)
- 		rq->buffer = NULL;
--}
- 
--EXPORT_SYMBOL(ide_dma_timeout_retry);
-+	return ret;
-+}
- 
- /**
-  *	ide_timer_expiry	-	handle lack of an IDE interrupt
-@@ -1041,11 +1045,10 @@ void ide_timer_expiry (unsigned long dat
- 	ide_hwgroup_t	*hwgroup = (ide_hwgroup_t *) data;
- 	ide_handler_t	*handler;
- 	ide_expiry_t	*expiry;
-- 	unsigned long	flags;
--	unsigned long	wait;
-+	unsigned long	flags;
-+	unsigned long	wait = -1;
- 
- 	spin_lock_irqsave(&ide_lock, flags);
--	del_timer(&hwgroup->timer);
- 
- 	if ((handler = hwgroup->handler) == NULL) {
- 		/*
-@@ -1072,7 +1075,7 @@ void ide_timer_expiry (unsigned long dat
- 			}
- 			if ((expiry = hwgroup->expiry) != NULL) {
- 				/* continue */
--				if ((wait = expiry(drive)) != 0) {
-+				if ((wait = expiry(drive)) > 0) {
- 					/* reset timer */
- 					hwgroup->timer.expires  = jiffies + wait;
- 					add_timer(&hwgroup->timer);
-@@ -1107,15 +1110,15 @@ void ide_timer_expiry (unsigned long dat
- 				startstop = handler(drive);
- 			} else {
- 				if (drive->waiting_for_dma) {
--					startstop = ide_stopped;
--					ide_dma_timeout_retry(drive);
-+					startstop = ide_dma_timeout_retry(drive, wait);
- 				} else
--					startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
-+					startstop =
-+					DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
- 			}
- 			set_recovery_timer(hwif);
- 			drive->service_time = jiffies - drive->service_start;
--			enable_irq(hwif->irq);
- 			spin_lock_irq(&ide_lock);
-+			enable_irq(hwif->irq);
- 			if (startstop == ide_stopped)
- 				hwgroup->busy = 0;
- 		}
---- linux-2.6.0-test1/drivers/ide/Kconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/ide/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -521,7 +521,7 @@ config BLK_DEV_ALI15X3
- 
- 	  If you say Y here, you also need to say Y to "Use DMA by default
- 	  when available", above.  Please read the comments at the top of
--	  <file:drivers/ide/alim15x3.c>.
-+	  <file:drivers/ide/pci/alim15x3.c>.
- 
- 	  If unsure, say N.
- 
-@@ -608,7 +608,7 @@ config HPT34X_AUTODMA
- 	depends on BLK_DEV_HPT34X && IDEDMA_PCI_WIP
- 	help
- 	  This is a dangerous thing to attempt currently! Please read the
--	  comments at the top of <file:drivers/ide/hpt34x.c>.  If you say Y
-+	  comments at the top of <file:drivers/ide/pci/hpt34x.c>.  If you say Y
- 	  here, then say Y to "Use DMA by default when available" as well.
- 
- 	  If unsure, say N.
-@@ -670,14 +670,14 @@ config BLK_DEV_NS87415
- 	  This driver adds detection and support for the NS87415 chip
- 	  (used in SPARC64, among others).
- 
--	  Please read the comments at the top of <file:drivers/ide/ns87415.c>.
-+	  Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
- 
- config BLK_DEV_OPTI621
- 	tristate "OPTi 82C621 chipset enhanced support (EXPERIMENTAL)"
- 	depends on PCI && BLK_DEV_IDEPCI && EXPERIMENTAL
- 	help
- 	  This is a driver for the OPTi 82C621 EIDE controller.
--	  Please read the comments at the top of <file:drivers/ide/opti621.c>.
-+	  Please read the comments at the top of <file:drivers/ide/pci/opti621.c>.
- 
- config BLK_DEV_PDC202XX_OLD
- 	tristate "PROMISE PDC202{46|62|65|67} support"
-@@ -696,7 +696,7 @@ config PDC202XX_BURST
- 	  when the PDC20265 BIOS has been disabled (for faster boot up).
- 
- 	  Please read the comments at the top of
--	  <file:drivers/ide/pdc202xx.c>.
-+	  <file:drivers/ide/pci/pdc202xx_old.c>.
- 
- 	  If unsure, say N.
- 
-@@ -754,7 +754,7 @@ config BLK_DEV_SIS5513
- 	  If you say Y here, you need to say Y to "Use DMA by default when
- 	  available" as well.
- 
--	  Please read the comments at the top of <file:drivers/ide/sis5513.c>.
-+	  Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
- 
- config BLK_DEV_SLC90E66
- 	tristate "SLC90E66 chipset support"
-@@ -770,7 +770,7 @@ config BLK_DEV_SLC90E66
- 	  available" as well.
- 
- 	  Please read the comments at the top of
--	  drivers/ide/slc90e66.c.
-+	  drivers/ide/pci/slc90e66.c.
- 
- config BLK_DEV_TRM290
- 	tristate "Tekram TRM290 chipset support"
-@@ -779,7 +779,7 @@ config BLK_DEV_TRM290
- 	  This driver adds support for bus master DMA transfers
- 	  using the Tekram TRM290 PCI IDE chip. Volunteers are
- 	  needed for further tweaking and development.
--	  Please read the comments at the top of <file:drivers/ide/trm290.c>.
-+	  Please read the comments at the top of <file:drivers/ide/pci/trm290.c>.
- 
- config BLK_DEV_VIA82CXXX
- 	tristate "VIA82CXXX chipset support"
-@@ -1010,7 +1010,7 @@ config BLK_DEV_ALI14XX
- 	  boot parameter.  It enables support for the secondary IDE interface
- 	  of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
- 	  I/O speeds to be set as well.  See the files
--	  <file:Documentation/ide.txt> and <file:drivers/ide/ali14xx.c> for
-+	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/ali14xx.c> for
- 	  more info.
- 
- config BLK_DEV_DTC2278
-@@ -1021,7 +1021,7 @@ config BLK_DEV_DTC2278
- 	  boot parameter. It enables support for the secondary IDE interface
- 	  of the DTC-2278 card, and permits faster I/O speeds to be set as
- 	  well. See the <file:Documentation/ide.txt> and
--	  <file:drivers/ide/dtc2278.c> files for more info.
-+	  <file:drivers/ide/legacy/dtc2278.c> files for more info.
- 
- config BLK_DEV_HT6560B
- 	tristate "Holtek HT6560B support"
-@@ -1031,7 +1031,7 @@ config BLK_DEV_HT6560B
- 	  boot parameter. It enables support for the secondary IDE interface
- 	  of the Holtek card, and permits faster I/O speeds to be set as well.
- 	  See the <file:Documentation/ide.txt> and
--	  <file:drivers/ide/ht6560b.c> files for more info.
-+	  <file:drivers/ide/legacy/ht6560b.c> files for more info.
- 
- config BLK_DEV_PDC4030
- 	tristate "PROMISE DC4030 support (EXPERIMENTAL)"
-@@ -1044,7 +1044,7 @@ config BLK_DEV_PDC4030
- 	  supported (and probably never will be since I don't think the cards
- 	  support them). This driver is enabled at runtime using the "ide0=dc4030"
- 	  or "ide1=dc4030" kernel boot parameter. See the
--	  <file:drivers/ide/pdc4030.c> file for more info.
-+	  <file:drivers/ide/legacy/pdc4030.c> file for more info.
- 
- config BLK_DEV_QD65XX
- 	tristate "QDI QD65xx support"
-@@ -1052,7 +1052,7 @@ config BLK_DEV_QD65XX
- 	help
- 	  This driver is enabled at runtime using the "ide0=qd65xx" kernel
- 	  boot parameter.  It permits faster I/O speeds to be set.  See the
--	  <file:Documentation/ide.txt> and <file:drivers/ide/qd65xx.c> for
-+	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/qd65xx.c> for
- 	  more info.
- 
- config BLK_DEV_UMC8672
-@@ -1063,7 +1063,7 @@ config BLK_DEV_UMC8672
- 	  boot parameter. It enables support for the secondary IDE interface
- 	  of the UMC-8672, and permits faster I/O speeds to be set as well.
- 	  See the files <file:Documentation/ide.txt> and
--	  <file:drivers/ide/umc8672.c> for more info.
-+	  <file:drivers/ide/legacy/umc8672.c> for more info.
- 
- config BLK_DEV_HD_ONLY
- 	bool "Old hard disk (MFM/RLL/IDE) driver"
-@@ -1132,7 +1132,7 @@ config BLK_DEV_PDC202XX
- 	  available" as well.
- 
- 	  Please read the comments at the top of
--	  <file:drivers/ide/pdc202xx.c>.
-+	  <file:drivers/ide/pdc202xx_old.c>.
- 
- 	  If unsure, say N.
- 
---- linux-2.6.0-test1/drivers/ide/legacy/hd98.c	2003-06-14 12:18:28.000000000 -0700
-+++ 25/drivers/ide/legacy/hd98.c	2003-07-19 17:03:49.000000000 -0700
-@@ -46,8 +46,6 @@
- #include <asm/io.h>
- #include <asm/uaccess.h>
- 
--#include <linux/blk.h>
--
- #include "io_ports.h"
- 
- #ifdef __arm__
---- linux-2.6.0-test1/drivers/ide/legacy/hd.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/ide/legacy/hd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -26,7 +26,7 @@
- /* Uncomment the following if you want verbose error reports. */
- /* #define VERBOSE_ERRORS */
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/errno.h>
- #include <linux/signal.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/ide/ppc/mpc8xx.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/ide/ppc/mpc8xx.c	2003-07-19 17:03:49.000000000 -0700
-@@ -27,7 +27,6 @@
- #include <linux/interrupt.h>
- #include <linux/reboot.h>
- #include <linux/init.h>
--#include <linux/blk.h>
- #include <linux/ioport.h>
- #include <linux/ide.h>
- #include <linux/bootmem.h>
---- linux-2.6.0-test1/drivers/ieee1394/amdtp.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/ieee1394/amdtp.c	2003-07-19 17:03:49.000000000 -0700
-@@ -62,6 +62,12 @@
-  * - Maybe make an ALSA interface, that is, create a file_ops
-  *   implementation that recognizes ALSA ioctls and uses defaults for
-  *   things that can't be controlled through ALSA (iso channel).
-+ *
-+ *   Changes:
-+ *
-+ * - Audit copy_from_user in amdtp_write.
-+ *                           Daniele Bellucci <bellucda@tiscali.it>
-+ *
-  */
- 
- #include <linux/module.h>
-@@ -1112,7 +1118,8 @@ static ssize_t amdtp_write(struct file *
- 
- 	for (i = 0; i < count; i += length) {
- 		p = buffer_put_bytes(s->input, count - i, &length);
--		copy_from_user(p, buffer + i, length);
-+		if (copy_from_user(p, buffer + i, length))
-+			return -EFAULT;
- 		if (s->input->length < s->input->size)
- 			continue;
- 		
---- linux-2.6.0-test1/drivers/ieee1394/sbp2.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/ieee1394/sbp2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -52,7 +52,7 @@
- #include <linux/delay.h>
- #include <linux/sched.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/smp_lock.h>
- #include <linux/init.h>
- #include <linux/version.h>
---- linux-2.6.0-test1/drivers/input/keyboard/sunkbd.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/drivers/input/keyboard/sunkbd.c	2003-07-19 17:03:49.000000000 -0700
-@@ -80,8 +80,8 @@ struct sunkbd {
- 	char name[64];
- 	char phys[32];
- 	char type;
--	char reset;
--	char layout;
-+	volatile char reset;
-+	volatile char layout;
- };
- 
- /*
---- linux-2.6.0-test1/drivers/input/mouse/psmouse-base.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/input/mouse/psmouse-base.c	2003-07-19 17:07:16.000000000 -0700
-@@ -200,7 +200,7 @@ int psmouse_command(struct psmouse *psmo
- 	psmouse->cmdcnt = receive;
- 
- 	if (command == PSMOUSE_CMD_RESET_BAT)
--                timeout = 2000000; /* 2 sec */
-+                timeout = 4000000; /* 4 sec */
- 
- 	if (command & 0xff)
- 		if (psmouse_sendbyte(psmouse, command & 0xff))
---- linux-2.6.0-test1/drivers/md/dm.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/md/dm.c	2003-07-19 17:03:49.000000000 -0700
-@@ -8,7 +8,6 @@
- 
- #include <linux/init.h>
- #include <linux/module.h>
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- #include <linux/bio.h>
- #include <linux/mempool.h>
-@@ -63,6 +62,12 @@ struct mapped_device {
- 	 * io objects are allocated from here.
- 	 */
- 	mempool_t *io_pool;
-+
-+	/*
-+	 * Event handling.
-+	 */
-+	uint32_t event_nr;
-+	wait_queue_head_t eventq;
- };
- 
- #define MIN_IOS 256
-@@ -510,6 +515,11 @@ static int dm_request(request_queue_t *q
- 		down_read(&md->lock);
- 	}
- 
-+	if (!md->map) {
-+		bio_io_error(bio, bio->bi_size);
-+		return 0;
-+	}
-+
- 	__split_bio(md, bio);
- 	up_read(&md->lock);
- 	return 0;
-@@ -619,6 +629,8 @@ static struct mapped_device *alloc_dev(u
- 
- 	atomic_set(&md->pending, 0);
- 	init_waitqueue_head(&md->wait);
-+	init_waitqueue_head(&md->eventq);
-+
- 	return md;
- }
- 
-@@ -634,6 +646,16 @@ static void free_dev(struct mapped_devic
- /*
-  * Bind a table to the device.
-  */
-+static void event_callback(void *context)
-+{
-+	struct mapped_device *md = (struct mapped_device *) context;
-+
-+	down_write(&md->lock);
-+	md->event_nr++;
-+	wake_up_interruptible(&md->eventq);
-+	up_write(&md->lock);
-+}
-+
- static int __bind(struct mapped_device *md, struct dm_table *t)
- {
- 	request_queue_t *q = &md->queue;
-@@ -645,6 +667,8 @@ static int __bind(struct mapped_device *
- 	if (size == 0)
- 		return 0;
- 
-+	dm_table_event_callback(md->map, event_callback, md);
-+
- 	dm_table_get(t);
- 	dm_table_set_restrictions(t, q);
- 	return 0;
-@@ -652,6 +676,10 @@ static int __bind(struct mapped_device *
- 
- static void __unbind(struct mapped_device *md)
- {
-+	if (!md->map)
-+		return;
-+
-+	dm_table_event_callback(md->map, NULL, NULL);
- 	dm_table_put(md->map);
- 	md->map = NULL;
- 	set_capacity(md->disk, 0);
-@@ -661,35 +689,26 @@ static void __unbind(struct mapped_devic
-  * Constructor for a new device.
-  */
- static int create_aux(unsigned int minor, int persistent,
--		      struct dm_table *table, struct mapped_device **result)
-+		      struct mapped_device **result)
- {
--	int r;
- 	struct mapped_device *md;
- 
- 	md = alloc_dev(minor, persistent);
- 	if (!md)
- 		return -ENXIO;
- 
--	r = __bind(md, table);
--	if (r) {
--		free_dev(md);
--		return r;
--	}
--	dm_table_resume_targets(md->map);
--
- 	*result = md;
- 	return 0;
- }
- 
--int dm_create(struct dm_table *table, struct mapped_device **result)
-+int dm_create(struct mapped_device **result)
- {
--	return create_aux(0, 0, table, result);
-+	return create_aux(0, 0, result);
- }
- 
--int dm_create_with_minor(unsigned int minor,
--			 struct dm_table *table, struct mapped_device **result)
-+int dm_create_with_minor(unsigned int minor, struct mapped_device **result)
- {
--	return create_aux(minor, 1, table, result);
-+	return create_aux(minor, 1, result);
- }
- 
- void dm_get(struct mapped_device *md)
-@@ -700,7 +719,7 @@ void dm_get(struct mapped_device *md)
- void dm_put(struct mapped_device *md)
- {
- 	if (atomic_dec_and_test(&md->holders)) {
--		if (!test_bit(DMF_SUSPENDED, &md->flags))
-+		if (!test_bit(DMF_SUSPENDED, &md->flags) && md->map)
- 			dm_table_suspend_targets(md->map);
- 		__unbind(md);
- 		free_dev(md);
-@@ -790,7 +809,8 @@ int dm_suspend(struct mapped_device *md)
- 	down_write(&md->lock);
- 	remove_wait_queue(&md->wait, &wait);
- 	set_bit(DMF_SUSPENDED, &md->flags);
--	dm_table_suspend_targets(md->map);
-+	if (md->map)
-+		dm_table_suspend_targets(md->map);
- 	up_write(&md->lock);
- 
- 	return 0;
-@@ -801,7 +821,8 @@ int dm_resume(struct mapped_device *md)
- 	struct deferred_io *def;
- 
- 	down_write(&md->lock);
--	if (!test_bit(DMF_SUSPENDED, &md->flags) ||
-+	if (!md->map ||
-+	    !test_bit(DMF_SUSPENDED, &md->flags) ||
- 	    !dm_table_get_size(md->map)) {
- 		up_write(&md->lock);
- 		return -EINVAL;
-@@ -820,6 +841,42 @@ int dm_resume(struct mapped_device *md)
- 	return 0;
- }
- 
-+/*-----------------------------------------------------------------
-+ * Event notification.
-+ *---------------------------------------------------------------*/
-+uint32_t dm_get_event_nr(struct mapped_device *md)
-+{
-+	uint32_t r;
-+
-+	down_read(&md->lock);
-+	r = md->event_nr;
-+	up_read(&md->lock);
-+
-+	return r;
-+}
-+
-+int dm_add_wait_queue(struct mapped_device *md, wait_queue_t *wq,
-+		      uint32_t event_nr)
-+{
-+	down_write(&md->lock);
-+	if (event_nr != md->event_nr) {
-+		up_write(&md->lock);
-+		return 1;
-+	}
-+
-+	add_wait_queue(&md->eventq, wq);
-+	up_write(&md->lock);
-+
-+	return 0;
-+}
-+
-+void dm_remove_wait_queue(struct mapped_device *md, wait_queue_t *wq)
-+{
-+	down_write(&md->lock);
-+	remove_wait_queue(&md->eventq, wq);
-+	up_write(&md->lock);
-+}
-+
- /*
-  * The gendisk is only valid as long as you have a reference
-  * count on 'md'.
-@@ -835,7 +892,8 @@ struct dm_table *dm_get_table(struct map
- 
- 	down_read(&md->lock);
- 	t = md->map;
--	dm_table_get(t);
-+	if (t)
-+		dm_table_get(t);
- 	up_read(&md->lock);
- 
- 	return t;
---- linux-2.6.0-test1/drivers/md/dm.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/drivers/md/dm.h	2003-07-19 17:03:49.000000000 -0700
-@@ -51,9 +51,8 @@ struct mapped_device;
-  * Functions for manipulating a struct mapped_device.
-  * Drop the reference with dm_put when you finish with the object.
-  *---------------------------------------------------------------*/
--int dm_create(struct dm_table *table, struct mapped_device **md);
--int dm_create_with_minor(unsigned int minor, struct dm_table *table,
--			 struct mapped_device **md);
-+int dm_create(struct mapped_device **md);
-+int dm_create_with_minor(unsigned int minor, struct mapped_device **md);
- 
- /*
-  * Reference counting for md.
-@@ -79,6 +78,14 @@ int dm_swap_table(struct mapped_device *
- struct dm_table *dm_get_table(struct mapped_device *md);
- 
- /*
-+ * Event functions.
-+ */
-+uint32_t dm_get_event_nr(struct mapped_device *md);
-+int dm_add_wait_queue(struct mapped_device *md, wait_queue_t *wq,
-+		      uint32_t event_nr);
-+void dm_remove_wait_queue(struct mapped_device *md, wait_queue_t *wq);
-+
-+/*
-  * Info functions.
-  */
- struct gendisk *dm_disk(struct mapped_device *md);
-@@ -96,6 +103,8 @@ void dm_table_put(struct dm_table *t);
- int dm_table_add_target(struct dm_table *t, const char *type,
- 			sector_t start,	sector_t len, char *params);
- int dm_table_complete(struct dm_table *t);
-+void dm_table_event_callback(struct dm_table *t,
-+			     void (*fn)(void *), void *context);
- void dm_table_event(struct dm_table *t);
- sector_t dm_table_get_size(struct dm_table *t);
- struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index);
-@@ -104,7 +113,6 @@ void dm_table_set_restrictions(struct dm
- unsigned int dm_table_get_num_targets(struct dm_table *t);
- struct list_head *dm_table_get_devices(struct dm_table *t);
- int dm_table_get_mode(struct dm_table *t);
--void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq);
- void dm_table_suspend_targets(struct dm_table *t);
- void dm_table_resume_targets(struct dm_table *t);
- 
---- linux-2.6.0-test1/drivers/md/dm-ioctl.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/md/dm-ioctl.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,1134 +1,13 @@
- /*
-- * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
-+ * Copyright (C) 2003 Sistina Software (UK) Limited.
-  *
-  * This file is released under the GPL.
-  */
- 
--#include "dm.h"
--
--#include <linux/module.h>
--#include <linux/vmalloc.h>
--#include <linux/miscdevice.h>
- #include <linux/dm-ioctl.h>
--#include <linux/init.h>
--#include <linux/wait.h>
--#include <linux/blk.h>
--#include <linux/slab.h>
--#include <linux/devfs_fs_kernel.h>
--
--#include <asm/uaccess.h>
--
--#define DM_DRIVER_EMAIL "dm@uk.sistina.com"
--
--/*-----------------------------------------------------------------
-- * The ioctl interface needs to be able to look up devices by
-- * name or uuid.
-- *---------------------------------------------------------------*/
--struct hash_cell {
--	struct list_head name_list;
--	struct list_head uuid_list;
--
--	char *name;
--	char *uuid;
--	struct mapped_device *md;
--};
--
--#define NUM_BUCKETS 64
--#define MASK_BUCKETS (NUM_BUCKETS - 1)
--static struct list_head _name_buckets[NUM_BUCKETS];
--static struct list_head _uuid_buckets[NUM_BUCKETS];
--
--void dm_hash_remove_all(void);
--
--/*
-- * Guards access to all three tables.
-- */
--static DECLARE_RWSEM(_hash_lock);
--
--static void init_buckets(struct list_head *buckets)
--{
--	unsigned int i;
--
--	for (i = 0; i < NUM_BUCKETS; i++)
--		INIT_LIST_HEAD(buckets + i);
--}
--
--int dm_hash_init(void)
--{
--	init_buckets(_name_buckets);
--	init_buckets(_uuid_buckets);
--	devfs_mk_dir(DM_DIR);
--	return 0;
--}
--
--void dm_hash_exit(void)
--{
--	dm_hash_remove_all();
--	devfs_remove(DM_DIR);
--}
--
--/*-----------------------------------------------------------------
-- * Hash function:
-- * We're not really concerned with the str hash function being
-- * fast since it's only used by the ioctl interface.
-- *---------------------------------------------------------------*/
--static unsigned int hash_str(const char *str)
--{
--	const unsigned int hash_mult = 2654435387U;
--	unsigned int h = 0;
--
--	while (*str)
--		h = (h + (unsigned int) *str++) * hash_mult;
--
--	return h & MASK_BUCKETS;
--}
--
--/*-----------------------------------------------------------------
-- * Code for looking up a device by name
-- *---------------------------------------------------------------*/
--static struct hash_cell *__get_name_cell(const char *str)
--{
--	struct list_head *tmp;
--	struct hash_cell *hc;
--	unsigned int h = hash_str(str);
--
--	list_for_each (tmp, _name_buckets + h) {
--		hc = list_entry(tmp, struct hash_cell, name_list);
--		if (!strcmp(hc->name, str))
--			return hc;
--	}
--
--	return NULL;
--}
--
--static struct hash_cell *__get_uuid_cell(const char *str)
--{
--	struct list_head *tmp;
--	struct hash_cell *hc;
--	unsigned int h = hash_str(str);
--
--	list_for_each (tmp, _uuid_buckets + h) {
--		hc = list_entry(tmp, struct hash_cell, uuid_list);
--		if (!strcmp(hc->uuid, str))
--			return hc;
--	}
--
--	return NULL;
--}
--
--/*-----------------------------------------------------------------
-- * Inserting, removing and renaming a device.
-- *---------------------------------------------------------------*/
--static inline char *kstrdup(const char *str)
--{
--	char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
--	if (r)
--		strcpy(r, str);
--	return r;
--}
--
--static struct hash_cell *alloc_cell(const char *name, const char *uuid,
--				    struct mapped_device *md)
--{
--	struct hash_cell *hc;
--
--	hc = kmalloc(sizeof(*hc), GFP_KERNEL);
--	if (!hc)
--		return NULL;
--
--	hc->name = kstrdup(name);
--	if (!hc->name) {
--		kfree(hc);
--		return NULL;
--	}
--
--	if (!uuid)
--		hc->uuid = NULL;
--
--	else {
--		hc->uuid = kstrdup(uuid);
--		if (!hc->uuid) {
--			kfree(hc->name);
--			kfree(hc);
--			return NULL;
--		}
--	}
--
--	INIT_LIST_HEAD(&hc->name_list);
--	INIT_LIST_HEAD(&hc->uuid_list);
--	hc->md = md;
--	return hc;
--}
--
--static void free_cell(struct hash_cell *hc)
--{
--	if (hc) {
--		kfree(hc->name);
--		kfree(hc->uuid);
--		kfree(hc);
--	}
--}
--
--/*
-- * devfs stuff.
-- */
--static int register_with_devfs(struct hash_cell *hc)
--{
--	struct gendisk *disk = dm_disk(hc->md);
--
--	devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
--		       S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
--		       DM_DIR "/%s", hc->name);
--	return 0;
--}
--
--static int unregister_with_devfs(struct hash_cell *hc)
--{
--	devfs_remove(DM_DIR"/%s", hc->name);
--	return 0;
--}
--
--/*
-- * The kdev_t and uuid of a device can never change once it is
-- * initially inserted.
-- */
--int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
--{
--	struct hash_cell *cell;
--
--	/*
--	 * Allocate the new cells.
--	 */
--	cell = alloc_cell(name, uuid, md);
--	if (!cell)
--		return -ENOMEM;
--
--	/*
--	 * Insert the cell into all three hash tables.
--	 */
--	down_write(&_hash_lock);
--	if (__get_name_cell(name))
--		goto bad;
--
--	list_add(&cell->name_list, _name_buckets + hash_str(name));
--
--	if (uuid) {
--		if (__get_uuid_cell(uuid)) {
--			list_del(&cell->name_list);
--			goto bad;
--		}
--		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
--	}
--	register_with_devfs(cell);
--	dm_get(md);
--	up_write(&_hash_lock);
--
--	return 0;
--
-- bad:
--	up_write(&_hash_lock);
--	free_cell(cell);
--	return -EBUSY;
--}
--
--void __hash_remove(struct hash_cell *hc)
--{
--	/* remove from the dev hash */
--	list_del(&hc->uuid_list);
--	list_del(&hc->name_list);
--	unregister_with_devfs(hc);
--	dm_put(hc->md);
--	free_cell(hc);
--}
--
--void dm_hash_remove_all(void)
--{
--	int i;
--	struct hash_cell *hc;
--	struct list_head *tmp, *n;
--
--	down_write(&_hash_lock);
--	for (i = 0; i < NUM_BUCKETS; i++) {
--		list_for_each_safe (tmp, n, _name_buckets + i) {
--			hc = list_entry(tmp, struct hash_cell, name_list);
--			__hash_remove(hc);
--		}
--	}
--	up_write(&_hash_lock);
--}
--
--int dm_hash_rename(const char *old, const char *new)
--{
--	char *new_name, *old_name;
--	struct hash_cell *hc;
--
--	/*
--	 * duplicate new.
--	 */
--	new_name = kstrdup(new);
--	if (!new_name)
--		return -ENOMEM;
--
--	down_write(&_hash_lock);
--
--	/*
--	 * Is new free ?
--	 */
--	hc = __get_name_cell(new);
--	if (hc) {
--		DMWARN("asked to rename to an already existing name %s -> %s",
--		       old, new);
--		up_write(&_hash_lock);
--		kfree(new_name);
--		return -EBUSY;
--	}
--
--	/*
--	 * Is there such a device as 'old' ?
--	 */
--	hc = __get_name_cell(old);
--	if (!hc) {
--		DMWARN("asked to rename a non existent device %s -> %s",
--		       old, new);
--		up_write(&_hash_lock);
--		kfree(new_name);
--		return -ENXIO;
--	}
--
--	/*
--	 * rename and move the name cell.
--	 */
--	unregister_with_devfs(hc);
--
--	list_del(&hc->name_list);
--	old_name = hc->name;
--	hc->name = new_name;
--	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
--
--	/* rename the device node in devfs */
--	register_with_devfs(hc);
--
--	up_write(&_hash_lock);
--	kfree(old_name);
--	return 0;
--}
--
--
--/*-----------------------------------------------------------------
-- * Implementation of the ioctl commands
-- *---------------------------------------------------------------*/
--
--/*
-- * All the ioctl commands get dispatched to functions with this
-- * prototype.
-- */
--typedef int (*ioctl_fn)(struct dm_ioctl *param, struct dm_ioctl *user);
--
--/*
-- * Check a string doesn't overrun the chunk of
-- * memory we copied from userland.
-- */
--static int valid_str(char *str, void *begin, void *end)
--{
--	while (((void *) str >= begin) && ((void *) str < end))
--		if (!*str++)
--			return 0;
--
--	return -EINVAL;
--}
--
--static int next_target(struct dm_target_spec *last, uint32_t next,
--		       void *begin, void *end,
--		       struct dm_target_spec **spec, char **params)
--{
--	*spec = (struct dm_target_spec *)
--	    ((unsigned char *) last + next);
--	*params = (char *) (*spec + 1);
--
--	if (*spec < (last + 1) || ((void *) *spec > end))
--		return -EINVAL;
--
--	return valid_str(*params, begin, end);
--}
--
--static int populate_table(struct dm_table *table, struct dm_ioctl *args)
--{
--	int r, first = 1;
--	unsigned int i = 0;
--	struct dm_target_spec *spec;
--	char *params;
--	void *begin, *end;
--
--	if (!args->target_count) {
--		DMWARN("populate_table: no targets specified");
--		return -EINVAL;
--	}
--
--	begin = (void *) args;
--	end = begin + args->data_size;
--
--	for (i = 0; i < args->target_count; i++) {
--
--		if (first)
--			r = next_target((struct dm_target_spec *) args,
--					args->data_start,
--					begin, end, &spec, &params);
--		else
--			r = next_target(spec, spec->next, begin, end,
--					&spec, &params);
--
--		if (r) {
--			DMWARN("unable to find target");
--			return -EINVAL;
--		}
--
--		r = dm_table_add_target(table, spec->target_type,
--					(sector_t) spec->sector_start,
--					(sector_t) spec->length,
--					params);
--		if (r) {
--			DMWARN("internal error adding target to table");
--			return -EINVAL;
--		}
--
--		first = 0;
--	}
--
--	return dm_table_complete(table);
--}
--
--/*
-- * Round up the ptr to the next 'align' boundary.  Obviously
-- * 'align' must be a power of 2.
-- */
--static inline void *align_ptr(void *ptr, unsigned int align)
--{
--	align--;
--	return (void *) (((unsigned long) (ptr + align)) & ~align);
--}
--
--/*
-- * Copies a dm_ioctl and an optional additional payload to
-- * userland.
-- */
--static int results_to_user(struct dm_ioctl *user, struct dm_ioctl *param,
--			   void *data, uint32_t len)
--{
--	int r;
--	void *ptr = NULL;
--
--	if (data) {
--		ptr = align_ptr(user + 1, sizeof(unsigned long));
--		param->data_start = ptr - (void *) user;
--	}
--
--	/*
--	 * The version number has already been filled in, so we
--	 * just copy later fields.
--	 */
--	r = copy_to_user(&user->data_size, &param->data_size,
--			 sizeof(*param) - sizeof(param->version));
--	if (r)
--		return -EFAULT;
--
--	if (data) {
--		if (param->data_start + len > param->data_size)
--			return -ENOSPC;
--
--		if (copy_to_user(ptr, data, len))
--			r = -EFAULT;
--	}
--
--	return r;
--}
--
--/*
-- * Fills in a dm_ioctl structure, ready for sending back to
-- * userland.
-- */
--static int __info(struct mapped_device *md, struct dm_ioctl *param)
--{
--	struct dm_table *table;
--	struct block_device *bdev;
--	struct gendisk *disk = dm_disk(md);
--
--	param->flags = DM_EXISTS_FLAG;
--	if (dm_suspended(md))
--		param->flags |= DM_SUSPEND_FLAG;
--
--	bdev = bdget_disk(disk, 0);
--	if (!bdev)
--		return -ENXIO;
--
--	param->dev = bdev->bd_dev;
--	param->open_count = bdev->bd_openers;
--	bdput(bdev);
--
--	if (disk->policy)
--		param->flags |= DM_READONLY_FLAG;
--
--	table = dm_get_table(md);
--	param->target_count = dm_table_get_num_targets(table);
--	dm_table_put(table);
--
--	return 0;
--}
--
--/*
-- * Always use UUID for lookups if it's present, otherwise use name.
-- */
--static inline struct mapped_device *find_device(struct dm_ioctl *param)
--{
--	struct hash_cell *hc;
--	struct mapped_device *md = NULL;
--
--	down_read(&_hash_lock);
--	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
--		__get_name_cell(param->name);
--	if (hc) {
--		md = hc->md;
--
--		/*
--		 * Sneakily write in both the name and the uuid
--		 * while we have the cell.
--		 */
--		strlcpy(param->name, hc->name, sizeof(param->name));
--		if (hc->uuid)
--			strlcpy(param->uuid, hc->uuid, sizeof(param->uuid));
--		else
--			param->uuid[0] = '\0';
--
--		dm_get(md);
--	}
--	up_read(&_hash_lock);
--
--	return md;
--}
--
--#define ALIGNMENT sizeof(int)
--static void *_align(void *ptr, unsigned int a)
--{
--	register unsigned long align = --a;
--
--	return (void *) (((unsigned long) ptr + align) & ~align);
--}
--
--/*
-- * Copies device info back to user space, used by
-- * the create and info ioctls.
-- */
--static int info(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	struct mapped_device *md;
--
--	param->flags = 0;
--
--	md = find_device(param);
--	if (!md)
--		/*
--		 * Device not found - returns cleared exists flag.
--		 */
--		goto out;
--
--	__info(md, param);
--	dm_put(md);
--
--      out:
--	return results_to_user(user, param, NULL, 0);
--}
--
--static inline int get_mode(struct dm_ioctl *param)
--{
--	int mode = FMODE_READ | FMODE_WRITE;
--
--	if (param->flags & DM_READONLY_FLAG)
--		mode = FMODE_READ;
--
--	return mode;
--}
--
--static int check_name(const char *name)
--{
--	if (name[0] == '/') {
--		DMWARN("invalid device name");
--		return -EINVAL;
--	}
--
--	return 0;
--}
--
--static int create(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	int r;
--	struct dm_table *t;
--	struct mapped_device *md;
--
--	r = check_name(param->name);
--	if (r)
--		return r;
--
--	r = dm_table_create(&t, get_mode(param));
--	if (r)
--		return r;
--
--	r = populate_table(t, param);
--	if (r) {
--		dm_table_put(t);
--		return r;
--	}
--
--	if (param->flags & DM_PERSISTENT_DEV_FLAG)
--		r = dm_create_with_minor(minor(to_kdev_t(param->dev)), t, &md);
--	else
--		r = dm_create(t, &md);
--
--	if (r) {
--		dm_table_put(t);
--		return r;
--	}
--	dm_table_put(t);	/* md will have grabbed its own reference */
--
--	set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
--	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
--	dm_put(md);
--
--	return r ? r : info(param, user);
--}
--
--/*
-- * Build up the status struct for each target
-- */
--static int __status(struct mapped_device *md, struct dm_ioctl *param,
--		    char *outbuf, size_t *len)
--{
--	unsigned int i, num_targets;
--	struct dm_target_spec *spec;
--	char *outptr;
--	status_type_t type;
--	struct dm_table *table = dm_get_table(md);
--
--	if (param->flags & DM_STATUS_TABLE_FLAG)
--		type = STATUSTYPE_TABLE;
--	else
--		type = STATUSTYPE_INFO;
--
--	outptr = outbuf;
--
--	/* Get all the target info */
--	num_targets = dm_table_get_num_targets(table);
--	for (i = 0; i < num_targets; i++) {
--		struct dm_target *ti = dm_table_get_target(table, i);
--
--		if (outptr - outbuf +
--		    sizeof(struct dm_target_spec) > param->data_size) {
--			dm_table_put(table);
--			return -ENOMEM;
--		}
--
--		spec = (struct dm_target_spec *) outptr;
--
--		spec->status = 0;
--		spec->sector_start = ti->begin;
--		spec->length = ti->len;
--		strlcpy(spec->target_type, ti->type->name,
--			sizeof(spec->target_type));
--
--		outptr += sizeof(struct dm_target_spec);
--
--		/* Get the status/table string from the target driver */
--		if (ti->type->status)
--			ti->type->status(ti, type, outptr,
--					 outbuf + param->data_size - outptr);
--		else
--			outptr[0] = '\0';
--
--		outptr += strlen(outptr) + 1;
--		_align(outptr, ALIGNMENT);
--		spec->next = outptr - outbuf;
--	}
--
--	param->target_count = num_targets;
--	*len = outptr - outbuf;
--	dm_table_put(table);
--
--	return 0;
--}
--
--/*
-- * Return the status of a device as a text string for each
-- * target.
-- */
--static int get_status(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	struct mapped_device *md;
--	size_t len = 0;
--	int ret;
--	char *outbuf = NULL;
--
--	md = find_device(param);
--	if (!md)
--		/*
--		 * Device not found - returns cleared exists flag.
--		 */
--		goto out;
--
--	/* We haven't a clue how long the resultant data will be so
--	   just allocate as much as userland has allowed us and make sure
--	   we don't overun it */
--	outbuf = kmalloc(param->data_size, GFP_KERNEL);
--	if (!outbuf)
--		goto out;
--	/*
--	 * Get the status of all targets
--	 */
--	__status(md, param, outbuf, &len);
--
--	/*
--	 * Setup the basic dm_ioctl structure.
--	 */
--	__info(md, param);
--
--      out:
--	if (md)
--		dm_put(md);
--
--	ret = results_to_user(user, param, outbuf, len);
--
--	if (outbuf)
--		kfree(outbuf);
--
--	return ret;
--}
--
--/*
-- * Wait for a device to report an event
-- */
--static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	struct mapped_device *md;
--	struct dm_table *table;
--	DECLARE_WAITQUEUE(wq, current);
--
--	md = find_device(param);
--	if (!md)
--		/*
--		 * Device not found - returns cleared exists flag.
--		 */
--		goto out;
--
--	/*
--	 * Setup the basic dm_ioctl structure.
--	 */
--	__info(md, param);
--
--	/*
--	 * Wait for a notification event
--	 */
--	set_current_state(TASK_INTERRUPTIBLE);
--	table = dm_get_table(md);
--	dm_table_add_wait_queue(table, &wq);
--	dm_table_put(table);
--	dm_put(md);
--
--	schedule();
--
--      out:
--	return results_to_user(user, param, NULL, 0);
--}
--
--/*
-- * Retrieves a list of devices used by a particular dm device.
-- */
--static int dep(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	int r;
--	unsigned int count;
--	struct mapped_device *md;
--	struct list_head *tmp;
--	size_t len = 0;
--	struct dm_target_deps *deps = NULL;
--	struct dm_table *table;
--
--	md = find_device(param);
--	if (!md)
--		goto out;
--	table = dm_get_table(md);
--
--	/*
--	 * Setup the basic dm_ioctl structure.
--	 */
--	__info(md, param);
--
--	/*
--	 * Count the devices.
--	 */
--	count = 0;
--	list_for_each(tmp, dm_table_get_devices(table))
--	    count++;
--
--	/*
--	 * Allocate a kernel space version of the dm_target_status
--	 * struct.
--	 */
--	if (array_too_big(sizeof(*deps), sizeof(*deps->dev), count)) {
--		dm_table_put(table);
--		dm_put(md);
--		return -ENOMEM;
--	}
--
--	len = sizeof(*deps) + (sizeof(*deps->dev) * count);
--	deps = kmalloc(len, GFP_KERNEL);
--	if (!deps) {
--		dm_table_put(table);
--		dm_put(md);
--		return -ENOMEM;
--	}
--
--	/*
--	 * Fill in the devices.
--	 */
--	deps->count = count;
--	count = 0;
--	list_for_each(tmp, dm_table_get_devices(table)) {
--		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
--		deps->dev[count++] = dd->bdev->bd_dev;
--	}
--	dm_table_put(table);
--	dm_put(md);
--
--      out:
--	r = results_to_user(user, param, deps, len);
--
--	kfree(deps);
--	return r;
--}
--
--static int remove(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	struct hash_cell *hc;
--
--	down_write(&_hash_lock);
--	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
--		__get_name_cell(param->name);
--	if (!hc) {
--		DMWARN("device doesn't appear to be in the dev hash table.");
--		up_write(&_hash_lock);
--		return -EINVAL;
--	}
--
--	/*
--	 * You may ask the interface to drop its reference to an
--	 * in use device.  This is no different to unlinking a
--	 * file that someone still has open.  The device will not
--	 * actually be destroyed until the last opener closes it.
--	 * The name and uuid of the device (both are interface
--	 * properties) will be available for reuse immediately.
--	 *
--	 * You don't want to drop a _suspended_ device from the
--	 * interface, since that will leave you with no way of
--	 * resuming it.
--	 */
--	if (dm_suspended(hc->md)) {
--		DMWARN("refusing to remove a suspended device.");
--		up_write(&_hash_lock);
--		return -EPERM;
--	}
--
--	__hash_remove(hc);
--	up_write(&_hash_lock);
--	return 0;
--}
--
--static int remove_all(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	dm_hash_remove_all();
--	return 0;
--}
--
--static int suspend(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	int r;
--	struct mapped_device *md;
--
--	md = find_device(param);
--	if (!md)
--		return -ENXIO;
--
--	if (param->flags & DM_SUSPEND_FLAG)
--		r = dm_suspend(md);
--	else
--		r = dm_resume(md);
--
--	dm_put(md);
--	return r;
--}
--
--static int reload(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	int r;
--	struct mapped_device *md;
--	struct dm_table *t;
--
--	r = dm_table_create(&t, get_mode(param));
--	if (r)
--		return r;
--
--	r = populate_table(t, param);
--	if (r) {
--		dm_table_put(t);
--		return r;
--	}
--
--	md = find_device(param);
--	if (!md) {
--		dm_table_put(t);
--		return -ENXIO;
--	}
--
--	r = dm_swap_table(md, t);
--	if (r) {
--		dm_put(md);
--		dm_table_put(t);
--		return r;
--	}
--	dm_table_put(t);	/* md will have taken its own reference */
--
--	set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
--	dm_put(md);
--
--	r = info(param, user);
--	return r;
--}
--
--static int rename(struct dm_ioctl *param, struct dm_ioctl *user)
--{
--	int r;
--	char *new_name = (char *) param + param->data_start;
--
--	if (valid_str(new_name, (void *) param,
--		      (void *) param + param->data_size)) {
--		DMWARN("Invalid new logical volume name supplied.");
--		return -EINVAL;
--	}
--
--	r = check_name(new_name);
--	if (r)
--		return r;
--
--	return dm_hash_rename(param->name, new_name);
--}
--
--
--/*-----------------------------------------------------------------
-- * Implementation of open/close/ioctl on the special char
-- * device.
-- *---------------------------------------------------------------*/
--static ioctl_fn lookup_ioctl(unsigned int cmd)
--{
--	static struct {
--		int cmd;
--		ioctl_fn fn;
--	} _ioctls[] = {
--		{DM_VERSION_CMD, NULL},	/* version is dealt with elsewhere */
--		{DM_REMOVE_ALL_CMD, remove_all},
--		{DM_DEV_CREATE_CMD, create},
--		{DM_DEV_REMOVE_CMD, remove},
--		{DM_DEV_RELOAD_CMD, reload},
--		{DM_DEV_RENAME_CMD, rename},
--		{DM_DEV_SUSPEND_CMD, suspend},
--		{DM_DEV_DEPS_CMD, dep},
--		{DM_DEV_STATUS_CMD, info},
--		{DM_TARGET_STATUS_CMD, get_status},
--		{DM_TARGET_WAIT_CMD, wait_device_event},
--	};
--
--	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
--}
--
--/*
-- * As well as checking the version compatibility this always
-- * copies the kernel interface version out.
-- */
--static int check_version(unsigned int cmd, struct dm_ioctl *user)
--{
--	uint32_t version[3];
--	int r = 0;
--
--	if (copy_from_user(version, user->version, sizeof(version)))
--		return -EFAULT;
--
--	if ((DM_VERSION_MAJOR != version[0]) ||
--	    (DM_VERSION_MINOR < version[1])) {
--		DMWARN("ioctl interface mismatch: "
--		       "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
--		       DM_VERSION_MAJOR, DM_VERSION_MINOR,
--		       DM_VERSION_PATCHLEVEL,
--		       version[0], version[1], version[2], cmd);
--		r = -EINVAL;
--	}
--
--	/*
--	 * Fill in the kernel version.
--	 */
--	version[0] = DM_VERSION_MAJOR;
--	version[1] = DM_VERSION_MINOR;
--	version[2] = DM_VERSION_PATCHLEVEL;
--	if (copy_to_user(user->version, version, sizeof(version)))
--		return -EFAULT;
--
--	return r;
--}
--
--static void free_params(struct dm_ioctl *param)
--{
--	vfree(param);
--}
--
--static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
--{
--	struct dm_ioctl tmp, *dmi;
--
--	if (copy_from_user(&tmp, user, sizeof(tmp)))
--		return -EFAULT;
--
--	if (tmp.data_size < sizeof(tmp))
--		return -EINVAL;
--
--	dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
--	if (!dmi)
--		return -ENOMEM;
--
--	if (copy_from_user(dmi, user, tmp.data_size)) {
--		vfree(dmi);
--		return -EFAULT;
--	}
--
--	*param = dmi;
--	return 0;
--}
--
--static int validate_params(uint cmd, struct dm_ioctl *param)
--{
--	/* Ignores parameters */
--	if (cmd == DM_REMOVE_ALL_CMD)
--		return 0;
--
--	/* Unless creating, either name of uuid but not both */
--	if (cmd != DM_DEV_CREATE_CMD) {
--		if ((!*param->uuid && !*param->name) ||
--		    (*param->uuid && *param->name)) {
--			DMWARN("one of name or uuid must be supplied");
--			return -EINVAL;
--		}
--	}
--
--	/* Ensure strings are terminated */
--	param->name[DM_NAME_LEN - 1] = '\0';
--	param->uuid[DM_UUID_LEN - 1] = '\0';
--
--	return 0;
--}
--
--static int ctl_ioctl(struct inode *inode, struct file *file,
--		     uint command, ulong u)
--{
--	int r = 0;
--	unsigned int cmd;
--	struct dm_ioctl *param;
--	struct dm_ioctl *user = (struct dm_ioctl *) u;
--	ioctl_fn fn = NULL;
--
--	/* only root can play with this */
--	if (!capable(CAP_SYS_ADMIN))
--		return -EACCES;
--
--	if (_IOC_TYPE(command) != DM_IOCTL)
--		return -ENOTTY;
--
--	cmd = _IOC_NR(command);
--
--	/*
--	 * Check the interface version passed in.  This also
--	 * writes out the kernels interface version.
--	 */
--	r = check_version(cmd, user);
--	if (r)
--		return r;
--
--	/*
--	 * Nothing more to do for the version command.
--	 */
--	if (cmd == DM_VERSION_CMD)
--		return 0;
--
--	fn = lookup_ioctl(cmd);
--	if (!fn) {
--		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
--		return -ENOTTY;
--	}
--
--	/*
--	 * Copy the parameters into kernel space.
--	 */
--	r = copy_params(user, &param);
--	if (r)
--		return r;
--
--	r = validate_params(cmd, param);
--	if (r) {
--		free_params(param);
--		return r;
--	}
--
--	r = fn(param, user);
--	free_params(param);
--	return r;
--}
--
--static struct file_operations _ctl_fops = {
--	.ioctl	 = ctl_ioctl,
--	.owner	 = THIS_MODULE,
--};
--
--static struct miscdevice _dm_misc = {
--	.minor		= MISC_DYNAMIC_MINOR,
--	.name		= DM_NAME,
--	.devfs_name	= "mapper/control",
--	.fops		= &_ctl_fops
--};
--
--/*
-- * Create misc character device and link to DM_DIR/control.
-- */
--int __init dm_interface_init(void)
--{
--	int r;
--
--	r = dm_hash_init();
--	if (r)
--		return r;
--
--	r = misc_register(&_dm_misc);
--	if (r) {
--		DMERR("misc_register failed for control device");
--		dm_hash_exit();
--		return r;
--	}
--
--	DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
--	       DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
--	       DM_DRIVER_EMAIL);
--	return 0;
--
--	if (misc_deregister(&_dm_misc) < 0)
--		DMERR("misc_deregister failed for control device");
--	dm_hash_exit();
--	return r;
--}
- 
--void dm_interface_exit(void)
--{
--	if (misc_deregister(&_dm_misc) < 0)
--		DMERR("misc_deregister failed for control device");
--	dm_hash_exit();
--}
-+#ifdef CONFIG_DM_IOCTL_V4
-+#include "dm-ioctl-v4.c"
-+#else
-+#include "dm-ioctl-v1.c"
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/md/dm-ioctl-v1.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,1160 @@
-+/*
-+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
-+ *
-+ * This file is released under the GPL.
-+ */
-+
-+#include "dm.h"
-+
-+#include <linux/module.h>
-+#include <linux/vmalloc.h>
-+#include <linux/miscdevice.h>
-+#include <linux/dm-ioctl.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/blk.h>
-+#include <linux/slab.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#include <asm/uaccess.h>
-+
-+#define DM_DRIVER_EMAIL "dm@uk.sistina.com"
-+
-+/*-----------------------------------------------------------------
-+ * The ioctl interface needs to be able to look up devices by
-+ * name or uuid.
-+ *---------------------------------------------------------------*/
-+struct hash_cell {
-+	struct list_head name_list;
-+	struct list_head uuid_list;
-+
-+	char *name;
-+	char *uuid;
-+	struct mapped_device *md;
-+};
-+
-+#define NUM_BUCKETS 64
-+#define MASK_BUCKETS (NUM_BUCKETS - 1)
-+static struct list_head _name_buckets[NUM_BUCKETS];
-+static struct list_head _uuid_buckets[NUM_BUCKETS];
-+
-+void dm_hash_remove_all(void);
-+
-+/*
-+ * Guards access to all three tables.
-+ */
-+static DECLARE_RWSEM(_hash_lock);
-+
-+static void init_buckets(struct list_head *buckets)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i < NUM_BUCKETS; i++)
-+		INIT_LIST_HEAD(buckets + i);
-+}
-+
-+int dm_hash_init(void)
-+{
-+	init_buckets(_name_buckets);
-+	init_buckets(_uuid_buckets);
-+	devfs_mk_dir(DM_DIR);
-+	return 0;
-+}
-+
-+void dm_hash_exit(void)
-+{
-+	dm_hash_remove_all();
-+	devfs_remove(DM_DIR);
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Hash function:
-+ * We're not really concerned with the str hash function being
-+ * fast since it's only used by the ioctl interface.
-+ *---------------------------------------------------------------*/
-+static unsigned int hash_str(const char *str)
-+{
-+	const unsigned int hash_mult = 2654435387U;
-+	unsigned int h = 0;
-+
-+	while (*str)
-+		h = (h + (unsigned int) *str++) * hash_mult;
-+
-+	return h & MASK_BUCKETS;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Code for looking up a device by name
-+ *---------------------------------------------------------------*/
-+static struct hash_cell *__get_name_cell(const char *str)
-+{
-+	struct list_head *tmp;
-+	struct hash_cell *hc;
-+	unsigned int h = hash_str(str);
-+
-+	list_for_each (tmp, _name_buckets + h) {
-+		hc = list_entry(tmp, struct hash_cell, name_list);
-+		if (!strcmp(hc->name, str))
-+			return hc;
-+	}
-+
-+	return NULL;
-+}
-+
-+static struct hash_cell *__get_uuid_cell(const char *str)
-+{
-+	struct list_head *tmp;
-+	struct hash_cell *hc;
-+	unsigned int h = hash_str(str);
-+
-+	list_for_each (tmp, _uuid_buckets + h) {
-+		hc = list_entry(tmp, struct hash_cell, uuid_list);
-+		if (!strcmp(hc->uuid, str))
-+			return hc;
-+	}
-+
-+	return NULL;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Inserting, removing and renaming a device.
-+ *---------------------------------------------------------------*/
-+static inline char *kstrdup(const char *str)
-+{
-+	char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
-+	if (r)
-+		strcpy(r, str);
-+	return r;
-+}
-+
-+static struct hash_cell *alloc_cell(const char *name, const char *uuid,
-+				    struct mapped_device *md)
-+{
-+	struct hash_cell *hc;
-+
-+	hc = kmalloc(sizeof(*hc), GFP_KERNEL);
-+	if (!hc)
-+		return NULL;
-+
-+	hc->name = kstrdup(name);
-+	if (!hc->name) {
-+		kfree(hc);
-+		return NULL;
-+	}
-+
-+	if (!uuid)
-+		hc->uuid = NULL;
-+
-+	else {
-+		hc->uuid = kstrdup(uuid);
-+		if (!hc->uuid) {
-+			kfree(hc->name);
-+			kfree(hc);
-+			return NULL;
-+		}
-+	}
-+
-+	INIT_LIST_HEAD(&hc->name_list);
-+	INIT_LIST_HEAD(&hc->uuid_list);
-+	hc->md = md;
-+	return hc;
-+}
-+
-+static void free_cell(struct hash_cell *hc)
-+{
-+	if (hc) {
-+		kfree(hc->name);
-+		kfree(hc->uuid);
-+		kfree(hc);
-+	}
-+}
-+
-+/*
-+ * devfs stuff.
-+ */
-+static int register_with_devfs(struct hash_cell *hc)
-+{
-+	struct gendisk *disk = dm_disk(hc->md);
-+
-+	devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
-+		       S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
-+		       DM_DIR "/%s", hc->name);
-+	return 0;
-+}
-+
-+static int unregister_with_devfs(struct hash_cell *hc)
-+{
-+	devfs_remove(DM_DIR"/%s", hc->name);
-+	return 0;
-+}
-+
-+/*
-+ * The kdev_t and uuid of a device can never change once it is
-+ * initially inserted.
-+ */
-+int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
-+{
-+	struct hash_cell *cell;
-+
-+	/*
-+	 * Allocate the new cells.
-+	 */
-+	cell = alloc_cell(name, uuid, md);
-+	if (!cell)
-+		return -ENOMEM;
-+
-+	/*
-+	 * Insert the cell into all three hash tables.
-+	 */
-+	down_write(&_hash_lock);
-+	if (__get_name_cell(name))
-+		goto bad;
-+
-+	list_add(&cell->name_list, _name_buckets + hash_str(name));
-+
-+	if (uuid) {
-+		if (__get_uuid_cell(uuid)) {
-+			list_del(&cell->name_list);
-+			goto bad;
-+		}
-+		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
-+	}
-+	register_with_devfs(cell);
-+	dm_get(md);
-+	up_write(&_hash_lock);
-+
-+	return 0;
-+
-+ bad:
-+	up_write(&_hash_lock);
-+	free_cell(cell);
-+	return -EBUSY;
-+}
-+
-+void __hash_remove(struct hash_cell *hc)
-+{
-+	/* remove from the dev hash */
-+	list_del(&hc->uuid_list);
-+	list_del(&hc->name_list);
-+	unregister_with_devfs(hc);
-+	dm_put(hc->md);
-+	free_cell(hc);
-+}
-+
-+void dm_hash_remove_all(void)
-+{
-+	int i;
-+	struct hash_cell *hc;
-+	struct list_head *tmp, *n;
-+
-+	down_write(&_hash_lock);
-+	for (i = 0; i < NUM_BUCKETS; i++) {
-+		list_for_each_safe (tmp, n, _name_buckets + i) {
-+			hc = list_entry(tmp, struct hash_cell, name_list);
-+			__hash_remove(hc);
-+		}
-+	}
-+	up_write(&_hash_lock);
-+}
-+
-+int dm_hash_rename(const char *old, const char *new)
-+{
-+	char *new_name, *old_name;
-+	struct hash_cell *hc;
-+
-+	/*
-+	 * duplicate new.
-+	 */
-+	new_name = kstrdup(new);
-+	if (!new_name)
-+		return -ENOMEM;
-+
-+	down_write(&_hash_lock);
-+
-+	/*
-+	 * Is new free ?
-+	 */
-+	hc = __get_name_cell(new);
-+	if (hc) {
-+		DMWARN("asked to rename to an already existing name %s -> %s",
-+		       old, new);
-+		up_write(&_hash_lock);
-+		kfree(new_name);
-+		return -EBUSY;
-+	}
-+
-+	/*
-+	 * Is there such a device as 'old' ?
-+	 */
-+	hc = __get_name_cell(old);
-+	if (!hc) {
-+		DMWARN("asked to rename a non existent device %s -> %s",
-+		       old, new);
-+		up_write(&_hash_lock);
-+		kfree(new_name);
-+		return -ENXIO;
-+	}
-+
-+	/*
-+	 * rename and move the name cell.
-+	 */
-+	unregister_with_devfs(hc);
-+
-+	list_del(&hc->name_list);
-+	old_name = hc->name;
-+	hc->name = new_name;
-+	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
-+
-+	/* rename the device node in devfs */
-+	register_with_devfs(hc);
-+
-+	up_write(&_hash_lock);
-+	kfree(old_name);
-+	return 0;
-+}
-+
-+
-+/*-----------------------------------------------------------------
-+ * Implementation of the ioctl commands
-+ *---------------------------------------------------------------*/
-+
-+/*
-+ * All the ioctl commands get dispatched to functions with this
-+ * prototype.
-+ */
-+typedef int (*ioctl_fn)(struct dm_ioctl *param, struct dm_ioctl *user);
-+
-+/*
-+ * Check a string doesn't overrun the chunk of
-+ * memory we copied from userland.
-+ */
-+static int valid_str(char *str, void *begin, void *end)
-+{
-+	while (((void *) str >= begin) && ((void *) str < end))
-+		if (!*str++)
-+			return 0;
-+
-+	return -EINVAL;
-+}
-+
-+static int next_target(struct dm_target_spec *last, uint32_t next,
-+		       void *begin, void *end,
-+		       struct dm_target_spec **spec, char **params)
-+{
-+	*spec = (struct dm_target_spec *)
-+	    ((unsigned char *) last + next);
-+	*params = (char *) (*spec + 1);
-+
-+	if (*spec < (last + 1) || ((void *) *spec > end))
-+		return -EINVAL;
-+
-+	return valid_str(*params, begin, end);
-+}
-+
-+static int populate_table(struct dm_table *table, struct dm_ioctl *args)
-+{
-+	int r, first = 1;
-+	unsigned int i = 0;
-+	struct dm_target_spec *spec;
-+	char *params;
-+	void *begin, *end;
-+
-+	if (!args->target_count) {
-+		DMWARN("populate_table: no targets specified");
-+		return -EINVAL;
-+	}
-+
-+	begin = (void *) args;
-+	end = begin + args->data_size;
-+
-+	for (i = 0; i < args->target_count; i++) {
-+
-+		if (first)
-+			r = next_target((struct dm_target_spec *) args,
-+					args->data_start,
-+					begin, end, &spec, &params);
-+		else
-+			r = next_target(spec, spec->next, begin, end,
-+					&spec, &params);
-+
-+		if (r) {
-+			DMWARN("unable to find target");
-+			return -EINVAL;
-+		}
-+
-+		r = dm_table_add_target(table, spec->target_type,
-+					(sector_t) spec->sector_start,
-+					(sector_t) spec->length,
-+					params);
-+		if (r) {
-+			DMWARN("internal error adding target to table");
-+			return -EINVAL;
-+		}
-+
-+		first = 0;
-+	}
-+
-+	return dm_table_complete(table);
-+}
-+
-+/*
-+ * Round up the ptr to the next 'align' boundary.  Obviously
-+ * 'align' must be a power of 2.
-+ */
-+static inline void *align_ptr(void *ptr, unsigned int align)
-+{
-+	align--;
-+	return (void *) (((unsigned long) (ptr + align)) & ~align);
-+}
-+
-+/*
-+ * Copies a dm_ioctl and an optional additional payload to
-+ * userland.
-+ */
-+static int results_to_user(struct dm_ioctl *user, struct dm_ioctl *param,
-+			   void *data, uint32_t len)
-+{
-+	int r;
-+	void *ptr = NULL;
-+
-+	if (data) {
-+		ptr = align_ptr(user + 1, sizeof(unsigned long));
-+		param->data_start = ptr - (void *) user;
-+	}
-+
-+	/*
-+	 * The version number has already been filled in, so we
-+	 * just copy later fields.
-+	 */
-+	r = copy_to_user(&user->data_size, &param->data_size,
-+			 sizeof(*param) - sizeof(param->version));
-+	if (r)
-+		return -EFAULT;
-+
-+	if (data) {
-+		if (param->data_start + len > param->data_size)
-+			return -ENOSPC;
-+
-+		if (copy_to_user(ptr, data, len))
-+			r = -EFAULT;
-+	}
-+
-+	return r;
-+}
-+
-+/*
-+ * Fills in a dm_ioctl structure, ready for sending back to
-+ * userland.
-+ */
-+static int __info(struct mapped_device *md, struct dm_ioctl *param)
-+{
-+	struct dm_table *table;
-+	struct block_device *bdev;
-+	struct gendisk *disk = dm_disk(md);
-+
-+	param->flags = DM_EXISTS_FLAG;
-+	if (dm_suspended(md))
-+		param->flags |= DM_SUSPEND_FLAG;
-+
-+	bdev = bdget_disk(disk, 0);
-+	if (!bdev)
-+		return -ENXIO;
-+
-+	param->dev = bdev->bd_dev;
-+	param->open_count = bdev->bd_openers;
-+	bdput(bdev);
-+
-+	if (disk->policy)
-+		param->flags |= DM_READONLY_FLAG;
-+
-+	table = dm_get_table(md);
-+	param->target_count = dm_table_get_num_targets(table);
-+	dm_table_put(table);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Always use UUID for lookups if it's present, otherwise use name.
-+ */
-+static inline struct mapped_device *find_device(struct dm_ioctl *param)
-+{
-+	struct hash_cell *hc;
-+	struct mapped_device *md = NULL;
-+
-+	down_read(&_hash_lock);
-+	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
-+		__get_name_cell(param->name);
-+	if (hc) {
-+		md = hc->md;
-+
-+		/*
-+		 * Sneakily write in both the name and the uuid
-+		 * while we have the cell.
-+		 */
-+		strlcpy(param->name, hc->name, sizeof(param->name));
-+		if (hc->uuid)
-+			strlcpy(param->uuid, hc->uuid, sizeof(param->uuid));
-+		else
-+			param->uuid[0] = '\0';
-+
-+		dm_get(md);
-+	}
-+	up_read(&_hash_lock);
-+
-+	return md;
-+}
-+
-+#define ALIGNMENT sizeof(int)
-+static void *_align(void *ptr, unsigned int a)
-+{
-+	register unsigned long align = --a;
-+
-+	return (void *) (((unsigned long) ptr + align) & ~align);
-+}
-+
-+/*
-+ * Copies device info back to user space, used by
-+ * the create and info ioctls.
-+ */
-+static int info(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	struct mapped_device *md;
-+
-+	param->flags = 0;
-+
-+	md = find_device(param);
-+	if (!md)
-+		/*
-+		 * Device not found - returns cleared exists flag.
-+		 */
-+		goto out;
-+
-+	__info(md, param);
-+	dm_put(md);
-+
-+      out:
-+	return results_to_user(user, param, NULL, 0);
-+}
-+
-+static inline int get_mode(struct dm_ioctl *param)
-+{
-+	int mode = FMODE_READ | FMODE_WRITE;
-+
-+	if (param->flags & DM_READONLY_FLAG)
-+		mode = FMODE_READ;
-+
-+	return mode;
-+}
-+
-+static int check_name(const char *name)
-+{
-+	if (name[0] == '/') {
-+		DMWARN("invalid device name");
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+static int create(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	int r;
-+	struct dm_table *t;
-+	struct mapped_device *md;
-+
-+	r = check_name(param->name);
-+	if (r)
-+		return r;
-+
-+	r = dm_table_create(&t, get_mode(param));
-+	if (r)
-+		return r;
-+
-+	r = populate_table(t, param);
-+	if (r) {
-+		dm_table_put(t);
-+		return r;
-+	}
-+
-+	if (param->flags & DM_PERSISTENT_DEV_FLAG)
-+		r = dm_create_with_minor(minor(to_kdev_t(param->dev)), &md);
-+	else
-+		r = dm_create(&md);
-+
-+	if (r) {
-+		dm_table_put(t);
-+		return r;
-+	}
-+
-+	/* suspend the device */
-+	r = dm_suspend(md);
-+	if (r) {
-+		DMWARN("suspend failed");
-+		dm_table_put(t);
-+		dm_put(md);
-+		return r;
-+	}
-+	/* swap in the table */
-+	r = dm_swap_table(md, t);
-+	if (r) {
-+		DMWARN("table swap failed");
-+		dm_table_put(t);
-+		dm_put(md);
-+		return r;
-+	}
-+
-+	/* resume the device */
-+	r = dm_resume(md);
-+	if (r) {
-+		DMWARN("resume failed");
-+		dm_table_put(t);
-+		dm_put(md);
-+		return r;
-+	}
-+
-+	dm_table_put(t);	/* md will have grabbed its own reference */
-+
-+	set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
-+	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
-+	dm_put(md);
-+
-+	return r ? r : info(param, user);
-+}
-+
-+/*
-+ * Build up the status struct for each target
-+ */
-+static int __status(struct mapped_device *md, struct dm_ioctl *param,
-+		    char *outbuf, size_t *len)
-+{
-+	unsigned int i, num_targets;
-+	struct dm_target_spec *spec;
-+	char *outptr;
-+	status_type_t type;
-+	struct dm_table *table = dm_get_table(md);
-+
-+	if (param->flags & DM_STATUS_TABLE_FLAG)
-+		type = STATUSTYPE_TABLE;
-+	else
-+		type = STATUSTYPE_INFO;
-+
-+	outptr = outbuf;
-+
-+	/* Get all the target info */
-+	num_targets = dm_table_get_num_targets(table);
-+	for (i = 0; i < num_targets; i++) {
-+		struct dm_target *ti = dm_table_get_target(table, i);
-+
-+		if (outptr - outbuf +
-+		    sizeof(struct dm_target_spec) > param->data_size) {
-+			dm_table_put(table);
-+			return -ENOMEM;
-+		}
-+
-+		spec = (struct dm_target_spec *) outptr;
-+
-+		spec->status = 0;
-+		spec->sector_start = ti->begin;
-+		spec->length = ti->len;
-+		strlcpy(spec->target_type, ti->type->name,
-+			sizeof(spec->target_type));
-+
-+		outptr += sizeof(struct dm_target_spec);
-+
-+		/* Get the status/table string from the target driver */
-+		if (ti->type->status)
-+			ti->type->status(ti, type, outptr,
-+					 outbuf + param->data_size - outptr);
-+		else
-+			outptr[0] = '\0';
-+
-+		outptr += strlen(outptr) + 1;
-+		_align(outptr, ALIGNMENT);
-+		spec->next = outptr - outbuf;
-+	}
-+
-+	param->target_count = num_targets;
-+	*len = outptr - outbuf;
-+	dm_table_put(table);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Return the status of a device as a text string for each
-+ * target.
-+ */
-+static int get_status(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	struct mapped_device *md;
-+	size_t len = 0;
-+	int ret;
-+	char *outbuf = NULL;
-+
-+	md = find_device(param);
-+	if (!md)
-+		/*
-+		 * Device not found - returns cleared exists flag.
-+		 */
-+		goto out;
-+
-+	/* We haven't a clue how long the resultant data will be so
-+	   just allocate as much as userland has allowed us and make sure
-+	   we don't overun it */
-+	outbuf = kmalloc(param->data_size, GFP_KERNEL);
-+	if (!outbuf)
-+		goto out;
-+	/*
-+	 * Get the status of all targets
-+	 */
-+	__status(md, param, outbuf, &len);
-+
-+	/*
-+	 * Setup the basic dm_ioctl structure.
-+	 */
-+	__info(md, param);
-+
-+      out:
-+	if (md)
-+		dm_put(md);
-+
-+	ret = results_to_user(user, param, outbuf, len);
-+
-+	if (outbuf)
-+		kfree(outbuf);
-+
-+	return ret;
-+}
-+
-+/*
-+ * Wait for a device to report an event
-+ */
-+static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	struct mapped_device *md;
-+	DECLARE_WAITQUEUE(wq, current);
-+
-+	md = find_device(param);
-+	if (!md)
-+		/*
-+		 * Device not found - returns cleared exists flag.
-+		 */
-+		goto out;
-+
-+	/*
-+	 * Setup the basic dm_ioctl structure.
-+	 */
-+	__info(md, param);
-+
-+	/*
-+	 * Wait for a notification event
-+	 */
-+	set_current_state(TASK_INTERRUPTIBLE);
-+ 	if (!dm_add_wait_queue(md, &wq, dm_get_event_nr(md))) {
-+ 		schedule();
-+ 		dm_remove_wait_queue(md, &wq);
-+ 	}
-+  	set_current_state(TASK_RUNNING);
-+ 	dm_put(md);
-+
-+      out:
-+	return results_to_user(user, param, NULL, 0);
-+}
-+
-+/*
-+ * Retrieves a list of devices used by a particular dm device.
-+ */
-+static int dep(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	int r;
-+	unsigned int count;
-+	struct mapped_device *md;
-+	struct list_head *tmp;
-+	size_t len = 0;
-+	struct dm_target_deps *deps = NULL;
-+	struct dm_table *table;
-+
-+	md = find_device(param);
-+	if (!md)
-+		goto out;
-+	table = dm_get_table(md);
-+
-+	/*
-+	 * Setup the basic dm_ioctl structure.
-+	 */
-+	__info(md, param);
-+
-+	/*
-+	 * Count the devices.
-+	 */
-+	count = 0;
-+	list_for_each(tmp, dm_table_get_devices(table))
-+	    count++;
-+
-+	/*
-+	 * Allocate a kernel space version of the dm_target_status
-+	 * struct.
-+	 */
-+	if (array_too_big(sizeof(*deps), sizeof(*deps->dev), count)) {
-+		dm_table_put(table);
-+		dm_put(md);
-+		return -ENOMEM;
-+	}
-+
-+	len = sizeof(*deps) + (sizeof(*deps->dev) * count);
-+	deps = kmalloc(len, GFP_KERNEL);
-+	if (!deps) {
-+		dm_table_put(table);
-+		dm_put(md);
-+		return -ENOMEM;
-+	}
-+
-+	/*
-+	 * Fill in the devices.
-+	 */
-+	deps->count = count;
-+	count = 0;
-+	list_for_each(tmp, dm_table_get_devices(table)) {
-+		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
-+		deps->dev[count++] = dd->bdev->bd_dev;
-+	}
-+	dm_table_put(table);
-+	dm_put(md);
-+
-+      out:
-+	r = results_to_user(user, param, deps, len);
-+
-+	kfree(deps);
-+	return r;
-+}
-+
-+static int remove(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	struct hash_cell *hc;
-+
-+	down_write(&_hash_lock);
-+	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
-+		__get_name_cell(param->name);
-+	if (!hc) {
-+		DMWARN("device doesn't appear to be in the dev hash table.");
-+		up_write(&_hash_lock);
-+		return -EINVAL;
-+	}
-+
-+	/*
-+	 * You may ask the interface to drop its reference to an
-+	 * in use device.  This is no different to unlinking a
-+	 * file that someone still has open.  The device will not
-+	 * actually be destroyed until the last opener closes it.
-+	 * The name and uuid of the device (both are interface
-+	 * properties) will be available for reuse immediately.
-+	 *
-+	 * You don't want to drop a _suspended_ device from the
-+	 * interface, since that will leave you with no way of
-+	 * resuming it.
-+	 */
-+	if (dm_suspended(hc->md)) {
-+		DMWARN("refusing to remove a suspended device.");
-+		up_write(&_hash_lock);
-+		return -EPERM;
-+	}
-+
-+	__hash_remove(hc);
-+	up_write(&_hash_lock);
-+	return 0;
-+}
-+
-+static int remove_all(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	dm_hash_remove_all();
-+	return 0;
-+}
-+
-+static int suspend(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	int r;
-+	struct mapped_device *md;
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	if (param->flags & DM_SUSPEND_FLAG)
-+		r = dm_suspend(md);
-+	else
-+		r = dm_resume(md);
-+
-+	dm_put(md);
-+	return r;
-+}
-+
-+static int reload(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	int r;
-+	struct mapped_device *md;
-+	struct dm_table *t;
-+
-+	r = dm_table_create(&t, get_mode(param));
-+	if (r)
-+		return r;
-+
-+	r = populate_table(t, param);
-+	if (r) {
-+		dm_table_put(t);
-+		return r;
-+	}
-+
-+	md = find_device(param);
-+	if (!md) {
-+		dm_table_put(t);
-+		return -ENXIO;
-+	}
-+
-+	r = dm_swap_table(md, t);
-+	if (r) {
-+		dm_put(md);
-+		dm_table_put(t);
-+		return r;
-+	}
-+	dm_table_put(t);	/* md will have taken its own reference */
-+
-+	set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0);
-+	dm_put(md);
-+
-+	r = info(param, user);
-+	return r;
-+}
-+
-+static int rename(struct dm_ioctl *param, struct dm_ioctl *user)
-+{
-+	int r;
-+	char *new_name = (char *) param + param->data_start;
-+
-+	if (valid_str(new_name, (void *) param,
-+		      (void *) param + param->data_size)) {
-+		DMWARN("Invalid new logical volume name supplied.");
-+		return -EINVAL;
-+	}
-+
-+	r = check_name(new_name);
-+	if (r)
-+		return r;
-+
-+	return dm_hash_rename(param->name, new_name);
-+}
-+
-+
-+/*-----------------------------------------------------------------
-+ * Implementation of open/close/ioctl on the special char
-+ * device.
-+ *---------------------------------------------------------------*/
-+static ioctl_fn lookup_ioctl(unsigned int cmd)
-+{
-+	static struct {
-+		int cmd;
-+		ioctl_fn fn;
-+	} _ioctls[] = {
-+		{DM_VERSION_CMD, NULL},	/* version is dealt with elsewhere */
-+		{DM_REMOVE_ALL_CMD, remove_all},
-+		{DM_DEV_CREATE_CMD, create},
-+		{DM_DEV_REMOVE_CMD, remove},
-+		{DM_DEV_RELOAD_CMD, reload},
-+		{DM_DEV_RENAME_CMD, rename},
-+		{DM_DEV_SUSPEND_CMD, suspend},
-+		{DM_DEV_DEPS_CMD, dep},
-+		{DM_DEV_STATUS_CMD, info},
-+		{DM_TARGET_STATUS_CMD, get_status},
-+		{DM_TARGET_WAIT_CMD, wait_device_event},
-+	};
-+
-+	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
-+}
-+
-+/*
-+ * As well as checking the version compatibility this always
-+ * copies the kernel interface version out.
-+ */
-+static int check_version(unsigned int cmd, struct dm_ioctl *user)
-+{
-+	uint32_t version[3];
-+	int r = 0;
-+
-+	if (copy_from_user(version, user->version, sizeof(version)))
-+		return -EFAULT;
-+
-+	if ((DM_VERSION_MAJOR != version[0]) ||
-+	    (DM_VERSION_MINOR < version[1])) {
-+		DMWARN("ioctl interface mismatch: "
-+		       "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
-+		       DM_VERSION_MAJOR, DM_VERSION_MINOR,
-+		       DM_VERSION_PATCHLEVEL,
-+		       version[0], version[1], version[2], cmd);
-+		r = -EINVAL;
-+	}
-+
-+	/*
-+	 * Fill in the kernel version.
-+	 */
-+	version[0] = DM_VERSION_MAJOR;
-+	version[1] = DM_VERSION_MINOR;
-+	version[2] = DM_VERSION_PATCHLEVEL;
-+	if (copy_to_user(user->version, version, sizeof(version)))
-+		return -EFAULT;
-+
-+	return r;
-+}
-+
-+static void free_params(struct dm_ioctl *param)
-+{
-+	vfree(param);
-+}
-+
-+static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
-+{
-+	struct dm_ioctl tmp, *dmi;
-+
-+	if (copy_from_user(&tmp, user, sizeof(tmp)))
-+		return -EFAULT;
-+
-+	if (tmp.data_size < sizeof(tmp))
-+		return -EINVAL;
-+
-+	dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
-+	if (!dmi)
-+		return -ENOMEM;
-+
-+	if (copy_from_user(dmi, user, tmp.data_size)) {
-+		vfree(dmi);
-+		return -EFAULT;
-+	}
-+
-+	*param = dmi;
-+	return 0;
-+}
-+
-+static int validate_params(uint cmd, struct dm_ioctl *param)
-+{
-+	/* Ignores parameters */
-+	if (cmd == DM_REMOVE_ALL_CMD)
-+		return 0;
-+
-+	/* Unless creating, either name of uuid but not both */
-+	if (cmd != DM_DEV_CREATE_CMD) {
-+		if ((!*param->uuid && !*param->name) ||
-+		    (*param->uuid && *param->name)) {
-+			DMWARN("one of name or uuid must be supplied");
-+			return -EINVAL;
-+		}
-+	}
-+
-+	/* Ensure strings are terminated */
-+	param->name[DM_NAME_LEN - 1] = '\0';
-+	param->uuid[DM_UUID_LEN - 1] = '\0';
-+
-+	return 0;
-+}
-+
-+static int ctl_ioctl(struct inode *inode, struct file *file,
-+		     uint command, ulong u)
-+{
-+	int r = 0;
-+	unsigned int cmd;
-+	struct dm_ioctl *param;
-+	struct dm_ioctl *user = (struct dm_ioctl *) u;
-+	ioctl_fn fn = NULL;
-+
-+	/* only root can play with this */
-+	if (!capable(CAP_SYS_ADMIN))
-+		return -EACCES;
-+
-+	if (_IOC_TYPE(command) != DM_IOCTL)
-+		return -ENOTTY;
-+
-+	cmd = _IOC_NR(command);
-+
-+	/*
-+	 * Check the interface version passed in.  This also
-+	 * writes out the kernels interface version.
-+	 */
-+	r = check_version(cmd, user);
-+	if (r)
-+		return r;
-+
-+	/*
-+	 * Nothing more to do for the version command.
-+	 */
-+	if (cmd == DM_VERSION_CMD)
-+		return 0;
-+
-+	fn = lookup_ioctl(cmd);
-+	if (!fn) {
-+		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
-+		return -ENOTTY;
-+	}
-+
-+	/*
-+	 * Copy the parameters into kernel space.
-+	 */
-+	r = copy_params(user, &param);
-+	if (r)
-+		return r;
-+
-+	r = validate_params(cmd, param);
-+	if (r) {
-+		free_params(param);
-+		return r;
-+	}
-+
-+	r = fn(param, user);
-+	free_params(param);
-+	return r;
-+}
-+
-+static struct file_operations _ctl_fops = {
-+	.ioctl	 = ctl_ioctl,
-+	.owner	 = THIS_MODULE,
-+};
-+
-+static struct miscdevice _dm_misc = {
-+	.minor		= MISC_DYNAMIC_MINOR,
-+	.name		= DM_NAME,
-+	.devfs_name	= "mapper/control",
-+	.fops		= &_ctl_fops
-+};
-+
-+/*
-+ * Create misc character device and link to DM_DIR/control.
-+ */
-+int __init dm_interface_init(void)
-+{
-+	int r;
-+
-+	r = dm_hash_init();
-+	if (r)
-+		return r;
-+
-+	r = misc_register(&_dm_misc);
-+	if (r) {
-+		DMERR("misc_register failed for control device");
-+		dm_hash_exit();
-+		return r;
-+	}
-+
-+	DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
-+	       DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
-+	       DM_DRIVER_EMAIL);
-+	return 0;
-+
-+	if (misc_deregister(&_dm_misc) < 0)
-+		DMERR("misc_deregister failed for control device");
-+	dm_hash_exit();
-+	return r;
-+}
-+
-+void dm_interface_exit(void)
-+{
-+	if (misc_deregister(&_dm_misc) < 0)
-+		DMERR("misc_deregister failed for control device");
-+	dm_hash_exit();
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/md/dm-ioctl-v4.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,1252 @@
-+/*
-+ * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
-+ *
-+ * This file is released under the GPL.
-+ */
-+
-+#include "dm.h"
-+
-+#include <linux/module.h>
-+#include <linux/vmalloc.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/blk.h>
-+#include <linux/slab.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#include <asm/uaccess.h>
-+
-+#define DM_DRIVER_EMAIL "dm@uk.sistina.com"
-+
-+/*-----------------------------------------------------------------
-+ * The ioctl interface needs to be able to look up devices by
-+ * name or uuid.
-+ *---------------------------------------------------------------*/
-+struct hash_cell {
-+	struct list_head name_list;
-+	struct list_head uuid_list;
-+
-+	char *name;
-+	char *uuid;
-+	struct mapped_device *md;
-+	struct dm_table *new_map;
-+};
-+
-+#define NUM_BUCKETS 64
-+#define MASK_BUCKETS (NUM_BUCKETS - 1)
-+static struct list_head _name_buckets[NUM_BUCKETS];
-+static struct list_head _uuid_buckets[NUM_BUCKETS];
-+
-+void dm_hash_remove_all(void);
-+
-+/*
-+ * Guards access to both hash tables.
-+ */
-+static DECLARE_RWSEM(_hash_lock);
-+
-+static void init_buckets(struct list_head *buckets)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i < NUM_BUCKETS; i++)
-+		INIT_LIST_HEAD(buckets + i);
-+}
-+
-+int dm_hash_init(void)
-+{
-+	init_buckets(_name_buckets);
-+	init_buckets(_uuid_buckets);
-+	devfs_mk_dir(DM_DIR);
-+	return 0;
-+}
-+
-+void dm_hash_exit(void)
-+{
-+	dm_hash_remove_all();
-+	devfs_remove(DM_DIR);
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Hash function:
-+ * We're not really concerned with the str hash function being
-+ * fast since it's only used by the ioctl interface.
-+ *---------------------------------------------------------------*/
-+static unsigned int hash_str(const char *str)
-+{
-+	const unsigned int hash_mult = 2654435387U;
-+	unsigned int h = 0;
-+
-+	while (*str)
-+		h = (h + (unsigned int) *str++) * hash_mult;
-+
-+	return h & MASK_BUCKETS;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Code for looking up a device by name
-+ *---------------------------------------------------------------*/
-+static struct hash_cell *__get_name_cell(const char *str)
-+{
-+	struct list_head *tmp;
-+	struct hash_cell *hc;
-+	unsigned int h = hash_str(str);
-+
-+	list_for_each (tmp, _name_buckets + h) {
-+		hc = list_entry(tmp, struct hash_cell, name_list);
-+		if (!strcmp(hc->name, str))
-+			return hc;
-+	}
-+
-+	return NULL;
-+}
-+
-+static struct hash_cell *__get_uuid_cell(const char *str)
-+{
-+	struct list_head *tmp;
-+	struct hash_cell *hc;
-+	unsigned int h = hash_str(str);
-+
-+	list_for_each (tmp, _uuid_buckets + h) {
-+		hc = list_entry(tmp, struct hash_cell, uuid_list);
-+		if (!strcmp(hc->uuid, str))
-+			return hc;
-+	}
-+
-+	return NULL;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Inserting, removing and renaming a device.
-+ *---------------------------------------------------------------*/
-+static inline char *kstrdup(const char *str)
-+{
-+	char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
-+	if (r)
-+		strcpy(r, str);
-+	return r;
-+}
-+
-+static struct hash_cell *alloc_cell(const char *name, const char *uuid,
-+				    struct mapped_device *md)
-+{
-+	struct hash_cell *hc;
-+
-+	hc = kmalloc(sizeof(*hc), GFP_KERNEL);
-+	if (!hc)
-+		return NULL;
-+
-+	hc->name = kstrdup(name);
-+	if (!hc->name) {
-+		kfree(hc);
-+		return NULL;
-+	}
-+
-+	if (!uuid)
-+		hc->uuid = NULL;
-+
-+	else {
-+		hc->uuid = kstrdup(uuid);
-+		if (!hc->uuid) {
-+			kfree(hc->name);
-+			kfree(hc);
-+			return NULL;
-+		}
-+	}
-+
-+	INIT_LIST_HEAD(&hc->name_list);
-+	INIT_LIST_HEAD(&hc->uuid_list);
-+	hc->md = md;
-+	hc->new_map = NULL;
-+	return hc;
-+}
-+
-+static void free_cell(struct hash_cell *hc)
-+{
-+	if (hc) {
-+		kfree(hc->name);
-+		kfree(hc->uuid);
-+		kfree(hc);
-+	}
-+}
-+
-+/*
-+ * devfs stuff.
-+ */
-+static int register_with_devfs(struct hash_cell *hc)
-+{
-+	struct gendisk *disk = dm_disk(hc->md);
-+
-+	devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
-+		      S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
-+		      DM_DIR "/%s", hc->name);
-+	return 0;
-+}
-+
-+static int unregister_with_devfs(struct hash_cell *hc)
-+{
-+	devfs_remove(DM_DIR"/%s", hc->name);
-+	return 0;
-+}
-+
-+/*
-+ * The kdev_t and uuid of a device can never change once it is
-+ * initially inserted.
-+ */
-+int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
-+{
-+	struct hash_cell *cell;
-+
-+	/*
-+	 * Allocate the new cells.
-+	 */
-+	cell = alloc_cell(name, uuid, md);
-+	if (!cell)
-+		return -ENOMEM;
-+
-+	/*
-+	 * Insert the cell into both hash tables.
-+	 */
-+	down_write(&_hash_lock);
-+	if (__get_name_cell(name))
-+		goto bad;
-+
-+	list_add(&cell->name_list, _name_buckets + hash_str(name));
-+
-+	if (uuid) {
-+		if (__get_uuid_cell(uuid)) {
-+			list_del(&cell->name_list);
-+			goto bad;
-+		}
-+		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
-+	}
-+	register_with_devfs(cell);
-+	dm_get(md);
-+	up_write(&_hash_lock);
-+
-+	return 0;
-+
-+ bad:
-+	up_write(&_hash_lock);
-+	free_cell(cell);
-+	return -EBUSY;
-+}
-+
-+void __hash_remove(struct hash_cell *hc)
-+{
-+	/* remove from the dev hash */
-+	list_del(&hc->uuid_list);
-+	list_del(&hc->name_list);
-+	unregister_with_devfs(hc);
-+	dm_put(hc->md);
-+	if (hc->new_map)
-+		dm_table_put(hc->new_map);
-+	free_cell(hc);
-+}
-+
-+void dm_hash_remove_all(void)
-+{
-+	int i;
-+	struct hash_cell *hc;
-+	struct list_head *tmp, *n;
-+
-+	down_write(&_hash_lock);
-+	for (i = 0; i < NUM_BUCKETS; i++) {
-+		list_for_each_safe (tmp, n, _name_buckets + i) {
-+			hc = list_entry(tmp, struct hash_cell, name_list);
-+			__hash_remove(hc);
-+		}
-+	}
-+	up_write(&_hash_lock);
-+}
-+
-+int dm_hash_rename(const char *old, const char *new)
-+{
-+	char *new_name, *old_name;
-+	struct hash_cell *hc;
-+
-+	/*
-+	 * duplicate new.
-+	 */
-+	new_name = kstrdup(new);
-+	if (!new_name)
-+		return -ENOMEM;
-+
-+	down_write(&_hash_lock);
-+
-+	/*
-+	 * Is new free ?
-+	 */
-+	hc = __get_name_cell(new);
-+	if (hc) {
-+		DMWARN("asked to rename to an already existing name %s -> %s",
-+		       old, new);
-+		up_write(&_hash_lock);
-+		kfree(new_name);
-+		return -EBUSY;
-+	}
-+
-+	/*
-+	 * Is there such a device as 'old' ?
-+	 */
-+	hc = __get_name_cell(old);
-+	if (!hc) {
-+		DMWARN("asked to rename a non existent device %s -> %s",
-+		       old, new);
-+		up_write(&_hash_lock);
-+		kfree(new_name);
-+		return -ENXIO;
-+	}
-+
-+	/*
-+	 * rename and move the name cell.
-+	 */
-+	unregister_with_devfs(hc);
-+
-+	list_del(&hc->name_list);
-+	old_name = hc->name;
-+	hc->name = new_name;
-+	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
-+
-+	/* rename the device node in devfs */
-+	register_with_devfs(hc);
-+
-+	up_write(&_hash_lock);
-+	kfree(old_name);
-+	return 0;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Implementation of the ioctl commands
-+ *---------------------------------------------------------------*/
-+/*
-+ * All the ioctl commands get dispatched to functions with this
-+ * prototype.
-+ */
-+typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size);
-+
-+static int remove_all(struct dm_ioctl *param, size_t param_size)
-+{
-+	dm_hash_remove_all();
-+	param->data_size = 0;
-+	return 0;
-+}
-+
-+/*
-+ * Round up the ptr to an 8-byte boundary.
-+ */
-+#define ALIGN_MASK 7
-+static inline void *align_ptr(void *ptr)
-+{
-+	return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK);
-+}
-+
-+/*
-+ * Retrieves the data payload buffer from an already allocated
-+ * struct dm_ioctl.
-+ */
-+static void *get_result_buffer(struct dm_ioctl *param, size_t param_size,
-+			       size_t *len)
-+{
-+	param->data_start = align_ptr(param + 1) - (void *) param;
-+
-+	if (param->data_start < param_size)
-+		*len = param_size - param->data_start;
-+	else
-+		*len = 0;
-+
-+	return ((void *) param) + param->data_start;
-+}
-+
-+static int list_devices(struct dm_ioctl *param, size_t param_size)
-+{
-+	unsigned int i;
-+	struct hash_cell *hc;
-+	size_t len, needed = 0;
-+	struct gendisk *disk;
-+	struct dm_name_list *nl, *old_nl = NULL;
-+
-+	down_write(&_hash_lock);
-+
-+	/*
-+	 * Loop through all the devices working out how much
-+	 * space we need.
-+	 */
-+	for (i = 0; i < NUM_BUCKETS; i++) {
-+		list_for_each_entry (hc, _name_buckets + i, name_list) {
-+			needed += sizeof(struct dm_name_list);
-+			needed += strlen(hc->name);
-+			needed += ALIGN_MASK;
-+		}
-+	}
-+
-+	/*
-+	 * Grab our output buffer.
-+	 */
-+	nl = get_result_buffer(param, param_size, &len);
-+	if (len < needed) {
-+		param->flags |= DM_BUFFER_FULL_FLAG;
-+		goto out;
-+	}
-+	param->data_size = param->data_start + needed;
-+
-+	nl->dev = 0;	/* Flags no data */
-+
-+	/*
-+	 * Now loop through filling out the names.
-+	 */
-+	for (i = 0; i < NUM_BUCKETS; i++) {
-+		list_for_each_entry (hc, _name_buckets + i, name_list) {
-+			if (old_nl)
-+				old_nl->next = (uint32_t) ((void *) nl -
-+							   (void *) old_nl);
-+			disk = dm_disk(hc->md);
-+			nl->dev = MKDEV(disk->major, disk->first_minor);
-+			nl->next = 0;
-+			strcpy(nl->name, hc->name);
-+
-+			old_nl = nl;
-+			nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1);
-+		}
-+	}
-+
-+ out:
-+	up_write(&_hash_lock);
-+	return 0;
-+}
-+
-+static int check_name(const char *name)
-+{
-+	if (strchr(name, '/')) {
-+		DMWARN("invalid device name");
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+/*
-+ * Fills in a dm_ioctl structure, ready for sending back to
-+ * userland.
-+ */
-+static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
-+{
-+	struct gendisk *disk = dm_disk(md);
-+	struct dm_table *table;
-+	struct block_device *bdev;
-+
-+	param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG |
-+			  DM_ACTIVE_PRESENT_FLAG);
-+
-+	if (dm_suspended(md))
-+		param->flags |= DM_SUSPEND_FLAG;
-+
-+	bdev = bdget_disk(disk, 0);
-+	if (!bdev)
-+		return -ENXIO;
-+
-+	param->dev = MKDEV(disk->major, disk->first_minor);
-+
-+	/*
-+	 * Yes, this will be out of date by the time it gets back
-+	 * to userland, but it is still very useful ofr
-+	 * debugging.
-+	 */
-+	param->open_count = bdev->bd_openers;
-+	bdput(bdev);
-+
-+	if (disk->policy)
-+		param->flags |= DM_READONLY_FLAG;
-+
-+	param->event_nr = dm_get_event_nr(md);
-+
-+	table = dm_get_table(md);
-+	if (table) {
-+		param->flags |= DM_ACTIVE_PRESENT_FLAG;
-+		param->target_count = dm_table_get_num_targets(table);
-+		dm_table_put(table);
-+	} else
-+		param->target_count = 0;
-+
-+	return 0;
-+}
-+
-+static int dev_create(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct mapped_device *md;
-+
-+	r = check_name(param->name);
-+	if (r)
-+		return r;
-+
-+	if (param->flags & DM_PERSISTENT_DEV_FLAG)
-+		r = dm_create_with_minor(minor(to_kdev_t(param->dev)), &md);
-+	else
-+		r = dm_create(&md);
-+
-+	if (r)
-+		return r;
-+
-+	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
-+	if (r) {
-+		dm_put(md);
-+		return r;
-+	}
-+
-+	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-+
-+	r = __dev_status(md, param);
-+	dm_put(md);
-+
-+	return r;
-+}
-+
-+/*
-+ * Always use UUID for lookups if it's present, otherwise use name.
-+ */
-+static inline struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
-+{
-+	return *param->uuid ?
-+	    __get_uuid_cell(param->uuid) : __get_name_cell(param->name);
-+}
-+
-+static inline struct mapped_device *find_device(struct dm_ioctl *param)
-+{
-+	struct hash_cell *hc;
-+	struct mapped_device *md = NULL;
-+
-+	down_read(&_hash_lock);
-+	hc = __find_device_hash_cell(param);
-+	if (hc) {
-+		md = hc->md;
-+
-+		/*
-+		 * Sneakily write in both the name and the uuid
-+		 * while we have the cell.
-+		 */
-+		strncpy(param->name, hc->name, sizeof(param->name));
-+		if (hc->uuid)
-+			strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1);
-+		else
-+			param->uuid[0] = '\0';
-+
-+		if (hc->new_map)
-+			param->flags |= DM_INACTIVE_PRESENT_FLAG;
-+		else
-+			param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-+
-+		dm_get(md);
-+	}
-+	up_read(&_hash_lock);
-+
-+	return md;
-+}
-+
-+static int dev_remove(struct dm_ioctl *param, size_t param_size)
-+{
-+	struct hash_cell *hc;
-+
-+	down_write(&_hash_lock);
-+	hc = __find_device_hash_cell(param);
-+
-+	if (!hc) {
-+		DMWARN("device doesn't appear to be in the dev hash table.");
-+		up_write(&_hash_lock);
-+		return -ENXIO;
-+	}
-+
-+	__hash_remove(hc);
-+	up_write(&_hash_lock);
-+	param->data_size = 0;
-+	return 0;
-+}
-+
-+/*
-+ * Check a string doesn't overrun the chunk of
-+ * memory we copied from userland.
-+ */
-+static int invalid_str(char *str, void *end)
-+{
-+	while ((void *) str < end)
-+		if (!*str++)
-+			return 0;
-+
-+	return -EINVAL;
-+}
-+
-+static int dev_rename(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	char *new_name = (char *) param + param->data_start;
-+
-+	if (new_name < (char *) (param + 1) ||
-+	    invalid_str(new_name, (void *) param + param_size)) {
-+		DMWARN("Invalid new logical volume name supplied.");
-+		return -EINVAL;
-+	}
-+
-+	r = check_name(new_name);
-+	if (r)
-+		return r;
-+
-+	param->data_size = 0;
-+	return dm_hash_rename(param->name, new_name);
-+}
-+
-+static int suspend(struct dm_ioctl *param)
-+{
-+	int r = 0;
-+	struct mapped_device *md;
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	if (!dm_suspended(md))
-+		r = dm_suspend(md);
-+
-+	if (!r)
-+		r = __dev_status(md, param);
-+
-+	dm_put(md);
-+	return r;
-+}
-+
-+static int resume(struct dm_ioctl *param)
-+{
-+	int r = 0;
-+	struct hash_cell *hc;
-+	struct mapped_device *md;
-+	struct dm_table *new_map;
-+
-+	down_write(&_hash_lock);
-+
-+	hc = __find_device_hash_cell(param);
-+	if (!hc) {
-+		DMWARN("device doesn't appear to be in the dev hash table.");
-+		up_write(&_hash_lock);
-+		return -ENXIO;
-+	}
-+
-+	md = hc->md;
-+	dm_get(md);
-+
-+	new_map = hc->new_map;
-+	hc->new_map = NULL;
-+	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-+
-+	up_write(&_hash_lock);
-+
-+	/* Do we need to load a new map ? */
-+	if (new_map) {
-+		/* Suspend if it isn't already suspended */
-+		if (!dm_suspended(md))
-+			dm_suspend(md);
-+
-+		r = dm_swap_table(md, new_map);
-+		if (r) {
-+			dm_put(md);
-+			dm_table_put(new_map);
-+			return r;
-+		}
-+
-+		if (dm_table_get_mode(new_map) & FMODE_WRITE)
-+			set_disk_ro(dm_disk(md), 0);
-+		else
-+			set_disk_ro(dm_disk(md), 1);
-+
-+		dm_table_put(new_map);
-+	}
-+
-+	if (dm_suspended(md))
-+		r = dm_resume(md);
-+
-+	if (!r)
-+		r = __dev_status(md, param);
-+
-+	dm_put(md);
-+	return r;
-+}
-+
-+/*
-+ * Set or unset the suspension state of a device.
-+ * If the device already is in the requested state we just return its status.
-+ */
-+static int dev_suspend(struct dm_ioctl *param, size_t param_size)
-+{
-+	if (param->flags & DM_SUSPEND_FLAG)
-+		return suspend(param);
-+
-+	return resume(param);
-+}
-+
-+/*
-+ * Copies device info back to user space, used by
-+ * the create and info ioctls.
-+ */
-+static int dev_status(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct mapped_device *md;
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	r = __dev_status(md, param);
-+	dm_put(md);
-+	return r;
-+}
-+
-+/*
-+ * Wait for a device to report an event
-+ */
-+static int dev_wait(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct mapped_device *md;
-+	DECLARE_WAITQUEUE(wq, current);
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	/*
-+	 * Wait for a notification event
-+	 */
-+	set_current_state(TASK_INTERRUPTIBLE);
-+	if (!dm_add_wait_queue(md, &wq, param->event_nr)) {
-+		schedule();
-+		dm_remove_wait_queue(md, &wq);
-+	}
-+ 	set_current_state(TASK_RUNNING);
-+
-+	/*
-+	 * The userland program is going to want to know what
-+	 * changed to trigger the event, so we may as well tell
-+	 * him and save an ioctl.
-+	 */
-+	r = __dev_status(md, param);
-+
-+	dm_put(md);
-+	return r;
-+}
-+
-+static inline int get_mode(struct dm_ioctl *param)
-+{
-+	int mode = FMODE_READ | FMODE_WRITE;
-+
-+	if (param->flags & DM_READONLY_FLAG)
-+		mode = FMODE_READ;
-+
-+	return mode;
-+}
-+
-+static int next_target(struct dm_target_spec *last, uint32_t next, void *end,
-+		       struct dm_target_spec **spec, char **target_params)
-+{
-+	*spec = (struct dm_target_spec *) ((unsigned char *) last + next);
-+	*target_params = (char *) (*spec + 1);
-+
-+	if (*spec < (last + 1))
-+		return -EINVAL;
-+
-+	return invalid_str(*target_params, end);
-+}
-+
-+static int populate_table(struct dm_table *table,
-+			  struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	unsigned int i = 0;
-+	struct dm_target_spec *spec = (struct dm_target_spec *) param;
-+	uint32_t next = param->data_start;
-+	void *end = (void *) param + param_size;
-+	char *target_params;
-+
-+	if (!param->target_count) {
-+		DMWARN("populate_table: no targets specified");
-+		return -EINVAL;
-+	}
-+
-+	for (i = 0; i < param->target_count; i++) {
-+
-+		r = next_target(spec, next, end, &spec, &target_params);
-+		if (r) {
-+			DMWARN("unable to find target");
-+			return r;
-+		}
-+
-+		r = dm_table_add_target(table, spec->target_type,
-+					(sector_t) spec->sector_start,
-+					(sector_t) spec->length,
-+					target_params);
-+		if (r) {
-+			DMWARN("error adding target to table");
-+			return r;
-+		}
-+
-+		next = spec->next;
-+	}
-+
-+	return dm_table_complete(table);
-+}
-+
-+static int table_load(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct hash_cell *hc;
-+	struct dm_table *t;
-+
-+	r = dm_table_create(&t, get_mode(param));
-+	if (r)
-+		return r;
-+
-+	r = populate_table(t, param, param_size);
-+	if (r) {
-+		dm_table_put(t);
-+		return r;
-+	}
-+
-+	down_write(&_hash_lock);
-+	hc = __find_device_hash_cell(param);
-+	if (!hc) {
-+		DMWARN("device doesn't appear to be in the dev hash table.");
-+		up_write(&_hash_lock);
-+		return -ENXIO;
-+	}
-+
-+	hc->new_map = t;
-+	param->flags |= DM_INACTIVE_PRESENT_FLAG;
-+
-+	r = __dev_status(hc->md, param);
-+	up_write(&_hash_lock);
-+	return r;
-+}
-+
-+static int table_clear(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct hash_cell *hc;
-+
-+	down_write(&_hash_lock);
-+
-+	hc = __find_device_hash_cell(param);
-+	if (!hc) {
-+		DMWARN("device doesn't appear to be in the dev hash table.");
-+		up_write(&_hash_lock);
-+		return -ENXIO;
-+	}
-+
-+	if (hc->new_map) {
-+		dm_table_put(hc->new_map);
-+		hc->new_map = NULL;
-+	}
-+
-+	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
-+
-+	r = __dev_status(hc->md, param);
-+	up_write(&_hash_lock);
-+	return r;
-+}
-+
-+/*
-+ * Retrieves a list of devices used by a particular dm device.
-+ */
-+static void retrieve_deps(struct dm_table *table,
-+			  struct dm_ioctl *param, size_t param_size)
-+{
-+	unsigned int count = 0;
-+	struct list_head *tmp;
-+	size_t len, needed;
-+	struct dm_target_deps *deps;
-+
-+	deps = get_result_buffer(param, param_size, &len);
-+
-+	/*
-+	 * Count the devices.
-+	 */
-+	list_for_each(tmp, dm_table_get_devices(table))
-+		count++;
-+
-+	/*
-+	 * Check we have enough space.
-+	 */
-+	needed = sizeof(*deps) + (sizeof(*deps->dev) * count);
-+	if (len < needed) {
-+		param->flags |= DM_BUFFER_FULL_FLAG;
-+		return;
-+	}
-+
-+	/*
-+	 * Fill in the devices.
-+	 */
-+	deps->count = count;
-+	count = 0;
-+	list_for_each(tmp, dm_table_get_devices(table)) {
-+		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
-+		deps->dev[count++] = dd->bdev->bd_dev;
-+	}
-+
-+	param->data_size = param->data_start + needed;
-+}
-+
-+static int table_deps(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r = 0;
-+	struct mapped_device *md;
-+	struct dm_table *table;
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	r = __dev_status(md, param);
-+	if (r)
-+		goto out;
-+
-+	table = dm_get_table(md);
-+	if (table) {
-+		retrieve_deps(table, param, param_size);
-+		dm_table_put(table);
-+	}
-+
-+ out:
-+	dm_put(md);
-+	return r;
-+}
-+
-+/*
-+ * Build up the status struct for each target
-+ */
-+static void retrieve_status(struct dm_table *table,
-+			    struct dm_ioctl *param, size_t param_size)
-+{
-+	unsigned int i, num_targets;
-+	struct dm_target_spec *spec;
-+	char *outbuf, *outptr;
-+	status_type_t type;
-+	size_t remaining, len, used = 0;
-+
-+	outptr = outbuf = get_result_buffer(param, param_size, &len);
-+
-+	if (param->flags & DM_STATUS_TABLE_FLAG)
-+		type = STATUSTYPE_TABLE;
-+	else
-+		type = STATUSTYPE_INFO;
-+
-+	/* Get all the target info */
-+	num_targets = dm_table_get_num_targets(table);
-+	for (i = 0; i < num_targets; i++) {
-+		struct dm_target *ti = dm_table_get_target(table, i);
-+
-+		remaining = len - (outptr - outbuf);
-+		if (remaining < sizeof(struct dm_target_spec)) {
-+			param->flags |= DM_BUFFER_FULL_FLAG;
-+			break;
-+		}
-+
-+		spec = (struct dm_target_spec *) outptr;
-+
-+		spec->status = 0;
-+		spec->sector_start = ti->begin;
-+		spec->length = ti->len;
-+		strncpy(spec->target_type, ti->type->name,
-+			sizeof(spec->target_type));
-+
-+		outptr += sizeof(struct dm_target_spec);
-+		remaining = len - (outptr - outbuf);
-+
-+		/* Get the status/table string from the target driver */
-+		if (ti->type->status) {
-+			if (ti->type->status(ti, type, outptr, remaining)) {
-+				param->flags |= DM_BUFFER_FULL_FLAG;
-+				break;
-+			}
-+		} else
-+			outptr[0] = '\0';
-+
-+		outptr += strlen(outptr) + 1;
-+		used = param->data_start + (outptr - outbuf);
-+
-+		align_ptr(outptr);
-+		spec->next = outptr - outbuf;
-+	}
-+
-+	if (used)
-+		param->data_size = used;
-+
-+	param->target_count = num_targets;
-+}
-+
-+/*
-+ * Return the status of a device as a text string for each
-+ * target.
-+ */
-+static int table_status(struct dm_ioctl *param, size_t param_size)
-+{
-+	int r;
-+	struct mapped_device *md;
-+	struct dm_table *table;
-+
-+	md = find_device(param);
-+	if (!md)
-+		return -ENXIO;
-+
-+	r = __dev_status(md, param);
-+	if (r)
-+		goto out;
-+
-+	table = dm_get_table(md);
-+	if (table) {
-+		retrieve_status(table, param, param_size);
-+		dm_table_put(table);
-+	}
-+
-+ out:
-+	dm_put(md);
-+	return r;
-+}
-+
-+/*-----------------------------------------------------------------
-+ * Implementation of open/close/ioctl on the special char
-+ * device.
-+ *---------------------------------------------------------------*/
-+static ioctl_fn lookup_ioctl(unsigned int cmd)
-+{
-+	static struct {
-+		int cmd;
-+		ioctl_fn fn;
-+	} _ioctls[] = {
-+		{DM_VERSION_CMD, NULL},	/* version is dealt with elsewhere */
-+		{DM_REMOVE_ALL_CMD, remove_all},
-+		{DM_LIST_DEVICES_CMD, list_devices},
-+
-+		{DM_DEV_CREATE_CMD, dev_create},
-+		{DM_DEV_REMOVE_CMD, dev_remove},
-+		{DM_DEV_RENAME_CMD, dev_rename},
-+		{DM_DEV_SUSPEND_CMD, dev_suspend},
-+		{DM_DEV_STATUS_CMD, dev_status},
-+		{DM_DEV_WAIT_CMD, dev_wait},
-+
-+		{DM_TABLE_LOAD_CMD, table_load},
-+		{DM_TABLE_CLEAR_CMD, table_clear},
-+		{DM_TABLE_DEPS_CMD, table_deps},
-+		{DM_TABLE_STATUS_CMD, table_status}
-+	};
-+
-+	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
-+}
-+
-+/*
-+ * As well as checking the version compatibility this always
-+ * copies the kernel interface version out.
-+ */
-+static int check_version(unsigned int cmd, struct dm_ioctl *user)
-+{
-+	uint32_t version[3];
-+	int r = 0;
-+
-+	if (copy_from_user(version, user->version, sizeof(version)))
-+		return -EFAULT;
-+
-+	if ((DM_VERSION_MAJOR != version[0]) ||
-+	    (DM_VERSION_MINOR < version[1])) {
-+		DMWARN("ioctl interface mismatch: "
-+		       "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
-+		       DM_VERSION_MAJOR, DM_VERSION_MINOR,
-+		       DM_VERSION_PATCHLEVEL,
-+		       version[0], version[1], version[2], cmd);
-+		r = -EINVAL;
-+	}
-+
-+	/*
-+	 * Fill in the kernel version.
-+	 */
-+	version[0] = DM_VERSION_MAJOR;
-+	version[1] = DM_VERSION_MINOR;
-+	version[2] = DM_VERSION_PATCHLEVEL;
-+	if (copy_to_user(user->version, version, sizeof(version)))
-+		return -EFAULT;
-+
-+	return r;
-+}
-+
-+static void free_params(struct dm_ioctl *param)
-+{
-+	vfree(param);
-+}
-+
-+static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
-+{
-+	struct dm_ioctl tmp, *dmi;
-+
-+	if (copy_from_user(&tmp, user, sizeof(tmp)))
-+		return -EFAULT;
-+
-+	if (tmp.data_size < sizeof(tmp))
-+		return -EINVAL;
-+
-+	dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
-+	if (!dmi)
-+		return -ENOMEM;
-+
-+	if (copy_from_user(dmi, user, tmp.data_size)) {
-+		vfree(dmi);
-+		return -EFAULT;
-+	}
-+
-+	*param = dmi;
-+	return 0;
-+}
-+
-+static int validate_params(uint cmd, struct dm_ioctl *param)
-+{
-+	/* Always clear this flag */
-+	param->flags &= ~DM_BUFFER_FULL_FLAG;
-+
-+	/* Ignores parameters */
-+	if (cmd == DM_REMOVE_ALL_CMD || cmd == DM_LIST_DEVICES_CMD)
-+		return 0;
-+
-+	/* Unless creating, either name or uuid but not both */
-+	if (cmd != DM_DEV_CREATE_CMD) {
-+		if ((!*param->uuid && !*param->name) ||
-+		    (*param->uuid && *param->name)) {
-+			DMWARN("one of name or uuid must be supplied, cmd(%u)",
-+			       cmd);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	/* Ensure strings are terminated */
-+	param->name[DM_NAME_LEN - 1] = '\0';
-+	param->uuid[DM_UUID_LEN - 1] = '\0';
-+
-+	return 0;
-+}
-+
-+static int ctl_ioctl(struct inode *inode, struct file *file,
-+		     uint command, ulong u)
-+{
-+	int r = 0;
-+	unsigned int cmd;
-+	struct dm_ioctl *param;
-+	struct dm_ioctl *user = (struct dm_ioctl *) u;
-+	ioctl_fn fn = NULL;
-+	size_t param_size;
-+
-+	/* only root can play with this */
-+	if (!capable(CAP_SYS_ADMIN))
-+		return -EACCES;
-+
-+	if (_IOC_TYPE(command) != DM_IOCTL)
-+		return -ENOTTY;
-+
-+	cmd = _IOC_NR(command);
-+
-+	/*
-+	 * Check the interface version passed in.  This also
-+	 * writes out the kernel's interface version.
-+	 */
-+	r = check_version(cmd, user);
-+	if (r)
-+		return r;
-+
-+	/*
-+	 * Nothing more to do for the version command.
-+	 */
-+	if (cmd == DM_VERSION_CMD)
-+		return 0;
-+
-+	fn = lookup_ioctl(cmd);
-+	if (!fn) {
-+		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
-+		return -ENOTTY;
-+	}
-+
-+	/*
-+	 * Trying to avoid low memory issues when a device is
-+	 * suspended.
-+	 */
-+	current->flags |= PF_MEMALLOC;
-+
-+	/*
-+	 * Copy the parameters into kernel space.
-+	 */
-+	r = copy_params(user, &param);
-+	if (r) {
-+		current->flags &= ~PF_MEMALLOC;
-+		return r;
-+	}
-+
-+	/*
-+	 * FIXME: eventually we will remove the PF_MEMALLOC flag
-+	 * here.  However the tools still do nasty things like
-+	 * 'load' while a device is suspended.
-+	 */
-+
-+	r = validate_params(cmd, param);
-+	if (r)
-+		goto out;
-+
-+	param_size = param->data_size;
-+	param->data_size = sizeof(*param);
-+	r = fn(param, param_size);
-+
-+	/*
-+	 * Copy the results back to userland.
-+	 */
-+	if (!r && copy_to_user(user, param, param->data_size))
-+		r = -EFAULT;
-+
-+ out:
-+	free_params(param);
-+	current->flags &= ~PF_MEMALLOC;
-+	return r;
-+}
-+
-+static struct file_operations _ctl_fops = {
-+	.ioctl	 = ctl_ioctl,
-+	.owner	 = THIS_MODULE,
-+};
-+
-+static struct miscdevice _dm_misc = {
-+	.minor 		= MISC_DYNAMIC_MINOR,
-+	.name  		= DM_NAME,
-+	.devfs_name 	= "mapper/control",
-+	.fops  		= &_ctl_fops
-+};
-+
-+/*
-+ * Create misc character device and link to DM_DIR/control.
-+ */
-+int __init dm_interface_init(void)
-+{
-+	int r;
-+
-+	r = dm_hash_init();
-+	if (r)
-+		return r;
-+
-+	r = misc_register(&_dm_misc);
-+	if (r) {
-+		DMERR("misc_register failed for control device");
-+		dm_hash_exit();
-+		return r;
-+	}
-+
-+	DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
-+	       DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
-+	       DM_DRIVER_EMAIL);
-+	return 0;
-+}
-+
-+void dm_interface_exit(void)
-+{
-+	if (misc_deregister(&_dm_misc) < 0)
-+		DMERR("misc_deregister failed for control device");
-+
-+	dm_hash_exit();
-+}
---- linux-2.6.0-test1/drivers/md/dm-table.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/md/dm-table.c	2003-07-19 17:03:49.000000000 -0700
-@@ -48,11 +48,9 @@ struct dm_table {
- 	 */
- 	struct io_restrictions limits;
- 
--	/*
--	 * A waitqueue for processes waiting for something
--	 * interesting to happen to this table.
--	 */
--	wait_queue_head_t eventq;
-+	/* events get handed up using this callback */
-+	void (*event_fn)(void *);
-+	void *event_context;
- };
- 
- /*
-@@ -222,7 +220,6 @@ int dm_table_create(struct dm_table **re
- 		return -ENOMEM;
- 	}
- 
--	init_waitqueue_head(&t->eventq);
- 	t->mode = mode;
- 	*result = t;
- 	return 0;
-@@ -243,9 +240,6 @@ void table_destroy(struct dm_table *t)
- {
- 	unsigned int i;
- 
--	/* destroying the table counts as an event */
--	dm_table_event(t);
--
- 	/* free the indexes (see dm_table_complete) */
- 	if (t->depth >= 2)
- 		vfree(t->index[t->depth - 2]);
-@@ -694,9 +688,22 @@ int dm_table_complete(struct dm_table *t
- 	return r;
- }
- 
-+static spinlock_t _event_lock = SPIN_LOCK_UNLOCKED;
-+void dm_table_event_callback(struct dm_table *t,
-+			     void (*fn)(void *), void *context)
-+{
-+	spin_lock_irq(&_event_lock);
-+	t->event_fn = fn;
-+	t->event_context = context;
-+	spin_unlock_irq(&_event_lock);
-+}
-+
- void dm_table_event(struct dm_table *t)
- {
--	wake_up_interruptible(&t->eventq);
-+	spin_lock(&_event_lock);
-+	if (t->event_fn)
-+		t->event_fn(t->event_context);
-+	spin_unlock(&_event_lock);
- }
- 
- sector_t dm_table_get_size(struct dm_table *t)
-@@ -761,11 +768,6 @@ int dm_table_get_mode(struct dm_table *t
- 	return t->mode;
- }
- 
--void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq)
--{
--	add_wait_queue(&t->eventq, wq);
--}
--
- void dm_table_suspend_targets(struct dm_table *t)
- {
- 	int i;
---- linux-2.6.0-test1/drivers/md/Kconfig	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/md/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -145,5 +145,12 @@ config BLK_DEV_DM
- 
- 	  If unsure, say N.
- 
-+config DM_IOCTL_V4
-+	bool "ioctl interface version 4"
-+	depends on BLK_DEV_DM
-+	---help---
-+	  Recent tools use a new version of the ioctl interface, only
-+          select this option if you intend using such tools.
-+
- endmenu
- 
---- linux-2.6.0-test1/drivers/md/linear.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/md/linear.c	2003-07-19 17:04:58.000000000 -0700
-@@ -114,6 +114,8 @@ static int linear_run (mddev_t *mddev)
- 		}
- 
- 		disk->rdev = rdev;
-+		blk_queue_stack_limits(&mddev->queue,
-+				       rdev->bdev->bd_disk->queue);
- 		disk->size = rdev->size;
- 		mddev->array_size += rdev->size;
- 
---- linux-2.6.0-test1/drivers/md/md.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/drivers/md/md.c	2003-07-19 17:03:49.000000000 -0700
-@@ -52,8 +52,6 @@
- #define MD_DRIVER
- #define DEVICE_NR(device) (minor(device))
- 
--#include <linux/blk.h>
--
- #define DEBUG 0
- #define dprintk(x...) ((void)(DEBUG && printk(x)))
- 
---- linux-2.6.0-test1/drivers/md/multipath.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/md/multipath.c	2003-07-19 17:04:58.000000000 -0700
-@@ -271,6 +271,8 @@ static int multipath_add_disk(mddev_t *m
- 	for (path=0; path<mddev->raid_disks; path++) 
- 		if ((p=conf->multipaths+path)->rdev == NULL) {
- 			p->rdev = rdev;
-+			blk_queue_stack_limits(&mddev->queue,
-+					       rdev->bdev->bd_disk->queue);
- 			conf->working_disks++;
- 			rdev->raid_disk = path;
- 			rdev->in_sync = 1;
-@@ -408,6 +410,8 @@ static int multipath_run (mddev_t *mddev
- 
- 		disk = conf->multipaths + disk_idx;
- 		disk->rdev = rdev;
-+		blk_queue_stack_limits(&mddev->queue,
-+				       rdev->bdev->bd_disk->queue);
- 		if (!rdev->faulty) 
- 			conf->working_disks++;
- 	}
---- linux-2.6.0-test1/drivers/md/raid0.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/md/raid0.c	2003-07-19 17:04:58.000000000 -0700
-@@ -113,6 +113,8 @@ static int create_strip_zones (mddev_t *
- 			goto abort;
- 		}
- 		zone->dev[j] = rdev1;
-+		blk_queue_stack_limits(&mddev->queue,
-+				       rdev1->bdev->bd_disk->queue);
- 		if (!smallest || (rdev1->size <smallest->size))
- 			smallest = rdev1;
- 		cnt++;
-@@ -293,7 +295,6 @@ static int raid0_run (mddev_t *mddev)
- 		conf->hash_spacing++;
- 	}
- 
--	blk_queue_max_sectors(&mddev->queue, mddev->chunk_size >> 9);
- 	blk_queue_merge_bvec(&mddev->queue, raid0_mergeable_bvec);
- 	return 0;
- 
---- linux-2.6.0-test1/drivers/md/raid1.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/md/raid1.c	2003-07-19 17:04:58.000000000 -0700
-@@ -678,6 +678,8 @@ static int raid1_add_disk(mddev_t *mddev
- 	for (mirror=0; mirror < mddev->raid_disks; mirror++)
- 		if ( !(p=conf->mirrors+mirror)->rdev) {
- 			p->rdev = rdev;
-+			blk_queue_stack_limits(&mddev->queue,
-+					       rdev->bdev->bd_disk->queue);
- 			p->head_position = 0;
- 			rdev->raid_disk = mirror;
- 			found = 1;
-@@ -1076,6 +1078,8 @@ static int run(mddev_t *mddev)
- 		disk = conf->mirrors + disk_idx;
- 
- 		disk->rdev = rdev;
-+		blk_queue_stack_limits(&mddev->queue,
-+				       rdev->bdev->bd_disk->queue);
- 		disk->head_position = 0;
- 		if (!rdev->faulty && rdev->in_sync)
- 			conf->working_disks++;
---- linux-2.6.0-test1/drivers/media/common/Makefile	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/media/common/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -1,5 +1,5 @@
- saa7146-objs    := saa7146_i2c.o saa7146_core.o 
--saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o  
-+saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o  
- 
- obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o saa7146_vv.o
- 
---- linux-2.6.0-test1/drivers/media/common/saa7146_core.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_core.c	2003-07-19 17:03:49.000000000 -0700
-@@ -373,6 +373,9 @@ static int saa7146_init_one(struct pci_d
- 	dev->module = THIS_MODULE;
- 	init_waitqueue_head(&dev->i2c_wq);
- 
-+	/* set some default values */
-+	saa7146_write(dev, BCS_CTRL, 0x80400040);
-+
- 	if( 0 != ext->probe) {
- 		if( 0 != ext->probe(dev) ) {
- 			DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));
-@@ -391,9 +394,6 @@ static int saa7146_init_one(struct pci_d
- 	list_add_tail(&dev->item,&saa7146_devices);
- 	saa7146_num++;
- 
--	/* set some default values */
--	saa7146_write(dev, BCS_CTRL, 0x80400040);
--
- 	err = 0;
- 	goto out;
- attach_error:
---- linux-2.6.0-test1/drivers/media/common/saa7146_fops.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_fops.c	2003-07-19 17:03:49.000000000 -0700
-@@ -106,10 +106,21 @@ void saa7146_buffer_next(struct saa7146_
- 			// fixme: fix this for vflip != 0
- 
- 			saa7146_write(dev, PROT_ADDR1, 0);
-+			saa7146_write(dev, MC2, (MASK_02|MASK_18));		
-+
- 			/* write the address of the rps-program */
- 			saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
- 			/* turn on rps */
- 			saa7146_write(dev, MC1, (MASK_12 | MASK_28));
-+				
-+/*
-+			printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
-+			printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
-+			printk("vdma%d.prot_addr:     0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
-+			printk("vdma%d.base_page:     0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
-+			printk("vdma%d.pitch:         0x%08x\n", 1,saa7146_read(dev,PITCH1));
-+			printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
-+*/
- 		}
- 		del_timer(&q->timeout);
- 	}
-@@ -374,7 +385,7 @@ static struct video_device device_templa
- 	.minor		= -1,
- };
- 
--int saa7146_vv_init(struct saa7146_dev* dev)
-+int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
- {
- 	struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
- 	if( NULL == vv ) {
-@@ -385,6 +396,11 @@ int saa7146_vv_init(struct saa7146_dev* 
- 
- 	DEB_EE(("dev:%p\n",dev));
- 	
-+	/* save per-device extension data (one extension can
-+	   handle different devices that might need different
-+	   configuration data) */
-+	dev->ext_vv_data = ext_vv;
-+	
- 	vv->video_minor = -1;
- 	vv->vbi_minor = -1;
- 
-@@ -475,13 +491,6 @@ static void __exit saa7146_vv_cleanup_mo
- module_init(saa7146_vv_init_module);
- module_exit(saa7146_vv_cleanup_module);
- 
--EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
--EXPORT_SYMBOL_GPL(saa7146_register_device);
--EXPORT_SYMBOL_GPL(saa7146_unregister_device);
--
--EXPORT_SYMBOL_GPL(saa7146_vv_init);
--EXPORT_SYMBOL_GPL(saa7146_vv_release);
--
- MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
- MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
- MODULE_LICENSE("GPL");
---- linux-2.6.0-test1/drivers/media/common/saa7146_hlp.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_hlp.c	2003-07-19 17:03:49.000000000 -0700
-@@ -242,7 +242,9 @@ static int calculate_v_scale_registers(s
- 		if( 2*out_y >= in_y) {
- 			lpi = 1;
- 		}
--	} else if (field == V4L2_FIELD_TOP || field == V4L2_FIELD_BOTTOM) {
-+	} else if (field == V4L2_FIELD_TOP
-+		|| field == V4L2_FIELD_ALTERNATE
-+		|| field == V4L2_FIELD_BOTTOM) {
- 		if( 4*out_y >= in_y ) {
- 			lpi = 1;
- 		}
-@@ -468,9 +470,7 @@ static void calculate_clipping_registers
- 	*clip_format &= 0xfffffff7;
- 	if (V4L2_FIELD_HAS_BOTH(field)) {
- 		*clip_format |= 0x00000008;
--	} else if (field == V4L2_FIELD_TOP) {
--		*clip_format |= 0x00000000;
--	} else if (field == V4L2_FIELD_BOTTOM) {
-+	} else {
- 		*clip_format |= 0x00000000;
- 	}
- }
-@@ -593,6 +593,10 @@ static void saa7146_set_position(struct 
- 	}
- 	
- 	if (V4L2_FIELD_HAS_BOTH(field)) {
-+	} else if (field == V4L2_FIELD_ALTERNATE) {
-+		/* fixme */
-+		vdma1.base_odd = vdma1.prot_addr;
-+		vdma1.pitch /= 2;
- 	} else if (field == V4L2_FIELD_TOP) {
- 		vdma1.base_odd = vdma1.prot_addr;
- 		vdma1.pitch /= 2;
-@@ -706,7 +710,7 @@ void saa7146_write_out_dma(struct saa714
- 	/* calculate starting address */
- 	where  = (which-1)*0x18;
- 
--	if( 0 != (dev->ext->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
-+	if( 0 != (dev->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
- 		saa7146_write(dev, where, 	vdma->base_even);
- 		saa7146_write(dev, where+0x04, 	vdma->base_odd);
- 	} else {
-@@ -760,6 +764,16 @@ static int calculate_video_dma_grab_pack
- 	}
- 
- 	if (V4L2_FIELD_HAS_BOTH(field)) {
-+	} else if (field == V4L2_FIELD_ALTERNATE) {
-+		/* fixme */
-+		if ( vv->last_field == V4L2_FIELD_TOP ) {
-+			vdma1.base_odd	= vdma1.prot_addr;
-+			vdma1.pitch /= 2;
-+		} else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
-+			vdma1.base_odd	= vdma1.base_even;
-+			vdma1.base_even = vdma1.prot_addr;
-+			vdma1.pitch /= 2;
-+		}
- 	} else if (field == V4L2_FIELD_TOP) {
- 		vdma1.base_odd	= vdma1.prot_addr;
- 		vdma1.pitch /= 2;
-@@ -896,6 +910,14 @@ static int calculate_video_dma_grab_plan
- 	}
- 
- 	if (V4L2_FIELD_HAS_BOTH(field)) {
-+	} else if (field == V4L2_FIELD_ALTERNATE) {
-+		/* fixme */
-+		vdma1.base_odd	= vdma1.prot_addr;
-+		vdma1.pitch /= 2;
-+		vdma2.base_odd	= vdma2.prot_addr;
-+		vdma2.pitch /= 2;
-+		vdma3.base_odd	= vdma3.prot_addr;
-+		vdma3.pitch /= 2;
- 	} else if (field == V4L2_FIELD_TOP) {
- 		vdma1.base_odd	= vdma1.prot_addr;
- 		vdma1.pitch /= 2;
-@@ -935,21 +957,22 @@ static int calculate_video_dma_grab_plan
- static void program_capture_engine(struct saa7146_dev *dev, int planar)
- {
- 	struct saa7146_vv *vv = dev->vv_data;
-+	int count = 0;
- 
- 	unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
- 	unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
- 
--	if( 0 != (dev->ext->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
-+	if( 0 != (dev->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
- 		unsigned long tmp = e_wait;
- 		e_wait = o_wait;
- 		o_wait = tmp;
- 	}
- 
--	/* wait for o_fid_a/b / e_fid_a/b toggle only if bit 0 is not set*/
--	WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
-+	/* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/
- 	WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait);
-+	WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
- 
--	/* set bit 0 */
-+	/* set rps register 0 */
- 	WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4)); 	
- 	WRITE_RPS0(MASK_27 | MASK_11);
- 	
-@@ -970,8 +993,14 @@ static void program_capture_engine(struc
- 	}
- 	
- 	/* wait for o_fid_a/b / e_fid_a/b toggle */
-+	if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
-+		WRITE_RPS0(CMD_PAUSE | o_wait);
- 	WRITE_RPS0(CMD_PAUSE | e_wait);
-+	} else if ( vv->last_field == V4L2_FIELD_TOP ) {
- 	WRITE_RPS0(CMD_PAUSE | o_wait);
-+	} else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
-+		WRITE_RPS0(CMD_PAUSE | e_wait);
-+	}
- 
- 	/* turn off video-dma1 */
- 	WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
-@@ -999,13 +1028,39 @@ static void program_capture_engine(struc
- void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
- {
- 	struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
-+	struct saa7146_vv *vv = dev->vv_data;
-+	u32 vdma1_prot_addr;
- 
- 	DEB_CAP(("buf:%p, next:%p\n",buf,next));
- 
-+/*
-+	printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
-+	printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
-+	printk("vdma%d.prot_addr:     0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
-+	printk("vdma%d.base_page:     0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
-+	printk("vdma%d.pitch:         0x%08x\n", 1,saa7146_read(dev,PITCH1));
-+	printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
-+	printk("vdma%d => vptr      : 0x%08x\n", 1,saa7146_read(dev,PCI_VDP1));
-+*/
-+
-+	vdma1_prot_addr = saa7146_read(dev, PROT_ADDR1);
-+	if( 0 == vdma1_prot_addr ) {
-+		/* clear out beginning of streaming bit (rps register 0)*/
-+		DEB_CAP(("forcing sync to new frame\n"));
-+		saa7146_write(dev, MC2, MASK_27 );
-+	}
-+
- 	saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
- 	saa7146_set_output_format(dev, sfmt->trans);
- 	saa7146_disable_clipping(dev);
- 
-+	if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
-+	} else if ( vv->last_field == V4L2_FIELD_TOP ) {
-+		vv->last_field = V4L2_FIELD_BOTTOM;
-+	} else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
-+		vv->last_field = V4L2_FIELD_TOP;
-+	}
-+
- 	if( 0 != IS_PLANAR(sfmt->trans)) {
- 		calculate_video_dma_grab_planar(dev, buf);
- 		program_capture_engine(dev,1);
---- linux-2.6.0-test1/drivers/media/common/saa7146_i2c.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_i2c.c	2003-07-19 17:03:49.000000000 -0700
-@@ -181,9 +181,10 @@ static int saa7146_i2c_reset(struct saa7
- /* this functions writes out the data-byte 'dword' to the i2c-device.
-    it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
-    failed badly (e.g. address error) */
--static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword)
-+static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
- {
- 	u32 status = 0, mc2 = 0;
-+	int trial = 0;
- 	int timeout;
- 
- 	/* write out i2c-command */
-@@ -224,10 +225,13 @@ static int saa7146_i2c_writeout(struct s
- 		/* wait until we get a transfer done or error */
- 		timeout = jiffies + HZ/100 + 1; /* 10ms */
- 		while(1) {
-+			/**
-+			 *  first read usually delivers bogus results...
-+			 */
-+			saa7146_i2c_status(dev);
- 			status = saa7146_i2c_status(dev);
--			if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
-+			if ((status & 0x3) != 1)
- 				break;
--			}
- 			if (jiffies > timeout) {
- 				/* this is normal when probing the bus
- 				 * (no answer from nonexisistant device...)
-@@ -235,6 +239,9 @@ static int saa7146_i2c_writeout(struct s
- 				DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
- 				return -EIO;
- 			}
-+			if ((++trial < 20) && short_delay)
-+				udelay(10);
-+			else
- 			my_wait(dev,1);
- 		}
- 	}
-@@ -277,6 +284,7 @@ int saa7146_i2c_transfer(struct saa7146_
- 	u32* buffer = dev->d_i2c.cpu_addr;
- 	int err = 0;
-         int address_err = 0;
-+        int short_delay = 0;
- 	
- 	if (down_interruptible (&dev->i2c_lock))
- 		return -ERESTARTSYS;
-@@ -292,6 +300,8 @@ int saa7146_i2c_transfer(struct saa7146_
- 		goto out;
- 	}
- 
-+        if (count > 3) short_delay = 1;
-+  
- 	do {
- 		/* reset the i2c-device if necessary */
- 		err = saa7146_i2c_reset(dev);
-@@ -302,7 +312,7 @@ int saa7146_i2c_transfer(struct saa7146_
- 
- 		/* write out the u32s one after another */
- 		for(i = 0; i < count; i++) {
--			err = saa7146_i2c_writeout(dev, &buffer[i] );
-+			err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
- 			if ( 0 != err) {
- 				/* this one is unsatisfying: some i2c slaves on some
- 				   dvb cards don't acknowledge correctly, so the saa7146
-@@ -357,7 +367,7 @@ out:
- 	if( 0 == dev->revision ) {
- 		u32 zero = 0;
- 		saa7146_i2c_reset(dev);
--		if( 0 != saa7146_i2c_writeout(dev, &zero)) {
-+		if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
- 			INFO(("revision 0 error. this should never happen.\n"));
- 		}
- 	}
-@@ -397,8 +407,13 @@ int saa7146_i2c_adapter_prepare(struct s
- 
- 	if( NULL != i2c_adapter ) {
- 		memset(i2c_adapter,0,sizeof(struct i2c_adapter));
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-+		strcpy(i2c_adapter->name, dev->name);	
-+		i2c_adapter->data = dev;
-+#else
- 		strcpy(i2c_adapter->dev.name, dev->name);	
- 		i2c_set_adapdata(i2c_adapter,dev);
-+#endif
- 		i2c_adapter->algo	   = &saa7146_algo;
- 		i2c_adapter->algo_data     = NULL;
- 		i2c_adapter->id 	   = I2C_ALGO_SAA7146;
---- linux-2.6.0-test1/drivers/media/common/saa7146_vbi.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_vbi.c	2003-07-19 17:03:49.000000000 -0700
-@@ -9,6 +9,7 @@ static int vbi_workaround(struct saa7146
-         u32          *cpu;
-         dma_addr_t   dma_addr;
- 	
-+	int count = 0;
- 	int i;
- 
- 	DECLARE_WAITQUEUE(wait, current);
-@@ -443,5 +444,3 @@ struct saa7146_use_ops saa7146_vbi_uops 
- 	.irq_done	= vbi_irq_done,
- 	.read 		= vbi_read,
- };
--
--EXPORT_SYMBOL_GPL(saa7146_vbi_uops);
---- linux-2.6.0-test1/drivers/media/common/saa7146_video.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/common/saa7146_video.c	2003-07-19 17:03:49.000000000 -0700
-@@ -137,6 +137,7 @@ static int try_win(struct saa7146_dev *d
-         switch (field) {
-         case V4L2_FIELD_TOP:
-         case V4L2_FIELD_BOTTOM:
-+        case V4L2_FIELD_ALTERNATE:
-                 maxh = maxh / 2;
-                 break;
-         case V4L2_FIELD_INTERLACED:
-@@ -186,11 +187,18 @@ static int try_fmt(struct saa7146_fh *fh
- 				: V4L2_FIELD_BOTTOM;
- 		}
- 		switch (field) {
-+		case V4L2_FIELD_ALTERNATE: {
-+			vv->last_field = V4L2_FIELD_TOP;
-+			maxh = maxh / 2;
-+			break;
-+		}
- 		case V4L2_FIELD_TOP:
- 		case V4L2_FIELD_BOTTOM:
-+			vv->last_field = V4L2_FIELD_INTERLACED;
- 			maxh = maxh / 2;
- 			break;
- 		case V4L2_FIELD_INTERLACED:
-+			vv->last_field = V4L2_FIELD_INTERLACED;
- 			break;
- 		default: {
- 			DEB_D(("no known field mode '%d'.\n",field));
-@@ -220,7 +228,7 @@ static int try_fmt(struct saa7146_fh *fh
- 	}
- }
- 
--static int start_preview(struct saa7146_fh *fh)
-+int saa7146_start_preview(struct saa7146_fh *fh)
- {
- 	struct saa7146_dev *dev = fh->dev;
- 	struct saa7146_vv *vv = dev->vv_data;
-@@ -266,12 +274,12 @@ static int start_preview(struct saa7146_
- 	return 0;
- }
- 
--static int stop_preview(struct saa7146_fh *fh)
-+int saa7146_stop_preview(struct saa7146_fh *fh)
- {
- 	struct saa7146_dev *dev = fh->dev;
- 	struct saa7146_vv *vv = dev->vv_data;
- 
--	DEB_EE(("saa7146.o: stop_preview()\n"));
-+	DEB_EE(("saa7146.o: saa7146_stop_preview()\n"));
- 
- 	/* check if overlay is running */
- 	if( 0 == vv->ov_data ) {
-@@ -333,8 +341,8 @@ static int s_fmt(struct saa7146_fh *fh, 
- 		if( vv->ov_data != NULL ) {
- 			if( fh == vv->ov_data->fh) {
- 				spin_lock_irqsave(&dev->slock,flags);
--				stop_preview(fh);
--				start_preview(fh);
-+				saa7146_stop_preview(fh);
-+				saa7146_start_preview(fh);
- 				spin_unlock_irqrestore(&dev->slock,flags);
- 			}
- 		}
-@@ -522,8 +530,8 @@ static int set_control(struct saa7146_fh
- 		if( 0 != vv->ov_data ) {
- 			if( fh == vv->ov_data->fh ) {
- 				spin_lock_irqsave(&dev->slock,flags);
--				stop_preview(fh);
--				start_preview(fh);
-+				saa7146_stop_preview(fh);
-+				saa7146_start_preview(fh);
- 				spin_unlock_irqrestore(&dev->slock,flags);
- 			}
- 		}
-@@ -561,7 +569,7 @@ static int saa7146_pgtable_build(struct 
- 				m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
- 				o1 = size%PAGE_SIZE;
- 				o2 = (size+(size/4))%PAGE_SIZE;
--				printk("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2);
-+				DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
- 				break;
- 			}
- 			case 16: {
-@@ -571,7 +579,7 @@ static int saa7146_pgtable_build(struct 
- 				m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
- 				o1 = size%PAGE_SIZE;
- 				o2 = (size+(size/2))%PAGE_SIZE;
--				printk("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2);
-+				DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
- 				break;
- 			}
- 			default: {
-@@ -674,7 +682,7 @@ static int video_begin(struct saa7146_fh
- 
- 	spin_lock_irqsave(&dev->slock,flags);
- 
--	/* clear out beginning of streaming bit */
-+	/* clear out beginning of streaming bit (rps register 0)*/
- 	saa7146_write(dev, MC2, MASK_27 );
- 
- 	/* enable rps0 irqs */
-@@ -740,19 +748,19 @@ int saa7146_video_do_ioctl(struct inode 
- 	struct videobuf_queue *q;
- 
- 	/* check if extension handles the command */
--	for(ee = 0; dev->ext->ext_vv_data->ioctls[ee].flags != 0; ee++) {
--		if( cmd == dev->ext->ext_vv_data->ioctls[ee].cmd )
-+	for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
-+		if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
- 			break;
- 	}
- 	
--	if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
-+	if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
- 		DEB_D(("extension handles ioctl exclusive.\n"));
--		result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
-+		result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- 		return result;
- 	}
--	if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
-+	if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
- 		DEB_D(("extension handles ioctl before.\n"));
--		result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
-+		result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- 		if( -EAGAIN != result ) {
- 			return result;
- 		}
-@@ -793,7 +801,7 @@ int saa7146_video_do_ioctl(struct inode 
- 			V4L2_CAP_VIDEO_OVERLAY |
- 			V4L2_CAP_READWRITE | 
- 			V4L2_CAP_STREAMING;
--		cap->capabilities |= dev->ext->ext_vv_data->capabilities;
-+		cap->capabilities |= dev->ext_vv_data->capabilities;
- 		return 0;
- 	}
- 	case VIDIOC_G_FBUF:
-@@ -942,9 +950,10 @@ int saa7146_video_do_ioctl(struct inode 
- 		struct v4l2_standard *e = arg;
- 		if (e->index < 0 )
- 			return -EINVAL;
--		if( e->index < dev->ext->ext_vv_data->num_stds ) {
-+		if( e->index < dev->ext_vv_data->num_stds ) {
- 			DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
--			return v4l2_video_std_construct(e, dev->ext->ext_vv_data->stds[e->index].id, dev->ext->ext_vv_data->stds[e->index].name);
-+			v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
-+			return 0;
- 		}
- 		return -EINVAL;
- 	}
-@@ -968,22 +977,22 @@ int saa7146_video_do_ioctl(struct inode 
- 
- 		if( vv->ov_data != NULL ) {
- 			ov_fh = vv->ov_data->fh;
--			stop_preview(ov_fh);
-+			saa7146_stop_preview(ov_fh);
- 			restart_overlay = 1;
- 		}
- 
--		for(i = 0; i < dev->ext->ext_vv_data->num_stds; i++)
--			if (*id & dev->ext->ext_vv_data->stds[i].id)
-+		for(i = 0; i < dev->ext_vv_data->num_stds; i++)
-+			if (*id & dev->ext_vv_data->stds[i].id)
- 				break;
--		if (i != dev->ext->ext_vv_data->num_stds) {
--			vv->standard = &dev->ext->ext_vv_data->stds[i];
--			if( NULL != dev->ext->ext_vv_data->std_callback )
--				dev->ext->ext_vv_data->std_callback(dev, vv->standard);
-+		if (i != dev->ext_vv_data->num_stds) {
-+			vv->standard = &dev->ext_vv_data->stds[i];
-+			if( NULL != dev->ext_vv_data->std_callback )
-+				dev->ext_vv_data->std_callback(dev, vv->standard);
- 			found = 1;
- 		}
- 
- 		if( 0 != restart_overlay ) {
--			start_preview(ov_fh);
-+			saa7146_start_preview(ov_fh);
- 		}
- 		up(&dev->lock);
- 
-@@ -1000,7 +1009,7 @@ int saa7146_video_do_ioctl(struct inode 
- 		int on = *(int *)arg;
- 		int err = 0;
- 
--		if( NULL == vv->ov_fmt ) {
-+		if( NULL == vv->ov_fmt && on != 0 ) {
- 			DEB_D(("VIDIOC_OVERLAY: no framebuffer informations. call S_FBUF first!\n"));
- 			return -EAGAIN;
- 		}
-@@ -1013,7 +1022,7 @@ int saa7146_video_do_ioctl(struct inode 
- 				}
- 			}
- 			spin_lock_irqsave(&dev->slock,flags);
--			err = start_preview(fh);
-+			err = saa7146_start_preview(fh);
- 			spin_unlock_irqrestore(&dev->slock,flags);
- 		} else {
- 			if( vv->ov_data != NULL ) {
-@@ -1022,7 +1031,7 @@ int saa7146_video_do_ioctl(struct inode 
- 				}
- 			}
- 			spin_lock_irqsave(&dev->slock,flags);
--			err = stop_preview(fh);
-+			err = saa7146_stop_preview(fh);
- 			spin_unlock_irqrestore(&dev->slock,flags);
- 		}
- 		return err;
-@@ -1036,12 +1045,18 @@ int saa7146_video_do_ioctl(struct inode 
- 		return videobuf_querybuf(q,arg);
- 	}
- 	case VIDIOC_QBUF: {
--		DEB_D(("VIDIOC_QBUF \n"));
--		return videobuf_qbuf(file,q,arg);
-+		struct v4l2_buffer *b = arg;
-+		int ret = 0;
-+		ret = videobuf_qbuf(file,q,b);
-+		DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,b->index));
-+		return ret;
- 	}
- 	case VIDIOC_DQBUF: {
--		DEB_D(("VIDIOC_DQBUF \n"));
--		return videobuf_dqbuf(file,q,arg);
-+		struct v4l2_buffer *b = arg;
-+		int ret = 0;
-+		ret = videobuf_dqbuf(file,q,b);
-+		DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,b->index));
-+		return ret;
- 	}
- 	case VIDIOC_STREAMON: {
- 		DEB_D(("VIDIOC_STREAMON \n"));
-@@ -1075,7 +1090,7 @@ int saa7146_video_do_ioctl(struct inode 
- 
- 		q = &fh->video_q;
- 		down(&q->lock);
--		err = videobuf_mmap_setup(file,q,gbuffers,gbufsize);
-+		err = videobuf_mmap_setup(file,q,gbuffers,gbufsize); // ,V4L2_MEMORY_MMAP);
- 		if (err < 0) {
- 			up(&q->lock);
- 			return err;
-@@ -1250,7 +1265,7 @@ static void video_init(struct saa7146_de
- 	vv->video_q.dev              = dev;
- 
- 	/* set some default values */
--	vv->standard = &dev->ext->ext_vv_data->stds[0];
-+	vv->standard = &dev->ext_vv_data->stds[0];
- 
- 	/* FIXME: what's this? */
- 	vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
-@@ -1287,7 +1302,7 @@ static void video_close(struct saa7146_d
- 	if( 0 != vv->ov_data ) {
- 		if( fh == vv->ov_data->fh ) {
- 			spin_lock_irqsave(&dev->slock,flags);
--			stop_preview(fh);
-+			saa7146_stop_preview(fh);
- 			spin_unlock_irqrestore(&dev->slock,flags);
- 		}
- 	}
-@@ -1331,7 +1346,7 @@ static ssize_t video_read(struct file *f
- 
- 	if( vv->ov_data != NULL ) {
- 		ov_fh = vv->ov_data->fh;
--		stop_preview(ov_fh);
-+		saa7146_stop_preview(ov_fh);
- 		restart_overlay = 1;
- 	}
- 
-@@ -1343,7 +1358,7 @@ static ssize_t video_read(struct file *f
- 
- 	/* restart overlay if it was active before */
- 	if( 0 != restart_overlay ) {
--		start_preview(ov_fh);
-+		saa7146_start_preview(ov_fh);
- 	}
- 	
- 	return ret;
-@@ -1358,5 +1373,3 @@ struct saa7146_use_ops saa7146_video_uop
- 	.capture_begin = video_begin,
- 	.capture_end = video_end,
- };
--
--EXPORT_SYMBOL_GPL(saa7146_video_uops);
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/common/saa7146_vv_ksyms.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,15 @@
-+#include <linux/module.h>
-+#include <media/saa7146_vv.h>
-+
-+EXPORT_SYMBOL_GPL(saa7146_vbi_uops);
-+EXPORT_SYMBOL_GPL(saa7146_video_uops);
-+
-+EXPORT_SYMBOL_GPL(saa7146_start_preview);
-+EXPORT_SYMBOL_GPL(saa7146_stop_preview);
-+
-+EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
-+EXPORT_SYMBOL_GPL(saa7146_register_device);
-+EXPORT_SYMBOL_GPL(saa7146_unregister_device);
-+
-+EXPORT_SYMBOL_GPL(saa7146_vv_init);
-+EXPORT_SYMBOL_GPL(saa7146_vv_release);
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/b2c2/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,8 @@
-+config DVB_B2C2_SKYSTAR
-+	tristate "Technisat Skystar2 PCI"
-+	depends on DVB_CORE
-+	help
-+	  Support for the Skystar2 PCI DVB card by Technisat, which
-+	  is equipped with the FlexCopII chipset by B2C2.
-+
-+	  Say Y if you own such a device and want to use it.
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/b2c2/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,3 @@
-+obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
-+
-+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/b2c2/skystar2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,2506 @@
-+/*
-+ * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
-+ *              based on the FlexCopII by B2C2,Inc.
-+ *
-+ * Copyright (C) 2003  V.C. , skystar@moldova.cc
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public License
-+ * as published by the Free Software Foundation; either version 2.1
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ */
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/pci.h>
-+
-+#include "dvb_i2c.h"
-+#include "dvb_frontend.h"
-+#include "dvb_functions.h"
-+
-+#include <linux/dvb/frontend.h>
-+#include <linux/dvb/dmx.h>
-+#include "dvb_demux.h"
-+#include "dmxdev.h"
-+#include "dvb_filter.h"
-+#include "dvbdev.h"
-+#include "demux.h"
-+#include "dvb_net.h"
-+
-+static int debug = 0;
-+#define dprintk(x...) do { if (debug) printk(x); } while (0)
-+
-+#define SizeOfBufDMA1	0x3AC00
-+#define SizeOfBufDMA2	0x758
-+
-+struct dmaq {
-+
-+	u32 bus_addr;
-+	u32 head;
-+	u32 tail;
-+	u32 buffer_size;
-+	u8 *buffer;
-+};
-+
-+struct packet_header {
-+
-+	u32 sync_byte;
-+	u32 transport_error_indicator;
-+	u32 payload_unit_start_indicator;
-+	u32 transport_priority;
-+	u32 pid;
-+	u32 transport_scrambling_control;
-+	u32 adaptation_field_control;
-+	u32 continuity_counter;
-+};
-+
-+struct adapter {
-+
-+	struct pci_dev *pdev;
-+
-+	u8 card_revision;
-+	u32 b2c2_revision;
-+	u32 PidFilterMax;
-+	u32 MacFilterMax;
-+	u32 irq;
-+	u32 io_mem;
-+	u32 io_port;
-+	u8 mac_addr[8];
-+	u32 dwSramType;
-+
-+	struct dvb_adapter *dvb_adapter;
-+	struct dvb_demux demux;
-+	struct dmxdev dmxdev;
-+	struct dmx_frontend hw_frontend;
-+	struct dmx_frontend mem_frontend;
-+	struct dvb_i2c_bus *i2c_bus;
-+	struct dvb_net dvbnet;
-+
-+	struct semaphore i2c_sem;
-+
-+	struct dmaq dmaq1;
-+	struct dmaq dmaq2;
-+
-+	u32 dma_ctrl;
-+	u32 dma_status;
-+
-+	u32 capturing;
-+
-+	spinlock_t lock;
-+
-+	u16 pids[0x27];
-+	u32 mac_filter;
-+};
-+
-+#define WriteRegDW(adapter,reg,value) writel(value, adapter->io_mem + reg)
-+#define ReadRegDW(adapter,reg) readl(adapter->io_mem + reg)
-+
-+static void WriteRegOp(struct adapter *adapter, u32 reg, u32 operation, u32 andvalue, u32 orvalue)
-+{
-+	u32 tmp;
-+
-+	tmp = ReadRegDW(adapter, reg);
-+
-+	if (operation == 1)
-+		tmp = tmp | orvalue;
-+	if (operation == 2)
-+		tmp = tmp & andvalue;
-+	if (operation == 3)
-+		tmp = (tmp & andvalue) | orvalue;
-+
-+	WriteRegDW(adapter, reg, tmp);
-+}
-+
-+/* i2c functions */
-+static int i2cMainWriteForFlex2(struct adapter * adapter, u32 command, u8 * buf, u32 retries)
-+{
-+	u32 i;
-+	u32 value;
-+
-+	WriteRegDW(adapter, 0x100, 0);
-+	WriteRegDW(adapter, 0x100, command);
-+
-+	for (i = 0; i < retries; i++) {
-+		value = ReadRegDW(adapter, 0x100);
-+
-+		if ((value & 0x40000000) == 0) {
-+			if ((value & 0x81000000) == 0x80000000) {
-+				if (buf != 0)
-+					*buf = (value >> 0x10) & 0xff;
-+
-+				return 1;
-+			}
-+
-+		} else {
-+
-+			WriteRegDW(adapter, 0x100, 0);
-+			WriteRegDW(adapter, 0x100, command);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
-+static void i2cMainSetup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
-+{
-+	*command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
-+
-+	if (op != 0)
-+		*command = *command | 0x03000000;
-+	else
-+		*command = *command | 0x01000000;
-+}
-+
-+static int FlexI2cRead4(struct adapter * adapter, u32 device, u32 chip_addr, u16 addr, u8 * buf, u8 len)
-+{
-+	u32 command;
-+	u32 value;
-+
-+	int result, i;
-+
-+	i2cMainSetup(device, chip_addr, 1, addr, 0, len, &command);
-+
-+	result = i2cMainWriteForFlex2(adapter, command, buf, 100000);
-+
-+	if ((result & 0xff) != 0) {
-+		if (len > 1) {
-+			value = ReadRegDW(adapter, 0x104);
-+
-+			for (i = 1; i < len; i++) {
-+				buf[i] = value & 0xff;
-+				value = value >> 8;
-+			}
-+		}
-+	}
-+
-+	return result;
-+}
-+
-+static int FlexI2cWrite4(struct adapter * adapter, u32 device, u32 chip_addr, u32 addr, u8 * buf, u8 len)
-+{
-+	u32 command;
-+	u32 value;
-+	int i;
-+
-+	if (len > 1) {
-+		value = 0;
-+
-+		for (i = len; i > 1; i--) {
-+			value = value << 8;
-+			value = value | buf[i - 1];
-+		}
-+
-+		WriteRegDW(adapter, 0x104, value);
-+	}
-+
-+	i2cMainSetup(device, chip_addr, 0, addr, buf[0], len, &command);
-+
-+	return i2cMainWriteForFlex2(adapter, command, 0, 100000);
-+}
-+
-+static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
-+{
-+	if (device == 0x20000000)
-+		*ret = bus | ((addr >> 8) & 3);
-+
-+	*ret = bus;
-+}
-+
-+static u32 FLEXI2C_read(struct adapter * adapter, u32 device, u32 bus, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 chipaddr;
-+	u32 bytes_to_transfer;
-+	u8 *start;
-+
-+//  dprintk("%s:\n", __FUNCTION__);
-+
-+	start = buf;
-+
-+	while (len != 0) {
-+		bytes_to_transfer = len;
-+
-+		if (bytes_to_transfer > 4)
-+			bytes_to_transfer = 4;
-+
-+		fixchipaddr(device, bus, addr, &chipaddr);
-+
-+		if (FlexI2cRead4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
-+			return buf - start;
-+
-+		buf = buf + bytes_to_transfer;
-+		addr = addr + bytes_to_transfer;
-+		len = len - bytes_to_transfer;
-+	};
-+
-+	return buf - start;
-+}
-+
-+static u32 FLEXI2C_write(struct adapter * adapter, u32 device, u32 bus, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 chipaddr;
-+	u32 bytes_to_transfer;
-+	u8 *start;
-+
-+//  dprintk("%s:\n", __FUNCTION__);
-+
-+	start = buf;
-+
-+	while (len != 0) {
-+		bytes_to_transfer = len;
-+
-+		if (bytes_to_transfer > 4)
-+			bytes_to_transfer = 4;
-+
-+		fixchipaddr(device, bus, addr, &chipaddr);
-+
-+		if (FlexI2cWrite4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
-+			return buf - start;
-+
-+		buf = buf + bytes_to_transfer;
-+		addr = addr + bytes_to_transfer;
-+		len = len - bytes_to_transfer;
-+	}
-+
-+	return buf - start;
-+}
-+
-+static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int num)
-+{
-+	struct adapter *tmp = i2c->data;
-+	int i, ret = 0;
-+
-+	if (down_interruptible(&tmp->i2c_sem))
-+		return -ERESTARTSYS;
-+
-+	if (0) {
-+		dprintk("%s:\n", __FUNCTION__);
-+
-+		for (i = 0; i < num; i++) {
-+			printk("message %d: flags=%x, addr=0x%04x, buf=%x, len=%d \n", i, msgs[i].flags, msgs[i].addr, (u32) msgs[i].buf, msgs[i].len);
-+		}
-+	}
-+	
-+	/* allow only the vp310 frontend to access the bus */
-+	if ((msgs[0].addr != 0x0E) && (msgs[0].addr != 0x61)) {
-+		up(&tmp->i2c_sem);
-+
-+		return -EREMOTEIO;
-+	}
-+
-+	if ((num == 1) && (msgs[0].buf != NULL)) {
-+		if (msgs[0].flags == I2C_M_RD) {
-+			ret = -EINVAL;
-+
-+		} else {
-+
-+			// single writes do have the reg addr in buf[0] and data in buf[1] to buf[n]
-+			ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], &msgs[0].buf[1], msgs[0].len - 1);
-+
-+			if (ret != msgs[0].len - 1)
-+				ret = -EREMOTEIO;
-+			else
-+				ret = num;
-+		}
-+
-+	} else if ((num == 2) && (msgs[1].buf != NULL)) {
-+
-+		// i2c reads consist of a reg addr _write_ followed by a data read, so msg[1].flags has to be examined
-+		if (msgs[1].flags == I2C_M_RD) {
-+			ret = FLEXI2C_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-+
-+		} else {
-+
-+			ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-+		}
-+
-+		if (ret != msgs[1].len)
-+			ret = -EREMOTEIO;
-+		else
-+			ret = num;
-+	}
-+
-+	up(&tmp->i2c_sem);
-+
-+	/* master xfer functions always return the number of successfully
-+	   transmitted messages, not the number of transmitted bytes.
-+	   return -EREMOTEIO in case of failure. */
-+	return ret;
-+}
-+
-+/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
-+   but it seems that FlexCopII can work with more than one chip) */
-+static void SRAMSetNetDest(struct adapter * adapter, u8 dest)
-+{
-+	u32 tmp;
-+
-+	udelay(1000);
-+
-+	tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFFC) | (dest & 3);
-+
-+	udelay(1000);
-+
-+	WriteRegDW(adapter, 0x714, tmp);
-+	WriteRegDW(adapter, 0x714, tmp);
-+
-+	udelay(1000);
-+
-+	/* return value is never used? */
-+/*	return tmp; */
-+}
-+
-+static void SRAMSetCaiDest(struct adapter * adapter, u8 dest)
-+{
-+	u32 tmp;
-+
-+	udelay(1000);
-+
-+	tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFF3) | ((dest & 3) << 2);
-+
-+	udelay(1000);
-+	udelay(1000);
-+
-+	WriteRegDW(adapter, 0x714, tmp);
-+	WriteRegDW(adapter, 0x714, tmp);
-+
-+	udelay(1000);
-+
-+	/* return value is never used? */
-+/*	return tmp; */
-+}
-+
-+static void SRAMSetCaoDest(struct adapter * adapter, u8 dest)
-+{
-+	u32 tmp;
-+
-+	udelay(1000);
-+
-+	tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFCF) | ((dest & 3) << 4);
-+
-+	udelay(1000);
-+	udelay(1000);
-+
-+	WriteRegDW(adapter, 0x714, tmp);
-+	WriteRegDW(adapter, 0x714, tmp);
-+
-+	udelay(1000);
-+
-+	/* return value is never used? */
-+/*	return tmp; */
-+}
-+
-+static void SRAMSetMediaDest(struct adapter * adapter, u8 dest)
-+{
-+	u32 tmp;
-+
-+	udelay(1000);
-+
-+	tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFF3F) | ((dest & 3) << 6);
-+
-+	udelay(1000);
-+	udelay(1000);
-+
-+	WriteRegDW(adapter, 0x714, tmp);
-+	WriteRegDW(adapter, 0x714, tmp);
-+
-+	udelay(1000);
-+
-+	/* return value is never used? */
-+/*	return tmp; */
-+}
-+
-+/* SRAM memory is accessed through a buffer register in the FlexCop
-+   chip (0x700). This register has the following structure:
-+    bits 0-14  : address
-+    bit  15    : read/write flag
-+    bits 16-23 : 8-bit word to write
-+    bits 24-27 : = 4
-+    bits 28-29 : memory bank selector
-+    bit  31    : busy flag
-+*/
-+static void FlexSramWrite(struct adapter *adapter, u32 bank, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 i, command, retries;
-+
-+	for (i = 0; i < len; i++) {
-+		command = bank | addr | 0x04000000 | (*buf << 0x10);
-+
-+		retries = 2;
-+
-+		while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-+			mdelay(1);
-+			retries--;
-+		};
-+
-+		if (retries == 0)
-+			printk("%s: SRAM timeout\n", __FUNCTION__);
-+
-+		WriteRegDW(adapter, 0x700, command);
-+
-+		buf++;
-+		addr++;
-+	}
-+}
-+
-+static void FlexSramRead(struct adapter *adapter, u32 bank, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 i, command, value, retries;
-+
-+	for (i = 0; i < len; i++) {
-+		command = bank | addr | 0x04008000;
-+
-+		retries = 10000;
-+
-+		while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-+			mdelay(1);
-+			retries--;
-+		};
-+
-+		if (retries == 0)
-+			printk("%s: SRAM timeout\n", __FUNCTION__);
-+
-+		WriteRegDW(adapter, 0x700, command);
-+
-+		retries = 10000;
-+
-+		while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-+			mdelay(1);
-+			retries--;
-+		};
-+
-+		if (retries == 0)
-+			printk("%s: SRAM timeout\n", __FUNCTION__);
-+
-+		value = ReadRegDW(adapter, 0x700) >> 0x10;
-+
-+		*buf = (value & 0xff);
-+
-+		addr++;
-+		buf++;
-+	}
-+}
-+
-+static void SRAM_writeChunk(struct adapter *adapter, u32 addr, u8 * buf, u16 len)
-+{
-+	u32 bank;
-+
-+	bank = 0;
-+
-+	if (adapter->dwSramType == 0x20000) {
-+		bank = (addr & 0x18000) << 0x0D;
-+	}
-+
-+	if (adapter->dwSramType == 0x00000) {
-+		if ((addr >> 0x0F) == 0)
-+			bank = 0x20000000;
-+		else
-+			bank = 0x10000000;
-+	}
-+
-+	FlexSramWrite(adapter, bank, addr & 0x7FFF, buf, len);
-+}
-+
-+static void SRAM_readChunk(struct adapter *adapter, u32 addr, u8 * buf, u16 len)
-+{
-+	u32 bank;
-+
-+	bank = 0;
-+
-+	if (adapter->dwSramType == 0x20000) {
-+		bank = (addr & 0x18000) << 0x0D;
-+	}
-+
-+	if (adapter->dwSramType == 0x00000) {
-+		if ((addr >> 0x0F) == 0)
-+			bank = 0x20000000;
-+		else
-+			bank = 0x10000000;
-+	}
-+
-+	FlexSramRead(adapter, bank, addr & 0x7FFF, buf, len);
-+}
-+
-+static void SRAM_read(struct adapter *adapter, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 length;
-+
-+	while (len != 0) {
-+		length = len;
-+
-+		// check if the address range belongs to the same 
-+		// 32K memory chip. If not, the data is read from 
-+		// one chip at a time.
-+		if ((addr >> 0x0F) != ((addr + len - 1) >> 0x0F)) {
-+			length = (((addr >> 0x0F) + 1) << 0x0F) - addr;
-+		}
-+
-+		SRAM_readChunk(adapter, addr, buf, length);
-+
-+		addr = addr + length;
-+		buf = buf + length;
-+		len = len - length;
-+	}
-+}
-+
-+static void SRAM_write(struct adapter *adapter, u32 addr, u8 * buf, u32 len)
-+{
-+	u32 length;
-+
-+	while (len != 0) {
-+		length = len;
-+
-+		// check if the address range belongs to the same 
-+		// 32K memory chip. If not, the data is written to
-+		// one chip at a time.
-+		if ((addr >> 0x0F) != ((addr + len - 1) >> 0x0F)) {
-+			length = (((addr >> 0x0F) + 1) << 0x0F) - addr;
-+		}
-+
-+		SRAM_writeChunk(adapter, addr, buf, length);
-+
-+		addr = addr + length;
-+		buf = buf + length;
-+		len = len - length;
-+	}
-+}
-+
-+static void SRAM_setSize(struct adapter *adapter, u32 mask)
-+{
-+	WriteRegDW(adapter, 0x71C, (mask | (~0x30000 & ReadRegDW(adapter, 0x71C))));
-+}
-+
-+static void SRAM_init(struct adapter *adapter)
-+{
-+	u32 tmp;
-+
-+	tmp = ReadRegDW(adapter, 0x71C);
-+
-+	WriteRegDW(adapter, 0x71C, 1);
-+
-+	if (ReadRegDW(adapter, 0x71C) != 0) {
-+		WriteRegDW(adapter, 0x71C, tmp);
-+
-+		adapter->dwSramType = tmp & 0x30000;
-+
-+		dprintk("%s: dwSramType = %x\n", __FUNCTION__, adapter->dwSramType);
-+
-+	} else {
-+
-+		adapter->dwSramType = 0x10000;
-+
-+		dprintk("%s: dwSramType = %x\n", __FUNCTION__, adapter->dwSramType);
-+	}
-+
-+	/* return value is never used? */
-+/*	return adapter->dwSramType; */
-+}
-+
-+static int SRAM_testLocation(struct adapter *adapter, u32 mask, u32 addr)
-+{
-+	u8 tmp1, tmp2;
-+
-+	dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
-+
-+	SRAM_setSize(adapter, mask);
-+	SRAM_init(adapter);
-+
-+	tmp2 = 0xA5;
-+	tmp1 = 0x4F;
-+
-+	SRAM_write(adapter, addr, &tmp2, 1);
-+	SRAM_write(adapter, addr + 4, &tmp1, 1);
-+
-+	tmp2 = 0;
-+
-+	mdelay(20);
-+
-+	SRAM_read(adapter, addr, &tmp2, 1);
-+	SRAM_read(adapter, addr, &tmp2, 1);
-+
-+	dprintk("%s: wrote 0xA5, read 0x%2x\n", __FUNCTION__, tmp2);
-+
-+	if (tmp2 != 0xA5)
-+		return 0;
-+
-+	tmp2 = 0x5A;
-+	tmp1 = 0xF4;
-+
-+	SRAM_write(adapter, addr, &tmp2, 1);
-+	SRAM_write(adapter, addr + 4, &tmp1, 1);
-+
-+	tmp2 = 0;
-+
-+	mdelay(20);
-+
-+	SRAM_read(adapter, addr, &tmp2, 1);
-+	SRAM_read(adapter, addr, &tmp2, 1);
-+
-+	dprintk("%s: wrote 0x5A, read 0x%2x\n", __FUNCTION__, tmp2);
-+
-+	if (tmp2 != 0x5A)
-+		return 0;
-+
-+	return 1;
-+}
-+
-+static u32 SRAM_length(struct adapter * adapter)
-+{
-+	if (adapter->dwSramType == 0x10000)
-+		return 32768;	//  32K
-+	if (adapter->dwSramType == 0x00000)
-+		return 65536;	//  64K        
-+	if (adapter->dwSramType == 0x20000)
-+		return 131072;	// 128K
-+
-+	return 32768;		// 32K
-+}
-+
-+/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
-+    - for 128K there are 4x32K chips at bank 0,1,2,3.
-+    - for  64K there are 2x32K chips at bank 1,2.
-+    - for  32K there is one 32K chip at bank 0.
-+
-+   FlexCop works only with one bank at a time. The bank is selected
-+   by bits 28-29 of the 0x700 register.
-+  
-+   bank 0 covers addresses 0x00000-0x07FFF
-+   bank 1 covers addresses 0x08000-0x0FFFF
-+   bank 2 covers addresses 0x10000-0x17FFF
-+   bank 3 covers addresses 0x18000-0x1FFFF
-+*/
-+static int SramDetectForFlex2(struct adapter *adapter)
-+{
-+	u32 tmp, tmp2, tmp3;
-+
-+	dprintk("%s:\n", __FUNCTION__);
-+
-+	tmp = ReadRegDW(adapter, 0x208);
-+	WriteRegDW(adapter, 0x208, 0);
-+
-+	tmp2 = ReadRegDW(adapter, 0x71C);
-+
-+	dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
-+
-+	WriteRegDW(adapter, 0x71C, 1);
-+
-+	tmp3 = ReadRegDW(adapter, 0x71C);
-+
-+	dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
-+
-+	WriteRegDW(adapter, 0x71C, tmp2);
-+
-+	// check for internal SRAM ???
-+	tmp3--;
-+	if (tmp3 != 0) {
-+		SRAM_setSize(adapter, 0x10000);
-+		SRAM_init(adapter);
-+		WriteRegDW(adapter, 0x208, tmp);
-+
-+		dprintk("%s: sram size = 32K\n", __FUNCTION__);
-+
-+		return 32;
-+	}
-+
-+	if (SRAM_testLocation(adapter, 0x20000, 0x18000) != 0) {
-+		SRAM_setSize(adapter, 0x20000);
-+		SRAM_init(adapter);
-+		WriteRegDW(adapter, 0x208, tmp);
-+
-+		dprintk("%s: sram size = 128K\n", __FUNCTION__);
-+
-+		return 128;
-+	}
-+
-+	if (SRAM_testLocation(adapter, 0x00000, 0x10000) != 0) {
-+		SRAM_setSize(adapter, 0x00000);
-+		SRAM_init(adapter);
-+		WriteRegDW(adapter, 0x208, tmp);
-+
-+		dprintk("%s: sram size = 64K\n", __FUNCTION__);
-+
-+		return 64;
-+	}
-+
-+	if (SRAM_testLocation(adapter, 0x10000, 0x00000) != 0) {
-+		SRAM_setSize(adapter, 0x10000);
-+		SRAM_init(adapter);
-+		WriteRegDW(adapter, 0x208, tmp);
-+
-+		dprintk("%s: sram size = 32K\n", __FUNCTION__);
-+
-+		return 32;
-+	}
-+
-+	SRAM_setSize(adapter, 0x10000);
-+	SRAM_init(adapter);
-+	WriteRegDW(adapter, 0x208, tmp);
-+
-+	dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
-+
-+	return 0;
-+}
-+
-+static void SLL_detectSramSize(struct adapter *adapter)
-+{
-+	SramDetectForFlex2(adapter);
-+}
-+/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
-+/*
-+static int EEPROM_write(struct adapter *adapter, u16 addr, u8 * buf, u16 len)
-+{
-+	return FLEXI2C_write(adapter, 0x20000000, 0x50, addr, buf, len);
-+}
-+*/
-+
-+static int EEPROM_read(struct adapter *adapter, u16 addr, u8 * buf, u16 len)
-+{
-+	return FLEXI2C_read(adapter, 0x20000000, 0x50, addr, buf, len);
-+}
-+
-+u8 calc_LRC(u8 * buf, u32 len)
-+{
-+	u32 i;
-+	u8 sum;
-+
-+	sum = 0;
-+
-+	for (i = 0; i < len; i++)
-+		sum = sum ^ buf[i];
-+
-+	return sum;
-+}
-+
-+static int EEPROM_LRC_read(struct adapter *adapter, u32 addr, u32 len, u8 * buf, u32 retries)
-+{
-+	int i;
-+
-+	for (i = 0; i < retries; i++) {
-+		if (EEPROM_read(adapter, addr, buf, len) == len) {
-+			if (calc_LRC(buf, len - 1) == buf[len - 1])
-+				return 1;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+/*
-+static int EEPROM_LRC_write(struct adapter *adapter, u32 addr, u32 len, u8 * wbuf, u8 * rbuf, u32 retries)
-+{
-+	int i;
-+
-+	for (i = 0; i < retries; i++) {
-+		if (EEPROM_write(adapter, addr, wbuf, len) == len) {
-+			if (EEPROM_LRC_read(adapter, addr, len, rbuf, retries) == 1)
-+				return 1;
-+		}
-+	}
-+
-+	return 0;
-+}
-+*/
-+
-+/* These functions could be called from the initialization routine 
-+   to unlock SkyStar2 cards, locked by "Europe On Line".
-+        
-+   in cards from "Europe On Line" the key is:
-+
-+       u8 key[20] = {
-+ 	    0xB2, 0x01, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+       };
-+
-+       LRC = 0xB3;
-+
-+  in unlocked cards the key is:
-+
-+       u8 key[20] = {
-+ 	    0xB2, 0x00, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+ 	    0x00, 0x00, 0x00, 0x00,
-+       };
-+
-+      LRC = 0xB2;
-+*/
-+/*
-+static int EEPROM_writeKey(struct adapter *adapter, u8 * key, u32 len)
-+{
-+	u8 rbuf[20];
-+	u8 wbuf[20];
-+
-+	if (len != 16)
-+		return 0;
-+
-+	memcpy(wbuf, key, len);
-+
-+	wbuf[16] = 0;
-+	wbuf[17] = 0;
-+	wbuf[18] = 0;
-+	wbuf[19] = calc_LRC(wbuf, 19);
-+
-+	return EEPROM_LRC_write(adapter, 0x3E4, 20, wbuf, rbuf, 4);
-+}
-+*/
-+static int EEPROM_readKey(struct adapter *adapter, u8 * key, u32 len)
-+{
-+	u8 buf[20];
-+
-+	if (len != 16)
-+		return 0;
-+
-+	if (EEPROM_LRC_read(adapter, 0x3E4, 20, buf, 4) == 0)
-+		return 0;
-+
-+	memcpy(key, buf, len);
-+
-+	return 1;
-+}
-+
-+static int EEPROM_getMacAddr(struct adapter *adapter, char type, u8 * mac)
-+{
-+	u8 tmp[8];
-+
-+	if (EEPROM_LRC_read(adapter, 0x3F8, 8, tmp, 4) != 0) {
-+		if (type != 0) {
-+			mac[0] = tmp[0];
-+			mac[1] = tmp[1];
-+			mac[2] = tmp[2];
-+			mac[3] = 0xFE;
-+			mac[4] = 0xFF;
-+			mac[5] = tmp[3];
-+			mac[6] = tmp[4];
-+			mac[7] = tmp[5];
-+
-+		} else {
-+
-+			mac[0] = tmp[0];
-+			mac[1] = tmp[1];
-+			mac[2] = tmp[2];
-+			mac[3] = tmp[3];
-+			mac[4] = tmp[4];
-+			mac[5] = tmp[5];
-+		}
-+
-+		return 1;
-+
-+	} else {
-+
-+		if (type == 0) {
-+			memset(mac, 0, 6);
-+
-+		} else {
-+
-+			memset(mac, 0, 8);
-+		}
-+
-+		return 0;
-+	}
-+}
-+
-+/*
-+static char EEPROM_setMacAddr(struct adapter *adapter, char type, u8 * mac)
-+{
-+	u8 tmp[8];
-+
-+	if (type != 0) {
-+		tmp[0] = mac[0];
-+		tmp[1] = mac[1];
-+		tmp[2] = mac[2];
-+		tmp[3] = mac[5];
-+		tmp[4] = mac[6];
-+		tmp[5] = mac[7];
-+
-+	} else {
-+
-+		tmp[0] = mac[0];
-+		tmp[1] = mac[1];
-+		tmp[2] = mac[2];
-+		tmp[3] = mac[3];
-+		tmp[4] = mac[4];
-+		tmp[5] = mac[5];
-+	}
-+
-+	tmp[6] = 0;
-+	tmp[7] = calc_LRC(tmp, 7);
-+
-+	if (EEPROM_write(adapter, 0x3F8, tmp, 8) == 8)
-+		return 1;
-+
-+	return 0;
-+}
-+*/
-+
-+/* PID filter */
-+static void FilterEnableStream1Filter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000001, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000001);
-+	}
-+}
-+
-+static void FilterEnableStream2Filter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000002, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000002);
-+	}
-+}
-+
-+static void FilterEnablePcrFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000004, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000004);
-+	}
-+}
-+
-+static void FilterEnablePmtFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000008, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000008);
-+	}
-+}
-+
-+static void FilterEnableEmmFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000010, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000010);
-+	}
-+}
-+
-+static void FilterEnableEcmFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000020, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000020);
-+	}
-+}
-+
-+/*
-+static void FilterEnableNullFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000040, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000040);
-+	}
-+}
-+*/
-+
-+static void FilterEnableMaskFilter(struct adapter *adapter, u32 op)
-+{
-+	dprintk("%s: op=%x\n", __FUNCTION__, op);
-+
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000080, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000080);
-+	}
-+}
-+
-+
-+static void CtrlEnableMAC(struct adapter *adapter, u32 op)
-+{
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00004000, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00004000);
-+	}
-+}
-+
-+static int CASetMacDstAddrFilter(struct adapter *adapter, u8 * mac)
-+{
-+	u32 tmp1, tmp2;
-+
-+	tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
-+	tmp2 = (mac[5] << 0x08) | mac[4];
-+
-+	WriteRegDW(adapter, 0x418, tmp1);
-+	WriteRegDW(adapter, 0x41C, tmp2);
-+
-+	return 0;
-+}
-+
-+/*
-+static void SetIgnoreMACFilter(struct adapter *adapter, u8 op)
-+{
-+	if (op != 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00004000, 0);
-+
-+		adapter->mac_filter = 1;
-+
-+	} else {
-+
-+		if (adapter->mac_filter != 0) {
-+			adapter->mac_filter = 0;
-+
-+			WriteRegOp(adapter, 0x208, 1, 0, 0x00004000);
-+		}
-+	}
-+}
-+*/
-+
-+/*
-+static void CheckNullFilterEnable(struct adapter *adapter)
-+{
-+	FilterEnableNullFilter(adapter, 1);
-+	FilterEnableMaskFilter(adapter, 1);
-+}
-+*/
-+
-+static void InitPIDsInfo(struct adapter *adapter)
-+{
-+	int i;
-+
-+	for (i = 0; i < 0x27; i++)
-+		adapter->pids[i] = 0x1FFF;
-+}
-+
-+static int CheckPID(struct adapter *adapter, u16 pid)
-+{
-+	u32 i;
-+
-+	if (pid == 0x1FFF)
-+		return 0;
-+
-+	for (i = 0; i < 0x27; i++) {
-+		if (adapter->pids[i] == pid)
-+			return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+static void PidSetGroupPID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x30C) & 0xFFFF0000);
-+
-+	WriteRegDW(adapter, 0x30C, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetGroupMASK(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x30C) & 0xFFFF);
-+
-+	WriteRegDW(adapter, 0x30C, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetStream1PID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x300) & 0xFFFFC000);
-+
-+	WriteRegDW(adapter, 0x300, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetStream2PID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x300) & 0xFFFF);
-+
-+	WriteRegDW(adapter, 0x300, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetPcrPID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x304) & 0xFFFFC000);
-+
-+	WriteRegDW(adapter, 0x304, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetPmtPID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x304) & 0x3FFF);
-+
-+	WriteRegDW(adapter, 0x304, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetEmmPID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = (pid & 0xFFFF) | (ReadRegDW(adapter, 0x308) & 0xFFFF0000);
-+
-+	WriteRegDW(adapter, 0x308, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static void PidSetEcmPID(struct adapter * adapter, u32 pid)
-+{
-+	u32 value;
-+
-+	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-+
-+	value = (pid << 0x10) | (ReadRegDW(adapter, 0x308) & 0xFFFF);
-+
-+	WriteRegDW(adapter, 0x308, value);
-+
-+	/* return value is never used? */
-+/*	return value; */
-+}
-+
-+static int PidGetStream1PID(struct adapter * adapter)
-+{
-+	return ReadRegDW(adapter, 0x300) & 0x00001FFF;
-+}
-+
-+static int PidGetStream2PID(struct adapter * adapter)
-+{
-+	return (ReadRegDW(adapter, 0x300) >> 0x10)& 0x00001FFF;
-+}
-+
-+static int PidGetPcrPID(struct adapter * adapter)
-+{
-+	return ReadRegDW(adapter, 0x304) & 0x00001FFF;
-+}
-+
-+static int PidGetPmtPID(struct adapter * adapter)
-+{
-+	return (ReadRegDW(adapter, 0x304) >> 0x10)& 0x00001FFF;
-+}
-+
-+static int PidGetEmmPID(struct adapter * adapter)
-+{
-+	return ReadRegDW(adapter, 0x308) & 0x00001FFF;
-+}
-+
-+static int PidGetEcmPID(struct adapter * adapter)
-+{
-+	return (ReadRegDW(adapter, 0x308) >> 0x10)& 0x00001FFF;
-+}
-+
-+static int PidGetGroupPID(struct adapter * adapter)
-+{
-+	return ReadRegDW(adapter, 0x30C) & 0x00001FFF;
-+}
-+
-+static int PidGetGroupMASK(struct adapter * adapter)
-+{
-+	return (ReadRegDW(adapter, 0x30C) >> 0x10)& 0x00001FFF;
-+}
-+
-+/*
-+static void ResetHardwarePIDFilter(struct adapter *adapter)
-+{
-+	PidSetStream1PID(adapter, 0x1FFF);
-+
-+	PidSetStream2PID(adapter, 0x1FFF);
-+	FilterEnableStream2Filter(adapter, 0);
-+
-+	PidSetPcrPID(adapter, 0x1FFF);
-+	FilterEnablePcrFilter(adapter, 0);
-+
-+	PidSetPmtPID(adapter, 0x1FFF);
-+	FilterEnablePmtFilter(adapter, 0);
-+
-+	PidSetEcmPID(adapter, 0x1FFF);
-+	FilterEnableEcmFilter(adapter, 0);
-+
-+	PidSetEmmPID(adapter, 0x1FFF);
-+	FilterEnableEmmFilter(adapter, 0);
-+}
-+*/
-+
-+static void OpenWholeBandwidth(struct adapter *adapter)
-+{
-+	PidSetGroupPID(adapter, 0);
-+
-+	PidSetGroupMASK(adapter, 0);
-+
-+	FilterEnableMaskFilter(adapter, 1);
-+}
-+
-+static int AddHwPID(struct adapter *adapter, u32 pid)
-+{
-+	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-+
-+	if (pid <= 0x1F)
-+		return 1;
-+
-+	if ((PidGetGroupMASK(adapter) == 0) && (PidGetGroupPID(adapter) == 0))
-+		return 0;
-+
-+	if (PidGetStream1PID(adapter) == 0x1FFF) {
-+		PidSetStream1PID(adapter, pid & 0xFFFF);
-+
-+		FilterEnableStream1Filter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetStream2PID(adapter) == 0x1FFF) {
-+		PidSetStream2PID(adapter, (pid & 0xFFFF));
-+
-+		FilterEnableStream2Filter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetPcrPID(adapter) == 0x1FFF) {
-+		PidSetPcrPID(adapter, (pid & 0xFFFF));
-+
-+		FilterEnablePcrFilter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	if ((PidGetPmtPID(adapter) & 0x1FFF) == 0x1FFF) {
-+		PidSetPmtPID(adapter, (pid & 0xFFFF));
-+
-+		FilterEnablePmtFilter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	if ((PidGetEmmPID(adapter) & 0x1FFF) == 0x1FFF) {
-+		PidSetEmmPID(adapter, (pid & 0xFFFF));
-+
-+		FilterEnableEmmFilter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	if ((PidGetEcmPID(adapter) & 0x1FFF) == 0x1FFF) {
-+		PidSetEcmPID(adapter, (pid & 0xFFFF));
-+
-+		FilterEnableEcmFilter(adapter, 1);
-+
-+		return 1;
-+	}
-+
-+	return -1;
-+}
-+
-+static int RemoveHwPID(struct adapter *adapter, u32 pid)
-+{
-+	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-+
-+	if (pid <= 0x1F)
-+		return 1;
-+
-+	if (PidGetStream1PID(adapter) == pid) {
-+		PidSetStream1PID(adapter, 0x1FFF);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetStream2PID(adapter) == pid) {
-+		PidSetStream2PID(adapter, 0x1FFF);
-+
-+		FilterEnableStream2Filter(adapter, 0);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetPcrPID(adapter) == pid) {
-+		PidSetPcrPID(adapter, 0x1FFF);
-+
-+		FilterEnablePcrFilter(adapter, 0);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetPmtPID(adapter) == pid) {
-+		PidSetPmtPID(adapter, 0x1FFF);
-+
-+		FilterEnablePmtFilter(adapter, 0);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetEmmPID(adapter) == pid) {
-+		PidSetEmmPID(adapter, 0x1FFF);
-+
-+		FilterEnableEmmFilter(adapter, 0);
-+
-+		return 1;
-+	}
-+
-+	if (PidGetEcmPID(adapter) == pid) {
-+		PidSetEcmPID(adapter, 0x1FFF);
-+
-+		FilterEnableEcmFilter(adapter, 0);
-+
-+		return 1;
-+	}
-+
-+	return -1;
-+}
-+
-+static int AddPID(struct adapter *adapter, u32 pid)
-+{
-+	int i;
-+
-+	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-+
-+	if (pid > 0x1FFE)
-+		return -1;
-+
-+	if (CheckPID(adapter, pid) == 1)
-+		return 1;
-+
-+	for (i = 0; i < 0x27; i++) {
-+		if (adapter->pids[i] == 0x1FFF)	// find free pid filter
-+		{
-+			adapter->pids[i] = pid;
-+
-+			if (AddHwPID(adapter, pid) < 0)
-+				OpenWholeBandwidth(adapter);
-+
-+			return 1;
-+		}
-+	}
-+
-+	return -1;
-+}
-+
-+static int RemovePID(struct adapter *adapter, u32 pid)
-+{
-+	u32 i;
-+
-+	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-+
-+	if (pid > 0x1FFE)
-+		return -1;
-+
-+	for (i = 0; i < 0x27; i++) {
-+		if (adapter->pids[i] == pid) {
-+			adapter->pids[i] = 0x1FFF;
-+
-+			RemoveHwPID(adapter, pid);
-+
-+			return 1;
-+		}
-+	}
-+
-+	return -1;
-+}
-+
-+/* dma & irq */
-+static void CtrlEnableSmc(struct adapter *adapter, u32 op)
-+{
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00000800, 0);
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00000800);
-+	}
-+}
-+
-+static void DmaEnableDisableIrq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
-+{
-+	adapter->dma_ctrl = adapter->dma_ctrl & 0x000F0000;
-+
-+	if (flag1 == 0) {
-+		if (flag2 == 0)
-+			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
-+		else
-+			adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
-+
-+		if (flag3 == 0)
-+			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
-+		else
-+			adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
-+
-+	} else {
-+
-+		if (flag2 == 0)
-+			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
-+		else
-+			adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
-+
-+		if (flag3 == 0)
-+			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
-+		else
-+			adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
-+	}
-+}
-+
-+static void IrqDmaEnableDisableIrq(struct adapter * adapter, u32 op)
-+{
-+	u32 value;
-+
-+	value = ReadRegDW(adapter, 0x208) & 0xFFF0FFFF;
-+
-+	if (op != 0)
-+		value = value | (adapter->dma_ctrl & 0x000F0000);
-+
-+	WriteRegDW(adapter, 0x208, value);
-+}
-+
-+/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
-+   system memory.
-+
-+   The DMA1 buffer is divided in 2 subbuffers of equal size.
-+   FlexCopII will transfer TS data to one subbuffer, signal an interrupt
-+   when the subbuffer is full and continue fillig the second subbuffer.
-+
-+   For DMA1:
-+       subbuffer size in 32-bit words is stored in the first 24 bits of
-+       register 0x004. The last 8 bits of register 0x004 contain the number
-+       of subbuffers.
-+       
-+       the first 30 bits of register 0x000 contain the address of the first
-+       subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
-+       when dma1 is enabled.
-+
-+       the first 30 bits of register 0x00C contain the address of the second
-+       subbuffer. the last 2 bits contain 1.
-+
-+       register 0x008 will contain the address of the subbuffer that was filled
-+       with TS data, when FlexCopII will generate an interrupt.
-+
-+   For DMA2:
-+       subbuffer size in 32-bit words is stored in the first 24 bits of
-+       register 0x014. The last 8 bits of register 0x014 contain the number
-+       of subbuffers.
-+       
-+       the first 30 bits of register 0x010 contain the address of the first
-+       subbuffer.  The last 2 bits contain 0, when dma1 is disabled and 1,
-+       when dma1 is enabled.
-+
-+       the first 30 bits of register 0x01C contain the address of the second
-+       subbuffer. the last 2 bits contain 1.
-+
-+       register 0x018 contains the address of the subbuffer that was filled
-+       with TS data, when FlexCopII generates an interrupt.
-+*/
-+static int DmaInitDMA(struct adapter *adapter, u32 dma_channel)
-+{
-+	u32 subbuffers, subbufsize, subbuf0, subbuf1;
-+
-+	if (dma_channel == 0) {
-+		dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
-+
-+		subbuffers = 2;
-+
-+		subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
-+
-+		subbuf0 = adapter->dmaq1.bus_addr & 0xFFFFFFFC;
-+
-+		subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xFFFFFFFC) | 1;
-+
-+		dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x000, subbuf0);
-+
-+		dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x004, subbufsize);
-+
-+		dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x00C, subbuf1);
-+
-+		dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xFFFFFFFC);
-+		WriteRegDW(adapter, 0x008, adapter->dmaq1.bus_addr & 0xFFFFFFFC);
-+		udelay(1000);
-+
-+		if (subbuffers == 0)
-+			DmaEnableDisableIrq(adapter, 0, 1, 0);
-+		else
-+			DmaEnableDisableIrq(adapter, 0, 1, 1);
-+
-+		IrqDmaEnableDisableIrq(adapter, 1);
-+
-+		SRAMSetMediaDest(adapter, 1);
-+		SRAMSetNetDest(adapter, 1);
-+		SRAMSetCaiDest(adapter, 2);
-+		SRAMSetCaoDest(adapter, 2);
-+	}
-+
-+	if (dma_channel == 1) {
-+		dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
-+
-+		subbuffers = 2;
-+
-+		subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
-+
-+		subbuf0 = adapter->dmaq2.bus_addr & 0xFFFFFFFC;
-+
-+		subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xFFFFFFFC) | 1;
-+
-+		dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x010, subbuf0);
-+
-+		dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x014, subbufsize);
-+
-+		dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
-+		udelay(1000);
-+		WriteRegDW(adapter, 0x01C, subbuf1);
-+
-+		SRAMSetCaiDest(adapter, 2);
-+	}
-+
-+	return 0;
-+}
-+
-+static void CtrlEnableReceiveData(struct adapter *adapter, u32 op)
-+{
-+	if (op == 0) {
-+		WriteRegOp(adapter, 0x208, 2, ~0x00008000, 0);
-+
-+		adapter->dma_status = adapter->dma_status & ~0x00000004;
-+
-+	} else {
-+
-+		WriteRegOp(adapter, 0x208, 1, 0, 0x00008000);
-+
-+		adapter->dma_status = adapter->dma_status | 0x00000004;
-+	}
-+}
-+
-+/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
-+   bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
-+*/
-+static void DmaStartStop0x2102(struct adapter *adapter, u32 dma_mask, u32 start_stop)
-+{
-+	u32 dma_enable, dma1_enable, dma2_enable;
-+
-+	dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
-+
-+	if (start_stop == 1) {
-+		dprintk("%s: starting dma\n", __FUNCTION__);
-+
-+		dma1_enable = 0;
-+		dma2_enable = 0;
-+
-+		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
-+			adapter->dma_status = adapter->dma_status | 1;
-+			dma1_enable = 1;
-+		}
-+
-+		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
-+			adapter->dma_status = adapter->dma_status | 2;
-+			dma2_enable = 1;
-+		}
-+		// enable dma1 and dma2
-+		if ((dma1_enable == 1) && (dma2_enable == 1)) {
-+			WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
-+			WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-+			WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-+
-+			CtrlEnableReceiveData(adapter, 1);
-+
-+			return;
-+		}
-+		// enable dma1
-+		if ((dma1_enable == 1) && (dma2_enable == 0)) {
-+			WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
-+			WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-+
-+			CtrlEnableReceiveData(adapter, 1);
-+
-+			return;
-+		}
-+		// enable dma2
-+		if ((dma1_enable == 0) && (dma2_enable == 1)) {
-+			WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-+
-+			CtrlEnableReceiveData(adapter, 1);
-+
-+			return;
-+		}
-+		// start dma
-+		if ((dma1_enable == 0) && (dma2_enable == 0)) {
-+			CtrlEnableReceiveData(adapter, 1);
-+
-+			return;
-+		}
-+
-+	} else {
-+
-+		dprintk("%s: stoping dma\n", __FUNCTION__);
-+
-+		dma_enable = adapter->dma_status & 0x00000003;
-+
-+		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
-+			dma_enable = dma_enable & 0xFFFFFFFE;
-+		}
-+
-+		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
-+			dma_enable = dma_enable & 0xFFFFFFFD;
-+		}
-+		//stop dma
-+		if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
-+			CtrlEnableReceiveData(adapter, 0);
-+
-+			udelay(3000);
-+		}
-+		//disable dma1
-+		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
-+			WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr);
-+			WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-+
-+			adapter->dma_status = adapter->dma_status & ~0x00000001;
-+		}
-+		//disable dma2
-+		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
-+			WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr);
-+
-+			adapter->dma_status = adapter->dma_status & ~0x00000002;
-+		}
-+	}
-+}
-+
-+static void OpenStream(struct adapter *adapter, u32 pid)
-+{
-+	u32 dma_mask;
-+
-+	if (adapter->capturing == 0)
-+		adapter->capturing = 1;
-+
-+	FilterEnableMaskFilter(adapter, 1);
-+
-+	AddPID(adapter, pid);
-+
-+	dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-+
-+	if ((adapter->dma_status & 7) != 7) {
-+		dma_mask = 0;
-+
-+		if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
-+			dma_mask = dma_mask | 1;
-+
-+			adapter->dmaq1.head = 0;
-+			adapter->dmaq1.tail = 0;
-+
-+			memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
-+		}
-+
-+		if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
-+			dma_mask = dma_mask | 2;
-+
-+			adapter->dmaq2.head = 0;
-+			adapter->dmaq2.tail = 0;
-+		}
-+
-+		if (dma_mask != 0) {
-+			IrqDmaEnableDisableIrq(adapter, 1);
-+
-+			DmaStartStop0x2102(adapter, dma_mask, 1);
-+		}
-+	}
-+}
-+
-+static void CloseStream(struct adapter *adapter, u32 pid)
-+{
-+	u32 dma_mask;
-+
-+	if (adapter->capturing != 0)
-+		adapter->capturing = 0;
-+
-+	dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-+
-+	dma_mask = 0;
-+
-+	if ((adapter->dma_status & 1) != 0)
-+		dma_mask = dma_mask | 0x00000001;
-+	if ((adapter->dma_status & 2) != 0)
-+		dma_mask = dma_mask | 0x00000002;
-+
-+	if (dma_mask != 0) {
-+		DmaStartStop0x2102(adapter, dma_mask, 0);
-+	}
-+
-+	RemovePID(adapter, pid);
-+}
-+
-+static void InterruptServiceDMA1(struct adapter *adapter)
-+{
-+	struct dvb_demux *dvbdmx = &adapter->demux;
-+	struct packet_header packet_header;
-+
-+	int nCurDmaCounter;
-+	u32 nNumBytesParsed;
-+	u32 nNumNewBytesTransferred;
-+	u32 dwDefaultPacketSize = 188;
-+	u8 gbTmpBuffer[188];
-+	u8 *pbDMABufCurPos;
-+
-+	nCurDmaCounter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
-+	nCurDmaCounter = (nCurDmaCounter / dwDefaultPacketSize) * dwDefaultPacketSize;
-+
-+	if ((nCurDmaCounter < 0) || (nCurDmaCounter > adapter->dmaq1.buffer_size)) {
-+		dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
-+		return;
-+	}
-+
-+	adapter->dmaq1.head = nCurDmaCounter;
-+
-+	if (adapter->dmaq1.tail <= nCurDmaCounter) {
-+		nNumNewBytesTransferred = nCurDmaCounter - adapter->dmaq1.tail;
-+
-+	} else {
-+
-+		nNumNewBytesTransferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + nCurDmaCounter;
-+	}
-+
-+//  dprintk("%s: nCurDmaCounter   = %d\n" , __FUNCTION__, nCurDmaCounter);
-+//	dprintk("%s: dmaq1.tail       = %d\n" , __FUNCTION__, adapter->dmaq1.tail):
-+//  dprintk("%s: BytesTransferred = %d\n" , __FUNCTION__, nNumNewBytesTransferred);
-+
-+	if (nNumNewBytesTransferred < dwDefaultPacketSize)
-+		return;
-+
-+	nNumBytesParsed = 0;
-+
-+	while (nNumBytesParsed < nNumNewBytesTransferred) {
-+		pbDMABufCurPos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
-+
-+		if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
-+			memcpy(gbTmpBuffer, adapter->dmaq1.buffer + adapter->dmaq1.tail, adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
-+			memcpy(gbTmpBuffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer, (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
-+
-+			pbDMABufCurPos = gbTmpBuffer;
-+		}
-+
-+		if (adapter->capturing != 0) {
-+			u32 *dq = (u32 *) pbDMABufCurPos;
-+
-+			packet_header.sync_byte = *dq & 0x000000FF;
-+			packet_header.transport_error_indicator = *dq & 0x00008000;
-+			packet_header.payload_unit_start_indicator = *dq & 0x00004000;
-+			packet_header.transport_priority = *dq & 0x00002000;
-+			packet_header.pid = ((*dq & 0x00FF0000) >> 0x10) | (*dq & 0x00001F00);
-+			packet_header.transport_scrambling_control = *dq >> 0x1E;
-+			packet_header.adaptation_field_control = (*dq & 0x30000000) >> 0x1C;
-+			packet_header.continuity_counter = (*dq & 0x0F000000) >> 0x18;
-+
-+			if ((packet_header.sync_byte == 0x47) && (packet_header.transport_error_indicator == 0) && (packet_header.pid != 0x1FFF)) {
-+				if (CheckPID(adapter, packet_header.pid & 0x0000FFFF) != 0) {
-+					dvb_dmx_swfilter_packets(dvbdmx, pbDMABufCurPos, dwDefaultPacketSize / 188);
-+
-+				} else {
-+
-+//                  dprintk("%s: pid=%x\n", __FUNCTION__, packet_header.pid);
-+				}
-+			}
-+		}
-+
-+		nNumBytesParsed = nNumBytesParsed + dwDefaultPacketSize;
-+
-+		adapter->dmaq1.tail = adapter->dmaq1.tail + dwDefaultPacketSize;
-+
-+		if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
-+			adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
-+	};
-+}
-+
-+static void InterruptServiceDMA2(struct adapter *adapter)
-+{
-+	printk("%s:\n", __FUNCTION__);
-+}
-+
-+static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+	struct adapter *tmp = dev_id;
-+
-+	u32 value;
-+
-+//  dprintk("%s:\n", __FUNCTION__);
-+
-+	spin_lock_irq(&tmp->lock);
-+
-+	if (0 == ((value = ReadRegDW(tmp, 0x20C)) & 0x0F)) {
-+		spin_unlock_irq(&tmp->lock);
-+		return IRQ_NONE;
-+	}
-+	
-+	while (value != 0) {
-+		if ((value & 0x03) != 0)
-+			InterruptServiceDMA1(tmp);
-+		if ((value & 0x0C) != 0)
-+			InterruptServiceDMA2(tmp);
-+		value = ReadRegDW(tmp, 0x20C) & 0x0F;
-+	}
-+
-+	spin_unlock_irq(&tmp->lock);
-+	return IRQ_HANDLED;
-+}
-+
-+static void Initdmaqueue(struct adapter *adapter)
-+{
-+	dma_addr_t dma_addr;
-+
-+	if (adapter->dmaq1.buffer != 0)
-+		return;
-+
-+	adapter->dmaq1.head = 0;
-+	adapter->dmaq1.tail = 0;
-+	adapter->dmaq1.buffer = 0;
-+
-+	adapter->dmaq1.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA1 + 0x80, &dma_addr);
-+
-+	if (adapter->dmaq1.buffer != 0) {
-+		memset(adapter->dmaq1.buffer, 0, SizeOfBufDMA1);
-+
-+		adapter->dmaq1.bus_addr = dma_addr;
-+		adapter->dmaq1.buffer_size = SizeOfBufDMA1;
-+
-+		DmaInitDMA(adapter, 0);
-+
-+		adapter->dma_status = adapter->dma_status | 0x10000000;
-+
-+		dprintk("%s: allocated dma buffer at 0x%x, length=%d\n", __FUNCTION__, (int) adapter->dmaq1.buffer, SizeOfBufDMA1);
-+
-+	} else {
-+
-+		adapter->dma_status = adapter->dma_status & ~0x10000000;
-+	}
-+
-+	if (adapter->dmaq2.buffer != 0)
-+		return;
-+
-+	adapter->dmaq2.head = 0;
-+	adapter->dmaq2.tail = 0;
-+	adapter->dmaq2.buffer = 0;
-+
-+	adapter->dmaq2.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA2 + 0x80, &dma_addr);
-+
-+	if (adapter->dmaq2.buffer != 0) {
-+		memset(adapter->dmaq2.buffer, 0, SizeOfBufDMA2);
-+
-+		adapter->dmaq2.bus_addr = dma_addr;
-+		adapter->dmaq2.buffer_size = SizeOfBufDMA2;
-+
-+		DmaInitDMA(adapter, 1);
-+
-+		adapter->dma_status = adapter->dma_status | 0x20000000;
-+
-+		dprintk("%s: allocated dma buffer at 0x%x, length=%d\n", __FUNCTION__, (int) adapter->dmaq2.buffer, (int) SizeOfBufDMA2);
-+
-+	} else {
-+
-+		adapter->dma_status = adapter->dma_status & ~0x20000000;
-+	}
-+}
-+
-+static void Freedmaqueue(struct adapter *adapter)
-+{
-+	if (adapter->dmaq1.buffer != 0) {
-+		pci_free_consistent(adapter->pdev, SizeOfBufDMA1 + 0x80, adapter->dmaq1.buffer, adapter->dmaq1.bus_addr);
-+
-+		adapter->dmaq1.bus_addr = 0;
-+		adapter->dmaq1.head = 0;
-+		adapter->dmaq1.tail = 0;
-+		adapter->dmaq1.buffer_size = 0;
-+		adapter->dmaq1.buffer = 0;
-+	}
-+
-+	if (adapter->dmaq2.buffer != 0) {
-+		pci_free_consistent(adapter->pdev, SizeOfBufDMA2 + 0x80, adapter->dmaq2.buffer, adapter->dmaq2.bus_addr);
-+
-+		adapter->dmaq2.bus_addr = 0;
-+		adapter->dmaq2.head = 0;
-+		adapter->dmaq2.tail = 0;
-+		adapter->dmaq2.buffer_size = 0;
-+		adapter->dmaq2.buffer = 0;
-+	}
-+}
-+
-+static void FreeAdapterObject(struct adapter *adapter)
-+{
-+	dprintk("%s:\n", __FUNCTION__);
-+
-+	CloseStream(adapter, 0);
-+
-+	if (adapter->irq != 0)
-+		free_irq(adapter->irq, adapter);
-+
-+	Freedmaqueue(adapter);
-+
-+	if (adapter->io_mem != 0)
-+		iounmap((void *) adapter->io_mem);
-+
-+	if (adapter != 0)
-+		kfree(adapter);
-+}
-+
-+static struct pci_driver skystar2_pci_driver;
-+
-+static int ClaimAdapter(struct adapter *adapter)
-+{
-+	struct pci_dev *pdev = adapter->pdev;
-+
-+	u16 var;
-+
-+	if (!request_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1), skystar2_pci_driver.name))
-+		return -EBUSY;
-+
-+	if (!request_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0), skystar2_pci_driver.name))
-+		return -EBUSY;
-+
-+	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
-+
-+	dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
-+
-+	if (pci_enable_device(pdev))
-+		return -EIO;
-+
-+	pci_read_config_word(pdev, 4, &var);
-+
-+	if ((var & 4) == 0)
-+		pci_set_master(pdev);
-+
-+	adapter->io_port = pdev->resource[1].start;
-+
-+	adapter->io_mem = (u32) ioremap(pdev->resource[0].start, 0x800);
-+
-+	if (adapter->io_mem == 0) {
-+		dprintk("%s: can not map io memory\n", __FUNCTION__);
-+
-+		return 2;
-+	}
-+
-+	dprintk("%s: io memory maped at %x\n", __FUNCTION__, adapter->io_mem);
-+
-+	return 1;
-+}
-+
-+/*
-+static int SLL_reset_FlexCOP(struct adapter *adapter)
-+{
-+	WriteRegDW(adapter, 0x208, 0);
-+	WriteRegDW(adapter, 0x210, 0xB2FF);
-+
-+	return 0;
-+}
-+*/
-+
-+static int DriverInitialize(struct pci_dev * pdev)
-+{
-+	struct adapter *adapter;
-+	u32 tmp;
-+	u8 key[16];
-+
-+	if (!(adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL))) {
-+		dprintk("%s: out of memory!\n", __FUNCTION__);
-+
-+		return -ENOMEM;
-+	}
-+
-+	memset(adapter, 0, sizeof(struct adapter));
-+
-+	pci_set_drvdata(pdev,adapter);
-+
-+	adapter->pdev = pdev;
-+	adapter->irq = pdev->irq;
-+
-+	if ((ClaimAdapter(adapter)) != 1) {
-+		FreeAdapterObject(adapter);
-+
-+		return -ENODEV;
-+	}
-+
-+	IrqDmaEnableDisableIrq(adapter, 0);
-+
-+	if (request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter) != 0) {
-+		dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
-+
-+		FreeAdapterObject(adapter);
-+
-+		return -ENODEV;
-+	}
-+
-+	ReadRegDW(adapter, 0x208);
-+	WriteRegDW(adapter, 0x208, 0);
-+	WriteRegDW(adapter, 0x210, 0xB2FF);
-+	WriteRegDW(adapter, 0x208, 0x40);
-+
-+	InitPIDsInfo(adapter);
-+
-+	PidSetGroupPID(adapter, 0);
-+	PidSetGroupMASK(adapter, 0x1FE0);
-+	PidSetStream1PID(adapter, 0x1FFF);
-+	PidSetStream2PID(adapter, 0x1FFF);
-+	PidSetPmtPID(adapter, 0x1FFF);
-+	PidSetPcrPID(adapter, 0x1FFF);
-+	PidSetEcmPID(adapter, 0x1FFF);
-+	PidSetEmmPID(adapter, 0x1FFF);
-+
-+	Initdmaqueue(adapter);
-+
-+	if ((adapter->dma_status & 0x30000000) == 0) {
-+		FreeAdapterObject(adapter);
-+
-+		return -ENODEV;
-+	}
-+
-+	adapter->b2c2_revision = (ReadRegDW(adapter, 0x204) >> 0x18);
-+
-+	if ((adapter->b2c2_revision != 0x82) && (adapter->b2c2_revision != 0xC3))
-+		if (adapter->b2c2_revision != 0x82) {
-+			dprintk("%s: The revision of the FlexCopII chip on your card is - %d\n", __FUNCTION__, adapter->b2c2_revision);
-+			dprintk("%s: This driver works now only with FlexCopII(rev.130) and FlexCopIIB(rev.195).\n", __FUNCTION__);
-+
-+			FreeAdapterObject(adapter);
-+
-+			return -ENODEV;
-+		}
-+
-+	tmp = ReadRegDW(adapter, 0x204);
-+
-+	WriteRegDW(adapter, 0x204, 0);
-+	mdelay(20);
-+
-+	WriteRegDW(adapter, 0x204, tmp);
-+	mdelay(10);
-+
-+	tmp = ReadRegDW(adapter, 0x308);
-+	WriteRegDW(adapter, 0x308, 0x4000 | tmp);
-+
-+	adapter->dwSramType = 0x10000;
-+
-+	SLL_detectSramSize(adapter);
-+
-+	dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, SRAM_length(adapter), adapter->dwSramType);
-+
-+	SRAMSetMediaDest(adapter, 1);
-+	SRAMSetNetDest(adapter, 1);
-+
-+	CtrlEnableSmc(adapter, 0);
-+
-+	SRAMSetCaiDest(adapter, 2);
-+	SRAMSetCaoDest(adapter, 2);
-+
-+	DmaEnableDisableIrq(adapter, 1, 0, 0);
-+
-+	if (EEPROM_getMacAddr(adapter, 0, adapter->mac_addr) != 0) {
-+		printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0], adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5], adapter->mac_addr[6], adapter->mac_addr[7]
-+		    );
-+
-+		CASetMacDstAddrFilter(adapter, adapter->mac_addr);
-+		CtrlEnableMAC(adapter, 1);
-+	}
-+
-+	EEPROM_readKey(adapter, key, 16);
-+
-+	printk("%s key = \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n", __FUNCTION__, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]);
-+
-+	adapter->lock = SPIN_LOCK_UNLOCKED;
-+
-+	return 0;
-+}
-+
-+static void DriverHalt(struct pci_dev *pdev)
-+{
-+	struct adapter *adapter;
-+
-+	adapter = pci_get_drvdata(pdev);
-+
-+	IrqDmaEnableDisableIrq(adapter, 0);
-+
-+	CtrlEnableReceiveData(adapter, 0);
-+
-+	FreeAdapterObject(adapter);
-+
-+	pci_set_drvdata(pdev, NULL);
-+
-+	release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-+
-+	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-+}
-+
-+static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-+	struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-+
-+	dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-+
-+	OpenStream(adapter, dvbdmxfeed->pid);
-+
-+	return 0;
-+}
-+
-+static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-+	struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-+
-+	dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-+
-+	CloseStream(adapter, dvbdmxfeed->pid);
-+
-+	return 0;
-+}
-+
-+/* lnb control */
-+static void set_tuner_tone(struct adapter *adapter, u8 tone)
-+{
-+	u16 wzHalfPeriodFor45MHz[] = { 0x01FF, 0x0154, 0x00FF, 0x00CC };
-+	u16 ax;
-+
-+	dprintk("%s: %u\n", __FUNCTION__, tone);
-+
-+	switch (tone) {
-+	case 1:
-+		ax = wzHalfPeriodFor45MHz[0];
-+		break;
-+	case 2:
-+		ax = wzHalfPeriodFor45MHz[1];
-+		break;
-+	case 3:
-+		ax = wzHalfPeriodFor45MHz[2];
-+		break;
-+	case 4:
-+		ax = wzHalfPeriodFor45MHz[3];
-+		break;
-+
-+	default:
-+		ax = 0;
-+	}
-+
-+	if (ax != 0) {
-+		WriteRegDW(adapter, 0x200, ((ax << 0x0F) + (ax & 0x7FFF)) | 0x40000000);
-+
-+	} else {
-+
-+		WriteRegDW(adapter, 0x200, 0x40FF8000);
-+	}
-+}
-+
-+static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
-+{
-+	u32 var;
-+
-+	dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
-+
-+	var = ReadRegDW(adapter, 0x204);
-+
-+	if (polarity == 0) {
-+		dprintk("%s: LNB power off\n", __FUNCTION__);
-+		var = var | 1;
-+	};
-+
-+	if (polarity == 1) {
-+		var = var & ~1;
-+		var = var & ~4;
-+	};
-+
-+	if (polarity == 2) {
-+		var = var & ~1;
-+		var = var | 4;
-+	}
-+
-+	WriteRegDW(adapter, 0x204, var);
-+}
-+
-+static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
-+{
-+	struct adapter *adapter = fe->before_after_data;
-+
-+	switch (cmd) {
-+	case FE_SLEEP:
-+		{
-+			printk("%s: FE_SLEEP\n", __FUNCTION__);
-+
-+			set_tuner_polarity(adapter, 0);
-+
-+			// return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend.
-+			return -EOPNOTSUPP;
-+		}
-+
-+	case FE_SET_VOLTAGE:
-+		{
-+			dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
-+
-+			switch ((fe_sec_voltage_t) arg) {
-+			case SEC_VOLTAGE_13:
-+
-+				printk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
-+
-+				set_tuner_polarity(adapter, 1);
-+
-+				break;
-+
-+			case SEC_VOLTAGE_18:
-+
-+				printk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
-+
-+				set_tuner_polarity(adapter, 2);
-+
-+				break;
-+
-+			default:
-+
-+				return -EINVAL;
-+			};
-+
-+			break;
-+		}
-+
-+	case FE_SET_TONE:
-+		{
-+			dprintk("%s: FE_SET_TONE\n", __FUNCTION__);
-+
-+			switch ((fe_sec_tone_mode_t) arg) {
-+			case SEC_TONE_ON:
-+
-+				printk("%s: SEC_TONE_ON, %x\n", __FUNCTION__, SEC_TONE_ON);
-+
-+				set_tuner_tone(adapter, 1);
-+
-+				break;
-+
-+			case SEC_TONE_OFF:
-+
-+				printk("%s: SEC_TONE_OFF, %x\n", __FUNCTION__, SEC_TONE_OFF);
-+
-+				set_tuner_tone(adapter, 0);
-+
-+				break;
-+
-+			default:
-+
-+				return -EINVAL;
-+			};
-+
-+			break;
-+		}
-+
-+	default:
-+
-+		return -EOPNOTSUPP;
-+	};
-+
-+	return 0;
-+}
-+
-+static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-+{
-+	struct adapter *adapter;
-+	struct dvb_adapter *dvb_adapter;
-+	struct dvb_demux *dvbdemux;
-+
-+	int ret;
-+
-+	if (pdev == NULL)
-+		return -ENODEV;
-+
-+	if (DriverInitialize(pdev) != 0)
-+		return -ENODEV;
-+
-+	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name);
-+
-+	if (dvb_adapter == NULL) {
-+		printk("%s: Error registering DVB adapter\n", __FUNCTION__);
-+
-+		DriverHalt(pdev);
-+
-+		return -ENODEV;
-+	}
-+
-+	adapter = (struct adapter *) pci_get_drvdata(pdev);
-+
-+	adapter->dvb_adapter = dvb_adapter;
-+
-+	init_MUTEX(&adapter->i2c_sem);
-+
-+	adapter->i2c_bus = dvb_register_i2c_bus(master_xfer, adapter, adapter->dvb_adapter, 0);
-+
-+	if (!adapter->i2c_bus)
-+		return -ENOMEM;
-+
-+	dvb_add_frontend_ioctls(adapter->dvb_adapter, flexcop_diseqc_ioctl, NULL, adapter);
-+
-+	dvbdemux = &adapter->demux;
-+
-+	dvbdemux->priv = (void *) adapter;
-+	dvbdemux->filternum = 32;
-+	dvbdemux->feednum = 32;
-+	dvbdemux->start_feed = dvb_start_feed;
-+	dvbdemux->stop_feed = dvb_stop_feed;
-+	dvbdemux->write_to_decoder = 0;
-+	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-+
-+	dvb_dmx_init(&adapter->demux);
-+
-+	adapter->hw_frontend.source = DMX_FRONTEND_0;
-+
-+	adapter->dmxdev.filternum = 32;
-+	adapter->dmxdev.demux = &dvbdemux->dmx;
-+	adapter->dmxdev.capabilities = 0;
-+
-+	dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
-+
-+	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-+	if (ret < 0)
-+		return ret;
-+
-+	adapter->mem_frontend.source = DMX_MEMORY_FE;
-+
-+	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
-+	if (ret < 0)
-+		return ret;
-+
-+	ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-+	if (ret < 0)
-+		return ret;
-+
-+	dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
-+	return 0;
-+}
-+
-+static void skystar2_remove(struct pci_dev *pdev)
-+{
-+	struct adapter *adapter;
-+	struct dvb_demux *dvbdemux;
-+
-+	if (pdev == NULL)
-+		return;
-+
-+	adapter = pci_get_drvdata(pdev);
-+
-+	if (adapter != NULL) {
-+		dvb_net_release(&adapter->dvbnet);
-+		dvbdemux = &adapter->demux;
-+
-+		dvbdemux->dmx.close(&dvbdemux->dmx);
-+		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-+		dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
-+
-+		dvb_dmxdev_release(&adapter->dmxdev);
-+		dvb_dmx_release(&adapter->demux);
-+
-+		if (adapter->dvb_adapter != NULL) {
-+			dvb_remove_frontend_ioctls(adapter->dvb_adapter, flexcop_diseqc_ioctl, NULL);
-+
-+			if (adapter->i2c_bus != NULL)
-+				dvb_unregister_i2c_bus(master_xfer, adapter->i2c_bus->adapter, adapter->i2c_bus->id);
-+
-+			dvb_unregister_adapter(adapter->dvb_adapter);
-+		}
-+
-+		DriverHalt(pdev);
-+	}
-+}
-+
-+static struct pci_device_id skystar2_pci_tbl[] = {
-+	{0x000013D0, 0x00002103, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000},
-+	{0,},
-+};
-+
-+static struct pci_driver skystar2_pci_driver = {
-+	.name = "Technisat SkyStar2 driver",
-+	.id_table = skystar2_pci_tbl,
-+	.probe = skystar2_probe,
-+	.remove = skystar2_remove,
-+};
-+
-+static int skystar2_init(void)
-+{
-+	return pci_module_init(&skystar2_pci_driver);
-+}
-+
-+static void skystar2_cleanup(void)
-+{
-+	pci_unregister_driver(&skystar2_pci_driver);
-+}
-+
-+module_init(skystar2_init);
-+module_exit(skystar2_cleanup);
-+
-+MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
-+MODULE_LICENSE("GPL");
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_demux.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_demux.c	2003-07-19 17:03:49.000000000 -0700
-@@ -403,13 +403,16 @@ void dvb_dmx_swfilter(struct dvb_demux *
- {
- 	int p = 0,i, j;
- 	
-+	spin_lock(&demux->lock);
-+
- 	if ((i = demux->tsbufp)) {
- 		if (count < (j=188-i)) {
- 			memcpy(&demux->tsbuf[i], buf, count);
- 			demux->tsbufp += count;
--			return;
-+			goto bailout;
- 		}
- 		memcpy(&demux->tsbuf[i], buf, j);
-+		if (demux->tsbuf[0] == 0x47)
- 		dvb_dmx_swfilter_packet(demux, demux->tsbuf);
- 		demux->tsbufp = 0;
- 		p += j;
-@@ -424,11 +427,14 @@ void dvb_dmx_swfilter(struct dvb_demux *
- 				i = count-p;
- 				memcpy(demux->tsbuf, buf+p, i);
- 				demux->tsbufp=i;
--				return;
-+				goto bailout;
- 			}
- 		} else 
- 			p++;
- 	}
-+
-+bailout:
-+	spin_unlock(&demux->lock);
- }
- 
- 
-@@ -1030,9 +1036,11 @@ static int dvbdmx_write(struct dmx_demux
- 
- 	if (down_interruptible (&dvbdemux->mutex))
- 		return -ERESTARTSYS;
--
- 	dvb_dmx_swfilter(dvbdemux, buf, count);
- 	up(&dvbdemux->mutex);
-+
-+	if (signal_pending(current))
-+		return -EINTR;
- 	return count;
- }
- 
-@@ -1110,8 +1118,8 @@ static int dvbdmx_get_pes_pids(struct dm
- 	return 0;
- }
- 
--int 
--dvb_dmx_init(struct dvb_demux *dvbdemux)
-+
-+int dvb_dmx_init(struct dvb_demux *dvbdemux)
- {
- 	int i, err;
- 	struct dmx_demux *dmx = &dvbdemux->dmx;
-@@ -1181,8 +1189,8 @@ dvb_dmx_init(struct dvb_demux *dvbdemux)
- 	return 0;
- }
- 
--int 
--dvb_dmx_release(struct dvb_demux *dvbdemux)
-+
-+int dvb_dmx_release(struct dvb_demux *dvbdemux)
- {
- 	struct dmx_demux *dmx = &dvbdemux->dmx;
- 
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvbdev.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvbdev.c	2003-07-19 17:03:49.000000000 -0700
-@@ -29,8 +29,6 @@
- #include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/slab.h>
--#include <linux/version.h>
--#include <asm/semaphore.h>
- 
- #include "dvbdev.h"
- #include "dvb_functions.h"
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvbdev.h	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvbdev.h	2003-07-19 17:03:49.000000000 -0700
-@@ -27,8 +27,9 @@
- #include <linux/types.h>
- #include <linux/poll.h>
- #include <linux/fs.h>
--#include <linux/devfs_fs_kernel.h>
- #include <linux/list.h>
-+#include <linux/version.h>
-+#include <linux/devfs_fs_kernel.h>
- 
- #define DVB_MAJOR 250
- 
-@@ -48,6 +49,7 @@ struct dvb_adapter {
- 	struct list_head list_head;
- 	struct list_head device_list;
- 	const char *name;
-+	u8 proposed_mac [6];
- };
- 
- 
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_frontend.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_frontend.c	2003-07-19 17:03:49.000000000 -0700
-@@ -263,8 +263,14 @@ static int dvb_frontend_get_event (struc
-                 if (flags & O_NONBLOCK)
-                         return -EWOULDBLOCK;
- 
-+		up(&fe->sem);
-+
-                 ret = wait_event_interruptible (events->wait_queue,
-                                                 events->eventw != events->eventr);
-+
-+        	if (down_interruptible (&fe->sem))
-+			return -ERESTARTSYS;
-+
-                 if (ret < 0)
-                         return ret;
-         }
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_functions.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_functions.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,11 +1,11 @@
- #include <linux/version.h>
--#include <linux/string.h>
--#include <linux/smp_lock.h>
--#include <linux/fs.h>
- #include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/string.h>
- #include <linux/module.h>
- #include <linux/ioctl.h>
- #include <linux/slab.h>
-+#include <linux/smp_lock.h>
- #include <asm/uaccess.h>
- 
- void dvb_kernel_thread_setup (const char *thread_name)
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_functions.h	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_functions.h	2003-07-19 17:03:49.000000000 -0700
-@@ -1,6 +1,8 @@
- #ifndef __DVB_FUNCTIONS_H__
- #define __DVB_FUNCTIONS_H__
- 
-+#include <linux/version.h>
-+
- /**
-  *  a sleeping delay function, waits i ms
-  *
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_net.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_net.c	2003-07-19 17:03:49.000000000 -0700
-@@ -24,22 +24,25 @@
-  * 
-  */
- 
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/string.h>
--#include <linux/ioctl.h>
--#include <linux/slab.h>
--#include <asm/uaccess.h>
--
- #include <linux/dvb/net.h>
-+#include <asm/uaccess.h>
- 
- #include "dvb_demux.h"
- #include "dvb_net.h"
- #include "dvb_functions.h"
- 
-+
-+#if 1
-+#define dprintk(x...) printk(x)
-+#else
-+#define dprintk(x...)
-+#endif
-+
-+
- #define DVB_NET_MULTICAST_MAX 10
- 
- struct dvb_net_priv {
-+	int in_use;
-         struct net_device_stats stats;
-         char name[6];
- 	u16 pid;
-@@ -49,10 +52,17 @@ struct dvb_net_priv {
- 	int multi_num;
- 	struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
- 	unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
--	int mode;
-+	int rx_mode;
-+#define RX_MODE_UNI 0
-+#define RX_MODE_MULTI 1
-+#define RX_MODE_ALL_MULTI 2
-+#define RX_MODE_PROMISC 3
-+	struct work_struct set_multicast_list_wq;
-+	struct work_struct restart_net_feed_wq;
- };
- 
--/*
-+
-+/**
-  *	Determine the packet's protocol ID. The rule here is that we 
-  *	assume 802.3 if the type field is short enough to be a length.
-  *	This is normal practice and works for any 'now in use' protocol.
-@@ -60,8 +70,8 @@ struct dvb_net_priv {
-  *  stolen from eth.c out of the linux kernel, hacked for dvb-device
-  *  by Michael Holzt <kju@debian.org>
-  */
-- 
--unsigned short my_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
-+static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
-+				      struct net_device *dev)
- {
- 	struct ethhdr *eth;
- 	unsigned char *rawp;
-@@ -70,8 +80,7 @@ unsigned short my_eth_type_trans(struct 
- 	skb_pull(skb,dev->hard_header_len);
- 	eth= skb->mac.ethernet;
- 	
--	if(*eth->h_dest&1)
--	{
-+	if (*eth->h_dest & 1) {
- 		if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
- 			skb->pkt_type=PACKET_BROADCAST;
- 		else
-@@ -83,7 +92,7 @@ unsigned short my_eth_type_trans(struct 
- 		
- 	rawp = skb->data;
- 	
--	/*
-+	/**
- 	 *	This is a magic hack to spot IPX packets. Older Novell breaks
- 	 *	the protocol design and runs IPX over 802.3 without an 802.2 LLC
- 	 *	layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-@@ -92,42 +101,73 @@ unsigned short my_eth_type_trans(struct 
- 	if (*(unsigned short *)rawp == 0xFFFF)
- 		return htons(ETH_P_802_3);
- 		
--	/*
-+	/**
- 	 *	Real 802.2 LLC
- 	 */
- 	return htons(ETH_P_802_2);
- }
- 
--static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len)
-+
-+static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
- {
-         u8 *eth;
-         struct sk_buff *skb;
- 
--        if (pkt_len<13) {
--                printk("%s: IP/MPE packet length = %d too small.\n", dev->name, pkt_len);
-+	/* note: pkt_len includes a 32bit checksum */
-+	if (pkt_len < 16) {
-+		printk("%s: IP/MPE packet length = %d too small.\n",
-+			dev->name, pkt_len);
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++;
-+		return;
-+	}
-+	if ((pkt[5] & 0xfd) != 0xc1) {
-+		/* drop scrambled or broken packets */
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++;
- 		return;
- 	}
--        skb = dev_alloc_skb(pkt_len+2);
--        if (skb == NULL) {
--                printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
--                       dev->name);
-+	if (pkt[5] & 0x02) {
-+		//FIXME: handle LLC/SNAP
-                 ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++;
-                 return;
-         }
--        eth=(u8 *) skb_put(skb, pkt_len+2);
--        memcpy(eth+14, (void*)pkt+12, pkt_len-12);
-+	if (pkt[7]) {
-+		/* FIXME: assemble datagram from multiple sections */
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
-+		return;
-+	}
- 
-+	/* we have 14 byte ethernet header (ip header follows);
-+	 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment
-+	 */
-+	if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) {
-+		//printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
-+		((struct dvb_net_priv *) dev->priv)->stats.rx_dropped++;
-+		return;
-+	}
-+	skb_reserve(skb, 2);    /* longword align L3 header */
-+	skb->dev = dev;
-+
-+	/* copy L3 payload */
-+	eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14);
-+	memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4);
-+
-+	/* create ethernet header: */
-         eth[0]=pkt[0x0b];
-         eth[1]=pkt[0x0a];
-         eth[2]=pkt[0x09];
-         eth[3]=pkt[0x08];
-         eth[4]=pkt[0x04];
-         eth[5]=pkt[0x03];
-+
-         eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
--        eth[12]=0x08; eth[13]=0x00;
- 
--	skb->protocol=my_eth_type_trans(skb,dev);
--        skb->dev=dev;
-+	eth[12] = 0x08;	/* ETH_P_IP */
-+	eth[13] = 0x00;
-+
-+	skb->protocol = dvb_net_eth_type_trans(skb, dev);
-         
-         ((struct dvb_net_priv *)dev->priv)->stats.rx_packets++;
-         ((struct dvb_net_priv *)dev->priv)->stats.rx_bytes+=skb->len;
-@@ -141,9 +181,11 @@ static int dvb_net_callback(const u8 *bu
- {
-         struct net_device *dev=(struct net_device *) filter->priv;
- 
--	/* FIXME: this only works if exactly one complete section is
--	          delivered in buffer1 only */
--	dvb_net_sec(dev, buffer1, buffer1_len);
-+	/**
-+	 * we rely on the DVB API definition where exactly one complete
-+	 * section is delivered in buffer1
-+	 */
-+	dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
- 	return 0;
- }
- 
-@@ -178,24 +220,27 @@ static int dvb_net_filter_set(struct net
- 	memset((*secfilter)->filter_mode,  0xff, DMX_MAX_FILTER_SIZE);
- 
- 	(*secfilter)->filter_value[0]=0x3e;
--	(*secfilter)->filter_mask[0]=0xff;
--
- 	(*secfilter)->filter_value[3]=mac[5];
--	(*secfilter)->filter_mask[3]=mac_mask[5];
- 	(*secfilter)->filter_value[4]=mac[4];
--	(*secfilter)->filter_mask[4]=mac_mask[4];
- 	(*secfilter)->filter_value[8]=mac[3];
--	(*secfilter)->filter_mask[8]=mac_mask[3];
- 	(*secfilter)->filter_value[9]=mac[2];
--	(*secfilter)->filter_mask[9]=mac_mask[2];
--
- 	(*secfilter)->filter_value[10]=mac[1];
--	(*secfilter)->filter_mask[10]=mac_mask[1];
- 	(*secfilter)->filter_value[11]=mac[0];
-+
-+	(*secfilter)->filter_mask[0] = 0xff;
-+	(*secfilter)->filter_mask[3] = mac_mask[5];
-+	(*secfilter)->filter_mask[4] = mac_mask[4];
-+	(*secfilter)->filter_mask[8] = mac_mask[3];
-+	(*secfilter)->filter_mask[9] = mac_mask[2];
-+	(*secfilter)->filter_mask[10] = mac_mask[1];
- 	(*secfilter)->filter_mask[11]=mac_mask[0];
- 
--	printk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n", 
-+	dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
- 	       dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-+	dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
-+	       dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
-+	       mac_mask[3], mac_mask[4], mac_mask[5]);
-+
- 	return 0;
- }
- 
-@@ -206,46 +251,57 @@ static int dvb_net_feed_start(struct net
-         struct dmx_demux *demux = priv->demux;
-         unsigned char *mac = (unsigned char *) dev->dev_addr;
- 		
-+	dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
-+	if (priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
-+		printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
-+
- 	priv->secfeed=0;
- 	priv->secfilter=0;
- 
-+	dprintk("%s: alloc secfeed\n", __FUNCTION__);
- 	ret=demux->allocate_section_feed(demux, &priv->secfeed, 
- 					 dvb_net_callback);
- 	if (ret<0) {
--		printk("%s: could not get section feed\n", dev->name);
-+		printk("%s: could not allocate section feed\n", dev->name);
- 		return ret;
- 	}
- 
--	ret=priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 0);
-+	ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
-+
- 	if (ret<0) {
- 		printk("%s: could not set section feed\n", dev->name);
--		priv->demux->
--		        release_section_feed(priv->demux, priv->secfeed);
-+		priv->demux->release_section_feed(priv->demux, priv->secfeed);
- 		priv->secfeed=0;
- 		return ret;
- 	}
--	/* fixme: is this correct? */
--	try_module_get(THIS_MODULE);
- 
--	if (priv->mode<3) 
-+	if (priv->rx_mode != RX_MODE_PROMISC) {
-+		dprintk("%s: set secfilter\n", __FUNCTION__);
- 		dvb_net_filter_set(dev, &priv->secfilter, mac, mask_normal);
-+	}
- 
--	switch (priv->mode) {
--	case 1:
--		for (i=0; i<priv->multi_num; i++) 
-+	switch (priv->rx_mode) {
-+	case RX_MODE_MULTI:
-+		for (i = 0; i < priv->multi_num; i++) {
-+			dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i);
- 			dvb_net_filter_set(dev, &priv->multi_secfilter[i],
- 					   priv->multi_macs[i], mask_normal);
-+		}
- 		break;
--	case 2:
-+	case RX_MODE_ALL_MULTI:
- 		priv->multi_num=1;
--		dvb_net_filter_set(dev, &priv->multi_secfilter[0], mac_allmulti, mask_allmulti);
-+		dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__);
-+		dvb_net_filter_set(dev, &priv->multi_secfilter[0],
-+				   mac_allmulti, mask_allmulti);
- 		break;
--	case 3:
-+	case RX_MODE_PROMISC:
- 		priv->multi_num=0;
-+		dprintk("%s: set secfilter\n", __FUNCTION__);
- 		dvb_net_filter_set(dev, &priv->secfilter, mac, mask_promisc);
- 		break;
- 	}
- 	
-+	dprintk("%s: start filtering\n", __FUNCTION__);
- 	priv->secfeed->start_filtering(priv->secfeed);
- 	return 0;
- }
-@@ -255,89 +311,93 @@ static void dvb_net_feed_stop(struct net
- 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
- 	int i;
- 
-+	dprintk("%s\n", __FUNCTION__);
-         if (priv->secfeed) {
--	        if (priv->secfeed->is_filtering)
-+		if (priv->secfeed->is_filtering) {
-+			dprintk("%s: stop secfeed\n", __FUNCTION__);
- 		        priv->secfeed->stop_filtering(priv->secfeed);
--	        if (priv->secfilter)
--		        priv->secfeed->
--			        release_filter(priv->secfeed, 
-+		}
-+
-+		if (priv->secfilter) {
-+			dprintk("%s: release secfilter\n", __FUNCTION__);
-+			priv->secfeed->release_filter(priv->secfeed,
- 					       priv->secfilter);
- 		priv->secfilter=0;
-+		}
- 
- 		for (i=0; i<priv->multi_num; i++) {
--			if (priv->multi_secfilter[i])
--				priv->secfeed->
--					release_filter(priv->secfeed, 
-+			if (priv->multi_secfilter[i]) {
-+				dprintk("%s: release multi_filter[%d]\n", __FUNCTION__, i);
-+				priv->secfeed->release_filter(priv->secfeed,
- 						       priv->multi_secfilter[i]);
- 			priv->multi_secfilter[i]=0;
- 		}
--		priv->demux->
--		        release_section_feed(priv->demux, priv->secfeed);
-+		}
-+
-+		priv->demux->release_section_feed(priv->demux, priv->secfeed);
- 		priv->secfeed=0;
--		/* fixme: is this correct? */
--		module_put(THIS_MODULE);
- 	} else
- 		printk("%s: no feed to stop\n", dev->name);
- }
- 
--static int dvb_add_mc_filter(struct net_device *dev, struct dev_mc_list *mc)
-+
-+static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
- {
- 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
--	int ret;
- 
--	if (priv->multi_num >= DVB_NET_MULTICAST_MAX)
-+	if (priv->multi_num == DVB_NET_MULTICAST_MAX)
- 		return -ENOMEM;
- 
--	ret = memcmp(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
- 	memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
- 
- 	priv->multi_num++;
--
--	return ret;
-+	return 0;
- }
- 
--static void dvb_net_set_multi(struct net_device *dev)
-+
-+static void wq_set_multicast_list (void *data)
- {
-+	struct net_device *dev = data;
- 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
--	struct dev_mc_list *mc;
--	int mci;
--	int update = 0;
-+
-+	dvb_net_feed_stop(dev);
-+
-+	priv->rx_mode = RX_MODE_UNI;
- 	
- 	if(dev->flags & IFF_PROMISC) {
--//	printk("%s: promiscuous mode\n", dev->name);
--		if(priv->mode != 3)
--			update = 1;
--		priv->mode = 3;
--	} else if(dev->flags & IFF_ALLMULTI) {
--//	printk("%s: allmulti mode\n", dev->name);
--		if(priv->mode != 2)
--			update = 1;
--		priv->mode = 2;
--	} else if(dev->mc_count > 0) {
--//	printk("%s: set_mc_list, %d entries\n", 
--//	       dev->name, dev->mc_count);
--		if(priv->mode != 1)
--			update = 1;
--		priv->mode = 1;
-+		dprintk("%s: promiscuous mode\n", dev->name);
-+		priv->rx_mode = RX_MODE_PROMISC;
-+	} else if ((dev->flags & IFF_ALLMULTI)) {
-+		dprintk("%s: allmulti mode\n", dev->name);
-+		priv->rx_mode = RX_MODE_ALL_MULTI;
-+	} else if (dev->mc_count) {
-+		int mci;
-+		struct dev_mc_list *mc;
-+
-+		dprintk("%s: set_mc_list, %d entries\n",
-+			dev->name, dev->mc_count);
-+
-+		priv->rx_mode = RX_MODE_MULTI;
- 		priv->multi_num = 0;
-+
- 		for (mci = 0, mc=dev->mc_list; 
- 		     mci < dev->mc_count;
--		     mc=mc->next, mci++)
--			if(dvb_add_mc_filter(dev, mc) != 0)
--				update = 1;
--	} else {
--		if(priv->mode != 0)
--			update = 1;
--		priv->mode = 0;
-+		     mc = mc->next, mci++) {
-+			dvb_set_mc_filter(dev, mc);
-+		}
- 	}
- 
--	if(netif_running(dev) != 0 && update > 0)
--	{
--		dvb_net_feed_stop(dev);
- 		dvb_net_feed_start(dev);
- 	}
-+
-+
-+static void dvb_net_set_multicast_list (struct net_device *dev)
-+{
-+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-+	schedule_work(&priv->set_multicast_list_wq);
- }
- 
-+
- static int dvb_net_set_config(struct net_device *dev, struct ifmap *map)
- {
- 	if (netif_running(dev))
-@@ -345,29 +405,47 @@ static int dvb_net_set_config(struct net
- 	return 0;
- }
- 
--static int dvb_net_set_mac(struct net_device *dev, void *p)
-+
-+static void wq_restart_net_feed (void *data)
- {
--	struct sockaddr *addr=p;
--	int update;
-+	struct net_device *dev = data;
- 
--	update = memcmp(dev->dev_addr, addr->sa_data, dev->addr_len);
--	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
--	if (netif_running(dev) != 0 && update > 0) {
-+	if (netif_running(dev)) {
- 		dvb_net_feed_stop(dev);
- 		dvb_net_feed_start(dev);
- 	}
-+}
-+
-+
-+static int dvb_net_set_mac (struct net_device *dev, void *p)
-+{
-+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-+	struct sockaddr *addr=p;
-+
-+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+
-+	if (netif_running(dev))
-+		schedule_work(&priv->restart_net_feed_wq);
-+
- 	return 0;
- }
- 
- 
- static int dvb_net_open(struct net_device *dev)
- {
-+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-+
-+	priv->in_use++;
- 	dvb_net_feed_start(dev);
- 	return 0;
- }
- 
-+
- static int dvb_net_stop(struct net_device *dev)
- {
-+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-+
-+	priv->in_use--;
-         dvb_net_feed_stop(dev);
- 	return 0;
- }
-@@ -386,16 +464,14 @@ static int dvb_net_init_dev(struct net_d
- 	dev->stop		= dvb_net_stop;
- 	dev->hard_start_xmit	= dvb_net_tx;
- 	dev->get_stats		= dvb_net_get_stats;
--	dev->set_multicast_list = dvb_net_set_multi;
-+	dev->set_multicast_list = dvb_net_set_multicast_list;
- 	dev->set_config         = dvb_net_set_config;
- 	dev->set_mac_address    = dvb_net_set_mac;
- 	dev->mtu		= 4096;
- 	dev->mc_count           = 0;
--
--	dev->flags             |= IFF_NOARP;
- 	dev->hard_header_cache  = NULL;
- 
--	//SET_MODULE_OWNER(dev);
-+	dev->flags |= IFF_NOARP;
- 	
- 	return 0;
- }
-@@ -404,18 +480,19 @@ static int get_if(struct dvb_net *dvbnet
- {
- 	int i;
- 
--	for (i=0; i<dvbnet->dev_num; i++) 
-+	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
- 		if (!dvbnet->state[i])
- 			break;
--	if (i==dvbnet->dev_num)
-+
-+	if (i == DVB_NET_DEVICES_MAX)
- 		return -1;
-+
- 	dvbnet->state[i]=1;
- 	return i;
- }
- 
- 
--int 
--dvb_net_add_if(struct dvb_net *dvbnet, u16 pid)
-+static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid)
- {
-         struct net_device *net;
- 	struct dmx_demux *demux;
-@@ -423,59 +500,63 @@ dvb_net_add_if(struct dvb_net *dvbnet, u
- 	int result;
- 	int if_num;
-  
--	if_num=get_if(dvbnet);
--	if (if_num<0)
-+	if ((if_num = get_if(dvbnet)) < 0)
- 		return -EINVAL;
- 
- 	net=&dvbnet->device[if_num];
- 	demux=dvbnet->demux;
- 	
--	net->base_addr = 0;
--	net->irq       = 0;
--	net->dma       = 0;
--	net->mem_start = 0;
-+	memset(net, 0, sizeof(struct net_device));
-+
-         memcpy(net->name, "dvb0_0", 7);
--        net->name[3]=dvbnet->card_num+0x30;
--        net->name[5]=if_num+0x30;
-+	net->name[3]   = dvbnet->dvbdev->adapter->num + '0';
-+	net->name[5]   = if_num + '0';
-+	net->addr_len  = 6;
-+	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
-         net->next      = NULL;
-         net->init      = dvb_net_init_dev;
--        net->priv      = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL);
--	if (net->priv == NULL)
-+
-+	if (!(net->priv = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL)))
- 			return -ENOMEM;
- 
- 	priv = net->priv;
- 	memset(priv, 0, sizeof(struct dvb_net_priv));
-         priv->demux = demux;
-         priv->pid = pid;
--	priv->mode = 0;
-+	priv->rx_mode = RX_MODE_UNI;
-+
-+	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
-+	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
- 
-         net->base_addr = pid;
-                 
- 	if ((result = register_netdev(net)) < 0) {
- 		return result;
- 	}
--	/* fixme: is this correct? */
--	try_module_get(THIS_MODULE);
- 
-         return if_num;
- }
- 
--int 
--dvb_net_remove_if(struct dvb_net *dvbnet, int num)
-+
-+static int dvb_net_remove_if(struct dvb_net *dvbnet, int num)
- {
-+	struct dvb_net_priv *priv = dvbnet->device[num].priv;
-+
- 	if (!dvbnet->state[num])
- 		return -EINVAL;
-+	if (priv->in_use)
-+		return -EBUSY;
-+
- 	dvb_net_stop(&dvbnet->device[num]);
--        kfree(dvbnet->device[num].priv);
-+	flush_scheduled_work();
-+	kfree(priv);
-         unregister_netdev(&dvbnet->device[num]);
- 	dvbnet->state[num]=0;
--	/* fixme: is this correct? */
--	module_put(THIS_MODULE);
--
- 	return 0;
- }
- 
--int dvb_net_do_ioctl(struct inode *inode, struct file *file, 
-+
-+static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
- 		  unsigned int cmd, void *parg)
- {
- 	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
-@@ -490,6 +571,8 @@ int dvb_net_do_ioctl(struct inode *inode
- 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
- 		int result;
- 		
-+		if (!capable(CAP_SYS_ADMIN))
-+			return -EPERM;
- 		result=dvb_net_add_if(dvbnet, dvbnetif->pid);
- 		if (result<0)
- 			return result;
-@@ -502,7 +585,7 @@ int dvb_net_do_ioctl(struct inode *inode
- 		struct dvb_net_priv *priv_data;
- 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
- 
--		if (dvbnetif->if_num >= dvbnet->dev_num ||
-+		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
- 		    !dvbnet->state[dvbnetif->if_num])
- 			return -EFAULT;
- 
-@@ -512,7 +595,9 @@ int dvb_net_do_ioctl(struct inode *inode
- 		break;
- 	}
- 	case NET_REMOVE_IF:
--		return dvb_net_remove_if(dvbnet, (long) parg);
-+		if (!capable(CAP_SYS_ADMIN))
-+			return -EPERM;
-+		return dvb_net_remove_if(dvbnet, (int) parg);
- 	default:
- 		return -EINVAL;
- 	}
-@@ -542,28 +627,29 @@ static struct dvb_device dvbdev_net = {
-         .fops = &dvb_net_fops,
- };
- 
--void
--dvb_net_release(struct dvb_net *dvbnet)
-+
-+void dvb_net_release (struct dvb_net *dvbnet)
- {
- 	int i;
- 
- 	dvb_unregister_device(dvbnet->dvbdev);
--	for (i=0; i<dvbnet->dev_num; i++) {
-+
-+	for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
- 		if (!dvbnet->state[i])
- 			continue;
- 		dvb_net_remove_if(dvbnet, i);
- 	}
- }
- 
--int
--dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet, struct dmx_demux *dmx)
-+
-+int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
-+		  struct dmx_demux *dmx)
- {
- 	int i;
- 		
- 	dvbnet->demux = dmx;
--	dvbnet->dev_num = DVB_NET_DEVICES_MAX;
- 
--	for (i=0; i<dvbnet->dev_num; i++) 
-+	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
- 		dvbnet->state[i] = 0;
- 
- 	dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
---- linux-2.6.0-test1/drivers/media/dvb/dvb-core/dvb_net.h	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/dvb-core/dvb_net.h	2003-07-19 17:03:49.000000000 -0700
-@@ -35,8 +35,6 @@
- 
- struct dvb_net {
- 	struct dvb_device *dvbdev;
--	int card_num;
--	int dev_num;
- 	struct net_device device[DVB_NET_DEVICES_MAX];
- 	int state[DVB_NET_DEVICES_MAX];
- 	struct dmx_demux *demux;
---- linux-2.6.0-test1/drivers/media/dvb/frontends/alps_bsrv2.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/alps_bsrv2.c	2003-07-19 17:03:49.000000000 -0700
-@@ -55,7 +55,7 @@ static u8 init_1893_tab [] = {
-         0x01, 0xA4, 0x35, 0x81, 0x2A, 0x0d, 0x55, 0xC4,
-         0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7F, 0x00,
-         0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	
--        0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x20,
-+        0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x00,
-         0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
-@@ -158,6 +158,11 @@ static int ves1893_set_inversion (struct
- {
- 	u8 val;
- 
-+	/*
-+	 * inversion on/off are interchanged because i and q seem to
-+	 * be swapped on the hardware
-+	 */
-+
- 	switch (inversion) {
- 	case INVERSION_OFF:
- 		val = 0xc0;
-@@ -166,13 +171,16 @@ static int ves1893_set_inversion (struct
- 		val = 0x80;
- 		break;
- 	case INVERSION_AUTO:
--		val = 0x40;
-+		val = 0x00;
- 		break;
- 	default:
- 		return -EINVAL;
- 	}
- 
--	return ves1893_writereg (i2c, 0x0c, (init_1893_tab[0x0c] & 0x3f) | val);
-+	/* needs to be saved for FE_GET_FRONTEND */
-+	init_1893_tab[0x0c] = (init_1893_tab[0x0c] & 0x3f) | val;
-+
-+	return ves1893_writereg (i2c, 0x0c, init_1893_tab[0x0c]);
- }
- 
- 
-@@ -383,8 +391,14 @@ static int bsrv2_ioctl (struct dvb_front
- 		afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
- 
- 		p->frequency -= afc;
-+
-+		/*
-+		 * inversion indicator is only valid
-+		 * if auto inversion was used
-+		 */
-+		if (!(init_1893_tab[0x0c] & 0x80))
- 		p->inversion = (ves1893_readreg (i2c, 0x0f) & 2) ? 
--					INVERSION_ON : INVERSION_OFF;
-+					INVERSION_OFF : INVERSION_ON;
- 		p->u.qpsk.fec_inner = ves1893_get_fec (i2c);
- 	/*  XXX FIXME: timing offset !! */
- 		break;
---- linux-2.6.0-test1/drivers/media/dvb/frontends/alps_tdlb7.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/alps_tdlb7.c	2003-07-19 17:03:49.000000000 -0700
-@@ -349,6 +349,9 @@ static int tdlb7_ioctl (struct dvb_front
- 
- 		sp5659_set_tv_freq (i2c, p->frequency);
- 
-+		// read status reg in order to clear pending irqs
-+		sp8870_readreg(i2c, 0x200);
-+
- 		// sample rate correction bit [23..17]
- 		sp8870_writereg(i2c,0x0319,0x000A);
- 		
---- linux-2.6.0-test1/drivers/media/dvb/frontends/grundig_29504-401.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/grundig_29504-401.c	2003-07-19 17:03:49.000000000 -0700
-@@ -37,15 +37,15 @@ static int debug = 0;
- 
- 
- struct dvb_frontend_info grundig_29504_401_info = {
--	.name 			= "Grundig 29504-401",
--	.type 			= FE_OFDM,
--/*	.frequency_min 		= ???,*/
--/*	.frequency_max 		= ???,*/
--	.frequency_stepsize 	= 166666,
--/*      .frequency_tolerance 	= ???,*/
--/*      .symbol_rate_tolerance 	= ???,*/
--	.notifier_delay =  0,
--	.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 
-+	name: "Grundig 29504-401",
-+	type: FE_OFDM,
-+/*	frequency_min: ???,*/
-+/*	frequency_max: ???,*/
-+	frequency_stepsize: 166666,
-+/*      frequency_tolerance: ???,*/
-+/*      symbol_rate_tolerance: ???,*/
-+	notifier_delay: 0,
-+	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 
- 	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
- 	      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
- 	      FE_CAN_MUTE_TS /*| FE_CAN_CLEAN_SETUP*/
-@@ -109,15 +109,15 @@ static int tsa5060_set_tv_freq (struct d
- 	div = (36125000 + freq) / 166666;
- 	cfg = 0x88;
- 
--	cpump = div < 175000000 ? 2 : div < 390000000 ? 1 :
--		div < 470000000 ? 2 : div < 750000000 ? 1 : 3;
-+	cpump = freq < 175000000 ? 2 : freq < 390000000 ? 1 :
-+		freq < 470000000 ? 2 : freq < 750000000 ? 1 : 3;
- 
--	band_select = div < 175000000 ? 0x0e : div < 470000000 ? 0x05 : 0x03;
-+	band_select = freq < 175000000 ? 0x0e : freq < 470000000 ? 0x05 : 0x03;
- 
- 	buf [0] = (div >> 8) & 0x7f;
- 	buf [1] = div & 0xff;
- 	buf [2] = ((div >> 10) & 0x60) | cfg;
--	buf [3] = cpump | band_select;
-+	buf [3] = (cpump << 6) | band_select;
- 
- 	return tsa5060_write (i2c, buf);
- }
-@@ -267,12 +267,12 @@ static int apply_frontend_param (struct 
- }
- 
- 
--static void reset_and_configure (struct dvb_i2c_bus *i2c)
-+static int reset_and_configure (struct dvb_i2c_bus *i2c)
- {
- 	u8 buf [] = { 0x06 };
- 	struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
- 
--	i2c->xfer (i2c, &msg, 1);
-+	return (i2c->xfer (i2c, &msg, 1) == 1) ? 0 : -ENODEV;
- }
- 
- 
-@@ -391,7 +391,7 @@ int grundig_29504_401_ioctl (struct dvb_
- 		struct dvb_frontend_parameters *p = arg;
- 
- 		tsa5060_set_tv_freq (i2c, p->frequency);
--		apply_frontend_param (i2c, p);
-+		return apply_frontend_param (i2c, p);
- 	}
-         case FE_GET_FRONTEND:
- 		/*  we could correct the frequency here, but...
-@@ -417,25 +417,61 @@ int grundig_29504_401_ioctl (struct dvb_
- 
- static int l64781_attach (struct dvb_i2c_bus *i2c)
- {
-+	u8 reg0x3e;
- 	u8 b0 [] = { 0x1a };
- 	u8 b1 [] = { 0x00 };
- 	struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
- 			   { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
- 
--	if (i2c->xfer (i2c, msg, 2) == 2)   /*  probably an EEPROM... */
-+	/**
-+	 *  the L64781 won't show up before we send the reset_and_configure()
-+	 *  broadcast. If nothing responds there is no L64781 on the bus...
-+	 */
-+	if (reset_and_configure(i2c) < 0) {
-+		dprintk("no response on reset_and_configure() broadcast, bailing out...\n");
- 		return -ENODEV;
-+	}
- 
--	reset_and_configure (i2c);
--
--	if (i2c->xfer (i2c, msg, 2) != 2)   /*  nothing... */
-+	/* The chip always responds to reads */
-+	if (i2c->xfer(i2c, msg, 2) != 2) {  
-+	        dprintk("no response to read on I2C bus\n");
- 		return -ENODEV;
-+	}
- 
--	if (b1[0] != 0xa1)
-+	/* Save current register contents for bailout */
-+	reg0x3e = l64781_readreg(i2c, 0x3e);
-+
-+	/* Reading the POWER_DOWN register always returns 0 */
-+	if (reg0x3e != 0) {
-+	        dprintk("Device doesn't look like L64781\n");
- 		return -ENODEV;
-+	}
-+
-+	/* Turn the chip off */
-+	l64781_writereg (i2c, 0x3e, 0x5a);
-+
-+	/* Responds to all reads with 0 */
-+	if (l64781_readreg(i2c, 0x1a) != 0) {
-+ 	        dprintk("Read 1 returned unexpcted value\n");
-+	        goto bailout;
-+	}	  
-+
-+	/* Turn the chip on */
-+	l64781_writereg (i2c, 0x3e, 0xa5);
-+	
-+	/* Responds with register default value */
-+	if (l64781_readreg(i2c, 0x1a) != 0xa1) { 
-+ 	        dprintk("Read 2 returned unexpcted value\n");
-+	        goto bailout;
-+	}
- 
- 	dvb_register_frontend (grundig_29504_401_ioctl, i2c, NULL,
- 			       &grundig_29504_401_info);
- 	return 0;
-+
-+ bailout:
-+	l64781_writereg (i2c, 0x3e, reg0x3e);  /* restore reg 0x3e */
-+	return -ENODEV;
- }
- 
- 
---- linux-2.6.0-test1/drivers/media/dvb/frontends/grundig_29504-491.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/grundig_29504-491.c	2003-07-19 17:03:49.000000000 -0700
-@@ -179,10 +179,7 @@ static fe_code_rate_t tda8083_get_fec (s
- 	static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
- 				       FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
- 
--	index = tda8083_readreg (i2c, 0x0e) & 0x3;
--
--	if (index > 7)
--		return FEC_NONE;
-+	index = tda8083_readreg(i2c, 0x0e) & 0x07;
- 
- 	return fec_tab [index];
- }
---- linux-2.6.0-test1/drivers/media/dvb/frontends/Kconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -93,6 +93,16 @@ config DVB_GRUNDIG_29504_401
- 	  DVB adapter simply enable all supported frontends, the 
- 	  right one will get autodetected.
- 
-+config DVB_MT312
-+	tristate "Zarlink MT312 Satellite Channel Decoder (QPSK)"
-+	depends on DVB_CORE
-+	help
-+	  A DVB-S tuner module. Say Y when you want to support this frontend.
-+
-+	  If you don't know what tuner module is soldered on your 
-+	  DVB adapter simply enable all supported frontends, the 
-+	  right one will get autodetected.
-+
- config DVB_VES1820
- 	tristate "Frontends with external VES1820 demodulator (QAM)"
- 	depends on DVB_CORE
-@@ -105,3 +115,23 @@ config DVB_VES1820
- 	  DVB adapter simply enable all supported frontends, the 
- 	  right one will get autodetected.
- 
-+config DVB_TDA1004X
-+	tristate "Frontends with external TDA1004X demodulators (OFDM)"
-+	depends on DVB_CORE
-+	help
-+	  A DVB-T tuner module. Say Y when you want to support this frontend.
-+
-+	  If you don't know what tuner module is soldered on your
-+	  DVB adapter simply enable all supported frontends, the
-+	  right one will get autodetected.
-+
-+config DVB_TDA1004X_FIRMWARE_FILE
-+        string "Full pathname of tda1004x.bin firmware file"
-+        depends on DVB_TDA1004X
-+        default "/etc/dvb/tda1004x.bin"
-+        help
-+          The TDA1004X requires additional firmware in order to function.
-+          The firmware file can obtained as follows:
-+            wget http://www.technotrend.de/new/215/TTweb_215a_budget_20_05_2003.zip
-+            unzip -j TTweb_215a_budget_20_05_2003.zip Software/Oem/PCI/App/ttlcdacc.dll
-+            mv ttlcdacc.dll /etc/dvb/tda1004x.bin
---- linux-2.6.0-test1/drivers/media/dvb/frontends/Makefile	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -12,4 +12,6 @@ obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76
- obj-$(CONFIG_DVB_CX24110) += cx24110.o
- obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o
- obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o
-+obi-$(CONFIG_DVB_MT312) += mt312.o
- obj-$(CONFIG_DVB_VES1820) += ves1820.o
-+obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/mt312.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,749 @@
-+/* 
-+    Driver for Zarlink MT312 Satellite Channel Decoder
-+
-+    Copyright (C) 2003 Andreas Oberritter <obi@saftware.de>
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+    References:
-+    http://products.zarlink.com/product_profiles/MT312.htm
-+    http://products.zarlink.com/product_profiles/SL1935.htm
-+*/
-+
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include "dvb_frontend.h"
-+#include "mt312.h"
-+
-+#define I2C_ADDR_MT312		0x0e
-+#define I2C_ADDR_SL1935		0x61
-+#define I2C_ADDR_TSA5059	0x61
-+
-+#define MT312_DEBUG		0
-+
-+#define MT312_SYS_CLK		90000000UL	/* 90 MHz */
-+#define MT312_PLL_CLK		10000000UL	/* 10 MHz */
-+
-+static struct dvb_frontend_info mt312_info = {
-+	.name = "Zarlink MT312",
-+	.type = FE_QPSK,
-+	.frequency_min = 950000,
-+	.frequency_max = 2150000,
-+	.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
-+	/*.frequency_tolerance = 29500,         FIXME: binary compatibility waste? */
-+	.symbol_rate_min = MT312_SYS_CLK / 128,
-+	.symbol_rate_max = MT312_SYS_CLK / 2,
-+	/*.symbol_rate_tolerance = 500,         FIXME: binary compatibility waste? 2% */
-+	.notifier_delay = 0,
-+	.caps =
-+	    FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-+	    FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-+	    FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_RECOVER |
-+	    FE_CAN_CLEAN_SETUP | FE_CAN_MUTE_TS
-+};
-+
-+static int mt312_read(struct dvb_i2c_bus *i2c,
-+		      const enum mt312_reg_addr reg, void *buf,
-+		      const size_t count)
-+{
-+	int ret;
-+	struct i2c_msg msg[2];
-+	u8 regbuf[1] = { reg };
-+
-+	msg[0].addr = I2C_ADDR_MT312;
-+	msg[0].flags = 0;
-+	msg[0].buf = regbuf;
-+	msg[0].len = 1;
-+	msg[1].addr = I2C_ADDR_MT312;
-+	msg[1].flags = I2C_M_RD;
-+	msg[1].buf = buf;
-+	msg[1].len = count;
-+
-+	ret = i2c->xfer(i2c, msg, 2);
-+
-+	if (ret != 2) {
-+		printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
-+		return -EREMOTEIO;
-+	}
-+#ifdef MT312_DEBUG
-+	{
-+		int i;
-+		printk(KERN_INFO "R(%d):", reg & 0x7f);
-+		for (i = 0; i < count; i++)
-+			printk(" %02x", ((const u8 *) buf)[i]);
-+		printk("\n");
-+	}
-+#endif
-+
-+	return 0;
-+}
-+
-+static int mt312_write(struct dvb_i2c_bus *i2c,
-+		       const enum mt312_reg_addr reg, const void *src,
-+		       const size_t count)
-+{
-+	int ret;
-+	u8 buf[count + 1];
-+	struct i2c_msg msg;
-+
-+#ifdef MT312_DEBUG
-+	{
-+		int i;
-+		printk(KERN_INFO "W(%d):", reg & 0x7f);
-+		for (i = 0; i < count; i++)
-+			printk(" %02x", ((const u8 *) src)[i]);
-+		printk("\n");
-+	}
-+#endif
-+
-+	buf[0] = reg;
-+	memcpy(&buf[1], src, count);
-+
-+	msg.addr = I2C_ADDR_MT312;
-+	msg.flags = 0;
-+	msg.buf = buf;
-+	msg.len = count + 1;
-+
-+	ret = i2c->xfer(i2c, &msg, 1);
-+
-+	if (ret != 1) {
-+		printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
-+		return -EREMOTEIO;
-+	}
-+
-+	return 0;
-+}
-+
-+static inline int mt312_readreg(struct dvb_i2c_bus *i2c,
-+				const enum mt312_reg_addr reg, u8 * val)
-+{
-+	return mt312_read(i2c, reg, val, 1);
-+}
-+
-+static inline int mt312_writereg(struct dvb_i2c_bus *i2c,
-+				 const enum mt312_reg_addr reg, const u8 val)
-+{
-+	return mt312_write(i2c, reg, &val, 1);
-+}
-+
-+static int mt312_pll_write(struct dvb_i2c_bus *i2c, const u8 addr,
-+			   u8 * buf, const u8 len)
-+{
-+	int ret;
-+	struct i2c_msg msg;
-+
-+	msg.addr = addr;
-+	msg.flags = 0;
-+	msg.buf = buf;
-+	msg.len = len;
-+
-+	if ((ret = mt312_writereg(i2c, GPP_CTRL, 0x40)) < 0)
-+		return ret;
-+
-+	if ((ret = i2c->xfer(i2c, &msg, 1)) != 1)
-+		printk(KERN_ERR "%s: i/o error (ret == %d)\n", __FUNCTION__, ret);
-+
-+	if ((ret = mt312_writereg(i2c, GPP_CTRL, 0x00)) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static inline u32 mt312_div(u32 a, u32 b)
-+{
-+	return (a + (b / 2)) / b;
-+}
-+
-+static int sl1935_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
-+{
-+	/* 155 uA, Baseband Path B */
-+	u8 buf[4] = { 0x00, 0x00, 0x80, 0x00 };
-+
-+	u8 exp;
-+	u32 ref;
-+	u32 div;
-+
-+	if (sr < 10000000) {	/* 1-10 MSym/s: ratio 2 ^ 3 */
-+		exp = 3;
-+		buf[2] |= 0x40;	/* 690 uA */
-+	} else if (sr < 15000000) {	/* 10-15 MSym/s: ratio 2 ^ 4 */
-+		exp = 4;
-+		buf[2] |= 0x20;	/* 330 uA */
-+	} else {		/* 15-45 MSym/s: ratio 2 ^ 7 */
-+		exp = 7;
-+		buf[3] |= 0x08;	/* Baseband Path A */
-+	}
-+
-+	div = mt312_div(MT312_PLL_CLK, 1 << exp);
-+	ref = mt312_div(freq * 1000, div);
-+	mt312_info.frequency_stepsize = mt312_div(div, 1000);
-+
-+	buf[0] = (ref >> 8) & 0x7f;
-+	buf[1] = (ref >> 0) & 0xff;
-+	buf[2] |= (exp - 1);
-+
-+	if (freq < 1550000)
-+		buf[3] |= 0x10;
-+
-+	printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
-+	       buf[1], buf[2], buf[3]);
-+
-+	return mt312_pll_write(i2c, I2C_ADDR_SL1935, buf, sizeof(buf));
-+}
-+
-+static int tsa5059_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq, u32 sr)
-+{
-+	u8 buf[4];
-+
-+	u32 ref = mt312_div(freq, 125);
-+
-+	buf[0] = (ref >> 8) & 0x7f;
-+	buf[1] = (ref >> 0) & 0xff;
-+	buf[2] = 0x84 | ((ref >> 10) & 0x60);
-+	buf[3] = 0x80;
-+	
-+	if (freq < 1550000)
-+		buf[3] |= 0x02;
-+
-+	printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
-+	       buf[1], buf[2], buf[3]);
-+
-+	return mt312_pll_write(i2c, I2C_ADDR_TSA5059, buf, sizeof(buf));
-+}
-+
-+static int mt312_reset(struct dvb_i2c_bus *i2c, const u8 full)
-+{
-+	return mt312_writereg(i2c, RESET, full ? 0x80 : 0x40);
-+}
-+
-+static int mt312_init(struct dvb_i2c_bus *i2c, const long id)
-+{
-+	int ret;
-+	u8 buf[2];
-+
-+	/* wake up */
-+	if ((ret = mt312_writereg(i2c, CONFIG, 0x8c)) < 0)
-+		return ret;
-+
-+	/* wait at least 150 usec */
-+	udelay(150);
-+
-+	/* full reset */
-+	if ((ret = mt312_reset(i2c, 1)) < 0)
-+		return ret;
-+
-+	/* SYS_CLK */
-+	buf[0] = mt312_div(MT312_SYS_CLK * 2, 1000000);
-+
-+	/* DISEQC_RATIO */
-+	buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
-+
-+	if ((ret = mt312_write(i2c, SYS_CLK, buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_writereg(i2c, SNR_THS_HIGH, 0x32)) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_writereg(i2c, OP_CTRL, 0x53)) < 0)
-+		return ret;
-+
-+	/* TS_SW_LIM */
-+	buf[0] = 0x8c;
-+	buf[1] = 0x98;
-+
-+	if ((ret = mt312_write(i2c, TS_SW_LIM_L, buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_writereg(i2c, CS_SW_LIM, 0x69)) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_send_master_cmd(struct dvb_i2c_bus *i2c,
-+				 const struct dvb_diseqc_master_cmd *c)
-+{
-+	int ret;
-+	u8 diseqc_mode;
-+
-+	if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
-+		return -EINVAL;
-+
-+	if ((ret = mt312_readreg(i2c, DISEQC_MODE, &diseqc_mode)) < 0)
-+		return ret;
-+
-+	if ((ret =
-+	     mt312_write(i2c, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0)
-+		return ret;
-+
-+	if ((ret =
-+	     mt312_writereg(i2c, DISEQC_MODE,
-+			    (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
-+			    | 0x04)) < 0)
-+		return ret;
-+
-+	/* set DISEQC_MODE[2:0] to zero if a return message is expected */
-+	if (c->msg[0] & 0x02)
-+		if ((ret =
-+		     mt312_writereg(i2c, DISEQC_MODE, (diseqc_mode & 0x40))) < 0)
-+			return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_recv_slave_reply(struct dvb_i2c_bus *i2c,
-+				  struct dvb_diseqc_slave_reply *r)
-+{
-+	/* TODO */
-+	return -EOPNOTSUPP;
-+}
-+
-+static int mt312_send_burst(struct dvb_i2c_bus *i2c, const fe_sec_mini_cmd_t c)
-+{
-+	const u8 mini_tab[2] = { 0x02, 0x03 };
-+
-+	int ret;
-+	u8 diseqc_mode;
-+
-+	if (c > SEC_MINI_B)
-+		return -EINVAL;
-+
-+	if ((ret = mt312_readreg(i2c, DISEQC_MODE, &diseqc_mode)) < 0)
-+		return ret;
-+
-+	if ((ret =
-+	     mt312_writereg(i2c, DISEQC_MODE,
-+			    (diseqc_mode & 0x40) | mini_tab[c])) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_set_tone(struct dvb_i2c_bus *i2c, const fe_sec_tone_mode_t t)
-+{
-+	const u8 tone_tab[2] = { 0x01, 0x00 };
-+
-+	int ret;
-+	u8 diseqc_mode;
-+
-+	if (t > SEC_TONE_OFF)
-+		return -EINVAL;
-+
-+	if ((ret = mt312_readreg(i2c, DISEQC_MODE, &diseqc_mode)) < 0)
-+		return ret;
-+
-+	if ((ret =
-+	     mt312_writereg(i2c, DISEQC_MODE,
-+			    (diseqc_mode & 0x40) | tone_tab[t])) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_set_voltage(struct dvb_i2c_bus *i2c, const fe_sec_voltage_t v)
-+{
-+	const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
-+
-+	if (v > SEC_VOLTAGE_OFF)
-+		return -EINVAL;
-+
-+	return mt312_writereg(i2c, DISEQC_MODE, volt_tab[v]);
-+}
-+
-+static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t * s)
-+{
-+	int ret;
-+	u8 status[3];
-+
-+	*s = 0;
-+
-+	if ((ret = mt312_read(i2c, QPSK_STAT_H, status, sizeof(status))) < 0)
-+		return ret;
-+
-+	if (status[0] & 0xc0)
-+		*s |= FE_HAS_SIGNAL;	/* signal noise ratio */
-+	if (status[0] & 0x04)
-+		*s |= FE_HAS_CARRIER;	/* qpsk carrier lock */
-+	if (status[2] & 0x02)
-+		*s |= FE_HAS_VITERBI;	/* viterbi lock */
-+	if (status[2] & 0x04)
-+		*s |= FE_HAS_SYNC;	/* byte align lock */
-+	if (status[0] & 0x01)
-+		*s |= FE_HAS_LOCK;	/* qpsk lock */
-+
-+	return 0;
-+}
-+
-+static int mt312_read_bercnt(struct dvb_i2c_bus *i2c, u32 * ber)
-+{
-+	int ret;
-+	u8 buf[3];
-+
-+	if ((ret = mt312_read(i2c, RS_BERCNT_H, buf, 3)) < 0)
-+		return ret;
-+
-+	*ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
-+
-+	return 0;
-+}
-+
-+static int mt312_read_agc(struct dvb_i2c_bus *i2c, u16 * signal_strength)
-+{
-+	int ret;
-+	u8 buf[3];
-+	u16 agc;
-+	s16 err_db;
-+
-+	if ((ret = mt312_read(i2c, AGC_H, buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	agc = (buf[0] << 6) | (buf[1] >> 2);
-+	err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
-+
-+	*signal_strength = agc;
-+
-+	printk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
-+
-+	return 0;
-+}
-+
-+static int mt312_read_snr(struct dvb_i2c_bus *i2c, u16 * snr)
-+{
-+	int ret;
-+	u8 buf[2];
-+
-+	if ((ret = mt312_read(i2c, M_SNR_H, &buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	*snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
-+
-+	return 0;
-+}
-+
-+static int mt312_read_ubc(struct dvb_i2c_bus *i2c, u32 * ubc)
-+{
-+	int ret;
-+	u8 buf[2];
-+
-+	if ((ret = mt312_read(i2c, RS_UBC_H, &buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	*ubc = (buf[0] << 8) | buf[1];
-+
-+	return 0;
-+}
-+
-+static int mt312_set_frontend(struct dvb_i2c_bus *i2c,
-+			      const struct dvb_frontend_parameters *p,
-+			      const long id)
-+{
-+	int ret;
-+	u8 buf[5];
-+	u16 sr;
-+
-+	const u8 fec_tab[10] =
-+	    { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
-+	const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
-+
-+	int (*set_tv_freq)(struct dvb_i2c_bus *i2c, u32 freq, u32 sr);
-+
-+	if ((p->frequency < mt312_info.frequency_min)
-+	    || (p->frequency > mt312_info.frequency_max))
-+		return -EINVAL;
-+
-+	if ((p->inversion < INVERSION_OFF)
-+	    || (p->inversion > INVERSION_AUTO))
-+		return -EINVAL;
-+
-+	if ((p->u.qpsk.symbol_rate < mt312_info.symbol_rate_min)
-+	    || (p->u.qpsk.symbol_rate > mt312_info.symbol_rate_max))
-+		return -EINVAL;
-+
-+	if ((p->u.qpsk.fec_inner < FEC_NONE)
-+	    || (p->u.qpsk.fec_inner > FEC_AUTO))
-+		return -EINVAL;
-+
-+	if ((p->u.qpsk.fec_inner == FEC_4_5)
-+	    || (p->u.qpsk.fec_inner == FEC_8_9))
-+		return -EINVAL;
-+
-+	switch (id) {
-+	case ID_VP310:
-+		set_tv_freq = tsa5059_set_tv_freq;
-+		break;
-+	case ID_MT312:
-+		set_tv_freq = sl1935_set_tv_freq;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	if ((ret = set_tv_freq(i2c, p->frequency, p->u.qpsk.symbol_rate)) < 0)
-+		return ret;
-+
-+	/* sr = (u16)(sr * 256.0 / 1000000.0) */
-+	sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
-+
-+	/* SYM_RATE */
-+	buf[0] = (sr >> 8) & 0x3f;
-+	buf[1] = (sr >> 0) & 0xff;
-+
-+	/* VIT_MODE */
-+	buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];
-+
-+	/* QPSK_CTRL */
-+	buf[3] = 0x40;		/* swap I and Q before QPSK demodulation */
-+
-+	if (p->u.qpsk.symbol_rate < 10000000)
-+		buf[3] |= 0x04;	/* use afc mode */
-+
-+	/* GO */
-+	buf[4] = 0x01;
-+
-+	if ((ret = mt312_write(i2c, SYM_RATE_H, buf, sizeof(buf))) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_get_inversion(struct dvb_i2c_bus *i2c,
-+			       fe_spectral_inversion_t * i)
-+{
-+	int ret;
-+	u8 vit_mode;
-+
-+	if ((ret = mt312_readreg(i2c, VIT_MODE, &vit_mode)) < 0)
-+		return ret;
-+
-+	if (vit_mode & 0x80)	/* auto inversion was used */
-+		*i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
-+
-+	return 0;
-+}
-+
-+static int mt312_get_symbol_rate(struct dvb_i2c_bus *i2c, u32 * sr)
-+{
-+	int ret;
-+	u8 sym_rate_h;
-+	u8 dec_ratio;
-+	u16 sym_rat_op;
-+	u16 monitor;
-+	u8 buf[2];
-+
-+	if ((ret = mt312_readreg(i2c, SYM_RATE_H, &sym_rate_h)) < 0)
-+		return ret;
-+
-+	if (sym_rate_h & 0x80) {	/* symbol rate search was used */
-+		if ((ret = mt312_writereg(i2c, MON_CTRL, 0x03)) < 0)
-+			return ret;
-+
-+		if ((ret = mt312_read(i2c, MONITOR_H, buf, sizeof(buf))) < 0)
-+			return ret;
-+
-+		monitor = (buf[0] << 8) | buf[1];
-+
-+		printk(KERN_DEBUG "sr(auto) = %u\n",
-+		       mt312_div(monitor * 15625, 4));
-+	} else {
-+		if ((ret = mt312_writereg(i2c, MON_CTRL, 0x05)) < 0)
-+			return ret;
-+
-+		if ((ret = mt312_read(i2c, MONITOR_H, buf, sizeof(buf))) < 0)
-+			return ret;
-+
-+		dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
-+
-+		if ((ret = mt312_read(i2c, SYM_RAT_OP_H, buf, sizeof(buf))) < 0)
-+			return ret;
-+
-+		sym_rat_op = (buf[0] << 8) | buf[1];
-+
-+		printk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
-+		       sym_rat_op, dec_ratio);
-+		printk(KERN_DEBUG "*sr(manual) = %lu\n",
-+		       (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
-+			2) - dec_ratio);
-+	}
-+
-+	return 0;
-+}
-+
-+static int mt312_get_code_rate(struct dvb_i2c_bus *i2c, fe_code_rate_t * cr)
-+{
-+	const fe_code_rate_t fec_tab[8] =
-+	    { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
-+		FEC_AUTO, FEC_AUTO };
-+
-+	int ret;
-+	u8 fec_status;
-+
-+	if ((ret = mt312_readreg(i2c, FEC_STATUS, &fec_status)) < 0)
-+		return ret;
-+
-+	*cr = fec_tab[(fec_status >> 4) & 0x07];
-+
-+	return 0;
-+}
-+
-+static int mt312_get_frontend(struct dvb_i2c_bus *i2c,
-+			      struct dvb_frontend_parameters *p)
-+{
-+	int ret;
-+
-+	if ((ret = mt312_get_inversion(i2c, &p->inversion)) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_get_symbol_rate(i2c, &p->u.qpsk.symbol_rate)) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_get_code_rate(i2c, &p->u.qpsk.fec_inner)) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_sleep(struct dvb_i2c_bus *i2c)
-+{
-+	int ret;
-+	u8 config;
-+
-+	/* reset all registers to defaults */
-+	if ((ret = mt312_reset(i2c, 1)) < 0)
-+		return ret;
-+
-+	if ((ret = mt312_readreg(i2c, CONFIG, &config)) < 0)
-+		return ret;
-+
-+	/* enter standby */
-+	if ((ret = mt312_writereg(i2c, CONFIG, config & 0x7f)) < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int mt312_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
-+{
-+	struct dvb_i2c_bus *i2c = fe->i2c;
-+
-+	switch (cmd) {
-+	case FE_GET_INFO:
-+		memcpy(arg, &mt312_info, sizeof(struct dvb_frontend_info));
-+		break;
-+
-+	case FE_DISEQC_RESET_OVERLOAD:
-+		return -EOPNOTSUPP;
-+
-+	case FE_DISEQC_SEND_MASTER_CMD:
-+		return mt312_send_master_cmd(i2c, arg);
-+
-+	case FE_DISEQC_RECV_SLAVE_REPLY:
-+		if ((long) fe->data == ID_MT312)
-+			return mt312_recv_slave_reply(i2c, arg);
-+		else
-+			return -EOPNOTSUPP;
-+
-+	case FE_DISEQC_SEND_BURST:
-+		return mt312_send_burst(i2c, (fe_sec_mini_cmd_t) arg);
-+
-+	case FE_SET_TONE:
-+		return mt312_set_tone(i2c, (fe_sec_tone_mode_t) arg);
-+
-+	case FE_SET_VOLTAGE:
-+		return mt312_set_voltage(i2c, (fe_sec_voltage_t) arg);
-+
-+	case FE_ENABLE_HIGH_LNB_VOLTAGE:
-+		return -EOPNOTSUPP;
-+
-+	case FE_READ_STATUS:
-+		return mt312_read_status(i2c, arg);
-+
-+	case FE_READ_BER:
-+		return mt312_read_bercnt(i2c, arg);
-+
-+	case FE_READ_SIGNAL_STRENGTH:
-+		return mt312_read_agc(i2c, arg);
-+
-+	case FE_READ_SNR:
-+		return mt312_read_snr(i2c, arg);
-+
-+	case FE_READ_UNCORRECTED_BLOCKS:
-+		return mt312_read_ubc(i2c, arg);
-+
-+	case FE_SET_FRONTEND:
-+		return mt312_set_frontend(i2c, arg, (long) fe->data);
-+
-+	case FE_GET_FRONTEND:
-+		return mt312_get_frontend(i2c, arg);
-+
-+	case FE_GET_EVENT:
-+		return -EOPNOTSUPP;
-+
-+	case FE_SLEEP:
-+		return mt312_sleep(i2c);
-+
-+	case FE_INIT:
-+		return mt312_init(i2c, (long) fe->data);
-+
-+	case FE_RESET:
-+		return mt312_reset(i2c, 0);
-+
-+	default:
-+		return -ENOIOCTLCMD;
-+	}
-+
-+	return 0;
-+}
-+
-+static int mt312_attach(struct dvb_i2c_bus *i2c)
-+{
-+	int ret;
-+	u8 id;
-+
-+	if ((ret = mt312_readreg(i2c, ID, &id)) < 0)
-+		return ret;
-+
-+	if ((id != ID_VP310) && (id != ID_MT312))
-+		return -ENODEV;
-+
-+	return dvb_register_frontend(mt312_ioctl, i2c, (void *) (long) id,
-+				     &mt312_info);
-+}
-+
-+static void mt312_detach(struct dvb_i2c_bus *i2c)
-+{
-+	dvb_unregister_frontend(mt312_ioctl, i2c);
-+}
-+
-+static int __init mt312_module_init(void)
-+{
-+	return dvb_register_i2c_device(THIS_MODULE, mt312_attach, mt312_detach);
-+}
-+
-+static void __exit mt312_module_exit(void)
-+{
-+	dvb_unregister_i2c_device(mt312_attach);
-+}
-+
-+module_init(mt312_module_init);
-+module_exit(mt312_module_exit);
-+
-+MODULE_DESCRIPTION("MT312 Satellite Channel Decoder Driver");
-+MODULE_AUTHOR("Andreas Oberritter <obi@saftware.de>");
-+MODULE_LICENSE("GPL");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/mt312.h	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,162 @@
-+/* 
-+    Driver for Zarlink MT312 QPSK Frontend
-+
-+    Copyright (C) 2003 Andreas Oberritter <obi@saftware.de>
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+*/
-+
-+#ifndef _DVB_FRONTENDS_MT312
-+#define _DVB_FRONTENDS_MT312
-+
-+enum mt312_reg_addr {
-+	QPSK_INT_H = 0,
-+	QPSK_INT_M = 1,
-+	QPSK_INT_L = 2,
-+	FEC_INT = 3,
-+	QPSK_STAT_H = 4,
-+	QPSK_STAT_L = 5,
-+	FEC_STATUS = 6,
-+	LNB_FREQ_H = 7,
-+	LNB_FREQ_L = 8,
-+	M_SNR_H = 9,
-+	M_SNR_L = 10,
-+	VIT_ERRCNT_H = 11,
-+	VIT_ERRCNT_M = 12,
-+	VIT_ERRCNT_L = 13,
-+	RS_BERCNT_H = 14,
-+	RS_BERCNT_M = 15,
-+	RS_BERCNT_L = 16,
-+	RS_UBC_H = 17,
-+	RS_UBC_L = 18,
-+	SIG_LEVEL = 19,
-+	GPP_CTRL = 20,
-+	RESET = 21,
-+	DISEQC_MODE = 22,
-+	SYM_RATE_H = 23,
-+	SYM_RATE_L = 24,
-+	VIT_MODE = 25,
-+	QPSK_CTRL = 26,
-+	GO = 27,
-+	IE_QPSK_H = 28,
-+	IE_QPSK_M = 29,
-+	IE_QPSK_L = 30,
-+	IE_FEC = 31,
-+	QPSK_STAT_EN = 32,
-+	FEC_STAT_EN = 33,
-+	SYS_CLK = 34,
-+	DISEQC_RATIO = 35,
-+	DISEQC_INSTR = 36,
-+	FR_LIM = 37,
-+	FR_OFF = 38,
-+	AGC_CTRL = 39,
-+	AGC_INIT = 40,
-+	AGC_REF = 41,
-+	AGC_MAX = 42,
-+	AGC_MIN = 43,
-+	AGC_LK_TH = 44,
-+	TS_AGC_LK_TH = 45,
-+	AGC_PWR_SET = 46,
-+	QPSK_MISC = 47,
-+	SNR_THS_LOW = 48,
-+	SNR_THS_HIGH = 49,
-+	TS_SW_RATE = 50,
-+	TS_SW_LIM_L = 51,
-+	TS_SW_LIM_H = 52,
-+	CS_SW_RATE_1 = 53,
-+	CS_SW_RATE_2 = 54,
-+	CS_SW_RATE_3 = 55,
-+	CS_SW_RATE_4 = 56,
-+	CS_SW_LIM = 57,
-+	TS_LPK = 58,
-+	TS_LPK_M = 59,
-+	TS_LPK_L = 60,
-+	CS_KPROP_H = 61,
-+	CS_KPROP_L = 62,
-+	CS_KINT_H = 63,
-+	CS_KINT_L = 64,
-+	QPSK_SCALE = 65,
-+	TLD_OUTCLK_TH = 66,
-+	TLD_INCLK_TH = 67,
-+	FLD_TH = 68,
-+	PLD_OUTLK3 = 69,
-+	PLD_OUTLK2 = 70,
-+	PLD_OUTLK1 = 71,
-+	PLD_OUTLK0 = 72,
-+	PLD_INLK3 = 73,
-+	PLD_INLK2 = 74,
-+	PLD_INLK1 = 75,
-+	PLD_INLK0 = 76,
-+	PLD_ACC_TIME = 77,
-+	SWEEP_PAR = 78,
-+	STARTUP_TIME = 79,
-+	LOSSLOCK_TH = 80,
-+	FEC_LOCK_TM = 81,
-+	LOSSLOCK_TM = 82,
-+	VIT_ERRPER_H = 83,
-+	VIT_ERRPER_M = 84,
-+	VIT_ERRPER_L = 85,
-+	VIT_SETUP = 86,
-+	VIT_REF0 = 87,
-+	VIT_REF1 = 88,
-+	VIT_REF2 = 89,
-+	VIT_REF3 = 90,
-+	VIT_REF4 = 91,
-+	VIT_REF5 = 92,
-+	VIT_REF6 = 93,
-+	VIT_MAXERR = 94,
-+	BA_SETUPT = 95,
-+	OP_CTRL = 96,
-+	FEC_SETUP = 97,
-+	PROG_SYNC = 98,
-+	AFC_SEAR_TH = 99,
-+	CSACC_DIF_TH = 100,
-+	QPSK_LK_CT = 101,
-+	QPSK_ST_CT = 102,
-+	MON_CTRL = 103,
-+	QPSK_RESET = 104,
-+	QPSK_TST_CT = 105,
-+	QPSK_TST_ST = 106,
-+	TEST_R = 107,
-+	AGC_H = 108,
-+	AGC_M = 109,
-+	AGC_L = 110,
-+	FREQ_ERR1_H = 111,
-+	FREQ_ERR1_M = 112,
-+	FREQ_ERR1_L = 113,
-+	FREQ_ERR2_H = 114,
-+	FREQ_ERR2_L = 115,
-+	SYM_RAT_OP_H = 116,
-+	SYM_RAT_OP_L = 117,
-+	DESEQC2_INT = 118,
-+	DISEQC2_STAT = 119,
-+	DISEQC2_FIFO = 120,
-+	DISEQC2_CTRL1 = 121,
-+	DISEQC2_CTRL2 = 122,
-+	MONITOR_H = 123,
-+	MONITOR_L = 124,
-+	TEST_MODE = 125,
-+	ID = 126,
-+	CONFIG = 127
-+};
-+
-+enum mt312_model_id {
-+	ID_VP310 = 1,
-+	ID_MT312 = 3
-+};
-+
-+#endif				/* DVB_FRONTENDS_MT312 */
---- linux-2.6.0-test1/drivers/media/dvb/frontends/nxt6000.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/nxt6000.c	2003-07-19 17:03:49.000000000 -0700
-@@ -6,8 +6,10 @@
- 	
- 	Alps TDME7 (Tuner: MITEL SP5659)
- 	Alps TDED4 (Tuner: TI ALP510, external Nxt6000)
-+	Comtech DVBT-6k07 (PLL IC: SP5730)
- 
-     Copyright (C) 2002-2003 Florian Schirmer <schirmer@taytron.net>
-+    Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
- 
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-@@ -78,6 +80,7 @@ struct nxt6000_config {
- 
- #define TUNER_TYPE_ALP510	0
- #define TUNER_TYPE_SP5659	1
-+#define TUNER_TYPE_SP5730	2
- 
- #define FE2NXT(fe) ((struct nxt6000_config *)&(fe->data))
- #define FREQ2DIV(freq) ((freq + 36166667) / 166667)
-@@ -212,6 +215,39 @@ static int alp510_set_tv_freq(struct dvb
- 	
- }
- 
-+static int sp5730_set_tv_freq(struct dvb_frontend *fe, u32 freq)
-+{
-+
-+	u8 buf[4];
-+	struct nxt6000_config *nxt = FE2NXT(fe);
-+
-+	buf[0] = (FREQ2DIV(freq) >> 8) & 0x7F;
-+	buf[1] = FREQ2DIV(freq) & 0xFF;
-+	buf[2] = 0x93;
-+
-+	if ((freq >= 51000000) && (freq < 132100000))
-+		buf[3] = 0x05;
-+	else if ((freq >= 132100000) && (freq < 143000000))
-+		buf[3] = 0x45;
-+	else if ((freq >= 146000000) && (freq < 349100000))
-+		buf[3] = 0x06;
-+	else if ((freq >= 349100000) && (freq < 397100000))
-+		buf[3] = 0x46;
-+	else if ((freq >= 397100000) && (freq < 426000000))
-+		buf[3] = 0x86;
-+	else if ((freq >= 430000000) && (freq < 659100000))
-+		buf[3] = 0x03;
-+	else if ((freq >= 659100000) && (freq < 759100000))
-+		buf[3] = 0x43;
-+	else if ((freq >= 759100000) && (freq < 858000000))
-+		buf[3] = 0x83;
-+	else
-+		return -EINVAL;
-+
-+	return pll_write(fe->i2c, nxt->demod_addr, nxt->tuner_addr, buf, 4);
-+	
-+}
-+
- static void nxt6000_reset(struct dvb_frontend *fe)
- {
- 
-@@ -756,6 +792,13 @@ static int nxt6000_ioctl(struct dvb_fron
- 						
- 					break;
- 					
-+				case TUNER_TYPE_SP5730:
-+
-+					if ((result = sp5730_set_tv_freq(fe, param->frequency)) < 0)
-+						return result;
-+
-+					break;
-+
- 				default:
- 				
- 					return -EFAULT;
-@@ -816,6 +859,14 @@ static int nxt6000_attach(struct dvb_i2c
- 	
- 			dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt.tuner_addr);
- 		
-+		} else if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC0, NULL, 0) == 0) {
-+
-+			nxt.tuner_addr = 0xC0;
-+			nxt.tuner_type = TUNER_TYPE_SP5730;
-+			nxt.clock_inversion = 0;
-+	
-+			dprintk("nxt6000: detected SP5730 tuner at 0x%02X\n", nxt.tuner_addr);
-+		
- 		} else {
- 
- 			printk("nxt6000: unable to detect tuner\n");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/tda1004x.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,1158 @@
-+  /*
-+     Driver for Philips tda1004x OFDM Frontend
-+
-+     This program 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.
-+
-+     This program is distributed in the hope that it will be useful,
-+     but WITHOUT ANY WARRANTY; without even the implied warranty of
-+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+
-+     GNU General Public License for more details.
-+
-+     You should have received a copy of the GNU General Public License
-+     along with this program; if not, write to the Free Software
-+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+   */
-+
-+/*
-+    This driver needs a copy of the DLL "ttlcdacc.dll" from the Haupauge or Technotrend
-+    windows driver saved as '/etc/dvb/tda1004x.mc'.
-+    You can also pass the complete file name with the module parameter 'tda1004x_firmware'.
-+
-+    Currently the DLL from v2.15a of the technotrend driver is supported. Other versions can
-+    be added reasonably painlessly.
-+
-+    Windows driver URL: http://www.technotrend.de/
-+ */
-+
-+
-+#define __KERNEL_SYSCALLS__
-+#include <linux/kernel.h>
-+#include <linux/vmalloc.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/unistd.h>
-+#include <linux/fcntl.h>
-+#include <linux/errno.h>
-+#include "dvb_frontend.h"
-+#include "dvb_functions.h"
-+
-+#ifndef CONFIG_TDA1004X_MC_LOCATION
-+#define CONFIG_TDA1004X_MC_LOCATION "/etc/dvb/tda1004x.mc"
-+#endif
-+
-+static int tda1004x_debug = 0;
-+static char *tda1004x_firmware = CONFIG_TDA1004X_MC_LOCATION;
-+
-+
-+#define TDA10045H_ADDRESS        0x08
-+#define TD1344_ADDRESS           0x61
-+#define TDM1316L_ADDRESS         0x63
-+#define MC44BC374_ADDRESS        0x65
-+
-+#define TDA1004X_CHIPID          0x00
-+#define TDA1004X_AUTO            0x01
-+#define TDA1004X_IN_CONF1        0x02
-+#define TDA1004X_IN_CONF2        0x03
-+#define TDA1004X_OUT_CONF1       0x04
-+#define TDA1004X_OUT_CONF2       0x05
-+#define TDA1004X_STATUS_CD       0x06
-+#define TDA1004X_CONFC4          0x07
-+#define TDA1004X_DSSPARE2        0x0C
-+#define TDA1004X_CODE_IN         0x0D
-+#define TDA1004X_FWPAGE          0x0E
-+#define TDA1004X_SCAN_CPT        0x10
-+#define TDA1004X_DSP_CMD         0x11
-+#define TDA1004X_DSP_ARG         0x12
-+#define TDA1004X_DSP_DATA1       0x13
-+#define TDA1004X_DSP_DATA2       0x14
-+#define TDA1004X_CONFADC1        0x15
-+#define TDA1004X_CONFC1          0x16
-+#define TDA1004X_SIGNAL_STRENGTH 0x1a
-+#define TDA1004X_SNR             0x1c
-+#define TDA1004X_REG1E           0x1e
-+#define TDA1004X_REG1F           0x1f
-+#define TDA1004X_CBER_RESET      0x20
-+#define TDA1004X_CBER_MSB        0x21
-+#define TDA1004X_CBER_LSB        0x22
-+#define TDA1004X_CVBER_LUT       0x23
-+#define TDA1004X_VBER_MSB        0x24
-+#define TDA1004X_VBER_MID        0x25
-+#define TDA1004X_VBER_LSB        0x26
-+#define TDA1004X_UNCOR           0x27
-+#define TDA1004X_CONFPLL_P       0x2D
-+#define TDA1004X_CONFPLL_M_MSB   0x2E
-+#define TDA1004X_CONFPLL_M_LSB   0x2F
-+#define TDA1004X_CONFPLL_N       0x30
-+#define TDA1004X_UNSURW_MSB      0x31
-+#define TDA1004X_UNSURW_LSB      0x32
-+#define TDA1004X_WREF_MSB        0x33
-+#define TDA1004X_WREF_MID        0x34
-+#define TDA1004X_WREF_LSB        0x35
-+#define TDA1004X_MUXOUT          0x36
-+#define TDA1004X_CONFADC2        0x37
-+#define TDA1004X_IOFFSET         0x38
-+
-+#define dprintk if (tda1004x_debug) printk
-+
-+static struct dvb_frontend_info tda10045h_info = {
-+	.name = "Philips TDA10045H",
-+	.type = FE_OFDM,
-+	.frequency_min = 51000000,
-+	.frequency_max = 858000000,
-+	.frequency_stepsize = 166667,
-+	.caps = FE_CAN_INVERSION_AUTO |
-+	    FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-+	    FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-+	    FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-+	    FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
-+};
-+
-+#pragma pack(1)
-+struct tda1004x_state {
-+	u8 tda1004x_address;
-+	u8 tuner_address;
-+	u8 initialised:1;
-+};
-+#pragma pack()
-+
-+struct fwinfo {
-+	int file_size;
-+	int fw_offset;
-+	int fw_size;
-+};
-+static struct fwinfo tda10045h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x34cc5,.fw_size = 30555} };
-+static int tda10045h_fwinfo_count = sizeof(tda10045h_fwinfo) / sizeof(struct fwinfo);
-+
-+static int errno;
-+
-+
-+static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data)
-+{
-+	int ret;
-+	u8 buf[] = { reg, data };
-+	struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };
-+
-+	dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
-+
-+        msg.addr = tda_state->tda1004x_address;
-+	ret = i2c->xfer(i2c, &msg, 1);
-+
-+	if (ret != 1)
-+		dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
-+		       __FUNCTION__, reg, data, ret);
-+
-+	dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
-+		reg, data, ret);
-+	return (ret != 1) ? -1 : 0;
-+}
-+
-+static int tda1004x_read_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg)
-+{
-+	int ret;
-+	u8 b0[] = { reg };
-+	u8 b1[] = { 0 };
-+	struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},
-+	                        { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};
-+
-+	dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
-+
-+        msg[0].addr = tda_state->tda1004x_address;
-+        msg[1].addr = tda_state->tda1004x_address;
-+	ret = i2c->xfer(i2c, msg, 2);
-+
-+	if (ret != 2) {
-+		dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
-+		       ret);
-+		return -1;
-+	}
-+
-+	dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
-+		reg, b1[0], ret);
-+	return b1[0];
-+}
-+
-+static int tda1004x_write_mask(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int mask, int data)
-+{
-+        int val;
-+	dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
-+		mask, data);
-+
-+	// read a byte and check
-+	val = tda1004x_read_byte(i2c, tda_state, reg);
-+	if (val < 0)
-+		return val;
-+
-+	// mask if off
-+	val = val & ~mask;
-+	val |= data & 0xff;
-+
-+	// write it out again
-+	return tda1004x_write_byte(i2c, tda_state, reg, val);
-+}
-+
-+static int tda1004x_write_buf(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, unsigned char *buf, int len)
-+{
-+	int i;
-+	int result;
-+
-+	dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
-+
-+	result = 0;
-+	for (i = 0; i < len; i++) {
-+		result = tda1004x_write_byte(i2c, tda_state, reg + i, buf[i]);
-+		if (result != 0)
-+			break;
-+	}
-+
-+	return result;
-+}
-+
-+static int tda1004x_enable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
-+{
-+        int result;
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	result = tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 2, 2);
-+	dvb_delay(1);
-+	return result;
-+}
-+
-+static int tda1004x_disable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
-+{
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	return tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 2, 0);
-+}
-+
-+
-+static int tda10045h_set_bandwidth(struct dvb_i2c_bus *i2c,
-+	                           struct tda1004x_state *tda_state,
-+		                   fe_bandwidth_t bandwidth)
-+{
-+        static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
-+        static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
-+        static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
-+
-+        switch (bandwidth) {
-+	case BANDWIDTH_6_MHZ:
-+		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);
-+		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
-+		break;
-+
-+	case BANDWIDTH_7_MHZ:
-+		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x80);
-+		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
-+		break;
-+
-+	case BANDWIDTH_8_MHZ:
-+		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);
-+		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	tda1004x_write_byte(i2c, tda_state, TDA1004X_IOFFSET, 0);
-+
-+        // done
-+        return 0;
-+}
-+
-+
-+static int tda1004x_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
-+{
-+	u8 fw_buf[65];
-+	struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = fw_buf,.len = 0 };
-+	struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 };
-+	unsigned char *firmware = NULL;
-+	int filesize;
-+	int fd;
-+	int fwinfo_idx;
-+	int fw_size = 0;
-+	int fw_pos;
-+	int tx_size;
-+        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
-+	mm_segment_t fs = get_fs();
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// Load the firmware
-+	set_fs(get_ds());
-+	fd = open(tda1004x_firmware, 0, 0);
-+	if (fd < 0) {
-+		printk("%s: Unable to open firmware %s\n", __FUNCTION__,
-+		       tda1004x_firmware);
-+		return -EIO;
-+	}
-+	filesize = lseek(fd, 0L, 2);
-+	if (filesize <= 0) {
-+		printk("%s: Firmware %s is empty\n", __FUNCTION__,
-+		       tda1004x_firmware);
-+		sys_close(fd);
-+		return -EIO;
-+	}
-+
-+	// find extraction parameters
-+	for (fwinfo_idx = 0; fwinfo_idx < tda10045h_fwinfo_count; fwinfo_idx++) {
-+		if (tda10045h_fwinfo[fwinfo_idx].file_size == filesize)
-+			break;
-+	}
-+	if (fwinfo_idx >= tda10045h_fwinfo_count) {
-+		printk("%s: Unsupported firmware %s\n", __FUNCTION__, tda1004x_firmware);
-+		sys_close(fd);
-+		return -EIO;
-+	}
-+	fw_size = tda10045h_fwinfo[fwinfo_idx].fw_size;
-+
-+	// allocate buffer for it
-+	firmware = vmalloc(fw_size);
-+	if (firmware == NULL) {
-+		printk("%s: Out of memory loading firmware\n",
-+		       __FUNCTION__);
-+		sys_close(fd);
-+		return -EIO;
-+	}
-+
-+	// read it!
-+	lseek(fd, tda10045h_fwinfo[fwinfo_idx].fw_offset, 0);
-+	if (read(fd, firmware, fw_size) != fw_size) {
-+		printk("%s: Failed to read firmware\n", __FUNCTION__);
-+		vfree(firmware);
-+		sys_close(fd);
-+		return -EIO;
-+	}
-+	sys_close(fd);
-+	set_fs(fs);
-+
-+	// Disable the MC44BC374C
-+	tda1004x_enable_tuner_i2c(i2c, tda_state);
-+	tuner_msg.addr = MC44BC374_ADDRESS;
-+	tuner_msg.buf = disable_mc44BC374c;
-+	tuner_msg.len = sizeof(disable_mc44BC374c);
-+	if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {
-+		i2c->xfer(i2c, &tuner_msg, 1);
-+	}
-+	tda1004x_disable_tuner_i2c(i2c, tda_state);
-+
-+	// set some valid bandwith parameters
-+        switch(tda_state->tda1004x_address) {
-+        case TDA10045H_ADDRESS:
-+                tda10045h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ);
-+                break;
-+        }
-+	dvb_delay(500);
-+
-+	// do the firmware upload
-+	tda1004x_write_byte(i2c, tda_state, TDA1004X_FWPAGE, 0);
-+        fw_msg.addr = tda_state->tda1004x_address;
-+	fw_pos = 0;
-+	while (fw_pos != fw_size) {
-+		// work out how much to send this time
-+		tx_size = fw_size - fw_pos;
-+		if (tx_size > 64) {
-+			tx_size = 64;
-+		}
-+		// send the chunk
-+		fw_buf[0] = TDA1004X_CODE_IN;
-+		memcpy(fw_buf + 1, firmware + fw_pos, tx_size);
-+		fw_msg.len = tx_size + 1;
-+		if (i2c->xfer(i2c, &fw_msg, 1) != 1) {
-+			vfree(firmware);
-+			return -EIO;
-+		}
-+		fw_pos += tx_size;
-+
-+		dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, fw_pos);
-+	}
-+	dvb_delay(100);
-+	vfree(firmware);
-+
-+	// Initialise the DSP and check upload was OK
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0);
-+	tda1004x_write_byte(i2c, tda_state, TDA1004X_DSP_CMD, 0x67);
-+	if ((tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA1) != 0x67) ||
-+	    (tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2) != 0x2c)) {
-+		printk("%s: firmware upload failed!\n", __FUNCTION__);
-+		return -EIO;
-+	}
-+
-+	// tda setup
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0);
-+        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10);
-+        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0x0);
-+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0);
-+        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONFADC1, 0x2e);
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0x80);
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0);
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0);
-+        tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1E, 0);
-+	tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1F, 0);
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_VBER_MSB, 0xe0, 0xa0);
-+
-+	// done
-+	return 0;
-+}
-+
-+static int tda1004x_encode_fec(int fec)
-+{
-+	// convert known FEC values
-+	switch (fec) {
-+	case FEC_1_2:
-+		return 0;
-+	case FEC_2_3:
-+		return 1;
-+	case FEC_3_4:
-+		return 2;
-+	case FEC_5_6:
-+		return 3;
-+	case FEC_7_8:
-+		return 4;
-+	}
-+
-+	// unsupported
-+	return -EINVAL;
-+}
-+
-+static int tda1004x_decode_fec(int tdafec)
-+{
-+	// convert known FEC values
-+	switch (tdafec) {
-+	case 0:
-+		return FEC_1_2;
-+	case 1:
-+		return FEC_2_3;
-+	case 2:
-+		return FEC_3_4;
-+	case 3:
-+		return FEC_5_6;
-+	case 4:
-+		return FEC_7_8;
-+	}
-+
-+	// unsupported
-+	return -1;
-+}
-+
-+static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c,
-+			   struct tda1004x_state *tda_state,
-+			   struct dvb_frontend_parameters *fe_params)
-+{
-+	u8 tuner_buf[4];
-+	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
-+	int tuner_frequency;
-+        u8 band, cp, filter;
-+	int counter, counter2;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// setup the frequency buffer
-+	switch (tda_state->tuner_address) {
-+	case TD1344_ADDRESS:
-+
-+		// setup tuner buffer
-+		tuner_frequency =
-+                        (((fe_params->frequency / 1000) * 6) + 217502) / 1000;
-+		tuner_buf[0] = tuner_frequency >> 8;
-+		tuner_buf[1] = tuner_frequency & 0xff;
-+		tuner_buf[2] = 0x88;
-+		if (fe_params->frequency < 550000000) {
-+			tuner_buf[3] = 0xab;
-+		} else {
-+			tuner_buf[3] = 0xeb;
-+		}
-+
-+		// tune it
-+		tda1004x_enable_tuner_i2c(i2c, tda_state);
-+		tuner_msg.addr = tda_state->tuner_address;
-+		tuner_msg.len = 4;
-+		i2c->xfer(i2c, &tuner_msg, 1);
-+
-+		// wait for it to finish
-+		tuner_msg.len = 1;
-+		tuner_msg.flags = I2C_M_RD;
-+		counter = 0;
-+		counter2 = 0;
-+		while (counter++ < 100) {
-+			if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
-+				if (tuner_buf[0] & 0x40) {
-+					counter2++;
-+				} else {
-+					counter2 = 0;
-+				}
-+			}
-+
-+			if (counter2 > 10) {
-+				break;
-+			}
-+		}
-+		tda1004x_disable_tuner_i2c(i2c, tda_state);
-+		break;
-+
-+	case TDM1316L_ADDRESS:
-+		// determine charge pump
-+		tuner_frequency = fe_params->frequency + 36130000;
-+		if (tuner_frequency < 87000000) {
-+			return -EINVAL;
-+		} else if (tuner_frequency < 130000000) {
-+                        cp = 3;
-+		} else if (tuner_frequency < 160000000) {
-+			cp = 5;
-+		} else if (tuner_frequency < 200000000) {
-+			cp = 6;
-+		} else if (tuner_frequency < 290000000) {
-+			cp = 3;
-+		} else if (tuner_frequency < 420000000) {
-+			cp = 5;
-+		} else if (tuner_frequency < 480000000) {
-+			cp = 6;
-+		} else if (tuner_frequency < 620000000) {
-+			cp = 3;
-+		} else if (tuner_frequency < 830000000) {
-+			cp = 5;
-+		} else if (tuner_frequency < 895000000) {
-+			cp = 7;
-+		} else {
-+			return -EINVAL;
-+		}
-+
-+		// determine band
-+		if (fe_params->frequency < 49000000) {
-+                        return -EINVAL;
-+		} else if (fe_params->frequency < 159000000) {
-+                        band = 1;
-+		} else if (fe_params->frequency < 444000000) {
-+			band = 2;
-+		} else if (fe_params->frequency < 861000000) {
-+			band = 4;
-+		} else {
-+			return -EINVAL;
-+		}
-+
-+		// work out filter
-+		switch (fe_params->u.ofdm.bandwidth) {
-+		case BANDWIDTH_6_MHZ:
-+                        // 6 MHz isn't supported directly, but set this to
-+                        // the 8 MHz setting in case we can fiddle it later
-+                        filter = 1;
-+                        break;
-+
-+                case BANDWIDTH_7_MHZ:
-+			filter = 0;
-+			break;
-+
-+		case BANDWIDTH_8_MHZ:
-+			filter = 1;
-+			break;
-+
-+		default:
-+			return -EINVAL;
-+		}
-+
-+		// calculate tuner parameters
-+		tuner_frequency =
-+                        (((fe_params->frequency / 1000) * 6) + 217280) / 1000;
-+		tuner_buf[0] = tuner_frequency >> 8;
-+		tuner_buf[1] = tuner_frequency & 0xff;
-+		tuner_buf[2] = 0xca;
-+		tuner_buf[3] = (cp << 5) | (filter << 3) | band;
-+
-+		// tune it
-+		tda1004x_enable_tuner_i2c(i2c, tda_state);
-+		tuner_msg.addr = tda_state->tuner_address;
-+		tuner_msg.len = 4;
-+                if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {
-+			return -EIO;
-+		}
-+		dvb_delay(1);
-+		tda1004x_disable_tuner_i2c(i2c, tda_state);
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	dprintk("%s: success\n", __FUNCTION__);
-+
-+	// done
-+	return 0;
-+}
-+
-+static int tda1004x_set_fe(struct dvb_i2c_bus *i2c,
-+	 	           struct tda1004x_state *tda_state,
-+		           struct dvb_frontend_parameters *fe_params)
-+{
-+	int tmp;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+
-+	// set frequency
-+	tmp = tda1004x_set_frequency(i2c, tda_state, fe_params);
-+	if (tmp < 0)
-+		return tmp;
-+
-+        // hardcoded to use auto as much as possible
-+        fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
-+        fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
-+        fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
-+
-+	// Set standard params.. or put them to auto
-+	if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
-+	    (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
-+	    (fe_params->u.ofdm.constellation == QAM_AUTO) ||
-+	    (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 1, 1);	// enable auto
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x03, 0);	// turn off constellation bits
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 0);	// turn off hierarchy bits
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0x3f, 0);	// turn off FEC bits
-+	} else {
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 1, 0);	// disable auto
-+
-+		// set HP FEC
-+		tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
-+		if (tmp < 0) return tmp;
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 7, tmp);
-+
-+		// set LP FEC
-+		if (fe_params->u.ofdm.code_rate_LP != FEC_NONE) {
-+			tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
-+			if (tmp < 0) return tmp;
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
-+		}
-+
-+		// set constellation
-+		switch (fe_params->u.ofdm.constellation) {
-+		case QPSK:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 3, 0);
-+			break;
-+
-+		case QAM_16:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 3, 1);
-+			break;
-+
-+		case QAM_64:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 3, 2);
-+			break;
-+
-+		default:
-+			return -EINVAL;
-+		}
-+
-+		// set hierarchy
-+		switch (fe_params->u.ofdm.hierarchy_information) {
-+		case HIERARCHY_NONE:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
-+			break;
-+
-+		case HIERARCHY_1:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
-+			break;
-+
-+		case HIERARCHY_2:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
-+			break;
-+
-+		case HIERARCHY_4:
-+			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
-+			break;
-+
-+		default:
-+			return -EINVAL;
-+		}
-+	}
-+
-+        // set bandwidth
-+        switch(tda_state->tda1004x_address) {
-+        case TDA10045H_ADDRESS:
-+                tda10045h_set_bandwidth(i2c, tda_state, fe_params->u.ofdm.bandwidth);
-+                break;
-+        }
-+
-+	// set inversion
-+	switch (fe_params->inversion) {
-+	case INVERSION_OFF:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x20, 0);
-+		break;
-+
-+	case INVERSION_ON:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x20, 0x20);
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	// set guard interval
-+	switch (fe_params->u.ofdm.guard_interval) {
-+	case GUARD_INTERVAL_1_32:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
-+		break;
-+
-+	case GUARD_INTERVAL_1_16:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
-+		break;
-+
-+	case GUARD_INTERVAL_1_8:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
-+		break;
-+
-+	case GUARD_INTERVAL_1_4:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
-+		break;
-+
-+	case GUARD_INTERVAL_AUTO:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 2);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	// set transmission mode
-+	switch (fe_params->u.ofdm.transmission_mode) {
-+	case TRANSMISSION_MODE_2K:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 4, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
-+		break;
-+
-+	case TRANSMISSION_MODE_8K:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 4, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
-+		break;
-+
-+	case TRANSMISSION_MODE_AUTO:
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 4, 4);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 0);
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	// reset DSP
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);
-+	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);
-+	dvb_delay(10);
-+
-+	// done
-+	return 0;
-+}
-+
-+
-+static int tda1004x_get_fe(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, struct dvb_frontend_parameters *fe_params)
-+{
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// inversion status
-+	fe_params->inversion = INVERSION_OFF;
-+	if (tda1004x_read_byte(i2c, tda_state, TDA1004X_CONFC1) & 0x20) {
-+		fe_params->inversion = INVERSION_ON;
-+	}
-+
-+	// bandwidth
-+	switch (tda1004x_read_byte(i2c, tda_state, TDA1004X_WREF_LSB)) {
-+	case 0x14:
-+		fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
-+		break;
-+	case 0xdb:
-+		fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
-+		break;
-+	case 0x4f:
-+		fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
-+		break;
-+	}
-+
-+	// FEC
-+	fe_params->u.ofdm.code_rate_HP =
-+	    tda1004x_decode_fec(tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF2) & 7);
-+	fe_params->u.ofdm.code_rate_LP =
-+	    tda1004x_decode_fec((tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF2) >> 3) & 7);
-+
-+	// constellation
-+	switch (tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF1) & 3) {
-+	case 0:
-+		fe_params->u.ofdm.constellation = QPSK;
-+		break;
-+	case 1:
-+		fe_params->u.ofdm.constellation = QAM_16;
-+		break;
-+	case 2:
-+		fe_params->u.ofdm.constellation = QAM_64;
-+		break;
-+	}
-+
-+	// transmission mode
-+	fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
-+	if (tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF1) & 0x10) {
-+		fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
-+	}
-+
-+	// guard interval
-+	switch ((tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
-+	case 0:
-+		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
-+		break;
-+	case 1:
-+		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
-+		break;
-+	case 2:
-+		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
-+		break;
-+	case 3:
-+		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
-+		break;
-+	}
-+
-+	// hierarchy
-+	switch ((tda1004x_read_byte(i2c, tda_state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
-+	case 0:
-+		fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
-+		break;
-+	case 1:
-+		fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
-+		break;
-+	case 2:
-+		fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
-+		break;
-+	case 3:
-+		fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
-+		break;
-+	}
-+
-+	// done
-+	return 0;
-+}
-+
-+
-+static int tda1004x_read_status(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, fe_status_t * fe_status)
-+{
-+	int status;
-+        int cber;
-+        int vber;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// read status
-+	status = tda1004x_read_byte(i2c, tda_state, TDA1004X_STATUS_CD);
-+	if (status == -1) {
-+		return -EIO;
-+	}
-+
-+        // decode
-+	*fe_status = 0;
-+        if (status & 4) *fe_status |= FE_HAS_SIGNAL;
-+        if (status & 2) *fe_status |= FE_HAS_CARRIER;
-+        if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-+
-+        // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
-+        // is getting anything valid
-+        if (!(*fe_status & FE_HAS_VITERBI)) {
-+                // read the CBER
-+                cber = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_LSB);
-+                if (cber == -1) return -EIO;
-+                status = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_MSB);
-+                if (status == -1) return -EIO;
-+                cber |= (status << 8);
-+                tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_RESET);
-+
-+                if (cber != 65535) {
-+                        *fe_status |= FE_HAS_VITERBI;
-+                }
-+        }
-+
-+        // if we DO have some valid VITERBI output, but don't already have SYNC
-+        // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
-+        if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
-+                // read the VBER
-+                vber = tda1004x_read_byte(i2c, tda_state, TDA1004X_VBER_LSB);
-+                if (vber == -1) return -EIO;
-+                status = tda1004x_read_byte(i2c, tda_state, TDA1004X_VBER_MID);
-+                if (status == -1) return -EIO;
-+                vber |= (status << 8);
-+                status = tda1004x_read_byte(i2c, tda_state, TDA1004X_VBER_MSB);
-+                if (status == -1) return -EIO;
-+                vber |= ((status << 16) & 0x0f);
-+                tda1004x_read_byte(i2c, tda_state, TDA1004X_CVBER_LUT);
-+
-+                // if RS has passed some valid TS packets, then we must be
-+                // getting some SYNC bytes
-+                if (vber < 16632) {
-+                        *fe_status |= FE_HAS_SYNC;
-+                }
-+        }
-+
-+	// success
-+	dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
-+	return 0;
-+}
-+
-+static int tda1004x_read_signal_strength(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * signal)
-+{
-+	int tmp;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// read it
-+	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_SIGNAL_STRENGTH);
-+	if (tmp < 0)
-+		return -EIO;
-+
-+	// done
-+	*signal = (tmp << 8) | tmp;
-+	dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
-+	return 0;
-+}
-+
-+
-+static int tda1004x_read_snr(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * snr)
-+{
-+	int tmp;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// read it
-+	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_SNR);
-+	if (tmp < 0)
-+		return -EIO;
-+        if (tmp) {
-+                tmp = 255 - tmp;
-+        }
-+
-+        // done
-+	*snr = ((tmp << 8) | tmp);
-+	dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
-+	return 0;
-+}
-+
-+static int tda1004x_read_ucblocks(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ucblocks)
-+{
-+	int tmp;
-+	int tmp2;
-+	int counter;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// read the UCBLOCKS and reset
-+	counter = 0;
-+	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_UNCOR);
-+	if (tmp < 0)
-+		return -EIO;
-+        tmp &= 0x7f;
-+	while (counter++ < 5) {
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);
-+		tda1004x_write_mask(i2c, tda_state, TDA1004X_UNCOR, 0x80, 0);
-+
-+		tmp2 = tda1004x_read_byte(i2c, tda_state, TDA1004X_UNCOR);
-+		if (tmp2 < 0)
-+			return -EIO;
-+		tmp2 &= 0x7f;
-+		if ((tmp2 < tmp) || (tmp2 == 0))
-+			break;
-+	}
-+
-+	// done
-+	if (tmp != 0x7f) {
-+		*ucblocks = tmp;
-+	} else {
-+		*ucblocks = 0xffffffff;
-+	}
-+	dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
-+	return 0;
-+}
-+
-+static int tda1004x_read_ber(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u32* ber)
-+{
-+        int tmp;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// read it in
-+        tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_LSB);
-+        if (tmp < 0) return -EIO;
-+        *ber = tmp << 1;
-+        tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_MSB);
-+        if (tmp < 0) return -EIO;
-+        *ber |= (tmp << 9);
-+        tda1004x_read_byte(i2c, tda_state, TDA1004X_CBER_RESET);
-+
-+	// done
-+	dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
-+	return 0;
-+}
-+
-+
-+static int tda1004x_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
-+{
-+	int status = 0;
-+	struct dvb_i2c_bus *i2c = fe->i2c;
-+	struct tda1004x_state *tda_state = (struct tda1004x_state *) &(fe->data);
-+
-+	dprintk("%s: cmd=0x%x\n", __FUNCTION__, cmd);
-+
-+	switch (cmd) {
-+	case FE_GET_INFO:
-+                switch(tda_state->tda1004x_address) {
-+                case TDA10045H_ADDRESS:
-+        		memcpy(arg, &tda10045h_info, sizeof(struct dvb_frontend_info));
-+                        break;
-+                }
-+		break;
-+
-+	case FE_READ_STATUS:
-+		return tda1004x_read_status(i2c, tda_state, (fe_status_t *) arg);
-+
-+	case FE_READ_BER:
-+		return tda1004x_read_ber(i2c, tda_state, (u32 *) arg);
-+
-+	case FE_READ_SIGNAL_STRENGTH:
-+		return tda1004x_read_signal_strength(i2c, tda_state, (u16 *) arg);
-+
-+	case FE_READ_SNR:
-+		return tda1004x_read_snr(i2c, tda_state, (u16 *) arg);
-+
-+	case FE_READ_UNCORRECTED_BLOCKS:
-+		return tda1004x_read_ucblocks(i2c, tda_state, (u32 *) arg);
-+
-+	case FE_SET_FRONTEND:
-+		return tda1004x_set_fe(i2c, tda_state, (struct dvb_frontend_parameters*) arg);
-+
-+	case FE_GET_FRONTEND:
-+		return tda1004x_get_fe(i2c, tda_state, (struct dvb_frontend_parameters*) arg);
-+
-+	case FE_INIT:
-+		// don't bother reinitialising
-+		if (tda_state->initialised)
-+			return 0;
-+
-+		// OK, perform initialisation
-+                status = tda1004x_init(i2c, tda_state);
-+		if (status == 0)
-+			tda_state->initialised = 1;
-+		return status;
-+
-+	default:
-+		return -EOPNOTSUPP;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+static int tda1004x_attach(struct dvb_i2c_bus *i2c)
-+{
-+        int tda1004x_address = -1;
-+	int tuner_address = -1;
-+	struct tda1004x_state tda_state;
-+	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=0, .len=0 };
-+        static u8 td1344_init[] = { 0x0b, 0xf5, 0x88, 0xab };
-+        static u8 tdm1316l_init[] = { 0x0b, 0xf5, 0x85, 0xab };
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	// probe for frontend
-+        tda_state.tda1004x_address = TDA10045H_ADDRESS;
-+	if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x25) {
-+                tda1004x_address = TDA10045H_ADDRESS;
-+                printk("tda1004x: Detected Philips TDA10045H.\n");
-+        }
-+
-+        // did we find a frontend?
-+        if (tda1004x_address == -1) {
-+		return -ENODEV;
-+        }
-+
-+	// supported tuner?
-+	tda1004x_enable_tuner_i2c(i2c, &tda_state);
-+	tuner_msg.addr = TD1344_ADDRESS;
-+	tuner_msg.buf = td1344_init;
-+	tuner_msg.len = sizeof(td1344_init);
-+	if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
-+                dvb_delay(1);
-+		tuner_address = TD1344_ADDRESS;
-+		printk("tda1004x: Detected Philips TD1344 tuner. PLEASE CHECK THIS AND REPORT BACK!.\n");
-+	} else {
-+		tuner_msg.addr = TDM1316L_ADDRESS;
-+                tuner_msg.buf = tdm1316l_init;
-+                tuner_msg.len = sizeof(tdm1316l_init);
-+                if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
-+                        dvb_delay(1);
-+			tuner_address = TDM1316L_ADDRESS;
-+			printk("tda1004x: Detected Philips TDM1316L tuner.\n");
-+		}
-+	}
-+	tda1004x_disable_tuner_i2c(i2c, &tda_state);
-+
-+	// did we find a tuner?
-+	if (tuner_address == -1) {
-+		printk("tda1004x: Detected, but with unknown tuner.\n");
-+		return -ENODEV;
-+	}
-+
-+        // create state
-+        tda_state.tda1004x_address = tda1004x_address;
-+	tda_state.tuner_address = tuner_address;
-+	tda_state.initialised = 0;
-+
-+	// register
-+        switch(tda_state.tda1004x_address) {
-+        case TDA10045H_ADDRESS:
-+        	dvb_register_frontend(tda1004x_ioctl, i2c, (void *)(*((u32*) &tda_state)), &tda10045h_info);
-+                break;
-+        }
-+
-+	// success
-+	return 0;
-+}
-+
-+
-+static
-+void tda1004x_detach(struct dvb_i2c_bus *i2c)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dvb_unregister_frontend(tda1004x_ioctl, i2c);
-+}
-+
-+
-+static
-+int __init init_tda1004x(void)
-+{
-+	return dvb_register_i2c_device(THIS_MODULE, tda1004x_attach, tda1004x_detach);
-+}
-+
-+
-+static
-+void __exit exit_tda1004x(void)
-+{
-+	dvb_unregister_i2c_device(tda1004x_attach);
-+}
-+
-+module_init(init_tda1004x);
-+module_exit(exit_tda1004x);
-+
-+MODULE_DESCRIPTION("Philips TDA10045H DVB-T Frontend");
-+MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(tda1004x_debug, "i");
-+MODULE_PARM_DESC(tda1004x_debug, "enable verbose debug messages");
-+
-+MODULE_PARM(tda1004x_firmware, "s");
-+MODULE_PARM_DESC(tda1004x_firmware, "Where to find the firmware file");
---- linux-2.6.0-test1/drivers/media/dvb/frontends/ves1820.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/frontends/ves1820.c	2003-07-19 17:03:49.000000000 -0700
-@@ -95,7 +95,7 @@ static struct dvb_frontend_info ves1820_
- 
- static u8 ves1820_inittab [] =
- {
--	0x69, 0x6A, 0x9B, 0x0A, 0x52, 0x46, 0x26, 0x1A,
-+	0x69, 0x6A, 0x9B, 0x12, 0x12, 0x46, 0x26, 0x1A,
- 	0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x28,
- 	0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
- 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-@@ -109,7 +109,7 @@ static int ves1820_writereg (struct dvb_
- {
- 	u8 addr = GET_DEMOD_ADDR(fe->data);
-         u8 buf[] = { 0x00, reg, data };
--	struct i2c_msg msg = { addr: addr, .flags = 0, .buf = buf, .len = 3 };
-+	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
- 	struct dvb_i2c_bus *i2c = fe->i2c;
-         int ret;
- 
-@@ -130,8 +130,8 @@ static u8 ves1820_readreg (struct dvb_fr
- 	u8 b0 [] = { 0x00, reg };
- 	u8 b1 [] = { 0 };
- 	u8 addr = GET_DEMOD_ADDR(fe->data);
--	struct i2c_msg msg [] = { { addr: addr, .flags = 0, .buf = b0, .len = 2 },
--	                   { addr: addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-+	struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b0, .len = 2 },
-+	                   { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
- 	struct dvb_i2c_bus *i2c = fe->i2c;
- 	int ret;
- 
-@@ -147,7 +147,7 @@ static u8 ves1820_readreg (struct dvb_fr
- static int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4])
- {
-         int ret;
--        struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = 4 };
-+        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
- 
-         ret = i2c->xfer (i2c, &msg, 1);
- 
---- linux-2.6.0-test1/drivers/media/dvb/Kconfig	2003-06-14 12:18:06.000000000 -0700
-+++ 25/drivers/media/dvb/Kconfig	2003-07-19 17:03:49.000000000 -0700
-@@ -33,9 +33,19 @@ source "drivers/media/dvb/dvb-core/Kconf
- source "drivers/media/dvb/frontends/Kconfig"
- 
- comment "Supported SAA7146 based PCI Adapters"
--	depends on DVB
-+	depends on DVB && PCI
- 
- source "drivers/media/dvb/ttpci/Kconfig"
- 
-+comment "Supported USB Adapters"
-+	depends on DVB && USB
-+
-+source "drivers/media/dvb/ttusb-budget/Kconfig"
-+source "drivers/media/dvb/ttusb-dec/Kconfig"
-+
-+comment "Supported FlexCopII (B2C2) Adapters"
-+	depends on DVB && PCI
-+source "drivers/media/dvb/b2c2/Kconfig"
-+
- endmenu
- 
---- linux-2.6.0-test1/drivers/media/dvb/Makefile	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/media/dvb/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -2,4 +2,5 @@
- # Makefile for the kernel multimedia device drivers.
- #
- 
--obj-y        := dvb-core/ frontends/ ttpci/ # ttusb-budget/
-+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/
-+
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/av7110.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/av7110.c	2003-07-19 17:03:49.000000000 -0700
-@@ -86,6 +86,7 @@
- 	#define DEB_EE(x)
- #endif
- 
-+#include "ttpci-eeprom.h"
- #include "av7110.h"
- #include "av7110_ipack.h"
- 
-@@ -110,7 +111,8 @@ static int hw_sections = 1;
- 
- int av7110_num = 0;
- 
--#define FW_CI_LL_SUPPORT(arm_app) (((arm_app) >> 16) & 0x8000)
-+#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
-+#define FW_VERSION(arm_app)       ((arm_app) & 0x0000FFFF)
- 
- /****************************************************************************
-  * DEBI functions
-@@ -1089,7 +1091,7 @@ static int OutCommand(struct av7110 *av7
-         u32 stat;
- #endif
- 
--	DEB_EE(("av7110: %p\n",av7110));
-+//	DEB_EE(("av7110: %p\n",av7110));
- 
- 	if (!av7110->arm_ready) {
- 		DEB_D(("arm not ready.\n"));
-@@ -1166,7 +1168,7 @@ static inline int SOutCommand(struct av7
- {
-         int ret;
-         
-- 	DEB_EE(("av7110: %p\n",av7110));
-+// 	DEB_EE(("av7110: %p\n",av7110));
- 
-         if (!av7110->arm_ready) {
- 		DEB_D(("arm not ready.\n"));
-@@ -1190,7 +1192,7 @@ static int outcom(struct av7110 *av7110,
-         u16 buf[num+2];
-         int i, ret;
- 
-- 	DEB_EE(("av7110: %p\n",av7110));
-+// 	DEB_EE(("av7110: %p\n",av7110));
- 
-         buf[0]=(( type << 8 ) | com);
-         buf[1]=num;
-@@ -1332,7 +1334,7 @@ static inline int msp_writereg(struct av
- 
- static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
- {
-- 	DEB_EE(("av7110: %p\n",av7110));
-+// 	DEB_EE(("av7110: %p\n",av7110));
- 
-         return outcom(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
- }
-@@ -1659,6 +1661,24 @@ static void OSDSetColor(struct av7110 *a
-                   color, ((blend>>4)&0x0f));
- }
- 
-+static int OSDSetPalette(struct av7110 *av7110, u32 *colors, u8 first, u8 last)
-+{
-+       int i;
-+       int length = last - first + 1;
-+
-+       if (length * 4 > DATA_BUFF3_SIZE)
-+               return -1;
-+
-+       for (i=0; i<length; i++) {
-+               u32 blend = (colors[i] & 0xF0000000) >> 4;
-+               u32 yuv = blend ? RGB2YUV(colors[i] & 0xFF, (colors[i] >> 8) & 0xFF, (colors[i] >> 16) & 0xFF) | blend : 0;
-+               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); // TODO kls2003-06-15: not sure if this is endian-proof
-+               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i*4, yuv, 4);
-+       }
-+       return outcom(av7110, COMTYPE_OSD, Set_Palette, 4,
-+               av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], first, last);
-+}
-+
- static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
- {
-         uint w, h, bpp, bpl, size, lpb, bnum, brest;
-@@ -1721,6 +1741,9 @@ static int OSD_DrawCommand(struct av7110
-                 return 0;
-         case OSD_SetPalette:
-         {      
-+                if (FW_VERSION(av7110->arm_app) >= 0x2618)
-+                        OSDSetPalette(av7110, (u32 *)dc->data, dc->color, dc->x0);
-+                else {
-                 int i, len=dc->x0-dc->color+1;
-                 u8 *colors=(u8 *)dc->data;
- 
-@@ -1728,6 +1751,7 @@ static int OSD_DrawCommand(struct av7110
-                         OSDSetColor(av7110, dc->color+i,
-                                     colors[i*4]  , colors[i*4+1],
-                                     colors[i*4+2], colors[i*4+3]);
-+                }
-                 return 0;
-         }
-         case OSD_SetTrans: 
-@@ -2087,28 +2111,28 @@ static void SetMode(struct av7110 *av711
- 
- static inline void TestMode(struct av7110 *av7110, int mode)
- {
-- 	DEB_EE(("av7110: %p\n",av7110));
-+//	DEB_EE(("av7110: %p\n",av7110));
-         outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode);
- }
- 
- static inline void VidMode(struct av7110 *av7110, int mode)
- {
-- 	DEB_EE(("av7110: %p\n",av7110));
-+// 	DEB_EE(("av7110: %p\n",av7110));
-         outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
- }
-            
- 
--static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
-+static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
- {
-- 	DEB_EE(("av7110: %p\n",av7110));
-+// 	DEB_EE(("av7110: %p\n",av7110));
-         return outcom(av7110, 0x80, 0x02, 4, 
-                       (com>>16), (com&0xffff), 
-                       (arg>>16), (arg&0xffff));
- }
- 
--static inline int audcom(struct av7110 *av7110, u32 com)
-+static int inline audcom(struct av7110 *av7110, u32 com)
- {
--	DEB_EE(("av7110: %p\n",av7110));
-+//	DEB_EE(("av7110: %p\n",av7110));
- 	return outcom(av7110, 0x80, 0x03, 4, 
-                       (com>>16), (com&0xffff));
- }
-@@ -2583,38 +2607,274 @@ void p_to_t(u8 const *buf, long int leng
-  * V4L SECTION
-  ****************************************************************************/
- 
--int av7110_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
-+static struct v4l2_input inputs[2] = {
-+	{ 0,	"DVB",		V4L2_INPUT_TYPE_CAMERA,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 
-+	{ 1,	"ANALOG",	V4L2_INPUT_TYPE_TUNER,	2, 1, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+};
-+
-+/* taken from ves1820.c */
-+static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
-+{
-+	u8 addr = 0x09;
-+        u8 buf[] = { 0x00, reg, data };
-+	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
-+
-+  	DEB_EE(("av7710: dev: %p\n",dev));
-+
-+	if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
-+		return -1;
-+	}
-+	return 0;
-+}
-+
-+static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
-+{
-+        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
-+
-+  	DEB_EE(("av7710: dev: %p\n",dev));
-+
-+	if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
-+		return -1;
-+	}
-+	return 0;
-+}
-+
-+
-+/**
-+ *   set up the downconverter frequency divisor for a
-+ *   reference clock comparision frequency of 62.5 kHz.
-+ */
-+static int tuner_set_tv_freq (struct saa7146_dev *dev, u32 freq)
-+{
-+        u32 div;
-+	u8 config;
-+        u8 buf [4];
-+
-+ 	DEB_EE(("av7710: freq: 0x%08x\n",freq));
-+
-+	/* magic number: 56. tuning with the frequency given by v4l2
-+	   is always off by 56*62.5 kHz...*/
-+	div = freq + 56;
-+
-+	buf[0] = (div >> 8) & 0x7f;
-+	buf[1] = div & 0xff;
-+	buf[2] = 0x8e;
-+
-+	if (freq < 16*168.25 ) 
-+		config = 0xa0;
-+	else if (freq < 16*447.25) 
-+		config = 0x90;
-+	else
-+		config = 0x30;
-+	config &= ~0x02;
-+
-+	buf[3] = config;
-+
-+        return tuner_write (dev, 0x61, buf);
-+}
-+
-+static struct saa7146_standard analog_standard[];
-+static struct saa7146_standard dvb_standard[];
-+static struct saa7146_standard standard[];
-+
-+int av7110_dvb_c_switch(struct saa7146_fh *fh)
-+{
-+	struct saa7146_dev *dev = fh->dev;
-+	struct saa7146_vv *vv = dev->vv_data;
-+	struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
-+	u16 buf[3] = { ((COMTYPE_AUDIODAC << 8) + ADSwitch), 1, 1 };
-+
-+	u8 band = 0;
-+	int source, sync;
-+	struct saa7146_fh *ov_fh = NULL;
-+	int restart_overlay = 0;
-+
-+	DEB_EE(("av7110: %p\n",av7110));
-+
-+	if( vv->ov_data != NULL ) {
-+		ov_fh = vv->ov_data->fh;
-+		saa7146_stop_preview(ov_fh);
-+		restart_overlay = 1;
-+	}
-+
-+	if( 0 != av7110->current_input ) {
-+		buf[2] = 0;
-+		band = 0x68; /* analog band */
-+		source = SAA7146_HPS_SOURCE_PORT_B;
-+		sync = SAA7146_HPS_SYNC_PORT_B;
-+		memcpy(standard,analog_standard,sizeof(struct saa7146_standard)*2);
-+	} else {
-+		buf[2] = 1;
-+		band = 0x28; /* digital band */	
-+		source = SAA7146_HPS_SOURCE_PORT_A;
-+		sync = SAA7146_HPS_SYNC_PORT_A;
-+		memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
-+	}
-+
-+	/* hmm, this does not do anything!? */
-+	if (OutCommand(av7110, buf, 3)) {
-+		printk("ADSwitch error\n");
-+	}
-+
-+	if( 0 != ves1820_writereg(dev, 0x0f, band )) {
-+		printk("setting band in demodulator failed.\n");
-+	}
-+	saa7146_set_hps_source_and_sync(dev, source, sync);
-+
-+	/* restart overlay if it was active before */
-+	if( 0 != restart_overlay ) {
-+		saa7146_start_preview(ov_fh);
-+	}
-+
-+	return 0;
-+}
-+
-+int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
- {
-+	struct saa7146_dev *dev = fh->dev;
-+	struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
-  	DEB_EE(("saa7146_dev: %p\n",dev));
- 
- 	switch(cmd) {
-+	case VIDIOC_G_TUNER:
-+	{
-+		struct v4l2_tuner *t = arg;
-+
-+		DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
-+
-+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
-+			return -EINVAL;
-+		}
-+
-+		memset(t,0,sizeof(*t));
-+		strcpy(t->name, "Television");
-+
-+		t->type = V4L2_TUNER_ANALOG_TV;
-+		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-+		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
-+		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
-+		/* FIXME: add the real signal strength here */
-+		t->signal = 0xffff;
-+		t->afc = 0;		
-+		/* fixme: real autodetection here */
-+		t->rxsubchans 	= V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
-+
-+		return 0;
-+	}
-+	case VIDIOC_S_TUNER:
-+	{
-+		struct v4l2_tuner *t = arg;
-+		
-+		DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index));
-+
-+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
-+			return -EINVAL;
-+		}
-+
-+
-+		switch(t->audmode) {
-+			case V4L2_TUNER_MODE_STEREO: {
-+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
-+				break;
-+			}
-+			case V4L2_TUNER_MODE_LANG1: {
-+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
-+				break;
-+			}
-+			case V4L2_TUNER_MODE_LANG2: {
-+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
-+				break;
-+			}
-+			default: { /* case V4L2_TUNER_MODE_MONO: {*/
-+				DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
-+				break;
-+			}
-+		}
-+
-+		return 0;
-+	}
-+	case VIDIOC_G_FREQUENCY:
-+	{
-+		struct v4l2_frequency *f = arg;
-+
-+		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency));
-+
-+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
-+			return -EINVAL;
-+		}
-+
-+		memset(f,0,sizeof(*f));
-+		f->type = V4L2_TUNER_ANALOG_TV;
-+		f->frequency =  av7110->current_freq;
-+
-+		return 0;
-+	}
-+	case VIDIOC_S_FREQUENCY:
-+	{
-+		struct v4l2_frequency *f = arg;
-+
-+		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
-+
-+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
-+			return -EINVAL;
-+		}
-+
-+		if (V4L2_TUNER_ANALOG_TV != f->type)
-+			return -EINVAL;
-+
-+		/* tune in desired frequency */			
-+		tuner_set_tv_freq(dev, f->frequency);
-+		av7110->current_freq = f->frequency;
-+
-+		return 0;
-+	}
- 	case VIDIOC_ENUMINPUT:
- 	{
- 		struct v4l2_input *i = arg;
- 		
-+		DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));
-+
-+		if( 0 != av7110->has_analog_tuner ) {
-+			if( i->index < 0 || i->index >= 2) {
-+				return -EINVAL;
-+			}
-+		} else {
- 		if( i->index != 0 ) {
- 			return -EINVAL;
- 		}
-+		}		
- 
--		memset(i,0,sizeof(*i));
--		i->index = 0;
--		strcpy(i->name, "DVB");
--		i->type = V4L2_INPUT_TYPE_CAMERA;
--		i->audioset = 1;
-+		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
- 		
- 		return 0;
- 	}
- 	case VIDIOC_G_INPUT:
- 	{
- 		int *input = (int *)arg;
--		*input = 0;
-+		*input = av7110->current_input;
-+		DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));
- 		return 0;		
- 	}	
- 	case VIDIOC_S_INPUT:
- 	{
-+		int input = *(int *)arg;
-+
-+		DEB_EE(("VIDIOC_S_INPUT: %d\n", input));
-+
-+		if( 0 == av7110->has_analog_tuner ) {
- 		return 0;		
- 	}	
-+		
-+		if( input < 0 || input >= 2) {
-+			return -EINVAL;
-+		}
-+		
-+		/* fixme: switch inputs here */
-+		av7110->current_input = input;
-+		return av7110_dvb_c_switch(fh);
-+	}	
- 	default:
-+		printk("no such ioctl\n");
- 		return -ENOIOCTLCMD;
- 	}
- 	return 0;
-@@ -2997,7 +3257,7 @@ static int dvb_get_stc(struct dmx_demux 
- 	DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
- 			fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
- 
--	*stc =  (((uint64_t)fwstc[2] & 1) << 32) |
-+	*stc =  (((uint64_t)(~fwstc[2]) & 1) << 32) |
- 		(((uint64_t)fwstc[1])     << 16) | ((uint64_t)fwstc[0]);
- 	*base = 1;
- 
-@@ -4006,7 +4266,6 @@ static int av7110_register(struct av7110
- #endif
- //        }
-         
--        av7110->dvb_net.card_num=av7110->dvb_adapter->num;
-         dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
- 
- 	return 0;
-@@ -4061,9 +4320,16 @@ struct saa7146_extension_ioctls ioctls[]
- 	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
- 	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
- 	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_FREQUENCY, 	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_G_TUNER, 	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_TUNER, 	SAA7146_EXCLUSIVE },
- 	{ 0, 0 }
- };
- 
-+static struct saa7146_ext_vv av7110_vv_data_st;
-+static struct saa7146_ext_vv av7110_vv_data_c;
-+
- static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
- {
- 	struct av7110 *av7110 = NULL;
-@@ -4081,7 +4347,16 @@ static int av7110_attach (struct saa7146
- 
- 	DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
- 
--	if (saa7146_vv_init(dev)) {
-+	/* special case DVB-C: these cards have an analog tuner
-+	   plus need some special handling, so we have separate
-+	   saa7146_ext_vv data for these... */
-+	if (dev->pci->subsystem_vendor == 0x110a) {
-+		ret = saa7146_vv_init(dev, &av7110_vv_data_c);
-+	} else {
-+		ret = saa7146_vv_init(dev, &av7110_vv_data_st);
-+	}
-+	
-+	if ( 0 != ret) {
- 		ERR(("cannot init capture device. skipping.\n"));
- 		kfree(av7110);
- 		return -1;
-@@ -4114,6 +4389,8 @@ static int av7110_attach (struct saa7146
- 		return -ENOMEM;
- 	}
- 
-+	ttpci_eeprom_parse_mac(av7110->i2c_bus);
-+
- 	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
- 	saa7146_write(dev, BCS_CTRL, 0x80400040);
- 
-@@ -4186,9 +4463,9 @@ static int av7110_attach (struct saa7146
- 	bootarm(av7110);
- 	firmversion(av7110);
- 
--	if ((av7110->arm_app&0xffff)<0x2501)
-+	if (FW_VERSION(av7110->arm_app)<0x2501)
- 		printk ("av7110: Warning, firmware version 0x%04x is too old. "
--			"System might be unstable!\n", av7110->arm_app&0xffff);
-+			"System might be unstable!\n", FW_VERSION(av7110->arm_app));
- 
- 	kernel_thread(arm_thread, (void *) av7110, 0);
- 
-@@ -4199,6 +4476,8 @@ static int av7110_attach (struct saa7146
- 	VidMode(av7110, vidmode);
- 
- 	/* remaining inits according to card and frontend type */
-+	av7110->has_analog_tuner = 0;
-+	av7110->current_input = 0;
- 	if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
- 		printk ("av7110(%d): Crystal audio DAC detected\n",
- 			av7110->dvb_adapter->num);
-@@ -4225,6 +4504,31 @@ static int av7110_attach (struct saa7146
- 			msp_writereg(av7110, 0x12, 0x000a, 0x0220); // SCART 1 source
- 			msp_writereg(av7110, 0x12, 0x0007, 0x7f00); // SCART 1 volume
- 			msp_writereg(av7110, 0x12, 0x000d, 0x4800); // prescale SCART
-+		
-+		if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
-+			INFO(("saa7113 not accessible.\n"));
-+		} else {
-+			av7110->has_analog_tuner = 1;
-+			/* init the saa7113 */
-+			i2c_writereg(av7110, 0x48, 0x02, 0xd0); i2c_writereg(av7110, 0x48, 0x03, 0x23); i2c_writereg(av7110, 0x48, 0x04, 0x00);
-+			i2c_writereg(av7110, 0x48, 0x05, 0x00); i2c_writereg(av7110, 0x48, 0x06, 0xe9); i2c_writereg(av7110, 0x48, 0x07, 0x0d);
-+			i2c_writereg(av7110, 0x48, 0x08, 0x98); i2c_writereg(av7110, 0x48, 0x09, 0x02); i2c_writereg(av7110, 0x48, 0x0a, 0x80);
-+			i2c_writereg(av7110, 0x48, 0x0b, 0x40); i2c_writereg(av7110, 0x48, 0x0c, 0x40); i2c_writereg(av7110, 0x48, 0x0d, 0x00);
-+			i2c_writereg(av7110, 0x48, 0x0e, 0x01);	i2c_writereg(av7110, 0x48, 0x0f, 0x7c); i2c_writereg(av7110, 0x48, 0x10, 0x48);
-+			i2c_writereg(av7110, 0x48, 0x11, 0x0c);	i2c_writereg(av7110, 0x48, 0x12, 0x8b);	i2c_writereg(av7110, 0x48, 0x13, 0x10);
-+			i2c_writereg(av7110, 0x48, 0x14, 0x00);	i2c_writereg(av7110, 0x48, 0x15, 0x00);	i2c_writereg(av7110, 0x48, 0x16, 0x00);
-+			i2c_writereg(av7110, 0x48, 0x17, 0x00);	i2c_writereg(av7110, 0x48, 0x18, 0x00);	i2c_writereg(av7110, 0x48, 0x19, 0x00);
-+			i2c_writereg(av7110, 0x48, 0x1a, 0x00);	i2c_writereg(av7110, 0x48, 0x1b, 0x00);	i2c_writereg(av7110, 0x48, 0x1c, 0x00);
-+			i2c_writereg(av7110, 0x48, 0x1d, 0x00);	i2c_writereg(av7110, 0x48, 0x1e, 0x00);
-+		}	
-+
-+		memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
-+		/* set dd1 stream a & b */
-+      		saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-+		saa7146_write(dev, DD1_INIT, 0x0200700);
-+		saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-+
-+
- 	} else if (dev->pci->subsystem_vendor == 0x110a) {
- 		printk("av7110(%d): DVB-C w/o analog module detected\n",
- 			av7110->dvb_adapter->num);
-@@ -4330,6 +4634,16 @@ static struct saa7146_standard standard[
- 	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
- };
- 
-+static struct saa7146_standard analog_standard[] = {
-+	{ "PAL", V4L2_STD_PAL, 0x18, 288, 576, 0x08, 708, 709, 576, 768 },
-+	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
-+};
-+
-+static struct saa7146_standard dvb_standard[] = {
-+	{ "PAL", V4L2_STD_PAL, 0x14, 288, 576, 0x4a, 708, 709, 576, 768 },
-+	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
-+};
-+
- static struct saa7146_extension av7110_extension;
- 
- #define MAKE_AV7110_INFO(x_var,x_name) \
-@@ -4387,7 +4701,7 @@ static int std_callback(struct saa7146_d
- }
- 
- 
--static struct saa7146_ext_vv av7110_vv_data = {
-+static struct saa7146_ext_vv av7110_vv_data_st = {
- 	.inputs		= 1,
- 	.audios 	= 1,
- 	.capabilities	= 0,
-@@ -4401,9 +4715,23 @@ static struct saa7146_ext_vv av7110_vv_d
- 	.ioctl		= av7110_ioctl,
- };
- 
-+static struct saa7146_ext_vv av7110_vv_data_c = {
-+	.inputs		= 1,
-+	.audios 	= 1,
-+	.capabilities	= V4L2_CAP_TUNER,
-+	.flags		= 0,
-+
-+	.stds		= &standard[0],
-+	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
-+	.std_callback	= &std_callback, 
-+
-+	.ioctls		= &ioctls[0],
-+	.ioctl		= av7110_ioctl,
-+};
-+
-+
- static struct saa7146_extension av7110_extension = {
- 	.name		= "dvb\0",
--	.ext_vv_data	= &av7110_vv_data,
- 
- 	.module		= THIS_MODULE,
- 	.pci_tbl	= &pci_tbl[0],
-@@ -4442,7 +4770,11 @@ MODULE_LICENSE("GPL");
- 
- MODULE_PARM(av7110_debug,"i");
- MODULE_PARM(vidmode,"i");
-+MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
- MODULE_PARM(pids_off,"i");
-+MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
- MODULE_PARM(adac,"i");
-+MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
- MODULE_PARM(hw_sections, "i");
-+MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
- 
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/av7110.h	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/av7110.h	2003-07-19 17:03:49.000000000 -0700
-@@ -153,7 +153,8 @@ enum av7110_osd_command {	
- 	BlitBmp,
- 	ReleaseBmp,
- 	SetWTrans,
--	SetWNoTrans
-+        SetWNoTrans,
-+        Set_Palette
- };
- 
- enum av7110_pid_command { 
-@@ -405,6 +406,11 @@ struct av7110 {
- 	struct dvb_i2c_bus	*i2c_bus;	
- 	char			*card_name;
- 
-+	/* support for analog module of dvb-c */
-+	int			has_analog_tuner;
-+	int			current_input;
-+	u32			current_freq;
-+				
- 	struct tasklet_struct   debi_tasklet;
- 	struct tasklet_struct   gpio_tasklet;
- 
-@@ -572,6 +578,9 @@ struct av7110 {
- #define DATA_BUFF2_BASE	(DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
- #define DATA_BUFF2_SIZE	0x0800
- 
-+#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
-+#define DATA_BUFF3_SIZE 0x0400
-+
- #define Reserved	(DPRAM_BASE + 0x1E00)
- #define Reserved_SIZE	0x1C0
- 
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/budget-av.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/budget-av.c	2003-07-19 17:03:49.000000000 -0700
-@@ -170,6 +170,7 @@ static int budget_av_detach (struct saa7
- 	return err;
- }
- 
-+static struct saa7146_ext_vv vv_data;
- 
- static int budget_av_attach (struct saa7146_dev* dev,
- 		      struct saa7146_pci_extension_data *info)
-@@ -207,16 +208,22 @@ static int budget_av_attach (struct saa7
- 	dvb_delay(500);
- 
- 	if ((err = saa7113_init (budget_av))) {
--		budget_av_detach(dev);
-+		/* fixme: proper cleanup here */
-+		ERR(("cannot init saa7113.\n"));
-+		return err;
-+	}
-+
-+	if ( 0 != saa7146_vv_init(dev,&vv_data)) {
-+		/* fixme: proper cleanup here */
-+		ERR(("cannot init vv subsystem.\n"));
- 		return err;
- 	}
- 
--	saa7146_vv_init(dev);
- 	if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1",
- 					   VFL_TYPE_GRABBER)))
- 	{
-+		/* fixme: proper cleanup here */
- 		ERR(("cannot register capture v4l2 device.\n"));
--		budget_av_detach(dev);
- 		return err;
- 	}
- 
-@@ -256,8 +263,9 @@ static struct saa7146_extension_ioctls i
- };
- 
- 
--static int av_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
-+static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
- {
-+	struct saa7146_dev *dev = fh->dev;
- 	struct budget_av *budget_av = (struct budget_av*) dev->ext_priv;
- /*
- 	struct saa7146_vv *vv = dev->vv_data; 
-@@ -299,11 +307,19 @@ static int av_ioctl(struct saa7146_dev *
- }
- 
- static struct saa7146_standard standard[] = {
--	{ "PAL",	V4L2_STD_PAL,	SAA7146_PAL_VALUES },
--	{ "NTSC",	V4L2_STD_NTSC,	SAA7146_NTSC_VALUES },
-+	{
-+		.name	= "PAL", 	.id	= V4L2_STD_PAL,
-+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}, {
-+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-+		.v_offset	= 0x16,	.v_field 	= 240,	.v_calc		= 480,
-+		.h_offset	= 0x06,	.h_pixels 	= 708,	.h_calc		= 708+1,
-+		.v_max_out	= 480,	.h_max_out	= 640,
-+	}
- };
- 
--
- static struct saa7146_ext_vv vv_data = {
- 	.inputs		= 2,
- 	.capabilities	= 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
-@@ -338,8 +354,6 @@ static struct saa7146_extension budget_e
- 	.attach		= budget_av_attach,
- 	.detach		= budget_av_detach,
- 
--	.ext_vv_data	= &vv_data,
--
- 	.irq_mask	= MASK_10,
- 	.irq_func	= ttpci_budget_irq10_handler,
- };	
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/budget.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/budget.c	2003-07-19 17:03:49.000000000 -0700
-@@ -192,6 +192,7 @@ static struct saa7146_extension budget_e
- MAKE_BUDGET_INFO(ttbs,	"TT-Budget/WinTV-NOVA-S  PCI",	BUDGET_TT);
- MAKE_BUDGET_INFO(ttbc,	"TT-Budget/WinTV-NOVA-C  PCI",	BUDGET_TT);
- MAKE_BUDGET_INFO(ttbt,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
-+MAKE_BUDGET_INFO(ttbt2,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
- MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC);
- /* Uncomment for Budget Patch */
- /*MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);*/
-@@ -202,6 +203,7 @@ static struct pci_device_id pci_tbl[] = 
- 	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
- 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
- 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
-+	MAKE_EXTENSION_PCI(ttbt2,  0x13c2, 0x1011),	
- 	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
- 	{
- 		.vendor    = 0,
-@@ -213,7 +215,6 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
- static struct saa7146_extension budget_extension = {
- 	.name		= "budget dvb\0",
- 	.flags	 	= 0,
--	.ext_vv_data	= NULL,
- 	
- 	.module		= THIS_MODULE,
- 	.pci_tbl	= pci_tbl,
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/budget-ci.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/budget-ci.c	2003-07-19 17:03:49.000000000 -0700
-@@ -371,7 +371,6 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
- static struct saa7146_extension budget_extension = {
- 	.name		= "budget_ci dvb\0",
- 	.flags	 	= 0,
--	.ext_vv_data	= NULL,
- 
- 	.module		= THIS_MODULE,
- 	.pci_tbl	= &pci_tbl[0],
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/budget-core.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/budget-core.c	2003-07-19 17:03:49.000000000 -0700
-@@ -1,4 +1,5 @@
- #include "budget.h"
-+#include "ttpci-eeprom.h"
- 
- int budget_debug = 0;
- 
-@@ -165,7 +166,6 @@ static int budget_register(struct budget
-         if (ret < 0)
-                 return ret;
- 
--        budget->dvb_net.card_num = budget->dvb_adapter->num;
-         dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
- 
- 	return 0;
-@@ -222,7 +222,7 @@ int ttpci_budget_init (struct budget *bu
-            get recognized before the main driver is loaded */
-         saa7146_write(dev, GPIO_CTRL, 0x500000);
- 	
--	saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
-+	saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_120);
- 
- 	budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev,
- 						budget->dvb_adapter, 0);
-@@ -232,6 +232,8 @@ int ttpci_budget_init (struct budget *bu
- 		return -ENOMEM;
- 	}
- 
-+	ttpci_eeprom_parse_mac(budget->i2c_bus);
-+
- 	if( NULL == (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci,length,&budget->pt))) {
- 		ret = -ENOMEM;
- 		goto err;
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/budget-patch.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/budget-patch.c	2003-07-19 17:03:49.000000000 -0700
-@@ -165,6 +165,7 @@ static int budget_patch_attach (struct s
- {
-         struct budget_patch *budget;
-         int err;
-+	int count = 0;
- 
-         if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
-                 return -ENOMEM;
-@@ -263,7 +264,6 @@ static void __exit budget_patch_exit(voi
- static struct saa7146_extension budget_extension = {
-         .name           = "budget_patch dvb\0",
-         .flags          = 0,
--        .ext_vv_data    = NULL,
-         
-         .module         = THIS_MODULE,
-         .pci_tbl        = pci_tbl,
---- linux-2.6.0-test1/drivers/media/dvb/ttpci/Makefile	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/Makefile	2003-07-19 17:03:49.000000000 -0700
-@@ -3,16 +3,12 @@
- # and the AV7110 DVB device driver
- #
- 
--dvb-ttpci-budget-objs := budget.o
--dvb-ttpci-budget-av-objs := budget-av.o
--dvb-ttpci-budget-ci-objs := budget-ci.o
--dvb-ttpci-budget-patch-objs := budget-patch.o
- dvb-ttpci-objs := av7110.o av7110_ipack.o av7110_ir.o
- 
--obj-$(CONFIG_DVB_BUDGET) += budget-core.o dvb-ttpci-budget.o
--obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o dvb-ttpci-budget-ci.o
--obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o dvb-ttpci-budget-av.o
--obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o dvb-ttpci-budget-patch.o
--obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
-+obj-$(CONFIG_DVB_BUDGET) += budget-core.o budget.o ttpci-eeprom.o
-+obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o budget-av.o ttpci-eeprom.o
-+obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o
-+obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o
-+obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
- 
- EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/ttpci-eeprom.c	2003-07-19 17:03:49.000000000 -0700
-@@ -0,0 +1,120 @@
-+/*
-+    Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,
-+    decode it and store it in the associated adapter struct for
-+    use by dvb_net.c
-+
-+    This code was tested on TT-Budget/WinTV-NOVA-CI PCI boards with
-+    Atmel and ST Microelectronics EEPROMs.
-+
-+    This card appear to have the 24C16 write protect held to ground,
-+    thus permitting normal read/write operation. Theoretically it
-+    would be possible to write routines to burn a different (encoded)
-+    MAC address into the EEPROM.
-+
-+    Robert Schlabbach	GMX
-+    Michael Glaum	KVH Industries
-+    Holger Waechtler	Convergence
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+*/
-+
-+#include <asm/errno.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+
-+#include "dvb_i2c.h"
-+#include "dvb_functions.h"
-+
-+#if 1
-+#define dprintk(x...) printk(x)
-+#else
-+#define dprintk(x...)
-+#endif
-+
-+
-+static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC)
-+{
-+	int ret;
-+	u8 b0[] = { 0xd4 };
-+
-+	struct i2c_msg msg[] = {
-+		{.addr = 0x50,.flags = 0,.buf = b0,.len = 1},
-+		{.addr = 0x50,.flags = I2C_M_RD,.buf = encodedMAC,.len = 6}
-+	};
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	ret = i2c->xfer(i2c, msg, 2);
-+
-+	if (ret != 2)		/* Assume EEPROM isn't there */
-+		return (-ENODEV);
-+
-+	return 0;
-+}
-+
-+static void decodeMAC(u8 * decodedMAC, const u8 * encodedMAC)
-+{
-+	u8 ormask0[3] = { 0x54, 0x7B, 0x9E };
-+	u8 ormask1[3] = { 0xD3, 0xF1, 0x23 };
-+	u8 low;
-+	u8 high;
-+	u8 shift;
-+	int i;
-+
-+	decodedMAC[0] = 0x00;
-+	decodedMAC[1] = 0xD0;
-+	decodedMAC[2] = 0x5C;
-+
-+	for (i = 0; i < 3; i++) {
-+		low = encodedMAC[2 * i] ^ ormask0[i];
-+		high = encodedMAC[2 * i + 1] ^ ormask1[i];
-+		shift = (high >> 6) & 0x3;
-+
-+		decodedMAC[5 - i] = ((high << 8) | low) >> shift;
-+	}
-+
-+}
-+
-+
-+int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c)
-+{
-+	int ret;
-+	u8 encodedMAC[6];
-+	u8 decodedMAC[6];
-+
-+	ret = ttpci_eeprom_read_encodedMAC(i2c, encodedMAC);
-+
-+	if (ret != 0) {		/* Will only be -ENODEV */
-+		dprintk("Couldn't read from EEPROM: not there?\n");
-+		memset(i2c->adapter->proposed_mac, 0, 6);
-+		return ret;
-+	}
-+
-+	decodeMAC(decodedMAC, encodedMAC);
-+	memcpy(i2c->adapter->proposed_mac, decodedMAC, 6);
-+
-+	dprintk("%s adapter %i has MAC addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-+		i2c->adapter->name, i2c->adapter->num,
-+		decodedMAC[0], decodedMAC[1], decodedMAC[2],
-+		decodedMAC[3], decodedMAC[4], decodedMAC[5]);
-+	dprintk("encoded MAC was %02x:%02x:%02x:%02x:%02x:%02x\n",
-+		encodedMAC[0], encodedMAC[1], encodedMAC[2],
-+		encodedMAC[3], encodedMAC[4], encodedMAC[5]);
-+	return 0;
-+}
-+
-+EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttpci/ttpci-eeprom.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,32 @@
-+/*
-+    Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
-+    decode it and store it in associated adapter net device
-+
-+    Robert Schlabbach	GMX
-+    Michael Glaum	KVH Industries
-+    Holger Waechtler	Convergence
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+*/
-+
-+#ifndef __TTPCI_EEPROM_H__
-+#define __TTPCI_EEPROM_H__
-+
-+#include "dvb_i2c.h"
-+
-+extern int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c);
-+
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,1271 @@
-+/*
-+ * TTUSB DVB driver
-+ *
-+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
-+ * Copyright (c) 2003 Felix Domke <tmbinc@gmx.net>
-+ *
-+ *	This program 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.
-+ */
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+#include <linux/module.h>
-+#include <linux/usb.h>
-+#include <linux/delay.h>
-+#include <linux/time.h>
-+#include <linux/errno.h>
-+#include <asm/semaphore.h>
-+
-+#include "dvb_frontend.h"
-+#include "dmxdev.h"
-+#include "dvb_demux.h"
-+#include "dvb_net.h"
-+
-+#include <linux/dvb/frontend.h>
-+#include <linux/dvb/dmx.h>
-+#include <linux/pci.h>
-+#include <linux/usb.h>
-+
-+#include "dvb_functions.h"
-+
-+/*
-+  TTUSB_HWSECTIONS:
-+    the DSP supports filtering in hardware, however, since the "muxstream"
-+    is a bit braindead (no matching channel masks or no matching filter mask),
-+    we won't support this - yet. it doesn't event support negative filters,
-+    so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
-+    parse TS data. USB bandwith will be a problem when having large
-+    datastreams, especially for dvb-net, but hey, that's not my problem.
-+	
-+  TTUSB_DISEQC, TTUSB_TONE:
-+    let the STC do the diseqc/tone stuff. this isn't supported at least with
-+    my TTUSB, so let it undef'd unless you want to implement another
-+    frontend. never tested.
-+		
-+  DEBUG:
-+    define it to > 3 for really hardcore debugging. you probably don't want
-+    this unless the device doesn't load at all. > 2 for bandwidth statistics.
-+*/
-+
-+static int debug = 0;
-+
-+#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
-+
-+#define ISO_BUF_COUNT      4
-+#define FRAMES_PER_ISO_BUF 4
-+#define ISO_FRAME_SIZE     912
-+#define TTUSB_MAXCHANNEL   32
-+#ifdef TTUSB_HWSECTIONS
-+#define TTUSB_MAXFILTER    16	/* ??? */
-+#endif
-+
-+#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
-+
-+/**
-+ *  since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
-+ *  the dvb_demux field must be the first in struct!!
-+ */
-+struct ttusb {
-+	struct dvb_demux dvb_demux;
-+	struct dmxdev dmxdev;
-+	struct dvb_net dvbnet;
-+
-+	/* our semaphore, for channel allocation/deallocation */
-+	struct semaphore sem;
-+	/* and one for USB access. */
-+	struct semaphore semusb;
-+
-+	struct dvb_adapter *adapter;
-+	struct usb_device *dev;
-+
-+	int disconnecting;
-+	int iso_streaming;
-+
-+	unsigned int bulk_out_pipe;
-+	unsigned int bulk_in_pipe;
-+	unsigned int isoc_in_pipe;
-+
-+	void *iso_buffer;
-+	dma_addr_t iso_dma_handle;
-+
-+	struct urb *iso_urb[ISO_BUF_COUNT];
-+
-+	int running_feed_count;
-+	int last_channel;
-+	int last_filter;
-+
-+	u8 c;			/* transaction counter, wraps around...  */
-+	fe_sec_tone_mode_t tone;
-+	fe_sec_voltage_t voltage;
-+
-+	int mux_state;		// 0..2 - MuxSyncWord, 3 - nMuxPacks,    4 - muxpack
-+	u8 mux_npacks;
-+	u8 muxpack[256 + 8];
-+	int muxpack_ptr, muxpack_len;
-+
-+	int insync;
-+
-+	u16 cc;			/* MuxCounter - will increment on EVERY MUX PACKET */
-+	/* (including stuffing. yes. really.) */
-+
-+	u8 last_result[32];
-+
-+	struct ttusb_channel {
-+		struct ttusb *ttusb;
-+		struct dvb_demux_feed *dvbdmxfeed;
-+
-+		int active;
-+		int id;
-+		int pid;
-+		int type;	/* 1 - TS, 2 - Filter */
-+#ifdef TTUSB_HWSECTIONS
-+		int filterstate[TTUSB_MAXFILTER];	/* 0: not busy, 1: busy */
-+#endif
-+	} channel[TTUSB_MAXCHANNEL];
-+#if 0
-+	devfs_handle_t stc_devfs_handle;
-+#endif
-+};
-+
-+/* ugly workaround ... don't know why it's neccessary to read */
-+/* all result codes. */
-+
-+#define DEBUG 0
-+static int ttusb_cmd(struct ttusb *ttusb,
-+	      const u8 * data, int len, int needresult)
-+{
-+	int actual_len;
-+	int err;
-+#if DEBUG >= 3
-+	int i;
-+
-+	printk(">");
-+	for (i = 0; i < len; ++i)
-+		printk(" %02x", data[i]);
-+	printk("\n");
-+#endif
-+
-+	if (down_interruptible(&ttusb->semusb) < 0)
-+		return -EAGAIN;
-+
-+	err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
-+			   (u8 *) data, len, &actual_len, HZ);
-+	if (err != 0) {
-+		dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
-+			__FUNCTION__, err);
-+		up(&ttusb->semusb);
-+		return err;
-+	}
-+	if (actual_len != len) {
-+		dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
-+			actual_len, len);
-+		up(&ttusb->semusb);
-+		return -1;
-+	}
-+
-+	err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
-+			   ttusb->last_result, 32, &actual_len, HZ);
-+
-+	if (err != 0) {
-+		printk("%s: failed, receive error %d\n", __FUNCTION__,
-+		       err);
-+		up(&ttusb->semusb);
-+		return err;
-+	}
-+#if DEBUG >= 3
-+	actual_len = ttusb->last_result[3] + 4;
-+	printk("<");
-+	for (i = 0; i < actual_len; ++i)
-+		printk(" %02x", ttusb->last_result[i]);
-+	printk("\n");
-+#endif
-+	if (!needresult)
-+		up(&ttusb->semusb);
-+	return 0;
-+}
-+
-+static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
-+{
-+	memcpy(data, ttusb->last_result, len);
-+	up(&ttusb->semusb);
-+	return 0;
-+}
-+
-+static int ttusb_i2c_msg(struct ttusb *ttusb,
-+		  u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
-+		  u8 rcv_len)
-+{
-+	u8 b[0x28];
-+	u8 id = ++ttusb->c;
-+	int i, err;
-+
-+	if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
-+		return -EINVAL;
-+
-+	b[0] = 0xaa;
-+	b[1] = id;
-+	b[2] = 0x31;
-+	b[3] = snd_len + 3;
-+	b[4] = addr << 1;
-+	b[5] = snd_len;
-+	b[6] = rcv_len;
-+
-+	for (i = 0; i < snd_len; i++)
-+		b[7 + i] = snd_buf[i];
-+
-+	err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
-+
-+	if (err)
-+		return -EREMOTEIO;
-+
-+	err = ttusb_result(ttusb, b, 0x20);
-+
-+	if (rcv_len > 0) {
-+
-+		if (err || b[0] != 0x55 || b[1] != id) {
-+			dprintk
-+			    ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
-+			     __FUNCTION__, err, id);
-+			return -EREMOTEIO;
-+		}
-+
-+		for (i = 0; i < rcv_len; i++)
-+			rcv_buf[i] = b[7 + i];
-+	}
-+
-+	return rcv_len;
-+}
-+
-+static int ttusb_i2c_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg msg[],
-+		   int num)
-+{
-+	struct ttusb *ttusb = i2c->data;
-+	int i = 0;
-+	int inc;
-+
-+	if (down_interruptible(&ttusb->sem) < 0)
-+		return -EAGAIN;
-+
-+	while (i < num) {
-+		u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
-+		int err;
-+
-+		if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
-+			addr = msg[i].addr;
-+			snd_buf = msg[i].buf;
-+			snd_len = msg[i].len;
-+			rcv_buf = msg[i + 1].buf;
-+			rcv_len = msg[i + 1].len;
-+			inc = 2;
-+		} else {
-+			addr = msg[i].addr;
-+			snd_buf = msg[i].buf;
-+			snd_len = msg[i].len;
-+			rcv_buf = NULL;
-+			rcv_len = 0;
-+			inc = 1;
-+		}
-+
-+		err = ttusb_i2c_msg(ttusb, addr,
-+				    snd_buf, snd_len, rcv_buf, rcv_len);
-+
-+		if (err < rcv_len) {
-+			printk("%s: i == %i\n", __FUNCTION__, i);
-+			break;
-+		}
-+
-+		i += inc;
-+	}
-+
-+	up(&ttusb->sem);
-+	return i;
-+}
-+
-+#include "dvb-ttusb-dspbootcode.h"
-+
-+static int ttusb_boot_dsp(struct ttusb *ttusb)
-+{
-+	int i, err;
-+	u8 b[40];
-+
-+	/* BootBlock */
-+	b[0] = 0xaa;
-+	b[2] = 0x13;
-+	b[3] = 28;
-+
-+	/* upload dsp code in 32 byte steps (36 didn't work for me ...) */
-+	/* 32 is max packet size, no messages should be splitted. */
-+	for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
-+		memcpy(&b[4], &dsp_bootcode[i], 28);
-+
-+		b[1] = ++ttusb->c;
-+
-+		err = ttusb_cmd(ttusb, b, 32, 0);
-+		if (err)
-+			goto done;
-+	}
-+
-+	/* last block ... */
-+	b[1] = ++ttusb->c;
-+	b[2] = 0x13;
-+	b[3] = 0;
-+
-+	err = ttusb_cmd(ttusb, b, 4, 0);
-+	if (err)
-+		goto done;
-+
-+	/* BootEnd */
-+	b[1] = ++ttusb->c;
-+	b[2] = 0x14;
-+	b[3] = 0;
-+
-+	err = ttusb_cmd(ttusb, b, 4, 0);
-+
-+      done:
-+	if (err) {
-+		dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-+			__FUNCTION__, err);
-+	}
-+
-+	return err;
-+}
-+
-+static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
-+		      int pid)
-+{
-+	int err;
-+	/* SetChannel */
-+	u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
-+		(pid >> 8) & 0xff, pid & 0xff
-+	};
-+
-+	err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-+	return err;
-+}
-+
-+static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
-+{
-+	int err;
-+	/* DelChannel */
-+	u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
-+
-+	err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-+	return err;
-+}
-+
-+#ifdef TTUSB_HWSECTIONS
-+static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
-+		     int associated_chan, u8 filter[8], u8 mask[8])
-+{
-+	int err;
-+	/* SetFilter */
-+	u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
-+		filter[0], filter[1], filter[2], filter[3],
-+		filter[4], filter[5], filter[6], filter[7],
-+		filter[8], filter[9], filter[10], filter[11],
-+		mask[0], mask[1], mask[2], mask[3],
-+		mask[4], mask[5], mask[6], mask[7],
-+		mask[8], mask[9], mask[10], mask[11]
-+	};
-+
-+	err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-+	return err;
-+}
-+
-+static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
-+{
-+	int err;
-+	/* DelFilter */
-+	u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
-+
-+	err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-+	return err;
-+}
-+#endif
-+
-+static int ttusb_init_controller(struct ttusb *ttusb)
-+{
-+	u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
-+	u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
-+	u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
-+	/* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
-+	u8 b3[] =
-+	    { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
-+	u8 b4[] =
-+	    { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
-+
-+	u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
-+	u8 get_dsp_version[0x20] =
-+	    { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
-+	int err;
-+
-+	/* reset board */
-+	if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
-+		return err;
-+
-+	/* reset board (again?) */
-+	if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
-+		return err;
-+
-+	ttusb_boot_dsp(ttusb);
-+
-+	/* set i2c bit rate */
-+	if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
-+		return err;
-+
-+	if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
-+		return err;
-+
-+	err = ttusb_result(ttusb, b4, sizeof(b4));
-+
-+	if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
-+		return err;
-+
-+	if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
-+		return err;
-+
-+	dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__,
-+		get_version[4], get_version[5], get_version[6],
-+		get_version[7], get_version[8]);
-+
-+	if (memcmp(get_version + 4, "V 0.0", 5) &&
-+	    memcmp(get_version + 4, "V 1.1", 5)) {
-+		printk
-+		    ("%s: unknown STC version %c%c%c%c%c, please report!\n",
-+		     __FUNCTION__, get_version[4], get_version[5],
-+		     get_version[6], get_version[7], get_version[8]);
-+	}
-+
-+	err =
-+	    ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
-+	if (err)
-+		return err;
-+
-+	err =
-+	    ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
-+	if (err)
-+		return err;
-+	printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
-+	       get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
-+	return 0;
-+}
-+
-+#ifdef TTUSB_DISEQC
-+static int ttusb_send_diseqc(struct ttusb *ttusb,
-+		      const struct dvb_diseqc_master_cmd *cmd)
-+{
-+	u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
-+
-+	int err;
-+
-+	b[3] = 4 + 2 + cmd->msg_len;
-+	b[4] = 0xFF;		/* send diseqc master, not burst */
-+	b[5] = cmd->msg_len;
-+
-+	memcpy(b + 5, cmd->msg, cmd->msg_len);
-+
-+	/* Diseqc */
-+	if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
-+		dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-+			__FUNCTION__, err);
-+	}
-+
-+	return err;
-+}
-+#endif
-+
-+static int ttusb_update_lnb(struct ttusb *ttusb)
-+{
-+	u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
-+		ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
-+		ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
-+	};
-+	int err;
-+
-+	/* SetLNB */
-+	if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
-+		dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-+			__FUNCTION__, err);
-+	}
-+
-+	return err;
-+}
-+
-+static int ttusb_set_voltage(struct ttusb *ttusb, fe_sec_voltage_t voltage)
-+{
-+	ttusb->voltage = voltage;
-+	return ttusb_update_lnb(ttusb);
-+}
-+
-+#ifdef TTUSB_TONE
-+static int ttusb_set_tone(struct ttusb *ttusb, fe_sec_tone_mode_t tone)
-+{
-+	ttusb->tone = tone;
-+	return ttusb_update_lnb(ttusb);
-+}
-+#endif
-+
-+static int ttusb_lnb_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
-+{
-+	struct ttusb *ttusb = fe->i2c->data;
-+
-+	switch (cmd) {
-+	case FE_SET_VOLTAGE:
-+		return ttusb_set_voltage(ttusb, (fe_sec_voltage_t) arg);
-+#ifdef TTUSB_TONE
-+	case FE_SET_TONE:
-+		return ttusb_set_tone(ttusb, (fe_sec_tone_mode_t) arg);
-+#endif
-+#ifdef TTUSB_DISEQC
-+	case FE_DISEQC_SEND_MASTER_CMD:
-+		return ttusb_send_diseqc(ttusb,
-+					 (struct dvb_diseqc_master_cmd *)
-+					 arg);
-+#endif
-+	default:
-+		return -EOPNOTSUPP;
-+	};
-+}
-+
-+#if 0
-+static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
-+{
-+	u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
-+	int err, actual_len;
-+
-+	err = ttusb_cmd(ttusb, b, sizeof(b), 0);
-+	if (err) {
-+		dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
-+			__FUNCTION__, err);
-+	}
-+}
-+#endif
-+
-+/*****************************************************************************/
-+
-+#ifdef TTUSB_HWSECTIONS
-+static void ttusb_handle_ts_data(struct ttusb_channel *channel,
-+				 const u8 * data, int len);
-+static void ttusb_handle_sec_data(struct ttusb_channel *channel,
-+				  const u8 * data, int len);
-+#endif
-+
-+int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid;
-+
-+static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
-+			   int len)
-+{
-+	u16 csum = 0, cc;
-+	int i;
-+	for (i = 0; i < len; i += 2)
-+		csum ^= le16_to_cpup((u16 *) (muxpack + i));
-+	if (csum) {
-+		printk("%s: muxpack with incorrect checksum, ignoring\n",
-+		       __FUNCTION__);
-+		numinvalid++;
-+		return;
-+	}
-+
-+	cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
-+	cc &= 0x7FFF;
-+	if (cc != ttusb->cc)
-+		printk("%s: cc discontinuity (%d frames missing)\n",
-+		       __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
-+	ttusb->cc = (cc + 1) & 0x7FFF;
-+	if (muxpack[0] & 0x80) {
-+#ifdef TTUSB_HWSECTIONS
-+		/* section data */
-+		int pusi = muxpack[0] & 0x40;
-+		int channel = muxpack[0] & 0x1F;
-+		int payload = muxpack[1];
-+		const u8 *data = muxpack + 2;
-+		/* check offset flag */
-+		if (muxpack[0] & 0x20)
-+			data++;
-+
-+		ttusb_handle_sec_data(ttusb->channel + channel, data,
-+				      payload);
-+		data += payload;
-+
-+		if ((!!(ttusb->muxpack[0] & 0x20)) ^
-+		    !!(ttusb->muxpack[1] & 1))
-+			data++;
-+#warning TODO: pusi
-+		printk("cc: %04x\n", (data[0] << 8) | data[1]);
-+#endif
-+		numsec++;
-+	} else if (muxpack[0] == 0x47) {
-+#ifdef TTUSB_HWSECTIONS
-+		/* we have TS data here! */
-+		int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
-+		int channel;
-+		for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
-+			if (ttusb->channel[channel].active
-+			    && (pid == ttusb->channel[channel].pid))
-+				ttusb_handle_ts_data(ttusb->channel +
-+						     channel, muxpack,
-+						     188);
-+#endif
-+		numts++;
-+		dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
-+	} else if (muxpack[0] != 0) {
-+		numinvalid++;
-+		printk("illegal muxpack type %02x\n", muxpack[0]);
-+	} else
-+		numstuff++;
-+}
-+
-+static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
-+{
-+	int maxwork = 1024;
-+	while (len) {
-+		if (!(maxwork--)) {
-+			printk("%s: too much work\n", __FUNCTION__);
-+			break;
-+		}
-+
-+		switch (ttusb->mux_state) {
-+		case 0:
-+		case 1:
-+		case 2:
-+			len--;
-+			if (*data++ == 0xAA)
-+				++ttusb->mux_state;
-+			else {
-+				ttusb->mux_state = 0;
-+#if DEBUG > 3
-+				if (ttusb->insync)
-+					printk("%02x ", data[-1]);
-+#else
-+				if (ttusb->insync) {
-+					printk("%s: lost sync.\n",
-+					       __FUNCTION__);
-+					ttusb->insync = 0;
-+				}
-+#endif
-+			}
-+			break;
-+		case 3:
-+			ttusb->insync = 1;
-+			len--;
-+			ttusb->mux_npacks = *data++;
-+			++ttusb->mux_state;
-+			ttusb->muxpack_ptr = 0;
-+			/* maximum bytes, until we know the length */
-+			ttusb->muxpack_len = 2;
-+			break;
-+		case 4:
-+			{
-+				int avail;
-+				avail = len;
-+				if (avail >
-+				    (ttusb->muxpack_len -
-+				     ttusb->muxpack_ptr))
-+					avail =
-+					    ttusb->muxpack_len -
-+					    ttusb->muxpack_ptr;
-+				memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
-+				       data, avail);
-+				ttusb->muxpack_ptr += avail;
-+				if (ttusb->muxpack_ptr > 264)
-+					BUG();
-+				data += avail;
-+				len -= avail;
-+				/* determine length */
-+				if (ttusb->muxpack_ptr == 2) {
-+					if (ttusb->muxpack[0] & 0x80) {
-+						ttusb->muxpack_len =
-+						    ttusb->muxpack[1] + 2;
-+						if (ttusb->
-+						    muxpack[0] & 0x20)
-+							ttusb->
-+							    muxpack_len++;
-+						if ((!!
-+						     (ttusb->
-+						      muxpack[0] & 0x20)) ^
-+						    !!(ttusb->
-+						       muxpack[1] & 1))
-+							ttusb->
-+							    muxpack_len++;
-+						ttusb->muxpack_len += 4;
-+					} else if (ttusb->muxpack[0] ==
-+						   0x47)
-+						ttusb->muxpack_len =
-+						    188 + 4;
-+					else if (ttusb->muxpack[0] == 0x00)
-+						ttusb->muxpack_len =
-+						    ttusb->muxpack[1] + 2 +
-+						    4;
-+					else {
-+						dprintk
-+						    ("%s: invalid state: first byte is %x\n",
-+						     __FUNCTION__,
-+						     ttusb->muxpack[0]);
-+						ttusb->mux_state = 0;
-+					}
-+				}
-+
-+			/**
-+			 * if length is valid and we reached the end:
-+			 * goto next muxpack
-+			 */
-+				if ((ttusb->muxpack_ptr >= 2) &&
-+				    (ttusb->muxpack_ptr ==
-+				     ttusb->muxpack_len)) {
-+					ttusb_process_muxpack(ttusb,
-+							      ttusb->
-+							      muxpack,
-+							      ttusb->
-+							      muxpack_ptr);
-+					ttusb->muxpack_ptr = 0;
-+					/* maximum bytes, until we know the length */
-+					ttusb->muxpack_len = 2;
-+
-+				/**
-+				 * no muxpacks left?
-+				 * return to search-sync state
-+				 */
-+					if (!ttusb->mux_npacks--) {
-+						ttusb->mux_state = 0;
-+						break;
-+					}
-+				}
-+				break;
-+			}
-+		default:
-+			BUG();
-+			break;
-+		}
-+	}
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void ttusb_iso_irq(struct urb *urb)
-+#else
-+static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
-+#endif
-+{
-+	struct ttusb *ttusb = urb->context;
-+
-+	if (!ttusb->iso_streaming)
-+		return;
-+
-+#if 0
-+	printk("%s: status %d, errcount == %d, length == %i\n",
-+	       __FUNCTION__,
-+	       urb->status, urb->error_count, urb->actual_length);
-+#endif
-+
-+	if (!urb->status) {
-+		int i;
-+		for (i = 0; i < urb->number_of_packets; ++i) {
-+			struct usb_iso_packet_descriptor *d;
-+			u8 *data;
-+			int len;
-+			numpkt++;
-+			if ((jiffies - lastj) >= HZ) {
-+#if DEBUG > 2
-+				printk
-+				    ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
-+				     numpkt * HZ / (jiffies - lastj),
-+				     numts, numstuff, numsec, numinvalid,
-+				     numts + numstuff + numsec +
-+				     numinvalid);
-+#endif
-+				numts = numstuff = numsec = numinvalid = 0;
-+				lastj = jiffies;
-+				numpkt = 0;
-+			}
-+			d = &urb->iso_frame_desc[i];
-+			data = urb->transfer_buffer + d->offset;
-+			len = d->actual_length;
-+			d->actual_length = 0;
-+			d->status = 0;
-+			ttusb_process_frame(ttusb, data, len);
-+		}
-+	}
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+	usb_submit_urb(urb, GFP_KERNEL);
-+#endif
-+}
-+
-+static void ttusb_free_iso_urbs(struct ttusb *ttusb)
-+{
-+	int i;
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++)
-+		if (ttusb->iso_urb[i])
-+			usb_free_urb(ttusb->iso_urb[i]);
-+
-+	pci_free_consistent(NULL,
-+			    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
-+			    ISO_BUF_COUNT, ttusb->iso_buffer,
-+			    ttusb->iso_dma_handle);
-+}
-+
-+static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
-+{
-+	int i;
-+
-+	ttusb->iso_buffer = pci_alloc_consistent(NULL,
-+						 ISO_FRAME_SIZE *
-+						 FRAMES_PER_ISO_BUF *
-+						 ISO_BUF_COUNT,
-+						 &ttusb->iso_dma_handle);
-+
-+	memset(ttusb->iso_buffer, 0,
-+	       ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		struct urb *urb;
-+
-+		if (!
-+		    (urb =
-+		     usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_KERNEL))) {
-+			ttusb_free_iso_urbs(ttusb);
-+			return -ENOMEM;
-+		}
-+
-+		ttusb->iso_urb[i] = urb;
-+	}
-+
-+	return 0;
-+}
-+
-+static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
-+{
-+	int i;
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++)
-+		usb_unlink_urb(ttusb->iso_urb[i]);
-+
-+	ttusb->iso_streaming = 0;
-+}
-+
-+static int ttusb_start_iso_xfer(struct ttusb *ttusb)
-+{
-+	int i, j, err, buffer_offset = 0;
-+
-+	if (ttusb->iso_streaming) {
-+		printk("%s: iso xfer already running!\n", __FUNCTION__);
-+		return 0;
-+	}
-+
-+	ttusb->insync = 0;
-+	ttusb->mux_state = 0;
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		int frame_offset = 0;
-+		struct urb *urb = ttusb->iso_urb[i];
-+
-+		urb->dev = ttusb->dev;
-+		urb->context = ttusb;
-+		urb->complete = ttusb_iso_irq;
-+		urb->pipe = ttusb->isoc_in_pipe;
-+		urb->transfer_flags = URB_ISO_ASAP;
-+		urb->number_of_packets = FRAMES_PER_ISO_BUF;
-+		urb->transfer_buffer_length =
-+		    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-+		urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
-+		buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-+
-+		for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
-+			urb->iso_frame_desc[j].offset = frame_offset;
-+			urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
-+			frame_offset += ISO_FRAME_SIZE;
-+		}
-+	}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		int next = (i + 1) % ISO_BUF_COUNT;
-+		ttusb->iso_urb[i]->next = ttusb->iso_urb[next];
-+	}
-+#endif
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_KERNEL))) {
-+			ttusb_stop_iso_xfer(ttusb);
-+			printk
-+			    ("%s: failed urb submission (%i: err = %i)!\n",
-+			     __FUNCTION__, i, err);
-+			return err;
-+		}
-+	}
-+
-+	ttusb->iso_streaming = 1;
-+
-+	return 0;
-+}
-+
-+#ifdef TTUSB_HWSECTIONS
-+static void ttusb_handle_ts_data(struct ttusb_channel *channel, const u8 * data,
-+			  int len)
-+{
-+	struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
-+
-+	dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
-+}
-+
-+static void ttusb_handle_sec_data(struct ttusb_channel *channel, const u8 * data,
-+			   int len)
-+{
-+//      struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
-+#error TODO: handle ugly stuff
-+//      dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
-+}
-+#endif
-+
-+static struct ttusb_channel *ttusb_channel_allocate(struct ttusb *ttusb)
-+{
-+	int i;
-+
-+	if (down_interruptible(&ttusb->sem))
-+		return NULL;
-+
-+	/* lock! */
-+	for (i = 0; i < TTUSB_MAXCHANNEL; ++i) {
-+		if (!ttusb->channel[i].active) {
-+			ttusb->channel[i].active = 1;
-+			up(&ttusb->sem);
-+			return ttusb->channel + i;
-+		}
-+	}
-+
-+	up(&ttusb->sem);
-+
-+	return NULL;
-+}
-+
-+static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
-+	struct ttusb_channel *channel;
-+
-+	printk("ttusb_start_feed\n");
-+
-+	switch (dvbdmxfeed->type) {
-+	case DMX_TYPE_TS:
-+		break;
-+	case DMX_TYPE_SEC:
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	if (dvbdmxfeed->type == DMX_TYPE_TS) {
-+		switch (dvbdmxfeed->pes_type) {
-+		case DMX_TS_PES_VIDEO:
-+		case DMX_TS_PES_AUDIO:
-+		case DMX_TS_PES_TELETEXT:
-+		case DMX_TS_PES_PCR:
-+		case DMX_TS_PES_OTHER:
-+			channel = ttusb_channel_allocate(ttusb);
-+			break;
-+		default:
-+			return -EINVAL;
-+		}
-+	} else {
-+		channel = ttusb_channel_allocate(ttusb);
-+	}
-+
-+	if (!channel)
-+		return -EBUSY;
-+
-+	dvbdmxfeed->priv = channel;
-+	channel->dvbdmxfeed = dvbdmxfeed;
-+
-+	channel->pid = dvbdmxfeed->pid;
-+
-+#ifdef TTUSB_HWSECTIONS
-+	if (dvbdmxfeed->type == DMX_TYPE_TS) {
-+		channel->type = 1;
-+	} else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
-+		channel->type = 2;
-+#error TODO: allocate filters
-+	}
-+#else
-+	channel->type = 1;
-+#endif
-+
-+	ttusb_set_channel(ttusb, channel->id, channel->type, channel->pid);
-+
-+	if (0 == ttusb->running_feed_count++)
-+		ttusb_start_iso_xfer(ttusb);
-+
-+	return 0;
-+}
-+
-+static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct ttusb_channel *channel =
-+	    (struct ttusb_channel *) dvbdmxfeed->priv;
-+	struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
-+
-+	ttusb_del_channel(channel->ttusb, channel->id);
-+
-+	if (--ttusb->running_feed_count == 0)
-+		ttusb_stop_iso_xfer(ttusb);
-+
-+	channel->active = 0;
-+
-+	return 0;
-+}
-+
-+static int ttusb_setup_interfaces(struct ttusb *ttusb)
-+{
-+	usb_set_configuration(ttusb->dev, 1);
-+	usb_set_interface(ttusb->dev, 1, 1);
-+
-+	ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
-+	ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
-+	ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
-+
-+	return 0;
-+}
-+
-+#if 0
-+static u8 stc_firmware[8192];
-+
-+static int stc_open(struct inode *inode, struct file *file)
-+{
-+	struct ttusb *ttusb = file->private_data;
-+	int addr;
-+
-+	for (addr = 0; addr < 8192; addr += 16) {
-+		u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
-+		ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
-+			      16);
-+	}
-+
-+	return 0;
-+}
-+
-+static ssize_t stc_read(struct file *file, char *buf, size_t count,
-+		 loff_t * offset)
-+{
-+	int tc = count;
-+
-+	if ((tc + *offset) > 8192)
-+		tc = 8192 - *offset;
-+
-+	if (tc < 0)
-+		return 0;
-+
-+	copy_to_user(buf, stc_firmware + *offset, tc);
-+
-+	*offset += tc;
-+
-+	return tc;
-+}
-+
-+static int stc_release(struct inode *inode, struct file *file)
-+{
-+	return 0;
-+}
-+
-+static struct file_operations stc_fops = {
-+	.owner = THIS_MODULE,
-+	.read = stc_read,
-+	.open = stc_open,
-+	.release = stc_release,
-+};
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void *ttusb_probe(struct usb_device *udev, unsigned int ifnum,
-+		  const struct usb_device_id *id)
-+{
-+	struct ttusb *ttusb;
-+	int result, channel;
-+
-+	if (ifnum != 0)
-+		return NULL;
-+
-+	dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
-+
-+	if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
-+		return NULL;
-+
-+#else
-+static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-+{
-+	struct usb_device *udev;
-+	struct ttusb *ttusb;
-+	int result, channel;
-+
-+	dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
-+
-+	udev = interface_to_usbdev(intf);
-+
-+	if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
-+		return -ENOMEM;
-+
-+#endif
-+
-+	memset(ttusb, 0, sizeof(struct ttusb));
-+
-+	for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel) {
-+		ttusb->channel[channel].id = channel;
-+		ttusb->channel[channel].ttusb = ttusb;
-+	}
-+
-+	ttusb->dev = udev;
-+	ttusb->c = 0;
-+	ttusb->mux_state = 0;
-+	sema_init(&ttusb->sem, 0);
-+	sema_init(&ttusb->semusb, 1);
-+
-+	ttusb_setup_interfaces(ttusb);
-+
-+	ttusb_alloc_iso_urbs(ttusb);
-+	if (ttusb_init_controller(ttusb))
-+		printk("ttusb_init_controller: error\n");
-+
-+	up(&ttusb->sem);
-+
-+	dvb_register_adapter(&ttusb->adapter,
-+			     "Technotrend/Hauppauge Nova-USB");
-+
-+	dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0);
-+	dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL,
-+				ttusb);
-+
-+	memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
-+
-+	ttusb->dvb_demux.dmx.capabilities =
-+	    DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-+	ttusb->dvb_demux.priv = 0;
-+#ifdef TTUSB_HWSECTIONS
-+	ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
-+#else
-+	ttusb->dvb_demux.filternum = 32;
-+#endif
-+	ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
-+	ttusb->dvb_demux.start_feed = ttusb_start_feed;
-+	ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
-+	ttusb->dvb_demux.write_to_decoder = 0;
-+
-+	if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
-+		printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n",
-+		       result);
-+		goto err;
-+	}
-+//FIXME dmxdev (nur WAS?)
-+	ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
-+	ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
-+	ttusb->dmxdev.capabilities = 0;
-+
-+	if ((result = dvb_dmxdev_init(&ttusb->dmxdev, ttusb->adapter)) < 0) {
-+		printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
-+		       result);
-+		dvb_dmx_release(&ttusb->dvb_demux);
-+		goto err;
-+	}
-+
-+	if (dvb_net_init
-+	    (ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
-+		printk("ttusb_dvb: dvb_net_init failed!\n");
-+	}
-+
-+      err:
-+#if 0
-+	ttusb->stc_devfs_handle =
-+	    devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
-+			   DEVFS_FL_DEFAULT, 0, 192,
-+			   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
-+			   | S_IROTH | S_IWOTH, &stc_fops, ttusb);
-+#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	return (void *) ttusb;
-+#else
-+	usb_set_intfdata(intf, (void *) ttusb);
-+
-+	return 0;
-+#endif
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void ttusb_disconnect(struct usb_device *udev, void *data)
-+{
-+	struct ttusb *ttusb = data;
-+#else
-+static void ttusb_disconnect(struct usb_interface *intf)
-+{
-+	struct ttusb *ttusb = usb_get_intfdata(intf);
-+
-+	usb_set_intfdata(intf, NULL);
-+#endif
-+
-+	ttusb->disconnecting = 1;
-+
-+	ttusb_stop_iso_xfer(ttusb);
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))
-+#undef devfs_remove
-+#define devfs_remove(x)	devfs_unregister(ttusb->stc_devfs_handle);
-+#endif
-+#if 0
-+	devfs_remove(TTUSB_BUDGET_NAME);
-+#endif
-+	ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
-+	dvb_net_release(&ttusb->dvbnet);
-+	dvb_dmxdev_release(&ttusb->dmxdev);
-+	dvb_dmx_release(&ttusb->dvb_demux);
-+
-+	dvb_unregister_i2c_bus(ttusb_i2c_xfer, ttusb->adapter, 0);
-+	dvb_unregister_adapter(ttusb->adapter);
-+
-+	ttusb_free_iso_urbs(ttusb);
-+
-+	kfree(ttusb);
-+
-+	dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__);
-+}
-+
-+static struct usb_device_id ttusb_table[] = {
-+	{USB_DEVICE(0xb48, 0x1003)},
-+	{USB_DEVICE(0xb48, 0x1004)},	/* to be confirmed ????  */
-+	{USB_DEVICE(0xb48, 0x1005)},	/* to be confirmed ????  */
-+	{}
-+};
-+
-+MODULE_DEVICE_TABLE(usb, ttusb_table);
-+
-+static struct usb_driver ttusb_driver = {
-+      .name 		= "Technotrend/Hauppauge USB-Nova",
-+      .probe 		= ttusb_probe,
-+      .disconnect 	= ttusb_disconnect,
-+      .id_table 	= ttusb_table,
-+};
-+
-+static int __init ttusb_init(void)
-+{
-+	int err;
-+
-+	if ((err = usb_register(&ttusb_driver)) < 0) {
-+		printk("%s: usb_register failed! Error number %d",
-+		       __FILE__, err);
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+static void __exit ttusb_exit(void)
-+{
-+	usb_deregister(&ttusb_driver);
-+}
-+
-+module_init(ttusb_init);
-+module_exit(ttusb_exit);
-+
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "Debug or not");
-+
-+MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
-+MODULE_DESCRIPTION("TTUSB DVB Driver");
-+MODULE_LICENSE("GPL");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,1644 @@
-+
-+#include <asm/types.h>
-+
-+u8 dsp_bootcode [] __initdata = {
-+	0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00, 
-+	0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f, 
-+	0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb, 
-+	0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8, 
-+	0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe, 
-+	0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5, 
-+	0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00, 
-+	0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8, 
-+	0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5, 
-+	0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01, 
-+	0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8, 
-+	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8, 
-+	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89, 
-+	0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20, 
-+	0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d, 
-+	0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02, 
-+	0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00, 
-+	0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03, 
-+	0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74, 
-+	0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11, 
-+	0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8, 
-+	0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95, 
-+	0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6, 
-+	0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee, 
-+	0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff, 
-+	0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45, 
-+	0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3, 
-+	0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16, 
-+	0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20, 
-+	0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e, 
-+	0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95, 
-+	0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11, 
-+	0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01, 
-+	0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11, 
-+	0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00, 
-+	0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11, 
-+	0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10, 
-+	0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15, 
-+	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21, 
-+	0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8, 
-+	0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16, 
-+	0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 
-+	0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 
-+	0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 
-+	0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01, 
-+	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb, 
-+	0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00, 
-+	0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c, 
-+	0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11, 
-+	0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e, 
-+	0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12, 
-+	0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3, 
-+	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66, 
-+	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87, 
-+	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8, 
-+	0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8, 
-+	0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8, 
-+	0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12, 
-+	0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f, 
-+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, 
-+	0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93, 
-+	0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05, 
-+	0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0, 
-+	0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f, 
-+	0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8, 
-+	0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f, 
-+	0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93, 
-+	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8, 
-+	0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0, 
-+	0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-+	0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2, 
-+	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74, 
-+	0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2, 
-+	0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00, 
-+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6, 
-+	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, 
-+	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, 
-+	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, 
-+	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, 
-+	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, 
-+	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, 
-+	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, 
-+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-+	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd, 
-+	0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 
-+	0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 
-+	0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 
-+	0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95, 
-+	0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a, 
-+	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19, 
-+	0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15, 
-+	0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11, 
-+	0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 
-+	0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb, 
-+	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 
-+	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 
-+	0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 
-+	0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 
-+	0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 
-+	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e, 
-+	0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01, 
-+	0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff, 
-+	0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 
-+	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2, 
-+	0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2, 
-+	0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1, 
-+	0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1, 
-+	0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff, 
-+	0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06, 
-+	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 
-+	0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 
-+	0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 
-+	0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 
-+	0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11, 
-+	0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95, 
-+	0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98, 
-+	0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b, 
-+	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71, 
-+	0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, 
-+	0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15, 
-+	0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11, 
-+	0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83, 
-+	0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05, 
-+	0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8, 
-+	0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01, 
-+	0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c, 
-+	0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1, 
-+	0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9, 
-+	0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00, 
-+	0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00, 
-+	0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74, 
-+	0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74, 
-+	0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12, 
-+	0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11, 
-+	0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2, 
-+	0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2, 
-+	0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c, 
-+	0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0, 
-+	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8, 
-+	0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, 
-+	0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16, 
-+	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 
-+	0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff, 
-+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8, 
-+	0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2, 
-+	0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0, 
-+	0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a, 
-+	0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff, 
-+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff, 
-+	0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2, 
-+	0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0, 
-+	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8, 
-+	0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, 
-+	0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a, 
-+	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 
-+	0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff, 
-+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2, 
-+	0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12, 
-+	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58, 
-+	0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8, 
-+	0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2, 
-+	0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16, 
-+	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58, 
-+	0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8, 
-+	0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2, 
-+	0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a, 
-+	0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00, 
-+	0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2, 
-+	0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e, 
-+	0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00, 
-+	0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2, 
-+	0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-+	0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed, 
-+	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02, 
-+	0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08, 
-+	0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20, 
-+	0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10, 
-+	0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08, 
-+	0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74, 
-+	0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12, 
-+	0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04, 
-+	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 
-+	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 
-+	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, 
-+	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69, 
-+	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, 
-+	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 
-+	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, 
-+	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41, 
-+	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, 
-+	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57, 
-+	0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c, 
-+	0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36, 
-+	0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 
-+	0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00, 
-+	0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 
-+	0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 
-+	0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74, 
-+	0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 
-+	0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff, 
-+	0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1, 
-+	0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01, 
-+	0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a, 
-+	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 
-+	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc, 
-+	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 
-+	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 
-+	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 
-+	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 
-+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09, 
-+	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 
-+	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00, 
-+	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 
-+	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 
-+	0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 
-+	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 
-+	0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01, 
-+	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02, 
-+	0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03, 
-+	0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11, 
-+	0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00, 
-+	0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00, 
-+	0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 
-+	0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11, 
-+	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a, 
-+	0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00, 
-+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1, 
-+	0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 
-+	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 
-+	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 
-+	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 
-+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c, 
-+	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 
-+	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00, 
-+	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 
-+	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 
-+	0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 
-+	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 
-+	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 
-+	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 
-+	0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 
-+	0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 
-+	0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d, 
-+	0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 
-+	0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 
-+	0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa, 
-+	0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38, 
-+	0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1, 
-+	0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56, 
-+	0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 
-+	0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8, 
-+	0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3, 
-+	0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2, 
-+	0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1, 
-+	0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1, 
-+	0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00, 
-+	0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8, 
-+	0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44, 
-+	0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd, 
-+	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8, 
-+	0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2, 
-+	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, 
-+	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, 
-+	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, 
-+	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, 
-+	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, 
-+	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, 
-+	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, 
-+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-+	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff, 
-+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04, 
-+	0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18, 
-+	0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 
-+	0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 
-+	0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 
-+	0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 
-+	0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 
-+	0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 
-+	0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38, 
-+	0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 
-+	0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6, 
-+	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b, 
-+	0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa, 
-+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c, 
-+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f, 
-+	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a, 
-+	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a, 
-+	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b, 
-+	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b, 
-+	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 
-+	0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, 
-+	0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 
-+	0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 
-+	0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79, 
-+	0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95, 
-+	0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 
-+	0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11, 
-+	0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8, 
-+	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, 
-+	0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0, 
-+	0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8, 
-+	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, 
-+	0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00, 
-+	0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02, 
-+	0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 
-+	0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73, 
-+	0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b, 
-+	0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-+	0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12, 
-+	0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, 
-+	0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 
-+	0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92, 
-+	0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13, 
-+	0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01, 
-+	0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda, 
-+	0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-+	0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 
-+	0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01, 
-+	0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01, 
-+	0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8, 
-+	0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00, 
-+	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba, 
-+	0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12, 
-+	0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13, 
-+	0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20, 
-+	0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, 
-+	0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8, 
-+	0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11, 
-+	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce, 
-+	0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30, 
-+	0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc, 
-+	0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16, 
-+	0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03, 
-+	0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45, 
-+	0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03, 
-+	0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00, 
-+	0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b, 
-+	0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff, 
-+	0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-+	0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9, 
-+	0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01, 
-+	0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74, 
-+	0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11, 
-+	0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9, 
-+	0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9, 
-+	0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8, 
-+	0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8, 
-+	0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8, 
-+	0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8, 
-+	0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9, 
-+	0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8, 
-+	0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76, 
-+	0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8, 
-+	0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8, 
-+	0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80, 
-+	0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80, 
-+	0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8, 
-+	0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8, 
-+	0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 
-+	0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 
-+	0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-+	0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1, 
-+	0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01, 
-+	0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8, 
-+	0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6, 
-+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 
-+	0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 
-+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 
-+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d, 
-+	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09, 
-+	0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74, 
-+	0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01, 
-+	0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-+	0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11, 
-+	0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00, 
-+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-+	0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00, 
-+	0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f, 
-+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80, 
-+	0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00, 
-+	0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33, 
-+	0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25, 
-+	0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82, 
-+	0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2, 
-+	0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3, 
-+	0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8, 
-+	0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39, 
-+	0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8, 
-+	0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2, 
-+	0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79, 
-+	0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30, 
-+	0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8, 
-+	0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 
-+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-+	0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79, 
-+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 
-+	0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20, 
-+	0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74, 
-+	0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72, 
-+	0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 
-+	0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f, 
-+	0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00, 
-+	0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83, 
-+	0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff, 
-+	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 
-+	0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91, 
-+	0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11, 
-+	0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30, 
-+	0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30, 
-+	0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08, 
-+	0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9, 
-+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 
-+	0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b, 
-+	0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08, 
-+	0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b, 
-+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff, 
-+	0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00, 
-+	0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75, 
-+	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8, 
-+	0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00, 
-+	0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74, 
-+	0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a, 
-+	0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62, 
-+	0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80, 
-+	0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb, 
-+	0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73, 
-+	0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 
-+	0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73, 
-+	0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20, 
-+	0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee, 
-+	0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96, 
-+	0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a, 
-+	0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 
-+	0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03, 
-+	0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 
-+	0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb, 
-+	0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41, 
-+	0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13, 
-+	0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8, 
-+	0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00, 
-+	0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0, 
-+	0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8, 
-+	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8, 
-+	0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38, 
-+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-+	0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81, 
-+	0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86, 
-+	0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, 
-+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-+	0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67, 
-+	0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a, 
-+	0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, 
-+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-+	0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67, 
-+	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b, 
-+	0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30, 
-+	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a, 
-+	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02, 
-+	0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30, 
-+	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a, 
-+	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01, 
-+	0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 
-+	0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8, 
-+	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, 
-+	0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8, 
-+	0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 
-+	0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00, 
-+	0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 
-+	0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-+	0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20, 
-+	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-+	0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73, 
-+	0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20, 
-+	0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73, 
-+	0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8, 
-+	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, 
-+	0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00, 
-+	0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30, 
-+	0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20, 
-+	0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8, 
-+	0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b, 
-+	0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00, 
-+	0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08, 
-+	0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30, 
-+	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, 
-+	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a, 
-+	0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16, 
-+	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, 
-+	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 
-+	0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00, 
-+	0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 
-+	0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17, 
-+	0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d, 
-+	0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18, 
-+	0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f, 
-+	0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01, 
-+	0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74, 
-+	0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04, 
-+	0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 
-+	0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8, 
-+	0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72, 
-+	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 
-+	0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79, 
-+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00, 
-+	0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8, 
-+	0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8, 
-+	0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 
-+	0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc, 
-+	0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00, 
-+	0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00, 
-+	0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12, 
-+	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12, 
-+	0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01, 
-+	0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02, 
-+	0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11, 
-+	0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80, 
-+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 
-+	0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-+	0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20, 
-+	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-+	0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00, 
-+	0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11, 
-+	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11, 
-+	0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 
-+	0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20, 
-+	0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b, 
-+	0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73, 
-+	0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-+	0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02, 
-+	0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb, 
-+	0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95, 
-+	0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8, 
-+	0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e, 
-+	0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e, 
-+	0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11, 
-+	0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff, 
-+	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00, 
-+	0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70, 
-+	0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8, 
-+	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12, 
-+	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4, 
-+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-+	0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01, 
-+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8, 
-+	0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71, 
-+	0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04, 
-+	0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a, 
-+	0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00, 
-+	0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff, 
-+	0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00, 
-+	0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 
-+	0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00, 
-+	0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11, 
-+	0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95, 
-+	0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17, 
-+	0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15, 
-+	0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05, 
-+	0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06, 
-+	0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11, 
-+	0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06, 
-+	0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20, 
-+	0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01, 
-+	0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa, 
-+	0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00, 
-+	0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11, 
-+	0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a, 
-+	0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09, 
-+	0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 
-+	0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73, 
-+	0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8, 
-+	0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c, 
-+	0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11, 
-+	0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01, 
-+	0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1, 
-+	0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02, 
-+	0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87, 
-+	0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20, 
-+	0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 
-+	0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 
-+	0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17, 
-+	0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09, 
-+	0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 
-+	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 
-+	0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 
-+	0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, 
-+	0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc, 
-+	0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11, 
-+	0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, 
-+	0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16, 
-+	0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 
-+	0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00, 
-+	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 
-+	0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45, 
-+	0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae, 
-+	0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1, 
-+	0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb, 
-+	0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9, 
-+	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, 
-+	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, 
-+	0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11, 
-+	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, 
-+	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, 
-+	0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06, 
-+	0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00, 
-+	0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f, 
-+	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 
-+	0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11, 
-+	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, 
-+	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, 
-+	0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11, 
-+	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, 
-+	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, 
-+	0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45, 
-+	0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06, 
-+	0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04, 
-+	0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30, 
-+	0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 
-+	0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 
-+	0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 
-+	0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 
-+	0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86, 
-+	0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e, 
-+	0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74, 
-+	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e, 
-+	0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8, 
-+	0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30, 
-+	0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09, 
-+	0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10, 
-+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71, 
-+	0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00, 
-+	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95, 
-+	0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01, 
-+	0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee, 
-+	0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99, 
-+	0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a, 
-+	0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00, 
-+	0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 
-+	0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01, 
-+	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9, 
-+	0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82, 
-+	0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01, 
-+	0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82, 
-+	0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01, 
-+	0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8, 
-+	0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8, 
-+	0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00, 
-+	0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11, 
-+	0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1, 
-+	0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14, 
-+	0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12, 
-+	0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff, 
-+	0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13, 
-+	0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c, 
-+	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, 
-+	0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01, 
-+	0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9, 
-+	0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02, 
-+	0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11, 
-+	0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00, 
-+	0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00, 
-+	0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa, 
-+	0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8, 
-+	0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00, 
-+	0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48, 
-+	0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8, 
-+	0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01, 
-+	0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a, 
-+	0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01, 
-+	0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a, 
-+	0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12, 
-+	0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73, 
-+	0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c, 
-+	0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81, 
-+	0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10, 
-+	0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1, 
-+	0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01, 
-+	0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13, 
-+	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11, 
-+	0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73, 
-+	0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01, 
-+	0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13, 
-+	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00, 
-+	0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a, 
-+	0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84, 
-+	0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88, 
-+	0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 
-+	0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 
-+	0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03, 
-+	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 
-+	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 
-+	0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 
-+	0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01, 
-+	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 
-+	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 
-+	0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff, 
-+	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1, 
-+	0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5, 
-+	0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06, 
-+	0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30, 
-+	0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 
-+	0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07, 
-+	0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b, 
-+	0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73, 
-+	0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, 
-+	0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11, 
-+	0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd, 
-+	0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4, 
-+	0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60, 
-+	0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8, 
-+	0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8, 
-+	0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00, 
-+	0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20, 
-+	0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, 
-+	0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73, 
-+	0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74, 
-+	0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8, 
-+	0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7, 
-+	0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 
-+	0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1, 
-+	0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11, 
-+	0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01, 
-+	0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95, 
-+	0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01, 
-+	0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c, 
-+	0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3, 
-+	0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, 
-+	0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e, 
-+	0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5, 
-+	0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87, 
-+	0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62, 
-+	0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5, 
-+	0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66, 
-+	0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87, 
-+	0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00, 
-+	0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00, 
-+	0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7, 
-+	0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6, 
-+	0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6, 
-+	0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11, 
-+	0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 
-+	0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-+	0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b, 
-+	0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73, 
-+	0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01, 
-+	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09, 
-+	0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08, 
-+	0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07, 
-+	0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0, 
-+	0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00, 
-+	0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01, 
-+	0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16, 
-+	0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 
-+	0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02, 
-+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-+	0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12, 
-+	0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 
-+	0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81, 
-+	0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d, 
-+	0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1, 
-+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 
-+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c, 
-+	0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e, 
-+	0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00, 
-+	0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-+	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 
-+	0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00, 
-+	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00, 
-+	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e, 
-+	0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00, 
-+	0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00, 
-+	0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14, 
-+	0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c, 
-+	0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11, 
-+	0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13, 
-+	0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13, 
-+	0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d, 
-+	0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e, 
-+	0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66, 
-+	0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 
-+	0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32, 
-+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-+	0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d, 
-+	0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20, 
-+	0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04, 
-+	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, 
-+	0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04, 
-+	0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1, 
-+	0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30, 
-+	0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa, 
-+	0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b, 
-+	0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8, 
-+	0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa, 
-+	0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96, 
-+	0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20, 
-+	0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16, 
-+	0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1, 
-+	0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12, 
-+	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c, 
-+	0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03, 
-+	0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01, 
-+	0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10, 
-+	0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8, 
-+	0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04, 
-+	0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10, 
-+	0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc, 
-+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-+	0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c, 
-+	0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95, 
-+	0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30, 
-+	0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 
-+	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae, 
-+	0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06, 
-+	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03, 
-+	0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8, 
-+	0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45, 
-+	0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, 
-+	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, 
-+	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, 
-+	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, 
-+	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, 
-+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-+	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, 
-+	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 
-+	0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10, 
-+	0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5, 
-+	0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10, 
-+	0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 
-+	0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8, 
-+	0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd, 
-+	0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05, 
-+	0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18, 
-+	0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03, 
-+	0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33, 
-+	0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1, 
-+	0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13, 
-+	0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27, 
-+	0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30, 
-+	0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45, 
-+	0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, 
-+	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, 
-+	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, 
-+	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, 
-+	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, 
-+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-+	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, 
-+	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 
-+	0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c, 
-+	0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab, 
-+	0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f, 
-+	0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa, 
-+	0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f, 
-+	0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c, 
-+	0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa, 
-+	0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c, 
-+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab, 
-+	0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa, 
-+	0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1, 
-+	0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1, 
-+	0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1, 
-+	0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c, 
-+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa, 
-+	0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c, 
-+	0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00, 
-+	0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17, 
-+	0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74, 
-+	0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1, 
-+	0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c, 
-+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa, 
-+	0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45, 
-+	0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05, 
-+	0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b, 
-+	0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04, 
-+	0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f, 
-+	0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 
-+	0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16, 
-+	0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16, 
-+	0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1, 
-+	0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04, 
-+	0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73, 
-+	0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1, 
-+	0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16, 
-+	0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3, 
-+	0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45, 
-+	0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17, 
-+	0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06, 
-+	0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9, 
-+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-+	0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00, 
-+	0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16, 
-+	0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b, 
-+	0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31, 
-+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-+	0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04, 
-+	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, 
-+	0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff, 
-+	0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86, 
-+	0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 
-+	0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11, 
-+	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, 
-+	0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81, 
-+	0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8, 
-+	0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c, 
-+	0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61, 
-+	0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8, 
-+	0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13, 
-+	0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01, 
-+	0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8, 
-+	0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10, 
-+	0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75, 
-+	0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01, 
-+	0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63, 
-+	0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8, 
-+	0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03, 
-+	0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00, 
-+	0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b, 
-+	0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01, 
-+	0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8, 
-+	0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 
-+	0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9, 
-+	0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04, 
-+	0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8, 
-+	0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20, 
-+	0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01, 
-+	0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74, 
-+	0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8, 
-+	0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68, 
-+	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00, 
-+	0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40, 
-+	0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f, 
-+	0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11, 
-+	0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1, 
-+	0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 
-+	0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0, 
-+	0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00, 
-+	0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95, 
-+	0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff, 
-+	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 
-+	0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00, 
-+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, 
-+	0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02, 
-+	0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9, 
-+	0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef, 
-+	0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d, 
-+	0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 
-+	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 
-+	0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11, 
-+	0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45, 
-+	0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78, 
-+	0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2, 
-+	0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08, 
-+	0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1, 
-+	0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0, 
-+	0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95, 
-+	0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00, 
-+	0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17, 
-+	0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42, 
-+	0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb, 
-+	0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90, 
-+	0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01, 
-+	0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01, 
-+	0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16, 
-+	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, 
-+	0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16, 
-+	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, 
-+	0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf, 
-+	0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00, 
-+	0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16, 
-+	0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 
-+	0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90, 
-+	0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90, 
-+	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc, 
-+	0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00, 
-+	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11, 
-+	0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10, 
-+	0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8, 
-+	0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90, 
-+	0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01, 
-+	0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e, 
-+	0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01, 
-+	0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12, 
-+	0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04, 
-+	0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-+	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, 
-+	0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00, 
-+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, 
-+	0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00, 
-+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11, 
-+	0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07, 
-+	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, 
-+	0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 
-+	0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 
-+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 
-+	0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec, 
-+	0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01, 
-+	0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb, 
-+	0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00, 
-+	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, 
-+	0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08, 
-+	0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85, 
-+	0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8, 
-+	0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00, 
-+	0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02, 
-+	0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 
-+	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, 
-+	0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8, 
-+	0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85, 
-+	0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06, 
-+	0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20, 
-+	0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d, 
-+	0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11, 
-+	0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec, 
-+	0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81, 
-+	0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81, 
-+	0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff, 
-+	0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80, 
-+	0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8, 
-+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, 
-+	0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00, 
-+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, 
-+	0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17, 
-+	0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17, 
-+	0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f, 
-+	0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17, 
-+	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3, 
-+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06, 
-+	0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b, 
-+	0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07, 
-+	0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14, 
-+	0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95, 
-+	0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57, 
-+	0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6, 
-+	0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8, 
-+	0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11, 
-+	0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81, 
-+	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07, 
-+	0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2, 
-+	0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08, 
-+	0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11, 
-+	0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81, 
-+	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09, 
-+	0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11, 
-+	0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, 
-+	0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52, 
-+	0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55, 
-+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-+	0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55, 
-+	0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12, 
-+	0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 
-+	0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73, 
-+	0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12, 
-+	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, 
-+	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d, 
-+	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34, 
-+	0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13, 
-+	0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83, 
-+	0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55, 
-+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-+	0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40, 
-+	0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40, 
-+	0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, 
-+	0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52, 
-+	0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55, 
-+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-+	0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73, 
-+	0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12, 
-+	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, 
-+	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f, 
-+	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32, 
-+	0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57, 
-+	0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40, 
-+	0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82, 
-+	0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2, 
-+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-+	0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e, 
-+	0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04, 
-+	0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff, 
-+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20, 
-+	0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12, 
-+	0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1, 
-+	0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54, 
-+	0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54, 
-+	0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 
-+	0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2, 
-+	0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55, 
-+	0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12, 
-+	0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13, 
-+	0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56, 
-+	0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1, 
-+	0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82, 
-+	0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01, 
-+	0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80, 
-+	0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9, 
-+	0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16, 
-+	0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a, 
-+	0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c, 
-+	0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17, 
-+	0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81, 
-+	0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53, 
-+	0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20, 
-+	0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08, 
-+	0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b, 
-+	0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06, 
-+	0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00, 
-+	0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03, 
-+	0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01, 
-+	0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08, 
-+	0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00, 
-+	0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17, 
-+	0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18, 
-+	0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c, 
-+	0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00, 
-+	0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2, 
-+	0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04, 
-+	0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14, 
-+	0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06, 
-+	0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10, 
-+	0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11, 
-+	0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05, 
-+	0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05, 
-+	0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05, 
-+	0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea, 
-+	0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07, 
-+	0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7, 
-+	0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b, 
-+	0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27, 
-+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11, 
-+	0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 
-+	0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10, 
-+	0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16, 
-+	0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11, 
-+	0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-+	0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71, 
-+	0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 
-+	0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11, 
-+	0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81, 
-+	0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff, 
-+	0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86, 
-+	0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 
-+	0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e, 
-+	0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16, 
-+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16, 
-+	0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 
-+	0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-+	0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 
-+	0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03, 
-+	0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12, 
-+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-+	0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8, 
-+	0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01, 
-+	0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12, 
-+	0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82, 
-+	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76, 
-+	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66, 
-+	0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b, 
-+	0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-+	0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11, 
-+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-+	0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, 
-+	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, 
-+	0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11, 
-+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-+	0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, 
-+	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, 
-+	0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11, 
-+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-+	0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-+	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 
-+	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 
-+	0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81, 
-+	0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73, 
-+	0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11, 
-+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 
-+	0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 
-+	0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08, 
-+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 
-+	0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 
-+	0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81, 
-+	0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, 
-+	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, 
-+	0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01, 
-+	0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81, 
-+	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, 
-+	0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11, 
-+	0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93, 
-+	0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10, 
-+	0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08, 
-+	0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01, 
-+	0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0, 
-+	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95, 
-+	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04, 
-+	0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-+	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 
-+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-+	0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c, 
-+	0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6, 
-+	0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82, 
-+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1, 
-+	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 
-+	0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6, 
-+	0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82, 
-+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-+	0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 
-+	0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1, 
-+	0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03, 
-+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 
-+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1, 
-+	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62, 
-+	0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 
-+	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 
-+	0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00, 
-+	0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 
-+	0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81, 
-+	0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-+	0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 
-+	0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c, 
-+	0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53, 
-+	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 
-+	0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-+	0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1, 
-+	0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-+	0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20, 
-+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1, 
-+	0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06, 
-+	0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39, 
-+	0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1, 
-+	0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a, 
-+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41, 
-+	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1, 
-+	0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e, 
-+	0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48, 
-+	0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1, 
-+	0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12, 
-+	0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06, 
-+	0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12, 
-+	0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82, 
-+	0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-+	0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd, 
-+	0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01, 
-+	0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8, 
-+	0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80, 
-+	0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80, 
-+	0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11, 
-+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 
-+	0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01, 
-+	0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11, 
-+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 
-+	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 
-+	0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d, 
-+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-+	0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, 
-+	0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, 
-+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1, 
-+	0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73, 
-+	0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-+	0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95, 
-+	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80, 
-+	0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80, 
-+	0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, 
-+	0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95, 
-+	0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11, 
-+	0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 
-+	0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 
-+	0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02, 
-+	0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6, 
-+	0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 
-+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, 
-+	0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62, 
-+	0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01, 
-+	0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 
-+	0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11, 
-+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 
-+	0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 
-+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-+	0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff, 
-+	0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b, 
-+	0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01, 
-+	0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00, 
-+	0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1, 
-+	0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04, 
-+	0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24, 
-+	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, 
-+	0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08, 
-+	0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31, 
-+	0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11, 
-+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 
-+	0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06, 
-+	0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 
-+	0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73, 
-+	0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 
-+	0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8, 
-+	0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 
-+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44, 
-+	0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95, 
-+	0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-+	0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95, 
-+	0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45, 
-+	0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c, 
-+	0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17, 
-+	0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86, 
-+	0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95, 
-+	0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-+	0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11, 
-+	0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80, 
-+	0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-+	0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc, 
-+	0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82, 
-+	0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 
-+	0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02, 
-+	0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1, 
-+	0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0, 
-+	0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82, 
-+	0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, 
-+	0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02, 
-+	0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1, 
-+	0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda, 
-+	0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b, 
-+	0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 
-+	0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-+	0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9, 
-+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 
-+	0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf, 
-+	0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01, 
-+	0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12, 
-+	0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01, 
-+	0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d, 
-+	0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 
-+	0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 
-+	0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 
-+	0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f, 
-+	0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 
-+	0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47, 
-+	0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30, 
-+	0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 
-+	0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62, 
-+	0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20, 
-+	0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 
-+	0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31, 
-+	0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35, 
-+	0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00, 
-+	0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00, 
-+	0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01, 
-+	0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1, 
-+	0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00, 
-+	0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02, 
-+	0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
-+	0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7, 
-+	0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41, 
-+	0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00, 
-+	0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40, 
-+	0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80, 
-+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00, 
-+	0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00, 
-+	0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8, 
-+	0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0, 
-+	0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81, 
-+	0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00, 
-+};
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-budget/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,11 @@
-+config DVB_TTUSB_BUDGET
-+	tristate "Technotrend/Hauppauge Nova-USB devices"
-+	depends on DVB_CORE && USB
-+	help
-+	  Support for external USB adapters designed by Technotrend and
-+	  produced by Hauppauge, shipped under the brand name 'Nova-USB'.
-+
-+          These devices don't have a MPEG decoder built in, so you need
-+	  an external software decoder to watch TV.	  
-+
-+	  Say Y if you own such a device and want to use it.
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-budget/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,3 @@
-+obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
-+
-+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/dec2000_frontend.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,180 @@
-+/*
-+ * TTUSB DEC-2000-t Frontend
-+ *
-+ * Copyright (C) 2003 Alex Woods <linux-dvb@giblets.org>
-+ *
-+ * This program 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+
-+#include "dvb_frontend.h"
-+#include "dvb_functions.h"
-+
-+static int debug = 0;
-+
-+#define dprintk	if (debug) printk
-+
-+static struct dvb_frontend_info dec2000_frontend_info = {
-+	name:			"TechnoTrend/Hauppauge DEC-2000-t Frontend",
-+	type:			FE_OFDM,
-+	frequency_min:		51000000,
-+	frequency_max:		858000000,
-+	frequency_stepsize:	62500,
-+	caps:	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-+		FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-+		FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-+		FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-+		FE_CAN_HIERARCHY_AUTO,
-+};
-+
-+static int dec2000_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd,
-+				  void *arg)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	switch (cmd) {
-+
-+	case FE_GET_INFO:
-+		dprintk("%s: FE_GET_INFO\n", __FUNCTION__);
-+		memcpy(arg, &dec2000_frontend_info,
-+		       sizeof (struct dvb_frontend_info));
-+		break;
-+
-+	case FE_READ_STATUS: {
-+			fe_status_t *status = (fe_status_t *)arg;
-+			dprintk("%s: FE_READ_STATUS\n", __FUNCTION__);
-+			*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
-+				  FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
-+			break;
-+		}
-+
-+	case FE_READ_BER: {
-+			u32 *ber = (u32 *)arg;
-+			dprintk("%s: FE_READ_BER\n", __FUNCTION__);
-+			*ber = 0;
-+			return -ENOSYS;
-+			break;
-+		}
-+
-+	case FE_READ_SIGNAL_STRENGTH: {
-+			dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);
-+			*(s32 *)arg = 0xFF;
-+			return -ENOSYS;
-+			break;
-+		}
-+
-+	case FE_READ_SNR:
-+		dprintk("%s: FE_READ_SNR\n", __FUNCTION__);
-+		*(s32 *)arg = 0;
-+		return -ENOSYS;
-+		break;
-+
-+	case FE_READ_UNCORRECTED_BLOCKS:
-+		dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__);
-+		*(u32 *)arg = 0;
-+		return -ENOSYS;
-+		break;
-+
-+	case FE_SET_FRONTEND:{
-+			struct dvb_frontend_parameters *p =
-+				(struct dvb_frontend_parameters *)arg;
-+			u8 b[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-+				   0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-+				   0x00, 0xff, 0x00, 0x00, 0x00, 0xff };
-+			u32 freq;
-+			struct i2c_msg msg = { addr: 0x71, flags: 0, len:20 };
-+
-+			dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);
-+
-+			dprintk("            frequency->%d\n", p->frequency);
-+			dprintk("            symbol_rate->%d\n",
-+				p->u.qam.symbol_rate);
-+			dprintk("            inversion->%d\n", p->inversion);
-+
-+			freq = htonl(p->frequency / 1000);
-+			memcpy(&b[4], &freq, sizeof (int));
-+			msg.buf = b;
-+			fe->i2c->xfer(fe->i2c, &msg, 1);
-+
-+			break;
-+		}
-+
-+	case FE_GET_FRONTEND:
-+		dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__);
-+		break;
-+
-+	case FE_SLEEP:
-+		dprintk("%s: FE_SLEEP\n", __FUNCTION__);
-+		return -ENOSYS;
-+		break;
-+
-+	case FE_INIT:
-+		dprintk("%s: FE_INIT\n", __FUNCTION__);
-+		break;
-+
-+	case FE_RESET:
-+		dprintk("%s: FE_RESET\n", __FUNCTION__);
-+		break;
-+
-+	default:
-+		dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);
-+		return -EINVAL;
-+
-+	}
-+
-+	return 0;
-+}
-+
-+static int dec2000_frontend_attach(struct dvb_i2c_bus *i2c)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dvb_register_frontend(dec2000_frontend_ioctl, i2c, NULL,
-+			      &dec2000_frontend_info);
-+
-+	return 0;
-+}
-+
-+static void dec2000_frontend_detach(struct dvb_i2c_bus *i2c)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dvb_unregister_frontend(dec2000_frontend_ioctl, i2c);
-+}
-+
-+static int __init dec2000_frontend_init(void)
-+{
-+	return dvb_register_i2c_device(THIS_MODULE, dec2000_frontend_attach,
-+				       dec2000_frontend_detach);
-+}
-+
-+static void __exit dec2000_frontend_exit(void)
-+{
-+	dvb_unregister_i2c_device(dec2000_frontend_attach);
-+}
-+
-+module_init(dec2000_frontend_init);
-+module_exit(dec2000_frontend_exit);
-+
-+MODULE_DESCRIPTION("TechnoTrend/Hauppauge DEC-2000-t Frontend");
-+MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "Debug level");
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/fdump.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,36 @@
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+
-+
-+int main (int argc, char **argv)
-+{
-+	unsigned char buf[8];
-+	unsigned int i, count, bytes = 0;
-+	int fd;
-+
-+	if (argc != 3) {
-+		fprintf (stderr, "\n\tusage: %s <ucode.bin> <array_name>\n\n",
-+			 argv[0]);
-+		return -1;
-+	}
-+
-+	fd = open (argv[1], O_RDONLY);
-+
-+	printf ("\n#include <asm/types.h>\n\nu8 %s [] __initdata = {",
-+		argv[2]);
-+
-+	while ((count = read (fd, buf, 8)) > 0) {
-+		printf ("\n\t");
-+		for (i=0;i<count;i++, bytes++)
-+			printf ("0x%02x, ", buf[i]);
-+	}
-+
-+	printf ("\n};\n\n");
-+	close (fd);
-+
-+	return 0;
-+}
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,24 @@
-+config DVB_TTUSB_DEC
-+	tristate "Technotrend/Hauppauge USB DEC2000-T devices"
-+	depends on DVB_CORE && USB
-+	help
-+	  Support for external USB adapters designed by Technotrend and
-+	  produced by Hauppauge, shipped under the brand name 'DEC2000-T'.
-+
-+          Even if these devices have a MPEG decoder built in, they transmit
-+	  only compressed MPEG data over the USB bus, so you need
-+	  an external software decoder to watch TV on your computer.	  
-+
-+	  Say Y if you own such a device and want to use it.
-+
-+config DVB_TTUSB_DEC_FIRMWARE_FILE
-+	string "Full pathname of dec2000t.bin firmware file"
-+	depends on DVB_TTUSB_DEC
-+	default "/etc/dvb/dec2000t.bin"
-+	help
-+	  The DEC2000-T requires a firmware in order to boot into a mode in
-+	  which it is a slave to the PC.  The firmware file can obtained as
-+	  follows:
-+	    wget http://hauppauge.lightpath.net/de/dec215a.exe
-+	    unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_T.bin
-+	    mv STB_PC_T.bin /etc/dvb/dec2000t.bin
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,11 @@
-+
-+obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o dec2000_frontend.o
-+
-+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
-+
-+host-progs	:= fdump
-+
-+$(obj)/ttusb_dec.o: $(obj)/dsp_dec2000.h
-+
-+$(obj)/dsp_dec2000.h: $(patsubst "%", %, $(CONFIG_DVB_TTUSB_DEC_FIRMWARE_FILE)) $(obj)/fdump
-+	$(obj)/fdump $< dsp_dec2000 > $@
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,991 @@
-+/*
-+ * TTUSB DEC Driver
-+ *
-+ * Copyright (C) 2003 Alex Woods <linux-dvb@giblets.org>
-+ *
-+ * This program 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+
-+#include "ttusb_dec.h"
-+#include "dvb_frontend.h"
-+
-+static int debug = 0;
-+
-+#define dprintk	if (debug) printk
-+
-+static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
-+				  int param_length, const u8 params[],
-+				  int *result_length, u8 cmd_result[])
-+{
-+	int result, actual_len, i;
-+	u8 b[COMMAND_PACKET_SIZE + 4];
-+	u8 c[COMMAND_PACKET_SIZE + 4];
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if ((result = down_interruptible(&dec->usb_sem))) {
-+		printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
-+		return result;
-+	}
-+
-+	b[0] = 0xaa;
-+	b[1] = ++dec->trans_count;
-+	b[2] = command;
-+	b[3] = param_length;
-+
-+	if (params)
-+		memcpy(&b[4], params, param_length);
-+
-+	if (debug) {
-+		printk("%s: command: ", __FUNCTION__);
-+		for (i = 0; i < param_length + 4; i++)
-+			printk("0x%02X ", b[i]);
-+		printk("\n");
-+	}
-+
-+	result = usb_bulk_msg(dec->udev, dec->command_pipe, b, sizeof(b),
-+			      &actual_len, HZ);
-+
-+	if (result) {
-+		printk("%s: command bulk message failed: error %d\n",
-+		       __FUNCTION__, result);
-+		up(&dec->usb_sem);
-+		return result;
-+	}
-+
-+	result = usb_bulk_msg(dec->udev, dec->result_pipe, c, sizeof(c),
-+			      &actual_len, HZ);
-+
-+	if (result) {
-+		printk("%s: result bulk message failed: error %d\n",
-+		       __FUNCTION__, result);
-+		up(&dec->usb_sem);
-+		return result;
-+	} else {
-+		if (debug) {
-+			printk("%s: result: ", __FUNCTION__);
-+			for (i = 0; i < actual_len; i++)
-+				printk("0x%02X ", c[i]);
-+			printk("\n");
-+		}
-+
-+		if (result_length)
-+			*result_length = c[3];
-+		if (cmd_result && c[3] > 0)
-+			memcpy(cmd_result, &c[4], c[3]);
-+
-+		up(&dec->usb_sem);
-+
-+		return 0;
-+	}
-+}
-+
-+static int ttusb_dec_av_pes2ts_cb(void *priv, unsigned char *data)
-+{
-+	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)priv;
-+
-+	dvbdmxfeed->cb.ts(data, 188, 0, 0, &dvbdmxfeed->feed.ts, DMX_OK);
-+
-+	return 0;
-+}
-+
-+static void ttusb_dec_set_pids(struct ttusb_dec *dec)
-+{
-+	u8 b[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-+		   0xff, 0xff };
-+
-+	u16 pcr = htons(dec->pid[DMX_PES_PCR]);
-+	u16 audio = htons(dec->pid[DMX_PES_AUDIO]);
-+	u16 video = htons(dec->pid[DMX_PES_VIDEO]);
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	memcpy(&b[0], &pcr, 2);
-+	memcpy(&b[2], &audio, 2);
-+	memcpy(&b[4], &video, 2);
-+
-+	ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
-+
-+	if (!down_interruptible(&dec->pes2ts_sem)) {
-+		dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
-+				       ttusb_dec_av_pes2ts_cb, dec->demux.feed);
-+		dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
-+				       ttusb_dec_av_pes2ts_cb, dec->demux.feed);
-+
-+		up(&dec->pes2ts_sem);
-+	}
-+}
-+
-+static int ttusb_dec_i2c_master_xfer(struct dvb_i2c_bus *i2c,
-+				     const struct i2c_msg msgs[], int num)
-+{
-+	int result, i;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	for (i = 0; i < num; i++)
-+		if ((result = ttusb_dec_send_command(i2c->data, msgs[i].addr,
-+						     msgs[i].len, msgs[i].buf,
-+						     NULL, NULL)))
-+			return result;
-+
-+	return 0;
-+}
-+
-+static void ttusb_dec_process_av_pes(struct ttusb_dec * dec, u8 * av_pes,
-+				     int length)
-+{
-+	int i;
-+	u16 csum = 0;
-+	u8 c;
-+
-+	if (length < 16) {
-+		printk("%s: packet too short.\n", __FUNCTION__);
-+		return;
-+	}
-+
-+	for (i = 0; i < length; i += 2) {
-+		csum ^= le16_to_cpup((u16 *)(av_pes + i));
-+		c = av_pes[i];
-+		av_pes[i] = av_pes[i + 1];
-+		av_pes[i + 1] = c;
-+	}
-+
-+	if (csum) {
-+		printk("%s: checksum failed.\n", __FUNCTION__);
-+		return;
-+	}
-+
-+	if (length > 8 + MAX_AV_PES_LENGTH + 4) {
-+		printk("%s: packet too long.\n", __FUNCTION__);
-+		return;
-+	}
-+
-+	if (!(av_pes[0] == 'A' && av_pes[1] == 'V')) {
-+		printk("%s: invalid AV_PES packet.\n", __FUNCTION__);
-+		return;
-+	}
-+
-+	switch (av_pes[2]) {
-+
-+	case 0x01: {		/* VideoStream */
-+			int prebytes = av_pes[5] & 0x03;
-+			int postbytes = (av_pes[5] & 0x0c) >> 2;
-+			u16 v_pes_payload_length;
-+
-+			if (dec->v_pes_postbytes > 0 &&
-+			    dec->v_pes_postbytes == prebytes) {
-+				memcpy(&dec->v_pes[dec->v_pes_length],
-+				       &av_pes[12], prebytes);
-+
-+				if (!down_interruptible(&dec->pes2ts_sem)) {
-+					dvb_filter_pes2ts(&dec->v_pes2ts,
-+							  dec->v_pes,
-+							  dec->v_pes_length +
-+							  prebytes);
-+
-+					up(&dec->pes2ts_sem);
-+				}
-+			}
-+
-+			if (av_pes[5] & 0x10) {
-+				dec->v_pes[7] = 0x80;
-+				dec->v_pes[8] = 0x05;
-+
-+				dec->v_pes[9] = 0x21 |
-+						((av_pes[8] & 0xc0) >> 5);
-+				dec->v_pes[10] = ((av_pes[8] & 0x3f) << 2) |
-+						 ((av_pes[9] & 0xc0) >> 6);
-+				dec->v_pes[11] = 0x01 |
-+						 ((av_pes[9] & 0x3f) << 2) |
-+						 ((av_pes[10] & 0x80) >> 6);
-+				dec->v_pes[12] = ((av_pes[10] & 0x7f) << 1) |
-+						 ((av_pes[11] & 0xc0) >> 7);
-+				dec->v_pes[13] = 0x01 |
-+						 ((av_pes[11] & 0x7f) << 1);
-+
-+				memcpy(&dec->v_pes[14], &av_pes[12 + prebytes],
-+				       length - 16 - prebytes);
-+				dec->v_pes_length = 14 + length - 16 - prebytes;
-+			} else {
-+				dec->v_pes[7] = 0x00;
-+				dec->v_pes[8] = 0x00;
-+
-+				memcpy(&dec->v_pes[9], &av_pes[8], length - 12);
-+				dec->v_pes_length = 9 + length - 12;
-+			}
-+
-+			dec->v_pes_postbytes = postbytes;
-+
-+			if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
-+			    dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
-+			    dec->v_pes[11 + dec->v_pes[8]] == 0x01)
-+				dec->v_pes[6] = 0x84;
-+			else
-+				dec->v_pes[6] = 0x80;
-+
-+			v_pes_payload_length = htons(dec->v_pes_length - 6 +
-+						     postbytes);
-+			memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
-+
-+			if (postbytes == 0) {
-+				if (!down_interruptible(&dec->pes2ts_sem)) {
-+					dvb_filter_pes2ts(&dec->v_pes2ts,
-+							  dec->v_pes,
-+							  dec->v_pes_length);
-+
-+					up(&dec->pes2ts_sem);
-+				}
-+			}
-+
-+			break;
-+		}
-+
-+	case 0x02:		/* MainAudioStream */
-+		dvb_filter_pes2ts(&dec->a_pes2ts, &av_pes[8], length - 12);
-+		break;
-+
-+	default:
-+		printk("%s: unknown AV_PES type: %02x.\n", __FUNCTION__,
-+		       av_pes[2]);
-+		break;
-+
-+	}
-+}
-+
-+static void ttusb_dec_process_urb_frame(struct ttusb_dec * dec, u8 * b,
-+					int length)
-+{
-+	while (length) {
-+		switch (dec->av_pes_state) {
-+
-+		case 0:
-+		case 1:
-+		case 3:
-+			if (*b++ == 0xaa) {
-+				dec->av_pes_state++;
-+				if (dec->av_pes_state == 4)
-+					dec->av_pes_length = 0;
-+			} else {
-+				dec->av_pes_state = 0;
-+			}
-+
-+			length--;
-+			break;
-+
-+		case 2:
-+			if (*b++ == 0x00) {
-+				dec->av_pes_state++;
-+			} else {
-+				dec->av_pes_state = 0;
-+			}
-+
-+			length--;
-+			break;
-+
-+		case 4:
-+			dec->av_pes[dec->av_pes_length++] = *b++;
-+
-+			if (dec->av_pes_length == 8) {
-+				dec->av_pes_state++;
-+				dec->av_pes_payload_length = le16_to_cpup(
-+						(u16 *)(dec->av_pes + 6));
-+			}
-+
-+			length--;
-+			break;
-+
-+		case 5: {
-+				int remainder = dec->av_pes_payload_length +
-+						8 - dec->av_pes_length;
-+
-+				if (length >= remainder) {
-+					memcpy(dec->av_pes + dec->av_pes_length,
-+					       b, remainder);
-+					dec->av_pes_length += remainder;
-+					b += remainder;
-+					length -= remainder;
-+					dec->av_pes_state++;
-+				} else {
-+					memcpy(&dec->av_pes[dec->av_pes_length],
-+					       b, length);
-+					dec->av_pes_length += length;
-+					length = 0;
-+				}
-+
-+				break;
-+			}
-+
-+		case 6:
-+			dec->av_pes[dec->av_pes_length++] = *b++;
-+
-+			if (dec->av_pes_length ==
-+			    8 + dec->av_pes_payload_length + 4) {
-+				ttusb_dec_process_av_pes(dec, dec->av_pes,
-+							 dec->av_pes_length);
-+				dec->av_pes_state = 0;
-+			}
-+
-+			length--;
-+			break;
-+
-+		default:
-+			printk("%s: illegal packet state encountered.\n",
-+			       __FUNCTION__);
-+			dec->av_pes_state = 0;
-+
-+		}
-+
-+	}
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void ttusb_dec_process_urb(struct urb *urb)
-+#else
-+static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs)
-+#endif
-+{
-+	struct ttusb_dec *dec = urb->context;
-+
-+	if (!urb->status) {
-+		int i;
-+
-+		for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
-+			struct usb_iso_packet_descriptor *d;
-+			u8 *b;
-+			int length;
-+
-+			d = &urb->iso_frame_desc[i];
-+			b = urb->transfer_buffer + d->offset;
-+			length = d->actual_length;
-+
-+			ttusb_dec_process_urb_frame(dec, b, length);
-+		}
-+	} else {
-+		 /* -ENOENT is expected when unlinking urbs */
-+		if (urb->status != -ENOENT)
-+			dprintk("%s: urb error: %d\n", __FUNCTION__,
-+				urb->status);
-+	}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+	if (dec->iso_stream_count)
-+		usb_submit_urb(urb, GFP_KERNEL);
-+#endif
-+}
-+
-+static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
-+{
-+	int i, j, buffer_offset = 0;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		int frame_offset = 0;
-+		struct urb *urb = dec->iso_urb[i];
-+
-+		urb->dev = dec->udev;
-+		urb->context = dec;
-+		urb->complete = ttusb_dec_process_urb;
-+		urb->pipe = dec->stream_pipe;
-+		urb->transfer_flags = URB_ISO_ASAP;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+		urb->interval = 1;
-+#endif
-+		urb->number_of_packets = FRAMES_PER_ISO_BUF;
-+		urb->transfer_buffer_length = ISO_FRAME_SIZE *
-+					      FRAMES_PER_ISO_BUF;
-+		urb->transfer_buffer = dec->iso_buffer + buffer_offset;
-+		buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
-+
-+		for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
-+			urb->iso_frame_desc[j].offset = frame_offset;
-+			urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
-+			frame_offset += ISO_FRAME_SIZE;
-+		}
-+	}
-+}
-+
-+static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
-+{
-+	int i;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if (down_interruptible(&dec->iso_sem))
-+		return;
-+
-+	dec->iso_stream_count--;
-+
-+	if (!dec->iso_stream_count) {
-+		u8 b0[] = { 0x00 };
-+
-+		for (i = 0; i < ISO_BUF_COUNT; i++)
-+			usb_unlink_urb(dec->iso_urb[i]);
-+
-+		ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
-+	}
-+
-+	up(&dec->iso_sem);
-+}
-+
-+/* Setting the interface of the DEC tends to take down the USB communications
-+ * for a short period, so it's important not to call this function just before
-+ * trying to talk to it.
-+ */
-+static void ttusb_dec_set_streaming_interface(struct ttusb_dec *dec)
-+{
-+	if (!dec->interface) {
-+		usb_set_interface(dec->udev, 0, 8);
-+		dec->interface = 8;
-+	}
-+}
-+
-+static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
-+{
-+	int i, result;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if (down_interruptible(&dec->iso_sem))
-+		return -EAGAIN;
-+
-+	if (!dec->iso_stream_count) {
-+		u8 b0[] = { 0x05 };
-+
-+		ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
-+
-+		ttusb_dec_setup_urbs(dec);
-+
-+		for (i = 0; i < ISO_BUF_COUNT; i++) {
-+			if ((result = usb_submit_urb(dec->iso_urb[i]
-+						    , GFP_KERNEL))) {
-+				printk("%s: failed urb submission %d: "
-+				       "error %d\n", __FUNCTION__, i, result);
-+
-+				while (i) {
-+					usb_unlink_urb(dec->iso_urb[i - 1]);
-+					i--;
-+				}
-+
-+				up(&dec->iso_sem);
-+				return result;
-+			}
-+		}
-+
-+		dec->av_pes_state = 0;
-+		dec->v_pes_postbytes = 0;
-+	}
-+
-+	dec->iso_stream_count++;
-+
-+	up(&dec->iso_sem);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	ttusb_dec_set_streaming_interface(dec);
-+#endif
-+
-+	return 0;
-+}
-+
-+static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-+	struct ttusb_dec *dec = dvbdmx->priv;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if (!dvbdmx->dmx.frontend)
-+		return -EINVAL;
-+
-+	dprintk("  pid: 0x%04X\n", dvbdmxfeed->pid);
-+
-+	switch (dvbdmxfeed->type) {
-+
-+	case DMX_TYPE_TS:
-+		dprintk("  type: DMX_TYPE_TS\n");
-+		break;
-+
-+	case DMX_TYPE_SEC:
-+		dprintk("  type: DMX_TYPE_SEC\n");
-+		break;
-+
-+	default:
-+		dprintk("  type: unknown (%d)\n", dvbdmxfeed->type);
-+		return -EINVAL;
-+
-+	}
-+
-+	dprintk("  ts_type:");
-+
-+	if (dvbdmxfeed->ts_type & TS_DECODER)
-+		dprintk(" TS_DECODER");
-+
-+	if (dvbdmxfeed->ts_type & TS_PACKET)
-+		dprintk(" TS_PACKET");
-+
-+	if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
-+		dprintk(" TS_PAYLOAD_ONLY");
-+
-+	dprintk("\n");
-+
-+	switch (dvbdmxfeed->pes_type) {
-+
-+	case DMX_TS_PES_VIDEO:
-+		dprintk("  pes_type: DMX_TS_PES_VIDEO\n");
-+		dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
-+		dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
-+		ttusb_dec_set_pids(dec);
-+		break;
-+
-+	case DMX_TS_PES_AUDIO:
-+		dprintk("  pes_type: DMX_TS_PES_AUDIO\n");
-+		dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
-+		ttusb_dec_set_pids(dec);
-+		break;
-+
-+	case DMX_TS_PES_TELETEXT:
-+		dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
-+		dprintk("  pes_type: DMX_TS_PES_TELETEXT\n");
-+		break;
-+
-+	case DMX_TS_PES_PCR:
-+		dprintk("  pes_type: DMX_TS_PES_PCR\n");
-+		dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
-+		ttusb_dec_set_pids(dec);
-+		break;
-+
-+	case DMX_TS_PES_OTHER:
-+		dprintk("  pes_type: DMX_TS_PES_OTHER\n");
-+		break;
-+
-+	default:
-+		dprintk("  pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
-+		return -EINVAL;
-+
-+	}
-+
-+	ttusb_dec_start_iso_xfer(dec);
-+
-+	return 0;
-+}
-+
-+static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-+{
-+	struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	ttusb_dec_stop_iso_xfer(dec);
-+
-+	return 0;
-+}
-+
-+static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
-+{
-+	int i;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++)
-+		if (dec->iso_urb[i])
-+			usb_free_urb(dec->iso_urb[i]);
-+
-+	pci_free_consistent(NULL,
-+			    ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
-+					      ISO_BUF_COUNT),
-+			    dec->iso_buffer, dec->iso_dma_handle);
-+}
-+
-+static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
-+{
-+	int i;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dec->iso_buffer = pci_alloc_consistent(NULL,
-+					       ISO_FRAME_SIZE *
-+					       (FRAMES_PER_ISO_BUF *
-+						ISO_BUF_COUNT),
-+				 	       &dec->iso_dma_handle);
-+
-+	memset(dec->iso_buffer, 0,
-+	       sizeof(ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT)));
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		struct urb *urb;
-+
-+		if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_KERNEL))) {
-+			ttusb_dec_free_iso_urbs(dec);
-+			return -ENOMEM;
-+		}
-+
-+		dec->iso_urb[i] = urb;
-+	}
-+
-+	ttusb_dec_setup_urbs(dec);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	for (i = 0; i < ISO_BUF_COUNT; i++) {
-+		int next = (i + 1) % ISO_BUF_COUNT;
-+		dec->iso_urb[i]->next = dec->iso_urb[next];
-+	}
-+#endif
-+
-+	return 0;
-+}
-+
-+static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dec->v_pes[0] = 0x00;
-+	dec->v_pes[1] = 0x00;
-+	dec->v_pes[2] = 0x01;
-+	dec->v_pes[3] = 0xe0;
-+}
-+
-+static void ttusb_dec_init_usb(struct ttusb_dec *dec)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	sema_init(&dec->usb_sem, 1);
-+	sema_init(&dec->iso_sem, 1);
-+
-+	dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
-+	dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
-+	dec->stream_pipe = usb_rcvisocpipe(dec->udev, STREAM_PIPE);
-+
-+	ttusb_dec_alloc_iso_urbs(dec);
-+}
-+
-+#include "dsp_dec2000.h"
-+
-+static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
-+{
-+	int i, j, actual_len, result, size, trans_count;
-+	u8 b0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x61,
-+		    0x00 };
-+	u8 b1[] = { 0x61 };
-+	u8 b[ARM_PACKET_SIZE];
-+	u32 dsp_length = htonl(sizeof(dsp_dec2000));
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	memcpy(b0, &dsp_length, 4);
-+
-+	result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
-+
-+	if (result)
-+		return result;
-+
-+	trans_count = 0;
-+	j = 0;
-+
-+	for (i = 0; i < sizeof(dsp_dec2000); i += COMMAND_PACKET_SIZE) {
-+		size = sizeof(dsp_dec2000) - i;
-+		if (size > COMMAND_PACKET_SIZE)
-+			size = COMMAND_PACKET_SIZE;
-+
-+		b[j + 0] = 0xaa;
-+		b[j + 1] = trans_count++;
-+		b[j + 2] = 0xf0;
-+		b[j + 3] = size;
-+		memcpy(&b[j + 4], &dsp_dec2000[i], size);
-+
-+		j += COMMAND_PACKET_SIZE + 4;
-+
-+		if (j >= ARM_PACKET_SIZE) {
-+			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
-+					      ARM_PACKET_SIZE, &actual_len,
-+					      HZ / 10);
-+			j = 0;
-+		} else if (size < COMMAND_PACKET_SIZE) {
-+			result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
-+					      j - COMMAND_PACKET_SIZE + size,
-+					      &actual_len, HZ / 10);
-+		}
-+	}
-+
-+	result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
-+
-+	return result;
-+}
-+
-+static void ttusb_dec_init_stb(struct ttusb_dec *dec)
-+{
-+	u8 c[COMMAND_PACKET_SIZE];
-+	int c_length;
-+	int result;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
-+
-+	if (!result)
-+		if (c_length != 0x0c || (c_length == 0x0c && c[9] != 0x63))
-+			ttusb_dec_boot_dsp(dec);
-+}
-+
-+static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
-+{
-+	int result;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if ((result = dvb_register_adapter(&dec->adapter, "dec2000")) < 0) {
-+		printk("%s: dvb_register_adapter failed: error %d\n",
-+		       __FUNCTION__, result);
-+
-+		return result;
-+	}
-+
-+	if (!(dec->i2c_bus = dvb_register_i2c_bus(ttusb_dec_i2c_master_xfer,
-+						  dec, dec->adapter, 0))) {
-+		printk("%s: dvb_register_i2c_bus failed\n", __FUNCTION__);
-+
-+		dvb_unregister_adapter(dec->adapter);
-+
-+		return -ENOMEM;
-+	}
-+
-+	dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-+
-+	dec->demux.priv = (void *)dec;
-+	dec->demux.filternum = 31;
-+	dec->demux.feednum = 31;
-+	dec->demux.start_feed = ttusb_dec_start_feed;
-+	dec->demux.stop_feed = ttusb_dec_stop_feed;
-+	dec->demux.write_to_decoder = NULL;
-+
-+	if ((result = dvb_dmx_init(&dec->demux)) < 0) {
-+		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
-+		       result);
-+
-+		dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
-+				       0);
-+		dvb_unregister_adapter(dec->adapter);
-+
-+		return result;
-+	}
-+
-+	dec->dmxdev.filternum = 32;
-+	dec->dmxdev.demux = &dec->demux.dmx;
-+	dec->dmxdev.capabilities = 0;
-+
-+	if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) {
-+		printk("%s: dvb_dmxdev_init failed: error %d\n",
-+		       __FUNCTION__, result);
-+
-+		dvb_dmx_release(&dec->demux);
-+		dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
-+				       0);
-+		dvb_unregister_adapter(dec->adapter);
-+
-+		return result;
-+	}
-+
-+	dec->frontend.source = DMX_FRONTEND_0;
-+
-+	if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
-+						  &dec->frontend)) < 0) {
-+		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
-+		       result);
-+
-+		dvb_dmxdev_release(&dec->dmxdev);
-+		dvb_dmx_release(&dec->demux);
-+		dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
-+				       0);
-+		dvb_unregister_adapter(dec->adapter);
-+
-+		return result;
-+	}
-+
-+	if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
-+						      &dec->frontend)) < 0) {
-+		printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
-+		       result);
-+
-+		dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
-+		dvb_dmxdev_release(&dec->dmxdev);
-+		dvb_dmx_release(&dec->demux);
-+		dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
-+				       0);
-+		dvb_unregister_adapter(dec->adapter);
-+
-+		return result;
-+	}
-+
-+	sema_init(&dec->pes2ts_sem, 1);
-+
-+	dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);
-+
-+	return 0;
-+}
-+
-+static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
-+{
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dvb_net_release(&dec->dvb_net);
-+	dec->demux.dmx.close(&dec->demux.dmx);
-+	dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
-+	dvb_dmxdev_release(&dec->dmxdev);
-+	dvb_dmx_release(&dec->demux);
-+	dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter, 0);
-+	dvb_unregister_adapter(dec->adapter);
-+}
-+
-+static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
-+{
-+	int i;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	dec->iso_stream_count = 0;
-+
-+	for (i = 0; i < ISO_BUF_COUNT; i++)
-+		usb_unlink_urb(dec->iso_urb[i]);
-+
-+	ttusb_dec_free_iso_urbs(dec);
-+}
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void *ttusb_dec_probe(struct usb_device *udev, unsigned int ifnum,
-+			     const struct usb_device_id *id)
-+{
-+	struct ttusb_dec *dec;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	if (ifnum != 0)
-+		return NULL;
-+
-+	if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
-+		printk("%s: couldn't allocate memory.\n", __FUNCTION__);
-+		return NULL;
-+	}
-+
-+	memset(dec, 0, sizeof(struct ttusb_dec));
-+
-+	dec->udev = udev;
-+
-+	ttusb_dec_init_usb(dec);
-+	ttusb_dec_init_stb(dec);
-+	ttusb_dec_init_dvb(dec);
-+	ttusb_dec_init_v_pes(dec);
-+
-+	return (void *)dec;
-+}
-+#else
-+static int ttusb_dec_probe(struct usb_interface *intf,
-+			   const struct usb_device_id *id)
-+{
-+	struct usb_device *udev;
-+	struct ttusb_dec *dec;
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	udev = interface_to_usbdev(intf);
-+
-+	if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
-+		printk("%s: couldn't allocate memory.\n", __FUNCTION__);
-+		return -ENOMEM;
-+	}
-+
-+	memset(dec, 0, sizeof(struct ttusb_dec));
-+
-+	dec->udev = udev;
-+
-+	ttusb_dec_init_usb(dec);
-+	ttusb_dec_init_stb(dec);
-+	ttusb_dec_init_dvb(dec);
-+	ttusb_dec_init_v_pes(dec);
-+
-+	usb_set_intfdata(intf, (void *)dec);
-+	ttusb_dec_set_streaming_interface(dec);
-+
-+	return 0;
-+}
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+static void ttusb_dec_disconnect(struct usb_device *udev, void *data)
-+{
-+	struct ttusb_dec *dec = data;
-+#else
-+static void ttusb_dec_disconnect(struct usb_interface *intf)
-+{
-+	struct ttusb_dec *dec = usb_get_intfdata(intf);
-+
-+	usb_set_intfdata(intf, NULL);
-+#endif
-+
-+	dprintk("%s\n", __FUNCTION__);
-+
-+	ttusb_dec_exit_usb(dec);
-+	ttusb_dec_exit_dvb(dec);
-+
-+	kfree(dec);
-+}
-+
-+static struct usb_device_id ttusb_dec_table[] = {
-+	{USB_DEVICE(0x0b48, 0x1006)},	/* Unconfirmed */
-+	{USB_DEVICE(0x0b48, 0x1007)},	/* Unconfirmed */
-+	{USB_DEVICE(0x0b48, 0x1008)},	/* DEC 2000 t */
-+	{}
-+};
-+
-+static struct usb_driver ttusb_dec_driver = {
-+      name:		DRIVER_NAME,
-+      probe:		ttusb_dec_probe,
-+      disconnect:	ttusb_dec_disconnect,
-+      id_table:		ttusb_dec_table,
-+};
-+
-+static int __init ttusb_dec_init(void)
-+{
-+	int result;
-+
-+	if ((result = usb_register(&ttusb_dec_driver)) < 0) {
-+		printk("%s: initialisation failed: error %d.\n", __FUNCTION__,
-+		       result);
-+		return result;
-+	}
-+
-+	return 0;
-+}
-+
-+static void __exit ttusb_dec_exit(void)
-+{
-+	usb_deregister(&ttusb_dec_driver);
-+}
-+
-+module_init(ttusb_dec_init);
-+module_exit(ttusb_dec_exit);
-+
-+MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
-+MODULE_DESCRIPTION(DRIVER_NAME);
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
-+
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "Debug level");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/dvb/ttusb-dec/ttusb_dec.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,87 @@
-+/*
-+ * TTUSB DEC Driver
-+ *
-+ * Copyright (C) 2003 Alex Woods <linux-dvb@giblets.org>
-+ *
-+ * This program 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#ifndef _TTUSB_DEC_H
-+#define _TTUSB_DEC_H
-+
-+#include "asm/semaphore.h"
-+#include "dmxdev.h"
-+#include "dvb_demux.h"
-+#include "dvb_filter.h"
-+#include "dvb_i2c.h"
-+#include "dvb_net.h"
-+
-+#define DRIVER_NAME		"TechnoTrend/Hauppauge DEC USB"
-+
-+#define COMMAND_PIPE		0x03
-+#define RESULT_PIPE		0x84
-+#define STREAM_PIPE		0x88
-+
-+#define COMMAND_PACKET_SIZE	0x3c
-+#define ARM_PACKET_SIZE		0x1000
-+
-+#define ISO_BUF_COUNT		0x04
-+#define FRAMES_PER_ISO_BUF	0x04
-+#define ISO_FRAME_SIZE		0x0380
-+
-+#define	MAX_AV_PES_LENGTH	6144
-+
-+struct ttusb_dec {
-+	/* DVB bits */
-+	struct dvb_adapter	*adapter;
-+	struct dmxdev		dmxdev;
-+	struct dvb_demux	demux;
-+	struct dmx_frontend	frontend;
-+	struct dvb_i2c_bus	*i2c_bus;
-+	struct dvb_net		dvb_net;
-+
-+	u16			pid[DMX_PES_OTHER];
-+
-+	/* USB bits */
-+	struct usb_device	*udev;
-+	u8			trans_count;
-+	unsigned int		command_pipe;
-+	unsigned int		result_pipe;
-+	unsigned int		stream_pipe;
-+	int			interface;
-+	struct semaphore	usb_sem;
-+
-+	void			*iso_buffer;
-+	dma_addr_t		iso_dma_handle;
-+	struct urb		*iso_urb[ISO_BUF_COUNT];
-+	int			iso_stream_count;
-+	struct semaphore	iso_sem;
-+
-+	u8			av_pes[MAX_AV_PES_LENGTH + 4];
-+	int			av_pes_state;
-+	int			av_pes_length;
-+	int			av_pes_payload_length;
-+
-+	struct dvb_filter_pes2ts	a_pes2ts;
-+	struct dvb_filter_pes2ts	v_pes2ts;
-+	struct semaphore		pes2ts_sem;
-+
-+	u8			v_pes[16 + MAX_AV_PES_LENGTH];
-+	int			v_pes_length;
-+	int			v_pes_postbytes;
-+};
-+
-+#endif
---- linux-2.6.0-test1/drivers/media/video/dpc7146.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/video/dpc7146.c	2003-07-19 17:03:50.000000000 -0700
-@@ -173,6 +173,8 @@ static int dpc_init_done(struct saa7146_
- 	return 0;
- }
- 
-+static struct saa7146_ext_vv vv_data;
-+
- /* this function only gets called when the probing was successful */
- static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
- {
-@@ -183,7 +185,7 @@ static int dpc_attach(struct saa7146_dev
- 	/* checking for i2c-devices can be omitted here, because we
- 	   already did this in "dpc_vl42_probe" */
- 
--	saa7146_vv_init(dev);
-+	saa7146_vv_init(dev,&vv_data);
- 	if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
- 		ERR(("cannot register capture v4l2 device. skipping.\n"));
- 		return -1;
-@@ -246,8 +248,9 @@ int dpc_vbi_bypass(struct saa7146_dev* d
- }
- #endif
- 
--static int dpc_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
-+static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
- {
-+	struct saa7146_dev *dev = fh->dev;
- 	struct dpc* dpc = (struct dpc*)dev->ext_priv;
- /*
- 	struct saa7146_vv *vv = dev->vv_data; 
-@@ -307,23 +310,32 @@ static int std_callback(struct saa7146_d
- }
- 
- static struct saa7146_standard standard[] = {
--	{ "PAL-BG",	V4L2_STD_PAL_BG,	SAA7146_PAL_VALUES },
--	{ "PAL-I",	V4L2_STD_PAL_I,		SAA7146_PAL_VALUES },
--	{ "NTSC",	V4L2_STD_NTSC,		SAA7146_NTSC_VALUES },
--	{ "SECAM", 	V4L2_STD_SECAM,		SAA7146_SECAM_VALUES },
-+	{
-+		.name	= "PAL", 	.id	= V4L2_STD_PAL,
-+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}, {
-+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-+		.v_offset	= 0x16,	.v_field 	= 240,	.v_calc		= 480,
-+		.h_offset	= 0x06,	.h_pixels 	= 708,	.h_calc		= 708+1,
-+		.v_max_out	= 480,	.h_max_out	= 640,
-+	}, {
-+		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-+		.v_offset	= 0x14,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 720,	.h_calc		= 720+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}
- };
- 
--static
--struct saa7146_extension extension;
-+static struct saa7146_extension extension;
- 
--static
--struct saa7146_pci_extension_data dpc = {
-+static struct saa7146_pci_extension_data dpc = {
-         .ext_priv = "Multimedia eXtension Board",
-         .ext = &extension,
- };
- 
--static
--struct pci_device_id pci_tbl[] = {
-+static struct pci_device_id pci_tbl[] = {
- 	{
- 		.vendor    = PCI_VENDOR_ID_PHILIPS,
- 		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
-@@ -337,8 +349,7 @@ struct pci_device_id pci_tbl[] = {
- 
- MODULE_DEVICE_TABLE(pci, pci_tbl);
- 
--static
--struct saa7146_ext_vv vv_data = {
-+static struct saa7146_ext_vv vv_data = {
- 	.inputs		= DPC_INPUTS,
- 	.capabilities	= V4L2_CAP_VBI_CAPTURE,
- 	.stds		= &standard[0],
-@@ -348,14 +359,12 @@ struct saa7146_ext_vv vv_data = {
- 	.ioctl		= dpc_ioctl,
- };
- 
--static
--struct saa7146_extension extension = {
-+static struct saa7146_extension extension = {
- 	.name		= "dpc7146 demonstration board",
- 	.flags		= SAA7146_USE_I2C_IRQ,
- 	
- 	.pci_tbl	= &pci_tbl[0],
- 	.module		= THIS_MODULE,
--	.ext_vv_data	= &vv_data,
- 
- 	.probe		= dpc_probe,
- 	.attach		= dpc_attach,
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/video/hexium_gemini.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,411 @@
-+/*
-+    hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
-+               
-+    Visit http://www.mihu.de/linux/saa7146/ and follow the link
-+    to "hexium" for further details about this card.
-+    
-+    Copyright (C) 2003 Michael Hunold <michael@mihu.de>
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+*/
-+
-+#define DEBUG_VARIABLE debug
-+
-+#include <media/saa7146_vv.h>
-+
-+static int debug = 255;
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "debug verbosity");
-+
-+/* global variables */
-+int hexium_num = 0;
-+
-+#include "hexium_gemini.h"
-+
-+/* bring hardware to a sane state. this has to be done, just in case someone
-+   wants to capture from this device before it has been properly initialized.
-+   the capture engine would badly fail, because no valid signal arrives on the
-+   saa7146, thus leading to timeouts and stuff. */
-+static int hexium_init_done(struct saa7146_dev *dev)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+	union i2c_smbus_data data;
-+	int i = 0;
-+
-+	DEB_D(("hexium_init_done called.\n"));
-+
-+	/* initialize the helper ics to useful values */
-+	for (i = 0; i < sizeof(hexium_ks0127b); i++) {
-+		data.byte = hexium_ks0127b[i];
-+		if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
-+			printk("failed for address 0x%02x\n", i);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int hexium_set_input(struct hexium *hexium, int input)
-+{
-+	union i2c_smbus_data data;
-+
-+	DEB_D((".\n"));
-+
-+	data.byte = hexium_input_select[input].byte;
-+	if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) {
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
-+{
-+	union i2c_smbus_data data;
-+	int i = 0;
-+
-+	DEB_D((".\n"));
-+
-+	while (vdec[i].adr != -1) {
-+		data.byte = vdec[i].byte;
-+		if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) {
-+			printk("failed for address 0x%02x\n", i);
-+			return -1;
-+		}
-+		i++;
-+	}
-+	return 0;
-+}
-+
-+static struct saa7146_ext_vv vv_data;
-+
-+/* this function only gets called when the probing was successful */
-+static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+
-+	DEB_EE((".\n"));
-+
-+	hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
-+	if (NULL == hexium) {
-+		printk("hexium_v4l2.o: hexium_probe: not enough kernel memory.\n");
-+		return -ENOMEM;
-+	}
-+	memset(hexium, 0x0, sizeof(struct hexium));
-+	(struct hexium *) dev->ext_priv = hexium;
-+
-+	/* FIXME: enable i2c-port pins, video-port-pins
-+	   video port pins should be enabled here ?! */
-+	saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
-+
-+	saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
-+	if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
-+		DEB_S(("cannot register i2c-device. skipping.\n"));
-+		kfree(hexium);
-+		return -EFAULT;
-+	}
-+
-+	/*  set HWControl GPIO number 2 */
-+	saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-+
-+	saa7146_write(dev, DD1_INIT, 0x07000700);
-+	saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-+	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-+
-+	/* the rest */
-+	hexium->cur_input = 0;
-+	hexium_init_done(dev);
-+
-+	hexium_set_standard(hexium, hexium_pal);
-+	hexium->cur_std = V4L2_STD_PAL;
-+
-+	hexium_set_input(hexium, 0);
-+	hexium->cur_input = 0;
-+
-+	saa7146_vv_init(dev, &vv_data);
-+	if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium", VFL_TYPE_GRABBER)) {
-+		ERR(("cannot register capture v4l2 device. skipping.\n"));
-+		return -1;
-+	}
-+
-+	printk("hexium: found 'hexium frame grabber'-%d.\n", hexium_num);
-+	hexium_num++;
-+
-+	return 0;
-+}
-+
-+static int hexium_detach(struct saa7146_dev *dev)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+
-+	DEB_EE(("dev:%p\n", dev));
-+
-+	saa7146_unregister_device(&hexium->video_dev, dev);
-+	saa7146_vv_release(dev);
-+
-+	hexium_num--;
-+
-+	i2c_del_adapter(&hexium->i2c_adapter);
-+	kfree(hexium);
-+	return 0;
-+}
-+
-+static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-+{
-+	struct saa7146_dev *dev = fh->dev;
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+/*
-+	struct saa7146_vv *vv = dev->vv_data; 
-+*/
-+	switch (cmd) {
-+	case VIDIOC_ENUMINPUT:
-+		{
-+			struct v4l2_input *i = arg;
-+			DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-+
-+			if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
-+				return -EINVAL;
-+			}
-+
-+			memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-+
-+			DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
-+			return 0;
-+		}
-+	case VIDIOC_G_INPUT:
-+		{
-+			int *input = (int *) arg;
-+			*input = hexium->cur_input;
-+
-+			DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
-+			return 0;
-+		}
-+	case VIDIOC_S_INPUT:
-+		{
-+			int input = *(int *) arg;
-+
-+			DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-+
-+			if (input < 0 || input >= HEXIUM_INPUTS) {
-+				return -EINVAL;
-+			}
-+
-+			hexium->cur_input = input;
-+			hexium_set_input(hexium, input);
-+
-+			return 0;
-+		}
-+		/* the saa7146 provides some controls (brightness, contrast, saturation)
-+		   which gets registered *after* this function. because of this we have
-+		   to return with a value != 0 even if the function succeded.. */
-+	case VIDIOC_QUERYCTRL:
-+		{
-+			struct v4l2_queryctrl *qc = arg;
-+			int i;
-+
-+			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-+				if (hexium_controls[i].id == qc->id) {
-+					*qc = hexium_controls[i];
-+					DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
-+					return 0;
-+				}
-+			}
-+			return -EAGAIN;
-+		}
-+	case VIDIOC_G_CTRL:
-+		{
-+			struct v4l2_control *vc = arg;
-+			int i;
-+
-+			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-+				if (hexium_controls[i].id == vc->id) {
-+					break;
-+				}
-+			}
-+
-+			if (i < 0) {
-+				return -EAGAIN;
-+			}
-+
-+			switch (vc->id) {
-+			case V4L2_CID_PRIVATE_BASE:{
-+					vc->value = hexium->cur_bw;
-+					DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
-+					return 0;
-+				}
-+			}
-+			return -EINVAL;
-+		}
-+
-+	case VIDIOC_S_CTRL:
-+		{
-+			struct v4l2_control *vc = arg;
-+			int i = 0;
-+
-+			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-+				if (hexium_controls[i].id == vc->id) {
-+					break;
-+				}
-+			}
-+
-+			if (i < 0) {
-+				return -EAGAIN;
-+			}
-+
-+			switch (vc->id) {
-+			case V4L2_CID_PRIVATE_BASE:{
-+					hexium->cur_bw = vc->value;
-+					break;
-+				}
-+			}
-+
-+			DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-+
-+			if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-+				hexium_set_standard(hexium, hexium_pal);
-+				return 0;
-+			}
-+			if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-+				hexium_set_standard(hexium, hexium_ntsc);
-+				return 0;
-+			}
-+			if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-+				hexium_set_standard(hexium, hexium_secam);
-+				return 0;
-+			}
-+			if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-+				hexium_set_standard(hexium, hexium_pal_bw);
-+				return 0;
-+			}
-+			if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-+				hexium_set_standard(hexium, hexium_ntsc_bw);
-+				return 0;
-+			}
-+			if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-+				/* fixme: is there no bw secam mode? */
-+				return -EINVAL;
-+			}
-+
-+			return -EINVAL;
-+		}
-+	default:
-+/*
-+		DEB_D(("v4l2_ioctl does not handle this ioctl.\n"));
-+*/
-+		return -ENOIOCTLCMD;
-+	}
-+	return 0;
-+}
-+
-+static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+
-+	if (V4L2_STD_PAL == std->id) {
-+		hexium_set_standard(hexium, hexium_pal);
-+		hexium->cur_std = V4L2_STD_PAL;
-+		return 0;
-+	} else if (V4L2_STD_NTSC == std->id) {
-+		hexium_set_standard(hexium, hexium_ntsc);
-+		hexium->cur_std = V4L2_STD_NTSC;
-+		return 0;
-+	} else if (V4L2_STD_SECAM == std->id) {
-+		hexium_set_standard(hexium, hexium_secam);
-+		hexium->cur_std = V4L2_STD_SECAM;
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+static struct saa7146_extension hexium_extension;
-+
-+static struct saa7146_pci_extension_data hexium_gemini_4bnc = {
-+	.ext_priv = "Hexium Gemini (4 BNC)",
-+	.ext = &hexium_extension,
-+};
-+
-+static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
-+	.ext_priv = "Hexium Gemini Dual (4 BNC)",
-+	.ext = &hexium_extension,
-+};
-+
-+static struct pci_device_id pci_tbl[] = {
-+	{
-+	 .vendor = PCI_VENDOR_ID_PHILIPS,
-+	 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
-+	 .subvendor = 0x17c8,
-+	 .subdevice = 0x2401,
-+	 .driver_data = (unsigned long) &hexium_gemini_4bnc,
-+	 },
-+	{
-+	 .vendor = PCI_VENDOR_ID_PHILIPS,
-+	 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
-+	 .subvendor = 0x17c8,
-+	 .subdevice = 0x2402,
-+	 .driver_data = (unsigned long) &hexium_gemini_dual_4bnc,
-+	 },
-+	{
-+	 .vendor = 0,
-+	 }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, pci_tbl);
-+
-+static struct saa7146_ext_vv vv_data = {
-+	.inputs = HEXIUM_INPUTS,
-+	.capabilities = 0,
-+	.stds = &hexium_standards[0],
-+	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
-+	.std_callback = &std_callback,
-+	.ioctls = &ioctls[0],
-+	.ioctl = hexium_ioctl,
-+};
-+
-+static struct saa7146_extension hexium_extension = {
-+	.name = "hexium gemini",
-+	.flags = SAA7146_USE_I2C_IRQ,
-+
-+	.pci_tbl = &pci_tbl[0],
-+	.module = THIS_MODULE,
-+
-+	.attach = hexium_attach,
-+	.detach = hexium_detach,
-+
-+	.irq_mask = 0,
-+	.irq_func = NULL,
-+};
-+
-+int __init hexium_init_module(void)
-+{
-+	if (0 != saa7146_register_extension(&hexium_extension)) {
-+		DEB_S(("failed to register extension.\n"));
-+		return -ENODEV;
-+	}
-+
-+	return 0;
-+}
-+
-+void __exit hexium_cleanup_module(void)
-+{
-+	saa7146_unregister_extension(&hexium_extension);
-+}
-+
-+module_init(hexium_init_module);
-+module_exit(hexium_cleanup_module);
-+
-+MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards");
-+MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-+MODULE_LICENSE("GPL");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/video/hexium_gemini.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,103 @@
-+#ifndef __HEXIUM_GEMINI__
-+#define __HEXIUM_GEMINI__
-+
-+#include "hexium.h"
-+
-+static struct saa7146_extension_ioctls ioctls[] = {
-+	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_QUERYCTRL, 	SAA7146_BEFORE },
-+	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_STD,		SAA7146_AFTER },
-+	{ VIDIOC_G_CTRL,	SAA7146_BEFORE },
-+	{ VIDIOC_S_CTRL,	SAA7146_BEFORE },
-+	{ 0,			0 }
-+};
-+
-+#define HEXIUM_CONTROLS	1
-+static struct v4l2_queryctrl hexium_controls[] = {
-+	{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
-+};
-+
-+#define HEXIUM_GEMUINI_V_1_0		1
-+#define HEXIUM_GEMUINI_DUAL_V_1_0	2
-+
-+struct hexium
-+{
-+	int type;
-+	struct video_device	video_dev;
-+	struct i2c_adapter	i2c_adapter;
-+		
-+	int 		cur_input;	/* current input */
-+	v4l2_std_id 	cur_std;	/* current standard */
-+	int		cur_bw;		/* current black/white status */
-+};
-+
-+/* Samsung KS0127B decoder default registers */
-+static u8 hexium_ks0127b[0x100]={
-+/*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10,
-+/*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06,
-+/*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00,
-+/*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22,
-+/*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00,
-+/*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80,
-+/*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00,
-+/*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-+};
-+
-+static struct hexium_data hexium_pal[] = {
-+	{ 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
-+};
-+
-+static struct hexium_data hexium_pal_bw[] = {
-+	{ 0x01, 0x52 },	{ 0x12, 0x64 },	{ 0x2D, 0x2C },	{ 0x2E, 0x9B },	{ -1 , 0xFF }
-+};
-+
-+static struct hexium_data hexium_ntsc[] = {
-+	{ 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
-+};
-+
-+static struct hexium_data hexium_ntsc_bw[] = {
-+	{ 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
-+};
-+
-+static struct hexium_data hexium_secam[] = {
-+	{ 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
-+};
-+
-+static struct hexium_data hexium_input_select[] = {
-+	{ 0x02, 0x60 },
-+	{ 0x02, 0x64 },
-+	{ 0x02, 0x61 },
-+	{ 0x02, 0x65 },
-+	{ 0x02, 0x62 },
-+	{ 0x02, 0x66 },
-+	{ 0x02, 0x68 },
-+	{ 0x02, 0x69 },
-+	{ 0x02, 0x6A },
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/video/hexium.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,51 @@
-+#ifndef __HEXIUM__
-+#define __HEXIUM__
-+
-+#define HEXIUM_HV_PCI6_ORION		1
-+#define HEXIUM_ORION_1SVHS_3BNC		2
-+#define HEXIUM_ORION_4BNC		3
-+#define HEXIUM_GEMUINI			4
-+#define HEXIUM_GEMUINI_DUAL		5
-+
-+static struct saa7146_standard hexium_standards[] = {
-+	{
-+		.name	= "PAL", 	.id	= V4L2_STD_PAL,
-+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}, {
-+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-+		.v_offset	= 0x17,	.v_field 	= 240,	.v_calc		= 480,
-+		.h_offset	= 0x06,	.h_pixels 	= 640,	.h_calc		= 641+1,
-+		.v_max_out	= 480,	.h_max_out	= 640,
-+	}, {
-+		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-+		.v_offset	= 0x14,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 720,	.h_calc		= 720+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}
-+};		
-+
-+
-+#define HEXIUM_INPUTS	9
-+static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
-+	{ 0, "CVBS 1",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 1, "CVBS 2",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 2, "CVBS 3",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 3, "CVBS 4",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 4, "CVBS 5",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 5, "CVBS 6",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 6, "Y/C 1",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 7, "Y/C 2",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+	{ 8, "Y/C 3",	V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-+};
-+
-+#define HEXIUM_AUDIOS	0
-+
-+struct hexium_data
-+{
-+	s8 adr;
-+	u8 byte;
-+};
-+
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/video/hexium_orion.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,328 @@
-+/*
-+    hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards
-+
-+    Visit http://www.mihu.de/linux/saa7146/ and follow the link
-+    to "hexium" for further details about this card.
-+    
-+    Copyright (C) 2003 Michael Hunold <michael@mihu.de>
-+
-+    This program 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.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+*/
-+
-+#define DEBUG_VARIABLE debug
-+
-+#include <media/saa7146_vv.h>
-+
-+static int debug = 255;
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "debug verbosity");
-+
-+/* global variables */
-+int hexium_num = 0;
-+
-+#include "hexium_orion.h"
-+
-+/* this is only called for old HV-PCI6/Orion cards
-+   without eeprom */
-+static int hexium_probe(struct saa7146_dev *dev)
-+{
-+	struct hexium *hexium = 0;
-+	union i2c_smbus_data data;
-+	int err = 0;
-+
-+	DEB_EE((".\n"));
-+
-+	/* there are no hexium orion cards with revision 0 saa7146s */
-+	if (0 == dev->revision) {
-+		return -EFAULT;
-+	}
-+
-+	hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
-+	if (NULL == hexium) {
-+		printk("hexium_orion.o: hexium_probe: not enough kernel memory.\n");
-+		return -ENOMEM;
-+	}
-+	memset(hexium, 0x0, sizeof(struct hexium));
-+
-+	/* FIXME: enable i2c-port pins, video-port-pins
-+	   video port pins should be enabled here ?! */
-+	saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
-+
-+	saa7146_write(dev, DD1_INIT, 0x02000200);
-+	saa7146_write(dev, DD1_STREAM_B, 0x00000000);
-+	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-+
-+	saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
-+	if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
-+		DEB_S(("cannot register i2c-device. skipping.\n"));
-+		kfree(hexium);
-+		return -EFAULT;
-+	}
-+
-+	/* set SAA7110 control GPIO 0 */
-+	saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
-+	/*  set HWControl GPIO number 2 */
-+	saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
-+
-+	mdelay(10);
-+
-+	/* detect newer Hexium Orion cards by subsystem ids */
-+	if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) {
-+		printk("hexium_orion.o: device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs.\n");
-+		/* we store the pointer in our private data field */
-+		(struct hexium *) dev->ext_priv = hexium;
-+		hexium->type = HEXIUM_ORION_1SVHS_3BNC;
-+		return 0;
-+	}
-+
-+	if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) {
-+		printk("hexium_orion.o: device is a Hexium Orion w/ 4 BNC inputs.\n");
-+		/* we store the pointer in our private data field */
-+		(struct hexium *) dev->ext_priv = hexium;
-+		hexium->type = HEXIUM_ORION_4BNC;
-+		return 0;
-+	}
-+
-+	/* check if this is an old hexium Orion card by looking at 
-+	   a saa7110 at address 0x4e */
-+	if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
-+		printk("hexium_orion.o: device is a Hexium HV-PCI6/Orion (old).\n");
-+		/* we store the pointer in our private data field */
-+		(struct hexium *) dev->ext_priv = hexium;
-+		hexium->type = HEXIUM_HV_PCI6_ORION;
-+		return 0;
-+	}
-+
-+	i2c_del_adapter(&hexium->i2c_adapter);
-+	kfree(hexium);
-+	return -EFAULT;
-+}
-+
-+/* bring hardware to a sane state. this has to be done, just in case someone
-+   wants to capture from this device before it has been properly initialized.
-+   the capture engine would badly fail, because no valid signal arrives on the
-+   saa7146, thus leading to timeouts and stuff. */
-+static int hexium_init_done(struct saa7146_dev *dev)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+	union i2c_smbus_data data;
-+	int i = 0;
-+
-+	DEB_D(("hexium_init_done called.\n"));
-+
-+	/* initialize the helper ics to useful values */
-+	for (i = 0; i < sizeof(hexium_saa7110); i++) {
-+		data.byte = hexium_saa7110[i];
-+		if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
-+			printk("hexium_orion: failed for address 0x%02x\n", i);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static struct saa7146_ext_vv vv_data;
-+
-+/* this function only gets called when the probing was successful */
-+static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+
-+	DEB_EE((".\n"));
-+
-+	saa7146_vv_init(dev, &vv_data);
-+	if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium", VFL_TYPE_GRABBER)) {
-+		ERR(("cannot register capture v4l2 device. skipping.\n"));
-+		return -1;
-+	}
-+
-+	printk("hexium_orion.o: found 'hexium orion' frame grabber-%d.\n", hexium_num);
-+	hexium_num++;
-+
-+	/* the rest */
-+	hexium->cur_input = 0;
-+	hexium_init_done(dev);
-+
-+	return 0;
-+}
-+
-+static int hexium_detach(struct saa7146_dev *dev)
-+{
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+
-+	DEB_EE(("dev:%p\n", dev));
-+
-+	saa7146_unregister_device(&hexium->video_dev, dev);
-+	saa7146_vv_release(dev);
-+
-+	hexium_num--;
-+
-+	i2c_del_adapter(&hexium->i2c_adapter);
-+	kfree(hexium);
-+	return 0;
-+}
-+
-+static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-+{
-+	struct saa7146_dev *dev = fh->dev;
-+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-+/*
-+	struct saa7146_vv *vv = dev->vv_data; 
-+*/
-+	switch (cmd) {
-+	case VIDIOC_ENUMINPUT:
-+		{
-+			struct v4l2_input *i = arg;
-+			DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-+
-+			if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
-+				return -EINVAL;
-+			}
-+
-+			memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-+
-+			DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
-+			return 0;
-+		}
-+	case VIDIOC_G_INPUT:
-+		{
-+			int *input = (int *) arg;
-+			*input = hexium->cur_input;
-+
-+			DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
-+			return 0;
-+		}
-+	case VIDIOC_S_INPUT:
-+		{
-+			int input = *(int *) arg;
-+
-+			if (input < 0 || input >= HEXIUM_INPUTS) {
-+				return -EINVAL;
-+			}
-+
-+			hexium->cur_input = input;
-+
-+			/* fixme: switch input here, switch audio, too! */
-+//              saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
-+			printk("hexium_orion.o: VIDIOC_S_INPUT: fixme switch input.\n");
-+
-+			return 0;
-+		}
-+	default:
-+/*
-+		DEB_D(("v4l2_ioctl does not handle this ioctl.\n"));
-+*/
-+		return -ENOIOCTLCMD;
-+	}
-+	return 0;
-+}
-+
-+static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
-+{
-+	return 0;
-+}
-+
-+static struct saa7146_extension extension;
-+
-+static struct saa7146_pci_extension_data hexium_hv_pci6 = {
-+	.ext_priv = "Hexium HV-PCI6 / Orion",
-+	.ext = &extension,
-+};
-+
-+static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = {
-+	.ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)",
-+	.ext = &extension,
-+};
-+
-+static struct saa7146_pci_extension_data hexium_orion_4bnc = {
-+	.ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)",
-+	.ext = &extension,
-+};
-+
-+static struct pci_device_id pci_tbl[] = {
-+	{
-+	 .vendor = PCI_VENDOR_ID_PHILIPS,
-+	 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
-+	 .subvendor = 0x0000,
-+	 .subdevice = 0x0000,
-+	 .driver_data = (unsigned long) &hexium_hv_pci6,
-+	 },
-+	{
-+	 .vendor = PCI_VENDOR_ID_PHILIPS,
-+	 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
-+	 .subvendor = 0x17c8,
-+	 .subdevice = 0x0101,
-+	 .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc,
-+	 },
-+	{
-+	 .vendor = PCI_VENDOR_ID_PHILIPS,
-+	 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
-+	 .subvendor = 0x17c8,
-+	 .subdevice = 0x2101,
-+	 .driver_data = (unsigned long) &hexium_orion_4bnc,
-+	 },
-+	{
-+	 .vendor = 0,
-+	 }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, pci_tbl);
-+
-+static struct saa7146_ext_vv vv_data = {
-+	.inputs = HEXIUM_INPUTS,
-+	.capabilities = 0,
-+	.stds = &hexium_standards[0],
-+	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
-+	.std_callback = &std_callback,
-+	.ioctls = &ioctls[0],
-+	.ioctl = hexium_ioctl,
-+};
-+
-+static struct saa7146_extension extension = {
-+	.name = "hexium HV-PCI6/Orion",
-+	.flags = 0,		// SAA7146_USE_I2C_IRQ,
-+
-+	.pci_tbl = &pci_tbl[0],
-+	.module = THIS_MODULE,
-+
-+	.probe = hexium_probe,
-+	.attach = hexium_attach,
-+	.detach = hexium_detach,
-+
-+	.irq_mask = 0,
-+	.irq_func = NULL,
-+};
-+
-+int __init hexium_init_module(void)
-+{
-+	if (0 != saa7146_register_extension(&extension)) {
-+		DEB_S(("failed to register extension.\n"));
-+		return -ENODEV;
-+	}
-+
-+	return 0;
-+}
-+
-+void __exit hexium_cleanup_module(void)
-+{
-+	saa7146_unregister_extension(&extension);
-+}
-+
-+module_init(hexium_init_module);
-+module_exit(hexium_cleanup_module);
-+
-+MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards");
-+MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
-+MODULE_LICENSE("GPL");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/media/video/hexium_orion.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,138 @@
-+#ifndef __HEXIUM_ORION__
-+#define __HEXIUM_ORION__
-+
-+#include "hexium.h"
-+
-+static struct saa7146_extension_ioctls ioctls[] = {
-+	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
-+	{ VIDIOC_S_STD,		SAA7146_AFTER },
-+	{ 0,			0 }
-+};
-+
-+struct hexium
-+{
-+	int type;
-+	struct video_device	video_dev;
-+	struct i2c_adapter	i2c_adapter;	
-+	int cur_input;	/* current input */
-+};
-+
-+/* Philips SAA7110 decoder default registers */
-+static u8 hexium_saa7110[53]={
-+/*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00,
-+/*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90,
-+/*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA,
-+/*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,
-+/*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F,
-+/*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03,
-+/*30*/ 0x44,0x75,0x01,0x8C,0x03
-+};
-+
-+static struct {
-+	struct hexium_data data[8];	
-+} hexium_input_select[] = {
-+{
-+	{ /* input 0 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0xD9 },
-+		{ 0x21, 0x17 }, // 0x16,
-+		{ 0x22, 0x40 },
-+		{ 0x2C, 0x03 },
-+		{ 0x30, 0x44 },
-+		{ 0x31, 0x75 }, // ??
-+		{ 0x21, 0x16 }, // 0x03,
-+	}
-+}, {
-+	{ /* input 1 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0xD8 },
-+		{ 0x21, 0x17 }, // 0x16,
-+		{ 0x22, 0x40 },
-+		{ 0x2C, 0x03 },
-+		{ 0x30, 0x44 },
-+		{ 0x31, 0x75 }, // ??
-+		{ 0x21, 0x16 }, // 0x03,
-+	}
-+}, {
-+	{ /* input 2 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0xBA },
-+		{ 0x21, 0x07 }, // 0x05,
-+		{ 0x22, 0x91 },
-+		{ 0x2C, 0x03 },
-+		{ 0x30, 0x60 },
-+		{ 0x31, 0xB5 }, // ??
-+		{ 0x21, 0x05 }, // 0x03,
-+	}
-+}, {
-+	{ /* input 3 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0xB8 },
-+		{ 0x21, 0x07 }, // 0x05,
-+		{ 0x22, 0x91 },
-+		{ 0x2C, 0x03 },
-+		{ 0x30, 0x60 },
-+		{ 0x31, 0xB5 }, // ??
-+		{ 0x21, 0x05 }, // 0x03,
-+	}
-+}, {
-+	{ /* input 4 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0x7C },
-+		{ 0x21, 0x07 }, // 0x03
-+		{ 0x22, 0xD2 },
-+		{ 0x2C, 0x83 },
-+		{ 0x30, 0x60 },
-+		{ 0x31, 0xB5 }, // ??
-+		{ 0x21, 0x03 },
-+	} 
-+}, {
-+	{ /* input 5 */
-+		{ 0x06, 0x00 },
-+		{ 0x20, 0x78 },
-+		{ 0x21, 0x07 }, // 0x03,
-+		{ 0x22, 0xD2 },
-+		{ 0x2C, 0x83 },
-+		{ 0x30, 0x60 },
-+		{ 0x31, 0xB5 }, // ?
-+		{ 0x21, 0x03 },
-+	}
-+}, {
-+	{ /* input 6 */
-+		{ 0x06, 0x80 },
-+		{ 0x20, 0x59 },
-+		{ 0x21, 0x17 },
-+		{ 0x22, 0x42 },
-+		{ 0x2C, 0xA3 },
-+		{ 0x30, 0x44 },
-+		{ 0x31, 0x75 },
-+		{ 0x21, 0x12 },
-+	}
-+}, {
-+	{ /* input 7 */
-+		{ 0x06, 0x80 },
-+		{ 0x20, 0x9A },
-+		{ 0x21, 0x17 },
-+		{ 0x22, 0xB1 },
-+		{ 0x2C, 0x13 },
-+		{ 0x30, 0x60 },
-+		{ 0x31, 0xB5 },
-+		{ 0x21, 0x14 },
-+	}
-+}, {
-+	{ /* input 8 */
-+		{ 0x06, 0x80 },
-+		{ 0x20, 0x3C },
-+		{ 0x21, 0x27 },
-+		{ 0x22, 0xC1 },
-+		{ 0x2C, 0x23 },
-+		{ 0x30, 0x44 },
-+		{ 0x31, 0x75 },
-+		{ 0x21, 0x21 },
-+	}
-+}	
-+};
-+
-+#endif
---- linux-2.6.0-test1/drivers/media/video/Kconfig	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/media/video/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -257,5 +257,30 @@ config VIDEO_DPC
- 	  whenever you want). If you want to compile it as a module, say M
- 	  here and read <file:Documentation/modules.txt>.
- 
-+config VIDEO_HEXIUM_ORION
-+	tristate "Hexium HV-PCI6 and Orion frame grabber"
-+	depends on VIDEO_DEV && PCI
-+	---help---
-+	  This is a video4linux driver for the Hexium HV-PCI6 and
-+	  Orion frame grabber cards by Hexium.
-+	  
-+	  This driver is available as a module called hexium_orion
-+	  ( = code which can be inserted in and removed from the
-+	  running kernel whenever you want). If you want to compile
-+	  it as a module, say M here and read <file:Documentation/modules.txt>.
-+
-+config VIDEO_HEXIUM_GEMINI
-+	tristate "Hexium Gemini frame grabber"
-+	depends on VIDEO_DEV && PCI
-+	---help---
-+	  This is a video4linux driver for the Hexium Gemini frame
-+	  grabber card by Hexium. Please note that the Gemini Dual
-+	  card is *not* fully supported.
-+	  
-+	  This driver is available as a module called hexium_gemini
-+	  ( = code which can be inserted in and removed from the
-+	  running kernel whenever you want). If you want to compile
-+	  it as a module, say M here and read <file:Documentation/modules.txt>.
-+
- endmenu
- 
---- linux-2.6.0-test1/drivers/media/video/Makefile	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/media/video/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -31,6 +31,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb
- obj-$(CONFIG_VIDEO_MEYE) += meye.o
- obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
- obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
-+obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
-+obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
- obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
- obj-$(CONFIG_TUNER_3036) += tuner-3036.o
- 
---- linux-2.6.0-test1/drivers/media/video/mxb.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/media/video/mxb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -81,7 +81,7 @@ MODULE_PARM_DESC(debug, "debug verbosity
- enum { TUNER, AUX1, AUX3, AUX3_YC };
- 
- static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
--	{ TUNER,	"Tuner",		V4L2_INPUT_TYPE_TUNER,	1, 1, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 
-+	{ TUNER,	"Tuner",		V4L2_INPUT_TYPE_TUNER,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 
- 	{ AUX1,		"AUX1",			V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- 	{ AUX3,		"AUX3 Composite",	V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
- 	{ AUX3_YC,	"AUX3 S-Video",		V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
-@@ -101,8 +101,8 @@ static struct {
- 
- /* this array holds the information of the audio source (mxb_audios),
-    which has to be switched corresponding to the video source (mxb_channels) */
--static int video_audio_connect[MXB_AUDIOS] =
--	{ 0, 1, 2, 3, 3 };
-+static int video_audio_connect[MXB_INPUTS] =
-+	{ 0, 1, 3, 3 };
- 
- /* these are the necessary input-output-pins for bringing one audio source
- (see above) to the CD-output */
-@@ -173,8 +173,7 @@ struct mxb
- 	int	cur_mute;	/* current mute status */
- };
- 
--static
--struct saa7146_extension extension;
-+static struct saa7146_extension extension;
- 
- static int mxb_vbi_bypass(struct saa7146_dev* dev)
- {
-@@ -431,10 +430,11 @@ static int mxb_init_done(struct saa7146_
- 		   polling method ... */
- 		extension.flags &= ~SAA7146_USE_I2C_IRQ;
- 		for(i = 1;;i++) {
--			msg.len = mxb_saa7740_init[i].length;		
--			if (msg.len == -1U) {
-+			if( -1 == mxb_saa7740_init[i].length ) {
- 				break;
- 			}
-+
-+			msg.len = mxb_saa7740_init[i].length;		
- 			msg.buf = &mxb_saa7740_init[i].data[0];
- 			if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
- 				DEB_D(("failed to initialize 'sound arena module'.\n"));
-@@ -472,6 +472,8 @@ void mxb_irq_bh(struct saa7146_dev* dev,
- }
- */
- 
-+static struct saa7146_ext_vv vv_data;
-+
- /* this function only gets called when the probing was successful */
- static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
- {
-@@ -482,7 +484,7 @@ static int mxb_attach(struct saa7146_dev
- 	/* checking for i2c-devices can be omitted here, because we
- 	   already did this in "mxb_vl42_probe" */
- 
--	saa7146_vv_init(dev);
-+	saa7146_vv_init(dev,&vv_data);
- 	if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- 		ERR(("cannot register capture v4l2 device. skipping.\n"));
- 		return -1;
-@@ -566,8 +568,9 @@ static int saa7111_set_gpio(struct saa71
- 	return 0;
- }
- 
--static int mxb_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
-+static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
- {
-+	struct saa7146_dev *dev = fh->dev;
- 	struct mxb* mxb = (struct mxb*)dev->ext_priv;
- 	struct saa7146_vv *vv = dev->vv_data; 
- 	
-@@ -1002,20 +1005,35 @@ static int std_callback(struct saa7146_d
- }
- 
- static struct saa7146_standard standard[] = {
--	{ "PAL-BG",	V4L2_STD_PAL_BG,	SAA7146_PAL_VALUES },
--	{ "PAL-I",	V4L2_STD_PAL_I,		SAA7146_PAL_VALUES },
--	{ "NTSC",	V4L2_STD_NTSC,		SAA7146_NTSC_VALUES },
--	{ "SECAM", 	V4L2_STD_SECAM,		SAA7146_SECAM_VALUES },
-+	{
-+		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
-+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}, {
-+		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
-+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}, {
-+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-+		.v_offset	= 0x16,	.v_field 	= 240,	.v_calc		= 480,
-+		.h_offset	= 0x06,	.h_pixels 	= 708,	.h_calc		= 708+1,
-+		.v_max_out	= 480,	.h_max_out	= 640,
-+	}, {
-+		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-+		.v_offset	= 0x14,	.v_field 	= 288,	.v_calc		= 576,
-+		.h_offset	= 0x14,	.h_pixels 	= 720,	.h_calc		= 720+1,
-+		.v_max_out	= 576,	.h_max_out	= 768,
-+	}
- };
- 
--static
--struct saa7146_pci_extension_data mxb = {
-+static struct saa7146_pci_extension_data mxb = {
-         .ext_priv = "Multimedia eXtension Board",
-         .ext = &extension,
- };
- 
--static
--struct pci_device_id pci_tbl[] = {
-+static struct pci_device_id pci_tbl[] = {
- 	{
- 		.vendor    = PCI_VENDOR_ID_PHILIPS,
- 		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
-@@ -1029,8 +1047,7 @@ struct pci_device_id pci_tbl[] = {
- 
- MODULE_DEVICE_TABLE(pci, pci_tbl);
- 
--static
--struct saa7146_ext_vv vv_data = {
-+static struct saa7146_ext_vv vv_data = {
- 	.inputs		= MXB_INPUTS,
- 	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
- 	.stds		= &standard[0],
-@@ -1040,14 +1057,12 @@ struct saa7146_ext_vv vv_data = {
- 	.ioctl		= mxb_ioctl,
- };
- 
--static
--struct saa7146_extension extension = {
-+static struct saa7146_extension extension = {
- 	.name		= MXB_IDENTIFIER,
- 	.flags		= SAA7146_USE_I2C_IRQ,
- 	
- 	.pci_tbl	= &pci_tbl[0],
- 	.module		= THIS_MODULE,
--	.ext_vv_data	= &vv_data,
- 
- 	.probe		= mxb_probe,
- 	.attach		= mxb_attach,
---- linux-2.6.0-test1/drivers/media/video/pms.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/media/video/pms.c	2003-07-19 17:03:50.000000000 -0700
-@@ -12,6 +12,10 @@
-  *	Most of this code is directly derived from his userspace driver.
-  *	His driver works so send any reports to alan@redhat.com unless the
-  *	userspace driver also doesn't work for you...
-+ *      
-+ *      Changes:
-+ *      08/07/2003        Daniele Bellucci <bellucda@tiscali.it>
-+ *                        - pms_capture: report back -EFAULT 
-  */
- 
- #include <linux/module.h>
-@@ -659,7 +663,8 @@ static int pms_capture(struct pms_device
- 			if(dt+len>count)
- 				dt=count-len;
- 			cnt += dev->height;
--			copy_to_user(buf, tmp+32, dt);
-+			if (copy_to_user(buf, tmp+32, dt))
-+				return -EFAULT;
- 			buf += dt;    
- 			len += dt;
- 		}
---- linux-2.6.0-test1/drivers/message/fusion/mptctl.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/message/fusion/mptctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -88,7 +88,6 @@
- 
- #include <linux/kdev_t.h>	/* needed for access to Scsi_Host struct */
- #include <linux/blkdev.h>
--#include <linux/blk.h>          /* for io_request_lock (spinlock) decl */
- #include "../../scsi/scsi.h"
- #include "../../scsi/hosts.h"
- 
---- linux-2.6.0-test1/drivers/message/fusion/mptscsih.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/message/fusion/mptscsih.c	2003-07-19 17:03:50.000000000 -0700
-@@ -72,7 +72,6 @@
- #include <linux/errno.h>
- #include <linux/kdev_t.h>
- #include <linux/blkdev.h>
--#include <linux/blk.h>		/* for io_request_lock (spinlock) decl */
- #include <linux/delay.h>	/* for mdelay */
- #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
- #include <linux/reboot.h>	/* notifier code */
---- linux-2.6.0-test1/drivers/message/i2o/i2o_block.c	2003-06-14 12:18:28.000000000 -0700
-+++ 25/drivers/message/i2o/i2o_block.c	2003-07-19 17:03:50.000000000 -0700
-@@ -87,8 +87,6 @@
- 
- #define MAJOR_NR I2O_MAJOR
- 
--#include <linux/blk.h>
--
- #define MAX_I2OB	16
- 
- #define MAX_I2OB_DEPTH	8
---- linux-2.6.0-test1/drivers/message/i2o/i2o_scsi.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/message/i2o/i2o_scsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -54,7 +54,7 @@
- #include <asm/system.h>
- #include <asm/io.h>
- #include <asm/atomic.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/i2o.h>
- #include "../../scsi/scsi.h"
- #include "../../scsi/hosts.h"
---- linux-2.6.0-test1/drivers/mtd/devices/blkmtd.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/drivers/mtd/devices/blkmtd.c	2003-07-19 17:07:03.000000000 -0700
-@@ -1189,6 +1189,7 @@ static int __init init_blkmtd(void)
-   INIT_LIST_HEAD(&mtd_rawdevice->as.locked_pages);
-   mtd_rawdevice->as.host = NULL;
-   init_MUTEX(&(mtd_rawdevice->as.i_shared_sem));
-+  atomic_set(&(mtd_rawdevice->as.truncate_count), 0);
- 
-   mtd_rawdevice->as.a_ops = &blkmtd_aops;
-   INIT_LIST_HEAD(&mtd_rawdevice->as.i_mmap);
---- linux-2.6.0-test1/drivers/mtd/mtd_blkdevs.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/mtd/mtd_blkdevs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -15,7 +15,6 @@
- #include <linux/mtd/blktrans.h>
- #include <linux/mtd/mtd.h>
- #include <linux/blkdev.h>
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- #include <linux/spinlock.h>
- #include <linux/hdreg.h>
---- linux-2.6.0-test1/drivers/net/3c59x.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/net/3c59x.c	2003-07-19 17:06:13.000000000 -0700
-@@ -291,8 +291,6 @@ MODULE_PARM(global_full_duplex, "i");
- MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
- MODULE_PARM(hw_checksums, "1-" __MODULE_STRING(8) "i");
- MODULE_PARM(flow_ctrl, "1-" __MODULE_STRING(8) "i");
--MODULE_PARM(global_enable_wol, "i");
--MODULE_PARM(enable_wol, "1-" __MODULE_STRING(8) "i");
- MODULE_PARM(rx_copybreak, "i");
- MODULE_PARM(max_interrupt_work, "i");
- MODULE_PARM(compaq_ioaddr, "i");
-@@ -306,8 +304,6 @@ MODULE_PARM_DESC(full_duplex, "3c59x ful
- MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
- MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
- MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
--MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
--MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
- MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
- MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
- MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
-@@ -484,10 +480,8 @@ static struct vortex_chip_info {
- } vortex_info_tbl[] __devinitdata = {
- 	{"3c590 Vortex 10Mbps",
- 	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
--#define EISA_3C592_OFFSET 1		/* Offset of this entry for vortex_eisa_init */
- 	{"3c592 EISA 10Mbps Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
- 	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
--#define EISA_3C597_OFFSET 2		/* Offset of this entry for vortex_eisa_init */
- 	{"3c597 EISA Fast Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
- 	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
- 	{"3c595 Vortex 100baseTx",
-@@ -819,7 +813,6 @@ struct vortex_private {
- 		flow_ctrl:1,					/* Use 802.3x flow control (PAUSE only) */
- 		partner_flow_ctrl:1,			/* Partner supports flow control */
- 		has_nway:1,
--		enable_wol:1,					/* Wake-on-LAN is enabled */
- 		pm_state_valid:1,				/* power_state[] has sane contents */
- 		open:1,
- 		medialock:1,
-@@ -915,10 +908,8 @@ static int options[MAX_UNITS] = { -1, -1
- static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
- static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
- static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
--static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
- static int global_options = -1;
- static int global_full_duplex = -1;
--static int global_enable_wol = -1;
- 
- /* #define dev_alloc_skb dev_alloc_skb_debug */
- 
-@@ -960,8 +951,8 @@ static int vortex_resume (struct pci_dev
- 
- #ifdef CONFIG_EISA
- static struct eisa_device_id vortex_eisa_ids[] = {
--	{ "TCM5920", EISA_3C592_OFFSET },
--	{ "TCM5970", EISA_3C597_OFFSET },
-+	{ "TCM5920", CH_3C592 },
-+	{ "TCM5970", CH_3C597 },
- 	{ "" }
- };
- 
-@@ -1138,8 +1129,6 @@ static int __devinit vortex_probe1(struc
- 			vortex_debug = 7;
- 		if (option & 0x4000)
- 			vortex_debug = 2;
--		if (option & 0x0400)
--			vp->enable_wol = 1;
- 	}
- 
- 	print_info = (vortex_debug > 1);
-@@ -1227,16 +1216,12 @@ static int __devinit vortex_probe1(struc
- 
- 	if (global_full_duplex > 0)
- 		vp->full_duplex = 1;
--	if (global_enable_wol > 0)
--		vp->enable_wol = 1;
- 
- 	if (card_idx < MAX_UNITS) {
- 		if (full_duplex[card_idx] > 0)
- 			vp->full_duplex = 1;
- 		if (flow_ctrl[card_idx] > 0)
- 			vp->flow_ctrl = 1;
--		if (enable_wol[card_idx] > 0)
--			vp->enable_wol = 1;
- 	}
- 
- 	vp->force_fd = vp->full_duplex;
-@@ -1379,7 +1364,7 @@ static int __devinit vortex_probe1(struc
- 	} else
- 		dev->if_port = vp->default_media;
- 
--	if ((vp->available_media & 0x4b) || (vci->drv_flags & HAS_NWAY) ||
-+	if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) ||
- 		dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
- 		int phy, phy_idx = 0;
- 		EL3WINDOW(4);
-@@ -1463,7 +1448,7 @@ static int __devinit vortex_probe1(struc
- 	dev->set_multicast_list = set_rx_mode;
- 	dev->tx_timeout = vortex_tx_timeout;
- 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
--	if (pdev && vp->enable_wol) {
-+	if (pdev) {
- 		vp->pm_state_valid = 1;
-  		pci_save_state(VORTEX_PCI(vp), vp->power_state);
-  		acpi_set_WOL(dev);
-@@ -1520,7 +1505,7 @@ vortex_up(struct net_device *dev)
- 	unsigned int config;
- 	int i;
- 
--	if (VORTEX_PCI(vp) && vp->enable_wol) {
-+	if (VORTEX_PCI(vp)) {
- 		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
- 		pci_restore_state(VORTEX_PCI(vp), vp->power_state);
- 	}
-@@ -2669,7 +2654,7 @@ vortex_down(struct net_device *dev)
- 	if (vp->full_bus_master_tx)
- 		outl(0, ioaddr + DownListPtr);
- 
--	if (VORTEX_PCI(vp) && vp->enable_wol) {
-+	if (VORTEX_PCI(vp)) {
- 		pci_save_state(VORTEX_PCI(vp), vp->power_state);
- 		acpi_set_WOL(dev);
- 	}
-@@ -3059,7 +3044,7 @@ static void __devexit vortex_remove_one 
- 	/* Should really use issue_and_wait() here */
- 	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
- 
--	if (VORTEX_PCI(vp) && vp->enable_wol) {
-+	if (VORTEX_PCI(vp)) {
- 		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
- 		if (vp->pm_state_valid)
- 			pci_restore_state(VORTEX_PCI(vp), vp->power_state);
---- linux-2.6.0-test1/drivers/net/eql.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/drivers/net/eql.c	2003-07-19 17:03:50.000000000 -0700
-@@ -162,22 +162,12 @@ static void eql_timer(unsigned long para
- static char version[] __initdata = 
- 	"Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
- 
--static int __init eql_init(struct net_device *dev)
-+static void __init eql_setup(struct net_device *dev)
- {
--	static unsigned int version_printed;
--	equalizer_t *eql;
-+	equalizer_t *eql = dev->priv;
- 
- 	SET_MODULE_OWNER(dev);
- 
--	if (version_printed++ == 0)
--		printk(version);
--
--	dev->priv = kmalloc(sizeof (equalizer_t), GFP_KERNEL);
--	if (dev->priv == NULL)
--		return -ENOMEM;
--	memset(dev->priv, 0, sizeof (equalizer_t));
--	eql = dev->priv;
--
- 	init_timer(&eql->timer);
- 	eql->timer.data     	= (unsigned long) dev->priv;
- 	eql->timer.expires  	= jiffies + EQL_DEFAULT_RESCHED_IVAL;
-@@ -203,8 +193,6 @@ static int __init eql_init(struct net_de
- 
- 	dev->type       	= ARPHRD_SLIP;
- 	dev->tx_queue_len 	= 5;		/* Hands them off fast */
--
--	return 0;
- }
- 
- static int eql_open(struct net_device *dev)
-@@ -598,23 +586,28 @@ static int eql_s_master_cfg(struct net_d
- 	return -EINVAL;
- }
- 
--static struct net_device dev_eql;
-+static struct net_device *dev_eql;
- 
- static int __init eql_init_module(void)
- {
--	strcpy(dev_eql.name, "eql");
--	dev_eql.init = eql_init;
--	if (register_netdev(&dev_eql) != 0) {
--		printk("eql: register_netdev() returned non-zero.\n");
--		return -EIO;
--	}
--	return 0;
-+	int err;
-+
-+	printk(version);
-+
-+	dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup);
-+	if (!dev_eql)
-+		return -ENOMEM;
-+
-+	err = register_netdev(dev_eql);
-+	if (err) 
-+		kfree(dev_eql);
-+	return err;
- }
- 
- static void __exit eql_cleanup_module(void)
- {
--	kfree(dev_eql.priv);
--	unregister_netdev(&dev_eql);
-+	unregister_netdev(dev_eql);
-+	kfree(dev_eql);
- }
- 
- module_init(eql_init_module);
---- linux-2.6.0-test1/drivers/net/fc/iph5526.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/drivers/net/fc/iph5526.c	2003-07-19 17:03:50.000000000 -0700
-@@ -48,7 +48,6 @@ static const char *version =
- #include <linux/timer.h>
- #include <linux/spinlock.h>
- #include <linux/netdevice.h>
--#include <linux/blk.h>
- #include <linux/fcdevice.h> /* had the declarations for init_fcdev among
- 			       others + includes if_fcdevice.h */
- 
---- linux-2.6.0-test1/drivers/net/irda/vlsi_ir.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/net/irda/vlsi_ir.c	2003-07-19 17:03:50.000000000 -0700
-@@ -474,10 +474,8 @@ static ssize_t vlsi_proc_read(struct fil
- 	if (pos + nbytes > size)
- 		nbytes = size - pos;
- 
--	if (!access_ok(VERIFY_WRITE, buf, nbytes))
--		return -EINVAL;
--
--	copy_to_user(buf, procdata->data + pos, nbytes);
-+	if (copy_to_user(buf, procdata->data + pos, nbytes))
-+		return -EFAULT;
- 
- 	*ppos += nbytes;
- 
---- linux-2.6.0-test1/drivers/net/Kconfig	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/net/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -1153,7 +1153,7 @@ config ZNET
- 
- config SEEQ8005
- 	tristate "SEEQ8005 support (EXPERIMENTAL)"
--	depends on NET_ISA && OBSOLETE && EXPERIMENTAL
-+	depends on NET_ISA && EXPERIMENTAL
- 	help
- 	  This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
- 	  is for you, read the Ethernet-HOWTO, available from
---- linux-2.6.0-test1/drivers/net/ni65.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/net/ni65.c	2003-07-19 17:03:50.000000000 -0700
-@@ -245,6 +245,7 @@ struct priv
- 	int cmdr_addr;
- 	int cardno;
- 	int features;
-+	spinlock_t ring_lock;
- };
- 
- static int  ni65_probe1(struct net_device *dev,int);
-@@ -299,7 +300,7 @@ static int ni65_open(struct net_device *
- 	int irqval = request_irq(dev->irq, &ni65_interrupt,0,
-                         cards[p->cardno].cardname,dev);
- 	if (irqval) {
--		printk ("%s: unable to get IRQ %d (irqval=%d).\n",
-+		printk(KERN_ERR "%s: unable to get IRQ %d (irqval=%d).\n",
- 		          dev->name,dev->irq, irqval);
- 		return -EAGAIN;
- 	}
-@@ -409,12 +410,14 @@ static int __init ni65_probe1(struct net
- 	p = (struct priv *) dev->priv;
- 	p->cmdr_addr = ioaddr + cards[i].cmd_offset;
- 	p->cardno = i;
-+	spin_lock_init(&p->ring_lock);
- 
--	printk("%s: %s found at %#3x, ", dev->name, cards[p->cardno].cardname , ioaddr);
-+	printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cards[p->cardno].cardname , ioaddr);
- 
- 	outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
- 	if( (j=readreg(CSR0)) != 0x4) {
--		 printk(KERN_ERR "can't RESET card: %04x\n",j);
-+		 printk("failed.\n");
-+		 printk(KERN_ERR "%s: Can't RESET card: %04x\n", dev->name, j);
- 		 ni65_free_buffer(p);
- 		 release_region(ioaddr, cards[p->cardno].total_size);
- 		 return -EAGAIN;
-@@ -467,7 +470,8 @@ static int __init ni65_probe1(struct net
- 					break;
- 			}
- 			if(i == 5) {
--				printk("Can't detect DMA channel!\n");
-+				printk("failed.\n");
-+				printk(KERN_ERR "%s: Can't detect DMA channel!\n", dev->name);
- 				ni65_free_buffer(p);
- 				release_region(ioaddr, cards[p->cardno].total_size);
- 				return -EAGAIN;
-@@ -480,13 +484,13 @@ static int __init ni65_probe1(struct net
- 
- 		if(dev->irq < 2)
- 		{
--			unsigned long irq_mask, delay;
-+			unsigned long irq_mask;
- 
- 			ni65_init_lance(p,dev->dev_addr,0,0);
- 			irq_mask = probe_irq_on();
- 			writereg(CSR0_INIT|CSR0_INEA,CSR0); /* trigger interrupt */
--			delay = jiffies + HZ/50;
--			while (time_before(jiffies, delay)) ;
-+			set_current_state(TASK_UNINTERRUPTIBLE);
-+			schedule_timeout(HZ/50);
- 			dev->irq = probe_irq_off(irq_mask);
- 			if(!dev->irq)
- 			{
-@@ -503,7 +507,7 @@ static int __init ni65_probe1(struct net
- 
- 	if(request_dma(dev->dma, cards[p->cardno].cardname ) != 0)
- 	{
--		printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
-+		printk(KERN_ERR "%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
- 		ni65_free_buffer(p);
- 		release_region(ioaddr, cards[p->cardno].total_size);
- 		return -EAGAIN;
-@@ -570,7 +574,7 @@ static void *ni65_alloc_mem(struct net_d
- 	if(type) {
- 		ret = skb = alloc_skb(2+16+size,GFP_KERNEL|GFP_DMA);
- 		if(!skb) {
--			printk("%s: unable to allocate %s memory.\n",dev->name,what);
-+			printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what);
- 			return NULL;
- 		}
- 		skb->dev = dev;
-@@ -581,12 +585,12 @@ static void *ni65_alloc_mem(struct net_d
- 	else {
- 		ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA);
- 		if(!ret) {
--			printk("%s: unable to allocate %s memory.\n",dev->name,what);
-+			printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what);
- 			return NULL;
- 		}
- 	}
- 	if( (u32) virt_to_phys(ptr+size) > 0x1000000) {
--		printk("%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what);
-+		printk(KERN_WARNING "%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what);
- 		if(type)
- 			kfree_skb(skb);
- 		else
-@@ -692,7 +696,7 @@ static void ni65_stop_start(struct net_d
- 	writedatareg(CSR0_STOP);
- 
- 	if(debuglevel > 1)
--		printk("ni65_stop_start\n");
-+		printk(KERN_DEBUG "ni65_stop_start\n");
- 
- 	if(p->features & INIT_RING_BEFORE_START) {
- 		int i;
-@@ -846,6 +850,8 @@ static irqreturn_t ni65_interrupt(int ir
- 
- 	p = (struct priv *) dev->priv;
- 
-+	spin_lock(&p->ring_lock);
-+	
- 	while(--bcnt) {
- 		csr0 = inw(PORT+L_DATAREG);
- 
-@@ -867,7 +873,7 @@ static irqreturn_t ni65_interrupt(int ir
- 		{
- 			struct priv *p = (struct priv *) dev->priv;
- 			if(debuglevel > 1)
--				printk("%s: general error: %04x.\n",dev->name,csr0);
-+				printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
- 			if(csr0 & CSR0_BABL)
- 				p->stats.tx_errors++;
- 			if(csr0 & CSR0_MISS) {
-@@ -879,7 +885,7 @@ static irqreturn_t ni65_interrupt(int ir
- 			}
- 			if(csr0 & CSR0_MERR) {
- 				if(debuglevel > 1)
--					printk("%s: Ooops .. memory error: %04x.\n",dev->name,csr0);
-+					printk(KERN_ERR "%s: Ooops .. memory error: %04x.\n",dev->name,csr0);
- 				ni65_stop_start(dev,p);
- 			}
- 		}
-@@ -932,12 +938,13 @@ static irqreturn_t ni65_interrupt(int ir
- #endif
- 
- 	if( (csr0 & (CSR0_RXON | CSR0_TXON)) != (CSR0_RXON | CSR0_TXON) ) {
--		printk("%s: RX or TX was offline -> restart\n",dev->name);
-+		printk(KERN_DEBUG "%s: RX or TX was offline -> restart\n",dev->name);
- 		ni65_stop_start(dev,p);
- 	}
- 	else
- 		writedatareg(CSR0_INEA);
- 
-+	spin_unlock(&p->ring_lock);
- 	return IRQ_HANDLED;
- }
- 
-@@ -1147,9 +1154,7 @@ static int ni65_send_packet(struct sk_bu
- 				memset((char *)p->tmdbounce[p->tmdbouncenum]+skb->len, 0, len-skb->len);
- 			dev_kfree_skb (skb);
- 
--			save_flags(flags);
--			cli();
--
-+			spin_lock_irqsave(&p->ring_lock, flags);
- 			tmdp = p->tmdhead + p->tmdnum;
- 			tmdp->u.buffer = (u32) isa_virt_to_bus(p->tmdbounce[p->tmdbouncenum]);
- 			p->tmdbouncenum = (p->tmdbouncenum + 1) & (TMDNUM - 1);
-@@ -1157,8 +1162,7 @@ static int ni65_send_packet(struct sk_bu
- #ifdef XMT_VIA_SKB
- 		}
- 		else {
--			save_flags(flags);
--			cli();
-+			spin_lock_irqsave(&p->ring_lock, flags);
- 
- 			tmdp = p->tmdhead + p->tmdnum;
- 			tmdp->u.buffer = (u32) isa_virt_to_bus(skb->data);
-@@ -1178,8 +1182,8 @@ static int ni65_send_packet(struct sk_bu
- 			
- 		p->lock = 0;
- 		dev->trans_start = jiffies;
--
--		restore_flags(flags);
-+		
-+		spin_unlock_irqrestore(&p->ring_lock, flags);
- 	}
- 
- 	return 0;
-@@ -1238,10 +1242,8 @@ void cleanup_module(void)
- {
- 	struct priv *p;
- 	p = (struct priv *) dev_ni65.priv;
--	if(!p) {
--		printk("Ooops .. no private struct\n");
--		return;
--	}
-+	if(!p)
-+		BUG();
- 	disable_dma(dev_ni65.dma);
- 	free_dma(dev_ni65.dma);
- 	unregister_netdev(&dev_ni65);
-@@ -1250,6 +1252,7 @@ void cleanup_module(void)
- 	dev_ni65.priv = NULL;
- }
- #endif /* MODULE */
-+
- MODULE_LICENSE("GPL");
- 
- /*
---- linux-2.6.0-test1/drivers/net/ni65.h	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/net/ni65.h	2003-07-19 17:03:50.000000000 -0700
-@@ -20,32 +20,32 @@
- #define CSR0_BABL	0x4000	/* Babble transmitter timeout error (RC) */
- #define CSR0_CERR	0x2000	/* Collision Error (RC) */
- #define CSR0_MISS	0x1000	/* Missed packet (RC) */
--#define CSR0_MERR	0x0800	/* Memory Error (RC) */ 
-+#define CSR0_MERR	0x0800	/* Memory Error (RC) */
- #define CSR0_RINT	0x0400	/* Receiver Interrupt (RC) */
--#define CSR0_TINT       0x0200	/* Transmit Interrupt (RC) */ 
-+#define CSR0_TINT       0x0200	/* Transmit Interrupt (RC) */
- #define CSR0_IDON	0x0100	/* Initialization Done (RC) */
- #define CSR0_INTR	0x0080	/* Interrupt Flag (R) */
- #define CSR0_INEA	0x0040	/* Interrupt Enable (RW) */
- #define CSR0_RXON	0x0020	/* Receiver on (R) */
--#define CSR0_TXON	0x0010  /* Transmitter on (R) */
-+#define CSR0_TXON	0x0010	/* Transmitter on (R) */
- #define CSR0_TDMD	0x0008	/* Transmit Demand (RS) */
--#define CSR0_STOP	0x0004 	/* Stop (RS) */
-+#define CSR0_STOP	0x0004	/* Stop (RS) */
- #define CSR0_STRT	0x0002	/* Start (RS) */
- #define CSR0_INIT	0x0001	/* Initialize (RS) */
- 
--#define CSR0_CLRALL    0x7f00  /* mask for all clearable bits */
-+#define CSR0_CLRALL    0x7f00	/* mask for all clearable bits */
- /*
-  *	Initialization Block  Mode operation Bit Definitions.
-  */
- 
- #define M_PROM		0x8000	/* Promiscuous Mode */
--#define M_INTL		0x0040  /* Internal Loopback */
--#define M_DRTY		0x0020  /* Disable Retry */ 
-+#define M_INTL		0x0040	/* Internal Loopback */
-+#define M_DRTY		0x0020	/* Disable Retry */
- #define M_COLL		0x0010	/* Force Collision */
- #define M_DTCR		0x0008	/* Disable Transmit CRC) */
- #define M_LOOP		0x0004	/* Loopback */
--#define M_DTX		0x0002	/* Disable the Transmitter */ 
--#define M_DRX		0x0001  /* Disable the Receiver */
-+#define M_DTX		0x0002	/* Disable the Transmitter */
-+#define M_DRX		0x0001	/* Disable the Receiver */
- 
- 
- /*
-@@ -56,7 +56,7 @@
- #define RCV_ERR		0x40	/* Error Summary */
- #define RCV_FRAM	0x20	/* Framing Error */
- #define RCV_OFLO	0x10	/* Overflow Error */
--#define RCV_CRC		0x08	/* CRC Error */ 
-+#define RCV_CRC		0x08	/* CRC Error */
- #define RCV_BUF_ERR	0x04	/* Buffer Error */
- #define RCV_START	0x02	/* Start of Packet */
- #define RCV_END		0x01	/* End of Packet */
-@@ -67,7 +67,7 @@
-  */
- 
- #define XMIT_OWN	0x80	/* owner bit 0 = host, 1 = lance */
--#define XMIT_ERR	0x40    /* Error Summary */
-+#define XMIT_ERR	0x40	/* Error Summary */
- #define XMIT_RETRY	0x10	/* more the 1 retry needed to Xmit */
- #define XMIT_1_RETRY	0x08	/* one retry needed to Xmit */
- #define XMIT_DEF	0x04	/* Deferred */
-@@ -78,53 +78,44 @@
-  * transmit status (2) (valid if XMIT_ERR == 1)
-  */
- 
--#define XMIT_TDRMASK    0x03ff  /* time-domain-reflectometer-value */
--#define XMIT_RTRY 	0x0400  /* Failed after 16 retransmissions  */
--#define XMIT_LCAR 	0x0800  /* Loss of Carrier */
--#define XMIT_LCOL 	0x1000  /* Late collision */
--#define XMIT_RESERV 	0x2000  /* Reserved */
--#define XMIT_UFLO 	0x4000  /* Underflow (late memory) */
--#define XMIT_BUFF 	0x8000  /* Buffering error (no ENP) */
--
--struct init_block 
--{
--  unsigned short mode;
--  unsigned char eaddr[6];
--  unsigned char filter[8];
--  /* bit 29-31: number of rmd's (power of 2) */
--  u32 rrp;   /* receive ring pointer (align 8) */
--  /* bit 29-31: number of tmd's (power of 2) */
--  u32 trp;   /* transmit ring pointer (align 8) */
-+#define XMIT_TDRMASK    0x03ff	/* time-domain-reflectometer-value */
-+#define XMIT_RTRY 	0x0400	/* Failed after 16 retransmissions  */
-+#define XMIT_LCAR 	0x0800	/* Loss of Carrier */
-+#define XMIT_LCOL 	0x1000	/* Late collision */
-+#define XMIT_RESERV 	0x2000	/* Reserved */
-+#define XMIT_UFLO 	0x4000	/* Underflow (late memory) */
-+#define XMIT_BUFF 	0x8000	/* Buffering error (no ENP) */
-+
-+struct init_block {
-+	unsigned short mode;
-+	unsigned char eaddr[6];
-+	unsigned char filter[8];
-+	/* bit 29-31: number of rmd's (power of 2) */
-+	u32 rrp;		/* receive ring pointer (align 8) */
-+	/* bit 29-31: number of tmd's (power of 2) */
-+	u32 trp;		/* transmit ring pointer (align 8) */
- };
- 
--struct rmd /* Receive Message Descriptor */
--{ 
--  union
--  {
--    volatile u32 buffer;
--    struct 
--    {
--      volatile unsigned char dummy[3];
--      volatile unsigned char status; 
--    } s;
--  } u;
--  volatile short blen;
--  volatile unsigned short mlen;
-+struct rmd {			/* Receive Message Descriptor */
-+	union {
-+		volatile u32 buffer;
-+		struct {
-+			volatile unsigned char dummy[3];
-+			volatile unsigned char status;
-+		} s;
-+	} u;
-+	volatile short blen;
-+	volatile unsigned short mlen;
- };
- 
--struct tmd
--{
--  union 
--  {
--    volatile u32 buffer;
--    struct 
--    {
--      volatile unsigned char dummy[3];
--      volatile unsigned char status;
--    } s;
--  } u;
--  volatile unsigned short blen;
--  volatile unsigned short status2;
-+struct tmd {
-+	union {
-+		volatile u32 buffer;
-+		struct {
-+			volatile unsigned char dummy[3];
-+			volatile unsigned char status;
-+		} s;
-+	} u;
-+	volatile unsigned short blen;
-+	volatile unsigned short status2;
- };
--
--
---- linux-2.6.0-test1/drivers/net/pcmcia/Kconfig	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/net/pcmcia/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -113,7 +113,7 @@ config PCMCIA_XIRC2PS
- 	  If unsure, say N.
- 
- config PCMCIA_AXNET
--	tristate "broken NS8390-cards support"
-+	tristate "Asix AX88190 PCMCIA support"
- 	depends on NET_PCMCIA && PCMCIA
- 	---help---
- 	  Say Y here if you intend to attach an Asix AX88190-based PCMCIA
---- linux-2.6.0-test1/drivers/net/seeq8005.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/net/seeq8005.c	2003-07-19 17:03:50.000000000 -0700
-@@ -700,7 +700,8 @@ static void hardware_send_packet(struct 
-  * wait_for_buffer
-  *
-  * This routine waits for the SEEQ chip to assert that the FIFO is ready
-- * by checking for a window interrupt, and then clearing it
-+ * by checking for a window interrupt, and then clearing it. This has to
-+ * occur in the interrupt handler!
-  */
- inline void wait_for_buffer(struct net_device * dev)
- {
-@@ -710,7 +711,7 @@ inline void wait_for_buffer(struct net_d
- 	
- 	tmp = jiffies + HZ;
- 	while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
--		mb();
-+		cpu_relax();
- 		
- 	if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
- 		outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
---- linux-2.6.0-test1/drivers/net/wan/comx-hw-comx.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/net/wan/comx-hw-comx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -11,6 +11,7 @@
-  *
-  * Contributors:
-  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 0.86
-+ * Daniele Bellucci         <bellucda@tiscali.it>   - 0.87
-  *
-  * This program is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU General Public License
-@@ -42,9 +43,12 @@
-  *		- printk cleanups
-  * Version 0.86 (00/08/15):
-  * 		- resource release on failure at COMX_init
-+ *
-+ * Version 0.87 (03/07/09)
-+ *              - audit copy_from_user in comxhw_write_proc
-  */
- 
--#define VERSION "0.86"
-+#define VERSION "0.87"
- 
- #include <linux/module.h>
- #include <linux/version.h>
-@@ -1084,7 +1088,8 @@ static int comxhw_write_proc(struct file
- 		if (hw->firmware->data) {
- 			kfree(hw->firmware->data);
- 		}
--		copy_from_user(tmp + file->f_pos, buffer, count);
-+		if (copy_from_user(tmp + file->f_pos, buffer, count))
-+			return -EFAULT;
- 		hw->firmware->len = entry->size = file->f_pos + count;
- 		hw->firmware->data = tmp;
- 		file->f_pos += count;
---- linux-2.6.0-test1/drivers/net/wan/sdladrv.c	2003-06-14 12:18:03.000000000 -0700
-+++ 25/drivers/net/wan/sdladrv.c	2003-07-19 17:03:50.000000000 -0700
-@@ -160,10 +160,6 @@
- 
- /****** Function Prototypes *************************************************/
- 
--/* Module entry points. These are called by the OS and must be public. */
--int init_module (void);
--void cleanup_module (void);
--
- /* Hardware-specific functions */
- static int sdla_detect	(sdlahw_t* hw);
- static int sdla_autodpm	(sdlahw_t* hw);
-@@ -325,11 +321,7 @@ static int pci_slot_ar[MAX_S514_CARDS];
-  * Context:	process
-  */
- 
--#ifdef MODULE
--int init_module (void)
--#else
- int sdladrv_init(void)
--#endif
- {
- 	int i=0;
- 
-@@ -354,9 +346,12 @@ int sdladrv_init(void)
-  * Module 'remove' entry point.
-  * o release all remaining system resources
-  */
--void cleanup_module (void)
-+static void sdladrv_cleanup(void)
- {
- }
-+
-+module_init(sdladrv_init);
-+module_cleanup(sdladrv_cleanup);
- #endif
- 
- /******* Kernel APIs ********************************************************/
---- linux-2.6.0-test1/drivers/net/wan/sdlamain.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/net/wan/sdlamain.c	2003-07-19 17:03:50.000000000 -0700
-@@ -177,10 +177,6 @@ static void dbg_kfree(void * v, int line
- extern void disable_irq(unsigned int);
- extern void enable_irq(unsigned int);
-  
--/* Module entry points */
--int init_module (void);
--void cleanup_module (void);
--
- /* WAN link driver entry points */
- static int setup(struct wan_device* wandev, wandev_conf_t* conf);
- static int shutdown(struct wan_device* wandev);
-@@ -246,11 +242,7 @@ static int wanpipe_bh_critical=0;
-  * Context:	process
-  */
-  
--#ifdef MODULE
--int init_module (void)
--#else
- int wanpipe_init(void)
--#endif
- {
- 	int cnt, err = 0;
- 
-@@ -313,7 +305,7 @@ int wanpipe_init(void)
-  * o unregister all adapters from the WAN router
-  * o release all remaining system resources
-  */
--void cleanup_module (void)
-+static void wanpipe_cleanup(void)
- {
- 	int i;
- 
-@@ -329,6 +321,8 @@ void cleanup_module (void)
- 	printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n");
- }
- 
-+module_init(wanpipe_init);
-+module_exit(wanpipe_cleanup);
- #endif
- 
- /******* WAN Device Driver Entry Points *************************************/
---- linux-2.6.0-test1/drivers/net/wan/syncppp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/net/wan/syncppp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -161,7 +161,7 @@ static int debug;
-  * then put the packet into tx_queue, and call sppp_flush_xmit()
-  * after spinlock is released.
-  */
--static void sppp_flush_xmit()
-+static void sppp_flush_xmit(void)
- {
- 	struct sk_buff *skb;
- 	while ((skb = skb_dequeue(&tx_queue)) != NULL)
---- linux-2.6.0-test1/drivers/net/wireless/airo.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/net/wireless/airo.c	2003-07-19 17:06:31.000000000 -0700
-@@ -927,9 +927,8 @@ static int enable_MAC( struct airo_info 
- static void disable_MAC(struct airo_info *ai);
- static void enable_interrupts(struct airo_info*);
- static void disable_interrupts(struct airo_info*);
--static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
--static u16 sendcommand(struct airo_info *ai, Cmd *pCmd);
--static void completecommand(struct airo_info *ai, Resp *pRsp);
-+static int issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
-+static int issuecommand_nolock(struct airo_info*, Cmd *pCmd, Resp *pRsp);
- static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
- static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
- 			int whichbap);
-@@ -939,13 +938,14 @@ static int bap_write(struct airo_info*, 
- 		     int whichbap);
- static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
- static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len);
-+static int PC4500_readrid_nolock(struct airo_info*, u16 rid, void *pBuf, int len);
- static int PC4500_writerid(struct airo_info*, u16 rid, const void
- 			   *pBuf, int len);
- static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
- 			int len );
- static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
--static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
--static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
-+static int transmit_802_3_packet(struct airo_info*, u16 txFid, char *pPacket, int len);
-+static int transmit_802_11_packet(struct airo_info*, u16 txFid, char *pPacket, int len);
- 
- static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
- 			    *regs);
-@@ -981,12 +981,11 @@ struct airo_info {
- 	struct timer_list timer;
- 	struct proc_dir_entry *proc_entry;
- 	struct airo_info *next;
--        spinlock_t aux_lock;
-+	spinlock_t main_lock;
-         unsigned long flags;
- #define FLAG_PROMISC   IFF_PROMISC	/* 0x100 - include/linux/if.h */
- #define FLAG_RADIO_OFF 0x02		/* User disabling of MAC */
- #define FLAG_RADIO_DOWN 0x08		/* ifup/ifdown disabling of MAC */
--#define FLAG_LOCKED    2		/* 0x04 - use as a bit offset */
- #define FLAG_FLASHING  0x10
- #define FLAG_ADHOC        0x01 /* Needed by MIC */
- #define FLAG_MIC_CAPABLE  0x20
-@@ -997,14 +996,8 @@ struct airo_info {
- 			int whichbap);
- 	unsigned short *flash;
- 	tdsRssiEntry *rssi;
--	struct semaphore sem;
- 	struct task_struct *task;
- 	struct work_struct promisc_task;
--	struct {
--		struct sk_buff *skb;
--		int fid;
--		struct work_struct task;
--	} xmit, xmit11;
- 	struct net_device *wifidev;
- #ifdef WIRELESS_EXT
- 	struct iw_statistics	wstats;		// wireless stats
-@@ -1045,10 +1038,8 @@ static int readBSSListRid(struct airo_in
- 	if (first == 1) {
- 			memset(&cmd, 0, sizeof(cmd));
- 			cmd.cmd=CMD_LISTBSS;
--			if (down_interruptible(&ai->sem))
--				return -ERESTARTSYS;
- 			issuecommand(ai, &cmd, &rsp);
--			up(&ai->sem);
-+
- 			/* Let the command take effect */
- 			set_current_state (TASK_INTERRUPTIBLE);
- 			ai->task = current;
-@@ -1193,7 +1184,7 @@ static int readStatusRid(struct airo_inf
- 	statr->len = le16_to_cpu(statr->len);
- 	for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
- 
--	for(s = &statr->beaconPeriod; s <= &statr->_reserved[9]; s++)
-+	for(s = &statr->beaconPeriod; s <= &statr->_reserved1; s++)
- 		*s = le16_to_cpu(*s);
- 
- 	return rc;
-@@ -1306,44 +1297,15 @@ static void get_tx_error(struct airo_inf
- 	}
- }
- 
--static void airo_do_xmit(struct net_device *dev) {
--	u16 status;
--	int i;
--	struct airo_info *priv = dev->priv;
--	struct sk_buff *skb = priv->xmit.skb;
--	int fid = priv->xmit.fid;
--	u32 *fids = priv->fids;
--
--	if (down_trylock(&priv->sem) != 0) {
--		netif_stop_queue(dev);
--		priv->xmit.task.func = (void (*)(void *))airo_do_xmit;
--		priv->xmit.task.data = (void *)dev;
--		schedule_work(&priv->xmit.task);
--		return;
--	}
--	status = transmit_802_3_packet (priv, fids[fid], skb->data);
--	up(&priv->sem);
--
--	i = 0;
--	if ( status == SUCCESS ) {
--		dev->trans_start = jiffies;
--		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
--	} else {
--		priv->fids[fid] &= 0xffff;
--		priv->stats.tx_window_errors++;
--	}
--	if (i < MAX_FIDS / 2)
--		netif_wake_queue(dev);
--	else
--		netif_stop_queue(dev);
--	dev_kfree_skb(skb);
--}
--
--static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
--	s16 len;
-+static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+	int len;
- 	int i;
-+	int ret = 0;
-+	int status;
-+	unsigned long flags;
- 	struct airo_info *priv = dev->priv;
--	u32 *fids = priv->fids;
-+	int *fids = priv->fids;
- 
- 	if ( skb == NULL ) {
- 		printk( KERN_ERR "airo:  skb == NULL!!!\n" );
-@@ -1351,61 +1313,50 @@ static int airo_start_xmit(struct sk_buf
- 	}
- 
- 	/* Find a vacant FID */
--	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
--
--	if ( i == MAX_FIDS / 2 ) {
--		priv->stats.tx_fifo_errors++;
--		dev_kfree_skb(skb);
--	} else {
--		/* check min length*/
--		len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
--	        /* Mark fid as used & save length for later */
--		fids[i] |= (len << 16);
--		priv->xmit.skb = skb;
--		priv->xmit.fid = i;
--		airo_do_xmit(dev);
--	}
--	return 0;
--}
-+	spin_lock_irqsave(&priv->main_lock, flags);
-+	for (i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++);
- 
--static void airo_do_xmit11(struct net_device *dev) {
--	u16 status;
--	int i;
--	struct airo_info *priv = dev->priv;
--	struct sk_buff *skb = priv->xmit11.skb;
--	int fid = priv->xmit11.fid;
--	u32 *fids = priv->fids;
--
--	if (down_trylock(&priv->sem) != 0) {
-+	if (i + 1 >= MAX_FIDS / 2) {
- 		netif_stop_queue(dev);
--		priv->xmit11.task.func = (void (*)(void *))airo_do_xmit11;
--		priv->xmit11.task.data = (void *)dev;
--		schedule_work(&priv->xmit11.task);
--		return;
-+
-+		/* we cannot transmit */
-+		if (i == MAX_FIDS / 2) {
-+			priv->stats.tx_fifo_errors++;
-+			ret = 1;
-+			goto tx_done;
-+		}
- 	}
--	status = transmit_802_11_packet (priv, fids[fid], skb->data);
--	up(&priv->sem);
- 
--	i = MAX_FIDS / 2;
--	if ( status == SUCCESS ) {
-+	/* check min length*/
-+	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-+	status = transmit_802_3_packet (priv, fids[i], skb->data, len);
-+
-+	if (status == SUCCESS) {
-+		/* Mark fid as used & save length for later */
-+		fids[i] |= (len << 16);
- 		dev->trans_start = jiffies;
--		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
--	} else {
--		priv->fids[fid] &= 0xffff;
-+	}
-+	else {
- 		priv->stats.tx_window_errors++;
-+		ret = 1;
- 	}
--	if (i < MAX_FIDS)
--		netif_wake_queue(dev);
--	else
--		netif_stop_queue(dev);
--	dev_kfree_skb(skb);
-+
-+tx_done:
-+	spin_unlock_irqrestore(&priv->main_lock, flags);
-+	if (!ret)
-+		dev_kfree_skb(skb);
-+	return ret;
- }
- 
--static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
--	s16 len;
-+static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev)
-+{
-+	int len;
- 	int i;
-+	int ret = 0;
-+	int status;
-+	unsigned long flags;
- 	struct airo_info *priv = dev->priv;
--	u32 *fids = priv->fids;
-+	int *fids = priv->fids;
- 
- 	if ( skb == NULL ) {
- 		printk( KERN_ERR "airo:  skb == NULL!!!\n" );
-@@ -1413,21 +1364,39 @@ static int airo_start_xmit11(struct sk_b
- 	}
- 
- 	/* Find a vacant FID */
-+	spin_lock_irqsave(&priv->main_lock, flags);
- 	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
- 
--	if ( i == MAX_FIDS ) {
--		priv->stats.tx_fifo_errors++;
--		dev_kfree_skb(skb);
--	} else {
--		/* check min length*/
--		len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
--	        /* Mark fid as used & save length for later */
-+	if (i + 1 >= MAX_FIDS) {
-+		netif_stop_queue(dev);
-+
-+		/* we cannot transmit */
-+		if (i == MAX_FIDS) {
-+			priv->stats.tx_fifo_errors++;
-+			ret = 1;
-+			goto tx_done;
-+		}
-+	}
-+
-+	/* check min length*/
-+	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-+	status = transmit_802_11_packet (priv, fids[i], skb->data, len);
-+
-+	if (status == SUCCESS) {
-+		/* Mark fid as used & save length for later */
- 		fids[i] |= (len << 16);
--		priv->xmit11.skb = skb;
--		priv->xmit11.fid = i;
--		airo_do_xmit11(dev);
-+		dev->trans_start = jiffies;
- 	}
--	return 0;
-+	else {
-+		priv->stats.tx_window_errors++;
-+		ret = 1;
-+	}
-+
-+tx_done:
-+	spin_unlock_irqrestore(&priv->main_lock, flags);
-+	if (!ret)
-+		dev_kfree_skb(skb);
-+	return ret;
- }
- 
- struct net_device_stats *airo_get_stats(struct net_device *dev)
-@@ -1457,36 +1426,19 @@ struct net_device_stats *airo_get_stats(
- 	return &local->stats;
- }
- 
--static void airo_end_promisc(struct airo_info *ai) {
--	Resp rsp;
--
--	if ((IN4500(ai, EVSTAT) & EV_CMD) != 0) {
--		completecommand(ai, &rsp);
--		up(&ai->sem);
--	} else {
--		ai->promisc_task.func = (void (*)(void *))airo_end_promisc;
--		ai->promisc_task.data = (void *)ai;
--		schedule_work(&ai->promisc_task);
--	}
--}
--
--static void airo_set_promisc(struct airo_info *ai) {
-+static void airo_set_promisc(struct airo_info *ai)
-+{
- 	Cmd cmd;
-+	Resp rsp;
- 
--	if (down_trylock(&ai->sem) == 0) {
--		memset(&cmd, 0, sizeof(cmd));
--		cmd.cmd=CMD_SETMODE;
--		cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
--		sendcommand(ai, &cmd);
--		airo_end_promisc(ai);
--	} else {
--		ai->promisc_task.func = (void (*)(void *))airo_set_promisc;
--		ai->promisc_task.data = (void *)ai;
--		schedule_work(&ai->promisc_task);
--	}
-+	memset(&cmd, 0, sizeof(cmd));
-+	cmd.cmd = CMD_SETMODE;
-+	cmd.parm0 = (ai->flags & IFF_PROMISC) ? PROMISC : NOPROMISC;
-+	issuecommand(ai, &cmd, &rsp);
- }
- 
--static void airo_set_multicast_list(struct net_device *dev) {
-+static void airo_set_multicast_list(struct net_device *dev)
-+{
- 	struct airo_info *ai = dev->priv;
- 
- 	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
-@@ -1551,11 +1503,10 @@ void stop_airo_card( struct net_device *
- {
- 	struct airo_info *ai = dev->priv;
- 	flush_scheduled_work();
--	if (ai->flash)
--		kfree(ai->flash);
--	if (ai->rssi)
--		kfree(ai->rssi);
--	takedown_proc_entry( dev, ai );
-+
-+	disable_interrupts(ai);
-+	free_irq(dev->irq, dev);
-+
- 	if (ai->registered) {
- 		unregister_netdev( dev );
- 		if (ai->wifidev) {
-@@ -1565,9 +1516,15 @@ void stop_airo_card( struct net_device *
- 		}
- 		ai->registered = 0;
- 	}
--	disable_interrupts(ai);
--	free_irq( dev->irq, dev );
--	if (auto_wep) del_timer_sync(&ai->timer);
-+
-+	if (ai->flash)
-+		kfree(ai->flash);
-+	if (ai->rssi)
-+		kfree(ai->rssi);
-+	takedown_proc_entry( dev, ai );
-+
-+	if (auto_wep)
-+	       	del_timer_sync(&ai->timer);
- 	if (freeres) {
- 		/* PCMCIA frees this stuff, so only for PCI and ISA */
- 	        release_region( dev->base_addr, 64 );
-@@ -1664,8 +1621,7 @@ struct net_device *init_airo_card( unsig
- 	ai->wifidev = 0;
- 	ai->registered = 0;
-         ai->dev = dev;
--	ai->aux_lock = SPIN_LOCK_UNLOCKED;
--	sema_init(&ai->sem, 1);
-+	ai->main_lock = SPIN_LOCK_UNLOCKED;
- 	ai->need_commit = 0;
- 	ai->config.len = 0;
- 	rc = add_airo_dev( dev );
-@@ -1730,7 +1686,6 @@ struct net_device *init_airo_card( unsig
- 			ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
- 
- 	setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
--	netif_start_queue(dev);
- 	SET_MODULE_OWNER(dev);
- 	return dev;
- 
-@@ -1794,47 +1749,31 @@ int reset_airo_card( struct net_device *
- EXPORT_SYMBOL(reset_airo_card);
- 
- #if WIRELESS_EXT > 13
-+/* must be called with lock held */
- static void airo_send_event(struct net_device *dev) {
- 	struct airo_info *ai = dev->priv;
- 	union iwreq_data wrqu;
- 	StatusRid status_rid;
- 
--	if (down_trylock(&ai->sem) == 0) {
--		__set_bit(FLAG_LOCKED, &ai->flags);
--		PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid));
--		clear_bit(FLAG_LOCKED, &ai->flags);
--		up(&ai->sem);
--		wrqu.data.length = 0;
--		wrqu.data.flags = 0;
--		memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
--		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-+	PC4500_readrid_nolock(ai, RID_STATUS, &status_rid, sizeof(status_rid));
- 
--		/* Send event to user space */
--		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
--	} else {
--		ai->event_task.func = (void (*)(void *))airo_send_event;
--		ai->event_task.data = (void *)dev;
--		schedule_work(&ai->event_task);
--	}
-+	wrqu.data.length = 0;
-+	wrqu.data.flags = 0;
-+	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
-+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-+
-+	/* Send event to user space */
-+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
- }
- #endif
- 
- static void airo_read_mic(struct airo_info *ai) {
-+#ifdef MICSUPPORT
- 	MICRid mic_rid;
- 
--	if (down_trylock(&ai->sem) == 0) {
--		__set_bit(FLAG_LOCKED, &ai->flags);
--		PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid));
--		clear_bit(FLAG_LOCKED, &ai->flags);
--		up(&ai->sem);
--#ifdef MICSUPPORT
--		micinit (ai, &mic_rid);
-+	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid));
-+	micinit (ai, &mic_rid);
- #endif
--	} else {
--		ai->mic_task.func = (void (*)(void *))airo_read_mic;
--		ai->mic_task.data = (void *)ai;
--		schedule_work(&ai->mic_task);
--	}
- }
- 
- static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
-@@ -1848,6 +1787,7 @@ static irqreturn_t airo_interrupt ( int 
- 	if (!netif_device_present(dev))
- 		return IRQ_NONE;
- 
-+	spin_lock(&apriv->main_lock);
- 	for (;;) {
- 		status = IN4500( apriv, EVSTAT );
- 		if ( !(status & STATUS_INTS) || status == 0xffff ) break;
-@@ -1866,7 +1806,8 @@ static irqreturn_t airo_interrupt ( int 
- 
- 		if ( status & EV_MIC ) {
- 			OUT4500( apriv, EVACK, EV_MIC );
--			airo_read_mic( apriv );
-+			if (apriv->flags & FLAG_MIC_CAPABLE)
-+				airo_read_mic( apriv );
- 		}
- 		if ( status & EV_LINK ) {
- #if WIRELESS_EXT > 13
-@@ -2115,10 +2056,14 @@ static irqreturn_t airo_interrupt ( int 
- 					index = i;
- 					/* Set up to be used again */
- 					apriv->fids[i] &= 0xffff;
-+
-+					if (i < MAX_FIDS / 2)
-+						netif_wake_queue(dev);
-+					else
-+						netif_wake_queue(apriv->wifidev);
- 				}
- 			}
- 			if (index != -1) {
--				netif_wake_queue(dev);
- 				if (status & EV_TXEXC)
- 					get_tx_error(apriv, index);
- 			}
-@@ -2134,6 +2079,7 @@ static irqreturn_t airo_interrupt ( int 
- 
- 	if (savedInterrupts)
- 		OUT4500( apriv, EVINTEN, savedInterrupts );
-+	spin_unlock(&apriv->main_lock);
- 
- 	/* done.. */
- 	return IRQ_RETVAL(handled);
-@@ -2169,8 +2115,8 @@ static u16 IN4500( struct airo_info *ai,
- 	return rc;
- }
- 
--static int enable_MAC( struct airo_info *ai, Resp *rsp ) {
--	int rc;
-+static int enable_MAC( struct airo_info *ai, Resp *rsp )
-+{
-         Cmd cmd;
- 
- 	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
-@@ -2182,45 +2128,41 @@ static int enable_MAC( struct airo_info 
- 	if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS;
- 	memset(&cmd, 0, sizeof(cmd));
- 	cmd.cmd = MAC_ENABLE;
--	if (test_bit(FLAG_LOCKED, &ai->flags) != 0)
--		return issuecommand(ai, &cmd, rsp);
--
--	if (down_interruptible(&ai->sem))
--		return -ERESTARTSYS;
--	rc = issuecommand(ai, &cmd, rsp);
--	up(&ai->sem);
--	return rc;
-+	return issuecommand(ai, &cmd, rsp);
- }
- 
--static void disable_MAC( struct airo_info *ai ) {
-+static void disable_MAC(struct airo_info *ai)
-+{
-         Cmd cmd;
- 	Resp rsp;
- 
- 	memset(&cmd, 0, sizeof(cmd));
- 	cmd.cmd = MAC_DISABLE; // disable in case already enabled
--	if (test_bit(FLAG_LOCKED, &ai->flags) != 0) {
--		issuecommand(ai, &cmd, &rsp);
--		return;
--	}
--
--	if (down_interruptible(&ai->sem))
--		return;
- 	issuecommand(ai, &cmd, &rsp);
--	up(&ai->sem);
- }
- 
--static void enable_interrupts( struct airo_info *ai ) {
-+static void enable_interrupts(struct airo_info *ai)
-+{
-+	unsigned long flags;
-+	u16 status;
-+	spin_lock_irqsave(&ai->main_lock, flags);
-+
- 	/* Reset the status register */
--	u16 status = IN4500( ai, EVSTAT );
-+	status = IN4500( ai, EVSTAT );
- 	OUT4500( ai, EVACK, status );
-+
- 	/* Enable the interrupts */
- 	OUT4500( ai, EVINTEN, STATUS_INTS );
--	/* Note there is a race condition between the last two lines that
--	   I don't know how to get rid of right now... */
-+
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
- }
- 
--static void disable_interrupts( struct airo_info *ai ) {
-+static void disable_interrupts(struct airo_info *ai)
-+{
-+	unsigned long flags;
-+	spin_lock_irqsave(&ai->main_lock, flags);
- 	OUT4500( ai, EVINTEN, 0 );
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
- }
- 
- static u16 setup_card(struct airo_info *ai, u8 *mac)
-@@ -2243,23 +2185,20 @@ static u16 setup_card(struct airo_info *
- 	/* The NOP is the first step in getting the card going */
- 	cmd.cmd = NOP;
- 	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
--	if (down_interruptible(&ai->sem))
-+	if (spin_is_locked(&ai->main_lock))
- 		return ERROR;
--	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
--		up(&ai->sem);
-+	if (issuecommand(ai, &cmd, &rsp) != SUCCESS)
- 		return ERROR;
--	}
-+
- 	memset(&cmd, 0, sizeof(cmd));
- 	cmd.cmd = MAC_DISABLE; // disable in case already enabled
--	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
--		up(&ai->sem);
-+	if (issuecommand( ai, &cmd, &rsp) != SUCCESS )
- 		return ERROR;
--	}
-+
- 
- 	// Let's figure out if we need to use the AUX port
- 	cmd.cmd = CMD_ENABLEAUX;
- 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
--		up(&ai->sem);
- 		printk(KERN_ERR "airo: Error checking for AUX port\n");
- 		return ERROR;
- 	}
-@@ -2270,7 +2209,7 @@ static u16 setup_card(struct airo_info *
- 		ai->bap_read = aux_bap_read;
- 		printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
- 	}
--	up(&ai->sem);
-+
- 	if (ai->config.len == 0) {
- 		tdsRssiRid rssi_rid;
- 		CapabilityRid cap_rid;
-@@ -2375,50 +2314,35 @@ static u16 setup_card(struct airo_info *
- 	}
- 	return SUCCESS;
- }
-+static int issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
-+	int rc;
-+	unsigned long flags;
- 
--static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
--        // Im really paranoid about letting it run forever!
--	int max_tries = 600000;
--
--	if (sendcommand(ai, pCmd) == (u16)ERROR)
--		return ERROR;
--
--	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
--		if (!in_interrupt() && (max_tries & 255) == 0)
--			schedule();
--	}
--	if ( max_tries == -1 ) {
--		printk( KERN_ERR
--			"airo: Max tries exceeded waiting for command\n" );
--                return ERROR;
--	}
--	completecommand(ai, pRsp);
--	return SUCCESS;
-+	spin_lock_irqsave(&ai->main_lock, flags);
-+	rc = issuecommand_nolock(ai, pCmd, pRsp);
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
-+	return rc;
- }
- 
--static u16 sendcommand(struct airo_info *ai, Cmd *pCmd) {
--        // Im really paranoid about letting it run forever!
-+static int issuecommand_nolock(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
-+	// Im really paranoid about letting it run forever!
- 	int max_tries = 600000;
--	u16 cmd;
- 
- 	OUT4500(ai, PARAM0, pCmd->parm0);
- 	OUT4500(ai, PARAM1, pCmd->parm1);
- 	OUT4500(ai, PARAM2, pCmd->parm2);
- 	OUT4500(ai, COMMAND, pCmd->cmd);
--	while ( max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0 &&
--		(cmd = IN4500(ai, COMMAND)) != 0 )
--			if (cmd == pCmd->cmd)
--				// PC4500 didn't notice command, try again
--				OUT4500(ai, COMMAND, pCmd->cmd);
--	if ( max_tries == -1 ) {
-+	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
-+		if (IN4500(ai, COMMAND) == pCmd->cmd) {
-+			// PC4500 didn't notice command, try again
-+			OUT4500(ai, COMMAND, pCmd->cmd);
-+		}
-+	}
-+	if (max_tries == -1) {
- 		printk( KERN_ERR
- 			"airo: Max tries exceeded when issueing command\n" );
-                 return ERROR;
- 	}
--	return SUCCESS;
--}
--
--static void completecommand(struct airo_info *ai, Resp *pRsp) {
- 	// command completed
- 	pRsp->status = IN4500(ai, STATUS);
- 	pRsp->rsp0 = IN4500(ai, RESP0);
-@@ -2431,8 +2355,10 @@ static void completecommand(struct airo_
- 	}
- 	// acknowledge processing the status/response
- 	OUT4500(ai, EVACK, EV_CMD);
-+	return SUCCESS;
- }
- 
-+
- /* Sets up the bap to start exchange data.  whichbap should
-  * be one of the BAP0 or BAP1 defines.  Locks should be held before
-  * calling! */
-@@ -2497,9 +2423,7 @@ static int aux_bap_read(struct airo_info
- 	u16 next;
- 	int words;
- 	int i;
--	unsigned long flags;
- 
--	spin_lock_irqsave(&ai->aux_lock, flags);
- 	page = IN4500(ai, SWS0+whichbap);
- 	offset = IN4500(ai, SWS2+whichbap);
- 	next = aux_setup(ai, page, offset, &len);
-@@ -2519,7 +2443,6 @@ static int aux_bap_read(struct airo_info
- 			next = aux_setup(ai, next, 4, &len);
- 		}
- 	}
--	spin_unlock_irqrestore(&ai->aux_lock, flags);
- 	return SUCCESS;
- }
- 
-@@ -2558,7 +2481,7 @@ static int PC4500_accessrid(struct airo_
- 	memset(&cmd, 0, sizeof(cmd));
- 	cmd.cmd = accmd;
- 	cmd.parm0 = rid;
--	status = issuecommand(ai, &cmd, &rsp);
-+	status = issuecommand_nolock(ai, &cmd, &rsp);
- 	if (status != 0) return status;
- 	if ( (rsp.status & 0x7F00) != 0) {
- 		return (accmd << 8) + (rsp.rsp0 & 0xFF);
-@@ -2567,25 +2490,16 @@ static int PC4500_accessrid(struct airo_
- }
- 
- /*  Note, that we are using BAP1 which is also used by transmit, so
-- *  we must get a lock. */
--static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len)
-+ *  it must be called with main_lock held. */
-+static int PC4500_readrid_nolock(struct airo_info *ai, u16 rid, void *pBuf, int len)
- {
--	u16 status, dolock = 0;
--        int rc = SUCCESS;
-+	u16 status;
-+
-+	if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS)
-+                return status;
-+	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS)
-+                return ERROR;
- 
--	if (test_bit(FLAG_LOCKED, &ai->flags) == 0) {
--		dolock = 1;
--		if (down_interruptible(&ai->sem))
--			return ERROR;
--	}
--	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
--                rc = status;
--                goto done;
--        }
--	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
--		rc = ERROR;
--                goto done;
--        }
- 	// read the rid length field
- 	bap_read(ai, pBuf, 2, BAP1);
- 	// length for remaining part of rid
-@@ -2596,30 +2510,34 @@ static int PC4500_readrid(struct airo_in
- 			"airo: Rid %x has a length of %d which is too short\n",
- 			(int)rid,
- 			(int)len );
--		rc = ERROR;
--                goto done;
-+		return ERROR;
- 	}
- 	// read remainder of the rid
--	rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
--done:
--	if (dolock)
--		up(&ai->sem);
--	return rc;
-+	return bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
- }
- 
-+static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len)
-+{
-+	unsigned long flags;
-+	int rc;
-+
-+	spin_lock_irqsave(&ai->main_lock, flags);
-+	rc = PC4500_readrid_nolock(ai, rid, pBuf, len);
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
-+	return rc;
-+}
- /*  Note, that we are using BAP1 which is also used by transmit, so
-  *  make sure this isnt called when a transmit is happening */
- static int PC4500_writerid(struct airo_info *ai, u16 rid,
- 			   const void *pBuf, int len)
- {
--	u16 status, dolock = 0;
-+	u16 status;
-+	unsigned long flags;
- 	int rc = SUCCESS;
- 
--	if (test_bit(FLAG_LOCKED, &ai->flags) == 0) {
--		dolock = 1;
--		if (down_interruptible(&ai->sem))
--			return ERROR;
--	}
-+	*(u16*)pBuf = cpu_to_le16((u16)len);
-+
-+	spin_lock_irqsave(&ai->main_lock, flags);
- 	// --- first access so that we can write the rid data
- 	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
-                 rc = status;
-@@ -2633,9 +2551,8 @@ static int PC4500_writerid(struct airo_i
- 	bap_write(ai, pBuf, len, BAP1);
- 	// ---now commit the rid data
- 	rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
-- done:
--	if (dolock)
--		up(&ai->sem);
-+done:
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
-         return rc;
- }
- 
-@@ -2643,6 +2560,8 @@ static int PC4500_writerid(struct airo_i
-    one for now. */
- static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
- {
-+	unsigned long flags;
-+	unsigned int loop = 3000;
- 	Cmd cmd;
- 	Resp rsp;
- 	u16 txFid;
-@@ -2650,20 +2569,25 @@ static u16 transmit_allocate(struct airo
- 
- 	cmd.cmd = CMD_ALLOCATETX;
- 	cmd.parm0 = lenPayload;
--	if (down_interruptible(&ai->sem))
--		return ERROR;
--	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
--		txFid = 0;
-+	spin_lock_irqsave(&ai->main_lock, flags);
-+	if (issuecommand_nolock(ai, &cmd, &rsp) != SUCCESS) {
-+		txFid = ERROR;
- 		goto done;
- 	}
- 	if ( (rsp.status & 0xFF00) != 0) {
--		txFid = 0;
-+		txFid = ERROR;
- 		goto done;
- 	}
-+
- 	/* wait for the allocate event/indication
--	 * It makes me kind of nervous that this can just sit here and spin,
--	 * but in practice it only loops like four times. */
--	while ( (IN4500(ai, EVSTAT) & EV_ALLOC) == 0) ;
-+	 * in practice it only loops like four times. */
-+	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop)
-+	       ; /* nada */
-+	if (!loop) {
-+		txFid = ERROR;
-+		goto done;
-+	}
-+
- 	// get the allocated fid and acknowledge
- 	txFid = IN4500(ai, TXALLOCFID);
- 	OUT4500(ai, EVACK, EV_ALLOC);
-@@ -2685,7 +2609,7 @@ static u16 transmit_allocate(struct airo
- 		bap_write(ai, &txControl, sizeof(txControl), BAP1);
- 
- done:
--	up(&ai->sem);
-+	spin_unlock_irqrestore(&ai->main_lock, flags);
- 
- 	return txFid;
- }
-@@ -2693,17 +2617,14 @@ done:
- /* In general BAP1 is dedicated to transmiting packets.  However,
-    since we need a BAP when accessing RIDs, we also use BAP1 for that.
-    Make sure the BAP1 spinlock is held when this is called. */
--static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
-+static int transmit_802_3_packet(struct airo_info *ai, u16 txFid, char *pPacket, int len)
- {
- 	u16 payloadLen;
- 	Cmd cmd;
- 	Resp rsp;
- 	int miclen = 0;
--	u16 txFid = len;
- 	MICBuffer pMic;
- 
--	len >>= 16;
--
- 	if (len < ETH_ALEN * 2) {
- 		printk( KERN_WARNING "Short packet %d\n", len );
- 		return ERROR;
-@@ -2734,12 +2655,12 @@ static int transmit_802_3_packet(struct 
- 	memset( &cmd, 0, sizeof( cmd ) );
- 	cmd.cmd = CMD_TRANSMIT;
- 	cmd.parm0 = txFid;
--	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
-+	if (issuecommand_nolock(ai, &cmd, &rsp) != SUCCESS) return ERROR;
- 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
- 	return SUCCESS;
- }
- 
--static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
-+static int transmit_802_11_packet(struct airo_info *ai, u16 txFid, char *pPacket, int len)
- {
- 	u16 fc, payloadLen;
- 	Cmd cmd;
-@@ -2750,8 +2671,6 @@ static int transmit_802_11_packet(struct
- 		u16 gaplen;
- 		u8 gap[6];
- 	} gap;
--	u16 txFid = len;
--	len >>= 16;
- 	gap.gaplen = 6;
- 
- 	fc = le16_to_cpu(*(const u16*)pPacket);
-@@ -2793,7 +2712,7 @@ static int transmit_802_11_packet(struct
- 	memset( &cmd, 0, sizeof( cmd ) );
- 	cmd.cmd = CMD_TRANSMIT;
- 	cmd.parm0 = txFid;
--	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
-+	if (issuecommand_nolock(ai, &cmd, &rsp) != SUCCESS) return ERROR;
- 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
- 	return SUCCESS;
- }
-@@ -3857,10 +3776,7 @@ static int proc_BSSList_open( struct ino
- 
- 			memset(&cmd, 0, sizeof(cmd));
- 			cmd.cmd=CMD_LISTBSS;
--			if (down_interruptible(&ai->sem))
--				return -ERESTARTSYS;
- 			issuecommand(ai, &cmd, &rsp);
--			up(&ai->sem);
- 			data->readlen = 0;
- 			return 0;
- 		}
-@@ -3923,13 +3839,6 @@ static void timer_func( u_long data ) {
- 
- 	if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) {
- /* We don't have a link so try changing the authtype */
--		if (down_trylock(&apriv->sem) != 0) {
--			apriv->timer.expires = RUN_AT(1);
--			add_timer(&apriv->timer);
--			return;
--		}
--		__set_bit(FLAG_LOCKED, &apriv->flags);
--
- 		readConfigRid(apriv);
- 		disable_MAC(apriv);
- 		switch(apriv->config.authType) {
-@@ -3955,8 +3864,6 @@ static void timer_func( u_long data ) {
- 		apriv->need_commit = 1;
- 		writeConfigRid(apriv);
- 		enable_MAC(apriv, &rsp);
--		clear_bit(FLAG_LOCKED, &apriv->flags);
--		up(&apriv->sem);
- 
- /* Schedule check to see if the change worked */
- 		apriv->timer.expires = RUN_AT(HZ*3);
-@@ -4135,7 +4042,11 @@ static int airo_get_freq(struct net_devi
- 	struct airo_info *local = dev->priv;
- 	StatusRid status_rid;		/* Card status info */
- 
--	readStatusRid(local, &status_rid);
-+	if (local->config.opmode & MODE_STA_ESS)
-+		status_rid.channel = local->config.channelSet;
-+	else
-+		readStatusRid(local, &status_rid);
-+
- 
- 	/* Will return zero in infrastructure mode */
- #ifdef WEXT_USECHANNELS
-@@ -4246,11 +4157,8 @@ static int airo_set_wap(struct net_devic
- 		return -EINVAL;
- 	else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
- 		memset(&cmd, 0, sizeof(cmd));
--		cmd.cmd=CMD_LOSE_SYNC;
--		if (down_interruptible(&local->sem))
--			return -ERESTARTSYS;
-+		cmd.cmd = CMD_LOSE_SYNC;
- 		issuecommand(local, &cmd, &rsp);
--		up(&local->sem);
- 	} else {
- 		memset(&APList_rid, 0, sizeof(APList_rid));
- 		APList_rid.len = sizeof(APList_rid);
-@@ -5132,11 +5040,8 @@ static int airo_set_scan(struct net_devi
- 	/* Initiate a scan command */
- 	memset(&cmd, 0, sizeof(cmd));
- 	cmd.cmd=CMD_LISTBSS;
--	if (down_interruptible(&ai->sem))
--		return -ERESTARTSYS;
- 	issuecommand(ai, &cmd, &rsp);
- 	ai->scan_timestamp = jiffies;
--	up(&ai->sem);
- 
- 	/* At this point, just return to the user. */
- 
---- linux-2.6.0-test1/drivers/net/wireless/ray_cs.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/net/wireless/ray_cs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -25,6 +25,8 @@
-  * - reorganize kmallocs in ray_attach, checking all for failure
-  *   and releasing the previous allocations if one fails
-  *
-+ * Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
-+ * - Audit copy_to_user in ioctl(SIOCGIWESSID)
-  * 
- =============================================================================*/
- 
-@@ -1315,7 +1317,8 @@ static int ray_dev_ioctl(struct net_devi
- 	  /* Push it out ! */
- 	  wrq->u.data.length = strlen(essid) + 1;
- 	  wrq->u.data.flags = 1; /* active */
--	  copy_to_user(wrq->u.data.pointer, essid, sizeof(essid));
-+	  if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)))
-+		  err = -EFAULT;
- 	}
-       break;
- 
---- linux-2.6.0-test1/drivers/parisc/led.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/drivers/parisc/led.c	2003-07-19 17:03:50.000000000 -0700
-@@ -14,6 +14,10 @@
-  * TODO:
-  *	- speed-up calculations with inlined assembler
-  *	- interface to write to second row of LCD from /proc (if technically possible)
-+ *
-+ * Changes:
-+ *      - Audit copy_from_user in led_proc_write.
-+ *                                Daniele Bellucci <bellucda@tiscali.it>
-  */
- 
- #include <linux/config.h>
-@@ -160,7 +164,9 @@ static int led_proc_write(struct file *f
- 
- 	memset(lbuf, 0, count);
- 
--	copy_from_user(lbuf, buf, count);
-+	if (copy_from_user(lbuf, buf, count))
-+		return -EFAULT;
-+
- 	cur = lbuf;
- 
- 	/* skip initial spaces */
---- linux-2.6.0-test1/drivers/parport/parport_pc.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/parport/parport_pc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -94,7 +94,8 @@ static struct superio_struct {	/* For Su
- } superios[NR_SUPERIOS] __devinitdata = { {0,},};
- 
- static int user_specified __devinitdata = 0;
--#if defined(CONFIG_PARPORT_PC_FIFO) || defined(CONFIG_PARPORT_PC_SUPERIO)
-+#if defined(CONFIG_PARPORT_PC_SUPERIO) || \
-+       (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
- static int verbose_probing;
- #endif
- static int registered_parport;
-@@ -3116,7 +3117,8 @@ MODULE_PARM_DESC(irq, "IRQ line");
- MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
- MODULE_PARM_DESC(dma, "DMA channel");
- MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
--#if defined(CONFIG_PARPORT_PC_FIFO) || defined(CONFIG_PARPORT_PC_SUPERIO)
-+#if defined(CONFIG_PARPORT_PC_SUPERIO) || \
-+       (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
- MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
- MODULE_PARM(verbose_probing, "i");
- #endif
---- linux-2.6.0-test1/drivers/pci/hotplug/acpiphp_glue.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/pci/hotplug/acpiphp_glue.c	2003-07-19 17:03:50.000000000 -0700
-@@ -607,7 +607,7 @@ find_p2p_bridge (acpi_handle handle, u32
- 
- 	/* check if this bridge has ejectable slots */
- 	if (detect_ejectable_slots(handle) > 0) {
--		dbg("found PCI-to-PCI bridge at PCI %s\n", dev->slot_name);
-+		dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
- 		add_p2p_bridge(handle, seg, bus, device, function);
- 	}
- 
-@@ -693,7 +693,7 @@ static int power_on_slot (struct acpiphp
- 
- 		if (func->flags & FUNC_HAS_PS0) {
- 			dbg("%s: executing _PS0 on %s\n", __FUNCTION__,
--			    func->pci_dev->slot_name);
-+			    pci_name(func->pci_dev));
- 			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
- 			if (ACPI_FAILURE(status)) {
- 				warn("%s: _PS0 failed\n", __FUNCTION__);
---- linux-2.6.0-test1/drivers/pci/hotplug/acpiphp_pci.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/pci/hotplug/acpiphp_pci.c	2003-07-19 17:03:50.000000000 -0700
-@@ -212,7 +212,7 @@ static int detect_used_resource (struct 
- 	int count;
- 	struct pci_resource *res;
- 
--	dbg("Device %s\n", dev->slot_name);
-+	dbg("Device %s\n", pci_name(dev));
- 
- 	for (count = 0; address[count]; count++) {	/* for 6 BARs */
- 		pci_read_config_dword(dev, address[count], &bar);
-@@ -337,7 +337,7 @@ int acpiphp_init_func_resource (struct a
- 	struct pci_dev *dev;
- 
- 	dev = func->pci_dev;
--	dbg("Hot-pluggable device %s\n", dev->slot_name);
-+	dbg("Hot-pluggable device %s\n", pci_name(dev));
- 
- 	for (count = 0; address[count]; count++) {	/* for 6 BARs */
- 		pci_read_config_dword(dev, address[count], &bar);
---- linux-2.6.0-test1/drivers/pci/hotplug.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pci/hotplug.c	2003-07-19 17:03:50.000000000 -0700
-@@ -10,8 +10,6 @@
- #define DBG(x...)
- #endif
- 
--static void pci_free_resources(struct pci_dev *dev);
--
- int pci_hotplug (struct device *dev, char **envp, int num_envp,
- 		 char *buffer, int buffer_size)
- {
-@@ -57,7 +55,7 @@ int pci_hotplug (struct device *dev, cha
- 
- 	envp[i++] = scratch;
- 	length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
--			    pdev->slot_name);
-+			    pci_name(pdev));
- 	if ((buffer_size - length <= 0) || (i >= num_envp))
- 		return -ENOMEM;
- 
-@@ -172,105 +170,3 @@ int pci_visit_dev (struct pci_visit *fn,
- }
- EXPORT_SYMBOL(pci_visit_dev);
- 
--static void pci_destroy_dev(struct pci_dev *dev)
--{
--	pci_proc_detach_device(dev);
--	device_unregister(&dev->dev);
--
--	/* Remove the device from the device lists, and prevent any further
--	 * list accesses from this device */
--	spin_lock(&pci_bus_lock);
--	list_del(&dev->bus_list);
--	list_del(&dev->global_list);
--	dev->bus_list.next = dev->bus_list.prev = NULL;
--	dev->global_list.next = dev->global_list.prev = NULL;
--	spin_unlock(&pci_bus_lock);
--
--	pci_free_resources(dev);
--	pci_dev_put(dev);
--}
--
--/**
-- * pci_remove_device_safe - remove an unused hotplug device
-- * @dev: the device to remove
-- *
-- * Delete the device structure from the device lists and 
-- * notify userspace (/sbin/hotplug), but only if the device
-- * in question is not being used by a driver.
-- * Returns 0 on success.
-- */
--int pci_remove_device_safe(struct pci_dev *dev)
--{
--	if (pci_dev_driver(dev))
--		return -EBUSY;
--	pci_destroy_dev(dev);
--	return 0;
--}
--EXPORT_SYMBOL(pci_remove_device_safe);
--
--static void
--pci_free_resources(struct pci_dev *dev)
--{
--	int i;
--
--	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
--		struct resource *res = dev->resource + i;
--		if (res->parent)
--			release_resource(res);
--	}
--}
--
--/**
-- * pci_remove_bus_device - remove a PCI device and any children
-- * @dev: the device to remove
-- *
-- * Remove a PCI device from the device lists, informing the drivers
-- * that the device has been removed.  We also remove any subordinate
-- * buses and children in a depth-first manner.
-- *
-- * For each device we remove, delete the device structure from the
-- * device lists, remove the /proc entry, and notify userspace
-- * (/sbin/hotplug).
-- */
--void pci_remove_bus_device(struct pci_dev *dev)
--{
--	if (dev->subordinate) {
--		struct pci_bus *b = dev->subordinate;
--
--		pci_remove_behind_bridge(dev);
--		pci_proc_detach_bus(b);
--
--		spin_lock(&pci_bus_lock);
--		list_del(&b->node);
--		spin_unlock(&pci_bus_lock);
--
--		kfree(b);
--		dev->subordinate = NULL;
--	}
--
--	pci_destroy_dev(dev);
--}
--
--/**
-- * pci_remove_behind_bridge - remove all devices behind a PCI bridge
-- * @dev: PCI bridge device
-- *
-- * Remove all devices on the bus, except for the parent bridge.
-- * This also removes any child buses, and any devices they may
-- * contain in a depth-first manner.
-- */
--void pci_remove_behind_bridge(struct pci_dev *dev)
--{
--	struct list_head *l, *n;
--
--	if (dev->subordinate) {
--		list_for_each_safe(l, n, &dev->subordinate->devices) {
--			struct pci_dev *dev = pci_dev_b(l);
--
--			pci_remove_bus_device(dev);
--		}
--	}
--}
--
--EXPORT_SYMBOL(pci_remove_bus_device);
--EXPORT_SYMBOL(pci_remove_behind_bridge);
---- linux-2.6.0-test1/drivers/pci/hotplug/cpci_hotplug_core.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pci/hotplug/cpci_hotplug_core.c	2003-07-19 17:03:50.000000000 -0700
-@@ -427,34 +427,6 @@ cpci_hp_unregister_bus(struct pci_bus *b
- 	return 0;
- }
- 
--struct slot *
--cpci_find_slot(struct pci_bus *bus, unsigned int devfn)
--{
--	struct slot *slot;
--	struct slot *found;
--	struct list_head *tmp;
--
--	if(!bus) {
--		return NULL;
--	}
--
--	spin_lock(&list_lock);
--	if(!slots) {
--		spin_unlock(&list_lock);
--		return NULL;
--	}
--	found = NULL;
--	list_for_each(tmp, &slot_list) {
--		slot = list_entry(tmp, struct slot, slot_list);
--		if(slot->bus == bus && slot->devfn == devfn) {
--			found = slot;
--			break;
--		}
--	}
--	spin_unlock(&list_lock);
--	return found;
--}
--
- /* This is the interrupt mode interrupt handler */
- irqreturn_t
- cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
-@@ -924,6 +896,5 @@ EXPORT_SYMBOL_GPL(cpci_hp_register_contr
- EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
- EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
- EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
--EXPORT_SYMBOL_GPL(cpci_find_slot);
- EXPORT_SYMBOL_GPL(cpci_hp_start);
- EXPORT_SYMBOL_GPL(cpci_hp_stop);
---- linux-2.6.0-test1/drivers/pci/hotplug/cpci_hotplug.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/pci/hotplug/cpci_hotplug.h	2003-07-19 17:03:50.000000000 -0700
-@@ -75,7 +75,6 @@ extern int cpci_hp_register_controller(s
- extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
- extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
- extern int cpci_hp_unregister_bus(struct pci_bus *bus);
--extern struct slot *cpci_find_slot(struct pci_bus *bus, unsigned int devfn);
- extern int cpci_hp_start(void);
- extern int cpci_hp_stop(void);
- 
---- linux-2.6.0-test1/drivers/pci/hotplug/cpci_hotplug_pci.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/pci/hotplug/cpci_hotplug_pci.c	2003-07-19 17:03:50.000000000 -0700
-@@ -448,7 +448,7 @@ static int cpci_configure_bridge(struct 
- }
- 
- static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
--			struct pci_bus_wrapped *wrapped_bus)
-+				   struct pci_bus_wrapped *wrapped_bus)
- {
- 	int rc;
- 	struct pci_dev *dev = wrapped_dev->dev;
-@@ -461,8 +461,8 @@ static int configure_visit_pci_dev(struc
- 	 * We need to fix up the hotplug representation with the Linux
- 	 * representation.
- 	 */
--	slot = cpci_find_slot(dev->bus, dev->devfn);
--	if(slot) {
-+	if(wrapped_dev->data) {
-+		slot = (struct slot*) wrapped_dev->data;
- 		slot->dev = dev;
- 	}
- 
-@@ -494,9 +494,7 @@ static int unconfigure_visit_pci_dev_pha
- 		return -ENODEV;
- 
- 	/* Remove the Linux representation */
--	if(pci_remove_device_safe(dev) == 0) {
--		kfree(dev);
--	} else {
-+	if(pci_remove_device_safe(dev)) {
- 		err("Could not remove device\n");
- 		return -1;
- 	}
-@@ -504,8 +502,8 @@ static int unconfigure_visit_pci_dev_pha
- 	/*
- 	 * Now remove the hotplug representation.
- 	 */
--	slot = cpci_find_slot(dev->bus, dev->devfn);
--	if(slot) {
-+	if(wrapped_dev->data) {
-+		slot = (struct slot*) wrapped_dev->data;
- 		slot->dev = NULL;
- 	} else {
- 		dbg("No hotplug representation for %02x:%02x.%x",
-@@ -574,13 +572,18 @@ int cpci_configure_slot(struct slot* slo
- 
- 	/* Still NULL? Well then scan for it! */
- 	if(slot->dev == NULL) {
-+		int n;
- 		dbg("pci_dev still null");
- 
- 		/*
- 		 * This will generate pci_dev structures for all functions, but
- 		 * we will only call this case when lookup fails.
- 		 */
--		slot->dev = pci_scan_slot(slot->bus, slot->devfn);
-+		n = pci_scan_slot(slot->bus, slot->devfn);
-+		dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
-+		if(n > 0)
-+			pci_bus_add_devices(slot->bus);
-+		slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
- 		if(slot->dev == NULL) {
- 			err("Could not find PCI device for slot %02x", slot->number);
- 			return 0;
-@@ -603,6 +606,10 @@ int cpci_configure_slot(struct slot* slo
- 				continue;
- 			wrapped_dev.dev = dev;
- 			wrapped_bus.bus = slot->dev->bus;
-+			if(i)
-+				wrapped_dev.data = NULL;
-+			else
-+				wrapped_dev.data = (void*) slot;
- 			rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
- 		}
- 	}
-@@ -635,9 +642,14 @@ int cpci_unconfigure_slot(struct slot* s
- 		if(dev) {
- 			wrapped_dev.dev = dev;
- 			wrapped_bus.bus = dev->bus;
-+ 			if(i)
-+ 				wrapped_dev.data = NULL;
-+ 			else
-+ 				wrapped_dev.data = (void*) slot;
- 			dbg("%s - unconfigure phase 2", __FUNCTION__);
- 			rc = pci_visit_dev(&unconfigure_functions_phase2,
--					   &wrapped_dev, &wrapped_bus);
-+					   &wrapped_dev,
-+					   &wrapped_bus);
- 			if(rc)
- 				break;
- 		}
---- linux-2.6.0-test1/drivers/pci/hotplug/Kconfig	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pci/hotplug/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -99,22 +99,17 @@ config HOTPLUG_PCI_ACPI
- 	  When in doubt, say N.
- 
- config HOTPLUG_PCI_CPCI
--	tristate "CompactPCI Hotplug driver"
-+	bool "CompactPCI Hotplug driver"
- 	depends on HOTPLUG_PCI
- 	help
- 	  Say Y here if you have a CompactPCI system card with CompactPCI
- 	  hotswap support per the PICMG 2.1 specification.
- 
--	  This code is also available as a module ( = code which can be
--	  inserted in and removed from the running kernel whenever you want).
--	  The module will be called cpci_hotplug. If you want to compile it
--	  as a module, say M here and read <file:Documentation/modules.txt>.
--
- 	  When in doubt, say N.
- 
- config HOTPLUG_PCI_CPCI_ZT5550
- 	tristate "Ziatech ZT5550 CompactPCI Hotplug driver"
--	depends on HOTPLUG_PCI_CPCI && X86
-+	depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
- 	help
- 	  Say Y here if you have an Performance Technologies (formerly Intel,
-           formerly just Ziatech) Ziatech ZT5550 CompactPCI system card.
-@@ -128,7 +123,7 @@ config HOTPLUG_PCI_CPCI_ZT5550
- 
- config HOTPLUG_PCI_CPCI_GENERIC
- 	tristate "Generic port I/O CompactPCI Hotplug driver"
--	depends on HOTPLUG_PCI_CPCI && X86
-+	depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
- 	help
- 	  Say Y here if you have a CompactPCI system card that exposes the #ENUM
- 	  hotswap signal as a bit in a system register that can be read through
---- linux-2.6.0-test1/drivers/pci/Makefile	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pci/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -2,7 +2,7 @@
- # Makefile for the PCI bus specific drivers.
- #
- 
--obj-y		+= access.o bus.o probe.o pci.o pool.o quirks.o \
-+obj-y		+= access.o bus.o probe.o remove.o pci.o pool.o quirks.o \
- 			names.o pci-driver.o search.o pci-sysfs.o
- obj-$(CONFIG_PM)  += power.o
- obj-$(CONFIG_PROC_FS) += proc.o
---- linux-2.6.0-test1/drivers/pci/pci.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pci/pci.c	2003-07-19 17:03:50.000000000 -0700
-@@ -506,7 +506,7 @@ err_out:
- 		pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
- 		bar + 1, /* PCI BAR # */
- 		pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
--		pdev->slot_name);
-+		pci_name(pdev));
- 	return -EBUSY;
- }
- 
-@@ -555,7 +555,7 @@ err_out:
- 		pci_resource_flags(pdev, i) & IORESOURCE_IO ? "I/O" : "mem",
- 		i + 1, /* PCI BAR # */
- 		pci_resource_len(pdev, i), pci_resource_start(pdev, i),
--		pdev->slot_name);
-+		pci_name(pdev));
- 	while(--i >= 0)
- 		pci_release_region(pdev, i);
- 		
-@@ -576,7 +576,7 @@ pci_set_master(struct pci_dev *dev)
- 
- 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
- 	if (! (cmd & PCI_COMMAND_MASTER)) {
--		DBG("PCI: Enabling bus mastering for device %s\n", dev->slot_name);
-+		DBG("PCI: Enabling bus mastering for device %s\n", pci_name(dev));
- 		cmd |= PCI_COMMAND_MASTER;
- 		pci_write_config_word(dev, PCI_COMMAND, cmd);
- 	}
-@@ -620,7 +620,7 @@ pci_generic_prep_mwi(struct pci_dev *dev
- 		return 0;
- 
- 	printk(KERN_WARNING "PCI: cache line size of %d is not supported "
--	       "by device %s\n", pci_cache_line_size << 2, dev->slot_name);
-+	       "by device %s\n", pci_cache_line_size << 2, pci_name(dev));
- 
- 	return -EINVAL;
- }
-@@ -653,7 +653,7 @@ pci_set_mwi(struct pci_dev *dev)
- 
- 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
- 	if (! (cmd & PCI_COMMAND_INVALIDATE)) {
--		DBG("PCI: Enabling Mem-Wr-Inval for device %s\n", dev->slot_name);
-+		DBG("PCI: Enabling Mem-Wr-Inval for device %s\n", pci_name(dev));
- 		cmd |= PCI_COMMAND_INVALIDATE;
- 		pci_write_config_word(dev, PCI_COMMAND, cmd);
- 	}
---- linux-2.6.0-test1/drivers/pci/pool.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/pci/pool.c	2003-07-19 17:03:50.000000000 -0700
-@@ -233,7 +233,7 @@ pci_pool_destroy (struct pci_pool *pool)
- 				struct pci_page, page_list);
- 		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
- 			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
--				pool->dev ? pool->dev->slot_name : NULL,
-+				pool->dev ? pci_name(pool->dev) : NULL,
- 				pool->name, page->vaddr);
- 			/* leak the still-in-use consistent memory */
- 			list_del (&page->page_list);
-@@ -359,7 +359,7 @@ pci_pool_free (struct pci_pool *pool, vo
- 
- 	if ((page = pool_find_page (pool, dma)) == 0) {
- 		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
--			pool->dev ? pool->dev->slot_name : NULL,
-+			pool->dev ? pci_name(pool->dev) : NULL,
- 			pool->name, vaddr, (unsigned long) dma);
- 		return;
- 	}
-@@ -372,13 +372,13 @@ pci_pool_free (struct pci_pool *pool, vo
- #ifdef	CONFIG_DEBUG_SLAB
- 	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
- 		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%Lx\n",
--			pool->dev ? pool->dev->slot_name : NULL,
-+			pool->dev ? pci_name(pool->dev) : NULL,
- 			pool->name, vaddr, (unsigned long long) dma);
- 		return;
- 	}
- 	if (page->bitmap [map] & (1UL << block)) {
- 		printk (KERN_ERR "pci_pool_free %s/%s, dma %Lx already free\n",
--			pool->dev ? pool->dev->slot_name : NULL,
-+			pool->dev ? pci_name(pool->dev) : NULL,
- 			pool->name, (unsigned long long)dma);
- 		return;
- 	}
---- linux-2.6.0-test1/drivers/pci/probe.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/pci/probe.c	2003-07-19 17:04:50.000000000 -0700
-@@ -176,7 +176,7 @@ void __devinit pci_read_bridge_bases(str
- 		limit |= (io_limit_hi << 16);
- 	}
- 
--	if (base && base <= limit) {
-+	if (base <= limit) {
- 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
- 		res->start = base;
- 		res->end = limit + 0xfff;
-@@ -187,7 +187,7 @@ void __devinit pci_read_bridge_bases(str
- 	pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
- 	base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
- 	limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
--	if (base && base <= limit) {
-+	if (base <= limit) {
- 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
- 		res->start = base;
- 		res->end = limit + 0xfffff;
-@@ -213,7 +213,7 @@ void __devinit pci_read_bridge_bases(str
- 		}
- #endif
- 	}
--	if (base && base <= limit) {
-+	if (base <= limit) {
- 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
- 		res->start = base;
- 		res->end = limit + 0xfffff;
---- linux-2.6.0-test1/drivers/pci/quirks.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/pci/quirks.c	2003-07-19 17:03:50.000000000 -0700
-@@ -33,7 +33,7 @@ static void __devinit quirk_passive_rele
- 	while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
- 		pci_read_config_byte(d, 0x82, &dlc);
- 		if (!(dlc & 1<<1)) {
--			printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", d->slot_name);
-+			printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d));
- 			dlc |= 1<<1;
- 			pci_write_config_byte(d, 0x82, dlc);
- 		}
-@@ -437,7 +437,7 @@ static void __devinit quirk_via_irqpic(s
- 
- 	if (new_irq != irq) {
- 		printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
--		       dev->slot_name, irq, new_irq);
-+		       pci_name(dev), irq, new_irq);
- 
- 		udelay(15);
- 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
-@@ -598,7 +598,7 @@ static void __devinit quirk_ide_bases(st
-                return;
- 
-        printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n",
--              first_bar, last_bar, dev->slot_name);
-+              first_bar, last_bar, pci_name(dev));
- }
- 
- /*
-@@ -856,7 +856,7 @@ static void pci_do_fixups(struct pci_dev
-  		    (f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
-  		    (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
- #ifdef DEBUG
--			printk(KERN_INFO "PCI: Calling quirk %p for %s\n", f->hook, dev->slot_name);
-+			printk(KERN_INFO "PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
- #endif
- 			f->hook(dev);
- 		}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/pci/remove.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,113 @@
-+#include <linux/pci.h>
-+#include <linux/module.h>
-+#include "pci.h"
-+
-+#undef DEBUG
-+
-+#ifdef DEBUG
-+#define DBG(x...) printk(x)
-+#else
-+#define DBG(x...)
-+#endif
-+
-+static void pci_free_resources(struct pci_dev *dev)
-+{
-+	int i;
-+
-+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-+		struct resource *res = dev->resource + i;
-+		if (res->parent)
-+			release_resource(res);
-+	}
-+}
-+
-+static void pci_destroy_dev(struct pci_dev *dev)
-+{
-+	pci_proc_detach_device(dev);
-+	device_unregister(&dev->dev);
-+
-+	/* Remove the device from the device lists, and prevent any further
-+	 * list accesses from this device */
-+	spin_lock(&pci_bus_lock);
-+	list_del(&dev->bus_list);
-+	list_del(&dev->global_list);
-+	dev->bus_list.next = dev->bus_list.prev = NULL;
-+	dev->global_list.next = dev->global_list.prev = NULL;
-+	spin_unlock(&pci_bus_lock);
-+
-+	pci_free_resources(dev);
-+	pci_dev_put(dev);
-+}
-+
-+/**
-+ * pci_remove_device_safe - remove an unused hotplug device
-+ * @dev: the device to remove
-+ *
-+ * Delete the device structure from the device lists and 
-+ * notify userspace (/sbin/hotplug), but only if the device
-+ * in question is not being used by a driver.
-+ * Returns 0 on success.
-+ */
-+int pci_remove_device_safe(struct pci_dev *dev)
-+{
-+	if (pci_dev_driver(dev))
-+		return -EBUSY;
-+	pci_destroy_dev(dev);
-+	return 0;
-+}
-+EXPORT_SYMBOL(pci_remove_device_safe);
-+
-+/**
-+ * pci_remove_bus_device - remove a PCI device and any children
-+ * @dev: the device to remove
-+ *
-+ * Remove a PCI device from the device lists, informing the drivers
-+ * that the device has been removed.  We also remove any subordinate
-+ * buses and children in a depth-first manner.
-+ *
-+ * For each device we remove, delete the device structure from the
-+ * device lists, remove the /proc entry, and notify userspace
-+ * (/sbin/hotplug).
-+ */
-+void pci_remove_bus_device(struct pci_dev *dev)
-+{
-+	if (dev->subordinate) {
-+		struct pci_bus *b = dev->subordinate;
-+
-+		pci_remove_behind_bridge(dev);
-+		pci_proc_detach_bus(b);
-+
-+		spin_lock(&pci_bus_lock);
-+		list_del(&b->node);
-+		spin_unlock(&pci_bus_lock);
-+
-+		kfree(b);
-+		dev->subordinate = NULL;
-+	}
-+
-+	pci_destroy_dev(dev);
-+}
-+
-+/**
-+ * pci_remove_behind_bridge - remove all devices behind a PCI bridge
-+ * @dev: PCI bridge device
-+ *
-+ * Remove all devices on the bus, except for the parent bridge.
-+ * This also removes any child buses, and any devices they may
-+ * contain in a depth-first manner.
-+ */
-+void pci_remove_behind_bridge(struct pci_dev *dev)
-+{
-+	struct list_head *l, *n;
-+
-+	if (dev->subordinate) {
-+		list_for_each_safe(l, n, &dev->subordinate->devices) {
-+			struct pci_dev *dev = pci_dev_b(l);
-+
-+			pci_remove_bus_device(dev);
-+		}
-+	}
-+}
-+
-+EXPORT_SYMBOL(pci_remove_bus_device);
-+EXPORT_SYMBOL(pci_remove_behind_bridge);
---- linux-2.6.0-test1/drivers/pci/setup-bus.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/pci/setup-bus.c	2003-07-19 17:03:50.000000000 -0700
-@@ -81,7 +81,7 @@ pci_setup_cardbus(struct pci_bus *bus)
- 	struct pci_bus_region region;
- 
- 	printk("PCI: Bus %d, cardbus bridge: %s\n",
--		bus->number, bridge->slot_name);
-+		bus->number, pci_name(bridge));
- 
- 	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
- 	if (bus->resource[0]->flags & IORESOURCE_IO) {
-@@ -344,7 +344,7 @@ pbus_size_mem(struct pci_bus *bus, unsig
- 			if (order > 11) {
- 				printk(KERN_WARNING "PCI: region %s/%d "
- 				       "too large: %lx-%lx\n",
--				       dev->slot_name, i, r->start, r->end);
-+				       pci_name(dev), i, r->start, r->end);
- 				r->flags = 0;
- 				continue;
- 			}
-@@ -513,7 +513,7 @@ pci_bus_assign_resources(struct pci_bus 
- 
- 		default:
- 			printk(KERN_INFO "PCI: not setting up bridge %s "
--			       "for bus %d\n", dev->slot_name, b->number);
-+			       "for bus %d\n", pci_name(dev), b->number);
- 			break;
- 		}
- 	}
---- linux-2.6.0-test1/drivers/pci/setup-res.c	2003-06-14 12:18:32.000000000 -0700
-+++ 25/drivers/pci/setup-res.c	2003-07-19 17:03:50.000000000 -0700
-@@ -68,7 +68,7 @@ pci_update_resource(struct pci_dev *dev,
- 
- 	if ((new ^ check) & mask) {
- 		printk(KERN_ERR "PCI: Error while updating region "
--		       "%s/%d (%08x != %08x)\n", dev->slot_name, resno,
-+		       "%s/%d (%08x != %08x)\n", pci_name(dev), resno,
- 		       new, check);
- 	}
- 
-@@ -80,7 +80,7 @@ pci_update_resource(struct pci_dev *dev,
- 		if (check != new) {
- 			printk(KERN_ERR "PCI: Error updating region "
- 			       "%s/%d (high %08x != %08x)\n",
--			       dev->slot_name, resno, new, check);
-+			       pci_name(dev), resno, new, check);
- 		}
- 	}
- }
-@@ -101,7 +101,7 @@ pci_claim_resource(struct pci_dev *dev, 
- 		printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n",
- 		       root ? "Address space collision on" :
- 			      "No parent found for",
--		       resource, dtype, dev->slot_name, res->start, res->end);
-+		       resource, dtype, pci_name(dev), res->start, res->end);
- 	}
- 
- 	return err;
-@@ -139,7 +139,7 @@ int pci_assign_resource(struct pci_dev *
- 
- 	if (ret) {
- 		printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n",
--		       resno, res->start, res->end, dev->slot_name);
-+		       resno, res->start, res->end, pci_name(dev));
- 	} else if (resno < PCI_BRIDGE_RESOURCES) {
- 		pci_update_resource(dev, res, resno);
- 	}
---- linux-2.6.0-test1/drivers/pcmcia/hd64465_ss.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/pcmcia/hd64465_ss.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,5 +1,5 @@
- /*
-- * $Id: 2.6.0-test1-mm2.patch,v 1.1.2.2 2003/07/22 07:20:21 braam Exp $
-+ * $Id: 2.6.0-test1-mm2.patch,v 1.1.2.2 2003/07/22 07:20:21 braam Exp $
-  *
-  * Device driver for the PCMCIA controller module of the
-  * Hitachi HD64465 handheld companion chip.
-@@ -24,7 +24,6 @@
-  *
-  * by Greg Banks <gbanks@pocketpenguins.com>
-  * (c) 2000 PocketPenguins Inc
-- *
-  */
- 
- #include <linux/types.h>
-@@ -37,28 +36,26 @@
- #include <linux/vmalloc.h>
- #include <asm/errno.h>
- #include <linux/irq.h>
--#include <linux/workqueue.h>
-+#include <linux/interrupt.h>
- #include <linux/device.h>
- 
- #include <asm/io.h>
--#include <asm/hd64465.h>
-+#include <asm/hd64465/hd64465.h>
-+#include <asm/hd64465/io.h>
- 
- #include <pcmcia/version.h>
- #include <pcmcia/cs_types.h>
- #include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ds.h>
- #include <pcmcia/ss.h>
- #include <pcmcia/bulkmem.h>
--#include <pcmcia/cistpl.h>
- #include "cs_internal.h"
- 
- #define MODNAME "hd64465_ss"
- 
- /* #define HD64465_DEBUG 1 */
- 
--#ifndef HD64465_DEBUG
--#define HD64465_DEBUG 0
--#endif
--
- #if HD64465_DEBUG
- #define DPRINTK(args...)	printk(MODNAME ": " args)
- #else
-@@ -66,7 +63,8 @@
- #endif
- 
- extern int hd64465_io_debug;
--
-+extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
-+extern void p3_iounmap(void *addr);
- 
- /*============================================================*/
- 
-@@ -74,37 +72,22 @@ extern int hd64465_io_debug;
- 
- typedef struct hs_socket_t
- {
-+    unsigned int	number;
-     u_int   	    	irq;
-     u_long  	    	mem_base;
-+    void		*io_base;
-     u_long  	    	mem_length;
--    void	    	(*handler)(void *info, u_int events);
--    void    	    	*handler_info;
--    u_int   	    	pending_events;
-     u_int   	    	ctrl_base;
-     socket_state_t  	state;
-     pccard_io_map     	io_maps[MAX_IO_WIN];
-     pccard_mem_map  	mem_maps[MAX_WIN];
--    struct vm_struct	*io_vma;    /* allocated kernel vm for mapping IO space */
-+    struct pcmcia_socket	socket;
- } hs_socket_t;
- 
--#define HS_MAX_SOCKETS 2
--static hs_socket_t hs_sockets[HS_MAX_SOCKETS];
--static spinlock_t hs_pending_event_lock = SPIN_LOCK_UNLOCKED;
- 
--/* Calculate socket number from ptr into hs_sockets[] */
--#define hs_sockno(sp) 	(sp - hs_sockets)
- 
--static socket_cap_t hs_socket_cap =
--{
--    SS_CAP_PCCARD   	    /* support 16 bit cards */
--    |SS_CAP_STATIC_MAP      /* mappings are fixed in host memory */
--    ,
--    0xffde/*0xffff*/, 	    /* IRQs mapped in s/w so can do any, really */
--    HD64465_PCC_WINDOW,     /* 16MB fixed window size */
--    0,	    	    	    /* no PCI support */
--    0,	    	    	    /* no CardBus support */
--    0	    	    	    /* no bus operations needed */
--};
-+#define HS_MAX_SOCKETS 2
-+static hs_socket_t hs_sockets[HS_MAX_SOCKETS];
- 
- #define hs_in(sp, r)	    inb((sp)->ctrl_base + (r))
- #define hs_out(sp, v, r)    outb(v, (sp)->ctrl_base + (r))
-@@ -179,7 +162,7 @@ static void hs_socket_enable_ireq(hs_soc
- {
-     	unsigned short cscier;
- 	
--    	DPRINTK("hs_socket_enable_ireq(sock=%d)\n", hs_sockno(sp));
-+    	DPRINTK("hs_socket_enable_ireq(sock=%d)\n", sp->number);
- 
-     	cscier = hs_in(sp, CSCIER);
- 	cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK;
-@@ -191,7 +174,7 @@ static void hs_socket_disable_ireq(hs_so
- {
-     	unsigned short cscier;
- 	
--    	DPRINTK("hs_socket_disable_ireq(sock=%d)\n", hs_sockno(sp));
-+    	DPRINTK("hs_socket_disable_ireq(sock=%d)\n", sp->number);
- 	
-     	cscier = hs_in(sp, CSCIER);
- 	cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK;
-@@ -255,7 +238,7 @@ static struct hw_interrupt_type hd64465_
-  */
- static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
- {
--    	DPRINTK("hs_map_irq(sock=%d irq=%d)\n", hs_sockno(sp), irq);
-+    	DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq);
- 	
- 	if (irq >= HS_NUM_MAPPED_IRQS)
- 	    return;
-@@ -272,7 +255,7 @@ static void hs_map_irq(hs_socket_t *sp, 
-  */
- static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq)
- {
--    	DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", hs_sockno(sp), irq);
-+    	DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq);
- 	
- 	if (irq >= HS_NUM_MAPPED_IRQS)
- 	    return;
-@@ -301,7 +284,7 @@ static int hs_set_voltages(hs_socket_t *
- {
-     	u_int psr;
- 	u_int vcci = 0;
--	u_int sock = hs_sockno(sp);
-+	u_int sock = sp->number;
- 	
-     	DPRINTK("hs_set_voltage(%d, %d, %d)\n", sock, Vcc, Vpp);
- 
-@@ -359,13 +342,12 @@ static void hs_reset_socket(hs_socket_t 
- 
- /*============================================================*/
- 
--static int hs_init(unsigned int sock)
-+static int hs_init(struct pcmcia_socket *s)
- {
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
- 	
--    	DPRINTK("hs_init(%d)\n", sock);
-+    	DPRINTK("hs_init(%d)\n", sp->number);
- 	
--	sp->pending_events = 0;
- 	sp->state.Vcc = 0;
- 	sp->state.Vpp = 0;
- 	hs_set_voltages(sp, 0, 0);
-@@ -375,9 +357,12 @@ static int hs_init(unsigned int sock)
- 
- /*============================================================*/
- 
--static int hs_suspend(unsigned int sock)
-+static int hs_suspend(struct pcmcia_socket *s)
- {
--    	DPRINTK("hs_suspend(%d)\n", sock);
-+#ifdef HD64465_DEBUG
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-+    	DPRINTK("hs_suspend(%d)\n", sp->number);
-+#endif
- 
-     	/* TODO */
- 	
-@@ -386,32 +371,10 @@ static int hs_suspend(unsigned int sock)
- 
- /*============================================================*/
- 
--static int hs_register_callback(unsigned int sock,
--    	    void (*handler)(void *, unsigned int), void * info)
--{
--    	hs_socket_t *sp = &hs_sockets[sock];
--	
--    	DPRINTK("hs_register_callback(%d)\n", sock);
--	sp->handler = handler;
--	sp->handler_info = info;
--	return 0;
--}
--
--/*============================================================*/
- 
--static int hs_inquire_socket(unsigned int sock, socket_cap_t *cap)
-+static int hs_get_status(struct pcmcia_socket *s, u_int *value)
- {
--    	DPRINTK("hs_inquire_socket(%d)\n", sock);
--
--	*cap = hs_socket_cap;
--	return 0;
--}
--
--/*============================================================*/
--
--static int hs_get_status(unsigned int sock, u_int *value)
--{
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-     	unsigned int isr;
- 	u_int status = 0;
- 	
-@@ -473,9 +436,9 @@ static int hs_get_status(unsigned int so
- 
- /*============================================================*/
- 
--static int hs_get_socket(unsigned int sock, socket_state_t *state)
-+static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state)
- {
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
- 
-     	DPRINTK("hs_get_socket(%d)\n", sock);
- 	
-@@ -485,9 +448,9 @@ static int hs_get_socket(unsigned int so
- 
- /*============================================================*/
- 
--static int hs_set_socket(unsigned int sock, socket_state_t *state)
-+static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)
- {
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-     	u_long flags;
- 	u_int changed;
- 	unsigned short cscier;
-@@ -495,12 +458,12 @@ static int hs_set_socket(unsigned int so
-     	DPRINTK("hs_set_socket(sock=%d, flags=%x, csc_mask=%x, Vcc=%d, Vpp=%d, io_irq=%d)\n",
- 	    sock, state->flags, state->csc_mask, state->Vcc, state->Vpp, state->io_irq);
- 	
--	save_and_cli(flags);	/* Don't want interrupts happening here */
-+	local_irq_save(flags);	/* Don't want interrupts happening here */
- 
- 	if (state->Vpp != sp->state.Vpp ||
- 	    state->Vcc != sp->state.Vcc) {
- 	    if (!hs_set_voltages(sp, state->Vcc, state->Vpp)) {
--	    	restore_flags(flags);
-+	    	local_irq_restore(flags);
- 	    	return -EINVAL;
- 	    }
- 	}
-@@ -588,7 +551,7 @@ static int hs_set_socket(unsigned int so
- /*    	hd64465_io_debug = 0; */
- 	sp->state = *state;
- 	    
--	restore_flags(flags);
-+	local_irq_restore(flags);
- 
- #if HD64465_DEBUG > 10
- 	if (state->flags & SS_OUTPUT_ENA)   
-@@ -599,10 +562,11 @@ static int hs_set_socket(unsigned int so
- 
- /*============================================================*/
- 
--static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io)
-+static int hs_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
- {
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
- 	int map = io->map;
-+	int sock = sp->number;
- 	struct pccard_io_map *sio;
- 	pgprot_t prot;
- 
-@@ -639,10 +603,9 @@ static int hs_set_io_map(unsigned int so
- 	    printk(KERN_INFO MODNAME ": MAP_0WS unimplemented\n");
- 
- 	if (io->flags & MAP_ACTIVE) {
--	    unsigned long pstart, psize, paddrbase, vaddrbase;
-+	    unsigned long pstart, psize, paddrbase;
- 	    
- 	    paddrbase = virt_to_phys((void*)(sp->mem_base + 2 * HD64465_PCC_WINDOW));
--	    vaddrbase = (unsigned long)sp->io_vma->addr;
- 	    pstart = io->start & PAGE_MASK;
- 	    psize = ((io->stop + PAGE_SIZE) & PAGE_MASK) - pstart;
- 
-@@ -653,26 +616,17 @@ static int hs_set_io_map(unsigned int so
- 	     * page will be mapped.  But the code allows for weird cards
- 	     * that might want IO ports > 4K.
- 	     */
--	    DPRINTK("remap_page_range(vaddr=0x%08lx, paddr=0x%08lx, size=0x%08lxx)\n",
--	    	vaddrbase + pstart, paddrbase + pstart, psize);
--#error This does not work.  Firstly remap_page_range() uses current->mm for
--#error the address space, which is wrong for kernel mappings.  remap_page_range
--#error also does flush_{cache,tlb}_range() which ONLY works for user mappings.
--#error Next, remap_page_range() now wants to take a vm_area_struct arg.
--	    remap_page_range(vaddrbase + pstart, paddrbase + pstart, psize, prot);
-+	    sp->io_base = p3_ioremap(paddrbase + pstart, psize, pgprot_val(prot));
- 	    
- 	    /*
- 	     * Change the mapping used by inb() outb() etc
- 	     */
--	    hd64465_port_map(
--	    	io->start,
-+	    hd64465_port_map(io->start,
- 		io->stop - io->start + 1,
--	    	vaddrbase + io->start,0);
-+	    	(unsigned long)sp->io_base + io->start, 0);
- 	} else {
--	    hd64465_port_unmap(
--	    	sio->start,
--		sio->stop - sio->start + 1);
--	    /* TODO: remap_page_range() to mark pages not present ? */
-+	    hd64465_port_unmap(sio->start, sio->stop - sio->start + 1);
-+	    p3_iounmap(sp->io_base);
- 	}
- 	
- 	*sio = *io;
-@@ -681,9 +635,9 @@ static int hs_set_io_map(unsigned int so
- 
- /*============================================================*/
- 
--static int hs_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
-+static int hs_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
- {
--    	hs_socket_t *sp = &hs_sockets[sock];
-+    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
- 	struct pccard_mem_map *smem;
- 	int map = mem->map;
- 	unsigned long paddr, size;
-@@ -722,13 +676,6 @@ static int hs_set_mem_map(unsigned int s
- 
- /*============================================================*/
- 
--static void hs_proc_setup(unsigned int sock, struct proc_dir_entry *base)
--{
--    	DPRINTK("hs_proc_setup(%d)\n", sock);
--}
--
--/*============================================================*/
--
- /*
-  * This function is registered with the HD64465 glue code to do a
-  * secondary demux step on the PCMCIA interrupts.  It handles 
-@@ -756,35 +703,9 @@ static int hs_irq_demux(int irq, void *d
- 
- /*
-  * Interrupt handling routine.
-- *
-- * This uses the schedule_work() technique to cause reportable events
-- * such as card insertion and removal to be handled in keventd's
-- * process context.
-  */
-  
--
--static void hs_events_bh(void *dummy)
--{
--	hs_socket_t *sp;
--	u_int events;
--	int i;
--
--	for (i=0; i<HS_MAX_SOCKETS; i++) {
--	    sp = &hs_sockets[i];
--
--	    spin_lock_irq(&hs_pending_event_lock);
--	    events = sp->pending_events;
--	    sp->pending_events = 0;
--	    spin_unlock_irq(&hs_pending_event_lock);
--	    
--	    if (sp->handler)
--		sp->handler(sp->handler_info, events);
--	}
--}
--
--static DECLARE_WORK(hs_events_task, hs_events_bh, NULL);
--
--static void hs_interrupt(int irq, void *dev, struct pt_regs *regs)
-+static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs)
- {
-     	hs_socket_t *sp = (hs_socket_t *)dev;
- 	u_int events = 0;
-@@ -801,7 +722,7 @@ static void hs_interrupt(int irq, void *
- 	    if ((hs_in(sp, ISR) & HD64465_PCCISR_PCD_MASK) != 0) {
- 	    	printk(KERN_NOTICE MODNAME
- 		    ": socket %d, card not a supported card type or not inserted correctly\n",
--		    hs_sockno(sp));
-+		    sp->number);
- 		/* Don't do the rest unless a card is present */
- 		cscr &= ~(HD64465_PCCCSCR_PCDC|
- 		    	  HD64465_PCCCSCR_PRC|
-@@ -839,34 +760,22 @@ static void hs_interrupt(int irq, void *
- 
- 	hs_out(sp, cscr, CSCR);
- 
--	if (events) {
--	    /*
--    	     * Arrange for events to be reported to the registered
--	     * event handler function (from CardServices) in a process
--	     * context (keventd) "soon".
--	     */
--	    spin_lock(&hs_pending_event_lock);
--	    sp->pending_events |= events;
--	    spin_unlock(&hs_pending_event_lock);
--	    
--	    schedule_work(&hs_events_task);
--	}
-+	if (events)
-+		pcmcia_parse_events(&sp->socket, events);
-+
-+	return IRQ_HANDLED;
- }
- 
- /*============================================================*/
- 
- static struct pccard_operations hs_operations = {
--	.owner			= THIS_MODULE,
- 	.init			= hs_init,
- 	.suspend		= hs_suspend,
--	.register_callback	= hs_register_callback,
--	.inquire_socket		= hs_inquire_socket,
- 	.get_status		= hs_get_status,
- 	.get_socket		= hs_get_socket,
- 	.set_socket		= hs_set_socket,
- 	.set_io_map		= hs_set_io_map,
- 	.set_mem_map		= hs_set_mem_map,
--	.proc_setup		= hs_proc_setup,
- };
- 
- static int hs_init_socket(hs_socket_t *sp, int irq, unsigned long mem_base,
-@@ -886,9 +795,6 @@ static int hs_init_socket(hs_socket_t *s
- 	for (i=0 ; i<MAX_WIN ; i++)
- 	    sp->mem_maps[i].map = i;
- 	
--	if ((sp->io_vma = get_vm_area(HS_IO_MAP_SIZE, VM_IOREMAP)) == 0)
--	    return -ENOMEM;
--
- 	hd64465_register_irq_demux(sp->irq, hs_irq_demux, sp);
- 	
-     	if ((err = request_irq(sp->irq, hs_interrupt, SA_INTERRUPT, MODNAME, sp)) < 0)
-@@ -925,9 +831,8 @@ static int hs_init_socket(hs_socket_t *s
- 	
- 	hs_reset_socket(sp, 1);
- 
--	printk(KERN_INFO "HD64465 PCMCIA bridge socket %d at 0x%08lx irq %d io window %ldK@0x%08lx\n",
--	    	i, sp->mem_base, sp->irq,
--		sp->io_vma->size>>10, (unsigned long)sp->io_vma->addr);
-+	printk(KERN_INFO "HD64465 PCMCIA bridge socket %d at 0x%08lx irq %d\n",
-+	    	i, sp->mem_base, sp->irq);
- 
-     	return 0;
- }
-@@ -935,7 +840,10 @@ static int hs_init_socket(hs_socket_t *s
- static void hs_exit_socket(hs_socket_t *sp)
- {
-     	unsigned short cscier, gcr;
-+	unsigned long flags;
- 	
-+	local_irq_save(flags);
-+
- 	/* turn off interrupts in hardware */
-     	cscier = hs_in(sp, CSCIER);
- 	cscier = (cscier & IER_MASK) | IER_OFF;
-@@ -955,19 +863,13 @@ static void hs_exit_socket(hs_socket_t *
- 	    free_irq(sp->irq, hs_interrupt);
-     	    hd64465_unregister_irq_demux(sp->irq);
- 	}
--	if (sp->io_vma != 0)
--	    vfree(sp->io_vma->addr);
--}
- 
--static struct pcmcia_socket_class_data hd64465_data = {
--	.nsock = HS_MAX_SOCKETS,
--	.ops = &hs_operations,
--};
-+	local_irq_restore(flags);
-+}
- 
- static struct device_driver hd64465_driver = {
- 	.name = "hd64465-pcmcia",
- 	.bus = &platform_bus_type,
--	.devclass = &pcmcia_socket_class,
- 	.suspend = pcmcia_socket_dev_suspend,
- 	.resume = pcmcia_socket_dev_resume,
- };
-@@ -996,7 +898,8 @@ static int __init init_hs(void)
- 	}
- 
- /*	hd64465_io_debug = 1; */
--	register_driver(&hd64465_driver);
-+	if (driver_register(&hd64465_driver))
-+		return -EINVAL;
- 	
- 	/* Wake both sockets out of STANDBY mode */
- 	/* TODO: wait 15ms */
-@@ -1014,14 +917,22 @@ static int __init init_hs(void)
- 	v |= HD64465_PCCCSCR_PSWSEL;
- 	outb(v, HD64465_REG_PCC0CSCR);
- 
--    	hs_set_voltages(&hs_sockets[0], 0, 0);
--    	hs_set_voltages(&hs_sockets[1], 0, 0);
--	
- 	/*
- 	 * Setup hs_sockets[] structures and request system resources.
- 	 * TODO: on memory allocation failure, power down the socket
- 	 *       before quitting.
- 	 */
-+	for (i=0; i<HS_MAX_SOCKETS; i++) {
-+		hs_set_voltages(&hs_sockets[i], 0, 0);
-+
-+		hs_sockets[i].socket.features |=  SS_CAP_PCCARD | SS_CAP_STATIC_MAP;      /* mappings are fixed in host memory */
-+		hs_sockets[i].socket.irq_mask =  0xffde;/*0xffff*/	    /* IRQs mapped in s/w so can do any, really */
-+		hs_sockets[i].socket.map_size = HD64465_PCC_WINDOW;     /* 16MB fixed window size */
-+
-+		hs_sockets[i].socket.owner = THIS_MODULE;
-+		hs_sockets[i].socket.ss_entry = &hs_operations;
-+	}
-+
- 	i = hs_init_socket(&hs_sockets[0],
- 	    HD64465_IRQ_PCMCIA0,
- 	    HD64465_PCC0_BASE,
-@@ -1040,27 +951,31 @@ static int __init init_hs(void)
- 	}
- 
- /*	hd64465_io_debug = 0; */
--	hd64465_device.dev.class_data = &hd64465_data;
-+
- 	platform_device_register(&hd64465_device);
- 
--	return 0;
-+	for (i=0; i<HS_MAX_SOCKETS; i++) {
-+		unsigned int ret;
-+		hs_sockets[i].socket.dev.dev = &hd64465_device.dev;		
-+		hs_sockets[i].number = i;
-+		ret = pcmcia_register_socket(&hs_sockets[i].socket);
-+		if (ret && i)
-+			pcmcia_unregister_socket(&hs_sockets[0].socket);
-+	}
-+
-+    	return 0;
- }
- 
- static void __exit exit_hs(void)
- {
--    	u_long flags;
- 	int i;
--	
--	save_and_cli(flags);
- 
--    	/*
--	 * Release kernel resources
--	 */
--	for (i=0 ; i<HS_MAX_SOCKETS ; i++)
--	    hs_exit_socket(&hs_sockets[i]);
-+	for (i=0 ; i<HS_MAX_SOCKETS ; i++) {
-+		pcmcia_unregister_socket(&hs_sockets[i].socket);
-+		hs_exit_socket(&hs_sockets[i]);
-+	}
-+
- 	platform_device_unregister(&hd64465_device);
--	
--	restore_flags(flags);
- 	unregister_driver(&hd64465_driver);
- }
- 
---- linux-2.6.0-test1/drivers/pcmcia/ricoh.h	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/pcmcia/ricoh.h	2003-07-19 17:03:50.000000000 -0700
-@@ -116,6 +116,8 @@
- #define  RL5C4XX_CMD_SHIFT		4
- #define  RL5C4XX_HOLD_MASK		0x1c00
- #define  RL5C4XX_HOLD_SHIFT		10
-+#define  RL5C4XX_MISC_CONTROL           0x2F /* 8 bit */
-+#define  RL5C4XX_ZV_ENABLE              0x08
- 
- #ifdef __YENTA_H
- 
-@@ -125,10 +127,41 @@
- #define rl_mem(socket)		((socket)->private[3])
- #define rl_config(socket)	((socket)->private[4])
- 
-+static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff)
-+{
-+        u8 reg;
-+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-+
-+        reg = config_readb(socket, RL5C4XX_MISC_CONTROL);
-+        if (onoff)
-+                /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */
-+                reg |=  RL5C4XX_ZV_ENABLE;
-+        else
-+                reg &= ~RL5C4XX_ZV_ENABLE;
-+	
-+        config_writeb(socket, RL5C4XX_MISC_CONTROL, reg);
-+}
-+
-+static void ricoh_set_zv(struct pcmcia_socket *sock)
-+{
-+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-+        if(socket->dev->vendor == PCI_VENDOR_ID_RICOH)
-+        {
-+                switch(socket->dev->device)
-+                {
-+                        /* There may be more .. */
-+		case  PCI_DEVICE_ID_RICOH_RL5C478:
-+			sock->zoom_video = ricoh_zoom_video;
-+			break;  
-+                }
-+        }
-+}
-+
- static int ricoh_init(struct pcmcia_socket *sock)
- {
- 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- 	yenta_init(sock);
-+	ricoh_set_zv(sock);
- 
- 	config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
- 	config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
---- linux-2.6.0-test1/drivers/pcmcia/ti113x.h	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/pcmcia/ti113x.h	2003-07-19 17:03:50.000000000 -0700
-@@ -148,14 +148,96 @@ static int ti_intctl(struct yenta_socket
- 	return 0;
- }
- 
-+/*
-+ *	Zoom video control for TI122x/113x chips
-+ */
-+
-+static void ti_zoom_video(struct pcmcia_socket *sock, int onoff)
-+{
-+	u8 reg;
-+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-+
-+	/* If we don't have a Zoom Video switch this is harmless,
-+	   we just tristate the unused (ZV) lines */
-+	reg = config_readb(socket, TI113X_CARD_CONTROL);
-+	if (onoff)
-+		/* Zoom zoom, we will all go together, zoom zoom, zoom zoom */
-+		reg |= TI113X_CCR_ZVENABLE;
-+	else
-+		reg &= ~TI113X_CCR_ZVENABLE;
-+	config_writeb(socket, TI113X_CARD_CONTROL, reg);
-+}
-+
-+/*
-+ *	The 145x series can also use this. They have an additional
-+ *	ZV autodetect mode we don't use but don't actually need.
-+ *	FIXME: manual says its in func0 and func1 but disagrees with
-+ *	itself about this - do we need to force func0, if so we need
-+ *	to know a lot more about socket pairings in pcmcia_socket than
-+ *	we do now.. uggh.
-+ */
-+ 
-+static void ti1250_zoom_video(struct pcmcia_socket *sock, int onoff)
-+{	
-+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-+	int shift = 0;
-+	u8 reg;
-+
-+	ti_zoom_video(sock, onoff);
-+
-+	reg = config_readb(socket, 0x84);
-+	reg |= (1<<7);	/* ZV bus enable */
-+
-+	if(PCI_FUNC(socket->dev->devfn)==1)
-+		shift = 1;
-+	
-+	if(onoff)
-+	{
-+		reg &= ~(1<<6); 	/* Clear select bit */
-+		reg |= shift<<6;	/* Favour our socket */
-+		reg |= 1<<shift;	/* Socket zoom video on */
-+	}
-+	else
-+	{
-+		reg &= ~(1<<6); 	/* Clear select bit */
-+		reg |= (1^shift)<<6;	/* Favour other socket */
-+		reg &= ~(1<<shift);	/* Socket zoon video off */
-+	}
-+
-+	config_writeb(socket, 0x84, reg);
-+}
-+
-+static void ti_set_zv(struct pcmcia_socket *sock)
-+{
-+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-+	if(socket->dev->vendor == PCI_VENDOR_ID_TI)
-+	{
-+		switch(socket->dev->device)
-+		{
-+			/* There may be more .. */
-+			case PCI_DEVICE_ID_TI_1220:
-+			case PCI_DEVICE_ID_TI_1221:
-+			case PCI_DEVICE_ID_TI_1225:
-+				sock->zoom_video = ti_zoom_video;
-+				break;	
-+			case PCI_DEVICE_ID_TI_1250:
-+			case PCI_DEVICE_ID_TI_1251A:
-+			case PCI_DEVICE_ID_TI_1251B:
-+			case PCI_DEVICE_ID_TI_1450:
-+				sock->zoom_video = ti1250_zoom_video;
-+		}
-+	}
-+}
- static int ti_init(struct pcmcia_socket *sock)
- {
- 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- 	yenta_init(sock);
-+	ti_set_zv(sock);
- 	ti_intctl(socket);
- 	return 0;
- }
- 
-+
- /*
-  * Generic TI init - TI has an extension for the
-  * INTCTL register that sets the PCI CSC interrupt.
-@@ -176,9 +258,6 @@ static int ti_override(struct yenta_sock
- 	if (new != reg)
- 		exca_writeb(socket, I365_INTCTL, new);
- 
--#if 0
--	/* THIS CAUSES HANGS! Disabled for now, do not know why */
--
- 	/*
- 	 * If ISA interrupts don't work, then fall back to routing card
- 	 * interrupts to the PCI interrupt of the socket.
-@@ -190,7 +269,7 @@ static int ti_override(struct yenta_sock
- 		u8 irqmux, devctl;
- 
- 		devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
--		if (devctl & TI113X_DCR_IMODE_MASK != TI12XX_DCR_IMODE_ALL_SERIAL) {
-+		if ((devctl & TI113X_DCR_IMODE_MASK) != TI12XX_DCR_IMODE_ALL_SERIAL) {
- 			printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n");
- 
- 			devctl &= ~TI113X_DCR_IMODE_MASK;
-@@ -203,7 +282,6 @@ static int ti_override(struct yenta_sock
- 			config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
- 		}
- 	}
--#endif
- 
- 	socket->socket.ops->init = ti_init;
- 	return 0;
-@@ -220,6 +298,7 @@ static int ti113x_init(struct pcmcia_soc
- {
- 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- 	yenta_init(sock);
-+	ti_set_zv(sock);
- 
- 	config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket));
- 	config_writeb(socket, TI113X_CARD_CONTROL, ti_cardctl(socket));
-@@ -248,6 +327,7 @@ static int ti1250_init(struct pcmcia_soc
- 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- 	yenta_init(sock);
- 	ti113x_init(sock);
-+	ti_set_zv(sock);
- 	ti_irqmux(socket) = config_readl(socket, TI122X_IRQMUX);
- 	ti_irqmux(socket) = (ti_irqmux(socket) & ~0x0f) | 0x02; /* route INTA */
- 	if (!(ti_sysctl(socket) & TI122X_SCR_INTRTIE))
---- linux-2.6.0-test1/drivers/pcmcia/yenta_socket.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/pcmcia/yenta_socket.c	2003-07-19 17:03:50.000000000 -0700
-@@ -297,6 +297,8 @@ static int yenta_set_socket(struct pcmci
- 		}
- 		exca_writeb(socket, I365_CSCINT, reg);
- 		exca_readb(socket, I365_CSC);
-+		if(sock->zoom_video)
-+			sock->zoom_video(sock, state->flags & SS_ZVCARD);
- 	}
- 	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
- 	/* Socket event mask: get card insert/remove events.. */
---- linux-2.6.0-test1/drivers/pnp/isapnp/core.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/pnp/isapnp/core.c	2003-07-19 17:03:50.000000000 -0700
-@@ -255,14 +255,22 @@ static void __init isapnp_peek(unsigned 
- static int isapnp_next_rdp(void)
- {
- 	int rdp = isapnp_rdp;
-+	static int old_rdp = 0;
-+	
-+	if(old_rdp)
-+	{
-+		release_region(old_rdp, 1);
-+		old_rdp = 0;
-+	}
- 	while (rdp <= 0x3ff) {
- 		/*
- 		 *	We cannot use NE2000 probe spaces for ISAPnP or we
- 		 *	will lock up machines.
- 		 */
--		if ((rdp < 0x280 || rdp >  0x380) && !check_region(rdp, 1))
-+		if ((rdp < 0x280 || rdp >  0x380) && request_region(rdp, 1, "ISAPnP"))
- 		{
- 			isapnp_rdp = rdp;
-+			old_rdp = rdp;
- 			return 0;
- 		}
- 		rdp += RDP_STEP;
---- linux-2.6.0-test1/drivers/s390/block/dasd.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/s390/block/dasd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -16,7 +16,6 @@
- #include <linux/interrupt.h>
- #include <linux/ctype.h>
- #include <linux/major.h>
--#include <linux/blk.h>
- #include <linux/slab.h>
- #include <linux/buffer_head.h>
- 
---- linux-2.6.0-test1/drivers/s390/block/dasd_genhd.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/s390/block/dasd_genhd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
-  *
-  * Dealing with devices registered to multiple major numbers.
-  *
-- * $Revision: 1.1.2.2 $
-+ * $Revision: 1.1.2.2 $
-  */
- 
- #include <linux/config.h>
-@@ -17,7 +17,6 @@
- #include <linux/interrupt.h>
- #include <linux/fs.h>
- #include <linux/blkpg.h>
--#include <linux/blk.h>
- 
- #include <asm/uaccess.h>
- 
-@@ -200,7 +199,6 @@ void
- dasd_destroy_partitions(struct dasd_device * device)
- {
- 	del_gendisk(device->gdp);
--	put_disk(device->gdp);
- }
- 
- int
---- linux-2.6.0-test1/drivers/s390/block/dasd_int.h	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/s390/block/dasd_int.h	2003-07-19 17:06:39.000000000 -0700
-@@ -14,7 +14,8 @@
- 
- #ifdef __KERNEL__
- 
--#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
-+#define DASD_MINORBITS 8
-+#define DASD_PER_MAJOR ( 1U<<(DASD_MINORBITS-DASD_PARTN_BITS))
- #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
- 
- /*
---- linux-2.6.0-test1/drivers/s390/block/dasd_ioctl.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/s390/block/dasd_ioctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -14,7 +14,6 @@
- #include <linux/major.h>
- #include <linux/fs.h>
- #include <linux/blkpg.h>
--#include <linux/blk.h>
- 
- #include <asm/ccwdev.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/drivers/s390/block/xpram.c	2003-07-02 14:53:14.000000000 -0700
-+++ 25/drivers/s390/block/xpram.c	2003-07-19 17:03:50.000000000 -0700
-@@ -31,7 +31,6 @@
- #include <linux/errno.h>
- #include <linux/init.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
- #include <linux/blkpg.h>
- #include <linux/hdreg.h>  /* HDIO_GETGEO */
- #include <linux/sysdev.h>
---- linux-2.6.0-test1/drivers/s390/char/sclp.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/s390/char/sclp.c	2003-07-19 17:04:07.000000000 -0700
-@@ -468,17 +468,17 @@ static struct sclp_register sclp_state_c
-  * SCLP quiesce event handler
-  */
- #ifdef CONFIG_SMP
--static volatile unsigned long cpu_quiesce_map;
-+static cpumask_t cpu_quiesce_map;
- 
- static void
- do_load_quiesce_psw(void * __unused)
- {
- 	psw_t quiesce_psw;
- 
--	clear_bit(smp_processor_id(), &cpu_quiesce_map);
-+	cpu_clear(smp_processor_id(), cpu_quiesce_map);
- 	if (smp_processor_id() == 0) {
- 		/* Wait for all other cpus to enter do_load_quiesce_psw */
--		while (cpu_quiesce_map != 0);
-+		while (!cpus_empty(cpu_quiesce_map));
- 		/* Quiesce the last cpu with the special psw */
- 		quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
- 		quiesce_psw.addr = 0xfff;
---- linux-2.6.0-test1/drivers/s390/char/tape_block.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/s390/char/tape_block.c	2003-07-19 17:03:50.000000000 -0700
-@@ -13,7 +13,6 @@
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/blkdev.h>
--#include <linux/blk.h>
- #include <linux/interrupt.h>
- #include <linux/buffer_head.h>
- 
---- linux-2.6.0-test1/drivers/s390/cio/chsc.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/cio/chsc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  *  drivers/s390/cio/chsc.c
-  *   S/390 common I/O routines -- channel subsystem call
-- *   $Revision: 1.1.2.2 $
-+ *   $Revision: 1.1.2.2 $
-  *
-  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
-  *			      IBM Corporation
-@@ -206,6 +206,7 @@ chsc_get_sch_descriptions(void)
- 	if (!page)
- 		return -ENOMEM;
- 
-+	err = 0;
- 	for (irq = 0; irq <= highest_subchannel; irq++) {
- 		/*
- 		 * retrieve information for each sch
-@@ -222,13 +223,14 @@ chsc_get_sch_descriptions(void)
- 				       "not work\n", err);
- 				cio_chsc_err_msg = 1;
- 			}
--			return err;
-+			goto out;
- 		}
- 		clear_page(page);
- 	}
- 	cio_chsc_desc_avail = 1;
-+out:
- 	free_page((unsigned long)page);
--	return 0;
-+	return err;
- }
- 
- __initcall(chsc_get_sch_descriptions);
-@@ -428,7 +430,7 @@ s390_process_res_acc (u8 chpid, __u16 fl
- 			ret = css_probe_device(irq);
- 			if (ret == -ENXIO)
- 				/* We're through */
--				return;
-+				break;
- 			continue;
- 		}
- 	
---- linux-2.6.0-test1/drivers/s390/cio/cio.c	2003-06-14 12:18:48.000000000 -0700
-+++ 25/drivers/s390/cio/cio.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  *  drivers/s390/cio/cio.c
-  *   S/390 common I/O routines -- low level i/o calls
-- *   $Revision: 1.1.2.2 $
-+ *   $Revision: 1.1.2.2 $
-  *
-  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
-  *			      IBM Corporation
-@@ -16,10 +16,12 @@
- #include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/device.h>
-+#include <linux/kernel_stat.h>
- 
- #include <asm/hardirq.h>
- #include <asm/cio.h>
- #include <asm/delay.h>
-+#include <asm/irq.h>
- 
- #include "airq.h"
- #include "cio.h"
-@@ -442,6 +444,11 @@ cio_enable_subchannel (struct subchannel
- 			if (sch->schib.pmcw.ena)
- 				break;
- 		}
-+		if (ret == -EBUSY) {
-+			struct irb irb;
-+			if (tsch(sch->irq, &irb) != 0)
-+				break;
-+		}
- 	}
- 	sprintf (dbf_txt, "ret:%d", ret);
- 	CIO_TRACE_EVENT (2, dbf_txt);
-@@ -608,6 +615,7 @@ do_IRQ (struct pt_regs regs)
- 	tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
- 	irb = (struct irb *) __LC_IRB;
- 	do {
-+		kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
- 		/*
- 		 * Non I/O-subchannel thin interrupts are processed differently
- 		 */
---- linux-2.6.0-test1/drivers/s390/cio/device.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/cio/device.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  *  drivers/s390/cio/device.c
-  *  bus driver for ccw devices
-- *   $Revision: 1.1.2.2 $
-+ *   $Revision: 1.1.2.2 $
-  *
-  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
-  *			 IBM Corporation
-@@ -434,6 +434,13 @@ ccw_device_register(struct ccw_device *c
- 	return ret;
- }
- 
-+void
-+ccw_device_unregister(void *data)
-+{
-+	device_unregister((struct device *)data);
-+}
-+	
-+
- static void
- ccw_device_release(struct device *dev)
- {
-@@ -513,17 +520,11 @@ io_subchannel_recog_done(struct ccw_devi
- 		wake_up(&ccw_device_init_wq);
- }
- 
--static void
-+static int
- io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
- {
- 	int rc;
- 
--	if (!get_device(&sch->dev)) {
--		if (cdev->dev.release)
--			cdev->dev.release(&cdev->dev);
--		return;
--	}
--
- 	sch->dev.driver_data = cdev;
- 	sch->driver = &io_subchannel_driver;
- 	cdev->ccwlock = &sch->lock;
-@@ -540,9 +541,6 @@ io_subchannel_recog(struct ccw_device *c
- 	snprintf (cdev->dev.bus_id, DEVICE_ID_SIZE, "0:%04x",
- 		  sch->schib.pmcw.dev);
- 
--	/* Do first half of device_register. */
--	device_initialize(&cdev->dev);
--
- 	/* Increase counter of devices currently in recognition. */
- 	atomic_inc(&ccw_device_init_count);
- 
-@@ -551,13 +549,10 @@ io_subchannel_recog(struct ccw_device *c
- 	rc = ccw_device_recognition(cdev);
- 	spin_unlock_irq(cdev->ccwlock);
- 	if (rc) {
--		sch->dev.driver_data = 0;
--		put_device(&sch->dev);
--		if (cdev->dev.release)
--			cdev->dev.release(&cdev->dev);
- 		if (atomic_dec_and_test(&ccw_device_init_count))
- 			wake_up(&ccw_device_init_wq);
- 	}
-+	return rc;
- }
- 
- static int
-@@ -565,6 +560,7 @@ io_subchannel_probe (struct device *pdev
- {
- 	struct subchannel *sch;
- 	struct ccw_device *cdev;
-+	int rc;
- 
- 	sch = to_subchannel(pdev);
- 	if (sch->dev.driver_data) {
-@@ -573,8 +569,20 @@ io_subchannel_probe (struct device *pdev
- 		 * Register it and exit. This happens for all early
- 		 * device, e.g. the console.
- 		 */
--		ccw_device_register(sch->dev.driver_data);
-+		cdev = sch->dev.driver_data;
-+		device_initialize(&cdev->dev);
-+		ccw_device_register(cdev);
- 		subchannel_add_files(&sch->dev);
-+		/*
-+		 * Check if the device is already online. If it is
-+		 * the reference count needs to be corrected
-+		 * (see ccw_device_online and css_init_done for the
-+		 * ugly details).
-+		 */
-+		if (cdev->private->state != DEV_STATE_NOT_OPER &&
-+		    cdev->private->state != DEV_STATE_OFFLINE &&
-+		    cdev->private->state != DEV_STATE_BOXED)
-+			get_device(&cdev->dev);
- 		return 0;
- 	}
- 	cdev  = kmalloc (sizeof(*cdev), GFP_KERNEL);
-@@ -592,7 +600,23 @@ io_subchannel_probe (struct device *pdev
- 		.parent = pdev,
- 		.release = ccw_device_release,
- 	};
--	io_subchannel_recog(cdev, to_subchannel(pdev));
-+	/* Do first half of device_register. */
-+	device_initialize(&cdev->dev);
-+
-+	if (!get_device(&sch->dev)) {
-+		if (cdev->dev.release)
-+			cdev->dev.release(&cdev->dev);
-+		return 0;
-+	}
-+
-+	rc = io_subchannel_recog(cdev, to_subchannel(pdev));
-+	if (rc) {
-+		sch->dev.driver_data = 0;
-+		put_device(&sch->dev);
-+		if (cdev->dev.release)
-+			cdev->dev.release(&cdev->dev);
-+	}
-+
- 	return 0;
- }
- 
-@@ -604,6 +628,8 @@ static int console_cdev_in_use;
- static int
- ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)
- {
-+	int rc;
-+
- 	/* Initialize the ccw_device structure. */
- 	cdev->dev = (struct device) {
- 		.parent = &sch->dev,
-@@ -613,7 +639,11 @@ ccw_device_console_enable (struct ccw_de
- 		.parent = &css_bus_device,
- 		.bus	= &css_bus_type,
- 	};
--	io_subchannel_recog(cdev, sch);
-+
-+	rc = io_subchannel_recog(cdev, sch);
-+	if (rc)
-+		return rc;
-+
- 	/* Now wait for the async. recognition to come to an end. */
- 	while (!dev_fsm_final_state(cdev))
- 		wait_cons_dev();
---- linux-2.6.0-test1/drivers/s390/cio/device_fsm.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/cio/device_fsm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -188,7 +188,7 @@ ccw_device_done(struct ccw_device *cdev,
- 
- 	wake_up(&cdev->private->wait_q);
- 
--	if (state != DEV_STATE_ONLINE)
-+	if (css_init_done && state != DEV_STATE_ONLINE)
- 		put_device (&cdev->dev);
- }
- 
-@@ -293,7 +293,7 @@ ccw_device_online(struct ccw_device *cde
- 	if (cdev->private->state != DEV_STATE_OFFLINE)
- 		return -EINVAL;
- 	sch = to_subchannel(cdev->dev.parent);
--	if (!get_device(&cdev->dev))
-+	if (css_init_done && !get_device(&cdev->dev))
- 		return -ENODEV;
- 	if (cio_enable_subchannel(sch, sch->schib.pmcw.isc) != 0) {
- 		/* Couldn't enable the subchannel for i/o. Sick device. */
-@@ -384,7 +384,9 @@ static void
- ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
- {
- 	cdev->private->state = DEV_STATE_NOT_OPER;
--	device_unregister(&cdev->dev);
-+	INIT_WORK(&cdev->private->kick_work,
-+		  ccw_device_unregister, (void *) &cdev->dev);
-+	queue_work(ccw_device_work, &cdev->private->kick_work);
- 	wake_up(&cdev->private->wait_q);
- }
- 
-@@ -403,8 +405,10 @@ ccw_device_online_notoper(struct ccw_dev
- 		// FIXME: not-oper indication to device driver ?
- 		ccw_device_call_handler(cdev);
- 	}
-+	INIT_WORK(&cdev->private->kick_work,
-+		  ccw_device_unregister, (void *) &cdev->dev);
-+	queue_work(ccw_device_work, &cdev->private->kick_work);
- 	wake_up(&cdev->private->wait_q);
--	device_unregister(&cdev->dev);
- }
- 
- /*
---- linux-2.6.0-test1/drivers/s390/cio/device.h	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/cio/device.h	2003-07-19 17:03:50.000000000 -0700
-@@ -65,6 +65,8 @@ extern struct workqueue_struct *ccw_devi
- 
- void io_subchannel_recog_done(struct ccw_device *cdev);
- 
-+void ccw_device_unregister(void *);
-+
- int ccw_device_recognition(struct ccw_device *);
- int ccw_device_online(struct ccw_device *);
- int ccw_device_offline(struct ccw_device *);
---- linux-2.6.0-test1/drivers/s390/cio/qdio.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/cio/qdio.c	2003-07-19 17:03:50.000000000 -0700
-@@ -55,7 +55,7 @@
- #include "ioasm.h"
- #include "chsc.h"
- 
--#define VERSION_QDIO_C "$Revision: 1.1.2.2 $"
-+#define VERSION_QDIO_C "$Revision: 1.1.2.2 $"
- 
- /****************** MODULE PARAMETER VARIABLES ********************/
- MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
-@@ -1643,6 +1643,7 @@ qdio_timeout_handler(struct ccw_device *
- 	default:
- 		BUG();
- 	}
-+	ccw_device_set_timeout(cdev, 0);
- 	wake_up(&cdev->private->wait_q);
- 
- }
-@@ -1891,26 +1892,25 @@ tiqdio_check_chsc_availability(void)
- 		result=-EIO;
- 		goto exit;
- 	}
--	/* 4: request block
--	 * 2: general char
--	 * 512: chsc char */
--	if ((scsc_area->general_char[1] & 0x00800000) != 0x00800000) {
-+	/* Check for bit 41. */
-+	if ((scsc_area->general_char[1] & 0x00400000) != 0x00400000) {
- 		QDIO_PRINT_WARN("Adapter interruption facility not " \
- 				"installed.\n");
- 		result=-ENOENT;
- 		goto exit;
- 	}
--	if ((scsc_area->chsc_char[2] & 0x00180000) != 0x00180000) {
-+	/* Check for bits 107 and 108. */
-+	if ((scsc_area->chsc_char[3] & 0x00180000) != 0x00180000) {
- 		QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
- 				"not available.\n");
- 		result=-ENOENT;
- 		goto exit;
- 	}
- 
--	/* Check for hydra thin interrupts. */
-+	/* Check for hydra thin interrupts (bit 67). */
- 	hydra_thinints = ((scsc_area->general_char[2] & 0x10000000)
- 		== 0x10000000);
--	sprintf(dbf_text,"hydra_ti%1x", hydra_thinints);
-+	sprintf(dbf_text,"hydrati%1x", hydra_thinints);
- 	QDIO_DBF_TEXT0(0,setup,dbf_text);
- exit:
- 	free_page ((unsigned long) scsc_area);
-@@ -2413,8 +2413,10 @@ qdio_establish_handle_irq(struct ccw_dev
- 	QDIO_DBF_TEXT0(0,setup,dbf_text);
- 	QDIO_DBF_TEXT0(0,trace,dbf_text);
- 
--	if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat))
-+	if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat)) {
-+		ccw_device_set_timeout(cdev, 0);
- 		return;
-+	}
- 
- 	irq_ptr = cdev->private->qdio_data;
- 
-@@ -2439,7 +2441,7 @@ qdio_establish_handle_irq(struct ccw_dev
- 	qdio_initialize_set_siga_flags_output(irq_ptr);
- 
- 	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED);
--
-+	ccw_device_set_timeout(cdev, 0);
- }
- 
- int
-@@ -2698,6 +2700,8 @@ qdio_establish(struct ccw_device *cdev)
-                            "returned %i, next try returned %i\n",
-                            irq_ptr->irq,result,result2);
- 		result=result2;
-+		if (result)
-+			ccw_device_set_timeout(cdev, 0);
- 	}
- 
- 	spin_unlock_irqrestore(get_ccwdev_lock(cdev),saveflags);
-@@ -3000,7 +3004,6 @@ qdio_perf_procfile_read(char *buffer, ch
- 			int buffer_length, int *eof, void *data)
- {
-         int c=0;
--	int irq;
- 
-         /* we are always called with buffer_length=4k, so we all
-            deliver on the first read */
-@@ -3020,7 +3023,7 @@ qdio_perf_procfile_read(char *buffer, ch
- 		 perf_stats.siga_ins);
- 	_OUTP_IT("Number of SIGA out's issued                     : %u\n",
- 		 perf_stats.siga_outs);
--	_OUTP_IT("Number of PCIs caught                          : %u\n",
-+	_OUTP_IT("Number of PCIs caught                           : %u\n",
- 		 perf_stats.pcis);
- 	_OUTP_IT("Number of adapter interrupts caught             : %u\n",
- 		 perf_stats.thinints);
-@@ -3037,27 +3040,6 @@ qdio_perf_procfile_read(char *buffer, ch
- 		 perf_stats.outbound_cnt);
- 	_OUTP_IT("\n");
- 
--	/* 
--	 * FIXME: Rather use driver_for_each_dev, if we had it. 
--	 * I know this loop destroys our layering, but at least gets the 
--	 * performance stats out...
--	 */
--	for (irq=0;irq <= highest_subchannel; irq++) {
--		struct qdio_irq *irq_ptr;
--		struct ccw_device *cdev;
--
--		if (!ioinfo[irq])
--			continue;
--		cdev = ioinfo[irq]->dev.driver_data;
--		if (!cdev)
--			continue;
--		irq_ptr = cdev->private->qdio_data;
--		if (!irq_ptr)
--			continue;
--		_OUTP_IT("Polling time on irq %4x                        " \
--			 ": %u\n",
--			 irq_ptr->irq,irq_ptr->input_qs[0]->timing.threshold);
--	}
-         return c;
- }
- 
---- linux-2.6.0-test1/drivers/s390/net/qeth.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/net/qeth.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,6 +1,6 @@
- /*
-  *
-- * linux/drivers/s390/net/qeth.c ($Revision: 1.1.2.2 $)
-+ * linux/drivers/s390/net/qeth.c ($Revision: 1.1.2.2 $)
-  *
-  * Linux on zSeries OSA Express and HiperSockets support
-  *
-@@ -165,7 +165,7 @@ MODULE_PARM_DESC(qeth_sparebufs, "the nu
- 		 "reserved for low memory situations");
- 
- /****************** MODULE STUFF **********************************/
--#define VERSION_QETH_C "$Revision: 1.1.2.2 $"
-+#define VERSION_QETH_C "$Revision: 1.1.2.2 $"
- static const char *version = "qeth S/390 OSA-Express driver ("
-     VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H
-     QETH_VERSION_IPV6 QETH_VERSION_VLAN ")";
-@@ -1156,7 +1156,7 @@ qeth_get_skb(unsigned int len)
- 	return skb;
- }
- 
--static struct sk_buff *
-+static inline struct sk_buff *
- qeth_get_next_skb(struct qeth_card *card,
- 		  int *element_ptr, int *pos_in_el_ptr,
- 		  void **hdr_ptr, struct qdio_buffer *buffer)
-@@ -1464,8 +1464,21 @@ __qeth_rebuild_skb(struct qeth_card *car
- 	skb->ip_summed = card->options.checksum_type;
- 	if (card->options.checksum_type == HW_CHECKSUMMING) {
- 		/* do we have a checksummed packet? */
--		if (*(__u8 *) (hdr_ptr + 11) & QETH_EXT_HEADER_CSUM_TRANSP_REQ) {
--			/* skb->ip_summed is set already */
-+
-+		/* 
-+		 * we only check for TCP/UDP checksums when the pseudo
-+		 * header was also checked successfully -- for the
-+		 * rest of the packets, it's not clear, whether the
-+		 * upper layer csum is alright. And they shouldn't
-+		 * occur too often anyway in real life 
-+		 */
-+
-+		if ((*(__u8*)(hdr_ptr+11) & (QETH_EXT_HEADER_CSUM_HDR_REQ |
-+					     QETH_EXT_HEADER_CSUM_TRANSP_REQ)) ==
-+		    (QETH_EXT_HEADER_CSUM_HDR_REQ |
-+		     QETH_EXT_HEADER_CSUM_TRANSP_REQ)) {
-+#if 0
-+			/* csum does not need to be set inbound anyway */
- 			
- 			/* 
- 			 * vlan is not an issue here, it's still in
-@@ -1485,11 +1498,15 @@ __qeth_rebuild_skb(struct qeth_card *car
- 					(&skb->data[ip_len +
- 						    QETH_TCP_CSUM_OFFSET]);
- 			}
-+#endif /* 0 */
-+			skb->ip_summed=CHECKSUM_UNNECESSARY;
- 		} else {
- 			/* make the stack check it */
- 			skb->ip_summed = SW_CHECKSUMMING;
- 		}
--	}
-+	} else
-+		skb->ip_summed=card->options.checksum_type;
-+
- 	__qeth_rebuild_skb_vlan(card, skb, hdr_ptr);
- }
- 
-@@ -1596,7 +1613,7 @@ __qeth_fill_header_add_vlan(struct qeth_
- #endif
- }
- 
--static __u8
-+static inline __u8
- __qeth_get_flags_v4(int multicast)
- {
- 	if (multicast == RTN_MULTICAST)
-@@ -1606,7 +1623,7 @@ __qeth_get_flags_v4(int multicast)
- 	return QETH_CAST_UNICAST;
- }
- 
--static __u8
-+static inline __u8
- __qeth_get_flags_v6(int multicast)
- {
- 	if (multicast == RTN_MULTICAST)
-@@ -1625,7 +1642,7 @@ __qeth_get_flags_v6(int multicast)
- 		QETH_HEADER_IPV6;
- }
- 
--static void
-+static inline void
- qeth_fill_header(struct qeth_hdr *hdr, struct sk_buff *skb,
- 		 int version, int multicast)
- {
-@@ -1681,7 +1698,7 @@ qeth_fill_header(struct qeth_hdr *hdr, s
- 		      __max(QETH_DBF_DATA_LEN, QETH_DBF_DATA_LEN));
- }
- 
--static int inline
-+static inline int
- qeth_fill_buffer(struct qdio_buffer *buffer, char *dataptr,
- 		 int length, int element)
- {
-@@ -1735,7 +1752,7 @@ qeth_fill_buffer(struct qdio_buffer *buf
- 	return element;
- }
- 
--static void
-+static inline void
- qeth_flush_packed_packets(struct qeth_card *card, int queue, int under_int)
- {
- 	struct qdio_buffer *buffer;
-@@ -1900,7 +1917,7 @@ qeth_determine_send_error(int cc, int qd
- 	return ERROR_LINK_FAILURE;	/* should never happen */
- }
- 
--static void
-+static inline void
- qeth_free_buffer(struct qeth_card *card, int queue, int bufno,
- 		 int qdio_error, int siga_error)
- {
-@@ -2013,7 +2030,7 @@ qeth_free_buffer(struct qeth_card *card,
- 	card->send_retries[queue][bufno] = 0;
- }
- 
--static void
-+static inline void
- qeth_free_all_skbs(struct qeth_card *card)
- {
- 	int q, b;
-@@ -2049,7 +2066,7 @@ qeth_flush_buffer(struct qeth_card *card
- }
- 
- #ifdef QETH_VLAN
--void
-+static inline void
- qeth_insert_ipv6_vlan_tag(struct sk_buff *__skb)
- {
- 
-@@ -2088,7 +2105,7 @@ __qeth_add_vlan_tag(struct qeth_card *ca
- #endif
- }
- 
--static void
-+static inline void
- qeth_send_packet_fast(struct qeth_card *card, struct sk_buff *skb,
- 		      struct net_device *dev,
- 		      int queue, int version, int multicast)
-@@ -2183,7 +2200,7 @@ qeth_send_packet_fast(struct qeth_card *
- 
- /* no checks, if all elements are used, as then we would not be here (at most
-    127 buffers are enqueued) */
--static void
-+static inline void
- qeth_send_packet_packed(struct qeth_card *card, struct sk_buff *skb,
- 			struct net_device *dev,
- 			int queue, int version, int multicast)
-@@ -2391,7 +2408,7 @@ __qeth_switch_state_if_needed(struct qet
- 	}
- }
- 
--static int
-+static inline int
- qeth_do_send_packet(struct qeth_card *card, struct sk_buff *skb,
- 		    struct net_device *dev)
- {
-@@ -2829,23 +2846,27 @@ qeth_send_ipa_cmd(struct qeth_card *card
- 
- 	if (!buffer) {
- 		if (atomic_read(&card->escape_softsetup))
--			result = 0;
-+			return 0;
- 		else
--			result = -1;
--	} else {
--		reply = (struct ipa_cmd *) PDU_ENCAPSULATION(buffer);
--		if ((update_cmd) && (reply))
--			memcpy(cmd, reply, sizeof (struct ipa_cmd));
--		result = reply->return_code;
--
--		/* some special sausages: */
--		if ((ipa_cmd == IPA_CMD_SETASSPARMS) && (result == 0)) {
--			result = reply->data.setassparms.return_code;
--		}
--		if ((ipa_cmd == IPA_CMD_SETADAPTERPARMS) && (result == 0)) {
--			result = reply->data.setadapterparms.return_code;
--		}
-+			return -1;
-+	}
-+	reply = (struct ipa_cmd *) PDU_ENCAPSULATION(buffer);
-+	if ((update_cmd) && (reply))
-+		memcpy(cmd, reply, sizeof (struct ipa_cmd));
-+	result = reply->return_code;
-+
-+	/* some special sausages: */
-+	if ((ipa_cmd == IPA_CMD_SETASSPARMS) && (result == 0)) {
-+		result = reply->data.setassparms.return_code;
-+		if ((reply->data.setassparms.assist_no==IPA_INBOUND_CHECKSUM) &&
-+		    (reply->data.setassparms.command_code == IPA_CMD_ASS_START))
-+			card->csum_enable_mask =
-+				reply->data.setassparms.data.flags_32bit;
-+	}
-+	if ((ipa_cmd == IPA_CMD_SETADAPTERPARMS) && (result == 0)) {
-+		result = reply->data.setadapterparms.return_code;
- 	}
-+
- 	return result;
- }
- 
-@@ -5599,7 +5620,7 @@ go_on_filt:
- 			}
- 			result=qeth_send_setassparms_simple_with_data
- 				(card,IPA_INBOUND_CHECKSUM,
--				 IPA_CMD_ASS_ENABLE, IPA_CHECKSUM_ENABLE_MASK);
-+				 IPA_CMD_ASS_ENABLE, card->csum_enable_mask);
- 			if (result) {
- 				PRINT_WARN("Could not enable inbound " \
- 					   "checksumming on %s: 0x%x, " \
-@@ -6881,6 +6902,14 @@ qeth_peer_func_level(int level)
- 	return level;		/* hmmm... don't know what to do with that level. */
- }
- 
-+/* returns last four digits of bus_id */
-+static inline __u16
-+__raw_devno_from_bus_id(char *id)
-+{
-+	id += (strlen(id) - 4); 
-+	return (__u16) simple_strtoul(id, &id, 16);
-+}
-+
- static int
- qeth_idx_activate_read(struct qeth_card *card)
- {
-@@ -6905,7 +6934,7 @@ qeth_idx_activate_read(struct qeth_card 
- 	memcpy(QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->sendbuf),
- 	       &card->func_level, 2);
- 
--	temp = _ccw_device_get_device_number(card->ddev);
-+	temp = __raw_devno_from_bus_id(card->ddev->dev.bus_id);
- 	memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(card->dma_stuff->sendbuf), &temp, 2);
- 	temp = (card->cula << 8) + card->unit_addr2;
- 	memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(card->dma_stuff->sendbuf),
-@@ -7501,10 +7530,8 @@ qeth_verify_dev(struct net_device *dev)
- 	for (; tmp && (!result); tmp = tmp->next) {
- 		if (atomic_read(&tmp->shutdown_phase))
- 			continue;
--		if (dev == tmp->dev) {
--			result = QETH_VERIFY_IS_REAL_DEV;
--		}
--		result = __qeth_verify_dev_vlan(dev, tmp);
-+		result = (dev == tmp->dev)?
-+			QETH_VERIFY_IS_REAL_DEV:__qeth_verify_dev_vlan(dev, tmp);
- 	}
- 	read_unlock(&list_lock);
- 	return result;
-@@ -8547,6 +8574,8 @@ qeth_alloc_card(void)
- 	card->ip_mc_new_state.ipm6_ifa = NULL;
- #endif /* QETH_IPV6 */
- 
-+	card->csum_enable_mask = IPA_CHECKSUM_DEFAULT_ENABLE_MASK;
-+
- 	/* setup net_device stuff */
- 	card->dev->priv = card;
- 
-@@ -9087,21 +9116,19 @@ qeth_procfile_open(struct inode *inode, 
- 		/* FIXME: this is really a mess... */
- 
- #ifdef QETH_IPV6
--		if (atomic_read(&card->rt4fld) && atomic_read(&card->rt6fld))
--			strcpy(router_str, "no");
--		else if (atomic_read(&card->rt4fld)
--			 || atomic_read(&card->rt6fld))
--			strcpy(router_str, "mix");
-+		if (atomic_read(&card->rt4fld) || atomic_read(&card->rt6fld))
-+			strcpy(router_str, "FLD");
- #else/* QETH_IPV6 */
- 		if (atomic_read(&card->rt4fld))
--			strcpy(router_str, "no");
-+			strcpy(router_str, "FLD");
- #endif /* QETH_IPV6 */
- 		else if (((card->options.routing_type4 & ROUTER_MASK) ==
- 			  PRIMARY_ROUTER)
- #ifdef QETH_IPV6
- 			 &&
--			 ((card->options.routing_type6 & ROUTER_MASK) ==
--			  PRIMARY_ROUTER)
-+			 (((card->options.routing_type6 & ROUTER_MASK) ==
-+			  PRIMARY_ROUTER) ||
-+			  (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "pri");
-@@ -9110,8 +9137,9 @@ qeth_procfile_open(struct inode *inode, 
- 			 SECONDARY_ROUTER)
- #ifdef QETH_IPV6
- 			&&
--			((card->options.routing_type6 & ROUTER_MASK) ==
--			 SECONDARY_ROUTER)
-+			(((card->options.routing_type6 & ROUTER_MASK) ==
-+			 SECONDARY_ROUTER) ||
-+			 (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "sec");
-@@ -9120,8 +9148,9 @@ qeth_procfile_open(struct inode *inode, 
- 			 MULTICAST_ROUTER)
- #ifdef QETH_IPV6
- 			&&
--			((card->options.routing_type6 & ROUTER_MASK) ==
--			 MULTICAST_ROUTER)
-+			(((card->options.routing_type6 & ROUTER_MASK) ==
-+			 MULTICAST_ROUTER) ||
-+			 (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "mc");
-@@ -9130,8 +9159,9 @@ qeth_procfile_open(struct inode *inode, 
- 			 PRIMARY_CONNECTOR)
- #ifdef QETH_IPV6
- 			&&
--			((card->options.routing_type6 & ROUTER_MASK) ==
--			 PRIMARY_CONNECTOR)
-+			(((card->options.routing_type6 & ROUTER_MASK) ==
-+			 PRIMARY_CONNECTOR) ||
-+			 (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "p.c");
-@@ -9140,8 +9170,9 @@ qeth_procfile_open(struct inode *inode, 
- 			 SECONDARY_CONNECTOR)
- #ifdef QETH_IPV6
- 			&&
--			((card->options.routing_type6 & ROUTER_MASK) ==
--			 SECONDARY_CONNECTOR)
-+			(((card->options.routing_type6 & ROUTER_MASK) ==
-+			 SECONDARY_CONNECTOR) ||
-+			 (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "s.c");
-@@ -9150,8 +9181,9 @@ qeth_procfile_open(struct inode *inode, 
- 			 NO_ROUTER)
- #ifdef QETH_IPV6
- 			&&
--			((card->options.routing_type6 & ROUTER_MASK) ==
--			 NO_ROUTER)
-+			(((card->options.routing_type6 & ROUTER_MASK) ==
-+			 NO_ROUTER) ||
-+			 (!qeth_is_supported(IPA_IPv6)))
- #endif /* QETH_IPV6 */
- 		    ) {
- 			strcpy(router_str, "no");
-@@ -10115,7 +10147,7 @@ qeth_route4_show(struct device *dev, cha
- 		return -EINVAL;
- 
- 	if (atomic_read(&card->rt4fld))
--		return sprintf(buf, "%s\n", "no");
-+		return sprintf(buf, "%s\n", "FLD");
- 
- 	switch (card->options.routing_type4 & ROUTER_MASK) {
- 	case PRIMARY_ROUTER:
-@@ -10202,7 +10234,10 @@ qeth_route6_show(struct device *dev, cha
- 		return -EINVAL;
- 
- 	if (atomic_read(&card->rt6fld))
--		return sprintf(buf, "%s\n", "no");
-+		return sprintf(buf, "%s\n", "FLD");
-+
-+	if (!qeth_is_supported(IPA_IPv6))
-+		return sprintf(buf, "%s\n", "n/a");
- 
- 	switch (card->options.routing_type6 & ROUTER_MASK) {
- 	case PRIMARY_ROUTER:
-@@ -11061,6 +11096,10 @@ qeth_set_offline(struct ccwgroup_device 
- 
- 	QETH_DBF_TEXT4(0, trace, "freecard");
- 
-+	memset(card->dev, 0, sizeof (struct net_device));
-+	card->dev->priv = card;
-+	strncpy(card->dev->name, card->dev_name, IFNAMSIZ);
-+
- 	ccw_device_set_offline(card->ddev);
- 	ccw_device_set_offline(card->wdev);
- 	ccw_device_set_offline(card->rdev);
---- linux-2.6.0-test1/drivers/s390/net/qeth.h	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/net/qeth.h	2003-07-19 17:03:50.000000000 -0700
-@@ -14,7 +14,7 @@
- 
- #define QETH_NAME " qeth"
- 
--#define VERSION_QETH_H "$Revision: 1.1.2.2 $"
-+#define VERSION_QETH_H "$Revision: 1.1.2.2 $"
- 
- /******************** CONFIG STUFF ***********************/
- //#define QETH_DBF_LIKE_HELL
-@@ -938,6 +938,8 @@ struct qeth_card {	/* pointed to by dev-
- 	__u32 ipa6_enabled;
- 	__u32 adp_supported;
- 
-+	__u32 csum_enable_mask;
-+
- 	atomic_t startlan_attempts;
- 	atomic_t enable_routing_attempts4;
- 	atomic_t rt4fld;
-@@ -1021,7 +1023,7 @@ qeth_get_arphrd_type(int cardtype, int l
- 		case QETH_MPC_LINK_TYPE_LANE_TR:
- 			/* fallthrough */
- 		case QETH_MPC_LINK_TYPE_HSTR:
--			return ARPHRD_IEEE802;
-+			return ARPHRD_IEEE802_TR;
- 		default:
- 			return ARPHRD_ETHER;
- 		}
---- linux-2.6.0-test1/drivers/s390/net/qeth_mpc.h	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/s390/net/qeth_mpc.h	2003-07-19 17:03:50.000000000 -0700
-@@ -10,7 +10,7 @@
- #ifndef __QETH_MPC_H__
- #define __QETH_MPC_H__
- 
--#define VERSION_QETH_MPC_H "$Revision: 1.1.2.2 $"
-+#define VERSION_QETH_MPC_H "$Revision: 1.1.2.2 $"
- 
- #define QETH_IPA_TIMEOUT (card->ipa_timeout)
- #define QETH_MPC_TIMEOUT 2000
-@@ -188,7 +188,7 @@ extern unsigned char DM_ACT[];
- #define IPA_CMD_ASS_ARP_QUERY_INFO 0x0104
- #define IPA_CMD_ASS_ARP_QUERY_STATS 0x0204
- 
--#define IPA_CHECKSUM_ENABLE_MASK 0x001a
-+#define IPA_CHECKSUM_DEFAULT_ENABLE_MASK 0x001a
- 
- #define IPA_CMD_ASS_FILTER_SET_TYPES 0x0003
- 
---- linux-2.6.0-test1/drivers/sbus/char/envctrl.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/sbus/char/envctrl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -14,6 +14,9 @@
-  *
-  * EB - Added support for CP1500 Global Address and PS/Voltage monitoring.
-  * 		Eric Brower <ebrower@usa.net>
-+ *
-+ * DB - Audit every copy_to_user in envctrl_read.
-+ *              Daniele Bellucci <bellucda@tiscali.it>
-  */
- 
- #include <linux/config.h>
-@@ -571,7 +574,8 @@ envctrl_read(struct file *file, char *bu
- 
- 		data[0] = (unsigned char)(warning_temperature);
- 		ret = 1;
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_SHUTDOWN_TEMPERATURE:
-@@ -580,14 +584,16 @@ envctrl_read(struct file *file, char *bu
- 
- 		data[0] = (unsigned char)(shutdown_temperature);
- 		ret = 1;
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_MTHRBD_TEMPERATURE:
- 		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_MTHRBDTEMP_MON)))
- 			return 0;
- 		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_MTHRBDTEMP_MON, data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_CPU_TEMPERATURE:
-@@ -596,7 +602,8 @@ envctrl_read(struct file *file, char *bu
- 		ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUTEMP_MON, data);
- 
- 		/* Reset cpu to the default cpu0. */
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_CPU_VOLTAGE:
-@@ -605,21 +612,24 @@ envctrl_read(struct file *file, char *bu
- 		ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUVOLTAGE_MON, data);
- 
- 		/* Reset cpu to the default cpu0. */
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_SCSI_TEMPERATURE:
- 		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_SCSITEMP_MON)))
- 			return 0;
- 		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_SCSITEMP_MON, data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_ETHERNET_TEMPERATURE:
- 		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_ETHERTEMP_MON)))
- 			return 0;
- 		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_ETHERTEMP_MON, data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_FAN_STATUS:
-@@ -627,7 +637,8 @@ envctrl_read(struct file *file, char *bu
- 			return 0;
- 		data[0] = envctrl_i2c_read_8574(pchild->addr);
- 		ret = envctrl_i2c_fan_status(pchild,data[0], data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 	
- 	case ENVCTRL_RD_GLOBALADDRESS:
-@@ -635,7 +646,8 @@ envctrl_read(struct file *file, char *bu
- 			return 0;
- 		data[0] = envctrl_i2c_read_8574(pchild->addr);
- 		ret = envctrl_i2c_globaladdr(pchild, data[0], data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	case ENVCTRL_RD_VOLTAGE_STATUS:
-@@ -645,7 +657,8 @@ envctrl_read(struct file *file, char *bu
- 				return 0;
- 		data[0] = envctrl_i2c_read_8574(pchild->addr);
- 		ret = envctrl_i2c_voltage_status(pchild, data[0], data);
--		copy_to_user((unsigned char *)buf, data, ret);
-+		if (copy_to_user((unsigned char *)buf, data, ret))
-+			ret = -EFAULT;
- 		break;
- 
- 	default:
---- linux-2.6.0-test1/drivers/sbus/char/jsflash.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/sbus/char/jsflash.c	2003-07-19 17:03:50.000000000 -0700
-@@ -38,12 +38,8 @@
- #include <linux/smp_lock.h>
- #include <linux/genhd.h>
- 
--/*
-- * <linux/blk.h> is controlled from the outside with these definitions.
-- */
- #define MAJOR_NR	JSFD_MAJOR
- 
--#include <linux/blk.h>
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
- #include <asm/io.h>
---- linux-2.6.0-test1/drivers/scsi/3w-xxxx.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/scsi/3w-xxxx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -187,7 +187,7 @@ MODULE_LICENSE("GPL");
- #include <linux/proc_fs.h>
- #include <linux/sched.h>
- #include <linux/ioport.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/hdreg.h>
- #include <linux/string.h>
- #include <linux/delay.h>
---- linux-2.6.0-test1/drivers/scsi/53c700.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/53c700.c	2003-07-19 17:03:50.000000000 -0700
-@@ -131,7 +131,7 @@
- #include <asm/io.h>
- #include <asm/pgtable.h>
- #include <asm/byteorder.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/module.h>
- #include <linux/interrupt.h>
- 
-@@ -172,7 +172,7 @@ STATIC void NCR_700_chip_reset(struct Sc
- STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
- STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
- 
--static struct device_attribute **NCR_700_dev_attrs = NULL;
-+STATIC struct device_attribute *NCR_700_dev_attrs[];
- 
- static char *NCR_700_phase[] = {
- 	"",
-@@ -2027,25 +2027,12 @@ static struct device_attribute NCR_700_a
- 	.show = NCR_700_show_active_tags,
- };
- 
--STATIC int __init
--NCR_700_init(void)
--{
--	scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
--					 &NCR_700_queue_depth_attr);
--	scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
--					 &NCR_700_active_tags_attr);
--	return 0;
--}
--
--/* NULL exit routine to keep modutils happy */
--STATIC void __exit
--NCR_700_exit(void)
--{
--}
-+STATIC struct device_attribute *NCR_700_dev_attrs[] = {
-+	&NCR_700_queue_depth_attr,
-+	&NCR_700_active_tags_attr,
-+	NULL,
-+};
- 
- EXPORT_SYMBOL(NCR_700_detect);
- EXPORT_SYMBOL(NCR_700_release);
- EXPORT_SYMBOL(NCR_700_intr);
--
--module_init(NCR_700_init);
--module_exit(NCR_700_exit);
---- linux-2.6.0-test1/drivers/scsi/53c7xx.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/scsi/53c7xx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -249,7 +249,7 @@
- #include <linux/mm.h>
- #include <linux/ioport.h>
- #include <linux/time.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include <linux/interrupt.h>
- #include <asm/pgtable.h>
---- linux-2.6.0-test1/drivers/scsi/a2091.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/scsi/a2091.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,6 +1,6 @@
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/a3000.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/scsi/a3000.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,6 +1,6 @@
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/aacraid/aachba.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/aacraid/aachba.c	2003-07-19 17:03:50.000000000 -0700
-@@ -33,7 +33,7 @@
- #include <linux/completion.h>
- #include <asm/semaphore.h>
- #include <asm/uaccess.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- 
---- linux-2.6.0-test1/drivers/scsi/aacraid/commctrl.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/scsi/aacraid/commctrl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -37,7 +37,7 @@
- #include <linux/spinlock.h>
- #include <linux/slab.h>
- #include <linux/completion.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/semaphore.h>
- #include <asm/uaccess.h>
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/aacraid/comminit.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/aacraid/comminit.c	2003-07-19 17:03:50.000000000 -0700
-@@ -37,7 +37,7 @@
- #include <linux/pci.h>
- #include <linux/spinlock.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/completion.h>
- #include <linux/mm.h>
- #include <asm/semaphore.h>
---- linux-2.6.0-test1/drivers/scsi/aacraid/commsup.c	2003-06-14 12:18:28.000000000 -0700
-+++ 25/drivers/scsi/aacraid/commsup.c	2003-07-19 17:03:50.000000000 -0700
-@@ -41,7 +41,7 @@
- #include <linux/slab.h>
- #include <linux/completion.h>
- #include <asm/semaphore.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- 
---- linux-2.6.0-test1/drivers/scsi/aacraid/dpcsup.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/scsi/aacraid/dpcsup.c	2003-07-19 17:03:50.000000000 -0700
-@@ -38,7 +38,7 @@
- #include <linux/spinlock.h>
- #include <linux/slab.h>
- #include <linux/completion.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/semaphore.h>
- #include "scsi.h"
- #include "hosts.h"
---- linux-2.6.0-test1/drivers/scsi/aacraid/linit.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/scsi/aacraid/linit.c	2003-07-19 17:05:05.000000000 -0700
-@@ -50,7 +50,7 @@
- #include <linux/completion.h>
- #include <linux/interrupt.h>
- #include <asm/semaphore.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <scsi/scsicam.h>
-@@ -295,7 +295,6 @@ static int aac_detect(Scsi_Host_Template
- 			printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
- 	}
- 
--	template->present = aac_count; /* # of cards of this type found */
- 	return aac_count;
- }
- 
---- linux-2.6.0-test1/drivers/scsi/aacraid/rx.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/scsi/aacraid/rx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -36,7 +36,7 @@
- #include <linux/pci.h>
- #include <linux/spinlock.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/completion.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/aacraid/sa.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/scsi/aacraid/sa.c	2003-07-19 17:03:50.000000000 -0700
-@@ -36,7 +36,7 @@
- #include <linux/pci.h>
- #include <linux/spinlock.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/completion.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/advansys.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/drivers/scsi/advansys.c	2003-07-19 17:03:50.000000000 -0700
-@@ -798,7 +798,7 @@
- #include <linux/mm.h>
- #include <linux/proc_fs.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/stat.h>
- #include <linux/spinlock.h>
- 
---- linux-2.6.0-test1/drivers/scsi/aha152x.c	2003-06-26 22:07:24.000000000 -0700
-+++ 25/drivers/scsi/aha152x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -225,7 +225,7 @@
- #include <asm/irq.h>
- #include <asm/io.h>
- #include <linux/version.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <asm/system.h>
-@@ -241,9 +241,7 @@
- #include <linux/isapnp.h>
- #include <linux/spinlock.h>
- #include <linux/workqueue.h>
--#include <linux/blk.h>
- #include <asm/semaphore.h>
--#include <asm/io.h>
- #include <scsi/scsicam.h>
- 
- #include "scsi.h"
-@@ -941,7 +939,8 @@ static irqreturn_t swintr(int irqno, voi
- 	struct Scsi_Host *shpnt = lookup_irq(irqno);
- 
- 	if (!shpnt) {
--        	printk(KERN_ERR "aha152x%d: catched software interrupt %d for unknown controller.\n", HOSTNO, irqno);
-+		/* no point using HOSTNO here! */
-+        	printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno);
- 		return IRQ_NONE;
- 	}
- 
-@@ -1049,6 +1048,10 @@ struct Scsi_Host *aha152x_probe_one(stru
- 
- 	printk(KERN_INFO "aha152x%d: trying software interrupt, ",
- 			 shost->host_no);
-+
-+	/* need to have host registered before triggering any interrupt */
-+	aha152x_host[registered_count] = shost;
-+	mb();
- 	SETPORT(DMACNTRL0, SWINT|INTEN);
- 	mdelay(1000);
- 	free_irq(shost->irq, shost);
-@@ -1064,7 +1067,7 @@ struct Scsi_Host *aha152x_probe_one(stru
- 
- 		printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong.  "
- 				"Please verify.\n", shost->host_no, shost->irq);
--		goto out_release_region;
-+		goto out_unregister_host;
- 	}
- 	printk("ok.\n");
- 
-@@ -1077,12 +1080,12 @@ struct Scsi_Host *aha152x_probe_one(stru
- 				"aha152x", shost) < 0) {
- 		printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n",
- 				shost->host_no);
--		goto out_release_region;
-+		goto out_unregister_host;
- 	}
--
--	aha152x_host[registered_count] = shost;
- 	return shost;	/* the pcmcia stub needs the return value; */
- 
-+out_unregister_host:
-+	aha152x_host[registered_count] = NULL;
- out_release_region:
- 	release_region(shost->io_port, IO_RANGE);
- out_unregister:
---- linux-2.6.0-test1/drivers/scsi/aha1542.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/aha1542.c	2003-07-19 17:03:50.000000000 -0700
-@@ -38,7 +38,7 @@
- #include <linux/spinlock.h>
- #include <linux/pci.h>
- #include <linux/isapnp.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/mca.h>
- #include <linux/mca-legacy.h>
- 
---- linux-2.6.0-test1/drivers/scsi/aha1542.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/scsi/aha1542.h	2003-07-19 17:03:50.000000000 -0700
-@@ -130,7 +130,6 @@ struct ccb {			/* Command Control Block 
- };
- 
- static int aha1542_detect(Scsi_Host_Template *);
--static int aha1542_command(Scsi_Cmnd *);
- static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
- static int aha1542_abort(Scsi_Cmnd * SCpnt);
- static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
---- linux-2.6.0-test1/drivers/scsi/aha1740.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/aha1740.c	2003-07-19 17:03:50.000000000 -0700
-@@ -34,7 +34,7 @@
-  * are deemed to be part of the source code.
-  */
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-@@ -375,7 +375,7 @@ static int aha1740_queuecommand(Scsi_Cmn
- #endif
- 
- 	/* locate an available ecb */
--	spin_lock_irqsave(&SCpnt->device->host->host_lock, flags);
-+	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
- 	ecbno = host->last_ecb_used + 1; /* An optimization */
- 	if (ecbno >= AHA1740_ECBS)
- 		ecbno = 0;
-@@ -394,7 +394,7 @@ static int aha1740_queuecommand(Scsi_Cmn
- 						    doubles as reserved flag */
- 
- 	host->last_ecb_used = ecbno;    
--	spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags);
-+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
- 
- #ifdef DEBUG
- 	printk("Sending command (%d %x)...", ecbno, done);
-@@ -491,7 +491,7 @@ static int aha1740_queuecommand(Scsi_Cmn
- 		unsigned int base = SCpnt->device->host->io_port;
- 		DEB(printk("aha1740[%d] critical section\n",ecbno));
- 
--		spin_lock_irqsave(&SCpnt->device->host->host_lock, flags);
-+		spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
- 		for (loopcnt = 0; ; loopcnt++) {
- 			if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
- 			if (loopcnt == LOOPCNT_WARN) {
-@@ -511,7 +511,7 @@ static int aha1740_queuecommand(Scsi_Cmn
- 				panic("aha1740.c: attn wait failed!\n");
- 		}
- 		outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
--		spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags);
-+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
- 		DEB(printk("aha1740[%d] request queued.\n",ecbno));
- 	} else
- 		printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
-@@ -594,7 +594,7 @@ static int aha1740_probe (struct device 
- 	if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
- 		return -EBUSY;
- 	if (!aha1740_test_port(slotbase))
--		goto err_release;
-+		goto err_release_region;
- 	aha1740_getconfig(slotbase,&irq_level,&translation);
- 	if ((inb(G2STAT(slotbase)) &
- 	     (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
-@@ -609,7 +609,7 @@ static int aha1740_probe (struct device 
- 	shpnt = scsi_host_alloc(&aha1740_template,
- 			      sizeof(struct aha1740_hostdata));
- 	if(shpnt == NULL)
--		goto err_release;
-+		goto err_release_region;
- 
- 	shpnt->base = 0;
- 	shpnt->io_port = slotbase;
-@@ -625,21 +625,27 @@ static int aha1740_probe (struct device 
- 	if (!host->ecb_dma_addr) {
- 		printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
- 		scsi_unregister (shpnt);
--		goto err_release;
-+		goto err_host_put;
- 	}
- 	
- 	DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
- 	if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",shpnt)) {
- 		printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
- 		       irq_level);
--		goto err_release;
-+		goto err_unmap;
- 	}
- 
- 	eisa_set_drvdata (edev, shpnt);
--	scsi_add_host (shpnt, dev);
-+	scsi_add_host (shpnt, dev); /* XXX handle failure */
-+	scsi_scan_host (shpnt);
- 	return 0;
- 
-- err_release:
-+ err_unmap:
-+	dma_unmap_single (&edev->dev, host->ecb_dma_addr,
-+			  sizeof (host->ecb), DMA_BIDIRECTIONAL);
-+ err_host_put:
-+	scsi_host_put (shpnt);
-+ err_release_region:
- 	release_region(slotbase, SLOTSIZE);
- 
- 	return -ENODEV;
---- linux-2.6.0-test1/drivers/scsi/aic7xxx/aic79xx_osm.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx/aic79xx_osm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -2173,7 +2173,8 @@ ahd_linux_register_host(struct ahd_softc
- 	ahd_unlock(ahd, &s);
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
--	scsi_add_host(host, &ahd->dev_softc->dev);
-+	scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
-+	scsi_scan_host(host);
- #endif
- 	return (0);
- }
---- linux-2.6.0-test1/drivers/scsi/aic7xxx/aic79xx_osm.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx/aic79xx_osm.h	2003-07-19 17:03:50.000000000 -0700
-@@ -43,7 +43,6 @@
- #define _AIC79XX_LINUX_H_
- 
- #include <linux/types.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -139,7 +139,7 @@
- #endif
- 
- #include <linux/mm.h>		/* For fetching system memory size */
--#include <linux/blk.h>		/* For block_size() */
-+#include <linux/blkdev.h>		/* For block_size() */
- 
- /*
-  * Lock protecting manipulation of the ahc softc list.
-@@ -1811,7 +1811,8 @@ ahc_linux_register_host(struct ahc_softc
- 	ahc_unlock(ahc, &s);
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
--	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
-+	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
-+	scsi_scan_host(host);
- #endif
- 	return (0);
- }
---- linux-2.6.0-test1/drivers/scsi/aic7xxx/aic7xxx_osm.h	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx/aic7xxx_osm.h	2003-07-19 17:03:50.000000000 -0700
-@@ -60,7 +60,6 @@
- #define _AIC7XXX_LINUX_H_
- 
- #include <linux/types.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/aic7xxx/aiclib.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx/aiclib.c	2003-07-19 17:03:50.000000000 -0700
-@@ -30,7 +30,6 @@
-  * $Id: 2.6.0-test1-mm2.patch,v 1.1.2.2 2003/07/22 07:20:21 braam Exp $
-  */
- 
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/version.h>
---- linux-2.6.0-test1/drivers/scsi/aic7xxx_old.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/scsi/aic7xxx_old.c	2003-07-19 17:03:50.000000000 -0700
-@@ -233,11 +233,10 @@
- #include <linux/sched.h>
- #include <linux/pci.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/spinlock.h>
- #include <linux/smp.h>
--#include <linux/blk.h>
- #include <linux/interrupt.h>
- #include "scsi.h"
- #include "hosts.h"
---- linux-2.6.0-test1/drivers/scsi/AM53C974.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/AM53C974.c	2003-07-19 17:03:50.000000000 -0700
-@@ -7,7 +7,7 @@
- #include <linux/errno.h>
- #include <linux/pci.h>
- #include <linux/string.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/spinlock.h>
- 
---- linux-2.6.0-test1/drivers/scsi/amiga7xx.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/amiga7xx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
-  */
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/config.h>
---- linux-2.6.0-test1/drivers/scsi/arm/acornscsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/acornscsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -138,7 +138,7 @@
- #include <linux/errno.h>
- #include <linux/proc_fs.h>
- #include <linux/ioport.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/init.h>
-@@ -3043,9 +3043,13 @@ acornscsi_probe(struct expansion_card *e
- 	acornscsi_resetcard(ashost);
- 
- 	ret = scsi_add_host(host, &ec->dev);
--	if (ret == 0)
--		goto out;
-+	if (ret)
-+		goto err_7;
-+
-+	scsi_scan_host(host);
-+	goto out;
- 
-+ err_7:
- 	free_irq(host->irq, ashost);
-  err_6:
- 	release_region(host->io_port, 2048);
---- linux-2.6.0-test1/drivers/scsi/arm/arxescsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/arxescsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -19,7 +19,7 @@
-  *  22-10-2000  SH		Updated for new registering scheme.
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/arm/cumana_1.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/cumana_1.c	2003-07-19 17:03:50.000000000 -0700
-@@ -8,7 +8,7 @@
- #include <linux/sched.h>
- #include <linux/ioport.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- 
- #include <asm/ecard.h>
-@@ -297,9 +297,13 @@ cumanascsi1_probe(struct expansion_card 
- 	printk("\n");
- 
- 	ret = scsi_add_host(host, &ec->dev);
--	if (ret == 0)
--		goto out;
-+	if (ret)
-+		goto out_free_irq;
-+
-+	scsi_scan_host(host);
-+	goto out;
- 
-+ out_free_irq:
- 	free_irq(host->irq, host);
-  out_release:
- 	release_region(host->io_port, host->n_io_port);
---- linux-2.6.0-test1/drivers/scsi/arm/cumana_2.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/cumana_2.c	2003-07-19 17:03:50.000000000 -0700
-@@ -17,7 +17,7 @@
-  *   02-04-2000	RMK	0.0.4	Updated for new error handling code.
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/arm/ecoscsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/ecoscsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -27,7 +27,7 @@
- #include <linux/ioport.h>
- #include <linux/delay.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <asm/io.h>
- #include <asm/system.h>
-@@ -205,7 +205,8 @@ static int __init ecoscsi_init(void)
- 	NCR5380_print_options(host);
- 	printk("\n");
- 
--	scsi_add_host(host, NULL);
-+	scsi_add_host(host, NULL); /* XXX handle failure */
-+	scsi_scan_host(host);
- 	return 0;
- 
- release_reg:
---- linux-2.6.0-test1/drivers/scsi/arm/eesox.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/eesox.c	2003-07-19 17:03:50.000000000 -0700
-@@ -23,7 +23,7 @@
-  *				error handling code.
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/arm/fas216.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/fas216.c	2003-07-19 17:03:50.000000000 -0700
-@@ -35,7 +35,7 @@
-  *			condition status from targets.
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
-@@ -2861,6 +2861,8 @@ int fas216_add(struct Scsi_Host *host, s
- 	ret = scsi_add_host(host, dev);
- 	if (ret)
- 		fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
-+	else
-+		scsi_scan_host(host);
- 
- 	return ret;
- }
---- linux-2.6.0-test1/drivers/scsi/arm/oak.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/oak.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/sched.h>
- #include <linux/ioport.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- 
- #include <asm/ecard.h>
-@@ -158,9 +158,13 @@ oakscsi_probe(struct expansion_card *ec,
- 	printk("\n");
- 
- 	ret = scsi_add_host(host, &ec->dev);
--	if (ret == 0)
--		goto out;
-+	if (ret)
-+		goto out_release;
-+
-+	scsi_scan_host(host);
-+	goto out;
- 
-+ out_release:
- 	release_region(host->io_port, host->n_io_port);
-  unreg:
- 	scsi_host_put(host);
---- linux-2.6.0-test1/drivers/scsi/arm/powertec.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/arm/powertec.c	2003-07-19 17:03:50.000000000 -0700
-@@ -8,7 +8,7 @@
-  * published by the Free Software Foundation.
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/arm/queue.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/scsi/arm/queue.c	2003-07-19 17:03:50.000000000 -0700
-@@ -15,7 +15,7 @@
-  *   30-Aug-2000 RMK	Use Linux list handling and spinlocks
-  */
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/slab.h>
---- linux-2.6.0-test1/drivers/scsi/atari_scsi.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/scsi/atari_scsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -86,7 +86,7 @@
- #include <linux/ctype.h>
- #include <linux/delay.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/interrupt.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/atp870u.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/atp870u.c	2003-07-19 17:03:50.000000000 -0700
-@@ -26,7 +26,7 @@
- #include <linux/proc_fs.h>
- #include <linux/spinlock.h>
- #include <linux/pci.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/stat.h>
- 
- #include <asm/system.h>
---- linux-2.6.0-test1/drivers/scsi/blz1230.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/blz1230.c	2003-07-19 17:03:50.000000000 -0700
-@@ -22,7 +22,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/blz2060.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/scsi/blz2060.c	2003-07-19 17:03:50.000000000 -0700
-@@ -22,7 +22,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/BusLogic.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/scsi/BusLogic.c	2003-07-19 17:03:50.000000000 -0700
-@@ -36,7 +36,6 @@
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/types.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/bvme6000.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/bvme6000.c	2003-07-19 17:03:50.000000000 -0700
-@@ -5,7 +5,7 @@
-  */
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/zorro.h>
---- linux-2.6.0-test1/drivers/scsi/constants.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/constants.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/module.h>
- 
- #include <linux/config.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include "scsi.h"
- #include "hosts.h"
---- linux-2.6.0-test1/drivers/scsi/cpqfcTScontrol.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/cpqfcTScontrol.c	2003-07-19 17:03:50.000000000 -0700
-@@ -30,7 +30,7 @@
- 
- #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>  // request_region() prototype
---- linux-2.6.0-test1/drivers/scsi/cpqfcTSinit.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/cpqfcTSinit.c	2003-07-19 17:03:50.000000000 -0700
-@@ -35,7 +35,7 @@
- #include <linux/interrupt.h>  
- #include <linux/module.h>
- #include <linux/version.h> 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/types.h>
---- linux-2.6.0-test1/drivers/scsi/cpqfcTSworker.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/scsi/cpqfcTSworker.c	2003-07-19 17:03:50.000000000 -0700
-@@ -26,7 +26,7 @@
- #include <linux/ioport.h>
- #include <linux/kernel.h>
- #include <linux/stat.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <linux/smp_lock.h>
---- linux-2.6.0-test1/drivers/scsi/cyberstorm.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/scsi/cyberstorm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -25,7 +25,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/cyberstormII.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/scsi/cyberstormII.c	2003-07-19 17:03:50.000000000 -0700
-@@ -21,7 +21,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/dc395x.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/dc395x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -50,7 +50,7 @@
- #include <linux/moduleparam.h>
- #include <linux/delay.h>
- #include <linux/ctype.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/io.h>
- #include "scsi.h"
- #include "hosts.h"
-@@ -6214,7 +6214,8 @@ int __devinit dc395x_init_one(struct pci
- 	pci_set_drvdata(pdev, scsi_host);
- 
- 	/* get the scsi mid level to scan for new devices on the bus */
--	scsi_add_host(scsi_host, &pdev->dev);
-+	scsi_add_host(scsi_host, &pdev->dev);	/* XXX handle failure */
-+	scsi_scan_host(scsi_host);
- 
- 	return 0;
- }
---- linux-2.6.0-test1/drivers/scsi/dec_esp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/dec_esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -24,7 +24,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- 
---- linux-2.6.0-test1/drivers/scsi/dmx3191d.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/scsi/dmx3191d.c	2003-07-19 17:03:50.000000000 -0700
-@@ -22,7 +22,7 @@
- 
- #include <asm/io.h>
- #include <asm/system.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/ioport.h>
- #include <linux/module.h>
---- linux-2.6.0-test1/drivers/scsi/dpt_i2o.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/dpt_i2o.c	2003-07-19 17:03:50.000000000 -0700
-@@ -47,7 +47,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Dri
- #include <linux/config.h>	/* for CONFIG_PCI */
- #include <linux/pci.h>		/* for PCI support */
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>	/* for udelay */
- #include <linux/interrupt.h>
- #include <linux/kernel.h>	/* for printk */
---- linux-2.6.0-test1/drivers/scsi/dtc.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/dtc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -76,7 +76,7 @@
- #include <linux/module.h>
- #include <linux/signal.h>
- #include <linux/sched.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/stat.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/eata.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/eata.c	2003-07-19 17:03:50.000000000 -0700
-@@ -486,7 +486,7 @@
- #include <asm/system.h>
- #include <asm/byteorder.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/stat.h>
- #include <linux/pci.h>
---- linux-2.6.0-test1/drivers/scsi/eata_pio.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/scsi/eata_pio.c	2003-07-19 17:03:50.000000000 -0700
-@@ -58,7 +58,7 @@
- #include <linux/interrupt.h>
- #include <linux/stat.h>
- #include <linux/config.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include <asm/io.h>
- 
---- linux-2.6.0-test1/drivers/scsi/esp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -19,7 +19,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/fastlane.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/scsi/fastlane.c	2003-07-19 17:03:50.000000000 -0700
-@@ -30,7 +30,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/fcal.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/fcal.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/fd_mcs.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/fd_mcs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -79,7 +79,7 @@
- 
- #include <linux/module.h>
- #include <linux/interrupt.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/errno.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/fdomain.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/fdomain.c	2003-07-19 17:03:50.000000000 -0700
-@@ -270,7 +270,7 @@
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include <linux/errno.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/gdth.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/gdth.c	2003-07-19 17:03:50.000000000 -0700
-@@ -357,11 +357,8 @@
- #include <asm/spinlock.h>
- #endif
- 
--#if LINUX_VERSION_CODE >= 0x010300
--#include <linux/blk.h>
--#else
--#include "../block/blk.h"
--#endif
-+#include <linux/blkdev.h>
-+
- #include "scsi.h"
- #include "hosts.h"
- #if LINUX_VERSION_CODE < 0x020503
---- linux-2.6.0-test1/drivers/scsi/g_NCR5380.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/scsi/g_NCR5380.c	2003-07-19 17:03:50.000000000 -0700
-@@ -105,7 +105,7 @@
- #include <asm/io.h>
- #include <linux/signal.h>
- #include <linux/sched.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include "g_NCR5380.h"
---- linux-2.6.0-test1/drivers/scsi/gvp11.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/scsi/gvp11.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,6 +1,6 @@
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/hosts.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/hosts.c	2003-07-19 17:05:05.000000000 -0700
-@@ -81,19 +81,15 @@ int scsi_add_host(struct Scsi_Host *shos
- 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
- 			sht->info ? sht->info(shost) : sht->name);
- 
--	error = scsi_sysfs_add_host(shost, dev);
--
- 	if (!shost->can_queue) {
- 		printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
- 				sht->name);
- 		error = -EINVAL;
- 	}
- 
--	if (!error) {
-+	error = scsi_sysfs_add_host(shost, dev);
-+	if (!error)
- 		scsi_proc_host_add(shost);
--		scsi_scan_host(shost);
--	}
--			
- 	return error;
- }
- 
-@@ -112,7 +108,7 @@ void scsi_free_shost(struct Scsi_Host *s
- 		shost->eh_notify = NULL;
- 	}
- 
--	shost->hostt->present--;
-+	scsi_proc_hostdir_rm(shost->hostt);
- 	scsi_destroy_command_freelist(shost);
- 	kfree(shost);
- }
-@@ -151,12 +147,6 @@ struct Scsi_Host *scsi_host_alloc(struct
- 		dump_stack();
-         }
- 
--	/* if its not set in the template, use the default */
--	if (!sht->shost_attrs)
--		 sht->shost_attrs = scsi_sysfs_shost_attrs;
--	if (!sht->sdev_attrs)
--		 sht->sdev_attrs = scsi_sysfs_sdev_attrs;
--
- 	shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
- 	if (!shost)
- 		return NULL;
-@@ -219,7 +209,7 @@ struct Scsi_Host *scsi_host_alloc(struct
- 	kernel_thread((int (*)(void *))scsi_error_handler, shost, 0);
- 	wait_for_completion(&complete);
- 	shost->eh_notify = NULL;
--	shost->hostt->present++;
-+	scsi_proc_hostdir_add(shost->hostt);
- 	return shost;
-  fail:
- 	kfree(shost);
-@@ -283,8 +273,8 @@ struct Scsi_Host *scsi_host_lookup(unsig
-  **/
- void scsi_host_get(struct Scsi_Host *shost)
- {
--	get_device(&shost->host_gendev);
--	class_device_get(&shost->class_dev);
-+	get_device(&shost->shost_gendev);
-+	class_device_get(&shost->shost_classdev);
- }
- 
- /**
-@@ -293,6 +283,6 @@ void scsi_host_get(struct Scsi_Host *sho
-  **/
- void scsi_host_put(struct Scsi_Host *shost)
- {
--	class_device_put(&shost->class_dev);
--	put_device(&shost->host_gendev);
-+	class_device_put(&shost->shost_classdev);
-+	put_device(&shost->shost_gendev);
- }
---- linux-2.6.0-test1/drivers/scsi/i91uscsi.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/scsi/i91uscsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -81,7 +81,7 @@
- 
- #include <linux/jiffies.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/io.h>
- 
- #include "i91uscsi.h"
---- linux-2.6.0-test1/drivers/scsi/ibmmca.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/ibmmca.c	2003-07-19 17:03:50.000000000 -0700
-@@ -32,7 +32,7 @@
- #include <linux/interrupt.h>
- #include <linux/ioport.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/mca.h>
---- linux-2.6.0-test1/drivers/scsi/ide-scsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/ide-scsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -978,8 +978,10 @@ static int idescsi_attach(ide_drive_t *d
- 		idescsi_setup (drive, idescsi);
- 		drive->disk->fops = &idescsi_ops;
- 		err = scsi_add_host(host, &idescsi_primary);
--		if (!err)
-+		if (!err) {
-+			scsi_scan_host(host);
- 			return 0;
-+		}
- 		/* fall through on error */
- 		ide_unregister_subdriver(drive);
- 	}
---- linux-2.6.0-test1/drivers/scsi/imm.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/imm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -24,7 +24,7 @@
- void imm_reset_pulse(unsigned int base);
- static int device_check(int host_no);
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/io.h>
- #include <linux/parport.h>
- #include <linux/workqueue.h>
---- linux-2.6.0-test1/drivers/scsi/imm.h	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/scsi/imm.h	2003-07-19 17:03:50.000000000 -0700
-@@ -75,7 +75,7 @@
- #include  <linux/delay.h>
- #include  <linux/proc_fs.h>
- #include  <linux/stat.h>
--#include  <linux/blk.h>
-+#include  <linux/blkdev.h>
- #include  <linux/sched.h>
- #include  <linux/interrupt.h>
- 
---- linux-2.6.0-test1/drivers/scsi/in2000.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/scsi/in2000.c	2003-07-19 17:03:50.000000000 -0700
-@@ -114,7 +114,6 @@
-  */
- 
- #include <linux/module.h>
--#include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/ini9100u.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/ini9100u.c	2003-07-19 17:03:50.000000000 -0700
-@@ -119,7 +119,7 @@
- #include <linux/delay.h>
- #include <linux/pci.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include <linux/stat.h>
- #include <linux/config.h>
---- linux-2.6.0-test1/drivers/scsi/inia100.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/inia100.c	2003-07-19 17:03:50.000000000 -0700
-@@ -74,7 +74,7 @@
- #include <linux/interrupt.h>
- #include <linux/pci.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include <linux/stat.h>
- #include <linux/kernel.h>
---- linux-2.6.0-test1/drivers/scsi/ips.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/ips.c	2003-07-19 17:03:50.000000000 -0700
-@@ -167,7 +167,7 @@
- #include <linux/reboot.h>
- #include <linux/interrupt.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/types.h>
- 
- #include <scsi/sg.h>
---- linux-2.6.0-test1/drivers/scsi/ips.h	2003-06-14 12:18:03.000000000 -0700
-+++ 25/drivers/scsi/ips.h	2003-07-19 17:03:50.000000000 -0700
-@@ -111,7 +111,7 @@
-    #else
-       #define IPS_REGISTER_HOSTS(SHT)      (!ips_detect(SHT))
-       #define IPS_UNREGISTER_HOSTS(SHT)
--      #define IPS_ADD_HOST(shost,device)   scsi_add_host(shost,device)
-+      #define IPS_ADD_HOST(shost,device)   do { scsi_add_host(shost,device); scsi_scan_host(shost); } while (0)
-       #define IPS_REMOVE_HOST(shost)       scsi_remove_host(shost)
-       #define IPS_SCSI_SET_DEVICE(sh,ha)   scsi_set_device(sh, &(ha)->pcidev->dev)
-       #define IPS_PRINTK(level, pcidev, format, arg...)                 \
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_1000.h	2003-07-19 17:06:32.000000000 -0700
-@@ -0,0 +1,3224 @@
-+/* @(#)asm_1000.h 1.2 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+#ifndef	ISP_TARGET_MODE
-+/*
-+ *	Firmware Version 1.37.00 (11:28 Aug 28, 2000)
-+ */
-+static const u_int16_t isp_1000_risc_code[] = {
-+	0x0078, 0x1041, 0x0000, 0x2757, 0x0000, 0x12ff, 0x2043, 0x4f50,
-+	0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932,
-+	0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749,
-+	0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049,
-+	0x5350, 0x3130, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520,
-+	0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3337, 0x2020,
-+	0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3135,
-+	0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2000, 0x3030,
-+	0x2024, 0x20b9, 0x1212, 0x20c1, 0x0008, 0x2071, 0x0010, 0x70c3,
-+	0x0004, 0x20c9, 0x5cff, 0x2089, 0x10ee, 0x70c7, 0x4953, 0x70cb,
-+	0x5020, 0x70cf, 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2031,
-+	0x0030, 0x2079, 0x3800, 0x7863, 0x0000, 0x2fa0, 0x2009, 0x031b,
-+	0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x1062,
-+	0x789b, 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f, 0x0bb8,
-+	0x2009, 0x3835, 0x200b, 0x0003, 0x78bb, 0x0000, 0x78bf, 0x0000,
-+	0x78c3, 0x0000, 0x2069, 0x3840, 0x00a8, 0x1085, 0x681b, 0x003c,
-+	0x2009, 0x1313, 0x21b8, 0x0078, 0x1087, 0x681b, 0x0028, 0x6807,
-+	0x0007, 0x680b, 0x00fa, 0x680f, 0x0008, 0x6813, 0x0005, 0x681f,
-+	0x0000, 0x6823, 0x0006, 0x6817, 0x0008, 0x6827, 0x0000, 0x2069,
-+	0x3a80, 0x2011, 0x0020, 0x2009, 0x0010, 0x680b, 0x0c19, 0x680f,
-+	0x0019, 0x6803, 0xdd00, 0x6807, 0x001a, 0x6a1a, 0x2d00, 0xa0e8,
-+	0x0008, 0xa290, 0x0004, 0x8109, 0x00c0, 0x109d, 0x2069, 0x3b00,
-+	0x2009, 0x0002, 0x20a9, 0x0100, 0x683f, 0x0000, 0x2001, 0x0008,
-+	0x8007, 0x6832, 0x6837, 0x000a, 0x680b, 0x0040, 0x6817, 0x0100,
-+	0x681f, 0x0064, 0xade8, 0x0010, 0x0070, 0x10c8, 0x0078, 0x10b4,
-+	0x8109, 0x00c0, 0x10b2, 0x1078, 0x1b64, 0x1078, 0x31c0, 0x1078,
-+	0x1747, 0x1078, 0x368b, 0x3200, 0xa085, 0x000d, 0x2090, 0x70c3,
-+	0x0000, 0x0090, 0x10e2, 0x70c0, 0xa086, 0x0002, 0x00c0, 0x10e2,
-+	0x1078, 0x11e0, 0x1078, 0x1112, 0x1078, 0x18f2, 0x1078, 0x1aaf,
-+	0x1078, 0x34fd, 0x1078, 0x184d, 0x0078, 0x10e2, 0x10f6, 0x10f8,
-+	0x1d05, 0x1d05, 0x321e, 0x321e, 0x1d05, 0x1d05, 0x0078, 0x10f6,
-+	0x0078, 0x10f8, 0x0078, 0x10fa, 0x0078, 0x10fc, 0x7008, 0x800c,
-+	0x00c8, 0x110d, 0x7007, 0x0002, 0xa08c, 0x000c, 0x00c0, 0x110e,
-+	0x8004, 0x8004, 0x00c8, 0x110d, 0x087a, 0x097a, 0x70c3, 0x4002,
-+	0x0078, 0x11e3, 0x7814, 0xa005, 0x00c0, 0x111a, 0x0010, 0x1156,
-+	0x0078, 0x1155, 0x2009, 0x3868, 0x2104, 0xa005, 0x00c0, 0x1155,
-+	0x7814, 0xa086, 0x0001, 0x00c0, 0x1127, 0x1078, 0x15ae, 0x7817,
-+	0x0000, 0x2009, 0x386f, 0x2104, 0xa065, 0x0040, 0x1143, 0x2009,
-+	0x386a, 0x211c, 0x8108, 0x2114, 0x8108, 0x2104, 0xa210, 0xa399,
-+	0x0000, 0x2009, 0x0018, 0x6083, 0x0103, 0x1078, 0x16d7, 0x00c0,
-+	0x114f, 0x1078, 0x173e, 0x2009, 0x386f, 0x200b, 0x0000, 0x2009,
-+	0x3869, 0x2104, 0x200b, 0x0000, 0xa005, 0x0040, 0x1153, 0x2001,
-+	0x4005, 0x0078, 0x11e2, 0x0078, 0x11e0, 0x007c, 0x2061, 0x0000,
-+	0x6018, 0xa084, 0x0001, 0x0040, 0x115e, 0x007c, 0x70c3, 0x0000,
-+	0x70c7, 0x0000, 0x70cb, 0x0000, 0x70cf, 0x0000, 0x70c0, 0xa0bc,
-+	0xffc0, 0x00c0, 0x11ae, 0x2038, 0x0079, 0x116e, 0x11e0, 0x122e,
-+	0x11fc, 0x122e, 0x127f, 0x127f, 0x11f3, 0x1608, 0x128a, 0x11ef,
-+	0x1200, 0x1202, 0x1204, 0x1206, 0x160d, 0x11ef, 0x1292, 0x12ba,
-+	0x15bc, 0x1602, 0x1208, 0x14e3, 0x1505, 0x151f, 0x1548, 0x149c,
-+	0x14aa, 0x14be, 0x14d2, 0x1357, 0x1332, 0x12e2, 0x12e9, 0x12ee,
-+	0x12f3, 0x12f9, 0x12fe, 0x1303, 0x1308, 0x130d, 0x1311, 0x1326,
-+	0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x1363, 0x136c, 0x137b,
-+	0x13a1, 0x13ab, 0x13b2, 0x13d8, 0x13e7, 0x13f6, 0x1408, 0x147a,
-+	0x11ef, 0x148a, 0x11ef, 0x11ef, 0x11ef, 0x1491, 0xa0bc, 0xffa0,
-+	0x00c0, 0x11ef, 0x2038, 0xa084, 0x001f, 0x0079, 0x11b7, 0x11ef,
-+	0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef,
-+	0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x1665, 0x1674, 0x11ef,
-+	0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef, 0x11ef,
-+	0x11ef, 0x16b3, 0x16bd, 0x16c1, 0x16cf, 0x167f, 0x169c, 0x72ca,
-+	0x71c6, 0x2001, 0x4006, 0x0078, 0x11e2, 0x73ce, 0x72ca, 0x71c6,
-+	0x2001, 0x4000, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091,
-+	0x5000, 0x2091, 0x4080, 0x007c, 0x71c6, 0x0078, 0x11e2, 0x70c3,
-+	0x4001, 0x0078, 0x11e3, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9,
-+	0x0005, 0x53a3, 0x0078, 0x11e0, 0x70c4, 0x70c3, 0x0004, 0x007a,
-+	0x0078, 0x11e0, 0x0078, 0x11e0, 0x0078, 0x11e0, 0x0078, 0x11e0,
-+	0x2091, 0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020,
-+	0x70cf, 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2079, 0x0000,
-+	0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457,
-+	0x2051, 0x0470, 0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000,
-+	0x2091, 0x5000, 0x2091, 0x4080, 0x0078, 0x0455, 0x71d0, 0x72c8,
-+	0x73cc, 0x70c4, 0x20a0, 0x2098, 0x2031, 0x0030, 0x81ff, 0x0040,
-+	0x11e0, 0x7007, 0x0004, 0x731a, 0x721e, 0x2051, 0x0012, 0x2049,
-+	0x125d, 0x2041, 0x11e0, 0x7003, 0x0002, 0xa786, 0x0001, 0x00c0,
-+	0x124f, 0x2049, 0x126b, 0x2041, 0x1277, 0x7003, 0x0003, 0x7017,
-+	0x0000, 0x810b, 0x7112, 0x00c8, 0x1257, 0x7017, 0x0001, 0x7007,
-+	0x0001, 0xa786, 0x0001, 0x0040, 0x126b, 0x700c, 0xa084, 0x007f,
-+	0x8004, 0x2009, 0x0020, 0xa102, 0x0942, 0x094a, 0x20a8, 0x26a0,
-+	0x53a6, 0x0078, 0x10fe, 0x700c, 0xa084, 0x007f, 0x0040, 0x126b,
-+	0x80ac, 0x0048, 0x126b, 0x2698, 0x53a5, 0x0078, 0x10fe, 0x700c,
-+	0xa084, 0x007f, 0x80ac, 0x2698, 0x53a5, 0x0078, 0x11e0, 0x71c4,
-+	0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1287, 0x200a, 0x72ca,
-+	0x0078, 0x11df, 0x70c7, 0x0125, 0x70cb, 0x0000, 0x70cf, 0x0f00,
-+	0x0078, 0x11e0, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
-+	0x73ce, 0x74d2, 0xa005, 0x0040, 0x12b4, 0x8001, 0x7872, 0xa084,
-+	0xfc00, 0x0040, 0x12ab, 0x7898, 0xa085, 0x0001, 0x789a, 0x2001,
-+	0x4005, 0x0078, 0x11e2, 0x7a7a, 0x7b7e, 0x7c76, 0x7898, 0xa084,
-+	0xfffc, 0x789a, 0x0078, 0x12b8, 0x7898, 0xa085, 0x0001, 0x789a,
-+	0x0078, 0x11e0, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca,
-+	0x73ce, 0x74d6, 0xa005, 0x0040, 0x12dc, 0x8001, 0x7886, 0xa084,
-+	0xfc00, 0x0040, 0x12d3, 0x7898, 0xa085, 0x0100, 0x789a, 0x2001,
-+	0x4005, 0x0078, 0x11e2, 0x7a8e, 0x7b92, 0x7c8a, 0x7898, 0xa084,
-+	0xfcff, 0x789a, 0x0078, 0x12e0, 0x7898, 0xa085, 0x0100, 0x789a,
-+	0x0078, 0x11e0, 0x2009, 0x3859, 0x210c, 0x2011, 0x0372, 0x0078,
-+	0x11de, 0x2009, 0x3841, 0x210c, 0x0078, 0x11df, 0x2009, 0x3842,
-+	0x210c, 0x0078, 0x11df, 0x2061, 0x3840, 0x610c, 0x6210, 0x0078,
-+	0x11de, 0x2009, 0x3845, 0x210c, 0x0078, 0x11df, 0x2009, 0x3846,
-+	0x210c, 0x0078, 0x11df, 0x2009, 0x3847, 0x210c, 0x0078, 0x11df,
-+	0x2009, 0x3848, 0x210c, 0x0078, 0x11df, 0x7908, 0x7a0c, 0x0078,
-+	0x11de, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa0e8, 0x3a80, 0x6a00, 0x6804, 0xa084, 0x0008, 0x0040, 0x1323,
-+	0x6b08, 0x0078, 0x1324, 0x6b0c, 0x0078, 0x11dd, 0x77c4, 0x1078,
-+	0x1758, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x11dd, 0x2091, 0x8000, 0x7848, 0xa005, 0x00c0, 0x1346,
-+	0x2061, 0x3b00, 0x20a9, 0x0100, 0x603c, 0xa005, 0x00c0, 0x1346,
-+	0xace0, 0x0010, 0x00f0, 0x133c, 0x0078, 0x134e, 0x2019, 0x0000,
-+	0x2011, 0x0000, 0x2009, 0x0000, 0x0078, 0x1353, 0x7bb8, 0x7abc,
-+	0x79c0, 0x78c3, 0x0000, 0x2091, 0x8001, 0x0078, 0x11dd, 0x77c4,
-+	0x1078, 0x1758, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
-+	0x8001, 0x0078, 0x11dd, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x11d8,
-+	0x1078, 0x1be8, 0x0078, 0x11dd, 0x71c4, 0xa182, 0x0010, 0x00c8,
-+	0x11d8, 0x2011, 0x3841, 0x2204, 0x007e, 0x2112, 0x1078, 0x1ba1,
-+	0x017f, 0x0078, 0x11df, 0x71c4, 0x2011, 0x1399, 0x20a9, 0x0008,
-+	0x2204, 0xa106, 0x0040, 0x138b, 0x8210, 0x0070, 0x1389, 0x0078,
-+	0x1380, 0x0078, 0x11d8, 0xa292, 0x1399, 0x027e, 0x2011, 0x3842,
-+	0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x1bad, 0x017f, 0x0078,
-+	0x11df, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
-+	0x004b, 0x2061, 0x3840, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
-+	0x6012, 0x0078, 0x11de, 0x2061, 0x3840, 0x6114, 0x70c4, 0x6016,
-+	0x0078, 0x11df, 0x71c4, 0x2011, 0x0004, 0x2019, 0x1212, 0xa186,
-+	0x0028, 0x0040, 0x13cb, 0x2011, 0x0005, 0x2019, 0x1212, 0xa186,
-+	0x0032, 0x0040, 0x13cb, 0x2011, 0x0006, 0x2019, 0x1313, 0xa186,
-+	0x003c, 0x00c0, 0x11d8, 0x2061, 0x3840, 0x6018, 0x007e, 0x611a,
-+	0x23b8, 0x1078, 0x1bbe, 0x1078, 0x368b, 0x017f, 0x0078, 0x11df,
-+	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x11d8, 0x2011, 0x3847, 0x2204,
-+	0x2112, 0x007e, 0x1078, 0x1be0, 0x017f, 0x0078, 0x11df, 0x71c4,
-+	0xa182, 0x0010, 0x00c8, 0x11d8, 0x2011, 0x3848, 0x2204, 0x007e,
-+	0x2112, 0x1078, 0x1bcf, 0x017f, 0x0078, 0x11df, 0x71c4, 0x72c8,
-+	0xa184, 0xfffd, 0x00c0, 0x11d7, 0xa284, 0xfffd, 0x00c0, 0x11d7,
-+	0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x11de,
-+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
-+	0x3a80, 0x2019, 0x0000, 0x72c8, 0x6800, 0x007e, 0xa226, 0x0040,
-+	0x1440, 0xa284, 0x0001, 0x0040, 0x1422, 0x2220, 0xa39d, 0x0002,
-+	0xa294, 0xfffe, 0x6a02, 0xa484, 0x2000, 0x0040, 0x1429, 0xa39d,
-+	0x0010, 0xa484, 0x1000, 0x0040, 0x142f, 0xa39d, 0x0008, 0xa484,
-+	0x4000, 0x0040, 0x1440, 0x810f, 0xa284, 0x4000, 0x0040, 0x143c,
-+	0x1078, 0x1c02, 0x0078, 0x1440, 0x1078, 0x1bf4, 0x0078, 0x1440,
-+	0x72cc, 0x82ff, 0x0040, 0x1472, 0x6808, 0xa206, 0x0040, 0x1472,
-+	0xa2a4, 0x00ff, 0x2061, 0x3840, 0x6118, 0xa186, 0x0028, 0x0040,
-+	0x1459, 0xa186, 0x0032, 0x0040, 0x145f, 0xa186, 0x003c, 0x0040,
-+	0x1465, 0xa482, 0x0064, 0x0048, 0x146f, 0x0078, 0x1469, 0xa482,
-+	0x0050, 0x0048, 0x146f, 0x0078, 0x1469, 0xa482, 0x0043, 0x0048,
-+	0x146f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x11d9, 0x6a0a,
-+	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
-+	0x0078, 0x11dd, 0x77c4, 0x1078, 0x1758, 0x2091, 0x8000, 0x6a14,
-+	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
-+	0x0078, 0x11dd, 0x2011, 0x3835, 0x220c, 0x70c4, 0x2012, 0x0078,
-+	0x11df, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x11d8,
-+	0x1078, 0x1c10, 0x0078, 0x11dd, 0x77c4, 0x1078, 0x1758, 0x2091,
-+	0x8000, 0x6a08, 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x11de, 0x77c4, 0x1078, 0x1758, 0x2091, 0x8000, 0x6a08,
-+	0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x14b9, 0x1078,
-+	0x1b49, 0x2091, 0x8001, 0x2708, 0x0078, 0x11de, 0x77c4, 0x1078,
-+	0x1758, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804,
-+	0xa005, 0x0040, 0x14cd, 0x1078, 0x1b49, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x11de, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051,
-+	0x0020, 0x2091, 0x8000, 0x1078, 0x1765, 0x2091, 0x8001, 0x2708,
-+	0x6a08, 0x0078, 0x11de, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca,
-+	0x73ce, 0x1078, 0x17e6, 0x00c0, 0x1501, 0x6818, 0xa005, 0x0040,
-+	0x14fb, 0x2708, 0x1078, 0x1c20, 0x00c0, 0x14fb, 0x7817, 0xffff,
-+	0x2091, 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078,
-+	0x11e2, 0x2091, 0x8001, 0x0078, 0x11e0, 0x77c4, 0x77c6, 0x2041,
-+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-+	0x1765, 0x2061, 0x3840, 0x60a3, 0x0003, 0x67b6, 0x60a7, 0x0000,
-+	0x7817, 0xffff, 0x1078, 0x1b49, 0x2091, 0x8001, 0x007c, 0x77c8,
-+	0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
-+	0x3840, 0x60a3, 0x0002, 0x60a7, 0x0000, 0x67b6, 0x7817, 0xffff,
-+	0x1078, 0x1b49, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0004,
-+	0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x1765, 0x70c8, 0x683e,
-+	0x8738, 0xa784, 0x001f, 0x00c0, 0x153c, 0x2091, 0x8001, 0x007c,
-+	0x7898, 0xa084, 0x0003, 0x00c0, 0x156c, 0x2039, 0x0000, 0x2041,
-+	0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078, 0x1758, 0x2091,
-+	0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x1555, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f,
-+	0xa784, 0x0f00, 0x00c0, 0x1555, 0x2091, 0x8000, 0x2069, 0x0100,
-+	0x6830, 0xa084, 0x0040, 0x0040, 0x1595, 0x684b, 0x0004, 0x20a9,
-+	0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x1582, 0x0070, 0x1582,
-+	0x0078, 0x1579, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084,
-+	0x0001, 0x0040, 0x158f, 0x0070, 0x158f, 0x0078, 0x1586, 0x20a9,
-+	0x00fa, 0x0070, 0x1595, 0x0078, 0x1591, 0x2079, 0x3800, 0x7817,
-+	0x0001, 0x2061, 0x3840, 0x60a3, 0x0001, 0x60a7, 0x0000, 0x60c3,
-+	0x000f, 0x7898, 0xa085, 0x0002, 0x789a, 0x6808, 0xa084, 0xfffd,
-+	0x680a, 0x681b, 0x0046, 0x2091, 0x8001, 0x007c, 0x7898, 0xa084,
-+	0xfffd, 0x789a, 0xa084, 0x0001, 0x00c0, 0x15b8, 0x1078, 0x1830,
-+	0x71c4, 0x71c6, 0x794a, 0x007c, 0x74c4, 0x73c8, 0x72cc, 0x74c6,
-+	0x73ca, 0x72ce, 0x2079, 0x3800, 0x2009, 0x0040, 0x1078, 0x1735,
-+	0x0040, 0x15fe, 0x1078, 0x1705, 0x0040, 0x15d2, 0x1078, 0x173e,
-+	0x0078, 0x15fe, 0x6010, 0x2091, 0x8000, 0x7817, 0xffff, 0x2009,
-+	0x3868, 0x200b, 0x0005, 0x8108, 0x200b, 0x0000, 0x8108, 0x230a,
-+	0x8108, 0x220a, 0x8108, 0x240a, 0x8108, 0x200a, 0x8108, 0x200b,
-+	0x0000, 0x8108, 0x2c0a, 0xa02e, 0x2530, 0x0e7e, 0x1078, 0x3199,
-+	0x0e7f, 0x6592, 0x65a2, 0x6696, 0x66a6, 0x60ab, 0x0000, 0x60af,
-+	0x0000, 0x1078, 0x1b49, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005,
-+	0x0078, 0x11e3, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x11e0,
-+	0x71c4, 0x71c6, 0x2168, 0x0078, 0x160f, 0x2069, 0x1000, 0x690c,
-+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1611, 0xa285,
-+	0x0000, 0x00c0, 0x161f, 0x70c3, 0x4000, 0x0078, 0x1621, 0x70c3,
-+	0x4003, 0x70ca, 0x0078, 0x11e3, 0x71c4, 0x72c8, 0x73cc, 0x2100,
-+	0xa184, 0xfffc, 0x00c0, 0x11ef, 0x2100, 0x0079, 0x162f, 0x1646,
-+	0x165b, 0x165d, 0x165f, 0x70c3, 0x4003, 0x71ce, 0x72d2, 0x73d6,
-+	0x0078, 0x1642, 0x70c3, 0x4000, 0x70cf, 0x0000, 0x70d3, 0x0000,
-+	0x70d7, 0x0000, 0x77c6, 0x71ca, 0x0078, 0x11e0, 0x2031, 0x1661,
-+	0x2624, 0x8630, 0x2412, 0x2204, 0xa446, 0x00c0, 0x1633, 0xa484,
-+	0xffff, 0x00c0, 0x1648, 0x2031, 0x1661, 0x8210, 0x8319, 0xa384,
-+	0xffff, 0x00c0, 0x1648, 0x0078, 0x163a, 0x0078, 0x163a, 0x0078,
-+	0x163a, 0x5555, 0xaaaa, 0xffff, 0x0000, 0x77c4, 0x1078, 0x1758,
-+	0x2091, 0x8000, 0x6830, 0xa084, 0xff00, 0x8007, 0x2010, 0x2091,
-+	0x8001, 0x2708, 0x0078, 0x11de, 0x77c4, 0x1078, 0x1758, 0x2091,
-+	0x8000, 0x6a34, 0x2091, 0x8001, 0x2708, 0x0078, 0x11de, 0x77c4,
-+	0x077e, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0x72c8, 0x8217, 0xa294,
-+	0xff00, 0x1078, 0x1758, 0x2091, 0x8000, 0x6c30, 0x6a32, 0x2091,
-+	0x8001, 0x8738, 0x00f0, 0x1689, 0x077f, 0x2708, 0x8427, 0xa4a4,
-+	0x00ff, 0x2410, 0x0078, 0x11de, 0x77c4, 0x077e, 0xa7bc, 0xff00,
-+	0x20a9, 0x0020, 0x72c8, 0x1078, 0x1758, 0x2091, 0x8000, 0x6c34,
-+	0x6a36, 0x2091, 0x8001, 0x8738, 0x00f0, 0x16a3, 0x077f, 0x2708,
-+	0x2410, 0x0078, 0x11de, 0x7960, 0x71c6, 0x71c4, 0xa182, 0x0003,
-+	0x00c8, 0x11d8, 0x7962, 0x0078, 0x11e0, 0x7960, 0x71c6, 0x0078,
-+	0x11e0, 0x7954, 0x71c6, 0x71c4, 0x7956, 0x7958, 0x71ca, 0x71c8,
-+	0x795a, 0x795c, 0x71ce, 0x71cc, 0x795e, 0x0078, 0x11e0, 0x7954,
-+	0x71c6, 0x7958, 0x71ca, 0x795c, 0x71ce, 0x0078, 0x11e0, 0x700c,
-+	0xa084, 0x007f, 0x0040, 0x16e3, 0x7007, 0x0004, 0x7004, 0xa084,
-+	0x0004, 0x00c0, 0x16de, 0x7017, 0x0000, 0x7112, 0x721a, 0x731e,
-+	0x8108, 0x810c, 0x81a9, 0x8c98, 0x20a1, 0x0030, 0x6080, 0x20a2,
-+	0x53a6, 0x780c, 0xa085, 0x0000, 0x7002, 0x7007, 0x0001, 0x7108,
-+	0x8104, 0x00c8, 0x16f7, 0x7007, 0x0002, 0xa184, 0x000c, 0x710c,
-+	0xa184, 0x0300, 0x7003, 0x0000, 0x007c, 0x700c, 0xa084, 0x007f,
-+	0x0040, 0x1711, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-+	0x170c, 0x7017, 0x0000, 0x7112, 0x721a, 0x731e, 0x2099, 0x0030,
-+	0x8108, 0x81ac, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001,
-+	0x7008, 0x800c, 0x00c8, 0x1720, 0x7007, 0x0002, 0xa08c, 0x000c,
-+	0x00c0, 0x1732, 0x710c, 0xa184, 0x0300, 0x00c0, 0x1732, 0x2ca0,
-+	0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x7850, 0xa065, 0x0040,
-+	0x173d, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079,
-+	0x3800, 0x7850, 0x2062, 0x2c00, 0x7852, 0x0f7f, 0x007c, 0x2011,
-+	0x5d00, 0x7a52, 0x2019, 0x0372, 0x8319, 0x0040, 0x1755, 0xa280,
-+	0x002f, 0x2012, 0x2010, 0x0078, 0x174c, 0x2013, 0x0000, 0x007c,
-+	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003,
-+	0x8003, 0xa105, 0xa0e8, 0x3b00, 0x007c, 0x1078, 0x1758, 0x2900,
-+	0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a,
-+	0x2091, 0x8000, 0x2009, 0x384f, 0x210c, 0x6804, 0xa005, 0x0040,
-+	0x1784, 0xa116, 0x00c0, 0x1784, 0x2060, 0x6000, 0x6806, 0x017e,
-+	0x200b, 0x0000, 0x0078, 0x1787, 0x2009, 0x0000, 0x017e, 0x6804,
-+	0xa065, 0x0040, 0x1798, 0x6000, 0x6806, 0x1078, 0x17ad, 0x1078,
-+	0x18a4, 0x1078, 0x2b27, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1787,
-+	0x1078, 0x2b27, 0x017f, 0x6902, 0x6906, 0x2091, 0x8001, 0x007c,
-+	0xa065, 0x0040, 0x17ac, 0x6098, 0x609b, 0x0000, 0x2008, 0x1078,
-+	0x173e, 0x2100, 0x0078, 0x17a0, 0x007c, 0x6003, 0x0103, 0x20a9,
-+	0x001c, 0xac80, 0x0004, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-+	0x6016, 0x682c, 0x601e, 0x007c, 0x0e7e, 0x2071, 0x3840, 0x7040,
-+	0xa08c, 0x0200, 0x00c0, 0x17ca, 0xa088, 0x3880, 0x2d0a, 0x8000,
-+	0x7042, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x3840, 0x2009,
-+	0x3880, 0x7240, 0x8221, 0x8211, 0x0048, 0x17e4, 0x2104, 0x8108,
-+	0xad06, 0x00c0, 0x17d3, 0x8119, 0x211e, 0x8108, 0x8318, 0x8211,
-+	0x00c8, 0x17dc, 0x7442, 0xa006, 0x0e7f, 0x007c, 0x1078, 0x1758,
-+	0x2091, 0x8000, 0x6804, 0x781e, 0xa065, 0x0040, 0x182f, 0x0078,
-+	0x17f7, 0x2c00, 0x781e, 0x6000, 0xa065, 0x0040, 0x182f, 0x600c,
-+	0xa306, 0x00c0, 0x17f1, 0x6008, 0xa206, 0x00c0, 0x17f1, 0x2c28,
-+	0x2001, 0x384f, 0x2004, 0xac06, 0x0040, 0x182f, 0x6804, 0xac06,
-+	0x00c0, 0x1814, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1814,
-+	0x6803, 0x0000, 0x0078, 0x181e, 0x6400, 0x781c, 0x2060, 0x6402,
-+	0xa486, 0x0000, 0x00c0, 0x181e, 0x2c00, 0x6802, 0x2560, 0x1078,
-+	0x17ad, 0x6017, 0x0005, 0x601f, 0x0020, 0x1078, 0x18a4, 0x1078,
-+	0x2b27, 0x6810, 0x8001, 0x6812, 0x2001, 0xffff, 0xa005, 0x007c,
-+	0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-+	0x2091, 0x8000, 0x1078, 0x1765, 0x8738, 0xa784, 0x001f, 0x00c0,
-+	0x183a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
-+	0x00c0, 0x183a, 0x2091, 0x8001, 0x007c, 0x0068, 0x185c, 0x2061,
-+	0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x185c, 0x78ac, 0x78af,
-+	0x0000, 0xa005, 0x00c0, 0x185d, 0x007c, 0xa08c, 0xfff0, 0x0040,
-+	0x1863, 0x1078, 0x1ce7, 0x0079, 0x1865, 0x1875, 0x1877, 0x187d,
-+	0x1881, 0x1875, 0x1885, 0x1875, 0x1875, 0x188b, 0x1875, 0x1892,
-+	0x1896, 0x1875, 0x1875, 0x1875, 0x1875, 0x1078, 0x1ce7, 0x1078,
-+	0x1830, 0x2001, 0x8001, 0x0078, 0x189c, 0x2001, 0x8003, 0x0078,
-+	0x189c, 0x2001, 0x8004, 0x0078, 0x189c, 0x1078, 0x1830, 0x2001,
-+	0x8006, 0x0078, 0x189c, 0x2001, 0x8009, 0x2011, 0x382c, 0x220c,
-+	0x0078, 0x11ec, 0x2001, 0x800c, 0x0078, 0x189c, 0x1078, 0x1830,
-+	0x2001, 0x800d, 0x0078, 0x189c, 0x70c2, 0x2061, 0x0000, 0x601b,
-+	0x0001, 0x2091, 0x4080, 0x007c, 0x2c04, 0x6082, 0x2c08, 0x2063,
-+	0x0000, 0x7864, 0x8000, 0x7866, 0x7868, 0xa005, 0x796a, 0x0040,
-+	0x18b4, 0x2c02, 0x0078, 0x18b5, 0x796e, 0x007c, 0x0c7e, 0x2061,
-+	0x3800, 0x6883, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6064, 0x8000,
-+	0x6066, 0x6068, 0xa005, 0x616a, 0x0040, 0x18c9, 0x2d02, 0x0078,
-+	0x18cc, 0x616e, 0x1078, 0x2b41, 0x0c7f, 0x007c, 0x1078, 0x18df,
-+	0x0040, 0x18de, 0x0c7e, 0x6098, 0xa065, 0x0040, 0x18d9, 0x1078,
-+	0x17a0, 0x0c7f, 0x609b, 0x0000, 0x1078, 0x173e, 0x007c, 0x786c,
-+	0xa065, 0x0040, 0x18f1, 0x2091, 0x8000, 0x7864, 0x8001, 0x7866,
-+	0x2c04, 0x786e, 0xa005, 0x00c0, 0x18ef, 0x786a, 0x8000, 0x2091,
-+	0x8001, 0x007c, 0x7898, 0xa005, 0x00c0, 0x194d, 0x7974, 0x70d0,
-+	0x0005, 0x0005, 0x72d0, 0xa206, 0x00c0, 0x18f7, 0x2200, 0xa106,
-+	0x00c0, 0x190e, 0x7804, 0xa005, 0x0040, 0x194d, 0x7807, 0x0000,
-+	0x0068, 0x194d, 0x2091, 0x4080, 0x0078, 0x194d, 0x1078, 0x1735,
-+	0x0040, 0x194d, 0x7a7c, 0x7b78, 0xa184, 0xff00, 0x0040, 0x1921,
-+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
-+	0x1924, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0x2009,
-+	0x0040, 0x1078, 0x1705, 0x0040, 0x1944, 0x1078, 0x173e, 0x7880,
-+	0x8000, 0x7882, 0xa086, 0x0002, 0x00c0, 0x194d, 0x2091, 0x8000,
-+	0x78af, 0x0002, 0x7883, 0x0000, 0x7898, 0xa085, 0x0003, 0x789a,
-+	0x2091, 0x8001, 0x0078, 0x194d, 0x7883, 0x0000, 0x1078, 0x1a99,
-+	0x6000, 0xa084, 0x0007, 0x0079, 0x194e, 0x007c, 0x1956, 0x1965,
-+	0x1985, 0x1956, 0x1997, 0x1956, 0x1956, 0x1956, 0x2039, 0x0400,
-+	0x78a8, 0xa705, 0x78aa, 0x6004, 0xa705, 0x6006, 0x1078, 0x19e2,
-+	0x6018, 0x78a6, 0x1078, 0x1a81, 0x007c, 0x78a8, 0xa084, 0x0100,
-+	0x0040, 0x196c, 0x0078, 0x1956, 0x78ab, 0x0000, 0x6000, 0x8007,
-+	0xa084, 0x00ff, 0x789e, 0x8001, 0x609b, 0x0000, 0x0040, 0x1982,
-+	0x1078, 0x19e2, 0x0040, 0x1982, 0x78a8, 0xa085, 0x0100, 0x78aa,
-+	0x0078, 0x1984, 0x1078, 0x1a06, 0x007c, 0x78a8, 0xa08c, 0x0e00,
-+	0x00c0, 0x198e, 0xa084, 0x0100, 0x00c0, 0x1990, 0x0078, 0x1956,
-+	0x1078, 0x19e2, 0x00c0, 0x1996, 0x1078, 0x1a06, 0x007c, 0x78a8,
-+	0xa084, 0x0100, 0x0040, 0x199e, 0x0078, 0x1956, 0x78ab, 0x0000,
-+	0x6710, 0x2011, 0x0001, 0x20a9, 0x0001, 0x6014, 0xa084, 0x00ff,
-+	0xa005, 0x0040, 0x19c1, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9,
-+	0x0020, 0xa08e, 0x0001, 0x0040, 0x19c1, 0x2039, 0x0000, 0x2011,
-+	0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x19c1, 0x0078,
-+	0x19df, 0x1078, 0x1758, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000,
-+	0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0x2d00, 0xa080,
-+	0x0010, 0x2068, 0x2091, 0x8001, 0x0070, 0x19d8, 0x0078, 0x19c4,
-+	0x8211, 0x0040, 0x19df, 0x20a9, 0x0100, 0x0078, 0x19c4, 0x1078,
-+	0x173e, 0x007c, 0x78a0, 0xa06d, 0x00c0, 0x19ed, 0x2c00, 0x78a2,
-+	0x78a6, 0x609b, 0x0000, 0x0078, 0x19f9, 0x2c00, 0x689a, 0x609b,
-+	0x0000, 0x78a2, 0x2d00, 0x6002, 0x78a4, 0xad06, 0x00c0, 0x19f9,
-+	0x6002, 0x789c, 0x8001, 0x789e, 0x00c0, 0x1a05, 0x78a8, 0xa084,
-+	0x0000, 0x78aa, 0x78a4, 0x2060, 0xa006, 0x007c, 0xa02e, 0x2530,
-+	0x6118, 0xa184, 0x0060, 0x619e, 0x0040, 0x1a12, 0x0e7e, 0x1078,
-+	0x3199, 0x0e7f, 0x6592, 0x65a2, 0x6696, 0x66a6, 0x60ab, 0x0000,
-+	0x60af, 0x0000, 0x6710, 0x1078, 0x1758, 0x2091, 0x8000, 0x6808,
-+	0xa084, 0x0001, 0x0040, 0x1a34, 0x2091, 0x8001, 0x1078, 0x17ad,
-+	0x2091, 0x8000, 0x1078, 0x18a4, 0x2091, 0x8001, 0x78a3, 0x0000,
-+	0x78a7, 0x0000, 0x0078, 0x1a80, 0x6020, 0xa096, 0x0001, 0x00c0,
-+	0x1a3b, 0x8000, 0x6022, 0x6a10, 0x6814, 0x2091, 0x8001, 0xa202,
-+	0x0048, 0x1a4a, 0x0040, 0x1a4a, 0x2039, 0x0200, 0x1078, 0x1a81,
-+	0x0078, 0x1a80, 0x2c08, 0x2091, 0x8000, 0x6800, 0xa065, 0x0040,
-+	0x1a52, 0x6102, 0x6902, 0x00c0, 0x1a56, 0x6906, 0x2160, 0x6003,
-+	0x0000, 0x6810, 0x8000, 0x6812, 0x78b8, 0x8000, 0x78ba, 0x2091,
-+	0x8001, 0x6808, 0xa08c, 0x0040, 0x0040, 0x1a76, 0xa086, 0x0040,
-+	0x680a, 0x1078, 0x17bc, 0x017e, 0x007e, 0x6930, 0x2100, 0x810f,
-+	0xa105, 0x6832, 0x6934, 0x693a, 0x007f, 0x017f, 0x2091, 0x8000,
-+	0x1078, 0x1b49, 0x2091, 0x8001, 0x78a7, 0x0000, 0x78a3, 0x0000,
-+	0x007c, 0x6004, 0xa705, 0x6006, 0x2091, 0x8000, 0x1078, 0x18a4,
-+	0x2091, 0x8001, 0x78a4, 0xa065, 0x0040, 0x1a94, 0x6098, 0x78a6,
-+	0x609b, 0x0000, 0x0078, 0x1a84, 0x78a3, 0x0000, 0x78a7, 0x0000,
-+	0x007c, 0x7970, 0x7874, 0x8000, 0xa10a, 0x00c8, 0x1aa0, 0xa006,
-+	0x7876, 0x70d2, 0x7804, 0xa005, 0x0040, 0x1aae, 0x8001, 0x7806,
-+	0x00c0, 0x1aae, 0x0068, 0x1aae, 0x2091, 0x4080, 0x007c, 0x0068,
-+	0x1ac9, 0x2029, 0x0000, 0x786c, 0xa065, 0x0040, 0x1ac4, 0x1078,
-+	0x1aca, 0x0040, 0x1ac4, 0x057e, 0x1078, 0x1ae8, 0x057f, 0x00c0,
-+	0x1ac4, 0x8528, 0x0078, 0x1ab3, 0x85ff, 0x0040, 0x1ac9, 0x2091,
-+	0x4080, 0x007c, 0x2091, 0x8000, 0x7b84, 0x7988, 0x72d4, 0x0005,
-+	0x0005, 0x70d4, 0xa206, 0x00c0, 0x1ace, 0x2200, 0xa102, 0x00c0,
-+	0x1ade, 0x2300, 0x2091, 0x8001, 0xa005, 0x007c, 0x0048, 0x1ae4,
-+	0xa302, 0x2091, 0x8001, 0x007c, 0x8002, 0x2091, 0x8001, 0x007c,
-+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1b3f,
-+	0x7008, 0x7208, 0xa206, 0x00c0, 0x1b3f, 0xa286, 0x0002, 0x00c0,
-+	0x1b3f, 0x2071, 0x0010, 0xa184, 0xff00, 0x0040, 0x1b08, 0x810f,
-+	0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x1b0b,
-+	0x8107, 0x8004, 0x8004, 0x7a90, 0x7b8c, 0xa210, 0xa399, 0x0000,
-+	0x2009, 0x0018, 0x6024, 0xa005, 0x0040, 0x1b18, 0x2009, 0x0040,
-+	0x1078, 0x16d7, 0x0040, 0x1b31, 0x7894, 0x8000, 0x7896, 0xa086,
-+	0x0002, 0x00c0, 0x1b3f, 0x2091, 0x8000, 0x78af, 0x0003, 0x7897,
-+	0x0000, 0x7898, 0xa085, 0x0300, 0x789a, 0x2091, 0x8001, 0x0078,
-+	0x1b3f, 0x7897, 0x0000, 0x1078, 0x18ce, 0x7984, 0x7888, 0x8000,
-+	0xa10a, 0x00c8, 0x1b3c, 0xa006, 0x788a, 0x70d6, 0xa006, 0x2071,
-+	0x0010, 0x2091, 0x8001, 0x007c, 0x2009, 0x3868, 0x2091, 0x8000,
-+	0x200a, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3840, 0x2104, 0xa086,
-+	0x0000, 0x00c0, 0x1b62, 0x2009, 0x3812, 0x2104, 0xa005, 0x00c0,
-+	0x1b62, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x1b62, 0x0018, 0x1b62,
-+	0x781b, 0x0044, 0x0f7f, 0x007c, 0x127e, 0x2091, 0x2300, 0x2071,
-+	0x3840, 0x2079, 0x0100, 0x2019, 0x305e, 0x20a1, 0x012b, 0x2304,
-+	0xa005, 0x0040, 0x1b7c, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398,
-+	0x53a6, 0x3318, 0x0078, 0x1b6f, 0x789b, 0x0020, 0x20a9, 0x0010,
-+	0x78af, 0x0000, 0x78af, 0x0220, 0x0070, 0x1b88, 0x0078, 0x1b80,
-+	0x7003, 0x0000, 0x1078, 0x1c87, 0x7004, 0xa084, 0x000f, 0xa085,
-+	0x6280, 0x7806, 0x780f, 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080,
-+	0x780b, 0x0008, 0x7047, 0x387f, 0x7043, 0x0000, 0x127f, 0x2000,
-+	0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, 0xfff0,
-+	0xa105, 0x2012, 0x1078, 0x1c87, 0x007c, 0x2011, 0x0101, 0x20a9,
-+	0x0009, 0x810b, 0x0070, 0x1bb6, 0x0078, 0x1bb1, 0xa18c, 0x0e00,
-+	0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, 0x0101,
-+	0x20a9, 0x0005, 0x8213, 0x0070, 0x1bc7, 0x0078, 0x1bc2, 0xa294,
-+	0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, 0x2011,
-+	0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x1bd8, 0x0078, 0x1bd3,
-+	0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c,
-+	0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c,
-+	0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a,
-+	0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022,
-+	0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae,
-+	0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061,
-+	0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c,
-+	0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a,
-+	0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c,
-+	0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x1c65,
-+	0x2061, 0x5c00, 0x1078, 0x1c6d, 0x0040, 0x1c53, 0x20a9, 0x0000,
-+	0x2061, 0x5b00, 0x0c7e, 0x1078, 0x1c6d, 0x0040, 0x1c3f, 0x0c7f,
-+	0x8c60, 0x0070, 0x1c3d, 0x0078, 0x1c32, 0x0078, 0x1c65, 0x007f,
-+	0xa082, 0x5b00, 0x2071, 0x3840, 0x70ba, 0x601c, 0xa085, 0x0800,
-+	0x601e, 0x71b6, 0x60a7, 0x0000, 0x2001, 0x0004, 0x70a2, 0x1078,
-+	0x1b44, 0x0078, 0x1c61, 0x2071, 0x3840, 0x601c, 0xa085, 0x0800,
-+	0x601e, 0x71b6, 0x60a7, 0x0000, 0x2001, 0x0006, 0x70a2, 0x1078,
-+	0x1b44, 0x2001, 0x0000, 0x0078, 0x1c67, 0x2001, 0x0001, 0x2091,
-+	0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040,
-+	0x1c84, 0x2060, 0x600c, 0xa306, 0x00c0, 0x1c81, 0x6008, 0xa206,
-+	0x00c0, 0x1c81, 0x6010, 0xa106, 0x00c0, 0x1c81, 0xa006, 0x0078,
-+	0x1c86, 0x6000, 0x0078, 0x1c6e, 0xa085, 0x0001, 0x007c, 0x2011,
-+	0x3841, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084,
-+	0x0100, 0x0040, 0x1c96, 0x2021, 0xff00, 0x2122, 0x007c, 0x0e7e,
-+	0x68e4, 0xa08c, 0x0020, 0x0040, 0x1ce5, 0xa084, 0x0006, 0x00c0,
-+	0x1ce5, 0x6010, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa0f0, 0x3a80, 0x7004, 0xa084, 0x000a, 0x00c0, 0x1ce5, 0x7108,
-+	0xa194, 0xff00, 0x0040, 0x1ce5, 0xa18c, 0x00ff, 0x7104, 0xa084,
-+	0x0014, 0x00c0, 0x1cd2, 0x017e, 0x611c, 0xa18d, 0x0002, 0x611e,
-+	0x017f, 0xa085, 0x0014, 0x7006, 0x2001, 0x000c, 0xa106, 0x0040,
-+	0x1cce, 0x2100, 0x8003, 0x2008, 0x0078, 0x1ce2, 0x2009, 0x0019,
-+	0x0078, 0x1ce2, 0x2011, 0x0000, 0x7000, 0xa084, 0xdfff, 0x7002,
-+	0x7004, 0xa084, 0xffef, 0x7006, 0x017e, 0x611c, 0xa18d, 0x0002,
-+	0x611e, 0x017f, 0x2100, 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068,
-+	0x1ce7, 0x007e, 0x2071, 0x0000, 0x7018, 0xa084, 0x0001, 0x00c0,
-+	0x1cec, 0x007f, 0x2e08, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6,
-+	0x70c3, 0x8002, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x007f, 0x2070, 0x007f, 0x0078, 0x1d03, 0x107e, 0x007e, 0x127e,
-+	0x2091, 0x2300, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0xa594, 0x003f,
-+	0xa484, 0x4000, 0x0040, 0x1d1a, 0xa784, 0x007c, 0x00c0, 0x3022,
-+	0x1078, 0x1ce7, 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x1d22,
-+	0x1078, 0x1ce7, 0x8507, 0xa084, 0x000f, 0x0079, 0x1d27, 0x21a1,
-+	0x2251, 0x2277, 0x24cf, 0x2787, 0x27cf, 0x2808, 0x2883, 0x28dd,
-+	0x2962, 0x1d4d, 0x1d37, 0x1fb8, 0x208d, 0x2766, 0x1d37, 0x1078,
-+	0x1ce7, 0x0018, 0x1d0a, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f,
-+	0x007c, 0x7003, 0x0000, 0x703f, 0x0000, 0x7030, 0xa005, 0x0040,
-+	0x1d4b, 0x7033, 0x0000, 0x0018, 0x1d0a, 0x705c, 0xa005, 0x00c0,
-+	0x1df8, 0x70a0, 0xa084, 0x001f, 0x0079, 0x1d56, 0x1e18, 0x1d5e,
-+	0x1d6c, 0x1d8d, 0x1db3, 0x1ddf, 0x1ddd, 0x1d5e, 0x7808, 0xa084,
-+	0xfffd, 0x780a, 0x2009, 0x0046, 0x1078, 0x260f, 0x00c0, 0x1d6a,
-+	0x7003, 0x0004, 0x0078, 0x1d39, 0x1078, 0x2fe4, 0x00c0, 0x1d8b,
-+	0x70b4, 0x8007, 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0x78ab,
-+	0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009,
-+	0x00f7, 0x1078, 0x260d, 0x00c0, 0x1d8b, 0x7003, 0x0004, 0x70c3,
-+	0x000f, 0x7033, 0x3870, 0x0078, 0x1d39, 0x1078, 0x2fe4, 0x00c0,
-+	0x1db1, 0x71b4, 0x8107, 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010,
-+	0xa18c, 0x0007, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b,
-+	0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078,
-+	0x260d, 0x00c0, 0x1db1, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033,
-+	0x3870, 0x0078, 0x1d39, 0x1078, 0x2fe4, 0x00c0, 0x1ddb, 0x71b4,
-+	0x8107, 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x0007,
-+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x71b8, 0x79aa, 0x78ab,
-+	0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009,
-+	0x00f7, 0x1078, 0x260d, 0x00c0, 0x1ddb, 0x7003, 0x0004, 0x70c3,
-+	0x000f, 0x7033, 0x3870, 0x0078, 0x1d39, 0x0078, 0x1d8d, 0x1078,
-+	0x2fe4, 0x00c0, 0x1d39, 0x70bc, 0x2068, 0x789b, 0x0010, 0x6f10,
-+	0x1078, 0x2f11, 0x2c50, 0x6810, 0xa084, 0x001f, 0xa085, 0x0080,
-+	0x78aa, 0x6e18, 0x2041, 0x0001, 0x2001, 0x0004, 0x0078, 0x1f41,
-+	0x1078, 0x2fe4, 0x00c0, 0x1d39, 0x789b, 0x0010, 0x705c, 0x2068,
-+	0x6f10, 0x1078, 0x2f11, 0x2c50, 0x6008, 0xa085, 0x0010, 0x600a,
-+	0x6810, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x2031, 0x0020,
-+	0x2041, 0x0001, 0x1078, 0x304b, 0x2001, 0x0003, 0x0078, 0x1f2c,
-+	0x0018, 0x1d0a, 0x7440, 0xa485, 0x0000, 0x0040, 0x1e32, 0xa080,
-+	0x3880, 0x2030, 0x7144, 0x8108, 0xa12a, 0x0048, 0x1e29, 0x2009,
-+	0x3880, 0x2164, 0x6504, 0x85ff, 0x00c0, 0x1e3f, 0x8421, 0x00c0,
-+	0x1e23, 0x7146, 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1d39,
-+	0x7640, 0xa6b0, 0x3880, 0x7144, 0x2600, 0x0078, 0x1e2e, 0x7146,
-+	0x2568, 0x2558, 0x753e, 0x2c50, 0x603c, 0xa085, 0x0000, 0x00c0,
-+	0x1e3c, 0x6708, 0x7736, 0xa784, 0x033f, 0x0040, 0x1e75, 0xa784,
-+	0x0021, 0x00c0, 0x1e3c, 0xa784, 0x0002, 0x0040, 0x1e5e, 0xa784,
-+	0x0004, 0x0040, 0x1e3c, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008,
-+	0x00c0, 0x1e3c, 0xa784, 0x0010, 0x00c0, 0x1e3c, 0xa184, 0x0200,
-+	0x00c0, 0x1e3c, 0xa784, 0x0100, 0x0040, 0x1e75, 0x6018, 0xa005,
-+	0x00c0, 0x1e3c, 0xa7bc, 0xfeff, 0x670a, 0x681f, 0x0000, 0x6e18,
-+	0xa684, 0x000e, 0x6118, 0x0040, 0x1e85, 0x601c, 0xa102, 0x0048,
-+	0x1e92, 0x0040, 0x1e92, 0x0078, 0x1e38, 0x81ff, 0x0040, 0x1e92,
-+	0x6828, 0x8007, 0xa084, 0x00ff, 0xa082, 0x0003, 0x0040, 0x1e92,
-+	0x00c0, 0x1e38, 0xa184, 0x0400, 0x00c0, 0x1ea1, 0x6130, 0xa18c,
-+	0xff00, 0x810f, 0x6030, 0xa084, 0xff00, 0xa105, 0x6032, 0x0078,
-+	0x1ea5, 0x6034, 0x603a, 0xa7bc, 0xfbff, 0xa784, 0x0080, 0x00c0,
-+	0x1eab, 0x700c, 0x6022, 0xa7bc, 0xff7f, 0x670a, 0x6b10, 0x8307,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3a80, 0x2060,
-+	0x2048, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0x2a60, 0x0018,
-+	0x1d0a, 0x789b, 0x0010, 0xa046, 0x1078, 0x2fe4, 0x00c0, 0x1d39,
-+	0x6b10, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x704c, 0xa084, 0x8000,
-+	0x0040, 0x1ed6, 0xa684, 0x0001, 0x0040, 0x1ed8, 0xa39c, 0xffbf,
-+	0xa684, 0x0010, 0x0040, 0x1ede, 0xa39d, 0x0020, 0x7baa, 0x8840,
-+	0xa684, 0x000e, 0x00c0, 0x1ee9, 0xa7bd, 0x0010, 0x670a, 0x0078,
-+	0x1f2a, 0x714c, 0xa18c, 0x0800, 0x0040, 0x2b74, 0x2011, 0x0021,
-+	0x8004, 0x8004, 0x0048, 0x1f00, 0x2011, 0x0022, 0x8004, 0x0048,
-+	0x1f00, 0x2011, 0x0020, 0x8004, 0x0048, 0x1f00, 0x0040, 0x1f2a,
-+	0x7aaa, 0x8840, 0x1078, 0x2ffd, 0x6a10, 0x610c, 0x8108, 0xa18c,
-+	0x00ff, 0xa1e0, 0x5b00, 0x2c64, 0x8cff, 0x0040, 0x1f21, 0x6010,
-+	0xa206, 0x00c0, 0x1f0b, 0x60b4, 0x8001, 0x60b6, 0x00c0, 0x1f06,
-+	0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078,
-+	0x1e18, 0x1078, 0x2fe4, 0x00c0, 0x1d39, 0x2a60, 0x610e, 0x79aa,
-+	0x8840, 0x712e, 0x2001, 0x0001, 0x007e, 0x7150, 0xa184, 0x0018,
-+	0x0040, 0x1f40, 0xa184, 0x0010, 0x0040, 0x1f3a, 0x1078, 0x2d3d,
-+	0x00c0, 0x1f40, 0xa184, 0x0008, 0x0040, 0x1f40, 0x1078, 0x2c58,
-+	0x007f, 0x7002, 0xa68c, 0x0060, 0x88ff, 0x0040, 0x1f49, 0xa18d,
-+	0x0004, 0x795a, 0x69b2, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b,
-+	0x0061, 0x6814, 0xa085, 0x8000, 0x6816, 0x78aa, 0x157e, 0x137e,
-+	0x147e, 0x20a1, 0x012c, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-+	0x000a, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6810, 0x8007,
-+	0x789b, 0x007e, 0x78aa, 0x6d90, 0x7dd6, 0x7dde, 0x6e94, 0x7ed2,
-+	0x7eda, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x1f78, 0x0098, 0x1f80,
-+	0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x2ffd, 0x0078, 0x1d41,
-+	0x7200, 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x1f8d, 0x781b,
-+	0x0049, 0x1078, 0x2ffd, 0x0078, 0x1f9e, 0x6ab0, 0xa295, 0x2000,
-+	0x7a5a, 0x781b, 0x0049, 0x1078, 0x2ffd, 0x7200, 0x2500, 0xa605,
-+	0x0040, 0x1f9e, 0xa284, 0x0007, 0x1079, 0x1fae, 0xad80, 0x0008,
-+	0x7032, 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x1fac, 0x6018,
-+	0x8000, 0x601a, 0x1078, 0x2b4b, 0x0078, 0x1d39, 0x1fb6, 0x3376,
-+	0x3376, 0x3365, 0x3376, 0x1fb6, 0x1fb6, 0x1fb6, 0x1078, 0x1ce7,
-+	0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, 0x3800, 0x7898,
-+	0x0f7f, 0xa084, 0x0001, 0x0040, 0x1fde, 0x70a0, 0xa086, 0x0001,
-+	0x00c0, 0x1fcd, 0x70a2, 0x0078, 0x2071, 0x70a0, 0xa086, 0x0005,
-+	0x00c0, 0x1fdc, 0x70bc, 0x2068, 0x6817, 0x0004, 0x6813, 0x0000,
-+	0x681c, 0xa085, 0x0008, 0x681e, 0x70a3, 0x0000, 0x157e, 0x2011,
-+	0x0004, 0x71a0, 0xa186, 0x0001, 0x0040, 0x2000, 0xa186, 0x0007,
-+	0x00c0, 0x1ff0, 0x2009, 0x382b, 0x200b, 0x0005, 0x0078, 0x2000,
-+	0x2009, 0x3813, 0x2104, 0x2009, 0x3812, 0x200a, 0x2009, 0x382b,
-+	0x200b, 0x0001, 0x70a3, 0x0000, 0x70a7, 0x0001, 0x0078, 0x2002,
-+	0x70a3, 0x0000, 0x1078, 0x314d, 0x20a9, 0x0010, 0x2039, 0x0000,
-+	0x1078, 0x2e16, 0xa7b8, 0x0100, 0x0070, 0x2010, 0x0078, 0x2008,
-+	0x7000, 0x2020, 0x0079, 0x2014, 0x2042, 0x202b, 0x202b, 0x201e,
-+	0x2042, 0x2042, 0x201c, 0x201c, 0x1078, 0x1ce7, 0x2021, 0x3857,
-+	0x2404, 0xa005, 0x0040, 0x202b, 0xad06, 0x00c0, 0x202b, 0x6800,
-+	0x2022, 0x0078, 0x203b, 0x681c, 0xa084, 0x0001, 0x00c0, 0x2037,
-+	0x6f10, 0x1078, 0x2f11, 0x1078, 0x2b06, 0x0078, 0x203b, 0x7054,
-+	0x2060, 0x6800, 0x6002, 0x6a16, 0x681c, 0xa085, 0x0008, 0x681e,
-+	0x1078, 0x18b6, 0x2021, 0x5c00, 0x1078, 0x2077, 0x2021, 0x3857,
-+	0x1078, 0x2077, 0x20a9, 0x0000, 0x2021, 0x5b00, 0x1078, 0x2077,
-+	0x8420, 0x0070, 0x2055, 0x0078, 0x204e, 0x1078, 0x2b55, 0x2061,
-+	0x3b00, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0xa102,
-+	0x6012, 0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x2069, 0x0078,
-+	0x205d, 0x2009, 0x382f, 0x200b, 0x0000, 0x8421, 0x00c0, 0x205b,
-+	0x157f, 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1d39, 0x047e,
-+	0x2404, 0xa005, 0x0040, 0x2089, 0x2068, 0x6800, 0x007e, 0x6a16,
-+	0x681c, 0xa085, 0x0008, 0x681e, 0x1078, 0x18b6, 0x007f, 0x0078,
-+	0x2079, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
-+	0x2093, 0x1078, 0x1ce7, 0x2300, 0x0079, 0x2096, 0x2099, 0x210c,
-+	0x211a, 0xa282, 0x0002, 0x0040, 0x209f, 0x1078, 0x1ce7, 0x70a0,
-+	0x70a3, 0x0000, 0x70c3, 0x0000, 0x0079, 0x20a6, 0x20ae, 0x20ae,
-+	0x20b0, 0x20e4, 0x2b7a, 0x20ae, 0x20e4, 0x20ae, 0x1078, 0x1ce7,
-+	0x77b4, 0x1078, 0x2e16, 0x77b4, 0xa7bc, 0x0f00, 0x1078, 0x2f11,
-+	0x6018, 0xa005, 0x0040, 0x20db, 0x2021, 0x5c00, 0x2009, 0x0004,
-+	0x2011, 0x0010, 0x1078, 0x216a, 0x0040, 0x20db, 0x157e, 0x20a9,
-+	0x0000, 0x2021, 0x5b00, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010,
-+	0x1078, 0x216a, 0x047f, 0x0040, 0x20da, 0x8420, 0x0070, 0x20da,
-+	0x0078, 0x20cb, 0x157f, 0x8738, 0xa784, 0x001f, 0x00c0, 0x20b6,
-+	0x0078, 0x1d41, 0x0078, 0x1d41, 0x77b4, 0x1078, 0x2f11, 0x6018,
-+	0xa005, 0x0040, 0x210a, 0x2021, 0x5c00, 0x2009, 0x0005, 0x2011,
-+	0x0020, 0x1078, 0x216a, 0x0040, 0x210a, 0x157e, 0x20a9, 0x0000,
-+	0x2021, 0x5b00, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078,
-+	0x216a, 0x047f, 0x0040, 0x2109, 0x8420, 0x0070, 0x2109, 0x0078,
-+	0x20fa, 0x157f, 0x0078, 0x1d41, 0x2200, 0x0079, 0x210f, 0x2112,
-+	0x2114, 0x2114, 0x1078, 0x1ce7, 0x70a3, 0x0000, 0x70a7, 0x0001,
-+	0x0078, 0x1d39, 0x2200, 0x0079, 0x211d, 0x2122, 0x2114, 0x2120,
-+	0x1078, 0x1ce7, 0x1078, 0x261c, 0x70a0, 0xa086, 0x0002, 0x00c0,
-+	0x2159, 0x77b4, 0x1078, 0x2e16, 0x77b4, 0xa7bc, 0x0f00, 0x1078,
-+	0x2f11, 0x6018, 0xa005, 0x0040, 0x2154, 0x2021, 0x5c00, 0x2009,
-+	0x0005, 0x2011, 0x0020, 0x1078, 0x216a, 0x0040, 0x2154, 0x157e,
-+	0x20a9, 0x0000, 0x2021, 0x5b00, 0x047e, 0x2009, 0x0005, 0x2011,
-+	0x0020, 0x1078, 0x216a, 0x047f, 0x0040, 0x2153, 0x8420, 0x0070,
-+	0x2153, 0x0078, 0x2144, 0x157f, 0x8738, 0xa784, 0x001f, 0x00c0,
-+	0x212f, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2acd, 0x1078, 0x2b1e,
-+	0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x2ac0, 0x0040, 0x2acd,
-+	0x0078, 0x1e18, 0x2404, 0xa005, 0x0040, 0x219d, 0x2068, 0x2d04,
-+	0x007e, 0x6810, 0xa706, 0x0040, 0x2179, 0x2d20, 0x007f, 0x0078,
-+	0x216b, 0x007f, 0x2022, 0x6916, 0x6814, 0xa086, 0x0050, 0x00c0,
-+	0x218c, 0x6817, 0x0006, 0x2200, 0xa086, 0x0010, 0x00c0, 0x218c,
-+	0x681c, 0xa084, 0xffef, 0x681e, 0x681c, 0xa205, 0x681e, 0x1078,
-+	0x18b6, 0x1078, 0x2b27, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x1078, 0x2b1e, 0x007c, 0xa085, 0x0001, 0x0078,
-+	0x219c, 0x2300, 0x0079, 0x21a4, 0x21a9, 0x21a7, 0x21ec, 0x1078,
-+	0x1ce7, 0x78e4, 0xa005, 0x00d0, 0x21cc, 0x0018, 0x21cc, 0x2008,
-+	0xa084, 0x0030, 0x00c0, 0x21b8, 0x781b, 0x0049, 0x0078, 0x1d39,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x21b4, 0x2100, 0xa084, 0x0007,
-+	0x0079, 0x21c2, 0x21da, 0x21e0, 0x21d4, 0x21ca, 0x2fde, 0x2fde,
-+	0x21ca, 0x21e6, 0x1078, 0x1ce7, 0x7000, 0xa005, 0x0040, 0x1d41,
-+	0x2001, 0x0003, 0x0078, 0x24e3, 0x1078, 0x2df9, 0x781b, 0x0055,
-+	0x0078, 0x1d39, 0x1078, 0x2df9, 0x781b, 0x00dc, 0x0078, 0x1d39,
-+	0x1078, 0x2df9, 0x781b, 0x00e3, 0x0078, 0x1d39, 0x1078, 0x2df9,
-+	0x781b, 0x009d, 0x0078, 0x1d39, 0xa584, 0x000f, 0x00c0, 0x2216,
-+	0x1078, 0x261c, 0x7000, 0x0079, 0x21f5, 0x21fd, 0x220a, 0x21fd,
-+	0x2acd, 0x21ff, 0x2acd, 0x21fd, 0x21fd, 0x1078, 0x1ce7, 0x71a0,
-+	0x70a3, 0x0000, 0xa186, 0x0004, 0x00c0, 0x2208, 0x0078, 0x2b7a,
-+	0x0078, 0x2acd, 0x1078, 0x2b1e, 0x6008, 0xa084, 0xffef, 0x600a,
-+	0x1078, 0x2ac0, 0x0040, 0x2acd, 0x0078, 0x1e18, 0x78e4, 0xa005,
-+	0x00d0, 0x21cc, 0x0018, 0x21cc, 0x2008, 0xa084, 0x0030, 0x00c0,
-+	0x2225, 0x781b, 0x0049, 0x0078, 0x1d39, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x2221, 0x2100, 0xa184, 0x0007, 0x0079, 0x222f, 0x223f,
-+	0x2245, 0x2239, 0x2237, 0x2fde, 0x2fde, 0x2237, 0x2fd6, 0x1078,
-+	0x1ce7, 0x1078, 0x2e01, 0x781b, 0x0055, 0x0078, 0x1d39, 0x1078,
-+	0x2e01, 0x781b, 0x00dc, 0x0078, 0x1d39, 0x1078, 0x2e01, 0x781b,
-+	0x00e3, 0x0078, 0x1d39, 0x1078, 0x2e01, 0x781b, 0x009d, 0x0078,
-+	0x1d39, 0x2300, 0x0079, 0x2254, 0x2259, 0x2257, 0x225b, 0x1078,
-+	0x1ce7, 0x0078, 0x2883, 0x6817, 0x0008, 0x78a3, 0x0000, 0x79e4,
-+	0xa184, 0x0030, 0x0040, 0x2883, 0x78ec, 0xa084, 0x0003, 0x0040,
-+	0x2883, 0xa184, 0x0007, 0x0079, 0x226d, 0x21da, 0x21e0, 0x21d4,
-+	0x2fb6, 0x2fde, 0x2fde, 0x2275, 0x2fd6, 0x1078, 0x1ce7, 0xa282,
-+	0x0005, 0x0050, 0x227d, 0x1078, 0x1ce7, 0x2300, 0x0079, 0x2280,
-+	0x2283, 0x24b7, 0x24c3, 0x2200, 0x0079, 0x2286, 0x228b, 0x228d,
-+	0x22a0, 0x228b, 0x249c, 0x1078, 0x1ce7, 0x789b, 0x0018, 0x78a8,
-+	0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x2dda, 0xa08a, 0x0004,
-+	0x00c8, 0x2dda, 0x0079, 0x229c, 0x2dda, 0x2dda, 0x2dda, 0x2d7c,
-+	0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x22b5, 0xa184,
-+	0x0018, 0x0040, 0x22b1, 0x0078, 0x2dda, 0x7000, 0xa005, 0x00c0,
-+	0x22ab, 0x2011, 0x0003, 0x0078, 0x2970, 0xa184, 0x00ff, 0xa08c,
-+	0x0080, 0x0040, 0x22e9, 0x7000, 0xa086, 0x0001, 0x00c0, 0x22c8,
-+	0x1078, 0x2b1e, 0x1078, 0x314d, 0x7034, 0x600a, 0x0078, 0x22cd,
-+	0x7000, 0xa086, 0x0003, 0x0040, 0x22c2, 0x7003, 0x0005, 0x2001,
-+	0x5c10, 0x2068, 0x703e, 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003,
-+	0x0000, 0x8000, 0x0070, 0x22de, 0x0078, 0x22d7, 0x157f, 0x6813,
-+	0x0000, 0x68b3, 0x0700, 0x681f, 0x0800, 0x6823, 0x0003, 0x0078,
-+	0x2dda, 0xa08a, 0x0010, 0x00c8, 0x2dda, 0x0079, 0x22ef, 0x2301,
-+	0x22ff, 0x2317, 0x2319, 0x23ab, 0x2dda, 0x2dda, 0x23ad, 0x2dda,
-+	0x2dda, 0x2498, 0x2498, 0x2dda, 0x2dda, 0x2dda, 0x249a, 0x1078,
-+	0x1ce7, 0xa684, 0x1000, 0x0040, 0x230e, 0x2001, 0x0300, 0x8000,
-+	0x8000, 0x783a, 0x781b, 0x009a, 0x0078, 0x1d39, 0x6814, 0xa084,
-+	0x8000, 0x0040, 0x2315, 0x6817, 0x0003, 0x0078, 0x2fb6, 0x1078,
-+	0x1ce7, 0x691c, 0x691e, 0xa684, 0x1800, 0x00c0, 0x2333, 0x681c,
-+	0xa084, 0x0001, 0x00c0, 0x233b, 0x6814, 0xa086, 0x0008, 0x00c0,
-+	0x232b, 0x6817, 0x0000, 0xa684, 0x0400, 0x0040, 0x23a7, 0x781b,
-+	0x0058, 0x0078, 0x1d39, 0xa684, 0x1000, 0x0040, 0x233b, 0x781b,
-+	0x0058, 0x0078, 0x1d39, 0xa684, 0x0060, 0x0040, 0x23a3, 0xa684,
-+	0x0800, 0x0040, 0x23a3, 0xa684, 0x8000, 0x00c0, 0x2349, 0x0078,
-+	0x2363, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb2, 0x789b, 0x0074, 0x7aac,
-+	0x79ac, 0x78ac, 0x801b, 0x00c8, 0x2356, 0x8000, 0xa084, 0x003f,
-+	0xa108, 0xa291, 0x0000, 0x6b94, 0x2100, 0xa302, 0x68ae, 0x6b90,
-+	0x2200, 0xa303, 0x68aa, 0xa684, 0x4000, 0x0040, 0x236b, 0xa6b4,
-+	0xbfff, 0x7e5a, 0x6eb2, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2378,
-+	0x1078, 0x31c0, 0x1078, 0x3365, 0x781b, 0x0067, 0x0078, 0x1d39,
-+	0xa006, 0x1078, 0x3414, 0x6aac, 0x69a8, 0x6c94, 0x6b90, 0x2200,
-+	0xa105, 0x0040, 0x2387, 0x2200, 0xa422, 0x2100, 0xa31b, 0x7cd2,
-+	0x7bd6, 0x2300, 0xa405, 0x00c0, 0x2395, 0xa6b5, 0x4000, 0x7e5a,
-+	0x6eb2, 0x781b, 0x0067, 0x0078, 0x1d39, 0x781b, 0x0067, 0x2200,
-+	0xa115, 0x00c0, 0x239f, 0x1078, 0x3376, 0x0078, 0x1d39, 0x1078,
-+	0x339d, 0x0078, 0x1d39, 0x781b, 0x006a, 0x0078, 0x1d39, 0x781b,
-+	0x0058, 0x0078, 0x1d39, 0x1078, 0x1ce7, 0x0078, 0x240a, 0x691c,
-+	0xa184, 0x0100, 0x0040, 0x23c5, 0xa18c, 0xfeff, 0x691e, 0x0c7e,
-+	0x7048, 0x2060, 0x6000, 0xa084, 0xefff, 0x6002, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x0c7f, 0x0078, 0x23f9, 0xa184, 0x0200, 0x0040,
-+	0x23f9, 0xa18c, 0xfdff, 0x691e, 0x0c7e, 0x7048, 0x2060, 0x6000,
-+	0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef, 0x6006, 0x2008,
-+	0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x23f9, 0x1078, 0x2f0d,
-+	0x1078, 0x2c58, 0x88ff, 0x0040, 0x23f9, 0x789b, 0x0060, 0x2800,
-+	0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-+	0x23f5, 0x781b, 0x0055, 0x0078, 0x1d39, 0x781b, 0x0069, 0x0078,
-+	0x1d39, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2402, 0x781b, 0x0058,
-+	0x0078, 0x1d39, 0x781b, 0x006a, 0x0078, 0x1d39, 0x0078, 0x2de0,
-+	0x0078, 0x2de0, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040,
-+	0x2408, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
-+	0x00c0, 0x242d, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
-+	0x2425, 0x0048, 0x2425, 0x0078, 0x2427, 0x0078, 0x23af, 0x24a8,
-+	0x7aa8, 0x00f0, 0x2427, 0x0078, 0x2413, 0xa284, 0x00f0, 0xa086,
-+	0x0020, 0x00c0, 0x2489, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040,
-+	0x243d, 0x0048, 0x243d, 0x0078, 0x2486, 0xa286, 0x0023, 0x0040,
-+	0x2408, 0x6818, 0xa084, 0xfff1, 0x681a, 0x7e58, 0xa684, 0xfff1,
-+	0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010, 0x600a,
-+	0x0c7e, 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184,
-+	0x0010, 0x0040, 0x2461, 0x1078, 0x2f0d, 0x1078, 0x2d3d, 0x0078,
-+	0x2470, 0x0c7e, 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f,
-+	0xa184, 0x0008, 0x0040, 0x23f9, 0x1078, 0x2f0d, 0x1078, 0x2c58,
-+	0x88ff, 0x0040, 0x23f9, 0x789b, 0x0060, 0x2800, 0x78aa, 0xa6b5,
-+	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2482, 0x781b, 0x0055,
-+	0x0078, 0x1d39, 0x781b, 0x0069, 0x0078, 0x1d39, 0x7aa8, 0x0078,
-+	0x2413, 0x8318, 0x2300, 0xa102, 0x0040, 0x2492, 0x0048, 0x2492,
-+	0x0078, 0x2413, 0xa284, 0x0080, 0x00c0, 0x2de6, 0x0078, 0x2de0,
-+	0x0078, 0x2de6, 0x0078, 0x2dda, 0x789b, 0x0018, 0x78a8, 0xa084,
-+	0x00ff, 0xa08e, 0x0001, 0x0040, 0x24a7, 0x1078, 0x1ce7, 0x7aa8,
-+	0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8,
-+	0x2dda, 0x0079, 0x24b3, 0x2dda, 0x2bab, 0x2dda, 0x2cd8, 0xa282,
-+	0x0000, 0x00c0, 0x24bd, 0x1078, 0x1ce7, 0x1078, 0x2df9, 0x781b,
-+	0x0069, 0x0078, 0x1d39, 0xa282, 0x0003, 0x00c0, 0x24c9, 0x1078,
-+	0x1ce7, 0x1078, 0x2e09, 0x781b, 0x0069, 0x0078, 0x1d39, 0xa282,
-+	0x0004, 0x0050, 0x24d5, 0x1078, 0x1ce7, 0x2300, 0x0079, 0x24d8,
-+	0x24db, 0x25c6, 0x25f7, 0xa286, 0x0003, 0x0040, 0x24e1, 0x1078,
-+	0x1ce7, 0x2001, 0x0000, 0x703a, 0x7000, 0xa084, 0x0007, 0x0079,
-+	0x24e9, 0x24f1, 0x24f3, 0x24f3, 0x2703, 0x274c, 0x26cd, 0x24f1,
-+	0x24f1, 0x1078, 0x1ce7, 0xa684, 0x1000, 0x00c0, 0x24fb, 0x1078,
-+	0x314d, 0x0040, 0x25a0, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2557,
-+	0xa186, 0x0008, 0x00c0, 0x2512, 0x6008, 0xa084, 0xffef, 0x600a,
-+	0x1078, 0x2ac0, 0x0040, 0x2557, 0x1078, 0x2b1e, 0x1078, 0x314d,
-+	0x0078, 0x253e, 0xa186, 0x0028, 0x00c0, 0x2557, 0x1078, 0x314d,
-+	0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x2b34, 0x6018, 0xa005,
-+	0x0040, 0x253e, 0x8001, 0x601a, 0xa005, 0x0040, 0x2534, 0x8001,
-+	0xa005, 0x0040, 0x2534, 0x601e, 0x0078, 0x253e, 0x6813, 0x0028,
-+	0x6817, 0x0000, 0x0078, 0x25b5, 0x6030, 0xa084, 0x00ff, 0xa005,
-+	0x0040, 0x252e, 0x6008, 0xa085, 0x0200, 0x600a, 0x681c, 0xa084,
-+	0x0001, 0x0040, 0x1d41, 0x681c, 0xa084, 0xfffe, 0x681e, 0x7054,
-+	0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005,
-+	0x2d00, 0x00c0, 0x2554, 0x6002, 0x6006, 0x0078, 0x1d41, 0x017e,
-+	0x1078, 0x261c, 0x017f, 0xa684, 0xdf00, 0x681a, 0x6827, 0x0000,
-+	0x6f10, 0x81ff, 0x0040, 0x25a0, 0xa186, 0x0002, 0x00c0, 0x2598,
-+	0xa684, 0x0800, 0x00c0, 0x2574, 0xa684, 0x0060, 0x0040, 0x2574,
-+	0x78d8, 0x7adc, 0x682e, 0x6a2a, 0x8717, 0xa294, 0x000f, 0x8213,
-+	0x8213, 0x8213, 0xa290, 0x3a80, 0xa290, 0x0000, 0x221c, 0xa384,
-+	0x0100, 0x00c0, 0x2585, 0x0078, 0x258b, 0x8210, 0x2204, 0xa085,
-+	0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2598, 0x689c,
-+	0xa084, 0x0100, 0x00c0, 0x2598, 0x1078, 0x268c, 0x0078, 0x1d41,
-+	0xa186, 0x0018, 0x0040, 0x25a0, 0xa186, 0x0014, 0x0040, 0x1d41,
-+	0x6912, 0x6814, 0xa084, 0x8000, 0x0040, 0x25a8, 0x7038, 0x6816,
-+	0xa68c, 0xdf00, 0x691a, 0x1078, 0x2b0d, 0x1078, 0x2b1e, 0x00c0,
-+	0x25b5, 0x6008, 0xa084, 0xffef, 0x600a, 0x681c, 0xa084, 0x0001,
-+	0x00c0, 0x25be, 0x1078, 0x2b06, 0x0078, 0x25c2, 0x7054, 0x2060,
-+	0x6800, 0x6002, 0x1078, 0x18b6, 0x0078, 0x1d41, 0xa282, 0x0004,
-+	0x0048, 0x25cc, 0x1078, 0x1ce7, 0x2200, 0x0079, 0x25cf, 0x25d3,
-+	0x25d5, 0x25e2, 0x25d5, 0x1078, 0x1ce7, 0x7000, 0xa086, 0x0005,
-+	0x0040, 0x25de, 0x1078, 0x2df9, 0x781b, 0x0069, 0x781b, 0x006a,
-+	0x0078, 0x1d39, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080,
-+	0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0040,
-+	0x25f3, 0x0078, 0x2dda, 0x781b, 0x006a, 0x0078, 0x1d39, 0x681c,
-+	0xa085, 0x0004, 0x681e, 0x82ff, 0x00c0, 0x2602, 0x1078, 0x2df9,
-+	0x0078, 0x2609, 0x8211, 0x0040, 0x2607, 0x1078, 0x1ce7, 0x1078,
-+	0x2e09, 0x781b, 0x0069, 0x0078, 0x1d39, 0x1078, 0x2ffd, 0x7830,
-+	0xa084, 0x00c0, 0x00c0, 0x2619, 0x0018, 0x2619, 0x791a, 0xa006,
-+	0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0, 0x2626,
-+	0x682f, 0x0000, 0x682b, 0x0000, 0x0078, 0x268b, 0xa684, 0x0800,
-+	0x00c0, 0x2635, 0x68b0, 0xa084, 0x4800, 0xa635, 0xa684, 0x0800,
-+	0x00c0, 0x2635, 0x1078, 0x314d, 0x007c, 0xa684, 0x0020, 0x0040,
-+	0x265f, 0x78d0, 0x8003, 0x00c8, 0x2643, 0xa006, 0x1078, 0x3414,
-+	0x78d4, 0x1078, 0x3479, 0xa684, 0x4000, 0x0040, 0x264d, 0x682f,
-+	0x0000, 0x682b, 0x0000, 0x0078, 0x2632, 0x68b0, 0xa084, 0x4800,
-+	0xa635, 0xa684, 0x4000, 0x00c0, 0x2647, 0x7038, 0xa005, 0x00c0,
-+	0x2659, 0x79d8, 0x7adc, 0x692e, 0x6a2a, 0x0078, 0x2632, 0xa684,
-+	0x4000, 0x0040, 0x2669, 0x682f, 0x0000, 0x682b, 0x0000, 0x0078,
-+	0x2632, 0x68b0, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0,
-+	0x2663, 0x7038, 0xa005, 0x00c0, 0x2675, 0x79d8, 0x7adc, 0x78d0,
-+	0x80f3, 0x00c8, 0x267c, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
-+	0x0000, 0x692e, 0x6a2a, 0x2100, 0xa205, 0x00c0, 0x2689, 0x0078,
-+	0x2632, 0x1078, 0x3414, 0x007c, 0xa384, 0x0200, 0x0040, 0x2694,
-+	0x6008, 0xa085, 0x0002, 0x600a, 0x6817, 0x0006, 0x6a28, 0x692c,
-+	0x6a3a, 0x693e, 0x682b, 0x0300, 0x682f, 0x0000, 0x6833, 0x2000,
-+	0x6893, 0x0000, 0x6897, 0x0020, 0x7000, 0x0079, 0x26a7, 0x26af,
-+	0x26b1, 0x26ba, 0x26af, 0x26af, 0x26af, 0x26af, 0x26af, 0x1078,
-+	0x1ce7, 0x681c, 0xa084, 0x0001, 0x00c0, 0x26ba, 0x1078, 0x2b06,
-+	0x0078, 0x26c0, 0x7054, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60,
-+	0x2021, 0x3857, 0x2404, 0xa005, 0x0040, 0x26c9, 0x2020, 0x0078,
-+	0x26c2, 0x2d22, 0x206b, 0x0000, 0x007c, 0x77b4, 0x1078, 0x2e16,
-+	0xa7bc, 0x0f00, 0x1078, 0x2f11, 0x6018, 0xa005, 0x0040, 0x26fc,
-+	0x0d7e, 0x2001, 0x5c10, 0x2068, 0x0d7f, 0x2021, 0x5c00, 0x2009,
-+	0x0004, 0x2011, 0x0010, 0x1078, 0x216a, 0x0040, 0x26fc, 0x157e,
-+	0x20a9, 0x0000, 0x2021, 0x5b00, 0x047e, 0x2009, 0x0004, 0x2011,
-+	0x0010, 0x1078, 0x216a, 0x047f, 0x0040, 0x26fb, 0x8420, 0x0070,
-+	0x26fb, 0x0078, 0x26ec, 0x157f, 0x8738, 0xa784, 0x001f, 0x00c0,
-+	0x26d2, 0x0078, 0x1d41, 0x1078, 0x2b0d, 0x1078, 0x2b1e, 0x6827,
-+	0x0000, 0x789b, 0x000e, 0x6f10, 0x1078, 0x344a, 0x017e, 0xad88,
-+	0x0010, 0xa188, 0x0006, 0x2104, 0x017f, 0x8007, 0xa084, 0x00ff,
-+	0xa082, 0x0047, 0x0040, 0x271e, 0x0078, 0x272f, 0x0c7e, 0x6810,
-+	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, 0x3a80,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x1078, 0x2f6b, 0x6813,
-+	0x0002, 0xa684, 0x0800, 0x0040, 0x2739, 0x6918, 0xa18d, 0x2000,
-+	0x691a, 0x6814, 0xa084, 0x8000, 0x0040, 0x2740, 0x6817, 0x0000,
-+	0x2021, 0x3857, 0x6800, 0x2022, 0x6a38, 0x693c, 0x6a2a, 0x692e,
-+	0x1078, 0x18b6, 0x0078, 0x1d41, 0x1078, 0x261c, 0x6827, 0x0000,
-+	0x789b, 0x000e, 0x6f10, 0x1078, 0x3002, 0xa08c, 0x00ff, 0x6912,
-+	0x6814, 0xa084, 0x8000, 0x0040, 0x275f, 0x7038, 0x6816, 0xa68c,
-+	0xdf00, 0x691a, 0x70a3, 0x0000, 0x0078, 0x1d41, 0xa006, 0x1078,
-+	0x314d, 0x6813, 0x0000, 0x6817, 0x0001, 0xa68c, 0xdf00, 0x691a,
-+	0x6827, 0x0000, 0x7000, 0x0079, 0x2775, 0x277d, 0x277f, 0x277f,
-+	0x2781, 0x2781, 0x2781, 0x277d, 0x277d, 0x1078, 0x1ce7, 0x1078,
-+	0x2b1e, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x2ad8, 0x2300,
-+	0x0079, 0x278a, 0x278d, 0x278f, 0x27cd, 0x1078, 0x1ce7, 0x7000,
-+	0x0079, 0x2792, 0x279a, 0x279c, 0x279c, 0x27a7, 0x279c, 0x27ae,
-+	0x279a, 0x279a, 0x1078, 0x1ce7, 0xa684, 0x2000, 0x00c0, 0x27a7,
-+	0xa6b5, 0x2000, 0x7e5a, 0x1078, 0x3376, 0x0078, 0x2fb6, 0x6814,
-+	0xa084, 0x8000, 0x0040, 0x27ae, 0x6817, 0x0007, 0x2009, 0x3818,
-+	0x210c, 0xa186, 0x0000, 0x0040, 0x27c3, 0xa186, 0x0001, 0x0040,
-+	0x27c7, 0x2009, 0x382b, 0x200b, 0x000b, 0x70a3, 0x0001, 0x781b,
-+	0x0046, 0x0078, 0x1d39, 0x781b, 0x00dd, 0x0078, 0x1d39, 0x2009,
-+	0x382b, 0x200b, 0x000a, 0x0078, 0x1d39, 0x1078, 0x1ce7, 0x2300,
-+	0x0079, 0x27d2, 0x27d5, 0x27d7, 0x27fa, 0x1078, 0x1ce7, 0x7000,
-+	0x0079, 0x27da, 0x27e2, 0x27e4, 0x27e4, 0x27ef, 0x27e4, 0x27f6,
-+	0x27e2, 0x27e2, 0x1078, 0x1ce7, 0xa684, 0x2000, 0x00c0, 0x27ef,
-+	0xa6b5, 0x2000, 0x7e5a, 0x1078, 0x3376, 0x0078, 0x2fb6, 0x6814,
-+	0xa084, 0x8000, 0x0040, 0x27f6, 0x6817, 0x0007, 0x781b, 0x00e4,
-+	0x0078, 0x1d39, 0x681c, 0xa085, 0x0004, 0x681e, 0x1078, 0x2f6b,
-+	0xa6b5, 0x0800, 0x1078, 0x2df9, 0x781b, 0x0069, 0x0078, 0x1d39,
-+	0x2300, 0x0079, 0x280b, 0x280e, 0x2810, 0x2812, 0x1078, 0x1ce7,
-+	0x1078, 0x1ce7, 0xa684, 0x0400, 0x00c0, 0x2831, 0x782b, 0x3009,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4,
-+	0xa184, 0x0020, 0x0040, 0x2829, 0x78ec, 0xa084, 0x0003, 0x00c0,
-+	0x282d, 0x2001, 0x0014, 0x0078, 0x24e3, 0xa184, 0x0007, 0x0079,
-+	0x2869, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff,
-+	0x0040, 0x2867, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0,
-+	0x2858, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x284b, 0x2009,
-+	0xfff7, 0x0078, 0x2851, 0xa386, 0x0003, 0x00c0, 0x2858, 0x2009,
-+	0xffef, 0x0c7e, 0x7048, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b,
-+	0x3009, 0x691c, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x691e, 0x0078,
-+	0x2fb6, 0x21da, 0x21e0, 0x2873, 0x287b, 0x2871, 0x2871, 0x2871,
-+	0x2fb6, 0x1078, 0x1ce7, 0x691c, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x691e, 0x0078, 0x2fbe, 0x691c, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x691e, 0x0078, 0x2fb6, 0x79e4, 0xa184, 0x0030, 0x0040, 0x288d,
-+	0x78ec, 0xa084, 0x0003, 0x00c0, 0x2895, 0x6814, 0xa085, 0x8000,
-+	0x6816, 0x2001, 0x0014, 0x0078, 0x24e3, 0xa184, 0x0007, 0x0079,
-+	0x2899, 0x2fb6, 0x2fb6, 0x28a1, 0x2fb6, 0x2fde, 0x2fde, 0x2fb6,
-+	0x2fb6, 0xa684, 0x0400, 0x00c0, 0x28d2, 0x681c, 0xa084, 0x0001,
-+	0x0040, 0x2fbe, 0xa68c, 0x2060, 0xa18c, 0xfffb, 0x795a, 0x69b2,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6814, 0xa085,
-+	0x8000, 0x6816, 0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012c,
-+	0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000a, 0x2098, 0x53a6,
-+	0x147f, 0x137f, 0x157f, 0x6810, 0x8007, 0x789b, 0x007e, 0x78aa,
-+	0x0078, 0x2fbe, 0x6814, 0xa084, 0x8000, 0x0040, 0x28d9, 0x6817,
-+	0x0008, 0x781b, 0x00d8, 0x0078, 0x1d39, 0x2300, 0x0079, 0x28e0,
-+	0x28e5, 0x2960, 0x28e3, 0x1078, 0x1ce7, 0x7000, 0xa084, 0x0007,
-+	0x0079, 0x28ea, 0x28f2, 0x28f4, 0x2910, 0x28f2, 0x28f2, 0x26cd,
-+	0x28f2, 0x28f2, 0x1078, 0x1ce7, 0x691c, 0xa18d, 0x0001, 0x691e,
-+	0x6800, 0x6006, 0xa005, 0x00c0, 0x28fe, 0x6002, 0x6818, 0xa084,
-+	0x000e, 0x0040, 0x290a, 0x7014, 0x68b6, 0x712c, 0xa188, 0x5b00,
-+	0x0078, 0x290c, 0x2009, 0x5c00, 0x2104, 0x6802, 0x2d0a, 0x7156,
-+	0x6eb2, 0xa684, 0x0060, 0x0040, 0x295e, 0xa684, 0x0800, 0x00c0,
-+	0x2922, 0xa684, 0x7fff, 0x68b2, 0x6890, 0x6894, 0x1078, 0x314d,
-+	0x0078, 0x295e, 0xa684, 0x0020, 0x0040, 0x2934, 0xa006, 0x1078,
-+	0x3414, 0x78d0, 0x8003, 0x00c8, 0x2930, 0x78d4, 0x1078, 0x3479,
-+	0x79d8, 0x7adc, 0x0078, 0x2938, 0x1078, 0x2f1e, 0x1078, 0x3414,
-+	0xa684, 0x8000, 0x0040, 0x295e, 0xa684, 0x7fff, 0x68b2, 0x789b,
-+	0x0074, 0x1078, 0x3002, 0x2010, 0x1078, 0x3002, 0x2008, 0xa684,
-+	0x0020, 0x00c0, 0x2956, 0x1078, 0x3002, 0x801b, 0x00c8, 0x2951,
-+	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b94, 0x2100,
-+	0xa302, 0x68ae, 0x6b90, 0x2200, 0xa303, 0x68aa, 0x0078, 0x1d41,
-+	0x0078, 0x2de6, 0x7033, 0x0000, 0xa282, 0x0005, 0x0050, 0x296a,
-+	0x1078, 0x1ce7, 0x2300, 0x0079, 0x296d, 0x2970, 0x297a, 0x299d,
-+	0x2200, 0x0079, 0x2973, 0x2978, 0x2de6, 0x2978, 0x29c6, 0x2a17,
-+	0x1078, 0x1ce7, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2987, 0x1078,
-+	0x2b1e, 0x1078, 0x314d, 0x7034, 0x600a, 0x0078, 0x298c, 0x7000,
-+	0xa086, 0x0003, 0x0040, 0x2981, 0x7003, 0x0005, 0x2001, 0x5c10,
-+	0x2068, 0x703e, 0x7032, 0x2200, 0x0079, 0x2996, 0x2de6, 0x299b,
-+	0x29c6, 0x299b, 0x2de6, 0x1078, 0x1ce7, 0x7000, 0xa086, 0x0001,
-+	0x00c0, 0x29aa, 0x1078, 0x2b1e, 0x1078, 0x314d, 0x7034, 0x600a,
-+	0x0078, 0x29af, 0x7000, 0xa086, 0x0003, 0x0040, 0x29a4, 0x7003,
-+	0x0005, 0x2001, 0x5c10, 0x2068, 0x703e, 0x7032, 0x2200, 0x0079,
-+	0x29b9, 0x29c0, 0x29be, 0x29c0, 0x29be, 0x29c0, 0x1078, 0x1ce7,
-+	0x1078, 0x2e09, 0x781b, 0x0069, 0x0078, 0x1d39, 0x7000, 0xa086,
-+	0x0001, 0x00c0, 0x29d3, 0x1078, 0x2b1e, 0x1078, 0x314d, 0x7034,
-+	0x600a, 0x0078, 0x29d8, 0x7000, 0xa086, 0x0003, 0x0040, 0x29cd,
-+	0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-+	0xa484, 0x001f, 0xa215, 0x2069, 0x5c00, 0x2d04, 0x2d08, 0x7156,
-+	0x2068, 0xa005, 0x0040, 0x29f3, 0x6810, 0xa206, 0x0040, 0x2a0c,
-+	0x6800, 0x0078, 0x29e6, 0x7003, 0x0005, 0x2001, 0x5c10, 0x2068,
-+	0x703e, 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000,
-+	0x0070, 0x2a04, 0x0078, 0x29fd, 0x157f, 0x6a12, 0x68b3, 0x0700,
-+	0x681f, 0x0800, 0x6823, 0x0003, 0x6eb0, 0x7e5a, 0x681c, 0xa084,
-+	0x0c00, 0x0040, 0x2a6d, 0x1078, 0x2e01, 0x0078, 0x2a6d, 0x7000,
-+	0xa086, 0x0001, 0x00c0, 0x2a24, 0x1078, 0x2b1e, 0x1078, 0x314d,
-+	0x7034, 0x600a, 0x0078, 0x2a29, 0x7000, 0xa086, 0x0003, 0x0040,
-+	0x2a1e, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-+	0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff,
-+	0xa1e8, 0x5b00, 0x2d04, 0x2d08, 0x7156, 0x2068, 0xa005, 0x0040,
-+	0x2a48, 0x6810, 0xa206, 0x0040, 0x2a61, 0x6800, 0x0078, 0x2a3b,
-+	0x7003, 0x0005, 0x2001, 0x5c10, 0x2068, 0x703e, 0x7032, 0x157e,
-+	0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070, 0x2a59, 0x0078,
-+	0x2a52, 0x157f, 0x6a12, 0x68b3, 0x0700, 0x681f, 0x0800, 0x6823,
-+	0x0003, 0x6eb0, 0x7e5a, 0x681c, 0xa084, 0x0c00, 0x0040, 0x2a6d,
-+	0x1078, 0x2dfd, 0x7e58, 0x0078, 0x2a6d, 0x027e, 0x8207, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3a80, 0x2060, 0x704a,
-+	0x6000, 0x704e, 0x6004, 0x7052, 0xa684, 0x0060, 0x0040, 0x2aa4,
-+	0x6b94, 0x6c90, 0x69a8, 0x68ac, 0xa105, 0x00c0, 0x2a92, 0x7bd2,
-+	0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, 0x1078, 0x3376,
-+	0x0078, 0x2aa4, 0x68ac, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305,
-+	0x0040, 0x2aa4, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68ac, 0xa6b4,
-+	0xbfff, 0x7e5a, 0x1078, 0x339d, 0x077f, 0x1078, 0x2f11, 0x2009,
-+	0x006a, 0xa684, 0x0008, 0x0040, 0x2aaf, 0x2009, 0x0069, 0xa6b5,
-+	0x2000, 0x7e5a, 0x791a, 0x2d00, 0x703e, 0x8207, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa080, 0x3a80, 0x2048, 0x0078, 0x1d39,
-+	0x6020, 0xa005, 0x0040, 0x2acc, 0x8001, 0x6022, 0x6008, 0xa085,
-+	0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x314d,
-+	0x6813, 0x0000, 0x6817, 0x0001, 0x681f, 0x0040, 0x681b, 0x0100,
-+	0x7000, 0xa084, 0x0007, 0x0079, 0x2add, 0x2ae5, 0x2ae7, 0x2ae7,
-+	0x2b02, 0x2aef, 0x2ae5, 0x2ae5, 0x2ae5, 0x1078, 0x1ce7, 0x1078,
-+	0x2b0d, 0x1078, 0x2b06, 0x1078, 0x18b6, 0x0078, 0x1d41, 0x70a0,
-+	0x70a3, 0x0000, 0x0079, 0x2af4, 0x2afe, 0x2afe, 0x2afc, 0x2afc,
-+	0x2afc, 0x2afe, 0x2afc, 0x2afe, 0x0079, 0x20a6, 0x70a3, 0x0000,
-+	0x0078, 0x1d41, 0x6817, 0x0000, 0x0078, 0x2703, 0x6800, 0xa005,
-+	0x00c0, 0x2b0b, 0x6002, 0x6006, 0x007c, 0x1078, 0x2b27, 0x6010,
-+	0xa005, 0x0040, 0x2b18, 0x8001, 0x00d0, 0x2b18, 0x1078, 0x1ce7,
-+	0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x1078, 0x2b34,
-+	0x6018, 0xa005, 0x0040, 0x2b26, 0x8001, 0x601a, 0x007c, 0x017e,
-+	0x007e, 0x2009, 0x382e, 0x2104, 0xa005, 0x0040, 0x2b31, 0x8001,
-+	0x200a, 0x007f, 0x017f, 0x007c, 0x017e, 0x007e, 0x2009, 0x382f,
-+	0x2104, 0xa005, 0x0040, 0x2b3e, 0x8001, 0x200a, 0x007f, 0x017f,
-+	0x007c, 0x017e, 0x007e, 0x2009, 0x3830, 0x2104, 0x8000, 0x200a,
-+	0x007f, 0x017f, 0x007c, 0x017e, 0x007e, 0x2009, 0x382f, 0x2104,
-+	0x8000, 0x200a, 0x007f, 0x017f, 0x007c, 0x027e, 0x037e, 0x007e,
-+	0x2009, 0x382e, 0x2114, 0x2019, 0x382f, 0x2304, 0xa202, 0x200a,
-+	0x201b, 0x0000, 0x2009, 0x3830, 0x007f, 0x037f, 0x027f, 0x007c,
-+	0x1078, 0x2ffd, 0x6817, 0x0018, 0x0078, 0x2b98, 0x1078, 0x2ffd,
-+	0x6817, 0x0019, 0x0078, 0x2b98, 0x1078, 0x2ffd, 0x6817, 0x001a,
-+	0x0078, 0x2b98, 0x77b4, 0x1078, 0x2f11, 0x71b8, 0xa18c, 0x00ff,
-+	0xa1e8, 0x5b00, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x2b8a,
-+	0x0078, 0x1d41, 0x6810, 0x72b4, 0xa206, 0x0040, 0x2b92, 0x6800,
-+	0x0078, 0x2b83, 0x6800, 0x200a, 0x6817, 0x0005, 0x70bf, 0x0000,
-+	0x1078, 0x2b0d, 0x681c, 0xa084, 0x0001, 0x00c0, 0x2ba1, 0x1078,
-+	0x2b06, 0x1078, 0x2b1e, 0x681b, 0x0000, 0x681f, 0x0020, 0x1078,
-+	0x18b6, 0x0078, 0x1d41, 0xa282, 0x0003, 0x00c0, 0x2dda, 0x7da8,
-+	0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x691c, 0xa18d, 0x0080,
-+	0x691e, 0xa184, 0x0100, 0x0040, 0x2c0b, 0xa18c, 0xfeff, 0x691e,
-+	0xa6b4, 0x00ff, 0x0040, 0x2bf5, 0xa682, 0x000f, 0x0048, 0x2bcc,
-+	0x0040, 0x2bcc, 0x2031, 0x000f, 0x852b, 0x852b, 0x1078, 0x2e94,
-+	0x0040, 0x2bd6, 0x1078, 0x2ca4, 0x0078, 0x2bfe, 0x1078, 0x2e4f,
-+	0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x2cc8,
-+	0x0c7f, 0x691c, 0xa18d, 0x0100, 0x691e, 0x7e58, 0xa6b5, 0x0004,
-+	0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2bf1, 0x781b, 0x0055, 0x0078,
-+	0x1d39, 0x781b, 0x0069, 0x0078, 0x1d39, 0x0c7e, 0x2960, 0x6004,
-+	0xa084, 0xfff5, 0x6006, 0x1078, 0x2cc8, 0x0c7f, 0x7e58, 0xa684,
-+	0x0400, 0x00c0, 0x2c07, 0x781b, 0x0058, 0x0078, 0x1d39, 0x781b,
-+	0x006a, 0x0078, 0x1d39, 0x0c7e, 0x7048, 0x2060, 0x6100, 0xa18c,
-+	0x1000, 0x0040, 0x2c4b, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282,
-+	0x000f, 0x0048, 0x2c1f, 0x0040, 0x2c1f, 0x2011, 0x000f, 0x2600,
-+	0xa202, 0x00c8, 0x2c24, 0x2230, 0x6208, 0xa294, 0x00ff, 0x7018,
-+	0xa086, 0x0028, 0x00c0, 0x2c34, 0xa282, 0x0019, 0x00c8, 0x2c3a,
-+	0x2011, 0x0019, 0x0078, 0x2c3a, 0xa282, 0x000c, 0x00c8, 0x2c3a,
-+	0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x2c3f, 0x2228, 0x1078,
-+	0x2e53, 0x852b, 0x852b, 0x1078, 0x2e94, 0x0040, 0x2c4b, 0x1078,
-+	0x2ca4, 0x0078, 0x2c4f, 0x1078, 0x2e4f, 0x1078, 0x2cc8, 0x7858,
-+	0xa085, 0x0004, 0x785a, 0x0c7f, 0x781b, 0x0069, 0x0078, 0x1d39,
-+	0x0c7e, 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x2c72, 0xa084,
-+	0x0040, 0x00c0, 0x2c6c, 0xa18c, 0x0002, 0x00c0, 0x2c6c, 0xa18c,
-+	0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000,
-+	0x0078, 0x2c94, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
-+	0x00c0, 0x2c82, 0xa282, 0x0019, 0x00c8, 0x2c88, 0x2011, 0x0019,
-+	0x0078, 0x2c88, 0xa282, 0x000c, 0x00c8, 0x2c88, 0x2011, 0x000c,
-+	0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000f, 0x0048, 0x2c94,
-+	0x0040, 0x2c94, 0x2019, 0x000f, 0x78ab, 0x0001, 0x78ab, 0x0003,
-+	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x681c, 0xa085,
-+	0x0100, 0x681e, 0x0c7f, 0x007c, 0x0c7e, 0x7148, 0x2160, 0x2008,
-+	0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612,
-+	0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016,
-+	0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff,
-+	0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c,
-+	0x0c7e, 0x7048, 0x2060, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0,
-+	0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, 0x0c7f, 0x007c,
-+	0xa282, 0x0002, 0x00c0, 0x2dda, 0x7aa8, 0x691c, 0xa18d, 0x0080,
-+	0x691e, 0xa184, 0x0200, 0x0040, 0x2d1d, 0xa18c, 0xfdff, 0x691e,
-+	0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, 0x2dda, 0x1078, 0x2d63,
-+	0x1078, 0x2cc8, 0xa980, 0x0001, 0x200c, 0x1078, 0x2f0d, 0x1078,
-+	0x2c58, 0x88ff, 0x0040, 0x2d10, 0x789b, 0x0060, 0x2800, 0x78aa,
-+	0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2d0c,
-+	0x781b, 0x0055, 0x0078, 0x1d39, 0x781b, 0x0069, 0x0078, 0x1d39,
-+	0x7e58, 0xa684, 0x0400, 0x00c0, 0x2d19, 0x781b, 0x0058, 0x0078,
-+	0x1d39, 0x781b, 0x006a, 0x0078, 0x1d39, 0xa282, 0x0002, 0x00c8,
-+	0x2d25, 0xa284, 0x0001, 0x0040, 0x2d2f, 0x7148, 0xa188, 0x0000,
-+	0x210c, 0xa18c, 0x2000, 0x00c0, 0x2d2f, 0x2011, 0x0000, 0x1078,
-+	0x2e41, 0x1078, 0x2d63, 0x1078, 0x2cc8, 0x7858, 0xa085, 0x0004,
-+	0x785a, 0x781b, 0x0069, 0x0078, 0x1d39, 0x0c7e, 0x027e, 0x2960,
-+	0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x2d53, 0xa084,
-+	0x0080, 0x00c0, 0x2d51, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078,
-+	0x2d60, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x681c, 0xa085, 0x0200, 0x681e,
-+	0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7048, 0x2060, 0x82ff, 0x0040,
-+	0x2d6b, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4,
-+	0xa084, 0xffbf, 0xa205, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
-+	0xffef, 0x6006, 0x0c7f, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003,
-+	0x0040, 0x2d85, 0x007f, 0x0078, 0x2d88, 0x007f, 0x0078, 0x2dd6,
-+	0xa684, 0x0020, 0x0040, 0x2dd6, 0x7888, 0xa084, 0x0040, 0x0040,
-+	0x2dd6, 0x78a8, 0x8001, 0x0040, 0x2d95, 0x7bb8, 0xa384, 0x003f,
-+	0x831b, 0x00c8, 0x2d9c, 0x8000, 0xa005, 0x0040, 0x2dbd, 0x831b,
-+	0x00c8, 0x2da5, 0x8001, 0x0040, 0x2dd2, 0xa006, 0x1078, 0x3414,
-+	0x78b4, 0x1078, 0x3479, 0x0078, 0x2dd6, 0xa684, 0x4000, 0x0040,
-+	0x2dbd, 0x78b8, 0x801b, 0x00c8, 0x2db6, 0x8000, 0xa084, 0x003f,
-+	0x00c0, 0x2dd2, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc, 0x2001,
-+	0x0001, 0xa108, 0x00c8, 0x2dc6, 0xa291, 0x0000, 0x79d2, 0x79da,
-+	0x7ad6, 0x7ade, 0x1078, 0x3414, 0x781b, 0x0067, 0x1078, 0x32e4,
-+	0x0078, 0x1d39, 0x781b, 0x0067, 0x0078, 0x1d39, 0x781b, 0x006a,
-+	0x0078, 0x1d39, 0x1078, 0x2e0d, 0x781b, 0x0069, 0x0078, 0x1d39,
-+	0x1078, 0x2df9, 0x781b, 0x0069, 0x0078, 0x1d39, 0x6823, 0x0002,
-+	0x1078, 0x2e01, 0x691c, 0xa18d, 0x0020, 0x691e, 0x6814, 0xa084,
-+	0x8000, 0x0040, 0x2df5, 0x6817, 0x0005, 0x781b, 0x0069, 0x0078,
-+	0x1d39, 0x2001, 0x0005, 0x0078, 0x2e0f, 0x2001, 0x000c, 0x0078,
-+	0x2e0f, 0x2001, 0x0006, 0x0078, 0x2e0f, 0x2001, 0x000d, 0x0078,
-+	0x2e0f, 0x2001, 0x0009, 0x0078, 0x2e0f, 0x2001, 0x0007, 0x789b,
-+	0x007f, 0x78aa, 0xa6b5, 0x0008, 0x7e5a, 0x007c, 0x077e, 0x873f,
-+	0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x3a80, 0xa7b8,
-+	0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x2e2f, 0xa184,
-+	0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008, 0x6006, 0x8738,
-+	0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040, 0x2e3f, 0xa184,
-+	0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010, 0x6006, 0x077f,
-+	0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, 0x007c, 0x2031,
-+	0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
-+	0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab,
-+	0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003,
-+	0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2001, 0x3846,
-+	0x2004, 0xa082, 0x0028, 0x0040, 0x2e7d, 0x2021, 0x2ef4, 0x2019,
-+	0x0014, 0x20a9, 0x000c, 0x0078, 0x2e83, 0x2021, 0x2f00, 0x2019,
-+	0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404, 0xa084, 0xfff0,
-+	0xa106, 0x0040, 0x2e92, 0x8420, 0x2300, 0xa210, 0x0070, 0x2e92,
-+	0x0078, 0x2e85, 0x157f, 0x007c, 0x157e, 0x2011, 0x3846, 0x2214,
-+	0xa282, 0x0032, 0x0048, 0x2ea8, 0x0040, 0x2eac, 0x2021, 0x2ee6,
-+	0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x0078, 0x2ebc,
-+	0xa282, 0x0028, 0x0040, 0x2eb4, 0x2021, 0x2ef4, 0x2019, 0x0014,
-+	0x20a9, 0x000c, 0x0078, 0x2eba, 0x2021, 0x2f00, 0x2019, 0x0019,
-+	0x20a9, 0x000d, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x2ecc,
-+	0x0048, 0x2ecc, 0x8420, 0x2300, 0xa210, 0x0070, 0x2ec9, 0x0078,
-+	0x2ebc, 0x157f, 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8,
-+	0x2ed5, 0x7808, 0xa085, 0x0070, 0x780a, 0x78ec, 0xa084, 0x0300,
-+	0x0040, 0x2ee3, 0x2404, 0xa09e, 0x1201, 0x00c0, 0x2ee3, 0x2001,
-+	0x2101, 0x0078, 0x2ee4, 0x2404, 0xa005, 0x007c, 0x1201, 0x3002,
-+	0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
-+	0x7a06, 0x0a07, 0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202,
-+	0x7202, 0x6605, 0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05,
-+	0x2202, 0x3202, 0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604,
-+	0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046,
-+	0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003,
-+	0x8003, 0x8003, 0xa105, 0xa0e0, 0x3b00, 0x007c, 0x79d8, 0x7adc,
-+	0x78d0, 0x801b, 0x00c8, 0x2f25, 0x8000, 0xa084, 0x003f, 0xa108,
-+	0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3840,
-+	0x2091, 0x8000, 0x2104, 0x0079, 0x2f35, 0x2f67, 0x2f3f, 0x2f3f,
-+	0x2f3f, 0x2f3f, 0x2f3f, 0x2f3d, 0x2f3d, 0x1078, 0x1ce7, 0x784b,
-+	0x0004, 0x7848, 0xa084, 0x0004, 0x00c0, 0x2f41, 0x784b, 0x0008,
-+	0x7848, 0xa084, 0x0008, 0x00c0, 0x2f48, 0x68b0, 0xa085, 0x4000,
-+	0x68b2, 0x7858, 0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080,
-+	0x00c0, 0x2f67, 0x0018, 0x2f67, 0x6818, 0xa084, 0x0020, 0x00c0,
-+	0x2f65, 0x781b, 0x00dd, 0x0078, 0x2f67, 0x781b, 0x00e4, 0x2091,
-+	0x8001, 0x0f7f, 0x007c, 0x0c7e, 0x6810, 0x8007, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa0e0, 0x3a80, 0x6004, 0xa084, 0x000a,
-+	0x00c0, 0x2fb4, 0x6108, 0xa194, 0xff00, 0x0040, 0x2fb4, 0xa18c,
-+	0x00ff, 0x6004, 0xa084, 0x0014, 0x00c0, 0x2f9d, 0xa085, 0x0014,
-+	0x6006, 0x017e, 0x691c, 0xa18d, 0x0002, 0x691e, 0x017f, 0x2001,
-+	0x000c, 0xa106, 0x0040, 0x2f99, 0x2100, 0x8003, 0x2008, 0x0078,
-+	0x2fad, 0x2009, 0x0019, 0x0078, 0x2fad, 0x2011, 0x0000, 0x6000,
-+	0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef, 0x6006, 0x017e,
-+	0x691c, 0xa18d, 0x0002, 0x691e, 0x017f, 0x2100, 0xa205, 0x600a,
-+	0x6004, 0xa085, 0x000a, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x006a,
-+	0x0078, 0x1d39, 0x781b, 0x0069, 0x0078, 0x1d39, 0x781b, 0x0058,
-+	0x0078, 0x1d39, 0x781b, 0x0055, 0x0078, 0x1d39, 0x781b, 0x00dd,
-+	0x0078, 0x1d39, 0x781b, 0x00dc, 0x0078, 0x1d39, 0x781b, 0x00e4,
-+	0x0078, 0x1d39, 0x781b, 0x00e3, 0x0078, 0x1d39, 0x781b, 0x009e,
-+	0x0078, 0x1d39, 0x781b, 0x009d, 0x0078, 0x1d39, 0x70a3, 0x0001,
-+	0x781b, 0x0046, 0x0078, 0x1d39, 0x007e, 0x7830, 0xa084, 0x00c0,
-+	0x00c0, 0x2ffb, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
-+	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x2ffb, 0x7808,
-+	0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0x7808, 0xa085, 0x0002,
-+	0x780a, 0x007c, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3002, 0x0098,
-+	0x300b, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005,
-+	0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x301a,
-+	0x0098, 0x3018, 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002, 0x780a,
-+	0x007f, 0x007c, 0xa784, 0x0070, 0x0040, 0x302e, 0x0c7e, 0x2d60,
-+	0x2f68, 0x1078, 0x1c97, 0x2d78, 0x2c68, 0x0c7f, 0x6817, 0x0003,
-+	0x7858, 0xa084, 0x3f00, 0x681a, 0x682f, 0x0000, 0x682b, 0x0000,
-+	0x784b, 0x0008, 0x78e4, 0xa005, 0x00d0, 0x21cc, 0xa084, 0x0020,
-+	0x0040, 0x21cc, 0x78ec, 0xa084, 0x0003, 0x0040, 0x21cc, 0x0018,
-+	0x21cc, 0x0078, 0x2de0, 0x0c7e, 0x6810, 0x8007, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa080, 0x3a80, 0x2060, 0x2048, 0x704a,
-+	0x6000, 0x704e, 0x6004, 0x7052, 0x0c7f, 0x007c, 0x0020, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0062, 0x0009, 0x0014, 0x0014, 0x9847, 0x0014, 0x0014, 0x98f5,
-+	0x98e7, 0x0014, 0x0014, 0x0080, 0x00bf, 0x0100, 0x0402, 0x2008,
-+	0xf880, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0xa200, 0x8838,
-+	0x817e, 0x842a, 0x84a0, 0x3806, 0x8839, 0x28c2, 0x9cc3, 0xa805,
-+	0x0864, 0xa83b, 0x3008, 0x28c1, 0x9cc3, 0xa201, 0x300c, 0x2847,
-+	0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2,
-+	0x9ca0, 0xa8f3, 0x0864, 0xa829, 0x300c, 0xa801, 0x3008, 0x28e1,
-+	0x9ca0, 0x280d, 0xa204, 0x64c0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
-+	0x7023, 0x8576, 0x8677, 0xa80f, 0x786e, 0x883e, 0xa80c, 0x282b,
-+	0xa205, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576,
-+	0x8677, 0xa801, 0x883e, 0x2069, 0x28c1, 0x9cc3, 0x2044, 0x2103,
-+	0x20a2, 0x2081, 0xa8dc, 0xa207, 0x0014, 0xa203, 0x8000, 0x84a8,
-+	0x85a4, 0x1872, 0x849a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e,
-+	0x866f, 0x0704, 0x3008, 0x9ca0, 0x0014, 0xa202, 0x8000, 0x85a4,
-+	0x3009, 0x84a8, 0x19e2, 0xf848, 0x8174, 0x86eb, 0x85eb, 0x872e,
-+	0x87a9, 0x883f, 0x08e6, 0xa8f1, 0xf861, 0xa8e8, 0xf801, 0x0014,
-+	0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014,
-+	0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014,
-+	0xa206, 0x6865, 0x817f, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042,
-+	0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, 0x3008,
-+	0x84a8, 0x1dc6, 0x20d7, 0x8822, 0x0016, 0x8000, 0x2848, 0x1011,
-+	0xa8fc, 0x3008, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd, 0xa887,
-+	0x3008, 0x283d, 0x1011, 0xa8fd, 0xa209, 0x0017, 0x300c, 0x8000,
-+	0x85a4, 0x1de2, 0xdac1, 0x0014, 0x26e0, 0x873a, 0xfaa2, 0x19f2,
-+	0x1fe2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x817e, 0x842a, 0x84a0,
-+	0x3806, 0x0210, 0x9ccd, 0x0704, 0x0000, 0x127e, 0x2091, 0x2200,
-+	0x2049, 0x314d, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008,
-+	0xa084, 0xfffd, 0xa205, 0x0040, 0x315f, 0x0078, 0x3164, 0x7003,
-+	0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084, 0x0001, 0x00c0,
-+	0x3192, 0x7108, 0x8104, 0x00c8, 0x3171, 0x1078, 0x322e, 0x0078,
-+	0x3169, 0x700c, 0xa08c, 0x007f, 0x0040, 0x3192, 0x7004, 0x8004,
-+	0x00c8, 0x3189, 0x7014, 0xa005, 0x00c0, 0x3185, 0x7010, 0xa005,
-+	0x0040, 0x3189, 0xa102, 0x00c8, 0x3169, 0x7007, 0x0010, 0x0078,
-+	0x3192, 0x8aff, 0x0040, 0x3192, 0x1078, 0x33eb, 0x00c0, 0x318c,
-+	0x0040, 0x3169, 0x1078, 0x31dc, 0x7003, 0x0000, 0x127f, 0x2000,
-+	0x007c, 0x6424, 0x84ff, 0x0040, 0x31b6, 0x2c70, 0x2039, 0x31bb,
-+	0x2704, 0xae68, 0x680c, 0xa630, 0x6808, 0xa529, 0x8421, 0x0040,
-+	0x31b6, 0x8738, 0x2704, 0xa005, 0x00c0, 0x31a1, 0x7098, 0xa075,
-+	0x0040, 0x31b6, 0x2039, 0x31b8, 0x0078, 0x31a0, 0x007c, 0x0000,
-+	0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018, 0x001c, 0x0000,
-+	0x127e, 0x2091, 0x2200, 0x2079, 0x3800, 0x2071, 0x0010, 0x7007,
-+	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071, 0x0020, 0x7007,
-+	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049, 0x0000, 0x78b7,
-+	0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x31dc, 0x7004, 0x8004,
-+	0x00c8, 0x3208, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106, 0x00c0,
-+	0x31e4, 0xa184, 0x0030, 0x0040, 0x31f1, 0xa086, 0x0030, 0x00c0,
-+	0x31e4, 0x7000, 0xa084, 0x0001, 0x00c0, 0x3208, 0x7008, 0xa084,
-+	0x000c, 0x00c0, 0x3206, 0x710c, 0xa184, 0x0300, 0x00c0, 0x3206,
-+	0xa184, 0x007f, 0x00c0, 0x31dc, 0x0078, 0x3208, 0x6817, 0x0003,
-+	0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0,
-+	0x320c, 0x7007, 0x0012, 0x7108, 0x8104, 0x0048, 0x3211, 0x78b7,
-+	0x0000, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e,
-+	0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x322e, 0x157f,
-+	0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x2118,
-+	0x7108, 0x700c, 0xa084, 0x0300, 0x00c0, 0x3270, 0xa184, 0x000c,
-+	0x00c0, 0x3270, 0x8213, 0x8213, 0x8213, 0x8213, 0xa284, 0x0100,
-+	0xa10d, 0x810b, 0x810b, 0x810f, 0xa184, 0x0007, 0x0079, 0x3248,
-+	0x3252, 0x3262, 0x3270, 0x3262, 0x3284, 0x3284, 0x3270, 0x3282,
-+	0x1078, 0x1ce7, 0x7007, 0x0002, 0x8aff, 0x00c0, 0x325b, 0x2049,
-+	0x0000, 0x0078, 0x325f, 0x1078, 0x33eb, 0x00c0, 0x325b, 0x78b7,
-+	0x0000, 0x007c, 0x7007, 0x0002, 0x8aff, 0x00c0, 0x3269, 0x0078,
-+	0x326d, 0x1078, 0x33eb, 0x00c0, 0x3269, 0x78b7, 0x0000, 0x007c,
-+	0x7007, 0x0002, 0x1078, 0x31dc, 0x1078, 0x2f2b, 0x6814, 0xa084,
-+	0x8000, 0x0040, 0x327d, 0x6817, 0x0002, 0x007c, 0x1078, 0x1ce7,
-+	0x1078, 0x1ce7, 0x1078, 0x32d6, 0x7210, 0x7114, 0x700c, 0xa09c,
-+	0x007f, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x78b4, 0xa005,
-+	0x0040, 0x3296, 0x78b7, 0x0000, 0x0078, 0x32b9, 0x1078, 0x32d6,
-+	0x2704, 0x2c58, 0xac60, 0x630c, 0x2200, 0xa322, 0x6308, 0x2100,
-+	0xa31b, 0x2400, 0xa305, 0x0040, 0x32af, 0x00c8, 0x32af, 0x8412,
-+	0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x3296, 0x2b60,
-+	0x8a07, 0xa7ba, 0x31b8, 0xa73d, 0x2c00, 0x6882, 0x6f86, 0x6c8e,
-+	0x6b8a, 0x7007, 0x0012, 0x1078, 0x31dc, 0x007c, 0x8738, 0x2704,
-+	0xa005, 0x00c0, 0x32ca, 0x6098, 0xa005, 0x0040, 0x32d3, 0x2060,
-+	0x2039, 0x31b8, 0x8a51, 0x0040, 0x32d2, 0x7008, 0xa084, 0x00c0,
-+	0xa086, 0x00c0, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8739,
-+	0x2704, 0xa004, 0x00c0, 0x32e3, 0x2039, 0x31be, 0x6000, 0xa064,
-+	0x00c0, 0x32e3, 0x2d60, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200,
-+	0x0d7f, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c, 0x8057, 0xaad4,
-+	0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x31b8, 0x7e08, 0xa6b5, 0x000c,
-+	0x6818, 0xa084, 0x0040, 0x0040, 0x32ff, 0xa6b5, 0x0001, 0x0f7e,
-+	0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040, 0x0040, 0x330e,
-+	0xa684, 0x0001, 0x00c0, 0x330e, 0xa6b5, 0x0001, 0x7007, 0x0004,
-+	0x7004, 0xa084, 0x0004, 0x00c0, 0x3310, 0x7000, 0xa005, 0x0040,
-+	0x331b, 0x1078, 0x1ce7, 0x2400, 0xa305, 0x00c0, 0x3321, 0x0078,
-+	0x335e, 0x2c58, 0x2704, 0xac60, 0x6004, 0xa400, 0x007e, 0x701a,
-+	0x6000, 0xa301, 0x701e, 0x2009, 0x04fd, 0x2104, 0xa086, 0x04fd,
-+	0x007f, 0x00c0, 0x334e, 0xa084, 0x0001, 0x0040, 0x334e, 0xa684,
-+	0x0001, 0x00c0, 0x334e, 0x7013, 0x0001, 0x7017, 0x0000, 0x7602,
-+	0x7007, 0x0001, 0x78b7, 0x0001, 0xa4a0, 0x0001, 0xa399, 0x0000,
-+	0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e, 0x620c, 0x2400,
-+	0xa202, 0x7012, 0x6208, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007,
-+	0x0001, 0x2b60, 0x1078, 0x32be, 0x0078, 0x3360, 0x1078, 0x33eb,
-+	0x00c0, 0x335e, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091,
-+	0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-+	0x336c, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e,
-+	0x2091, 0x2200, 0x0d7f, 0x2049, 0x3376, 0x7007, 0x0004, 0x7004,
-+	0xa084, 0x0004, 0x00c0, 0x337f, 0x7e08, 0xa6b5, 0x000c, 0x6818,
-+	0xa084, 0x0040, 0x0040, 0x338e, 0xa6b5, 0x0001, 0x6824, 0xa005,
-+	0x0040, 0x339a, 0x2050, 0x2039, 0x31bb, 0x2d60, 0x1078, 0x33eb,
-+	0x00c0, 0x3396, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
-+	0x000c, 0x6818, 0xa084, 0x0040, 0x0040, 0x33b0, 0xa6b5, 0x0001,
-+	0x2049, 0x339d, 0x6824, 0xa055, 0x0040, 0x33e8, 0x2d70, 0x2e60,
-+	0x2039, 0x31bb, 0x2704, 0xae68, 0x680c, 0xa422, 0x6808, 0xa31b,
-+	0x0048, 0x33d5, 0x8a51, 0x00c0, 0x33c7, 0x1078, 0x1ce7, 0x8738,
-+	0x2704, 0xa005, 0x00c0, 0x33bb, 0x7098, 0xa075, 0x2060, 0x0040,
-+	0x33e8, 0x2039, 0x31b8, 0x0078, 0x33ba, 0x8422, 0x8420, 0x831a,
-+	0xa399, 0x0000, 0x690c, 0x2400, 0xa122, 0x6908, 0x2300, 0xa11b,
-+	0x00c8, 0x33e4, 0x1078, 0x1ce7, 0x2071, 0x0020, 0x0078, 0x330e,
-+	0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x00c0, 0xa086, 0x00c0,
-+	0x0040, 0x3413, 0x2704, 0xac08, 0x2104, 0x701e, 0x8108, 0x2104,
-+	0x701a, 0x8108, 0x2104, 0x7016, 0x8108, 0x2104, 0x7012, 0x0f7e,
-+	0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040, 0x0040, 0x340e,
-+	0xa684, 0x0001, 0x00c0, 0x340e, 0xa6b5, 0x0001, 0x7602, 0x7007,
-+	0x0001, 0x1078, 0x32be, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091,
-+	0x2200, 0x2049, 0x3414, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x00c0,
-+	0x00c0, 0x342a, 0x6824, 0xa005, 0x0040, 0x343a, 0x0078, 0x3164,
-+	0x0078, 0x343a, 0x7108, 0x8104, 0x00c8, 0x3432, 0x1078, 0x322e,
-+	0x0078, 0x341d, 0x7007, 0x0010, 0x7108, 0x8104, 0x00c8, 0x3434,
-+	0x1078, 0x322e, 0x7008, 0xa086, 0x0002, 0x00c0, 0x341d, 0x7000,
-+	0xa005, 0x00c0, 0x341d, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f,
-+	0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0d7e, 0x2091,
-+	0x2200, 0x0d7f, 0x2049, 0x344a, 0xad80, 0x0010, 0x20a0, 0x2099,
-+	0x0031, 0x700c, 0xa084, 0x007f, 0x6826, 0x7007, 0x0008, 0x7007,
-+	0x0002, 0x7003, 0x0001, 0x0040, 0x3468, 0x8000, 0x80ac, 0x53a5,
-+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x346a, 0x2049,
-+	0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
-+	0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049,
-+	0x3479, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c, 0x8057, 0xaad4,
-+	0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x31b8, 0x7e08, 0xa6b5, 0x0004,
-+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x3492, 0x2c58,
-+	0x2704, 0xac60, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e,
-+	0x7013, 0x0001, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x007f,
-+	0x8007, 0x2009, 0x0031, 0x200a, 0x00a0, 0x34ac, 0x7108, 0x7007,
-+	0x0002, 0x810c, 0x00c8, 0x34ac, 0x810c, 0x0048, 0x34b9, 0x0078,
-+	0x3270, 0xa4a0, 0x0001, 0xa399, 0x0000, 0x6b8a, 0x6c8e, 0x7007,
-+	0x0004, 0x2049, 0x0000, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x34d1,
-+	0xa200, 0x00f0, 0x34cc, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
-+	0x0010, 0xa005, 0x0040, 0x34f7, 0xa11a, 0x00c8, 0x34f7, 0x8213,
-+	0x818d, 0x0048, 0x34ea, 0xa11a, 0x00c8, 0x34eb, 0x00f0, 0x34df,
-+	0x0078, 0x34ef, 0xa11a, 0x2308, 0x8210, 0x00f0, 0x34df, 0x007e,
-+	0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e,
-+	0x3200, 0xa085, 0x0800, 0x0078, 0x34f3, 0x00e0, 0x3563, 0x2091,
-+	0x6000, 0x7820, 0x8001, 0x7822, 0x00c0, 0x355b, 0x7824, 0x7822,
-+	0x2009, 0x3834, 0x2104, 0xa005, 0x00c0, 0x3510, 0x2001, 0x0010,
-+	0x8001, 0x200a, 0x077e, 0x803f, 0x1078, 0x2f11, 0x077f, 0x20a9,
-+	0x0020, 0x601f, 0x0064, 0xace0, 0x0010, 0x00f0, 0x3519, 0x2091,
-+	0x8000, 0x2069, 0x3840, 0x6800, 0xa084, 0x0007, 0x0040, 0x3538,
-+	0xa086, 0x0002, 0x0040, 0x3538, 0x6830, 0xa00d, 0x0040, 0x3538,
-+	0x2104, 0xa005, 0x0040, 0x3538, 0x8001, 0x200a, 0x0040, 0x3640,
-+	0x2061, 0x3b00, 0x2009, 0x0002, 0x20a9, 0x0100, 0x603c, 0xa005,
-+	0x0040, 0x354e, 0x8001, 0x603e, 0x00c0, 0x354e, 0x6010, 0xa005,
-+	0x0040, 0x354e, 0x017e, 0x1078, 0x1b49, 0x017f, 0xace0, 0x0010,
-+	0x0070, 0x3554, 0x0078, 0x353e, 0x8109, 0x0040, 0x355b, 0x20a9,
-+	0x0100, 0x0078, 0x353e, 0x1078, 0x3578, 0x1078, 0x3566, 0x1078,
-+	0x359d, 0x1078, 0x3707, 0x2091, 0x8001, 0x007c, 0x783c, 0x8001,
-+	0x783e, 0x00c0, 0x3577, 0x7840, 0x783e, 0x7848, 0xa005, 0x0040,
-+	0x3577, 0x8001, 0x784a, 0x00c0, 0x3577, 0x1078, 0x1b49, 0x007c,
-+	0x7834, 0x8001, 0x7836, 0x00c0, 0x359c, 0x7838, 0x7836, 0x2091,
-+	0x8000, 0x7844, 0xa005, 0x00c0, 0x3587, 0x2001, 0x0101, 0x8001,
-+	0x7846, 0xa080, 0x5b00, 0x2040, 0x2004, 0xa065, 0x0040, 0x359c,
-+	0x6020, 0xa005, 0x0040, 0x3598, 0x8001, 0x6022, 0x0040, 0x35cc,
-+	0x6000, 0x2c40, 0x0078, 0x358d, 0x007c, 0x7828, 0x8001, 0x782a,
-+	0x00c0, 0x35cb, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x35aa,
-+	0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003,
-+	0xa090, 0x3b00, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040,
-+	0x35cb, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x35c3, 0x8001,
-+	0x2012, 0x00c0, 0x35cb, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080,
-+	0x201a, 0x1078, 0x1b49, 0x007c, 0x2069, 0x3840, 0x6800, 0xa005,
-+	0x0040, 0x35d6, 0x683c, 0xac06, 0x0040, 0x3640, 0x6710, 0x6fb6,
-+	0x1078, 0x1758, 0x6808, 0xa084, 0x0020, 0x00c0, 0x363d, 0x2009,
-+	0x382b, 0x2104, 0xa005, 0x0040, 0x35e9, 0x6023, 0x0001, 0x0078,
-+	0x363d, 0x6808, 0xa084, 0xffef, 0xa085, 0x0021, 0x6017, 0x0006,
-+	0x60b0, 0xa084, 0x3f00, 0x601a, 0x601c, 0xa084, 0x00ff, 0xa085,
-+	0x0060, 0x601e, 0x6000, 0x2042, 0x6710, 0x6fb6, 0x1078, 0x1758,
-+	0x6818, 0xa005, 0x0040, 0x3606, 0x8001, 0x681a, 0x6808, 0xa084,
-+	0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x3610, 0x1078, 0x1ce7,
-+	0x6812, 0x602f, 0x0000, 0x602b, 0x0000, 0x2c68, 0x1078, 0x18b6,
-+	0x2069, 0x3840, 0x6710, 0xa784, 0x0f00, 0x68b6, 0x2001, 0x0002,
-+	0x1078, 0x1b44, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0030,
-+	0x1078, 0x1765, 0x2011, 0x3835, 0x2214, 0x6a3e, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x3622, 0x2009, 0x382b, 0x200b, 0x0008, 0x2009,
-+	0x382c, 0x2069, 0x3840, 0x68b4, 0x200a, 0x2091, 0x8001, 0x007c,
-+	0x2009, 0x384f, 0x2164, 0x2069, 0x0100, 0x1078, 0x1c97, 0x6017,
-+	0x0006, 0x6858, 0xa084, 0x3f00, 0x601a, 0x601c, 0xa084, 0x00ff,
-+	0xa085, 0x0048, 0x601e, 0x602f, 0x0000, 0x602b, 0x0000, 0x6830,
-+	0xa084, 0x0040, 0x0040, 0x367c, 0x684b, 0x0004, 0x20a9, 0x0014,
-+	0x6848, 0xa084, 0x0004, 0x0040, 0x3669, 0x0070, 0x3669, 0x0078,
-+	0x3660, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
-+	0x0040, 0x3676, 0x0070, 0x3676, 0x0078, 0x366d, 0x20a9, 0x00fa,
-+	0x0070, 0x367c, 0x0078, 0x3678, 0x6808, 0xa084, 0xfffd, 0x680a,
-+	0x681b, 0x0046, 0x2009, 0x3868, 0x200b, 0x0007, 0x784c, 0x784a,
-+	0x2091, 0x8001, 0x007c, 0x2079, 0x3800, 0x1078, 0x36de, 0x1078,
-+	0x36a6, 0x1078, 0x36b4, 0x1078, 0x36c9, 0x1078, 0x36f3, 0x2009,
-+	0x3833, 0x200b, 0x0000, 0x2009, 0x3834, 0x200b, 0x0000, 0x7833,
-+	0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x007c, 0x2019, 0x0003,
-+	0x2011, 0x3846, 0x2204, 0xa086, 0x003c, 0x0040, 0x36b1, 0x2019,
-+	0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, 0x0030, 0x2011, 0x3846,
-+	0x2204, 0xa086, 0x0032, 0x0040, 0x36c6, 0x2019, 0x0039, 0x2204,
-+	0xa086, 0x003c, 0x0040, 0x36c6, 0x2019, 0x0027, 0x7b36, 0x7b3a,
-+	0x007c, 0x2019, 0x000f, 0x2011, 0x3846, 0x2204, 0xa086, 0x003c,
-+	0x0040, 0x36db, 0x2019, 0x000d, 0x2204, 0xa086, 0x0032, 0x0040,
-+	0x36db, 0x2019, 0x000a, 0x7b3e, 0x7b42, 0x007c, 0x2019, 0x2faf,
-+	0x2011, 0x3846, 0x2204, 0xa086, 0x0032, 0x0040, 0x36f0, 0x2019,
-+	0x3971, 0x2204, 0xa086, 0x003c, 0x0040, 0x36f0, 0x2019, 0x2626,
-+	0x7b22, 0x7b26, 0x007c, 0x2019, 0x0001, 0x2011, 0x3846, 0x2204,
-+	0xa086, 0x003c, 0x0040, 0x36fe, 0x2019, 0x0001, 0x017e, 0x2009,
-+	0x3831, 0x230a, 0x2009, 0x3832, 0x230a, 0x017f, 0x007c, 0x2009,
-+	0x3831, 0x2104, 0x8001, 0x200a, 0xa005, 0x00c0, 0x3755, 0x2009,
-+	0x3832, 0x2104, 0x2009, 0x3831, 0x200a, 0x2009, 0x3833, 0x2104,
-+	0xa005, 0x00c0, 0x371d, 0x2001, 0x0200, 0x8001, 0x200a, 0x8003,
-+	0x8003, 0x8003, 0x8003, 0xa090, 0x3b00, 0x2208, 0xa298, 0x0002,
-+	0x2304, 0xa084, 0x0200, 0x0040, 0x3755, 0xa290, 0x000e, 0x2204,
-+	0xa005, 0x0040, 0x3740, 0x8001, 0x0040, 0x3740, 0x8001, 0x0040,
-+	0x3740, 0x8001, 0x0040, 0x3740, 0x8001, 0x2012, 0x00c0, 0x3755,
-+	0x2012, 0x2304, 0xa084, 0xfdff, 0xa085, 0x0400, 0x201a, 0xa188,
-+	0x000c, 0x2104, 0x007e, 0xa084, 0x00ff, 0x8001, 0x027f, 0xa294,
-+	0xff00, 0xa205, 0x200a, 0x1078, 0x1b49, 0x007c, 0x6ed0
-+};
-+#else
-+/*
-+ * Flakey, not quite functional, target mode code for ISP1000
-+ * hacked out of PCI 7.55 initiator/target mode code.
-+ */
-+static const u_int16_t isp_1000_risc_code[] = {
-+	0x0078, 0x103a, 0x0000, 0x3c1f, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
-+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
-+	0x3130, 0x3030, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
-+	0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3535,
-+	0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
-+	0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
-+	0x3031, 0x2024, 0x3700, 0xa086, 0xffff, 0x0040, 0x1043, 0x2079,
-+	0x4d00, 0x7803, 0x0001, 0x20c1, 0x0008, 0x2071, 0x0010, 0x70c3,
-+	0x0004, 0x20c9, 0x73ff, 0x2089, 0x116f, 0x70c7, 0x4953, 0x70cb,
-+	0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00, 0x70d6, 0x20c1,
-+	0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5,
-+	0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54,
-+	0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10b5, 0xa386,
-+	0x000f, 0x0040, 0x107b, 0x2c6a, 0x2a5a, 0x20c1, 0x0000, 0x2019,
-+	0x000f, 0x0078, 0x105b, 0x2c6a, 0x2a5a, 0x20c1, 0x0008, 0x2009,
-+	0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc, 0x3fff, 0x2734,
-+	0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040, 0x109f, 0x284a,
-+	0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134, 0x200b, 0x5050,
-+	0x2114, 0xa286, 0x5050, 0x0040, 0x10a0, 0x0078, 0x1177, 0x284a,
-+	0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b, 0xa5a5, 0x2114,
-+	0xa286, 0xa5a5, 0x0040, 0x10b2, 0x250a, 0xa18a, 0x1000, 0x98c1,
-+	0x0078, 0x10b7, 0x250a, 0x0078, 0x10b7, 0x2c6a, 0x2a5a, 0x2130,
-+	0xa18a, 0x0040, 0x2128, 0xa1a2, 0x4d00, 0x8424, 0x8424, 0x8424,
-+	0x8424, 0x8424, 0x8424, 0xa192, 0x7400, 0x2009, 0x0000, 0x2001,
-+	0x0031, 0x1078, 0x1bd8, 0x2218, 0x2079, 0x4d00, 0x2fa0, 0x2408,
-+	0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10d2,
-+	0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883, 0x0000, 0x2031,
-+	0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f,
-+	0x0003, 0x2069, 0x4d40, 0x00a8, 0x10f1, 0x681b, 0x003c, 0x0078,
-+	0x10f3, 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f,
-+	0x0008, 0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817,
-+	0x0008, 0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x4f80, 0x2011,
-+	0x0020, 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803,
-+	0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290,
-+	0x0004, 0x8109, 0x00c0, 0x110b, 0x2069, 0x5000, 0x2009, 0x0002,
-+	0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386,
-+	0xfeff, 0x00c0, 0x1131, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078,
-+	0x1135, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070,
-+	0x113b, 0x0078, 0x1122, 0x8109, 0x00c0, 0x1120, 0x1078, 0x20d8,
-+	0x1078, 0x43d1, 0x1078, 0x18a9, 0x1078, 0x48d9, 0x3200, 0xa085,
-+	0x000d, 0x2090, 0x70c3, 0x0000, 0x0090, 0x1155, 0x70c0, 0xa086,
-+	0x0002, 0x00c0, 0x1155, 0x1078, 0x126d, 0x1078, 0x117f, 0x78cc,
-+	0xa005, 0x00c0, 0x1163, 0x1078, 0x1c01, 0x0010, 0x1169, 0x0068,
-+	0x1169, 0x1078, 0x1fbd, 0x0010, 0x1169, 0x0068, 0x1169, 0x1078,
-+	0x198e, 0x00e0, 0x1155, 0x1078, 0x4760, 0x0078, 0x1155, 0x1177,
-+	0x1179, 0x22cc, 0x22cc, 0x4452, 0x4452, 0x22cc, 0x22cc, 0x0078,
-+	0x1177, 0x0078, 0x1179, 0x0078, 0x117b, 0x0078, 0x117d, 0x0068,
-+	0x11ea, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x11ea,
-+	0x7814, 0xa005, 0x00c0, 0x1190, 0x0010, 0x11eb, 0x0078, 0x11ea,
-+	0x2009, 0x4d5b, 0x2104, 0xa005, 0x00c0, 0x11ea, 0x2009, 0x4d64,
-+	0x200b, 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11b5, 0x7816,
-+	0x2009, 0x4d62, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014,
-+	0x70ca, 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105,
-+	0x70ce, 0x1078, 0x188e, 0x0078, 0x11e8, 0x7814, 0xa086, 0x0018,
-+	0x00c0, 0x11bc, 0x1078, 0x15e0, 0x7817, 0x0000, 0x2009, 0x4d62,
-+	0x2104, 0xa065, 0x0040, 0x11d8, 0x0c7e, 0x609c, 0x2060, 0x1078,
-+	0x18f9, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x16a2, 0x2009, 0x000e,
-+	0x6007, 0x0103, 0x1078, 0x186a, 0x00c0, 0x11e4, 0x1078, 0x188e,
-+	0x2009, 0x4d62, 0x200b, 0x0000, 0x2009, 0x4d5c, 0x2104, 0x200b,
-+	0x0000, 0xa005, 0x0040, 0x11e8, 0x2001, 0x4005, 0x0078, 0x126f,
-+	0x0078, 0x126d, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb,
-+	0x0000, 0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x123b,
-+	0x2038, 0x0079, 0x11fb, 0x126d, 0x12c4, 0x1292, 0x12d3, 0x12e2,
-+	0x12e8, 0x1289, 0x16ba, 0x12ec, 0x1281, 0x1296, 0x1298, 0x129a,
-+	0x129c, 0x16bf, 0x1281, 0x12f4, 0x1313, 0x15ee, 0x16b4, 0x129e,
-+	0x1517, 0x1533, 0x154f, 0x157a, 0x14d0, 0x14de, 0x14f2, 0x1506,
-+	0x1384, 0x1281, 0x1332, 0x1338, 0x133d, 0x1342, 0x1348, 0x134d,
-+	0x1352, 0x1357, 0x135c, 0x1360, 0x1375, 0x1381, 0x1281, 0x1281,
-+	0x1281, 0x1281, 0x1390, 0x1399, 0x13a8, 0x13ce, 0x13d8, 0x13df,
-+	0x141a, 0x1429, 0x1438, 0x144a, 0x14b0, 0x14c0, 0x1281, 0x1281,
-+	0x1281, 0x1281, 0x14c5, 0xa0bc, 0xffa0, 0x00c0, 0x1281, 0x2038,
-+	0xa084, 0x001f, 0x0079, 0x1244, 0x16f8, 0x16fb, 0x170b, 0x1281,
-+	0x1281, 0x1846, 0x1858, 0x1281, 0x1281, 0x1281, 0x185c, 0x1864,
-+	0x1281, 0x1281, 0x1281, 0x1281, 0x1281, 0x1281, 0x1281, 0x1281,
-+	0x1281, 0x16d6, 0x16ea, 0x1281, 0x1797, 0x1281, 0x1822, 0x182c,
-+	0x1830, 0x183e, 0x1281, 0x1281, 0x72ca, 0x71c6, 0x2001, 0x4006,
-+	0x0078, 0x126f, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2,
-+	0x0068, 0x1270, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000,
-+	0x00e0, 0x1278, 0x00e0, 0x127a, 0x0068, 0x127a, 0x2091, 0x4080,
-+	0x007c, 0x70c3, 0x4001, 0x0078, 0x1270, 0x70c3, 0x4006, 0x0078,
-+	0x1270, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3,
-+	0x0078, 0x126d, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x126d,
-+	0x0078, 0x126d, 0x0078, 0x126d, 0x0078, 0x126d, 0x2091, 0x8000,
-+	0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
-+	0x70d3, 0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001,
-+	0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470,
-+	0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000,
-+	0x2091, 0x4080, 0x0078, 0x0455, 0x2029, 0x0000, 0x2520, 0x71d0,
-+	0x73c8, 0x72cc, 0x70c4, 0x1078, 0x19d3, 0x0040, 0x126d, 0x70c3,
-+	0x4002, 0x0078, 0x126d, 0x2029, 0x0000, 0x2520, 0x71d0, 0x73c8,
-+	0x72cc, 0x70c4, 0x1078, 0x1a1f, 0x0040, 0x126d, 0x70c3, 0x4002,
-+	0x0078, 0x126d, 0x71c4, 0x70c8, 0x2114, 0x200a, 0x0078, 0x126b,
-+	0x71c4, 0x2114, 0x0078, 0x126b, 0x70c7, 0x0007, 0x70cb, 0x0037,
-+	0x70cf, 0x0000, 0x0078, 0x126d, 0x2029, 0x0000, 0x2530, 0x70c4,
-+	0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005,
-+	0x0040, 0x130d, 0x8001, 0x7892, 0x7a9a, 0x7b9e, 0x7c96, 0x78cc,
-+	0xa084, 0xfffc, 0x78ce, 0x0078, 0x1311, 0x78cc, 0xa085, 0x0001,
-+	0x78ce, 0x0078, 0x126d, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8,
-+	0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040,
-+	0x132c, 0x8001, 0x78ae, 0x7ab6, 0x7bba, 0x7cb2, 0x78cc, 0xa084,
-+	0xfcff, 0x78ce, 0x0078, 0x1330, 0x78cc, 0xa085, 0x0100, 0x78ce,
-+	0x0078, 0x126d, 0x2009, 0x4d61, 0x210c, 0x7aec, 0x0078, 0x126b,
-+	0x2009, 0x4d41, 0x210c, 0x0078, 0x126c, 0x2009, 0x4d42, 0x210c,
-+	0x0078, 0x126c, 0x2061, 0x4d40, 0x610c, 0x6210, 0x0078, 0x126b,
-+	0x2009, 0x4d45, 0x210c, 0x0078, 0x126c, 0x2009, 0x4d46, 0x210c,
-+	0x0078, 0x126c, 0x2009, 0x4d48, 0x210c, 0x0078, 0x126c, 0x2009,
-+	0x4d49, 0x210c, 0x0078, 0x126c, 0x7908, 0x7a0c, 0x0078, 0x126b,
-+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
-+	0x4f80, 0x6a00, 0x6804, 0xa084, 0x0008, 0x0040, 0x1372, 0x6b08,
-+	0x0078, 0x1373, 0x6b0c, 0x0078, 0x126a, 0x77c4, 0x1078, 0x18b9,
-+	0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078,
-+	0x126a, 0x794c, 0x0078, 0x126c, 0x77c4, 0x1078, 0x18b9, 0x2091,
-+	0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091, 0x8001, 0x0078, 0x126a,
-+	0x71c4, 0xa182, 0x0010, 0x00c8, 0x1265, 0x1078, 0x21a3, 0x0078,
-+	0x126a, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x1265, 0x2011, 0x4d41,
-+	0x2204, 0x007e, 0x2112, 0x1078, 0x215c, 0x017f, 0x0078, 0x126c,
-+	0x71c4, 0x2011, 0x13c6, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0040,
-+	0x13b8, 0x8210, 0x0070, 0x13b6, 0x0078, 0x13ad, 0x0078, 0x1265,
-+	0xa292, 0x13c6, 0x027e, 0x2011, 0x4d42, 0x2204, 0x2112, 0x017f,
-+	0x007e, 0x1078, 0x2168, 0x017f, 0x0078, 0x126c, 0x03e8, 0x00fa,
-+	0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4d40,
-+	0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8, 0x6012, 0x0078, 0x126b,
-+	0x2061, 0x4d40, 0x6114, 0x70c4, 0x6016, 0x0078, 0x126c, 0x2061,
-+	0x4d40, 0x71c4, 0x2011, 0x0004, 0x601f, 0x0019, 0x2019, 0x1212,
-+	0xa186, 0x0028, 0x0040, 0x1400, 0x2011, 0x0005, 0x601f, 0x0019,
-+	0x2019, 0x1212, 0xa186, 0x0032, 0x0040, 0x1400, 0x2011, 0x0006,
-+	0x601f, 0x000c, 0x2019, 0x2222, 0xa186, 0x003c, 0x00c0, 0x1265,
-+	0x6018, 0x007e, 0x611a, 0x7800, 0xa084, 0x0001, 0x00c0, 0x1410,
-+	0x0028, 0x140c, 0x0078, 0x1410, 0x2019, 0x2222, 0x0078, 0x1412,
-+	0x2019, 0x1212, 0x23b8, 0x1078, 0x2179, 0x1078, 0x48d9, 0x017f,
-+	0x0078, 0x126c, 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x1265, 0x2011,
-+	0x4d48, 0x2204, 0x2112, 0x007e, 0x1078, 0x219b, 0x017f, 0x0078,
-+	0x126c, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x1265, 0x2011, 0x4d49,
-+	0x2204, 0x007e, 0x2112, 0x1078, 0x218a, 0x017f, 0x0078, 0x126c,
-+	0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x1264, 0xa284, 0xfffd,
-+	0x00c0, 0x1264, 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e,
-+	0x0078, 0x126b, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0xa0e8, 0x4f80, 0x2019, 0x0000, 0x72c8, 0x6800, 0x007e,
-+	0xa226, 0x0040, 0x1479, 0x6a02, 0xa484, 0x2000, 0x0040, 0x1462,
-+	0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x1468, 0xa39d, 0x0008,
-+	0xa484, 0x4000, 0x0040, 0x1479, 0x810f, 0xa284, 0x4000, 0x0040,
-+	0x1475, 0x1078, 0x21bd, 0x0078, 0x1479, 0x1078, 0x21af, 0x0078,
-+	0x1479, 0x72cc, 0x6808, 0xa206, 0x0040, 0x14a8, 0xa2a4, 0x00ff,
-+	0x2061, 0x4d40, 0x6118, 0xa186, 0x0028, 0x0040, 0x148f, 0xa186,
-+	0x0032, 0x0040, 0x1495, 0xa186, 0x003c, 0x0040, 0x149b, 0xa482,
-+	0x0064, 0x0048, 0x14a5, 0x0078, 0x149f, 0xa482, 0x0050, 0x0048,
-+	0x14a5, 0x0078, 0x149f, 0xa482, 0x0043, 0x0048, 0x14a5, 0x71c4,
-+	0x71c6, 0x027f, 0x72ca, 0x0078, 0x1266, 0x6a0a, 0xa39d, 0x000a,
-+	0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, 0x126a,
-+	0x77c4, 0x1078, 0x18b9, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091,
-+	0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x126a,
-+	0x70c4, 0x794c, 0x784e, 0x0078, 0x126c, 0x71c4, 0x72c8, 0x73cc,
-+	0xa182, 0x0010, 0x00c8, 0x1265, 0x1078, 0x21cb, 0x0078, 0x126a,
-+	0x77c4, 0x1078, 0x18b9, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002,
-+	0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x126b, 0x77c4, 0x1078,
-+	0x18b9, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804,
-+	0xa005, 0x0040, 0x14ed, 0x1078, 0x20a0, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x126b, 0x77c4, 0x1078, 0x18b9, 0x2091, 0x8000, 0x6a08,
-+	0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1501, 0x1078,
-+	0x20a0, 0x2091, 0x8001, 0x2708, 0x0078, 0x126b, 0x77c4, 0x2041,
-+	0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-+	0x18c6, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x126b, 0x77c4,
-+	0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, 0x1927, 0x00c0,
-+	0x152f, 0x6818, 0xa005, 0x0040, 0x152f, 0x2708, 0x1078, 0x21db,
-+	0x00c0, 0x152f, 0x7817, 0x0015, 0x2091, 0x8001, 0x007c, 0x2091,
-+	0x8001, 0x0078, 0x126d, 0x77c4, 0x77c6, 0x2041, 0x0021, 0x2049,
-+	0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x18c6, 0x2061,
-+	0x4d40, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, 0x6073, 0x0000,
-+	0x7817, 0x0016, 0x1078, 0x20a0, 0x2091, 0x8001, 0x007c, 0x77c8,
-+	0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
-+	0x4d40, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, 0x6093, 0x000f,
-+	0x7817, 0x0017, 0x1078, 0x20a0, 0x2091, 0x8001, 0x2041, 0x0021,
-+	0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x18c6,
-+	0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, 0x156e, 0x2091,
-+	0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, 0x159e, 0x2039,
-+	0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
-+	0x18b9, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001,
-+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1587, 0xa7bc, 0xff00, 0x873f,
-+	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1587, 0x2091, 0x8000,
-+	0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040, 0x15c7, 0x684b,
-+	0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x15b4,
-+	0x0070, 0x15b4, 0x0078, 0x15ab, 0x684b, 0x0009, 0x20a9, 0x0014,
-+	0x6848, 0xa084, 0x0001, 0x0040, 0x15c1, 0x0070, 0x15c1, 0x0078,
-+	0x15b8, 0x20a9, 0x00fa, 0x0070, 0x15c7, 0x0078, 0x15c3, 0x2079,
-+	0x4d00, 0x7817, 0x0018, 0x2061, 0x4d40, 0x606f, 0x0001, 0x6073,
-+	0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002, 0x78ce, 0x6808,
-+	0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091, 0x8001, 0x007c,
-+	0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001, 0x00c0, 0x15ea,
-+	0x1078, 0x1971, 0x71c4, 0x71c6, 0x794a, 0x007c, 0x2029, 0x0000,
-+	0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079,
-+	0x4d00, 0x1078, 0x1874, 0x0040, 0x169e, 0x20a9, 0x0005, 0x20a1,
-+	0x4d18, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020,
-+	0x1078, 0x186f, 0x0040, 0x1610, 0x1078, 0x188e, 0x0078, 0x169e,
-+	0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x166d, 0x0c7e,
-+	0x2c68, 0x1078, 0x1874, 0x0040, 0x163e, 0x2c00, 0x689e, 0x8109,
-+	0x00c0, 0x1618, 0x609f, 0x0000, 0x0c7f, 0x0c7e, 0x7218, 0x731c,
-+	0x2c68, 0x689c, 0xa065, 0x0040, 0x166c, 0x2009, 0x0020, 0x1078,
-+	0x186f, 0x00c0, 0x1655, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002,
-+	0x00c0, 0x163e, 0x2d00, 0x6002, 0x0078, 0x1626, 0x0c7f, 0x0c7e,
-+	0x609c, 0x2060, 0x1078, 0x18f9, 0x0c7f, 0x609f, 0x0000, 0x1078,
-+	0x16a2, 0x2009, 0x000e, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078,
-+	0x186a, 0x1078, 0x188e, 0x0078, 0x169e, 0x0c7f, 0x0c7e, 0x609c,
-+	0x2060, 0x1078, 0x18f9, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x16a2,
-+	0x2009, 0x000e, 0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x186a,
-+	0x1078, 0x188e, 0x0078, 0x169e, 0x0c7f, 0x74c4, 0x73c8, 0x72cc,
-+	0x6014, 0x2091, 0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x4d40,
-+	0x706f, 0x0005, 0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082,
-+	0x7087, 0x0000, 0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530,
-+	0x611c, 0x61a2, 0xa184, 0x0060, 0x0040, 0x1690, 0x1078, 0x4367,
-+	0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3,
-+	0x0000, 0x1078, 0x20a0, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005,
-+	0x0078, 0x1270, 0x20a9, 0x0005, 0x2099, 0x4d18, 0x2091, 0x8000,
-+	0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1,
-+	0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906,
-+	0x0078, 0x126d, 0x71c4, 0x71c6, 0x2168, 0x0078, 0x16c1, 0x2069,
-+	0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0,
-+	0x16c3, 0xa285, 0x0000, 0x00c0, 0x16d1, 0x70c3, 0x4000, 0x0078,
-+	0x16d3, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x1270, 0x2011, 0x4d67,
-+	0x220c, 0x70c4, 0x8003, 0x0048, 0x16e3, 0x1078, 0x398d, 0xa184,
-+	0x7fff, 0x0078, 0x16e7, 0x1078, 0x3980, 0xa185, 0x8000, 0x2012,
-+	0x0078, 0x126c, 0x71c4, 0x1078, 0x3977, 0x6100, 0x2001, 0x4d67,
-+	0x2004, 0xa084, 0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x126a,
-+	0x79e4, 0x0078, 0x126c, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042,
-+	0x20a9, 0x0004, 0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004,
-+	0x53a3, 0x0078, 0x126d, 0x70c4, 0x2068, 0x2079, 0x4d00, 0x1078,
-+	0x1874, 0x0040, 0x1793, 0x6007, 0x0001, 0x600b, 0x0000, 0x602b,
-+	0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f, 0xa284, 0x00f0,
-+	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, 0xa284, 0x0800,
-+	0x0040, 0x172e, 0x601b, 0x000a, 0x0078, 0x1734, 0xa284, 0x1000,
-+	0x0040, 0x1734, 0x601b, 0x000c, 0xa284, 0x0300, 0x0040, 0x173d,
-+	0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, 0x0001, 0x601e,
-+	0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400, 0x0040, 0x174a,
-+	0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, 0x20a0, 0xad80,
-+	0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, 0x175f, 0x604a,
-+	0x6046, 0x6052, 0x604e, 0x6096, 0x609a, 0x0078, 0x1769, 0x6800,
-+	0x604a, 0x6804, 0x6046, 0x6e08, 0x6652, 0x6d0c, 0x654e, 0x6596,
-+	0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042, 0x2c08, 0x2061,
-+	0x4d40, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077, 0x0000, 0x607b,
-+	0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284, 0x0400, 0x608e,
-+	0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007,
-+	0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000, 0x1078, 0x20a0,
-+	0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1270, 0x0c7e,
-+	0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, 0x4d40, 0x2079,
-+	0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, 0x1818, 0x6a04,
-+	0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x17b2, 0xa286, 0x000f,
-+	0x00c0, 0x1818, 0x6920, 0xa184, 0x0080, 0x00c0, 0x1818, 0x6824,
-+	0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b8, 0x81ff, 0x0040,
-+	0x17d3, 0x0d7e, 0x2069, 0x0020, 0x6908, 0x6808, 0xa106, 0x00c0,
-+	0x17c4, 0x690c, 0x680c, 0xa106, 0x00c0, 0x17c9, 0xa184, 0x00ff,
-+	0x00c0, 0x17c9, 0x0d7f, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x17d3,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x71b8, 0x81ff, 0x0040, 0x17f6,
-+	0x70bb, 0x0000, 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0008, 0x6804,
-+	0xa084, 0x0008, 0x00c0, 0x17e7, 0x6807, 0x0008, 0x6804, 0xa084,
-+	0x0008, 0x00c0, 0x17ee, 0x6807, 0x0002, 0x0d7f, 0x61c4, 0x62c8,
-+	0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x0e7e, 0x2071, 0x4d00, 0x7266,
-+	0x736a, 0xae80, 0x0019, 0x0e7f, 0x1078, 0x42b7, 0x78a3, 0x0000,
-+	0x7858, 0xa084, 0xedff, 0x785a, 0x70bc, 0xa080, 0x00da, 0x781a,
-+	0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x0078, 0x126d,
-+	0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x2001, 0x4005,
-+	0x0078, 0x126f, 0x7980, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8,
-+	0x1265, 0x7982, 0x0078, 0x126d, 0x7980, 0x71c6, 0x0078, 0x126d,
-+	0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca, 0x71c8, 0x797a,
-+	0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x126d, 0x7974, 0x71c6,
-+	0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x126d, 0x7900, 0x71c6,
-+	0x71c4, 0x7902, 0x00a8, 0x1856, 0xa18c, 0x0001, 0x00c0, 0x1854,
-+	0x20b9, 0x2222, 0x0078, 0x1856, 0x20b9, 0x1212, 0x0078, 0x126d,
-+	0x7900, 0x71c6, 0x0078, 0x126d, 0x2009, 0x4d74, 0x2104, 0x70c6,
-+	0x70c4, 0x200a, 0x0078, 0x126d, 0x2009, 0x4d74, 0x2104, 0x70c6,
-+	0x0078, 0x126d, 0xac80, 0x0001, 0x1078, 0x1a3d, 0x007c, 0xac80,
-+	0x0001, 0x1078, 0x19f1, 0x007c, 0x7850, 0xa065, 0x0040, 0x187c,
-+	0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4d00,
-+	0x7850, 0xa06d, 0x0040, 0x188c, 0x2d04, 0x7852, 0x6803, 0x0000,
-+	0x6807, 0x0000, 0x680b, 0x0000, 0x0f7f, 0x007c, 0x2091, 0x8000,
-+	0x0f7e, 0x2079, 0x4d00, 0x7850, 0x2062, 0x2c00, 0xa005, 0x00c0,
-+	0x189b, 0x1078, 0x22ac, 0x7852, 0x0f7f, 0x2091, 0x8001, 0x007c,
-+	0x0f7e, 0x2079, 0x4d00, 0x7850, 0x206a, 0x2d00, 0x7852, 0x0f7f,
-+	0x007c, 0x2011, 0x7400, 0x7a52, 0x7bec, 0x8319, 0x0040, 0x18b6,
-+	0xa280, 0x0031, 0x2012, 0x2010, 0x0078, 0x18ad, 0x2013, 0x0000,
-+	0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003,
-+	0x8003, 0x8003, 0xa105, 0xa0e8, 0x5000, 0x007c, 0x1078, 0x18b9,
-+	0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xffef, 0xa80d,
-+	0x690a, 0x2009, 0x4d52, 0x210c, 0x6804, 0xa005, 0x0040, 0x18f8,
-+	0xa116, 0x00c0, 0x18e3, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b,
-+	0x0000, 0x0078, 0x18e6, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065,
-+	0x0040, 0x18f5, 0x6000, 0x6806, 0x1078, 0x1906, 0x1078, 0x1b7d,
-+	0x6810, 0x8001, 0x6812, 0x00c0, 0x18e6, 0x017f, 0x6902, 0x6906,
-+	0x007c, 0xa065, 0x0040, 0x1905, 0x609c, 0x609f, 0x0000, 0x2008,
-+	0x1078, 0x188e, 0x2100, 0x0078, 0x18f9, 0x007c, 0x6007, 0x0103,
-+	0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001,
-+	0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e,
-+	0x2071, 0x4d40, 0x704c, 0xa08c, 0x0200, 0x00c0, 0x1925, 0xa088,
-+	0x4d80, 0x2d0a, 0x8000, 0x704e, 0xa006, 0x0e7f, 0x007c, 0x1078,
-+	0x18b9, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065, 0x0040, 0x1970,
-+	0x0078, 0x1938, 0x2c00, 0x781e, 0x6000, 0xa065, 0x0040, 0x1970,
-+	0x6010, 0xa306, 0x00c0, 0x1932, 0x600c, 0xa206, 0x00c0, 0x1932,
-+	0x2c28, 0x2001, 0x4d52, 0x2004, 0xac06, 0x00c0, 0x1949, 0x0078,
-+	0x196e, 0x6804, 0xac06, 0x00c0, 0x1956, 0x6000, 0xa065, 0x6806,
-+	0x00c0, 0x1960, 0x6803, 0x0000, 0x0078, 0x1960, 0x6400, 0x781c,
-+	0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1960, 0x2c00, 0x6802,
-+	0x2560, 0x1078, 0x1906, 0x601b, 0x0005, 0x6023, 0x0020, 0x1078,
-+	0x1b7d, 0x6810, 0x8001, 0x1050, 0x22ac, 0x6812, 0xa085, 0xffff,
-+	0x007c, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-+	0x0008, 0x2091, 0x8000, 0x1078, 0x18c6, 0x8738, 0xa784, 0x001f,
-+	0x00c0, 0x197b, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784,
-+	0x0f00, 0x00c0, 0x197b, 0x2091, 0x8001, 0x007c, 0x2061, 0x0000,
-+	0x6018, 0xa084, 0x0001, 0x00c0, 0x199f, 0x2091, 0x8000, 0x78e0,
-+	0x78e3, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x19a0, 0x007c,
-+	0xa08c, 0xfff0, 0x0040, 0x19a6, 0x1078, 0x22ac, 0x0079, 0x19a8,
-+	0x19b8, 0x19bb, 0x19c1, 0x19c5, 0x19b9, 0x19c9, 0x19cf, 0x19b9,
-+	0x19b9, 0x1b47, 0x1b6b, 0x1b6f, 0x19b9, 0x19b9, 0x19b9, 0x19b9,
-+	0x007c, 0x1078, 0x22ac, 0x1078, 0x1971, 0x2001, 0x8001, 0x0078,
-+	0x1b75, 0x2001, 0x8003, 0x0078, 0x1b75, 0x2001, 0x8004, 0x0078,
-+	0x1b75, 0x1078, 0x1971, 0x2001, 0x8006, 0x0078, 0x1b75, 0x2001,
-+	0x8007, 0x0078, 0x1b75, 0x2030, 0x2138, 0xa782, 0x0021, 0x0048,
-+	0x19db, 0x2009, 0x0020, 0x2600, 0x1078, 0x19f1, 0x00c0, 0x19f0,
-+	0xa7ba, 0x0020, 0x0048, 0x19ef, 0x0040, 0x19ef, 0x2708, 0xa6b0,
-+	0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0x0078, 0x19d5, 0xa006,
-+	0x007c, 0x81ff, 0x0040, 0x1a1c, 0x2099, 0x0030, 0x20a0, 0x700c,
-+	0xa084, 0x00ff, 0x0040, 0x1a03, 0x7007, 0x0004, 0x7004, 0xa084,
-+	0x0004, 0x00c0, 0x19fe, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112,
-+	0x721a, 0x731e, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001,
-+	0x7008, 0x800c, 0x00c8, 0x1a10, 0x7007, 0x0002, 0xa08c, 0x000c,
-+	0x00c0, 0x1a1c, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030,
-+	0x2138, 0xa782, 0x0021, 0x0048, 0x1a27, 0x2009, 0x0020, 0x2600,
-+	0x1078, 0x1a3d, 0x00c0, 0x1a3c, 0xa7ba, 0x0020, 0x0048, 0x1a3b,
-+	0x0040, 0x1a3b, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399,
-+	0x0000, 0x0078, 0x1a21, 0xa006, 0x007c, 0x81ff, 0x0040, 0x1a6e,
-+	0x2098, 0x20a1, 0x0030, 0x700c, 0xa084, 0x00ff, 0x0040, 0x1a4f,
-+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x1a4a, 0x21a8,
-+	0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e, 0x780c, 0xa085,
-+	0x0000, 0x7002, 0x53a6, 0x7007, 0x0001, 0x7010, 0xa084, 0xf000,
-+	0x0040, 0x1a66, 0x7007, 0x0008, 0x0078, 0x1a6a, 0x7108, 0x8104,
-+	0x00c8, 0x1a5d, 0x7007, 0x0002, 0xa184, 0x000c, 0x7003, 0x0000,
-+	0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0004, 0x00c8, 0x1a7a,
-+	0x0078, 0x1a7d, 0xa006, 0x0078, 0x1a7f, 0xa085, 0x0001, 0x007c,
-+	0x0e7e, 0x2071, 0x4d00, 0x2d08, 0x7058, 0x6802, 0xa005, 0x00c0,
-+	0x1a8a, 0x715e, 0x715a, 0x0e7f, 0x007c, 0x2c08, 0x7858, 0x6002,
-+	0xa005, 0x00c0, 0x1a94, 0x795e, 0x795a, 0x007c, 0x2091, 0x8000,
-+	0x6003, 0x0000, 0x2c08, 0x785c, 0xa065, 0x00c0, 0x1aa2, 0x795a,
-+	0x0078, 0x1aa3, 0x6102, 0x795e, 0x2091, 0x8001, 0x1078, 0x20bd,
-+	0x007c, 0x0e7e, 0x2071, 0x4d00, 0x7058, 0xa06d, 0x0040, 0x1ab7,
-+	0x6800, 0x705a, 0xa005, 0x00c0, 0x1ab6, 0x705e, 0x8dff, 0x0e7f,
-+	0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x4d00, 0xaf80, 0x0016,
-+	0x2060, 0x6000, 0xa005, 0x0040, 0x1ae7, 0x2068, 0x6814, 0xa306,
-+	0x00c0, 0x1ad0, 0x6828, 0xa084, 0x00ff, 0xa406, 0x0040, 0x1ad3,
-+	0x2d60, 0x0078, 0x1ac1, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1adf,
-+	0xaf80, 0x0016, 0xac06, 0x0040, 0x1ade, 0x2c00, 0x785e, 0x0d7e,
-+	0x689c, 0xa005, 0x0040, 0x1ae6, 0x1078, 0x18f9, 0x007f, 0x0f7f,
-+	0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079,
-+	0x4d00, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1b16,
-+	0x2068, 0x6814, 0xa084, 0x00ff, 0xa306, 0x0040, 0x1b02, 0x2d60,
-+	0x0078, 0x1af4, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1b0e, 0xaf80,
-+	0x0016, 0xac06, 0x0040, 0x1b0d, 0x2c00, 0x785e, 0x0d7e, 0x689c,
-+	0xa005, 0x0040, 0x1b15, 0x1078, 0x18f9, 0x007f, 0x0f7f, 0x0c7f,
-+	0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x4d00,
-+	0xaf80, 0x0016, 0x2060, 0x6000, 0xa06d, 0x0040, 0x1b42, 0x6814,
-+	0xa306, 0x0040, 0x1b2e, 0x2d60, 0x0078, 0x1b23, 0x6800, 0xa005,
-+	0x6002, 0x00c0, 0x1b3a, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1b39,
-+	0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1b41, 0x1078,
-+	0x18f9, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091,
-+	0x8000, 0x2069, 0x4d40, 0x6800, 0xa086, 0x0000, 0x0040, 0x1b55,
-+	0x2091, 0x8001, 0x78e3, 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00,
-+	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078, 0x18c6,
-+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1b5e, 0x2091, 0x8001, 0x2001,
-+	0x800a, 0x0078, 0x1b75, 0x2001, 0x800c, 0x0078, 0x1b75, 0x1078,
-+	0x1971, 0x2001, 0x800d, 0x0078, 0x1b75, 0x70c2, 0x2061, 0x0000,
-+	0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063,
-+	0x0000, 0x7884, 0x8000, 0x7886, 0x7888, 0xa005, 0x798a, 0x0040,
-+	0x1b8c, 0x2c02, 0x0078, 0x1b8d, 0x798e, 0x007c, 0x6807, 0x0103,
-+	0x0c7e, 0x2061, 0x4d00, 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000,
-+	0x6086, 0x6088, 0xa005, 0x618a, 0x0040, 0x1ba1, 0x2d02, 0x0078,
-+	0x1ba2, 0x618e, 0x0c7f, 0x007c, 0x1078, 0x1bb5, 0x0040, 0x1bb4,
-+	0x0c7e, 0x609c, 0xa065, 0x0040, 0x1baf, 0x1078, 0x18f9, 0x0c7f,
-+	0x609f, 0x0000, 0x1078, 0x188e, 0x007c, 0x788c, 0xa065, 0x0040,
-+	0x1bc7, 0x2091, 0x8000, 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e,
-+	0xa005, 0x00c0, 0x1bc5, 0x788a, 0x8000, 0x2091, 0x8001, 0x007c,
-+	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x1bd1,
-+	0xa200, 0x0070, 0x1bd5, 0x0078, 0x1bcc, 0x8086, 0x818e, 0x007c,
-+	0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1bfb, 0xa11a, 0x00c8,
-+	0x1bfb, 0x8213, 0x818d, 0x0048, 0x1bec, 0xa11a, 0x00c8, 0x1bed,
-+	0x0070, 0x1bf3, 0x0078, 0x1be1, 0xa11a, 0x2308, 0x8210, 0x0070,
-+	0x1bf3, 0x0078, 0x1be1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080,
-+	0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078,
-+	0x1bf7, 0x7994, 0x70d0, 0xa106, 0x0040, 0x1c6d, 0x2091, 0x8000,
-+	0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1c6d, 0x7008, 0x7208,
-+	0xa206, 0x00c0, 0x1c6d, 0xa286, 0x0002, 0x00c0, 0x1c6d, 0x2071,
-+	0x0010, 0x1078, 0x1874, 0x0040, 0x1c6d, 0x7a9c, 0x7b98, 0xa184,
-+	0xff00, 0x0040, 0x1c3b, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b,
-+	0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
-+	0x86b5, 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9,
-+	0x0000, 0x0078, 0x1c45, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
-+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078,
-+	0x186f, 0x2091, 0x8001, 0x0040, 0x1c64, 0x1078, 0x188e, 0x78a8,
-+	0x8000, 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1c6d, 0x2091, 0x8000,
-+	0x78e3, 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce,
-+	0x2091, 0x8001, 0x0078, 0x1c6d, 0x78ab, 0x0000, 0x1078, 0x1fa1,
-+	0x6004, 0xa084, 0x000f, 0x0079, 0x1c72, 0x2071, 0x0010, 0x2091,
-+	0x8001, 0x007c, 0x1c82, 0x1c91, 0x1cb1, 0x1c82, 0x1cce, 0x1c82,
-+	0x1e29, 0x1e40, 0x1c82, 0x1c82, 0x1c82, 0x1d16, 0x1d7f, 0x1dcf,
-+	0x1de1, 0x1c82, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008,
-+	0xa705, 0x600a, 0x1078, 0x1ebc, 0x609c, 0x78da, 0x1078, 0x1f89,
-+	0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1c98, 0x0078, 0x1c82,
-+	0x78df, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001,
-+	0x609f, 0x0000, 0x0040, 0x1cae, 0x1078, 0x1ebc, 0x0040, 0x1cae,
-+	0x78dc, 0xa085, 0x0100, 0x78de, 0x0078, 0x1cb0, 0x1078, 0x1ee0,
-+	0x007c, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1cba, 0xa084, 0x0100,
-+	0x00c0, 0x1cbc, 0x0078, 0x1c82, 0x1078, 0x1ebc, 0x00c0, 0x1ccd,
-+	0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x1e72, 0xa186,
-+	0x000f, 0x0040, 0x1e72, 0x1078, 0x1ee0, 0x007c, 0x78dc, 0xa084,
-+	0x0100, 0x0040, 0x1cd5, 0x0078, 0x1c82, 0x78df, 0x0000, 0x6714,
-+	0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005,
-+	0x0040, 0x1cf8, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020,
-+	0xa08e, 0x0001, 0x0040, 0x1cf8, 0x2039, 0x0000, 0x2011, 0x0002,
-+	0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1cf8, 0x0078, 0x1d13,
-+	0x1078, 0x18b9, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
-+	0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
-+	0x0070, 0x1d0c, 0x0078, 0x1cfa, 0x8211, 0x0040, 0x1d13, 0x20a9,
-+	0x0100, 0x0078, 0x1cfa, 0x1078, 0x188e, 0x007c, 0x2001, 0x4d67,
-+	0x2004, 0xa084, 0x8000, 0x0040, 0x1ea1, 0x6114, 0x1078, 0x1fb7,
-+	0x6900, 0xa184, 0x0001, 0x0040, 0x1d37, 0x6028, 0xa084, 0x00ff,
-+	0x00c0, 0x1e99, 0x6800, 0xa084, 0x0001, 0x0040, 0x1ea1, 0x6803,
-+	0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x1ea9, 0x2011,
-+	0x0001, 0x601c, 0xa084, 0x4000, 0x0040, 0x1d40, 0xa295, 0x0002,
-+	0x601c, 0xa084, 0x0100, 0x0040, 0x1d47, 0xa295, 0x0008, 0x6020,
-+	0xa084, 0x0002, 0x0040, 0x1d4e, 0xa295, 0x0004, 0x602c, 0xa08c,
-+	0x00ff, 0xa182, 0x0002, 0x0048, 0x1ea5, 0xa182, 0x0019, 0x00c8,
-+	0x1ea5, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff, 0xa182, 0x0002,
-+	0x0048, 0x1ea5, 0xa182, 0x0019, 0x00c8, 0x1ea5, 0x6912, 0x6030,
-+	0xa005, 0x00c0, 0x1d6d, 0x2001, 0x001e, 0x8000, 0x6816, 0x6028,
-+	0xa084, 0x00ff, 0x0040, 0x1ea1, 0x6806, 0x6028, 0x8007, 0xa084,
-+	0x00ff, 0x0040, 0x1ea1, 0x680a, 0x6a02, 0x0078, 0x1ea9, 0x2001,
-+	0x4d67, 0x2004, 0xa084, 0x8000, 0x0040, 0x1ea1, 0x6114, 0x1078,
-+	0x1fb7, 0x2091, 0x8000, 0x6a04, 0x6b08, 0x6418, 0xa484, 0x0003,
-+	0x0040, 0x1da5, 0x6128, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x1d9e,
-+	0x2100, 0xa210, 0x0048, 0x1dcb, 0x0078, 0x1da5, 0x8001, 0x00c0,
-+	0x1dcb, 0x2100, 0xa212, 0x0048, 0x1dcb, 0xa484, 0x000c, 0x0040,
-+	0x1dbf, 0x6128, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
-+	0x1db7, 0x2100, 0xa318, 0x0048, 0x1dcb, 0x0078, 0x1dbf, 0xa082,
-+	0x0004, 0x00c0, 0x1dcb, 0x2100, 0xa31a, 0x0048, 0x1dcb, 0x6030,
-+	0xa005, 0x0040, 0x1dc5, 0x8000, 0x6816, 0x6a06, 0x6b0a, 0x2091,
-+	0x8001, 0x0078, 0x1ea9, 0x2091, 0x8001, 0x0078, 0x1ea5, 0x6114,
-+	0x1078, 0x1fb7, 0x2091, 0x8000, 0x6b08, 0x8318, 0x0048, 0x1ddd,
-+	0x6b0a, 0x2091, 0x8001, 0x0078, 0x1eb8, 0x2091, 0x8001, 0x0078,
-+	0x1ea5, 0x6024, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1dff, 0xa086,
-+	0x0080, 0x00c0, 0x1e27, 0x20a9, 0x0008, 0x2069, 0x7110, 0x2091,
-+	0x8000, 0x6800, 0xa084, 0xfcff, 0x6802, 0xade8, 0x0008, 0x0070,
-+	0x1dfb, 0x0078, 0x1df1, 0x2091, 0x8001, 0x0078, 0x1ea9, 0x6028,
-+	0xa015, 0x0040, 0x1e27, 0x6114, 0x1078, 0x1fb7, 0x0d7e, 0xade8,
-+	0x0007, 0x2091, 0x8000, 0x6800, 0xa00d, 0x0040, 0x1e24, 0xa206,
-+	0x0040, 0x1e15, 0x2168, 0x0078, 0x1e0b, 0x0c7e, 0x2160, 0x6000,
-+	0x6802, 0x1078, 0x188e, 0x0c7f, 0x0d7f, 0x6808, 0x8000, 0x680a,
-+	0x2091, 0x8001, 0x0078, 0x1eb8, 0x2091, 0x8001, 0x0d7f, 0x0078,
-+	0x1ea1, 0x6114, 0x1078, 0x1fb7, 0x6800, 0xa084, 0x0001, 0x0040,
-+	0x1e91, 0x2091, 0x8000, 0x6a04, 0x8210, 0x0048, 0x1e3c, 0x6a06,
-+	0x2091, 0x8001, 0x0078, 0x1eb8, 0x2091, 0x8001, 0x0078, 0x1ea5,
-+	0x6114, 0x1078, 0x1fb7, 0x60be, 0x6900, 0xa184, 0x0008, 0x0040,
-+	0x1e4d, 0x601c, 0xa085, 0x0100, 0x601e, 0xa184, 0x0001, 0x0040,
-+	0x1ea1, 0xa184, 0x0100, 0x00c0, 0x1e8d, 0xa184, 0x0200, 0x00c0,
-+	0x1e89, 0x681c, 0xa005, 0x00c0, 0x1e95, 0x78df, 0x0000, 0x6004,
-+	0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040,
-+	0x1e72, 0x1078, 0x1ebc, 0x0040, 0x1e72, 0x78dc, 0xa085, 0x0100,
-+	0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024, 0xa084,
-+	0xff00, 0x6026, 0x6020, 0xa084, 0x8000, 0x0040, 0x1e85, 0x1078,
-+	0x37e7, 0x0040, 0x1c01, 0x0078, 0x1e91, 0x1078, 0x1a96, 0x0078,
-+	0x1c01, 0x2009, 0x0017, 0x0078, 0x1eab, 0x2009, 0x000e, 0x0078,
-+	0x1eab, 0x2009, 0x0007, 0x0078, 0x1eab, 0x2009, 0x0035, 0x0078,
-+	0x1eab, 0x2009, 0x003e, 0x0078, 0x1eab, 0x2009, 0x0004, 0x0078,
-+	0x1eab, 0x2009, 0x0006, 0x0078, 0x1eab, 0x2009, 0x0016, 0x0078,
-+	0x1eab, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, 0xa105, 0x6026,
-+	0x2091, 0x8000, 0x1078, 0x1b7d, 0x2091, 0x8001, 0x0078, 0x1c01,
-+	0x1078, 0x188e, 0x0078, 0x1c01, 0x78d4, 0xa06d, 0x00c0, 0x1ec7,
-+	0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078, 0x1ed3, 0x2c00,
-+	0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002, 0x78d8, 0xad06,
-+	0x00c0, 0x1ed3, 0x6002, 0x78d0, 0x8001, 0x78d2, 0x00c0, 0x1edf,
-+	0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060, 0xa006, 0x007c,
-+	0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff, 0x601e, 0xa184,
-+	0x0060, 0x0040, 0x1eef, 0x0e7e, 0x1078, 0x4367, 0x0e7f, 0x6596,
-+	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714,
-+	0x1078, 0x18b9, 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x00c0,
-+	0x1f16, 0x6808, 0xa084, 0x0001, 0x0040, 0x1f16, 0x2091, 0x8001,
-+	0x1078, 0x1906, 0x2091, 0x8000, 0x1078, 0x1b7d, 0x2091, 0x8001,
-+	0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x1f88, 0x6024, 0xa096,
-+	0x0001, 0x00c0, 0x1f1d, 0x8000, 0x6026, 0x6a10, 0x6814, 0x2091,
-+	0x8001, 0xa202, 0x0048, 0x1f2c, 0x0040, 0x1f2c, 0x2039, 0x0200,
-+	0x1078, 0x1f89, 0x0078, 0x1f88, 0x2c08, 0x2091, 0x8000, 0x60a0,
-+	0xa084, 0x8000, 0x0040, 0x1f59, 0x6800, 0xa065, 0x0040, 0x1f5e,
-+	0x6a04, 0x0e7e, 0x2071, 0x4d40, 0x7000, 0xa084, 0x0001, 0x0040,
-+	0x1f53, 0x7048, 0xa206, 0x00c0, 0x1f53, 0x6b04, 0x231c, 0x2160,
-+	0x6302, 0x2300, 0xa005, 0x00c0, 0x1f4e, 0x6902, 0x2260, 0x6102,
-+	0x0e7f, 0x0078, 0x1f65, 0x2160, 0x6202, 0x6906, 0x0e7f, 0x0078,
-+	0x1f65, 0x6800, 0xa065, 0x0040, 0x1f5e, 0x6102, 0x6902, 0x00c0,
-+	0x1f62, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0x60a0, 0xa084,
-+	0x8000, 0x0040, 0x1f6f, 0x6808, 0xa084, 0xfffc, 0x680a, 0x6810,
-+	0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040,
-+	0x1f7e, 0xa086, 0x0040, 0x680a, 0x1078, 0x1917, 0x2091, 0x8000,
-+	0x1078, 0x20a0, 0x2091, 0x8001, 0x78db, 0x0000, 0x78d7, 0x0000,
-+	0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x1b7d,
-+	0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x1f9c, 0x609c, 0x78da,
-+	0x609f, 0x0000, 0x0078, 0x1f8c, 0x78d7, 0x0000, 0x78db, 0x0000,
-+	0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x1fa8, 0xa006,
-+	0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x1fb6, 0x8001, 0x7806,
-+	0x00c0, 0x1fb6, 0x0068, 0x1fb6, 0x2091, 0x4080, 0x007c, 0x0c7e,
-+	0x1078, 0x3977, 0x2c68, 0x0c7f, 0x007c, 0x0010, 0x202e, 0x0068,
-+	0x202e, 0x2029, 0x0000, 0x78cb, 0x0000, 0x788c, 0xa065, 0x0040,
-+	0x2027, 0x2009, 0x4d74, 0x2104, 0xa084, 0x0001, 0x0040, 0x1ff5,
-+	0x6004, 0xa086, 0x0103, 0x00c0, 0x1ff5, 0x6018, 0xa005, 0x00c0,
-+	0x1ff5, 0x6014, 0xa005, 0x00c0, 0x1ff5, 0x0d7e, 0x2069, 0x0000,
-+	0x6818, 0xa084, 0x0001, 0x00c0, 0x1ff4, 0x6010, 0x70c6, 0x600c,
-+	0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x0d7f,
-+	0x1078, 0x1ba4, 0x0078, 0x202c, 0x0d7f, 0x1078, 0x202f, 0x0040,
-+	0x2027, 0x6204, 0xa294, 0x00ff, 0xa296, 0x0003, 0x0040, 0x2007,
-+	0x6204, 0xa296, 0x0110, 0x00c0, 0x2015, 0x78cb, 0x0001, 0x6204,
-+	0xa294, 0xff00, 0x8217, 0x8211, 0x0040, 0x2015, 0x85ff, 0x00c0,
-+	0x2027, 0x8210, 0xa202, 0x00c8, 0x2027, 0x057e, 0x1078, 0x203e,
-+	0x057f, 0x0040, 0x2022, 0x78e0, 0xa086, 0x0003, 0x0040, 0x2027,
-+	0x0078, 0x2015, 0x8528, 0x78c8, 0xa005, 0x0040, 0x1fc5, 0x85ff,
-+	0x0040, 0x202e, 0x2091, 0x4080, 0x78b0, 0x70d6, 0x007c, 0x7bac,
-+	0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2038, 0x2300, 0xa005, 0x007c,
-+	0x0048, 0x203c, 0xa302, 0x007c, 0x8002, 0x007c, 0x2001, 0x04fd,
-+	0x2004, 0xa082, 0x0005, 0x00c8, 0x2058, 0x2091, 0x8000, 0x2071,
-+	0x0020, 0x7004, 0xa005, 0x00c0, 0x208d, 0x7008, 0x7208, 0xa206,
-+	0x00c0, 0x208d, 0xa286, 0x0002, 0x00c0, 0x208d, 0x2071, 0x0010,
-+	0x1078, 0x2092, 0x2009, 0x0020, 0x6004, 0xa086, 0x0103, 0x00c0,
-+	0x2067, 0x6028, 0xa005, 0x00c0, 0x2067, 0x2009, 0x000e, 0x1078,
-+	0x186a, 0x0040, 0x2080, 0x78c4, 0x8000, 0x78c6, 0xa086, 0x0002,
-+	0x00c0, 0x208d, 0x2091, 0x8000, 0x78e3, 0x0003, 0x78c7, 0x0000,
-+	0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091, 0x8001, 0x0078, 0x208d,
-+	0x78c7, 0x0000, 0x1078, 0x1ba4, 0x79ac, 0x78b0, 0x8000, 0xa10a,
-+	0x00c8, 0x208b, 0xa006, 0x78b2, 0xa006, 0x2071, 0x0010, 0x2091,
-+	0x8001, 0x007c, 0x8107, 0x8004, 0x8004, 0x7ab8, 0x7bb4, 0xa210,
-+	0xa399, 0x0000, 0x007c, 0x2009, 0x4d5b, 0x2091, 0x8000, 0x200a,
-+	0x0f7e, 0x0e7e, 0x2071, 0x4d40, 0x7000, 0xa086, 0x0000, 0x00c0,
-+	0x20ba, 0x2009, 0x4d12, 0x2104, 0xa005, 0x00c0, 0x20ba, 0x2079,
-+	0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x20ba, 0x0018, 0x20ba,
-+	0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x2071,
-+	0x4d40, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, 0x20d3,
-+	0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x20d3, 0x0018,
-+	0x20d3, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, 0x007c,
-+	0x127e, 0x2091, 0x2300, 0x2071, 0x4d40, 0x2079, 0x0100, 0x784b,
-+	0x000f, 0x0098, 0x20e6, 0x7838, 0x0078, 0x20df, 0x20a9, 0x0040,
-+	0x7800, 0xa082, 0x0004, 0x0048, 0x20ef, 0x20a9, 0x0060, 0x789b,
-+	0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x20f9, 0x0078,
-+	0x20f1, 0x7800, 0xa082, 0x0004, 0x0048, 0x2108, 0x70bf, 0x009f,
-+	0x2019, 0x4ab1, 0x1078, 0x2137, 0x702f, 0x8001, 0x0078, 0x2114,
-+	0x70bf, 0x0000, 0x2019, 0x4916, 0x1078, 0x2137, 0x2019, 0x4955,
-+	0x1078, 0x2137, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078, 0x2240,
-+	0x7004, 0xa084, 0x000f, 0x017e, 0x0028, 0x2122, 0xa085, 0x6280,
-+	0x0078, 0x2124, 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204,
-+	0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008,
-+	0x7053, 0x4d7f, 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e,
-+	0x147e, 0x157e, 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a,
-+	0x0040, 0x2157, 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484,
-+	0xff00, 0x0040, 0x214f, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020,
-+	0x53a6, 0xa005, 0x00c0, 0x2146, 0x3318, 0x0078, 0x213d, 0x047f,
-+	0x157f, 0x147f, 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101,
-+	0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x2240, 0x007c,
-+	0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x2171, 0x0078,
-+	0x216c, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012,
-+	0x007c, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x2182,
-+	0x0078, 0x217d, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
-+	0x200a, 0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070,
-+	0x2193, 0x0078, 0x218e, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff,
-+	0xa105, 0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf,
-+	0xa105, 0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e,
-+	0x2061, 0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103,
-+	0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
-+	0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080,
-+	0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020,
-+	0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e,
-+	0x2061, 0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae,
-+	0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818,
-+	0xa005, 0x0040, 0x221e, 0x2061, 0x7100, 0x1078, 0x2226, 0x0040,
-+	0x220a, 0x20a9, 0x0000, 0x2061, 0x7000, 0x0c7e, 0x1078, 0x2226,
-+	0x0040, 0x21fa, 0x0c7f, 0x8c60, 0x0070, 0x21f8, 0x0078, 0x21ed,
-+	0x0078, 0x221e, 0x007f, 0xa082, 0x7000, 0x2071, 0x4d40, 0x7086,
-+	0x7182, 0x2001, 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x209b,
-+	0x0078, 0x221a, 0x60c0, 0xa005, 0x00c0, 0x221e, 0x2071, 0x4d40,
-+	0x7182, 0x2c00, 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f,
-+	0x1078, 0x209b, 0x2001, 0x0000, 0x0078, 0x2220, 0x2001, 0x0001,
-+	0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005,
-+	0x0040, 0x223d, 0x2060, 0x6010, 0xa306, 0x00c0, 0x223a, 0x600c,
-+	0xa206, 0x00c0, 0x223a, 0x6014, 0xa106, 0x00c0, 0x223a, 0xa006,
-+	0x0078, 0x223f, 0x6000, 0x0078, 0x2227, 0xa085, 0x0001, 0x007c,
-+	0x2011, 0x4d41, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204,
-+	0xa084, 0x0100, 0x0040, 0x2256, 0x2021, 0xff04, 0x2122, 0x810b,
-+	0x810b, 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e,
-+	0x68e4, 0xa08c, 0x0020, 0x0040, 0x22aa, 0xa084, 0x0006, 0x00c0,
-+	0x22aa, 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa0f0, 0x4f80, 0x7004, 0xa084, 0x000a, 0x00c0, 0x22aa, 0x7108,
-+	0xa194, 0xff00, 0x0040, 0x22aa, 0xa18c, 0x00ff, 0x2001, 0x000c,
-+	0xa106, 0x0040, 0x2291, 0x2001, 0x0012, 0xa106, 0x0040, 0x2295,
-+	0x2001, 0x0014, 0xa106, 0x0040, 0x2299, 0x2001, 0x0019, 0xa106,
-+	0x0040, 0x229d, 0x2001, 0x0032, 0xa106, 0x0040, 0x22a1, 0x0078,
-+	0x22a5, 0x2009, 0x0012, 0x0078, 0x22a7, 0x2009, 0x0014, 0x0078,
-+	0x22a7, 0x2009, 0x0019, 0x0078, 0x22a7, 0x2009, 0x0020, 0x0078,
-+	0x22a7, 0x2009, 0x003f, 0x0078, 0x22a7, 0x2011, 0x0000, 0x2100,
-+	0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x22ac, 0x2091, 0x8000,
-+	0x2071, 0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x22b3,
-+	0x007f, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
-+	0x70db, 0x0737, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001,
-+	0x2091, 0x4080, 0x0078, 0x22ca, 0x107e, 0x007e, 0x127e, 0x2091,
-+	0x2300, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca,
-+	0x75ce, 0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079,
-+	0x22e1, 0x22f3, 0x22f3, 0x22f3, 0x2624, 0x3741, 0x22f1, 0x2322,
-+	0x232c, 0x22f1, 0x22f1, 0x22f1, 0x22f1, 0x22f1, 0x22f1, 0x22f1,
-+	0x22f1, 0x1078, 0x22ac, 0x8507, 0xa084, 0x001f, 0x0079, 0x22f8,
-+	0x2336, 0x2624, 0x27d8, 0x28d5, 0x28fd, 0x2b6d, 0x2e18, 0x2e5b,
-+	0x2ea6, 0x2f2b, 0x2fb1, 0x3056, 0x2322, 0x26fc, 0x2ded, 0x2318,
-+	0x3a92, 0x3ab2, 0x3be5, 0x3bf1, 0x3ca2, 0x2318, 0x2318, 0x3d53,
-+	0x3d57, 0x3a90, 0x2318, 0x3b8c, 0x2318, 0x399a, 0x232c, 0x2318,
-+	0x1078, 0x22ac, 0x0018, 0x22d1, 0x127f, 0x2091, 0x8001, 0x007f,
-+	0x107f, 0x007c, 0x2019, 0x4a07, 0x1078, 0x2137, 0x702f, 0x0001,
-+	0x781b, 0x004f, 0x0078, 0x231a, 0x2019, 0x4955, 0x1078, 0x2137,
-+	0x702f, 0x8000, 0x781b, 0x00e1, 0x0078, 0x231a, 0x7242, 0x2009,
-+	0x4d0f, 0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x39a6, 0x0040,
-+	0x2353, 0x1078, 0x22ac, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043,
-+	0x0000, 0x7037, 0x0000, 0x1078, 0x371d, 0x0018, 0x22d1, 0x2009,
-+	0x4d0f, 0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x2426, 0x706c,
-+	0xa084, 0x0007, 0x0079, 0x235c, 0x245d, 0x2364, 0x2370, 0x238f,
-+	0x23b3, 0x2404, 0x23db, 0x2364, 0x1078, 0x3705, 0x2009, 0x0048,
-+	0x1078, 0x2cc3, 0x00c0, 0x236e, 0x7003, 0x0004, 0x0078, 0x231a,
-+	0x1078, 0x3705, 0x00c0, 0x238d, 0x7080, 0x8007, 0x789b, 0x0080,
-+	0x78aa, 0x789b, 0x0010, 0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab,
-+	0x0001, 0x785b, 0x0004, 0x2009, 0x00f2, 0x1078, 0x2cb7, 0x00c0,
-+	0x238d, 0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x231a, 0x1078,
-+	0x3705, 0x00c0, 0x23b1, 0x7180, 0x8107, 0x789b, 0x0080, 0x78aa,
-+	0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab,
-+	0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009,
-+	0x00f2, 0x1078, 0x2cb7, 0x00c0, 0x23b1, 0x7003, 0x0004, 0x7093,
-+	0x000f, 0x0078, 0x231a, 0x1078, 0x3705, 0x00c0, 0x23d9, 0x7180,
-+	0x8107, 0x789b, 0x0080, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x001f,
-+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa, 0x78ab,
-+	0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009,
-+	0x00f2, 0x1078, 0x2cb7, 0x00c0, 0x23d9, 0x7003, 0x0004, 0x7093,
-+	0x000f, 0x0078, 0x231a, 0x1078, 0x3705, 0x00c0, 0x2402, 0x7180,
-+	0x8107, 0x789b, 0x0080, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x001f,
-+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
-+	0x0002, 0x785b, 0x0004, 0x2009, 0x00f2, 0x1078, 0x2cb7, 0x00c0,
-+	0x2402, 0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002,
-+	0x7093, 0x000f, 0x0078, 0x231a, 0x1078, 0x3705, 0x00c0, 0x231a,
-+	0x7088, 0x2068, 0x6f14, 0x1078, 0x35fc, 0x2c50, 0x1078, 0x37b5,
-+	0x789b, 0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa,
-+	0x6e1c, 0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004,
-+	0x0040, 0x2424, 0x2001, 0x0006, 0x0078, 0x2545, 0x1078, 0x3705,
-+	0x00c0, 0x231a, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078,
-+	0x35fc, 0x2c50, 0x1078, 0x37b5, 0x6008, 0xa085, 0x0010, 0x600a,
-+	0x6824, 0xa005, 0x0040, 0x2444, 0xa082, 0x0006, 0x0048, 0x2442,
-+	0x0078, 0x2444, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d,
-+	0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x2452, 0xa684, 0x0001,
-+	0x0040, 0x2454, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041,
-+	0x0001, 0x2001, 0x0003, 0x0078, 0x2545, 0x0018, 0x22d1, 0x744c,
-+	0xa485, 0x0000, 0x0040, 0x2477, 0xa080, 0x4d80, 0x2030, 0x7150,
-+	0x8108, 0xa12a, 0x0048, 0x246e, 0x2009, 0x4d80, 0x2164, 0x6504,
-+	0x85ff, 0x00c0, 0x2488, 0x8421, 0x00c0, 0x2468, 0x7152, 0x7003,
-+	0x0000, 0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x39a6, 0x0078,
-+	0x231a, 0x764c, 0xa6b0, 0x4d80, 0x7150, 0x2600, 0x0078, 0x2473,
-+	0x7152, 0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000,
-+	0x00c0, 0x2485, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x24be,
-+	0xa784, 0x0021, 0x00c0, 0x2485, 0xa784, 0x0002, 0x0040, 0x24a7,
-+	0xa784, 0x0004, 0x0040, 0x2485, 0xa7bc, 0xfffb, 0x670a, 0xa784,
-+	0x0008, 0x00c0, 0x2485, 0xa784, 0x0010, 0x00c0, 0x2485, 0xa784,
-+	0x0200, 0x00c0, 0x2485, 0xa784, 0x0100, 0x0040, 0x24be, 0x6018,
-+	0xa005, 0x00c0, 0x2485, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000,
-+	0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040, 0x24ce, 0x601c, 0xa102,
-+	0x0048, 0x24d1, 0x0040, 0x24d1, 0x0078, 0x2481, 0x81ff, 0x00c0,
-+	0x2481, 0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x24d9, 0x700c,
-+	0x6022, 0xa7bc, 0xff7f, 0x670a, 0x1078, 0x37b5, 0x0018, 0x22d1,
-+	0x789b, 0x0010, 0xa046, 0x1078, 0x3705, 0x00c0, 0x231a, 0x6b14,
-+	0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040,
-+	0x24f5, 0xa684, 0x0001, 0x0040, 0x24f7, 0xa39c, 0xffbf, 0xa684,
-+	0x0010, 0x0040, 0x24fd, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684,
-+	0x000e, 0x00c0, 0x2508, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x2543,
-+	0x7158, 0xa18c, 0x0800, 0x0040, 0x322a, 0x2011, 0x0020, 0xa684,
-+	0x0008, 0x00c0, 0x2519, 0x8210, 0xa684, 0x0002, 0x00c0, 0x2519,
-+	0x8210, 0x7aaa, 0x8840, 0x1078, 0x371d, 0x6a14, 0x610c, 0x8108,
-+	0xa18c, 0x00ff, 0xa1e0, 0x7000, 0x2c64, 0x8cff, 0x0040, 0x253a,
-+	0x6014, 0xa206, 0x00c0, 0x2524, 0x60b8, 0x8001, 0x60ba, 0x00c0,
-+	0x251f, 0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f,
-+	0x0078, 0x245d, 0x1078, 0x3705, 0x00c0, 0x231a, 0x2a60, 0x610e,
-+	0x79aa, 0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184,
-+	0x0018, 0x0040, 0x2560, 0xa184, 0x0010, 0x0040, 0x2553, 0x1078,
-+	0x3429, 0x00c0, 0x2583, 0xa184, 0x0008, 0x0040, 0x2560, 0x69a0,
-+	0xa184, 0x0600, 0x00c0, 0x2560, 0x1078, 0x331a, 0x0078, 0x2583,
-+	0x69a0, 0xa184, 0x0800, 0x0040, 0x2577, 0x0c7e, 0x027e, 0x2960,
-+	0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106,
-+	0x027f, 0x0c7f, 0x1078, 0x3429, 0x00c0, 0x2583, 0x69a0, 0xa184,
-+	0x0200, 0x0040, 0x257f, 0x1078, 0x3369, 0x0078, 0x2583, 0xa184,
-+	0x0400, 0x00c0, 0x255c, 0x69a0, 0xa184, 0x1000, 0x0040, 0x258e,
-+	0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x21af, 0x007f, 0x7002,
-+	0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x259c, 0xa086, 0x0060,
-+	0x00c0, 0x259c, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x25a1, 0xa18d,
-+	0x0004, 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b,
-+	0x0061, 0x6818, 0xa085, 0x8000, 0x681a, 0x78aa, 0x8008, 0x810c,
-+	0x0040, 0x3230, 0xa18c, 0x00f8, 0x00c0, 0x3230, 0x157e, 0x137e,
-+	0x147e, 0x20a1, 0x012c, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-+	0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0x8007,
-+	0x789b, 0x0080, 0x78aa, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2,
-+	0x7eda, 0x1078, 0x3705, 0x00c0, 0x25e6, 0x702c, 0x8003, 0x0048,
-+	0x25df, 0x2019, 0x4955, 0x1078, 0x2137, 0x702f, 0x8000, 0x7830,
-+	0xa084, 0x00c0, 0x00c0, 0x25e6, 0x0098, 0x25ee, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x1078, 0x371d, 0x0078, 0x2343, 0x7200, 0xa284,
-+	0x0007, 0xa086, 0x0001, 0x00c0, 0x25fb, 0x781b, 0x004f, 0x1078,
-+	0x371d, 0x0078, 0x260c, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b,
-+	0x004f, 0x1078, 0x371d, 0x7200, 0x2500, 0xa605, 0x0040, 0x260c,
-+	0xa284, 0x0007, 0x1079, 0x261a, 0xad80, 0x0009, 0x7036, 0xa284,
-+	0x0007, 0xa086, 0x0001, 0x00c0, 0x231a, 0x6018, 0x8000, 0x601a,
-+	0x0078, 0x231a, 0x2622, 0x45ed, 0x45ed, 0x45dc, 0x45ed, 0x2622,
-+	0x45dc, 0x2622, 0x1078, 0x22ac, 0x1078, 0x3705, 0x0f7e, 0x2079,
-+	0x4d00, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2648, 0x706c,
-+	0xa086, 0x0001, 0x00c0, 0x2637, 0x706e, 0x0078, 0x26d9, 0x706c,
-+	0xa086, 0x0005, 0x00c0, 0x2646, 0x7088, 0x2068, 0x681b, 0x0004,
-+	0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000,
-+	0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2669, 0xa186,
-+	0x0007, 0x00c0, 0x2659, 0x2009, 0x4d38, 0x200b, 0x0005, 0x0078,
-+	0x2669, 0x2009, 0x4d13, 0x2104, 0x2009, 0x4d12, 0x200a, 0x2009,
-+	0x4d38, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078,
-+	0x266b, 0x706f, 0x0000, 0x1078, 0x431b, 0x157e, 0x20a9, 0x0010,
-+	0x2039, 0x0000, 0x1078, 0x34f9, 0xa7b8, 0x0100, 0x0070, 0x267a,
-+	0x0078, 0x2672, 0x157f, 0x7000, 0x0079, 0x267e, 0x26aa, 0x2693,
-+	0x2693, 0x2686, 0x26aa, 0x26aa, 0x26aa, 0x26aa, 0x2021, 0x4d5a,
-+	0x2404, 0xa005, 0x0040, 0x26aa, 0xad06, 0x00c0, 0x2693, 0x6800,
-+	0x2022, 0x0078, 0x26a3, 0x6820, 0xa084, 0x0001, 0x00c0, 0x269f,
-+	0x6f14, 0x1078, 0x35fc, 0x1078, 0x3201, 0x0078, 0x26a3, 0x7060,
-+	0x2060, 0x6800, 0x6002, 0x6a1a, 0x6820, 0xa085, 0x0008, 0x6822,
-+	0x1078, 0x1b8e, 0x2021, 0x7100, 0x1078, 0x26e6, 0x2021, 0x4d5a,
-+	0x1078, 0x26e6, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7000, 0x1078,
-+	0x26e6, 0x8420, 0x0070, 0x26be, 0x0078, 0x26b7, 0x2061, 0x5000,
-+	0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff, 0x0040,
-+	0x26cd, 0xa102, 0x0050, 0x26cd, 0x6012, 0x601b, 0x0000, 0xace0,
-+	0x0010, 0x0070, 0x26d5, 0x0078, 0x26c4, 0x8421, 0x00c0, 0x26c2,
-+	0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x26e0, 0x1078, 0x3810,
-+	0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x231a, 0x047e, 0x2404,
-+	0xa005, 0x0040, 0x26f8, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6820,
-+	0xa085, 0x0008, 0x6822, 0x1078, 0x1b8e, 0x007f, 0x0078, 0x26e8,
-+	0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2702,
-+	0x1078, 0x22ac, 0x2300, 0x0079, 0x2705, 0x2708, 0x277b, 0x2798,
-+	0xa282, 0x0002, 0x0040, 0x270e, 0x1078, 0x22ac, 0x706c, 0x706f,
-+	0x0000, 0x7093, 0x0000, 0x0079, 0x2715, 0x271d, 0x271d, 0x271f,
-+	0x2753, 0x3236, 0x271d, 0x2753, 0x271d, 0x1078, 0x22ac, 0x7780,
-+	0x1078, 0x34f9, 0x7780, 0xa7bc, 0x0f00, 0x1078, 0x35fc, 0x6018,
-+	0xa005, 0x0040, 0x274a, 0x2021, 0x7100, 0x2009, 0x0004, 0x2011,
-+	0x0010, 0x1078, 0x27b3, 0x0040, 0x274a, 0x157e, 0x20a9, 0x0000,
-+	0x2021, 0x7000, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078,
-+	0x27b3, 0x047f, 0x0040, 0x2749, 0x8420, 0x0070, 0x2749, 0x0078,
-+	0x273a, 0x157f, 0x8738, 0xa784, 0x001f, 0x00c0, 0x2725, 0x0078,
-+	0x2343, 0x0078, 0x2343, 0x7780, 0x1078, 0x35fc, 0x6018, 0xa005,
-+	0x0040, 0x2779, 0x2021, 0x7100, 0x2009, 0x0005, 0x2011, 0x0020,
-+	0x1078, 0x27b3, 0x0040, 0x2779, 0x157e, 0x20a9, 0x0000, 0x2021,
-+	0x7000, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x27b3,
-+	0x047f, 0x0040, 0x2778, 0x8420, 0x0070, 0x2778, 0x0078, 0x2769,
-+	0x157f, 0x0078, 0x2343, 0x2200, 0x0079, 0x277e, 0x2781, 0x2783,
-+	0x2783, 0x1078, 0x22ac, 0x2009, 0x0012, 0x706c, 0xa086, 0x0002,
-+	0x0040, 0x278c, 0x2009, 0x000e, 0x6818, 0xa084, 0x8000, 0x0040,
-+	0x2792, 0x691a, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078, 0x3693,
-+	0x2200, 0x0079, 0x279b, 0x27a0, 0x2783, 0x279e, 0x1078, 0x22ac,
-+	0x1078, 0x431b, 0x7000, 0xa086, 0x0001, 0x00c0, 0x31c6, 0x1078,
-+	0x3217, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x31b9, 0x0040,
-+	0x31c6, 0x0078, 0x245d, 0x2404, 0xa005, 0x0040, 0x27d4, 0x2068,
-+	0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x27c2, 0x2d20, 0x007f,
-+	0x0078, 0x27b4, 0x007f, 0x2022, 0x691a, 0x6820, 0xa205, 0x6822,
-+	0x1078, 0x1b8e, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef,
-+	0x600a, 0x1078, 0x3217, 0x007c, 0xa085, 0x0001, 0x0078, 0x27d3,
-+	0x2300, 0x0079, 0x27db, 0x27e0, 0x27de, 0x2879, 0x1078, 0x22ac,
-+	0x78ec, 0xa084, 0x0001, 0x00c0, 0x27f4, 0x7000, 0xa086, 0x0004,
-+	0x00c0, 0x27ec, 0x0078, 0x2817, 0x1078, 0x3217, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x0078, 0x31c6, 0x78e4, 0xa005, 0x00d0, 0x2817,
-+	0x0018, 0x2817, 0x2008, 0xa084, 0x0030, 0x00c0, 0x2803, 0x781b,
-+	0x004f, 0x0078, 0x231a, 0x78ec, 0xa084, 0x0003, 0x0040, 0x27ff,
-+	0x2100, 0xa084, 0x0007, 0x0079, 0x280d, 0x2850, 0x285b, 0x2841,
-+	0x2815, 0x36f8, 0x36f8, 0x2815, 0x286a, 0x1078, 0x22ac, 0x7000,
-+	0xa086, 0x0004, 0x00c0, 0x2831, 0x706c, 0xa086, 0x0002, 0x00c0,
-+	0x2827, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x26fc, 0x706c,
-+	0xa086, 0x0006, 0x0040, 0x2821, 0x706c, 0xa086, 0x0004, 0x0040,
-+	0x2821, 0x79e4, 0xa184, 0x0030, 0x0040, 0x283b, 0x78ec, 0xa084,
-+	0x0003, 0x00c0, 0x283d, 0x0078, 0x2ded, 0x2001, 0x0003, 0x0078,
-+	0x2b81, 0x6818, 0xa084, 0x8000, 0x0040, 0x2848, 0x681b, 0x001d,
-+	0x1078, 0x34d8, 0x782b, 0x3008, 0x781b, 0x005b, 0x0078, 0x231a,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x2857, 0x681b, 0x001d, 0x1078,
-+	0x34d8, 0x0078, 0x36c3, 0x6818, 0xa084, 0x8000, 0x0040, 0x2862,
-+	0x681b, 0x001d, 0x1078, 0x34d8, 0x782b, 0x3008, 0x781b, 0x00de,
-+	0x0078, 0x231a, 0x6818, 0xa084, 0x8000, 0x0040, 0x2871, 0x681b,
-+	0x001d, 0x1078, 0x34d8, 0x782b, 0x3008, 0x781b, 0x009c, 0x0078,
-+	0x231a, 0xa584, 0x000f, 0x00c0, 0x2896, 0x7000, 0x0079, 0x2880,
-+	0x2343, 0x288a, 0x2888, 0x31c6, 0x31c6, 0x31c6, 0x31c6, 0x2888,
-+	0x1078, 0x22ac, 0x1078, 0x3217, 0x6008, 0xa084, 0xffef, 0x600a,
-+	0x1078, 0x31b9, 0x0040, 0x31c6, 0x0078, 0x245d, 0x78e4, 0xa005,
-+	0x00d0, 0x2817, 0x0018, 0x2817, 0x2008, 0xa084, 0x0030, 0x00c0,
-+	0x28a5, 0x781b, 0x004f, 0x0078, 0x231a, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x28a1, 0x2100, 0xa184, 0x0007, 0x0079, 0x28af, 0x28c1,
-+	0x28c5, 0x28b9, 0x28b7, 0x36f8, 0x36f8, 0x28b7, 0x36ee, 0x1078,
-+	0x22ac, 0x1078, 0x34e0, 0x782b, 0x3008, 0x781b, 0x005b, 0x0078,
-+	0x231a, 0x1078, 0x34e0, 0x0078, 0x36c3, 0x1078, 0x34e0, 0x782b,
-+	0x3008, 0x781b, 0x00de, 0x0078, 0x231a, 0x1078, 0x34e0, 0x782b,
-+	0x3008, 0x781b, 0x009c, 0x0078, 0x231a, 0x2300, 0x0079, 0x28d8,
-+	0x28dd, 0x28db, 0x28df, 0x1078, 0x22ac, 0x0078, 0x2f2b, 0x681b,
-+	0x0008, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x2f2b,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x2f2b, 0xa184, 0x0007, 0x0079,
-+	0x28f1, 0x28f9, 0x28c5, 0x2841, 0x3693, 0x36f8, 0x36f8, 0x28f9,
-+	0x36ee, 0x1078, 0x36a7, 0x0078, 0x231a, 0xa282, 0x0005, 0x0050,
-+	0x2903, 0x1078, 0x22ac, 0x2300, 0x0079, 0x2906, 0x2909, 0x2b2e,
-+	0x2b3c, 0x2200, 0x0079, 0x290c, 0x2926, 0x2913, 0x2926, 0x2911,
-+	0x2b13, 0x1078, 0x22ac, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
-+	0xa082, 0x0020, 0x0048, 0x34be, 0xa08a, 0x0004, 0x00c8, 0x34be,
-+	0x0079, 0x2922, 0x34be, 0x34be, 0x34be, 0x346c, 0x789b, 0x0018,
-+	0x79a8, 0xa184, 0x0080, 0x0040, 0x2937, 0x0078, 0x34be, 0x7000,
-+	0xa005, 0x00c0, 0x292d, 0x2011, 0x0004, 0x0078, 0x3069, 0xa184,
-+	0x00ff, 0xa08a, 0x0010, 0x00c8, 0x34be, 0x0079, 0x293f, 0x2951,
-+	0x294f, 0x2969, 0x296d, 0x29ff, 0x34be, 0x34be, 0x2a01, 0x34be,
-+	0x34be, 0x2b0f, 0x2b0f, 0x34be, 0x34be, 0x34be, 0x2b11, 0x1078,
-+	0x22ac, 0xa684, 0x1000, 0x0040, 0x295e, 0x2001, 0x0500, 0x8000,
-+	0x8000, 0x783a, 0x781b, 0x009a, 0x0078, 0x231a, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x2967, 0x681b, 0x001d, 0x0078, 0x2955, 0x0078,
-+	0x3693, 0x681b, 0x001d, 0x0078, 0x34ce, 0x6920, 0x6922, 0xa684,
-+	0x1800, 0x00c0, 0x2987, 0x6820, 0xa084, 0x0001, 0x00c0, 0x298d,
-+	0x6818, 0xa086, 0x0008, 0x00c0, 0x297f, 0x681b, 0x0000, 0xa684,
-+	0x0400, 0x0040, 0x29fb, 0x781b, 0x005d, 0x0078, 0x231a, 0xa684,
-+	0x1000, 0x0040, 0x298d, 0x0078, 0x231a, 0xa684, 0x0060, 0x0040,
-+	0x29f7, 0xa684, 0x0800, 0x0040, 0x29f7, 0xa684, 0x8000, 0x00c0,
-+	0x299b, 0x0078, 0x29b5, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x789b,
-+	0x0076, 0x7aac, 0x79ac, 0x78ac, 0x801b, 0x00c8, 0x29a8, 0x8000,
-+	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
-+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040,
-+	0x29bd, 0xa6b4, 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003,
-+	0x00c0, 0x29ca, 0x1078, 0x43d1, 0x1078, 0x45dc, 0x781b, 0x006c,
-+	0x0078, 0x231a, 0xa006, 0x1078, 0x46d8, 0x6ab0, 0x69ac, 0x6c98,
-+	0x6b94, 0x2200, 0xa105, 0x0040, 0x29d9, 0x2200, 0xa422, 0x2100,
-+	0xa31b, 0x6caa, 0x7cd2, 0x6ba6, 0x7bd6, 0x2300, 0xa405, 0x00c0,
-+	0x29e9, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x006c, 0x0078,
-+	0x231a, 0x781b, 0x006c, 0x2200, 0xa115, 0x00c0, 0x29f3, 0x1078,
-+	0x45ed, 0x0078, 0x231a, 0x1078, 0x4638, 0x0078, 0x231a, 0x781b,
-+	0x006d, 0x0078, 0x231a, 0x781b, 0x005d, 0x0078, 0x231a, 0x1078,
-+	0x22ac, 0x0078, 0x2a62, 0x6920, 0xa184, 0x0100, 0x0040, 0x2a19,
-+	0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084,
-+	0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078,
-+	0x2a51, 0xa184, 0x0200, 0x0040, 0x2a51, 0xa18c, 0xfdff, 0x6922,
-+	0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004,
-+	0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008,
-+	0x0040, 0x2a51, 0x1078, 0x35f8, 0x1078, 0x331a, 0x88ff, 0x0040,
-+	0x2a51, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
-+	0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2a4b, 0x782b, 0x3008, 0x781b,
-+	0x005b, 0x0078, 0x231a, 0x782b, 0x3008, 0x781b, 0x006d, 0x0078,
-+	0x231a, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2a5a, 0x781b, 0x005d,
-+	0x0078, 0x231a, 0x781b, 0x006d, 0x0078, 0x231a, 0x0078, 0x34c6,
-+	0x0078, 0x34c6, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040,
-+	0x2a60, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
-+	0x00c0, 0x2aa0, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
-+	0x2a98, 0x0048, 0x2a7d, 0x0078, 0x2a9a, 0xa380, 0x0002, 0xa102,
-+	0x00c8, 0x2a98, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054,
-+	0x2060, 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5,
-+	0x6006, 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2a52,
-+	0x0078, 0x2a03, 0x24a8, 0x7aa8, 0x00f0, 0x2a9a, 0x0078, 0x2a6b,
-+	0xa284, 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2b00, 0x8318, 0x8318,
-+	0x2300, 0xa102, 0x0040, 0x2ab0, 0x0048, 0x2ab0, 0x0078, 0x2afd,
-+	0xa286, 0x0023, 0x0040, 0x2a60, 0x681c, 0xa084, 0xfff1, 0x681e,
-+	0x7e58, 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008,
-+	0xa085, 0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
-+	0x2c48, 0x0c7f, 0xa184, 0x0010, 0x0040, 0x2ad4, 0x1078, 0x35f8,
-+	0x1078, 0x3429, 0x0078, 0x2ae3, 0x0c7e, 0x7054, 0x2060, 0x6004,
-+	0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2a51, 0x1078,
-+	0x35f8, 0x1078, 0x331a, 0x88ff, 0x0040, 0x2a51, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-+	0x2af7, 0x782b, 0x3008, 0x781b, 0x005b, 0x0078, 0x231a, 0x782b,
-+	0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x7aa8, 0x0078, 0x2a6b,
-+	0x8318, 0x2300, 0xa102, 0x0040, 0x2b09, 0x0048, 0x2b09, 0x0078,
-+	0x2a6b, 0xa284, 0x0080, 0x00c0, 0x34ce, 0x0078, 0x34c6, 0x0078,
-+	0x34ce, 0x0078, 0x34be, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
-+	0xa08e, 0x0001, 0x0040, 0x2b1e, 0x1078, 0x22ac, 0x7aa8, 0xa294,
-+	0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x34be,
-+	0x0079, 0x2b2a, 0x34be, 0x3267, 0x34be, 0x33be, 0xa282, 0x0000,
-+	0x00c0, 0x2b34, 0x1078, 0x22ac, 0x1078, 0x34d8, 0x782b, 0x3008,
-+	0x781b, 0x006d, 0x0078, 0x231a, 0xa282, 0x0003, 0x00c0, 0x2b42,
-+	0x1078, 0x22ac, 0xa484, 0x8000, 0x00c0, 0x2b65, 0x706c, 0xa005,
-+	0x0040, 0x2b4c, 0x1078, 0x22ac, 0x6f14, 0x7782, 0xa7bc, 0x0f00,
-+	0x1078, 0x35fc, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x2b50, 0x1078, 0x34dc, 0x706f, 0x0002, 0x2009,
-+	0x4d38, 0x200b, 0x0009, 0x0078, 0x2b67, 0x1078, 0x34e8, 0x782b,
-+	0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0xa282, 0x0004, 0x0050,
-+	0x2b73, 0x1078, 0x22ac, 0x2300, 0x0079, 0x2b76, 0x2b79, 0x2c6c,
-+	0x2c9f, 0xa286, 0x0003, 0x0040, 0x2b7f, 0x1078, 0x22ac, 0x2001,
-+	0x0000, 0x007e, 0x68c0, 0xa005, 0x0040, 0x2b88, 0x7003, 0x0003,
-+	0x68a0, 0xa084, 0x2000, 0x0040, 0x2b91, 0x6008, 0xa085, 0x0002,
-+	0x600a, 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2b98,
-+	0x2343, 0x2ba2, 0x2ba2, 0x2d97, 0x2dd3, 0x2343, 0x2dd3, 0x2ba0,
-+	0x1078, 0x22ac, 0xa684, 0x1000, 0x00c0, 0x2baa, 0x1078, 0x431b,
-+	0x0040, 0x2c46, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2bf2, 0xa186,
-+	0x0008, 0x00c0, 0x2bc1, 0x1078, 0x3217, 0x6008, 0xa084, 0xffef,
-+	0x600a, 0x1078, 0x31b9, 0x0040, 0x2bf2, 0x1078, 0x431b, 0x0078,
-+	0x2bd9, 0xa186, 0x0028, 0x00c0, 0x2bf2, 0x1078, 0x431b, 0x6008,
-+	0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2bd9, 0x8001,
-+	0x601a, 0xa005, 0x0040, 0x2bd9, 0x8001, 0xa005, 0x0040, 0x2bd9,
-+	0x601e, 0x6820, 0xa084, 0x0001, 0x0040, 0x2343, 0x6820, 0xa084,
-+	0xfffe, 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f,
-+	0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2bef, 0x6002, 0x6006,
-+	0x0078, 0x2343, 0x017e, 0x1078, 0x2cd0, 0x017f, 0xa684, 0xdf00,
-+	0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2c46, 0xa186,
-+	0x0002, 0x00c0, 0x2c3e, 0xa684, 0x0800, 0x00c0, 0x2c0f, 0xa684,
-+	0x0060, 0x0040, 0x2c0f, 0x78d8, 0x7adc, 0x6832, 0x6a2e, 0x6820,
-+	0xa084, 0x0800, 0x00c0, 0x2c46, 0x8717, 0xa294, 0x000f, 0x8213,
-+	0x8213, 0x8213, 0xa290, 0x4f80, 0xa290, 0x0000, 0x221c, 0xa384,
-+	0x0100, 0x00c0, 0x2c25, 0x0078, 0x2c2b, 0x8210, 0x2204, 0xa085,
-+	0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2c38, 0x68a0,
-+	0xa084, 0x0100, 0x00c0, 0x2c38, 0x1078, 0x2d4a, 0x0078, 0x2343,
-+	0x6008, 0xa085, 0x0002, 0x600a, 0x0078, 0x2c46, 0xa186, 0x0018,
-+	0x0040, 0x2c46, 0xa186, 0x0014, 0x0040, 0x2343, 0x6916, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2c4e, 0x703c, 0x681a, 0xa68c, 0xdf00,
-+	0x691e, 0x1078, 0x3208, 0x1078, 0x3217, 0x00c0, 0x2c5b, 0x6008,
-+	0xa084, 0xffef, 0x600a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2c64,
-+	0x1078, 0x3201, 0x0078, 0x2c68, 0x7060, 0x2060, 0x6800, 0x6002,
-+	0x1078, 0x1b8e, 0x0078, 0x2343, 0xa282, 0x0004, 0x0048, 0x2c72,
-+	0x1078, 0x22ac, 0x2200, 0x0079, 0x2c75, 0x2c70, 0x2c79, 0x2c86,
-+	0x2c79, 0x7000, 0xa086, 0x0005, 0x0040, 0x2c82, 0x1078, 0x34d8,
-+	0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x7890, 0x8007,
-+	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
-+	0x00ff, 0xa186, 0x0003, 0x0040, 0x2c9b, 0xa186, 0x0000, 0x0040,
-+	0x2c9b, 0x0078, 0x34be, 0x781b, 0x006d, 0x0078, 0x231a, 0x6820,
-+	0xa085, 0x0004, 0x6822, 0x82ff, 0x00c0, 0x2caa, 0x1078, 0x34d8,
-+	0x0078, 0x2cb1, 0x8211, 0x0040, 0x2caf, 0x1078, 0x22ac, 0x1078,
-+	0x34e8, 0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x702c,
-+	0x8003, 0x0048, 0x2cc1, 0x2019, 0x4955, 0x1078, 0x2137, 0x702f,
-+	0x8000, 0x1078, 0x371d, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2ccd,
-+	0x0018, 0x2ccd, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
-+	0xa684, 0x0060, 0x00c0, 0x2cda, 0x6833, 0x0000, 0x682f, 0x0000,
-+	0x0078, 0x2d49, 0xa684, 0x0800, 0x00c0, 0x2cf2, 0x68b4, 0xa084,
-+	0x4800, 0xa635, 0xa684, 0x0800, 0x00c0, 0x2cf2, 0x6998, 0x6a94,
-+	0x6932, 0x6a2e, 0x7000, 0xa086, 0x0006, 0x0040, 0x2cf1, 0x1078,
-+	0x431b, 0x007c, 0xa684, 0x0020, 0x0040, 0x2d14, 0xa684, 0x4000,
-+	0x0040, 0x2d00, 0x6833, 0x0000, 0x682f, 0x0000, 0x0078, 0x2cea,
-+	0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2cfa,
-+	0x703c, 0xa005, 0x00c0, 0x2d0e, 0x703f, 0x0015, 0x79d8, 0x7adc,
-+	0x6932, 0x6a2e, 0x0078, 0x2cea, 0xa684, 0x4000, 0x0040, 0x2d1e,
-+	0x6833, 0x0000, 0x682f, 0x0000, 0x0078, 0x2cea, 0x68b4, 0xa084,
-+	0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2d18, 0x703c, 0xa005,
-+	0x00c0, 0x2d2c, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb,
-+	0x00c8, 0x2d33, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x6932, 0x6a2e, 0x2100, 0xa205, 0x00c0, 0x2d40, 0x0078, 0x2cea,
-+	0x7000, 0xa086, 0x0006, 0x0040, 0x2d49, 0x1078, 0x46d8, 0x0078,
-+	0x2cea, 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200,
-+	0x0040, 0x2d56, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006,
-+	0x688f, 0x0000, 0x6893, 0x0000, 0x6a2c, 0x6930, 0x6a3e, 0x6942,
-+	0x682f, 0x0300, 0x6833, 0x0000, 0x6837, 0x2000, 0x6897, 0x0000,
-+	0x689b, 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079,
-+	0x2d71, 0x2343, 0x2d7b, 0x2d84, 0x2d79, 0x2d79, 0x2d79, 0x2d79,
-+	0x2d79, 0x1078, 0x22ac, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2d84,
-+	0x1078, 0x3201, 0x0078, 0x2d8a, 0x7060, 0x2c50, 0x2060, 0x6800,
-+	0x6002, 0x2a60, 0x2021, 0x4d5a, 0x2404, 0xa005, 0x0040, 0x2d93,
-+	0x2020, 0x0078, 0x2d8c, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078,
-+	0x3208, 0x1078, 0x3217, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b,
-+	0x0000, 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x472f,
-+	0xa684, 0x0800, 0x0040, 0x2db0, 0x691c, 0xa18d, 0x2000, 0x691e,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x2dc0, 0x7868, 0xa08c, 0x00ff,
-+	0x0040, 0x2dbe, 0x681b, 0x001e, 0x0078, 0x2dc0, 0x681b, 0x0000,
-+	0x2021, 0x4d5a, 0x2404, 0xad06, 0x0040, 0x2dc7, 0x7460, 0x6800,
-+	0x2022, 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a2e, 0x6932, 0x1078,
-+	0x1b8e, 0x0078, 0x2343, 0x1078, 0x2cd0, 0x682b, 0x0000, 0x789b,
-+	0x000e, 0x6f14, 0x1078, 0x3723, 0xa08c, 0x00ff, 0x6916, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2de6, 0x703c, 0x681a, 0xa68c, 0xdf00,
-+	0x691e, 0x706f, 0x0000, 0x0078, 0x2343, 0x7000, 0xa005, 0x00c0,
-+	0x2df3, 0x0078, 0x2343, 0xa006, 0x1078, 0x431b, 0x6817, 0x0000,
-+	0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
-+	0xa085, 0x00ff, 0x6822, 0x7000, 0x0079, 0x2e06, 0x2343, 0x2e10,
-+	0x2e10, 0x2e12, 0x2e12, 0x2e12, 0x2e12, 0x2e0e, 0x1078, 0x22ac,
-+	0x1078, 0x3217, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x31d1,
-+	0x2300, 0x0079, 0x2e1b, 0x2e1e, 0x2e20, 0x2e59, 0x1078, 0x22ac,
-+	0x7000, 0x0079, 0x2e23, 0x2343, 0x2e2d, 0x2e2d, 0x2e48, 0x2e2d,
-+	0x2e55, 0x2e48, 0x2e2b, 0x1078, 0x22ac, 0xa684, 0x0060, 0xa086,
-+	0x0060, 0x00c0, 0x2e44, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5,
-+	0x2000, 0x7e5a, 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x431b,
-+	0x1078, 0x45ed, 0x0078, 0x3693, 0xa684, 0x2000, 0x0040, 0x2e37,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x2e55, 0x681b, 0x0015, 0xa684,
-+	0x4000, 0x0040, 0x2e55, 0x681b, 0x0007, 0x1078, 0x36a7, 0x0078,
-+	0x231a, 0x1078, 0x22ac, 0x2300, 0x0079, 0x2e5e, 0x2e61, 0x2e63,
-+	0x2e96, 0x1078, 0x22ac, 0x7000, 0x0079, 0x2e66, 0x2343, 0x2e70,
-+	0x2e70, 0x2e8b, 0x2e70, 0x2e92, 0x2e8b, 0x2e6e, 0x1078, 0x22ac,
-+	0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x2e87, 0xa6b4, 0xffbf,
-+	0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf,
-+	0x681e, 0x1078, 0x431b, 0x1078, 0x45ed, 0x0078, 0x3693, 0xa684,
-+	0x2000, 0x0040, 0x2e7a, 0x6818, 0xa084, 0x8000, 0x0040, 0x2e92,
-+	0x681b, 0x0007, 0x781b, 0x00de, 0x0078, 0x231a, 0x6820, 0xa085,
-+	0x0004, 0x6822, 0x1078, 0x365e, 0xa6b5, 0x0800, 0x1078, 0x34d8,
-+	0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x2300, 0x0079,
-+	0x2ea9, 0x2eac, 0x2eae, 0x2eb0, 0x1078, 0x22ac, 0x1078, 0x22ac,
-+	0xa684, 0x0400, 0x00c0, 0x2ed9, 0x79e4, 0xa184, 0x0020, 0x0040,
-+	0x2ec0, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2ec0, 0x782b, 0x3009,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4,
-+	0xa184, 0x0020, 0x0040, 0x2ed1, 0x78ec, 0xa084, 0x0003, 0x00c0,
-+	0x2ed5, 0x2001, 0x0014, 0x0078, 0x2b81, 0xa184, 0x0007, 0x0079,
-+	0x2f11, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff,
-+	0x0040, 0x2f0f, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0,
-+	0x2f00, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x2ef3, 0x2009,
-+	0xfff7, 0x0078, 0x2ef9, 0xa386, 0x0003, 0x00c0, 0x2f00, 0x2009,
-+	0xffef, 0x0c7e, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b,
-+	0x3009, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
-+	0x3693, 0x2850, 0x285b, 0x2f1b, 0x2f23, 0x2f19, 0x2f19, 0x2f19,
-+	0x3693, 0x1078, 0x22ac, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x6922, 0x0078, 0x369d, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x6922, 0x0078, 0x3693, 0x79e4, 0xa184, 0x0030, 0x0040, 0x2f35,
-+	0x78ec, 0xa084, 0x0003, 0x00c0, 0x2f57, 0x7000, 0xa086, 0x0004,
-+	0x00c0, 0x2f4f, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2f45, 0x2011,
-+	0x0002, 0x2019, 0x0000, 0x0078, 0x26fc, 0x706c, 0xa086, 0x0006,
-+	0x0040, 0x2f3f, 0x706c, 0xa086, 0x0004, 0x0040, 0x2f3f, 0x6818,
-+	0xa085, 0x8000, 0x681a, 0x2001, 0x0014, 0x0078, 0x2b81, 0xa184,
-+	0x0007, 0x0079, 0x2f5b, 0x3693, 0x3693, 0x2f63, 0x3693, 0x36f8,
-+	0x36f8, 0x3693, 0x3693, 0xa684, 0x0400, 0x00c0, 0x2fa6, 0x6820,
-+	0xa084, 0x0001, 0x0040, 0x369d, 0xa68c, 0x0060, 0xa684, 0x0060,
-+	0x0040, 0x2f78, 0xa086, 0x0060, 0x00c0, 0x2f78, 0xa18d, 0x4000,
-+	0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000,
-+	0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a, 0x78aa, 0x8008,
-+	0x810c, 0x0040, 0x3230, 0xa18c, 0x00f8, 0x00c0, 0x3230, 0x157e,
-+	0x137e, 0x147e, 0x20a1, 0x012c, 0x789b, 0x0000, 0x8000, 0x80ac,
-+	0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814,
-+	0x8007, 0x789b, 0x0080, 0x78aa, 0x0078, 0x369d, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x2fad, 0x681b, 0x0008, 0x781b, 0x00d4, 0x0078,
-+	0x231a, 0x2300, 0x0079, 0x2fb4, 0x2fb9, 0x3054, 0x2fb7, 0x1078,
-+	0x22ac, 0x7000, 0xa084, 0x0007, 0x0079, 0x2fbe, 0x2343, 0x2fc8,
-+	0x2ffd, 0x2fd3, 0x2fc6, 0x2343, 0x2fc6, 0x2fc6, 0x1078, 0x22ac,
-+	0x681c, 0xa084, 0x2000, 0x0040, 0x2fe1, 0x6008, 0xa085, 0x0002,
-+	0x600a, 0x0078, 0x2fe1, 0x68c0, 0xa005, 0x00c0, 0x2ffd, 0x6920,
-+	0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078,
-+	0x2ff7, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005,
-+	0x00c0, 0x2feb, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x2ff7,
-+	0x7014, 0x68ba, 0x7130, 0xa188, 0x7000, 0x0078, 0x2ff9, 0x2009,
-+	0x7100, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060,
-+	0x0040, 0x3052, 0xa684, 0x0800, 0x00c0, 0x3011, 0xa684, 0x7fff,
-+	0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x431b, 0x0078,
-+	0x3052, 0xa684, 0x0020, 0x0040, 0x3026, 0x68c0, 0xa005, 0x0040,
-+	0x301d, 0x1078, 0x472f, 0x0078, 0x3020, 0xa006, 0x1078, 0x46d8,
-+	0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x302c, 0x1078, 0x3609,
-+	0x69aa, 0x6aa6, 0x1078, 0x46d8, 0xa684, 0x8000, 0x0040, 0x3052,
-+	0xa684, 0x7fff, 0x68b6, 0x789b, 0x0076, 0x1078, 0x3723, 0x2010,
-+	0x1078, 0x3723, 0x2008, 0xa684, 0x0020, 0x00c0, 0x304a, 0x1078,
-+	0x3723, 0x801b, 0x00c8, 0x3045, 0x8000, 0xa084, 0x003f, 0xa108,
-+	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0x0078, 0x2343, 0x0078, 0x34ce, 0x7037, 0x0000,
-+	0xa282, 0x0006, 0x0050, 0x305e, 0x1078, 0x22ac, 0x7000, 0xa084,
-+	0x0007, 0x10c0, 0x37c7, 0x2300, 0x0079, 0x3066, 0x3069, 0x308f,
-+	0x30a1, 0x2200, 0x0079, 0x306c, 0x308d, 0x34ce, 0x3072, 0x308d,
-+	0x30bb, 0x30fa, 0x7003, 0x0005, 0x2001, 0x7210, 0x2068, 0x704a,
-+	0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3082,
-+	0x0078, 0x307b, 0x157f, 0x6817, 0x0000, 0x68b7, 0x0700, 0x6823,
-+	0x0800, 0x6827, 0x0003, 0x0078, 0x34be, 0x1078, 0x22ac, 0x7003,
-+	0x0005, 0x2001, 0x7210, 0x2068, 0x704a, 0x7036, 0x2200, 0x0079,
-+	0x3099, 0x34ce, 0x309f, 0x309f, 0x30bb, 0x309f, 0x34ce, 0x1078,
-+	0x22ac, 0x7003, 0x0005, 0x2001, 0x7210, 0x2068, 0x704a, 0x7036,
-+	0x2200, 0x0079, 0x30ab, 0x30b3, 0x30b1, 0x30b1, 0x30b3, 0x30b1,
-+	0x30b3, 0x1078, 0x22ac, 0x1078, 0x34e8, 0x782b, 0x3008, 0x781b,
-+	0x006d, 0x0078, 0x231a, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00,
-+	0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x7100,
-+	0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x30d6, 0x6814,
-+	0xa206, 0x0040, 0x30ef, 0x6800, 0x0078, 0x30c9, 0x7003, 0x0005,
-+	0x2001, 0x7210, 0x2068, 0x704a, 0x7036, 0x157e, 0x20a9, 0x0031,
-+	0x2003, 0x0000, 0x8000, 0x0070, 0x30e7, 0x0078, 0x30e0, 0x157f,
-+	0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4,
-+	0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3146, 0x1078, 0x34e0,
-+	0x0078, 0x3146, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
-+	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c,
-+	0x00ff, 0xa1e8, 0x7000, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005,
-+	0x0040, 0x3119, 0x6814, 0xa206, 0x0040, 0x3131, 0x6800, 0x0078,
-+	0x310c, 0x7003, 0x0005, 0x2001, 0x7210, 0x2068, 0x704a, 0x157e,
-+	0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3129, 0x0078,
-+	0x3122, 0x157f, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
-+	0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3146,
-+	0xa084, 0x0800, 0x0040, 0x3140, 0x1078, 0x34e4, 0x0078, 0x3146,
-+	0x1078, 0x34e0, 0x708b, 0x0000, 0x0078, 0x3146, 0x027e, 0x8207,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x4f80, 0x2060,
-+	0x7056, 0x6000, 0x705a, 0x6004, 0x705e, 0xa684, 0x0060, 0x0040,
-+	0x319e, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3180,
-+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, 0xa684,
-+	0x0060, 0xa086, 0x0060, 0x0040, 0x319e, 0x68c0, 0xa005, 0x0040,
-+	0x3179, 0x7003, 0x0003, 0x682b, 0x0000, 0x1078, 0x45dc, 0x0078,
-+	0x317b, 0x1078, 0x45ed, 0xa6b5, 0x2000, 0x7e5a, 0x0078, 0x319e,
-+	0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x319e,
-+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xa6b4, 0xbfff, 0x7e5a,
-+	0x007e, 0x68c0, 0xa005, 0x007f, 0x0040, 0x319c, 0x7003, 0x0003,
-+	0x1078, 0x45dc, 0x0078, 0x319e, 0x1078, 0x4638, 0x077f, 0x1078,
-+	0x35fc, 0x2009, 0x006d, 0xa684, 0x0004, 0x0040, 0x31ab, 0x782b,
-+	0x3008, 0x2009, 0x006d, 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x4f80, 0x2048, 0x0078,
-+	0x231a, 0x6020, 0xa005, 0x0040, 0x31c5, 0x8001, 0x6022, 0x6008,
-+	0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006, 0x1078,
-+	0x431b, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f,
-+	0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x31d6, 0x2343, 0x31e0,
-+	0x31e0, 0x31fd, 0x31e8, 0x31e6, 0x31e8, 0x31de, 0x1078, 0x22ac,
-+	0x1078, 0x3208, 0x1078, 0x3201, 0x1078, 0x1b8e, 0x0078, 0x2343,
-+	0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x31ef, 0x31f9,
-+	0x31f9, 0x31f7, 0x31f7, 0x31f7, 0x31f9, 0x31f7, 0x31f9, 0x0079,
-+	0x2715, 0x706f, 0x0000, 0x0078, 0x2343, 0x681b, 0x0000, 0x0078,
-+	0x2d97, 0x6800, 0xa005, 0x00c0, 0x3206, 0x6002, 0x6006, 0x007c,
-+	0x6010, 0xa005, 0x0040, 0x3211, 0x8001, 0x00d0, 0x3211, 0x1078,
-+	0x22ac, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018,
-+	0xa005, 0x0040, 0x321d, 0x8001, 0x601a, 0x007c, 0x1078, 0x371d,
-+	0x681b, 0x0018, 0x0078, 0x3254, 0x1078, 0x371d, 0x681b, 0x0019,
-+	0x0078, 0x3254, 0x1078, 0x371d, 0x681b, 0x001a, 0x0078, 0x3254,
-+	0x1078, 0x371d, 0x681b, 0x0003, 0x0078, 0x3254, 0x7780, 0x1078,
-+	0x35fc, 0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7000, 0x2d04, 0x2d08,
-+	0x2068, 0xa005, 0x00c0, 0x3246, 0x0078, 0x2343, 0x6814, 0x7280,
-+	0xa206, 0x0040, 0x324e, 0x6800, 0x0078, 0x323f, 0x6800, 0x200a,
-+	0x681b, 0x0005, 0x708b, 0x0000, 0x1078, 0x3208, 0x6820, 0xa084,
-+	0x0001, 0x00c0, 0x325d, 0x1078, 0x3201, 0x1078, 0x3217, 0x681f,
-+	0x0000, 0x6823, 0x0020, 0x1078, 0x1b8e, 0x0078, 0x2343, 0xa282,
-+	0x0003, 0x00c0, 0x34be, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4,
-+	0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100, 0x0040,
-+	0x32cb, 0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x32b5,
-+	0xa482, 0x000c, 0x0048, 0x3288, 0x0040, 0x3288, 0x2021, 0x000c,
-+	0x852b, 0x852b, 0x1078, 0x3577, 0x0040, 0x3292, 0x1078, 0x3384,
-+	0x0078, 0x32be, 0x1078, 0x3532, 0x0c7e, 0x2960, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x1078, 0x33ab, 0x0c7f, 0x6920, 0xa18d, 0x0100,
-+	0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-+	0x32af, 0x782b, 0x3008, 0x781b, 0x005b, 0x0078, 0x231a, 0x782b,
-+	0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x0c7e, 0x2960, 0x6004,
-+	0xa084, 0xfff5, 0x6006, 0x1078, 0x33ab, 0x0c7f, 0x7e58, 0xa684,
-+	0x0400, 0x00c0, 0x32c7, 0x781b, 0x005d, 0x0078, 0x231a, 0x781b,
-+	0x006d, 0x0078, 0x231a, 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c,
-+	0x1000, 0x0040, 0x330b, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282,
-+	0x000c, 0x0048, 0x32df, 0x0040, 0x32df, 0x2011, 0x000c, 0x2400,
-+	0xa202, 0x00c8, 0x32e4, 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018,
-+	0xa086, 0x0028, 0x00c0, 0x32f4, 0xa282, 0x0019, 0x00c8, 0x32fa,
-+	0x2011, 0x0019, 0x0078, 0x32fa, 0xa282, 0x000c, 0x00c8, 0x32fa,
-+	0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x32ff, 0x2228, 0x1078,
-+	0x3536, 0x852b, 0x852b, 0x1078, 0x3577, 0x0040, 0x330b, 0x1078,
-+	0x3384, 0x0078, 0x330f, 0x1078, 0x3532, 0x1078, 0x33ab, 0x7858,
-+	0xa085, 0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b, 0x006d,
-+	0x0078, 0x231a, 0x0c7e, 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0,
-+	0x3332, 0x6010, 0xa084, 0x000f, 0x00c0, 0x332c, 0x6104, 0xa18c,
-+	0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000,
-+	0x0078, 0x3359, 0x68a0, 0xa084, 0x0200, 0x00c0, 0x332c, 0x6208,
-+	0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x3347, 0xa282,
-+	0x0019, 0x00c8, 0x334d, 0x2011, 0x0019, 0x0078, 0x334d, 0xa282,
-+	0x000c, 0x00c8, 0x334d, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c,
-+	0x00ff, 0xa382, 0x000c, 0x0048, 0x3359, 0x0040, 0x3359, 0x2019,
-+	0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
-+	0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f,
-+	0x007c, 0x0c7e, 0x2960, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032,
-+	0x2019, 0x0000, 0x0078, 0x3374, 0x78ab, 0x0001, 0x78ab, 0x0003,
-+	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085,
-+	0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078,
-+	0x338b, 0x0c7f, 0x007c, 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86,
-+	0x6018, 0x789a, 0x7cae, 0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c,
-+	0x0007, 0xa105, 0x78a6, 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427,
-+	0x8204, 0x8004, 0xa084, 0x00ff, 0xa405, 0x600e, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x33b2,
-+	0x0c7f, 0x007c, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6,
-+	0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002,
-+	0x00c0, 0x34be, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184,
-+	0x0200, 0x0040, 0x3407, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff,
-+	0xa282, 0x0002, 0x00c8, 0x34be, 0x1078, 0x3450, 0x1078, 0x33ab,
-+	0xa980, 0x0001, 0x200c, 0x1078, 0x35f8, 0x1078, 0x331a, 0x88ff,
-+	0x0040, 0x33fa, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5,
-+	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x33f4, 0x782b, 0x3008,
-+	0x781b, 0x005b, 0x0078, 0x231a, 0x782b, 0x3008, 0x781b, 0x006d,
-+	0x0078, 0x231a, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x3403, 0x781b,
-+	0x005d, 0x0078, 0x231a, 0x781b, 0x006d, 0x0078, 0x231a, 0xa282,
-+	0x0002, 0x00c8, 0x340f, 0xa284, 0x0001, 0x0040, 0x3419, 0x7154,
-+	0xa188, 0x0000, 0x210c, 0xa18c, 0x2000, 0x00c0, 0x3419, 0x2011,
-+	0x0000, 0x1078, 0x3524, 0x1078, 0x3450, 0x1078, 0x33ab, 0x7858,
-+	0xa085, 0x0004, 0x785a, 0x782b, 0x3008, 0x781b, 0x006d, 0x0078,
-+	0x231a, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xa084,
-+	0x2000, 0x00c0, 0x3440, 0x6014, 0xa084, 0x0040, 0x00c0, 0x343e,
-+	0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x344d, 0x2011, 0x0000,
-+	0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0,
-+	0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c,
-+	0x0c7e, 0x7054, 0x2060, 0x1078, 0x3457, 0x0c7f, 0x007c, 0x82ff,
-+	0x0040, 0x345c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
-+	0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6, 0x788a, 0x6016, 0x6004,
-+	0xa084, 0xffef, 0x6006, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003,
-+	0x0040, 0x3475, 0x007f, 0x0078, 0x3478, 0x007f, 0x0078, 0x34ba,
-+	0xa684, 0x0020, 0x0040, 0x34ba, 0x7888, 0xa084, 0x0040, 0x0040,
-+	0x34ba, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x3488, 0x8000,
-+	0xa005, 0x0040, 0x349e, 0x831b, 0x00c8, 0x3491, 0x8001, 0x0040,
-+	0x34b6, 0xa684, 0x4000, 0x0040, 0x349e, 0x78b8, 0x801b, 0x00c8,
-+	0x349a, 0x8000, 0xa084, 0x003f, 0x00c0, 0x34b6, 0xa6b4, 0xbfff,
-+	0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x34aa,
-+	0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x46d8,
-+	0x781b, 0x006c, 0x1078, 0x4568, 0x0078, 0x231a, 0x781b, 0x006c,
-+	0x0078, 0x231a, 0x781b, 0x006d, 0x0078, 0x231a, 0x1078, 0x34ec,
-+	0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x1078, 0x34d8,
-+	0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x6827, 0x0002,
-+	0x1078, 0x34e0, 0x782b, 0x3008, 0x781b, 0x006d, 0x0078, 0x231a,
-+	0x2001, 0x0005, 0x0078, 0x34ee, 0x2001, 0x000c, 0x0078, 0x34ee,
-+	0x2001, 0x0006, 0x0078, 0x34ee, 0x2001, 0x000d, 0x0078, 0x34ee,
-+	0x2001, 0x0009, 0x0078, 0x34ee, 0x2001, 0x0007, 0x789b, 0x0010,
-+	0x78aa, 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a,
-+	0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703,
-+	0xa0e0, 0x4f80, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f,
-+	0x0040, 0x3512, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085,
-+	0x0008, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
-+	0x0040, 0x3522, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085,
-+	0x0010, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
-+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
-+	0x0004, 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010,
-+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa,
-+	0x789b, 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084,
-+	0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c,
-+	0xfff0, 0x2001, 0x4d46, 0x2004, 0xa082, 0x0028, 0x0040, 0x3560,
-+	0x2021, 0x35df, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x3566,
-+	0x2021, 0x35eb, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
-+	0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, 0x3575, 0x8420, 0x2300,
-+	0xa210, 0x0070, 0x3575, 0x0078, 0x3568, 0x157f, 0x007c, 0x157e,
-+	0x2009, 0x4d46, 0x210c, 0xa182, 0x0032, 0x0048, 0x358b, 0x0040,
-+	0x358f, 0x2009, 0x35d1, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
-+	0x0032, 0x0078, 0x35a1, 0xa182, 0x0028, 0x0040, 0x3599, 0x2009,
-+	0x35df, 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078,
-+	0x35a1, 0x2009, 0x35eb, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011,
-+	0x0064, 0x2200, 0xa502, 0x0040, 0x35b1, 0x0048, 0x35b1, 0x8108,
-+	0x2300, 0xa210, 0x0070, 0x35ae, 0x0078, 0x35a1, 0x157f, 0xa006,
-+	0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x35c0, 0x7808, 0xa085,
-+	0x0070, 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x35c0,
-+	0x78ec, 0xa084, 0x0300, 0x0040, 0x35ce, 0x2104, 0xa09e, 0x1201,
-+	0x00c0, 0x35ce, 0x2001, 0x2101, 0x0078, 0x35cf, 0x2104, 0xa005,
-+	0x007c, 0x1201, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404, 0x5604,
-+	0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x3202,
-+	0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805, 0x7a05,
-+	0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202, 0x5404,
-+	0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04,
-+	0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784,
-+	0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0, 0x5000,
-+	0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x3610, 0x8000,
-+	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079,
-+	0x0100, 0x2009, 0x4d40, 0x2091, 0x8000, 0x2104, 0x0079, 0x3620,
-+	0x3656, 0x362a, 0x362a, 0x362a, 0x362a, 0x362a, 0x362a, 0x365a,
-+	0x1078, 0x22ac, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x00c0,
-+	0x362c, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3633,
-+	0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000, 0x785a,
-+	0x7830, 0xa084, 0x0080, 0x00c0, 0x3656, 0x0018, 0x3656, 0x681c,
-+	0xa084, 0x0020, 0x00c0, 0x3654, 0x0e7e, 0x2071, 0x4d40, 0x1078,
-+	0x36a7, 0x0e7f, 0x0078, 0x3656, 0x781b, 0x00de, 0x2091, 0x8001,
-+	0x0f7f, 0x007c, 0x1078, 0x3886, 0x0078, 0x3656, 0x0c7e, 0x6814,
-+	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, 0x4f80,
-+	0x6004, 0xa084, 0x000a, 0x00c0, 0x3691, 0x6108, 0xa194, 0xff00,
-+	0x0040, 0x3691, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040,
-+	0x3680, 0x2001, 0x0032, 0xa106, 0x0040, 0x3684, 0x0078, 0x3688,
-+	0x2009, 0x0020, 0x0078, 0x368a, 0x2009, 0x003f, 0x0078, 0x368a,
-+	0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002,
-+	0x6006, 0x0c7f, 0x007c, 0x781b, 0x006d, 0x0078, 0x231a, 0x782b,
-+	0x3008, 0x781b, 0x006d, 0x0078, 0x231a, 0x781b, 0x005d, 0x0078,
-+	0x231a, 0x782b, 0x3008, 0x781b, 0x005b, 0x0078, 0x231a, 0x2009,
-+	0x4d20, 0x210c, 0xa186, 0x0000, 0x0040, 0x36bb, 0xa186, 0x0001,
-+	0x0040, 0x36be, 0x2009, 0x4d38, 0x200b, 0x000b, 0x706f, 0x0001,
-+	0x781b, 0x0048, 0x007c, 0x781b, 0x00d8, 0x007c, 0x2009, 0x4d38,
-+	0x200b, 0x000a, 0x007c, 0x2009, 0x4d20, 0x210c, 0xa186, 0x0000,
-+	0x0040, 0x36de, 0xa186, 0x0001, 0x0040, 0x36d8, 0x2009, 0x4d38,
-+	0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x231a,
-+	0x2009, 0x4d38, 0x200b, 0x000a, 0x0078, 0x231a, 0x782b, 0x3008,
-+	0x781b, 0x00d8, 0x0078, 0x231a, 0x781b, 0x00de, 0x0078, 0x231a,
-+	0x782b, 0x3008, 0x781b, 0x00de, 0x0078, 0x231a, 0x781b, 0x009c,
-+	0x0078, 0x231a, 0x782b, 0x3008, 0x781b, 0x009c, 0x0078, 0x231a,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x36ff, 0x681b, 0x001d, 0x706f,
-+	0x0001, 0x781b, 0x0048, 0x0078, 0x231a, 0x007e, 0x7830, 0xa084,
-+	0x00c0, 0x00c0, 0x371b, 0x7808, 0xa084, 0xfffc, 0x780a, 0x0005,
-+	0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x371b,
-+	0x7044, 0x780a, 0xa005, 0x007f, 0x007c, 0x7044, 0xa085, 0x0002,
-+	0x7046, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3723,
-+	0x0098, 0x372c, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
-+	0x373b, 0x0098, 0x3739, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f,
-+	0x007c, 0xa784, 0x007d, 0x00c0, 0x3748, 0x2700, 0x1078, 0x22ac,
-+	0xa784, 0x0001, 0x00c0, 0x2ded, 0xa784, 0x0070, 0x0040, 0x3758,
-+	0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2257, 0x2d78, 0x2c68, 0x0c7f,
-+	0xa784, 0x0008, 0x0040, 0x3765, 0x784b, 0x0008, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x2343, 0x0078, 0x3693, 0xa784, 0x0004, 0x0040,
-+	0x3798, 0x78b8, 0xa084, 0x4001, 0x0040, 0x3798, 0x784b, 0x0008,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x2343, 0x78e4, 0xa084, 0x0007,
-+	0xa086, 0x0001, 0x00c0, 0x3798, 0x78c0, 0xa085, 0x4800, 0x2030,
-+	0x7e5a, 0x781b, 0x00de, 0x0078, 0x231a, 0x784b, 0x0008, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x3794, 0x681b, 0x0015, 0xa684, 0x4000,
-+	0x0040, 0x3794, 0x681b, 0x0007, 0x1078, 0x36a7, 0x0078, 0x231a,
-+	0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x6833, 0x0000,
-+	0x682f, 0x0000, 0x784b, 0x0008, 0x78e4, 0xa005, 0x00d0, 0x2817,
-+	0xa084, 0x0020, 0x0040, 0x2817, 0x78ec, 0xa084, 0x0003, 0x0040,
-+	0x2817, 0x0018, 0x2817, 0x0078, 0x34c6, 0x6b14, 0x8307, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x4f80, 0x2060, 0x2048,
-+	0x7056, 0x6000, 0x705a, 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079,
-+	0x37c9, 0x37d1, 0x37d2, 0x37d1, 0x37d4, 0x37d1, 0x37d1, 0x37d1,
-+	0x37d9, 0x007c, 0x1078, 0x3217, 0x1078, 0x431b, 0x7038, 0x600a,
-+	0x007c, 0x70a0, 0xa005, 0x0040, 0x37e6, 0x2068, 0x1078, 0x1a80,
-+	0x1078, 0x42d4, 0x1078, 0x42db, 0x70a3, 0x0000, 0x007c, 0x0e7e,
-+	0x2091, 0x8000, 0x2071, 0x4d40, 0x7000, 0xa086, 0x0007, 0x00c0,
-+	0x3804, 0x6114, 0x70ac, 0xa106, 0x00c0, 0x3804, 0x6128, 0x70b0,
-+	0xa106, 0x00c0, 0x3804, 0x2c00, 0x70a2, 0x0e7f, 0x1078, 0x1a8d,
-+	0x1078, 0x380a, 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085,
-+	0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x4d40, 0x0078, 0x20c8,
-+	0x785b, 0x0000, 0x70b7, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0,
-+	0xa06d, 0x0040, 0x381f, 0x70a3, 0x0000, 0x0078, 0x3825, 0x70bb,
-+	0x0000, 0x1078, 0x1aa9, 0x0040, 0x382b, 0x70b4, 0x6826, 0x1078,
-+	0x3906, 0x0078, 0x381f, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9,
-+	0x0008, 0x2061, 0x7110, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d,
-+	0x0040, 0x3843, 0x6800, 0x601e, 0x1078, 0x18a0, 0x6008, 0x8000,
-+	0x600a, 0x0078, 0x3836, 0x6018, 0xa06d, 0x0040, 0x384d, 0x6800,
-+	0x601a, 0x1078, 0x18a0, 0x0078, 0x3843, 0xace0, 0x0008, 0x0070,
-+	0x3853, 0x0078, 0x3833, 0x709c, 0xa084, 0x8000, 0x0040, 0x385a,
-+	0x1078, 0x3980, 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091,
-+	0x2300, 0x6804, 0xa084, 0x000f, 0x0079, 0x3866, 0x3876, 0x3876,
-+	0x3876, 0x3876, 0x3876, 0x3876, 0x3878, 0x387e, 0x3876, 0x3876,
-+	0x3876, 0x3876, 0x3876, 0x3880, 0x3876, 0x3878, 0x1078, 0x22ac,
-+	0x1078, 0x4172, 0x1078, 0x18a0, 0x0078, 0x3884, 0x6827, 0x000b,
-+	0x1078, 0x4172, 0x1078, 0x3906, 0x127f, 0x007c, 0x127e, 0x2091,
-+	0x2300, 0x0098, 0x38a2, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x38a2,
-+	0x0d7e, 0x1078, 0x42e4, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001,
-+	0x0000, 0x6827, 0x0084, 0x1078, 0x429c, 0x1078, 0x3906, 0x0d7f,
-+	0x0078, 0x38d4, 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x38ab,
-+	0x794a, 0x0078, 0x3890, 0x7828, 0xa086, 0x1834, 0x00c0, 0x38b4,
-+	0xa185, 0x0004, 0x0078, 0x38bb, 0x7828, 0xa186, 0x1814, 0x00c0,
-+	0x38a8, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002,
-+	0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a, 0x70bc, 0xa080,
-+	0x008d, 0x781a, 0x6827, 0x0002, 0x6827, 0x0084, 0x2009, 0x0004,
-+	0x2001, 0x0000, 0x1078, 0x429c, 0x127f, 0x007c, 0x0d7e, 0x6b14,
-+	0x1078, 0x1b1b, 0x0040, 0x38e3, 0x2068, 0x6827, 0x0002, 0x1078,
-+	0x3906, 0x0078, 0x38d8, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0x6c28,
-+	0xa4a4, 0x00ff, 0x1078, 0x1ab9, 0x0040, 0x38f3, 0x2068, 0x6827,
-+	0x0002, 0x1078, 0x3906, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0xa39c,
-+	0x00ff, 0x1078, 0x1aec, 0x0040, 0x3904, 0x2068, 0x6827, 0x0002,
-+	0x1078, 0x3906, 0x0078, 0x38f9, 0x0d7f, 0x007c, 0x0c7e, 0x6914,
-+	0x1078, 0x3977, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0006, 0x0040,
-+	0x3921, 0xa186, 0x000d, 0x0040, 0x3940, 0xa186, 0x0017, 0x00c0,
-+	0x391d, 0x1078, 0x18a0, 0x0078, 0x391f, 0x1078, 0x1b90, 0x0c7f,
-+	0x007c, 0x6004, 0x8001, 0x0048, 0x393e, 0x6006, 0x2009, 0x0000,
-+	0xa684, 0x0001, 0x00c0, 0x392e, 0xa18d, 0x8000, 0xa684, 0x0004,
-+	0x0040, 0x3934, 0xa18d, 0x0002, 0x6922, 0x681f, 0x0000, 0x7104,
-+	0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x391d, 0x1078, 0x22ac,
-+	0x6018, 0xa005, 0x00c0, 0x394f, 0x6008, 0x8001, 0x0048, 0x394f,
-+	0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, 0x3965, 0xac88,
-+	0x0006, 0x2104, 0xa005, 0x0040, 0x3958, 0x2008, 0x0078, 0x3951,
-+	0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x391f, 0x600a, 0x6018,
-+	0x2068, 0x6800, 0x601a, 0x0078, 0x3949, 0x157e, 0x137e, 0x147e,
-+	0x0c7e, 0x0d7e, 0x1078, 0x187d, 0x2da0, 0x137f, 0x20a9, 0x0031,
-+	0x53a3, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x0078, 0x391d, 0xa184,
-+	0x001f, 0x8003, 0x8003, 0x8003, 0xa080, 0x7110, 0x2060, 0x007c,
-+	0x2019, 0x4d51, 0x2304, 0xa085, 0x0001, 0x201a, 0x2019, 0x0102,
-+	0x2304, 0xa085, 0x0001, 0x201a, 0x007c, 0x2019, 0x4d51, 0x2304,
-+	0xa084, 0xfffe, 0x201a, 0x2019, 0x0102, 0x2304, 0xa084, 0xfffe,
-+	0x201a, 0x007c, 0x0078, 0x231a, 0x70a3, 0x0000, 0x7003, 0x0000,
-+	0x7043, 0x0001, 0x7037, 0x0000, 0x0018, 0x22d1, 0x1078, 0x1aa9,
-+	0x0040, 0x39cf, 0x2009, 0x4d0f, 0x200b, 0x0000, 0x68bc, 0x2060,
-+	0x6100, 0xa184, 0x0300, 0x0040, 0x39c1, 0x6827, 0x000e, 0xa084,
-+	0x0200, 0x0040, 0x39bd, 0x6827, 0x0017, 0x1078, 0x3906, 0x0078,
-+	0x399c, 0x6820, 0xa084, 0x8000, 0x0040, 0x3a11, 0x7000, 0xa086,
-+	0x0007, 0x10c0, 0x22ac, 0x2d00, 0x70a2, 0x0078, 0x39d6, 0x7040,
-+	0xa086, 0x0001, 0x0040, 0x2353, 0x0078, 0x231a, 0x2031, 0x0000,
-+	0x6920, 0xa184, 0x0002, 0x0040, 0x39df, 0xa6b5, 0x0004, 0xa184,
-+	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3a8c, 0x2004, 0xa635,
-+	0x681c, 0xa084, 0x0400, 0x0040, 0x39f7, 0x789b, 0x0018, 0x78ab,
-+	0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0x681c,
-+	0xa084, 0x8000, 0x0040, 0x3a03, 0xa6b5, 0x0400, 0x789b, 0x000e,
-+	0x6824, 0x8007, 0x78aa, 0xa684, 0x0200, 0x0040, 0x3a0d, 0x6830,
-+	0x78d2, 0x682c, 0x78d6, 0x1078, 0x42cc, 0x7e5a, 0x6eb6, 0x0078,
-+	0x4303, 0x1078, 0x3705, 0x00c0, 0x3a86, 0x702c, 0x8004, 0x0048,
-+	0x3a1f, 0x2019, 0x4a07, 0x1078, 0x2137, 0x702f, 0x0001, 0x2011,
-+	0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814, 0xa084, 0x001f,
-+	0xa085, 0x0080, 0x78aa, 0x6920, 0xa184, 0x0002, 0x0040, 0x3a38,
-+	0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa, 0xa290, 0x0002,
-+	0x681c, 0xa084, 0x8000, 0x0040, 0x3a46, 0xa6b5, 0x0400, 0x789b,
-+	0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3a54, 0x6820, 0xa084,
-+	0x8000, 0x00c0, 0x3a54, 0xa6b5, 0x0800, 0x681c, 0xa084, 0x0100,
-+	0x0040, 0x3a54, 0xa6b5, 0x4000, 0x6820, 0xa084, 0x00c0, 0x8003,
-+	0x8003, 0x8007, 0xa080, 0x3a8c, 0x2004, 0xa635, 0x789b, 0x007e,
-+	0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7aaa, 0x7830, 0xa084,
-+	0x00c0, 0x00c0, 0x3a86, 0x0018, 0x3a86, 0x70bc, 0xa080, 0x00dd,
-+	0x781a, 0x1078, 0x371d, 0xa684, 0x0200, 0x0040, 0x3a7d, 0x6830,
-+	0x78d2, 0x682c, 0x78d6, 0x1078, 0x42cc, 0x2d00, 0x70a2, 0x7003,
-+	0x0007, 0xad80, 0x000f, 0x7036, 0x0078, 0x231a, 0x1078, 0x1a80,
-+	0x1078, 0x371d, 0x0078, 0x231a, 0x0000, 0x0300, 0x0200, 0x0000,
-+	0x1078, 0x22ac, 0x2300, 0x0079, 0x3a95, 0x3a98, 0x3a98, 0x3a9a,
-+	0x1078, 0x22ac, 0x1078, 0x42db, 0x6924, 0xa184, 0x00ff, 0xa086,
-+	0x000a, 0x0040, 0x3aac, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826,
-+	0x1078, 0x1a80, 0x0078, 0x399c, 0x2001, 0x000a, 0x1078, 0x4254,
-+	0x0078, 0x399c, 0xa282, 0x0005, 0x0050, 0x3ab8, 0x1078, 0x22ac,
-+	0x7000, 0xa084, 0x0007, 0x10c0, 0x37c7, 0x1078, 0x187d, 0x6807,
-+	0x0106, 0x680b, 0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0x1078,
-+	0x3e02, 0x2d00, 0x70a2, 0x7003, 0x0007, 0x6014, 0x68ba, 0xad80,
-+	0x002e, 0x7036, 0x6824, 0xa084, 0x0080, 0x0040, 0x3adb, 0x1078,
-+	0x3ea9, 0x0078, 0x231a, 0x2300, 0x0079, 0x3ade, 0x3ae1, 0x3b59,
-+	0x3b78, 0x2200, 0x0079, 0x3ae4, 0x3ae9, 0x3af9, 0x3b1f, 0x3b29,
-+	0x3b4a, 0x2029, 0x0001, 0xa026, 0x2011, 0x0000, 0x1078, 0x3f97,
-+	0x0079, 0x3af2, 0x3af7, 0x231a, 0x399c, 0x3af7, 0x3af7, 0x1078,
-+	0x22ac, 0x7990, 0xa18c, 0x0007, 0x00c0, 0x3b00, 0x2009, 0x0008,
-+	0x2011, 0x0001, 0xa684, 0x0004, 0x0040, 0x3b08, 0x2011, 0x0003,
-+	0x2220, 0xa12a, 0x2011, 0x0001, 0x1078, 0x3f97, 0x0079, 0x3b10,
-+	0x3b15, 0x231a, 0x399c, 0x3b1d, 0x3b17, 0x0078, 0x4309, 0x70ab,
-+	0x3b1b, 0x0078, 0x231a, 0x0078, 0x3b15, 0x1078, 0x22ac, 0xa684,
-+	0x0010, 0x0040, 0x3b27, 0x1078, 0x3e79, 0x0078, 0x231a, 0x0078,
-+	0x3eda, 0x6000, 0xa084, 0x0002, 0x0040, 0x3b44, 0x70bc, 0xa080,
-+	0x00c4, 0x781a, 0x0d7e, 0x1078, 0x42e4, 0x2d00, 0x682e, 0x6827,
-+	0x0000, 0x1078, 0x3906, 0x0d7f, 0x1078, 0x18a0, 0x7003, 0x0000,
-+	0x7037, 0x0000, 0x0078, 0x399c, 0xa684, 0x0004, 0x00c0, 0x3b4a,
-+	0x0078, 0x4309, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3b57, 0x70ab,
-+	0x3b57, 0x2001, 0x0007, 0x1078, 0x424c, 0x0078, 0x430f, 0x0078,
-+	0x4309, 0x2200, 0x0079, 0x3b5c, 0x3b61, 0x3b61, 0x3b61, 0x3b63,
-+	0x3b61, 0x1078, 0x22ac, 0x70a7, 0x3b67, 0x0078, 0x4315, 0x2011,
-+	0x0018, 0x1078, 0x3f91, 0x0079, 0x3b6d, 0x3b72, 0x231a, 0x399c,
-+	0x3b74, 0x3b76, 0x1078, 0x22ac, 0x1078, 0x22ac, 0x1078, 0x22ac,
-+	0x2200, 0x0079, 0x3b7b, 0x3b80, 0x3b80, 0x3b82, 0x3b80, 0x3b80,
-+	0x1078, 0x22ac, 0x70ab, 0x3b8a, 0x2001, 0x0003, 0x1078, 0x424c,
-+	0x0078, 0x430f, 0x0078, 0x4309, 0xa282, 0x0003, 0x0050, 0x3b92,
-+	0x1078, 0x22ac, 0xa684, 0x0008, 0x0040, 0x3b98, 0x1078, 0x3e57,
-+	0x7003, 0x0007, 0x2300, 0x0079, 0x3b9d, 0x3ba0, 0x3bcb, 0x3bd3,
-+	0x2200, 0x0079, 0x3ba3, 0x3ba8, 0x3ba6, 0x3bc1, 0x1078, 0x22ac,
-+	0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x3f97,
-+	0x0079, 0x3bb2, 0x3bb7, 0x231a, 0x399c, 0x3bbf, 0x3bb9, 0x0078,
-+	0x4309, 0x70ab, 0x3bbd, 0x0078, 0x231a, 0x0078, 0x3bb7, 0x1078,
-+	0x22ac, 0xa684, 0x0010, 0x0040, 0x3bc9, 0x1078, 0x3e79, 0x0078,
-+	0x231a, 0x0078, 0x3eda, 0x2200, 0x0079, 0x3bce, 0x3bd1, 0x3bd1,
-+	0x3bd1, 0x1078, 0x22ac, 0x2200, 0x0079, 0x3bd6, 0x3bd9, 0x3bd9,
-+	0x3bdb, 0x1078, 0x22ac, 0x70ab, 0x3be3, 0x2001, 0x0003, 0x1078,
-+	0x424c, 0x0078, 0x430f, 0x0078, 0x4309, 0x2300, 0x0079, 0x3be8,
-+	0x3bed, 0x3bef, 0x3beb, 0x1078, 0x22ac, 0x70a4, 0x007a, 0x70a4,
-+	0x007a, 0xa282, 0x0002, 0x0050, 0x3bf7, 0x1078, 0x22ac, 0xa684,
-+	0x0200, 0x0040, 0x3c01, 0x1078, 0x42d4, 0x1078, 0x3f79, 0x1078,
-+	0x42db, 0x2300, 0x0079, 0x3c04, 0x3c07, 0x3c1d, 0x3c77, 0xa286,
-+	0x0001, 0x0040, 0x3c0d, 0x1078, 0x22ac, 0xa684, 0x0200, 0x0040,
-+	0x3c15, 0x1078, 0x42d4, 0x1078, 0x42db, 0x2001, 0x0001, 0x1078,
-+	0x4254, 0x7003, 0x0000, 0x0078, 0x399c, 0x2200, 0x0079, 0x3c20,
-+	0x3c22, 0x3c47, 0x70a7, 0x3c26, 0x0078, 0x4315, 0x2011, 0x000d,
-+	0x1078, 0x3f91, 0x0079, 0x3c2c, 0x3c31, 0x231a, 0x399c, 0x3c39,
-+	0x3c41, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078,
-+	0x4303, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078,
-+	0x4303, 0x70ab, 0x3c45, 0x0078, 0x231a, 0x0078, 0x3c31, 0x70a7,
-+	0x3c4b, 0x0078, 0x4315, 0x2011, 0x0012, 0x1078, 0x3f91, 0x0079,
-+	0x3c51, 0x3c57, 0x231a, 0x399c, 0x3c63, 0x3c6b, 0x3c71, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70bc, 0xa080, 0x00a1,
-+	0x781a, 0x0078, 0x231a, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6,
-+	0x7e5a, 0x0078, 0x4303, 0x70ab, 0x3c6f, 0x0078, 0x231a, 0x0078,
-+	0x3c57, 0x70ab, 0x3c75, 0x0078, 0x231a, 0x0078, 0x3c63, 0xa286,
-+	0x0001, 0x0040, 0x3c7d, 0x1078, 0x22ac, 0x70a7, 0x3c81, 0x0078,
-+	0x4315, 0x2011, 0x0015, 0x1078, 0x3f91, 0x0079, 0x3c87, 0x3c8c,
-+	0x231a, 0x399c, 0x3c94, 0x3c9c, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
-+	0x6eb6, 0x7e5a, 0x0078, 0x4303, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
-+	0x6eb6, 0x7e5a, 0x0078, 0x4303, 0x70ab, 0x3ca0, 0x0078, 0x231a,
-+	0x0078, 0x3c8c, 0xa282, 0x0002, 0x0050, 0x3ca8, 0x1078, 0x22ac,
-+	0x2300, 0x0079, 0x3cab, 0x3cae, 0x3cd7, 0x3d26, 0xa286, 0x0001,
-+	0x0040, 0x3cb4, 0x1078, 0x22ac, 0x6804, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x00c0, 0x3cc1, 0x1078, 0x3906, 0x7003, 0x0000, 0x0078,
-+	0x399c, 0x6837, 0x0000, 0x683b, 0x0000, 0xa684, 0x0200, 0x0040,
-+	0x3ccf, 0x1078, 0x42d4, 0x1078, 0x3f79, 0x1078, 0x42db, 0x2001,
-+	0x0001, 0x1078, 0x4254, 0x7003, 0x0000, 0x0078, 0x399c, 0x2200,
-+	0x0079, 0x3cda, 0x3cdc, 0x3d01, 0x70a7, 0x3ce0, 0x0078, 0x4315,
-+	0x2011, 0x000d, 0x1078, 0x3f91, 0x0079, 0x3ce6, 0x3ceb, 0x231a,
-+	0x399c, 0x3cf3, 0x3cfb, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6,
-+	0x7e5a, 0x0078, 0x4303, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6,
-+	0x7e5a, 0x0078, 0x4303, 0x70ab, 0x3cff, 0x0078, 0x231a, 0x0078,
-+	0x3ceb, 0x70a7, 0x3d05, 0x0078, 0x4315, 0x2011, 0x0005, 0x1078,
-+	0x3f91, 0x0079, 0x3d0b, 0x3d10, 0x231a, 0x399c, 0x3d18, 0x3d20,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4303,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4303,
-+	0x70ab, 0x3d24, 0x0078, 0x231a, 0x0078, 0x3d10, 0xa286, 0x0001,
-+	0x0040, 0x3d2c, 0x1078, 0x22ac, 0x70a7, 0x3d30, 0x0078, 0x4315,
-+	0x2011, 0x0006, 0x1078, 0x3f91, 0x0079, 0x3d36, 0x3d3b, 0x231a,
-+	0x399c, 0x3d41, 0x3d43, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078,
-+	0x4303, 0x1078, 0x22ac, 0x70ab, 0x3d47, 0x0078, 0x231a, 0x0078,
-+	0x3d3b, 0x2300, 0x0079, 0x3d4c, 0x3d51, 0x3d4f, 0x3d4f, 0x1078,
-+	0x22ac, 0x1078, 0x22ac, 0x2300, 0x71a8, 0xa005, 0x017a, 0xa282,
-+	0x0002, 0x0050, 0x3d5d, 0x1078, 0x22ac, 0x2300, 0x0079, 0x3d60,
-+	0x3d63, 0x3d76, 0x3d94, 0x82ff, 0x00c0, 0x3d68, 0x1078, 0x22ac,
-+	0xa684, 0x0200, 0x0040, 0x3d70, 0x1078, 0x42d4, 0x1078, 0x42db,
-+	0x2001, 0x0001, 0x1078, 0x4254, 0x0078, 0x231a, 0x82ff, 0x0040,
-+	0x3d7b, 0x1078, 0x22ac, 0x70a7, 0x3d7f, 0x0078, 0x4315, 0x2011,
-+	0x0018, 0x1078, 0x3f91, 0x0079, 0x3d85, 0x3d8a, 0x231a, 0x399c,
-+	0x3d8c, 0x3d8e, 0x0078, 0x4303, 0x0078, 0x4303, 0x70ab, 0x3d92,
-+	0x0078, 0x231a, 0x0078, 0x3d8a, 0x2200, 0x0079, 0x3d97, 0x3d99,
-+	0x3db2, 0x70a7, 0x3d9d, 0x0078, 0x4315, 0x2011, 0x0018, 0x1078,
-+	0x3f91, 0x0079, 0x3da3, 0x3da8, 0x231a, 0x399c, 0x3daa, 0x3dac,
-+	0x0078, 0x4303, 0x0078, 0x4303, 0x70ab, 0x3db0, 0x0078, 0x231a,
-+	0x0078, 0x3da8, 0xa484, 0x8000, 0x00c0, 0x3df0, 0xa684, 0x0100,
-+	0x0040, 0x3dc6, 0x1078, 0x42d4, 0x1078, 0x3f79, 0x1078, 0x42db,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x0078, 0x3dca, 0x78d8, 0x78d2,
-+	0x78dc, 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x3dd1, 0x0078,
-+	0x4315, 0x2011, 0x000d, 0x1078, 0x3f91, 0x0079, 0x3dd7, 0x3ddc,
-+	0x231a, 0x399c, 0x3ddc, 0x3dea, 0xa684, 0x0100, 0x0040, 0x3de8,
-+	0x1078, 0x4291, 0x6830, 0x78d2, 0x682c, 0x78d6, 0x1078, 0x42cc,
-+	0x0078, 0x4303, 0x70ab, 0x3dee, 0x0078, 0x231a, 0x0078, 0x3ddc,
-+	0x1078, 0x42db, 0x70ab, 0x3dfa, 0x2001, 0x0003, 0x1078, 0x424c,
-+	0x0078, 0x430f, 0x1078, 0x42cc, 0x6830, 0x78d2, 0x682c, 0x78d6,
-+	0x0078, 0x4303, 0x681b, 0x0000, 0xa684, 0x0008, 0x0040, 0x3e20,
-+	0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004,
-+	0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80, 0x002c,
-+	0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f, 0x157f,
-+	0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x3e2d, 0x692c, 0x810f,
-+	0x810d, 0x810d, 0x810d, 0x0078, 0x3e3a, 0x789b, 0x0010, 0x79ac,
-+	0x0078, 0x3e3a, 0x017e, 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078,
-+	0x429c, 0x017f, 0xa184, 0x001f, 0xa805, 0x6816, 0x1078, 0x3977,
-+	0x68be, 0xa684, 0x0004, 0x0040, 0x3e4b, 0xa18c, 0xff00, 0x78a8,
-+	0xa084, 0x00ff, 0xa105, 0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084,
-+	0x0008, 0x0040, 0x3e55, 0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e,
-+	0x137e, 0x147e, 0x6918, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004,
-+	0xa084, 0x000f, 0x007e, 0xa100, 0x681a, 0x007f, 0x8004, 0x0040,
-+	0x3e75, 0x20a8, 0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b,
-+	0x0000, 0xaf80, 0x002c, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f,
-+	0x007c, 0x682c, 0xa084, 0x2000, 0x00c0, 0x3e81, 0x620c, 0x0078,
-+	0x3e82, 0x6210, 0x6b18, 0x2300, 0xa202, 0x0040, 0x3ea0, 0x2018,
-+	0xa382, 0x000e, 0x0048, 0x3e92, 0x0040, 0x3e92, 0x2019, 0x000e,
-+	0x0078, 0x3e96, 0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b02,
-+	0x7893, 0x0000, 0x7ba2, 0x70bc, 0xa080, 0x008a, 0x781a, 0x007c,
-+	0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b02, 0x7893, 0x0000,
-+	0x007c, 0x6807, 0x0117, 0x6914, 0x1078, 0x3977, 0x6100, 0x8104,
-+	0x00c8, 0x3ec6, 0x601c, 0xa005, 0x0040, 0x3eba, 0x2001, 0x0800,
-+	0x0078, 0x3ec8, 0x0d7e, 0x6824, 0x007e, 0x1078, 0x42e4, 0x007f,
-+	0x6826, 0x2d00, 0x682e, 0x1078, 0x3906, 0x0d7f, 0x2001, 0x0200,
-+	0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x681c, 0xa085, 0x8000,
-+	0x681e, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71bc, 0xa188, 0x008d,
-+	0x791a, 0x007c, 0x6914, 0x1078, 0x3977, 0x6100, 0x8104, 0x00c8,
-+	0x3f27, 0xa184, 0x0300, 0x0040, 0x3ee9, 0x6807, 0x0117, 0x0078,
-+	0x3f07, 0x6004, 0xa005, 0x00c0, 0x3f10, 0x6807, 0x0117, 0x601c,
-+	0xa005, 0x00c0, 0x3efd, 0x0d7e, 0x1078, 0x42e4, 0x6827, 0x0034,
-+	0x2d00, 0x682e, 0x1078, 0x3906, 0x0d7f, 0xa684, 0x0004, 0x0040,
-+	0x3f07, 0x2031, 0x0400, 0x2001, 0x2800, 0x0078, 0x3f0b, 0x2031,
-+	0x0400, 0x2001, 0x0800, 0x71bc, 0xa188, 0x008d, 0x0078, 0x3f56,
-+	0x6018, 0xa005, 0x00c0, 0x3efd, 0x601c, 0xa005, 0x00c0, 0x3efd,
-+	0x689f, 0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x3f64,
-+	0xa6b5, 0x0800, 0x71bc, 0xa188, 0x00a5, 0x0078, 0x3f5f, 0x6807,
-+	0x0117, 0x2031, 0x0400, 0x692c, 0x810f, 0xa18c, 0x00ff, 0xa186,
-+	0x0012, 0x00c0, 0x3f39, 0x2001, 0x3f6f, 0x2009, 0x0001, 0x0078,
-+	0x3f4a, 0xa186, 0x0003, 0x00c0, 0x3f43, 0x2001, 0x3f70, 0x2009,
-+	0x0012, 0x0078, 0x3f4a, 0x2001, 0x0200, 0x71bc, 0xa188, 0x008d,
-+	0x0078, 0x3f56, 0x1078, 0x42b7, 0x78a3, 0x0000, 0x6820, 0xa085,
-+	0x0040, 0x6822, 0x71bc, 0xa188, 0x00da, 0xa006, 0x6826, 0x8007,
-+	0x789b, 0x000e, 0x78aa, 0x681c, 0xa085, 0x8000, 0x681e, 0x6eb6,
-+	0x7e5a, 0x791a, 0x0078, 0x231a, 0x6eb6, 0x1078, 0x3906, 0x6814,
-+	0x70ae, 0x6828, 0x70b2, 0x7003, 0x0007, 0x0078, 0x231a, 0x0023,
-+	0x0070, 0x0005, 0x0000, 0x0a00, 0x0000, 0x0000, 0x0025, 0x0000,
-+	0x0000, 0x6837, 0x0000, 0x683b, 0x0000, 0xa684, 0x0200, 0x0040,
-+	0x3f90, 0x78b8, 0xa08c, 0x001f, 0xa084, 0x8000, 0x0040, 0x3f89,
-+	0x8108, 0x78d8, 0xa100, 0x683a, 0x78dc, 0xa081, 0x0000, 0x6836,
-+	0x007c, 0x7990, 0x810f, 0xa5ac, 0x0007, 0x2021, 0x0000, 0xa480,
-+	0x0010, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa184, 0x0080, 0x00c0,
-+	0x3fbf, 0xa182, 0x0020, 0x00c8, 0x3fd9, 0xa182, 0x0012, 0x00c8,
-+	0x4241, 0x2100, 0x1079, 0x3fad, 0x007c, 0x4241, 0x418a, 0x4241,
-+	0x4241, 0x3fe6, 0x3fe9, 0x4023, 0x4063, 0x4093, 0x4096, 0x4241,
-+	0x4241, 0x4045, 0x40b8, 0x40f3, 0x4241, 0x4241, 0x411b, 0xa18c,
-+	0x001f, 0x6814, 0xa084, 0x001f, 0xa106, 0x0040, 0x3fd6, 0x70bc,
-+	0xa080, 0x00c4, 0x781a, 0x2001, 0x0014, 0x1078, 0x4254, 0x1078,
-+	0x42db, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000,
-+	0x007c, 0xa182, 0x0024, 0x00c8, 0x4241, 0xa184, 0x0003, 0x1079,
-+	0x3fad, 0x007c, 0x4241, 0x4241, 0x4241, 0x4241, 0x1078, 0x4241,
-+	0x007c, 0x2200, 0x0079, 0x3fec, 0x411e, 0x411e, 0x4010, 0x4010,
-+	0x4010, 0x4010, 0x4010, 0x4010, 0x4010, 0x4010, 0x400e, 0x4010,
-+	0x4005, 0x4010, 0x4010, 0x4010, 0x4010, 0x4010, 0x4018, 0x401b,
-+	0x411e, 0x401b, 0x4010, 0x4010, 0x4010, 0x0c7e, 0x077e, 0x6f14,
-+	0x1078, 0x34f9, 0x077f, 0x0c7f, 0x0078, 0x4010, 0x1078, 0x41df,
-+	0x6827, 0x02b3, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x414e,
-+	0x1078, 0x4236, 0x007c, 0x6827, 0x0293, 0x2009, 0x000b, 0x2001,
-+	0x4800, 0x0078, 0x413a, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x00c0, 0x402d, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
-+	0x42e4, 0x6827, 0x0036, 0x810f, 0x6932, 0x2d00, 0x682e, 0x0d7e,
-+	0x1078, 0x38d6, 0x1078, 0x4172, 0x2b68, 0x1078, 0x3906, 0x0d7f,
-+	0x1078, 0x3906, 0x2001, 0x0002, 0x007c, 0x1078, 0x4172, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4056, 0xa186, 0x000f,
-+	0x0040, 0x4056, 0x1078, 0x18a0, 0x70a3, 0x0000, 0x2009, 0x4d38,
-+	0x200b, 0x0006, 0x70b7, 0x0017, 0x2009, 0x0200, 0x1078, 0x3816,
-+	0x2001, 0x0001, 0x007c, 0x2200, 0x0079, 0x4066, 0x411e, 0x414b,
-+	0x414b, 0x414b, 0x4085, 0x415b, 0x415b, 0x415b, 0x415b, 0x415e,
-+	0x415e, 0x4163, 0x4163, 0x407f, 0x407f, 0x414b, 0x414b, 0x415b,
-+	0x414b, 0x408b, 0x411e, 0x408b, 0x408b, 0x415b, 0x408b, 0x2009,
-+	0x000b, 0x2001, 0x4300, 0x0078, 0x416d, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x414e, 0x6827, 0x0293, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x413a, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079,
-+	0x4099, 0x411e, 0x40b2, 0x40b2, 0x40b2, 0x40b2, 0x415b, 0x415b,
-+	0x415b, 0x415b, 0x415b, 0x415b, 0x415b, 0x415b, 0x40b2, 0x40b2,
-+	0x40b2, 0x40b2, 0x415b, 0x40b2, 0x40b2, 0x415b, 0x415b, 0x415b,
-+	0x415b, 0x411e, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, 0x413a,
-+	0xa684, 0x0004, 0x00c0, 0x40cc, 0x6804, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x00c0, 0x4241, 0x1078, 0x4172, 0x6807, 0x0117, 0x1078,
-+	0x3906, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040,
-+	0x4241, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-+	0x40db, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x42e4, 0x6827,
-+	0x0036, 0x810f, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x38e5,
-+	0x1078, 0x4172, 0x2b68, 0x1078, 0x3906, 0x0d7f, 0x1078, 0x3906,
-+	0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, 0x4241,
-+	0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0, 0x4102,
-+	0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x42e4, 0x6827,
-+	0x0036, 0x810f, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x38f5,
-+	0x1078, 0x4172, 0x2b68, 0x1078, 0x3906, 0x0d7f, 0x1078, 0x3906,
-+	0x2001, 0x0002, 0x007c, 0x1078, 0x4241, 0x007c, 0x70bc, 0xa080,
-+	0x00c4, 0x781a, 0x2001, 0x0001, 0x1078, 0x4254, 0x1078, 0x42db,
-+	0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x429c, 0x1078,
-+	0x42d4, 0x1078, 0x3f79, 0x1078, 0x3ea9, 0x1078, 0x42db, 0x2001,
-+	0x0001, 0x007c, 0x1078, 0x429c, 0x1078, 0x42d4, 0x1078, 0x3f79,
-+	0x70bc, 0xa080, 0x00c4, 0x781a, 0x1078, 0x42db, 0x7003, 0x0000,
-+	0x2001, 0x0002, 0x007c, 0x1078, 0x4241, 0x007c, 0x1078, 0x429c,
-+	0x1078, 0x42d4, 0x1078, 0x3f79, 0x1078, 0x3ea9, 0x1078, 0x42db,
-+	0x2001, 0x0001, 0x007c, 0x2001, 0x0003, 0x007c, 0x1078, 0x41df,
-+	0x2001, 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x34f9,
-+	0x077f, 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, 0x429c, 0x1078,
-+	0x4241, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040,
-+	0x417d, 0xa186, 0x000f, 0x00c0, 0x4181, 0x1078, 0x42d4, 0x1078,
-+	0x3f79, 0x70bc, 0xa080, 0x00c4, 0x781a, 0x1078, 0x42db, 0x7003,
-+	0x0000, 0x007c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff,
-+	0xa08a, 0x0004, 0x00c8, 0x4241, 0x1079, 0x4197, 0x007c, 0x4241,
-+	0x419b, 0x4241, 0x41ed, 0xa282, 0x0003, 0x0040, 0x41a2, 0x1078,
-+	0x4241, 0x007c, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff,
-+	0xa482, 0x000c, 0x0048, 0x41b0, 0x0040, 0x41b0, 0x2021, 0x000c,
-+	0x701c, 0xa502, 0x00c8, 0x41b5, 0x751c, 0x1078, 0x4227, 0x852b,
-+	0x852b, 0x1078, 0x3577, 0x0040, 0x41c1, 0x1078, 0x41d1, 0x0078,
-+	0x41c5, 0x1078, 0x4223, 0x1078, 0x41df, 0xa6b5, 0x1000, 0x789b,
-+	0x007e, 0x7ea6, 0x70bc, 0xa080, 0x00b0, 0x781a, 0x2001, 0x0004,
-+	0x007c, 0x0c7e, 0x6914, 0x810f, 0xa18c, 0x000f, 0x810b, 0x810b,
-+	0x810b, 0xa1e0, 0x4f80, 0x1078, 0x338b, 0x0c7f, 0x007c, 0x0c7e,
-+	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-+	0x4f80, 0x1078, 0x33b2, 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0,
-+	0x4241, 0x7aa8, 0xa294, 0x00ff, 0xa284, 0xfffe, 0x0040, 0x41fa,
-+	0x2011, 0x0001, 0x1078, 0x4215, 0x1078, 0x4207, 0x1078, 0x41df,
-+	0x70bc, 0xa080, 0x00b0, 0x781a, 0x2001, 0x0004, 0x007c, 0x0c7e,
-+	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-+	0x4f80, 0x1078, 0x3457, 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab,
-+	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081,
-+	0x78ab, 0x0004, 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b,
-+	0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-+	0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003,
-+	0x1078, 0x424c, 0x70bc, 0xa080, 0x00b0, 0x781a, 0x2001, 0x0005,
-+	0x007c, 0x2001, 0x0007, 0x1078, 0x424c, 0x70bc, 0xa080, 0x00b0,
-+	0x781a, 0x2001, 0x0004, 0x007c, 0x789b, 0x0018, 0x78aa, 0x789b,
-+	0x0081, 0x78ab, 0x0001, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196,
-+	0x0007, 0x0040, 0x4262, 0xa196, 0x000f, 0x0040, 0x4262, 0x1078,
-+	0x18a0, 0x007c, 0x6924, 0xa194, 0x003f, 0x00c0, 0x426b, 0xa18c,
-+	0xffc0, 0xa105, 0x6826, 0x1078, 0x3906, 0x6920, 0xa184, 0x0100,
-+	0x0040, 0x4290, 0x6824, 0xa084, 0x0001, 0x0040, 0x4290, 0x6b14,
-+	0xa184, 0x0002, 0x00c0, 0x4280, 0x1078, 0x1b1b, 0x0078, 0x4285,
-+	0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1ab9, 0x0d7e, 0x2068, 0x1078,
-+	0x18a0, 0x0d7f, 0x6914, 0x1078, 0x3977, 0x6204, 0x8210, 0x6206,
-+	0x007c, 0x6930, 0x6838, 0x6832, 0xa112, 0x692c, 0x6834, 0x682e,
-+	0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e, 0xade0, 0x0018, 0x6003,
-+	0x7000, 0x810f, 0x6106, 0x600b, 0x0000, 0x600f, 0x000a, 0x6013,
-+	0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f, 0x0000, 0x6023,
-+	0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826, 0x007c, 0x157e,
-+	0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0, 0x81ac, 0x0040,
-+	0x42c2, 0x53a6, 0xa184, 0x0001, 0x0040, 0x42c8, 0x3304, 0x78be,
-+	0x147f, 0x137f, 0x157f, 0x007c, 0x70b8, 0xa005, 0x10c0, 0x22ac,
-+	0x70bb, 0x8000, 0x0078, 0x45ed, 0x71b8, 0x81ff, 0x0040, 0x42da,
-+	0x1078, 0x46d8, 0x007c, 0x71b8, 0x81ff, 0x0040, 0x42e3, 0x70bb,
-+	0x0000, 0x1078, 0x431b, 0x007c, 0x0c7e, 0x0d7e, 0x1078, 0x187d,
-+	0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98, 0x20a9, 0x0031,
-+	0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d, 0x680b, 0x0000,
-+	0x7004, 0x8007, 0x681a, 0x681f, 0x0000, 0x6823, 0x0000, 0x689f,
-+	0x0000, 0x0c7f, 0x007c, 0x70bc, 0xa080, 0x008d, 0x781a, 0x0078,
-+	0x231a, 0x70bc, 0xa080, 0x007d, 0x781a, 0x0078, 0x231a, 0x70bc,
-+	0xa080, 0x00b0, 0x781a, 0x0078, 0x231a, 0x70bc, 0xa080, 0x00ba,
-+	0x781a, 0x0078, 0x231a, 0x127e, 0x2091, 0x2200, 0x2049, 0x431b,
-+	0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008, 0xa084, 0xfffd,
-+	0xa205, 0x0040, 0x432d, 0x0078, 0x4332, 0x7003, 0x0000, 0x127f,
-+	0x2000, 0x007c, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4360, 0x7108,
-+	0x8104, 0x00c8, 0x433f, 0x1078, 0x4462, 0x0078, 0x4337, 0x700c,
-+	0xa08c, 0x00ff, 0x0040, 0x4360, 0x7004, 0x8004, 0x00c8, 0x4357,
-+	0x7014, 0xa005, 0x00c0, 0x4353, 0x7010, 0xa005, 0x0040, 0x4357,
-+	0xa102, 0x00c8, 0x4337, 0x7007, 0x0010, 0x0078, 0x4360, 0x8aff,
-+	0x0040, 0x4360, 0x1078, 0x46ba, 0x00c0, 0x435a, 0x0040, 0x4337,
-+	0x1078, 0x43eb, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x017e,
-+	0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4373, 0xa18e,
-+	0x000f, 0x00c0, 0x4376, 0x6040, 0x0078, 0x4377, 0x6428, 0x017f,
-+	0x84ff, 0x0040, 0x43a1, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8,
-+	0x43b1, 0x273c, 0x87fb, 0x00c0, 0x438f, 0x0048, 0x4389, 0x1078,
-+	0x22ac, 0x609c, 0xa075, 0x0040, 0x43a1, 0x0078, 0x437c, 0x2704,
-+	0xae68, 0x680c, 0xa630, 0x6808, 0xa529, 0x8421, 0x0040, 0x43a1,
-+	0x8738, 0x2704, 0xa005, 0x00c0, 0x4390, 0x709c, 0xa075, 0x00c0,
-+	0x437c, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015,
-+	0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
-+	0x0000, 0x0000, 0x43a6, 0x43a3, 0x0000, 0x0000, 0x8000, 0x0000,
-+	0x43a6, 0x0000, 0x43ae, 0x43ab, 0x0000, 0x0000, 0x0000, 0x0000,
-+	0x43ae, 0x0000, 0x43a9, 0x43a9, 0x0000, 0x0000, 0x8000, 0x0000,
-+	0x43a9, 0x0000, 0x43af, 0x43af, 0x0000, 0x0000, 0x0000, 0x0000,
-+	0x43af, 0x127e, 0x2091, 0x2200, 0x2079, 0x4d00, 0x2071, 0x0010,
-+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071, 0x0020,
-+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049, 0x0000,
-+	0x127f, 0x2000, 0x007c, 0x2049, 0x43eb, 0x2019, 0x0000, 0x7004,
-+	0x8004, 0x00c8, 0x443e, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106,
-+	0x00c0, 0x43f5, 0xa184, 0x000c, 0x0040, 0x4400, 0x1078, 0x22ac,
-+	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x440b, 0xa184,
-+	0x0000, 0x00c0, 0x43f5, 0xa19c, 0x0032, 0xa386, 0x0030, 0x0040,
-+	0x4419, 0xa386, 0x0002, 0x0040, 0x4424, 0xa386, 0x0032, 0x00c0,
-+	0x43f5, 0x7200, 0x8204, 0x0048, 0x4424, 0x730c, 0xa384, 0x00ff,
-+	0x0040, 0x4424, 0x1078, 0x22ac, 0x7007, 0x0012, 0x7000, 0xa084,
-+	0x0001, 0x00c0, 0x443e, 0x7008, 0xa084, 0x000c, 0x00c0, 0x443e,
-+	0x7310, 0x7014, 0xa305, 0x0040, 0x443e, 0x710c, 0xa184, 0x0300,
-+	0x00c0, 0x443e, 0xa184, 0x00ff, 0x00c0, 0x43eb, 0x7007, 0x0012,
-+	0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x4442, 0x7007,
-+	0x0012, 0x7108, 0x8104, 0x0048, 0x4447, 0x7003, 0x0000, 0x2049,
-+	0x0000, 0x007c, 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200,
-+	0x7108, 0x1078, 0x4462, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f,
-+	0x107f, 0x007c, 0x7204, 0x7500, 0x730c, 0xa384, 0x0300, 0x00c0,
-+	0x4497, 0xa184, 0x000c, 0x00c0, 0x44bb, 0x7108, 0xa184, 0x000c,
-+	0x00c0, 0x44bb, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
-+	0x447d, 0xa184, 0x0000, 0x00c0, 0x446d, 0xa184, 0x00c0, 0x8004,
-+	0x8004, 0x8004, 0x8004, 0x8004, 0x8004, 0xa18c, 0x0030, 0xa18e,
-+	0x0030, 0x00c0, 0x448d, 0xa085, 0x0004, 0x0079, 0x448f, 0x4499,
-+	0x44ab, 0x4497, 0x44ab, 0x4497, 0x44f7, 0x4497, 0x44f5, 0x1078,
-+	0x22ac, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff,
-+	0x00c0, 0x44a6, 0x2049, 0x0000, 0x0078, 0x44aa, 0x1078, 0x46ba,
-+	0x00c0, 0x44a6, 0x007c, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002,
-+	0x7006, 0x8aff, 0x00c0, 0x44b6, 0x0078, 0x44ba, 0x1078, 0x46ba,
-+	0x00c0, 0x44b6, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x44be,
-+	0x2091, 0x6000, 0x00e0, 0x44c2, 0x2091, 0x6000, 0x7007, 0x0012,
-+	0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x44ca, 0x7007,
-+	0x0012, 0x7108, 0x8104, 0x0048, 0x44cf, 0x7003, 0x0000, 0x7000,
-+	0xa005, 0x00c0, 0x44e3, 0x7004, 0xa005, 0x00c0, 0x44e3, 0x700c,
-+	0xa005, 0x0040, 0x44e5, 0x0078, 0x44c6, 0x2049, 0x0000, 0x1078,
-+	0x3616, 0x6818, 0xa084, 0x8000, 0x0040, 0x44f0, 0x681b, 0x0002,
-+	0x007c, 0x1078, 0x22ac, 0x1078, 0x22ac, 0x1078, 0x4553, 0x7210,
-+	0x7114, 0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189,
-+	0x0000, 0x1078, 0x4553, 0x2704, 0x2c58, 0xac60, 0x630c, 0x2200,
-+	0xa322, 0x6308, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x451a,
-+	0x00c8, 0x451a, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60,
-+	0x0078, 0x4501, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008,
-+	0x0040, 0x4526, 0xa7ba, 0x43ab, 0x0078, 0x4528, 0xa7ba, 0x43a3,
-+	0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007,
-+	0x0012, 0x1078, 0x43eb, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0,
-+	0x4547, 0x609c, 0xa005, 0x0040, 0x4550, 0x2060, 0x6004, 0xa084,
-+	0x000f, 0xa080, 0x43b1, 0x203c, 0x87fb, 0x1040, 0x22ac, 0x8a51,
-+	0x0040, 0x454f, 0x7008, 0xa084, 0x00c0, 0xa086, 0x00c0, 0x007c,
-+	0x2051, 0x0000, 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0,
-+	0x4567, 0x6000, 0xa064, 0x00c0, 0x455e, 0x2d60, 0x6004, 0xa084,
-+	0x000f, 0xa080, 0x43c1, 0x203c, 0x87fb, 0x1040, 0x22ac, 0x007c,
-+	0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888,
-+	0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e,
-+	0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x4582, 0xa0b8, 0x43ab,
-+	0x0078, 0x4584, 0xa0b8, 0x43a3, 0x7e08, 0xa6b5, 0x000c, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4592, 0xa18e, 0x000f,
-+	0x00c0, 0x459b, 0x6820, 0xa084, 0x0040, 0x0040, 0x45a2, 0xa6b5,
-+	0x0001, 0x0078, 0x45a2, 0x681c, 0xa084, 0x0040, 0x0040, 0x45a2,
-+	0xa6b5, 0x0001, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-+	0x45a4, 0x2400, 0xa305, 0x00c0, 0x45af, 0x0078, 0x45d5, 0x2c58,
-+	0x2704, 0x6104, 0xac60, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301,
-+	0x701e, 0xa184, 0x0008, 0x0040, 0x45c5, 0x6014, 0xa081, 0x0000,
-+	0x7022, 0x6010, 0xa081, 0x0000, 0x7026, 0x620c, 0x2400, 0xa202,
-+	0x7012, 0x6208, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
-+	0x2b60, 0x1078, 0x4534, 0x0078, 0x45d7, 0x1078, 0x46ba, 0x00c0,
-+	0x45d5, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200,
-+	0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x45e3,
-+	0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091,
-+	0x2200, 0x0d7f, 0x2049, 0x45ed, 0x7007, 0x0004, 0x7004, 0xa084,
-+	0x0004, 0x00c0, 0x45f6, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c,
-+	0x00ff, 0xa186, 0x0007, 0x0040, 0x4609, 0xa18e, 0x000f, 0x00c0,
-+	0x4614, 0x6820, 0xa084, 0x0040, 0x0040, 0x4610, 0xa6b5, 0x0001,
-+	0x6840, 0x2050, 0x0078, 0x461d, 0x681c, 0xa084, 0x0020, 0x00c0,
-+	0x461b, 0xa6b5, 0x0001, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc,
-+	0x000f, 0xa7b8, 0x43b1, 0x273c, 0x87fb, 0x00c0, 0x4631, 0x0048,
-+	0x462b, 0x1078, 0x22ac, 0x689c, 0xa065, 0x0040, 0x4635, 0x0078,
-+	0x461e, 0x1078, 0x46ba, 0x00c0, 0x4631, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x007e, 0x017e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f,
-+	0x047f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
-+	0x0007, 0x0040, 0x464f, 0xa18e, 0x000f, 0x00c0, 0x4658, 0x6820,
-+	0xa084, 0x0040, 0x0040, 0x465f, 0xa6b5, 0x0001, 0x0078, 0x465f,
-+	0x681c, 0xa084, 0x0040, 0x0040, 0x465f, 0xa6b5, 0x0001, 0x2049,
-+	0x4638, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040,
-+	0x466d, 0xa18e, 0x000f, 0x00c0, 0x4670, 0x6840, 0x0078, 0x4671,
-+	0x6828, 0x017f, 0xa055, 0x0040, 0x46b7, 0x2d70, 0x2e60, 0x7004,
-+	0xa0bc, 0x000f, 0xa7b8, 0x43b1, 0x273c, 0x87fb, 0x00c0, 0x468b,
-+	0x0048, 0x4684, 0x1078, 0x22ac, 0x709c, 0xa075, 0x2060, 0x0040,
-+	0x46b7, 0x0078, 0x4677, 0x2704, 0xae68, 0x680c, 0xa422, 0x6808,
-+	0xa31b, 0x0048, 0x46a4, 0x8a51, 0x00c0, 0x4698, 0x1078, 0x22ac,
-+	0x8738, 0x2704, 0xa005, 0x00c0, 0x468c, 0x709c, 0xa075, 0x2060,
-+	0x0040, 0x46b7, 0x0078, 0x4677, 0x8422, 0x8420, 0x831a, 0xa399,
-+	0x0000, 0x690c, 0x2400, 0xa122, 0x6908, 0x2300, 0xa11b, 0x00c8,
-+	0x46b3, 0x1078, 0x22ac, 0x2071, 0x0020, 0x0078, 0x45a2, 0x127f,
-+	0x2000, 0x007c, 0x7008, 0xa084, 0x00c0, 0xa086, 0x00c0, 0x0040,
-+	0x46d7, 0x2704, 0xac08, 0x2104, 0x701e, 0x8108, 0x2104, 0x701a,
-+	0x8108, 0x2104, 0x7016, 0x8108, 0x2104, 0x7012, 0x7602, 0x7004,
-+	0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4534, 0x007c,
-+	0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x46d8, 0x0d7f,
-+	0x087f, 0x7108, 0xa184, 0x00c0, 0x00c0, 0x4702, 0x017e, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x46f2, 0xa18e, 0x000f,
-+	0x00c0, 0x46f5, 0x6840, 0x0078, 0x46f6, 0x6828, 0x017f, 0xa005,
-+	0x0040, 0x471f, 0x0078, 0x4332, 0x0020, 0x4702, 0x1078, 0x44f7,
-+	0x0078, 0x471f, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4702, 0x017e,
-+	0x017f, 0x810c, 0x00c8, 0x4711, 0x7108, 0x1078, 0x4462, 0x0078,
-+	0x46e1, 0x7007, 0x0010, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4713,
-+	0x017e, 0x017f, 0x810c, 0x00c8, 0x4713, 0x1078, 0x4462, 0x7008,
-+	0xa086, 0x0002, 0x00c0, 0x46e1, 0x7000, 0xa005, 0x00c0, 0x46e1,
-+	0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x127e,
-+	0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200, 0x0d7f,
-+	0x2049, 0x472f, 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031, 0x700c,
-+	0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003,
-+	0x0001, 0x0040, 0x474e, 0x8000, 0x80ac, 0x53a5, 0x7007, 0x0004,
-+	0x7004, 0xa084, 0x0004, 0x00c0, 0x4750, 0x0c7f, 0x2049, 0x0000,
-+	0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000, 0x007c,
-+	0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040, 0x4777,
-+	0x7994, 0x70d0, 0xa106, 0x00c0, 0x4777, 0x7804, 0xa005, 0x0040,
-+	0x4777, 0x7807, 0x0000, 0x0068, 0x4777, 0x2091, 0x4080, 0x7820,
-+	0x8001, 0x7822, 0x00c0, 0x47d2, 0x7824, 0x7822, 0x2069, 0x4d40,
-+	0x6800, 0xa084, 0x0007, 0x0040, 0x4795, 0xa086, 0x0002, 0x0040,
-+	0x4795, 0x6834, 0xa00d, 0x0040, 0x4795, 0x2104, 0xa005, 0x0040,
-+	0x4795, 0x8001, 0x200a, 0x0040, 0x487a, 0x7848, 0xa005, 0x0040,
-+	0x47a3, 0x8001, 0x784a, 0x00c0, 0x47a3, 0x2009, 0x0102, 0x6844,
-+	0x200a, 0x1078, 0x20a0, 0x6890, 0xa005, 0x0040, 0x47af, 0x8001,
-+	0x6892, 0x00c0, 0x47af, 0x686f, 0x0000, 0x6873, 0x0001, 0x2061,
-+	0x5000, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034, 0xa005, 0x0040,
-+	0x47c5, 0x8001, 0x6036, 0x00c0, 0x47c5, 0x6010, 0xa005, 0x0040,
-+	0x47c5, 0x017e, 0x1078, 0x20a0, 0x017f, 0xace0, 0x0010, 0x0070,
-+	0x47cb, 0x0078, 0x47b5, 0x8109, 0x0040, 0x47d2, 0x20a9, 0x0100,
-+	0x0078, 0x47b5, 0x1078, 0x47df, 0x1078, 0x4804, 0x2009, 0x4d51,
-+	0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001, 0x007c, 0x7834,
-+	0x8001, 0x7836, 0x00c0, 0x4803, 0x7838, 0x7836, 0x2091, 0x8000,
-+	0x7844, 0xa005, 0x00c0, 0x47ee, 0x2001, 0x0101, 0x8001, 0x7846,
-+	0xa080, 0x7000, 0x2040, 0x2004, 0xa065, 0x0040, 0x4803, 0x6024,
-+	0xa005, 0x0040, 0x47ff, 0x8001, 0x6026, 0x0040, 0x4833, 0x6000,
-+	0x2c40, 0x0078, 0x47f4, 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0,
-+	0x4832, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x4811, 0x2001,
-+	0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003, 0xa090,
-+	0x5000, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040, 0x4832,
-+	0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x482a, 0x8001, 0x2012,
-+	0x00c0, 0x4832, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a,
-+	0x1078, 0x20a0, 0x007c, 0x2069, 0x4d40, 0x6800, 0xa005, 0x0040,
-+	0x483d, 0x6848, 0xac06, 0x0040, 0x487a, 0x601b, 0x0006, 0x60b4,
-+	0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060,
-+	0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078, 0x18b9, 0x6818,
-+	0xa005, 0x0040, 0x4855, 0x8001, 0x681a, 0x6808, 0xa084, 0xffef,
-+	0x680a, 0x6810, 0x8001, 0x00d0, 0x485f, 0x1078, 0x22ac, 0x6812,
-+	0x6033, 0x0000, 0x602f, 0x0000, 0x2c68, 0x1078, 0x1b8e, 0x2069,
-+	0x4d40, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006, 0x686e, 0x00c0,
-+	0x4875, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078, 0x209b, 0x2091,
-+	0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x4d40, 0x2104, 0xa084,
-+	0x0007, 0x0040, 0x48d6, 0xa086, 0x0007, 0x00c0, 0x4890, 0x0d7e,
-+	0x2009, 0x4d52, 0x216c, 0x1078, 0x385e, 0x0d7f, 0x0078, 0x48d6,
-+	0x2009, 0x4d52, 0x2164, 0x1078, 0x2257, 0x601b, 0x0006, 0x6858,
-+	0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048,
-+	0x6022, 0x6033, 0x0000, 0x602f, 0x0000, 0x6830, 0xa084, 0x0040,
-+	0x0040, 0x48ca, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084,
-+	0x0004, 0x0040, 0x48b7, 0x0070, 0x48b7, 0x0078, 0x48ae, 0x684b,
-+	0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x48c4,
-+	0x0070, 0x48c4, 0x0078, 0x48bb, 0x20a9, 0x00fa, 0x0070, 0x48ca,
-+	0x0078, 0x48c6, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048,
-+	0x2009, 0x4d5b, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091, 0x8001,
-+	0x007c, 0x2079, 0x4d00, 0x1078, 0x4904, 0x1078, 0x48e8, 0x1078,
-+	0x48f6, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x007c,
-+	0x2019, 0x0003, 0x2011, 0x4d46, 0x2204, 0xa086, 0x003c, 0x0040,
-+	0x48f3, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, 0x0039,
-+	0x2011, 0x4d46, 0x2204, 0xa086, 0x003c, 0x0040, 0x4901, 0x2019,
-+	0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011, 0x4d46,
-+	0x2204, 0xa086, 0x003c, 0x0040, 0x490f, 0x2019, 0x2626, 0x7b22,
-+	0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c, 0x0020, 0x002b,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014, 0x0014, 0x0014,
-+	0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000, 0x0201, 0x0604,
-+	0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014,
-+	0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c, 0x0002, 0x0014,
-+	0x98e1, 0x009e, 0x00ab, 0xa202, 0x8838, 0x8180, 0x842a, 0x84a0,
-+	0x3806, 0x8839, 0x28c2, 0x9cc1, 0x985d, 0x0864, 0x9891, 0x28c1,
-+	0x9cc1, 0xa203, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4,
-+	0x1856, 0x883a, 0x986d, 0x28e2, 0x9c9e, 0x985d, 0x0864, 0x9891,
-+	0x300c, 0x28e1, 0x9c9e, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0,
-+	0x1814, 0x883b, 0x782c, 0x786d, 0x9881, 0x282b, 0xa207, 0x64a0,
-+	0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7822, 0x883e, 0x9885, 0x8576,
-+	0x8677, 0x206b, 0x28c1, 0x9cc1, 0x2044, 0x2103, 0x20a2, 0x2081,
-+	0x986d, 0xa209, 0x2901, 0x989a, 0x0014, 0xa205, 0x8000, 0x85a4,
-+	0x1872, 0x879a, 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704,
-+	0x9c9e, 0x0014, 0xa204, 0x8000, 0x85a4, 0x84a8, 0x3009, 0x19e2,
-+	0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9, 0x883f, 0x08e6,
-+	0x989e, 0xf881, 0x9899, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2,
-+	0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014,
-+	0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008,
-+	0x1dc1, 0x0016, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf041, 0x3008,
-+	0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, 0x0016,
-+	0x8000, 0x2847, 0x1011, 0x98d4, 0x8000, 0xa000, 0x2802, 0x1011,
-+	0x98da, 0x986d, 0x283e, 0x1011, 0x98de, 0xa20b, 0x0017, 0x300c,
-+	0x8000, 0x85a4, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98ec, 0x0014,
-+	0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x8180,
-+	0x842a, 0x84a0, 0x3806, 0x0210, 0x9cc6, 0x0704, 0x0000, 0x006c,
-+	0x0002, 0x984f, 0x0014, 0x009e, 0x00a3, 0x0017, 0x60ff, 0x300c,
-+	0x8720, 0xa211, 0x9cc7, 0x8772, 0x8837, 0x2007, 0x10d2, 0x78e2,
-+	0x9ccb, 0x9858, 0xd984, 0xf0e2, 0xf0a1, 0x98c4, 0x0014, 0x8831,
-+	0xd167, 0x8830, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820,
-+	0x9878, 0x2301, 0x9878, 0x10d2, 0x78e2, 0x9ccb, 0x986d, 0xf123,
-+	0xf142, 0xf101, 0x98bd, 0x10d2, 0x70f8, 0x8832, 0x8203, 0x6001,
-+	0x0014, 0x6845, 0x0214, 0xa21b, 0x9cc7, 0x2001, 0x98bc, 0x8202,
-+	0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x9889, 0x3027, 0x84a8,
-+	0x1856, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cb3, 0x6b2a, 0x6902,
-+	0x1834, 0x9899, 0x1814, 0x8010, 0x8592, 0x8026, 0x84b9, 0x7021,
-+	0x0014, 0x8000, 0x85a4, 0x84a8, 0x6946, 0xa213, 0x1462, 0xa213,
-+	0x8000, 0x16e1, 0x98ac, 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1,
-+	0x8004, 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, 0x9cb3,
-+	0x0014, 0x8000, 0x85a4, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x0016,
-+	0xa212, 0x9cc7, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a,
-+	0x9ccb, 0x98bc, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, 0x84a8,
-+	0x0016, 0x2002, 0x10d2, 0x98cb, 0x870e, 0xa21d, 0x0012, 0x878e,
-+	0x85b2, 0x80f8, 0x9424, 0xa532, 0x84a4, 0x8000, 0x84a8, 0x0016,
-+	0xa21c, 0x1035, 0x988d, 0xa210, 0x8180, 0x842a, 0x84a0, 0xa000,
-+	0x8010, 0x8592, 0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ed,
-+	0x8021, 0x3807, 0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x988d,
-+	0x0000, 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014,
-+	0x0014, 0x98ee, 0x98d9, 0x0014, 0x0014, 0x0014, 0x0080, 0x013d,
-+	0x0000, 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018,
-+	0x300b, 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202,
-+	0x8838, 0x3806, 0x8839, 0x28c2, 0x9cba, 0xa804, 0x0864, 0xa835,
-+	0x28c1, 0x9cba, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300,
-+	0x1856, 0x883a, 0xa806, 0x28e2, 0x9c99, 0xa8f4, 0x0864, 0xa825,
-+	0x300c, 0x28e1, 0x9c99, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0,
-+	0x1814, 0x883b, 0x782c, 0x786d, 0xa808, 0x282b, 0xa207, 0x64a0,
-+	0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7822, 0x883e, 0xa802, 0x8576,
-+	0x8677, 0x206b, 0x28c1, 0x9cba, 0x2044, 0x2103, 0x20a2, 0x2081,
-+	0xa8e0, 0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872,
-+	0x879a, 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c99,
-+	0x0014, 0xa204, 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb,
-+	0x85eb, 0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec,
-+	0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02,
-+	0x1de2, 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0,
-+	0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300,
-+	0x8160, 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd,
-+	0x0011, 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc,
-+	0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd, 0xa893, 0x283e, 0x1011,
-+	0xa8fd, 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014,
-+	0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2,
-+	0x0014, 0xa20d, 0x3806, 0x0210, 0x9cbf, 0x0704, 0x0017, 0x60ff,
-+	0x300c, 0x8720, 0xa211, 0x9d63, 0x8772, 0x8837, 0x2007, 0x10d2,
-+	0x78e2, 0x9d66, 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa861, 0x0014,
-+	0x8831, 0xd167, 0x8830, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802,
-+	0x8820, 0xa80d, 0x2301, 0xa80b, 0x10d2, 0x78e2, 0x9d66, 0xa8fc,
-+	0xf123, 0xf142, 0xf101, 0xa845, 0x10d2, 0x70f8, 0x8832, 0x8203,
-+	0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d63, 0x2001, 0xa838,
-+	0x8202, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801, 0x3027,
-+	0x84a8, 0x1856, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d50, 0x6b2a,
-+	0x6902, 0x1834, 0xa805, 0x1814, 0x8010, 0x8592, 0x8026, 0x84b9,
-+	0x7021, 0x0014, 0xa300, 0x6946, 0xa213, 0x1462, 0xa213, 0x8000,
-+	0x16e1, 0xa807, 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004,
-+	0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, 0x9d50, 0x0014,
-+	0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x0016, 0xa212, 0x9d63,
-+	0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d66, 0xa8f8,
-+	0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x2002, 0x10d2,
-+	0xa8fd, 0x870e, 0xa21d, 0x0012, 0x878e, 0x85b2, 0x80f8, 0x9424,
-+	0xa532, 0x84a4, 0x0016, 0xa21c, 0x1035, 0xa8b6, 0xa210, 0x3807,
-+	0x300c, 0x817e, 0x872b, 0x8772, 0xa8af, 0x0000, 0xd66f
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_1040.h	2003-07-19 17:06:32.000000000 -0700
-@@ -0,0 +1,3545 @@
-+/* @(#)asm_1040.h 1.2 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+/************************************************************************
-+ *									*
-+ * 	            --- ISP1040 Initiator Firmware ---                  *
-+ *			     32 LUN Support				*
-+ *									*
-+ ************************************************************************/
-+#ifndef	ISP_TARGET_MODE
-+/*
-+ *	Firmware Version 4.66.00 (14:49 Sep 05, 2000)
-+ */
-+static const u_int16_t isp_1040_risc_code[] = {
-+	0x0078, 0x1041, 0x0000, 0x2cd0, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
-+	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
-+	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
-+	0x3130, 0x3230, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-+	0x6572, 0x7369, 0x6f6e, 0x2030, 0x342e, 0x3636, 0x2020, 0x2043,
-+	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
-+	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-+	0x2400, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048, 0x104c,
-+	0x0038, 0x1052, 0x0078, 0x104e, 0x0028, 0x1052, 0x20b9, 0x1212,
-+	0x0078, 0x1054, 0x20b9, 0x1313, 0x2071, 0x0010, 0x70c3, 0x0004,
-+	0x20c9, 0x62ff, 0x2089, 0x1185, 0x70c7, 0x4953, 0x70cb, 0x5020,
-+	0x70cf, 0x2020, 0x70d3, 0x0004, 0x3f00, 0x70d6, 0x20c1, 0x0008,
-+	0x2019, 0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec,
-+	0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b,
-+	0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10c4, 0xa386, 0x000f,
-+	0x0040, 0x108a, 0x2c6a, 0x2a5a, 0x20c1, 0x0000, 0x2019, 0x000f,
-+	0x0078, 0x106a, 0x2c6a, 0x2a5a, 0x20c1, 0x0008, 0x2009, 0x7fff,
-+	0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc, 0x3fff, 0x2734, 0x203b,
-+	0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040, 0x10ae, 0x284a, 0x263a,
-+	0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134, 0x200b, 0x5050, 0x2114,
-+	0xa286, 0x5050, 0x0040, 0x10af, 0x0078, 0x118d, 0x284a, 0x263a,
-+	0x98c0, 0xa188, 0x1000, 0x212c, 0x200b, 0xa5a5, 0x2114, 0xa286,
-+	0xa5a5, 0x0040, 0x10c1, 0x250a, 0xa18a, 0x1000, 0x98c1, 0x0078,
-+	0x10c6, 0x250a, 0x0078, 0x10c6, 0x2c6a, 0x2a5a, 0x2130, 0xa18a,
-+	0x0040, 0x2128, 0xa1a2, 0x3d00, 0x8424, 0x8424, 0x8424, 0x8424,
-+	0x8424, 0x8424, 0xa192, 0x6300, 0x2009, 0x0000, 0x2001, 0x002f,
-+	0x1078, 0x1bc9, 0x2218, 0x2079, 0x3d00, 0x2fa0, 0x2408, 0x2011,
-+	0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10e1, 0x7ee6,
-+	0x8528, 0x7dda, 0x7cde, 0x7be2, 0x787b, 0x0000, 0x2031, 0x0030,
-+	0x78c3, 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f, 0x0003,
-+	0x7803, 0x0002, 0x2069, 0x3d40, 0x2001, 0x04fd, 0x2004, 0xa082,
-+	0x0005, 0x0048, 0x1107, 0x0038, 0x1109, 0x0078, 0x110d, 0x00a8,
-+	0x110d, 0x681b, 0x003c, 0x0078, 0x110f, 0x681b, 0x0028, 0x6807,
-+	0x0007, 0x680b, 0x00fa, 0x680f, 0x0008, 0x6813, 0x0005, 0x681f,
-+	0x0000, 0x6823, 0x0006, 0x6817, 0x0008, 0x6827, 0x0000, 0x2069,
-+	0x3f80, 0x2011, 0x0020, 0x2009, 0x0010, 0x680b, 0x0c19, 0x680f,
-+	0x0019, 0x6803, 0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8,
-+	0x0008, 0xa290, 0x0004, 0x8109, 0x00c0, 0x1125, 0x2069, 0x4000,
-+	0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040,
-+	0x7be4, 0xa386, 0xfeff, 0x00c0, 0x114b, 0x6817, 0x0100, 0x681f,
-+	0x0064, 0x0078, 0x114f, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8,
-+	0x0010, 0x0070, 0x1155, 0x0078, 0x113c, 0x8109, 0x00c0, 0x113a,
-+	0x1078, 0x1f20, 0x1078, 0x3792, 0x1078, 0x19e0, 0x1078, 0x3c4a,
-+	0x3200, 0xa085, 0x000d, 0x2090, 0x70c3, 0x0000, 0x0090, 0x116f,
-+	0x70c0, 0xa086, 0x0002, 0x00c0, 0x116f, 0x1078, 0x12a4, 0x1078,
-+	0x11b6, 0x78c0, 0xa005, 0x00c0, 0x117b, 0x1078, 0x1bf2, 0x0068,
-+	0x117f, 0x1078, 0x1e44, 0x0068, 0x117f, 0x1078, 0x1adf, 0x00e0,
-+	0x116f, 0x1078, 0x3ac1, 0x0078, 0x116f, 0x118d, 0x1192, 0x20e8,
-+	0x20e8, 0x380c, 0x380c, 0x20e8, 0x20e8, 0x0088, 0x118d, 0x2091,
-+	0x8001, 0x007c, 0x0088, 0x1192, 0x2091, 0x8001, 0x007c, 0x0078,
-+	0x1197, 0x0078, 0x1199, 0x2009, 0x0022, 0x2104, 0xa086, 0x4000,
-+	0x0040, 0x11b1, 0x7008, 0x800b, 0x00c8, 0x11b1, 0x7007, 0x0002,
-+	0xa08c, 0x01e0, 0x00c0, 0x11b2, 0xa084, 0x0008, 0x0040, 0x11b1,
-+	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x12a7, 0x0068, 0x1221,
-+	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1221, 0x7814,
-+	0xa005, 0x00c0, 0x11c7, 0x0010, 0x1222, 0x0078, 0x1221, 0x2009,
-+	0x3d68, 0x2104, 0xa005, 0x00c0, 0x1221, 0x2009, 0x3d71, 0x200b,
-+	0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11ec, 0x7816, 0x2009,
-+	0x3d6f, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
-+	0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
-+	0x1078, 0x19d2, 0x0078, 0x121f, 0x7814, 0xa086, 0x0018, 0x00c0,
-+	0x11f3, 0x1078, 0x16cd, 0x7817, 0x0000, 0x2009, 0x3d6f, 0x2104,
-+	0xa065, 0x0040, 0x120f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a30,
-+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x17b3, 0x2009, 0x0018, 0x6087,
-+	0x0103, 0x1078, 0x1959, 0x00c0, 0x121b, 0x1078, 0x19d2, 0x2009,
-+	0x3d6f, 0x200b, 0x0000, 0x2009, 0x3d69, 0x2104, 0x200b, 0x0000,
-+	0xa005, 0x0040, 0x121f, 0x2001, 0x4005, 0x0078, 0x12a6, 0x0078,
-+	0x12a4, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
-+	0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1272, 0x2038,
-+	0x0079, 0x1232, 0x12a4, 0x12ff, 0x12c3, 0x12ff, 0x1368, 0x1368,
-+	0x12ba, 0x17cb, 0x1373, 0x12b2, 0x12c7, 0x12c9, 0x12cb, 0x12cd,
-+	0x17d0, 0x12b2, 0x1385, 0x13c1, 0x16e5, 0x17c5, 0x12cf, 0x15fa,
-+	0x161c, 0x163a, 0x1667, 0x15b3, 0x15c1, 0x15d5, 0x15e9, 0x1445,
-+	0x12b2, 0x13f3, 0x13f9, 0x13fe, 0x1403, 0x1409, 0x140e, 0x1413,
-+	0x1418, 0x141d, 0x1421, 0x1436, 0x1442, 0x12b2, 0x12b2, 0x12b2,
-+	0x12b2, 0x1451, 0x145a, 0x1469, 0x148f, 0x1499, 0x14a0, 0x14e0,
-+	0x14ef, 0x14fe, 0x1510, 0x1593, 0x15a3, 0x12b2, 0x12b2, 0x12b2,
-+	0x12b2, 0x15a8, 0xa0bc, 0xffa0, 0x00c0, 0x12b2, 0x2038, 0xa084,
-+	0x001f, 0x0079, 0x127b, 0x17e7, 0x17ea, 0x17fa, 0x189f, 0x18d8,
-+	0x1914, 0x1931, 0x1886, 0x12b2, 0x12b2, 0x1935, 0x193d, 0x12b2,
-+	0x12b2, 0x12b2, 0x12b2, 0x12f5, 0x135e, 0x137b, 0x13b7, 0x16db,
-+	0x12b2, 0x12b2, 0x12b2, 0x12b2, 0x1943, 0x18f0, 0x18fa, 0x18fe,
-+	0x190c, 0x12b2, 0x12b2, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
-+	0x12a6, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
-+	0x12a7, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091,
-+	0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x12a7, 0x70c3, 0x4006,
-+	0x0078, 0x12a7, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005,
-+	0x53a3, 0x0078, 0x12a4, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078,
-+	0x12a4, 0x0078, 0x12a4, 0x0078, 0x12a4, 0x0078, 0x12a4, 0x2091,
-+	0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
-+	0x2020, 0x70d3, 0x0004, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b,
-+	0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051,
-+	0x0470, 0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091,
-+	0x5000, 0x2091, 0x4080, 0x0078, 0x0455, 0x1078, 0x1b4c, 0x00c0,
-+	0x12b6, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1302, 0x2029,
-+	0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2098,
-+	0x2031, 0x0030, 0x81ff, 0x0040, 0x12a4, 0x7007, 0x0004, 0x731a,
-+	0x721e, 0x7422, 0x7526, 0x2051, 0x0012, 0x2049, 0x133d, 0x2041,
-+	0x12a4, 0x7003, 0x0002, 0xa786, 0x0001, 0x0040, 0x1325, 0xa786,
-+	0x0050, 0x0040, 0x1325, 0x0078, 0x132b, 0x2049, 0x134a, 0x2041,
-+	0x1356, 0x7003, 0x0003, 0x7017, 0x0000, 0x810b, 0x7112, 0x00c8,
-+	0x1333, 0x7017, 0x0001, 0x7007, 0x0001, 0xa786, 0x0001, 0x0040,
-+	0x134a, 0xa786, 0x0050, 0x0040, 0x134a, 0x700c, 0xa084, 0x007f,
-+	0x2009, 0x0040, 0xa102, 0x8004, 0x094a, 0x20a8, 0x26a0, 0x53a6,
-+	0x0078, 0x119b, 0x700c, 0xa084, 0x007f, 0x0040, 0x134a, 0x80ac,
-+	0x0048, 0x134a, 0x2698, 0x53a5, 0x0078, 0x119b, 0x700c, 0xa084,
-+	0x007f, 0x80ac, 0x2698, 0x53a5, 0x0078, 0x12a4, 0x1078, 0x1b4c,
-+	0x00c0, 0x12b6, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1302,
-+	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1370, 0x200a,
-+	0x72ca, 0x0078, 0x12a3, 0x70c7, 0x0004, 0x70cb, 0x0042, 0x70cf,
-+	0x0000, 0x0078, 0x12a4, 0x1078, 0x1b4c, 0x00c0, 0x12b6, 0x75d8,
-+	0x76dc, 0x75da, 0x76de, 0x0078, 0x1388, 0x2029, 0x0000, 0x2530,
-+	0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2,
-+	0xa005, 0x0040, 0x13b1, 0xa40a, 0x0040, 0x1398, 0x00c8, 0x13a2,
-+	0x8001, 0x788a, 0xa084, 0xfc00, 0x0040, 0x13a6, 0x78c0, 0xa085,
-+	0x0001, 0x78c2, 0x2001, 0x4005, 0x0078, 0x12a6, 0x7a92, 0x7b96,
-+	0x7d9a, 0x7e9e, 0x7c8e, 0x78c0, 0xa084, 0xfffc, 0x78c2, 0x0078,
-+	0x13b5, 0x78c0, 0xa085, 0x0001, 0x78c2, 0x0078, 0x12a4, 0x1078,
-+	0x1b4c, 0x00c0, 0x12b6, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
-+	0x13c4, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4,
-+	0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x13ed, 0xa40a,
-+	0x0040, 0x13d4, 0x00c8, 0x13de, 0x8001, 0x78a6, 0xa084, 0xfc00,
-+	0x0040, 0x13e2, 0x78c0, 0xa085, 0x0100, 0x78c2, 0x2001, 0x4005,
-+	0x0078, 0x12a6, 0x7aae, 0x7bb2, 0x7db6, 0x7eba, 0x7caa, 0x78c0,
-+	0xa084, 0xfcff, 0x78c2, 0x0078, 0x13f1, 0x78c0, 0xa085, 0x0100,
-+	0x78c2, 0x0078, 0x12a4, 0x2009, 0x3d5f, 0x210c, 0x7ae0, 0x0078,
-+	0x12a2, 0x2009, 0x3d41, 0x210c, 0x0078, 0x12a3, 0x2009, 0x3d42,
-+	0x210c, 0x0078, 0x12a3, 0x2061, 0x3d40, 0x610c, 0x6210, 0x0078,
-+	0x12a2, 0x2009, 0x3d45, 0x210c, 0x0078, 0x12a3, 0x2009, 0x3d46,
-+	0x210c, 0x0078, 0x12a3, 0x2009, 0x3d47, 0x210c, 0x0078, 0x12a3,
-+	0x2009, 0x3d48, 0x210c, 0x0078, 0x12a3, 0x7908, 0x7a0c, 0x0078,
-+	0x12a2, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa0e8, 0x3f80, 0x6a00, 0x6804, 0xa084, 0x0008, 0x0040, 0x1433,
-+	0x6b08, 0x0078, 0x1434, 0x6b0c, 0x0078, 0x12a1, 0x77c4, 0x1078,
-+	0x19f0, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x12a1, 0x794c, 0x0078, 0x12a3, 0x77c4, 0x1078, 0x19f0,
-+	0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091, 0x8001, 0x0078,
-+	0x12a1, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x129c, 0x1078, 0x1fb7,
-+	0x0078, 0x12a1, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x129c, 0x2011,
-+	0x3d41, 0x2204, 0x007e, 0x2112, 0x1078, 0x1f70, 0x017f, 0x0078,
-+	0x12a3, 0x71c4, 0x2011, 0x1487, 0x20a9, 0x0008, 0x2204, 0xa106,
-+	0x0040, 0x1479, 0x8210, 0x0070, 0x1477, 0x0078, 0x146e, 0x0078,
-+	0x129c, 0xa292, 0x1487, 0x027e, 0x2011, 0x3d42, 0x2204, 0x2112,
-+	0x017f, 0x007e, 0x1078, 0x1f7c, 0x017f, 0x0078, 0x12a3, 0x03e8,
-+	0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061,
-+	0x3d40, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8, 0x6012, 0x0078,
-+	0x12a2, 0x2061, 0x3d40, 0x6114, 0x70c4, 0x6016, 0x0078, 0x12a3,
-+	0x71c4, 0x2011, 0x0004, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040,
-+	0x14b9, 0x2011, 0x0005, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
-+	0x14b9, 0x2011, 0x0006, 0x2019, 0x1313, 0xa186, 0x003c, 0x00c0,
-+	0x129c, 0x2061, 0x3d40, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
-+	0x0001, 0x00c0, 0x14d6, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-+	0x0048, 0x14ce, 0x0038, 0x14d2, 0x0078, 0x14d6, 0x0028, 0x14d2,
-+	0x0078, 0x14d6, 0x2019, 0x1313, 0x0078, 0x14d8, 0x2019, 0x1212,
-+	0x23b8, 0x1078, 0x1f8d, 0x1078, 0x3c4a, 0x017f, 0x0078, 0x12a3,
-+	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x129c, 0x2011, 0x3d47, 0x2204,
-+	0x2112, 0x007e, 0x1078, 0x1faf, 0x017f, 0x0078, 0x12a3, 0x71c4,
-+	0xa182, 0x0010, 0x00c8, 0x129c, 0x2011, 0x3d48, 0x2204, 0x007e,
-+	0x2112, 0x1078, 0x1f9e, 0x017f, 0x0078, 0x12a3, 0x71c4, 0x72c8,
-+	0xa184, 0xfffd, 0x00c0, 0x129b, 0xa284, 0xfffd, 0x00c0, 0x129b,
-+	0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x12a2,
-+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
-+	0x3f80, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x1526,
-+	0x6c14, 0x84ff, 0x00c0, 0x1526, 0x6817, 0x0040, 0xa284, 0x0040,
-+	0x0040, 0x1530, 0x6c10, 0x84ff, 0x00c0, 0x1530, 0x6813, 0x0001,
-+	0x6800, 0x007e, 0xa226, 0x0040, 0x155c, 0xa284, 0x0001, 0x0040,
-+	0x153e, 0x2220, 0xa39d, 0x0002, 0xa294, 0xfffe, 0x6a02, 0xa484,
-+	0x2000, 0x0040, 0x1545, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040,
-+	0x154b, 0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x155c, 0x810f,
-+	0xa284, 0x4000, 0x0040, 0x1558, 0x1078, 0x1fd1, 0x0078, 0x155c,
-+	0x1078, 0x1fc3, 0x0078, 0x155c, 0x72cc, 0x6808, 0xa206, 0x0040,
-+	0x158b, 0xa2a4, 0x00ff, 0x2061, 0x3d40, 0x6118, 0xa186, 0x0028,
-+	0x0040, 0x1572, 0xa186, 0x0032, 0x0040, 0x1578, 0xa186, 0x003c,
-+	0x0040, 0x157e, 0xa482, 0x0064, 0x0048, 0x1588, 0x0078, 0x1582,
-+	0xa482, 0x0050, 0x0048, 0x1588, 0x0078, 0x1582, 0xa482, 0x0043,
-+	0x0048, 0x1588, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x129d,
-+	0x6a0a, 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c,
-+	0x71c4, 0x0078, 0x12a1, 0x77c4, 0x1078, 0x19f0, 0x2091, 0x8000,
-+	0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e,
-+	0x2708, 0x0078, 0x12a1, 0x70c4, 0x794c, 0x784e, 0x0078, 0x12a3,
-+	0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x129c, 0x1078,
-+	0x1fdf, 0x0078, 0x12a1, 0x77c4, 0x1078, 0x19f0, 0x2091, 0x8000,
-+	0x6a08, 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078,
-+	0x12a2, 0x77c4, 0x1078, 0x19f0, 0x2091, 0x8000, 0x6a08, 0xa294,
-+	0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x15d0, 0x1078, 0x1f05,
-+	0x2091, 0x8001, 0x2708, 0x0078, 0x12a2, 0x77c4, 0x1078, 0x19f0,
-+	0x2091, 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005,
-+	0x0040, 0x15e4, 0x1078, 0x1f05, 0x2091, 0x8001, 0x2708, 0x0078,
-+	0x12a2, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
-+	0x2091, 0x8000, 0x1078, 0x19fd, 0x2091, 0x8001, 0x2708, 0x6a08,
-+	0x0078, 0x12a2, 0x77c4, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce,
-+	0x1078, 0x1a78, 0x00c0, 0x1618, 0x6818, 0xa005, 0x0040, 0x1612,
-+	0x2708, 0x1078, 0x1fef, 0x00c0, 0x1612, 0x7817, 0x0015, 0x2091,
-+	0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x12a6,
-+	0x2091, 0x8001, 0x0078, 0x12a4, 0x77c4, 0x77c6, 0x2041, 0x0021,
-+	0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x19fd,
-+	0x2061, 0x3d40, 0x60a3, 0x0003, 0x67b6, 0x60c7, 0x000f, 0x60a7,
-+	0x0000, 0x7817, 0x0016, 0x2091, 0x8000, 0x1078, 0x1f05, 0x2091,
-+	0x8001, 0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00,
-+	0x2091, 0x8000, 0x2061, 0x3d40, 0x60a3, 0x0002, 0x60a7, 0x0000,
-+	0x67b6, 0x60c7, 0x000f, 0x7817, 0x0017, 0x2091, 0x8000, 0x1078,
-+	0x1f05, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-+	0x0010, 0x2091, 0x8000, 0x1078, 0x19fd, 0x70c8, 0x6836, 0x8738,
-+	0xa784, 0x001f, 0x00c0, 0x165b, 0x2091, 0x8001, 0x007c, 0x78c0,
-+	0xa084, 0x0003, 0x00c0, 0x168b, 0x2039, 0x0000, 0x2041, 0x0021,
-+	0x2049, 0x0004, 0x2051, 0x0008, 0x1078, 0x19f0, 0x2091, 0x8000,
-+	0x6808, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f,
-+	0x00c0, 0x1674, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784,
-+	0x0f00, 0x00c0, 0x1674, 0x2091, 0x8000, 0x2069, 0x0100, 0x6830,
-+	0xa084, 0x0040, 0x0040, 0x16b4, 0x684b, 0x0004, 0x20a9, 0x0014,
-+	0x6848, 0xa084, 0x0004, 0x0040, 0x16a1, 0x0070, 0x16a1, 0x0078,
-+	0x1698, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
-+	0x0040, 0x16ae, 0x0070, 0x16ae, 0x0078, 0x16a5, 0x20a9, 0x00fa,
-+	0x0070, 0x16b4, 0x0078, 0x16b0, 0x2079, 0x3d00, 0x7817, 0x0018,
-+	0x2061, 0x3d40, 0x60a3, 0x0001, 0x60a7, 0x0000, 0x60c7, 0x000f,
-+	0x78c0, 0xa085, 0x0002, 0x78c2, 0x6808, 0xa084, 0xfffd, 0x680a,
-+	0x681b, 0x0047, 0x2091, 0x8001, 0x007c, 0x78c0, 0xa084, 0xfffd,
-+	0x78c2, 0xa084, 0x0001, 0x00c0, 0x16d7, 0x1078, 0x1ac2, 0x71c4,
-+	0x71c6, 0x794a, 0x007c, 0x1078, 0x1b4c, 0x00c0, 0x12b6, 0x75d8,
-+	0x74dc, 0x75da, 0x74de, 0x0078, 0x16e8, 0x2029, 0x0000, 0x2520,
-+	0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x3d00,
-+	0x1078, 0x19c9, 0x0040, 0x17af, 0x20a9, 0x0005, 0x20a1, 0x3d16,
-+	0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x1078,
-+	0x1993, 0x0040, 0x1707, 0x1078, 0x19d2, 0x0078, 0x17af, 0x6004,
-+	0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, 0x1712, 0x007e, 0x1078,
-+	0x1e27, 0x007f, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x177d,
-+	0x0c7e, 0x2c68, 0x1078, 0x19c9, 0x0040, 0x174c, 0x2c00, 0x689e,
-+	0x8109, 0x00c0, 0x1719, 0x609f, 0x0000, 0x0c7f, 0x0c7e, 0x7218,
-+	0x731c, 0x7420, 0x7524, 0x2c68, 0x689c, 0xa065, 0x0040, 0x177c,
-+	0x2009, 0x0040, 0x1078, 0x1993, 0x00c0, 0x1765, 0x6004, 0xa084,
-+	0x00ff, 0xa086, 0x0002, 0x00c0, 0x174c, 0x6004, 0xa084, 0x00ff,
-+	0xa086, 0x000a, 0x00c0, 0x1748, 0x017e, 0x1078, 0x1e23, 0x017f,
-+	0x2d00, 0x6002, 0x0078, 0x1727, 0x0c7f, 0x0c7e, 0x609c, 0x2060,
-+	0x1078, 0x1a30, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x17b3, 0x2009,
-+	0x0018, 0x6008, 0xa085, 0x0200, 0x600a, 0x6004, 0x6086, 0x1078,
-+	0x1959, 0x1078, 0x19d2, 0x0078, 0x17af, 0x0c7f, 0x0c7e, 0x609c,
-+	0x2060, 0x1078, 0x1a30, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x17b3,
-+	0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003, 0x1078, 0x1959,
-+	0x1078, 0x19d2, 0x0078, 0x17af, 0x0c7f, 0x74c4, 0x73c8, 0x72cc,
-+	0x6014, 0x2091, 0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x3d40,
-+	0x70a3, 0x0005, 0x70a7, 0x0000, 0x73aa, 0x72ae, 0x74b2, 0x70b6,
-+	0x70bb, 0x0000, 0x2c00, 0x70be, 0x70c3, 0x0000, 0xa02e, 0x2530,
-+	0x611c, 0xa184, 0x0060, 0x0040, 0x179f, 0x1078, 0x3736, 0x0e7f,
-+	0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000,
-+	0x2091, 0x8000, 0x1078, 0x1f05, 0x2091, 0x8001, 0x007c, 0x70c3,
-+	0x4005, 0x0078, 0x12a7, 0x20a9, 0x0005, 0x2099, 0x3d16, 0x2091,
-+	0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000,
-+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000,
-+	0x7906, 0x0078, 0x12a4, 0x71c4, 0x71c6, 0x2168, 0x0078, 0x17d2,
-+	0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109,
-+	0x00c0, 0x17d4, 0xa285, 0x0000, 0x00c0, 0x17e2, 0x70c3, 0x4000,
-+	0x0078, 0x17e4, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x12a7, 0x79d8,
-+	0x0078, 0x12a3, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9,
-+	0x0004, 0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3,
-+	0x0078, 0x12a4, 0x70c4, 0x2068, 0x2079, 0x3d00, 0x1078, 0x19c9,
-+	0x00c0, 0x1806, 0x70c3, 0x4005, 0x0078, 0x12a7, 0x6007, 0x0001,
-+	0x600b, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c,
-+	0x000f, 0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
-+	0x6016, 0xa284, 0x0800, 0x0040, 0x1821, 0x601b, 0x000a, 0x0078,
-+	0x1827, 0xa284, 0x1000, 0x0040, 0x1827, 0x601b, 0x000c, 0xa284,
-+	0x0300, 0x0040, 0x1830, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004,
-+	0xa085, 0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284,
-+	0x0400, 0x0040, 0x183d, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80,
-+	0x000b, 0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300,
-+	0x00c0, 0x1852, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a,
-+	0x0078, 0x185c, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e,
-+	0x6d0c, 0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817,
-+	0x0042, 0x2c08, 0x2061, 0x3d40, 0x60a3, 0x0005, 0x60a7, 0x0000,
-+	0x60ab, 0x0000, 0x60af, 0x0000, 0x60b3, 0x0000, 0x60b6, 0x61be,
-+	0xa284, 0x0400, 0x60c2, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020,
-+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091,
-+	0x8000, 0x1078, 0x1f05, 0x2091, 0x8001, 0x007c, 0x70c4, 0x2068,
-+	0x2079, 0x3d00, 0x1078, 0x19c9, 0x0040, 0x189b, 0x6007, 0x0001,
-+	0x600b, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x70c8, 0x6016,
-+	0x6a10, 0x0078, 0x1819, 0x70c3, 0x4005, 0x0078, 0x12a7, 0x78ec,
-+	0xa005, 0x0040, 0x12b2, 0x2091, 0x8000, 0x70c4, 0x800a, 0x2011,
-+	0x0010, 0x810c, 0x0048, 0x18b1, 0x3a00, 0xa084, 0xfff7, 0x0078,
-+	0x18b4, 0x3a00, 0xa085, 0x0008, 0x20d0, 0x0005, 0x0005, 0xa084,
-+	0xfffb, 0x20d0, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005,
-+	0x0005, 0x0005, 0xa085, 0x0004, 0x20d0, 0x0005, 0x0005, 0x0005,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x8211, 0x00c0, 0x18a9,
-+	0x3a00, 0xa085, 0x0008, 0x20d0, 0x2091, 0x8001, 0x0078, 0x12a4,
-+	0x2011, 0x04fd, 0x2204, 0xa082, 0x0004, 0x0048, 0x18ec, 0x78ef,
-+	0x0001, 0x2009, 0xff01, 0x200a, 0x2001, 0x000c, 0x20d8, 0x2001,
-+	0x000c, 0x20d0, 0x0078, 0x12a4, 0x2001, 0x4005, 0x0078, 0x12a6,
-+	0x7978, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x129c, 0x797a,
-+	0x0078, 0x12a4, 0x7978, 0x71c6, 0x0078, 0x12a4, 0x796c, 0x71c6,
-+	0x71c4, 0x796e, 0x7970, 0x71ca, 0x71c8, 0x7972, 0x7974, 0x71ce,
-+	0x71cc, 0x7976, 0x0078, 0x12a4, 0x796c, 0x71c6, 0x7970, 0x71ca,
-+	0x7974, 0x71ce, 0x0078, 0x12a4, 0x7900, 0x71c6, 0x71c4, 0x7902,
-+	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048, 0x1923, 0x0038,
-+	0x1925, 0x0078, 0x192f, 0x00a8, 0x192f, 0xa18c, 0x0001, 0x00c0,
-+	0x192d, 0x20b9, 0x1313, 0x0078, 0x192f, 0x20b9, 0x1212, 0x0078,
-+	0x12a4, 0x7900, 0x71c6, 0x0078, 0x12a4, 0x2009, 0x3d79, 0x2104,
-+	0x70c6, 0x70c4, 0x200a, 0x0078, 0x12a4, 0x2009, 0x3d79, 0x2104,
-+	0x70c6, 0x0078, 0x12a4, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003,
-+	0x8003, 0x8003, 0xa0e8, 0x3f80, 0x6a14, 0xd2b4, 0x0040, 0x1954,
-+	0x2011, 0x0001, 0x0078, 0x1956, 0x2011, 0x0000, 0x6b0c, 0x0078,
-+	0x12a1, 0x700c, 0xa084, 0x00ff, 0x0040, 0x1965, 0x7007, 0x0004,
-+	0x7004, 0xa084, 0x0004, 0x00c0, 0x1960, 0x7017, 0x0000, 0x7112,
-+	0x721a, 0x731e, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
-+	0x81a9, 0x8098, 0x20a1, 0x0030, 0x6084, 0x20a2, 0x53a6, 0x780c,
-+	0xa085, 0x0000, 0x7002, 0x7007, 0x0001, 0x2009, 0x0022, 0x2104,
-+	0xa084, 0x4000, 0x00c0, 0x197d, 0x7108, 0x8103, 0x00c8, 0x197d,
-+	0x7014, 0xa005, 0x0040, 0x197d, 0x7007, 0x0002, 0xa184, 0x01e0,
-+	0x7003, 0x0000, 0x007c, 0x700c, 0xa084, 0x00ff, 0x0040, 0x199f,
-+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x199a, 0x7017,
-+	0x0000, 0x7112, 0x721a, 0x7422, 0x7526, 0x731e, 0x2099, 0x0030,
-+	0x8108, 0x81ac, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001,
-+	0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x19b0, 0x7008,
-+	0x800b, 0x00c8, 0x19b0, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
-+	0x19c6, 0xac80, 0x0001, 0x20a0, 0x53a5, 0xa006, 0x7003, 0x0000,
-+	0x007c, 0x7850, 0xa065, 0x0040, 0x19d1, 0x2c04, 0x7852, 0x2063,
-+	0x0000, 0x007c, 0x0f7e, 0x2079, 0x3d00, 0x7850, 0x2062, 0x2c00,
-+	0xa005, 0x00c0, 0x19dd, 0x1078, 0x20c8, 0x7852, 0x0f7f, 0x007c,
-+	0x2011, 0x6300, 0x7a52, 0x7be0, 0x8319, 0x0040, 0x19ed, 0xa280,
-+	0x002f, 0x2012, 0x2010, 0x0078, 0x19e4, 0x2013, 0x0000, 0x007c,
-+	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003,
-+	0x8003, 0xa105, 0xa0e8, 0x4000, 0x007c, 0x1078, 0x19f0, 0x2900,
-+	0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a,
-+	0x2009, 0x3d4f, 0x210c, 0x6804, 0xa005, 0x0040, 0x1a1a, 0xa116,
-+	0x00c0, 0x1a1a, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000,
-+	0x0078, 0x1a1d, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040,
-+	0x1a2c, 0x6000, 0x6806, 0x1078, 0x1a3d, 0x1078, 0x1b6d, 0x6810,
-+	0x8001, 0x6812, 0x00c0, 0x1a1d, 0x017f, 0x6902, 0x6906, 0x007c,
-+	0xa065, 0x0040, 0x1a3c, 0x609c, 0x609f, 0x0000, 0x2008, 0x1078,
-+	0x19d2, 0x2100, 0x0078, 0x1a30, 0x007c, 0x6007, 0x0103, 0x608f,
-+	0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000,
-+	0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0x2071,
-+	0x3d40, 0x7040, 0xa08c, 0x0200, 0x00c0, 0x1a5c, 0xa088, 0x3d80,
-+	0x2d0a, 0x8000, 0x7042, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
-+	0x3d40, 0x2009, 0x3d80, 0x7240, 0x8221, 0x8211, 0x0048, 0x1a76,
-+	0x2104, 0x8108, 0xad06, 0x00c0, 0x1a65, 0x8119, 0x211e, 0x8108,
-+	0x8318, 0x8211, 0x00c8, 0x1a6e, 0x7442, 0xa006, 0x0e7f, 0x007c,
-+	0x1078, 0x19f0, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065, 0x0040,
-+	0x1ac1, 0x0078, 0x1a89, 0x2c00, 0x781e, 0x6000, 0xa065, 0x0040,
-+	0x1ac1, 0x6010, 0xa306, 0x00c0, 0x1a83, 0x600c, 0xa206, 0x00c0,
-+	0x1a83, 0x2c28, 0x2001, 0x3d4f, 0x2004, 0xac06, 0x00c0, 0x1a9a,
-+	0x0078, 0x1abe, 0x6804, 0xac06, 0x00c0, 0x1aa8, 0x6000, 0x2060,
-+	0x6806, 0xa005, 0x00c0, 0x1aa8, 0x6803, 0x0000, 0x0078, 0x1ab2,
-+	0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1ab2,
-+	0x2c00, 0x6802, 0x2560, 0x1078, 0x1a3d, 0x601b, 0x0005, 0x6023,
-+	0x0020, 0x1078, 0x1b6d, 0x6810, 0x8001, 0x6812, 0x2001, 0xffff,
-+	0xa005, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004,
-+	0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x19fd, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x1acc, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f,
-+	0xa784, 0x0f00, 0x00c0, 0x1acc, 0x2091, 0x8001, 0x007c, 0x2061,
-+	0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1af0, 0x2091, 0x8000,
-+	0x78d4, 0x78d7, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1af1,
-+	0x007c, 0xa08c, 0xfff0, 0x0040, 0x1af7, 0x1078, 0x20c8, 0x0079,
-+	0x1af9, 0x1b09, 0x1b0c, 0x1b12, 0x1b16, 0x1b0a, 0x1b1a, 0x1b0a,
-+	0x1b20, 0x1b24, 0x1b28, 0x1b5b, 0x1b5f, 0x1b0a, 0x1b0a, 0x1b0a,
-+	0x1b0a, 0x007c, 0x1078, 0x20c8, 0x1078, 0x1ac2, 0x2001, 0x8001,
-+	0x0078, 0x1b65, 0x2001, 0x8003, 0x0078, 0x1b65, 0x2001, 0x8004,
-+	0x0078, 0x1b65, 0x1078, 0x1ac2, 0x2001, 0x8006, 0x0078, 0x1b65,
-+	0x2001, 0x8008, 0x0078, 0x1b65, 0x2001, 0x8009, 0x0078, 0x1b65,
-+	0x2091, 0x8000, 0x2069, 0x3d40, 0x6800, 0xa086, 0x0000, 0x0040,
-+	0x1b36, 0x2091, 0x8001, 0x78d7, 0x0009, 0x007c, 0x68b4, 0xa0bc,
-+	0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078,
-+	0x19fd, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1b3f, 0x2091, 0x8001,
-+	0x2001, 0x800a, 0x0078, 0x1b65, 0x2001, 0x04fd, 0x2004, 0xa082,
-+	0x0004, 0x00c8, 0x1b55, 0x0078, 0x1b58, 0xa006, 0x0078, 0x1b5a,
-+	0xa085, 0x0001, 0x007c, 0x2001, 0x800c, 0x0078, 0x1b65, 0x1078,
-+	0x1ac2, 0x2001, 0x800d, 0x0078, 0x1b65, 0x70c2, 0x2061, 0x0000,
-+	0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0x6004, 0x6086, 0x2c08,
-+	0x2063, 0x0000, 0x787c, 0x8000, 0x787e, 0x7880, 0xa005, 0x7982,
-+	0x0040, 0x1b7d, 0x2c02, 0x0078, 0x1b7e, 0x7986, 0x007c, 0x0c7e,
-+	0x2061, 0x3d00, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x607c,
-+	0x8000, 0x607e, 0x6080, 0xa005, 0x6182, 0x0040, 0x1b92, 0x2d02,
-+	0x0078, 0x1b93, 0x6186, 0x0c7f, 0x007c, 0x1078, 0x1ba6, 0x0040,
-+	0x1ba5, 0x0c7e, 0x609c, 0xa065, 0x0040, 0x1ba0, 0x1078, 0x1a30,
-+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x19d2, 0x007c, 0x7884, 0xa065,
-+	0x0040, 0x1bb8, 0x2091, 0x8000, 0x787c, 0x8001, 0x787e, 0x2c04,
-+	0x7886, 0xa005, 0x00c0, 0x1bb6, 0x7882, 0x8000, 0x2091, 0x8001,
-+	0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8,
-+	0x1bc2, 0xa200, 0x0070, 0x1bc6, 0x0078, 0x1bbd, 0x8086, 0x818e,
-+	0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1bec, 0xa11a,
-+	0x00c8, 0x1bec, 0x8213, 0x818d, 0x0048, 0x1bdd, 0xa11a, 0x00c8,
-+	0x1bde, 0x0070, 0x1be4, 0x0078, 0x1bd2, 0xa11a, 0x2308, 0x8210,
-+	0x0070, 0x1be4, 0x0078, 0x1bd2, 0x007e, 0x3200, 0xa084, 0xf7ff,
-+	0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800,
-+	0x0078, 0x1be8, 0x798c, 0x70d0, 0x007e, 0x007f, 0xa106, 0x0040,
-+	0x1c6e, 0x7800, 0xa084, 0x0002, 0x0040, 0x1c05, 0x2011, 0x04fd,
-+	0x2204, 0xa082, 0x0005, 0x00c8, 0x1c18, 0x2091, 0x8000, 0x2071,
-+	0x0020, 0x7004, 0xa005, 0x00c0, 0x1c6e, 0x7008, 0x7208, 0xa206,
-+	0x00c0, 0x1c6e, 0xa286, 0x0008, 0x00c0, 0x1c6e, 0x2071, 0x0010,
-+	0x1078, 0x19c9, 0x0040, 0x1c6e, 0x7a94, 0x7b90, 0x7c9c, 0x7d98,
-+	0xa184, 0xff00, 0x0040, 0x1c3c, 0x2031, 0x0000, 0x810b, 0x86b5,
-+	0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5,
-+	0x810b, 0x86b5, 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000,
-+	0xa5a9, 0x0000, 0x0078, 0x1c46, 0x8107, 0x8004, 0x8004, 0xa210,
-+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0040,
-+	0x1078, 0x1993, 0x2091, 0x8001, 0x0040, 0x1c65, 0x1078, 0x19d2,
-+	0x78a0, 0x8000, 0x78a2, 0xa086, 0x0002, 0x00c0, 0x1c6e, 0x2091,
-+	0x8000, 0x78d7, 0x0002, 0x78a3, 0x0000, 0x78c0, 0xa085, 0x0003,
-+	0x78c2, 0x2091, 0x8001, 0x0078, 0x1c6e, 0x78a3, 0x0000, 0x1078,
-+	0x1e0d, 0x6004, 0xa084, 0x000f, 0x0079, 0x1c73, 0x2071, 0x0010,
-+	0x2091, 0x8001, 0x007c, 0x1c83, 0x1ca5, 0x1ccb, 0x1c83, 0x1cdd,
-+	0x1c92, 0x1c83, 0x1c83, 0x1c83, 0x1c9f, 0x1cc5, 0x1c83, 0x1c83,
-+	0x1c83, 0x1c83, 0x1c83, 0x2039, 0x0400, 0x78d0, 0xa705, 0x78d2,
-+	0x6008, 0xa705, 0x600a, 0x1078, 0x1d28, 0x609c, 0x78ce, 0x1078,
-+	0x1df5, 0x007c, 0x78d0, 0xa084, 0x0100, 0x0040, 0x1c99, 0x0078,
-+	0x1c83, 0x601c, 0xa085, 0x0080, 0x601e, 0x0078, 0x1cac, 0x1078,
-+	0x1b4c, 0x00c0, 0x1c83, 0x1078, 0x1e27, 0x78d0, 0xa084, 0x0100,
-+	0x0040, 0x1cac, 0x0078, 0x1c83, 0x78d3, 0x0000, 0x6004, 0x8007,
-+	0xa084, 0x00ff, 0x78c6, 0x8001, 0x609f, 0x0000, 0x0040, 0x1cc2,
-+	0x1078, 0x1d28, 0x0040, 0x1cc2, 0x78d0, 0xa085, 0x0100, 0x78d2,
-+	0x0078, 0x1cc4, 0x1078, 0x1d4c, 0x007c, 0x1078, 0x1b4c, 0x00c0,
-+	0x1c83, 0x1078, 0x1e23, 0x78d0, 0xa08c, 0x0e00, 0x00c0, 0x1cd4,
-+	0xa084, 0x0100, 0x00c0, 0x1cd6, 0x0078, 0x1c83, 0x1078, 0x1d28,
-+	0x00c0, 0x1cdc, 0x1078, 0x1d4c, 0x007c, 0x78d0, 0xa084, 0x0100,
-+	0x0040, 0x1ce4, 0x0078, 0x1c83, 0x78d3, 0x0000, 0x6714, 0x2011,
-+	0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040,
-+	0x1d07, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e,
-+	0x0001, 0x0040, 0x1d07, 0x2039, 0x0000, 0x2011, 0x0002, 0x20a9,
-+	0x0100, 0xa08e, 0x0002, 0x0040, 0x1d07, 0x0078, 0x1d25, 0x1078,
-+	0x19f0, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
-+	0x6808, 0xa084, 0xffde, 0x680a, 0x2d00, 0xa080, 0x0010, 0x2068,
-+	0x2091, 0x8001, 0x0070, 0x1d1e, 0x0078, 0x1d0a, 0x8211, 0x0040,
-+	0x1d25, 0x20a9, 0x0100, 0x0078, 0x1d0a, 0x1078, 0x19d2, 0x007c,
-+	0x78c8, 0xa06d, 0x00c0, 0x1d33, 0x2c00, 0x78ca, 0x78ce, 0x609f,
-+	0x0000, 0x0078, 0x1d3f, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78ca,
-+	0x2d00, 0x6002, 0x78cc, 0xad06, 0x00c0, 0x1d3f, 0x6002, 0x78c4,
-+	0x8001, 0x78c6, 0x00c0, 0x1d4b, 0x78d0, 0xa084, 0x0000, 0x78d2,
-+	0x78cc, 0x2060, 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2,
-+	0xa184, 0xe1ff, 0x601e, 0xa184, 0x0060, 0x0040, 0x1d5b, 0x0e7e,
-+	0x1078, 0x3736, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af,
-+	0x0000, 0x60b3, 0x0000, 0x6714, 0x1078, 0x19f0, 0x2091, 0x8000,
-+	0x60a0, 0xa084, 0x8000, 0x00c0, 0x1d82, 0x6808, 0xa084, 0x0001,
-+	0x0040, 0x1d82, 0x2091, 0x8001, 0x1078, 0x1a3d, 0x2091, 0x8000,
-+	0x1078, 0x1b6d, 0x2091, 0x8001, 0x78cb, 0x0000, 0x78cf, 0x0000,
-+	0x0078, 0x1df4, 0x6024, 0xa096, 0x0001, 0x00c0, 0x1d89, 0x8000,
-+	0x6026, 0x6a10, 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x1d98,
-+	0x0040, 0x1d98, 0x2039, 0x0200, 0x1078, 0x1df5, 0x0078, 0x1df4,
-+	0x2c08, 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x1dc5,
-+	0x6800, 0xa065, 0x0040, 0x1dca, 0x6a04, 0x0e7e, 0x2071, 0x3d40,
-+	0x7000, 0xa084, 0x0001, 0x0040, 0x1dbf, 0x703c, 0xa206, 0x00c0,
-+	0x1dbf, 0x6b04, 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0,
-+	0x1dba, 0x6902, 0x2260, 0x6102, 0x0e7f, 0x0078, 0x1dd1, 0x2160,
-+	0x6202, 0x6906, 0x0e7f, 0x0078, 0x1dd1, 0x6800, 0xa065, 0x0040,
-+	0x1dca, 0x6102, 0x6902, 0x00c0, 0x1dce, 0x6906, 0x2160, 0x6003,
-+	0x0000, 0x2160, 0x60a0, 0xa084, 0x8000, 0x0040, 0x1ddb, 0x6808,
-+	0xa084, 0xfffc, 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001,
-+	0x6808, 0xa08c, 0x0040, 0x0040, 0x1dea, 0xa086, 0x0040, 0x680a,
-+	0x1078, 0x1a4e, 0x2091, 0x8000, 0x1078, 0x1f05, 0x2091, 0x8001,
-+	0x78cf, 0x0000, 0x78cb, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a,
-+	0x2091, 0x8000, 0x1078, 0x1b6d, 0x2091, 0x8001, 0x78cc, 0xa065,
-+	0x0040, 0x1e08, 0x609c, 0x78ce, 0x609f, 0x0000, 0x0078, 0x1df8,
-+	0x78cb, 0x0000, 0x78cf, 0x0000, 0x007c, 0x7988, 0x788c, 0x8000,
-+	0xa10a, 0x00c8, 0x1e14, 0xa006, 0x788e, 0x70d2, 0x7804, 0xa005,
-+	0x0040, 0x1e22, 0x8001, 0x7806, 0x00c0, 0x1e22, 0x0068, 0x1e22,
-+	0x2091, 0x4080, 0x007c, 0x2039, 0x1e3b, 0x0078, 0x1e29, 0x2039,
-+	0x1e41, 0x2704, 0xa005, 0x0040, 0x1e3a, 0xac00, 0x2068, 0x6b08,
-+	0x6c0c, 0x6910, 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738,
-+	0x0078, 0x1e29, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
-+	0x0000, 0x0015, 0x001b, 0x0000, 0x0068, 0x1e8a, 0x2029, 0x0000,
-+	0x7884, 0xa065, 0x0040, 0x1e85, 0x2009, 0x3d79, 0x2104, 0xa084,
-+	0x0001, 0x0040, 0x1e78, 0x6084, 0xa086, 0x0103, 0x00c0, 0x1e78,
-+	0x6018, 0xa005, 0x00c0, 0x1e78, 0x6014, 0xa005, 0x00c0, 0x1e78,
-+	0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x1e77,
-+	0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001,
-+	0x2091, 0x4080, 0x0d7f, 0x1078, 0x1b95, 0x0078, 0x1e85, 0x0d7f,
-+	0x1078, 0x1e8b, 0x0040, 0x1e85, 0x057e, 0x1078, 0x1e9c, 0x057f,
-+	0x00c0, 0x1e85, 0x8528, 0x0078, 0x1e48, 0x85ff, 0x0040, 0x1e8a,
-+	0x2091, 0x4080, 0x007c, 0x7ba4, 0x79a8, 0x70d4, 0x007e, 0x007f,
-+	0xa102, 0x00c0, 0x1e96, 0x2300, 0xa005, 0x007c, 0x0048, 0x1e9a,
-+	0xa302, 0x007c, 0x8002, 0x007c, 0x7800, 0xa084, 0x0002, 0x0040,
-+	0x1ea8, 0x2011, 0x04fd, 0x2204, 0xa082, 0x0005, 0x00c8, 0x1ebb,
-+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1eec,
-+	0x7008, 0x7208, 0xa206, 0x00c0, 0x1eec, 0xa286, 0x0008, 0x00c0,
-+	0x1eec, 0x2071, 0x0010, 0x1078, 0x1ef1, 0x2009, 0x0018, 0x6028,
-+	0xa005, 0x0040, 0x1ec5, 0x2009, 0x0040, 0x1078, 0x1959, 0x0040,
-+	0x1ede, 0x78bc, 0x8000, 0x78be, 0xa086, 0x0002, 0x00c0, 0x1eec,
-+	0x2091, 0x8000, 0x78d7, 0x0003, 0x78bf, 0x0000, 0x78c0, 0xa085,
-+	0x0300, 0x78c2, 0x2091, 0x8001, 0x0078, 0x1eec, 0x78bf, 0x0000,
-+	0x1078, 0x1b95, 0x79a4, 0x78a8, 0x8000, 0xa10a, 0x00c8, 0x1ee9,
-+	0xa006, 0x78aa, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001,
-+	0x007c, 0x8107, 0x8004, 0x8004, 0x7ab0, 0x7bac, 0x7cb8, 0x7db4,
-+	0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c,
-+	0x2009, 0x3d68, 0x2091, 0x8000, 0x200a, 0x0f7e, 0x2079, 0x0100,
-+	0x2009, 0x3d40, 0x2104, 0xa086, 0x0000, 0x00c0, 0x1f1e, 0x2009,
-+	0x3d12, 0x2104, 0xa005, 0x00c0, 0x1f1e, 0x7830, 0xa084, 0x00c0,
-+	0x00c0, 0x1f1e, 0x0018, 0x1f1e, 0x781b, 0x0045, 0x0f7f, 0x007c,
-+	0x127e, 0x2091, 0x2300, 0x2071, 0x3d40, 0x2079, 0x0100, 0x784b,
-+	0x000f, 0x2019, 0x35fc, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040,
-+	0x1f3a, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318,
-+	0x0078, 0x1f2d, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000,
-+	0x78af, 0x0020, 0x0070, 0x1f46, 0x0078, 0x1f3e, 0x7003, 0x0000,
-+	0x1078, 0x205c, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd,
-+	0x210c, 0xa18a, 0x0005, 0x0048, 0x1f5d, 0x0038, 0x1f59, 0x0078,
-+	0x1f5d, 0xa085, 0x62c0, 0x0078, 0x1f5f, 0xa085, 0x6280, 0x017f,
-+	0x7806, 0x780f, 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b,
-+	0x0008, 0x7047, 0x3d7f, 0x7043, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105,
-+	0x2012, 0x1078, 0x205c, 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009,
-+	0x810b, 0x0070, 0x1f85, 0x0078, 0x1f80, 0xa18c, 0x0e00, 0x2204,
-+	0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9,
-+	0x0005, 0x8213, 0x0070, 0x1f96, 0x0078, 0x1f91, 0xa294, 0x00e0,
-+	0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, 0x2011, 0x0101,
-+	0x20a9, 0x000c, 0x810b, 0x0070, 0x1fa7, 0x0078, 0x1fa2, 0xa18c,
-+	0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011,
-+	0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103,
-+	0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac,
-+	0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
-+	0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
-+	0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100,
-+	0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103,
-+	0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
-+	0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091,
-+	0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x203a, 0x2061,
-+	0x6100, 0x1078, 0x2042, 0x0040, 0x2024, 0x20a9, 0x0000, 0x2061,
-+	0x6000, 0x0c7e, 0x1078, 0x2042, 0x0040, 0x200e, 0x0c7f, 0x8c60,
-+	0x0070, 0x200c, 0x0078, 0x2001, 0x0078, 0x203a, 0x007f, 0xa082,
-+	0x6000, 0x2071, 0x3d40, 0x70ba, 0x6020, 0xa085, 0x0800, 0x6022,
-+	0x71b6, 0x2001, 0x0004, 0x70a2, 0x70c7, 0x000f, 0x70a7, 0x0000,
-+	0x1078, 0x1f00, 0x0078, 0x2036, 0x2071, 0x3d40, 0x6020, 0xa085,
-+	0x0800, 0x6022, 0x71b6, 0x2c00, 0x70be, 0x2001, 0x0006, 0x70a2,
-+	0x70c7, 0x000f, 0x70a7, 0x0000, 0x1078, 0x1f00, 0x2001, 0x0000,
-+	0x0078, 0x203c, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f,
-+	0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x2059, 0x2060, 0x6010,
-+	0xa306, 0x00c0, 0x2056, 0x600c, 0xa206, 0x00c0, 0x2056, 0x6014,
-+	0xa106, 0x00c0, 0x2056, 0xa006, 0x0078, 0x205b, 0x6000, 0x0078,
-+	0x2043, 0xa085, 0x0001, 0x007c, 0x2011, 0x3d41, 0x220c, 0xa18c,
-+	0x000f, 0x2011, 0x013b, 0x2204, 0xa084, 0x0100, 0x0040, 0x2072,
-+	0x2021, 0xff04, 0x2122, 0x810b, 0x810b, 0x810b, 0x810b, 0xa18d,
-+	0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4, 0xa08c, 0x0020, 0x0040,
-+	0x20c6, 0xa084, 0x0006, 0x00c0, 0x20c6, 0x6014, 0x8007, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x3f80, 0x7004, 0xa084,
-+	0x000a, 0x00c0, 0x20c6, 0x7108, 0xa194, 0xff00, 0x0040, 0x20c6,
-+	0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106, 0x0040, 0x20ad, 0x2001,
-+	0x0012, 0xa106, 0x0040, 0x20b1, 0x2001, 0x0014, 0xa106, 0x0040,
-+	0x20b5, 0x2001, 0x0019, 0xa106, 0x0040, 0x20b9, 0x2001, 0x0032,
-+	0xa106, 0x0040, 0x20bd, 0x0078, 0x20c1, 0x2009, 0x0012, 0x0078,
-+	0x20c3, 0x2009, 0x0014, 0x0078, 0x20c3, 0x2009, 0x0019, 0x0078,
-+	0x20c3, 0x2009, 0x0020, 0x0078, 0x20c3, 0x2009, 0x003f, 0x0078,
-+	0x20c3, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x0e7f, 0x007c,
-+	0x0068, 0x20c8, 0x2091, 0x8000, 0x2071, 0x0000, 0x007e, 0x7018,
-+	0xa084, 0x0001, 0x00c0, 0x20cf, 0x007f, 0x2071, 0x0010, 0x70ca,
-+	0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0442, 0x70df, 0x0000,
-+	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x20e6,
-+	0x107e, 0x007e, 0x127e, 0x2091, 0x2300, 0x7f3c, 0x7e58, 0x7c30,
-+	0x7d38, 0x2009, 0x3d74, 0x78a0, 0x200a, 0x8108, 0x250a, 0x8108,
-+	0x240a, 0x8108, 0x260a, 0x8108, 0x270a, 0xa594, 0x003f, 0xa484,
-+	0x4000, 0x0040, 0x210c, 0xa784, 0x007d, 0x00c0, 0x3585, 0xd784,
-+	0x00c0, 0x2d06, 0x1078, 0x20c8, 0xa49c, 0x000f, 0xa382, 0x0004,
-+	0x0050, 0x2114, 0x1078, 0x20c8, 0x8507, 0xa084, 0x000f, 0x0079,
-+	0x2119, 0x25cf, 0x268a, 0x26b2, 0x2946, 0x2bc0, 0x2c23, 0x2c81,
-+	0x2d06, 0x2dad, 0x2e33, 0x2141, 0x2129, 0x2418, 0x24ef, 0x2b9b,
-+	0x2129, 0x1078, 0x20c8, 0x0018, 0x20ed, 0x127f, 0x2091, 0x8001,
-+	0x007f, 0x107f, 0x007c, 0x7003, 0x0000, 0x703f, 0x0000, 0x7030,
-+	0xa005, 0x0040, 0x213d, 0x7033, 0x0000, 0x1078, 0x355b, 0x0018,
-+	0x20ed, 0x2009, 0x3d0f, 0x200b, 0x0000, 0x705c, 0xa005, 0x00c0,
-+	0x2216, 0x70a0, 0xa084, 0x0007, 0x0079, 0x214e, 0x2242, 0x2156,
-+	0x2164, 0x2181, 0x21a3, 0x21f0, 0x21c9, 0x2156, 0x7808, 0xa084,
-+	0xfffd, 0x780a, 0x2009, 0x0047, 0x1078, 0x2a7a, 0x00c0, 0x2162,
-+	0x7003, 0x0004, 0x0078, 0x212b, 0x1078, 0x3542, 0x00c0, 0x217f,
-+	0x70b4, 0x8007, 0x7882, 0x789b, 0x0010, 0x78ab, 0x000c, 0x789b,
-+	0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009, 0x00fa, 0x1078,
-+	0x2a78, 0x00c0, 0x217f, 0x7003, 0x0004, 0x70c7, 0x000f, 0x0078,
-+	0x212b, 0x1078, 0x3542, 0x00c0, 0x21a1, 0x71b4, 0x8107, 0x7882,
-+	0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab,
-+	0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009,
-+	0x00fa, 0x1078, 0x2a78, 0x00c0, 0x21a1, 0x7003, 0x0004, 0x70c7,
-+	0x000f, 0x0078, 0x212b, 0x1078, 0x3542, 0x00c0, 0x21c7, 0x71b4,
-+	0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0,
-+	0x79aa, 0x78ab, 0x0020, 0x71b8, 0x79aa, 0x78ab, 0x000d, 0x789b,
-+	0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009, 0x00fa, 0x1078,
-+	0x2a78, 0x00c0, 0x21c7, 0x7003, 0x0004, 0x70c7, 0x000f, 0x0078,
-+	0x212b, 0x1078, 0x3542, 0x00c0, 0x21ee, 0x71b4, 0x8107, 0x7882,
-+	0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab,
-+	0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009,
-+	0x00fa, 0x1078, 0x2a78, 0x00c0, 0x21ee, 0x70bc, 0x70bf, 0x0000,
-+	0x2068, 0x703e, 0x7003, 0x0002, 0x70c7, 0x000f, 0x0078, 0x212b,
-+	0x1078, 0x3542, 0x00c0, 0x212b, 0x70bc, 0x2068, 0x6f14, 0x1078,
-+	0x3449, 0x2c50, 0x1078, 0x35ea, 0x789b, 0x0010, 0x6814, 0xa084,
-+	0x001f, 0xa085, 0x0080, 0x007e, 0x007f, 0x78aa, 0x6e1c, 0x067e,
-+	0x067f, 0x2041, 0x0001, 0x70c0, 0xa084, 0x0400, 0x2001, 0x0004,
-+	0x0040, 0x2214, 0x2001, 0x0006, 0x0078, 0x2334, 0x1078, 0x3542,
-+	0x00c0, 0x212b, 0x789b, 0x0010, 0x705c, 0x2068, 0x6f14, 0x1078,
-+	0x3449, 0x2c50, 0x1078, 0x35ea, 0x6008, 0xa085, 0x0010, 0x600a,
-+	0x6824, 0xa005, 0x0040, 0x2234, 0xa082, 0x0006, 0x0048, 0x2232,
-+	0x0078, 0x2234, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xa085,
-+	0x0080, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003,
-+	0x0078, 0x2334, 0x0018, 0x20ed, 0x7440, 0xa485, 0x0000, 0x0040,
-+	0x226c, 0xa080, 0x3d80, 0x2030, 0x7144, 0x0018, 0x20ed, 0x8108,
-+	0xa12a, 0x0048, 0x2255, 0x2009, 0x3d80, 0x2164, 0x6504, 0x85ff,
-+	0x00c0, 0x2279, 0x8421, 0x00c0, 0x224d, 0x017e, 0x2009, 0x3d0f,
-+	0x2104, 0xa005, 0x00c0, 0x226a, 0x017e, 0x2009, 0x3d10, 0x2104,
-+	0x017f, 0x200a, 0x017f, 0x7146, 0x7003, 0x0000, 0x703f, 0x0000,
-+	0x0078, 0x212b, 0x7640, 0xa6b0, 0x3d80, 0x7144, 0x2600, 0x0078,
-+	0x225a, 0x7146, 0x2568, 0x2558, 0x753e, 0x2c50, 0x6034, 0xa085,
-+	0x0000, 0x00c0, 0x2276, 0x6708, 0x7736, 0xa784, 0x013f, 0x0040,
-+	0x22a7, 0xa784, 0x0021, 0x00c0, 0x2276, 0xa784, 0x0002, 0x0040,
-+	0x2298, 0xa784, 0x0004, 0x0040, 0x2276, 0xa7bc, 0xfffb, 0x670a,
-+	0xa784, 0x0018, 0x00c0, 0x2276, 0xa784, 0x0100, 0x0040, 0x22a7,
-+	0x6018, 0xa005, 0x00c0, 0x2276, 0xa7bc, 0xfeff, 0x670a, 0x6823,
-+	0x0000, 0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040, 0x22b7, 0x601c,
-+	0xa102, 0x0048, 0x22ba, 0x0040, 0x22ba, 0x0078, 0x2272, 0x81ff,
-+	0x00c0, 0x2272, 0xa784, 0x0080, 0x00c0, 0x22c0, 0x700c, 0x6022,
-+	0xa7bc, 0xff7f, 0x670a, 0x1078, 0x35ea, 0x0018, 0x20ed, 0x789b,
-+	0x0010, 0xa046, 0x1078, 0x3542, 0x00c0, 0x212b, 0x6b14, 0xa39c,
-+	0x001f, 0xa39d, 0x00c0, 0x704c, 0xa084, 0x8000, 0x0040, 0x22dc,
-+	0xa684, 0x0001, 0x0040, 0x22de, 0xa39c, 0xffbf, 0xa684, 0x0010,
-+	0x0040, 0x22e4, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e,
-+	0x00c0, 0x22ef, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x2330, 0x714c,
-+	0xa18c, 0x0800, 0x0040, 0x304e, 0x2011, 0x0021, 0x8004, 0x8004,
-+	0x0048, 0x2306, 0x2011, 0x0022, 0x8004, 0x0048, 0x2306, 0x2011,
-+	0x0020, 0x8004, 0x0048, 0x2306, 0x0040, 0x2330, 0x7aaa, 0x8840,
-+	0x1078, 0x355b, 0x6a14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0xa1e0,
-+	0x6000, 0x2c64, 0x8cff, 0x0040, 0x2327, 0x6014, 0xa206, 0x00c0,
-+	0x2311, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x230c, 0x0c7e, 0x2a60,
-+	0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x2242, 0x1078,
-+	0x3542, 0x00c0, 0x212b, 0x2a60, 0x610e, 0x79aa, 0x8840, 0x712e,
-+	0x0018, 0x20ed, 0x2001, 0x0001, 0x007e, 0x7150, 0xa184, 0x0018,
-+	0x0040, 0x234f, 0xa184, 0x0010, 0x0040, 0x2342, 0x1078, 0x3273,
-+	0x00c0, 0x2372, 0xa184, 0x0008, 0x0040, 0x234f, 0x69a0, 0xa184,
-+	0x0600, 0x00c0, 0x234f, 0x1078, 0x316f, 0x0078, 0x2372, 0x69a0,
-+	0xa184, 0x0800, 0x0040, 0x2366, 0x0c7e, 0x027e, 0x2960, 0x6000,
-+	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f,
-+	0x0c7f, 0x1078, 0x3273, 0x00c0, 0x2372, 0x69a0, 0xa184, 0x0200,
-+	0x0040, 0x236e, 0x1078, 0x31be, 0x0078, 0x2372, 0xa184, 0x0400,
-+	0x00c0, 0x234b, 0x69a0, 0xa184, 0x1000, 0x0040, 0x237d, 0x6914,
-+	0xa18c, 0xff00, 0x810f, 0x1078, 0x1fc3, 0x007f, 0x0018, 0x20ed,
-+	0x7002, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x238d, 0xa086,
-+	0x0060, 0x00c0, 0x238d, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x2392,
-+	0xa18d, 0x0004, 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa,
-+	0x789b, 0x0061, 0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a,
-+	0xa68c, 0x0080, 0x0040, 0x23b1, 0x70cb, 0x0000, 0xa08a, 0x000d,
-+	0x0050, 0x23af, 0xa08a, 0x000c, 0x71ca, 0x2001, 0x000c, 0x800c,
-+	0x71ce, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3054, 0xa18c, 0x00f8,
-+	0x00c0, 0x3054, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b,
-+	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
-+	0x137f, 0x157f, 0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde,
-+	0x6e98, 0x7ed2, 0x7eda, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x23da,
-+	0x0098, 0x23e2, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x355b,
-+	0x0078, 0x2133, 0x7200, 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0,
-+	0x23ef, 0x781b, 0x004a, 0x1078, 0x355b, 0x0078, 0x2400, 0x6ab4,
-+	0xa295, 0x2000, 0x7a5a, 0x781b, 0x004a, 0x1078, 0x355b, 0x7200,
-+	0x2500, 0xa605, 0x0040, 0x2400, 0xa284, 0x0007, 0x1079, 0x240e,
-+	0xad80, 0x0009, 0x7032, 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0,
-+	0x212b, 0x6018, 0x8000, 0x601a, 0x0078, 0x212b, 0x2416, 0x39a0,
-+	0x39a0, 0x398f, 0x39a0, 0x2416, 0x398f, 0x2416, 0x1078, 0x20c8,
-+	0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, 0x3d00, 0x78c0,
-+	0x0f7f, 0xa084, 0x0001, 0x0040, 0x243e, 0x70a0, 0xa086, 0x0001,
-+	0x00c0, 0x242d, 0x70a2, 0x0078, 0x24d1, 0x70a0, 0xa086, 0x0005,
-+	0x00c0, 0x243c, 0x70bc, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000,
-+	0x6820, 0xa085, 0x0008, 0x6822, 0x70a3, 0x0000, 0x157e, 0x2011,
-+	0x0004, 0x71a0, 0xa186, 0x0001, 0x0040, 0x2460, 0xa186, 0x0007,
-+	0x00c0, 0x2450, 0x2009, 0x3d35, 0x200b, 0x0005, 0x0078, 0x2460,
-+	0x2009, 0x3d13, 0x2104, 0x2009, 0x3d12, 0x200a, 0x2009, 0x3d35,
-+	0x200b, 0x0001, 0x70a3, 0x0000, 0x70a7, 0x0001, 0x0078, 0x2462,
-+	0x70a3, 0x0000, 0x1078, 0x36ec, 0x20a9, 0x0010, 0x2039, 0x0000,
-+	0x1078, 0x3340, 0xa7b8, 0x0100, 0x0070, 0x2470, 0x0078, 0x2468,
-+	0x7000, 0x0079, 0x2473, 0x24a3, 0x248a, 0x248a, 0x247d, 0x24a3,
-+	0x24a3, 0x24a3, 0x247b, 0x1078, 0x20c8, 0x2021, 0x3d57, 0x2404,
-+	0xa005, 0x0040, 0x24a3, 0xad06, 0x00c0, 0x248a, 0x6800, 0x2022,
-+	0x0078, 0x249a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2496, 0x6f14,
-+	0x1078, 0x3449, 0x1078, 0x3025, 0x0078, 0x249a, 0x7054, 0x2060,
-+	0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008,
-+	0x6822, 0x1078, 0x1b7f, 0x2021, 0x6100, 0x1078, 0x24d7, 0x2021,
-+	0x3d57, 0x1078, 0x24d7, 0x20a9, 0x0000, 0x2021, 0x6000, 0x1078,
-+	0x24d7, 0x8420, 0x0070, 0x24b6, 0x0078, 0x24af, 0x2061, 0x4000,
-+	0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff, 0x0040,
-+	0x24c5, 0xa102, 0x0050, 0x24c5, 0x6012, 0x601b, 0x0000, 0xace0,
-+	0x0010, 0x0070, 0x24cd, 0x0078, 0x24bc, 0x8421, 0x00c0, 0x24ba,
-+	0x157f, 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x212b, 0x047e,
-+	0x2404, 0xa005, 0x0040, 0x24eb, 0x2068, 0x6800, 0x007e, 0x6a1a,
-+	0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, 0x1b7f,
-+	0x007f, 0x0078, 0x24d9, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282,
-+	0x0003, 0x0050, 0x24f5, 0x1078, 0x20c8, 0x2300, 0x0079, 0x24f8,
-+	0x24fb, 0x256e, 0x258b, 0xa282, 0x0002, 0x0040, 0x2501, 0x1078,
-+	0x20c8, 0x70a0, 0x70a3, 0x0000, 0x70c7, 0x0000, 0x0079, 0x2508,
-+	0x2510, 0x2510, 0x2512, 0x2546, 0x305a, 0x2510, 0x2546, 0x2510,
-+	0x1078, 0x20c8, 0x77b4, 0x1078, 0x3340, 0x77b4, 0xa7bc, 0x0f00,
-+	0x1078, 0x3449, 0x6018, 0xa005, 0x0040, 0x253d, 0x2021, 0x6100,
-+	0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x25a8, 0x0040, 0x253d,
-+	0x157e, 0x20a9, 0x0000, 0x2021, 0x6000, 0x047e, 0x2009, 0x0004,
-+	0x2011, 0x0010, 0x1078, 0x25a8, 0x047f, 0x0040, 0x253c, 0x8420,
-+	0x0070, 0x253c, 0x0078, 0x252d, 0x157f, 0x8738, 0xa784, 0x001f,
-+	0x00c0, 0x2518, 0x0078, 0x2133, 0x0078, 0x2133, 0x77b4, 0x1078,
-+	0x3449, 0x6018, 0xa005, 0x0040, 0x256c, 0x2021, 0x6100, 0x2009,
-+	0x0005, 0x2011, 0x0020, 0x1078, 0x25a8, 0x0040, 0x256c, 0x157e,
-+	0x20a9, 0x0000, 0x2021, 0x6000, 0x047e, 0x2009, 0x0005, 0x2011,
-+	0x0020, 0x1078, 0x25a8, 0x047f, 0x0040, 0x256b, 0x8420, 0x0070,
-+	0x256b, 0x0078, 0x255c, 0x157f, 0x0078, 0x2133, 0x2200, 0x0079,
-+	0x2571, 0x2574, 0x2576, 0x2576, 0x1078, 0x20c8, 0x2009, 0x0012,
-+	0x70a0, 0xa086, 0x0002, 0x0040, 0x257f, 0x2009, 0x000e, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2585, 0x691a, 0x70a3, 0x0000, 0x70a7,
-+	0x0001, 0x0078, 0x34da, 0x2200, 0x0079, 0x258e, 0x2593, 0x2576,
-+	0x2591, 0x1078, 0x20c8, 0x7000, 0xa086, 0x0001, 0x00c0, 0x25a4,
-+	0x1078, 0x303b, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x2fdd,
-+	0x0040, 0x25a4, 0x0078, 0x2242, 0x1078, 0x2a87, 0x0078, 0x2fea,
-+	0x2404, 0xa005, 0x0040, 0x25cb, 0x2068, 0x2d04, 0x007e, 0x6814,
-+	0xa706, 0x0040, 0x25b7, 0x2d20, 0x007f, 0x0078, 0x25a9, 0x007f,
-+	0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078,
-+	0x1b7f, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a,
-+	0x1078, 0x303b, 0x007c, 0xa085, 0x0001, 0x0078, 0x25ca, 0x2300,
-+	0x0079, 0x25d2, 0x25d7, 0x25d5, 0x2630, 0x1078, 0x20c8, 0x78e4,
-+	0xa005, 0x00d0, 0x25fa, 0x0018, 0x212b, 0x2008, 0xa084, 0x0030,
-+	0x00c0, 0x25e6, 0x781b, 0x004a, 0x0078, 0x212b, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x25e2, 0x2100, 0xa084, 0x0007, 0x0079, 0x25f0,
-+	0x260b, 0x2616, 0x25fe, 0x25f8, 0x3535, 0x3535, 0x25f8, 0x2623,
-+	0x1078, 0x20c8, 0x2001, 0x0003, 0x0078, 0x295a, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x2605, 0x681b, 0x001d, 0x1078, 0x3323, 0x781b,
-+	0x0053, 0x0078, 0x212b, 0x6818, 0xa084, 0x8000, 0x0040, 0x2612,
-+	0x681b, 0x001d, 0x1078, 0x3323, 0x0078, 0x3506, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x261d, 0x681b, 0x001d, 0x1078, 0x3323, 0x781b,
-+	0x00e3, 0x0078, 0x212b, 0x6818, 0xa084, 0x8000, 0x0040, 0x262a,
-+	0x681b, 0x001d, 0x1078, 0x3323, 0x781b, 0x009e, 0x0078, 0x212b,
-+	0xa584, 0x000f, 0x00c0, 0x2651, 0x7000, 0x0079, 0x2637, 0x263f,
-+	0x2641, 0x263f, 0x264d, 0x264d, 0x264d, 0x264d, 0x263f, 0x1078,
-+	0x20c8, 0x1078, 0x303b, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
-+	0x2fdd, 0x0040, 0x264d, 0x0078, 0x2242, 0x1078, 0x2a87, 0x0078,
-+	0x2fea, 0x78e4, 0xa005, 0x00d0, 0x25fa, 0x0018, 0x25fa, 0x2008,
-+	0xa084, 0x0030, 0x00c0, 0x2660, 0x781b, 0x004a, 0x0078, 0x212b,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x265c, 0x2100, 0xa184, 0x0007,
-+	0x0079, 0x266a, 0x267a, 0x267e, 0x2674, 0x2672, 0x3535, 0x3535,
-+	0x2672, 0x352d, 0x1078, 0x20c8, 0x1078, 0x332b, 0x781b, 0x0053,
-+	0x0078, 0x212b, 0x1078, 0x332b, 0x0078, 0x3506, 0x1078, 0x332b,
-+	0x781b, 0x00e3, 0x0078, 0x212b, 0x1078, 0x332b, 0x781b, 0x009e,
-+	0x0078, 0x212b, 0x2300, 0x0079, 0x268d, 0x2692, 0x2690, 0x2694,
-+	0x1078, 0x20c8, 0x0078, 0x2d06, 0x681b, 0x0008, 0x78a3, 0x0000,
-+	0x79e4, 0xa184, 0x0030, 0x0040, 0x2d06, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x2d06, 0xa184, 0x0007, 0x0079, 0x26a6, 0x26ae, 0x267e,
-+	0x25fe, 0x34da, 0x3535, 0x3535, 0x26ae, 0x352d, 0x1078, 0x34ea,
-+	0x0078, 0x212b, 0xa282, 0x0005, 0x0050, 0x26b8, 0x1078, 0x20c8,
-+	0x2300, 0x0079, 0x26bb, 0x26be, 0x290b, 0x2917, 0x2200, 0x0079,
-+	0x26c1, 0x26db, 0x26c8, 0x26db, 0x26c6, 0x28f0, 0x1078, 0x20c8,
-+	0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048,
-+	0x3305, 0xa08a, 0x0004, 0x00c8, 0x3305, 0x0079, 0x26d7, 0x3305,
-+	0x3305, 0x3305, 0x32b3, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080,
-+	0x0040, 0x26ec, 0x0078, 0x3305, 0x7000, 0xa005, 0x00c0, 0x26e2,
-+	0x2011, 0x0004, 0x0078, 0x2e41, 0xa184, 0x00ff, 0xa08a, 0x0010,
-+	0x00c8, 0x3305, 0x0079, 0x26f4, 0x2706, 0x2704, 0x271e, 0x2722,
-+	0x27dd, 0x3305, 0x3305, 0x27df, 0x3305, 0x3305, 0x28ec, 0x28ec,
-+	0x3305, 0x3305, 0x3305, 0x28ee, 0x1078, 0x20c8, 0xa684, 0x1000,
-+	0x0040, 0x2713, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, 0x781b,
-+	0x009b, 0x0078, 0x212b, 0x6818, 0xa084, 0x8000, 0x0040, 0x271c,
-+	0x681b, 0x001d, 0x0078, 0x270a, 0x0078, 0x34da, 0x681b, 0x001d,
-+	0x0078, 0x3311, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x2763,
-+	0x6820, 0xa084, 0x0001, 0x00c0, 0x276b, 0x6818, 0xa086, 0x0008,
-+	0x00c0, 0x2734, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040, 0x27d9,
-+	0xa684, 0x0080, 0x0040, 0x275f, 0x70cb, 0x0000, 0x6818, 0xa084,
-+	0x003f, 0xa08a, 0x000d, 0x0050, 0x275f, 0xa08a, 0x000c, 0x71ca,
-+	0x2001, 0x000c, 0x800c, 0x71ce, 0x789b, 0x0061, 0x78aa, 0x157e,
-+	0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac,
-+	0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b,
-+	0x0056, 0x0078, 0x212b, 0xa684, 0x1000, 0x0040, 0x276b, 0x781b,
-+	0x0068, 0x0078, 0x212b, 0xa684, 0x0060, 0x0040, 0x27d5, 0xa684,
-+	0x0800, 0x0040, 0x27d5, 0xa684, 0x8000, 0x00c0, 0x2779, 0x0078,
-+	0x2791, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0,
-+	0x801b, 0x00c8, 0x2784, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
-+	0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
-+	0x68ae, 0xa684, 0x4000, 0x0040, 0x2799, 0xa6b4, 0xbfff, 0x7e5a,
-+	0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x27a6, 0x1078, 0x3792,
-+	0x1078, 0x398f, 0x781b, 0x0065, 0x0078, 0x212b, 0xa006, 0x1078,
-+	0x3a5e, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040,
-+	0x27b5, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda,
-+	0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x27c7, 0xa6b5,
-+	0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0065, 0x0078, 0x212b, 0x781b,
-+	0x0065, 0x2200, 0xa115, 0x00c0, 0x27d1, 0x1078, 0x39a0, 0x0078,
-+	0x212b, 0x1078, 0x39d5, 0x0078, 0x212b, 0x781b, 0x0068, 0x0078,
-+	0x212b, 0x781b, 0x0056, 0x0078, 0x212b, 0x1078, 0x20c8, 0x0078,
-+	0x283c, 0x6920, 0xa184, 0x0100, 0x0040, 0x27f7, 0xa18c, 0xfeff,
-+	0x6922, 0x0c7e, 0x7048, 0x2060, 0x6000, 0xa084, 0xefff, 0x6002,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x282b, 0xa184,
-+	0x0200, 0x0040, 0x282b, 0xa18c, 0xfdff, 0x6922, 0x0c7e, 0x7048,
-+	0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef,
-+	0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x282b,
-+	0x1078, 0x3445, 0x1078, 0x316f, 0x88ff, 0x0040, 0x282b, 0x789b,
-+	0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
-+	0x0400, 0x00c0, 0x2827, 0x781b, 0x0053, 0x0078, 0x212b, 0x781b,
-+	0x0067, 0x0078, 0x212b, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2834,
-+	0x781b, 0x0056, 0x0078, 0x212b, 0x781b, 0x0068, 0x0078, 0x212b,
-+	0x0078, 0x330b, 0x0078, 0x330b, 0x2019, 0x0000, 0x7990, 0xa18c,
-+	0x0007, 0x00c0, 0x284a, 0x6820, 0xa084, 0x0100, 0x0040, 0x283a,
-+	0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286,
-+	0x0001, 0x00c0, 0x2881, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102,
-+	0x0040, 0x2879, 0x0048, 0x285e, 0x0078, 0x287b, 0xa380, 0x0002,
-+	0xa102, 0x00c8, 0x2879, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e,
-+	0x7048, 0x2060, 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084,
-+	0xffe5, 0x6006, 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078,
-+	0x282c, 0x0078, 0x27e1, 0x24a8, 0x7aa8, 0x00f0, 0x287b, 0x0078,
-+	0x284c, 0xa284, 0x00f0, 0xa086, 0x0020, 0x00c0, 0x28dd, 0x8318,
-+	0x8318, 0x2300, 0xa102, 0x0040, 0x2891, 0x0048, 0x2891, 0x0078,
-+	0x28da, 0xa286, 0x0023, 0x0040, 0x283a, 0x681c, 0xa084, 0xfff1,
-+	0x681e, 0x7e58, 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a,
-+	0x6008, 0xa085, 0x0010, 0x600a, 0x0c7e, 0x7048, 0x2060, 0x6004,
-+	0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0010, 0x0040, 0x28b5, 0x1078,
-+	0x3445, 0x1078, 0x3273, 0x0078, 0x28c4, 0x0c7e, 0x7048, 0x2060,
-+	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x282b,
-+	0x1078, 0x3445, 0x1078, 0x316f, 0x88ff, 0x0040, 0x282b, 0x789b,
-+	0x0060, 0x2800, 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400,
-+	0x00c0, 0x28d6, 0x781b, 0x0053, 0x0078, 0x212b, 0x781b, 0x0067,
-+	0x0078, 0x212b, 0x7aa8, 0x0078, 0x284c, 0x8318, 0x2300, 0xa102,
-+	0x0040, 0x28e6, 0x0048, 0x28e6, 0x0078, 0x284c, 0xa284, 0x0080,
-+	0x00c0, 0x3311, 0x0078, 0x330b, 0x0078, 0x3311, 0x0078, 0x3305,
-+	0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040,
-+	0x28fb, 0x1078, 0x20c8, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
-+	0x00ff, 0xa08a, 0x0004, 0x00c8, 0x3305, 0x0079, 0x2907, 0x308b,
-+	0x30c2, 0x3305, 0x320e, 0xa282, 0x0000, 0x00c0, 0x2911, 0x1078,
-+	0x20c8, 0x1078, 0x3323, 0x781b, 0x0067, 0x0078, 0x212b, 0xa282,
-+	0x0003, 0x00c0, 0x291d, 0x1078, 0x20c8, 0xa484, 0x8000, 0x00c0,
-+	0x2940, 0x70a0, 0xa005, 0x0040, 0x2927, 0x1078, 0x20c8, 0x6f14,
-+	0x77b6, 0xa7bc, 0x0f00, 0x1078, 0x3449, 0x6008, 0xa085, 0x0021,
-+	0x600a, 0x8738, 0xa784, 0x001f, 0x00c0, 0x292b, 0x1078, 0x3327,
-+	0x70a3, 0x0002, 0x2009, 0x3d35, 0x200b, 0x0009, 0x0078, 0x2942,
-+	0x1078, 0x3333, 0x781b, 0x0067, 0x0078, 0x212b, 0xa282, 0x0004,
-+	0x0050, 0x294c, 0x1078, 0x20c8, 0x2300, 0x0079, 0x294f, 0x2952,
-+	0x2a33, 0x2a62, 0xa286, 0x0003, 0x0040, 0x2958, 0x1078, 0x20c8,
-+	0x2001, 0x0000, 0x007e, 0x68a0, 0xa084, 0x2000, 0x0040, 0x2964,
-+	0x6008, 0xa085, 0x0002, 0x600a, 0x007f, 0x703a, 0x7000, 0xa084,
-+	0x0007, 0x0079, 0x296b, 0x2133, 0x2975, 0x2975, 0x2b50, 0x2b81,
-+	0x2133, 0x2b81, 0x2973, 0x1078, 0x20c8, 0xa684, 0x1000, 0x00c0,
-+	0x297d, 0x1078, 0x36ec, 0x0040, 0x2a0d, 0x7868, 0xa08c, 0x00ff,
-+	0x0040, 0x29c3, 0xa186, 0x0008, 0x00c0, 0x2994, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x1078, 0x2fdd, 0x0040, 0x29c3, 0x1078, 0x303b,
-+	0x1078, 0x36ec, 0x0078, 0x29aa, 0xa186, 0x0028, 0x00c0, 0x29c3,
-+	0x1078, 0x36ec, 0x6008, 0xa084, 0xffef, 0x600a, 0x6018, 0xa005,
-+	0x0040, 0x29aa, 0x8001, 0x601a, 0x6008, 0xa085, 0x0008, 0x600a,
-+	0x7010, 0x6026, 0x6820, 0xa084, 0x0001, 0x0040, 0x2133, 0x6820,
-+	0xa084, 0xfffe, 0x6822, 0x7054, 0x0c7e, 0x2060, 0x6800, 0x6002,
-+	0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x29c0, 0x6002,
-+	0x6006, 0x0078, 0x2133, 0x017e, 0x1078, 0x2a87, 0x017f, 0xa684,
-+	0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2a0d,
-+	0xa186, 0x0002, 0x00c0, 0x2a0d, 0xa684, 0x0800, 0x00c0, 0x29e0,
-+	0xa684, 0x0060, 0x0040, 0x29e0, 0x78d8, 0x7adc, 0x682e, 0x6a32,
-+	0x6820, 0xa084, 0x0800, 0x00c0, 0x2a0d, 0x8717, 0xa294, 0x000f,
-+	0x8213, 0x8213, 0x8213, 0xa290, 0x3f80, 0xa290, 0x0000, 0x221c,
-+	0xa384, 0x0100, 0x00c0, 0x29f6, 0x0078, 0x29fc, 0x8210, 0x2204,
-+	0xa085, 0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2a09,
-+	0x68a0, 0xa084, 0x0100, 0x00c0, 0x2a09, 0x1078, 0x2b0b, 0x0078,
-+	0x2133, 0x6008, 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x2a15, 0x7038, 0x681a, 0xa68c, 0xdf00, 0x691e,
-+	0x1078, 0x302c, 0x1078, 0x303b, 0x00c0, 0x2a22, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2a2b, 0x1078,
-+	0x3025, 0x0078, 0x2a2f, 0x7054, 0x2060, 0x6800, 0x6002, 0x1078,
-+	0x1b7f, 0x0078, 0x2133, 0xa282, 0x0004, 0x0048, 0x2a39, 0x1078,
-+	0x20c8, 0x2200, 0x0079, 0x2a3c, 0x2a37, 0x2a40, 0x2a4d, 0x2a40,
-+	0x7000, 0xa086, 0x0005, 0x0040, 0x2a49, 0x1078, 0x3323, 0x781b,
-+	0x0067, 0x781b, 0x0068, 0x0078, 0x212b, 0x7890, 0x8007, 0x8001,
-+	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-+	0xa186, 0x0003, 0x0040, 0x2a5e, 0x0078, 0x3305, 0x781b, 0x0068,
-+	0x0078, 0x212b, 0x6820, 0xa085, 0x0004, 0x6822, 0x82ff, 0x00c0,
-+	0x2a6d, 0x1078, 0x3323, 0x0078, 0x2a74, 0x8211, 0x0040, 0x2a72,
-+	0x1078, 0x20c8, 0x1078, 0x3333, 0x781b, 0x0067, 0x0078, 0x212b,
-+	0x1078, 0x355b, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2a84, 0x0018,
-+	0x2a84, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
-+	0x0060, 0x00c0, 0x2a91, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-+	0x2b0a, 0xa684, 0x0800, 0x00c0, 0x2ab3, 0x68b4, 0xa084, 0x4800,
-+	0xa635, 0xa684, 0x0800, 0x00c0, 0x2ab3, 0x6998, 0x6a94, 0x692e,
-+	0x6a32, 0x7038, 0xa005, 0x00c0, 0x2aab, 0x2200, 0xa105, 0x0040,
-+	0x2ab2, 0x703b, 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2ab2,
-+	0x1078, 0x36ec, 0x007c, 0xa684, 0x0020, 0x0040, 0x2ad5, 0xa684,
-+	0x4000, 0x0040, 0x2ac1, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-+	0x2aab, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0,
-+	0x2abb, 0x7038, 0xa005, 0x00c0, 0x2acf, 0x703b, 0x0015, 0x79d8,
-+	0x7adc, 0x692e, 0x6a32, 0x0078, 0x2aab, 0xa684, 0x4000, 0x0040,
-+	0x2adf, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2aab, 0x68b4,
-+	0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2ad9, 0x7038,
-+	0xa005, 0x00c0, 0x2aed, 0x703b, 0x0015, 0x79d8, 0x7adc, 0x78d0,
-+	0x80fb, 0x00c8, 0x2af4, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
-+	0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2b01, 0x0078,
-+	0x2aab, 0x7000, 0xa086, 0x0006, 0x0040, 0x2b0a, 0x1078, 0x3a5e,
-+	0x0078, 0x2aab, 0x007c, 0xa384, 0x0200, 0x0040, 0x2b13, 0x6008,
-+	0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893,
-+	0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833,
-+	0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000,
-+	0x0079, 0x2b2a, 0x2b32, 0x2b34, 0x2b3d, 0x2b32, 0x2b32, 0x2b32,
-+	0x2b32, 0x2b32, 0x1078, 0x20c8, 0x6820, 0xa084, 0x0001, 0x00c0,
-+	0x2b3d, 0x1078, 0x3025, 0x0078, 0x2b43, 0x7054, 0x2c50, 0x2060,
-+	0x6800, 0x6002, 0x2a60, 0x2021, 0x3d57, 0x2404, 0xa005, 0x0040,
-+	0x2b4c, 0x2020, 0x0078, 0x2b45, 0x2d22, 0x206b, 0x0000, 0x007c,
-+	0x1078, 0x302c, 0x1078, 0x303b, 0x682b, 0x0000, 0x789b, 0x000e,
-+	0x6f14, 0x1078, 0x3a90, 0x6817, 0x0002, 0xa684, 0x0800, 0x0040,
-+	0x2b65, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x2b75, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2b73, 0x681b,
-+	0x001e, 0x0078, 0x2b75, 0x681b, 0x0000, 0x2021, 0x3d57, 0x6800,
-+	0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1b7f, 0x0078,
-+	0x2133, 0x1078, 0x2a87, 0x682b, 0x0000, 0x2001, 0x000e, 0x6f14,
-+	0x1078, 0x3560, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x2b94, 0x7038, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x70a3,
-+	0x0000, 0x0078, 0x2133, 0xa006, 0x1078, 0x36ec, 0x6817, 0x0000,
-+	0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
-+	0xa085, 0x00ff, 0x6822, 0x7000, 0x0079, 0x2bae, 0x2bb6, 0x2bb8,
-+	0x2bb8, 0x2bba, 0x2bba, 0x2bba, 0x2bba, 0x2bb6, 0x1078, 0x20c8,
-+	0x1078, 0x303b, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x2ff5,
-+	0x2300, 0x0079, 0x2bc3, 0x2bc6, 0x2bc8, 0x2c21, 0x1078, 0x20c8,
-+	0xa684, 0x8000, 0x00c0, 0x2c06, 0x7000, 0x0079, 0x2bcf, 0x2bd7,
-+	0x2bd9, 0x2bd9, 0x2bf5, 0x2bd9, 0x2c02, 0x2bf5, 0x2bd7, 0x1078,
-+	0x20c8, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x2bf1, 0xa6b4,
-+	0xffdf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x6eb6, 0x681c,
-+	0xa084, 0xffdf, 0x681e, 0x1078, 0x36ec, 0x1078, 0x39a0, 0x0078,
-+	0x34da, 0xa684, 0x2000, 0x0040, 0x2be3, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x2c02, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x2c02,
-+	0x681b, 0x0007, 0x1078, 0x34ea, 0x0078, 0x212b, 0xa6b4, 0x7fff,
-+	0x7e5a, 0x7adc, 0x79d8, 0x78d0, 0x79d2, 0x801b, 0x00c8, 0x2c11,
-+	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100,
-+	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0068,
-+	0x007c, 0x1078, 0x20c8, 0x2300, 0x0079, 0x2c26, 0x2c29, 0x2c2b,
-+	0x2c73, 0x1078, 0x20c8, 0xa684, 0x8000, 0x00c0, 0x2c62, 0x7000,
-+	0x0079, 0x2c32, 0x2c39, 0x2c3b, 0x2c3b, 0x2c57, 0x2c3b, 0x2c57,
-+	0x2c39, 0x1078, 0x20c8, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
-+	0x2c53, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
-+	0x6eb6, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078, 0x36ec, 0x1078,
-+	0x39a0, 0x0078, 0x34da, 0xa684, 0x2000, 0x0040, 0x2c45, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2c5e, 0x681b, 0x0007, 0x781b, 0x00e4,
-+	0x0078, 0x212b, 0xa6b4, 0x7fff, 0x7e5a, 0x7adc, 0x79d8, 0x6b98,
-+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2,
-+	0x781b, 0x0068, 0x007c, 0x6820, 0xa085, 0x0004, 0x6822, 0x1078,
-+	0x34a7, 0xa6b5, 0x0800, 0x1078, 0x3323, 0x781b, 0x0067, 0x0078,
-+	0x212b, 0x2300, 0x0079, 0x2c84, 0x2c87, 0x2c89, 0x2c8b, 0x1078,
-+	0x20c8, 0x0078, 0x3311, 0xa684, 0x0400, 0x00c0, 0x2cb4, 0x79e4,
-+	0xa184, 0x0020, 0x0040, 0x2c9b, 0x78ec, 0xa084, 0x0003, 0x0040,
-+	0x2c9b, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
-+	0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040, 0x2cac, 0x78ec,
-+	0xa084, 0x0003, 0x00c0, 0x2cb0, 0x2001, 0x0014, 0x0078, 0x295a,
-+	0xa184, 0x0007, 0x0079, 0x2cec, 0x7a90, 0xa294, 0x0007, 0x789b,
-+	0x0060, 0x79a8, 0x81ff, 0x0040, 0x2cea, 0x789b, 0x0010, 0x7ba8,
-+	0xa384, 0x0001, 0x00c0, 0x2cdb, 0x7ba8, 0x7ba8, 0xa386, 0x0001,
-+	0x00c0, 0x2cce, 0x2009, 0xfff7, 0x0078, 0x2cd4, 0xa386, 0x0003,
-+	0x00c0, 0x2cdb, 0x2009, 0xffef, 0x0c7e, 0x7048, 0x2060, 0x6004,
-+	0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
-+	0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfdff, 0xa18c,
-+	0xfeff, 0x6922, 0x0078, 0x34da, 0x260b, 0x2616, 0x2cf6, 0x2cfe,
-+	0x2cf4, 0x2cf4, 0x34da, 0x34da, 0x1078, 0x20c8, 0x6920, 0xa18c,
-+	0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x34e2, 0x6920, 0xa18c,
-+	0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x34da, 0x79e4, 0xa184,
-+	0x0030, 0x0040, 0x2d10, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x2d26,
-+	0x70a0, 0xa086, 0x0002, 0x00c0, 0x2d19, 0x2011, 0x0002, 0x0078,
-+	0x24ef, 0x7000, 0xa086, 0x0000, 0x0040, 0x212b, 0x6818, 0xa085,
-+	0x8000, 0x681a, 0x2001, 0x0014, 0x0078, 0x295a, 0xa184, 0x0007,
-+	0x0079, 0x2d2a, 0x34da, 0x34da, 0x2d32, 0x34da, 0x3535, 0x3535,
-+	0x34da, 0x34da, 0xa684, 0x0080, 0x0040, 0x2d61, 0x71c8, 0x81ff,
-+	0x0040, 0x2d61, 0xa182, 0x000d, 0x00d0, 0x2d42, 0x70cb, 0x0000,
-+	0x0078, 0x2d47, 0xa182, 0x000c, 0x70ca, 0x2009, 0x000c, 0x789b,
-+	0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x70cc, 0x8114, 0xa210,
-+	0x72ce, 0xa080, 0x000b, 0xad00, 0x2098, 0x20a1, 0x012b, 0x789b,
-+	0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078,
-+	0x34e2, 0xa684, 0x0400, 0x00c0, 0x2da2, 0x6820, 0xa084, 0x0001,
-+	0x0040, 0x34e2, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x2d76,
-+	0xa086, 0x0060, 0x00c0, 0x2d76, 0xa18d, 0x4000, 0xa18c, 0xfffb,
-+	0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061,
-+	0x6818, 0xa085, 0x8000, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040,
-+	0x3054, 0xa18c, 0x00f8, 0x00c0, 0x3054, 0x157e, 0x137e, 0x147e,
-+	0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b,
-+	0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882,
-+	0x0078, 0x34e2, 0x6818, 0xa084, 0x8000, 0x0040, 0x2da9, 0x681b,
-+	0x0008, 0x781b, 0x00d8, 0x0078, 0x212b, 0x2300, 0x0079, 0x2db0,
-+	0x2db5, 0x2e31, 0x2db3, 0x1078, 0x20c8, 0x7000, 0xa084, 0x0007,
-+	0x0079, 0x2dba, 0x2dc2, 0x2dc4, 0x2de9, 0x2958, 0x2dc2, 0x2133,
-+	0x2dc2, 0x2dc2, 0x1078, 0x20c8, 0x681c, 0xa084, 0x2000, 0x0040,
-+	0x2dcd, 0x6008, 0xa085, 0x0002, 0x600a, 0x6920, 0xa18d, 0x0001,
-+	0x6922, 0x6800, 0x6006, 0xa005, 0x00c0, 0x2dd7, 0x6002, 0x681c,
-+	0xa084, 0x000e, 0x0040, 0x2de3, 0x7014, 0x68ba, 0x712c, 0xa188,
-+	0x6000, 0x0078, 0x2de5, 0x2009, 0x6100, 0x2104, 0x6802, 0x2d0a,
-+	0x7156, 0x6eb6, 0xa684, 0x0060, 0x0040, 0x2e2f, 0xa684, 0x0800,
-+	0x00c0, 0x2dfd, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898,
-+	0x68aa, 0x1078, 0x36ec, 0x0078, 0x2e2f, 0xa684, 0x0020, 0x0040,
-+	0x2e0a, 0xa006, 0x1078, 0x3a5e, 0x79d8, 0x7adc, 0x69aa, 0x6aa6,
-+	0x0078, 0x2e10, 0x1078, 0x3456, 0x69aa, 0x6aa6, 0x1078, 0x3a5e,
-+	0xa684, 0x8000, 0x0040, 0x2e2f, 0xa684, 0x7fff, 0x68b6, 0x7adc,
-+	0x79d8, 0xa684, 0x0020, 0x00c0, 0x2e27, 0x78d0, 0x801b, 0x00c8,
-+	0x2e22, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98,
-+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078,
-+	0x2133, 0x0078, 0x3311, 0x7033, 0x0000, 0xa282, 0x0006, 0x0050,
-+	0x2e3b, 0x1078, 0x20c8, 0x2300, 0x0079, 0x2e3e, 0x2e41, 0x2e6a,
-+	0x2e90, 0x2200, 0x0079, 0x2e44, 0x2e4a, 0x3311, 0x2e4c, 0x2e4a,
-+	0x2ebc, 0x2f0f, 0x1078, 0x20c8, 0x7003, 0x0005, 0x2001, 0x6110,
-+	0x2068, 0x703e, 0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000,
-+	0x0070, 0x2e5c, 0x0078, 0x2e55, 0x157f, 0xad80, 0x0009, 0x7032,
-+	0x6817, 0x0000, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003,
-+	0x0078, 0x3305, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2e77, 0x1078,
-+	0x303b, 0x1078, 0x36ec, 0x7034, 0x600a, 0x0078, 0x2e7c, 0x7000,
-+	0xa086, 0x0003, 0x0040, 0x2e71, 0x7003, 0x0005, 0x2001, 0x6110,
-+	0x2068, 0x703e, 0xad80, 0x0009, 0x7032, 0x2200, 0x0079, 0x2e88,
-+	0x3311, 0x2e8e, 0x2e8e, 0x2ebc, 0x2e8e, 0x3311, 0x1078, 0x20c8,
-+	0x7000, 0xa086, 0x0001, 0x00c0, 0x2e9d, 0x1078, 0x303b, 0x1078,
-+	0x36ec, 0x7034, 0x600a, 0x0078, 0x2ea2, 0x7000, 0xa086, 0x0003,
-+	0x0040, 0x2e97, 0x7003, 0x0005, 0x2001, 0x6110, 0x2068, 0x703e,
-+	0xad80, 0x0009, 0x7032, 0x2200, 0x0079, 0x2eae, 0x2eb6, 0x2eb4,
-+	0x2eb4, 0x2eb6, 0x2eb4, 0x2eb6, 0x1078, 0x20c8, 0x1078, 0x3333,
-+	0x781b, 0x0067, 0x0078, 0x212b, 0x7000, 0xa086, 0x0001, 0x00c0,
-+	0x2ec9, 0x1078, 0x303b, 0x1078, 0x36ec, 0x7034, 0x600a, 0x0078,
-+	0x2ece, 0x7000, 0xa086, 0x0003, 0x0040, 0x2ec3, 0x7003, 0x0002,
-+	0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
-+	0xa215, 0x2069, 0x6100, 0x2d04, 0x2d08, 0x7156, 0x2068, 0xa005,
-+	0x0040, 0x2ee9, 0x6814, 0xa206, 0x0040, 0x2f04, 0x6800, 0x0078,
-+	0x2edc, 0x7003, 0x0005, 0x2001, 0x6110, 0x2068, 0x703e, 0x157e,
-+	0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070, 0x2ef9, 0x0078,
-+	0x2ef2, 0x157f, 0xad80, 0x0009, 0x7032, 0x6a16, 0x68b7, 0x0700,
-+	0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084,
-+	0x0c00, 0x0040, 0x2f70, 0x1078, 0x332b, 0x0078, 0x2f70, 0x7000,
-+	0xa086, 0x0001, 0x00c0, 0x2f1c, 0x1078, 0x303b, 0x1078, 0x36ec,
-+	0x7034, 0x600a, 0x0078, 0x2f21, 0x7000, 0xa086, 0x0003, 0x0040,
-+	0x2f16, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-+	0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff,
-+	0xa1e8, 0x6000, 0x2d04, 0x2d08, 0x7156, 0x2068, 0xa005, 0x0040,
-+	0x2f40, 0x6814, 0xa206, 0x0040, 0x2f5b, 0x6800, 0x0078, 0x2f33,
-+	0x7003, 0x0005, 0x2001, 0x6110, 0x2068, 0x703e, 0x157e, 0x20a9,
-+	0x002f, 0x2003, 0x0000, 0x8000, 0x0070, 0x2f50, 0x0078, 0x2f49,
-+	0x157f, 0xad80, 0x0009, 0x7032, 0x6a16, 0x68b7, 0x0700, 0x6823,
-+	0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00,
-+	0x0040, 0x2f70, 0xa084, 0x0800, 0x0040, 0x2f6a, 0x1078, 0x332f,
-+	0x0078, 0x2f70, 0x1078, 0x332b, 0x70bf, 0x0000, 0x0078, 0x2f70,
-+	0x027e, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080,
-+	0x3f80, 0x2060, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0xa684,
-+	0x0060, 0x0040, 0x2fb0, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105,
-+	0x00c0, 0x2f9e, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff,
-+	0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x2fb0, 0x1078,
-+	0x39a0, 0xa6b5, 0x2000, 0x7e5a, 0x0078, 0x2fb0, 0x68b0, 0xa31a,
-+	0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x2fb0, 0x7bd2, 0x7bda,
-+	0x7cd6, 0x7cde, 0x68b0, 0xa6b4, 0xbfff, 0x7e5a, 0x1078, 0x39d5,
-+	0x077f, 0x1078, 0x3449, 0x2009, 0x0068, 0xa684, 0x0008, 0x0040,
-+	0x2fcf, 0x78e4, 0xa084, 0x0030, 0x0040, 0x2fc7, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x2fc7, 0x2009, 0x0067, 0x0078, 0x2fcf, 0x0f7e,
-+	0x2079, 0x3d00, 0x1078, 0x36ec, 0x0f7f, 0x0078, 0x2133, 0x791a,
-+	0x2d00, 0x703e, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa080, 0x3f80, 0x2048, 0x0078, 0x212b, 0x6020, 0xa005, 0x0040,
-+	0x2fe9, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x7010,
-+	0x6026, 0x007c, 0xa006, 0x1078, 0x36ec, 0x6817, 0x0000, 0x681b,
-+	0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x0007,
-+	0x0079, 0x2ffa, 0x3002, 0x3004, 0x3004, 0x3021, 0x300c, 0x3002,
-+	0x300c, 0x3002, 0x1078, 0x20c8, 0x1078, 0x302c, 0x1078, 0x3025,
-+	0x1078, 0x1b7f, 0x0078, 0x2133, 0x70a0, 0x70a3, 0x0000, 0x70c7,
-+	0x0000, 0x0079, 0x3013, 0x301d, 0x301d, 0x301b, 0x301b, 0x301b,
-+	0x301d, 0x301b, 0x301d, 0x0079, 0x2508, 0x70a3, 0x0000, 0x0078,
-+	0x2133, 0x681b, 0x0000, 0x0078, 0x2b50, 0x6800, 0xa005, 0x00c0,
-+	0x302a, 0x6002, 0x6006, 0x007c, 0x6010, 0xa005, 0x0040, 0x3035,
-+	0x8001, 0x00d0, 0x3035, 0x1078, 0x20c8, 0x6012, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3041, 0x8001,
-+	0x601a, 0x007c, 0x1078, 0x355b, 0x681b, 0x0018, 0x0078, 0x3078,
-+	0x1078, 0x355b, 0x681b, 0x0019, 0x0078, 0x3078, 0x1078, 0x355b,
-+	0x681b, 0x001a, 0x0078, 0x3078, 0x1078, 0x355b, 0x681b, 0x0003,
-+	0x0078, 0x3078, 0x77b4, 0x1078, 0x3449, 0x71b8, 0xa18c, 0x00ff,
-+	0xa1e8, 0x6000, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x306a,
-+	0x0078, 0x2133, 0x6814, 0x72b4, 0xa206, 0x0040, 0x3072, 0x6800,
-+	0x0078, 0x3063, 0x6800, 0x200a, 0x681b, 0x0005, 0x70bf, 0x0000,
-+	0x1078, 0x302c, 0x6820, 0xa084, 0x0001, 0x00c0, 0x3081, 0x1078,
-+	0x3025, 0x1078, 0x303b, 0x681f, 0x0000, 0x6823, 0x0020, 0x1078,
-+	0x1b7f, 0x0078, 0x2133, 0xa282, 0x0005, 0x00c0, 0x3305, 0x78a8,
-+	0xa084, 0x00ff, 0x802f, 0x78a8, 0xa084, 0x00ff, 0xa52d, 0x78a8,
-+	0xa084, 0x00ff, 0x8037, 0x78a8, 0xa084, 0x00ff, 0xa635, 0x7cd8,
-+	0x2600, 0xa420, 0x7bdc, 0x2500, 0xa319, 0x0048, 0x3305, 0x7cda,
-+	0x7bde, 0x6caa, 0x7cd2, 0x6ba6, 0x7bd6, 0x1078, 0x3792, 0x1078,
-+	0x398f, 0x781b, 0x0065, 0x0078, 0x212b, 0xa006, 0x1078, 0x3a5e,
-+	0x781b, 0x0065, 0x0078, 0x212b, 0x78d0, 0x79d4, 0x1078, 0x39d5,
-+	0x0078, 0x212b, 0xa282, 0x0003, 0x00c0, 0x3305, 0x7da8, 0xa5ac,
-+	0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922,
-+	0xa184, 0x0100, 0x0040, 0x3122, 0xa18c, 0xfeff, 0x6922, 0xa6b4,
-+	0x00ff, 0x0040, 0x310c, 0xa682, 0x000c, 0x0048, 0x30e3, 0x0040,
-+	0x30e3, 0x2031, 0x000c, 0x852b, 0x852b, 0x1078, 0x33be, 0x0040,
-+	0x30ed, 0x1078, 0x31da, 0x0078, 0x3115, 0x1078, 0x3379, 0x0c7e,
-+	0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x31fe, 0x0c7f,
-+	0x6920, 0xa18d, 0x0100, 0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a,
-+	0xa684, 0x0400, 0x00c0, 0x3108, 0x781b, 0x0053, 0x0078, 0x212b,
-+	0x781b, 0x0067, 0x0078, 0x212b, 0x0c7e, 0x2960, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x1078, 0x31fe, 0x0c7f, 0x7e58, 0xa684, 0x0400,
-+	0x00c0, 0x311e, 0x781b, 0x0056, 0x0078, 0x212b, 0x781b, 0x0068,
-+	0x0078, 0x212b, 0x0c7e, 0x7048, 0x2060, 0x6100, 0xa18c, 0x1000,
-+	0x0040, 0x3162, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c,
-+	0x0048, 0x3136, 0x0040, 0x3136, 0x2011, 0x000c, 0x2600, 0xa202,
-+	0x00c8, 0x313b, 0x2230, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086,
-+	0x0028, 0x00c0, 0x314b, 0xa282, 0x0019, 0x00c8, 0x3151, 0x2011,
-+	0x0019, 0x0078, 0x3151, 0xa282, 0x000c, 0x00c8, 0x3151, 0x2011,
-+	0x000c, 0x2200, 0xa502, 0x00c8, 0x3156, 0x2228, 0x1078, 0x337d,
-+	0x852b, 0x852b, 0x1078, 0x33be, 0x0040, 0x3162, 0x1078, 0x31da,
-+	0x0078, 0x3166, 0x1078, 0x3379, 0x1078, 0x31fe, 0x7858, 0xa085,
-+	0x0004, 0x785a, 0x0c7f, 0x781b, 0x0067, 0x0078, 0x212b, 0x0c7e,
-+	0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x3187, 0x6010, 0xa084,
-+	0x000f, 0x00c0, 0x3181, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f,
-+	0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x31ae, 0x68a0,
-+	0xa084, 0x0200, 0x00c0, 0x3181, 0x6208, 0xa294, 0x00ff, 0x7018,
-+	0xa086, 0x0028, 0x00c0, 0x319c, 0xa282, 0x0019, 0x00c8, 0x31a2,
-+	0x2011, 0x0019, 0x0078, 0x31a2, 0xa282, 0x000c, 0x00c8, 0x31a2,
-+	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
-+	0x0048, 0x31ae, 0x0040, 0x31ae, 0x2019, 0x000c, 0x78ab, 0x0001,
-+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
-+	0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960,
-+	0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000,
-+	0x0078, 0x31ca, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001,
-+	0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822,
-+	0x0c7f, 0x007c, 0x0c7e, 0x7148, 0x2160, 0x2008, 0xa084, 0xfff0,
-+	0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084,
-+	0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a, 0xa6b4,
-+	0x000f, 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7048,
-+	0x2060, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012,
-+	0x7884, 0xa084, 0xfff0, 0x7886, 0x0c7f, 0x007c, 0xa282, 0x0002,
-+	0x00c0, 0x3305, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184,
-+	0x0200, 0x0040, 0x3253, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff,
-+	0xa282, 0x0002, 0x00c8, 0x3305, 0x1078, 0x329a, 0x1078, 0x31fe,
-+	0xa980, 0x0001, 0x200c, 0x1078, 0x3445, 0x1078, 0x316f, 0x88ff,
-+	0x0040, 0x3246, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5,
-+	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x3242, 0x781b, 0x0053,
-+	0x0078, 0x212b, 0x781b, 0x0067, 0x0078, 0x212b, 0x7e58, 0xa684,
-+	0x0400, 0x00c0, 0x324f, 0x781b, 0x0056, 0x0078, 0x212b, 0x781b,
-+	0x0068, 0x0078, 0x212b, 0xa282, 0x0002, 0x00c8, 0x325b, 0xa284,
-+	0x0001, 0x0040, 0x3265, 0x7148, 0xa188, 0x0000, 0x210c, 0xa18c,
-+	0x2000, 0x00c0, 0x3265, 0x2011, 0x0000, 0x1078, 0x336b, 0x1078,
-+	0x329a, 0x1078, 0x31fe, 0x7858, 0xa085, 0x0004, 0x785a, 0x781b,
-+	0x0067, 0x0078, 0x212b, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011,
-+	0x0001, 0xa084, 0x2000, 0x00c0, 0x328a, 0x6014, 0xa084, 0x0040,
-+	0x00c0, 0x3288, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x3297,
-+	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-+	0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f,
-+	0x0c7f, 0x007c, 0x0c7e, 0x7048, 0x2060, 0x82ff, 0x0040, 0x32a2,
-+	0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
-+	0xffbf, 0xa205, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef,
-+	0x6006, 0x0c7f, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040,
-+	0x32bc, 0x007f, 0x0078, 0x32bf, 0x007f, 0x0078, 0x3301, 0xa684,
-+	0x0020, 0x0040, 0x3301, 0x7888, 0xa084, 0x0040, 0x0040, 0x3301,
-+	0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x32cf, 0x8000, 0xa005,
-+	0x0040, 0x32e5, 0x831b, 0x00c8, 0x32d8, 0x8001, 0x0040, 0x32fd,
-+	0xa684, 0x4000, 0x0040, 0x32e5, 0x78b8, 0x801b, 0x00c8, 0x32e1,
-+	0x8000, 0xa084, 0x003f, 0x00c0, 0x32fd, 0xa6b4, 0xbfff, 0x7e5a,
-+	0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x32f1, 0xa291,
-+	0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x3a5e, 0x781b,
-+	0x0065, 0x1078, 0x392f, 0x0078, 0x212b, 0x781b, 0x0065, 0x0078,
-+	0x212b, 0x781b, 0x0068, 0x0078, 0x212b, 0x1078, 0x3337, 0x781b,
-+	0x0067, 0x0078, 0x212b, 0x1078, 0x3323, 0x781b, 0x0067, 0x0078,
-+	0x212b, 0x6827, 0x0002, 0x1078, 0x332b, 0x78e4, 0xa084, 0x0030,
-+	0x0040, 0x2133, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2133, 0x781b,
-+	0x0067, 0x0078, 0x212b, 0x2001, 0x0005, 0x0078, 0x3339, 0x2001,
-+	0x000c, 0x0078, 0x3339, 0x2001, 0x0006, 0x0078, 0x3339, 0x2001,
-+	0x000d, 0x0078, 0x3339, 0x2001, 0x0009, 0x0078, 0x3339, 0x2001,
-+	0x0007, 0x789b, 0x007e, 0x78aa, 0xa6b5, 0x0008, 0x7e5a, 0x007c,
-+	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
-+	0x3f80, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
-+	0x3359, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
-+	0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
-+	0x3369, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
-+	0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
-+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
-+	0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
-+	0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b,
-+	0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
-+	0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
-+	0x2001, 0x3d46, 0x2004, 0xa082, 0x0028, 0x0040, 0x33a7, 0x2021,
-+	0x342c, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x33ad, 0x2021,
-+	0x3438, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
-+	0xa084, 0xfff0, 0xa106, 0x0040, 0x33bc, 0x8420, 0x2300, 0xa210,
-+	0x0070, 0x33bc, 0x0078, 0x33af, 0x157f, 0x007c, 0x157e, 0x2011,
-+	0x3d46, 0x2214, 0xa282, 0x0032, 0x0048, 0x33d2, 0x0040, 0x33d6,
-+	0x2021, 0x341e, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
-+	0x0078, 0x33e8, 0xa282, 0x0028, 0x0040, 0x33e0, 0x2021, 0x342c,
-+	0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x33e8,
-+	0x2021, 0x3438, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
-+	0x2200, 0xa502, 0x0040, 0x33f8, 0x0048, 0x33f8, 0x8420, 0x2300,
-+	0xa210, 0x0070, 0x33f5, 0x0078, 0x33e8, 0x157f, 0xa006, 0x007c,
-+	0x157f, 0xa582, 0x0064, 0x00c8, 0x3403, 0x7808, 0xa085, 0x0070,
-+	0x780a, 0x0078, 0x3403, 0x78ec, 0xa084, 0x0300, 0x0040, 0x340b,
-+	0x2404, 0x0078, 0x341c, 0x2404, 0xa09e, 0x1102, 0x00c0, 0x341c,
-+	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048, 0x341b, 0x2001,
-+	0x1201, 0x0078, 0x341c, 0x2404, 0xa005, 0x007c, 0x1102, 0x3002,
-+	0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
-+	0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202,
-+	0x7202, 0x6605, 0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05,
-+	0x2202, 0x3202, 0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604,
-+	0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046,
-+	0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003,
-+	0x8003, 0x8003, 0xa105, 0xa0e0, 0x4000, 0x007c, 0x79d8, 0x7adc,
-+	0x78d0, 0x801b, 0x00c8, 0x345d, 0x8000, 0xa084, 0x003f, 0xa108,
-+	0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3d40,
-+	0x2091, 0x8000, 0x2104, 0x0079, 0x346d, 0x34a3, 0x3477, 0x3477,
-+	0x3477, 0x3477, 0x3477, 0x3477, 0x3475, 0x1078, 0x20c8, 0x784b,
-+	0x0004, 0x7848, 0xa084, 0x0004, 0x00c0, 0x3479, 0x784b, 0x0008,
-+	0x7848, 0xa084, 0x0008, 0x00c0, 0x3480, 0x68b4, 0xa085, 0x4000,
-+	0x68b6, 0x7858, 0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080,
-+	0x00c0, 0x34a3, 0x0018, 0x34a3, 0x681c, 0xa084, 0x0020, 0x00c0,
-+	0x34a1, 0x0e7e, 0x2071, 0x3d40, 0x1078, 0x34ea, 0x0e7f, 0x0078,
-+	0x34a3, 0x781b, 0x00e4, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x0c7e,
-+	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-+	0x3f80, 0x6004, 0xa084, 0x000a, 0x00c0, 0x34d8, 0x6108, 0xa194,
-+	0xff00, 0x0040, 0x34d8, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106,
-+	0x0040, 0x34c9, 0x2001, 0x0032, 0xa106, 0x0040, 0x34cd, 0x0078,
-+	0x34d1, 0x2009, 0x0020, 0x0078, 0x34d3, 0x2009, 0x003f, 0x0078,
-+	0x34d3, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0x6006,
-+	0x0c7f, 0x007c, 0x781b, 0x0068, 0x0078, 0x212b, 0x781b, 0x0067,
-+	0x0078, 0x212b, 0x781b, 0x0056, 0x0078, 0x212b, 0x781b, 0x0053,
-+	0x0078, 0x212b, 0x2009, 0x3d1e, 0x210c, 0xa186, 0x0000, 0x0040,
-+	0x34fe, 0xa186, 0x0001, 0x0040, 0x3501, 0x2009, 0x3d35, 0x200b,
-+	0x000b, 0x70a3, 0x0001, 0x781b, 0x0047, 0x007c, 0x781b, 0x00dd,
-+	0x007c, 0x2009, 0x3d35, 0x200b, 0x000a, 0x007c, 0x2009, 0x3d1e,
-+	0x210c, 0xa186, 0x0000, 0x0040, 0x3521, 0xa186, 0x0001, 0x0040,
-+	0x351b, 0x2009, 0x3d35, 0x200b, 0x000b, 0x70a3, 0x0001, 0x781b,
-+	0x0047, 0x0078, 0x212b, 0x2009, 0x3d35, 0x200b, 0x000a, 0x0078,
-+	0x212b, 0x781b, 0x00dc, 0x0078, 0x212b, 0x781b, 0x00e4, 0x0078,
-+	0x212b, 0x781b, 0x00e3, 0x0078, 0x212b, 0x781b, 0x009f, 0x0078,
-+	0x212b, 0x781b, 0x009e, 0x0078, 0x212b, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x353c, 0x681b, 0x001d, 0x70a3, 0x0001, 0x781b, 0x0047,
-+	0x0078, 0x212b, 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3559,
-+	0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-+	0x78ec, 0xa084, 0x0021, 0x0040, 0x3559, 0x7808, 0xa085, 0x0002,
-+	0x780a, 0x007f, 0x007c, 0x7808, 0xa085, 0x0002, 0x780a, 0x007c,
-+	0x007e, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3561, 0x0098, 0x356c,
-+	0x007f, 0x789a, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
-+	0x357b, 0x0098, 0x3579, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7808,
-+	0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
-+	0x2b9b, 0xa784, 0x0070, 0x0040, 0x3595, 0x0c7e, 0x2d60, 0x2f68,
-+	0x1078, 0x2073, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
-+	0x35a2, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2133,
-+	0x0078, 0x34da, 0xa784, 0x0004, 0x0040, 0x35d5, 0x78b8, 0xa084,
-+	0x4001, 0x0040, 0x35d5, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x2133, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
-+	0x35d5, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00e4,
-+	0x0078, 0x212b, 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040,
-+	0x35d1, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x35d1, 0x681b,
-+	0x0007, 0x1078, 0x34ea, 0x0078, 0x212b, 0x681b, 0x0003, 0x7858,
-+	0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b,
-+	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x25fa, 0x0018, 0x212b,
-+	0x0078, 0x330b, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0xa080, 0x3f80, 0x2060, 0x2048, 0x704a, 0x6000, 0x704e,
-+	0x6004, 0x7052, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x000a,
-+	0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x98f8, 0x98e7, 0x0014,
-+	0x0014, 0x0014, 0x0080, 0x00bf, 0x0100, 0x0402, 0x2008, 0xf880,
-+	0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0xa200, 0x8838,
-+	0x3806, 0x8839, 0x28c2, 0x9cc0, 0xa805, 0x0864, 0xa83f, 0x3008,
-+	0x28c1, 0x9cc0, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000,
-+	0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9ca1, 0xa8f3, 0x0864,
-+	0xa82d, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9ca1, 0x280e, 0xa204,
-+	0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576,
-+	0x8677, 0xa810, 0x7861, 0x883e, 0xa80d, 0x282c, 0xa205, 0x64a0,
-+	0x6de0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677,
-+	0xa801, 0x883e, 0x206b, 0x28c1, 0x9cc0, 0x2044, 0x2103, 0x20a2,
-+	0x2081, 0xa8da, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000,
-+	0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e,
-+	0x866f, 0x0704, 0x3008, 0x9ca1, 0x0014, 0xa202, 0x8000, 0x85a4,
-+	0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5,
-+	0xf861, 0xa8ec, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0,
-+	0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2,
-+	0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0xa206, 0x6865, 0x817e, 0x842a,
-+	0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4,
-+	0x8160, 0x842a, 0xf021, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd,
-+	0x0011, 0x20d4, 0x8822, 0x0016, 0x8000, 0x2848, 0x1011, 0xa8fc,
-+	0x3008, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd, 0xa885, 0x3008,
-+	0x283d, 0x1011, 0xa8fd, 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4,
-+	0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a,
-+	0xfaa2, 0x19f2, 0x1fe2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806,
-+	0x0210, 0x9cca, 0x0704, 0x0000, 0x127e, 0x2091, 0x2200, 0x2049,
-+	0x36ec, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008, 0xa084,
-+	0xfff7, 0xa205, 0x0040, 0x36fe, 0x0078, 0x3701, 0x127f, 0x2000,
-+	0x007c, 0x7000, 0xa084, 0x0001, 0x00c0, 0x372f, 0x7108, 0x8103,
-+	0x00c8, 0x370e, 0x1078, 0x381c, 0x0078, 0x3706, 0x700c, 0xa08c,
-+	0x00ff, 0x0040, 0x372f, 0x7004, 0x8004, 0x00c8, 0x3726, 0x7014,
-+	0xa005, 0x00c0, 0x3722, 0x7010, 0xa005, 0x0040, 0x3726, 0xa102,
-+	0x00c8, 0x3706, 0x7007, 0x0010, 0x0078, 0x372f, 0x8aff, 0x0040,
-+	0x372f, 0x1078, 0x3a35, 0x00c0, 0x3729, 0x0040, 0x3706, 0x1078,
-+	0x37ac, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x6428, 0x84ff,
-+	0x0040, 0x3762, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3772,
-+	0x273c, 0x87fb, 0x00c0, 0x3750, 0x0048, 0x3748, 0x1078, 0x20c8,
-+	0x609c, 0xa075, 0x0040, 0x3762, 0x0078, 0x373b, 0x2039, 0x3767,
-+	0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040,
-+	0x3762, 0x8738, 0x2704, 0xa005, 0x00c0, 0x3751, 0x709c, 0xa075,
-+	0x00c0, 0x373b, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011,
-+	0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015,
-+	0x001b, 0x0000, 0x0000, 0x3767, 0x3764, 0x0000, 0x0000, 0x8000,
-+	0x0000, 0x3767, 0x0000, 0x376f, 0x376c, 0x0000, 0x0000, 0x0000,
-+	0x0000, 0x376f, 0x0000, 0x376a, 0x376a, 0x0000, 0x0000, 0x8000,
-+	0x0000, 0x376a, 0x0000, 0x3770, 0x3770, 0x0000, 0x0000, 0x0000,
-+	0x0000, 0x3770, 0x127e, 0x2091, 0x2200, 0x2079, 0x3d00, 0x2071,
-+	0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071,
-+	0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049,
-+	0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x37ac, 0x2019, 0x0000,
-+	0x7004, 0x8004, 0x00c8, 0x37f8, 0x7007, 0x0012, 0x7108, 0x7008,
-+	0xa106, 0x00c0, 0x37b6, 0xa184, 0x01e0, 0x0040, 0x37c1, 0x1078,
-+	0x20c8, 0xa184, 0x4000, 0x00c0, 0x37b6, 0xa19c, 0x300c, 0xa386,
-+	0x2004, 0x0040, 0x37d3, 0xa386, 0x0008, 0x0040, 0x37de, 0xa386,
-+	0x200c, 0x00c0, 0x37b6, 0x7200, 0x8204, 0x0048, 0x37de, 0x730c,
-+	0xa384, 0x00ff, 0x0040, 0x37de, 0x1078, 0x20c8, 0x7007, 0x0012,
-+	0x7000, 0xa084, 0x0001, 0x00c0, 0x37f8, 0x7008, 0xa084, 0x01e0,
-+	0x00c0, 0x37f8, 0x7310, 0x7014, 0xa305, 0x0040, 0x37f8, 0x710c,
-+	0xa184, 0x0300, 0x00c0, 0x37f8, 0xa184, 0x00ff, 0x00c0, 0x37ac,
-+	0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0,
-+	0x37fc, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x3801, 0x7003,
-+	0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e, 0x127e, 0x157e,
-+	0x2091, 0x2200, 0x7108, 0x1078, 0x381c, 0x157f, 0x127f, 0x2091,
-+	0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500, 0x730c, 0xa384,
-+	0x0300, 0x00c0, 0x385e, 0xa184, 0x01e0, 0x00c0, 0x3882, 0x7108,
-+	0xa184, 0x01e0, 0x00c0, 0x3882, 0x2001, 0x04fd, 0x2004, 0xa082,
-+	0x0005, 0x00c8, 0x3852, 0xa184, 0x4000, 0x00c0, 0x3827, 0xa986,
-+	0x3a5e, 0x00c0, 0x3852, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040,
-+	0x3849, 0xa386, 0x0008, 0x0040, 0x3852, 0xa386, 0x200c, 0x00c0,
-+	0x3827, 0x7200, 0x8204, 0x0048, 0x3852, 0x730c, 0xa384, 0x00ff,
-+	0x00c0, 0x385e, 0xa184, 0x0007, 0x0079, 0x3856, 0x3860, 0x3872,
-+	0x385e, 0x3872, 0x385e, 0x38be, 0x385e, 0x38bc, 0x1078, 0x20c8,
-+	0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0,
-+	0x386d, 0x2049, 0x0000, 0x0078, 0x3871, 0x1078, 0x3a35, 0x00c0,
-+	0x386d, 0x007c, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006,
-+	0x8aff, 0x00c0, 0x387d, 0x0078, 0x3881, 0x1078, 0x3a35, 0x00c0,
-+	0x387d, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x3885, 0x2091,
-+	0x6000, 0x00e0, 0x3889, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007,
-+	0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x3891, 0x7007, 0x0012,
-+	0x7108, 0x8103, 0x0048, 0x3896, 0x7003, 0x0000, 0x7000, 0xa005,
-+	0x00c0, 0x38aa, 0x7004, 0xa005, 0x00c0, 0x38aa, 0x700c, 0xa005,
-+	0x0040, 0x38ac, 0x0078, 0x388d, 0x2049, 0x0000, 0x1078, 0x3463,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x38b7, 0x681b, 0x0002, 0x007c,
-+	0x1078, 0x20c8, 0x1078, 0x20c8, 0x1078, 0x391a, 0x7210, 0x7114,
-+	0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
-+	0x1078, 0x391a, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322,
-+	0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x38e1, 0x00c8,
-+	0x38e1, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
-+	0x38c8, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040,
-+	0x38ed, 0xa7ba, 0x376c, 0x0078, 0x38ef, 0xa7ba, 0x3764, 0x007f,
-+	0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012,
-+	0x1078, 0x37ac, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x390e,
-+	0x609c, 0xa005, 0x0040, 0x3917, 0x2060, 0x6004, 0xa084, 0x000f,
-+	0xa080, 0x3772, 0x203c, 0x87fb, 0x1040, 0x20c8, 0x8a51, 0x0040,
-+	0x3916, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051,
-+	0x0000, 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x392e,
-+	0x6000, 0xa064, 0x00c0, 0x3925, 0x2d60, 0x6004, 0xa084, 0x000f,
-+	0xa080, 0x3782, 0x203c, 0x87fb, 0x1040, 0x20c8, 0x007c, 0x127e,
-+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c,
-+	0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804,
-+	0xa084, 0x0008, 0x007f, 0x0040, 0x3949, 0xa0b8, 0x376c, 0x0078,
-+	0x394b, 0xa0b8, 0x3764, 0x7e08, 0xa6b5, 0x000c, 0x681c, 0xa084,
-+	0x0040, 0x0040, 0x3955, 0xa6b5, 0x0001, 0x7007, 0x0004, 0x7004,
-+	0xa084, 0x0004, 0x00c0, 0x3957, 0x2400, 0xa305, 0x00c0, 0x3962,
-+	0x0078, 0x3988, 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400,
-+	0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, 0x0040, 0x3978,
-+	0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, 0x7026,
-+	0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, 0x7016,
-+	0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x38fb, 0x0078, 0x398a,
-+	0x1078, 0x3a35, 0x00c0, 0x3988, 0x127f, 0x2000, 0x007c, 0x127e,
-+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084,
-+	0x0004, 0x00c0, 0x3996, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x39a0, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x39a9, 0x7e08, 0xa6b5,
-+	0x000c, 0x681c, 0xa084, 0x0020, 0x00c0, 0x39b8, 0xa6b5, 0x0001,
-+	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3772,
-+	0x273c, 0x87fb, 0x00c0, 0x39ce, 0x0048, 0x39c8, 0x1078, 0x20c8,
-+	0x689c, 0xa065, 0x0040, 0x39d2, 0x0078, 0x39bb, 0x1078, 0x3a35,
-+	0x00c0, 0x39ce, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
-+	0x000c, 0x681c, 0xa084, 0x0040, 0x0040, 0x39e8, 0xa6b5, 0x0001,
-+	0x2049, 0x39d5, 0x6828, 0xa055, 0x0040, 0x3a32, 0x2d70, 0x2e60,
-+	0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3772, 0x273c, 0x87fb, 0x00c0,
-+	0x3a04, 0x0048, 0x39fd, 0x1078, 0x20c8, 0x709c, 0xa075, 0x2060,
-+	0x0040, 0x3a32, 0x0078, 0x39f0, 0x2704, 0xae68, 0x6808, 0xa422,
-+	0x680c, 0xa31b, 0x0048, 0x3a1f, 0x8a51, 0x00c0, 0x3a11, 0x1078,
-+	0x20c8, 0x8738, 0x2704, 0xa005, 0x00c0, 0x3a05, 0x709c, 0xa075,
-+	0x2060, 0x0040, 0x3a32, 0x2039, 0x3764, 0x0078, 0x39f0, 0x8422,
-+	0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c,
-+	0x2300, 0xa11b, 0x00c8, 0x3a2e, 0x1078, 0x20c8, 0x2071, 0x0020,
-+	0x0078, 0x3955, 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003,
-+	0xa086, 0x0003, 0x0040, 0x3a5d, 0x2704, 0xac08, 0x2104, 0x701a,
-+	0x8108, 0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108, 0x2104,
-+	0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x3a54, 0x8108, 0x2104,
-+	0x7022, 0x8108, 0x2104, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010,
-+	0xa085, 0x0001, 0x7006, 0x1078, 0x38fb, 0x007c, 0x127e, 0x007e,
-+	0x0d7e, 0x2091, 0x2200, 0x2049, 0x3a5e, 0x0d7f, 0x087f, 0x7108,
-+	0xa184, 0x0003, 0x00c0, 0x3a72, 0x6828, 0xa005, 0x0040, 0x3a80,
-+	0x0078, 0x3701, 0x00a0, 0x3a79, 0x7108, 0x1078, 0x381c, 0x0078,
-+	0x3a67, 0x7007, 0x0010, 0x00a0, 0x3a7b, 0x7108, 0x1078, 0x381c,
-+	0x7008, 0xa086, 0x0008, 0x00c0, 0x3a67, 0x7000, 0xa005, 0x00c0,
-+	0x3a67, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200,
-+	0x0d7f, 0x2049, 0x3a90, 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031,
-+	0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
-+	0x7003, 0x0001, 0x0040, 0x3aaf, 0x8000, 0x80ac, 0x53a5, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x3ab1, 0x0c7f, 0x2049,
-+	0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
-+	0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78c0, 0xa005, 0x00c0,
-+	0x3ad8, 0x798c, 0x70d0, 0xa106, 0x00c0, 0x3ad8, 0x7804, 0xa005,
-+	0x0040, 0x3ad8, 0x7807, 0x0000, 0x0068, 0x3ad8, 0x2091, 0x4080,
-+	0x7820, 0x8001, 0x7822, 0x00c0, 0x3b5d, 0x7824, 0x7822, 0x783c,
-+	0xa005, 0x0040, 0x3ae9, 0x8001, 0x783e, 0x00c0, 0x3ae9, 0x1078,
-+	0x3c87, 0x78ec, 0xa005, 0x0040, 0x3b0d, 0x78d4, 0xa005, 0x00c0,
-+	0x3b0d, 0x3a10, 0xa284, 0x0002, 0x00c0, 0x3afd, 0x78d7, 0x0007,
-+	0x2009, 0xff01, 0x200a, 0x0078, 0x3b0d, 0xa284, 0x0001, 0x00c0,
-+	0x3b05, 0x78eb, 0x0000, 0x0078, 0x3b0d, 0x78e8, 0xa005, 0x00c0,
-+	0x3b0d, 0x78d7, 0x0008, 0x78eb, 0x0001, 0x2069, 0x3d40, 0x6800,
-+	0xa084, 0x0007, 0x0040, 0x3b24, 0xa086, 0x0002, 0x0040, 0x3b24,
-+	0x6830, 0xa00d, 0x0040, 0x3b24, 0x2104, 0xa005, 0x0040, 0x3b24,
-+	0x8001, 0x200a, 0x0040, 0x3bff, 0x7848, 0xa005, 0x0040, 0x3b2e,
-+	0x8001, 0x784a, 0x00c0, 0x3b2e, 0x1078, 0x1f05, 0x68c4, 0xa005,
-+	0x0040, 0x3b3a, 0x8001, 0x68c6, 0x00c0, 0x3b3a, 0x68a3, 0x0000,
-+	0x68a7, 0x0001, 0x2061, 0x4000, 0x2009, 0x0002, 0x20a9, 0x0100,
-+	0x6034, 0xa005, 0x0040, 0x3b50, 0x8001, 0x6036, 0x00c0, 0x3b50,
-+	0x6010, 0xa005, 0x0040, 0x3b50, 0x017e, 0x1078, 0x1f05, 0x017f,
-+	0xace0, 0x0010, 0x0070, 0x3b56, 0x0078, 0x3b40, 0x8109, 0x0040,
-+	0x3b5d, 0x20a9, 0x0100, 0x0078, 0x3b40, 0x1078, 0x3b64, 0x1078,
-+	0x3b89, 0x2091, 0x8001, 0x007c, 0x7834, 0x8001, 0x7836, 0x00c0,
-+	0x3b88, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005, 0x00c0,
-+	0x3b73, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x6000, 0x2040,
-+	0x2004, 0xa065, 0x0040, 0x3b88, 0x6024, 0xa005, 0x0040, 0x3b84,
-+	0x8001, 0x6026, 0x0040, 0x3bb8, 0x6000, 0x2c40, 0x0078, 0x3b79,
-+	0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x3bb7, 0x782c, 0x782a,
-+	0x7830, 0xa005, 0x00c0, 0x3b96, 0x2001, 0x0200, 0x8001, 0x7832,
-+	0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x4000, 0xa298, 0x0002,
-+	0x2304, 0xa084, 0x0008, 0x0040, 0x3bb7, 0xa290, 0x0009, 0x2204,
-+	0xa005, 0x0040, 0x3baf, 0x8001, 0x2012, 0x00c0, 0x3bb7, 0x2304,
-+	0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x1f05, 0x007c,
-+	0x2069, 0x3d40, 0x6800, 0xa005, 0x0040, 0x3bc2, 0x683c, 0xac06,
-+	0x0040, 0x3bff, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e,
-+	0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042,
-+	0x6714, 0x6fb6, 0x1078, 0x19f0, 0x6818, 0xa005, 0x0040, 0x3bda,
-+	0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810, 0x8001,
-+	0x00d0, 0x3be4, 0x1078, 0x20c8, 0x6812, 0x602f, 0x0000, 0x6033,
-+	0x0000, 0x2c68, 0x1078, 0x1b7f, 0x2069, 0x3d40, 0x7944, 0xa184,
-+	0x0100, 0x2001, 0x0006, 0x68a2, 0x00c0, 0x3bfa, 0x69ba, 0x2001,
-+	0x0004, 0x68a2, 0x1078, 0x1f00, 0x2091, 0x8001, 0x007c, 0x2009,
-+	0x3d4f, 0x2164, 0x2069, 0x0100, 0x1078, 0x2073, 0x601b, 0x0006,
-+	0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-+	0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, 0xa084,
-+	0x0040, 0x0040, 0x3c3b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-+	0xa084, 0x0004, 0x0040, 0x3c28, 0x0070, 0x3c28, 0x0078, 0x3c1f,
-+	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
-+	0x3c35, 0x0070, 0x3c35, 0x0078, 0x3c2c, 0x20a9, 0x00fa, 0x0070,
-+	0x3c3b, 0x0078, 0x3c37, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
-+	0x0047, 0x2009, 0x3d68, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091,
-+	0x8001, 0x007c, 0x2079, 0x3d00, 0x1078, 0x3c75, 0x1078, 0x3c59,
-+	0x1078, 0x3c67, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000,
-+	0x007c, 0x2019, 0x0003, 0x2011, 0x3d46, 0x2204, 0xa086, 0x003c,
-+	0x0040, 0x3c64, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019,
-+	0x0039, 0x2011, 0x3d46, 0x2204, 0xa086, 0x003c, 0x0040, 0x3c72,
-+	0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011,
-+	0x3d46, 0x2204, 0xa086, 0x003c, 0x0040, 0x3c80, 0x2019, 0x2626,
-+	0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c, 0x2069,
-+	0x3d40, 0x6a40, 0xa285, 0x0000, 0x0040, 0x3cce, 0x6944, 0xa080,
-+	0x3d80, 0x2164, 0x6304, 0x83ff, 0x00c0, 0x3ca1, 0x8211, 0x0040,
-+	0x3ca4, 0x8108, 0xa11a, 0x0048, 0x3c91, 0x2009, 0x3d80, 0x0078,
-+	0x3c91, 0x7940, 0x793e, 0x007c, 0x2011, 0x0002, 0x2039, 0x0000,
-+	0x20a9, 0x0100, 0x1078, 0x19f0, 0x2d00, 0xa088, 0x0002, 0x2168,
-+	0x682b, 0x0000, 0x682f, 0x0000, 0x2104, 0xa085, 0x0040, 0x200a,
-+	0x2100, 0xa088, 0x0010, 0x0070, 0x3cbf, 0x0078, 0x3caf, 0x8211,
-+	0x0040, 0x3cc6, 0x20a9, 0x0100, 0x0078, 0x3caf, 0x2009, 0x3d51,
-+	0x200b, 0x3d7f, 0x2009, 0x3d50, 0x200b, 0x0000, 0x007c, 0x4de2
-+};
-+#else
-+/************************************************************************
-+ *									*
-+ * 	        --- ISP1040 Initiator/Target Firmware ---               *
-+ *			    32 LUN Support				*
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 7.65.00 (14:17 Jul 20, 1999)
-+ */
-+static const u_int16_t isp_1040_risc_code[] = {
-+	0x0078, 0x103a, 0x0000, 0x4057, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
-+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
-+	0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
-+	0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3635,
-+	0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
-+	0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
-+	0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
-+	0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
-+	0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
-+	0x0010, 0x70c3, 0x0004, 0x20c9, 0x77ff, 0x2089, 0x1186, 0x70c7,
-+	0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
-+	0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
-+	0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
-+	0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040,
-+	0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1,
-+	0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1,
-+	0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc,
-+	0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040,
-+	0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134,
-+	0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078,
-+	0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
-+	0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
-+	0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
-+	0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5100, 0x8424,
-+	0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7800, 0x2009,
-+	0x0000, 0x2001, 0x0031, 0x1078, 0x1cba, 0x2218, 0x2079, 0x5100,
-+	0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
-+	0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
-+	0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
-+	0x0002, 0x784f, 0x0003, 0x2069, 0x5140, 0x2001, 0x04fd, 0x2004,
-+	0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
-+	0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
-+	0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
-+	0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
-+	0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5380, 0x2011, 0x0020,
-+	0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
-+	0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
-+	0x8109, 0x00c0, 0x1122, 0x2069, 0x5400, 0x2009, 0x0002, 0x20a9,
-+	0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
-+	0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
-+	0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
-+	0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x220a, 0x1078,
-+	0x482c, 0x1078, 0x1963, 0x1078, 0x4d22, 0x3200, 0xa085, 0x000d,
-+	0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
-+	0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
-+	0x00c0, 0x117a, 0x1078, 0x1ce3, 0x0010, 0x1180, 0x0068, 0x1180,
-+	0x1078, 0x20e9, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a48,
-+	0x00e0, 0x116c, 0x1078, 0x4ba9, 0x0078, 0x116c, 0x118e, 0x1190,
-+	0x240b, 0x240b, 0x48ad, 0x48ad, 0x240b, 0x240b, 0x0078, 0x118e,
-+	0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
-+	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
-+	0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
-+	0x515b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5164, 0x200b,
-+	0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
-+	0x5162, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
-+	0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
-+	0x1078, 0x1948, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
-+	0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5162, 0x2104,
-+	0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x19b3,
-+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007,
-+	0x0103, 0x1078, 0x1924, 0x00c0, 0x11fb, 0x1078, 0x1948, 0x2009,
-+	0x5162, 0x200b, 0x0000, 0x2009, 0x515c, 0x2104, 0x200b, 0x0000,
-+	0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
-+	0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
-+	0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
-+	0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
-+	0x12a0, 0x1748, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
-+	0x174d, 0x1298, 0x1329, 0x1360, 0x1672, 0x1742, 0x12b5, 0x1591,
-+	0x15ad, 0x15c9, 0x15f4, 0x154a, 0x1558, 0x156c, 0x1580, 0x13df,
-+	0x1298, 0x138d, 0x1393, 0x1398, 0x139d, 0x13a3, 0x13a8, 0x13ad,
-+	0x13b2, 0x13b7, 0x13bb, 0x13d0, 0x13dc, 0x1298, 0x1298, 0x1298,
-+	0x1298, 0x13eb, 0x13f4, 0x1403, 0x1429, 0x1433, 0x143a, 0x1480,
-+	0x148f, 0x149e, 0x14b0, 0x152a, 0x153a, 0x1298, 0x1298, 0x1298,
-+	0x1298, 0x153f, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
-+	0x001f, 0x0079, 0x125b, 0x1786, 0x1789, 0x1799, 0x1298, 0x1298,
-+	0x18df, 0x18fc, 0x1298, 0x1298, 0x1298, 0x1900, 0x1908, 0x1298,
-+	0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668,
-+	0x1764, 0x1778, 0x1298, 0x1829, 0x190e, 0x18bb, 0x18c5, 0x18c9,
-+	0x18d7, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
-+	0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
-+	0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
-+	0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
-+	0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287,
-+	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
-+	0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078,
-+	0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3,
-+	0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
-+	0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
-+	0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
-+	0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
-+	0x4080, 0x0078, 0x0455, 0x1078, 0x1b53, 0x00c0, 0x129c, 0x75d8,
-+	0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
-+	0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a8d, 0x0040, 0x1284,
-+	0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b53, 0x00c0, 0x129c,
-+	0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
-+	0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1aed, 0x0040,
-+	0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
-+	0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
-+	0x0007, 0x70cb, 0x0041, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078,
-+	0x1b53, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
-+	0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
-+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1350, 0x8001,
-+	0x7892, 0xa084, 0xfc00, 0x0040, 0x1345, 0x78cc, 0xa085, 0x0001,
-+	0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2,
-+	0x7ea6, 0x7c96, 0x78cc, 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1354,
-+	0x78cc, 0xa085, 0x0001, 0x78ce, 0x0078, 0x1284, 0x1078, 0x1b53,
-+	0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1363,
-+	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
-+	0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1387, 0x8001, 0x78ae,
-+	0xa084, 0xfc00, 0x0040, 0x137c, 0x78cc, 0xa085, 0x0100, 0x78ce,
-+	0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba, 0x7dbe, 0x7ec2,
-+	0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078, 0x138b, 0x78cc,
-+	0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009, 0x5161, 0x210c,
-+	0x7aec, 0x0078, 0x1282, 0x2009, 0x5141, 0x210c, 0x0078, 0x1283,
-+	0x2009, 0x5142, 0x210c, 0x0078, 0x1283, 0x2061, 0x5140, 0x610c,
-+	0x6210, 0x0078, 0x1282, 0x2009, 0x5145, 0x210c, 0x0078, 0x1283,
-+	0x2009, 0x5146, 0x210c, 0x0078, 0x1283, 0x2009, 0x5148, 0x210c,
-+	0x0078, 0x1283, 0x2009, 0x5149, 0x210c, 0x0078, 0x1283, 0x7908,
-+	0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003,
-+	0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a00, 0x6804, 0xa084, 0x0008,
-+	0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281,
-+	0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091,
-+	0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4,
-+	0x1078, 0x1973, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
-+	0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c,
-+	0x1078, 0x22e2, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8,
-+	0x127c, 0x2011, 0x5141, 0x2204, 0x007e, 0x2112, 0x1078, 0x229b,
-+	0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008,
-+	0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078,
-+	0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5142,
-+	0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x22a7, 0x017f, 0x0078,
-+	0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
-+	0x004b, 0x2061, 0x5140, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
-+	0x6012, 0x0078, 0x1282, 0x2061, 0x5140, 0x6114, 0x70c4, 0x6016,
-+	0x0078, 0x1283, 0x2061, 0x5140, 0x71c4, 0x2011, 0x0004, 0x601f,
-+	0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x145b, 0x2011,
-+	0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
-+	0x145b, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
-+	0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
-+	0x0001, 0x00c0, 0x1476, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-+	0x0048, 0x146e, 0x0038, 0x1472, 0x0078, 0x1476, 0x0028, 0x1472,
-+	0x0078, 0x1476, 0x2019, 0x2222, 0x0078, 0x1478, 0x2019, 0x1212,
-+	0x23b8, 0x1078, 0x22b8, 0x1078, 0x4d22, 0x017f, 0x0078, 0x1283,
-+	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5148, 0x2204,
-+	0x2112, 0x007e, 0x1078, 0x22da, 0x017f, 0x0078, 0x1283, 0x71c4,
-+	0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5149, 0x2204, 0x007e,
-+	0x2112, 0x1078, 0x22c9, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
-+	0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
-+	0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
-+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
-+	0x5380, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x14c6,
-+	0x6c14, 0x84ff, 0x00c0, 0x14c6, 0x6817, 0x0040, 0xa284, 0x0040,
-+	0x0040, 0x14d0, 0x6c10, 0x84ff, 0x00c0, 0x14d0, 0x6813, 0x0001,
-+	0x6800, 0x007e, 0xa226, 0x0040, 0x14f3, 0x6a02, 0xa484, 0x2000,
-+	0x0040, 0x14dc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14e2,
-+	0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14f3, 0x810f, 0xa284,
-+	0x4000, 0x0040, 0x14ef, 0x1078, 0x22fc, 0x0078, 0x14f3, 0x1078,
-+	0x22ee, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522,
-+	0xa2a4, 0x00ff, 0x2061, 0x5140, 0x6118, 0xa186, 0x0028, 0x0040,
-+	0x1509, 0xa186, 0x0032, 0x0040, 0x150f, 0xa186, 0x003c, 0x0040,
-+	0x1515, 0xa482, 0x0064, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482,
-+	0x0050, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, 0x0043, 0x0048,
-+	0x151f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a,
-+	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
-+	0x0078, 0x1281, 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a14,
-+	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
-+	0x0078, 0x1281, 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4,
-+	0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x230a,
-+	0x0078, 0x1281, 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08,
-+	0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
-+	0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
-+	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21d2, 0x2091,
-+	0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1973, 0x2091,
-+	0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040,
-+	0x157b, 0x1078, 0x21d2, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
-+	0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
-+	0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078,
-+	0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078,
-+	0x19e1, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708,
-+	0x1078, 0x231a, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001,
-+	0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041,
-+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-+	0x1980, 0x2061, 0x5140, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f,
-+	0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21d2, 0x2091, 0x8001,
-+	0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091,
-+	0x8000, 0x2061, 0x5140, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782,
-+	0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21d2, 0x2091, 0x8001,
-+	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000,
-+	0x1078, 0x1980, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0,
-+	0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0,
-+	0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-+	0x0008, 0x1078, 0x1973, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a,
-+	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1601, 0xa7bc,
-+	0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1601,
-+	0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040,
-+	0x1641, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004,
-+	0x0040, 0x162e, 0x0070, 0x162e, 0x0078, 0x1625, 0x684b, 0x0009,
-+	0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x163b, 0x0070,
-+	0x163b, 0x0078, 0x1632, 0x20a9, 0x00fa, 0x0070, 0x1641, 0x0078,
-+	0x163d, 0x2079, 0x5100, 0x7817, 0x0018, 0x2061, 0x5140, 0x606f,
-+	0x0001, 0x6073, 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002,
-+	0x78ce, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091,
-+	0x8001, 0x007c, 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001,
-+	0x00c0, 0x1664, 0x1078, 0x1a2b, 0x71c4, 0x71c6, 0x794a, 0x007c,
-+	0x1078, 0x1b53, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de,
-+	0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc,
-+	0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5100, 0x2091, 0x8000, 0x1078,
-+	0x192e, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1,
-+	0x5118, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020,
-+	0x1078, 0x1929, 0x0040, 0x1698, 0x1078, 0x1948, 0x0078, 0x172c,
-+	0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e,
-+	0x2c68, 0x2091, 0x8000, 0x1078, 0x192e, 0x2091, 0x8001, 0x0040,
-+	0x16cc, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x16a0, 0x609f, 0x0000,
-+	0x0c7f, 0x0c7e, 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c,
-+	0xa065, 0x0040, 0x16fa, 0x2009, 0x0020, 0x1078, 0x1929, 0x00c0,
-+	0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc,
-+	0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060,
-+	0x1078, 0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009,
-+	0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1924, 0x1078,
-+	0x1948, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078,
-+	0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c,
-+	0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1924, 0x1078, 0x1948,
-+	0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091,
-+	0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5140, 0x706f, 0x0005,
-+	0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000,
-+	0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2,
-+	0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x47c2, 0x0e7f, 0x6596,
-+	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078,
-+	0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287,
-+	0x20a9, 0x0005, 0x2099, 0x5118, 0x2091, 0x8000, 0x530a, 0x2091,
-+	0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-+	0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284,
-+	0x71c4, 0x71c6, 0x2168, 0x0078, 0x174f, 0x2069, 0x1000, 0x690c,
-+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1751, 0xa285,
-+	0x0000, 0x00c0, 0x175f, 0x70c3, 0x4000, 0x0078, 0x1761, 0x70c3,
-+	0x4003, 0x70ca, 0x0078, 0x1287, 0x2011, 0x5167, 0x220c, 0x70c4,
-+	0x8003, 0x0048, 0x1771, 0x1078, 0x3b7f, 0xa184, 0x7fff, 0x0078,
-+	0x1775, 0x1078, 0x3b72, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283,
-+	0x71c4, 0x1078, 0x3b69, 0x6100, 0x2001, 0x5167, 0x2004, 0xa084,
-+	0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078,
-+	0x1283, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004,
-+	0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078,
-+	0x1284, 0x70c4, 0x2068, 0x2079, 0x5100, 0x2091, 0x8000, 0x1078,
-+	0x192e, 0x2091, 0x8001, 0x0040, 0x1825, 0x6007, 0x0001, 0x600b,
-+	0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f,
-+	0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016,
-+	0xa284, 0x0800, 0x0040, 0x17c0, 0x601b, 0x000a, 0x0078, 0x17c6,
-+	0xa284, 0x1000, 0x0040, 0x17c6, 0x601b, 0x000c, 0xa284, 0x0300,
-+	0x0040, 0x17cf, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085,
-+	0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400,
-+	0x0040, 0x17dc, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b,
-+	0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0,
-+	0x17f1, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078,
-+	0x17fb, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c,
-+	0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042,
-+	0x2c08, 0x2061, 0x5140, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077,
-+	0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284,
-+	0x0400, 0x608e, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007,
-+	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000,
-+	0x1078, 0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078,
-+	0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071,
-+	0x5140, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040,
-+	0x18b1, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844,
-+	0xa286, 0x000f, 0x00c0, 0x18b1, 0x691c, 0xa184, 0x0080, 0x00c0,
-+	0x18b1, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0,
-+	0x81ff, 0x0040, 0x1867, 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0010,
-+	0x6908, 0x6808, 0xa106, 0x00c0, 0x1858, 0x690c, 0x680c, 0xa106,
-+	0x00c0, 0x185d, 0xa184, 0x00ff, 0x00c0, 0x185d, 0x0d7f, 0x78b8,
-+	0xa084, 0x801f, 0x00c0, 0x1867, 0x7848, 0xa085, 0x000c, 0x784a,
-+	0x71b0, 0x81ff, 0x0040, 0x188a, 0x70b3, 0x0000, 0x0d7e, 0x2069,
-+	0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x187b,
-+	0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1882, 0x6807,
-+	0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce,
-+	0x0e7e, 0x2071, 0x5100, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f,
-+	0x7848, 0xa084, 0x000c, 0x00c0, 0x1898, 0x1078, 0x46db, 0x78a3,
-+	0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080, 0x00df,
-+	0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x0078,
-+	0x1284, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x2001,
-+	0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4, 0xa182, 0x0003,
-+	0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980, 0x71c6, 0x0078,
-+	0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca, 0x71c8,
-+	0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x1284, 0x7974,
-+	0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x1284, 0x7900,
-+	0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-+	0x0048, 0x18ee, 0x0038, 0x18f0, 0x0078, 0x18fa, 0x00a8, 0x18fa,
-+	0xa18c, 0x0001, 0x00c0, 0x18f8, 0x20b9, 0x2222, 0x0078, 0x18fa,
-+	0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078, 0x1284,
-+	0x2009, 0x5174, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078, 0x1284,
-+	0x2009, 0x5174, 0x2104, 0x70c6, 0x0078, 0x1284, 0x71c4, 0x8107,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a14,
-+	0xd2b4, 0x0040, 0x191f, 0x2011, 0x0001, 0x0078, 0x1921, 0x2011,
-+	0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001, 0x1078, 0x1b0f,
-+	0x007c, 0xac80, 0x0001, 0x1078, 0x1aaf, 0x007c, 0x7850, 0xa065,
-+	0x0040, 0x1936, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e,
-+	0x2079, 0x5100, 0x7850, 0xa06d, 0x0040, 0x1946, 0x2d04, 0x7852,
-+	0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000, 0x0f7f, 0x007c,
-+	0x2091, 0x8000, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x2062, 0x2c00,
-+	0xa005, 0x00c0, 0x1955, 0x1078, 0x23eb, 0x7852, 0x0f7f, 0x2091,
-+	0x8001, 0x007c, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x206a, 0x2d00,
-+	0x7852, 0x0f7f, 0x007c, 0x2011, 0x7800, 0x7a52, 0x7bec, 0x8319,
-+	0x0040, 0x1970, 0xa280, 0x0031, 0x2012, 0x2010, 0x0078, 0x1967,
-+	0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
-+	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x5400, 0x007c,
-+	0x1078, 0x1973, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084,
-+	0xffef, 0xa80d, 0x690a, 0x2009, 0x5152, 0x210c, 0x6804, 0xa005,
-+	0x0040, 0x19b2, 0xa116, 0x00c0, 0x199d, 0x2060, 0x6000, 0x6806,
-+	0x017e, 0x200b, 0x0000, 0x0078, 0x19a0, 0x2009, 0x0000, 0x017e,
-+	0x6804, 0xa065, 0x0040, 0x19af, 0x6000, 0x6806, 0x1078, 0x19c0,
-+	0x1078, 0x1c5f, 0x6810, 0x8001, 0x6812, 0x00c0, 0x19a0, 0x017f,
-+	0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x19bf, 0x609c, 0x609f,
-+	0x0000, 0x2008, 0x1078, 0x1948, 0x2100, 0x0078, 0x19b3, 0x007c,
-+	0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005,
-+	0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022,
-+	0x007c, 0x0e7e, 0x2071, 0x5140, 0x704c, 0xa08c, 0x0200, 0x00c0,
-+	0x19df, 0xa088, 0x5180, 0x2d0a, 0x8000, 0x704e, 0xa006, 0x0e7f,
-+	0x007c, 0x1078, 0x1973, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065,
-+	0x0040, 0x1a2a, 0x0078, 0x19f2, 0x2c00, 0x781e, 0x6000, 0xa065,
-+	0x0040, 0x1a2a, 0x600c, 0xa306, 0x00c0, 0x19ec, 0x6010, 0xa206,
-+	0x00c0, 0x19ec, 0x2c28, 0x2001, 0x5152, 0x2004, 0xac06, 0x00c0,
-+	0x1a03, 0x0078, 0x1a28, 0x6804, 0xac06, 0x00c0, 0x1a10, 0x6000,
-+	0xa065, 0x6806, 0x00c0, 0x1a1a, 0x6803, 0x0000, 0x0078, 0x1a1a,
-+	0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1a1a,
-+	0x2c00, 0x6802, 0x2560, 0x1078, 0x19c0, 0x601b, 0x0005, 0x6023,
-+	0x0020, 0x1078, 0x1c5f, 0x6810, 0x8001, 0x1050, 0x23eb, 0x6812,
-+	0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049,
-+	0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1980, 0x8738,
-+	0xa784, 0x001f, 0x00c0, 0x1a35, 0xa7bc, 0xff00, 0x873f, 0x8738,
-+	0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a35, 0x2091, 0x8001, 0x007c,
-+	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1a59, 0x2091,
-+	0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0,
-+	0x1a5a, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1a60, 0x1078, 0x23eb,
-+	0x0079, 0x1a62, 0x1a72, 0x1a75, 0x1a7b, 0x1a7f, 0x1a73, 0x1a83,
-+	0x1a89, 0x1a73, 0x1a73, 0x1c29, 0x1c4d, 0x1c51, 0x1a73, 0x1a73,
-+	0x1a73, 0x1a73, 0x007c, 0x1078, 0x23eb, 0x1078, 0x1a2b, 0x2001,
-+	0x8001, 0x0078, 0x1c57, 0x2001, 0x8003, 0x0078, 0x1c57, 0x2001,
-+	0x8004, 0x0078, 0x1c57, 0x1078, 0x1a2b, 0x2001, 0x8006, 0x0078,
-+	0x1c57, 0x2001, 0x8007, 0x0078, 0x1c57, 0x2030, 0x2138, 0xa782,
-+	0x0021, 0x0048, 0x1a95, 0x2009, 0x0020, 0x2600, 0x1078, 0x1aaf,
-+	0x00c0, 0x1aae, 0xa7ba, 0x0020, 0x0048, 0x1aad, 0x0040, 0x1aad,
-+	0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-+	0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a8f, 0xa006, 0x007c, 0x81ff,
-+	0x0040, 0x1aea, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x00ff,
-+	0x0040, 0x1ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-+	0x1abc, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e,
-+	0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001,
-+	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1ade, 0x2009,
-+	0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ad0, 0x7008, 0x800b,
-+	0x00c8, 0x1ad0, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1aea,
-+	0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138, 0xa782,
-+	0x0021, 0x0048, 0x1af5, 0x2009, 0x0020, 0x2600, 0x1078, 0x1b0f,
-+	0x00c0, 0x1b0e, 0xa7ba, 0x0020, 0x0048, 0x1b0d, 0x0040, 0x1b0d,
-+	0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-+	0x0000, 0xa5a9, 0x0000, 0x0078, 0x1aef, 0xa006, 0x007c, 0x81ff,
-+	0x0040, 0x1b50, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084, 0x00ff,
-+	0x0040, 0x1b21, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-+	0x1b1c, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e,
-+	0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6, 0x7007,
-+	0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b3f,
-+	0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b31, 0x7010,
-+	0xa084, 0xf000, 0x0040, 0x1b48, 0x7007, 0x0008, 0x0078, 0x1b4c,
-+	0x7108, 0x8103, 0x00c8, 0x1b31, 0x7007, 0x0002, 0xa184, 0x01e0,
-+	0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0004,
-+	0x00c8, 0x1b5c, 0x0078, 0x1b5f, 0xa006, 0x0078, 0x1b61, 0xa085,
-+	0x0001, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x2d08, 0x7058, 0x6802,
-+	0xa005, 0x00c0, 0x1b6c, 0x715e, 0x715a, 0x0e7f, 0x007c, 0x2c08,
-+	0x7858, 0x6002, 0xa005, 0x00c0, 0x1b76, 0x795e, 0x795a, 0x007c,
-+	0x2091, 0x8000, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065, 0x00c0,
-+	0x1b84, 0x795a, 0x0078, 0x1b85, 0x6102, 0x795e, 0x2091, 0x8001,
-+	0x1078, 0x21ef, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x7058, 0xa06d,
-+	0x0040, 0x1b99, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1b98, 0x705e,
-+	0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5100,
-+	0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1bc9, 0x2068,
-+	0x6814, 0xa306, 0x00c0, 0x1bb2, 0x6828, 0xa084, 0x00ff, 0xa406,
-+	0x0040, 0x1bb5, 0x2d60, 0x0078, 0x1ba3, 0x6800, 0xa005, 0x6002,
-+	0x00c0, 0x1bc1, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bc0, 0x2c00,
-+	0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bc8, 0x1078, 0x19b3,
-+	0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e,
-+	0x0f7e, 0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005,
-+	0x0040, 0x1bf8, 0x2068, 0x6814, 0xa084, 0x00ff, 0xa306, 0x0040,
-+	0x1be4, 0x2d60, 0x0078, 0x1bd6, 0x6800, 0xa005, 0x6002, 0x00c0,
-+	0x1bf0, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bef, 0x2c00, 0x785e,
-+	0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bf7, 0x1078, 0x19b3, 0x007f,
-+	0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e,
-+	0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa06d, 0x0040,
-+	0x1c24, 0x6814, 0xa306, 0x0040, 0x1c10, 0x2d60, 0x0078, 0x1c05,
-+	0x6800, 0xa005, 0x6002, 0x00c0, 0x1c1c, 0xaf80, 0x0016, 0xac06,
-+	0x0040, 0x1c1b, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040,
-+	0x1c23, 0x1078, 0x19b3, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005,
-+	0x007c, 0x2091, 0x8000, 0x2069, 0x5140, 0x6800, 0xa086, 0x0000,
-+	0x0040, 0x1c37, 0x2091, 0x8001, 0x78e3, 0x0009, 0x007c, 0x6880,
-+	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-+	0x1078, 0x1980, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1c40, 0x2091,
-+	0x8001, 0x2001, 0x800a, 0x0078, 0x1c57, 0x2001, 0x800c, 0x0078,
-+	0x1c57, 0x1078, 0x1a2b, 0x2001, 0x800d, 0x0078, 0x1c57, 0x70c2,
-+	0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0x6004,
-+	0x2c08, 0x2063, 0x0000, 0x7884, 0x8000, 0x7886, 0x7888, 0xa005,
-+	0x798a, 0x0040, 0x1c6e, 0x2c02, 0x0078, 0x1c6f, 0x798e, 0x007c,
-+	0x6807, 0x0103, 0x0c7e, 0x2061, 0x5100, 0x2d08, 0x206b, 0x0000,
-+	0x6084, 0x8000, 0x6086, 0x6088, 0xa005, 0x618a, 0x0040, 0x1c83,
-+	0x2d02, 0x0078, 0x1c84, 0x618e, 0x0c7f, 0x007c, 0x1078, 0x1c97,
-+	0x0040, 0x1c96, 0x0c7e, 0x609c, 0xa065, 0x0040, 0x1c91, 0x1078,
-+	0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1948, 0x007c, 0x788c,
-+	0xa065, 0x0040, 0x1ca9, 0x2091, 0x8000, 0x7884, 0x8001, 0x7886,
-+	0x2c04, 0x788e, 0xa005, 0x00c0, 0x1ca7, 0x788a, 0x8000, 0x2091,
-+	0x8001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
-+	0x00c8, 0x1cb3, 0xa200, 0x0070, 0x1cb7, 0x0078, 0x1cae, 0x8086,
-+	0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1cdd,
-+	0xa11a, 0x00c8, 0x1cdd, 0x8213, 0x818d, 0x0048, 0x1cce, 0xa11a,
-+	0x00c8, 0x1ccf, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0xa11a, 0x2308,
-+	0x8210, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0x007e, 0x3200, 0xa084,
-+	0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085,
-+	0x0800, 0x0078, 0x1cd9, 0x7994, 0x70d0, 0xa106, 0x0040, 0x1d51,
-+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1d51,
-+	0x7008, 0x7208, 0xa206, 0x00c0, 0x1d51, 0xa286, 0x0008, 0x00c0,
-+	0x1d51, 0x2071, 0x0010, 0x1078, 0x192e, 0x0040, 0x1d51, 0x7a9c,
-+	0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00, 0x0040, 0x1d1f, 0x2031,
-+	0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
-+	0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x2100, 0xa210, 0x2600,
-+	0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1d29, 0x8107,
-+	0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-+	0x0000, 0x2009, 0x0020, 0x1078, 0x1929, 0x2091, 0x8001, 0x0040,
-+	0x1d48, 0x1078, 0x1948, 0x78a8, 0x8000, 0x78aa, 0xa086, 0x0002,
-+	0x00c0, 0x1d51, 0x2091, 0x8000, 0x78e3, 0x0002, 0x78ab, 0x0000,
-+	0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091, 0x8001, 0x0078, 0x1d51,
-+	0x78ab, 0x0000, 0x1078, 0x20ac, 0x6004, 0xa084, 0x000f, 0x0079,
-+	0x1d56, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x1d66, 0x1d88,
-+	0x1dae, 0x1d66, 0x1dcb, 0x1d75, 0x1f2c, 0x1f47, 0x1d66, 0x1d82,
-+	0x1da8, 0x1e13, 0x1e82, 0x1ed2, 0x1ee4, 0x1f43, 0x2039, 0x0400,
-+	0x78dc, 0xa705, 0x78de, 0x6008, 0xa705, 0x600a, 0x1078, 0x1fc7,
-+	0x609c, 0x78da, 0x1078, 0x2094, 0x007c, 0x78dc, 0xa084, 0x0100,
-+	0x0040, 0x1d7c, 0x0078, 0x1d66, 0x601c, 0xa085, 0x0080, 0x601e,
-+	0x0078, 0x1d8f, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c6,
-+	0x78dc, 0xa084, 0x0100, 0x0040, 0x1d8f, 0x0078, 0x1d66, 0x78df,
-+	0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f,
-+	0x0000, 0x0040, 0x1da5, 0x1078, 0x1fc7, 0x0040, 0x1da5, 0x78dc,
-+	0xa085, 0x0100, 0x78de, 0x0078, 0x1da7, 0x1078, 0x1feb, 0x007c,
-+	0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c2, 0x78dc, 0xa08c,
-+	0x0e00, 0x00c0, 0x1db7, 0xa084, 0x0100, 0x00c0, 0x1db9, 0x0078,
-+	0x1d66, 0x1078, 0x1fc7, 0x00c0, 0x1dca, 0x6104, 0xa18c, 0x00ff,
-+	0xa186, 0x0007, 0x0040, 0x1f84, 0xa186, 0x000f, 0x0040, 0x1f84,
-+	0x1078, 0x1feb, 0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1dd2,
-+	0x0078, 0x1d66, 0x78df, 0x0000, 0x6714, 0x2011, 0x0001, 0x20a9,
-+	0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x1df5, 0x2011,
-+	0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040,
-+	0x1df5, 0x2039, 0x0000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e,
-+	0x0002, 0x0040, 0x1df5, 0x0078, 0x1e10, 0x1078, 0x1973, 0x2091,
-+	0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde,
-+	0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x0070, 0x1e09, 0x0078,
-+	0x1df7, 0x8211, 0x0040, 0x1e10, 0x20a9, 0x0100, 0x0078, 0x1df7,
-+	0x1078, 0x1948, 0x007c, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000,
-+	0x0040, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6900, 0xa184, 0x0001,
-+	0x0040, 0x1e34, 0x6028, 0xa084, 0x00ff, 0x00c0, 0x1fa4, 0x6800,
-+	0xa084, 0x0001, 0x0040, 0x1fac, 0x6803, 0x0000, 0x680b, 0x0000,
-+	0x6807, 0x0000, 0x0078, 0x1fb4, 0x2011, 0x0001, 0x6020, 0xd0f4,
-+	0x0040, 0x1e3c, 0xa295, 0x0002, 0xd0c4, 0x0040, 0x1e41, 0xa295,
-+	0x0008, 0xd0cc, 0x0040, 0x1e46, 0xa295, 0x0400, 0x601c, 0xa084,
-+	0x0002, 0x0040, 0x1e4d, 0xa295, 0x0004, 0x602c, 0xa08c, 0x00ff,
-+	0xa182, 0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0,
-+	0x0040, 0x1fb0, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff, 0xa182,
-+	0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0, 0x0040,
-+	0x1fb0, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e70, 0x2001, 0x001e,
-+	0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x6806,
-+	0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x680a, 0x6a02,
-+	0x0078, 0x1fb4, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000, 0x0040,
-+	0x1fac, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6a04, 0x6b08,
-+	0x6418, 0xa484, 0x0003, 0x0040, 0x1ea8, 0x6128, 0xa18c, 0x00ff,
-+	0x8001, 0x00c0, 0x1ea1, 0x2100, 0xa210, 0x0048, 0x1ece, 0x0078,
-+	0x1ea8, 0x8001, 0x00c0, 0x1ece, 0x2100, 0xa212, 0x0048, 0x1ece,
-+	0xa484, 0x000c, 0x0040, 0x1ec2, 0x6128, 0x810f, 0xa18c, 0x00ff,
-+	0xa082, 0x0004, 0x00c0, 0x1eba, 0x2100, 0xa318, 0x0048, 0x1ece,
-+	0x0078, 0x1ec2, 0xa082, 0x0004, 0x00c0, 0x1ece, 0x2100, 0xa31a,
-+	0x0048, 0x1ece, 0x6030, 0xa005, 0x0040, 0x1ec8, 0x8000, 0x6816,
-+	0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fb4, 0x2091, 0x8001,
-+	0x0078, 0x1fb0, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6b08,
-+	0x8318, 0x0048, 0x1ee0, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fc3,
-+	0x2091, 0x8001, 0x0078, 0x1fb0, 0x6024, 0x8007, 0xa084, 0x00ff,
-+	0x0040, 0x1f02, 0xa086, 0x0080, 0x00c0, 0x1f2a, 0x20a9, 0x0008,
-+	0x2069, 0x7510, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802,
-+	0xade8, 0x0008, 0x0070, 0x1efe, 0x0078, 0x1ef4, 0x2091, 0x8001,
-+	0x0078, 0x1fb4, 0x6028, 0xa015, 0x0040, 0x1f2a, 0x6114, 0x1078,
-+	0x20e3, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d,
-+	0x0040, 0x1f27, 0xa206, 0x0040, 0x1f18, 0x2168, 0x0078, 0x1f0e,
-+	0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x1948, 0x0c7f, 0x0d7f,
-+	0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091,
-+	0x8001, 0x0d7f, 0x0078, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6800,
-+	0xa084, 0x0001, 0x0040, 0x1f9c, 0x2091, 0x8000, 0x6a04, 0x8210,
-+	0x0048, 0x1f3f, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091,
-+	0x8001, 0x0078, 0x1fb0, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x6114,
-+	0x1078, 0x20e3, 0x60be, 0x60bb, 0x0000, 0x6900, 0xa184, 0x0008,
-+	0x0040, 0x1f56, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001,
-+	0x0040, 0x1fac, 0xa184, 0x0100, 0x00c0, 0x1f98, 0xa184, 0x0200,
-+	0x00c0, 0x1f94, 0x681c, 0xa005, 0x00c0, 0x1fa0, 0x6004, 0xa084,
-+	0x00ff, 0xa086, 0x000f, 0x00c0, 0x1f6f, 0x1078, 0x20c6, 0x78df,
-+	0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f,
-+	0x0000, 0x0040, 0x1f84, 0x1078, 0x1fc7, 0x0040, 0x1f84, 0x78dc,
-+	0xa085, 0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000,
-+	0x6024, 0xa084, 0xff00, 0x6026, 0x1078, 0x39de, 0x0040, 0x1ce3,
-+	0x1078, 0x1b78, 0x0078, 0x1ce3, 0x2009, 0x0017, 0x0078, 0x1fb6,
-+	0x2009, 0x000e, 0x0078, 0x1fb6, 0x2009, 0x0007, 0x0078, 0x1fb6,
-+	0x2009, 0x0035, 0x0078, 0x1fb6, 0x2009, 0x003e, 0x0078, 0x1fb6,
-+	0x2009, 0x0004, 0x0078, 0x1fb6, 0x2009, 0x0006, 0x0078, 0x1fb6,
-+	0x2009, 0x0016, 0x0078, 0x1fb6, 0x2009, 0x0001, 0x6024, 0xa084,
-+	0xff00, 0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c5f, 0x2091,
-+	0x8001, 0x0078, 0x1ce3, 0x1078, 0x1948, 0x0078, 0x1ce3, 0x78d4,
-+	0xa06d, 0x00c0, 0x1fd2, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000,
-+	0x0078, 0x1fde, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00,
-+	0x6002, 0x78d8, 0xad06, 0x00c0, 0x1fde, 0x6002, 0x78d0, 0x8001,
-+	0x78d2, 0x00c0, 0x1fea, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8,
-+	0x2060, 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184,
-+	0xe1ff, 0x601e, 0xa184, 0x0060, 0x0040, 0x1ffa, 0x0e7e, 0x1078,
-+	0x47c2, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000,
-+	0x60b3, 0x0000, 0x6714, 0x1078, 0x1973, 0x2091, 0x8000, 0x60a0,
-+	0xa084, 0x8000, 0x00c0, 0x2021, 0x6808, 0xa084, 0x0001, 0x0040,
-+	0x2021, 0x2091, 0x8001, 0x1078, 0x19c0, 0x2091, 0x8000, 0x1078,
-+	0x1c5f, 0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078,
-+	0x2093, 0x6024, 0xa096, 0x0001, 0x00c0, 0x2028, 0x8000, 0x6026,
-+	0x6a10, 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2037, 0x0040,
-+	0x2037, 0x2039, 0x0200, 0x1078, 0x2094, 0x0078, 0x2093, 0x2c08,
-+	0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2064, 0x6800,
-+	0xa065, 0x0040, 0x2069, 0x6a04, 0x0e7e, 0x2071, 0x5140, 0x7000,
-+	0xa084, 0x0001, 0x0040, 0x205e, 0x7048, 0xa206, 0x00c0, 0x205e,
-+	0x6b04, 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2059,
-+	0x6902, 0x2260, 0x6102, 0x0e7f, 0x0078, 0x2070, 0x2160, 0x6202,
-+	0x6906, 0x0e7f, 0x0078, 0x2070, 0x6800, 0xa065, 0x0040, 0x2069,
-+	0x6102, 0x6902, 0x00c0, 0x206d, 0x6906, 0x2160, 0x6003, 0x0000,
-+	0x2160, 0x60a0, 0xa084, 0x8000, 0x0040, 0x207a, 0x6808, 0xa084,
-+	0xfffc, 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808,
-+	0xa08c, 0x0040, 0x0040, 0x2089, 0xa086, 0x0040, 0x680a, 0x1078,
-+	0x19d1, 0x2091, 0x8000, 0x1078, 0x21d2, 0x2091, 0x8001, 0x78db,
-+	0x0000, 0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091,
-+	0x8000, 0x1078, 0x1c5f, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040,
-+	0x20a7, 0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2097, 0x78d7,
-+	0x0000, 0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a,
-+	0x00c8, 0x20b3, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040,
-+	0x20c1, 0x8001, 0x7806, 0x00c0, 0x20c1, 0x0068, 0x20c1, 0x2091,
-+	0x4080, 0x007c, 0x2039, 0x20da, 0x0078, 0x20c8, 0x2039, 0x20e0,
-+	0x2704, 0xa005, 0x0040, 0x20d9, 0xac00, 0x2068, 0x6b08, 0x6c0c,
-+	0x6910, 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078,
-+	0x20c8, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000,
-+	0x0015, 0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b69, 0x2c68, 0x0c7f,
-+	0x007c, 0x0010, 0x215a, 0x0068, 0x215a, 0x2029, 0x0000, 0x78cb,
-+	0x0000, 0x788c, 0xa065, 0x0040, 0x2153, 0x2009, 0x5174, 0x2104,
-+	0xa084, 0x0001, 0x0040, 0x2121, 0x6004, 0xa086, 0x0103, 0x00c0,
-+	0x2121, 0x6018, 0xa005, 0x00c0, 0x2121, 0x6014, 0xa005, 0x00c0,
-+	0x2121, 0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0,
-+	0x2120, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b,
-+	0x0001, 0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c86, 0x0078, 0x2158,
-+	0x0d7f, 0x1078, 0x215b, 0x0040, 0x2153, 0x6204, 0xa294, 0x00ff,
-+	0xa296, 0x0003, 0x0040, 0x2133, 0x6204, 0xa296, 0x0110, 0x00c0,
-+	0x2141, 0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211,
-+	0x0040, 0x2141, 0x85ff, 0x00c0, 0x2153, 0x8210, 0xa202, 0x00c8,
-+	0x2153, 0x057e, 0x1078, 0x216a, 0x057f, 0x0040, 0x214e, 0x78e0,
-+	0xa086, 0x0003, 0x0040, 0x2153, 0x0078, 0x2141, 0x8528, 0x78c8,
-+	0xa005, 0x0040, 0x20f1, 0x85ff, 0x0040, 0x215a, 0x2091, 0x4080,
-+	0x78b0, 0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0,
-+	0x2164, 0x2300, 0xa005, 0x007c, 0x0048, 0x2168, 0xa302, 0x007c,
-+	0x8002, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
-+	0x2184, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0,
-+	0x21b9, 0x7008, 0x7208, 0xa206, 0x00c0, 0x21b9, 0xa286, 0x0008,
-+	0x00c0, 0x21b9, 0x2071, 0x0010, 0x1078, 0x21be, 0x2009, 0x0020,
-+	0x6004, 0xa086, 0x0103, 0x00c0, 0x2193, 0x6028, 0xa005, 0x00c0,
-+	0x2193, 0x2009, 0x000c, 0x1078, 0x1924, 0x0040, 0x21ac, 0x78c4,
-+	0x8000, 0x78c6, 0xa086, 0x0002, 0x00c0, 0x21b9, 0x2091, 0x8000,
-+	0x78e3, 0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce,
-+	0x2091, 0x8001, 0x0078, 0x21b9, 0x78c7, 0x0000, 0x1078, 0x1c86,
-+	0x79ac, 0x78b0, 0x8000, 0xa10a, 0x00c8, 0x21b7, 0xa006, 0x78b2,
-+	0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004,
-+	0x8004, 0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000,
-+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x515b, 0x2091,
-+	0x8000, 0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x7000, 0xa086,
-+	0x0000, 0x00c0, 0x21ec, 0x2009, 0x5112, 0x2104, 0xa005, 0x00c0,
-+	0x21ec, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21ec,
-+	0x0018, 0x21ec, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e,
-+	0x0e7e, 0x2071, 0x5140, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000,
-+	0x00c0, 0x2205, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0,
-+	0x2205, 0x0018, 0x2205, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f,
-+	0x0f7f, 0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5140, 0x2079,
-+	0x0100, 0x784b, 0x000f, 0x0098, 0x2218, 0x7838, 0x0078, 0x2211,
-+	0x20a9, 0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2221, 0x20a9,
-+	0x0060, 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070,
-+	0x222b, 0x0078, 0x2223, 0x7800, 0xa082, 0x0004, 0x0048, 0x223a,
-+	0x70b7, 0x0096, 0x2019, 0x4ee7, 0x1078, 0x2276, 0x702f, 0x8001,
-+	0x0078, 0x2246, 0x70b7, 0x0000, 0x2019, 0x4d5f, 0x1078, 0x2276,
-+	0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7003, 0x0000,
-+	0x1078, 0x237f, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd,
-+	0x210c, 0xa18a, 0x0005, 0x0048, 0x225b, 0x0038, 0x2261, 0xa085,
-+	0x6280, 0x0078, 0x2263, 0x0028, 0x2261, 0xa085, 0x6280, 0x0078,
-+	0x2263, 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843,
-+	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053,
-+	0x517f, 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e,
-+	0x157e, 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040,
-+	0x2296, 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00,
-+	0x0040, 0x228e, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6,
-+	0xa005, 0x00c0, 0x2285, 0x3318, 0x0078, 0x227c, 0x047f, 0x157f,
-+	0x147f, 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204,
-+	0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x237f, 0x007c, 0x2011,
-+	0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x22b0, 0x0078, 0x22ab,
-+	0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c,
-+	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22c1, 0x0078,
-+	0x22bc, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a,
-+	0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22d2,
-+	0x0078, 0x22cd, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105,
-+	0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105,
-+	0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061,
-+	0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003,
-+	0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084,
-+	0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022,
-+	0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae,
-+	0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061,
-+	0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018,
-+	0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005,
-+	0x0040, 0x235d, 0x2061, 0x7500, 0x1078, 0x2365, 0x0040, 0x2349,
-+	0x20a9, 0x0000, 0x2061, 0x7400, 0x0c7e, 0x1078, 0x2365, 0x0040,
-+	0x2339, 0x0c7f, 0x8c60, 0x0070, 0x2337, 0x0078, 0x232c, 0x0078,
-+	0x235d, 0x007f, 0xa082, 0x7400, 0x2071, 0x5140, 0x7086, 0x7182,
-+	0x2001, 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21cd, 0x0078,
-+	0x2359, 0x60c0, 0xa005, 0x00c0, 0x235d, 0x2071, 0x5140, 0x7182,
-+	0x2c00, 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078,
-+	0x21cd, 0x2001, 0x0000, 0x0078, 0x235f, 0x2001, 0x0001, 0x2091,
-+	0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040,
-+	0x237c, 0x2060, 0x600c, 0xa306, 0x00c0, 0x2379, 0x6010, 0xa206,
-+	0x00c0, 0x2379, 0x6014, 0xa106, 0x00c0, 0x2379, 0xa006, 0x0078,
-+	0x237e, 0x6000, 0x0078, 0x2366, 0xa085, 0x0001, 0x007c, 0x2011,
-+	0x5141, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084,
-+	0x0100, 0x0040, 0x2395, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b,
-+	0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4,
-+	0xa08c, 0x0020, 0x0040, 0x23e9, 0xa084, 0x0006, 0x00c0, 0x23e9,
-+	0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0,
-+	0x5380, 0x7004, 0xa084, 0x000a, 0x00c0, 0x23e9, 0x7108, 0xa194,
-+	0xff00, 0x0040, 0x23e9, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106,
-+	0x0040, 0x23d0, 0x2001, 0x0012, 0xa106, 0x0040, 0x23d4, 0x2001,
-+	0x0014, 0xa106, 0x0040, 0x23d8, 0x2001, 0x0019, 0xa106, 0x0040,
-+	0x23dc, 0x2001, 0x0032, 0xa106, 0x0040, 0x23e0, 0x0078, 0x23e4,
-+	0x2009, 0x0012, 0x0078, 0x23e6, 0x2009, 0x0014, 0x0078, 0x23e6,
-+	0x2009, 0x0019, 0x0078, 0x23e6, 0x2009, 0x0020, 0x0078, 0x23e6,
-+	0x2009, 0x003f, 0x0078, 0x23e6, 0x2011, 0x0000, 0x2100, 0xa205,
-+	0x700a, 0x0e7f, 0x007c, 0x0068, 0x23eb, 0x2091, 0x8000, 0x2071,
-+	0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23f2, 0x007f,
-+	0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db,
-+	0x0741, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
-+	0x4080, 0x0078, 0x2409, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300,
-+	0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce,
-+	0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x2420,
-+	0x2432, 0x2432, 0x2432, 0x276c, 0x393b, 0x2430, 0x2461, 0x246b,
-+	0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430,
-+	0x1078, 0x23eb, 0x8507, 0xa084, 0x001f, 0x0079, 0x2437, 0x2475,
-+	0x276c, 0x2926, 0x2a23, 0x2a4b, 0x2ced, 0x2f98, 0x2fdb, 0x3026,
-+	0x30ab, 0x3163, 0x320c, 0x2461, 0x2848, 0x2f6d, 0x2457, 0x3cc8,
-+	0x3ce8, 0x3eae, 0x3eba, 0x3f8f, 0x2457, 0x2457, 0x4062, 0x4066,
-+	0x3cc6, 0x2457, 0x3e19, 0x2457, 0x3b8c, 0x246b, 0x2457, 0x1078,
-+	0x23eb, 0x0018, 0x2410, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f,
-+	0x007c, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x781b,
-+	0x004f, 0x0078, 0x2459, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f,
-+	0x8000, 0x781b, 0x00d0, 0x0078, 0x2459, 0x7242, 0x2009, 0x510f,
-+	0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3ba0, 0x0040, 0x2492,
-+	0x1078, 0x23eb, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000,
-+	0x7037, 0x0000, 0x1078, 0x3912, 0x0018, 0x2410, 0x2009, 0x510f,
-+	0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x255d, 0x706c, 0xa084,
-+	0x0007, 0x0079, 0x249b, 0x2594, 0x24a3, 0x24af, 0x24cc, 0x24ee,
-+	0x253b, 0x2514, 0x24a3, 0x1078, 0x38fa, 0x2009, 0x0048, 0x1078,
-+	0x2e39, 0x00c0, 0x24ad, 0x7003, 0x0004, 0x0078, 0x2459, 0x1078,
-+	0x38fa, 0x00c0, 0x24ca, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010,
-+	0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004,
-+	0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ca, 0x7003, 0x0004,
-+	0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x24ec,
-+	0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d,
-+	0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002,
-+	0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ec,
-+	0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa,
-+	0x00c0, 0x2512, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c,
-+	0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa,
-+	0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004,
-+	0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2512, 0x7003, 0x0004,
-+	0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2539,
-+	0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d,
-+	0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002,
-+	0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2539,
-+	0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093,
-+	0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x7088,
-+	0x2068, 0x6f14, 0x1078, 0x37ef, 0x2c50, 0x1078, 0x39ac, 0x789b,
-+	0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c,
-+	0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040,
-+	0x255b, 0x2001, 0x0006, 0x0078, 0x267c, 0x1078, 0x38fa, 0x00c0,
-+	0x2459, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37ef,
-+	0x2c50, 0x1078, 0x39ac, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824,
-+	0xa005, 0x0040, 0x257b, 0xa082, 0x0006, 0x0048, 0x2579, 0x0078,
-+	0x257b, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0,
-+	0x7058, 0xa084, 0x8000, 0x0040, 0x2589, 0xa684, 0x0001, 0x0040,
-+	0x258b, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001,
-+	0x2001, 0x0003, 0x0078, 0x267c, 0x0018, 0x2410, 0x744c, 0xa485,
-+	0x0000, 0x0040, 0x25ae, 0xa080, 0x5180, 0x2030, 0x7150, 0x8108,
-+	0xa12a, 0x0048, 0x25a5, 0x2009, 0x5180, 0x2164, 0x6504, 0x85ff,
-+	0x00c0, 0x25bf, 0x8421, 0x00c0, 0x259f, 0x7152, 0x7003, 0x0000,
-+	0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3ba0, 0x0078, 0x2459,
-+	0x764c, 0xa6b0, 0x5180, 0x7150, 0x2600, 0x0078, 0x25aa, 0x7152,
-+	0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0,
-+	0x25bc, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25f5, 0xa784,
-+	0x0021, 0x00c0, 0x25bc, 0xa784, 0x0002, 0x0040, 0x25de, 0xa784,
-+	0x0004, 0x0040, 0x25bc, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008,
-+	0x00c0, 0x25bc, 0xa784, 0x0010, 0x00c0, 0x25bc, 0xa784, 0x0200,
-+	0x00c0, 0x25bc, 0xa784, 0x0100, 0x0040, 0x25f5, 0x6018, 0xa005,
-+	0x00c0, 0x25bc, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c,
-+	0xa684, 0x000e, 0x6118, 0x0040, 0x2605, 0x601c, 0xa102, 0x0048,
-+	0x2608, 0x0040, 0x2608, 0x0078, 0x25b8, 0x81ff, 0x00c0, 0x25b8,
-+	0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x2610, 0x700c, 0x6022,
-+	0xa7bc, 0xff7f, 0x670a, 0x1078, 0x39ac, 0x0018, 0x2410, 0x789b,
-+	0x0010, 0xa046, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x6b14, 0xa39c,
-+	0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262c,
-+	0xa684, 0x0001, 0x0040, 0x262e, 0xa39c, 0xffbf, 0xa684, 0x0010,
-+	0x0040, 0x2634, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e,
-+	0x00c0, 0x263f, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x267a, 0x7158,
-+	0xa18c, 0x0800, 0x0040, 0x3401, 0x2011, 0x0020, 0xa684, 0x0008,
-+	0x00c0, 0x2650, 0x8210, 0xa684, 0x0002, 0x00c0, 0x2650, 0x8210,
-+	0x7aaa, 0x8840, 0x1078, 0x3912, 0x6a14, 0x610c, 0x8108, 0xa18c,
-+	0x00ff, 0xa1e0, 0x7400, 0x2c64, 0x8cff, 0x0040, 0x2671, 0x6014,
-+	0xa206, 0x00c0, 0x265b, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2656,
-+	0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078,
-+	0x2594, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x2a60, 0x610e, 0x79aa,
-+	0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018,
-+	0x0040, 0x2697, 0xa184, 0x0010, 0x0040, 0x268a, 0x1078, 0x3604,
-+	0x00c0, 0x26ba, 0xa184, 0x0008, 0x0040, 0x2697, 0x69a0, 0xa184,
-+	0x0600, 0x00c0, 0x2697, 0x1078, 0x34f1, 0x0078, 0x26ba, 0x69a0,
-+	0xa184, 0x0800, 0x0040, 0x26ae, 0x0c7e, 0x027e, 0x2960, 0x6000,
-+	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f,
-+	0x0c7f, 0x1078, 0x3604, 0x00c0, 0x26ba, 0x69a0, 0xa184, 0x0200,
-+	0x0040, 0x26b6, 0x1078, 0x3540, 0x0078, 0x26ba, 0xa184, 0x0400,
-+	0x00c0, 0x2693, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26c5, 0x6914,
-+	0xa18c, 0xff00, 0x810f, 0x1078, 0x22ee, 0x007f, 0x7002, 0xa68c,
-+	0x00e0, 0xa684, 0x0060, 0x0040, 0x26d3, 0xa086, 0x0060, 0x00c0,
-+	0x26d3, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x26d8, 0xa18d, 0x0004,
-+	0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061,
-+	0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080,
-+	0x0040, 0x26f7, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26f5,
-+	0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa,
-+	0x8008, 0x810c, 0x0040, 0x3407, 0xa18c, 0x00f8, 0x00c0, 0x3407,
-+	0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
-+	0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
-+	0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2,
-+	0x7eda, 0x1078, 0x38fa, 0x00c0, 0x272e, 0x702c, 0x8003, 0x0048,
-+	0x2727, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7830,
-+	0xa084, 0x00c0, 0x00c0, 0x272e, 0x0098, 0x2736, 0x6008, 0xa084,
-+	0xffef, 0x600a, 0x1078, 0x3912, 0x0078, 0x2482, 0x7200, 0xa284,
-+	0x0007, 0xa086, 0x0001, 0x00c0, 0x2743, 0x781b, 0x004f, 0x1078,
-+	0x3912, 0x0078, 0x2754, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b,
-+	0x004f, 0x1078, 0x3912, 0x7200, 0x2500, 0xa605, 0x0040, 0x2754,
-+	0xa284, 0x0007, 0x1079, 0x2762, 0xad80, 0x0009, 0x7036, 0xa284,
-+	0x0007, 0xa086, 0x0001, 0x00c0, 0x2459, 0x6018, 0x8000, 0x601a,
-+	0x0078, 0x2459, 0x276a, 0x4a3a, 0x4a3a, 0x4a29, 0x4a3a, 0x276a,
-+	0x4a29, 0x276a, 0x1078, 0x23eb, 0x1078, 0x38fa, 0x0f7e, 0x2079,
-+	0x5100, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2790, 0x706c,
-+	0xa086, 0x0001, 0x00c0, 0x277f, 0x706e, 0x0078, 0x2823, 0x706c,
-+	0xa086, 0x0005, 0x00c0, 0x278e, 0x7088, 0x2068, 0x681b, 0x0004,
-+	0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000,
-+	0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x27b1, 0xa186,
-+	0x0007, 0x00c0, 0x27a1, 0x2009, 0x5138, 0x200b, 0x0005, 0x0078,
-+	0x27b1, 0x2009, 0x5113, 0x2104, 0x2009, 0x5112, 0x200a, 0x2009,
-+	0x5138, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078,
-+	0x27b3, 0x706f, 0x0000, 0x1078, 0x4776, 0x157e, 0x20a9, 0x0010,
-+	0x2039, 0x0000, 0x1078, 0x36e2, 0xa7b8, 0x0100, 0x0070, 0x27c2,
-+	0x0078, 0x27ba, 0x157f, 0x7000, 0x0079, 0x27c6, 0x27f4, 0x27db,
-+	0x27db, 0x27ce, 0x27f4, 0x27f4, 0x27f4, 0x27f4, 0x2021, 0x515a,
-+	0x2404, 0xa005, 0x0040, 0x27f4, 0xad06, 0x00c0, 0x27db, 0x6800,
-+	0x2022, 0x0078, 0x27eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27e7,
-+	0x6f14, 0x1078, 0x37ef, 0x1078, 0x33d8, 0x0078, 0x27eb, 0x7060,
-+	0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085,
-+	0x0008, 0x6822, 0x1078, 0x1c70, 0x2021, 0x7500, 0x1078, 0x2830,
-+	0x2021, 0x515a, 0x1078, 0x2830, 0x157e, 0x20a9, 0x0000, 0x2021,
-+	0x7400, 0x1078, 0x2830, 0x8420, 0x0070, 0x2808, 0x0078, 0x2801,
-+	0x2061, 0x5400, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110,
-+	0x81ff, 0x0040, 0x2817, 0xa102, 0x0050, 0x2817, 0x6012, 0x601b,
-+	0x0000, 0xace0, 0x0010, 0x0070, 0x281f, 0x0078, 0x280e, 0x8421,
-+	0x00c0, 0x280c, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x282a,
-+	0x1078, 0x3a00, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2459,
-+	0x047e, 0x2404, 0xa005, 0x0040, 0x2844, 0x2068, 0x6800, 0x007e,
-+	0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078,
-+	0x1c70, 0x007f, 0x0078, 0x2832, 0x047f, 0x2023, 0x0000, 0x007c,
-+	0xa282, 0x0003, 0x0050, 0x284e, 0x1078, 0x23eb, 0x2300, 0x0079,
-+	0x2851, 0x2854, 0x28c7, 0x28e4, 0xa282, 0x0002, 0x0040, 0x285a,
-+	0x1078, 0x23eb, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079,
-+	0x2861, 0x2869, 0x2869, 0x286b, 0x289f, 0x340d, 0x2869, 0x289f,
-+	0x2869, 0x1078, 0x23eb, 0x7780, 0x1078, 0x36e2, 0x7780, 0xa7bc,
-+	0x0f00, 0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x2896, 0x2021,
-+	0x7500, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x0040,
-+	0x2896, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009,
-+	0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x047f, 0x0040, 0x2895,
-+	0x8420, 0x0070, 0x2895, 0x0078, 0x2886, 0x157f, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x2871, 0x0078, 0x2482, 0x0078, 0x2482, 0x7780,
-+	0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x28c5, 0x2021, 0x7500,
-+	0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x28ff, 0x0040, 0x28c5,
-+	0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009, 0x0005,
-+	0x2011, 0x0020, 0x1078, 0x28ff, 0x047f, 0x0040, 0x28c4, 0x8420,
-+	0x0070, 0x28c4, 0x0078, 0x28b5, 0x157f, 0x0078, 0x2482, 0x2200,
-+	0x0079, 0x28ca, 0x28cd, 0x28cf, 0x28cf, 0x1078, 0x23eb, 0x2009,
-+	0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x28d8, 0x2009, 0x000e,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x28de, 0x691a, 0x706f, 0x0000,
-+	0x7073, 0x0001, 0x0078, 0x3888, 0x2200, 0x0079, 0x28e7, 0x28ec,
-+	0x28cf, 0x28ea, 0x1078, 0x23eb, 0x1078, 0x4776, 0x7000, 0xa086,
-+	0x0001, 0x00c0, 0x339d, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef,
-+	0x600a, 0x1078, 0x3390, 0x0040, 0x339d, 0x0078, 0x2594, 0x2404,
-+	0xa005, 0x0040, 0x2922, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706,
-+	0x0040, 0x290e, 0x2d20, 0x007f, 0x0078, 0x2900, 0x007f, 0x2022,
-+	0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c70,
-+	0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
-+	0x33ee, 0x007c, 0xa085, 0x0001, 0x0078, 0x2921, 0x2300, 0x0079,
-+	0x2929, 0x292e, 0x292c, 0x29c7, 0x1078, 0x23eb, 0x78ec, 0xa084,
-+	0x0001, 0x00c0, 0x2942, 0x7000, 0xa086, 0x0004, 0x00c0, 0x293a,
-+	0x0078, 0x2965, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a,
-+	0x0078, 0x339d, 0x78e4, 0xa005, 0x00d0, 0x2965, 0x0018, 0x2459,
-+	0x2008, 0xa084, 0x0030, 0x00c0, 0x2951, 0x781b, 0x004f, 0x0078,
-+	0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x294d, 0x2100, 0xa084,
-+	0x0007, 0x0079, 0x295b, 0x299e, 0x29a9, 0x298f, 0x2963, 0x38ed,
-+	0x38ed, 0x2963, 0x29b8, 0x1078, 0x23eb, 0x7000, 0xa086, 0x0004,
-+	0x00c0, 0x297f, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2975, 0x2011,
-+	0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006,
-+	0x0040, 0x296f, 0x706c, 0xa086, 0x0004, 0x0040, 0x296f, 0x79e4,
-+	0xa184, 0x0030, 0x0040, 0x2989, 0x78ec, 0xa084, 0x0003, 0x00c0,
-+	0x298b, 0x0078, 0x2f6d, 0x2001, 0x0003, 0x0078, 0x2d01, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2996, 0x681b, 0x001d, 0x1078, 0x36c1,
-+	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x29a5, 0x681b, 0x001d, 0x1078, 0x36c1, 0x0078,
-+	0x38b8, 0x6818, 0xa084, 0x8000, 0x0040, 0x29b0, 0x681b, 0x001d,
-+	0x1078, 0x36c1, 0x782b, 0x3008, 0x781b, 0x00cd, 0x0078, 0x2459,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x29bf, 0x681b, 0x001d, 0x1078,
-+	0x36c1, 0x782b, 0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0xa584,
-+	0x000f, 0x00c0, 0x29e4, 0x7000, 0x0079, 0x29ce, 0x2482, 0x29d8,
-+	0x29d6, 0x339d, 0x339d, 0x339d, 0x339d, 0x29d6, 0x1078, 0x23eb,
-+	0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3390,
-+	0x0040, 0x339d, 0x0078, 0x2594, 0x78e4, 0xa005, 0x00d0, 0x2965,
-+	0x0018, 0x2965, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f3, 0x781b,
-+	0x004f, 0x0078, 0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ef,
-+	0x2100, 0xa184, 0x0007, 0x0079, 0x29fd, 0x2a0f, 0x2a13, 0x2a07,
-+	0x2a05, 0x38ed, 0x38ed, 0x2a05, 0x38e3, 0x1078, 0x23eb, 0x1078,
-+	0x36c9, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x1078,
-+	0x36c9, 0x0078, 0x38b8, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b,
-+	0x00cd, 0x0078, 0x2459, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b,
-+	0x008e, 0x0078, 0x2459, 0x2300, 0x0079, 0x2a26, 0x2a2b, 0x2a29,
-+	0x2a2d, 0x1078, 0x23eb, 0x0078, 0x30ab, 0x681b, 0x0008, 0x78a3,
-+	0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30ab, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x30ab, 0xa184, 0x0007, 0x0079, 0x2a3f, 0x2a47,
-+	0x2a13, 0x298f, 0x3888, 0x38ed, 0x38ed, 0x2a47, 0x38e3, 0x1078,
-+	0x389c, 0x0078, 0x2459, 0xa282, 0x0005, 0x0050, 0x2a51, 0x1078,
-+	0x23eb, 0x2300, 0x0079, 0x2a54, 0x2a57, 0x2cae, 0x2cbc, 0x2200,
-+	0x0079, 0x2a5a, 0x2a74, 0x2a61, 0x2a74, 0x2a5f, 0x2c93, 0x1078,
-+	0x23eb, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020,
-+	0x0048, 0x369d, 0xa08a, 0x0004, 0x00c8, 0x369d, 0x0079, 0x2a70,
-+	0x369d, 0x369d, 0x369d, 0x364b, 0x789b, 0x0018, 0x79a8, 0xa184,
-+	0x0080, 0x0040, 0x2a85, 0x0078, 0x369d, 0x7000, 0xa005, 0x00c0,
-+	0x2a7b, 0x2011, 0x0004, 0x0078, 0x321f, 0xa184, 0x00ff, 0xa08a,
-+	0x0010, 0x00c8, 0x369d, 0x0079, 0x2a8d, 0x2a9f, 0x2a9d, 0x2ab7,
-+	0x2abb, 0x2b78, 0x369d, 0x369d, 0x2b7a, 0x369d, 0x369d, 0x2c8f,
-+	0x2c8f, 0x369d, 0x369d, 0x369d, 0x2c91, 0x1078, 0x23eb, 0xa684,
-+	0x1000, 0x0040, 0x2aac, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a,
-+	0x781b, 0x008c, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000, 0x0040,
-+	0x2ab5, 0x681b, 0x001d, 0x0078, 0x2aa3, 0x0078, 0x3888, 0x681b,
-+	0x001d, 0x0078, 0x36ad, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0,
-+	0x2afc, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2b04, 0x6818, 0xa086,
-+	0x0008, 0x00c0, 0x2acd, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040,
-+	0x2b74, 0xa684, 0x0080, 0x0040, 0x2af8, 0x7097, 0x0000, 0x6818,
-+	0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2af8, 0xa08a, 0x000c,
-+	0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061, 0x78aa,
-+	0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
-+	0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
-+	0x781b, 0x0058, 0x0078, 0x2459, 0xa684, 0x1000, 0x0040, 0x2b04,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0xa684, 0x0060, 0x0040, 0x2b70,
-+	0xa684, 0x0800, 0x0040, 0x2b70, 0xa684, 0x8000, 0x00c0, 0x2b12,
-+	0x0078, 0x2b2c, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076,
-+	0x7aac, 0x79ac, 0x78ac, 0x801b, 0x00c8, 0x2b1f, 0x8000, 0xa084,
-+	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-+	0x6b94, 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2b34,
-+	0xa6b4, 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0,
-+	0x2b41, 0x1078, 0x482c, 0x1078, 0x4a29, 0x781b, 0x0064, 0x0078,
-+	0x2459, 0xa006, 0x1078, 0x4b30, 0x6ab0, 0x69ac, 0x6c98, 0x6b94,
-+	0x2200, 0xa105, 0x0040, 0x2b50, 0x2200, 0xa422, 0x2100, 0xa31b,
-+	0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405,
-+	0x00c0, 0x2b62, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064,
-+	0x0078, 0x2459, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2b6c,
-+	0x1078, 0x4a3a, 0x0078, 0x2459, 0x1078, 0x4a85, 0x0078, 0x2459,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459,
-+	0x1078, 0x23eb, 0x0078, 0x2bdb, 0x6920, 0xa184, 0x0100, 0x0040,
-+	0x2b92, 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000,
-+	0xa084, 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f,
-+	0x0078, 0x2bca, 0xa184, 0x0200, 0x0040, 0x2bca, 0xa18c, 0xfdff,
-+	0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002,
-+	0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184,
-+	0x0008, 0x0040, 0x2bca, 0x1078, 0x37eb, 0x1078, 0x34f1, 0x88ff,
-+	0x0040, 0x2bca, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5,
-+	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2bc4, 0x782b, 0x3008,
-+	0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065,
-+	0x0078, 0x2459, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2bd3, 0x781b,
-+	0x0058, 0x0078, 0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x0078,
-+	0x36a5, 0x0078, 0x36a5, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007,
-+	0x00c0, 0x2be9, 0x6820, 0xa084, 0x0100, 0x0040, 0x2bd9, 0x2009,
-+	0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
-+	0x00c0, 0x2c20, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
-+	0x2c18, 0x0048, 0x2bfd, 0x0078, 0x2c1a, 0xa380, 0x0002, 0xa102,
-+	0x00c8, 0x2c18, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054,
-+	0x2060, 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5,
-+	0x6006, 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2bcb,
-+	0x0078, 0x2b7c, 0x24a8, 0x7aa8, 0x00f0, 0x2c1a, 0x0078, 0x2beb,
-+	0xa284, 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2c80, 0x8318, 0x8318,
-+	0x2300, 0xa102, 0x0040, 0x2c30, 0x0048, 0x2c30, 0x0078, 0x2c7d,
-+	0xa286, 0x0023, 0x0040, 0x2bd9, 0x681c, 0xa084, 0xfff1, 0x681e,
-+	0x7e58, 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008,
-+	0xa085, 0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
-+	0x2c48, 0x0c7f, 0xa184, 0x0010, 0x0040, 0x2c54, 0x1078, 0x37eb,
-+	0x1078, 0x3604, 0x0078, 0x2c63, 0x0c7e, 0x7054, 0x2060, 0x6004,
-+	0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2bca, 0x1078,
-+	0x37eb, 0x1078, 0x34f1, 0x88ff, 0x0040, 0x2bca, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-+	0x2c77, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7aa8, 0x0078, 0x2beb,
-+	0x8318, 0x2300, 0xa102, 0x0040, 0x2c89, 0x0048, 0x2c89, 0x0078,
-+	0x2beb, 0xa284, 0x0080, 0x00c0, 0x36ad, 0x0078, 0x36a5, 0x0078,
-+	0x36ad, 0x0078, 0x369d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
-+	0xa08e, 0x0001, 0x0040, 0x2c9e, 0x1078, 0x23eb, 0x7aa8, 0xa294,
-+	0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x369d,
-+	0x0079, 0x2caa, 0x369d, 0x343e, 0x369d, 0x3599, 0xa282, 0x0000,
-+	0x00c0, 0x2cb4, 0x1078, 0x23eb, 0x1078, 0x36c1, 0x782b, 0x3008,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0003, 0x00c0, 0x2cc2,
-+	0x1078, 0x23eb, 0xa484, 0x8000, 0x00c0, 0x2ce5, 0x706c, 0xa005,
-+	0x0040, 0x2ccc, 0x1078, 0x23eb, 0x6f14, 0x7782, 0xa7bc, 0x0f00,
-+	0x1078, 0x37ef, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x2cd0, 0x1078, 0x36c5, 0x706f, 0x0002, 0x2009,
-+	0x5138, 0x200b, 0x0009, 0x0078, 0x2ce7, 0x1078, 0x36d1, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0004, 0x0050,
-+	0x2cf3, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2cf6, 0x2cf9, 0x2de2,
-+	0x2e15, 0xa286, 0x0003, 0x0040, 0x2cff, 0x1078, 0x23eb, 0x2001,
-+	0x0000, 0x007e, 0x68c0, 0xa005, 0x0040, 0x2d08, 0x7003, 0x0003,
-+	0x68a0, 0xa084, 0x2000, 0x0040, 0x2d11, 0x6008, 0xa085, 0x0002,
-+	0x600a, 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2d18,
-+	0x2482, 0x2d22, 0x2d22, 0x2f17, 0x2f53, 0x2482, 0x2f53, 0x2d20,
-+	0x1078, 0x23eb, 0xa684, 0x1000, 0x00c0, 0x2d2a, 0x1078, 0x4776,
-+	0x0040, 0x2dbc, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d72, 0xa186,
-+	0x0008, 0x00c0, 0x2d41, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef,
-+	0x600a, 0x1078, 0x3390, 0x0040, 0x2d72, 0x1078, 0x4776, 0x0078,
-+	0x2d59, 0xa186, 0x0028, 0x00c0, 0x2d72, 0x1078, 0x4776, 0x6008,
-+	0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2d59, 0x8001,
-+	0x601a, 0xa005, 0x0040, 0x2d59, 0x8001, 0xa005, 0x0040, 0x2d59,
-+	0x601e, 0x6820, 0xa084, 0x0001, 0x0040, 0x2482, 0x6820, 0xa084,
-+	0xfffe, 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f,
-+	0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2d6f, 0x6002, 0x6006,
-+	0x0078, 0x2482, 0x017e, 0x1078, 0x2e46, 0x017f, 0xa684, 0xdf00,
-+	0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2dbc, 0xa186,
-+	0x0002, 0x00c0, 0x2dbc, 0xa684, 0x0800, 0x00c0, 0x2d8f, 0xa684,
-+	0x0060, 0x0040, 0x2d8f, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820,
-+	0xa084, 0x0800, 0x00c0, 0x2dbc, 0x8717, 0xa294, 0x000f, 0x8213,
-+	0x8213, 0x8213, 0xa290, 0x5380, 0xa290, 0x0000, 0x221c, 0xa384,
-+	0x0100, 0x00c0, 0x2da5, 0x0078, 0x2dab, 0x8210, 0x2204, 0xa085,
-+	0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2db8, 0x68a0,
-+	0xa084, 0x0100, 0x00c0, 0x2db8, 0x1078, 0x2eca, 0x0078, 0x2482,
-+	0x6008, 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x2dc4, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078,
-+	0x33df, 0x1078, 0x33ee, 0x00c0, 0x2dd1, 0x6008, 0xa084, 0xffef,
-+	0x600a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2dda, 0x1078, 0x33d8,
-+	0x0078, 0x2dde, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c70,
-+	0x0078, 0x2482, 0xa282, 0x0004, 0x0048, 0x2de8, 0x1078, 0x23eb,
-+	0x2200, 0x0079, 0x2deb, 0x2de6, 0x2def, 0x2dfc, 0x2def, 0x7000,
-+	0xa086, 0x0005, 0x0040, 0x2df8, 0x1078, 0x36c1, 0x782b, 0x3008,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0x7890, 0x8007, 0x8001, 0xa084,
-+	0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186,
-+	0x0003, 0x0040, 0x2e11, 0xa186, 0x0000, 0x0040, 0x2e11, 0x0078,
-+	0x369d, 0x781b, 0x0065, 0x0078, 0x2459, 0x6820, 0xa085, 0x0004,
-+	0x6822, 0x82ff, 0x00c0, 0x2e20, 0x1078, 0x36c1, 0x0078, 0x2e27,
-+	0x8211, 0x0040, 0x2e25, 0x1078, 0x23eb, 0x1078, 0x36d1, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x702c, 0x8003, 0x0048,
-+	0x2e37, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x1078,
-+	0x3912, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2e43, 0x0018, 0x2e43,
-+	0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060,
-+	0x00c0, 0x2e50, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2ec9,
-+	0xa684, 0x0800, 0x00c0, 0x2e72, 0x68b4, 0xa084, 0x4800, 0xa635,
-+	0xa684, 0x0800, 0x00c0, 0x2e72, 0x6998, 0x6a94, 0x692e, 0x6a32,
-+	0x703c, 0xa005, 0x00c0, 0x2e6a, 0x2200, 0xa105, 0x0040, 0x2e71,
-+	0x703f, 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2e71, 0x1078,
-+	0x4776, 0x007c, 0xa684, 0x0020, 0x0040, 0x2e94, 0xa684, 0x4000,
-+	0x0040, 0x2e80, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a,
-+	0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e7a,
-+	0x703c, 0xa005, 0x00c0, 0x2e8e, 0x703f, 0x0015, 0x79d8, 0x7adc,
-+	0x692e, 0x6a32, 0x0078, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e9e,
-+	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a, 0x68b4, 0xa084,
-+	0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e98, 0x703c, 0xa005,
-+	0x00c0, 0x2eac, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb,
-+	0x00c8, 0x2eb3, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2ec0, 0x0078, 0x2e6a,
-+	0x7000, 0xa086, 0x0006, 0x0040, 0x2ec9, 0x1078, 0x4b30, 0x0078,
-+	0x2e6a, 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200,
-+	0x0040, 0x2ed6, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006,
-+	0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942,
-+	0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000,
-+	0x689b, 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079,
-+	0x2ef1, 0x2482, 0x2efb, 0x2f04, 0x2ef9, 0x2ef9, 0x2ef9, 0x2ef9,
-+	0x2ef9, 0x1078, 0x23eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2f04,
-+	0x1078, 0x33d8, 0x0078, 0x2f0a, 0x7060, 0x2c50, 0x2060, 0x6800,
-+	0x6002, 0x2a60, 0x2021, 0x515a, 0x2404, 0xa005, 0x0040, 0x2f13,
-+	0x2020, 0x0078, 0x2f0c, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078,
-+	0x33df, 0x1078, 0x33ee, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b,
-+	0x0000, 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4b78,
-+	0xa684, 0x0800, 0x0040, 0x2f30, 0x691c, 0xa18d, 0x2000, 0x691e,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x2f40, 0x7868, 0xa08c, 0x00ff,
-+	0x0040, 0x2f3e, 0x681b, 0x001e, 0x0078, 0x2f40, 0x681b, 0x0000,
-+	0x2021, 0x515a, 0x2404, 0xad06, 0x0040, 0x2f47, 0x7460, 0x6800,
-+	0x2022, 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078,
-+	0x1c70, 0x0078, 0x2482, 0x1078, 0x2e46, 0x682b, 0x0000, 0x2001,
-+	0x000e, 0x6f14, 0x1078, 0x3918, 0xa08c, 0x00ff, 0x6916, 0x6818,
-+	0xa084, 0x8000, 0x0040, 0x2f66, 0x703c, 0x681a, 0xa68c, 0xdf00,
-+	0x691e, 0x706f, 0x0000, 0x0078, 0x2482, 0x7000, 0xa005, 0x00c0,
-+	0x2f73, 0x0078, 0x2482, 0xa006, 0x1078, 0x4776, 0x6817, 0x0000,
-+	0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
-+	0xa085, 0x00ff, 0x6822, 0x7000, 0x0079, 0x2f86, 0x2482, 0x2f90,
-+	0x2f90, 0x2f92, 0x2f92, 0x2f92, 0x2f92, 0x2f8e, 0x1078, 0x23eb,
-+	0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x33a8,
-+	0x2300, 0x0079, 0x2f9b, 0x2f9e, 0x2fa0, 0x2fd9, 0x1078, 0x23eb,
-+	0x7000, 0x0079, 0x2fa3, 0x2482, 0x2fad, 0x2fad, 0x2fc8, 0x2fad,
-+	0x2fd5, 0x2fc8, 0x2fab, 0x1078, 0x23eb, 0xa684, 0x0060, 0xa086,
-+	0x0060, 0x00c0, 0x2fc4, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5,
-+	0x2000, 0x7e5a, 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4776,
-+	0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684, 0x2000, 0x0040, 0x2fb7,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x2fd5, 0x681b, 0x0015, 0xa684,
-+	0x4000, 0x0040, 0x2fd5, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078,
-+	0x2459, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2fde, 0x2fe1, 0x2fe3,
-+	0x3016, 0x1078, 0x23eb, 0x7000, 0x0079, 0x2fe6, 0x2482, 0x2ff0,
-+	0x2ff0, 0x300b, 0x2ff0, 0x3012, 0x300b, 0x2fee, 0x1078, 0x23eb,
-+	0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3007, 0xa6b4, 0xffbf,
-+	0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf,
-+	0x681e, 0x1078, 0x4776, 0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684,
-+	0x2000, 0x0040, 0x2ffa, 0x6818, 0xa084, 0x8000, 0x0040, 0x3012,
-+	0x681b, 0x0007, 0x781b, 0x00cd, 0x0078, 0x2459, 0x6820, 0xa085,
-+	0x0004, 0x6822, 0x1078, 0x3853, 0xa6b5, 0x0800, 0x1078, 0x36c1,
-+	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x2300, 0x0079,
-+	0x3029, 0x302c, 0x302e, 0x3030, 0x1078, 0x23eb, 0x0078, 0x36ad,
-+	0xa684, 0x0400, 0x00c0, 0x3059, 0x79e4, 0xa184, 0x0020, 0x0040,
-+	0x3040, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3040, 0x782b, 0x3009,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4,
-+	0xa184, 0x0020, 0x0040, 0x3051, 0x78ec, 0xa084, 0x0003, 0x00c0,
-+	0x3055, 0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079,
-+	0x3091, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff,
-+	0x0040, 0x308f, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0,
-+	0x3080, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3073, 0x2009,
-+	0xfff7, 0x0078, 0x3079, 0xa386, 0x0003, 0x00c0, 0x3080, 0x2009,
-+	0xffef, 0x0c7e, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b,
-+	0x3009, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
-+	0x3888, 0x299e, 0x29a9, 0x309b, 0x30a3, 0x3099, 0x3099, 0x3888,
-+	0x3888, 0x1078, 0x23eb, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x6922, 0x0078, 0x3892, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-+	0x6922, 0x0078, 0x3888, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30b5,
-+	0x78ec, 0xa084, 0x0003, 0x00c0, 0x30dc, 0x7000, 0xa086, 0x0004,
-+	0x00c0, 0x30cf, 0x706c, 0xa086, 0x0002, 0x00c0, 0x30c5, 0x2011,
-+	0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006,
-+	0x0040, 0x30bf, 0x706c, 0xa086, 0x0004, 0x0040, 0x30bf, 0x7000,
-+	0xa086, 0x0000, 0x0040, 0x2459, 0x6818, 0xa085, 0x8000, 0x681a,
-+	0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079, 0x30e0,
-+	0x3888, 0x3888, 0x30e8, 0x3888, 0x38ed, 0x38ed, 0x3888, 0x3888,
-+	0xa684, 0x0080, 0x0040, 0x3117, 0x7194, 0x81ff, 0x0040, 0x3117,
-+	0xa182, 0x000d, 0x00d0, 0x30f8, 0x7097, 0x0000, 0x0078, 0x30fd,
-+	0xa182, 0x000c, 0x7096, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa,
-+	0x157e, 0x137e, 0x147e, 0x7098, 0x8114, 0xa210, 0x729a, 0xa080,
-+	0x000b, 0xad00, 0x2098, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108,
-+	0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x3892, 0xa684,
-+	0x0400, 0x00c0, 0x3158, 0x6820, 0xa084, 0x0001, 0x0040, 0x3892,
-+	0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x312c, 0xa086, 0x0060,
-+	0x00c0, 0x312c, 0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085,
-+	0x8000, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3407, 0xa18c,
-+	0x00f8, 0x00c0, 0x3407, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b,
-+	0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
-+	0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x3892,
-+	0x6818, 0xa084, 0x8000, 0x0040, 0x315f, 0x681b, 0x0008, 0x781b,
-+	0x00c3, 0x0078, 0x2459, 0x2300, 0x0079, 0x3166, 0x316b, 0x320a,
-+	0x3169, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x0079, 0x3170,
-+	0x2482, 0x317a, 0x31af, 0x3185, 0x3178, 0x2482, 0x3178, 0x3178,
-+	0x1078, 0x23eb, 0x681c, 0xa084, 0x2000, 0x0040, 0x3193, 0x6008,
-+	0xa085, 0x0002, 0x600a, 0x0078, 0x3193, 0x68c0, 0xa005, 0x00c0,
-+	0x31af, 0x6920, 0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800,
-+	0x706a, 0x0078, 0x31a9, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800,
-+	0x6006, 0xa005, 0x00c0, 0x319d, 0x6002, 0x681c, 0xa084, 0x000e,
-+	0x0040, 0x31a9, 0x7014, 0x68ba, 0x7130, 0xa188, 0x7400, 0x0078,
-+	0x31ab, 0x2009, 0x7500, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6,
-+	0xa684, 0x0060, 0x0040, 0x3208, 0xa684, 0x0800, 0x00c0, 0x31c3,
-+	0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078,
-+	0x4776, 0x0078, 0x3208, 0xa684, 0x0020, 0x0040, 0x31d8, 0x68c0,
-+	0xa005, 0x0040, 0x31cf, 0x1078, 0x4b78, 0x0078, 0x31d2, 0xa006,
-+	0x1078, 0x4b30, 0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31de,
-+	0x1078, 0x37fc, 0x69aa, 0x6aa6, 0x1078, 0x4b30, 0xa684, 0x8000,
-+	0x0040, 0x3208, 0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078,
-+	0x3918, 0x2010, 0x2001, 0x0078, 0x1078, 0x3918, 0x2008, 0xa684,
-+	0x0020, 0x00c0, 0x3200, 0x2001, 0x007a, 0x1078, 0x3918, 0x801b,
-+	0x00c8, 0x31fb, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
-+	0x0078, 0x2482, 0x0078, 0x36ad, 0x7037, 0x0000, 0xa282, 0x0006,
-+	0x0050, 0x3214, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x10c0,
-+	0x39be, 0x2300, 0x0079, 0x321c, 0x321f, 0x3248, 0x325c, 0x2200,
-+	0x0079, 0x3222, 0x3246, 0x36ad, 0x3228, 0x3246, 0x3278, 0x32ba,
-+	0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e, 0x20a9,
-+	0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3238, 0x0078, 0x3231,
-+	0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700,
-+	0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x369d, 0x1078, 0x23eb,
-+	0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0xad80, 0x0009,
-+	0x7036, 0x2200, 0x0079, 0x3254, 0x36ad, 0x325a, 0x325a, 0x3278,
-+	0x325a, 0x36ad, 0x1078, 0x23eb, 0x7003, 0x0005, 0x2001, 0x7610,
-+	0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x3268,
-+	0x3270, 0x326e, 0x326e, 0x3270, 0x326e, 0x3270, 0x1078, 0x23eb,
-+	0x1078, 0x36d1, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459,
-+	0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-+	0xa484, 0x001f, 0xa215, 0x2069, 0x7500, 0x2d04, 0x2d08, 0x7162,
-+	0x2068, 0xa005, 0x0040, 0x3293, 0x6814, 0xa206, 0x0040, 0x32af,
-+	0x6800, 0x0078, 0x3286, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068,
-+	0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000,
-+	0x0070, 0x32a4, 0x0078, 0x329d, 0x157f, 0xad80, 0x0009, 0x7036,
-+	0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4,
-+	0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3309, 0x1078, 0x36c9,
-+	0x0078, 0x3309, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
-+	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c,
-+	0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005,
-+	0x0040, 0x32d9, 0x6814, 0xa206, 0x0040, 0x32f4, 0x6800, 0x0078,
-+	0x32cc, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e,
-+	0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x32e9, 0x0078,
-+	0x32e2, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700,
-+	0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084,
-+	0x0c00, 0x0040, 0x3309, 0xa084, 0x0800, 0x0040, 0x3303, 0x1078,
-+	0x36cd, 0x0078, 0x3309, 0x1078, 0x36c9, 0x708b, 0x0000, 0x0078,
-+	0x3309, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa080, 0x5380, 0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e,
-+	0xa684, 0x0060, 0x0040, 0x3361, 0x6b98, 0x6c94, 0x69ac, 0x68b0,
-+	0xa105, 0x00c0, 0x3343, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4,
-+	0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3361,
-+	0x68c0, 0xa005, 0x0040, 0x333c, 0x7003, 0x0003, 0x682b, 0x0000,
-+	0x1078, 0x4a29, 0x0078, 0x333e, 0x1078, 0x4a3a, 0xa6b5, 0x2000,
-+	0x7e5a, 0x0078, 0x3361, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400,
-+	0xa305, 0x0040, 0x3361, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0,
-+	0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040,
-+	0x335f, 0x7003, 0x0003, 0x1078, 0x4a29, 0x0078, 0x3361, 0x1078,
-+	0x4a85, 0x077f, 0x1078, 0x37ef, 0x2009, 0x0065, 0xa684, 0x0004,
-+	0x0040, 0x3382, 0x78e4, 0xa084, 0x0030, 0x0040, 0x337a, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x337a, 0x782b, 0x3008, 0x2009, 0x0065,
-+	0x0078, 0x3382, 0x0f7e, 0x2079, 0x5100, 0x1078, 0x4776, 0x0f7f,
-+	0x0040, 0x2482, 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2048, 0x0078, 0x2459,
-+	0x6020, 0xa005, 0x0040, 0x339c, 0x8001, 0x6022, 0x6008, 0xa085,
-+	0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4776,
-+	0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100,
-+	0x7000, 0xa084, 0x0007, 0x0079, 0x33ad, 0x2482, 0x33b7, 0x33b7,
-+	0x33d4, 0x33bf, 0x33bd, 0x33bf, 0x33b5, 0x1078, 0x23eb, 0x1078,
-+	0x33df, 0x1078, 0x33d8, 0x1078, 0x1c70, 0x0078, 0x2482, 0x706c,
-+	0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x33c6, 0x33d0, 0x33d0,
-+	0x33ce, 0x33ce, 0x33ce, 0x33d0, 0x33ce, 0x33d0, 0x0079, 0x2861,
-+	0x706f, 0x0000, 0x0078, 0x2482, 0x681b, 0x0000, 0x0078, 0x2f17,
-+	0x6800, 0xa005, 0x00c0, 0x33dd, 0x6002, 0x6006, 0x007c, 0x6010,
-+	0xa005, 0x0040, 0x33e8, 0x8001, 0x00d0, 0x33e8, 0x1078, 0x23eb,
-+	0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005,
-+	0x0040, 0x33f4, 0x8001, 0x601a, 0x007c, 0x1078, 0x3912, 0x681b,
-+	0x0018, 0x0078, 0x342b, 0x1078, 0x3912, 0x681b, 0x0019, 0x0078,
-+	0x342b, 0x1078, 0x3912, 0x681b, 0x001a, 0x0078, 0x342b, 0x1078,
-+	0x3912, 0x681b, 0x0003, 0x0078, 0x342b, 0x7780, 0x1078, 0x37ef,
-+	0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x2068,
-+	0xa005, 0x00c0, 0x341d, 0x0078, 0x2482, 0x6814, 0x7280, 0xa206,
-+	0x0040, 0x3425, 0x6800, 0x0078, 0x3416, 0x6800, 0x200a, 0x681b,
-+	0x0005, 0x708b, 0x0000, 0x1078, 0x33df, 0x6820, 0xa084, 0x0001,
-+	0x00c0, 0x3434, 0x1078, 0x33d8, 0x1078, 0x33ee, 0x681f, 0x0000,
-+	0x6823, 0x0020, 0x1078, 0x1c70, 0x0078, 0x2482, 0xa282, 0x0003,
-+	0x00c0, 0x369d, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff,
-+	0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x34a2,
-+	0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x348c, 0xa482,
-+	0x000c, 0x0048, 0x345f, 0x0040, 0x345f, 0x2021, 0x000c, 0x852b,
-+	0x852b, 0x1078, 0x3760, 0x0040, 0x3469, 0x1078, 0x355b, 0x0078,
-+	0x3495, 0x1078, 0x371b, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
-+	0x6006, 0x1078, 0x3586, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922,
-+	0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x3486,
-+	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x2960, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x1078, 0x3586, 0x0c7f, 0x7e58, 0xa684, 0x0400,
-+	0x00c0, 0x349e, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065,
-+	0x0078, 0x2459, 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000,
-+	0x0040, 0x34e2, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c,
-+	0x0048, 0x34b6, 0x0040, 0x34b6, 0x2011, 0x000c, 0x2400, 0xa202,
-+	0x00c8, 0x34bb, 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086,
-+	0x0028, 0x00c0, 0x34cb, 0xa282, 0x0019, 0x00c8, 0x34d1, 0x2011,
-+	0x0019, 0x0078, 0x34d1, 0xa282, 0x000c, 0x00c8, 0x34d1, 0x2011,
-+	0x000c, 0x2200, 0xa502, 0x00c8, 0x34d6, 0x2228, 0x1078, 0x371f,
-+	0x852b, 0x852b, 0x1078, 0x3760, 0x0040, 0x34e2, 0x1078, 0x355b,
-+	0x0078, 0x34e6, 0x1078, 0x371b, 0x1078, 0x3586, 0x7858, 0xa085,
-+	0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
-+	0x2459, 0x0c7e, 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x3509,
-+	0x6010, 0xa084, 0x000f, 0x00c0, 0x3503, 0x6104, 0xa18c, 0xfff5,
-+	0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
-+	0x3530, 0x68a0, 0xa084, 0x0200, 0x00c0, 0x3503, 0x6208, 0xa294,
-+	0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x351e, 0xa282, 0x0019,
-+	0x00c8, 0x3524, 0x2011, 0x0019, 0x0078, 0x3524, 0xa282, 0x000c,
-+	0x00c8, 0x3524, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff,
-+	0xa382, 0x000c, 0x0048, 0x3530, 0x0040, 0x3530, 0x2019, 0x000c,
-+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
-+	0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c,
-+	0x0c7e, 0x2960, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019,
-+	0x0000, 0x0078, 0x354b, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100,
-+	0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3562,
-+	0x0c7f, 0x007c, 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018,
-+	0x789a, 0x7cae, 0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007,
-+	0xa105, 0x78a6, 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204,
-+	0x8004, 0xa084, 0x00ff, 0xa405, 0x600e, 0x78ec, 0xd08c, 0x00c0,
-+	0x3585, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c, 0x0c7e, 0x7054,
-+	0x2060, 0x1078, 0x358d, 0x0c7f, 0x007c, 0x6018, 0x789a, 0x78a4,
-+	0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
-+	0x007c, 0xa282, 0x0002, 0x00c0, 0x369d, 0x7aa8, 0x6920, 0xa18d,
-+	0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35e2, 0xa18c, 0xfdff,
-+	0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, 0x369d, 0x1078,
-+	0x362b, 0x1078, 0x3586, 0xa980, 0x0001, 0x200c, 0x1078, 0x37eb,
-+	0x1078, 0x34f1, 0x88ff, 0x0040, 0x35d5, 0x789b, 0x0060, 0x2800,
-+	0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-+	0x35cf, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7e58, 0xa684, 0x0400,
-+	0x00c0, 0x35de, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065,
-+	0x0078, 0x2459, 0xa282, 0x0002, 0x00c8, 0x35ea, 0xa284, 0x0001,
-+	0x0040, 0x35f4, 0x7154, 0xa188, 0x0000, 0x210c, 0xa18c, 0x2000,
-+	0x00c0, 0x35f4, 0x2011, 0x0000, 0x1078, 0x370d, 0x1078, 0x362b,
-+	0x1078, 0x3586, 0x7858, 0xa085, 0x0004, 0x785a, 0x782b, 0x3008,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x027e, 0x2960, 0x6000,
-+	0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x361b, 0x6014, 0xa084,
-+	0x0040, 0x00c0, 0x3619, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078,
-+	0x3628, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822,
-+	0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3632,
-+	0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3637, 0x2011, 0x0040, 0x6018,
-+	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6,
-+	0x788a, 0x6016, 0x78ec, 0xd08c, 0x00c0, 0x364a, 0x6004, 0xa084,
-+	0xffef, 0x6006, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040,
-+	0x3654, 0x007f, 0x0078, 0x3657, 0x007f, 0x0078, 0x3699, 0xa684,
-+	0x0020, 0x0040, 0x3699, 0x7888, 0xa084, 0x0040, 0x0040, 0x3699,
-+	0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x3667, 0x8000, 0xa005,
-+	0x0040, 0x367d, 0x831b, 0x00c8, 0x3670, 0x8001, 0x0040, 0x3695,
-+	0xa684, 0x4000, 0x0040, 0x367d, 0x78b8, 0x801b, 0x00c8, 0x3679,
-+	0x8000, 0xa084, 0x003f, 0x00c0, 0x3695, 0xa6b4, 0xbfff, 0x7e5a,
-+	0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3689, 0xa291,
-+	0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4b30, 0x781b,
-+	0x0064, 0x1078, 0x49b5, 0x0078, 0x2459, 0x781b, 0x0064, 0x0078,
-+	0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36d5, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36c1, 0x782b,
-+	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x6827, 0x0002, 0x1078,
-+	0x36c9, 0x78e4, 0xa084, 0x0030, 0x0040, 0x2482, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x2482, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
-+	0x2459, 0x2001, 0x0005, 0x0078, 0x36d7, 0x2001, 0x000c, 0x0078,
-+	0x36d7, 0x2001, 0x0006, 0x0078, 0x36d7, 0x2001, 0x000d, 0x0078,
-+	0x36d7, 0x2001, 0x0009, 0x0078, 0x36d7, 0x2001, 0x0007, 0x789b,
-+	0x0010, 0x78aa, 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004,
-+	0x7e5a, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b,
-+	0x8703, 0xa0e0, 0x5380, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
-+	0x000f, 0x0040, 0x36fb, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
-+	0xa085, 0x0008, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184,
-+	0x0040, 0x0040, 0x370b, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004,
-+	0xa085, 0x0010, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab,
-+	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060,
-+	0x78ab, 0x0004, 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b,
-+	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-+	0x7caa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007,
-+	0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
-+	0xa18c, 0xfff0, 0x2001, 0x5146, 0x2004, 0xa082, 0x0028, 0x0040,
-+	0x3749, 0x2021, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078,
-+	0x374f, 0x2021, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011,
-+	0x0064, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, 0x375e, 0x8420,
-+	0x2300, 0xa210, 0x0070, 0x375e, 0x0078, 0x3751, 0x157f, 0x007c,
-+	0x157e, 0x2009, 0x5146, 0x210c, 0xa182, 0x0032, 0x0048, 0x3774,
-+	0x0040, 0x3778, 0x2009, 0x37c4, 0x2019, 0x0011, 0x20a9, 0x000e,
-+	0x2011, 0x0032, 0x0078, 0x378a, 0xa182, 0x0028, 0x0040, 0x3782,
-+	0x2009, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064,
-+	0x0078, 0x378a, 0x2009, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d,
-+	0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x379a, 0x0048, 0x379a,
-+	0x8108, 0x2300, 0xa210, 0x0070, 0x3797, 0x0078, 0x378a, 0x157f,
-+	0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x37a9, 0x7808,
-+	0xa085, 0x0070, 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078,
-+	0x37a9, 0x78ec, 0xa084, 0x0300, 0x0040, 0x37b1, 0x2104, 0x0078,
-+	0x37c2, 0x2104, 0xa09e, 0x1102, 0x00c0, 0x37c2, 0x2001, 0x04fd,
-+	0x2004, 0xa082, 0x0005, 0x0048, 0x37c1, 0x2001, 0x1201, 0x0078,
-+	0x37c2, 0x2104, 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203,
-+	0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07,
-+	0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605,
-+	0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202,
-+	0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04,
-+	0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784,
-+	0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003,
-+	0xa105, 0xa0e0, 0x5400, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b,
-+	0x00c8, 0x3803, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x5140, 0x2091, 0x8000,
-+	0x2104, 0x0079, 0x3813, 0x3849, 0x381d, 0x381d, 0x381d, 0x381d,
-+	0x381d, 0x381d, 0x384d, 0x1078, 0x23eb, 0x784b, 0x0004, 0x7848,
-+	0xa084, 0x0004, 0x00c0, 0x381f, 0x784b, 0x0008, 0x7848, 0xa084,
-+	0x0008, 0x00c0, 0x3826, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858,
-+	0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3849,
-+	0x0018, 0x3849, 0x681c, 0xa084, 0x0020, 0x00c0, 0x3847, 0x0e7e,
-+	0x2071, 0x5140, 0x1078, 0x389c, 0x0e7f, 0x0078, 0x3849, 0x781b,
-+	0x00cd, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078,
-+	0x3a76, 0x0078, 0x3849, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa0e0, 0x5380, 0x6004, 0xa084, 0x000a,
-+	0x00c0, 0x3886, 0x6108, 0xa194, 0xff00, 0x0040, 0x3886, 0xa18c,
-+	0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x3875, 0x2001, 0x0032,
-+	0xa106, 0x0040, 0x3879, 0x0078, 0x387d, 0x2009, 0x0020, 0x0078,
-+	0x387f, 0x2009, 0x003f, 0x0078, 0x387f, 0x2011, 0x0000, 0x2100,
-+	0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c,
-+	0x781b, 0x0065, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065,
-+	0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459, 0x782b, 0x3008,
-+	0x781b, 0x0056, 0x0078, 0x2459, 0x2009, 0x5120, 0x210c, 0xa186,
-+	0x0000, 0x0040, 0x38b0, 0xa186, 0x0001, 0x0040, 0x38b3, 0x2009,
-+	0x5138, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c,
-+	0x781b, 0x00c7, 0x007c, 0x2009, 0x5138, 0x200b, 0x000a, 0x007c,
-+	0x2009, 0x5120, 0x210c, 0xa186, 0x0000, 0x0040, 0x38d3, 0xa186,
-+	0x0001, 0x0040, 0x38cd, 0x2009, 0x5138, 0x200b, 0x000b, 0x706f,
-+	0x0001, 0x781b, 0x0048, 0x0078, 0x2459, 0x2009, 0x5138, 0x200b,
-+	0x000a, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x00c7, 0x0078,
-+	0x2459, 0x781b, 0x00cd, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b,
-+	0x00cd, 0x0078, 0x2459, 0x781b, 0x008e, 0x0078, 0x2459, 0x782b,
-+	0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000,
-+	0x0040, 0x38f4, 0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048,
-+	0x0078, 0x2459, 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3910,
-+	0x7808, 0xa084, 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-+	0x78ec, 0xa084, 0x0021, 0x0040, 0x3910, 0x7044, 0x780a, 0xa005,
-+	0x007f, 0x007c, 0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c,
-+	0x007e, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3919, 0x0098, 0x3924,
-+	0x007f, 0x789a, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
-+	0x3933, 0x0098, 0x3931, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044,
-+	0x780a, 0x007f, 0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4760,
-+	0xa784, 0x007d, 0x00c0, 0x3947, 0x2700, 0x1078, 0x23eb, 0xa784,
-+	0x0001, 0x00c0, 0x2f6d, 0xa784, 0x0070, 0x0040, 0x3957, 0x0c7e,
-+	0x2d60, 0x2f68, 0x1078, 0x2396, 0x2d78, 0x2c68, 0x0c7f, 0xa784,
-+	0x0008, 0x0040, 0x3964, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x2482, 0x0078, 0x3888, 0xa784, 0x0004, 0x0040, 0x3997,
-+	0x78b8, 0xa084, 0x4001, 0x0040, 0x3997, 0x784b, 0x0008, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x2482, 0x78e4, 0xa084, 0x0007, 0xa086,
-+	0x0001, 0x00c0, 0x3997, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a,
-+	0x781b, 0x00cd, 0x0078, 0x2459, 0x784b, 0x0008, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x3993, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040,
-+	0x3993, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078, 0x2459, 0x681b,
-+	0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833,
-+	0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2965,
-+	0x0018, 0x2459, 0x0078, 0x36a5, 0x6b14, 0x8307, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2060, 0x2048, 0x7056,
-+	0x6000, 0x705a, 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x39c0,
-+	0x39c8, 0x39c9, 0x39c8, 0x39cb, 0x39c8, 0x39c8, 0x39c8, 0x39d0,
-+	0x007c, 0x1078, 0x33ee, 0x1078, 0x4776, 0x7038, 0x600a, 0x007c,
-+	0x70a0, 0xa005, 0x0040, 0x39dd, 0x2068, 0x1078, 0x1b62, 0x1078,
-+	0x46f8, 0x1078, 0x46ff, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091,
-+	0x8000, 0x2071, 0x5140, 0x7000, 0xa086, 0x0007, 0x00c0, 0x39f4,
-+	0x6110, 0x70bc, 0xa106, 0x00c0, 0x39f4, 0x0e7f, 0x1078, 0x1b6f,
-+	0x1078, 0x39fa, 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085,
-+	0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x0078, 0x21fa,
-+	0x785b, 0x0000, 0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0,
-+	0xa06d, 0x0040, 0x3a0f, 0x70a3, 0x0000, 0x0078, 0x3a15, 0x70b3,
-+	0x0000, 0x1078, 0x1b8b, 0x0040, 0x3a1b, 0x70ac, 0x6826, 0x1078,
-+	0x3af8, 0x0078, 0x3a0f, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9,
-+	0x0008, 0x2061, 0x7510, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d,
-+	0x0040, 0x3a33, 0x6800, 0x601e, 0x1078, 0x195a, 0x6008, 0x8000,
-+	0x600a, 0x0078, 0x3a26, 0x6018, 0xa06d, 0x0040, 0x3a3d, 0x6800,
-+	0x601a, 0x1078, 0x195a, 0x0078, 0x3a33, 0xace0, 0x0008, 0x0070,
-+	0x3a43, 0x0078, 0x3a23, 0x709c, 0xa084, 0x8000, 0x0040, 0x3a4a,
-+	0x1078, 0x3b72, 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091,
-+	0x2300, 0x6804, 0xa084, 0x000f, 0x0079, 0x3a56, 0x3a66, 0x3a66,
-+	0x3a66, 0x3a66, 0x3a66, 0x3a66, 0x3a68, 0x3a6e, 0x3a66, 0x3a66,
-+	0x3a66, 0x3a66, 0x3a66, 0x3a70, 0x3a66, 0x3a68, 0x1078, 0x23eb,
-+	0x1078, 0x44d0, 0x1078, 0x195a, 0x0078, 0x3a74, 0x6827, 0x000b,
-+	0x1078, 0x44d0, 0x1078, 0x3af8, 0x127f, 0x007c, 0x127e, 0x2091,
-+	0x2300, 0x0098, 0x3a92, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3a92,
-+	0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001,
-+	0x0000, 0x6827, 0x0084, 0x1078, 0x46c1, 0x1078, 0x3af8, 0x0d7f,
-+	0x0078, 0x3ac6, 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3a9b,
-+	0x794a, 0x0078, 0x3a80, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3aa4,
-+	0xa185, 0x0004, 0x0078, 0x3aab, 0x7828, 0xa086, 0x1814, 0x00c0,
-+	0x3a98, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002,
-+	0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080,
-+	0x0091, 0x781a, 0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a,
-+	0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x46c1, 0x127f, 0x007c,
-+	0x0d7e, 0x6b14, 0x1078, 0x1bfd, 0x0040, 0x3ad5, 0x2068, 0x6827,
-+	0x0002, 0x1078, 0x3af8, 0x0078, 0x3aca, 0x0d7f, 0x007c, 0x0d7e,
-+	0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b9b, 0x0040, 0x3ae5,
-+	0x2068, 0x6827, 0x0002, 0x1078, 0x3af8, 0x0d7f, 0x007c, 0x0d7e,
-+	0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bce, 0x0040, 0x3af6, 0x2068,
-+	0x6827, 0x0002, 0x1078, 0x3af8, 0x0078, 0x3aeb, 0x0d7f, 0x007c,
-+	0x0c7e, 0x6914, 0x1078, 0x3b69, 0x6904, 0xa18c, 0x00ff, 0xa186,
-+	0x0006, 0x0040, 0x3b13, 0xa186, 0x000d, 0x0040, 0x3b32, 0xa186,
-+	0x0017, 0x00c0, 0x3b0f, 0x1078, 0x195a, 0x0078, 0x3b11, 0x1078,
-+	0x1c72, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048, 0x3b30, 0x6006,
-+	0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3b20, 0xa18d, 0x8000,
-+	0xa684, 0x0004, 0x0040, 0x3b26, 0xa18d, 0x0002, 0x691e, 0x6823,
-+	0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3b0f,
-+	0x1078, 0x23eb, 0x6018, 0xa005, 0x00c0, 0x3b41, 0x6008, 0x8001,
-+	0x0048, 0x3b41, 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078,
-+	0x3b57, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040, 0x3b4a, 0x2008,
-+	0x0078, 0x3b43, 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3b11,
-+	0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078, 0x3b3b, 0x157e,
-+	0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x1937, 0x2da0, 0x137f,
-+	0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x0078,
-+	0x3b0f, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003, 0xa080, 0x7510,
-+	0x2060, 0x007c, 0x2019, 0x5151, 0x2304, 0xa085, 0x0001, 0x201a,
-+	0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a, 0x007c, 0x2019,
-+	0x5151, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019, 0x0102, 0x2304,
-+	0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c, 0xfff8, 0x7992,
-+	0x70b4, 0xa080, 0x00dd, 0x781a, 0x0078, 0x2459, 0x70a3, 0x0000,
-+	0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000, 0x0018, 0x2410,
-+	0x1078, 0x1b8b, 0x0040, 0x3bc7, 0x2009, 0x510f, 0x200b, 0x0000,
-+	0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040, 0x3bbb, 0x6827,
-+	0x000e, 0xa084, 0x0200, 0x0040, 0x3bb7, 0x6827, 0x0017, 0x1078,
-+	0x3af8, 0x0078, 0x3b96, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3c29,
-+	0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078, 0x3bce, 0x7040,
-+	0xa086, 0x0001, 0x0040, 0x2492, 0x0078, 0x2459, 0x2031, 0x0000,
-+	0x691c, 0xa184, 0x0002, 0x0040, 0x3bd7, 0xa6b5, 0x0004, 0xa184,
-+	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635,
-+	0x6820, 0xa084, 0x0400, 0x0040, 0x3bef, 0x789b, 0x0018, 0x78ab,
-+	0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0x6820,
-+	0xa084, 0x8000, 0x00c0, 0x3bfd, 0x681c, 0xa084, 0x8000, 0x00c0,
-+	0x3c04, 0xa6b5, 0x0800, 0x0078, 0x3c04, 0xa6b5, 0x0400, 0x789b,
-+	0x000e, 0x6824, 0x8007, 0x78aa, 0x6820, 0xa084, 0x0100, 0x0040,
-+	0x3c0b, 0xa6b5, 0x4000, 0xa684, 0x0200, 0x0040, 0x3c25, 0x682c,
-+	0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040, 0x3c23, 0x682c,
-+	0xa084, 0x0001, 0x0040, 0x3c23, 0x7888, 0xa084, 0x0040, 0x0040,
-+	0x3c23, 0xa6b5, 0x8000, 0x1078, 0x46f0, 0x7e5a, 0x6eb6, 0x0078,
-+	0x4727, 0x1078, 0x38fa, 0x00c0, 0x3cbc, 0x702c, 0x8004, 0x0048,
-+	0x3c37, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x2041,
-+	0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814, 0xa084, 0x001f,
-+	0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002, 0x0040, 0x3c50,
-+	0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa, 0xa8c0, 0x0002,
-+	0x681c, 0xd0f4, 0x0040, 0x3c59, 0x2c50, 0x1078, 0x39ac, 0x1078,
-+	0x45ff, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c67, 0xa6b5, 0x0400,
-+	0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c6e, 0x681c,
-+	0xa084, 0x8000, 0x00c0, 0x3c6e, 0xa6b5, 0x0800, 0x6820, 0xa084,
-+	0x0100, 0x0040, 0x3c75, 0xa6b5, 0x4000, 0x681c, 0xa084, 0x00c0,
-+	0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635, 0xa684,
-+	0x0100, 0x0040, 0x3c8f, 0x682c, 0xa084, 0x0001, 0x0040, 0x3c8f,
-+	0x7888, 0xa084, 0x0040, 0x0040, 0x3c8f, 0xa6b5, 0x8000, 0x789b,
-+	0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882, 0x2810,
-+	0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3cbc, 0x0018, 0x3cbc,
-+	0x70b4, 0xa080, 0x00e2, 0x781a, 0x1078, 0x3912, 0xa684, 0x0200,
-+	0x0040, 0x3cb0, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x46f0,
-+	0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80,
-+	0x000f, 0x7036, 0x0078, 0x2459, 0x1078, 0x1b62, 0x1078, 0x3912,
-+	0x0078, 0x2459, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23eb,
-+	0x2300, 0x0079, 0x3ccb, 0x3cce, 0x3cce, 0x3cd0, 0x1078, 0x23eb,
-+	0x1078, 0x46ff, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040,
-+	0x3ce2, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b62,
-+	0x0078, 0x3b96, 0x2001, 0x000a, 0x1078, 0x4691, 0x0078, 0x3b96,
-+	0xa282, 0x0005, 0x0050, 0x3cee, 0x1078, 0x23eb, 0x7000, 0xa084,
-+	0x0007, 0x10c0, 0x39be, 0x1078, 0x1937, 0x00c0, 0x3d0d, 0xa684,
-+	0x0004, 0x0040, 0x3cff, 0x2001, 0x2800, 0x0078, 0x3d01, 0x2001,
-+	0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031,
-+	0x0400, 0x7e5a, 0x791a, 0x0078, 0x2459, 0x6807, 0x0106, 0x680b,
-+	0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0,
-+	0x3d2e, 0xa286, 0x0002, 0x00c0, 0x3d2e, 0x78a0, 0xa005, 0x00c0,
-+	0x3d2e, 0xa484, 0x8000, 0x00c0, 0x3d2e, 0x78e4, 0xa084, 0x0008,
-+	0x0040, 0x3d2e, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x411e,
-+	0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824,
-+	0xa084, 0x0080, 0x0040, 0x3d40, 0x1078, 0x41d0, 0x0078, 0x2459,
-+	0x2300, 0x0079, 0x3d43, 0x3d46, 0x3dc7, 0x3de6, 0x2200, 0x0079,
-+	0x3d49, 0x3d4e, 0x3d5e, 0x3d84, 0x3d90, 0x3db3, 0x2029, 0x0001,
-+	0xa026, 0x2011, 0x0000, 0x1078, 0x42f1, 0x0079, 0x3d57, 0x3d5c,
-+	0x2459, 0x3b96, 0x3d5c, 0x3d5c, 0x1078, 0x23eb, 0x7990, 0xa18c,
-+	0x0007, 0x00c0, 0x3d65, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684,
-+	0x0004, 0x0040, 0x3d6d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011,
-+	0x0001, 0x1078, 0x42f1, 0x0079, 0x3d75, 0x3d7a, 0x2459, 0x3b96,
-+	0x3d82, 0x3d7c, 0x0078, 0x472d, 0x70ab, 0x3d80, 0x0078, 0x2459,
-+	0x0078, 0x3d7a, 0x1078, 0x23eb, 0xa684, 0x0010, 0x0040, 0x3d8e,
-+	0x1078, 0x419f, 0x0040, 0x3d8e, 0x0078, 0x2459, 0x0078, 0x420c,
-+	0x6000, 0xa084, 0x0002, 0x0040, 0x3dad, 0x70b4, 0xa080, 0x00d2,
-+	0x781a, 0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x6827, 0x0000,
-+	0x1078, 0x3af8, 0x0d7f, 0x1078, 0x195a, 0x7003, 0x0000, 0x7037,
-+	0x0000, 0x704b, 0x0000, 0x0078, 0x3b96, 0xa684, 0x0004, 0x00c0,
-+	0x3db3, 0x0078, 0x472d, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3dc5,
-+	0x6000, 0xa084, 0x0001, 0x0040, 0x3dc5, 0x70ab, 0x3dc5, 0x2001,
-+	0x0007, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x2200,
-+	0x0079, 0x3dca, 0x3dcf, 0x3dcf, 0x3dcf, 0x3dd1, 0x3dcf, 0x1078,
-+	0x23eb, 0x70a7, 0x3dd5, 0x0078, 0x4739, 0x2011, 0x0018, 0x1078,
-+	0x42eb, 0x0079, 0x3ddb, 0x3de0, 0x2459, 0x3b96, 0x3de2, 0x3de4,
-+	0x1078, 0x23eb, 0x1078, 0x23eb, 0x1078, 0x23eb, 0x2200, 0x0079,
-+	0x3de9, 0x3dee, 0x3df0, 0x3df0, 0x3dee, 0x3dee, 0x1078, 0x23eb,
-+	0x78e4, 0xa084, 0x0008, 0x0040, 0x3e05, 0x70a7, 0x3df9, 0x0078,
-+	0x4739, 0x2011, 0x0004, 0x1078, 0x42eb, 0x0079, 0x3dff, 0x3e05,
-+	0x2459, 0x3b96, 0x3e05, 0x3e0f, 0x3e13, 0x70ab, 0x3e0d, 0x2001,
-+	0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x70ab,
-+	0x3e05, 0x0078, 0x2459, 0x70ab, 0x3e17, 0x0078, 0x2459, 0x0078,
-+	0x3e0d, 0xa282, 0x0003, 0x0050, 0x3e1f, 0x1078, 0x23eb, 0xa386,
-+	0x0002, 0x00c0, 0x3e38, 0xa286, 0x0002, 0x00c0, 0x3e3e, 0x78a0,
-+	0xa005, 0x00c0, 0x3e3e, 0xa484, 0x8000, 0x00c0, 0x3e3e, 0x78e4,
-+	0xa084, 0x0008, 0x0040, 0x3e38, 0xa6b5, 0x0008, 0x2019, 0x0000,
-+	0xa684, 0x0008, 0x0040, 0x3e3e, 0x1078, 0x417c, 0x6810, 0x70be,
-+	0x7003, 0x0007, 0x2300, 0x0079, 0x3e45, 0x3e48, 0x3e75, 0x3e7d,
-+	0x2200, 0x0079, 0x3e4b, 0x3e50, 0x3e4e, 0x3e69, 0x1078, 0x23eb,
-+	0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x42f1,
-+	0x0079, 0x3e5a, 0x3e5f, 0x2459, 0x3b96, 0x3e67, 0x3e61, 0x0078,
-+	0x472d, 0x70ab, 0x3e65, 0x0078, 0x2459, 0x0078, 0x3e5f, 0x1078,
-+	0x23eb, 0xa684, 0x0010, 0x0040, 0x3e73, 0x1078, 0x419f, 0x0040,
-+	0x3e73, 0x0078, 0x2459, 0x0078, 0x420c, 0x2200, 0x0079, 0x3e78,
-+	0x3e7b, 0x3e7b, 0x3e7b, 0x1078, 0x23eb, 0x2200, 0x0079, 0x3e80,
-+	0x3e83, 0x3e85, 0x3e85, 0x1078, 0x23eb, 0x78e4, 0xa084, 0x0008,
-+	0x0040, 0x3e9a, 0x70a7, 0x3e8e, 0x0078, 0x4739, 0x2011, 0x0004,
-+	0x1078, 0x42eb, 0x0079, 0x3e94, 0x3e9a, 0x2459, 0x3b96, 0x3e9a,
-+	0x3ea4, 0x3ea8, 0x70ab, 0x3ea2, 0x2001, 0x0003, 0x1078, 0x4689,
-+	0x0078, 0x4733, 0x0078, 0x472d, 0x70ab, 0x3e9a, 0x0078, 0x2459,
-+	0x70ab, 0x3eac, 0x0078, 0x2459, 0x0078, 0x3ea2, 0x2300, 0x0079,
-+	0x3eb1, 0x3eb6, 0x3eb8, 0x3eb4, 0x1078, 0x23eb, 0x70a4, 0x007a,
-+	0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3ec0, 0x1078, 0x23eb,
-+	0xa684, 0x0200, 0x0040, 0x3eca, 0x1078, 0x46f8, 0x1078, 0x42d3,
-+	0x1078, 0x46ff, 0x2300, 0x0079, 0x3ecd, 0x3ed0, 0x3ef4, 0x3f5a,
-+	0xa286, 0x0001, 0x0040, 0x3ed6, 0x1078, 0x23eb, 0xa684, 0x0200,
-+	0x0040, 0x3ede, 0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001,
-+	0x1078, 0x4691, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ef0, 0x7848,
-+	0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3eeb,
-+	0x7003, 0x0000, 0x0078, 0x3b96, 0x2200, 0x0079, 0x3ef7, 0x3ef9,
-+	0x3f2a, 0x70a7, 0x3efd, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078,
-+	0x42eb, 0x0079, 0x3f03, 0x3f0a, 0x2459, 0x3b96, 0x3f12, 0x3f1a,
-+	0x3f20, 0x3f22, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0078, 0x4727, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0078, 0x4727, 0x70ab, 0x3f1e, 0x0078, 0x2459, 0x0078, 0x3f0a,
-+	0x1078, 0x23eb, 0x70ab, 0x3f26, 0x0078, 0x2459, 0x1078, 0x473f,
-+	0x0078, 0x2459, 0x70a7, 0x3f2e, 0x0078, 0x4739, 0x2011, 0x0012,
-+	0x1078, 0x42eb, 0x0079, 0x3f34, 0x3f3a, 0x2459, 0x3b96, 0x3f46,
-+	0x3f4e, 0x3f54, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff,
-+	0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab, 0x3f52,
-+	0x0078, 0x2459, 0x0078, 0x3f3a, 0x70ab, 0x3f58, 0x0078, 0x2459,
-+	0x0078, 0x3f46, 0xa286, 0x0001, 0x0040, 0x3f60, 0x1078, 0x23eb,
-+	0x70a7, 0x3f64, 0x0078, 0x4739, 0x2011, 0x0015, 0x1078, 0x42eb,
-+	0x0079, 0x3f6a, 0x3f6f, 0x2459, 0x3b96, 0x3f7d, 0x3f89, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4,
-+	0xa080, 0x00b4, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff, 0xa6b5,
-+	0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078,
-+	0x2459, 0x70ab, 0x3f8d, 0x0078, 0x2459, 0x0078, 0x3f6f, 0xa282,
-+	0x0003, 0x0050, 0x3f95, 0x1078, 0x23eb, 0x2300, 0x0079, 0x3f98,
-+	0x3f9b, 0x3fd2, 0x402d, 0xa286, 0x0001, 0x0040, 0x3fa1, 0x1078,
-+	0x23eb, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3fae,
-+	0x1078, 0x3af8, 0x7003, 0x0000, 0x0078, 0x3b96, 0x683b, 0x0000,
-+	0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3fbc, 0x1078, 0x46f8,
-+	0x1078, 0x42d3, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691,
-+	0x78b8, 0xa084, 0xc001, 0x0040, 0x3fce, 0x7848, 0xa085, 0x0008,
-+	0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3fc9, 0x7003, 0x0000,
-+	0x0078, 0x3b96, 0x2200, 0x0079, 0x3fd5, 0x3fd7, 0x4008, 0x70a7,
-+	0x3fdb, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079,
-+	0x3fe1, 0x3fe8, 0x2459, 0x3b96, 0x3ff0, 0x3ff8, 0x3ffe, 0x4000,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-+	0x70ab, 0x3ffc, 0x0078, 0x2459, 0x0078, 0x3fe8, 0x1078, 0x23eb,
-+	0x70ab, 0x4004, 0x0078, 0x2459, 0x1078, 0x473f, 0x0078, 0x2459,
-+	0x70a7, 0x400c, 0x0078, 0x4739, 0x2011, 0x0005, 0x1078, 0x42eb,
-+	0x0079, 0x4012, 0x4017, 0x2459, 0x3b96, 0x401f, 0x4027, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab,
-+	0x402b, 0x0078, 0x2459, 0x0078, 0x4017, 0xa286, 0x0001, 0x0040,
-+	0x4033, 0x1078, 0x23eb, 0x70a7, 0x4037, 0x0078, 0x4739, 0x2011,
-+	0x0006, 0x1078, 0x42eb, 0x0079, 0x403d, 0x4042, 0x2459, 0x3b96,
-+	0x4048, 0x4052, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a,
-+	0x0078, 0x4727, 0x70ab, 0x4056, 0x0078, 0x2459, 0x0078, 0x4042,
-+	0x2300, 0x0079, 0x405b, 0x4060, 0x405e, 0x405e, 0x1078, 0x23eb,
-+	0x1078, 0x23eb, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be,
-+	0xa282, 0x0003, 0x0050, 0x406e, 0x1078, 0x23eb, 0x2300, 0x0079,
-+	0x4071, 0x4074, 0x4082, 0x40a4, 0xa684, 0x0200, 0x0040, 0x407c,
-+	0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691,
-+	0x0078, 0x2459, 0xa296, 0x0002, 0x0040, 0x408b, 0x82ff, 0x0040,
-+	0x408b, 0x1078, 0x23eb, 0x70a7, 0x408f, 0x0078, 0x4739, 0x2011,
-+	0x0018, 0x1078, 0x42eb, 0x0079, 0x4095, 0x409a, 0x2459, 0x3b96,
-+	0x409c, 0x409e, 0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40a2,
-+	0x0078, 0x2459, 0x0078, 0x409a, 0x2200, 0x0079, 0x40a7, 0x40a9,
-+	0x40c2, 0x70a7, 0x40ad, 0x0078, 0x4739, 0x2011, 0x0017, 0x1078,
-+	0x42eb, 0x0079, 0x40b3, 0x40b8, 0x2459, 0x3b96, 0x40ba, 0x40bc,
-+	0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40c0, 0x0078, 0x2459,
-+	0x0078, 0x40b8, 0xa484, 0x8000, 0x00c0, 0x410c, 0xa684, 0x0100,
-+	0x0040, 0x40d6, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x1078, 0x46ff,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x0078, 0x40da, 0x78d8, 0x78d2,
-+	0x78dc, 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x40e1, 0x0078,
-+	0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079, 0x40e7, 0x40ee,
-+	0x2459, 0x3b96, 0x40ee, 0x40fc, 0x4102, 0x4104, 0xa684, 0x0100,
-+	0x0040, 0x40fa, 0x1078, 0x46b6, 0x682c, 0x78d2, 0x6830, 0x78d6,
-+	0x1078, 0x46f0, 0x0078, 0x4727, 0x70ab, 0x4100, 0x0078, 0x2459,
-+	0x0078, 0x40ee, 0x1078, 0x23eb, 0x70ab, 0x4108, 0x0078, 0x2459,
-+	0x1078, 0x473f, 0x0078, 0x2459, 0x1078, 0x46ff, 0x70ab, 0x4116,
-+	0x2001, 0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x1078, 0x46f0,
-+	0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4727, 0x70b8, 0x6812,
-+	0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008, 0x0040,
-+	0x4141, 0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004, 0x8004,
-+	0x8004, 0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80,
-+	0x002b, 0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f,
-+	0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x4150, 0x692c,
-+	0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078, 0x415f,
-+	0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x415f, 0x017e,
-+	0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x46c1, 0x017f, 0xa184,
-+	0x001f, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0xa684, 0x0004,
-+	0x0040, 0x4170, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105,
-+	0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x417a,
-+	0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918,
-+	0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e,
-+	0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x419b, 0x20a8,
-+	0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80,
-+	0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c,
-+	0xa084, 0x0020, 0x00c0, 0x41a7, 0x620c, 0x0078, 0x41a8, 0x6210,
-+	0x6b18, 0x2300, 0xa202, 0x0040, 0x41c8, 0x2018, 0xa382, 0x000e,
-+	0x0048, 0x41b8, 0x0040, 0x41b8, 0x2019, 0x000e, 0x0078, 0x41bc,
-+	0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000,
-+	0x7ba2, 0x70b4, 0xa080, 0x008e, 0x781a, 0xa085, 0x0001, 0x007c,
-+	0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006, 0x007c,
-+	0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x41dd, 0xa196,
-+	0x000f, 0x0040, 0x41dd, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b69,
-+	0x6100, 0x8104, 0x00c8, 0x41f8, 0x601c, 0xa005, 0x0040, 0x41ec,
-+	0x2001, 0x0800, 0x0078, 0x41fa, 0x0d7e, 0x6824, 0x007e, 0x1078,
-+	0x4708, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3af8, 0x0d7f,
-+	0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
-+	0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4,
-+	0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684, 0x0002,
-+	0x00c0, 0x4220, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007,
-+	0x2008, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0x0078, 0x4223,
-+	0x6914, 0x1078, 0x3b69, 0x6100, 0x8104, 0x00c8, 0x4280, 0xa184,
-+	0x0300, 0x0040, 0x422f, 0x6807, 0x0117, 0x0078, 0x424d, 0x6004,
-+	0xa005, 0x00c0, 0x4256, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0,
-+	0x4243, 0x0d7e, 0x1078, 0x4708, 0x6827, 0x0034, 0x2d00, 0x682e,
-+	0x1078, 0x3af8, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x424d, 0x2031,
-+	0x0400, 0x2001, 0x2800, 0x0078, 0x4251, 0x2031, 0x0400, 0x2001,
-+	0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x42ae, 0x6018, 0xa005,
-+	0x00c0, 0x4243, 0x601c, 0xa005, 0x00c0, 0x4243, 0x689f, 0x0000,
-+	0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x42bc, 0xd694, 0x00c0,
-+	0x4279, 0x6100, 0xd1d4, 0x0040, 0x4279, 0x692c, 0x81ff, 0x0040,
-+	0x42bc, 0xa186, 0x0003, 0x0040, 0x42bc, 0xa186, 0x0012, 0x0040,
-+	0x42bc, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00af, 0x0078, 0x42b7,
-+	0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c, 0x00ff, 0xa186,
-+	0x0012, 0x00c0, 0x4291, 0x2001, 0x42c9, 0x2009, 0x0001, 0x0078,
-+	0x42a2, 0xa186, 0x0003, 0x00c0, 0x429b, 0x2001, 0x42ca, 0x2009,
-+	0x0012, 0x0078, 0x42a2, 0x2001, 0x0200, 0x71b4, 0xa188, 0x0091,
-+	0x0078, 0x42ae, 0x1078, 0x46db, 0x78a3, 0x0000, 0x681c, 0xa085,
-+	0x0040, 0x681e, 0x71b4, 0xa188, 0x00df, 0xa006, 0x6826, 0x8007,
-+	0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x6eb6,
-+	0x7e5a, 0x791a, 0x0078, 0x2459, 0x6eb6, 0x1078, 0x3af8, 0x6810,
-+	0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b, 0x0000, 0x0078,
-+	0x2459, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00, 0x0000, 0x0000,
-+	0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
-+	0x0200, 0x0040, 0x42ea, 0x78b8, 0xa08c, 0x001f, 0xa084, 0x8000,
-+	0x0040, 0x42e3, 0x8108, 0x78d8, 0xa100, 0x6836, 0x78dc, 0xa081,
-+	0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac, 0x0007, 0x2021,
-+	0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa184,
-+	0x0080, 0x00c0, 0x4319, 0xa182, 0x0020, 0x00c8, 0x4337, 0xa182,
-+	0x0012, 0x00c8, 0x467b, 0x2100, 0x1079, 0x4307, 0x007c, 0x467b,
-+	0x44e8, 0x467b, 0x467b, 0x4344, 0x4347, 0x4381, 0x43b7, 0x43eb,
-+	0x43ee, 0x467b, 0x467b, 0x43a2, 0x4412, 0x444c, 0x467b, 0x467b,
-+	0x4473, 0xa184, 0x0020, 0x00c0, 0x44a7, 0xa18c, 0x001f, 0x6814,
-+	0xa084, 0x001f, 0xa106, 0x0040, 0x4334, 0x70b4, 0xa080, 0x00d2,
-+	0x781a, 0x2001, 0x0014, 0x1078, 0x4691, 0x1078, 0x46ff, 0x7003,
-+	0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182,
-+	0x0024, 0x00c8, 0x467b, 0xa184, 0x0003, 0x1079, 0x4307, 0x007c,
-+	0x467b, 0x467b, 0x467b, 0x467b, 0x1078, 0x467b, 0x007c, 0x2200,
-+	0x0079, 0x434a, 0x4476, 0x4476, 0x436e, 0x436e, 0x436e, 0x436e,
-+	0x436e, 0x436e, 0x436e, 0x436e, 0x436c, 0x436e, 0x4363, 0x436e,
-+	0x436e, 0x436e, 0x436e, 0x436e, 0x4376, 0x4379, 0x4476, 0x4379,
-+	0x436e, 0x436e, 0x436e, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36e2,
-+	0x077f, 0x0c7f, 0x0078, 0x436e, 0x1078, 0x458b, 0x6827, 0x02b3,
-+	0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x44aa, 0x1078, 0x4670,
-+	0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078,
-+	0x4492, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-+	0x438b, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x4708, 0x6827,
-+	0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ac8, 0x1078,
-+	0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8, 0x2001,
-+	0x0002, 0x007c, 0x1078, 0x44d0, 0x2001, 0x0017, 0x1078, 0x4691,
-+	0x70a3, 0x0000, 0x2009, 0x5138, 0x200b, 0x0006, 0x70af, 0x0017,
-+	0x2009, 0x0200, 0x1078, 0x3a06, 0x2001, 0x0001, 0x007c, 0x2200,
-+	0x0079, 0x43ba, 0x4476, 0x44a7, 0x44a7, 0x44a7, 0x43db, 0x44b7,
-+	0x43e3, 0x44b7, 0x44b7, 0x44ba, 0x44ba, 0x44bf, 0x44bf, 0x43d3,
-+	0x43d3, 0x44a7, 0x44a7, 0x44b7, 0x44a7, 0x43e3, 0x4476, 0x43e3,
-+	0x43e3, 0x43e3, 0x43e3, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x44c9, 0x6827, 0x000d, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x44aa, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x4492, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079,
-+	0x43f1, 0x4476, 0x440a, 0x440a, 0x440a, 0x440a, 0x44b7, 0x44b7,
-+	0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x440a, 0x440a,
-+	0x440a, 0x440a, 0x44b7, 0x440a, 0x440a, 0x44b7, 0x44b7, 0x44b7,
-+	0x44b7, 0x4476, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300,
-+	0x0078, 0x4492, 0xa684, 0x0004, 0x00c0, 0x4426, 0x6804, 0xa084,
-+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x467b, 0x1078, 0x44d0, 0x6807,
-+	0x0117, 0x1078, 0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084,
-+	0x0004, 0x0040, 0x467b, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x00c0, 0x4435, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
-+	0x4708, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
-+	0x3ad7, 0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078,
-+	0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040,
-+	0x467b, 0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0,
-+	0x445b, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x4708,
-+	0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ae7,
-+	0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8,
-+	0x2001, 0x0002, 0x007c, 0x1078, 0x467b, 0x007c, 0x70b4, 0xa080,
-+	0x00d2, 0x781a, 0x2001, 0x0001, 0x1078, 0x4691, 0x1078, 0x46ff,
-+	0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x46c1, 0x1078,
-+	0x46f8, 0x1078, 0x42d3, 0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001,
-+	0x0001, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3,
-+	0x70b4, 0xa080, 0x00d2, 0x781a, 0x2001, 0x0013, 0x1078, 0x4691,
-+	0x1078, 0x46ff, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078,
-+	0x467b, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3,
-+	0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001, 0x0001, 0x007c, 0x2001,
-+	0x0003, 0x007c, 0x1078, 0x458b, 0x2001, 0x0000, 0x007c, 0x0c7e,
-+	0x077e, 0x6f14, 0x1078, 0x36e2, 0x077f, 0x0c7f, 0x2001, 0x0000,
-+	0x007c, 0x1078, 0x46c1, 0x1078, 0x467b, 0x2001, 0x0006, 0x007c,
-+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x44db, 0xa186,
-+	0x000f, 0x00c0, 0x44df, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x70b4,
-+	0xa080, 0x00d2, 0x781a, 0x1078, 0x46ff, 0x7003, 0x0000, 0x007c,
-+	0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004,
-+	0x00c8, 0x467b, 0x1079, 0x44f5, 0x007c, 0x467b, 0x44f9, 0x467b,
-+	0x4592, 0xa282, 0x0003, 0x0040, 0x4500, 0x1078, 0x467b, 0x007c,
-+	0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x69b8, 0xa184,
-+	0x0100, 0x0040, 0x453f, 0xa18c, 0xfeff, 0x69ba, 0x78a0, 0xa005,
-+	0x00c0, 0x453f, 0xa4a4, 0x00ff, 0x0040, 0x4533, 0xa482, 0x000c,
-+	0x0040, 0x451c, 0x00c8, 0x4526, 0x852b, 0x852b, 0x1078, 0x3760,
-+	0x0040, 0x4526, 0x1078, 0x355b, 0x0078, 0x4535, 0x1078, 0x465d,
-+	0x1078, 0x3586, 0x69b8, 0xa18d, 0x0100, 0x69ba, 0xa6b5, 0x1000,
-+	0x7e5a, 0x0078, 0x4538, 0x1078, 0x3586, 0xa6b4, 0xefff, 0x7e5a,
-+	0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e,
-+	0x1078, 0x457f, 0x6200, 0xd2e4, 0x0040, 0x4570, 0x6208, 0x8217,
-+	0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x4552, 0x0040, 0x4552,
-+	0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x4557, 0x2220, 0x6208,
-+	0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8, 0x455f, 0x721c, 0x2200,
-+	0xa502, 0x00c8, 0x4564, 0x2228, 0x1078, 0x4661, 0x852b, 0x852b,
-+	0x1078, 0x3760, 0x0040, 0x4570, 0x1078, 0x3562, 0x0078, 0x4574,
-+	0x1078, 0x465d, 0x1078, 0x358d, 0xa6b5, 0x1000, 0x7e5a, 0x70b4,
-+	0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x007e,
-+	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-+	0x5380, 0x007f, 0x007c, 0x0c7e, 0x1078, 0x457f, 0x1078, 0x358d,
-+	0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0, 0x467b, 0x7aa8, 0xa294,
-+	0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040, 0x45c9, 0xa18c, 0xfdff,
-+	0x69ba, 0x78a0, 0xa005, 0x00c0, 0x45c9, 0xa282, 0x0002, 0x00c8,
-+	0x369d, 0x1078, 0x4627, 0x1078, 0x362b, 0x1078, 0x3586, 0xa684,
-+	0x0100, 0x0040, 0x45bf, 0x682c, 0xa084, 0x0001, 0x0040, 0x45bf,
-+	0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x45bf, 0xc6fd, 0xa6b5,
-+	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001,
-+	0x007c, 0x0c7e, 0x1078, 0x457f, 0xa284, 0xfffe, 0x0040, 0x45d4,
-+	0x2011, 0x0001, 0x0078, 0x45d8, 0xa284, 0x0001, 0x0040, 0x45de,
-+	0x6100, 0xd1ec, 0x00c0, 0x45de, 0x2011, 0x0000, 0x1078, 0x4619,
-+	0x1078, 0x3632, 0x1078, 0x358d, 0xa684, 0x0100, 0x0040, 0x45f4,
-+	0x682c, 0xa084, 0x0001, 0x0040, 0x45f4, 0xc6fc, 0x7888, 0xa084,
-+	0x0040, 0x0040, 0x45f4, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4,
-+	0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x0c7e,
-+	0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x460a,
-+	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-+	0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085, 0x0200, 0x68ba, 0x0c7f,
-+	0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c, 0x0c7e,
-+	0x7054, 0x2060, 0x6000, 0xa084, 0x1000, 0x00c0, 0x4635, 0x2029,
-+	0x0032, 0x2021, 0x0000, 0x0078, 0x4655, 0x6508, 0xa5ac, 0x00ff,
-+	0x7018, 0xa086, 0x0028, 0x00c0, 0x4645, 0xa582, 0x0019, 0x00c8,
-+	0x464b, 0x2029, 0x0019, 0x0078, 0x464b, 0xa582, 0x000c, 0x00c8,
-+	0x464b, 0x2029, 0x000c, 0x6408, 0x8427, 0xa4a4, 0x00ff, 0xa482,
-+	0x000c, 0x0048, 0x4655, 0x2021, 0x000c, 0x1078, 0x4661, 0x68b8,
-+	0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c, 0x2021, 0x0000, 0x2029,
-+	0x0032, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x007c,
-+	0x2001, 0x0003, 0x1078, 0x4689, 0x70b4, 0xa080, 0x00be, 0x781a,
-+	0x2001, 0x0005, 0x007c, 0x2001, 0x0007, 0x1078, 0x4689, 0xa6b5,
-+	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00be, 0x781a, 0x2001, 0x0004,
-+	0x007c, 0x789b, 0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001,
-+	0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x469f,
-+	0xa196, 0x000f, 0x0040, 0x469f, 0x1078, 0x195a, 0x007c, 0x6924,
-+	0xa194, 0x003f, 0x00c0, 0x46a8, 0xa18c, 0xffc0, 0xa105, 0x6826,
-+	0x1078, 0x3af8, 0x691c, 0xa184, 0x0100, 0x0040, 0x46b5, 0x6914,
-+	0x1078, 0x3b69, 0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834,
-+	0x682e, 0xa112, 0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301,
-+	0x007c, 0x0c7e, 0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b,
-+	0x0000, 0x600f, 0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007,
-+	0x601a, 0x601f, 0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085,
-+	0x0080, 0x6826, 0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80,
-+	0x002d, 0x20a0, 0x81ac, 0x0040, 0x46e6, 0x53a6, 0xa184, 0x0001,
-+	0x0040, 0x46ec, 0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c,
-+	0x70b0, 0xa005, 0x10c0, 0x23eb, 0x70b3, 0x8000, 0x0078, 0x4a3a,
-+	0x71b0, 0x81ff, 0x0040, 0x46fe, 0x1078, 0x4b30, 0x007c, 0x71b0,
-+	0x81ff, 0x0040, 0x4707, 0x70b3, 0x0000, 0x1078, 0x4776, 0x007c,
-+	0x0c7e, 0x0d7e, 0x1078, 0x1937, 0x0c7f, 0x157e, 0x137e, 0x147e,
-+	0x2da0, 0x2c98, 0x20a9, 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f,
-+	0x6807, 0x010d, 0x680b, 0x0000, 0x7004, 0x8007, 0x681a, 0x6823,
-+	0x0000, 0x681f, 0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4,
-+	0xa080, 0x0091, 0x781a, 0x0078, 0x2459, 0x70b4, 0xa080, 0x0081,
-+	0x781a, 0x0078, 0x2459, 0x70b4, 0xa080, 0x00be, 0x781a, 0x0078,
-+	0x2459, 0x70b4, 0xa080, 0x00c8, 0x781a, 0x0078, 0x2459, 0x6904,
-+	0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x474c, 0xa196, 0x000f,
-+	0x0040, 0x474c, 0x6807, 0x0117, 0x2001, 0x0200, 0x6826, 0x8007,
-+	0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x2031,
-+	0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c,
-+	0x1078, 0x46ff, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4, 0xa080,
-+	0x00d2, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078, 0x46c1,
-+	0x2001, 0x0013, 0x1078, 0x4691, 0x0078, 0x3b96, 0x127e, 0x2091,
-+	0x2200, 0x2049, 0x4776, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215,
-+	0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4788, 0x0078, 0x478d,
-+	0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084, 0x0001,
-+	0x00c0, 0x47bb, 0x7108, 0x8103, 0x00c8, 0x479a, 0x1078, 0x48bd,
-+	0x0078, 0x4792, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x47bb, 0x7004,
-+	0x8004, 0x00c8, 0x47b2, 0x7014, 0xa005, 0x00c0, 0x47ae, 0x7010,
-+	0xa005, 0x0040, 0x47b2, 0xa102, 0x00c8, 0x4792, 0x7007, 0x0010,
-+	0x0078, 0x47bb, 0x8aff, 0x0040, 0x47bb, 0x1078, 0x4b07, 0x00c0,
-+	0x47b5, 0x0040, 0x4792, 0x1078, 0x4846, 0x7003, 0x0000, 0x127f,
-+	0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x47ce, 0xa18e, 0x000f, 0x00c0, 0x47d1, 0x6040, 0x0078,
-+	0x47d2, 0x6428, 0x017f, 0x84ff, 0x0040, 0x47fc, 0x2c70, 0x7004,
-+	0xa0bc, 0x000f, 0xa7b8, 0x480c, 0x273c, 0x87fb, 0x00c0, 0x47ea,
-+	0x0048, 0x47e4, 0x1078, 0x23eb, 0x609c, 0xa075, 0x0040, 0x47fc,
-+	0x0078, 0x47d7, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529,
-+	0x8421, 0x0040, 0x47fc, 0x8738, 0x2704, 0xa005, 0x00c0, 0x47eb,
-+	0x709c, 0xa075, 0x00c0, 0x47d7, 0x007c, 0x0000, 0x0005, 0x0009,
-+	0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009,
-+	0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4801, 0x47fe, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x4801, 0x0000, 0x4809, 0x4806, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x4809, 0x0000, 0x4804, 0x4804, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x4804, 0x0000, 0x480a, 0x480a, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x480a, 0x127e, 0x2091, 0x2200, 0x2079,
-+	0x5100, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
-+	0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
-+	0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x4846,
-+	0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x4899, 0x7007, 0x0012,
-+	0x7108, 0x7008, 0xa106, 0x00c0, 0x4850, 0xa184, 0x01e0, 0x0040,
-+	0x485b, 0x1078, 0x23eb, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-+	0x00c8, 0x4866, 0xa184, 0x4000, 0x00c0, 0x4850, 0xa19c, 0x300c,
-+	0xa386, 0x2004, 0x0040, 0x4874, 0xa386, 0x0008, 0x0040, 0x487f,
-+	0xa386, 0x200c, 0x00c0, 0x4850, 0x7200, 0x8204, 0x0048, 0x487f,
-+	0x730c, 0xa384, 0x00ff, 0x0040, 0x487f, 0x1078, 0x23eb, 0x7007,
-+	0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4899, 0x7008, 0xa084,
-+	0x01e0, 0x00c0, 0x4899, 0x7310, 0x7014, 0xa305, 0x0040, 0x4899,
-+	0x710c, 0xa184, 0x0300, 0x00c0, 0x4899, 0xa184, 0x00ff, 0x00c0,
-+	0x4846, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008,
-+	0x00c0, 0x489d, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x48a2,
-+	0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e, 0x127e,
-+	0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x48bd, 0x157f, 0x127f,
-+	0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500, 0x730c,
-+	0xa384, 0x0300, 0x00c0, 0x48e4, 0xa184, 0x01e0, 0x00c0, 0x4908,
-+	0x7108, 0xa184, 0x01e0, 0x00c0, 0x4908, 0x2001, 0x04fd, 0x2004,
-+	0xa082, 0x0005, 0x00c8, 0x48d8, 0xa184, 0x4000, 0x00c0, 0x48c8,
-+	0xa184, 0x0007, 0x0079, 0x48dc, 0x48e6, 0x48f8, 0x48e4, 0x48f8,
-+	0x48e4, 0x4944, 0x48e4, 0x4942, 0x1078, 0x23eb, 0x7004, 0xa084,
-+	0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x48f3, 0x2049,
-+	0x0000, 0x0078, 0x48f7, 0x1078, 0x4b07, 0x00c0, 0x48f3, 0x007c,
-+	0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0,
-+	0x4903, 0x0078, 0x4907, 0x1078, 0x4b07, 0x00c0, 0x4903, 0x007c,
-+	0x7007, 0x0012, 0x7108, 0x00e0, 0x490b, 0x2091, 0x6000, 0x00e0,
-+	0x490f, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
-+	0xa084, 0x0008, 0x00c0, 0x4917, 0x7007, 0x0012, 0x7108, 0x8103,
-+	0x0048, 0x491c, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4930,
-+	0x7004, 0xa005, 0x00c0, 0x4930, 0x700c, 0xa005, 0x0040, 0x4932,
-+	0x0078, 0x4913, 0x2049, 0x0000, 0x1078, 0x3809, 0x6818, 0xa084,
-+	0x8000, 0x0040, 0x493d, 0x681b, 0x0002, 0x007c, 0x1078, 0x23eb,
-+	0x1078, 0x23eb, 0x1078, 0x49a0, 0x7210, 0x7114, 0x700c, 0xa09c,
-+	0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x49a0,
-+	0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100,
-+	0xa31b, 0x2400, 0xa305, 0x0040, 0x4967, 0x00c8, 0x4967, 0x8412,
-+	0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x494e, 0x2b60,
-+	0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4973, 0xa7ba,
-+	0x4806, 0x0078, 0x4975, 0xa7ba, 0x47fe, 0x007f, 0xa73d, 0x2c00,
-+	0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4846,
-+	0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4994, 0x609c, 0xa005,
-+	0x0040, 0x499d, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x480c,
-+	0x203c, 0x87fb, 0x1040, 0x23eb, 0x8a51, 0x0040, 0x499c, 0x7008,
-+	0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000, 0x007c,
-+	0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x49b4, 0x6000, 0xa064,
-+	0x00c0, 0x49ab, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x481c,
-+	0x203c, 0x87fb, 0x1040, 0x23eb, 0x007c, 0x127e, 0x0d7e, 0x2091,
-+	0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
-+	0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008,
-+	0x007f, 0x0040, 0x49cf, 0xa0b8, 0x4806, 0x0078, 0x49d1, 0xa0b8,
-+	0x47fe, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
-+	0x0007, 0x0040, 0x49df, 0xa18e, 0x000f, 0x00c0, 0x49e8, 0x681c,
-+	0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x0078, 0x49ef,
-+	0x681c, 0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x49f1, 0x2400, 0xa305,
-+	0x00c0, 0x49fc, 0x0078, 0x4a22, 0x2c58, 0x2704, 0x6104, 0xac60,
-+	0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008,
-+	0x0040, 0x4a12, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081,
-+	0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300,
-+	0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x4981,
-+	0x0078, 0x4a24, 0x1078, 0x4b07, 0x00c0, 0x4a22, 0x127f, 0x2000,
-+	0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004,
-+	0x7004, 0xa084, 0x0004, 0x00c0, 0x4a30, 0x7003, 0x0008, 0x127f,
-+	0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049,
-+	0x4a3a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a43,
-+	0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x4a56, 0xa18e, 0x000f, 0x00c0, 0x4a61, 0x681c, 0xa084,
-+	0x0040, 0x0040, 0x4a5d, 0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078,
-+	0x4a6a, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4a68, 0xa6b5, 0x0001,
-+	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x480c,
-+	0x273c, 0x87fb, 0x00c0, 0x4a7e, 0x0048, 0x4a78, 0x1078, 0x23eb,
-+	0x689c, 0xa065, 0x0040, 0x4a82, 0x0078, 0x4a6b, 0x1078, 0x4b07,
-+	0x00c0, 0x4a7e, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
-+	0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4a9c,
-+	0xa18e, 0x000f, 0x00c0, 0x4aa5, 0x681c, 0xa084, 0x0040, 0x0040,
-+	0x4aac, 0xa6b5, 0x0001, 0x0078, 0x4aac, 0x681c, 0xa084, 0x0040,
-+	0x0040, 0x4aac, 0xa6b5, 0x0001, 0x2049, 0x4a85, 0x017e, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4aba, 0xa18e, 0x000f,
-+	0x00c0, 0x4abd, 0x6840, 0x0078, 0x4abe, 0x6828, 0x017f, 0xa055,
-+	0x0040, 0x4b04, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8,
-+	0x480c, 0x273c, 0x87fb, 0x00c0, 0x4ad8, 0x0048, 0x4ad1, 0x1078,
-+	0x23eb, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078, 0x4ac4,
-+	0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x4af1,
-+	0x8a51, 0x00c0, 0x4ae5, 0x1078, 0x23eb, 0x8738, 0x2704, 0xa005,
-+	0x00c0, 0x4ad9, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078,
-+	0x4ac4, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400,
-+	0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4b00, 0x1078, 0x23eb,
-+	0x2071, 0x0020, 0x0078, 0x49ef, 0x127f, 0x2000, 0x007c, 0x7008,
-+	0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4b2f, 0x2704, 0xac08,
-+	0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104, 0x7012,
-+	0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4b26,
-+	0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602, 0x7004,
-+	0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4981, 0x007c,
-+	0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4b30, 0x0d7f,
-+	0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4b5a, 0x017e, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4b4a, 0xa18e, 0x000f,
-+	0x00c0, 0x4b4d, 0x6840, 0x0078, 0x4b4e, 0x6828, 0x017f, 0xa005,
-+	0x0040, 0x4b68, 0x0078, 0x478d, 0x0020, 0x4b5a, 0x1078, 0x4944,
-+	0x0078, 0x4b68, 0x00a0, 0x4b61, 0x7108, 0x1078, 0x48bd, 0x0078,
-+	0x4b39, 0x7007, 0x0010, 0x00a0, 0x4b63, 0x7108, 0x1078, 0x48bd,
-+	0x7008, 0xa086, 0x0008, 0x00c0, 0x4b39, 0x7000, 0xa005, 0x00c0,
-+	0x4b39, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200,
-+	0x0d7f, 0x2049, 0x4b78, 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031,
-+	0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
-+	0x7003, 0x0001, 0x0040, 0x4b97, 0x8000, 0x80ac, 0x53a5, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b99, 0x0c7f, 0x2049,
-+	0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
-+	0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040,
-+	0x4bc0, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4bc0, 0x7804, 0xa005,
-+	0x0040, 0x4bc0, 0x7807, 0x0000, 0x0068, 0x4bc0, 0x2091, 0x4080,
-+	0x7820, 0x8001, 0x7822, 0x00c0, 0x4c1b, 0x7824, 0x7822, 0x2069,
-+	0x5140, 0x6800, 0xa084, 0x0007, 0x0040, 0x4bde, 0xa086, 0x0002,
-+	0x0040, 0x4bde, 0x6834, 0xa00d, 0x0040, 0x4bde, 0x2104, 0xa005,
-+	0x0040, 0x4bde, 0x8001, 0x200a, 0x0040, 0x4cc3, 0x7848, 0xa005,
-+	0x0040, 0x4bec, 0x8001, 0x784a, 0x00c0, 0x4bec, 0x2009, 0x0102,
-+	0x6844, 0x200a, 0x1078, 0x21d2, 0x6890, 0xa005, 0x0040, 0x4bf8,
-+	0x8001, 0x6892, 0x00c0, 0x4bf8, 0x686f, 0x0000, 0x6873, 0x0001,
-+	0x2061, 0x5400, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034, 0xa005,
-+	0x0040, 0x4c0e, 0x8001, 0x6036, 0x00c0, 0x4c0e, 0x6010, 0xa005,
-+	0x0040, 0x4c0e, 0x017e, 0x1078, 0x21d2, 0x017f, 0xace0, 0x0010,
-+	0x0070, 0x4c14, 0x0078, 0x4bfe, 0x8109, 0x0040, 0x4c1b, 0x20a9,
-+	0x0100, 0x0078, 0x4bfe, 0x1078, 0x4c28, 0x1078, 0x4c4d, 0x2009,
-+	0x5151, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001, 0x007c,
-+	0x7834, 0x8001, 0x7836, 0x00c0, 0x4c4c, 0x7838, 0x7836, 0x2091,
-+	0x8000, 0x7844, 0xa005, 0x00c0, 0x4c37, 0x2001, 0x0101, 0x8001,
-+	0x7846, 0xa080, 0x7400, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c,
-+	0x6024, 0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x0040, 0x4c7c,
-+	0x6000, 0x2c40, 0x0078, 0x4c3d, 0x007c, 0x7828, 0x8001, 0x782a,
-+	0x00c0, 0x4c7b, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x4c5a,
-+	0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003,
-+	0xa090, 0x5400, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040,
-+	0x4c7b, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4c73, 0x8001,
-+	0x2012, 0x00c0, 0x4c7b, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080,
-+	0x201a, 0x1078, 0x21d2, 0x007c, 0x2069, 0x5140, 0x6800, 0xa005,
-+	0x0040, 0x4c86, 0x6848, 0xac06, 0x0040, 0x4cc3, 0x601b, 0x0006,
-+	0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-+	0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078, 0x1973,
-+	0x6818, 0xa005, 0x0040, 0x4c9e, 0x8001, 0x681a, 0x6808, 0xa084,
-+	0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4ca8, 0x1078, 0x23eb,
-+	0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x1c70,
-+	0x2069, 0x5140, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006, 0x686e,
-+	0x00c0, 0x4cbe, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078, 0x21cd,
-+	0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5140, 0x2104,
-+	0xa084, 0x0007, 0x0040, 0x4d1f, 0xa086, 0x0007, 0x00c0, 0x4cd9,
-+	0x0d7e, 0x2009, 0x5152, 0x216c, 0x1078, 0x3a4e, 0x0d7f, 0x0078,
-+	0x4d1f, 0x2009, 0x5152, 0x2164, 0x1078, 0x2396, 0x601b, 0x0006,
-+	0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-+	0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, 0xa084,
-+	0x0040, 0x0040, 0x4d13, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-+	0xa084, 0x0004, 0x0040, 0x4d00, 0x0070, 0x4d00, 0x0078, 0x4cf7,
-+	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
-+	0x4d0d, 0x0070, 0x4d0d, 0x0078, 0x4d04, 0x20a9, 0x00fa, 0x0070,
-+	0x4d13, 0x0078, 0x4d0f, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
-+	0x0048, 0x2009, 0x515b, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091,
-+	0x8001, 0x007c, 0x2079, 0x5100, 0x1078, 0x4d4d, 0x1078, 0x4d31,
-+	0x1078, 0x4d3f, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000,
-+	0x007c, 0x2019, 0x0003, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c,
-+	0x0040, 0x4d3c, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019,
-+	0x0039, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d4a,
-+	0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011,
-+	0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d58, 0x2019, 0x2626,
-+	0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c, 0x0020,
-+	0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014, 0x0014,
-+	0x0014, 0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000, 0x0201,
-+	0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b, 0xa201,
-+	0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c, 0x0002,
-+	0x0014, 0x98d0, 0x009e, 0x0096, 0xa202, 0x8838, 0x3806, 0x8839,
-+	0x20c3, 0x0864, 0x9884, 0x28c1, 0x9cb1, 0xa203, 0x300c, 0x2846,
-+	0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2, 0x9c90,
-+	0x9858, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3, 0x282d,
-+	0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824, 0x68c1,
-+	0x7864, 0x883e, 0x9878, 0x8576, 0x8677, 0x206b, 0x28c1, 0x9cb1,
-+	0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209, 0x2901, 0x988c,
-+	0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xc601,
-+	0xa20a, 0x856e, 0x0704, 0x9c90, 0x0014, 0xa204, 0xa300, 0x3009,
-+	0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9, 0x883f,
-+	0x08e6, 0x9890, 0xf881, 0x988b, 0xc801, 0x0014, 0xf8c1, 0x0016,
-+	0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241,
-+	0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043,
-+	0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008,
-+	0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016,
-+	0x8000, 0x2847, 0x1011, 0x98c3, 0x8000, 0xa000, 0x2802, 0x1011,
-+	0x98c9, 0x9865, 0x283e, 0x1011, 0x98cd, 0xa20b, 0x0017, 0x300c,
-+	0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98da, 0x0014, 0x26e0,
-+	0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210,
-+	0x9cb6, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e,
-+	0x00a5, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd5, 0x8772,
-+	0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd8, 0x9859, 0xd984,
-+	0xf0e2, 0xf0a1, 0x98d2, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f,
-+	0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2,
-+	0x78e4, 0x9cd8, 0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101,
-+	0x98cb, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001,
-+	0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd5, 0x2001, 0x98ca, 0x8201,
-+	0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8,
-+	0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cc1, 0x692a, 0x6902,
-+	0x1834, 0x989d, 0x1a14, 0x8010, 0x8592, 0x8026, 0x84b9, 0x7021,
-+	0x0014, 0xa300, 0x69e1, 0x9caa, 0x694c, 0xa213, 0x9cba, 0x1462,
-+	0xa213, 0x8000, 0x16e1, 0x98b4, 0x8023, 0x16e1, 0x8001, 0x10f1,
-+	0x0016, 0x6968, 0xa214, 0x9cba, 0x8004, 0x16e1, 0x0101, 0x300a,
-+	0x8827, 0x0014, 0x9cba, 0x0014, 0x61c2, 0x8002, 0x14e1, 0x0016,
-+	0xa217, 0x9cc1, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6,
-+	0x882c, 0x0016, 0xa212, 0x9cd5, 0x10d2, 0x70e4, 0x0004, 0x8007,
-+	0x9424, 0xcc1a, 0x9cd8, 0x98ca, 0x8827, 0x300a, 0x0013, 0x8000,
-+	0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e,
-+	0x0016, 0xa21c, 0x1035, 0x9891, 0xa210, 0xa000, 0x8010, 0x8592,
-+	0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ef, 0x8021, 0x3807,
-+	0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x9891, 0x0000, 0x0020,
-+	0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014, 0x98e5,
-+	0x98d0, 0x0014, 0x0014, 0x0014, 0x0080, 0x013f, 0x0000, 0x0201,
-+	0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b, 0xa201,
-+	0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202, 0x8838, 0x3806,
-+	0x8839, 0x20c3, 0x0864, 0xa82e, 0x28c1, 0x9cb1, 0xa203, 0x300c,
-+	0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804, 0x28f2,
-+	0x9c90, 0xa8f4, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3,
-+	0x282d, 0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824,
-+	0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677, 0x206b, 0x28c1,
-+	0x9cb1, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e5, 0xa209, 0x2901,
-+	0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2,
-+	0xc601, 0xa20a, 0x856e, 0x0704, 0x9c90, 0x0014, 0xa204, 0xa300,
-+	0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9,
-+	0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec, 0xc801, 0x0014, 0xf8c1,
-+	0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532,
-+	0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208,
-+	0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041,
-+	0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822,
-+	0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc, 0x8000, 0xa000, 0x2802,
-+	0x1011, 0xa8fd, 0xa898, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017,
-+	0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014,
-+	0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806,
-+	0x0210, 0x9cb6, 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211,
-+	0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d6e,
-+	0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa871, 0x0014, 0x8831, 0xd166,
-+	0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301,
-+	0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820, 0xa8e6, 0xf123,
-+	0xf142, 0xf101, 0xa854, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c,
-+	0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d6b, 0x2001,
-+	0xa845, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801,
-+	0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d57,
-+	0x692a, 0x6902, 0x1834, 0xa805, 0x1a14, 0x8010, 0x8592, 0x8026,
-+	0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d40, 0x694c, 0xa213,
-+	0x9d50, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80a, 0x8023, 0x16e1,
-+	0x8001, 0x10f1, 0x0016, 0x6968, 0xa214, 0x9d50, 0x8004, 0x16e1,
-+	0x0101, 0x300a, 0x8827, 0x0014, 0x9d50, 0x0014, 0x61c2, 0x8002,
-+	0x14e1, 0x0016, 0xa217, 0x9d57, 0x0014, 0xa300, 0x8181, 0x842a,
-+	0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9d6b, 0x10d2, 0x70e4,
-+	0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d6e, 0xa8f8, 0x8827, 0x300a,
-+	0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d,
-+	0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8af, 0xa210, 0x3807,
-+	0x300c, 0x817e, 0x872b, 0x8772, 0xa8a8, 0x0000, 0xdf21
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_1080.h	2003-07-19 17:06:32.000000000 -0700
-@@ -0,0 +1,4554 @@
-+/* @(#)asm_1080.h 1.2 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+#ifndef	ISP_TARGET_MODE
-+/************************************************************************
-+ *									*
-+ *	 --- ISP1240/ISP1080/ISP1280 Initiator Firmware ---		*
-+ *			      32 LUN Support				*
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 8.15.00 (14:35 Aug 22, 2000)
-+ */
-+static const u_int16_t isp_1080_risc_code[] = {
-+	0x0078, 0x1041, 0x0000, 0x3d3b, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
-+	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
-+	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
-+	0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-+	0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043,
-+	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
-+	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-+	0x2400, 0x20c9, 0x97ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
-+	0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
-+	0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
-+	0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071,
-+	0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078,
-+	0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3,
-+	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
-+	0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000,
-+	0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64,
-+	0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114,
-+	0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0,
-+	0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080,
-+	0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128,
-+	0xa1a2, 0x4e00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-+	0xa192, 0x9800, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x207a,
-+	0x2218, 0x2079, 0x4e00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
-+	0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400,
-+	0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001,
-+	0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100,
-+	0x0d7e, 0x2069, 0x4e40, 0x1078, 0x4cdd, 0x0d7f, 0x7810, 0xc0ed,
-+	0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004,
-+	0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816,
-+	0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4e40, 0x1078,
-+	0x4cdd, 0x2069, 0x4e80, 0x2071, 0x0100, 0x1078, 0x4cdd, 0x7814,
-+	0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816,
-+	0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800,
-+	0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002,
-+	0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4e40, 0x681b, 0x0003,
-+	0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028,
-+	0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000,
-+	0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4ec0, 0x2079,
-+	0x4e00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
-+	0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a,
-+	0x68d7, 0x732d, 0x68c7, 0x53c0, 0x68cb, 0x52c0, 0x68cf, 0x93c0,
-+	0x68ab, 0x9644, 0x68af, 0x9649, 0x68b3, 0x9644, 0x68b7, 0x9644,
-+	0x68a7, 0x0001, 0x2069, 0x4e80, 0x0078, 0x111e, 0x68d3, 0x000a,
-+	0x68c3, 0x50c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
-+	0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x73c0, 0x68cb, 0x5340,
-+	0x68cf, 0x94d0, 0x68ab, 0x9649, 0x68af, 0x964e, 0x68b3, 0x9649,
-+	0x68b7, 0x9649, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
-+	0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x52c0, 0x2071,
-+	0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021,
-+	0x000c, 0x1078, 0x2009, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
-+	0x000a, 0x1078, 0x2009, 0x2069, 0x5340, 0x2071, 0x0100, 0x70ec,
-+	0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
-+	0x2009, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
-+	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
-+	0x2069, 0x52c0, 0x1078, 0x2009, 0x2069, 0x5340, 0x1078, 0x2009,
-+	0x0078, 0x11db, 0x2069, 0x52c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
-+	0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
-+	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
-+	0x1078, 0x2009, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x53c0, 0x2009,
-+	0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8,
-+	0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064,
-+	0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
-+	0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204,
-+	0x2069, 0x73c0, 0x0078, 0x11df, 0x1078, 0x265b, 0x1078, 0x468e,
-+	0x1078, 0x1dd4, 0x1078, 0x4c6f, 0x2091, 0x2100, 0x2079, 0x4e00,
-+	0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a,
-+	0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4e00, 0x2071, 0x0020,
-+	0x2091, 0x2300, 0x2079, 0x4e00, 0x7810, 0xd0ec, 0x0040, 0x122c,
-+	0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4e40,
-+	0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4e80, 0x2091, 0x2000,
-+	0x2079, 0x4e00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
-+	0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086,
-+	0x0002, 0x00c0, 0x124d, 0x1078, 0x15ba, 0x2039, 0x0000, 0x7810,
-+	0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0,
-+	0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
-+	0x2395, 0x1078, 0x20a1, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
-+	0x126b, 0x1078, 0x2395, 0x0068, 0x1278, 0x2009, 0x4e47, 0x2011,
-+	0x4e87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f0a,
-+	0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
-+	0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4,
-+	0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000, 0x2091,
-+	0x303d, 0x0068, 0x129d, 0x2079, 0x4e00, 0x786c, 0xa065, 0x0040,
-+	0x129d, 0x2071, 0x0010, 0x1078, 0x2395, 0x00e0, 0x12a5, 0x2079,
-+	0x4e00, 0x2071, 0x0010, 0x1078, 0x4a43, 0x2071, 0x4e80, 0x70a4,
-+	0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079,
-+	0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078,
-+	0x2b6a, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4e00, 0x2071,
-+	0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078,
-+	0x2395, 0x00e0, 0x1253, 0x1078, 0x4a43, 0x0078, 0x1253, 0x1078,
-+	0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c,
-+	0xa065, 0x0040, 0x12dd, 0x1078, 0x2395, 0x1078, 0x20a1, 0x0068,
-+	0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x2395, 0x0068,
-+	0x12f1, 0x2009, 0x4e47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
-+	0x1f0a, 0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
-+	0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000,
-+	0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000,
-+	0x2091, 0x303d, 0x2079, 0x4e00, 0x2071, 0x0010, 0x0068, 0x1316,
-+	0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x2395, 0x00e0, 0x12cf,
-+	0x1078, 0x4a43, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
-+	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
-+	0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e,
-+	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
-+	0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e,
-+	0x127e, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
-+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8,
-+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
-+	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
-+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300,
-+	0x1078, 0x298a, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f,
-+	0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396,
-+	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396,
-+	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af,
-+	0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af,
-+	0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e,
-+	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
-+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5,
-+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e,
-+	0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069,
-+	0x4e40, 0x2079, 0x4e00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
-+	0x4cdd, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
-+	0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0,
-+	0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003,
-+	0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x296b,
-+	0x2091, 0x2200, 0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078,
-+	0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x2091, 0x2200,
-+	0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x007c,
-+	0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427,
-+	0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427,
-+	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
-+	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
-+	0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078,
-+	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
-+	0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091,
-+	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
-+	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
-+	0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x2091, 0x2400,
-+	0x1078, 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
-+	0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4e00,
-+	0x2071, 0x0200, 0x2069, 0x4e40, 0x3d00, 0xd08c, 0x0040, 0x1466,
-+	0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4cdd, 0x3d00, 0xd084,
-+	0x0040, 0x1474, 0x2069, 0x4e80, 0x2071, 0x0100, 0x70ec, 0xa084,
-+	0x1c00, 0x78e6, 0x1078, 0x4cdd, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
-+	0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007,
-+	0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489,
-+	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15bd, 0x0068, 0x1513,
-+	0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x1513, 0x7828, 0xa005,
-+	0x00c0, 0x149e, 0x0010, 0x1514, 0x0078, 0x1513, 0x7910, 0xd1f4,
-+	0x0040, 0x14a6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x7914, 0xd1ec,
-+	0x0040, 0x14c1, 0xd0fc, 0x0040, 0x14b7, 0x007e, 0x1078, 0x1d64,
-+	0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, 0x15bc, 0x007e,
-+	0x1078, 0x1d54, 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078,
-+	0x15bc, 0x7910, 0xd0fc, 0x00c0, 0x14cb, 0x2061, 0x4e40, 0xc19c,
-+	0xc7fc, 0x0078, 0x14cf, 0x2061, 0x4e80, 0xc19d, 0xc7fd, 0x6064,
-+	0xa005, 0x00c0, 0x1513, 0x7912, 0x6083, 0x0000, 0x7828, 0xc0fc,
-+	0xa086, 0x0018, 0x00c0, 0x14e0, 0x0c7e, 0x1078, 0x1b5b, 0x0c7f,
-+	0x782b, 0x0000, 0x607c, 0xa065, 0x0040, 0x14f9, 0x0c7e, 0x609c,
-+	0x1078, 0x1e49, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c84, 0x2009,
-+	0x0018, 0x6087, 0x0103, 0x1078, 0x1d74, 0x00c0, 0x150d, 0x1078,
-+	0x1dc6, 0x7810, 0xd09c, 0x00c0, 0x1501, 0x2061, 0x4e40, 0x0078,
-+	0x1505, 0x2061, 0x4e80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4,
-+	0xd0dc, 0x0040, 0x1511, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078,
-+	0x15bc, 0x0078, 0x15ba, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x151c,
-+	0x2001, 0x4007, 0x0078, 0x15bc, 0xa006, 0x70c2, 0x70c6, 0x70ca,
-+	0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x152a,
-+	0x0079, 0x1531, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15c8, 0x0079,
-+	0x1571, 0x15ba, 0x1610, 0x15d9, 0x1648, 0x1680, 0x1680, 0x15d0,
-+	0x1c9c, 0x168b, 0x15c8, 0x15dd, 0x15df, 0x15e1, 0x15e3, 0x1ca1,
-+	0x15c8, 0x1699, 0x16f6, 0x1b7b, 0x1c96, 0x15e5, 0x19c0, 0x1a02,
-+	0x1a3d, 0x1a8e, 0x197b, 0x1988, 0x199c, 0x19af, 0x17cb, 0x15c8,
-+	0x172d, 0x173a, 0x1746, 0x1752, 0x1768, 0x1774, 0x1777, 0x1783,
-+	0x178f, 0x1797, 0x17b3, 0x17bf, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x17d8, 0x17ea, 0x1806, 0x183c, 0x1864, 0x1874, 0x1877, 0x18a8,
-+	0x18d9, 0x18eb, 0x194a, 0x195a, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x196a, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x1cc6, 0x1ccc,
-+	0x15c8, 0x15c8, 0x15c8, 0x1cd0, 0x1d15, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x160a, 0x167a, 0x1693, 0x16f0, 0x1b75, 0x15c8, 0x15c8,
-+	0x1b3e, 0x15c8, 0x1d19, 0x1cb8, 0x1cc2, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-+	0x15c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15bc, 0x73ce,
-+	0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15bd, 0x2061,
-+	0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c,
-+	0x70c3, 0x4001, 0x0078, 0x15bd, 0x70c3, 0x4006, 0x0078, 0x15bd,
-+	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
-+	0x15ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15ba, 0x0078,
-+	0x15ba, 0x0078, 0x15ba, 0x0078, 0x15ba, 0x2091, 0x8000, 0x70c3,
-+	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
-+	0x0008, 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001,
-+	0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445,
-+	0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080,
-+	0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1613,
-+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
-+	0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
-+	0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15ba, 0xa182,
-+	0x0040, 0x00c8, 0x162d, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012,
-+	0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1634,
-+	0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, 0x1642, 0x70c3, 0x4002,
-+	0x0078, 0x15bd, 0x24a8, 0x53a5, 0x0078, 0x1624, 0x0078, 0x15ba,
-+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098,
-+	0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e,
-+	0x7422, 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040,
-+	0x15ba, 0xa182, 0x0040, 0x00c8, 0x1667, 0x2120, 0xa006, 0x2008,
-+	0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc,
-+	0x0040, 0x166e, 0xa084, 0x01e0, 0x0040, 0x165c, 0x70c3, 0x4002,
-+	0x0078, 0x15bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x164b,
-+	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1688, 0x200a,
-+	0x72ca, 0x0078, 0x15b9, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf,
-+	0x0000, 0x0078, 0x15ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
-+	0x169c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
-+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16eb, 0xa40a,
-+	0x0040, 0x16ac, 0x00c8, 0x16b5, 0x8001, 0x7872, 0xa084, 0xfc00,
-+	0x0040, 0x16b9, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078,
-+	0x15bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00,
-+	0x0040, 0x16d1, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f,
-+	0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078,
-+	0x16db, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
-+	0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
-+	0x0040, 0x16e5, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc,
-+	0x78ae, 0x0078, 0x16ee, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15ba,
-+	0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16f9, 0x2029, 0x0000,
-+	0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce,
-+	0x74d6, 0xa005, 0x0040, 0x1728, 0xa40a, 0x0040, 0x1709, 0x00c8,
-+	0x15bc, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x1716, 0x78ac,
-+	0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15bc, 0x7a9a, 0x7b9e,
-+	0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1721, 0x7a10, 0xc2c5,
-+	0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x172b,
-+	0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x15ba, 0x2009, 0x0000, 0x786c,
-+	0xa065, 0x0040, 0x1737, 0x8108, 0x6000, 0x0078, 0x1730, 0x7ac4,
-+	0x0078, 0x15b8, 0x2009, 0x4e48, 0x210c, 0x7810, 0xd0ec, 0x00c0,
-+	0x15b9, 0x2011, 0x4e88, 0x2214, 0x0078, 0x15b8, 0x2009, 0x4e49,
-+	0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e89, 0x2214,
-+	0x0078, 0x15b8, 0x2061, 0x4e40, 0x6128, 0x622c, 0x8214, 0x8214,
-+	0x8214, 0x7810, 0xd0ec, 0x00c0, 0x1766, 0x2061, 0x4e80, 0x6328,
-+	0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15b8,
-+	0x2009, 0x4e4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011,
-+	0x4e8c, 0x2214, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x2009,
-+	0x4e4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e8d,
-+	0x2214, 0x0078, 0x15b8, 0x2009, 0x4e4e, 0x210c, 0x7810, 0xd0ec,
-+	0x00c0, 0x15b9, 0x2011, 0x4e8e, 0x2214, 0x0078, 0x15b8, 0x7920,
-+	0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x7a24, 0x0078, 0x15b8, 0x71c4,
-+	0xd1fc, 0x00c0, 0x179f, 0x2011, 0x52c0, 0x0078, 0x17a1, 0x2011,
-+	0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
-+	0x6a00, 0x6804, 0xd09c, 0x0040, 0x17b0, 0x6b08, 0x0078, 0x17b1,
-+	0x6b0c, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-+	0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b7, 0x2061,
-+	0x4e40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80,
-+	0x6218, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-+	0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15b7,
-+	0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b2,
-+	0x1078, 0x277f, 0xa384, 0x4000, 0x0040, 0x17e8, 0xa295, 0x0020,
-+	0x0078, 0x15b7, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
-+	0x15b2, 0xd1bc, 0x00c0, 0x17f9, 0x2011, 0x4e48, 0x2204, 0x0078,
-+	0x17fd, 0x2011, 0x4e88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
-+	0x2012, 0x1078, 0x26dc, 0x017f, 0x0078, 0x15b9, 0x71c4, 0x2021,
-+	0x4e49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1815, 0x71c8,
-+	0x2021, 0x4e89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1834, 0x20a9,
-+	0x0008, 0x2204, 0xa106, 0x0040, 0x1824, 0x8210, 0x00f0, 0x1819,
-+	0x71c4, 0x72c8, 0x0078, 0x15b1, 0xa292, 0x1834, 0x027e, 0x2122,
-+	0x017f, 0x1078, 0x26fd, 0x7810, 0xd0ec, 0x00c0, 0x1832, 0xd3fc,
-+	0x0040, 0x180f, 0x0078, 0x15ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
-+	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4e40, 0x6128, 0x622c,
-+	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
-+	0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1862, 0x027e, 0x017e,
-+	0x2061, 0x4e80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
-+	0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
-+	0x017f, 0x027f, 0x0078, 0x15b8, 0x2061, 0x4e40, 0x6130, 0x70c4,
-+	0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80, 0x6230,
-+	0x70c8, 0x6032, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x71c4,
-+	0xa184, 0xffcf, 0x0040, 0x1883, 0x7810, 0xd0ec, 0x00c0, 0x15b2,
-+	0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4d, 0x2204, 0x2112, 0x007e,
-+	0x2019, 0x0000, 0x1078, 0x2764, 0x7810, 0xd0ec, 0x0040, 0x1893,
-+	0x017f, 0x0078, 0x15b9, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x189c,
-+	0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8d, 0x2204, 0x2112,
-+	0x007e, 0xc3fd, 0x1078, 0x2764, 0x027f, 0x017f, 0x0078, 0x15b8,
-+	0x71c4, 0xa182, 0x0010, 0x0048, 0x18b4, 0x7810, 0xd0ec, 0x00c0,
-+	0x15b2, 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4e, 0x2204, 0x007e,
-+	0x2112, 0x2019, 0x0000, 0x1078, 0x2742, 0x7810, 0xd0ec, 0x0040,
-+	0x18c4, 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa182, 0x0010, 0x0048,
-+	0x18cd, 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8e, 0x2204,
-+	0x007e, 0x2112, 0xc3fd, 0x1078, 0x2742, 0x027f, 0x017f, 0x0078,
-+	0x15b8, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b1, 0xa284,
-+	0xfffd, 0x00c0, 0x15b1, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
-+	0x7826, 0x0078, 0x15b8, 0x71c4, 0xd1fc, 0x00c0, 0x18f3, 0x2011,
-+	0x52c0, 0x0078, 0x18f5, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0x2091,
-+	0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x191e, 0x6a02, 0xd4ec,
-+	0x0040, 0x190b, 0xc3a5, 0xd4e4, 0x0040, 0x190f, 0xc39d, 0xd4f4,
-+	0x0040, 0x191e, 0x810f, 0xd2f4, 0x0040, 0x191a, 0x1078, 0x27c1,
-+	0x0078, 0x191e, 0x1078, 0x279f, 0x0078, 0x191e, 0x72cc, 0x6808,
-+	0xa206, 0x0040, 0x1940, 0xa2a4, 0x00ff, 0x7814, 0xd0e4, 0x00c0,
-+	0x1931, 0xa482, 0x0028, 0x0048, 0x193d, 0x0040, 0x193d, 0x0078,
-+	0x1935, 0xa482, 0x0043, 0x0048, 0x193d, 0x71c4, 0x71c6, 0x027f,
-+	0x72ca, 0x2091, 0x8001, 0x0078, 0x15b3, 0x6a0a, 0xa39d, 0x000a,
-+	0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x2091, 0x8001,
-+	0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a14,
-+	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
-+	0x0078, 0x15b7, 0x70c4, 0x2061, 0x4e40, 0x6118, 0x601a, 0x7810,
-+	0xd0ec, 0x00c0, 0x15b9, 0x70c8, 0x2061, 0x4e80, 0x6218, 0x601a,
-+	0x0078, 0x15b8, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8,
-+	0x15b2, 0x1078, 0x27e3, 0xa384, 0x4000, 0x0040, 0x1979, 0xa295,
-+	0x0020, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-+	0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8,
-+	0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
-+	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1997, 0x1078, 0x2628, 0x2091,
-+	0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091,
-+	0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19aa,
-+	0x1078, 0x2628, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4,
-+	0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
-+	0x1078, 0x1dff, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x15b8,
-+	0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19d4, 0xd7fc, 0x0040, 0x19ce,
-+	0x1078, 0x1d64, 0x0040, 0x19d4, 0x0078, 0x15bc, 0x1078, 0x1d54,
-+	0x0040, 0x19d4, 0x0078, 0x15bc, 0x73c8, 0x72cc, 0x77c6, 0x73ca,
-+	0x72ce, 0x1078, 0x1e86, 0x00c0, 0x19fe, 0x6818, 0xa005, 0x0040,
-+	0x19f8, 0x2708, 0x077e, 0x1078, 0x2813, 0x077f, 0x00c0, 0x19f8,
-+	0x2001, 0x0015, 0xd7fc, 0x00c0, 0x19f1, 0x2061, 0x4e40, 0x0078,
-+	0x19f4, 0xc0fd, 0x2061, 0x4e80, 0x782a, 0x2091, 0x8001, 0x007c,
-+	0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15bc, 0x2091, 0x8001,
-+	0x0078, 0x15ba, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x1a16, 0xd7fc,
-+	0x0040, 0x1a10, 0x1078, 0x1d64, 0x0040, 0x1a16, 0x0078, 0x15bc,
-+	0x1078, 0x1d54, 0x0040, 0x1a16, 0x0078, 0x15bc, 0x77c6, 0x2041,
-+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-+	0x1dff, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a2a, 0x2061, 0x4e40,
-+	0x0078, 0x1a2d, 0x2061, 0x4e80, 0xc1fd, 0x6067, 0x0003, 0x607f,
-+	0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6,
-+	0x1078, 0x2628, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca, 0x77c4,
-+	0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a54, 0xd7fc, 0x0040, 0x1a4e,
-+	0x1078, 0x1d64, 0x0040, 0x1a54, 0x0078, 0x15bc, 0x1078, 0x1d54,
-+	0x0040, 0x1a54, 0x0078, 0x15bc, 0xa7bc, 0xff00, 0x2091, 0x8000,
-+	0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a61, 0x2061, 0x4e40, 0x0078,
-+	0x1a64, 0x2061, 0x4e80, 0xc1fd, 0x607f, 0x0000, 0x6067, 0x0002,
-+	0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6, 0x1078,
-+	0x2628, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
-+	0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040, 0x1a82, 0x60d4,
-+	0xc0fd, 0x60d6, 0x1078, 0x1dff, 0x70c8, 0x6836, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x1a82, 0x2091, 0x8001, 0x007c, 0x2019, 0x0000,
-+	0x7814, 0xd0e4, 0x00c0, 0x1aa4, 0x72c8, 0xd284, 0x0040, 0x1a9e,
-+	0x1078, 0x1d64, 0x0040, 0x1aa4, 0x0078, 0x15bc, 0x1078, 0x1d54,
-+	0x0040, 0x1aa4, 0x0078, 0x15bc, 0x72c8, 0x72ca, 0x78ac, 0xa084,
-+	0x0003, 0x00c0, 0x1acf, 0x2039, 0x0000, 0xd284, 0x0040, 0x1ab1,
-+	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
-+	0x1de4, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091,
-+	0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ab7, 0xa7bc, 0xff00,
-+	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ab7, 0x2091,
-+	0x8000, 0x72c8, 0xd284, 0x00c0, 0x1ae1, 0x7810, 0xd0ec, 0x0040,
-+	0x1add, 0x2069, 0x0100, 0x0078, 0x1ae3, 0x2069, 0x0200, 0x0078,
-+	0x1ae3, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830,
-+	0xd0b4, 0x0040, 0x1b03, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-+	0xd094, 0x0040, 0x1af5, 0x00f0, 0x1aef, 0x684b, 0x0009, 0x20a9,
-+	0x0014, 0x6848, 0xd084, 0x0040, 0x1aff, 0x00f0, 0x1af9, 0x20a9,
-+	0x00fa, 0x00f0, 0x1b01, 0x2079, 0x4e00, 0x2009, 0x0018, 0x72c8,
-+	0xd284, 0x00c0, 0x1b0f, 0x2061, 0x4e40, 0x0078, 0x1b12, 0x2061,
-+	0x4e80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067, 0x0001, 0x6083,
-+	0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4,
-+	0x0040, 0x1b2e, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008,
-+	0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084,
-+	0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0040, 0x1b39,
-+	0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c, 0x73cc, 0x1078,
-+	0x1a90, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a, 0xa185, 0x0040,
-+	0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff, 0x00f0, 0x1b4e,
-+	0x8421, 0x00c0, 0x1b4c, 0x8319, 0x00c0, 0x1b4a, 0x69ee, 0x6a4a,
-+	0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b62, 0x2069, 0x4e40,
-+	0x0078, 0x1b64, 0x2069, 0x4e80, 0x71c4, 0x71c6, 0x6916, 0x81ff,
-+	0x00c0, 0x1b6c, 0x68a7, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
-+	0x00c0, 0x1b74, 0x1078, 0x1ee6, 0x007c, 0x75d8, 0x74dc, 0x75da,
-+	0x74de, 0x0078, 0x1b7e, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8,
-+	0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4e00, 0x7dde, 0x7cda,
-+	0x7bd6, 0x7ad2, 0x1078, 0x1dbd, 0x0040, 0x1c80, 0x20a9, 0x0005,
-+	0x20a1, 0x4e14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009,
-+	0x0040, 0x1078, 0x1fd1, 0x0040, 0x1ba1, 0x1078, 0x1dc6, 0x0078,
-+	0x1c80, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, 0x1bac,
-+	0x007e, 0x1078, 0x2378, 0x007f, 0xa084, 0xff00, 0x8007, 0x8009,
-+	0x0040, 0x1c20, 0x0c7e, 0x2c68, 0x1078, 0x1dbd, 0x0040, 0x1bf2,
-+	0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bb3, 0x609f, 0x0000, 0x0c7f,
-+	0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399,
-+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6,
-+	0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c1f, 0x2009, 0x0040,
-+	0x1078, 0x1fd1, 0x00c0, 0x1c09, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0002, 0x00c0, 0x1bf2, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a,
-+	0x00c0, 0x1bee, 0x017e, 0x1078, 0x2374, 0x017f, 0x2d00, 0x6002,
-+	0x0078, 0x1bc1, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f,
-+	0x609f, 0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6008, 0xc0cd,
-+	0x600a, 0x6004, 0x6086, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078,
-+	0x1c80, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f, 0x609f,
-+	0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b,
-+	0x0003, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078, 0x1c80, 0x0c7f,
-+	0x7814, 0xd0e4, 0x00c0, 0x1c45, 0x6114, 0xd1fc, 0x0040, 0x1c2e,
-+	0x1078, 0x1d64, 0x0040, 0x1c45, 0x0078, 0x1c32, 0x1078, 0x1d54,
-+	0x0040, 0x1c45, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, 0x73c8,
-+	0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, 0x1d74, 0x1078,
-+	0x1dc6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x74c4, 0x73c8, 0x72cc,
-+	0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, 0xd0fc, 0x00c0,
-+	0x1c55, 0x2071, 0x4e40, 0x0078, 0x1c58, 0x2071, 0x4e80, 0xc1fd,
-+	0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6, 0x736a, 0x726e,
-+	0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530,
-+	0x611c, 0xa184, 0x0060, 0x0040, 0x1c6f, 0x1078, 0x4632, 0x0e7f,
-+	0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000,
-+	0x6714, 0x6023, 0x0000, 0x1078, 0x2628, 0x2091, 0x8001, 0x007c,
-+	0x70c3, 0x4005, 0x0078, 0x15bd, 0x20a9, 0x0005, 0x2099, 0x4e14,
-+	0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399,
-+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7,
-+	0x0000, 0x791e, 0x0078, 0x15ba, 0x71c4, 0x71c6, 0x2168, 0x0078,
-+	0x1ca3, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68,
-+	0x8109, 0x00c0, 0x1ca5, 0xa285, 0x0000, 0x00c0, 0x1cb3, 0x70c3,
-+	0x4000, 0x0078, 0x1cb5, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x15bd,
-+	0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b2, 0x7966,
-+	0x0078, 0x15ba, 0x7964, 0x71c6, 0x0078, 0x15ba, 0x7900, 0x71c6,
-+	0x71c4, 0x7902, 0x0078, 0x15ba, 0x7900, 0x71c6, 0x0078, 0x15ba,
-+	0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1ce5, 0x810c,
-+	0x0048, 0x1ce1, 0x8210, 0x810c, 0x810c, 0x0048, 0x1ce1, 0x8210,
-+	0x810c, 0x81ff, 0x00c0, 0x15b3, 0x8210, 0x7a0e, 0xd28c, 0x0040,
-+	0x1d11, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003,
-+	0xd284, 0x0040, 0x1d0b, 0x8108, 0x2019, 0x0041, 0x2011, 0x964e,
-+	0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210,
-+	0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210,
-+	0x2312, 0x2019, 0x0006, 0x2011, 0x9653, 0x2112, 0x2011, 0x9673,
-+	0x2312, 0x7904, 0x7806, 0x0078, 0x15b9, 0x7804, 0x70c6, 0x0078,
-+	0x15ba, 0x71c4, 0xd1fc, 0x00c0, 0x1d21, 0x2011, 0x52c0, 0x0078,
-+	0x1d23, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d32, 0x2011, 0x0001,
-+	0x0078, 0x1d34, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da, 0x0078,
-+	0x15b7, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d46, 0x2001, 0x4007,
-+	0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d52, 0xd0fc, 0x0040,
-+	0x1d51, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
-+	0x1d52, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040,
-+	0x1d61, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078,
-+	0x1d62, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040,
-+	0x1d71, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
-+	0x1d72, 0xa006, 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810,
-+	0xd0c4, 0x0040, 0x1d7d, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
-+	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
-+	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040,
-+	0x1d9a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
-+	0x0078, 0x1d9d, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
-+	0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1daa, 0x7b84, 0xa319,
-+	0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1daa, 0x7003, 0x0001,
-+	0x7007, 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dba,
-+	0x7322, 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040,
-+	0x1dc5, 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079,
-+	0x4e00, 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1dd1, 0x1078,
-+	0x296b, 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9800, 0x7a4a, 0x7bc4,
-+	0x8319, 0x0040, 0x1de1, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078,
-+	0x1dd8, 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0,
-+	0x1ded, 0x2011, 0x53c0, 0x0078, 0x1def, 0x2011, 0x73c0, 0xa784,
-+	0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x1dfa, 0x8003, 0x8003,
-+	0x8003, 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078,
-+	0x1de4, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef,
-+	0xa80d, 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e14, 0x2009, 0x4e53,
-+	0x2071, 0x4e40, 0x0078, 0x1e18, 0x2009, 0x4e93, 0x2071, 0x4e80,
-+	0x210c, 0x6804, 0xa005, 0x0040, 0x1e28, 0xa116, 0x00c0, 0x1e28,
-+	0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e2b,
-+	0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e40, 0x6000,
-+	0x6806, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x6810, 0x7908, 0x8109,
-+	0x790a, 0x8001, 0x6812, 0x00c0, 0x1e2b, 0x7910, 0xc1a5, 0x7912,
-+	0x017f, 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x0e7f,
-+	0x007c, 0xa065, 0x0040, 0x1e5a, 0x2008, 0x609c, 0xa005, 0x0040,
-+	0x1e57, 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e4d, 0x7848,
-+	0x794a, 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
-+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-+	0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1e76,
-+	0x2071, 0x4e40, 0x2031, 0x4ec0, 0x0078, 0x1e7a, 0x2071, 0x4e80,
-+	0x2031, 0x50c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1e84, 0xa608,
-+	0x2d0a, 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc,
-+	0x00c0, 0x1e8e, 0x2079, 0x4e40, 0x0078, 0x1e90, 0x2079, 0x4e80,
-+	0x1078, 0x1de4, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040,
-+	0x1ee4, 0x0078, 0x1ea2, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
-+	0x0040, 0x1ee4, 0x6010, 0xa306, 0x00c0, 0x1e9b, 0x600c, 0xa206,
-+	0x00c0, 0x1e9b, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1eb1, 0x0078,
-+	0x1ee1, 0x6804, 0xac06, 0x00c0, 0x1ebf, 0x6000, 0x2060, 0x6806,
-+	0xa005, 0x00c0, 0x1ebf, 0x6803, 0x0000, 0x0078, 0x1ec9, 0x6400,
-+	0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1ec9, 0x2c00,
-+	0x6802, 0x2560, 0x0f7f, 0x1078, 0x1e5b, 0x0f7e, 0x601b, 0x0005,
-+	0x6023, 0x0020, 0x0f7f, 0x1078, 0x201d, 0x0f7e, 0x7908, 0x8109,
-+	0x790a, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1ee1, 0x7810, 0xc0a5,
-+	0x7812, 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700,
-+	0x2039, 0x0000, 0xd0fc, 0x0040, 0x1eee, 0xc7fd, 0x2041, 0x0021,
-+	0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1dff,
-+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1ef6, 0xa7bc, 0xff00, 0x873f,
-+	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ef6, 0x2091, 0x8001,
-+	0x077f, 0x007c, 0x786c, 0x2009, 0x9674, 0x210c, 0xa10d, 0x0040,
-+	0x1f14, 0xa065, 0x0078, 0x2395, 0x2061, 0x0000, 0x6018, 0xd084,
-+	0x00c0, 0x1f34, 0x7810, 0xd08c, 0x0040, 0x1f25, 0xc08c, 0x7812,
-+	0xc7fc, 0x2069, 0x4e40, 0x0078, 0x1f2a, 0xc08d, 0x7812, 0x2069,
-+	0x4e80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091,
-+	0x8001, 0xa005, 0x00c0, 0x1f35, 0x007c, 0xa08c, 0xfff0, 0x0040,
-+	0x1f3b, 0x1078, 0x296b, 0x0079, 0x1f3d, 0x1f4d, 0x1f50, 0x1f56,
-+	0x1f5a, 0x1f4e, 0x1f5e, 0x1f4e, 0x1f4e, 0x1f4e, 0x1f64, 0x1f95,
-+	0x1f99, 0x1f9f, 0x1fb4, 0x1f4e, 0x1f4e, 0x007c, 0x1078, 0x296b,
-+	0x1078, 0x1ee6, 0x2001, 0x8001, 0x0078, 0x1fc0, 0x2001, 0x8003,
-+	0x0078, 0x1fc0, 0x2001, 0x8004, 0x0078, 0x1fc0, 0x1078, 0x1ee6,
-+	0x2001, 0x8006, 0x0078, 0x1fc0, 0x2091, 0x8000, 0x077e, 0xd7fc,
-+	0x00c0, 0x1f70, 0x2069, 0x4e40, 0x2039, 0x0009, 0x0078, 0x1f74,
-+	0x2069, 0x4e80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040,
-+	0x1f7e, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f,
-+	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-+	0x1078, 0x1dff, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f88, 0x2091,
-+	0x8001, 0x2001, 0x800a, 0x0078, 0x1fc0, 0x2001, 0x800c, 0x0078,
-+	0x1fc0, 0x1078, 0x1ee6, 0x2001, 0x800d, 0x0078, 0x1fc0, 0x7814,
-+	0xd0e4, 0x00c0, 0x1fb2, 0xd0ec, 0x0040, 0x1fac, 0xd7fc, 0x0040,
-+	0x1fac, 0x78e4, 0x0078, 0x1fad, 0x78e0, 0x70c6, 0x2001, 0x800e,
-+	0x0078, 0x1fc0, 0x0078, 0x1f4e, 0xd7fc, 0x0040, 0x1fba, 0x78ec,
-+	0x0078, 0x1fbb, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x1fc0,
-+	0x70c2, 0xd7fc, 0x00c0, 0x1fc8, 0x70db, 0x0000, 0x0078, 0x1fca,
-+	0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
-+	0x007c, 0xac80, 0x0001, 0x81ff, 0x0040, 0x1ffc, 0x2099, 0x0030,
-+	0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040, 0x1fde, 0x7018, 0x007e,
-+	0x701c, 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac,
-+	0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001,
-+	0x7008, 0x800b, 0x00c8, 0x1ff0, 0x7007, 0x0002, 0xa08c, 0x01e0,
-+	0x00c0, 0x1ffc, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004,
-+	0x007f, 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a,
-+	0x007c, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803,
-+	0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290,
-+	0x0004, 0x8109, 0x00c0, 0x200d, 0x007c, 0x6004, 0x6086, 0x2c08,
-+	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x202a, 0x2c02,
-+	0x0078, 0x202b, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4e00, 0x6887,
-+	0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040,
-+	0x203c, 0x2d02, 0x0078, 0x203d, 0x616e, 0x0c7f, 0x007c, 0x2091,
-+	0x8000, 0x2c04, 0x786e, 0xa005, 0x00c0, 0x2047, 0x786a, 0x2091,
-+	0x8001, 0x609c, 0xa005, 0x0040, 0x2060, 0x0c7e, 0x2060, 0x2008,
-+	0x609c, 0xa005, 0x0040, 0x205c, 0x2062, 0x609f, 0x0000, 0xa065,
-+	0x609c, 0xa005, 0x00c0, 0x2054, 0x7848, 0x794a, 0x2062, 0x0c7f,
-+	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x206a,
-+	0x1078, 0x296b, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004,
-+	0x8086, 0x818e, 0x00c8, 0x2075, 0xa200, 0x00f0, 0x2070, 0x8086,
-+	0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x209b,
-+	0xa11a, 0x00c8, 0x209b, 0x8213, 0x818d, 0x0048, 0x208e, 0xa11a,
-+	0x00c8, 0x208f, 0x00f0, 0x2083, 0x0078, 0x2093, 0xa11a, 0x2308,
-+	0x8210, 0x00f0, 0x2083, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080,
-+	0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078,
-+	0x2097, 0x7d74, 0x70d0, 0xa506, 0x0040, 0x2187, 0x7810, 0x2050,
-+	0x7800, 0xd08c, 0x0040, 0x20c3, 0xdaec, 0x0040, 0x20c3, 0x0e7e,
-+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20c0,
-+	0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x20c3, 0x0078, 0x2187,
-+	0x0e7f, 0x0078, 0x2187, 0x1078, 0x1dbd, 0x0040, 0x2187, 0xa046,
-+	0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d2,
-+	0x0078, 0x20d9, 0x72d0, 0xa206, 0x0040, 0x20d9, 0x8840, 0x2009,
-+	0x0080, 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9,
-+	0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040,
-+	0x20eb, 0x1078, 0x1dbd, 0x7008, 0xd0fc, 0x0040, 0x20eb, 0x7007,
-+	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2122, 0x53a5,
-+	0x8cff, 0x00c0, 0x2100, 0x88ff, 0x0040, 0x2171, 0x0078, 0x210a,
-+	0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5,
-+	0x0078, 0x2171, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2112,
-+	0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000,
-+	0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2122, 0x7422,
-+	0x7526, 0xa006, 0x7007, 0x0004, 0x0040, 0x2171, 0x8cff, 0x0040,
-+	0x212b, 0x1078, 0x1dc6, 0x0c7f, 0x1078, 0x1dc6, 0xa046, 0x7888,
-+	0x8000, 0x788a, 0xa086, 0x0002, 0x0040, 0x2151, 0x7a7c, 0x7b78,
-+	0xdac4, 0x0040, 0x213d, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
-+	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-+	0x721a, 0x731e, 0xdac4, 0x0040, 0x2187, 0x7422, 0x7526, 0x0078,
-+	0x2187, 0x6014, 0xd0fc, 0x00c0, 0x2159, 0x2069, 0x4e40, 0x0078,
-+	0x215b, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff,
-+	0x0040, 0x2167, 0xa046, 0x788c, 0x2060, 0x0078, 0x2151, 0x788b,
-+	0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078,
-+	0x2187, 0x0c7f, 0x788b, 0x0000, 0x1078, 0x2346, 0x6004, 0xa084,
-+	0x000f, 0x1078, 0x2188, 0x88ff, 0x0040, 0x2185, 0x788c, 0x2060,
-+	0x6004, 0xa084, 0x000f, 0x1078, 0x2188, 0x0078, 0x20a1, 0x007c,
-+	0x0079, 0x218a, 0x219a, 0x21b8, 0x21d6, 0x219a, 0x21e7, 0x21ab,
-+	0x219a, 0x219a, 0x219a, 0x21b6, 0x21d4, 0x219a, 0x219a, 0x219a,
-+	0x219a, 0x219a, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008,
-+	0xa705, 0x600a, 0x1078, 0x222a, 0x609c, 0x78ba, 0x609f, 0x0000,
-+	0x1078, 0x2330, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21b1, 0x0078,
-+	0x219a, 0x601c, 0xc0bd, 0x601e, 0x0078, 0x21be, 0x1078, 0x2378,
-+	0x78bc, 0xd0c4, 0x0040, 0x21be, 0x0078, 0x219a, 0x78bf, 0x0000,
-+	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21d1,
-+	0x1078, 0x222a, 0x0040, 0x21d1, 0x78bc, 0xc0c5, 0x78be, 0x0078,
-+	0x21d3, 0x0078, 0x2249, 0x007c, 0x1078, 0x2374, 0x78bc, 0xa08c,
-+	0x0e00, 0x00c0, 0x21de, 0xd0c4, 0x00c0, 0x21e0, 0x0078, 0x219a,
-+	0x1078, 0x222a, 0x00c0, 0x21e6, 0x0078, 0x2249, 0x007c, 0x78bc,
-+	0xd0c4, 0x0040, 0x21ed, 0x0078, 0x219a, 0x78bf, 0x0000, 0x6714,
-+	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040,
-+	0x220d, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040,
-+	0x220d, 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e,
-+	0x0002, 0x0040, 0x220d, 0x0078, 0x2227, 0x1078, 0x1de4, 0x2d00,
-+	0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084,
-+	0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2210,
-+	0x8211, 0x0040, 0x2227, 0x20a9, 0x0100, 0x0078, 0x2210, 0x1078,
-+	0x1dc6, 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6,
-+	0x00c0, 0x2235, 0x78ba, 0x0078, 0x223d, 0x689e, 0x2d00, 0x6002,
-+	0x78b8, 0xad06, 0x00c0, 0x223d, 0x6002, 0x78b0, 0x8001, 0x78b2,
-+	0x00c0, 0x2248, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006,
-+	0x007c, 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2,
-+	0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060,
-+	0x0040, 0x225c, 0x1078, 0x4632, 0x6596, 0x65a6, 0x669a, 0x66aa,
-+	0x6714, 0x2071, 0x4e80, 0xd7fc, 0x00c0, 0x2268, 0x2071, 0x4e40,
-+	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x2273, 0x8003,
-+	0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2,
-+	0x2091, 0x8000, 0x7814, 0xd0c4, 0x0040, 0x2298, 0xd0ec, 0x0040,
-+	0x2294, 0xd7fc, 0x00c0, 0x2291, 0xd0f4, 0x00c0, 0x229f, 0x0078,
-+	0x2298, 0xd0fc, 0x00c0, 0x229f, 0x7810, 0xd0f4, 0x00c0, 0x229f,
-+	0x6e08, 0xd684, 0x0040, 0x22c9, 0xd9fc, 0x00c0, 0x22c9, 0x2091,
-+	0x8001, 0x1078, 0x1e5b, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
-+	0x8001, 0x7814, 0xd0e4, 0x00c0, 0x232e, 0x7814, 0xd0c4, 0x0040,
-+	0x232e, 0xd0ec, 0x0040, 0x22c1, 0xd7fc, 0x00c0, 0x22bc, 0xd0f4,
-+	0x00c0, 0x22c5, 0x0078, 0x232e, 0xd0fc, 0x00c0, 0x22c5, 0x0078,
-+	0x232e, 0x7810, 0xd0f4, 0x0040, 0x232e, 0x601b, 0x0021, 0x0078,
-+	0x232e, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22d0, 0x8000, 0x6026,
-+	0x6a10, 0x6814, 0xa202, 0x0048, 0x22e3, 0x0040, 0x22e3, 0x2091,
-+	0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
-+	0x2330, 0x0078, 0x232e, 0x2c08, 0xd9fc, 0x0040, 0x230b, 0x6800,
-+	0xa065, 0x0040, 0x230b, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040,
-+	0x2301, 0x704c, 0xa206, 0x00c0, 0x2301, 0x6b04, 0x2160, 0x2304,
-+	0x6002, 0xa005, 0x00c0, 0x22fd, 0x6902, 0x2260, 0x6102, 0x0078,
-+	0x2317, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x6e08, 0x2160, 0x6202,
-+	0x6906, 0x0078, 0x2317, 0x6800, 0x6902, 0xa065, 0x0040, 0x2313,
-+	0x6102, 0x0078, 0x2314, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
-+	0xd9fc, 0x0040, 0x231e, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08,
-+	0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040,
-+	0x232e, 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1e6c, 0x0e7f, 0x007c,
-+	0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
-+	0x8001, 0x78b8, 0xa065, 0x0040, 0x2343, 0x609c, 0x78ba, 0x609f,
-+	0x0000, 0x0078, 0x2330, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874,
-+	0x2818, 0xd384, 0x0040, 0x2350, 0x8000, 0xa112, 0x0048, 0x2355,
-+	0x8000, 0xa112, 0x00c8, 0x2365, 0xc384, 0x7a7c, 0x721a, 0x7a78,
-+	0x721e, 0xdac4, 0x0040, 0x2360, 0x7a84, 0x7222, 0x7a80, 0x7226,
-+	0xa006, 0xd384, 0x0040, 0x2365, 0x8000, 0x7876, 0x70d2, 0x781c,
-+	0xa005, 0x0040, 0x2373, 0x8001, 0x781e, 0x00c0, 0x2373, 0x0068,
-+	0x2373, 0x2091, 0x4080, 0x007c, 0x2039, 0x238c, 0x0078, 0x237a,
-+	0x2039, 0x2392, 0x2704, 0xa005, 0x0040, 0x238b, 0xac00, 0x2068,
-+	0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e,
-+	0x8738, 0x0078, 0x237a, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015,
-+	0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c,
-+	0x0079, 0x239a, 0x256c, 0x253f, 0x239e, 0x2417, 0x2039, 0x9674,
-+	0x2734, 0x7d10, 0x0078, 0x23be, 0x6084, 0xa086, 0x0103, 0x00c0,
-+	0x2400, 0x6114, 0x6018, 0xa105, 0x0040, 0x23b3, 0x86ff, 0x00c0,
-+	0x23cf, 0x0078, 0x2400, 0x8603, 0xa080, 0x9655, 0x620c, 0x2202,
-+	0x8000, 0x6210, 0x2202, 0x1078, 0x203f, 0x8630, 0xa68e, 0x000f,
-+	0x0040, 0x248b, 0x786c, 0xa065, 0x00c0, 0x23a4, 0x7808, 0xa602,
-+	0x00c8, 0x23cf, 0xd5ac, 0x00c0, 0x23cf, 0x263a, 0x007c, 0xa682,
-+	0x0003, 0x00c8, 0x248b, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818,
-+	0xd084, 0x00c0, 0x23fb, 0x2011, 0x9655, 0x2204, 0x70c6, 0x8210,
-+	0x2204, 0x70ca, 0xd684, 0x00c0, 0x23eb, 0x8210, 0x2204, 0x70da,
-+	0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001,
-+	0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
-+	0x203b, 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x248b,
-+	0x263a, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065, 0x00c0,
-+	0x23a4, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040,
-+	0x2412, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x2599, 0x2039,
-+	0x9674, 0x2734, 0x7d10, 0x0078, 0x2433, 0x6084, 0xa086, 0x0103,
-+	0x00c0, 0x2474, 0x6114, 0x6018, 0xa105, 0x0040, 0x242c, 0x86ff,
-+	0x00c0, 0x2444, 0x0078, 0x2474, 0xa680, 0x9655, 0x620c, 0x2202,
-+	0x1078, 0x203f, 0x8630, 0xa68e, 0x001e, 0x0040, 0x248b, 0x786c,
-+	0xa065, 0x00c0, 0x241d, 0x7808, 0xa602, 0x00c8, 0x2444, 0xd5ac,
-+	0x00c0, 0x2444, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x248b,
-+	0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x246f,
-+	0x2011, 0x9655, 0x2009, 0x964e, 0x26a8, 0x211c, 0x2204, 0x201a,
-+	0x8108, 0x8210, 0x00f0, 0x2455, 0xa685, 0x8030, 0x70c2, 0x681b,
-+	0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091,
-+	0x8001, 0xa006, 0x2009, 0x9675, 0x200a, 0x203a, 0x007c, 0x7810,
-+	0xc0ad, 0x7812, 0x0078, 0x248b, 0x263a, 0x1078, 0x2576, 0x00c0,
-+	0x2599, 0x786c, 0xa065, 0x00c0, 0x241d, 0x2091, 0x8000, 0x7810,
-+	0xa084, 0xffcf, 0x86ff, 0x0040, 0x2486, 0xc0ad, 0x7812, 0x2091,
-+	0x8001, 0x0078, 0x2599, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994,
-+	0x70d4, 0xa102, 0x0048, 0x249c, 0x0040, 0x24a6, 0x7b90, 0xa302,
-+	0x00c0, 0x24a6, 0x0078, 0x249f, 0x8002, 0x00c0, 0x24a6, 0x263a,
-+	0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00,
-+	0x0040, 0x24b3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-+	0xa100, 0x0078, 0x24b6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210,
-+	0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x24c6,
-+	0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030,
-+	0x7003, 0x0000, 0x2009, 0x9654, 0x260a, 0x8109, 0x2198, 0x2104,
-+	0xd084, 0x0040, 0x24d4, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
-+	0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
-+	0x00c8, 0x24e3, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040,
-+	0x24f2, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
-+	0x0078, 0x24f5, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
-+	0xa006, 0xa211, 0xd4c4, 0x0040, 0x2501, 0x7b84, 0xa319, 0x7c80,
-+	0xa421, 0x7008, 0xd0fc, 0x0040, 0x2501, 0xa084, 0x01e0, 0x0040,
-+	0x2526, 0x7d10, 0x2031, 0x9654, 0x2634, 0x78a8, 0x8000, 0x78aa,
-+	0xd08c, 0x00c0, 0x251b, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0,
-+	0x2515, 0x0078, 0x248d, 0x2069, 0x4e47, 0x206b, 0x0003, 0x78ac,
-+	0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x252f, 0x2030, 0x75d6,
-+	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
-+	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
-+	0x721e, 0xd5c4, 0x0040, 0x253e, 0x7322, 0x7426, 0x007c, 0x6084,
-+	0xa086, 0x0103, 0x00c0, 0x2562, 0x6114, 0x6018, 0xa105, 0x00c0,
-+	0x2562, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x2562, 0x600c,
-+	0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091,
-+	0x4080, 0x1078, 0x203f, 0x0068, 0x2561, 0x786c, 0xa065, 0x00c0,
-+	0x253f, 0x007c, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065,
-+	0x00c0, 0x253f, 0x0078, 0x2599, 0x1078, 0x2576, 0x00c0, 0x2599,
-+	0x786c, 0xa065, 0x00c0, 0x256c, 0x0078, 0x2599, 0x6084, 0xa086,
-+	0x0103, 0x00c0, 0x258a, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004,
-+	0x00c0, 0x258a, 0x7804, 0xd0a4, 0x0040, 0x258a, 0x1078, 0x203f,
-+	0xa006, 0x007c, 0x1078, 0x259f, 0x00c0, 0x2591, 0xa085, 0x0001,
-+	0x007c, 0x1078, 0x25ae, 0x00c0, 0x2597, 0x2041, 0x0001, 0x7d10,
-+	0x007c, 0x88ff, 0x0040, 0x259e, 0x2091, 0x4080, 0x007c, 0x7b90,
-+	0x7994, 0x70d4, 0xa102, 0x00c0, 0x25a8, 0xa385, 0x0000, 0x007c,
-+	0x0048, 0x25ac, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec,
-+	0x0040, 0x25c6, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004,
-+	0xa005, 0x00c0, 0x25c3, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040,
-+	0x25c6, 0x0078, 0x2617, 0x0e7f, 0x0078, 0x2617, 0xa184, 0xff00,
-+	0x0040, 0x25d3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-+	0xa100, 0x0078, 0x25d6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98,
-+	0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009,
-+	0x0018, 0x6028, 0xa005, 0x0040, 0x25e7, 0x2009, 0x0040, 0x1078,
-+	0x1d74, 0x0040, 0x2609, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0,
-+	0x2617, 0x6014, 0xd0fc, 0x00c0, 0x25f9, 0x2069, 0x4e40, 0x0078,
-+	0x25fb, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab,
-+	0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078,
-+	0x2617, 0x78ab, 0x0000, 0x1078, 0x203f, 0x7990, 0x7894, 0x8000,
-+	0xa10a, 0x00c8, 0x2614, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
-+	0x0010, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x2623, 0x2009,
-+	0x4e59, 0x0078, 0x2625, 0x2009, 0x4e99, 0x2091, 0x8000, 0x200a,
-+	0x0f7e, 0xd7fc, 0x00c0, 0x263c, 0x2009, 0x4e40, 0x2001, 0x4e04,
-+	0x2004, 0xd0ec, 0x0040, 0x2638, 0x2079, 0x0100, 0x0078, 0x2640,
-+	0x2079, 0x0200, 0x0078, 0x2640, 0x2009, 0x4e80, 0x2079, 0x0100,
-+	0x2104, 0xa086, 0x0000, 0x00c0, 0x2659, 0xd7fc, 0x00c0, 0x264c,
-+	0x2009, 0x4e45, 0x0078, 0x264e, 0x2009, 0x4e85, 0x2104, 0xa005,
-+	0x00c0, 0x2659, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2659, 0x781b,
-+	0x0045, 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4e00, 0x6810,
-+	0xd0ec, 0x00c0, 0x26c8, 0x2071, 0x4e80, 0x2079, 0x0100, 0x2021,
-+	0x50bf, 0x784b, 0x000f, 0x2019, 0x4457, 0xd184, 0x0040, 0x267c,
-+	0x6810, 0xd0ec, 0x0040, 0x2678, 0x20a1, 0x012b, 0x0078, 0x267e,
-+	0x20a1, 0x022b, 0x0078, 0x267e, 0x20a1, 0x012b, 0x2304, 0xa005,
-+	0x0040, 0x268b, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6,
-+	0x3318, 0x0078, 0x267e, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814,
-+	0xd0e4, 0x0040, 0x269b, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0,
-+	0x2693, 0x0078, 0x26a1, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0,
-+	0x269b, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040,
-+	0x26aa, 0xc1bd, 0x1078, 0x289b, 0x017f, 0x7020, 0xa084, 0x000f,
-+	0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x26ba, 0xa085, 0x6340,
-+	0x0078, 0x26bc, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843,
-+	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000,
-+	0x8109, 0x0040, 0x26db, 0x2071, 0x4e40, 0x6810, 0xd0ec, 0x0040,
-+	0x26d5, 0x2079, 0x0100, 0x0078, 0x26d7, 0x2079, 0x0200, 0x2021,
-+	0x4ebf, 0x0078, 0x2669, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x26f0,
-+	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26ec,
-+	0x2011, 0x0101, 0x0078, 0x26f2, 0x2011, 0x0201, 0x0078, 0x26f2,
-+	0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105,
-+	0x2012, 0x017f, 0x1078, 0x289b, 0x007c, 0xd3fc, 0x00c0, 0x2710,
-+	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x270c,
-+	0x2011, 0x0101, 0x0078, 0x2712, 0x2011, 0x0201, 0x0078, 0x2712,
-+	0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x2714, 0xa18c,
-+	0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019,
-+	0x0002, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040, 0x272c, 0x8319,
-+	0x2009, 0x0101, 0x0078, 0x272e, 0x2009, 0x0101, 0x20a9, 0x0005,
-+	0x8213, 0x00f0, 0x2730, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f,
-+	0xa205, 0x200a, 0x8319, 0x0040, 0x2741, 0x2009, 0x0201, 0x0078,
-+	0x272e, 0x007c, 0xd3fc, 0x00c0, 0x2755, 0x007e, 0x2001, 0x4e04,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2751, 0x2011, 0x0101, 0x0078,
-+	0x2757, 0x2011, 0x0201, 0x0078, 0x2757, 0x2011, 0x0101, 0x20a9,
-+	0x000c, 0x810b, 0x00f0, 0x2759, 0xa18c, 0xf000, 0x2204, 0xa084,
-+	0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x2777, 0x007e,
-+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2773, 0x2011,
-+	0x0102, 0x0078, 0x2779, 0x2011, 0x0202, 0x0078, 0x2779, 0x2011,
-+	0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e,
-+	0xd1bc, 0x00c0, 0x2793, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x278f, 0x2061, 0x0100, 0x0078, 0x2795, 0x2061,
-+	0x0200, 0x0078, 0x2795, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
-+	0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e,
-+	0xd1bc, 0x00c0, 0x27b3, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x27af, 0x2061, 0x0100, 0x0078, 0x27b5, 0x2061,
-+	0x0200, 0x0078, 0x27b5, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
-+	0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
-+	0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27d5, 0x007e, 0x2001, 0x4e04,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x27d1, 0x2061, 0x0100, 0x0078,
-+	0x27d7, 0x2061, 0x0200, 0x0078, 0x27d7, 0x2061, 0x0100, 0xc1bc,
-+	0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020,
-+	0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27f7, 0x007e,
-+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27f3, 0x2061,
-+	0x0100, 0x0078, 0x27f9, 0x2061, 0x0200, 0x0078, 0x27f9, 0x2061,
-+	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4,
-+	0xa28c, 0x0020, 0x0040, 0x2807, 0xc2ac, 0xa39d, 0x4000, 0xc3fc,
-+	0xd3b4, 0x00c0, 0x280c, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae,
-+	0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818,
-+	0xa005, 0x0040, 0x2879, 0xd1fc, 0x0040, 0x2822, 0x2061, 0x95d0,
-+	0x0078, 0x2824, 0x2061, 0x94c0, 0x1078, 0x2881, 0x0040, 0x285b,
-+	0x20a9, 0x0101, 0xd1fc, 0x0040, 0x2831, 0x2061, 0x94d0, 0x0078,
-+	0x2833, 0x2061, 0x93c0, 0x0c7e, 0x1078, 0x2881, 0x0040, 0x283e,
-+	0x0c7f, 0x8c60, 0x00f0, 0x2833, 0x0078, 0x2879, 0x007f, 0xd1fc,
-+	0x0040, 0x2848, 0xa082, 0x94d0, 0x2071, 0x4e80, 0x0078, 0x284c,
-+	0xa082, 0x93c0, 0x2071, 0x4e40, 0x707a, 0x7176, 0x2138, 0x2001,
-+	0x0004, 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078,
-+	0x261c, 0x0078, 0x2875, 0xd1fc, 0x00c0, 0x2862, 0x2071, 0x4e40,
-+	0x0078, 0x2864, 0x2071, 0x4e80, 0x6020, 0xc0dd, 0x6022, 0x7176,
-+	0x2138, 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f,
-+	0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x261c, 0x2001, 0x0000, 0x0078,
-+	0x287b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f,
-+	0x007c, 0x2c04, 0xa005, 0x0040, 0x2898, 0x2060, 0x6010, 0xa306,
-+	0x00c0, 0x2895, 0x600c, 0xa206, 0x00c0, 0x2895, 0x6014, 0xa106,
-+	0x00c0, 0x2895, 0xa006, 0x0078, 0x289a, 0x6000, 0x0078, 0x2882,
-+	0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0,
-+	0x28b3, 0x2079, 0x4e40, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x28af, 0x2071, 0x0100, 0x0078, 0x28b7, 0x2071,
-+	0x0200, 0x0078, 0x28b7, 0x2079, 0x4e80, 0x2071, 0x0100, 0x7920,
-+	0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x28c1, 0x017f, 0x0078,
-+	0x28dc, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0,
-+	0x28d9, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x28d5, 0xa18d, 0x0f00, 0x0078, 0x28db, 0xa18d, 0x0f00, 0x0078,
-+	0x28db, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e,
-+	0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0, 0x295c, 0x68e4, 0xd0ac,
-+	0x0040, 0x295c, 0xa084, 0x0006, 0x00c0, 0x295c, 0x6014, 0xd0fc,
-+	0x00c0, 0x28f6, 0x2071, 0x52c0, 0x0078, 0x28f8, 0x2071, 0x5340,
-+	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004,
-+	0xa084, 0x000a, 0x00c0, 0x295c, 0x7108, 0xa194, 0xff00, 0x0040,
-+	0x295c, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x292b,
-+	0x2001, 0x000c, 0xa106, 0x0040, 0x292f, 0x2001, 0x0012, 0xa106,
-+	0x0040, 0x2933, 0x2001, 0x0014, 0xa106, 0x0040, 0x2937, 0x2001,
-+	0x0019, 0xa106, 0x0040, 0x293b, 0x2001, 0x0032, 0xa106, 0x0040,
-+	0x293f, 0x0078, 0x2943, 0x2009, 0x000c, 0x0078, 0x2945, 0x2009,
-+	0x0012, 0x0078, 0x2945, 0x2009, 0x0014, 0x0078, 0x2945, 0x2009,
-+	0x0019, 0x0078, 0x2945, 0x2009, 0x0020, 0x0078, 0x2945, 0x2009,
-+	0x003f, 0x0078, 0x2945, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a,
-+	0x2071, 0x4e00, 0x7004, 0xd0bc, 0x0040, 0x295c, 0x6014, 0xd0fc,
-+	0x00c0, 0x2957, 0x70ea, 0x2071, 0x4e40, 0x0078, 0x295a, 0x70ee,
-+	0x2071, 0x4e80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4e05,
-+	0x2004, 0xd0e4, 0x00c0, 0x296a, 0x7804, 0xa084, 0xff1f, 0xa085,
-+	0x6340, 0x7806, 0x007c, 0x0068, 0x296b, 0x2091, 0x8000, 0x2071,
-+	0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x2972, 0x007f, 0x2071,
-+	0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f,
-+	0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x0078, 0x2988, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e,
-+	0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040,
-+	0x299f, 0xa784, 0x007d, 0x00c0, 0x43cd, 0x1078, 0x296b, 0xa49c,
-+	0x000f, 0xa382, 0x0004, 0x0050, 0x29aa, 0xa3a6, 0x0007, 0x00c0,
-+	0x296b, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29af, 0x3028,
-+	0x3119, 0x3144, 0x33b6, 0x379f, 0x3819, 0x38ce, 0x395f, 0x3a4d,
-+	0x3b3c, 0x29c2, 0x29bf, 0x2df9, 0x2f1c, 0x3770, 0x29bf, 0x1078,
-+	0x296b, 0x007c, 0xa006, 0x0078, 0x29cc, 0x7808, 0xc08d, 0x780a,
-+	0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0,
-+	0x2b32, 0x7064, 0xa084, 0x0007, 0x0079, 0x29d6, 0x29de, 0x2a51,
-+	0x2a5a, 0x2a65, 0x2a70, 0x2b18, 0x2a7b, 0x2a51, 0x7830, 0xd0bc,
-+	0x00c0, 0x29c1, 0x71d4, 0xd1bc, 0x00c0, 0x29c1, 0xd1b4, 0x00c0,
-+	0x2a2e, 0x70a4, 0xa086, 0x0001, 0x0040, 0x29c1, 0x70b4, 0xa06d,
-+	0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808,
-+	0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040,
-+	0x2a04, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
-+	0x0010, 0x0078, 0x2c8c, 0x7060, 0xa005, 0x00c0, 0x29c1, 0x0c7e,
-+	0x0d7e, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010,
-+	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
-+	0xa886, 0x0001, 0x0040, 0x2a27, 0x69bc, 0x7daa, 0x79aa, 0x68c0,
-+	0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2c8c, 0x1078, 0x4360,
-+	0x00c0, 0x29c1, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a,
-+	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d,
-+	0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0,
-+	0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046,
-+	0x007c, 0x1078, 0x4360, 0x00c0, 0x2a59, 0x781b, 0x0047, 0x7003,
-+	0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a64, 0x2011, 0x000c,
-+	0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0,
-+	0x2a6f, 0x2011, 0x0006, 0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c,
-+	0x1078, 0x4360, 0x00c0, 0x2a7a, 0x2011, 0x000d, 0x1078, 0x2a8b,
-+	0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a8a, 0x2011,
-+	0x0006, 0x1078, 0x2a8b, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e,
-+	0x7003, 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b,
-+	0x0010, 0xa286, 0x000c, 0x00c0, 0x2a9a, 0x7aaa, 0x2001, 0x0001,
-+	0x0078, 0x2aaf, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286,
-+	0x000d, 0x0040, 0x2aa8, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2aaf,
-+	0x78ab, 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
-+	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x4383,
-+	0x7083, 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2acb, 0xc0b4, 0x70d6,
-+	0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
-+	0x8001, 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2ada,
-+	0x70d4, 0xd0b4, 0x0040, 0x2adb, 0x70b8, 0xac06, 0x00c0, 0x2adb,
-+	0x1078, 0x2aba, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040,
-+	0x2b0d, 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4,
-+	0x2068, 0x6800, 0xac06, 0x0040, 0x2af4, 0x8211, 0x0040, 0x2b0b,
-+	0x1078, 0x2b0f, 0x0078, 0x2ae9, 0x0c7e, 0x2100, 0x2011, 0x0001,
-+	0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef,
-+	0x600a, 0x8211, 0x0040, 0x2b08, 0x1078, 0x2b0f, 0x0078, 0x2afb,
-+	0x70a7, 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8,
-+	0x0005, 0x70ac, 0xad06, 0x00c0, 0x2b17, 0x70a8, 0x2068, 0x007c,
-+	0x1078, 0x4360, 0x00c0, 0x29c1, 0x707c, 0x2068, 0x7774, 0x1078,
-+	0x41fe, 0x2c50, 0x1078, 0x4442, 0x789b, 0x0010, 0x6814, 0xa084,
-+	0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004,
-+	0x0078, 0x2c92, 0x1078, 0x4360, 0x00c0, 0x29c1, 0x789b, 0x0010,
-+	0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b4c, 0xc0b4,
-+	0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x41fe, 0x2c50, 0x1078,
-+	0x4442, 0x6824, 0xa005, 0x0040, 0x2b5d, 0xa082, 0x0006, 0x0048,
-+	0x2b5b, 0x0078, 0x2b5d, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f,
-+	0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003,
-+	0x0078, 0x2c92, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154,
-+	0x8108, 0xa12a, 0x0048, 0x2b75, 0x71c0, 0x2164, 0x6504, 0x85ff,
-+	0x00c0, 0x2b8c, 0x7156, 0x8421, 0x00c0, 0x2b70, 0x70d4, 0xd08c,
-+	0x0040, 0x2b88, 0x70d0, 0xa005, 0x00c0, 0x2b88, 0x70d3, 0x000a,
-+	0x007c, 0x2200, 0x0078, 0x2b7a, 0x70d4, 0xc08c, 0x70d6, 0x70d3,
-+	0x0000, 0x6034, 0xa005, 0x00c0, 0x2b89, 0x6708, 0xa784, 0x073f,
-+	0x0040, 0x2bbb, 0xd7d4, 0x00c0, 0x2b89, 0xa784, 0x0021, 0x00c0,
-+	0x2b89, 0xa784, 0x0002, 0x0040, 0x2bac, 0xa784, 0x0004, 0x0040,
-+	0x2b89, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2b89,
-+	0xa784, 0x0100, 0x0040, 0x2bbb, 0x6018, 0xa005, 0x00c0, 0x2b89,
-+	0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684,
-+	0x000e, 0x6318, 0x0040, 0x2bcc, 0x601c, 0xa302, 0x0048, 0x2bcf,
-+	0x0040, 0x2bcf, 0x0078, 0x2b89, 0x83ff, 0x00c0, 0x2b89, 0x2d58,
-+	0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2bd8, 0x7028, 0x6022, 0x603a,
-+	0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041,
-+	0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040,
-+	0x2bec, 0xd684, 0x0040, 0x2bee, 0xa39c, 0xffbf, 0xd6a4, 0x0040,
-+	0x2bf3, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c3e, 0xc7a5,
-+	0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
-+	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
-+	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
-+	0x0078, 0x2c8a, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005,
-+	0x70ac, 0xa606, 0x00c0, 0x2c1d, 0x76a8, 0x76b2, 0x2c3a, 0x8738,
-+	0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830,
-+	0xd0bc, 0x0040, 0x2c35, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4,
-+	0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040,
-+	0x2c3d, 0x8421, 0x2200, 0x00c0, 0x2b6f, 0x007c, 0xd1dc, 0x0040,
-+	0x3e00, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c4b, 0x8528, 0xd68c,
-+	0x00c0, 0x2c4b, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c,
-+	0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2c6a, 0x6014,
-+	0xa706, 0x00c0, 0x2c53, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c4e,
-+	0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0,
-+	0x2b6f, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840,
-+	0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
-+	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
-+	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
-+	0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a,
-+	0x0078, 0x2c93, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018,
-+	0x0040, 0x2caf, 0xa184, 0x0010, 0x0040, 0x2ca2, 0x1078, 0x4011,
-+	0x00c0, 0x2cd4, 0xa184, 0x0008, 0x0040, 0x2caf, 0x69a0, 0xa184,
-+	0x0600, 0x00c0, 0x2caf, 0x1078, 0x3ef5, 0x0078, 0x2cd4, 0x69a0,
-+	0xa184, 0x1e00, 0x0040, 0x2cdf, 0xa184, 0x0800, 0x0040, 0x2cc8,
-+	0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d,
-+	0x0010, 0x6106, 0x0c7f, 0x1078, 0x4011, 0x00c0, 0x2cd4, 0x69a0,
-+	0xa184, 0x0200, 0x0040, 0x2cd0, 0x1078, 0x3f54, 0x0078, 0x2cd4,
-+	0xa184, 0x0400, 0x00c0, 0x2cab, 0x69a0, 0xa184, 0x1000, 0x0040,
-+	0x2cdf, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x279f, 0x027f,
-+	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2cec, 0xa086, 0x0060,
-+	0x00c0, 0x2cec, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b,
-+	0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040,
-+	0x2d07, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d05,
-+	0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa,
-+	0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
-+	0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
-+	0x25a0, 0xa286, 0x0020, 0x00c0, 0x2d3f, 0x70d4, 0xc0b5, 0x70d6,
-+	0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882,
-+	0xa286, 0x0002, 0x0040, 0x2d75, 0x70a4, 0x8000, 0x70a6, 0x74b4,
-+	0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d37, 0x73a8, 0x73b6,
-+	0xa286, 0x0010, 0x0040, 0x29c1, 0x0d7f, 0x0c7f, 0x007c, 0x7000,
-+	0xa005, 0x00c0, 0x2d1d, 0xa286, 0x0002, 0x00c0, 0x2d8f, 0x1078,
-+	0x4360, 0x00c0, 0x2d1d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
-+	0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-+	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
-+	0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f,
-+	0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002,
-+	0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040,
-+	0x2d81, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000,
-+	0x2090, 0x70a4, 0xa005, 0x00c0, 0x2d86, 0x007c, 0x8421, 0x0040,
-+	0x2d85, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2b6f, 0xa286,
-+	0x0010, 0x00c0, 0x2dc0, 0x1078, 0x4360, 0x00c0, 0x2d1d, 0x6814,
-+	0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894,
-+	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
-+	0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206,
-+	0x00c0, 0x2db3, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042,
-+	0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c,
-+	0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882,
-+	0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b,
-+	0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605,
-+	0x0040, 0x2deb, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0,
-+	0x2de5, 0x2009, 0x0000, 0x0078, 0x2de7, 0x2009, 0x0001, 0xa284,
-+	0x000f, 0x1079, 0x2def, 0xad80, 0x0009, 0x7046, 0x007c, 0x2df7,
-+	0x48bd, 0x48bd, 0x48aa, 0x48bd, 0x2df7, 0x2df7, 0x2df7, 0x1078,
-+	0x296b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x295e, 0x0f7e,
-+	0x2079, 0x4e00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e21, 0x7064,
-+	0xa086, 0x0001, 0x00c0, 0x2e0f, 0x7066, 0x0078, 0x2ef8, 0x7064,
-+	0xa086, 0x0005, 0x00c0, 0x2e1f, 0x707c, 0x2068, 0x681b, 0x0004,
-+	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067,
-+	0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078, 0x2aba,
-+	0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040, 0x2e41,
-+	0xa186, 0x0007, 0x00c0, 0x2e38, 0x701f, 0x0005, 0x0078, 0x2e41,
-+	0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
-+	0x2e43, 0x7067, 0x0000, 0x2001, 0x4e0a, 0x2004, 0xa084, 0x00ff,
-+	0xa086, 0x0018, 0x0040, 0x2e53, 0x7018, 0x7016, 0xa005, 0x00c0,
-+	0x2e53, 0x70a7, 0x0001, 0x067e, 0x1078, 0x4586, 0x20a9, 0x0010,
-+	0x2039, 0x0000, 0x1078, 0x40f8, 0xa7b8, 0x0100, 0x00f0, 0x2e5a,
-+	0x067f, 0x7000, 0x0079, 0x2e64, 0x2e9e, 0x2e79, 0x2e79, 0x2e6e,
-+	0x2e9e, 0x2e9e, 0x2e9e, 0x2e6c, 0x1078, 0x296b, 0x7060, 0xa005,
-+	0x0040, 0x2e9e, 0xad06, 0x00c0, 0x2e79, 0x6800, 0x7062, 0x0078,
-+	0x2e8b, 0x6820, 0xd084, 0x00c0, 0x2e87, 0x6f14, 0x1078, 0x41fe,
-+	0x6008, 0xc0d4, 0x600a, 0x1078, 0x3dd0, 0x0078, 0x2e8b, 0x705c,
-+	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
-+	0x0040, 0x2e93, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820,
-+	0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0xb284, 0x0400,
-+	0x0040, 0x2ea6, 0x2021, 0x95d0, 0x0078, 0x2ea8, 0x2021, 0x94c0,
-+	0x1078, 0x2efd, 0xb284, 0x0400, 0x0040, 0x2eb2, 0x2021, 0x4e98,
-+	0x0078, 0x2eb4, 0x2021, 0x4e58, 0x1078, 0x2efd, 0x20a9, 0x0101,
-+	0xb284, 0x0400, 0x0040, 0x2ec0, 0x2021, 0x94d0, 0x0078, 0x2ec2,
-+	0x2021, 0x93c0, 0x1078, 0x2efd, 0x8420, 0x00f0, 0x2ec2, 0xb284,
-+	0x0300, 0x0040, 0x2ecf, 0x2061, 0x53c0, 0x0078, 0x2ed1, 0x2061,
-+	0x73c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040,
-+	0x2eee, 0x6018, 0x017e, 0x007e, 0x2011, 0x4e02, 0x220c, 0xa102,
-+	0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2eee, 0x6012, 0x00c0,
-+	0x2eee, 0x2011, 0x4e04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000,
-+	0xace0, 0x0010, 0x00f0, 0x2ed5, 0x8421, 0x00c0, 0x2ed3, 0x157f,
-+	0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005,
-+	0x0040, 0x2f18, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000,
-+	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
-+	0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0x007f, 0x0078, 0x2eff,
-+	0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2f22,
-+	0x1078, 0x296b, 0x2300, 0x0079, 0x2f25, 0x2f28, 0x2fb3, 0x2fd0,
-+	0xa282, 0x0002, 0x0040, 0x2f2e, 0x1078, 0x296b, 0x7064, 0x7067,
-+	0x0000, 0x7083, 0x0000, 0x0079, 0x2f35, 0x2f3d, 0x2f3d, 0x2f3f,
-+	0x2f7f, 0x3e0c, 0x2f3d, 0x2f7f, 0x2f3d, 0x1078, 0x296b, 0x7774,
-+	0x1078, 0x40f8, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x41fe, 0x6018,
-+	0xa005, 0x0040, 0x2f76, 0xd7fc, 0x00c0, 0x2f52, 0x2021, 0x94c0,
-+	0x0078, 0x2f54, 0x2021, 0x95d0, 0x2009, 0x0005, 0x2011, 0x0010,
-+	0x1078, 0x2feb, 0x0040, 0x2f76, 0x157e, 0x20a9, 0x0101, 0xd7fc,
-+	0x00c0, 0x2f66, 0x2021, 0x93c0, 0x0078, 0x2f68, 0x2021, 0x94d0,
-+	0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2feb, 0x047f,
-+	0x0040, 0x2f75, 0x8420, 0x00f0, 0x2f68, 0x157f, 0x8738, 0xa784,
-+	0x001f, 0x00c0, 0x2f45, 0x0078, 0x29c5, 0x0078, 0x29c5, 0x7774,
-+	0x1078, 0x41fe, 0x6018, 0xa005, 0x0040, 0x2fb1, 0xd7fc, 0x00c0,
-+	0x2f8d, 0x2021, 0x94c0, 0x0078, 0x2f8f, 0x2021, 0x95d0, 0x2009,
-+	0x0005, 0x2011, 0x0020, 0x1078, 0x2feb, 0x0040, 0x2fb1, 0x157e,
-+	0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fa1, 0x2021, 0x93c0, 0x0078,
-+	0x2fa3, 0x2021, 0x94d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020,
-+	0x1078, 0x2feb, 0x047f, 0x0040, 0x2fb0, 0x8420, 0x00f0, 0x2fa3,
-+	0x157f, 0x0078, 0x29c5, 0x2200, 0x0079, 0x2fb6, 0x2fb9, 0x2fbb,
-+	0x2fbb, 0x1078, 0x296b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002,
-+	0x0040, 0x2fc4, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2fc9,
-+	0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x430d,
-+	0x2200, 0x0079, 0x2fd3, 0x2fd8, 0x2fbb, 0x2fd6, 0x1078, 0x296b,
-+	0x1078, 0x4586, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3d7e, 0x1078,
-+	0x3ded, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3d6f, 0x0040,
-+	0x3d7e, 0x0078, 0x29c5, 0x2404, 0xa005, 0x0040, 0x3024, 0x2068,
-+	0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x2ffa, 0x2d20, 0x007f,
-+	0x0078, 0x2fec, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b,
-+	0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff,
-+	0xa205, 0x6822, 0x1078, 0x202c, 0x2021, 0x4e02, 0x241c, 0x8319,
-+	0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x301b, 0x2021, 0x4e04,
-+	0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078,
-+	0x2adb, 0x1078, 0x3ded, 0x007c, 0xa085, 0x0001, 0x0078, 0x3023,
-+	0x2300, 0x0079, 0x302b, 0x3030, 0x302e, 0x30b0, 0x1078, 0x296b,
-+	0x78e4, 0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x3041, 0xa18c, 0x0300, 0x0078,
-+	0x3043, 0xa18c, 0x0400, 0x0040, 0x3049, 0x0018, 0x29c1, 0x0078,
-+	0x304b, 0x0028, 0x29c1, 0x2008, 0xa084, 0x0030, 0x00c0, 0x3052,
-+	0x0078, 0x3770, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3050, 0x2100,
-+	0xa084, 0x0007, 0x0079, 0x305c, 0x3090, 0x309a, 0x3085, 0x3064,
-+	0x4355, 0x4355, 0x3064, 0x30a5, 0x1078, 0x296b, 0x7000, 0xa086,
-+	0x0004, 0x00c0, 0x3080, 0x7064, 0xa086, 0x0002, 0x00c0, 0x3076,
-+	0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f1c, 0x7064, 0xa086,
-+	0x0006, 0x0040, 0x3070, 0x7064, 0xa086, 0x0004, 0x0040, 0x3070,
-+	0x79e4, 0x2001, 0x0003, 0x0078, 0x33fa, 0x6818, 0xd0fc, 0x0040,
-+	0x308b, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x0064, 0x007c,
-+	0x6818, 0xd0fc, 0x0040, 0x3096, 0x681b, 0x001d, 0x1078, 0x40c8,
-+	0x0078, 0x4331, 0x6818, 0xd0fc, 0x0040, 0x30a0, 0x681b, 0x001d,
-+	0x1078, 0x40c8, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc, 0x0040,
-+	0x30ab, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x00c8, 0x007c,
-+	0xa584, 0x000f, 0x00c0, 0x30cf, 0x1078, 0x295e, 0x7000, 0x0079,
-+	0x30b9, 0x29c5, 0x30c1, 0x30c3, 0x3d7e, 0x3d7e, 0x3d7e, 0x30c1,
-+	0x30c1, 0x1078, 0x296b, 0x1078, 0x3ded, 0x6008, 0xa084, 0xfbef,
-+	0x600a, 0x1078, 0x3d6f, 0x0040, 0x3d7e, 0x0078, 0x29c5, 0x78e4,
-+	0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004,
-+	0xd0ec, 0x007f, 0x0040, 0x30e0, 0xa18c, 0x0300, 0x0078, 0x30e2,
-+	0xa18c, 0x0400, 0x0040, 0x30e8, 0x0018, 0x3066, 0x0078, 0x30ea,
-+	0x0028, 0x3066, 0x2008, 0xa084, 0x0030, 0x00c0, 0x30f2, 0x781b,
-+	0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x30ef, 0x2100,
-+	0xa184, 0x0007, 0x0079, 0x30fc, 0x310b, 0x310f, 0x3106, 0x3104,
-+	0x4355, 0x4355, 0x3104, 0x434f, 0x1078, 0x296b, 0x1078, 0x40d0,
-+	0x781b, 0x0064, 0x007c, 0x1078, 0x40d0, 0x0078, 0x4331, 0x1078,
-+	0x40d0, 0x781b, 0x00f8, 0x007c, 0x1078, 0x40d0, 0x781b, 0x00c8,
-+	0x007c, 0x2300, 0x0079, 0x311c, 0x3121, 0x311f, 0x3123, 0x1078,
-+	0x296b, 0x0078, 0x395f, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4,
-+	0xa184, 0x0030, 0x0040, 0x395f, 0x78ec, 0xa084, 0x0003, 0x0040,
-+	0x395f, 0xa184, 0x0100, 0x0040, 0x3127, 0xa184, 0x0007, 0x0079,
-+	0x3139, 0x3141, 0x310f, 0x3085, 0x430d, 0x4355, 0x4355, 0x430d,
-+	0x434f, 0x1078, 0x4319, 0x007c, 0xa282, 0x0005, 0x0050, 0x314a,
-+	0x1078, 0x296b, 0x2300, 0x0079, 0x314d, 0x3150, 0x3380, 0x338b,
-+	0x2200, 0x0079, 0x3153, 0x316d, 0x315a, 0x316d, 0x3158, 0x3363,
-+	0x1078, 0x296b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
-+	0x0020, 0x0048, 0x40b7, 0xa08a, 0x0004, 0x00c8, 0x40b7, 0x0079,
-+	0x3169, 0x40b7, 0x40b7, 0x40b7, 0x4061, 0x789b, 0x0018, 0x79a8,
-+	0xa184, 0x0080, 0x0040, 0x317e, 0x0078, 0x40b7, 0x7000, 0xa005,
-+	0x00c0, 0x3174, 0x2011, 0x0004, 0x0078, 0x3b4a, 0xa184, 0x00ff,
-+	0xa08a, 0x0010, 0x00c8, 0x40b7, 0x0079, 0x3186, 0x3198, 0x3196,
-+	0x31ad, 0x31b1, 0x3284, 0x40b7, 0x40b7, 0x3286, 0x40b7, 0x40b7,
-+	0x335f, 0x335f, 0x40b7, 0x40b7, 0x40b7, 0x3361, 0x1078, 0x296b,
-+	0xd6e4, 0x0040, 0x31a3, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a,
-+	0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31ab, 0x681b,
-+	0x001d, 0x0078, 0x319b, 0x0078, 0x430d, 0x681b, 0x001d, 0x0078,
-+	0x40c1, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x3216, 0x6820,
-+	0xd084, 0x00c0, 0x321c, 0x6818, 0xa086, 0x0008, 0x00c0, 0x31c2,
-+	0x681b, 0x0000, 0xd6d4, 0x0040, 0x3281, 0xd6bc, 0x0040, 0x3202,
-+	0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050,
-+	0x3202, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a,
-+	0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
-+	0xa18c, 0x0300, 0x0040, 0x31f4, 0x007e, 0x2001, 0x4e04, 0x2004,
-+	0xd0ec, 0x007f, 0x0040, 0x31f0, 0x20a1, 0x012b, 0x0078, 0x31f6,
-+	0x20a1, 0x022b, 0x0078, 0x31f6, 0x20a1, 0x012b, 0x017f, 0x789b,
-+	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
-+	0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x3211, 0x681c, 0xa084,
-+	0x000e, 0x0040, 0x40c1, 0x1078, 0x40d7, 0x782b, 0x3008, 0x0078,
-+	0x3213, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4, 0x0040,
-+	0x321c, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040, 0x327e,
-+	0xd6dc, 0x0040, 0x327e, 0xd6fc, 0x00c0, 0x3228, 0x0078, 0x323f,
-+	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8,
-+	0x3232, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98,
-+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
-+	0x0040, 0x3245, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003,
-+	0x00c0, 0x3253, 0x007e, 0x1078, 0x4586, 0x1078, 0x48bd, 0x007f,
-+	0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x49c3, 0x6ab0, 0x69ac,
-+	0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x3262, 0x2200, 0xa422,
-+	0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde,
-+	0x2300, 0xa405, 0x00c0, 0x3272, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b,
-+	0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0, 0x327b,
-+	0x1078, 0x48bd, 0x007c, 0x1078, 0x48f5, 0x007c, 0x781b, 0x0079,
-+	0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x296b, 0x0078, 0x32d2,
-+	0x6920, 0xd1c4, 0x0040, 0x329b, 0xc1c4, 0x6922, 0x0c7e, 0x7058,
-+	0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006,
-+	0x0c7f, 0x0078, 0x32c6, 0xd1cc, 0x0040, 0x32c6, 0xc1cc, 0x6922,
-+	0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004, 0xc0a4,
-+	0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
-+	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x32c3,
-+	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58, 0xd6d4,
-+	0x00c0, 0x32cd, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079, 0x007c,
-+	0x0078, 0x40bc, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
-+	0x32e0, 0x6820, 0xa084, 0x0100, 0x0040, 0x32d0, 0x2009, 0x0008,
-+	0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
-+	0x32fc, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x32f4,
-+	0x0048, 0x32f4, 0x0078, 0x32f6, 0x0078, 0x3288, 0x24a8, 0x7aa8,
-+	0x00f0, 0x32f6, 0x0078, 0x32e2, 0xa284, 0x00f0, 0xa086, 0x0020,
-+	0x00c0, 0x3350, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x330c,
-+	0x0048, 0x330c, 0x0078, 0x334d, 0xa286, 0x0023, 0x0040, 0x32d0,
-+	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
-+	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058, 0x2060,
-+	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x332d, 0x1078,
-+	0x41fa, 0x1078, 0x4011, 0x0078, 0x333b, 0x0c7e, 0x7058, 0x2060,
-+	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
-+	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x334a, 0x781b,
-+	0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078, 0x32e2,
-+	0x8318, 0x2300, 0xa102, 0x0040, 0x3359, 0x0048, 0x3359, 0x0078,
-+	0x32e2, 0xa284, 0x0080, 0x00c0, 0x40c1, 0x0078, 0x40bc, 0x0078,
-+	0x40c1, 0x0078, 0x40b7, 0x7058, 0xa04d, 0x789b, 0x0018, 0x78a8,
-+	0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x3370, 0x1078, 0x296b,
-+	0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004,
-+	0x00c8, 0x40b7, 0x0079, 0x337c, 0x40b7, 0x3e46, 0x40b7, 0x3fb9,
-+	0xa282, 0x0000, 0x00c0, 0x3386, 0x1078, 0x296b, 0x1078, 0x40c8,
-+	0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x3391, 0x1078,
-+	0x296b, 0xd4fc, 0x00c0, 0x33b1, 0x7064, 0xa005, 0x0040, 0x339a,
-+	0x1078, 0x296b, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078, 0x41fe,
-+	0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0,
-+	0x339e, 0x1078, 0x40cc, 0x7067, 0x0002, 0x701f, 0x0009, 0x0078,
-+	0x33b3, 0x1078, 0x40db, 0x781b, 0x0078, 0x007c, 0xa282, 0x0004,
-+	0x0050, 0x33bc, 0x1078, 0x296b, 0x2300, 0x0079, 0x33bf, 0x33c2,
-+	0x3582, 0x35c5, 0xa286, 0x0003, 0x0040, 0x33fa, 0x7200, 0x7cd8,
-+	0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x33f2, 0xd1b4, 0x0040,
-+	0x33f2, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x33f2, 0xa282, 0x0002,
-+	0x00c8, 0x33f2, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c, 0x70bc,
-+	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-+	0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001, 0x0000,
-+	0x0078, 0x33fe, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001, 0x0000,
-+	0x0078, 0x33fe, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0,
-+	0xd0ec, 0x0040, 0x3406, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
-+	0x0079, 0x340a, 0x3562, 0x3417, 0x3414, 0x36c8, 0x3754, 0x29c5,
-+	0x3412, 0x3412, 0x1078, 0x296b, 0x6008, 0xc0d4, 0x600a, 0xd6e4,
-+	0x0040, 0x341f, 0x7048, 0xa086, 0x0014, 0x00c0, 0x343f, 0x1078,
-+	0x4586, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3428, 0x7048,
-+	0xa086, 0x0014, 0x0040, 0x3439, 0x6818, 0xa086, 0x0008, 0x00c0,
-+	0x351a, 0x7858, 0xd09c, 0x0040, 0x351a, 0x6820, 0xd0ac, 0x0040,
-+	0x351a, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x347e, 0x7868,
-+	0xa08c, 0x00ff, 0x0040, 0x347e, 0xa186, 0x0008, 0x00c0, 0x3455,
-+	0x6008, 0xc0a4, 0x600a, 0x1078, 0x3d6f, 0x0040, 0x347e, 0x1078,
-+	0x3ded, 0x1078, 0x4586, 0x0078, 0x3466, 0xa186, 0x0028, 0x00c0,
-+	0x347e, 0x6018, 0xa005, 0x0040, 0x3448, 0x8001, 0x0040, 0x3448,
-+	0x8001, 0x0040, 0x3448, 0x601e, 0x0078, 0x3448, 0x6820, 0xd084,
-+	0x0040, 0x29c5, 0xc084, 0x6822, 0x1078, 0x2acc, 0x705c, 0x0c7e,
-+	0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00,
-+	0x00c0, 0x347b, 0x6002, 0x6006, 0x0078, 0x29c5, 0x017e, 0x81ff,
-+	0x00c0, 0x34c8, 0x7000, 0xa086, 0x0030, 0x0040, 0x34c8, 0x71d4,
-+	0xd1bc, 0x00c0, 0x34c8, 0xd1b4, 0x00c0, 0x34af, 0x7060, 0xa005,
-+	0x00c0, 0x34c8, 0x70a4, 0xa086, 0x0001, 0x0040, 0x34c8, 0x7003,
-+	0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078,
-+	0x29ee, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4,
-+	0xd1b4, 0x00c0, 0x34c8, 0x7003, 0x0040, 0x0078, 0x34c8, 0x1078,
-+	0x4360, 0x00c0, 0x34c8, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d,
-+	0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
-+	0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f,
-+	0x1078, 0x35ff, 0x017f, 0x81ff, 0x0040, 0x351a, 0xa684, 0xdf00,
-+	0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x351b,
-+	0x6818, 0xa086, 0x0014, 0x00c0, 0x34e4, 0x2008, 0xd6e4, 0x0040,
-+	0x34e4, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2aba, 0x1078, 0x2adb,
-+	0x6820, 0xd0dc, 0x00c0, 0x351b, 0x8717, 0xa294, 0x000f, 0x8213,
-+	0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x34fa, 0xa290, 0x52c0,
-+	0x0078, 0x34fc, 0xa290, 0x5340, 0xa290, 0x0000, 0x221c, 0xd3c4,
-+	0x00c0, 0x3504, 0x0078, 0x350a, 0x8210, 0x2204, 0xa085, 0x0018,
-+	0x2012, 0x8211, 0xd3d4, 0x0040, 0x3515, 0x68a0, 0xd0c4, 0x00c0,
-+	0x3515, 0x1078, 0x3679, 0x0078, 0x29c5, 0x6008, 0xc08d, 0x600a,
-+	0x0078, 0x351b, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3522,
-+	0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0040,
-+	0x3537, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412,
-+	0x00c0, 0x3537, 0x2021, 0x4e04, 0x2404, 0xc0a5, 0x2022, 0x6018,
-+	0xa005, 0x0040, 0x353f, 0x8001, 0x601a, 0x00c0, 0x3542, 0x6008,
-+	0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x354e, 0x6800, 0xa005,
-+	0x00c0, 0x354b, 0x6002, 0x6006, 0x0078, 0x3552, 0x705c, 0x2060,
-+	0x6800, 0x6002, 0x2061, 0x4e00, 0x6887, 0x0103, 0x2d08, 0x206b,
-+	0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x3561, 0x2d02, 0x0078,
-+	0x3562, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x3572, 0xa286,
-+	0x0040, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4,
-+	0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042,
-+	0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009,
-+	0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3588, 0x1078, 0x296b,
-+	0x2200, 0x0079, 0x358b, 0x358f, 0x35a0, 0x35ad, 0x35a0, 0xa586,
-+	0x1300, 0x0040, 0x35a0, 0xa586, 0x8300, 0x00c0, 0x3586, 0x7003,
-+	0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x7000, 0xa086, 0x0005, 0x0040, 0x35aa, 0x1078, 0x40c8, 0x781b,
-+	0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007, 0x8001,
-+	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-+	0xa186, 0x0003, 0x0040, 0x35c2, 0xa186, 0x0000, 0x0040, 0x35c2,
-+	0x0078, 0x40b7, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095, 0x6822,
-+	0x82ff, 0x00c0, 0x35cf, 0x1078, 0x40c8, 0x0078, 0x35d6, 0x8211,
-+	0x0040, 0x35d4, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
-+	0x007c, 0x1078, 0x4383, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x35fc,
-+	0x017e, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
-+	0x0040, 0x35ee, 0xa18c, 0x0300, 0x0078, 0x35f0, 0xa18c, 0x0400,
-+	0x017f, 0x0040, 0x35f7, 0x0018, 0x35fc, 0x0078, 0x35f9, 0x0028,
-+	0x35fc, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
-+	0x0060, 0x00c0, 0x3609, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-+	0x3678, 0xd6dc, 0x00c0, 0x3621, 0x68b4, 0xd0dc, 0x00c0, 0x3621,
-+	0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, 0x361e,
-+	0x2200, 0xa105, 0x0040, 0x4586, 0x704b, 0x0015, 0x0078, 0x4586,
-+	0x007c, 0xd6ac, 0x0040, 0x3647, 0xd6f4, 0x0040, 0x362d, 0x682f,
-+	0x0000, 0x6833, 0x0000, 0x0078, 0x4586, 0x68b4, 0xa084, 0x4000,
-+	0xa635, 0xd6f4, 0x00c0, 0x3627, 0x7048, 0xa005, 0x00c0, 0x363a,
-+	0x704b, 0x0015, 0xd6dc, 0x00c0, 0x3643, 0x68b4, 0xd0dc, 0x0040,
-+	0x3643, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4586, 0xd6f4,
-+	0x0040, 0x3650, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4586,
-+	0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x364a, 0x7048,
-+	0xa005, 0x00c0, 0x365d, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700,
-+	0x80fb, 0x00c8, 0x3664, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
-+	0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x3671, 0x0078,
-+	0x4586, 0x7000, 0xa086, 0x0006, 0x0040, 0x3678, 0x0078, 0x4586,
-+	0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3680, 0xc08d,
-+	0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893,
-+	0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833,
-+	0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000,
-+	0x0079, 0x369a, 0x29c5, 0x36ac, 0x36a4, 0x36a2, 0x36a2, 0x36a2,
-+	0x36a2, 0x36a2, 0x1078, 0x296b, 0x6820, 0xd084, 0x00c0, 0x36ac,
-+	0x1078, 0x3dd0, 0x0078, 0x36b2, 0x705c, 0x2c50, 0x2060, 0x6800,
-+	0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x36bb, 0x2021,
-+	0x4e58, 0x0078, 0x36bd, 0x2021, 0x4e98, 0x2404, 0xa005, 0x0040,
-+	0x36c4, 0x2020, 0x0078, 0x36bd, 0x2d22, 0x206b, 0x0000, 0x007c,
-+	0x1078, 0x3dd7, 0x1078, 0x3ded, 0x6008, 0xc0cc, 0x600a, 0x682b,
-+	0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916,
-+	0x3208, 0xa18c, 0x0300, 0x0040, 0x36e1, 0x2009, 0x0000, 0x0078,
-+	0x36e3, 0x2009, 0x0001, 0x1078, 0x49f8, 0xd6dc, 0x0040, 0x36eb,
-+	0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x36fa, 0x7868,
-+	0xa08c, 0x00ff, 0x0040, 0x36f8, 0x681b, 0x001e, 0x0078, 0x36fa,
-+	0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x3702, 0x2021, 0x4e98,
-+	0x0078, 0x3704, 0x2021, 0x4e58, 0x6800, 0x2022, 0x6a3c, 0x6940,
-+	0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040, 0x3744,
-+	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e, 0x0f7e,
-+	0x157e, 0x147e, 0x2079, 0x4e00, 0x1078, 0x1dff, 0x147f, 0x157f,
-+	0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204, 0xa06d,
-+	0x0040, 0x3734, 0x6814, 0xa706, 0x0040, 0x3731, 0x6800, 0x0078,
-+	0x3727, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109, 0x00c0,
-+	0x3725, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776, 0x7083,
-+	0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002, 0x00c0,
-+	0x3750, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e,
-+	0x1078, 0x202c, 0x0078, 0x29c5, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078,
-+	0x35ff, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4387,
-+	0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3769, 0x7048,
-+	0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x29c5,
-+	0x7000, 0xa005, 0x00c0, 0x3776, 0x0078, 0x29c5, 0xa006, 0x1078,
-+	0x4586, 0x6920, 0xd1ac, 0x00c0, 0x377f, 0x681b, 0x0014, 0xa68c,
-+	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
-+	0x7000, 0x0079, 0x378b, 0x29c5, 0x3795, 0x3795, 0x3798, 0x3798,
-+	0x3798, 0x3793, 0x3793, 0x1078, 0x296b, 0x6818, 0x0078, 0x33fa,
-+	0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3d95, 0x2300,
-+	0x0079, 0x37a2, 0x37a5, 0x37a7, 0x3817, 0x1078, 0x296b, 0xd6fc,
-+	0x00c0, 0x37fe, 0x7000, 0xa00d, 0x0079, 0x37ae, 0x29c5, 0x37b8,
-+	0x37b8, 0x37e8, 0x37b8, 0x37fb, 0x37b6, 0x37b6, 0x1078, 0x296b,
-+	0xa684, 0x0060, 0x0040, 0x37e8, 0xa086, 0x0060, 0x00c0, 0x37e5,
-+	0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e,
-+	0xa186, 0x0002, 0x0040, 0x37d7, 0x1078, 0x4586, 0x69ac, 0x68b0,
-+	0xa115, 0x0040, 0x37d7, 0x1078, 0x48f5, 0x0078, 0x37d9, 0x1078,
-+	0x48bd, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4,
-+	0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x37c2,
-+	0x6818, 0xd0fc, 0x0040, 0x37fb, 0xd6f4, 0x00c0, 0x37f5, 0x681b,
-+	0x0015, 0x781b, 0x0079, 0x0078, 0x29c1, 0x681b, 0x0007, 0x682f,
-+	0x0000, 0x6833, 0x0000, 0x1078, 0x4319, 0x007c, 0xc6fc, 0x7e5a,
-+	0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3807, 0x8000, 0xa084,
-+	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-+	0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c, 0x1078,
-+	0x296b, 0x2300, 0x0079, 0x381c, 0x3821, 0x3846, 0x38a6, 0x1078,
-+	0x296b, 0x7000, 0x0079, 0x3824, 0x382c, 0x382e, 0x3837, 0x382c,
-+	0x382c, 0x382c, 0x382c, 0x382c, 0x1078, 0x296b, 0x69ac, 0x68b0,
-+	0xa115, 0x0040, 0x3837, 0x1078, 0x48f5, 0x0078, 0x3839, 0x1078,
-+	0x48bd, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x29c1,
-+	0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6fc, 0x00c0,
-+	0x3896, 0x7000, 0xa00d, 0x0079, 0x384d, 0x29c5, 0x385d, 0x3857,
-+	0x388d, 0x385d, 0x3893, 0x3855, 0x3855, 0x1078, 0x296b, 0x6894,
-+	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0040,
-+	0x388d, 0xa086, 0x0060, 0x00c0, 0x388a, 0xa6b4, 0xbfbf, 0xc6ed,
-+	0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x3879, 0x1078, 0x4586,
-+	0x69ac, 0x68b0, 0xa115, 0x0040, 0x3879, 0x1078, 0x48f5, 0x0078,
-+	0x387b, 0x1078, 0x48bd, 0x781b, 0x0079, 0x681c, 0xc0b4, 0x681e,
-+	0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0,
-+	0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x3867, 0x6818, 0xd0fc, 0x0040,
-+	0x3893, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc, 0x7e5a,
-+	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc, 0x0040,
-+	0x38af, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x29c1, 0x7884,
-+	0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x38c2, 0xa484,
-+	0x0200, 0x0040, 0x38bc, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0079,
-+	0x0078, 0x29c1, 0x6820, 0xc095, 0x6822, 0x1078, 0x4292, 0xc6dd,
-+	0x1078, 0x40c8, 0x781b, 0x0078, 0x0078, 0x29c1, 0x2300, 0x0079,
-+	0x38d1, 0x38d4, 0x38d6, 0x38d8, 0x1078, 0x296b, 0x0078, 0x40c1,
-+	0xd6d4, 0x00c0, 0x3913, 0x79e4, 0xd1ac, 0x0040, 0x38e6, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x38e6, 0x782b, 0x3009, 0x789b, 0x0060,
-+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac, 0x0040,
-+	0x38f6, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x390f, 0x2001, 0x4e04,
-+	0x2004, 0xd0e4, 0x00c0, 0x390b, 0x6820, 0xd0c4, 0x0040, 0x390b,
-+	0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008, 0xa084,
-+	0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184,
-+	0x0007, 0x0079, 0x3949, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060,
-+	0x79a8, 0x81ff, 0x0040, 0x3947, 0x789b, 0x0010, 0x7ba8, 0xa384,
-+	0x0001, 0x00c0, 0x393a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0,
-+	0x392d, 0x2009, 0xfff7, 0x0078, 0x3933, 0xa386, 0x0003, 0x00c0,
-+	0x393a, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104,
-+	0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
-+	0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
-+	0x430d, 0x3090, 0x309a, 0x3953, 0x3959, 0x3951, 0x3951, 0x430d,
-+	0x430d, 0x1078, 0x296b, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
-+	0x4313, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x430d, 0x79e4,
-+	0xa184, 0x0030, 0x0040, 0x3969, 0x78ec, 0xa084, 0x0003, 0x00c0,
-+	0x399d, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3983, 0x7064, 0xa086,
-+	0x0002, 0x00c0, 0x3979, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078,
-+	0x2f1c, 0x7064, 0xa086, 0x0006, 0x0040, 0x3973, 0x7064, 0xa086,
-+	0x0004, 0x0040, 0x3973, 0x7000, 0xa086, 0x0000, 0x0040, 0x29c1,
-+	0x6920, 0xa184, 0x0420, 0x0040, 0x3992, 0xc1d4, 0x6922, 0x6818,
-+	0x0078, 0x33fa, 0x6818, 0xa08e, 0x0002, 0x0040, 0x399b, 0xc0fd,
-+	0x681a, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184, 0x0007, 0x0079,
-+	0x39a1, 0x430d, 0x430d, 0x39a9, 0x430d, 0x4355, 0x4355, 0x430d,
-+	0x430d, 0xd6bc, 0x0040, 0x39eb, 0x7184, 0x81ff, 0x0040, 0x39eb,
-+	0xa182, 0x000d, 0x00d0, 0x39b8, 0x7087, 0x0000, 0x0078, 0x39bd,
-+	0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa,
-+	0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a, 0xa080,
-+	0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x39df, 0x007e,
-+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x39db, 0x20a1,
-+	0x012b, 0x0078, 0x39e1, 0x20a1, 0x022b, 0x0078, 0x39e1, 0x20a1,
-+	0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f,
-+	0x157f, 0x0078, 0x4313, 0xd6d4, 0x00c0, 0x3a3f, 0x6820, 0xd084,
-+	0x0040, 0x4313, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x39fd,
-+	0xa086, 0x0060, 0x00c0, 0x39fd, 0xc1f5, 0xc194, 0x795a, 0x69b6,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd,
-+	0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e06, 0xa18c, 0x00f8,
-+	0x00c0, 0x3e06, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c,
-+	0x0300, 0x0040, 0x3a2b, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x3a27, 0x20a1, 0x012b, 0x0078, 0x3a2d, 0x20a1,
-+	0x022b, 0x0078, 0x3a2d, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000,
-+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
-+	0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4313, 0x6818,
-+	0xd0fc, 0x0040, 0x3a45, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822,
-+	0x1078, 0x40d0, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079, 0x3a50,
-+	0x3a55, 0x3b2d, 0x3a53, 0x1078, 0x296b, 0x7cd8, 0x7ddc, 0x7fd0,
-+	0x82ff, 0x00c0, 0x3a7e, 0x7200, 0xa286, 0x0003, 0x0040, 0x33c7,
-+	0x71d4, 0xd1bc, 0x00c0, 0x3a81, 0xd1b4, 0x0040, 0x3a81, 0x0d7e,
-+	0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0xc0a5,
-+	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
-+	0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3a85, 0x7200, 0x0078,
-+	0x3a85, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f, 0x0079,
-+	0x3a89, 0x3b18, 0x3ac7, 0x3a93, 0x33f6, 0x3a91, 0x3b18, 0x3a91,
-+	0x3a91, 0x1078, 0x296b, 0x681c, 0xd0ec, 0x0040, 0x3a9a, 0x6008,
-+	0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005,
-+	0x00c0, 0x3aa3, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
-+	0x000e, 0x00c0, 0x3ab7, 0xb284, 0x0300, 0x0040, 0x3ab3, 0x2009,
-+	0x94c0, 0x0078, 0x3abc, 0x2009, 0x95d0, 0x0078, 0x3abc, 0x7030,
-+	0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e,
-+	0xd6dc, 0x00c0, 0x3ac7, 0xc6fc, 0x6eb6, 0x0078, 0x3b18, 0x6eb6,
-+	0xa684, 0x0060, 0x00c0, 0x3ad1, 0xa684, 0x7fff, 0x68b6, 0x0078,
-+	0x3b18, 0xd6dc, 0x00c0, 0x3adf, 0xa684, 0x7fff, 0x68b6, 0x6894,
-+	0x68a6, 0x6898, 0x68aa, 0x1078, 0x4586, 0x0078, 0x3b18, 0xd6ac,
-+	0x0040, 0x3aeb, 0xa006, 0x1078, 0x4586, 0x2408, 0x2510, 0x69aa,
-+	0x6aa6, 0x0078, 0x3afb, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8,
-+	0x3af2, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa,
-+	0x6aa6, 0x1078, 0x4586, 0xd6fc, 0x0040, 0x3b18, 0xa684, 0x7fff,
-+	0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b10, 0x2700, 0x801b,
-+	0x00c8, 0x3b0b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
-+	0x7000, 0xa086, 0x0030, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x70bc,
-+	0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00,
-+	0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0,
-+	0x3b3a, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
-+	0xfbef, 0x600a, 0x0078, 0x40c1, 0x7047, 0x0000, 0xa282, 0x0006,
-+	0x0050, 0x3b44, 0x1078, 0x296b, 0x2300, 0x0079, 0x3b47, 0x3b4a,
-+	0x3b5c, 0x3b68, 0x2200, 0x0079, 0x3b4d, 0x3b53, 0x40c1, 0x3b55,
-+	0x3b53, 0x3ba2, 0x3bf7, 0x1078, 0x296b, 0x7a80, 0xa294, 0x0f00,
-+	0x1078, 0x3c81, 0x0078, 0x40b7, 0x1078, 0x3b79, 0x0079, 0x3b60,
-+	0x40c1, 0x3b66, 0x3b66, 0x3ba2, 0x3b66, 0x40c1, 0x1078, 0x296b,
-+	0x1078, 0x3b79, 0x0079, 0x3b6c, 0x3b74, 0x3b72, 0x3b72, 0x3b74,
-+	0x3b72, 0x3b74, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
-+	0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b8a, 0x1078, 0x3ded,
-+	0x0078, 0x3b84, 0x1078, 0x4586, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x0078, 0x3b8f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3b82, 0x7003,
-+	0x0005, 0xb284, 0x0300, 0x0040, 0x3b99, 0x2001, 0x95e0, 0x0078,
-+	0x3b9b, 0x2001, 0x9612, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046,
-+	0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bb4, 0x70d4,
-+	0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3bb9,
-+	0x1078, 0x4586, 0x0078, 0x3bb9, 0x7000, 0xa086, 0x0003, 0x0040,
-+	0x3bb0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-+	0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x94c0, 0xb284, 0x0300,
-+	0x00c0, 0x3bcd, 0xc2fd, 0x2069, 0x95d0, 0x2d04, 0x2d08, 0x715e,
-+	0xa06d, 0x0040, 0x3bda, 0x6814, 0xa206, 0x0040, 0x3bdc, 0x6800,
-+	0x0078, 0x3bce, 0x1078, 0x3c81, 0x6eb4, 0x7e5a, 0x6920, 0xa184,
-+	0x0c00, 0x0040, 0x3cab, 0x7064, 0xa086, 0x0006, 0x00c0, 0x3bee,
-+	0x7074, 0xa206, 0x00c0, 0x3bee, 0x7066, 0x707e, 0x681b, 0x0005,
-+	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x0078, 0x3cab, 0x7200,
-+	0xa286, 0x0002, 0x00c0, 0x3c09, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
-+	0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c0d, 0x1078, 0x4586, 0x0078,
-+	0x3c0d, 0xa286, 0x0003, 0x0040, 0x3c05, 0x7003, 0x0001, 0x7a80,
-+	0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215,
-+	0xb284, 0x0300, 0x00c0, 0x3c1d, 0xc2fd, 0x79a8, 0x79a8, 0xa18c,
-+	0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d,
-+	0x0040, 0x3c31, 0x6814, 0xa206, 0x0040, 0x3c5a, 0x6800, 0x0078,
-+	0x3c25, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c3b, 0x2001,
-+	0x95e0, 0x0078, 0x3c3d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
-+	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c42, 0x157f,
-+	0xb284, 0x0300, 0x0040, 0x3c4f, 0xc2fc, 0x0078, 0x3c50, 0xc2fd,
-+	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
-+	0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040, 0x3cab,
-+	0xd0dc, 0x0040, 0x3c76, 0x7064, 0xa086, 0x0004, 0x00c0, 0x3c72,
-+	0x7074, 0xa206, 0x00c0, 0x3c72, 0x7078, 0xa306, 0x00c0, 0x3c72,
-+	0x7066, 0x707e, 0x1078, 0x40d7, 0x0078, 0x3cab, 0x681b, 0x0005,
-+	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x707f, 0x0000, 0x0078,
-+	0x3cab, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c8b, 0x2001,
-+	0x95e0, 0x0078, 0x3c8d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
-+	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c92, 0x157f,
-+	0xb284, 0x0300, 0x0040, 0x3c9f, 0xc2fc, 0x0078, 0x3ca0, 0xc2fd,
-+	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
-+	0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040, 0x3cfd,
-+	0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3cd8, 0x7bd2,
-+	0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d02, 0xd6f4,
-+	0x00c0, 0x3cc3, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
-+	0xd69c, 0x0040, 0x3cd0, 0x2009, 0x0078, 0x2019, 0x0000, 0x2320,
-+	0x791a, 0xd6ec, 0x0040, 0x3d0d, 0x1078, 0x48bd, 0x0078, 0x3d0d,
-+	0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x3d04,
-+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0, 0x3ce9,
-+	0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040, 0x3cf5,
-+	0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0040,
-+	0x3d0d, 0x1078, 0x48f5, 0x0078, 0x3d0d, 0x2019, 0x0000, 0x2320,
-+	0x0078, 0x3d04, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079, 0xd69c,
-+	0x0040, 0x3d0c, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a, 0x2d00,
-+	0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4e01, 0x2004, 0xd0c4,
-+	0x00c0, 0x3d62, 0x70d8, 0xa02d, 0x0040, 0x3d3b, 0xd1bc, 0x0040,
-+	0x3d55, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040, 0x3d2c,
-+	0x78e0, 0xa504, 0x00c0, 0x3d62, 0x70da, 0xc1bc, 0x71d6, 0x0078,
-+	0x3d62, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d3a, 0x8633, 0x8210,
-+	0x0078, 0x3d33, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040, 0x3d48,
-+	0x2011, 0x0008, 0x852f, 0x1078, 0x3d31, 0x8637, 0x0078, 0x3d4a,
-+	0x1078, 0x3d31, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0040,
-+	0x3d62, 0x72de, 0x76da, 0x0078, 0x3d62, 0x7a80, 0xa294, 0x0f00,
-+	0x70dc, 0xa236, 0x0040, 0x3d52, 0x78e0, 0xa534, 0x0040, 0x3d52,
-+	0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x29c1, 0x2300, 0xa405, 0x0040,
-+	0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0x6020,
-+	0xa005, 0x0040, 0x3d7d, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008,
-+	0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006, 0x1078,
-+	0x4586, 0x7000, 0xa086, 0x0002, 0x0040, 0x3d8b, 0x7064, 0xa086,
-+	0x0005, 0x00c0, 0x3d95, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
-+	0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
-+	0x0079, 0x3d9a, 0x29c5, 0x3daa, 0x3da4, 0x3dcc, 0x3db4, 0x29c5,
-+	0x3da2, 0x3da2, 0x1078, 0x296b, 0x1078, 0x3dd7, 0x1078, 0x3dd0,
-+	0x0078, 0x3db0, 0x1078, 0x3dd7, 0x705c, 0x2060, 0x6800, 0x6002,
-+	0x1078, 0x202c, 0x0078, 0x29c5, 0x7064, 0x7067, 0x0000, 0x7083,
-+	0x0000, 0x0079, 0x3dbb, 0x3dc8, 0x3dc8, 0x3dc3, 0x3dc3, 0x3dc3,
-+	0x3dc8, 0x3dc3, 0x3dc8, 0x77d4, 0xc7dd, 0x77d6, 0x0079, 0x2f35,
-+	0x7067, 0x0000, 0x0078, 0x29c5, 0x681b, 0x0000, 0x0078, 0x36c8,
-+	0x6800, 0xa005, 0x00c0, 0x3dd5, 0x6002, 0x6006, 0x007c, 0x6410,
-+	0x84ff, 0x0040, 0x3de9, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a,
-+	0x8421, 0x6412, 0x00c0, 0x3de9, 0x2021, 0x4e04, 0x2404, 0xc0a5,
-+	0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040,
-+	0x3df3, 0x8001, 0x601a, 0x007c, 0x1078, 0x4383, 0x681b, 0x0018,
-+	0x0078, 0x3e34, 0x1078, 0x4383, 0x681b, 0x0019, 0x0078, 0x3e34,
-+	0x1078, 0x4383, 0x681b, 0x001a, 0x0078, 0x3e34, 0x1078, 0x4383,
-+	0x681b, 0x0003, 0x0078, 0x3e34, 0x7774, 0x1078, 0x41fe, 0x7178,
-+	0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e1b, 0xa1e8,
-+	0x93c0, 0x0078, 0x3e1d, 0xa1e8, 0x94d0, 0x2d04, 0x2d08, 0x2068,
-+	0xa005, 0x00c0, 0x3e26, 0x707e, 0x0078, 0x29c5, 0x6814, 0x7274,
-+	0xa206, 0x0040, 0x3e2e, 0x6800, 0x0078, 0x3e1e, 0x6800, 0x200a,
-+	0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3dd7, 0x6820, 0xd084,
-+	0x00c0, 0x3e3c, 0x1078, 0x3dd0, 0x1078, 0x3ded, 0x681f, 0x0000,
-+	0x6823, 0x0020, 0x1078, 0x202c, 0x0078, 0x29c5, 0xa282, 0x0003,
-+	0x00c0, 0x40b7, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8, 0xa6b4,
-+	0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3ea1, 0xc1c4,
-+	0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3e8e, 0xa682, 0x000c, 0x0048,
-+	0x3e65, 0x0040, 0x3e65, 0x2031, 0x000c, 0x2500, 0xa086, 0x000a,
-+	0x0040, 0x3e6c, 0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3e74,
-+	0x1078, 0x3f6f, 0x0078, 0x3e97, 0x1078, 0x414b, 0x0c7e, 0x2960,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x6920,
-+	0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3e8b,
-+	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x7e58,
-+	0xd6d4, 0x00c0, 0x3e9e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
-+	0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3eea,
-+	0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x3eb4,
-+	0x0040, 0x3eb4, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8, 0x3eb9,
-+	0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4,
-+	0x00c0, 0x3ece, 0x78ec, 0xd0e4, 0x0040, 0x3ece, 0xa282, 0x000a,
-+	0x00c8, 0x3ed4, 0x2011, 0x000a, 0x0078, 0x3ed4, 0xa282, 0x000c,
-+	0x00c8, 0x3ed4, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x3ed9,
-+	0x2228, 0x1078, 0x414f, 0x2500, 0xa086, 0x000a, 0x0040, 0x3ee2,
-+	0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3eea, 0x1078, 0x3f6f,
-+	0x0078, 0x3eee, 0x1078, 0x414b, 0x1078, 0x3fa5, 0x7858, 0xc095,
-+	0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960, 0x6000,
-+	0xd0e4, 0x00c0, 0x3f0b, 0xa084, 0x0040, 0x00c0, 0x3f05, 0x6104,
-+	0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019,
-+	0x0000, 0x0078, 0x3f36, 0x68a0, 0xd0cc, 0x00c0, 0x3f05, 0x6208,
-+	0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x3f24,
-+	0x78ec, 0xd0e4, 0x0040, 0x3f24, 0xa282, 0x000b, 0x00c8, 0x3f24,
-+	0x2011, 0x000a, 0x0078, 0x3f2a, 0xa282, 0x000c, 0x00c8, 0x3f2a,
-+	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
-+	0x0048, 0x3f36, 0x0040, 0x3f36, 0x2019, 0x000c, 0x78ab, 0x0001,
-+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
-+	0x6820, 0xc0c5, 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3f52, 0xc0b4,
-+	0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
-+	0x8001, 0x601a, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c,
-+	0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f60,
-+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
-+	0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
-+	0x7158, 0x2160, 0x2018, 0xa08c, 0x0020, 0x0040, 0x3f78, 0xc0ac,
-+	0x2008, 0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae,
-+	0x6612, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4,
-+	0xa39c, 0x0020, 0x0040, 0x3f8e, 0xa085, 0x4000, 0xc0fc, 0xd0b4,
-+	0x00c0, 0x3f93, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f,
-+	0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004,
-+	0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060,
-+	0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884,
-+	0xa084, 0xfff0, 0x7886, 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f,
-+	0x007c, 0xa282, 0x0002, 0x00c0, 0x40b7, 0x7aa8, 0x6920, 0xc1bd,
-+	0x6922, 0xd1cc, 0x0040, 0x3ff4, 0xc1cc, 0x6922, 0xa294, 0x00ff,
-+	0xa282, 0x0002, 0x00c8, 0x40b7, 0x1078, 0x4044, 0x1078, 0x3fa5,
-+	0xa980, 0x0001, 0x200c, 0x1078, 0x41fa, 0x1078, 0x3ef5, 0x88ff,
-+	0x0040, 0x3fea, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695,
-+	0x7e5a, 0xd6d4, 0x00c0, 0x3fe7, 0x781b, 0x0064, 0x007c, 0x781b,
-+	0x0078, 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3ff1, 0x781b, 0x0067,
-+	0x007c, 0x781b, 0x0079, 0x007c, 0xa282, 0x0002, 0x00c8, 0x3ffc,
-+	0xa284, 0x0001, 0x0040, 0x4005, 0x7158, 0xa188, 0x0000, 0x210c,
-+	0xd1ec, 0x00c0, 0x4005, 0x2011, 0x0000, 0x1078, 0x412c, 0x1078,
-+	0x4044, 0x1078, 0x3fa5, 0x7858, 0xc095, 0x785a, 0x781b, 0x0078,
-+	0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec,
-+	0x00c0, 0x4025, 0xa084, 0x0080, 0x00c0, 0x4023, 0xc1a4, 0x6106,
-+	0xa006, 0x0078, 0x4041, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
-+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4,
-+	0x0040, 0x403d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
-+	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200,
-+	0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff,
-+	0x0040, 0x404c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
-+	0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x4059,
-+	0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f,
-+	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x406a, 0x007f,
-+	0x0078, 0x406d, 0x007f, 0x0078, 0x40b4, 0xd6ac, 0x0040, 0x40b4,
-+	0x7888, 0xa084, 0x0040, 0x0040, 0x40b4, 0x7bb8, 0xa384, 0x003f,
-+	0x831b, 0x00c8, 0x407c, 0x8000, 0xa005, 0x0040, 0x4091, 0x831b,
-+	0x00c8, 0x4085, 0x8001, 0x0040, 0x40b1, 0xd6f4, 0x0040, 0x4091,
-+	0x78b8, 0x801b, 0x00c8, 0x408d, 0x8000, 0xa084, 0x003f, 0x00c0,
-+	0x40b1, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
-+	0x00c8, 0x409c, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
-+	0x1078, 0x49c3, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40ac,
-+	0x2001, 0x0000, 0x0078, 0x40ae, 0x2001, 0x0001, 0x1078, 0x484b,
-+	0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078,
-+	0x40df, 0x781b, 0x0078, 0x007c, 0x1078, 0x40c8, 0x781b, 0x0078,
-+	0x007c, 0x6827, 0x0002, 0x1078, 0x40d0, 0x781b, 0x0078, 0x007c,
-+	0x2001, 0x0005, 0x0078, 0x40e1, 0x2001, 0x000c, 0x0078, 0x40e1,
-+	0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x40e1, 0x2001,
-+	0x000d, 0x0078, 0x40e1, 0x2001, 0x0009, 0x0078, 0x40e1, 0x2001,
-+	0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4,
-+	0x0040, 0x40f7, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
-+	0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c,
-+	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e,
-+	0xb28c, 0x0300, 0x0040, 0x4108, 0xa0e0, 0x52c0, 0x0078, 0x410a,
-+	0xa0e0, 0x5340, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
-+	0x000f, 0x0040, 0x411a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
-+	0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
-+	0x0040, 0x412a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
-+	0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
-+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
-+	0x0004, 0x70d4, 0xd0b4, 0x0040, 0x414a, 0xc0b4, 0x70d6, 0x0c7e,
-+	0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-+	0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
-+	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-+	0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040,
-+	0x416e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
-+	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e,
-+	0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a,
-+	0x79a4, 0xa18c, 0xfff0, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9,
-+	0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040,
-+	0x418e, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4183, 0x157f, 0x007c,
-+	0x157e, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x41c1, 0x2021,
-+	0x41f1, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
-+	0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
-+	0x0032, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2019,
-+	0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048,
-+	0x41d7, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41b3, 0x157f, 0x0078,
-+	0x41d5, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
-+	0x0032, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420,
-+	0x2300, 0xa210, 0x00f0, 0x41c9, 0x157f, 0xa006, 0x007c, 0x157f,
-+	0xa582, 0x0064, 0x00c8, 0x41e0, 0x7808, 0xa085, 0x0070, 0x780a,
-+	0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403,
-+	0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07,
-+	0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07,
-+	0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00,
-+	0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
-+	0xd7fc, 0x0040, 0x420f, 0xa0e0, 0x73c0, 0x0078, 0x4211, 0xa0e0,
-+	0x53c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x421f, 0x2079,
-+	0x0100, 0x2009, 0x4e80, 0x2071, 0x4e80, 0x0078, 0x422f, 0x2009,
-+	0x4e40, 0x2071, 0x4e40, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040,
-+	0x422d, 0x2079, 0x0100, 0x0078, 0x422f, 0x2079, 0x0200, 0x2091,
-+	0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4236, 0x4240, 0x4240,
-+	0x4240, 0x4240, 0x4240, 0x4240, 0x423e, 0x423e, 0x1078, 0x296b,
-+	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x428f,
-+	0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086,
-+	0x1814, 0x00c0, 0x428f, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
-+	0x00c0, 0x4255, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
-+	0x425c, 0x7830, 0xd0bc, 0x00c0, 0x428f, 0x007e, 0x2001, 0x4e04,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4271, 0xb284, 0x0300, 0x0078,
-+	0x4273, 0xb284, 0x0400, 0x0040, 0x4279, 0x0018, 0x428f, 0x0078,
-+	0x427b, 0x0028, 0x428f, 0x79e4, 0xa184, 0x0030, 0x0040, 0x428f,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x428f, 0x681c, 0xd0ac, 0x00c0,
-+	0x428d, 0x1078, 0x4319, 0x0078, 0x428f, 0x781b, 0x00f9, 0x0f7f,
-+	0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0,
-+	0x430b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xb28c, 0x0300, 0x0040, 0x42a8, 0xa0e0, 0x52c0, 0x0078, 0x42aa,
-+	0xa0e0, 0x5340, 0x6004, 0xa084, 0x000a, 0x00c0, 0x430b, 0x6108,
-+	0xa194, 0xff00, 0x0040, 0x430b, 0xa18c, 0x00ff, 0x2001, 0x000a,
-+	0xa106, 0x0040, 0x42d6, 0x2001, 0x000c, 0xa106, 0x0040, 0x42da,
-+	0x2001, 0x0012, 0xa106, 0x0040, 0x42de, 0x2001, 0x0014, 0xa106,
-+	0x0040, 0x42e2, 0x2001, 0x0019, 0xa106, 0x0040, 0x42e6, 0x2001,
-+	0x0032, 0xa106, 0x0040, 0x42ea, 0x0078, 0x42ee, 0x2009, 0x000c,
-+	0x0078, 0x42f0, 0x2009, 0x0012, 0x0078, 0x42f0, 0x2009, 0x0014,
-+	0x0078, 0x42f0, 0x2009, 0x0019, 0x0078, 0x42f0, 0x2009, 0x0020,
-+	0x0078, 0x42f0, 0x2009, 0x003f, 0x0078, 0x42f0, 0x2011, 0x0000,
-+	0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061,
-+	0x4e00, 0x6004, 0xd0bc, 0x0040, 0x430b, 0x6814, 0xd0fc, 0x00c0,
-+	0x4306, 0x60ea, 0x2061, 0x4e40, 0x0078, 0x4309, 0x60ee, 0x2061,
-+	0x4e80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
-+	0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064,
-+	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x432b,
-+	0xa186, 0x0001, 0x0040, 0x432e, 0x701f, 0x000b, 0x7067, 0x0001,
-+	0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a,
-+	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4346,
-+	0xa186, 0x0001, 0x0040, 0x4343, 0x701f, 0x000b, 0x7067, 0x0001,
-+	0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef,
-+	0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b,
-+	0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040,
-+	0x435b, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
-+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x4382, 0x7808, 0xc08c, 0x780a,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0,
-+	0x437f, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x437d, 0x7804,
-+	0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808,
-+	0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830,
-+	0xa084, 0x0040, 0x00c0, 0x4387, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-+	0x0040, 0x4396, 0xb284, 0x0300, 0x0078, 0x4398, 0xb284, 0x0400,
-+	0x0040, 0x439e, 0x0098, 0x43a2, 0x0078, 0x43a0, 0x00a8, 0x43a2,
-+	0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
-+	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x43c5, 0x007e,
-+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x43bb, 0xb284,
-+	0x0300, 0x0078, 0x43bd, 0xb284, 0x0400, 0x0040, 0x43c3, 0x0098,
-+	0x43bf, 0x0078, 0x43c5, 0x00a8, 0x43c3, 0x78ac, 0x007e, 0x7808,
-+	0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
-+	0x3770, 0xa784, 0x0070, 0x0040, 0x43dd, 0x0c7e, 0x2d60, 0x2f68,
-+	0x1078, 0x28df, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
-+	0x43ea, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3770,
-+	0x0078, 0x430d, 0xa784, 0x0004, 0x0040, 0x4419, 0x78b8, 0xa084,
-+	0x4001, 0x0040, 0x4419, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x3770, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
-+	0x4419, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
-+	0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4416, 0x681b,
-+	0x0015, 0xd6f4, 0x0040, 0x4416, 0x681b, 0x0007, 0x1078, 0x4319,
-+	0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f,
-+	0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x3066, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
-+	0x0040, 0x4436, 0xb284, 0x0300, 0x0078, 0x4438, 0xb284, 0x0400,
-+	0x0040, 0x443e, 0x0018, 0x29c1, 0x0078, 0x4440, 0x0028, 0x29c1,
-+	0x0078, 0x40bc, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0xd3fc, 0x0040, 0x4450, 0xa080, 0x5340, 0x0078, 0x4452,
-+	0xa080, 0x52c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014,
-+	0x9914, 0x98fd, 0x0014, 0x0014, 0x0080, 0x00ff, 0x0100, 0x0402,
-+	0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
-+	0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
-+	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
-+	0x0010, 0xa200, 0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c4,
-+	0x0864, 0xa856, 0x3008, 0x28c1, 0x9d1b, 0xa201, 0x300c, 0x2847,
-+	0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2,
-+	0x9ccb, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1,
-+	0x9ccb, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0,
-+	0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020,
-+	0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2,
-+	0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814,
-+	0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942,
-+	0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576,
-+	0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d1b, 0x2044,
-+	0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x0904, 0xa20e, 0xa809,
-+	0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601,
-+	0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9ccb,
-+	0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844,
-+	0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014,
-+	0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014,
-+	0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014,
-+	0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d33, 0x8000,
-+	0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d39, 0xa8bd, 0x3008, 0x9d33,
-+	0x283b, 0x1011, 0xa8fd, 0xa209, 0x7102, 0x805f, 0x9481, 0x0017,
-+	0x300c, 0xa209, 0x8000, 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014,
-+	0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0,
-+	0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d25,
-+	0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016,
-+	0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021,
-+	0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822,
-+	0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944,
-+	0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4,
-+	0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
-+	0x00c0, 0x45a2, 0x720c, 0x82ff, 0x0040, 0x459d, 0x8aff, 0x00c0,
-+	0x45a2, 0x7200, 0xd284, 0x00c0, 0x45a2, 0x7003, 0x0008, 0x127f,
-+	0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084,
-+	0x0040, 0x45e5, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45aa,
-+	0xa184, 0x0003, 0x0040, 0x4616, 0xa184, 0x01e0, 0x00c0, 0x4616,
-+	0xd1f4, 0x00c0, 0x45aa, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
-+	0x45aa, 0x2011, 0x0180, 0x710c, 0x8211, 0x0040, 0x45cf, 0x7008,
-+	0xd0f4, 0x00c0, 0x45aa, 0x700c, 0xa106, 0x0040, 0x45c4, 0x7007,
-+	0x0012, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45d1, 0xa184,
-+	0x0003, 0x0040, 0x4616, 0xd194, 0x0040, 0x45d1, 0xd1f4, 0x0040,
-+	0x4616, 0x7007, 0x0002, 0x0078, 0x45aa, 0x7108, 0xd1fc, 0x0040,
-+	0x45f0, 0x1078, 0x4769, 0x8aff, 0x0040, 0x458c, 0x0078, 0x45e5,
-+	0x700c, 0xa08c, 0x03ff, 0x0040, 0x461b, 0x7004, 0xd084, 0x0040,
-+	0x460d, 0x7014, 0xa005, 0x00c0, 0x4609, 0x7010, 0x7310, 0xa306,
-+	0x00c0, 0x45fd, 0x2300, 0xa005, 0x0040, 0x460d, 0xa102, 0x00c8,
-+	0x45e5, 0x7007, 0x0010, 0x0078, 0x4616, 0x8aff, 0x0040, 0x461b,
-+	0x1078, 0x4970, 0x00c0, 0x4610, 0x0040, 0x45e5, 0x1078, 0x46b4,
-+	0x127f, 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8,
-+	0x462a, 0x7007, 0x0002, 0x0078, 0x461b, 0x7003, 0x0008, 0x127f,
-+	0x2000, 0x007c, 0xa205, 0x00c0, 0x4616, 0x7003, 0x0008, 0x127f,
-+	0x2000, 0x007c, 0x6428, 0x84ff, 0x0040, 0x465e, 0x2c70, 0x7004,
-+	0xa0bc, 0x000f, 0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x464c,
-+	0x0048, 0x4644, 0x1078, 0x296b, 0x609c, 0xa075, 0x0040, 0x465e,
-+	0x0078, 0x4637, 0x2039, 0x4663, 0x2704, 0xae68, 0x6808, 0xa630,
-+	0x680c, 0xa529, 0x8421, 0x0040, 0x465e, 0x8738, 0x2704, 0xa005,
-+	0x00c0, 0x464d, 0x709c, 0xa075, 0x00c0, 0x4637, 0x007c, 0x0000,
-+	0x0005, 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000,
-+	0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4663,
-+	0x4660, 0x0000, 0x0000, 0x8000, 0x0000, 0x4663, 0x0000, 0x466b,
-+	0x4668, 0x0000, 0x0000, 0x0000, 0x0000, 0x466b, 0x0000, 0x4666,
-+	0x4666, 0x0000, 0x0000, 0x8000, 0x0000, 0x4666, 0x0000, 0x466c,
-+	0x466c, 0x0000, 0x0000, 0x0000, 0x0000, 0x466c, 0x2079, 0x4e00,
-+	0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001,
-+	0x7810, 0xd0ec, 0x0040, 0x46a2, 0x2009, 0x0001, 0x2071, 0x0020,
-+	0x0078, 0x46a6, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a,
-+	0x7007, 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x46b3, 0x2071,
-+	0x0020, 0x0078, 0x46a6, 0x007c, 0x7004, 0x8004, 0x00c8, 0x473d,
-+	0x7108, 0x7008, 0xa106, 0x00c0, 0x46b8, 0xa184, 0x01e0, 0x0040,
-+	0x46c5, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x2019,
-+	0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x46c9, 0xa184, 0x01e0,
-+	0x0040, 0x46d6, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7810, 0xd0ec,
-+	0x0040, 0x46f0, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0,
-+	0x46f4, 0xa184, 0x4000, 0x0040, 0x46f8, 0xa382, 0x0003, 0x00c8,
-+	0x46f8, 0xa184, 0x0004, 0x0040, 0x46c9, 0x8318, 0x0078, 0x46c9,
-+	0x7814, 0xd0ec, 0x00c0, 0x46f8, 0xa184, 0x4000, 0x00c0, 0x46c9,
-+	0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4715, 0xa386, 0x0008,
-+	0x0040, 0x4720, 0x7004, 0xd084, 0x00c0, 0x4711, 0x7108, 0x7008,
-+	0xa106, 0x00c0, 0x4706, 0xa184, 0x0003, 0x0040, 0x4711, 0x0078,
-+	0x47ac, 0xa386, 0x200c, 0x00c0, 0x46c9, 0x7200, 0x8204, 0x0048,
-+	0x4720, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4720, 0x1078, 0x296b,
-+	0x7108, 0x7008, 0xa106, 0x00c0, 0x4720, 0xa184, 0x01e0, 0x0040,
-+	0x472d, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x7000,
-+	0xd084, 0x00c0, 0x473d, 0x7310, 0x7014, 0xa305, 0x0040, 0x473d,
-+	0x710c, 0xa184, 0x03ff, 0x00c0, 0x46b4, 0x7108, 0x7008, 0xa106,
-+	0x00c0, 0x473d, 0xa184, 0x01e0, 0x0040, 0x474a, 0x1078, 0x47ac,
-+	0x0078, 0x4765, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c,
-+	0x00c0, 0x474e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4752, 0xa184,
-+	0x01e0, 0x0040, 0x475f, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007,
-+	0x0012, 0x7108, 0x8103, 0x0048, 0x4752, 0x7003, 0x0008, 0x007c,
-+	0x7108, 0xa184, 0x01e0, 0x00c0, 0x47ac, 0x7108, 0xa184, 0x01e0,
-+	0x00c0, 0x47ac, 0xa184, 0x0007, 0x0079, 0x4776, 0x4780, 0x4790,
-+	0x477e, 0x4790, 0x477e, 0x47ee, 0x477e, 0x47ec, 0x1078, 0x296b,
-+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, 0x478b,
-+	0x2049, 0x0000, 0x007c, 0x1078, 0x4970, 0x00c0, 0x478b, 0x007c,
-+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x00c0,
-+	0x47a4, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4799, 0xa184, 0x0003,
-+	0x0040, 0x47a4, 0x0078, 0x47ac, 0x8aff, 0x0040, 0x47ab, 0x1078,
-+	0x4970, 0x00c0, 0x47a7, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0,
-+	0x47af, 0x2091, 0x6000, 0x00e0, 0x47b3, 0x2091, 0x6000, 0x7007,
-+	0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47bb, 0x7007,
-+	0x0012, 0x7108, 0xd1fc, 0x00c0, 0x47bf, 0x7003, 0x0000, 0x7000,
-+	0xa005, 0x00c0, 0x47d3, 0x7004, 0xa005, 0x00c0, 0x47d3, 0x700c,
-+	0xa005, 0x0040, 0x47d5, 0x0078, 0x47b7, 0x2049, 0x0000, 0xb284,
-+	0x0100, 0x0040, 0x47df, 0x2001, 0x0000, 0x0078, 0x47e1, 0x2001,
-+	0x0001, 0x1078, 0x4212, 0x681b, 0x0002, 0x2051, 0x0000, 0x007c,
-+	0x1078, 0x296b, 0x1078, 0x296b, 0x1078, 0x4836, 0x7210, 0x7114,
-+	0x700c, 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
-+	0x1078, 0x4836, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322,
-+	0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4811, 0x00c8,
-+	0x4811, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
-+	0x47f8, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040,
-+	0x481d, 0xa7ba, 0x4668, 0x0078, 0x481f, 0xa7ba, 0x4660, 0x007f,
-+	0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, 0x7008,
-+	0xa106, 0x00c0, 0x4826, 0xa184, 0x01e0, 0x0040, 0x4831, 0x1078,
-+	0x47ac, 0x7007, 0x0012, 0x1078, 0x46b4, 0x007c, 0x8a50, 0x8739,
-+	0x2704, 0xa004, 0x00c0, 0x484a, 0x6000, 0xa064, 0x00c0, 0x4841,
-+	0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x467e, 0x203c, 0x87fb,
-+	0x1040, 0x296b, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600,
-+	0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
-+	0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
-+	0x0008, 0x007f, 0x0040, 0x4868, 0xa0b8, 0x4668, 0x0078, 0x486a,
-+	0xa0b8, 0x4660, 0xb284, 0x0100, 0x0040, 0x4871, 0x7e20, 0x0078,
-+	0x4872, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4879,
-+	0xc685, 0x2400, 0xa305, 0x0040, 0x48a3, 0x2c58, 0x2704, 0x6104,
-+	0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
-+	0x0008, 0x0040, 0x4893, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
-+	0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
-+	0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
-+	0x499b, 0x0078, 0x48a5, 0x1078, 0x4970, 0x00c0, 0x48a3, 0x127f,
-+	0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004,
-+	0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x48b4,
-+	0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4,
-+	0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x0d7f, 0x7e20,
-+	0xb284, 0x0100, 0x00c0, 0x48cd, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-+	0xd0ac, 0x00c0, 0x48d8, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
-+	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x466e,
-+	0x273c, 0x87fb, 0x00c0, 0x48ee, 0x0048, 0x48e8, 0x1078, 0x296b,
-+	0x689c, 0xa065, 0x0040, 0x48f2, 0x0078, 0x48db, 0x1078, 0x4970,
-+	0x00c0, 0x48ee, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-+	0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f,
-+	0x7e20, 0xb284, 0x0100, 0x00c0, 0x4906, 0x7e24, 0x0d7f, 0x037f,
-+	0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4914, 0xc685,
-+	0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x48f5, 0x6828, 0xa055,
-+	0x0d7e, 0x0040, 0x496c, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
-+	0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x4931, 0x0048, 0x492a,
-+	0x1078, 0x296b, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c, 0x0078,
-+	0x491d, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
-+	0x494a, 0x8a51, 0x00c0, 0x493e, 0x1078, 0x296b, 0x8738, 0x2704,
-+	0xa005, 0x00c0, 0x4932, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c,
-+	0x0078, 0x491d, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
-+	0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4959, 0x1078,
-+	0x296b, 0xb284, 0x0100, 0x0040, 0x4967, 0x2001, 0x4e04, 0x2004,
-+	0xd0ec, 0x00c0, 0x4967, 0x2071, 0x0050, 0x0078, 0x4969, 0x2071,
-+	0x0020, 0x0d7f, 0x0078, 0x4879, 0x0d7f, 0x127f, 0x2000, 0x007c,
-+	0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x4979, 0xa006,
-+	0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0, 0x4980, 0x007c,
-+	0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012,
-+	0x780c, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4993, 0x7810,
-+	0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085,
-+	0x7006, 0x2079, 0x4e00, 0x8a51, 0x0040, 0x49bf, 0x8738, 0x2704,
-+	0xa005, 0x00c0, 0x49b1, 0x609c, 0xa005, 0x0040, 0x49c0, 0x2060,
-+	0x6004, 0xa084, 0x000f, 0xa080, 0x466e, 0x203c, 0x87fb, 0x1040,
-+	0x296b, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x49bb,
-+	0xa006, 0x0078, 0x49c0, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c,
-+	0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003,
-+	0x00c0, 0x49d8, 0x6828, 0xa005, 0x0040, 0x49e8, 0x0078, 0x45a2,
-+	0x7108, 0xd1fc, 0x0040, 0x49e0, 0x1078, 0x4769, 0x0078, 0x49cd,
-+	0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x49e2, 0x1078, 0x4769,
-+	0x7008, 0xa086, 0x0008, 0x00c0, 0x49cd, 0x7000, 0xa005, 0x00c0,
-+	0x49cd, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x49f8, 0xad80, 0x0011,
-+	0x20a0, 0xb284, 0x0100, 0x0040, 0x4a1b, 0x2001, 0x4e04, 0x2004,
-+	0xd0ec, 0x0040, 0x4a17, 0x2099, 0x0031, 0x0078, 0x4a1d, 0x2099,
-+	0x0032, 0x0078, 0x4a1d, 0x2099, 0x0031, 0x700c, 0xa084, 0x03ff,
-+	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040,
-+	0x4a2c, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040,
-+	0x4a38, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a33,
-+	0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f,
-+	0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac,
-+	0xa005, 0x00c0, 0x4a5a, 0x7974, 0x70d0, 0xa106, 0x00c0, 0x4a5a,
-+	0x781c, 0xa005, 0x0040, 0x4a5a, 0x781f, 0x0000, 0x0068, 0x4a5a,
-+	0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, 0x4ae2, 0x7834,
-+	0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4adb, 0x2061, 0x73c0, 0x2069,
-+	0x4e80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4a74, 0x8001, 0x68d2,
-+	0x00c0, 0x4a74, 0x1078, 0x4cb0, 0x6800, 0xa084, 0x000f, 0x0040,
-+	0x4a89, 0xa086, 0x0001, 0x0040, 0x4a89, 0x6844, 0xa00d, 0x0040,
-+	0x4a89, 0x2104, 0xa005, 0x0040, 0x4a89, 0x8001, 0x200a, 0x0040,
-+	0x4c23, 0x6814, 0xa005, 0x0040, 0x4aae, 0x8001, 0x6816, 0x00c0,
-+	0x4aae, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, 0x4aa3, 0x7810,
-+	0xd0ec, 0x0040, 0x4a9f, 0x2079, 0x0100, 0x0078, 0x4aa5, 0x2079,
-+	0x0200, 0x0078, 0x4aa5, 0x2079, 0x0100, 0x1078, 0x4383, 0x0f7f,
-+	0x6864, 0xa005, 0x0040, 0x4aae, 0x1078, 0x2628, 0x6880, 0xa005,
-+	0x0040, 0x4abb, 0x8001, 0x6882, 0x00c0, 0x4abb, 0x6867, 0x0000,
-+	0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, 0x4ad8, 0xc0fc,
-+	0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0040, 0x4ad4, 0x8001,
-+	0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x4ad4, 0x6010, 0xa005,
-+	0x0040, 0x4ad4, 0x1078, 0x2628, 0xace0, 0x0010, 0x00f0, 0x4ac3,
-+	0xd7fc, 0x0040, 0x4ae2, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
-+	0x0078, 0x4a6a, 0x1078, 0x4b1e, 0x7838, 0x8001, 0x783a, 0x00c0,
-+	0x4b04, 0x783c, 0x783a, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
-+	0x680c, 0xa005, 0x0040, 0x4af6, 0x1078, 0x4b88, 0xd7fc, 0x00c0,
-+	0x4b04, 0x7810, 0xd0ec, 0x00c0, 0x4b04, 0x2061, 0x73c0, 0x2069,
-+	0x4e80, 0xc7fd, 0x0078, 0x4af0, 0x7814, 0xd0e4, 0x00c0, 0x4b08,
-+	0x7810, 0xd0cc, 0x0040, 0x4b1b, 0xd0ac, 0x00c0, 0x4b14, 0xd0a4,
-+	0x0040, 0x4b1b, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0068, 0x4b1a,
-+	0x1078, 0x2395, 0x007c, 0x2091, 0x8001, 0x007c, 0x7840, 0x8001,
-+	0x7842, 0x00c0, 0x4b87, 0x7844, 0x7842, 0x2069, 0x4e40, 0xc7fc,
-+	0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040, 0x4b30, 0x2079, 0x0100,
-+	0x68d8, 0xa005, 0x0040, 0x4b3c, 0x7de0, 0xa504, 0x00c0, 0x4b3c,
-+	0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079, 0x4e00, 0x6810, 0xa005,
-+	0x00c0, 0x4b44, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040,
-+	0x4b4d, 0xa080, 0x94d0, 0x0078, 0x4b4f, 0xa080, 0x93c0, 0x2040,
-+	0x2004, 0xa065, 0x0040, 0x4b79, 0x6024, 0xa005, 0x0040, 0x4b75,
-+	0x8001, 0x6026, 0x00c0, 0x4b75, 0x6800, 0xa005, 0x0040, 0x4b68,
-+	0x684c, 0xac06, 0x00c0, 0x4b68, 0x1078, 0x4c23, 0x0078, 0x4b79,
-+	0x6864, 0xa005, 0x0040, 0x4b70, 0x6027, 0x0001, 0x0078, 0x4b75,
-+	0x1078, 0x4bd6, 0x2804, 0x0078, 0x4b51, 0x6000, 0x2c40, 0x0078,
-+	0x4b51, 0xd7fc, 0x00c0, 0x4b87, 0x7810, 0xd0ec, 0x00c0, 0x4b87,
-+	0x2069, 0x4e80, 0xc7fd, 0x2079, 0x0100, 0x0078, 0x4b30, 0x007c,
-+	0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4bc2,
-+	0x6024, 0xa005, 0x0040, 0x4b98, 0x8001, 0x6026, 0x0078, 0x4bc0,
-+	0x6008, 0xc09c, 0xd084, 0x00c0, 0x4ba0, 0xd0ac, 0x0040, 0x4bba,
-+	0x600a, 0x6004, 0xa005, 0x0040, 0x4bc2, 0x0d7e, 0x0c7e, 0x017e,
-+	0x2068, 0x6010, 0x8001, 0x6012, 0x1078, 0x3dd0, 0x2d00, 0x2c68,
-+	0x2060, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x017f, 0x0c7f, 0x0d7f,
-+	0x0078, 0x4bc2, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4bc2,
-+	0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x4b8c, 0xa184, 0x0001,
-+	0x0040, 0x4bd1, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x2628, 0x0078,
-+	0x4bd2, 0x690e, 0x007c, 0x00c0, 0x4bd2, 0x786c, 0x2c00, 0x687e,
-+	0x6714, 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006,
-+	0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-+	0x0060, 0x6022, 0x6000, 0x2042, 0x1078, 0x1de4, 0x6818, 0xa005,
-+	0x0040, 0x4bf4, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
-+	0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, 0x4c00, 0x1078, 0x296b,
-+	0x6812, 0x00c0, 0x4c06, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000,
-+	0x6033, 0x0000, 0x2c68, 0x1078, 0x202c, 0xd7fc, 0x00c0, 0x4c14,
-+	0x2069, 0x4e40, 0x0078, 0x4c16, 0x2069, 0x4e80, 0x6910, 0xa184,
-+	0x0100, 0x2001, 0x0006, 0x00c0, 0x4c20, 0x697a, 0x2001, 0x0004,
-+	0x1078, 0x261c, 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0,
-+	0x4c35, 0x7810, 0xd0ec, 0x0040, 0x4c31, 0x2069, 0x0100, 0x0078,
-+	0x4c37, 0x2069, 0x0200, 0x0078, 0x4c37, 0x2069, 0x0100, 0x1078,
-+	0x28df, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020,
-+	0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033,
-+	0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x0040,
-+	0x4c69, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0040,
-+	0x4c5b, 0x00f0, 0x4c55, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848,
-+	0xd084, 0x0040, 0x4c65, 0x00f0, 0x4c5f, 0x20a9, 0x00fa, 0x00f0,
-+	0x4c67, 0x681b, 0x0047, 0x0d7f, 0x6867, 0x0007, 0x007c, 0x2079,
-+	0x4e00, 0x1078, 0x4ca3, 0x1078, 0x4c89, 0x1078, 0x4c96, 0x2009,
-+	0x0002, 0x2069, 0x4e80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817,
-+	0x0000, 0x8109, 0x0040, 0x4c88, 0x2069, 0x4e40, 0x0078, 0x4c7b,
-+	0x007c, 0x7810, 0xd0ec, 0x0040, 0x4c91, 0x2019, 0x00cc, 0x0078,
-+	0x4c93, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4,
-+	0x00c0, 0x4c9e, 0x2019, 0x0040, 0x0078, 0x4ca0, 0x2019, 0x0026,
-+	0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4cab, 0x2019,
-+	0x3f94, 0x0078, 0x4cad, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c,
-+	0x6a50, 0xa285, 0x0000, 0x0040, 0x4cdc, 0x6954, 0x6bc0, 0xa300,
-+	0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0, 0x4cc8, 0x8211, 0x0040,
-+	0x4ccc, 0x8108, 0xa11a, 0x0048, 0x4cb9, 0x69c0, 0x0078, 0x4cb9,
-+	0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950, 0x6ac0, 0x2264, 0x602b,
-+	0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
-+	0x00c0, 0x4cce, 0x6952, 0x0c7f, 0x007c, 0x00e0, 0x4cdd, 0x2091,
-+	0x6000, 0x00e0, 0x4ce1, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x00c0,
-+	0x4cee, 0xd0d4, 0x0040, 0x4d17, 0x0078, 0x4d1a, 0x2008, 0x7810,
-+	0xd0ec, 0x0040, 0x4d01, 0xd1c4, 0x00c0, 0x4d39, 0x7814, 0xc0c5,
-+	0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x4d35, 0x0078,
-+	0x4d31, 0xae8e, 0x0100, 0x0040, 0x4d0e, 0x7814, 0xc0f5, 0xc0c5,
-+	0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0x7814, 0xc0fd,
-+	0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0xd0e4,
-+	0x0040, 0x4d37, 0x00e0, 0x4d1a, 0x2091, 0x6000, 0x2009, 0x000c,
-+	0x00e0, 0x4d20, 0x2091, 0x6000, 0x8109, 0x00c0, 0x4d20, 0x70e4,
-+	0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0, 0x4d31, 0x70ec, 0x0078,
-+	0x4cee, 0x7804, 0xd08c, 0x0040, 0x4d37, 0x681f, 0x000c, 0x70a0,
-+	0x70a2, 0x007c, 0x205b
-+};
-+#else
-+/************************************************************************
-+ *									*
-+ *	 --- ISP1240/ISP1080/ISP1280 Initiator/Target Firmware ---      *
-+ *			    32 LUN Support				*
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 9.11.01 (15:46 May 23, 2000)
-+ */
-+
-+static const u_int16_t isp_1080_risc_code[] = {
-+	0x0078, 0x103a, 0x0000, 0x4f62, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
-+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
-+	0x3132, 0x3430, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
-+	0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x392e, 0x3131,
-+	0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
-+	0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
-+	0x3031, 0x2024, 0x20c9, 0xabff, 0x2001, 0x04fc, 0x2004, 0xa086,
-+	0x1080, 0x00c0, 0x104d, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1,
-+	0x0010, 0x2089, 0x136f, 0x0078, 0x1066, 0x2001, 0x04fc, 0x2004,
-+	0xa086, 0x1280, 0x00c0, 0x1062, 0x2071, 0x0200, 0x70a0, 0x70a2,
-+	0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f3,
-+	0x0078, 0x1066, 0x20c1, 0x0020, 0x2089, 0x1317, 0x2071, 0x0010,
-+	0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
-+	0x70d3, 0x0009, 0x2001, 0x04fd, 0x70d6, 0x20c1, 0x0021, 0x2019,
-+	0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff,
-+	0x2d64, 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050,
-+	0x2114, 0xa286, 0xa5a5, 0x0040, 0x109d, 0xa386, 0x000f, 0x0040,
-+	0x1099, 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078,
-+	0x1079, 0x2c6a, 0x2a5a, 0x0078, 0x109b, 0x2c6a, 0x2a5a, 0x2130,
-+	0x2128, 0xa1a2, 0x6000, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-+	0x8424, 0xa192, 0xac00, 0x2009, 0x0000, 0x2001, 0x0037, 0x1078,
-+	0x22c0, 0x2218, 0x2079, 0x6000, 0x2fa0, 0x2408, 0x2011, 0x0000,
-+	0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10b8, 0x2009, 0xff00,
-+	0x3400, 0xa102, 0x0048, 0x10c8, 0x0040, 0x10c8, 0x20a8, 0x42a4,
-+	0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e0, 0x2071,
-+	0x0100, 0x0d7e, 0x2069, 0x6040, 0x1078, 0x5d94, 0x0d7f, 0x7808,
-+	0xc0ed, 0x780a, 0x7813, 0x0064, 0x2011, 0x000a, 0x0078, 0x1107,
-+	0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, 0x00c0, 0x1100, 0x780c,
-+	0xc0ed, 0xc0d5, 0x780e, 0x7813, 0x0064, 0x2071, 0x0200, 0x0d7e,
-+	0x2069, 0x6040, 0x1078, 0x5d94, 0x2069, 0x6080, 0x2071, 0x0100,
-+	0x1078, 0x5d94, 0x780c, 0xc0d4, 0x780e, 0x0d7f, 0x0078, 0x1107,
-+	0x780c, 0xc0e5, 0x780e, 0x7813, 0x003c, 0x2011, 0x000c, 0x2009,
-+	0x604c, 0x220a, 0x2009, 0x608c, 0x220a, 0x7ece, 0x7cc6, 0x7bca,
-+	0x785f, 0x0000, 0x7800, 0xc08d, 0x7802, 0x2031, 0x0030, 0x78b3,
-+	0x0101, 0x781b, 0x0002, 0x781f, 0x0002, 0x2009, 0x0002, 0x2069,
-+	0x6040, 0x6817, 0x0003, 0x681f, 0x0007, 0x6823, 0x00fa, 0x6827,
-+	0x0008, 0x682b, 0x0028, 0x6837, 0x0006, 0x682f, 0x0008, 0x683b,
-+	0x0000, 0x8109, 0x0040, 0x1158, 0x68ef, 0x000a, 0x68df, 0x60c0,
-+	0x2079, 0x6000, 0x780c, 0xd0e4, 0x00c0, 0x1142, 0x68f3, 0x7329,
-+	0x0078, 0x1144, 0x68f3, 0x730d, 0x68e3, 0x65c0, 0x68e7, 0x64c0,
-+	0x68eb, 0xa5c0, 0x68c7, 0xaa8e, 0x68cb, 0xaa93, 0x68cf, 0xaa8e,
-+	0x68d3, 0xaa8e, 0x68c3, 0x0001, 0x2069, 0x6080, 0x0078, 0x1121,
-+	0x68ef, 0x000a, 0x68df, 0x62c0, 0x68f3, 0x7419, 0x68e3, 0x85c0,
-+	0x68e7, 0x6540, 0x68eb, 0xa6d0, 0x68c7, 0xaa93, 0x68cb, 0xaa98,
-+	0x68cf, 0xaa93, 0x68d3, 0xaa93, 0x68c3, 0x0001, 0x7808, 0xd0ec,
-+	0x00c0, 0x11b4, 0x780c, 0xd0e4, 0x00c0, 0x11a6, 0x0e7e, 0x2069,
-+	0x64c0, 0x2071, 0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1187, 0x2019,
-+	0x0c0c, 0x2021, 0x000c, 0x1078, 0x222c, 0x0078, 0x118d, 0x2019,
-+	0x0c0a, 0x2021, 0x000a, 0x1078, 0x222c, 0x2069, 0x6540, 0x2071,
-+	0x0100, 0x70ec, 0xd0e4, 0x00c0, 0x119d, 0x2019, 0x0c0c, 0x2021,
-+	0x000c, 0x1078, 0x222c, 0x0078, 0x11a3, 0x2019, 0x0c0a, 0x2021,
-+	0x000a, 0x1078, 0x222c, 0x0e7f, 0x0078, 0x11cd, 0x2019, 0x0c0c,
-+	0x2021, 0x000c, 0x2069, 0x64c0, 0x1078, 0x222c, 0x2069, 0x6540,
-+	0x1078, 0x222c, 0x0078, 0x11cd, 0x2069, 0x64c0, 0x0e7e, 0x2071,
-+	0x0100, 0x70ec, 0xd0e4, 0x00c0, 0x11c6, 0x2019, 0x0c0c, 0x2021,
-+	0x000c, 0x1078, 0x222c, 0x0e7f, 0x0078, 0x11cd, 0x2019, 0x0c0a,
-+	0x2021, 0x000a, 0x1078, 0x222c, 0x0e7f, 0x2011, 0x0002, 0x2069,
-+	0x65c0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
-+	0x0040, 0x7bcc, 0xa386, 0xfeff, 0x00c0, 0x11e4, 0x6817, 0x0100,
-+	0x681f, 0x0064, 0x0078, 0x11e8, 0x6817, 0x0064, 0x681f, 0x0002,
-+	0xade8, 0x0010, 0x00f0, 0x11d5, 0x8109, 0x00c0, 0x11d3, 0x8211,
-+	0x0040, 0x11f6, 0x2069, 0x85c0, 0x0078, 0x11d1, 0x1078, 0x28df,
-+	0x1078, 0x56b4, 0x1078, 0x1e5e, 0x1078, 0x5d2a, 0x2091, 0x2100,
-+	0x2079, 0x6000, 0x7808, 0xd0ec, 0x0040, 0x120a, 0x2071, 0x0020,
-+	0x0078, 0x120c, 0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x6000,
-+	0x2071, 0x0020, 0x2091, 0x2300, 0x2079, 0x6000, 0x7808, 0xd0ec,
-+	0x0040, 0x121e, 0x2079, 0x0100, 0x0078, 0x1220, 0x2079, 0x0200,
-+	0x2071, 0x6040, 0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x6080,
-+	0x2091, 0x2000, 0x2079, 0x6000, 0x2071, 0x0010, 0x3200, 0xa085,
-+	0x303d, 0x2090, 0x70c3, 0x0000, 0x0090, 0x123d, 0x70c0, 0xa086,
-+	0x0002, 0x00c0, 0x123d, 0x1078, 0x15ae, 0x2039, 0x0000, 0x7808,
-+	0xd0ec, 0x00c0, 0x12c7, 0x1078, 0x1477, 0x78b0, 0xa005, 0x00c0,
-+	0x125f, 0x0068, 0x1253, 0x7868, 0xa065, 0x0040, 0x1253, 0x2029,
-+	0x0000, 0x1078, 0x2774, 0x1078, 0x22e7, 0x0068, 0x126c, 0x7868,
-+	0xa065, 0x0040, 0x125f, 0x2029, 0x0000, 0x1078, 0x2774, 0x0068,
-+	0x126c, 0x2009, 0x6046, 0x2011, 0x6086, 0x2104, 0x220c, 0xa105,
-+	0x0040, 0x126c, 0x1078, 0x1f9d, 0x0e7e, 0x0f7e, 0x2071, 0x6040,
-+	0x70c0, 0xa005, 0x0040, 0x1295, 0x7454, 0xa485, 0x0000, 0x0040,
-+	0x1295, 0x2079, 0x0200, 0x2091, 0x8000, 0x72f0, 0xa28c, 0x303d,
-+	0x2190, 0x1078, 0x2e28, 0x2091, 0x8000, 0x2091, 0x303d, 0x0068,
-+	0x1295, 0x0f7f, 0x7868, 0xa065, 0x0040, 0x1294, 0x0e7f, 0x2029,
-+	0x0000, 0x1078, 0x2774, 0x0e7e, 0x0f7e, 0x00e0, 0x129d, 0x0f7f,
-+	0x0e7f, 0x1078, 0x5b00, 0x0e7e, 0x0f7e, 0x2071, 0x6080, 0x70c0,
-+	0xa005, 0x0040, 0x12b6, 0x7454, 0xa485, 0x0000, 0x0040, 0x12b6,
-+	0x2079, 0x0100, 0x2091, 0x8000, 0x72f0, 0xa28c, 0x303d, 0x2190,
-+	0x1078, 0x2e28, 0x2091, 0x8000, 0x2091, 0x303d, 0x0f7f, 0x0e7f,
-+	0x0068, 0x12c1, 0x7868, 0xa065, 0x0040, 0x12c1, 0xa02e, 0x1078,
-+	0x2774, 0x00e0, 0x1243, 0x1078, 0x5b00, 0x0078, 0x1243, 0x1078,
-+	0x1477, 0x78b0, 0xa005, 0x00c0, 0x12e3, 0x0068, 0x12d7, 0x7868,
-+	0xa065, 0x0040, 0x12d7, 0x2029, 0x0000, 0x1078, 0x2774, 0x1078,
-+	0x22e7, 0x0068, 0x12ed, 0x7868, 0xa065, 0x0040, 0x12e3, 0x2029,
-+	0x0000, 0x1078, 0x2774, 0x0068, 0x12ed, 0x2009, 0x6046, 0x2104,
-+	0xa005, 0x0040, 0x12ed, 0x1078, 0x1f9d, 0x0e7e, 0x0f7e, 0x2071,
-+	0x6040, 0x70c0, 0xa005, 0x0040, 0x1305, 0x7454, 0xa485, 0x0000,
-+	0x0040, 0x1305, 0x2079, 0x0100, 0x2091, 0x8000, 0x72f0, 0x1078,
-+	0x2e28, 0x2091, 0x8000, 0x2091, 0x303d, 0x0f7f, 0x0e7f, 0x0068,
-+	0x1311, 0x7868, 0xa065, 0x0040, 0x1311, 0x2029, 0x0000, 0x1078,
-+	0x2774, 0x00e0, 0x12c7, 0x1078, 0x5b00, 0x0078, 0x12c7, 0x1337,
-+	0x1337, 0x1339, 0x1339, 0x1346, 0x1346, 0x1346, 0x1346, 0x1351,
-+	0x1351, 0x135e, 0x135e, 0x1346, 0x1346, 0x1346, 0x1346, 0x1337,
-+	0x1337, 0x1339, 0x1339, 0x1346, 0x1346, 0x1346, 0x1346, 0x1351,
-+	0x1351, 0x135e, 0x135e, 0x1346, 0x1346, 0x1346, 0x1346, 0x0078,
-+	0x1337, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078, 0x2c19,
-+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
-+	0x127e, 0x1078, 0x13c3, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-+	0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x2c19,
-+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
-+	0x127e, 0x2091, 0x2300, 0x1078, 0x2c19, 0x2091, 0x2400, 0x1078,
-+	0x2c19, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x138f,
-+	0x138f, 0x1391, 0x1391, 0x139e, 0x139e, 0x139e, 0x139e, 0x13a9,
-+	0x13a9, 0x1391, 0x1391, 0x139e, 0x139e, 0x139e, 0x139e, 0x13aa,
-+	0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa,
-+	0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x13aa, 0x0078,
-+	0x138f, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x2c19,
-+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
-+	0x127e, 0x1078, 0x13d0, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-+	0x007c, 0x007c, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e,
-+	0x2071, 0x0100, 0x2069, 0x6040, 0x2079, 0x6000, 0x70ec, 0xa084,
-+	0x1c00, 0x78e6, 0x1078, 0x5d94, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f,
-+	0x127f, 0x107f, 0x007c, 0x3c00, 0xa084, 0x0007, 0x0079, 0x13c8,
-+	0x13d9, 0x13d9, 0x13db, 0x13db, 0x13e0, 0x13e0, 0x13e5, 0x13e5,
-+	0x3c00, 0xa084, 0x0003, 0x0079, 0x13d5, 0x13d9, 0x13d9, 0x13ee,
-+	0x13ee, 0x1078, 0x2bfa, 0x2091, 0x2200, 0x1078, 0x578c, 0x007c,
-+	0x2091, 0x2100, 0x1078, 0x578c, 0x007c, 0x2091, 0x2100, 0x1078,
-+	0x578c, 0x2091, 0x2200, 0x1078, 0x578c, 0x007c, 0x2091, 0x2100,
-+	0x1078, 0x578c, 0x007c, 0x1413, 0x1413, 0x1415, 0x1415, 0x1422,
-+	0x1422, 0x1422, 0x1422, 0x142d, 0x142d, 0x143a, 0x143a, 0x1422,
-+	0x1422, 0x1422, 0x1422, 0x144b, 0x144b, 0x144b, 0x144b, 0x144b,
-+	0x144b, 0x144b, 0x144b, 0x144b, 0x144b, 0x144b, 0x144b, 0x144b,
-+	0x144b, 0x144b, 0x144b, 0x0078, 0x1413, 0x007e, 0x107e, 0x127e,
-+	0x2091, 0x2400, 0x1078, 0x2c19, 0x127f, 0x107f, 0x007f, 0x2091,
-+	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c3, 0x127f,
-+	0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e,
-+	0x2091, 0x2300, 0x1078, 0x2c19, 0x127f, 0x107f, 0x007f, 0x2091,
-+	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
-+	0x2c19, 0x2091, 0x2400, 0x1078, 0x2c19, 0x127f, 0x107f, 0x007f,
-+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e,
-+	0x0f7e, 0x2079, 0x6000, 0x2071, 0x0200, 0x2069, 0x6040, 0x3d00,
-+	0xd08c, 0x0040, 0x1461, 0x70ec, 0xa084, 0x1c00, 0x78e6, 0x1078,
-+	0x5d94, 0x3d00, 0xd084, 0x0040, 0x146f, 0x2069, 0x6080, 0x2071,
-+	0x0100, 0x70ec, 0xa084, 0x1c00, 0x78ea, 0x1078, 0x5d94, 0x0f7f,
-+	0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007f, 0x007c, 0x007c, 0x0068,
-+	0x14fd, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x14fd,
-+	0x7820, 0xa005, 0x00c0, 0x1488, 0x0010, 0x14fe, 0x0078, 0x14fd,
-+	0x7908, 0xd1f4, 0x0040, 0x1490, 0x2001, 0x4007, 0x0078, 0x15b0,
-+	0x790c, 0xd1ec, 0x0040, 0x14ab, 0xd0fc, 0x0040, 0x14a1, 0x007e,
-+	0x1078, 0x1dd3, 0x007f, 0x0040, 0x14ab, 0x2001, 0x4007, 0x0078,
-+	0x15b0, 0x007e, 0x1078, 0x1dc7, 0x007f, 0x0040, 0x14ab, 0x2001,
-+	0x4007, 0x0078, 0x15b0, 0x7908, 0xd0fc, 0x00c0, 0x14b5, 0x2061,
-+	0x6040, 0xc19c, 0xc7fc, 0x0078, 0x14b9, 0x2061, 0x6080, 0xc19d,
-+	0xc7fd, 0x6068, 0xa005, 0x00c0, 0x14fd, 0x790a, 0x6087, 0x0000,
-+	0x7820, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14ca, 0x0c7e, 0x1078,
-+	0x1aed, 0x0c7f, 0x7823, 0x0000, 0x6080, 0xa065, 0x0040, 0x14e3,
-+	0x0c7e, 0x609c, 0x1078, 0x1edb, 0x0c7f, 0x609f, 0x0000, 0x1078,
-+	0x1c18, 0x2009, 0x000c, 0x6007, 0x0103, 0x1078, 0x1ddf, 0x00c0,
-+	0x14f7, 0x1078, 0x1e43, 0x7808, 0xd09c, 0x00c0, 0x14eb, 0x2061,
-+	0x6040, 0x0078, 0x14ee, 0x2061, 0x6080, 0xc09c, 0x6083, 0x0000,
-+	0x780a, 0x60f0, 0xd0dc, 0x0040, 0x14fb, 0xc0dc, 0x60f2, 0x2001,
-+	0x4005, 0x0078, 0x15b0, 0x0078, 0x15ae, 0x007c, 0x7808, 0xd0f4,
-+	0x0040, 0x1506, 0x2001, 0x4007, 0x0078, 0x15b0, 0x70c3, 0x0000,
-+	0x70c7, 0x0000, 0x70cb, 0x0000, 0x70cf, 0x0000, 0x70db, 0x0000,
-+	0x71c4, 0x7a08, 0xd2ec, 0x0040, 0x1516, 0xc1fc, 0x70c0, 0xa03d,
-+	0xa092, 0x0030, 0x00c8, 0x151e, 0x0079, 0x1525, 0x2200, 0xa092,
-+	0x0050, 0x00c8, 0x15bc, 0x0079, 0x1555, 0x15ae, 0x1604, 0x15cd,
-+	0x1619, 0x1628, 0x162e, 0x15c4, 0x1c30, 0x1632, 0x15bc, 0x15d1,
-+	0x15d3, 0x15d5, 0x15d7, 0x1c35, 0x15bc, 0x1640, 0x1698, 0x1b0f,
-+	0x1c2a, 0x15d9, 0x1949, 0x198b, 0x19c6, 0x1a13, 0x1902, 0x1910,
-+	0x1924, 0x1938, 0x175e, 0x15bc, 0x16c9, 0x16cd, 0x16d9, 0x16e5,
-+	0x16fb, 0x1707, 0x170a, 0x1716, 0x1722, 0x172a, 0x1746, 0x1752,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x176b, 0x177a, 0x1795, 0x17cb,
-+	0x17f3, 0x1803, 0x1806, 0x182f, 0x1860, 0x1872, 0x18d4, 0x18e4,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x18f4, 0x15bc, 0x15bc, 0x15bc,
-+	0x15bc, 0x15bc, 0x1d7e, 0x1d84, 0x15bc, 0x15bc, 0x15bc, 0x1d88,
-+	0x1d8d, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15fe, 0x1613, 0x163a,
-+	0x1692, 0x1b09, 0x1c4c, 0x1c72, 0x1ad0, 0x1c8a, 0x1d91, 0x1d70,
-+	0x1d7a, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc,
-+	0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x15bc, 0x72ca, 0x71c6, 0x2001,
-+	0x4006, 0x0078, 0x15b0, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000,
-+	0x70c2, 0x0068, 0x15b1, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091,
-+	0x5000, 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x15b1,
-+	0x70c3, 0x4006, 0x0078, 0x15b1, 0x2099, 0x0041, 0x20a1, 0x0041,
-+	0x20a9, 0x0005, 0x53a3, 0x0078, 0x15ae, 0x70c4, 0x70c3, 0x0004,
-+	0x007a, 0x0078, 0x15ae, 0x0078, 0x15ae, 0x0078, 0x15ae, 0x0078,
-+	0x15ae, 0x2091, 0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb,
-+	0x5020, 0x70cf, 0x2020, 0x70d3, 0x0009, 0x2001, 0x000b, 0x70d6,
-+	0x2079, 0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000,
-+	0x2029, 0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020,
-+	0x2091, 0x5000, 0x2091, 0x4080, 0x0078, 0x0418, 0x75d8, 0x74dc,
-+	0x75da, 0x74de, 0x0078, 0x1607, 0x2029, 0x0000, 0x2520, 0x71d0,
-+	0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1ff2, 0x0040, 0x15ae, 0x70c3,
-+	0x4002, 0x0078, 0x15ae, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078,
-+	0x161c, 0x2029, 0x0000, 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4,
-+	0x1078, 0x203c, 0x0040, 0x15ae, 0x70c3, 0x4002, 0x0078, 0x15ae,
-+	0x71c4, 0x70c8, 0x2114, 0x200a, 0x0078, 0x15ac, 0x71c4, 0x2114,
-+	0x0078, 0x15ac, 0x70c7, 0x0009, 0x70cb, 0x000b, 0x70cf, 0x0001,
-+	0x0078, 0x15ae, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1643,
-+	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6,
-+	0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x168c, 0xa40a, 0x0040,
-+	0x1653, 0x00c8, 0x15b0, 0x8001, 0x786e, 0xa084, 0xfc00, 0x0040,
-+	0x1660, 0x78b0, 0xc085, 0x78b2, 0x2001, 0x4005, 0x0078, 0x15b0,
-+	0x7a76, 0x7b7a, 0x7d7e, 0x7e82, 0x7c72, 0xa48c, 0xff00, 0x0040,
-+	0x1678, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118,
-+	0xa291, 0x0000, 0xa6b1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1682,
-+	0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000,
-+	0xa5a9, 0x0000, 0x731a, 0x721e, 0x7622, 0x7526, 0x78b0, 0xa084,
-+	0xfffc, 0x78b2, 0x0078, 0x1690, 0x78b0, 0xa085, 0x0001, 0x78b2,
-+	0x0078, 0x15ae, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x169b,
-+	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
-+	0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x16c3, 0xa40a, 0x0040,
-+	0x16ab, 0x00c8, 0x15b0, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040,
-+	0x16b8, 0x78b0, 0xc0c5, 0x78b2, 0x2001, 0x4005, 0x0078, 0x15b0,
-+	0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x7c96, 0x78b0, 0xa084, 0xfcff,
-+	0x78b2, 0x0078, 0x16c7, 0x78b0, 0xa085, 0x0100, 0x78b2, 0x0078,
-+	0x15ae, 0x7960, 0x7ac8, 0x0078, 0x15ac, 0x2009, 0x6047, 0x210c,
-+	0x7808, 0xd0ec, 0x00c0, 0x15ad, 0x2011, 0x6087, 0x2214, 0x0078,
-+	0x15ac, 0x2009, 0x6048, 0x210c, 0x7808, 0xd0ec, 0x00c0, 0x15ad,
-+	0x2011, 0x6088, 0x2214, 0x0078, 0x15ac, 0x2061, 0x6040, 0x6124,
-+	0x6228, 0x8214, 0x8214, 0x8214, 0x7808, 0xd0ec, 0x00c0, 0x16f9,
-+	0x2061, 0x6080, 0x6324, 0x73da, 0x6328, 0x831c, 0x831c, 0x831c,
-+	0x73de, 0x0078, 0x15ac, 0x2009, 0x604b, 0x210c, 0x7808, 0xd0ec,
-+	0x00c0, 0x15ad, 0x2011, 0x608b, 0x2214, 0x0078, 0x15ac, 0x7910,
-+	0x0078, 0x15ad, 0x2009, 0x0202, 0x210c, 0x7808, 0xd0ec, 0x00c0,
-+	0x15ad, 0x2011, 0x0102, 0x2214, 0x0078, 0x15ac, 0x2009, 0x604d,
-+	0x210c, 0x7808, 0xd0ec, 0x00c0, 0x15ad, 0x2011, 0x608d, 0x2214,
-+	0x0078, 0x15ac, 0x7918, 0x7808, 0xd0ec, 0x00c0, 0x15ad, 0x7a1c,
-+	0x0078, 0x15ac, 0xd1fc, 0x00c0, 0x1731, 0x2011, 0x64c0, 0x0078,
-+	0x1733, 0x2011, 0x6540, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0xa268, 0x6a00, 0x6804, 0xa084, 0x0008, 0x0040, 0x1743,
-+	0x6b08, 0x0078, 0x1744, 0x6b0c, 0x0078, 0x15ab, 0x2138, 0x1078,
-+	0x1e6e, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-+	0x0078, 0x15ab, 0x2061, 0x6040, 0x6114, 0x7808, 0xd0ec, 0x00c0,
-+	0x15ad, 0x2061, 0x6080, 0x6214, 0x0078, 0x15ac, 0x2138, 0x1078,
-+	0x1e6e, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091,
-+	0x8001, 0x0078, 0x15ab, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010,
-+	0x00c8, 0x15a6, 0x1078, 0x2a23, 0xd3f4, 0x0040, 0x1778, 0xc2ad,
-+	0x0078, 0x15ab, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8, 0x15a6,
-+	0xd1bc, 0x00c0, 0x1788, 0x2011, 0x6047, 0x2204, 0x0078, 0x178c,
-+	0x2011, 0x6087, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc, 0x2012,
-+	0x1078, 0x297e, 0x017f, 0x0078, 0x15ad, 0x71c4, 0x2021, 0x6048,
-+	0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x17a4, 0x71c8, 0x2021,
-+	0x6088, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x17c3, 0x20a9, 0x0008,
-+	0x2204, 0xa106, 0x0040, 0x17b3, 0x8210, 0x00f0, 0x17a8, 0x71c4,
-+	0x72c8, 0x0078, 0x15a5, 0xa292, 0x17c3, 0x027e, 0x2122, 0x017f,
-+	0x1078, 0x29a1, 0x7808, 0xd0ec, 0x00c0, 0x17c1, 0xd3fc, 0x0040,
-+	0x179e, 0x0078, 0x15ae, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004,
-+	0x0001, 0x0002, 0x0003, 0x2061, 0x6040, 0x6124, 0x6228, 0x8214,
-+	0x8214, 0x8214, 0x70c4, 0x6026, 0x70c8, 0x8003, 0x8003, 0x8003,
-+	0x602a, 0x7808, 0xd0ec, 0x00c0, 0x17f1, 0x027e, 0x017e, 0x2061,
-+	0x6080, 0x6124, 0x6228, 0x8214, 0x8214, 0x8214, 0x70d8, 0x6026,
-+	0x70dc, 0x8003, 0x8003, 0x8003, 0x602a, 0x71da, 0x72de, 0x017f,
-+	0x027f, 0x0078, 0x15ac, 0x2061, 0x6040, 0x612c, 0x70c4, 0x602e,
-+	0x7808, 0xd0ec, 0x00c0, 0x15ad, 0x2061, 0x6080, 0x622c, 0x70c8,
-+	0x602e, 0x0078, 0x15ac, 0x7910, 0x0078, 0x15ad, 0x71c4, 0xa184,
-+	0xffcf, 0x0040, 0x1812, 0x7808, 0xd0ec, 0x00c0, 0x15a6, 0x72c8,
-+	0x0078, 0x15a5, 0x007e, 0x2019, 0x0000, 0x1078, 0x2a08, 0x7808,
-+	0xd0ec, 0x0040, 0x181e, 0x017f, 0x0078, 0x15ad, 0x71c8, 0xa184,
-+	0xffcf, 0x0040, 0x1827, 0x2110, 0x71c4, 0x0078, 0x15a5, 0x007e,
-+	0xc3fd, 0x1078, 0x2a08, 0x027f, 0x017f, 0x0078, 0x15ac, 0x71c4,
-+	0xa182, 0x0010, 0x0048, 0x183b, 0x7808, 0xd0ec, 0x00c0, 0x15a6,
-+	0x72c8, 0x0078, 0x15a5, 0x2011, 0x604d, 0x2204, 0x007e, 0x2112,
-+	0x2019, 0x0000, 0x1078, 0x29e6, 0x7808, 0xd0ec, 0x0040, 0x184b,
-+	0x017f, 0x0078, 0x15ad, 0x71c8, 0xa182, 0x0010, 0x0048, 0x1854,
-+	0x2110, 0x71c4, 0x0078, 0x15a5, 0x2011, 0x608d, 0x2204, 0x007e,
-+	0x2112, 0xc3fd, 0x1078, 0x29e6, 0x027f, 0x017f, 0x0078, 0x15ac,
-+	0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15a5, 0xa284, 0xfffd,
-+	0x00c0, 0x15a5, 0x2100, 0x7918, 0x781a, 0x2200, 0x7a1c, 0x781e,
-+	0x0078, 0x15ac, 0x017e, 0xd1fc, 0x00c0, 0x187a, 0x2011, 0x64c0,
-+	0x0078, 0x187c, 0x2011, 0x6540, 0x8107, 0xa084, 0x000f, 0x8003,
-+	0x8003, 0x8003, 0xa268, 0xa01e, 0x72c8, 0x2091, 0x8000, 0x6800,
-+	0x007e, 0xa226, 0x0040, 0x18a8, 0x6a02, 0xa484, 0x2000, 0x0040,
-+	0x1893, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x1899, 0xa39d,
-+	0x0008, 0xa484, 0x4000, 0x0040, 0x18a8, 0x810f, 0xa284, 0x4000,
-+	0x0040, 0x18a6, 0x1078, 0x2a65, 0x0078, 0x18a8, 0x1078, 0x2a43,
-+	0x72cc, 0x6808, 0xa206, 0x0040, 0x18ca, 0xa2a4, 0x00ff, 0x780c,
-+	0xd0e4, 0x00c0, 0x18bb, 0xa482, 0x0028, 0x0048, 0x18c7, 0x0040,
-+	0x18c7, 0x0078, 0x18bf, 0xa482, 0x0043, 0x0048, 0x18c7, 0x027f,
-+	0x72ca, 0x017f, 0x71c6, 0x2091, 0x8001, 0x0078, 0x15a7, 0x6a0a,
-+	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x017f,
-+	0x2091, 0x8001, 0x0078, 0x15ab, 0x2138, 0x1078, 0x1e6e, 0x2091,
-+	0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc,
-+	0x681e, 0x2708, 0x0078, 0x15ab, 0x70c4, 0x2061, 0x6040, 0x6114,
-+	0x6016, 0x7808, 0xd0ec, 0x00c0, 0x15ad, 0x70c8, 0x2061, 0x6080,
-+	0x6214, 0x6016, 0x0078, 0x15ac, 0x72c8, 0x73cc, 0xa182, 0x0010,
-+	0x00c8, 0x15a6, 0x1078, 0x2a87, 0xd3f4, 0x0040, 0x1900, 0xc2ad,
-+	0x0078, 0x15ab, 0x2138, 0x1078, 0x1e6e, 0x2091, 0x8000, 0x6a08,
-+	0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x15ac,
-+	0x2138, 0x1078, 0x1e6e, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
-+	0x6a0a, 0x6804, 0xa005, 0x0040, 0x191f, 0x1078, 0x2852, 0x2091,
-+	0x8001, 0x2708, 0x0078, 0x15ac, 0x2138, 0x1078, 0x1e6e, 0x2091,
-+	0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040,
-+	0x1933, 0x1078, 0x2852, 0x2091, 0x8001, 0x2708, 0x0078, 0x15ac,
-+	0x2138, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
-+	0x8000, 0x1078, 0x1e83, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078,
-+	0x15ac, 0x2138, 0x780c, 0xd0e4, 0x00c0, 0x195d, 0xd7fc, 0x0040,
-+	0x1957, 0x1078, 0x1dd3, 0x0040, 0x195d, 0x0078, 0x15b0, 0x1078,
-+	0x1dc7, 0x0040, 0x195d, 0x0078, 0x15b0, 0x73c8, 0x72cc, 0x77c6,
-+	0x73ca, 0x72ce, 0x1078, 0x1f20, 0x00c0, 0x1987, 0x6818, 0xa005,
-+	0x0040, 0x1981, 0x2708, 0x077e, 0x1078, 0x2ab0, 0x077f, 0x00c0,
-+	0x1981, 0x2001, 0x0015, 0xd7fc, 0x00c0, 0x197a, 0x2061, 0x6040,
-+	0x0078, 0x197d, 0xc0fd, 0x2061, 0x6080, 0x7822, 0x2091, 0x8001,
-+	0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15b0, 0x2091,
-+	0x8001, 0x0078, 0x15ae, 0x2138, 0x780c, 0xd0e4, 0x00c0, 0x199f,
-+	0xd7fc, 0x0040, 0x1999, 0x1078, 0x1dd3, 0x0040, 0x199f, 0x0078,
-+	0x15b0, 0x1078, 0x1dc7, 0x0040, 0x199f, 0x0078, 0x15b0, 0x77c6,
-+	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
-+	0x1078, 0x1e83, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x19b3, 0x2061,
-+	0x6040, 0x0078, 0x19b6, 0x2061, 0x6080, 0xc1fd, 0x606b, 0x0003,
-+	0x6083, 0x0000, 0x677a, 0x6087, 0x000f, 0x7922, 0x61f0, 0xc1dc,
-+	0x61f2, 0x1078, 0x2852, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca,
-+	0x2138, 0x77c6, 0x780c, 0xd0e4, 0x00c0, 0x19dd, 0xd7fc, 0x0040,
-+	0x19d7, 0x1078, 0x1dd3, 0x0040, 0x19dd, 0x0078, 0x15b0, 0x1078,
-+	0x1dc7, 0x0040, 0x19dd, 0x0078, 0x15b0, 0xa7bc, 0xff00, 0x2091,
-+	0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x19ea, 0x2061, 0x6040,
-+	0x0078, 0x19ed, 0x2061, 0x6080, 0xc1fd, 0x6083, 0x0000, 0x606b,
-+	0x0002, 0x677a, 0x6087, 0x000f, 0x7922, 0x61f0, 0xc1dc, 0x61f2,
-+	0x1078, 0x2852, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010,
-+	0x70c8, 0xa005, 0x0040, 0x1a07, 0x60f0, 0xc0fd, 0x60f2, 0x1078,
-+	0x1e83, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a07,
-+	0x2091, 0x8001, 0x007c, 0x2019, 0x0000, 0x2011, 0x0000, 0x7808,
-+	0xd0ec, 0x00c0, 0x1a2f, 0x72c8, 0x780c, 0xd0e4, 0x00c0, 0x1a2f,
-+	0xd284, 0x0040, 0x1a29, 0x1078, 0x1dd3, 0x0040, 0x1a2f, 0x0078,
-+	0x15b0, 0x1078, 0x1dc7, 0x0040, 0x1a2f, 0x0078, 0x15b0, 0x72ca,
-+	0x78b0, 0xa084, 0x0003, 0x00c0, 0x1a59, 0x2039, 0x0000, 0xd284,
-+	0x0040, 0x1a3b, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-+	0x0008, 0x1078, 0x1e6e, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d,
-+	0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a41,
-+	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0,
-+	0x1a41, 0x2091, 0x8000, 0x7808, 0xd0ec, 0x0040, 0x1a63, 0x2069,
-+	0x0100, 0x0078, 0x1a6d, 0x72c8, 0xd284, 0x00c0, 0x1a6b, 0x2069,
-+	0x0200, 0x0078, 0x1a6d, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd,
-+	0x680a, 0x6830, 0xa084, 0x0040, 0x0040, 0x1a90, 0x684b, 0x0004,
-+	0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x1a81, 0x00f0,
-+	0x1a7a, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
-+	0x0040, 0x1a8c, 0x00f0, 0x1a85, 0x20a9, 0x00fa, 0x00f0, 0x1a8e,
-+	0x2079, 0x6000, 0x2009, 0x0018, 0x7808, 0xd0ec, 0x00c0, 0x1a9c,
-+	0x72c8, 0xd284, 0x00c0, 0x1aa0, 0x2061, 0x6040, 0x0078, 0x1aa3,
-+	0x2061, 0x6080, 0xc1fd, 0x6083, 0x0000, 0x7922, 0x606b, 0x0001,
-+	0x6087, 0x000f, 0x60c3, 0x0000, 0x60c4, 0x60ce, 0x60d2, 0x60f0,
-+	0xd0b4, 0x0040, 0x1abf, 0xc0b4, 0x60f2, 0x0c7e, 0x60d4, 0xa065,
-+	0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x60f0,
-+	0xa084, 0x77ff, 0x60f2, 0x78b0, 0xa085, 0x0002, 0x78b2, 0x83ff,
-+	0x0040, 0x1acb, 0x007c, 0x681b, 0x0048, 0x2091, 0x8001, 0x007c,
-+	0x73cc, 0x1078, 0x1a15, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a,
-+	0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff,
-+	0x00f0, 0x1ae0, 0x8421, 0x00c0, 0x1ade, 0x8319, 0x00c0, 0x1adc,
-+	0x69ee, 0x6a4a, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1af4,
-+	0x2069, 0x6040, 0x0078, 0x1af6, 0x2069, 0x6080, 0x71c4, 0x71c6,
-+	0x6912, 0x81ff, 0x00c0, 0x1afe, 0x68c3, 0x0001, 0x78b0, 0xa084,
-+	0xfffd, 0x78b2, 0xa084, 0x0001, 0x00c0, 0x1b08, 0x1078, 0x1f79,
-+	0x007c, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1b12, 0x2029,
-+	0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce,
-+	0x2079, 0x6000, 0x7de2, 0x7cde, 0x7bda, 0x7ad6, 0x1078, 0x1e25,
-+	0x0040, 0x1c14, 0x20a9, 0x0005, 0x20a1, 0x6012, 0x2091, 0x8000,
-+	0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x1078, 0x21f4, 0x0040,
-+	0x1b35, 0x1078, 0x1e43, 0x0078, 0x1c14, 0x6004, 0xa08c, 0x00ff,
-+	0xa18e, 0x0009, 0x00c0, 0x1b40, 0x007e, 0x1078, 0x2750, 0x007f,
-+	0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x1bb3, 0x0c7e, 0x2c68,
-+	0x1078, 0x1e25, 0x0040, 0x1b86, 0x2c00, 0x689e, 0x8109, 0x00c0,
-+	0x1b47, 0x609f, 0x0000, 0x0c7f, 0x0c7e, 0x7de0, 0x7cdc, 0x7bd8,
-+	0x7ad4, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-+	0x0000, 0x7de2, 0x7cde, 0x7bda, 0x7ad6, 0x2c68, 0x689c, 0xa065,
-+	0x0040, 0x1bb2, 0x2009, 0x0040, 0x1078, 0x21f4, 0x00c0, 0x1b9c,
-+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x1b86, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x000a, 0x00c0, 0x1b82, 0x017e, 0x1078,
-+	0x274c, 0x017f, 0x2d00, 0x6002, 0x0078, 0x1b55, 0x0c7f, 0x0c7e,
-+	0x609c, 0x1078, 0x1edb, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c18,
-+	0x2009, 0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1ddf,
-+	0x1078, 0x1e43, 0x0078, 0x1c14, 0x0c7f, 0x0c7e, 0x609c, 0x1078,
-+	0x1edb, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c18, 0x2009, 0x000c,
-+	0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1ddf, 0x1078, 0x1e43,
-+	0x0078, 0x1c14, 0x0c7f, 0x780c, 0xd0e4, 0x00c0, 0x1bd8, 0x6114,
-+	0xd1fc, 0x0040, 0x1bc1, 0x1078, 0x1dd3, 0x0040, 0x1bd8, 0x0078,
-+	0x1bc5, 0x1078, 0x1dc7, 0x0040, 0x1bd8, 0x2029, 0x0000, 0x2520,
-+	0x2009, 0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021,
-+	0x1078, 0x1ddf, 0x1078, 0x1e43, 0x2001, 0x4007, 0x0078, 0x15b0,
-+	0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009,
-+	0x0012, 0xd0fc, 0x00c0, 0x1be8, 0x2071, 0x6040, 0x0078, 0x1beb,
-+	0x2071, 0x6080, 0xc1fd, 0x7922, 0x706b, 0x0005, 0x71f0, 0xc1dc,
-+	0x71f2, 0x736e, 0x7272, 0x7476, 0x707a, 0x707f, 0x0000, 0x2c00,
-+	0x7082, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0x0060, 0x0040,
-+	0x1c03, 0x1078, 0x564a, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa,
-+	0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x1078,
-+	0x2852, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x15b1,
-+	0x20a9, 0x0005, 0x2099, 0x6012, 0x2091, 0x8000, 0x530a, 0x2091,
-+	0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-+	0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7916, 0x0078, 0x15ae,
-+	0x71c4, 0x71c6, 0x2168, 0x0078, 0x1c37, 0x2069, 0x1000, 0x690c,
-+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1c39, 0xa285,
-+	0x0000, 0x00c0, 0x1c47, 0x70c3, 0x4000, 0x0078, 0x1c49, 0x70c3,
-+	0x4003, 0x70ca, 0x0078, 0x15b1, 0x2011, 0x6064, 0xa03e, 0x7908,
-+	0xd1ec, 0x00c0, 0x1c6a, 0x77c8, 0xd7fc, 0x0040, 0x1c59, 0x2011,
-+	0x60a4, 0x220c, 0x007e, 0x037e, 0x047e, 0x1078, 0x482c, 0x70c4,
-+	0xd0fc, 0x047f, 0x037f, 0x007f, 0x00c0, 0x1c6a, 0xa184, 0x7fff,
-+	0x0078, 0x1c6e, 0x1078, 0x480c, 0xa185, 0x8000, 0x2012, 0x2710,
-+	0x0078, 0x15ac, 0x017e, 0x2100, 0xc1fc, 0x1078, 0x47fa, 0x017f,
-+	0xd1fc, 0x00c0, 0x1c7f, 0x2001, 0x6064, 0x0078, 0x1c81, 0x2001,
-+	0x60a4, 0x2004, 0xa084, 0x8000, 0x6100, 0xa10d, 0x6204, 0x6308,
-+	0x0078, 0x15ab, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000,
-+	0x2061, 0x0010, 0x60c4, 0xd0fc, 0x00c0, 0x1ca8, 0x2071, 0x6040,
-+	0x7808, 0xd0ec, 0x0040, 0x1ca2, 0x2079, 0x0100, 0x2019, 0x0020,
-+	0x0078, 0x1cae, 0x2079, 0x0200, 0x2019, 0x0050, 0x0078, 0x1cae,
-+	0x2071, 0x6080, 0x2079, 0x0100, 0x2019, 0x0020, 0x7094, 0xa06d,
-+	0x0040, 0x1d66, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040,
-+	0x1cbd, 0xa286, 0x000f, 0x00c0, 0x1d66, 0x691c, 0xa184, 0x00c0,
-+	0x0040, 0x1d66, 0xa186, 0x00c0, 0x0040, 0x1d66, 0x6824, 0xa084,
-+	0xff00, 0xa085, 0x0019, 0x6826, 0x2368, 0x7830, 0xa084, 0x0040,
-+	0x00c0, 0x1ccd, 0xa184, 0x0080, 0x00c0, 0x1d36, 0x78e4, 0xa084,
-+	0x0007, 0x8001, 0x00c0, 0x1cd6, 0x71a4, 0x81ff, 0x0040, 0x1cec,
-+	0x6807, 0x0010, 0x6908, 0x6808, 0xa106, 0x00c0, 0x1ce2, 0x6804,
-+	0xa084, 0x0010, 0x00c0, 0x1ce7, 0x78b8, 0xa084, 0x801f, 0x00c0,
-+	0x1cec, 0x7848, 0xa085, 0x000c, 0x784a, 0x71a4, 0x81ff, 0x0040,
-+	0x1d0b, 0x70a7, 0x0000, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008,
-+	0x00c0, 0x1cfd, 0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0,
-+	0x1d04, 0x6807, 0x0002, 0x61c4, 0xa18c, 0x0003, 0x0040, 0x1d61,
-+	0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x7848, 0xa084, 0x000c,
-+	0x00c0, 0x1d15, 0x0e7e, 0x2071, 0x6000, 0x724e, 0x7352, 0xae80,
-+	0x0013, 0x0e7f, 0x1078, 0x54f9, 0x78a3, 0x0000, 0x7858, 0xa084,
-+	0xedff, 0x785a, 0x70a8, 0xa080, 0x00d9, 0x781a, 0x0f7f, 0x0e7f,
-+	0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x0078, 0x15ae, 0x78e4, 0xa084,
-+	0x0007, 0x00c0, 0x1d36, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x1d3b,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x7848, 0xa084, 0x000c, 0x00c0,
-+	0x1d44, 0x71a4, 0x81ff, 0x0040, 0x1d61, 0x6807, 0x0010, 0x70a7,
-+	0x0000, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1d53,
-+	0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1d5a, 0x6807,
-+	0x0002, 0x70a8, 0xa080, 0x00a7, 0x0078, 0x1d2d, 0x0f7f, 0x0e7f,
-+	0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15b0,
-+	0x795c, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15a6, 0x795e,
-+	0x0078, 0x15ae, 0x795c, 0x71c6, 0x0078, 0x15ae, 0x7900, 0x71c6,
-+	0x71c4, 0x7902, 0x0078, 0x15ae, 0x7900, 0x71c6, 0x0078, 0x15ae,
-+	0x7904, 0x70c4, 0x7806, 0x0078, 0x15ad, 0x7804, 0x70c6, 0x0078,
-+	0x15ae, 0xd1fc, 0x00c0, 0x1d98, 0x2011, 0x64c0, 0x0078, 0x1d9a,
-+	0x2011, 0x6540, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1da9, 0x2011, 0x0001, 0x0078,
-+	0x1dab, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da, 0x0078, 0x15ab,
-+	0x780c, 0xd0f4, 0x0040, 0x1dbb, 0x2001, 0x4007, 0x70db, 0x0000,
-+	0xa005, 0x0078, 0x1dc6, 0xd0fc, 0x0040, 0x1dc5, 0x2001, 0x4007,
-+	0x70db, 0x0001, 0xa005, 0x0078, 0x1dc6, 0xa006, 0x007c, 0x780c,
-+	0xd0f4, 0x0040, 0x1dd1, 0x2001, 0x4007, 0x70db, 0x0000, 0x0078,
-+	0x1dd2, 0xa006, 0x007c, 0x780c, 0xd0fc, 0x0040, 0x1ddd, 0x2001,
-+	0x4007, 0x70db, 0x0001, 0x0078, 0x1dde, 0xa006, 0x007c, 0xac80,
-+	0x0001, 0x1078, 0x205e, 0x007c, 0x7112, 0x7003, 0x0001, 0x7007,
-+	0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0,
-+	0x7008, 0xd0fc, 0x0040, 0x1df0, 0x7007, 0x0002, 0xa08c, 0x01e0,
-+	0x00c0, 0x1e20, 0x53a5, 0x7888, 0xa005, 0x0040, 0x1e1f, 0x1078,
-+	0x1e25, 0x0040, 0x1e0d, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80,
-+	0x0001, 0x20a0, 0x53a5, 0x0078, 0x1e1f, 0x788b, 0x0000, 0x7218,
-+	0x731c, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3,
-+	0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0x7422, 0x7526, 0xa006,
-+	0x7003, 0x0000, 0x7007, 0x0004, 0x007c, 0x2091, 0x8000, 0x7840,
-+	0xa065, 0x0040, 0x1e2f, 0x2c04, 0x7842, 0x2063, 0x0000, 0x2091,
-+	0x8001, 0x007c, 0x0f7e, 0x2079, 0x6000, 0x7840, 0xa06d, 0x0040,
-+	0x1e41, 0x2d04, 0x7842, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b,
-+	0x0000, 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x6000,
-+	0x7840, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1e50, 0x1078, 0x2bfa,
-+	0x7842, 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x6000,
-+	0x7840, 0x206a, 0x2d00, 0x7842, 0x0f7f, 0x007c, 0x2011, 0xac00,
-+	0x7a42, 0x7bc8, 0x8319, 0x0040, 0x1e6b, 0xa280, 0x0037, 0x2012,
-+	0x2010, 0x0078, 0x1e62, 0x2013, 0x0000, 0x007c, 0x017e, 0x2069,
-+	0x85c0, 0xd7fc, 0x00c0, 0x1e76, 0x2069, 0x65c0, 0xa784, 0x0f00,
-+	0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
-+	0xad68, 0x017f, 0x007c, 0x1078, 0x1e6e, 0x2900, 0x682a, 0x2a00,
-+	0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x0e7e, 0xd7fc,
-+	0x00c0, 0x1e98, 0x2009, 0x6054, 0x2071, 0x6040, 0x0078, 0x1e9c,
-+	0x2009, 0x6094, 0x2071, 0x6080, 0x210c, 0x6804, 0xa005, 0x0040,
-+	0x1eac, 0xa116, 0x00c0, 0x1eac, 0x2060, 0x6000, 0x6806, 0x017e,
-+	0x200b, 0x0000, 0x0078, 0x1eaf, 0x2009, 0x0000, 0x017e, 0x6804,
-+	0xa065, 0x0040, 0x1ebe, 0x6000, 0x6806, 0x1078, 0x1ef5, 0x1078,
-+	0x2240, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1eaf, 0x017f, 0x6902,
-+	0x6906, 0x2d00, 0x2060, 0x1078, 0x2d8b, 0x0e7f, 0x007c, 0xa065,
-+	0x0040, 0x1eda, 0x2008, 0x609c, 0xa005, 0x0040, 0x1ed5, 0x2062,
-+	0x609f, 0x0000, 0xa065, 0x0078, 0x1ecb, 0x2079, 0x6000, 0x7840,
-+	0x7942, 0x2062, 0x007c, 0xa065, 0x0040, 0x1ef4, 0x2008, 0x609c,
-+	0xa005, 0x0040, 0x1ee9, 0x2062, 0x609f, 0x0000, 0xa065, 0x0078,
-+	0x1edf, 0x0f7e, 0x2079, 0x6000, 0x2091, 0x8000, 0x7840, 0x7942,
-+	0x0f7f, 0x2062, 0x2091, 0x8001, 0x007c, 0x6007, 0x0103, 0x608f,
-+	0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000,
-+	0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc,
-+	0x00c0, 0x1f10, 0x2071, 0x6040, 0x2031, 0x60c0, 0x0078, 0x1f14,
-+	0x2071, 0x6080, 0x2031, 0x62c0, 0x7054, 0xa08c, 0x0200, 0x00c0,
-+	0x1f1e, 0xa608, 0x2d0a, 0x8000, 0x7056, 0xa006, 0x0e7f, 0x007c,
-+	0x0f7e, 0xd7fc, 0x00c0, 0x1f28, 0x2079, 0x6040, 0x0078, 0x1f2a,
-+	0x2079, 0x6080, 0x1078, 0x1e6e, 0x2091, 0x8000, 0x6804, 0x7806,
-+	0xa065, 0x0040, 0x1f77, 0x0078, 0x1f3b, 0x2c00, 0x7806, 0x6000,
-+	0xa065, 0x0040, 0x1f77, 0x6010, 0xa306, 0x00c0, 0x1f35, 0x600c,
-+	0xa206, 0x00c0, 0x1f35, 0x2c28, 0x7850, 0xac06, 0x00c0, 0x1f4a,
-+	0x0078, 0x1f74, 0x6804, 0xac06, 0x00c0, 0x1f58, 0x6000, 0x2060,
-+	0x6806, 0xa005, 0x00c0, 0x1f58, 0x6803, 0x0000, 0x0078, 0x1f62,
-+	0x6400, 0x7804, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1f62,
-+	0x2c00, 0x6802, 0x2560, 0x0f7f, 0x1078, 0x1ef5, 0x0f7e, 0x601b,
-+	0x0005, 0x6023, 0x0020, 0x0f7f, 0x1078, 0x2240, 0x0f7e, 0x6810,
-+	0x8001, 0x1050, 0x2bfa, 0x6812, 0xa085, 0xffff, 0xa005, 0x0f7f,
-+	0x007c, 0x077e, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0040, 0x1f81,
-+	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091,
-+	0x8000, 0x1078, 0x1e83, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f89,
-+	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0,
-+	0x1f89, 0x2091, 0x8001, 0x077f, 0x007c, 0x2061, 0x0000, 0x6018,
-+	0xa084, 0x0001, 0x00c0, 0x1fbe, 0x7808, 0xd08c, 0x0040, 0x1faf,
-+	0xc08c, 0x780a, 0xc7fc, 0x2069, 0x6040, 0x0078, 0x1fb4, 0xc08d,
-+	0x780a, 0x2069, 0x6080, 0xc7fd, 0x2091, 0x8000, 0x6818, 0x681b,
-+	0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1fbf, 0x007c, 0xa08c,
-+	0xfff0, 0x0040, 0x1fc5, 0x1078, 0x2bfa, 0x0079, 0x1fc7, 0x1fd7,
-+	0x1fda, 0x1fe0, 0x1fe4, 0x1fd8, 0x1fe8, 0x1fee, 0x1fd8, 0x1fd8,
-+	0x2193, 0x21c4, 0x21c8, 0x21ce, 0x1fd8, 0x1fd8, 0x1fd8, 0x007c,
-+	0x1078, 0x2bfa, 0x1078, 0x1f79, 0x2001, 0x8001, 0x0078, 0x21e3,
-+	0x2001, 0x8003, 0x0078, 0x21e3, 0x2001, 0x8004, 0x0078, 0x21e3,
-+	0x1078, 0x1f79, 0x2001, 0x8006, 0x0078, 0x21e3, 0x2001, 0x8007,
-+	0x0078, 0x21e3, 0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1ffa,
-+	0x2009, 0x0020, 0x2600, 0x1078, 0x2014, 0x00c0, 0x2013, 0xa7ba,
-+	0x0020, 0x0048, 0x2012, 0x0040, 0x2012, 0x2708, 0xa6b0, 0x0020,
-+	0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-+	0x0078, 0x1ff4, 0xa006, 0x007c, 0x81ff, 0x0040, 0x2039, 0x2099,
-+	0x0030, 0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040, 0x2026, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x2021, 0x21a8, 0x810b,
-+	0x7112, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x00c8,
-+	0x202d, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x2039, 0x53a5,
-+	0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138, 0xa782, 0x0021,
-+	0x0048, 0x2044, 0x2009, 0x0020, 0x2600, 0x1078, 0x205e, 0x00c0,
-+	0x205d, 0xa7ba, 0x0020, 0x0048, 0x205c, 0x0040, 0x205c, 0x2708,
-+	0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
-+	0xa5a9, 0x0000, 0x0078, 0x203e, 0xa006, 0x007c, 0x81ff, 0x0040,
-+	0x2096, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084, 0x03ff, 0x0040,
-+	0x2069, 0x21a8, 0x810b, 0x7112, 0x7018, 0x007e, 0x701c, 0x007e,
-+	0x7020, 0x007e, 0x7024, 0x007e, 0x721a, 0x731e, 0x7422, 0x7526,
-+	0x7003, 0x0000, 0x53a6, 0x7007, 0x0001, 0x7010, 0xa084, 0xf000,
-+	0x0040, 0x2086, 0x7007, 0x0008, 0x0078, 0x208a, 0x7108, 0x8103,
-+	0x00c8, 0x207d, 0x007f, 0x7026, 0x007f, 0x7022, 0x007f, 0x701e,
-+	0x007f, 0x701a, 0x7007, 0x0002, 0xa184, 0x01e0, 0x7003, 0x0000,
-+	0x7007, 0x0004, 0x007c, 0x0e7e, 0x6914, 0xd1fc, 0x0040, 0x20a4,
-+	0x2071, 0x6080, 0x0078, 0x20a6, 0x2071, 0x6040, 0x2d08, 0x70b4,
-+	0x6802, 0xa005, 0x00c0, 0x20ad, 0x71ba, 0x71b6, 0x0e7f, 0x007c,
-+	0x0f7e, 0x6114, 0xd1fc, 0x0040, 0x20b9, 0x2079, 0x6080, 0x0078,
-+	0x20bb, 0x2079, 0x6040, 0x2c08, 0x78b4, 0x6002, 0xa005, 0x00c0,
-+	0x20c2, 0x79ba, 0x79b6, 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e,
-+	0x6114, 0xd1fc, 0x0040, 0x20d0, 0x2079, 0x6080, 0x0078, 0x20d2,
-+	0x2079, 0x6040, 0x6003, 0x0000, 0x2c08, 0x78b8, 0xa065, 0x00c0,
-+	0x20dc, 0x79b6, 0x0078, 0x20dd, 0x6102, 0x79ba, 0x0f7f, 0x2091,
-+	0x8001, 0x1078, 0x2885, 0x007c, 0x70b4, 0xa06d, 0x0040, 0x20ef,
-+	0x6800, 0x70b6, 0xa005, 0x00c0, 0x20ee, 0x70ba, 0x8dff, 0x007c,
-+	0x0d7e, 0x0c7e, 0x0f7e, 0xd3fc, 0x0040, 0x20fa, 0x2079, 0x6080,
-+	0x0078, 0x20fc, 0x2079, 0x6040, 0xaf80, 0x002d, 0x2060, 0x6000,
-+	0xa005, 0x0040, 0x2125, 0x2068, 0x6814, 0xa306, 0x00c0, 0x210e,
-+	0x6828, 0xa084, 0x00ff, 0xa406, 0x0040, 0x2111, 0x2d60, 0x0078,
-+	0x20ff, 0x6800, 0xa005, 0x6002, 0x00c0, 0x211d, 0xaf80, 0x002d,
-+	0xac06, 0x0040, 0x211c, 0x2c00, 0x78ba, 0x0d7e, 0x689c, 0xa005,
-+	0x0040, 0x2124, 0x1078, 0x1ec7, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f,
-+	0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0xd0fc, 0x0040, 0x2134,
-+	0x2079, 0x6080, 0x0078, 0x2136, 0x2079, 0x6040, 0xaf80, 0x002d,
-+	0x2060, 0x6000, 0xa005, 0x0040, 0x215b, 0x2068, 0x6814, 0xa084,
-+	0x00ff, 0xa306, 0x0040, 0x2147, 0x2d60, 0x0078, 0x2139, 0x6800,
-+	0xa005, 0x6002, 0x00c0, 0x2153, 0xaf80, 0x002d, 0xac06, 0x0040,
-+	0x2152, 0x2c00, 0x78ba, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x215a,
-+	0x1078, 0x1ec7, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
-+	0x0d7e, 0x0c7e, 0x0f7e, 0xd3fc, 0x0040, 0x216a, 0x2079, 0x6080,
-+	0x0078, 0x216c, 0x2079, 0x6040, 0xaf80, 0x002d, 0x2060, 0x6000,
-+	0xa06d, 0x0040, 0x218e, 0x6814, 0xa306, 0x0040, 0x217a, 0x2d60,
-+	0x0078, 0x216f, 0x6800, 0xa005, 0x6002, 0x00c0, 0x2186, 0xaf80,
-+	0x002d, 0xac06, 0x0040, 0x2185, 0x2c00, 0x78ba, 0x0d7e, 0x689c,
-+	0xa005, 0x0040, 0x218d, 0x1078, 0x1ec7, 0x007f, 0x0f7f, 0x0c7f,
-+	0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0xd7fc, 0x00c0, 0x219c,
-+	0x2069, 0x6040, 0x0078, 0x219e, 0x2069, 0x6080, 0x6800, 0xa086,
-+	0x0000, 0x0040, 0x21a8, 0x2091, 0x8001, 0x681b, 0x0009, 0x007c,
-+	0x6878, 0xd7fc, 0x00c0, 0x21ae, 0x0078, 0x21af, 0xc0fd, 0xa0bc,
-+	0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078,
-+	0x1e83, 0x8738, 0xa784, 0x001f, 0x00c0, 0x21b7, 0x2091, 0x8001,
-+	0x2001, 0x800a, 0x0078, 0x21e3, 0x2001, 0x800c, 0x0078, 0x21e3,
-+	0x1078, 0x1f79, 0x2001, 0x800d, 0x0078, 0x21e3, 0x780c, 0xd0e4,
-+	0x00c0, 0x21e1, 0xd0ec, 0x0040, 0x21db, 0xd7fc, 0x0040, 0x21db,
-+	0x78e8, 0x0078, 0x21dc, 0x78e4, 0x70c6, 0x2001, 0x800e, 0x0078,
-+	0x21e3, 0x0078, 0x1fd8, 0x70c2, 0xd7fc, 0x00c0, 0x21eb, 0x70db,
-+	0x0000, 0x0078, 0x21ed, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b,
-+	0x0001, 0x2091, 0x4080, 0x007c, 0xac80, 0x0001, 0x81ff, 0x0040,
-+	0x221f, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040,
-+	0x2201, 0x7018, 0x007e, 0x701c, 0x007e, 0x7020, 0x007e, 0x7024,
-+	0x007e, 0x7112, 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003,
-+	0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x00c8, 0x2213, 0x7007,
-+	0x0002, 0xa08c, 0x01e0, 0x00c0, 0x221f, 0x53a5, 0xa006, 0x7003,
-+	0x0000, 0x7007, 0x0004, 0x007f, 0x7026, 0x007f, 0x7022, 0x007f,
-+	0x701e, 0x007f, 0x701a, 0x007c, 0x2011, 0x0020, 0x2009, 0x0010,
-+	0x6b0a, 0x6c0e, 0x6803, 0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00,
-+	0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, 0x00c0, 0x2230, 0x007c,
-+	0x6004, 0x2c08, 0x2063, 0x0000, 0x7860, 0x8000, 0x7862, 0x7864,
-+	0xa005, 0x7966, 0x0040, 0x224f, 0x2c02, 0x0078, 0x2250, 0x796a,
-+	0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061, 0x6000, 0x2d08, 0x206b,
-+	0x0000, 0x6060, 0x8000, 0x6062, 0x6064, 0xa005, 0x6166, 0x0040,
-+	0x2264, 0x2d02, 0x0078, 0x2265, 0x616a, 0x0c7f, 0x007c, 0x2091,
-+	0x8000, 0x7860, 0x8001, 0x7862, 0x2c04, 0x786a, 0xa005, 0x00c0,
-+	0x2272, 0x7866, 0x2091, 0x8001, 0x609c, 0xa005, 0x0040, 0x228f,
-+	0x0c7e, 0x2060, 0x2008, 0x609c, 0xa005, 0x0040, 0x2287, 0x2062,
-+	0x609f, 0x0000, 0xa065, 0x609c, 0xa005, 0x00c0, 0x227f, 0x2091,
-+	0x8000, 0x7840, 0x7942, 0x2062, 0x2091, 0x8001, 0x0c7f, 0x2091,
-+	0x8000, 0x7840, 0x2062, 0x609f, 0x0000, 0x2c00, 0xa005, 0x00c0,
-+	0x229b, 0x1078, 0x2bfa, 0x7842, 0x2091, 0x8001, 0x007c, 0x7868,
-+	0xa065, 0x0040, 0x22b1, 0x2091, 0x8000, 0x7860, 0x8001, 0x7862,
-+	0x2c04, 0x786a, 0xa005, 0x00c0, 0x22af, 0x7866, 0x8000, 0x2091,
-+	0x8001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
-+	0x00c8, 0x22bb, 0xa200, 0x00f0, 0x22b6, 0x8086, 0x818e, 0x007c,
-+	0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x22e1, 0xa11a, 0x00c8,
-+	0x22e1, 0x8213, 0x818d, 0x0048, 0x22d4, 0xa11a, 0x00c8, 0x22d5,
-+	0x00f0, 0x22c9, 0x0078, 0x22d9, 0xa11a, 0x2308, 0x8210, 0x00f0,
-+	0x22c9, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
-+	0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x22dd, 0x7d70,
-+	0x70d0, 0xa506, 0x0040, 0x237c, 0x7808, 0xd0ec, 0x0040, 0x2304,
-+	0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0,
-+	0x2301, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x2304, 0x0078,
-+	0x237c, 0x0e7f, 0x0078, 0x237c, 0x1078, 0x1e25, 0x0040, 0x237c,
-+	0x796c, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x2313,
-+	0xa006, 0x0078, 0x231b, 0x72d0, 0xa206, 0x0040, 0x231b, 0x788b,
-+	0x0001, 0x2009, 0x0080, 0x0c7e, 0x1078, 0x1de4, 0x0c7f, 0x0040,
-+	0x2364, 0x1078, 0x1e43, 0x788b, 0x0000, 0x7884, 0x8000, 0x7886,
-+	0xa086, 0x0002, 0x0040, 0x2342, 0x8507, 0x8004, 0x8004, 0x7978,
-+	0xa108, 0x711a, 0x00c8, 0x2340, 0x7974, 0xa189, 0x0000, 0x711e,
-+	0x7980, 0xa189, 0x0000, 0x7122, 0x797c, 0xa189, 0x0000, 0x7126,
-+	0x0078, 0x237c, 0x6014, 0xd0fc, 0x00c0, 0x234a, 0x2069, 0x6040,
-+	0x0078, 0x234c, 0x2069, 0x6080, 0x2091, 0x8000, 0x681b, 0x0002,
-+	0x7888, 0xa005, 0x0040, 0x235a, 0x788b, 0x0000, 0x788c, 0x2060,
-+	0x0078, 0x2342, 0x7887, 0x0000, 0x78b0, 0xa085, 0x0003, 0x78b2,
-+	0x2091, 0x8001, 0x0078, 0x237c, 0x7887, 0x0000, 0x1078, 0x2721,
-+	0x6004, 0xa084, 0x000f, 0x1078, 0x237d, 0x7888, 0xa005, 0x0040,
-+	0x2378, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, 0x1078, 0x237d,
-+	0x788b, 0x0000, 0x0078, 0x22e7, 0x007c, 0x0079, 0x237f, 0x238f,
-+	0x23ad, 0x23cd, 0x238f, 0x23ea, 0x239e, 0x2564, 0x257b, 0x238f,
-+	0x23ab, 0x23cb, 0x2434, 0x24aa, 0x2502, 0x2514, 0x257b, 0x2039,
-+	0x0400, 0x78c0, 0xa705, 0x78c2, 0x6008, 0xa705, 0x600a, 0x1078,
-+	0x25ff, 0x609c, 0x78be, 0x1078, 0x2709, 0x007c, 0x78c0, 0xa084,
-+	0x0100, 0x0040, 0x23a5, 0x0078, 0x238f, 0x601c, 0xa085, 0x0080,
-+	0x601e, 0x0078, 0x23b4, 0x1078, 0x2750, 0x78c0, 0xa084, 0x0100,
-+	0x0040, 0x23b4, 0x0078, 0x238f, 0x78c3, 0x0000, 0x6004, 0x8007,
-+	0xa084, 0x00ff, 0x78b6, 0x8001, 0x0040, 0x23c8, 0x1078, 0x25ff,
-+	0x0040, 0x23c8, 0x78c0, 0xa085, 0x0100, 0x78c2, 0x0078, 0x23ca,
-+	0x0078, 0x261f, 0x007c, 0x1078, 0x274c, 0x78c0, 0xa08c, 0x0e00,
-+	0x00c0, 0x23d6, 0xa084, 0x0100, 0x00c0, 0x23d8, 0x0078, 0x238f,
-+	0x1078, 0x25ff, 0x00c0, 0x23e9, 0x6104, 0xa18c, 0x00ff, 0xa186,
-+	0x0007, 0x0040, 0x25c0, 0xa186, 0x000f, 0x0040, 0x25c0, 0x0078,
-+	0x261f, 0x007c, 0x78c0, 0xa084, 0x0100, 0x0040, 0x23f1, 0x0078,
-+	0x238f, 0x78c3, 0x0000, 0x6714, 0x1078, 0x1e6e, 0x2011, 0x0001,
-+	0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x2416,
-+	0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001,
-+	0x0040, 0x2416, 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100,
-+	0xa08e, 0x0002, 0x0040, 0x2416, 0x0078, 0x2431, 0x157e, 0x1078,
-+	0x1e6e, 0x157f, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
-+	0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
-+	0x00f0, 0x241a, 0x8211, 0x0040, 0x2431, 0x20a9, 0x0100, 0x0078,
-+	0x241a, 0x1078, 0x1e43, 0x007c, 0x6114, 0x1078, 0x276d, 0x6900,
-+	0xa184, 0x0001, 0x0040, 0x244e, 0x6028, 0xa084, 0x00ff, 0x00c0,
-+	0x25df, 0x6800, 0xa084, 0x0001, 0x0040, 0x25e7, 0x6803, 0x0000,
-+	0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x25ef, 0x2011, 0x0001,
-+	0x6020, 0xd0f4, 0x0040, 0x2456, 0xa295, 0x0002, 0xd0c4, 0x0040,
-+	0x245b, 0xa295, 0x0008, 0xd0cc, 0x0040, 0x2460, 0xa295, 0x0400,
-+	0x601c, 0xa084, 0x0002, 0x0040, 0x2467, 0xa295, 0x0004, 0x602c,
-+	0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x25eb, 0xa182, 0x001b,
-+	0x00c8, 0x25eb, 0x0040, 0x25eb, 0x690e, 0x602c, 0x8007, 0xa08c,
-+	0x00ff, 0xa182, 0x0002, 0x0048, 0x25eb, 0xa182, 0x001b, 0x00c8,
-+	0x25eb, 0x0040, 0x25eb, 0x6912, 0x6134, 0xa184, 0x000f, 0x0040,
-+	0x2491, 0x8000, 0xd0a4, 0x0040, 0x248e, 0x8001, 0xa18c, 0xfff0,
-+	0xa10d, 0x6922, 0x6030, 0xa005, 0x00c0, 0x2498, 0x2001, 0x001e,
-+	0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x25e7, 0x6806,
-+	0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x25e7, 0x680a, 0x6a02,
-+	0x0078, 0x25ef, 0x6014, 0xd0fc, 0x00c0, 0x24b2, 0x2001, 0x6064,
-+	0x0078, 0x24b4, 0x2001, 0x60a4, 0x2004, 0xa084, 0x8000, 0x0040,
-+	0x25e7, 0x6114, 0x1078, 0x276d, 0x2091, 0x8000, 0x6a04, 0x6b08,
-+	0x6418, 0xa484, 0x0003, 0x0040, 0x24d8, 0x6128, 0xa18c, 0x00ff,
-+	0x8001, 0x00c0, 0x24d1, 0x2100, 0xa210, 0x0048, 0x24fe, 0x0078,
-+	0x24d8, 0x8001, 0x00c0, 0x24fe, 0x2100, 0xa212, 0x0048, 0x24fe,
-+	0xa484, 0x000c, 0x0040, 0x24f2, 0x6128, 0x810f, 0xa18c, 0x00ff,
-+	0xa082, 0x0004, 0x00c0, 0x24ea, 0x2100, 0xa318, 0x0048, 0x24fe,
-+	0x0078, 0x24f2, 0xa082, 0x0004, 0x00c0, 0x24fe, 0x2100, 0xa31a,
-+	0x0048, 0x24fe, 0x6030, 0xa005, 0x0040, 0x24f8, 0x8000, 0x6816,
-+	0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x25ef, 0x2091, 0x8001,
-+	0x0078, 0x25eb, 0x6114, 0x1078, 0x276d, 0x2091, 0x8000, 0x6b08,
-+	0x8318, 0x0048, 0x2510, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x25fd,
-+	0x2091, 0x8001, 0x0078, 0x25eb, 0x6024, 0x8007, 0xa084, 0x00ff,
-+	0x0040, 0x253a, 0xa086, 0x0080, 0x00c0, 0x2562, 0x20a9, 0x0008,
-+	0x6014, 0xd0fc, 0x00c0, 0x2528, 0x2069, 0xa7e0, 0x0078, 0x252a,
-+	0x2069, 0xa900, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802,
-+	0xade8, 0x0009, 0x0070, 0x2536, 0x0078, 0x252c, 0x2091, 0x8001,
-+	0x0078, 0x25ef, 0x6028, 0xa015, 0x0040, 0x2562, 0x6114, 0x1078,
-+	0x276d, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d,
-+	0x0040, 0x255f, 0xa206, 0x0040, 0x2550, 0x2168, 0x0078, 0x2546,
-+	0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x1e43, 0x0c7f, 0x0d7f,
-+	0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x25fd, 0x2091,
-+	0x8001, 0x0d7f, 0x0078, 0x25e7, 0x6114, 0x1078, 0x276d, 0x6800,
-+	0xa084, 0x0001, 0x0040, 0x25d7, 0x2091, 0x8000, 0x6a04, 0x8210,
-+	0x0048, 0x2577, 0x6a06, 0x2091, 0x8001, 0x0078, 0x25fd, 0x2091,
-+	0x8001, 0x0078, 0x25eb, 0x6114, 0x1078, 0x276d, 0x60ce, 0x60bb,
-+	0x0000, 0x6018, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff, 0xa105,
-+	0x601a, 0x6900, 0xa184, 0x0008, 0x0040, 0x2592, 0x6020, 0xa085,
-+	0x0100, 0x6022, 0xa184, 0x0001, 0x0040, 0x25e7, 0xa184, 0x0100,
-+	0x00c0, 0x25d3, 0xa184, 0x0200, 0x00c0, 0x25cf, 0x681c, 0xa005,
-+	0x00c0, 0x25db, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000f, 0x00c0,
-+	0x25ab, 0x1078, 0x2750, 0x78c3, 0x0000, 0x6004, 0x8007, 0xa084,
-+	0x00ff, 0x78b6, 0x8001, 0x609f, 0x0000, 0x0040, 0x25c0, 0x1078,
-+	0x25ff, 0x0040, 0x25c0, 0x78c0, 0xa085, 0x0100, 0x78c2, 0x007c,
-+	0x78bb, 0x0000, 0x78bf, 0x0000, 0x6024, 0xa084, 0xff00, 0x6026,
-+	0x1078, 0x4611, 0x00c0, 0x25cd, 0x007c, 0x0078, 0x20c5, 0x2009,
-+	0x0017, 0x0078, 0x25f1, 0x2009, 0x000e, 0x0078, 0x25f1, 0x2009,
-+	0x0007, 0x0078, 0x25f1, 0x2009, 0x0035, 0x0078, 0x25f1, 0x2009,
-+	0x003e, 0x0078, 0x25f1, 0x2009, 0x0004, 0x0078, 0x25f1, 0x2009,
-+	0x0006, 0x0078, 0x25f1, 0x2009, 0x0016, 0x0078, 0x25f1, 0x2009,
-+	0x0001, 0x6024, 0xa084, 0xff00, 0xa105, 0x6026, 0x2091, 0x8000,
-+	0x1078, 0x2240, 0x2091, 0x8001, 0x007c, 0x0078, 0x1e43, 0x609f,
-+	0x0000, 0x78b8, 0xa06d, 0x2c00, 0x78ba, 0x00c0, 0x260a, 0x78be,
-+	0x0078, 0x2612, 0x689e, 0x2d00, 0x6002, 0x78bc, 0xad06, 0x00c0,
-+	0x2612, 0x6002, 0x78b4, 0x8001, 0x78b6, 0x00c0, 0x261e, 0x78c0,
-+	0xa084, 0xfeff, 0x78c2, 0x78bc, 0x2060, 0xa006, 0x007c, 0x0e7e,
-+	0xa02e, 0x2530, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984,
-+	0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, 0x2630, 0x1078, 0x564a,
-+	0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x6080, 0xd7fc,
-+	0x00c0, 0x263c, 0x2071, 0x6040, 0xa784, 0x0f00, 0x800b, 0xa784,
-+	0x001f, 0x0040, 0x2647, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
-+	0x71e0, 0xa168, 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
-+	0x8003, 0x71e4, 0xa100, 0x60c6, 0x2091, 0x8000, 0x780c, 0xd0c4,
-+	0x0040, 0x266c, 0xd0ec, 0x0040, 0x2668, 0xd7fc, 0x00c0, 0x2665,
-+	0xd0f4, 0x00c0, 0x2673, 0x0078, 0x266c, 0xd0fc, 0x00c0, 0x2673,
-+	0x7808, 0xd0f4, 0x00c0, 0x2673, 0x6e08, 0xd684, 0x0040, 0x26a1,
-+	0xd9fc, 0x00c0, 0x26a1, 0x2091, 0x8001, 0x1078, 0x1ef5, 0x2091,
-+	0x8000, 0x1078, 0x2240, 0x2091, 0x8001, 0x78bb, 0x0000, 0x78bf,
-+	0x0000, 0x780c, 0xd0e4, 0x00c0, 0x2707, 0x780c, 0xd0c4, 0x0040,
-+	0x2707, 0xd0ec, 0x0040, 0x2699, 0xd7fc, 0x00c0, 0x2694, 0xd0f4,
-+	0x00c0, 0x269d, 0x0078, 0x2707, 0xd0fc, 0x00c0, 0x269d, 0x0078,
-+	0x2707, 0x7808, 0xd0f4, 0x0040, 0x2707, 0x601b, 0x0021, 0x0078,
-+	0x2707, 0x6024, 0xa096, 0x0001, 0x00c0, 0x26a8, 0x8000, 0x6026,
-+	0x6a10, 0x6814, 0xa202, 0x0048, 0x26b7, 0x0040, 0x26b7, 0x2091,
-+	0x8001, 0x2039, 0x0200, 0x1078, 0x2709, 0x0078, 0x2707, 0x2c08,
-+	0xd9fc, 0x0040, 0x26df, 0x6800, 0xa065, 0x0040, 0x26df, 0x6a04,
-+	0x7000, 0xa084, 0x0002, 0x0040, 0x26d5, 0x7050, 0xa206, 0x00c0,
-+	0x26d5, 0x6b04, 0x2160, 0x2304, 0x6002, 0xa005, 0x00c0, 0x26d1,
-+	0x6902, 0x2260, 0x6102, 0x0078, 0x26eb, 0x2d00, 0x2060, 0x1078,
-+	0x2d8b, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0078, 0x26eb, 0x6800,
-+	0x6902, 0xa065, 0x0040, 0x26e7, 0x6102, 0x0078, 0x26e8, 0x6906,
-+	0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc, 0x0040, 0x26f6, 0xa6b4,
-+	0xffdc, 0x6e0a, 0x682b, 0x0000, 0x682f, 0x0000, 0x6810, 0x8000,
-+	0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040, 0x2703, 0xa6b6, 0x0040,
-+	0x6e0a, 0x1078, 0x1f06, 0x78bf, 0x0000, 0x78bb, 0x0000, 0x0e7f,
-+	0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x2240,
-+	0x2091, 0x8001, 0x78bc, 0xa065, 0x0040, 0x271c, 0x609c, 0x78be,
-+	0x609f, 0x0000, 0x0078, 0x270c, 0x78bb, 0x0000, 0x78bf, 0x0000,
-+	0x007c, 0x796c, 0x7870, 0x7b88, 0xd384, 0x0040, 0x272b, 0x8000,
-+	0xa112, 0x0048, 0x2730, 0xc384, 0x8000, 0xa112, 0x00c8, 0x273d,
-+	0x7a78, 0x721a, 0x7a74, 0x721e, 0x7a80, 0x7222, 0x7a7c, 0x7226,
-+	0xa006, 0xd384, 0x0040, 0x273d, 0x8000, 0x7872, 0x70d2, 0x7814,
-+	0xa005, 0x0040, 0x274b, 0x8001, 0x7816, 0x00c0, 0x274b, 0x0068,
-+	0x274b, 0x2091, 0x4080, 0x007c, 0x2039, 0x2764, 0x0078, 0x2752,
-+	0x2039, 0x276a, 0x2704, 0xa005, 0x0040, 0x2763, 0xac00, 0x2068,
-+	0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e,
-+	0x8738, 0x0078, 0x2752, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015,
-+	0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x0c7e, 0x6014, 0x1078,
-+	0x47fa, 0x2c68, 0x0c7f, 0x007c, 0x78af, 0x0000, 0x2009, 0x6001,
-+	0x2104, 0xd084, 0x0040, 0x27a3, 0x6004, 0xa086, 0x0103, 0x00c0,
-+	0x27a3, 0x6114, 0x6018, 0xa105, 0x00c0, 0x27a3, 0x0d7e, 0x2069,
-+	0x0000, 0x6818, 0xd084, 0x00c0, 0x27a2, 0x600c, 0x70c6, 0x6010,
-+	0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x0d7f,
-+	0x1078, 0x2267, 0x0068, 0x27d7, 0x7868, 0xa065, 0x00c0, 0x2776,
-+	0x0078, 0x27d7, 0x0d7f, 0x1078, 0x27da, 0x0040, 0x27d2, 0x6204,
-+	0xa294, 0x00ff, 0xa296, 0x0003, 0x0040, 0x27b5, 0x6204, 0xa296,
-+	0x0110, 0x00c0, 0x27c3, 0x78af, 0x0001, 0x6204, 0xa294, 0xff00,
-+	0x8217, 0x8211, 0x0040, 0x27c3, 0x85ff, 0x00c0, 0x27d2, 0x8210,
-+	0xa202, 0x00c8, 0x27d2, 0x057e, 0x1078, 0x27e9, 0x057f, 0x00c0,
-+	0x27d2, 0x8528, 0x78ac, 0xa005, 0x00c0, 0x27d2, 0x7868, 0xa065,
-+	0x00c0, 0x2776, 0x85ff, 0x0040, 0x27d9, 0x2091, 0x4080, 0x7894,
-+	0x70d6, 0x007c, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x00c0, 0x27e3,
-+	0x2300, 0xa005, 0x007c, 0x0048, 0x27e7, 0xa302, 0x007c, 0x8002,
-+	0x007c, 0xa184, 0xff00, 0x0040, 0x27f6, 0x810f, 0x810c, 0x810c,
-+	0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x27f9, 0x8107, 0x8004,
-+	0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319,
-+	0xa421, 0xa529, 0x2009, 0x0020, 0x6004, 0xa086, 0x0103, 0x00c0,
-+	0x280f, 0x6028, 0xa005, 0x00c0, 0x280f, 0x2009, 0x000c, 0x1078,
-+	0x1ddf, 0x0040, 0x2832, 0x78a8, 0x8000, 0x78aa, 0xa086, 0x0002,
-+	0x00c0, 0x2840, 0x6014, 0xd0fc, 0x00c0, 0x2822, 0x2069, 0x6040,
-+	0x0078, 0x2824, 0x2069, 0x6080, 0x2091, 0x8000, 0x681b, 0x0003,
-+	0x78ab, 0x0000, 0x78b0, 0xa085, 0x0300, 0x78b2, 0x2091, 0x8001,
-+	0x0078, 0x2840, 0x78ab, 0x0000, 0x1078, 0x2267, 0x7990, 0x7894,
-+	0x8000, 0xa10a, 0x00c8, 0x283d, 0xa006, 0x7896, 0x70d6, 0xa006,
-+	0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x2138, 0xd7fc, 0x00c0,
-+	0x284d, 0x2009, 0x605a, 0x0078, 0x284f, 0x2009, 0x609a, 0x2091,
-+	0x8000, 0x200a, 0x0f7e, 0xd7fc, 0x00c0, 0x2866, 0x2009, 0x6040,
-+	0x2001, 0x6002, 0x2004, 0xd0ec, 0x0040, 0x2862, 0x2079, 0x0100,
-+	0x0078, 0x286a, 0x2079, 0x0200, 0x0078, 0x286a, 0x2009, 0x6080,
-+	0x2079, 0x0100, 0x2104, 0xa086, 0x0000, 0x00c0, 0x2883, 0xd7fc,
-+	0x00c0, 0x2876, 0x2009, 0x6044, 0x0078, 0x2878, 0x2009, 0x6084,
-+	0x2104, 0xa005, 0x00c0, 0x2883, 0x7830, 0xa084, 0x00c0, 0x00c0,
-+	0x2883, 0x781b, 0x004b, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x2c00,
-+	0xa005, 0x00c0, 0x2890, 0xa188, 0x0005, 0x2104, 0x0078, 0x2891,
-+	0x6014, 0xd0fc, 0x00c0, 0x28a4, 0x2071, 0x6040, 0x2001, 0x6002,
-+	0x2004, 0xd0ec, 0x0040, 0x28a0, 0x2079, 0x0100, 0x0078, 0x28a8,
-+	0x2079, 0x0200, 0x0078, 0x28a8, 0x2071, 0x6080, 0x2079, 0x0100,
-+	0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, 0x28da, 0x0078,
-+	0x28ce, 0x2c00, 0xa005, 0x00c0, 0x28ba, 0xa188, 0x0005, 0x2104,
-+	0x0078, 0x28bb, 0x6014, 0xd0fc, 0x00c0, 0x28cc, 0x2001, 0x6002,
-+	0x2004, 0xd0ec, 0x0040, 0x28c8, 0x2079, 0x0100, 0x0078, 0x28ce,
-+	0x2079, 0x0200, 0x0078, 0x28ce, 0x2079, 0x0100, 0x7830, 0xa084,
-+	0x00c0, 0x00c0, 0x28da, 0x2c00, 0xa005, 0x00c0, 0x28d8, 0x2104,
-+	0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, 0x007c, 0x2009,
-+	0x0002, 0x2069, 0x6000, 0x6808, 0xd0ec, 0x00c0, 0x2942, 0x2071,
-+	0x6080, 0x2079, 0x0100, 0x2021, 0x62bf, 0x784b, 0x000f, 0x0098,
-+	0x28fb, 0x7838, 0x0078, 0x28ed, 0x784b, 0x000f, 0x00a8, 0x28fb,
-+	0x7838, 0x0078, 0x28f4, 0x20a9, 0x0060, 0x789b, 0x0000, 0x78af,
-+	0x0000, 0x78af, 0x0000, 0x00f0, 0x28ff, 0x70ab, 0x009d, 0x2019,
-+	0x5df1, 0x1078, 0x2958, 0x680c, 0xd0e4, 0x0040, 0x2919, 0x789b,
-+	0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x1020, 0x00f0,
-+	0x2913, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040,
-+	0x2922, 0xc1bd, 0x1078, 0x2b31, 0x017f, 0x701c, 0xa084, 0x000f,
-+	0x007e, 0x680c, 0xd0e4, 0x007f, 0x00c0, 0x2932, 0xa085, 0x6340,
-+	0x0078, 0x2934, 0xa085, 0x62c0, 0x7806, 0x780f, 0xb204, 0x7843,
-+	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x704f, 0x0008, 0x745a,
-+	0x7057, 0x0000, 0x8109, 0x0040, 0x2957, 0x2071, 0x6040, 0x6808,
-+	0xd0ec, 0x0040, 0x2951, 0x2079, 0x0100, 0x2021, 0x60bf, 0x0078,
-+	0x28ed, 0x2079, 0x0200, 0x2021, 0x60bf, 0x0078, 0x28f4, 0x007c,
-+	0x137e, 0x147e, 0x157e, 0x047e, 0xaf80, 0x002b, 0x20a0, 0x2304,
-+	0xa005, 0x789a, 0x0040, 0x2979, 0x8318, 0x2324, 0x8318, 0x2398,
-+	0x24a8, 0xa484, 0xff00, 0x0040, 0x2971, 0xa482, 0x0100, 0x20a9,
-+	0x0100, 0x2020, 0x53a6, 0xa005, 0x00c0, 0x2968, 0x3318, 0x0078,
-+	0x295f, 0x047f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0f7e,
-+	0xd1bc, 0x00c0, 0x2993, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x298f, 0x2079, 0x0100, 0x0078, 0x2995, 0x2079,
-+	0x0200, 0x0078, 0x2995, 0x2079, 0x0100, 0xa18c, 0x000f, 0x7804,
-+	0xa084, 0xfff0, 0xa105, 0x7806, 0x0f7f, 0x017f, 0x1078, 0x2b31,
-+	0x007c, 0xd3fc, 0x00c0, 0x29b4, 0x007e, 0x2001, 0x6002, 0x2004,
-+	0xd0ec, 0x007f, 0x0040, 0x29b0, 0x2011, 0x0101, 0x0078, 0x29b6,
-+	0x2011, 0x0201, 0x0078, 0x29b6, 0x2011, 0x0101, 0x20a9, 0x0009,
-+	0x810b, 0x00f0, 0x29b8, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff,
-+	0xa105, 0x2012, 0x007c, 0x2019, 0x0002, 0x2001, 0x6002, 0x2004,
-+	0xd0ec, 0x0040, 0x29d0, 0x8319, 0x2009, 0x0101, 0x0078, 0x29d2,
-+	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x00f0, 0x29d4, 0xa294,
-+	0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0040,
-+	0x29e5, 0x2009, 0x0201, 0x0078, 0x29d2, 0x007c, 0xd3fc, 0x00c0,
-+	0x29f9, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x29f5, 0x2011, 0x0101, 0x0078, 0x29fb, 0x2011, 0x0201, 0x0078,
-+	0x29fb, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x00f0, 0x29fd,
-+	0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c,
-+	0xd3fc, 0x00c0, 0x2a1b, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x2a17, 0x2011, 0x0102, 0x0078, 0x2a1d, 0x2011,
-+	0x0202, 0x0078, 0x2a1d, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf,
-+	0xa105, 0x2012, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x2a37, 0x007e,
-+	0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2a33, 0x2061,
-+	0x0100, 0x0078, 0x2a39, 0x2061, 0x0200, 0x0078, 0x2a39, 0x2061,
-+	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x62ac,
-+	0x63ac, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x2a57, 0x007e,
-+	0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2a53, 0x2061,
-+	0x0100, 0x0078, 0x2a59, 0x2061, 0x0200, 0x0078, 0x2a59, 0x2061,
-+	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4,
-+	0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0,
-+	0x2a79, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x2a75, 0x2061, 0x0100, 0x0078, 0x2a7b, 0x2061, 0x0200, 0x0078,
-+	0x2a7b, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022,
-+	0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x0c7e,
-+	0xd1bc, 0x00c0, 0x2a9b, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x2a97, 0x2061, 0x0100, 0x0078, 0x2a9d, 0x2061,
-+	0x0200, 0x0078, 0x2a9d, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
-+	0xa080, 0x0020, 0x609a, 0x60a4, 0xd2ac, 0x0040, 0x2aa9, 0xc2ac,
-+	0xc3f5, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c,
-+	0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x2b0f,
-+	0xd1fc, 0x00c0, 0x2abf, 0x2061, 0xa6c0, 0x0078, 0x2ac1, 0x2061,
-+	0xa7d0, 0x1078, 0x2b17, 0x0040, 0x2af4, 0x20a9, 0x0101, 0xd1fc,
-+	0x00c0, 0x2ace, 0x2061, 0xa5c0, 0x0078, 0x2ad0, 0x2061, 0xa6d0,
-+	0x0c7e, 0x1078, 0x2b17, 0x0040, 0x2adb, 0x0c7f, 0x8c60, 0x00f0,
-+	0x2ad0, 0x0078, 0x2b0f, 0x007f, 0xd1fc, 0x00c0, 0x2ae5, 0x2071,
-+	0x6040, 0xa082, 0xa5c0, 0x0078, 0x2ae9, 0x2071, 0x6080, 0xa082,
-+	0xa6d0, 0x707e, 0x717a, 0x2001, 0x0004, 0x706a, 0x7087, 0x000f,
-+	0x1078, 0x2845, 0x0078, 0x2b0b, 0x60d0, 0xa005, 0x00c0, 0x2b0f,
-+	0xd1fc, 0x00c0, 0x2aff, 0x2071, 0x6040, 0x0078, 0x2b01, 0x2071,
-+	0x6080, 0x717a, 0x2c00, 0x7082, 0x2001, 0x0006, 0x706a, 0x7087,
-+	0x000f, 0x1078, 0x2845, 0x2001, 0x0000, 0x0078, 0x2b11, 0x2001,
-+	0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04,
-+	0xa005, 0x0040, 0x2b2e, 0x2060, 0x6010, 0xa306, 0x00c0, 0x2b2b,
-+	0x600c, 0xa206, 0x00c0, 0x2b2b, 0x6014, 0xa106, 0x00c0, 0x2b2b,
-+	0xa006, 0x0078, 0x2b30, 0x6000, 0x0078, 0x2b18, 0xa085, 0x0001,
-+	0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, 0x2b49, 0x2079,
-+	0x6040, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x2b45, 0x2071, 0x0100, 0x0078, 0x2b4d, 0x2071, 0x0200, 0x0078,
-+	0x2b4d, 0x2079, 0x6080, 0x2071, 0x0100, 0x791c, 0xa18c, 0x000f,
-+	0x70ec, 0xa084, 0x0100, 0x007f, 0x0040, 0x2b64, 0x810b, 0x810b,
-+	0x810b, 0x810b, 0xd0bc, 0x00c0, 0x2b61, 0xa18d, 0x0f00, 0x0078,
-+	0x2b63, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x2001,
-+	0x6001, 0x2004, 0xd0ac, 0x00c0, 0x2b78, 0x68e4, 0xa08c, 0x0020,
-+	0x0040, 0x2b78, 0xa084, 0x0006, 0x00c0, 0x2b78, 0x1078, 0x2b79,
-+	0x007c, 0x6014, 0x0e7e, 0x037e, 0x2018, 0x2071, 0x6540, 0xd0fc,
-+	0x00c0, 0x2b84, 0x2071, 0x64c0, 0x8007, 0xa084, 0x000f, 0x8003,
-+	0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a, 0x00c0, 0x2bea,
-+	0x7108, 0xa194, 0xff00, 0x0040, 0x2bea, 0xa18c, 0x00ff, 0x2001,
-+	0x000a, 0xa106, 0x0040, 0x2bb7, 0x2001, 0x000c, 0xa106, 0x0040,
-+	0x2bbb, 0x2001, 0x0012, 0xa106, 0x0040, 0x2bbf, 0x2001, 0x0014,
-+	0xa106, 0x0040, 0x2bc3, 0x2001, 0x0019, 0xa106, 0x0040, 0x2bc7,
-+	0x2001, 0x0032, 0xa106, 0x0040, 0x2bcb, 0x0078, 0x2bcf, 0x2009,
-+	0x000c, 0x0078, 0x2bd0, 0x2009, 0x0012, 0x0078, 0x2bd0, 0x2009,
-+	0x0014, 0x0078, 0x2bd0, 0x2009, 0x0019, 0x0078, 0x2bd0, 0x2009,
-+	0x0020, 0x0078, 0x2bd0, 0x2009, 0x003f, 0x0078, 0x2bd0, 0xa016,
-+	0x2100, 0xa205, 0x700a, 0x7004, 0xa085, 0x000a, 0x7006, 0x2071,
-+	0x6000, 0x7004, 0xd0bc, 0x0040, 0x2bea, 0xd3fc, 0x00c0, 0x2be5,
-+	0x73ee, 0x2071, 0x6040, 0x0078, 0x2be8, 0x73f2, 0x2071, 0x6080,
-+	0x701b, 0x800f, 0x037f, 0x0e7f, 0x007c, 0x2001, 0x6003, 0x2004,
-+	0xd0e4, 0x00c0, 0x2bf9, 0x7804, 0xa084, 0xff1f, 0xa085, 0x6340,
-+	0x7806, 0x007c, 0x0068, 0x2bfa, 0x2091, 0x8000, 0x2071, 0x0000,
-+	0x007e, 0x7018, 0xd084, 0x00c0, 0x2c01, 0x007f, 0x2071, 0x0010,
-+	0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x090b, 0x70df,
-+	0x0001, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
-+	0x2c17, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0xa594, 0x003f, 0xa49c,
-+	0x0003, 0xa484, 0x000f, 0x0079, 0x2c25, 0x2c37, 0x2c37, 0x2c37,
-+	0x30a9, 0x4547, 0x2c35, 0x2c5f, 0x2c62, 0x2c35, 0x2c35, 0x2c35,
-+	0x2c35, 0x2c35, 0x2c35, 0x2c35, 0x2c35, 0x1078, 0x2bfa, 0x8507,
-+	0xa084, 0x001f, 0x0079, 0x2c3c, 0x2c65, 0x30a9, 0x32d8, 0x33f3,
-+	0x341e, 0x36b7, 0x39f0, 0x3a6f, 0x3aed, 0x3b81, 0x3c6c, 0x3d13,
-+	0x2c5f, 0x31d4, 0x39bf, 0x2c5c, 0x49b9, 0x49e0, 0x4bd7, 0x4be3,
-+	0x4cc7, 0x2c5c, 0x2c5c, 0x4dae, 0x4db2, 0x49b7, 0x2c5c, 0x4b1d,
-+	0x2c5c, 0x484c, 0x2c62, 0x2c5c, 0x1078, 0x2bfa, 0x007c, 0x781b,
-+	0x004f, 0x007c, 0x781b, 0x00d6, 0x007c, 0x724a, 0xa584, 0x0001,
-+	0x00c0, 0x485e, 0x0040, 0x2c78, 0x1078, 0x2bfa, 0x7003, 0x0000,
-+	0x7053, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, 0x1078, 0x44fa,
-+	0x7064, 0xa06d, 0x0040, 0x2c85, 0x70f4, 0xa084, 0x0001, 0x7168,
-+	0xa105, 0x00c0, 0x2c85, 0x0078, 0x2df1, 0x7068, 0xa084, 0x0007,
-+	0x0079, 0x2c8a, 0x2c92, 0x2d10, 0x2d19, 0x2d24, 0x2d2f, 0x2dd7,
-+	0x2d3a, 0x2d10, 0x7830, 0xd0bc, 0x00c0, 0x2c5e, 0x71f0, 0xd1bc,
-+	0x00c0, 0x2c5e, 0xd1b4, 0x00c0, 0x2cee, 0x70c0, 0xa086, 0x0001,
-+	0x0040, 0x2c5e, 0x1078, 0x44e0, 0x00c0, 0x2c5e, 0x70d0, 0xa06d,
-+	0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808,
-+	0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040,
-+	0x2cbc, 0x69c0, 0x7daa, 0x79aa, 0x68c4, 0xa04d, 0x6e1c, 0x7830,
-+	0xd0bc, 0x00c0, 0x2c5e, 0x2001, 0x0010, 0x0078, 0x2f58, 0x7064,
-+	0xa005, 0x00c0, 0x2c5e, 0x1078, 0x44e0, 0x00c0, 0x2c5e, 0x0c7e,
-+	0x0d7e, 0x70d0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010,
-+	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
-+	0xa886, 0x0001, 0x0040, 0x2ce7, 0x69c0, 0x7daa, 0x79aa, 0x68c4,
-+	0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2f58, 0x1078, 0x44bc,
-+	0x00c0, 0x2c5e, 0x70d8, 0xa06d, 0x6814, 0xc0fc, 0x8007, 0x7882,
-+	0x68b4, 0x785a, 0x781b, 0x004f, 0x704c, 0xc08d, 0x780a, 0x68c0,
-+	0x703e, 0x70f0, 0xc0b4, 0x70f2, 0x70d4, 0xa065, 0x68c4, 0x705e,
-+	0x7003, 0x0002, 0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x007c,
-+	0x1078, 0x44bc, 0x00c0, 0x2d18, 0x781b, 0x0048, 0x7003, 0x0004,
-+	0x007c, 0x1078, 0x44bc, 0x00c0, 0x2d23, 0x2011, 0x000c, 0x1078,
-+	0x2d4a, 0x7003, 0x0004, 0x007c, 0x1078, 0x44bc, 0x00c0, 0x2d2e,
-+	0x2011, 0x0006, 0x1078, 0x2d4a, 0x7003, 0x0004, 0x007c, 0x1078,
-+	0x44bc, 0x00c0, 0x2d39, 0x2011, 0x000d, 0x1078, 0x2d4a, 0x7003,
-+	0x0004, 0x007c, 0x1078, 0x44bc, 0x00c0, 0x2d49, 0x2011, 0x0006,
-+	0x1078, 0x2d4a, 0x7080, 0x7083, 0x0000, 0x2068, 0x7052, 0x7003,
-+	0x0001, 0x007c, 0x7178, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010,
-+	0xa286, 0x000c, 0x00c0, 0x2d59, 0x7aaa, 0x2001, 0x0001, 0x0078,
-+	0x2d6e, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d,
-+	0x0040, 0x2d67, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2d6e, 0x78ab,
-+	0x0020, 0x717c, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060,
-+	0x78aa, 0x785b, 0x0004, 0x781b, 0x00e7, 0x1078, 0x44fa, 0x7087,
-+	0x000f, 0x70f0, 0xd0b4, 0x0040, 0x2d8a, 0xc0b4, 0x70f2, 0x0c7e,
-+	0x70d4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-+	0x601a, 0x0c7f, 0x007c, 0x7010, 0xa005, 0x00c0, 0x2d99, 0x70f0,
-+	0xd0b4, 0x0040, 0x2d9a, 0x70d4, 0xac06, 0x00c0, 0x2d9a, 0x1078,
-+	0x2d79, 0x007c, 0x017e, 0x71c0, 0xa186, 0x0001, 0x0040, 0x2dcc,
-+	0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70d0, 0x2068,
-+	0x6800, 0xac06, 0x0040, 0x2db3, 0x8211, 0x0040, 0x2dca, 0x1078,
-+	0x2dce, 0x0078, 0x2da8, 0x0c7e, 0x2100, 0x2011, 0x0001, 0xa212,
-+	0x70d0, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x8211, 0x0040, 0x2dc7, 0x1078, 0x2dce, 0x0078, 0x2dba, 0x70c3,
-+	0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8, 0x0005,
-+	0x70c8, 0xad06, 0x00c0, 0x2dd6, 0x70c4, 0x2068, 0x007c, 0x1078,
-+	0x44bc, 0x00c0, 0x2c5e, 0x7080, 0x2068, 0x7778, 0x1078, 0x43a8,
-+	0x2c50, 0x1078, 0x45c9, 0x789b, 0x0010, 0x6814, 0xa084, 0x001f,
-+	0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0078,
-+	0x2f5e, 0x1078, 0x44bc, 0x00c0, 0x2c5e, 0x789b, 0x0010, 0x7064,
-+	0x2068, 0x6f14, 0x1078, 0x2d79, 0x1078, 0x43a8, 0x2c50, 0x1078,
-+	0x45c9, 0x6824, 0xa005, 0x0040, 0x2e0d, 0xa082, 0x0006, 0x0048,
-+	0x2e0b, 0x0078, 0x2e0d, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f,
-+	0xa39d, 0x00c0, 0x2960, 0x6000, 0x2a60, 0xa084, 0x8000, 0x0040,
-+	0x2e1d, 0xa684, 0x0001, 0x0040, 0x2e1f, 0xa39c, 0xffbf, 0x7baa,
-+	0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0078, 0x2f5e,
-+	0xc28d, 0x72f2, 0x72dc, 0xa200, 0xa015, 0x7158, 0x8108, 0xa12a,
-+	0x0048, 0x2e33, 0x71dc, 0x2164, 0x6504, 0x85ff, 0x00c0, 0x2e4e,
-+	0x715a, 0x8421, 0x00c0, 0x2e2e, 0x70f0, 0xd08c, 0x0040, 0x2e46,
-+	0x70ec, 0xa005, 0x00c0, 0x2e46, 0x70ef, 0x000a, 0x7048, 0xa005,
-+	0x0040, 0x485e, 0x007c, 0x2200, 0x0078, 0x2e38, 0x70f0, 0xc08c,
-+	0x70f2, 0x70ef, 0x0000, 0x6034, 0xa005, 0x00c0, 0x2e4b, 0x6708,
-+	0xa784, 0x073f, 0x0040, 0x2e78, 0xd7d4, 0x00c0, 0x2e4b, 0xa784,
-+	0x0021, 0x00c0, 0x2e4b, 0xd78c, 0x0040, 0x2e6b, 0xd794, 0x0040,
-+	0x2e4b, 0xc794, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2e4b, 0xd7c4,
-+	0x0040, 0x2e78, 0x6018, 0xa005, 0x00c0, 0x2e4b, 0xc7c4, 0x670a,
-+	0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0040,
-+	0x2e89, 0x601c, 0xa302, 0x0048, 0x2e8c, 0x0040, 0x2e8c, 0x0078,
-+	0x2e4b, 0x83ff, 0x00c0, 0x2e4b, 0x2d58, 0x2c50, 0x715a, 0x68d3,
-+	0x0000, 0xd7bc, 0x00c0, 0x2e97, 0x7024, 0x6022, 0x603a, 0xc7bc,
-+	0x670a, 0x68c4, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001,
-+	0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, 0x2eab,
-+	0xd684, 0x0040, 0x2ead, 0xa39c, 0xffbf, 0xd6a4, 0x0040, 0x2eb2,
-+	0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2f03, 0xc7a5, 0x670a,
-+	0x2c00, 0x68ca, 0x77c0, 0xa786, 0x0001, 0x00c0, 0x2ed9, 0x70f0,
-+	0xd0b4, 0x00c0, 0x2ed9, 0x7000, 0xa082, 0x0001, 0x00c8, 0x2ed9,
-+	0x7010, 0xa005, 0x00c0, 0x2ed9, 0x1078, 0x44e0, 0x00c0, 0x2ed9,
-+	0x7830, 0xd0bc, 0x00c0, 0x2ed9, 0x789b, 0x0010, 0x7baa, 0x0078,
-+	0x2f56, 0x8739, 0x77c2, 0x2750, 0x77cc, 0xa7b0, 0x0005, 0x70c8,
-+	0xa606, 0x00c0, 0x2ee4, 0x76c4, 0x76ce, 0x2c3a, 0x8738, 0x2d3a,
-+	0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc,
-+	0x0040, 0x2efa, 0x2091, 0x303d, 0x70f0, 0xa084, 0x303d, 0x2091,
-+	0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, 0x2f02, 0x8421, 0x2200,
-+	0x00c0, 0x2e2d, 0x007c, 0xd1dc, 0x0040, 0x3ffb, 0x2029, 0x0020,
-+	0xd69c, 0x00c0, 0x2f10, 0x8528, 0xd68c, 0x00c0, 0x2f10, 0x8528,
-+	0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70e8, 0xa160,
-+	0x2c64, 0x8cff, 0x0040, 0x2f2e, 0x6014, 0xa706, 0x00c0, 0x2f18,
-+	0x60bc, 0x8001, 0x60be, 0x00c0, 0x2f13, 0x2a60, 0x6008, 0xc0c5,
-+	0x600a, 0x2200, 0x8421, 0x00c0, 0x2e2d, 0x007c, 0x2a60, 0x610e,
-+	0x69c2, 0x2c00, 0x68ca, 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77c0,
-+	0xa786, 0x0001, 0x00c0, 0x2ed9, 0x70f0, 0xd0b4, 0x00c0, 0x2ed9,
-+	0x7000, 0xa082, 0x0001, 0x00c8, 0x2ed9, 0x7010, 0xa005, 0x00c0,
-+	0x2ed9, 0x1078, 0x44e0, 0x00c0, 0x2ed9, 0x7830, 0xd0bc, 0x00c0,
-+	0x2ed9, 0x789b, 0x0010, 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002,
-+	0x007e, 0x6018, 0x8000, 0x601a, 0x0078, 0x2f5f, 0x007e, 0x2960,
-+	0x6104, 0x2a60, 0xa184, 0x0018, 0x0040, 0x2f7a, 0xa184, 0x0010,
-+	0x0040, 0x2f6e, 0x1078, 0x4201, 0x00c0, 0x2f9a, 0xd19c, 0x0040,
-+	0x2f7a, 0x69a0, 0xa184, 0x0600, 0x00c0, 0x2f7a, 0x1078, 0x40f5,
-+	0x0078, 0x2f9a, 0x69a0, 0xa184, 0x1e00, 0x0040, 0x2fa4, 0xd1dc,
-+	0x0040, 0x2f90, 0x0c7e, 0x2960, 0x6000, 0xc0ed, 0x6002, 0x6104,
-+	0xc1a5, 0x6106, 0x0c7f, 0x1078, 0x4201, 0x00c0, 0x2f9a, 0x69a0,
-+	0xd1cc, 0x0040, 0x2f97, 0x1078, 0x4147, 0x0078, 0x2f9a, 0xd1d4,
-+	0x00c0, 0x2f76, 0x69a0, 0xd1e4, 0x0040, 0x2fa4, 0x6914, 0xa18c,
-+	0xff00, 0x810f, 0x1078, 0x2a43, 0x027f, 0xa68c, 0x00e0, 0xa684,
-+	0x0060, 0x0040, 0x2fb0, 0xa086, 0x0060, 0x00c0, 0x2fb0, 0xc1f5,
-+	0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818,
-+	0xc0fd, 0x681a, 0xd6bc, 0x0040, 0x2fcb, 0xc0fc, 0x708b, 0x0000,
-+	0xa08a, 0x000d, 0x0050, 0x2fc9, 0xa08a, 0x000c, 0x718a, 0x2001,
-+	0x000c, 0x800c, 0x718e, 0x78aa, 0x3518, 0x3340, 0x3428, 0x80ac,
-+	0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098,
-+	0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2ffe,
-+	0x70f0, 0xc0b5, 0x70f2, 0x2c00, 0x70d6, 0x2d00, 0x70da, 0xa286,
-+	0x0002, 0x0040, 0x302a, 0x70c0, 0x8000, 0x70c2, 0x74d0, 0xa498,
-+	0x0005, 0x70c8, 0xa306, 0x00c0, 0x2ff6, 0x73c4, 0x73d2, 0xa286,
-+	0x0010, 0x0040, 0x2c5e, 0x0d7f, 0x0c7f, 0x007c, 0x7000, 0xa005,
-+	0x00c0, 0x2fe0, 0xa286, 0x0002, 0x00c0, 0x3044, 0x1078, 0x44bc,
-+	0x00c0, 0x2fe0, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x68b4, 0x785a,
-+	0x781b, 0x004f, 0x704c, 0xc08d, 0x780a, 0x127e, 0x0d7e, 0x0c7e,
-+	0x70f0, 0xa084, 0x2700, 0x2090, 0x0c7f, 0x0d7f, 0x127f, 0x2900,
-+	0x705e, 0x68c0, 0x703e, 0x7003, 0x0002, 0x2d00, 0x7052, 0xad80,
-+	0x0009, 0x7042, 0x7830, 0xd0bc, 0x0040, 0x3036, 0x2091, 0x303d,
-+	0x70f0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0x70c0, 0xa005,
-+	0x00c0, 0x303b, 0x007c, 0x8421, 0x0040, 0x303a, 0x7254, 0x70dc,
-+	0xa200, 0xa015, 0x0078, 0x2e2d, 0xa286, 0x0010, 0x00c0, 0x306f,
-+	0x1078, 0x44bc, 0x00c0, 0x2fe0, 0x6814, 0xc0fc, 0x8007, 0x7882,
-+	0x68b4, 0x785a, 0x781b, 0x004f, 0x704c, 0xc08d, 0x780a, 0x70c0,
-+	0x8000, 0x70c2, 0x74d0, 0xa490, 0x0005, 0x70c8, 0xa206, 0x00c0,
-+	0x3062, 0x72c4, 0x72d2, 0x2900, 0x705e, 0x68c0, 0x703e, 0x7003,
-+	0x0002, 0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x007c, 0x6bb4,
-+	0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
-+	0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x004f, 0x2900,
-+	0x705e, 0x7202, 0x704c, 0xc08d, 0x780a, 0x7200, 0x2300, 0xa605,
-+	0x0040, 0x309b, 0x70f0, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0,
-+	0x3095, 0x2009, 0x0000, 0x0078, 0x3097, 0x2009, 0x0001, 0xa284,
-+	0x000f, 0x1079, 0x309f, 0xad80, 0x0009, 0x7042, 0x007c, 0x30a7,
-+	0x591e, 0x591e, 0x590b, 0x591e, 0x30a7, 0x30a7, 0x30a7, 0x1078,
-+	0x2bfa, 0x1078, 0x44bc, 0x1078, 0x2bed, 0x7808, 0xa084, 0xfffc,
-+	0x780a, 0x0f7e, 0x2079, 0x6000, 0x78b0, 0x0f7f, 0xd084, 0x0040,
-+	0x30d2, 0x7068, 0xa086, 0x0001, 0x00c0, 0x30c0, 0x0078, 0x31a7,
-+	0x7068, 0xa086, 0x0005, 0x00c0, 0x30d0, 0x7080, 0x2068, 0x681b,
-+	0x0004, 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822,
-+	0x706b, 0x0000, 0x70c3, 0x0000, 0x70c4, 0x70ce, 0x70d2, 0x70f4,
-+	0xc084, 0x70f6, 0x1078, 0x2d79, 0x2011, 0x0004, 0x7168, 0xa186,
-+	0x0001, 0x0040, 0x30f2, 0xa186, 0x0007, 0x00c0, 0x30eb, 0x701b,
-+	0x0005, 0x0078, 0x30f2, 0x701b, 0x0001, 0x70f0, 0xc0dd, 0x70f2,
-+	0x0078, 0x30f2, 0x2001, 0x6008, 0x203c, 0xd7fc, 0x00c0, 0x30fe,
-+	0xae86, 0x6040, 0x0040, 0x3102, 0x0078, 0x3108, 0xae86, 0x6080,
-+	0x00c0, 0x3108, 0xa784, 0x00ff, 0xa086, 0x0018, 0x0040, 0x310f,
-+	0x7014, 0x7012, 0xa005, 0x00c0, 0x310f, 0x70c3, 0x0001, 0x067e,
-+	0x1078, 0x55ac, 0x157e, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078,
-+	0x42de, 0xa7b8, 0x0100, 0x00f0, 0x3117, 0x157f, 0x067f, 0x7000,
-+	0x0079, 0x3122, 0x315a, 0x3135, 0x3135, 0x312a, 0x315a, 0x315a,
-+	0x315a, 0x315a, 0x7064, 0xa005, 0x0040, 0x315a, 0xad06, 0x00c0,
-+	0x3135, 0x6800, 0x7066, 0x0078, 0x3147, 0x6820, 0xd084, 0x00c0,
-+	0x3143, 0x6f14, 0x1078, 0x43a8, 0x6008, 0xc0d4, 0x600a, 0x1078,
-+	0x3fd3, 0x0078, 0x3147, 0x7060, 0x2060, 0x6800, 0x6002, 0xa684,
-+	0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0040, 0x314f, 0x6a1a, 0x6817,
-+	0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822,
-+	0x1078, 0x2251, 0x2011, 0x0004, 0xb284, 0x0400, 0x00c0, 0x3164,
-+	0x2021, 0xa6c0, 0x0078, 0x3166, 0x2021, 0xa7d0, 0x1078, 0x31b5,
-+	0xb284, 0x0400, 0x0040, 0x3170, 0x2021, 0x6099, 0x0078, 0x3172,
-+	0x2021, 0x6059, 0x1078, 0x31b5, 0x157e, 0x20a9, 0x0101, 0xb284,
-+	0x0400, 0x00c0, 0x317f, 0x2021, 0xa5c0, 0x0078, 0x3181, 0x2021,
-+	0xa6d0, 0x1078, 0x31b5, 0x8420, 0x00f0, 0x3181, 0xb284, 0x0300,
-+	0x0040, 0x318e, 0x2061, 0x65c0, 0x0078, 0x3190, 0x2061, 0x85c0,
-+	0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff, 0x0040,
-+	0x319d, 0xa102, 0x0050, 0x319d, 0x6012, 0x601b, 0x0000, 0xace0,
-+	0x0010, 0x00f0, 0x3194, 0x8421, 0x00c0, 0x3192, 0x157f, 0x7090,
-+	0xa084, 0x8000, 0x0040, 0x31ae, 0x1078, 0x4639, 0x706b, 0x0000,
-+	0x7003, 0x0000, 0x7053, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005,
-+	0x0040, 0x31d0, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000,
-+	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
-+	0x00ff, 0xc09d, 0x6822, 0x1078, 0x2251, 0x007f, 0x0078, 0x31b7,
-+	0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x31da,
-+	0x1078, 0x2bfa, 0x1078, 0x2bed, 0x2300, 0x0079, 0x31df, 0x31e2,
-+	0x326d, 0x328a, 0xa282, 0x0002, 0x0040, 0x31e8, 0x1078, 0x2bfa,
-+	0x7068, 0x706b, 0x0000, 0x7087, 0x0000, 0x0079, 0x31ef, 0x31f7,
-+	0x31f7, 0x31f9, 0x3239, 0x4007, 0x31f7, 0x3239, 0x31f7, 0x1078,
-+	0x2bfa, 0x7778, 0x1078, 0x42de, 0x7778, 0xa7bc, 0x8f00, 0x1078,
-+	0x43a8, 0x6018, 0xa005, 0x0040, 0x3230, 0xd7fc, 0x00c0, 0x320c,
-+	0x2021, 0xa6c0, 0x0078, 0x320e, 0x2021, 0xa7d0, 0x2009, 0x0005,
-+	0x2011, 0x0010, 0x1078, 0x32a5, 0x0040, 0x3230, 0x157e, 0x20a9,
-+	0x0101, 0xd7fc, 0x00c0, 0x3220, 0x2021, 0xa5c0, 0x0078, 0x3222,
-+	0x2021, 0xa6d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078,
-+	0x32a5, 0x047f, 0x0040, 0x322f, 0x8420, 0x00f0, 0x3222, 0x157f,
-+	0x8738, 0xa784, 0x001f, 0x00c0, 0x31ff, 0x0078, 0x2c6e, 0x0078,
-+	0x2c6e, 0x7778, 0x1078, 0x43a8, 0x6018, 0xa005, 0x0040, 0x326b,
-+	0xd7fc, 0x00c0, 0x3247, 0x2021, 0xa6c0, 0x0078, 0x3249, 0x2021,
-+	0xa7d0, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x32a5, 0x0040,
-+	0x326b, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x325b, 0x2021,
-+	0xa5c0, 0x0078, 0x325d, 0x2021, 0xa6d0, 0x047e, 0x2009, 0x0005,
-+	0x2011, 0x0020, 0x1078, 0x32a5, 0x047f, 0x0040, 0x326a, 0x8420,
-+	0x00f0, 0x325d, 0x157f, 0x0078, 0x2c6e, 0x2200, 0x0079, 0x3270,
-+	0x3273, 0x3275, 0x3275, 0x1078, 0x2bfa, 0x2009, 0x0012, 0x7068,
-+	0xa086, 0x0002, 0x0040, 0x327e, 0x2009, 0x000e, 0x6818, 0xd0fc,
-+	0x0040, 0x3283, 0x691a, 0x706b, 0x0000, 0x70f0, 0xc0dd, 0x70f2,
-+	0x0078, 0x445a, 0x2200, 0x0079, 0x328d, 0x3292, 0x3275, 0x3290,
-+	0x1078, 0x2bfa, 0x1078, 0x55ac, 0x7000, 0xa086, 0x0002, 0x00c0,
-+	0x3f81, 0x1078, 0x3fe8, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078,
-+	0x3f72, 0x0040, 0x3f81, 0x0078, 0x2c6e, 0x2404, 0xa005, 0x0040,
-+	0x32d4, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x32b4,
-+	0x2d20, 0x007f, 0x0078, 0x32a6, 0x007f, 0x2022, 0x6817, 0x0000,
-+	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x691a, 0x6820,
-+	0xa084, 0x00ff, 0xa205, 0x6822, 0x682b, 0x0000, 0x1078, 0x2251,
-+	0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078,
-+	0x2d9a, 0x1078, 0x3fe8, 0x007c, 0xa085, 0x0001, 0x0078, 0x32d3,
-+	0x2300, 0x0079, 0x32db, 0x32e0, 0x32de, 0x3385, 0x1078, 0x2bfa,
-+	0x78ec, 0xa084, 0x0001, 0x00c0, 0x32f4, 0x7000, 0xa086, 0x0004,
-+	0x00c0, 0x32ec, 0x0078, 0x332a, 0x1078, 0x3fe8, 0x6008, 0xa084,
-+	0xf9ef, 0x600a, 0x0078, 0x3f81, 0x78e4, 0xa005, 0x00d0, 0x332a,
-+	0x3208, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x3305, 0xa18c, 0x0300, 0x0078, 0x3307, 0xa18c, 0x0400, 0x0040,
-+	0x330d, 0x0018, 0x2c5e, 0x0078, 0x330f, 0x0028, 0x2c5e, 0x2008,
-+	0xa084, 0x0030, 0x00c0, 0x3317, 0x781b, 0x004f, 0x007c, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x3314, 0xa184, 0x0007, 0x0079, 0x3320,
-+	0x3361, 0x336b, 0x3354, 0x3328, 0x44b1, 0x44b1, 0x3328, 0x3378,
-+	0x1078, 0x2bfa, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3344, 0x7068,
-+	0xa086, 0x0002, 0x00c0, 0x333a, 0x2011, 0x0002, 0x2019, 0x0000,
-+	0x0078, 0x31d4, 0x7068, 0xa086, 0x0006, 0x0040, 0x3334, 0x7068,
-+	0xa086, 0x0004, 0x0040, 0x3334, 0x79e4, 0xa184, 0x0030, 0x0040,
-+	0x334e, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x3350, 0x0078, 0x39bf,
-+	0x2001, 0x0003, 0x0078, 0x36cb, 0x6818, 0xd0fc, 0x0040, 0x335a,
-+	0x681b, 0x001d, 0x1078, 0x42bd, 0x782b, 0x3008, 0x781b, 0x0058,
-+	0x007c, 0x6818, 0xd0fc, 0x0040, 0x3367, 0x681b, 0x001d, 0x1078,
-+	0x42bd, 0x0078, 0x4484, 0x6818, 0xd0fc, 0x0040, 0x3371, 0x681b,
-+	0x001d, 0x1078, 0x42bd, 0x782b, 0x3008, 0x781b, 0x00d3, 0x007c,
-+	0x6818, 0xd0fc, 0x0040, 0x337e, 0x681b, 0x001d, 0x1078, 0x42bd,
-+	0x782b, 0x3008, 0x781b, 0x009b, 0x007c, 0xa584, 0x000f, 0x00c0,
-+	0x33a4, 0x1078, 0x2bed, 0x7000, 0x0079, 0x338e, 0x2c6e, 0x3396,
-+	0x3398, 0x3f81, 0x3f81, 0x3f81, 0x3396, 0x3396, 0x1078, 0x2bfa,
-+	0x1078, 0x3fe8, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3f72,
-+	0x0040, 0x3f81, 0x0078, 0x2c6e, 0x78e4, 0xa005, 0x00d0, 0x332a,
-+	0x3208, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x33b5, 0xa18c, 0x0300, 0x0078, 0x33b7, 0xa18c, 0x0400, 0x0040,
-+	0x33bd, 0x0018, 0x332a, 0x0078, 0x33bf, 0x0028, 0x332a, 0x2008,
-+	0xa084, 0x0030, 0x00c0, 0x33c7, 0x781b, 0x004f, 0x007c, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x33c4, 0xa184, 0x0007, 0x0079, 0x33d0,
-+	0x33e1, 0x33e5, 0x33da, 0x33d8, 0x44b1, 0x44b1, 0x33d8, 0x44a9,
-+	0x1078, 0x2bfa, 0x1078, 0x42c5, 0x782b, 0x3008, 0x781b, 0x0058,
-+	0x007c, 0x1078, 0x42c5, 0x0078, 0x4484, 0x1078, 0x42c5, 0x782b,
-+	0x3008, 0x781b, 0x00d3, 0x007c, 0x1078, 0x42c5, 0x782b, 0x3008,
-+	0x781b, 0x009b, 0x007c, 0x2300, 0x0079, 0x33f6, 0x33fb, 0x33f9,
-+	0x33fd, 0x1078, 0x2bfa, 0x0078, 0x3b81, 0x681b, 0x0016, 0x78a3,
-+	0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x3b81, 0x78ec, 0xa084,
-+	0x0003, 0x0040, 0x3b81, 0xa184, 0x0100, 0x0040, 0x3401, 0xa184,
-+	0x0007, 0x0079, 0x3413, 0x341b, 0x33e5, 0x3354, 0x445a, 0x44b1,
-+	0x44b1, 0x445a, 0x44a9, 0x1078, 0x446a, 0x007c, 0xa282, 0x0005,
-+	0x0050, 0x3424, 0x1078, 0x2bfa, 0x2300, 0x0079, 0x3427, 0x342a,
-+	0x367d, 0x368a, 0x2200, 0x0079, 0x342d, 0x3447, 0x3434, 0x3447,
-+	0x3432, 0x3660, 0x1078, 0x2bfa, 0x789b, 0x0018, 0x78a8, 0xa084,
-+	0x00ff, 0xa082, 0x0020, 0x0048, 0x429c, 0xa08a, 0x0004, 0x00c8,
-+	0x429c, 0x0079, 0x3443, 0x429c, 0x429c, 0x429c, 0x4246, 0x789b,
-+	0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x3458, 0x0078, 0x429c,
-+	0x7000, 0xa005, 0x00c0, 0x344e, 0x2011, 0x0004, 0x0078, 0x3d26,
-+	0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x429c, 0x0079, 0x3460,
-+	0x3472, 0x3470, 0x3488, 0x348c, 0x355f, 0x429c, 0x429c, 0x3561,
-+	0x429c, 0x429c, 0x365c, 0x365c, 0x429c, 0x429c, 0x429c, 0x365e,
-+	0x1078, 0x2bfa, 0xa684, 0x1000, 0x0040, 0x347e, 0x2001, 0x0500,
-+	0x8000, 0x8000, 0x783a, 0x781b, 0x0094, 0x007c, 0x6818, 0xd0fc,
-+	0x0040, 0x3486, 0x681b, 0x001d, 0x0078, 0x3476, 0x0078, 0x445a,
-+	0x681b, 0x001d, 0x0078, 0x42aa, 0x6920, 0x6922, 0xa684, 0x1800,
-+	0x00c0, 0x34f1, 0x6820, 0xa084, 0x0001, 0x00c0, 0x34f7, 0x6818,
-+	0xa086, 0x0008, 0x00c0, 0x349e, 0x681b, 0x0000, 0xd6d4, 0x0040,
-+	0x355c, 0xd6bc, 0x0040, 0x34dd, 0x708b, 0x0000, 0x6818, 0xa084,
-+	0x003f, 0xa08a, 0x000d, 0x0050, 0x34dd, 0xa08a, 0x000c, 0x718a,
-+	0x2001, 0x000c, 0x800c, 0x718e, 0x789b, 0x0061, 0x78aa, 0x157e,
-+	0x137e, 0x147e, 0x017e, 0xb28c, 0x0300, 0x0040, 0x34cf, 0x007e,
-+	0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x34cb, 0x20a1,
-+	0x012b, 0x0078, 0x34d1, 0x20a1, 0x022b, 0x0078, 0x34d1, 0x20a1,
-+	0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b,
-+	0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6038, 0xa005, 0x00c0,
-+	0x34ec, 0x681c, 0xa084, 0x000e, 0x0040, 0x42aa, 0x1078, 0x42c9,
-+	0x782b, 0x3008, 0x0078, 0x34ee, 0x8001, 0x603a, 0x781b, 0x005a,
-+	0x007c, 0xd6e4, 0x0040, 0x34f7, 0x781b, 0x0067, 0x007c, 0xa684,
-+	0x0060, 0x0040, 0x3559, 0xd6dc, 0x0040, 0x3559, 0xd6fc, 0x00c0,
-+	0x3503, 0x0078, 0x351a, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8,
-+	0x78d0, 0x801b, 0x00c8, 0x350d, 0x8000, 0xa084, 0x003f, 0xa108,
-+	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0xd6f4, 0x0040, 0x3520, 0xc6f4, 0x7e5a, 0x6eb6,
-+	0x7000, 0xa086, 0x0003, 0x00c0, 0x352e, 0x007e, 0x1078, 0x55ac,
-+	0x1078, 0x591e, 0x007f, 0x781b, 0x0066, 0x007c, 0xa006, 0x1078,
-+	0x5a6b, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040,
-+	0x353d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda,
-+	0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x354d, 0xc6f5,
-+	0x7e5a, 0x6eb6, 0x781b, 0x0066, 0x007c, 0x781b, 0x0066, 0x2200,
-+	0xa115, 0x00c0, 0x3556, 0x1078, 0x591e, 0x007c, 0x1078, 0x5972,
-+	0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x005a, 0x007c, 0x1078,
-+	0x2bfa, 0x0078, 0x35b1, 0x6920, 0xd1c4, 0x0040, 0x3576, 0xc1c4,
-+	0x6922, 0x0c7e, 0x705c, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004,
-+	0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x35a5, 0xd1cc, 0x0040,
-+	0x35a5, 0xc1cc, 0x6922, 0x0c7e, 0x705c, 0x2060, 0x6000, 0xc0ec,
-+	0x6002, 0x6004, 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c,
-+	0x0040, 0x35a5, 0x1078, 0x43a4, 0x1078, 0x40f5, 0x88ff, 0x0040,
-+	0x35a5, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
-+	0xd6d4, 0x00c0, 0x35a0, 0x782b, 0x3008, 0x781b, 0x0058, 0x007c,
-+	0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0x7e58, 0xd6d4, 0x00c0,
-+	0x35ac, 0x781b, 0x005a, 0x007c, 0x781b, 0x0067, 0x007c, 0x0078,
-+	0x42a3, 0xa01e, 0x7990, 0xa18c, 0x0007, 0x00c0, 0x35be, 0x6820,
-+	0xa084, 0x0100, 0x0040, 0x35af, 0x2009, 0x0008, 0x789b, 0x0010,
-+	0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0, 0x35f5, 0x2300,
-+	0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x35ed, 0x0048, 0x35d2,
-+	0x0078, 0x35ef, 0xa380, 0x0002, 0xa102, 0x00c8, 0x35ed, 0x6920,
-+	0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x705c, 0x2060, 0x6000, 0xa084,
-+	0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006, 0x0c7f, 0x7e58,
-+	0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x35a6, 0x0078, 0x3563, 0x24a8,
-+	0x7aa8, 0x00f0, 0x35ef, 0x0078, 0x35c0, 0xa284, 0x00f0, 0xa086,
-+	0x0020, 0x00c0, 0x364d, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040,
-+	0x3605, 0x0048, 0x3605, 0x0078, 0x364a, 0xa286, 0x0023, 0x0040,
-+	0x35af, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1,
-+	0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x705c,
-+	0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x3626,
-+	0x1078, 0x43a4, 0x1078, 0x4201, 0x0078, 0x3634, 0x0c7e, 0x705c,
-+	0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x35a5,
-+	0x1078, 0x43a4, 0x1078, 0x40f5, 0x88ff, 0x0040, 0x35a5, 0x789b,
-+	0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3645,
-+	0x782b, 0x3008, 0x781b, 0x0058, 0x007c, 0x782b, 0x3008, 0x781b,
-+	0x0067, 0x007c, 0x7aa8, 0x0078, 0x35c0, 0x8318, 0x2300, 0xa102,
-+	0x0040, 0x3656, 0x0048, 0x3656, 0x0078, 0x35c0, 0xa284, 0x0080,
-+	0x00c0, 0x42aa, 0x0078, 0x42a3, 0x0078, 0x42aa, 0x0078, 0x429c,
-+	0x705c, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e,
-+	0x0001, 0x0040, 0x366d, 0x1078, 0x2bfa, 0x7aa8, 0xa294, 0x00ff,
-+	0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x429c, 0x0079,
-+	0x3679, 0x429c, 0x4041, 0x429c, 0x41a4, 0xa282, 0x0000, 0x00c0,
-+	0x3683, 0x1078, 0x2bfa, 0x1078, 0x42bd, 0x782b, 0x3008, 0x781b,
-+	0x0067, 0x007c, 0xa282, 0x0003, 0x00c0, 0x3690, 0x1078, 0x2bfa,
-+	0xd4fc, 0x00c0, 0x36b0, 0x7068, 0xa005, 0x0040, 0x3699, 0x1078,
-+	0x2bfa, 0x6f14, 0x777a, 0xa7bc, 0x8f00, 0x1078, 0x43a8, 0x6008,
-+	0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0, 0x369d,
-+	0x1078, 0x42c1, 0x706b, 0x0002, 0x701b, 0x0009, 0x0078, 0x36b2,
-+	0x1078, 0x42cd, 0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0xa282,
-+	0x0004, 0x0050, 0x36bd, 0x1078, 0x2bfa, 0x2300, 0x0079, 0x36c0,
-+	0x36c3, 0x37f4, 0x3825, 0xa286, 0x0003, 0x0040, 0x36c9, 0x1078,
-+	0x2bfa, 0x2001, 0x0000, 0x7046, 0x68d0, 0xa005, 0x0040, 0x36d2,
-+	0x7003, 0x0003, 0x68a0, 0xd0ec, 0x0040, 0x36d9, 0x6008, 0xc08d,
-+	0x600a, 0x7000, 0xa084, 0x000f, 0x0079, 0x36de, 0x2c6e, 0x36eb,
-+	0x36e8, 0x390e, 0x39a6, 0x2c6e, 0x36e6, 0x36e6, 0x1078, 0x2bfa,
-+	0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x00c0, 0x36f4, 0x1078, 0x55ac,
-+	0x2009, 0x0000, 0x0078, 0x379c, 0x7868, 0xa08c, 0x00ff, 0x0040,
-+	0x3733, 0xa186, 0x0008, 0x00c0, 0x370a, 0x6008, 0xc0a4, 0x600a,
-+	0x1078, 0x3f72, 0x0040, 0x3733, 0x1078, 0x3fe8, 0x1078, 0x55ac,
-+	0x0078, 0x371b, 0xa186, 0x0028, 0x00c0, 0x3733, 0x6018, 0xa005,
-+	0x0040, 0x36fd, 0x8001, 0x0040, 0x36fd, 0x8001, 0x0040, 0x36fd,
-+	0x601e, 0x0078, 0x36fd, 0x6820, 0xd084, 0x0040, 0x2c6e, 0xc084,
-+	0x6822, 0x1078, 0x2d8b, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002,
-+	0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x3730, 0x6002,
-+	0x6006, 0x0078, 0x2c6e, 0x017e, 0x81ff, 0x00c0, 0x3755, 0x71f0,
-+	0xd1bc, 0x00c0, 0x3755, 0xd1b4, 0x0040, 0x3755, 0x1078, 0x44bc,
-+	0x00c0, 0x3755, 0x0d7e, 0x70d8, 0xa06d, 0x6814, 0xc0fc, 0x8007,
-+	0x7882, 0x68b4, 0x785a, 0x781b, 0x004f, 0x704c, 0xc08d, 0x780a,
-+	0xc1b4, 0x71f2, 0x7003, 0x0030, 0x0d7f, 0x1078, 0x383b, 0x017f,
-+	0x81ff, 0x0040, 0x379c, 0xa684, 0x5f00, 0x681e, 0x682b, 0x0000,
-+	0x6f14, 0xa186, 0x0002, 0x00c0, 0x379d, 0x1078, 0x2d79, 0x1078,
-+	0x2d9a, 0x6820, 0xa084, 0x0800, 0x00c0, 0x379d, 0x8717, 0xa294,
-+	0x000f, 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x377c,
-+	0xa290, 0x64c0, 0x0078, 0x377e, 0xa290, 0x6540, 0xa290, 0x0000,
-+	0x221c, 0xd3c4, 0x00c0, 0x3786, 0x0078, 0x378c, 0x8210, 0x2204,
-+	0xa085, 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x3797, 0x68a0,
-+	0xd0c4, 0x00c0, 0x3797, 0x1078, 0x38bd, 0x0078, 0x2c6e, 0x6008,
-+	0xc08d, 0x600a, 0x0078, 0x379d, 0x692a, 0x6916, 0x6818, 0xd0fc,
-+	0x0040, 0x37a4, 0x7044, 0x681a, 0xa68c, 0x5f00, 0x691e, 0x6010,
-+	0xa005, 0x0040, 0x37b0, 0x8001, 0x00d0, 0x37b0, 0x1078, 0x2bfa,
-+	0x6012, 0x6018, 0xa005, 0x0040, 0x37b9, 0x8001, 0x601a, 0x00c0,
-+	0x37bc, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x37c8,
-+	0x6800, 0xa005, 0x00c0, 0x37c5, 0x6002, 0x6006, 0x0078, 0x37cc,
-+	0x7060, 0x2060, 0x6800, 0x6002, 0x2061, 0x6000, 0x6807, 0x0103,
-+	0x2d08, 0x206b, 0x0000, 0x6060, 0x8000, 0x6062, 0x6064, 0xa005,
-+	0x6166, 0x0040, 0x37de, 0x2d02, 0x0078, 0x37df, 0x616a, 0x7000,
-+	0xa086, 0x0030, 0x00c0, 0x2c6e, 0x7003, 0x0002, 0x70d8, 0xa06d,
-+	0x68c0, 0x703e, 0x70d4, 0xa065, 0x68c4, 0x705e, 0x2d00, 0x7052,
-+	0xad80, 0x0009, 0x7042, 0x007c, 0xa282, 0x0004, 0x0048, 0x37fa,
-+	0x1078, 0x2bfa, 0x2200, 0x0079, 0x37fd, 0x37f8, 0x3801, 0x380d,
-+	0x3801, 0x7000, 0xa086, 0x0005, 0x0040, 0x380a, 0x1078, 0x42bd,
-+	0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0x7890, 0x8007, 0x8001,
-+	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-+	0xa186, 0x0003, 0x0040, 0x3822, 0xa186, 0x0000, 0x0040, 0x3822,
-+	0x0078, 0x429c, 0x781b, 0x0067, 0x007c, 0x6820, 0xc095, 0x6822,
-+	0x82ff, 0x00c0, 0x382f, 0x1078, 0x42bd, 0x0078, 0x3836, 0x8211,
-+	0x0040, 0x3834, 0x1078, 0x2bfa, 0x1078, 0x42cd, 0x782b, 0x3008,
-+	0x781b, 0x0067, 0x007c, 0xa684, 0x0060, 0x00c0, 0x3849, 0x2d00,
-+	0xa005, 0x0040, 0x38bc, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-+	0x38bc, 0xd6dc, 0x00c0, 0x3861, 0x68b4, 0xd0dc, 0x00c0, 0x3861,
-+	0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005, 0x00c0, 0x385e,
-+	0x2200, 0xa105, 0x0040, 0x3860, 0x7047, 0x0015, 0x0078, 0x55ac,
-+	0x007c, 0xd6ac, 0x0040, 0x388b, 0xd6f4, 0x0040, 0x386d, 0x682f,
-+	0x0000, 0x6833, 0x0000, 0x0078, 0x55ac, 0x68b4, 0xa084, 0x4000,
-+	0xa635, 0xd6f4, 0x00c0, 0x3867, 0x7044, 0xa005, 0x00c0, 0x387a,
-+	0x7047, 0x0015, 0xd6dc, 0x00c0, 0x3885, 0x68b4, 0xd0dc, 0x0040,
-+	0x3885, 0x69a8, 0x6aa4, 0x0078, 0x3887, 0x79d8, 0x7adc, 0x692e,
-+	0x6a32, 0x0078, 0x55ac, 0xd6f4, 0x0040, 0x3894, 0x682f, 0x0000,
-+	0x6833, 0x0000, 0x0078, 0x55ac, 0x68b4, 0xa084, 0x4800, 0xa635,
-+	0xd6f4, 0x00c0, 0x388e, 0x7044, 0xa005, 0x00c0, 0x38a1, 0x7047,
-+	0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8, 0x38a8, 0x8000,
-+	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100,
-+	0xa205, 0x00c0, 0x38b5, 0x0078, 0x55ac, 0x7000, 0xa086, 0x0006,
-+	0x0040, 0x38bc, 0x0078, 0x55ac, 0x007c, 0x6008, 0xc0cd, 0xd3cc,
-+	0x0040, 0x38c3, 0xc08d, 0x600a, 0x6818, 0x68ba, 0x681b, 0x0006,
-+	0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942,
-+	0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000,
-+	0x689b, 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079,
-+	0x38e1, 0x2c6e, 0x38f3, 0x38eb, 0x38e9, 0x38e9, 0x38e9, 0x38e9,
-+	0x38e9, 0x1078, 0x2bfa, 0x6820, 0xd084, 0x00c0, 0x38f3, 0x1078,
-+	0x3fd3, 0x0078, 0x38f9, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002,
-+	0x2a60, 0xb28c, 0x0300, 0x0040, 0x3901, 0x2021, 0x6059, 0x0078,
-+	0x3903, 0x2021, 0x6099, 0x2404, 0xa005, 0x0040, 0x390a, 0x2020,
-+	0x0078, 0x3903, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x3fda,
-+	0x1078, 0x3fe8, 0x6008, 0xc0cc, 0x600a, 0x789b, 0x000e, 0x6f14,
-+	0x6817, 0x0002, 0xb28c, 0x0300, 0x0040, 0x3922, 0x2009, 0x0000,
-+	0x0078, 0x3924, 0x2009, 0x0001, 0x1078, 0x5ab0, 0xd6dc, 0x0040,
-+	0x392c, 0x691c, 0xc1ed, 0x691e, 0x68b8, 0xd0fc, 0x00c0, 0x3933,
-+	0x681a, 0x0078, 0x3942, 0x6818, 0xd0fc, 0x0040, 0x3942, 0x7868,
-+	0xa08c, 0x00ff, 0x0040, 0x3940, 0x681b, 0x001e, 0x0078, 0x3942,
-+	0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x394a, 0x2021, 0x6099,
-+	0x0078, 0x394c, 0x2021, 0x6059, 0x2404, 0xad06, 0x0040, 0x3951,
-+	0x7460, 0x6800, 0x2022, 0x68d3, 0x0000, 0x70f4, 0xc084, 0x70f6,
-+	0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c4, 0x2060, 0x6000, 0xd0a4,
-+	0x0040, 0x3996, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020,
-+	0x0d7e, 0x0f7e, 0x157e, 0x147e, 0x2079, 0x6000, 0x1078, 0x1e83,
-+	0x147f, 0x157f, 0x0f7f, 0x70e8, 0x2010, 0x2009, 0x0101, 0x027e,
-+	0x2204, 0xa06d, 0x0040, 0x3986, 0x6814, 0xa706, 0x0040, 0x3983,
-+	0x6800, 0x0078, 0x3979, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210,
-+	0x8109, 0x00c0, 0x3977, 0x0d7f, 0x706b, 0x0003, 0x7083, 0x0000,
-+	0x777a, 0x7087, 0x000f, 0x71f0, 0xc1dc, 0x71f2, 0x6818, 0xa086,
-+	0x0002, 0x00c0, 0x39a2, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c,
-+	0xc0ec, 0x681e, 0x1078, 0x2251, 0x0078, 0x2c6e, 0x1078, 0x383b,
-+	0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x44ff, 0xa08c,
-+	0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x39b8, 0x7044, 0x681a,
-+	0xa68c, 0x5f00, 0x691e, 0x706b, 0x0000, 0x0078, 0x2c6e, 0x7000,
-+	0xa005, 0x00c0, 0x39c5, 0x0078, 0x2c6e, 0xa006, 0x1078, 0x55ac,
-+	0x6817, 0x0000, 0x6920, 0xd1ac, 0x00c0, 0x39d0, 0x681b, 0x0014,
-+	0xa68c, 0x5f00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
-+	0x6822, 0x7000, 0x0079, 0x39dc, 0x2c6e, 0x39e9, 0x39e6, 0x39eb,
-+	0x39eb, 0x39eb, 0x39e4, 0x39e4, 0x1078, 0x2bfa, 0x6008, 0xc0d4,
-+	0x600a, 0x1078, 0x3fe8, 0x6008, 0xc0a4, 0x600a, 0x0078, 0x3f98,
-+	0x2300, 0x0079, 0x39f3, 0x39f6, 0x39f8, 0x3a6d, 0x1078, 0x2bfa,
-+	0xd6fc, 0x00c0, 0x3a53, 0x7000, 0xa00d, 0x0079, 0x39ff, 0x2c6e,
-+	0x3a0f, 0x3a09, 0x3a3f, 0x3a0f, 0x3a4a, 0x3a07, 0x3a07, 0x1078,
-+	0x2bfa, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684,
-+	0x0060, 0x0040, 0x3a3f, 0xa086, 0x0060, 0x00c0, 0x3a3c, 0xc6ac,
-+	0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e, 0xa186,
-+	0x0002, 0x0040, 0x3a2e, 0x1078, 0x55ac, 0x69ac, 0x68b0, 0xa115,
-+	0x0040, 0x3a2e, 0x1078, 0x5972, 0x0078, 0x3a30, 0x1078, 0x591e,
-+	0x781b, 0x0067, 0x71f0, 0xd1b4, 0x00c0, 0x2c5e, 0x70c0, 0xa086,
-+	0x0001, 0x00c0, 0x2cc7, 0x007c, 0xd6ec, 0x0040, 0x3a19, 0x6818,
-+	0xd0fc, 0x0040, 0x3a4a, 0x681b, 0x0015, 0xd6f4, 0x0040, 0x3a4a,
-+	0x681b, 0x0007, 0x1078, 0x446a, 0x007c, 0x78cb, 0x0000, 0x781b,
-+	0x00cf, 0x0078, 0x2c5e, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x78d0,
-+	0x79d2, 0x801b, 0x00c8, 0x3a5d, 0x8000, 0xa084, 0x003f, 0xa108,
-+	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0x781b, 0x0067, 0x007c, 0x1078, 0x2bfa, 0x2300,
-+	0x0079, 0x3a72, 0x3a75, 0x3a77, 0x3ad7, 0x1078, 0x2bfa, 0xd6fc,
-+	0x00c0, 0x3ac7, 0x7000, 0xa00d, 0x0079, 0x3a7e, 0x2c6e, 0x3a8e,
-+	0x3a88, 0x3abe, 0x3a8e, 0x3ac4, 0x3a86, 0x3a86, 0x1078, 0x2bfa,
-+	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060,
-+	0x0040, 0x3abe, 0xa086, 0x0060, 0x00c0, 0x3abb, 0xa6b4, 0xbfbf,
-+	0xc6ed, 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x3aaa, 0x1078,
-+	0x55ac, 0x69ac, 0x68b0, 0xa115, 0x0040, 0x3aaa, 0x1078, 0x5972,
-+	0x0078, 0x3aac, 0x1078, 0x591e, 0x781b, 0x0067, 0x681c, 0xc0b4,
-+	0x681e, 0x71f0, 0xd1b4, 0x00c0, 0x2c5e, 0x70c0, 0xa086, 0x0001,
-+	0x00c0, 0x2cc7, 0x007c, 0xd6ec, 0x0040, 0x3a98, 0x6818, 0xd0fc,
-+	0x0040, 0x3ac4, 0x681b, 0x0007, 0x781b, 0x00d3, 0x007c, 0xc6fc,
-+	0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
-+	0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0067, 0x007c, 0xd6dc,
-+	0x0040, 0x3ae0, 0x782b, 0x3009, 0x781b, 0x0067, 0x0078, 0x2c5e,
-+	0x6820, 0xc095, 0x6822, 0x1078, 0x4450, 0xc6dd, 0x1078, 0x42bd,
-+	0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0x2300, 0x0079, 0x3af0,
-+	0x3af3, 0x3af5, 0x3af7, 0x1078, 0x2bfa, 0x0078, 0x42aa, 0x7d98,
-+	0xd6d4, 0x00c0, 0x3b34, 0x79e4, 0xd1ac, 0x0040, 0x3b06, 0x78ec,
-+	0xa084, 0x0003, 0x0040, 0x3b06, 0x782b, 0x3009, 0x789b, 0x0060,
-+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac,
-+	0x0040, 0x3b17, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x3b30, 0x2001,
-+	0x6002, 0x2004, 0xd0e4, 0x00c0, 0x3b2c, 0x6820, 0xd0c4, 0x0040,
-+	0x3b2c, 0x0c7e, 0x705c, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008,
-+	0xa084, 0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x36cb,
-+	0xa184, 0x0007, 0x0079, 0x3b6b, 0x7a90, 0xa294, 0x0007, 0x789b,
-+	0x0060, 0x79a8, 0x81ff, 0x0040, 0x3b68, 0x789b, 0x0010, 0x7ba8,
-+	0xa384, 0x0001, 0x00c0, 0x3b5b, 0x7ba8, 0x7ba8, 0xa386, 0x0001,
-+	0x00c0, 0x3b4e, 0x2009, 0xfff7, 0x0078, 0x3b54, 0xa386, 0x0003,
-+	0x00c0, 0x3b5b, 0x2009, 0xffef, 0x0c7e, 0x705c, 0x2060, 0x6004,
-+	0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
-+	0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922,
-+	0x7d9a, 0x0078, 0x445a, 0x3361, 0x336b, 0x3b75, 0x3b7b, 0x3b73,
-+	0x3b73, 0x445a, 0x445a, 0x1078, 0x2bfa, 0x6920, 0xa18c, 0xfcff,
-+	0x6922, 0x0078, 0x4462, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
-+	0x445a, 0x79e4, 0xa184, 0x0030, 0x0040, 0x3b8b, 0x78ec, 0xa084,
-+	0x0003, 0x00c0, 0x3bb9, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3ba5,
-+	0x7068, 0xa086, 0x0002, 0x00c0, 0x3b9b, 0x2011, 0x0002, 0x2019,
-+	0x0000, 0x0078, 0x31d4, 0x7068, 0xa086, 0x0006, 0x0040, 0x3b95,
-+	0x7068, 0xa086, 0x0004, 0x0040, 0x3b95, 0x7000, 0xa086, 0x0000,
-+	0x0040, 0x2c5e, 0x6820, 0xd0ac, 0x00c0, 0x36cb, 0x6818, 0xa08e,
-+	0x0002, 0x0040, 0x3bb7, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078,
-+	0x36cb, 0xa184, 0x0007, 0x0079, 0x3bbd, 0x445a, 0x445a, 0x3bc5,
-+	0x445a, 0x44b1, 0x44b1, 0x445a, 0x445a, 0xd6bc, 0x0040, 0x3c09,
-+	0x7188, 0x81ff, 0x0040, 0x3c09, 0xa182, 0x000d, 0x00d0, 0x3bd4,
-+	0x708b, 0x0000, 0x0078, 0x3bd9, 0xa182, 0x000c, 0x708a, 0x2009,
-+	0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x708c,
-+	0x8114, 0xa210, 0x728e, 0xa080, 0x000b, 0xad00, 0x2098, 0x017e,
-+	0xb28c, 0x0300, 0x0040, 0x3bfc, 0x007e, 0x2001, 0x6002, 0x2004,
-+	0xd0ec, 0x007f, 0x0040, 0x3bf8, 0x20a1, 0x012b, 0x0078, 0x3bfe,
-+	0x20a1, 0x022b, 0x0078, 0x3bfe, 0x20a1, 0x012b, 0x017f, 0x789b,
-+	0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078,
-+	0x4462, 0xd6d4, 0x00c0, 0x3c5c, 0x6820, 0xd084, 0x0040, 0x4462,
-+	0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x3c1b, 0xa086, 0x0060,
-+	0x00c0, 0x3c1b, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060,
-+	0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa,
-+	0x8008, 0x810c, 0x0040, 0x4001, 0xa18c, 0x00f8, 0x00c0, 0x4001,
-+	0x157e, 0x137e, 0x147e, 0x017e, 0xb28c, 0x0300, 0x0040, 0x3c48,
-+	0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3c44,
-+	0x20a1, 0x012b, 0x0078, 0x3c4a, 0x20a1, 0x022b, 0x0078, 0x3c4a,
-+	0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-+	0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0xc0fc,
-+	0x8007, 0x7882, 0x0078, 0x4462, 0x6818, 0xd0fc, 0x0040, 0x3c62,
-+	0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822, 0x1078, 0x42c5, 0x78cb,
-+	0x0000, 0x781b, 0x00cb, 0x007c, 0x2300, 0x0079, 0x3c6f, 0x3c74,
-+	0x3d11, 0x3c72, 0x1078, 0x2bfa, 0x7000, 0xa084, 0x000f, 0x0079,
-+	0x3c79, 0x2c6e, 0x3cc1, 0x3c83, 0x3c8c, 0x3c81, 0x2c6e, 0x3c81,
-+	0x3c81, 0x1078, 0x2bfa, 0x681c, 0xd0ec, 0x0040, 0x3c9d, 0x6008,
-+	0xc08d, 0x600a, 0x0078, 0x3c9d, 0x68d0, 0xa005, 0x00c0, 0x3cc1,
-+	0x6920, 0xa18d, 0x0001, 0x6922, 0x68d3, 0x0001, 0x70f4, 0xc085,
-+	0x70f6, 0x6800, 0x7066, 0x0078, 0x3cae, 0x6920, 0xc185, 0x6922,
-+	0x6800, 0x6006, 0xa005, 0x00c0, 0x3ca6, 0x6002, 0x6008, 0xc0d4,
-+	0x600a, 0x681c, 0xa084, 0x000e, 0x00c0, 0x3cb8, 0x2009, 0xa7d0,
-+	0xb284, 0x0300, 0x0040, 0x3cbd, 0x2009, 0xa6c0, 0x0078, 0x3cbd,
-+	0x702c, 0x68be, 0x713c, 0x70e8, 0xa108, 0x2104, 0x6802, 0x2d0a,
-+	0x7162, 0x6eb6, 0xa684, 0x0060, 0x00c0, 0x3ccb, 0xa684, 0x7fff,
-+	0x68b6, 0x0078, 0x3d0f, 0xd6dc, 0x00c0, 0x3cd9, 0xa684, 0x7fff,
-+	0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x55ac, 0x0078,
-+	0x3d0f, 0xd6ac, 0x0040, 0x3cec, 0x68d0, 0xa005, 0x0040, 0x3ce4,
-+	0x1078, 0x5ab0, 0x0078, 0x3ce6, 0x1078, 0x55ac, 0x79d8, 0x7adc,
-+	0x69aa, 0x6aa6, 0x0078, 0x3cf2, 0x1078, 0x43bc, 0x69aa, 0x6aa6,
-+	0x1078, 0x55ac, 0xd6fc, 0x0040, 0x3d0f, 0xa684, 0x7fff, 0x68b6,
-+	0x7adc, 0x79d8, 0xd6ac, 0x00c0, 0x3d07, 0x78d0, 0x801b, 0x00c8,
-+	0x3d02, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98,
-+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078,
-+	0x2c6e, 0x0078, 0x42aa, 0x7043, 0x0000, 0xa282, 0x0006, 0x0050,
-+	0x3d1b, 0x1078, 0x2bfa, 0x7000, 0xa086, 0x0007, 0x1040, 0x45de,
-+	0x2300, 0x0079, 0x3d23, 0x3d26, 0x3d5d, 0x3d7e, 0x2200, 0x0079,
-+	0x3d29, 0x3d5b, 0x42aa, 0x3d2f, 0x3d5b, 0x3da1, 0x3e14, 0x7003,
-+	0x0005, 0xb284, 0x0300, 0x0040, 0x3d39, 0x2001, 0xaa20, 0x0078,
-+	0x3d3b, 0x2001, 0xaa57, 0x2068, 0x7052, 0x157e, 0x20a9, 0x0037,
-+	0x2003, 0x0000, 0x8000, 0x00f0, 0x3d40, 0x157f, 0xad80, 0x0009,
-+	0x7042, 0xb284, 0x0300, 0x0040, 0x3d51, 0x6817, 0x0000, 0x0078,
-+	0x3d53, 0x6817, 0x8000, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
-+	0x0003, 0x0078, 0x429c, 0x1078, 0x2bfa, 0x2200, 0xa086, 0x0003,
-+	0x0040, 0x3da1, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3d6c,
-+	0x2001, 0xaa20, 0x0078, 0x3d6e, 0x2001, 0xaa57, 0x2068, 0x7052,
-+	0xad80, 0x0009, 0x7042, 0x2200, 0x0079, 0x3d76, 0x42aa, 0x3d7c,
-+	0x3d7c, 0x3da1, 0x3d7c, 0x42aa, 0x1078, 0x2bfa, 0x7003, 0x0005,
-+	0xb284, 0x0300, 0x0040, 0x3d88, 0x2001, 0xaa20, 0x0078, 0x3d8a,
-+	0x2001, 0xaa57, 0x2068, 0x7052, 0xad80, 0x0009, 0x7042, 0x2200,
-+	0x0079, 0x3d92, 0x3d9a, 0x3d98, 0x3d98, 0x3d9a, 0x3d98, 0x3d9a,
-+	0x1078, 0x2bfa, 0x1078, 0x42cd, 0x782b, 0x3008, 0x781b, 0x0067,
-+	0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3db3, 0x70f0, 0xc0b5,
-+	0x70f2, 0x2c00, 0x70d6, 0x2d00, 0x70da, 0x0078, 0x3db8, 0x1078,
-+	0x55ac, 0x0078, 0x3db8, 0x7000, 0xa086, 0x0003, 0x0040, 0x3daf,
-+	0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-+	0xa484, 0x001f, 0xa215, 0x2069, 0xa6c0, 0xb284, 0x0300, 0x00c0,
-+	0x3dcc, 0xc2fd, 0x2069, 0xa7d0, 0x2d04, 0x2d08, 0x7162, 0xa06d,
-+	0x0040, 0x3dd9, 0x6814, 0xa206, 0x0040, 0x3df9, 0x6800, 0x0078,
-+	0x3dcd, 0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3de2, 0x2001, 0xaa20,
-+	0x0078, 0x3de4, 0x2001, 0xaa57, 0x2068, 0x7052, 0x157e, 0x20a9,
-+	0x0037, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3de9, 0x157f, 0xad80,
-+	0x0009, 0x7042, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
-+	0x0003, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0040, 0x3e9e,
-+	0x7068, 0xa086, 0x0006, 0x00c0, 0x3e0b, 0x7078, 0xa206, 0x00c0,
-+	0x3e0b, 0x706a, 0x7082, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922,
-+	0x1078, 0x42c5, 0x0078, 0x3e9e, 0x7200, 0xa286, 0x0002, 0x00c0,
-+	0x3e26, 0x70f0, 0xc0b5, 0x70f2, 0x2c00, 0x70d6, 0x2d00, 0x70da,
-+	0x0078, 0x3e2a, 0x1078, 0x55ac, 0x0078, 0x3e2a, 0xa286, 0x0003,
-+	0x0040, 0x3e22, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b,
-+	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0,
-+	0x3e3a, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70e8,
-+	0xa168, 0x2d04, 0x2d08, 0x7162, 0xa06d, 0x0040, 0x3e4e, 0x6814,
-+	0xa206, 0x0040, 0x3e77, 0x6800, 0x0078, 0x3e42, 0x7003, 0x0005,
-+	0xb284, 0x0300, 0x0040, 0x3e58, 0x2001, 0xaa20, 0x0078, 0x3e5a,
-+	0x2001, 0xaa57, 0x2068, 0x7052, 0x157e, 0x20a9, 0x0037, 0x2003,
-+	0x0000, 0x8000, 0x00f0, 0x3e5f, 0x157f, 0xad80, 0x0009, 0x7042,
-+	0xb284, 0x0300, 0x0040, 0x3e6f, 0xc2fc, 0x0078, 0x3e70, 0xc2fd,
-+	0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4,
-+	0x6920, 0xa184, 0x0c00, 0x0040, 0x3e9e, 0xd0dc, 0x0040, 0x3e93,
-+	0x7068, 0xa086, 0x0004, 0x00c0, 0x3e8f, 0x7078, 0xa206, 0x00c0,
-+	0x3e8f, 0x707c, 0xa306, 0x00c0, 0x3e8f, 0x706a, 0x7082, 0x1078,
-+	0x42c9, 0x0078, 0x3e9e, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922,
-+	0x1078, 0x42c5, 0x7083, 0x0000, 0x0078, 0x3e9e, 0x68c4, 0x705e,
-+	0xc6ec, 0xa684, 0x0060, 0x0040, 0x3ee9, 0x6b98, 0x6c94, 0x69ac,
-+	0x68b0, 0xa105, 0x00c0, 0x3ecb, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde,
-+	0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3eef, 0x68d0, 0xa005,
-+	0x0040, 0x3ec3, 0x7003, 0x0003, 0x682b, 0x0000, 0xc6ed, 0x1078,
-+	0x590b, 0x0078, 0x3eef, 0xd6f4, 0x00c0, 0x3eef, 0xc6ed, 0x1078,
-+	0x591e, 0x0078, 0x3eef, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400,
-+	0xa305, 0x0040, 0x3ef1, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68d0,
-+	0xa005, 0x0040, 0x3ee1, 0x7003, 0x0003, 0x1078, 0x590b, 0x0078,
-+	0x3ef1, 0xd6f4, 0x00c0, 0x3ee8, 0xc6ed, 0x68b0, 0x1078, 0x5972,
-+	0xc6f4, 0x2019, 0x0000, 0x2021, 0x0000, 0x0078, 0x3ef1, 0xa6b4,
-+	0xb7ff, 0x7e5a, 0x2009, 0x0067, 0xa684, 0x0004, 0x0040, 0x3f11,
-+	0x78e4, 0xa084, 0x0030, 0x0040, 0x3f09, 0x78ec, 0xa084, 0x0003,
-+	0x0040, 0x3f09, 0x782b, 0x3008, 0x2019, 0x0000, 0x2320, 0x0078,
-+	0x3f11, 0x0f7e, 0x2079, 0x6000, 0x1078, 0x55ac, 0x0f7f, 0x0040,
-+	0x2c6e, 0x791a, 0x2d00, 0x7052, 0x68c8, 0x2060, 0x71f0, 0x2001,
-+	0x6001, 0x2004, 0xd0c4, 0x00c0, 0x3f65, 0x70f8, 0xa02d, 0x0040,
-+	0x3f3e, 0xd1bc, 0x0040, 0x3f58, 0x7a80, 0xa294, 0x0f00, 0x70fc,
-+	0xa206, 0x0040, 0x3f2f, 0x78e0, 0xa504, 0x00c0, 0x3f65, 0x70fa,
-+	0xc1bc, 0x71f2, 0x0078, 0x3f65, 0x2031, 0x0001, 0x852c, 0x0048,
-+	0x3f3d, 0x8633, 0x8210, 0x0078, 0x3f36, 0x007c, 0x7de0, 0xa594,
-+	0xff00, 0x0040, 0x3f4b, 0x2011, 0x0008, 0x852f, 0x1078, 0x3f34,
-+	0x8637, 0x0078, 0x3f4d, 0x1078, 0x3f34, 0x8217, 0x7880, 0xa084,
-+	0x0f00, 0xa206, 0x0040, 0x3f65, 0x72fe, 0x76fa, 0x0078, 0x3f65,
-+	0x7a80, 0xa294, 0x0f00, 0x70fc, 0xa236, 0x0040, 0x3f55, 0x78e0,
-+	0xa534, 0x0040, 0x3f55, 0xc1bd, 0x71f2, 0xd1b4, 0x00c0, 0x2c5e,
-+	0x2300, 0xa405, 0x0040, 0x2c5e, 0x70c0, 0xa086, 0x0001, 0x00c0,
-+	0x2cc7, 0x007c, 0x6020, 0xa005, 0x0040, 0x3f80, 0x8001, 0x6022,
-+	0x6008, 0xa085, 0x0008, 0x600a, 0x700b, 0x0100, 0x7028, 0x6026,
-+	0x007c, 0xa006, 0x1078, 0x55ac, 0x7000, 0xa086, 0x0002, 0x0040,
-+	0x3f8e, 0x7068, 0xa086, 0x0005, 0x00c0, 0x3f98, 0x682b, 0x0000,
-+	0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100,
-+	0x7000, 0xa084, 0x000f, 0x0079, 0x3f9d, 0x2c6e, 0x3fad, 0x3fa7,
-+	0x3fcf, 0x3fb7, 0x3fb5, 0x3fa5, 0x3fa5, 0x1078, 0x2bfa, 0x1078,
-+	0x3fda, 0x1078, 0x3fd3, 0x0078, 0x3fb3, 0x1078, 0x3fda, 0x7060,
-+	0x2060, 0x6800, 0x6002, 0x1078, 0x2251, 0x0078, 0x2c6e, 0x7068,
-+	0x706b, 0x0000, 0x7087, 0x0000, 0x0079, 0x3fbe, 0x3fcb, 0x3fcb,
-+	0x3fc6, 0x3fc6, 0x3fc6, 0x3fcb, 0x3fc6, 0x3fcb, 0x77f0, 0xc7dd,
-+	0x77f2, 0x0079, 0x31ef, 0x706b, 0x0000, 0x0078, 0x2c6e, 0x681b,
-+	0x0000, 0x0078, 0x390e, 0x6800, 0xa005, 0x00c0, 0x3fd8, 0x6002,
-+	0x6006, 0x007c, 0x6010, 0xa005, 0x0040, 0x3fe3, 0x8001, 0x00d0,
-+	0x3fe3, 0x1078, 0x2bfa, 0x6012, 0x6008, 0xc0a4, 0x600a, 0x007c,
-+	0x6018, 0xa005, 0x0040, 0x3fee, 0x8001, 0x601a, 0x007c, 0x1078,
-+	0x44fa, 0x681b, 0x0018, 0x0078, 0x402d, 0x1078, 0x44fa, 0x681b,
-+	0x0019, 0x0078, 0x402d, 0x1078, 0x44fa, 0x681b, 0x001a, 0x0078,
-+	0x402d, 0x1078, 0x44fa, 0x681b, 0x0003, 0x0078, 0x402d, 0x7778,
-+	0x1078, 0x43a8, 0x717c, 0xa18c, 0x00ff, 0xd7fc, 0x00c0, 0x4014,
-+	0xa1e8, 0xa5c0, 0x0078, 0x4016, 0xa1e8, 0xa6d0, 0x2d04, 0x2d08,
-+	0x2068, 0xa005, 0x00c0, 0x401f, 0x7082, 0x0078, 0x2c6e, 0x6814,
-+	0x7278, 0xa206, 0x0040, 0x4027, 0x6800, 0x0078, 0x4017, 0x6800,
-+	0x200a, 0x681b, 0x0005, 0x7083, 0x0000, 0x1078, 0x3fda, 0x6820,
-+	0xd084, 0x00c0, 0x4035, 0x1078, 0x3fd3, 0x1078, 0x3fe8, 0x681f,
-+	0x0000, 0x6823, 0x0020, 0x682b, 0x0000, 0x1078, 0x2251, 0x0078,
-+	0x2c6e, 0xa282, 0x0003, 0x00c0, 0x429c, 0x7da8, 0xa5ac, 0x00ff,
-+	0x7ca8, 0xa4a4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040,
-+	0x409f, 0xc1c4, 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x408c, 0xa482,
-+	0x000c, 0x0048, 0x405f, 0x0040, 0x405f, 0x2021, 0x000c, 0x2500,
-+	0xa086, 0x000a, 0x0040, 0x4066, 0x852b, 0x852b, 0x1078, 0x4334,
-+	0x0040, 0x406e, 0x1078, 0x4162, 0x0078, 0x4095, 0x1078, 0x4320,
-+	0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x418d,
-+	0x0c7f, 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4,
-+	0x00c0, 0x4087, 0x782b, 0x3008, 0x781b, 0x0058, 0x007c, 0x782b,
-+	0x3008, 0x781b, 0x0067, 0x007c, 0x0c7e, 0x2960, 0x6004, 0xa084,
-+	0xfff5, 0x6006, 0x1078, 0x418d, 0x0c7f, 0x7e58, 0xd6d4, 0x00c0,
-+	0x409c, 0x781b, 0x005a, 0x007c, 0x781b, 0x0067, 0x007c, 0x0c7e,
-+	0x705c, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x40e8, 0x6208, 0x8217,
-+	0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x40b2, 0x0040, 0x40b2,
-+	0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x40b7, 0x2220, 0x6208,
-+	0xa294, 0x00ff, 0x2001, 0x6003, 0x2004, 0xd0e4, 0x00c0, 0x40cc,
-+	0x78ec, 0xd0e4, 0x0040, 0x40cc, 0xa282, 0x000a, 0x00c8, 0x40d2,
-+	0x2011, 0x000a, 0x0078, 0x40d2, 0xa282, 0x000c, 0x00c8, 0x40d2,
-+	0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x40d7, 0x2228, 0x1078,
-+	0x4324, 0x2500, 0xa086, 0x000a, 0x0040, 0x40e0, 0x852b, 0x852b,
-+	0x1078, 0x4334, 0x0040, 0x40e8, 0x1078, 0x4162, 0x0078, 0x40ec,
-+	0x1078, 0x4320, 0x1078, 0x418d, 0x7858, 0xc095, 0x785a, 0x0c7f,
-+	0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0x0c7e, 0x2960, 0x6000,
-+	0xd0e4, 0x00c0, 0x410b, 0xa084, 0x0040, 0x00c0, 0x4105, 0x6104,
-+	0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019,
-+	0x0000, 0x0078, 0x4136, 0x68a0, 0xd0cc, 0x00c0, 0x4105, 0x6208,
-+	0xa294, 0x00ff, 0x2001, 0x6003, 0x2004, 0xd0e4, 0x00c0, 0x4124,
-+	0x78ec, 0xd0e4, 0x0040, 0x4124, 0xa282, 0x000b, 0x00c8, 0x4124,
-+	0x2011, 0x000a, 0x0078, 0x412a, 0xa282, 0x000c, 0x00c8, 0x412a,
-+	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
-+	0x0048, 0x4136, 0x0040, 0x4136, 0x2019, 0x000c, 0x78ab, 0x0001,
-+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
-+	0x6820, 0xc0c5, 0x6822, 0x1078, 0x2d79, 0x0c7f, 0x007c, 0x0c7e,
-+	0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019,
-+	0x0000, 0x0078, 0x4153, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822,
-+	0x0c7f, 0x007c, 0x0c7e, 0x715c, 0x2160, 0x1078, 0x4169, 0x0c7f,
-+	0x007c, 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a,
-+	0x7cae, 0x6412, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105,
-+	0x78a6, 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004,
-+	0xa084, 0x00ff, 0xa405, 0x600e, 0x78ec, 0xd08c, 0x00c0, 0x418c,
-+	0x6004, 0xa084, 0xfff5, 0x6006, 0x007c, 0x0c7e, 0x705c, 0x2060,
-+	0x1078, 0x4194, 0x0c7f, 0x007c, 0x6018, 0x789a, 0x78a4, 0xa084,
-+	0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, 0x600c,
-+	0xa084, 0x00ff, 0x600e, 0x007c, 0xa282, 0x0002, 0x00c0, 0x429c,
-+	0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040, 0x41e3, 0xc1cc,
-+	0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, 0x429c, 0x1078,
-+	0x4227, 0x1078, 0x418d, 0xa980, 0x0001, 0x200c, 0x1078, 0x43a4,
-+	0x1078, 0x40f5, 0x88ff, 0x0040, 0x41d9, 0x789b, 0x0060, 0x2800,
-+	0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x41d4, 0x782b,
-+	0x3008, 0x781b, 0x0058, 0x007c, 0x782b, 0x3008, 0x781b, 0x0067,
-+	0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x41e0, 0x781b, 0x005a, 0x007c,
-+	0x781b, 0x0067, 0x007c, 0xa282, 0x0002, 0x00c8, 0x41eb, 0xa284,
-+	0x0001, 0x0040, 0x41f3, 0x715c, 0xa188, 0x0000, 0x210c, 0xd1ec,
-+	0x00c0, 0x41f3, 0xa016, 0x1078, 0x4311, 0x1078, 0x4227, 0x1078,
-+	0x418d, 0x7858, 0xc095, 0x785a, 0x782b, 0x3008, 0x781b, 0x0067,
-+	0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec,
-+	0x00c0, 0x4215, 0xa084, 0x0080, 0x00c0, 0x4213, 0xc1a4, 0x6106,
-+	0xa006, 0x0078, 0x4224, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
-+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x1078, 0x2d79,
-+	0x6820, 0xa085, 0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e,
-+	0x705c, 0x2060, 0x1078, 0x422e, 0x0c7f, 0x007c, 0x82ff, 0x0040,
-+	0x4233, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4,
-+	0xa084, 0xffbf, 0xa205, 0x78a6, 0x788a, 0x6016, 0x6004, 0x78ec,
-+	0xd08c, 0x00c0, 0x4245, 0xc0a4, 0x6006, 0x007c, 0x007e, 0x7000,
-+	0xa086, 0x0003, 0x0040, 0x424f, 0x007f, 0x0078, 0x4252, 0x007f,
-+	0x0078, 0x4299, 0xd6ac, 0x0040, 0x4299, 0x7888, 0xa084, 0x0040,
-+	0x0040, 0x4299, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x4261,
-+	0x8000, 0xa005, 0x0040, 0x4276, 0x831b, 0x00c8, 0x426a, 0x8001,
-+	0x0040, 0x4296, 0xd6f4, 0x0040, 0x4276, 0x78b8, 0x801b, 0x00c8,
-+	0x4272, 0x8000, 0xa084, 0x003f, 0x00c0, 0x4296, 0xc6f4, 0x7e5a,
-+	0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x4281, 0xa291,
-+	0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x5a6b, 0x781b,
-+	0x0066, 0xb284, 0x0300, 0x0040, 0x4291, 0x2001, 0x0000, 0x0078,
-+	0x4293, 0x2001, 0x0001, 0x1078, 0x588c, 0x007c, 0x781b, 0x0066,
-+	0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x42d1, 0x782b, 0x3008,
-+	0x781b, 0x0067, 0x007c, 0x1078, 0x42bd, 0x782b, 0x3008, 0x781b,
-+	0x0067, 0x007c, 0x6827, 0x0002, 0x1078, 0x42c5, 0x78e4, 0xa084,
-+	0x0030, 0x0040, 0x2c6e, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2c6e,
-+	0x782b, 0x3008, 0x781b, 0x0067, 0x007c, 0x2001, 0x0005, 0x0078,
-+	0x42d3, 0x2001, 0x000c, 0x0078, 0x42d3, 0x2001, 0x0006, 0x0078,
-+	0x42d3, 0x2001, 0x000d, 0x0078, 0x42d3, 0x2001, 0x0009, 0x0078,
-+	0x42d3, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa, 0x789b, 0x0060,
-+	0x78ab, 0x0001, 0xc695, 0x7e5a, 0x0078, 0x2d79, 0x077e, 0x873f,
-+	0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e, 0xb28c, 0x0300,
-+	0x0040, 0x42ee, 0xa0e0, 0x64c0, 0x0078, 0x42f0, 0xa0e0, 0x6540,
-+	0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
-+	0x4300, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xc09d, 0x6006,
-+	0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040, 0x430f,
-+	0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xc0a5, 0x6006, 0x077f,
-+	0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, 0x0078, 0x2d79,
-+	0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001,
-+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0060,
-+	0x78ab, 0x0005, 0x0078, 0x2d79, 0x157e, 0x2001, 0x6003, 0x2004,
-+	0xd0e4, 0x00c0, 0x4367, 0x2009, 0x439b, 0x20a9, 0x0009, 0x2510,
-+	0xa582, 0x000a, 0x0040, 0x4362, 0x0048, 0x4362, 0x8108, 0x95a9,
-+	0xa582, 0x0030, 0x0040, 0x437d, 0x0048, 0x437d, 0x8108, 0x95a9,
-+	0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x437d,
-+	0x0048, 0x437d, 0x8108, 0x2300, 0xa210, 0x00f0, 0x4354, 0x157f,
-+	0x0078, 0x437b, 0x2510, 0x8213, 0x8213, 0x0078, 0x437d, 0x2009,
-+	0x438d, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2200,
-+	0xa502, 0x0040, 0x437d, 0x0048, 0x437d, 0x8108, 0x2300, 0xa210,
-+	0x00f0, 0x436f, 0x157f, 0xa006, 0x007c, 0x157f, 0xa582, 0x0064,
-+	0x00c8, 0x438a, 0x7808, 0xa085, 0x0070, 0x780a, 0x704c, 0xa085,
-+	0x0070, 0x704e, 0x2104, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202,
-+	0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06,
-+	0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06,
-+	0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c,
-+	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003,
-+	0x8003, 0xa105, 0xd7fc, 0x0040, 0x43b9, 0xa0e0, 0x85c0, 0x0078,
-+	0x43bb, 0xa0e0, 0x65c0, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b,
-+	0x00c8, 0x43c3, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-+	0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x43d6, 0x2079, 0x0100,
-+	0x2009, 0x6080, 0x2071, 0x6080, 0x0078, 0x43e6, 0x2001, 0x6002,
-+	0x2004, 0xd0ec, 0x0040, 0x43e0, 0x2079, 0x0100, 0x0078, 0x43e2,
-+	0x2079, 0x0200, 0x2009, 0x6040, 0x2071, 0x6040, 0x2091, 0x8000,
-+	0x2104, 0xa084, 0x000f, 0x0079, 0x43ed, 0x43f7, 0x43f7, 0x43f7,
-+	0x43f7, 0x43f7, 0x43f7, 0x43f5, 0x444a, 0x1078, 0x2bfa, 0x69b4,
-+	0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x4447, 0x7858,
-+	0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814,
-+	0x00c0, 0x4447, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x00c0,
-+	0x440c, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0, 0x4413,
-+	0x7830, 0xd0bc, 0x00c0, 0x4447, 0x3200, 0x007e, 0x2001, 0x6002,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4429, 0xa084, 0x0300, 0x0078,
-+	0x442b, 0xa084, 0x0400, 0x0040, 0x4431, 0x0018, 0x4447, 0x0078,
-+	0x4433, 0x0028, 0x4447, 0x79e4, 0xa184, 0x0030, 0x0040, 0x4447,
-+	0x78ec, 0xa084, 0x0003, 0x0040, 0x4447, 0x681c, 0xd0ac, 0x00c0,
-+	0x4445, 0x1078, 0x446a, 0x0078, 0x4447, 0x781b, 0x00d3, 0x0f7f,
-+	0x0e7f, 0x007c, 0x70a7, 0x0000, 0x1078, 0x46d0, 0x0078, 0x4447,
-+	0x2001, 0x6001, 0x2004, 0xd0ac, 0x00c0, 0x4459, 0x6814, 0x1078,
-+	0x2b7a, 0x007c, 0x781b, 0x0067, 0x007c, 0x782b, 0x3008, 0x781b,
-+	0x0067, 0x007c, 0x781b, 0x005a, 0x007c, 0x782b, 0x3008, 0x781b,
-+	0x0058, 0x007c, 0x2009, 0x6017, 0x210c, 0xa186, 0x0000, 0x0040,
-+	0x447c, 0xa186, 0x0001, 0x0040, 0x4481, 0x701b, 0x000b, 0x706b,
-+	0x0001, 0x781b, 0x0048, 0x007c, 0x78cb, 0x0000, 0x781b, 0x00cf,
-+	0x007c, 0x701b, 0x000a, 0x007c, 0x2009, 0x6017, 0x210c, 0xa186,
-+	0x0000, 0x0040, 0x449a, 0xa186, 0x0001, 0x0040, 0x4497, 0x701b,
-+	0x000b, 0x706b, 0x0001, 0x781b, 0x0048, 0x0078, 0x2c5e, 0x701b,
-+	0x000a, 0x007c, 0x782b, 0x3008, 0x78cb, 0x0000, 0x781b, 0x00cf,
-+	0x007c, 0x781b, 0x00d3, 0x007c, 0x782b, 0x3008, 0x781b, 0x00d3,
-+	0x007c, 0x781b, 0x009b, 0x007c, 0x782b, 0x3008, 0x781b, 0x009b,
-+	0x007c, 0x6818, 0xd0fc, 0x0040, 0x44b7, 0x681b, 0x001d, 0x706b,
-+	0x0001, 0x781b, 0x0048, 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0,
-+	0x44df, 0x7808, 0xa084, 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005,
-+	0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0, 0x44dc, 0x2001, 0x6003,
-+	0x2004, 0xd0e4, 0x00c0, 0x44da, 0x7804, 0xa084, 0xff1f, 0xa085,
-+	0x00e0, 0x7806, 0xa006, 0x007c, 0x704c, 0xc08d, 0x780a, 0x007c,
-+	0x7830, 0xa084, 0x0080, 0x00c0, 0x44f9, 0x78ec, 0xa084, 0x0002,
-+	0x00c0, 0x44f9, 0x7808, 0xc08c, 0x780a, 0x0005, 0x0005, 0x0005,
-+	0x0005, 0x78ec, 0xa084, 0x0002, 0x0040, 0x44f9, 0x7808, 0xc08d,
-+	0x780a, 0x007c, 0x704c, 0xc08d, 0x704e, 0x780a, 0x007c, 0x7830,
-+	0xa084, 0x0040, 0x00c0, 0x44ff, 0x3200, 0x007e, 0x2001, 0x6002,
-+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4511, 0xa084, 0x0300, 0x0078,
-+	0x4513, 0xa084, 0x0400, 0x0040, 0x4519, 0x0098, 0x451d, 0x0078,
-+	0x451b, 0x00a8, 0x451d, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd,
-+	0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021,
-+	0x0040, 0x4541, 0x3200, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x4537, 0xa084, 0x0300, 0x0078, 0x4539, 0xa084,
-+	0x0400, 0x0040, 0x453f, 0x0098, 0x453b, 0x0078, 0x4541, 0x00a8,
-+	0x453f, 0x78ac, 0x007e, 0x704c, 0x780a, 0x007f, 0x007c, 0x78ec,
-+	0xa084, 0x0002, 0x00c0, 0x5596, 0xa784, 0x007d, 0x00c0, 0x4553,
-+	0x2700, 0x1078, 0x2bfa, 0xa784, 0x0001, 0x00c0, 0x39bf, 0xa784,
-+	0x0070, 0x0040, 0x4563, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2b67,
-+	0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x4570, 0x784b,
-+	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x39bf, 0x0078, 0x445a,
-+	0xa784, 0x0004, 0x0040, 0x459f, 0x78b8, 0xa084, 0x4001, 0x0040,
-+	0x459f, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x39bf,
-+	0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x459f, 0x78c0,
-+	0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00d3, 0x007c, 0x784b,
-+	0x0008, 0x6818, 0xd0fc, 0x0040, 0x459c, 0x681b, 0x0015, 0xd6f4,
-+	0x0040, 0x459c, 0x681b, 0x0007, 0x1078, 0x446a, 0x007c, 0x681b,
-+	0x0003, 0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833,
-+	0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x332a,
-+	0x3200, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x007f, 0x0040,
-+	0x45bd, 0xa084, 0x0300, 0x0078, 0x45bf, 0xa084, 0x0400, 0x0040,
-+	0x45c5, 0x0018, 0x2c5e, 0x0078, 0x45c7, 0x0028, 0x2c5e, 0x0078,
-+	0x42a3, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0xd3fc, 0x0040, 0x45d7, 0xa080, 0x6540, 0x0078, 0x45d9, 0xa080,
-+	0x64c0, 0x2060, 0x2048, 0x705e, 0x2a60, 0x007c, 0x7000, 0x0079,
-+	0x45e1, 0x45e9, 0x45e9, 0x45ea, 0x45f2, 0x45e9, 0x45e9, 0x45e9,
-+	0x45f5, 0x007c, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-+	0x601a, 0x007c, 0x1078, 0x55ac, 0x007c, 0x7094, 0xa005, 0x0040,
-+	0x4610, 0x2068, 0xb284, 0x0300, 0x0040, 0x4602, 0x2009, 0x0000,
-+	0x0078, 0x4604, 0x2009, 0x0001, 0x017e, 0x1078, 0x209b, 0x017f,
-+	0x017e, 0x1078, 0x552b, 0x017f, 0x1078, 0x552c, 0x7097, 0x0000,
-+	0x007c, 0x0e7e, 0x2091, 0x8000, 0x6014, 0xd0fc, 0x00c0, 0x461c,
-+	0x2071, 0x6040, 0x0078, 0x461e, 0x2071, 0x6080, 0x7000, 0xa086,
-+	0x0007, 0x00c0, 0x462f, 0x6110, 0x70b0, 0xa106, 0x00c0, 0x462f,
-+	0x0e7f, 0x1078, 0x20b0, 0x1078, 0x4635, 0xa006, 0x007c, 0x2091,
-+	0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x0078,
-+	0x28b1, 0x785b, 0x0000, 0x70a3, 0x000e, 0x2009, 0x0100, 0x017e,
-+	0x7094, 0xa06d, 0x0040, 0x4648, 0x7097, 0x0000, 0x0078, 0x464e,
-+	0x70a7, 0x0000, 0x1078, 0x20e4, 0x0040, 0x4654, 0x70a0, 0x6826,
-+	0x1078, 0x4781, 0x0078, 0x4648, 0x017f, 0x077e, 0x157e, 0x0c7e,
-+	0x0d7e, 0x20a9, 0x0020, 0x3238, 0xa7bc, 0x0300, 0x0040, 0x4665,
-+	0x2061, 0xa7e0, 0xc7fc, 0x0078, 0x4668, 0x2061, 0xa900, 0xc7fd,
-+	0x6000, 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x4678, 0x6800,
-+	0x601e, 0x1078, 0x1e55, 0x6008, 0x8000, 0x600a, 0x0078, 0x466b,
-+	0x6018, 0xa06d, 0x0040, 0x4682, 0x6800, 0x601a, 0x1078, 0x1e55,
-+	0x0078, 0x4678, 0xace0, 0x0009, 0x0070, 0x4688, 0x0078, 0x4668,
-+	0x7090, 0xa084, 0x8000, 0x0040, 0x468f, 0x1078, 0x480c, 0x0d7f,
-+	0x0c7f, 0x157f, 0x077f, 0x007c, 0x6804, 0xa084, 0x000f, 0x0079,
-+	0x4699, 0x46a9, 0x46a9, 0x46a9, 0x46a9, 0x46a9, 0x46a9, 0x46ab,
-+	0x46bd, 0x46a9, 0x46a9, 0x46a9, 0x46a9, 0x46a9, 0x46cb, 0x46a9,
-+	0x46ab, 0x1078, 0x2bfa, 0x007e, 0x7830, 0xd0b4, 0x0040, 0x46b6,
-+	0x784b, 0x0004, 0x7848, 0xd094, 0x00c0, 0x46b2, 0x007f, 0x1078,
-+	0x52d3, 0x1078, 0x1e55, 0x0078, 0x46cf, 0x6827, 0x000b, 0x007e,
-+	0x7830, 0xd0b4, 0x0040, 0x46ca, 0x784b, 0x0004, 0x7848, 0xd094,
-+	0x00c0, 0x46c6, 0x007f, 0x1078, 0x52d3, 0x1078, 0x4781, 0x007c,
-+	0x0f7e, 0x6814, 0xd0fc, 0x00c0, 0x46e7, 0x2001, 0x6002, 0x2004,
-+	0xd0ec, 0x0040, 0x46e1, 0x2079, 0x0100, 0x0098, 0x4706, 0x0078,
-+	0x46eb, 0x2079, 0x0200, 0x00a8, 0x4706, 0x0078, 0x46eb, 0x2079,
-+	0x0100, 0x0098, 0x4706, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x4706,
-+	0x0d7e, 0x1078, 0x5539, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001,
-+	0x0000, 0x6827, 0x0084, 0x1078, 0x54df, 0x1078, 0x4781, 0x0d7f,
-+	0x70a8, 0xa080, 0x00af, 0x781a, 0x0078, 0x474f, 0x7948, 0x6814,
-+	0xd0fc, 0x00c0, 0x4719, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x0040,
-+	0x4715, 0x0098, 0x471e, 0x0078, 0x471b, 0x00a8, 0x471e, 0x0078,
-+	0x471b, 0x0098, 0x471e, 0x794a, 0x0078, 0x46f0, 0x7948, 0x7828,
-+	0x007e, 0xa084, 0xf000, 0xa086, 0x1000, 0x007f, 0x00c0, 0x471b,
-+	0xd0b4, 0x00c0, 0x471b, 0xd0ac, 0x0040, 0x4732, 0xa185, 0x0004,
-+	0x0078, 0x4734, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab,
-+	0x0002, 0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a, 0x70a8,
-+	0xa080, 0x0097, 0x781a, 0x6827, 0x0284, 0x682c, 0x6836, 0x6830,
-+	0x683a, 0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x54df, 0x0f7f,
-+	0x007c, 0x0d7e, 0x6b14, 0x1078, 0x2160, 0x0040, 0x475e, 0x2068,
-+	0x6827, 0x0002, 0x1078, 0x4781, 0x0078, 0x4753, 0x0d7f, 0x007c,
-+	0x0d7e, 0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x20f0, 0x0040,
-+	0x476e, 0x2068, 0x6827, 0x0002, 0x1078, 0x4781, 0x0d7f, 0x007c,
-+	0x0d7e, 0x6814, 0xa09c, 0x00ff, 0x1078, 0x212a, 0x0040, 0x477f,
-+	0x2068, 0x6827, 0x0002, 0x1078, 0x4781, 0x0078, 0x4774, 0x0d7f,
-+	0x007c, 0x0c7e, 0x6914, 0x6814, 0x1078, 0x47fa, 0x6904, 0xa18c,
-+	0x00ff, 0xa186, 0x0006, 0x0040, 0x479d, 0xa186, 0x000d, 0x0040,
-+	0x47c1, 0xa186, 0x0017, 0x00c0, 0x4799, 0x1078, 0x1e55, 0x0c7f,
-+	0x007c, 0x1078, 0x2253, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048,
-+	0x47ba, 0x6006, 0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x47aa,
-+	0xa18d, 0x8000, 0xa684, 0x0004, 0x0040, 0x47b0, 0xa18d, 0x0002,
-+	0x691e, 0x6823, 0x0000, 0x711c, 0x810f, 0x6818, 0xa105, 0x681a,
-+	0x0078, 0x4799, 0x6100, 0xa184, 0x0001, 0x0040, 0x4795, 0x1078,
-+	0x2bfa, 0x6018, 0xa005, 0x00c0, 0x47d0, 0x6008, 0x8001, 0x0048,
-+	0x47d0, 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, 0x47e8,
-+	0xac88, 0x0006, 0x2104, 0xa005, 0x0040, 0x47d9, 0x2008, 0x0078,
-+	0x47d2, 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x47e6, 0x600a,
-+	0x6018, 0x2068, 0x6800, 0x601a, 0x0078, 0x47ca, 0x0c7f, 0x007c,
-+	0x157e, 0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x1e32, 0x2da0,
-+	0x137f, 0x20a9, 0x0037, 0x53a3, 0x0c7f, 0x147f, 0x137f, 0x157f,
-+	0x0078, 0x4799, 0xd0fc, 0x00c0, 0x4801, 0x2061, 0xa7e0, 0x0078,
-+	0x4803, 0x2061, 0xa900, 0xa184, 0x001f, 0xac60, 0x8003, 0x8003,
-+	0x8003, 0xac00, 0x2060, 0x007c, 0xd7fc, 0x00c0, 0x481f, 0x2019,
-+	0x6053, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x0040, 0x481b, 0x2021,
-+	0x0102, 0x0078, 0x4823, 0x2021, 0x0202, 0x0078, 0x4823, 0x2019,
-+	0x6093, 0x2021, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a, 0x2404,
-+	0xa085, 0x0001, 0x2022, 0x007c, 0xd7fc, 0x00c0, 0x483f, 0x2019,
-+	0x6053, 0x2001, 0x6002, 0x2004, 0xd0ec, 0x0040, 0x483b, 0x2021,
-+	0x0102, 0x0078, 0x4843, 0x2021, 0x0202, 0x0078, 0x4843, 0x2019,
-+	0x6093, 0x2021, 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2404,
-+	0xa084, 0xfffe, 0x2022, 0x007c, 0x7990, 0xa18c, 0xfff8, 0x7992,
-+	0x70a8, 0xa080, 0x00d7, 0x781a, 0x0078, 0x2c5e, 0x7097, 0x0000,
-+	0x7003, 0x0000, 0x704b, 0x0001, 0x7043, 0x0000, 0x1078, 0x20e4,
-+	0x0040, 0x488c, 0x70ef, 0x0000, 0x68cc, 0x2060, 0x6100, 0xa184,
-+	0x0300, 0x0040, 0x4877, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040,
-+	0x4873, 0x6827, 0x0017, 0x1078, 0x4781, 0x0078, 0x4856, 0x7000,
-+	0xa086, 0x0007, 0x00c0, 0x4905, 0x6910, 0x70b0, 0xa106, 0x0040,
-+	0x4885, 0x2d60, 0x1078, 0x20b0, 0x007c, 0x2d00, 0x7096, 0xad80,
-+	0x000f, 0x7042, 0x0078, 0x4897, 0x7010, 0xa005, 0x00c0, 0x4895,
-+	0x7048, 0xa086, 0x0001, 0x0040, 0x2c78, 0x0078, 0x2c5e, 0xa036,
-+	0x691c, 0xa184, 0x0002, 0x0040, 0x489f, 0xa6b5, 0x0004, 0xa184,
-+	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x49b3, 0x2004, 0xa635,
-+	0x1078, 0x2d79, 0x6820, 0xa084, 0x0400, 0x0040, 0x48b9, 0x789b,
-+	0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
-+	0x5000, 0x6820, 0xa084, 0x8000, 0x0040, 0x48c7, 0xa6b5, 0x0400,
-+	0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x48e7, 0x681c,
-+	0xd0fc, 0x00c0, 0x48d5, 0xa6b5, 0x0800, 0x6820, 0xd0c4, 0x0040,
-+	0x48e7, 0xa6b5, 0x4000, 0x0078, 0x48e7, 0x6820, 0xd0c4, 0x0040,
-+	0x48dd, 0xa6b5, 0x4000, 0x0078, 0x48e7, 0x789b, 0x0018, 0x78ab,
-+	0x0002, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0xa684,
-+	0x0200, 0x0040, 0x4901, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684,
-+	0x0100, 0x0040, 0x48ff, 0x682c, 0xa084, 0x0001, 0x0040, 0x48ff,
-+	0x7888, 0xa084, 0x0040, 0x0040, 0x48ff, 0xa6b5, 0x8000, 0x1078,
-+	0x550e, 0x7e5a, 0x6eb6, 0x0078, 0x5558, 0x1078, 0x44bc, 0x00c0,
-+	0x49ad, 0x2041, 0x0001, 0x2031, 0x1000, 0x1078, 0x2d79, 0x789b,
-+	0x0018, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c,
-+	0xa184, 0x0002, 0x0040, 0x4924, 0xa6b5, 0x0004, 0x78ab, 0x0020,
-+	0x6828, 0x78aa, 0xa8c0, 0x0002, 0x681c, 0xd0f4, 0x0040, 0x492d,
-+	0x2c50, 0x1078, 0x45c9, 0x1078, 0x5424, 0x6820, 0xa084, 0x8000,
-+	0x0040, 0x493b, 0xa6b5, 0x0400, 0x789b, 0x000e, 0x6824, 0x8007,
-+	0x78aa, 0x0078, 0x4949, 0x681c, 0xa084, 0x8000, 0x00c0, 0x4949,
-+	0xa6b5, 0x0800, 0x6820, 0xa084, 0x0100, 0x0040, 0x4949, 0xa6b5,
-+	0x4000, 0x681c, 0xa084, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080,
-+	0x49b3, 0x2004, 0xa635, 0xa684, 0x0100, 0x0040, 0x4963, 0x682c,
-+	0xa084, 0x0001, 0x0040, 0x4963, 0x7888, 0xa084, 0x0040, 0x0040,
-+	0x4963, 0xa6b5, 0x8000, 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814,
-+	0xc0fc, 0x8007, 0x78aa, 0x7882, 0x2810, 0x7aaa, 0x7830, 0xa084,
-+	0x00c0, 0x00c0, 0x49ad, 0x6914, 0xd1fc, 0x00c0, 0x4985, 0x2001,
-+	0x6002, 0x2004, 0xd0ec, 0x0040, 0x4981, 0x0018, 0x49ad, 0x0078,
-+	0x4987, 0x0028, 0x49ad, 0x0078, 0x4987, 0x0018, 0x49ad, 0x127e,
-+	0x0d7e, 0x0c7e, 0x70f0, 0xa084, 0x2700, 0x2090, 0x0c7f, 0x0d7f,
-+	0x127f, 0xa684, 0x0200, 0x0040, 0x499b, 0x682c, 0x78d2, 0x6830,
-+	0x78d6, 0x1078, 0x550e, 0x70a8, 0xa080, 0x00dc, 0x781a, 0x1078,
-+	0x44fa, 0x2d00, 0x7096, 0x7052, 0x6810, 0x70b2, 0x7003, 0x0007,
-+	0xad80, 0x000f, 0x7042, 0x0078, 0x2c5e, 0x1078, 0x209b, 0x1078,
-+	0x44fa, 0x0078, 0x2c5e, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078,
-+	0x2bfa, 0x1078, 0x2bed, 0x2300, 0x0079, 0x49be, 0x49c3, 0x49c1,
-+	0x49c8, 0x1078, 0x2bfa, 0x71a8, 0xa188, 0x0097, 0x791a, 0x007c,
-+	0x1078, 0x552c, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040,
-+	0x49da, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x209b,
-+	0x0078, 0x4856, 0x2001, 0x000a, 0x1078, 0x54ae, 0x0078, 0x4856,
-+	0xa282, 0x0005, 0x0050, 0x49e6, 0x1078, 0x2bfa, 0x7000, 0xa084,
-+	0x000f, 0x10c0, 0x45de, 0x1078, 0x1e32, 0x00c0, 0x4a08, 0x2069,
-+	0xffff, 0xa684, 0x0004, 0x0040, 0x49f9, 0x2001, 0x2800, 0x0078,
-+	0x49fb, 0x2001, 0x0800, 0x71a8, 0xa188, 0x0097, 0x789b, 0x000e,
-+	0x8007, 0x78aa, 0x2031, 0x0400, 0x7e5a, 0x791a, 0x0078, 0x2c5e,
-+	0x6807, 0x0106, 0x680b, 0x0000, 0x689f, 0x0000, 0x6827, 0x0000,
-+	0xa386, 0x0002, 0x00c0, 0x4a28, 0xa286, 0x0002, 0x00c0, 0x4a28,
-+	0x78a0, 0xa005, 0x00c0, 0x4a28, 0xd4fc, 0x00c0, 0x4a28, 0x78e4,
-+	0xa084, 0x0008, 0x0040, 0x4a28, 0xa6b5, 0x0008, 0x2019, 0x0000,
-+	0x1078, 0x4e89, 0x2d00, 0x7096, 0x7052, 0x7003, 0x0007, 0x7043,
-+	0x0000, 0x6020, 0xa084, 0x000f, 0x680e, 0x6824, 0xa084, 0x0080,
-+	0x0040, 0x4a3e, 0x1078, 0x4f59, 0x0078, 0x2c5e, 0x2300, 0x0079,
-+	0x4a41, 0x4a44, 0x4ac5, 0x4ade, 0x2200, 0x0079, 0x4a47, 0x4a4c,
-+	0x4a5c, 0x4a82, 0x4a8e, 0x4ab1, 0x2029, 0x0001, 0xa026, 0x2011,
-+	0x0000, 0x1078, 0x5092, 0x0079, 0x4a55, 0x4a5a, 0x2c5e, 0x4856,
-+	0x4a5a, 0x4a5a, 0x1078, 0x2bfa, 0x7990, 0xa18c, 0x0007, 0x00c0,
-+	0x4a63, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, 0x0004, 0x0040,
-+	0x4a6b, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, 0x0001, 0x1078,
-+	0x5092, 0x0079, 0x4a73, 0x4a78, 0x2c5e, 0x4856, 0x4a80, 0x4a7a,
-+	0x0078, 0x555e, 0x709f, 0x4a7e, 0x0078, 0x2c5e, 0x0078, 0x4a78,
-+	0x1078, 0x2bfa, 0xa684, 0x0010, 0x0040, 0x4a8c, 0x1078, 0x4f1a,
-+	0x0040, 0x4a8c, 0x0078, 0x2c5e, 0x0078, 0x4f9a, 0x6000, 0xa084,
-+	0x0002, 0x0040, 0x4aab, 0x70a8, 0xa080, 0x0085, 0x781a, 0x0d7e,
-+	0x1078, 0x5539, 0x2d00, 0x682e, 0x6827, 0x0000, 0x1078, 0x4781,
-+	0x0d7f, 0x1078, 0x1e55, 0x7003, 0x0000, 0x7043, 0x0000, 0x7053,
-+	0x0000, 0x0078, 0x4856, 0xa684, 0x0004, 0x00c0, 0x4ab1, 0x0078,
-+	0x555e, 0x6000, 0xa084, 0x0004, 0x00c0, 0x4ac3, 0x6000, 0xa084,
-+	0x0001, 0x0040, 0x4ac3, 0x709f, 0x4ac3, 0x2001, 0x0007, 0x1078,
-+	0x54a6, 0x0078, 0x5564, 0x0078, 0x555e, 0x2200, 0x0079, 0x4ac8,
-+	0x4acd, 0x4acf, 0x4acd, 0x4acd, 0x4acd, 0x1078, 0x2bfa, 0x709b,
-+	0x4ad3, 0x0078, 0x556c, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x4acf,
-+	0x1078, 0x5496, 0x709f, 0x4adc, 0x0078, 0x555e, 0x2200, 0x0079,
-+	0x4ae1, 0x4ae6, 0x4ae8, 0x4ae8, 0x4ae6, 0x4ae6, 0x1078, 0x2bfa,
-+	0x78e4, 0xa084, 0x0008, 0x0040, 0x4afd, 0x709b, 0x4af1, 0x0078,
-+	0x556c, 0x2011, 0x0004, 0x1078, 0x508c, 0x0079, 0x4af7, 0x4b09,
-+	0x2c5e, 0x4856, 0x4b09, 0x4b13, 0x4b17, 0x690c, 0x81ff, 0x0040,
-+	0x4b09, 0x8109, 0x00c0, 0x4b08, 0x6827, 0x000f, 0x0078, 0x4bbd,
-+	0x690e, 0x709f, 0x4b11, 0x2001, 0x0003, 0x1078, 0x54a6, 0x0078,
-+	0x5564, 0x0078, 0x555e, 0x709f, 0x4b09, 0x0078, 0x2c5e, 0x709f,
-+	0x4b1b, 0x0078, 0x2c5e, 0x0078, 0x4b11, 0xa282, 0x0003, 0x0050,
-+	0x4b23, 0x1078, 0x2bfa, 0xa386, 0x0002, 0x00c0, 0x4b3b, 0xa286,
-+	0x0002, 0x00c0, 0x4b41, 0x78a0, 0xa005, 0x00c0, 0x4b41, 0xd4fc,
-+	0x00c0, 0x4b41, 0x78e4, 0xa084, 0x0008, 0x0040, 0x4b3b, 0xa6b5,
-+	0x0008, 0x2019, 0x0000, 0xa684, 0x0008, 0x0040, 0x4b41, 0x1078,
-+	0x4ef7, 0x6810, 0x70b2, 0x7003, 0x0007, 0x2300, 0x0079, 0x4b48,
-+	0x4b4b, 0x4b78, 0x4b80, 0x2200, 0x0079, 0x4b4e, 0x4b53, 0x4b51,
-+	0x4b6c, 0x1078, 0x2bfa, 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011,
-+	0x0001, 0x1078, 0x5092, 0x0079, 0x4b5d, 0x4b62, 0x2c5e, 0x4856,
-+	0x4b6a, 0x4b64, 0x0078, 0x555e, 0x709f, 0x4b68, 0x0078, 0x2c5e,
-+	0x0078, 0x4b62, 0x1078, 0x2bfa, 0xa684, 0x0010, 0x0040, 0x4b76,
-+	0x1078, 0x4f1a, 0x0040, 0x4b76, 0x0078, 0x2c5e, 0x0078, 0x4f9a,
-+	0x2200, 0x0079, 0x4b7b, 0x4b7e, 0x4b7e, 0x4b7e, 0x1078, 0x2bfa,
-+	0x2200, 0x0079, 0x4b83, 0x4b86, 0x4b88, 0x4b88, 0x1078, 0x2bfa,
-+	0x78e4, 0xa084, 0x0008, 0x0040, 0x4b9d, 0x709b, 0x4b91, 0x0078,
-+	0x556c, 0x2011, 0x0004, 0x1078, 0x508c, 0x0079, 0x4b97, 0x4ba9,
-+	0x2c5e, 0x4856, 0x4ba9, 0x4bb3, 0x4bb7, 0x690c, 0x81ff, 0x0040,
-+	0x4ba9, 0x8109, 0x00c0, 0x4ba8, 0x6827, 0x000f, 0x0078, 0x4bbd,
-+	0x690e, 0x709f, 0x4bb1, 0x2001, 0x0003, 0x1078, 0x54a6, 0x0078,
-+	0x5564, 0x0078, 0x555e, 0x709f, 0x4ba9, 0x0078, 0x2c5e, 0x709f,
-+	0x4bbb, 0x0078, 0x2c5e, 0x0078, 0x4bb1, 0x70a8, 0xa080, 0x0085,
-+	0x781a, 0x0d7e, 0x6824, 0x007e, 0x1078, 0x5539, 0x007f, 0x6826,
-+	0x2d00, 0x682e, 0x1078, 0x4781, 0x0d7f, 0x1078, 0x54ae, 0x7003,
-+	0x0000, 0x7043, 0x0000, 0x7053, 0x0000, 0x0078, 0x4856, 0x2300,
-+	0x0079, 0x4bda, 0x4bdf, 0x4be1, 0x4bdd, 0x1078, 0x2bfa, 0x7098,
-+	0x007a, 0x7098, 0x007a, 0xa282, 0x0002, 0x0050, 0x4be9, 0x1078,
-+	0x2bfa, 0xa684, 0x0200, 0x0040, 0x4bf3, 0x1078, 0x552b, 0x1078,
-+	0x5074, 0x1078, 0x552c, 0x2300, 0x0079, 0x4bf6, 0x4bf9, 0x4c2c,
-+	0x4c92, 0xad86, 0xffff, 0x00c0, 0x4bfe, 0x007c, 0xa286, 0x0001,
-+	0x0040, 0x4c04, 0x1078, 0x2bfa, 0xa684, 0x0200, 0x0040, 0x4c0c,
-+	0x1078, 0x552b, 0x1078, 0x552c, 0x6924, 0xa184, 0x00ff, 0xa086,
-+	0x000a, 0x00c0, 0x4c16, 0xa184, 0xff00, 0x6826, 0x2001, 0x0001,
-+	0x1078, 0x54ae, 0x78b8, 0xa084, 0xc001, 0x0040, 0x4c28, 0x7848,
-+	0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x4c23,
-+	0x7003, 0x0000, 0x0078, 0x4856, 0x2200, 0x0079, 0x4c2f, 0x4c31,
-+	0x4c62, 0x709b, 0x4c35, 0x0078, 0x556c, 0x2011, 0x000d, 0x1078,
-+	0x508c, 0x0079, 0x4c3b, 0x4c42, 0x2c5e, 0x4856, 0x4c4a, 0x4c52,
-+	0x4c58, 0x4c5a, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0078, 0x5558, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0078, 0x5558, 0x709f, 0x4c56, 0x0078, 0x2c5e, 0x0078, 0x4c42,
-+	0x1078, 0x2bfa, 0x709f, 0x4c5e, 0x0078, 0x2c5e, 0x1078, 0x5572,
-+	0x0078, 0x2c5e, 0x709b, 0x4c66, 0x0078, 0x556c, 0x2011, 0x0012,
-+	0x1078, 0x508c, 0x0079, 0x4c6c, 0x4c72, 0x2c5e, 0x4856, 0x4c7e,
-+	0x4c86, 0x4c8c, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x70a8, 0xa080, 0x00af, 0x781a, 0x0078, 0x2c5e, 0xa6b4, 0x00ff,
-+	0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x5558, 0x709f, 0x4c8a,
-+	0x0078, 0x2c5e, 0x0078, 0x4c72, 0x709f, 0x4c90, 0x0078, 0x2c5e,
-+	0x0078, 0x4c7e, 0xa286, 0x0001, 0x0040, 0x4c98, 0x1078, 0x2bfa,
-+	0x709b, 0x4c9c, 0x0078, 0x556c, 0x2011, 0x0015, 0x1078, 0x508c,
-+	0x0079, 0x4ca2, 0x4ca7, 0x2c5e, 0x4856, 0x4cb5, 0x4cc1, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70a8,
-+	0xa080, 0x00bb, 0x781a, 0x0078, 0x2c5e, 0xa6b4, 0x00ff, 0xa6b5,
-+	0x0400, 0x6eb6, 0x7e5a, 0x70a8, 0xa080, 0x00af, 0x781a, 0x0078,
-+	0x2c5e, 0x709f, 0x4cc5, 0x0078, 0x2c5e, 0x0078, 0x4ca7, 0xa282,
-+	0x0003, 0x0050, 0x4ccd, 0x1078, 0x2bfa, 0x2300, 0x0079, 0x4cd0,
-+	0x4cd3, 0x4d14, 0x4d79, 0xa286, 0x0001, 0x0040, 0x4cd9, 0x1078,
-+	0x2bfa, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4ce6,
-+	0x1078, 0x4781, 0x7003, 0x0000, 0x0078, 0x4856, 0x683b, 0x0000,
-+	0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x4cf4, 0x1078, 0x552b,
-+	0x1078, 0x5074, 0x1078, 0x552c, 0x6924, 0xa184, 0x00ff, 0xa086,
-+	0x000a, 0x00c0, 0x4cfe, 0xa184, 0xff00, 0x6826, 0x2001, 0x0001,
-+	0x1078, 0x54ae, 0x78b8, 0xa084, 0xc001, 0x0040, 0x4d10, 0x7848,
-+	0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x4d0b,
-+	0x7003, 0x0000, 0x0078, 0x4856, 0xa684, 0x0200, 0x0040, 0x4d1c,
-+	0x1078, 0x5074, 0x1078, 0x552c, 0x2200, 0x0079, 0x4d1f, 0x4d21,
-+	0x4d54, 0x709b, 0x4d25, 0x0078, 0x556c, 0x2011, 0x000d, 0x1078,
-+	0x508c, 0x0079, 0x4d2b, 0x4d32, 0x2c5e, 0x4856, 0x4d3a, 0x4d42,
-+	0x4d48, 0x4d4a, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a,
-+	0x0078, 0x5558, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a,
-+	0x0078, 0x5558, 0x709f, 0x4d46, 0x0078, 0x2c5e, 0x0078, 0x4d32,
-+	0x1078, 0x2bfa, 0x709f, 0x4d50, 0x1078, 0x552c, 0x0078, 0x2c5e,
-+	0x1078, 0x5572, 0x0078, 0x2c5e, 0x709b, 0x4d58, 0x0078, 0x556c,
-+	0x2011, 0x0005, 0x1078, 0x508c, 0x0079, 0x4d5e, 0x4d63, 0x2c5e,
-+	0x4856, 0x4d6b, 0x4d73, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6,
-+	0x7e5a, 0x0078, 0x5558, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6,
-+	0x7e5a, 0x0078, 0x5558, 0x709f, 0x4d77, 0x0078, 0x2c5e, 0x0078,
-+	0x4d63, 0xa286, 0x0001, 0x0040, 0x4d7f, 0x1078, 0x2bfa, 0x709b,
-+	0x4d83, 0x0078, 0x556c, 0x2011, 0x0006, 0x1078, 0x508c, 0x0079,
-+	0x4d89, 0x4d8e, 0x2c5e, 0x4856, 0x4d94, 0x4d9e, 0xa6b5, 0x0800,
-+	0x6eb6, 0x7e5a, 0x0078, 0x5558, 0xa6b4, 0x00ff, 0xa6b5, 0x0800,
-+	0x6eb6, 0xa6b5, 0x4000, 0x7e5a, 0x0078, 0x5558, 0x709f, 0x4da2,
-+	0x0078, 0x2c5e, 0x0078, 0x4d8e, 0x2300, 0x0079, 0x4da7, 0x4dac,
-+	0x4daa, 0x4daa, 0x1078, 0x2bfa, 0x1078, 0x2bfa, 0x2300, 0x719c,
-+	0xa005, 0x017a, 0x6810, 0x70b2, 0xa282, 0x0003, 0x0050, 0x4dba,
-+	0x1078, 0x2bfa, 0x2300, 0x0079, 0x4dbd, 0x4dc0, 0x4dce, 0x4df0,
-+	0xa684, 0x0200, 0x0040, 0x4dc8, 0x1078, 0x552b, 0x1078, 0x552c,
-+	0x2001, 0x0001, 0x1078, 0x54ae, 0x0078, 0x2c5e, 0xa286, 0x0002,
-+	0x0040, 0x4dd7, 0x82ff, 0x0040, 0x4dd7, 0x1078, 0x2bfa, 0x709b,
-+	0x4ddb, 0x0078, 0x556c, 0x2011, 0x0018, 0x1078, 0x508c, 0x0079,
-+	0x4de1, 0x4de6, 0x2c5e, 0x4856, 0x4de8, 0x4dea, 0x0078, 0x5558,
-+	0x0078, 0x5558, 0x709f, 0x4dee, 0x0078, 0x2c5e, 0x0078, 0x4de6,
-+	0x2200, 0x0079, 0x4df3, 0x4df5, 0x4e0e, 0x709b, 0x4df9, 0x0078,
-+	0x556c, 0x2011, 0x0017, 0x1078, 0x508c, 0x0079, 0x4dff, 0x4e04,
-+	0x2c5e, 0x4856, 0x4e06, 0x4e08, 0x0078, 0x5558, 0x0078, 0x5558,
-+	0x709f, 0x4e0c, 0x0078, 0x2c5e, 0x0078, 0x4e04, 0xd4fc, 0x00c0,
-+	0x4e6b, 0xa684, 0x0100, 0x0040, 0x4e19, 0x1078, 0x552b, 0x1078,
-+	0x5074, 0x78d8, 0x78d2, 0x78dc, 0x78d6, 0xa6b4, 0xefff, 0x7e5a,
-+	0x709b, 0x4e24, 0x0078, 0x556c, 0x2011, 0x000d, 0x1078, 0x508c,
-+	0x0079, 0x4e2a, 0x4e31, 0x2c5e, 0x4856, 0x4e31, 0x4e59, 0x4e5f,
-+	0x4e61, 0x78d8, 0x79dc, 0xa105, 0x00c0, 0x4e43, 0x78b8, 0xa084,
-+	0x801f, 0x00c0, 0x4e43, 0x70a7, 0x0000, 0x7858, 0xa084, 0xfdff,
-+	0x785a, 0x0078, 0x5558, 0xa684, 0x0100, 0x0040, 0x4e57, 0x1078,
-+	0x552c, 0x1078, 0x54d4, 0x027e, 0x037e, 0x682c, 0x78d2, 0x6830,
-+	0x78d6, 0x70a7, 0x0000, 0x017f, 0x007f, 0x1078, 0x5972, 0x0078,
-+	0x5558, 0x709f, 0x4e5d, 0x0078, 0x2c5e, 0x0078, 0x4e31, 0x1078,
-+	0x2bfa, 0x709f, 0x4e67, 0x1078, 0x552c, 0x0078, 0x2c5e, 0x1078,
-+	0x5572, 0x0078, 0x2c5e, 0x1078, 0x552c, 0x6918, 0xd1a4, 0x0040,
-+	0x4e79, 0x6827, 0x000f, 0x1078, 0x54ae, 0x1078, 0x552c, 0x0078,
-+	0x2c5e, 0x709f, 0x4e81, 0x2001, 0x0003, 0x1078, 0x54a6, 0x0078,
-+	0x5564, 0x1078, 0x550e, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078,
-+	0x5558, 0x70ac, 0x6812, 0x70b2, 0x8000, 0x70ae, 0x681b, 0x0000,
-+	0xa684, 0x0008, 0x0040, 0x4eac, 0x157e, 0x137e, 0x147e, 0x7890,
-+	0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x681a, 0x80ac,
-+	0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0xad80, 0x000b, 0x20a0,
-+	0x53a5, 0x147f, 0x137f, 0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002,
-+	0x00c0, 0x4ebb, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007,
-+	0x2008, 0x0078, 0x4ece, 0x789b, 0x0010, 0x79ac, 0xa184, 0x0020,
-+	0x0040, 0x4ece, 0x017e, 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078,
-+	0x54df, 0x6824, 0xa085, 0x003b, 0x6826, 0x017f, 0xa184, 0x001f,
-+	0xa805, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x4eda, 0xc0fc,
-+	0x0078, 0x4edb, 0xc0fd, 0x017f, 0x6816, 0x1078, 0x47fa, 0x68ce,
-+	0xa684, 0x0004, 0x0040, 0x4eea, 0xa18c, 0xff00, 0x78a8, 0xa084,
-+	0x00ff, 0xa105, 0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008,
-+	0x0040, 0x4ef4, 0xa6b5, 0x4000, 0x6eb6, 0x7e5a, 0x007c, 0x157e,
-+	0x137e, 0x147e, 0x6918, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004,
-+	0xa084, 0x000f, 0x007e, 0xa100, 0x681a, 0x007f, 0x8000, 0x8004,
-+	0x0040, 0x4f16, 0x20a8, 0x8104, 0xa080, 0x000b, 0xad00, 0x20a0,
-+	0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0x53a5, 0x147f, 0x137f,
-+	0x157f, 0x007c, 0x682c, 0xd0b4, 0x00c0, 0x4f29, 0xd0ac, 0x00c0,
-+	0x4f25, 0x2011, 0x0010, 0x0078, 0x4f31, 0x2011, 0x000c, 0x0078,
-+	0x4f31, 0xa084, 0x0020, 0x00c0, 0x4f30, 0x620c, 0x0078, 0x4f31,
-+	0x6210, 0x6b18, 0x2300, 0xa202, 0x0040, 0x4f51, 0x2018, 0xa382,
-+	0x000e, 0x0048, 0x4f41, 0x0040, 0x4f41, 0x2019, 0x000e, 0x0078,
-+	0x4f45, 0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893,
-+	0x0000, 0x7ba2, 0x70a8, 0xa080, 0x0094, 0x781a, 0xa085, 0x0001,
-+	0x007c, 0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006,
-+	0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x4f66,
-+	0xa196, 0x000f, 0x0040, 0x4f66, 0x6807, 0x0117, 0x6914, 0x6814,
-+	0x1078, 0x47fa, 0x6100, 0x8104, 0x00c8, 0x4f82, 0x601c, 0xa005,
-+	0x0040, 0x4f76, 0x2001, 0x0800, 0x0078, 0x4f84, 0x0d7e, 0x6824,
-+	0x007e, 0x1078, 0x5539, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078,
-+	0x4781, 0x0d7f, 0x2001, 0x0200, 0x6924, 0xa18c, 0x00ff, 0xa10d,
-+	0x6926, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000,
-+	0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71a8, 0xa188, 0x0097,
-+	0x791a, 0x007c, 0x1078, 0x2d79, 0x6814, 0x2040, 0xa684, 0x0002,
-+	0x00c0, 0x4fb0, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007,
-+	0x2008, 0xa805, 0x6816, 0x1078, 0x47fa, 0x68ce, 0x0078, 0x4fb4,
-+	0x6914, 0x6814, 0x1078, 0x47fa, 0x6100, 0x8104, 0x00c8, 0x5012,
-+	0xa184, 0x0300, 0x0040, 0x4fc0, 0x6807, 0x0117, 0x0078, 0x4fde,
-+	0x6004, 0xa005, 0x00c0, 0x4fe7, 0x6807, 0x0117, 0x601c, 0xa005,
-+	0x00c0, 0x4fd4, 0x0d7e, 0x1078, 0x5539, 0x6827, 0x0034, 0x2d00,
-+	0x682e, 0x1078, 0x4781, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x4fde,
-+	0x2031, 0x0400, 0x2001, 0x2800, 0x0078, 0x4fe2, 0x2031, 0x0400,
-+	0x2001, 0x0800, 0x71a8, 0xa188, 0x0097, 0x0078, 0x504f, 0x6018,
-+	0xa005, 0x00c0, 0x4fd4, 0x601c, 0xa005, 0x00c0, 0x4fd4, 0x689f,
-+	0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x505d, 0xd694,
-+	0x00c0, 0x500b, 0x6100, 0xd1d4, 0x0040, 0x500b, 0x692c, 0xa18c,
-+	0x00ff, 0x0040, 0x505d, 0xa186, 0x0003, 0x0040, 0x505d, 0xa186,
-+	0x0012, 0x0040, 0x505d, 0xa6b5, 0x0800, 0x71a8, 0xa188, 0x00b3,
-+	0x0078, 0x5058, 0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c,
-+	0x00ff, 0xa186, 0x0012, 0x00c0, 0x5023, 0x2001, 0x506a, 0x2009,
-+	0x0001, 0x0078, 0x5034, 0xa186, 0x0003, 0x00c0, 0x502d, 0x2001,
-+	0x506b, 0x2009, 0x0012, 0x0078, 0x5034, 0x2001, 0x0200, 0x71a8,
-+	0xa188, 0x0097, 0x0078, 0x504f, 0x6a34, 0xa29d, 0x0000, 0x00c0,
-+	0x503c, 0xa006, 0x0078, 0x502f, 0x007e, 0x2100, 0xa21a, 0x007f,
-+	0x00c8, 0x5043, 0x2208, 0x1078, 0x54f9, 0x78a3, 0x0000, 0x681c,
-+	0xa085, 0x0040, 0x681e, 0x71a8, 0xa188, 0x00d9, 0xa006, 0x6826,
-+	0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822,
-+	0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x2c5e, 0x6eb6, 0x1078, 0x4781,
-+	0x6810, 0x70b2, 0x7003, 0x0007, 0x7097, 0x0000, 0x7053, 0x0000,
-+	0x0078, 0x2c5e, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00, 0x0000,
-+	0x0000, 0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837, 0x0000,
-+	0xa684, 0x0200, 0x0040, 0x508b, 0x78b8, 0xa08c, 0x001f, 0xa084,
-+	0x8000, 0x0040, 0x5084, 0x8108, 0x78d8, 0xa100, 0x6836, 0x78dc,
-+	0xa081, 0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac, 0x0007,
-+	0x2021, 0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-+	0xa184, 0x0080, 0x00c0, 0x50ba, 0xa182, 0x0020, 0x00c8, 0x50d8,
-+	0xa182, 0x0012, 0x00c8, 0x5496, 0x2100, 0x1079, 0x50a8, 0x007c,
-+	0x5496, 0x52eb, 0x5496, 0x5496, 0x50e5, 0x50e8, 0x512f, 0x516d,
-+	0x51a1, 0x51a4, 0x5496, 0x5496, 0x5150, 0x5213, 0x524d, 0x5496,
-+	0x5496, 0x5274, 0xa184, 0x0020, 0x00c0, 0x52a8, 0xa18c, 0x001f,
-+	0x6814, 0xa084, 0x001f, 0xa106, 0x0040, 0x50d5, 0x70a8, 0xa080,
-+	0x0085, 0x781a, 0x2001, 0x0014, 0x1078, 0x54ae, 0x1078, 0x552c,
-+	0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c,
-+	0xa182, 0x0024, 0x00c8, 0x5496, 0xa184, 0x0003, 0x1079, 0x50a8,
-+	0x007c, 0x5496, 0x5496, 0x5496, 0x5496, 0x1078, 0x5496, 0x007c,
-+	0x2200, 0x0079, 0x50eb, 0x5277, 0x5277, 0x511c, 0x511c, 0x511c,
-+	0x511c, 0x511c, 0x511c, 0x511c, 0x511c, 0x511a, 0x511c, 0x5104,
-+	0x510d, 0x510d, 0x510d, 0x511c, 0x511c, 0x5124, 0x5127, 0x5277,
-+	0x5127, 0x511c, 0x511c, 0x511c, 0x0c7e, 0x077e, 0x6f14, 0x1078,
-+	0x42de, 0x077f, 0x0c7f, 0x0078, 0x511c, 0x6818, 0xd0a4, 0x0040,
-+	0x511c, 0x6827, 0x0033, 0x1078, 0x54ae, 0x1078, 0x552c, 0x2001,
-+	0x0001, 0x007c, 0x1078, 0x53ae, 0x6827, 0x02b3, 0x2009, 0x000b,
-+	0x2001, 0x4800, 0x0078, 0x52ab, 0x1078, 0x5486, 0x007c, 0x6827,
-+	0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x5293, 0x2d58,
-+	0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x5139, 0x6807,
-+	0x0117, 0x6827, 0x0002, 0x1078, 0x5539, 0x6827, 0x0036, 0x6932,
-+	0x2d00, 0x682e, 0x0d7e, 0x1078, 0x4751, 0x1078, 0x52d3, 0x2b68,
-+	0x1078, 0x4781, 0x0d7f, 0x1078, 0x4781, 0x2001, 0x0002, 0x007c,
-+	0x1078, 0x52d3, 0x2001, 0x0017, 0x1078, 0x54ae, 0x7097, 0x0000,
-+	0x6914, 0xd1fc, 0x0040, 0x5160, 0x2009, 0x6086, 0x0078, 0x5162,
-+	0x2009, 0x6046, 0x200b, 0x0006, 0x70a3, 0x0017, 0x2009, 0x0200,
-+	0x1078, 0x463f, 0x2001, 0x0001, 0x007c, 0x2200, 0x0079, 0x5170,
-+	0x5277, 0x52a8, 0x52a8, 0x52a8, 0x5191, 0x52ba, 0x5199, 0x52ba,
-+	0x52ba, 0x52bd, 0x52bd, 0x52c2, 0x52c2, 0x5189, 0x5189, 0x52a8,
-+	0x52a8, 0x52ba, 0x52a8, 0x5199, 0x5277, 0x5199, 0x5199, 0x5199,
-+	0x5199, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
-+	0x52cc, 0x6827, 0x000d, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
-+	0x52ab, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
-+	0x5293, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079, 0x51a7, 0x5277,
-+	0x520b, 0x520b, 0x520b, 0x520b, 0x51c0, 0x51c0, 0x51c0, 0x51c0,
-+	0x51c0, 0x51c0, 0x51c0, 0x51c0, 0x520b, 0x520b, 0x520b, 0x520b,
-+	0x51e8, 0x520b, 0x520b, 0x51e8, 0x51e8, 0x51e8, 0x51e8, 0x5277,
-+	0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x51e8, 0x690c,
-+	0xa184, 0x000f, 0x0040, 0x52ba, 0x8001, 0x0040, 0x51d5, 0xa18c,
-+	0xfff0, 0xa105, 0x680e, 0x0078, 0x52ba, 0x70a8, 0xa080, 0x0085,
-+	0x781a, 0x6827, 0x000f, 0x1078, 0x4f59, 0x1078, 0x54ae, 0x7003,
-+	0x0000, 0x7043, 0x0000, 0x7053, 0x0000, 0x2001, 0x0002, 0x007c,
-+	0x6918, 0xa184, 0x000f, 0x0040, 0x52ba, 0x8001, 0x0040, 0x51f6,
-+	0xa18c, 0xfff0, 0xa105, 0x681a, 0x0078, 0x52ba, 0x70a8, 0xa080,
-+	0x0085, 0x781a, 0x6827, 0x008f, 0x2009, 0x000b, 0x2001, 0x4300,
-+	0x1078, 0x54df, 0x1078, 0x54ae, 0x1078, 0x552c, 0x7003, 0x0000,
-+	0x2001, 0x0002, 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x0078, 0x5293, 0xa684, 0x0004, 0x00c0, 0x5227, 0x6804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x5496, 0x1078, 0x52d3,
-+	0x6807, 0x0117, 0x1078, 0x4781, 0x2001, 0x0002, 0x007c, 0x6000,
-+	0xa084, 0x0004, 0x0040, 0x5496, 0x2d58, 0x6804, 0xa084, 0x00ff,
-+	0xa086, 0x0006, 0x00c0, 0x5236, 0x6807, 0x0117, 0x6827, 0x0002,
-+	0x1078, 0x5539, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e,
-+	0x1078, 0x4760, 0x1078, 0x52d3, 0x2b68, 0x1078, 0x4781, 0x0d7f,
-+	0x1078, 0x4781, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004,
-+	0x0040, 0x5496, 0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006,
-+	0x00c0, 0x525c, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078,
-+	0x5539, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
-+	0x4770, 0x1078, 0x52d3, 0x2b68, 0x1078, 0x4781, 0x0d7f, 0x1078,
-+	0x4781, 0x2001, 0x0002, 0x007c, 0x1078, 0x5496, 0x007c, 0x70a8,
-+	0xa080, 0x0085, 0x781a, 0x2001, 0x0001, 0x1078, 0x54ae, 0x1078,
-+	0x552c, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x54df,
-+	0x1078, 0x552b, 0x1078, 0x5074, 0x1078, 0x4f59, 0x1078, 0x552c,
-+	0x2001, 0x0001, 0x007c, 0x1078, 0x54df, 0x1078, 0x552b, 0x1078,
-+	0x5074, 0x70a8, 0xa080, 0x0085, 0x781a, 0x2001, 0x0013, 0x1078,
-+	0x54ae, 0x1078, 0x552c, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c,
-+	0x1078, 0x5496, 0x007c, 0x1078, 0x54df, 0x1078, 0x552b, 0x1078,
-+	0x5074, 0x1078, 0x4f59, 0x1078, 0x552c, 0x1078, 0x5572, 0x2001,
-+	0x0001, 0x007c, 0x2001, 0x0003, 0x007c, 0x1078, 0x53ae, 0x2001,
-+	0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x42de, 0x077f,
-+	0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, 0x54df, 0x1078, 0x5496,
-+	0x2001, 0x0006, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x52de, 0xa186, 0x000f, 0x00c0, 0x52e2, 0x1078, 0x552b,
-+	0x1078, 0x5074, 0x70a8, 0xa080, 0x0085, 0x781a, 0x1078, 0x552c,
-+	0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
-+	0x00ff, 0xa08a, 0x0004, 0x00c8, 0x5496, 0x1079, 0x52f8, 0x007c,
-+	0x5496, 0x52fc, 0x5496, 0x53b5, 0xa282, 0x0003, 0x0040, 0x5303,
-+	0x1078, 0x5496, 0x007c, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4,
-+	0x00ff, 0x69b8, 0xa184, 0x0100, 0x0040, 0x5342, 0xa18c, 0xfeff,
-+	0x69ba, 0x78a0, 0xa005, 0x00c0, 0x5342, 0xa4a4, 0x00ff, 0x0040,
-+	0x5336, 0xa482, 0x000c, 0x0040, 0x531f, 0x00c8, 0x5329, 0x852b,
-+	0x852b, 0x1078, 0x4334, 0x0040, 0x5329, 0x1078, 0x4162, 0x0078,
-+	0x5338, 0x1078, 0x5474, 0x1078, 0x418d, 0x69b8, 0xa18d, 0x0100,
-+	0x69ba, 0xa6b5, 0x1000, 0x7e5a, 0x0078, 0x533b, 0x1078, 0x418d,
-+	0xa6b4, 0xefff, 0x7e5a, 0x70a8, 0xa080, 0x0097, 0x781a, 0x2001,
-+	0x0001, 0x007c, 0x0c7e, 0x1078, 0x539c, 0x6200, 0xd2e4, 0x0040,
-+	0x538b, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
-+	0x5355, 0x0040, 0x5355, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8,
-+	0x535a, 0x2220, 0x6208, 0xa294, 0x00ff, 0x2001, 0x6003, 0x2004,
-+	0xd0e4, 0x00c0, 0x536f, 0x78ec, 0xd0e4, 0x0040, 0x536f, 0xa282,
-+	0x000a, 0x00c8, 0x5375, 0x2011, 0x000a, 0x0078, 0x5375, 0xa282,
-+	0x000c, 0x00c8, 0x5375, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8,
-+	0x537a, 0x2228, 0x1078, 0x5477, 0x2500, 0xa086, 0x000a, 0x0040,
-+	0x5383, 0x852b, 0x852b, 0x1078, 0x4334, 0x0040, 0x538b, 0x1078,
-+	0x4169, 0x0078, 0x538f, 0x1078, 0x5474, 0x1078, 0x4194, 0xa6b5,
-+	0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080, 0x00c4, 0x781a,
-+	0x2001, 0x0004, 0x0c7f, 0x007c, 0x6814, 0x8007, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0x6914, 0xd1fc, 0x00c0, 0x53ab, 0xa0e0,
-+	0x64c0, 0x0078, 0x53ad, 0xa0e0, 0x6540, 0x007c, 0x0c7e, 0x1078,
-+	0x539c, 0x1078, 0x4194, 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0,
-+	0x5496, 0x7aa8, 0xa294, 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040,
-+	0x53ec, 0xa18c, 0xfdff, 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x53ec,
-+	0xa282, 0x0002, 0x00c8, 0x429c, 0x1078, 0x544c, 0x1078, 0x4227,
-+	0x1078, 0x418d, 0xa684, 0x0100, 0x0040, 0x53e2, 0x682c, 0xa084,
-+	0x0001, 0x0040, 0x53e2, 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040,
-+	0x53e2, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70a8, 0xa080, 0x0097,
-+	0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e, 0x1078, 0x539c, 0xa284,
-+	0xfffe, 0x0040, 0x53f7, 0x2011, 0x0001, 0x0078, 0x53fb, 0xa284,
-+	0x0001, 0x0040, 0x5401, 0x6100, 0xd1ec, 0x00c0, 0x5401, 0x2011,
-+	0x0000, 0x1078, 0x543e, 0x1078, 0x422e, 0x1078, 0x4194, 0xa684,
-+	0x0100, 0x0040, 0x5417, 0x682c, 0xa084, 0x0001, 0x0040, 0x5417,
-+	0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x5417, 0xc6fd, 0xa6b5,
-+	0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080, 0x00c4, 0x781a,
-+	0x2001, 0x0004, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6000, 0x2011,
-+	0x0001, 0xa084, 0x2000, 0x00c0, 0x542f, 0x2011, 0x0000, 0x78ab,
-+	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004,
-+	0x68b8, 0xa085, 0x0200, 0x68ba, 0x0c7f, 0x007c, 0x789b, 0x0018,
-+	0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b,
-+	0x0081, 0x78ab, 0x0004, 0x007c, 0x0c7e, 0x705c, 0x2060, 0x6000,
-+	0xa084, 0x1000, 0x00c0, 0x545a, 0x2029, 0x0032, 0x2021, 0x0000,
-+	0x0078, 0x546c, 0x6408, 0xa4ac, 0x00ff, 0xa582, 0x000c, 0x00c8,
-+	0x5463, 0x2029, 0x000c, 0x8427, 0xa4a4, 0x00ff, 0xa482, 0x000c,
-+	0x0048, 0x546c, 0x2021, 0x000c, 0x1078, 0x5477, 0x68b8, 0xa085,
-+	0x0100, 0x68ba, 0x0c7f, 0x007c, 0xa026, 0x2029, 0x0032, 0x789b,
-+	0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-+	0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003,
-+	0x1078, 0x54a6, 0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8,
-+	0xa080, 0x00c4, 0x781a, 0x2001, 0x0005, 0x007c, 0x2001, 0x0007,
-+	0x1078, 0x54a6, 0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8,
-+	0xa080, 0x00c4, 0x781a, 0x2001, 0x0004, 0x007c, 0x789b, 0x0018,
-+	0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904, 0xa18c,
-+	0x00ff, 0xa196, 0x0007, 0x0040, 0x54bc, 0xa196, 0x000f, 0x0040,
-+	0x54bc, 0x1078, 0x1e55, 0x007c, 0x6924, 0xa194, 0x003f, 0x00c0,
-+	0x54c5, 0xa18c, 0xffc0, 0xa105, 0x6826, 0x1078, 0x4781, 0x691c,
-+	0xa184, 0x0100, 0x0040, 0x54d3, 0x6914, 0x2100, 0x1078, 0x47fa,
-+	0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112,
-+	0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e,
-+	0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f,
-+	0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f,
-+	0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826,
-+	0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0,
-+	0x81ac, 0x0040, 0x5504, 0x53a6, 0xa184, 0x0001, 0x0040, 0x550a,
-+	0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70a4, 0x0e7e,
-+	0x007e, 0x007f, 0x0e7f, 0xa005, 0x6918, 0x017e, 0x6914, 0x017e,
-+	0x6928, 0x017e, 0x017f, 0x017f, 0x017f, 0x10c0, 0x2bfa, 0x70a7,
-+	0x8000, 0x6814, 0xd0fc, 0x0040, 0x5528, 0xc185, 0x0078, 0x5529,
-+	0xc184, 0x0078, 0x591e, 0x007c, 0x71a4, 0x81ff, 0x0040, 0x5538,
-+	0x7848, 0xa085, 0x0008, 0x784a, 0x70a7, 0x0000, 0x1078, 0x55ac,
-+	0x007c, 0x0c7e, 0x0d7e, 0x1078, 0x1e32, 0x0c7f, 0x157e, 0x137e,
-+	0x147e, 0x2da0, 0x2c98, 0x20a9, 0x0037, 0x53a3, 0x147f, 0x137f,
-+	0x157f, 0x6807, 0x010d, 0x680b, 0x0000, 0x701c, 0x8007, 0x681a,
-+	0x6823, 0x0000, 0x681f, 0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c,
-+	0x70a8, 0xa080, 0x0097, 0x781a, 0x0078, 0x2c5e, 0x70a8, 0xa080,
-+	0x0088, 0x781a, 0x0078, 0x2c5e, 0x783b, 0x1700, 0x70a8, 0xa080,
-+	0x00c4, 0x781a, 0x0078, 0x2c5e, 0x70a8, 0xa080, 0x00cd, 0x781a,
-+	0x0078, 0x2c5e, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040,
-+	0x557f, 0xa196, 0x000f, 0x0040, 0x557f, 0x6807, 0x0117, 0x6824,
-+	0xa084, 0x00ff, 0xa085, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e,
-+	0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6,
-+	0x7e5a, 0x71a8, 0xa188, 0x0097, 0x791a, 0x007c, 0x1078, 0x552c,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x70a8, 0xa080, 0x0085, 0x781a,
-+	0x2009, 0x000b, 0x2001, 0x4400, 0x1078, 0x54df, 0x2001, 0x0013,
-+	0x1078, 0x54ae, 0x0078, 0x4856, 0x127e, 0x70f0, 0xa084, 0x4600,
-+	0x8004, 0x2090, 0x7204, 0x700c, 0xa215, 0x7008, 0xc09c, 0xa205,
-+	0x00c0, 0x55c1, 0x7007, 0x0004, 0x7003, 0x0000, 0x127f, 0x2000,
-+	0x007c, 0x7000, 0xd084, 0x0040, 0x5600, 0x7108, 0x0005, 0x7008,
-+	0xa106, 0x00c0, 0x55c5, 0xa184, 0x0003, 0x0040, 0x562c, 0xa184,
-+	0x01e0, 0x00c0, 0x562c, 0xd1f4, 0x00c0, 0x55c5, 0xa184, 0x3000,
-+	0xa086, 0x1000, 0x0040, 0x55c5, 0x2011, 0x0180, 0x710c, 0x8211,
-+	0x0040, 0x55ea, 0x7008, 0xd0f4, 0x00c0, 0x55c5, 0x700c, 0xa106,
-+	0x0040, 0x55df, 0x7007, 0x0012, 0x7108, 0x0005, 0x7008, 0xa106,
-+	0x00c0, 0x55ec, 0xa184, 0x0003, 0x0040, 0x562c, 0xd194, 0x0040,
-+	0x55ec, 0xd1f4, 0x0040, 0x562c, 0x7007, 0x0002, 0x0078, 0x55c5,
-+	0x7108, 0xd1fc, 0x0040, 0x560b, 0x1078, 0x5792, 0x8aff, 0x0040,
-+	0x55b2, 0x0078, 0x5600, 0x700c, 0xa08c, 0x03ff, 0x0040, 0x5631,
-+	0x7004, 0xd084, 0x0040, 0x5623, 0x7014, 0xa005, 0x00c0, 0x561f,
-+	0x7010, 0xa005, 0x0040, 0x5623, 0xa102, 0x00c8, 0x5600, 0x7007,
-+	0x0010, 0x0078, 0x562c, 0x8aff, 0x0040, 0x5631, 0x1078, 0x5a15,
-+	0x00c0, 0x5626, 0x0040, 0x5600, 0x1078, 0x56da, 0x127f, 0x2000,
-+	0x007c, 0x7204, 0x700c, 0xa215, 0x7108, 0xc19c, 0x8103, 0x00c8,
-+	0x5640, 0xa205, 0x00c0, 0x562c, 0x7007, 0x0002, 0x0078, 0x5631,
-+	0xa205, 0x00c0, 0x562c, 0x7003, 0x0000, 0x7007, 0x0004, 0x127f,
-+	0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x5656, 0xa18e, 0x000f, 0x00c0, 0x5659, 0x6040, 0x0078,
-+	0x565a, 0x6428, 0x017f, 0x84ff, 0x0040, 0x5684, 0x2c70, 0x7004,
-+	0xa0bc, 0x000f, 0xa7b8, 0x5694, 0x273c, 0x87fb, 0x00c0, 0x5672,
-+	0x0048, 0x566c, 0x1078, 0x2bfa, 0x609c, 0xa075, 0x0040, 0x5684,
-+	0x0078, 0x565f, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529,
-+	0x8421, 0x0040, 0x5684, 0x8738, 0x2704, 0xa005, 0x00c0, 0x5673,
-+	0x709c, 0xa075, 0x00c0, 0x565f, 0x007c, 0x0000, 0x0005, 0x0009,
-+	0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009,
-+	0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x5689, 0x5686, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x5689, 0x0000, 0x5691, 0x568e, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x5691, 0x0000, 0x568c, 0x568c, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x568c, 0x0000, 0x5692, 0x5692, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x5692, 0x2079, 0x6000, 0x2071, 0x0010,
-+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x7808, 0xd0ec,
-+	0x0040, 0x56c8, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, 0x56cc,
-+	0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002,
-+	0x7003, 0x0000, 0x8109, 0x0040, 0x56d9, 0x2071, 0x0020, 0x0078,
-+	0x56cc, 0x007c, 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x5761,
-+	0x7108, 0x7008, 0xa106, 0x00c0, 0x56e0, 0xa184, 0x01e0, 0x0040,
-+	0x56ed, 0x1078, 0x57d8, 0x0078, 0x5789, 0x7007, 0x0012, 0x7108,
-+	0x7008, 0xa106, 0x00c0, 0x56ef, 0xa184, 0x01e0, 0x0040, 0x56fa,
-+	0x1078, 0x57d8, 0x7808, 0xd0ec, 0x0040, 0x5714, 0x2001, 0x04fd,
-+	0x2004, 0xa086, 0x0003, 0x00c0, 0x5718, 0xa184, 0x4000, 0x0040,
-+	0x571c, 0xa382, 0x0003, 0x00c8, 0x571c, 0xa184, 0x0004, 0x0040,
-+	0x56ef, 0x8318, 0x0078, 0x56ef, 0x780c, 0xd0ec, 0x00c0, 0x571c,
-+	0xa184, 0x4000, 0x00c0, 0x56ef, 0xa19c, 0x300c, 0xa386, 0x2004,
-+	0x0040, 0x5739, 0xa386, 0x0008, 0x0040, 0x5744, 0x7004, 0xd084,
-+	0x00c0, 0x5735, 0x7108, 0x7008, 0xa106, 0x00c0, 0x572a, 0xa184,
-+	0x0003, 0x0040, 0x5735, 0x0078, 0x57d8, 0xa386, 0x200c, 0x00c0,
-+	0x56ef, 0x7200, 0x8204, 0x0048, 0x5744, 0x730c, 0xa384, 0x03ff,
-+	0x0040, 0x5744, 0x1078, 0x2bfa, 0x7108, 0x7008, 0xa106, 0x00c0,
-+	0x5744, 0xa184, 0x01e0, 0x0040, 0x5751, 0x1078, 0x57d8, 0x0078,
-+	0x5789, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x5761, 0x7310,
-+	0x7014, 0xa305, 0x0040, 0x5761, 0x710c, 0xa184, 0x03ff, 0x00c0,
-+	0x56da, 0x7108, 0x7008, 0xa106, 0x00c0, 0x5761, 0xa184, 0x01e0,
-+	0x0040, 0x576e, 0x1078, 0x57d8, 0x0078, 0x5789, 0x7007, 0x0012,
-+	0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x5772, 0x7108, 0x7008,
-+	0xa106, 0x00c0, 0x5776, 0xa184, 0x01e0, 0x0040, 0x5783, 0x1078,
-+	0x57d8, 0x0078, 0x5789, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0,
-+	0x5776, 0x7003, 0x0000, 0x007c, 0x157e, 0x7108, 0x1078, 0x5792,
-+	0x157f, 0x007c, 0x7204, 0x7500, 0xa184, 0x01e0, 0x00c0, 0x57d8,
-+	0x7108, 0xa184, 0x01e0, 0x00c0, 0x57d8, 0xa184, 0x0007, 0x0079,
-+	0x57a1, 0x57ab, 0x57bc, 0x57a9, 0x57bc, 0x57a9, 0x582f, 0x57a9,
-+	0x582d, 0x1078, 0x2bfa, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006,
-+	0x8aff, 0x00c0, 0x57b7, 0x2049, 0x0000, 0x0078, 0x57bb, 0x1078,
-+	0x5a15, 0x00c0, 0x57b7, 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d,
-+	0x7006, 0x7004, 0xd084, 0x00c0, 0x57d0, 0x7108, 0x7008, 0xa106,
-+	0x00c0, 0x57c5, 0xa184, 0x0003, 0x0040, 0x57d0, 0x0078, 0x57d8,
-+	0x8aff, 0x0040, 0x57d7, 0x1078, 0x5a15, 0x00c0, 0x57d3, 0x007c,
-+	0x7007, 0x0012, 0x7108, 0x00e0, 0x57db, 0x2091, 0x6000, 0x00e0,
-+	0x57df, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
-+	0xd09c, 0x00c0, 0x57e7, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0,
-+	0x57eb, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x57ff, 0x7004,
-+	0xa005, 0x00c0, 0x57ff, 0x700c, 0xa005, 0x0040, 0x5801, 0x0078,
-+	0x57e3, 0x2049, 0x0000, 0xb284, 0x0100, 0x0040, 0x580b, 0x2001,
-+	0x0000, 0x0078, 0x580d, 0x2001, 0x0001, 0x1078, 0x43c9, 0xb284,
-+	0x0100, 0x0040, 0x5817, 0x2001, 0x6064, 0x0078, 0x5819, 0x2001,
-+	0x60a4, 0x2004, 0xa084, 0x8000, 0x0040, 0x5826, 0x6824, 0xa005,
-+	0x00c0, 0x5828, 0x6827, 0x0004, 0x0078, 0x5828, 0x681b, 0x0002,
-+	0x007c, 0x1078, 0x2bfa, 0x1078, 0x2bfa, 0x1078, 0x5877, 0x7210,
-+	0x7114, 0x700c, 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189,
-+	0x0000, 0x1078, 0x5877, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
-+	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x5852,
-+	0x00c8, 0x5852, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60,
-+	0x0078, 0x5839, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008,
-+	0x0040, 0x585e, 0xa7ba, 0x568e, 0x0078, 0x5860, 0xa7ba, 0x5686,
-+	0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108,
-+	0x7008, 0xa106, 0x00c0, 0x5867, 0xa184, 0x01e0, 0x0040, 0x5872,
-+	0x1078, 0x57d8, 0x7007, 0x0012, 0x1078, 0x56da, 0x007c, 0x8a50,
-+	0x8739, 0x2704, 0xa004, 0x00c0, 0x588b, 0x6000, 0xa064, 0x00c0,
-+	0x5882, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x56a4, 0x203c,
-+	0x87fb, 0x1040, 0x2bfa, 0x007c, 0x127e, 0x0d7e, 0x70f0, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c,
-+	0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804,
-+	0xa084, 0x0008, 0x007f, 0x0040, 0x58a9, 0xa0b8, 0x568e, 0x0078,
-+	0x58ab, 0xa0b8, 0x5686, 0xb284, 0x0100, 0x0040, 0x58b2, 0x7e18,
-+	0x0078, 0x58b3, 0x7e1c, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff,
-+	0xa186, 0x0007, 0x0040, 0x58c0, 0xa18e, 0x000f, 0x00c0, 0x58c8,
-+	0x681c, 0xa084, 0x0040, 0x0040, 0x58cd, 0xc685, 0x0078, 0x58cd,
-+	0x681c, 0xd0b4, 0x0040, 0x58cd, 0xc685, 0x700c, 0xa084, 0x03ff,
-+	0x0040, 0x58d8, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x58d4,
-+	0x2400, 0xa305, 0x00c0, 0x58de, 0x0078, 0x5904, 0x2c58, 0x2704,
-+	0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e,
-+	0xa184, 0x0008, 0x0040, 0x58f4, 0x6010, 0xa081, 0x0000, 0x7022,
-+	0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012,
-+	0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60,
-+	0x1078, 0x5a43, 0x0078, 0x5906, 0x1078, 0x5a15, 0x00c0, 0x5904,
-+	0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70f0, 0xa084, 0x4600,
-+	0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0,
-+	0x5915, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e,
-+	0x70f0, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x700c, 0xa084,
-+	0x03ff, 0x0040, 0x5931, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0,
-+	0x592d, 0x6814, 0xd0fc, 0x0040, 0x5938, 0x7e1c, 0x0078, 0x5939,
-+	0x7e18, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x5946, 0xa18e, 0x000f, 0x00c0, 0x5950, 0x681c, 0xa084,
-+	0x0040, 0x0040, 0x594c, 0xc685, 0x6840, 0x2050, 0x0078, 0x5957,
-+	0x681c, 0xd0ac, 0x00c0, 0x5955, 0xc685, 0x6828, 0x2050, 0x2d60,
-+	0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x5694, 0x273c, 0x87fb, 0x00c0,
-+	0x596b, 0x0048, 0x5965, 0x1078, 0x2bfa, 0x689c, 0xa065, 0x0040,
-+	0x596f, 0x0078, 0x5958, 0x1078, 0x5a15, 0x00c0, 0x596b, 0x127f,
-+	0x2000, 0x007c, 0x127e, 0x007e, 0x017e, 0x0d7e, 0x70f0, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0xb284, 0x0100, 0x0040, 0x5982, 0x7e18,
-+	0x0078, 0x5983, 0x7e1c, 0x0d7f, 0x037f, 0x047f, 0xa6b5, 0x000c,
-+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x5993, 0xa18e,
-+	0x000f, 0x00c0, 0x599b, 0x681c, 0xa084, 0x0040, 0x0040, 0x59a0,
-+	0xc685, 0x0078, 0x59a0, 0x681c, 0xd0b4, 0x0040, 0x59a0, 0xc685,
-+	0x2049, 0x5972, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x59ae, 0xa18e, 0x000f, 0x00c0, 0x59b1, 0x6840, 0x0078,
-+	0x59b2, 0x6828, 0x017f, 0xa055, 0x0d7e, 0x0040, 0x5a11, 0x2d70,
-+	0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x5694, 0x273c, 0x87fb,
-+	0x00c0, 0x59cd, 0x0048, 0x59c6, 0x1078, 0x2bfa, 0x709c, 0xa075,
-+	0x2060, 0x0040, 0x5a11, 0x0078, 0x59b9, 0x2704, 0xae68, 0x6808,
-+	0xa422, 0x680c, 0xa31b, 0x0048, 0x59e6, 0x8a51, 0x00c0, 0x59da,
-+	0x1078, 0x2bfa, 0x8738, 0x2704, 0xa005, 0x00c0, 0x59ce, 0x709c,
-+	0xa075, 0x2060, 0x0040, 0x5a11, 0x0078, 0x59b9, 0x8422, 0x8420,
-+	0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
-+	0xa11b, 0x00c8, 0x59f5, 0x1078, 0x2bfa, 0x017e, 0x3208, 0xa18c,
-+	0x0100, 0x0040, 0x5a0b, 0x007e, 0x2001, 0x6002, 0x2004, 0xd0ec,
-+	0x007f, 0x0040, 0x5a07, 0x2071, 0x0020, 0x0078, 0x5a0d, 0x2071,
-+	0x0050, 0x0078, 0x5a0d, 0x2071, 0x0020, 0x017f, 0x0d7f, 0x0078,
-+	0x58cd, 0x0d7f, 0x127f, 0x2000, 0x007c, 0x7008, 0x007e, 0xa084,
-+	0x01e0, 0x007f, 0x0040, 0x5a1e, 0xa006, 0x007c, 0xa084, 0x0003,
-+	0xa086, 0x0003, 0x00c0, 0x5a25, 0x007c, 0x2704, 0xac08, 0x2104,
-+	0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108,
-+	0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x5a3d, 0x8108,
-+	0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602, 0x7004, 0xa084,
-+	0x0010, 0xc085, 0x7006, 0x8738, 0x2704, 0xa005, 0x00c0, 0x5a56,
-+	0x609c, 0xa005, 0x0040, 0x5a68, 0x2060, 0x6004, 0xa084, 0x000f,
-+	0xa080, 0x5694, 0x203c, 0x87fb, 0x1040, 0x2bfa, 0x8a51, 0x0040,
-+	0x5a67, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x5a63,
-+	0xa006, 0x0078, 0x5a68, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c,
-+	0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70f0, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003,
-+	0x00c0, 0x5a90, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-+	0x0040, 0x5a86, 0xa18e, 0x000f, 0x00c0, 0x5a89, 0x6840, 0x0078,
-+	0x5a8a, 0x6828, 0x017f, 0xa005, 0x0040, 0x5aa0, 0x0078, 0x55c1,
-+	0x7108, 0xd1fc, 0x0040, 0x5a98, 0x1078, 0x5792, 0x0078, 0x5a75,
-+	0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x5a9a, 0x1078, 0x5792,
-+	0x7008, 0xa086, 0x0008, 0x00c0, 0x5a75, 0x7000, 0xa005, 0x00c0,
-+	0x5a75, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-+	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70f0, 0xa084,
-+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x5ab0, 0x69b0, 0xad80,
-+	0x0011, 0xa100, 0x20a0, 0xb284, 0x0100, 0x0040, 0x5ad5, 0x2001,
-+	0x6002, 0x2004, 0xd0ec, 0x0040, 0x5ad1, 0x2099, 0x0031, 0x0078,
-+	0x5ad7, 0x2099, 0x0032, 0x0078, 0x5ad7, 0x2099, 0x0031, 0x700c,
-+	0xa084, 0x03ff, 0x0040, 0x5af5, 0x6928, 0xa100, 0x682a, 0x7007,
-+	0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040, 0x5aea, 0x8000,
-+	0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040, 0x5af5, 0x7007,
-+	0x0004, 0x7004, 0xd094, 0x00c0, 0x5af1, 0x0c7f, 0x2049, 0x0000,
-+	0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000, 0x007c,
-+	0x2091, 0x6000, 0x2091, 0x8000, 0x78b0, 0xa005, 0x00c0, 0x5b17,
-+	0x7970, 0x70d0, 0xa106, 0x00c0, 0x5b17, 0x7814, 0xa005, 0x0040,
-+	0x5b17, 0x7817, 0x0000, 0x0068, 0x5b17, 0x2091, 0x4080, 0x7828,
-+	0x8001, 0x782a, 0x00c0, 0x5b9f, 0x782c, 0x782a, 0x7808, 0xd0ec,
-+	0x00c0, 0x5b98, 0x2061, 0x85c0, 0x2069, 0x6080, 0xc7fd, 0x68ec,
-+	0xa005, 0x0040, 0x5b32, 0x8001, 0x68ee, 0xa005, 0x00c0, 0x5b32,
-+	0x1078, 0x5d6b, 0x6800, 0xa084, 0x000f, 0x0040, 0x5b47, 0xa086,
-+	0x0001, 0x0040, 0x5b47, 0x6840, 0xa00d, 0x0040, 0x5b47, 0x2104,
-+	0xa005, 0x0040, 0x5b47, 0x8001, 0x200a, 0x0040, 0x5cc9, 0x6810,
-+	0xa005, 0x0040, 0x5b6b, 0x8001, 0x6812, 0x00c0, 0x5b6b, 0x68c3,
-+	0x0001, 0xd7fc, 0x00c0, 0x5b60, 0x7808, 0xd0ec, 0x0040, 0x5b5c,
-+	0x2009, 0x0102, 0x0078, 0x5b62, 0x2009, 0x0202, 0x0078, 0x5b62,
-+	0x2009, 0x0102, 0x684c, 0xc08d, 0x200a, 0x6868, 0xa005, 0x0040,
-+	0x5b6b, 0x1078, 0x2852, 0x6884, 0xa005, 0x0040, 0x5b78, 0x8001,
-+	0x6886, 0x00c0, 0x5b78, 0x686b, 0x0000, 0x68f0, 0xc0dd, 0x68f2,
-+	0x68f0, 0xd0fc, 0x0040, 0x5b95, 0xc0fc, 0x68f2, 0x20a9, 0x0200,
-+	0x6034, 0xa005, 0x0040, 0x5b91, 0x8001, 0x6036, 0x68f0, 0xc0fd,
-+	0x68f2, 0x00c0, 0x5b91, 0x6010, 0xa005, 0x0040, 0x5b91, 0x1078,
-+	0x2852, 0xace0, 0x0010, 0x00f0, 0x5b80, 0xd7fc, 0x0040, 0x5b9f,
-+	0x2061, 0x65c0, 0x2069, 0x6040, 0xc7fc, 0x0078, 0x5b27, 0x1078,
-+	0x5bc8, 0x7830, 0x8001, 0x7832, 0x00c0, 0x5bc1, 0x7834, 0x7832,
-+	0x2061, 0x65c0, 0x2069, 0x6040, 0xc7fc, 0x6808, 0xa005, 0x0040,
-+	0x5bb3, 0x1078, 0x5c32, 0xd7fc, 0x00c0, 0x5bc1, 0x7808, 0xd0ec,
-+	0x00c0, 0x5bc1, 0x2061, 0x85c0, 0x2069, 0x6080, 0xc7fd, 0x0078,
-+	0x5bad, 0x780c, 0xd0e4, 0x00c0, 0x5bc5, 0x2091, 0x8001, 0x007c,
-+	0x7838, 0x8001, 0x783a, 0x00c0, 0x5c31, 0x783c, 0x783a, 0x2069,
-+	0x6040, 0xc7fc, 0x7808, 0x2079, 0x0200, 0xd0ec, 0x0040, 0x5bda,
-+	0x2079, 0x0100, 0x68f8, 0xa005, 0x0040, 0x5be6, 0x7de0, 0xa504,
-+	0x00c0, 0x5be6, 0x68fa, 0x68f0, 0xc0bc, 0x68f2, 0x2079, 0x6000,
-+	0x680c, 0xa005, 0x00c0, 0x5bee, 0x2001, 0x0101, 0x8001, 0x680e,
-+	0xd7fc, 0x00c0, 0x5bf7, 0xa080, 0xa5c0, 0x0078, 0x5bf9, 0xa080,
-+	0xa6d0, 0x2040, 0x2004, 0xa065, 0x0040, 0x5c23, 0x6024, 0xa005,
-+	0x0040, 0x5c1f, 0x8001, 0x6026, 0x00c0, 0x5c1f, 0x6800, 0xa005,
-+	0x0040, 0x5c12, 0x6850, 0xac06, 0x00c0, 0x5c12, 0x1078, 0x5cc9,
-+	0x0078, 0x5c23, 0x6868, 0xa005, 0x0040, 0x5c1a, 0x6027, 0x0001,
-+	0x0078, 0x5c1f, 0x1078, 0x5c7c, 0x2804, 0x0078, 0x5bfb, 0x6000,
-+	0x2c40, 0x0078, 0x5bfb, 0xd7fc, 0x00c0, 0x5c31, 0x7808, 0xd0ec,
-+	0x00c0, 0x5c31, 0x2069, 0x6080, 0xc7fd, 0x2079, 0x0100, 0x0078,
-+	0x5bda, 0x007c, 0xa00e, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040,
-+	0x5c6b, 0x6024, 0xa005, 0x0040, 0x5c41, 0x8001, 0x6026, 0x0078,
-+	0x5c69, 0x6008, 0xc09c, 0xd084, 0x00c0, 0x5c49, 0xd0ac, 0x0040,
-+	0x5c63, 0x600a, 0x6004, 0xa005, 0x0040, 0x5c6b, 0x0d7e, 0x0c7e,
-+	0x017e, 0x2068, 0x6010, 0x8001, 0x6012, 0x1078, 0x3fd3, 0x2d00,
-+	0x2c68, 0x2060, 0x1078, 0x1ef5, 0x1078, 0x2240, 0x017f, 0x0c7f,
-+	0x0d7f, 0x0078, 0x5c6b, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078,
-+	0x5c6b, 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x5c35, 0xa184,
-+	0x0001, 0x0040, 0x5c7a, 0xa18c, 0xfffe, 0x690a, 0x1078, 0x2852,
-+	0x0078, 0x5c7b, 0x690a, 0x007c, 0x2c00, 0x6882, 0x6714, 0x6f7a,
-+	0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084,
-+	0x5f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022,
-+	0x6000, 0x2042, 0x6860, 0xac06, 0x00c0, 0x5c98, 0x2800, 0x6862,
-+	0x1078, 0x1e6e, 0x6818, 0xa005, 0x0040, 0x5cc8, 0x8001, 0x681a,
-+	0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x8001, 0x0050, 0x5cc8,
-+	0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x2251,
-+	0xd7fc, 0x00c0, 0x5cb7, 0x2069, 0x6040, 0x0078, 0x5cb9, 0x2069,
-+	0x6080, 0x690c, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x5cc5,
-+	0x6883, 0x0000, 0x697e, 0x2001, 0x0004, 0x2708, 0x1078, 0x2845,
-+	0x007c, 0x0d7e, 0x0e7e, 0x2d70, 0xd7fc, 0x00c0, 0x5cdb, 0x7808,
-+	0xd0ec, 0x0040, 0x5cd7, 0x2069, 0x0100, 0x0078, 0x5cdd, 0x2069,
-+	0x0200, 0x0078, 0x5cdd, 0x2069, 0x0100, 0x7000, 0xa084, 0x000f,
-+	0x0040, 0x5d27, 0xa086, 0x0007, 0x00c0, 0x5cef, 0x0f7e, 0x2d78,
-+	0x7094, 0x2068, 0x1078, 0x4694, 0x0f7f, 0x0078, 0x5d27, 0x7050,
-+	0x2060, 0x1078, 0x2b67, 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00,
-+	0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f,
-+	0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830,
-+	0xd0b4, 0x0040, 0x5d23, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-+	0xd094, 0x0040, 0x5d15, 0x00f0, 0x5d0f, 0x684b, 0x0009, 0x20a9,
-+	0x0014, 0x6848, 0xd084, 0x0040, 0x5d1f, 0x00f0, 0x5d19, 0x20a9,
-+	0x00fa, 0x00f0, 0x5d21, 0x681b, 0x0048, 0x706b, 0x0007, 0x0e7f,
-+	0x0d7f, 0x007c, 0x2079, 0x6000, 0x1078, 0x5d5e, 0x1078, 0x5d44,
-+	0x1078, 0x5d51, 0x2009, 0x0002, 0x2069, 0x6080, 0x680b, 0x0000,
-+	0x680f, 0x0000, 0x6813, 0x0000, 0x8109, 0x0040, 0x5d43, 0x2069,
-+	0x6040, 0x0078, 0x5d36, 0x007c, 0x7808, 0xd0ec, 0x0040, 0x5d4c,
-+	0x2019, 0x00cc, 0x0078, 0x5d4e, 0x2019, 0x007b, 0x7b32, 0x7b36,
-+	0x007c, 0x780c, 0xd0e4, 0x00c0, 0x5d59, 0x2019, 0x0040, 0x0078,
-+	0x5d5b, 0x2019, 0x0026, 0x7b3a, 0x7b3e, 0x007c, 0x780c, 0xd0e4,
-+	0x00c0, 0x5d66, 0x2019, 0x3f94, 0x0078, 0x5d68, 0x2019, 0x2626,
-+	0x7b2a, 0x7b2e, 0x007c, 0x6a54, 0xa285, 0x0000, 0x0040, 0x5d93,
-+	0x6958, 0x6bdc, 0xa300, 0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0,
-+	0x5d83, 0x8211, 0x0040, 0x5d87, 0x8108, 0xa11a, 0x0048, 0x5d74,
-+	0x69dc, 0x0078, 0x5d74, 0x68ef, 0x000a, 0x0c7f, 0x007c, 0x6954,
-+	0x6adc, 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, 0x00c0,
-+	0x5d89, 0x6956, 0x0c7f, 0x007c, 0x00e0, 0x5d94, 0x2091, 0x6000,
-+	0x00e0, 0x5d98, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x00c0, 0x5da5,
-+	0xd0d4, 0x0040, 0x5dce, 0x0078, 0x5dd1, 0x2008, 0x7808, 0xd0ec,
-+	0x0040, 0x5db8, 0xd1c4, 0x00c0, 0x5df0, 0x780c, 0xc0c5, 0x780e,
-+	0x7808, 0xc0f5, 0x780a, 0xd0ec, 0x0040, 0x5dec, 0x0078, 0x5de8,
-+	0xae8e, 0x0100, 0x0040, 0x5dc5, 0x780c, 0xc0f5, 0xc0c5, 0x780e,
-+	0xd0d4, 0x00c0, 0x5dec, 0x0078, 0x5de8, 0x780c, 0xc0fd, 0xc0c5,
-+	0x780e, 0xd0d4, 0x00c0, 0x5dec, 0x0078, 0x5de8, 0xd0e4, 0x0040,
-+	0x5dee, 0x00e0, 0x5dd1, 0x2091, 0x6000, 0x2009, 0x000c, 0x00e0,
-+	0x5dd7, 0x2091, 0x6000, 0x8109, 0x00c0, 0x5dd7, 0x70e4, 0xa084,
-+	0x01ff, 0xa086, 0x01ff, 0x00c0, 0x5de8, 0x70ec, 0x0078, 0x5da5,
-+	0x7804, 0xd08c, 0x0040, 0x5dee, 0x681b, 0x000c, 0x70a0, 0x70a2,
-+	0x007c, 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014,
-+	0x0014, 0x98ec, 0x98d6, 0x0014, 0x0014, 0x0014, 0x0080, 0x0140,
-+	0x0000, 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018,
-+	0x300b, 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202,
-+	0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c3, 0x0864, 0xa834,
-+	0x28c1, 0x9cb9, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300,
-+	0x1856, 0x883a, 0xa804, 0x28f2, 0x9c9d, 0xa8f4, 0x300c, 0x28e1,
-+	0x9c9d, 0x2822, 0xa207, 0x64a4, 0x2001, 0xa811, 0xa206, 0x64c0,
-+	0x6de0, 0x67a0, 0x6fc0, 0x882b, 0x1814, 0x883b, 0x7824, 0x68c1,
-+	0x7864, 0x883e, 0xa802, 0x8576, 0x8677, 0x80df, 0x94a1, 0x206c,
-+	0x28c1, 0x9cb9, 0x2045, 0x2104, 0x20a1, 0x2080, 0x7961, 0xa8df,
-+	0xa209, 0x0904, 0xa20e, 0xa808, 0xa205, 0xa300, 0x1872, 0x879a,
-+	0x883c, 0x1fe2, 0xc601, 0xa20a, 0x8000, 0x85a1, 0x806f, 0x9422,
-+	0x84a2, 0x856e, 0x0704, 0x9c9d, 0x0014, 0xa204, 0xa300, 0x3009,
-+	0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6, 0xa8f7, 0xf881, 0xa8eb,
-+	0xc007, 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2,
-+	0x0014, 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6,
-+	0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160,
-+	0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011,
-+	0x20d5, 0x8822, 0x0016, 0x3008, 0x2845, 0x1011, 0xa8fd, 0x2802,
-+	0x1011, 0xa8fd, 0xa894, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x7102,
-+	0x805f, 0x9481, 0x0017, 0x300c, 0xa300, 0x1de2, 0xd387, 0x0210,
-+	0xa800, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d,
-+	0x3806, 0x0210, 0x9cbe, 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720,
-+	0xa211, 0x7102, 0x805f, 0x9481, 0x8000, 0x8300, 0x8772, 0x8837,
-+	0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d5c, 0xa8fc, 0xd984, 0xf0e2,
-+	0xf0a1, 0xa820, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f, 0x9401,
-+	0xb520, 0xc802, 0x8820, 0xa80f, 0x2301, 0xa80d, 0x10d2, 0x78e4,
-+	0x9d5c, 0x8821, 0x8820, 0xa8e6, 0xf123, 0xf142, 0xf101, 0xa855,
-+	0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014,
-+	0x6848, 0x0214, 0x8827, 0x300a, 0x0013, 0xa21b, 0x8300, 0x2001,
-+	0xa843, 0x8201, 0x1852, 0xd183, 0x8834, 0x8001, 0xa801, 0x3027,
-+	0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d63, 0x692b,
-+	0x6902, 0x1a34, 0xa806, 0x8080, 0x9521, 0xc002, 0x1a94, 0xa801,
-+	0x1a14, 0x7021, 0x0014, 0xa300, 0x69e4, 0x8023, 0x16e1, 0x8001,
-+	0x10f1, 0x6946, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa808,
-+	0x6161, 0x0014, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1,
-+	0x0101, 0x300a, 0x8827, 0x0014, 0x11c2, 0x211e, 0x870e, 0xa21d,
-+	0x0014, 0x9d63, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6,
-+	0x882c, 0x0016, 0xa212, 0x8300, 0x10d2, 0x70e4, 0x0004, 0x8007,
-+	0x9424, 0xcc1a, 0x9d5c, 0xa8f8, 0x878e, 0x0016, 0xa21c, 0x1035,
-+	0xa8bb, 0xa210, 0x3807, 0x300c, 0x817e, 0x872b, 0x8772, 0x0014,
-+	0x0000, 0xd27a
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_12160.h	2003-07-19 17:06:32.000000000 -0700
-@@ -0,0 +1,4198 @@
-+/* @(#)asm_12160.h 1.3 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+/************************************************************************
-+ *									*
-+ *	      --- ISP12160A Initiator/Target RISC Firmware ---      	*
-+ *			     32 LUN Support				*
-+ *									*
-+ ************************************************************************/
-+#ifndef	ISP_TARGET_MODE
-+/*
-+ *	Firmware Version 10.04.32 (12:03 May 09, 2001)
-+ */
-+static const u_int16_t isp_12160_risc_code[] = {
-+	0x0804, 0x1041, 0x0000, 0x35e6, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
-+	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
-+	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
-+	0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-+	0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043,
-+	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
-+	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-+	0x2400, 0x20c9, 0x8fff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
-+	0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2,
-+	0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004,
-+	0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a,
-+	0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128,
-+	0xa1a2, 0x4600, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-+	0xa192, 0x9000, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1de8,
-+	0x2218, 0x2079, 0x4600, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
-+	0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102,
-+	0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd,
-+	0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4640, 0x080c,
-+	0x459a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4680,
-+	0x2071, 0x0100, 0x080c, 0x459a, 0x7814, 0xc0d4, 0x7816, 0x00de,
-+	0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
-+	0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
-+	0x2009, 0x0002, 0x2069, 0x4640, 0x681b, 0x0003, 0x6823, 0x0007,
-+	0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006,
-+	0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a,
-+	0x68bf, 0x46c0, 0x2079, 0x4600, 0x68d3, 0x762d, 0x68c3, 0x4bc0,
-+	0x68c7, 0x4ac0, 0x68cb, 0x8bc0, 0x68a7, 0x8e44, 0x68ab, 0x8e49,
-+	0x68af, 0x8e44, 0x68b3, 0x8e44, 0x68a3, 0x0001, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4680, 0x0870, 0x68cf, 0x000a,
-+	0x68bf, 0x48c0, 0x68d3, 0x7839, 0x68c3, 0x6bc0, 0x68c7, 0x4b40,
-+	0x68cb, 0x8cd0, 0x68a7, 0x8e49, 0x68ab, 0x8e4e, 0x68af, 0x8e49,
-+	0x68b3, 0x8e49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4ac0, 0x2071,
-+	0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120,
-+	0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d58, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1188, 0x2069, 0x4b40, 0x2071, 0x0100, 0x70ec,
-+	0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c,
-+	0x2021, 0x000c, 0x080c, 0x1d58, 0x00ee, 0x2011, 0x0002, 0x2069,
-+	0x4bc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
-+	0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f,
-+	0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
-+	0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x1128, 0x8211, 0x0118, 0x2069, 0x6bc0, 0x08d8, 0x080c, 0x22cf,
-+	0x080c, 0x4015, 0x080c, 0x1b6d, 0x080c, 0x4553, 0x2091, 0x2200,
-+	0x2079, 0x4600, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4600,
-+	0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4640,
-+	0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4680, 0x2091, 0x2000,
-+	0x2079, 0x4600, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
-+	0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086,
-+	0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab,
-+	0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110,
-+	0x080c, 0x207a, 0x080c, 0x1e09, 0x0e04, 0x11af, 0x786c, 0xa065,
-+	0x0110, 0x080c, 0x207a, 0x0e04, 0x11af, 0x2009, 0x4647, 0x2011,
-+	0x4687, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c7c, 0x2071,
-+	0x4640, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
-+	0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190,
-+	0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
-+	0x2079, 0x4600, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
-+	0x207a, 0x1d04, 0x11d9, 0x2079, 0x4600, 0x2071, 0x0010, 0x080c,
-+	0x4370, 0x2071, 0x4680, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
-+	0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d,
-+	0x2190, 0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
-+	0x4600, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
-+	0x080c, 0x207a, 0x1d04, 0x118e, 0x080c, 0x4370, 0x0804, 0x118e,
-+	0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e,
-+	0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x254c, 0x2091, 0x2400,
-+	0x080c, 0x40ad, 0x0005, 0x2091, 0x2200, 0x080c, 0x40ad, 0x0005,
-+	0x2091, 0x2200, 0x080c, 0x40ad, 0x2091, 0x2400, 0x080c, 0x40ad,
-+	0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d,
-+	0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d,
-+	0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
-+	0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
-+	0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c,
-+	0x2569, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
-+	0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
-+	0x0126, 0x2091, 0x2600, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e,
-+	0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2569,
-+	0x2091, 0x2800, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e, 0x000d,
-+	0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4600,
-+	0x2071, 0x0200, 0x2069, 0x4640, 0x3d00, 0xd08c, 0x0130, 0x70ec,
-+	0xa084, 0x1c00, 0x78e2, 0x080c, 0x459a, 0x3d00, 0xd084, 0x0150,
-+	0x2069, 0x4680, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
-+	0x080c, 0x459a, 0x080c, 0x24fd, 0x00fe, 0x00ee, 0x00de, 0x012e,
-+	0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002,
-+	0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3,
-+	0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018,
-+	0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f,
-+	0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b0a, 0x000e,
-+	0x0150, 0x0028, 0x0006, 0x080c, 0x1aff, 0x000e, 0x0120, 0x2001,
-+	0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4640,
-+	0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4680, 0xc19d, 0xc7fd, 0x6060,
-+	0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086,
-+	0x0018, 0x1120, 0x00c6, 0x080c, 0x1916, 0x00ce, 0x782b, 0x0000,
-+	0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce,
-+	0x609f, 0x0000, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103,
-+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-+	0x080c, 0x1b15, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b60, 0x7810,
-+	0xd09c, 0x1118, 0x2061, 0x4640, 0x0020, 0x2061, 0x4680, 0xc09c,
-+	0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2,
-+	0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006,
-+	0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a,
-+	0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c,
-+	0x1470, 0x1470, 0x13ce, 0x1a59, 0x147a, 0x13c8, 0x13da, 0x13db,
-+	0x13dc, 0x13dd, 0x1a5d, 0x13c8, 0x1487, 0x14db, 0x1931, 0x1a53,
-+	0x13de, 0x17ba, 0x17f0, 0x1822, 0x1868, 0x1777, 0x1784, 0x1797,
-+	0x17a9, 0x15b0, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
-+	0x1559, 0x155c, 0x156a, 0x1578, 0x1582, 0x1596, 0x15a2, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x15bd, 0x15ce, 0x15e8, 0x161c, 0x1645,
-+	0x1657, 0x165a, 0x1685, 0x16be, 0x16d0, 0x1745, 0x1755, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x1767, 0x2100, 0xa08a, 0x0040, 0x1a04,
-+	0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a7f,
-+	0x1a85, 0x13c8, 0x13c8, 0x13c8, 0x1a89, 0x1ac9, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x192c, 0x13c8,
-+	0x13c8, 0x18fb, 0x13c8, 0x1acd, 0x1a71, 0x1a7b, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
-+	0x13c8, 0x13c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, 0x73ce,
-+	0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13bd, 0x2061,
-+	0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005,
-+	0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041,
-+	0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3,
-+	0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000,
-+	0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
-+	0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b,
-+	0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051,
-+	0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091,
-+	0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018,
-+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
-+	0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
-+	0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13ba, 0xa182,
-+	0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
-+	0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002,
-+	0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13bd, 0x24a8,
-+	0x53a5, 0x0c10, 0x0804, 0x13ba, 0x2029, 0x0000, 0x2520, 0x71d0,
-+	0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000,
-+	0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040,
-+	0x7007, 0x0006, 0x81ff, 0x0904, 0x13ba, 0xa182, 0x0040, 0x1210,
-+	0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007,
-+	0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3,
-+	0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878,
-+	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca,
-+	0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x0020,
-+	0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029,
-+	0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
-+	0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001,
-+	0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, 0x78ae, 0x2001,
-+	0x4005, 0x0804, 0x13bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76,
-+	0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c,
-+	0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000,
-+	0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
-+	0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
-+	0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
-+	0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13ba, 0x75d8, 0x76dc,
-+	0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8,
-+	0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0500,
-+	0xa40a, 0x0110, 0x1a04, 0x13bc, 0x8001, 0x7892, 0xa084, 0xfc00,
-+	0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x13bc,
-+	0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10,
-+	0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018,
-+	0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c,
-+	0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8,
-+	0x2009, 0x4648, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-+	0x13b9, 0x2011, 0x4688, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4649,
-+	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
-+	0x4689, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6128, 0x622c,
-+	0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148,
-+	0x2061, 0x4680, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
-+	0x73de, 0x0804, 0x13b8, 0x2009, 0x464c, 0x210c, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468c, 0x2214, 0x0804,
-+	0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0x2001,
-+	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x0102, 0x2214,
-+	0x0804, 0x13b8, 0x2009, 0x464d, 0x210c, 0x2001, 0x01ff, 0x2004,
-+	0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468d, 0x2214, 0x0804, 0x13b8,
-+	0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x7a24,
-+	0x0804, 0x13b8, 0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011,
-+	0x4ac0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
-+	0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13b7, 0x77c4, 0x080c,
-+	0x1b7b, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-+	0x0804, 0x13b7, 0x2061, 0x4640, 0x6118, 0x2001, 0x01ff, 0x2004,
-+	0xd0fc, 0x1904, 0x13b9, 0x2061, 0x4680, 0x6218, 0x0804, 0x13b8,
-+	0x77c4, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10,
-+	0x77da, 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294,
-+	0x000f, 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x238b, 0xa384,
-+	0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100,
-+	0xc0bc, 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011,
-+	0x4648, 0x2204, 0x0020, 0x2011, 0x4688, 0x2204, 0xc0bd, 0x0006,
-+	0x2100, 0xc0bc, 0x2012, 0x080c, 0x2331, 0x001e, 0x0804, 0x13b9,
-+	0x71c4, 0x2021, 0x4649, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030,
-+	0x71c8, 0x2021, 0x4689, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1614,
-+	0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x15fa,
-+	0x71c4, 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1614, 0x0026, 0x2122,
-+	0x001e, 0x080c, 0x2343, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110,
-+	0xd3fc, 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
-+	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4640, 0x6128, 0x622c,
-+	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
-+	0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026,
-+	0x0016, 0x2061, 0x4680, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
-+	0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da,
-+	0x72de, 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6130,
-+	0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
-+	0x2061, 0x4680, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918,
-+	0x0804, 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x0006,
-+	0x2019, 0x0000, 0x080c, 0x237f, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128,
-+	0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x0006, 0xc3fd, 0x080c,
-+	0x237f, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010,
-+	0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8,
-+	0x0804, 0x13b2, 0x2011, 0x464d, 0x2204, 0x0006, 0x8104, 0x1208,
-+	0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x236c, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182,
-+	0x0010, 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011,
-+	0x468d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd,
-+	0x080c, 0x236c, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8,
-+	0xa184, 0xfffd, 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2,
-+	0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8,
-+	0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4ac0, 0x8107,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc,
-+	0x74d8, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000,
-+	0x6a02, 0xd2ac, 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff,
-+	0xa082, 0x0002, 0x1a04, 0x1741, 0x843f, 0xa7bc, 0x00ff, 0x0140,
-+	0xa786, 0x0002, 0x1904, 0x1741, 0xa484, 0x00ff, 0x0904, 0x1741,
-+	0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009,
-+	0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084,
-+	0x00ff, 0x1110, 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff,
-+	0xa082, 0x001a, 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff,
-+	0x0188, 0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff,
-+	0xa39d, 0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600,
-+	0xa702, 0x1278, 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a,
-+	0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804,
-+	0x13ba, 0x2091, 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b7b,
-+	0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816,
-+	0x70cc, 0x681e, 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4640,
-+	0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
-+	0x70c8, 0x2061, 0x4680, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4,
-+	0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23af,
-+	0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4,
-+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091,
-+	0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b7b, 0x2091,
-+	0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110,
-+	0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
-+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804,
-+	0xa005, 0x0110, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804,
-+	0x13b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
-+	0x2091, 0x8000, 0x080c, 0x1b93, 0x2091, 0x8001, 0x2708, 0x6a08,
-+	0x0804, 0x13b8, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138,
-+	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x73c8,
-+	0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, 0x1c0b, 0x11e8, 0x6818,
-+	0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, 0x23ce, 0x007e, 0x1170,
-+	0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0xc0fd,
-+	0x2061, 0x4680, 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001,
-+	0x2001, 0x4005, 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba,
-+	0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc,
-+	0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021,
-+	0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b93,
-+	0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061,
-+	0x4680, 0xc1fd, 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f,
-+	0x000f, 0x792a, 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091,
-+	0x8001, 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128,
-+	0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110,
-+	0x0804, 0x13bc, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017,
-+	0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680, 0xc1fd,
-+	0x607b, 0x0000, 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a,
-+	0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2041,
-+	0x0021, 0x2049, 0x0005, 0x2051, 0x0030, 0x2091, 0x8000, 0x70c8,
-+	0xa005, 0x0118, 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1b93, 0x70c8,
-+	0x6836, 0x8738, 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005,
-+	0x2019, 0x0000, 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b0a, 0x0138,
-+	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x72c8,
-+	0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, 0x2039, 0x0000, 0xd284,
-+	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a,
-+	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d90, 0xa7bc, 0xff00,
-+	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d50, 0x2091, 0x8000,
-+	0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808,
-+	0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
-+	0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18b2, 0x684b,
-+	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18bb,
-+	0x20a9, 0x00fa, 0x1f04, 0x18c2, 0x2079, 0x4600, 0x2009, 0x0018,
-+	0x72c8, 0xd284, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680,
-+	0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f,
-+	0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160,
-+	0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a,
-+	0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2,
-+	0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054,
-+	0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x186a, 0x69ec, 0x6a48,
-+	0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021,
-+	0x0004, 0x20a9, 0x09ff, 0x1f04, 0x190b, 0x8421, 0x1dd0, 0x8319,
-+	0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118,
-+	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x71c4, 0x71c6, 0x6916,
-+	0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
-+	0x1110, 0x080c, 0x1c5b, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
-+	0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
-+	0x72ce, 0x2079, 0x4600, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
-+	0x1b58, 0x0904, 0x1a3d, 0x20a9, 0x0005, 0x20a1, 0x4614, 0x2091,
-+	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d24,
-+	0x0120, 0x080c, 0x1b60, 0x0804, 0x1a3d, 0x6004, 0xa08c, 0x00ff,
-+	0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x205f, 0x000e, 0xa084,
-+	0xff00, 0x8007, 0x8009, 0x0904, 0x19e1, 0x00c6, 0x2c68, 0x080c,
-+	0x1b58, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
-+	0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
-+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
-+	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19e0, 0x2009,
-+	0x0040, 0x080c, 0x1d24, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0002, 0x1168, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120,
-+	0x0016, 0x080c, 0x205c, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
-+	0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000, 0x080c,
-+	0x1a41, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
-+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-+	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
-+	0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000,
-+	0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
-+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-+	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
-+	0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b0a, 0x01f0, 0x0018,
-+	0x080c, 0x1aff, 0x01d0, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087,
-+	0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff,
-+	0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c,
-+	0x1b60, 0x2001, 0x4007, 0x0804, 0x13bc, 0x74c4, 0x73c8, 0x72cc,
-+	0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, 0x1118,
-+	0x2071, 0x4640, 0x0018, 0x2071, 0x4680, 0xc1fd, 0x792a, 0x7063,
-+	0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e, 0x7072,
-+	0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c, 0xa184,
-+	0x0060, 0x0110, 0x080c, 0x3fc1, 0x00ee, 0x6596, 0x65a6, 0x669a,
-+	0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000,
-+	0x080c, 0x22ae, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804,
-+	0x13bd, 0x20a9, 0x0005, 0x2099, 0x4614, 0x2091, 0x8000, 0x530a,
-+	0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
-+	0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804,
-+	0x13ba, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c,
-+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000,
-+	0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804,
-+	0x13bd, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3,
-+	0x7966, 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900,
-+	0x71c6, 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804,
-+	0x13ba, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c,
-+	0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff,
-+	0x1904, 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd,
-+	0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108,
-+	0x2019, 0x0041, 0x2011, 0x8e4e, 0x2312, 0x2019, 0x0042, 0x8210,
-+	0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210,
-+	0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011,
-+	0x8e53, 0x2112, 0x2011, 0x8e73, 0x2312, 0x7904, 0x7806, 0x0804,
-+	0x13b9, 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118,
-+	0x2011, 0x4ac0, 0x0010, 0x2011, 0x4b40, 0x8107, 0xa084, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc,
-+	0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c,
-+	0x6800, 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001,
-+	0x4007, 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001,
-+	0x4007, 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814,
-+	0xd0f4, 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008,
-+	0xa006, 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db,
-+	0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e,
-+	0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
-+	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
-+	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140,
-+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
-+	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
-+	0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008,
-+	0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e,
-+	0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005,
-+	0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005,
-+	0x00f6, 0x2079, 0x4600, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110,
-+	0x080c, 0x254c, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9000, 0x7a4a,
-+	0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8,
-+	0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011,
-+	0x4bc0, 0x0010, 0x2011, 0x6bc0, 0xa784, 0x0f00, 0x800b, 0xa784,
-+	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268,
-+	0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e,
-+	0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128,
-+	0x2009, 0x4652, 0x2071, 0x4640, 0x0020, 0x2009, 0x4692, 0x2071,
-+	0x4680, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060,
-+	0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000,
-+	0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c,
-+	0x1d95, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88,
-+	0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060,
-+	0x080c, 0x2693, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c,
-+	0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848,
-+	0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
-+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-+	0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071,
-+	0x4640, 0x2031, 0x46c0, 0x0020, 0x2071, 0x4680, 0x2031, 0x48c0,
-+	0x704c, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e,
-+	0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4640,
-+	0x0010, 0x2079, 0x4680, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6804,
-+	0x780a, 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000,
-+	0xa065, 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0,
-+	0x2c28, 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140,
-+	0x6000, 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048,
-+	0x6400, 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00,
-+	0x6802, 0x2560, 0x080c, 0x1be3, 0x601b, 0x0005, 0x6023, 0x0020,
-+	0x00fe, 0x080c, 0x1d95, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810,
-+	0x8001, 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff,
-+	0xa005, 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc,
-+	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-+	0x2091, 0x8000, 0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0,
-+	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90,
-+	0x2091, 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8e74, 0x210c,
-+	0xa10d, 0x0118, 0xa065, 0x0804, 0x207a, 0x2061, 0x0000, 0x6018,
-+	0xd084, 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc,
-+	0x2069, 0x4640, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4680, 0xc7fd,
-+	0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005,
-+	0x1108, 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x254c, 0x0002,
-+	0x1cb8, 0x1cbb, 0x1cc1, 0x1cc5, 0x1cb9, 0x1cc9, 0x1cb9, 0x1cb9,
-+	0x1cb9, 0x1ccf, 0x1cfb, 0x1cfe, 0x1d03, 0x1d0c, 0x1cb9, 0x1cb9,
-+	0x0005, 0x080c, 0x254c, 0x080c, 0x1c5b, 0x2001, 0x8001, 0x0804,
-+	0x1d15, 0x2001, 0x8003, 0x0804, 0x1d15, 0x2001, 0x8004, 0x0804,
-+	0x1d15, 0x080c, 0x1c5b, 0x2001, 0x8006, 0x0804, 0x1d15, 0x2091,
-+	0x8000, 0x0076, 0xd7fc, 0x1128, 0x2069, 0x4640, 0x2039, 0x0009,
-+	0x0020, 0x2069, 0x4680, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000,
-+	0x0128, 0x000e, 0x6f1e, 0x2091, 0x8001, 0x0005, 0x6870, 0x007e,
-+	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-+	0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0, 0x2091, 0x8001,
-+	0x2001, 0x800a, 0x00d0, 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c5b,
-+	0x2001, 0x800d, 0x0090, 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0,
-+	0x70c6, 0x2001, 0x800e, 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008,
-+	0x78e8, 0x70c6, 0x2001, 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118,
-+	0x70db, 0x0000, 0x0010, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b,
-+	0x0001, 0x2091, 0x4080, 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518,
-+	0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018,
-+	0x0006, 0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x7112,
-+	0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007,
-+	0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0,
-+	0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x000e,
-+	0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x0005,
-+	0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201,
-+	0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008,
-+	0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520,
-+	0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019,
-+	0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c,
-+	0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, 0x180c, 0x2021, 0x000c,
-+	0x0030, 0x2019, 0x1809, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a,
-+	0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08,
-+	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008,
-+	0x796e, 0x0005, 0x00c6, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
-+	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
-+	0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005,
-+	0x1108, 0x786a, 0x2091, 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6,
-+	0x2060, 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f, 0x0000,
-+	0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce,
-+	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x1110, 0x080c,
-+	0x254c, 0x784a, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
-+	0x818e, 0x1208, 0xa200, 0x1f04, 0x1ddf, 0x8086, 0x818e, 0x0005,
-+	0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213,
-+	0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x1def, 0x0028, 0xa11a,
-+	0x2308, 0x8210, 0x1f04, 0x1def, 0x0006, 0x3200, 0xa084, 0xefff,
-+	0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000,
-+	0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, 0x1ebd, 0x7810, 0x2050,
-+	0x080c, 0x1b58, 0x0904, 0x1ebd, 0xa046, 0x7970, 0x2500, 0x8000,
-+	0xa112, 0x2009, 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118,
-+	0x8840, 0x2009, 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099,
-+	0x0030, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000,
-+	0x88ff, 0x0110, 0x080c, 0x1b58, 0x7008, 0xd0fc, 0x0de8, 0x7007,
-+	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff,
-+	0x1120, 0x88ff, 0x0904, 0x1eaa, 0x0050, 0x2c00, 0x788e, 0x20a9,
-+	0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1eaa, 0xa046,
-+	0x7218, 0x731c, 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040,
-+	0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e,
-+	0xdac4, 0x0118, 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904,
-+	0x1eaa, 0x8cff, 0x0110, 0x080c, 0x1b60, 0x00ce, 0x080c, 0x1b60,
-+	0xa046, 0x7888, 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c,
-+	0x7b78, 0xdac4, 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
-+	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-+	0x721a, 0x731e, 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014,
-+	0xd0fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091,
-+	0x8000, 0x681f, 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060,
-+	0x0c70, 0x788b, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091,
-+	0x8001, 0x0098, 0x00ce, 0x788b, 0x0000, 0x080c, 0x2035, 0x6004,
-+	0xa084, 0x000f, 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004,
-+	0xa084, 0x000f, 0x0019, 0x0804, 0x1e09, 0x0005, 0x0002, 0x1ecf,
-+	0x1eea, 0x1f03, 0x1ecf, 0x1f10, 0x1ee0, 0x1ecf, 0x1ecf, 0x1ecf,
-+	0x1ee8, 0x1f01, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x2039,
-+	0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c,
-+	0x1f4c, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0005,
-+	0x78bc, 0xd0c4, 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030,
-+	0x080c, 0x205f, 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000,
-+	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c,
-+	0x1f4c, 0x0120, 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f67,
-+	0x0005, 0x080c, 0x205c, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4,
-+	0x1108, 0x0828, 0x080c, 0x1f4c, 0x1110, 0x0804, 0x1f67, 0x0005,
-+	0x78bc, 0xd0c4, 0x0110, 0x0804, 0x1ecf, 0x78bf, 0x0000, 0x6714,
-+	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188,
-+	0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc,
-+	0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108,
-+	0x00c0, 0x080c, 0x1b7b, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000,
-+	0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010,
-+	0x2091, 0x8001, 0x1f04, 0x1f34, 0x8211, 0x0118, 0x20a9, 0x0100,
-+	0x0c58, 0x080c, 0x1b60, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d,
-+	0x2c00, 0x78b6, 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002,
-+	0x78b8, 0xad06, 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130,
-+	0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6,
-+	0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2,
-+	0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c,
-+	0x3fc1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4680,
-+	0xd7fc, 0x1110, 0x2071, 0x4640, 0xa784, 0x0f00, 0x800b, 0xa784,
-+	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0,
-+	0xa168, 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-+	0x71c4, 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138,
-+	0xd7fc, 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08,
-+	0xd684, 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1be3,
-+	0x2091, 0x8000, 0x080c, 0x1d95, 0x2091, 0x8001, 0x7814, 0xd0c4,
-+	0x0904, 0x201f, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x201f,
-+	0xd0fc, 0x1110, 0x0804, 0x201f, 0x601b, 0x0021, 0x0804, 0x201f,
-+	0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814,
-+	0xa202, 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c,
-+	0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0804, 0x201f, 0x2c08,
-+	0xd9fc, 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084,
-+	0x0002, 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304,
-+	0x6002, 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00,
-+	0x2060, 0x080c, 0x2693, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050,
-+	0x6800, 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160,
-+	0x6003, 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a,
-+	0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001,
-+	0xd6b4, 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1bf4, 0x00ee,
-+	0x0005, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1d95,
-+	0x2091, 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f,
-+	0x0000, 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818,
-+	0xd384, 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278,
-+	0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84,
-+	0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876,
-+	0x70d2, 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04,
-+	0x205b, 0x2091, 0x4080, 0x0005, 0x2039, 0x2071, 0x0010, 0x2039,
-+	0x2077, 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810,
-+	0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88,
-+	0x0005, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015,
-+	0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x2223, 0x21fe,
-+	0x2082, 0x20f2, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00c0, 0x6084,
-+	0xa086, 0x0103, 0x1904, 0x20dc, 0x6114, 0x6018, 0xa105, 0x0120,
-+	0x86ff, 0x11d8, 0x0804, 0x20dc, 0x8603, 0xa080, 0x8e55, 0x620c,
-+	0x2202, 0x8000, 0x6210, 0x2202, 0x080c, 0x1db3, 0x8630, 0xa68e,
-+	0x000f, 0x0904, 0x215d, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602,
-+	0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04,
-+	0x215d, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8,
-+	0x2011, 0x8e55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684,
-+	0x1130, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685,
-+	0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
-+	0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810,
-+	0xc0ad, 0x7812, 0x0804, 0x215d, 0x263a, 0x080c, 0x2229, 0x1904,
-+	0x2245, 0x786c, 0xa065, 0x1904, 0x2087, 0x2091, 0x8000, 0x7810,
-+	0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001,
-+	0x0804, 0x2245, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00a0, 0x6084,
-+	0xa086, 0x0103, 0x1904, 0x2147, 0x6114, 0x6018, 0xa105, 0x0120,
-+	0x86ff, 0x11b8, 0x0804, 0x2147, 0xa680, 0x8e55, 0x620c, 0x2202,
-+	0x080c, 0x1db3, 0x8630, 0xa68e, 0x001e, 0x0904, 0x215d, 0x786c,
-+	0xa065, 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a,
-+	0x0005, 0xa682, 0x0006, 0x1a04, 0x215d, 0x2091, 0x8000, 0x2069,
-+	0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8e55, 0x2009, 0x8e4e,
-+	0x26a8, 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2129,
-+	0xa685, 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810,
-+	0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8e75,
-+	0x200a, 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a,
-+	0x080c, 0x2229, 0x1904, 0x2245, 0x786c, 0xa065, 0x1904, 0x20f7,
-+	0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad,
-+	0x7812, 0x2091, 0x8001, 0x0804, 0x2245, 0x2091, 0x8000, 0x7007,
-+	0x0004, 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302,
-+	0x1150, 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812,
-+	0x2091, 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c,
-+	0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004,
-+	0x8004, 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e,
-+	0xd4c4, 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226,
-+	0x20a1, 0x0030, 0x7003, 0x0000, 0x2009, 0x8e54, 0x260a, 0x8109,
-+	0x2198, 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8,
-+	0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000,
-+	0xa10a, 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140,
-+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
-+	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
-+	0xd4c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
-+	0x0de8, 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8e54, 0x2634,
-+	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004,
-+	0xd094, 0x1de8, 0x0804, 0x215f, 0x2069, 0x4647, 0x206b, 0x0003,
-+	0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6,
-+	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
-+	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
-+	0x721e, 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086,
-+	0x0103, 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000,
-+	0x6818, 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3,
-+	0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1db3, 0x0e04,
-+	0x221c, 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c,
-+	0xa065, 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8,
-+	0x00e0, 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a,
-+	0xa086, 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1db3,
-+	0xa006, 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9,
-+	0x1110, 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091,
-+	0x4080, 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385,
-+	0x0000, 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184,
-+	0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-+	0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
-+	0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
-+	0x6028, 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b15, 0x01d0,
-+	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118,
-+	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091, 0x8000, 0x681f,
-+	0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091,
-+	0x8001, 0x0068, 0x78ab, 0x0000, 0x080c, 0x1db3, 0x7990, 0x7894,
-+	0x8000, 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
-+	0x0010, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4658,
-+	0x0010, 0x2009, 0x4698, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009,
-+	0x4680, 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4640, 0x2079,
-+	0x0200, 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009,
-+	0x4645, 0x0010, 0x2009, 0x4685, 0x2104, 0xa005, 0x1130, 0x7830,
-+	0xa084, 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009,
-+	0x0002, 0x2069, 0x4600, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-+	0x2324, 0x2071, 0x4680, 0x2079, 0x0100, 0x2021, 0x48bf, 0x784b,
-+	0x000f, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e0f,
-+	0x0030, 0x20a1, 0x012b, 0x2019, 0x3e0f, 0xd184, 0x0110, 0x20a1,
-+	0x022b, 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318,
-+	0x2398, 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020,
-+	0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2302,
-+	0x7003, 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd,
-+	0x080c, 0x2443, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300,
-+	0x7806, 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b,
-+	0x2f08, 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4640,
-+	0x2079, 0x0200, 0x2021, 0x46bf, 0x0804, 0x22df, 0x080c, 0x24fd,
-+	0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201,
-+	0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e,
-+	0x080c, 0x2443, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
-+	0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x234b, 0xa18c, 0x0e00,
-+	0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002,
-+	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x235c, 0xa294,
-+	0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118,
-+	0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110,
-+	0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x2374, 0xa18c,
-+	0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011,
-+	0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa084, 0xf0cf,
-+	0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110,
-+	0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a,
-+	0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
-+	0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022,
-+	0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6,
-+	0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103,
-+	0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0118,
-+	0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed, 0x62ae,
-+	0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000,
-+	0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2427, 0xd1fc, 0x0118,
-+	0x2061, 0x8dd0, 0x0010, 0x2061, 0x8cc0, 0x080c, 0x242f, 0x0560,
-+	0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8cd0, 0x0010, 0x2061,
-+	0x8bc0, 0x00c6, 0x080c, 0x242f, 0x0128, 0x00ce, 0x8c60, 0x1f04,
-+	0x23e9, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8cd0, 0x2071,
-+	0x4680, 0x0020, 0xa082, 0x8bc0, 0x2071, 0x4640, 0x7076, 0x7172,
-+	0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0, 0xc1c4,
-+	0x71d2, 0x080c, 0x22a4, 0x00c0, 0xd1fc, 0x1118, 0x2071, 0x4640,
-+	0x0010, 0x2071, 0x4680, 0x6020, 0xc0dd, 0x6022, 0x7172, 0x2138,
-+	0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f, 0x71d0,
-+	0xc1c4, 0x71d2, 0x080c, 0x22a4, 0x2001, 0x0000, 0x0010, 0x2001,
-+	0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04,
-+	0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206,
-+	0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80,
-+	0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079, 0x4680,
-+	0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4640, 0x2071, 0x0200,
-+	0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e, 0x0060,
-+	0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800, 0xd0bc,
-+	0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005, 0x2001,
-+	0x4601, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120, 0xa084,
-+	0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036, 0x2018,
-+	0x2071, 0x4b40, 0xd0fc, 0x1110, 0x2071, 0x4ac0, 0x8007, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a,
-+	0x1904, 0x24fa, 0x7108, 0xa194, 0xff00, 0x0904, 0x24fa, 0xa18c,
-+	0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085, 0x003a,
-+	0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a, 0xa102,
-+	0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084, 0x00ff,
-+	0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a, 0xa106,
-+	0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012, 0xa106,
-+	0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019, 0xa106,
-+	0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009, 0x000c,
-+	0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0, 0x2009,
-+	0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f, 0x0058,
-+	0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009, 0x0019,
-+	0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004, 0xa085,
-+	0x000a, 0x7006, 0x2071, 0x4600, 0x7004, 0xd0bc, 0x0158, 0xd3fc,
-+	0x1120, 0x73ea, 0x2071, 0x4640, 0x0018, 0x73ee, 0x2071, 0x4680,
-+	0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff, 0x2004,
-+	0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x12a0,
-+	0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c, 0x810c,
-+	0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004, 0x8004,
-+	0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x254b, 0x2532,
-+	0x254b, 0x2532, 0x2525, 0x253f, 0x2525, 0x7008, 0xa084, 0xc3ff,
-+	0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x3000,
-+	0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x700a,
-+	0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005, 0x7008,
-+	0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084, 0xc3ff,
-+	0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x254c, 0x2091, 0x8000,
-+	0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071,
-+	0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a04,
-+	0x70df, 0x0020, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a, 0x758e,
-+	0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc,
-+	0x1128, 0xa784, 0x007d, 0x1904, 0x3c74, 0x0871, 0xa49c, 0x000f,
-+	0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507,
-+	0xa084, 0x000f, 0x0002, 0x2b49, 0x2c34, 0x2c72, 0x2ed8, 0x3256,
-+	0x32ad, 0x3353, 0x33e2, 0x34b6, 0x3588, 0x259e, 0x259b, 0x2970,
-+	0x2a56, 0x322a, 0x259b, 0x080c, 0x254c, 0x0005, 0xa006, 0x0038,
-+	0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042, 0x70ce,
-+	0x705c, 0xa005, 0x1904, 0x26ec, 0x7060, 0xa084, 0x0007, 0x0002,
-+	0x25b8, 0x2626, 0x262e, 0x2637, 0x2640, 0x26d2, 0x2649, 0x2626,
-+	0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4, 0x1904,
-+	0x2603, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x70b0, 0xa06d, 0x6800,
-+	0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045,
-+	0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc,
-+	0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804,
-+	0x281f, 0x705c, 0xa005, 0x1904, 0x259d, 0x00c6, 0x00d6, 0x70b0,
-+	0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa,
-+	0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001,
-+	0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
-+	0x0020, 0x0804, 0x281f, 0x080c, 0x3c33, 0x1904, 0x259d, 0x781b,
-+	0x0068, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-+	0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, 0x703e,
-+	0xc1b4, 0x71d2, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x7003, 0x0002,
-+	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c, 0x3c33,
-+	0x1120, 0x781b, 0x0054, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c33,
-+	0x1128, 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005, 0x080c,
-+	0x3c33, 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005,
-+	0x080c, 0x3c33, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003, 0x0004,
-+	0x0005, 0x080c, 0x3c33, 0x1150, 0x2011, 0x0006, 0x0041, 0x7078,
-+	0x707b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0004, 0x0005, 0x7170,
-+	0xc1fc, 0x8107, 0x7882, 0x789b, 0x0080, 0xa286, 0x000c, 0x1120,
-+	0x7aaa, 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0,
-+	0x79aa, 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038,
-+	0x78ab, 0x0020, 0x7174, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
-+	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0113, 0x080c, 0x3c46,
-+	0x707f, 0x000f, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
-+	0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-+	0x601a, 0x00ce, 0x0005, 0x7014, 0xa005, 0x1138, 0x70d0, 0xd0b4,
-+	0x0128, 0x70b4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a0,
-+	0xa186, 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001,
-+	0xa212, 0x70b0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0,
-+	0x00c9, 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0,
-+	0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211,
-+	0x0110, 0x0041, 0x0cb0, 0x70a3, 0x0001, 0x00ce, 0x002e, 0x00de,
-+	0x001e, 0x0005, 0xade8, 0x0005, 0x70a8, 0xad06, 0x1110, 0x70a4,
-+	0x2068, 0x0005, 0x080c, 0x3c33, 0x1904, 0x259d, 0x7078, 0x2068,
-+	0x7770, 0x080c, 0x3b6f, 0x2c50, 0x080c, 0x3cce, 0x789b, 0x0080,
-+	0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001,
-+	0x2001, 0x0004, 0x0804, 0x2824, 0x080c, 0x3c33, 0x1904, 0x259d,
-+	0x789b, 0x0080, 0x705c, 0x2068, 0x6f14, 0x70d0, 0xd0b4, 0x0168,
-+	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
-+	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x080c, 0x3b6f, 0x2c50,
-+	0x080c, 0x3cce, 0x6824, 0xa005, 0x0130, 0xa082, 0x0006, 0x0208,
-+	0x0010, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa,
-+	0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2824,
-+	0xc28d, 0x72d2, 0x72bc, 0xa200, 0xa015, 0x7150, 0x8108, 0xa12a,
-+	0x0208, 0x71bc, 0x2164, 0x6504, 0x85ff, 0x1170, 0x7152, 0x8421,
-+	0x1da8, 0x70d0, 0xd08c, 0x0128, 0x70cc, 0xa005, 0x1110, 0x70cf,
-+	0x000a, 0x0005, 0x2200, 0x0c90, 0x70d0, 0xc08c, 0x70d2, 0x70cf,
-+	0x0000, 0x6034, 0xa005, 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0,
-+	0xd7d4, 0x1d80, 0xa784, 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130,
-+	0xa784, 0x0004, 0x0d38, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218,
-+	0x1d08, 0xa784, 0x0100, 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc,
-+	0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
-+	0x6318, 0x0128, 0x601c, 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff,
-+	0x1948, 0x2d58, 0x2c50, 0x7152, 0xd7bc, 0x1120, 0x7028, 0x6022,
-+	0x603a, 0x0010, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100,
-+	0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0,
-+	0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110,
-+	0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, 0x27d6, 0xc7a5, 0x670a,
-+	0x2c00, 0x68c6, 0x77a0, 0xa786, 0x0001, 0x1178, 0x70d0, 0xd0b4,
-+	0x1160, 0x7000, 0xa082, 0x0002, 0x1240, 0x7830, 0xd0bc, 0x1128,
-+	0x789b, 0x0080, 0x7baa, 0x0804, 0x281d, 0x8739, 0x77a2, 0x2750,
-+	0x77ac, 0xa7b0, 0x0005, 0x70a8, 0xa606, 0x1108, 0x76a4, 0x76ae,
-+	0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738,
-+	0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, 0x8000, 0x2091, 0x303d,
-+	0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000,
-+	0x0120, 0x8421, 0x2200, 0x1904, 0x2725, 0x0005, 0xd1dc, 0x0904,
-+	0x37ce, 0x2029, 0x0020, 0xd69c, 0x1120, 0x8528, 0xd68c, 0x1108,
-+	0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70c8,
-+	0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, 0xa706, 0x1dd0, 0x60b8,
-+	0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a,
-+	0x2200, 0x8421, 0x1904, 0x2725, 0x0005, 0x2a60, 0x610e, 0x69be,
-+	0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a0, 0xa786,
-+	0x0001, 0x1904, 0x27ad, 0x70d0, 0xd0b4, 0x1904, 0x27ad, 0x7000,
-+	0xa082, 0x0002, 0x1a04, 0x27ad, 0x7830, 0xd0bc, 0x1904, 0x27ad,
-+	0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x0006,
-+	0x6018, 0x8000, 0x601a, 0x0008, 0x0006, 0x2960, 0x6104, 0x2a60,
-+	0x080c, 0x3ce1, 0x1590, 0xa184, 0x0018, 0x0180, 0xa184, 0x0010,
-+	0x0118, 0x080c, 0x3977, 0x1548, 0xa184, 0x0008, 0x0138, 0x69a0,
-+	0xa184, 0x0600, 0x1118, 0x080c, 0x3895, 0x00f8, 0x69a0, 0xa184,
-+	0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, 0x00c6, 0x2960, 0x6000,
-+	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x00ce,
-+	0x080c, 0x3977, 0x1150, 0x69a0, 0xa184, 0x0200, 0x0118, 0x080c,
-+	0x38da, 0x0018, 0xa184, 0x0400, 0x19f0, 0x69a0, 0xa184, 0x1000,
-+	0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, 0x080c, 0x239c, 0x002e,
-+	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, 0xa086, 0x0060, 0x1110,
-+	0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800,
-+	0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0168, 0xc0fc, 0x7083,
-+	0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, 0x000c, 0x7182, 0x2001,
-+	0x000c, 0x800c, 0x7186, 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000,
-+	0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b,
-+	0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020, 0x1508,
-+	0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x6814,
-+	0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, 0x0904, 0x28f5, 0x70a0,
-+	0x8000, 0x70a2, 0x74b0, 0xa498, 0x0005, 0x70a8, 0xa306, 0x1108,
-+	0x73a4, 0x73b2, 0xa286, 0x0010, 0x0904, 0x259d, 0x00de, 0x00ce,
-+	0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, 0x0002, 0x1904, 0x290c,
-+	0x080c, 0x3c33, 0x19a8, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
-+	0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-+	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
-+	0x0126, 0x00d6, 0x00c6, 0x70d0, 0xa084, 0x2e00, 0x2090, 0x00ce,
-+	0x00de, 0x012e, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002,
-+	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x7830, 0xd0bc, 0x0140,
-+	0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
-+	0x70a0, 0xa005, 0x1108, 0x0005, 0x8421, 0x0de8, 0x724c, 0x70bc,
-+	0xa200, 0xa015, 0x0804, 0x2725, 0xa286, 0x0010, 0x1560, 0x080c,
-+	0x3c33, 0x1904, 0x28a0, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b,
-+	0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-+	0x78da, 0x7808, 0xc08d, 0x780a, 0x70a0, 0x8000, 0x70a2, 0x74b0,
-+	0xa490, 0x0005, 0x70a8, 0xa206, 0x1108, 0x72a4, 0x72b2, 0x2900,
-+	0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80,
-+	0x0009, 0x7042, 0x0005, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814,
-+	0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2,
-+	0x7eda, 0x781b, 0x0068, 0x2900, 0x7056, 0x7202, 0x7808, 0xc08d,
-+	0x780a, 0x2300, 0xa605, 0x0170, 0x70d0, 0xa084, 0x2e00, 0xa086,
-+	0x2600, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x0001, 0xa284,
-+	0x000f, 0x0023, 0xad80, 0x0009, 0x7042, 0x0005, 0x296e, 0x41d9,
-+	0x41d9, 0x41c7, 0x41d9, 0x296e, 0x296e, 0x296e, 0x080c, 0x254c,
-+	0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4600, 0x78ac,
-+	0x00fe, 0xd084, 0x01b0, 0x7060, 0xa086, 0x0001, 0x0904, 0x2a32,
-+	0x7060, 0xa086, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
-+	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063,
-+	0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x2682,
-+	0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0160, 0xa186,
-+	0x0007, 0x1118, 0x701f, 0x0005, 0x0030, 0x701f, 0x0001, 0x70d0,
-+	0xc0c5, 0x70d2, 0x0000, 0x2001, 0x460a, 0x2004, 0xa084, 0x00ff,
-+	0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3,
-+	0x0001, 0x0066, 0x080c, 0x3f26, 0x20a9, 0x0010, 0x2039, 0x0000,
-+	0x080c, 0x3a66, 0xa7b8, 0x0100, 0x1f04, 0x29c0, 0x006e, 0x7000,
-+	0x0002, 0x29fd, 0x29db, 0x29db, 0x29d3, 0x29fd, 0x29fd, 0x29fd,
-+	0x29d1, 0x080c, 0x254c, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118,
-+	0x6800, 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c,
-+	0x3b6f, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37a4, 0x0020, 0x7058,
-+	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
-+	0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084,
-+	0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2, 0x2011, 0x0004, 0x74c8,
-+	0xa4a0, 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101,
-+	0x74c8, 0x0479, 0x8420, 0x1f04, 0x2a09, 0x70c0, 0x2060, 0x2021,
-+	0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016,
-+	0x0006, 0x2011, 0x4602, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e,
-+	0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4604, 0x2204, 0xc0a5,
-+	0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a13, 0x8421,
-+	0x1d00, 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000,
-+	0x0005, 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006,
-+	0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00,
-+	0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2,
-+	0x000e, 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003,
-+	0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2a60, 0x2add, 0x2af7,
-+	0xa282, 0x0002, 0x0110, 0x080c, 0x254c, 0x7060, 0x7063, 0x0000,
-+	0x707f, 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2a77,
-+	0x2a77, 0x2a79, 0x2ab1, 0x37d8, 0x2a77, 0x2ab1, 0x2a77, 0x080c,
-+	0x254c, 0x7770, 0x080c, 0x3a66, 0x7770, 0xa7bc, 0x8f00, 0x080c,
-+	0x3b6f, 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
-+	0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c,
-+	0x2b11, 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021,
-+	0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046, 0x2009, 0x0005, 0x2011,
-+	0x0010, 0x080c, 0x2b11, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2a9c,
-+	0x015e, 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25a0, 0x0804,
-+	0x25a0, 0x7770, 0x080c, 0x3b6f, 0x6018, 0xa005, 0x0520, 0xd7fc,
-+	0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005,
-+	0x2011, 0x0020, 0x080c, 0x2b11, 0x01b0, 0x0156, 0x20a9, 0x0101,
-+	0xd7fc, 0x1118, 0x2021, 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046,
-+	0x2009, 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420,
-+	0x1f04, 0x2acf, 0x015e, 0x0804, 0x25a0, 0x2200, 0x0002, 0x2ae2,
-+	0x2ae4, 0x2ae4, 0x080c, 0x254c, 0x2009, 0x0012, 0x7060, 0xa086,
-+	0x0002, 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a,
-+	0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2, 0x0804, 0x3be5, 0x2200,
-+	0x0002, 0x2afe, 0x2ae4, 0x2afc, 0x080c, 0x254c, 0x080c, 0x3f26,
-+	0x7000, 0xa086, 0x0002, 0x1904, 0x375d, 0x080c, 0x37be, 0x6008,
-+	0xa084, 0xfbef, 0x600a, 0x080c, 0x374f, 0x0904, 0x375d, 0x0804,
-+	0x25a0, 0x2404, 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814,
-+	0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a,
-+	0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e,
-+	0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, 0x080c, 0x1da2, 0x2021,
-+	0x4602, 0x241c, 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128,
-+	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef,
-+	0x600a, 0x080c, 0x269e, 0x080c, 0x37be, 0x0005, 0xa085, 0x0001,
-+	0x0ce0, 0x2300, 0x0002, 0x2b50, 0x2b4e, 0x2bcb, 0x080c, 0x254c,
-+	0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104,
-+	0x259d, 0x0010, 0x0304, 0x259d, 0x2008, 0xa084, 0x0030, 0x1110,
-+	0x0804, 0x322a, 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x7884, 0xd0fc,
-+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
-+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2bae,
-+	0x2bb7, 0x2ba4, 0x2b87, 0x3c29, 0x3c29, 0x2b87, 0x2bc1, 0x080c,
-+	0x254c, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, 0x0002,
-+	0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56, 0x7060,
-+	0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, 0x79e4,
-+	0x2001, 0x0003, 0x0804, 0x2f18, 0x6818, 0xd0fc, 0x0110, 0x681b,
-+	0x001d, 0x080c, 0x3a3c, 0x781b, 0x006e, 0x0005, 0x6818, 0xd0fc,
-+	0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x0804, 0x3c07, 0x6818,
-+	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x781b, 0x00fa,
-+	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c,
-+	0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, 0x0002,
-+	0x25a0, 0x2bd8, 0x2bda, 0x375d, 0x375d, 0x375d, 0x2bd8, 0x2bd8,
-+	0x080c, 0x254c, 0x080c, 0x37be, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x080c, 0x374f, 0x0904, 0x375d, 0x0804, 0x25a0, 0x78e4, 0xa005,
-+	0x1b04, 0x2b89, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x2b89,
-+	0x0010, 0x0304, 0x2b89, 0x2008, 0xa084, 0x0030, 0x1118, 0x781b,
-+	0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc,
-+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
-+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c26,
-+	0x2c2a, 0x2c21, 0x2c1f, 0x3c29, 0x3c29, 0x2c1f, 0x3c23, 0x080c,
-+	0x254c, 0x080c, 0x3a42, 0x781b, 0x006e, 0x0005, 0x080c, 0x3a42,
-+	0x0804, 0x3c07, 0x080c, 0x3a42, 0x781b, 0x00fa, 0x0005, 0x080c,
-+	0x3a42, 0x781b, 0x00cb, 0x0005, 0x2300, 0x0002, 0x2c3b, 0x2c39,
-+	0x2c3d, 0x080c, 0x254c, 0x0804, 0x33e2, 0x681b, 0x0016, 0x78a3,
-+	0x0000, 0x79e4, 0xa184, 0x0030, 0x0904, 0x33e2, 0x78ec, 0xa084,
-+	0x0003, 0x0904, 0x33e2, 0xa184, 0x0100, 0x0d98, 0x7884, 0xd0fc,
-+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
-+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c6f,
-+	0x2c2a, 0x2ba4, 0x3be5, 0x3c29, 0x3c29, 0x3be5, 0x3c23, 0x080c,
-+	0x3bf1, 0x0005, 0xa282, 0x0005, 0x0310, 0x080c, 0x254c, 0x7898,
-+	0x2040, 0x2300, 0x0002, 0x2c7e, 0x2ea8, 0x2eb2, 0x2200, 0x0002,
-+	0x2c9a, 0x2c87, 0x2c9a, 0x2c85, 0x2e8a, 0x080c, 0x254c, 0x789b,
-+	0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04,
-+	0x3a0b, 0xa08a, 0x0004, 0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x3a0b,
-+	0x3a0b, 0x39c1, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148,
-+	0x0804, 0x3a0b, 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804,
-+	0x3594, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3a0b, 0x0002,
-+	0x2cc2, 0x2cc0, 0x2cd4, 0x2cd8, 0x2d86, 0x3a0b, 0x3a0b, 0x2d88,
-+	0x3a0b, 0x3a0b, 0x2e86, 0x2e86, 0x3a0b, 0x3a0b, 0x3a0b, 0x2e88,
-+	0x080c, 0x254c, 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000,
-+	0x783a, 0x781b, 0x00c7, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b,
-+	0x001d, 0x0c90, 0x0804, 0x3be5, 0x681b, 0x001d, 0x0804, 0x3a36,
-+	0x6920, 0x6922, 0xa684, 0x1800, 0x1904, 0x2d29, 0x6820, 0xd084,
-+	0x1904, 0x2d31, 0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000,
-+	0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083, 0x0000, 0x6818, 0xa084,
-+	0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a, 0x000c, 0x7182, 0x2001,
-+	0x000c, 0x800c, 0x7186, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136,
-+	0x0146, 0x0016, 0x3208, 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b,
-+	0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac,
-+	0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6038,
-+	0xa005, 0x1150, 0x681c, 0xa084, 0x000e, 0x0904, 0x3a36, 0x080c,
-+	0x3a48, 0x782b, 0x3008, 0x0010, 0x8001, 0x603a, 0x781b, 0x0071,
-+	0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083,
-+	0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0,
-+	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084,
-+	0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-+	0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a,
-+	0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3f26,
-+	0x080c, 0x41d9, 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c,
-+	0x42b5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120,
-+	0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6,
-+	0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6,
-+	0x781b, 0x0080, 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118,
-+	0x080c, 0x41d9, 0x0005, 0x080c, 0x4206, 0x0005, 0x080c, 0x254c,
-+	0x0804, 0x2e1c, 0x00c6, 0x7054, 0x2060, 0x6920, 0xa18c, 0xecff,
-+	0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002, 0x080c, 0x38f4, 0xa006,
-+	0x2040, 0x2038, 0x080c, 0x399c, 0x0804, 0x2e10, 0x00c6, 0x7054,
-+	0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, 0x11d8,
-+	0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
-+	0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, 0x080c, 0x399c, 0x0804,
-+	0x2e10, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, 0x6106,
-+	0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, 0xa184,
-+	0x0010, 0x0548, 0x080c, 0x3b6b, 0x080c, 0x3977, 0x88ff, 0x0518,
-+	0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
-+	0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
-+	0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, 0xc0ec,
-+	0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006,
-+	0x2010, 0x080c, 0x399c, 0xa286, 0x0001, 0x0158, 0x6104, 0xa184,
-+	0x0008, 0x01b0, 0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x1980,
-+	0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, 0x6000,
-+	0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
-+	0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b,
-+	0x0083, 0x0005, 0x0804, 0x3a32, 0x2808, 0x789b, 0x0080, 0x2019,
-+	0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x11b8, 0x2300,
-+	0xa102, 0xa086, 0x0001, 0x0904, 0x2d8a, 0x7ca8, 0xa4a4, 0x00ff,
-+	0xa480, 0x0002, 0xa300, 0x2018, 0xa102, 0x0a04, 0x2d9e, 0x0904,
-+	0x2d9e, 0x24a8, 0x7aa8, 0x1f04, 0x2e3a, 0x0c18, 0xa284, 0x00f0,
-+	0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, 0x0021, 0x1698, 0x7aa8,
-+	0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0, 0xa286, 0x0023, 0x0950,
-+	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
-+	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x78a0, 0x8001, 0x0904,
-+	0x2e10, 0x20a8, 0x7998, 0x789b, 0x0060, 0x78aa, 0x2011, 0x0080,
-+	0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, 0x7a98, 0x1f04, 0x2e68,
-+	0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b,
-+	0x0082, 0x0005, 0x8318, 0x2100, 0xa302, 0x0a04, 0x2e21, 0xa284,
-+	0x0080, 0x1904, 0x3a36, 0x78a0, 0xa005, 0x08c8, 0x0804, 0x3a36,
-+	0x0804, 0x3a0b, 0x7054, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084,
-+	0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, 0x254c, 0x7aa8, 0xa294,
-+	0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005,
-+	0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x380c, 0x3a0b, 0x3927, 0x3d31,
-+	0xa282, 0x0000, 0x1110, 0x080c, 0x254c, 0x080c, 0x3a3c, 0x781b,
-+	0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x254c, 0xd4fc,
-+	0x11d0, 0x7060, 0xa005, 0x0110, 0x080c, 0x254c, 0x6f14, 0x7772,
-+	0xa7bc, 0x8f00, 0x080c, 0x3b6f, 0x6008, 0xa085, 0x0021, 0x600a,
-+	0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x3a3f, 0x7063, 0x0002,
-+	0x701f, 0x0009, 0x0010, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005,
-+	0xa282, 0x0004, 0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2ee2,
-+	0x3078, 0x30b4, 0xa286, 0x0003, 0x0598, 0x7200, 0x7cd8, 0x7ddc,
-+	0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc, 0x1518, 0x2001, 0x4601,
-+	0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084, 0x00ff, 0x11d0, 0xa282,
-+	0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, 0x0059, 0x70b8,
-+	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-+	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x2001, 0x0000,
-+	0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, 0x0000, 0x0020,
-+	0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046, 0x68a0, 0xd0ec, 0x0118,
-+	0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, 0x3059, 0x2f33,
-+	0x2f30, 0x3184, 0x320f, 0x25a0, 0x2f2e, 0x2f2e, 0x080c, 0x254c,
-+	0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7044, 0xa086, 0x0014,
-+	0x11e8, 0x080c, 0x3f26, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0108,
-+	0x7044, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, 0x0008, 0x1904,
-+	0x301b, 0x7858, 0xd09c, 0x0904, 0x301b, 0x6820, 0xd0ac, 0x0904,
-+	0x301b, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, 0x7868, 0xa08c,
-+	0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, 0xc0a4, 0x600a,
-+	0x080c, 0x374f, 0x0540, 0x080c, 0x37be, 0x080c, 0x3f26, 0x0060,
-+	0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, 0x8001, 0x0d68,
-+	0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, 0x0904, 0x25a0,
-+	0xc084, 0x6822, 0x080c, 0x2693, 0x7058, 0x00c6, 0x2060, 0x6800,
-+	0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, 0x1108, 0x6002,
-+	0x6006, 0x0804, 0x25a0, 0x0016, 0x81ff, 0x15f0, 0x7000, 0xa086,
-+	0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8, 0xd1b4, 0x11e8, 0x705c,
-+	0xa005, 0x1590, 0x70a0, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000,
-+	0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x25c5,
-+	0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d0, 0xd1b4,
-+	0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3c33, 0x11a8, 0x781b,
-+	0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
-+	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
-+	0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x30dc, 0x001e, 0x81ff,
-+	0x0904, 0x301b, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14,
-+	0xa186, 0x0002, 0x1904, 0x301c, 0x6818, 0xa086, 0x0014, 0x1130,
-+	0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3a55,
-+	0x080c, 0x269e, 0x6820, 0xd0dc, 0x1578, 0x8717, 0xa294, 0x000f,
-+	0x8213, 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x4ac0,
-+	0x0010, 0xa290, 0x4b40, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0170,
-+	0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff, 0x6822, 0xc3ac, 0x2312,
-+	0x8210, 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138,
-+	0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3144, 0x0804, 0x25a0, 0x6008,
-+	0xc08d, 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110,
-+	0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168,
-+	0x2009, 0x4602, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
-+	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118,
-+	0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084,
-+	0x1130, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x7058,
-+	0x2060, 0x6800, 0x6002, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
-+	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
-+	0x616e, 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904,
-+	0x25a0, 0x7003, 0x0002, 0x7048, 0x2068, 0x68c4, 0x2060, 0x0005,
-+	0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065,
-+	0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005,
-+	0xa282, 0x0004, 0x0210, 0x080c, 0x254c, 0x2200, 0x0002, 0x3083,
-+	0x3092, 0x309e, 0x3092, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300,
-+	0x1d90, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
-+	0xfbef, 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3a3c,
-+	0x781b, 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007,
-+	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
-+	0x00ff, 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804,
-+	0x3a0b, 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff,
-+	0x1118, 0x080c, 0x3a3c, 0x0030, 0x8211, 0x0110, 0x080c, 0x254c,
-+	0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x080c, 0x3c46, 0x7830,
-+	0xa084, 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e,
-+	0x0118, 0x0104, 0x30d9, 0x0010, 0x0304, 0x30d9, 0x791a, 0xa006,
-+	0x0005, 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f,
-+	0x0000, 0x6833, 0x0000, 0x0804, 0x3143, 0xd6dc, 0x1198, 0x68b4,
-+	0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005,
-+	0x1130, 0x2200, 0xa105, 0x0904, 0x3f26, 0x7047, 0x0015, 0x0804,
-+	0x3f26, 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000,
-+	0x6833, 0x0000, 0x0804, 0x3f26, 0x68b4, 0xa084, 0x4000, 0xa635,
-+	0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0xd6dc,
-+	0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32,
-+	0x0804, 0x3f26, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000,
-+	0x0804, 0x3f26, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0,
-+	0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0x2408, 0x2510, 0x2700,
-+	0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32,
-+	0x2100, 0xa205, 0x1110, 0x0804, 0x3f26, 0x7000, 0xa086, 0x0006,
-+	0x0110, 0x0804, 0x3f26, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc,
-+	0x0108, 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f,
-+	0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
-+	0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
-+	0x0020, 0x7000, 0x0002, 0x25a0, 0x3173, 0x316d, 0x316b, 0x316b,
-+	0x316b, 0x316b, 0x316b, 0x080c, 0x254c, 0x6820, 0xd084, 0x1118,
-+	0x080c, 0x37a4, 0x0030, 0x7058, 0x2c50, 0x2060, 0x6800, 0x6002,
-+	0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8,
-+	0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, 0x37aa, 0x080c, 0x37be,
-+	0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14,
-+	0x6938, 0x691a, 0x6944, 0x6916, 0x2009, 0x0000, 0xae86, 0x4640,
-+	0x0110, 0x2009, 0x0001, 0x080c, 0x42ec, 0xd6dc, 0x01c8, 0x691c,
-+	0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e, 0x0290, 0x6848, 0xa084,
-+	0x000f, 0xa086, 0x000b, 0x1160, 0x685c, 0xa086, 0x0047, 0x1140,
-+	0x2001, 0x4601, 0x2004, 0xd0ac, 0x1118, 0x2700, 0x080c, 0x2475,
-+	0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000, 0x7868, 0xa08c, 0x00ff,
-+	0x0110, 0x681b, 0x001e, 0xaea0, 0x0017, 0x6800, 0x2022, 0x6a3c,
-+	0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0580,
-+	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, 0x00f6,
-+	0x0156, 0x0146, 0x2079, 0x4600, 0x080c, 0x1b93, 0x014e, 0x015e,
-+	0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, 0xa06d,
-+	0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, 0xc0d5,
-+	0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7063, 0x0003,
-+	0x707b, 0x0000, 0x7772, 0x707f, 0x000f, 0x71d0, 0xc1c4, 0x71d2,
-+	0x6818, 0xa086, 0x0002, 0x1138, 0x6817, 0x0000, 0x682b, 0x0000,
-+	0x681c, 0xc0ec, 0x681e, 0x080c, 0x1da2, 0x0804, 0x25a0, 0x7cd8,
-+	0x7ddc, 0x7fd0, 0x080c, 0x30dc, 0x682b, 0x0000, 0x789b, 0x000e,
-+	0x6f14, 0x080c, 0x3c4a, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc,
-+	0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7063, 0x0000,
-+	0x0804, 0x25a0, 0x7000, 0xa005, 0x1110, 0x0804, 0x25a0, 0xa006,
-+	0x080c, 0x3f26, 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c,
-+	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
-+	0x7000, 0x0002, 0x25a0, 0x324c, 0x324c, 0x324f, 0x324f, 0x324f,
-+	0x324a, 0x324a, 0x080c, 0x254c, 0x6818, 0x0804, 0x2f18, 0x6008,
-+	0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804, 0x3772, 0x2300, 0x0002,
-+	0x325b, 0x325d, 0x32ab, 0x080c, 0x254c, 0xd6fc, 0x1904, 0x2d38,
-+	0x7000, 0xa00d, 0x0002, 0x25a0, 0x326d, 0x326d, 0x3297, 0x326d,
-+	0x32a8, 0x326b, 0x326b, 0x080c, 0x254c, 0xa684, 0x0060, 0x0538,
-+	0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6,
-+	0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f26,
-+	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
-+	0x41d9, 0x781b, 0x0083, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0,
-+	0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818,
-+	0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b, 0x0015, 0x781b, 0x0083,
-+	0x0804, 0x259d, 0x681b, 0x0007, 0x682f, 0x0000, 0x6833, 0x0000,
-+	0x080c, 0x3bf1, 0x0005, 0x080c, 0x254c, 0x2300, 0x0002, 0x32b4,
-+	0x32d6, 0x332e, 0x080c, 0x254c, 0x7000, 0x0002, 0x32be, 0x32c0,
-+	0x32c7, 0x32be, 0x32be, 0x32be, 0x32be, 0x32be, 0x080c, 0x254c,
-+	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
-+	0x41d9, 0x681c, 0xc0b4, 0x681e, 0x70d0, 0xd0b4, 0x1904, 0x259d,
-+	0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6fc, 0x1904,
-+	0x331e, 0x7000, 0xa00d, 0x0002, 0x25a0, 0x32ec, 0x32e6, 0x3316,
-+	0x32ec, 0x331b, 0x32e4, 0x32e4, 0x080c, 0x254c, 0x6894, 0x78d6,
-+	0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0538, 0xa086,
-+	0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0x6eb6, 0xa186,
-+	0x0002, 0x0148, 0x080c, 0x3f26, 0x69ac, 0x68b0, 0xa115, 0x0118,
-+	0x080c, 0x4206, 0x0010, 0x080c, 0x41d9, 0x781b, 0x0083, 0x681c,
-+	0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0, 0xa086,
-+	0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818, 0xd0fc,
-+	0x0110, 0x681b, 0x0007, 0x781b, 0x00fb, 0x0005, 0xc6fc, 0x7e5a,
-+	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083, 0x0005, 0xd6dc, 0x0130,
-+	0x782b, 0x3009, 0x781b, 0x0083, 0x0804, 0x259d, 0x7884, 0xc0ac,
-+	0x7886, 0x78e4, 0xa084, 0x0008, 0x1150, 0xa484, 0x0200, 0x0108,
-+	0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083, 0x0804, 0x259d, 0x6820,
-+	0xc095, 0x6822, 0x080c, 0x3bdc, 0xc6dd, 0x080c, 0x3a3c, 0x781b,
-+	0x0082, 0x0804, 0x259d, 0x2300, 0x0002, 0x3358, 0x335a, 0x335c,
-+	0x080c, 0x254c, 0x0804, 0x3a36, 0x7d98, 0xd6d4, 0x15a8, 0x79e4,
-+	0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003, 0x0110, 0x782b, 0x3009,
-+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a,
-+	0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1120, 0x2001,
-+	0x0014, 0x0804, 0x2f18, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
-+	0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
-+	0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
-+	0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b,
-+	0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384,
-+	0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009,
-+	0xffdf, 0x0058, 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028,
-+	0xa386, 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6, 0x7054, 0x2060,
-+	0x6004, 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000,
-+	0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff,
-+	0x6922, 0x7d9a, 0x0804, 0x3be5, 0x2bae, 0x2bb7, 0x33d6, 0x33dc,
-+	0x33d4, 0x33d4, 0x3be5, 0x3be5, 0x080c, 0x254c, 0x6920, 0xa18c,
-+	0xfcff, 0x6922, 0x0804, 0x3beb, 0x6920, 0xa18c, 0xfcff, 0x6922,
-+	0x0804, 0x3be5, 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084,
-+	0x0003, 0x1570, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086,
-+	0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56,
-+	0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90,
-+	0x7000, 0xa086, 0x0000, 0x0904, 0x259d, 0x6920, 0xa184, 0x0420,
-+	0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804, 0x2f18, 0x6818, 0xa08e,
-+	0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0804, 0x2f18,
-+	0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007,
-+	0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007,
-+	0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001,
-+	0x0002, 0x3be5, 0x3be5, 0x3439, 0x3be5, 0x3c29, 0x3c29, 0x3be5,
-+	0x3be5, 0xd6bc, 0x0570, 0x7180, 0x81ff, 0x0558, 0xa182, 0x000d,
-+	0x1318, 0x7083, 0x0000, 0x0028, 0xa182, 0x000c, 0x7082, 0x2009,
-+	0x000c, 0x789b, 0x0061, 0x79aa, 0x0156, 0x0136, 0x0146, 0x7084,
-+	0x8114, 0xa210, 0x7286, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284,
-+	0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b,
-+	0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804,
-+	0x3beb, 0xd6d4, 0x1904, 0x34ac, 0x6820, 0xd084, 0x0904, 0x3beb,
-+	0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060, 0x1108,
-+	0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000,
-+	0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c,
-+	0x0904, 0x37d3, 0xa18c, 0x00f8, 0x1904, 0x37d3, 0x0156, 0x0136,
-+	0x0146, 0x0016, 0x20a1, 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110,
-+	0x20a1, 0x022b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-+	0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc,
-+	0x8007, 0x7882, 0x0804, 0x3beb, 0x6818, 0xd0fc, 0x0110, 0x681b,
-+	0x0008, 0x080c, 0x3a3c, 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002,
-+	0x34bd, 0x357a, 0x34bb, 0x080c, 0x254c, 0x7cd8, 0x7ddc, 0x7fd0,
-+	0x82ff, 0x1528, 0x7200, 0xa286, 0x0003, 0x0904, 0x2ee6, 0x71d0,
-+	0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001, 0x4601, 0x2004, 0xd0c4,
-+	0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b, 0x0059, 0x70b8, 0xa06d,
-+	0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-+	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200,
-+	0x0020, 0x783b, 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002,
-+	0x3565, 0x3522, 0x34fa, 0x2f15, 0x34f8, 0x3565, 0x34f8, 0x34f8,
-+	0x080c, 0x254c, 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a,
-+	0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002,
-+	0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1120, 0x71c8,
-+	0xa188, 0x0100, 0x0028, 0x7030, 0x68ba, 0x713c, 0x70c8, 0xa108,
-+	0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc, 0x1120, 0xc6fc, 0x6eb6,
-+	0x0804, 0x3565, 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff,
-+	0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894,
-+	0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f26, 0x0478, 0xd6ac, 0x0140,
-+	0xa006, 0x080c, 0x3f26, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068,
-+	0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
-+	0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f26, 0xd6fc, 0x01b0, 0xa684,
-+	0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007,
-+	0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
-+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030,
-+	0x1904, 0x25a0, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e,
-+	0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009,
-+	0x7042, 0x0005, 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018,
-+	0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3a36,
-+	0x7043, 0x0000, 0xa282, 0x0006, 0x0310, 0x080c, 0x254c, 0x2300,
-+	0x0002, 0x3594, 0x35a5, 0x35af, 0x2200, 0x0002, 0x359c, 0x3a36,
-+	0x359e, 0x359c, 0x35e0, 0x362e, 0x080c, 0x254c, 0x7a80, 0xa294,
-+	0x0f00, 0x080c, 0x3682, 0x0804, 0x3a0b, 0x00c1, 0x0002, 0x3a36,
-+	0x35ad, 0x35ad, 0x35e0, 0x35ad, 0x3a36, 0x080c, 0x254c, 0x0071,
-+	0x0002, 0x35b9, 0x35b7, 0x35b7, 0x35b9, 0x35b7, 0x35b9, 0x080c,
-+	0x254c, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x7000, 0xa086,
-+	0x0002, 0x1150, 0x080c, 0x37be, 0x0010, 0x080c, 0x3f26, 0x6008,
-+	0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8,
-+	0x7003, 0x0005, 0x2001, 0x8de0, 0xae8e, 0x4640, 0x0110, 0x2001,
-+	0x8e12, 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, 0x2200, 0x0005,
-+	0x7000, 0xa086, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
-+	0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c, 0x3f26, 0x0020, 0x7000,
-+	0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
-+	0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x8cc0,
-+	0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8dd0, 0x2d04, 0x2d08,
-+	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0120, 0x6800, 0x0cb8,
-+	0x080c, 0x3682, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0904,
-+	0x36a8, 0x7060, 0xa086, 0x0006, 0x1128, 0x7070, 0xa206, 0x1110,
-+	0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad, 0x681b, 0x0005, 0xc1ad,
-+	0xc1d4, 0x6922, 0x080c, 0x3a42, 0x0804, 0x36a8, 0x7200, 0xa286,
-+	0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00,
-+	0x70ba, 0x0030, 0x080c, 0x3f26, 0x0018, 0xa286, 0x0003, 0x0dd0,
-+	0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-+	0xa484, 0x001f, 0xa215, 0xae86, 0x4640, 0x0108, 0xc2fd, 0x79a8,
-+	0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8, 0xa168, 0x2d04, 0x2d08,
-+	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0118, 0x6800, 0x0cb8,
-+	0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0904, 0x36a8, 0xd0dc,
-+	0x0178, 0x7060, 0xa086, 0x0004, 0x1140, 0x7070, 0xa206, 0x1128,
-+	0x7074, 0xa306, 0x1110, 0x7062, 0x707a, 0x080c, 0x3a48, 0x0480,
-+	0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a42, 0x707b,
-+	0x0000, 0x0430, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001,
-+	0x8de0, 0x0010, 0x2001, 0x8e12, 0x2068, 0x704a, 0x0156, 0x20a9,
-+	0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x3691, 0x015e, 0xb284,
-+	0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0xad80, 0x0009,
-+	0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0005,
-+	0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x36ef, 0x6b98, 0x6c94, 0x69ac,
-+	0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586,
-+	0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a,
-+	0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, 0x0082, 0x2019, 0x0000,
-+	0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c, 0x41d9, 0x0470, 0x68b0,
-+	0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01f8, 0x7bd2, 0x7bda,
-+	0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108, 0xc6ed, 0xc6f4, 0x7e5a,
-+	0x2011, 0x0083, 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000,
-+	0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c, 0x4206, 0x0070, 0x2019,
-+	0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083,
-+	0xd69c, 0x0110, 0x2009, 0x0082, 0x791a, 0x68c0, 0x7056, 0x2d00,
-+	0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001, 0x4601, 0x2004, 0xd0c4,
-+	0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80, 0xa294,
-+	0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558, 0x70d6,
-+	0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218, 0x8633,
-+	0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130, 0x2011,
-+	0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217, 0x7880,
-+	0xa084, 0x0f00, 0xa206, 0x0170, 0x72da, 0x76d6, 0x0058, 0x7a80,
-+	0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0, 0x78e0, 0xa534, 0x0da8,
-+	0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x259d, 0x2300, 0xa405, 0x0904,
-+	0x259d, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0x6020,
-+	0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a,
-+	0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3f26,
-+	0x7000, 0xa086, 0x0002, 0x0120, 0x7060, 0xa086, 0x0005, 0x1150,
-+	0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
-+	0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x25a0, 0x3783,
-+	0x3780, 0x37a0, 0x378c, 0x25a0, 0x377e, 0x377e, 0x080c, 0x254c,
-+	0x0449, 0x0411, 0x0028, 0x0431, 0x7058, 0x2060, 0x6800, 0x6002,
-+	0x080c, 0x1da2, 0x0804, 0x25a0, 0x7060, 0x7063, 0x0000, 0x707f,
-+	0x0000, 0x0002, 0x379c, 0x379c, 0x379a, 0x379a, 0x379a, 0x379c,
-+	0x379a, 0x379c, 0x0804, 0x2a6b, 0x7063, 0x0000, 0x0804, 0x25a0,
-+	0x681b, 0x0000, 0x0804, 0x3184, 0x6800, 0xa005, 0x1108, 0x6002,
-+	0x6006, 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4602, 0x2104,
-+	0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4604, 0x2404,
-+	0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005,
-+	0x0110, 0x8001, 0x601a, 0x0005, 0x080c, 0x3c46, 0x681b, 0x0018,
-+	0x0490, 0x080c, 0x3c46, 0x681b, 0x0019, 0x0468, 0x080c, 0x3c46,
-+	0x681b, 0x001a, 0x0440, 0x080c, 0x3c46, 0x681b, 0x0003, 0x0418,
-+	0x7770, 0x080c, 0x3b6f, 0x7174, 0xa18c, 0x00ff, 0x3210, 0xa294,
-+	0x0600, 0x0118, 0xa1e8, 0x8bc0, 0x0010, 0xa1e8, 0x8cd0, 0x2d04,
-+	0x2d08, 0x2068, 0xa005, 0x1118, 0x707a, 0x0804, 0x25a0, 0x6814,
-+	0x7270, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800, 0x200a, 0x681b,
-+	0x0005, 0x707b, 0x0000, 0x080c, 0x37aa, 0x6820, 0xd084, 0x1110,
-+	0x080c, 0x37a4, 0x080c, 0x37be, 0x681f, 0x0000, 0x6823, 0x0020,
-+	0x080c, 0x1da2, 0x0804, 0x25a0, 0xa282, 0x0003, 0x1904, 0x3a10,
-+	0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd,
-+	0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0530,
-+	0xa682, 0x0018, 0x0218, 0x0110, 0x2031, 0x0018, 0xa686, 0x0010,
-+	0x1108, 0x8630, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9,
-+	0x0118, 0x080c, 0x38f7, 0x00a0, 0x080c, 0x3a95, 0x080c, 0x38f4,
-+	0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118,
-+	0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x080c, 0x38f4,
-+	0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083,
-+	0x0005, 0x00c6, 0x7054, 0x2060, 0x6100, 0xd1e4, 0x0598, 0x6208,
-+	0x8217, 0xa294, 0x00ff, 0xa282, 0x0018, 0x0218, 0x0110, 0x2011,
-+	0x0018, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010, 0x1108,
-+	0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
-+	0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
-+	0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, 0x3a99,
-+	0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9, 0x0118, 0x080c,
-+	0x38f7, 0x0020, 0x080c, 0x3a95, 0x080c, 0x38f4, 0x7858, 0xc095,
-+	0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, 0x6000,
-+	0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010, 0xa084, 0x000f, 0x1130,
-+	0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032,
-+	0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294,
-+	0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011,
-+	0x000a, 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308,
-+	0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018, 0x0218, 0x0110, 0x2019,
-+	0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
-+	0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3a55,
-+	0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106,
-+	0x2011, 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab,
-+	0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
-+	0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6,
-+	0x7154, 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86,
-+	0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c,
-+	0x000f, 0xa105, 0x2029, 0x4605, 0x252c, 0xd5cc, 0x0140, 0xd3a4,
-+	0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6,
-+	0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605,
-+	0x600e, 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282,
-+	0x0002, 0x1904, 0x3a1a, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc,
-+	0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04,
-+	0x3a0b, 0x080c, 0x399e, 0x080c, 0x38f4, 0xa980, 0x0001, 0x200c,
-+	0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x0178, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
-+	0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118,
-+	0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002,
-+	0x1218, 0xa284, 0x0001, 0x0140, 0x7154, 0xa188, 0x0000, 0x210c,
-+	0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c, 0x3a87, 0x0479, 0x080c,
-+	0x38f4, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6,
-+	0x0026, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1158, 0xd0bc,
-+	0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088,
-+	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-+	0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a55, 0x6820, 0xa085, 0x0200,
-+	0x6822, 0x002e, 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009,
-+	0x0000, 0x7054, 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018,
-+	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec,
-+	0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020,
-+	0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce,
-+	0x0005, 0x0006, 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010,
-+	0x000e, 0x0488, 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558,
-+	0x7bb8, 0x8307, 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff,
-+	0xa09e, 0x0001, 0x1904, 0x3a32, 0xd6f4, 0x11d0, 0x79d8, 0x7adc,
-+	0xa108, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c,
-+	0x42b5, 0x781b, 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000,
-+	0x0010, 0x2001, 0x0001, 0x080c, 0x4172, 0x0005, 0x080c, 0x254c,
-+	0x781b, 0x0080, 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000,
-+	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
-+	0x080c, 0x399c, 0x7e58, 0x080c, 0x3a4e, 0x781b, 0x0082, 0x0005,
-+	0x0cd1, 0x6820, 0xc0c4, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c,
-+	0x3921, 0x00b0, 0x0c81, 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054,
-+	0x2060, 0x080c, 0x39bb, 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff,
-+	0x6822, 0x00c6, 0x7054, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006,
-+	0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, 0x0005, 0x6827, 0x0002,
-+	0x0049, 0x781b, 0x0082, 0x0005, 0x2001, 0x0005, 0x0088, 0x2001,
-+	0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040,
-+	0x2001, 0x000d, 0x0028, 0x2001, 0x0009, 0x0010, 0x2001, 0x0007,
-+	0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168,
-+	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
-+	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f,
-+	0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x4ac0, 0xae8e,
-+	0x4640, 0x0110, 0xa0e0, 0x4b40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4,
-+	0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6,
-+	0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e, 0x0005, 0x789b,
-+	0x0080, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
-+	0x789b, 0x0060, 0x78ab, 0x0004, 0x0800, 0x2031, 0x0000, 0x2029,
-+	0x0032, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804,
-+	0x3a55, 0x0156, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080,
-+	0x0020, 0x789a, 0x79a4, 0xa18c, 0xffe0, 0x2021, 0x3b54, 0x2019,
-+	0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0,
-+	0xa106, 0x0128, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3abd, 0x015e,
-+	0x0005, 0x0156, 0x04f8, 0x2021, 0x3b62, 0x20a9, 0x0009, 0x2011,
-+	0x0029, 0xa582, 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033,
-+	0xa582, 0x0033, 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011,
-+	0x0065, 0x2200, 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04,
-+	0x3ae1, 0x015e, 0x0088, 0x2021, 0x3b54, 0x2019, 0x0011, 0x20a9,
-+	0x000e, 0x2011, 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300,
-+	0xa210, 0x1f04, 0x3af3, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e,
-+	0xa582, 0x0064, 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404,
-+	0xa005, 0x0005, 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b40, 0x20a9,
-+	0x000d, 0x2011, 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019,
-+	0x0019, 0x2011, 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300,
-+	0xa210, 0x1f04, 0x3b1b, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185,
-+	0x0ab0, 0x0890, 0x2021, 0x3b4f, 0x20a9, 0x0003, 0x2011, 0x0024,
-+	0xa586, 0x0024, 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028,
-+	0x0930, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3af3,
-+	0x1021, 0x2202, 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610,
-+	0x4612, 0x5812, 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021,
-+	0xb002, 0xe204, 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203,
-+	0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07,
-+	0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06,
-+	0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784,
-+	0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003,
-+	0xa105, 0xd7fc, 0x0118, 0xa0e0, 0x6bc0, 0x0010, 0xa0e0, 0x4bc0,
-+	0x0005, 0x00e6, 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009,
-+	0x4680, 0x2071, 0x4680, 0x0030, 0x2009, 0x4640, 0x2079, 0x0200,
-+	0x2071, 0x4640, 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002,
-+	0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba0, 0x3ba0,
-+	0x080c, 0x254c, 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005,
-+	0x0580, 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828,
-+	0xa086, 0x1814, 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
-+	0x1de0, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830,
-+	0xd0bc, 0x11b8, 0xb284, 0x0800, 0x0118, 0x0104, 0x3bd9, 0x0010,
-+	0x0304, 0x3bd9, 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084,
-+	0x0003, 0x0138, 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b,
-+	0x00fb, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x4601, 0x2004, 0xd0ac,
-+	0x1118, 0x6814, 0x080c, 0x2475, 0x0005, 0x781b, 0x0083, 0x0005,
-+	0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e,
-+	0x0005, 0x2009, 0x4619, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186,
-+	0x0001, 0x0150, 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054,
-+	0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009,
-+	0x4619, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138,
-+	0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f,
-+	0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005,
-+	0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb,
-+	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x7063, 0x0001,
-+	0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808,
-+	0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084,
-+	0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d,
-+	0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800,
-+	0x0118, 0x1104, 0x3c58, 0x0010, 0x1304, 0x3c58, 0x78ac, 0x0005,
-+	0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
-+	0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104,
-+	0x3c67, 0x0010, 0x1304, 0x3c6a, 0x78ac, 0x0006, 0x7808, 0xa085,
-+	0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x322a,
-+	0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2467,
-+	0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008,
-+	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x0804, 0x3be5, 0xa784,
-+	0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008,
-+	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x78e4, 0xa084, 0x0007,
-+	0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a,
-+	0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc,
-+	0x0128, 0x080c, 0x3a32, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
-+	0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000,
-+	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2b89, 0xb284,
-+	0x0800, 0x0110, 0x0104, 0x259d, 0x0304, 0x259d, 0x6b14, 0x8307,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
-+	0x4b40, 0x0010, 0xa080, 0x4ac0, 0x2060, 0x2048, 0x7056, 0x2a60,
-+	0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d2f, 0x68a0,
-+	0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d2d, 0x6108, 0x8117,
-+	0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001,
-+	0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110,
-+	0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec,
-+	0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248,
-+	0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029,
-+	0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa,
-+	0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820,
-+	0xa085, 0x1000, 0x6822, 0x080c, 0x3a55, 0xa085, 0x0001, 0x00ce,
-+	0x0005, 0xa282, 0x0006, 0x1904, 0x3a24, 0x7da8, 0x7eac, 0x8637,
-+	0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff,
-+	0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3da3,
-+	0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x39fe, 0xa6b4,
-+	0x00ff, 0x0904, 0x3da0, 0xa682, 0x0031, 0x1a04, 0x39fe, 0xa582,
-+	0x0009, 0x0a04, 0x39fe, 0xa882, 0x0003, 0x1a04, 0x39fe, 0xa886,
-+	0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x39fe, 0x2001, 0x000c,
-+	0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c,
-+	0x39fe, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
-+	0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x39fe,
-+	0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804,
-+	0x3df1, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
-+	0x3ac9, 0x0904, 0x39fe, 0x080c, 0x38f7, 0x080c, 0x399c, 0x7e58,
-+	0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005,
-+	0x080c, 0x38f4, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
-+	0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x39fe, 0xd1ec, 0x1120,
-+	0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000,
-+	0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff,
-+	0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f,
-+	0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705,
-+	0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000,
-+	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284,
-+	0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128,
-+	0x852b, 0x852b, 0x080c, 0x3ac9, 0x0d58, 0x080c, 0x38f7, 0x080c,
-+	0x399c, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
-+	0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa,
-+	0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c,
-+	0x3a55, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-+	0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9855, 0x984d, 0x0014,
-+	0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, 0x00e7, 0x0100, 0x0402,
-+	0x2008, 0xf880, 0x0018, 0x0017, 0x840f, 0xd8c1, 0x0014, 0x0016,
-+	0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500,
-+	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
-+	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806,
-+	0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d18, 0xa201,
-+	0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
-+	0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, 0xa83e, 0x300c, 0xa801,
-+	0x3008, 0x28e1, 0x9cce, 0x28a2, 0x7163, 0xa831, 0x2021, 0xa818,
-+	0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, 0x6c80,
-+	0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, 0x85f2,
-+	0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa813, 0x883e, 0xa811,
-+	0x2882, 0x7162, 0xa814, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0,
-+	0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861,
-+	0x883e, 0x206a, 0x28c1, 0x9d18, 0x2042, 0x2101, 0xa8ca, 0x2902,
-+	0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872,
-+	0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x7121, 0x0014,
-+	0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009,
-+	0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861,
-+	0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532,
-+	0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8,
-+	0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x2849, 0x1011, 0xa8fc,
-+	0x3008, 0x8000, 0xa000, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa889,
-+	0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, 0xa209, 0x0017, 0x300c,
-+	0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014,
-+	0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b,
-+	0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, 0x0704, 0xa206, 0x6865,
-+	0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa,
-+	0x8160, 0x842a, 0x8180, 0xf021, 0x3008, 0x84a8, 0x11d7, 0x7042,
-+	0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0,
-+	0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
-+	0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284,
-+	0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x7007, 0x0008,
-+	0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003,
-+	0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106,
-+	0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fa2, 0xa184, 0x01e0, 0x1904,
-+	0x3fa2, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
-+	0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20,
-+	0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008,
-+	0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4,
-+	0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130,
-+	0x080c, 0x40ae, 0x8aff, 0x0904, 0x3f2c, 0x0cb8, 0x700c, 0xa08c,
-+	0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148,
-+	0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102,
-+	0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x426b,
-+	0x1de8, 0x09d8, 0x080c, 0x4034, 0x012e, 0x2000, 0x0005, 0x7204,
-+	0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205,
-+	0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4601,
-+	0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x000e, 0x012e, 0x2000,
-+	0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f,
-+	0xa7b8, 0x3ff5, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x254c,
-+	0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x3fea, 0x2704, 0xae68,
-+	0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704,
-+	0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005,
-+	0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
-+	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x3fea, 0x3fe7,
-+	0x0000, 0x0000, 0x8000, 0x0000, 0x3fea, 0x0000, 0x3ff2, 0x3fef,
-+	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff2, 0x0000, 0x3fed, 0x3fed,
-+	0x0000, 0x0000, 0x8000, 0x0000, 0x3fed, 0x0000, 0x3ff3, 0x3ff3,
-+	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff3, 0x2079, 0x4600, 0x2071,
-+	0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009,
-+	0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
-+	0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118,
-+	0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x408a,
-+	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c,
-+	0x40e6, 0x0804, 0x40aa, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
-+	0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x40e6,
-+	0x0804, 0x40aa, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
-+	0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106,
-+	0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x40e6, 0xa386, 0x200c,
-+	0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110,
-+	0x080c, 0x254c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
-+	0x0118, 0x080c, 0x40e6, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
-+	0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff,
-+	0x1904, 0x4034, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
-+	0x0118, 0x080c, 0x40e6, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
-+	0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184,
-+	0x01e0, 0x0118, 0x080c, 0x40e6, 0x0028, 0x7007, 0x0012, 0x7108,
-+	0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0,
-+	0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
-+	0x40c2, 0x40d0, 0x40c0, 0x40d0, 0x40c0, 0x4120, 0x40c0, 0x411e,
-+	0x080c, 0x254c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
-+	0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x426b, 0x1de8, 0x0005,
-+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
-+	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
-+	0x8aff, 0x0118, 0x080c, 0x426b, 0x1de8, 0x0005, 0x7007, 0x0012,
-+	0x7108, 0x1d04, 0x40e9, 0x2091, 0x6000, 0x1d04, 0x40ed, 0x2091,
-+	0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
-+	0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
-+	0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
-+	0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
-+	0x0010, 0x2001, 0x0001, 0x080c, 0x3b81, 0x681b, 0x0002, 0x2051,
-+	0x0000, 0x0005, 0x080c, 0x254c, 0x080c, 0x254c, 0x080c, 0x415f,
-+	0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
-+	0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
-+	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
-+	0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
-+	0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x3fef, 0x0010,
-+	0xa7ba, 0x3fe7, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
-+	0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
-+	0x080c, 0x40e6, 0x7007, 0x0012, 0x080c, 0x4034, 0x0005, 0x8a50,
-+	0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60,
-+	0x6004, 0xa084, 0x000f, 0xa080, 0x4005, 0x203c, 0x87fb, 0x090c,
-+	0x254c, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
-+	0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
-+	0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008,
-+	0x000e, 0x0118, 0xa0b8, 0x3fef, 0x0010, 0xa0b8, 0x3fe7, 0xb284,
-+	0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-+	0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0518, 0x2c58, 0x2704,
-+	0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e,
-+	0xd19c, 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081,
-+	0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300,
-+	0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4292,
-+	0x0010, 0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126,
-+	0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007,
-+	0x0004, 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000,
-+	0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
-+	0x00de, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c,
-+	0x681c, 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050,
-+	0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c, 0x87fb,
-+	0x1138, 0x0210, 0x080c, 0x254c, 0x689c, 0xa065, 0x0120, 0x0c88,
-+	0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006,
-+	0x0016, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20,
-+	0xb284, 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5,
-+	0x000c, 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007,
-+	0x0004, 0x2049, 0x4206, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4267,
-+	0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c,
-+	0x87fb, 0x1140, 0x0210, 0x080c, 0x254c, 0x709c, 0xa075, 0x2060,
-+	0x0570, 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b,
-+	0x0268, 0x8a51, 0x1110, 0x080c, 0x254c, 0x8738, 0x2704, 0xa005,
-+	0x1d90, 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420,
-+	0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
-+	0xa11b, 0x1210, 0x080c, 0x254c, 0xb284, 0x0200, 0x0118, 0x2071,
-+	0x0050, 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x419b, 0x00de,
-+	0x012e, 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e,
-+	0x0110, 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108,
-+	0x0005, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808,
-+	0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0120, 0x7810, 0x7022,
-+	0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006,
-+	0x2079, 0x4600, 0x8a51, 0x01e8, 0x8738, 0x2704, 0xa005, 0x1168,
-+	0x609c, 0xa005, 0x01b8, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
-+	0x3ff5, 0x203c, 0x87fb, 0x090c, 0x254c, 0x7008, 0x0006, 0xa084,
-+	0x01e0, 0x000e, 0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086,
-+	0x0003, 0x0005, 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6,
-+	0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108,
-+	0xa184, 0x0003, 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3f45,
-+	0x7108, 0xd1fc, 0x0118, 0x080c, 0x40ae, 0x0c88, 0x7007, 0x0010,
-+	0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40ae, 0x7008, 0xa086, 0x0008,
-+	0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000,
-+	0x0006, 0x2001, 0x4601, 0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328,
-+	0x000e, 0x012e, 0x2000, 0x0005, 0x0126, 0x0146, 0x0136, 0x0156,
-+	0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
-+	0x2049, 0x42ec, 0xad80, 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118,
-+	0x2099, 0x0032, 0x0010, 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff,
-+	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118,
-+	0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007,
-+	0x0004, 0x7004, 0xa084, 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000,
-+	0x7003, 0x0000, 0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005,
-+	0x6814, 0xd0fc, 0x0904, 0x436b, 0x7000, 0xd084, 0x05e0, 0x7e24,
-+	0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
-+	0x7118, 0x0016, 0x711c, 0x0016, 0x7120, 0x0016, 0x7124, 0x0016,
-+	0x701b, 0x0000, 0x701f, 0x3fff, 0x7023, 0x0000, 0x7027, 0x0000,
-+	0x7013, 0x0004, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x2001,
-+	0xffff, 0x2009, 0x0031, 0x200a, 0x200a, 0x7108, 0x7008, 0xa106,
-+	0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226, 0x002e, 0x7222, 0x002e,
-+	0x721e, 0x002e, 0x721a, 0x7007, 0x0002, 0x7008, 0xa086, 0x0008,
-+	0x0110, 0x0804, 0x40e6, 0x7007, 0x0004, 0x7003, 0x0000, 0x0005,
-+	0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974,
-+	0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f, 0x0000,
-+	0x0e04, 0x4384, 0x2091, 0x4080, 0x2069, 0x4680, 0xd7fc, 0x1110,
-+	0x2069, 0x4640, 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4,
-+	0x0180, 0xd0bc, 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110,
-+	0x2079, 0x0200, 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22ae,
-+	0x00fe, 0x7830, 0x8001, 0x7832, 0x1904, 0x440b, 0x7834, 0x7832,
-+	0x2061, 0x6bc0, 0x2069, 0x4680, 0xc7fd, 0x68cc, 0xa005, 0x0128,
-+	0x8001, 0x68ce, 0x1110, 0x080c, 0x4577, 0x6800, 0xa084, 0x000f,
-+	0x0168, 0xa086, 0x0001, 0x0150, 0x6840, 0xa00d, 0x0138, 0x2104,
-+	0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x4514, 0x6814, 0xa005,
-+	0x01a8, 0x8001, 0x6816, 0x1190, 0x68a3, 0x0001, 0x00f6, 0xd7fc,
-+	0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3c46,
-+	0x00fe, 0x6860, 0xa005, 0x0110, 0x080c, 0x22ae, 0x687c, 0xa005,
-+	0x0140, 0x8001, 0x687e, 0x1128, 0x6863, 0x0000, 0x68d0, 0xc0c5,
-+	0x68d2, 0x68d0, 0xd0fc, 0x01b0, 0xc0fc, 0x68d2, 0x20a9, 0x0200,
-+	0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d0, 0xc0fd, 0x68d2,
-+	0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x22ae, 0xace0, 0x0010,
-+	0x1f04, 0x43f0, 0xd7fc, 0x0138, 0x2061, 0x4bc0, 0x2069, 0x4640,
-+	0xc7fc, 0x0804, 0x43ad, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0,
-+	0x783c, 0x783a, 0x2061, 0x4bc0, 0x2069, 0x4640, 0xc7fc, 0x680c,
-+	0xa005, 0x0110, 0x080c, 0x4487, 0xd7fc, 0x1130, 0x2061, 0x6bc0,
-+	0x2069, 0x4680, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac,
-+	0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0e04,
-+	0x4433, 0x080c, 0x207a, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840,
-+	0x8001, 0x7842, 0x1904, 0x4486, 0x7844, 0x7842, 0x2069, 0x4640,
-+	0xc7fc, 0x2079, 0x0200, 0x68d4, 0xa005, 0x0138, 0x7de0, 0xa504,
-+	0x1120, 0x68d6, 0x68d0, 0xc0bc, 0x68d2, 0x2079, 0x4600, 0x6810,
-+	0xa005, 0x1110, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118,
-+	0xa080, 0x8cd0, 0x0010, 0xa080, 0x8bc0, 0x2040, 0x2004, 0xa065,
-+	0x01e0, 0x6024, 0xa005, 0x01b0, 0x8001, 0x6026, 0x1198, 0x6800,
-+	0xa005, 0x0130, 0x6848, 0xac06, 0x1118, 0x080c, 0x4514, 0x0068,
-+	0x6860, 0xa005, 0x0118, 0x6027, 0x0001, 0x0020, 0x080c, 0x44c8,
-+	0x2804, 0x0c28, 0x6000, 0x2c40, 0x0c10, 0xd7fc, 0x1138, 0x2069,
-+	0x4680, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x4443, 0x0005, 0x2009,
-+	0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, 0x6024, 0xa005,
-+	0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, 0xd084, 0x1110,
-+	0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, 0x00d6, 0x00c6,
-+	0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, 0x37a4, 0x2d00,
-+	0x2c68, 0x2060, 0x080c, 0x1be3, 0x080c, 0x1d95, 0x001e, 0x00ce,
-+	0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d,
-+	0x0100, 0xace0, 0x0010, 0x1f04, 0x448b, 0xa184, 0x0001, 0x0130,
-+	0xa18c, 0xfffe, 0x690e, 0x080c, 0x22ae, 0x0008, 0x690e, 0x0005,
-+	0x2c00, 0x687a, 0x6714, 0x6f72, 0x6017, 0x0000, 0x602b, 0x0000,
-+	0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
-+	0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6858, 0xac06,
-+	0x1110, 0x2800, 0x685a, 0x080c, 0x1b7b, 0x6818, 0xa005, 0x0110,
-+	0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109,
-+	0x790a, 0x8001, 0x1310, 0x080c, 0x254c, 0x6812, 0x1118, 0x7910,
-+	0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c,
-+	0x1da2, 0xd7fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680,
-+	0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x6976, 0x2001,
-+	0x0004, 0x080c, 0x22a4, 0x0005, 0x00d6, 0x6948, 0x2160, 0xd7fc,
-+	0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x080c, 0x2467,
-+	0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
-+	0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000,
-+	0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b,
-+	0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x453b,
-+	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04,
-+	0x4544, 0x20a9, 0x00fa, 0x1f04, 0x454b, 0x681b, 0x0054, 0x00de,
-+	0x6863, 0x0007, 0x0005, 0x2079, 0x4600, 0x00e1, 0x0089, 0x00a9,
-+	0x2009, 0x0002, 0x2069, 0x4680, 0x680f, 0x0000, 0x6813, 0x0000,
-+	0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4640, 0x0ca8, 0x0005,
-+	0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42,
-+	0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6a4c,
-+	0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300, 0x00c6, 0x2164,
-+	0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108, 0xa11a, 0x0eb8,
-+	0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005, 0x694c, 0x6abc,
-+	0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1dc8, 0x694e,
-+	0x00ce, 0x0005, 0x1d04, 0x459a, 0x2091, 0x6000, 0x1d04, 0x459e,
-+	0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0190, 0x0098,
-+	0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4,
-+	0x1578, 0x0458, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x1540,
-+	0x0420, 0xd0e4, 0x0538, 0x1d04, 0x45bb, 0x2091, 0x6000, 0x2009,
-+	0x000c, 0x1d04, 0x45c1, 0x2091, 0x6000, 0x8109, 0x1dd0, 0x70e4,
-+	0xa084, 0x01ff, 0xa086, 0x01ff, 0x1110, 0x70ec, 0x08c8, 0xae8e,
-+	0x0100, 0x0128, 0x7814, 0xc0f4, 0xd0fc, 0x1130, 0x0020, 0x7814,
-+	0xc0fc, 0xd0f4, 0x1108, 0xc0c4, 0x7816, 0x7804, 0xd08c, 0x0110,
-+	0x681f, 0x000c, 0x70a0, 0x70a2, 0x0005, 0x7c12
-+};
-+#else
-+/*
-+ *	Firmware Version 11.12.01 (12:37 May 24, 2000)
-+ */
-+static const u_int16_t isp_12160_risc_code[] = {
-+	0x0804, 0x103a, 0x0000, 0x4bd8, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
-+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
-+	0x3132, 0x3430, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
-+	0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2031, 0x312e, 0x3132,
-+	0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
-+	0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
-+	0x3031, 0x2024, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1,
-+	0x0020, 0x2089, 0x128f, 0x0030, 0x2001, 0x04fc, 0x2004, 0xa086,
-+	0x1216, 0x0d40, 0x2071, 0x0010, 0x70c3, 0x0004, 0x70c7, 0x4953,
-+	0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000b, 0x2001, 0x04fd,
-+	0x70d6, 0x20c1, 0x0022, 0x20c9, 0x10ff, 0x2009, 0xfeff, 0x200b,
-+	0xa5a5, 0xe000, 0xe000, 0x2114, 0xa286, 0xa5a5, 0x0120, 0x20c1,
-+	0x0020, 0x20c9, 0x5cff, 0x2009, 0x0200, 0xa18e, 0x0400, 0x1168,
-+	0x3808, 0xa18e, 0x0020, 0x1148, 0x70c3, 0x8010, 0x2061, 0x0000,
-+	0x601b, 0x0001, 0x2091, 0x4080, 0x0cf8, 0x2009, 0xfeff, 0x2130,
-+	0x2128, 0x3800, 0xa084, 0x0003, 0x0006, 0x0118, 0xa1a2, 0x1100,
-+	0x0010, 0xa1a2, 0x5cff, 0x000e, 0x8424, 0x8424, 0x8424, 0x8424,
-+	0x8424, 0x8424, 0x2009, 0xb33f, 0xa005, 0x0128, 0x2079, 0x1100,
-+	0xa192, 0x1100, 0x0020, 0x2079, 0x5d00, 0xa192, 0x5d00, 0x2009,
-+	0x0000, 0x2001, 0x0037, 0x080c, 0x20ea, 0x2218, 0x2fa0, 0x2408,
-+	0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2079,
-+	0xb340, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, 0x11e8, 0x780c,
-+	0xc0ed, 0xc0d5, 0x780e, 0x7813, 0x0064, 0x2071, 0x0200, 0x00d6,
-+	0x2069, 0xb380, 0x080c, 0x59b8, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x1130, 0x2069, 0xb3c0, 0x2071, 0x0100, 0x080c, 0x59b8, 0x780c,
-+	0xc0d4, 0x780e, 0x00de, 0x0090, 0x2001, 0x04fc, 0x2004, 0xa086,
-+	0x1216, 0x1128, 0x7813, 0x0064, 0x780c, 0xc0cd, 0x08c8, 0x780c,
-+	0xc0e5, 0x780e, 0x7813, 0x003c, 0x2011, 0x000c, 0x2009, 0xb38c,
-+	0x220a, 0x2009, 0xb3cc, 0x220a, 0x7eca, 0x7cc2, 0x7bc6, 0x785b,
-+	0x0000, 0x7800, 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101,
-+	0x781b, 0x0002, 0x781f, 0x0002, 0x2009, 0x0002, 0x2069, 0xb380,
-+	0x6817, 0x0003, 0x681f, 0x0007, 0x6823, 0x00fa, 0x6827, 0x0008,
-+	0x682b, 0x0028, 0x6837, 0x0006, 0x682f, 0x0008, 0x683b, 0x0000,
-+	0x8109, 0x0508, 0x68ef, 0x000a, 0x68df, 0xb400, 0x2079, 0xb340,
-+	0x780c, 0xd0e4, 0x1118, 0x68f3, 0x7629, 0x0010, 0x68f3, 0x760d,
-+	0x68e3, 0xba00, 0x68e7, 0xb800, 0x68eb, 0xfa00, 0x68c7, 0xfece,
-+	0x68cb, 0xfed3, 0x68cf, 0xfece, 0x68d3, 0xfece, 0x68c3, 0x0001,
-+	0x2069, 0xb3c0, 0x0868, 0x68ef, 0x000a, 0x68df, 0xb600, 0x68f3,
-+	0x7819, 0x68e3, 0xda00, 0x68e7, 0xb900, 0x68eb, 0xfb10, 0x68c7,
-+	0xfed3, 0x68cb, 0xfed8, 0x68cf, 0xfed3, 0x68d3, 0xfed3, 0x68c3,
-+	0x0001, 0x00e6, 0x2069, 0xb800, 0x2071, 0x0200, 0x70ec, 0xd0e4,
-+	0x2019, 0x1c09, 0x2021, 0x0009, 0x1120, 0x2019, 0x1c0c, 0x2021,
-+	0x000c, 0x080c, 0x200a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1188,
-+	0x2069, 0xb900, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x2019, 0x1c09,
-+	0x2021, 0x0009, 0x1120, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c,
-+	0x200a, 0x00ee, 0x2011, 0x0002, 0x2069, 0xba00, 0x2009, 0x0002,
-+	0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386,
-+	0xfeff, 0x1128, 0x6817, 0x0100, 0x681f, 0x0064, 0x0020, 0x6817,
-+	0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x1f04, 0x1182, 0x8109,
-+	0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8211, 0x0118,
-+	0x2069, 0xda00, 0x08d8, 0x080c, 0x2680, 0x080c, 0x53c4, 0x080c,
-+	0x1caf, 0x080c, 0x595f, 0x2091, 0x2200, 0x2079, 0xb340, 0x7808,
-+	0xd0ec, 0x0118, 0x2071, 0x0020, 0x0010, 0x2071, 0x0050, 0x2091,
-+	0x2400, 0x2079, 0xb340, 0x2071, 0x0020, 0x2091, 0x2600, 0x2079,
-+	0xb340, 0x7808, 0xd0ec, 0x0118, 0x2079, 0x0100, 0x0010, 0x2079,
-+	0x0200, 0x2071, 0xb380, 0x2091, 0x2800, 0x2079, 0x0100, 0x2071,
-+	0xb3c0, 0x2091, 0x2000, 0x2079, 0xb340, 0x2071, 0x0010, 0x3200,
-+	0xa085, 0x303d, 0x2090, 0x70c3, 0x0000, 0x1004, 0x11e5, 0x70c0,
-+	0xa086, 0x0002, 0x1110, 0x080c, 0x142c, 0x2039, 0x0000, 0x080c,
-+	0x130a, 0x78ac, 0xa005, 0x11a0, 0x0e04, 0x11f5, 0x7864, 0xa065,
-+	0x0120, 0x2029, 0x0000, 0x080c, 0x252c, 0x080c, 0x210b, 0x0e04,
-+	0x120c, 0x7864, 0xa065, 0x0120, 0x2029, 0x0000, 0x080c, 0x252c,
-+	0x0e04, 0x120c, 0x2009, 0xb386, 0x2011, 0xb3c6, 0x2104, 0x220c,
-+	0xa105, 0x0110, 0x080c, 0x1dd0, 0x00e6, 0x00f6, 0x2071, 0xb380,
-+	0x70c0, 0xa005, 0x01f8, 0x7454, 0xa485, 0x0000, 0x01d8, 0x2079,
-+	0x0200, 0x2091, 0x8000, 0x72f0, 0xa28c, 0x303d, 0x2190, 0x080c,
-+	0x2b7f, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x1232, 0x00fe,
-+	0x7864, 0xa065, 0x0130, 0x00ee, 0x2029, 0x0000, 0x080c, 0x252c,
-+	0x00e6, 0x00f6, 0x1d04, 0x123a, 0x00fe, 0x00ee, 0x080c, 0x577e,
-+	0x00e6, 0x00f6, 0x2071, 0xb3c0, 0x70c0, 0xa005, 0x0190, 0x7454,
-+	0xa485, 0x0000, 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72f0,
-+	0xa28c, 0x303d, 0x2190, 0x080c, 0x2b7f, 0x2091, 0x8000, 0x2091,
-+	0x303d, 0x00fe, 0x00ee, 0x0e04, 0x125b, 0x7864, 0xa065, 0x0118,
-+	0xa02e, 0x080c, 0x252c, 0x1d04, 0x11e7, 0x080c, 0x577e, 0x0804,
-+	0x11e7, 0x3c00, 0xa084, 0x0007, 0x0002, 0x1275, 0x1275, 0x1277,
-+	0x1277, 0x127c, 0x127c, 0x1281, 0x1281, 0x3c00, 0xa084, 0x0003,
-+	0x0002, 0x1275, 0x1275, 0x128a, 0x128a, 0x080c, 0x297f, 0x2091,
-+	0x2400, 0x080c, 0x547f, 0x0005, 0x2091, 0x2200, 0x080c, 0x547f,
-+	0x0005, 0x2091, 0x2200, 0x080c, 0x547f, 0x2091, 0x2400, 0x080c,
-+	0x547f, 0x0005, 0x2091, 0x2200, 0x080c, 0x547f, 0x0005, 0x12af,
-+	0x12af, 0x12b0, 0x12b0, 0x12bb, 0x12bb, 0x12bb, 0x12bb, 0x12c4,
-+	0x12c4, 0x12cf, 0x12cf, 0x12bb, 0x12bb, 0x12bb, 0x12bb, 0x12de,
-+	0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x12de,
-+	0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x12de, 0x0cf8,
-+	0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c, 0x299c, 0x012e,
-+	0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x080c, 0x1261,
-+	0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x2091,
-+	0x2600, 0x080c, 0x299c, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006,
-+	0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x299c, 0x2091, 0x2800,
-+	0x080c, 0x299c, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
-+	0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0xb340, 0x2071, 0x0200,
-+	0x2069, 0xb380, 0x3d00, 0xd08c, 0x0130, 0x70ec, 0xa084, 0x1c00,
-+	0x78e2, 0x080c, 0x59b8, 0x3d00, 0xd084, 0x0150, 0x2069, 0xb3c0,
-+	0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6, 0x080c, 0x59b8,
-+	0x080c, 0x2930, 0x00fe, 0x00ee, 0x00de, 0x012e, 0x010e, 0x000e,
-+	0x000d, 0x0005, 0x0e04, 0x1381, 0x2061, 0x0000, 0x6018, 0xa084,
-+	0x0001, 0x1904, 0x1381, 0x7820, 0xa005, 0x1120, 0x0004, 0x1382,
-+	0x0804, 0x1381, 0x7908, 0xd1f4, 0x0120, 0x2001, 0x4007, 0x0804,
-+	0x142e, 0x790c, 0xd1ec, 0x01a0, 0xd0fc, 0x0148, 0x0006, 0x080c,
-+	0x1c2f, 0x000e, 0x0168, 0x2001, 0x4007, 0x0804, 0x142e, 0x0006,
-+	0x080c, 0x1c25, 0x000e, 0x0120, 0x2001, 0x4007, 0x0804, 0x142e,
-+	0x7908, 0xd0fc, 0x1128, 0x2061, 0xb380, 0xc19c, 0xc7fc, 0x0020,
-+	0x2061, 0xb3c0, 0xc19d, 0xc7fd, 0x6068, 0xa005, 0x15d0, 0x790a,
-+	0x6087, 0x0000, 0x7820, 0xc0fc, 0xa086, 0x0018, 0x1120, 0x00c6,
-+	0x080c, 0x196b, 0x00ce, 0x7823, 0x0000, 0x6080, 0xa065, 0x0190,
-+	0x00c6, 0x609c, 0x080c, 0x1d24, 0x00ce, 0x609f, 0x0000, 0x080c,
-+	0x1a81, 0x2009, 0x000c, 0x6007, 0x0103, 0x080c, 0x1c39, 0x1198,
-+	0x080c, 0x1c95, 0x7808, 0xd09c, 0x1118, 0x2061, 0xb380, 0x0018,
-+	0x2061, 0xb3c0, 0xc09c, 0x6083, 0x0000, 0x780a, 0x60f0, 0xd0c4,
-+	0x0130, 0xc0c4, 0x60f2, 0x2001, 0x4005, 0x0804, 0x142e, 0x0804,
-+	0x142c, 0x0005, 0x7808, 0xd0f4, 0x0120, 0x2001, 0x4007, 0x0804,
-+	0x142e, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000, 0x70cf,
-+	0x0000, 0x70db, 0x0000, 0x71c4, 0x7a08, 0xd2ec, 0x0108, 0xc1fc,
-+	0x70c0, 0xa03d, 0xa092, 0x0030, 0x1208, 0x0032, 0x2200, 0xa092,
-+	0x0050, 0x1a04, 0x143a, 0x0482, 0x142c, 0x14a7, 0x1448, 0x14bb,
-+	0x14ca, 0x14d0, 0x1440, 0x1a99, 0x14d4, 0x143a, 0x144c, 0x144d,
-+	0x144e, 0x144f, 0x1a9d, 0x143a, 0x14e1, 0x1532, 0x1988, 0x1a93,
-+	0x1450, 0x17f5, 0x182e, 0x1863, 0x18a8, 0x17b0, 0x17be, 0x17d1,
-+	0x17e4, 0x1600, 0x143a, 0x155f, 0x1563, 0x1571, 0x157f, 0x1596,
-+	0x15a4, 0x15a7, 0x15b5, 0x15c3, 0x15cd, 0x15e6, 0x15f2, 0x143a,
-+	0x143a, 0x143a, 0x143a, 0x160d, 0x1618, 0x1631, 0x1665, 0x168e,
-+	0x16a0, 0x16a3, 0x16cd, 0x1705, 0x1717, 0x1784, 0x1794, 0x143a,
-+	0x1475, 0x143a, 0x143a, 0x17a6, 0x143a, 0x143a, 0x143a, 0x143a,
-+	0x143a, 0x1bc9, 0x1bcf, 0x143a, 0x143a, 0x143a, 0x1bd3, 0x1be2,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x14a2, 0x14b6, 0x14dc, 0x152d,
-+	0x1983, 0x1ab1, 0x1ad3, 0x1950, 0x1ae9, 0x1bf0, 0x1bbb, 0x1bc5,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a, 0x143a,
-+	0x143a, 0x143a, 0x143a, 0x143a, 0x72ca, 0x71c6, 0x2001, 0x4006,
-+	0x0028, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04,
-+	0x142f, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091,
-+	0x4080, 0x0005, 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78,
-+	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20,
-+	0x70c4, 0x70c3, 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0,
-+	0x2091, 0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020,
-+	0x70cf, 0x2020, 0x70d3, 0x000b, 0x2001, 0x000c, 0x70d6, 0x2079,
-+	0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029,
-+	0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091,
-+	0x5000, 0x2091, 0x4080, 0x0804, 0x0418, 0x00d6, 0x70c4, 0x7904,
-+	0xd19c, 0x0180, 0x70c7, 0x0001, 0x2069, 0xfed8, 0x2d14, 0x72ca,
-+	0x8d68, 0x2d14, 0x72ce, 0x8d68, 0x2d14, 0x72da, 0x8d68, 0x2d14,
-+	0x72de, 0x0010, 0x70c7, 0x0000, 0xa005, 0x0178, 0xc19d, 0x72c8,
-+	0x2069, 0xfed8, 0x226a, 0x72cc, 0x8d68, 0x226a, 0x72d8, 0x8d68,
-+	0x226a, 0x72dc, 0x8d68, 0x226a, 0x0008, 0xc19c, 0x7906, 0x00de,
-+	0x0804, 0x142c, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018, 0x2029,
-+	0x0000, 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x080c, 0x1e1f,
-+	0x0904, 0x142c, 0x70c3, 0x4002, 0x0804, 0x142c, 0x75d8, 0x74dc,
-+	0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, 0x71d0, 0x73c8,
-+	0x72cc, 0x70c4, 0x080c, 0x1e5e, 0x0904, 0x142c, 0x70c3, 0x4002,
-+	0x0804, 0x142c, 0x71c4, 0x70c8, 0x2114, 0x200a, 0x0804, 0x142a,
-+	0x71c4, 0x2114, 0x0804, 0x142a, 0x70c7, 0x000b, 0x70cb, 0x000c,
-+	0x70cf, 0x0001, 0x0804, 0x142c, 0x75d8, 0x76dc, 0x75da, 0x76de,
-+	0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
-+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x05c8, 0xa40a, 0x0110,
-+	0x1a04, 0x142e, 0x8001, 0x786a, 0xa084, 0xfc00, 0x0138, 0x78ac,
-+	0xc085, 0x78ae, 0x2001, 0x4005, 0x0804, 0x142e, 0x7a72, 0x7b76,
-+	0x7d7a, 0x7e7e, 0x7c6e, 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004,
-+	0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1,
-+	0x0000, 0xa5a9, 0x0000, 0x0050, 0x8407, 0x8004, 0x8004, 0xa318,
-+	0xa291, 0x0000, 0xa6b1, 0x0000, 0xa5a9, 0x0000, 0x731a, 0x721e,
-+	0x7622, 0x7526, 0x78ac, 0xa084, 0xfffc, 0x78ae, 0x0020, 0x78ac,
-+	0xa085, 0x0001, 0x78ae, 0x0804, 0x142c, 0x75d8, 0x76dc, 0x75da,
-+	0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc,
-+	0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x01d0, 0xa40a,
-+	0x0110, 0x1a04, 0x142e, 0x8001, 0x788e, 0xa084, 0xfc00, 0x0138,
-+	0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x142e, 0x7a96,
-+	0x7b9a, 0x7d9e, 0x7ea2, 0x7c92, 0x78ac, 0xa084, 0xfcff, 0x78ae,
-+	0x0020, 0x78ac, 0xa085, 0x0100, 0x78ae, 0x0804, 0x142c, 0x795c,
-+	0x7ac4, 0x0804, 0x142a, 0x2009, 0xb387, 0x210c, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1904, 0x142b, 0x2011, 0xb3c7, 0x2214, 0x0804,
-+	0x142a, 0x2009, 0xb388, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x1904, 0x142b, 0x2011, 0xb3c8, 0x2214, 0x0804, 0x142a, 0x2061,
-+	0xb380, 0x6124, 0x6228, 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x1148, 0x2061, 0xb3c0, 0x6324, 0x73da, 0x6328,
-+	0x831c, 0x831c, 0x831c, 0x73de, 0x0804, 0x142a, 0x2009, 0xb38b,
-+	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x142b, 0x2011,
-+	0xb3cb, 0x2214, 0x0804, 0x142a, 0x7910, 0x0804, 0x142b, 0x2009,
-+	0x0202, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x142b,
-+	0x2011, 0x0102, 0x2214, 0x0804, 0x142a, 0x2009, 0xb38d, 0x210c,
-+	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x142b, 0x2011, 0xb3cd,
-+	0x2214, 0x0804, 0x142a, 0x7918, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x1904, 0x142b, 0x7a1c, 0x0804, 0x142a, 0x2011, 0xb900, 0x71c4,
-+	0xd1fc, 0x1110, 0x2011, 0xb800, 0x8107, 0xa084, 0x000f, 0x8003,
-+	0x8003, 0x8003, 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da,
-+	0xd29c, 0x0110, 0x6820, 0x70de, 0x0804, 0x1429, 0x2138, 0x080c,
-+	0x1cc4, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-+	0x0804, 0x1429, 0x2061, 0xb380, 0x6114, 0x2001, 0x01ff, 0x2004,
-+	0xd0fc, 0x1904, 0x142b, 0x2061, 0xb3c0, 0x6214, 0x0804, 0x142a,
-+	0x2138, 0x080c, 0x1cc4, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10,
-+	0x77da, 0x2091, 0x8001, 0x0804, 0x1429, 0x2110, 0xa294, 0x000f,
-+	0xa282, 0x0010, 0x1a04, 0x1425, 0x080c, 0x27a4, 0x0804, 0x1429,
-+	0x2100, 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x1425, 0xd1bc, 0x1120,
-+	0x2011, 0xb387, 0x2204, 0x0020, 0x2011, 0xb3c7, 0x2204, 0xc0bd,
-+	0x0006, 0x2100, 0xc0bc, 0x2012, 0x080c, 0x2713, 0x001e, 0x0804,
-+	0x142b, 0x71c4, 0x2021, 0xb388, 0x2404, 0x70c6, 0x2019, 0x0000,
-+	0x0030, 0x71c8, 0x2021, 0xb3c8, 0x2404, 0x70ca, 0xc3fd, 0x2011,
-+	0x165d, 0x20a9, 0x0008, 0x2205, 0xa106, 0x0138, 0x8210, 0x1f04,
-+	0x1643, 0x71c4, 0x72c8, 0x0804, 0x1424, 0xa292, 0x165d, 0x0026,
-+	0x2122, 0x001e, 0x080c, 0x2732, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-+	0x1110, 0xd3fc, 0x09f0, 0x0804, 0x142c, 0x03e8, 0x00fa, 0x01f4,
-+	0x02ee, 0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0xb380, 0x6124,
-+	0x6228, 0x8214, 0x8214, 0x8214, 0x70c4, 0x6026, 0x70c8, 0x8003,
-+	0x8003, 0x8003, 0x602a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0,
-+	0x0026, 0x0016, 0x2061, 0xb3c0, 0x6124, 0x6228, 0x8214, 0x8214,
-+	0x8214, 0x70d8, 0x6026, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602a,
-+	0x71da, 0x72de, 0x001e, 0x002e, 0x0804, 0x142a, 0x2061, 0xb380,
-+	0x612c, 0x70c4, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-+	0x142b, 0x2061, 0xb3c0, 0x622c, 0x70c8, 0x602e, 0x0804, 0x142a,
-+	0x7910, 0x0804, 0x142b, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001,
-+	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x1425, 0x72c8, 0x0804, 0x1424,
-+	0x0006, 0x2019, 0x0000, 0x080c, 0x278d, 0x2001, 0x01ff, 0x2004,
-+	0xd0fc, 0x0118, 0x001e, 0x0804, 0x142b, 0x71c8, 0xa184, 0xf0cf,
-+	0x0120, 0x2110, 0x71c4, 0x0804, 0x1424, 0x0006, 0xc3fd, 0x080c,
-+	0x278d, 0x002e, 0x001e, 0x0804, 0x142a, 0x71c4, 0xa182, 0x0010,
-+	0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x1425, 0x72c8,
-+	0x0804, 0x1424, 0x2011, 0xb38d, 0x2204, 0x0006, 0x8104, 0x1208,
-+	0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x276f, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x142b, 0x71c8, 0xa182,
-+	0x0010, 0x0220, 0x2110, 0x71c4, 0x0804, 0x1424, 0x2011, 0xb3cd,
-+	0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd, 0x080c,
-+	0x276f, 0x002e, 0x001e, 0x0804, 0x142a, 0x71c4, 0x72c8, 0xa184,
-+	0xfffd, 0x1904, 0x1424, 0xa284, 0xfffd, 0x1904, 0x1424, 0x2100,
-+	0x7918, 0x781a, 0x2200, 0x7a1c, 0x781e, 0x0804, 0x142a, 0x2011,
-+	0xb900, 0x71c4, 0xd1fc, 0x1110, 0x2011, 0xb800, 0x8107, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc,
-+	0x74d8, 0xd29c, 0x0130, 0x75dc, 0x75de, 0x6d22, 0x2001, 0x0002,
-+	0x682a, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000,
-+	0x6a02, 0xd2ac, 0x1110, 0xa026, 0x0078, 0xa484, 0x00ff, 0xa082,
-+	0x0002, 0x16f0, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0xa786, 0x0002,
-+	0x15b8, 0xa484, 0x00ff, 0x05a0, 0x2029, 0x0009, 0x2031, 0x0062,
-+	0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084, 0x00ff, 0x1110,
-+	0xa73d, 0x1530, 0x2041, 0x001d, 0x8307, 0xa084, 0x00ff, 0x0188,
-+	0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff, 0xa39d,
-+	0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600, 0xa702,
-+	0x1278, 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a, 0x6b0c,
-+	0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804, 0x142c,
-+	0x2091, 0x8001, 0x0804, 0x1426, 0x2138, 0x080c, 0x1cc4, 0x2091,
-+	0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc,
-+	0x681e, 0x2708, 0x0804, 0x1429, 0x70c4, 0x2061, 0xb380, 0x6114,
-+	0x6016, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x142b, 0x70c8,
-+	0x2061, 0xb3c0, 0x6214, 0x6016, 0x0804, 0x142a, 0x72c8, 0x73cc,
-+	0xa182, 0x0010, 0x1a04, 0x1425, 0x080c, 0x27de, 0x0804, 0x1429,
-+	0x2138, 0x080c, 0x1cc4, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002,
-+	0x6a0a, 0x2091, 0x8001, 0x2708, 0x0804, 0x142a, 0x2138, 0x080c,
-+	0x1cc4, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804,
-+	0xa005, 0x0110, 0x080c, 0x260c, 0x2091, 0x8001, 0x2708, 0x0804,
-+	0x142a, 0x2138, 0x080c, 0x1cc4, 0x2091, 0x8000, 0x6a08, 0xa295,
-+	0x0004, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x260c, 0x2091,
-+	0x8001, 0x2708, 0x0804, 0x142a, 0x2138, 0x2041, 0x0001, 0x2049,
-+	0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1cd8, 0x2091,
-+	0x8001, 0x2708, 0x6a08, 0x0804, 0x142a, 0x2138, 0x780c, 0xd0e4,
-+	0x1160, 0xd7fc, 0x0128, 0x080c, 0x1c2f, 0x0138, 0x0804, 0x142e,
-+	0x080c, 0x1c25, 0x0110, 0x0804, 0x142e, 0x73c8, 0x72cc, 0x77c6,
-+	0x73ca, 0x72ce, 0x080c, 0x1d63, 0x11e8, 0x6818, 0xa005, 0x01a0,
-+	0x2708, 0x0076, 0x080c, 0x27fe, 0x007e, 0x1170, 0x2001, 0x0015,
-+	0xd7fc, 0x1118, 0x2061, 0xb380, 0x0018, 0xc0fd, 0x2061, 0xb3c0,
-+	0x7822, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001, 0x2001, 0x4005,
-+	0x0804, 0x142e, 0x2091, 0x8001, 0x0804, 0x142c, 0x2138, 0x780c,
-+	0xd0e4, 0x1160, 0xd7fc, 0x0128, 0x080c, 0x1c2f, 0x0138, 0x0804,
-+	0x142e, 0x080c, 0x1c25, 0x0110, 0x0804, 0x142e, 0x77c6, 0x2041,
-+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c,
-+	0x1cd8, 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0xb380, 0x0018,
-+	0x2061, 0xb3c0, 0xc1fd, 0x606b, 0x0003, 0x6083, 0x0000, 0x677a,
-+	0x6087, 0x000f, 0x7922, 0x61f0, 0xc1c4, 0x61f2, 0x080c, 0x260c,
-+	0x2091, 0x8001, 0x0005, 0x77c8, 0x77ca, 0x2138, 0x77c6, 0x780c,
-+	0xd0e4, 0x1160, 0xd7fc, 0x0128, 0x080c, 0x1c2f, 0x0138, 0x0804,
-+	0x142e, 0x080c, 0x1c25, 0x0110, 0x0804, 0x142e, 0xa7bc, 0xff00,
-+	0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x1118, 0x2061, 0xb380,
-+	0x0018, 0x2061, 0xb3c0, 0xc1fd, 0x6083, 0x0000, 0x606b, 0x0002,
-+	0x677a, 0x6087, 0x000f, 0x7922, 0x61f0, 0xc1c4, 0x61f2, 0x080c,
-+	0x260c, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x70c8,
-+	0xa005, 0x0118, 0x60f0, 0xc0fd, 0x60f2, 0x080c, 0x1cd8, 0x70c8,
-+	0x6836, 0x8738, 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005,
-+	0x2019, 0x0000, 0x2011, 0x0000, 0x7808, 0xd0ec, 0x1180, 0x72c8,
-+	0x780c, 0xd0e4, 0x1160, 0xd284, 0x0128, 0x080c, 0x1c2f, 0x0138,
-+	0x0804, 0x142e, 0x080c, 0x1c25, 0x0110, 0x0804, 0x142e, 0x72ca,
-+	0x78ac, 0xa084, 0x0003, 0x1508, 0x2039, 0x0000, 0xd284, 0x0108,
-+	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x080c,
-+	0x1cc4, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091,
-+	0x8001, 0x8738, 0xa784, 0x001f, 0x1d90, 0xa7bc, 0xff00, 0x873f,
-+	0x8738, 0x873f, 0xa784, 0x0f00, 0x1d50, 0x2091, 0x8000, 0x7808,
-+	0xd0ec, 0x0118, 0x2069, 0x0100, 0x0040, 0x72c8, 0xd284, 0x1118,
-+	0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd,
-+	0x680a, 0x6830, 0xa084, 0x0040, 0x01c0, 0x684b, 0x0004, 0x20a9,
-+	0x0014, 0x6848, 0xa084, 0x0004, 0x0110, 0x1f04, 0x1901, 0x684b,
-+	0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0110, 0x1f04,
-+	0x190b, 0x20a9, 0x00fa, 0x1f04, 0x1913, 0x2079, 0xb340, 0x2009,
-+	0x0018, 0x7808, 0xd0ec, 0x1118, 0x72c8, 0xd284, 0x1118, 0x2061,
-+	0xb380, 0x0018, 0x2061, 0xb3c0, 0xc1fd, 0x6083, 0x0000, 0x7922,
-+	0x606b, 0x0001, 0x6087, 0x000f, 0x60c3, 0x0000, 0x60c4, 0x60ce,
-+	0x60d2, 0x60f0, 0xd0b4, 0x0160, 0xc0b4, 0x60f2, 0x00c6, 0x60d4,
-+	0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce,
-+	0x60f0, 0xa084, 0x7eff, 0x60f2, 0x78ac, 0xa085, 0x0002, 0x78ae,
-+	0x83ff, 0x0108, 0x0005, 0x681b, 0x0050, 0x2091, 0x8001, 0x0005,
-+	0x73cc, 0x080c, 0x18aa, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a,
-+	0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff,
-+	0x1f04, 0x1960, 0x8421, 0x1dd0, 0x8319, 0x1db0, 0x69ee, 0x6a4a,
-+	0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2069, 0xb380, 0x0010,
-+	0x2069, 0xb3c0, 0x71c4, 0x71c6, 0x6912, 0x81ff, 0x1110, 0x68c3,
-+	0x0001, 0x78ac, 0xa084, 0xfffd, 0x78ae, 0xa084, 0x0001, 0x1110,
-+	0x080c, 0x1daf, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018,
-+	0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
-+	0x72ce, 0x2079, 0xb340, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
-+	0x1c79, 0x0904, 0x1a7d, 0x20a9, 0x0005, 0x20a1, 0xb351, 0x2091,
-+	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1fd6,
-+	0x0120, 0x080c, 0x1c95, 0x0804, 0x1a7d, 0x6004, 0xa08c, 0x00ff,
-+	0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x250a, 0x000e, 0xa084,
-+	0xff00, 0x8007, 0x8009, 0x0904, 0x1a24, 0x00c6, 0x2c68, 0x080c,
-+	0x1c79, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
-+	0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
-+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
-+	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x1a23, 0x2009,
-+	0x0040, 0x080c, 0x1fd6, 0x1548, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0002, 0x1168, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120,
-+	0x0016, 0x080c, 0x2507, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
-+	0x00c6, 0x609c, 0x080c, 0x1d24, 0x00ce, 0x609f, 0x0000, 0x080c,
-+	0x1a81, 0x2009, 0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x080c,
-+	0x1c39, 0x080c, 0x1c95, 0x0804, 0x1a7d, 0x00ce, 0x00c6, 0x609c,
-+	0x080c, 0x1d24, 0x00ce, 0x609f, 0x0000, 0x080c, 0x1a81, 0x2009,
-+	0x000c, 0x6007, 0x0103, 0x601b, 0x0003, 0x080c, 0x1c39, 0x080c,
-+	0x1c95, 0x0804, 0x1a7d, 0x00ce, 0x780c, 0xd0e4, 0x11e8, 0x6114,
-+	0xd1fc, 0x0120, 0x080c, 0x1c2f, 0x01b8, 0x0018, 0x080c, 0x1c25,
-+	0x0198, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, 0x73c8, 0x72cc,
-+	0x6087, 0x0103, 0x601b, 0x0021, 0x080c, 0x1c39, 0x080c, 0x1c95,
-+	0x2001, 0x4007, 0x0804, 0x142e, 0x74c4, 0x73c8, 0x72cc, 0x6014,
-+	0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, 0x1118, 0x2071,
-+	0xb380, 0x0018, 0x2071, 0xb3c0, 0xc1fd, 0x7922, 0x706b, 0x0005,
-+	0x71f0, 0xc1c4, 0x71f2, 0x736e, 0x7272, 0x7476, 0x707a, 0x707f,
-+	0x0000, 0x2c00, 0x7082, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184,
-+	0x0060, 0x0110, 0x080c, 0x5365, 0x00ee, 0x6596, 0x65a6, 0x669a,
-+	0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000,
-+	0x080c, 0x260c, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804,
-+	0x142f, 0x20a9, 0x0005, 0x2099, 0xb351, 0x2091, 0x8000, 0x530a,
-+	0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
-+	0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x7916, 0x0804,
-+	0x142c, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c,
-+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000,
-+	0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804,
-+	0x142f, 0x2011, 0xb3a4, 0xa03e, 0x7908, 0xd1ec, 0x11a0, 0x77c8,
-+	0xd7fc, 0x0110, 0x2011, 0xb3e4, 0x220c, 0x0006, 0x0036, 0x0046,
-+	0x080c, 0x44c8, 0x70c4, 0xd0fc, 0x004e, 0x003e, 0x000e, 0x1118,
-+	0xa184, 0x7fff, 0x0020, 0x080c, 0x44ac, 0xa185, 0x8000, 0x2012,
-+	0x2710, 0x0804, 0x142a, 0x0016, 0x2100, 0xc1fc, 0x080c, 0x449c,
-+	0x001e, 0xd1fc, 0x1118, 0x2001, 0xb3a4, 0x0010, 0x2001, 0xb3e4,
-+	0x2004, 0xa084, 0x8000, 0x6100, 0xa10d, 0x6204, 0x6308, 0x0804,
-+	0x1429, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2091, 0x8000, 0x2061,
-+	0x0010, 0x60c4, 0xd0fc, 0x1178, 0x2071, 0xb380, 0x7808, 0xd0ec,
-+	0x0128, 0x2079, 0x0100, 0x2019, 0x0020, 0x0058, 0x2079, 0x0200,
-+	0x2019, 0x0050, 0x0030, 0x2071, 0xb3c0, 0x2079, 0x0100, 0x2019,
-+	0x0020, 0x7094, 0xa06d, 0x0904, 0x1bb1, 0x6a04, 0xa294, 0x00ff,
-+	0xa286, 0x0007, 0x0120, 0xa286, 0x000f, 0x1904, 0x1bb1, 0x691c,
-+	0xa184, 0x00c0, 0x0904, 0x1bb1, 0xa186, 0x00c0, 0x0904, 0x1bb1,
-+	0x6824, 0xa084, 0xff00, 0xa085, 0x0019, 0x6826, 0x2368, 0x7830,
-+	0xa084, 0x0040, 0x1de0, 0xa184, 0x0080, 0x1904, 0x1b87, 0x78e4,
-+	0xa084, 0x0007, 0x8001, 0x1dd8, 0x71a4, 0x81ff, 0x0150, 0x6807,
-+	0x0010, 0x6908, 0x6808, 0xa106, 0x1de0, 0x6804, 0xa084, 0x0010,
-+	0x1de0, 0x78b8, 0x8007, 0xa084, 0x007f, 0x1dd8, 0x7848, 0xa085,
-+	0x000c, 0x784a, 0x71a4, 0x81ff, 0x0180, 0x70a7, 0x0000, 0x6807,
-+	0x0018, 0x6804, 0xa084, 0x0008, 0x1de0, 0x6807, 0x0008, 0x6804,
-+	0xa084, 0x0008, 0x1de0, 0x6807, 0x0002, 0x61c4, 0xa18c, 0x0003,
-+	0x0904, 0x1bad, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x7848,
-+	0xa084, 0x000c, 0x1de0, 0x00e6, 0x2071, 0xb340, 0x724a, 0x734e,
-+	0xae80, 0x0012, 0x00ee, 0x080c, 0x51f4, 0x78a3, 0x0000, 0x7858,
-+	0xa084, 0xedff, 0x785a, 0x70a8, 0xa080, 0x00f3, 0x781a, 0x00fe,
-+	0x00ee, 0x00de, 0x00ce, 0x2091, 0x8001, 0x0804, 0x142c, 0x78e4,
-+	0xa084, 0x0007, 0x1de0, 0x78b8, 0x8007, 0xa084, 0x007f, 0x1dd8,
-+	0x7848, 0xa085, 0x000c, 0x784a, 0x7848, 0xa084, 0x000c, 0x1de0,
-+	0x71a4, 0x81ff, 0x0190, 0x6807, 0x0010, 0x70a7, 0x0000, 0x6807,
-+	0x0018, 0x6804, 0xa084, 0x0008, 0x1de0, 0x6807, 0x0008, 0x6804,
-+	0xa084, 0x0008, 0x1de0, 0x6807, 0x0002, 0x70a8, 0xa080, 0x00b7,
-+	0x0868, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x2091, 0x8001, 0x2001,
-+	0x4005, 0x0804, 0x142e, 0x7958, 0x71c6, 0x71c4, 0xa182, 0x0003,
-+	0x1a04, 0x1425, 0x795a, 0x0804, 0x142c, 0x7958, 0x71c6, 0x0804,
-+	0x142c, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0804, 0x142c, 0x7900,
-+	0x71c6, 0x0804, 0x142c, 0x7904, 0x70c4, 0x7806, 0xd094, 0x0140,
-+	0x70c8, 0x78f2, 0x70cc, 0x78f6, 0x70d8, 0x78fa, 0x70dc, 0x78fe,
-+	0x0804, 0x142b, 0x7804, 0x70c6, 0xd094, 0x0140, 0x78f0, 0x70ca,
-+	0x78f4, 0x70ce, 0x78f8, 0x70da, 0x78fc, 0x70de, 0x0804, 0x142c,
-+	0x71c4, 0xd1fc, 0x1118, 0x2011, 0xb800, 0x0010, 0x2011, 0xb900,
-+	0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa268,
-+	0x2011, 0x0000, 0x6814, 0xd0fc, 0x0110, 0xa295, 0x0200, 0xd0b4,
-+	0x0110, 0xa295, 0x0001, 0x6b0c, 0x6800, 0x70da, 0x6820, 0x70de,
-+	0x0804, 0x1429, 0x780c, 0xd0f4, 0x0130, 0x2001, 0x4007, 0x70db,
-+	0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db,
-+	0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x780c, 0xd0f4, 0x0128,
-+	0x2001, 0x4007, 0x70db, 0x0000, 0x0008, 0xa006, 0x0005, 0x780c,
-+	0xd0fc, 0x0128, 0x2001, 0x4007, 0x70db, 0x0001, 0x0008, 0xa006,
-+	0x0005, 0xac80, 0x0001, 0x080c, 0x1e7a, 0x0005, 0x7112, 0x7003,
-+	0x0001, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80,
-+	0x0001, 0x20a0, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0xa08c,
-+	0x01e0, 0x1510, 0x53a5, 0x7884, 0xa005, 0x01e8, 0x0411, 0x0148,
-+	0x2c00, 0x788a, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5,
-+	0x0090, 0x7887, 0x0000, 0x7218, 0x731c, 0x7420, 0x7524, 0xa292,
-+	0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a,
-+	0x731e, 0x7422, 0x7526, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004,
-+	0x0005, 0x2091, 0x8000, 0x783c, 0xa065, 0x0120, 0x2c04, 0x783e,
-+	0x2063, 0x0000, 0x2091, 0x8001, 0x0005, 0x00f6, 0x2079, 0xb340,
-+	0x783c, 0xa06d, 0x0140, 0x2d04, 0x783e, 0x6803, 0x0000, 0x6807,
-+	0x0000, 0x680b, 0x0000, 0x00fe, 0x0005, 0x2091, 0x8000, 0x00f6,
-+	0x2079, 0xb340, 0x783c, 0x2062, 0x2c00, 0xa005, 0x1110, 0x080c,
-+	0x297f, 0x783e, 0x00fe, 0x2091, 0x8001, 0x0005, 0x00f6, 0x2079,
-+	0xb340, 0x783c, 0x206a, 0x2d00, 0x783e, 0x00fe, 0x0005, 0x3800,
-+	0xa084, 0x0003, 0x0118, 0x2011, 0x1100, 0x0010, 0x2011, 0x5d00,
-+	0x7a3e, 0x7bc4, 0x8319, 0x0128, 0xa280, 0x0037, 0x2012, 0x2010,
-+	0x0cc8, 0x2013, 0x0000, 0x0005, 0x0016, 0x2069, 0xda00, 0xd7fc,
-+	0x1110, 0x2069, 0xba00, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
-+	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xad68, 0x001e, 0x0005,
-+	0x0c59, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef,
-+	0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128, 0x2009, 0xb394, 0x2071,
-+	0xb380, 0x0020, 0x2009, 0xb3d4, 0x2071, 0xb3c0, 0x210c, 0x6804,
-+	0xa005, 0x0148, 0xa116, 0x1138, 0x2060, 0x6000, 0x6806, 0x0016,
-+	0x200b, 0x0000, 0x0018, 0x2009, 0x0000, 0x0016, 0x6804, 0xa065,
-+	0x0148, 0x6000, 0x6806, 0x04b9, 0x080c, 0x2076, 0x6810, 0x8001,
-+	0x6812, 0x1da0, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060, 0x080c,
-+	0x2af4, 0x00ee, 0x0005, 0xa065, 0x0170, 0x2008, 0x609c, 0xa005,
-+	0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x2079, 0xb340,
-+	0x783c, 0x793e, 0x2062, 0x0005, 0xa065, 0x01a0, 0x2008, 0x609c,
-+	0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x00f6,
-+	0x2079, 0xb340, 0x2091, 0x8000, 0x783c, 0x793e, 0x00fe, 0x2062,
-+	0x2091, 0x8001, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
-+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-+	0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071,
-+	0xb380, 0x2031, 0xb400, 0x0020, 0x2071, 0xb3c0, 0x2031, 0xb600,
-+	0x7054, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x7056,
-+	0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0xb380,
-+	0x0010, 0x2079, 0xb3c0, 0x080c, 0x1cc4, 0x2091, 0x8000, 0x6804,
-+	0x7806, 0xa065, 0x05d0, 0x0028, 0x2c00, 0x7806, 0x6000, 0xa065,
-+	0x05a0, 0x6010, 0xa306, 0x1dc0, 0x600c, 0xa206, 0x1da8, 0x2c28,
-+	0x7850, 0xac06, 0x1108, 0x0430, 0x6804, 0xac06, 0x1140, 0x6000,
-+	0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, 0x6400,
-+	0x7804, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, 0x6802,
-+	0x2560, 0x00fe, 0x080c, 0x1d3b, 0x00f6, 0x601b, 0x0005, 0x6023,
-+	0x0020, 0x00fe, 0x080c, 0x2076, 0x00f6, 0x6810, 0x8001, 0x0b0c,
-+	0x297f, 0x6812, 0xa085, 0xffff, 0xa005, 0x00fe, 0x0005, 0x0076,
-+	0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108, 0xc7fd, 0x2041, 0x0021,
-+	0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x080c, 0x1cd8,
-+	0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc, 0xff00, 0x873f, 0x8738,
-+	0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091, 0x8001, 0x007e, 0x0005,
-+	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x11b8, 0x7808, 0xd08c,
-+	0x0130, 0xc08c, 0x780a, 0xc7fc, 0x2069, 0xb380, 0x0028, 0xc08d,
-+	0x780a, 0x2069, 0xb3c0, 0xc7fd, 0x2091, 0x8000, 0x6818, 0x681b,
-+	0x0000, 0x2091, 0x8001, 0xa005, 0x1108, 0x0005, 0xa08c, 0xfff0,
-+	0x0110, 0x080c, 0x297f, 0x0002, 0x1e04, 0x1e07, 0x1e0d, 0x1e11,
-+	0x1e05, 0x1e15, 0x1e1b, 0x1e05, 0x1e05, 0x1f85, 0x1faf, 0x1fb2,
-+	0x1fb7, 0x1e05, 0x1e05, 0x1e05, 0x0005, 0x080c, 0x297f, 0x080c,
-+	0x1daf, 0x2001, 0x8001, 0x0804, 0x1fc7, 0x2001, 0x8003, 0x0804,
-+	0x1fc7, 0x2001, 0x8004, 0x0804, 0x1fc7, 0x080c, 0x1daf, 0x2001,
-+	0x8006, 0x0804, 0x1fc7, 0x2001, 0x8007, 0x0804, 0x1fc7, 0x2030,
-+	0x2138, 0xa782, 0x0021, 0x0210, 0x2009, 0x0020, 0x2600, 0x0099,
-+	0x1188, 0xa7ba, 0x0020, 0x0268, 0x0160, 0x2708, 0xa6b0, 0x0020,
-+	0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-+	0x0c40, 0xa006, 0x0005, 0x81ff, 0x01f0, 0x2099, 0x0030, 0x20a0,
-+	0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084,
-+	0x0004, 0x1de0, 0x21a8, 0x810b, 0x7112, 0x7003, 0x0001, 0x7007,
-+	0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0,
-+	0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x0005, 0x2030, 0x2138,
-+	0xa782, 0x0021, 0x0210, 0x2009, 0x0020, 0x2600, 0x0099, 0x1188,
-+	0xa7ba, 0x0020, 0x0268, 0x0160, 0x2708, 0xa6b0, 0x0020, 0xa290,
-+	0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0c40,
-+	0xa006, 0x0005, 0x81ff, 0x0588, 0x2098, 0x20a1, 0x0030, 0x700c,
-+	0xa084, 0x07ff, 0x0100, 0x21a8, 0x810b, 0x7112, 0x7018, 0x0006,
-+	0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x721a, 0x731e,
-+	0x7422, 0x7526, 0x7003, 0x0000, 0x53a6, 0x7007, 0x0001, 0x7010,
-+	0xa084, 0xf000, 0x0118, 0x7007, 0x0008, 0x0018, 0x7108, 0x8103,
-+	0x1eb0, 0x000e, 0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e,
-+	0x701a, 0x7007, 0x0002, 0xa184, 0x01e0, 0x7003, 0x0000, 0x7007,
-+	0x0004, 0x0005, 0x00e6, 0x6914, 0xd1fc, 0x0118, 0x2071, 0xb3c0,
-+	0x0010, 0x2071, 0xb380, 0x2d08, 0x70b4, 0x6802, 0xa005, 0x1108,
-+	0x71ba, 0x71b6, 0x00ee, 0x0005, 0x00f6, 0x6114, 0xd1fc, 0x0118,
-+	0x2079, 0xb3c0, 0x0010, 0x2079, 0xb380, 0x2c08, 0x78b4, 0x6002,
-+	0xa005, 0x1108, 0x79ba, 0x79b6, 0x00fe, 0x0005, 0x2091, 0x8000,
-+	0x00f6, 0x6114, 0xd1fc, 0x0118, 0x2079, 0xb3c0, 0x0010, 0x2079,
-+	0xb380, 0x6003, 0x0000, 0x2c08, 0x78b8, 0xa065, 0x1110, 0x79b6,
-+	0x0008, 0x6102, 0x79ba, 0x00fe, 0x2091, 0x8001, 0x080c, 0x2636,
-+	0x0005, 0x70b4, 0xa06d, 0x0130, 0x6800, 0x70b6, 0xa005, 0x1108,
-+	0x70ba, 0x8dff, 0x0005, 0x00d6, 0x00c6, 0x00f6, 0xd3fc, 0x0118,
-+	0x2079, 0xb3c0, 0x0010, 0x2079, 0xb380, 0xaf80, 0x002d, 0x2060,
-+	0x6000, 0xa005, 0x01e0, 0x2068, 0x6814, 0xa306, 0x1128, 0x6828,
-+	0xa084, 0x00ff, 0xa406, 0x0110, 0x2d60, 0x0c90, 0x6800, 0xa005,
-+	0x6002, 0x1130, 0xaf80, 0x002d, 0xac06, 0x0108, 0x2c00, 0x78ba,
-+	0x00d6, 0x689c, 0xa005, 0x0110, 0x080c, 0x1d13, 0x000e, 0x00fe,
-+	0x00ce, 0x00de, 0xa005, 0x0005, 0x00d6, 0x00c6, 0x00f6, 0xd0fc,
-+	0x0118, 0x2079, 0xb3c0, 0x0010, 0x2079, 0xb380, 0xaf80, 0x002d,
-+	0x2060, 0x6000, 0xa005, 0x01c8, 0x2068, 0x6814, 0xa084, 0x00ff,
-+	0xa306, 0x0110, 0x2d60, 0x0ca8, 0x6800, 0xa005, 0x6002, 0x1130,
-+	0xaf80, 0x002d, 0xac06, 0x0108, 0x2c00, 0x78ba, 0x00d6, 0x689c,
-+	0xa005, 0x0110, 0x080c, 0x1d13, 0x000e, 0x00fe, 0x00ce, 0x00de,
-+	0xa005, 0x0005, 0x00d6, 0x00c6, 0x00f6, 0xd3fc, 0x0118, 0x2079,
-+	0xb3c0, 0x0010, 0x2079, 0xb380, 0xaf80, 0x002d, 0x2060, 0x6000,
-+	0xa06d, 0x01b0, 0x6814, 0xa306, 0x0110, 0x2d60, 0x0cc0, 0x6800,
-+	0xa005, 0x6002, 0x1130, 0xaf80, 0x002d, 0xac06, 0x0108, 0x2c00,
-+	0x78ba, 0x00d6, 0x689c, 0xa005, 0x0110, 0x080c, 0x1d13, 0x000e,
-+	0x00fe, 0x00ce, 0x00de, 0xa005, 0x0005, 0x2091, 0x8000, 0xd7fc,
-+	0x1118, 0x2069, 0xb380, 0x0010, 0x2069, 0xb3c0, 0x6800, 0xa086,
-+	0x0000, 0x0128, 0x2091, 0x8001, 0x681b, 0x0009, 0x0005, 0x6878,
-+	0xd7fc, 0x1108, 0x0008, 0xc0fd, 0xa0bc, 0xff00, 0x2041, 0x0021,
-+	0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1cd8, 0x8738, 0xa784,
-+	0x001f, 0x1dd0, 0x2091, 0x8001, 0x2001, 0x800a, 0x00c0, 0x2001,
-+	0x800c, 0x00a8, 0x080c, 0x1daf, 0x2001, 0x800d, 0x0080, 0x780c,
-+	0xd0e4, 0x1158, 0xd0ec, 0x0120, 0xd7fc, 0x0110, 0x78e4, 0x0008,
-+	0x78e0, 0x70c6, 0x2001, 0x800e, 0x0010, 0x0804, 0x1e05, 0x70c2,
-+	0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010, 0x70db, 0x0001, 0x2061,
-+	0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x0005, 0xac80, 0x0001,
-+	0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff,
-+	0x0100, 0x7018, 0x0006, 0x701c, 0x0006, 0x7020, 0x0006, 0x7024,
-+	0x0006, 0x7112, 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003,
-+	0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002,
-+	0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007,
-+	0x0004, 0x000e, 0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e,
-+	0x701a, 0x0005, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e,
-+	0x681f, 0x0201, 0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x6823,
-+	0x0200, 0x6827, 0x0000, 0x2d00, 0xa0e8, 0x0010, 0xa290, 0x0004,
-+	0x8109, 0x1d60, 0x0005, 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001,
-+	0x780c, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021,
-+	0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec,
-+	0xd0e4, 0x1128, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x0030, 0x2019,
-+	0x1c09, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e,
-+	0x6807, 0x0038, 0x0005, 0x7018, 0x0006, 0x701c, 0x0006, 0x7020,
-+	0x0006, 0x7024, 0x0006, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003,
-+	0x0000, 0x7007, 0x0001, 0x7010, 0xa084, 0xf000, 0x0118, 0x7007,
-+	0x0008, 0x0018, 0x7108, 0x8103, 0x1eb0, 0x000e, 0x7026, 0x000e,
-+	0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x7007, 0x0002, 0xa184,
-+	0x01e0, 0x7003, 0x0000, 0x7007, 0x0004, 0x0005, 0x6004, 0x2c08,
-+	0x2063, 0x0000, 0x785c, 0x8000, 0x785e, 0x7860, 0xa005, 0x7962,
-+	0x0110, 0x2c02, 0x0008, 0x7966, 0x0005, 0x6807, 0x0103, 0x00c6,
-+	0x2061, 0xb340, 0x2d08, 0x206b, 0x0000, 0x605c, 0x8000, 0x605e,
-+	0x6060, 0xa005, 0x6162, 0x0110, 0x2d02, 0x0008, 0x6166, 0x00ce,
-+	0x0005, 0x2091, 0x8000, 0x785c, 0x8001, 0x785e, 0x2c04, 0x7866,
-+	0xa005, 0x1108, 0x7862, 0x2091, 0x8001, 0x609c, 0xa005, 0x01a8,
-+	0x00c6, 0x2060, 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f,
-+	0x0000, 0xa065, 0x609c, 0xa005, 0x1dc8, 0x2091, 0x8000, 0x783c,
-+	0x793e, 0x2062, 0x2091, 0x8001, 0x00ce, 0x2091, 0x8000, 0x783c,
-+	0x2062, 0x609f, 0x0000, 0x2c00, 0xa005, 0x1110, 0x080c, 0x297f,
-+	0x783e, 0x2091, 0x8001, 0x0005, 0x7864, 0xa065, 0x0168, 0x2091,
-+	0x8000, 0x785c, 0x8001, 0x785e, 0x2c04, 0x7866, 0xa005, 0x1110,
-+	0x7862, 0x8000, 0x2091, 0x8001, 0x0005, 0x20a9, 0x0010, 0xa006,
-+	0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x20e1, 0x8086,
-+	0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a,
-+	0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x20f1,
-+	0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x20f1, 0x0006, 0x3200,
-+	0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200,
-+	0xa085, 0x1000, 0x0cb8, 0x7d6c, 0x70d0, 0xa506, 0x0904, 0x218e,
-+	0x7808, 0xd0ec, 0x0190, 0x00e6, 0x2091, 0x8000, 0x2071, 0x0020,
-+	0x7004, 0xa005, 0x1138, 0x7008, 0x00ee, 0xa086, 0x0008, 0x0128,
-+	0x0804, 0x218e, 0x00ee, 0x0804, 0x218e, 0x080c, 0x1c79, 0x0904,
-+	0x218e, 0x7968, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x1210,
-+	0xa006, 0x0038, 0x72d0, 0xa206, 0x0120, 0x7887, 0x0001, 0x2009,
-+	0x0080, 0x00c6, 0x080c, 0x1c3e, 0x00ce, 0x05d8, 0x080c, 0x1c95,
-+	0x7887, 0x0000, 0x7880, 0x8000, 0x7882, 0xa086, 0x0002, 0x01a0,
-+	0x8507, 0x8004, 0x8004, 0x7974, 0xa108, 0x711a, 0x1260, 0x7970,
-+	0xa189, 0x0000, 0x711e, 0x797c, 0xa189, 0x0000, 0x7122, 0x7978,
-+	0xa189, 0x0000, 0x7126, 0x0490, 0x6014, 0xd0fc, 0x1118, 0x2069,
-+	0xb380, 0x0010, 0x2069, 0xb3c0, 0x2091, 0x8000, 0x681b, 0x0002,
-+	0x7884, 0xa005, 0x0128, 0x7887, 0x0000, 0x7888, 0x2060, 0x0c60,
-+	0x7883, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001,
-+	0x00a8, 0x7883, 0x0000, 0x080c, 0x24c9, 0x6004, 0xa084, 0x000f,
-+	0x0071, 0x7884, 0xa005, 0x0130, 0x7888, 0x2060, 0x6004, 0xa084,
-+	0x000f, 0x0029, 0x7887, 0x0000, 0x0804, 0x210b, 0x0005, 0x0002,
-+	0x21a0, 0x21bb, 0x21d6, 0x21a0, 0x21ef, 0x21af, 0x2341, 0x2357,
-+	0x21a0, 0x21b9, 0x21d4, 0x2232, 0x22a0, 0x22e9, 0x22fa, 0x2357,
-+	0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a,
-+	0x080c, 0x23ca, 0x609c, 0x78ba, 0x080c, 0x24b3, 0x0005, 0x78bc,
-+	0xa084, 0x0100, 0x0108, 0x0c60, 0x601c, 0xa085, 0x0080, 0x601e,
-+	0x0038, 0x080c, 0x250a, 0x78bc, 0xa084, 0x0100, 0x0108, 0x0c00,
-+	0x78bf, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001,
-+	0x0140, 0x080c, 0x23ca, 0x0128, 0x78bc, 0xa085, 0x0100, 0x78be,
-+	0x0010, 0x0804, 0x23e6, 0x0005, 0x080c, 0x2507, 0x78bc, 0xa08c,
-+	0x0e00, 0x1118, 0xa084, 0x0100, 0x1108, 0x0810, 0x080c, 0x23ca,
-+	0x1168, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0904, 0x2394,
-+	0xa186, 0x000f, 0x0904, 0x2394, 0x0804, 0x23e6, 0x0005, 0x78bc,
-+	0xa084, 0x0100, 0x0110, 0x0804, 0x21a0, 0x78bf, 0x0000, 0x6714,
-+	0x080c, 0x1cc4, 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084,
-+	0x00ff, 0xa005, 0x0198, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9,
-+	0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, 0x0002,
-+	0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c8, 0x0156, 0x080c,
-+	0x1cc4, 0x015e, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
-+	0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
-+	0x1f04, 0x221a, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c,
-+	0x1c95, 0x0005, 0x6114, 0x080c, 0x2525, 0x6900, 0xa184, 0x0001,
-+	0x0190, 0x6028, 0xa084, 0x00ff, 0x1904, 0x23ae, 0x6800, 0xa084,
-+	0x0001, 0x0904, 0x23b4, 0x6803, 0x0000, 0x680b, 0x0000, 0x6807,
-+	0x0000, 0x0804, 0x23ba, 0x2011, 0x0001, 0x6020, 0xd0f4, 0x0110,
-+	0xa295, 0x0002, 0xd0c4, 0x0110, 0xa295, 0x0008, 0xd0cc, 0x0110,
-+	0xa295, 0x0400, 0x601c, 0xa084, 0x0002, 0x0110, 0xa295, 0x0004,
-+	0x602c, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0a04, 0x23b7, 0xa182,
-+	0x001b, 0x1a04, 0x23b7, 0x0904, 0x23b7, 0x690e, 0x602c, 0x8007,
-+	0xa08c, 0x00ff, 0xa182, 0x0002, 0x0a04, 0x23b7, 0xa182, 0x001b,
-+	0x1a04, 0x23b7, 0x0904, 0x23b7, 0x6912, 0x6134, 0xa184, 0x000f,
-+	0x0138, 0x8000, 0xd0a4, 0x0108, 0x8001, 0xa18c, 0xfff0, 0xa10d,
-+	0x6922, 0x6030, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6816,
-+	0x6028, 0xa084, 0x00ff, 0x0904, 0x23b4, 0x6806, 0x6028, 0x8007,
-+	0xa084, 0x00ff, 0x0904, 0x23b4, 0x680a, 0x6a02, 0x0804, 0x23ba,
-+	0x6014, 0xd0fc, 0x1118, 0x2001, 0xb3a4, 0x0010, 0x2001, 0xb3e4,
-+	0x2004, 0xa084, 0x8000, 0x0904, 0x23b4, 0x6114, 0x080c, 0x2525,
-+	0x2091, 0x8000, 0x6a04, 0x6b08, 0x6418, 0xa484, 0x0003, 0x0170,
-+	0x6128, 0xa18c, 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0628,
-+	0x0028, 0x8001, 0x1510, 0x2100, 0xa212, 0x02f8, 0xa484, 0x000c,
-+	0x0188, 0x6128, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120,
-+	0x2100, 0xa318, 0x0290, 0x0030, 0xa082, 0x0004, 0x1170, 0x2100,
-+	0xa31a, 0x0258, 0x6030, 0xa005, 0x0110, 0x8000, 0x6816, 0x6a06,
-+	0x6b0a, 0x2091, 0x8001, 0x0804, 0x23ba, 0x2091, 0x8001, 0x0804,
-+	0x23b7, 0x6114, 0x080c, 0x2525, 0x2091, 0x8000, 0x6b08, 0x8318,
-+	0x0228, 0x6b0a, 0x2091, 0x8001, 0x0804, 0x23c8, 0x2091, 0x8001,
-+	0x0804, 0x23b7, 0x6024, 0x8007, 0xa084, 0x00ff, 0x01e0, 0xa086,
-+	0x0080, 0x15e8, 0x20a9, 0x0008, 0x6014, 0xd0fc, 0x1118, 0x2069,
-+	0xfc20, 0x0010, 0x2069, 0xfd40, 0x2091, 0x8000, 0x6800, 0xa084,
-+	0xfcff, 0x6802, 0xade8, 0x0009, 0x0f04, 0x2317, 0x0cb8, 0x2091,
-+	0x8001, 0x0804, 0x23ba, 0x6028, 0xa015, 0x0508, 0x6114, 0x080c,
-+	0x2525, 0x00d6, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d,
-+	0x0198, 0xa206, 0x0110, 0x2168, 0x0cc8, 0x00c6, 0x2160, 0x6000,
-+	0x6802, 0x080c, 0x1c95, 0x00ce, 0x00de, 0x6808, 0x8000, 0x680a,
-+	0x2091, 0x8001, 0x0804, 0x23c8, 0x2091, 0x8001, 0x00de, 0x0804,
-+	0x23b4, 0x6114, 0x080c, 0x2525, 0x6800, 0xa084, 0x0001, 0x0904,
-+	0x23a8, 0x2091, 0x8000, 0x6a04, 0x8210, 0x0228, 0x6a06, 0x2091,
-+	0x8001, 0x0804, 0x23c8, 0x2091, 0x8001, 0x0804, 0x23b7, 0x6114,
-+	0x080c, 0x2525, 0x60ce, 0x60bb, 0x0000, 0x6018, 0xa08c, 0xff00,
-+	0x6820, 0xa084, 0x00ff, 0xa105, 0x601a, 0x6900, 0xa184, 0x0008,
-+	0x0120, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0904,
-+	0x23b4, 0xa184, 0x0100, 0x1588, 0xa184, 0x0200, 0x1558, 0x681c,
-+	0xa005, 0x1588, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000f, 0x1110,
-+	0x080c, 0x250a, 0x78bf, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff,
-+	0x78b2, 0x8001, 0x609f, 0x0000, 0x0138, 0x04e1, 0x0128, 0x78bc,
-+	0xa085, 0x0100, 0x78be, 0x0005, 0x78b7, 0x0000, 0x78bb, 0x0000,
-+	0x6024, 0xa084, 0xff00, 0x6026, 0x080c, 0x42ef, 0x1108, 0x0005,
-+	0x0804, 0x1ed6, 0x2009, 0x0017, 0x00b8, 0x2009, 0x000e, 0x00a0,
-+	0x2009, 0x0007, 0x0088, 0x2009, 0x0035, 0x0070, 0x2009, 0x003e,
-+	0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009,
-+	0x0016, 0x0010, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, 0xa105,
-+	0x6026, 0x2091, 0x8000, 0x080c, 0x2076, 0x2091, 0x8001, 0x0005,
-+	0x0804, 0x1c95, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6,
-+	0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06,
-+	0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1138, 0x78bc, 0xa084,
-+	0xfeff, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e,
-+	0x2530, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff,
-+	0x601e, 0xa984, 0x0060, 0x0110, 0x080c, 0x5365, 0x6596, 0x65a6,
-+	0x669a, 0x66aa, 0x6714, 0x2071, 0xb3c0, 0xd7fc, 0x1110, 0x2071,
-+	0xb380, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0120, 0x8003,
-+	0x8003, 0x8003, 0x8003, 0xa105, 0x71e0, 0xa168, 0x2700, 0x8007,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x8003, 0x71e4, 0xa100,
-+	0x60c6, 0x2091, 0x8000, 0x780c, 0xd0c4, 0x0160, 0xd0ec, 0x0138,
-+	0xd7fc, 0x1118, 0xd0f4, 0x1158, 0x0028, 0xd0fc, 0x1140, 0x7808,
-+	0xd0f4, 0x1128, 0x6e08, 0xd684, 0x0560, 0xd9fc, 0x1550, 0x2091,
-+	0x8001, 0x080c, 0x1d3b, 0x2091, 0x8000, 0x080c, 0x2076, 0x2091,
-+	0x8001, 0x78b7, 0x0000, 0x78bb, 0x0000, 0x780c, 0xd0e4, 0x1904,
-+	0x24b1, 0x780c, 0xd0c4, 0x0904, 0x24b1, 0xd0ec, 0x0150, 0xd7fc,
-+	0x1120, 0xd0f4, 0x1150, 0x0804, 0x24b1, 0xd0fc, 0x1130, 0x0804,
-+	0x24b1, 0x7808, 0xd0f4, 0x0904, 0x24b1, 0x601b, 0x0021, 0x0804,
-+	0x24b1, 0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10,
-+	0x6814, 0xa202, 0x0248, 0x0140, 0x2091, 0x8001, 0x2039, 0x0200,
-+	0x080c, 0x24b3, 0x0804, 0x24b1, 0x2c08, 0xd9fc, 0x01f0, 0x6800,
-+	0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0168, 0x7050,
-+	0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002, 0xa005, 0x1108,
-+	0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060, 0x080c, 0x2af4,
-+	0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, 0x6800, 0x6902, 0xa065,
-+	0x0110, 0x6102, 0x0008, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
-+	0xd9fc, 0x0138, 0xa6b4, 0xffdc, 0x6e0a, 0x682b, 0x0000, 0x682f,
-+	0x0000, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0128,
-+	0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1d4c, 0x78bb, 0x0000, 0x78b7,
-+	0x0000, 0x00ee, 0x0005, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000,
-+	0x080c, 0x2076, 0x2091, 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c,
-+	0x78ba, 0x609f, 0x0000, 0x0c90, 0x78b7, 0x0000, 0x78bb, 0x0000,
-+	0x0005, 0x7968, 0x786c, 0x7b84, 0xd384, 0x0118, 0x8000, 0xa112,
-+	0x0220, 0xc384, 0x8000, 0xa112, 0x1260, 0x7a74, 0x721a, 0x7a70,
-+	0x721e, 0x7a7c, 0x7222, 0x7a78, 0x7226, 0xa006, 0xd384, 0x0108,
-+	0x8000, 0x786e, 0x70d2, 0x7904, 0xd19c, 0x01b0, 0x0146, 0x00c6,
-+	0x20a1, 0x0030, 0x20a2, 0x20a3, 0x0000, 0x7013, 0x0004, 0x2061,
-+	0xfed8, 0x2c14, 0x8c60, 0x2c1c, 0x8c60, 0x2c24, 0x8c60, 0x2c2c,
-+	0x080c, 0x204b, 0x00ce, 0x014e, 0x7814, 0xa005, 0x0138, 0x8001,
-+	0x7816, 0x1120, 0x0e04, 0x2506, 0x2091, 0x4080, 0x0005, 0x2039,
-+	0x251c, 0x0010, 0x2039, 0x2522, 0x2704, 0xa005, 0x0160, 0xac00,
-+	0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916,
-+	0x680e, 0x8738, 0x0c88, 0x0005, 0x0003, 0x0009, 0x000f, 0x0015,
-+	0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x00c6, 0x6014, 0x080c,
-+	0x449c, 0x2c68, 0x00ce, 0x0005, 0x78ab, 0x0000, 0x2009, 0xb341,
-+	0x2104, 0xd084, 0x0510, 0x6004, 0xa086, 0x0103, 0x11f0, 0x6114,
-+	0x6018, 0xa105, 0x11d0, 0x00d6, 0x2069, 0x0000, 0x6818, 0xd084,
-+	0x1198, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b,
-+	0x0001, 0x2091, 0x4080, 0x00de, 0x080c, 0x2099, 0x0e04, 0x257e,
-+	0x7864, 0xa065, 0x19d8, 0x0450, 0x00de, 0x0459, 0x0518, 0x6204,
-+	0xa294, 0x00ff, 0xa296, 0x0003, 0x0130, 0x6204, 0xa296, 0x0110,
-+	0x1168, 0x78ab, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211,
-+	0x0128, 0x85ff, 0x1178, 0x8210, 0xa202, 0x1260, 0x0056, 0x00f1,
-+	0x005e, 0x1140, 0x8528, 0x78a8, 0xa005, 0x1120, 0x7864, 0xa065,
-+	0x1904, 0x252e, 0x85ff, 0x0120, 0x2091, 0x4080, 0x7890, 0x70d6,
-+	0x0005, 0x7b8c, 0x7990, 0x70d4, 0xa102, 0x1118, 0x2300, 0xa005,
-+	0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, 0xff00,
-+	0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
-+	0x0018, 0x8107, 0x8004, 0x8004, 0x7a98, 0x7b94, 0x7ca0, 0x7d9c,
-+	0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0020, 0x6004,
-+	0xa086, 0x0103, 0x1128, 0x6028, 0xa005, 0x1110, 0x2009, 0x000c,
-+	0x080c, 0x1c39, 0x01e0, 0x78a4, 0x8000, 0x78a6, 0xa086, 0x0002,
-+	0x1904, 0x25fc, 0x6014, 0xd0fc, 0x1118, 0x2069, 0xb380, 0x0010,
-+	0x2069, 0xb3c0, 0x2091, 0x8000, 0x681b, 0x0003, 0x78a7, 0x0000,
-+	0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0468, 0x78a7,
-+	0x0000, 0x080c, 0x2099, 0x798c, 0x7890, 0x8000, 0xa10a, 0x1208,
-+	0xa006, 0x7892, 0x70d6, 0x7904, 0xd19c, 0x01e8, 0x0006, 0x0146,
-+	0x00c6, 0x20a1, 0x0030, 0x20a2, 0xa006, 0x20a2, 0x7013, 0x0004,
-+	0x2061, 0xfed8, 0x2c14, 0xa290, 0x0004, 0x8c60, 0x2c1c, 0xa319,
-+	0x8c60, 0x2c24, 0xa421, 0x8c60, 0x2c2c, 0xa529, 0x080c, 0x204b,
-+	0x00ce, 0x014e, 0x000e, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001,
-+	0x0005, 0x2138, 0xd7fc, 0x1118, 0x2009, 0xb39a, 0x0010, 0x2009,
-+	0xb3da, 0x2091, 0x8000, 0x200a, 0x00f6, 0xd7fc, 0x1168, 0x2009,
-+	0xb380, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x0118, 0x2079, 0x0100,
-+	0x0038, 0x2079, 0x0200, 0x0020, 0x2009, 0xb3c0, 0x2079, 0x0100,
-+	0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0xb384,
-+	0x0010, 0x2009, 0xb3c4, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084,
-+	0x00c0, 0x1110, 0x781b, 0x0053, 0x00fe, 0x0005, 0x00f6, 0x00e6,
-+	0x2c00, 0xa005, 0x1120, 0xa188, 0x0005, 0x2104, 0x0008, 0x6014,
-+	0xd0fc, 0x1168, 0x2071, 0xb380, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x0118, 0x2079, 0x0100, 0x0038, 0x2079, 0x0200, 0x0020, 0x2071,
-+	0xb3c0, 0x2079, 0x0100, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000,
-+	0x1510, 0x00b8, 0x2c00, 0xa005, 0x1120, 0xa188, 0x0005, 0x2104,
-+	0x0008, 0x6014, 0xd0fc, 0x1158, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x0118, 0x2079, 0x0100, 0x0028, 0x2079, 0x0200, 0x0010, 0x2079,
-+	0x0100, 0x7830, 0xa084, 0x00c0, 0x1130, 0x2c00, 0xa005, 0x1108,
-+	0x2104, 0x781b, 0x0055, 0x2091, 0x8001, 0x00ee, 0x00fe, 0x0005,
-+	0x2009, 0x0002, 0x2069, 0xb340, 0x6808, 0xd0ec, 0x1904, 0x26d5,
-+	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x26d5, 0x2071, 0xb3c0,
-+	0x2079, 0x0100, 0x2021, 0xb5ff, 0x784b, 0x000f, 0x1104, 0x26a0,
-+	0x7838, 0x0cd0, 0x784b, 0x000f, 0x1304, 0x26a0, 0x7838, 0x0cd0,
-+	0x20a9, 0x0060, 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000,
-+	0x1f04, 0x26a4, 0x70ab, 0x009d, 0x2019, 0x5a04, 0x04e1, 0x7003,
-+	0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c,
-+	0x286a, 0x001e, 0x701c, 0xa084, 0x000f, 0x0006, 0x680c, 0xd0e4,
-+	0x000e, 0x1118, 0xa085, 0x6300, 0x0010, 0xa085, 0x62c0, 0x7806,
-+	0x780f, 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x2f08,
-+	0x704f, 0x2f08, 0x745a, 0x7057, 0x0000, 0x8109, 0x0188, 0x2071,
-+	0xb380, 0x6808, 0xd0ec, 0x0130, 0x2079, 0x0100, 0x2021, 0xb3ff,
-+	0x0804, 0x2694, 0x2079, 0x0200, 0x2021, 0xb3ff, 0x0804, 0x269a,
-+	0x080c, 0x2930, 0x0005, 0x0136, 0x0146, 0x0156, 0x0046, 0x0016,
-+	0x3808, 0x20c1, 0x0020, 0xaf80, 0x002b, 0x20a0, 0x2304, 0xa005,
-+	0x789a, 0x0190, 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484,
-+	0xff00, 0x0120, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6,
-+	0xa005, 0x1da0, 0x3318, 0x0c50, 0x21c0, 0x001e, 0x004e, 0x015e,
-+	0x014e, 0x013e, 0x0005, 0x0016, 0x00f6, 0xd1bc, 0x1168, 0x0006,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x2079, 0x0100,
-+	0x0028, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0xa18c, 0x000f,
-+	0x7804, 0xa084, 0xfff0, 0xa105, 0x7806, 0x00fe, 0x001e, 0x080c,
-+	0x286a, 0x0005, 0xd3fc, 0x1168, 0x0006, 0x2001, 0xb342, 0x2004,
-+	0xd0ec, 0x000e, 0x0118, 0x2011, 0x0101, 0x0028, 0x2011, 0x0201,
-+	0x0010, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x2745,
-+	0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005,
-+	0x2019, 0x0002, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x0120, 0x8319,
-+	0x2009, 0x0101, 0x0010, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213,
-+	0x1f04, 0x275f, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
-+	0x200a, 0x8319, 0x0118, 0x2009, 0x0201, 0x0c78, 0x0005, 0xd3fc,
-+	0x1168, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118,
-+	0x2011, 0x0101, 0x0028, 0x2011, 0x0201, 0x0010, 0x2011, 0x0101,
-+	0x20a9, 0x000c, 0x810b, 0x1f04, 0x2782, 0xa18c, 0xf000, 0x2204,
-+	0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0xd3fc, 0x1168, 0x0006,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x2011, 0x0102,
-+	0x0028, 0x2011, 0x0202, 0x0010, 0x2011, 0x0102, 0x2204, 0xa084,
-+	0xf0cf, 0xa105, 0x2012, 0x0005, 0x00c6, 0xd1bc, 0x1168, 0x0006,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x2061, 0x0100,
-+	0x0028, 0x2061, 0x0200, 0x0010, 0x2061, 0x0100, 0xc1bc, 0x8103,
-+	0x8003, 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005,
-+	0x00c6, 0xd1bc, 0x1168, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x000e, 0x0118, 0x2061, 0x0100, 0x0028, 0x2061, 0x0200, 0x0010,
-+	0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a,
-+	0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6, 0xd1bc,
-+	0x1168, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118,
-+	0x2061, 0x0100, 0x0028, 0x2061, 0x0200, 0x0010, 0x2061, 0x0100,
-+	0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0x62ae,
-+	0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000,
-+	0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x284e, 0xd1fc, 0x1118,
-+	0x2061, 0xfb00, 0x0010, 0x2061, 0xfc10, 0x080c, 0x2856, 0x0538,
-+	0x20a9, 0x0101, 0xd1fc, 0x1118, 0x2061, 0xfa00, 0x0010, 0x2061,
-+	0xfb10, 0x00c6, 0x04d9, 0x0128, 0x00ce, 0x8c60, 0x1f04, 0x2819,
-+	0x0468, 0x000e, 0xd1fc, 0x1128, 0x2071, 0xb380, 0xa082, 0xfa00,
-+	0x0020, 0x2071, 0xb3c0, 0xa082, 0xfb10, 0x707e, 0x717a, 0x2001,
-+	0x0004, 0x706a, 0x7087, 0x000f, 0x080c, 0x2601, 0x00a0, 0x60d0,
-+	0xa005, 0x11a0, 0xd1fc, 0x1118, 0x2071, 0xb380, 0x0010, 0x2071,
-+	0xb3c0, 0x717a, 0x2c00, 0x7082, 0x2001, 0x0006, 0x706a, 0x7087,
-+	0x000f, 0x080c, 0x2601, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001,
-+	0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04, 0xa005,
-+	0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206, 0x1128,
-+	0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80, 0xa085,
-+	0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0xd1bc, 0x1178, 0x2079,
-+	0xb380, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118,
-+	0x2071, 0x0100, 0x0038, 0x2071, 0x0200, 0x0020, 0x2079, 0xb3c0,
-+	0x2071, 0x0100, 0x791c, 0xa18c, 0x000f, 0x70ec, 0xa084, 0x0100,
-+	0x000e, 0x0160, 0x810b, 0x810b, 0x810b, 0x810b, 0xd0bc, 0x1118,
-+	0xa18d, 0x0f00, 0x0010, 0xa18d, 0x0800, 0x2104, 0x00ee, 0x00fe,
-+	0x0005, 0x2001, 0xb341, 0x2004, 0xd0ac, 0x1140, 0x68e4, 0xa08c,
-+	0x0020, 0x0120, 0xa084, 0x0006, 0x1108, 0x0009, 0x0005, 0x6014,
-+	0x00e6, 0x0036, 0x2018, 0x2071, 0xb900, 0xd0fc, 0x1110, 0x2071,
-+	0xb800, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x8003,
-+	0xae70, 0x7004, 0xa084, 0x000a, 0x1904, 0x292d, 0x7108, 0xa194,
-+	0xff00, 0x0904, 0x292d, 0xa18c, 0x00ff, 0x701c, 0xa084, 0xff00,
-+	0x01c0, 0x7004, 0xa085, 0x003a, 0x7006, 0x2001, 0x0009, 0xa102,
-+	0x16d8, 0x2001, 0x000a, 0xa102, 0x16d0, 0x2001, 0x000c, 0xa102,
-+	0x16c8, 0x701c, 0xa084, 0x00ff, 0x701e, 0x7004, 0xa084, 0xffdf,
-+	0x7006, 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106,
-+	0x01a0, 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106,
-+	0x0190, 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106,
-+	0x0180, 0x00d8, 0x2009, 0x000c, 0x00c8, 0x2009, 0x0012, 0x00b0,
-+	0x2009, 0x0014, 0x0098, 0x2009, 0x0019, 0x0080, 0x2009, 0x0020,
-+	0x0068, 0x2009, 0x003f, 0x0050, 0x2009, 0x000a, 0x0038, 0x2009,
-+	0x000c, 0x0020, 0x2009, 0x0019, 0x0008, 0xa016, 0x2100, 0xa205,
-+	0x700a, 0x7004, 0xa085, 0x000a, 0x7006, 0x2071, 0xb340, 0x7004,
-+	0xd0bc, 0x0158, 0xd3fc, 0x1120, 0x73ea, 0x2071, 0xb380, 0x0018,
-+	0x73ee, 0x2071, 0xb3c0, 0x701b, 0x800f, 0x003e, 0x00ee, 0x0005,
-+	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004,
-+	0xa082, 0x0005, 0x12a0, 0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00,
-+	0x810f, 0x810c, 0x810c, 0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00,
-+	0x8007, 0x8004, 0x8004, 0xa105, 0xa08a, 0x0007, 0x0208, 0x0005,
-+	0x0002, 0x297e, 0x2965, 0x297e, 0x2965, 0x2958, 0x2972, 0x2958,
-+	0x7008, 0xa084, 0xc3ff, 0xa085, 0x3000, 0x700a, 0x7808, 0xa084,
-+	0xc3ff, 0xa085, 0x3000, 0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff,
-+	0xa085, 0x2000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000,
-+	0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a,
-+	0x7808, 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04,
-+	0x297f, 0x2091, 0x8000, 0x2071, 0x0000, 0x0006, 0x7018, 0xd084,
-+	0x1de8, 0x000e, 0x2071, 0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3,
-+	0x8002, 0x70db, 0x0b0c, 0x70df, 0x0001, 0x2071, 0x0000, 0x701b,
-+	0x0001, 0x2091, 0x4080, 0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38,
-+	0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0002, 0x29b8,
-+	0x29b8, 0x29b8, 0x2dbc, 0x4117, 0x29b7, 0x29e0, 0x29e3, 0x29b7,
-+	0x29b7, 0x29b7, 0x29b7, 0x29b7, 0x29b7, 0x29b7, 0x29b7, 0x0839,
-+	0x8507, 0xa084, 0x003f, 0x0002, 0x29e6, 0x2dbc, 0x2fa8, 0x30d0,
-+	0x310e, 0x338a, 0x3681, 0x36f3, 0x3767, 0x3804, 0x38ee, 0x397e,
-+	0x29e0, 0x2ec1, 0x3653, 0x29dd, 0x464c, 0x466f, 0x4832, 0x483d,
-+	0x4910, 0x29dd, 0x29dd, 0x49e6, 0x49ea, 0x464a, 0x29dd, 0x478d,
-+	0x29dd, 0x44e4, 0x29e3, 0x4ad8, 0x4af6, 0x080c, 0x297f, 0x0005,
-+	0x781b, 0x0057, 0x0005, 0x781b, 0x00e1, 0x0005, 0x724a, 0xa584,
-+	0x0001, 0x1904, 0x44f6, 0x0160, 0x080c, 0x297f, 0x7003, 0x0000,
-+	0x7053, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, 0x080c, 0x40d4,
-+	0x7064, 0xa06d, 0x0140, 0x70f4, 0xa084, 0x0001, 0x7168, 0xa105,
-+	0x1110, 0x0804, 0x2b4d, 0x7068, 0xa084, 0x0007, 0x0002, 0x2a0f,
-+	0x2a87, 0x2a8f, 0x2a98, 0x2aa1, 0x2b33, 0x2aaa, 0x2a87, 0x7830,
-+	0xd0bc, 0x1968, 0x71f0, 0xd1bc, 0x1950, 0xd1b4, 0x1904, 0x2a65,
-+	0x70c0, 0xa086, 0x0001, 0x0918, 0x080c, 0x40bd, 0x1900, 0x70d0,
-+	0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0090, 0x6b0c, 0x7baa,
-+	0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001,
-+	0x0118, 0x69c0, 0x7daa, 0x79aa, 0x68c4, 0xa04d, 0x6e1c, 0x7830,
-+	0xd0bc, 0x1904, 0x29df, 0x2001, 0x0010, 0x0804, 0x2c89, 0x7064,
-+	0xa005, 0x1904, 0x29df, 0x080c, 0x40bd, 0x1904, 0x29df, 0x00c6,
-+	0x00d6, 0x70d0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0090,
-+	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
-+	0xa886, 0x0001, 0x0118, 0x69c0, 0x7daa, 0x79aa, 0x68c4, 0xa04d,
-+	0x6e1c, 0x2001, 0x0020, 0x0804, 0x2c89, 0x080c, 0x40a8, 0x1904,
-+	0x29df, 0x70d8, 0xa06d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x68b4,
-+	0x785a, 0x781b, 0x0057, 0x704c, 0xc08d, 0x780a, 0x68c0, 0x703e,
-+	0x70f0, 0xc0b4, 0x70f2, 0x70d4, 0xa065, 0x68c4, 0x705e, 0x7003,
-+	0x0002, 0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c,
-+	0x40a8, 0x1120, 0x781b, 0x0050, 0x7003, 0x0004, 0x0005, 0x080c,
-+	0x40a8, 0x1128, 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005,
-+	0x080c, 0x40a8, 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004,
-+	0x0005, 0x080c, 0x40a8, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003,
-+	0x0004, 0x0005, 0x080c, 0x40a8, 0x1150, 0x2011, 0x0006, 0x0041,
-+	0x7080, 0x7083, 0x0000, 0x2068, 0x7052, 0x7003, 0x0001, 0x0005,
-+	0x7178, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0090, 0xa286, 0x000c,
-+	0x1120, 0x7aaa, 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d,
-+	0x00c0, 0x79aa, 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002,
-+	0x0038, 0x78ab, 0x0020, 0x717c, 0x79aa, 0x7aaa, 0x2001, 0x0004,
-+	0x789b, 0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x00ef, 0x080c,
-+	0x40d4, 0x7087, 0x000f, 0x70f0, 0xd0b4, 0x0168, 0xc0b4, 0x70f2,
-+	0x00c6, 0x70d4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
-+	0x8001, 0x601a, 0x00ce, 0x0005, 0x7010, 0xa005, 0x1138, 0x70f0,
-+	0xd0b4, 0x0128, 0x70d4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016,
-+	0x71c0, 0xa186, 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011,
-+	0x0001, 0xa212, 0x70d0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211,
-+	0x01b0, 0x00c9, 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212,
-+	0x70d0, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x8211, 0x0110, 0x0041, 0x0cb0, 0x70c3, 0x0001, 0x00ce, 0x002e,
-+	0x00de, 0x001e, 0x0005, 0xade8, 0x0005, 0x70c8, 0xad06, 0x1110,
-+	0x70c4, 0x2068, 0x0005, 0x080c, 0x40a8, 0x1904, 0x29df, 0x7080,
-+	0x2068, 0x7778, 0x080c, 0x3fb3, 0x2c50, 0x080c, 0x418d, 0x789b,
-+	0x0090, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041,
-+	0x0001, 0x2001, 0x0004, 0x0804, 0x2c8e, 0x080c, 0x40a8, 0x1904,
-+	0x29df, 0x789b, 0x0090, 0x7064, 0x2068, 0x6f14, 0x080c, 0x2ae3,
-+	0x080c, 0x3fb3, 0x2c50, 0x080c, 0x418d, 0x6824, 0xa005, 0x0130,
-+	0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, 0x6b14, 0xa39c,
-+	0x001f, 0xa39d, 0x00c0, 0x2960, 0x6000, 0x2a60, 0xa084, 0x8000,
-+	0x0118, 0xa684, 0x0001, 0x0110, 0xa39c, 0xffbf, 0x7baa, 0x2031,
-+	0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2c8e, 0xc28d,
-+	0x72f2, 0x72dc, 0xa200, 0xa015, 0x7158, 0x8108, 0xa12a, 0x0208,
-+	0x71dc, 0x2164, 0x6504, 0x85ff, 0x1190, 0x715a, 0x8421, 0x1da8,
-+	0x70f0, 0xd08c, 0x0128, 0x70ec, 0xa005, 0x1110, 0x70ef, 0x000a,
-+	0x7048, 0xa005, 0x0904, 0x44f6, 0x0005, 0x2200, 0x0c70, 0x70f0,
-+	0xc08c, 0x70f2, 0x70ef, 0x0000, 0x6034, 0xa005, 0x1db0, 0x6708,
-+	0xa784, 0x073f, 0x01a8, 0xd7d4, 0x1d80, 0xa784, 0x0021, 0x1d68,
-+	0xd78c, 0x0120, 0xd794, 0x0d48, 0xc794, 0x670a, 0xa784, 0x0218,
-+	0x1d20, 0xd7c4, 0x0128, 0x6018, 0xa005, 0x19f8, 0xc7c4, 0x670a,
-+	0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128,
-+	0x601c, 0xa302, 0x0220, 0x0118, 0x0880, 0x83ff, 0x1970, 0x2d58,
-+	0x2c50, 0x715a, 0x68d3, 0x0000, 0xd7bc, 0x1118, 0x7024, 0x6022,
-+	0x603a, 0xc7bc, 0x670a, 0x68c4, 0xa065, 0xa04d, 0x6100, 0x2a60,
-+	0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc,
-+	0x0110, 0xd684, 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110, 0xa39d,
-+	0x0020, 0xa684, 0x000e, 0x1904, 0x2c39, 0xc7a5, 0x670a, 0x2c00,
-+	0x68ca, 0x77c0, 0xa786, 0x0001, 0x11a8, 0x70f0, 0xd0b4, 0x1190,
-+	0x7000, 0xa082, 0x0001, 0x1270, 0x7010, 0xa005, 0x1158, 0x080c,
-+	0x40bd, 0x1140, 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0090, 0x7baa,
-+	0x0804, 0x2c87, 0x8739, 0x77c2, 0x2750, 0x77cc, 0xa7b0, 0x0005,
-+	0x70c8, 0xa606, 0x1108, 0x76c4, 0x76ce, 0x2c3a, 0x8738, 0x2d3a,
-+	0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc,
-+	0x0140, 0x2091, 0x303d, 0x70f0, 0xa084, 0x303d, 0x2091, 0x8000,
-+	0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904, 0x2b84,
-+	0x0005, 0xd1dc, 0x0904, 0x3c0a, 0x2029, 0x0020, 0xd69c, 0x1120,
-+	0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108,
-+	0xa18c, 0x00ff, 0x70e8, 0xa160, 0x2c64, 0x8cff, 0x0180, 0x6014,
-+	0xa706, 0x1dd0, 0x60bc, 0x8001, 0x60be, 0x1d88, 0x2a60, 0x6008,
-+	0xc0c5, 0x600a, 0x2200, 0x8421, 0x1904, 0x2b84, 0x0005, 0x2a60,
-+	0x610e, 0x69c2, 0x2c00, 0x68ca, 0x8840, 0x6008, 0xc0d5, 0x600a,
-+	0x77c0, 0xa786, 0x0001, 0x1904, 0x2c12, 0x70f0, 0xd0b4, 0x1904,
-+	0x2c12, 0x7000, 0xa082, 0x0001, 0x1a04, 0x2c12, 0x7010, 0xa005,
-+	0x1904, 0x2c12, 0x080c, 0x40bd, 0x1904, 0x2c12, 0x7830, 0xd0bc,
-+	0x1904, 0x2c12, 0x789b, 0x0090, 0x7baa, 0x7daa, 0x79aa, 0x2001,
-+	0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008, 0x0006, 0x2960,
-+	0x6104, 0x2a60, 0x080c, 0x41d0, 0x1560, 0xa184, 0x0018, 0x0178,
-+	0xa184, 0x0010, 0x0118, 0x080c, 0x3dc6, 0x1518, 0xd19c, 0x0138,
-+	0x69a0, 0xa184, 0x0600, 0x1118, 0x080c, 0x3cd1, 0x00d0, 0x69a0,
-+	0xa184, 0x1e00, 0x01f8, 0xd1dc, 0x0168, 0x00c6, 0x2960, 0x6000,
-+	0xc0ed, 0x6002, 0x6104, 0xc1a5, 0x6106, 0x00ce, 0x080c, 0x3dc6,
-+	0x1140, 0x69a0, 0xd1cc, 0x0118, 0x080c, 0x3d18, 0x0010, 0xd1d4,
-+	0x1d18, 0x69a0, 0xd1e4, 0x0130, 0x6914, 0xa18c, 0xff00, 0x810f,
-+	0x080c, 0x27c0, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0120,
-+	0xa086, 0x0060, 0x1108, 0xc1f5, 0xa18d, 0x0104, 0x69b6, 0x789b,
-+	0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0168,
-+	0xc0fc, 0x708b, 0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, 0x000c,
-+	0x718a, 0x2001, 0x000c, 0x800c, 0x718e, 0x78aa, 0x3518, 0x3340,
-+	0x3428, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80,
-+	0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020,
-+	0x11e0, 0x70f0, 0xc0b5, 0x70f2, 0x2c00, 0x70d6, 0x2d00, 0x70da,
-+	0xa286, 0x0002, 0x05d8, 0x70c0, 0x8000, 0x70c2, 0x74d0, 0xa498,
-+	0x0005, 0x70c8, 0xa306, 0x1108, 0x73c4, 0x73d2, 0xa286, 0x0010,
-+	0x0904, 0x29df, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x1d08,
-+	0xa286, 0x0002, 0x15d0, 0x080c, 0x40a8, 0x19d8, 0x6814, 0xc0fc,
-+	0x8007, 0x7882, 0x68b4, 0x785a, 0x781b, 0x0057, 0x704c, 0xc08d,
-+	0x780a, 0x0126, 0x00d6, 0x00c6, 0x70f0, 0xa084, 0x2e00, 0x2090,
-+	0x00ce, 0x00de, 0x012e, 0x2900, 0x705e, 0x68c0, 0x703e, 0x7003,
-+	0x0002, 0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x7830, 0xd0bc,
-+	0x0140, 0x2091, 0x303d, 0x70f0, 0xa084, 0x303d, 0x2091, 0x8000,
-+	0x2090, 0x70c0, 0xa005, 0x1108, 0x0005, 0x8421, 0x0de8, 0x7254,
-+	0x70dc, 0xa200, 0xa015, 0x0804, 0x2b84, 0xa286, 0x0010, 0x1530,
-+	0x080c, 0x40a8, 0x1904, 0x2d01, 0x6814, 0xc0fc, 0x8007, 0x7882,
-+	0x68b4, 0x785a, 0x781b, 0x0057, 0x704c, 0xc08d, 0x780a, 0x70c0,
-+	0x8000, 0x70c2, 0x74d0, 0xa490, 0x0005, 0x70c8, 0xa206, 0x1108,
-+	0x72c4, 0x72d2, 0x2900, 0x705e, 0x68c0, 0x703e, 0x7003, 0x0002,
-+	0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x0005, 0x6bb4, 0xa39d,
-+	0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6,
-+	0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0057, 0x2900, 0x705e,
-+	0x7202, 0x704c, 0xc08d, 0x780a, 0x7200, 0x2300, 0xa605, 0x0170,
-+	0x70f0, 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000,
-+	0x0010, 0x2009, 0x0001, 0xa284, 0x000f, 0x0023, 0xad80, 0x0009,
-+	0x7042, 0x0005, 0x2dba, 0x55dc, 0x55dc, 0x55ca, 0x55dc, 0x2dba,
-+	0x2dba, 0x2dba, 0x080c, 0x297f, 0x080c, 0x40a8, 0x7808, 0xa084,
-+	0xfffc, 0x780a, 0x00f6, 0x2079, 0xb340, 0x78ac, 0x00fe, 0xd084,
-+	0x01b8, 0x7068, 0xa086, 0x0001, 0x1110, 0x0804, 0x2e97, 0x7068,
-+	0xa086, 0x0005, 0x1158, 0x7080, 0x2068, 0x681b, 0x0004, 0x6817,
-+	0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x706b, 0x0000,
-+	0x70c3, 0x0000, 0x70c4, 0x70ce, 0x70d2, 0x70f4, 0xc084, 0x70f6,
-+	0x080c, 0x2ae3, 0x2011, 0x0004, 0x7168, 0xa186, 0x0001, 0x0160,
-+	0xa186, 0x0007, 0x1118, 0x701b, 0x0005, 0x0030, 0x701b, 0x0001,
-+	0x70f0, 0xc0c5, 0x70f2, 0x0000, 0x2001, 0xb348, 0x203c, 0xd7fc,
-+	0x1120, 0xae86, 0xb380, 0x0120, 0x0040, 0xae86, 0xb3c0, 0x1128,
-+	0xa784, 0x00ff, 0xa086, 0x0018, 0x0130, 0x7014, 0x7012, 0xa005,
-+	0x1110, 0x70c3, 0x0001, 0x0066, 0x080c, 0x52e3, 0x0156, 0x20a9,
-+	0x0010, 0x2039, 0x0000, 0x080c, 0x3ec6, 0xa7b8, 0x0100, 0x1f04,
-+	0x2e1b, 0x015e, 0x006e, 0x7000, 0x0002, 0x2e57, 0x2e35, 0x2e35,
-+	0x2e2d, 0x2e57, 0x2e57, 0x2e57, 0x2e57, 0x7064, 0xa005, 0x0538,
-+	0xad06, 0x1118, 0x6800, 0x7066, 0x0080, 0x6820, 0xd084, 0x1148,
-+	0x6f14, 0x080c, 0x3fb3, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x3be8,
-+	0x0020, 0x7060, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e,
-+	0x6818, 0xd0fc, 0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000,
-+	0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x2085, 0x2011,
-+	0x0004, 0xb284, 0x0800, 0x1118, 0x2021, 0xfb00, 0x0010, 0x2021,
-+	0xfc10, 0x080c, 0x2ea4, 0xb284, 0x0800, 0x0118, 0x2021, 0xb3d9,
-+	0x0010, 0x2021, 0xb399, 0x04c1, 0x0156, 0x20a9, 0x0101, 0xb284,
-+	0x0800, 0x1118, 0x2021, 0xfa00, 0x0010, 0x2021, 0xfb10, 0x0461,
-+	0x8420, 0x1f04, 0x2e77, 0xb284, 0x0600, 0x0118, 0x2061, 0xba00,
-+	0x0010, 0x2061, 0xda00, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018,
-+	0x6110, 0x81ff, 0x0118, 0xa102, 0x0308, 0x6012, 0x601b, 0x0000,
-+	0xace0, 0x0010, 0x1f04, 0x2e87, 0x8421, 0x1d78, 0x015e, 0x7090,
-+	0xa084, 0x8000, 0x0110, 0x080c, 0x4312, 0x706b, 0x0000, 0x7003,
-+	0x0000, 0x7053, 0x0000, 0x0005, 0x0046, 0x2404, 0xa005, 0x01a8,
-+	0x2068, 0x6800, 0x0006, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000,
-+	0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d,
-+	0x6822, 0x080c, 0x2085, 0x000e, 0x0c48, 0x004e, 0x2023, 0x0000,
-+	0x0005, 0xa282, 0x0003, 0x0310, 0x080c, 0x297f, 0x2300, 0x0002,
-+	0x2ecb, 0x2f45, 0x2f5f, 0xa282, 0x0002, 0x0110, 0x080c, 0x297f,
-+	0x7068, 0x706b, 0x0000, 0x7087, 0x0000, 0x000a, 0x0002, 0x2edf,
-+	0x2edf, 0x2ee1, 0x2f19, 0x3c14, 0x2edf, 0x2f19, 0x2edf, 0x080c,
-+	0x297f, 0x7778, 0x080c, 0x3ec6, 0x7778, 0xa7bc, 0x8f00, 0x080c,
-+	0x3fb3, 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0xfb00,
-+	0x0010, 0x2021, 0xfc10, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c,
-+	0x2f79, 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021,
-+	0xfa00, 0x0010, 0x2021, 0xfb10, 0x0046, 0x2009, 0x0005, 0x2011,
-+	0x0010, 0x080c, 0x2f79, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2f04,
-+	0x015e, 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x29ee, 0x0804,
-+	0x29ee, 0x7778, 0x080c, 0x3fb3, 0x6018, 0xa005, 0x0520, 0xd7fc,
-+	0x1118, 0x2021, 0xfb00, 0x0010, 0x2021, 0xfc10, 0x2009, 0x0005,
-+	0x2011, 0x0020, 0x080c, 0x2f79, 0x01b0, 0x0156, 0x20a9, 0x0101,
-+	0xd7fc, 0x1118, 0x2021, 0xfa00, 0x0010, 0x2021, 0xfb10, 0x0046,
-+	0x2009, 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420,
-+	0x1f04, 0x2f37, 0x015e, 0x0804, 0x29ee, 0x2200, 0x0002, 0x2f4a,
-+	0x2f4c, 0x2f4c, 0x080c, 0x297f, 0x2009, 0x0012, 0x7068, 0xa086,
-+	0x0002, 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a,
-+	0x706b, 0x0000, 0x70f0, 0xc0c5, 0x70f2, 0x0804, 0x404b, 0x2200,
-+	0x0002, 0x2f66, 0x2f4c, 0x2f64, 0x080c, 0x297f, 0x080c, 0x52e3,
-+	0x7000, 0xa086, 0x0002, 0x1904, 0x3b9e, 0x080c, 0x3bfa, 0x6008,
-+	0xa084, 0xfbef, 0x600a, 0x080c, 0x3b90, 0x0904, 0x3b9e, 0x0804,
-+	0x29ee, 0x2404, 0xa005, 0x0548, 0x2068, 0x2d04, 0x0006, 0x6814,
-+	0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x6817,
-+	0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x691a,
-+	0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, 0x682b, 0x0000, 0x080c,
-+	0x2085, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xf9ef, 0x600a,
-+	0x080c, 0x2aff, 0x080c, 0x3bfa, 0x0005, 0xa085, 0x0001, 0x0ce0,
-+	0x2300, 0x0002, 0x2faf, 0x2fad, 0x3057, 0x080c, 0x297f, 0x78ec,
-+	0xa084, 0x0001, 0x1170, 0x7000, 0xa086, 0x0004, 0x1110, 0x0804,
-+	0x3006, 0x080c, 0x3bfa, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x0804,
-+	0x3b9e, 0x78e4, 0xa005, 0x1b04, 0x3006, 0x3208, 0x0006, 0x2001,
-+	0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0xa18c, 0x0600, 0x0010,
-+	0xa18c, 0x0800, 0x0118, 0x0104, 0x29df, 0x0010, 0x0304, 0x29df,
-+	0x2008, 0xa084, 0x0030, 0x1118, 0x781b, 0x0057, 0x0005, 0x78ec,
-+	0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
-+	0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
-+	0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
-+	0x0010, 0x2001, 0x0001, 0x0002, 0x3036, 0x303f, 0x302a, 0x3004,
-+	0x409e, 0x409e, 0x3004, 0x304b, 0x080c, 0x297f, 0x7000, 0xa086,
-+	0x0004, 0x1190, 0x7068, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002,
-+	0x2019, 0x0000, 0x0804, 0x2ec1, 0x7068, 0xa086, 0x0006, 0x0db0,
-+	0x7068, 0xa086, 0x0004, 0x0d90, 0x79e4, 0xa184, 0x0030, 0x0120,
-+	0x78ec, 0xa084, 0x0003, 0x1110, 0x0804, 0x3653, 0x2001, 0x0003,
-+	0x0804, 0x339b, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c,
-+	0x3eaa, 0x782b, 0x3008, 0x781b, 0x005d, 0x0005, 0x6818, 0xd0fc,
-+	0x0110, 0x681b, 0x001d, 0x080c, 0x3eaa, 0x0804, 0x4073, 0x6818,
-+	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3eaa, 0x782b, 0x3008,
-+	0x781b, 0x00dd, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d,
-+	0x080c, 0x3eaa, 0x782b, 0x3008, 0x781b, 0x00a4, 0x0005, 0xa584,
-+	0x000f, 0x11c0, 0x7000, 0x0002, 0x29ee, 0x3064, 0x3066, 0x3b9e,
-+	0x3b9e, 0x3b9e, 0x3064, 0x3064, 0x080c, 0x297f, 0x080c, 0x3bfa,
-+	0x6008, 0xa084, 0xfbef, 0x600a, 0x080c, 0x3b90, 0x0904, 0x3b9e,
-+	0x0804, 0x29ee, 0x78e4, 0xa005, 0x1b04, 0x3006, 0x3208, 0x0006,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0xa18c, 0x0600,
-+	0x0010, 0xa18c, 0x0800, 0x0118, 0x0104, 0x3006, 0x0010, 0x0304,
-+	0x3006, 0x2008, 0xa084, 0x0030, 0x1118, 0x781b, 0x0057, 0x0005,
-+	0x78ec, 0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc, 0x1118, 0xa184,
-+	0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001,
-+	0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184,
-+	0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x30be, 0x30c2, 0x30b7,
-+	0x30b5, 0x409e, 0x409e, 0x30b5, 0x4096, 0x080c, 0x297f, 0x080c,
-+	0x3eb0, 0x782b, 0x3008, 0x781b, 0x005d, 0x0005, 0x080c, 0x3eb0,
-+	0x0804, 0x4073, 0x080c, 0x3eb0, 0x782b, 0x3008, 0x781b, 0x00dd,
-+	0x0005, 0x080c, 0x3eb0, 0x782b, 0x3008, 0x781b, 0x00a4, 0x0005,
-+	0x2300, 0x0002, 0x30d7, 0x30d5, 0x30d9, 0x080c, 0x297f, 0x0804,
-+	0x3804, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030,
-+	0x0904, 0x3804, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3804, 0xa184,
-+	0x0100, 0x0d98, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090,
-+	0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050,
-+	0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010,
-+	0x2001, 0x0001, 0x0002, 0x310b, 0x30c2, 0x302a, 0x404b, 0x409e,
-+	0x409e, 0x404b, 0x4096, 0x080c, 0x405b, 0x0005, 0xa282, 0x0005,
-+	0x0310, 0x080c, 0x297f, 0x7898, 0x2040, 0x2300, 0x0002, 0x311a,
-+	0x3356, 0x3362, 0x2200, 0x0002, 0x3136, 0x3123, 0x3136, 0x3121,
-+	0x3338, 0x080c, 0x297f, 0x789b, 0x0018, 0x78a8, 0x2010, 0xa084,
-+	0x00ff, 0xa082, 0x0020, 0x0a04, 0x3e69, 0xa08a, 0x0004, 0x1a04,
-+	0x3e69, 0x0002, 0x3e69, 0x3e69, 0x3e69, 0x3e1d, 0x789b, 0x0018,
-+	0x79a8, 0xa184, 0x0080, 0x0148, 0x0804, 0x3e69, 0x7000, 0xa005,
-+	0x1dd8, 0x2011, 0x0004, 0x0804, 0x398f, 0xa184, 0x00ff, 0xa08a,
-+	0x0010, 0x1a04, 0x3e69, 0x0002, 0x315e, 0x315c, 0x3171, 0x3175,
-+	0x3234, 0x3e69, 0x3e69, 0x3236, 0x3e69, 0x3e69, 0x3334, 0x3334,
-+	0x3e69, 0x3e69, 0x3e69, 0x3336, 0x080c, 0x297f, 0xa684, 0x1000,
-+	0x0140, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a, 0x781b, 0x009d,
-+	0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, 0x0804,
-+	0x404b, 0x681b, 0x001d, 0x0804, 0x3e98, 0x6920, 0x6922, 0xa684,
-+	0x1800, 0x1904, 0x31d1, 0x6820, 0xa084, 0x0001, 0x1904, 0x31d6,
-+	0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0904,
-+	0x3231, 0xd6bc, 0x05a0, 0x708b, 0x0000, 0x6818, 0xa084, 0x003f,
-+	0xa08a, 0x000d, 0x0760, 0xa08a, 0x000c, 0x718a, 0x2001, 0x000c,
-+	0x800c, 0x718e, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, 0x0146,
-+	0x0016, 0xb28c, 0x0600, 0x0168, 0x0006, 0x2001, 0xb342, 0x2004,
-+	0xd0ec, 0x000e, 0x0118, 0x20a1, 0x012b, 0x0028, 0x20a1, 0x022b,
-+	0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac,
-+	0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6038,
-+	0xa005, 0x1150, 0x681c, 0xa084, 0x000e, 0x0904, 0x3e98, 0x080c,
-+	0x3eb3, 0x782b, 0x3008, 0x0010, 0x8001, 0x603a, 0x781b, 0x005f,
-+	0x0005, 0xd6e4, 0x0118, 0x781b, 0x006c, 0x0005, 0xa684, 0x0060,
-+	0x0904, 0x322e, 0xd6dc, 0x0904, 0x322e, 0xd6fc, 0x1108, 0x00a0,
-+	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084,
-+	0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-+	0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a,
-+	0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x52e3,
-+	0x080c, 0x55dc, 0x000e, 0x781b, 0x006b, 0x0005, 0xa006, 0x080c,
-+	0x56fb, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120,
-+	0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6,
-+	0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6,
-+	0x781b, 0x006b, 0x0005, 0x781b, 0x006b, 0x2200, 0xa115, 0x1118,
-+	0x080c, 0x55dc, 0x0005, 0x080c, 0x5622, 0x0005, 0x781b, 0x006c,
-+	0x0005, 0x781b, 0x005f, 0x0005, 0x080c, 0x297f, 0x0804, 0x32cc,
-+	0x00c6, 0x705c, 0x2060, 0x6920, 0xa18c, 0xecff, 0x6922, 0x6000,
-+	0xa084, 0xcfdf, 0x6002, 0x080c, 0x3d32, 0xa006, 0x2040, 0x2038,
-+	0x080c, 0x3de9, 0x0804, 0x32c0, 0x00c6, 0x705c, 0x2060, 0x2c48,
-+	0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, 0x11e8, 0x6920, 0xd1e4,
-+	0x1180, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006,
-+	0x2010, 0x080c, 0x3d35, 0x2029, 0x0000, 0x080c, 0x3de9, 0x0804,
-+	0x32c0, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, 0x6106,
-+	0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01c0, 0x6104, 0xa184,
-+	0x0010, 0x0548, 0x080c, 0x3faf, 0x080c, 0x3dc6, 0x88ff, 0x0518,
-+	0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
-+	0xd6d4, 0x1110, 0x0804, 0x4056, 0x0804, 0x3ccc, 0x6920, 0xd1cc,
-+	0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, 0xc0ec, 0x6002, 0x2039,
-+	0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x2029,
-+	0x0000, 0x080c, 0x3de9, 0xa286, 0x0001, 0x0158, 0x6104, 0xa184,
-+	0x0008, 0x01b0, 0x080c, 0x3faf, 0x080c, 0x3cd1, 0x88ff, 0x1980,
-+	0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, 0x6000,
-+	0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x3d35,
-+	0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x005f, 0x0005, 0x781b,
-+	0x006c, 0x0005, 0x0804, 0x3e92, 0x2808, 0x789b, 0x0090, 0x2019,
-+	0x0090, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x11b8, 0x2300,
-+	0xa102, 0xa086, 0x0001, 0x0904, 0x3238, 0x7ca8, 0xa4a4, 0x00ff,
-+	0xa480, 0x0002, 0xa300, 0x2018, 0xa102, 0x0a04, 0x324c, 0x0904,
-+	0x324c, 0x24a8, 0x7aa8, 0x1f04, 0x32ea, 0x0c18, 0xa284, 0x00f0,
-+	0xa082, 0x0020, 0x06a8, 0x2200, 0xa082, 0x0021, 0x1688, 0x7aa8,
-+	0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0, 0xa286, 0x0023, 0x0950,
-+	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
-+	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x78a0, 0x8001, 0x0904,
-+	0x32c0, 0x20a8, 0x7998, 0x789b, 0x0060, 0x78aa, 0x2011, 0x0090,
-+	0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, 0x7a98, 0x1f04, 0x3318,
-+	0xc695, 0x7e5a, 0xd6d4, 0x1110, 0x0804, 0x4056, 0x0804, 0x3ccc,
-+	0x8318, 0x2100, 0xa302, 0x0a04, 0x32d1, 0xa284, 0x0080, 0x1904,
-+	0x3e98, 0x78a0, 0xa005, 0x08d8, 0x0804, 0x3e98, 0x0804, 0x3e69,
-+	0x705c, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e,
-+	0x0001, 0x0110, 0x080c, 0x297f, 0x7aa8, 0xa294, 0x00ff, 0x784b,
-+	0x0008, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005, 0x1a04, 0x3e69,
-+	0x0002, 0x3e69, 0x3c48, 0x3e69, 0x3d77, 0x4218, 0xa282, 0x0000,
-+	0x1110, 0x080c, 0x297f, 0x080c, 0x3eaa, 0x782b, 0x3008, 0x781b,
-+	0x006c, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x297f, 0xd4fc,
-+	0x11d0, 0x7068, 0xa005, 0x0110, 0x080c, 0x297f, 0x6f14, 0x777a,
-+	0xa7bc, 0x8f00, 0x080c, 0x3fb3, 0x6008, 0xa085, 0x0021, 0x600a,
-+	0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x3ead, 0x706b, 0x0002,
-+	0x701b, 0x0009, 0x0010, 0x080c, 0x3eb6, 0x782b, 0x3008, 0x781b,
-+	0x006c, 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x297f, 0x2300,
-+	0x0002, 0x3394, 0x34a8, 0x34d4, 0xa286, 0x0003, 0x0110, 0x080c,
-+	0x297f, 0x2001, 0x0000, 0x7046, 0x68d0, 0xa005, 0x0110, 0x7003,
-+	0x0003, 0x68a0, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0x7000,
-+	0xa084, 0x000f, 0x0002, 0x29ee, 0x33b8, 0x33b5, 0x359e, 0x363b,
-+	0x29ee, 0x33b3, 0x33b3, 0x080c, 0x297f, 0x6008, 0xc0d4, 0x600a,
-+	0xd6e4, 0x1130, 0x080c, 0x52e3, 0x2009, 0x0000, 0x0804, 0x345a,
-+	0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008,
-+	0xc0a4, 0x600a, 0x080c, 0x3b90, 0x0540, 0x080c, 0x3bfa, 0x080c,
-+	0x52e3, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78,
-+	0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084,
-+	0x0904, 0x29ee, 0xc084, 0x6822, 0x080c, 0x2af4, 0x7060, 0x00c6,
-+	0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00,
-+	0x1108, 0x6002, 0x6006, 0x0804, 0x29ee, 0x0016, 0x81ff, 0x11d8,
-+	0x71f0, 0xd1bc, 0x11c0, 0xd1b4, 0x01b0, 0x080c, 0x40a8, 0x1198,
-+	0x00d6, 0x70d8, 0xa06d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x68b4,
-+	0x785a, 0x781b, 0x0057, 0x704c, 0xc08d, 0x780a, 0xc1b4, 0x71f2,
-+	0x7003, 0x0030, 0x00de, 0x080c, 0x34e7, 0x001e, 0x81ff, 0x0904,
-+	0x345a, 0xa684, 0x5f00, 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186,
-+	0x0002, 0x15c8, 0x080c, 0x2ae3, 0x080c, 0x2aff, 0x6820, 0xa084,
-+	0x0800, 0x1588, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213,
-+	0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0xb800, 0x0010, 0xa290,
-+	0xb900, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x1108, 0x0070, 0x6820,
-+	0xd0e4, 0x0128, 0xa084, 0xefff, 0x6822, 0xc3ac, 0x2312, 0x8210,
-+	0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138, 0x68a0,
-+	0xd0c4, 0x1120, 0x080c, 0x3555, 0x0804, 0x29ee, 0x6008, 0xc08d,
-+	0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044,
-+	0x681a, 0xa68c, 0x5f00, 0x691e, 0x6010, 0xa005, 0x0120, 0x8001,
-+	0x1310, 0x080c, 0x297f, 0x6012, 0x6018, 0xa005, 0x0118, 0x8001,
-+	0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x1130,
-+	0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x7060, 0x2060,
-+	0x6800, 0x6002, 0x2061, 0xb340, 0x6807, 0x0103, 0x2d08, 0x206b,
-+	0x0000, 0x605c, 0x8000, 0x605e, 0x6060, 0xa005, 0x6162, 0x0110,
-+	0x2d02, 0x0008, 0x6166, 0x7000, 0xa086, 0x0030, 0x1904, 0x29ee,
-+	0x7003, 0x0002, 0x70d8, 0xa06d, 0x68c0, 0x703e, 0x70d4, 0xa065,
-+	0x68c4, 0x705e, 0x2d00, 0x7052, 0xad80, 0x0009, 0x7042, 0x0005,
-+	0xa282, 0x0004, 0x0210, 0x080c, 0x297f, 0x2200, 0x0002, 0x34ab,
-+	0x34b3, 0x34be, 0x34b3, 0x7000, 0xa086, 0x0005, 0x0120, 0x080c,
-+	0x3eaa, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005, 0x7890, 0x8007,
-+	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
-+	0x00ff, 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804,
-+	0x3e69, 0x781b, 0x006c, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff,
-+	0x1118, 0x080c, 0x3eaa, 0x0030, 0x8211, 0x0110, 0x080c, 0x297f,
-+	0x080c, 0x3eb6, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005, 0xa684,
-+	0x0060, 0x1150, 0x2d00, 0xa005, 0x0904, 0x3554, 0x682f, 0x0000,
-+	0x6833, 0x0000, 0x0804, 0x3554, 0xd6dc, 0x1190, 0x68b4, 0xd0dc,
-+	0x1178, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005, 0x1128,
-+	0x2200, 0xa105, 0x0120, 0x7047, 0x0015, 0x0804, 0x52e3, 0x0005,
-+	0xd6ac, 0x0508, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000,
-+	0x0804, 0x52e3, 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4, 0x1da0,
-+	0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0xd6dc, 0x1130, 0x68b4,
-+	0xd0dc, 0x0118, 0x69a8, 0x6aa4, 0x0010, 0x79d8, 0x7adc, 0x692e,
-+	0x6a32, 0x0804, 0x52e3, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833,
-+	0x0000, 0x0804, 0x52e3, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4,
-+	0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0x79d8, 0x7adc,
-+	0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e,
-+	0x6a32, 0x2100, 0xa205, 0x1110, 0x0804, 0x52e3, 0x7000, 0xa086,
-+	0x0006, 0x0110, 0x0804, 0x52e3, 0x0005, 0x6008, 0xc0cd, 0xd3cc,
-+	0x0108, 0xc08d, 0x600a, 0x6818, 0x68ba, 0x681b, 0x0006, 0x688f,
-+	0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
-+	0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
-+	0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0002, 0x29ee,
-+	0x3587, 0x3581, 0x357f, 0x357f, 0x357f, 0x357f, 0x357f, 0x080c,
-+	0x297f, 0x6820, 0xd084, 0x1118, 0x080c, 0x3be8, 0x0030, 0x7060,
-+	0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, 0xb28c, 0x0600, 0x0118,
-+	0x2021, 0xb399, 0x0010, 0x2021, 0xb3d9, 0x2404, 0xa005, 0x0110,
-+	0x2020, 0x0cd8, 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, 0x3bee,
-+	0x080c, 0x3bfa, 0x6008, 0xc0cc, 0x600a, 0x789b, 0x000e, 0x6f14,
-+	0x6817, 0x0002, 0xb28c, 0x0600, 0x0118, 0x2009, 0x0000, 0x0010,
-+	0x2009, 0x0001, 0x080c, 0x5736, 0xd6dc, 0x01c8, 0x691c, 0xc1ed,
-+	0x691e, 0x6828, 0xa082, 0x000e, 0x0290, 0x6848, 0xa084, 0x000f,
-+	0xa086, 0x000b, 0x1160, 0x685c, 0xa086, 0x0047, 0x1140, 0x2001,
-+	0xb341, 0x2004, 0xd0ac, 0x1118, 0x2700, 0x080c, 0x28a8, 0x68b8,
-+	0xd0fc, 0x1110, 0x681a, 0x0060, 0x6818, 0xd0fc, 0x0148, 0x7868,
-+	0xa08c, 0x00ff, 0x0118, 0x681b, 0x001e, 0x0010, 0x681b, 0x0000,
-+	0xb284, 0x0600, 0x1118, 0x2021, 0xb3d9, 0x0010, 0x2021, 0xb399,
-+	0x2404, 0xad06, 0x0108, 0x7460, 0x6800, 0x2022, 0x68d3, 0x0000,
-+	0x70f4, 0xc084, 0x70f6, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c4,
-+	0x2060, 0x6000, 0xd0a4, 0x0580, 0x2041, 0x0021, 0x2049, 0x0005,
-+	0x2051, 0x0020, 0x00d6, 0x00f6, 0x0156, 0x0146, 0x2079, 0xb340,
-+	0x080c, 0x1cd8, 0x014e, 0x015e, 0x00fe, 0x70e8, 0x2010, 0x2009,
-+	0x0101, 0x0026, 0x2204, 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110,
-+	0x6800, 0x0cc8, 0x6820, 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109,
-+	0x1d80, 0x00de, 0x706b, 0x0003, 0x7083, 0x0000, 0x777a, 0x7087,
-+	0x000f, 0x71f0, 0xc1c4, 0x71f2, 0x6818, 0xa086, 0x0002, 0x1138,
-+	0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, 0x080c,
-+	0x2085, 0x0804, 0x29ee, 0x080c, 0x34e7, 0x682b, 0x0000, 0x789b,
-+	0x000e, 0x6f14, 0x080c, 0x40d9, 0xa08c, 0x00ff, 0x6916, 0x6818,
-+	0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0x5f00, 0x691e, 0x706b,
-+	0x0000, 0x0804, 0x29ee, 0x7000, 0xa005, 0x1110, 0x0804, 0x29ee,
-+	0xa006, 0x080c, 0x52e3, 0x6817, 0x0000, 0x6920, 0xd1ac, 0x1110,
-+	0x681b, 0x0014, 0xa68c, 0x5f00, 0x691e, 0x682b, 0x0000, 0x6820,
-+	0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, 0x29ee, 0x367a, 0x3677,
-+	0x367c, 0x367c, 0x367c, 0x3675, 0x3675, 0x080c, 0x297f, 0x6008,
-+	0xc0d4, 0x600a, 0x080c, 0x3bfa, 0x6008, 0xc0a4, 0x600a, 0x0804,
-+	0x3bb3, 0x2300, 0x0002, 0x3686, 0x3688, 0x36f1, 0x080c, 0x297f,
-+	0xd6fc, 0x1904, 0x36da, 0x7000, 0xa00d, 0x0002, 0x29ee, 0x369e,
-+	0x3698, 0x36c8, 0x369e, 0x36d1, 0x3696, 0x3696, 0x080c, 0x297f,
-+	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060,
-+	0x0538, 0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a,
-+	0x6eb6, 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, 0x080c,
-+	0x52e3, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x5622, 0x0010,
-+	0x080c, 0x55dc, 0x781b, 0x006c, 0x71f0, 0xd1b4, 0x1904, 0x29df,
-+	0x70c0, 0xa086, 0x0001, 0x1904, 0x2a3f, 0x0005, 0xd6ec, 0x09f0,
-+	0x6818, 0xd0fc, 0x0130, 0x681b, 0x0015, 0xd6f4, 0x0110, 0x681b,
-+	0x0007, 0x080c, 0x405b, 0x0005, 0x78cb, 0x0000, 0x781b, 0x00d8,
-+	0x0804, 0x29df, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x78d0, 0x79d2,
-+	0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100,
-+	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x006c,
-+	0x0005, 0x080c, 0x297f, 0x2300, 0x0002, 0x36f8, 0x36fa, 0x3752,
-+	0x080c, 0x297f, 0xd6fc, 0x1904, 0x3742, 0x7000, 0xa00d, 0x0002,
-+	0x29ee, 0x3710, 0x370a, 0x373a, 0x3710, 0x373f, 0x3708, 0x3708,
-+	0x080c, 0x297f, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
-+	0xa684, 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xa6b4, 0xbfbf,
-+	0xc6ed, 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0148, 0x080c, 0x52e3,
-+	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x5622, 0x0010, 0x080c,
-+	0x55dc, 0x781b, 0x006c, 0x681c, 0xc0b4, 0x681e, 0x71f0, 0xd1b4,
-+	0x1904, 0x29df, 0x70c0, 0xa086, 0x0001, 0x1904, 0x2a3f, 0x0005,
-+	0xd6ec, 0x09f0, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b,
-+	0x00dd, 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100,
-+	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b,
-+	0x006c, 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x006c,
-+	0x0804, 0x29df, 0x6820, 0xc095, 0x6822, 0x080c, 0x4042, 0xc6dd,
-+	0x080c, 0x3eaa, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005, 0x2300,
-+	0x0002, 0x376c, 0x376e, 0x3770, 0x080c, 0x297f, 0x0804, 0x3e98,
-+	0x7d98, 0xd6d4, 0x1904, 0x37bc, 0x79e4, 0xd1ac, 0x0130, 0x78ec,
-+	0xa084, 0x0003, 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab,
-+	0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120,
-+	0x78ec, 0xa084, 0x0003, 0x11b8, 0x2001, 0xb342, 0x2004, 0xd0e4,
-+	0x1170, 0x6820, 0xd0c4, 0x0158, 0x00c6, 0x705c, 0x2060, 0x6004,
-+	0xc09d, 0x6006, 0x6008, 0xa084, 0x00ff, 0x600a, 0x00ce, 0x2001,
-+	0x0014, 0x0804, 0x339b, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
-+	0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
-+	0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
-+	0x0010, 0x2001, 0x0001, 0x0492, 0x7a90, 0xa294, 0x0007, 0x789b,
-+	0x0060, 0x79a8, 0x81ff, 0x0538, 0x789b, 0x0090, 0x7ba8, 0xa384,
-+	0x0001, 0x11a0, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x1118, 0x2009,
-+	0xfff7, 0x0028, 0xa386, 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6,
-+	0x705c, 0x2060, 0x6004, 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060,
-+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920,
-+	0xa18c, 0xfcff, 0x6922, 0x7d9a, 0x0804, 0x404b, 0x3036, 0x303f,
-+	0x37f8, 0x37fe, 0x37f6, 0x37f6, 0x404b, 0x404b, 0x080c, 0x297f,
-+	0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x4053, 0x6920, 0xa18c,
-+	0xfcff, 0x6922, 0x0804, 0x404b, 0x79e4, 0xa184, 0x0030, 0x0120,
-+	0x78ec, 0xa084, 0x0003, 0x1548, 0x7000, 0xa086, 0x0004, 0x1190,
-+	0x7068, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000,
-+	0x0804, 0x2ec1, 0x7068, 0xa086, 0x0006, 0x0db0, 0x7068, 0xa086,
-+	0x0004, 0x0d90, 0x7000, 0xa086, 0x0000, 0x0904, 0x29df, 0x6820,
-+	0xd0ac, 0x1904, 0x339b, 0x6818, 0xa08e, 0x0002, 0x0120, 0xc0fd,
-+	0x681a, 0x2001, 0x0014, 0x0804, 0x339b, 0x7884, 0xd0fc, 0x1118,
-+	0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118,
-+	0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118,
-+	0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x404b, 0x404b,
-+	0x3856, 0x404b, 0x409e, 0x409e, 0x404b, 0x404b, 0xd6bc, 0x05d0,
-+	0x7188, 0x81ff, 0x05b8, 0xa182, 0x000d, 0x1318, 0x708b, 0x0000,
-+	0x0028, 0xa182, 0x000c, 0x708a, 0x2009, 0x000c, 0x789b, 0x0061,
-+	0x79aa, 0x0156, 0x0136, 0x0146, 0x708c, 0x8114, 0xa210, 0x728e,
-+	0xa080, 0x000b, 0xad00, 0x2098, 0x0016, 0xb28c, 0x0600, 0x0168,
-+	0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x20a1,
-+	0x012b, 0x0028, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x001e,
-+	0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e,
-+	0x0804, 0x4053, 0xd6d4, 0x1904, 0x38df, 0x6820, 0xd084, 0x0904,
-+	0x4053, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060,
-+	0x1108, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab,
-+	0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008,
-+	0x810c, 0x0904, 0x3c0f, 0xa18c, 0x00f8, 0x1904, 0x3c0f, 0x0156,
-+	0x0136, 0x0146, 0x0016, 0xb28c, 0x0600, 0x0168, 0x0006, 0x2001,
-+	0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x20a1, 0x012b, 0x0028,
-+	0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000,
-+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e,
-+	0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, 0x4053, 0x6818,
-+	0xd0fc, 0x0110, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822, 0x080c,
-+	0x3eb0, 0x78cb, 0x0000, 0x781b, 0x00d4, 0x0005, 0x2300, 0x0002,
-+	0x38f5, 0x397c, 0x38f3, 0x080c, 0x297f, 0x7000, 0xa084, 0x000f,
-+	0x0002, 0x29ee, 0x3939, 0x3903, 0x390a, 0x3901, 0x29ee, 0x3901,
-+	0x3901, 0x080c, 0x297f, 0x681c, 0xd0ec, 0x0198, 0x6008, 0xc08d,
-+	0x600a, 0x0078, 0x68d0, 0xa005, 0x1560, 0x6920, 0xa18d, 0x0001,
-+	0x6922, 0x68d3, 0x0001, 0x70f4, 0xc085, 0x70f6, 0x6800, 0x7066,
-+	0x0078, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108,
-+	0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1140,
-+	0x2009, 0xfc10, 0xb284, 0x0600, 0x0140, 0x2009, 0xfb00, 0x0028,
-+	0x702c, 0x68be, 0x713c, 0x70e8, 0xa108, 0x2104, 0x6802, 0x2d0a,
-+	0x7162, 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff, 0x68b6,
-+	0x04c8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6,
-+	0x6898, 0x68aa, 0x080c, 0x52e3, 0x0468, 0xd6ac, 0x0168, 0x68d0,
-+	0xa005, 0x0118, 0x080c, 0x5736, 0x0010, 0x080c, 0x52e3, 0x79d8,
-+	0x7adc, 0x69aa, 0x6aa6, 0x0030, 0x080c, 0x3fc5, 0x69aa, 0x6aa6,
-+	0x080c, 0x52e3, 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, 0x7adc,
-+	0x79d8, 0xd6ac, 0x1138, 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108,
-+	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-+	0xa303, 0x68ae, 0x0804, 0x29ee, 0x0804, 0x3e98, 0x7043, 0x0000,
-+	0xa282, 0x0006, 0x0310, 0x080c, 0x297f, 0x7000, 0xa086, 0x0007,
-+	0x090c, 0x41a1, 0x2300, 0x0002, 0x398f, 0x39c1, 0x39de, 0x2200,
-+	0x0002, 0x39bf, 0x3e98, 0x3997, 0x39bf, 0x39fe, 0x3a65, 0x7003,
-+	0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0xfe60, 0x0010, 0x2001,
-+	0xfe97, 0x2068, 0x7052, 0x0156, 0x20a9, 0x0037, 0x2003, 0x0000,
-+	0x8000, 0x1f04, 0x39a6, 0x015e, 0xad80, 0x0009, 0x7042, 0xb284,
-+	0x0600, 0x0118, 0x6817, 0x0000, 0x0010, 0x6817, 0x8000, 0x68b7,
-+	0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0804, 0x3e69, 0x080c,
-+	0x297f, 0x2200, 0xa086, 0x0003, 0x05c8, 0x7003, 0x0005, 0xb284,
-+	0x0600, 0x0118, 0x2001, 0xfe60, 0x0010, 0x2001, 0xfe97, 0x2068,
-+	0x7052, 0xad80, 0x0009, 0x7042, 0x2200, 0x0002, 0x3e98, 0x39dc,
-+	0x39dc, 0x39fe, 0x39dc, 0x3e98, 0x080c, 0x297f, 0x7003, 0x0005,
-+	0xb284, 0x0600, 0x0118, 0x2001, 0xfe60, 0x0010, 0x2001, 0xfe97,
-+	0x2068, 0x7052, 0xad80, 0x0009, 0x7042, 0x2200, 0x0002, 0x39f7,
-+	0x39f5, 0x39f5, 0x39f7, 0x39f5, 0x39f7, 0x080c, 0x297f, 0x080c,
-+	0x3eb6, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005, 0x7000, 0xa086,
-+	0x0002, 0x1158, 0x70f0, 0xc0b5, 0x70f2, 0x2c00, 0x70d6, 0x2d00,
-+	0x70da, 0x0038, 0x080c, 0x52e3, 0x0020, 0x7000, 0xa086, 0x0003,
-+	0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-+	0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0xfb00, 0xb284, 0x0600,
-+	0x1118, 0xc2fd, 0x2069, 0xfc10, 0x2d04, 0x2d08, 0x7162, 0xa06d,
-+	0x0128, 0x6814, 0xa206, 0x0500, 0x6800, 0x0cb8, 0x7003, 0x0005,
-+	0xd2fc, 0x1118, 0x2001, 0xfe60, 0x0010, 0x2001, 0xfe97, 0x2068,
-+	0x7052, 0x0156, 0x20a9, 0x0037, 0x2003, 0x0000, 0x8000, 0x1f04,
-+	0x3a3c, 0x015e, 0xad80, 0x0009, 0x7042, 0x6a16, 0x68b7, 0x0700,
-+	0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6920, 0xa184,
-+	0x0c00, 0x0904, 0x3adc, 0x7068, 0xa086, 0x0006, 0x1128, 0x7078,
-+	0xa206, 0x1110, 0x706a, 0x7082, 0x681b, 0x0005, 0xc1ad, 0xc1d4,
-+	0x6922, 0x080c, 0x3eb0, 0x0804, 0x3adc, 0x7200, 0xa286, 0x0002,
-+	0x1158, 0x70f0, 0xc0b5, 0x70f2, 0x2c00, 0x70d6, 0x2d00, 0x70da,
-+	0x0030, 0x080c, 0x52e3, 0x0018, 0xa286, 0x0003, 0x0dd0, 0x7003,
-+	0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484,
-+	0x001f, 0xa215, 0xb284, 0x0600, 0x1108, 0xc2fd, 0x79a8, 0x79a8,
-+	0xa18c, 0x00ff, 0x2118, 0x70e8, 0xa168, 0x2d04, 0x2d08, 0x7162,
-+	0xa06d, 0x0128, 0x6814, 0xa206, 0x0538, 0x6800, 0x0cb8, 0x7003,
-+	0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0xfe60, 0x0010, 0x2001,
-+	0xfe97, 0x2068, 0x7052, 0x0156, 0x20a9, 0x0037, 0x2003, 0x0000,
-+	0x8000, 0x1f04, 0x3aa6, 0x015e, 0xad80, 0x0009, 0x7042, 0xb284,
-+	0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0x68b7, 0x0700,
-+	0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00,
-+	0x01d8, 0xd0dc, 0x0178, 0x7068, 0xa086, 0x0004, 0x1140, 0x7078,
-+	0xa206, 0x1128, 0x707c, 0xa306, 0x1110, 0x706a, 0x7082, 0x080c,
-+	0x3eb3, 0x0050, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c,
-+	0x3eb0, 0x7083, 0x0000, 0x0000, 0x68c4, 0x705e, 0xc6ec, 0xa684,
-+	0x0060, 0x05d0, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11d0,
-+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa684, 0x0060, 0xa086, 0x0060,
-+	0x0580, 0x68d0, 0xa005, 0x0140, 0x7003, 0x0003, 0x682b, 0x0000,
-+	0xc6ed, 0x080c, 0x55ca, 0x0428, 0xd6f4, 0x1518, 0xc6ed, 0x080c,
-+	0x55dc, 0x00f8, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305,
-+	0x01d0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68d0, 0xa005, 0x0128,
-+	0x7003, 0x0003, 0x080c, 0x55ca, 0x0070, 0xd6f4, 0x1120, 0xc6ed,
-+	0x68b0, 0x080c, 0x5622, 0xc6f4, 0x2019, 0x0000, 0x2021, 0x0000,
-+	0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x006c, 0xa684, 0x0004,
-+	0x01b0, 0x78e4, 0xa084, 0x0030, 0x0150, 0x78ec, 0xa084, 0x0003,
-+	0x0130, 0x782b, 0x3008, 0x2019, 0x0000, 0x2320, 0x0040, 0x00f6,
-+	0x2079, 0xb340, 0x080c, 0x52e3, 0x00fe, 0x0904, 0x29ee, 0x791a,
-+	0x2d00, 0x7052, 0x68c8, 0x2060, 0x71f0, 0x2001, 0xb341, 0x2004,
-+	0xd0c4, 0x15c8, 0x70f8, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80,
-+	0xa294, 0x0f00, 0x70fc, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558,
-+	0x70fa, 0xc1bc, 0x71f2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218,
-+	0x8633, 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130,
-+	0x2011, 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217,
-+	0x7880, 0xa084, 0x0f00, 0xa206, 0x0170, 0x72fe, 0x76fa, 0x0058,
-+	0x7a80, 0xa294, 0x0f00, 0x70fc, 0xa236, 0x0dc0, 0x78e0, 0xa534,
-+	0x0da8, 0xc1bd, 0x71f2, 0xd1b4, 0x1904, 0x29df, 0x2300, 0xa405,
-+	0x0904, 0x29df, 0x70c0, 0xa086, 0x0001, 0x1904, 0x2a3f, 0x0005,
-+	0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008,
-+	0x600a, 0x700b, 0x0100, 0x7028, 0x6026, 0x0005, 0xa006, 0x080c,
-+	0x52e3, 0x7000, 0xa086, 0x0002, 0x0120, 0x7068, 0xa086, 0x0005,
-+	0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823,
-+	0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x29ee,
-+	0x3bc4, 0x3bc1, 0x3be4, 0x3bcd, 0x3bcb, 0x3bbf, 0x3bbf, 0x080c,
-+	0x297f, 0x0461, 0x0429, 0x0028, 0x0449, 0x7060, 0x2060, 0x6800,
-+	0x6002, 0x080c, 0x2085, 0x0804, 0x29ee, 0x7068, 0x706b, 0x0000,
-+	0x7087, 0x0000, 0x0002, 0x3be0, 0x3be0, 0x3bdb, 0x3bdb, 0x3bdb,
-+	0x3be0, 0x3bdb, 0x3be0, 0x77f0, 0xc7c5, 0x77f2, 0x0804, 0x2ed6,
-+	0x706b, 0x0000, 0x0804, 0x29ee, 0x681b, 0x0000, 0x0804, 0x359e,
-+	0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0005, 0x6010, 0xa005,
-+	0x0120, 0x8001, 0x1310, 0x080c, 0x297f, 0x6012, 0x6008, 0xc0a4,
-+	0x600a, 0x0005, 0x6018, 0xa005, 0x0110, 0x8001, 0x601a, 0x0005,
-+	0x080c, 0x40d4, 0x681b, 0x0018, 0x0480, 0x080c, 0x40d4, 0x681b,
-+	0x0019, 0x0458, 0x080c, 0x40d4, 0x681b, 0x001a, 0x0430, 0x080c,
-+	0x40d4, 0x681b, 0x0003, 0x0408, 0x7778, 0x080c, 0x3fb3, 0x717c,
-+	0xa18c, 0x00ff, 0xd7fc, 0x1118, 0xa1e8, 0xfa00, 0x0010, 0xa1e8,
-+	0xfb10, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x1118, 0x7082, 0x0804,
-+	0x29ee, 0x6814, 0x7278, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800,
-+	0x200a, 0x681b, 0x0005, 0x7083, 0x0000, 0x080c, 0x3bee, 0x6820,
-+	0xd084, 0x1110, 0x080c, 0x3be8, 0x080c, 0x3bfa, 0x681f, 0x0000,
-+	0x6823, 0x0020, 0x682b, 0x0000, 0x080c, 0x2085, 0x0804, 0x29ee,
-+	0xa282, 0x0003, 0x1904, 0x3e70, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8,
-+	0xa6b4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x05a0, 0xc1c4,
-+	0x6922, 0xa6b4, 0x00ff, 0x0520, 0xa682, 0x001c, 0x0218, 0x0110,
-+	0x2031, 0x001c, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b,
-+	0x2041, 0x0000, 0x080c, 0x3f0c, 0x0118, 0x080c, 0x3d35, 0x0090,
-+	0x080c, 0x3ef8, 0x080c, 0x3d32, 0x6920, 0xc1c5, 0x6922, 0x7e58,
-+	0xc695, 0x7e5a, 0xd6d4, 0x1110, 0x0804, 0x4056, 0x0804, 0x3ccc,
-+	0x080c, 0x3d32, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x005f, 0x0005,
-+	0x781b, 0x006c, 0x0005, 0x00c6, 0x705c, 0x2060, 0x6100, 0xd1e4,
-+	0x0598, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x001c, 0x0218,
-+	0x0110, 0x2011, 0x001c, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686,
-+	0x0010, 0x1108, 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4,
-+	0x0130, 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282,
-+	0x000c, 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228,
-+	0x080c, 0x3efc, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3f0c,
-+	0x0118, 0x080c, 0x3d35, 0x0020, 0x080c, 0x3ef8, 0x080c, 0x3d32,
-+	0x7858, 0xc095, 0x785a, 0x00ce, 0x782b, 0x3008, 0x781b, 0x006c,
-+	0x0005, 0x00c6, 0x2960, 0x6000, 0xd0e4, 0x1170, 0xa084, 0x0040,
-+	0x1130, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011,
-+	0x0032, 0x2019, 0x0000, 0x0418, 0x68a0, 0xd0cc, 0x1dc0, 0x6208,
-+	0xa294, 0x00ff, 0x2001, 0xb343, 0x2004, 0xd0e4, 0x1148, 0x78ec,
-+	0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, 0x000a, 0x0028,
-+	0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c,
-+	0x00ff, 0xa382, 0x001c, 0x0218, 0x0110, 0x2019, 0x001c, 0x78ab,
-+	0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0,
-+	0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x2ae3, 0x00ce, 0x0005,
-+	0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032,
-+	0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822,
-+	0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, 0x715c, 0x2160,
-+	0x0029, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x2018, 0x2008,
-+	0xa084, 0xffe0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612,
-+	0x78a4, 0xa084, 0x7770, 0xa18c, 0x000f, 0xa105, 0x0056, 0x2029,
-+	0xb343, 0x252c, 0xd5cc, 0x005e, 0x0140, 0xd3a4, 0x0110, 0xa085,
-+	0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, 0x0006, 0x78ec,
-+	0xd08c, 0x0130, 0x6028, 0xd08c, 0x0118, 0x000e, 0xc0bc, 0x0008,
-+	0x000e, 0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004,
-+	0xa605, 0x600e, 0x6004, 0xa084, 0xffd5, 0x6006, 0x0005, 0xa282,
-+	0x0002, 0x1904, 0x3e7a, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc,
-+	0x0558, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04,
-+	0x3e69, 0x080c, 0x3deb, 0x080c, 0x3d32, 0xa980, 0x0001, 0x200c,
-+	0x080c, 0x3faf, 0x080c, 0x3cd1, 0x88ff, 0x0168, 0x789b, 0x0060,
-+	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1110, 0x0804,
-+	0x4056, 0x0804, 0x3ccc, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x005f,
-+	0x0005, 0x781b, 0x006c, 0x0005, 0xa282, 0x0002, 0x1218, 0xa284,
-+	0x0001, 0x0138, 0x715c, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x1108,
-+	0xa016, 0x080c, 0x3ee9, 0x0479, 0x080c, 0x3d32, 0x7858, 0xc095,
-+	0x785a, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005, 0x00c6, 0x0026,
-+	0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1148, 0xa084, 0x0080,
-+	0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, 0x78ab,
-+	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004,
-+	0x080c, 0x2ae3, 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, 0x00ce,
-+	0x0005, 0x8807, 0xa715, 0x00c6, 0x705c, 0x2060, 0x0011, 0x00ce,
-+	0x0005, 0x2009, 0x0000, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018,
-+	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec,
-+	0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020,
-+	0x78a6, 0x0006, 0x6000, 0xd09c, 0x0140, 0x6028, 0xd08c, 0x0128,
-+	0x000e, 0xd0bc, 0x0118, 0xc0bc, 0x0008, 0x000e, 0xe016, 0x788a,
-+	0x6004, 0xa084, 0xffef, 0x6006, 0x0005, 0x0006, 0x7000, 0xa086,
-+	0x0003, 0x0110, 0x000e, 0x0010, 0x000e, 0x0488, 0xd6ac, 0x0578,
-+	0x7888, 0xa084, 0x0040, 0x0558, 0x7bb8, 0x8307, 0xa084, 0x007f,
-+	0x1508, 0x8207, 0xa084, 0x00ff, 0xa09e, 0x0001, 0x1904, 0x3e92,
-+	0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, 0x0000, 0x79d2,
-+	0x79da, 0x7ad6, 0x7ade, 0x080c, 0x56fb, 0x781b, 0x006b, 0xb284,
-+	0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, 0x080c,
-+	0x555b, 0x0005, 0x080c, 0x297f, 0x781b, 0x006b, 0x0005, 0x781b,
-+	0x006c, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000,
-+	0xa006, 0x2010, 0x080c, 0x3d35, 0x2029, 0x0000, 0x080c, 0x3de9,
-+	0x7e58, 0x080c, 0x3eb9, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005,
-+	0x0cc1, 0x6820, 0xc0c4, 0x6822, 0x00c6, 0x705c, 0x2060, 0x080c,
-+	0x3d72, 0x00b0, 0x0c71, 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x705c,
-+	0x2060, 0x080c, 0x3e18, 0x0060, 0x0c21, 0x6820, 0xa084, 0xecff,
-+	0x6822, 0x00c6, 0x705c, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006,
-+	0x00ce, 0x0005, 0x00b9, 0x782b, 0x3008, 0x781b, 0x006c, 0x0005,
-+	0x6827, 0x0002, 0x00a9, 0x78e4, 0xa084, 0x0030, 0x0904, 0x29ee,
-+	0x78ec, 0xa084, 0x0003, 0x0904, 0x29ee, 0x782b, 0x3008, 0x781b,
-+	0x006c, 0x0005, 0x2001, 0x0005, 0x0070, 0x2001, 0x000c, 0x0058,
-+	0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028, 0x2001, 0x0009,
-+	0x0010, 0x2001, 0x0007, 0x789b, 0x0090, 0x78aa, 0x789b, 0x0060,
-+	0x78ab, 0x0001, 0xc695, 0x7e5a, 0x0804, 0x2ae3, 0x0076, 0x873f,
-+	0xa7bc, 0x000f, 0x873b, 0x873b, 0x873b, 0x8703, 0xb28c, 0x0600,
-+	0x0118, 0xa0e0, 0xb800, 0x0010, 0xa0e0, 0xb900, 0xa7b8, 0x0020,
-+	0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184,
-+	0x773f, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e,
-+	0x0005, 0x789b, 0x0090, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-+	0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, 0x0804, 0x2ae3,
-+	0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0090, 0x78ab, 0x0001,
-+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0060,
-+	0x78ab, 0x0005, 0x0804, 0x2ae3, 0x0156, 0x0804, 0x3f4e, 0x2021,
-+	0x3fa6, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582, 0x0028, 0x0550,
-+	0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033, 0x0618, 0x8420,
-+	0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200, 0xa502, 0x02d0,
-+	0x8420, 0x2300, 0xa210, 0x1f04, 0x3f25, 0x015e, 0x0088, 0x2021,
-+	0x3f98, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0033, 0x2200,
-+	0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3f37, 0x015e,
-+	0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064, 0x1220, 0x7808,
-+	0xa085, 0x0070, 0x780a, 0x2405, 0xa005, 0x0005, 0xa886, 0x0002,
-+	0x01e8, 0x2021, 0x3f84, 0x20a9, 0x000d, 0x2011, 0x0028, 0xa582,
-+	0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x2200,
-+	0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3f5f, 0x015e,
-+	0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890, 0x2021, 0x3f93,
-+	0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024, 0x0960, 0x8420,
-+	0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420, 0x2019, 0x0019,
-+	0x2011, 0x0033, 0x0804, 0x3f37, 0x1021, 0x2202, 0x3403, 0x4604,
-+	0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812, 0x5a12, 0x6a14,
-+	0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204, 0xe210, 0xe210,
-+	0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605,
-+	0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a,
-+	0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b,
-+	0x0090, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
-+	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc, 0x0118, 0xa0e0,
-+	0xda00, 0x0010, 0xa0e0, 0xba00, 0x0005, 0x79d8, 0x7adc, 0x78d0,
-+	0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x0005, 0x00e6,
-+	0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0xb3c0, 0x2071,
-+	0xb3c0, 0x0070, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x0118, 0x2079,
-+	0x0100, 0x0010, 0x2079, 0x0200, 0x2009, 0xb380, 0x2071, 0xb380,
-+	0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x3ff8, 0x3ff8,
-+	0x3ff8, 0x3ff8, 0x3ff8, 0x3ff8, 0x3ff6, 0x403d, 0x080c, 0x297f,
-+	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x05d8, 0x7858,
-+	0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814,
-+	0x1588, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b,
-+	0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, 0xd0bc, 0x1510,
-+	0x3200, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118,
-+	0xa084, 0x0600, 0x0010, 0xa084, 0x0800, 0x0118, 0x0104, 0x403a,
-+	0x0010, 0x0304, 0x403a, 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec,
-+	0xa084, 0x0003, 0x0138, 0x681c, 0xd0ac, 0x1110, 0x0421, 0x0010,
-+	0x781b, 0x00dd, 0x00fe, 0x00ee, 0x0005, 0x70a7, 0x0000, 0x080c,
-+	0x4397, 0x0cc0, 0x2001, 0xb341, 0x2004, 0xd0ac, 0x1118, 0x6814,
-+	0x080c, 0x28a8, 0x0005, 0x781b, 0x006c, 0x0005, 0x782b, 0x3008,
-+	0x781b, 0x006c, 0x0005, 0x781b, 0x005f, 0x0005, 0x782b, 0x3008,
-+	0x781b, 0x005d, 0x0005, 0x2009, 0xb356, 0x210c, 0xa186, 0x0000,
-+	0x0150, 0xa186, 0x0001, 0x0160, 0x701b, 0x000b, 0x706b, 0x0001,
-+	0x781b, 0x0050, 0x0005, 0x78cb, 0x0000, 0x781b, 0x00d8, 0x0005,
-+	0x701b, 0x000a, 0x0005, 0x2009, 0xb356, 0x210c, 0xa186, 0x0000,
-+	0x0170, 0xa186, 0x0001, 0x0140, 0x701b, 0x000b, 0x706b, 0x0001,
-+	0x781b, 0x0050, 0x0804, 0x29df, 0x701b, 0x000a, 0x0005, 0x782b,
-+	0x3008, 0x78cb, 0x0000, 0x781b, 0x00d8, 0x0005, 0x781b, 0x00dd,
-+	0x0005, 0x782b, 0x3008, 0x781b, 0x00dd, 0x0005, 0x781b, 0x00a4,
-+	0x0005, 0x782b, 0x3008, 0x781b, 0x00a4, 0x0005, 0x6818, 0xd0fc,
-+	0x0110, 0x681b, 0x001d, 0x706b, 0x0001, 0x781b, 0x0050, 0x0005,
-+	0x7830, 0xa084, 0x00c0, 0x1180, 0x7808, 0xa084, 0xfffc, 0x780a,
-+	0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x1108,
-+	0x0005, 0x704c, 0xc08d, 0x780a, 0x0005, 0x7830, 0xa084, 0x0080,
-+	0x1190, 0x78ec, 0xa084, 0x0002, 0x1170, 0x7808, 0xc08c, 0x780a,
-+	0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084, 0x0002, 0x0118,
-+	0x7808, 0xc08d, 0x780a, 0x0005, 0x704c, 0xc08d, 0x704e, 0x780a,
-+	0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0x3200, 0x0006, 0x2001,
-+	0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0xa084, 0x0600, 0x0010,
-+	0xa084, 0x0800, 0x0118, 0x1104, 0x40f2, 0x0010, 0x1304, 0x40f2,
-+	0x78ac, 0x0005, 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000,
-+	0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x0198, 0x3200, 0x0006,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0xa084, 0x0600,
-+	0x0010, 0xa084, 0x0800, 0x0118, 0x1104, 0x410c, 0x0010, 0x1304,
-+	0x410f, 0x78ac, 0x0006, 0x704c, 0x780a, 0x000e, 0x0005, 0x78ec,
-+	0xa084, 0x0002, 0x1904, 0x52a1, 0xa784, 0x007d, 0x1118, 0x2700,
-+	0x080c, 0x297f, 0xa784, 0x0001, 0x1904, 0x3653, 0xa784, 0x0070,
-+	0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2899, 0x2d78, 0x2c68,
-+	0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008, 0x78ec, 0xa084,
-+	0x0003, 0x0904, 0x3653, 0x0804, 0x404b, 0xa784, 0x0004, 0x0538,
-+	0x78b8, 0xa084, 0x8000, 0x0518, 0x784b, 0x0008, 0x78ec, 0xa084,
-+	0x0003, 0x0904, 0x3653, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001,
-+	0x11b0, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00dd,
-+	0x0005, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0130, 0x681b, 0x0015,
-+	0xd6f4, 0x0110, 0x681b, 0x0007, 0x080c, 0x405b, 0x0005, 0x681b,
-+	0x0003, 0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833,
-+	0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3006,
-+	0x3200, 0x0006, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118,
-+	0xa084, 0x0600, 0x0010, 0xa084, 0x0800, 0x0118, 0x0104, 0x29df,
-+	0x0010, 0x0304, 0x29df, 0x0804, 0x3e92, 0x6b14, 0x8307, 0xa084,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
-+	0xb900, 0x0010, 0xa080, 0xb800, 0x2060, 0x2048, 0x705e, 0x2a60,
-+	0x0005, 0x7000, 0x0002, 0x41ab, 0x41ab, 0x41ac, 0x41b4, 0x41ab,
-+	0x41ab, 0x41ab, 0x41b7, 0x0005, 0x6008, 0xa084, 0xfbef, 0x600a,
-+	0x6018, 0x8001, 0x601a, 0x0005, 0x080c, 0x52e3, 0x0005, 0x7094,
-+	0xa005, 0x01a8, 0x2068, 0xb284, 0x0600, 0x0118, 0x2009, 0x0000,
-+	0x0010, 0x2009, 0x0001, 0x0016, 0x080c, 0x1eb2, 0x001e, 0x0016,
-+	0x080c, 0x5222, 0x001e, 0x080c, 0x5223, 0x7097, 0x0000, 0x0005,
-+	0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x4216, 0xd1ac, 0x05e0,
-+	0x6108, 0x8117, 0xa18c, 0x00ff, 0x631c, 0x832f, 0x68a0, 0xd0cc,
-+	0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110, 0x8213,
-+	0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec, 0xd0e4,
-+	0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248, 0x2009,
-+	0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029, 0x0000,
-+	0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa, 0x78ab,
-+	0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820, 0xa085,
-+	0x1000, 0x6822, 0x080c, 0x2ae3, 0xa085, 0x0001, 0x00ce, 0x0005,
-+	0xa282, 0x0006, 0x1904, 0x3e84, 0x7da8, 0x7eac, 0x8637, 0xa5ac,
-+	0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff, 0xa8c4,
-+	0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x4286, 0xa18c,
-+	0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x3e5a, 0xa6b4, 0x00ff,
-+	0x0904, 0x4283, 0xa682, 0x0039, 0x1a04, 0x3e5a, 0xa582, 0x0009,
-+	0x0a04, 0x3e5a, 0xa882, 0x0003, 0x1a04, 0x3e5a, 0xa886, 0x0002,
-+	0x01d0, 0xa886, 0x0000, 0x1904, 0x3e5a, 0x2001, 0x000c, 0x79ec,
-+	0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c, 0x3e5a,
-+	0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000, 0xc0ac,
-+	0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x3e5a, 0x8634,
-+	0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c, 0x3f0c,
-+	0x0904, 0x3e5a, 0x2029, 0x0000, 0x080c, 0x3d35, 0x2029, 0x0000,
-+	0x080c, 0x3de9, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x005f, 0x0005,
-+	0x781b, 0x006c, 0x0005, 0x080c, 0x3d32, 0x0c80, 0xa886, 0x0002,
-+	0x1108, 0x8634, 0x715c, 0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904,
-+	0x3e5a, 0xd1ec, 0x1120, 0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4,
-+	0x1118, 0xa036, 0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c,
-+	0xa284, 0x00ff, 0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190,
-+	0x6108, 0x811f, 0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330,
-+	0x8807, 0xa705, 0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168,
-+	0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010,
-+	0x0070, 0xa284, 0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502,
-+	0x0108, 0x2128, 0x852b, 0x852b, 0x080c, 0x3f0c, 0x0d58, 0x080c,
-+	0x3d35, 0x2029, 0x0000, 0x080c, 0x3de9, 0x789b, 0x0090, 0x78ab,
-+	0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x78ab, 0x0000, 0x7daa,
-+	0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b, 0x0060, 0x78ab, 0x0005,
-+	0x080c, 0x2ae3, 0x7858, 0xc095, 0x785a, 0x0804, 0x1e66, 0x00e6,
-+	0x2091, 0x8000, 0x6014, 0xd0fc, 0x1118, 0x2071, 0xb380, 0x0010,
-+	0x2071, 0xb3c0, 0x7000, 0xa086, 0x0007, 0x1150, 0x6110, 0x70b0,
-+	0xa106, 0x1130, 0x00ee, 0x080c, 0x1ec4, 0x0041, 0xa006, 0x0005,
-+	0x2091, 0x8001, 0x00ee, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6,
-+	0x0804, 0x265a, 0x785b, 0x0000, 0x70a3, 0x000e, 0x2009, 0x0100,
-+	0x0016, 0x7094, 0xa06d, 0x0118, 0x7097, 0x0000, 0x0028, 0x70a7,
-+	0x0000, 0x080c, 0x1ef1, 0x0128, 0x70a0, 0x6826, 0x080c, 0x4432,
-+	0x0cb0, 0x001e, 0x0076, 0x0156, 0x00c6, 0x00d6, 0x20a9, 0x0020,
-+	0x3238, 0xa7bc, 0x0600, 0x0120, 0x2061, 0xfc20, 0xc7fc, 0x0018,
-+	0x2061, 0xfd40, 0xc7fd, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d,
-+	0x0140, 0x6800, 0x601e, 0x080c, 0x1ca6, 0x6008, 0x8000, 0x600a,
-+	0x0ca8, 0x6018, 0xa06d, 0x0128, 0x6800, 0x601a, 0x080c, 0x1ca6,
-+	0x0cc0, 0xace0, 0x0009, 0x0f04, 0x4356, 0x0c28, 0x7090, 0xa084,
-+	0x8000, 0x0110, 0x080c, 0x44ac, 0x00de, 0x00ce, 0x015e, 0x007e,
-+	0x0005, 0x6804, 0xa084, 0x000f, 0x0002, 0x4375, 0x4375, 0x4375,
-+	0x4375, 0x4375, 0x4375, 0x4377, 0x4386, 0x4375, 0x4375, 0x4375,
-+	0x4375, 0x4375, 0x4392, 0x4375, 0x4377, 0x080c, 0x297f, 0x0006,
-+	0x7830, 0xd0b4, 0x0128, 0x784b, 0x0004, 0x7848, 0xd094, 0x1de8,
-+	0x000e, 0x080c, 0x4f11, 0x080c, 0x1ca6, 0x0080, 0x6827, 0x000b,
-+	0x0006, 0x7830, 0xd0b4, 0x0128, 0x784b, 0x0004, 0x7848, 0xd094,
-+	0x1de8, 0x000e, 0x080c, 0x4f11, 0x080c, 0x4432, 0x0005, 0x00f6,
-+	0x6814, 0xd0fc, 0x1178, 0x2001, 0xb342, 0x2004, 0xd0ec, 0x0128,
-+	0x2079, 0x0100, 0x1104, 0x43c8, 0x0048, 0x2079, 0x0200, 0x1304,
-+	0x43c8, 0x0020, 0x2079, 0x0100, 0x1104, 0x43c8, 0x7830, 0xa084,
-+	0x00c0, 0x11b0, 0x00d6, 0x080c, 0x522f, 0x2d00, 0x682e, 0x2009,
-+	0x0004, 0x2001, 0x0000, 0x6827, 0x0084, 0x080c, 0x51da, 0x080c,
-+	0x4432, 0x00de, 0x70a8, 0xa080, 0x00bf, 0x781a, 0x0804, 0x4408,
-+	0x7948, 0x6814, 0xd0fc, 0x1158, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x0118, 0x1104, 0x43db, 0x0028, 0x1304, 0x43db, 0x0010, 0x1104,
-+	0x43db, 0x794a, 0x08b8, 0x7948, 0x7828, 0x0006, 0xa084, 0xf000,
-+	0xa086, 0x1000, 0x000e, 0x1da8, 0xd0b4, 0x1d98, 0xd0ac, 0x0118,
-+	0xa185, 0x0004, 0x0010, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e,
-+	0x78ab, 0x0002, 0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a,
-+	0x70a8, 0xa080, 0x00a1, 0x781a, 0x6827, 0x0284, 0x682c, 0x6836,
-+	0x6830, 0x683a, 0x2009, 0x0004, 0x2001, 0x0000, 0x080c, 0x51da,
-+	0x00fe, 0x0005, 0x00d6, 0x6b14, 0x080c, 0x1f5a, 0x0128, 0x2068,
-+	0x6827, 0x0002, 0x00f9, 0x0cc0, 0x00de, 0x0005, 0x00d6, 0x6b14,
-+	0x6c28, 0xa4a4, 0x00ff, 0x080c, 0x1efb, 0x0120, 0x2068, 0x6827,
-+	0x0002, 0x0081, 0x00de, 0x0005, 0x00d6, 0x6814, 0xa09c, 0x00ff,
-+	0x080c, 0x1f2c, 0x0128, 0x2068, 0x6827, 0x0002, 0x0019, 0x0cc0,
-+	0x00de, 0x0005, 0x00c6, 0x6914, 0x6814, 0x080c, 0x449c, 0x6904,
-+	0xa18c, 0x00ff, 0xa186, 0x0006, 0x0170, 0xa186, 0x000d, 0x0550,
-+	0xa186, 0x0017, 0x1120, 0x080c, 0x1ca6, 0x00ce, 0x0005, 0x080c,
-+	0x2087, 0x00ce, 0x0005, 0x6004, 0x8001, 0x02b0, 0x6006, 0x2009,
-+	0x0000, 0xa684, 0x0001, 0x1110, 0xa18d, 0x8000, 0xa684, 0x0004,
-+	0x0110, 0xa18d, 0x0002, 0x691e, 0x6823, 0x0000, 0x711c, 0x810f,
-+	0x6818, 0xa105, 0x681a, 0x0c18, 0x6100, 0xa184, 0x0001, 0x09d8,
-+	0x080c, 0x297f, 0x6018, 0xa005, 0x1148, 0x6008, 0x8001, 0x0230,
-+	0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x00a0, 0xac88, 0x0006,
-+	0x2104, 0xa005, 0x0110, 0x2008, 0x0cd8, 0x6802, 0x2d0a, 0x6008,
-+	0x8001, 0x0230, 0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0c48,
-+	0x00ce, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6, 0x00d6, 0x080c,
-+	0x1c85, 0x2da0, 0x013e, 0x20a9, 0x0037, 0x53a3, 0x00ce, 0x014e,
-+	0x013e, 0x015e, 0x0804, 0x4447, 0xd0fc, 0x1118, 0x2061, 0xfc20,
-+	0x0010, 0x2061, 0xfd40, 0xa184, 0x001f, 0xac60, 0x8003, 0x8003,
-+	0x8003, 0xac00, 0x2060, 0x0005, 0xd7fc, 0x1168, 0x2019, 0xb393,
-+	0x2001, 0xb342, 0x2004, 0xd0ec, 0x0118, 0x2021, 0x0102, 0x0038,
-+	0x2021, 0x0202, 0x0020, 0x2019, 0xb3d3, 0x2021, 0x0102, 0x2304,
-+	0xa085, 0x0001, 0x201a, 0x2404, 0xa085, 0x0001, 0x2022, 0x0005,
-+	0xd7fc, 0x1168, 0x2019, 0xb393, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x0118, 0x2021, 0x0102, 0x0038, 0x2021, 0x0202, 0x0020, 0x2019,
-+	0xb3d3, 0x2021, 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2404,
-+	0xa084, 0xfffe, 0x2022, 0x0005, 0x7990, 0xa18c, 0xfff8, 0x7992,
-+	0x70a8, 0xa080, 0x00f1, 0x781a, 0x0804, 0x29df, 0x7097, 0x0000,
-+	0x7003, 0x0000, 0x704b, 0x0001, 0x7043, 0x0000, 0x080c, 0x1ef1,
-+	0x0528, 0x70ef, 0x0000, 0x68cc, 0x2060, 0x6100, 0xa184, 0x0300,
-+	0x0150, 0x6827, 0x000e, 0xa084, 0x0200, 0x0110, 0x6827, 0x0017,
-+	0x080c, 0x4432, 0x0c18, 0x7000, 0xa086, 0x0007, 0x1904, 0x4597,
-+	0x6910, 0x70b0, 0xa106, 0x0120, 0x2d60, 0x080c, 0x1ec4, 0x0005,
-+	0x2d00, 0x7096, 0xad80, 0x000f, 0x7042, 0x0050, 0x7010, 0xa005,
-+	0x1128, 0x7048, 0xa086, 0x0001, 0x0904, 0x29f8, 0x0804, 0x29df,
-+	0xa036, 0x691c, 0xa184, 0x0002, 0x0110, 0xa6b5, 0x0004, 0xa184,
-+	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x4646, 0x2005, 0xa635,
-+	0x080c, 0x2ae3, 0x6820, 0xa084, 0x0400, 0x0150, 0x789b, 0x0018,
-+	0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x5000,
-+	0x6820, 0xa084, 0x8000, 0x0140, 0xa6b5, 0x0400, 0x789b, 0x000e,
-+	0x6824, 0x8007, 0x78aa, 0x00d8, 0x681c, 0xd0fc, 0x1140, 0xa6b5,
-+	0x0800, 0x6820, 0xd0c4, 0x0198, 0xa6b5, 0x4000, 0x0080, 0x6820,
-+	0xd0c4, 0x0118, 0xa6b5, 0x4000, 0x0050, 0x789b, 0x0018, 0x78ab,
-+	0x0002, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0xa684,
-+	0x0200, 0x0508, 0x00c6, 0x080c, 0x4fc6, 0x6028, 0xd08c, 0x0138,
-+	0x6020, 0x00ce, 0x6930, 0x6a2c, 0x080c, 0x52b7, 0x0028, 0x00ce,
-+	0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0150, 0x682c,
-+	0xa084, 0x0001, 0x0130, 0x7888, 0xa084, 0x0040, 0x0110, 0xa6b5,
-+	0x8000, 0x080c, 0x5207, 0x7e5a, 0x6eb6, 0x0804, 0x524e, 0x080c,
-+	0x40a8, 0x1904, 0x4640, 0x2041, 0x0001, 0x2031, 0x1000, 0x080c,
-+	0x2ae3, 0x789b, 0x0018, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080,
-+	0x78aa, 0x691c, 0xa184, 0x0002, 0x0140, 0xa6b5, 0x0004, 0x78ab,
-+	0x0020, 0x6828, 0x78aa, 0xa8c0, 0x0002, 0x681c, 0xd0f4, 0x0128,
-+	0x2c50, 0x080c, 0x418d, 0x080c, 0x5044, 0x6820, 0xa084, 0x8000,
-+	0x0140, 0xa6b5, 0x0400, 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa,
-+	0x0060, 0x681c, 0xa084, 0x8000, 0x1140, 0xa6b5, 0x0800, 0x6820,
-+	0xa084, 0x0100, 0x0110, 0xa6b5, 0x4000, 0x681c, 0xa084, 0x00c0,
-+	0x8003, 0x8003, 0x8007, 0xa080, 0x4646, 0x2005, 0xa635, 0xa684,
-+	0x0100, 0x0150, 0x682c, 0xa084, 0x0001, 0x0130, 0x7888, 0xa084,
-+	0x0040, 0x0110, 0xa6b5, 0x8000, 0x789b, 0x007e, 0x7eae, 0x6eb6,
-+	0x6814, 0xc0fc, 0x8007, 0x78aa, 0x7882, 0x2810, 0x7aaa, 0x7830,
-+	0xa084, 0x00c0, 0x1904, 0x4640, 0x6914, 0xd1fc, 0x1158, 0x2001,
-+	0xb342, 0x2004, 0xd0ec, 0x0118, 0x0104, 0x4640, 0x0028, 0x0304,
-+	0x4640, 0x0010, 0x0104, 0x4640, 0x0126, 0x00d6, 0x00c6, 0x70f0,
-+	0xa084, 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0xa684, 0x0200,
-+	0x01a8, 0x00c6, 0x080c, 0x4fc6, 0x6028, 0xd08c, 0x0140, 0x6020,
-+	0xa005, 0x0128, 0x6930, 0x6a2c, 0x080c, 0x52b7, 0x0020, 0x682c,
-+	0x78d2, 0x6830, 0x78d6, 0x00ce, 0x080c, 0x5207, 0x70a8, 0xa080,
-+	0x00fc, 0x781a, 0x080c, 0x40d4, 0x2d00, 0x7096, 0x7052, 0x6810,
-+	0x70b2, 0x7003, 0x0007, 0xad80, 0x000f, 0x7042, 0x0804, 0x29df,
-+	0x080c, 0x1eb2, 0x080c, 0x40d4, 0x0804, 0x29df, 0x0000, 0x0300,
-+	0x0200, 0x0000, 0x080c, 0x297f, 0x2300, 0x0002, 0x4651, 0x4651,
-+	0x4658, 0x080c, 0x297f, 0x71a8, 0xa188, 0x00a1, 0x791a, 0x0005,
-+	0x080c, 0x5223, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0148,
-+	0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x080c, 0x1eb2, 0x0804,
-+	0x44ee, 0x2001, 0x000a, 0x080c, 0x5184, 0x0804, 0x44ee, 0xa282,
-+	0x0005, 0x0310, 0x080c, 0x297f, 0x7000, 0xa084, 0x000f, 0x190c,
-+	0x41a1, 0x080c, 0x1c85, 0x11b8, 0x2069, 0xffff, 0xa684, 0x0004,
-+	0x0118, 0x2001, 0x2800, 0x0010, 0x2001, 0x0800, 0x71a8, 0xa188,
-+	0x00a1, 0x789b, 0x000e, 0x8007, 0x78aa, 0x2031, 0x0400, 0x7e5a,
-+	0x791a, 0x0804, 0x29df, 0x6807, 0x0106, 0x680b, 0x0000, 0x689f,
-+	0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x1180, 0xa286, 0x0002,
-+	0x1168, 0x78a0, 0xa005, 0x1150, 0xd4fc, 0x1140, 0x78e4, 0xa084,
-+	0x0008, 0x0120, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x080c, 0x4b0c,
-+	0x2d00, 0x7096, 0x7052, 0x7003, 0x0007, 0x7043, 0x0000, 0x6020,
-+	0xa084, 0x000f, 0x680e, 0x6824, 0xa084, 0x0080, 0x0120, 0x080c,
-+	0x4bc9, 0x0804, 0x29df, 0x2300, 0x0002, 0x46c8, 0x473d, 0x4754,
-+	0x2200, 0x0002, 0x46cf, 0x46de, 0x4700, 0x470a, 0x472b, 0x2029,
-+	0x0001, 0xa026, 0x2011, 0x0000, 0x080c, 0x4ce3, 0x0002, 0x46dc,
-+	0x29df, 0x44ee, 0x46dc, 0x46dc, 0x080c, 0x297f, 0x7990, 0xa18c,
-+	0x0007, 0x1110, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, 0x0004,
-+	0x0110, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, 0x0001, 0x080c,
-+	0x4ce3, 0x0002, 0x46f7, 0x29df, 0x44ee, 0x46fe, 0x46f9, 0x0804,
-+	0x526b, 0x709f, 0x46fd, 0x0804, 0x29df, 0x0cc8, 0x080c, 0x297f,
-+	0xa684, 0x0010, 0x0128, 0x080c, 0x4b94, 0x0110, 0x0804, 0x29df,
-+	0x0804, 0x4c05, 0x6000, 0xa084, 0x0002, 0x01c0, 0x70a8, 0xa080,
-+	0x008f, 0x781a, 0x00d6, 0x080c, 0x522f, 0x2d00, 0x682e, 0x6827,
-+	0x0000, 0x080c, 0x4432, 0x00de, 0x080c, 0x1ca6, 0x7003, 0x0000,
-+	0x7043, 0x0000, 0x7053, 0x0000, 0x0804, 0x44ee, 0xa684, 0x0004,
-+	0x1110, 0x0804, 0x526b, 0x6000, 0xa084, 0x0004, 0x1160, 0x6000,
-+	0xa084, 0x0001, 0x0140, 0x709f, 0x473b, 0x2001, 0x0007, 0x080c,
-+	0x517c, 0x0804, 0x5271, 0x0804, 0x526b, 0x2200, 0x0002, 0x4744,
-+	0x4746, 0x4744, 0x4744, 0x4744, 0x080c, 0x297f, 0x709b, 0x474a,
-+	0x0804, 0x5279, 0x78e4, 0xa084, 0x0008, 0x1dc0, 0x080c, 0x516d,
-+	0x709f, 0x4752, 0x0804, 0x526b, 0x2200, 0x0002, 0x475b, 0x475d,
-+	0x475d, 0x475b, 0x475b, 0x080c, 0x297f, 0x78e4, 0xa084, 0x0008,
-+	0x0178, 0x709b, 0x4765, 0x0804, 0x5279, 0x2011, 0x0004, 0x080c,
-+	0x4cdd, 0x0002, 0x477a, 0x29df, 0x44ee, 0x477a, 0x4784, 0x4788,
-+	0x690c, 0x81ff, 0x0138, 0x8109, 0x1120, 0x6827, 0x000f, 0x0804,
-+	0x4818, 0x690e, 0x709f, 0x4782, 0x2001, 0x0003, 0x080c, 0x517c,
-+	0x0804, 0x5271, 0x0804, 0x526b, 0x709f, 0x477a, 0x0804, 0x29df,
-+	0x709f, 0x478c, 0x0804, 0x29df, 0x0ca8, 0xa282, 0x0003, 0x0310,
-+	0x080c, 0x297f, 0xa386, 0x0002, 0x1180, 0xa286, 0x0002, 0x1190,
-+	0x78a0, 0xa005, 0x1178, 0xd4fc, 0x1168, 0x78e4, 0xa084, 0x0008,
-+	0x0120, 0xa6b5, 0x0008, 0x2019, 0x0000, 0xa684, 0x0008, 0x0110,
-+	0x080c, 0x4b72, 0x6810, 0x70b2, 0x7003, 0x0007, 0x2300, 0x0002,
-+	0x47b3, 0x47db, 0x47e2, 0x2200, 0x0002, 0x47ba, 0x47b8, 0x47d1,
-+	0x080c, 0x297f, 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001,
-+	0x080c, 0x4ce3, 0x0002, 0x47c8, 0x29df, 0x44ee, 0x47cf, 0x47ca,
-+	0x0804, 0x526b, 0x709f, 0x47ce, 0x0804, 0x29df, 0x0cc8, 0x080c,
-+	0x297f, 0xa684, 0x0010, 0x0128, 0x080c, 0x4b94, 0x0110, 0x0804,
-+	0x29df, 0x0804, 0x4c05, 0x2200, 0x0002, 0x47e0, 0x47e0, 0x47e0,
-+	0x080c, 0x297f, 0x2200, 0x0002, 0x47e7, 0x47e9, 0x47e9, 0x080c,
-+	0x297f, 0x78e4, 0xa084, 0x0008, 0x0178, 0x709b, 0x47f1, 0x0804,
-+	0x5279, 0x2011, 0x0004, 0x080c, 0x4cdd, 0x0002, 0x4805, 0x29df,
-+	0x44ee, 0x4805, 0x480f, 0x4813, 0x690c, 0x81ff, 0x0130, 0x8109,
-+	0x1118, 0x6827, 0x000f, 0x00a0, 0x690e, 0x709f, 0x480d, 0x2001,
-+	0x0003, 0x080c, 0x517c, 0x0804, 0x5271, 0x0804, 0x526b, 0x709f,
-+	0x4805, 0x0804, 0x29df, 0x709f, 0x4817, 0x0804, 0x29df, 0x0ca8,
-+	0x70a8, 0xa080, 0x008f, 0x781a, 0x00d6, 0x6824, 0x0006, 0x080c,
-+	0x522f, 0x000e, 0x6826, 0x2d00, 0x682e, 0x080c, 0x4432, 0x00de,
-+	0x080c, 0x5184, 0x7003, 0x0000, 0x7043, 0x0000, 0x7053, 0x0000,
-+	0x0804, 0x44ee, 0x2300, 0x0002, 0x4839, 0x483b, 0x4837, 0x080c,
-+	0x297f, 0x7098, 0x0807, 0x7098, 0x0807, 0xa282, 0x0002, 0x0310,
-+	0x080c, 0x297f, 0xa684, 0x0200, 0x0130, 0x080c, 0x5222, 0x080c,
-+	0x4cca, 0x080c, 0x5223, 0x2300, 0x0002, 0x4850, 0x487e, 0x48de,
-+	0xad86, 0xffff, 0x1108, 0x0005, 0xa286, 0x0001, 0x0110, 0x080c,
-+	0x297f, 0xa684, 0x0200, 0x0120, 0x080c, 0x5222, 0x080c, 0x5223,
-+	0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x1118, 0xa184, 0xff00,
-+	0x6826, 0x2001, 0x0001, 0x080c, 0x5184, 0x78b8, 0x8007, 0xa084,
-+	0x007f, 0x0140, 0x7848, 0xa085, 0x0008, 0x784a, 0x7848, 0xa084,
-+	0x0008, 0x1de0, 0x7003, 0x0000, 0x0804, 0x44ee, 0x2200, 0x0002,
-+	0x4882, 0x48b1, 0x709b, 0x4886, 0x0804, 0x5279, 0x2011, 0x000d,
-+	0x080c, 0x4cdd, 0x0002, 0x4892, 0x29df, 0x44ee, 0x489a, 0x48a2,
-+	0x48a7, 0x48a9, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0804, 0x524e, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-+	0x0804, 0x524e, 0x709f, 0x48a6, 0x0804, 0x29df, 0x0c58, 0x080c,
-+	0x297f, 0x709f, 0x48ad, 0x0804, 0x29df, 0x080c, 0x527f, 0x0804,
-+	0x29df, 0x709b, 0x48b5, 0x0804, 0x5279, 0x2011, 0x0012, 0x080c,
-+	0x4cdd, 0x0002, 0x48c0, 0x29df, 0x44ee, 0x48cc, 0x48d4, 0x48d9,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70a8, 0xa080,
-+	0x00bf, 0x781a, 0x0804, 0x29df, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
-+	0x6eb6, 0x7e5a, 0x0804, 0x524e, 0x709f, 0x48d8, 0x0804, 0x29df,
-+	0x0c38, 0x709f, 0x48dd, 0x0804, 0x29df, 0x0c70, 0xa286, 0x0001,
-+	0x0110, 0x080c, 0x297f, 0x709b, 0x48e7, 0x0804, 0x5279, 0x2011,
-+	0x0015, 0x080c, 0x4cdd, 0x0002, 0x48f1, 0x29df, 0x44ee, 0x48ff,
-+	0x490b, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b,
-+	0x1301, 0x70a8, 0xa080, 0x00cb, 0x781a, 0x0804, 0x29df, 0xa6b4,
-+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70a8, 0xa080, 0x00bf,
-+	0x781a, 0x0804, 0x29df, 0x709f, 0x490f, 0x0804, 0x29df, 0x0c08,
-+	0xa282, 0x0003, 0x0310, 0x080c, 0x297f, 0x2300, 0x0002, 0x491a,
-+	0x4956, 0x49b5, 0xa286, 0x0001, 0x0110, 0x080c, 0x297f, 0x6804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1130, 0x080c, 0x4432, 0x7003,
-+	0x0000, 0x0804, 0x44ee, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
-+	0x0200, 0x0130, 0x080c, 0x5222, 0x080c, 0x4cca, 0x080c, 0x5223,
-+	0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x1118, 0xa184, 0xff00,
-+	0x6826, 0x2001, 0x0001, 0x080c, 0x5184, 0x78b8, 0x8007, 0xa084,
-+	0x007f, 0x0140, 0x7848, 0xa085, 0x0008, 0x784a, 0x7848, 0xa084,
-+	0x0008, 0x1de0, 0x7003, 0x0000, 0x0804, 0x44ee, 0xa684, 0x0200,
-+	0x0120, 0x080c, 0x4cca, 0x080c, 0x5223, 0x2200, 0x0002, 0x4961,
-+	0x4992, 0x709b, 0x4965, 0x0804, 0x5279, 0x2011, 0x000d, 0x080c,
-+	0x4cdd, 0x0002, 0x4971, 0x29df, 0x44ee, 0x4979, 0x4981, 0x4986,
-+	0x4988, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0804,
-+	0x524e, 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0804,
-+	0x524e, 0x709f, 0x4985, 0x0804, 0x29df, 0x0c58, 0x080c, 0x297f,
-+	0x709f, 0x498e, 0x080c, 0x5223, 0x0804, 0x29df, 0x080c, 0x527f,
-+	0x0804, 0x29df, 0x709b, 0x4996, 0x0804, 0x5279, 0x2011, 0x0005,
-+	0x080c, 0x4cdd, 0x0002, 0x49a0, 0x29df, 0x44ee, 0x49a8, 0x49b0,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0804, 0x524e,
-+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0804, 0x524e,
-+	0x709f, 0x49b4, 0x0804, 0x29df, 0x0c58, 0xa286, 0x0001, 0x0110,
-+	0x080c, 0x297f, 0x709b, 0x49be, 0x0804, 0x5279, 0x2011, 0x0006,
-+	0x080c, 0x4cdd, 0x0002, 0x49c8, 0x29df, 0x44ee, 0x49ce, 0x49d8,
-+	0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0804, 0x524e, 0xa6b4, 0x00ff,
-+	0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, 0x0804, 0x524e,
-+	0x709f, 0x49dc, 0x0804, 0x29df, 0x0c58, 0x2300, 0x0002, 0x49e4,
-+	0x49e2, 0x49e2, 0x080c, 0x297f, 0x080c, 0x297f, 0x2300, 0x719c,
-+	0xa005, 0x0817, 0x6810, 0x70b2, 0xa282, 0x0003, 0x0310, 0x080c,
-+	0x297f, 0x2300, 0x0002, 0x49f6, 0x4a03, 0x4a21, 0xa684, 0x0200,
-+	0x0120, 0x080c, 0x5222, 0x080c, 0x5223, 0x2001, 0x0001, 0x080c,
-+	0x5184, 0x0804, 0x29df, 0xa286, 0x0002, 0x0120, 0x82ff, 0x0110,
-+	0x080c, 0x297f, 0x709b, 0x4a0e, 0x0804, 0x5279, 0x2011, 0x0018,
-+	0x080c, 0x4cdd, 0x0002, 0x4a18, 0x29df, 0x44ee, 0x4a1a, 0x4a1c,
-+	0x0804, 0x524e, 0x0804, 0x524e, 0x709f, 0x4a20, 0x0804, 0x29df,
-+	0x0cb8, 0x2200, 0x0002, 0x4a25, 0x4a3c, 0x709b, 0x4a29, 0x0804,
-+	0x5279, 0x2011, 0x0017, 0x080c, 0x4cdd, 0x0002, 0x4a33, 0x29df,
-+	0x44ee, 0x4a35, 0x4a37, 0x0804, 0x524e, 0x0804, 0x524e, 0x709f,
-+	0x4a3b, 0x0804, 0x29df, 0x0cb8, 0xd4fc, 0x1904, 0x4abb, 0xa684,
-+	0x0100, 0x0120, 0x080c, 0x5222, 0x080c, 0x4cca, 0x00c6, 0x080c,
-+	0x4fc6, 0x6028, 0xd08c, 0x0190, 0x612c, 0x7adc, 0x080c, 0x20dd,
-+	0x2110, 0x2008, 0x6024, 0xa210, 0xa189, 0x0000, 0x78d8, 0xa210,
-+	0xa189, 0x0000, 0x602c, 0x080c, 0x52b7, 0x0020, 0x78d8, 0x78d2,
-+	0x78dc, 0x78d6, 0x00ce, 0xa6b4, 0xefff, 0x7e5a, 0x709b, 0x4a6a,
-+	0x0804, 0x5279, 0x2011, 0x000d, 0x080c, 0x4cdd, 0x0002, 0x4a76,
-+	0x29df, 0x44ee, 0x4a76, 0x4aaa, 0x4aaf, 0x4ab1, 0x78d8, 0x79dc,
-+	0xa105, 0x1168, 0x78b8, 0x8007, 0xa084, 0x007f, 0x1140, 0x70a7,
-+	0x0000, 0x7858, 0xa084, 0xfdff, 0x785a, 0x0804, 0x524e, 0xa684,
-+	0x0100, 0x01f0, 0x080c, 0x5223, 0x080c, 0x51cf, 0x0026, 0x0036,
-+	0x00c6, 0x080c, 0x4fc6, 0x6028, 0xd08c, 0x0138, 0x6020, 0x00ce,
-+	0x6930, 0x6a2c, 0x080c, 0x52b7, 0x0028, 0x00ce, 0x682c, 0x78d2,
-+	0x6830, 0x78d6, 0x70a7, 0x0000, 0x001e, 0x000e, 0x080c, 0x5622,
-+	0x0804, 0x524e, 0x709f, 0x4aae, 0x0804, 0x29df, 0x0838, 0x080c,
-+	0x297f, 0x709f, 0x4ab7, 0x080c, 0x5223, 0x0804, 0x29df, 0x080c,
-+	0x527f, 0x0804, 0x29df, 0x080c, 0x5223, 0x6918, 0xd1a4, 0x0140,
-+	0x6827, 0x000f, 0x080c, 0x5184, 0x080c, 0x5223, 0x0804, 0x29df,
-+	0x709f, 0x4ad0, 0x2001, 0x0003, 0x080c, 0x517c, 0x0804, 0x5271,
-+	0x080c, 0x5207, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0804, 0x524e,
-+	0xa282, 0x0002, 0x0310, 0x080c, 0x297f, 0x2300, 0x0002, 0x4ae2,
-+	0x4af2, 0x4af4, 0xa286, 0x0001, 0x0110, 0x080c, 0x297f, 0x00c6,
-+	0x080c, 0x4fc6, 0x6224, 0x2009, 0x0000, 0x602c, 0x080c, 0x52b7,
-+	0x0804, 0x524e, 0x080c, 0x297f, 0x080c, 0x297f, 0x0026, 0x002e,
-+	0xa684, 0x0200, 0x0130, 0x080c, 0x5222, 0x080c, 0x4cca, 0x080c,
-+	0x5223, 0x2300, 0x0002, 0x4b06, 0x4b08, 0x4b0a, 0x0804, 0x4850,
-+	0x0804, 0x487e, 0x0804, 0x48de, 0x70ac, 0x6812, 0x70b2, 0x8000,
-+	0x70ae, 0x681b, 0x0000, 0xa684, 0x0008, 0x01c0, 0x0156, 0x0136,
-+	0x0146, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f,
-+	0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0xad80,
-+	0x000b, 0x20a0, 0x53a5, 0x014e, 0x013e, 0x015e, 0xa6c4, 0x0f00,
-+	0xa684, 0x0002, 0x1140, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184,
-+	0x0007, 0x2008, 0x0090, 0x789b, 0x0090, 0x79ac, 0xa184, 0x0020,
-+	0x0160, 0x0016, 0x2009, 0x0005, 0x2001, 0x3d00, 0x080c, 0x51da,
-+	0x6824, 0xa085, 0x003b, 0x6826, 0x001e, 0xa184, 0x001f, 0xa805,
-+	0x0016, 0x3208, 0xa18c, 0x0600, 0x0110, 0xc0fc, 0x0008, 0xc0fd,
-+	0x001e, 0x6816, 0x080c, 0x449c, 0x68ce, 0xa684, 0x0004, 0x0130,
-+	0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, 0x682a, 0xa6b4,
-+	0x00ff, 0x6000, 0xa084, 0x0008, 0x0110, 0xa6b5, 0x4000, 0x6eb6,
-+	0x7e5a, 0x0005, 0x0156, 0x0136, 0x0146, 0x6918, 0x7890, 0x8004,
-+	0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x0006, 0xa100, 0x681a,
-+	0x000e, 0x8000, 0x8004, 0x0160, 0x20a8, 0x8104, 0xa080, 0x000b,
-+	0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0x53a5,
-+	0x014e, 0x013e, 0x015e, 0x0005, 0x682c, 0xd0b4, 0x1140, 0xd0ac,
-+	0x1118, 0x2011, 0x0010, 0x0048, 0x2011, 0x000c, 0x0030, 0xa084,
-+	0x0020, 0x1110, 0x620c, 0x0008, 0x6210, 0x6b18, 0x2300, 0xa202,
-+	0x01c0, 0x2018, 0xa382, 0x000e, 0x0220, 0x0118, 0x2019, 0x000e,
-+	0x0020, 0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893,
-+	0x0000, 0x7ba2, 0x70a8, 0xa080, 0x009e, 0x781a, 0xa085, 0x0001,
-+	0x0005, 0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006,
-+	0x0005, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0128, 0xa196,
-+	0x000f, 0x0110, 0x6807, 0x0117, 0x6914, 0x6814, 0x080c, 0x449c,
-+	0x6100, 0x8104, 0x1290, 0x601c, 0xa005, 0x0118, 0x2001, 0x0800,
-+	0x0070, 0x00d6, 0x6824, 0x0006, 0x080c, 0x522f, 0x000e, 0x6826,
-+	0x2d00, 0x682e, 0x080c, 0x4432, 0x00de, 0x2001, 0x0200, 0x6924,
-+	0xa18c, 0x00ff, 0xa10d, 0x6926, 0x8007, 0x789b, 0x000e, 0x78aa,
-+	0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
-+	0x71a8, 0xa188, 0x00a1, 0x791a, 0x0005, 0x080c, 0x2ae3, 0x6814,
-+	0x2040, 0xa684, 0x0002, 0x1168, 0x692c, 0x810d, 0x810d, 0x810d,
-+	0xa184, 0x0007, 0x2008, 0xa805, 0x6816, 0x080c, 0x449c, 0x68ce,
-+	0x0020, 0x6914, 0x6814, 0x080c, 0x449c, 0x6100, 0x8104, 0x1a04,
-+	0x4c70, 0xa184, 0x0300, 0x0118, 0x6807, 0x0117, 0x00d0, 0x6004,
-+	0xa005, 0x1500, 0x6807, 0x0117, 0x601c, 0xa005, 0x1150, 0x00d6,
-+	0x080c, 0x522f, 0x6827, 0x0034, 0x2d00, 0x682e, 0x080c, 0x4432,
-+	0x00de, 0xa684, 0x0004, 0x0128, 0x2031, 0x0400, 0x2001, 0x2800,
-+	0x0020, 0x2031, 0x0400, 0x2001, 0x0800, 0x71a8, 0xa188, 0x00a1,
-+	0x0804, 0x4ca5, 0x6018, 0xa005, 0x1d60, 0x601c, 0xa005, 0x1d48,
-+	0x689f, 0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0904, 0x4cb3,
-+	0xd694, 0x1180, 0x6100, 0xd1d4, 0x0168, 0x692c, 0xa18c, 0x00ff,
-+	0x0904, 0x4cb3, 0xa186, 0x0003, 0x0904, 0x4cb3, 0xa186, 0x0012,
-+	0x0904, 0x4cb3, 0xa6b5, 0x0800, 0x71a8, 0xa188, 0x00c3, 0x04f0,
-+	0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c, 0x00ff, 0xa186,
-+	0x0012, 0x1128, 0x2001, 0x4cc0, 0x2009, 0x0001, 0x0070, 0xa186,
-+	0x0003, 0x1128, 0x2001, 0x4cc1, 0x2009, 0x0012, 0x0030, 0x2001,
-+	0x0200, 0x71a8, 0xa188, 0x00a1, 0x00c0, 0x6a34, 0xa29d, 0x0000,
-+	0x1110, 0xa006, 0x0cb0, 0x0006, 0x2100, 0xa21a, 0x000e, 0x1208,
-+	0x2208, 0x080c, 0x51f4, 0x78a3, 0x0000, 0x681c, 0xa085, 0x0040,
-+	0x681e, 0x71a8, 0xa188, 0x00f3, 0xa006, 0x6826, 0x8007, 0x789b,
-+	0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x6eb6, 0x7e5a,
-+	0x791a, 0x0804, 0x29df, 0x6eb6, 0x080c, 0x4432, 0x6810, 0x70b2,
-+	0x7003, 0x0007, 0x7097, 0x0000, 0x7053, 0x0000, 0x0804, 0x29df,
-+	0x0023, 0x0070, 0x0005, 0x0000, 0x0a00, 0x0000, 0x0000, 0x0025,
-+	0x0000, 0x0000, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684, 0x0200,
-+	0x0158, 0x78b8, 0x8007, 0xa08c, 0x007f, 0x78d8, 0xa100, 0x6836,
-+	0x78dc, 0xa081, 0x0000, 0x683a, 0x0005, 0x7990, 0x810f, 0xa5ac,
-+	0x0007, 0x2021, 0x0000, 0xa480, 0x0090, 0x789a, 0x79a8, 0xa18c,
-+	0x00ff, 0xa184, 0x0080, 0x11e0, 0xa182, 0x0020, 0x16b0, 0xa182,
-+	0x0012, 0x1a04, 0x516d, 0x2100, 0x000b, 0x0005, 0x516d, 0x4f27,
-+	0x516d, 0x516d, 0x4d31, 0x4d34, 0x4d78, 0x4db3, 0x4de6, 0x4de9,
-+	0x516d, 0x516d, 0x4d98, 0x4e54, 0x4e8c, 0x516d, 0x516d, 0x4eb2,
-+	0xa184, 0x0020, 0x1904, 0x4ee6, 0xa18c, 0x001f, 0x6814, 0xa084,
-+	0x001f, 0xa106, 0x0178, 0x70a8, 0xa080, 0x008f, 0x781a, 0x2001,
-+	0x0014, 0x080c, 0x5184, 0x080c, 0x5223, 0x7003, 0x0000, 0x2001,
-+	0x0002, 0x0005, 0x2001, 0x0000, 0x0005, 0xa182, 0x0024, 0x1a04,
-+	0x516d, 0xa184, 0x0003, 0x0853, 0x0005, 0x516d, 0x516d, 0x516d,
-+	0x516d, 0x080c, 0x516d, 0x0005, 0x2200, 0x0002, 0x4eb5, 0x4eb5,
-+	0x4d65, 0x4d65, 0x4d65, 0x4d65, 0x4d65, 0x4d65, 0x4d65, 0x4d65,
-+	0x4d63, 0x4d65, 0x4d4f, 0x4d57, 0x4d57, 0x4d57, 0x4d65, 0x4d65,
-+	0x4d6d, 0x4d70, 0x4eb5, 0x4d70, 0x4d65, 0x4d65, 0x4d65, 0x00c6,
-+	0x0076, 0x6f14, 0x080c, 0x3ec6, 0x007e, 0x00ce, 0x0070, 0x6818,
-+	0xd0a4, 0x0158, 0x6827, 0x0033, 0x080c, 0x5184, 0x080c, 0x5223,
-+	0x2001, 0x0001, 0x0005, 0x080c, 0x4fd7, 0x6827, 0x02b3, 0x2009,
-+	0x000b, 0x2001, 0x4800, 0x0804, 0x4ee9, 0x080c, 0x515e, 0x0005,
-+	0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0804, 0x4ed1,
-+	0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x6807,
-+	0x0117, 0x6827, 0x0002, 0x080c, 0x522f, 0x6827, 0x0036, 0x6932,
-+	0x2d00, 0x682e, 0x00d6, 0x080c, 0x440a, 0x080c, 0x4f11, 0x2b68,
-+	0x080c, 0x4432, 0x00de, 0x080c, 0x4432, 0x2001, 0x0002, 0x0005,
-+	0x080c, 0x4f11, 0x2001, 0x0017, 0x080c, 0x5184, 0x7097, 0x0000,
-+	0x6914, 0xd1fc, 0x0118, 0x2009, 0xb3c6, 0x0010, 0x2009, 0xb386,
-+	0x200b, 0x0006, 0x70a3, 0x0017, 0x2009, 0x0200, 0x080c, 0x4318,
-+	0x2001, 0x0001, 0x0005, 0x2200, 0x0002, 0x4eb5, 0x4ee6, 0x4ee6,
-+	0x4ee6, 0x4dd6, 0x4ef8, 0x4dde, 0x4ef8, 0x4ef8, 0x4efb, 0x4efb,
-+	0x4f00, 0x4f00, 0x4dce, 0x4dce, 0x4ee6, 0x4ee6, 0x4ef8, 0x4ee6,
-+	0x4dde, 0x4eb5, 0x4dde, 0x4dde, 0x4dde, 0x4dde, 0x6827, 0x0084,
-+	0x2009, 0x000b, 0x2001, 0x4300, 0x0804, 0x4f0a, 0x6827, 0x000d,
-+	0x2009, 0x000b, 0x2001, 0x4300, 0x0804, 0x4ee9, 0x6827, 0x0093,
-+	0x2009, 0x000b, 0x2001, 0x4300, 0x0804, 0x4ed1, 0x2001, 0x0000,
-+	0x0005, 0x2200, 0x0002, 0x4eb5, 0x4e4c, 0x4e4c, 0x4e4c, 0x4e4c,
-+	0x4e04, 0x4e04, 0x4e04, 0x4e04, 0x4e04, 0x4e04, 0x4e04, 0x4e04,
-+	0x4e4c, 0x4e4c, 0x4e4c, 0x4e4c, 0x4e2a, 0x4e4c, 0x4e4c, 0x4e2a,
-+	0x4e2a, 0x4e2a, 0x4e2a, 0x4eb5, 0x6804, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x1500, 0x690c, 0xa184, 0x000f, 0x0904, 0x4ef8, 0x8001,
-+	0x0130, 0xa18c, 0xfff0, 0xa105, 0x680e, 0x0804, 0x4ef8, 0x70a8,
-+	0xa080, 0x008f, 0x781a, 0x6827, 0x000f, 0x080c, 0x4bc9, 0x080c,
-+	0x5184, 0x7003, 0x0000, 0x7043, 0x0000, 0x7053, 0x0000, 0x2001,
-+	0x0002, 0x0005, 0x6918, 0xa184, 0x000f, 0x0904, 0x4ef8, 0x8001,
-+	0x0130, 0xa18c, 0xfff0, 0xa105, 0x681a, 0x0804, 0x4ef8, 0x70a8,
-+	0xa080, 0x008f, 0x781a, 0x6827, 0x008f, 0x2009, 0x000b, 0x2001,
-+	0x4300, 0x080c, 0x51da, 0x080c, 0x5184, 0x080c, 0x5223, 0x7003,
-+	0x0000, 0x2001, 0x0002, 0x0005, 0x6827, 0x0093, 0x2009, 0x000b,
-+	0x2001, 0x4300, 0x0804, 0x4ed1, 0xa684, 0x0004, 0x1180, 0x6804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x516d, 0x080c, 0x4f11,
-+	0x6807, 0x0117, 0x080c, 0x4432, 0x2001, 0x0002, 0x0005, 0x6000,
-+	0xa084, 0x0004, 0x0904, 0x516d, 0x2d58, 0x6804, 0xa084, 0x00ff,
-+	0xa086, 0x0006, 0x1110, 0x6807, 0x0117, 0x6827, 0x0002, 0x080c,
-+	0x522f, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x00d6, 0x080c,
-+	0x4416, 0x080c, 0x4f11, 0x2b68, 0x080c, 0x4432, 0x00de, 0x080c,
-+	0x4432, 0x2001, 0x0002, 0x0005, 0x6000, 0xa084, 0x0004, 0x0904,
-+	0x516d, 0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1110,
-+	0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x080c, 0x522f, 0x6827,
-+	0x0036, 0x6932, 0x2d00, 0x682e, 0x00d6, 0x080c, 0x4424, 0x080c,
-+	0x4f11, 0x2b68, 0x080c, 0x4432, 0x00de, 0x080c, 0x4432, 0x2001,
-+	0x0002, 0x0005, 0x080c, 0x516d, 0x0005, 0x70a8, 0xa080, 0x008f,
-+	0x781a, 0x2001, 0x0001, 0x080c, 0x5184, 0x080c, 0x5223, 0x7003,
-+	0x0000, 0x2001, 0x0002, 0x0005, 0x080c, 0x51da, 0x080c, 0x5222,
-+	0x080c, 0x4cca, 0x080c, 0x4bc9, 0x080c, 0x5223, 0x2001, 0x0001,
-+	0x0005, 0x080c, 0x51da, 0x080c, 0x5222, 0x080c, 0x4cca, 0x70a8,
-+	0xa080, 0x008f, 0x781a, 0x2001, 0x0013, 0x080c, 0x5184, 0x080c,
-+	0x5223, 0x7003, 0x0000, 0x2001, 0x0002, 0x0005, 0x080c, 0x516d,
-+	0x0005, 0x080c, 0x51da, 0x080c, 0x5222, 0x080c, 0x4cca, 0x080c,
-+	0x4bc9, 0x080c, 0x5223, 0x080c, 0x527f, 0x2001, 0x0001, 0x0005,
-+	0x2001, 0x0003, 0x0005, 0x080c, 0x4fd7, 0x2001, 0x0000, 0x0005,
-+	0x00c6, 0x0076, 0x6f14, 0x080c, 0x3ec6, 0x007e, 0x00ce, 0x2001,
-+	0x0000, 0x0005, 0x080c, 0x51da, 0x080c, 0x516d, 0x2001, 0x0006,
-+	0x0005, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0118, 0xa186,
-+	0x000f, 0x1120, 0x080c, 0x5222, 0x080c, 0x4cca, 0x70a8, 0xa080,
-+	0x008f, 0x781a, 0x080c, 0x5223, 0x7003, 0x0000, 0x0005, 0x7aa8,
-+	0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005, 0x1a04,
-+	0x516d, 0x000b, 0x0005, 0x516d, 0x4f38, 0x516d, 0x4fdd, 0x50a0,
-+	0xa282, 0x0003, 0x1904, 0x516d, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8,
-+	0xa6b4, 0x00ff, 0x69b8, 0xa184, 0x0100, 0x05a0, 0xa18c, 0xfeff,
-+	0x69ba, 0x78a0, 0xa005, 0x1570, 0xa6b4, 0x00ff, 0x01f0, 0xa682,
-+	0x001d, 0x1270, 0xa686, 0x0010, 0x1108, 0x8631, 0x852b, 0x852b,
-+	0x2041, 0x0000, 0x080c, 0x3f0c, 0x0118, 0x080c, 0x3d35, 0x0078,
-+	0x080c, 0x508e, 0x080c, 0x3d32, 0x69b8, 0xa18d, 0x0100, 0x69ba,
-+	0x7e58, 0xa6b5, 0x1000, 0x7e5a, 0x0030, 0x080c, 0x3d32, 0x7e58,
-+	0xa6b4, 0xefff, 0x7e5a, 0x70a8, 0xa080, 0x00a1, 0x781a, 0x2001,
-+	0x0001, 0x0005, 0x00c6, 0x080c, 0x4fc6, 0x6200, 0xd2e4, 0x05a0,
-+	0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x001c, 0x0218, 0x0110,
-+	0x2011, 0x001c, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010,
-+	0x1108, 0x8631, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130,
-+	0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c,
-+	0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x2620,
-+	0x080c, 0x5091, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3f0c,
-+	0x0118, 0x080c, 0x3d3e, 0x0020, 0x080c, 0x508e, 0x080c, 0x3d3b,
-+	0x7e58, 0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080,
-+	0x00de, 0x781a, 0x2001, 0x0004, 0x00ce, 0x0005, 0x6814, 0x8007,
-+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x8003, 0x6914, 0xd1fc,
-+	0x1118, 0xa0e0, 0xb800, 0x0010, 0xa0e0, 0xb900, 0x0005, 0x00c6,
-+	0x0c69, 0x080c, 0x3d3b, 0x00ce, 0x0005, 0xa282, 0x0002, 0x1904,
-+	0x516d, 0x7aa8, 0xa294, 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0540,
-+	0xa18c, 0xfdff, 0x69ba, 0x78a0, 0xa005, 0x1510, 0xa282, 0x0002,
-+	0x1a04, 0x3e69, 0x080c, 0x506b, 0x080c, 0x3deb, 0x080c, 0x3d32,
-+	0x7e58, 0xa684, 0x0100, 0x0150, 0x682c, 0xa084, 0x0001, 0x0130,
-+	0xc6fc, 0x7888, 0xa084, 0x0040, 0x0108, 0xc6fd, 0xa6b5, 0x1000,
-+	0x7e5a, 0x70a8, 0xa080, 0x00a1, 0x781a, 0x2001, 0x0001, 0x0005,
-+	0x00c6, 0x080c, 0x4fc6, 0x6028, 0xc08c, 0x602a, 0xa284, 0xfffe,
-+	0x0118, 0x2011, 0x0001, 0x0018, 0xa284, 0x0001, 0x0128, 0x6100,
-+	0xd1ec, 0x1110, 0x2011, 0x0000, 0x04c1, 0x080c, 0x3df1, 0x080c,
-+	0x3d3b, 0x7e58, 0xa684, 0x0100, 0x0150, 0x682c, 0xa084, 0x0001,
-+	0x0130, 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0108, 0xc6fd, 0xa6b5,
-+	0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080, 0x00de, 0x781a,
-+	0x2001, 0x0004, 0x00ce, 0x0005, 0x00c6, 0x2960, 0x6000, 0x2011,
-+	0x0001, 0xa084, 0x2000, 0x1110, 0x2011, 0x0000, 0x78ab, 0x0001,
-+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x68b8,
-+	0xa085, 0x0200, 0x68ba, 0x00ce, 0x0005, 0x789b, 0x0018, 0x78ab,
-+	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081,
-+	0x78ab, 0x0004, 0x0005, 0x00c6, 0x705c, 0x2060, 0x6000, 0xa084,
-+	0x1000, 0x1128, 0x2029, 0x0032, 0x2021, 0x0000, 0x0080, 0x6408,
-+	0xa4ac, 0x00ff, 0xa582, 0x000c, 0x1210, 0x2029, 0x000c, 0x8427,
-+	0xa4a4, 0x00ff, 0xa482, 0x001c, 0x0210, 0x2021, 0x001c, 0x0049,
-+	0x68b8, 0xa085, 0x0100, 0x68ba, 0x00ce, 0x0005, 0xa026, 0x2029,
-+	0x0032, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-+	0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x0005,
-+	0x080c, 0x4fc6, 0x6000, 0xd09c, 0x1118, 0x080c, 0x516d, 0x0005,
-+	0xa282, 0x0006, 0x0118, 0x080c, 0x516d, 0x0005, 0x7aa8, 0xa294,
-+	0x00ff, 0x7e5a, 0x7ea8, 0x7ea8, 0xa6b4, 0x00ff, 0x7fa8, 0xa7bc,
-+	0x00ff, 0xa782, 0x0002, 0x0218, 0x080c, 0x516d, 0x0005, 0x78a8,
-+	0x2040, 0xa8c4, 0x00ff, 0xa882, 0x0003, 0x0218, 0x080c, 0x516d,
-+	0x0005, 0xa886, 0x0001, 0x1118, 0x080c, 0x516d, 0x0005, 0x2600,
-+	0xa005, 0x1120, 0x080c, 0x4fd7, 0x0804, 0x513e, 0xa682, 0x001c,
-+	0x0218, 0x0110, 0x2031, 0x001c, 0x88ff, 0x0168, 0x87ff, 0x1118,
-+	0x080c, 0x516d, 0x0005, 0x6000, 0xd0ec, 0x0118, 0x78ec, 0xd0e4,
-+	0x1110, 0x2041, 0x0000, 0x87ff, 0x1178, 0xa282, 0x000a, 0x0230,
-+	0x0128, 0xa282, 0x0061, 0x1128, 0x0120, 0x00b8, 0x2011, 0x000a,
-+	0x00a0, 0x2011, 0x0061, 0x0088, 0x78ec, 0xd0e4, 0x1108, 0x0c68,
-+	0xa282, 0x0009, 0x0228, 0x0120, 0xa282, 0x0019, 0x0230, 0x0018,
-+	0x2011, 0x0009, 0x0010, 0x2011, 0x0019, 0x0086, 0x0076, 0x0066,
-+	0x8213, 0x8213, 0x2228, 0x080c, 0x3f0c, 0x006e, 0x007e, 0x008e,
-+	0x1128, 0x080c, 0x4fd7, 0xa016, 0xa036, 0x0400, 0x87ff, 0x0150,
-+	0xa8ac, 0x0002, 0x0138, 0x6520, 0x85ff, 0x0120, 0x6528, 0xc58d,
-+	0x652a, 0x0018, 0x6528, 0xc58c, 0x652a, 0x2620, 0x88ff, 0x0108,
-+	0x8634, 0xa69e, 0x0010, 0x1108, 0x8631, 0x0026, 0x080c, 0x3d3e,
-+	0x080c, 0x3df1, 0x2430, 0x002e, 0x8214, 0x8214, 0x789b, 0x0018,
-+	0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x7aaa, 0x78ab,
-+	0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b, 0x0081, 0x78ab,
-+	0x0008, 0x7e58, 0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8,
-+	0xa080, 0x00de, 0x781a, 0x2001, 0x0004, 0x0005, 0x2001, 0x0003,
-+	0x00d9, 0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080,
-+	0x00de, 0x781a, 0x2001, 0x0005, 0x0005, 0x2001, 0x0007, 0x0061,
-+	0xa6b5, 0x1000, 0x7e5a, 0x783b, 0x1700, 0x70a8, 0xa080, 0x00de,
-+	0x781a, 0x2001, 0x0004, 0x0005, 0x789b, 0x0018, 0x78aa, 0x789b,
-+	0x0081, 0x78ab, 0x0001, 0x0005, 0x6904, 0xa18c, 0x00ff, 0xa196,
-+	0x0007, 0x0130, 0xa196, 0x000f, 0x0118, 0x080c, 0x1ca6, 0x0005,
-+	0x6924, 0xa194, 0x003f, 0x1120, 0xa18c, 0xffc0, 0xa105, 0x6826,
-+	0x6a1c, 0xd29c, 0x1530, 0xa086, 0x0001, 0x1518, 0x2001, 0xb341,
-+	0x2004, 0xd094, 0x01f0, 0x0e04, 0x51c1, 0x0156, 0x00e6, 0x0036,
-+	0x0046, 0x0056, 0x2071, 0x0010, 0x7bf0, 0x7af4, 0x7cf8, 0x7dfc,
-+	0x2009, 0x0002, 0xad80, 0x0003, 0x080c, 0x1e7a, 0x005e, 0x004e,
-+	0x003e, 0x00ee, 0x015e, 0x1128, 0x2091, 0x4080, 0x080c, 0x1ca6,
-+	0x0010, 0x080c, 0x4432, 0x691c, 0xa184, 0x0100, 0x0138, 0x6914,
-+	0x2100, 0x080c, 0x449c, 0x6204, 0x8210, 0x6206, 0x0005, 0x692c,
-+	0x6834, 0x682e, 0xa112, 0x6930, 0x6838, 0x6832, 0xa11b, 0xa200,
-+	0xa301, 0x0005, 0x00c6, 0xade0, 0x0018, 0x6003, 0x0070, 0x6106,
-+	0x600b, 0x0000, 0x600f, 0x0a00, 0x6013, 0x0000, 0x6017, 0x0000,
-+	0x8007, 0x601a, 0x601f, 0x0000, 0x6023, 0x0000, 0x00ce, 0x6824,
-+	0xa085, 0x0080, 0x6826, 0x0005, 0x0156, 0x0136, 0x0146, 0x2098,
-+	0xaf80, 0x002d, 0x20a0, 0x81ac, 0x0108, 0x53a6, 0xa184, 0x0001,
-+	0x0110, 0x3304, 0x78be, 0x014e, 0x013e, 0x015e, 0x0005, 0x70a4,
-+	0x00e6, 0x0006, 0x000e, 0x00ee, 0xa005, 0x6918, 0x0016, 0x6914,
-+	0x0016, 0x6928, 0x0016, 0x001e, 0x001e, 0x001e, 0x190c, 0x297f,
-+	0x70a7, 0x8000, 0x6814, 0xd0fc, 0x0110, 0xc185, 0x0008, 0xc184,
-+	0x0804, 0x55dc, 0x0005, 0x71a4, 0x81ff, 0x0140, 0x7848, 0xa085,
-+	0x0008, 0x784a, 0x70a7, 0x0000, 0x080c, 0x52e3, 0x0005, 0x00c6,
-+	0x00d6, 0x080c, 0x1c85, 0x00ce, 0x0156, 0x0136, 0x0146, 0x2da0,
-+	0x2c98, 0x20a9, 0x0037, 0x53a3, 0x014e, 0x013e, 0x015e, 0x6807,
-+	0x010d, 0x680b, 0x0000, 0x701c, 0x8007, 0x681a, 0x6823, 0x0000,
-+	0x681f, 0x0000, 0x689f, 0x0000, 0x00ce, 0x0005, 0x00c6, 0x080c,
-+	0x4fc6, 0x6028, 0xd08c, 0x00ce, 0x0180, 0x7814, 0xa084, 0x0001,
-+	0x0130, 0x70a8, 0xa080, 0x011c, 0x781a, 0x0804, 0x29df, 0x70a8,
-+	0xa080, 0x0135, 0x781a, 0x0804, 0x29df, 0x70a8, 0xa080, 0x00a1,
-+	0x781a, 0x0804, 0x29df, 0x70a8, 0xa080, 0x0092, 0x781a, 0x0804,
-+	0x29df, 0x783b, 0x1700, 0x70a8, 0xa080, 0x00de, 0x781a, 0x0804,
-+	0x29df, 0x70a8, 0xa080, 0x00e7, 0x781a, 0x0804, 0x29df, 0x6904,
-+	0xa18c, 0x00ff, 0xa196, 0x0007, 0x0128, 0xa196, 0x000f, 0x0110,
-+	0x6807, 0x0117, 0x6824, 0xa084, 0x00ff, 0xa085, 0x0200, 0x6826,
-+	0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822,
-+	0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71a8, 0xa188, 0x00a1, 0x791a,
-+	0x0005, 0x080c, 0x5223, 0x7848, 0xa085, 0x000c, 0x784a, 0x70a8,
-+	0xa080, 0x008f, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x080c,
-+	0x51da, 0x2001, 0x0013, 0x080c, 0x5184, 0x0804, 0x44ee, 0x81ff,
-+	0x1110, 0xa21a, 0x0218, 0x080c, 0x20ea, 0x0070, 0x7ad2, 0x7ada,
-+	0x2200, 0x2011, 0x0001, 0x6027, 0x0000, 0x7ad6, 0x78df, 0x0000,
-+	0x7b14, 0xc384, 0x7b16, 0x0088, 0x81ff, 0x1130, 0x6027, 0x0000,
-+	0x7b14, 0xc384, 0x7b16, 0x0020, 0x6126, 0x7b14, 0xc385, 0x7b16,
-+	0x78d2, 0x78da, 0x7ad6, 0x8211, 0x7ade, 0x6232, 0x602e, 0x6028,
-+	0xc085, 0x602a, 0x0005, 0x0126, 0x70f0, 0xa084, 0x4c00, 0x8004,
-+	0x2090, 0x7204, 0x700c, 0xa215, 0x7008, 0xc09c, 0xa205, 0x1138,
-+	0x7007, 0x0004, 0x7003, 0x0000, 0x012e, 0x2000, 0x0005, 0x7000,
-+	0xd084, 0x0580, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184,
-+	0x0003, 0x0904, 0x534b, 0xa184, 0x01e0, 0x1904, 0x534b, 0xd1f4,
-+	0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, 0x2011, 0x0180,
-+	0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, 0x700c, 0xa106,
-+	0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8,
-+	0xa184, 0x0003, 0x0540, 0xd194, 0x0db0, 0xd1f4, 0x0520, 0x7007,
-+	0x0002, 0x0880, 0x7108, 0xd1fc, 0x0130, 0x080c, 0x5484, 0x8aff,
-+	0x0904, 0x52e9, 0x0cb8, 0x700c, 0xa08c, 0x07ff, 0x01c8, 0x7004,
-+	0xd084, 0x0158, 0x7014, 0xa005, 0x1128, 0x7010, 0xa005, 0x0128,
-+	0xa102, 0x1e40, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c,
-+	0x56ad, 0x1de8, 0x09f8, 0x080c, 0x53ee, 0x012e, 0x2000, 0x0005,
-+	0x7204, 0x700c, 0xa215, 0x7108, 0xc19c, 0x8103, 0x1228, 0xa205,
-+	0x1d90, 0x7007, 0x0002, 0x0ca0, 0xa205, 0x1d68, 0x7003, 0x0000,
-+	0x7007, 0x0004, 0x012e, 0x2000, 0x0005, 0x0016, 0x6104, 0xa18c,
-+	0x00ff, 0xa186, 0x0007, 0x0118, 0xa18e, 0x000f, 0x1110, 0x6040,
-+	0x0008, 0x6428, 0x001e, 0x84ff, 0x01f8, 0x2c70, 0x7004, 0xa0bc,
-+	0x000f, 0xa7b8, 0x53a4, 0x273d, 0x87fb, 0x1138, 0x0210, 0x080c,
-+	0x297f, 0x609c, 0xa075, 0x0180, 0x0c88, 0x2705, 0xae68, 0x6808,
-+	0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2705, 0xa005,
-+	0x1da8, 0x709c, 0xa075, 0x1d10, 0x0005, 0x0000, 0x0005, 0x0009,
-+	0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009,
-+	0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x5399, 0x5396, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x5399, 0x0000, 0x53a1, 0x539e, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x53a1, 0x0000, 0x539c, 0x539c, 0x0000,
-+	0x0000, 0x8000, 0x0000, 0x539c, 0x0000, 0x53a2, 0x53a2, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x53a2, 0x2079, 0xb340, 0x2071, 0x0010,
-+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x7808, 0xd0ec,
-+	0x0128, 0x2009, 0x0001, 0x2071, 0x0020, 0x0060, 0x2001, 0x01ff,
-+	0x2004, 0xd0fc, 0x0118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0002,
-+	0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000,
-+	0x8109, 0x0118, 0x2071, 0x0020, 0x0ca8, 0x0005, 0x2019, 0x0000,
-+	0x7004, 0x8004, 0x1a04, 0x545c, 0x7108, 0x7008, 0xa106, 0x1de0,
-+	0xa184, 0x01e0, 0x0120, 0x080c, 0x54be, 0x0804, 0x547c, 0x7007,
-+	0x0012, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
-+	0x080c, 0x54be, 0x7808, 0xd0ec, 0x0188, 0x2001, 0x04fd, 0x2004,
-+	0xa086, 0x0003, 0x1170, 0xa184, 0x4000, 0x0170, 0xa382, 0x0003,
-+	0x1258, 0xa184, 0x0004, 0x0d28, 0x8318, 0x0c18, 0x780c, 0xd0ec,
-+	0x1118, 0xa184, 0x4000, 0x19e8, 0xa19c, 0x300c, 0xa386, 0x2004,
-+	0x0190, 0xa386, 0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108,
-+	0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x54be,
-+	0xa386, 0x200c, 0x1930, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384,
-+	0x07ff, 0x0110, 0x080c, 0x297f, 0x7108, 0x7008, 0xa106, 0x1de0,
-+	0xa184, 0x01e0, 0x0118, 0x080c, 0x54be, 0x0470, 0x7007, 0x0012,
-+	0x7000, 0xd084, 0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c,
-+	0xa184, 0x07ff, 0x1904, 0x53ee, 0x7108, 0x7008, 0xa106, 0x1de0,
-+	0xa184, 0x01e0, 0x0118, 0x080c, 0x54be, 0x00b0, 0x7007, 0x0012,
-+	0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106,
-+	0x1de0, 0xa184, 0x01e0, 0x0118, 0x080c, 0x54be, 0x0028, 0x7007,
-+	0x0012, 0x7108, 0xd1fc, 0x1d88, 0x7003, 0x0000, 0x0005, 0x0156,
-+	0x7108, 0x0011, 0x015e, 0x0005, 0x7204, 0x7500, 0xa184, 0x01e0,
-+	0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
-+	0x549a, 0x54a8, 0x5498, 0x54a8, 0x5498, 0x5508, 0x5498, 0x5506,
-+	0x080c, 0x297f, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
-+	0x1118, 0x2049, 0x0000, 0x0018, 0x080c, 0x56ad, 0x1de8, 0x0005,
-+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
-+	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
-+	0x8aff, 0x0118, 0x080c, 0x56ad, 0x1de8, 0x0005, 0x7007, 0x0012,
-+	0x7108, 0x1d04, 0x54c1, 0x2091, 0x6000, 0x1d04, 0x54c5, 0x2091,
-+	0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
-+	0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
-+	0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
-+	0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
-+	0x0010, 0x2001, 0x0001, 0x080c, 0x3fcf, 0xb284, 0x0200, 0x0118,
-+	0x2001, 0xb3a4, 0x0010, 0x2001, 0xb3e4, 0x2004, 0xa084, 0x8000,
-+	0x0130, 0x6824, 0xa005, 0x1128, 0x6827, 0x0004, 0x0010, 0x681b,
-+	0x0002, 0x0005, 0x080c, 0x297f, 0x080c, 0x297f, 0x080c, 0x5548,
-+	0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
-+	0xa189, 0x0000, 0x04a9, 0x2705, 0x2c58, 0xac60, 0x6308, 0x2200,
-+	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
-+	0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
-+	0x8a07, 0x0006, 0x6004, 0xa084, 0x0008, 0x0118, 0xa7ba, 0x539e,
-+	0x0010, 0xa7ba, 0x5396, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a,
-+	0x6c92, 0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
-+	0x0110, 0x080c, 0x54be, 0x7007, 0x0012, 0x080c, 0x53ee, 0x0005,
-+	0x8a50, 0x8739, 0x2705, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108,
-+	0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x53b4, 0x203d, 0x87fb,
-+	0x090c, 0x297f, 0x0005, 0x0126, 0x00d6, 0x70f0, 0xa084, 0x4c00,
-+	0x8004, 0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
-+	0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084,
-+	0x0008, 0x000e, 0x0118, 0xa0b8, 0x539e, 0x0010, 0xa0b8, 0x5396,
-+	0xb284, 0x0200, 0x0110, 0x7e18, 0x0008, 0x7e1c, 0xa6b5, 0x000c,
-+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0118, 0xa18e, 0x000f,
-+	0x1130, 0x681c, 0xa084, 0x0040, 0x0130, 0xc685, 0x0020, 0x681c,
-+	0xd0b4, 0x0108, 0xc685, 0x700c, 0xa084, 0x07ff, 0x0128, 0x7007,
-+	0x0004, 0x7004, 0xd094, 0x1de8, 0x2400, 0xa305, 0x1108, 0x0420,
-+	0x2c58, 0x2705, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004,
-+	0xa301, 0x701e, 0xa184, 0x0008, 0x0140, 0x6010, 0xa081, 0x0000,
-+	0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202,
-+	0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
-+	0x2b60, 0x080c, 0x56d8, 0x0010, 0x080c, 0x56ad, 0x1de8, 0x012e,
-+	0x2000, 0x0005, 0x0126, 0x00d6, 0x70f0, 0xa084, 0x4c00, 0x8004,
-+	0x2090, 0x00de, 0x7007, 0x0004, 0x7004, 0xd094, 0x1de8, 0x7003,
-+	0x0008, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6, 0x70f0, 0xa084,
-+	0x4c00, 0x8004, 0x2090, 0x00de, 0x700c, 0xa084, 0x07ff, 0x0128,
-+	0x7007, 0x0004, 0x7004, 0xd094, 0x1de8, 0x6814, 0xd0fc, 0x0110,
-+	0x7e1c, 0x0008, 0x7e18, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff,
-+	0xa186, 0x0007, 0x0118, 0xa18e, 0x000f, 0x1140, 0x681c, 0xa084,
-+	0x0040, 0x0108, 0xc685, 0x6840, 0x2050, 0x0030, 0x681c, 0xd0ac,
-+	0x1108, 0xc685, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f,
-+	0xa7b8, 0x53a4, 0x273d, 0x87fb, 0x1138, 0x0210, 0x080c, 0x297f,
-+	0x689c, 0xa065, 0x0120, 0x0c88, 0x080c, 0x56ad, 0x1de8, 0x012e,
-+	0x2000, 0x0005, 0x0126, 0x0006, 0x0016, 0x00d6, 0x70f0, 0xa084,
-+	0x4c00, 0x8004, 0x2090, 0xb284, 0x0200, 0x0110, 0x7e18, 0x0008,
-+	0x7e1c, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c, 0x6904, 0xa18c,
-+	0x00ff, 0xa186, 0x0007, 0x0118, 0xa18e, 0x000f, 0x1130, 0x681c,
-+	0xa084, 0x0040, 0x0130, 0xc685, 0x0020, 0x681c, 0xd0b4, 0x0108,
-+	0xc685, 0x2049, 0x5622, 0x0016, 0x6904, 0xa18c, 0x00ff, 0xa186,
-+	0x0007, 0x0118, 0xa18e, 0x000f, 0x1110, 0x6840, 0x0008, 0x6828,
-+	0x001e, 0xa055, 0x00d6, 0x0904, 0x56a9, 0x2d70, 0x2e60, 0x7004,
-+	0xa0bc, 0x000f, 0xa7b8, 0x53a4, 0x273d, 0x87fb, 0x1140, 0x0210,
-+	0x080c, 0x297f, 0x709c, 0xa075, 0x2060, 0x05d8, 0x0c80, 0x2705,
-+	0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268, 0x8a51, 0x1110,
-+	0x080c, 0x297f, 0x8738, 0x2705, 0xa005, 0x1d90, 0x709c, 0xa075,
-+	0x2060, 0x0538, 0x08e0, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000,
-+	0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1210, 0x080c,
-+	0x297f, 0x0016, 0x3208, 0xa18c, 0x0200, 0x0168, 0x0006, 0x2001,
-+	0xb342, 0x2004, 0xd0ec, 0x000e, 0x0118, 0x2071, 0x0020, 0x0028,
-+	0x2071, 0x0050, 0x0010, 0x2071, 0x0020, 0x001e, 0x00de, 0x0804,
-+	0x5593, 0x00de, 0x012e, 0x2000, 0x0005, 0x7008, 0x0006, 0xa084,
-+	0x01e0, 0x000e, 0x0110, 0xa006, 0x0005, 0xa084, 0x0003, 0xa086,
-+	0x0003, 0x1108, 0x0005, 0x2705, 0xac08, 0x2104, 0x701a, 0x8108,
-+	0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108, 0x2104, 0x7016,
-+	0x6004, 0xa084, 0x0008, 0x0130, 0x8108, 0x2104, 0x7022, 0x8108,
-+	0x2104, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006,
-+	0x8738, 0x2705, 0xa005, 0x1168, 0x609c, 0xa005, 0x01c8, 0x2060,
-+	0x6004, 0xa084, 0x000f, 0xa080, 0x53a4, 0x203d, 0x87fb, 0x090c,
-+	0x297f, 0x8a51, 0x0160, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e,
-+	0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086, 0x0003, 0x0005,
-+	0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, 0x70f0, 0xa084,
-+	0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, 0xa184, 0x0003,
-+	0x1190, 0x0016, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0118,
-+	0xa18e, 0x000f, 0x1110, 0x6840, 0x0008, 0x6828, 0x001e, 0xa005,
-+	0x0178, 0x0804, 0x52f7, 0x7108, 0xd1fc, 0x0118, 0x080c, 0x5484,
-+	0x0c20, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x5484,
-+	0x7008, 0xa086, 0x0008, 0x19c8, 0x7000, 0xa005, 0x19b0, 0x7003,
-+	0x0000, 0x2049, 0x0000, 0x012e, 0x2000, 0x0005, 0x0126, 0x0146,
-+	0x0136, 0x0156, 0x00c6, 0x00d6, 0x70f0, 0xa084, 0x4c00, 0x8004,
-+	0x2090, 0x00de, 0x2049, 0x5736, 0x69b0, 0xad80, 0x0011, 0xa100,
-+	0x20a0, 0xb284, 0x0200, 0x0158, 0x2001, 0xb342, 0x2004, 0xd0ec,
-+	0x0118, 0x2099, 0x0031, 0x0028, 0x2099, 0x0032, 0x0010, 0x2099,
-+	0x0031, 0x700c, 0xa084, 0x07ff, 0x01b0, 0x6928, 0xa100, 0x682a,
-+	0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118, 0x8000,
-+	0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0128, 0x7007, 0x0004,
-+	0x7004, 0xd094, 0x1de8, 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000,
-+	0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005, 0x2091, 0x6000,
-+	0x2091, 0x8000, 0x78ac, 0xa005, 0x1168, 0x796c, 0x70d0, 0xa106,
-+	0x1148, 0x7814, 0xa005, 0x0130, 0x7817, 0x0000, 0x0e04, 0x5792,
-+	0x2091, 0x4080, 0x7824, 0x8001, 0x7826, 0x1904, 0x5806, 0x7828,
-+	0x7826, 0x7808, 0xd0ec, 0x1904, 0x57ff, 0x2061, 0xda00, 0x2069,
-+	0xb3c0, 0xc7fd, 0x68ec, 0xa005, 0x0130, 0x8001, 0x68ee, 0xa005,
-+	0x1110, 0x080c, 0x5995, 0x6800, 0xa084, 0x000f, 0x0168, 0xa086,
-+	0x0001, 0x0150, 0x6840, 0xa00d, 0x0138, 0x2104, 0xa005, 0x0120,
-+	0x8001, 0x200a, 0x0904, 0x5907, 0x6810, 0xa005, 0x01d0, 0x8001,
-+	0x6812, 0x11b8, 0x68c3, 0x0001, 0xd7fc, 0x1148, 0x7808, 0xd0ec,
-+	0x0118, 0x2009, 0x0102, 0x0028, 0x2009, 0x0202, 0x0010, 0x2009,
-+	0x0102, 0x684c, 0xc08d, 0x200a, 0x6868, 0xa005, 0x0110, 0x080c,
-+	0x260c, 0x6884, 0xa005, 0x0140, 0x8001, 0x6886, 0x1128, 0x686b,
-+	0x0000, 0x68f0, 0xc0c5, 0x68f2, 0x68f0, 0xd0fc, 0x01b0, 0xc0fc,
-+	0x68f2, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0158, 0x8001, 0x6036,
-+	0x68f0, 0xc0fd, 0x68f2, 0x1128, 0x6010, 0xa005, 0x0110, 0x080c,
-+	0x260c, 0xace0, 0x0010, 0x1f04, 0x57eb, 0xd7fc, 0x0138, 0x2061,
-+	0xba00, 0x2069, 0xb380, 0xc7fc, 0x0804, 0x57a2, 0x0409, 0x782c,
-+	0x8001, 0x782e, 0x11b8, 0x7830, 0x782e, 0x2061, 0xba00, 0x2069,
-+	0xb380, 0xc7fc, 0x6808, 0xa005, 0x0110, 0x080c, 0x5880, 0xd7fc,
-+	0x1148, 0x7808, 0xd0ec, 0x1130, 0x2061, 0xda00, 0x2069, 0xb3c0,
-+	0xc7fd, 0x0c80, 0x780c, 0xd0e4, 0x1100, 0x2091, 0x8001, 0x0005,
-+	0x7834, 0x8001, 0x7836, 0x1904, 0x587f, 0x7838, 0x7836, 0x2069,
-+	0xb380, 0xc7fc, 0x7808, 0x2079, 0x0200, 0xd0ec, 0x0110, 0x2079,
-+	0x0100, 0x68f8, 0xa005, 0x0138, 0x7de0, 0xa504, 0x1120, 0x68fa,
-+	0x68f0, 0xc0bc, 0x68f2, 0x2079, 0xb340, 0x680c, 0xa005, 0x1110,
-+	0x2001, 0x0101, 0x8001, 0x680e, 0xd7fc, 0x1118, 0xa080, 0xfa00,
-+	0x0010, 0xa080, 0xfb10, 0x2040, 0x2004, 0xa065, 0x01e0, 0x6024,
-+	0xa005, 0x01b0, 0x8001, 0x6026, 0x1198, 0x6800, 0xa005, 0x0130,
-+	0x6850, 0xac06, 0x1118, 0x080c, 0x5907, 0x0068, 0x6868, 0xa005,
-+	0x0118, 0x6027, 0x0001, 0x0020, 0x080c, 0x58c0, 0x2804, 0x0c28,
-+	0x6000, 0x2c40, 0x0c10, 0xd7fc, 0x1150, 0x7808, 0xd0ec, 0x1138,
-+	0x2069, 0xb3c0, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x5839, 0x0005,
-+	0xa00e, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, 0x6024, 0xa005,
-+	0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, 0xd084, 0x1110,
-+	0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, 0x00d6, 0x00c6,
-+	0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, 0x3be8, 0x2d00,
-+	0x2c68, 0x2060, 0x080c, 0x1d3b, 0x080c, 0x2076, 0x001e, 0x00ce,
-+	0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d,
-+	0x0100, 0xace0, 0x0010, 0x1f04, 0x5883, 0xa184, 0x0001, 0x0130,
-+	0xa18c, 0xfffe, 0x690a, 0x080c, 0x260c, 0x0008, 0x690a, 0x0005,
-+	0x2c00, 0x6882, 0x6714, 0x6f7a, 0x6017, 0x0000, 0x602b, 0x0000,
-+	0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
-+	0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6860, 0xac06,
-+	0x1110, 0x2800, 0x6862, 0x080c, 0x1cc4, 0x6818, 0xa005, 0x0530,
-+	0x8001, 0x681a, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x8001,
-+	0x03e8, 0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c,
-+	0x2085, 0xd7fc, 0x1118, 0x2069, 0xb380, 0x0010, 0x2069, 0xb3c0,
-+	0x690c, 0xa184, 0x0100, 0x2001, 0x0006, 0x1128, 0x6883, 0x0000,
-+	0x697e, 0x2001, 0x0004, 0x2708, 0x080c, 0x2601, 0x0005, 0x00d6,
-+	0x00e6, 0x2d70, 0xd7fc, 0x1148, 0x7808, 0xd0ec, 0x0118, 0x2069,
-+	0x0100, 0x0028, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x7000,
-+	0xa084, 0x000f, 0x0904, 0x595c, 0xa086, 0x0007, 0x1140, 0x00f6,
-+	0x2d78, 0x7094, 0x2068, 0x080c, 0x4361, 0x00fe, 0x04a8, 0x7050,
-+	0x2060, 0x080c, 0x2899, 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00,
-+	0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f,
-+	0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830,
-+	0xd0b4, 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094,
-+	0x0110, 0x1f04, 0x5946, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848,
-+	0xd084, 0x0110, 0x1f04, 0x594f, 0x20a9, 0x00fa, 0x1f04, 0x5956,
-+	0x681b, 0x0050, 0x706b, 0x0007, 0x00ee, 0x00de, 0x0005, 0x2079,
-+	0xb340, 0x0441, 0x0089, 0x00d9, 0x2009, 0x0002, 0x2069, 0xb3c0,
-+	0x680b, 0x0000, 0x680f, 0x0000, 0x6813, 0x0000, 0x8109, 0x0118,
-+	0x2069, 0xb380, 0x0ca8, 0x0005, 0x7808, 0xd0ec, 0x0118, 0x2019,
-+	0x00cc, 0x0010, 0x2019, 0x007b, 0x7b2e, 0x7b32, 0x0005, 0x780c,
-+	0xd0e4, 0x1118, 0x2019, 0x0040, 0x0010, 0x2019, 0x0026, 0x7b36,
-+	0x7b3a, 0x0005, 0x780c, 0xd0e4, 0x1118, 0x2019, 0x3f94, 0x0010,
-+	0x2019, 0x2624, 0x7b26, 0x7b2a, 0x0005, 0x6a54, 0xa285, 0x0000,
-+	0x01f0, 0x6958, 0x6bdc, 0xa300, 0x00c6, 0x2164, 0x6304, 0x83ff,
-+	0x1138, 0x8211, 0x0148, 0x8108, 0xa11a, 0x0eb8, 0x69dc, 0x0ca8,
-+	0x68ef, 0x000a, 0x00ce, 0x0005, 0x6954, 0x6adc, 0x2264, 0x6008,
-+	0xc0b5, 0x600a, 0x8210, 0x8109, 0x1dc8, 0x6956, 0x00ce, 0x0005,
-+	0x1d04, 0x59b8, 0x2091, 0x6000, 0x1d04, 0x59bc, 0x2091, 0x6000,
-+	0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0508, 0x0410, 0x2008, 0x7808,
-+	0xd0ec, 0x0158, 0xd1c4, 0x15b8, 0x780c, 0xc0c5, 0x780e, 0x7808,
-+	0xc0f5, 0x780a, 0xd0ec, 0x0558, 0x0438, 0xae8e, 0x0100, 0x0138,
-+	0x780c, 0xc0f5, 0xc0c5, 0x780e, 0xd0d4, 0x1508, 0x00e8, 0x780c,
-+	0xc0fd, 0xc0c5, 0x780e, 0xd0d4, 0x11d0, 0x00b0, 0xd0e4, 0x01c8,
-+	0x1d04, 0x59e8, 0x2091, 0x6000, 0x2009, 0x000c, 0x1d04, 0x59ee,
-+	0x2091, 0x6000, 0x8109, 0x1dd0, 0x70e4, 0xa084, 0x01ff, 0xa086,
-+	0x01ff, 0x1110, 0x70ec, 0x0850, 0x7804, 0xd08c, 0x0110, 0x681b,
-+	0x000c, 0x70a0, 0x70a2, 0x0005, 0x0020, 0x002b, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
-+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014,
-+	0x0014, 0x9851, 0x0014, 0x0014, 0x98f4, 0x98e1, 0x0014, 0x0014,
-+	0x0014, 0x0080, 0x01a3, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120,
-+	0x4022, 0xf880, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+	0x0000, 0x0000, 0x0000, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014,
-+	0xa200, 0x0214, 0xa202, 0x3806, 0x8839, 0x20c3, 0x0864, 0xa838,
-+	0x28c1, 0x9cc2, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300,
-+	0x1856, 0x883a, 0xa804, 0x28f2, 0x9ca6, 0xa8f4, 0x300c, 0x28e1,
-+	0x9ca6, 0x28a2, 0x7162, 0xa820, 0x2822, 0xa207, 0x64a7, 0x2882,
-+	0x7163, 0xa81a, 0x2001, 0xa80f, 0xa206, 0x64c0, 0x6de0, 0x67a0,
-+	0x6fc0, 0x882b, 0x1814, 0x883b, 0x7824, 0x68c1, 0x7864, 0x883e,
-+	0xa802, 0x8576, 0x8677, 0x206c, 0x28c1, 0x9cc2, 0x2045, 0x2104,
-+	0x20a1, 0x2080, 0x7961, 0xa8db, 0xa209, 0x0904, 0xa20e, 0xa808,
-+	0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xc601, 0xa20a,
-+	0x8000, 0x85a1, 0x806f, 0x9422, 0x84a2, 0x856e, 0x0704, 0x9ca6,
-+	0x0014, 0xa204, 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f,
-+	0x08e6, 0xa8f7, 0xf881, 0xa8eb, 0xc007, 0xf8c1, 0x0016, 0x85b2,
-+	0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014,
-+	0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008,
-+	0x1dc1, 0x0016, 0x8160, 0x842a, 0x8190, 0xf041, 0x3008, 0x84a8,
-+	0x11d7, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x3008,
-+	0x2846, 0x1011, 0xa8fd, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa88f,
-+	0x20a1, 0x283d, 0x1011, 0xa8fc, 0xa20b, 0x0017, 0x300c, 0xa300,
-+	0x1de2, 0xd387, 0x0210, 0xa800, 0x26e0, 0x873a, 0xfb02, 0x19f2,
-+	0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cc7, 0x0704, 0x0017,
-+	0x60ff, 0x300c, 0x807f, 0x9521, 0x85a1, 0x806f, 0x9422, 0x84a2,
-+	0x8720, 0xa211, 0x9d72, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d3,
-+	0x78e2, 0x9d76, 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa820, 0x0014,
-+	0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820,
-+	0xa80f, 0x2301, 0xa80d, 0x10d3, 0x78e4, 0x9d76, 0x8821, 0x8820,
-+	0xa8e6, 0xf123, 0xf142, 0xf101, 0xa865, 0x10d3, 0x70f6, 0x8832,
-+	0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6848, 0x0214, 0x8827,
-+	0x300a, 0x0013, 0xa21b, 0x9d72, 0x2001, 0xa853, 0x8201, 0x1852,
-+	0xd183, 0x8834, 0x8001, 0xa801, 0x3027, 0x84a8, 0x1a56, 0x8833,
-+	0x0014, 0xa218, 0x6981, 0x9d7d, 0x6926, 0x6908, 0x8080, 0x9521,
-+	0xc003, 0x1ab4, 0xa809, 0xa80a, 0x1a34, 0xa806, 0x8080, 0x9521,
-+	0xc002, 0x1a94, 0xa801, 0x1a14, 0x7021, 0x0014, 0xa300, 0x69e4,
-+	0x8023, 0x16e1, 0x8001, 0x10f1, 0x6946, 0xa213, 0x1462, 0xa213,
-+	0x8000, 0x16e1, 0xa808, 0x6161, 0x0014, 0xa214, 0x61c2, 0x8002,
-+	0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827, 0x0012, 0x8080,
-+	0x940c, 0xc81d, 0x8001, 0x8492, 0x0013, 0x8000, 0x84a4, 0x8190,
-+	0x0016, 0x11c3, 0x211e, 0x870e, 0xa21d, 0x0014, 0x9d7d, 0x0014,
-+	0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212,
-+	0x9d72, 0x10d3, 0x70e4, 0x0004, 0x800f, 0x9426, 0xcc1a, 0x9d76,
-+	0xa8f8, 0x878e, 0x0016, 0xa21c, 0x1035, 0x7965, 0x8001, 0x9405,
-+	0xc001, 0xa817, 0xa82f, 0xa8a5, 0xa210, 0x3807, 0x300c, 0x807f,
-+	0x9521, 0x85a1, 0x806f, 0x9422, 0x84a2, 0x817e, 0x872b, 0x8772,
-+	0x7965, 0x8001, 0x9405, 0xc001, 0xa804, 0xa81c, 0xa892, 0x0014,
-+	0xa8a6, 0xa21f, 0x8080, 0xa521, 0x85a1, 0x8090, 0xa422, 0x84a2,
-+	0x6981, 0x9d7d, 0x6923, 0x6903, 0x18b4, 0xa802, 0xa809, 0x1894,
-+	0x807f, 0x9521, 0x85a1, 0x806f, 0x9422, 0x84a2, 0x7021, 0x0014,
-+	0xa300, 0x0014, 0xa220, 0x8080, 0xa521, 0x85a1, 0x8090, 0xa422,
-+	0x84a2, 0x6981, 0x9d7d, 0x6923, 0x6903, 0x18b4, 0xa802, 0xa80c,
-+	0x1894, 0x807f, 0x9521, 0x85a1, 0x806f, 0x9422, 0x84a2, 0x80fd,
-+	0x9405, 0x8485, 0x7021, 0x0014, 0xa300, 0xa8ca, 0x0000, 0x0710
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_2100.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,8147 @@
-+/* @(#)asm_2100.h 1.5 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+/*
-+ * Some very early boards have problems loading firmware that is larger than
-+ * 0x8000 words. In order to be able to provide at least *some* support
-+ * for such ancient cards, an alternate firmware set is provided. This firmware
-+ * isn't all that great, but, hey, it's better than nothing.
-+ *
-+ * Define USE_SMALLER_2100_FIRMWARE to select this.
-+ */
-+#ifndef	USE_SMALLER_2100_FIRMWARE
-+/************************************************************************
-+ *									*
-+ * 	 --- ISP2100 Fabric Initiator/Target Firmware ---               *
-+ *                   with expanded LUN addressing                       *
-+ *                   and FcTape (FCP-2) support                         *
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 1.19.24 (14:02 Jul 16, 2002)
-+ */
-+static const u_int16_t isp_2100_risc_code[] = {
-+	0x0078, 0x102d, 0x0000, 0x95f1, 0x0000, 0x0001, 0x0013, 0x0018,
-+	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
-+	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
-+	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972,
-+	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-+	0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1,
-+	0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff,
-+	0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04,
-+	0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c,
-+	0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
-+	0x2039, 0x8fff, 0x20a1, 0xad00, 0x2708, 0x810d, 0x810d, 0x810d,
-+	0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
-+	0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
-+	0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
-+	0xa5f1, 0x2009, 0x0000, 0x20a9, 0x070f, 0x41a4, 0x3400, 0x20c9,
-+	0xaaff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x25c7,
-+	0x2051, 0xa600, 0x2a70, 0x7762, 0xa786, 0x8fff, 0x0040, 0x1092,
-+	0x705f, 0xcd00, 0x705b, 0xccf1, 0x7067, 0x0200, 0x706b, 0x0200,
-+	0x0078, 0x109a, 0x705b, 0xbd01, 0x7067, 0x0100, 0x706b, 0x0100,
-+	0x705f, 0xbd00, 0x1078, 0x12df, 0x1078, 0x13ca, 0x1078, 0x1577,
-+	0x1078, 0x1ce9, 0x1078, 0x42ec, 0x1078, 0x76bf, 0x1078, 0x1355,
-+	0x1078, 0x2ac0, 0x1078, 0x4e93, 0x1078, 0x49a3, 0x1078, 0x594a,
-+	0x1078, 0x2263, 0x1078, 0x5c43, 0x1078, 0x5485, 0x1078, 0x2162,
-+	0x1078, 0x2240, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf,
-+	0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068,
-+	0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
-+	0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000,
-+	0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x365e, 0x1078, 0x2ae8,
-+	0x1078, 0x4ee3, 0x1078, 0x4b66, 0x2009, 0x0100, 0x2104, 0xa082,
-+	0x0002, 0x0048, 0x10f3, 0x1078, 0x5966, 0x0078, 0x10d6, 0x1079,
-+	0x10f7, 0x0078, 0x10dc, 0x1078, 0x7197, 0x0078, 0x10eb, 0x1101,
-+	0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078,
-+	0x1332, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086,
-+	0x0001, 0x00c0, 0x1198, 0x1078, 0x3aec, 0x2079, 0x0100, 0x7844,
-+	0xa005, 0x00c0, 0x1198, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x1078,
-+	0x1adf, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
-+	0x8010, 0x73c4, 0x1078, 0x361b, 0x2001, 0xffff, 0x1078, 0x5ae6,
-+	0x723c, 0xc284, 0x723e, 0x2001, 0xa60c, 0x2014, 0xc2ac, 0x2202,
-+	0x1078, 0x6f9f, 0x2011, 0x0004, 0x1078, 0x8d1b, 0x1078, 0x489e,
-+	0x1078, 0x42d4, 0x0040, 0x1144, 0x7087, 0x0001, 0x70bf, 0x0000,
-+	0x1078, 0x3c9e, 0x0078, 0x1198, 0x1078, 0x4967, 0x0040, 0x114d,
-+	0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x90a6, 0x70cc,
-+	0xd09c, 0x00c0, 0x1159, 0x7098, 0xa005, 0x0040, 0x1159, 0x1078,
-+	0x42b8, 0x70d7, 0x0000, 0x70d3, 0x0000, 0x72cc, 0x2079, 0xa652,
-+	0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ce, 0xa296, 0x0004,
-+	0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8d1b, 0x7093, 0x0000,
-+	0x7097, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x2677, 0x2011,
-+	0x0005, 0x1078, 0x70e0, 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100,
-+	0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x7093, 0x0000,
-+	0x7097, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x70e0,
-+	0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
-+	0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
-+	0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
-+	0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f, 0x027f, 0x017f, 0x1078,
-+	0x298e, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706f, 0x0000, 0x7070,
-+	0xa084, 0x00ff, 0x7072, 0x709b, 0x0000, 0x007c, 0x127e, 0x2091,
-+	0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7094, 0xa086,
-+	0xffff, 0x0040, 0x11d1, 0x1078, 0x2677, 0x1078, 0x62d1, 0x0078,
-+	0x1244, 0x70cc, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd,
-+	0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
-+	0x0040, 0x11fd, 0x70d0, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078,
-+	0x27f7, 0x1078, 0x62d1, 0x70cc, 0xd094, 0x00c0, 0x1244, 0x2011,
-+	0x0001, 0x2019, 0x0000, 0x1078, 0x282f, 0x1078, 0x62d1, 0x0078,
-+	0x1244, 0x70d4, 0xa005, 0x00c0, 0x1244, 0x7090, 0xa005, 0x00c0,
-+	0x1244, 0x1078, 0x4967, 0x00c0, 0x1244, 0x2001, 0xa653, 0x2004,
-+	0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
-+	0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0, 0x121a, 0x6000, 0xd0ec,
-+	0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
-+	0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
-+	0x0003, 0x7097, 0xffff, 0x2001, 0x0000, 0x1078, 0x24e8, 0x1078,
-+	0x3699, 0x2001, 0xa8b2, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
-+	0x2011, 0x0000, 0x1078, 0x70e0, 0x2011, 0x0000, 0x1078, 0x70ea,
-+	0x1078, 0x62d1, 0x1078, 0x639b, 0x127f, 0x007c, 0x017e, 0x0f7e,
-+	0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
-+	0x42a1, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040,
-+	0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008,
-+	0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5ae6, 0x7900, 0xa18a,
-+	0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009,
-+	0x00f8, 0x1078, 0x42a1, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
-+	0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0,
-+	0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x24e8, 0x0078,
-+	0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0,
-+	0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f,
-+	0x0000, 0x2009, 0x00f8, 0x1078, 0x42a1, 0x20a9, 0x000e, 0x0005,
-+	0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
-+	0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
-+	0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
-+	0xa632, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
-+	0x200b, 0x0000, 0x1078, 0x2588, 0x2001, 0x0001, 0x1078, 0x24e8,
-+	0x0078, 0x12d3, 0x2001, 0xa632, 0x2003, 0x0000, 0x7828, 0xc09d,
-+	0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
-+	0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
-+	0x2061, 0xa8ad, 0x2063, 0x0001, 0x6007, 0x0013, 0x600b, 0x0018,
-+	0x600f, 0x0017, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
-+	0x12f5, 0x7053, 0xffff, 0x0078, 0x12f7, 0x7053, 0x0000, 0x7057,
-+	0xffff, 0x706f, 0x0000, 0x7073, 0x0000, 0x1078, 0x90a6, 0x2061,
-+	0xa88d, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f,
-+	0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f,
-+	0x07d0, 0x2061, 0xa895, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b,
-+	0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b,
-+	0x0001, 0x601f, 0x0000, 0x2061, 0xa8a5, 0x6003, 0x514c, 0x6007,
-+	0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xa626, 0x2003,
-+	0x0000, 0x007c, 0x2091, 0x8000, 0x0068, 0x1334, 0x007e, 0x017e,
-+	0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x133a, 0x017f, 0x792e,
-+	0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002,
-+	0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa600,
-+	0x7803, 0x0005, 0x0078, 0x1352, 0x007c, 0x2071, 0xa600, 0x715c,
-+	0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048,
-+	0x136b, 0x7060, 0xa302, 0x00c8, 0x136b, 0x220a, 0x2208, 0x2310,
-+	0x8420, 0x0078, 0x135d, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x007c,
-+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa600, 0x70ac, 0xa0ea,
-+	0x0010, 0x00c8, 0x137e, 0xa06e, 0x0078, 0x1388, 0x8001, 0x70ae,
-+	0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000,
-+	0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa600, 0x127e, 0x2091,
-+	0x8000, 0x70ac, 0x8001, 0x00c8, 0x1398, 0xa06e, 0x0078, 0x13a1,
-+	0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807,
-+	0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
-+	0x2071, 0xa600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
-+	0x70ae, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13c0, 0x6804,
-+	0x6807, 0x0000, 0x007e, 0x1078, 0x13a4, 0x0d7f, 0x0078, 0x13b4,
-+	0x007c, 0x0e7e, 0x2071, 0xa600, 0x70ac, 0xa08a, 0x0010, 0xa00d,
-+	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa8d6, 0x7007, 0x0000, 0x701b,
-+	0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004,
-+	0x7012, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x0e7e, 0x2270,
-+	0x700b, 0x0000, 0x2071, 0xa8d6, 0x7018, 0xa088, 0xa8df, 0x220a,
-+	0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, 0x13f6,
-+	0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x127f,
-+	0x007c, 0x0e7e, 0x2071, 0xa8d6, 0x7004, 0xa005, 0x00c0, 0x1406,
-+	0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x007c,
-+	0x7000, 0x0079, 0x140b, 0x140f, 0x1479, 0x1496, 0x1496, 0x7018,
-+	0x711c, 0xa106, 0x00c0, 0x1417, 0x7007, 0x0000, 0x007c, 0x0d7e,
-+	0xa180, 0xa8df, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
-+	0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c,
-+	0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804,
-+	0x0d7f, 0xd084, 0x0040, 0x1439, 0x7007, 0x0001, 0x1078, 0x143e,
-+	0x007c, 0x7007, 0x0002, 0x1078, 0x1454, 0x007c, 0x017e, 0x027e,
-+	0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1449, 0x2110,
-+	0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
-+	0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e,
-+	0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c,
-+	0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1468, 0x2110, 0xa006,
-+	0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300,
-+	0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f,
-+	0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa6fa, 0x20a1, 0x0018,
-+	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
-+	0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b,
-+	0xa6f5, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
-+	0x157e, 0x2001, 0xa729, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
-+	0x2001, 0xa72a, 0x20ac, 0x53a6, 0x2099, 0xa72b, 0x20a1, 0x0018,
-+	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
-+	0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b,
-+	0xa726, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
-+	0x2071, 0xa8d6, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
-+	0xd1fc, 0x0040, 0x14d0, 0xa18c, 0x0700, 0x7004, 0x1079, 0x14d4,
-+	0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1408, 0x14dc, 0x1509, 0x1531,
-+	0x1564, 0x14da, 0x0078, 0x14da, 0xa18c, 0x0700, 0x00c0, 0x1502,
-+	0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803,
-+	0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f,
-+	0x137f, 0x700c, 0xa005, 0x0040, 0x151e, 0x1078, 0x143e, 0x007c,
-+	0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078,
-+	0x1408, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x0078,
-+	0x14fd, 0xa18c, 0x0700, 0x00c0, 0x1514, 0x700c, 0xa005, 0x0040,
-+	0x151e, 0x1078, 0x1454, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
-+	0x0200, 0x7007, 0x0000, 0x1078, 0x1408, 0x007c, 0x0d7e, 0x7008,
-+	0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c,
-+	0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1408,
-+	0x007c, 0xa18c, 0x0700, 0x00c0, 0x155e, 0x137e, 0x147e, 0x157e,
-+	0x2001, 0xa6f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014,
-+	0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xa6fa, 0x2004,
-+	0xd0bc, 0x0040, 0x1554, 0x2001, 0xa703, 0x2004, 0xa080, 0x000d,
-+	0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f, 0x137f, 0x7007,
-+	0x0000, 0x1078, 0x4f8c, 0x1078, 0x1408, 0x007c, 0x2011, 0x8003,
-+	0x1078, 0x361b, 0x0078, 0x1562, 0xa18c, 0x0700, 0x00c0, 0x1571,
-+	0x2001, 0xa728, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1408,
-+	0x007c, 0x2011, 0x8004, 0x1078, 0x361b, 0x0078, 0x1575, 0x127e,
-+	0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa8e7, 0x7803, 0x0004,
-+	0x7003, 0x0000, 0x700f, 0xa8ed, 0x7013, 0xa8ed, 0x780f, 0x0076,
-+	0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079,
-+	0x1591, 0x1599, 0x15df, 0x1599, 0x1599, 0x1599, 0x15c4, 0x15a8,
-+	0x159d, 0xa085, 0x0001, 0x0078, 0x15f9, 0x684c, 0xd0bc, 0x0040,
-+	0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x15e7,
-+	0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1599, 0x684c, 0xd0bc,
-+	0x0040, 0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a,
-+	0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004,
-+	0x6832, 0x6858, 0x0078, 0x15ef, 0xa18c, 0x00ff, 0xa186, 0x0015,
-+	0x00c0, 0x1599, 0x684c, 0xd0ac, 0x0040, 0x1599, 0x6804, 0x681a,
-+	0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004,
-+	0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x15ef, 0x684c,
-+	0xd0ac, 0x0040, 0x1599, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c,
-+	0x000f, 0xa188, 0x206a, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826,
-+	0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980,
-+	0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a,
-+	0x2004, 0x82ff, 0x0040, 0x161c, 0xa280, 0x0004, 0x0d7e, 0x206c,
-+	0x684c, 0xd0dc, 0x00c0, 0x1618, 0x1078, 0x158c, 0x0040, 0x1618,
-+	0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0078, 0x161c,
-+	0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e,
-+	0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0,
-+	0x1630, 0x7206, 0x2001, 0x1651, 0x007e, 0x2260, 0x0078, 0x17e0,
-+	0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
-+	0xa908, 0x0048, 0x163d, 0x2009, 0xa8ed, 0x710e, 0x7010, 0xa102,
-+	0xa082, 0x0009, 0x0040, 0x1648, 0xa080, 0x001b, 0x00c0, 0x164b,
-+	0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, 0x1651, 0x1078,
-+	0x17c1, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, 0x0c7e, 0x007e,
-+	0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f, 0x0d7e, 0x0c7e,
-+	0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005, 0x0040, 0x16dd,
-+	0x6808, 0xa005, 0x0040, 0x174a, 0x7000, 0xa005, 0x00c0, 0x1672,
-+	0x0078, 0x16d2, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1753, 0x7004,
-+	0xa406, 0x00c0, 0x16d2, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040,
-+	0x168f, 0x047e, 0x1078, 0x1913, 0x047f, 0x2460, 0x6010, 0xa080,
-+	0x0002, 0x2004, 0xa005, 0x0040, 0x174a, 0x0078, 0x166c, 0x2001,
-+	0x0207, 0x2004, 0xd09c, 0x00c0, 0x167b, 0x7804, 0xa084, 0x6000,
-+	0x0040, 0x16a0, 0xa086, 0x6000, 0x0040, 0x16a0, 0x0078, 0x167b,
-+	0x7100, 0xa186, 0x0002, 0x00c0, 0x16c0, 0x0e7e, 0x2b68, 0x6818,
-+	0x2060, 0x1078, 0x203f, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0,
-+	0x16b5, 0x7108, 0x720c, 0x0078, 0x16b7, 0x7110, 0x7214, 0x6810,
-+	0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f, 0x0078, 0x16c4,
-+	0xa186, 0x0001, 0x00c0, 0x16cc, 0x7820, 0x6910, 0xa100, 0x6812,
-+	0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000,
-+	0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009,
-+	0x0048, 0x1078, 0x775c, 0x0078, 0x1753, 0x6808, 0xa005, 0x0040,
-+	0x174a, 0x7000, 0xa005, 0x00c0, 0x16e7, 0x0078, 0x174a, 0x700c,
-+	0x7110, 0xa106, 0x00c0, 0x16f0, 0x7004, 0xa406, 0x00c0, 0x174a,
-+	0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x1704, 0x047e, 0x1078,
-+	0x1913, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002, 0x2004, 0xa005,
-+	0x0040, 0x174a, 0x0078, 0x16e1, 0x2001, 0x0207, 0x2004, 0xd09c,
-+	0x00c0, 0x16f0, 0x2001, 0x0005, 0x2004, 0xd08c, 0x00c0, 0x16f6,
-+	0x7804, 0xa084, 0x6000, 0x0040, 0x171b, 0xa086, 0x6000, 0x0040,
-+	0x171b, 0x0078, 0x16f0, 0x7007, 0x0000, 0xa016, 0x2218, 0x7000,
-+	0xa08e, 0x0001, 0x0040, 0x173c, 0xa08e, 0x0002, 0x00c0, 0x174a,
-+	0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x203f, 0x2804, 0xac70,
-+	0x6034, 0xd09c, 0x00c0, 0x1738, 0x7308, 0x720c, 0x0078, 0x173a,
-+	0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, 0x7824, 0xa211,
-+	0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004,
-+	0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009,
-+	0x0048, 0x1078, 0x775c, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e,
-+	0x0e7e, 0x027e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa8e7, 0x7000,
-+	0xa086, 0x0000, 0x0040, 0x17ba, 0x7004, 0xac06, 0x00c0, 0x17ab,
-+	0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040, 0x17ab, 0x7804,
-+	0xd0fc, 0x00c0, 0x17a7, 0x20e1, 0x6000, 0x2011, 0x0032, 0x2001,
-+	0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, 0x00c0, 0x176f,
-+	0x8211, 0x00c0, 0x1777, 0x7804, 0xd0fc, 0x00c0, 0x17a7, 0x1078,
-+	0x1b22, 0x027e, 0x057e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
-+	0x178d, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
-+	0x0000, 0x057f, 0x027f, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001,
-+	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0078, 0x17ab, 0x1078,
-+	0x1913, 0x0078, 0x175f, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa8ed,
-+	0x2104, 0xac06, 0x00c0, 0x17b5, 0x200a, 0xa188, 0x0003, 0x00f0,
-+	0x17b0, 0x157f, 0x057f, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f,
-+	0x007c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x17c9, 0x7003, 0x0000,
-+	0x007c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124,
-+	0x8108, 0xa182, 0xa908, 0x0048, 0x17d7, 0x2009, 0xa8ed, 0x7112,
-+	0x700c, 0xa106, 0x00c0, 0x17e0, 0x2001, 0x0138, 0x2003, 0x0008,
-+	0x8cff, 0x00c0, 0x17e7, 0x1078, 0x1b4d, 0x0078, 0x1854, 0x6010,
-+	0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x17f2, 0x682c, 0xa306,
-+	0x0040, 0x182f, 0x601c, 0xa086, 0x0008, 0x0040, 0x182f, 0x6024,
-+	0xd0f4, 0x00c0, 0x181c, 0xd0d4, 0x0040, 0x1818, 0x6038, 0xa402,
-+	0x6034, 0xa303, 0x0040, 0x1806, 0x00c8, 0x1818, 0x643a, 0x6336,
-+	0x6c2a, 0x6b2e, 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812,
-+	0x2300, 0x6b80, 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x181c,
-+	0x1078, 0x9053, 0x0040, 0x17e3, 0x2001, 0xa674, 0x2004, 0xd0b4,
-+	0x00c0, 0x182b, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x182b, 0x6817,
-+	0x7fff, 0x6813, 0xffff, 0x1078, 0x208a, 0x00c0, 0x17e3, 0x0c7e,
-+	0x7004, 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4,
-+	0x0040, 0x1840, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17e3,
-+	0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc,
-+	0x000f, 0x2009, 0x0011, 0x1078, 0x1855, 0x0040, 0x1853, 0x2009,
-+	0x0001, 0x1078, 0x1855, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18ec,
-+	0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1877, 0xd0f4, 0x00c0,
-+	0x1887, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1867, 0x18ce,
-+	0x188e, 0x188e, 0x18ce, 0x18ce, 0x18c6, 0x18ce, 0x188e, 0x18ce,
-+	0x1894, 0x1894, 0x18ce, 0x18ce, 0x18ce, 0x18bd, 0x1894, 0xc0fc,
-+	0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040,
-+	0x18d1, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0xc0f4,
-+	0x6852, 0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18d8, 0x6b08, 0x6a0c,
-+	0x6d00, 0x6c04, 0x0078, 0x18d1, 0x7b0c, 0xd3bc, 0x0040, 0x18b5,
-+	0x7004, 0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0,
-+	0x18b5, 0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14,
-+	0x82ff, 0x00c0, 0x18b0, 0x6810, 0xa302, 0x0048, 0x18b0, 0x6b10,
-+	0x2011, 0x0000, 0x2468, 0x0078, 0x18b7, 0x6b10, 0x6a14, 0x6d00,
-+	0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0x0d7f, 0x0d7e, 0x6834,
-+	0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x18ce, 0x0d7f, 0x1078,
-+	0x2026, 0x00c0, 0x1855, 0xa00e, 0x0078, 0x18ec, 0x0d7f, 0x1078,
-+	0x1332, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902,
-+	0x7000, 0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c,
-+	0xa201, 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14,
-+	0xa203, 0x6816, 0x1078, 0x2026, 0x007c, 0x1078, 0x1332, 0x1078,
-+	0x1c97, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000,
-+	0x1078, 0x1af4, 0x1078, 0x8d06, 0x0040, 0x190c, 0x6808, 0x8001,
-+	0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f,
-+	0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8a01, 0x0078,
-+	0x1adb, 0x1078, 0x1332, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e,
-+	0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700,
-+	0x00c0, 0x18ef, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x1911,
-+	0x7000, 0x0079, 0x192b, 0x1933, 0x1935, 0x1a34, 0x1ab2, 0x1ac9,
-+	0x1933, 0x1933, 0x1933, 0x1078, 0x1332, 0x8001, 0x7002, 0xa184,
-+	0x0880, 0x00c0, 0x194a, 0x8aff, 0x0040, 0x19d4, 0x2009, 0x0001,
-+	0x1078, 0x1855, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078, 0x1855,
-+	0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0,
-+	0x19b2, 0x027e, 0x037e, 0x017e, 0x7808, 0xd0ec, 0x00c0, 0x1962,
-+	0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004,
-+	0x0078, 0x1964, 0x1078, 0x1bd7, 0x017f, 0xd194, 0x0040, 0x196b,
-+	0x8aff, 0x0040, 0x19a1, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a,
-+	0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060,
-+	0x6024, 0xd0f4, 0x00c0, 0x197e, 0x633a, 0x6236, 0x0c7f, 0x2400,
-+	0x6910, 0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f,
-+	0x027f, 0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x203f, 0x2a00,
-+	0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
-+	0x6808, 0x8001, 0x680a, 0x00c0, 0x19a7, 0x684c, 0xd0e4, 0x0040,
-+	0x19a7, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x7000,
-+	0xa086, 0x0004, 0x0040, 0x1adb, 0x7003, 0x0000, 0x1078, 0x17c1,
-+	0x0078, 0x1adb, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x19b9, 0x1078,
-+	0xa57e, 0x057f, 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078,
-+	0x4963, 0x0040, 0x19c6, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
-+	0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
-+	0x6980, 0x6916, 0x0078, 0x1adb, 0x7004, 0x0c7e, 0x2060, 0x6024,
-+	0x0c7f, 0xd0f4, 0x0040, 0x19e1, 0x6808, 0x8001, 0x680a, 0x0078,
-+	0x19f5, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19f9,
-+	0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19f5, 0x7004,
-+	0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078,
-+	0x1adb, 0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000,
-+	0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa192, 0x0841, 0x00c8,
-+	0x18ef, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104,
-+	0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x1078, 0x1b5e,
-+	0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc,
-+	0x0040, 0x1a1e, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x0076,
-+	0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c,
-+	0x1078, 0x1b92, 0x0040, 0x19f5, 0x8001, 0x7002, 0xd194, 0x0040,
-+	0x1a46, 0x7804, 0xd0fc, 0x00c0, 0x191b, 0x8aff, 0x0040, 0x1adb,
-+	0x2009, 0x0001, 0x1078, 0x1855, 0x0078, 0x1adb, 0xa184, 0x0880,
-+	0x00c0, 0x1a53, 0x8aff, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078,
-+	0x1855, 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc,
-+	0x00c0, 0x1a93, 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1a66,
-+	0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a68, 0x1078, 0x1bd7,
-+	0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x0f7e, 0x2d78, 0x2804,
-+	0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a83, 0x6808, 0x2008, 0xa31a,
-+	0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101,
-+	0x7816, 0x0078, 0x1a8f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213,
-+	0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f,
-+	0x0d7f, 0x0078, 0x196d, 0x057e, 0x7d0c, 0x1078, 0xa57e, 0x057f,
-+	0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4963, 0x0040,
-+	0x1aa4, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff, 0x682f,
-+	0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
-+	0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d,
-+	0x0040, 0x1ac5, 0x6808, 0x8001, 0x680a, 0x00c0, 0x1ac5, 0x7004,
-+	0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078,
-+	0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6010,
-+	0xa005, 0x0040, 0x1ac5, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28,
-+	0x6b2c, 0x1078, 0x17e0, 0x017f, 0x007f, 0x127f, 0x007c, 0x127e,
-+	0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0, 0x1af2, 0x700c,
-+	0x7110, 0xa106, 0x0040, 0x1af2, 0x20e1, 0x9028, 0x700f, 0xa8ed,
-+	0x7013, 0xa8ed, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x1b22, 0x20e1,
-+	0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1b19, 0x2104, 0xa005,
-+	0x0040, 0x1b08, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
-+	0xa188, 0x0003, 0xa182, 0xa908, 0x0048, 0x1b10, 0x2009, 0xa8ed,
-+	0x7112, 0x700c, 0xa106, 0x00c0, 0x1af9, 0x2011, 0x0008, 0x0078,
-+	0x1af9, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0138, 0x2202,
-+	0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2021,
-+	0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x00c0, 0x1b3f, 0x2001,
-+	0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0, 0x1b3f, 0x2001, 0x0111,
-+	0x201c, 0x83ff, 0x00c0, 0x1b3f, 0x8421, 0x00c0, 0x1b29, 0x007c,
-+	0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x00c0, 0x1b4c,
-+	0x8109, 0x00c0, 0x1b44, 0x007c, 0x007c, 0x1078, 0x1b40, 0x0040,
-+	0x1b55, 0x780c, 0xd0a4, 0x0040, 0x1b5b, 0x1078, 0x1af4, 0xa085,
-+	0x0001, 0x0078, 0x1b5d, 0x1078, 0x1b92, 0x007c, 0x0e7e, 0x2071,
-+	0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1b22, 0x2019,
-+	0x5000, 0x8319, 0x0040, 0x1b7c, 0x2001, 0xa908, 0x2004, 0xa086,
-+	0x0000, 0x0040, 0x1b7c, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b69,
-+	0x1078, 0x1eaa, 0x0078, 0x1b67, 0x20e1, 0x7000, 0x7324, 0x7420,
-+	0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f,
-+	0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202,
-+	0x0e7f, 0x007c, 0x027e, 0x2001, 0x015d, 0x2001, 0x0000, 0x7908,
-+	0xa18c, 0x0fff, 0xa182, 0x0ffd, 0x0048, 0x1ba0, 0x2009, 0x0000,
-+	0xa190, 0x0007, 0xa294, 0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001,
-+	0x020a, 0x82ff, 0x0040, 0x1bb5, 0x20e1, 0x6000, 0x200c, 0x200c,
-+	0x200c, 0x200c, 0x8211, 0x00c0, 0x1bae, 0x20e1, 0x7000, 0x200c,
-+	0x200c, 0x7003, 0x0000, 0x20e1, 0x6000, 0x2001, 0x0208, 0x200c,
-+	0x2001, 0x0209, 0x2004, 0xa106, 0x0040, 0x1bd4, 0x1078, 0x1b40,
-+	0x0040, 0x1bd2, 0x7908, 0xd1ec, 0x00c0, 0x1bd4, 0x790c, 0xd1a4,
-+	0x0040, 0x1b97, 0x1078, 0x1af4, 0xa006, 0x027f, 0x007c, 0x7c20,
-+	0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c69,
-+	0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c69, 0x0d7e,
-+	0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c67, 0x681c, 0xa086,
-+	0x0008, 0x0040, 0x1c67, 0x6824, 0xd0d4, 0x00c0, 0x1c67, 0x6810,
-+	0x2068, 0x6850, 0xd0fc, 0x0040, 0x1c29, 0x8108, 0x2104, 0x6b2c,
-+	0xa306, 0x00c0, 0x1c67, 0x8108, 0x2104, 0x6a28, 0xa206, 0x00c0,
-+	0x1c67, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870,
-+	0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034,
-+	0xd09c, 0x0040, 0x1c24, 0x6830, 0x2004, 0xac68, 0x6808, 0x783a,
-+	0x680c, 0x783e, 0x0078, 0x1c65, 0xa006, 0x783a, 0x783e, 0x0078,
-+	0x1c65, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6b2c, 0xa306,
-+	0x00c0, 0x1c67, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6a28,
-+	0xa206, 0x00c0, 0x1c67, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2004,
-+	0x6918, 0xa160, 0xa180, 0x000d, 0x2004, 0xd09c, 0x00c0, 0x1c57,
-+	0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832,
-+	0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0078, 0x1c65, 0x6010,
-+	0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004,
-+	0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f,
-+	0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0x027e, 0x2071, 0xa8e7,
-+	0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x0040,
-+	0x1c92, 0x8211, 0x0040, 0x1c90, 0x2001, 0x0005, 0x2004, 0xd08c,
-+	0x0040, 0x1c79, 0x7904, 0xa18c, 0x0780, 0x017e, 0x1078, 0x1913,
-+	0x017f, 0x81ff, 0x00c0, 0x1c90, 0x2011, 0x0050, 0x0078, 0x1c74,
-+	0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f, 0x0f7f, 0x007c, 0x7803,
-+	0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0040, 0x1ce8, 0x8109,
-+	0x00c0, 0x1c9b, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, 0x1048,
-+	0x1332, 0x1078, 0x1fca, 0x0e7e, 0x0f7e, 0x2071, 0xa8d6, 0x2079,
-+	0x0010, 0x7004, 0xa086, 0x0000, 0x0040, 0x1ce0, 0x7800, 0x007e,
-+	0x7820, 0x007e, 0x7830, 0x007e, 0x7834, 0x007e, 0x7838, 0x007e,
-+	0x783c, 0x007e, 0x7803, 0x0004, 0x7823, 0x0000, 0x0005, 0x0005,
-+	0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x2079, 0x0010,
-+	0x007f, 0x783e, 0x007f, 0x783a, 0x007f, 0x7836, 0x007f, 0x7832,
-+	0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f, 0x0e7f, 0x0078, 0x1ce6,
-+	0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x1078, 0x639b,
-+	0x007c, 0x0e7e, 0x2071, 0xa908, 0x7003, 0x0000, 0x0e7f, 0x007c,
-+	0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1d6b,
-+	0x6934, 0xa184, 0x0007, 0x0079, 0x1cfd, 0x1d05, 0x1d56, 0x1d05,
-+	0x1d05, 0x1d05, 0x1d3b, 0x1d18, 0x1d07, 0x1078, 0x1332, 0x684c,
-+	0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a,
-+	0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1d5e,
-+	0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1d05, 0x684c,
-+	0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a,
-+	0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080,
-+	0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832,
-+	0x6958, 0x0078, 0x1d67, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0,
-+	0x1d6b, 0x684c, 0xd0b4, 0x0040, 0x1e79, 0x6804, 0x681a, 0xa080,
-+	0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832,
-+	0x6958, 0xa006, 0x682e, 0x682a, 0x0078, 0x1d67, 0x684c, 0xd0b4,
-+	0x0040, 0x18ed, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a,
-+	0x6834, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, 0x6926,
-+	0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020,
-+	0x7804, 0xd0fc, 0x10c0, 0x1eaa, 0x0e7e, 0x0d7e, 0x2071, 0xa908,
-+	0x7000, 0xa005, 0x00c0, 0x1df0, 0x0c7e, 0x7206, 0xa280, 0x0004,
-+	0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068,
-+	0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200,
-+	0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68,
-+	0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc,
-+	0x000f, 0x6908, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0007, 0x0040,
-+	0x1db2, 0xa184, 0x0007, 0x0040, 0x1db2, 0x017e, 0x2009, 0x0008,
-+	0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081,
-+	0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c,
-+	0x6814, 0xa106, 0x00c0, 0x1dc9, 0x6928, 0x6810, 0xa106, 0x0040,
-+	0x1dd6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x208a, 0x047f,
-+	0x037f, 0x0040, 0x1dd6, 0x0c7f, 0x0078, 0x1df0, 0x8aff, 0x00c0,
-+	0x1dde, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1df0, 0x127e, 0x2091,
-+	0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0040,
-+	0x1ded, 0x2009, 0x0001, 0x1078, 0x1df4, 0x127f, 0x0c7f, 0xa006,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e,
-+	0x037e, 0x027e, 0x8aff, 0x0040, 0x1e72, 0x700c, 0x7214, 0xa23a,
-+	0x7010, 0x7218, 0xa203, 0x0048, 0x1e71, 0xa705, 0x0040, 0x1e71,
-+	0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1e24, 0x0d7e, 0x2804,
-+	0xac68, 0x2900, 0x0079, 0x1e14, 0x1e53, 0x1e34, 0x1e34, 0x1e53,
-+	0x1e53, 0x1e4b, 0x1e53, 0x1e34, 0x1e53, 0x1e3a, 0x1e3a, 0x1e53,
-+	0x1e53, 0x1e53, 0x1e42, 0x1e3a, 0xc0fc, 0x6852, 0x6b6c, 0x6a70,
-+	0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e57, 0x0d7e, 0x2804, 0xac68,
-+	0x6f08, 0x6e0c, 0x0078, 0x1e56, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
-+	0x0078, 0x1e56, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
-+	0x0078, 0x1e56, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086,
-+	0x001e, 0x00c0, 0x1e53, 0x0d7f, 0x1078, 0x2026, 0x00c0, 0x1dfa,
-+	0xa00e, 0x0078, 0x1e72, 0x0d7f, 0x1078, 0x1332, 0x0d7f, 0x7b22,
-+	0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000,
-+	0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c,
-+	0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x1078, 0x2026, 0x0078,
-+	0x1e72, 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f,
-+	0x007c, 0x1078, 0x1332, 0x027e, 0x2001, 0x0105, 0x2003, 0x0010,
-+	0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
-+	0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x1e92, 0x6850,
-+	0xc0bd, 0x6852, 0x0d7f, 0x0c7e, 0x1078, 0x8a01, 0x0c7f, 0x2001,
-+	0xa8c0, 0x2004, 0xac06, 0x00c0, 0x1ea7, 0x20e1, 0x9040, 0x1078,
-+	0x738a, 0x2011, 0x0000, 0x1078, 0x70ea, 0x1078, 0x639b, 0x027f,
-+	0x0078, 0x1f76, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e,
-+	0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0xa908, 0x2b68,
-+	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
-+	0x1e7b, 0x7000, 0x0079, 0x1ec4, 0x1f76, 0x1ec8, 0x1f43, 0x1f74,
-+	0x8001, 0x7002, 0xd19c, 0x00c0, 0x1edc, 0x8aff, 0x0040, 0x1efb,
-+	0x2009, 0x0001, 0x1078, 0x1df4, 0x0040, 0x1f76, 0x2009, 0x0001,
-+	0x1078, 0x1df4, 0x0078, 0x1f76, 0x7803, 0x0004, 0xd194, 0x0040,
-+	0x1eec, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1ef1, 0x684c,
-+	0xc0f5, 0x684e, 0x0078, 0x1ef1, 0x1078, 0x203f, 0x6850, 0xc0fd,
-+	0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003,
-+	0x0000, 0x0078, 0x1f76, 0x711c, 0x81ff, 0x0040, 0x1f11, 0x7918,
-+	0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002,
-+	0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078,
-+	0x1f76, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079,
-+	0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x037e,
-+	0x2019, 0x1000, 0x8319, 0x1040, 0x1332, 0x7820, 0xd0bc, 0x00c0,
-+	0x1f22, 0x037f, 0x79c8, 0x007f, 0xa102, 0x017f, 0x007e, 0x017e,
-+	0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f, 0x78ca, 0xa284, 0x0004,
-+	0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003,
-+	0x0000, 0x0078, 0x1f76, 0x8001, 0x7002, 0xd194, 0x0040, 0x1f58,
-+	0x7804, 0xd0fc, 0x00c0, 0x1eba, 0xd19c, 0x00c0, 0x1f72, 0x8aff,
-+	0x0040, 0x1f76, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0078, 0x1f76,
-+	0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x2804,
-+	0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f6b, 0x6808, 0xa31a, 0x680c,
-+	0xa213, 0x0078, 0x1f6f, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f,
-+	0x0078, 0x1eec, 0x0078, 0x1eec, 0x1078, 0x1332, 0x0c7f, 0x0d7f,
-+	0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e,
-+	0x2071, 0xa908, 0x7000, 0xa086, 0x0000, 0x0040, 0x1fc7, 0x2079,
-+	0x0020, 0x017e, 0x2009, 0x0207, 0x210c, 0xd194, 0x0040, 0x1fa4,
-+	0x2009, 0x020c, 0x210c, 0xa184, 0x0003, 0x0040, 0x1fa4, 0x1078,
-+	0xa5d2, 0x2001, 0x0133, 0x2004, 0xa005, 0x1040, 0x1332, 0x20e1,
-+	0x9040, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
-+	0x0203, 0x210c, 0xa106, 0x00c0, 0x1faf, 0x20e1, 0x9040, 0x7804,
-+	0xd0fc, 0x0040, 0x1f8a, 0x1078, 0x1eaa, 0x7000, 0xa086, 0x0000,
-+	0x00c0, 0x1f8a, 0x017f, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
-+	0x1fbd, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f,
-+	0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071,
-+	0xa908, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0040, 0x2003,
-+	0x7004, 0x2060, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x1fed,
-+	0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x00c0, 0x1fed,
-+	0x6808, 0x7a18, 0xa206, 0x0040, 0x2009, 0x2001, 0x0105, 0x2003,
-+	0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
-+	0x2060, 0x1078, 0x8a01, 0x20e1, 0x9040, 0x1078, 0x738a, 0x2011,
-+	0x0000, 0x1078, 0x70ea, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x027f,
-+	0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0, 0x1fed, 0x684c, 0xc0dc,
-+	0x684e, 0x2c10, 0x1078, 0x1cf0, 0x2001, 0x0105, 0x2003, 0x0010,
-+	0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x2069, 0xa8b1,
-+	0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x2003, 0x8840, 0x2804,
-+	0xa005, 0x00c0, 0x203a, 0x6004, 0xa005, 0x0040, 0x203c, 0x681a,
-+	0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x206a, 0x2044, 0x88ff,
-+	0x1040, 0x1332, 0x8a51, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50,
-+	0x8841, 0x2804, 0xa005, 0x00c0, 0x2059, 0x2c00, 0xad06, 0x0040,
-+	0x204e, 0x6000, 0xa005, 0x00c0, 0x204e, 0x2d00, 0x2060, 0x681a,
-+	0x6034, 0xa084, 0x000f, 0xa080, 0x207a, 0x2044, 0x88ff, 0x1040,
-+	0x1332, 0x007c, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021,
-+	0x0025, 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027,
-+	0x0000, 0x0000, 0x0000, 0x205f, 0x205b, 0x0000, 0x0000, 0x2069,
-+	0x0000, 0x205f, 0x0000, 0x2066, 0x2063, 0x0000, 0x0000, 0x0000,
-+	0x2069, 0x2066, 0x0000, 0x2061, 0x2061, 0x0000, 0x0000, 0x2069,
-+	0x0000, 0x2061, 0x0000, 0x2067, 0x2067, 0x0000, 0x0000, 0x0000,
-+	0x2069, 0x2067, 0x0a7e, 0x097e, 0x087e, 0x6b2e, 0x6c2a, 0x6858,
-+	0xa055, 0x0040, 0x212d, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0,
-+	0x206a, 0xa986, 0x0007, 0x0040, 0x20a5, 0xa986, 0x000e, 0x0040,
-+	0x20a5, 0xa986, 0x000f, 0x00c0, 0x20a9, 0x605c, 0xa422, 0x6060,
-+	0xa31a, 0x2804, 0xa045, 0x00c0, 0x20b7, 0x0050, 0x20b1, 0x0078,
-+	0x212d, 0x6004, 0xa065, 0x0040, 0x212d, 0x0078, 0x2094, 0x2804,
-+	0xa005, 0x0040, 0x20d5, 0xac68, 0xd99c, 0x00c0, 0x20c5, 0x6808,
-+	0xa422, 0x680c, 0xa31b, 0x0078, 0x20c9, 0x6810, 0xa422, 0x6814,
-+	0xa31b, 0x0048, 0x20f4, 0x2300, 0xa405, 0x0040, 0x20db, 0x8a51,
-+	0x0040, 0x212d, 0x8840, 0x0078, 0x20b7, 0x6004, 0xa065, 0x0040,
-+	0x212d, 0x0078, 0x2094, 0x8a51, 0x0040, 0x212d, 0x8840, 0x2804,
-+	0xa005, 0x00c0, 0x20ee, 0x6004, 0xa065, 0x0040, 0x212d, 0x6034,
-+	0xa0cc, 0x000f, 0xa9c0, 0x206a, 0x2804, 0x2040, 0x2b68, 0x6850,
-+	0xc0fc, 0x6852, 0x0078, 0x2121, 0x8422, 0x8420, 0x831a, 0xa399,
-+	0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, 0xd99c, 0x00c0,
-+	0x210f, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1048,
-+	0x1332, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, 0x211b, 0x6910,
-+	0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, 0x1332, 0x6800,
-+	0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850, 0xc0fd,
-+	0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, 0x6826, 0x007f,
-+	0x007f, 0x007f, 0xa006, 0x0078, 0x2132, 0x087f, 0x097f, 0x0a7f,
-+	0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004, 0xa084, 0x0007,
-+	0x0079, 0x213a, 0x2142, 0x2143, 0x2146, 0x2149, 0x214e, 0x2151,
-+	0x2156, 0x215b, 0x007c, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x1913,
-+	0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x14be,
-+	0x007c, 0x1078, 0x1eaa, 0x1078, 0x14be, 0x007c, 0x1078, 0x1913,
-+	0x1078, 0x14be, 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x1078,
-+	0x14be, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079, 0x0200, 0x2071,
-+	0xab80, 0x2069, 0xa600, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004,
-+	0x1078, 0x251f, 0x781b, 0x0002, 0x20e1, 0x8700, 0x127f, 0x007c,
-+	0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, 0x0079, 0x2180,
-+	0x21a4, 0x2188, 0x218c, 0x2190, 0x2196, 0x219a, 0x219e, 0x21a2,
-+	0x1078, 0x548e, 0x0078, 0x21a4, 0x1078, 0x54da, 0x0078, 0x21a4,
-+	0x1078, 0x548e, 0x1078, 0x54da, 0x0078, 0x21a4, 0x1078, 0x21a6,
-+	0x0078, 0x21a4, 0x1078, 0x21a6, 0x0078, 0x21a4, 0x1078, 0x21a6,
-+	0x0078, 0x21a4, 0x1078, 0x21a6, 0x127f, 0x007c, 0x007e, 0x017e,
-+	0x027e, 0x1078, 0xa5d2, 0x7930, 0xa184, 0x0003, 0x0040, 0x21c9,
-+	0x2001, 0xa8c0, 0x2004, 0xa005, 0x0040, 0x21c5, 0x2001, 0x0133,
-+	0x2004, 0xa005, 0x1040, 0x1332, 0x0c7e, 0x2001, 0xa8c0, 0x2064,
-+	0x1078, 0x8a01, 0x0c7f, 0x0078, 0x21f2, 0x20e1, 0x9040, 0x0078,
-+	0x21f2, 0xa184, 0x0030, 0x0040, 0x21da, 0x6a00, 0xa286, 0x0003,
-+	0x00c0, 0x21d4, 0x0078, 0x21d6, 0x1078, 0x4224, 0x20e1, 0x9010,
-+	0x0078, 0x21f2, 0xa184, 0x00c0, 0x0040, 0x21ec, 0x0e7e, 0x037e,
-+	0x047e, 0x057e, 0x2071, 0xa8e7, 0x1078, 0x1af4, 0x057f, 0x047f,
-+	0x037f, 0x0e7f, 0x0078, 0x21f2, 0xa184, 0x0300, 0x0040, 0x21f2,
-+	0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e,
-+	0x0e7e, 0x0f7e, 0x2071, 0xa600, 0x7128, 0x2001, 0xa890, 0x2102,
-+	0x2001, 0xa898, 0x2102, 0xa182, 0x0211, 0x00c8, 0x220b, 0x2009,
-+	0x0008, 0x0078, 0x2235, 0xa182, 0x0259, 0x00c8, 0x2213, 0x2009,
-+	0x0007, 0x0078, 0x2235, 0xa182, 0x02c1, 0x00c8, 0x221b, 0x2009,
-+	0x0006, 0x0078, 0x2235, 0xa182, 0x0349, 0x00c8, 0x2223, 0x2009,
-+	0x0005, 0x0078, 0x2235, 0xa182, 0x0421, 0x00c8, 0x222b, 0x2009,
-+	0x0004, 0x0078, 0x2235, 0xa182, 0x0581, 0x00c8, 0x2233, 0x2009,
-+	0x0003, 0x0078, 0x2235, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912,
-+	0x7817, 0x0004, 0x1078, 0x251f, 0x0f7f, 0x0e7f, 0x017f, 0x007c,
-+	0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0xa600, 0x6024,
-+	0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb,
-+	0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
-+	0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b,
-+	0x002f, 0x127f, 0x007c, 0x2001, 0xa630, 0x2003, 0x0000, 0x2001,
-+	0xa62f, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e,
-+	0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x227b, 0xa184,
-+	0x0007, 0x0079, 0x2281, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079,
-+	0x2281, 0x22ad, 0x2289, 0x228d, 0x2291, 0x2297, 0x229b, 0x22a1,
-+	0x22a7, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078, 0x5d45, 0x0078,
-+	0x22ad, 0x1078, 0x5d45, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078,
-+	0x22b2, 0x0078, 0x22ad, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x0078,
-+	0x22ad, 0x1078, 0x5d45, 0x1078, 0x22b2, 0x0078, 0x22ad, 0x1078,
-+	0x5d45, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x027f, 0x017f, 0x007f,
-+	0x127f, 0x007c, 0x6124, 0xd1ac, 0x0040, 0x23ac, 0x017e, 0x047e,
-+	0x0c7e, 0x644c, 0xa486, 0xf0f0, 0x00c0, 0x22c5, 0x2061, 0x0100,
-+	0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74c6, 0xa48c, 0xff00,
-+	0x7034, 0xd084, 0x0040, 0x22dd, 0xa186, 0xf800, 0x00c0, 0x22dd,
-+	0x703c, 0xd084, 0x00c0, 0x22dd, 0xc085, 0x703e, 0x037e, 0x2418,
-+	0x2011, 0x8016, 0x1078, 0x361b, 0x037f, 0xa196, 0xff00, 0x0040,
-+	0x231f, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x231f,
-+	0x7130, 0xd184, 0x00c0, 0x231f, 0x2011, 0xa653, 0x2214, 0xd2ec,
-+	0x0040, 0x22fa, 0xc18d, 0x7132, 0x2011, 0xa653, 0x2214, 0xd2ac,
-+	0x00c0, 0x231f, 0x6240, 0xa294, 0x0010, 0x0040, 0x2306, 0x6248,
-+	0xa294, 0xff00, 0xa296, 0xff00, 0x0040, 0x231f, 0x7030, 0xd08c,
-+	0x0040, 0x2371, 0x7034, 0xd08c, 0x00c0, 0x2316, 0x2001, 0xa60c,
-+	0x200c, 0xd1ac, 0x00c0, 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4,
-+	0x2011, 0x8013, 0x1078, 0x361b, 0x037f, 0x0078, 0x2371, 0x7034,
-+	0xd08c, 0x00c0, 0x232b, 0x2001, 0xa60c, 0x200c, 0xd1ac, 0x00c0,
-+	0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, 0x2011, 0x8013, 0x1078,
-+	0x361b, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0xa653, 0x220c,
-+	0xd1a4, 0x0040, 0x2355, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100,
-+	0x1078, 0x5bf1, 0x2019, 0x000e, 0x1078, 0xa195, 0xa484, 0x00ff,
-+	0xa080, 0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006,
-+	0x2009, 0x000e, 0x1078, 0xa21d, 0x017f, 0xd1ac, 0x00c0, 0x2362,
-+	0x017e, 0x2009, 0x0000, 0x2019, 0x0004, 0x1078, 0x284f, 0x017f,
-+	0x0078, 0x2371, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078,
-+	0x45c4, 0x00c0, 0x236d, 0x1078, 0x42f8, 0x8108, 0x00f0, 0x2367,
-+	0x157f, 0x0c7f, 0x047f, 0x0f7e, 0x2079, 0xa8c4, 0x783c, 0xa086,
-+	0x0000, 0x0040, 0x2383, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079,
-+	0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x70e0,
-+	0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019,
-+	0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001,
-+	0xa600, 0x2014, 0xa296, 0x0004, 0x00c0, 0x23a4, 0xd19c, 0x00c0,
-+	0x23ac, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa622,
-+	0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x2490, 0x0f7e,
-+	0x2079, 0xa8c4, 0x783c, 0xa086, 0x0001, 0x00c0, 0x23d0, 0x017e,
-+	0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000,
-+	0x7803, 0x0000, 0x2079, 0xa8b1, 0x7807, 0x0000, 0x7833, 0x0000,
-+	0x1078, 0x62d1, 0x1078, 0x639b, 0x017f, 0x0f7f, 0x0078, 0x2490,
-+	0x0f7f, 0x017e, 0x3900, 0xa082, 0xa9e3, 0x00c8, 0x23db, 0x017e,
-+	0x1078, 0x747a, 0x017f, 0x6220, 0xd2b4, 0x0040, 0x2446, 0x1078,
-+	0x5acb, 0x1078, 0x6e0f, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa8ba,
-+	0x2304, 0xa07d, 0x0040, 0x241c, 0x7804, 0xa086, 0x0032, 0x00c0,
-+	0x241c, 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288,
-+	0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003,
-+	0x8001, 0x00c0, 0x2400, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803,
-+	0x0000, 0x618e, 0x628a, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x7810,
-+	0x2070, 0x7037, 0x0103, 0x2f60, 0x1078, 0x772d, 0x0e7f, 0x0c7f,
-+	0x0d7f, 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140,
-+	0x6804, 0xa084, 0x4000, 0x0040, 0x2429, 0x6803, 0x1000, 0x6803,
-+	0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa8b1, 0x6028, 0xa09a, 0x00c8,
-+	0x00c8, 0x2439, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6e01, 0x0078,
-+	0x248f, 0x2019, 0xa8ba, 0x2304, 0xa065, 0x0040, 0x2443, 0x2009,
-+	0x0027, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x248f, 0xd2bc, 0x0040,
-+	0x248f, 0x1078, 0x5ad8, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e,
-+	0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x245b, 0x6803,
-+	0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa8b1, 0x6044,
-+	0xa09a, 0x00c8, 0x00c8, 0x247e, 0x8000, 0x6046, 0x603c, 0x0c7f,
-+	0xa005, 0x0040, 0x248f, 0x2009, 0x07d0, 0x1078, 0x5ad0, 0xa080,
-+	0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x247a, 0x6017, 0x0012,
-+	0x0078, 0x248f, 0x6017, 0x0016, 0x0078, 0x248f, 0x037e, 0x2019,
-+	0x0001, 0x1078, 0x7058, 0x037f, 0x2019, 0xa8c0, 0x2304, 0xa065,
-+	0x0040, 0x248e, 0x2009, 0x004f, 0x1078, 0x775c, 0x0c7f, 0x017f,
-+	0xd19c, 0x0040, 0x24e4, 0x7034, 0xd0ac, 0x00c0, 0x24c1, 0x017e,
-+	0x157e, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0,
-+	0x249f, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9,
-+	0x0320, 0x00e0, 0x24a9, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0,
-+	0x24b8, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x24e4,
-+	0x1078, 0x2577, 0x00f0, 0x24a9, 0x157f, 0x6152, 0x017f, 0x6027,
-+	0x0008, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078,
-+	0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e,
-+	0x2019, 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x1078,
-+	0xa5ad, 0x1078, 0xa5cb, 0x2001, 0xa600, 0x2003, 0x0004, 0x6027,
-+	0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
-+	0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
-+	0x2071, 0xa600, 0x71bc, 0x70be, 0xa116, 0x0040, 0x2518, 0x81ff,
-+	0x0040, 0x2500, 0x2011, 0x8011, 0x1078, 0x361b, 0x0078, 0x2518,
-+	0x2011, 0x8012, 0x1078, 0x361b, 0x2001, 0xa672, 0x2004, 0xd0fc,
-+	0x00c0, 0x2518, 0x037e, 0x0c7e, 0x1078, 0x6f9f, 0x2061, 0x0100,
-+	0x2019, 0x0028, 0x2009, 0x0000, 0x1078, 0x284f, 0x0c7f, 0x037f,
-+	0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e,
-+	0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x253b, 0x2204,
-+	0x60f2, 0x2011, 0x2548, 0x6000, 0xa082, 0x0003, 0x00c8, 0x2534,
-+	0x2001, 0x00ff, 0x0078, 0x2535, 0x2204, 0x60ee, 0x027f, 0x007f,
-+	0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420,
-+	0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8,
-+	0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff,
-+	0x2130, 0xa094, 0xff00, 0x00c0, 0x2558, 0x81ff, 0x0040, 0x255c,
-+	0x1078, 0x5761, 0x0078, 0x2563, 0xa080, 0x29c0, 0x200c, 0xa18c,
-+	0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x29c0, 0x200c, 0xa18c,
-+	0x00ff, 0x007c, 0x0c7e, 0x2061, 0xa600, 0x6030, 0x0040, 0x2573,
-+	0xc09d, 0x0078, 0x2574, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e,
-+	0x157e, 0x0f7e, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c,
-+	0x00c0, 0x2584, 0x00f0, 0x257e, 0x0f7f, 0x157f, 0x007f, 0x007c,
-+	0x0c7e, 0x007e, 0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e,
-+	0x60e4, 0x007e, 0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e,
-+	0x60ec, 0x007e, 0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e,
-+	0x60e0, 0x007e, 0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005,
-+	0x0005, 0x0005, 0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2,
-+	0x007f, 0x602a, 0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee,
-+	0x007f, 0x60f2, 0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6,
-+	0x007f, 0x604a, 0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x25e7,
-+	0x25eb, 0x25ef, 0x25f5, 0x25fb, 0x2601, 0x2607, 0x260f, 0x2617,
-+	0x261d, 0x2623, 0x262b, 0x2633, 0x263b, 0x2643, 0x264d, 0x2657,
-+	0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657,
-+	0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x107e,
-+	0x007e, 0x0078, 0x2670, 0x107e, 0x007e, 0x0078, 0x2670, 0x107e,
-+	0x007e, 0x1078, 0x226c, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078,
-+	0x226c, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x0078,
-+	0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e,
-+	0x007e, 0x1078, 0x226c, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e,
-+	0x007e, 0x1078, 0x226c, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e,
-+	0x007e, 0x1078, 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078,
-+	0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078,
-+	0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078,
-+	0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x1078,
-+	0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x1078,
-+	0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078,
-+	0x2133, 0x1078, 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078,
-+	0x226c, 0x1078, 0x2133, 0x1078, 0x2178, 0x0078, 0x2670, 0x0005,
-+	0x0078, 0x2657, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x2660,
-+	0x2670, 0x25ed, 0x25f1, 0x25f7, 0x25fd, 0x2603, 0x2609, 0x2611,
-+	0x2619, 0x261f, 0x2625, 0x262d, 0x2635, 0x263d, 0x2645, 0x264f,
-+	0x0008, 0x265a, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e,
-+	0x027e, 0x047e, 0x2021, 0x0000, 0x1078, 0x4967, 0x00c0, 0x2772,
-+	0x70cc, 0xd09c, 0x0040, 0x268e, 0xd084, 0x00c0, 0x268e, 0xd0bc,
-+	0x00c0, 0x2772, 0x1078, 0x2776, 0x0078, 0x2772, 0xd0cc, 0x00c0,
-+	0x2772, 0xd094, 0x0040, 0x2698, 0x7097, 0xffff, 0x0078, 0x2772,
-+	0x2001, 0x010c, 0x203c, 0x7284, 0xd284, 0x0040, 0x2701, 0xd28c,
-+	0x00c0, 0x2701, 0x037e, 0x7394, 0xa38e, 0xffff, 0x0040, 0x26ab,
-+	0x83ff, 0x00c0, 0x26ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xacc0,
-+	0x2c04, 0xa38c, 0x0001, 0x0040, 0x26ba, 0xa084, 0xff00, 0x8007,
-+	0x0078, 0x26bc, 0xa084, 0x00ff, 0xa70e, 0x0040, 0x26f6, 0xa08e,
-+	0x0000, 0x0040, 0x26f6, 0xa08e, 0x00ff, 0x00c0, 0x26d3, 0x7230,
-+	0xd284, 0x00c0, 0x26fc, 0x7284, 0xc28d, 0x7286, 0x7097, 0xffff,
-+	0x037f, 0x0078, 0x2701, 0x2009, 0x0000, 0x1078, 0x254d, 0x1078,
-+	0x455c, 0x00c0, 0x26f9, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
-+	0x00c0, 0x26f0, 0x7030, 0xd08c, 0x0040, 0x26ea, 0x6000, 0xd0bc,
-+	0x0040, 0x26f0, 0x1078, 0x278c, 0x0040, 0x26f9, 0x0078, 0x26f6,
-+	0x1078, 0x28c4, 0x1078, 0x27b9, 0x0040, 0x26f9, 0x8318, 0x0078,
-+	0x26ad, 0x7396, 0x0078, 0x26fe, 0x7097, 0xffff, 0x037f, 0x0078,
-+	0x2772, 0xa780, 0x29c0, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x2041,
-+	0x007e, 0x7094, 0xa096, 0xffff, 0x00c0, 0x2713, 0x2009, 0x0000,
-+	0x28a8, 0x0078, 0x271f, 0xa812, 0x0048, 0x271b, 0x2008, 0xa802,
-+	0x20a8, 0x0078, 0x271f, 0x7097, 0xffff, 0x0078, 0x2772, 0x2700,
-+	0x157e, 0x017e, 0xa106, 0x0040, 0x2766, 0xc484, 0x1078, 0x45c4,
-+	0x0040, 0x2730, 0x1078, 0x455c, 0x00c0, 0x276f, 0x0078, 0x2731,
-+	0xc485, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2740,
-+	0x7030, 0xd08c, 0x0040, 0x275e, 0x6000, 0xd0bc, 0x00c0, 0x275e,
-+	0x7284, 0xd28c, 0x0040, 0x2756, 0x6004, 0xa084, 0x00ff, 0xa082,
-+	0x0006, 0x0048, 0x2766, 0xd484, 0x00c0, 0x2752, 0x1078, 0x457f,
-+	0x0078, 0x2754, 0x1078, 0x298e, 0x0078, 0x2766, 0x1078, 0x28c4,
-+	0x1078, 0x27b9, 0x0040, 0x276f, 0x0078, 0x2766, 0x1078, 0x2959,
-+	0x0040, 0x2766, 0x1078, 0x278c, 0x0040, 0x276f, 0x017f, 0x8108,
-+	0x157f, 0x00f0, 0x271f, 0x7097, 0xffff, 0x0078, 0x2772, 0x017f,
-+	0x157f, 0x7196, 0x047f, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x017e,
-+	0x7097, 0x0001, 0x2009, 0x007e, 0x1078, 0x455c, 0x00c0, 0x2789,
-+	0x1078, 0x28c4, 0x1078, 0x27b9, 0x0040, 0x2789, 0x70cc, 0xc0bd,
-+	0x70ce, 0x017f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
-+	0x2c68, 0x2001, 0xa657, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
-+	0x76c7, 0x0040, 0x27b4, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001,
-+	0x0000, 0x1078, 0x44ee, 0x2001, 0x0000, 0x1078, 0x4502, 0x127e,
-+	0x2091, 0x8000, 0x7090, 0x8000, 0x7092, 0x127f, 0x2009, 0x0004,
-+	0x1078, 0x775c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f,
-+	0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa657,
-+	0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, 0x9187, 0x0040, 0x27f2,
-+	0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e,
-+	0x0040, 0x27db, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-+	0x27db, 0x1078, 0x2880, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
-+	0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x127e, 0x2091, 0x8000,
-+	0x7090, 0x8000, 0x7092, 0x127f, 0x2009, 0x0002, 0x1078, 0x775c,
-+	0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
-+	0x027e, 0x2009, 0x0080, 0x1078, 0x455c, 0x00c0, 0x2805, 0x1078,
-+	0x2808, 0x0040, 0x2805, 0x70d3, 0xffff, 0x027f, 0x0c7f, 0x007c,
-+	0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x76c7, 0x0040,
-+	0x282a, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
-+	0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x127e, 0x2091, 0x8000,
-+	0x70d4, 0x8000, 0x70d6, 0x127f, 0x2009, 0x0002, 0x1078, 0x775c,
-+	0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
-+	0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009, 0x007f, 0x1078, 0x455c,
-+	0x00c0, 0x284b, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x284b, 0x2d00,
-+	0x601a, 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022, 0x1078,
-+	0x775c, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e,
-+	0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078, 0x5f0e, 0x1078, 0x5eae,
-+	0x1078, 0x8068, 0x2130, 0x81ff, 0x0040, 0x2864, 0x20a9, 0x007e,
-+	0x2009, 0x0000, 0x0078, 0x2868, 0x20a9, 0x007f, 0x2009, 0x0000,
-+	0x017e, 0x1078, 0x45c4, 0x00c0, 0x2871, 0x1078, 0x47e9, 0x1078,
-+	0x42f8, 0x017f, 0x8108, 0x00f0, 0x2868, 0x86ff, 0x00c0, 0x287a,
-+	0x1078, 0x119b, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c,
-+	0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0,
-+	0x027e, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000,
-+	0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f, 0x017f, 0x2e60,
-+	0x1078, 0x47e9, 0x6210, 0x6314, 0x1078, 0x42f8, 0x6212, 0x6316,
-+	0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x007e,
-+	0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x28ba, 0x2071,
-+	0xa600, 0x7090, 0xa005, 0x0040, 0x28b7, 0x8001, 0x7092, 0x007f,
-+	0x0e7f, 0x007c, 0x2071, 0xa600, 0x70d4, 0xa005, 0x0040, 0x28b7,
-+	0x8001, 0x70d6, 0x0078, 0x28b7, 0x6000, 0xc08c, 0x6002, 0x007c,
-+	0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x2178,
-+	0x81ff, 0x00c0, 0x28d7, 0x20a9, 0x0001, 0x0078, 0x28f2, 0x2001,
-+	0xa653, 0x2004, 0xd0c4, 0x0040, 0x28ee, 0xd0a4, 0x0040, 0x28ee,
-+	0x047e, 0x6018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427,
-+	0xa006, 0x2009, 0x002d, 0x1078, 0xa21d, 0x047f, 0x20a9, 0x00ff,
-+	0x2011, 0x0000, 0x027e, 0xa28e, 0x007e, 0x0040, 0x2936, 0xa28e,
-+	0x007f, 0x0040, 0x2936, 0xa28e, 0x0080, 0x0040, 0x2936, 0xa288,
-+	0xa735, 0x210c, 0x81ff, 0x0040, 0x2936, 0x8fff, 0x1040, 0x2942,
-+	0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078, 0x4972, 0x0c7f, 0x2019,
-+	0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a,
-+	0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006,
-+	0x00c0, 0x2926, 0x6007, 0x0404, 0x0078, 0x292b, 0x2001, 0x0004,
-+	0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f, 0x017e, 0x2c08, 0x1078,
-+	0x9f8b, 0x017f, 0x077f, 0x2160, 0x1078, 0x47e9, 0x027f, 0x8210,
-+	0x00f0, 0x28f2, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
-+	0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e, 0x2001, 0xa653, 0x2004,
-+	0xd0c4, 0x0040, 0x2955, 0xd0a4, 0x0040, 0x2955, 0xa006, 0x2220,
-+	0x8427, 0x2009, 0x0029, 0x1078, 0xa21d, 0x017f, 0x027f, 0x047f,
-+	0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e, 0x7284, 0x82ff, 0x0040,
-+	0x2987, 0xa290, 0xa653, 0x2214, 0xd2ac, 0x00c0, 0x2987, 0x2100,
-+	0x1078, 0x2564, 0x81ff, 0x0040, 0x2989, 0x2019, 0x0001, 0x8314,
-+	0xa2e0, 0xacc0, 0x2c04, 0xd384, 0x0040, 0x297b, 0xa084, 0xff00,
-+	0x8007, 0x0078, 0x297d, 0xa084, 0x00ff, 0xa116, 0x0040, 0x2989,
-+	0xa096, 0x00ff, 0x0040, 0x2987, 0x8318, 0x0078, 0x296f, 0xa085,
-+	0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f, 0x007c, 0x017e, 0x0c7e,
-+	0x127e, 0x2091, 0x8000, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e,
-+	0x2019, 0x0029, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f,
-+	0x027f, 0x017f, 0xa180, 0xa735, 0x2004, 0xa065, 0x0040, 0x29b7,
-+	0x017e, 0x0c7e, 0x1078, 0x9187, 0x017f, 0x1040, 0x1332, 0x611a,
-+	0x1078, 0x2880, 0x1078, 0x772d, 0x017f, 0x1078, 0x457f, 0x127f,
-+	0x0c7f, 0x017f, 0x007c, 0x2001, 0xa633, 0x2004, 0xd0cc, 0x007c,
-+	0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da,
-+	0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce,
-+	0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5,
-+	0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3,
-+	0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9,
-+	0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b,
-+	0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081,
-+	0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073,
-+	0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69,
-+	0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056,
-+	0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c,
-+	0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c,
-+	0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831,
-+	0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026,
-+	0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017,
-+	0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000,
-+	0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000,
-+	0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300,
-+	0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100,
-+	0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00,
-+	0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800,
-+	0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000,
-+	0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000,
-+	0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500,
-+	0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000,
-+	0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000,
-+	0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000,
-+	0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000,
-+	0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x2071, 0xa682, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a,
-+	0x703e, 0x7033, 0xa692, 0x7037, 0xa692, 0x7007, 0x0001, 0x2061,
-+	0xa6d2, 0x6003, 0x0002, 0x007c, 0x0090, 0x2ae7, 0x0068, 0x2ae7,
-+	0x2071, 0xa682, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2ae7, 0x2a60,
-+	0x7820, 0xa08e, 0x0069, 0x00c0, 0x2bd7, 0x0079, 0x2b6b, 0x007c,
-+	0x2071, 0xa682, 0x7004, 0x0079, 0x2aed, 0x2af1, 0x2af2, 0x2afc,
-+	0x2b0e, 0x007c, 0x0090, 0x2afb, 0x0068, 0x2afb, 0x2b78, 0x7818,
-+	0xd084, 0x0040, 0x2b1a, 0x007c, 0x2b78, 0x2061, 0xa6d2, 0x6008,
-+	0xa08e, 0x0100, 0x0040, 0x2b09, 0xa086, 0x0200, 0x0040, 0x2bcf,
-+	0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068,
-+	0x6834, 0xa086, 0x0103, 0x0040, 0x2b16, 0x007c, 0x2a60, 0x2b78,
-+	0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2b23,
-+	0x61bc, 0x0079, 0x2b2b, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2bcb,
-+	0x61bc, 0x0079, 0x2b6b, 0x2bad, 0x2bdf, 0x2be7, 0x2beb, 0x2bf3,
-+	0x2bf9, 0x2bfd, 0x2c09, 0x2c0d, 0x2c17, 0x2c1b, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2c1f, 0x2bcb, 0x2c2f, 0x2c46, 0x2c5d, 0x2cdd, 0x2ce2,
-+	0x2d0f, 0x2d69, 0x2d7a, 0x2d98, 0x2dd9, 0x2de3, 0x2df0, 0x2e03,
-+	0x2e22, 0x2e2b, 0x2e68, 0x2e6e, 0x2bcb, 0x2e8a, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x2e91, 0x2e9b, 0x2bcb, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2ea3, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x2eb5, 0x2ece, 0x2bcb, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x2ee0, 0x2f37, 0x2f95, 0x2fa9, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x398e, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x2c17, 0x2c1b, 0x2fc0, 0x2bcb, 0x2fcd,
-+	0x3a26, 0x3a83, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb,
-+	0x2bcb, 0x2bcb, 0x2bcb, 0x301a, 0x314f, 0x316b, 0x3177, 0x31da,
-+	0x3233, 0x323e, 0x327d, 0x328c, 0x329b, 0x329e, 0x2fd1, 0x32c2,
-+	0x331e, 0x332b, 0x343c, 0x356f, 0x3599, 0x36a6, 0x2bcb, 0x36b6,
-+	0x36f0, 0x37bf, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x3827, 0x3843,
-+	0x38bd, 0x3977, 0x713c, 0x0078, 0x2bad, 0x2021, 0x4000, 0x1078,
-+	0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x2bba, 0x7818, 0xd084,
-+	0x0040, 0x2bbd, 0x127f, 0x0078, 0x2bb1, 0x7c22, 0x7926, 0x7a2a,
-+	0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091,
-+	0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2baf, 0x2021,
-+	0x4002, 0x0078, 0x2baf, 0x2021, 0x4003, 0x0078, 0x2baf, 0x2021,
-+	0x4005, 0x0078, 0x2baf, 0x2021, 0x4006, 0x0078, 0x2baf, 0xa02e,
-+	0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3604, 0x7823,
-+	0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
-+	0x7930, 0x0078, 0x3608, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078,
-+	0x2bad, 0x7924, 0x2114, 0x0078, 0x2bad, 0x2099, 0x0009, 0x20a1,
-+	0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078,
-+	0x2bad, 0x7824, 0x2060, 0x0078, 0x2c21, 0x2009, 0x0001, 0x2011,
-+	0x0013, 0x2019, 0x0018, 0x783b, 0x0017, 0x0078, 0x2bad, 0x7d38,
-+	0x7c3c, 0x0078, 0x2be1, 0x7d38, 0x7c3c, 0x0078, 0x2bed, 0x2061,
-+	0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0,
-+	0x2c23, 0x2010, 0xa005, 0x0040, 0x2bad, 0x0078, 0x2bd3, 0x2069,
-+	0xa652, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040,
-+	0x2bdb, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006,
-+	0x685a, 0x685e, 0x1078, 0x4eae, 0x0078, 0x2bad, 0x2069, 0xa652,
-+	0x7824, 0x7934, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040, 0x2bdb,
-+	0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a,
-+	0x686e, 0x1078, 0x4a3e, 0x0078, 0x2bad, 0xa02e, 0x2520, 0x81ff,
-+	0x00c0, 0x2bd7, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1,
-+	0xa689, 0x41a1, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020,
-+	0x1078, 0x3604, 0x701b, 0x2c75, 0x007c, 0x6834, 0x2008, 0xa084,
-+	0x00ff, 0xa096, 0x0011, 0x0040, 0x2c85, 0xa096, 0x0019, 0x0040,
-+	0x2c85, 0xa096, 0x0015, 0x00c0, 0x2bd7, 0x810f, 0xa18c, 0x00ff,
-+	0x0040, 0x2bd7, 0x710e, 0x700c, 0x8001, 0x0040, 0x2cb6, 0x700e,
-+	0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020, 0x2061, 0xa6d2,
-+	0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000,
-+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, 0x3604, 0x701b, 0x2ca9,
-+	0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x2cb4,
-+	0xa096, 0x000a, 0x00c0, 0x2bd7, 0x0078, 0x2c8b, 0x7010, 0x2068,
-+	0x6838, 0xc0fd, 0x683a, 0x1078, 0x4431, 0x00c0, 0x2cc4, 0x7007,
-+	0x0003, 0x701b, 0x2cc6, 0x007c, 0x1078, 0x4b51, 0x127e, 0x2091,
-+	0x8000, 0x20a9, 0x0005, 0x2099, 0xa689, 0x530a, 0x2100, 0xa210,
-+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d,
-+	0x2009, 0x0020, 0x127f, 0x0078, 0x3608, 0x61a4, 0x7824, 0x60a6,
-+	0x0078, 0x2bad, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953,
-+	0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832,
-+	0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c,
-+	0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b,
-+	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1,
-+	0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, 0x81ff,
-+	0x00c0, 0x2bd7, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x45c4,
-+	0x00c0, 0x2bdb, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048,
-+	0x2d23, 0x0078, 0x2bdb, 0x7c28, 0x7d2c, 0x1078, 0x47a4, 0xd28c,
-+	0x00c0, 0x2d2e, 0x1078, 0x4736, 0x0078, 0x2d30, 0x1078, 0x4772,
-+	0x00c0, 0x2d5a, 0x2061, 0xad00, 0x127e, 0x2091, 0x8000, 0x6000,
-+	0xa086, 0x0000, 0x0040, 0x2d48, 0x6010, 0xa06d, 0x0040, 0x2d48,
-+	0x683c, 0xa406, 0x00c0, 0x2d48, 0x6840, 0xa506, 0x0040, 0x2d53,
-+	0x127f, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02, 0x00c8,
-+	0x2bd7, 0x0078, 0x2d34, 0x1078, 0x8a01, 0x127f, 0x0040, 0x2bd7,
-+	0x0078, 0x2bad, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x8f85, 0x1078, 0x4a73, 0x127f, 0x0078,
-+	0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, 0x0040, 0x2bdb,
-+	0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078, 0x47b2, 0x0040, 0x2bd7,
-+	0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040,
-+	0x2bdb, 0x1078, 0x482f, 0x0040, 0x2bd7, 0x2019, 0x0005, 0x1078,
-+	0x47d3, 0x0040, 0x2bd7, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb,
-+	0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x5a52, 0x0078, 0x2bad,
-+	0x127e, 0x2091, 0x8000, 0x81ff, 0x0040, 0x2da2, 0x2009, 0x0001,
-+	0x0078, 0x2dd3, 0x2029, 0x00ff, 0x6450, 0x2400, 0xa506, 0x0040,
-+	0x2dcd, 0x2508, 0x1078, 0x45c4, 0x00c0, 0x2dcd, 0x1078, 0x482f,
-+	0x00c0, 0x2db8, 0x2009, 0x0002, 0x62ac, 0x2518, 0x0078, 0x2dd3,
-+	0x2019, 0x0004, 0x1078, 0x47d3, 0x00c0, 0x2dc2, 0x2009, 0x0006,
-+	0x0078, 0x2dd3, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x2dd6, 0x8003,
-+	0x800b, 0x810b, 0xa108, 0x1078, 0x5a52, 0x8529, 0x00c8, 0x2da5,
-+	0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, 0x2bd7, 0x127f, 0x0078,
-+	0x2bdb, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x46e7, 0x1078,
-+	0x47a4, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2,
-+	0x0040, 0x2bdb, 0x1078, 0x46d6, 0x1078, 0x47a4, 0x0078, 0x2bad,
-+	0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078,
-+	0x4775, 0x0040, 0x2bd7, 0x1078, 0x4484, 0x1078, 0x472f, 0x1078,
-+	0x47a4, 0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078,
-+	0x4673, 0x0040, 0x2bd7, 0x62a0, 0x2019, 0x0005, 0x0c7e, 0x1078,
-+	0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078,
-+	0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x1078, 0x47a4,
-+	0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x47a4,
-+	0x2208, 0x0078, 0x2bad, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0xa714,
-+	0x6810, 0x6914, 0xa10a, 0x00c8, 0x2e37, 0x2009, 0x0000, 0x6816,
-+	0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0xa735,
-+	0x2d04, 0xa075, 0x0040, 0x2e4c, 0x704c, 0x1078, 0x2e56, 0xa210,
-+	0x7080, 0x1078, 0x2e56, 0xa318, 0x8d68, 0x00f0, 0x2e40, 0x2300,
-+	0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, 0x2bad, 0x0f7e, 0x017e,
-+	0xa07d, 0x0040, 0x2e65, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff,
-+	0x0040, 0x2e65, 0x2178, 0x0078, 0x2e5d, 0x017f, 0x0f7f, 0x007c,
-+	0x2069, 0xa714, 0x6910, 0x62a8, 0x0078, 0x2bad, 0x81ff, 0x00c0,
-+	0x2bd7, 0x6150, 0xa190, 0x29c0, 0x2214, 0xa294, 0x00ff, 0x6070,
-+	0xa084, 0xff00, 0xa215, 0x636c, 0x67cc, 0xd79c, 0x0040, 0x2e84,
-+	0x2031, 0x0001, 0x0078, 0x2e86, 0x2031, 0x0000, 0x7e3a, 0x7f3e,
-+	0x0078, 0x2bad, 0x6140, 0x6244, 0x2019, 0xa8a2, 0x231c, 0x0078,
-+	0x2bad, 0x127e, 0x2091, 0x8000, 0x6134, 0x6338, 0xa006, 0x2010,
-+	0x127f, 0x0078, 0x2bad, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6244,
-+	0x6338, 0x0078, 0x2bad, 0x6140, 0x6244, 0x7824, 0x6042, 0x7b28,
-+	0x6346, 0x2069, 0xa652, 0x831f, 0xa305, 0x6816, 0x782c, 0x2069,
-+	0xa8a2, 0x2d1c, 0x206a, 0x0078, 0x2bad, 0x017e, 0x127e, 0x2091,
-+	0x8000, 0x7824, 0x6036, 0xd094, 0x0040, 0x2ec8, 0x7828, 0xa085,
-+	0x0001, 0x2009, 0xa8ab, 0x200a, 0x2001, 0xffff, 0x1078, 0x5ae6,
-+	0x782c, 0x603a, 0x127f, 0x017f, 0x0078, 0x2bad, 0x1078, 0x35e4,
-+	0x0040, 0x2bdb, 0x7828, 0xa00d, 0x0040, 0x2bdb, 0x782c, 0xa005,
-+	0x0040, 0x2bdb, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, 0x2bad,
-+	0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e,
-+	0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
-+	0x00c0, 0x2ef7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f06, 0xa182,
-+	0x007f, 0x00c8, 0x2f30, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff,
-+	0x6030, 0xa116, 0x0040, 0x2f30, 0x810f, 0xa105, 0x127e, 0x2091,
-+	0x8000, 0x007e, 0x1078, 0x76c7, 0x007f, 0x0040, 0x2f2c, 0x601a,
-+	0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x35ba, 0x0040, 0x2f33,
-+	0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd,
-+	0x683a, 0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
-+	0x775c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7,
-+	0x0c7f, 0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f2c, 0x2001,
-+	0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e, 0x2061,
-+	0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x00c0,
-+	0x2f4e, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f5d, 0xa182, 0x007f,
-+	0x00c8, 0x2f87, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff, 0x6030,
-+	0xa116, 0x0040, 0x2f87, 0x810f, 0xa105, 0x127e, 0x2091, 0x8000,
-+	0x007e, 0x1078, 0x76c7, 0x007f, 0x0040, 0x2f83, 0x601a, 0x600b,
-+	0xbc05, 0x601f, 0x0001, 0x1078, 0x35ba, 0x0040, 0x2f8a, 0x6837,
-+	0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
-+	0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x775c,
-+	0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7, 0x0c7f,
-+	0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f83, 0x6830, 0xa086,
-+	0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad, 0x2061, 0xa933, 0x127e,
-+	0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2fa6, 0x6104, 0x6208,
-+	0x2019, 0xa612, 0x231c, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078,
-+	0x2bdb, 0x81ff, 0x00c0, 0x2bd7, 0x127e, 0x2091, 0x8000, 0x6248,
-+	0x6064, 0xa202, 0x0048, 0x2fbd, 0xa085, 0x0001, 0x1078, 0x256a,
-+	0x1078, 0x3c9e, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, 0x2bdb,
-+	0x127e, 0x2091, 0x8000, 0x20a9, 0x0012, 0x2001, 0xa640, 0x20a0,
-+	0xa006, 0x40a4, 0x127f, 0x0078, 0x2bad, 0x7d38, 0x7c3c, 0x0078,
-+	0x2c5f, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2bd7,
-+	0x6250, 0xa084, 0xff00, 0x8007, 0xa206, 0x00c0, 0x2fe9, 0x2001,
-+	0xa640, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
-+	0x3608, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb,
-+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2bd7, 0x0c7e,
-+	0x1078, 0x35ba, 0x0c7f, 0x0040, 0x2bd7, 0x6837, 0x0000, 0x6838,
-+	0xc0fd, 0x683a, 0x1078, 0x8e4a, 0x0040, 0x2bd7, 0x7007, 0x0003,
-+	0x701b, 0x300b, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7,
-+	0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-+	0x0078, 0x3608, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x1078, 0x42dd,
-+	0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604,
-+	0x701b, 0x302b, 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040,
-+	0x2bdb, 0x6804, 0xd0ac, 0x0040, 0x3038, 0xd0a4, 0x0040, 0x2bdb,
-+	0xd094, 0x0040, 0x3043, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c,
-+	0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x304e, 0x0c7e, 0x2061,
-+	0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100,
-+	0x210c, 0xa18a, 0x0002, 0x0048, 0x3063, 0xd084, 0x0040, 0x3063,
-+	0x6a28, 0xa28a, 0x007f, 0x00c8, 0x2bdb, 0xa288, 0x29c0, 0x210c,
-+	0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0040, 0x306c, 0x6828, 0xa08a,
-+	0x007f, 0x00c8, 0x2bdb, 0x6052, 0x6808, 0xa08a, 0x0100, 0x0048,
-+	0x2bdb, 0xa08a, 0x0841, 0x00c8, 0x2bdb, 0xa084, 0x0007, 0x00c0,
-+	0x2bdb, 0x680c, 0xa005, 0x0040, 0x2bdb, 0x6810, 0xa005, 0x0040,
-+	0x2bdb, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x2bdb, 0x8001, 0x0040,
-+	0x2bdb, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x2bdb, 0x8001, 0x0040,
-+	0x2bdb, 0x6804, 0xd0fc, 0x0040, 0x30c2, 0x1078, 0x35ba, 0x0040,
-+	0x2bd7, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290,
-+	0x0038, 0xa399, 0x0000, 0x1078, 0x3604, 0x701b, 0x30a8, 0x007c,
-+	0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa66e, 0x2da0,
-+	0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xa672, 0x200c, 0xd1e4,
-+	0x0040, 0x30c2, 0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00,
-+	0x6006, 0x0c7f, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa652, 0x2da0,
-+	0x53a3, 0x6814, 0xa08c, 0x00ff, 0x6142, 0x8007, 0xa084, 0x00ff,
-+	0x6046, 0x1078, 0x4eae, 0x1078, 0x49ce, 0x1078, 0x4a3e, 0x6000,
-+	0xa086, 0x0000, 0x00c0, 0x314d, 0x6808, 0x602a, 0x1078, 0x21f7,
-+	0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f,
-+	0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x30fa,
-+	0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
-+	0x0078, 0x30fc, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312,
-+	0x1078, 0x5b19, 0x6904, 0xd1fc, 0x0040, 0x312f, 0x0c7e, 0x2009,
-+	0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0040, 0x312c, 0x0078,
-+	0x3116, 0x839d, 0x00c8, 0x312c, 0x3508, 0x8109, 0x1078, 0x5480,
-+	0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a,
-+	0xa184, 0x00ff, 0x6006, 0x8108, 0x00c0, 0x312a, 0x6003, 0x0003,
-+	0x0078, 0x312c, 0x6003, 0x0001, 0x00f0, 0x3111, 0x0c7f, 0x0c7e,
-+	0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078,
-+	0x3819, 0x0040, 0x313d, 0x1078, 0x256a, 0x60c0, 0xa005, 0x0040,
-+	0x3149, 0x6003, 0x0001, 0x2091, 0x301d, 0x1078, 0x4224, 0x0078,
-+	0x314d, 0x6003, 0x0004, 0x2091, 0x301d, 0x0078, 0x2bad, 0x6000,
-+	0xa086, 0x0000, 0x0040, 0x2bd7, 0x2069, 0xa652, 0x7830, 0x6842,
-+	0x7834, 0x6846, 0x6804, 0xd0fc, 0x0040, 0x3162, 0x2009, 0x0030,
-+	0x0078, 0x3164, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c,
-+	0x7d38, 0x0078, 0x3608, 0xa006, 0x1078, 0x256a, 0x81ff, 0x00c0,
-+	0x2bd7, 0x1078, 0x42dd, 0x1078, 0x4224, 0x0078, 0x2bad, 0x81ff,
-+	0x00c0, 0x2bd7, 0x6184, 0x81ff, 0x0040, 0x3191, 0x703f, 0x0000,
-+	0x2001, 0xacc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x3608, 0x701b, 0x2baa, 0x127f,
-+	0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0xacc0, 0x20a9, 0x0040,
-+	0x20a1, 0xacc0, 0x2019, 0xffff, 0x43a4, 0x6550, 0xa588, 0x29c0,
-+	0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
-+	0xa506, 0x0040, 0x31c3, 0x1078, 0x45c4, 0x00c0, 0x31c3, 0x6014,
-+	0x821c, 0x0048, 0x31bb, 0xa398, 0xacc0, 0xa085, 0xff00, 0x8007,
-+	0x201a, 0x0078, 0x31c2, 0xa398, 0xacc0, 0x2324, 0xa4a4, 0xff00,
-+	0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x31ca,
-+	0x0078, 0x31a7, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f,
-+	0x20a9, 0x0040, 0x20a1, 0xacc0, 0x2099, 0xacc0, 0x1078, 0x4281,
-+	0x0078, 0x3180, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0c7e, 0x1078,
-+	0x35ba, 0x0c7f, 0x00c0, 0x31e8, 0x2009, 0x0002, 0x0078, 0x2bd7,
-+	0x2001, 0xa653, 0x2004, 0xd0b4, 0x0040, 0x320f, 0x6000, 0xd08c,
-+	0x00c0, 0x320f, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-+	0x320f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8e9e,
-+	0x00c0, 0x3206, 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003,
-+	0x701b, 0x320b, 0x007c, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x20a9,
-+	0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004,
-+	0xac80, 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x4281,
-+	0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0,
-+	0x1078, 0x4281, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c,
-+	0x7d38, 0x0078, 0x3608, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2,
-+	0x0040, 0x2bdb, 0x1078, 0x47bd, 0x0078, 0x2bad, 0x81ff, 0x00c0,
-+	0x2bd7, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, 0x1078, 0x35e4,
-+	0x0040, 0x2bdb, 0x1078, 0x482f, 0x0040, 0x2bd7, 0x2019, 0x0004,
-+	0x1078, 0x47d3, 0x7924, 0x810f, 0x7a28, 0x1078, 0x3259, 0x0078,
-+	0x2bad, 0xa186, 0x00ff, 0x0040, 0x3261, 0x1078, 0x3271, 0x0078,
-+	0x3270, 0x2029, 0x007e, 0x2061, 0xa600, 0x6450, 0x2400, 0xa506,
-+	0x0040, 0x326d, 0x2508, 0x1078, 0x3271, 0x8529, 0x00c8, 0x3266,
-+	0x007c, 0x1078, 0x45c4, 0x00c0, 0x327c, 0x2200, 0x8003, 0x800b,
-+	0x810b, 0xa108, 0x1078, 0x5a52, 0x007c, 0x81ff, 0x00c0, 0x2bd7,
-+	0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7,
-+	0x1078, 0x47c8, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078,
-+	0x35d2, 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078,
-+	0x47b2, 0x0078, 0x2bad, 0x6100, 0x0078, 0x2bad, 0x1078, 0x35e4,
-+	0x0040, 0x2bdb, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0,
-+	0x2bd7, 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x32b2,
-+	0xace8, 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a,
-+	0x6b04, 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200,
-+	0x0078, 0x2bad, 0xa006, 0x1078, 0x256a, 0x7824, 0xa084, 0x00ff,
-+	0xa086, 0x00ff, 0x0040, 0x32cf, 0x81ff, 0x00c0, 0x2bd7, 0x1078,
-+	0x42dd, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, 0x7924, 0xa18c,
-+	0xff00, 0x810f, 0xa186, 0x00ff, 0x0040, 0x32e5, 0xa182, 0x007f,
-+	0x00c8, 0x2bdb, 0x2100, 0x1078, 0x2564, 0x027e, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x2061, 0xa8c4, 0x601b, 0x0000, 0x601f, 0x0000,
-+	0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea,
-+	0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078, 0x7058, 0x037f,
-+	0x2061, 0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a,
-+	0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4259,
-+	0x1078, 0x5add, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078,
-+	0x3259, 0x127f, 0x0c7f, 0x027f, 0x0078, 0x2bad, 0x7924, 0xa18c,
-+	0xff00, 0x810f, 0x0c7e, 0x1078, 0x455c, 0x2c08, 0x0c7f, 0x00c0,
-+	0x2bdb, 0x0078, 0x2bad, 0x81ff, 0x0040, 0x3332, 0x2009, 0x0001,
-+	0x0078, 0x2bd7, 0x60cc, 0xd09c, 0x00c0, 0x333a, 0x2009, 0x0005,
-+	0x0078, 0x2bd7, 0x1078, 0x35ba, 0x00c0, 0x3342, 0x2009, 0x0002,
-+	0x0078, 0x2bd7, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
-+	0x3604, 0x701b, 0x334c, 0x007c, 0x2009, 0x0080, 0x1078, 0x45c4,
-+	0x00c0, 0x3359, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040,
-+	0x335d, 0x2021, 0x400a, 0x0078, 0x2baf, 0x0d7e, 0xade8, 0x000d,
-+	0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be,
-+	0x0100, 0x0040, 0x33d0, 0xa0be, 0x0112, 0x0040, 0x33d0, 0xa0be,
-+	0x0113, 0x0040, 0x33d0, 0xa0be, 0x0114, 0x0040, 0x33d0, 0xa0be,
-+	0x0117, 0x0040, 0x33d0, 0xa0be, 0x011a, 0x0040, 0x33d0, 0xa0be,
-+	0x0121, 0x0040, 0x33c6, 0xa0be, 0x0131, 0x0040, 0x33c6, 0xa0be,
-+	0x0171, 0x0040, 0x33d0, 0xa0be, 0x0173, 0x0040, 0x33d0, 0xa0be,
-+	0x01a1, 0x00c0, 0x3398, 0x6830, 0x8007, 0x6832, 0x0078, 0x33d6,
-+	0xa0be, 0x0212, 0x0040, 0x33cc, 0xa0be, 0x0213, 0x0040, 0x33cc,
-+	0xa0be, 0x0214, 0x0040, 0x33be, 0xa0be, 0x0217, 0x0040, 0x33b8,
-+	0xa0be, 0x021a, 0x00c0, 0x33b1, 0x6838, 0x8007, 0x683a, 0x0078,
-+	0x33d0, 0xa0be, 0x0300, 0x0040, 0x33d0, 0x0d7f, 0x0078, 0x2bdb,
-+	0xad80, 0x0010, 0x20a9, 0x0007, 0x1078, 0x3418, 0xad80, 0x000e,
-+	0x20a9, 0x0001, 0x1078, 0x3418, 0x0078, 0x33d0, 0xad80, 0x000c,
-+	0x1078, 0x3426, 0x0078, 0x33d6, 0xad80, 0x000e, 0x1078, 0x3426,
-+	0xad80, 0x000c, 0x20a9, 0x0001, 0x1078, 0x3418, 0x0c7e, 0x1078,
-+	0x35ba, 0x0040, 0x3409, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119,
-+	0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e,
-+	0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b,
-+	0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
-+	0x6823, 0x0000, 0x6804, 0x2068, 0x1078, 0x8e66, 0x00c0, 0x3404,
-+	0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x340f,
-+	0x007c, 0x0c7f, 0x0d7f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6820,
-+	0xa086, 0x8001, 0x00c0, 0x2bad, 0x2009, 0x0004, 0x0078, 0x2bd7,
-+	0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
-+	0x280a, 0x8108, 0x00f0, 0x341a, 0x017f, 0x007c, 0x017e, 0x0a7e,
-+	0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000,
-+	0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a,
-+	0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x0040, 0x3443, 0x2009,
-+	0x0001, 0x0078, 0x2bd7, 0x60cc, 0xd09c, 0x00c0, 0x344b, 0x2009,
-+	0x0005, 0x0078, 0x2bd7, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f,
-+	0xa182, 0x0080, 0x0048, 0x2bdb, 0xa182, 0x00ff, 0x00c8, 0x2bdb,
-+	0x7a2c, 0x7b28, 0x606c, 0xa306, 0x00c0, 0x3466, 0x6070, 0xa24e,
-+	0x0040, 0x2bdb, 0xa9cc, 0xff00, 0x0040, 0x2bdb, 0x0c7e, 0x1078,
-+	0x350f, 0x2c68, 0x0c7f, 0x0040, 0x349e, 0xa0c6, 0x4000, 0x00c0,
-+	0x3484, 0x0c7e, 0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x489b,
-+	0x00c0, 0x347b, 0xc185, 0x6000, 0xd0bc, 0x0040, 0x3480, 0xc18d,
-+	0x007f, 0x0c7f, 0x0078, 0x349b, 0xa0c6, 0x4007, 0x00c0, 0x348b,
-+	0x2408, 0x0078, 0x349b, 0xa0c6, 0x4008, 0x00c0, 0x3493, 0x2708,
-+	0x2610, 0x0078, 0x349b, 0xa0c6, 0x4009, 0x00c0, 0x3499, 0x0078,
-+	0x349b, 0x2001, 0x4006, 0x2020, 0x0078, 0x2baf, 0x2d00, 0x7022,
-+	0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x76c7, 0x0040,
-+	0x34e4, 0x2d00, 0x601a, 0x2001, 0xa657, 0x2004, 0xa084, 0x00ff,
-+	0x6842, 0x2e58, 0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x35ba, 0x0c7f,
-+	0x2b70, 0x00c0, 0x34c5, 0x1078, 0x772d, 0x0e7f, 0x0c7f, 0x0b7f,
-+	0x017f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6837, 0x0000, 0x2d00,
-+	0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x2880, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000,
-+	0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x2009, 0x0002,
-+	0x1078, 0x775c, 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f,
-+	0x00c0, 0x34ee, 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003,
-+	0x701b, 0x34f3, 0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060,
-+	0x00c0, 0x3501, 0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078,
-+	0x2bd7, 0x2009, 0x0000, 0x1078, 0x489b, 0x00c0, 0x3508, 0xc185,
-+	0x6000, 0xd0bc, 0x0040, 0x350d, 0xc18d, 0x0078, 0x2bad, 0x0e7e,
-+	0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
-+	0xa7b5, 0x2e04, 0xa005, 0x00c0, 0x3524, 0x2100, 0xa406, 0x00c0,
-+	0x3555, 0x2428, 0x0078, 0x3555, 0x2068, 0x6f10, 0x2700, 0xa306,
-+	0x00c0, 0x3546, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x3546, 0x2400,
-+	0xa106, 0x00c0, 0x3542, 0x2d60, 0xd884, 0x0040, 0x356a, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x356a, 0x2001, 0x4000,
-+	0x0078, 0x356b, 0x2001, 0x4007, 0x0078, 0x356b, 0x2400, 0xa106,
-+	0x00c0, 0x3555, 0x6e14, 0x87ff, 0x00c0, 0x3551, 0x86ff, 0x0040,
-+	0x3521, 0x2001, 0x4008, 0x0078, 0x356b, 0x8420, 0x8e70, 0x00f0,
-+	0x3519, 0x85ff, 0x00c0, 0x3564, 0x2001, 0x4009, 0x0078, 0x356b,
-+	0x2001, 0x0001, 0x0078, 0x356b, 0x1078, 0x455c, 0x00c0, 0x3560,
-+	0x6312, 0x6216, 0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff,
-+	0x00c0, 0x2bd7, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x6837, 0x0000,
-+	0x6838, 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0040, 0x2bdb, 0xa096,
-+	0x00ff, 0x0040, 0x3587, 0xa092, 0x0004, 0x00c8, 0x2bdb, 0x2010,
-+	0x2d18, 0x1078, 0x282f, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b,
-+	0x3592, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078,
-+	0x2bad, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048,
-+	0x2bdb, 0xa182, 0x00ff, 0x00c8, 0x2bdb, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x8d4b, 0x00c0, 0x35b7, 0xa190, 0xa735, 0x2204, 0xa065,
-+	0x0040, 0x35b7, 0x1078, 0x42f8, 0x127f, 0x0078, 0x2bad, 0x127f,
-+	0x0078, 0x2bd7, 0x1078, 0x138b, 0x0040, 0x35d1, 0xa006, 0x6802,
-+	0x7010, 0xa005, 0x00c0, 0x35c9, 0x2d00, 0x7012, 0x7016, 0x0078,
-+	0x35cf, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
-+	0x000d, 0x007c, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x45c4,
-+	0x00c0, 0x35e1, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048,
-+	0x35e2, 0xa066, 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff,
-+	0x1078, 0x45c4, 0x00c0, 0x35f2, 0xa6b4, 0x00ff, 0xa682, 0x4000,
-+	0x0048, 0x35f3, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff,
-+	0x0040, 0x3600, 0x2168, 0x6904, 0x1078, 0x13a4, 0x0078, 0x35f7,
-+	0x7112, 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x360a,
-+	0x2031, 0x0000, 0x2061, 0xa6d2, 0x6606, 0x6112, 0x600e, 0x6226,
-+	0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002,
-+	0x701b, 0x2bad, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079,
-+	0x0000, 0x2001, 0xa690, 0x2004, 0xa005, 0x00c0, 0x3636, 0x0068,
-+	0x3636, 0x7818, 0xd084, 0x00c0, 0x3636, 0x7a22, 0x7b26, 0x7c2a,
-+	0x781b, 0x0001, 0x2091, 0x4080, 0x0078, 0x365b, 0x017e, 0x0c7e,
-+	0x0e7e, 0x2071, 0xa682, 0x7138, 0xa182, 0x0008, 0x0048, 0x3644,
-+	0x7030, 0x2060, 0x0078, 0x3655, 0x7030, 0xa0e0, 0x0008, 0xac82,
-+	0xa6d2, 0x0048, 0x364d, 0x2061, 0xa692, 0x2c00, 0x7032, 0x81ff,
-+	0x00c0, 0x3653, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a,
-+	0x0e7f, 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071,
-+	0xa682, 0x7038, 0xa005, 0x0040, 0x3697, 0x127e, 0x2091, 0x8000,
-+	0x0068, 0x3696, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0,
-+	0x3695, 0x0c7e, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
-+	0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
-+	0x703a, 0xa005, 0x00c0, 0x368b, 0x7033, 0xa692, 0x7037, 0xa692,
-+	0x0c7f, 0x0078, 0x3695, 0xac80, 0x0008, 0xa0fa, 0xa6d2, 0x0048,
-+	0x3693, 0x2001, 0xa692, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f,
-+	0x007c, 0x027e, 0x2001, 0xa653, 0x2004, 0xd0c4, 0x0040, 0x36a4,
-+	0x2011, 0x8014, 0x1078, 0x361b, 0x027f, 0x007c, 0x81ff, 0x00c0,
-+	0x2bd7, 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac,
-+	0x6032, 0x1078, 0x4224, 0x127f, 0x0078, 0x2bad, 0x81ff, 0x00c0,
-+	0x2bd7, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x2001, 0xa653,
-+	0x2004, 0xd0ac, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb,
-+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x36d3, 0x7828,
-+	0xa005, 0x0040, 0x2bad, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, 0x0040,
-+	0x2bd7, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
-+	0x1078, 0x8f12, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x36e9,
-+	0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad,
-+	0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x7f24,
-+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x35ba, 0x0040, 0x2bd7,
-+	0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000,
-+	0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x45c4, 0x00c0, 0x376d,
-+	0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0040, 0x371d, 0xa0c4,
-+	0xff00, 0xa8c6, 0x0600, 0x00c0, 0x376d, 0x2001, 0xa653, 0x2004,
-+	0xd0ac, 0x00c0, 0x372a, 0x1078, 0x489b, 0x00c0, 0x372a, 0xd79c,
-+	0x0040, 0x376d, 0xd794, 0x00c0, 0x3730, 0xd784, 0x0040, 0x373c,
-+	0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078,
-+	0x3426, 0xd794, 0x0040, 0x3745, 0xac80, 0x000a, 0x2098, 0x3400,
-+	0x20a9, 0x0004, 0x53a3, 0x1078, 0x3426, 0x21a2, 0xd794, 0x0040,
-+	0x3765, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, 0x53a3,
-+	0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, 0x3400,
-+	0x20a9, 0x0002, 0x53a3, 0x1078, 0x3418, 0xac80, 0x0026, 0x2098,
-+	0x20a9, 0x0002, 0x53a3, 0x0078, 0x3766, 0x94a0, 0xd794, 0x0040,
-+	0x376b, 0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0xd78c, 0x0040,
-+	0x3777, 0xa186, 0x0100, 0x0040, 0x3788, 0x0078, 0x377b, 0xa186,
-+	0x007e, 0x0040, 0x3788, 0xd794, 0x0040, 0x3782, 0xa686, 0x0020,
-+	0x0078, 0x3784, 0xa686, 0x0028, 0x0040, 0x3791, 0x0078, 0x370c,
-+	0x86ff, 0x00c0, 0x378f, 0x7120, 0x810b, 0x0078, 0x2bad, 0x702f,
-+	0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xa6d2,
-+	0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e,
-+	0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x37a9,
-+	0x007c, 0x702c, 0xa005, 0x00c0, 0x37bb, 0x711c, 0x7024, 0x20a0,
-+	0x7728, 0x2031, 0x0000, 0x2061, 0xa6d2, 0x6224, 0x6328, 0x642c,
-+	0x6530, 0x0078, 0x370c, 0x7120, 0x810b, 0x0078, 0x2bad, 0x2029,
-+	0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007,
-+	0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa184,
-+	0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb,
-+	0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502,
-+	0x0048, 0x2bdb, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb,
-+	0xa502, 0x0048, 0x2bdb, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020,
-+	0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa384, 0x00ff, 0xa0e2,
-+	0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa484, 0xff00,
-+	0x8007, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb,
-+	0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048,
-+	0x2bdb, 0x2061, 0xa8a5, 0x6102, 0x6206, 0x630a, 0x640e, 0x0078,
-+	0x2bad, 0x007e, 0x2001, 0xa653, 0x2004, 0xd0cc, 0x007f, 0x007c,
-+	0x007e, 0x2001, 0xa672, 0x2004, 0xd0bc, 0x007f, 0x007c, 0x6164,
-+	0x7a24, 0x6300, 0x82ff, 0x00c0, 0x3830, 0x7926, 0x0078, 0x2bad,
-+	0x83ff, 0x00c0, 0x2bdb, 0x2001, 0xfff0, 0xa200, 0x00c8, 0x2bdb,
-+	0x2019, 0xffff, 0x6068, 0xa302, 0xa200, 0x0048, 0x2bdb, 0x7926,
-+	0x6266, 0x0078, 0x2bad, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003,
-+	0x00c0, 0x2bd7, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x1078, 0x35ba,
-+	0x0040, 0x2bd7, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, 0x0000,
-+	0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xa735,
-+	0x2c64, 0x8cff, 0x0040, 0x387d, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x0040, 0x3872, 0x6004, 0xa084, 0xff00, 0xa086, 0x0600,
-+	0x00c0, 0x387d, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105,
-+	0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff,
-+	0x0040, 0x3888, 0xa386, 0x002a, 0x0040, 0x3891, 0x0078, 0x385e,
-+	0x83ff, 0x00c0, 0x388f, 0x7120, 0x810c, 0x0078, 0x2bad, 0x702f,
-+	0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0xa6d2, 0x6007,
-+	0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732,
-+	0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x38a8, 0x007c,
-+	0x702c, 0xa005, 0x00c0, 0x38b9, 0x711c, 0x7024, 0x20a0, 0x2019,
-+	0x0000, 0x2061, 0xa6d2, 0x6424, 0x6528, 0x662c, 0x6730, 0x0078,
-+	0x385e, 0x7120, 0x810c, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7,
-+	0x60cc, 0xd09c, 0x0040, 0x2bd7, 0x1078, 0x35ba, 0x0040, 0x2bd7,
-+	0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, 0x701b,
-+	0x38d2, 0x007c, 0x0d7e, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000,
-+	0x0040, 0x38e5, 0xa0be, 0x7100, 0x0040, 0x38e5, 0xa0be, 0x7200,
-+	0x0040, 0x38e5, 0x0d7f, 0x0078, 0x2bdb, 0x6820, 0x6924, 0x1078,
-+	0x254d, 0x00c0, 0x3910, 0x1078, 0x455c, 0x00c0, 0x3910, 0x7122,
-+	0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, 0x35ba, 0x0040, 0x3910,
-+	0x1078, 0x35ba, 0x0040, 0x3910, 0x0c7f, 0x0d7f, 0x6837, 0x0000,
-+	0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x1078,
-+	0x8e82, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3913, 0x007c,
-+	0x0d7f, 0x0078, 0x2bd7, 0x7120, 0x1078, 0x298e, 0x6820, 0xa086,
-+	0x8001, 0x0040, 0x2bd7, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
-+	0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x4281, 0x007f,
-+	0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xa6d2,
-+	0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x00c0, 0x393a,
-+	0x0078, 0x393e, 0xa7c6, 0x7100, 0x00c0, 0x3946, 0xa6c2, 0x0004,
-+	0x0048, 0x2bdb, 0x2009, 0x0004, 0x0078, 0x3608, 0xa7c6, 0x7200,
-+	0x00c0, 0x2bdb, 0xa6c2, 0x0054, 0x0048, 0x2bdb, 0x600e, 0x6013,
-+	0x002a, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13db,
-+	0x7007, 0x0002, 0x701b, 0x395d, 0x007c, 0x701c, 0x2068, 0x6804,
-+	0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a,
-+	0x2098, 0x20a0, 0x1078, 0x4281, 0x007f, 0x2009, 0x002a, 0x2061,
-+	0xa6d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3608, 0x81ff,
-+	0x00c0, 0x2bd7, 0x792c, 0x2001, 0xa89d, 0x2102, 0x1078, 0x35d2,
-+	0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x47de, 0x127f, 0x0078, 0x2bad, 0x7824, 0xd08c,
-+	0x00c0, 0x3995, 0xd084, 0x0040, 0x31da, 0x1078, 0x35e4, 0x0040,
-+	0x2bdb, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, 0x00c0, 0x39a3, 0x2009,
-+	0x0002, 0x0078, 0x2bd7, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
-+	0x0040, 0x39b0, 0xa08e, 0x0004, 0x0040, 0x39b0, 0xa08e, 0x0005,
-+	0x00c0, 0x39dd, 0x7824, 0xd08c, 0x0040, 0x39bb, 0x6000, 0xc08c,
-+	0x6002, 0x0078, 0x39c5, 0x2001, 0xa653, 0x2004, 0xd0b4, 0x0040,
-+	0x320f, 0x6000, 0xd08c, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6838,
-+	0xc0fd, 0x683a, 0x1078, 0x8e9e, 0x00c0, 0x39d2, 0x2009, 0x0003,
-+	0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x39d7, 0x007c, 0x1078,
-+	0x35e4, 0x0040, 0x2bdb, 0x0078, 0x320f, 0x2009, 0xa62f, 0x210c,
-+	0x81ff, 0x0040, 0x39e7, 0x2009, 0x0001, 0x0078, 0x2bd7, 0x2001,
-+	0xa600, 0x2004, 0xa086, 0x0003, 0x0040, 0x39f2, 0x2009, 0x0007,
-+	0x0078, 0x2bd7, 0x2001, 0xa653, 0x2004, 0xd0ac, 0x0040, 0x39fc,
-+	0x2009, 0x0008, 0x0078, 0x2bd7, 0x609c, 0xd0a4, 0x00c0, 0x3a03,
-+	0xd0ac, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
-+	0xc0fd, 0x683a, 0x1078, 0x8f12, 0x00c0, 0x3a12, 0x2009, 0x0003,
-+	0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3a17, 0x007c, 0x6830,
-+	0xa086, 0x0100, 0x00c0, 0x3a20, 0x2009, 0x0004, 0x0078, 0x2bd7,
-+	0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0078, 0x39b2, 0x81ff, 0x2009,
-+	0x0001, 0x00c0, 0x2bd7, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007,
-+	0x00c0, 0x2bd7, 0x2001, 0xa653, 0x2004, 0xd0ac, 0x2009, 0x0008,
-+	0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6004, 0xa084,
-+	0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2bd7, 0x0c7e,
-+	0x1078, 0x35ba, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2bd7, 0x6837,
-+	0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194,
-+	0xff00, 0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x3a65, 0xc0ed,
-+	0x6952, 0x792c, 0x6956, 0x0078, 0x3a6e, 0xa28e, 0x0100, 0x00c0,
-+	0x2bdb, 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078,
-+	0x90bd, 0x2009, 0x0003, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b,
-+	0x3a7a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
-+	0x2bd7, 0x0078, 0x2bad, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2bd7,
-+	0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2bd7, 0x1078,
-+	0x35e4, 0x0040, 0x2bdb, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
-+	0x2009, 0x0009, 0x00c0, 0x2bd7, 0x0c7e, 0x1078, 0x35ba, 0x0c7f,
-+	0x2009, 0x0002, 0x0040, 0x2bd7, 0xad80, 0x000f, 0x2009, 0x0008,
-+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, 0x701b, 0x3ab1,
-+	0x007c, 0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0,
-+	0x3ac4, 0x6804, 0xa005, 0x00c0, 0x3ac4, 0x6808, 0xa084, 0xff00,
-+	0x00c0, 0x3ac4, 0x0078, 0x3ac7, 0x0d7f, 0x00c0, 0x2bdb, 0x0d7f,
-+	0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e,
-+	0x1078, 0x35e4, 0x00c0, 0x3ad7, 0x0c7f, 0x0078, 0x2bdb, 0x1078,
-+	0x9119, 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2bd7, 0x7007, 0x0003,
-+	0x701b, 0x3ae3, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004,
-+	0x0040, 0x2bd7, 0x0078, 0x2bad, 0x127e, 0x0c7e, 0x0e7e, 0x2061,
-+	0x0100, 0x2071, 0xa600, 0x6044, 0xd0a4, 0x00c0, 0x3b15, 0xd084,
-+	0x0040, 0x3afe, 0x1078, 0x3c75, 0x0078, 0x3b11, 0xd08c, 0x0040,
-+	0x3b05, 0x1078, 0x3b8c, 0x0078, 0x3b11, 0xd094, 0x0040, 0x3b0c,
-+	0x1078, 0x3b60, 0x0078, 0x3b11, 0xd09c, 0x0040, 0x3b11, 0x1078,
-+	0x3b1f, 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c,
-+	0x00c0, 0x3b1c, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3b11, 0x624c,
-+	0xa286, 0xf0f0, 0x00c0, 0x3b30, 0x6048, 0xa086, 0xf0f0, 0x0040,
-+	0x3b30, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3b5f,
-+	0xa294, 0xff00, 0xa296, 0xf700, 0x0040, 0x3b45, 0x7134, 0xd1a4,
-+	0x00c0, 0x3b45, 0x6240, 0xa294, 0x0010, 0x0040, 0x3b45, 0x2009,
-+	0x00f7, 0x1078, 0x42a1, 0x0078, 0x3b5f, 0x6043, 0x0040, 0x6043,
-+	0x0000, 0x7077, 0x0000, 0x708f, 0x0001, 0x70b3, 0x0000, 0x70cf,
-+	0x0000, 0x2009, 0xacc0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b,
-+	0x000f, 0x2009, 0x000f, 0x2011, 0x41d5, 0x1078, 0x5add, 0x007c,
-+	0x157e, 0x7078, 0xa005, 0x00c0, 0x3b8a, 0x2011, 0x41d5, 0x1078,
-+	0x5a45, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
-+	0x00c8, 0x6044, 0xd08c, 0x00c0, 0x3b83, 0x00f0, 0x3b71, 0x6242,
-+	0x708b, 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042,
-+	0x6242, 0x0078, 0x3b8a, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000,
-+	0x0078, 0x3b8a, 0x157f, 0x007c, 0x707c, 0xa08a, 0x0003, 0x00c8,
-+	0x3b95, 0x1079, 0x3b98, 0x0078, 0x3b97, 0x1078, 0x1332, 0x007c,
-+	0x3b9b, 0x3bea, 0x3c74, 0x0f7e, 0x707f, 0x0001, 0x20e1, 0xa000,
-+	0x20e1, 0x8700, 0x1078, 0x21f7, 0x20e1, 0x9080, 0x20e1, 0x4000,
-+	0x2079, 0xab00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
-+	0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000,
-+	0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000,
-+	0x782f, 0x0000, 0x2079, 0xab0c, 0x207b, 0x1101, 0x7807, 0x0000,
-+	0x2099, 0xa605, 0x20a1, 0xab0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
-+	0xab12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xab00, 0x20a1,
-+	0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000,
-+	0x1078, 0x420b, 0x0f7f, 0x7083, 0x0000, 0x6043, 0x0008, 0x6043,
-+	0x0000, 0x007c, 0x0d7e, 0x7080, 0x7083, 0x0000, 0xa025, 0x0040,
-+	0x3c5e, 0x6020, 0xd0b4, 0x00c0, 0x3c5c, 0x718c, 0x81ff, 0x0040,
-+	0x3c4b, 0xa486, 0x000c, 0x00c0, 0x3c56, 0xa480, 0x0018, 0x8004,
-+	0x20a8, 0x2011, 0xab80, 0x2019, 0xab00, 0x220c, 0x2304, 0xa106,
-+	0x00c0, 0x3c22, 0x8210, 0x8318, 0x00f0, 0x3c05, 0x6043, 0x0004,
-+	0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, 0x0002,
-+	0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078, 0x5add,
-+	0x0078, 0x3c5c, 0x2069, 0xab80, 0x6930, 0xa18e, 0x1101, 0x00c0,
-+	0x3c56, 0x6834, 0xa005, 0x00c0, 0x3c56, 0x6900, 0xa18c, 0x00ff,
-+	0x00c0, 0x3c36, 0x6804, 0xa005, 0x0040, 0x3c4b, 0x2011, 0xab8e,
-+	0x2019, 0xa605, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048,
-+	0x3c49, 0x00c0, 0x3c56, 0x8210, 0x8318, 0x00f0, 0x3c3c, 0x0078,
-+	0x3c56, 0x708f, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-+	0xab80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008,
-+	0x6043, 0x0000, 0x0078, 0x3c5e, 0x0d7f, 0x007c, 0x6020, 0xd0b4,
-+	0x00c0, 0x3c5c, 0x60c3, 0x000c, 0x2011, 0xa8bb, 0x2013, 0x0000,
-+	0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
-+	0x1078, 0x6e06, 0x0078, 0x3c5c, 0x007c, 0x7088, 0xa08a, 0x001d,
-+	0x00c8, 0x3c7e, 0x1079, 0x3c81, 0x0078, 0x3c80, 0x1078, 0x1332,
-+	0x007c, 0x3cab, 0x3cba, 0x3ce9, 0x3d02, 0x3d2e, 0x3d5a, 0x3d86,
-+	0x3dbc, 0x3de8, 0x3e10, 0x3e53, 0x3e7d, 0x3e9f, 0x3eb5, 0x3edb,
-+	0x3eee, 0x3ef7, 0x3f2b, 0x3f57, 0x3f83, 0x3faf, 0x3fe5, 0x4030,
-+	0x405f, 0x4081, 0x40c3, 0x40e9, 0x4102, 0x4103, 0x0c7e, 0x2061,
-+	0xa600, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
-+	0x6006, 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
-+	0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078,
-+	0x5add, 0x007c, 0x0f7e, 0x7080, 0xa086, 0x0014, 0x00c0, 0x3ce7,
-+	0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3ce7, 0x2079, 0xab80,
-+	0x7a30, 0xa296, 0x1102, 0x00c0, 0x3ce5, 0x7834, 0xa005, 0x00c0,
-+	0x3ce5, 0x7a38, 0xd2fc, 0x0040, 0x3cdb, 0x70b0, 0xa005, 0x00c0,
-+	0x3cdb, 0x70b3, 0x0001, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x708b,
-+	0x0010, 0x1078, 0x3ef7, 0x0078, 0x3ce7, 0x1078, 0x4224, 0x0f7f,
-+	0x007c, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x41dc, 0x1078,
-+	0x5a45, 0x1078, 0x4289, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9,
-+	0x000a, 0x20a3, 0x0000, 0x00f0, 0x3cf9, 0x60c3, 0x0014, 0x1078,
-+	0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d2c, 0x2011,
-+	0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d2a, 0x2079,
-+	0xab80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3d2a, 0x7834, 0xa005,
-+	0x00c0, 0x3d2a, 0x7a38, 0xd2fc, 0x0040, 0x3d24, 0x70b0, 0xa005,
-+	0x00c0, 0x3d24, 0x70b3, 0x0001, 0x708b, 0x0004, 0x1078, 0x3d2e,
-+	0x0078, 0x3d2c, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0005,
-+	0x1078, 0x4289, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011,
-+	0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3d4c, 0x7074, 0xa005, 0x00c0,
-+	0x3d4c, 0x7150, 0xa186, 0xffff, 0x0040, 0x3d4c, 0x1078, 0x419d,
-+	0x0040, 0x3d4c, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298, 0x26a0,
-+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d84, 0x2011,
-+	0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d82, 0x2079,
-+	0xab80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3d82, 0x7834, 0xa005,
-+	0x00c0, 0x3d82, 0x7a38, 0xd2fc, 0x0040, 0x3d7c, 0x70b0, 0xa005,
-+	0x00c0, 0x3d7c, 0x70b3, 0x0001, 0x708b, 0x0006, 0x1078, 0x3d86,
-+	0x0078, 0x3d84, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0007,
-+	0x1078, 0x4289, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011,
-+	0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3dae, 0x7074, 0xa005, 0x00c0,
-+	0x3dae, 0x7154, 0xa186, 0xffff, 0x0040, 0x3dae, 0xa180, 0x29c0,
-+	0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040, 0x3dae,
-+	0x1078, 0x3820, 0x0040, 0x3dae, 0x1078, 0x256a, 0x20a9, 0x0008,
-+	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040,
-+	0x3de6, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0,
-+	0x3de4, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3de4,
-+	0x7834, 0xa005, 0x00c0, 0x3de4, 0x7a38, 0xd2fc, 0x0040, 0x3dde,
-+	0x70b0, 0xa005, 0x00c0, 0x3dde, 0x70b3, 0x0001, 0x708b, 0x0008,
-+	0x1078, 0x3de8, 0x0078, 0x3de6, 0x1078, 0x4224, 0x0f7f, 0x007c,
-+	0x708b, 0x0009, 0x1078, 0x4289, 0x20a3, 0x1105, 0x20a3, 0x0100,
-+	0x3430, 0x1078, 0x42d4, 0x00c0, 0x3e01, 0x7074, 0xa005, 0x00c0,
-+	0x3e01, 0x1078, 0x4104, 0x00c0, 0x3e0b, 0xa085, 0x0001, 0x1078,
-+	0x256a, 0x20a9, 0x0008, 0x2099, 0xab8e, 0x26a0, 0x53a6, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c,
-+	0x0f7e, 0x7080, 0xa005, 0x0040, 0x3e51, 0x2011, 0x41dc, 0x1078,
-+	0x5a45, 0xa086, 0x0014, 0x00c0, 0x3e4f, 0x2079, 0xab80, 0x7a30,
-+	0xa296, 0x1105, 0x00c0, 0x3e4f, 0x7834, 0x2011, 0x0100, 0xa21e,
-+	0x00c0, 0x3e3a, 0x7a38, 0xd2fc, 0x0040, 0x3e34, 0x70b0, 0xa005,
-+	0x00c0, 0x3e34, 0x70b3, 0x0001, 0x708b, 0x000a, 0x1078, 0x3e53,
-+	0x0078, 0x3e51, 0xa005, 0x00c0, 0x3e4f, 0x7a38, 0xd2fc, 0x0040,
-+	0x3e47, 0x70b0, 0xa005, 0x00c0, 0x3e47, 0x70b3, 0x0001, 0x7087,
-+	0x0000, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3e51, 0x1078,
-+	0x4224, 0x0f7f, 0x007c, 0x708b, 0x000b, 0x2011, 0xab0e, 0x22a0,
-+	0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009,
-+	0x0000, 0x41a4, 0x1078, 0x4289, 0x20a3, 0x1106, 0x20a3, 0x0000,
-+	0x1078, 0x42d4, 0x0040, 0x3e70, 0x2013, 0x0000, 0x0078, 0x3e74,
-+	0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6,
-+	0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
-+	0x0040, 0x3e9d, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084,
-+	0x00c0, 0x3e9b, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1106, 0x00c0,
-+	0x3e9b, 0x7834, 0xa005, 0x00c0, 0x3e9b, 0x708b, 0x000c, 0x1078,
-+	0x3e9f, 0x0078, 0x3e9d, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
-+	0x000d, 0x1078, 0x4289, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099,
-+	0xab8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
-+	0x0040, 0x3ed9, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084,
-+	0x00c0, 0x3ed7, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1107, 0x00c0,
-+	0x3ed7, 0x7834, 0xa005, 0x00c0, 0x3ed7, 0x7087, 0x0001, 0x1078,
-+	0x427b, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3ed9, 0x1078,
-+	0x4224, 0x0f7f, 0x007c, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b,
-+	0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009,
-+	0x07d0, 0x2011, 0x41dc, 0x1078, 0x5a38, 0x007c, 0x7080, 0xa005,
-+	0x0040, 0x3ef6, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x007c, 0x708b,
-+	0x0011, 0x1078, 0x42d4, 0x00c0, 0x3f14, 0x716c, 0x81ff, 0x0040,
-+	0x3f14, 0x2009, 0x0000, 0x7070, 0xa084, 0x00ff, 0x1078, 0x254d,
-+	0xa186, 0x007e, 0x0040, 0x3f14, 0xa186, 0x0080, 0x0040, 0x3f14,
-+	0x2011, 0xab8e, 0x1078, 0x419d, 0x20e1, 0x9080, 0x20e1, 0x4000,
-+	0x2099, 0xab80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080,
-+	0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014,
-+	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3f55,
-+	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3f53,
-+	0x2079, 0xab80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3f53, 0x7834,
-+	0xa005, 0x00c0, 0x3f53, 0x7a38, 0xd2fc, 0x0040, 0x3f4d, 0x70b0,
-+	0xa005, 0x00c0, 0x3f4d, 0x70b3, 0x0001, 0x708b, 0x0012, 0x1078,
-+	0x3f57, 0x0078, 0x3f55, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
-+	0x0013, 0x1078, 0x4295, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
-+	0x2011, 0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3f75, 0x7074, 0xa005,
-+	0x00c0, 0x3f75, 0x7150, 0xa186, 0xffff, 0x0040, 0x3f75, 0x1078,
-+	0x419d, 0x0040, 0x3f75, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298,
-+	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
-+	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3fad,
-+	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3fab,
-+	0x2079, 0xab80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3fab, 0x7834,
-+	0xa005, 0x00c0, 0x3fab, 0x7a38, 0xd2fc, 0x0040, 0x3fa5, 0x70b0,
-+	0xa005, 0x00c0, 0x3fa5, 0x70b3, 0x0001, 0x708b, 0x0014, 0x1078,
-+	0x3faf, 0x0078, 0x3fad, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
-+	0x0015, 0x1078, 0x4295, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430,
-+	0x2011, 0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3fd7, 0x7074, 0xa005,
-+	0x00c0, 0x3fd7, 0x7154, 0xa186, 0xffff, 0x0040, 0x3fd7, 0xa180,
-+	0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040,
-+	0x3fd7, 0x1078, 0x3820, 0x0040, 0x3fd7, 0x1078, 0x256a, 0x20a9,
-+	0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
-+	0x0040, 0x402e, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014,
-+	0x00c0, 0x402c, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1105, 0x00c0,
-+	0x402c, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x400b, 0x7a38,
-+	0xd2fc, 0x0040, 0x4009, 0x70b0, 0xa005, 0x00c0, 0x4009, 0x70b3,
-+	0x0001, 0x0078, 0x401a, 0xa005, 0x00c0, 0x402c, 0x7a38, 0xd2fc,
-+	0x0040, 0x4018, 0x70b0, 0xa005, 0x00c0, 0x4018, 0x70b3, 0x0001,
-+	0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0040, 0x4026, 0x2001, 0xa674,
-+	0x2004, 0xd0a4, 0x00c0, 0x4026, 0x70cf, 0x0008, 0x708b, 0x0016,
-+	0x1078, 0x4030, 0x0078, 0x402e, 0x1078, 0x4224, 0x0f7f, 0x007c,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xab80, 0x20a1, 0x020b,
-+	0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xab8e, 0x708b, 0x0017,
-+	0x1078, 0x42d4, 0x00c0, 0x4050, 0x7074, 0xa005, 0x00c0, 0x4050,
-+	0x1078, 0x4104, 0x00c0, 0x405a, 0xa085, 0x0001, 0x1078, 0x256a,
-+	0x20a9, 0x0008, 0x2099, 0xab8e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e,
-+	0x7080, 0xa005, 0x0040, 0x407f, 0x2011, 0x41dc, 0x1078, 0x5a45,
-+	0xa086, 0x0084, 0x00c0, 0x407d, 0x2079, 0xab80, 0x7a30, 0xa296,
-+	0x1106, 0x00c0, 0x407d, 0x7834, 0xa005, 0x00c0, 0x407d, 0x708b,
-+	0x0018, 0x1078, 0x4081, 0x0078, 0x407f, 0x1078, 0x4224, 0x0f7f,
-+	0x007c, 0x708b, 0x0019, 0x1078, 0x4295, 0x20a3, 0x1106, 0x20a3,
-+	0x0000, 0x3430, 0x2099, 0xab8e, 0x2039, 0xab0e, 0x27a0, 0x20a9,
-+	0x0040, 0x53a3, 0x1078, 0x42d4, 0x00c0, 0x40b5, 0x2728, 0x2514,
-+	0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
-+	0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0xab0e, 0x2414,
-+	0xa38c, 0x0001, 0x0040, 0x40b0, 0xa294, 0xff00, 0x0078, 0x40b3,
-+	0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9,
-+	0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084,
-+	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x40e7,
-+	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084, 0x00c0, 0x40e5,
-+	0x2079, 0xab80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x40e5, 0x7834,
-+	0xa005, 0x00c0, 0x40e5, 0x7087, 0x0001, 0x1078, 0x427b, 0x708b,
-+	0x001a, 0x1078, 0x40e9, 0x0078, 0x40e7, 0x1078, 0x4224, 0x0f7f,
-+	0x007c, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-+	0xab80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
-+	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078,
-+	0x420b, 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0xa653,
-+	0x252c, 0x20a9, 0x0008, 0x2041, 0xab0e, 0x28a0, 0x2099, 0xab8e,
-+	0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x411a,
-+	0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0,
-+	0x412c, 0xd5d4, 0x0040, 0x4127, 0x8210, 0x0078, 0x4128, 0x8211,
-+	0x00f0, 0x411a, 0x0078, 0x4194, 0x82ff, 0x00c0, 0x413e, 0xd5d4,
-+	0x0040, 0x4138, 0xa1a6, 0x3fff, 0x0040, 0x4124, 0x0078, 0x413c,
-+	0xa1a6, 0x3fff, 0x0040, 0x4194, 0xa18d, 0xc000, 0x20a9, 0x0010,
-+	0x2019, 0x0001, 0xd5d4, 0x0040, 0x4147, 0x2019, 0x0010, 0x2120,
-+	0xd5d4, 0x0040, 0x414e, 0x8423, 0x0078, 0x414f, 0x8424, 0x00c8,
-+	0x415c, 0xd5d4, 0x0040, 0x4157, 0x8319, 0x0078, 0x4158, 0x8318,
-+	0x00f0, 0x4148, 0x0078, 0x4194, 0x23a8, 0x2021, 0x0001, 0x8426,
-+	0x8425, 0x00f0, 0x4160, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040,
-+	0x4174, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8,
-+	0xa5a8, 0x0010, 0x00f0, 0x4170, 0x7552, 0xa5c8, 0x29c0, 0x292c,
-+	0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0000,
-+	0x7572, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001, 0x26a0,
-+	0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0xa085, 0x0001, 0x0078, 0x419a, 0xa006, 0x0078, 0x419a, 0xa006,
-+	0x1078, 0x1332, 0x097f, 0x087f, 0x007c, 0x2118, 0x2021, 0x0000,
-+	0x2001, 0x0007, 0xa39a, 0x0010, 0x0048, 0x41aa, 0x8420, 0x8001,
-+	0x0078, 0x41a2, 0x2118, 0x84ff, 0x0040, 0x41b3, 0xa39a, 0x0010,
-+	0x8421, 0x00c0, 0x41ae, 0x2021, 0x0001, 0x83ff, 0x0040, 0x41bc,
-+	0x8423, 0x8319, 0x00c0, 0x41b8, 0xa238, 0x2704, 0xa42c, 0x00c0,
-+	0x41d4, 0xa405, 0x203a, 0x7152, 0xa1a0, 0x29c0, 0x242c, 0xa5ac,
-+	0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0000, 0x7572,
-+	0x7077, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa600,
-+	0x707b, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002,
-+	0x1078, 0x5ae6, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x6e0f,
-+	0x7004, 0xa084, 0x4000, 0x0040, 0x41f1, 0x7003, 0x1000, 0x7003,
-+	0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0xa622, 0x2073, 0x0000,
-+	0x7840, 0x027e, 0x017e, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x017f,
-+	0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f,
-+	0x0f7f, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0xa8bb,
-+	0x2013, 0x0000, 0x7083, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3,
-+	0x0056, 0x60a7, 0x9575, 0x1078, 0x6e06, 0x2009, 0x07d0, 0x2011,
-+	0x41dc, 0x1078, 0x5add, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002,
-+	0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078,
-+	0x7058, 0x037f, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x2061, 0xa8c4,
-+	0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xa600, 0x6003, 0x0001,
-+	0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x002d,
-+	0x2011, 0x4259, 0x1078, 0x5a38, 0x127f, 0x0c7f, 0x027f, 0x017f,
-+	0x007c, 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2001, 0x0001,
-+	0x1078, 0x5ae6, 0x2071, 0x0100, 0x1078, 0x6e0f, 0x2071, 0x0140,
-+	0x7004, 0xa084, 0x4000, 0x0040, 0x4271, 0x7003, 0x1000, 0x7003,
-+	0x0000, 0x2001, 0x0001, 0x1078, 0x24e8, 0x1078, 0x4224, 0x127f,
-+	0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0xacc0, 0x2099,
-+	0xab8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x4281,
-+	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xab00, 0x20a1,
-+	0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0xab80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6,
-+	0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001, 0xa62f,
-+	0x2004, 0xa005, 0x00c0, 0x42b2, 0x6030, 0xa084, 0x00ff, 0xa105,
-+	0x0078, 0x42b4, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c,
-+	0x017e, 0x047e, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x42cb,
-+	0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0xa21d, 0x2001, 0xa60c,
-+	0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x1078,
-+	0x284f, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0xa60c, 0x2004,
-+	0xd09c, 0x0040, 0x42db, 0x007f, 0x007c, 0x007e, 0x017e, 0x127e,
-+	0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102,
-+	0x127f, 0x017f, 0x007f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009,
-+	0xa735, 0xa006, 0x200a, 0x8108, 0x00f0, 0x42f2, 0x157f, 0x007c,
-+	0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0xa652, 0xa006,
-+	0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x29c0,
-+	0x231c, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006,
-+	0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4,
-+	0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062,
-+	0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082,
-+	0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae,
-+	0x61a2, 0x0d7e, 0x60a4, 0xa06d, 0x0040, 0x4338, 0x1078, 0x13a4,
-+	0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0040, 0x4340, 0x1078, 0x13a4,
-+	0x60ab, 0x0000, 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c,
-+	0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f,
-+	0x037f, 0x0d7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48,
-+	0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x4424, 0xa18c, 0xff00,
-+	0x810f, 0xa182, 0x00ff, 0x00c8, 0x442a, 0x2001, 0xa60c, 0x2004,
-+	0xa084, 0x0003, 0x0040, 0x4385, 0x2001, 0xa60c, 0x2004, 0xd084,
-+	0x00c0, 0x4405, 0xa188, 0xa735, 0x2104, 0xa065, 0x0040, 0x4405,
-+	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x4405, 0x6000,
-+	0xd0c4, 0x0040, 0x4405, 0x0078, 0x4392, 0xa188, 0xa735, 0x2104,
-+	0xa065, 0x0040, 0x43e9, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
-+	0x00c0, 0x43ef, 0x60a4, 0xa00d, 0x0040, 0x439a, 0x1078, 0x4817,
-+	0x0040, 0x43e3, 0x60a8, 0xa00d, 0x0040, 0x43b4, 0x1078, 0x486a,
-+	0x00c0, 0x43b4, 0x694c, 0xd1fc, 0x00c0, 0x43aa, 0x1078, 0x44df,
-+	0x0078, 0x43de, 0x1078, 0x4484, 0x694c, 0xd1ec, 0x00c0, 0x43de,
-+	0x1078, 0x46d6, 0x0078, 0x43de, 0x694c, 0xa184, 0xa000, 0x0040,
-+	0x43ce, 0xd1ec, 0x0040, 0x43c7, 0xd1fc, 0x0040, 0x43c3, 0x1078,
-+	0x46e7, 0x0078, 0x43ca, 0x1078, 0x46e7, 0x0078, 0x43ce, 0xd1fc,
-+	0x0040, 0x43ce, 0x1078, 0x4484, 0x0078, 0x43de, 0x6050, 0xa00d,
-+	0x0040, 0x43d9, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0078,
-+	0x43de, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x1078, 0x5da9,
-+	0xa006, 0x127f, 0x007c, 0x2001, 0x0005, 0x2009, 0x0000, 0x0078,
-+	0x442e, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x442e, 0xa082,
-+	0x0006, 0x00c8, 0x4405, 0x60a0, 0xd0bc, 0x00c0, 0x4401, 0x6100,
-+	0xd1fc, 0x0040, 0x4392, 0x2001, 0x0029, 0x2009, 0x1000, 0x0078,
-+	0x442e, 0x2001, 0x0028, 0x0078, 0x4420, 0x2009, 0xa60c, 0x210c,
-+	0xd18c, 0x0040, 0x440f, 0x2001, 0x0004, 0x0078, 0x4420, 0xd184,
-+	0x0040, 0x4416, 0x2001, 0x0004, 0x0078, 0x4420, 0x2001, 0x0029,
-+	0x6100, 0xd1fc, 0x0040, 0x4420, 0x2009, 0x1000, 0x0078, 0x442e,
-+	0x2009, 0x0000, 0x0078, 0x442e, 0x2001, 0x0029, 0x2009, 0x0000,
-+	0x0078, 0x442e, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x127f,
-+	0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8,
-+	0x447e, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x00c8, 0x4464,
-+	0xa188, 0xa735, 0x2104, 0xa065, 0x0040, 0x4464, 0x6004, 0xa084,
-+	0x00ff, 0xa08e, 0x0006, 0x00c0, 0x446a, 0x684c, 0xd0ec, 0x0040,
-+	0x4457, 0x1078, 0x46e7, 0x1078, 0x4484, 0x0078, 0x445f, 0x1078,
-+	0x4484, 0x684c, 0xd0fc, 0x0040, 0x445f, 0x1078, 0x46d6, 0x1078,
-+	0x472f, 0xa006, 0x0078, 0x4482, 0x2001, 0x0028, 0x2009, 0x0000,
-+	0x0078, 0x4482, 0xa082, 0x0006, 0x00c8, 0x4478, 0x6100, 0xd1fc,
-+	0x0040, 0x444d, 0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x4482,
-+	0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x4482, 0x2001, 0x0029,
-+	0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000, 0x6050,
-+	0xa00d, 0x0040, 0x4492, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
-+	0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078,
-+	0x4490, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, 0x44af,
-+	0x0e7e, 0x2071, 0xa8b1, 0x7004, 0xa086, 0x0002, 0x0040, 0x44b6,
-+	0x0e7f, 0x604c, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00,
-+	0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x44ad, 0x701c, 0xac06,
-+	0x00c0, 0x44a8, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002,
-+	0x0e7f, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x604c, 0xa06d,
-+	0x0040, 0x44d1, 0x6800, 0xa005, 0x00c0, 0x44cf, 0x6052, 0x604e,
-+	0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040, 0x44de, 0x6800,
-+	0xa005, 0x00c0, 0x44dc, 0x6052, 0x604e, 0xad05, 0x007c, 0x6803,
-+	0x0000, 0x6084, 0xa00d, 0x0040, 0x44e9, 0x2d00, 0x200a, 0x6086,
-+	0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x44e8, 0x127e, 0x0c7e,
-+	0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0040,
-+	0x44fc, 0xc285, 0x0078, 0x44fd, 0xc284, 0x6202, 0x027f, 0x0c7f,
-+	0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
-+	0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4521, 0x609c, 0xd0ac,
-+	0x0040, 0x4521, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x4521,
-+	0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x00c0, 0x4521, 0x2011,
-+	0x0600, 0x007f, 0xa294, 0xff00, 0xa215, 0x6206, 0x007e, 0xa086,
-+	0x0006, 0x00c0, 0x4531, 0x6290, 0x82ff, 0x00c0, 0x4531, 0x1078,
-+	0x1332, 0x007f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091,
-+	0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0,
-+	0x4553, 0x609c, 0xd0a4, 0x0040, 0x4553, 0x2001, 0xa653, 0x2004,
-+	0xd0ac, 0x00c0, 0x4553, 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0,
-+	0x4553, 0x2011, 0x0006, 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215,
-+	0x6206, 0x0c7f, 0x127f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048,
-+	0x4565, 0xa085, 0x0001, 0x0078, 0x457d, 0xa190, 0xa735, 0x2204,
-+	0xa065, 0x00c0, 0x457c, 0x017e, 0x0d7e, 0x1078, 0x1370, 0x2d60,
-+	0x0d7f, 0x017f, 0x0040, 0x4561, 0x2c00, 0x2012, 0x60a7, 0x0000,
-+	0x60ab, 0x0000, 0x1078, 0x42f8, 0xa006, 0x027f, 0x007c, 0x127e,
-+	0x2091, 0x8000, 0x027e, 0xa182, 0x00ff, 0x0048, 0x458b, 0xa085,
-+	0x0001, 0x0078, 0x45c1, 0x0d7e, 0xa190, 0xa735, 0x2204, 0xa06d,
-+	0x0040, 0x45bf, 0x2013, 0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4,
-+	0xa06d, 0x0040, 0x459d, 0x1078, 0x13a4, 0x60a8, 0xa06d, 0x0040,
-+	0x45a3, 0x1078, 0x13a4, 0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac,
-+	0x2060, 0x8cff, 0x0040, 0x45bb, 0x600c, 0x007e, 0x6010, 0x2068,
-+	0x1078, 0x8d06, 0x0040, 0x45b6, 0x1078, 0x13b4, 0x1078, 0x772d,
-+	0x0c7f, 0x0078, 0x45a9, 0x0c7f, 0x0d7f, 0x1078, 0x13a4, 0x0d7f,
-+	0xa006, 0x027f, 0x127f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048,
-+	0x45cd, 0xa085, 0x0001, 0x0078, 0x45d4, 0xa188, 0xa735, 0x2104,
-+	0xa065, 0x0040, 0x45c9, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e,
-+	0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c,
-+	0x6002, 0x2069, 0xab8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
-+	0xa10a, 0x0048, 0x45ec, 0x603a, 0x6814, 0x6066, 0x2099, 0xab96,
-+	0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xab9a,
-+	0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xabae,
-+	0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076,
-+	0x60a0, 0xa086, 0x007e, 0x00c0, 0x4611, 0x2069, 0xab8e, 0x690c,
-+	0x616e, 0xa182, 0x0211, 0x00c8, 0x4619, 0x2009, 0x0008, 0x0078,
-+	0x4643, 0xa182, 0x0259, 0x00c8, 0x4621, 0x2009, 0x0007, 0x0078,
-+	0x4643, 0xa182, 0x02c1, 0x00c8, 0x4629, 0x2009, 0x0006, 0x0078,
-+	0x4643, 0xa182, 0x0349, 0x00c8, 0x4631, 0x2009, 0x0005, 0x0078,
-+	0x4643, 0xa182, 0x0421, 0x00c8, 0x4639, 0x2009, 0x0004, 0x0078,
-+	0x4643, 0xa182, 0x0581, 0x00c8, 0x4641, 0x2009, 0x0003, 0x0078,
-+	0x4643, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f,
-+	0x007c, 0x017e, 0x027e, 0x0e7e, 0x2071, 0xab8d, 0x2e04, 0x6896,
-+	0x2071, 0xab8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00, 0x2009,
-+	0xa672, 0x210c, 0xd0bc, 0x0040, 0x4663, 0xd1ec, 0x0040, 0x4663,
-+	0xc2ad, 0x0078, 0x4664, 0xc2ac, 0xd0c4, 0x0040, 0x466d, 0xd1e4,
-+	0x0040, 0x466d, 0xc2bd, 0x0078, 0x466e, 0xc2bc, 0x6a02, 0x0e7f,
-+	0x027f, 0x017f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4,
-+	0xa06d, 0x0040, 0x4697, 0x6900, 0x81ff, 0x00c0, 0x46ab, 0x6a04,
-+	0xa282, 0x0010, 0x00c8, 0x46b0, 0xad88, 0x0004, 0x20a9, 0x0010,
-+	0x2104, 0xa086, 0xffff, 0x0040, 0x4692, 0x8108, 0x00f0, 0x4688,
-+	0x1078, 0x1332, 0x260a, 0x8210, 0x6a06, 0x0078, 0x46ab, 0x1078,
-+	0x138b, 0x0040, 0x46b0, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88,
-+	0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x46a3,
-+	0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
-+	0xa006, 0x0078, 0x46ad, 0x127e, 0x2091, 0x8000, 0x0d7e, 0x60a4,
-+	0xa00d, 0x0040, 0x46d3, 0x2168, 0x6800, 0xa005, 0x00c0, 0x46cf,
-+	0x1078, 0x4817, 0x00c0, 0x46d3, 0x200b, 0xffff, 0x6804, 0xa08a,
-+	0x0002, 0x0048, 0x46cf, 0x8001, 0x6806, 0x0078, 0x46d3, 0x1078,
-+	0x13a4, 0x60a7, 0x0000, 0x0d7f, 0x127f, 0x007c, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x487f, 0x0078, 0x46df, 0x1078, 0x4484, 0x1078,
-+	0x4775, 0x00c0, 0x46dd, 0x1078, 0x472f, 0x127f, 0x007c, 0x0d7e,
-+	0x127e, 0x2091, 0x8000, 0x60a8, 0xa06d, 0x0040, 0x470b, 0x6950,
-+	0x81ff, 0x00c0, 0x471f, 0x6a54, 0xa282, 0x0010, 0x00c8, 0x472c,
-+	0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
-+	0x4706, 0x8108, 0x00f0, 0x46fc, 0x1078, 0x1332, 0x260a, 0x8210,
-+	0x6a56, 0x0078, 0x471f, 0x1078, 0x138b, 0x0040, 0x472c, 0x2d00,
-+	0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b,
-+	0xffff, 0x8108, 0x00f0, 0x4717, 0x6857, 0x0001, 0x6e62, 0x0078,
-+	0x4723, 0x1078, 0x44df, 0x1078, 0x4739, 0x00c0, 0x4721, 0xa085,
-+	0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x4729, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x5da9, 0x127f, 0x007c, 0xa01e, 0x0078,
-+	0x473b, 0x2019, 0x0001, 0xa00e, 0x127e, 0x2091, 0x8000, 0x604c,
-+	0x2068, 0x6000, 0xd0dc, 0x00c0, 0x4759, 0x8dff, 0x0040, 0x4770,
-+	0x83ff, 0x0040, 0x4751, 0x6848, 0xa606, 0x0040, 0x475e, 0x0078,
-+	0x4759, 0x683c, 0xa406, 0x00c0, 0x4759, 0x6840, 0xa506, 0x0040,
-+	0x475e, 0x2d08, 0x6800, 0x2068, 0x0078, 0x4745, 0x1078, 0x7233,
-+	0x6a00, 0x604c, 0xad06, 0x00c0, 0x4768, 0x624e, 0x0078, 0x476b,
-+	0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x4770, 0x6152, 0x8dff,
-+	0x127f, 0x007c, 0xa01e, 0x0078, 0x4777, 0x2019, 0x0001, 0xa00e,
-+	0x6080, 0x2068, 0x8dff, 0x0040, 0x47a3, 0x83ff, 0x0040, 0x4786,
-+	0x6848, 0xa606, 0x0040, 0x4793, 0x0078, 0x478e, 0x683c, 0xa406,
-+	0x00c0, 0x478e, 0x6840, 0xa506, 0x0040, 0x4793, 0x2d08, 0x6800,
-+	0x2068, 0x0078, 0x477a, 0x6a00, 0x6080, 0xad06, 0x00c0, 0x479b,
-+	0x6282, 0x0078, 0x479e, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0,
-+	0x47a3, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078, 0x4810, 0x00c0,
-+	0x47ab, 0x2011, 0x0001, 0x1078, 0x4863, 0x00c0, 0x47b1, 0xa295,
-+	0x0002, 0x007c, 0x1078, 0x489b, 0x0040, 0x47ba, 0x1078, 0x8dca,
-+	0x0078, 0x47bc, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040,
-+	0x47c5, 0x1078, 0x8d62, 0x0078, 0x47c7, 0xa085, 0x0001, 0x007c,
-+	0x1078, 0x489b, 0x0040, 0x47d0, 0x1078, 0x8dac, 0x0078, 0x47d2,
-+	0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040, 0x47db, 0x1078,
-+	0x8d7e, 0x0078, 0x47dd, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b,
-+	0x0040, 0x47e6, 0x1078, 0x8de8, 0x0078, 0x47e8, 0xa085, 0x0001,
-+	0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d,
-+	0x0040, 0x4808, 0x6800, 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847,
-+	0x0000, 0x1078, 0x8f7d, 0x007e, 0x6000, 0xd0fc, 0x0040, 0x4802,
-+	0x1078, 0xa4ed, 0x007f, 0x1078, 0x4a73, 0x007f, 0x0078, 0x47ef,
-+	0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c,
-+	0x60a4, 0xa00d, 0x00c0, 0x4817, 0xa085, 0x0001, 0x007c, 0x0e7e,
-+	0x2170, 0x7000, 0xa005, 0x00c0, 0x482c, 0x20a9, 0x0010, 0xae88,
-+	0x0004, 0x2104, 0xa606, 0x0040, 0x482c, 0x8108, 0x00f0, 0x4821,
-+	0xa085, 0x0001, 0x0078, 0x482d, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
-+	0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x483d, 0x1078,
-+	0x138b, 0x0040, 0x484f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
-+	0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
-+	0x00f0, 0x4845, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
-+	0x0078, 0x484c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
-+	0x0040, 0x4860, 0x60a7, 0x0000, 0x1078, 0x13a4, 0xa085, 0x0001,
-+	0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x486a, 0xa085,
-+	0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x487d,
-+	0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x487d,
-+	0x8108, 0x00f0, 0x4874, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x4863, 0x00c0, 0x4899, 0x200b, 0xffff,
-+	0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x4894,
-+	0x8001, 0x6856, 0x0078, 0x4898, 0x1078, 0x13a4, 0x60ab, 0x0000,
-+	0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71b0,
-+	0x81ff, 0x00c0, 0x48b9, 0x71cc, 0xd19c, 0x0040, 0x48b9, 0x2001,
-+	0x007e, 0xa080, 0xa735, 0x2004, 0xa07d, 0x0040, 0x48b9, 0x7804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x48b9, 0x7800, 0xc0ed,
-+	0x7802, 0x2079, 0xa652, 0x7804, 0xd0a4, 0x0040, 0x48df, 0x157e,
-+	0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4,
-+	0x00c0, 0x48d9, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
-+	0x0040, 0x48d6, 0xa086, 0x0006, 0x00c0, 0x48d9, 0x6000, 0xc0ed,
-+	0x6002, 0x017f, 0x8108, 0x00f0, 0x48c5, 0x0c7f, 0x157f, 0x1078,
-+	0x4967, 0x0040, 0x48e8, 0x2001, 0xa8a1, 0x200c, 0x0078, 0x48f0,
-+	0x2079, 0xa652, 0x7804, 0xd0a4, 0x0040, 0x48f4, 0x2009, 0x07d0,
-+	0x2011, 0x48f6, 0x1078, 0x5add, 0x0f7f, 0x007c, 0x2011, 0x48f6,
-+	0x1078, 0x5a45, 0x1078, 0x4967, 0x0040, 0x491e, 0x2001, 0xa7b3,
-+	0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa653,
-+	0x2004, 0xd0a4, 0x0040, 0x4912, 0x2009, 0x07d0, 0x2011, 0x48f6,
-+	0x1078, 0x5add, 0x0e7e, 0x2071, 0xa600, 0x706f, 0x0000, 0x7073,
-+	0x0000, 0x1078, 0x2677, 0x0e7f, 0x0078, 0x4956, 0x157e, 0x0c7e,
-+	0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0,
-+	0x4950, 0x6000, 0xd0ec, 0x0040, 0x4950, 0x047e, 0x62a0, 0xa294,
-+	0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0xa21d, 0x6000,
-+	0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
-+	0x6006, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000,
-+	0x1078, 0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x047f,
-+	0x017f, 0x8108, 0x00f0, 0x4924, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
-+	0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
-+	0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
-+	0x2001, 0xa7b3, 0x2004, 0xa07d, 0x0040, 0x4970, 0x7800, 0xd0ec,
-+	0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x007e, 0x62a0,
-+	0xa290, 0xa735, 0x2204, 0xac06, 0x10c0, 0x1332, 0x007f, 0x6200,
-+	0xa005, 0x0040, 0x4986, 0xc2fd, 0x0078, 0x4987, 0xc2fc, 0x6202,
-+	0x027f, 0x127f, 0x007c, 0x2011, 0xa633, 0x2204, 0xd0cc, 0x0040,
-+	0x4998, 0x2001, 0xa89f, 0x200c, 0x2011, 0x4999, 0x1078, 0x5add,
-+	0x007c, 0x2011, 0x4999, 0x1078, 0x5a45, 0x2011, 0xa633, 0x2204,
-+	0xc0cc, 0x2012, 0x007c, 0x2071, 0xa714, 0x7003, 0x0001, 0x7007,
-+	0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f,
-+	0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b,
-+	0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa87d, 0x7003,
-+	0xa714, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa85d, 0x7013,
-+	0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e,
-+	0x2071, 0xa835, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001,
-+	0xa653, 0x2004, 0xd0fc, 0x00c0, 0x49e8, 0x2001, 0xa653, 0x2004,
-+	0xa00e, 0xd09c, 0x0040, 0x49e5, 0x8108, 0x7102, 0x0078, 0x4a3b,
-+	0x2001, 0xa672, 0x200c, 0xa184, 0x000f, 0x2009, 0xa673, 0x210c,
-+	0x0079, 0x49f2, 0x49dd, 0x4a13, 0x4a1b, 0x4a26, 0x4a2c, 0x49dd,
-+	0x49dd, 0x49dd, 0x4a02, 0x49dd, 0x49dd, 0x49dd, 0x49dd, 0x49dd,
-+	0x49dd, 0x49dd, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099,
-+	0xa676, 0x20a1, 0xa886, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f,
-+	0x137f, 0x0078, 0x4a3b, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001,
-+	0x0002, 0x0078, 0x4a21, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001,
-+	0x0003, 0x7002, 0x7097, 0x0001, 0x0078, 0x4a38, 0x7007, 0x0122,
-+	0x2001, 0x0002, 0x0078, 0x4a30, 0x7007, 0x0121, 0x2001, 0x0003,
-+	0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a,
-+	0xa184, 0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071,
-+	0xa714, 0x684c, 0xa005, 0x00c0, 0x4a4c, 0x7028, 0xc085, 0x702a,
-+	0xa085, 0x0001, 0x0078, 0x4a71, 0x6a60, 0x7236, 0x6b64, 0x733a,
-+	0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e,
-+	0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007,
-+	0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100,
-+	0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001,
-+	0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0,
-+	0x4ac9, 0x6804, 0xa00d, 0x0040, 0x4a8f, 0x0d7e, 0x2071, 0xa600,
-+	0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff,
-+	0x00c0, 0x4a82, 0x702e, 0x70ac, 0xa200, 0x70ae, 0x0d7f, 0x2071,
-+	0xa714, 0x701c, 0xa005, 0x00c0, 0x4adb, 0x0068, 0x4ad9, 0x2071,
-+	0xa835, 0x7200, 0x82ff, 0x0040, 0x4ad9, 0x6934, 0xa186, 0x0103,
-+	0x00c0, 0x4aec, 0x6948, 0x6844, 0xa105, 0x00c0, 0x4acc, 0x2009,
-+	0x8020, 0x2200, 0x0079, 0x4aac, 0x4ad9, 0x4ab1, 0x4b09, 0x4b17,
-+	0x4ad9, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ad9, 0x7122,
-+	0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x2071, 0xa600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
-+	0x70ae, 0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0,
-+	0x4ad9, 0x6868, 0xa005, 0x00c0, 0x4ad9, 0x2009, 0x8020, 0x0078,
-+	0x4aa9, 0x2071, 0xa714, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000,
-+	0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x4ae9, 0x6902, 0x0078,
-+	0x4aea, 0x711e, 0x0078, 0x4ac9, 0xa18c, 0x00ff, 0xa186, 0x0017,
-+	0x0040, 0x4afa, 0xa186, 0x001e, 0x0040, 0x4afa, 0xa18e, 0x001f,
-+	0x00c0, 0x4ad9, 0x684c, 0xd0cc, 0x0040, 0x4ad9, 0x6850, 0xa084,
-+	0x00ff, 0xa086, 0x0001, 0x00c0, 0x4ad9, 0x2009, 0x8021, 0x0078,
-+	0x4aa9, 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4ad9, 0x7186,
-+	0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4b27, 0x7084,
-+	0x8008, 0xa092, 0x000f, 0x00c8, 0x4ad9, 0x7186, 0xae90, 0x0003,
-+	0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088,
-+	0xa10a, 0x0048, 0x4ac0, 0x718c, 0x7084, 0xa10a, 0x0048, 0x4ac0,
-+	0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ac0, 0x2071, 0xa835,
-+	0x7000, 0xa086, 0x0002, 0x00c0, 0x4b47, 0x1078, 0x4dc3, 0x2071,
-+	0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4ac0, 0x1078,
-+	0x4dee, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
-+	0x4ac0, 0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c,
-+	0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084,
-+	0x00ff, 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa714,
-+	0x7004, 0x0079, 0x4b6b, 0x4b75, 0x4b86, 0x4d94, 0x4d95, 0x4dbc,
-+	0x4dc2, 0x4b76, 0x4d82, 0x4d23, 0x4da5, 0x007c, 0x127e, 0x2091,
-+	0x8000, 0x0068, 0x4b85, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091,
-+	0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa8c4,
-+	0x6844, 0xa005, 0x0050, 0x4bae, 0x00c0, 0x4bae, 0x127e, 0x2091,
-+	0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xa720, 0x2004, 0xa10a,
-+	0x0040, 0x4ba9, 0x0068, 0x4bad, 0x2069, 0x0000, 0x6818, 0xd084,
-+	0x00c0, 0x4bad, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
-+	0x4080, 0x2069, 0xa8c4, 0x6847, 0xffff, 0x127f, 0x2069, 0xa600,
-+	0x6848, 0x6964, 0xa102, 0x2069, 0xa835, 0x688a, 0x6984, 0x701c,
-+	0xa06d, 0x0040, 0x4bc0, 0x81ff, 0x0040, 0x4c08, 0x0078, 0x4bd6,
-+	0x81ff, 0x0040, 0x4cda, 0x2071, 0xa835, 0x7184, 0x7088, 0xa10a,
-+	0x00c8, 0x4bd6, 0x7190, 0x2071, 0xa8c4, 0x7040, 0xa005, 0x0040,
-+	0x4bd6, 0x00d0, 0x4cda, 0x7142, 0x0078, 0x4cda, 0x2071, 0xa835,
-+	0x718c, 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4cf7,
-+	0x0068, 0x4c8c, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4c8c,
-+	0x2001, 0xffff, 0x2071, 0xa8c4, 0x7042, 0x2071, 0xa835, 0x7000,
-+	0xa086, 0x0002, 0x00c0, 0x4bfe, 0x1078, 0x4dc3, 0x2071, 0x0000,
-+	0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c, 0x1078, 0x4dee,
-+	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c,
-+	0x2071, 0xa835, 0x7000, 0xa005, 0x0040, 0x4cb9, 0x6934, 0xa186,
-+	0x0103, 0x00c0, 0x4c8f, 0x684c, 0xd0bc, 0x00c0, 0x4cb9, 0x6948,
-+	0x6844, 0xa105, 0x00c0, 0x4cac, 0x2009, 0x8020, 0x2071, 0xa835,
-+	0x7000, 0x0079, 0x4c23, 0x4cb9, 0x4c71, 0x4c49, 0x4c5b, 0x4c28,
-+	0x137e, 0x147e, 0x157e, 0x2099, 0xa676, 0x20a1, 0xa886, 0x20a9,
-+	0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa87d, 0xad80,
-+	0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000,
-+	0x2e10, 0x1078, 0x13db, 0x2071, 0xa714, 0x7007, 0x0009, 0x0078,
-+	0x4cda, 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4cda, 0xae90,
-+	0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa714, 0x1078,
-+	0x4e4c, 0x0078, 0x4cda, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8,
-+	0x4cda, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
-+	0x6840, 0x2012, 0x7186, 0x2071, 0xa714, 0x1078, 0x4e4c, 0x0078,
-+	0x4cda, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8c, 0x2071, 0x0000,
-+	0x7018, 0xd084, 0x00c0, 0x4c8c, 0x7122, 0x683c, 0x7026, 0x6840,
-+	0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa714,
-+	0x1078, 0x4e4c, 0x0078, 0x4cda, 0x127f, 0x0078, 0x4cda, 0xa18c,
-+	0x00ff, 0xa186, 0x0017, 0x0040, 0x4c9d, 0xa186, 0x001e, 0x0040,
-+	0x4c9d, 0xa18e, 0x001f, 0x00c0, 0x4cb9, 0x684c, 0xd0cc, 0x0040,
-+	0x4cb9, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4cb9,
-+	0x2009, 0x8021, 0x0078, 0x4c1e, 0x6844, 0xa086, 0x0100, 0x00c0,
-+	0x4cb9, 0x6868, 0xa005, 0x00c0, 0x4cb9, 0x2009, 0x8020, 0x0078,
-+	0x4c1e, 0x2071, 0xa714, 0x1078, 0x4e60, 0x0040, 0x4cda, 0x2071,
-+	0xa714, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
-+	0x00c0, 0x4cd1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4cd1,
-+	0x710e, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086, 0x0100,
-+	0x0040, 0x4d95, 0x127e, 0x2091, 0x8000, 0x2071, 0xa714, 0x7008,
-+	0xa086, 0x0001, 0x00c0, 0x4cf5, 0x0068, 0x4cf5, 0x2009, 0x000d,
-+	0x7030, 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086,
-+	0x0006, 0x00c0, 0x4cf5, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071,
-+	0xa714, 0x1078, 0x4e60, 0x0040, 0x4d20, 0x2071, 0xa835, 0x7084,
-+	0x700a, 0x20a9, 0x0020, 0x2099, 0xa836, 0x20a1, 0xa85d, 0x53a3,
-+	0x7087, 0x0000, 0x2071, 0xa714, 0x2069, 0xa87d, 0x706c, 0x6826,
-+	0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078,
-+	0x13db, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa8c4, 0x7042,
-+	0x127f, 0x0078, 0x4cda, 0x2069, 0xa87d, 0x6808, 0xa08e, 0x0000,
-+	0x0040, 0x4d81, 0xa08e, 0x0200, 0x0040, 0x4d7f, 0xa08e, 0x0100,
-+	0x00c0, 0x4d81, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d7c, 0x2069,
-+	0x0000, 0x6818, 0xd084, 0x00c0, 0x4d7c, 0x702c, 0x7130, 0x8108,
-+	0xa102, 0x0048, 0x4d4a, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
-+	0x0078, 0x4d54, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d54,
-+	0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000,
-+	0x2001, 0xa85a, 0x2004, 0xa005, 0x00c0, 0x4d73, 0x6934, 0x2069,
-+	0xa835, 0x689c, 0x699e, 0x2069, 0xa8c4, 0xa102, 0x00c0, 0x4d6c,
-+	0x6844, 0xa005, 0x00d0, 0x4d7a, 0x2001, 0xa85b, 0x200c, 0x810d,
-+	0x6946, 0x0078, 0x4d7a, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
-+	0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4d81, 0x7007,
-+	0x0005, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d93, 0x1078, 0x4e60,
-+	0x0040, 0x4d93, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086,
-+	0x0100, 0x0040, 0x4d95, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100,
-+	0x00c0, 0x4d9e, 0x7007, 0x0004, 0x0078, 0x4dbc, 0xa086, 0x0200,
-+	0x00c0, 0x4da4, 0x7007, 0x0005, 0x007c, 0x2001, 0xa87f, 0x2004,
-+	0xa08e, 0x0100, 0x00c0, 0x4db1, 0x7007, 0x0001, 0x1078, 0x4e4c,
-+	0x007c, 0xa08e, 0x0000, 0x0040, 0x4db0, 0xa08e, 0x0200, 0x00c0,
-+	0x4db0, 0x7007, 0x0005, 0x007c, 0x1078, 0x4e16, 0x7006, 0x1078,
-+	0x4e4c, 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa835, 0x7184,
-+	0x81ff, 0x0040, 0x4deb, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071,
-+	0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4de8, 0x2014,
-+	0x722a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x722e, 0x8000, 0x0070,
-+	0x4de8, 0x2014, 0x723a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x723e,
-+	0xa180, 0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e,
-+	0x2071, 0xa835, 0x7184, 0x81ff, 0x0040, 0x4e13, 0xa006, 0x7086,
-+	0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000,
-+	0x2014, 0x722a, 0x8000, 0x0070, 0x4e0c, 0x2014, 0x723a, 0x8000,
-+	0x2014, 0x723e, 0x0078, 0x4e10, 0x2001, 0x8020, 0x0078, 0x4e12,
-+	0x2001, 0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130,
-+	0x8108, 0xa102, 0x0048, 0x4e23, 0xa00e, 0x7034, 0x706e, 0x7038,
-+	0x7072, 0x0078, 0x4e2d, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8,
-+	0x4e2d, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001,
-+	0x700e, 0x00c0, 0x4e43, 0x127e, 0x2091, 0x8000, 0x0068, 0x4e46,
-+	0x2001, 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b,
-+	0x0000, 0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006,
-+	0x700b, 0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4e5f,
-+	0x127e, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e,
-+	0xa005, 0x00c0, 0x4e5c, 0x701a, 0x127f, 0x1078, 0x13a4, 0x007c,
-+	0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4e6f, 0x2304,
-+	0x230c, 0xa10e, 0x0040, 0x4e6f, 0xa006, 0x0078, 0x4e7f, 0x732c,
-+	0x8319, 0x7130, 0xa102, 0x00c0, 0x4e79, 0x2300, 0xa005, 0x0078,
-+	0x4e7f, 0x0048, 0x4e7e, 0xa302, 0x0078, 0x4e7f, 0x8002, 0x007c,
-+	0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e,
-+	0x2091, 0x8000, 0x2009, 0xa8d6, 0x2104, 0xc08d, 0x200a, 0x127f,
-+	0x1078, 0x13f9, 0x007c, 0x2071, 0xa6e2, 0x7003, 0x0000, 0x7007,
-+	0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053,
-+	0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b,
-+	0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071,
-+	0xa6e2, 0x6848, 0xa005, 0x00c0, 0x4ebc, 0x7028, 0xc085, 0x702a,
-+	0xa085, 0x0001, 0x0078, 0x4ee1, 0x6a50, 0x7236, 0x6b54, 0x733a,
-+	0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e,
-+	0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006,
-+	0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272,
-+	0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000,
-+	0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa6e2, 0x7004, 0x1079,
-+	0x4f41, 0x700c, 0x0079, 0x4eec, 0x4ef1, 0x4ee6, 0x4ee6, 0x4ee6,
-+	0x4ee6, 0x007c, 0x700c, 0x0079, 0x4ef5, 0x4efa, 0x4f3f, 0x4f3f,
-+	0x4f40, 0x4f40, 0x7830, 0x7930, 0xa106, 0x0040, 0x4f04, 0x7830,
-+	0x7930, 0xa106, 0x00c0, 0x4f2a, 0x7030, 0xa10a, 0x0040, 0x4f2a,
-+	0x00c8, 0x4f0c, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4f2b,
-+	0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00, 0x705a, 0x7063, 0x0040,
-+	0x2001, 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000,
-+	0x2009, 0xa8d6, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f,
-+	0x1078, 0x13f9, 0x007c, 0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00,
-+	0x705a, 0x1078, 0x1370, 0x00c0, 0x4f37, 0x0078, 0x4f16, 0x2d00,
-+	0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4f1a, 0x007c,
-+	0x007c, 0x4f52, 0x4f53, 0x4f8a, 0x4f8b, 0x4f3f, 0x4fc1, 0x4fc6,
-+	0x4ffd, 0x4ffe, 0x5019, 0x501a, 0x501b, 0x501c, 0x501d, 0x501e,
-+	0x509e, 0x50c8, 0x007c, 0x700c, 0x0079, 0x4f56, 0x4f5b, 0x4f5e,
-+	0x4f6e, 0x4f89, 0x4f89, 0x1078, 0x4ef2, 0x007c, 0x127e, 0x8001,
-+	0x700e, 0x7058, 0x007e, 0x1078, 0x5464, 0x0040, 0x4f6b, 0x2091,
-+	0x8000, 0x1078, 0x4ef2, 0x0d7f, 0x0078, 0x4f77, 0x127e, 0x8001,
-+	0x700e, 0x1078, 0x5464, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803,
-+	0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020,
-+	0x00c8, 0x4f86, 0x1079, 0x4fa1, 0x127f, 0x007c, 0x127f, 0x1078,
-+	0x501f, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa6e2, 0x700c,
-+	0x0079, 0x4f92, 0x4f97, 0x4f97, 0x4f97, 0x4f99, 0x4f9d, 0x0e7f,
-+	0x007c, 0x700f, 0x0001, 0x0078, 0x4f9f, 0x700f, 0x0002, 0x0e7f,
-+	0x007c, 0x501f, 0x501f, 0x503b, 0x501f, 0x5171, 0x501f, 0x501f,
-+	0x501f, 0x501f, 0x501f, 0x503b, 0x51bb, 0x5208, 0x5261, 0x5277,
-+	0x501f, 0x501f, 0x5057, 0x503b, 0x501f, 0x501f, 0x5078, 0x5338,
-+	0x5356, 0x501f, 0x5057, 0x501f, 0x501f, 0x501f, 0x501f, 0x506d,
-+	0x5356, 0x7020, 0x2068, 0x1078, 0x13a4, 0x007c, 0x700c, 0x0079,
-+	0x4fc9, 0x4fce, 0x4fd1, 0x4fe1, 0x4ffc, 0x4ffc, 0x1078, 0x4ef2,
-+	0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5464,
-+	0x0040, 0x4fde, 0x2091, 0x8000, 0x1078, 0x4ef2, 0x0d7f, 0x0078,
-+	0x4fea, 0x127e, 0x8001, 0x700e, 0x1078, 0x5464, 0x7058, 0x2068,
-+	0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084,
-+	0x00ff, 0xa08a, 0x001a, 0x00c8, 0x4ff9, 0x1079, 0x4fff, 0x127f,
-+	0x007c, 0x127f, 0x1078, 0x501f, 0x007c, 0x007c, 0x007c, 0x501f,
-+	0x503b, 0x515b, 0x501f, 0x503b, 0x501f, 0x503b, 0x503b, 0x501f,
-+	0x503b, 0x515b, 0x503b, 0x503b, 0x503b, 0x503b, 0x503b, 0x501f,
-+	0x503b, 0x515b, 0x501f, 0x501f, 0x503b, 0x501f, 0x501f, 0x501f,
-+	0x503b, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007,
-+	0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x4a73, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838,
-+	0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
-+	0x4a73, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
-+	0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4a73, 0x127f,
-+	0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x4a73, 0x127f, 0x007c, 0x6834,
-+	0x8007, 0xa084, 0x00ff, 0x0040, 0x502d, 0x8001, 0x00c0, 0x5064,
-+	0x7007, 0x0001, 0x0078, 0x513a, 0x7007, 0x0006, 0x7012, 0x2d00,
-+	0x7016, 0x701a, 0x704b, 0x513a, 0x007c, 0x684c, 0xa084, 0x00c0,
-+	0xa086, 0x00c0, 0x00c0, 0x5078, 0x7007, 0x0001, 0x0078, 0x5373,
-+	0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098,
-+	0x20a1, 0xa70d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8,
-+	0x5049, 0x6884, 0xa08a, 0x0002, 0x00c8, 0x5049, 0x82ff, 0x00c0,
-+	0x509a, 0x6888, 0x698c, 0xa105, 0x0040, 0x509a, 0x2001, 0x510a,
-+	0x0078, 0x509d, 0xa280, 0x5100, 0x2004, 0x70c6, 0x7010, 0xa015,
-+	0x0040, 0x50e8, 0x1078, 0x1370, 0x00c0, 0x50a9, 0x7007, 0x000f,
-+	0x007c, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004,
-+	0xad00, 0x7096, 0x6008, 0xa20a, 0x00c8, 0x50b8, 0xa00e, 0x2200,
-+	0x7112, 0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x50c1,
-+	0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13db,
-+	0x7090, 0xa08e, 0x0100, 0x0040, 0x50dc, 0xa086, 0x0200, 0x0040,
-+	0x50d4, 0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x13a4,
-+	0x7014, 0x2068, 0x0078, 0x5049, 0x7020, 0x2068, 0x7018, 0x6802,
-+	0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x509e,
-+	0x7014, 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x50f7,
-+	0x6888, 0x698c, 0xa105, 0x0040, 0x50f7, 0x1078, 0x510e, 0x6834,
-+	0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, 0x5373, 0x0078, 0x513a,
-+	0x5102, 0x5106, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f,
-+	0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e,
-+	0x0c7e, 0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0,
-+	0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008,
-+	0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109,
-+	0x0040, 0x5130, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x511d,
-+	0x6004, 0xa065, 0x00c0, 0x5117, 0x067f, 0x077f, 0x0c7f, 0x0e7f,
-+	0x0f7f, 0x007c, 0x2009, 0xa62f, 0x210c, 0x81ff, 0x00c0, 0x5155,
-+	0x6838, 0xa084, 0x00ff, 0x683a, 0x1078, 0x4353, 0x00c0, 0x5149,
-+	0x007c, 0x1078, 0x4b51, 0x127e, 0x2091, 0x8000, 0x1078, 0x8f7d,
-+	0x1078, 0x4a73, 0x127f, 0x0078, 0x5148, 0x2001, 0x0028, 0x2009,
-+	0x0000, 0x0078, 0x5149, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906,
-+	0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x516a, 0x7007, 0x0006,
-+	0x0078, 0x5170, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a,
-+	0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848,
-+	0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x519a,
-+	0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x519a,
-+	0xa005, 0x00c0, 0x51ad, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078,
-+	0x45c4, 0x00c0, 0x51ad, 0x067e, 0x6e50, 0x1078, 0x46b3, 0x067f,
-+	0x0078, 0x51ad, 0x047e, 0x2011, 0xa60c, 0x2224, 0xc484, 0xc48c,
-+	0x2412, 0x047f, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x51a9, 0x1078,
-+	0x4852, 0x8108, 0x00f0, 0x51a3, 0x0c7f, 0x684c, 0xd084, 0x00c0,
-+	0x51b4, 0x1078, 0x13a4, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
-+	0x4a73, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001,
-+	0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x51ff, 0x2061, 0xa933,
-+	0x6100, 0xd184, 0x0040, 0x51df, 0x6858, 0xa084, 0x00ff, 0x00c0,
-+	0x5202, 0x6000, 0xd084, 0x0040, 0x51ff, 0x6004, 0xa005, 0x00c0,
-+	0x5205, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x51fc, 0x2011,
-+	0x0001, 0x6860, 0xa005, 0x00c0, 0x51e7, 0x2001, 0x001e, 0x8000,
-+	0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x51ff, 0x6006, 0x6858,
-+	0x8007, 0xa084, 0x00ff, 0x0040, 0x51ff, 0x600a, 0x6858, 0x8000,
-+	0x00c0, 0x51fb, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5453, 0x127f,
-+	0x0078, 0x544b, 0x127f, 0x0078, 0x5443, 0x127f, 0x0078, 0x5447,
-+	0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa653, 0x2004,
-+	0xd0a4, 0x0040, 0x525e, 0x2061, 0xa933, 0x6000, 0xd084, 0x0040,
-+	0x525e, 0x6204, 0x6308, 0xd08c, 0x00c0, 0x5250, 0x6c48, 0xa484,
-+	0x0003, 0x0040, 0x5236, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0,
-+	0x522f, 0x2100, 0xa210, 0x0048, 0x525b, 0x0078, 0x5236, 0x8001,
-+	0x00c0, 0x525b, 0x2100, 0xa212, 0x0048, 0x525b, 0xa484, 0x000c,
-+	0x0040, 0x5250, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004,
-+	0x00c0, 0x5248, 0x2100, 0xa318, 0x0048, 0x525b, 0x0078, 0x5250,
-+	0xa082, 0x0004, 0x00c0, 0x525b, 0x2100, 0xa31a, 0x0048, 0x525b,
-+	0x6860, 0xa005, 0x0040, 0x5256, 0x8000, 0x6016, 0x6206, 0x630a,
-+	0x127f, 0x0078, 0x5453, 0x127f, 0x0078, 0x544f, 0x127f, 0x0078,
-+	0x544b, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa933,
-+	0x6300, 0xd38c, 0x00c0, 0x5271, 0x6308, 0x8318, 0x0048, 0x5274,
-+	0x630a, 0x127f, 0x0078, 0x5461, 0x127f, 0x0078, 0x544f, 0x127e,
-+	0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040,
-+	0x528b, 0x0c7e, 0x2061, 0xa933, 0x6000, 0xa084, 0xfcff, 0x6002,
-+	0x0c7f, 0x0078, 0x52ba, 0x6858, 0xa005, 0x0040, 0x52d1, 0x685c,
-+	0xa065, 0x0040, 0x52cd, 0x2001, 0xa62f, 0x2004, 0xa005, 0x0040,
-+	0x529d, 0x1078, 0x8ec6, 0x0078, 0x52ab, 0x6013, 0x0400, 0x6037,
-+	0x0000, 0x694c, 0xd1a4, 0x0040, 0x52a7, 0x6950, 0x6136, 0x2009,
-+	0x0041, 0x1078, 0x775c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000,
-+	0x00c0, 0x52ba, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078,
-+	0x5bf1, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x52c9, 0x2061, 0xa933,
-+	0x6000, 0xd08c, 0x00c0, 0x52c9, 0x6008, 0x8000, 0x0048, 0x52cd,
-+	0x600a, 0x0c7f, 0x127f, 0x0078, 0x5453, 0x0c7f, 0x127f, 0x0078,
-+	0x544b, 0x6954, 0xa186, 0x0045, 0x0040, 0x5306, 0xa186, 0x002a,
-+	0x00c0, 0x52e1, 0x2001, 0xa60c, 0x200c, 0xc194, 0x2102, 0x0078,
-+	0x52ba, 0xa186, 0x0020, 0x0040, 0x52fa, 0xa186, 0x0029, 0x0040,
-+	0x52ed, 0xa186, 0x002d, 0x00c0, 0x52cd, 0x6944, 0xa18c, 0xff00,
-+	0x810f, 0x1078, 0x45c4, 0x00c0, 0x52ba, 0x6000, 0xc0e4, 0x6002,
-+	0x0078, 0x52ba, 0x685c, 0xa065, 0x0040, 0x52cd, 0x6007, 0x0024,
-+	0x2001, 0xa8a3, 0x2004, 0x6016, 0x0078, 0x52ba, 0x685c, 0xa065,
-+	0x0040, 0x52cd, 0x0e7e, 0x6860, 0xa075, 0x2001, 0xa62f, 0x2004,
-+	0xa005, 0x0040, 0x531e, 0x1078, 0x8ec6, 0x8eff, 0x0040, 0x531b,
-+	0x2e60, 0x1078, 0x8ec6, 0x0e7f, 0x0078, 0x52ba, 0x6024, 0xc0dc,
-+	0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0040,
-+	0x532f, 0x6007, 0x003b, 0x6874, 0x602a, 0x6878, 0x6012, 0x6003,
-+	0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x0078, 0x52ba,
-+	0x2061, 0xa933, 0x6000, 0xd084, 0x0040, 0x5352, 0xd08c, 0x00c0,
-+	0x5461, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048, 0x534c, 0x6206,
-+	0x2091, 0x8001, 0x0078, 0x5461, 0x2091, 0x8001, 0x6853, 0x0016,
-+	0x0078, 0x545a, 0x6853, 0x0007, 0x0078, 0x545a, 0x6834, 0x8007,
-+	0xa084, 0x00ff, 0x00c0, 0x5360, 0x1078, 0x502d, 0x0078, 0x5372,
-+	0x2030, 0x8001, 0x00c0, 0x536a, 0x7007, 0x0001, 0x1078, 0x5373,
-+	0x0078, 0x5372, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a,
-+	0x704b, 0x5373, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0xa03e,
-+	0x2009, 0xa62f, 0x210c, 0x81ff, 0x00c0, 0x53ff, 0x2009, 0xa60c,
-+	0x210c, 0xd194, 0x00c0, 0x5431, 0x6848, 0x2070, 0xae82, 0xad00,
-+	0x0048, 0x53ef, 0x2001, 0xa616, 0x2004, 0xae02, 0x00c8, 0x53ef,
-+	0x2061, 0xa933, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001, 0x00c0,
-+	0x53d2, 0x711c, 0xa186, 0x0006, 0x00c0, 0x53da, 0x7018, 0xa005,
-+	0x0040, 0x53ff, 0x2004, 0xd0e4, 0x00c0, 0x542b, 0x7024, 0xd0dc,
-+	0x00c0, 0x5435, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7010,
-+	0xa005, 0x00c0, 0x53be, 0x7112, 0x684c, 0xd0f4, 0x00c0, 0x5439,
-+	0x2e60, 0x1078, 0x5b27, 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800,
-+	0xa005, 0x00c0, 0x53be, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x00c0,
-+	0x5439, 0x127f, 0x0e7f, 0x007c, 0x127f, 0x0e7f, 0x6853, 0x0006,
-+	0x0078, 0x545a, 0xd184, 0x0040, 0x53cc, 0xd1c4, 0x00c0, 0x53f3,
-+	0x0078, 0x53f7, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x45c4,
-+	0x00c0, 0x542b, 0x6000, 0xd0e4, 0x00c0, 0x542b, 0x711c, 0xa186,
-+	0x0007, 0x00c0, 0x53ef, 0x6853, 0x0002, 0x0078, 0x542d, 0x6853,
-+	0x0008, 0x0078, 0x542d, 0x6853, 0x000e, 0x0078, 0x542d, 0x6853,
-+	0x0017, 0x0078, 0x542d, 0x6853, 0x0035, 0x0078, 0x542d, 0x2001,
-+	0xa672, 0x2004, 0xd0fc, 0x0040, 0x5427, 0x6848, 0x2070, 0xae82,
-+	0xad00, 0x0048, 0x5427, 0x6058, 0xae02, 0x00c8, 0x5427, 0x711c,
-+	0xa186, 0x0006, 0x00c0, 0x5427, 0x7018, 0xa005, 0x0040, 0x5427,
-+	0x2004, 0xd0bc, 0x0040, 0x5427, 0x2039, 0x0001, 0x7000, 0xa086,
-+	0x0007, 0x00c0, 0x537e, 0x7003, 0x0002, 0x0078, 0x537e, 0x6853,
-+	0x0028, 0x0078, 0x542d, 0x6853, 0x0029, 0x127f, 0x0e7f, 0x0078,
-+	0x545a, 0x6853, 0x002a, 0x0078, 0x542d, 0x6853, 0x0045, 0x0078,
-+	0x542d, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x1078, 0x9dc7,
-+	0x127f, 0x0e7f, 0x007c, 0x2009, 0x003e, 0x0078, 0x5455, 0x2009,
-+	0x0004, 0x0078, 0x5455, 0x2009, 0x0006, 0x0078, 0x5455, 0x2009,
-+	0x0016, 0x0078, 0x5455, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00,
-+	0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x4a73, 0x2091, 0x8001,
-+	0x007c, 0x1078, 0x13a4, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102,
-+	0x0048, 0x5471, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0078,
-+	0x547d, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8, 0x547d, 0x7074,
-+	0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x007c,
-+	0x0d7e, 0x1078, 0x5b1e, 0x0d7f, 0x007c, 0x0d7e, 0x2011, 0x0004,
-+	0x2204, 0xa085, 0x8002, 0x2012, 0x0d7f, 0x007c, 0x20e1, 0x0002,
-+	0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0040, 0x549c,
-+	0xa086, 0x1000, 0x00c0, 0x54d3, 0x20e1, 0x0000, 0x3d00, 0xa094,
-+	0xff00, 0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x00c0, 0x54b7,
-+	0xa184, 0xff00, 0x8007, 0xa086, 0x0008, 0x00c0, 0x54d3, 0x1078,
-+	0x29bb, 0x00c0, 0x54d3, 0x1078, 0x56b2, 0x0078, 0x54ce, 0x20e1,
-+	0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x54be, 0x3e60, 0xac84, 0x000f,
-+	0x00c0, 0x54d3, 0xac82, 0xad00, 0x0048, 0x54d3, 0x6858, 0xac02,
-+	0x00c8, 0x54d3, 0x2009, 0x0047, 0x1078, 0x775c, 0x7a1c, 0xd284,
-+	0x00c0, 0x548e, 0x007c, 0xa016, 0x1078, 0x15fa, 0x0078, 0x54ce,
-+	0x0078, 0x54d3, 0x781c, 0xd08c, 0x0040, 0x5502, 0x157e, 0x137e,
-+	0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076, 0x00c0,
-+	0x5518, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x5507, 0x1078,
-+	0x554e, 0x0040, 0x5518, 0x20e1, 0x3000, 0x7828, 0x7828, 0x1078,
-+	0x556c, 0x147f, 0x137f, 0x157f, 0x2009, 0xa8b9, 0x2104, 0xa005,
-+	0x00c0, 0x5503, 0x007c, 0x1078, 0x62d1, 0x0078, 0x5502, 0xa484,
-+	0x7000, 0x00c0, 0x5518, 0x1078, 0x554e, 0x0040, 0x552c, 0x7000,
-+	0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x54f3, 0x0078, 0x552c,
-+	0x1078, 0xa54f, 0xd5a4, 0x0040, 0x5528, 0x047e, 0x1078, 0x1b22,
-+	0x047f, 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5530,
-+	0x1078, 0x554e, 0x6883, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828,
-+	0x1078, 0x5537, 0x147f, 0x137f, 0x157f, 0x0078, 0x5502, 0x2001,
-+	0xa60e, 0x2004, 0xd08c, 0x0040, 0x554d, 0x2001, 0xa600, 0x2004,
-+	0xa086, 0x0003, 0x00c0, 0x554d, 0x027e, 0x037e, 0x2011, 0x8048,
-+	0x2518, 0x1078, 0x361b, 0x037f, 0x027f, 0x007c, 0xa484, 0x01ff,
-+	0x6882, 0xa005, 0x0040, 0x5560, 0xa080, 0x001f, 0xa084, 0x03f8,
-+	0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c,
-+	0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
-+	0xa085, 0x0001, 0x0078, 0x555f, 0x7000, 0xa084, 0xff00, 0xa08c,
-+	0xf000, 0x8007, 0xa196, 0x0000, 0x00c0, 0x5579, 0x0078, 0x57ba,
-+	0x007c, 0xa196, 0x2000, 0x00c0, 0x558a, 0x6900, 0xa18e, 0x0001,
-+	0x00c0, 0x5586, 0x1078, 0x3aec, 0x0078, 0x5578, 0x1078, 0x5592,
-+	0x0078, 0x5578, 0xa196, 0x8000, 0x00c0, 0x5578, 0x1078, 0x5871,
-+	0x0078, 0x5578, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196,
-+	0x0001, 0x0040, 0x559f, 0xa196, 0x0023, 0x00c0, 0x56aa, 0xa08e,
-+	0x0023, 0x00c0, 0x55d4, 0x1078, 0x591d, 0x0040, 0x56aa, 0x7124,
-+	0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x55b8, 0x7034, 0xa005,
-+	0x00c0, 0x56aa, 0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x56aa,
-+	0xa08e, 0x0214, 0x0040, 0x55c0, 0xa08e, 0x0210, 0x00c0, 0x55c6,
-+	0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x56aa, 0xa08e, 0x0100,
-+	0x00c0, 0x56aa, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x0016,
-+	0x1078, 0x775c, 0x0078, 0x56aa, 0xa08e, 0x0022, 0x00c0, 0x56aa,
-+	0x7030, 0xa08e, 0x0300, 0x00c0, 0x55e5, 0x7034, 0xa005, 0x00c0,
-+	0x56aa, 0x2009, 0x0017, 0x0078, 0x5676, 0xa08e, 0x0500, 0x00c0,
-+	0x55f1, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x0018, 0x0078,
-+	0x5676, 0xa08e, 0x2010, 0x00c0, 0x55f9, 0x2009, 0x0019, 0x0078,
-+	0x5676, 0xa08e, 0x2110, 0x00c0, 0x5601, 0x2009, 0x001a, 0x0078,
-+	0x5676, 0xa08e, 0x5200, 0x00c0, 0x560d, 0x7034, 0xa005, 0x00c0,
-+	0x56aa, 0x2009, 0x001b, 0x0078, 0x5676, 0xa08e, 0x5000, 0x00c0,
-+	0x5619, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x001c, 0x0078,
-+	0x5676, 0xa08e, 0x1300, 0x00c0, 0x5621, 0x2009, 0x0034, 0x0078,
-+	0x5676, 0xa08e, 0x1200, 0x00c0, 0x562d, 0x7034, 0xa005, 0x00c0,
-+	0x56aa, 0x2009, 0x0024, 0x0078, 0x5676, 0xa08c, 0xff00, 0xa18e,
-+	0x2400, 0x00c0, 0x5637, 0x2009, 0x002d, 0x0078, 0x5676, 0xa08c,
-+	0xff00, 0xa18e, 0x5300, 0x00c0, 0x5641, 0x2009, 0x002a, 0x0078,
-+	0x5676, 0xa08e, 0x0f00, 0x00c0, 0x5649, 0x2009, 0x0020, 0x0078,
-+	0x5676, 0xa08e, 0x5300, 0x00c0, 0x564f, 0x0078, 0x566c, 0xa08e,
-+	0x6104, 0x00c0, 0x566c, 0x2011, 0xab8d, 0x8208, 0x2204, 0xa082,
-+	0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108,
-+	0x047e, 0x2124, 0x1078, 0x361b, 0x047f, 0x8108, 0x00f0, 0x565c,
-+	0x2009, 0x0023, 0x0078, 0x5676, 0xa08e, 0x6000, 0x00c0, 0x5674,
-+	0x2009, 0x003f, 0x0078, 0x5676, 0x2009, 0x001d, 0x017e, 0x2011,
-+	0xab83, 0x2204, 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x56ac,
-+	0x1078, 0x455c, 0x00c0, 0x56ac, 0x6612, 0x6516, 0x86ff, 0x0040,
-+	0x569c, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x569c, 0x686c,
-+	0xa606, 0x00c0, 0x569c, 0x6870, 0xa506, 0xa084, 0xff00, 0x00c0,
-+	0x569c, 0x6000, 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x76c7, 0x0040,
-+	0x56af, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f,
-+	0x1078, 0x775c, 0x0c7f, 0x007c, 0x017f, 0x0078, 0x56aa, 0x0c7f,
-+	0x0078, 0x56ac, 0x0c7e, 0x1078, 0x570f, 0x00c0, 0x570d, 0xa28e,
-+	0x0033, 0x00c0, 0x56de, 0x1078, 0x591d, 0x0040, 0x570d, 0x7124,
-+	0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x56d0, 0x7034, 0xa005,
-+	0x00c0, 0x570d, 0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x570d,
-+	0xa08e, 0x0100, 0x00c0, 0x570d, 0x7034, 0xa005, 0x00c0, 0x570d,
-+	0x2009, 0x0016, 0x1078, 0x775c, 0x0078, 0x570d, 0xa28e, 0x0032,
-+	0x00c0, 0x570d, 0x7030, 0xa08e, 0x1400, 0x00c0, 0x570d, 0x2009,
-+	0x0038, 0x017e, 0x2011, 0xab83, 0x2204, 0x8211, 0x220c, 0x1078,
-+	0x254d, 0x00c0, 0x570c, 0x1078, 0x455c, 0x00c0, 0x570c, 0x6612,
-+	0x6516, 0x0c7e, 0x1078, 0x76c7, 0x0040, 0x570b, 0x017f, 0x611a,
-+	0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x775c, 0x1078,
-+	0x62d1, 0x0078, 0x570d, 0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e,
-+	0x0d7e, 0x027e, 0x017e, 0x137e, 0x147e, 0x157e, 0x3c00, 0x007e,
-+	0x2079, 0x0030, 0x2069, 0x0200, 0x1078, 0x1c6a, 0x00c0, 0x5750,
-+	0x1078, 0x1b40, 0x0040, 0x575d, 0x7908, 0xa18c, 0x1fff, 0xa182,
-+	0x0011, 0x00c8, 0x575a, 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0,
-+	0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004,
-+	0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140,
-+	0x10c8, 0x1332, 0x80ac, 0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5,
-+	0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, 0x0004, 0xa294, 0x0070,
-+	0x007f, 0x20e0, 0x157f, 0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f,
-+	0x0f7f, 0x007c, 0xa016, 0x1078, 0x15fa, 0xa085, 0x0001, 0x0078,
-+	0x5750, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff,
-+	0x00c0, 0x5782, 0xa596, 0xfffd, 0x00c0, 0x5772, 0x2009, 0x007f,
-+	0x0078, 0x57b5, 0xa596, 0xfffe, 0x00c0, 0x577a, 0x2009, 0x007e,
-+	0x0078, 0x57b5, 0xa596, 0xfffc, 0x00c0, 0x5782, 0x2009, 0x0080,
-+	0x0078, 0x57b5, 0x2011, 0x0000, 0x2021, 0x0081, 0x20a9, 0x007e,
-+	0x2071, 0xa7b6, 0x2e1c, 0x83ff, 0x00c0, 0x5794, 0x82ff, 0x00c0,
-+	0x57a9, 0x2410, 0x0078, 0x57a9, 0x2368, 0x6f10, 0x007e, 0x2100,
-+	0xa706, 0x007f, 0x6b14, 0x00c0, 0x57a3, 0xa346, 0x00c0, 0x57a3,
-+	0x2408, 0x0078, 0x57b5, 0x87ff, 0x00c0, 0x57a9, 0x83ff, 0x0040,
-+	0x578e, 0x8420, 0x8e70, 0x00f0, 0x578a, 0x82ff, 0x00c0, 0x57b4,
-+	0xa085, 0x0001, 0x0078, 0x57b6, 0x2208, 0xa006, 0x0d7f, 0x0e7f,
-+	0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x57bf, 0x007c, 0x57c7,
-+	0x57c7, 0x57c7, 0x5933, 0x57c7, 0x57c8, 0x57e1, 0x5858, 0x007c,
-+	0x7110, 0xd1bc, 0x0040, 0x57e0, 0x7120, 0x2160, 0xac8c, 0x000f,
-+	0x00c0, 0x57e0, 0xac8a, 0xad00, 0x0048, 0x57e0, 0x6858, 0xac02,
-+	0x00c8, 0x57e0, 0x7124, 0x610a, 0x2009, 0x0046, 0x1078, 0x775c,
-+	0x007c, 0x0c7e, 0xa484, 0x01ff, 0x0040, 0x5833, 0x7110, 0xd1bc,
-+	0x00c0, 0x5833, 0x2011, 0xab83, 0x2204, 0x8211, 0x220c, 0x1078,
-+	0x254d, 0x00c0, 0x5833, 0x1078, 0x455c, 0x00c0, 0x5833, 0x6612,
-+	0x6516, 0x6000, 0xd0ec, 0x00c0, 0x5833, 0x6204, 0xa294, 0xff00,
-+	0x8217, 0xa286, 0x0006, 0x00c0, 0x5818, 0x0c7e, 0x1078, 0x76c7,
-+	0x017f, 0x0040, 0x5835, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
-+	0x7130, 0x6122, 0x2009, 0x0044, 0x1078, 0x775c, 0x0078, 0x5833,
-+	0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f,
-+	0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x582b, 0x6007,
-+	0x0005, 0x0078, 0x582d, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
-+	0x5dd7, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x2001, 0xa60d, 0x2004,
-+	0xd0ec, 0x0040, 0x583f, 0x2011, 0x8049, 0x1078, 0x361b, 0x0c7e,
-+	0x1078, 0x9187, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f, 0x0006,
-+	0x7120, 0x610a, 0x7130, 0x6122, 0x6013, 0x0300, 0x6003, 0x0001,
-+	0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x5833,
-+	0x7110, 0xd1bc, 0x0040, 0x5870, 0x7020, 0x2060, 0xac84, 0x000f,
-+	0x00c0, 0x5870, 0xac82, 0xad00, 0x0048, 0x5870, 0x6858, 0xac02,
-+	0x00c8, 0x5870, 0x7124, 0x610a, 0x2009, 0x0045, 0x1078, 0x775c,
-+	0x007c, 0x007e, 0x1078, 0x29bb, 0x007f, 0x00c0, 0x5887, 0x7110,
-+	0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x00c0, 0x5887, 0xa084,
-+	0x000f, 0xa08a, 0x0006, 0x00c8, 0x5887, 0x1079, 0x5888, 0x007c,
-+	0x588e, 0x588f, 0x588e, 0x588e, 0x58ff, 0x590e, 0x007c, 0x7110,
-+	0xd1bc, 0x0040, 0x5897, 0x702c, 0xd084, 0x0040, 0x58fe, 0x700c,
-+	0x7108, 0x1078, 0x254d, 0x00c0, 0x58fe, 0x1078, 0x455c, 0x00c0,
-+	0x58fe, 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x0040, 0x58c9,
-+	0xa28c, 0x00ff, 0xa186, 0x0004, 0x0040, 0x58b2, 0xa186, 0x0006,
-+	0x00c0, 0x58ef, 0x0c7e, 0x1078, 0x591d, 0x0c7f, 0x0040, 0x58fe,
-+	0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f,
-+	0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x1078, 0x775c, 0x0078,
-+	0x58fe, 0xa28c, 0x00ff, 0xa186, 0x0006, 0x0040, 0x58de, 0xa186,
-+	0x0004, 0x0040, 0x58de, 0xa294, 0xff00, 0x8217, 0xa286, 0x0004,
-+	0x0040, 0x58de, 0xa286, 0x0006, 0x00c0, 0x58ef, 0x0c7e, 0x1078,
-+	0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f, 0x0005, 0x7120,
-+	0x610a, 0x2009, 0x0088, 0x1078, 0x775c, 0x0078, 0x58fe, 0x0c7e,
-+	0x1078, 0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f, 0x0004,
-+	0x7120, 0x610a, 0x2009, 0x0001, 0x1078, 0x775c, 0x007c, 0x7110,
-+	0xd1bc, 0x0040, 0x590d, 0x1078, 0x591d, 0x0040, 0x590d, 0x7124,
-+	0x610a, 0x2009, 0x0089, 0x1078, 0x775c, 0x007c, 0x7110, 0xd1bc,
-+	0x0040, 0x591c, 0x1078, 0x591d, 0x0040, 0x591c, 0x7124, 0x610a,
-+	0x2009, 0x008a, 0x1078, 0x775c, 0x007c, 0x7020, 0x2060, 0xac84,
-+	0x000f, 0x00c0, 0x5930, 0xac82, 0xad00, 0x0048, 0x5930, 0x2001,
-+	0xa616, 0x2004, 0xac02, 0x00c8, 0x5930, 0xa085, 0x0001, 0x007c,
-+	0xa006, 0x0078, 0x592f, 0x7110, 0xd1bc, 0x00c0, 0x5949, 0x7024,
-+	0x2060, 0xac84, 0x000f, 0x00c0, 0x5949, 0xac82, 0xad00, 0x0048,
-+	0x5949, 0x6858, 0xac02, 0x00c8, 0x5949, 0x2009, 0x0051, 0x1078,
-+	0x775c, 0x007c, 0x2071, 0xa8c4, 0x7003, 0x0003, 0x700f, 0x0361,
-+	0xa006, 0x701a, 0x7012, 0x7017, 0xad00, 0x7007, 0x0000, 0x7026,
-+	0x702b, 0x6e1c, 0x7032, 0x7037, 0x6e70, 0x703b, 0x0002, 0x703f,
-+	0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c, 0x2071, 0xa8c4,
-+	0x00e0, 0x5a32, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x00c0,
-+	0x59de, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091, 0x8000,
-+	0x7138, 0x8109, 0x713a, 0x00c0, 0x59dc, 0x703b, 0x0002, 0x2009,
-+	0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x59dc, 0x703c, 0xa086,
-+	0x0001, 0x00c0, 0x59b9, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
-+	0x4000, 0x0040, 0x5997, 0x6803, 0x1000, 0x0078, 0x599e, 0x6804,
-+	0xa084, 0x1000, 0x0040, 0x599e, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x703f, 0x0000, 0x2069, 0xa8b1, 0x6804, 0xa082, 0x0006, 0x00c0,
-+	0x59ab, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0, 0x59b2,
-+	0x6833, 0x0000, 0x1078, 0x62d1, 0x1078, 0x639b, 0x0d7f, 0x0078,
-+	0x59dc, 0x0d7e, 0x2069, 0xa600, 0x6948, 0x6864, 0xa102, 0x00c8,
-+	0x59db, 0x2069, 0xa8b1, 0x6804, 0xa086, 0x0000, 0x00c0, 0x59db,
-+	0x6830, 0xa086, 0x0000, 0x00c0, 0x59db, 0x703f, 0x0001, 0x6807,
-+	0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e, 0x2069,
-+	0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x59e1, 0x127e, 0x2091,
-+	0x8000, 0x7024, 0xa00d, 0x0040, 0x59f9, 0x7020, 0x8001, 0x7022,
-+	0x00c0, 0x59f9, 0x7023, 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8,
-+	0x00c0, 0x59f4, 0x7028, 0x107a, 0x81ff, 0x00c0, 0x59f9, 0x7028,
-+	0x107a, 0x7030, 0xa00d, 0x0040, 0x5a10, 0x702c, 0x8001, 0x702e,
-+	0x00c0, 0x5a10, 0x702f, 0x0009, 0x8109, 0x7132, 0x0040, 0x5a0e,
-+	0xa184, 0x007f, 0x1040, 0x6ea2, 0x0078, 0x5a10, 0x7034, 0x107a,
-+	0x7040, 0xa005, 0x0040, 0x5a18, 0x0050, 0x5a18, 0x8001, 0x7042,
-+	0x7044, 0xa005, 0x0040, 0x5a20, 0x0050, 0x5a20, 0x8001, 0x7046,
-+	0x7018, 0xa00d, 0x0040, 0x5a31, 0x7008, 0x8001, 0x700a, 0x00c0,
-+	0x5a31, 0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x5a31, 0x701c,
-+	0x107a, 0x127f, 0x7004, 0x0079, 0x5a35, 0x5a5c, 0x5a5d, 0x5a79,
-+	0x0e7e, 0x2071, 0xa8c4, 0x7018, 0xa005, 0x00c0, 0x5a43, 0x711a,
-+	0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071,
-+	0xa8c4, 0x701c, 0xa206, 0x00c0, 0x5a4f, 0x701a, 0x701e, 0x007f,
-+	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa8c4, 0x6088, 0xa102, 0x0048,
-+	0x5a5a, 0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x45c4,
-+	0x00c0, 0x5a6f, 0x6088, 0x8001, 0x0048, 0x5a6f, 0x608a, 0x00c0,
-+	0x5a6f, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x8108,
-+	0xa182, 0x00ff, 0x0048, 0x5a77, 0xa00e, 0x7007, 0x0002, 0x7112,
-+	0x007c, 0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005,
-+	0x0040, 0x5a88, 0x8001, 0x603e, 0x00c0, 0x5a88, 0x1078, 0x8f9c,
-+	0x6014, 0xa005, 0x0040, 0x5ab2, 0x8001, 0x6016, 0x00c0, 0x5ab2,
-+	0x611c, 0xa186, 0x0003, 0x0040, 0x5a99, 0xa186, 0x0006, 0x00c0,
-+	0x5ab0, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x5ab0,
-+	0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5aa9, 0x2001,
-+	0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5ab2,
-+	0x1078, 0x8abe, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xcd00,
-+	0xa102, 0x0048, 0x5abf, 0x7017, 0xad00, 0x7007, 0x0000, 0x007c,
-+	0x0e7e, 0x2071, 0xa8c4, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b,
-+	0x0002, 0x0e7f, 0x007c, 0x2001, 0xa8cd, 0x2003, 0x0000, 0x007c,
-+	0x0e7e, 0x2071, 0xa8c4, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c,
-+	0x2011, 0xa8d0, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa8c4,
-+	0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e,
-+	0x0f7e, 0x2079, 0xa600, 0x7a34, 0xd294, 0x0040, 0x5b15, 0x2071,
-+	0xa8ac, 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5b02, 0xa0fe, 0x0001,
-+	0x0040, 0x5b06, 0xa0fe, 0x0002, 0x00c0, 0x5b11, 0xa292, 0x0085,
-+	0x0078, 0x5b08, 0xa292, 0x0005, 0x0078, 0x5b08, 0xa292, 0x0002,
-+	0x2272, 0x0040, 0x5b0d, 0x00c8, 0x5b15, 0x2011, 0x8037, 0x1078,
-+	0x361b, 0x2011, 0xa8ab, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f,
-+	0x007c, 0x0c7e, 0x2061, 0xa933, 0x0c7f, 0x007c, 0xa184, 0x000f,
-+	0x8003, 0x8003, 0x8003, 0xa080, 0xa933, 0x2060, 0x007c, 0x6854,
-+	0xa08a, 0x199a, 0x0048, 0x5b2e, 0x2001, 0x1999, 0xa005, 0x00c0,
-+	0x5b3d, 0x0c7e, 0x2061, 0xa933, 0x6014, 0x0c7f, 0xa005, 0x00c0,
-+	0x5b42, 0x2001, 0x001e, 0x0078, 0x5b42, 0xa08e, 0xffff, 0x00c0,
-+	0x5b42, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c,
-+	0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5b9e, 0xd0b4, 0x00c0,
-+	0x5b59, 0xd0bc, 0x00c0, 0x5b8b, 0x2009, 0x0006, 0x1078, 0x5bc3,
-+	0x007c, 0xd0fc, 0x0040, 0x5b64, 0xa084, 0x0003, 0x0040, 0x5b64,
-+	0xa086, 0x0003, 0x00c0, 0x5bbc, 0x6024, 0xd0d4, 0x0040, 0x5b6e,
-+	0xc0d4, 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa674,
-+	0x2104, 0xd084, 0x0040, 0x5b83, 0x6118, 0xa188, 0x0027, 0x2104,
-+	0xd08c, 0x00c0, 0x5b83, 0x87ff, 0x00c0, 0x5b82, 0x2009, 0x0042,
-+	0x1078, 0x775c, 0x007c, 0x87ff, 0x00c0, 0x5b8a, 0x2009, 0x0043,
-+	0x1078, 0x775c, 0x007c, 0xd0fc, 0x0040, 0x5b96, 0xa084, 0x0003,
-+	0x0040, 0x5b96, 0xa086, 0x0003, 0x00c0, 0x5bbc, 0x87ff, 0x00c0,
-+	0x5b9d, 0x2009, 0x0042, 0x1078, 0x775c, 0x007c, 0xd0fc, 0x0040,
-+	0x5baf, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0040, 0x5bb3, 0x87ff,
-+	0x00c0, 0x5bae, 0x2009, 0x0041, 0x1078, 0x775c, 0x007c, 0x1078,
-+	0x5bc1, 0x0078, 0x5bae, 0x87ff, 0x00c0, 0x5bae, 0x2009, 0x0043,
-+	0x1078, 0x775c, 0x0078, 0x5bae, 0x2009, 0x0004, 0x1078, 0x5bc3,
-+	0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
-+	0x5bef, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
-+	0x5be5, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5be5,
-+	0x0c7e, 0x2061, 0xa933, 0x6200, 0xd28c, 0x00c0, 0x5be4, 0x6204,
-+	0x8210, 0x0048, 0x5be4, 0x6206, 0x0c7f, 0x1078, 0x4a73, 0x6010,
-+	0xa06d, 0x077e, 0x2039, 0x0000, 0x10c0, 0x5b27, 0x077f, 0x0d7f,
-+	0x007c, 0x157e, 0x0c7e, 0x2061, 0xa933, 0x6000, 0x81ff, 0x0040,
-+	0x5bfc, 0xa205, 0x0078, 0x5bfd, 0xa204, 0x6002, 0x0c7f, 0x157f,
-+	0x007c, 0x6800, 0xd08c, 0x00c0, 0x5c0d, 0x6808, 0xa005, 0x0040,
-+	0x5c0d, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x20a9, 0x0010,
-+	0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x5c17, 0xa200, 0x00f0,
-+	0x5c12, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005,
-+	0x0040, 0x5c3d, 0xa11a, 0x00c8, 0x5c3d, 0x8213, 0x818d, 0x0048,
-+	0x5c30, 0xa11a, 0x00c8, 0x5c31, 0x00f0, 0x5c25, 0x0078, 0x5c35,
-+	0xa11a, 0x2308, 0x8210, 0x00f0, 0x5c25, 0x007e, 0x3200, 0xa084,
-+	0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085,
-+	0x0800, 0x0078, 0x5c39, 0x127e, 0x2091, 0x2200, 0x2079, 0xa8b1,
-+	0x127f, 0x0d7e, 0x2069, 0xa8b1, 0x6803, 0x0005, 0x2069, 0x0004,
-+	0x2d04, 0xa085, 0x8001, 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027,
-+	0x0001, 0x7804, 0xa084, 0x0007, 0x0079, 0x5c5e, 0x5c68, 0x5c8d,
-+	0x5ce8, 0x5c6e, 0x5c8d, 0x5c68, 0x5c66, 0x5c66, 0x1078, 0x1332,
-+	0x1078, 0x5acb, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x62c0, 0x82ff,
-+	0x00c0, 0x5c74, 0x0c7f, 0x007c, 0x2011, 0x41dc, 0x1078, 0x5a45,
-+	0x7828, 0xa092, 0x00c8, 0x00c8, 0x5c83, 0x8000, 0x782a, 0x1078,
-+	0x421b, 0x0078, 0x5c72, 0x1078, 0x41dc, 0x7807, 0x0003, 0x7827,
-+	0x0000, 0x782b, 0x0000, 0x0078, 0x5c72, 0x1078, 0x5acb, 0x3c00,
-+	0x007e, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x007f, 0x20e0,
-+	0x82ff, 0x0040, 0x5cab, 0x62c0, 0x82ff, 0x00c0, 0x5cab, 0x782b,
-+	0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013, 0x1078,
-+	0x775c, 0x0c7f, 0x007c, 0x3900, 0xa082, 0xa9e3, 0x00c8, 0x5cb2,
-+	0x1078, 0x747a, 0x0c7e, 0x7824, 0xa065, 0x1040, 0x1332, 0x7804,
-+	0xa086, 0x0004, 0x0040, 0x5d2d, 0x7828, 0xa092, 0x2710, 0x00c8,
-+	0x5cc8, 0x8000, 0x782a, 0x0c7f, 0x1078, 0x6e01, 0x0078, 0x5ca9,
-+	0x6104, 0xa186, 0x0003, 0x00c0, 0x5cdf, 0x0e7e, 0x2071, 0xa600,
-+	0x70d8, 0x0e7f, 0xd08c, 0x0040, 0x5cdf, 0x0c7e, 0x0e7e, 0x2061,
-+	0x0100, 0x2071, 0xa600, 0x1078, 0x4224, 0x0e7f, 0x0c7f, 0x1078,
-+	0xa5c4, 0x2009, 0x0014, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x5ca9,
-+	0x2001, 0xa8cd, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5cfc,
-+	0x782b, 0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013,
-+	0x1078, 0x77b3, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x3900, 0xa082,
-+	0xa9e3, 0x00c8, 0x5d05, 0x1078, 0x747a, 0x7824, 0xa005, 0x1040,
-+	0x1332, 0x781c, 0xa06d, 0x1040, 0x1332, 0x6800, 0xc0dc, 0x6802,
-+	0x7924, 0x2160, 0x1078, 0x772d, 0x693c, 0x81ff, 0x1040, 0x1332,
-+	0x8109, 0x693e, 0x6854, 0xa015, 0x0040, 0x5d21, 0x7a1e, 0x0078,
-+	0x5d23, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f,
-+	0x0c7f, 0x1078, 0x62d1, 0x0078, 0x5cfa, 0x6104, 0xa186, 0x0002,
-+	0x0040, 0x5d38, 0xa186, 0x0004, 0x0040, 0x5d38, 0x0078, 0x5cbc,
-+	0x7808, 0xac06, 0x0040, 0x5cbc, 0x1078, 0x61cd, 0x1078, 0x5dd7,
-+	0x0c7f, 0x1078, 0x62d1, 0x0078, 0x5ca9, 0x0c7e, 0x6027, 0x0002,
-+	0x62c8, 0x82ff, 0x00c0, 0x5d61, 0x62c4, 0x82ff, 0x00c0, 0x5d61,
-+	0x793c, 0xa1e5, 0x0000, 0x0040, 0x5d5b, 0x2009, 0x0049, 0x1078,
-+	0x775c, 0x0c7f, 0x007c, 0x2011, 0xa8d0, 0x2013, 0x0000, 0x0078,
-+	0x5d59, 0x3908, 0xa192, 0xa9e3, 0x00c8, 0x5d68, 0x1078, 0x747a,
-+	0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5d5b, 0x7944, 0xa192,
-+	0x7530, 0x00c8, 0x5d85, 0x8108, 0x7946, 0x793c, 0xa188, 0x0007,
-+	0x210c, 0xa18e, 0x0006, 0x00c0, 0x5d81, 0x6017, 0x0012, 0x0078,
-+	0x5d59, 0x6017, 0x0016, 0x0078, 0x5d59, 0x7848, 0xc085, 0x784a,
-+	0x0078, 0x5d59, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000,
-+	0x600f, 0x0000, 0x2c08, 0x2061, 0xa8b1, 0x6020, 0x8000, 0x6022,
-+	0x6010, 0xa005, 0x0040, 0x5da5, 0xa080, 0x0003, 0x2102, 0x6112,
-+	0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078,
-+	0x5da0, 0x0d7e, 0x2069, 0xa8b1, 0x6000, 0xd0d4, 0x0040, 0x5dbe,
-+	0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x5db9, 0x2c00,
-+	0x681e, 0x6804, 0xa084, 0x0007, 0x0079, 0x62d9, 0xc0d5, 0x6002,
-+	0x6818, 0xa005, 0x0040, 0x5dd0, 0x6056, 0x605b, 0x0000, 0x007e,
-+	0x2c00, 0x681a, 0x0d7f, 0x685a, 0x2069, 0xa8b1, 0x0078, 0x5db0,
-+	0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x5db0, 0x007e,
-+	0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08,
-+	0x2061, 0xa8b1, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040,
-+	0x5df2, 0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f,
-+	0x007f, 0x007c, 0x610e, 0x610a, 0x0078, 0x5ded, 0x0c7e, 0x600f,
-+	0x0000, 0x2c08, 0x2061, 0xa8b1, 0x6034, 0xa005, 0x0040, 0x5e06,
-+	0xa080, 0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136,
-+	0x0078, 0x5e04, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e,
-+	0x037e, 0x027e, 0x017e, 0x007e, 0x127e, 0xa02e, 0x2071, 0xa8b1,
-+	0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x5e8c,
-+	0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5e87, 0x87ff,
-+	0x0040, 0x5e2e, 0x6020, 0xa106, 0x00c0, 0x5e87, 0x703c, 0xac06,
-+	0x00c0, 0x5e44, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x7033,
-+	0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b,
-+	0x0000, 0x037f, 0x2029, 0x0001, 0x7038, 0xac36, 0x00c0, 0x5e4a,
-+	0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5e58, 0x2c00, 0xaf36,
-+	0x0040, 0x5e56, 0x2f00, 0x7036, 0x0078, 0x5e58, 0x7037, 0x0000,
-+	0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5e61, 0x7e0e, 0x0078,
-+	0x5e62, 0x2678, 0x600f, 0x0000, 0x1078, 0x8d06, 0x0040, 0x5e82,
-+	0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e9d, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x077e, 0x1078,
-+	0x8f7d, 0x1078, 0xa4e2, 0x1078, 0x4a73, 0x077f, 0x037f, 0x017f,
-+	0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x5e1d, 0x2c78,
-+	0x600c, 0x2060, 0x0078, 0x5e1d, 0x85ff, 0x0040, 0x5e91, 0x1078,
-+	0x639b, 0x127f, 0x007f, 0x017f, 0x027f, 0x037f, 0x057f, 0x067f,
-+	0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006,
-+	0x00c0, 0x5e6f, 0x017e, 0x037e, 0x077e, 0x1078, 0xa4e2, 0x1078,
-+	0xa1ca, 0x077f, 0x037f, 0x017f, 0x0078, 0x5e82, 0x007e, 0x067e,
-+	0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000,
-+	0x2079, 0xa8b1, 0x7838, 0xa065, 0x0040, 0x5eef, 0x600c, 0x007e,
-+	0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x5ed6, 0x037e, 0x2019,
-+	0x0001, 0x1078, 0x7058, 0x7833, 0x0000, 0x783f, 0x0000, 0x7843,
-+	0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x037f, 0x1078, 0x8d06,
-+	0x0040, 0x5eea, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0,
-+	0x5ef8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73,
-+	0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x007f, 0x0078, 0x5ebb, 0x7e3a,
-+	0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c,
-+	0x601c, 0xa086, 0x0006, 0x00c0, 0x5ee1, 0x1078, 0xa1ca, 0x0078,
-+	0x5eea, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, 0x1078, 0x5f1b,
-+	0x1078, 0x5fdb, 0x087f, 0x027f, 0x017f, 0x007c, 0x0f7e, 0x127e,
-+	0x2079, 0xa8b1, 0x2091, 0x8000, 0x1078, 0x6076, 0x1078, 0x60ec,
-+	0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e,
-+	0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x7614,
-+	0x2660, 0x2678, 0x8cff, 0x0040, 0x5fb5, 0x6018, 0xa080, 0x0028,
-+	0x2004, 0xa206, 0x00c0, 0x5fb0, 0x88ff, 0x0040, 0x5f3b, 0x6020,
-+	0xa106, 0x00c0, 0x5fb0, 0x7024, 0xac06, 0x00c0, 0x5f6b, 0x2069,
-+	0x0100, 0x68c0, 0xa005, 0x0040, 0x5f66, 0x1078, 0x5acb, 0x1078,
-+	0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7027, 0x0000, 0x037e,
-+	0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5f5b, 0x6803,
-+	0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040,
-+	0x5f63, 0x6827, 0x0001, 0x037f, 0x0078, 0x5f6b, 0x6003, 0x0009,
-+	0x630a, 0x0078, 0x5fb0, 0x7014, 0xac36, 0x00c0, 0x5f71, 0x660c,
-+	0x7616, 0x7010, 0xac36, 0x00c0, 0x5f7f, 0x2c00, 0xaf36, 0x0040,
-+	0x5f7d, 0x2f00, 0x7012, 0x0078, 0x5f7f, 0x7013, 0x0000, 0x660c,
-+	0x067e, 0x2c00, 0xaf06, 0x0040, 0x5f88, 0x7e0e, 0x0078, 0x5f89,
-+	0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-+	0x5fa9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5fbe, 0x6837, 0x0103,
-+	0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x087e, 0x1078, 0x8f7d,
-+	0x1078, 0xa4e2, 0x1078, 0x4a73, 0x087f, 0x037f, 0x017f, 0x1078,
-+	0x8eb9, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x5f2a,
-+	0x2c78, 0x600c, 0x2060, 0x0078, 0x5f2a, 0x127f, 0x007f, 0x017f,
-+	0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086,
-+	0x0006, 0x00c0, 0x5fcf, 0x017e, 0x037e, 0x087e, 0x1078, 0xa4e2,
-+	0x1078, 0xa1ca, 0x087f, 0x037f, 0x017f, 0x0078, 0x5fa9, 0x601c,
-+	0xa086, 0x0002, 0x00c0, 0x5fa9, 0x6004, 0xa086, 0x0085, 0x0040,
-+	0x5f96, 0x0078, 0x5fa9, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000,
-+	0xa280, 0xa735, 0x2004, 0xa065, 0x0040, 0x6072, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x067e, 0x2071, 0xa8b1, 0x6654, 0x7018, 0xac06, 0x00c0,
-+	0x5ff2, 0x761a, 0x701c, 0xac06, 0x00c0, 0x5ffe, 0x86ff, 0x00c0,
-+	0x5ffd, 0x7018, 0x701e, 0x0078, 0x5ffe, 0x761e, 0x6058, 0xa07d,
-+	0x0040, 0x6003, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x6009, 0x2f00,
-+	0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
-+	0x6002, 0x1078, 0x44d3, 0x0040, 0x606e, 0x7624, 0x86ff, 0x0040,
-+	0x605c, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, 0x605c, 0x0d7e,
-+	0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x6053, 0x1078, 0x5acb,
-+	0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7027, 0x0000,
-+	0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x603c,
-+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
-+	0x0040, 0x6044, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c,
-+	0xa005, 0x0040, 0x604d, 0x8001, 0x603e, 0x2660, 0x1078, 0x8ec6,
-+	0x0c7f, 0x0078, 0x605c, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009,
-+	0x630a, 0x0c7f, 0x0078, 0x6011, 0x8dff, 0x0040, 0x606a, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f7d, 0x1078, 0xa4e2,
-+	0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x6011, 0x067f, 0x0d7f,
-+	0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e,
-+	0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x60d0,
-+	0x600c, 0x007e, 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x60b5,
-+	0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x60af, 0x1078, 0x5acb,
-+	0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7827, 0x0000,
-+	0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x60a4,
-+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
-+	0x0040, 0x60ac, 0x6827, 0x0001, 0x037f, 0x0078, 0x60b5, 0x6003,
-+	0x0009, 0x630a, 0x2c30, 0x0078, 0x60cd, 0x6010, 0x2068, 0x1078,
-+	0x8d06, 0x0040, 0x60c9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x60d7,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078,
-+	0x8eb9, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x007f, 0x0078, 0x607d,
-+	0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c,
-+	0xa086, 0x0006, 0x00c0, 0x60e0, 0x1078, 0xa1ca, 0x0078, 0x60c9,
-+	0x601c, 0xa086, 0x0002, 0x00c0, 0x60c9, 0x6004, 0xa086, 0x0085,
-+	0x0040, 0x60c0, 0x0078, 0x60c9, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
-+	0x7818, 0xa065, 0x0040, 0x615a, 0x6054, 0x007e, 0x6057, 0x0000,
-+	0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x44d3,
-+	0x0040, 0x6157, 0x7e24, 0x86ff, 0x0040, 0x6149, 0xa680, 0x0004,
-+	0x2004, 0xad06, 0x00c0, 0x6149, 0x0d7e, 0x2069, 0x0100, 0x68c0,
-+	0xa005, 0x0040, 0x6140, 0x1078, 0x5acb, 0x1078, 0x6e0f, 0x68c3,
-+	0x0000, 0x1078, 0x7378, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140,
-+	0x6b04, 0xa384, 0x1000, 0x0040, 0x6129, 0x6803, 0x0100, 0x6803,
-+	0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x6131, 0x6827,
-+	0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x613a,
-+	0x8001, 0x603e, 0x2660, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x6149,
-+	0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078,
-+	0x60fe, 0x8dff, 0x0040, 0x6153, 0x6837, 0x0103, 0x6b4a, 0x6847,
-+	0x0000, 0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x60fe, 0x007f,
-+	0x0078, 0x60f1, 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f,
-+	0x007c, 0x0e7e, 0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x6181,
-+	0x604c, 0xa06d, 0x0040, 0x6181, 0x6848, 0xa606, 0x00c0, 0x6181,
-+	0x2071, 0xa8b1, 0x7024, 0xa035, 0x0040, 0x6181, 0xa080, 0x0004,
-+	0x2004, 0xad06, 0x00c0, 0x6181, 0x6000, 0xc0dc, 0x6002, 0x1078,
-+	0x6185, 0x067f, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x2079, 0x0100,
-+	0x78c0, 0xa005, 0x00c0, 0x6194, 0x0c7e, 0x2660, 0x6003, 0x0009,
-+	0x630a, 0x0c7f, 0x0078, 0x61cb, 0x1078, 0x6e0f, 0x78c3, 0x0000,
-+	0x1078, 0x7378, 0x7027, 0x0000, 0x037e, 0x2079, 0x0140, 0x7b04,
-+	0xa384, 0x1000, 0x0040, 0x61a8, 0x7803, 0x0100, 0x7803, 0x0000,
-+	0x2079, 0x0100, 0x7824, 0xd084, 0x0040, 0x61b0, 0x7827, 0x0001,
-+	0x1078, 0x7378, 0x037f, 0x1078, 0x44d3, 0x0c7e, 0x603c, 0xa005,
-+	0x0040, 0x61bc, 0x8001, 0x603e, 0x2660, 0x1078, 0x772d, 0x0c7f,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f7d, 0x1078,
-+	0x4a73, 0x1078, 0x7233, 0x0f7f, 0x007c, 0x0e7e, 0x0c7e, 0x2071,
-+	0xa8b1, 0x7004, 0xa084, 0x0007, 0x0079, 0x61d6, 0x61e0, 0x61e3,
-+	0x61fc, 0x6218, 0x6262, 0x61e0, 0x61e0, 0x61de, 0x1078, 0x1332,
-+	0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x61f1, 0x7020,
-+	0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x61f8, 0x7216, 0x600f,
-+	0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
-+	0x7216, 0x7212, 0x0078, 0x61f1, 0x6018, 0x2060, 0x1078, 0x44d3,
-+	0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0040, 0x620d,
-+	0x6054, 0xa015, 0x0040, 0x6214, 0x721e, 0x7007, 0x0000, 0x7027,
-+	0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, 0x0078, 0x620d,
-+	0x7024, 0xa065, 0x0040, 0x625f, 0x700c, 0xac06, 0x00c0, 0x622f,
-+	0x1078, 0x7233, 0x600c, 0xa015, 0x0040, 0x622b, 0x720e, 0x600f,
-+	0x0000, 0x0078, 0x625d, 0x720e, 0x720a, 0x0078, 0x625d, 0x7014,
-+	0xac06, 0x00c0, 0x6242, 0x1078, 0x7233, 0x600c, 0xa015, 0x0040,
-+	0x623e, 0x7216, 0x600f, 0x0000, 0x0078, 0x625d, 0x7216, 0x7212,
-+	0x0078, 0x625d, 0x601c, 0xa086, 0x0003, 0x00c0, 0x625d, 0x6018,
-+	0x2060, 0x1078, 0x44d3, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7233,
-+	0x701c, 0xa065, 0x0040, 0x625d, 0x6054, 0xa015, 0x0040, 0x625b,
-+	0x721e, 0x0078, 0x625d, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f,
-+	0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x626f, 0x1078, 0x7233,
-+	0x600c, 0xa015, 0x0040, 0x6276, 0x720e, 0x600f, 0x0000, 0x1078,
-+	0x7378, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a,
-+	0x0078, 0x626f, 0x0d7e, 0x2069, 0xa8b1, 0x6830, 0xa084, 0x0003,
-+	0x0079, 0x6282, 0x6288, 0x628a, 0x62b4, 0x6288, 0x1078, 0x1332,
-+	0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x62aa,
-+	0x683c, 0xa065, 0x0040, 0x629b, 0x600c, 0xa015, 0x0040, 0x62a6,
-+	0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011,
-+	0xa8d0, 0x2013, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836,
-+	0x0078, 0x629b, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x629b,
-+	0x6003, 0x0003, 0x0078, 0x629b, 0x0c7e, 0x6843, 0x0000, 0x6847,
-+	0x0000, 0x684b, 0x0000, 0x683c, 0xa065, 0x0040, 0x62ce, 0x600c,
-+	0xa015, 0x0040, 0x62ca, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
-+	0x0078, 0x62ce, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
-+	0x007c, 0x0d7e, 0x2069, 0xa8b1, 0x6804, 0xa084, 0x0007, 0x0079,
-+	0x62d9, 0x62e3, 0x638a, 0x638a, 0x638a, 0x638a, 0x638c, 0x638a,
-+	0x62e1, 0x1078, 0x1332, 0x6820, 0xa005, 0x00c0, 0x62e9, 0x0d7f,
-+	0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x62f8, 0x6807, 0x0004,
-+	0x6826, 0x682b, 0x0000, 0x1078, 0x63d4, 0x0c7f, 0x0d7f, 0x007c,
-+	0x6814, 0xa065, 0x0040, 0x6306, 0x6807, 0x0001, 0x6826, 0x682b,
-+	0x0000, 0x1078, 0x63d4, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e,
-+	0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x6385, 0x704c, 0xa00d, 0x0040,
-+	0x6315, 0x7088, 0xa005, 0x0040, 0x632d, 0x7054, 0xa075, 0x0040,
-+	0x631e, 0xa20e, 0x0040, 0x6385, 0x0078, 0x6323, 0x6818, 0xa20e,
-+	0x0040, 0x6385, 0x2070, 0x704c, 0xa00d, 0x0040, 0x6315, 0x7088,
-+	0xa005, 0x00c0, 0x6315, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
-+	0x00c8, 0x6315, 0x1078, 0x76fc, 0x0040, 0x6385, 0x8318, 0x733e,
-+	0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
-+	0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
-+	0xa08a, 0x199a, 0x0048, 0x634e, 0x2001, 0x1999, 0x8003, 0x801b,
-+	0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc,
-+	0x0040, 0x6367, 0x7100, 0xd1f4, 0x0040, 0x6363, 0x7114, 0xa18c,
-+	0x00ff, 0x0078, 0x636c, 0x2009, 0x0000, 0x0078, 0x636c, 0xa1e0,
-+	0x29c0, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078,
-+	0x6965, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
-+	0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
-+	0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
-+	0x0078, 0x6383, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
-+	0x6398, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x63d4,
-+	0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa8b1, 0x6830,
-+	0xa086, 0x0000, 0x00c0, 0x63bb, 0x6838, 0xa07d, 0x0040, 0x63bb,
-+	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x127e,
-+	0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1d6d, 0x00c0, 0x63be,
-+	0x127f, 0x1078, 0x6cb3, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843,
-+	0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0040, 0x63d0, 0x6a3a,
-+	0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x63bb,
-+	0x683a, 0x6836, 0x0078, 0x63ca, 0x601c, 0xa084, 0x000f, 0x1079,
-+	0x63da, 0x007c, 0x63e3, 0x63e8, 0x6809, 0x6922, 0x63e8, 0x6809,
-+	0x6922, 0x63e3, 0x63e8, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x007c,
-+	0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044,
-+	0x10c8, 0x1332, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x6405,
-+	0x7900, 0xd1f4, 0x0040, 0x6401, 0x7914, 0xa18c, 0x00ff, 0x0078,
-+	0x640a, 0x2009, 0x0000, 0x0078, 0x640a, 0xa1f8, 0x29c0, 0x2f0c,
-+	0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040,
-+	0x00c8, 0x645c, 0x1079, 0x641a, 0x0f7f, 0x0c7f, 0x147f, 0x137f,
-+	0x157f, 0x007c, 0x64c2, 0x650a, 0x6532, 0x65cd, 0x65fd, 0x6605,
-+	0x662c, 0x663d, 0x664e, 0x6656, 0x666e, 0x6656, 0x66d9, 0x663d,
-+	0x66fa, 0x6702, 0x664e, 0x6702, 0x6713, 0x645a, 0x645a, 0x645a,
-+	0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a,
-+	0x6eef, 0x6f14, 0x6f29, 0x6f4c, 0x6f6d, 0x662c, 0x645a, 0x662c,
-+	0x6656, 0x645a, 0x6532, 0x65cd, 0x645a, 0x749c, 0x6656, 0x645a,
-+	0x74bc, 0x6656, 0x645a, 0x645a, 0x64bd, 0x646b, 0x645a, 0x74e1,
-+	0x7558, 0x7640, 0x645a, 0x7651, 0x6626, 0x766d, 0x645a, 0x6f82,
-+	0x645a, 0x645a, 0x1078, 0x1332, 0x2100, 0x1079, 0x6465, 0x0f7f,
-+	0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x6469, 0x6469, 0x6469,
-+	0x649f, 0x1078, 0x1332, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6731,
-+	0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800,
-+	0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6dfb, 0x0d7f, 0x007c,
-+	0x0d7e, 0x7818, 0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x649c,
-+	0xa085, 0x0001, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x649a, 0x0d7e,
-+	0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x0500, 0x20a3, 0x0000,
-+	0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810,
-+	0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3,
-+	0x0010, 0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078,
-+	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x5200,
-+	0x20a3, 0x0000, 0x0d7e, 0x2069, 0xa652, 0x6804, 0xd084, 0x0040,
-+	0x64dc, 0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2564, 0x21a2,
-+	0x017f, 0x0d7f, 0x0078, 0x64e1, 0x0d7f, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x20a9, 0x0004,
-+	0x2099, 0xa601, 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
-+	0x007f, 0x0048, 0x64fb, 0x2001, 0xa61b, 0x20a6, 0x2001, 0xa61c,
-+	0x20a6, 0x0078, 0x6501, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff,
-+	0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078,
-+	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x0500,
-+	0x20a3, 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f,
-+	0x0048, 0x6522, 0x2001, 0xa61b, 0x20a6, 0x2001, 0xa61c, 0x20a6,
-+	0x0078, 0x6528, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2,
-+	0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x60c3, 0x0010, 0x1078,
-+	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x0c7e, 0x7818,
-+	0x2060, 0x2001, 0x0000, 0x1078, 0x4972, 0x0c7f, 0x7818, 0xa080,
-+	0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x654d, 0x20a3, 0x0400,
-+	0x620c, 0xc2b4, 0x620e, 0x0078, 0x654f, 0x20a3, 0x0300, 0x20a3,
-+	0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0,
-+	0x659c, 0x2099, 0xa88d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304,
-+	0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099,
-+	0xa605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa601, 0x53a6, 0x20a9,
-+	0x0010, 0x20a3, 0x0000, 0x00f0, 0x6579, 0x2099, 0xa895, 0x3304,
-+	0xc0dd, 0x20a2, 0x2001, 0xa672, 0x2004, 0xd0e4, 0x0040, 0x6594,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6,
-+	0x20a9, 0x0004, 0x0078, 0x6596, 0x20a9, 0x0007, 0x20a3, 0x0000,
-+	0x00f0, 0x6596, 0x0078, 0x65bc, 0x2099, 0xa88d, 0x20a9, 0x0008,
-+	0x53a6, 0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x20a9, 0x0004,
-+	0x2099, 0xa601, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0,
-+	0x65ad, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x65b3, 0x2099,
-+	0xa895, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000,
-+	0x00f0, 0x65be, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x65c4,
-+	0x60c3, 0x0074, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
-+	0x6731, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3,
-+	0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e,
-+	0x2079, 0xa652, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x65e9, 0xa085,
-+	0x0020, 0xd1a4, 0x0040, 0x65ee, 0xa085, 0x0010, 0xa085, 0x0002,
-+	0x0d7e, 0x0078, 0x66b7, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
-+	0x6731, 0x20a3, 0x5000, 0x0078, 0x654f, 0x20a1, 0x020b, 0x1078,
-+	0x6731, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b,
-+	0x1078, 0x67b9, 0x0078, 0x6630, 0x20a1, 0x020b, 0x1078, 0x67c2,
-+	0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0004, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
-+	0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3,
-+	0x2a00, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b,
-+	0x1078, 0x67c2, 0x20a3, 0x0200, 0x0078, 0x654f, 0x20a1, 0x020b,
-+	0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005,
-+	0x0040, 0x6665, 0x20a2, 0x0078, 0x6667, 0x20a3, 0x0003, 0x7810,
-+	0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x0d7e, 0x20a1,
-+	0x020b, 0x1078, 0x67c2, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
-+	0x0800, 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x6694,
-+	0x6998, 0xa184, 0xc000, 0x00c0, 0x6690, 0xd1ec, 0x0040, 0x668c,
-+	0x20a3, 0x2100, 0x0078, 0x6696, 0x20a3, 0x0100, 0x0078, 0x6696,
-+	0x20a3, 0x0400, 0x0078, 0x6696, 0x20a3, 0x0700, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa652, 0x7904,
-+	0x0f7f, 0xd1ac, 0x00c0, 0x66a6, 0xa085, 0x0020, 0xd1a4, 0x0040,
-+	0x66ab, 0xa085, 0x0010, 0x2009, 0xa674, 0x210c, 0xd184, 0x0040,
-+	0x66b5, 0x699c, 0xd18c, 0x0040, 0x66b7, 0xa085, 0x0002, 0x027e,
-+	0x2009, 0xa672, 0x210c, 0xd1e4, 0x0040, 0x66c5, 0xc0c5, 0xa094,
-+	0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xd1ec, 0x0040, 0x66cf,
-+	0xa094, 0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xc0bd, 0x027f,
-+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x0d7f,
-+	0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0210, 0x20a3,
-+	0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0200,
-+	0x0078, 0x64c8, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008,
-+	0x1078, 0x6dfb, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1,
-+	0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
-+	0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c,
-+	0x027e, 0x037e, 0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078,
-+	0x6738, 0x027e, 0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014,
-+	0xa286, 0x007e, 0x00c0, 0x674b, 0xa385, 0x00ff, 0x20a2, 0x20a3,
-+	0xfffe, 0x0078, 0x6780, 0xa286, 0x007f, 0x00c0, 0x6757, 0x0d7e,
-+	0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x0078, 0x676e, 0xd2bc,
-+	0x0040, 0x6776, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x6766, 0xa385,
-+	0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0078, 0x676e, 0xa2e8, 0xa735,
-+	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6784, 0x0d7e, 0xa2e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
-+	0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f,
-+	0x037f, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000,
-+	0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
-+	0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff,
-+	0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0xa61b, 0x2da6, 0x8d68,
-+	0x2da6, 0x0d7f, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x678b,
-+	0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000,
-+	0x007c, 0x027e, 0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800,
-+	0x0078, 0x67c9, 0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021,
-+	0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa092, 0x007e, 0x0048, 0x67e6, 0x0d7e, 0xa0e8, 0xa735,
-+	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x67f4, 0x0d7e, 0xa0e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
-+	0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
-+	0x0000, 0x047f, 0x037f, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000,
-+	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
-+	0x007c, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1332,
-+	0xa08a, 0x008c, 0x10c8, 0x1332, 0x6118, 0x2178, 0x79a0, 0xd1bc,
-+	0x0040, 0x6827, 0x7900, 0xd1f4, 0x0040, 0x6823, 0x7914, 0xa18c,
-+	0x00ff, 0x0078, 0x682c, 0x2009, 0x0000, 0x0078, 0x682c, 0xa1f8,
-+	0x29c0, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
-+	0xa082, 0x0085, 0x1079, 0x6837, 0x0f7f, 0x0c7f, 0x007c, 0x6840,
-+	0x684b, 0x6866, 0x683e, 0x683e, 0x683e, 0x6840, 0x1078, 0x1332,
-+	0x147e, 0x20a1, 0x020b, 0x1078, 0x6879, 0x60c3, 0x0000, 0x1078,
-+	0x6dfb, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x68ad,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2,
-+	0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x000c, 0x1078, 0x6dfb, 0x147f, 0x007c, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x68ee, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x6dfb, 0x147f,
-+	0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
-+	0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6898, 0x0d7e, 0xa0e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
-+	0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x68a7,
-+	0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
-+	0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
-+	0x0009, 0x20a3, 0x0000, 0x0078, 0x678b, 0x027e, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e,
-+	0x0048, 0x68cc, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085,
-+	0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68,
-+	0x2da6, 0x0d7f, 0x0078, 0x68db, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-+	0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3,
-+	0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078,
-+	0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1,
-+	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
-+	0x007e, 0x0048, 0x690d, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810,
-+	0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6,
-+	0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x691c, 0x0d7e, 0xa0e8, 0xa735,
-+	0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
-+	0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000,
-+	0x0078, 0x68df, 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040,
-+	0x1048, 0x1332, 0xa08a, 0x0053, 0x10c8, 0x1332, 0x7918, 0x2160,
-+	0x61a0, 0xd1bc, 0x0040, 0x6941, 0x6100, 0xd1f4, 0x0040, 0x693d,
-+	0x6114, 0xa18c, 0x00ff, 0x0078, 0x6946, 0x2009, 0x0000, 0x0078,
-+	0x6946, 0xa1e0, 0x29c0, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100,
-+	0x619a, 0xa082, 0x0040, 0x1079, 0x6950, 0x0f7f, 0x0c7f, 0x007c,
-+	0x6965, 0x6a73, 0x6a14, 0x6c27, 0x6963, 0x6963, 0x6963, 0x6963,
-+	0x6963, 0x6963, 0x6963, 0x714c, 0x715d, 0x716e, 0x717f, 0x6963,
-+	0x767e, 0x6963, 0x713b, 0x1078, 0x1332, 0x0d7e, 0x157e, 0x147e,
-+	0x780b, 0xffff, 0x20a1, 0x020b, 0x1078, 0x69d0, 0x7910, 0x2168,
-+	0x6948, 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c,
-+	0xa184, 0x000f, 0x00c0, 0x6980, 0x2001, 0x0005, 0x0078, 0x698a,
-+	0xd184, 0x0040, 0x6987, 0x2001, 0x0004, 0x0078, 0x698a, 0xa084,
-+	0x0006, 0x8004, 0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007,
-+	0xa105, 0x017f, 0x20a2, 0xd1ac, 0x0040, 0x699a, 0x20a3, 0x0002,
-+	0x0078, 0x69a6, 0xd1b4, 0x0040, 0x69a1, 0x20a3, 0x0001, 0x0078,
-+	0x69a6, 0x20a3, 0x0000, 0x2230, 0x0078, 0x69a8, 0x6a80, 0x6e7c,
-+	0x20a9, 0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000,
-+	0x00f0, 0x69ac, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080,
-+	0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa8cd,
-+	0x2003, 0x07d0, 0x2001, 0xa8cc, 0x2003, 0x0009, 0x2001, 0xa8d2,
-+	0x2003, 0x0002, 0x1078, 0x158c, 0x147f, 0x157f, 0x0d7f, 0x007c,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014,
-+	0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xd0bc, 0x0040, 0x69f6, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-+	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a05, 0x0d7e, 0xa0e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2,
-+	0x0d7f, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3,
-+	0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x6a34, 0x7810, 0x2068, 0x6860, 0x20a2,
-+	0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x147f,
-+	0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a52,
-+	0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
-+	0x0078, 0x6a61, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085,
-+	0x0500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
-+	0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2,
-+	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810,
-+	0xa0ec, 0xf000, 0x0040, 0x6a8b, 0xa06d, 0x1078, 0x495f, 0x0040,
-+	0x6a8b, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6a8b,
-+	0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078, 0x6be0, 0xa016,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000,
-+	0x00c0, 0x6aa2, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x6aaa,
-+	0x0078, 0x6aa5, 0xa006, 0x1079, 0x6aaa, 0x147f, 0x137f, 0x157f,
-+	0x0d7f, 0x007c, 0x6ab4, 0x6b4c, 0x6b57, 0x6b81, 0x6b95, 0x6bb1,
-+	0x6bbc, 0x6ab2, 0x1078, 0x1332, 0x017e, 0x037e, 0x694c, 0xa18c,
-+	0x0003, 0x0040, 0x6abf, 0xa186, 0x0003, 0x00c0, 0x6ace, 0x6b78,
-+	0x7824, 0xd0cc, 0x0040, 0x6ac5, 0xc3e5, 0x23a2, 0x6868, 0x20a2,
-+	0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x6b8c, 0xa186, 0x0001,
-+	0x10c0, 0x1332, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x6ad8, 0xc3e5,
-+	0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2,
-+	0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, 0x0300, 0x0040,
-+	0x6b46, 0xd3c4, 0x0040, 0x6aee, 0x687c, 0xa108, 0xd3cc, 0x0040,
-+	0x6af3, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, 0xad80, 0x0020,
-+	0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x6af8, 0x157f, 0x22a2,
-+	0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6b46, 0x20a1, 0x020b,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xd0bc, 0x0040, 0x6b26, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-+	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6b35, 0x0d7e, 0xa0e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
-+	0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f, 0x7b24, 0xd3cc,
-+	0x0040, 0x6b3e, 0x20a3, 0x0889, 0x0078, 0x6b40, 0x20a3, 0x0898,
-+	0x20a2, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x61c2, 0x037f,
-+	0x017f, 0x1078, 0x6dfb, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc,
-+	0x0040, 0x6b53, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x6b8a, 0x2011,
-+	0x0302, 0x7824, 0xd0cc, 0x0040, 0x6b5e, 0xc2e5, 0x22a2, 0xa016,
-+	0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
-+	0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x1078, 0x6dfb,
-+	0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040, 0x6b88, 0xc2e5,
-+	0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
-+	0x60c3, 0x0018, 0x1078, 0x6dfb, 0x007c, 0x2011, 0x0100, 0x7824,
-+	0xd0cc, 0x0040, 0x6b9c, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2,
-+	0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7834, 0xa084,
-+	0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x6dfb,
-+	0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040, 0x6bb8, 0xc2e5,
-+	0x22a2, 0xa016, 0x0078, 0x6b8a, 0x037e, 0x7b10, 0xa384, 0xff00,
-+	0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6bcf, 0x7824, 0xd0cc,
-+	0x0040, 0x6bcb, 0xc2e5, 0x22a2, 0x037f, 0x0078, 0x6b8a, 0x047e,
-+	0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f, 0x0040, 0x6bd9,
-+	0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f, 0x0078, 0x6b8c,
-+	0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xd0bc, 0x0040, 0x6bfe, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-+	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6c0d, 0x0d7e, 0xa0e8,
-+	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
-+	0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824, 0xd0cc, 0x0040,
-+	0x6c15, 0x20a3, 0x0889, 0x0078, 0x6c17, 0x20a3, 0x0898, 0x20a3,
-+	0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
-+	0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e,
-+	0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084, 0x0700,
-+	0x8007, 0x1079, 0x6c3a, 0x037f, 0x017f, 0x147f, 0x137f, 0x157f,
-+	0x0d7f, 0x007c, 0x6c42, 0x6c42, 0x6c44, 0x6c42, 0x6c42, 0x6c42,
-+	0x6c69, 0x6c42, 0x1078, 0x1332, 0x7910, 0xa18c, 0xf8ff, 0xa18d,
-+	0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73,
-+	0x0d7e, 0x2069, 0xa652, 0x6804, 0xd0bc, 0x0040, 0x6c5e, 0x682c,
-+	0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6c60, 0x20a3, 0x3f00,
-+	0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078, 0x6dfb,
-+	0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73, 0x20a3,
-+	0x7f00, 0x0078, 0x6c61, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
-+	0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6c91, 0x0d7e,
-+	0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814,
-+	0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
-+	0x6ca0, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0100,
-+	0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2,
-+	0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, 0x6dea, 0x22a2,
-+	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e,
-+	0x037e, 0x2061, 0x0100, 0x2071, 0xa600, 0x6130, 0x7818, 0x2068,
-+	0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6cca, 0x6910, 0x6a14, 0x6430,
-+	0x0078, 0x6cce, 0x6910, 0x6a14, 0x736c, 0x7470, 0x781c, 0xa086,
-+	0x0006, 0x0040, 0x6d2d, 0xd5bc, 0x0040, 0x6cde, 0xa185, 0x0100,
-+	0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6ce5, 0xa185, 0x0100,
-+	0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809, 0x6077,
-+	0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a,
-+	0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070,
-+	0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
-+	0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000,
-+	0xa582, 0x0080, 0x0048, 0x6d17, 0x6a00, 0xd2f4, 0x0040, 0x6d15,
-+	0x6a14, 0xa294, 0x00ff, 0x0078, 0x6d17, 0x2011, 0x0000, 0x629e,
-+	0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005,
-+	0x0040, 0x6d24, 0x2009, 0x1b58, 0x1078, 0x5ad0, 0x037f, 0x047f,
-+	0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c,
-+	0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6d85, 0xd5bc, 0x0040,
-+	0x6d41, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078,
-+	0x6d48, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e,
-+	0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff,
-+	0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808,
-+	0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c,
-+	0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, 0xa109,
-+	0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
-+	0x0000, 0xa582, 0x0080, 0x0048, 0x6d80, 0x6a00, 0xd2f4, 0x0040,
-+	0x6d7e, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6d80, 0x2011, 0x0000,
-+	0x629e, 0x6017, 0x0012, 0x0078, 0x6d1a, 0xd5bc, 0x0040, 0x6d90,
-+	0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6d97,
-+	0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x1078,
-+	0x495f, 0x0040, 0x6dad, 0x0d7e, 0x7810, 0xa06d, 0x684c, 0x0d7f,
-+	0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6dad, 0x7824, 0xc0cd,
-+	0x7826, 0x6073, 0x0889, 0x0078, 0x6daf, 0x6073, 0x0898, 0x6077,
-+	0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a,
-+	0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7014, 0x608a,
-+	0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce,
-+	0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080,
-+	0x0048, 0x6ddd, 0x6a00, 0xd2f4, 0x0040, 0x6ddb, 0x6a14, 0xa294,
-+	0x00ff, 0x0078, 0x6ddd, 0x2011, 0x0000, 0x629e, 0x7824, 0xd0cc,
-+	0x0040, 0x6de6, 0x6017, 0x0016, 0x0078, 0x6d1a, 0x6017, 0x0012,
-+	0x0078, 0x6d1a, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
-+	0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069, 0xa8b1, 0x6843,
-+	0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7,
-+	0x9575, 0x1078, 0x6e06, 0x1078, 0x5ac0, 0x007c, 0x007e, 0x6014,
-+	0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f, 0x007c, 0x007e,
-+	0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008,
-+	0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e,
-+	0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040,
-+	0x6e59, 0x1078, 0x6e0f, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e,
-+	0x2061, 0xa8b1, 0x6128, 0xa192, 0x00c8, 0x00c8, 0x6e44, 0x8108,
-+	0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6e54, 0x1078, 0x5ac0,
-+	0x1078, 0x6e06, 0x0078, 0x6e54, 0x6124, 0xa1e5, 0x0000, 0x0040,
-+	0x6e51, 0x1078, 0xa5c4, 0x1078, 0x5acb, 0x2009, 0x0014, 0x1078,
-+	0x775c, 0x0c7f, 0x0078, 0x6e54, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
-+	0x007c, 0x2001, 0xa8cd, 0x2004, 0xa005, 0x00c0, 0x6e54, 0x0c7e,
-+	0x2061, 0xa8b1, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6e44, 0x8108,
-+	0x612a, 0x0c7f, 0x1078, 0x5ac0, 0x1078, 0x4224, 0x0078, 0x6e54,
-+	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5ad8, 0x2071,
-+	0xa8b1, 0x713c, 0x81ff, 0x0040, 0x6e9a, 0x2061, 0x0100, 0x2069,
-+	0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6ea0, 0x6803, 0x1000,
-+	0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x037f,
-+	0x713c, 0x2160, 0x1078, 0xa5c4, 0x2009, 0x004a, 0x1078, 0x775c,
-+	0x0078, 0x6e9a, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
-+	0x0078, 0x6e8a, 0x0e7e, 0x2071, 0xa8b1, 0x7048, 0xd084, 0x0040,
-+	0x6ebc, 0x713c, 0x81ff, 0x0040, 0x6ebc, 0x2071, 0x0100, 0xa188,
-+	0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x6eba, 0x7017, 0x0012,
-+	0x0078, 0x6ebc, 0x7017, 0x0016, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e,
-+	0x0c7e, 0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000,
-+	0x6018, 0x2068, 0x6ca0, 0x2071, 0xa8b1, 0x7018, 0x2068, 0x8dff,
-+	0x0040, 0x6ee6, 0x68a0, 0xa406, 0x0040, 0x6eda, 0x6854, 0x2068,
-+	0x0078, 0x6ecf, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60,
-+	0x1078, 0x4736, 0x0040, 0x6ee6, 0xa085, 0x0001, 0x127f, 0x007f,
-+	0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1,
-+	0x020b, 0x1078, 0x6731, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x781c, 0xa086, 0x0004, 0x00c0, 0x6f01, 0x6098, 0x0078,
-+	0x6f02, 0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9,
-+	0x0010, 0xa006, 0x20a2, 0x00f0, 0x6f0a, 0x20a2, 0x20a2, 0x60c3,
-+	0x002c, 0x1078, 0x6dfb, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b,
-+	0x1078, 0x6731, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x147f, 0x157f,
-+	0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3,
-+	0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0xa640, 0x2019,
-+	0xa641, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0,
-+	0x6f39, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078,
-+	0x6dfb, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e,
-+	0x20a1, 0x020b, 0x1078, 0x6799, 0x1078, 0x67b0, 0x7810, 0xa080,
-+	0x0000, 0x2004, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002,
-+	0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6dfb,
-+	0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x6731, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x147f,
-+	0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b,
-+	0x1078, 0x6731, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017,
-+	0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2,
-+	0x1078, 0x6dfb, 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e,
-+	0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x700c,
-+	0x2060, 0x8cff, 0x0040, 0x6fbb, 0x1078, 0x8f00, 0x00c0, 0x6fb2,
-+	0x1078, 0x7c83, 0x600c, 0x007e, 0x1078, 0x772d, 0x1078, 0x7233,
-+	0x0c7f, 0x0078, 0x6fa9, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f,
-+	0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069,
-+	0x0100, 0x2079, 0x0140, 0x2071, 0xa8b1, 0x7024, 0x2060, 0x8cff,
-+	0x0040, 0x7014, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x5acb,
-+	0x2009, 0x0013, 0x1078, 0x775c, 0x20a9, 0x01f4, 0x6824, 0xd094,
-+	0x0040, 0x6ff7, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040,
-+	0x7009, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x7009, 0xd084,
-+	0x0040, 0x6ffe, 0x6827, 0x0001, 0x0078, 0x7000, 0x00f0, 0x6fe6,
-+	0x7804, 0xa084, 0x1000, 0x0040, 0x7009, 0x7803, 0x0100, 0x7803,
-+	0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f,
-+	0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0xa600, 0x2004, 0xa096,
-+	0x0001, 0x0040, 0x704e, 0xa096, 0x0004, 0x0040, 0x704e, 0x1078,
-+	0x5acb, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x41dc, 0x1078,
-+	0x5a45, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x703c, 0x6827,
-+	0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x704e, 0x7803, 0x1000,
-+	0x7803, 0x0000, 0x0078, 0x704e, 0xd084, 0x0040, 0x7043, 0x6827,
-+	0x0001, 0x0078, 0x7045, 0x00f0, 0x702b, 0x7804, 0xa084, 0x1000,
-+	0x0040, 0x704e, 0x7803, 0x0100, 0x7803, 0x0000, 0x007f, 0x017f,
-+	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
-+	0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e,
-+	0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
-+	0xa8b1, 0x703c, 0x2060, 0x8cff, 0x0040, 0x70d6, 0x68af, 0x95f5,
-+	0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0, 0x7074, 0x68c7,
-+	0x0000, 0x68cb, 0x0008, 0x1078, 0x5ad8, 0x1078, 0x1f7e, 0x047e,
-+	0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, 0x0169,
-+	0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x70a5, 0x68c7,
-+	0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079, 0x0020, 0x2071,
-+	0xa908, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803,
-+	0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a, 0x057f, 0x047f,
-+	0xa39d, 0x0000, 0x00c0, 0x70b0, 0x2009, 0x0049, 0x1078, 0x775c,
-+	0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x70c3, 0x6827, 0x0004,
-+	0x7804, 0xa084, 0x4000, 0x0040, 0x70d5, 0x7803, 0x1000, 0x7803,
-+	0x0000, 0x0078, 0x70d5, 0xd08c, 0x0040, 0x70ca, 0x6827, 0x0002,
-+	0x0078, 0x70cc, 0x00f0, 0x70b2, 0x7804, 0xa084, 0x1000, 0x0040,
-+	0x70d5, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f,
-+	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
-+	0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa8b1, 0x6a06, 0x127f,
-+	0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa8b1,
-+	0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
-+	0x007e, 0x127e, 0x2071, 0xa8b1, 0x7614, 0x2660, 0x2678, 0x2091,
-+	0x8000, 0x8cff, 0x0040, 0x7134, 0x601c, 0xa206, 0x00c0, 0x712f,
-+	0x7014, 0xac36, 0x00c0, 0x710e, 0x660c, 0x7616, 0x7010, 0xac36,
-+	0x00c0, 0x711c, 0x2c00, 0xaf36, 0x0040, 0x711a, 0x2f00, 0x7012,
-+	0x0078, 0x711c, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
-+	0x0040, 0x7125, 0x7e0e, 0x0078, 0x7126, 0x2678, 0x600f, 0x0000,
-+	0x1078, 0x8ec6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x7101, 0x2c78,
-+	0x600c, 0x2060, 0x0078, 0x7101, 0x127f, 0x007f, 0x067f, 0x0c7f,
-+	0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
-+	0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a3, 0x1000, 0x0078, 0x718e, 0x157e, 0x147e, 0x20a1, 0x020b,
-+	0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a3, 0x4000, 0x0078, 0x718e, 0x157e, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x718e, 0x157e, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x718e, 0x157e,
-+	0x147e, 0x20a1, 0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006,
-+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x723e,
-+	0x60c3, 0x0020, 0x1078, 0x6dfb, 0x147f, 0x157f, 0x007c, 0x127e,
-+	0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0,
-+	0x71a6, 0xd1bc, 0x00c0, 0x71f0, 0x0078, 0x7230, 0x2009, 0x017f,
-+	0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9,
-+	0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x71e7,
-+	0x6020, 0xd0b4, 0x0040, 0x71e7, 0x6024, 0xd094, 0x00c0, 0x71e7,
-+	0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x71e7, 0x00f0,
-+	0x71b3, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c,
-+	0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043,
-+	0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0,
-+	0x71e6, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x71dd, 0x027f, 0x0d7f,
-+	0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x7230,
-+	0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069,
-+	0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000,
-+	0x0040, 0x7229, 0x6020, 0xd0bc, 0x0040, 0x7229, 0x2104, 0xa084,
-+	0x000f, 0xa086, 0x0004, 0x00c0, 0x7229, 0x00f0, 0x71fd, 0x027e,
-+	0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d,
-+	0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043,
-+	0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x7223,
-+	0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
-+	0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa8b1, 0x7020, 0xa005,
-+	0x0040, 0x723c, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008,
-+	0x20a2, 0x00f0, 0x7240, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000,
-+	0x2071, 0xa8b1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff,
-+	0x0040, 0x72e2, 0x8cff, 0x0040, 0x72e2, 0x601c, 0xa086, 0x0006,
-+	0x00c0, 0x72dd, 0x88ff, 0x0040, 0x726d, 0x2800, 0xac06, 0x00c0,
-+	0x72dd, 0x2039, 0x0000, 0x0078, 0x7278, 0x6018, 0xa206, 0x00c0,
-+	0x72dd, 0x85ff, 0x0040, 0x7278, 0x6020, 0xa106, 0x00c0, 0x72dd,
-+	0x7024, 0xac06, 0x00c0, 0x72a8, 0x2069, 0x0100, 0x68c0, 0xa005,
-+	0x0040, 0x72a3, 0x1078, 0x5acb, 0x6817, 0x0008, 0x68c3, 0x0000,
-+	0x1078, 0x7378, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
-+	0xa384, 0x1000, 0x0040, 0x7298, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x72a0, 0x6827, 0x0001,
-+	0x037f, 0x0078, 0x72a8, 0x6003, 0x0009, 0x630a, 0x0078, 0x72dd,
-+	0x7014, 0xac36, 0x00c0, 0x72ae, 0x660c, 0x7616, 0x7010, 0xac36,
-+	0x00c0, 0x72bc, 0x2c00, 0xaf36, 0x0040, 0x72ba, 0x2f00, 0x7012,
-+	0x0078, 0x72bc, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
-+	0x0040, 0x72c5, 0x7e0e, 0x0078, 0x72c6, 0x2678, 0x89ff, 0x00c0,
-+	0x72d5, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-+	0x72d3, 0x1078, 0xa1ca, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x88ff,
-+	0x00c0, 0x72ec, 0x0c7f, 0x0078, 0x7257, 0x2c78, 0x600c, 0x2060,
-+	0x0078, 0x7257, 0xa006, 0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5,
-+	0x0001, 0x0078, 0x72e3, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e,
-+	0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x7638,
-+	0x2660, 0x2678, 0x8cff, 0x0040, 0x7367, 0x601c, 0xa086, 0x0006,
-+	0x00c0, 0x7362, 0x87ff, 0x0040, 0x7313, 0x2700, 0xac06, 0x00c0,
-+	0x7362, 0x0078, 0x731e, 0x6018, 0xa206, 0x00c0, 0x7362, 0x85ff,
-+	0x0040, 0x731e, 0x6020, 0xa106, 0x00c0, 0x7362, 0x703c, 0xac06,
-+	0x00c0, 0x7332, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x7033,
-+	0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b,
-+	0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7338, 0x660c, 0x763a,
-+	0x7034, 0xac36, 0x00c0, 0x7346, 0x2c00, 0xaf36, 0x0040, 0x7344,
-+	0x2f00, 0x7036, 0x0078, 0x7346, 0x7037, 0x0000, 0x660c, 0x067e,
-+	0x2c00, 0xaf06, 0x0040, 0x734f, 0x7e0e, 0x0078, 0x7350, 0x2678,
-+	0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x735a,
-+	0x1078, 0xa1ca, 0x1078, 0x8ec6, 0x87ff, 0x00c0, 0x7371, 0x0c7f,
-+	0x0078, 0x7302, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7302, 0xa006,
-+	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
-+	0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7368,
-+	0x0e7e, 0x2071, 0xa8b1, 0x2001, 0xa600, 0x2004, 0xa086, 0x0002,
-+	0x00c0, 0x7386, 0x7007, 0x0005, 0x0078, 0x7388, 0x7007, 0x0000,
-+	0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
-+	0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x2c10, 0x7638, 0x2660,
-+	0x2678, 0x8cff, 0x0040, 0x73c8, 0x2200, 0xac06, 0x00c0, 0x73c3,
-+	0x7038, 0xac36, 0x00c0, 0x73a6, 0x660c, 0x763a, 0x7034, 0xac36,
-+	0x00c0, 0x73b4, 0x2c00, 0xaf36, 0x0040, 0x73b2, 0x2f00, 0x7036,
-+	0x0078, 0x73b4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040,
-+	0x73bc, 0x7e0e, 0x0078, 0x73bd, 0x2678, 0x600f, 0x0000, 0xa085,
-+	0x0001, 0x0078, 0x73c8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7399,
-+	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
-+	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
-+	0x8000, 0x2071, 0xa8b1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
-+	0x7469, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7464,
-+	0x7024, 0xac06, 0x00c0, 0x740f, 0x2069, 0x0100, 0x68c0, 0xa005,
-+	0x0040, 0x743d, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378,
-+	0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
-+	0x0040, 0x7406, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
-+	0x6824, 0xd084, 0x0040, 0x740e, 0x6827, 0x0001, 0x037f, 0x700c,
-+	0xac36, 0x00c0, 0x7415, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0,
-+	0x7423, 0x2c00, 0xaf36, 0x0040, 0x7421, 0x2f00, 0x700a, 0x0078,
-+	0x7423, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
-+	0x742c, 0x7e0e, 0x0078, 0x742d, 0x2678, 0x600f, 0x0000, 0x1078,
-+	0x8eec, 0x00c0, 0x7441, 0x1078, 0x28a6, 0x1078, 0x8f00, 0x00c0,
-+	0x745d, 0x1078, 0x7c83, 0x0078, 0x745d, 0x1078, 0x7378, 0x0078,
-+	0x740f, 0x1078, 0x8f00, 0x00c0, 0x7449, 0x1078, 0x7c83, 0x0078,
-+	0x745d, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x745d, 0x601c,
-+	0xa086, 0x0003, 0x00c0, 0x7471, 0x6837, 0x0103, 0x6b4a, 0x6847,
-+	0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x1078,
-+	0x7233, 0x0c7f, 0x0078, 0x73de, 0x2c78, 0x600c, 0x2060, 0x0078,
-+	0x73de, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
-+	0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x745d, 0x1078, 0xa1ca,
-+	0x0078, 0x745d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
-+	0xa190, 0x0020, 0x221c, 0xa39e, 0x2676, 0x00c0, 0x748b, 0x8210,
-+	0x8000, 0x0078, 0x7482, 0xa005, 0x0040, 0x7497, 0x20a9, 0x0020,
-+	0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
-+	0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
-+	0x67c2, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x2099, 0xa8a5, 0x20a9, 0x0004, 0x53a6,
-+	0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2,
-+	0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
-+	0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6dfb,
-+	0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x91bc,
-+	0x00c0, 0x7551, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x1300,
-+	0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
-+	0x752d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
-+	0x7507, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7542, 0xa286,
-+	0x007f, 0x00c0, 0x7511, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
-+	0x7542, 0xd2bc, 0x0040, 0x7527, 0xa286, 0x0080, 0x00c0, 0x751e,
-+	0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7542, 0xa2e8, 0xa735,
-+	0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7542, 0x20a3,
-+	0x0000, 0x6098, 0x20a2, 0x0078, 0x7542, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa082, 0x007e, 0x0048, 0x753e, 0x0d7e, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7542, 0x20a3, 0x0000,
-+	0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x017f, 0x0d7f,
-+	0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c,
-+	0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040,
-+	0x757a, 0xa186, 0x0003, 0x0040, 0x75d5, 0xa186, 0x0005, 0x0040,
-+	0x75b8, 0xa186, 0x0004, 0x0040, 0x75a8, 0xa186, 0x0008, 0x0040,
-+	0x75c2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7640, 0x027f,
-+	0x0d7f, 0x007c, 0x1078, 0x75fd, 0x2009, 0x4000, 0x6800, 0x0079,
-+	0x7581, 0x7594, 0x75a2, 0x7596, 0x75a2, 0x759d, 0x7594, 0x7594,
-+	0x75a2, 0x75a2, 0x75a2, 0x75a2, 0x7594, 0x7594, 0x7594, 0x7594,
-+	0x7594, 0x75a2, 0x7594, 0x75a2, 0x1078, 0x1332, 0x6824, 0xd0e4,
-+	0x0040, 0x759d, 0xd0cc, 0x0040, 0x75a0, 0xa00e, 0x0078, 0x75a2,
-+	0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x75f3,
-+	0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
-+	0x6a00, 0xa286, 0x0002, 0x00c0, 0x75b6, 0xa00e, 0x0078, 0x75f3,
-+	0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
-+	0x0078, 0x75f3, 0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x75d2, 0xa286, 0x0002,
-+	0x00c0, 0x75d3, 0xa00e, 0x0078, 0x75f3, 0x1078, 0x75fd, 0x6810,
-+	0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2,
-+	0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040,
-+	0x75f1, 0xa08e, 0x0004, 0x0040, 0x75f1, 0x2009, 0x4000, 0x0078,
-+	0x75f3, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018,
-+	0x1078, 0x6dfb, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
-+	0x067e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0xa006, 0x20a3, 0x0200,
-+	0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa092, 0x007e, 0x0048, 0x7623, 0x0d7e, 0x2069, 0xa61b,
-+	0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa735, 0x2d6c, 0x6b10, 0x6c14,
-+	0x0d7f, 0x0078, 0x7629, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
-+	0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
-+	0x7637, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x763b, 0x23a2,
-+	0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c,
-+	0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000,
-+	0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb,
-+	0x007c, 0x20a1, 0x020b, 0x1078, 0x6728, 0x20a3, 0x1400, 0x20a3,
-+	0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
-+	0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
-+	0x60c3, 0x0010, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
-+	0x67b9, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
-+	0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x7689, 0x60c3, 0x0000, 0x1078, 0x6dfb, 0x147f,
-+	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xd0bc, 0x0040, 0x76a6, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-+	0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x76ae, 0x20a3, 0x0300,
-+	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
-+	0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
-+	0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
-+	0xad00, 0x2a70, 0x7064, 0x704a, 0x704f, 0xad00, 0x007c, 0x0e7e,
-+	0x127e, 0x2071, 0xa600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010,
-+	0x0048, 0x76f9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
-+	0x76e5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x76e1, 0x0078,
-+	0x76d4, 0x2061, 0xad00, 0x0078, 0x76d4, 0x6003, 0x0008, 0x8529,
-+	0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x76f5, 0x754e,
-+	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xad00, 0x0078,
-+	0x76f0, 0xa006, 0x0078, 0x76f2, 0x0e7e, 0x2071, 0xa600, 0x7548,
-+	0xa582, 0x0010, 0x0048, 0x772a, 0x704c, 0x2060, 0x6000, 0xa086,
-+	0x0000, 0x0040, 0x7717, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8,
-+	0x7713, 0x0078, 0x7706, 0x2061, 0xad00, 0x0078, 0x7706, 0x6003,
-+	0x0008, 0x8529, 0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8,
-+	0x7726, 0x754e, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704f, 0xad00,
-+	0x0078, 0x7722, 0xa006, 0x0078, 0x7724, 0xac82, 0xad00, 0x1048,
-+	0x1332, 0x2001, 0xa616, 0x2004, 0xac02, 0x10c8, 0x1332, 0xa006,
-+	0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
-+	0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
-+	0x603a, 0x603e, 0x2061, 0xa600, 0x6048, 0x8000, 0x604a, 0xa086,
-+	0x0001, 0x0040, 0x7754, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
-+	0x62d1, 0x127f, 0x0078, 0x7753, 0x601c, 0xa084, 0x000f, 0x0079,
-+	0x7761, 0x776a, 0x777b, 0x7797, 0x77b3, 0x920e, 0x922a, 0x9246,
-+	0x776a, 0x777b, 0xa186, 0x0013, 0x00c0, 0x7773, 0x1078, 0x61cd,
-+	0x1078, 0x62d1, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x777a, 0xa016,
-+	0x1078, 0x15fa, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
-+	0x1332, 0x1079, 0x7785, 0x067f, 0x007c, 0x7795, 0x7b00, 0x7cb2,
-+	0x7795, 0x7d36, 0x77cf, 0x7795, 0x7795, 0x7a92, 0x80f6, 0x7795,
-+	0x7795, 0x7795, 0x7795, 0x7795, 0x7795, 0x1078, 0x1332, 0x067e,
-+	0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x77a1, 0x067f,
-+	0x007c, 0x77b1, 0x87c3, 0x77b1, 0x77b1, 0x77b1, 0x77b1, 0x77b1,
-+	0x77b1, 0x8766, 0x8951, 0x77b1, 0x87f3, 0x8879, 0x87f3, 0x8879,
-+	0x77b1, 0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
-+	0x1332, 0x1079, 0x77bd, 0x067f, 0x007c, 0x77cd, 0x813d, 0x820e,
-+	0x8368, 0x84e4, 0x77cd, 0x77cd, 0x77cd, 0x8116, 0x870e, 0x8712,
-+	0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x8742, 0x1078, 0x1332, 0xa1b6,
-+	0x0015, 0x00c0, 0x77d7, 0x1078, 0x772d, 0x0078, 0x77dd, 0xa1b6,
-+	0x0016, 0x10c0, 0x1332, 0x1078, 0x772d, 0x007c, 0x20a9, 0x000e,
-+	0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
-+	0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
-+	0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x77ec,
-+	0x0e7e, 0x1078, 0x8d06, 0x0040, 0x7803, 0x6010, 0x2070, 0x7007,
-+	0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0d7e,
-+	0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7814, 0x6018, 0x2068,
-+	0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x781e,
-+	0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x772d,
-+	0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c,
-+	0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a,
-+	0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
-+	0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078,
-+	0x772d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
-+	0x017e, 0x2009, 0x0035, 0x1078, 0x91bc, 0x017f, 0x00c0, 0x785f,
-+	0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xab8c, 0x6b1c, 0xa386,
-+	0x0003, 0x0040, 0x7863, 0xa386, 0x0006, 0x0040, 0x7867, 0x1078,
-+	0x772d, 0x0078, 0x7869, 0x1078, 0x786c, 0x0078, 0x7869, 0x1078,
-+	0x7938, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
-+	0x0015, 0x0040, 0x791d, 0xa18e, 0x0016, 0x00c0, 0x7936, 0x700c,
-+	0xa08c, 0xff00, 0xa186, 0x1700, 0x0040, 0x7882, 0xa186, 0x0300,
-+	0x00c0, 0x78f8, 0x8fff, 0x00c0, 0x788c, 0x6800, 0xa086, 0x000f,
-+	0x0040, 0x78db, 0x0078, 0x7934, 0x6808, 0xa086, 0xffff, 0x00c0,
-+	0x7921, 0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x00c0, 0x78a2,
-+	0x797c, 0x7810, 0xa106, 0x00c0, 0x7921, 0x7980, 0x7814, 0xa106,
-+	0x00c0, 0x7921, 0x1078, 0x8eb9, 0x6830, 0x7852, 0x784c, 0xc0dc,
-+	0xc0f4, 0xc0d4, 0x784e, 0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a,
-+	0x1078, 0x5c1c, 0x7854, 0xa20a, 0x0048, 0x78b7, 0x8011, 0x7a56,
-+	0x82ff, 0x027f, 0x00c0, 0x78c3, 0x0c7e, 0x2d60, 0x1078, 0x8ae0,
-+	0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc,
-+	0x00c0, 0x78ce, 0x1078, 0x4353, 0x0078, 0x78d0, 0x1078, 0x4431,
-+	0x0d7f, 0x0c7f, 0x00c0, 0x7921, 0x0c7e, 0x2d60, 0x1078, 0x772d,
-+	0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x1078, 0x9187, 0x0040, 0x78f1,
-+	0x6013, 0x0000, 0x6818, 0x601a, 0x601f, 0x0003, 0x6904, 0x0c7e,
-+	0x2d60, 0x1078, 0x772d, 0x0c7f, 0x1078, 0x775c, 0x0c7f, 0x0078,
-+	0x7934, 0x2001, 0xa8a4, 0x2004, 0x683e, 0x0c7f, 0x0078, 0x7934,
-+	0x7008, 0xa086, 0x000b, 0x00c0, 0x7912, 0x6018, 0x200c, 0xc1bc,
-+	0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
-+	0x000b, 0x601f, 0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f,
-+	0x0078, 0x7934, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7921, 0x2001,
-+	0xa8a4, 0x2004, 0x683e, 0x0078, 0x7934, 0x1078, 0x7953, 0x0078,
-+	0x7936, 0x8fff, 0x1040, 0x1332, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
-+	0x6837, 0x0103, 0x684b, 0x0003, 0x1078, 0x89cf, 0x1078, 0x8eb9,
-+	0x1078, 0x8ec6, 0x0d7f, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c,
-+	0xa186, 0x0015, 0x00c0, 0x7942, 0x2001, 0xa8a4, 0x2004, 0x683e,
-+	0x0078, 0x7950, 0xa18e, 0x0016, 0x00c0, 0x7952, 0x0c7e, 0x2d00,
-+	0x2060, 0x1078, 0xa495, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x0c7f,
-+	0x1078, 0x772d, 0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80,
-+	0x7b7c, 0xd2f4, 0x0040, 0x7962, 0x2001, 0xa8a4, 0x2004, 0x683e,
-+	0x0078, 0x79c6, 0x0c7e, 0x2d60, 0x1078, 0x89f3, 0x0c7f, 0x6804,
-+	0xa086, 0x0050, 0x00c0, 0x797a, 0x0c7e, 0x2d00, 0x2060, 0x6003,
-+	0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f,
-+	0x0078, 0x79c6, 0x6800, 0xa086, 0x000f, 0x0040, 0x799c, 0x8fff,
-+	0x1040, 0x1332, 0x6824, 0xd0dc, 0x00c0, 0x799c, 0x6800, 0xa086,
-+	0x0004, 0x00c0, 0x79a1, 0x784c, 0xd0ac, 0x0040, 0x79a1, 0x784c,
-+	0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001,
-+	0x0001, 0x682e, 0x0078, 0x79c0, 0x2001, 0x0007, 0x682e, 0x0078,
-+	0x79c0, 0x784c, 0xd0b4, 0x00c0, 0x79ae, 0xd0ac, 0x0040, 0x799c,
-+	0x784c, 0xd0f4, 0x00c0, 0x799c, 0x0078, 0x798f, 0xd2ec, 0x00c0,
-+	0x799c, 0x7024, 0xa306, 0x00c0, 0x79b9, 0x7020, 0xa406, 0x0040,
-+	0x799c, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
-+	0x1078, 0x8ff0, 0x1078, 0x62d1, 0x0078, 0x79c8, 0x1078, 0x772d,
-+	0x047f, 0x037f, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034,
-+	0x2068, 0x6a1c, 0xa286, 0x0007, 0x0040, 0x7a35, 0xa286, 0x0002,
-+	0x0040, 0x7a35, 0xa286, 0x0000, 0x0040, 0x7a35, 0x6808, 0x6338,
-+	0xa306, 0x00c0, 0x7a35, 0x2071, 0xab8c, 0xa186, 0x0015, 0x0040,
-+	0x7a2f, 0xa18e, 0x0016, 0x00c0, 0x7a02, 0x6030, 0xa084, 0x00ff,
-+	0xa086, 0x0001, 0x00c0, 0x7a02, 0x700c, 0xa086, 0x2a00, 0x00c0,
-+	0x7a02, 0x6034, 0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
-+	0x0078, 0x7a2f, 0x0c7e, 0x6034, 0x2060, 0x6104, 0xa186, 0x004b,
-+	0x0040, 0x7a22, 0xa186, 0x004c, 0x0040, 0x7a22, 0xa186, 0x004d,
-+	0x0040, 0x7a22, 0xa186, 0x004e, 0x0040, 0x7a22, 0xa186, 0x0052,
-+	0x0040, 0x7a22, 0x6010, 0x2068, 0x1078, 0x8d06, 0x1040, 0x1332,
-+	0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
-+	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f, 0x0078, 0x7a35, 0x6034,
-+	0x2068, 0x2001, 0xa8a4, 0x2004, 0x683e, 0x1078, 0x772d, 0x027f,
-+	0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010,
-+	0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7a73, 0x6018, 0x2068,
-+	0x157e, 0x037e, 0x027e, 0xae90, 0x000c, 0xa290, 0x0004, 0x20a9,
-+	0x0004, 0xad98, 0x000a, 0x1078, 0x80de, 0x027f, 0x037f, 0x157f,
-+	0x00c0, 0x7a76, 0x157e, 0x037e, 0x027e, 0xae90, 0x000c, 0xa290,
-+	0x0008, 0x20a9, 0x0004, 0xad98, 0x0006, 0x1078, 0x80de, 0x027f,
-+	0x037f, 0x157f, 0x00c0, 0x7a76, 0x7038, 0x680a, 0x703c, 0x680e,
-+	0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x77f8, 0x1078, 0x2880,
-+	0x0c7e, 0x1078, 0x76c7, 0x2f00, 0x601a, 0x6013, 0x0000, 0x601f,
-+	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x1078,
-+	0x4502, 0x1078, 0x4535, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0c7f,
-+	0x0078, 0x7a73, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1332, 0xa1b2,
-+	0x0040, 0x00c8, 0x7af7, 0x0079, 0x7a9d, 0x7aeb, 0x7adf, 0x7aeb,
-+	0x7aeb, 0x7aeb, 0x7aeb, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add,
-+	0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add,
-+	0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add,
-+	0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb, 0x7add, 0x7aeb, 0x7aeb,
-+	0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb, 0x7add, 0x7add,
-+	0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb,
-+	0x7aeb, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add,
-+	0x7add, 0x7add, 0x7aeb, 0x7add, 0x7add, 0x1078, 0x1332, 0x6003,
-+	0x0001, 0x6106, 0x1078, 0x5dd7, 0x127e, 0x2091, 0x8000, 0x1078,
-+	0x62d1, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5dd7,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x2600,
-+	0x0079, 0x7afa, 0x7afe, 0x7afe, 0x7afe, 0x7aeb, 0x1078, 0x1332,
-+	0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0,
-+	0x7b10, 0xa0b2, 0x0040, 0x00c8, 0x7c79, 0x2008, 0x0079, 0x7bbf,
-+	0xa1b6, 0x0027, 0x00c0, 0x7b7c, 0x1078, 0x61cd, 0x6004, 0x1078,
-+	0x8eec, 0x0040, 0x7b2d, 0x1078, 0x8f00, 0x0040, 0x7b74, 0xa08e,
-+	0x0021, 0x0040, 0x7b78, 0xa08e, 0x0022, 0x0040, 0x7b74, 0xa08e,
-+	0x003d, 0x0040, 0x7b78, 0x0078, 0x7b6f, 0x1078, 0x28a6, 0x2001,
-+	0x0007, 0x1078, 0x4502, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078,
-+	0x7c83, 0xa186, 0x007e, 0x00c0, 0x7b42, 0x2001, 0xa633, 0x2014,
-+	0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019,
-+	0x0028, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f, 0x027f,
-+	0x017f, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078,
-+	0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x0c7e, 0x6018,
-+	0xa065, 0x0040, 0x7b65, 0x1078, 0x47e9, 0x0c7f, 0x2c08, 0x1078,
-+	0x9f8b, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078, 0x457f, 0x1078,
-+	0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x7b6f,
-+	0x1078, 0x7ca6, 0x0078, 0x7b6f, 0xa186, 0x0014, 0x00c0, 0x7b73,
-+	0x1078, 0x61cd, 0x1078, 0x2880, 0x1078, 0x8eec, 0x00c0, 0x7b9b,
-+	0x1078, 0x28a6, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x7c83,
-+	0xa186, 0x007e, 0x00c0, 0x7b99, 0x2001, 0xa633, 0x200c, 0xc185,
-+	0x2102, 0x0078, 0x7b6f, 0x1078, 0x8f00, 0x00c0, 0x7ba3, 0x1078,
-+	0x7c83, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0032, 0x00c0, 0x7bb4,
-+	0x0e7e, 0x0f7e, 0x2071, 0xa682, 0x2079, 0x0000, 0x1078, 0x2bd7,
-+	0x0f7f, 0x0e7f, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0021, 0x0040,
-+	0x7b9f, 0xa08e, 0x0022, 0x1040, 0x7c83, 0x0078, 0x7b6f, 0x7c01,
-+	0x7c03, 0x7c07, 0x7c0b, 0x7c0f, 0x7c13, 0x7bff, 0x7bff, 0x7bff,
-+	0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
-+	0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
-+	0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7c17, 0x7c29, 0x7bff,
-+	0x7c2b, 0x7c29, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7c29,
-+	0x7c29, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
-+	0x7bff, 0x7c5c, 0x7c29, 0x7bff, 0x7c23, 0x7bff, 0x7bff, 0x7bff,
-+	0x7c25, 0x7bff, 0x7bff, 0x7bff, 0x7c29, 0x7bff, 0x7bff, 0x1078,
-+	0x1332, 0x0078, 0x7c29, 0x2001, 0x000b, 0x0078, 0x7c36, 0x2001,
-+	0x0003, 0x0078, 0x7c36, 0x2001, 0x0005, 0x0078, 0x7c36, 0x2001,
-+	0x0001, 0x0078, 0x7c36, 0x2001, 0x0009, 0x0078, 0x7c36, 0x1078,
-+	0x61cd, 0x6003, 0x0005, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x1078,
-+	0x62d1, 0x0078, 0x7c35, 0x0078, 0x7c29, 0x0078, 0x7c29, 0x1078,
-+	0x4502, 0x0078, 0x7c6e, 0x1078, 0x61cd, 0x6003, 0x0004, 0x2001,
-+	0xa8a2, 0x2004, 0x6016, 0x1078, 0x62d1, 0x007c, 0x1078, 0x4502,
-+	0x1078, 0x61cd, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002,
-+	0x037e, 0x2019, 0xa65d, 0x2304, 0xa084, 0xff00, 0x00c0, 0x7c4d,
-+	0x2019, 0xa8a2, 0x231c, 0x0078, 0x7c56, 0x8007, 0xa09a, 0x0004,
-+	0x0048, 0x7c48, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f,
-+	0x1078, 0x62d1, 0x0078, 0x7c35, 0x0e7e, 0x0f7e, 0x2071, 0xa682,
-+	0x2079, 0x0000, 0x1078, 0x2bd7, 0x0f7f, 0x0e7f, 0x1078, 0x61cd,
-+	0x1078, 0x772d, 0x1078, 0x62d1, 0x0078, 0x7c35, 0x1078, 0x61cd,
-+	0x6003, 0x0002, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x1078, 0x62d1,
-+	0x007c, 0x2600, 0x2008, 0x0079, 0x7c7d, 0x7c81, 0x7c81, 0x7c81,
-+	0x7c6e, 0x1078, 0x1332, 0x0e7e, 0x1078, 0x8d06, 0x0040, 0x7c9f,
-+	0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7c9f, 0x7007, 0x0000,
-+	0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7ca1, 0xa08e, 0x003d,
-+	0x0040, 0x7ca1, 0x017f, 0x7037, 0x0103, 0x7033, 0x0100, 0x0e7f,
-+	0x007c, 0x017f, 0x1078, 0x7ca6, 0x0078, 0x7c9f, 0x0e7e, 0xacf0,
-+	0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001,
-+	0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff,
-+	0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0x6604, 0xa6b6, 0x0043,
-+	0x00c0, 0x7cc6, 0x1078, 0x9134, 0x0078, 0x7d25, 0x6604, 0xa6b6,
-+	0x0033, 0x00c0, 0x7ccf, 0x1078, 0x90d8, 0x0078, 0x7d25, 0x6604,
-+	0xa6b6, 0x0028, 0x00c0, 0x7cd8, 0x1078, 0x8f2f, 0x0078, 0x7d25,
-+	0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7ce1, 0x1078, 0x8f49, 0x0078,
-+	0x7d25, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7cea, 0x1078, 0x77de,
-+	0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0000, 0x00c0, 0x7cf3, 0x1078,
-+	0x7a3b, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0022, 0x00c0, 0x7cfc,
-+	0x1078, 0x7807, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0035, 0x00c0,
-+	0x7d05, 0x1078, 0x7843, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0039,
-+	0x00c0, 0x7d0e, 0x1078, 0x79cc, 0x0078, 0x7d25, 0x6604, 0xa6b6,
-+	0x003d, 0x00c0, 0x7d17, 0x1078, 0x7823, 0x0078, 0x7d25, 0xa1b6,
-+	0x0015, 0x00c0, 0x7d1f, 0x1079, 0x7d2a, 0x0078, 0x7d25, 0xa1b6,
-+	0x0016, 0x00c0, 0x7d26, 0x1079, 0x7e7f, 0x007c, 0x1078, 0x7773,
-+	0x0078, 0x7d25, 0x7d4e, 0x7d51, 0x7d4e, 0x7d9c, 0x7d4e, 0x7e13,
-+	0x7e8b, 0x7d4e, 0x7d4e, 0x7e57, 0x7d4e, 0x7e6d, 0xa1b6, 0x0048,
-+	0x0040, 0x7d42, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
-+	0x15fa, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070,
-+	0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0005, 0x0005,
-+	0x007c, 0x0e7e, 0x2071, 0xa600, 0x7080, 0xa086, 0x0074, 0x00c0,
-+	0x7d85, 0x1078, 0x9f5f, 0x00c0, 0x7d77, 0x0d7e, 0x6018, 0x2068,
-+	0x7030, 0xd08c, 0x0040, 0x7d6a, 0x6800, 0xd0bc, 0x0040, 0x7d6a,
-+	0xc0c5, 0x6802, 0x1078, 0x7d89, 0x0d7f, 0x2001, 0x0006, 0x1078,
-+	0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078, 0x7d87, 0x2001,
-+	0x000a, 0x1078, 0x4502, 0x1078, 0x28a6, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x1078, 0x5dd7, 0x0078, 0x7d87, 0x1078, 0x7dff, 0x0e7f,
-+	0x007c, 0x6800, 0xd084, 0x0040, 0x7d9b, 0x2001, 0x0000, 0x1078,
-+	0x44ee, 0x2069, 0xa652, 0x6804, 0xd0a4, 0x0040, 0x7d9b, 0x2001,
-+	0x0006, 0x1078, 0x4535, 0x007c, 0x0d7e, 0x2011, 0xa620, 0x2204,
-+	0xa086, 0x0074, 0x00c0, 0x7dfb, 0x6018, 0x2068, 0x6aa0, 0xa286,
-+	0x007e, 0x00c0, 0x7daf, 0x1078, 0x7f9b, 0x0078, 0x7dfd, 0x1078,
-+	0x7f91, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286, 0x0080,
-+	0x00c0, 0x7dd3, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
-+	0x0040, 0x7dc9, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833,
-+	0x0200, 0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x28a6, 0x1078,
-+	0x772d, 0x0078, 0x7dfd, 0x0e7e, 0x2071, 0xa633, 0x2e04, 0xd09c,
-+	0x0040, 0x7dee, 0x2071, 0xab80, 0x7108, 0x720c, 0xa18c, 0x00ff,
-+	0x00c0, 0x7de6, 0xa284, 0xff00, 0x0040, 0x7dee, 0x6018, 0x2070,
-+	0x70a0, 0xd0bc, 0x00c0, 0x7dee, 0x7112, 0x7216, 0x0e7f, 0x2001,
-+	0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078,
-+	0x5dd7, 0x0078, 0x7dfd, 0x1078, 0x7dff, 0x0d7f, 0x007c, 0x2001,
-+	0x0007, 0x1078, 0x4502, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003,
-+	0x00c0, 0x7e0e, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x28a6,
-+	0x1078, 0x772d, 0x007c, 0x0e7e, 0x2071, 0xa600, 0x7080, 0xa086,
-+	0x0014, 0x00c0, 0x7e51, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7e26,
-+	0x6010, 0xa005, 0x00c0, 0x7e26, 0x1078, 0x3699, 0x0d7e, 0x6018,
-+	0x2068, 0x1078, 0x4649, 0x1078, 0x7d89, 0x0d7f, 0x1078, 0x8043,
-+	0x00c0, 0x7e51, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005,
-+	0x0040, 0x7e51, 0x2001, 0x0006, 0x1078, 0x4502, 0x0e7e, 0x6010,
-+	0xa005, 0x0040, 0x7e4a, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
-+	0x7033, 0x0200, 0x0e7f, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078,
-+	0x7e55, 0x1078, 0x7c83, 0x1078, 0x7dff, 0x0e7f, 0x007c, 0x2011,
-+	0xa620, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7e6a, 0x2001, 0x0002,
-+	0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5dd7,
-+	0x0078, 0x7e6c, 0x1078, 0x7dff, 0x007c, 0x2011, 0xa620, 0x2204,
-+	0xa086, 0x0004, 0x00c0, 0x7e7c, 0x2001, 0x0007, 0x1078, 0x4502,
-+	0x1078, 0x772d, 0x0078, 0x7e7e, 0x1078, 0x7dff, 0x007c, 0x7d4e,
-+	0x7e97, 0x7d4e, 0x7ed2, 0x7d4e, 0x7f44, 0x7e8b, 0x7d4e, 0x7d4e,
-+	0x7f59, 0x7d4e, 0x7f6c, 0x6604, 0xa686, 0x0003, 0x0040, 0x7e13,
-+	0xa6b6, 0x001e, 0x00c0, 0x7e96, 0x1078, 0x772d, 0x007c, 0x0d7e,
-+	0x0c7e, 0x1078, 0x7f7f, 0x00c0, 0x7ead, 0x2001, 0x0000, 0x1078,
-+	0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007,
-+	0x0002, 0x1078, 0x5dd7, 0x0078, 0x7ecf, 0x2009, 0xab8e, 0x2104,
-+	0xa086, 0x0009, 0x00c0, 0x7ec2, 0x6018, 0x2068, 0x6840, 0xa084,
-+	0x00ff, 0xa005, 0x0040, 0x7ecd, 0x8001, 0x6842, 0x6017, 0x000a,
-+	0x0078, 0x7ecf, 0x2009, 0xab8f, 0x2104, 0xa084, 0xff00, 0xa086,
-+	0x1900, 0x00c0, 0x7ecd, 0x0078, 0x7ea1, 0x1078, 0x7dff, 0x0c7f,
-+	0x0d7f, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7ee6, 0x2001, 0x0000,
-+	0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001,
-+	0x6007, 0x0002, 0x1078, 0x5dd7, 0x0078, 0x7f12, 0x1078, 0x7c83,
-+	0x2009, 0xab8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040,
-+	0x7f13, 0xa686, 0x000b, 0x0040, 0x7f10, 0x2009, 0xab8f, 0x2104,
-+	0xa084, 0xff00, 0x00c0, 0x7f00, 0xa686, 0x0009, 0x0040, 0x7f13,
-+	0xa086, 0x1900, 0x00c0, 0x7f10, 0xa686, 0x0009, 0x0040, 0x7f13,
-+	0x2001, 0x0004, 0x1078, 0x4502, 0x1078, 0x772d, 0x0078, 0x7f12,
-+	0x1078, 0x7dff, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06,
-+	0x0040, 0x7f21, 0x6838, 0xd0fc, 0x0040, 0x7f21, 0x0d7f, 0x0078,
-+	0x7f10, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040,
-+	0x7f32, 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f,
-+	0x0078, 0x7f12, 0x68a0, 0xa086, 0x007e, 0x00c0, 0x7f3f, 0x0e7e,
-+	0x2071, 0xa600, 0x1078, 0x42b8, 0x0e7f, 0x0078, 0x7f41, 0x1078,
-+	0x2880, 0x0d7f, 0x0078, 0x7f10, 0x1078, 0x7f8e, 0x00c0, 0x7f54,
-+	0x2001, 0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003,
-+	0x1078, 0x5dd7, 0x0078, 0x7f58, 0x1078, 0x7c83, 0x1078, 0x7dff,
-+	0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7f69, 0x2001, 0x0008, 0x1078,
-+	0x4502, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x5dd7, 0x0078,
-+	0x7f6b, 0x1078, 0x7dff, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7f7c,
-+	0x2001, 0x000a, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001,
-+	0x1078, 0x5dd7, 0x0078, 0x7f7e, 0x1078, 0x7dff, 0x007c, 0x2009,
-+	0xab8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x7f8d, 0x2009, 0xab8f,
-+	0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001,
-+	0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x45d6,
-+	0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x037e, 0x017e,
-+	0x6018, 0x2068, 0x2071, 0xa633, 0x2e04, 0xa085, 0x0003, 0x2072,
-+	0x1078, 0x8014, 0x0040, 0x7fd9, 0x2009, 0xa633, 0x2104, 0xc0cd,
-+	0x200a, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x7fc2, 0xa006,
-+	0x2020, 0x2009, 0x002a, 0x1078, 0xa21d, 0x2001, 0xa60c, 0x200c,
-+	0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x284f,
-+	0x2071, 0xa600, 0x1078, 0x2677, 0x0c7e, 0x157e, 0x20a9, 0x0081,
-+	0x2009, 0x007f, 0x1078, 0x298e, 0x8108, 0x00f0, 0x7fd2, 0x157f,
-+	0x0c7f, 0x1078, 0x7f91, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071,
-+	0xab80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa61b,
-+	0x206a, 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa61c, 0x206a,
-+	0x78ea, 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa626, 0x200a,
-+	0x2069, 0xab8e, 0x2071, 0xa89e, 0x6810, 0x2072, 0x6814, 0x7006,
-+	0x6818, 0x700a, 0x681c, 0x700e, 0x1078, 0x906e, 0x2001, 0x0006,
-+	0x1078, 0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x017f, 0x037f,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e,
-+	0x2019, 0xa626, 0x231c, 0x83ff, 0x0040, 0x803e, 0x2071, 0xab80,
-+	0x2e14, 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306,
-+	0x00c0, 0x803e, 0x2011, 0xab96, 0xad98, 0x000a, 0x20a9, 0x0004,
-+	0x1078, 0x80de, 0x00c0, 0x803e, 0x2011, 0xab9a, 0xad98, 0x0006,
-+	0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x803e, 0x157f, 0x0e7f,
-+	0x037f, 0x027f, 0x007c, 0x0e7e, 0x2071, 0xab8c, 0x7004, 0xa086,
-+	0x0014, 0x00c0, 0x8066, 0x7008, 0xa086, 0x0800, 0x00c0, 0x8066,
-+	0x700c, 0xd0ec, 0x0040, 0x8064, 0xa084, 0x0f00, 0xa086, 0x0100,
-+	0x00c0, 0x8064, 0x7024, 0xd0a4, 0x00c0, 0x8061, 0xd0ac, 0x0040,
-+	0x8064, 0xa006, 0x0078, 0x8066, 0xa085, 0x0001, 0x0e7f, 0x007c,
-+	0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e,
-+	0x127e, 0x2091, 0x8000, 0x2029, 0xa8ba, 0x252c, 0x2021, 0xa8c0,
-+	0x2424, 0x2061, 0xad00, 0x2071, 0xa600, 0x7248, 0x7064, 0xa202,
-+	0x00c8, 0x80cc, 0x1078, 0xa242, 0x0040, 0x80c4, 0x671c, 0xa786,
-+	0x0001, 0x0040, 0x80c4, 0xa786, 0x0007, 0x0040, 0x80c4, 0x2500,
-+	0xac06, 0x0040, 0x80c4, 0x2400, 0xac06, 0x0040, 0x80c4, 0x0c7e,
-+	0x6000, 0xa086, 0x0004, 0x00c0, 0x809f, 0x1078, 0x1757, 0xa786,
-+	0x0008, 0x00c0, 0x80ae, 0x1078, 0x8f00, 0x00c0, 0x80ae, 0x0c7f,
-+	0x1078, 0x7c83, 0x1078, 0x8ec6, 0x0078, 0x80c4, 0x6010, 0x2068,
-+	0x1078, 0x8d06, 0x0040, 0x80c1, 0xa786, 0x0003, 0x00c0, 0x80d6,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078,
-+	0x8eb9, 0x1078, 0x8ec6, 0x0c7f, 0xace0, 0x0010, 0x7058, 0xac02,
-+	0x00c8, 0x80cc, 0x0078, 0x807d, 0x127f, 0x007f, 0x027f, 0x047f,
-+	0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006,
-+	0x00c0, 0x80b8, 0x1078, 0xa1ca, 0x0078, 0x80c1, 0x220c, 0x2304,
-+	0xa106, 0x00c0, 0x80e9, 0x8210, 0x8318, 0x00f0, 0x80de, 0xa006,
-+	0x007c, 0x2304, 0xa102, 0x0048, 0x80f1, 0x2001, 0x0001, 0x0078,
-+	0x80f3, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a,
-+	0x0044, 0x10c8, 0x1332, 0x1078, 0x8eec, 0x0040, 0x8105, 0x1078,
-+	0x8f00, 0x0040, 0x8112, 0x0078, 0x810b, 0x1078, 0x28a6, 0x1078,
-+	0x8f00, 0x0040, 0x8112, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078,
-+	0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x810b, 0xa182, 0x0040,
-+	0x0079, 0x811a, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d,
-+	0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812f, 0x812f, 0x812f,
-+	0x812f, 0x812d, 0x812d, 0x812d, 0x812f, 0x1078, 0x1332, 0x600b,
-+	0xffff, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0,
-+	0x8146, 0x6004, 0xa082, 0x0040, 0x0079, 0x81d1, 0xa186, 0x0027,
-+	0x00c0, 0x8168, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6110,
-+	0x2168, 0x1078, 0x8d06, 0x0040, 0x8162, 0x6837, 0x0103, 0x684b,
-+	0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4a73,
-+	0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c,
-+	0xa186, 0x0014, 0x00c0, 0x8171, 0x6004, 0xa082, 0x0040, 0x0079,
-+	0x8199, 0xa186, 0x0046, 0x0040, 0x817d, 0xa186, 0x0045, 0x0040,
-+	0x817d, 0xa186, 0x0047, 0x10c0, 0x1332, 0x2001, 0x0109, 0x2004,
-+	0xd084, 0x0040, 0x8196, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e,
-+	0x027e, 0x1078, 0x5c56, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000,
-+	0xa086, 0x0002, 0x00c0, 0x8196, 0x0078, 0x820e, 0x1078, 0x7773,
-+	0x007c, 0x81ae, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac,
-+	0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ca, 0x81ca, 0x81ca, 0x81ca,
-+	0x81ac, 0x81ca, 0x81ac, 0x81ca, 0x1078, 0x1332, 0x1078, 0x61cd,
-+	0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d06, 0x0040, 0x81c4, 0x6837,
-+	0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852,
-+	0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d, 0x1078,
-+	0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1,
-+	0x007c, 0x81e6, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4,
-+	0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81f8, 0x81f8, 0x81f8, 0x81f8,
-+	0x81e4, 0x8207, 0x81e4, 0x81f8, 0x1078, 0x1332, 0x1078, 0x61cd,
-+	0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x62d1,
-+	0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c,
-+	0x1078, 0x61cd, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x2001, 0xa8a4,
-+	0x2004, 0x603e, 0x6003, 0x000f, 0x1078, 0x62d1, 0x007c, 0x1078,
-+	0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040,
-+	0x0079, 0x8212, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8227,
-+	0x8327, 0x8359, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225,
-+	0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x1078, 0x1332, 0x0e7e,
-+	0x0d7e, 0x603f, 0x0000, 0x2071, 0xab80, 0x7124, 0x610a, 0x2071,
-+	0xab8c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040,
-+	0x82e9, 0xa68c, 0x0c00, 0x0040, 0x825e, 0x0f7e, 0x2c78, 0x1078,
-+	0x4963, 0x0f7f, 0x0040, 0x825a, 0x684c, 0xd0ac, 0x0040, 0x825a,
-+	0x6024, 0xd0dc, 0x00c0, 0x825a, 0x6850, 0xd0bc, 0x00c0, 0x825a,
-+	0x7318, 0x6814, 0xa306, 0x00c0, 0x8301, 0x731c, 0x6810, 0xa306,
-+	0x00c0, 0x8301, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
-+	0xa186, 0x0002, 0x0040, 0x8291, 0xa186, 0x0028, 0x00c0, 0x826e,
-+	0x1078, 0x8eda, 0x684b, 0x001c, 0x0078, 0x8293, 0xd6dc, 0x0040,
-+	0x828a, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0040, 0x8288, 0x6914,
-+	0x6a10, 0x2100, 0xa205, 0x0040, 0x8288, 0x7018, 0xa106, 0x00c0,
-+	0x8285, 0x701c, 0xa206, 0x0040, 0x8288, 0x6962, 0x6a5e, 0xc6dc,
-+	0x0078, 0x8293, 0xd6d4, 0x0040, 0x8291, 0x684b, 0x0007, 0x0078,
-+	0x8293, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4,
-+	0x0040, 0x82bc, 0xa686, 0x0100, 0x00c0, 0x82a7, 0x2001, 0xab99,
-+	0x2004, 0xa005, 0x00c0, 0x82a7, 0xc6c4, 0x0078, 0x8236, 0x7328,
-+	0x732c, 0x6b56, 0x83ff, 0x0040, 0x82bc, 0xa38a, 0x0009, 0x0048,
-+	0x82b3, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90,
-+	0x0019, 0x1078, 0x89e2, 0x037f, 0xd6cc, 0x0040, 0x8317, 0x7124,
-+	0x695a, 0x81ff, 0x0040, 0x8317, 0xa192, 0x0021, 0x00c8, 0x82d5,
-+	0x2071, 0xab98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
-+	0x89e2, 0x1078, 0x91f4, 0x0078, 0x8317, 0x6838, 0xd0fc, 0x0040,
-+	0x82de, 0x2009, 0x0020, 0x695a, 0x0078, 0x82c8, 0x0f7e, 0x2d78,
-+	0x1078, 0x897a, 0x0f7f, 0x1078, 0x91f4, 0x1078, 0x89cf, 0x0078,
-+	0x8319, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x8307,
-+	0x684c, 0xd0ac, 0x0040, 0x8307, 0x6024, 0xd0dc, 0x00c0, 0x8307,
-+	0x6850, 0xd0bc, 0x00c0, 0x8307, 0x6810, 0x6914, 0xa105, 0x0040,
-+	0x8307, 0x1078, 0x8fbf, 0x0d7f, 0x0e7f, 0x0078, 0x8326, 0x684b,
-+	0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8317,
-+	0x6810, 0x6914, 0xa115, 0x0040, 0x8317, 0x1078, 0x84d5, 0x1078,
-+	0x4a73, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8f89,
-+	0x0d7f, 0x0e7f, 0x00c0, 0x8326, 0x1078, 0x772d, 0x007c, 0x0f7e,
-+	0x6003, 0x0003, 0x2079, 0xab8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
-+	0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x833e, 0x6003, 0x0002,
-+	0x0f7f, 0x007c, 0x2130, 0x2228, 0x0078, 0x834a, 0x2400, 0x797c,
-+	0xa10a, 0x2300, 0x7a80, 0xa213, 0x2600, 0xa102, 0x2500, 0xa203,
-+	0x0048, 0x833a, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f,
-+	0x0000, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, 0x1078, 0x639b,
-+	0x007c, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
-+	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15fa, 0x007c,
-+	0xa182, 0x0040, 0x0079, 0x836c, 0x837f, 0x837f, 0x837f, 0x837f,
-+	0x837f, 0x8381, 0x8424, 0x837f, 0x837f, 0x843a, 0x84ab, 0x837f,
-+	0x837f, 0x837f, 0x837f, 0x84ba, 0x837f, 0x837f, 0x837f, 0x1078,
-+	0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xab8c, 0x6110,
-+	0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e,
-+	0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x841f,
-+	0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x83a2, 0x7018, 0x7862,
-+	0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x841f, 0x1078, 0x138b,
-+	0x1040, 0x1332, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837,
-+	0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46,
-+	0xa68c, 0x0c00, 0x0040, 0x83c0, 0x7318, 0x6b62, 0x731c, 0x6b5e,
-+	0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x83dc, 0xa186, 0x0028,
-+	0x00c0, 0x83ce, 0x684b, 0x001c, 0x0078, 0x83de, 0xd6dc, 0x0040,
-+	0x83d5, 0x684b, 0x0015, 0x0078, 0x83de, 0xd6d4, 0x0040, 0x83dc,
-+	0x684b, 0x0007, 0x0078, 0x83de, 0x684b, 0x0000, 0x6f4e, 0x7850,
-+	0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x83fc, 0x7328,
-+	0x732c, 0x6b56, 0x83ff, 0x0040, 0x83fc, 0xa38a, 0x0009, 0x0048,
-+	0x83f3, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90,
-+	0x0019, 0x1078, 0x89e2, 0x037f, 0xd6cc, 0x0040, 0x841f, 0x7124,
-+	0x695a, 0x81ff, 0x0040, 0x841f, 0xa192, 0x0021, 0x00c8, 0x8413,
-+	0x2071, 0xab98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
-+	0x89e2, 0x0078, 0x841f, 0x7838, 0xd0fc, 0x0040, 0x841c, 0x2009,
-+	0x0020, 0x695a, 0x0078, 0x8408, 0x2d78, 0x1078, 0x897a, 0x0d7f,
-+	0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079,
-+	0xab8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12,
-+	0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cf0, 0x1078,
-+	0x6df4, 0x007c, 0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f,
-+	0x0040, 0x8446, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002,
-+	0x1078, 0x627a, 0x1078, 0x639b, 0x6110, 0x2168, 0x694c, 0xd1e4,
-+	0x0040, 0x84a9, 0xd1cc, 0x0040, 0x8480, 0x6948, 0x6838, 0xd0fc,
-+	0x0040, 0x8478, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90,
-+	0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304,
-+	0x2012, 0x8318, 0x8210, 0x00f0, 0x8467, 0x157f, 0x007f, 0x6852,
-+	0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078, 0x84a3,
-+	0x017e, 0x1078, 0x13b4, 0x0d7f, 0x1078, 0x89cf, 0x0078, 0x84a3,
-+	0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
-+	0x849f, 0xa086, 0x0028, 0x00c0, 0x8491, 0x684b, 0x001c, 0x0078,
-+	0x84a1, 0xd1dc, 0x0040, 0x8498, 0x684b, 0x0015, 0x0078, 0x84a1,
-+	0xd1d4, 0x0040, 0x849f, 0x684b, 0x0007, 0x0078, 0x84a1, 0x684b,
-+	0x0000, 0x1078, 0x4a73, 0x1078, 0x8f89, 0x00c0, 0x84a9, 0x1078,
-+	0x772d, 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x7058, 0x6003,
-+	0x0002, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x1078, 0x627a, 0x1078,
-+	0x639b, 0x007c, 0x1078, 0x627a, 0x1078, 0x2880, 0x0d7e, 0x6110,
-+	0x2168, 0x1078, 0x8d06, 0x0040, 0x84cf, 0x6837, 0x0103, 0x684b,
-+	0x0029, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f,
-+	0x1078, 0x772d, 0x1078, 0x639b, 0x007c, 0x684b, 0x0015, 0xd1fc,
-+	0x0040, 0x84e1, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189,
-+	0x0000, 0x6962, 0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x84e8,
-+	0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fd, 0x84fb, 0x85d0,
-+	0x85dc, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb,
-+	0x84fb, 0x84fb, 0x84fb, 0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x2071, 0xab8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff,
-+	0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x851b, 0xa684,
-+	0x00ff, 0x00c0, 0x851b, 0x6024, 0xd0f4, 0x0040, 0x851b, 0x1078,
-+	0x8fbf, 0x0078, 0x85cb, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
-+	0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x85c0, 0xa694,
-+	0xff00, 0xa284, 0x0c00, 0x0040, 0x8531, 0x7018, 0x7862, 0x701c,
-+	0x785e, 0xa284, 0x0300, 0x0040, 0x85bd, 0xa686, 0x0100, 0x00c0,
-+	0x8543, 0x2001, 0xab99, 0x2004, 0xa005, 0x00c0, 0x8543, 0xc6c4,
-+	0x7e46, 0x0078, 0x8524, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00,
-+	0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838,
-+	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
-+	0x0040, 0x855e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
-+	0xa186, 0x0002, 0x0040, 0x857a, 0xa186, 0x0028, 0x00c0, 0x856c,
-+	0x684b, 0x001c, 0x0078, 0x857c, 0xd6dc, 0x0040, 0x8573, 0x684b,
-+	0x0015, 0x0078, 0x857c, 0xd6d4, 0x0040, 0x857a, 0x684b, 0x0007,
-+	0x0078, 0x857c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
-+	0x6856, 0xa01e, 0xd6c4, 0x0040, 0x859a, 0x7328, 0x732c, 0x6b56,
-+	0x83ff, 0x0040, 0x859a, 0xa38a, 0x0009, 0x0048, 0x8591, 0x2019,
-+	0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90, 0x0019, 0x1078,
-+	0x89e2, 0x037f, 0xd6cc, 0x0040, 0x85bd, 0x7124, 0x695a, 0x81ff,
-+	0x0040, 0x85bd, 0xa192, 0x0021, 0x00c8, 0x85b1, 0x2071, 0xab98,
-+	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89e2, 0x0078,
-+	0x85bd, 0x7838, 0xd0fc, 0x0040, 0x85ba, 0x2009, 0x0020, 0x695a,
-+	0x0078, 0x85a6, 0x2d78, 0x1078, 0x897a, 0xd6dc, 0x00c0, 0x85c3,
-+	0xa006, 0x0078, 0x85c9, 0x2001, 0x0001, 0x2071, 0xab8c, 0x7218,
-+	0x731c, 0x1078, 0x1653, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c,
-+	0x2001, 0xa8a4, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
-+	0x2c10, 0x1078, 0x15fa, 0x007c, 0x2001, 0xa8a4, 0x2004, 0x603e,
-+	0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040,
-+	0x870c, 0x603f, 0x0000, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f,
-+	0x0040, 0x8622, 0x6814, 0x6910, 0xa115, 0x0040, 0x8622, 0x6a60,
-+	0xa206, 0x00c0, 0x85ff, 0x685c, 0xa106, 0x0040, 0x8622, 0x684c,
-+	0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000,
-+	0x6024, 0xd0f4, 0x00c0, 0x8617, 0x697c, 0x6810, 0xa102, 0x603a,
-+	0x6980, 0x6814, 0xa103, 0x6036, 0x6024, 0xc0f5, 0x6026, 0x0d7e,
-+	0x6018, 0x2068, 0x683c, 0x8000, 0x683e, 0x0d7f, 0x1078, 0x8fbf,
-+	0x0078, 0x870c, 0x694c, 0xd1cc, 0x0040, 0x86d1, 0x6948, 0x6838,
-+	0xd0fc, 0x0040, 0x8689, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e,
-+	0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
-+	0x865c, 0xa086, 0x0028, 0x00c0, 0x8643, 0x684b, 0x001c, 0x784b,
-+	0x001c, 0x0078, 0x8667, 0xd1dc, 0x0040, 0x8653, 0x684b, 0x0015,
-+	0x784b, 0x0015, 0x1078, 0x916c, 0x0040, 0x8651, 0x7944, 0xc1dc,
-+	0x7946, 0x0078, 0x8667, 0xd1d4, 0x0040, 0x865c, 0x684b, 0x0007,
-+	0x784b, 0x0007, 0x0078, 0x8667, 0x684c, 0xd0ac, 0x0040, 0x8667,
-+	0x6810, 0x6914, 0xa115, 0x0040, 0x8667, 0x1078, 0x84d5, 0x6848,
-+	0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d, 0xaf98,
-+	0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
-+	0x8210, 0x00f0, 0x8675, 0x157f, 0x0f7f, 0x007f, 0x6852, 0x007f,
-+	0x684e, 0x1078, 0x91f4, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078,
-+	0x8706, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6,
-+	0x0002, 0x0040, 0x86b6, 0xa086, 0x0028, 0x00c0, 0x869d, 0x684b,
-+	0x001c, 0x784b, 0x001c, 0x0078, 0x86c1, 0xd1dc, 0x0040, 0x86ad,
-+	0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x916c, 0x0040, 0x86ab,
-+	0x7944, 0xc1dc, 0x7946, 0x0078, 0x86c1, 0xd1d4, 0x0040, 0x86b6,
-+	0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x86c1, 0x684c, 0xd0ac,
-+	0x0040, 0x86c1, 0x6810, 0x6914, 0xa115, 0x0040, 0x86c1, 0x1078,
-+	0x84d5, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x0f7f,
-+	0x1078, 0x13b4, 0x0d7f, 0x1078, 0x91f4, 0x1078, 0x89cf, 0x0078,
-+	0x8706, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
-+	0x0040, 0x86f7, 0xa086, 0x0028, 0x00c0, 0x86e2, 0x684b, 0x001c,
-+	0x0078, 0x8704, 0xd1dc, 0x0040, 0x86f0, 0x684b, 0x0015, 0x1078,
-+	0x916c, 0x0040, 0x86ee, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8704,
-+	0xd1d4, 0x0040, 0x86f7, 0x684b, 0x0007, 0x0078, 0x8704, 0x684b,
-+	0x0000, 0x684c, 0xd0ac, 0x0040, 0x8704, 0x6810, 0x6914, 0xa115,
-+	0x0040, 0x8704, 0x1078, 0x84d5, 0x1078, 0x4a73, 0x1078, 0x8f89,
-+	0x00c0, 0x870c, 0x1078, 0x772d, 0x0d7f, 0x007c, 0x1078, 0x61cd,
-+	0x0078, 0x8714, 0x1078, 0x627a, 0x1078, 0x8d06, 0x0040, 0x8733,
-+	0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa60c, 0x210c,
-+	0xd18c, 0x00c0, 0x873e, 0xd184, 0x00c0, 0x873a, 0x6108, 0x694a,
-+	0xa18e, 0x0029, 0x00c0, 0x872e, 0x1078, 0xa4e2, 0x6847, 0x0000,
-+	0x1078, 0x4a73, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x1078,
-+	0x639b, 0x007c, 0x684b, 0x0004, 0x0078, 0x872e, 0x684b, 0x0004,
-+	0x0078, 0x872e, 0xa182, 0x0040, 0x0079, 0x8746, 0x8759, 0x8759,
-+	0x8759, 0x8759, 0x8759, 0x875b, 0x8759, 0x875e, 0x8759, 0x8759,
-+	0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759,
-+	0x8759, 0x1078, 0x1332, 0x1078, 0x772d, 0x007c, 0x007e, 0x027e,
-+	0xa016, 0x1078, 0x15fa, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085,
-+	0x0079, 0x876a, 0x8773, 0x8771, 0x8771, 0x877f, 0x8771, 0x8771,
-+	0x8771, 0x1078, 0x1332, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x027e,
-+	0x057e, 0x0d7e, 0x0e7e, 0x2071, 0xab80, 0x7224, 0x6212, 0x7220,
-+	0x1078, 0x8cf2, 0x0040, 0x87a4, 0x2268, 0x6800, 0xa086, 0x0000,
-+	0x0040, 0x87a4, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x87a4, 0x0c7e,
-+	0x2d60, 0x1078, 0x89f3, 0x0c7f, 0x0040, 0x87a4, 0x6803, 0x0002,
-+	0x6007, 0x0086, 0x0078, 0x87a6, 0x6007, 0x0087, 0x6003, 0x0001,
-+	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0f7e, 0x2278, 0x1078, 0x4963,
-+	0x0f7f, 0x0040, 0x87be, 0x6824, 0xd0ec, 0x0040, 0x87be, 0x0c7e,
-+	0x2260, 0x603f, 0x0000, 0x1078, 0x8fbf, 0x0c7f, 0x0e7f, 0x0d7f,
-+	0x057f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87d4, 0x6004,
-+	0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332,
-+	0xa082, 0x0085, 0x0079, 0x87e3, 0xa186, 0x0027, 0x0040, 0x87dc,
-+	0xa186, 0x0014, 0x10c0, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-+	0x1078, 0x62d1, 0x007c, 0x87ea, 0x87ec, 0x87ec, 0x87ea, 0x87ea,
-+	0x87ea, 0x87ea, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-+	0x1078, 0x62d1, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87fd, 0x6004,
-+	0xa082, 0x0085, 0x2008, 0x0078, 0x8838, 0xa186, 0x0027, 0x00c0,
-+	0x8820, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6010, 0x2068,
-+	0x1078, 0x8d06, 0x0040, 0x8816, 0x6837, 0x0103, 0x6847, 0x0000,
-+	0x684b, 0x0029, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078,
-+	0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7773, 0x0078, 0x881b,
-+	0xa186, 0x0014, 0x00c0, 0x881c, 0x1078, 0x61cd, 0x0d7e, 0x6010,
-+	0x2068, 0x1078, 0x8d06, 0x0040, 0x8816, 0x6837, 0x0103, 0x6847,
-+	0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8812,
-+	0x0079, 0x883a, 0x8843, 0x8841, 0x8841, 0x8841, 0x8841, 0x8841,
-+	0x885e, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6030, 0xa08c, 0xff00,
-+	0x810f, 0xa186, 0x0039, 0x0040, 0x8851, 0xa186, 0x0035, 0x00c0,
-+	0x8855, 0x2001, 0xa8a2, 0x0078, 0x8857, 0x2001, 0xa8a3, 0x2004,
-+	0x6016, 0x6003, 0x000c, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd,
-+	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x886c,
-+	0xa186, 0x0035, 0x00c0, 0x8870, 0x2001, 0xa8a2, 0x0078, 0x8872,
-+	0x2001, 0xa8a3, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x62d1,
-+	0x007c, 0xa182, 0x008c, 0x00c8, 0x8883, 0xa182, 0x0085, 0x0048,
-+	0x8883, 0x0079, 0x8886, 0x1078, 0x7773, 0x007c, 0x888d, 0x888d,
-+	0x888d, 0x888d, 0x888f, 0x88ec, 0x888d, 0x1078, 0x1332, 0x0f7e,
-+	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x88a2, 0x6030, 0xa08c,
-+	0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8903, 0xa186, 0x0035,
-+	0x0040, 0x8903, 0x0d7e, 0x1078, 0x8d06, 0x00c0, 0x88ab, 0x1078,
-+	0x8eb9, 0x0078, 0x88ce, 0x6010, 0x2068, 0x684c, 0xd0e4, 0x00c0,
-+	0x88b3, 0x1078, 0x8eb9, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040,
-+	0x88bf, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x88ca, 0xd0bc,
-+	0x0040, 0x88c6, 0x684b, 0x0002, 0x0078, 0x88ca, 0x684b, 0x0005,
-+	0x1078, 0x8f85, 0x6847, 0x0000, 0x1078, 0x4a73, 0x2c68, 0x1078,
-+	0x76c7, 0x0040, 0x88e7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
-+	0xab8e, 0x210c, 0x6136, 0x2009, 0xab8f, 0x210c, 0x613a, 0x6918,
-+	0x611a, 0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5d8a, 0x2d60,
-+	0x1078, 0x772d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963,
-+	0x0f7f, 0x0040, 0x8929, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186,
-+	0x0035, 0x0040, 0x8903, 0xa186, 0x001e, 0x0040, 0x8903, 0xa186,
-+	0x0039, 0x00c0, 0x8929, 0x0d7e, 0x2c68, 0x1078, 0x91bc, 0x00c0,
-+	0x894d, 0x1078, 0x76c7, 0x0040, 0x8926, 0x6106, 0x6003, 0x0001,
-+	0x601f, 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e,
-+	0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a,
-+	0x6920, 0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2d60, 0x0078,
-+	0x894d, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x894d,
-+	0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x893c, 0xc0ec, 0x6852,
-+	0x684b, 0x0006, 0x0078, 0x8947, 0xd0bc, 0x0040, 0x8943, 0x684b,
-+	0x0002, 0x0078, 0x8947, 0x684b, 0x0005, 0x1078, 0x8f85, 0x6847,
-+	0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d,
-+	0x007c, 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-+	0x8961, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078,
-+	0x4a73, 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x8973, 0xa186,
-+	0x0014, 0x0040, 0x8973, 0xa186, 0x0027, 0x0040, 0x8973, 0x1078,
-+	0x7773, 0x0078, 0x8979, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078,
-+	0x62d1, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001,
-+	0xa182, 0x0101, 0x00c8, 0x8986, 0x0078, 0x8988, 0x2009, 0x0100,
-+	0x2130, 0x2069, 0xab98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
-+	0xaf90, 0x001d, 0x1078, 0x89e2, 0xa6b2, 0x0020, 0x7804, 0xa06d,
-+	0x0040, 0x899c, 0x1078, 0x13b4, 0x1078, 0x138b, 0x0040, 0x89c6,
-+	0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a,
-+	0x003d, 0x00c8, 0x89b2, 0x2608, 0xad90, 0x000f, 0x1078, 0x89e2,
-+	0x0078, 0x89c6, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90,
-+	0x000f, 0x1078, 0x89e2, 0x0078, 0x899c, 0x0f7f, 0x852f, 0xa5ad,
-+	0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x89cb, 0x0f7f, 0x852f,
-+	0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e,
-+	0x8dff, 0x0040, 0x89e0, 0x6804, 0xa07d, 0x0040, 0x89de, 0x6807,
-+	0x0000, 0x1078, 0x4a73, 0x2f68, 0x0078, 0x89d3, 0x1078, 0x4a73,
-+	0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x89e8, 0x8108,
-+	0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0,
-+	0x89ea, 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031,
-+	0x0001, 0x601c, 0xa084, 0x000f, 0x1079, 0x8a0f, 0x127f, 0x067f,
-+	0x007c, 0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c,
-+	0xa084, 0x000f, 0x1079, 0x8a0f, 0x067f, 0x127f, 0x007c, 0x8a29,
-+	0x8a17, 0x8a24, 0x8a45, 0x8a17, 0x8a24, 0x8a45, 0x8a24, 0x1078,
-+	0x1332, 0x037e, 0x2019, 0x0010, 0x1078, 0x9dc7, 0x601f, 0x0006,
-+	0x6003, 0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001,
-+	0x007c, 0x0d7e, 0x86ff, 0x00c0, 0x8a40, 0x6010, 0x2068, 0x1078,
-+	0x8d06, 0x0040, 0x8a42, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51,
-+	0x1078, 0x8f85, 0x1078, 0x4a73, 0x1078, 0x772d, 0xa085, 0x0001,
-+	0x0d7f, 0x007c, 0xa006, 0x0078, 0x8a40, 0x6000, 0xa08a, 0x0010,
-+	0x10c8, 0x1332, 0x1079, 0x8a4d, 0x007c, 0x8a5d, 0x8a82, 0x8a5f,
-+	0x8aa5, 0x8a7e, 0x8a5d, 0x8a24, 0x8a29, 0x8a29, 0x8a24, 0x8a24,
-+	0x8a24, 0x8a24, 0x8a24, 0x8a24, 0x8a24, 0x1078, 0x1332, 0x86ff,
-+	0x00c0, 0x8a7b, 0x601c, 0xa086, 0x0006, 0x0040, 0x8a7b, 0x0d7e,
-+	0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x8a70, 0x1078, 0x8f85,
-+	0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
-+	0x5d8a, 0x1078, 0x62d1, 0xa085, 0x0001, 0x007c, 0x1078, 0x1757,
-+	0x0078, 0x8a5f, 0x0e7e, 0x2071, 0xa8b1, 0x7024, 0xac06, 0x00c0,
-+	0x8a8b, 0x1078, 0x6fc4, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006,
-+	0x00c0, 0x8a9d, 0x087e, 0x097e, 0x2049, 0x0001, 0x2c40, 0x1078,
-+	0x7246, 0x097f, 0x087f, 0x0078, 0x8a9f, 0x1078, 0x6ebe, 0x0e7f,
-+	0x00c0, 0x8a5f, 0x1078, 0x8a24, 0x007c, 0x037e, 0x0e7e, 0x2071,
-+	0xa8b1, 0x703c, 0xac06, 0x00c0, 0x8ab5, 0x2019, 0x0000, 0x1078,
-+	0x7058, 0x0e7f, 0x037f, 0x0078, 0x8a5f, 0x1078, 0x738a, 0x0e7f,
-+	0x037f, 0x00c0, 0x8a5f, 0x1078, 0x8a24, 0x007c, 0x0c7e, 0x601c,
-+	0xa084, 0x000f, 0x1079, 0x8ac6, 0x0c7f, 0x007c, 0x8ad5, 0x8b47,
-+	0x8c7f, 0x8ae0, 0x8ec6, 0x8ad5, 0x9db8, 0x772d, 0x8b47, 0x1078,
-+	0x8f00, 0x00c0, 0x8ad5, 0x1078, 0x7c83, 0x007c, 0x1078, 0x61cd,
-+	0x1078, 0x62d1, 0x1078, 0x772d, 0x007c, 0x6017, 0x0001, 0x007c,
-+	0x1078, 0x8d06, 0x0040, 0x8ae8, 0x6010, 0xa080, 0x0019, 0x2c02,
-+	0x6000, 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8af0, 0x007c,
-+	0x8b00, 0x8b02, 0x8b24, 0x8b36, 0x8b43, 0x8b00, 0x8ad5, 0x8ad5,
-+	0x8ad5, 0x8b36, 0x8b36, 0x8b00, 0x8b00, 0x8b00, 0x8b00, 0x8b40,
-+	0x1078, 0x1332, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052,
-+	0x2071, 0xa8b1, 0x7024, 0xac06, 0x0040, 0x8b20, 0x1078, 0x6ebe,
-+	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa8a3,
-+	0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x007c,
-+	0x6017, 0x0001, 0x0078, 0x8b1e, 0x0d7e, 0x6010, 0x2068, 0x6850,
-+	0xc0b5, 0x6852, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
-+	0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x0d7e, 0x6017,
-+	0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c,
-+	0x1078, 0x772d, 0x007c, 0x1078, 0x1757, 0x0078, 0x8b24, 0x6000,
-+	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b4f, 0x007c, 0x8b5f,
-+	0x8add, 0x8b61, 0x8b5f, 0x8b61, 0x8b61, 0x8ad6, 0x8b5f, 0x8acf,
-+	0x8acf, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x1078,
-+	0x1332, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
-+	0xa08a, 0x000c, 0x10c8, 0x1332, 0x1079, 0x8b6f, 0x007c, 0x8b7b,
-+	0x8c23, 0x8b7d, 0x8bbd, 0x8b7d, 0x8bbd, 0x8b7d, 0x8b8a, 0x8b7b,
-+	0x8bbd, 0x8b7b, 0x8ba7, 0x1078, 0x1332, 0x6004, 0xa08e, 0x0016,
-+	0x0040, 0x8bb8, 0xa08e, 0x0004, 0x0040, 0x8bb8, 0xa08e, 0x0002,
-+	0x0040, 0x8bb8, 0x6004, 0x1078, 0x8f00, 0x0040, 0x8c3e, 0xa08e,
-+	0x0021, 0x0040, 0x8c42, 0xa08e, 0x0022, 0x0040, 0x8c3e, 0xa08e,
-+	0x003d, 0x0040, 0x8c42, 0xa08e, 0x0039, 0x0040, 0x8c46, 0xa08e,
-+	0x0035, 0x0040, 0x8c46, 0xa08e, 0x001e, 0x0040, 0x8bba, 0xa08e,
-+	0x0001, 0x00c0, 0x8bb6, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084,
-+	0x00ff, 0x0d7f, 0xa086, 0x0006, 0x0040, 0x8bb8, 0x1078, 0x2880,
-+	0x1078, 0x7c83, 0x1078, 0x8ec6, 0x007c, 0x0c7e, 0x0d7e, 0x6104,
-+	0xa186, 0x0016, 0x0040, 0x8c13, 0xa186, 0x0002, 0x00c0, 0x8be6,
-+	0x6018, 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x8c6a, 0x6840, 0xa084,
-+	0x00ff, 0xa005, 0x0040, 0x8be6, 0x8001, 0x6842, 0x6013, 0x0000,
-+	0x601f, 0x0007, 0x6017, 0x0398, 0x1078, 0x76c7, 0x0040, 0x8be6,
-+	0x2d00, 0x601a, 0x601f, 0x0001, 0x0078, 0x8c13, 0x0d7f, 0x0c7f,
-+	0x6004, 0xa08e, 0x0002, 0x00c0, 0x8c04, 0x6018, 0xa080, 0x0028,
-+	0x2004, 0xa086, 0x007e, 0x00c0, 0x8c04, 0x2009, 0xa633, 0x2104,
-+	0xc085, 0x200a, 0x0e7e, 0x2071, 0xa600, 0x1078, 0x42b8, 0x0e7f,
-+	0x1078, 0x7c83, 0x0078, 0x8c08, 0x1078, 0x7c83, 0x1078, 0x2880,
-+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x127f, 0x0e7f,
-+	0x1078, 0x8ec6, 0x007c, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003,
-+	0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0d7f,
-+	0x0c7f, 0x0078, 0x8c12, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
-+	0x0040, 0x8c13, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005,
-+	0x0040, 0x8be6, 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5dd7,
-+	0x1078, 0x62d1, 0x0d7f, 0x0c7f, 0x0078, 0x8c12, 0x1078, 0x7c83,
-+	0x0078, 0x8bba, 0x1078, 0x7ca6, 0x0078, 0x8bba, 0x0d7e, 0x2c68,
-+	0x6104, 0x1078, 0x91bc, 0x0d7f, 0x0040, 0x8c52, 0x1078, 0x772d,
-+	0x0078, 0x8c69, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
-+	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
-+	0x600a, 0x2001, 0xa8a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078,
-+	0x62d1, 0x007c, 0x0d7f, 0x0c7f, 0x1078, 0x7c83, 0x1078, 0x2880,
-+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x6013, 0x0000,
-+	0x601f, 0x0007, 0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000,
-+	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8c87, 0x007c, 0x8c97,
-+	0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97,
-+	0x8ad5, 0x8c97, 0x8add, 0x8c99, 0x8add, 0x8ca7, 0x8c97, 0x1078,
-+	0x1332, 0x6004, 0xa086, 0x008b, 0x0040, 0x8ca7, 0x6007, 0x008b,
-+	0x6003, 0x000d, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x1078,
-+	0x8eb9, 0x1078, 0x8d06, 0x0040, 0x8cdf, 0x1078, 0x2880, 0x0d7e,
-+	0x1078, 0x8d06, 0x0040, 0x8cc1, 0x6010, 0x2068, 0x6837, 0x0103,
-+	0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078,
-+	0x4a73, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x8ccf, 0x6818, 0x601a,
-+	0x0c7e, 0x2d60, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x8cd0, 0x2d60,
-+	0x0d7f, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003,
-+	0x0001, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0078, 0x8cf1, 0x6030,
-+	0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8ceb, 0xa186,
-+	0x0035, 0x00c0, 0x8cef, 0x1078, 0x2880, 0x0078, 0x8cc1, 0x1078,
-+	0x8ec6, 0x007c, 0xa284, 0x000f, 0x00c0, 0x8d03, 0xa282, 0xad00,
-+	0x0048, 0x8d03, 0x2001, 0xa616, 0x2004, 0xa202, 0x00c8, 0x8d03,
-+	0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x8d02, 0x027e, 0x0e7e,
-+	0x2071, 0xa600, 0x6210, 0x705c, 0xa202, 0x0048, 0x8d18, 0x7060,
-+	0xa202, 0x00c8, 0x8d18, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c,
-+	0xa006, 0x0078, 0x8d15, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e,
-+	0x2091, 0x8000, 0x2061, 0xad00, 0x2071, 0xa600, 0x7348, 0x7064,
-+	0xa302, 0x00c8, 0x8d45, 0x601c, 0xa206, 0x00c0, 0x8d3d, 0x1078,
-+	0x902b, 0x0040, 0x8d3d, 0x1078, 0x8f00, 0x00c0, 0x8d39, 0x1078,
-+	0x7c83, 0x0c7e, 0x1078, 0x772d, 0x0c7f, 0xace0, 0x0010, 0x7058,
-+	0xac02, 0x00c8, 0x8d45, 0x0078, 0x8d26, 0x127f, 0x007f, 0x037f,
-+	0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa735,
-+	0x210c, 0x81ff, 0x0040, 0x8d59, 0x2061, 0xa9b3, 0x611a, 0x1078,
-+	0x2880, 0xa006, 0x0078, 0x8d5e, 0xa085, 0x0001, 0x017f, 0x0c7f,
-+	0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
-+	0x1078, 0x76c7, 0x057f, 0x0040, 0x8d7b, 0x6612, 0x651a, 0x601f,
-+	0x0003, 0x2009, 0x004b, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f,
-+	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8d77, 0x0c7e, 0x057e,
-+	0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x76c7, 0x057f,
-+	0x0040, 0x8da9, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
-+	0x2560, 0x1078, 0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039,
-+	0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f, 0x2009,
-+	0x004c, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
-+	0x007c, 0xa006, 0x0078, 0x8da5, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
-+	0x1078, 0x76c7, 0x2c78, 0x0c7f, 0x0040, 0x8dc6, 0x7e12, 0x2c00,
-+	0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8e11, 0x2f60,
-+	0x2009, 0x004d, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f,
-+	0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7,
-+	0x2c78, 0x0c7f, 0x0040, 0x8de4, 0x7e12, 0x2c00, 0x781a, 0x781f,
-+	0x0003, 0x2021, 0x0005, 0x1078, 0x8e11, 0x2f60, 0x2009, 0x004e,
-+	0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
-+	0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7, 0x2c78, 0x0c7f,
-+	0x0040, 0x8e0d, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
-+	0x0004, 0x1078, 0x8e11, 0x2001, 0xa89d, 0x2004, 0xd0fc, 0x0040,
-+	0x8e06, 0x2f60, 0x1078, 0x772d, 0x0078, 0x8e0b, 0x2f60, 0x2009,
-+	0x0052, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f,
-+	0x007c, 0x097e, 0x077e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4775,
-+	0x0040, 0x8e1e, 0x2001, 0x8e16, 0x0078, 0x8e24, 0x1078, 0x4739,
-+	0x0040, 0x8e2d, 0x2001, 0x8e1e, 0x007e, 0xa00e, 0x2400, 0x1078,
-+	0x4b51, 0x1078, 0x4a73, 0x007f, 0x007a, 0x2418, 0x1078, 0x6161,
-+	0x62a0, 0x087e, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x1078,
-+	0x5f1b, 0x087f, 0x1078, 0x5e0a, 0x2f08, 0x2648, 0x1078, 0x9f8b,
-+	0x613c, 0x81ff, 0x1040, 0x5fdb, 0x1078, 0x62d1, 0x127f, 0x077f,
-+	0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-+	0x76c7, 0x017f, 0x0040, 0x8e63, 0x660a, 0x611a, 0x601f, 0x0001,
-+	0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x775c, 0xa085, 0x0001,
-+	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e60, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8e7f,
-+	0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021,
-+	0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
-+	0x0078, 0x8e7c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-+	0x76c7, 0x017f, 0x0040, 0x8e9b, 0x660a, 0x611a, 0x601f, 0x0001,
-+	0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, 0x775c, 0xa085, 0x0001,
-+	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e98, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8eb6,
-+	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078,
-+	0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
-+	0x8eb3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040,
-+	0x8ec3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x007e, 0x6000,
-+	0xa086, 0x0000, 0x0040, 0x8ed8, 0x6013, 0x0000, 0x601f, 0x0007,
-+	0x2001, 0xa8a3, 0x2004, 0x6016, 0x1078, 0xa495, 0x603f, 0x0000,
-+	0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0xa653, 0x2634,
-+	0xd6e4, 0x0040, 0x8ee8, 0x6618, 0x2660, 0x6e48, 0x1078, 0x46e7,
-+	0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e,
-+	0x0002, 0x0040, 0x8efd, 0xa08e, 0x0003, 0x0040, 0x8efd, 0xa08e,
-+	0x0004, 0x0040, 0x8efd, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c,
-+	0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8f0d, 0x6838, 0xd0fc,
-+	0x0040, 0x8f0d, 0xa006, 0x0078, 0x8f0f, 0xa085, 0x0001, 0x0d7f,
-+	0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-+	0x76c7, 0x017f, 0x0040, 0x8f2c, 0x611a, 0x601f, 0x0001, 0x2d00,
-+	0x6012, 0x1078, 0x2880, 0x2009, 0x0028, 0x1078, 0x775c, 0xa085,
-+	0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8f29, 0xa186,
-+	0x0015, 0x00c0, 0x8f44, 0x2011, 0xa620, 0x2204, 0xa086, 0x0074,
-+	0x00c0, 0x8f44, 0x1078, 0x7f91, 0x6003, 0x0001, 0x6007, 0x0029,
-+	0x1078, 0x5dd7, 0x0078, 0x8f48, 0x1078, 0x7c83, 0x1078, 0x772d,
-+	0x007c, 0xa186, 0x0016, 0x00c0, 0x8f53, 0x2001, 0x0004, 0x1078,
-+	0x4502, 0x0078, 0x8f74, 0xa186, 0x0015, 0x00c0, 0x8f78, 0x2011,
-+	0xa620, 0x2204, 0xa086, 0x0014, 0x00c0, 0x8f78, 0x0d7e, 0x6018,
-+	0x2068, 0x1078, 0x4649, 0x0d7f, 0x1078, 0x8043, 0x00c0, 0x8f78,
-+	0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x8f78,
-+	0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x77f8, 0x0078, 0x8f7c,
-+	0x1078, 0x7c83, 0x1078, 0x772d, 0x007c, 0x6848, 0xa086, 0x0005,
-+	0x00c0, 0x8f84, 0x1078, 0x8f85, 0x007c, 0x6850, 0xc0ad, 0x6852,
-+	0x007c, 0x0e7e, 0x2071, 0xab8c, 0x7014, 0xd0e4, 0x0040, 0x8f9a,
-+	0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a,
-+	0x1078, 0x62d1, 0x0e7f, 0x007c, 0x0c7e, 0x0f7e, 0x2c78, 0x1078,
-+	0x4963, 0x0f7f, 0x0040, 0x8fa9, 0x601c, 0xa084, 0x000f, 0x1079,
-+	0x8fab, 0x0c7f, 0x007c, 0x8ad5, 0x8fb6, 0x8fb9, 0x8fbc, 0xa25d,
-+	0xa279, 0xa27c, 0x8ad5, 0x8ad5, 0x1078, 0x1332, 0x0005, 0x0005,
-+	0x007c, 0x0005, 0x0005, 0x007c, 0x1078, 0x8fbf, 0x007c, 0x0f7e,
-+	0x2c78, 0x1078, 0x4963, 0x0040, 0x8fee, 0x1078, 0x76c7, 0x00c0,
-+	0x8fcf, 0x2001, 0xa8a4, 0x2004, 0x783e, 0x0078, 0x8fee, 0x7818,
-+	0x601a, 0x781c, 0xa086, 0x0003, 0x0040, 0x8fdc, 0x7808, 0x6036,
-+	0x2f00, 0x603a, 0x0078, 0x8fe0, 0x7808, 0x603a, 0x2f00, 0x6036,
-+	0x602a, 0x601f, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7920,
-+	0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2f60, 0x0f7f, 0x007c,
-+	0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0040, 0x9001,
-+	0xa086, 0x0005, 0x0040, 0x9005, 0xa006, 0x602a, 0x602e, 0x0078,
-+	0x9016, 0x6824, 0xc0f4, 0xc0d5, 0x6826, 0x6810, 0x2078, 0x787c,
-+	0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x00c8, 0x8ffc, 0x6834,
-+	0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
-+	0x6808, 0x603a, 0x6918, 0x611a, 0x6920, 0x6122, 0x601f, 0x0001,
-+	0x6007, 0x0039, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x6803, 0x0002,
-+	0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0034,
-+	0x0040, 0x9050, 0xa08e, 0x0035, 0x0040, 0x9050, 0xa08e, 0x0036,
-+	0x0040, 0x9050, 0xa08e, 0x0037, 0x0040, 0x9050, 0xa08e, 0x0038,
-+	0x0040, 0x9050, 0xa08e, 0x0039, 0x0040, 0x9050, 0xa08e, 0x003a,
-+	0x0040, 0x9050, 0xa08e, 0x003b, 0x0040, 0x9050, 0xa085, 0x0001,
-+	0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x00c0,
-+	0x905d, 0xa085, 0x0001, 0x0078, 0x906c, 0x6024, 0xd0f4, 0x00c0,
-+	0x906b, 0xc0f5, 0x6026, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c,
-+	0x6036, 0x1078, 0x1757, 0xa006, 0x0f7f, 0x007c, 0x007e, 0x017e,
-+	0x027e, 0x037e, 0x0e7e, 0x2001, 0xa89e, 0x200c, 0x8000, 0x2014,
-+	0x2001, 0x0032, 0x1078, 0x5c1c, 0x2001, 0xa8a2, 0x82ff, 0x00c0,
-+	0x9083, 0x2011, 0x0014, 0x2202, 0x2001, 0xa8a0, 0x200c, 0x8000,
-+	0x2014, 0x2071, 0xa88d, 0x711a, 0x721e, 0x2001, 0x0064, 0x1078,
-+	0x5c1c, 0x2001, 0xa8a3, 0x82ff, 0x00c0, 0x9098, 0x2011, 0x0014,
-+	0x2202, 0x2009, 0xa8a4, 0xa280, 0x000a, 0x200a, 0x1078, 0x498b,
-+	0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e, 0x0e7e,
-+	0x2001, 0xa8a2, 0x2003, 0x0028, 0x2001, 0xa8a3, 0x2003, 0x0014,
-+	0x2071, 0xa88d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xa8a4,
-+	0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
-+	0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x90d5, 0x611a,
-+	0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078, 0x775c,
-+	0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x90d2,
-+	0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa600, 0xa186, 0x0015, 0x00c0,
-+	0x9107, 0x7080, 0xa086, 0x0018, 0x00c0, 0x9107, 0x6010, 0x2068,
-+	0x6a3c, 0xd2e4, 0x00c0, 0x90fb, 0x2c78, 0x1078, 0x6490, 0x0040,
-+	0x910f, 0x706c, 0x6a50, 0xa206, 0x00c0, 0x9103, 0x7070, 0x6a54,
-+	0xa206, 0x00c0, 0x9103, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
-+	0x0000, 0x1078, 0x28c8, 0x1078, 0x77f8, 0x0078, 0x910b, 0x1078,
-+	0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x7050,
-+	0xa080, 0x29c0, 0x2004, 0x6a54, 0xa206, 0x0040, 0x90fb, 0x0078,
-+	0x9103, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7,
-+	0x017f, 0x0040, 0x9131, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
-+	0x2009, 0x0043, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f,
-+	0x007c, 0xa006, 0x0078, 0x912e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071,
-+	0xa600, 0xa186, 0x0015, 0x00c0, 0x915a, 0x7080, 0xa086, 0x0004,
-+	0x00c0, 0x915a, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078, 0x6490,
-+	0x0040, 0x9162, 0x706c, 0x6a08, 0xa206, 0x00c0, 0x9156, 0x7070,
-+	0x6a0c, 0xa206, 0x00c0, 0x9156, 0x1078, 0x2880, 0x1078, 0x77f8,
-+	0x0078, 0x915e, 0x1078, 0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f,
-+	0x0d7f, 0x007c, 0x7050, 0xa080, 0x29c0, 0x2004, 0x6a0c, 0xa206,
-+	0x0040, 0x9154, 0x0078, 0x9156, 0x017e, 0x027e, 0x684c, 0xd0ac,
-+	0x0040, 0x9184, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x9184,
-+	0x6860, 0xa106, 0x00c0, 0x9180, 0x685c, 0xa206, 0x0040, 0x9184,
-+	0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c, 0x0e7e,
-+	0x127e, 0x2071, 0xa600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001,
-+	0x0048, 0x91b9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
-+	0x91a5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x91a1, 0x0078,
-+	0x9194, 0x2061, 0xad00, 0x0078, 0x9194, 0x6003, 0x0008, 0x8529,
-+	0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x91b5, 0x754e,
-+	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xad00, 0x0078,
-+	0x91b0, 0xa006, 0x0078, 0x91b2, 0x0c7e, 0x027e, 0x017e, 0xa186,
-+	0x0035, 0x0040, 0x91c6, 0x6a34, 0x0078, 0x91c7, 0x6a28, 0x1078,
-+	0x8cf2, 0x0040, 0x91f0, 0x2260, 0x611c, 0xa186, 0x0003, 0x0040,
-+	0x91d5, 0xa186, 0x0006, 0x00c0, 0x91ec, 0x6834, 0xa206, 0x0040,
-+	0x91e4, 0x6838, 0xa206, 0x00c0, 0x91ec, 0x6108, 0x6834, 0xa106,
-+	0x00c0, 0x91ec, 0x0078, 0x91e9, 0x6008, 0x6938, 0xa106, 0x00c0,
-+	0x91ec, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f, 0x007c,
-+	0xa085, 0x0001, 0x0078, 0x91ec, 0x6944, 0xd1cc, 0x0040, 0x920d,
-+	0xa18c, 0x00ff, 0xa18e, 0x0002, 0x00c0, 0x920d, 0xad88, 0x001e,
-+	0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001, 0x00c0, 0x920d,
-+	0x6810, 0x6914, 0xa115, 0x10c0, 0x84d5, 0x007c, 0x067e, 0x6000,
-+	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9218, 0x067f, 0x007c,
-+	0x9228, 0x96df, 0x97fb, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
-+	0x9262, 0x988e, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
-+	0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332,
-+	0x1079, 0x9234, 0x067f, 0x007c, 0x9244, 0x9d53, 0x9244, 0x9244,
-+	0x9244, 0x9244, 0x9244, 0x9244, 0x9d11, 0x9da1, 0x9244, 0xa3b0,
-+	0xa3e4, 0xa3b0, 0xa3e4, 0x9244, 0x1078, 0x1332, 0x067e, 0x6000,
-+	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9250, 0x067f, 0x007c,
-+	0x9260, 0x99eb, 0x9ac7, 0x9af5, 0x9b70, 0x9260, 0x9c76, 0x9c1e,
-+	0x989a, 0x9ce5, 0x9cfb, 0x9260, 0x9260, 0x9260, 0x9260, 0x9260,
-+	0x1078, 0x1332, 0xa1b2, 0x0044, 0x10c8, 0x1332, 0x2100, 0x0079,
-+	0x9269, 0x92a9, 0x9498, 0x92a9, 0x92a9, 0x92a9, 0x94a0, 0x92a9,
-+	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-+	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-+	0x92ab, 0x9311, 0x9320, 0x9377, 0x9396, 0x9415, 0x9485, 0x92a9,
-+	0x92a9, 0x94a4, 0x92a9, 0x92a9, 0x94b7, 0x94c2, 0x92a9, 0x92a9,
-+	0x92a9, 0x92a9, 0x92a9, 0x94fa, 0x92a9, 0x92a9, 0x9509, 0x92a9,
-+	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x9522, 0x92a9, 0x92a9,
-+	0x92a9, 0x95af, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-+	0x9629, 0x1078, 0x1332, 0x1078, 0x4967, 0x00c0, 0x92bb, 0x2001,
-+	0xa633, 0x2004, 0xd0cc, 0x00c0, 0x92bb, 0xa084, 0x0009, 0xa086,
-+	0x0008, 0x00c0, 0x92c3, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
-+	0x0000, 0x0078, 0x9493, 0x1078, 0x4957, 0x0e7e, 0x0c7e, 0x037e,
-+	0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029,
-+	0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08,
-+	0x1078, 0x9f8b, 0x077f, 0x017f, 0x2e60, 0x1078, 0x47e9, 0x017f,
-+	0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x6618, 0x0c7e, 0x2660, 0x1078,
-+	0x45d6, 0x0c7f, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082,
-+	0x0006, 0x0048, 0x9303, 0x1078, 0x9ebf, 0x00c0, 0x9371, 0x1078,
-+	0x9e50, 0x00c0, 0x92ff, 0x6007, 0x0008, 0x0078, 0x9493, 0x6007,
-+	0x0009, 0x0078, 0x9493, 0x1078, 0xa09f, 0x0040, 0x930d, 0x1078,
-+	0x9ebf, 0x0040, 0x92f7, 0x0078, 0x9371, 0x6013, 0x1900, 0x0078,
-+	0x92ff, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6106, 0x1078, 0x9e05,
-+	0x6007, 0x0006, 0x0078, 0x9493, 0x6007, 0x0007, 0x0078, 0x9493,
-+	0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0, 0x9664,
-+	0x0d7e, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082, 0x0006,
-+	0x00c8, 0x9336, 0x2001, 0x0001, 0x1078, 0x44ee, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0040, 0x9353, 0xa686, 0x0004, 0x0040,
-+	0x9353, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9353,
-+	0xa686, 0x0004, 0x0040, 0x9353, 0xa686, 0x0005, 0x0040, 0x9353,
-+	0x0d7f, 0x0078, 0x9371, 0x1078, 0x9f25, 0x00c0, 0x936c, 0xa686,
-+	0x0006, 0x00c0, 0x9365, 0x027e, 0x6218, 0xa290, 0x0028, 0x2214,
-+	0x2009, 0x0000, 0x1078, 0x28c8, 0x027f, 0x1078, 0x4649, 0x6007,
-+	0x000a, 0x0d7f, 0x0078, 0x9493, 0x6007, 0x000b, 0x0d7f, 0x0078,
-+	0x9493, 0x1078, 0x2880, 0x6007, 0x0001, 0x0078, 0x9493, 0x1078,
-+	0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6618,
-+	0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x9371,
-+	0x027e, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078,
-+	0x28c8, 0x027f, 0x6007, 0x000c, 0x0078, 0x9493, 0x1078, 0x4967,
-+	0x00c0, 0x93a3, 0x2001, 0xa633, 0x2004, 0xa084, 0x0009, 0xa086,
-+	0x0008, 0x00c0, 0x93ab, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
-+	0x0000, 0x0078, 0x9493, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001,
-+	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x93ef, 0xa6b4,
-+	0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x93c2, 0xa686, 0x0006,
-+	0x00c0, 0x9371, 0x1078, 0x9f34, 0x00c0, 0x93ca, 0x6007, 0x000e,
-+	0x0078, 0x9493, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4,
-+	0x00ff, 0x8427, 0x047e, 0x1078, 0x2880, 0x047f, 0x017e, 0xa006,
-+	0x2009, 0xa653, 0x210c, 0xd1a4, 0x0040, 0x93e9, 0x2009, 0x0029,
-+	0x1078, 0xa21d, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802,
-+	0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9493, 0x2001,
-+	0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9,
-+	0x0004, 0x2019, 0xa605, 0x2011, 0xab90, 0x1078, 0x80de, 0x037f,
-+	0x027f, 0x017f, 0x157f, 0xa005, 0x0040, 0x940f, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0040, 0x93c2, 0x0078, 0x9371, 0x6013,
-+	0x1900, 0x6007, 0x0009, 0x0078, 0x9493, 0x1078, 0x4967, 0x00c0,
-+	0x9422, 0x2001, 0xa633, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
-+	0x00c0, 0x942a, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000,
-+	0x0078, 0x9493, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001, 0x2634,
-+	0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x9472, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0004, 0x0040, 0x9441, 0xa686, 0x0006, 0x00c0,
-+	0x9371, 0x1078, 0x9f5f, 0x00c0, 0x944d, 0x1078, 0x9e50, 0x00c0,
-+	0x944d, 0x6007, 0x0010, 0x0078, 0x9493, 0x047e, 0x6418, 0xa4a0,
-+	0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2880,
-+	0x047f, 0x017e, 0xa006, 0x2009, 0xa653, 0x210c, 0xd1a4, 0x0040,
-+	0x946c, 0x2009, 0x0029, 0x1078, 0xa21d, 0x6018, 0x0d7e, 0x2068,
-+	0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001,
-+	0x0078, 0x9493, 0x1078, 0xa09f, 0x0040, 0x947f, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0040, 0x9441, 0x0078, 0x9371, 0x6013,
-+	0x1900, 0x6007, 0x0009, 0x0078, 0x9493, 0x1078, 0x29bb, 0x00c0,
-+	0x9664, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0,
-+	0x9371, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c,
-+	0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x0078, 0x9497,
-+	0x6007, 0x0005, 0x0078, 0x949a, 0x1078, 0xa41c, 0x00c0, 0x9664,
-+	0x1078, 0x29bb, 0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0, 0x9371,
-+	0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c, 0x1078,
-+	0x29bb, 0x00c0, 0x9664, 0x6007, 0x0023, 0x6003, 0x0001, 0x1078,
-+	0x5dd7, 0x007c, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb,
-+	0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0, 0x9371, 0x017e, 0x027e,
-+	0x2011, 0xab90, 0x2214, 0x2c08, 0xa006, 0x1078, 0xa1e6, 0x00c0,
-+	0x94e9, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xab89,
-+	0x2214, 0xa296, 0xffff, 0x00c0, 0x94f3, 0x6007, 0x0025, 0x0078,
-+	0x94f3, 0x6004, 0xa086, 0x0024, 0x00c0, 0x94f0, 0x1078, 0x772d,
-+	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x027f,
-+	0x017f, 0x007c, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6106, 0x1078,
-+	0x9687, 0x6007, 0x002b, 0x0078, 0x9493, 0x6007, 0x002c, 0x0078,
-+	0x9493, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0,
-+	0x9664, 0x1078, 0x9667, 0x00c0, 0x9371, 0x6106, 0x1078, 0x968c,
-+	0x00c0, 0x951e, 0x6007, 0x002e, 0x0078, 0x9493, 0x6007, 0x002f,
-+	0x0078, 0x9493, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x0e7e, 0x0d7e,
-+	0x0c7e, 0x6018, 0xa080, 0x0001, 0x200c, 0xa184, 0x00ff, 0xa086,
-+	0x0006, 0x0040, 0x953f, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006,
-+	0x0040, 0x953f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0078, 0x9498, 0x2001,
-+	0xa672, 0x2004, 0xd0e4, 0x0040, 0x95ab, 0x2071, 0xab8c, 0x7010,
-+	0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xa653, 0x2004,
-+	0xd0a4, 0x0040, 0x955d, 0x6018, 0x2068, 0x6810, 0xa106, 0x00c0,
-+	0x955d, 0x6814, 0xa206, 0x0040, 0x9581, 0x2001, 0xa653, 0x2004,
-+	0xd0ac, 0x00c0, 0x959f, 0x2069, 0xa600, 0x6870, 0xa206, 0x00c0,
-+	0x959f, 0x686c, 0xa106, 0x00c0, 0x959f, 0x7210, 0x1078, 0x8cf2,
-+	0x0040, 0x95a5, 0x1078, 0xa28e, 0x0040, 0x95a5, 0x622a, 0x6007,
-+	0x0036, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0c7f, 0x0d7f, 0x0e7f,
-+	0x007c, 0x7214, 0xa286, 0xffff, 0x0040, 0x9593, 0x1078, 0x8cf2,
-+	0x0040, 0x95a5, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x00c0,
-+	0x95a5, 0x0078, 0x956e, 0x7210, 0x2c08, 0xa085, 0x0001, 0x1078,
-+	0xa1e6, 0x2c10, 0x2160, 0x0040, 0x95a5, 0x0078, 0x956e, 0x6007,
-+	0x0037, 0x6013, 0x1500, 0x0078, 0x9579, 0x6007, 0x0037, 0x6013,
-+	0x1700, 0x0078, 0x9579, 0x6007, 0x0012, 0x0078, 0x9579, 0x1078,
-+	0x29bb, 0x00c0, 0x9664, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084,
-+	0xff00, 0x8007, 0xa086, 0x0006, 0x00c0, 0x9498, 0x0e7e, 0x0d7e,
-+	0x0c7e, 0x2001, 0xa672, 0x2004, 0xd0e4, 0x0040, 0x9621, 0x2069,
-+	0xa600, 0x2071, 0xab8c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286,
-+	0xffff, 0x00c0, 0x95de, 0x7208, 0x0c7e, 0x2c08, 0xa085, 0x0001,
-+	0x1078, 0xa1e6, 0x2c10, 0x0c7f, 0x0040, 0x9615, 0x1078, 0x8cf2,
-+	0x0040, 0x9615, 0x0c7e, 0x027e, 0x2260, 0x1078, 0x89f3, 0x027f,
-+	0x0c7f, 0x7118, 0xa18c, 0xff00, 0x810f, 0xa186, 0x0001, 0x0040,
-+	0x95ff, 0xa186, 0x0005, 0x0040, 0x95f9, 0xa186, 0x0007, 0x00c0,
-+	0x9609, 0xa280, 0x0004, 0x2004, 0xa005, 0x0040, 0x9609, 0x057e,
-+	0x7510, 0x7614, 0x1078, 0xa2a3, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f,
-+	0x007c, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003,
-+	0x0001, 0x1078, 0x5d8a, 0x0078, 0x9605, 0x6007, 0x003b, 0x602b,
-+	0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0078,
-+	0x9605, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0078,
-+	0x9579, 0x0e7e, 0x027e, 0x1078, 0x4967, 0x0040, 0x965e, 0x1078,
-+	0x4957, 0x1078, 0xa4a9, 0x00c0, 0x965c, 0x2071, 0xa600, 0x70cc,
-+	0xc085, 0x70ce, 0x0f7e, 0x2079, 0x0100, 0x7298, 0xa284, 0x00ff,
-+	0x706e, 0x78e6, 0xa284, 0xff00, 0x7270, 0xa205, 0x7072, 0x78ea,
-+	0x0f7f, 0x70d7, 0x0000, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040,
-+	0x9655, 0x2011, 0xa8ca, 0x2013, 0x07d0, 0xd0ac, 0x00c0, 0x965e,
-+	0x1078, 0x2677, 0x0078, 0x965e, 0x1078, 0xa4d9, 0x027f, 0x0e7f,
-+	0x1078, 0x772d, 0x0078, 0x9497, 0x1078, 0x772d, 0x007c, 0x0d7e,
-+	0x067e, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686,
-+	0x0006, 0x0040, 0x9684, 0xa686, 0x0004, 0x0040, 0x9684, 0x6e04,
-+	0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9684, 0xa686, 0x0004,
-+	0x0040, 0x9684, 0xa085, 0x0001, 0x067f, 0x0d7f, 0x007c, 0x0d7e,
-+	0x1078, 0x96bb, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x96ca, 0x00c0,
-+	0x96b4, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff, 0xa115,
-+	0x6212, 0x6824, 0x602a, 0xd1e4, 0x0040, 0x96a2, 0x2009, 0x0001,
-+	0x0078, 0x96b0, 0xd1ec, 0x0040, 0x96b4, 0x6920, 0xa18c, 0x00ff,
-+	0x6824, 0x1078, 0x254d, 0x00c0, 0x96b4, 0x2110, 0x2009, 0x0000,
-+	0x1078, 0x28c8, 0x0078, 0x96b8, 0xa085, 0x0001, 0x0078, 0x96b9,
-+	0xa006, 0x0d7f, 0x007c, 0x2069, 0xab8d, 0x6800, 0xa082, 0x0010,
-+	0x00c8, 0x96c8, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x96c9,
-+	0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0xab8c, 0x6808, 0xa084,
-+	0xff00, 0xa086, 0x0800, 0x00c0, 0x96de, 0x6800, 0xa084, 0x00ff,
-+	0xa08e, 0x0014, 0x0040, 0x96de, 0xa08e, 0x0010, 0x007c, 0x6004,
-+	0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0, 0x96eb,
-+	0x2008, 0x0079, 0x96fe, 0xa1b6, 0x0027, 0x0040, 0x96f3, 0xa1b6,
-+	0x0014, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078,
-+	0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c, 0x973e, 0x9740,
-+	0x973e, 0x973e, 0x973e, 0x9740, 0x974c, 0x97d6, 0x9799, 0x97d6,
-+	0x97ad, 0x97d6, 0x974c, 0x97d6, 0x97ce, 0x97d6, 0x97ce, 0x97d6,
-+	0x97d6, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e,
-+	0x973e, 0x973e, 0x973e, 0x973e, 0x9740, 0x973e, 0x97d6, 0x973e,
-+	0x973e, 0x97d6, 0x973e, 0x97d6, 0x97d6, 0x973e, 0x973e, 0x973e,
-+	0x973e, 0x97d6, 0x97d6, 0x973e, 0x97d6, 0x97d6, 0x973e, 0x973e,
-+	0x973e, 0x973e, 0x973e, 0x9740, 0x97d6, 0x97d6, 0x973e, 0x973e,
-+	0x97d6, 0x97d6, 0x973e, 0x973e, 0x973e, 0x973e, 0x1078, 0x1332,
-+	0x1078, 0x61cd, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x6003, 0x0002,
-+	0x1078, 0x62d1, 0x0078, 0x97dc, 0x0f7e, 0x2079, 0xa652, 0x7804,
-+	0x0f7f, 0xd0ac, 0x00c0, 0x97d6, 0x2001, 0x0000, 0x1078, 0x44ee,
-+	0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x97d6,
-+	0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9770, 0x6010,
-+	0xa005, 0x0040, 0x9770, 0x0c7f, 0x1078, 0x3699, 0x0078, 0x97d6,
-+	0x0c7f, 0x2001, 0xa600, 0x2004, 0xa086, 0x0002, 0x00c0, 0x977f,
-+	0x0f7e, 0x2079, 0xa600, 0x7890, 0x8000, 0x7892, 0x0f7f, 0x2001,
-+	0x0002, 0x1078, 0x4502, 0x1078, 0x61cd, 0x601f, 0x0001, 0x6003,
-+	0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0c7e,
-+	0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x5a52, 0x0c7f, 0x0078,
-+	0x97dc, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0040, 0x97d6, 0xa686, 0x0004, 0x0040,
-+	0x97d6, 0x2001, 0x0004, 0x0078, 0x97d4, 0x2001, 0xa600, 0x2004,
-+	0xa086, 0x0003, 0x00c0, 0x97b6, 0x1078, 0x3699, 0x2001, 0x0006,
-+	0x1078, 0x97dd, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
-+	0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x97d6, 0x2001, 0x0006,
-+	0x0078, 0x97d4, 0x2001, 0x0004, 0x0078, 0x97d4, 0x2001, 0x0006,
-+	0x1078, 0x97dd, 0x0078, 0x97d6, 0x1078, 0x4535, 0x1078, 0x61cd,
-+	0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0x017e, 0x0d7e, 0x6118,
-+	0x2168, 0x6900, 0xd184, 0x0040, 0x97f8, 0x6104, 0xa18e, 0x000a,
-+	0x00c0, 0x97f0, 0x699c, 0xd1a4, 0x00c0, 0x97f0, 0x2001, 0x0007,
-+	0x1078, 0x4502, 0x2001, 0x0000, 0x1078, 0x44ee, 0x1078, 0x28a6,
-+	0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
-+	0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0xa1b6,
-+	0x0015, 0x00c0, 0x980f, 0x1079, 0x9816, 0x0078, 0x9815, 0xa1b6,
-+	0x0016, 0x10c0, 0x1332, 0x1079, 0x9822, 0x007c, 0x7d4e, 0x7d4e,
-+	0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x9877, 0x982e, 0x7d4e, 0x7d4e,
-+	0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e,
-+	0x9877, 0x987f, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x0f7e, 0x2079,
-+	0xa652, 0x7804, 0xd0ac, 0x00c0, 0x9855, 0x6018, 0xa07d, 0x0040,
-+	0x9855, 0x7800, 0xd0f4, 0x00c0, 0x9841, 0x7810, 0xa005, 0x00c0,
-+	0x9855, 0x2001, 0x0000, 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078,
-+	0x4502, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
-+	0x5dd7, 0x1078, 0x62d1, 0x0078, 0x9875, 0x2011, 0xab83, 0x2204,
-+	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9875, 0x0c7e, 0x1078,
-+	0x45c4, 0x0040, 0x9868, 0x0c7f, 0x1078, 0x772d, 0x0078, 0x9875,
-+	0x6010, 0x007e, 0x6014, 0x007e, 0x1078, 0x42f8, 0x007f, 0x6016,
-+	0x007f, 0x6012, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c, 0x6604,
-+	0xa6b6, 0x001e, 0x00c0, 0x987e, 0x1078, 0x772d, 0x007c, 0x1078,
-+	0x7f8e, 0x00c0, 0x988b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
-+	0x5dd7, 0x0078, 0x988d, 0x1078, 0x772d, 0x007c, 0x6004, 0xa08a,
-+	0x0044, 0x10c8, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078,
-+	0x62d1, 0x007c, 0xa182, 0x0040, 0x0079, 0x989e, 0x98b1, 0x98b1,
-+	0x98b1, 0x98b1, 0x98b3, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1,
-+	0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1,
-+	0x98b1, 0x1078, 0x1332, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
-+	0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x98c4,
-+	0x2021, 0x0000, 0x1078, 0xa472, 0x6106, 0x2071, 0xab80, 0x7444,
-+	0xa4a4, 0xff00, 0x0040, 0x991b, 0xa486, 0x2000, 0x00c0, 0x98d6,
-+	0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5bf1, 0x1078, 0x138b,
-+	0x1040, 0x1332, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
-+	0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
-+	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084,
-+	0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4a73,
-+	0x017f, 0xa486, 0x2000, 0x00c0, 0x9903, 0x2019, 0x0017, 0x1078,
-+	0xa195, 0x0078, 0x997d, 0xa486, 0x0400, 0x00c0, 0x990d, 0x2019,
-+	0x0002, 0x1078, 0xa146, 0x0078, 0x997d, 0xa486, 0x0200, 0x00c0,
-+	0x9913, 0x1078, 0xa12b, 0xa486, 0x1000, 0x00c0, 0x9919, 0x1078,
-+	0xa17a, 0x0078, 0x997d, 0x2069, 0xa933, 0x6a00, 0xd284, 0x0040,
-+	0x99e7, 0xa284, 0x0300, 0x00c0, 0x99df, 0x6804, 0xa005, 0x0040,
-+	0x99c5, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1370, 0x0040, 0x9984,
-+	0x7800, 0xd08c, 0x00c0, 0x9937, 0x7804, 0x8001, 0x7806, 0x6013,
-+	0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
-+	0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
-+	0x6986, 0x6846, 0x7928, 0x698a, 0x792c, 0x698e, 0x7930, 0x6992,
-+	0x7934, 0x6996, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
-+	0x0002, 0x00c0, 0x995f, 0x684f, 0x0040, 0x0078, 0x9969, 0xa286,
-+	0x0001, 0x00c0, 0x9967, 0x684f, 0x0080, 0x0078, 0x9969, 0x684f,
-+	0x0000, 0x20a9, 0x000a, 0x2001, 0xab90, 0xad90, 0x0015, 0x200c,
-+	0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x996f, 0x200c, 0x6982,
-+	0x8000, 0x200c, 0x697e, 0x1078, 0x4a73, 0x027f, 0x047f, 0x157f,
-+	0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x2001, 0xa60e, 0x2004, 0xd084,
-+	0x0040, 0x998e, 0x1078, 0x138b, 0x00c0, 0x9930, 0x6013, 0x0100,
-+	0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-+	0x0078, 0x997d, 0x2069, 0xab92, 0x2d04, 0xa084, 0xff00, 0xa086,
-+	0x1200, 0x00c0, 0x99b9, 0x2069, 0xab80, 0x686c, 0xa084, 0x00ff,
-+	0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003,
-+	0x0001, 0x6007, 0x0043, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078,
-+	0x997d, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078,
-+	0x5d8a, 0x1078, 0x62d1, 0x0078, 0x997d, 0x2001, 0xa60d, 0x2004,
-+	0xd0ec, 0x0040, 0x99cf, 0x2011, 0x8049, 0x1078, 0x361b, 0x6013,
-+	0x0300, 0x0078, 0x99d5, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
-+	0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x997d, 0x6013,
-+	0x0500, 0x0078, 0x99d5, 0x6013, 0x0600, 0x0078, 0x999a, 0x6013,
-+	0x0200, 0x0078, 0x999a, 0xa186, 0x0013, 0x00c0, 0x99fd, 0x6004,
-+	0xa08a, 0x0040, 0x1048, 0x1332, 0xa08a, 0x0053, 0x10c8, 0x1332,
-+	0xa082, 0x0040, 0x2008, 0x0079, 0x9a82, 0xa186, 0x0051, 0x0040,
-+	0x9a0a, 0xa186, 0x0047, 0x00c0, 0x9a23, 0x6004, 0xa086, 0x0041,
-+	0x0040, 0x9a31, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x9a31,
-+	0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x5c56,
-+	0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0,
-+	0x9a31, 0x0078, 0x9ac7, 0xa186, 0x0027, 0x0040, 0x9a2b, 0xa186,
-+	0x0014, 0x10c0, 0x1332, 0x6004, 0xa082, 0x0040, 0x2008, 0x0079,
-+	0x9a34, 0x1078, 0x7773, 0x007c, 0x9a47, 0x9a49, 0x9a49, 0x9a71,
-+	0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47,
-+	0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x1078,
-+	0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x037e, 0x0d7e, 0x6010,
-+	0xa06d, 0x0040, 0x9a6e, 0xad84, 0xf000, 0x0040, 0x9a6e, 0x6003,
-+	0x0002, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x9a6e, 0x2019, 0x0004,
-+	0x1078, 0xa1ca, 0x6013, 0x0000, 0x6014, 0xa005, 0x00c0, 0x9a6c,
-+	0x2001, 0xa8a3, 0x2004, 0x6016, 0x6003, 0x0007, 0x0d7f, 0x037f,
-+	0x007c, 0x0d7e, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x1078, 0x8d06,
-+	0x0040, 0x9a7e, 0x6010, 0x2068, 0x1078, 0x13a4, 0x1078, 0x8ec6,
-+	0x0d7f, 0x007c, 0x9a95, 0x9ab4, 0x9a9e, 0x9ac1, 0x9a95, 0x9a95,
-+	0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95,
-+	0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x1078, 0x1332, 0x6010,
-+	0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x61cd,
-+	0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x9aaf, 0x6003,
-+	0x0007, 0x2009, 0x0043, 0x1078, 0x775c, 0x0078, 0x9ab1, 0x6003,
-+	0x0002, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0xa423,
-+	0x00c0, 0x9abe, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x1078, 0x62d1,
-+	0x007c, 0x1078, 0x61cd, 0x2009, 0x0041, 0x0078, 0x9c1e, 0xa182,
-+	0x0040, 0x0079, 0x9acb, 0x9ade, 0x9ae0, 0x9ade, 0x9ade, 0x9ade,
-+	0x9ade, 0x9ade, 0x9ae1, 0x9ade, 0x9ade, 0x9ade, 0x9ade, 0x9ade,
-+	0x9ade, 0x9ade, 0x9ade, 0x9ade, 0x9aec, 0x9ade, 0x1078, 0x1332,
-+	0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
-+	0x2c10, 0x1078, 0x15fa, 0x007c, 0x0d7e, 0x1078, 0x5bc1, 0x0d7f,
-+	0x1078, 0xa495, 0x1078, 0x772d, 0x007c, 0xa182, 0x0040, 0x0079,
-+	0x9af9, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c,
-+	0x9b0e, 0x9b0c, 0x9b11, 0x9b3c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c,
-+	0x9b3c, 0x9b0c, 0x9b0c, 0x9b0c, 0x1078, 0x1332, 0x1078, 0x7773,
-+	0x007c, 0x1078, 0x627a, 0x1078, 0x639b, 0x6010, 0x0d7e, 0x2068,
-+	0x684c, 0xd0fc, 0x0040, 0x9b27, 0xa08c, 0x0003, 0xa18e, 0x0002,
-+	0x0040, 0x9b2f, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c1e, 0x6003,
-+	0x0007, 0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x1078,
-+	0xa423, 0x0040, 0x9b35, 0x0d7f, 0x007c, 0x1078, 0x5bc1, 0x1078,
-+	0x772d, 0x0d7f, 0x0078, 0x9b2e, 0x037e, 0x1078, 0x627a, 0x1078,
-+	0x639b, 0x6010, 0x0d7e, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0040,
-+	0x9b5c, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x9b58,
-+	0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
-+	0x6003, 0x0002, 0x0078, 0x9b6d, 0x2019, 0x0004, 0x1078, 0xa1ca,
-+	0x6014, 0xa005, 0x00c0, 0x9b69, 0x2001, 0xa8a3, 0x2004, 0x8003,
-+	0x6016, 0x6013, 0x0000, 0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c,
-+	0xa186, 0x0013, 0x00c0, 0x9b7e, 0x6004, 0xa086, 0x0042, 0x10c0,
-+	0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0027,
-+	0x0040, 0x9b86, 0xa186, 0x0014, 0x00c0, 0x9b96, 0x6004, 0xa086,
-+	0x0042, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078,
-+	0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040,
-+	0x0079, 0x9b9a, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad,
-+	0x9bad, 0x9baf, 0x9bbb, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad,
-+	0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x1078, 0x1332, 0x037e,
-+	0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15fa,
-+	0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x6810, 0x6a14,
-+	0x6118, 0x210c, 0xd1bc, 0x0040, 0x9bda, 0x6124, 0xd1f4, 0x00c0,
-+	0x9bda, 0x007e, 0x047e, 0x057e, 0x6c7c, 0xa422, 0x6d80, 0x2200,
-+	0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a, 0x057f,
-+	0x047f, 0x007f, 0xa20d, 0x00c0, 0x9bee, 0x684c, 0xd0fc, 0x0040,
-+	0x9be6, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c1e, 0x6003, 0x0007,
-+	0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x007e, 0x0f7e,
-+	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x007f, 0x0040, 0x9bfb, 0x6003,
-+	0x0002, 0x0d7f, 0x007c, 0x2009, 0xa60d, 0x210c, 0xd19c, 0x0040,
-+	0x9c05, 0x6003, 0x0007, 0x0078, 0x9c07, 0x6003, 0x0006, 0x1078,
-+	0x9c0d, 0x1078, 0x5bc3, 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x9c19,
-+	0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0078,
-+	0x9c1b, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040,
-+	0x0048, 0x9c24, 0x0079, 0x9c31, 0xa186, 0x0013, 0x0040, 0x9c2c,
-+	0xa186, 0x0014, 0x10c0, 0x1332, 0x6024, 0xd0dc, 0x1040, 0x1332,
-+	0x007c, 0x9c44, 0x9c4b, 0x9c57, 0x9c63, 0x9c44, 0x9c44, 0x9c44,
-+	0x9c72, 0x9c44, 0x9c46, 0x9c46, 0x9c44, 0x9c44, 0x9c44, 0x9c44,
-+	0x9c44, 0x9c44, 0x9c44, 0x9c44, 0x1078, 0x1332, 0x6024, 0xd0dc,
-+	0x1040, 0x1332, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x6003,
-+	0x0001, 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078,
-+	0x62d1, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078,
-+	0x1cf0, 0x127e, 0x2091, 0x8000, 0x1078, 0x5df6, 0x1078, 0x639b,
-+	0x127f, 0x007c, 0xa016, 0x1078, 0x15fa, 0x007c, 0x127e, 0x2091,
-+	0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x9c83, 0x0d7f,
-+	0x037f, 0x127f, 0x007c, 0x9c93, 0x9c95, 0x9caa, 0x9cc9, 0x9c93,
-+	0x9c93, 0x9c93, 0x9ce1, 0x9c93, 0x9c93, 0x9c93, 0x9c93, 0x9c93,
-+	0x9c93, 0x9c93, 0x9c93, 0x1078, 0x1332, 0x6010, 0x2068, 0x684c,
-+	0xd0fc, 0x0040, 0x9cbf, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
-+	0x9cbf, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-+	0x0078, 0x9ce4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9cbf,
-+	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9cbf, 0x6003, 0x0001,
-+	0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x9ce4, 0x6013,
-+	0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0xa1ca, 0x0078,
-+	0x9ce4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9cbf, 0xa09c,
-+	0x0003, 0xa39e, 0x0003, 0x0040, 0x9cbf, 0x6003, 0x0003, 0x6106,
-+	0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, 0x1078, 0x639b, 0x0078,
-+	0x9ce4, 0xa016, 0x1078, 0x15fa, 0x007c, 0x1078, 0x61cd, 0x6110,
-+	0x81ff, 0x0040, 0x9cf6, 0x0d7e, 0x2168, 0x1078, 0xa4e2, 0x037e,
-+	0x2019, 0x0029, 0x1078, 0xa1ca, 0x037f, 0x0d7f, 0x1078, 0x8ec6,
-+	0x1078, 0x62d1, 0x007c, 0x1078, 0x627a, 0x6110, 0x81ff, 0x0040,
-+	0x9d0c, 0x0d7e, 0x2168, 0x1078, 0xa4e2, 0x037e, 0x2019, 0x0029,
-+	0x1078, 0xa1ca, 0x037f, 0x0d7f, 0x1078, 0x8ec6, 0x1078, 0x639b,
-+	0x007c, 0xa182, 0x0085, 0x0079, 0x9d15, 0x9d1e, 0x9d1c, 0x9d1c,
-+	0x9d2a, 0x9d1c, 0x9d1c, 0x9d1c, 0x1078, 0x1332, 0x6003, 0x000b,
-+	0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1,
-+	0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078, 0xa41c, 0x0040, 0x9d34,
-+	0x1078, 0x772d, 0x0078, 0x9d50, 0x2071, 0xab80, 0x7224, 0x6212,
-+	0x7220, 0x1078, 0xa069, 0x0040, 0x9d41, 0x6007, 0x0086, 0x0078,
-+	0x9d4a, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0, 0x9d4a,
-+	0x6007, 0x0086, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-+	0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9d64, 0x6004,
-+	0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332,
-+	0xa082, 0x0085, 0x0079, 0x9d7b, 0xa186, 0x0027, 0x0040, 0x9d70,
-+	0xa186, 0x0014, 0x0040, 0x9d70, 0x1078, 0x7773, 0x0078, 0x9d7a,
-+	0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-+	0x1078, 0x62d1, 0x007c, 0x9d82, 0x9d84, 0x9d84, 0x9d82, 0x9d82,
-+	0x9d82, 0x9d82, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-+	0x1078, 0x62d1, 0x007c, 0xa182, 0x0085, 0x1048, 0x1332, 0xa182,
-+	0x008c, 0x10c8, 0x1332, 0xa182, 0x0085, 0x0079, 0x9d97, 0x9d9e,
-+	0x9d9e, 0x9d9e, 0x9da0, 0x9d9e, 0x9d9e, 0x9d9e, 0x1078, 0x1332,
-+	0x007c, 0xa186, 0x0013, 0x0040, 0x9db1, 0xa186, 0x0014, 0x0040,
-+	0x9db1, 0xa186, 0x0027, 0x0040, 0x9db1, 0x1078, 0x7773, 0x0078,
-+	0x9db7, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c,
-+	0x037e, 0x1078, 0xa495, 0x603f, 0x0000, 0x2019, 0x000b, 0x1078,
-+	0x9dc7, 0x601f, 0x0006, 0x6003, 0x0007, 0x037f, 0x007c, 0x127e,
-+	0x037e, 0x2091, 0x8000, 0x087e, 0x2c40, 0x097e, 0x2049, 0x0000,
-+	0x1078, 0x7246, 0x097f, 0x087f, 0x00c0, 0x9e02, 0x077e, 0x2c38,
-+	0x1078, 0x72f3, 0x077f, 0x00c0, 0x9e02, 0x6000, 0xa086, 0x0000,
-+	0x0040, 0x9e02, 0x601c, 0xa086, 0x0007, 0x0040, 0x9e02, 0x0d7e,
-+	0x6000, 0xa086, 0x0004, 0x00c0, 0x9df3, 0x1078, 0xa495, 0x601f,
-+	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-+	0x9dfb, 0x1078, 0xa1ca, 0x0d7f, 0x6013, 0x0000, 0x1078, 0xa495,
-+	0x601f, 0x0007, 0x037f, 0x127f, 0x007c, 0x0f7e, 0x0c7e, 0x037e,
-+	0x157e, 0x2079, 0xab80, 0x7938, 0x783c, 0x1078, 0x254d, 0x00c0,
-+	0x9e49, 0x017e, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x9e49, 0x017f,
-+	0x027f, 0x027e, 0x017e, 0x2019, 0x0029, 0x1078, 0x73d0, 0x1078,
-+	0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x077f, 0x017f,
-+	0x077e, 0x2039, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x1078, 0x47e9,
-+	0x027e, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040,
-+	0x9e3d, 0xa286, 0x0004, 0x00c0, 0x9e40, 0x62a0, 0x1078, 0x2942,
-+	0x027f, 0x017f, 0x1078, 0x42f8, 0x6612, 0x6516, 0xa006, 0x0078,
-+	0x9e4b, 0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c,
-+	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x2009, 0xa620, 0x2104, 0xa086,
-+	0x0074, 0x00c0, 0x9eb3, 0x2069, 0xab8e, 0x690c, 0xa182, 0x0100,
-+	0x0048, 0x9ea3, 0x6908, 0xa184, 0x8000, 0x0040, 0x9eaf, 0x6018,
-+	0x2070, 0x7010, 0xa084, 0x00ff, 0x0040, 0x9e72, 0x7000, 0xd0f4,
-+	0x0040, 0x9e76, 0xa184, 0x0800, 0x0040, 0x9eaf, 0x6910, 0xa18a,
-+	0x0001, 0x0048, 0x9ea7, 0x6914, 0x2069, 0xabae, 0x6904, 0x81ff,
-+	0x00c0, 0x9e9b, 0x690c, 0xa182, 0x0100, 0x0048, 0x9ea3, 0x6908,
-+	0x81ff, 0x00c0, 0x9e9f, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9ea7,
-+	0x6918, 0xa18a, 0x0001, 0x0048, 0x9eaf, 0x0078, 0x9eb9, 0x6013,
-+	0x0100, 0x0078, 0x9eb5, 0x6013, 0x0300, 0x0078, 0x9eb5, 0x6013,
-+	0x0500, 0x0078, 0x9eb5, 0x6013, 0x0700, 0x0078, 0x9eb5, 0x6013,
-+	0x0900, 0x0078, 0x9eb5, 0x6013, 0x0b00, 0x0078, 0x9eb5, 0x6013,
-+	0x0f00, 0x0078, 0x9eb5, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078,
-+	0x9eba, 0xa006, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e,
-+	0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394,
-+	0x00ff, 0xa286, 0x0006, 0x0040, 0x9ee3, 0xa286, 0x0004, 0x0040,
-+	0x9ee3, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9ee3,
-+	0xa286, 0x0004, 0x0040, 0x9ee3, 0x0c7e, 0x2d60, 0x1078, 0x45d6,
-+	0x0c7f, 0x0078, 0x9f1e, 0x2011, 0xab96, 0xad98, 0x000a, 0x20a9,
-+	0x0004, 0x1078, 0x80de, 0x00c0, 0x9f1f, 0x2011, 0xab9a, 0xad98,
-+	0x0006, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f1f, 0x047e,
-+	0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xa653,
-+	0x210c, 0xd1a4, 0x0040, 0x9f0b, 0x2009, 0x0029, 0x1078, 0xa21d,
-+	0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e,
-+	0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f,
-+	0x2001, 0x0007, 0x1078, 0x4535, 0x017f, 0x047f, 0xa006, 0x157f,
-+	0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xab8e,
-+	0x6800, 0xa086, 0x0800, 0x0040, 0x9f31, 0x6013, 0x0000, 0x0078,
-+	0x9f32, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e,
-+	0x037e, 0x157e, 0x2079, 0xab8c, 0x7930, 0x7834, 0x1078, 0x254d,
-+	0x00c0, 0x9f58, 0x1078, 0x45c4, 0x00c0, 0x9f58, 0x2011, 0xab90,
-+	0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f58,
-+	0x2011, 0xab94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x80de,
-+	0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e,
-+	0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0xab83, 0x2204,
-+	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9f84, 0x1078, 0x45c4,
-+	0x00c0, 0x9f84, 0x2011, 0xab96, 0xac98, 0x000a, 0x20a9, 0x0004,
-+	0x1078, 0x80de, 0x00c0, 0x9f84, 0x2011, 0xab9a, 0xac98, 0x0006,
-+	0x20a9, 0x0004, 0x1078, 0x80de, 0x157f, 0x037f, 0x027f, 0x017f,
-+	0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e,
-+	0x057e, 0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2029,
-+	0xa8ba, 0x252c, 0x2021, 0xa8c0, 0x2424, 0x2061, 0xad00, 0x2071,
-+	0xa600, 0x7648, 0x7064, 0x81ff, 0x0040, 0x9fb2, 0x007e, 0xa186,
-+	0xa9b3, 0x007f, 0x0040, 0x9fb2, 0x8001, 0xa602, 0x00c8, 0xa01c,
-+	0x0078, 0x9fb5, 0xa606, 0x0040, 0xa01c, 0x2100, 0xac06, 0x0040,
-+	0xa012, 0x1078, 0xa242, 0x0040, 0xa012, 0x671c, 0xa786, 0x0001,
-+	0x0040, 0xa037, 0xa786, 0x0004, 0x0040, 0xa037, 0xa786, 0x0007,
-+	0x0040, 0xa012, 0x2500, 0xac06, 0x0040, 0xa012, 0x2400, 0xac06,
-+	0x0040, 0xa012, 0x1078, 0xa256, 0x00c0, 0xa012, 0x88ff, 0x0040,
-+	0x9fdd, 0x6020, 0xa906, 0x00c0, 0xa012, 0x0d7e, 0x6000, 0xa086,
-+	0x0004, 0x00c0, 0x9fe7, 0x017e, 0x1078, 0x1757, 0x017f, 0xa786,
-+	0x0008, 0x00c0, 0x9ff6, 0x1078, 0x8f00, 0x00c0, 0x9ff6, 0x1078,
-+	0x7c83, 0x0d7f, 0x1078, 0x8ec6, 0x0078, 0xa012, 0x6010, 0x2068,
-+	0x1078, 0x8d06, 0x0040, 0xa00f, 0xa786, 0x0003, 0x00c0, 0xa026,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa4e2, 0x017e,
-+	0x1078, 0x8f7d, 0x1078, 0x4a73, 0x017f, 0x1078, 0x8eb9, 0x0d7f,
-+	0x1078, 0x8ec6, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02,
-+	0x00c8, 0xa01c, 0x0078, 0x9f9f, 0x127f, 0x027f, 0x047f, 0x057f,
-+	0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006,
-+	0x00c0, 0xa000, 0xa386, 0x0005, 0x0040, 0xa034, 0x1078, 0xa4e2,
-+	0x1078, 0xa1ca, 0x0078, 0xa00f, 0x0d7f, 0x0078, 0xa012, 0x1078,
-+	0xa256, 0x00c0, 0xa012, 0x81ff, 0x0040, 0xa012, 0xa180, 0x0001,
-+	0x2004, 0xa086, 0x0018, 0x0040, 0xa04c, 0xa180, 0x0001, 0x2004,
-+	0xa086, 0x002d, 0x00c0, 0xa012, 0x6000, 0xa086, 0x0002, 0x00c0,
-+	0xa012, 0x1078, 0x8eec, 0x0040, 0xa05d, 0x1078, 0x8f00, 0x00c0,
-+	0xa012, 0x1078, 0x7c83, 0x0078, 0xa065, 0x1078, 0x28a6, 0x1078,
-+	0x8f00, 0x00c0, 0xa065, 0x1078, 0x7c83, 0x1078, 0x8ec6, 0x0078,
-+	0xa012, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0xa006, 0x1078,
-+	0xa1e6, 0x017f, 0x0040, 0xa079, 0x601c, 0xa084, 0x000f, 0x1079,
-+	0xa07c, 0x0e7f, 0x0c7f, 0x007c, 0xa084, 0xa084, 0xa084, 0xa084,
-+	0xa084, 0xa084, 0xa086, 0xa084, 0xa006, 0x007c, 0x047e, 0x017e,
-+	0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00,
-+	0x2009, 0x0020, 0x1078, 0xa21d, 0x017f, 0x047f, 0x037e, 0x2019,
-+	0x0002, 0x1078, 0x9dc7, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001,
-+	0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9,
-+	0x0004, 0x2019, 0xa605, 0x2011, 0xab96, 0x1078, 0x80de, 0x037f,
-+	0x027f, 0x017f, 0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e,
-+	0x087e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740,
-+	0x2061, 0xad00, 0x2079, 0x0001, 0x8fff, 0x0040, 0xa11d, 0x2071,
-+	0xa600, 0x7648, 0x7064, 0x8001, 0xa602, 0x00c8, 0xa11d, 0x88ff,
-+	0x0040, 0xa0d8, 0x2800, 0xac06, 0x00c0, 0xa113, 0x2079, 0x0000,
-+	0x1078, 0xa242, 0x0040, 0xa113, 0x2400, 0xac06, 0x0040, 0xa113,
-+	0x671c, 0xa786, 0x0006, 0x00c0, 0xa113, 0xa786, 0x0007, 0x0040,
-+	0xa113, 0x88ff, 0x00c0, 0xa0f7, 0x6018, 0xa206, 0x00c0, 0xa113,
-+	0x85ff, 0x0040, 0xa0f7, 0x6020, 0xa106, 0x00c0, 0xa113, 0x0d7e,
-+	0x6000, 0xa086, 0x0004, 0x00c0, 0xa103, 0x1078, 0xa495, 0x601f,
-+	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-+	0xa10d, 0x047e, 0x1078, 0xa1ca, 0x047f, 0x0d7f, 0x1078, 0x8ec6,
-+	0x88ff, 0x00c0, 0xa127, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004,
-+	0xac02, 0x00c8, 0xa11d, 0x0078, 0xa0c4, 0xa006, 0x127f, 0x027f,
-+	0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5,
-+	0x0001, 0x0078, 0xa11e, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000,
-+	0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049,
-+	0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
-+	0x72f3, 0x1078, 0xa0b5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e,
-+	0x057e, 0x077e, 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f,
-+	0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa16e,
-+	0x2c10, 0x057e, 0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001,
-+	0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039,
-+	0x0000, 0x1078, 0x72f3, 0x1078, 0xa0b5, 0x057f, 0x037f, 0x017f,
-+	0x8108, 0x00f0, 0xa152, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
-+	0x027f, 0x007c, 0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000,
-+	0x2029, 0x0001, 0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078,
-+	0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x72f3, 0x2c20,
-+	0x1078, 0xa0b5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e,
-+	0x077e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000,
-+	0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa1be, 0x2c10, 0x087e,
-+	0x2041, 0x0000, 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa472,
-+	0x047f, 0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f,
-+	0x2039, 0x0000, 0x1078, 0x72f3, 0x1078, 0xa0b5, 0x037f, 0x017f,
-+	0x8108, 0x00f0, 0xa1a0, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
-+	0x027f, 0x007c, 0x017e, 0x0f7e, 0xad82, 0xcd00, 0x0048, 0xa1e3,
-+	0xad82, 0xffff, 0x00c8, 0xa1e3, 0x6800, 0xa07d, 0x0040, 0xa1e0,
-+	0x6803, 0x0000, 0x6b52, 0x1078, 0x4a73, 0x2f68, 0x0078, 0xa1d4,
-+	0x6b52, 0x1078, 0x4a73, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e,
-+	0x037e, 0x2061, 0xad00, 0xa005, 0x00c0, 0xa1f6, 0x2071, 0xa600,
-+	0x7448, 0x7064, 0x8001, 0xa402, 0x00c8, 0xa218, 0x2100, 0xac06,
-+	0x0040, 0xa20a, 0x6000, 0xa086, 0x0000, 0x0040, 0xa20a, 0x6008,
-+	0xa206, 0x00c0, 0xa20a, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406,
-+	0x0040, 0xa214, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02,
-+	0x00c8, 0xa218, 0x0078, 0xa1f6, 0xa085, 0x0001, 0x0078, 0xa219,
-+	0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, 0x007e, 0x1078,
-+	0x138b, 0x007f, 0x1040, 0x1332, 0x6837, 0x010d, 0x685e, 0x027e,
-+	0x2010, 0x1078, 0x8cf2, 0x2001, 0x0000, 0x0040, 0xa233, 0x2200,
-+	0xa080, 0x0008, 0x2004, 0x027f, 0x684a, 0x6956, 0x6c46, 0x684f,
-+	0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x1078, 0x4a73,
-+	0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0xa255, 0xa786,
-+	0x0001, 0x0040, 0xa255, 0xa786, 0x000a, 0x0040, 0xa255, 0xa786,
-+	0x0009, 0x0040, 0xa255, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018,
-+	0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x017e, 0x6004, 0xa08e,
-+	0x001e, 0x00c0, 0xa277, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
-+	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005, 0x2001,
-+	0xa8a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x017f,
-+	0x007c, 0x0005, 0x0005, 0x007c, 0x6024, 0xd0e4, 0x0040, 0xa28d,
-+	0xd0cc, 0x0040, 0xa287, 0x1078, 0x8fbf, 0x0078, 0xa28d, 0x1078,
-+	0xa495, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x007c, 0xa280, 0x0007,
-+	0x2004, 0xa084, 0x000f, 0x0079, 0xa295, 0xa29e, 0xa29e, 0xa29e,
-+	0xa2a0, 0xa29e, 0xa2a0, 0xa2a0, 0xa29e, 0xa2a0, 0xa006, 0x007c,
-+	0xa085, 0x0001, 0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
-+	0x0079, 0xa2aa, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3,
-+	0xa2be, 0xa2b3, 0xa2b3, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013,
-+	0x2a00, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x007c, 0x0c7e, 0x2260,
-+	0x1078, 0xa495, 0x603f, 0x0000, 0x6024, 0xc0f4, 0xc0cc, 0x6026,
-+	0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007, 0x00c0, 0xa31f, 0x6810,
-+	0xa005, 0x0040, 0xa2dc, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x00c0,
-+	0xa2dc, 0x0d7f, 0x0078, 0xa2b3, 0x6007, 0x003a, 0x6003, 0x0001,
-+	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100, 0xa186,
-+	0x0002, 0x00c0, 0xa3ad, 0x6010, 0xa005, 0x00c0, 0xa2f6, 0x6000,
-+	0xa086, 0x0007, 0x10c0, 0x1332, 0x0078, 0xa3ad, 0xa08c, 0xf000,
-+	0x00c0, 0xa302, 0x0078, 0xa302, 0x2068, 0x6800, 0xa005, 0x00c0,
-+	0xa2fc, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086,
-+	0x0002, 0x00c0, 0xa31b, 0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4,
-+	0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043, 0x1078,
-+	0x9c1e, 0x0078, 0xa3ad, 0x2009, 0x0041, 0x0078, 0xa3a7, 0xa186,
-+	0x0005, 0x00c0, 0xa366, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
-+	0x00c0, 0xa32d, 0x0d7f, 0x0078, 0xa2b3, 0xd0b4, 0x0040, 0xa335,
-+	0xd0fc, 0x1040, 0x1332, 0x0078, 0xa2cf, 0x6007, 0x003a, 0x6003,
-+	0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100,
-+	0xa186, 0x0002, 0x0040, 0xa348, 0xa186, 0x0004, 0x00c0, 0xa3ad,
-+	0x2071, 0xa8e7, 0x7000, 0xa086, 0x0003, 0x00c0, 0xa355, 0x7004,
-+	0xac06, 0x00c0, 0xa355, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013,
-+	0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc,
-+	0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078, 0xa3a7, 0x037e, 0x0d7e,
-+	0x0d7e, 0x1078, 0x138b, 0x037f, 0x1040, 0x1332, 0x6837, 0x010d,
-+	0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857,
-+	0x0045, 0x2c00, 0x6862, 0x6034, 0x6872, 0x2360, 0x6024, 0xc0dd,
-+	0x6026, 0x6018, 0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007,
-+	0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000, 0x6d6a, 0x6e66, 0x686f,
-+	0x0001, 0x1078, 0x4a73, 0x2019, 0x0045, 0x6008, 0x2068, 0x1078,
-+	0x9dc7, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, 0x6017,
-+	0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f, 0x0078, 0xa3ae, 0x603f,
-+	0x0000, 0x6003, 0x0007, 0x1078, 0x9c1e, 0x0c7f, 0x0d7f, 0x007c,
-+	0xa186, 0x0013, 0x00c0, 0xa3ba, 0x6004, 0xa082, 0x0085, 0x2008,
-+	0x0079, 0xa3d4, 0xa186, 0x0027, 0x00c0, 0xa3cd, 0x1078, 0x61cd,
-+	0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019, 0x0004, 0x1078, 0xa1ca,
-+	0x0d7f, 0x037f, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0014, 0x0040,
-+	0xa3be, 0x1078, 0x7773, 0x007c, 0xa3dd, 0xa3db, 0xa3db, 0xa3db,
-+	0xa3db, 0xa3db, 0xa3dd, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6003,
-+	0x000c, 0x1078, 0x62d1, 0x007c, 0xa182, 0x008c, 0x00c8, 0xa3ee,
-+	0xa182, 0x0085, 0x0048, 0xa3ee, 0x0079, 0xa3f1, 0x1078, 0x7773,
-+	0x007c, 0xa3f8, 0xa3f8, 0xa3f8, 0xa3f8, 0xa3fa, 0xa419, 0xa3f8,
-+	0x1078, 0x1332, 0x0d7e, 0x2c68, 0x1078, 0x76c7, 0x0040, 0xa414,
-+	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xab8e, 0x210c, 0x6136,
-+	0x2009, 0xab8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a,
-+	0x601f, 0x0004, 0x1078, 0x5d8a, 0x2d60, 0x1078, 0x772d, 0x0d7f,
-+	0x007c, 0x1078, 0x772d, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000,
-+	0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa08c, 0xf000, 0x0040, 0xa471,
-+	0xa080, 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa471, 0x2001, 0xa672,
-+	0x2004, 0xd0ec, 0x0040, 0xa471, 0x6003, 0x0002, 0x6024, 0xc0e5,
-+	0x6026, 0xd1ac, 0x0040, 0xa44f, 0x0f7e, 0x2c78, 0x1078, 0x495f,
-+	0x0f7f, 0x0040, 0xa44f, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x2009,
-+	0xa672, 0x210c, 0xd1f4, 0x00c0, 0xa46f, 0x0078, 0xa461, 0x2009,
-+	0xa672, 0x210c, 0xd1f4, 0x0040, 0xa45b, 0x6024, 0xc0e4, 0x6026,
-+	0xa006, 0x0078, 0xa471, 0x2001, 0xa8a4, 0x200c, 0x8103, 0xa100,
-+	0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa46c,
-+	0xa088, 0x0003, 0x0078, 0xa464, 0x2c0a, 0x600f, 0x0000, 0xa085,
-+	0x0001, 0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b,
-+	0x2e04, 0x2060, 0x8cff, 0x0040, 0xa491, 0x84ff, 0x00c0, 0xa484,
-+	0x6020, 0xa106, 0x00c0, 0xa48c, 0x600c, 0x2072, 0x1078, 0x5bc1,
-+	0x1078, 0x772d, 0x0078, 0xa48e, 0xacf0, 0x0003, 0x2e64, 0x0078,
-+	0xa47a, 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8,
-+	0x002b, 0x2d04, 0xa005, 0x0040, 0xa4a7, 0xac06, 0x0040, 0xa4a5,
-+	0x2d04, 0xa0e8, 0x0003, 0x0078, 0xa499, 0x600c, 0x206a, 0x0d7f,
-+	0x007c, 0x027e, 0x037e, 0x157e, 0x2011, 0xa626, 0x2204, 0xa084,
-+	0x00ff, 0x2019, 0xab8e, 0x2334, 0xa636, 0x00c0, 0xa4d5, 0x8318,
-+	0x2334, 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa4d5, 0x2011,
-+	0xab90, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de,
-+	0x00c0, 0xa4d5, 0x2011, 0xab94, 0x6018, 0xa098, 0x0006, 0x20a9,
-+	0x0004, 0x1078, 0x80de, 0x00c0, 0xa4d5, 0x157f, 0x037f, 0x027f,
-+	0x007c, 0x0e7e, 0x2071, 0xa600, 0x1078, 0x42b8, 0x1078, 0x2677,
-+	0x0e7f, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040,
-+	0xa4eb, 0x1078, 0xa4ed, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852,
-+	0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
-+	0x017e, 0x127e, 0x2091, 0x8000, 0x2029, 0xa8ba, 0x252c, 0x2021,
-+	0xa8c0, 0x2424, 0x2061, 0xad00, 0x2071, 0xa600, 0x7648, 0x7064,
-+	0xa606, 0x0040, 0xa545, 0x671c, 0xa786, 0x0001, 0x0040, 0xa514,
-+	0xa786, 0x0008, 0x00c0, 0xa53b, 0x2500, 0xac06, 0x0040, 0xa53b,
-+	0x2400, 0xac06, 0x0040, 0xa53b, 0x1078, 0xa242, 0x0040, 0xa53b,
-+	0x1078, 0xa256, 0x00c0, 0xa53b, 0x6000, 0xa086, 0x0004, 0x00c0,
-+	0xa52d, 0x017e, 0x1078, 0x1757, 0x017f, 0x1078, 0x8eec, 0x00c0,
-+	0xa533, 0x1078, 0x28a6, 0x1078, 0x8f00, 0x00c0, 0xa539, 0x1078,
-+	0x7c83, 0x1078, 0x8ec6, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004,
-+	0xac02, 0x00c8, 0xa545, 0x0078, 0xa504, 0x127f, 0x017f, 0x027f,
-+	0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e,
-+	0x007e, 0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa640, 0xd5a4,
-+	0x0040, 0xa55d, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa563,
-+	0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0xa579, 0x2500, 0xa084,
-+	0x0007, 0xa08e, 0x0003, 0x0040, 0xa579, 0xa08e, 0x0004, 0x0040,
-+	0xa579, 0xa08e, 0x0005, 0x0040, 0xa579, 0x2071, 0xa64a, 0x1078,
-+	0xa5ba, 0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e,
-+	0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa640, 0xd5a4, 0x0040,
-+	0xa58c, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa592, 0x7030,
-+	0x8000, 0x7032, 0xd5ac, 0x0040, 0xa5a8, 0x2500, 0xa084, 0x0007,
-+	0xa08e, 0x0003, 0x0040, 0xa5a8, 0xa08e, 0x0004, 0x0040, 0xa5a8,
-+	0xa08e, 0x0005, 0x0040, 0xa5a8, 0x2071, 0xa64a, 0x1078, 0xa5ba,
-+	0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e,
-+	0x2091, 0x8000, 0x2071, 0xa642, 0x1078, 0xa5ba, 0x0e7f, 0x007f,
-+	0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8, 0xa5c3, 0x8e70,
-+	0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071, 0xa640, 0x1078,
-+	0xa5ba, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa644, 0x1078, 0xa5ba,
-+	0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
-+	0xa640, 0x7044, 0x8000, 0x7046, 0x0e7f, 0x007f, 0x127f, 0x007c,
-+	0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
-+	0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
-+	0xa50c
-+};
-+#else
-+/*
-+ *	Firmware Version 1.15.37 (15:36 May 03, 1999)
-+ */
-+static const u_int16_t isp_2100_risc_code[] = {
-+	0x0078, 0x1029, 0x0000, 0x66e6, 0x0000, 0x2043, 0x4f50, 0x5952,
-+	0x4947, 0x4854, 0x2031, 0x3939, 0x3620, 0x514c, 0x4f47, 0x4943,
-+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
-+	0x3231, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-+	0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3135, 0x2020, 0x2020,
-+	0x2400, 0x20c1, 0x0021, 0x20a1, 0x76e6, 0x2009, 0x0000, 0x20a9,
-+	0x071a, 0x41a4, 0x3400, 0x20c9, 0x7bff, 0x2091, 0x2000, 0x2059,
-+	0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x209a, 0x2051, 0x7700,
-+	0x2a70, 0x705b, 0x9600, 0x705f, 0xffff, 0x7057, 0x95f9, 0x7063,
-+	0x0300, 0x1078, 0x127a, 0x20a1, 0x7e00, 0x715c, 0x810d, 0x810d,
-+	0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0007, 0xa112, 0xa00e,
-+	0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0, 0x1058, 0x715c, 0x3400,
-+	0xa102, 0x0040, 0x1068, 0x0048, 0x1068, 0x20a8, 0xa00e, 0x41a4,
-+	0x1078, 0x1241, 0x1078, 0x1366, 0x1078, 0x14eb, 0x1078, 0x19c0,
-+	0x1078, 0x362b, 0x1078, 0x5cac, 0x1078, 0x12f1, 0x1078, 0x2429,
-+	0x1078, 0x3d6e, 0x1078, 0x3b46, 0x1078, 0x45af, 0x1078, 0x1e55,
-+	0x1078, 0x47ef, 0x1078, 0x428f, 0x1078, 0x1d74, 0x1078, 0x1e34,
-+	0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x109d, 0x7820, 0xa086,
-+	0x0002, 0x00c0, 0x109d, 0x7823, 0x4000, 0x0068, 0x1095, 0x781b,
-+	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
-+	0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003,
-+	0x00c0, 0x10bd, 0x1078, 0x2d9c, 0x1078, 0x2451, 0x1078, 0x3dbe,
-+	0x1078, 0x3c31, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
-+	0x10c1, 0x1078, 0x45c7, 0x0078, 0x10a4, 0x1079, 0x10c5, 0x0078,
-+	0x10aa, 0x1078, 0x597e, 0x0078, 0x10b9, 0x10cf, 0x10d0, 0x1143,
-+	0x10cd, 0x11be, 0x123e, 0x123f, 0x1240, 0x1078, 0x12cd, 0x007c,
-+	0x127e, 0x0f7e, 0x2091, 0x8000, 0x1078, 0x2ec1, 0x2079, 0x0100,
-+	0x7844, 0xa005, 0x00c0, 0x1134, 0x2011, 0x3558, 0x1078, 0x4689,
-+	0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010,
-+	0x73b8, 0x1078, 0x2d59, 0x1078, 0x57c9, 0x2011, 0x0004, 0x1078,
-+	0x6a6d, 0x1078, 0x3ae0, 0x70c7, 0x0000, 0x70c3, 0x0000, 0x1078,
-+	0x1137, 0x72bc, 0x2079, 0x7751, 0x7804, 0xd0ac, 0x0040, 0x1101,
-+	0xc295, 0x72be, 0xa296, 0x0004, 0x0040, 0x1122, 0x2011, 0x0001,
-+	0x1078, 0x6a6d, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002,
-+	0x0f7f, 0x1078, 0x214a, 0x2011, 0x0005, 0x1078, 0x58d8, 0x1078,
-+	0x4d96, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f,
-+	0x0078, 0x1136, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002,
-+	0x2011, 0x0005, 0x1078, 0x58d8, 0x1078, 0x4d96, 0x0c7e, 0x2061,
-+	0x0100, 0x60e3, 0x0008, 0x0c7f, 0x0f7f, 0x127f, 0x007c, 0x0c7e,
-+	0x20a9, 0x0082, 0x2009, 0x007e, 0x1078, 0x3834, 0x8108, 0x00f0,
-+	0x113c, 0x0c7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x708c, 0xa086,
-+	0xffff, 0x0040, 0x1151, 0x1078, 0x214a, 0x1078, 0x4d96, 0x0078,
-+	0x11bc, 0x70bc, 0xd09c, 0x0040, 0x1179, 0xd084, 0x0040, 0x1179,
-+	0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
-+	0x0040, 0x1179, 0x70c0, 0xa086, 0xffff, 0x0040, 0x1175, 0x1078,
-+	0x223f, 0x1078, 0x4d96, 0x2011, 0x0001, 0x2019, 0x0000, 0x1078,
-+	0x2277, 0x1078, 0x4d96, 0x0078, 0x11bc, 0x70c4, 0xa005, 0x00c0,
-+	0x11bc, 0x7088, 0xa005, 0x00c0, 0x11bc, 0x2001, 0x7752, 0x2004,
-+	0xd0ac, 0x0040, 0x119f, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
-+	0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x1192, 0x6000, 0xd0ec,
-+	0x00c0, 0x119a, 0x017f, 0x8108, 0x00f0, 0x1189, 0x0c7f, 0x157f,
-+	0x0078, 0x119f, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x11bc, 0x7003,
-+	0x0003, 0x708f, 0xffff, 0x2001, 0x0000, 0x1078, 0x2025, 0x1078,
-+	0x2dd7, 0x2001, 0x7937, 0x2004, 0xa086, 0x0005, 0x00c0, 0x11b4,
-+	0x2011, 0x0000, 0x1078, 0x58d8, 0x2011, 0x0000, 0x1078, 0x58e2,
-+	0x1078, 0x4d96, 0x1078, 0x4e56, 0x127f, 0x007c, 0x017e, 0x0f7e,
-+	0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x7940, 0xa18c, 0x0010,
-+	0x7942, 0x7924, 0xd1b4, 0x0040, 0x11cf, 0x7827, 0x0040, 0xd19c,
-+	0x0040, 0x11d4, 0x7827, 0x0008, 0x007e, 0x037e, 0x157e, 0x7900,
-+	0xa18a, 0x0003, 0x0050, 0x11fa, 0x7954, 0xd1ac, 0x00c0, 0x11fa,
-+	0x2009, 0x00f8, 0x1078, 0x35fa, 0x7843, 0x0090, 0x7843, 0x0010,
-+	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x11f2, 0x7824, 0xd0ac,
-+	0x00c0, 0x122e, 0x00f0, 0x11ea, 0x2001, 0x0001, 0x1078, 0x2025,
-+	0x0078, 0x1237, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0008,
-+	0x00e0, 0x1200, 0x2091, 0x6000, 0x00f0, 0x1200, 0x7853, 0x0400,
-+	0x782f, 0x0000, 0x2009, 0x00f8, 0x1078, 0x35fa, 0x20a9, 0x000e,
-+	0x0005, 0x00f0, 0x1210, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843,
-+	0x0010, 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040,
-+	0x1225, 0x7824, 0xd0ac, 0x00c0, 0x122e, 0x8319, 0x00c0, 0x121b,
-+	0x2001, 0x0001, 0x1078, 0x2025, 0x0078, 0x1235, 0x7828, 0xc09d,
-+	0x782a, 0x7827, 0x0008, 0x7827, 0x0040, 0x7853, 0x0400, 0x157f,
-+	0x037f, 0x007f, 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c,
-+	0x007c, 0x2a70, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
-+	0x124d, 0x704f, 0xffff, 0x0078, 0x124f, 0x704f, 0x0000, 0x7053,
-+	0xffff, 0x7067, 0x0000, 0x706b, 0x0000, 0x2061, 0x7920, 0x6003,
-+	0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
-+	0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
-+	0x7928, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
-+	0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
-+	0x0000, 0x007c, 0x1078, 0x12a0, 0x2011, 0x0000, 0x81ff, 0x0040,
-+	0x129f, 0xa186, 0x0001, 0x00c0, 0x128f, 0x705f, 0x8fff, 0x7057,
-+	0x8601, 0x7063, 0x0100, 0x705b, 0x8600, 0x0078, 0x129d, 0xa186,
-+	0x0002, 0x00c0, 0x1297, 0x2011, 0x0000, 0x0078, 0x129d, 0xa186,
-+	0x0005, 0x00c0, 0x129d, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c,
-+	0x2009, 0x0000, 0x2011, 0x0000, 0x1078, 0x12c7, 0x2019, 0xaaaa,
-+	0x2061, 0xffff, 0x2362, 0x2c24, 0x2061, 0x7fff, 0x2c04, 0xa406,
-+	0x0040, 0x12b5, 0xc18d, 0x0078, 0x12c2, 0xc185, 0x2011, 0x0001,
-+	0x1078, 0x12c7, 0x2061, 0xffff, 0x2362, 0x2c04, 0xa306, 0x00c0,
-+	0x12c2, 0xc195, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c, 0x3800,
-+	0xa084, 0xfffc, 0xa205, 0x20c0, 0x007c, 0x2091, 0x8000, 0x0068,
-+	0x12cf, 0x007e, 0x017e, 0x2079, 0x0000, 0x7818, 0xa084, 0x0000,
-+	0x00c0, 0x12d5, 0x017f, 0x792e, 0x007f, 0x782a, 0x007f, 0x7826,
-+	0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000,
-+	0x2091, 0x4080, 0x2079, 0x7700, 0x7803, 0x0005, 0x0078, 0x12ee,
-+	0x007c, 0x2071, 0x7700, 0x7158, 0x712e, 0x2021, 0x0001, 0xa190,
-+	0x002d, 0xa298, 0x002d, 0x0048, 0x1307, 0x705c, 0xa302, 0x00c8,
-+	0x1307, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, 0x12f9, 0x200b,
-+	0x0000, 0x749e, 0x74a2, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
-+	0x2071, 0x7700, 0x70a0, 0xa0ea, 0x0010, 0x00c8, 0x131a, 0xa06e,
-+	0x0078, 0x1324, 0x8001, 0x70a2, 0x702c, 0x2068, 0x2d04, 0x702e,
-+	0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e,
-+	0x2071, 0x7700, 0x127e, 0x2091, 0x8000, 0x70a0, 0x8001, 0x00c8,
-+	0x1334, 0xa06e, 0x0078, 0x133d, 0x70a2, 0x702c, 0x2068, 0x2d04,
-+	0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c,
-+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x702c, 0x206a,
-+	0x2d00, 0x702e, 0x70a0, 0x8000, 0x70a2, 0x127f, 0x0e7f, 0x007c,
-+	0x8dff, 0x0040, 0x135c, 0x6804, 0x6807, 0x0000, 0x007e, 0x1078,
-+	0x1340, 0x0d7f, 0x0078, 0x1350, 0x007c, 0x0e7e, 0x2071, 0x7700,
-+	0x70a0, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
-+	0x7959, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071,
-+	0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, 0x007c, 0x0e7e,
-+	0x2270, 0x700b, 0x0000, 0x2071, 0x7959, 0x7018, 0xa088, 0x7962,
-+	0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0,
-+	0x138f, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f,
-+	0x007c, 0x0e7e, 0x2071, 0x7959, 0x7004, 0xa005, 0x00c0, 0x139e,
-+	0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f, 0x007c,
-+	0x7000, 0x0079, 0x13a3, 0x13a7, 0x1411, 0x142e, 0x142e, 0x7018,
-+	0x711c, 0xa106, 0x00c0, 0x13af, 0x7007, 0x0000, 0x007c, 0x0d7e,
-+	0xa180, 0x7962, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
-+	0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c,
-+	0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804,
-+	0x0d7f, 0xd084, 0x0040, 0x13d1, 0x7007, 0x0001, 0x1078, 0x13d6,
-+	0x007c, 0x7007, 0x0002, 0x1078, 0x13ec, 0x007c, 0x017e, 0x027e,
-+	0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13e1, 0x2110,
-+	0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
-+	0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e,
-+	0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c,
-+	0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1400, 0x2110, 0xa006,
-+	0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
-+	0x0001, 0x3300, 0x7016, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f,
-+	0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0x77e5, 0x20a1, 0x0018,
-+	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
-+	0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b,
-+	0x77e0, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
-+	0x157e, 0x2001, 0x7814, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
-+	0x2001, 0x7815, 0x20ac, 0x53a6, 0x2099, 0x7816, 0x20a1, 0x0018,
-+	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
-+	0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b,
-+	0x7811, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
-+	0x2071, 0x7959, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
-+	0xd1fc, 0x0040, 0x1471, 0xa18c, 0x0700, 0x0040, 0x146e, 0x7008,
-+	0xa080, 0x0002, 0x2003, 0x0200, 0x0078, 0x1471, 0x7004, 0x1079,
-+	0x1475, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13a0, 0x147d, 0x149f,
-+	0x14b9, 0x14e2, 0x147b, 0x0078, 0x147b, 0x137e, 0x147e, 0x157e,
-+	0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8,
-+	0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005,
-+	0x0040, 0x14a6, 0x1078, 0x13d6, 0x007c, 0x7008, 0xa080, 0x0002,
-+	0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x13a0, 0x007c, 0x700c,
-+	0xa005, 0x0040, 0x14a6, 0x1078, 0x13ec, 0x007c, 0x0d7e, 0x7008,
-+	0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c,
-+	0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x13a0,
-+	0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x77e3, 0x2004, 0xa080,
-+	0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020,
-+	0x53a5, 0x2001, 0x77e5, 0x2004, 0xd0bc, 0x0040, 0x14d8, 0x2001,
-+	0x77ee, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5,
-+	0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x3e67, 0x1078,
-+	0x13a0, 0x007c, 0x2001, 0x7813, 0x2003, 0x0100, 0x7007, 0x0000,
-+	0x1078, 0x13a0, 0x007c, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030,
-+	0x2071, 0x796a, 0x7003, 0x0000, 0x700f, 0x7970, 0x7013, 0x7970,
-+	0x780f, 0x0070, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079,
-+	0x1501, 0x1509, 0x154f, 0x1509, 0x1509, 0x1509, 0x1534, 0x1518,
-+	0x150d, 0xa085, 0x0001, 0x0078, 0x1569, 0x684c, 0xd0bc, 0x0040,
-+	0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x1557,
-+	0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1509, 0x684c, 0xd0bc,
-+	0x0040, 0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a,
-+	0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004,
-+	0x6832, 0x6858, 0x0078, 0x155f, 0xa18c, 0x00ff, 0xa186, 0x0015,
-+	0x00c0, 0x1509, 0x684c, 0xd0ac, 0x0040, 0x1509, 0x6804, 0x681a,
-+	0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004,
-+	0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x155f, 0x684c,
-+	0xd0ac, 0x0040, 0x1509, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c,
-+	0x000f, 0xa188, 0x1c7e, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826,
-+	0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980,
-+	0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a,
-+	0x2004, 0x82ff, 0x0040, 0x1584, 0xa280, 0x0004, 0x0d7e, 0x206c,
-+	0x684c, 0xd0dc, 0x00c0, 0x1580, 0x1078, 0x14fc, 0x10c0, 0x12cd,
-+	0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e,
-+	0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0,
-+	0x1598, 0x7206, 0x2001, 0x15ac, 0x007e, 0x2260, 0x0078, 0x16c4,
-+	0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
-+	0x798b, 0x0048, 0x15a5, 0x2009, 0x7970, 0x710e, 0x7000, 0xa005,
-+	0x00c0, 0x15ac, 0x1078, 0x16ad, 0x127f, 0x007c, 0x127e, 0x027e,
-+	0x037e, 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f,
-+	0x027f, 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e,
-+	0xa005, 0x0040, 0x1600, 0x6808, 0xa005, 0x0040, 0x1666, 0x7000,
-+	0xa005, 0x00c0, 0x15cd, 0x0078, 0x15fa, 0x700c, 0x7110, 0xa106,
-+	0x00c0, 0x166a, 0x7004, 0xa406, 0x00c0, 0x15fa, 0x2001, 0x0005,
-+	0x2004, 0xd08c, 0x0040, 0x15e3, 0x047e, 0x1078, 0x1785, 0x047f,
-+	0x2460, 0x0078, 0x15c3, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0,
-+	0x15d6, 0x7804, 0xa084, 0x6000, 0x0040, 0x15f4, 0xa086, 0x6000,
-+	0x0040, 0x15f4, 0x0078, 0x15d6, 0x7803, 0x0004, 0x7003, 0x0000,
-+	0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5d41, 0x0078, 0x166a,
-+	0x6808, 0xa005, 0x0040, 0x1666, 0x7000, 0xa005, 0x00c0, 0x160a,
-+	0x0078, 0x1666, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1613, 0x7004,
-+	0xa406, 0x00c0, 0x1666, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040,
-+	0x1620, 0x047e, 0x1078, 0x1785, 0x047f, 0x2460, 0x0078, 0x1600,
-+	0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x1613, 0x2001, 0x0005,
-+	0x2004, 0xd08c, 0x00c0, 0x1619, 0x7804, 0xa084, 0x6000, 0x0040,
-+	0x1637, 0xa086, 0x6000, 0x0040, 0x1637, 0x0078, 0x1613, 0x7007,
-+	0x0000, 0xa016, 0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x1658,
-+	0xa08e, 0x0002, 0x00c0, 0x1666, 0x0c7e, 0x0e7e, 0x6818, 0x2060,
-+	0x1078, 0x1c53, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x1654,
-+	0x7308, 0x720c, 0x0078, 0x1656, 0x7310, 0x7214, 0x0e7f, 0x0c7f,
-+	0x7820, 0xa318, 0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814,
-+	0xa201, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x2009, 0x0048,
-+	0x1078, 0x5d41, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, 0x0e7e,
-+	0x2071, 0x796a, 0x7000, 0xa086, 0x0000, 0x0040, 0x16aa, 0x7004,
-+	0xac06, 0x00c0, 0x169b, 0x2079, 0x0030, 0x7804, 0xd0fc, 0x00c0,
-+	0x1697, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x167d, 0x7803,
-+	0x0004, 0x7804, 0xd0ac, 0x00c0, 0x1689, 0x7803, 0x0002, 0x7803,
-+	0x0009, 0x7003, 0x0003, 0x7007, 0x0000, 0x0078, 0x169b, 0x1078,
-+	0x1785, 0x0078, 0x1672, 0x157e, 0x20a9, 0x0009, 0x2009, 0x7970,
-+	0x2104, 0xac06, 0x00c0, 0x16a5, 0x200a, 0xa188, 0x0003, 0x00f0,
-+	0x16a0, 0x157f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, 0x7110, 0xa106,
-+	0x00c0, 0x16b5, 0x7003, 0x0000, 0x007c, 0x2104, 0x7006, 0x2060,
-+	0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0x798b, 0x0048,
-+	0x16c3, 0x2009, 0x7970, 0x7112, 0x8cff, 0x00c0, 0x16cb, 0x1078,
-+	0x1950, 0x0078, 0x16f2, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406,
-+	0x00c0, 0x16d6, 0x682c, 0xa306, 0x0040, 0x16da, 0x1078, 0x1c9e,
-+	0x00c0, 0x16c7, 0x684c, 0xd0f4, 0x00c0, 0x16c7, 0x6824, 0x2050,
-+	0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009,
-+	0x0011, 0x1078, 0x16f3, 0x0040, 0x16f1, 0x2009, 0x0001, 0x1078,
-+	0x16f3, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x1780, 0xa03e, 0x2730,
-+	0x6850, 0xd0fc, 0x00c0, 0x1712, 0x0d7e, 0x2804, 0xac68, 0x2900,
-+	0x0079, 0x1702, 0x1762, 0x1722, 0x1722, 0x1762, 0x1762, 0x175a,
-+	0x1762, 0x1722, 0x1762, 0x1728, 0x1728, 0x1762, 0x1762, 0x1762,
-+	0x1751, 0x1728, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20,
-+	0x0d7e, 0xd99c, 0x0040, 0x1765, 0x2804, 0xac68, 0x6f08, 0x6e0c,
-+	0x0078, 0x1765, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1765,
-+	0x7b0c, 0xd3bc, 0x0040, 0x1749, 0x7004, 0x0e7e, 0x2070, 0x701c,
-+	0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1749, 0x7b08, 0xa39c, 0x0fff,
-+	0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, 0x00c0, 0x1744, 0x6810,
-+	0xa302, 0x0048, 0x1744, 0x6b10, 0x2011, 0x0000, 0x2468, 0x0078,
-+	0x174b, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078,
-+	0x1765, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
-+	0x00c0, 0x1762, 0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x16f3, 0xa00e,
-+	0x0078, 0x1780, 0x0d7f, 0x1078, 0x12cd, 0x7b22, 0x7a26, 0x7d32,
-+	0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f,
-+	0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x2300, 0x6b10,
-+	0xa302, 0x6812, 0x2200, 0x6a14, 0xa203, 0x6816, 0x1078, 0x1c3a,
-+	0x007c, 0x1078, 0x12cd, 0x1078, 0x12cd, 0x127e, 0x2091, 0x2100,
-+	0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
-+	0xa184, 0x0700, 0x00c0, 0x1783, 0xa184, 0x0003, 0xa086, 0x0003,
-+	0x0040, 0x1783, 0x7000, 0x0079, 0x179d, 0x17a5, 0x17a7, 0x187f,
-+	0x18e7, 0x18fe, 0x17a5, 0x17a5, 0x17a5, 0x1078, 0x12cd, 0x8001,
-+	0x7002, 0xa184, 0x0880, 0x00c0, 0x17bc, 0x8aff, 0x0040, 0x181f,
-+	0x2009, 0x0001, 0x1078, 0x16f3, 0x0040, 0x1910, 0x2009, 0x0001,
-+	0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004, 0x7003, 0x0000,
-+	0xd1bc, 0x00c0, 0x1807, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x7820,
-+	0x686e, 0xa31a, 0x7824, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x7820,
-+	0x6910, 0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x037f,
-+	0x027f, 0x7830, 0x681e, 0x7834, 0x6822, 0x1078, 0x1c53, 0x2a00,
-+	0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x6850,
-+	0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a, 0x00c0, 0x17f9, 0x684c,
-+	0xd0e4, 0x0040, 0x17f9, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078,
-+	0x5d41, 0x7808, 0xd0ec, 0x00c0, 0x1803, 0x7803, 0x0009, 0x7003,
-+	0x0004, 0x0078, 0x1910, 0x1078, 0x16ad, 0x0078, 0x1910, 0x057e,
-+	0x7d0c, 0xd5bc, 0x00c0, 0x180e, 0x1078, 0x7692, 0x057f, 0x1078,
-+	0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980,
-+	0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x684c,
-+	0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x1837, 0x7003, 0x0000,
-+	0x6808, 0x8001, 0x680a, 0x00c0, 0x1833, 0x7004, 0x2060, 0x2009,
-+	0x0048, 0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7814,
-+	0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, 0x7814,
-+	0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214,
-+	0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b,
-+	0x1078, 0x197b, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001,
-+	0x7804, 0xd0fc, 0x0040, 0x1858, 0x7803, 0x0002, 0x7803, 0x0004,
-+	0x780f, 0x0070, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
-+	0x1078, 0x5d41, 0x1078, 0x199e, 0x0040, 0x1833, 0x7908, 0xd1ec,
-+	0x00c0, 0x1876, 0x2009, 0x0009, 0x0078, 0x1878, 0x2009, 0x0019,
-+	0x7902, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x8001,
-+	0x7002, 0xd194, 0x0040, 0x1891, 0x7804, 0xd0fc, 0x00c0, 0x178d,
-+	0x8aff, 0x0040, 0x1910, 0x2009, 0x0001, 0x1078, 0x16f3, 0x0078,
-+	0x1910, 0xa184, 0x0880, 0x00c0, 0x189e, 0x8aff, 0x0040, 0x1910,
-+	0x2009, 0x0001, 0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004,
-+	0x7003, 0x0000, 0xd1bc, 0x00c0, 0x18d2, 0x027e, 0x037e, 0x6b28,
-+	0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, 0xac68,
-+	0x6034, 0xd09c, 0x00c0, 0x18c2, 0x6808, 0x2008, 0xa31a, 0x680c,
-+	0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, 0x7816,
-+	0x0078, 0x18ce, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, 0x7810,
-+	0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, 0x0d7f,
-+	0x0078, 0x17c7, 0x057e, 0x7d0c, 0x1078, 0x7692, 0x057f, 0x1078,
-+	0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980,
-+	0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x7803,
-+	0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x18fa, 0x6808,
-+	0x8001, 0x680a, 0x00c0, 0x18fa, 0x7004, 0x2060, 0x2009, 0x0048,
-+	0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7803, 0x0004,
-+	0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0040, 0x18fa,
-+	0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x16c4,
-+	0x017f, 0x007f, 0x127f, 0x007c, 0x1078, 0x1925, 0x20e1, 0x9028,
-+	0x700f, 0x7970, 0x7013, 0x7970, 0x2001, 0x015d, 0x200c, 0x810a,
-+	0x2102, 0x2001, 0x0138, 0x2202, 0x007c, 0x2001, 0x0138, 0x2014,
-+	0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc,
-+	0x00c0, 0x1942, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0,
-+	0x1942, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, 0x1942, 0x8421,
-+	0x00c0, 0x192c, 0x007c, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204,
-+	0xa005, 0x00c0, 0x194f, 0x8109, 0x00c0, 0x1947, 0x007c, 0x007c,
-+	0x1078, 0x1943, 0x0040, 0x1978, 0x7908, 0xd1ec, 0x00c0, 0x1968,
-+	0x1078, 0x199e, 0x0040, 0x1968, 0x7803, 0x0009, 0x7904, 0xd1fc,
-+	0x0040, 0x195e, 0x7803, 0x0006, 0x1078, 0x1943, 0x0040, 0x1978,
-+	0x780c, 0xd0a4, 0x00c0, 0x1978, 0x7007, 0x0000, 0x1078, 0x199e,
-+	0x0040, 0x197a, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x197a,
-+	0x1078, 0x1914, 0x007c, 0x3c00, 0x007e, 0x0e7e, 0x2071, 0x0200,
-+	0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1925, 0x20e1, 0x7000,
-+	0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
-+	0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
-+	0x0138, 0x2202, 0x0e7f, 0x007f, 0x20e0, 0x007c, 0x3c00, 0x007e,
-+	0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x19ab, 0xa085,
-+	0x0001, 0x0078, 0x19bd, 0x2001, 0x020a, 0x81ff, 0x0040, 0x19b6,
-+	0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1, 0x7000,
-+	0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007f, 0x20e0, 0x007c,
-+	0x0e7e, 0x2071, 0x798b, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e,
-+	0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1a42, 0x6934,
-+	0xa184, 0x0007, 0x0079, 0x19d4, 0x19dc, 0x1a2d, 0x19dc, 0x19dc,
-+	0x19dc, 0x1a12, 0x19ef, 0x19de, 0x1078, 0x12cd, 0x684c, 0xd0b4,
-+	0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
-+	0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1a35, 0x6834,
-+	0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x19dc, 0x684c, 0xd0b4,
-+	0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
-+	0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d,
-+	0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958,
-+	0x0078, 0x1a3e, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x1a42,
-+	0x684c, 0xd0b4, 0x0040, 0x1b46, 0x6804, 0x681a, 0xa080, 0x000d,
-+	0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958,
-+	0xa006, 0x682e, 0x682a, 0x0078, 0x1a3e, 0x684c, 0xd0b4, 0x0040,
-+	0x1781, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834,
-+	0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6926, 0x684c,
-+	0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020, 0x7804,
-+	0xd0fc, 0x10c0, 0x1b4a, 0x0e7e, 0x0d7e, 0x2071, 0x798b, 0x7000,
-+	0xa005, 0x00c0, 0x1ac0, 0x0c7e, 0x7206, 0xa280, 0x0004, 0x205c,
-+	0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068, 0x686c,
-+	0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200, 0x781a,
-+	0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68, 0x6824,
-+	0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
-+	0x6908, 0xa184, 0x0007, 0x0040, 0x1a82, 0x017e, 0x2009, 0x0008,
-+	0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081,
-+	0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c,
-+	0x6814, 0xa106, 0x00c0, 0x1a99, 0x6928, 0x6810, 0xa106, 0x0040,
-+	0x1aa6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x1c9e, 0x047f,
-+	0x037f, 0x0040, 0x1aa6, 0x0c7f, 0x0078, 0x1ac0, 0x8aff, 0x00c0,
-+	0x1aae, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1ac0, 0x127e, 0x2091,
-+	0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040,
-+	0x1abd, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x127f, 0x0c7f, 0xa006,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e,
-+	0x037e, 0x027e, 0x8aff, 0x0040, 0x1b3f, 0x700c, 0x7214, 0xa202,
-+	0x7010, 0x7218, 0xa203, 0x0048, 0x1b3e, 0xa03e, 0x2730, 0x6850,
-+	0xd0fc, 0x00c0, 0x1af1, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079,
-+	0x1ae1, 0x1b20, 0x1b01, 0x1b01, 0x1b20, 0x1b20, 0x1b18, 0x1b20,
-+	0x1b01, 0x1b20, 0x1b07, 0x1b07, 0x1b20, 0x1b20, 0x1b20, 0x1b0f,
-+	0x1b07, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c,
-+	0x0040, 0x1b24, 0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078,
-+	0x1b23, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1b23, 0x6b10,
-+	0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1b23, 0x0d7f,
-+	0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1b20,
-+	0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x1aca, 0xa00e, 0x0078, 0x1b3f,
-+	0x0d7f, 0x1078, 0x12cd, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36,
-+	0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300,
-+	0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010,
-+	0xa201, 0x7012, 0x1078, 0x1c3a, 0x0078, 0x1b3f, 0xa006, 0x027f,
-+	0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x12cd,
-+	0x1078, 0x12cd, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e,
-+	0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0x798b, 0x2b68,
-+	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
-+	0x1b48, 0x7000, 0x0079, 0x1b64, 0x1c0b, 0x1b68, 0x1bd8, 0x1c09,
-+	0x8001, 0x7002, 0xd19c, 0x00c0, 0x1b7c, 0x8aff, 0x0040, 0x1b9b,
-+	0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040, 0x1c0b, 0x2009, 0x0001,
-+	0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x7803, 0x0004, 0xd194, 0x0040,
-+	0x1b8c, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1b91, 0x684c,
-+	0xc0f5, 0x684e, 0x0078, 0x1b91, 0x1078, 0x1c53, 0x6850, 0xc0fd,
-+	0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003,
-+	0x0000, 0x0078, 0x1c0b, 0x711c, 0x81ff, 0x0040, 0x1bb1, 0x7918,
-+	0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002,
-+	0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078,
-+	0x1c0b, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079,
-+	0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x7820,
-+	0xd0bc, 0x00c0, 0x1bbf, 0x79c8, 0x007f, 0xa102, 0x78ca, 0x79c4,
-+	0x007f, 0xa102, 0x78c6, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816,
-+	0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1c0b,
-+	0x8001, 0x7002, 0xd194, 0x0040, 0x1bed, 0x7804, 0xd0fc, 0x00c0,
-+	0x1b5a, 0xd19c, 0x00c0, 0x1c07, 0x8aff, 0x0040, 0x1c0b, 0x2009,
-+	0x0001, 0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x027e, 0x037e, 0x6b28,
-+	0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c,
-+	0x00c0, 0x1c00, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1c04,
-+	0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1b8c, 0x0078,
-+	0x1b8c, 0x1078, 0x12cd, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f,
-+	0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x798b, 0x7000,
-+	0xa086, 0x0000, 0x0040, 0x1c37, 0x2079, 0x0020, 0x20e1, 0x9040,
-+	0x7804, 0xd0fc, 0x0040, 0x1c1e, 0x1078, 0x1b4a, 0x7000, 0xa086,
-+	0x0000, 0x00c0, 0x1c1e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
-+	0x1c2d, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f,
-+	0x0f7f, 0x007c, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1c4e, 0x6004,
-+	0xa005, 0x0040, 0x1c50, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f,
-+	0xa080, 0x1c7e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x8a51, 0x007c,
-+	0x2051, 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0,
-+	0x1c6d, 0x2c00, 0xad06, 0x0040, 0x1c62, 0x6000, 0xa005, 0x00c0,
-+	0x1c62, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
-+	0x1c8e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x007c, 0x0000, 0x0011,
-+	0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
-+	0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x1c73,
-+	0x1c6f, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c73, 0x0000, 0x1c7a,
-+	0x1c77, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7a, 0x0000, 0x1c75,
-+	0x1c75, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c75, 0x0000, 0x1c7b,
-+	0x1c7b, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7b, 0x0a7e, 0x097e,
-+	0x087e, 0x6858, 0xa055, 0x0040, 0x1d3f, 0x2d60, 0x6034, 0xa0cc,
-+	0x000f, 0xa9c0, 0x1c7e, 0xa986, 0x0007, 0x0040, 0x1cb7, 0xa986,
-+	0x000e, 0x0040, 0x1cb7, 0xa986, 0x000f, 0x00c0, 0x1cbb, 0x605c,
-+	0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1cc9, 0x0050,
-+	0x1cc3, 0x0078, 0x1d3f, 0x6004, 0xa065, 0x0040, 0x1d3f, 0x0078,
-+	0x1ca6, 0x2804, 0xa005, 0x0040, 0x1ce7, 0xac68, 0xd99c, 0x00c0,
-+	0x1cd7, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1cdb, 0x6810,
-+	0xa422, 0x6814, 0xa31b, 0x0048, 0x1d06, 0x2300, 0xa405, 0x0040,
-+	0x1ced, 0x8a51, 0x0040, 0x1d3f, 0x8840, 0x0078, 0x1cc9, 0x6004,
-+	0xa065, 0x0040, 0x1d3f, 0x0078, 0x1ca6, 0x8a51, 0x0040, 0x1d3f,
-+	0x8840, 0x2804, 0xa005, 0x00c0, 0x1d00, 0x6004, 0xa065, 0x0040,
-+	0x1d3f, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1c7e, 0x2804, 0x2040,
-+	0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1d33, 0x8422, 0x8420,
-+	0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f,
-+	0xd99c, 0x00c0, 0x1d21, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
-+	0xa11b, 0x1048, 0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078,
-+	0x1d2d, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048,
-+	0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22,
-+	0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00,
-+	0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1d44, 0x087f,
-+	0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004,
-+	0xa084, 0x0007, 0x0079, 0x1d4c, 0x1d54, 0x1d55, 0x1d58, 0x1d5b,
-+	0x1d60, 0x1d63, 0x1d68, 0x1d6d, 0x007c, 0x1078, 0x1b4a, 0x007c,
-+	0x1078, 0x1785, 0x007c, 0x1078, 0x1785, 0x1078, 0x1b4a, 0x007c,
-+	0x1078, 0x1456, 0x007c, 0x1078, 0x1b4a, 0x1078, 0x1456, 0x007c,
-+	0x1078, 0x1785, 0x1078, 0x1456, 0x007c, 0x1078, 0x1785, 0x1078,
-+	0x1b4a, 0x1078, 0x1456, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079,
-+	0x0200, 0x2071, 0x7c80, 0x2069, 0x7700, 0x2009, 0x0004, 0x7912,
-+	0x7817, 0x0004, 0x1078, 0x2052, 0x781b, 0x0002, 0x20e1, 0x8700,
-+	0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007,
-+	0x0079, 0x1d92, 0x1db6, 0x1d9a, 0x1d9e, 0x1da2, 0x1da8, 0x1dac,
-+	0x1db0, 0x1db4, 0x1078, 0x4298, 0x0078, 0x1db6, 0x1078, 0x42c7,
-+	0x0078, 0x1db6, 0x1078, 0x4298, 0x1078, 0x42c7, 0x0078, 0x1db6,
-+	0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x0078, 0x1db6,
-+	0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x127f, 0x007c,
-+	0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, 0x1dc2,
-+	0x1078, 0x12cd, 0xa184, 0x0030, 0x0040, 0x1dd3, 0x6a00, 0xa286,
-+	0x0003, 0x00c0, 0x1dcd, 0x1078, 0x12cd, 0x1078, 0x3591, 0x20e1,
-+	0x9010, 0x0078, 0x1ddf, 0xa184, 0x00c0, 0x0040, 0x1dd9, 0x1078,
-+	0x12cd, 0xa184, 0x0300, 0x0040, 0x1ddf, 0x20e1, 0x9020, 0x7932,
-+	0x027f, 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071,
-+	0x7700, 0x7128, 0x2001, 0x7923, 0x2102, 0x2001, 0x792b, 0x2102,
-+	0xa182, 0x0211, 0x00c8, 0x1df8, 0x2009, 0x0008, 0x0078, 0x1e22,
-+	0xa182, 0x0259, 0x00c8, 0x1e00, 0x2009, 0x0007, 0x0078, 0x1e22,
-+	0xa182, 0x02c1, 0x00c8, 0x1e08, 0x2009, 0x0006, 0x0078, 0x1e22,
-+	0xa182, 0x0349, 0x00c8, 0x1e10, 0x2009, 0x0005, 0x0078, 0x1e22,
-+	0xa182, 0x0421, 0x00c8, 0x1e18, 0x2009, 0x0004, 0x0078, 0x1e22,
-+	0xa182, 0x0581, 0x00c8, 0x1e20, 0x2009, 0x0003, 0x0078, 0x1e22,
-+	0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0xa182, 0x0005, 0x00c8,
-+	0x1e2c, 0x7916, 0x0078, 0x1e2e, 0x7817, 0x0004, 0x1078, 0x2052,
-+	0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
-+	0x0100, 0x2071, 0x7700, 0x6024, 0x6026, 0x6033, 0x00ef, 0x60e7,
-+	0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043,
-+	0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0caf, 0x600f,
-+	0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001, 0x772d, 0x2003,
-+	0x0000, 0x2001, 0x772c, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091,
-+	0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0,
-+	0x1e6d, 0xa184, 0x0007, 0x0079, 0x1e73, 0xa195, 0x0004, 0xa284,
-+	0x0007, 0x0079, 0x1e73, 0x1e9f, 0x1e7b, 0x1e7f, 0x1e83, 0x1e89,
-+	0x1e8d, 0x1e93, 0x1e99, 0x1078, 0x4802, 0x0078, 0x1e9f, 0x1078,
-+	0x48f1, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x0078,
-+	0x1e9f, 0x1078, 0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x4802, 0x1078,
-+	0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x1ea4, 0x0078,
-+	0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x1078, 0x1ea4, 0x027f,
-+	0x017f, 0x007f, 0x127f, 0x007c, 0xd1ac, 0x0040, 0x1f58, 0x017e,
-+	0x047e, 0x0c7e, 0x644c, 0x74ba, 0xa48c, 0xff00, 0xa196, 0xff00,
-+	0x0040, 0x1ed3, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040,
-+	0x1ed3, 0x7130, 0xd18c, 0x00c0, 0x1ed3, 0x2011, 0x7752, 0x2214,
-+	0xd2ec, 0x0040, 0x1ec7, 0xc18d, 0x7132, 0x0078, 0x1ed3, 0x6240,
-+	0xa294, 0x0010, 0x0040, 0x1f15, 0x6248, 0xa294, 0xff00, 0xa296,
-+	0xff00, 0x00c0, 0x1f15, 0x037e, 0x73b8, 0x2011, 0x8013, 0x1078,
-+	0x2d59, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0x7752, 0x220c,
-+	0xd1a4, 0x0040, 0x1efd, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100,
-+	0x1078, 0x47d0, 0x2019, 0x000e, 0x1078, 0x75d9, 0xa484, 0x00ff,
-+	0xa080, 0x2329, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006,
-+	0x2009, 0x000e, 0x1078, 0x7641, 0x017f, 0xd1ac, 0x00c0, 0x1f06,
-+	0x2019, 0x0004, 0x1078, 0x2293, 0x0078, 0x1f15, 0x157e, 0x20a9,
-+	0x007f, 0x2009, 0x0000, 0x1078, 0x384c, 0x00c0, 0x1f11, 0x1078,
-+	0x3637, 0x8108, 0x00f0, 0x1f0b, 0x157f, 0x0c7f, 0x047f, 0x6043,
-+	0x0000, 0x2009, 0x00f7, 0x1078, 0x35fa, 0x0f7e, 0x2079, 0x7949,
-+	0x783c, 0xa086, 0x0000, 0x0040, 0x1f2d, 0x6027, 0x0004, 0x783f,
-+	0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003,
-+	0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2, 0x1078, 0x57ee,
-+	0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078, 0x5880, 0x037f,
-+	0x60e3, 0x0000, 0x017f, 0x2001, 0x7700, 0x2014, 0xa296, 0x0004,
-+	0x00c0, 0x1f50, 0xd19c, 0x00c0, 0x1f50, 0x6228, 0xc29d, 0x622a,
-+	0x2003, 0x0001, 0x2001, 0x7720, 0x2003, 0x0000, 0x6027, 0x0020,
-+	0xd194, 0x0040, 0x1ff9, 0x0f7e, 0x2079, 0x7949, 0x783c, 0xa086,
-+	0x0001, 0x00c0, 0x1f7c, 0x017e, 0x6027, 0x0004, 0x783f, 0x0000,
-+	0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000, 0x2079, 0x7936,
-+	0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56,
-+	0x017f, 0x0f7f, 0x0078, 0x1ff9, 0x0f7f, 0x017e, 0x6220, 0xd2b4,
-+	0x0040, 0x1fb1, 0x1078, 0x4706, 0x1078, 0x569c, 0x6027, 0x0004,
-+	0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x1f94,
-+	0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0x7936,
-+	0x6028, 0xa09a, 0x0002, 0x00c8, 0x1fa4, 0x8000, 0x602a, 0x0c7f,
-+	0x1078, 0x568e, 0x0078, 0x1ff8, 0x2019, 0x793f, 0x2304, 0xa065,
-+	0x0040, 0x1fae, 0x2009, 0x0027, 0x1078, 0x5d41, 0x0c7f, 0x0078,
-+	0x1ff8, 0xd2bc, 0x0040, 0x1ff8, 0x1078, 0x4714, 0x6017, 0x0010,
-+	0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
-+	0x0040, 0x1fc6, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e,
-+	0x2061, 0x7936, 0x6044, 0xa09a, 0x0002, 0x00c8, 0x1fe7, 0x8000,
-+	0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, 0x1ff8, 0x1078, 0x470b,
-+	0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x1fe3, 0x6017,
-+	0x0012, 0x0078, 0x1ff8, 0x6017, 0x0016, 0x0078, 0x1ff8, 0x037e,
-+	0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x2019, 0x7945, 0x2304,
-+	0xa065, 0x0040, 0x1ff7, 0x2009, 0x004f, 0x1078, 0x5d41, 0x0c7f,
-+	0x017f, 0xd19c, 0x0040, 0x2021, 0x017e, 0x6028, 0xc09c, 0x602a,
-+	0x2011, 0x0003, 0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2,
-+	0x1078, 0x57ee, 0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078,
-+	0x5880, 0x037f, 0x60e3, 0x0000, 0x1078, 0x76b0, 0x1078, 0x76ce,
-+	0x2001, 0x7700, 0x2003, 0x0004, 0x6027, 0x0008, 0x1078, 0x11be,
-+	0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, 0x007e, 0x017e, 0x027e,
-+	0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x71b0,
-+	0x70b2, 0xa116, 0x0040, 0x204b, 0x81ff, 0x0040, 0x203d, 0x2011,
-+	0x8011, 0x1078, 0x2d59, 0x0078, 0x204b, 0x2011, 0x8012, 0x1078,
-+	0x2d59, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, 0x1078,
-+	0x2293, 0x0c7f, 0x037f, 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f,
-+	0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100,
-+	0xa190, 0x206d, 0x2204, 0x60f2, 0xa192, 0x0005, 0x00c8, 0x2064,
-+	0xa190, 0x2076, 0x0078, 0x2066, 0x2011, 0x207a, 0x2204, 0x60ee,
-+	0x027f, 0x007f, 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840,
-+	0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8,
-+	0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028,
-+	0x2130, 0xa094, 0xff00, 0x00c0, 0x2088, 0x81ff, 0x0040, 0x208c,
-+	0x1078, 0x444b, 0x0078, 0x2093, 0xa080, 0x2329, 0x200c, 0xa18c,
-+	0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x2329, 0x200c, 0xa18c,
-+	0x00ff, 0x007c, 0x20ba, 0x20be, 0x20c2, 0x20c8, 0x20ce, 0x20d4,
-+	0x20da, 0x20e2, 0x20ea, 0x20f0, 0x20f6, 0x20fe, 0x2106, 0x210e,
-+	0x2116, 0x2120, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a,
-+	0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a,
-+	0x212a, 0x212a, 0x107e, 0x007e, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143,
-+	0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1d45, 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d45,
-+	0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45,
-+	0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45,
-+	0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143,
-+	0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
-+	0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143,
-+	0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a,
-+	0x0078, 0x2143, 0x0005, 0x0078, 0x212a, 0xb084, 0x003c, 0x8004,
-+	0x8004, 0x0079, 0x2133, 0x2143, 0x20c0, 0x20c4, 0x20ca, 0x20d0,
-+	0x20d6, 0x20dc, 0x20e4, 0x20ec, 0x20f2, 0x20f8, 0x2100, 0x2108,
-+	0x2110, 0x2118, 0x2122, 0x0008, 0x212d, 0x007f, 0x107f, 0x2091,
-+	0x8001, 0x007c, 0x0c7e, 0x027e, 0x2041, 0x007e, 0x70bc, 0xd09c,
-+	0x0040, 0x2154, 0x2041, 0x007f, 0x2001, 0x010c, 0x203c, 0x727c,
-+	0x82ff, 0x0040, 0x219f, 0x037e, 0x738c, 0xa38e, 0xffff, 0x00c0,
-+	0x2163, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x7dc0, 0x2c04, 0xa38c,
-+	0x0001, 0x0040, 0x2170, 0xa084, 0xff00, 0x8007, 0x0078, 0x2172,
-+	0xa084, 0x00ff, 0xa70e, 0x0040, 0x2194, 0xa08e, 0x00ff, 0x0040,
-+	0x219a, 0x2009, 0x0000, 0x1078, 0x207f, 0x1078, 0x3811, 0x00c0,
-+	0x2197, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x218e,
-+	0x1078, 0x21f1, 0x0040, 0x2197, 0x0078, 0x2194, 0x1078, 0x22f5,
-+	0x1078, 0x2218, 0x0040, 0x2197, 0x8318, 0x0078, 0x2163, 0x738e,
-+	0x0078, 0x219c, 0x708f, 0xffff, 0x037f, 0x0078, 0x21ee, 0xa780,
-+	0x2329, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x708c, 0xa096, 0xffff,
-+	0x0040, 0x21b1, 0xa812, 0x00c8, 0x21c1, 0x708f, 0xffff, 0x0078,
-+	0x21eb, 0x2009, 0x0000, 0x70bc, 0xd09c, 0x0040, 0x21bc, 0xd094,
-+	0x0040, 0x21bc, 0x2009, 0x007e, 0x2100, 0xa802, 0x20a8, 0x0078,
-+	0x21c5, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x157e, 0x017e,
-+	0xa106, 0x0040, 0x21e2, 0x1078, 0x3811, 0x00c0, 0x21eb, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x21dc, 0x1078, 0x21f1,
-+	0x0040, 0x21eb, 0x0078, 0x21e2, 0x1078, 0x22f5, 0x1078, 0x2218,
-+	0x0040, 0x21eb, 0x017f, 0x8108, 0x157f, 0x00f0, 0x21c5, 0x708f,
-+	0xffff, 0x0078, 0x21ee, 0x017f, 0x157f, 0x718e, 0x027f, 0x0c7f,
-+	0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4,
-+	0x0040, 0x2213, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000,
-+	0x1078, 0x37e0, 0x2001, 0x0000, 0x1078, 0x37f4, 0x127e, 0x2091,
-+	0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0004, 0x1078,
-+	0x5d41, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c,
-+	0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040,
-+	0x223a, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
-+	0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000,
-+	0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41,
-+	0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
-+	0x027e, 0x2009, 0x0080, 0x1078, 0x3811, 0x00c0, 0x224d, 0x1078,
-+	0x2250, 0x0040, 0x224d, 0x70c3, 0xffff, 0x027f, 0x0c7f, 0x007c,
-+	0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040,
-+	0x2272, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
-+	0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000,
-+	0x70c4, 0x8000, 0x70c6, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41,
-+	0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
-+	0x0d7e, 0x2009, 0x007f, 0x1078, 0x3811, 0x00c0, 0x2290, 0x2c68,
-+	0x1078, 0x5cb4, 0x0040, 0x2290, 0x2d00, 0x601a, 0x6312, 0x601f,
-+	0x0001, 0x620a, 0x2009, 0x0022, 0x1078, 0x5d41, 0xa085, 0x0001,
-+	0x0d7f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e,
-+	0x1078, 0x4a85, 0x1078, 0x4a35, 0x1078, 0x6219, 0x20a9, 0x007f,
-+	0x2009, 0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x22ab, 0x1078,
-+	0x3a36, 0x1078, 0x3637, 0x017f, 0x8108, 0x00f0, 0x22a2, 0x027f,
-+	0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e,
-+	0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029,
-+	0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f,
-+	0x2e60, 0x1078, 0x3a36, 0x6210, 0x6314, 0x1078, 0x3637, 0x6212,
-+	0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e,
-+	0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x22eb,
-+	0x2071, 0x7700, 0x7088, 0xa005, 0x0040, 0x22e8, 0x8001, 0x708a,
-+	0x007f, 0x0e7f, 0x007c, 0x2071, 0x7700, 0x70c4, 0xa005, 0x0040,
-+	0x22e8, 0x8001, 0x70c6, 0x0078, 0x22e8, 0x6000, 0xc08c, 0x6002,
-+	0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x81ff,
-+	0x00c0, 0x2306, 0x20a9, 0x0001, 0x0078, 0x230a, 0x20a9, 0x007f,
-+	0x2011, 0x0000, 0x027e, 0xa2e0, 0x7820, 0x2c64, 0x8cff, 0x0040,
-+	0x231c, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08,
-+	0x1078, 0x747b, 0x1078, 0x3a36, 0x027f, 0x8210, 0x00f0, 0x230a,
-+	0x027e, 0x027f, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
-+	0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
-+	0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
-+	0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
-+	0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
-+	0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
-+	0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
-+	0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
-+	0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
-+	0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
-+	0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
-+	0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
-+	0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
-+	0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
-+	0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
-+	0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
-+	0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
-+	0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
-+	0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
-+	0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
-+	0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
-+	0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
-+	0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
-+	0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
-+	0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
-+	0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
-+	0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
-+	0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x2071, 0x776d, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016,
-+	0x703a, 0x703e, 0x7033, 0x777d, 0x7037, 0x777d, 0x7007, 0x0001,
-+	0x2061, 0x77bd, 0x6003, 0x0002, 0x007c, 0x0090, 0x2450, 0x0068,
-+	0x2450, 0x2071, 0x776d, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2450,
-+	0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x2537, 0x0079, 0x24d4,
-+	0x007c, 0x2071, 0x776d, 0x7004, 0x0079, 0x2456, 0x245a, 0x245b,
-+	0x2465, 0x2477, 0x007c, 0x0090, 0x2464, 0x0068, 0x2464, 0x2b78,
-+	0x7818, 0xd084, 0x0040, 0x2483, 0x007c, 0x2b78, 0x2061, 0x77bd,
-+	0x6008, 0xa08e, 0x0100, 0x0040, 0x2472, 0xa086, 0x0200, 0x0040,
-+	0x252f, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010,
-+	0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x247f, 0x007c, 0x2a60,
-+	0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8,
-+	0x248c, 0x61b0, 0x0079, 0x2494, 0x2100, 0xa08a, 0x0036, 0x00c8,
-+	0x252b, 0x61b0, 0x0079, 0x24d4, 0x250d, 0x253f, 0x2547, 0x254b,
-+	0x2553, 0x2559, 0x255d, 0x2566, 0x256a, 0x2572, 0x2576, 0x252b,
-+	0x252b, 0x252b, 0x257a, 0x252b, 0x258a, 0x25a1, 0x25b8, 0x2634,
-+	0x2639, 0x2666, 0x26c0, 0x26d1, 0x26ef, 0x2722, 0x272c, 0x2739,
-+	0x274c, 0x2766, 0x276f, 0x27ac, 0x27b2, 0x252b, 0x27c2, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x27c6, 0x27cc, 0x252b, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x27d4, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x27e1, 0x27e7, 0x252b, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x2572, 0x2576, 0x252b, 0x252b,
-+	0x27f9, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
-+	0x252b, 0x252b, 0x252b, 0x252b, 0x2846, 0x2913, 0x2927, 0x292e,
-+	0x2991, 0x29e2, 0x29ed, 0x2a2c, 0x2a3b, 0x2a4a, 0x2a4d, 0x27fd,
-+	0x2a76, 0x2abd, 0x2aca, 0x2bc5, 0x2cb3, 0x2cda, 0x2de4, 0x2df2,
-+	0x2dff, 0x2e39, 0x713c, 0x0078, 0x250d, 0x2021, 0x4000, 0x1078,
-+	0x2d33, 0x127e, 0x2091, 0x8000, 0x0068, 0x251a, 0x7818, 0xd084,
-+	0x0040, 0x251d, 0x127f, 0x0078, 0x2511, 0x781b, 0x0001, 0x7c22,
-+	0x7926, 0x7a2a, 0x7b2e, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091,
-+	0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x250f, 0x2021,
-+	0x4002, 0x0078, 0x250f, 0x2021, 0x4003, 0x0078, 0x250f, 0x2021,
-+	0x4005, 0x0078, 0x250f, 0x2021, 0x4006, 0x0078, 0x250f, 0xa02e,
-+	0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x2d42, 0x7823,
-+	0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
-+	0x7930, 0x0078, 0x2d46, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078,
-+	0x250d, 0x7924, 0x2114, 0x0078, 0x250d, 0x2099, 0x0009, 0x20a1,
-+	0x0009, 0x20a9, 0x0007, 0x53a3, 0x0078, 0x250d, 0x7824, 0x2060,
-+	0x0078, 0x257c, 0x2009, 0x0001, 0x2011, 0x000f, 0x2019, 0x0025,
-+	0x0078, 0x250d, 0x7d38, 0x7c3c, 0x0078, 0x2541, 0x7d38, 0x7c3c,
-+	0x0078, 0x254d, 0x2061, 0x1000, 0x610c, 0xa006, 0x2c14, 0xa200,
-+	0x8c60, 0x8109, 0x00c0, 0x257e, 0x2010, 0xa005, 0x0040, 0x250d,
-+	0x0078, 0x2533, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8,
-+	0x253b, 0x8019, 0x0040, 0x253b, 0x604a, 0x6142, 0x782c, 0x6052,
-+	0x7828, 0x6056, 0xa006, 0x605a, 0x605e, 0x1078, 0x3d89, 0x0078,
-+	0x250d, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x253b,
-+	0x8019, 0x0040, 0x253b, 0x604e, 0x6146, 0x782c, 0x6062, 0x7828,
-+	0x6066, 0xa006, 0x606a, 0x606e, 0x1078, 0x3b5f, 0x0078, 0x250d,
-+	0xa02e, 0x2520, 0x81ff, 0x00c0, 0x2537, 0x7924, 0x7b28, 0x7a2c,
-+	0x20a9, 0x0005, 0x20a1, 0x7774, 0x41a1, 0x1078, 0x2cf8, 0x0040,
-+	0x2537, 0x2009, 0x0020, 0x1078, 0x2d42, 0x701b, 0x25d0, 0x007c,
-+	0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0040, 0x25dc,
-+	0xa096, 0x0019, 0x00c0, 0x2537, 0x810f, 0xa18c, 0x00ff, 0x0040,
-+	0x2537, 0x710e, 0x700c, 0x8001, 0x0040, 0x260d, 0x700e, 0x1078,
-+	0x2cf8, 0x0040, 0x2537, 0x2009, 0x0020, 0x2061, 0x77bd, 0x6224,
-+	0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-+	0x0000, 0xa5a9, 0x0000, 0x1078, 0x2d42, 0x701b, 0x2600, 0x007c,
-+	0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x260b, 0xa096,
-+	0x000a, 0x00c0, 0x2537, 0x0078, 0x25e2, 0x7010, 0x2068, 0x6838,
-+	0xc0fd, 0x683a, 0x1078, 0x3744, 0x00c0, 0x261b, 0x7007, 0x0003,
-+	0x701b, 0x261d, 0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000,
-+	0x20a9, 0x0005, 0x2099, 0x7774, 0x530a, 0x2100, 0xa210, 0xa399,
-+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009,
-+	0x0020, 0x127f, 0x0078, 0x2d46, 0x6198, 0x7824, 0x609a, 0x0078,
-+	0x250d, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, 0x782b,
-+	0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, 0x3f00,
-+	0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007,
-+	0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, 0x0001,
-+	0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0,
-+	0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, 0x81ff, 0x00c0,
-+	0x2537, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0,
-+	0x253b, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x267a,
-+	0x0078, 0x253b, 0x7c28, 0x7d2c, 0x1078, 0x39fd, 0xd28c, 0x00c0,
-+	0x2685, 0x1078, 0x3991, 0x0078, 0x2687, 0x1078, 0x39cb, 0x00c0,
-+	0x26b1, 0x2061, 0x7e00, 0x127e, 0x2091, 0x8000, 0x6000, 0xa086,
-+	0x0000, 0x0040, 0x269f, 0x6010, 0xa06d, 0x0040, 0x269f, 0x683c,
-+	0xa406, 0x00c0, 0x269f, 0x6840, 0xa506, 0x0040, 0x26aa, 0x127f,
-+	0xace0, 0x0008, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x2537,
-+	0x0078, 0x268b, 0x1078, 0x6852, 0x127f, 0x0040, 0x2537, 0x0078,
-+	0x250d, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x6c5c, 0x1078, 0x3b92, 0x127f, 0x0078, 0x250d,
-+	0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078,
-+	0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a, 0x0040, 0x2537, 0x0078,
-+	0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040, 0x253b,
-+	0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0005, 0x1078, 0x3a2b,
-+	0x0040, 0x2537, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x8003,
-+	0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x0078, 0x250d, 0x127e,
-+	0x2091, 0x8000, 0x81ff, 0x00c0, 0x271c, 0x2029, 0x00ff, 0x644c,
-+	0x2400, 0xa506, 0x0040, 0x2716, 0x2508, 0x1078, 0x384c, 0x00c0,
-+	0x2716, 0x1078, 0x3a71, 0x0040, 0x271c, 0x2019, 0x0004, 0x1078,
-+	0x3a2b, 0x0040, 0x271c, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x271f,
-+	0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x8529, 0x00c8,
-+	0x26f8, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537, 0x127f,
-+	0x0078, 0x253b, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078, 0x3942,
-+	0x1078, 0x39fd, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078,
-+	0x2d10, 0x0040, 0x253b, 0x1078, 0x3931, 0x1078, 0x39fd, 0x0078,
-+	0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b,
-+	0x1078, 0x39ce, 0x0040, 0x2537, 0x1078, 0x378d, 0x1078, 0x398a,
-+	0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10, 0x0040, 0x253b,
-+	0x1078, 0x38d5, 0x0040, 0x2537, 0x62a0, 0x2019, 0x0005, 0x0c7e,
-+	0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08,
-+	0x1078, 0x747b, 0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10,
-+	0x0040, 0x253b, 0x1078, 0x39fd, 0x2208, 0x0078, 0x250d, 0x157e,
-+	0x0d7e, 0x0e7e, 0x2069, 0x77ff, 0x6810, 0x6914, 0xa10a, 0x00c8,
-+	0x277b, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000,
-+	0x20a9, 0x007e, 0x2069, 0x7820, 0x2d04, 0xa075, 0x0040, 0x2790,
-+	0x704c, 0x1078, 0x279a, 0xa210, 0x7080, 0x1078, 0x279a, 0xa318,
-+	0x8d68, 0x00f0, 0x2784, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f,
-+	0x0078, 0x250d, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x27a9, 0x2001,
-+	0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x27a9, 0x2178, 0x0078,
-+	0x27a1, 0x017f, 0x0f7f, 0x007c, 0x2069, 0x77ff, 0x6910, 0x629c,
-+	0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x614c, 0xa190, 0x2329,
-+	0x2214, 0xa294, 0x00ff, 0x6068, 0xa084, 0xff00, 0xa215, 0x6364,
-+	0x0078, 0x250d, 0x613c, 0x6240, 0x0078, 0x250d, 0x1078, 0x2d22,
-+	0x0040, 0x253b, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040, 0x253b,
-+	0x6244, 0x6338, 0x0078, 0x250d, 0x613c, 0x6240, 0x7824, 0x603e,
-+	0x7b28, 0x6342, 0x2069, 0x7751, 0x831f, 0xa305, 0x6816, 0x0078,
-+	0x250d, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0078, 0x250d, 0x1078,
-+	0x2d22, 0x0040, 0x253b, 0x7828, 0xa00d, 0x0040, 0x253b, 0x782c,
-+	0xa005, 0x0040, 0x253b, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
-+	0x250d, 0x7d38, 0x7c3c, 0x0078, 0x25ba, 0x7824, 0xa09c, 0x00ff,
-+	0xa39a, 0x0003, 0x00c8, 0x2537, 0x624c, 0xa084, 0xff00, 0x8007,
-+	0xa206, 0x00c0, 0x2815, 0x2001, 0x7740, 0x2009, 0x000c, 0x7a2c,
-+	0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537,
-+	0x1078, 0x2d22, 0x0040, 0x253b, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x00c0, 0x2537, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x0040,
-+	0x2537, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x6b56,
-+	0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2837, 0x007c, 0x6830,
-+	0xa086, 0x0100, 0x0040, 0x2537, 0xad80, 0x000e, 0x2009, 0x000c,
-+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x1078, 0x2cf8,
-+	0x0040, 0x2537, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-+	0x1078, 0x2d42, 0x701b, 0x2855, 0x007c, 0xade8, 0x000d, 0x6800,
-+	0xa005, 0x0040, 0x253b, 0x6804, 0xd0ac, 0x0040, 0x2862, 0xd0a4,
-+	0x0040, 0x253b, 0xd094, 0x0040, 0x286d, 0x0c7e, 0x2061, 0x0100,
-+	0x6104, 0xa18c, 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x2878,
-+	0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f,
-+	0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0048, 0x288d, 0xd084,
-+	0x0040, 0x288d, 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x253b, 0xa288,
-+	0x2329, 0x210c, 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x2896,
-+	0x6828, 0xa08a, 0x007f, 0x00c8, 0x253b, 0x604e, 0x6808, 0xa08a,
-+	0x0100, 0x0048, 0x253b, 0xa08a, 0x0841, 0x00c8, 0x253b, 0xa084,
-+	0x0007, 0x00c0, 0x253b, 0x680c, 0xa005, 0x0040, 0x253b, 0x6810,
-+	0xa005, 0x0040, 0x253b, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x253b,
-+	0x8001, 0x0040, 0x253b, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x253b,
-+	0x8001, 0x0040, 0x253b, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x7751,
-+	0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
-+	0x00ff, 0x6042, 0x1078, 0x3d89, 0x1078, 0x3b5f, 0x6000, 0xa086,
-+	0x0000, 0x00c0, 0x2911, 0x6808, 0x602a, 0x1078, 0x1de4, 0x6818,
-+	0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016,
-+	0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x28f1, 0x6830,
-+	0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078,
-+	0x28f3, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078,
-+	0x4722, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
-+	0x0c7f, 0x60b4, 0xa005, 0x0040, 0x290d, 0x6003, 0x0001, 0x2091,
-+	0x301d, 0x1078, 0x3591, 0x0078, 0x2911, 0x6003, 0x0004, 0x2091,
-+	0x301d, 0x0078, 0x250d, 0x6000, 0xa086, 0x0000, 0x0040, 0x2537,
-+	0x2069, 0x7751, 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009,
-+	0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff,
-+	0x00c0, 0x2537, 0x1078, 0x3591, 0x0078, 0x250d, 0x81ff, 0x00c0,
-+	0x2537, 0x617c, 0x81ff, 0x0040, 0x2948, 0x703f, 0x0000, 0x2001,
-+	0x7dc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x2d46, 0x701b, 0x250a, 0x127f, 0x007c,
-+	0x703f, 0x0001, 0x0d7e, 0x2069, 0x7dc0, 0x20a9, 0x0040, 0x20a1,
-+	0x7dc0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2329, 0x210c,
-+	0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506,
-+	0x0040, 0x297a, 0x1078, 0x384c, 0x00c0, 0x297a, 0x6014, 0x821c,
-+	0x0048, 0x2972, 0xa398, 0x7dc0, 0xa085, 0xff00, 0x8007, 0x201a,
-+	0x0078, 0x2979, 0xa398, 0x7dc0, 0x2324, 0xa4a4, 0xff00, 0xa405,
-+	0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x2981, 0x0078,
-+	0x295e, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9,
-+	0x0040, 0x20a1, 0x7dc0, 0x2099, 0x7dc0, 0x1078, 0x35da, 0x0078,
-+	0x2937, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2cf8,
-+	0x0c7f, 0x0040, 0x2537, 0x2001, 0x7752, 0x2004, 0xd0b4, 0x0040,
-+	0x29be, 0x6000, 0xd08c, 0x00c0, 0x29be, 0x6004, 0xa084, 0x00ff,
-+	0xa086, 0x0006, 0x00c0, 0x29be, 0x6837, 0x0000, 0x6838, 0xc0fd,
-+	0x683a, 0x1078, 0x6b8e, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b,
-+	0x29ba, 0x007c, 0x1078, 0x2d22, 0x0040, 0x253b, 0x20a9, 0x002b,
-+	0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80,
-+	0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x35da, 0x20a9,
-+	0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078,
-+	0x35da, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-+	0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040,
-+	0x253b, 0x1078, 0x3a15, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537,
-+	0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x1078, 0x2d22, 0x0040,
-+	0x253b, 0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0004, 0x1078,
-+	0x3a2b, 0x7924, 0x810f, 0x7a28, 0x1078, 0x2a08, 0x0078, 0x250d,
-+	0xa186, 0x00ff, 0x0040, 0x2a10, 0x1078, 0x2a20, 0x0078, 0x2a1f,
-+	0x2029, 0x007e, 0x2061, 0x7700, 0x644c, 0x2400, 0xa506, 0x0040,
-+	0x2a1c, 0x2508, 0x1078, 0x2a20, 0x8529, 0x00c8, 0x2a15, 0x007c,
-+	0x1078, 0x384c, 0x00c0, 0x2a2b, 0x2200, 0x8003, 0x800b, 0x810b,
-+	0xa108, 0x1078, 0x4696, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078,
-+	0x2d10, 0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078,
-+	0x3a20, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10,
-+	0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a,
-+	0x0078, 0x250d, 0x6100, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040,
-+	0x253b, 0x6004, 0xa086, 0x0707, 0x0040, 0x253b, 0x2001, 0x7700,
-+	0x2004, 0xa086, 0x0003, 0x00c0, 0x2537, 0x0d7e, 0xace8, 0x000a,
-+	0x7924, 0xd184, 0x0040, 0x2a66, 0xace8, 0x0006, 0x680c, 0x8007,
-+	0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
-+	0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x250d, 0x7824, 0xa084,
-+	0x00ff, 0xa086, 0x00ff, 0x0040, 0x2a80, 0x81ff, 0x00c0, 0x2537,
-+	0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x7924, 0xa18c, 0xff00,
-+	0x810f, 0xa186, 0x00ff, 0x0040, 0x2a94, 0xa182, 0x007f, 0x00c8,
-+	0x253b, 0x2100, 0x1078, 0x2094, 0x027e, 0x0c7e, 0x127e, 0x2091,
-+	0x8000, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061,
-+	0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078,
-+	0x4719, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x2a08,
-+	0x127f, 0x0c7f, 0x027f, 0x0078, 0x250d, 0x7924, 0xa18c, 0xff00,
-+	0x810f, 0x0c7e, 0x1078, 0x3811, 0x2c08, 0x0c7f, 0x00c0, 0x253b,
-+	0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x60bc, 0xd09c, 0x0040,
-+	0x2537, 0x1078, 0x2cf8, 0x0040, 0x2537, 0x6823, 0x0000, 0x7924,
-+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2d42, 0x701b, 0x2ae1,
-+	0x007c, 0x2009, 0x0080, 0x1078, 0x384c, 0x00c0, 0x2aee, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x2af2, 0x2021, 0x400a,
-+	0x0078, 0x250f, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
-+	0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, 0x2b65,
-+	0xa0be, 0x0112, 0x0040, 0x2b65, 0xa0be, 0x0113, 0x0040, 0x2b65,
-+	0xa0be, 0x0114, 0x0040, 0x2b65, 0xa0be, 0x0117, 0x0040, 0x2b65,
-+	0xa0be, 0x011a, 0x0040, 0x2b65, 0xa0be, 0x0121, 0x0040, 0x2b5b,
-+	0xa0be, 0x0131, 0x0040, 0x2b5b, 0xa0be, 0x0171, 0x0040, 0x2b65,
-+	0xa0be, 0x0173, 0x0040, 0x2b65, 0xa0be, 0x01a1, 0x00c0, 0x2b2d,
-+	0x6830, 0x8007, 0x6832, 0x0078, 0x2b6b, 0xa0be, 0x0212, 0x0040,
-+	0x2b61, 0xa0be, 0x0213, 0x0040, 0x2b61, 0xa0be, 0x0214, 0x0040,
-+	0x2b53, 0xa0be, 0x0217, 0x0040, 0x2b4d, 0xa0be, 0x021a, 0x00c0,
-+	0x2b46, 0x6838, 0x8007, 0x683a, 0x0078, 0x2b65, 0xa0be, 0x0300,
-+	0x0040, 0x2b65, 0x0d7f, 0x0078, 0x253b, 0xad80, 0x0010, 0x20a9,
-+	0x0007, 0x1078, 0x2ba1, 0xad80, 0x000e, 0x20a9, 0x0001, 0x1078,
-+	0x2ba1, 0x0078, 0x2b65, 0xad80, 0x000c, 0x1078, 0x2baf, 0x0078,
-+	0x2b6b, 0xad80, 0x000e, 0x1078, 0x2baf, 0xad80, 0x000c, 0x20a9,
-+	0x0001, 0x1078, 0x2ba1, 0x0c7e, 0x1078, 0x2cf8, 0x0040, 0x2b96,
-+	0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x684f, 0x0020, 0x685b,
-+	0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e,
-+	0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000,
-+	0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x1078, 0x6b72, 0x0040,
-+	0x2537, 0x7007, 0x0003, 0x701b, 0x2b9a, 0x007c, 0x0c7f, 0x0d7f,
-+	0x0078, 0x2537, 0x6820, 0xa086, 0x8001, 0x0040, 0x2537, 0x0078,
-+	0x250d, 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a,
-+	0x8108, 0x280a, 0x8108, 0x00f0, 0x2ba3, 0x017f, 0x007c, 0x017e,
-+	0x0a7e, 0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054,
-+	0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108,
-+	0x280a, 0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x00c0, 0x2537,
-+	0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048,
-+	0x253b, 0xa182, 0x00ff, 0x00c8, 0x253b, 0x7a2c, 0x7b28, 0x6064,
-+	0xa306, 0x00c0, 0x2be3, 0x6068, 0xa24e, 0x0040, 0x253b, 0xa9cc,
-+	0xff00, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2c57, 0x2c68, 0x0c7f,
-+	0x0040, 0x2c0a, 0xa0c6, 0x4000, 0x00c0, 0x2bf0, 0x0078, 0x2c07,
-+	0xa0c6, 0x4007, 0x00c0, 0x2bf7, 0x2408, 0x0078, 0x2c07, 0xa0c6,
-+	0x4008, 0x00c0, 0x2bff, 0x2708, 0x2610, 0x0078, 0x2c07, 0xa0c6,
-+	0x4009, 0x00c0, 0x2c05, 0x0078, 0x2c07, 0x2001, 0x4006, 0x2020,
-+	0x0078, 0x250f, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078,
-+	0x5cb4, 0x0040, 0x2c45, 0x2d00, 0x601a, 0x2e58, 0x0e7f, 0x0e7e,
-+	0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x2b70, 0x0040, 0x2537, 0x6837,
-+	0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
-+	0x127e, 0x2091, 0x8000, 0x1078, 0x22b5, 0x127f, 0x601f, 0x0001,
-+	0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4,
-+	0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009,
-+	0x0002, 0x1078, 0x5d41, 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f,
-+	0x017f, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2c50, 0x007c,
-+	0x6830, 0xa086, 0x0100, 0x00c0, 0x250d, 0x0078, 0x2537, 0x0e7e,
-+	0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
-+	0x78a0, 0x2e04, 0xa005, 0x00c0, 0x2c6b, 0x2100, 0xa406, 0x0040,
-+	0x2ca8, 0x0078, 0x2c9c, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0,
-+	0x2c8d, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x2c8d, 0x2400, 0xa106,
-+	0x00c0, 0x2c89, 0x2d60, 0xd884, 0x0040, 0x2cae, 0x6004, 0xa084,
-+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x2cae, 0x2001, 0x4000, 0x0078,
-+	0x2caf, 0x2001, 0x4007, 0x0078, 0x2caf, 0x2400, 0xa106, 0x00c0,
-+	0x2c9c, 0x6e14, 0x87ff, 0x00c0, 0x2c98, 0x86ff, 0x0040, 0x2ca8,
-+	0x2001, 0x4008, 0x0078, 0x2caf, 0x8420, 0x8e70, 0x00f0, 0x2c61,
-+	0x2001, 0x4009, 0x0078, 0x2caf, 0x2001, 0x0001, 0x0078, 0x2caf,
-+	0x1078, 0x3811, 0x00c0, 0x2ca4, 0x6312, 0x6216, 0xa006, 0xa005,
-+	0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2cf8,
-+	0x0040, 0x2537, 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x253b,
-+	0xa096, 0x00ff, 0x0040, 0x2cc8, 0xa092, 0x0004, 0x00c8, 0x253b,
-+	0x2010, 0x2d18, 0x1078, 0x2277, 0x0040, 0x2537, 0x7007, 0x0003,
-+	0x701b, 0x2cd3, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537,
-+	0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x7924, 0xa18c, 0xff00,
-+	0x810f, 0xa182, 0x0080, 0x0048, 0x253b, 0xa182, 0x00ff, 0x00c8,
-+	0x253b, 0x127e, 0x2091, 0x8000, 0x1078, 0x6a99, 0x00c0, 0x2cf5,
-+	0x1078, 0x3834, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537,
-+	0x1078, 0x1327, 0x0040, 0x2d0f, 0xa006, 0x6802, 0x7010, 0xa005,
-+	0x00c0, 0x2d07, 0x2d00, 0x7012, 0x7016, 0x0078, 0x2d0d, 0x7014,
-+	0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
-+	0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0, 0x2d1f,
-+	0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x2d20, 0xa066,
-+	0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x384c,
-+	0x00c0, 0x2d30, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x2d31,
-+	0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x2d3e,
-+	0x2168, 0x6904, 0x1078, 0x1340, 0x0078, 0x2d35, 0x7112, 0x7116,
-+	0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x2d48, 0x2031, 0x0000,
-+	0x2061, 0x77bd, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
-+	0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002, 0x701b, 0x250d,
-+	0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
-+	0x777b, 0x2004, 0xa005, 0x00c0, 0x2d74, 0x0068, 0x2d74, 0x7818,
-+	0xd084, 0x00c0, 0x2d74, 0x781b, 0x0001, 0x7a22, 0x7b26, 0x7c2a,
-+	0x2091, 0x4080, 0x0078, 0x2d99, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
-+	0x776d, 0x7138, 0xa182, 0x0008, 0x0048, 0x2d82, 0x7030, 0x2060,
-+	0x0078, 0x2d93, 0x7030, 0xa0e0, 0x0008, 0xac82, 0x77bd, 0x0048,
-+	0x2d8b, 0x2061, 0x777d, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x2d91,
-+	0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
-+	0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0x776d, 0x7038,
-+	0xa005, 0x0040, 0x2dd5, 0x127e, 0x2091, 0x8000, 0x0068, 0x2dd4,
-+	0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x2dd3, 0x0c7e,
-+	0x781b, 0x0001, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
-+	0x6008, 0x782a, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
-+	0x00c0, 0x2dc9, 0x7033, 0x777d, 0x7037, 0x777d, 0x0c7f, 0x0078,
-+	0x2dd3, 0xac80, 0x0008, 0xa0fa, 0x77bd, 0x0048, 0x2dd1, 0x2001,
-+	0x777d, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
-+	0x2001, 0x7752, 0x2004, 0xd0c4, 0x0040, 0x2de2, 0x2011, 0x8014,
-+	0x1078, 0x2d59, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x127e,
-+	0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x1078, 0x3591, 0x127f,
-+	0x0078, 0x250d, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x00c0, 0x2dfd,
-+	0x61c8, 0xa10d, 0x61ca, 0x0078, 0x250d, 0x0078, 0x253b, 0x81ff,
-+	0x00c0, 0x2537, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2537, 0x2001,
-+	0x7752, 0x2004, 0xd0a4, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040,
-+	0x253b, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2e1c,
-+	0x7828, 0xa005, 0x0040, 0x250d, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f,
-+	0x0040, 0x2537, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
-+	0x683a, 0x1078, 0x6bfb, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b,
-+	0x2e32, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537, 0x0078,
-+	0x250d, 0x2001, 0x7700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2537,
-+	0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2cf8, 0x0040,
-+	0x2537, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
-+	0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x384c, 0x00c0,
-+	0x2e7f, 0x6004, 0xa0c6, 0x0707, 0x0040, 0x2e7f, 0xa084, 0x00ff,
-+	0xa0c6, 0x0006, 0x00c0, 0x2e7f, 0x87ff, 0x0040, 0x2e72, 0xac80,
-+	0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x2baf,
-+	0x0078, 0x2e7b, 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
-+	0x53a3, 0x1078, 0x2baf, 0x21a2, 0x94a0, 0xa6b0, 0x0005, 0x8108,
-+	0xa186, 0x007e, 0x0040, 0x2e8a, 0xa686, 0x0028, 0x0040, 0x2e93,
-+	0x0078, 0x2e55, 0x86ff, 0x00c0, 0x2e91, 0x7120, 0x810b, 0x0078,
-+	0x250d, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a,
-+	0x2061, 0x77bd, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226,
-+	0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002,
-+	0x701b, 0x2eab, 0x007c, 0x702c, 0xa005, 0x00c0, 0x2ebd, 0x711c,
-+	0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0x77bd, 0x6224,
-+	0x6328, 0x642c, 0x6530, 0x0078, 0x2e55, 0x7120, 0x810b, 0x0078,
-+	0x250d, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700,
-+	0x6044, 0xd0a4, 0x00c0, 0x2eea, 0xd084, 0x0040, 0x2ed3, 0x1078,
-+	0x3015, 0x0078, 0x2ee6, 0xd08c, 0x0040, 0x2eda, 0x1078, 0x2f2c,
-+	0x0078, 0x2ee6, 0xd094, 0x0040, 0x2ee1, 0x1078, 0x2f0f, 0x0078,
-+	0x2ee6, 0xd09c, 0x0040, 0x2ee6, 0x1078, 0x2ef4, 0x0e7f, 0x0c7f,
-+	0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, 0x2ef1, 0xc19d,
-+	0x612a, 0x017f, 0x0078, 0x2ee6, 0x6043, 0x0040, 0x6043, 0x0000,
-+	0x706f, 0x0000, 0x7087, 0x0001, 0x70a7, 0x0000, 0x70bf, 0x0000,
-+	0x2009, 0x7dc0, 0x200b, 0x0000, 0x707f, 0x0000, 0x7073, 0x000f,
-+	0x2009, 0x000f, 0x2011, 0x3551, 0x1078, 0x4719, 0x007c, 0x7070,
-+	0xa005, 0x00c0, 0x2f2b, 0x2011, 0x3551, 0x1078, 0x4689, 0x6043,
-+	0x0020, 0x6043, 0x0000, 0x6044, 0xd08c, 0x00c0, 0x2f27, 0x7083,
-+	0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x2f2b, 0x7077,
-+	0x0000, 0x0078, 0x2f2b, 0x007c, 0x7074, 0xa08a, 0x0003, 0x00c8,
-+	0x2f35, 0x1079, 0x2f38, 0x0078, 0x2f37, 0x1078, 0x12cd, 0x007c,
-+	0x2f3b, 0x2f8a, 0x3014, 0x0f7e, 0x7077, 0x0001, 0x20e1, 0xa000,
-+	0x20e1, 0x8700, 0x1078, 0x1de4, 0x20e1, 0x9080, 0x20e1, 0x4000,
-+	0x2079, 0x7c00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
-+	0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000,
-+	0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000,
-+	0x782f, 0x0000, 0x2079, 0x7c0c, 0x207b, 0x1101, 0x7807, 0x0000,
-+	0x2099, 0x7705, 0x20a1, 0x7c0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
-+	0x7c12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x7c00, 0x20a1,
-+	0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000,
-+	0x1078, 0x3578, 0x0f7f, 0x707b, 0x0000, 0x6043, 0x0008, 0x6043,
-+	0x0000, 0x007c, 0x0d7e, 0x7078, 0x707b, 0x0000, 0xa025, 0x0040,
-+	0x2ffe, 0x6020, 0xd0b4, 0x00c0, 0x2ffc, 0x7184, 0x81ff, 0x0040,
-+	0x2fe5, 0xa486, 0x000c, 0x00c0, 0x2ff0, 0xa480, 0x0018, 0x8004,
-+	0x20a8, 0x2011, 0x7c80, 0x2019, 0x7c00, 0x220c, 0x2304, 0xa106,
-+	0x00c0, 0x2fbc, 0x8210, 0x8318, 0x00f0, 0x2fa5, 0x6043, 0x0004,
-+	0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7077, 0x0002,
-+	0x7083, 0x0002, 0x0078, 0x2ffc, 0x2069, 0x7c80, 0x6930, 0xa18e,
-+	0x1101, 0x00c0, 0x2ff0, 0x6834, 0xa005, 0x00c0, 0x2ff0, 0x6900,
-+	0xa18c, 0x00ff, 0x00c0, 0x2fd0, 0x6804, 0xa005, 0x0040, 0x2fe5,
-+	0x2011, 0x7c8e, 0x2019, 0x7705, 0x20a9, 0x0004, 0x220c, 0x2304,
-+	0xa102, 0x0048, 0x2fe3, 0x00c0, 0x2ff0, 0x8210, 0x8318, 0x00f0,
-+	0x2fd6, 0x0078, 0x2ff0, 0x7087, 0x0000, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
-+	0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2ffc,
-+	0x60c3, 0x000c, 0x1078, 0x3578, 0x0d7f, 0x007c, 0x6020, 0xd0b4,
-+	0x00c0, 0x2ffc, 0x60c3, 0x000c, 0x2011, 0x7940, 0x2013, 0x0000,
-+	0x707b, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
-+	0x1078, 0x5693, 0x0078, 0x2ffc, 0x007c, 0x7080, 0xa08a, 0x001d,
-+	0x00c8, 0x301e, 0x1079, 0x3021, 0x0078, 0x3020, 0x1078, 0x12cd,
-+	0x007c, 0x3045, 0x3054, 0x3085, 0x309a, 0x30ca, 0x30f2, 0x3122,
-+	0x314c, 0x317c, 0x31a2, 0x31eb, 0x320d, 0x3231, 0x3247, 0x326f,
-+	0x3282, 0x328b, 0x32a4, 0x32d2, 0x32fa, 0x3328, 0x3352, 0x339a,
-+	0x33cb, 0x33ed, 0x342b, 0x3451, 0x346a, 0x3477, 0x7003, 0x0007,
-+	0x6004, 0xa084, 0xfff9, 0x6006, 0x007c, 0x608b, 0xbc94, 0x608f,
-+	0xf0f0, 0x6043, 0x0002, 0x7083, 0x0001, 0x2009, 0x07d0, 0x2011,
-+	0x3558, 0x1078, 0x467c, 0x007c, 0x0f7e, 0x7078, 0xa086, 0x0014,
-+	0x00c0, 0x3083, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3083,
-+	0x2079, 0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3081, 0x7834,
-+	0xa005, 0x00c0, 0x3081, 0x7a38, 0xd2fc, 0x0040, 0x3077, 0x70a4,
-+	0xa005, 0x00c0, 0x3077, 0x1078, 0x3611, 0x70a7, 0x0001, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0x7083, 0x0010, 0x1078, 0x328b, 0x0078,
-+	0x3083, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0003, 0x6043,
-+	0x0004, 0x1078, 0x35e2, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9,
-+	0x000a, 0x20a3, 0x0000, 0x00f0, 0x3091, 0x60c3, 0x0014, 0x1078,
-+	0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x30c8, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x30c4, 0x2079,
-+	0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x30c4, 0x7834, 0xa005,
-+	0x00c0, 0x30c4, 0x7a38, 0xd2fc, 0x0040, 0x30be, 0x70a4, 0xa005,
-+	0x00c0, 0x30be, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0004,
-+	0x1078, 0x30ca, 0x0078, 0x30c8, 0x7083, 0x0002, 0x707b, 0x0000,
-+	0x0f7f, 0x007c, 0x7083, 0x0005, 0x1078, 0x35e2, 0x20a3, 0x1103,
-+	0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
-+	0x30e4, 0x714c, 0xa186, 0xffff, 0x0040, 0x30e4, 0x1078, 0x351c,
-+	0x0040, 0x30e4, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0,
-+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3120, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x311c, 0x2079,
-+	0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x311c, 0x7834, 0xa005,
-+	0x00c0, 0x311c, 0x7a38, 0xd2fc, 0x0040, 0x3116, 0x70a4, 0xa005,
-+	0x00c0, 0x3116, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0006,
-+	0x1078, 0x3122, 0x0078, 0x3120, 0x7083, 0x0002, 0x707b, 0x0000,
-+	0x0f7f, 0x007c, 0x7083, 0x0007, 0x1078, 0x35e2, 0x20a3, 0x1104,
-+	0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
-+	0x313e, 0x7150, 0xa186, 0xffff, 0x0040, 0x313e, 0xa180, 0x2329,
-+	0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008,
-+	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040,
-+	0x317a, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0,
-+	0x3176, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3176,
-+	0x7834, 0xa005, 0x00c0, 0x3176, 0x7a38, 0xd2fc, 0x0040, 0x3170,
-+	0x70a4, 0xa005, 0x00c0, 0x3170, 0x1078, 0x3611, 0x70a7, 0x0001,
-+	0x7083, 0x0008, 0x1078, 0x317c, 0x0078, 0x317a, 0x7083, 0x0002,
-+	0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0009, 0x1078, 0x35e2,
-+	0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x706c, 0xa005, 0x00c0,
-+	0x318f, 0x1078, 0x3486, 0x0040, 0x319f, 0x0078, 0x3199, 0x20a9,
-+	0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x31a1, 0x1078,
-+	0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x31e9, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x31e5, 0x2079,
-+	0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x31e5, 0x7834, 0x2011,
-+	0x0100, 0xa21e, 0x00c0, 0x31ce, 0x7a38, 0xd2fc, 0x0040, 0x31c8,
-+	0x70a4, 0xa005, 0x00c0, 0x31c8, 0x1078, 0x3611, 0x70a7, 0x0001,
-+	0x7083, 0x000a, 0x1078, 0x31eb, 0x0078, 0x31e9, 0xa005, 0x00c0,
-+	0x31e5, 0x7a38, 0xd2fc, 0x0040, 0x31dd, 0x70a4, 0xa005, 0x00c0,
-+	0x31dd, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083,
-+	0x000e, 0x1078, 0x326f, 0x0078, 0x31e9, 0x7083, 0x0002, 0x707b,
-+	0x0000, 0x0f7f, 0x007c, 0x7083, 0x000b, 0x2011, 0x7c0e, 0x22a0,
-+	0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009,
-+	0x0000, 0x41a4, 0x1078, 0x35e2, 0x20a3, 0x1106, 0x20a3, 0x0000,
-+	0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6,
-+	0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005,
-+	0x0040, 0x322f, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084,
-+	0x00c0, 0x322b, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0,
-+	0x322b, 0x7834, 0xa005, 0x00c0, 0x322b, 0x7083, 0x000c, 0x1078,
-+	0x3231, 0x0078, 0x322f, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f,
-+	0x007c, 0x7083, 0x000d, 0x1078, 0x35e2, 0x20a3, 0x1107, 0x20a3,
-+	0x0000, 0x2099, 0x7c8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e,
-+	0x7078, 0xa005, 0x0040, 0x326d, 0x2011, 0x3558, 0x1078, 0x4689,
-+	0xa086, 0x0084, 0x00c0, 0x3269, 0x2079, 0x7c80, 0x7a30, 0xa296,
-+	0x1107, 0x00c0, 0x3269, 0x7834, 0xa005, 0x00c0, 0x3269, 0x707f,
-+	0x0001, 0x1078, 0x35d4, 0x7083, 0x000e, 0x1078, 0x326f, 0x0078,
-+	0x326d, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083,
-+	0x000f, 0x707b, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043,
-+	0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078,
-+	0x467c, 0x007c, 0x7078, 0xa005, 0x0040, 0x328a, 0x2011, 0x3558,
-+	0x1078, 0x4689, 0x007c, 0x7083, 0x0011, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018,
-+	0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3,
-+	0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040,
-+	0x32d0, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0,
-+	0x32ce, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x32ce,
-+	0x7834, 0xa005, 0x00c0, 0x32ce, 0x7a38, 0xd2fc, 0x0040, 0x32c8,
-+	0x70a4, 0xa005, 0x00c0, 0x32c8, 0x1078, 0x3611, 0x70a7, 0x0001,
-+	0x7083, 0x0012, 0x1078, 0x32d2, 0x0078, 0x32d0, 0x707b, 0x0000,
-+	0x0f7f, 0x007c, 0x7083, 0x0013, 0x1078, 0x35ee, 0x20a3, 0x1103,
-+	0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
-+	0x32ec, 0x714c, 0xa186, 0xffff, 0x0040, 0x32ec, 0x1078, 0x351c,
-+	0x0040, 0x32ec, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0,
-+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3326, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3324, 0x2079,
-+	0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3324, 0x7834, 0xa005,
-+	0x00c0, 0x3324, 0x7a38, 0xd2fc, 0x0040, 0x331e, 0x70a4, 0xa005,
-+	0x00c0, 0x331e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0014,
-+	0x1078, 0x3328, 0x0078, 0x3326, 0x707b, 0x0000, 0x0f7f, 0x007c,
-+	0x7083, 0x0015, 0x1078, 0x35ee, 0x20a3, 0x1104, 0x20a3, 0x0000,
-+	0x3430, 0x2011, 0x7c8e, 0x706c, 0xa006, 0x00c0, 0x3344, 0x7150,
-+	0xa186, 0xffff, 0x0040, 0x3344, 0xa180, 0x2329, 0x200c, 0xa18c,
-+	0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008, 0x2298, 0x26a0,
-+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3398, 0x2011,
-+	0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3396, 0x2079,
-+	0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x3396, 0x7834, 0x2011,
-+	0x0100, 0xa21e, 0x00c0, 0x337f, 0x7a38, 0xd2f4, 0x0040, 0x3372,
-+	0x70bf, 0x0008, 0xd2fc, 0x0040, 0x337d, 0x70a4, 0xa005, 0x00c0,
-+	0x337d, 0x1078, 0x3611, 0x70a7, 0x0001, 0x0078, 0x3390, 0xa005,
-+	0x00c0, 0x3396, 0x7a38, 0xd2fc, 0x0040, 0x338e, 0x70a4, 0xa005,
-+	0x00c0, 0x338e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000,
-+	0x7083, 0x0016, 0x1078, 0x339a, 0x0078, 0x3398, 0x707b, 0x0000,
-+	0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c80,
-+	0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0x7c8e,
-+	0x7083, 0x0017, 0x0078, 0x33ae, 0x7083, 0x001b, 0x706c, 0xa005,
-+	0x00c0, 0x33b8, 0x1078, 0x3486, 0x0040, 0x33c8, 0x0078, 0x33c2,
-+	0x20a9, 0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x33ca,
-+	0x1078, 0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x33eb,
-+	0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x33e9,
-+	0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x33e9, 0x7834,
-+	0xa005, 0x00c0, 0x33e9, 0x7083, 0x0018, 0x1078, 0x33ed, 0x0078,
-+	0x33eb, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0019, 0x1078,
-+	0x35ee, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0x7c8e,
-+	0x2039, 0x7c0e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x2728, 0x2514,
-+	0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
-+	0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x7c0e, 0x2414,
-+	0xa38c, 0x0001, 0x0040, 0x3418, 0xa294, 0xff00, 0x0078, 0x341b,
-+	0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9,
-+	0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084,
-+	0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x344f,
-+	0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x344d,
-+	0x2079, 0x7c80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x344d, 0x7834,
-+	0xa005, 0x00c0, 0x344d, 0x707f, 0x0001, 0x1078, 0x35d4, 0x7083,
-+	0x001a, 0x1078, 0x3451, 0x0078, 0x344f, 0x707b, 0x0000, 0x0f7f,
-+	0x007c, 0x7083, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-+	0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007,
-+	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078,
-+	0x3578, 0x007c, 0x7078, 0xa005, 0x0040, 0x3476, 0x2011, 0x3558,
-+	0x1078, 0x4689, 0x7083, 0x001c, 0x1078, 0x3477, 0x007c, 0x707b,
-+	0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0001, 0x2009,
-+	0x07d0, 0x2011, 0x3558, 0x1078, 0x467c, 0x007c, 0x087e, 0x097e,
-+	0x2029, 0x7752, 0x252c, 0x20a9, 0x0008, 0x2041, 0x7c0e, 0x28a0,
-+	0x2099, 0x7c8e, 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4,
-+	0x0040, 0x349c, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6,
-+	0xffff, 0x00c0, 0x34ae, 0xd5d4, 0x0040, 0x34a9, 0x8210, 0x0078,
-+	0x34aa, 0x8211, 0x00f0, 0x349c, 0x0078, 0x3513, 0x82ff, 0x00c0,
-+	0x34c0, 0xd5d4, 0x0040, 0x34ba, 0xa1a6, 0x3fff, 0x0040, 0x34a6,
-+	0x0078, 0x34be, 0xa1a6, 0x3fff, 0x0040, 0x3513, 0xa18d, 0xc000,
-+	0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0040, 0x34c9, 0x2019,
-+	0x0010, 0x2120, 0xd5d4, 0x0040, 0x34d0, 0x8423, 0x0078, 0x34d1,
-+	0x8424, 0x00c8, 0x34de, 0xd5d4, 0x0040, 0x34d9, 0x8319, 0x0078,
-+	0x34da, 0x8318, 0x00f0, 0x34ca, 0x0078, 0x3513, 0x23a8, 0x2021,
-+	0x0001, 0x8426, 0x8425, 0x00f0, 0x34e2, 0x2328, 0x8529, 0xa2be,
-+	0x0007, 0x0040, 0x34f6, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a,
-+	0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0, 0x34f2, 0x754e, 0xa5c8,
-+	0x2329, 0x292c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea,
-+	0x2018, 0x2304, 0xa405, 0x201a, 0x706f, 0x0001, 0x26a0, 0x2898,
-+	0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085,
-+	0x0001, 0x0078, 0x3519, 0xa006, 0x0078, 0x3519, 0xa006, 0x1078,
-+	0x12cd, 0x097f, 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001,
-+	0x0007, 0xa39a, 0x0010, 0x0048, 0x3529, 0x8420, 0x8001, 0x0078,
-+	0x3521, 0x2118, 0x84ff, 0x0040, 0x3532, 0xa39a, 0x0010, 0x8421,
-+	0x00c0, 0x352d, 0x2021, 0x0001, 0x83ff, 0x0040, 0x353b, 0x8423,
-+	0x8319, 0x00c0, 0x3537, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3550,
-+	0xa405, 0x203a, 0x714e, 0xa1a0, 0x2329, 0x242c, 0xa5ac, 0x00ff,
-+	0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0001, 0xa084, 0x0000,
-+	0x007c, 0x0e7e, 0x2071, 0x7700, 0x7073, 0x0000, 0x0e7f, 0x007c,
-+	0x0e7e, 0x0f7e, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x569c,
-+	0x7004, 0xa084, 0x4000, 0x0040, 0x3569, 0x7003, 0x1000, 0x7003,
-+	0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0x7720, 0x2073, 0x0000,
-+	0x7843, 0x0090, 0x7843, 0x0010, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
-+	0x127e, 0x2091, 0x8000, 0x2011, 0x7940, 0x2013, 0x0000, 0x707b,
-+	0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
-+	0x1078, 0x5693, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078, 0x4719,
-+	0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
-+	0x00f7, 0x1078, 0x35fa, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f,
-+	0x0000, 0x2061, 0x7700, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078,
-+	0x467c, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
-+	0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078, 0x569c, 0x2071,
-+	0x0140, 0x7004, 0xa084, 0x4000, 0x0040, 0x35ca, 0x7003, 0x1000,
-+	0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x2025, 0x1078, 0x3591,
-+	0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0x7dc0,
-+	0x2099, 0x7c8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0,
-+	0x35da, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c00,
-+	0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x000c,
-+	0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001,
-+	0x772c, 0x2004, 0xa005, 0x00c0, 0x360b, 0x6030, 0xa084, 0x00ff,
-+	0xa105, 0x0078, 0x360d, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f,
-+	0x007c, 0x017e, 0x047e, 0x2001, 0x7752, 0x2004, 0xd0a4, 0x0040,
-+	0x3624, 0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0x7641, 0x2001,
-+	0x770c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x1078, 0x2293,
-+	0x047f, 0x017f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0x7820,
-+	0xa006, 0x200a, 0x8108, 0x00f0, 0x3631, 0x157f, 0x007c, 0x0d7e,
-+	0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0x7751, 0xa006, 0x6002,
-+	0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2329, 0x231c,
-+	0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0,
-+	0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e,
-+	0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066,
-+	0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086,
-+	0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2, 0x0d7e,
-+	0x60a4, 0xa06d, 0x0040, 0x3676, 0x1078, 0x1340, 0x60a7, 0x0000,
-+	0x60a8, 0xa06d, 0x0040, 0x367e, 0x1078, 0x1340, 0x60ab, 0x0000,
-+	0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814,
-+	0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f,
-+	0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff,
-+	0xa082, 0x4000, 0x00c8, 0x3737, 0xa18c, 0xff00, 0x810f, 0xa182,
-+	0x00ff, 0x00c8, 0x373d, 0x2001, 0x770c, 0x2004, 0xa084, 0x0003,
-+	0x00c0, 0x3720, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040, 0x370e,
-+	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x3714, 0x60a4,
-+	0xa00d, 0x0040, 0x36bf, 0x1078, 0x3a5c, 0x0040, 0x3708, 0x60a8,
-+	0xa00d, 0x0040, 0x36d9, 0x1078, 0x3aac, 0x00c0, 0x36d9, 0x694c,
-+	0xd1fc, 0x00c0, 0x36cf, 0x1078, 0x37d1, 0x0078, 0x3703, 0x1078,
-+	0x37a2, 0x694c, 0xd1ec, 0x00c0, 0x3703, 0x1078, 0x3931, 0x0078,
-+	0x3703, 0x694c, 0xa184, 0xa000, 0x0040, 0x36f3, 0xd1ec, 0x0040,
-+	0x36ec, 0xd1fc, 0x0040, 0x36e8, 0x1078, 0x3942, 0x0078, 0x36ef,
-+	0x1078, 0x3942, 0x0078, 0x36f3, 0xd1fc, 0x0040, 0x36f3, 0x1078,
-+	0x37a2, 0x0078, 0x3703, 0x6050, 0xa00d, 0x0040, 0x36fe, 0x2d00,
-+	0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x3703, 0x2d00, 0x6052,
-+	0x604e, 0x6803, 0x0000, 0x1078, 0x4960, 0xa006, 0x127f, 0x007c,
-+	0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0028,
-+	0x2009, 0x0000, 0x0078, 0x3741, 0xa082, 0x0006, 0x00c8, 0x3720,
-+	0x60a0, 0xd0bc, 0x0040, 0x36b7, 0x2001, 0x0028, 0x0078, 0x3733,
-+	0x2009, 0x770c, 0x210c, 0xd18c, 0x0040, 0x372a, 0x2001, 0x0004,
-+	0x0078, 0x3733, 0xd184, 0x0040, 0x3731, 0x2001, 0x0004, 0x0078,
-+	0x3733, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001,
-+	0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0029, 0x2009,
-+	0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff,
-+	0xa082, 0x4000, 0x00c8, 0x3787, 0xa18c, 0xff00, 0x810f, 0xa182,
-+	0x00ff, 0x00c8, 0x3777, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040,
-+	0x3777, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x377d,
-+	0x684c, 0xd0ec, 0x0040, 0x376a, 0x1078, 0x3942, 0x1078, 0x37a2,
-+	0x0078, 0x3772, 0x1078, 0x37a2, 0x684c, 0xd0fc, 0x0040, 0x3772,
-+	0x1078, 0x3931, 0x1078, 0x398a, 0xa006, 0x0078, 0x378b, 0x2001,
-+	0x0028, 0x2009, 0x0000, 0x0078, 0x378b, 0xa082, 0x0006, 0x0048,
-+	0x3760, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x378b, 0x2001,
-+	0x0029, 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000,
-+	0x6050, 0xa00d, 0x0040, 0x379b, 0x2d00, 0x200a, 0x6803, 0x0000,
-+	0x6052, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000,
-+	0x0078, 0x3799, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040,
-+	0x37ae, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052,
-+	0x604e, 0x6803, 0x0000, 0x0078, 0x37ac, 0x127e, 0x2091, 0x8000,
-+	0x604c, 0xa06d, 0x0040, 0x37c3, 0x6800, 0xa005, 0x00c0, 0x37c1,
-+	0x6052, 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040,
-+	0x37d0, 0x6800, 0xa005, 0x00c0, 0x37ce, 0x6052, 0x604e, 0xad05,
-+	0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x37db, 0x2d00,
-+	0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x37da,
-+	0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200,
-+	0xa005, 0x0040, 0x37ee, 0xc285, 0x0078, 0x37ef, 0xc284, 0x6202,
-+	0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000,
-+	0x6218, 0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x0c7f,
-+	0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
-+	0x6204, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
-+	0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x381a, 0xa085, 0x0001,
-+	0x0078, 0x3832, 0xa190, 0x7820, 0x2204, 0xa065, 0x00c0, 0x3831,
-+	0x017e, 0x0d7e, 0x1078, 0x130c, 0x2d60, 0x0d7f, 0x017f, 0x0040,
-+	0x3816, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
-+	0x3637, 0xa006, 0x027f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048,
-+	0x383d, 0xa085, 0x0001, 0x0078, 0x384a, 0x0d7e, 0xa190, 0x7820,
-+	0x2204, 0xa06d, 0x0040, 0x3848, 0x2013, 0x0000, 0x1078, 0x1340,
-+	0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048,
-+	0x3855, 0xa085, 0x0001, 0x0078, 0x385c, 0xa188, 0x7820, 0x2104,
-+	0xa065, 0x0040, 0x3851, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e,
-+	0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c,
-+	0x6002, 0x2069, 0x7c8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
-+	0xa10a, 0x0048, 0x3874, 0x603a, 0x6814, 0x6066, 0x2099, 0x7c96,
-+	0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0x7c9a,
-+	0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0x7cae,
-+	0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076,
-+	0xa182, 0x0211, 0x00c8, 0x3898, 0x2009, 0x0008, 0x0078, 0x38c2,
-+	0xa182, 0x0259, 0x00c8, 0x38a0, 0x2009, 0x0007, 0x0078, 0x38c2,
-+	0xa182, 0x02c1, 0x00c8, 0x38a8, 0x2009, 0x0006, 0x0078, 0x38c2,
-+	0xa182, 0x0349, 0x00c8, 0x38b0, 0x2009, 0x0005, 0x0078, 0x38c2,
-+	0xa182, 0x0421, 0x00c8, 0x38b8, 0x2009, 0x0004, 0x0078, 0x38c2,
-+	0xa182, 0x0581, 0x00c8, 0x38c0, 0x2009, 0x0003, 0x0078, 0x38c2,
-+	0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c,
-+	0x0e7e, 0x2071, 0x7c8d, 0x2e04, 0x6896, 0x2071, 0x7c8e, 0x7004,
-+	0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x0d7e, 0x127e, 0x2091,
-+	0x8000, 0x60a4, 0xa06d, 0x0040, 0x38f9, 0x6900, 0x81ff, 0x00c0,
-+	0x390d, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x3912, 0xad88, 0x0004,
-+	0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, 0x38f4, 0x8108,
-+	0x00f0, 0x38ea, 0x1078, 0x12cd, 0x260a, 0x8210, 0x6a06, 0x0078,
-+	0x390d, 0x1078, 0x130c, 0x0040, 0x3912, 0x2d00, 0x60a6, 0x6803,
-+	0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
-+	0x00f0, 0x3905, 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x127f,
-+	0x0d7f, 0x007c, 0xa006, 0x0078, 0x390f, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x3a55, 0x00c0, 0x392f, 0x200b, 0xffff, 0x0d7e, 0x60a4,
-+	0x2068, 0x6804, 0xa08a, 0x0002, 0x0048, 0x392a, 0x8001, 0x6806,
-+	0x0078, 0x392e, 0x1078, 0x1340, 0x60a7, 0x0000, 0x0d7f, 0x127f,
-+	0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3ac1, 0x0078, 0x393a,
-+	0x1078, 0x378d, 0x1078, 0x39ce, 0x00c0, 0x3938, 0x1078, 0x398a,
-+	0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8, 0xa06d,
-+	0x0040, 0x3966, 0x6950, 0x81ff, 0x00c0, 0x397a, 0x6a54, 0xa282,
-+	0x0010, 0x00c8, 0x3987, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104,
-+	0xa086, 0xffff, 0x0040, 0x3961, 0x8108, 0x00f0, 0x3957, 0x1078,
-+	0x12cd, 0x260a, 0x8210, 0x6a56, 0x0078, 0x397a, 0x1078, 0x130c,
-+	0x0040, 0x3987, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018,
-+	0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x3972, 0x6857,
-+	0x0001, 0x6e62, 0x0078, 0x397e, 0x1078, 0x37d1, 0x1078, 0x3994,
-+	0x00c0, 0x397c, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
-+	0x0078, 0x3984, 0x127e, 0x2091, 0x8000, 0x1078, 0x4960, 0x127f,
-+	0x007c, 0xa01e, 0x0078, 0x3996, 0x2019, 0x0001, 0xa00e, 0x127e,
-+	0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, 0x39b4,
-+	0x8dff, 0x0040, 0x39c9, 0x83ff, 0x0040, 0x39ac, 0x6848, 0xa606,
-+	0x0040, 0x39b9, 0x0078, 0x39b4, 0x683c, 0xa406, 0x00c0, 0x39b4,
-+	0x6840, 0xa506, 0x0040, 0x39b9, 0x2d08, 0x6800, 0x2068, 0x0078,
-+	0x39a0, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x39c1, 0x624e, 0x0078,
-+	0x39c4, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x39c9, 0x6152,
-+	0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x39d0, 0x2019, 0x0001,
-+	0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x39fc, 0x83ff, 0x0040,
-+	0x39df, 0x6848, 0xa606, 0x0040, 0x39ec, 0x0078, 0x39e7, 0x683c,
-+	0xa406, 0x00c0, 0x39e7, 0x6840, 0xa506, 0x0040, 0x39ec, 0x2d08,
-+	0x6800, 0x2068, 0x0078, 0x39d3, 0x6a00, 0x6080, 0xad06, 0x00c0,
-+	0x39f4, 0x6282, 0x0078, 0x39f7, 0xa180, 0x0000, 0x2202, 0x82ff,
-+	0x00c0, 0x39fc, 0x6186, 0x8dff, 0x007c, 0x1078, 0x3a55, 0x00c0,
-+	0x3a03, 0x2011, 0x0001, 0x1078, 0x3aa5, 0x00c0, 0x3a09, 0xa295,
-+	0x0002, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a12, 0x1078, 0x6b2b,
-+	0x0078, 0x3a14, 0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040,
-+	0x3a1d, 0x1078, 0x6aba, 0x0078, 0x3a1f, 0xa085, 0x0001, 0x007c,
-+	0x1078, 0x3add, 0x0040, 0x3a28, 0x1078, 0x6b00, 0x0078, 0x3a2a,
-+	0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a33, 0x1078,
-+	0x6ad6, 0x0078, 0x3a35, 0xa085, 0x0001, 0x007c, 0x127e, 0x007e,
-+	0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0040, 0x3a4d, 0x6800,
-+	0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54,
-+	0x1078, 0x3b92, 0x007f, 0x0078, 0x3a3c, 0x6083, 0x0000, 0x6087,
-+	0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0,
-+	0x3a5c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005,
-+	0x00c0, 0x3a6f, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, 0xa606,
-+	0x0040, 0x3a6f, 0x8108, 0x00f0, 0x3a66, 0xa085, 0x0001, 0x0e7f,
-+	0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0,
-+	0x3a7f, 0x1078, 0x130c, 0x0040, 0x3a91, 0x2d00, 0x60a6, 0x6803,
-+	0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
-+	0xffff, 0x8108, 0x00f0, 0x3a87, 0xa085, 0x0001, 0x127f, 0x0d7f,
-+	0x007c, 0xa006, 0x0078, 0x3a8e, 0x0d7e, 0x127e, 0x2091, 0x8000,
-+	0x60a4, 0xa06d, 0x0040, 0x3aa2, 0x60a7, 0x0000, 0x1078, 0x1340,
-+	0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0,
-+	0x3aac, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005,
-+	0x00c0, 0x3abf, 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606,
-+	0x0040, 0x3abf, 0x8108, 0x00f0, 0x3ab6, 0xa085, 0x0001, 0x0e7f,
-+	0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3aa5, 0x00c0, 0x3adb,
-+	0x200b, 0xffff, 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002,
-+	0x0048, 0x3ad6, 0x8001, 0x6856, 0x0078, 0x3ada, 0x1078, 0x1340,
-+	0x60ab, 0x0000, 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c,
-+	0x0f7e, 0x2079, 0x7751, 0x7804, 0xd0a4, 0x0040, 0x3b09, 0x157e,
-+	0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c,
-+	0x00c0, 0x3afd, 0x6004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006,
-+	0x00c0, 0x3afd, 0x6000, 0xc0ed, 0x6002, 0x017f, 0x8108, 0x00f0,
-+	0x3aed, 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, 0x3b0b, 0x1078,
-+	0x4719, 0x0f7f, 0x007c, 0x2011, 0x3b0b, 0x1078, 0x4689, 0x157e,
-+	0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c,
-+	0x00c0, 0x3b37, 0x6000, 0xd0ec, 0x0040, 0x3b37, 0x047e, 0x62a0,
-+	0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x7641,
-+	0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x2019, 0x0029, 0x1078, 0x4a7e,
-+	0x1078, 0x49c1, 0x2009, 0x0000, 0x1078, 0x747b, 0x047f, 0x017f,
-+	0x8108, 0x00f0, 0x3b15, 0x0c7f, 0x157f, 0x007c, 0x0c7e, 0x6018,
-+	0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x2071, 0x77ff,
-+	0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000,
-+	0x701b, 0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000,
-+	0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x007c, 0x0e7e,
-+	0x2071, 0x77ff, 0x684c, 0xa005, 0x00c0, 0x3b6d, 0x7028, 0xc085,
-+	0x702a, 0xa085, 0x0001, 0x0078, 0x3b90, 0x6a60, 0x7236, 0x6b64,
-+	0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
-+	0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006,
-+	0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
-+	0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
-+	0x0e7f, 0x007c, 0x0e7e, 0x6838, 0xd0fc, 0x00c0, 0x3be3, 0x6804,
-+	0xa00d, 0x0040, 0x3bb1, 0x0d7e, 0x0e7e, 0x2071, 0x7700, 0x027e,
-+	0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff,
-+	0x00c0, 0x3ba2, 0x702e, 0x70a0, 0xa200, 0x70a2, 0x027f, 0x0e7f,
-+	0x0d7f, 0x2071, 0x77ff, 0x701c, 0xa005, 0x00c0, 0x3bf4, 0x0068,
-+	0x3bf2, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3bf2, 0x6934,
-+	0xa186, 0x0103, 0x00c0, 0x3c05, 0x6948, 0x6844, 0xa105, 0x00c0,
-+	0x3be5, 0x2009, 0x8020, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0,
-+	0x3bf2, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001,
-+	0x2091, 0x4080, 0x2071, 0x7700, 0x702c, 0x206a, 0x2d00, 0x702e,
-+	0x70a0, 0x8000, 0x70a2, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100,
-+	0x00c0, 0x3bf2, 0x6868, 0xa005, 0x00c0, 0x3bf2, 0x2009, 0x8020,
-+	0x0078, 0x3bcb, 0x2071, 0x77ff, 0x2d08, 0x206b, 0x0000, 0x7010,
-+	0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x3c02, 0x6902,
-+	0x0078, 0x3c03, 0x711e, 0x0078, 0x3be3, 0xa18c, 0x00ff, 0xa186,
-+	0x0017, 0x0040, 0x3c13, 0xa186, 0x001e, 0x0040, 0x3c13, 0xa18e,
-+	0x001f, 0x00c0, 0x3bf2, 0x684c, 0xd0cc, 0x0040, 0x3bf2, 0x6850,
-+	0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x3bf2, 0x2009, 0x8021,
-+	0x0078, 0x3bcb, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
-+	0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0x684a, 0x6952,
-+	0x007c, 0x2071, 0x77ff, 0x7004, 0x0079, 0x3c36, 0x3c3e, 0x3c4d,
-+	0x3cdd, 0x3cde, 0x3cee, 0x3cf4, 0x3c3f, 0x3ccb, 0x007c, 0x127e,
-+	0x2091, 0x8000, 0x0068, 0x3c4c, 0x2009, 0x000d, 0x7030, 0x200a,
-+	0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x701c, 0xa06d, 0x0040,
-+	0x3cca, 0x0e7e, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3cac,
-+	0x6934, 0xa186, 0x0103, 0x00c0, 0x3c82, 0x6948, 0x6844, 0xa105,
-+	0x00c0, 0x3c9f, 0x2009, 0x8020, 0x127e, 0x2091, 0x8000, 0x0068,
-+	0x3c7e, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x3c7e, 0x7122,
-+	0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x127f, 0x0e7f, 0x1078, 0x3d27, 0x0078, 0x3cca, 0x127f, 0x0e7f,
-+	0x0078, 0x3cca, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, 0x3c90,
-+	0xa186, 0x001e, 0x0040, 0x3c90, 0xa18e, 0x001f, 0x00c0, 0x3cac,
-+	0x684c, 0xd0cc, 0x0040, 0x3cac, 0x6850, 0xa084, 0x00ff, 0xa086,
-+	0x0001, 0x00c0, 0x3cac, 0x2009, 0x8021, 0x0078, 0x3c64, 0x6844,
-+	0xa086, 0x0100, 0x00c0, 0x3cac, 0x6868, 0xa005, 0x00c0, 0x3cac,
-+	0x2009, 0x8020, 0x0078, 0x3c64, 0x0e7f, 0x1078, 0x3d3b, 0x0040,
-+	0x3cca, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
-+	0x00c0, 0x3cc1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x3cc1,
-+	0x710e, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050, 0xa086, 0x0100,
-+	0x0040, 0x3cde, 0x007c, 0x701c, 0xa06d, 0x0040, 0x3cdc, 0x1078,
-+	0x3d3b, 0x0040, 0x3cdc, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050,
-+	0xa086, 0x0100, 0x0040, 0x3cde, 0x007c, 0x007c, 0x7050, 0xa09e,
-+	0x0100, 0x00c0, 0x3ce7, 0x7007, 0x0004, 0x0078, 0x3cee, 0xa086,
-+	0x0200, 0x00c0, 0x3ced, 0x7007, 0x0005, 0x007c, 0x1078, 0x3cf5,
-+	0x7006, 0x1078, 0x3d27, 0x007c, 0x007c, 0x702c, 0x7130, 0x8108,
-+	0xa102, 0x0048, 0x3d02, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
-+	0x0078, 0x3d0c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x3d0c,
-+	0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
-+	0x00c0, 0x3d20, 0x127e, 0x2091, 0x8000, 0x0068, 0x3d23, 0x2001,
-+	0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x127f, 0x007c,
-+	0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x127f, 0x007c, 0x701c,
-+	0xa06d, 0x0040, 0x3d3a, 0x127e, 0x2091, 0x8000, 0x7010, 0x8001,
-+	0x7012, 0x2d04, 0x701e, 0xa005, 0x00c0, 0x3d37, 0x701a, 0x127f,
-+	0x1078, 0x1340, 0x007c, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e,
-+	0x0040, 0x3d4a, 0x2304, 0x230c, 0xa10e, 0x0040, 0x3d4a, 0xa006,
-+	0x0078, 0x3d5a, 0x732c, 0x8319, 0x7130, 0xa102, 0x00c0, 0x3d54,
-+	0x2300, 0xa005, 0x0078, 0x3d5a, 0x0048, 0x3d59, 0xa302, 0x0078,
-+	0x3d5a, 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056,
-+	0x7053, 0x0000, 0x127e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104,
-+	0xc08d, 0x200a, 0x127f, 0x1078, 0x1391, 0x007c, 0x2071, 0x77cd,
-+	0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001,
-+	0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040,
-+	0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000,
-+	0x007c, 0x0e7e, 0x2071, 0x77cd, 0x6848, 0xa005, 0x00c0, 0x3d97,
-+	0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, 0x3dbc, 0x6a50,
-+	0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042,
-+	0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a,
-+	0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210,
-+	0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007,
-+	0x0001, 0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071,
-+	0x77cd, 0x7004, 0x1079, 0x3e1c, 0x700c, 0x0079, 0x3dc7, 0x3dcc,
-+	0x3dc1, 0x3dc1, 0x3dc1, 0x3dc1, 0x007c, 0x700c, 0x0079, 0x3dd0,
-+	0x3dd5, 0x3e1a, 0x3e1a, 0x3e1b, 0x3e1b, 0x7830, 0x7930, 0xa106,
-+	0x0040, 0x3ddf, 0x7830, 0x7930, 0xa106, 0x00c0, 0x3e05, 0x7030,
-+	0xa10a, 0x0040, 0x3e05, 0x00c8, 0x3de7, 0x712c, 0xa10a, 0xa18a,
-+	0x0002, 0x00c8, 0x3e06, 0x1078, 0x130c, 0x0040, 0x3e05, 0x2d00,
-+	0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x127e,
-+	0x007e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104, 0xc085, 0x200a,
-+	0x007f, 0x700e, 0x127f, 0x1078, 0x1391, 0x007c, 0x1078, 0x130c,
-+	0x0040, 0x3e05, 0x2d00, 0x705a, 0x1078, 0x130c, 0x00c0, 0x3e12,
-+	0x0078, 0x3df1, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004,
-+	0x0078, 0x3df5, 0x007c, 0x007c, 0x3e2d, 0x3e2e, 0x3e65, 0x3e66,
-+	0x3e1a, 0x3e9c, 0x3ea1, 0x3ed8, 0x3ed9, 0x3ef4, 0x3ef5, 0x3ef6,
-+	0x3ef7, 0x3ef8, 0x3ef9, 0x3f62, 0x3f8c, 0x007c, 0x700c, 0x0079,
-+	0x3e31, 0x3e36, 0x3e39, 0x3e49, 0x3e64, 0x3e64, 0x1078, 0x3dcd,
-+	0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x426e,
-+	0x0040, 0x3e46, 0x2091, 0x8000, 0x1078, 0x3dcd, 0x0d7f, 0x0078,
-+	0x3e52, 0x127e, 0x8001, 0x700e, 0x1078, 0x426e, 0x7058, 0x2068,
-+	0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084,
-+	0x00ff, 0xa08a, 0x0020, 0x00c8, 0x3e61, 0x1079, 0x3e7c, 0x127f,
-+	0x007c, 0x127f, 0x1078, 0x3efa, 0x007c, 0x007c, 0x007c, 0x0e7e,
-+	0x2071, 0x77cd, 0x700c, 0x0079, 0x3e6d, 0x3e72, 0x3e72, 0x3e72,
-+	0x3e74, 0x3e78, 0x0e7f, 0x007c, 0x700f, 0x0001, 0x0078, 0x3e7a,
-+	0x700f, 0x0002, 0x0e7f, 0x007c, 0x3efa, 0x3efa, 0x3f16, 0x3efa,
-+	0x4001, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x4040,
-+	0x408a, 0x40e3, 0x40f7, 0x3efa, 0x3efa, 0x3f32, 0x3f16, 0x3efa,
-+	0x3efa, 0x3f48, 0x4182, 0x41a0, 0x3efa, 0x3f32, 0x3efa, 0x3efa,
-+	0x3efa, 0x3efa, 0x3f48, 0x41a0, 0x7020, 0x2068, 0x1078, 0x1340,
-+	0x007c, 0x700c, 0x0079, 0x3ea4, 0x3ea9, 0x3eac, 0x3ebc, 0x3ed7,
-+	0x3ed7, 0x1078, 0x3dcd, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058,
-+	0x007e, 0x1078, 0x426e, 0x0040, 0x3eb9, 0x2091, 0x8000, 0x1078,
-+	0x3dcd, 0x0d7f, 0x0078, 0x3ec5, 0x127e, 0x8001, 0x700e, 0x1078,
-+	0x426e, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807,
-+	0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x3ed4,
-+	0x1079, 0x3eda, 0x127f, 0x007c, 0x127f, 0x1078, 0x3efa, 0x007c,
-+	0x007c, 0x007c, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3f16, 0x3efa,
-+	0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3f16, 0x3f16, 0x3f16,
-+	0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3efa, 0x3f16,
-+	0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x007c, 0x007c, 0x007c, 0x007c,
-+	0x007c, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5,
-+	0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c,
-+	0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001,
-+	0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
-+	0x00ff, 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92,
-+	0x127f, 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3f08,
-+	0x8001, 0x00c0, 0x3f3f, 0x7007, 0x0001, 0x0078, 0x3fc8, 0x7007,
-+	0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x3fc8, 0x007c,
-+	0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098,
-+	0x20a1, 0x77f8, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8,
-+	0x3f24, 0x6884, 0xa08a, 0x0003, 0x00c8, 0x3f24, 0xa080, 0x3fb9,
-+	0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, 0x3fac, 0x1078, 0x130c,
-+	0x00c0, 0x3f6d, 0x7007, 0x000f, 0x007c, 0x2d00, 0x7022, 0x70c4,
-+	0x2060, 0x6000, 0x6836, 0x6004, 0xad00, 0x7096, 0x6008, 0xa20a,
-+	0x00c8, 0x3f7c, 0xa00e, 0x2200, 0x7112, 0x620c, 0x8003, 0x800b,
-+	0xa296, 0x0004, 0x0040, 0x3f85, 0xa108, 0x719a, 0x810b, 0x719e,
-+	0xae90, 0x0022, 0x1078, 0x1377, 0x7090, 0xa08e, 0x0100, 0x0040,
-+	0x3fa0, 0xa086, 0x0200, 0x0040, 0x3f98, 0x7007, 0x0010, 0x007c,
-+	0x7020, 0x2068, 0x1078, 0x1340, 0x7014, 0x2068, 0x0078, 0x3f24,
-+	0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068,
-+	0x6906, 0x711a, 0x0078, 0x3f62, 0x7014, 0x2068, 0x7007, 0x0001,
-+	0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, 0x41bd, 0x0078,
-+	0x3fc8, 0x3fbc, 0x3fc0, 0x3fc4, 0x0002, 0x0011, 0x0007, 0x0004,
-+	0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, 0x0005, 0x0006,
-+	0x2009, 0x772c, 0x210c, 0x81ff, 0x00c0, 0x3fe5, 0x6838, 0xa084,
-+	0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3691, 0x00c0, 0x3fd9,
-+	0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000, 0x1078, 0x6c54,
-+	0x1078, 0x3b92, 0x127f, 0x0078, 0x3fd8, 0x2001, 0x0028, 0x2009,
-+	0x0000, 0x0078, 0x3fd9, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906,
-+	0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x3ffa, 0x7007, 0x0006,
-+	0x0078, 0x4000, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a,
-+	0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848,
-+	0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x402a,
-+	0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, 0x0002, 0x0040, 0x402a,
-+	0xa005, 0x00c0, 0x403d, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078,
-+	0x384c, 0x00c0, 0x403d, 0x067e, 0x6e50, 0x1078, 0x3915, 0x067f,
-+	0x0078, 0x403d, 0x047e, 0x2011, 0x770c, 0x2224, 0xc484, 0xc48c,
-+	0x2412, 0x047f, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x4039, 0x1078,
-+	0x3a94, 0x8108, 0x00f0, 0x4033, 0x0c7f, 0x1078, 0x1340, 0x007c,
-+	0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x7752, 0x2004,
-+	0xd0a4, 0x0040, 0x4081, 0x2009, 0x0000, 0x1078, 0x428a, 0x6100,
-+	0xd184, 0x0040, 0x4066, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x4084,
-+	0x6000, 0xd084, 0x0040, 0x4081, 0x6004, 0xa005, 0x00c0, 0x4087,
-+	0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x407e, 0x2011, 0x0001,
-+	0x6860, 0xa005, 0x00c0, 0x406e, 0x2001, 0x001e, 0x8000, 0x6016,
-+	0x6858, 0xa084, 0x00ff, 0x0040, 0x4081, 0x6006, 0x6858, 0x8007,
-+	0xa084, 0x00ff, 0x0040, 0x4081, 0x600a, 0x6202, 0x127f, 0x0078,
-+	0x425d, 0x127f, 0x0078, 0x4255, 0x127f, 0x0078, 0x424d, 0x127f,
-+	0x0078, 0x4251, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
-+	0x7752, 0x2004, 0xd0a4, 0x0040, 0x40e0, 0x2009, 0x0000, 0x1078,
-+	0x428a, 0x6000, 0xa084, 0x0001, 0x0040, 0x40e0, 0x6204, 0x6308,
-+	0x6c48, 0xa484, 0x0003, 0x0040, 0x40b8, 0x6958, 0xa18c, 0x00ff,
-+	0x8001, 0x00c0, 0x40b1, 0x2100, 0xa210, 0x0048, 0x40dd, 0x0078,
-+	0x40b8, 0x8001, 0x00c0, 0x40dd, 0x2100, 0xa212, 0x0048, 0x40dd,
-+	0xa484, 0x000c, 0x0040, 0x40d2, 0x6958, 0x810f, 0xa18c, 0x00ff,
-+	0xa082, 0x0004, 0x00c0, 0x40ca, 0x2100, 0xa318, 0x0048, 0x40dd,
-+	0x0078, 0x40d2, 0xa082, 0x0004, 0x00c0, 0x40dd, 0x2100, 0xa31a,
-+	0x0048, 0x40dd, 0x6860, 0xa005, 0x0040, 0x40d8, 0x8000, 0x6016,
-+	0x6206, 0x630a, 0x127f, 0x0078, 0x425d, 0x127f, 0x0078, 0x4259,
-+	0x127f, 0x0078, 0x4255, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001,
-+	0x2009, 0x0000, 0x1078, 0x428a, 0x6308, 0x8318, 0x0048, 0x40f4,
-+	0x630a, 0x127f, 0x0078, 0x426b, 0x127f, 0x0078, 0x4259, 0x127e,
-+	0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040,
-+	0x410d, 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0x2001,
-+	0xfcff, 0x6002, 0x0c7f, 0x0078, 0x4144, 0x6858, 0xa005, 0x0040,
-+	0x4159, 0x685c, 0xa065, 0x0040, 0x4155, 0x2001, 0x772c, 0x2004,
-+	0xa005, 0x0040, 0x411f, 0x1078, 0x6bb6, 0x0078, 0x4125, 0x6013,
-+	0x0400, 0x2009, 0x0041, 0x1078, 0x5d41, 0x6958, 0xa18c, 0xe600,
-+	0xa186, 0x2000, 0x0040, 0x413c, 0xa186, 0x0400, 0x0040, 0x413c,
-+	0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0xa084, 0xfdff,
-+	0x6002, 0x0c7f, 0x0078, 0x4144, 0x027e, 0x2009, 0x0000, 0x2011,
-+	0xfdff, 0x1078, 0x47d0, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x4151,
-+	0x2009, 0x0000, 0x1078, 0x4727, 0x6008, 0x8000, 0x0048, 0x4151,
-+	0x600a, 0x0c7f, 0x127f, 0x0078, 0x425d, 0x0c7f, 0x127f, 0x0078,
-+	0x4255, 0x6954, 0xa186, 0x002a, 0x00c0, 0x4165, 0x2001, 0x770c,
-+	0x200c, 0xc194, 0x2102, 0x0078, 0x4144, 0xa186, 0x0020, 0x0040,
-+	0x417a, 0xa186, 0x0029, 0x00c0, 0x4155, 0x6944, 0xa18c, 0xff00,
-+	0x810f, 0x1078, 0x384c, 0x00c0, 0x4144, 0x6000, 0xc0e4, 0x6002,
-+	0x0078, 0x4144, 0x685c, 0xa065, 0x0040, 0x4155, 0x6017, 0x0014,
-+	0x0078, 0x4144, 0x2009, 0x0000, 0x1078, 0x428a, 0x6000, 0xa084,
-+	0x0001, 0x0040, 0x419c, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048,
-+	0x4196, 0x6206, 0x2091, 0x8001, 0x0078, 0x426b, 0x2091, 0x8001,
-+	0x6853, 0x0016, 0x0078, 0x4264, 0x6853, 0x0007, 0x0078, 0x4264,
-+	0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x41aa, 0x1078, 0x3f08,
-+	0x0078, 0x41bc, 0x2030, 0x8001, 0x00c0, 0x41b4, 0x7007, 0x0001,
-+	0x1078, 0x41bd, 0x0078, 0x41bc, 0x7007, 0x0006, 0x7012, 0x2d00,
-+	0x7016, 0x701a, 0x704b, 0x41bd, 0x007c, 0x0e7e, 0x2009, 0x772c,
-+	0x210c, 0x81ff, 0x00c0, 0x423f, 0x2009, 0x770c, 0x210c, 0xd194,
-+	0x00c0, 0x4249, 0x6848, 0x2070, 0xae82, 0x7e00, 0x0048, 0x422e,
-+	0x2001, 0x7715, 0x2004, 0xae02, 0x00c8, 0x422e, 0x2009, 0x0000,
-+	0x1078, 0x428a, 0x6100, 0xa184, 0x0001, 0x0040, 0x4214, 0xa184,
-+	0x0100, 0x00c0, 0x4232, 0xa184, 0x0200, 0x00c0, 0x4236, 0x601c,
-+	0xa005, 0x00c0, 0x423a, 0x711c, 0xa186, 0x0006, 0x00c0, 0x4219,
-+	0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x127e, 0x2091, 0x8000,
-+	0x7010, 0xa005, 0x00c0, 0x420b, 0x7112, 0x7018, 0xa065, 0x0040,
-+	0x423e, 0x6000, 0xd0e4, 0x00c0, 0x4243, 0x2e60, 0x1078, 0x4730,
-+	0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x420b,
-+	0x6902, 0x127f, 0x0e7f, 0x007c, 0x0e7f, 0x6853, 0x0006, 0x0078,
-+	0x4264, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x384c, 0x00c0,
-+	0x4244, 0x6000, 0xd0e4, 0x00c0, 0x4244, 0x711c, 0xa186, 0x0007,
-+	0x00c0, 0x422e, 0x6853, 0x0002, 0x0078, 0x4246, 0x6853, 0x0008,
-+	0x0078, 0x4246, 0x6853, 0x000e, 0x0078, 0x4246, 0x6853, 0x0017,
-+	0x0078, 0x4246, 0x6853, 0x0035, 0x0078, 0x4246, 0x127f, 0x6853,
-+	0x0028, 0x0078, 0x4246, 0x127f, 0x6853, 0x0029, 0x0e7f, 0x0078,
-+	0x4264, 0x6853, 0x002a, 0x0078, 0x4246, 0x2009, 0x003e, 0x0078,
-+	0x425f, 0x2009, 0x0004, 0x0078, 0x425f, 0x2009, 0x0006, 0x0078,
-+	0x425f, 0x2009, 0x0016, 0x0078, 0x425f, 0x2009, 0x0001, 0x6854,
-+	0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x3b92,
-+	0x2091, 0x8001, 0x007c, 0x1078, 0x1340, 0x007c, 0x702c, 0x7130,
-+	0x8108, 0xa102, 0x0048, 0x427b, 0xa00e, 0x7034, 0x7072, 0x7038,
-+	0x7076, 0x0078, 0x4287, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8,
-+	0x4287, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932,
-+	0x7132, 0x007c, 0x0d7e, 0x1078, 0x4727, 0x0d7f, 0x007c, 0x0d7e,
-+	0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x0d7f, 0x007c,
-+	0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000,
-+	0x0040, 0x42a6, 0xa086, 0x1000, 0x00c0, 0x42c2, 0x20e1, 0x0004,
-+	0x3d60, 0xd1bc, 0x00c0, 0x42ad, 0x3e60, 0xac84, 0x0007, 0x00c0,
-+	0x42c2, 0xac82, 0x7e00, 0x0048, 0x42c2, 0x6854, 0xac02, 0x00c8,
-+	0x42c2, 0x2009, 0x0047, 0x1078, 0x5d41, 0x7a1c, 0xd284, 0x00c0,
-+	0x4298, 0x007c, 0xa016, 0x1078, 0x156a, 0x0078, 0x42bd, 0x157e,
-+	0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0070,
-+	0x00c0, 0x42f0, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x42f0,
-+	0x1078, 0x42fd, 0x0040, 0x42f0, 0x20e1, 0x3000, 0x7828, 0x7828,
-+	0x1078, 0x431b, 0x147f, 0x137f, 0x157f, 0x2009, 0x793e, 0x2104,
-+	0xa005, 0x00c0, 0x42ec, 0x007c, 0x1078, 0x4d96, 0x0078, 0x42eb,
-+	0x1078, 0x7674, 0x1078, 0x42fd, 0x20e1, 0x3000, 0x7828, 0x7828,
-+	0x147f, 0x137f, 0x157f, 0x0078, 0x42eb, 0xa484, 0x01ff, 0x687a,
-+	0xa005, 0x0040, 0x430f, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
-+	0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9,
-+	0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
-+	0x0001, 0x0078, 0x430e, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000,
-+	0x8007, 0xa196, 0x0000, 0x00c0, 0x4328, 0x0078, 0x449c, 0x007c,
-+	0xa196, 0x2000, 0x00c0, 0x4339, 0x6900, 0xa18e, 0x0001, 0x00c0,
-+	0x4335, 0x1078, 0x2ec1, 0x0078, 0x4327, 0x1078, 0x4341, 0x0078,
-+	0x4327, 0xa196, 0x8000, 0x00c0, 0x4327, 0x1078, 0x4522, 0x0078,
-+	0x4327, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001,
-+	0x0040, 0x434e, 0xa196, 0x0023, 0x00c0, 0x4443, 0xa08e, 0x0023,
-+	0x00c0, 0x437f, 0x1078, 0x4599, 0x0040, 0x4443, 0x7124, 0x610a,
-+	0x7030, 0xa08e, 0x0200, 0x00c0, 0x4367, 0x7034, 0xa005, 0x00c0,
-+	0x4443, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e,
-+	0x0210, 0x00c0, 0x4371, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078,
-+	0x4443, 0xa08e, 0x0100, 0x00c0, 0x4443, 0x7034, 0xa005, 0x00c0,
-+	0x4443, 0x2009, 0x0016, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e,
-+	0x0022, 0x00c0, 0x4443, 0x7030, 0xa08e, 0x0300, 0x00c0, 0x4390,
-+	0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0017, 0x0078, 0x440f,
-+	0xa08e, 0x0500, 0x00c0, 0x439c, 0x7034, 0xa005, 0x00c0, 0x4443,
-+	0x2009, 0x0018, 0x0078, 0x440f, 0xa08e, 0x2010, 0x00c0, 0x43a4,
-+	0x2009, 0x0019, 0x0078, 0x440f, 0xa08e, 0x2110, 0x00c0, 0x43ac,
-+	0x2009, 0x001a, 0x0078, 0x440f, 0xa08e, 0x5200, 0x00c0, 0x43b8,
-+	0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x001b, 0x0078, 0x440f,
-+	0xa08e, 0x5000, 0x00c0, 0x43c4, 0x7034, 0xa005, 0x00c0, 0x4443,
-+	0x2009, 0x001c, 0x0078, 0x440f, 0xa08e, 0x1200, 0x00c0, 0x43d0,
-+	0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0024, 0x0078, 0x440f,
-+	0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0, 0x43da, 0x2009, 0x002d,
-+	0x0078, 0x440f, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x00c0, 0x43e4,
-+	0x2009, 0x002a, 0x0078, 0x440f, 0xa08e, 0x0f00, 0x00c0, 0x43ec,
-+	0x2009, 0x0020, 0x0078, 0x440f, 0xa08e, 0x5300, 0x00c0, 0x43f2,
-+	0x0078, 0x440d, 0xa08e, 0x6104, 0x00c0, 0x440d, 0x2011, 0x7c8d,
-+	0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011,
-+	0x8015, 0x211c, 0x8108, 0x2124, 0x1078, 0x2d59, 0x8108, 0x00f0,
-+	0x43ff, 0x2009, 0x0023, 0x0078, 0x440f, 0x2009, 0x001d, 0x017e,
-+	0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0,
-+	0x4445, 0x1078, 0x3811, 0x00c0, 0x4445, 0x6612, 0x6516, 0x86ff,
-+	0x0040, 0x4435, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x4435,
-+	0x6864, 0xa606, 0x00c0, 0x4435, 0x6868, 0xa506, 0xa084, 0xff00,
-+	0x00c0, 0x4435, 0x6000, 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x5cb4,
-+	0x0040, 0x4448, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a,
-+	0x017f, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x017f, 0x0078, 0x4443,
-+	0x0c7f, 0x0078, 0x4445, 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696,
-+	0x00ff, 0x00c0, 0x446b, 0xa596, 0xfffd, 0x00c0, 0x445b, 0x2009,
-+	0x007f, 0x0078, 0x4498, 0xa596, 0xfffe, 0x00c0, 0x4463, 0x2009,
-+	0x007e, 0x0078, 0x4498, 0xa596, 0xfffc, 0x00c0, 0x446b, 0x2009,
-+	0x0080, 0x0078, 0x4498, 0x2011, 0x0000, 0x2021, 0x007e, 0x20a9,
-+	0x0082, 0x2071, 0x789e, 0x2e1c, 0x83ff, 0x00c0, 0x447d, 0x82ff,
-+	0x00c0, 0x448c, 0x2410, 0x0078, 0x448c, 0x2368, 0x6b10, 0x007e,
-+	0x2100, 0xa31e, 0x007f, 0x00c0, 0x448c, 0x6b14, 0xa31e, 0x00c0,
-+	0x448c, 0x2408, 0x0078, 0x4498, 0x8420, 0x8e70, 0x00f0, 0x4473,
-+	0x82ff, 0x00c0, 0x4497, 0xa085, 0x0001, 0x0078, 0x4499, 0x2208,
-+	0xa006, 0x0d7f, 0x0e7f, 0x007c, 0xa084, 0x0007, 0x0079, 0x44a1,
-+	0x007c, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44aa, 0x44c3,
-+	0x450b, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x44c2, 0x7120, 0x2160,
-+	0xac8c, 0x0007, 0x00c0, 0x44c2, 0xac8a, 0x7e00, 0x0048, 0x44c2,
-+	0x6854, 0xac02, 0x00c8, 0x44c2, 0x7124, 0x610a, 0x2009, 0x0046,
-+	0x1078, 0x5d41, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x4509,
-+	0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0,
-+	0x4509, 0x1078, 0x384c, 0x00c0, 0x4509, 0x6204, 0xa294, 0xff00,
-+	0x8217, 0xa286, 0x0006, 0x00c0, 0x44ee, 0x0c7e, 0x1078, 0x5cb4,
-+	0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
-+	0x2009, 0x0044, 0x1078, 0x5d41, 0x0078, 0x4509, 0x0c7e, 0x1078,
-+	0x5cb4, 0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0004, 0x7120,
-+	0x610a, 0xa286, 0x0004, 0x00c0, 0x4501, 0x6007, 0x0005, 0x0078,
-+	0x4503, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078,
-+	0x4d96, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4521, 0x7020,
-+	0x2060, 0xac84, 0x0007, 0x00c0, 0x4521, 0xac82, 0x7e00, 0x0048,
-+	0x4521, 0x6854, 0xac02, 0x00c8, 0x4521, 0x2009, 0x0045, 0x1078,
-+	0x5d41, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
-+	0x00c0, 0x4532, 0xa084, 0x000f, 0xa08a, 0x0006, 0x10c8, 0x12cd,
-+	0x1079, 0x4533, 0x007c, 0x4539, 0x453a, 0x4539, 0x4539, 0x457b,
-+	0x458a, 0x007c, 0x7110, 0xd1bc, 0x00c0, 0x457a, 0x700c, 0x7108,
-+	0x1078, 0x207f, 0x00c0, 0x457a, 0x1078, 0x3811, 0x00c0, 0x457a,
-+	0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
-+	0x00c0, 0x4563, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x457a,
-+	0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x1078,
-+	0x5d41, 0x0078, 0x457a, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040,
-+	0x457a, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
-+	0x00c0, 0x4576, 0x2009, 0x0005, 0x0078, 0x4578, 0x2009, 0x0001,
-+	0x1078, 0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4589, 0x1078,
-+	0x4599, 0x0040, 0x4589, 0x7124, 0x610a, 0x2009, 0x0089, 0x1078,
-+	0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4598, 0x1078, 0x4599,
-+	0x0040, 0x4598, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078, 0x5d41,
-+	0x007c, 0x7020, 0x2060, 0xac84, 0x0007, 0x00c0, 0x45ac, 0xac82,
-+	0x7e00, 0x0048, 0x45ac, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8,
-+	0x45ac, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x45ab, 0x2071,
-+	0x7949, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
-+	0x7017, 0x7e00, 0x7007, 0x0000, 0x7026, 0x702b, 0x56a9, 0x7032,
-+	0x7037, 0x56ea, 0x703b, 0x0002, 0x703f, 0x0000, 0x007c, 0x2071,
-+	0x7949, 0x00e0, 0x4676, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e,
-+	0x00c0, 0x463f, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091,
-+	0x8000, 0x7138, 0x8109, 0x713a, 0x00c0, 0x463d, 0x703b, 0x0002,
-+	0x2009, 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x463d, 0x703c,
-+	0xa086, 0x0001, 0x00c0, 0x461a, 0x0d7e, 0x2069, 0x0140, 0x6804,
-+	0xa084, 0x4000, 0x0040, 0x45f8, 0x6803, 0x1000, 0x0078, 0x45ff,
-+	0x6804, 0xa084, 0x1000, 0x0040, 0x45ff, 0x6803, 0x0100, 0x6803,
-+	0x0000, 0x703f, 0x0000, 0x2069, 0x7936, 0x6804, 0xa082, 0x0006,
-+	0x00c0, 0x460c, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0,
-+	0x4613, 0x6833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56, 0x0d7f,
-+	0x0078, 0x463d, 0x0d7e, 0x2069, 0x7700, 0x6944, 0x6860, 0xa102,
-+	0x00c8, 0x463c, 0x2069, 0x7936, 0x6804, 0xa086, 0x0000, 0x00c0,
-+	0x463c, 0x6830, 0xa086, 0x0000, 0x00c0, 0x463c, 0x703f, 0x0001,
-+	0x6807, 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e,
-+	0x2069, 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x4642, 0x127e,
-+	0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x4653, 0x7020, 0x8001,
-+	0x7022, 0x00c0, 0x4653, 0x7023, 0x0009, 0x8109, 0x7126, 0x00c0,
-+	0x4653, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x4664, 0x702c,
-+	0x8001, 0x702e, 0x00c0, 0x4664, 0x702f, 0x0009, 0x8109, 0x7132,
-+	0x00c0, 0x4664, 0x7034, 0x107a, 0x7018, 0xa00d, 0x0040, 0x4675,
-+	0x7008, 0x8001, 0x700a, 0x00c0, 0x4675, 0x700b, 0x0009, 0x8109,
-+	0x711a, 0x00c0, 0x4675, 0x701c, 0x107a, 0x127f, 0x7004, 0x0079,
-+	0x4679, 0x46a0, 0x46a1, 0x46bd, 0x0e7e, 0x2071, 0x7949, 0x7018,
-+	0xa005, 0x00c0, 0x4687, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f,
-+	0x007c, 0x0e7e, 0x007e, 0x2071, 0x7949, 0x701c, 0xa206, 0x00c0,
-+	0x4693, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
-+	0x7949, 0x6088, 0xa102, 0x0048, 0x469e, 0x618a, 0x0e7f, 0x007c,
-+	0x007c, 0x7110, 0x1078, 0x384c, 0x00c0, 0x46b3, 0x6088, 0x8001,
-+	0x0048, 0x46b3, 0x608a, 0x00c0, 0x46b3, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x4d96, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, 0x46bb,
-+	0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, 0x127e,
-+	0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x46ec, 0x8001, 0x6016,
-+	0x00c0, 0x46ec, 0x611c, 0xa186, 0x0003, 0x0040, 0x46d3, 0xa186,
-+	0x0006, 0x00c0, 0x46ea, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a,
-+	0x0048, 0x46ea, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048,
-+	0x46e3, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
-+	0x0078, 0x46ec, 0x1078, 0x68e3, 0x127f, 0xac88, 0x0008, 0x7116,
-+	0x2001, 0x7716, 0x2004, 0xa102, 0x0048, 0x46fa, 0x7017, 0x7e00,
-+	0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7027, 0x07d0,
-+	0x7023, 0x0009, 0x703b, 0x0002, 0x0e7f, 0x007c, 0x2001, 0x7952,
-+	0x2003, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7033, 0x07d0,
-+	0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, 0x7955, 0x2013, 0x0000,
-+	0x007c, 0x0e7e, 0x2071, 0x7949, 0x711a, 0x721e, 0x700b, 0x0009,
-+	0x0e7f, 0x007c, 0x0c7e, 0x2061, 0x79da, 0x0c7f, 0x007c, 0xa184,
-+	0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x79da, 0x2060, 0x007c,
-+	0x6854, 0xa08a, 0x199a, 0x0048, 0x4737, 0x2001, 0x1999, 0xa005,
-+	0x00c0, 0x4747, 0x6944, 0x0c7e, 0x1078, 0x4727, 0x6014, 0x0c7f,
-+	0xa005, 0x00c0, 0x474c, 0x2001, 0x001e, 0x0078, 0x474c, 0xa08e,
-+	0xffff, 0x00c0, 0x474c, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108,
-+	0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x4787,
-+	0xd0b4, 0x00c0, 0x4763, 0xd0bc, 0x00c0, 0x4775, 0x2009, 0x0006,
-+	0x1078, 0x47aa, 0x007c, 0xd0fc, 0x0040, 0x4770, 0xa084, 0x0003,
-+	0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000, 0x00c0, 0x47a3,
-+	0x2009, 0x0043, 0x1078, 0x5d41, 0x007c, 0xd0fc, 0x0040, 0x4782,
-+	0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000,
-+	0x00c0, 0x47a3, 0x2009, 0x0042, 0x1078, 0x5d41, 0x007c, 0xd0fc,
-+	0x0040, 0x4799, 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3,
-+	0xa08e, 0x0002, 0x0040, 0x479d, 0x2009, 0x0041, 0x1078, 0x5d41,
-+	0x007c, 0x1078, 0x47a8, 0x0078, 0x4798, 0x2009, 0x0043, 0x1078,
-+	0x5d41, 0x0078, 0x4798, 0x2009, 0x0004, 0x1078, 0x47aa, 0x007c,
-+	0x2009, 0x0001, 0x6010, 0xa0ec, 0xf000, 0x0040, 0x47cf, 0x2068,
-+	0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, 0x47c9, 0x694c,
-+	0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x47c9, 0x0c7e, 0x2009,
-+	0x0000, 0x1078, 0x4727, 0x6204, 0x8210, 0x0048, 0x47c8, 0x6206,
-+	0x0c7f, 0x1078, 0x3b92, 0x6010, 0xa06d, 0x10c0, 0x4730, 0x007c,
-+	0x157e, 0x0c7e, 0x20a9, 0x0010, 0x2061, 0x79da, 0x6000, 0x81ff,
-+	0x0040, 0x47dd, 0xa205, 0x0078, 0x47de, 0xa204, 0x6002, 0xace0,
-+	0x0008, 0x00f0, 0x47d6, 0x0c7f, 0x157f, 0x007c, 0x6808, 0xa005,
-+	0x0040, 0x47ee, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x127e,
-+	0x2091, 0x2200, 0x2079, 0x7936, 0x127f, 0x0d7e, 0x2069, 0x7936,
-+	0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
-+	0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
-+	0x0079, 0x480a, 0x4814, 0x4839, 0x4894, 0x481a, 0x4839, 0x4812,
-+	0x4812, 0x4812, 0x1078, 0x12cd, 0x1078, 0x4706, 0x1078, 0x4d96,
-+	0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x4820, 0x0c7f, 0x007c,
-+	0x2011, 0x3558, 0x1078, 0x4689, 0x7828, 0xa092, 0x0002, 0x00c8,
-+	0x482f, 0x8000, 0x782a, 0x1078, 0x3588, 0x0078, 0x481e, 0x1078,
-+	0x3558, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
-+	0x481e, 0x1078, 0x4706, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
-+	0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x4857, 0x62c0,
-+	0x82ff, 0x00c0, 0x4857, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
-+	0x12cd, 0x2009, 0x0013, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x3900,
-+	0xa082, 0x7a7a, 0x00c8, 0x485e, 0x1078, 0x5c44, 0x0c7e, 0x7824,
-+	0xa065, 0x1040, 0x12cd, 0x7804, 0xa086, 0x0004, 0x0040, 0x48d9,
-+	0x7828, 0xa092, 0x2710, 0x00c8, 0x4874, 0x8000, 0x782a, 0x0c7f,
-+	0x1078, 0x568e, 0x0078, 0x4855, 0x6104, 0xa186, 0x0003, 0x00c0,
-+	0x488b, 0x0e7e, 0x2071, 0x7700, 0x70c8, 0x0e7f, 0xd08c, 0x0040,
-+	0x488b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700, 0x1078,
-+	0x3591, 0x0e7f, 0x0c7f, 0x1078, 0x76c7, 0x2009, 0x0014, 0x1078,
-+	0x5d41, 0x0c7f, 0x0078, 0x4855, 0x2001, 0x7952, 0x2003, 0x0000,
-+	0x62c0, 0x82ff, 0x00c0, 0x48a8, 0x782b, 0x0000, 0x7824, 0xa065,
-+	0x1040, 0x12cd, 0x2009, 0x0013, 0x1078, 0x5d8f, 0x0c7f, 0x007c,
-+	0x0c7e, 0x0d7e, 0x3900, 0xa082, 0x7a7a, 0x00c8, 0x48b1, 0x1078,
-+	0x5c44, 0x7824, 0xa005, 0x1040, 0x12cd, 0x781c, 0xa06d, 0x1040,
-+	0x12cd, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x5d1a,
-+	0x693c, 0x81ff, 0x1040, 0x12cd, 0x8109, 0x693e, 0x6854, 0xa015,
-+	0x0040, 0x48cd, 0x7a1e, 0x0078, 0x48cf, 0x7918, 0x791e, 0x7807,
-+	0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x4d96, 0x0078,
-+	0x48a6, 0x6104, 0xa186, 0x0002, 0x0040, 0x48e4, 0xa186, 0x0004,
-+	0x0040, 0x48e4, 0x0078, 0x4868, 0x7808, 0xac06, 0x0040, 0x4868,
-+	0x1078, 0x4c9d, 0x1078, 0x498e, 0x0c7f, 0x1078, 0x4d96, 0x0078,
-+	0x4855, 0x0c7e, 0x6027, 0x0002, 0x2011, 0x7955, 0x2013, 0x0000,
-+	0x62c8, 0x82ff, 0x00c0, 0x490b, 0x62c4, 0x82ff, 0x00c0, 0x490b,
-+	0x793c, 0xa1e5, 0x0000, 0x0040, 0x4909, 0x2009, 0x0049, 0x1078,
-+	0x5d41, 0x0c7f, 0x007c, 0x3908, 0xa192, 0x7a7a, 0x00c8, 0x4912,
-+	0x1078, 0x5c44, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x4909,
-+	0x7944, 0xa192, 0x7530, 0x00c8, 0x4931, 0x8108, 0x7946, 0x1078,
-+	0x470b, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0,
-+	0x492d, 0x6017, 0x0012, 0x0078, 0x4909, 0x6017, 0x0016, 0x0078,
-+	0x4909, 0x037e, 0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x1078,
-+	0x76c7, 0x793c, 0x2160, 0x2009, 0x004a, 0x1078, 0x5d41, 0x0078,
-+	0x4909, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f,
-+	0x0000, 0x2c08, 0x2061, 0x7936, 0x6020, 0x8000, 0x6022, 0x6010,
-+	0xa005, 0x0040, 0x495c, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f,
-+	0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x4957,
-+	0x0d7e, 0x2069, 0x7936, 0x6000, 0xd0d4, 0x0040, 0x4975, 0x6820,
-+	0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x4970, 0x2c00, 0x681e,
-+	0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0xc0d5, 0x6002, 0x6818,
-+	0xa005, 0x0040, 0x4987, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00,
-+	0x681a, 0x0d7f, 0x685a, 0x2069, 0x7936, 0x0078, 0x4967, 0x6056,
-+	0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x4967, 0x007e, 0x017e,
-+	0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
-+	0x7936, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x49a9,
-+	0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f,
-+	0x007c, 0x610e, 0x610a, 0x0078, 0x49a4, 0x0c7e, 0x600f, 0x0000,
-+	0x2c08, 0x2061, 0x7936, 0x6034, 0xa005, 0x0040, 0x49bd, 0xa080,
-+	0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078,
-+	0x49bb, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
-+	0x127e, 0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
-+	0x8cff, 0x0040, 0x4a23, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
-+	0x00c0, 0x4a1e, 0x703c, 0xac06, 0x00c0, 0x49e3, 0x6003, 0x000a,
-+	0x630a, 0x0078, 0x4a1e, 0x7038, 0xac36, 0x00c0, 0x49e9, 0x660c,
-+	0x763a, 0x7034, 0xac36, 0x00c0, 0x49f7, 0x2c00, 0xaf36, 0x0040,
-+	0x49f5, 0x2f00, 0x7036, 0x0078, 0x49f7, 0x7037, 0x0000, 0x660c,
-+	0x067e, 0x2c00, 0xaf06, 0x0040, 0x4a00, 0x7e0e, 0x0078, 0x4a01,
-+	0x2678, 0x600f, 0x0000, 0x1078, 0x6a58, 0x0040, 0x4a19, 0x6010,
-+	0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a2c, 0x6837, 0x0103,
-+	0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078,
-+	0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0x0078, 0x49d0, 0x2c78, 0x600c,
-+	0x2060, 0x0078, 0x49d0, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0,
-+	0x4a0e, 0x1078, 0x75fd, 0x0078, 0x4a19, 0x007e, 0x067e, 0x0c7e,
-+	0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000, 0x2079,
-+	0x7936, 0x7838, 0xa065, 0x0040, 0x4a6c, 0x600c, 0x007e, 0x600f,
-+	0x0000, 0x783c, 0xac06, 0x00c0, 0x4a53, 0x6003, 0x000a, 0x630a,
-+	0x2c30, 0x0078, 0x4a69, 0x1078, 0x6a58, 0x0040, 0x4a67, 0x6010,
-+	0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a75, 0x6837, 0x0103,
-+	0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078,
-+	0x6bb6, 0x007f, 0x0078, 0x4a42, 0x7e3a, 0x7e36, 0x127f, 0x0f7f,
-+	0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
-+	0x00c0, 0x4a5e, 0x1078, 0x75fd, 0x0078, 0x4a67, 0x027e, 0x1078,
-+	0x4a92, 0x1078, 0x4b2b, 0x027f, 0x007c, 0x0f7e, 0x127e, 0x2079,
-+	0x7936, 0x2091, 0x8000, 0x1078, 0x4bc2, 0x1078, 0x4c2a, 0x127f,
-+	0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e,
-+	0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678,
-+	0x8cff, 0x0040, 0x4b1a, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
-+	0x00c0, 0x4b15, 0x7024, 0xac06, 0x00c0, 0x4ad8, 0x2069, 0x0100,
-+	0x68c0, 0xa005, 0x0040, 0x4ad3, 0x1078, 0x569c, 0x68c3, 0x0000,
-+	0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
-+	0xa384, 0x1000, 0x0040, 0x4ac8, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4ad0, 0x6827, 0x0001,
-+	0x037f, 0x0078, 0x4ad8, 0x6003, 0x0009, 0x630a, 0x0078, 0x4b15,
-+	0x7014, 0xac36, 0x00c0, 0x4ade, 0x660c, 0x7616, 0x7010, 0xac36,
-+	0x00c0, 0x4aec, 0x2c00, 0xaf36, 0x0040, 0x4aea, 0x2f00, 0x7012,
-+	0x0078, 0x4aec, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
-+	0x0040, 0x4af5, 0x7e0e, 0x0078, 0x4af6, 0x2678, 0x600f, 0x0000,
-+	0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x4b0e, 0x601c, 0xa086,
-+	0x0003, 0x00c0, 0x4b22, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-+	0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6,
-+	0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x4aa0, 0x2c78, 0x600c, 0x2060,
-+	0x0078, 0x4aa0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
-+	0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4b03, 0x1078,
-+	0x75fd, 0x0078, 0x4b0e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000,
-+	0xa280, 0x7820, 0x2004, 0xa065, 0x0040, 0x4bbe, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x067e, 0x2071, 0x7936, 0x6654, 0x7018, 0xac06, 0x00c0,
-+	0x4b42, 0x761a, 0x701c, 0xac06, 0x00c0, 0x4b4e, 0x86ff, 0x00c0,
-+	0x4b4d, 0x7018, 0x701e, 0x0078, 0x4b4e, 0x761e, 0x6058, 0xa07d,
-+	0x0040, 0x4b53, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x4b59, 0x2f00,
-+	0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
-+	0x6002, 0x1078, 0x37c5, 0x0040, 0x4bba, 0x7624, 0x86ff, 0x0040,
-+	0x4baa, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, 0x4baa, 0x0d7e,
-+	0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x4ba1, 0x1078, 0x569c,
-+	0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069,
-+	0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x4b8a, 0x6803, 0x0100,
-+	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4b92,
-+	0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
-+	0x4b9b, 0x8001, 0x603e, 0x2660, 0x1078, 0x6bb6, 0x0c7f, 0x0078,
-+	0x4baa, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
-+	0x0078, 0x4b61, 0x8dff, 0x0040, 0x4bb6, 0x6837, 0x0103, 0x6b4a,
-+	0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x5a1a,
-+	0x0078, 0x4b61, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f,
-+	0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000,
-+	0x7814, 0xa065, 0x0040, 0x4c1a, 0x600c, 0x007e, 0x600f, 0x0000,
-+	0x7824, 0xac06, 0x00c0, 0x4bff, 0x2069, 0x0100, 0x68c0, 0xa005,
-+	0x0040, 0x4bf9, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a,
-+	0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
-+	0x0040, 0x4bee, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
-+	0x6824, 0xd084, 0x0040, 0x4bf6, 0x6827, 0x0001, 0x037f, 0x0078,
-+	0x4bff, 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x4c17, 0x6010,
-+	0x2068, 0x1078, 0x6a58, 0x0040, 0x4c13, 0x601c, 0xa086, 0x0003,
-+	0x00c0, 0x4c21, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
-+	0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x007f,
-+	0x0078, 0x4bc9, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f,
-+	0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4c0a, 0x1078, 0x75fd,
-+	0x0078, 0x4c13, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
-+	0x0040, 0x4c96, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
-+	0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x37c5, 0x0040, 0x4c93,
-+	0x7e24, 0x86ff, 0x0040, 0x4c85, 0xa680, 0x0004, 0x2004, 0xad06,
-+	0x00c0, 0x4c85, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
-+	0x4c7c, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7827,
-+	0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
-+	0x4c65, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
-+	0xd084, 0x0040, 0x4c6d, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e,
-+	0x603c, 0xa005, 0x0040, 0x4c76, 0x8001, 0x603e, 0x2660, 0x1078,
-+	0x6bb6, 0x0c7f, 0x0078, 0x4c85, 0x0d7f, 0x0c7e, 0x2660, 0x6003,
-+	0x0009, 0x630a, 0x0c7f, 0x0078, 0x4c3c, 0x8dff, 0x0040, 0x4c8f,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078,
-+	0x5a1a, 0x0078, 0x4c3c, 0x007f, 0x0078, 0x4c2f, 0x781e, 0x781a,
-+	0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, 0x0c7e, 0x2071,
-+	0x7936, 0x7004, 0xa084, 0x0007, 0x0079, 0x4ca6, 0x4cb0, 0x4cb3,
-+	0x4ccc, 0x4ce8, 0x4d2d, 0x4cb0, 0x4cb0, 0x4cae, 0x1078, 0x12cd,
-+	0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x4cc1, 0x7020,
-+	0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x4cc8, 0x7216, 0x600f,
-+	0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
-+	0x7216, 0x7212, 0x0078, 0x4cc1, 0x6018, 0x2060, 0x1078, 0x37c5,
-+	0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0040, 0x4cdd,
-+	0x6054, 0xa015, 0x0040, 0x4ce4, 0x721e, 0x7007, 0x0000, 0x7027,
-+	0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, 0x0078, 0x4cdd,
-+	0x7024, 0xa065, 0x0040, 0x4d2a, 0x700c, 0xac06, 0x00c0, 0x4cff,
-+	0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4cfb, 0x720e, 0x600f,
-+	0x0000, 0x0078, 0x4d28, 0x720e, 0x720a, 0x0078, 0x4d28, 0x7014,
-+	0xac06, 0x00c0, 0x4d12, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040,
-+	0x4d0e, 0x7216, 0x600f, 0x0000, 0x0078, 0x4d28, 0x7216, 0x7212,
-+	0x0078, 0x4d28, 0x6018, 0x2060, 0x1078, 0x37c5, 0x6000, 0xc0dc,
-+	0x6002, 0x1078, 0x5a1a, 0x701c, 0xa065, 0x0040, 0x4d28, 0x6054,
-+	0xa015, 0x0040, 0x4d26, 0x721e, 0x0078, 0x4d28, 0x7218, 0x721e,
-+	0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040,
-+	0x4d3a, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4d41, 0x720e,
-+	0x600f, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x0c7f, 0x0e7f,
-+	0x007c, 0x720e, 0x720a, 0x0078, 0x4d3a, 0x0d7e, 0x2069, 0x7936,
-+	0x6830, 0xa084, 0x0003, 0x0079, 0x4d4d, 0x4d53, 0x4d55, 0x4d7b,
-+	0x4d53, 0x1078, 0x12cd, 0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086,
-+	0x0001, 0x0040, 0x4d71, 0x683c, 0xa065, 0x0040, 0x4d66, 0x600c,
-+	0xa015, 0x0040, 0x4d6d, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000,
-+	0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836, 0x0078,
-+	0x4d66, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x4d66, 0x6003,
-+	0x0003, 0x0078, 0x4d66, 0x0c7e, 0x6843, 0x0000, 0x6847, 0x0000,
-+	0x683c, 0xa065, 0x0040, 0x4d93, 0x600c, 0xa015, 0x0040, 0x4d8f,
-+	0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0078, 0x4d93, 0x683f,
-+	0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, 0x007c, 0x0d7e, 0x2069,
-+	0x7936, 0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0x4da8, 0x4e45,
-+	0x4e45, 0x4e45, 0x4e45, 0x4e47, 0x4e45, 0x4da6, 0x1078, 0x12cd,
-+	0x6820, 0xa005, 0x00c0, 0x4dae, 0x0d7f, 0x007c, 0x0c7e, 0x680c,
-+	0xa065, 0x0040, 0x4dbd, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
-+	0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x6814, 0xa065, 0x0040,
-+	0x4dcb, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x1078, 0x4e8d,
-+	0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, 0x6a1c, 0xa2f5, 0x0000,
-+	0x0040, 0x4e40, 0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005,
-+	0x0040, 0x4df2, 0x7054, 0xa075, 0x0040, 0x4de3, 0xa20e, 0x0040,
-+	0x4e40, 0x0078, 0x4de8, 0x6818, 0xa20e, 0x0040, 0x4e40, 0x2070,
-+	0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005, 0x00c0, 0x4dda,
-+	0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x00c8, 0x4dda, 0x1078,
-+	0x5ce9, 0x0040, 0x4e40, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a,
-+	0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0048, 0x4e09, 0x2001,
-+	0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e,
-+	0x2c78, 0x71a0, 0xd1bc, 0x0040, 0x4e22, 0x7100, 0xd1f4, 0x0040,
-+	0x4e1e, 0x7114, 0xa18c, 0x00ff, 0x0078, 0x4e27, 0x2009, 0x0000,
-+	0x0078, 0x4e27, 0xa1e0, 0x2329, 0x2c0c, 0xa18c, 0x00ff, 0x2061,
-+	0x0100, 0x619a, 0x1078, 0x52de, 0x7300, 0xc3dd, 0x7302, 0x6807,
-+	0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803,
-+	0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c,
-+	0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x4e3e, 0x0d7f, 0x007c, 0x0c7e,
-+	0x680c, 0xa065, 0x0040, 0x4e53, 0x6807, 0x0004, 0x6826, 0x682b,
-+	0x0000, 0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e,
-+	0x2069, 0x7936, 0x6830, 0xa086, 0x0000, 0x00c0, 0x4e74, 0x6838,
-+	0xa07d, 0x0040, 0x4e74, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
-+	0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1a44, 0x00c0,
-+	0x4e77, 0x127f, 0x1078, 0x5571, 0x0d7f, 0x0f7f, 0x007c, 0x127f,
-+	0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0040, 0x4e89,
-+	0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
-+	0x4e74, 0x683a, 0x6836, 0x0078, 0x4e83, 0x601c, 0xa084, 0x000f,
-+	0x1079, 0x4e93, 0x007c, 0x4e9c, 0x4ea1, 0x51a8, 0x529e, 0x4ea1,
-+	0x51a8, 0x529e, 0x4e9c, 0x4ea1, 0x1078, 0x4c9d, 0x1078, 0x4d96,
-+	0x007c, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a,
-+	0x0030, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040,
-+	0x4ebe, 0x7900, 0xd1f4, 0x0040, 0x4eba, 0x7914, 0xa18c, 0x00ff,
-+	0x0078, 0x4ec3, 0x2009, 0x0000, 0x0078, 0x4ec3, 0xa1f8, 0x2329,
-+	0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x1079,
-+	0x4ecf, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x4f01,
-+	0x4f39, 0x4f51, 0x4fd0, 0x4ffd, 0x5005, 0x5026, 0x5037, 0x5048,
-+	0x5050, 0x5061, 0x5050, 0x50a9, 0x5037, 0x50ca, 0x50d2, 0x5048,
-+	0x50d2, 0x50e3, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff,
-+	0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x5758, 0x576d,
-+	0x5790, 0x57b4, 0x5026, 0x4eff, 0x5026, 0x5050, 0x4eff, 0x4f51,
-+	0x4fd0, 0x4eff, 0x5c64, 0x5050, 0x4eff, 0x5c87, 0x5050, 0x1078,
-+	0x12cd, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x5200, 0x20a3,
-+	0x0000, 0x0d7e, 0x2069, 0x7751, 0x6804, 0xd084, 0x0040, 0x4f1b,
-+	0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2094, 0x21a2, 0x017f,
-+	0x0d7f, 0x0078, 0x4f20, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a9, 0x0004, 0x2099, 0x7705, 0x53a6, 0x20a9, 0x0004, 0x2099,
-+	0x7701, 0x53a6, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x5688,
-+	0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0500, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9,
-+	0x0004, 0x2099, 0x7705, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x5688,
-+	0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa086, 0x007e, 0x00c0, 0x4f64, 0x20a3, 0x0400, 0x620c,
-+	0xc2b4, 0x620e, 0x0078, 0x4f66, 0x20a3, 0x0300, 0x20a3, 0x0000,
-+	0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x4f9f,
-+	0x2099, 0x7920, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084,
-+	0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x7705,
-+	0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0010,
-+	0x20a3, 0x0000, 0x00f0, 0x4f90, 0x2099, 0x7928, 0x33a6, 0x20a9,
-+	0x0007, 0x20a3, 0x0000, 0x00f0, 0x4f99, 0x0078, 0x4fbf, 0x2099,
-+	0x7920, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7705,
-+	0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0008,
-+	0x20a3, 0x0000, 0x00f0, 0x4fb0, 0x20a9, 0x0008, 0x20a3, 0x0000,
-+	0x00f0, 0x4fb6, 0x2099, 0x7928, 0x20a9, 0x0008, 0x53a6, 0x20a9,
-+	0x0008, 0x20a3, 0x0000, 0x00f0, 0x4fc1, 0x20a9, 0x000a, 0x20a3,
-+	0x0000, 0x00f0, 0x4fc7, 0x60c3, 0x0074, 0x1078, 0x5688, 0x007c,
-+	0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x2010, 0x20a3, 0x0014,
-+	0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a2, 0x0f7e, 0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac,
-+	0x00c0, 0x4fec, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x4ff1, 0xa085,
-+	0x0010, 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b, 0x1078,
-+	0x50f8, 0x20a3, 0x5000, 0x0078, 0x4f66, 0x20a1, 0x020b, 0x1078,
-+	0x50f8, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b,
-+	0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x007c, 0x20a1,
-+	0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
-+	0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c,
-+	0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x0078, 0x4f66,
-+	0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000,
-+	0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688,
-+	0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210,
-+	0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086,
-+	0x0014, 0x00c0, 0x5087, 0x6998, 0xa184, 0xc000, 0x00c0, 0x5083,
-+	0xd1ec, 0x0040, 0x507f, 0x20a3, 0x2100, 0x0078, 0x5089, 0x20a3,
-+	0x0100, 0x0078, 0x5089, 0x20a3, 0x0400, 0x0078, 0x5089, 0x20a3,
-+	0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e,
-+	0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x5099, 0xa085,
-+	0x0020, 0xd1a4, 0x0040, 0x509e, 0xa085, 0x0010, 0xa085, 0x0002,
-+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x5688, 0x0d7f,
-+	0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3,
-+	0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
-+	0x5688, 0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200,
-+	0x0078, 0x4f07, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008,
-+	0x1078, 0x5688, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1,
-+	0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
-+	0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c,
-+	0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2014, 0xa286, 0x007e, 0x00c0, 0x510b, 0x20a3, 0x22ff, 0x20a3,
-+	0xfffe, 0x0078, 0x5139, 0xa286, 0x007f, 0x00c0, 0x5116, 0x0d7e,
-+	0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, 0x512d, 0xd2bc, 0x0040,
-+	0x5135, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x5124, 0x20a3, 0x22ff,
-+	0x20a3, 0xfffc, 0x0078, 0x512d, 0xa2e8, 0x7820, 0x2d6c, 0x6810,
-+	0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6,
-+	0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x513d, 0x20a3, 0x2200, 0x6298,
-+	0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0129, 0x20a3,
-+	0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
-+	0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
-+	0x22a2, 0x0d7e, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
-+	0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x5141, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
-+	0xa092, 0x007e, 0x0048, 0x518e, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
-+	0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5196, 0x20a3, 0x2300,
-+	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0198,
-+	0x20a3, 0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x7a08,
-+	0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c,
-+	0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a,
-+	0x008c, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040,
-+	0x51c6, 0x7900, 0xd1f4, 0x0040, 0x51c2, 0x7914, 0xa18c, 0x00ff,
-+	0x0078, 0x51cb, 0x2009, 0x0000, 0x0078, 0x51cb, 0xa1f8, 0x2329,
-+	0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082,
-+	0x0085, 0x1079, 0x51d6, 0x0f7f, 0x0c7f, 0x007c, 0x51df, 0x51ea,
-+	0x5204, 0x51dd, 0x51dd, 0x51dd, 0x51df, 0x1078, 0x12cd, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x5217, 0x60c3, 0x0000, 0x1078, 0x5688,
-+	0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5244, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x2fa2, 0x20a3, 0x0000,
-+	0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
-+	0x1078, 0x5688, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
-+	0x5271, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x147f, 0x007c, 0x027e,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
-+	0xa092, 0x007e, 0x0048, 0x5236, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
-+	0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x523e, 0x20a3, 0x8100,
-+	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009,
-+	0x20a3, 0x0000, 0x0078, 0x5141, 0x027e, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
-+	0x5263, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x8400,
-+	0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6,
-+	0x0d7f, 0x0078, 0x526b, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3,
-+	0x0000, 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078,
-+	0x519a, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
-+	0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x5290, 0x0d7e, 0xa0e8,
-+	0x7820, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2,
-+	0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5298,
-+	0x20a3, 0x8500, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2,
-+	0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x519a, 0x0c7e, 0x0f7e,
-+	0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x12cd, 0xa08a, 0x0050,
-+	0x10c8, 0x12cd, 0x7918, 0x2160, 0x61a0, 0xd1bc, 0x0040, 0x52bd,
-+	0x6100, 0xd1f4, 0x0040, 0x52b9, 0x6114, 0xa18c, 0x00ff, 0x0078,
-+	0x52c2, 0x2009, 0x0000, 0x0078, 0x52c2, 0xa1e0, 0x2329, 0x2c0c,
-+	0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x1079,
-+	0x52cc, 0x0f7f, 0x0c7f, 0x007c, 0x52de, 0x53c4, 0x536c, 0x54ec,
-+	0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x5933,
-+	0x5944, 0x5955, 0x5966, 0x52dc, 0x1078, 0x12cd, 0x0d7e, 0x157e,
-+	0x147e, 0x20a1, 0x020b, 0x1078, 0x532f, 0x7910, 0x2168, 0x6948,
-+	0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x0006,
-+	0x8004, 0x20a2, 0xd1ac, 0x0040, 0x52f9, 0x20a3, 0x0002, 0x0078,
-+	0x5305, 0xd1b4, 0x0040, 0x5300, 0x20a3, 0x0001, 0x0078, 0x5305,
-+	0x20a3, 0x0000, 0x2230, 0x0078, 0x5307, 0x6a80, 0x6e7c, 0x20a9,
-+	0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0,
-+	0x530b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014,
-+	0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x7952, 0x2003,
-+	0x07d0, 0x2001, 0x7951, 0x2003, 0x0009, 0x2001, 0x7957, 0x2003,
-+	0x0002, 0x1078, 0x14fc, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1,
-+	0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
-+	0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
-+	0xd0bc, 0x0040, 0x5355, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810,
-+	0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6,
-+	0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x535d, 0x20a3, 0x0600, 0x6198,
-+	0x21a2, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3,
-+	0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x538c, 0x7810, 0x2068, 0x6860, 0x20a2,
-+	0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x5688, 0x147f,
-+	0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x53aa,
-+	0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
-+	0x0078, 0x53b2, 0x20a3, 0x0500, 0x6298, 0x22a2, 0x20a3, 0x0000,
-+	0x6230, 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x5677,
-+	0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x54b4, 0x7810, 0x2068, 0xa016, 0x22a2,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x00c0,
-+	0x53e1, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x53e9, 0x0078,
-+	0x53e4, 0xa006, 0x1079, 0x53e9, 0x147f, 0x137f, 0x157f, 0x0d7f,
-+	0x007c, 0x53f3, 0x5455, 0x5459, 0x547c, 0x5489, 0x549b, 0x549f,
-+	0x53f1, 0x1078, 0x12cd, 0x017e, 0x037e, 0x694c, 0xa18c, 0x0003,
-+	0xa186, 0x0000, 0x00c0, 0x5406, 0x6b78, 0x23a2, 0x6868, 0x20a2,
-+	0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x5480, 0xa186, 0x0001,
-+	0x00c0, 0x5450, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2,
-+	0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018,
-+	0xa384, 0x0300, 0x0040, 0x544f, 0xd3c4, 0x0040, 0x5421, 0x687c,
-+	0xa108, 0xd3cc, 0x0040, 0x5426, 0x6874, 0xa108, 0x157e, 0x20a9,
-+	0x000d, 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0,
-+	0x542b, 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040,
-+	0x544f, 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3,
-+	0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
-+	0x0898, 0x20a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x61c2,
-+	0x037f, 0x017f, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078,
-+	0x547e, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012,
-+	0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3,
-+	0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2,
-+	0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
-+	0x0032, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0028, 0x22a2, 0x22a2,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x5688,
-+	0x007c, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
-+	0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
-+	0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078, 0x547e, 0x037e,
-+	0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0,
-+	0x54ad, 0x22a2, 0x037f, 0x0078, 0x547e, 0x20a3, 0x0800, 0x22a2,
-+	0x20a2, 0x037f, 0x0078, 0x5480, 0x027e, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x54d2,
-+	0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
-+	0x0078, 0x54da, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000,
-+	0x6230, 0x22a2, 0x20a3, 0x0898, 0x20a3, 0x0000, 0x1078, 0x5677,
-+	0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
-+	0x017e, 0x037e, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x54ff,
-+	0x037f, 0x017f, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x5507,
-+	0x5507, 0x5509, 0x5507, 0x5507, 0x5507, 0x552e, 0x5507, 0x1078,
-+	0x12cd, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1,
-+	0x020b, 0x2009, 0x0003, 0x1078, 0x5538, 0x0d7e, 0x2069, 0x7751,
-+	0x6804, 0xd0bc, 0x0040, 0x5523, 0x682c, 0xa084, 0x00ff, 0x8007,
-+	0x20a2, 0x0078, 0x5525, 0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2,
-+	0x22a2, 0x60c3, 0x0001, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b,
-+	0x2009, 0x0003, 0x1078, 0x5538, 0x20a3, 0x7f00, 0x0078, 0x5526,
-+	0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xd0bc, 0x0040, 0x5556, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
-+	0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
-+	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x555e, 0x20a3, 0x0100,
-+	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0888,
-+	0xa18d, 0x0008, 0x21a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000,
-+	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
-+	0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e, 0x037e, 0x2061,
-+	0x0100, 0x2071, 0x7700, 0x6130, 0x7818, 0x2068, 0x68a0, 0x2028,
-+	0xd0bc, 0x00c0, 0x558a, 0xa080, 0x2329, 0x2014, 0xa294, 0x00ff,
-+	0x0078, 0x558e, 0x6910, 0x6a14, 0x7364, 0x7468, 0x781c, 0xa086,
-+	0x0006, 0x0040, 0x55e2, 0xd5bc, 0x0040, 0x559e, 0xa185, 0x0100,
-+	0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55a4, 0x6063, 0x0100,
-+	0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0809, 0x6077, 0x0008,
-+	0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f,
-+	0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070, 0x7014,
-+	0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c,
-+	0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582,
-+	0x0080, 0x0048, 0x55d6, 0x6a00, 0xd2f4, 0x0040, 0x55d4, 0x6a14,
-+	0xa294, 0x00ff, 0x0078, 0x55d6, 0x2011, 0x0000, 0x629e, 0x6017,
-+	0x0016, 0x1078, 0x470b, 0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f,
-+	0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086,
-+	0x0002, 0x0040, 0x5631, 0xd5bc, 0x0040, 0x55f6, 0xa185, 0x0100,
-+	0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55fc, 0x6063, 0x0100,
-+	0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0880, 0x6077, 0x0008,
-+	0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f,
-+	0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c,
-+	0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab,
-+	0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048,
-+	0x562c, 0x6a00, 0xd2f4, 0x0040, 0x562a, 0x6a14, 0xa294, 0x00ff,
-+	0x0078, 0x562c, 0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078,
-+	0x55d9, 0xd5bc, 0x0040, 0x563c, 0xa185, 0x0700, 0x6062, 0x6266,
-+	0x636a, 0x646e, 0x0078, 0x5642, 0x6063, 0x0700, 0x6266, 0x606b,
-+	0x0000, 0x616e, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000,
-+	0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
-+	0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c,
-+	0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
-+	0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x5672, 0x6a00,
-+	0xd2f4, 0x0040, 0x5670, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x5672,
-+	0x2011, 0x0000, 0x629e, 0x6017, 0x0016, 0x0078, 0x55d9, 0x7a18,
-+	0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217,
-+	0x007c, 0x0d7e, 0x2069, 0x7936, 0x6843, 0x0001, 0x0d7f, 0x007c,
-+	0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, 0x5693,
-+	0x1078, 0x46fb, 0x007c, 0x007e, 0x6014, 0xa084, 0x0004, 0xa085,
-+	0x0009, 0x6016, 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100,
-+	0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f,
-+	0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e, 0x1078, 0x4706, 0x2061,
-+	0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x56e6,
-+	0x1078, 0x569c, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, 0x2061,
-+	0x7936, 0x6128, 0xa192, 0x0002, 0x00c8, 0x56d3, 0x8108, 0x612a,
-+	0x6124, 0x0c7f, 0x81ff, 0x0040, 0x56e1, 0x1078, 0x46fb, 0x1078,
-+	0x5693, 0x0078, 0x56e1, 0x6124, 0xa1e5, 0x0000, 0x0040, 0x56de,
-+	0x1078, 0x76c7, 0x2009, 0x0014, 0x1078, 0x5d41, 0x0c7f, 0x0078,
-+	0x56e1, 0x027f, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, 0x3591,
-+	0x0078, 0x56e1, 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078,
-+	0x4714, 0x2071, 0x7936, 0x713c, 0x81ff, 0x0040, 0x5714, 0x2061,
-+	0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x571a,
-+	0x6803, 0x1000, 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078,
-+	0x5880, 0x037f, 0x713c, 0x2160, 0x1078, 0x76c7, 0x2009, 0x004a,
-+	0x1078, 0x5d41, 0x0078, 0x5714, 0x027f, 0x017f, 0x0e7f, 0x0d7f,
-+	0x0c7f, 0x007c, 0x7144, 0xa192, 0x0002, 0x00c8, 0x5704, 0x8108,
-+	0x7146, 0x1078, 0x470b, 0x0078, 0x5714, 0x0e7e, 0x0d7e, 0x0c7e,
-+	0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000, 0x6018,
-+	0x2068, 0x6ca0, 0x2071, 0x7936, 0x7018, 0x2068, 0x8dff, 0x0040,
-+	0x574f, 0x68a0, 0xa406, 0x0040, 0x5741, 0x6854, 0x2068, 0x0078,
-+	0x5736, 0x6010, 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078,
-+	0x3991, 0x0040, 0x574f, 0x1078, 0x5a1a, 0xa085, 0x0001, 0x127f,
-+	0x007f, 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c,
-+	0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0f00,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008,
-+	0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9,
-+	0x0006, 0x2011, 0x7740, 0x2019, 0x7741, 0x23a6, 0x22a6, 0xa398,
-+	0x0002, 0xa290, 0x0002, 0x00f0, 0x577d, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x001c, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c,
-+	0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x514f,
-+	0x1078, 0x5166, 0x7810, 0x007e, 0xa080, 0x0015, 0x2098, 0x7808,
-+	0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2,
-+	0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, 0x5688, 0x027f,
-+	0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b,
-+	0x1078, 0x50f8, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688, 0x147f, 0x157f,
-+	0x007c, 0x0e7e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
-+	0x7936, 0x700c, 0x2060, 0x8cff, 0x0040, 0x57e5, 0x1078, 0x6be3,
-+	0x00c0, 0x57dc, 0x1078, 0x5f6d, 0x600c, 0x007e, 0x1078, 0x5d1a,
-+	0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x57d3, 0x700f, 0x0000, 0x700b,
-+	0x0000, 0x127f, 0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e,
-+	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091,
-+	0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x7936, 0x7024,
-+	0x2060, 0x8cff, 0x0040, 0x583e, 0x1078, 0x569c, 0x68c3, 0x0000,
-+	0x1078, 0x4706, 0x2009, 0x0013, 0x1078, 0x5d41, 0x20a9, 0x01f4,
-+	0x6824, 0xd094, 0x0040, 0x5821, 0x6827, 0x0004, 0x7804, 0xa084,
-+	0x4000, 0x0040, 0x5833, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
-+	0x5833, 0xd084, 0x0040, 0x5828, 0x6827, 0x0001, 0x0078, 0x582a,
-+	0x00f0, 0x5810, 0x7804, 0xa084, 0x1000, 0x0040, 0x5833, 0x7803,
-+	0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f,
-+	0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0x7700,
-+	0x2004, 0xa096, 0x0001, 0x0040, 0x5876, 0xa096, 0x0004, 0x0040,
-+	0x5876, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x3558, 0x1078,
-+	0x4689, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x5864, 0x6827,
-+	0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x5876, 0x7803, 0x1000,
-+	0x7803, 0x0000, 0x0078, 0x5876, 0xd084, 0x0040, 0x586b, 0x6827,
-+	0x0001, 0x0078, 0x586d, 0x00f0, 0x5853, 0x7804, 0xa084, 0x1000,
-+	0x0040, 0x5876, 0x7803, 0x0100, 0x7803, 0x0000, 0x007f, 0x017f,
-+	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
-+	0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e,
-+	0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
-+	0x7936, 0x703c, 0x2060, 0x8cff, 0x0040, 0x58ce, 0x6817, 0x0010,
-+	0x68cb, 0x0000, 0x68c7, 0x0000, 0x1078, 0x4714, 0x1078, 0x1c13,
-+	0xa39d, 0x0000, 0x00c0, 0x58a8, 0x2009, 0x0049, 0x1078, 0x5d41,
-+	0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x58bb, 0x6827, 0x0004,
-+	0x7804, 0xa084, 0x4000, 0x0040, 0x58cd, 0x7803, 0x1000, 0x7803,
-+	0x0000, 0x0078, 0x58cd, 0xd094, 0x0040, 0x58c2, 0x6827, 0x0002,
-+	0x0078, 0x58c4, 0x00f0, 0x58aa, 0x7804, 0xa084, 0x1000, 0x0040,
-+	0x58cd, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f,
-+	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
-+	0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936, 0x6a06, 0x127f,
-+	0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936,
-+	0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
-+	0x007e, 0x127e, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678, 0x2091,
-+	0x8000, 0x8cff, 0x0040, 0x592c, 0x601c, 0xa206, 0x00c0, 0x5927,
-+	0x7014, 0xac36, 0x00c0, 0x5906, 0x660c, 0x7616, 0x7010, 0xac36,
-+	0x00c0, 0x5914, 0x2c00, 0xaf36, 0x0040, 0x5912, 0x2f00, 0x7012,
-+	0x0078, 0x5914, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
-+	0x0040, 0x591d, 0x7e0e, 0x0078, 0x591e, 0x2678, 0x600f, 0x0000,
-+	0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x58f9, 0x2c78,
-+	0x600c, 0x2060, 0x0078, 0x58f9, 0x127f, 0x007f, 0x067f, 0x0c7f,
-+	0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
-+	0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a3, 0x4000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1, 0x020b,
-+	0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a3, 0x2000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1,
-+	0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x5975, 0x157e, 0x147e,
-+	0x20a1, 0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x5a25, 0x60c3,
-+	0x0020, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x127e, 0x0c7e,
-+	0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, 0x598d,
-+	0xd1bc, 0x00c0, 0x59d7, 0x0078, 0x5a17, 0x2009, 0x017f, 0x200b,
-+	0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e,
-+	0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x59ce, 0x6020,
-+	0xd0b4, 0x0040, 0x59ce, 0x6024, 0xd094, 0x00c0, 0x59ce, 0x2104,
-+	0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x59ce, 0x00f0, 0x599a,
-+	0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff,
-+	0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, 0x0001,
-+	0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, 0x59cd,
-+	0x6a04, 0xa294, 0x4000, 0x00c0, 0x59c4, 0x027f, 0x0d7f, 0x007f,
-+	0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x5a17, 0x2009,
-+	0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140,
-+	0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040,
-+	0x5a10, 0x6020, 0xd0bc, 0x0040, 0x5a10, 0x2104, 0xa084, 0x000f,
-+	0xa086, 0x0004, 0x00c0, 0x5a10, 0x00f0, 0x59e4, 0x027e, 0x6164,
-+	0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088,
-+	0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, 0x0000,
-+	0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x5a0a, 0x027f,
-+	0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0c7f,
-+	0x127f, 0x007c, 0x0e7e, 0x2071, 0x7936, 0x7020, 0xa005, 0x0040,
-+	0x5a23, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, 0x20a2,
-+	0x00f0, 0x5a27, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
-+	0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
-+	0x7936, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0040,
-+	0x5abd, 0x8cff, 0x0040, 0x5abd, 0x601c, 0xa086, 0x0006, 0x00c0,
-+	0x5ab8, 0x88ff, 0x0040, 0x5a54, 0x2800, 0xac06, 0x00c0, 0x5ab8,
-+	0x2039, 0x0000, 0x0078, 0x5a58, 0x6018, 0xa206, 0x00c0, 0x5ab8,
-+	0x7024, 0xac06, 0x00c0, 0x5a86, 0x2069, 0x0100, 0x68c0, 0xa005,
-+	0x0040, 0x5a81, 0x6817, 0x0008, 0x68c3, 0x0000, 0x1078, 0x5b4a,
-+	0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
-+	0x0040, 0x5a76, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
-+	0x6824, 0xd084, 0x0040, 0x5a7e, 0x6827, 0x0001, 0x037f, 0x0078,
-+	0x5a86, 0x6003, 0x0009, 0x630a, 0x0078, 0x5ab8, 0x7014, 0xac36,
-+	0x00c0, 0x5a8c, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5a9a,
-+	0x2c00, 0xaf36, 0x0040, 0x5a98, 0x2f00, 0x7012, 0x0078, 0x5a9a,
-+	0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5aa3,
-+	0x7e0e, 0x0078, 0x5aa4, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
-+	0x1078, 0x6a58, 0x0040, 0x5aae, 0x1078, 0x75fd, 0x1078, 0x6bb6,
-+	0x1078, 0x5a1a, 0x88ff, 0x00c0, 0x5ac7, 0x0c7f, 0x0078, 0x5a3e,
-+	0x2c78, 0x600c, 0x2060, 0x0078, 0x5a3e, 0xa006, 0x127f, 0x007f,
-+	0x067f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017,
-+	0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x5abe, 0x0f7e, 0x0e7e,
-+	0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000,
-+	0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b39,
-+	0x601c, 0xa086, 0x0006, 0x00c0, 0x5b34, 0x88ff, 0x0040, 0x5aee,
-+	0x2800, 0xac06, 0x00c0, 0x5b34, 0x0078, 0x5af2, 0x6018, 0xa206,
-+	0x00c0, 0x5b34, 0x703c, 0xac06, 0x00c0, 0x5b04, 0x037e, 0x2019,
-+	0x0001, 0x1078, 0x5880, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043,
-+	0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5b0a,
-+	0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5b18, 0x2c00, 0xaf36,
-+	0x0040, 0x5b16, 0x2f00, 0x7036, 0x0078, 0x5b18, 0x7037, 0x0000,
-+	0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5b21, 0x7e0e, 0x0078,
-+	0x5b22, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x6a58,
-+	0x0040, 0x5b2c, 0x1078, 0x75fd, 0x1078, 0x6bb6, 0x88ff, 0x00c0,
-+	0x5b43, 0x0c7f, 0x0078, 0x5add, 0x2c78, 0x600c, 0x2060, 0x0078,
-+	0x5add, 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f,
-+	0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001,
-+	0x0078, 0x5b3a, 0x0e7e, 0x2071, 0x7936, 0x2001, 0x7700, 0x2004,
-+	0xa086, 0x0002, 0x00c0, 0x5b58, 0x7007, 0x0005, 0x0078, 0x5b5a,
-+	0x7007, 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
-+	0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x2c10,
-+	0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b9a, 0x2200, 0xac06,
-+	0x00c0, 0x5b95, 0x7038, 0xac36, 0x00c0, 0x5b78, 0x660c, 0x763a,
-+	0x7034, 0xac36, 0x00c0, 0x5b86, 0x2c00, 0xaf36, 0x0040, 0x5b84,
-+	0x2f00, 0x7036, 0x0078, 0x5b86, 0x7037, 0x0000, 0x660c, 0x2c00,
-+	0xaf06, 0x0040, 0x5b8e, 0x7e0e, 0x0078, 0x5b8f, 0x2678, 0x600f,
-+	0x0000, 0xa085, 0x0001, 0x0078, 0x5b9a, 0x2c78, 0x600c, 0x2060,
-+	0x0078, 0x5b6b, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f,
-+	0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e,
-+	0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x760c, 0x2660, 0x2678,
-+	0x8cff, 0x0040, 0x5c33, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
-+	0x00c0, 0x5c2e, 0x7024, 0xac06, 0x00c0, 0x5be1, 0x2069, 0x0100,
-+	0x68c0, 0xa005, 0x0040, 0x5be1, 0x1078, 0x569c, 0x68c3, 0x0000,
-+	0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
-+	0xa384, 0x1000, 0x0040, 0x5bd8, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5be0, 0x6827, 0x0001,
-+	0x037f, 0x700c, 0xac36, 0x00c0, 0x5be7, 0x660c, 0x760e, 0x7008,
-+	0xac36, 0x00c0, 0x5bf5, 0x2c00, 0xaf36, 0x0040, 0x5bf3, 0x2f00,
-+	0x700a, 0x0078, 0x5bf5, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00,
-+	0xaf06, 0x0040, 0x5bfe, 0x7e0e, 0x0078, 0x5bff, 0x2678, 0x600f,
-+	0x0000, 0x1078, 0x6bcf, 0x00c0, 0x5c09, 0x1078, 0x22d7, 0x0078,
-+	0x5c25, 0x1078, 0x6be3, 0x00c0, 0x5c11, 0x1078, 0x5f6d, 0x0078,
-+	0x5c25, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x5c25, 0x601c,
-+	0xa086, 0x0003, 0x00c0, 0x5c3b, 0x6837, 0x0103, 0x6b4a, 0x6847,
-+	0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x6003, 0x0000, 0x1078,
-+	0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x5bb0, 0x2c78, 0x600c,
-+	0x2060, 0x0078, 0x5bb0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f,
-+	0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5c1c,
-+	0x1078, 0x75fd, 0x0078, 0x5c25, 0x037e, 0x157e, 0x137e, 0x147e,
-+	0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x2149, 0x00c0,
-+	0x5c55, 0x8210, 0x8000, 0x0078, 0x5c4c, 0xa005, 0x0040, 0x5c5f,
-+	0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x147f,
-+	0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
-+	0x516f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x514c, 0x20a3, 0x4f47, 0x20a3,
-+	0x4943, 0x20a3, 0x2020, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x1078, 0x5688, 0x0d7f, 0x007c, 0x20a1,
-+	0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3,
-+	0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810,
-+	0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0018, 0x1078, 0x5688, 0x007c, 0x2061, 0x7e00, 0x2a70, 0x7060,
-+	0x7046, 0x704b, 0x7e00, 0x007c, 0x0e7e, 0x127e, 0x2071, 0x7700,
-+	0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0048, 0x5ce6, 0x7048,
-+	0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5cd2, 0xace0, 0x0008,
-+	0x7054, 0xac02, 0x00c8, 0x5cce, 0x0078, 0x5cc1, 0x2061, 0x7e00,
-+	0x0078, 0x5cc1, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0008,
-+	0x7054, 0xa502, 0x00c8, 0x5ce2, 0x754a, 0xa085, 0x0001, 0x127f,
-+	0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5cdd, 0xa006, 0x0078,
-+	0x5cdf, 0x0e7e, 0x2071, 0x7700, 0x7544, 0xa582, 0x0001, 0x0048,
-+	0x5d17, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5d04,
-+	0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, 0x5d00, 0x0078, 0x5cf3,
-+	0x2061, 0x7e00, 0x0078, 0x5cf3, 0x6003, 0x0008, 0x8529, 0x7546,
-+	0xaca8, 0x0008, 0x7054, 0xa502, 0x00c8, 0x5d13, 0x754a, 0xa085,
-+	0x0001, 0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5d0f, 0xa006,
-+	0x0078, 0x5d11, 0xac82, 0x7e00, 0x1048, 0x12cd, 0x2001, 0x7715,
-+	0x2004, 0xac02, 0x10c8, 0x12cd, 0xa006, 0x6006, 0x600a, 0x600e,
-+	0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x2061,
-+	0x7700, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x5d39,
-+	0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x0078,
-+	0x5d38, 0x601c, 0xa084, 0x000f, 0x0079, 0x5d46, 0x5d4f, 0x5d57,
-+	0x5d73, 0x5d8f, 0x6c60, 0x6c7c, 0x6c98, 0x5d4f, 0x5d57, 0xa18e,
-+	0x0047, 0x00c0, 0x5d56, 0xa016, 0x1078, 0x156a, 0x007c, 0x067e,
-+	0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d61, 0x067f,
-+	0x007c, 0x5d71, 0x5e58, 0x5f88, 0x5d71, 0x5fdf, 0x5d71, 0x5d71,
-+	0x5d71, 0x5e07, 0x6298, 0x5d71, 0x5d71, 0x5d71, 0x5d71, 0x5d71,
-+	0x5d71, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
-+	0x12cd, 0x1079, 0x5d7d, 0x067f, 0x007c, 0x5d8d, 0x5d8d, 0x5d8d,
-+	0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x670c, 0x67d2, 0x5d8d,
-+	0x6725, 0x677e, 0x6725, 0x677e, 0x5d8d, 0x1078, 0x12cd, 0x067e,
-+	0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d99, 0x067f,
-+	0x007c, 0x5da9, 0x62d6, 0x637c, 0x643e, 0x6596, 0x5da9, 0x5da9,
-+	0x5da9, 0x62b4, 0x66c1, 0x66c5, 0x5da9, 0x5da9, 0x5da9, 0x5da9,
-+	0x66eb, 0x1078, 0x12cd, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0,
-+	0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318,
-+	0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398,
-+	0x0002, 0xa4a0, 0x0002, 0x00f0, 0x5db9, 0x0e7e, 0x1078, 0x6a58,
-+	0x0040, 0x5dd0, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
-+	0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0d7e, 0x037e, 0x7330, 0xa386,
-+	0x0200, 0x00c0, 0x5de1, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817,
-+	0xfffd, 0x6010, 0xa005, 0x0040, 0x5deb, 0x2068, 0x6807, 0x0000,
-+	0x6837, 0x0103, 0x6b32, 0x1078, 0x5d1a, 0x037f, 0x0d7f, 0x007c,
-+	0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6,
-+	0x0015, 0x00c0, 0x5e04, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c,
-+	0x680e, 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x5dc5, 0x2100,
-+	0xa1b2, 0x0030, 0x10c8, 0x12cd, 0x0079, 0x5e0e, 0x5e40, 0x5e4c,
-+	0x5e40, 0x5e40, 0x5e40, 0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
-+	0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
-+	0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
-+	0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e, 0x5e40,
-+	0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e,
-+	0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x1078, 0x12cd,
-+	0x6003, 0x0001, 0x6106, 0x1078, 0x498e, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
-+	0x498e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c,
-+	0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013, 0x00c0,
-+	0x5e64, 0x2008, 0x0079, 0x5eeb, 0xa1b6, 0x0027, 0x00c0, 0x5eb9,
-+	0x1078, 0x4c9d, 0x6004, 0x1078, 0x6bcf, 0x0040, 0x5e7d, 0x1078,
-+	0x6be3, 0x0040, 0x5eb1, 0xa08e, 0x0021, 0x0040, 0x5eb5, 0xa08e,
-+	0x0022, 0x0040, 0x5eb1, 0x0078, 0x5eac, 0x1078, 0x22d7, 0x2001,
-+	0x0007, 0x1078, 0x37f4, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078,
-+	0x5f6d, 0xa186, 0x007e, 0x00c0, 0x5e92, 0x2001, 0x772f, 0x2014,
-+	0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028,
-+	0x1078, 0x4a7e, 0x1078, 0x49c1, 0x0c7e, 0x6018, 0xa065, 0x0040,
-+	0x5ea3, 0x1078, 0x3a36, 0x0c7f, 0x2c08, 0x1078, 0x747b, 0x037f,
-+	0x027f, 0x017f, 0x1078, 0x3834, 0x1078, 0x5d1a, 0x1078, 0x4d96,
-+	0x007c, 0x1078, 0x5f6d, 0x0078, 0x5eac, 0x1078, 0x5f7c, 0x0078,
-+	0x5eac, 0xa186, 0x0014, 0x00c0, 0x5eb0, 0x1078, 0x4c9d, 0x1078,
-+	0x22b5, 0x1078, 0x6bcf, 0x00c0, 0x5ed8, 0x1078, 0x22d7, 0x6018,
-+	0xa080, 0x0028, 0x200c, 0x1078, 0x5f6d, 0xa186, 0x007e, 0x00c0,
-+	0x5ed6, 0x2001, 0x772f, 0x200c, 0xc185, 0x2102, 0x0078, 0x5eac,
-+	0x1078, 0x6be3, 0x00c0, 0x5ee0, 0x1078, 0x5f6d, 0x0078, 0x5eac,
-+	0x6004, 0xa08e, 0x0021, 0x0040, 0x5edc, 0xa08e, 0x0022, 0x1040,
-+	0x5f7c, 0x0078, 0x5eac, 0x5f1d, 0x5f1f, 0x5f23, 0x5f27, 0x5f2b,
-+	0x5f2f, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
-+	0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
-+	0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
-+	0x5f1b, 0x5f33, 0x5f39, 0x5f1b, 0x5f43, 0x5f39, 0x5f1b, 0x5f1b,
-+	0x5f1b, 0x5f1b, 0x5f1b, 0x5f39, 0x5f39, 0x5f1b, 0x5f1b, 0x5f1b,
-+	0x5f1b, 0x5f1b, 0x5f1b, 0x1078, 0x12cd, 0x0078, 0x5f39, 0x2001,
-+	0x000b, 0x0078, 0x5f4c, 0x2001, 0x0003, 0x0078, 0x5f4c, 0x2001,
-+	0x0005, 0x0078, 0x5f4c, 0x2001, 0x0001, 0x0078, 0x5f4c, 0x2001,
-+	0x0009, 0x0078, 0x5f4c, 0x1078, 0x12cd, 0x0078, 0x5f4b, 0x1078,
-+	0x37f4, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x6017, 0x0028, 0x1078,
-+	0x4d96, 0x0078, 0x5f4b, 0x1078, 0x4c9d, 0x6003, 0x0004, 0x6017,
-+	0x0028, 0x1078, 0x4d96, 0x007c, 0x1078, 0x37f4, 0x1078, 0x4c9d,
-+	0x6003, 0x0002, 0x037e, 0x2019, 0x775c, 0x2304, 0xa084, 0xff00,
-+	0x00c0, 0x5f5e, 0x2019, 0x0028, 0x0078, 0x5f67, 0x8007, 0xa09a,
-+	0x0004, 0x0048, 0x5f5a, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316,
-+	0x037f, 0x1078, 0x4d96, 0x0078, 0x5f4b, 0x0e7e, 0x1078, 0x6a58,
-+	0x0040, 0x5f7a, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
-+	0x7033, 0x0100, 0x0e7f, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
-+	0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x0e7f, 0x007c,
-+	0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa0b2,
-+	0x000c, 0x10c8, 0x12cd, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x5f9c,
-+	0x1078, 0x6c18, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x0029, 0x00c0,
-+	0x5fa5, 0x1078, 0x6c32, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x001f,
-+	0x00c0, 0x5fae, 0x1078, 0x5dab, 0x0078, 0x5fce, 0x6604, 0xa6b6,
-+	0x0000, 0x00c0, 0x5fb7, 0x1078, 0x5df0, 0x0078, 0x5fce, 0x6604,
-+	0xa6b6, 0x0022, 0x00c0, 0x5fc0, 0x1078, 0x5dd4, 0x0078, 0x5fce,
-+	0xa1b6, 0x0015, 0x00c0, 0x5fc8, 0x1079, 0x5fd3, 0x0078, 0x5fce,
-+	0xa1b6, 0x0016, 0x00c0, 0x5fcf, 0x1079, 0x6110, 0x007c, 0x1078,
-+	0x5d4f, 0x0078, 0x5fce, 0x5ff7, 0x5ffa, 0x5ff7, 0x603b, 0x5ff7,
-+	0x60ac, 0x5ff7, 0x5ff7, 0x5ff7, 0x60e8, 0x5ff7, 0x60fe, 0xa1b6,
-+	0x0048, 0x0040, 0x5feb, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
-+	0x1078, 0x156a, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000,
-+	0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0005,
-+	0x0005, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078, 0xa086, 0x0074,
-+	0x00c0, 0x6024, 0x1078, 0x744f, 0x00c0, 0x6016, 0x0d7e, 0x6018,
-+	0x2068, 0x1078, 0x6028, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x37f4,
-+	0x1078, 0x22d7, 0x1078, 0x5d1a, 0x0078, 0x6026, 0x2001, 0x000a,
-+	0x1078, 0x37f4, 0x1078, 0x22d7, 0x6003, 0x0001, 0x6007, 0x0001,
-+	0x1078, 0x498e, 0x0078, 0x6026, 0x1078, 0x609c, 0x0e7f, 0x007c,
-+	0x6800, 0xd084, 0x0040, 0x603a, 0x2001, 0x0000, 0x1078, 0x37e0,
-+	0x2069, 0x7751, 0x6804, 0xd0a4, 0x0040, 0x603a, 0x2001, 0x0006,
-+	0x1078, 0x3802, 0x007c, 0x0d7e, 0x2011, 0x771e, 0x2204, 0xa086,
-+	0x0074, 0x00c0, 0x6098, 0x1078, 0x61ea, 0x6018, 0x2068, 0xa080,
-+	0x0028, 0x2014, 0xa286, 0x007e, 0x0040, 0x6063, 0xa286, 0x0080,
-+	0x00c0, 0x608c, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
-+	0x0040, 0x6082, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833,
-+	0x0200, 0x0078, 0x6082, 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817,
-+	0xfffe, 0x2071, 0x772f, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071,
-+	0x7c80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x7719,
-+	0x206a, 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x771a, 0x206a, 0x78ea,
-+	0x0f7f, 0x0e7f, 0x2001, 0x0006, 0x1078, 0x37f4, 0x1078, 0x22d7,
-+	0x1078, 0x5d1a, 0x0078, 0x609a, 0x2001, 0x0004, 0x1078, 0x37f4,
-+	0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x498e, 0x0078, 0x609a,
-+	0x1078, 0x609c, 0x0d7f, 0x007c, 0x2001, 0x7700, 0x2004, 0xa086,
-+	0x0003, 0x0040, 0x60a7, 0x2001, 0x0007, 0x1078, 0x37f4, 0x1078,
-+	0x22d7, 0x1078, 0x5d1a, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078,
-+	0xa086, 0x0014, 0x00c0, 0x60e2, 0x7000, 0xa086, 0x0003, 0x00c0,
-+	0x60bf, 0x6010, 0xa005, 0x00c0, 0x60bf, 0x1078, 0x2dd7, 0x0d7e,
-+	0x6018, 0x2068, 0x1078, 0x38c8, 0x1078, 0x6028, 0x0d7f, 0x1078,
-+	0x61f4, 0x00c0, 0x60e2, 0x2001, 0x0006, 0x1078, 0x37f4, 0x0e7e,
-+	0x6010, 0xa005, 0x0040, 0x60db, 0x2070, 0x7007, 0x0000, 0x7037,
-+	0x0103, 0x7033, 0x0200, 0x0e7f, 0x1078, 0x22d7, 0x1078, 0x5d1a,
-+	0x0078, 0x60e6, 0x1078, 0x5f6d, 0x1078, 0x609c, 0x0e7f, 0x007c,
-+	0x2011, 0x771e, 0x2204, 0xa086, 0x0014, 0x00c0, 0x60fb, 0x2001,
-+	0x0002, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
-+	0x498e, 0x0078, 0x60fd, 0x1078, 0x609c, 0x007c, 0x2011, 0x771e,
-+	0x2204, 0xa086, 0x0004, 0x00c0, 0x610d, 0x2001, 0x0007, 0x1078,
-+	0x37f4, 0x1078, 0x5d1a, 0x0078, 0x610f, 0x1078, 0x609c, 0x007c,
-+	0x5ff7, 0x611c, 0x5ff7, 0x6142, 0x5ff7, 0x619d, 0x5ff7, 0x5ff7,
-+	0x5ff7, 0x61b2, 0x5ff7, 0x61c5, 0x0c7e, 0x1078, 0x61d8, 0x00c0,
-+	0x6131, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078,
-+	0x37f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x0078,
-+	0x6140, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900,
-+	0x00c0, 0x613e, 0x1078, 0x5d1a, 0x0078, 0x6140, 0x1078, 0x609c,
-+	0x0c7f, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x6156, 0x2001, 0x0000,
-+	0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x6003, 0x0001,
-+	0x6007, 0x0002, 0x1078, 0x498e, 0x0078, 0x6178, 0x1078, 0x5f6d,
-+	0x2009, 0x7c8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040,
-+	0x6179, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900,
-+	0x00c0, 0x6176, 0xa686, 0x0009, 0x0040, 0x6179, 0x2001, 0x0004,
-+	0x1078, 0x37f4, 0x1078, 0x5d1a, 0x0078, 0x6178, 0x1078, 0x609c,
-+	0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6187,
-+	0x6838, 0xd0fc, 0x0040, 0x6187, 0x0d7f, 0x0078, 0x6176, 0x6018,
-+	0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x6198, 0x8001,
-+	0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x6178,
-+	0x1078, 0x22b5, 0x0d7f, 0x0078, 0x6176, 0x1078, 0x61e7, 0x00c0,
-+	0x61ad, 0x2001, 0x0004, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007,
-+	0x0003, 0x1078, 0x498e, 0x0078, 0x61b1, 0x1078, 0x5f6d, 0x1078,
-+	0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x61c2, 0x2001, 0x0008,
-+	0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x498e,
-+	0x0078, 0x61c4, 0x1078, 0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0,
-+	0x61d5, 0x2001, 0x000a, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x1078, 0x498e, 0x0078, 0x61d7, 0x1078, 0x609c, 0x007c,
-+	0x2009, 0x7c8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x61e6, 0x2009,
-+	0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085,
-+	0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078,
-+	0x385e, 0x017f, 0x0c7f, 0x007c, 0x0e7e, 0x2071, 0x7c8c, 0x7004,
-+	0xa086, 0x0014, 0x00c0, 0x6217, 0x7008, 0xa086, 0x0800, 0x00c0,
-+	0x6217, 0x700c, 0xd0ec, 0x0040, 0x6215, 0xa084, 0x0f00, 0xa086,
-+	0x0100, 0x00c0, 0x6215, 0x7024, 0xd0a4, 0x0040, 0x6215, 0xd08c,
-+	0x0040, 0x6215, 0xa006, 0x0078, 0x6217, 0xa085, 0x0001, 0x0e7f,
-+	0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e,
-+	0x007e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c, 0x2021,
-+	0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7244, 0x7060,
-+	0xa202, 0x00c8, 0x626e, 0x1078, 0x7659, 0x0040, 0x6266, 0x671c,
-+	0xa786, 0x0001, 0x0040, 0x6266, 0xa786, 0x0007, 0x0040, 0x6266,
-+	0x2500, 0xac06, 0x0040, 0x6266, 0x2400, 0xac06, 0x0040, 0x6266,
-+	0x0c7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x6250, 0x1078, 0x166e,
-+	0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6263, 0xa786, 0x0003,
-+	0x00c0, 0x6278, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
-+	0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0xace0, 0x0008,
-+	0x7054, 0xac02, 0x00c8, 0x626e, 0x0078, 0x622e, 0x127f, 0x007f,
-+	0x027f, 0x047f, 0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c,
-+	0xa786, 0x0006, 0x00c0, 0x625a, 0x1078, 0x75fd, 0x0078, 0x6263,
-+	0x220c, 0x2304, 0xa106, 0x00c0, 0x628b, 0x8210, 0x8318, 0x00f0,
-+	0x6280, 0xa006, 0x007c, 0x2304, 0xa102, 0x0048, 0x6293, 0x2001,
-+	0x0001, 0x0078, 0x6295, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c,
-+	0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x6bcf, 0x0040,
-+	0x62a7, 0x1078, 0x6be3, 0x0040, 0x62b0, 0x0078, 0x62a9, 0x1078,
-+	0x22d7, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c,
-+	0x1078, 0x5f6d, 0x0078, 0x62a9, 0xa182, 0x0040, 0x0079, 0x62b8,
-+	0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8,
-+	0x62c8, 0x62c8, 0x62c8, 0x62ca, 0x62ca, 0x62ca, 0x62ca, 0x62c8,
-+	0x1078, 0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e,
-+	0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013,
-+	0x00c0, 0x62df, 0x6004, 0xa082, 0x0040, 0x0079, 0x6355, 0xa186,
-+	0x0027, 0x00c0, 0x62fc, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e,
-+	0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x62f6, 0x6837, 0x0103,
-+	0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
-+	0x5d1a, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0014, 0x00c0, 0x6305,
-+	0x6004, 0xa082, 0x0040, 0x0079, 0x6325, 0xa186, 0x0047, 0x10c0,
-+	0x12cd, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x6322, 0x127e,
-+	0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x4802, 0x027f,
-+	0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0, 0x6322,
-+	0x0078, 0x637c, 0x1078, 0x5d4f, 0x007c, 0x6337, 0x6335, 0x6335,
-+	0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335,
-+	0x634e, 0x634e, 0x634e, 0x634e, 0x6335, 0x1078, 0x12cd, 0x1078,
-+	0x4c9d, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x6348,
-+	0x6837, 0x0103, 0x684b, 0x0006, 0x1078, 0x3b92, 0x1078, 0x6ba9,
-+	0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d,
-+	0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x6367, 0x6365, 0x6365,
-+	0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365,
-+	0x6375, 0x6375, 0x6375, 0x6375, 0x6365, 0x1078, 0x12cd, 0x1078,
-+	0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96, 0x6010, 0xa088, 0x0013,
-+	0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, 0x4c9d, 0x6003,
-+	0x000f, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6380,
-+	0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6392, 0x641b, 0x6433,
-+	0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390,
-+	0x1078, 0x12cd, 0x0e7e, 0x0d7e, 0x2071, 0x7c8c, 0x6110, 0x2168,
-+	0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x63ff, 0xa68c, 0x00ff,
-+	0xa186, 0x0002, 0x0040, 0x63c4, 0xa186, 0x0028, 0x00c0, 0x63ae,
-+	0x1078, 0x6bbd, 0x684b, 0x001c, 0x0078, 0x63c6, 0xd6dc, 0x0040,
-+	0x63b9, 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078,
-+	0x63c6, 0xd6d4, 0x0040, 0x63c4, 0x684b, 0x0007, 0x7318, 0x6b62,
-+	0x731c, 0x6b5e, 0x0078, 0x63c6, 0x684b, 0x0000, 0x6837, 0x0103,
-+	0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x63d9, 0x7328, 0x732c, 0x6b56,
-+	0x037e, 0x2308, 0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841,
-+	0x037f, 0xd6cc, 0x0040, 0x640f, 0x7124, 0x695a, 0xa192, 0x0021,
-+	0x00c8, 0x63ed, 0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90,
-+	0x001d, 0x1078, 0x6841, 0x0078, 0x640f, 0x6838, 0xd0fc, 0x0040,
-+	0x63f6, 0x2009, 0x0020, 0x695a, 0x0078, 0x63e2, 0x0f7e, 0x2d78,
-+	0x1078, 0x67d9, 0x0f7f, 0x1078, 0x682e, 0x0078, 0x6411, 0x684b,
-+	0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x640f,
-+	0x6810, 0x6914, 0xa115, 0x0040, 0x640f, 0x1078, 0x6587, 0x1078,
-+	0x3b92, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x0d7f, 0x0e7f,
-+	0x1078, 0x5d1a, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c,
-+	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16,
-+	0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x49ad,
-+	0x1078, 0x4e56, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
-+	0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040,
-+	0x0079, 0x6442, 0x6452, 0x6452, 0x6452, 0x6452, 0x6452, 0x6454,
-+	0x64eb, 0x6452, 0x6452, 0x6501, 0x6563, 0x6452, 0x6452, 0x6452,
-+	0x6452, 0x656e, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e,
-+	0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
-+	0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
-+	0x86ff, 0x0040, 0x64e6, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040,
-+	0x6475, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040,
-+	0x64e6, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c,
-+	0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e,
-+	0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040,
-+	0x64af, 0xa186, 0x0028, 0x00c0, 0x6499, 0x684b, 0x001c, 0x0078,
-+	0x64b1, 0xd6dc, 0x0040, 0x64a4, 0x684b, 0x0015, 0x7318, 0x6b62,
-+	0x731c, 0x6b5e, 0x0078, 0x64b1, 0xd6d4, 0x0040, 0x64af, 0x684b,
-+	0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x64b1, 0x684b,
-+	0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4,
-+	0x0040, 0x64c6, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019,
-+	0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc, 0x0040,
-+	0x64e6, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x64da, 0x2071,
-+	0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x6841,
-+	0x0078, 0x64e6, 0x7838, 0xd0fc, 0x0040, 0x64e3, 0x2009, 0x0020,
-+	0x695a, 0x0078, 0x64cf, 0x2d78, 0x1078, 0x67d9, 0x0d7f, 0x0e7f,
-+	0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c,
-+	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16,
-+	0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x5681,
-+	0x007c, 0x0d7e, 0x6003, 0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56,
-+	0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x6561, 0xd1cc, 0x0040,
-+	0x653c, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x6534, 0x017e, 0x684c,
-+	0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009,
-+	0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0,
-+	0x6523, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168,
-+	0x1078, 0x1350, 0x0078, 0x655f, 0x017e, 0x1078, 0x1350, 0x0d7f,
-+	0x1078, 0x682e, 0x0078, 0x655f, 0x6837, 0x0103, 0x6944, 0xa184,
-+	0x00ff, 0xa186, 0x0002, 0x0040, 0x655b, 0xa086, 0x0028, 0x00c0,
-+	0x654d, 0x684b, 0x001c, 0x0078, 0x655d, 0xd1dc, 0x0040, 0x6554,
-+	0x684b, 0x0015, 0x0078, 0x655d, 0xd1d4, 0x0040, 0x655b, 0x684b,
-+	0x0007, 0x0078, 0x655d, 0x684b, 0x0000, 0x1078, 0x3b92, 0x1078,
-+	0x5d1a, 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x5880, 0x6003,
-+	0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x007c, 0x1078, 0x4d45,
-+	0x1078, 0x22b5, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040,
-+	0x6581, 0x6837, 0x0103, 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078,
-+	0x6ba9, 0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4e56, 0x007c, 0x684b,
-+	0x0015, 0xd1fc, 0x0040, 0x6593, 0x684b, 0x0007, 0x8002, 0x8000,
-+	0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x007c, 0xa182, 0x0040,
-+	0x0079, 0x659a, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65ac,
-+	0x65aa, 0x6650, 0x6658, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa,
-+	0x65aa, 0x65aa, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e,
-+	0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
-+	0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
-+	0x86ff, 0x0040, 0x6642, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040,
-+	0x65cd, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040,
-+	0x663f, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c,
-+	0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
-+	0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002,
-+	0x0040, 0x6608, 0xa186, 0x0028, 0x00c0, 0x65f2, 0x684b, 0x001c,
-+	0x0078, 0x660a, 0xd6dc, 0x0040, 0x65fd, 0x684b, 0x0015, 0x7318,
-+	0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a, 0xd6d4, 0x0040, 0x6608,
-+	0x684b, 0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a,
-+	0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
-+	0xd6c4, 0x0040, 0x661f, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308,
-+	0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc,
-+	0x0040, 0x663f, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x6633,
-+	0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
-+	0x6841, 0x0078, 0x663f, 0x7838, 0xd0fc, 0x0040, 0x663c, 0x2009,
-+	0x0020, 0x695a, 0x0078, 0x6628, 0x2d78, 0x1078, 0x67d9, 0xd6dc,
-+	0x00c0, 0x6645, 0xa006, 0x0078, 0x6649, 0x2001, 0x0001, 0x7218,
-+	0x731c, 0x1078, 0x15ae, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c,
-+	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c,
-+	0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040,
-+	0x66bf, 0xd1cc, 0x0040, 0x668f, 0x6948, 0x6838, 0xd0fc, 0x0040,
-+	0x6687, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d,
-+	0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012,
-+	0x8318, 0x8210, 0x00f0, 0x6676, 0x157f, 0x007f, 0x6852, 0x007f,
-+	0x684e, 0x017f, 0x2168, 0x1078, 0x1350, 0x0078, 0x66bd, 0x017e,
-+	0x1078, 0x1350, 0x0d7f, 0x1078, 0x682e, 0x0078, 0x66bd, 0x6837,
-+	0x0103, 0x6944, 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x66ae,
-+	0xa086, 0x0028, 0x00c0, 0x66a0, 0x684b, 0x001c, 0x0078, 0x66bb,
-+	0xd1dc, 0x0040, 0x66a7, 0x684b, 0x0015, 0x0078, 0x66bb, 0xd1d4,
-+	0x0040, 0x66ae, 0x684b, 0x0007, 0x0078, 0x66bb, 0x684b, 0x0000,
-+	0x684c, 0xd0ac, 0x0040, 0x66bb, 0x6810, 0x6914, 0xa115, 0x0040,
-+	0x66bb, 0x1078, 0x6587, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0x0d7f,
-+	0x007c, 0x1078, 0x4c9d, 0x0078, 0x66c7, 0x1078, 0x4d45, 0x1078,
-+	0x6a58, 0x0040, 0x66de, 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103,
-+	0x2009, 0x770c, 0x210c, 0xd18c, 0x00c0, 0x66e7, 0xd184, 0x00c0,
-+	0x66e3, 0x6108, 0x694a, 0x1078, 0x3b92, 0x0d7f, 0x1078, 0x5d1a,
-+	0x1078, 0x4d96, 0x007c, 0x684b, 0x0004, 0x0078, 0x66db, 0x684b,
-+	0x0004, 0x0078, 0x66db, 0xa182, 0x0040, 0x0079, 0x66ef, 0x66ff,
-+	0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x6701, 0x66ff, 0x6704, 0x66ff,
-+	0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x1078,
-+	0x12cd, 0x1078, 0x5d1a, 0x007c, 0x007e, 0x027e, 0xa016, 0x1078,
-+	0x156a, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079, 0x6710,
-+	0x6719, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x1078,
-+	0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0,
-+	0x672f, 0x6004, 0xa082, 0x0085, 0x2008, 0x0079, 0x6763, 0xa186,
-+	0x0027, 0x00c0, 0x6750, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e,
-+	0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103,
-+	0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
-+	0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x5d4f, 0x0078, 0x674b,
-+	0xa186, 0x0014, 0x00c0, 0x674c, 0x1078, 0x4c9d, 0x0d7e, 0x6010,
-+	0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103, 0x684b,
-+	0x0006, 0x0078, 0x6742, 0x676c, 0x676a, 0x676a, 0x676a, 0x676a,
-+	0x676a, 0x6775, 0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6017, 0x0014,
-+	0x6003, 0x000c, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x6017,
-+	0x0014, 0x6003, 0x000e, 0x1078, 0x4d96, 0x007c, 0xa182, 0x008c,
-+	0x00c8, 0x6788, 0xa182, 0x0085, 0x0048, 0x6788, 0x0079, 0x678b,
-+	0x1078, 0x5d4f, 0x007c, 0x6792, 0x6792, 0x6792, 0x6792, 0x6794,
-+	0x67b3, 0x6792, 0x1078, 0x12cd, 0x0d7e, 0x1078, 0x6ba9, 0x1078,
-+	0x6a58, 0x0040, 0x67af, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850,
-+	0xd0b4, 0x0040, 0x67a7, 0x684b, 0x0006, 0x0078, 0x67ab, 0x684b,
-+	0x0005, 0x1078, 0x6c5c, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078,
-+	0x5d1a, 0x0d7f, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58,
-+	0x0040, 0x67ce, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x67c4,
-+	0x684b, 0x0006, 0x0078, 0x67c8, 0x684b, 0x0005, 0x1078, 0x6c5c,
-+	0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
-+	0x5d1a, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96,
-+	0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
-+	0x0101, 0x00c8, 0x67e5, 0x0078, 0x67e7, 0x2009, 0x0100, 0x2130,
-+	0x2069, 0x7c98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
-+	0x001d, 0x1078, 0x6841, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
-+	0x67fb, 0x1078, 0x1350, 0x1078, 0x1327, 0x0040, 0x6825, 0x8528,
-+	0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
-+	0x00c8, 0x6811, 0x2608, 0xad90, 0x000f, 0x1078, 0x6841, 0x0078,
-+	0x6825, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
-+	0x1078, 0x6841, 0x0078, 0x67fb, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
-+	0x7d36, 0xa5ac, 0x0000, 0x0078, 0x682a, 0x0f7f, 0x852f, 0xa5ad,
-+	0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
-+	0x0040, 0x683f, 0x6804, 0xa07d, 0x0040, 0x683d, 0x6807, 0x0000,
-+	0x1078, 0x3b92, 0x2f68, 0x0078, 0x6832, 0x1078, 0x3b92, 0x0f7f,
-+	0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x6847, 0x8108, 0x810c,
-+	0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x6849,
-+	0x157f, 0x007c, 0x127e, 0x2091, 0x8000, 0x601c, 0xa084, 0x000f,
-+	0x1079, 0x685c, 0x127f, 0x007c, 0x686b, 0x6864, 0x6866, 0x6884,
-+	0x6864, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0xa006, 0x007c,
-+	0xa085, 0x0001, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58,
-+	0x0040, 0x6881, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x1078,
-+	0x6c5c, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0xa085, 0x0001, 0x0d7f,
-+	0x007c, 0xa006, 0x0078, 0x687f, 0x6000, 0xa08a, 0x0010, 0x10c8,
-+	0x12cd, 0x1079, 0x688c, 0x007c, 0x689c, 0x68b9, 0x689e, 0x68ca,
-+	0x68b5, 0x689c, 0x6866, 0x686b, 0x686b, 0x6866, 0x6866, 0x6866,
-+	0x6866, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0x0d7e, 0x6010,
-+	0x2068, 0x1078, 0x6a58, 0x0040, 0x68a7, 0x1078, 0x6c5c, 0x0d7f,
-+	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941,
-+	0x1078, 0x4d96, 0xa085, 0x0001, 0x007c, 0x1078, 0x166e, 0x0078,
-+	0x689e, 0x0e7e, 0x2071, 0x7936, 0x7024, 0xac06, 0x00c0, 0x68c2,
-+	0x1078, 0x57ee, 0x1078, 0x5725, 0x0e7f, 0x00c0, 0x689e, 0x1078,
-+	0x6866, 0x007c, 0x037e, 0x0e7e, 0x2071, 0x7936, 0x703c, 0xac06,
-+	0x00c0, 0x68da, 0x2019, 0x0000, 0x1078, 0x5880, 0x0e7f, 0x037f,
-+	0x0078, 0x689e, 0x1078, 0x5b5c, 0x0e7f, 0x037f, 0x00c0, 0x689e,
-+	0x1078, 0x6866, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079,
-+	0x68eb, 0x0c7f, 0x007c, 0x68fa, 0x6957, 0x69fc, 0x68fe, 0x68fa,
-+	0x68fa, 0x72dd, 0x5d1a, 0x6957, 0x1078, 0x6be3, 0x00c0, 0x68fa,
-+	0x1078, 0x5f6d, 0x007c, 0x6017, 0x0001, 0x007c, 0x6000, 0xa08a,
-+	0x0010, 0x10c8, 0x12cd, 0x1079, 0x6906, 0x007c, 0x6916, 0x6918,
-+	0x6938, 0x694a, 0x694a, 0x6916, 0x68fa, 0x68fa, 0x68fa, 0x694a,
-+	0x694a, 0x6916, 0x6916, 0x6916, 0x6916, 0x6954, 0x1078, 0x12cd,
-+	0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0x7936,
-+	0x7024, 0xac06, 0x0040, 0x6934, 0x1078, 0x5725, 0x6007, 0x0085,
-+	0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, 0x1078, 0x4941,
-+	0x1078, 0x4d96, 0x0e7f, 0x007c, 0x6017, 0x0001, 0x0078, 0x6932,
-+	0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x6007,
-+	0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941, 0x1078,
-+	0x4d96, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010, 0x2068, 0x6850,
-+	0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x5d1a, 0x007c, 0x6000,
-+	0xa08a, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x695f, 0x007c, 0x696f,
-+	0x68fb, 0x6971, 0x696f, 0x6971, 0x696f, 0x696f, 0x696f, 0x68f4,
-+	0x68f4, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x1078,
-+	0x12cd, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
-+	0xa08a, 0x000c, 0x10c8, 0x12cd, 0x1079, 0x697f, 0x007c, 0x698b,
-+	0x69aa, 0x698b, 0x69aa, 0x698b, 0x69aa, 0x698d, 0x6996, 0x698b,
-+	0x69aa, 0x698b, 0x69a3, 0x1078, 0x12cd, 0x6004, 0xa08e, 0x0004,
-+	0x0040, 0x69a5, 0xa08e, 0x0002, 0x0040, 0x69a5, 0x6004, 0x1078,
-+	0x6be3, 0x0040, 0x69f4, 0xa08e, 0x0021, 0x0040, 0x69f8, 0xa08e,
-+	0x0022, 0x0040, 0x69f4, 0x1078, 0x22b5, 0x1078, 0x5f6d, 0x1078,
-+	0x5d1a, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040,
-+	0x69e4, 0xa186, 0x0002, 0x00c0, 0x69d3, 0x6018, 0x2068, 0x68a0,
-+	0xd0bc, 0x00c0, 0x69d3, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040,
-+	0x69d3, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017,
-+	0x0398, 0x1078, 0x5cb4, 0x0040, 0x69d3, 0x2d00, 0x601a, 0x601f,
-+	0x0001, 0x0078, 0x69e4, 0x0d7f, 0x0c7f, 0x1078, 0x5f6d, 0x1078,
-+	0x22b5, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x22d7, 0x127f,
-+	0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x2001, 0x0002, 0x1078, 0x37f4,
-+	0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96,
-+	0x0d7f, 0x0c7f, 0x0078, 0x69e3, 0x1078, 0x5f6d, 0x0078, 0x69a7,
-+	0x1078, 0x5f7c, 0x0078, 0x69a7, 0x6000, 0xa08a, 0x0010, 0x10c8,
-+	0x12cd, 0x1079, 0x6a04, 0x007c, 0x6a14, 0x6a14, 0x6a14, 0x6a14,
-+	0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x68fa, 0x6a14, 0x68fb,
-+	0x6a16, 0x68fb, 0x6a1f, 0x6a14, 0x1078, 0x12cd, 0x6007, 0x008b,
-+	0x6003, 0x000d, 0x1078, 0x4941, 0x1078, 0x4d96, 0x007c, 0x1078,
-+	0x6ba9, 0x1078, 0x6a58, 0x0040, 0x6a41, 0x1078, 0x22b5, 0x0d7e,
-+	0x1078, 0x6a58, 0x0040, 0x6a34, 0x6010, 0x2068, 0x6837, 0x0103,
-+	0x684b, 0x0006, 0x1078, 0x3b92, 0x0d7f, 0x601f, 0x0001, 0x6007,
-+	0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0078,
-+	0x6a43, 0x1078, 0x5d1a, 0x007c, 0xa284, 0x0007, 0x00c0, 0x6a55,
-+	0xa282, 0x7e00, 0x0048, 0x6a55, 0x2001, 0x7715, 0x2004, 0xa202,
-+	0x00c8, 0x6a55, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x6a54,
-+	0x027e, 0x0e7e, 0x2071, 0x7700, 0x6210, 0x7058, 0xa202, 0x0048,
-+	0x6a6a, 0x705c, 0xa202, 0x00c8, 0x6a6a, 0xa085, 0x0001, 0x0e7f,
-+	0x027f, 0x007c, 0xa006, 0x0078, 0x6a67, 0x0e7e, 0x0c7e, 0x037e,
-+	0x007e, 0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2071, 0x7700,
-+	0x7344, 0x7060, 0xa302, 0x00c8, 0x6a93, 0x601c, 0xa206, 0x00c0,
-+	0x6a8b, 0x1078, 0x6be3, 0x00c0, 0x6a87, 0x1078, 0x5f6d, 0x0c7e,
-+	0x1078, 0x5d1a, 0x0c7f, 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8,
-+	0x6a93, 0x0078, 0x6a78, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
-+	0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0x7820, 0x210c, 0x81ff,
-+	0x0040, 0x6ab1, 0x2061, 0x7e00, 0x2071, 0x7700, 0x017e, 0x1078,
-+	0x5cb4, 0x017f, 0x0040, 0x6ab4, 0x611a, 0x1078, 0x22b5, 0x1078,
-+	0x5d1a, 0xa006, 0x0078, 0x6ab6, 0xa085, 0x0001, 0x017f, 0x0c7f,
-+	0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
-+	0x1078, 0x5cb4, 0x057f, 0x0040, 0x6ad3, 0x6612, 0x651a, 0x601f,
-+	0x0003, 0x2009, 0x004b, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f,
-+	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6acf, 0x0c7e, 0x057e,
-+	0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f,
-+	0x0040, 0x6afd, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
-+	0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1,
-+	0x2c08, 0x1078, 0x747b, 0x2009, 0x004c, 0x1078, 0x5d41, 0xa085,
-+	0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6af9,
-+	0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078,
-+	0x5cb4, 0x057f, 0x0040, 0x6b28, 0x6612, 0x651a, 0x601f, 0x0003,
-+	0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078,
-+	0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x2009, 0x004d,
-+	0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c,
-+	0xa006, 0x0078, 0x6b24, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000,
-+	0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f, 0x0040, 0x6b53, 0x6612,
-+	0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078,
-+	0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078,
-+	0x747b, 0x2009, 0x004e, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f,
-+	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b4f, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6b6f,
-+	0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f,
-+	0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
-+	0x0078, 0x6b6c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-+	0x5cb4, 0x017f, 0x0040, 0x6b8b, 0x660a, 0x611a, 0x601f, 0x0008,
-+	0x2d00, 0x6012, 0x2009, 0x0021, 0x1078, 0x5d41, 0xa085, 0x0001,
-+	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b88, 0x0c7e, 0x127e,
-+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6ba6,
-+	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078,
-+	0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
-+	0x6ba3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040,
-+	0x6bb3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x6013, 0x0000,
-+	0x601f, 0x0007, 0x6017, 0x0014, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
-+	0x2031, 0x7752, 0x2634, 0xd6e4, 0x0040, 0x6bcb, 0x6618, 0x2660,
-+	0x6e48, 0x1078, 0x3942, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
-+	0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x6be0, 0xa08e, 0x0003,
-+	0x0040, 0x6be0, 0xa08e, 0x0004, 0x0040, 0x6be0, 0xa085, 0x0001,
-+	0x017f, 0x007f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0000,
-+	0x0040, 0x6bf8, 0xa08e, 0x001f, 0x0040, 0x6bf8, 0xa08e, 0x0028,
-+	0x0040, 0x6bf8, 0xa08e, 0x0029, 0x0040, 0x6bf8, 0xa085, 0x0001,
-+	0x017f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e,
-+	0x1078, 0x5cb4, 0x017f, 0x0040, 0x6c15, 0x611a, 0x601f, 0x0001,
-+	0x2d00, 0x6012, 0x1078, 0x22b5, 0x2009, 0x0028, 0x1078, 0x5d41,
-+	0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6c12,
-+	0xa186, 0x0015, 0x00c0, 0x6c2d, 0x2011, 0x771e, 0x2204, 0xa086,
-+	0x0074, 0x00c0, 0x6c2d, 0x1078, 0x61ea, 0x6003, 0x0001, 0x6007,
-+	0x0029, 0x1078, 0x498e, 0x0078, 0x6c31, 0x1078, 0x5f6d, 0x1078,
-+	0x5d1a, 0x007c, 0xa186, 0x0015, 0x00c0, 0x6c4f, 0x2011, 0x771e,
-+	0x2204, 0xa086, 0x0014, 0x00c0, 0x6c4f, 0x0d7e, 0x6018, 0x2068,
-+	0x1078, 0x38c8, 0x0d7f, 0x1078, 0x61f4, 0x00c0, 0x6c4f, 0x2001,
-+	0x0006, 0x1078, 0x37f4, 0x1078, 0x5dc5, 0x0078, 0x6c53, 0x1078,
-+	0x5f6d, 0x1078, 0x5d1a, 0x007c, 0x6848, 0xa086, 0x0005, 0x00c0,
-+	0x6c5b, 0x1078, 0x6c5c, 0x007c, 0x6850, 0xc0ad, 0x6852, 0x007c,
-+	0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6c6a,
-+	0x067f, 0x007c, 0x6c7a, 0x6e51, 0x6f32, 0x6c7a, 0x6c7a, 0x6c7a,
-+	0x6c7a, 0x6c7a, 0x6cb4, 0x6fa0, 0x6c7a, 0x6c7a, 0x6c7a, 0x6c7a,
-+	0x6c7a, 0x6c7a, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010,
-+	0x10c8, 0x12cd, 0x1079, 0x6c86, 0x067f, 0x007c, 0x6c96, 0x728c,
-+	0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x7267, 0x72d6,
-+	0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x1078, 0x12cd,
-+	0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6ca2,
-+	0x067f, 0x007c, 0x6cb2, 0x70d8, 0x714a, 0x716c, 0x71b8, 0x6cb2,
-+	0x6cb2, 0x7212, 0x6fac, 0x724f, 0x7253, 0x6cb2, 0x6cb2, 0x6cb2,
-+	0x6cb2, 0x6cb2, 0x1078, 0x12cd, 0xa1b2, 0x0030, 0x10c8, 0x12cd,
-+	0x2100, 0x0079, 0x6cbb, 0x6ceb, 0x6dc8, 0x6ceb, 0x6ceb, 0x6ceb,
-+	0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb,
-+	0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb,
-+	0x6ceb, 0x6ceb, 0x6ced, 0x6d1c, 0x6d27, 0x6d4f, 0x6d55, 0x6d89,
-+	0x6dc1, 0x6ceb, 0x6ceb, 0x6dd0, 0x6ceb, 0x6ceb, 0x6dd7, 0x6dde,
-+	0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6dfb, 0x6ceb, 0x6ceb,
-+	0x6e06, 0x6ceb, 0x6ceb, 0x1078, 0x12cd, 0x1078, 0x3b3e, 0x6618,
-+	0x0c7e, 0x2660, 0x1078, 0x385e, 0x0c7f, 0xa6b0, 0x0001, 0x2634,
-+	0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x6d0e, 0x1078, 0x73b7,
-+	0x00c0, 0x6d49, 0x1078, 0x7355, 0x00c0, 0x6d0a, 0x6007, 0x0008,
-+	0x0078, 0x6dc3, 0x6007, 0x0009, 0x0078, 0x6dc3, 0x1078, 0x754c,
-+	0x0040, 0x6d18, 0x1078, 0x73b7, 0x0040, 0x6d02, 0x0078, 0x6d49,
-+	0x6013, 0x1900, 0x0078, 0x6d0a, 0x6106, 0x1078, 0x7317, 0x6007,
-+	0x0006, 0x0078, 0x6dc3, 0x6007, 0x0007, 0x0078, 0x6dc3, 0x0d7e,
-+	0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006,
-+	0x0040, 0x6d39, 0xa686, 0x0004, 0x0040, 0x6d39, 0x0d7f, 0x0078,
-+	0x6d49, 0x1078, 0x7415, 0x00c0, 0x6d44, 0x1078, 0x38c8, 0x6007,
-+	0x000a, 0x0d7f, 0x0078, 0x6dc3, 0x6007, 0x000b, 0x0d7f, 0x0078,
-+	0x6dc3, 0x1078, 0x22b5, 0x6007, 0x0001, 0x0078, 0x6dc3, 0x1078,
-+	0x22b5, 0x6007, 0x000c, 0x0078, 0x6dc3, 0x1078, 0x3b3e, 0x6618,
-+	0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048,
-+	0x6d76, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x00c0, 0x6d49,
-+	0x1078, 0x7424, 0x00c0, 0x6d70, 0x6007, 0x000e, 0x0078, 0x6dc3,
-+	0x1078, 0x22b5, 0x6007, 0x000f, 0x0078, 0x6dc3, 0x1078, 0x754c,
-+	0x0040, 0x6d83, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040,
-+	0x6d68, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078,
-+	0x6dc3, 0x1078, 0x3b3e, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
-+	0x00ff, 0xa082, 0x0006, 0x0048, 0x6dae, 0xa6b4, 0xff00, 0x8637,
-+	0xa686, 0x0006, 0x00c0, 0x6d49, 0x1078, 0x744f, 0x00c0, 0x6da8,
-+	0x1078, 0x7355, 0x00c0, 0x6da8, 0x6007, 0x0010, 0x0078, 0x6dc3,
-+	0x1078, 0x22b5, 0x6007, 0x0011, 0x0078, 0x6dc3, 0x1078, 0x754c,
-+	0x0040, 0x6dbb, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040,
-+	0x6d9c, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078,
-+	0x6dc3, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c,
-+	0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x0078, 0x6dc7,
-+	0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x6007,
-+	0x0023, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x017e, 0x027e,
-+	0x2011, 0x7c88, 0x2214, 0x2c08, 0x1078, 0x7614, 0x00c0, 0x6def,
-+	0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x0078, 0x6df4, 0x1078,
-+	0x5d1a, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x498e,
-+	0x027f, 0x017f, 0x007c, 0x6106, 0x1078, 0x6e0d, 0x6007, 0x002b,
-+	0x0078, 0x6dc3, 0x6007, 0x002c, 0x0078, 0x6dc3, 0x6106, 0x1078,
-+	0x6e12, 0x6007, 0x002e, 0x0078, 0x6dc3, 0x0d7e, 0x1078, 0x6e38,
-+	0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x6e47, 0x00c0, 0x6e31, 0x680c,
-+	0xa08c, 0xff00, 0x6824, 0xa084, 0x00ff, 0xa115, 0x6212, 0xd1e4,
-+	0x0040, 0x6e26, 0x2009, 0x0001, 0x0078, 0x6e2d, 0xd1ec, 0x0040,
-+	0x6e31, 0x2009, 0x0000, 0xa294, 0x00ff, 0x1078, 0x22f9, 0x0078,
-+	0x6e35, 0xa085, 0x0001, 0x0078, 0x6e36, 0xa006, 0x0d7f, 0x007c,
-+	0x2069, 0x7c8d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x6e45, 0x6013,
-+	0x0000, 0xa085, 0x0001, 0x0078, 0x6e46, 0xa006, 0x007c, 0x6013,
-+	0x0000, 0x2069, 0x7c8c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800,
-+	0x007c, 0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013,
-+	0x00c0, 0x6e5d, 0x2008, 0x0079, 0x6e70, 0xa1b6, 0x0027, 0x0040,
-+	0x6e65, 0xa1b6, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078,
-+	0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c,
-+	0x6ea0, 0x6ea2, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea2, 0x6eaa, 0x6f0d,
-+	0x6ed0, 0x6f0d, 0x6ee4, 0x6f0d, 0x6eaa, 0x6f0d, 0x6f05, 0x6f0d,
-+	0x6f05, 0x6f0d, 0x6f0d, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0,
-+	0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0,
-+	0x6f0d, 0x6ea0, 0x6ea0, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0,
-+	0x6ea0, 0x6ea0, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d,
-+	0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96,
-+	0x0078, 0x6f13, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac,
-+	0x00c0, 0x6f0d, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002,
-+	0x1078, 0x37f4, 0x1078, 0x4c9d, 0x601f, 0x0001, 0x6003, 0x0001,
-+	0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0c7e, 0x6118,
-+	0x2160, 0x2009, 0x0001, 0x1078, 0x4696, 0x0c7f, 0x0078, 0x6f13,
-+	0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, 0x8637,
-+	0xa686, 0x0006, 0x0040, 0x6f0d, 0xa686, 0x0004, 0x0040, 0x6f0d,
-+	0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x7700, 0x2004, 0xa086,
-+	0x0003, 0x00c0, 0x6eed, 0x1078, 0x2dd7, 0x2001, 0x0006, 0x1078,
-+	0x6f14, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0040, 0x6f0d, 0x2001, 0x0006, 0x0078,
-+	0x6f0b, 0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x0006, 0x1078,
-+	0x6f14, 0x0078, 0x6f0d, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078,
-+	0x5d1a, 0x1078, 0x4d96, 0x007c, 0x017e, 0x0d7e, 0x6118, 0x2168,
-+	0x6900, 0xd184, 0x0040, 0x6f2f, 0x6104, 0xa18e, 0x000a, 0x00c0,
-+	0x6f27, 0x699c, 0xd1a4, 0x00c0, 0x6f27, 0x2001, 0x0007, 0x1078,
-+	0x37f4, 0x2001, 0x0000, 0x1078, 0x37e0, 0x1078, 0x22d7, 0x0d7f,
-+	0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0xff00,
-+	0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12cd, 0xa1b6, 0x0015,
-+	0x00c0, 0x6f46, 0x1079, 0x6f4d, 0x0078, 0x6f4c, 0xa1b6, 0x0016,
-+	0x10c0, 0x12cd, 0x1079, 0x6f85, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7,
-+	0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f59, 0x5ff7, 0x5ff7, 0x5ff7,
-+	0x5ff7, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac, 0x00c0,
-+	0x6f75, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078,
-+	0x37f4, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
-+	0x498e, 0x1078, 0x4d96, 0x0078, 0x6f84, 0x2011, 0x7c83, 0x220c,
-+	0x017e, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x6f84, 0x1078, 0x3637,
-+	0x0c7f, 0x017f, 0x1078, 0x5d1a, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7,
-+	0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f91, 0x5ff7, 0x5ff7, 0x5ff7,
-+	0x5ff7, 0x1078, 0x61e7, 0x00c0, 0x6f9d, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x1078, 0x498e, 0x0078, 0x6f9f, 0x1078, 0x5d1a, 0x007c,
-+	0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x4c9d, 0x1078,
-+	0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6fb0,
-+	0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc2, 0x6fc0, 0x6fc0, 0x6fc0,
-+	0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0,
-+	0x1078, 0x12cd, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, 0x027e,
-+	0x6106, 0x2071, 0x7c80, 0x7444, 0xa4a4, 0xe600, 0x0040, 0x7026,
-+	0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00,
-+	0xa284, 0x0001, 0x0040, 0x7091, 0x1078, 0x47e6, 0x0040, 0x70bc,
-+	0xa295, 0x0200, 0x6a02, 0x0078, 0x6feb, 0x2009, 0x0001, 0x2011,
-+	0x0200, 0x1078, 0x47d0, 0x1078, 0x1327, 0x1040, 0x12cd, 0x6003,
-+	0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000,
-+	0x6c5a, 0x2c00, 0x685e, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
-+	0x694a, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036,
-+	0x1078, 0x3b92, 0xa486, 0x2000, 0x00c0, 0x7014, 0x2019, 0x0017,
-+	0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0400, 0x00c0, 0x701e,
-+	0x2019, 0x0002, 0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0200,
-+	0x00c0, 0x7024, 0x1078, 0x75ca, 0x0078, 0x707e, 0x2009, 0x0000,
-+	0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00, 0xa284, 0x0001,
-+	0x0040, 0x70d4, 0xa284, 0x0300, 0x00c0, 0x70cc, 0x6804, 0xa005,
-+	0x0040, 0x70bc, 0x8001, 0x6806, 0x6003, 0x0007, 0x1078, 0x130c,
-+	0x0040, 0x7085, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116,
-+	0x683b, 0x0000, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007,
-+	0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7044, 0xa084, 0x0003,
-+	0xa086, 0x0002, 0x00c0, 0x7060, 0x684f, 0x0040, 0x0078, 0x706a,
-+	0xa086, 0x0001, 0x00c0, 0x7068, 0x684f, 0x0080, 0x0078, 0x706a,
-+	0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x7c90, 0xad90, 0x0015,
-+	0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x7070, 0x200c,
-+	0x6982, 0x8000, 0x200c, 0x697e, 0x1078, 0x3b92, 0x027f, 0x047f,
-+	0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003,
-+	0x0001, 0x6007, 0x0041, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078,
-+	0x707e, 0x2069, 0x7c92, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200,
-+	0x00c0, 0x70b0, 0x2069, 0x7c80, 0x686c, 0xa084, 0x00ff, 0x017e,
-+	0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001,
-+	0x6007, 0x0043, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078, 0x707e,
-+	0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941,
-+	0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0300, 0x0078, 0x70c2,
-+	0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941,
-+	0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0500, 0x0078, 0x70c2,
-+	0x6013, 0x0600, 0x0078, 0x7091, 0x6013, 0x0200, 0x0078, 0x7091,
-+	0xa186, 0x0013, 0x00c0, 0x70ea, 0x6004, 0xa08a, 0x0040, 0x1048,
-+	0x12cd, 0xa08a, 0x0050, 0x10c8, 0x12cd, 0xa082, 0x0040, 0x2008,
-+	0x0079, 0x711b, 0xa186, 0x0047, 0x00c0, 0x70f0, 0x0078, 0x714a,
-+	0xa186, 0x0027, 0x0040, 0x70f8, 0xa186, 0x0014, 0x10c0, 0x12cd,
-+	0x6004, 0xa082, 0x0040, 0x2008, 0x0079, 0x70fe, 0x710e, 0x7110,
-+	0x7110, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e,
-+	0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x1078, 0x12cd,
-+	0x2001, 0x0007, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6,
-+	0x1078, 0x4d96, 0x007c, 0x712b, 0x713b, 0x7134, 0x7144, 0x712b,
-+	0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b,
-+	0x712b, 0x712b, 0x712b, 0x1078, 0x12cd, 0x6010, 0xa088, 0x0013,
-+	0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x4c9d, 0x6003, 0x0002,
-+	0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x47a8, 0x1078,
-+	0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x2009, 0x0041,
-+	0x0078, 0x7212, 0xa182, 0x0040, 0x0079, 0x714e, 0x715e, 0x7160,
-+	0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x7161, 0x715e, 0x715e,
-+	0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x1078, 0x12cd,
-+	0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
-+	0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040, 0x0079, 0x7170,
-+	0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180,
-+	0x7180, 0x7182, 0x71a5, 0x7180, 0x7180, 0x7180, 0x7180, 0x71a5,
-+	0x1078, 0x12cd, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x6010, 0x0d7e,
-+	0x2068, 0x684c, 0xd0fc, 0x0040, 0x7198, 0xa08c, 0x0003, 0xa18e,
-+	0x0002, 0x0040, 0x719e, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x7212,
-+	0x6003, 0x0007, 0x1078, 0x47a8, 0x0d7f, 0x007c, 0x1078, 0x47a8,
-+	0x1078, 0x5d1a, 0x0d7f, 0x0078, 0x719d, 0x037e, 0x1078, 0x4d45,
-+	0x1078, 0x4e56, 0x6010, 0x0d7e, 0x2068, 0x2019, 0x0004, 0x1078,
-+	0x75fd, 0x1078, 0x6bb6, 0x6017, 0x0028, 0x0d7f, 0x037f, 0x007c,
-+	0xa186, 0x0013, 0x00c0, 0x71c6, 0x6004, 0xa086, 0x0042, 0x10c0,
-+	0x12cd, 0x1078, 0x4c9d, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0027,
-+	0x0040, 0x71ce, 0xa186, 0x0014, 0x00c0, 0x71de, 0x6004, 0xa086,
-+	0x0042, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078, 0x3802, 0x1078,
-+	0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040,
-+	0x0079, 0x71e2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
-+	0x71f2, 0x71f4, 0x7200, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
-+	0x71f2, 0x71f2, 0x1078, 0x12cd, 0x037e, 0x047e, 0x20e1, 0x0005,
-+	0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x047f, 0x037f, 0x007c,
-+	0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x720c, 0x2009,
-+	0x0041, 0x0d7f, 0x0078, 0x7212, 0x6003, 0x0007, 0x1078, 0x47a8,
-+	0x0d7f, 0x007c, 0xa182, 0x0040, 0x0079, 0x7216, 0x7226, 0x7228,
-+	0x7234, 0x7240, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226,
-+	0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x1078, 0x12cd,
-+	0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091, 0x8000,
-+	0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
-+	0x4941, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c,
-+	0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x19c7, 0x127e, 0x2091,
-+	0x8000, 0x1078, 0x49ad, 0x1078, 0x4e56, 0x127f, 0x007c, 0x1078,
-+	0x4c9d, 0x0078, 0x7255, 0x1078, 0x4d45, 0x6110, 0x81ff, 0x0040,
-+	0x7262, 0x0d7e, 0x2168, 0x037e, 0x2019, 0x0029, 0x1078, 0x75fd,
-+	0x037f, 0x0d7f, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182,
-+	0x0085, 0x0079, 0x726b, 0x7272, 0x7272, 0x7272, 0x7274, 0x7272,
-+	0x7272, 0x7272, 0x1078, 0x12cd, 0x027e, 0x0e7e, 0x2071, 0x7c80,
-+	0x7220, 0x1078, 0x7517, 0x0040, 0x7281, 0x6007, 0x0086, 0x0078,
-+	0x7283, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078, 0x4941, 0x1078,
-+	0x4d96, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x729d,
-+	0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a, 0x008c, 0x10c8,
-+	0x12cd, 0xa082, 0x0085, 0x0079, 0x72b0, 0xa186, 0x0027, 0x0040,
-+	0x72a5, 0xa186, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078,
-+	0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c,
-+	0x72b7, 0x72b9, 0x72b9, 0x72b7, 0x72b7, 0x72b7, 0x72b7, 0x1078,
-+	0x12cd, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c,
-+	0xa182, 0x0085, 0x1048, 0x12cd, 0xa182, 0x008c, 0x10c8, 0x12cd,
-+	0xa182, 0x0085, 0x0079, 0x72cc, 0x72d3, 0x72d3, 0x72d3, 0x72d5,
-+	0x72d3, 0x72d3, 0x72d3, 0x1078, 0x12cd, 0x007c, 0x1078, 0x4c9d,
-+	0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0x037e, 0x2019, 0x000b,
-+	0x1078, 0x72e6, 0x601f, 0x0006, 0x037f, 0x007c, 0x127e, 0x037e,
-+	0x087e, 0x2091, 0x8000, 0x2c40, 0x1078, 0x5a2d, 0x00c0, 0x7313,
-+	0x1078, 0x5ace, 0x00c0, 0x7313, 0x6000, 0xa086, 0x0000, 0x0040,
-+	0x7313, 0x601c, 0xa086, 0x0007, 0x0040, 0x7313, 0x0d7e, 0x6000,
-+	0xa086, 0x0004, 0x00c0, 0x7306, 0x1078, 0x166e, 0x6010, 0x2068,
-+	0x1078, 0x6a58, 0x0040, 0x730e, 0x1078, 0x75fd, 0x0d7f, 0x6013,
-+	0x0000, 0x601f, 0x0007, 0x087f, 0x037f, 0x127f, 0x007c, 0x0f7e,
-+	0x0c7e, 0x037e, 0x157e, 0x2079, 0x7c80, 0x7838, 0xa08c, 0x00ff,
-+	0x783c, 0x1078, 0x207f, 0x00c0, 0x734e, 0x017e, 0x0c7e, 0x1078,
-+	0x384c, 0x00c0, 0x734e, 0x2011, 0x7c90, 0xac98, 0x000a, 0x20a9,
-+	0x0004, 0x1078, 0x6280, 0x00c0, 0x734e, 0x017f, 0x027f, 0x027e,
-+	0x017e, 0x2019, 0x0029, 0x1078, 0x5ba2, 0x1078, 0x4a7e, 0x1078,
-+	0x49c1, 0x017f, 0x1078, 0x747b, 0x1078, 0x3a36, 0x017f, 0x1078,
-+	0x3637, 0x6612, 0x6516, 0xa006, 0x0078, 0x7350, 0x0c7f, 0x017f,
-+	0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x017e,
-+	0x2009, 0x771e, 0x2104, 0xa086, 0x0074, 0x00c0, 0x73ac, 0x2069,
-+	0x7c8e, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c, 0x6908, 0xa184,
-+	0x8000, 0x0040, 0x73a8, 0xa184, 0x0800, 0x0040, 0x73a8, 0x6910,
-+	0xa18a, 0x0001, 0x0048, 0x73a0, 0x6914, 0x2069, 0x7cae, 0x6904,
-+	0x81ff, 0x00c0, 0x7394, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c,
-+	0x6908, 0x81ff, 0x00c0, 0x7398, 0x6910, 0xa18a, 0x0001, 0x0048,
-+	0x73a0, 0x6918, 0xa18a, 0x0001, 0x0048, 0x73a8, 0x0078, 0x73b2,
-+	0x6013, 0x0100, 0x0078, 0x73ae, 0x6013, 0x0300, 0x0078, 0x73ae,
-+	0x6013, 0x0500, 0x0078, 0x73ae, 0x6013, 0x0700, 0x0078, 0x73ae,
-+	0x6013, 0x0900, 0x0078, 0x73ae, 0x6013, 0x0b00, 0x0078, 0x73ae,
-+	0x6013, 0x0f00, 0x0078, 0x73ae, 0x6013, 0x2d00, 0xa085, 0x0001,
-+	0x0078, 0x73b3, 0xa006, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e,
-+	0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394,
-+	0x00ff, 0xa286, 0x0006, 0x0040, 0x73db, 0xa286, 0x0004, 0x0040,
-+	0x73db, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x73db,
-+	0xa286, 0x0004, 0x0040, 0x73db, 0x0c7e, 0x2d60, 0x1078, 0x385e,
-+	0x0c7f, 0x0078, 0x740e, 0x2011, 0x7c96, 0xad98, 0x000a, 0x20a9,
-+	0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x2011, 0x7c9a, 0xad98,
-+	0x0006, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x047e,
-+	0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x7752,
-+	0x210c, 0xd1a4, 0x0040, 0x7403, 0x2009, 0x0029, 0x1078, 0x7641,
-+	0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078,
-+	0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f, 0x047f, 0xa006, 0x157f,
-+	0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0x7c8e,
-+	0x6800, 0xa086, 0x0800, 0x0040, 0x7421, 0x6013, 0x0000, 0x0078,
-+	0x7422, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e,
-+	0x037e, 0x157e, 0x2079, 0x7c8c, 0x7930, 0x7834, 0x1078, 0x207f,
-+	0x00c0, 0x7448, 0x1078, 0x384c, 0x00c0, 0x7448, 0x2011, 0x7c90,
-+	0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x7448,
-+	0x2011, 0x7c94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x6280,
-+	0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e,
-+	0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0x7c83, 0x2204,
-+	0x8211, 0x220c, 0x1078, 0x207f, 0x00c0, 0x7474, 0x1078, 0x384c,
-+	0x00c0, 0x7474, 0x2011, 0x7c96, 0xac98, 0x000a, 0x20a9, 0x0004,
-+	0x1078, 0x6280, 0x00c0, 0x7474, 0x2011, 0x7c9a, 0xac98, 0x0006,
-+	0x20a9, 0x0004, 0x1078, 0x6280, 0x157f, 0x037f, 0x027f, 0x017f,
-+	0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e,
-+	0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c,
-+	0x2021, 0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7644,
-+	0x7060, 0x8001, 0xa602, 0x00c8, 0x74e0, 0x2100, 0xac06, 0x0040,
-+	0x74d6, 0x1078, 0x7659, 0x0040, 0x74d6, 0x671c, 0xa786, 0x0001,
-+	0x0040, 0x74f5, 0xa786, 0x0007, 0x0040, 0x74d6, 0x2500, 0xac06,
-+	0x0040, 0x74d6, 0x2400, 0xac06, 0x0040, 0x74d6, 0x1078, 0x766d,
-+	0x00c0, 0x74d6, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x74bc,
-+	0x017e, 0x1078, 0x166e, 0x017f, 0x6010, 0x2068, 0x1078, 0x6a58,
-+	0x0040, 0x74d3, 0xa786, 0x0003, 0x00c0, 0x74e9, 0x6837, 0x0103,
-+	0x6b4a, 0x6847, 0x0000, 0x017e, 0x1078, 0x6c54, 0x1078, 0x3b92,
-+	0x017f, 0x1078, 0x6ba9, 0x0d7f, 0x1078, 0x6bb6, 0xace0, 0x0008,
-+	0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x74e0, 0x0078, 0x748d,
-+	0x127f, 0x027f, 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f,
-+	0x007c, 0xa786, 0x0006, 0x00c0, 0x74c6, 0xa386, 0x0005, 0x0040,
-+	0x74d6, 0x1078, 0x75fd, 0x0078, 0x74d3, 0x1078, 0x766d, 0x00c0,
-+	0x74d6, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x00c0, 0x74d6,
-+	0x6000, 0xa086, 0x0002, 0x00c0, 0x74d6, 0x1078, 0x6bcf, 0x0040,
-+	0x7511, 0x1078, 0x6be3, 0x00c0, 0x74d6, 0x1078, 0x5f6d, 0x0078,
-+	0x7513, 0x1078, 0x22d7, 0x1078, 0x6bb6, 0x0078, 0x74d6, 0x0c7e,
-+	0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x7614, 0x017f, 0x0040,
-+	0x7526, 0x601c, 0xa084, 0x000f, 0x1079, 0x7529, 0x0e7f, 0x0c7f,
-+	0x007c, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7533,
-+	0x7531, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, 0x0028,
-+	0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x1078,
-+	0x7641, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, 0x72e6,
-+	0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x37e0,
-+	0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x7705,
-+	0x2011, 0x7c96, 0x1078, 0x6280, 0x037f, 0x027f, 0x017f, 0x157f,
-+	0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e,
-+	0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2079, 0x0001, 0x8fff,
-+	0x0040, 0x75bd, 0x2071, 0x7700, 0x7644, 0x7060, 0x8001, 0xa602,
-+	0x00c8, 0x75bd, 0x88ff, 0x0040, 0x7583, 0x2800, 0xac06, 0x00c0,
-+	0x75b3, 0x2079, 0x0000, 0x1078, 0x7659, 0x0040, 0x75b3, 0x2400,
-+	0xac06, 0x0040, 0x75b3, 0x671c, 0xa786, 0x0006, 0x00c0, 0x75b3,
-+	0xa786, 0x0007, 0x0040, 0x75b3, 0x88ff, 0x00c0, 0x759b, 0x6018,
-+	0xa206, 0x00c0, 0x75b3, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0,
-+	0x75a3, 0x1078, 0x166e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040,
-+	0x75ad, 0x047e, 0x1078, 0x75fd, 0x047f, 0x0d7f, 0x1078, 0x6bb6,
-+	0x88ff, 0x00c0, 0x75c6, 0xace0, 0x0008, 0x2001, 0x7715, 0x2004,
-+	0xac02, 0x00c8, 0x75bd, 0x0078, 0x756f, 0xa006, 0x127f, 0x027f,
-+	0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001,
-+	0x0078, 0x75be, 0x087e, 0x2041, 0x0000, 0x2c20, 0x2019, 0x0002,
-+	0x6218, 0x1078, 0x5a2d, 0x1078, 0x5ace, 0x1078, 0x7562, 0x087f,
-+	0x007c, 0x027e, 0x047e, 0x087e, 0x0c7e, 0x157e, 0x2c20, 0x20a9,
-+	0x007f, 0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x384c, 0x00c0,
-+	0x75f2, 0x2c10, 0x2041, 0x0000, 0x1078, 0x5a2d, 0x1078, 0x5ace,
-+	0x1078, 0x7562, 0x037f, 0x017f, 0x8108, 0x00f0, 0x75e3, 0x157f,
-+	0x0c7f, 0x087f, 0x047f, 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff,
-+	0x0040, 0x7611, 0x6800, 0xa07d, 0x0040, 0x760e, 0x6803, 0x0000,
-+	0x6b52, 0x1078, 0x3b92, 0x2f68, 0x0078, 0x7602, 0x6b52, 0x1078,
-+	0x3b92, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
-+	0x7e00, 0x2071, 0x7700, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
-+	0x763c, 0x2100, 0xac06, 0x0040, 0x762e, 0x6000, 0xa086, 0x0000,
-+	0x0040, 0x762e, 0x6008, 0xa206, 0x0040, 0x7638, 0xace0, 0x0008,
-+	0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x763c, 0x0078, 0x7619,
-+	0xa085, 0x0001, 0x0078, 0x763d, 0xa006, 0x037f, 0x047f, 0x0e7f,
-+	0x007c, 0x0d7e, 0x007e, 0x1078, 0x1327, 0x007f, 0x1040, 0x12cd,
-+	0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000,
-+	0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, 0x1078, 0x3b92, 0x0d7f,
-+	0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0x766c, 0xa786, 0x0001,
-+	0x0040, 0x766c, 0xa786, 0x000a, 0x0040, 0x766c, 0xa786, 0x0009,
-+	0x0040, 0x766c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018, 0x2070,
-+	0x70a0, 0xa206, 0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
-+	0x8000, 0x2071, 0x7740, 0xd5a4, 0x0040, 0x7681, 0x7034, 0x8000,
-+	0x7036, 0xd5b4, 0x0040, 0x7687, 0x7030, 0x8000, 0x7032, 0xd5ac,
-+	0x0040, 0x768e, 0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f,
-+	0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
-+	0x7740, 0xd5a4, 0x0040, 0x769f, 0x7034, 0x8000, 0x7036, 0xd5b4,
-+	0x0040, 0x76a5, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0x76ac,
-+	0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c,
-+	0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x7742, 0x1078,
-+	0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072,
-+	0x00c8, 0x76c6, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e,
-+	0x2071, 0x7740, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
-+	0x7744, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0001, 0x0002, 0x0004,
-+	0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400,
-+	0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x687d
-+};
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_2200.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,5286 @@
-+/* @(#)asm_2200.h 1.5 */
-+/*
-+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 by Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+/************************************************************************
-+ *									*
-+ *               --- ISP2200 Initiator/Target Firmware ---              *
-+ *             with Fabric (Public Loop), Point-point, and              *
-+ *             expanded LUN addressing for FCTAPE                       *
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 2.02.03 (08:58 May 02, 2002)
-+ */
-+static const u_int16_t isp_2200_risc_code[] = {
-+	0x0470, 0x0000, 0x0000, 0xa3f2, 0x0000, 0x0002, 0x0002, 0x0003,
-+	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
-+	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
-+	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
-+	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-+	0x322e, 0x3032, 0x2e30, 0x3320, 0x2020, 0x2020, 0x2400, 0x20c1,
-+	0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb9ff, 0x2091,
-+	0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x2930,
-+	0x2051, 0xb400, 0x2a70, 0x2029, 0xec00, 0x2031, 0xffff, 0x2039,
-+	0xebe9, 0x2021, 0x0200, 0x0804, 0x1464, 0x20a1, 0xb3f2, 0xa00e,
-+	0x20a9, 0x080e, 0x41a4, 0x3400, 0x7562, 0x7666, 0x775e, 0x746a,
-+	0x746e, 0x20a1, 0xbc00, 0x7164, 0x810d, 0x810d, 0x810d, 0x810d,
-+	0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
-+	0x3400, 0x8211, 0x1dd8, 0x7164, 0x3400, 0xa102, 0x0120, 0x0218,
-+	0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xb400,
-+	0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
-+	0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
-+	0x2009, 0xb400, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
-+	0x41a4, 0x080c, 0x140d, 0x080c, 0x162e, 0x080c, 0x17c7, 0x080c,
-+	0x1f73, 0x080c, 0x4bb9, 0x080c, 0x8562, 0x080c, 0x15b7, 0x080c,
-+	0x2e88, 0x080c, 0x5d4b, 0x080c, 0x5302, 0x080c, 0x6893, 0x080c,
-+	0x24d9, 0x080c, 0x6b26, 0x080c, 0x637c, 0x080c, 0x239b, 0x080c,
-+	0x24a7, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
-+	0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
-+	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
-+	0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3ec6, 0x080c,
-+	0x2eaf, 0x080c, 0x5d99, 0x080c, 0x54b1, 0x080c, 0x68be, 0x0c80,
-+	0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1210, 0x10e2, 0x12d9, 0x140a,
-+	0x140b, 0x140c, 0x080c, 0x1511, 0x0005, 0x0126, 0x00f6, 0x2091,
-+	0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11ed, 0x080c, 0x1584,
-+	0x080c, 0x5a90, 0x0150, 0x080c, 0x5ab6, 0x15c0, 0x2079, 0x0100,
-+	0x7828, 0xa085, 0x1800, 0x782a, 0x0488, 0x080c, 0x59c8, 0x7000,
-+	0xa086, 0x0001, 0x1904, 0x11ed, 0x708c, 0xa086, 0x0028, 0x1904,
-+	0x11ed, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
-+	0xffff, 0x7a28, 0xa295, 0x1e2f, 0x7a2a, 0x2011, 0x5963, 0x080c,
-+	0x6961, 0x2011, 0x5956, 0x080c, 0x6a21, 0x2011, 0x59a5, 0x080c,
-+	0x6961, 0x2011, 0x4a96, 0x080c, 0x6961, 0x2011, 0x8030, 0x2019,
-+	0x0000, 0x708b, 0x0000, 0x080c, 0x1db8, 0x00e8, 0x080c, 0x4449,
-+	0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11ed, 0x2011, 0x4a96,
-+	0x080c, 0x6961, 0x2011, 0x59a5, 0x080c, 0x6961, 0x080c, 0x1db8,
-+	0x2001, 0xb68d, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
-+	0x2011, 0x8010, 0x73cc, 0x080c, 0x3e8a, 0x723c, 0xc284, 0x723e,
-+	0x2001, 0xb40c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x7edf, 0x2011,
-+	0x0004, 0x080c, 0x9bf1, 0x080c, 0x520e, 0x080c, 0x5a90, 0x0158,
-+	0x080c, 0x4ba2, 0x0140, 0x708b, 0x0001, 0x70c7, 0x0000, 0x080c,
-+	0x45e6, 0x0804, 0x11ed, 0x080c, 0x52ca, 0x0120, 0x7a0c, 0xc2b4,
-+	0x7a0e, 0x0060, 0x7073, 0x0000, 0x080c, 0x9f99, 0x70d4, 0xd09c,
-+	0x1128, 0x70a0, 0xa005, 0x0110, 0x080c, 0x4b80, 0x70df, 0x0000,
-+	0x70db, 0x0000, 0x72d4, 0x080c, 0x5a90, 0x1178, 0x2011, 0x0000,
-+	0x0016, 0x080c, 0x28b1, 0x2019, 0xb68f, 0x211a, 0x001e, 0x7053,
-+	0xffff, 0x7057, 0x00ef, 0x7077, 0x0000, 0x2079, 0xb452, 0x7804,
-+	0xd0ac, 0x0108, 0xc295, 0x72d6, 0x080c, 0x5a90, 0x0118, 0xa296,
-+	0x0004, 0x0548, 0x2011, 0x0001, 0x080c, 0x9bf1, 0x709b, 0x0000,
-+	0x709f, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003,
-+	0x7828, 0xa085, 0x0003, 0x782a, 0x00fe, 0x080c, 0x2a7e, 0x2011,
-+	0x0005, 0x080c, 0x801f, 0x080c, 0x7134, 0x080c, 0x5a90, 0x0148,
-+	0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x28b1, 0x61e2, 0x001e,
-+	0x00ce, 0x012e, 0x0420, 0x709b, 0x0000, 0x709f, 0xffff, 0x7003,
-+	0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0xa085,
-+	0x0003, 0x782a, 0x00fe, 0x2011, 0x0005, 0x080c, 0x801f, 0x080c,
-+	0x7134, 0x080c, 0x5a90, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016,
-+	0x080c, 0x28b1, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005,
-+	0x00c6, 0x080c, 0x5a90, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9,
-+	0x0082, 0x080c, 0x5a90, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009,
-+	0x007e, 0x080c, 0x2d5b, 0x8108, 0x1f04, 0x1201, 0x00ce, 0x7073,
-+	0x0000, 0x7074, 0xa084, 0x00ff, 0x7076, 0x70a3, 0x0000, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x7000, 0xa086, 0x0002, 0x1904, 0x12d7,
-+	0x709c, 0xa086, 0xffff, 0x0130, 0x080c, 0x2a7e, 0x080c, 0x7134,
-+	0x0804, 0x12d7, 0x70d4, 0xd0ac, 0x1110, 0xd09c, 0x0540, 0xd084,
-+	0x0530, 0x0006, 0x0016, 0x2001, 0x0103, 0x2009, 0xb68d, 0x210c,
-+	0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0, 0x70d8, 0xa086, 0xffff,
-+	0x0190, 0x080c, 0x2bdd, 0x080c, 0x7134, 0x70d4, 0xd094, 0x1904,
-+	0x12d7, 0x2011, 0x0001, 0x2019, 0x0000, 0x080c, 0x2c13, 0x080c,
-+	0x7134, 0x0804, 0x12d7, 0x70dc, 0xa005, 0x1904, 0x12d7, 0x7098,
-+	0xa005, 0x1904, 0x12d7, 0x70d4, 0xd0a4, 0x0118, 0xd0b4, 0x0904,
-+	0x12d7, 0x080c, 0x52ca, 0x1904, 0x12d7, 0x2001, 0xb453, 0x2004,
-+	0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000,
-+	0x0016, 0x080c, 0x4f6a, 0x1118, 0x6000, 0xd0ec, 0x1138, 0x001e,
-+	0x8108, 0x1f04, 0x1268, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce,
-+	0x015e, 0x0804, 0x12d7, 0x0006, 0x0016, 0x2001, 0x0103, 0x2009,
-+	0xb68d, 0x210c, 0x2102, 0x001e, 0x000e, 0xa006, 0x2009, 0x0700,
-+	0x20a9, 0x0002, 0x20a1, 0xb6ce, 0x40a1, 0x7070, 0x8007, 0x7174,
-+	0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009, 0x0000, 0x080c, 0x14f7,
-+	0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x40a1, 0xa006, 0x2009,
-+	0x0200, 0x20a9, 0x0002, 0x20a1, 0xb6de, 0x40a1, 0x7030, 0xc08c,
-+	0x7032, 0x7003, 0x0003, 0x709f, 0xffff, 0x080c, 0x157d, 0xa006,
-+	0x080c, 0x2789, 0x080c, 0x3efc, 0x00f6, 0x2079, 0x0100, 0x080c,
-+	0x5ab6, 0x0150, 0x080c, 0x5a90, 0x7828, 0x0118, 0xa084, 0xe1ff,
-+	0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0xb6e1, 0x2004,
-+	0xa086, 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x801f, 0x2011,
-+	0x0000, 0x080c, 0x8029, 0x080c, 0x7134, 0x080c, 0x71f1, 0x012e,
-+	0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079,
-+	0x0100, 0x2009, 0xb434, 0x2104, 0xa005, 0x1110, 0x080c, 0x28dd,
-+	0x2009, 0x00f7, 0x080c, 0x4b69, 0x7940, 0xa18c, 0x0010, 0x7942,
-+	0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827,
-+	0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, 0x1347,
-+	0x080c, 0x5aa2, 0x0158, 0x080c, 0x5ab6, 0x1128, 0x2001, 0xb69e,
-+	0x2003, 0x0000, 0x0070, 0x080c, 0x5a98, 0x0dc0, 0x2001, 0xb69e,
-+	0x2003, 0xaaaa, 0x2001, 0xb69f, 0x2003, 0x0001, 0x080c, 0x59c8,
-+	0x0058, 0x080c, 0x5a90, 0x0140, 0x2009, 0x00f8, 0x080c, 0x4b69,
-+	0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c,
-+	0x1138, 0x080c, 0x5a90, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x13f1,
-+	0x1f04, 0x1326, 0x0070, 0x7824, 0x080c, 0x5aac, 0x0118, 0xd0ac,
-+	0x1904, 0x13f1, 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804,
-+	0x13f1, 0x2001, 0x0001, 0x080c, 0x2789, 0x0804, 0x1400, 0x7850,
-+	0xa084, 0x0180, 0x7852, 0x782f, 0x0020, 0x20a9, 0x0046, 0x1d04,
-+	0x134f, 0x080c, 0x6a09, 0x1f04, 0x134f, 0x7850, 0xa084, 0x0180,
-+	0xa085, 0x0400, 0x7852, 0x782f, 0x0000, 0x080c, 0x5aa2, 0x0158,
-+	0x080c, 0x5ab6, 0x1128, 0x2001, 0xb69e, 0x2003, 0x0000, 0x0070,
-+	0x080c, 0x5a98, 0x0dc0, 0x2001, 0xb69e, 0x2003, 0xaaaa, 0x2001,
-+	0xb69f, 0x2003, 0x0001, 0x080c, 0x59c8, 0x0020, 0x2009, 0x00f8,
-+	0x080c, 0x4b69, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x137c, 0x7850,
-+	0xa084, 0x0180, 0xa085, 0x1400, 0x7852, 0x080c, 0x5a90, 0x0120,
-+	0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60,
-+	0x7820, 0xd09c, 0x1558, 0x080c, 0x5a90, 0x05d8, 0x7824, 0xd0ac,
-+	0x1904, 0x13f1, 0x080c, 0x5ab6, 0x1508, 0x0046, 0x2021, 0x0190,
-+	0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8, 0x7827, 0x0048, 0x20a9,
-+	0x01f4, 0x1d04, 0x13a9, 0x080c, 0x6a09, 0x1f04, 0x13a9, 0x7824,
-+	0xa084, 0x0068, 0x15c8, 0x2001, 0xb69e, 0x2003, 0xaaaa, 0x2001,
-+	0xb69f, 0x2003, 0x0001, 0x7003, 0x0001, 0x0498, 0x1d04, 0x13c2,
-+	0x080c, 0x6a09, 0x8319, 0x1960, 0x2009, 0xb434, 0x2104, 0x8000,
-+	0x200a, 0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x28dd,
-+	0x00d8, 0x080c, 0x5aa2, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c,
-+	0x5a67, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000,
-+	0x7824, 0x080c, 0x5aac, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800,
-+	0x09a8, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2789,
-+	0x0048, 0x2001, 0xb434, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828,
-+	0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852,
-+	0x015e, 0x003e, 0x000e, 0x080c, 0x1554, 0x012e, 0x00fe, 0x004e,
-+	0x001e, 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2061, 0xb6c1,
-+	0x2063, 0x0002, 0x6007, 0x0002, 0x600b, 0x0003, 0x600f, 0x0017,
-+	0x2001, 0xb69e, 0x2003, 0x0000, 0x708b, 0x0000, 0x2009, 0x0100,
-+	0x2104, 0xa082, 0x0002, 0x0218, 0x7053, 0xffff, 0x0010, 0x7053,
-+	0x0000, 0x705b, 0xffff, 0x7073, 0x0000, 0x7077, 0x0000, 0x080c,
-+	0x9f99, 0x2061, 0xb68e, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b,
-+	0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x601b,
-+	0x0000, 0x601f, 0x07d0, 0x2061, 0xb696, 0x6003, 0x8000, 0x6007,
-+	0x0000, 0x600b, 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017,
-+	0x0000, 0x601b, 0x0001, 0x601f, 0x0000, 0x2061, 0xb6b9, 0x6003,
-+	0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001,
-+	0xb428, 0x2003, 0x0000, 0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff,
-+	0x0570, 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039, 0xd401,
-+	0x2021, 0x0100, 0x2029, 0xd400, 0x00e8, 0xa186, 0x0002, 0x1118,
-+	0x2011, 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011, 0x0001,
-+	0x0088, 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058, 0xa186,
-+	0x000a, 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055, 0x1110,
-+	0x2011, 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804,
-+	0x104d, 0xa00e, 0x2011, 0x0003, 0x2019, 0x14a0, 0x0804, 0x14f1,
-+	0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000,
-+	0x2c04, 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000,
-+	0x2019, 0x14b3, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14,
-+	0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000,
-+	0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d, 0x0008,
-+	0xc185, 0x2011, 0x0002, 0x2019, 0x14ce, 0x0418, 0x2061, 0xffff,
-+	0x2019, 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0x2262,
-+	0xa306, 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061,
-+	0x7fff, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110, 0xc195,
-+	0x0008, 0xc19d, 0x2011, 0x0001, 0x2019, 0x14ef, 0x0010, 0x0804,
-+	0x1465, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011,
-+	0x0000, 0x080c, 0x4f6a, 0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6,
-+	0x0006, 0x0128, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186,
-+	0x0080, 0x0108, 0x8210, 0x8108, 0xa186, 0x0100, 0x1d50, 0x2208,
-+	0x0005, 0x2091, 0x8000, 0x0e04, 0x1513, 0x0006, 0x0016, 0x2079,
-+	0x0000, 0x7818, 0xd084, 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a,
-+	0x000e, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001,
-+	0x2091, 0x5000, 0x0126, 0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1,
-+	0xb80c, 0x2091, 0x2000, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200,
-+	0x40a1, 0x20a9, 0x0010, 0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010,
-+	0x2091, 0x2600, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1,
-+	0x014e, 0x015e, 0x012e, 0x2079, 0xb400, 0x7803, 0x0005, 0x2091,
-+	0x4080, 0x04c9, 0x0cf8, 0x0005, 0x0006, 0x080c, 0x159f, 0x1518,
-+	0x00f6, 0x2079, 0xb424, 0x2f04, 0x8000, 0x207a, 0xa082, 0x000f,
-+	0x0258, 0xa006, 0x207a, 0x2079, 0xb426, 0x2f04, 0xa084, 0x0001,
-+	0xa086, 0x0001, 0x207a, 0x0070, 0x2079, 0xb426, 0x2f7c, 0x8fff,
-+	0x1128, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0020, 0x2001, 0x0c03,
-+	0x2003, 0x00c0, 0x00fe, 0x000e, 0x0005, 0x0409, 0x1120, 0x2001,
-+	0x0c03, 0x2003, 0x0080, 0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03,
-+	0x2003, 0x0040, 0x0005, 0x0006, 0x0091, 0x1178, 0x2001, 0x0c03,
-+	0x2003, 0x0040, 0x2009, 0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003,
-+	0x0080, 0x2009, 0x0fff, 0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6,
-+	0x2061, 0x0c00, 0x2c04, 0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce,
-+	0x0005, 0x0156, 0x0126, 0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x15ae,
-+	0x2091, 0x6000, 0x1f04, 0x15ae, 0x012e, 0x015e, 0x0005, 0x2071,
-+	0xb400, 0x7160, 0x712e, 0x2021, 0x0001, 0xa190, 0x0030, 0xa298,
-+	0x0030, 0x0240, 0x7064, 0xa302, 0x1228, 0x220a, 0x2208, 0x2310,
-+	0x8420, 0x0ca8, 0x3800, 0xd08c, 0x0148, 0x7064, 0xa086, 0xb400,
-+	0x0128, 0x7067, 0xb400, 0x2011, 0x1000, 0x0c48, 0x200b, 0x0000,
-+	0x74b2, 0x74b6, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
-+	0xb400, 0x70b4, 0xa0ea, 0x0010, 0x0268, 0x8001, 0x70b6, 0x702c,
-+	0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e,
-+	0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x2071, 0xb400, 0x0126,
-+	0x2091, 0x8000, 0x70b4, 0x8001, 0x0260, 0x70b6, 0x702c, 0x2068,
-+	0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee,
-+	0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
-+	0xb400, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70b4, 0x8000, 0x70b6,
-+	0x012e, 0x00ee, 0x0005, 0x8dff, 0x0138, 0x6804, 0x6807, 0x0000,
-+	0x0006, 0x0c49, 0x00de, 0x0cb8, 0x0005, 0x00e6, 0x2071, 0xb400,
-+	0x70b4, 0xa08a, 0x0010, 0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071,
-+	0xb712, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071,
-+	0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6,
-+	0x2270, 0x700b, 0x0000, 0x2071, 0xb712, 0x7018, 0xa088, 0xb71b,
-+	0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x1128,
-+	0x00f6, 0x2079, 0x0010, 0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6,
-+	0x2071, 0xb712, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
-+	0x0019, 0x00fe, 0x00ee, 0x0005, 0x7000, 0x0002, 0x166a, 0x16ce,
-+	0x16eb, 0x16eb, 0x7018, 0x711c, 0xa106, 0x1118, 0x7007, 0x0000,
-+	0x0005, 0x00d6, 0xa180, 0xb71b, 0x2004, 0x700a, 0x2068, 0x8108,
-+	0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828,
-+	0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c,
-+	0x7016, 0x6804, 0x00de, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029,
-+	0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c,
-+	0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e,
-+	0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, 0x0041, 0x002e,
-+	0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014,
-+	0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, 0x2011, 0x0040,
-+	0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6,
-+	0x8203, 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803, 0x0001,
-+	0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x0136, 0x0146,
-+	0x0156, 0x2099, 0xb4fa, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3,
-+	0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0041, 0x7007,
-+	0x0003, 0x7000, 0xc084, 0x7002, 0x700b, 0xb4f5, 0x012e, 0x015e,
-+	0x014e, 0x013e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2001, 0xb529,
-+	0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0xb52a, 0x20ac,
-+	0x53a6, 0x2099, 0xb52b, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3,
-+	0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0001, 0x7007,
-+	0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, 0xb526, 0x012e, 0x015e,
-+	0x014e, 0x013e, 0x0005, 0x0016, 0x00e6, 0x2071, 0xb712, 0x00f6,
-+	0x2079, 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c,
-+	0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1664,
-+	0x172e, 0x175c, 0x1786, 0x17b6, 0x172d, 0x0cf8, 0xa18c, 0x0700,
-+	0x1528, 0x0136, 0x0146, 0x0156, 0x7014, 0x20a0, 0x2099, 0x0014,
-+	0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e,
-+	0x014e, 0x013e, 0x700c, 0xa005, 0x0570, 0x7830, 0x7832, 0x7834,
-+	0x7836, 0x080c, 0x1695, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003,
-+	0x0100, 0x7007, 0x0000, 0x080c, 0x1664, 0x0005, 0x7008, 0xa080,
-+	0x0002, 0x2003, 0x0200, 0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c,
-+	0xa005, 0x0188, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x16aa,
-+	0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x7007, 0x0000,
-+	0x080c, 0x1664, 0x0005, 0x00d6, 0x7008, 0x2068, 0x7830, 0x6826,
-+	0x7834, 0x682a, 0x7838, 0x682e, 0x783c, 0x6832, 0x680b, 0x0100,
-+	0x00de, 0x7007, 0x0000, 0x080c, 0x1664, 0x0005, 0xa18c, 0x0700,
-+	0x1540, 0x0136, 0x0146, 0x0156, 0x2001, 0xb4f8, 0x2004, 0xa080,
-+	0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020,
-+	0x53a5, 0x2001, 0xb4fa, 0x2004, 0xd0bc, 0x0148, 0x2001, 0xb503,
-+	0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e,
-+	0x014e, 0x013e, 0x7007, 0x0000, 0x080c, 0x5e30, 0x080c, 0x1664,
-+	0x0005, 0x2011, 0x8003, 0x080c, 0x3e8a, 0x0cf8, 0xa18c, 0x0700,
-+	0x1148, 0x2001, 0xb528, 0x2003, 0x0100, 0x7007, 0x0000, 0x080c,
-+	0x1664, 0x0005, 0x2011, 0x8004, 0x080c, 0x3e8a, 0x0cf8, 0x0126,
-+	0x2091, 0x2200, 0x2079, 0x0030, 0x2071, 0xb723, 0x7003, 0x0000,
-+	0x700f, 0xb72f, 0x7013, 0xb72f, 0x780f, 0x00f6, 0x7803, 0x0004,
-+	0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002, 0x17e6, 0x1824,
-+	0x17e6, 0x17e6, 0x17e6, 0x180c, 0x17f3, 0x17ea, 0xa085, 0x0001,
-+	0x0804, 0x183e, 0x684c, 0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c,
-+	0x682a, 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70,
-+	0x684c, 0xd0bc, 0x0d58, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804,
-+	0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x22b6,
-+	0x2005, 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015,
-+	0x19a8, 0x684c, 0xd0ac, 0x0990, 0x6804, 0x681a, 0xa080, 0x000d,
-+	0x2004, 0xa084, 0x000f, 0xa080, 0x22b6, 0x2005, 0x6832, 0xa006,
-+	0x682e, 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac, 0x0904, 0x17e6,
-+	0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x22b6,
-+	0x210d, 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e,
-+	0xa006, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x684c,
-+	0xd0ac, 0x090c, 0x1511, 0x6833, 0x22b3, 0x2d08, 0x691a, 0x6858,
-+	0x8001, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x682e,
-+	0x682a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007,
-+	0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x82ff, 0x01e8, 0xa280,
-+	0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc, 0x1190, 0xa280, 0x0007,
-+	0x2004, 0xa086, 0x000a, 0x1110, 0x0891, 0x0010, 0x080c, 0x17da,
-+	0x0138, 0x00de, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020,
-+	0x6808, 0x8000, 0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026,
-+	0x2091, 0x2200, 0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0,
-+	0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
-+	0xb74a, 0x0210, 0x2009, 0xb72f, 0x710e, 0x7010, 0xa102, 0xa082,
-+	0x0009, 0x0118, 0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a,
-+	0x012e, 0x0005, 0x7206, 0x2001, 0x18a0, 0x0006, 0x2260, 0x0804,
-+	0x19cc, 0x0126, 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200,
-+	0x000e, 0x004e, 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110,
-+	0x2168, 0x6a62, 0x6b5e, 0xa005, 0x0904, 0x1901, 0x6808, 0xa005,
-+	0x0904, 0x1938, 0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110,
-+	0xa106, 0x1904, 0x1940, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005,
-+	0x2004, 0xd08c, 0x0168, 0x0046, 0x080c, 0x1ad5, 0x004e, 0x2460,
-+	0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0904, 0x1938, 0x0c10,
-+	0x2001, 0x0207, 0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000,
-+	0x0120, 0xa086, 0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c,
-+	0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100,
-+	0xa18e, 0x0004, 0x1904, 0x1940, 0x2009, 0x0048, 0x080c, 0x85ef,
-+	0x04f8, 0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c,
-+	0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005,
-+	0x2004, 0xd08c, 0x0160, 0x0046, 0x080c, 0x1ad5, 0x004e, 0x2460,
-+	0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001,
-+	0x0207, 0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c,
-+	0x1d50, 0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0,
-+	0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000,
-+	0x6100, 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x85ef,
-+	0x00ce, 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036,
-+	0x0046, 0x0056, 0x2071, 0xb723, 0x7000, 0xa086, 0x0000, 0x0904,
-+	0x19aa, 0x7004, 0xac06, 0x1904, 0x199c, 0x2079, 0x0030, 0x7000,
-+	0xa086, 0x0003, 0x0904, 0x199c, 0x7804, 0xd0fc, 0x15c8, 0x20e1,
-+	0x6000, 0x2011, 0x0032, 0x2001, 0x0208, 0x200c, 0x2001, 0x0209,
-+	0x2004, 0xa106, 0x1d88, 0x8211, 0x1db0, 0x7804, 0xd0fc, 0x1540,
-+	0x080c, 0x1e3f, 0x0026, 0x0056, 0x7803, 0x0004, 0x7804, 0xd0ac,
-+	0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
-+	0x0000, 0x005e, 0x002e, 0x2001, 0x015d, 0x2003, 0x0000, 0x080c,
-+	0x5a90, 0x1138, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b12, 0x006e,
-+	0x0058, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0020,
-+	0x080c, 0x1ad5, 0x0804, 0x194c, 0x0156, 0x20a9, 0x0009, 0x2009,
-+	0xb72f, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003, 0x1f04,
-+	0x19a1, 0x015e, 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe,
-+	0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1a40, 0x2104, 0x7006,
-+	0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb74a,
-+	0x0210, 0x2009, 0xb72f, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c,
-+	0x28b1, 0x2001, 0x0138, 0x2102, 0x8cff, 0x0598, 0x6010, 0x2068,
-+	0x2d58, 0x6828, 0xa406, 0x1590, 0x682c, 0xa306, 0x1578, 0x7004,
-+	0x2060, 0x6020, 0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817,
-+	0xffff, 0x6813, 0xffff, 0x00e8, 0x6850, 0xd0f4, 0x1130, 0x7803,
-+	0x0004, 0x6810, 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818,
-+	0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011,
-+	0x080c, 0x1a43, 0x0120, 0x2009, 0x0001, 0x080c, 0x1a43, 0x2d58,
-+	0x0005, 0x080c, 0x1dac, 0x0904, 0x19b1, 0x0cd0, 0x6020, 0xd0f4,
-+	0x11e0, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034, 0xa303, 0x0108,
-+	0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046, 0x0036, 0x2400,
-+	0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303, 0x6816, 0x003e,
-+	0x004e, 0x0018, 0x080c, 0x9f2b, 0x09e0, 0x601c, 0xa08e, 0x0008,
-+	0x0904, 0x19d7, 0xa08e, 0x000a, 0x0904, 0x19d7, 0x2001, 0xb474,
-+	0x2004, 0xd0b4, 0x1140, 0x6018, 0x2004, 0xd0bc, 0x1120, 0x6817,
-+	0x7fff, 0x6813, 0xffff, 0x080c, 0x22d6, 0x1918, 0x0804, 0x19d7,
-+	0x7003, 0x0000, 0x0005, 0x8aff, 0x0904, 0x1aaf, 0xa03e, 0x2730,
-+	0x6850, 0xd0fc, 0x11b8, 0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68,
-+	0x2900, 0x0002, 0x1a93, 0x1a78, 0x1a78, 0x1a93, 0x1a93, 0x1a8c,
-+	0x1a93, 0x1a78, 0x1a93, 0x1a7d, 0x1a7d, 0x1a93, 0x1a93, 0x1a93,
-+	0x1a84, 0x1a7d, 0x7803, 0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70,
-+	0x6d1c, 0x6c20, 0x00d6, 0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08,
-+	0x6e0c, 0x0420, 0xc0f4, 0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0458,
-+	0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00,
-+	0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084,
-+	0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x2278, 0x1904,
-+	0x1a43, 0xa00e, 0x00e0, 0x00de, 0x080c, 0x1511, 0x7b22, 0x7a26,
-+	0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7316, 0x721a, 0x751e, 0x7422,
-+	0x7726, 0x762a, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828,
-+	0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2278, 0x0005,
-+	0x080c, 0x1511, 0x080c, 0x1f26, 0x7004, 0x2060, 0x00d6, 0x6010,
-+	0x2068, 0x7003, 0x0000, 0x080c, 0x1dcd, 0x080c, 0x9beb, 0x0170,
-+	0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b,
-+	0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c,
-+	0x98c3, 0x0804, 0x1cfa, 0x080c, 0x1511, 0x0126, 0x2091, 0x2200,
-+	0x0006, 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
-+	0xa184, 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58,
-+	0x7000, 0x0002, 0x1af2, 0x1af8, 0x1c09, 0x1cd5, 0x1ce9, 0x1af2,
-+	0x1af2, 0x1af2, 0x7804, 0xd09c, 0x1904, 0x1cfa, 0x080c, 0x1511,
-+	0x8001, 0x7002, 0xd1bc, 0x11a0, 0xd19c, 0x1904, 0x1b8d, 0xd1dc,
-+	0x1178, 0x8aff, 0x0904, 0x1b8d, 0x2009, 0x0001, 0x080c, 0x1a43,
-+	0x0904, 0x1cfa, 0x2009, 0x0001, 0x080c, 0x1a43, 0x0804, 0x1cfa,
-+	0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b6d, 0x0026,
-+	0x0036, 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c,
-+	0x6816, 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec,
-+	0x1128, 0x7803, 0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1cfe,
-+	0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213,
-+	0x6b2a, 0x6a2e, 0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110,
-+	0x633a, 0x6236, 0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x2500,
-+	0xa405, 0x0128, 0x080c, 0x228e, 0x6850, 0xc0fd, 0x6852, 0x2a00,
-+	0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, 0x680a,
-+	0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, 0x2060, 0x2009, 0x0048,
-+	0x080c, 0x85ef, 0x7000, 0xa086, 0x0004, 0x0904, 0x1cfa, 0x7003,
-+	0x0000, 0x080c, 0x19b1, 0x0804, 0x1cfa, 0x0056, 0x7d0c, 0xd5bc,
-+	0x1110, 0x080c, 0xb38a, 0x005e, 0x080c, 0x1dcd, 0x00f6, 0x7004,
-+	0x2078, 0x080c, 0x52c6, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
-+	0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
-+	0x791a, 0x6980, 0x791e, 0x0804, 0x1cfa, 0x7004, 0x00c6, 0x2060,
-+	0x6020, 0x00ce, 0xd0f4, 0x0120, 0x6808, 0x8001, 0x680a, 0x04c0,
-+	0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c, 0x0160, 0xa205, 0x0150,
-+	0x7004, 0xa080, 0x0007, 0x2004, 0xa084, 0xfffd, 0xa086, 0x0008,
-+	0x1904, 0x1b10, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x1520,
-+	0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x01a0, 0x7004, 0x2060,
-+	0x601c, 0xa086, 0x000a, 0x11a0, 0x0156, 0x20a9, 0x0009, 0x2009,
-+	0xb72f, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003, 0x1f04,
-+	0x1bc1, 0x015e, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x85ef,
-+	0x080c, 0x19b1, 0x0804, 0x1cfa, 0x7818, 0x6812, 0x781c, 0x6816,
-+	0x7814, 0x7908, 0xa18c, 0x0fff, 0xa192, 0x0841, 0x1a04, 0x1ab2,
-+	0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104, 0x8004,
-+	0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c, 0x1e6a, 0x7803,
-+	0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc, 0x0de8,
-+	0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f6, 0x7004, 0x7007,
-+	0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x85ef, 0x080c, 0x1ec0,
-+	0x0838, 0x8001, 0x7002, 0xd194, 0x01b0, 0x7804, 0xd0fc, 0x1904,
-+	0x1ca5, 0xd09c, 0x0138, 0x7804, 0xd0fc, 0x1904, 0x1ca5, 0xd09c,
-+	0x1904, 0x1ca9, 0x8aff, 0x0904, 0x1cfa, 0x2009, 0x0001, 0x080c,
-+	0x1a43, 0x0804, 0x1cfa, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
-+	0x1cfa, 0x2009, 0x0001, 0x080c, 0x1a43, 0x0804, 0x1cfa, 0x7818,
-+	0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1baa, 0x7803, 0x0004,
-+	0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c87, 0x6834, 0xa084, 0x00ff,
-+	0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1baa, 0x0026, 0x0036,
-+	0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816,
-+	0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128,
-+	0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1cfe,
-+	0x001e, 0x6b28, 0x6a2c, 0x080c, 0x228e, 0x00d6, 0x2805, 0xac68,
-+	0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
-+	0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1b32,
-+	0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
-+	0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1bd0, 0x0056,
-+	0x7d0c, 0x080c, 0xb38a, 0x005e, 0x080c, 0x1dcd, 0x00f6, 0x7004,
-+	0x2078, 0x080c, 0x52c6, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
-+	0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
-+	0x791a, 0x6980, 0x791e, 0x0804, 0x1cfa, 0x7804, 0xd09c, 0x0904,
-+	0x1add, 0x7c20, 0x7824, 0xa405, 0x1904, 0x1add, 0x7818, 0x6812,
-+	0x7c1c, 0x6c16, 0xa405, 0x1120, 0x7803, 0x0002, 0x0804, 0x1baa,
-+	0x751c, 0x7420, 0x7724, 0x7628, 0x7014, 0xa528, 0x7018, 0xa421,
-+	0xa7b9, 0x0000, 0xa6b1, 0x0000, 0x7830, 0xa506, 0x1150, 0x7834,
-+	0xa406, 0x1138, 0x7838, 0xa706, 0x1120, 0x783c, 0xa606, 0x0904,
-+	0x1add, 0x7803, 0x0002, 0x0804, 0x1c36, 0x7803, 0x0004, 0x7003,
-+	0x0000, 0x7004, 0xa00d, 0x0150, 0x6808, 0x8001, 0x680a, 0x1130,
-+	0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x85ef, 0x080c, 0x19b1,
-+	0x0088, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6010,
-+	0xa005, 0x0da0, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c,
-+	0x080c, 0x19cc, 0x001e, 0x000e, 0x012e, 0x0005, 0x700c, 0x7110,
-+	0xa106, 0x0904, 0x1da0, 0x7004, 0x0016, 0x210c, 0xa106, 0x001e,
-+	0x0904, 0x1da0, 0x00d6, 0x00c6, 0x216c, 0x2d00, 0xa005, 0x0904,
-+	0x1d9e, 0x681c, 0xa086, 0x0008, 0x0904, 0x1d9e, 0x6820, 0xd0d4,
-+	0x1904, 0x1d9e, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x05a8, 0x8108,
-+	0x2104, 0x6b2c, 0xa306, 0x1904, 0x1d9e, 0x8108, 0x2104, 0x6a28,
-+	0xa206, 0x1904, 0x1d9e, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c,
-+	0x7822, 0x7016, 0x6870, 0x7826, 0x701a, 0x681c, 0x7832, 0x701e,
-+	0x6820, 0x7836, 0x7022, 0x6818, 0x2060, 0x6034, 0xd09c, 0x0168,
-+	0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a, 0x7026, 0x680c,
-+	0x783e, 0x702a, 0x00de, 0x0804, 0x1d98, 0xa006, 0x783a, 0x783e,
-+	0x7026, 0x702a, 0x0804, 0x1d98, 0x8108, 0x2104, 0xa005, 0x1904,
-+	0x1d9e, 0x6b2c, 0xa306, 0x1904, 0x1d9e, 0x8108, 0x2104, 0xa005,
-+	0x15e8, 0x6a28, 0xa206, 0x15d0, 0x6850, 0xc0f5, 0x6852, 0x6830,
-+	0x2005, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004, 0xd09c, 0x11a0,
-+	0x6008, 0x7822, 0x7016, 0x686e, 0x600c, 0x7826, 0x701a, 0x6872,
-+	0x6000, 0x7832, 0x701e, 0x6004, 0x7836, 0x7022, 0xa006, 0x783a,
-+	0x783e, 0x7026, 0x702a, 0x00a0, 0x6010, 0x7822, 0x7016, 0x686e,
-+	0x6014, 0x7826, 0x701a, 0x6872, 0x6000, 0x7832, 0x701e, 0x6004,
-+	0x7836, 0x7022, 0x6008, 0x783a, 0x7026, 0x600c, 0x783e, 0x702a,
-+	0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce, 0x00de,
-+	0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x1118,
-+	0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x0118, 0x780c, 0xd0a4,
-+	0x0120, 0x00d9, 0xa085, 0x0001, 0x0010, 0x080c, 0x1ec0, 0x0005,
-+	0x0126, 0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1160, 0x700c,
-+	0x7110, 0xa106, 0x0140, 0x080c, 0x2922, 0x20e1, 0x9028, 0x700f,
-+	0xb72f, 0x7013, 0xb72f, 0x012e, 0x0005, 0x00c6, 0x080c, 0x5a90,
-+	0x11b8, 0x2001, 0x0160, 0x2003, 0x0000, 0x2001, 0x0138, 0x2003,
-+	0x0000, 0x2011, 0x00c8, 0xe000, 0xe000, 0x8211, 0x1de0, 0x04c1,
-+	0x0066, 0x2031, 0x0000, 0x080c, 0x5b12, 0x006e, 0x00ce, 0x0005,
-+	0x080c, 0x1e3f, 0x080c, 0x2922, 0x20e1, 0x9028, 0x700c, 0x7110,
-+	0xa106, 0x01d0, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
-+	0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb74a, 0x0210,
-+	0x2009, 0xb72f, 0x7112, 0x700c, 0xa106, 0x1d40, 0x080c, 0x28b1,
-+	0x2001, 0x0138, 0x2102, 0x0c10, 0x2001, 0x015d, 0x2003, 0x0000,
-+	0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005,
-+	0x080c, 0x2922, 0x20e1, 0x9028, 0x2001, 0x015d, 0x2003, 0x0000,
-+	0x00e6, 0x00c6, 0x0016, 0x2071, 0xb723, 0x700c, 0x7110, 0xa106,
-+	0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008,
-+	0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb74a, 0x0210, 0x2009,
-+	0xb72f, 0x7112, 0x0c50, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x2001,
-+	0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003,
-+	0x0000, 0x080c, 0x5a90, 0x1148, 0x2021, 0x0002, 0x1d04, 0x1e4e,
-+	0x2091, 0x6000, 0x8421, 0x1dd0, 0x0005, 0x2021, 0xb015, 0x2001,
-+	0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0xa39c,
-+	0x0048, 0x1138, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421,
-+	0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200, 0x7808, 0xa084, 0xf000,
-+	0xa10d, 0x0869, 0x2001, 0x0105, 0x2004, 0xa084, 0x0003, 0x1130,
-+	0x2001, 0xb74a, 0x2004, 0xa086, 0x0000, 0x0548, 0xa026, 0x2019,
-+	0xf000, 0x8319, 0x1148, 0x2001, 0x012b, 0x2003, 0x95f5, 0x2001,
-+	0x0129, 0x2003, 0x95f5, 0x00d8, 0x2001, 0x0105, 0x2004, 0xa084,
-+	0x0003, 0x1130, 0x2001, 0xb74a, 0x2004, 0xa086, 0x0000, 0x0178,
-+	0x2001, 0x0132, 0x2004, 0xa436, 0x0110, 0x2020, 0x0c00, 0x2001,
-+	0x0021, 0x2004, 0xd0fc, 0x09e8, 0x080c, 0x211b, 0x08c0, 0x20e1,
-+	0x7000, 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001,
-+	0x810f, 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422,
-+	0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005,
-+	0x0026, 0x2001, 0x015d, 0x2003, 0x0000, 0x7908, 0xa18c, 0x0fff,
-+	0xa182, 0x0ffd, 0x0210, 0x2009, 0x0000, 0xa190, 0x0007, 0xa294,
-+	0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001, 0x020a, 0x82ff, 0x0140,
-+	0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x8211, 0x1dd0,
-+	0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0x20e1, 0x6000,
-+	0x2001, 0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, 0x0158,
-+	0x080c, 0x1da1, 0x0130, 0x7908, 0xd1ec, 0x1128, 0x790c, 0xd1a4,
-+	0x0960, 0x080c, 0x1dcd, 0xa006, 0x002e, 0x0005, 0x00f6, 0x00e6,
-+	0x0016, 0x0026, 0x2071, 0xb723, 0x2079, 0x0030, 0x2011, 0x0050,
-+	0x7000, 0xa086, 0x0000, 0x01a8, 0x8211, 0x0188, 0x2001, 0x0005,
-+	0x2004, 0xd08c, 0x0dc8, 0x7904, 0xa18c, 0x0780, 0x0016, 0x080c,
-+	0x1ad5, 0x001e, 0x81ff, 0x1118, 0x2011, 0x0050, 0x0c48, 0xa085,
-+	0x0001, 0x002e, 0x001e, 0x00ee, 0x00fe, 0x0005, 0x7803, 0x0004,
-+	0x2009, 0x0064, 0x7804, 0xd0ac, 0x0904, 0x1f72, 0x8109, 0x1dd0,
-+	0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, 0x0a0c, 0x1511, 0x080c,
-+	0x2222, 0x00e6, 0x00f6, 0x2071, 0xb712, 0x2079, 0x0010, 0x7004,
-+	0xa086, 0x0000, 0x0538, 0x7800, 0x0006, 0x7820, 0x0006, 0x7830,
-+	0x0006, 0x7834, 0x0006, 0x7838, 0x0006, 0x783c, 0x0006, 0x7803,
-+	0x0004, 0xe000, 0xe000, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x190c,
-+	0x1511, 0x2079, 0x0010, 0x000e, 0x783e, 0x000e, 0x783a, 0x000e,
-+	0x7836, 0x000e, 0x7832, 0x000e, 0x7822, 0x000e, 0x7802, 0x00fe,
-+	0x00ee, 0x0030, 0x00fe, 0x00ee, 0x7804, 0xd0ac, 0x190c, 0x1511,
-+	0x080c, 0x71f1, 0x0005, 0x00e6, 0x2071, 0xb74a, 0x7003, 0x0000,
-+	0x00ee, 0x0005, 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc,
-+	0x1904, 0x1ff0, 0x6934, 0xa184, 0x0007, 0x0002, 0x1f8e, 0x1fdb,
-+	0x1f8e, 0x1f8e, 0x1f8e, 0x1fc2, 0x1fa1, 0x1f90, 0x080c, 0x1511,
-+	0x684c, 0xd0b4, 0x0904, 0x20d8, 0x6860, 0x682e, 0x6816, 0x685c,
-+	0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0804,
-+	0x1fe3, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1d38, 0x684c,
-+	0xd0b4, 0x0904, 0x20d8, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a,
-+	0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080,
-+	0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x22b6, 0x2005, 0x6832,
-+	0x6958, 0x0450, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c,
-+	0xd0b4, 0x0904, 0x20d8, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004,
-+	0xa084, 0x000f, 0xa080, 0x22b6, 0x2005, 0x6832, 0x6958, 0xa006,
-+	0x682e, 0x682a, 0x0088, 0x684c, 0xd0b4, 0x0904, 0x1ab0, 0x6958,
-+	0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f,
-+	0xa080, 0x22b6, 0x2005, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e,
-+	0x00de, 0x0005, 0x00f6, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c,
-+	0x211b, 0x00e6, 0x00d6, 0x2071, 0xb74a, 0x7000, 0xa005, 0x1904,
-+	0x2058, 0x00c6, 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068,
-+	0x7803, 0x0004, 0x6818, 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890,
-+	0x00f6, 0x20e1, 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100,
-+	0x8004, 0x78d6, 0x00fe, 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818,
-+	0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x791a,
-+	0x7116, 0x680c, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004,
-+	0x692c, 0x6814, 0xa106, 0x1120, 0x6928, 0x6810, 0xa106, 0x0158,
-+	0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x22d6, 0x004e, 0x003e,
-+	0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, 0xa085, 0x0001,
-+	0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001,
-+	0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e, 0x00ce, 0xa006,
-+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, 0x0056, 0x0046,
-+	0x0036, 0x0026, 0x8aff, 0x0904, 0x20d1, 0x700c, 0x7214, 0xa23a,
-+	0x7010, 0x7218, 0xa203, 0x0a04, 0x20d0, 0xa705, 0x0904, 0x20d0,
-+	0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, 0x2805, 0xac68,
-+	0x2900, 0x0002, 0x20b3, 0x2098, 0x2098, 0x20b3, 0x20b3, 0x20ac,
-+	0x20b3, 0x2098, 0x20b3, 0x209d, 0x209d, 0x20b3, 0x20b3, 0x20b3,
-+	0x20a4, 0x209d, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20,
-+	0xd99c, 0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x00f0,
-+	0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00,
-+	0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084,
-+	0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x2278, 0x1904,
-+	0x2062, 0xa00e, 0x00f0, 0x00de, 0x080c, 0x1511, 0x00de, 0x7b22,
-+	0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000,
-+	0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c,
-+	0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x080c, 0x2278, 0x0008,
-+	0xa006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005,
-+	0x080c, 0x1511, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1,
-+	0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x00d6,
-+	0x6010, 0x2068, 0x080c, 0x9beb, 0x0118, 0x6850, 0xc0bd, 0x6852,
-+	0x601c, 0xa086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001,
-+	0x00fa, 0x8001, 0x1df0, 0x60c8, 0xa206, 0x1dc0, 0x60c4, 0x686a,
-+	0x60c8, 0x6866, 0x7004, 0x2060, 0x00de, 0x00c6, 0x080c, 0x98c3,
-+	0x00ce, 0x2001, 0xb6ef, 0x2004, 0xac06, 0x1150, 0x20e1, 0x9040,
-+	0x080c, 0x8200, 0x2011, 0x0000, 0x080c, 0x8029, 0x080c, 0x71f1,
-+	0x002e, 0x0804, 0x21d5, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016,
-+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071, 0xb74a,
-+	0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700,
-+	0x1904, 0x20da, 0x7000, 0x0002, 0x21d5, 0x2138, 0x21a8, 0x21d3,
-+	0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001,
-+	0x080c, 0x205c, 0x0904, 0x21d5, 0x2009, 0x0001, 0x080c, 0x205c,
-+	0x0804, 0x21d5, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc,
-+	0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026,
-+	0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
-+	0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e,
-+	0x002e, 0x080c, 0x228e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
-+	0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x21d5,
-+	0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100,
-+	0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019,
-+	0x1000, 0x8319, 0x090c, 0x1511, 0x7820, 0xd0bc, 0x1dd0, 0x003e,
-+	0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
-+	0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
-+	0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
-+	0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x212b,
-+	0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x205c,
-+	0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x228e, 0x00d6,
-+	0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
-+	0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
-+	0x215b, 0x0804, 0x2157, 0x080c, 0x1511, 0x00ce, 0x00de, 0x00ee,
-+	0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
-+	0xb74a, 0x7000, 0xa086, 0x0000, 0x05d0, 0x2079, 0x0020, 0x0016,
-+	0x2009, 0x0207, 0x210c, 0xd194, 0x0198, 0x2009, 0x020c, 0x210c,
-+	0xa184, 0x0003, 0x0168, 0x080c, 0xb3d3, 0x2001, 0x0133, 0x2004,
-+	0xa005, 0x090c, 0x1511, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102,
-+	0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110,
-+	0x20e1, 0x9040, 0x7804, 0xd0fc, 0x09d8, 0x080c, 0x211b, 0x7000,
-+	0xa086, 0x0000, 0x19a8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac,
-+	0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee,
-+	0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071,
-+	0xb74a, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004,
-+	0x2060, 0x6010, 0x2068, 0x080c, 0x9beb, 0x0158, 0x6850, 0xc0b5,
-+	0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206,
-+	0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
-+	0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x98c3, 0x20e1,
-+	0x9040, 0x080c, 0x8200, 0x2011, 0x0000, 0x080c, 0x8029, 0x00fe,
-+	0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205,
-+	0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1f7a, 0x2001,
-+	0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
-+	0x0000, 0x2069, 0xb6e0, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8,
-+	0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
-+	0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x22b6, 0x2045, 0x88ff,
-+	0x090c, 0x1511, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
-+	0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
-+	0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
-+	0x22c6, 0x2045, 0x88ff, 0x090c, 0x1511, 0x0005, 0x0000, 0x0011,
-+	0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
-+	0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x22ab,
-+	0x22a7, 0x0000, 0x0000, 0x22b5, 0x0000, 0x22ab, 0x0000, 0x22b2,
-+	0x22af, 0x0000, 0x0000, 0x0000, 0x22b5, 0x22b2, 0x0000, 0x22ad,
-+	0x22ad, 0x0000, 0x0000, 0x22b5, 0x0000, 0x22ad, 0x0000, 0x22b3,
-+	0x22b3, 0x0000, 0x0000, 0x0000, 0x22b5, 0x22b3, 0x00a6, 0x0096,
-+	0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2367, 0x2d60,
-+	0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x22b6, 0xa986, 0x0007, 0x0130,
-+	0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422,
-+	0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2367,
-+	0x6004, 0xa065, 0x0904, 0x2367, 0x0c18, 0x2805, 0xa005, 0x01a8,
-+	0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020,
-+	0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150,
-+	0x8a51, 0x0904, 0x2367, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904,
-+	0x2367, 0x0830, 0x8a51, 0x0904, 0x2367, 0x8840, 0x2805, 0xa005,
-+	0x1158, 0x6004, 0xa065, 0x0904, 0x2367, 0x6034, 0xa0cc, 0x000f,
-+	0xa9c0, 0x22b6, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852,
-+	0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68,
-+	0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122,
-+	0x690c, 0x2300, 0xa11b, 0x0a0c, 0x1511, 0x6800, 0xa420, 0x6804,
-+	0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
-+	0x0a0c, 0x1511, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
-+	0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
-+	0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e,
-+	0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
-+	0xa084, 0x0007, 0x0002, 0x237b, 0x237c, 0x237f, 0x2382, 0x2387,
-+	0x238a, 0x238f, 0x2394, 0x0005, 0x080c, 0x211b, 0x0005, 0x080c,
-+	0x1ad5, 0x0005, 0x080c, 0x1ad5, 0x080c, 0x211b, 0x0005, 0x080c,
-+	0x1713, 0x0005, 0x080c, 0x211b, 0x080c, 0x1713, 0x0005, 0x080c,
-+	0x1ad5, 0x080c, 0x1713, 0x0005, 0x080c, 0x1ad5, 0x080c, 0x211b,
-+	0x080c, 0x1713, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
-+	0x2071, 0xba80, 0x2069, 0xb400, 0x080c, 0x2489, 0x080c, 0x2479,
-+	0x2009, 0x0004, 0x7912, 0x7817, 0x0004, 0x080c, 0x27be, 0x781b,
-+	0x0002, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a9, 0x0080, 0x782f,
-+	0x0000, 0x1f04, 0x23b7, 0x20e1, 0x9080, 0x783b, 0x001f, 0x20e1,
-+	0x8700, 0x012e, 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4,
-+	0x190c, 0x2476, 0xa084, 0x0007, 0x0002, 0x23e7, 0x23d5, 0x23d8,
-+	0x23db, 0x23e0, 0x23e2, 0x23e4, 0x23e6, 0x080c, 0x6385, 0x0078,
-+	0x080c, 0x63c4, 0x0060, 0x080c, 0x6385, 0x080c, 0x63c4, 0x0038,
-+	0x0041, 0x0028, 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e,
-+	0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xb3d3, 0x7930, 0xa184,
-+	0x0003, 0x0170, 0x2001, 0xb6ef, 0x2004, 0xa005, 0x0130, 0x2001,
-+	0x0133, 0x2004, 0xa005, 0x090c, 0x1511, 0x20e1, 0x9040, 0x04a0,
-+	0xa184, 0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0,
-+	0x080c, 0x5a90, 0x1178, 0x2001, 0xb69f, 0x2003, 0x0001, 0x2001,
-+	0xb400, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5ad4, 0x080c,
-+	0x59c8, 0x0010, 0x080c, 0x4ad9, 0x080c, 0x2479, 0x00a8, 0xa184,
-+	0x00c0, 0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xb723,
-+	0x080c, 0x1dcd, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184,
-+	0x0300, 0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e,
-+	0x0005, 0x0016, 0x00e6, 0x00f6, 0x2071, 0xb400, 0x7128, 0x2001,
-+	0xb691, 0x2102, 0x2001, 0xb699, 0x2102, 0xa182, 0x0211, 0x1218,
-+	0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007,
-+	0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182,
-+	0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218,
-+	0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003,
-+	0x0010, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004,
-+	0x080c, 0x27be, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c,
-+	0x1511, 0x00e6, 0x0026, 0x2071, 0x0200, 0x20e1, 0x1000, 0x7220,
-+	0x7028, 0x7020, 0xa206, 0x0de0, 0x20e1, 0x9010, 0x002e, 0x00ee,
-+	0x0005, 0x20e1, 0xa000, 0x7837, 0x0001, 0x782f, 0x0000, 0x782f,
-+	0x0000, 0x782f, 0x0000, 0x782f, 0x0000, 0x7837, 0x0005, 0x20a9,
-+	0x0210, 0x7830, 0xd0bc, 0x1110, 0x1f04, 0x2499, 0x7837, 0x0001,
-+	0x7837, 0x0000, 0xe000, 0xe000, 0x20e1, 0xa000, 0x0005, 0x0126,
-+	0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xb400, 0x6024, 0x6026,
-+	0x6053, 0x0030, 0x080c, 0x27fd, 0x6050, 0xa084, 0xfe7f, 0x6052,
-+	0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x280d, 0x60e7, 0x0000,
-+	0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
-+	0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e, 0x600f,
-+	0x00ff, 0x2001, 0xb68d, 0x2003, 0x00ff, 0x602b, 0x002f, 0x012e,
-+	0x0005, 0x2001, 0xb432, 0x2003, 0x0000, 0x2001, 0xb431, 0x2003,
-+	0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
-+	0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195,
-+	0x0004, 0xa284, 0x0007, 0x0002, 0x2516, 0x24fc, 0x24ff, 0x2502,
-+	0x2507, 0x2509, 0x250d, 0x2511, 0x080c, 0x6b39, 0x00b8, 0x080c,
-+	0x6c14, 0x00a0, 0x080c, 0x6c14, 0x080c, 0x6b39, 0x0078, 0x0099,
-+	0x0068, 0x080c, 0x6b39, 0x0079, 0x0048, 0x080c, 0x6c14, 0x0059,
-+	0x0028, 0x080c, 0x6c14, 0x080c, 0x6b39, 0x0029, 0x002e, 0x001e,
-+	0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x272c, 0x080c,
-+	0x5a90, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, 0xa084,
-+	0x1800, 0x0178, 0x080c, 0x5ab6, 0x0118, 0x080c, 0x5aa2, 0x1148,
-+	0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xb69e, 0x2003, 0xaaaa,
-+	0x0458, 0x080c, 0x5ab6, 0x15d0, 0x6024, 0xa084, 0x1800, 0x1108,
-+	0x04a8, 0x2001, 0xb69e, 0x2003, 0xaaaa, 0x2001, 0xb69f, 0x2003,
-+	0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0x080c, 0x59c8, 0x0804,
-+	0x272c, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1188,
-+	0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x708c, 0xa086, 0x0028, 0x1110,
-+	0x080c, 0x5c1f, 0x0804, 0x272c, 0x2001, 0xb69f, 0x2003, 0x0000,
-+	0x0048, 0x2001, 0xb69f, 0x2003, 0x0002, 0x0020, 0x080c, 0x5b92,
-+	0x0804, 0x272c, 0x080c, 0x5cc4, 0x0804, 0x272c, 0xd1ac, 0x0904,
-+	0x2674, 0x080c, 0x5a90, 0x11d8, 0x6027, 0x0020, 0x0006, 0x0026,
-+	0x0036, 0x080c, 0x5aac, 0x1170, 0x2001, 0xb69f, 0x2003, 0x0001,
-+	0x2001, 0xb400, 0x2003, 0x0001, 0x080c, 0x59c8, 0x003e, 0x002e,
-+	0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5a67, 0x0016,
-+	0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, 0x0100,
-+	0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ce, 0xa48c, 0xff00,
-+	0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x703c, 0xd084,
-+	0x1148, 0xc085, 0x703e, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
-+	0x3e8a, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7054, 0xa084, 0x00ff,
-+	0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011, 0xb453,
-+	0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xb453, 0x2214,
-+	0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248, 0xa294,
-+	0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x2641,
-+	0x7034, 0xd08c, 0x1140, 0x2001, 0xb40c, 0x200c, 0xd1ac, 0x1904,
-+	0x2641, 0xc1ad, 0x2102, 0x0036, 0x73cc, 0x2011, 0x8013, 0x080c,
-+	0x3e8a, 0x003e, 0x0804, 0x2641, 0x7034, 0xd08c, 0x1140, 0x2001,
-+	0xb40c, 0x200c, 0xd1ac, 0x1904, 0x2641, 0xc1ad, 0x2102, 0x0036,
-+	0x73cc, 0x2011, 0x8013, 0x080c, 0x3e8a, 0x003e, 0x7130, 0xc185,
-+	0x7132, 0x2011, 0xb453, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009,
-+	0x0001, 0x2011, 0x0100, 0x080c, 0x6adf, 0x2019, 0x000e, 0x080c,
-+	0xafe8, 0xa484, 0x00ff, 0xa080, 0x2d88, 0x200d, 0xa18c, 0xff00,
-+	0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xb06b, 0x001e,
-+	0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c,
-+	0x2c33, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
-+	0x080c, 0x4f6a, 0x1110, 0x080c, 0x4bc5, 0x8108, 0x1f04, 0x2638,
-+	0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x801f, 0x2011,
-+	0x0002, 0x080c, 0x8029, 0x080c, 0x7f03, 0x0036, 0x2019, 0x0000,
-+	0x080c, 0x7f8e, 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001, 0xb400,
-+	0x2014, 0xa296, 0x0004, 0x1128, 0xd19c, 0x11b0, 0x6228, 0xc29d,
-+	0x622a, 0x2003, 0x0001, 0x2001, 0xb423, 0x2003, 0x0000, 0x6027,
-+	0x0020, 0x080c, 0x5ab6, 0x1140, 0x0016, 0x2009, 0x07d0, 0x2011,
-+	0x59a5, 0x080c, 0x69e7, 0x001e, 0xd194, 0x0904, 0x272c, 0x0016,
-+	0x6220, 0xd2b4, 0x0904, 0x26dd, 0x080c, 0x69d5, 0x080c, 0x7d24,
-+	0x6027, 0x0004, 0x00f6, 0x2019, 0xb6e9, 0x2304, 0xa07d, 0x0570,
-+	0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6, 0x00e6, 0x2069,
-+	0x0140, 0x618c, 0x6288, 0x7818, 0x608e, 0x7808, 0x608a, 0x6043,
-+	0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x6803,
-+	0x1000, 0x6803, 0x0000, 0x618e, 0x628a, 0x080c, 0x7055, 0x080c,
-+	0x7134, 0x7810, 0x2070, 0x7037, 0x0103, 0x2f60, 0x080c, 0x85c0,
-+	0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe, 0x00d6,
-+	0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000,
-+	0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0xb6e0, 0x6028, 0xa09a,
-+	0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x7d17, 0x0804,
-+	0x272b, 0x2019, 0xb6e9, 0x2304, 0xa065, 0x0120, 0x2009, 0x0027,
-+	0x080c, 0x85ef, 0x00ce, 0x0804, 0x272b, 0xd2bc, 0x0904, 0x272b,
-+	0x080c, 0x69e2, 0x6014, 0xa084, 0x0184, 0xa085, 0x0010, 0x6016,
-+	0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
-+	0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
-+	0xb6e0, 0x6044, 0xa09a, 0x00c8, 0x12f0, 0x8000, 0x6046, 0x603c,
-+	0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0, 0x080c, 0x69da, 0xa080,
-+	0x0007, 0x2004, 0xa086, 0x0006, 0x1138, 0x6114, 0xa18c, 0x0184,
-+	0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c, 0x0184, 0xa18d,
-+	0x0016, 0x6116, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c, 0x7f8e,
-+	0x003e, 0x2019, 0xb6ef, 0x2304, 0xa065, 0x0120, 0x2009, 0x004f,
-+	0x080c, 0x85ef, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x2785, 0x7034,
-+	0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027, 0x0008, 0x602f, 0x0020,
-+	0x20a9, 0x0006, 0x1d04, 0x273a, 0x2091, 0x6000, 0x1f04, 0x273a,
-+	0x602f, 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0366,
-+	0x1d04, 0x2748, 0x2091, 0x6000, 0x6020, 0xd09c, 0x1130, 0x015e,
-+	0x6152, 0x001e, 0x6027, 0x0008, 0x0480, 0x080c, 0x28cd, 0x1f04,
-+	0x2748, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028,
-+	0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x801f, 0x2011, 0x0002,
-+	0x080c, 0x8029, 0x080c, 0x7f03, 0x0036, 0x2019, 0x0000, 0x080c,
-+	0x7f8e, 0x003e, 0x60e3, 0x0000, 0x080c, 0xb3b2, 0x080c, 0xb3cd,
-+	0xa085, 0x0001, 0x080c, 0x5ad4, 0x2001, 0xb400, 0x2003, 0x0004,
-+	0x6027, 0x0008, 0x080c, 0x12d9, 0x001e, 0xa18c, 0xffd0, 0x6126,
-+	0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091,
-+	0x8000, 0x2071, 0xb400, 0x71c4, 0x70c6, 0xa116, 0x0500, 0x81ff,
-+	0x0128, 0x2011, 0x8011, 0x080c, 0x3e8a, 0x00c8, 0x2011, 0x8012,
-+	0x080c, 0x3e8a, 0x2001, 0xb472, 0x2004, 0xd0fc, 0x1180, 0x0036,
-+	0x00c6, 0x080c, 0x2858, 0x080c, 0x7edf, 0x2061, 0x0100, 0x2019,
-+	0x0028, 0x2009, 0x0000, 0x080c, 0x2c33, 0x00ce, 0x003e, 0x012e,
-+	0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6,
-+	0x0006, 0x0026, 0x2061, 0x0100, 0xa190, 0x27d1, 0x2205, 0x60f2,
-+	0x2011, 0x27de, 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce,
-+	0x0005, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0,
-+	0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
-+	0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094,
-+	0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, 0x6672, 0x0038, 0xa080,
-+	0x2d88, 0x200d, 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080,
-+	0x2d88, 0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140,
-+	0x2001, 0xb415, 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852,
-+	0x6856, 0x1f04, 0x2808, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026,
-+	0x2069, 0x0140, 0x2001, 0xb415, 0x2102, 0x8114, 0x8214, 0x8214,
-+	0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128,
-+	0xa184, 0x000f, 0xa080, 0xb3e1, 0x2005, 0x6856, 0x8211, 0x1f04,
-+	0x281d, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0xb400,
-+	0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005,
-+	0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980,
-+	0xa116, 0x0180, 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001,
-+	0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x284d,
-+	0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005,
-+	0x2001, 0xb453, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006,
-+	0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xb06b, 0x004e, 0x0005,
-+	0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0548,
-+	0xa084, 0x0700, 0xa08e, 0x0300, 0x1520, 0x2011, 0x0000, 0x2009,
-+	0x0002, 0x2300, 0xa080, 0x0020, 0x2018, 0x2300, 0x080c, 0x6b05,
-+	0x2011, 0x0030, 0x2200, 0x8007, 0xa085, 0x004c, 0x78c2, 0x2009,
-+	0x0204, 0x210c, 0x2200, 0xa100, 0x2009, 0x0138, 0x200a, 0x080c,
-+	0x5a90, 0x1118, 0x2009, 0xb68f, 0x200a, 0x002e, 0x001e, 0x00fe,
-+	0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
-+	0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0xa184,
-+	0x0003, 0x0110, 0x0804, 0x1ad3, 0x002e, 0x001e, 0x000e, 0x012e,
-+	0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e,
-+	0x0268, 0x2001, 0x0170, 0x200c, 0xa18c, 0x00ff, 0xa18e, 0x004c,
-+	0x1128, 0x200c, 0xa18c, 0xff00, 0x810f, 0x0010, 0x2009, 0x0000,
-+	0x2001, 0x0204, 0x2004, 0xa108, 0x0005, 0x0006, 0x0156, 0x00f6,
-+	0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x1110, 0x1f04,
-+	0x28d4, 0x00fe, 0x015e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006,
-+	0x2061, 0x0100, 0x6030, 0x0006, 0x6048, 0x0006, 0x60e4, 0x0006,
-+	0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006,
-+	0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x60e0, 0x0006,
-+	0x602f, 0x0100, 0x602f, 0x0000, 0xe000, 0xe000, 0xe000, 0xe000,
-+	0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x60e2, 0x000e, 0x602a,
-+	0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2,
-+	0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a,
-+	0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x280d, 0x000e, 0x00ce,
-+	0x001e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009,
-+	0x0170, 0x2104, 0x200b, 0x0080, 0xe000, 0xe000, 0x200a, 0x0005,
-+	0x29c0, 0x29c4, 0x29c8, 0x29ce, 0x29d4, 0x29da, 0x29e0, 0x29e8,
-+	0x29f0, 0x29f6, 0x29fc, 0x2a04, 0x2a0c, 0x2a14, 0x2a1c, 0x2a26,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a32, 0x2a32, 0x2a38, 0x2a38, 0x2a3f, 0x2a3f, 0x2a46, 0x2a46,
-+	0x2a4f, 0x2a4f, 0x2a56, 0x2a56, 0x2a5f, 0x2a5f, 0x2a68, 0x2a68,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73, 0x2a73,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30, 0x2a30,
-+	0x0106, 0x0006, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x0804, 0x2a7b,
-+	0x0106, 0x0006, 0x080c, 0x24e2, 0x0804, 0x2a7b, 0x0106, 0x0006,
-+	0x080c, 0x24e2, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x236d,
-+	0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x236d, 0x0804, 0x2a7b,
-+	0x0106, 0x0006, 0x080c, 0x24e2, 0x080c, 0x236d, 0x0804, 0x2a7b,
-+	0x0106, 0x0006, 0x080c, 0x24e2, 0x080c, 0x236d, 0x0804, 0x2a7b,
-+	0x0106, 0x0006, 0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006,
-+	0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x24e2,
-+	0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x24e2,
-+	0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x236d,
-+	0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x236d,
-+	0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006, 0x080c, 0x24e2,
-+	0x080c, 0x236d, 0x080c, 0x23c3, 0x0804, 0x2a7b, 0x0106, 0x0006,
-+	0x080c, 0x24e2, 0x080c, 0x236d, 0x080c, 0x23c3, 0x0804, 0x2a7b,
-+	0xe000, 0x0cf0, 0x0106, 0x0006, 0x080c, 0x289c, 0x0804, 0x2a7b,
-+	0x0106, 0x0006, 0x080c, 0x289c, 0x080c, 0x24e2, 0x04e0, 0x0106,
-+	0x0006, 0x080c, 0x289c, 0x080c, 0x236d, 0x04a8, 0x0106, 0x0006,
-+	0x080c, 0x289c, 0x080c, 0x24e2, 0x080c, 0x236d, 0x0460, 0x0106,
-+	0x0006, 0x080c, 0x289c, 0x080c, 0x23c3, 0x0428, 0x0106, 0x0006,
-+	0x080c, 0x289c, 0x080c, 0x24e2, 0x080c, 0x23c3, 0x00e0, 0x0106,
-+	0x0006, 0x080c, 0x289c, 0x080c, 0x236d, 0x080c, 0x23c3, 0x0098,
-+	0x0106, 0x0006, 0x080c, 0x289c, 0x080c, 0x24e2, 0x080c, 0x236d,
-+	0x080c, 0x23c3, 0x0040, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1,
-+	0x0000, 0x080c, 0x1511, 0x000e, 0x010e, 0x000d, 0x00c6, 0x0026,
-+	0x0046, 0x2021, 0x0000, 0x080c, 0x52ca, 0x1904, 0x2b5b, 0x72d4,
-+	0x2001, 0xb69e, 0x2004, 0xa005, 0x1110, 0xd29c, 0x0148, 0xd284,
-+	0x1138, 0xd2bc, 0x1904, 0x2b5b, 0x080c, 0x2b5f, 0x0804, 0x2b5b,
-+	0xd2cc, 0x1904, 0x2b5b, 0x080c, 0x5a90, 0x1120, 0x709f, 0xffff,
-+	0x0804, 0x2b5b, 0xd294, 0x0120, 0x709f, 0xffff, 0x0804, 0x2b5b,
-+	0x2001, 0xb415, 0x203c, 0x7288, 0xd284, 0x0904, 0x2afd, 0xd28c,
-+	0x1904, 0x2afd, 0x0036, 0x739c, 0xa38e, 0xffff, 0x1110, 0x2019,
-+	0x0001, 0x8314, 0xa2e0, 0xbbc0, 0x2c04, 0xa38c, 0x0001, 0x0120,
-+	0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, 0x0560,
-+	0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230, 0xd284,
-+	0x1538, 0x7288, 0xc28d, 0x728a, 0x709f, 0xffff, 0x003e, 0x0428,
-+	0x2009, 0x0000, 0x080c, 0x27e3, 0x080c, 0x4f0e, 0x11b8, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c, 0x0118,
-+	0x6000, 0xd0bc, 0x0120, 0x080c, 0x2b72, 0x0140, 0x0028, 0x080c,
-+	0x2ca1, 0x080c, 0x2ba0, 0x0110, 0x8318, 0x0818, 0x739e, 0x0010,
-+	0x709f, 0xffff, 0x003e, 0x0804, 0x2b5b, 0xa780, 0x2d88, 0x203d,
-+	0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x709c, 0xa096, 0xffff,
-+	0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220, 0x2008,
-+	0xa802, 0x20a8, 0x0020, 0x709f, 0xffff, 0x0804, 0x2b5b, 0x2700,
-+	0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4f6a, 0x0120,
-+	0x080c, 0x4f0e, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084, 0x00ff,
-+	0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000, 0xd0bc,
-+	0x11d0, 0x7288, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff, 0xa082,
-+	0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4f2d, 0x0028, 0x080c,
-+	0x2d2e, 0x0170, 0x080c, 0x2d5b, 0x0058, 0x080c, 0x2ca1, 0x080c,
-+	0x2ba0, 0x0170, 0x0028, 0x080c, 0x2d2e, 0x0110, 0x0419, 0x0140,
-+	0x001e, 0x8108, 0x015e, 0x1f04, 0x2b17, 0x709f, 0xffff, 0x0018,
-+	0x001e, 0x015e, 0x719e, 0x004e, 0x002e, 0x00ce, 0x0005, 0x00c6,
-+	0x0016, 0x709f, 0x0001, 0x2009, 0x007e, 0x080c, 0x4f0e, 0x1138,
-+	0x080c, 0x2ca1, 0x04a9, 0x0118, 0x70d4, 0xc0bd, 0x70d6, 0x001e,
-+	0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001,
-+	0xb457, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9e67, 0x01d8,
-+	0x2d00, 0x601a, 0x080c, 0x9fb8, 0x601f, 0x0001, 0x2001, 0x0000,
-+	0x080c, 0x4eac, 0x2001, 0x0000, 0x080c, 0x4ebe, 0x0126, 0x2091,
-+	0x8000, 0x7098, 0x8000, 0x709a, 0x012e, 0x2009, 0x0004, 0x080c,
-+	0x85ef, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
-+	0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xb457, 0x2004,
-+	0xa084, 0x00ff, 0x6842, 0x080c, 0x9e67, 0x0550, 0x2d00, 0x601a,
-+	0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140, 0x6804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2c60, 0x080c,
-+	0x9fb8, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4eac, 0x2001,
-+	0x0002, 0x080c, 0x4ebe, 0x0126, 0x2091, 0x8000, 0x7098, 0x8000,
-+	0x709a, 0x012e, 0x2009, 0x0002, 0x080c, 0x85ef, 0xa085, 0x0001,
-+	0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009,
-+	0x0080, 0x080c, 0x4f0e, 0x1120, 0x0031, 0x0110, 0x70db, 0xffff,
-+	0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
-+	0x080c, 0x856a, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9fb8, 0x601f,
-+	0x0001, 0x2001, 0x0000, 0x080c, 0x4eac, 0x2001, 0x0002, 0x080c,
-+	0x4ebe, 0x0126, 0x2091, 0x8000, 0x70dc, 0x8000, 0x70de, 0x012e,
-+	0x2009, 0x0002, 0x080c, 0x85ef, 0xa085, 0x0001, 0x00ce, 0x00de,
-+	0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000,
-+	0x2009, 0x007f, 0x080c, 0x4f0e, 0x1190, 0x2c68, 0x080c, 0x856a,
-+	0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, 0x080c,
-+	0x9fb8, 0x2009, 0x0022, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e,
-+	0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026,
-+	0x080c, 0x6dc6, 0x080c, 0x6d69, 0x080c, 0x900f, 0x2130, 0x81ff,
-+	0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9, 0x007f,
-+	0x2009, 0x0000, 0x0016, 0x080c, 0x4f6a, 0x1120, 0x080c, 0x516b,
-+	0x080c, 0x4bc5, 0x001e, 0x8108, 0x1f04, 0x2c4a, 0x86ff, 0x1110,
-+	0x080c, 0x11f0, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005,
-+	0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270, 0x72a0,
-+	0x0026, 0x2019, 0x0029, 0x080c, 0x6dba, 0x0076, 0x2039, 0x0000,
-+	0x080c, 0x6cc7, 0x2c08, 0x080c, 0xae05, 0x007e, 0x001e, 0x2e60,
-+	0x080c, 0x516b, 0x6210, 0x6314, 0x080c, 0x4bc5, 0x6212, 0x6316,
-+	0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006,
-+	0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150, 0x2071,
-+	0xb400, 0x7098, 0xa005, 0x0110, 0x8001, 0x709a, 0x000e, 0x00ee,
-+	0x0005, 0x2071, 0xb400, 0x70dc, 0xa005, 0x0dc0, 0x8001, 0x70de,
-+	0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-+	0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, 0x20a9,
-+	0x0001, 0x0098, 0x2001, 0xb453, 0x2004, 0xd0c4, 0x0150, 0xd0a4,
-+	0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c, 0xb06b,
-+	0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e, 0x007e,
-+	0x0904, 0x2d0d, 0xa28e, 0x007f, 0x0904, 0x2d0d, 0xa28e, 0x0080,
-+	0x05e0, 0xa288, 0xb535, 0x210c, 0x81ff, 0x05b8, 0x8fff, 0x1148,
-+	0x2001, 0xb6be, 0x0006, 0x2003, 0x0001, 0x04d9, 0x000e, 0x2003,
-+	0x0000, 0x00c6, 0x2160, 0x2001, 0x0001, 0x080c, 0x52d4, 0x00ce,
-+	0x2019, 0x0029, 0x080c, 0x6dba, 0x0076, 0x2039, 0x0000, 0x080c,
-+	0x6cc7, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286,
-+	0x0006, 0x1118, 0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007,
-+	0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xae05,
-+	0x001e, 0x007e, 0x2160, 0x080c, 0x516b, 0x002e, 0x8210, 0x1f04,
-+	0x2cc5, 0x015e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe,
-+	0x0005, 0x0046, 0x0026, 0x0016, 0x2001, 0xb453, 0x2004, 0xd0c4,
-+	0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029,
-+	0x080c, 0xb06b, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026,
-+	0x0036, 0x00c6, 0x7288, 0x82ff, 0x01f8, 0x2011, 0xb453, 0x2214,
-+	0xd2ac, 0x11d0, 0x2100, 0x080c, 0x27f7, 0x81ff, 0x01b8, 0x2019,
-+	0x0001, 0x8314, 0xa2e0, 0xbbc0, 0x2c04, 0xd384, 0x0120, 0xa084,
-+	0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096,
-+	0x00ff, 0x0110, 0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e,
-+	0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000,
-+	0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019, 0x0029, 0x080c,
-+	0x823c, 0x002e, 0x080c, 0xb310, 0x003e, 0x002e, 0x001e, 0xa180,
-+	0xb535, 0x2004, 0xa065, 0x0158, 0x0016, 0x00c6, 0x2061, 0xb7f4,
-+	0x001e, 0x611a, 0x080c, 0x2c60, 0x001e, 0x080c, 0x4f2d, 0x012e,
-+	0x00ce, 0x001e, 0x0005, 0x2001, 0xb435, 0x2004, 0xd0cc, 0x0005,
-+	0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da,
-+	0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce,
-+	0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5,
-+	0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3,
-+	0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9,
-+	0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b,
-+	0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081,
-+	0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073,
-+	0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69,
-+	0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056,
-+	0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c,
-+	0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c,
-+	0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831,
-+	0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026,
-+	0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017,
-+	0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000,
-+	0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000,
-+	0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300,
-+	0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100,
-+	0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00,
-+	0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800,
-+	0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000,
-+	0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000,
-+	0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500,
-+	0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000,
-+	0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000,
-+	0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000,
-+	0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000,
-+	0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x2071, 0xb482, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a,
-+	0x703e, 0x7033, 0xb492, 0x7037, 0xb492, 0x7007, 0x0001, 0x2061,
-+	0xb4d2, 0x6003, 0x0002, 0x0005, 0x1004, 0x2eae, 0x0e04, 0x2eae,
-+	0x2071, 0xb482, 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820,
-+	0xa08e, 0x0069, 0x1904, 0x2f93, 0x0804, 0x2f2c, 0x0005, 0x2071,
-+	0xb482, 0x7004, 0x0002, 0x2eb7, 0x2eb8, 0x2ec1, 0x2ed2, 0x0005,
-+	0x1004, 0x2ec0, 0x0e04, 0x2ec0, 0x2b78, 0x7818, 0xd084, 0x01e8,
-+	0x0005, 0x2b78, 0x2061, 0xb4d2, 0x6008, 0xa08e, 0x0100, 0x0128,
-+	0xa086, 0x0200, 0x0904, 0x2f8d, 0x0005, 0x7014, 0x2068, 0x2a60,
-+	0x7018, 0x0807, 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108,
-+	0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a,
-+	0x0040, 0x1210, 0x61c4, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04,
-+	0x2f8a, 0x61c4, 0x0804, 0x2f2c, 0x2f6e, 0x2f99, 0x2fa1, 0x2fa5,
-+	0x2fad, 0x2fb3, 0x2fb7, 0x2fc3, 0x2fc6, 0x2fd0, 0x2fd3, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2fd6, 0x2f8a, 0x2fe5, 0x2ffc, 0x3013, 0x308d,
-+	0x3092, 0x30bb, 0x310c, 0x311d, 0x313c, 0x3174, 0x317e, 0x318b,
-+	0x319e, 0x31bf, 0x31c8, 0x31fe, 0x3204, 0x2f8a, 0x322d, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x3234, 0x323e, 0x2f8a, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x3246, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x3258, 0x3262, 0x2f8a, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x0002, 0x328c, 0x32e0, 0x333b,
-+	0x334e, 0x2f8a, 0x337f, 0x37b2, 0x41f1, 0x2f8a, 0x2f8a, 0x2f8a,
-+	0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a, 0x2fd0, 0x2fd3, 0x37b4,
-+	0x2f8a, 0x37c1, 0x428a, 0x42e5, 0x4349, 0x2f8a, 0x43ac, 0x43d2,
-+	0x43f1, 0x4423, 0x2f8a, 0x2f8a, 0x2f8a, 0x37c5, 0x396a, 0x3984,
-+	0x39a2, 0x3a03, 0x3a63, 0x3a6e, 0x3aa6, 0x3ab5, 0x3ac4, 0x3ac7,
-+	0x3aea, 0x3b34, 0x3baa, 0x3bb7, 0x3cb8, 0x3de1, 0x3e0a, 0x3f08,
-+	0x3f2a, 0x3f36, 0x3f6f, 0x4033, 0x2f8a, 0x2f8a, 0x2f8a, 0x2f8a,
-+	0x409b, 0x40b6, 0x4128, 0x41da, 0x713c, 0x0000, 0x2021, 0x4000,
-+	0x080c, 0x3e67, 0x0126, 0x2091, 0x8000, 0x0e04, 0x2f7a, 0x7818,
-+	0xd084, 0x0110, 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
-+	0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000,
-+	0x012e, 0x0005, 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00,
-+	0x2021, 0x4003, 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006,
-+	0x08b8, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804,
-+	0x3e74, 0x7823, 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28,
-+	0x7a2c, 0x7824, 0x7930, 0x0804, 0x3e77, 0x7924, 0x7828, 0x2114,
-+	0x200a, 0x0804, 0x2f6e, 0x7924, 0x2114, 0x0804, 0x2f6e, 0x2099,
-+	0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28,
-+	0x7b2c, 0x0804, 0x2f6e, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002,
-+	0x2011, 0x0002, 0x2019, 0x0003, 0x783b, 0x0017, 0x0804, 0x2f6e,
-+	0x7d38, 0x7c3c, 0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000,
-+	0xe10c, 0xa006, 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010,
-+	0xa005, 0x0904, 0x2f6e, 0x0804, 0x2f90, 0x2069, 0xb452, 0x7824,
-+	0x7930, 0xa11a, 0x1a04, 0x2f96, 0x8019, 0x0904, 0x2f96, 0x684a,
-+	0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e,
-+	0x080c, 0x5d66, 0x0804, 0x2f6e, 0x2069, 0xb452, 0x7824, 0x7934,
-+	0xa11a, 0x1a04, 0x2f96, 0x8019, 0x0904, 0x2f96, 0x684e, 0x6946,
-+	0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c,
-+	0x5396, 0x0804, 0x2f6e, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2f93,
-+	0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xb489, 0x41a1,
-+	0x080c, 0x3e33, 0x0904, 0x2f93, 0x2009, 0x0020, 0x080c, 0x3e74,
-+	0x701b, 0x302b, 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096,
-+	0x0011, 0x0138, 0xa096, 0x0019, 0x0120, 0xa096, 0x0015, 0x1904,
-+	0x2f93, 0x810f, 0xa18c, 0x00ff, 0x0904, 0x2f93, 0x710e, 0x700c,
-+	0x8001, 0x0528, 0x700e, 0x080c, 0x3e33, 0x0904, 0x2f93, 0x2009,
-+	0x0020, 0x2061, 0xb4d2, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290,
-+	0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x080c,
-+	0x3e74, 0x701b, 0x305c, 0x0005, 0x6834, 0xa084, 0x00ff, 0xa096,
-+	0x0002, 0x0120, 0xa096, 0x000a, 0x1904, 0x2f93, 0x08c0, 0x7010,
-+	0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x4e0a, 0x1128, 0x7007,
-+	0x0003, 0x701b, 0x3076, 0x0005, 0x080c, 0x549c, 0x0126, 0x2091,
-+	0x8000, 0x20a9, 0x0005, 0x2099, 0xb489, 0x530a, 0x2100, 0xa210,
-+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d,
-+	0x2009, 0x0020, 0x012e, 0x0804, 0x3e77, 0x61ac, 0x7824, 0x60ae,
-+	0x0804, 0x2f6e, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953,
-+	0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832,
-+	0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c,
-+	0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b,
-+	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1,
-+	0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904, 0x2f93, 0x7924, 0x810f,
-+	0xa18c, 0x00ff, 0x080c, 0x4f6a, 0x1904, 0x2f96, 0x7e38, 0xa684,
-+	0x3fff, 0xa082, 0x4000, 0x0210, 0x0804, 0x2f96, 0x7c28, 0x7d2c,
-+	0x080c, 0x5132, 0xd28c, 0x1118, 0x080c, 0x50db, 0x0010, 0x080c,
-+	0x510b, 0x1518, 0x2061, 0xbc00, 0x0126, 0x2091, 0x8000, 0x6000,
-+	0xa086, 0x0000, 0x0148, 0x6010, 0xa06d, 0x0130, 0x683c, 0xa406,
-+	0x1118, 0x6840, 0xa506, 0x0150, 0x012e, 0xace0, 0x0018, 0x2001,
-+	0xb417, 0x2004, 0xac02, 0x1a04, 0x2f93, 0x0c30, 0x080c, 0x98c3,
-+	0x012e, 0x0904, 0x2f93, 0x0804, 0x2f6e, 0xa00e, 0x2001, 0x0005,
-+	0x080c, 0x549c, 0x0126, 0x2091, 0x8000, 0x080c, 0x9e63, 0x080c,
-+	0x53c9, 0x012e, 0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93, 0x080c,
-+	0x3e48, 0x0904, 0x2f96, 0x080c, 0x5030, 0x0904, 0x2f93, 0x080c,
-+	0x513e, 0x0904, 0x2f93, 0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93,
-+	0x080c, 0x3e58, 0x0904, 0x2f96, 0x080c, 0x51aa, 0x0904, 0x2f93,
-+	0x2019, 0x0005, 0x7924, 0x080c, 0x5159, 0x0904, 0x2f93, 0x7828,
-+	0xa08a, 0x1000, 0x1a04, 0x2f96, 0x8003, 0x800b, 0x810b, 0xa108,
-+	0x080c, 0x696d, 0x0804, 0x2f6e, 0x0126, 0x2091, 0x8000, 0x81ff,
-+	0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x00ff, 0x6450, 0x2400,
-+	0xa506, 0x01f8, 0x2508, 0x080c, 0x4f6a, 0x11d8, 0x080c, 0x51aa,
-+	0x1128, 0x2009, 0x0002, 0x62b4, 0x2518, 0x00c0, 0x2019, 0x0004,
-+	0xa00e, 0x080c, 0x5159, 0x1118, 0x2009, 0x0006, 0x0078, 0x7824,
-+	0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
-+	0x696d, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x2f6e, 0x012e, 0x0804,
-+	0x2f93, 0x012e, 0x0804, 0x2f96, 0x080c, 0x3e48, 0x0904, 0x2f96,
-+	0x080c, 0x5096, 0x080c, 0x5132, 0x0804, 0x2f6e, 0x81ff, 0x1904,
-+	0x2f93, 0x080c, 0x3e48, 0x0904, 0x2f96, 0x080c, 0x5087, 0x080c,
-+	0x5132, 0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93, 0x080c, 0x3e48,
-+	0x0904, 0x2f96, 0x080c, 0x510d, 0x0904, 0x2f93, 0x080c, 0x4e4e,
-+	0x080c, 0x50d4, 0x080c, 0x5132, 0x0804, 0x2f6e, 0x080c, 0x3e48,
-+	0x0904, 0x2f96, 0x080c, 0x5030, 0x0904, 0x2f93, 0x62a0, 0x2019,
-+	0x0005, 0x00c6, 0x080c, 0x516b, 0x2061, 0x0000, 0x080c, 0x6dba,
-+	0x0076, 0x2039, 0x0000, 0x080c, 0x6cc7, 0x2009, 0x0000, 0x080c,
-+	0xae05, 0x007e, 0x00ce, 0x080c, 0x5132, 0x0804, 0x2f6e, 0x080c,
-+	0x3e48, 0x0904, 0x2f96, 0x080c, 0x5132, 0x2208, 0x0804, 0x2f6e,
-+	0x0156, 0x00d6, 0x00e6, 0x2069, 0xb514, 0x6810, 0x6914, 0xa10a,
-+	0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000,
-+	0x20a9, 0x007e, 0x2069, 0xb535, 0x2d04, 0xa075, 0x0130, 0x704c,
-+	0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04, 0x31dc,
-+	0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2f6e, 0x00f6,
-+	0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff,
-+	0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0xb514,
-+	0x6910, 0x62b0, 0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93, 0x6150,
-+	0xa190, 0x2d88, 0x2215, 0xa294, 0x00ff, 0x6370, 0x83ff, 0x0108,
-+	0x6274, 0x67d4, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090, 0xd7ac,
-+	0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031, 0x0002,
-+	0x0040, 0x080c, 0x5a90, 0x1118, 0x2031, 0x0004, 0x0010, 0x2031,
-+	0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2f6e, 0x6140, 0x6244, 0x2019,
-+	0xb6b6, 0x231c, 0x0804, 0x2f6e, 0x0126, 0x2091, 0x8000, 0x6134,
-+	0xa006, 0x2010, 0x6338, 0x012e, 0x0804, 0x2f6e, 0x080c, 0x3e58,
-+	0x0904, 0x2f96, 0x6244, 0x6338, 0x0804, 0x2f6e, 0x6140, 0x6244,
-+	0x7824, 0x6042, 0x7b28, 0x6346, 0x2069, 0xb452, 0x831f, 0xa305,
-+	0x6816, 0x782c, 0x2069, 0xb6b6, 0x2d1c, 0x206a, 0x0804, 0x2f6e,
-+	0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x782c, 0x603a, 0x012e,
-+	0x0804, 0x2f6e, 0x7838, 0xa005, 0x01a8, 0x7828, 0xa025, 0x0904,
-+	0x2f96, 0x782c, 0xa02d, 0x0904, 0x2f96, 0xa00e, 0x080c, 0x4f6a,
-+	0x1120, 0x6244, 0x6338, 0x6446, 0x653a, 0xa186, 0x00ff, 0x0190,
-+	0x8108, 0x0ca0, 0x080c, 0x3e58, 0x0904, 0x2f96, 0x7828, 0xa00d,
-+	0x0904, 0x2f96, 0x782c, 0xa005, 0x0904, 0x2f96, 0x6244, 0x6146,
-+	0x6338, 0x603a, 0x0804, 0x2f6e, 0x2001, 0xb400, 0x2004, 0xa086,
-+	0x0003, 0x1904, 0x2f93, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f,
-+	0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xb415, 0x2004,
-+	0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2d88,
-+	0x210d, 0xa18c, 0x00ff, 0x2001, 0xb415, 0x2004, 0xa116, 0x0550,
-+	0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x856a,
-+	0x000e, 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c,
-+	0x3e33, 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000,
-+	0x6838, 0xc0fd, 0x683a, 0x701b, 0x3334, 0x2d00, 0x6012, 0x2009,
-+	0x0032, 0x080c, 0x85ef, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce,
-+	0x0804, 0x2f93, 0x00ce, 0x0804, 0x2f96, 0x080c, 0x85c0, 0x0cb0,
-+	0x2001, 0xb400, 0x2004, 0xa086, 0x0003, 0x1904, 0x2f93, 0x00c6,
-+	0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
-+	0x1130, 0x2001, 0xb415, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182,
-+	0x007f, 0x16a0, 0xa188, 0x2d88, 0x210d, 0xa18c, 0x00ff, 0x2001,
-+	0xb415, 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091,
-+	0x8000, 0x0006, 0x080c, 0x856a, 0x000e, 0x01e0, 0x601a, 0x600b,
-+	0xbc05, 0x601f, 0x0001, 0x080c, 0x3e33, 0x01d8, 0x6837, 0x0000,
-+	0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b,
-+	0x3334, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x85ef, 0x012e,
-+	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x2f93, 0x00ce, 0x0804,
-+	0x2f96, 0x080c, 0x85c0, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904,
-+	0x2f93, 0x0804, 0x2f6e, 0x2061, 0xb774, 0x0126, 0x2091, 0x8000,
-+	0x6000, 0xd084, 0x0140, 0x6104, 0x6208, 0x2019, 0xb412, 0x231c,
-+	0x012e, 0x0804, 0x2f6e, 0x012e, 0x0804, 0x2f96, 0x81ff, 0x1904,
-+	0x2f93, 0x080c, 0x5a90, 0x0904, 0x2f93, 0x0126, 0x2091, 0x8000,
-+	0x6248, 0x6068, 0xa202, 0x0248, 0xa085, 0x0001, 0x080c, 0x282d,
-+	0x080c, 0x45e6, 0x012e, 0x0804, 0x2f6e, 0x012e, 0x0804, 0x2f96,
-+	0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0xb6bf, 0x2070, 0x2061,
-+	0xb452, 0x6008, 0x2072, 0x2009, 0x0000, 0x2011, 0x1000, 0x080c,
-+	0x6b05, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x7824, 0xa084, 0x0007, 0x0002, 0x3391, 0x339a,
-+	0x33a1, 0x338e, 0x338e, 0x338e, 0x338e, 0x338e, 0x012e, 0x0804,
-+	0x2f96, 0x2009, 0x0114, 0x2104, 0xa085, 0x0800, 0x200a, 0x080c,
-+	0x350c, 0x0070, 0x2009, 0x010b, 0x200b, 0x0010, 0x080c, 0x350c,
-+	0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2f70,
-+	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
-+	0x080c, 0x3368, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0138,
-+	0x200c, 0x2003, 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, 0x2001,
-+	0x007b, 0x202c, 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, 0x3757,
-+	0x080c, 0x36bb, 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, 0x2d60,
-+	0x2071, 0xb74a, 0x2079, 0x0020, 0x00d6, 0x2069, 0x0000, 0x6824,
-+	0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004, 0x783e, 0x2001, 0x007c,
-+	0x2004, 0x783a, 0x00de, 0x2011, 0x0001, 0x080c, 0x3667, 0x080c,
-+	0x3667, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x35b2, 0x080c, 0x368f,
-+	0x080c, 0x360c, 0x080c, 0x3571, 0x080c, 0x35a2, 0x00f6, 0x2079,
-+	0x0100, 0x7824, 0xd094, 0x0530, 0x7814, 0xa084, 0x0184, 0xa085,
-+	0x0010, 0x7816, 0x2079, 0x0140, 0x080c, 0x34ea, 0x1110, 0x00fe,
-+	0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086,
-+	0x7814, 0xa084, 0x0184, 0xa085, 0x0032, 0x7816, 0x080c, 0x34ea,
-+	0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc, 0x0dc0, 0x7827, 0x0080,
-+	0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x34f4,
-+	0x00fe, 0x0804, 0x34b4, 0x00fe, 0x080c, 0x34ea, 0x1150, 0x8948,
-+	0x2001, 0x007a, 0x2602, 0x2001, 0x007b, 0x2502, 0x080c, 0x34f4,
-+	0x0088, 0x87ff, 0x0140, 0x2001, 0x0201, 0x2004, 0xa005, 0x1904,
-+	0x33ee, 0x8739, 0x0038, 0x2001, 0xb723, 0x2004, 0xa086, 0x0000,
-+	0x1904, 0x33ee, 0x2001, 0x0033, 0x2003, 0x00f6, 0x8631, 0x1208,
-+	0x8529, 0x2500, 0xa605, 0x0904, 0x34b4, 0x7824, 0xd0bc, 0x0128,
-+	0x2900, 0xaa05, 0xab05, 0x1904, 0x34b4, 0x6033, 0x000d, 0x2001,
-+	0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1148, 0x2001, 0xb723,
-+	0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x0040, 0x6027,
-+	0x0001, 0x2001, 0x0075, 0x2004, 0xa005, 0x0108, 0x6026, 0x2c00,
-+	0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a, 0x6833, 0x000d, 0x7824,
-+	0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061,
-+	0x0020, 0x6003, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3489,
-+	0x00ce, 0x0040, 0x6827, 0x0001, 0x2001, 0x0074, 0x2004, 0xa005,
-+	0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0020,
-+	0x7827, 0x0002, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x601a,
-+	0x0006, 0x2001, 0x0073, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca,
-+	0x00ce, 0x00fe, 0x0804, 0x33cc, 0x2061, 0x0100, 0x6027, 0x0002,
-+	0x001e, 0x61e2, 0x001e, 0x6106, 0x7824, 0xa084, 0x0003, 0xa086,
-+	0x0002, 0x0188, 0x20e1, 0x9028, 0x6050, 0xa084, 0xf7ef, 0x6052,
-+	0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e, 0x604b, 0xf7f7, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0xaa05,
-+	0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-+	0x008e, 0x1118, 0x012e, 0x0804, 0x2f6e, 0x012e, 0x2021, 0x400c,
-+	0x0804, 0x2f70, 0xa085, 0x0001, 0x1d04, 0x34f3, 0x2091, 0x6000,
-+	0x8420, 0xa486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010,
-+	0x2001, 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, 0x2003, 0x0004,
-+	0x2001, 0xb723, 0x2003, 0x0000, 0x2001, 0xb74a, 0x2003, 0x0000,
-+	0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001,
-+	0xb415, 0x200c, 0x7932, 0x7936, 0x080c, 0x280d, 0x7850, 0xa084,
-+	0x0980, 0xa085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0,
-+	0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad, 0x782e, 0x20a9, 0x0046,
-+	0x1d04, 0x3528, 0x2091, 0x6000, 0x1f04, 0x3528, 0x7850, 0xa085,
-+	0x0400, 0x7852, 0x2001, 0x0009, 0x2004, 0xa084, 0x0003, 0xa086,
-+	0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, 0x784b, 0xf7f7, 0x7843,
-+	0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x3545,
-+	0x7850, 0xa085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xe000,
-+	0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
-+	0xa085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xe000,
-+	0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7827,
-+	0x0020, 0x7843, 0x0000, 0x2003, 0x0000, 0x7827, 0x0048, 0x00fe,
-+	0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0xb723,
-+	0x2079, 0x0030, 0x2001, 0x0201, 0x2004, 0xa005, 0x0160, 0x7000,
-+	0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003,
-+	0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x780c, 0xa08c,
-+	0x0070, 0x0178, 0x2009, 0x007a, 0x260a, 0x2009, 0x007b, 0x250a,
-+	0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108,
-+	0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0140,
-+	0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x0ca8,
-+	0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0xb6c0, 0x2004,
-+	0x70e2, 0x2009, 0xb415, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166,
-+	0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078,
-+	0xa080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa,
-+	0xa006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af,
-+	0x95d5, 0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032,
-+	0x7016, 0x080c, 0x368f, 0x080c, 0x34ea, 0x1110, 0x8421, 0x0028,
-+	0x7024, 0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071,
-+	0xb723, 0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4,
-+	0x0120, 0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011,
-+	0x080c, 0x3667, 0x2011, 0x0001, 0x080c, 0x3667, 0x00ee, 0x00fe,
-+	0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xb723,
-+	0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904, 0x3664, 0x7803, 0x0002,
-+	0xa026, 0xd19c, 0x1904, 0x3660, 0x7000, 0x0002, 0x3664, 0x3622,
-+	0x3646, 0x3660, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002,
-+	0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000,
-+	0x7820, 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201,
-+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x358e, 0x2009, 0x0001, 0x7808,
-+	0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002,
-+	0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001,
-+	0x00b1, 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120,
-+	0x6000, 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870,
-+	0x7803, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024,
-+	0xa005, 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804,
-+	0x7832, 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840,
-+	0x2804, 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018,
-+	0xa802, 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004,
-+	0x601a, 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6,
-+	0x00e6, 0x00c6, 0x2071, 0xb74a, 0x2079, 0x0020, 0x7904, 0xd1fc,
-+	0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x36b7,
-+	0x36a2, 0x36ae, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001,
-+	0x080c, 0x3667, 0x0160, 0x080c, 0x3667, 0x0048, 0x8001, 0x7002,
-+	0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3667, 0x00ce,
-+	0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200,
-+	0x2001, 0xb6c0, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0xb6bf,
-+	0x2004, 0x60ce, 0x6004, 0xc0ac, 0xa085, 0x0200, 0x6006, 0x2001,
-+	0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, 0x2001, 0x0076, 0x2024,
-+	0x2001, 0x0077, 0x201c, 0x080c, 0x3e33, 0x6833, 0x000d, 0x6f26,
-+	0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007,
-+	0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, 0x04b1, 0x1d90,
-+	0x2d00, 0x681a, 0x0088, 0x080c, 0x3e33, 0x6833, 0x000d, 0x2070,
-+	0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, 0x0076, 0x2004, 0x2072,
-+	0x2001, 0x0077, 0x2004, 0x7006, 0x2061, 0x0020, 0x2079, 0x0100,
-+	0x2001, 0xb6bf, 0x2004, 0x6012, 0x20e1, 0x9040, 0x2001, 0x0072,
-+	0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, 0x0073,
-+	0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, 0x603a,
-+	0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0010,
-+	0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, 0xa006,
-+	0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, 0x7003,
-+	0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, 0x0040,
-+	0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, 0x2d60,
-+	0x00c6, 0x080c, 0x3e33, 0x00ce, 0x6018, 0x2070, 0x2d00, 0x7006,
-+	0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6,
-+	0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, 0x0078,
-+	0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3e33, 0x2d60, 0x6833,
-+	0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138,
-+	0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d,
-+	0x080c, 0x3725, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c, 0x3e33,
-+	0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, 0x601a,
-+	0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, 0x7006,
-+	0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, 0x0073,
-+	0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
-+	0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, 0x0000,
-+	0x2001, 0xb723, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009,
-+	0x00ee, 0x0005, 0x0804, 0x2f6e, 0x0126, 0x2091, 0x8000, 0x20a9,
-+	0x0012, 0x2001, 0xb440, 0x20a0, 0xa006, 0x40a4, 0x012e, 0x0804,
-+	0x2f6e, 0x7d38, 0x7c3c, 0x0804, 0x3015, 0x080c, 0x3e33, 0x0904,
-+	0x2f93, 0x080c, 0x5a90, 0x0110, 0x080c, 0x4baa, 0x2009, 0x001c,
-+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3e74, 0x701b, 0x37d9,
-+	0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2f96, 0x6804,
-+	0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2f96, 0xd094, 0x00c6, 0x2061,
-+	0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, 0xa18c,
-+	0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6,
-+	0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c,
-+	0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002,
-+	0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x2f96,
-+	0xa288, 0x2d88, 0x210d, 0xa18c, 0x00ff, 0x615a, 0xd0dc, 0x0130,
-+	0x6828, 0xa08a, 0x007f, 0x1a04, 0x2f96, 0x6052, 0x6808, 0xa08a,
-+	0x0100, 0x0a04, 0x2f96, 0xa08a, 0x0841, 0x1a04, 0x2f96, 0xa084,
-+	0x0007, 0x1904, 0x2f96, 0x680c, 0xa005, 0x0904, 0x2f96, 0x6810,
-+	0xa005, 0x0904, 0x2f96, 0x6848, 0x6940, 0xa10a, 0x1a04, 0x2f96,
-+	0x8001, 0x0904, 0x2f96, 0x684c, 0x6944, 0xa10a, 0x1a04, 0x2f96,
-+	0x8001, 0x0904, 0x2f96, 0x6804, 0xd0fc, 0x0560, 0x080c, 0x3e33,
-+	0x0904, 0x2f93, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-+	0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3e74, 0x701b, 0x3859,
-+	0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xb46e,
-+	0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xb472, 0x200c,
-+	0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00,
-+	0x6006, 0x00ce, 0x2009, 0xb6b1, 0x200b, 0x0000, 0x2001, 0xb474,
-+	0x2004, 0xd0ac, 0x0158, 0x7824, 0x200a, 0x2009, 0x017f, 0x200a,
-+	0x3200, 0xa084, 0x003f, 0xa085, 0x3020, 0x2090, 0x20a9, 0x001c,
-+	0x2d98, 0x2069, 0xb452, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff,
-+	0x6142, 0x8007, 0xa084, 0x00ff, 0x6046, 0x080c, 0x5d66, 0x080c,
-+	0x532d, 0x080c, 0x5396, 0x6000, 0xa086, 0x0000, 0x1904, 0x3954,
-+	0x6808, 0x602a, 0x080c, 0x2439, 0x0006, 0x2001, 0x0100, 0x2004,
-+	0xa082, 0x0005, 0x000e, 0x0268, 0x2009, 0x0170, 0x200b, 0x0080,
-+	0xe000, 0xe000, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2868,
-+	0x003e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
-+	0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148,
-+	0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
-+	0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007,
-+	0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0xb6c6, 0x40a1,
-+	0x080c, 0x6a2d, 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000,
-+	0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0,
-+	0x3508, 0x8109, 0x080c, 0x631d, 0x6878, 0x6016, 0x6874, 0x2008,
-+	0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108,
-+	0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x38ee,
-+	0x00ce, 0x2069, 0xb452, 0x2001, 0xb69e, 0x6a80, 0xa294, 0x0030,
-+	0xa28e, 0x0000, 0x0170, 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020,
-+	0x0140, 0x2003, 0xaaaa, 0x080c, 0x28b1, 0x2001, 0xb68f, 0x2102,
-+	0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f,
-+	0x0000, 0x00ce, 0x080c, 0x5a90, 0x0128, 0x080c, 0x408d, 0x0110,
-+	0x080c, 0x282d, 0x60c8, 0xa005, 0x01d0, 0x6003, 0x0001, 0x2009,
-+	0x393a, 0x00e0, 0x080c, 0x5a90, 0x1178, 0x2011, 0x5963, 0x080c,
-+	0x6961, 0x2011, 0x5956, 0x080c, 0x6a21, 0x2001, 0xb69f, 0x2003,
-+	0x0000, 0x080c, 0x59c8, 0x0040, 0x080c, 0x4ad9, 0x0028, 0x6003,
-+	0x0004, 0x2009, 0x3954, 0x0010, 0x0804, 0x2f6e, 0x2001, 0x0100,
-+	0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004, 0xa084,
-+	0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817, 0x2091,
-+	0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2f93, 0x2069,
-+	0xb452, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc, 0x0118,
-+	0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28,
-+	0x7c3c, 0x7d38, 0x0804, 0x3e77, 0xa006, 0x080c, 0x282d, 0x81ff,
-+	0x1904, 0x2f93, 0x080c, 0x5a90, 0x1178, 0x2001, 0xb69f, 0x2003,
-+	0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c,
-+	0x5ad4, 0x080c, 0x59c8, 0x0020, 0x080c, 0x4baa, 0x080c, 0x4ad9,
-+	0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93, 0x080c, 0x5a90, 0x1110,
-+	0x0804, 0x2f93, 0x6188, 0x81ff, 0x0198, 0x703f, 0x0000, 0x2001,
-+	0xbbc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x3e77, 0x701b, 0x2f6c, 0x012e, 0x0005,
-+	0x703f, 0x0001, 0x00d6, 0x2069, 0xbbc0, 0x20a9, 0x0040, 0x20a1,
-+	0xbbc0, 0x2019, 0xffff, 0x43a4, 0x6550, 0xa588, 0x2d88, 0x210d,
-+	0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506,
-+	0x01a8, 0x080c, 0x4f6a, 0x1190, 0x6014, 0x821c, 0x0238, 0xa398,
-+	0xbbc0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398, 0xbbc0,
-+	0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182,
-+	0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a,
-+	0x00de, 0x20a9, 0x0040, 0x20a1, 0xbbc0, 0x2099, 0xbbc0, 0x080c,
-+	0x4b49, 0x0804, 0x39af, 0x080c, 0x3e58, 0x0904, 0x2f96, 0x00c6,
-+	0x080c, 0x3e33, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x2f93,
-+	0x2001, 0xb453, 0x2004, 0xd0b4, 0x0550, 0x7824, 0xa084, 0xff00,
-+	0xa08e, 0x7e00, 0x0520, 0xa08e, 0x7f00, 0x0508, 0xa08e, 0x8000,
-+	0x01f0, 0x6000, 0xd08c, 0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x11a8, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
-+	0x9d6b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2f93, 0x7007, 0x0003,
-+	0x701b, 0x3a3b, 0x0005, 0x080c, 0x3e58, 0x0904, 0x2f96, 0x20a9,
-+	0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004,
-+	0xac80, 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x080c, 0x4b49,
-+	0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0,
-+	0x080c, 0x4b49, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c,
-+	0x7d38, 0x0804, 0x3e77, 0x81ff, 0x1904, 0x2f93, 0x080c, 0x3e48,
-+	0x0904, 0x2f96, 0x080c, 0x5147, 0x0804, 0x2f6e, 0x81ff, 0x1904,
-+	0x2f93, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2f96, 0x080c, 0x3e58,
-+	0x0904, 0x2f96, 0x080c, 0x51aa, 0x0904, 0x2f93, 0x2019, 0x0004,
-+	0xa00e, 0x080c, 0x5159, 0x7924, 0x810f, 0x7a28, 0x0011, 0x0804,
-+	0x2f6e, 0xa186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e,
-+	0x2061, 0xb400, 0x6450, 0x2400, 0xa506, 0x0110, 0x2508, 0x0019,
-+	0x8529, 0x1ec8, 0x0005, 0x080c, 0x4f6a, 0x1138, 0x2200, 0x8003,
-+	0x800b, 0x810b, 0xa108, 0x080c, 0x696d, 0x0005, 0x81ff, 0x1904,
-+	0x2f93, 0x080c, 0x3e48, 0x0904, 0x2f96, 0x080c, 0x5030, 0x0904,
-+	0x2f93, 0x080c, 0x5150, 0x0804, 0x2f6e, 0x81ff, 0x1904, 0x2f93,
-+	0x080c, 0x3e48, 0x0904, 0x2f96, 0x080c, 0x5030, 0x0904, 0x2f93,
-+	0x080c, 0x513e, 0x0804, 0x2f6e, 0x6100, 0x0804, 0x2f6e, 0x080c,
-+	0x3e58, 0x0904, 0x2f96, 0x2001, 0xb400, 0x2004, 0xa086, 0x0003,
-+	0x1904, 0x2f93, 0x00d6, 0xace8, 0x000a, 0x7924, 0xd184, 0x0110,
-+	0xace8, 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a,
-+	0x6b04, 0x831f, 0x6a00, 0x8217, 0x00de, 0x6100, 0xa18c, 0x0200,
-+	0x0804, 0x2f6e, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x1a04,
-+	0x2f93, 0x6250, 0xa294, 0x00ff, 0xa084, 0xff00, 0x8007, 0xa206,
-+	0x1150, 0x2001, 0xb440, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c,
-+	0x7d38, 0x0804, 0x3e77, 0x81ff, 0x1904, 0x2f93, 0x080c, 0x3e58,
-+	0x0904, 0x2f96, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1904,
-+	0x2f93, 0x00c6, 0x080c, 0x3e33, 0x00ce, 0x0904, 0x2f93, 0x6837,
-+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9d17, 0x0904, 0x2f93,
-+	0x7007, 0x0003, 0x701b, 0x3b25, 0x0005, 0x6830, 0xa086, 0x0100,
-+	0x0904, 0x2f93, 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28,
-+	0x7c3c, 0x7d38, 0x0804, 0x3e77, 0xa006, 0x080c, 0x282d, 0x7824,
-+	0xa084, 0x00ff, 0xa086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x2f93,
-+	0x080c, 0x5a90, 0x0110, 0x080c, 0x4baa, 0x7828, 0xa08a, 0x1000,
-+	0x1a04, 0x2f96, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff,
-+	0x0138, 0xa182, 0x007f, 0x1a04, 0x2f96, 0x2100, 0x080c, 0x27f7,
-+	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0xb6f3, 0x601b,
-+	0x0000, 0x601f, 0x0000, 0x080c, 0x5a90, 0x1178, 0x2001, 0xb69f,
-+	0x2003, 0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0xa085, 0x0001,
-+	0x080c, 0x5ad4, 0x080c, 0x59c8, 0x0420, 0x2011, 0x0003, 0x080c,
-+	0x801f, 0x2011, 0x0002, 0x080c, 0x8029, 0x080c, 0x7f03, 0x0036,
-+	0x2019, 0x0000, 0x080c, 0x7f8e, 0x003e, 0x2061, 0x0100, 0x2001,
-+	0xb415, 0x2004, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4b0e, 0x080c,
-+	0x69e7, 0x7924, 0xa18c, 0xff00, 0x810f, 0x080c, 0x5a90, 0x1110,
-+	0x2009, 0x00ff, 0x7a28, 0x080c, 0x3a89, 0x012e, 0x00ce, 0x002e,
-+	0x0804, 0x2f6e, 0x7924, 0xa18c, 0xff00, 0x810f, 0x00c6, 0x080c,
-+	0x4f0e, 0x2c08, 0x00ce, 0x1904, 0x2f96, 0x0804, 0x2f6e, 0x81ff,
-+	0x0120, 0x2009, 0x0001, 0x0804, 0x2f93, 0x60d4, 0xd0ac, 0x1130,
-+	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x2f93, 0x080c, 0x3e33,
-+	0x1120, 0x2009, 0x0002, 0x0804, 0x2f93, 0x7924, 0x7a2c, 0x7b28,
-+	0x7c3c, 0x7d38, 0x080c, 0x3e74, 0x701b, 0x3bd7, 0x0005, 0x2009,
-+	0x0080, 0x080c, 0x4f6a, 0x1130, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x0120, 0x2021, 0x400a, 0x0804, 0x2f70, 0x00d6, 0xade8,
-+	0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820,
-+	0xa0be, 0x0100, 0x0904, 0x3c4e, 0xa0be, 0x0112, 0x0904, 0x3c4e,
-+	0xa0be, 0x0113, 0x0904, 0x3c4e, 0xa0be, 0x0114, 0x0904, 0x3c4e,
-+	0xa0be, 0x0117, 0x0904, 0x3c4e, 0xa0be, 0x011a, 0x0904, 0x3c4e,
-+	0xa0be, 0x011c, 0x0904, 0x3c4e, 0xa0be, 0x0121, 0x05b0, 0xa0be,
-+	0x0131, 0x0598, 0xa0be, 0x0171, 0x05c8, 0xa0be, 0x0173, 0x05b0,
-+	0xa0be, 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832, 0x04a8, 0xa0be,
-+	0x0212, 0x0540, 0xa0be, 0x0213, 0x0528, 0xa0be, 0x0214, 0x01b0,
-+	0xa0be, 0x0217, 0x0168, 0xa0be, 0x021a, 0x1120, 0x6838, 0x8007,
-+	0x683a, 0x00e0, 0xa0be, 0x0300, 0x01c8, 0x00de, 0x0804, 0x2f96,
-+	0xad80, 0x0010, 0x20a9, 0x0007, 0x080c, 0x3c94, 0xad80, 0x000e,
-+	0x20a9, 0x0001, 0x080c, 0x3c94, 0x0048, 0xad80, 0x000c, 0x080c,
-+	0x3ca2, 0x0050, 0xad80, 0x000e, 0x080c, 0x3ca2, 0xad80, 0x000c,
-+	0x20a9, 0x0001, 0x080c, 0x3c94, 0x00c6, 0x080c, 0x3e33, 0x0568,
-+	0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, 0x0000, 0x684f,
-+	0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86,
-+	0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, 0x00ce, 0x00de,
-+	0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804,
-+	0x2068, 0x080c, 0x9d33, 0x1120, 0x2009, 0x0003, 0x0804, 0x2f93,
-+	0x7007, 0x0003, 0x701b, 0x3c8b, 0x0005, 0x00ce, 0x00de, 0x2009,
-+	0x0002, 0x0804, 0x2f93, 0x6820, 0xa086, 0x8001, 0x1904, 0x2f6e,
-+	0x2009, 0x0004, 0x0804, 0x2f93, 0x0016, 0x2008, 0x2044, 0x8000,
-+	0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, 0x1f04, 0x3c96,
-+	0x001e, 0x0005, 0x0016, 0x00a6, 0x00b6, 0x2008, 0x2044, 0x8000,
-+	0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a,
-+	0x8108, 0x290a, 0x8108, 0x280a, 0x00be, 0x00ae, 0x001e, 0x0005,
-+	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2f93, 0x60d4, 0xd0ac,
-+	0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x2f93, 0x7924,
-+	0x2140, 0xa18c, 0xff00, 0x810f, 0x60d4, 0xd0ac, 0x1120, 0xa182,
-+	0x0080, 0x0a04, 0x2f96, 0xa182, 0x00ff, 0x1a04, 0x2f96, 0x7a2c,
-+	0x7b28, 0x6070, 0xa306, 0x1140, 0x6074, 0xa24e, 0x0904, 0x2f96,
-+	0xa9cc, 0xff00, 0x0904, 0x2f96, 0x00c6, 0x080c, 0x3d81, 0x2c68,
-+	0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180, 0x00c6, 0x0006, 0x2d60,
-+	0x2009, 0x0000, 0x080c, 0x520b, 0x1108, 0xc185, 0x6000, 0xd0bc,
-+	0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088, 0xa0c6, 0x4007, 0x1110,
-+	0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0030,
-+	0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001, 0x4006, 0x2020, 0x0804,
-+	0x2f70, 0x2d00, 0x7022, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70,
-+	0x080c, 0x856a, 0x05d8, 0x2d00, 0x601a, 0x080c, 0x9fb8, 0x2e58,
-+	0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3e33, 0x00ce, 0x2b70, 0x1150,
-+	0x080c, 0x85c0, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x2009, 0x0002,
-+	0x0804, 0x2f93, 0x6837, 0x0000, 0x683b, 0x0000, 0x2d00, 0x6012,
-+	0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0x683a,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x2c60, 0x012e, 0x601f, 0x0001,
-+	0x2001, 0x0000, 0x080c, 0x4eac, 0x2001, 0x0002, 0x080c, 0x4ebe,
-+	0x2009, 0x0002, 0x080c, 0x85ef, 0xa085, 0x0001, 0x00ee, 0x00ce,
-+	0x00be, 0x001e, 0x1120, 0x2009, 0x0003, 0x0804, 0x2f93, 0x7007,
-+	0x0003, 0x701b, 0x3d64, 0x0005, 0x6830, 0xa086, 0x0100, 0x7020,
-+	0x2060, 0x1138, 0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0804,
-+	0x2f93, 0x2009, 0x0000, 0x6838, 0xd0f4, 0x1904, 0x2f6e, 0x080c,
-+	0x520b, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804,
-+	0x2f6e, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xb435, 0x2004,
-+	0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xb535,
-+	0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xb5b5, 0x2e04,
-+	0xa005, 0x1130, 0x2100, 0xa406, 0x1570, 0x2428, 0xc5fd, 0x0458,
-+	0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206,
-+	0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0568, 0x6004,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1538, 0x2001, 0x4000, 0x0428,
-+	0x2001, 0x4007, 0x0410, 0x2400, 0xa106, 0x1168, 0x6e14, 0x87ff,
-+	0x1138, 0x86ff, 0x09d0, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x19a8,
-+	0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x3d97, 0x85ff,
-+	0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c,
-+	0x4f0e, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005, 0x00de, 0x00ee,
-+	0x0005, 0x81ff, 0x1904, 0x2f93, 0x080c, 0x3e33, 0x0904, 0x2f93,
-+	0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0904,
-+	0x2f96, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004, 0x1a04, 0x2f96,
-+	0x2010, 0x2d18, 0x080c, 0x2c13, 0x0904, 0x2f93, 0x7007, 0x0003,
-+	0x701b, 0x3e03, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2f93,
-+	0x0804, 0x2f6e, 0x7924, 0xa18c, 0xff00, 0x810f, 0x60d4, 0xd0ac,
-+	0x1120, 0xa182, 0x0080, 0x0a04, 0x2f96, 0xa182, 0x00ff, 0x1a04,
-+	0x2f96, 0x0126, 0x2091, 0x8000, 0x080c, 0x9c1b, 0x1188, 0xa190,
-+	0xb535, 0x2204, 0xa065, 0x0160, 0x080c, 0x4bc5, 0x2001, 0xb435,
-+	0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e, 0x0804, 0x2f6e,
-+	0x012e, 0x0804, 0x2f93, 0x080c, 0x15f4, 0x0188, 0xa006, 0x6802,
-+	0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014,
-+	0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x0005,
-+	0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4f6a, 0x1130, 0x7e28,
-+	0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005,
-+	0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4f6a, 0x1128, 0xa6b4,
-+	0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x0016,
-+	0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c, 0x160b, 0x0cc8,
-+	0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031,
-+	0x0000, 0x2061, 0xb4d2, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a,
-+	0x642e, 0x6532, 0x2c10, 0x080c, 0x163f, 0x7007, 0x0002, 0x701b,
-+	0x2f6e, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000,
-+	0x2001, 0xb490, 0x2004, 0xa005, 0x1168, 0x0e04, 0x3ea2, 0x7818,
-+	0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001, 0x2091,
-+	0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071, 0xb482, 0x7138,
-+	0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078, 0x7030, 0xa0e0,
-+	0x0004, 0xac82, 0xb4d2, 0x0210, 0x2061, 0xb492, 0x2c00, 0x7032,
-+	0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a,
-+	0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005, 0x00e6, 0x2071,
-+	0xb482, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091, 0x8000, 0x0e04,
-+	0x3ef9, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084, 0x1508, 0x00c6,
-+	0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a,
-+	0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
-+	0x1130, 0x7033, 0xb492, 0x7037, 0xb492, 0x00ce, 0x0048, 0xac80,
-+	0x0004, 0xa0fa, 0xb4d2, 0x0210, 0x2001, 0xb492, 0x7036, 0x00ce,
-+	0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001, 0xb453, 0x2004,
-+	0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3e8a, 0x002e, 0x0005,
-+	0x81ff, 0x1904, 0x2f93, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
-+	0xc085, 0xc0ac, 0x6032, 0x080c, 0x5a90, 0x1178, 0x2001, 0xb69f,
-+	0x2003, 0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0xa085, 0x0001,
-+	0x080c, 0x5ad4, 0x080c, 0x59c8, 0x0010, 0x080c, 0x4ad9, 0x012e,
-+	0x0804, 0x2f6e, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, 0x61e0,
-+	0xa10d, 0x61e2, 0x0804, 0x2f6e, 0x0804, 0x2f96, 0x81ff, 0x1904,
-+	0x2f93, 0x6000, 0xa086, 0x0003, 0x1904, 0x2f93, 0x2001, 0xb453,
-+	0x2004, 0xd0ac, 0x1904, 0x2f93, 0x080c, 0x3e58, 0x0904, 0x2f96,
-+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, 0xa005,
-+	0x0904, 0x2f6e, 0x00c6, 0x080c, 0x3e33, 0x00ce, 0x0904, 0x2f93,
-+	0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
-+	0x9dfc, 0x0904, 0x2f93, 0x7007, 0x0003, 0x701b, 0x3f68, 0x0005,
-+	0x6830, 0xa086, 0x0100, 0x0904, 0x2f93, 0x0804, 0x2f6e, 0x2001,
-+	0xb400, 0x2004, 0xa086, 0x0003, 0x1904, 0x2f93, 0x7f24, 0x7a2c,
-+	0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3e33, 0x0904, 0x2f93, 0x2009,
-+	0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
-+	0x0005, 0x7026, 0x20a0, 0x080c, 0x4f6a, 0x1904, 0x3fe2, 0x6004,
-+	0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4, 0xff00, 0xa8c6,
-+	0x0600, 0x1904, 0x3fe2, 0x2001, 0xb453, 0x2004, 0xd0ac, 0x1128,
-+	0x080c, 0x520b, 0x1110, 0xd79c, 0x05e8, 0xd794, 0x1110, 0xd784,
-+	0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3,
-+	0x080c, 0x3ca2, 0xd794, 0x0148, 0xac80, 0x000a, 0x2098, 0x3400,
-+	0x20a9, 0x0004, 0x53a3, 0x080c, 0x3ca2, 0x21a2, 0xd794, 0x01d8,
-+	0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, 0x53a3, 0xac80,
-+	0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, 0x3400, 0x20a9,
-+	0x0002, 0x53a3, 0x080c, 0x3c94, 0xac80, 0x0026, 0x2098, 0x20a9,
-+	0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110, 0xa6b0, 0x000b,
-+	0xa6b0, 0x0005, 0x8108, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x0118,
-+	0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, 0x0170,
-+	0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118, 0xa686, 0x0020,
-+	0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3f8b, 0x86ff, 0x1120,
-+	0x7120, 0x810b, 0x0804, 0x2f6e, 0x702f, 0x0001, 0x711e, 0x7020,
-+	0xa600, 0x7022, 0x772a, 0x2061, 0xb4d2, 0x6007, 0x0000, 0x6612,
-+	0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c,
-+	0x163f, 0x7007, 0x0002, 0x701b, 0x401e, 0x0005, 0x702c, 0xa005,
-+	0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061,
-+	0xb4d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, 0x3f8b, 0x7120,
-+	0x810b, 0x0804, 0x2f6e, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c,
-+	0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2f96,
-+	0xa502, 0x0a04, 0x2f96, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
-+	0x2f96, 0xa502, 0x0a04, 0x2f96, 0xa284, 0xff00, 0x8007, 0xa0e2,
-+	0x0020, 0x0a04, 0x2f96, 0xa502, 0x0a04, 0x2f96, 0xa284, 0x00ff,
-+	0xa0e2, 0x0020, 0x0a04, 0x2f96, 0xa502, 0x0a04, 0x2f96, 0xa384,
-+	0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2f96, 0xa502, 0x0a04,
-+	0x2f96, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2f96, 0xa502,
-+	0x0a04, 0x2f96, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04,
-+	0x2f96, 0xa502, 0x0a04, 0x2f96, 0xa484, 0x00ff, 0xa0e2, 0x0020,
-+	0x0a04, 0x2f96, 0xa502, 0x0a04, 0x2f96, 0x2061, 0xb6b9, 0x6102,
-+	0x6206, 0x630a, 0x640e, 0x0804, 0x2f6e, 0x0006, 0x2001, 0xb453,
-+	0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, 0xb472, 0x2004,
-+	0xd0bc, 0x000e, 0x0005, 0x6168, 0x7a24, 0x6300, 0x82ff, 0x1118,
-+	0x7926, 0x0804, 0x2f6e, 0x83ff, 0x1904, 0x2f96, 0x2001, 0xfff0,
-+	0xa200, 0x1a04, 0x2f96, 0x2019, 0xffff, 0x606c, 0xa302, 0xa200,
-+	0x0a04, 0x2f96, 0x7926, 0x626a, 0x0804, 0x2f6e, 0x2001, 0xb400,
-+	0x2004, 0xa086, 0x0003, 0x1904, 0x2f93, 0x7c28, 0x7d24, 0x7e38,
-+	0x7f2c, 0x080c, 0x3e33, 0x0904, 0x2f93, 0x2009, 0x0000, 0x2019,
-+	0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026,
-+	0x20a0, 0xa1e0, 0xb535, 0x2c64, 0x8cff, 0x01b8, 0x6004, 0xa084,
-+	0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084, 0xff00, 0xa086,
-+	0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105,
-+	0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff,
-+	0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff, 0x1120, 0x7120,
-+	0x810c, 0x0804, 0x2f6e, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300,
-+	0x7022, 0x2061, 0xb4d2, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e,
-+	0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c, 0x163f, 0x7007,
-+	0x0002, 0x701b, 0x4114, 0x0005, 0x702c, 0xa005, 0x1168, 0x711c,
-+	0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xb4d2, 0x6424, 0x6528,
-+	0x662c, 0x6730, 0x0804, 0x40d1, 0x7120, 0x810c, 0x0804, 0x2f6e,
-+	0x81ff, 0x1904, 0x2f93, 0x60d4, 0xd0ac, 0x1118, 0xd09c, 0x0904,
-+	0x2f93, 0x080c, 0x3e33, 0x0904, 0x2f93, 0x7924, 0x7a2c, 0x7b28,
-+	0x7c3c, 0x7d38, 0x080c, 0x3e74, 0x701b, 0x413f, 0x0005, 0x00d6,
-+	0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, 0xa0be, 0x7100,
-+	0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, 0x2f96, 0x6820,
-+	0x6924, 0x080c, 0x27e3, 0x1510, 0x080c, 0x4f0e, 0x11f8, 0x7122,
-+	0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3e33, 0x01b8, 0x080c,
-+	0x3e33, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd,
-+	0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x9d4f, 0x0904,
-+	0x2f93, 0x7007, 0x0003, 0x701b, 0x4179, 0x0005, 0x00de, 0x0804,
-+	0x2f93, 0x7120, 0x080c, 0x2d5b, 0x6820, 0xa086, 0x8001, 0x0904,
-+	0x2f93, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x0006, 0x20a9,
-+	0x002a, 0x2098, 0x20a0, 0x080c, 0x4b49, 0x000e, 0xade8, 0x000d,
-+	0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xb4d2, 0x6007, 0x0000,
-+	0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6, 0x7100,
-+	0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2f96, 0x2009, 0x0004, 0x0804,
-+	0x3e77, 0xa7c6, 0x7200, 0x1904, 0x2f96, 0xa6c2, 0x0054, 0x0a04,
-+	0x2f96, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532,
-+	0x2c10, 0x080c, 0x163f, 0x7007, 0x0002, 0x701b, 0x41c0, 0x0005,
-+	0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002,
-+	0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4b49, 0x000e,
-+	0x2009, 0x002a, 0x2061, 0xb4d2, 0x6224, 0x6328, 0x642c, 0x6530,
-+	0x0804, 0x3e77, 0x81ff, 0x1904, 0x2f93, 0x792c, 0x2001, 0xb6a0,
-+	0x2102, 0x080c, 0x3e48, 0x0904, 0x2f96, 0x080c, 0x5030, 0x0904,
-+	0x2f93, 0x0126, 0x2091, 0x8000, 0x080c, 0x5162, 0x012e, 0x0804,
-+	0x2f6e, 0x7824, 0xd08c, 0x1118, 0xd084, 0x0904, 0x3a03, 0x080c,
-+	0x3e58, 0x0904, 0x2f96, 0x00c6, 0x080c, 0x3e33, 0x00ce, 0x1120,
-+	0x2009, 0x0002, 0x0804, 0x2f93, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x15b8,
-+	0x7824, 0xd08c, 0x0120, 0x6000, 0xc08c, 0x6002, 0x0030, 0x2001,
-+	0xb453, 0x2004, 0xd0b4, 0x0904, 0x3a3f, 0x7824, 0xa084, 0xff00,
-+	0xa08e, 0x7e00, 0x0904, 0x3a3f, 0xa08e, 0x7f00, 0x0904, 0x3a3f,
-+	0xa08e, 0x8000, 0x0904, 0x3a3f, 0x6000, 0xd08c, 0x1904, 0x3a3f,
-+	0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9d6b, 0x1120,
-+	0x2009, 0x0003, 0x0804, 0x2f93, 0x7007, 0x0003, 0x701b, 0x4241,
-+	0x0005, 0x080c, 0x3e58, 0x0904, 0x2f96, 0x0804, 0x3a3f, 0x2009,
-+	0xb431, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2f93,
-+	0x2001, 0xb400, 0x2004, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007,
-+	0x0804, 0x2f93, 0x2001, 0xb453, 0x2004, 0xd0ac, 0x0120, 0x2009,
-+	0x0008, 0x0804, 0x2f93, 0x609c, 0xd0a4, 0x1118, 0xd0ac, 0x1904,
-+	0x3a3f, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
-+	0x080c, 0x9dfc, 0x1120, 0x2009, 0x0003, 0x0804, 0x2f93, 0x7007,
-+	0x0003, 0x701b, 0x427c, 0x0005, 0x6830, 0xa086, 0x0100, 0x1120,
-+	0x2009, 0x0004, 0x0804, 0x2f93, 0x080c, 0x3e58, 0x0904, 0x2f96,
-+	0x0804, 0x4210, 0x81ff, 0x2009, 0x0001, 0x1904, 0x2f93, 0x6000,
-+	0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2f93, 0x2001, 0xb453,
-+	0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2f93, 0x080c, 0x3e58,
-+	0x0904, 0x2f96, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009,
-+	0x0009, 0x1904, 0x2f93, 0x00c6, 0x080c, 0x3e33, 0x00ce, 0x2009,
-+	0x0002, 0x0904, 0x2f93, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
-+	0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c, 0x00ff, 0xa006,
-+	0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956, 0x0048, 0xa28e,
-+	0x0100, 0x1904, 0x2f96, 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000,
-+	0x683e, 0x080c, 0x9fb9, 0x2009, 0x0003, 0x0904, 0x2f93, 0x7007,
-+	0x0003, 0x701b, 0x42dc, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009,
-+	0x0004, 0x0904, 0x2f93, 0x0804, 0x2f6e, 0x81ff, 0x2009, 0x0001,
-+	0x1904, 0x2f93, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904,
-+	0x2f93, 0x080c, 0x3e58, 0x0904, 0x2f96, 0x6004, 0xa084, 0x00ff,
-+	0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2f93, 0x00c6, 0x080c,
-+	0x3e33, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2f93, 0xad80, 0x000f,
-+	0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3e74,
-+	0x701b, 0x4313, 0x0005, 0x00d6, 0xade8, 0x000f, 0x6800, 0xa086,
-+	0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808, 0xa084, 0xff00,
-+	0x1108, 0x0018, 0x00de, 0x1904, 0x2f96, 0x00de, 0x6837, 0x0000,
-+	0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6, 0x080c, 0x3e58,
-+	0x1118, 0x00ce, 0x0804, 0x2f96, 0x080c, 0xa008, 0x2009, 0x0003,
-+	0x00ce, 0x0904, 0x2f93, 0x7007, 0x0003, 0x701b, 0x4340, 0x0005,
-+	0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, 0x2f93, 0x0804,
-+	0x2f6e, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2f93, 0x6000,
-+	0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804, 0x2f93, 0x7e24,
-+	0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c, 0x4f6a, 0x1904,
-+	0x2f96, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084, 0x00ff, 0xa086,
-+	0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2f93, 0x00c6, 0x080c,
-+	0x3e33, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x2f93, 0x6837,
-+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x2001, 0x0100, 0x8007, 0x680a,
-+	0x080c, 0x9d86, 0x1120, 0x2009, 0x0003, 0x0804, 0x2f93, 0x7007,
-+	0x0003, 0x701b, 0x438c, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100,
-+	0x1120, 0x2009, 0x0004, 0x0804, 0x2f93, 0x68b0, 0x6836, 0x6810,
-+	0x8007, 0xa084, 0x00ff, 0x800c, 0x6814, 0x8007, 0xa084, 0x00ff,
-+	0x8004, 0xa080, 0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28,
-+	0x7c3c, 0x7d38, 0x0804, 0x3e77, 0x080c, 0x3e33, 0x1120, 0x2009,
-+	0x0002, 0x0804, 0x2f93, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff,
-+	0x8217, 0x82ff, 0x0110, 0x0804, 0x2f96, 0x2009, 0x001a, 0x7a2c,
-+	0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3e74, 0x701b, 0x43c8, 0x0005,
-+	0xad80, 0x000d, 0x2098, 0x20a9, 0x001a, 0x20a1, 0xb6c6, 0x53a3,
-+	0x0804, 0x2f6e, 0x080c, 0x3e33, 0x1120, 0x2009, 0x0002, 0x0804,
-+	0x2f93, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff,
-+	0x0110, 0x0804, 0x2f96, 0x2099, 0xb6c6, 0x20a0, 0x20a9, 0x001a,
-+	0x53a3, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804,
-+	0x3e77, 0x7824, 0xa08a, 0x1000, 0x1a04, 0x2f96, 0x0126, 0x2091,
-+	0x8000, 0x8003, 0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xb6f3,
-+	0x6142, 0x00ce, 0x012e, 0x0804, 0x2f6e, 0x00c6, 0x080c, 0x5a90,
-+	0x1188, 0x2001, 0xb69f, 0x2003, 0x0001, 0x2001, 0xb400, 0x2003,
-+	0x0001, 0xa085, 0x0001, 0x080c, 0x5ad4, 0x080c, 0x59c8, 0x080c,
-+	0x1511, 0x0038, 0x2061, 0xb400, 0x6030, 0xc09d, 0x6032, 0x080c,
-+	0x4ad9, 0x00ce, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061,
-+	0xb6f3, 0x7924, 0x6152, 0x614e, 0x6057, 0x0000, 0x604b, 0x0009,
-+	0x7838, 0x606a, 0x783c, 0x6066, 0x7828, 0x6062, 0x782c, 0x605e,
-+	0x2061, 0xb6a1, 0x2001, 0xb708, 0x600e, 0x6013, 0x0001, 0x6017,
-+	0x0002, 0x6007, 0x0000, 0x6037, 0x0000, 0x00ce, 0x012e, 0x0804,
-+	0x2f6e, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb400,
-+	0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x45c0, 0x0068,
-+	0xd08c, 0x0118, 0x080c, 0x44e1, 0x0040, 0xd094, 0x0118, 0x080c,
-+	0x44b2, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e,
-+	0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e,
-+	0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0,
-+	0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294,
-+	0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240,
-+	0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7,
-+	0x080c, 0x4b69, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0140,
-+	0x6042, 0x6043, 0x0000, 0x707b, 0x0000, 0x7097, 0x0001, 0x70bb,
-+	0x0000, 0x70d7, 0x0000, 0x2009, 0xbbc0, 0x200b, 0x0000, 0x708b,
-+	0x0000, 0x707f, 0x000a, 0x2009, 0x000a, 0x2011, 0x4a8f, 0x080c,
-+	0x69e7, 0x0005, 0x0156, 0x2001, 0xb474, 0x2004, 0xd08c, 0x0110,
-+	0x7053, 0xffff, 0x707c, 0xa005, 0x1510, 0x2011, 0x4a8f, 0x080c,
-+	0x6961, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
-+	0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x44c9, 0x6242, 0x708f,
-+	0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
-+	0x0030, 0x6242, 0x708f, 0x0000, 0x7083, 0x0000, 0x0000, 0x015e,
-+	0x0005, 0x7080, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c,
-+	0x1511, 0x0005, 0x44ed, 0x453d, 0x45bf, 0x00f6, 0x7083, 0x0001,
-+	0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x2439, 0x20e1,
-+	0x9080, 0x20e1, 0x4000, 0x2079, 0xba00, 0x207b, 0x2200, 0x7807,
-+	0x00ef, 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817,
-+	0x0000, 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827,
-+	0xffff, 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0xba0c, 0x207b,
-+	0x1101, 0x7807, 0x0000, 0x2099, 0xb405, 0x20a1, 0xba0e, 0x20a9,
-+	0x0004, 0x53a3, 0x2079, 0xba12, 0x207b, 0x0000, 0x7807, 0x0000,
-+	0x2099, 0xba00, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3,
-+	0x000c, 0x600f, 0x0000, 0x080c, 0x4ac0, 0x00fe, 0x7087, 0x0000,
-+	0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7084, 0x7087,
-+	0x0000, 0xa025, 0x0904, 0x45a7, 0x6020, 0xd0b4, 0x1904, 0x45a5,
-+	0x7194, 0x81ff, 0x0904, 0x4595, 0xa486, 0x000c, 0x1904, 0x45a0,
-+	0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xba80, 0x2019, 0xba00,
-+	0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x4558,
-+	0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006,
-+	0x7083, 0x0002, 0x708f, 0x0002, 0x2009, 0x07d0, 0x2011, 0x4a96,
-+	0x080c, 0x69e7, 0x0490, 0x2069, 0xba80, 0x6930, 0xa18e, 0x1101,
-+	0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118,
-+	0x6804, 0xa005, 0x0190, 0x2011, 0xba8e, 0x2019, 0xb405, 0x20a9,
-+	0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318,
-+	0x1f04, 0x4589, 0x0068, 0x7097, 0x0000, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0xba80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
-+	0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040,
-+	0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c,
-+	0x2011, 0xb6ea, 0x2013, 0x0000, 0x7087, 0x0000, 0x20e1, 0x9080,
-+	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x7d1b, 0x0c30, 0x0005,
-+	0x708c, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x1511,
-+	0x0005, 0x45f3, 0x4602, 0x462a, 0x4643, 0x4667, 0x468f, 0x46b3,
-+	0x46e4, 0x4708, 0x4730, 0x4767, 0x478f, 0x47ab, 0x47c1, 0x47e1,
-+	0x47f4, 0x47fc, 0x482c, 0x4850, 0x4878, 0x489c, 0x48cd, 0x490a,
-+	0x4939, 0x4955, 0x4994, 0x49b4, 0x49cd, 0x49ce, 0x00c6, 0x2061,
-+	0xb400, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
-+	0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
-+	0x0002, 0x708f, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4a96, 0x080c,
-+	0x69e7, 0x0005, 0x00f6, 0x7084, 0xa086, 0x0014, 0x1508, 0x6043,
-+	0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xba80, 0x7a30, 0xa296,
-+	0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
-+	0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x2011, 0x4a96, 0x080c,
-+	0x6961, 0x708f, 0x0010, 0x080c, 0x47fc, 0x0010, 0x080c, 0x4ad9,
-+	0x00fe, 0x0005, 0x708f, 0x0003, 0x6043, 0x0004, 0x2011, 0x4a96,
-+	0x080c, 0x6961, 0x080c, 0x4b51, 0x20a3, 0x1102, 0x20a3, 0x0000,
-+	0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x463a, 0x60c3, 0x0014,
-+	0x080c, 0x4ac0, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011,
-+	0x4a96, 0x080c, 0x6961, 0xa086, 0x0014, 0x11a8, 0x2079, 0xba80,
-+	0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38,
-+	0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f,
-+	0x0004, 0x0029, 0x0010, 0x080c, 0x4ad9, 0x00fe, 0x0005, 0x708f,
-+	0x0005, 0x080c, 0x4b51, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
-+	0x2011, 0xba8e, 0x080c, 0x4ba2, 0x1160, 0x7078, 0xa005, 0x1148,
-+	0x7150, 0xa186, 0xffff, 0x0128, 0x080c, 0x4a5a, 0x0110, 0x080c,
-+	0x4b80, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4ac0, 0x0005, 0x00f6,
-+	0x7084, 0xa005, 0x01f0, 0x2011, 0x4a96, 0x080c, 0x6961, 0xa086,
-+	0x0014, 0x11a8, 0x2079, 0xba80, 0x7a30, 0xa296, 0x1103, 0x1178,
-+	0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005,
-+	0x1110, 0x70bb, 0x0001, 0x708f, 0x0006, 0x0029, 0x0010, 0x080c,
-+	0x4ad9, 0x00fe, 0x0005, 0x708f, 0x0007, 0x080c, 0x4b51, 0x20a3,
-+	0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xba8e, 0x080c, 0x4ba2,
-+	0x11a8, 0x7078, 0xa005, 0x1190, 0x7158, 0xa186, 0xffff, 0x0170,
-+	0xa180, 0x2d88, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4a5a,
-+	0x0128, 0x080c, 0x4094, 0x0110, 0x080c, 0x282d, 0x20a9, 0x0008,
-+	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0014, 0x080c, 0x4ac0, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0,
-+	0x2011, 0x4a96, 0x080c, 0x6961, 0xa086, 0x0014, 0x11a8, 0x2079,
-+	0xba80, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160,
-+	0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001,
-+	0x708f, 0x0008, 0x0029, 0x0010, 0x080c, 0x4ad9, 0x00fe, 0x0005,
-+	0x708f, 0x0009, 0x080c, 0x4b51, 0x20a3, 0x1105, 0x20a3, 0x0100,
-+	0x3430, 0x080c, 0x4ba2, 0x1150, 0x7078, 0xa005, 0x1138, 0x080c,
-+	0x49cf, 0x1170, 0xa085, 0x0001, 0x080c, 0x282d, 0x20a9, 0x0008,
-+	0x2099, 0xba8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x080c, 0x4ac0, 0x0010, 0x080c, 0x45e6, 0x0005,
-+	0x00f6, 0x7084, 0xa005, 0x0588, 0x2011, 0x4a96, 0x080c, 0x6961,
-+	0xa086, 0x0014, 0x1540, 0x2079, 0xba80, 0x7a30, 0xa296, 0x1105,
-+	0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc,
-+	0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x000a,
-+	0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b8,
-+	0xa005, 0x1110, 0x70bb, 0x0001, 0x708b, 0x0000, 0x708f, 0x000e,
-+	0x080c, 0x47e1, 0x0010, 0x080c, 0x4ad9, 0x00fe, 0x0005, 0x708f,
-+	0x000b, 0x2011, 0xba0e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
-+	0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x4b51,
-+	0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4ba2, 0x0118, 0x2013,
-+	0x0000, 0x0020, 0x7054, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9,
-+	0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4ac0, 0x0005, 0x00f6,
-+	0x7084, 0xa005, 0x01b0, 0x2011, 0x4a96, 0x080c, 0x6961, 0xa086,
-+	0x0084, 0x1168, 0x2079, 0xba80, 0x7a30, 0xa296, 0x1106, 0x1138,
-+	0x7834, 0xa005, 0x1120, 0x708f, 0x000c, 0x0029, 0x0010, 0x080c,
-+	0x4ad9, 0x00fe, 0x0005, 0x708f, 0x000d, 0x080c, 0x4b51, 0x20a3,
-+	0x1107, 0x20a3, 0x0000, 0x2099, 0xba8e, 0x20a9, 0x0040, 0x53a6,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4ac0,
-+	0x0005, 0x00f6, 0x7084, 0xa005, 0x01d0, 0x2011, 0x4a96, 0x080c,
-+	0x6961, 0xa086, 0x0084, 0x1188, 0x2079, 0xba80, 0x7a30, 0xa296,
-+	0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x708b, 0x0001, 0x080c,
-+	0x4b43, 0x708f, 0x000e, 0x0029, 0x0010, 0x080c, 0x4ad9, 0x00fe,
-+	0x0005, 0x708f, 0x000f, 0x7087, 0x0000, 0x608b, 0xbc85, 0x608f,
-+	0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
-+	0x4a96, 0x080c, 0x6955, 0x0005, 0x7084, 0xa005, 0x0120, 0x2011,
-+	0x4a96, 0x080c, 0x6961, 0x0005, 0x708f, 0x0011, 0x080c, 0x4ba2,
-+	0x11a0, 0x7170, 0x81ff, 0x0188, 0x2009, 0x0000, 0x7074, 0xa084,
-+	0x00ff, 0x080c, 0x27e3, 0xa186, 0x007e, 0x0138, 0xa186, 0x0080,
-+	0x0120, 0x2011, 0xba8e, 0x080c, 0x4a5a, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0xba80, 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018,
-+	0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3,
-+	0x0014, 0x080c, 0x4ac0, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0,
-+	0x2011, 0x4a96, 0x080c, 0x6961, 0xa086, 0x0014, 0x11a8, 0x2079,
-+	0xba80, 0x7a30, 0xa296, 0x1103, 0x1178, 0x7834, 0xa005, 0x1160,
-+	0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001,
-+	0x708f, 0x0012, 0x0029, 0x0010, 0x080c, 0x4ad9, 0x00fe, 0x0005,
-+	0x708f, 0x0013, 0x080c, 0x4b5d, 0x20a3, 0x1103, 0x20a3, 0x0000,
-+	0x3430, 0x2011, 0xba8e, 0x080c, 0x4ba2, 0x1160, 0x7078, 0xa005,
-+	0x1148, 0x7150, 0xa186, 0xffff, 0x0128, 0x080c, 0x4a5a, 0x0110,
-+	0x080c, 0x4b80, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4ac0, 0x0005,
-+	0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4a96, 0x080c, 0x6961,
-+	0xa086, 0x0014, 0x11a8, 0x2079, 0xba80, 0x7a30, 0xa296, 0x1104,
-+	0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8,
-+	0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0014, 0x0029, 0x0010,
-+	0x080c, 0x4ad9, 0x00fe, 0x0005, 0x708f, 0x0015, 0x080c, 0x4b5d,
-+	0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xba8e, 0x080c,
-+	0x4ba2, 0x11a8, 0x7078, 0xa005, 0x1190, 0x7158, 0xa186, 0xffff,
-+	0x0170, 0xa180, 0x2d88, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c,
-+	0x4a5a, 0x0128, 0x080c, 0x4094, 0x0110, 0x080c, 0x282d, 0x20a9,
-+	0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x080c, 0x4ac0, 0x0005, 0x00f6, 0x7084, 0xa005,
-+	0x05b8, 0x2011, 0x4a96, 0x080c, 0x6961, 0xa086, 0x0014, 0x1570,
-+	0x2079, 0xba80, 0x7a30, 0xa296, 0x1105, 0x1540, 0x7834, 0x2011,
-+	0x0100, 0xa21e, 0x1148, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005,
-+	0x1110, 0x70bb, 0x0001, 0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc,
-+	0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708b, 0x0000,
-+	0x7a38, 0xd2f4, 0x0138, 0x2001, 0xb474, 0x2004, 0xd0a4, 0x1110,
-+	0x70d7, 0x0008, 0x708f, 0x0016, 0x0029, 0x0010, 0x080c, 0x4ad9,
-+	0x00fe, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xba80,
-+	0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xba8e,
-+	0x708f, 0x0017, 0x080c, 0x4ba2, 0x1150, 0x7078, 0xa005, 0x1138,
-+	0x080c, 0x49cf, 0x1170, 0xa085, 0x0001, 0x080c, 0x282d, 0x20a9,
-+	0x0008, 0x2099, 0xba8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x60c3, 0x0014, 0x080c, 0x4ac0, 0x0010, 0x080c, 0x45e6,
-+	0x0005, 0x00f6, 0x7084, 0xa005, 0x01b0, 0x2011, 0x4a96, 0x080c,
-+	0x6961, 0xa086, 0x0084, 0x1168, 0x2079, 0xba80, 0x7a30, 0xa296,
-+	0x1106, 0x1138, 0x7834, 0xa005, 0x1120, 0x708f, 0x0018, 0x0029,
-+	0x0010, 0x080c, 0x4ad9, 0x00fe, 0x0005, 0x708f, 0x0019, 0x080c,
-+	0x4b5d, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0xba8e,
-+	0x2039, 0xba0e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x080c, 0x4ba2,
-+	0x11e8, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018,
-+	0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x7054, 0x2310, 0x8214,
-+	0xa2a0, 0xba0e, 0x2414, 0xa38c, 0x0001, 0x0118, 0xa294, 0xff00,
-+	0x0018, 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0,
-+	0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0084, 0x080c, 0x4ac0, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01d0,
-+	0x2011, 0x4a96, 0x080c, 0x6961, 0xa086, 0x0084, 0x1188, 0x2079,
-+	0xba80, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, 0xa005, 0x1140,
-+	0x708b, 0x0001, 0x080c, 0x4b43, 0x708f, 0x001a, 0x0029, 0x0010,
-+	0x080c, 0x4ad9, 0x00fe, 0x0005, 0x708f, 0x001b, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x2099, 0xba80, 0x20a1, 0x020b, 0x7484, 0xa480,
-+	0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6,
-+	0x60c3, 0x0084, 0x080c, 0x4ac0, 0x0005, 0x0005, 0x0005, 0x0086,
-+	0x0096, 0x2029, 0xb453, 0x252c, 0x20a9, 0x0008, 0x2041, 0xba0e,
-+	0x28a0, 0x2099, 0xba8e, 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007,
-+	0xd5d4, 0x0110, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6,
-+	0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04,
-+	0x49e4, 0x0804, 0x4a52, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6,
-+	0x3fff, 0x0d90, 0x0020, 0xa1a6, 0x3fff, 0x0904, 0x4a52, 0xa18d,
-+	0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019,
-+	0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240,
-+	0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x4a0a, 0x04d0,
-+	0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x4a1c, 0x2328,
-+	0x8529, 0xa2be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200,
-+	0xa73a, 0x000e, 0x27a8, 0xa5a8, 0x0010, 0x1f04, 0x4a2b, 0x7552,
-+	0xa5c8, 0x2d88, 0x292d, 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536,
-+	0x0016, 0x2508, 0x080c, 0x280d, 0x001e, 0x60e7, 0x0000, 0x65ea,
-+	0x2018, 0x2304, 0xa405, 0x201a, 0x707b, 0x0001, 0x26a0, 0x2898,
-+	0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085,
-+	0x0001, 0x0028, 0xa006, 0x0018, 0xa006, 0x080c, 0x1511, 0x009e,
-+	0x008e, 0x0005, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
-+	0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120,
-+	0xa39a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118,
-+	0x8423, 0x8319, 0x1de8, 0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405,
-+	0x203a, 0x7152, 0xa1a0, 0x2d88, 0x242d, 0xa5ac, 0x00ff, 0x7576,
-+	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x280d, 0x001e, 0x60e7,
-+	0x0000, 0x65ea, 0x707b, 0x0001, 0xa084, 0x0000, 0x0005, 0x00e6,
-+	0x2071, 0xb400, 0x707f, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6,
-+	0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x7d24, 0x7004, 0xa084,
-+	0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x0126, 0x2091,
-+	0x8000, 0x2071, 0xb423, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016,
-+	0x2009, 0x00f7, 0x080c, 0x4b69, 0x001e, 0xa094, 0x0010, 0xa285,
-+	0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x2011, 0xb6ea, 0x2013, 0x0000, 0x7087,
-+	0x0000, 0x012e, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
-+	0x080c, 0x7d1b, 0x2009, 0x07d0, 0x2011, 0x4a96, 0x080c, 0x69e7,
-+	0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2011,
-+	0x0003, 0x080c, 0x801f, 0x2011, 0x0002, 0x080c, 0x8029, 0x080c,
-+	0x7f03, 0x0036, 0x2019, 0x0000, 0x080c, 0x7f8e, 0x003e, 0x2009,
-+	0x00f7, 0x080c, 0x4b69, 0x2061, 0xb6f3, 0x601b, 0x0000, 0x601f,
-+	0x0000, 0x2061, 0xb400, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4b0e, 0x080c,
-+	0x6955, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006,
-+	0x0126, 0x2091, 0x8000, 0x2071, 0x0100, 0x080c, 0x7d24, 0x2071,
-+	0x0140, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003,
-+	0x0000, 0x080c, 0x5a98, 0x01a8, 0x080c, 0x5ab6, 0x1190, 0x2001,
-+	0xb69e, 0x2003, 0xaaaa, 0x0016, 0x080c, 0x28b1, 0x2001, 0xb68f,
-+	0x2102, 0x001e, 0x2001, 0xb69f, 0x2003, 0x0000, 0x080c, 0x59c8,
-+	0x0030, 0x2001, 0x0001, 0x080c, 0x2789, 0x080c, 0x4ad9, 0x012e,
-+	0x000e, 0x00ee, 0x0005, 0x20a9, 0x0040, 0x20a1, 0xbbc0, 0x2099,
-+	0xba8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4b49,
-+	0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xba00, 0x20a1,
-+	0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x2099, 0xba80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6,
-+	0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0xb431,
-+	0x2004, 0xa005, 0x1138, 0x2001, 0xb415, 0x2004, 0xa084, 0x00ff,
-+	0xa105, 0x0010, 0xa185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005,
-+	0x0016, 0x0046, 0x2001, 0xb453, 0x2004, 0xd0a4, 0x0158, 0xa006,
-+	0x2020, 0x2009, 0x002a, 0x080c, 0xb06b, 0x2001, 0xb40c, 0x200c,
-+	0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x080c, 0x2c33,
-+	0x004e, 0x001e, 0x0005, 0x080c, 0x4ad9, 0x708f, 0x0000, 0x7087,
-+	0x0000, 0x0005, 0x0006, 0x2001, 0xb40c, 0x2004, 0xd09c, 0x0100,
-+	0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001,
-+	0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e,
-+	0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009, 0xb535, 0xa006, 0x200a,
-+	0x8108, 0x1f04, 0x4bbf, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156,
-+	0x0136, 0x0146, 0x2069, 0xb452, 0xa006, 0x6002, 0x6007, 0x0707,
-+	0x600a, 0x600e, 0x6012, 0xa198, 0x2d88, 0x231d, 0xa39c, 0x00ff,
-+	0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9,
-+	0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e,
-+	0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e,
-+	0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e,
-+	0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4,
-+	0xa06d, 0x0110, 0x080c, 0x160b, 0x60a7, 0x0000, 0x60a8, 0xa06d,
-+	0x0110, 0x080c, 0x160b, 0x60ab, 0x0000, 0x00de, 0xa006, 0x604a,
-+	0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042,
-+	0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091,
-+	0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04,
-+	0x4cd4, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04, 0x4cd9,
-+	0x2001, 0xb40c, 0x2004, 0xa084, 0x0003, 0x01c0, 0x2001, 0xb40c,
-+	0x2004, 0xd084, 0x1904, 0x4cbc, 0xa188, 0xb535, 0x2104, 0xa065,
-+	0x0904, 0x4cbc, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904,
-+	0x4cbc, 0x6000, 0xd0c4, 0x0904, 0x4cbc, 0x0068, 0xa188, 0xb535,
-+	0x2104, 0xa065, 0x0904, 0x4ca0, 0x6004, 0xa084, 0x00ff, 0xa08e,
-+	0x0006, 0x1904, 0x4ca5, 0x60a4, 0xa00d, 0x0118, 0x080c, 0x5195,
-+	0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, 0x51e0, 0x1170, 0x694c,
-+	0xd1fc, 0x1118, 0x080c, 0x4e9f, 0x0448, 0x080c, 0x4e4e, 0x694c,
-+	0xd1ec, 0x1520, 0x080c, 0x5087, 0x0408, 0x694c, 0xa184, 0xa000,
-+	0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, 0x080c, 0x5096, 0x0028,
-+	0x080c, 0x5096, 0x0028, 0xd1fc, 0x0118, 0x080c, 0x4e4e, 0x0070,
-+	0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
-+	0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x080c, 0x6c6f,
-+	0xa006, 0x012e, 0x0005, 0x2001, 0x0005, 0x2009, 0x0000, 0x04e8,
-+	0x2001, 0x0028, 0x2009, 0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0,
-+	0x2001, 0xb435, 0x2004, 0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148,
-+	0x6100, 0xd1fc, 0x0904, 0x4c5b, 0x2001, 0x0029, 0x2009, 0x1000,
-+	0x0420, 0x2001, 0x0028, 0x00a8, 0x2009, 0xb40c, 0x210c, 0xd18c,
-+	0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004,
-+	0x0040, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000,
-+	0x0060, 0x2009, 0x0000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000,
-+	0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x012e, 0x0005,
-+	0x00e6, 0x0126, 0x2091, 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff,
-+	0x2008, 0xa182, 0x00ff, 0x1a04, 0x4d33, 0xa188, 0xb535, 0x2104,
-+	0xa065, 0x01c0, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8,
-+	0x2c70, 0x080c, 0x856a, 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012,
-+	0x600b, 0xffff, 0x601f, 0x000a, 0x2009, 0x0003, 0x080c, 0x85ef,
-+	0xa006, 0x0460, 0x2001, 0x0028, 0x0440, 0xa082, 0x0006, 0x1298,
-+	0x2001, 0xb435, 0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140,
-+	0x6100, 0xd1fc, 0x09e8, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8,
-+	0x2001, 0x0028, 0x0090, 0x2009, 0xb40c, 0x210c, 0xd18c, 0x0118,
-+	0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028,
-+	0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee,
-+	0x0005, 0x2001, 0x002c, 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091,
-+	0x8000, 0x2011, 0x0000, 0x2079, 0xb400, 0x6944, 0xa18c, 0xff00,
-+	0x810f, 0xa182, 0x00ff, 0x1a04, 0x4e05, 0x2001, 0xb40c, 0x2004,
-+	0xa084, 0x0003, 0x1904, 0x4df3, 0x080c, 0x4f6a, 0x11a0, 0x6004,
-+	0xa084, 0x00ff, 0xa082, 0x0006, 0x1270, 0x6864, 0xa0c6, 0x006f,
-+	0x0150, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x1904, 0x4dee, 0x60a0,
-+	0xd0bc, 0x1904, 0x4dee, 0x6864, 0xa0c6, 0x006f, 0x0118, 0x2008,
-+	0x0804, 0x4db7, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f, 0x78d4,
-+	0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff, 0x16b8,
-+	0x6a70, 0x6b6c, 0x7870, 0xa306, 0x1160, 0x7874, 0xa24e, 0x1118,
-+	0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208, 0x2310,
-+	0x0430, 0x080c, 0x3d81, 0x2c70, 0x0550, 0x2009, 0x0000, 0x2011,
-+	0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c, 0x520b,
-+	0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x0088,
-+	0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118,
-+	0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001,
-+	0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0450, 0x080c,
-+	0x856a, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011, 0x0000,
-+	0x0c80, 0x2e00, 0x601a, 0x080c, 0x9fb8, 0x2d00, 0x6012, 0x601f,
-+	0x0001, 0x6838, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x2c60, 0x012e, 0x2001, 0x0000, 0x080c, 0x4eac,
-+	0x2001, 0x0002, 0x080c, 0x4ebe, 0x2009, 0x0002, 0x080c, 0x85ef,
-+	0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x0028,
-+	0x2009, 0x0000, 0x0cb0, 0x2009, 0xb40c, 0x210c, 0xd18c, 0x0118,
-+	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
-+	0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001, 0x0029, 0x2009,
-+	0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000,
-+	0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x12e0, 0xa188,
-+	0xb535, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa08e,
-+	0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c, 0x5096, 0x0431,
-+	0x0030, 0x0421, 0x684c, 0xd0fc, 0x0110, 0x080c, 0x5087, 0x080c,
-+	0x50d4, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009, 0x0000, 0x00a0,
-+	0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20, 0x2001, 0x0029,
-+	0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020,
-+	0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005, 0x0126, 0x2091,
-+	0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a, 0x6803, 0x0000,
-+	0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000,
-+	0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005, 0x0170, 0x00e6,
-+	0x2071, 0xb6e0, 0x7004, 0xa086, 0x0002, 0x0168, 0x00ee, 0x604c,
-+	0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e,
-+	0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80, 0x604c, 0x2070,
-+	0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108,
-+	0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c, 0xa06d, 0x0130,
-+	0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x0005, 0x6803,
-+	0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a, 0x6086, 0x0005,
-+	0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6, 0x0026, 0x2091,
-+	0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110, 0xc285, 0x0008,
-+	0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6,
-+	0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006,
-+	0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xb453, 0x2004, 0xd0a4,
-+	0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x1110, 0x2011,
-+	0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206, 0x0006, 0xa086,
-+	0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c, 0x1511, 0x000e,
-+	0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218,
-+	0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178, 0x609c, 0xd0a4,
-+	0x0160, 0x2001, 0xb453, 0x2004, 0xd0ac, 0x1138, 0xa284, 0x00ff,
-+	0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0xa294, 0x00ff,
-+	0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026, 0xa182,
-+	0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0xb535, 0x2204,
-+	0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15db, 0x2d60, 0x00de,
-+	0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000,
-+	0x080c, 0x4bc5, 0xa006, 0x002e, 0x0005, 0x0126, 0x2091, 0x8000,
-+	0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0480, 0x00d6,
-+	0xa190, 0xb535, 0x2204, 0xa06d, 0x0540, 0x2013, 0x0000, 0x00d6,
-+	0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x160b, 0x60a8,
-+	0xa06d, 0x0110, 0x080c, 0x160b, 0x00ce, 0x00de, 0x00d6, 0x00c6,
-+	0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x0110, 0x080c, 0x161b, 0x080c, 0x85c0, 0x00ce,
-+	0x0c88, 0x00ce, 0x00de, 0x080c, 0x160b, 0x00de, 0xa006, 0x002e,
-+	0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
-+	0x0030, 0xa188, 0xb535, 0x2104, 0xa065, 0x0dc0, 0xa006, 0x001e,
-+	0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000, 0x600f,
-+	0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x5a90, 0x1558, 0x60a0,
-+	0xa086, 0x007e, 0x2069, 0xba90, 0x0130, 0x2001, 0xb435, 0x2004,
-+	0xd0ac, 0x1500, 0x0098, 0x2d04, 0xd0e4, 0x01e0, 0x00d6, 0x2069,
-+	0xba8e, 0x00c6, 0x2061, 0xb6b2, 0x6810, 0x2062, 0x6814, 0x6006,
-+	0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69, 0x2d04,
-+	0x2069, 0x0140, 0xa005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069,
-+	0xb400, 0x68a6, 0x2069, 0xba8e, 0x6808, 0x605e, 0x6810, 0x6062,
-+	0x6138, 0xa10a, 0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xba96,
-+	0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xba9a,
-+	0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xbaae,
-+	0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076,
-+	0x60a0, 0xa086, 0x007e, 0x1120, 0x2069, 0xba8e, 0x690c, 0x616e,
-+	0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259,
-+	0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009,
-+	0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070,
-+	0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581,
-+	0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e,
-+	0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071,
-+	0xba8d, 0x2e04, 0x6896, 0x2071, 0xba8e, 0x7004, 0x689a, 0x701c,
-+	0x689e, 0x6a00, 0x2009, 0xb472, 0x210c, 0xd0bc, 0x0120, 0xd1ec,
-+	0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110,
-+	0xc2bd, 0x0008, 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005,
-+	0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900,
-+	0x81ff, 0x1540, 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004,
-+	0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04,
-+	0x5042, 0x080c, 0x1511, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c,
-+	0x15f4, 0x01a8, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004,
-+	0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x505a, 0x6807,
-+	0x0001, 0x6e12, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006,
-+	0x0cd8, 0x0126, 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0,
-+	0x2168, 0x6800, 0xa005, 0x1160, 0x080c, 0x5195, 0x1168, 0x200b,
-+	0xffff, 0x6804, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020,
-+	0x080c, 0x160b, 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x51f3, 0x0010, 0x080c, 0x4e4e, 0x080c,
-+	0x510d, 0x1dd8, 0x080c, 0x50d4, 0x012e, 0x0005, 0x00d6, 0x0126,
-+	0x2091, 0x8000, 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540,
-+	0x6a54, 0xa282, 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010,
-+	0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x50a8, 0x080c,
-+	0x1511, 0x260a, 0x8210, 0x6a56, 0x0098, 0x080c, 0x15f4, 0x01d0,
-+	0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010,
-+	0x200b, 0xffff, 0x8108, 0x1f04, 0x50c0, 0x6857, 0x0001, 0x6e62,
-+	0x0010, 0x080c, 0x4e9f, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e,
-+	0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c,
-+	0x6c6f, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e,
-+	0x0126, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170,
-+	0x8dff, 0x01f8, 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030,
-+	0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800,
-+	0x2068, 0x0c70, 0x080c, 0x80c8, 0x6a00, 0x604c, 0xad06, 0x1110,
-+	0x624e, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, 0x6152,
-+	0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e,
-+	0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120, 0x6848, 0xa606,
-+	0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0120,
-+	0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080, 0xad06, 0x1110,
-+	0x6282, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, 0x6186,
-+	0x8dff, 0x0005, 0xa016, 0x080c, 0x518f, 0x1110, 0x2011, 0x0001,
-+	0x080c, 0x51da, 0x1110, 0xa295, 0x0002, 0x0005, 0x080c, 0x520b,
-+	0x0118, 0x080c, 0x9ca0, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c,
-+	0x520b, 0x0118, 0x080c, 0x9c30, 0x0010, 0xa085, 0x0001, 0x0005,
-+	0x080c, 0x520b, 0x0118, 0x080c, 0x9c83, 0x0010, 0xa085, 0x0001,
-+	0x0005, 0x080c, 0x520b, 0x0118, 0x080c, 0x9c4c, 0x0010, 0xa085,
-+	0x0001, 0x0005, 0x080c, 0x520b, 0x0118, 0x080c, 0x9cbc, 0x0010,
-+	0xa085, 0x0001, 0x0005, 0x0126, 0x0006, 0x00d6, 0x2091, 0x8000,
-+	0x6080, 0xa06d, 0x01a0, 0x6800, 0x0006, 0x6837, 0x0103, 0x6b4a,
-+	0x6847, 0x0000, 0x080c, 0x9e5d, 0x0006, 0x6000, 0xd0fc, 0x0110,
-+	0x080c, 0xb30c, 0x000e, 0x080c, 0x53c9, 0x000e, 0x0c50, 0x6083,
-+	0x0000, 0x6087, 0x0000, 0x00de, 0x000e, 0x012e, 0x0005, 0x60a4,
-+	0xa00d, 0x1118, 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7000,
-+	0xa005, 0x1168, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, 0xa606,
-+	0x0130, 0x8108, 0x1f04, 0x519e, 0xa085, 0x0001, 0x0008, 0xa006,
-+	0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d,
-+	0x1128, 0x080c, 0x15f4, 0x01a0, 0x2d00, 0x60a6, 0x6803, 0x0001,
-+	0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff,
-+	0x8108, 0x1f04, 0x51be, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
-+	0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d,
-+	0x0130, 0x60a7, 0x0000, 0x080c, 0x160b, 0xa085, 0x0001, 0x012e,
-+	0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005,
-+	0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, 0x20a9, 0x0010, 0xae88,
-+	0x0018, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x51e9, 0xa085,
-+	0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0c19, 0x1188,
-+	0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002,
-+	0x0218, 0x8001, 0x6856, 0x0020, 0x080c, 0x160b, 0x60ab, 0x0000,
-+	0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005, 0x00f6, 0x080c,
-+	0x5a90, 0x01b0, 0x71b8, 0x81ff, 0x1198, 0x71d4, 0xd19c, 0x0180,
-+	0x2001, 0x007e, 0xa080, 0xb535, 0x2004, 0xa07d, 0x0148, 0x7804,
-+	0xa084, 0x00ff, 0xa086, 0x0006, 0x1118, 0x7800, 0xc0ed, 0x7802,
-+	0x2079, 0xb452, 0x7804, 0xd0a4, 0x01e8, 0x0156, 0x00c6, 0x20a9,
-+	0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4f6a, 0x1168, 0x6004,
-+	0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086, 0x0006,
-+	0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04, 0x5233,
-+	0x00ce, 0x015e, 0x080c, 0x52ca, 0x0120, 0x2001, 0xb6b5, 0x200c,
-+	0x0038, 0x2079, 0xb452, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0,
-+	0x2011, 0x525e, 0x080c, 0x69e7, 0x00fe, 0x0005, 0x2011, 0x525e,
-+	0x080c, 0x6961, 0x080c, 0x52ca, 0x01f0, 0x2001, 0xb5b3, 0x2004,
-+	0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xb453, 0x2004,
-+	0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, 0x525e, 0x080c, 0x69e7,
-+	0x00e6, 0x2071, 0xb400, 0x7073, 0x0000, 0x7077, 0x0000, 0x080c,
-+	0x2a7e, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009,
-+	0x0000, 0x0016, 0x080c, 0x4f6a, 0x1530, 0x6000, 0xd0ec, 0x0518,
-+	0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029,
-+	0x080c, 0xb06b, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084,
-+	0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x080c, 0x6dba,
-+	0x0076, 0x2039, 0x0000, 0x080c, 0x6cc7, 0x2009, 0x0000, 0x080c,
-+	0xae05, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x5289, 0x00ce,
-+	0x015e, 0x0005, 0x00c6, 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002,
-+	0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac, 0x0005, 0x7818, 0x2004,
-+	0xd0bc, 0x0005, 0x00f6, 0x2001, 0xb5b3, 0x2004, 0xa07d, 0x0110,
-+	0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000,
-+	0x0006, 0x62a0, 0xa290, 0xb535, 0x2204, 0xac06, 0x190c, 0x1511,
-+	0x000e, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0x6202,
-+	0x002e, 0x012e, 0x0005, 0x2011, 0xb435, 0x2204, 0xd0cc, 0x0138,
-+	0x2001, 0xb6b3, 0x200c, 0x2011, 0x52f8, 0x080c, 0x69e7, 0x0005,
-+	0x2011, 0x52f8, 0x080c, 0x6961, 0x2011, 0xb435, 0x2204, 0xc0cc,
-+	0x2012, 0x0005, 0x2071, 0xb514, 0x7003, 0x0001, 0x7007, 0x0000,
-+	0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
-+	0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020,
-+	0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xb67d, 0x7003, 0xb514,
-+	0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xb65d, 0x7013, 0x0020,
-+	0x7017, 0x0040, 0x7037, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071,
-+	0xb635, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xb453,
-+	0x2004, 0xd0fc, 0x1150, 0x2001, 0xb453, 0x2004, 0xa00e, 0xd09c,
-+	0x0108, 0x8108, 0x7102, 0x0804, 0x5393, 0x2001, 0xb472, 0x200c,
-+	0xa184, 0x000f, 0x2009, 0xb473, 0x210c, 0x0002, 0x533b, 0x536e,
-+	0x5375, 0x537f, 0x5384, 0x533b, 0x533b, 0x533b, 0x535e, 0x533b,
-+	0x533b, 0x533b, 0x533b, 0x533b, 0x533b, 0x533b, 0x7003, 0x0004,
-+	0x0136, 0x0146, 0x0156, 0x2099, 0xb476, 0x20a1, 0xb686, 0x20a9,
-+	0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x0428, 0x708f, 0x0005,
-+	0x7007, 0x0122, 0x2001, 0x0002, 0x0030, 0x708f, 0x0002, 0x7007,
-+	0x0121, 0x2001, 0x0003, 0x7002, 0x7097, 0x0001, 0x0088, 0x7007,
-+	0x0122, 0x2001, 0x0002, 0x0020, 0x7007, 0x0121, 0x2001, 0x0003,
-+	0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a,
-+	0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005, 0x00e6, 0x2071,
-+	0xb514, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085,
-+	0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, 0x703e,
-+	0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, 0x7032,
-+	0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006, 0x8006,
-+	0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e,
-+	0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, 0x00ee,
-+	0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x5422,
-+	0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0xb400, 0xa016, 0x702c,
-+	0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e,
-+	0x70b4, 0xa200, 0x70b6, 0x00de, 0x2071, 0xb514, 0x701c, 0xa005,
-+	0x1904, 0x5432, 0x20a9, 0x0032, 0x0f04, 0x5430, 0x0e04, 0x53ec,
-+	0x2071, 0xb635, 0x7200, 0x82ff, 0x05d8, 0x6934, 0xa186, 0x0103,
-+	0x1904, 0x5440, 0x6948, 0x6844, 0xa105, 0x1540, 0x2009, 0x8020,
-+	0x2200, 0x0002, 0x5430, 0x5407, 0x5458, 0x5464, 0x5430, 0x2071,
-+	0x0000, 0x20a9, 0x0032, 0x0f04, 0x5430, 0x7018, 0xd084, 0x1dd8,
-+	0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091,
-+	0x4080, 0x2071, 0xb400, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70b4,
-+	0x8000, 0x70b6, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844, 0xa086,
-+	0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0880,
-+	0x2071, 0xb514, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012,
-+	0x7018, 0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x0c10,
-+	0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118,
-+	0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850, 0xa084,
-+	0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804, 0x5400,
-+	0x7084, 0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90, 0x0003,
-+	0xa210, 0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092, 0x000f,
-+	0x1a38, 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012,
-+	0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x5419, 0x718c,
-+	0x7084, 0xa10a, 0x0a04, 0x5419, 0x2071, 0x0000, 0x7018, 0xd084,
-+	0x1904, 0x5419, 0x2071, 0xb635, 0x7000, 0xa086, 0x0002, 0x1150,
-+	0x080c, 0x56e3, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-+	0x0804, 0x5419, 0x080c, 0x570d, 0x2071, 0x0000, 0x701b, 0x0001,
-+	0x2091, 0x4080, 0x0804, 0x5419, 0x0006, 0x684c, 0x0006, 0x6837,
-+	0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000,
-+	0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a, 0x6952,
-+	0x0005, 0x2071, 0xb514, 0x7004, 0x0002, 0x54bf, 0x54d0, 0x56ce,
-+	0x56cf, 0x56dc, 0x56e2, 0x54c0, 0x56bf, 0x5655, 0x56ab, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0e04, 0x54cf, 0x2009, 0x000d, 0x7030,
-+	0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x012e,
-+	0x2069, 0xb6f3, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091,
-+	0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xb520, 0x2004, 0xa10a,
-+	0x0170, 0x0e04, 0x54f3, 0x2069, 0x0000, 0x6818, 0xd084, 0x1158,
-+	0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x2069,
-+	0xb6f3, 0x683f, 0xffff, 0x012e, 0x2069, 0xb400, 0x6848, 0x6968,
-+	0xa102, 0x2069, 0xb635, 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120,
-+	0x81ff, 0x0904, 0x5549, 0x00a0, 0x81ff, 0x0904, 0x560f, 0x2071,
-+	0xb635, 0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071, 0xb6f3,
-+	0x7038, 0xa005, 0x0128, 0x1b04, 0x560f, 0x713a, 0x0804, 0x560f,
-+	0x2071, 0xb635, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a,
-+	0x0a04, 0x562a, 0x0e04, 0x55cb, 0x2071, 0x0000, 0x7018, 0xd084,
-+	0x1904, 0x55cb, 0x2001, 0xffff, 0x2071, 0xb6f3, 0x703a, 0x2071,
-+	0xb635, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x56e3, 0x2071,
-+	0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x55cb, 0x080c,
-+	0x570d, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804,
-+	0x55cb, 0x2071, 0xb635, 0x7000, 0xa005, 0x0904, 0x55f1, 0x6934,
-+	0xa186, 0x0103, 0x1904, 0x55ce, 0x684c, 0xd0bc, 0x1904, 0x55f1,
-+	0x6948, 0x6844, 0xa105, 0x1904, 0x55e6, 0x2009, 0x8020, 0x2071,
-+	0xb635, 0x7000, 0x0002, 0x55f1, 0x55b1, 0x5589, 0x559b, 0x5568,
-+	0x0136, 0x0146, 0x0156, 0x2099, 0xb476, 0x20a1, 0xb686, 0x20a9,
-+	0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x2071, 0xb67d, 0xad80,
-+	0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000,
-+	0x2e10, 0x080c, 0x163f, 0x2071, 0xb514, 0x7007, 0x0009, 0x0804,
-+	0x560f, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x560f, 0xae90,
-+	0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xb514, 0x080c,
-+	0x5764, 0x0804, 0x560f, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04,
-+	0x560f, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
-+	0x6840, 0x2012, 0x7186, 0x2071, 0xb514, 0x080c, 0x5764, 0x0804,
-+	0x560f, 0x0126, 0x2091, 0x8000, 0x0e04, 0x55cb, 0x2071, 0x0000,
-+	0x7018, 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
-+	0x701b, 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0xb514, 0x080c,
-+	0x5764, 0x0804, 0x560f, 0x012e, 0x0804, 0x560f, 0xa18c, 0x00ff,
-+	0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f,
-+	0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850, 0xa084, 0x00ff, 0xa086,
-+	0x0001, 0x1178, 0x2009, 0x8021, 0x0804, 0x555f, 0x6844, 0xa086,
-+	0x0100, 0x1138, 0x6868, 0xa005, 0x1120, 0x2009, 0x8020, 0x0804,
-+	0x555f, 0x2071, 0xb514, 0x080c, 0x5776, 0x01c8, 0x2071, 0xb514,
-+	0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130,
-+	0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007, 0x0003,
-+	0x080c, 0x578f, 0x7050, 0xa086, 0x0100, 0x0904, 0x56cf, 0x0126,
-+	0x2091, 0x8000, 0x2071, 0xb514, 0x7008, 0xa086, 0x0001, 0x1180,
-+	0x0e04, 0x5628, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080,
-+	0x700b, 0x0000, 0x7004, 0xa086, 0x0006, 0x1110, 0x7007, 0x0001,
-+	0x012e, 0x0005, 0x2071, 0xb514, 0x080c, 0x5776, 0x0518, 0x2071,
-+	0xb635, 0x7084, 0x700a, 0x20a9, 0x0020, 0x2099, 0xb636, 0x20a1,
-+	0xb65d, 0x53a3, 0x7087, 0x0000, 0x2071, 0xb514, 0x2069, 0xb67d,
-+	0x706c, 0x6826, 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832,
-+	0x2d10, 0x080c, 0x163f, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071,
-+	0xb6f3, 0x703a, 0x012e, 0x0804, 0x560f, 0x2069, 0xb67d, 0x6808,
-+	0xa08e, 0x0000, 0x0904, 0x56aa, 0xa08e, 0x0200, 0x0904, 0x56a8,
-+	0xa08e, 0x0100, 0x1904, 0x56aa, 0x0126, 0x2091, 0x8000, 0x0e04,
-+	0x56a6, 0x2069, 0x0000, 0x6818, 0xd084, 0x15c0, 0x702c, 0x7130,
-+	0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
-+	0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081,
-+	0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001, 0xb65a,
-+	0x2004, 0xa005, 0x1190, 0x6934, 0x2069, 0xb635, 0x689c, 0x699e,
-+	0x2069, 0xb6f3, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368, 0x2001,
-+	0xb65b, 0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040, 0x6922,
-+	0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0010,
-+	0x7007, 0x0005, 0x0005, 0x2001, 0xb67f, 0x2004, 0xa08e, 0x0100,
-+	0x1128, 0x7007, 0x0001, 0x080c, 0x5764, 0x0005, 0xa08e, 0x0000,
-+	0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007, 0x0005, 0x0005, 0x701c,
-+	0xa06d, 0x0158, 0x080c, 0x5776, 0x0140, 0x7007, 0x0003, 0x080c,
-+	0x578f, 0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005, 0x7050,
-+	0xa09e, 0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086, 0x0200,
-+	0x1110, 0x7007, 0x0005, 0x0005, 0x080c, 0x5732, 0x7006, 0x080c,
-+	0x5764, 0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0xb635, 0x7184,
-+	0x81ff, 0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000,
-+	0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04, 0x5707, 0x2014, 0x722a,
-+	0x8000, 0x0f04, 0x5707, 0x2014, 0x722e, 0x8000, 0x0f04, 0x5707,
-+	0x2014, 0x723a, 0x8000, 0x0f04, 0x5707, 0x2014, 0x723e, 0xa180,
-+	0x8030, 0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156, 0x2071,
-+	0xb635, 0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80, 0x0003,
-+	0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, 0x722a,
-+	0x8000, 0x0f04, 0x5729, 0x2014, 0x723a, 0x8000, 0x2014, 0x723e,
-+	0x0018, 0x2001, 0x8020, 0x0010, 0x2001, 0x8042, 0x7022, 0x015e,
-+	0x00ee, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e,
-+	0x7034, 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040,
-+	0x706e, 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c,
-+	0x8001, 0x700e, 0x1180, 0x0126, 0x2091, 0x8000, 0x0e04, 0x575e,
-+	0x2001, 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b,
-+	0x0000, 0x012e, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001, 0x0006,
-+	0x700b, 0x0001, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, 0x0126,
-+	0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005,
-+	0x1108, 0x701a, 0x012e, 0x080c, 0x160b, 0x0005, 0x2019, 0x000d,
-+	0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, 0x0110,
-+	0xa006, 0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, 0x2300,
-+	0xa005, 0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, 0x2d00,
-+	0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, 0x2091,
-+	0x8000, 0x2009, 0xb712, 0x2104, 0xc08d, 0x200a, 0x012e, 0x080c,
-+	0x1657, 0x0005, 0x708c, 0xa08a, 0x0029, 0x1220, 0xa082, 0x001d,
-+	0x0033, 0x0010, 0x080c, 0x1511, 0x6027, 0x1e00, 0x0005, 0x589d,
-+	0x5818, 0x5830, 0x586d, 0x588e, 0x58c8, 0x58da, 0x5830, 0x58b4,
-+	0x57bc, 0x57ea, 0x57bb, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804,
-+	0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028, 0x2069,
-+	0xb6c5, 0x2d04, 0x7002, 0x080c, 0x5b92, 0x6028, 0xa085, 0x0600,
-+	0x602a, 0x00b0, 0x708f, 0x0028, 0x2069, 0xb6c5, 0x2d04, 0x7002,
-+	0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056,
-+	0x2071, 0xb723, 0x080c, 0x1dcd, 0x005e, 0x004e, 0x003e, 0x00ee,
-+	0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0xa005, 0x1180,
-+	0x6808, 0xa005, 0x1518, 0x708f, 0x0028, 0x2069, 0xb6c5, 0x2d04,
-+	0x7002, 0x080c, 0x5c1f, 0x6028, 0xa085, 0x0600, 0x602a, 0x00b0,
-+	0x708f, 0x0028, 0x2069, 0xb6c5, 0x2d04, 0x7002, 0x6028, 0xa085,
-+	0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xb723,
-+	0x080c, 0x1dcd, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005,
-+	0x6803, 0x0090, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x5945, 0xd1d4,
-+	0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x708f, 0x0020, 0x080c,
-+	0x5945, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f, 0x0005,
-+	0x6803, 0x0088, 0x6124, 0xd1cc, 0x1590, 0xd1dc, 0x1568, 0xd1e4,
-+	0x1540, 0xa184, 0x1e00, 0x1580, 0x60e3, 0x0001, 0x600c, 0xc0b4,
-+	0x600e, 0x080c, 0x5ac0, 0x080c, 0x2479, 0x0156, 0x6803, 0x0100,
-+	0x20a9, 0x0014, 0x6804, 0xd0dc, 0x1118, 0x1f04, 0x584a, 0x0048,
-+	0x20a9, 0x0014, 0x6803, 0x0080, 0x6804, 0xd0d4, 0x1130, 0x1f04,
-+	0x5854, 0x080c, 0x5ae1, 0x015e, 0x0078, 0x015e, 0x708f, 0x0028,
-+	0x0058, 0x708f, 0x001e, 0x0040, 0x708f, 0x001d, 0x0028, 0x708f,
-+	0x0020, 0x0010, 0x708f, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c,
-+	0xc0b4, 0x600e, 0x080c, 0x5ac0, 0x080c, 0x2479, 0x6803, 0x0080,
-+	0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184,
-+	0x1e00, 0x1158, 0x708f, 0x0028, 0x0040, 0x708f, 0x001e, 0x0028,
-+	0x708f, 0x001d, 0x0010, 0x708f, 0x001f, 0x0005, 0x6803, 0x00a0,
-+	0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1e18, 0x708f,
-+	0x001e, 0x0010, 0x708f, 0x001d, 0x0005, 0x080c, 0x59b7, 0x6124,
-+	0xd1dc, 0x1188, 0x080c, 0x5945, 0x0016, 0x080c, 0x1e18, 0x001e,
-+	0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x708f, 0x001e, 0x0020, 0x708f,
-+	0x001f, 0x080c, 0x5945, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4,
-+	0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708f,
-+	0x001e, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x0021, 0x0005,
-+	0x080c, 0x59b7, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
-+	0x0140, 0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f,
-+	0x001f, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc,
-+	0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x708f, 0x001e, 0x0040,
-+	0x708f, 0x001d, 0x0028, 0x708f, 0x0020, 0x0010, 0x708f, 0x001f,
-+	0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100,
-+	0x2069, 0x0140, 0x2071, 0xb400, 0x2091, 0x8000, 0x080c, 0x5a90,
-+	0x11e8, 0x2001, 0xb40c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102,
-+	0x6027, 0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803,
-+	0x00a0, 0x2001, 0xb69f, 0x2003, 0x0001, 0x2001, 0xb400, 0x2003,
-+	0x0001, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x5aac,
-+	0x0150, 0x080c, 0x5aa2, 0x1138, 0x2001, 0x0001, 0x080c, 0x2789,
-+	0x080c, 0x5a67, 0x00a0, 0x080c, 0x59b4, 0x0178, 0x2001, 0x0001,
-+	0x080c, 0x2789, 0x708c, 0xa086, 0x001e, 0x0120, 0x708c, 0xa086,
-+	0x0022, 0x1118, 0x708f, 0x0025, 0x0010, 0x708f, 0x0021, 0x012e,
-+	0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x5956,
-+	0x080c, 0x6a21, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
-+	0x5956, 0x080c, 0x6a18, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
-+	0x0016, 0x080c, 0x7d24, 0x2071, 0xb400, 0x080c, 0x58f1, 0x001e,
-+	0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-+	0x00e6, 0x00f6, 0x0126, 0x080c, 0x7d24, 0x2061, 0x0100, 0x2069,
-+	0x0140, 0x2071, 0xb400, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a,
-+	0x2011, 0x0003, 0x080c, 0x801f, 0x2011, 0x0002, 0x080c, 0x8029,
-+	0x080c, 0x7f03, 0x080c, 0x69d5, 0x0036, 0x2019, 0x0000, 0x080c,
-+	0x7f8e, 0x003e, 0x60e3, 0x0000, 0x080c, 0xb3b2, 0x080c, 0xb3cd,
-+	0x2001, 0xb400, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c, 0x12d9,
-+	0x2001, 0x0001, 0x080c, 0x2789, 0x012e, 0x00fe, 0x00ee, 0x00de,
-+	0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x2001, 0xb400, 0x2004,
-+	0xa086, 0x0004, 0x0140, 0x2001, 0xb69e, 0x2003, 0xaaaa, 0x2001,
-+	0xb69f, 0x2003, 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800,
-+	0xa086, 0x00c0, 0x0160, 0x6803, 0x00c0, 0x0156, 0x20a9, 0x002d,
-+	0x1d04, 0x59c0, 0x2091, 0x6000, 0x1f04, 0x59c0, 0x015e, 0x0005,
-+	0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-+	0xb400, 0x2001, 0xb69f, 0x200c, 0xa186, 0x0000, 0x0158, 0xa186,
-+	0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003, 0x0158,
-+	0x0804, 0x5a55, 0x708f, 0x0022, 0x0040, 0x708f, 0x0021, 0x0028,
-+	0x708f, 0x0023, 0x0020, 0x708f, 0x0024, 0x6043, 0x0000, 0x60e3,
-+	0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2838, 0x0026,
-+	0x2011, 0x0003, 0x080c, 0x801f, 0x2011, 0x0002, 0x080c, 0x8029,
-+	0x080c, 0x7f03, 0x0036, 0x2019, 0x0000, 0x080c, 0x7f8e, 0x003e,
-+	0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010,
-+	0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005,
-+	0x6024, 0xd0ac, 0x0120, 0x012e, 0x015e, 0x0804, 0x5a63, 0x6800,
-+	0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130, 0x6803,
-+	0x0100, 0x1f04, 0x5a18, 0x080c, 0x5ae1, 0x012e, 0x015e, 0x080c,
-+	0x5aa2, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, 0xa085,
-+	0x0020, 0x6052, 0x080c, 0x5ae1, 0xa006, 0x8001, 0x1df0, 0x000e,
-+	0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x5ae1, 0x0016,
-+	0x0026, 0x2009, 0x00c8, 0x2011, 0x5963, 0x080c, 0x69e7, 0x002e,
-+	0x001e, 0x2001, 0xb69f, 0x2003, 0x0004, 0x080c, 0x57a2, 0x080c,
-+	0x5aa2, 0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001,
-+	0xb69f, 0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
-+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb400,
-+	0x2001, 0xb69e, 0x2003, 0x0000, 0x2001, 0xb68f, 0x2003, 0x0000,
-+	0x708f, 0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000,
-+	0x080c, 0x2838, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010,
-+	0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005,
-+	0x0006, 0x2001, 0xb69e, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005,
-+	0x0006, 0x2001, 0xb472, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000,
-+	0x000e, 0x0005, 0x0006, 0x2001, 0xb472, 0x2004, 0xa084, 0x0030,
-+	0xa086, 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xb472, 0x2004,
-+	0xa084, 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001,
-+	0xb472, 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005,
-+	0x2001, 0xb40c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x2858, 0x0036,
-+	0x0016, 0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2c33, 0x001e,
-+	0x003e, 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xb40c, 0x2e04,
-+	0x0118, 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee,
-+	0x0005, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c,
-+	0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f,
-+	0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e,
-+	0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3,
-+	0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2838, 0x6800,
-+	0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052,
-+	0x6050, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-+	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb400, 0x6020,
-+	0xa084, 0x0080, 0x0138, 0x2001, 0xb40c, 0x200c, 0xc1bd, 0x2102,
-+	0x0804, 0x5b8a, 0x2001, 0xb40c, 0x200c, 0xc1bc, 0x2102, 0x6028,
-+	0xa084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9,
-+	0x0384, 0x6024, 0xd0cc, 0x1508, 0x1d04, 0x5b39, 0x2091, 0x6000,
-+	0x1f04, 0x5b39, 0x2011, 0x0003, 0x080c, 0x801f, 0x2011, 0x0002,
-+	0x080c, 0x8029, 0x080c, 0x7f03, 0x2019, 0x0000, 0x080c, 0x7f8e,
-+	0x6803, 0x00a0, 0x2001, 0xb69f, 0x2003, 0x0001, 0x2001, 0xb400,
-+	0x2003, 0x0001, 0xa085, 0x0001, 0x0468, 0x86ff, 0x1110, 0x080c,
-+	0x1e18, 0x60e3, 0x0000, 0x2001, 0xb68f, 0x2004, 0x080c, 0x2838,
-+	0x60e2, 0x080c, 0x2479, 0x6803, 0x0080, 0x20a9, 0x0384, 0x6027,
-+	0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0138, 0x1d04,
-+	0x5b6f, 0x2091, 0x6000, 0x1f04, 0x5b6f, 0x0820, 0x6028, 0xa085,
-+	0x1e00, 0x602a, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008,
-+	0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
-+	0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-+	0x00e6, 0x2061, 0x0100, 0x2071, 0xb400, 0x2069, 0x0140, 0x6020,
-+	0xa084, 0x00c0, 0x0120, 0x6884, 0xa005, 0x1904, 0x5be6, 0x6803,
-+	0x0088, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
-+	0x2838, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808, 0xa005,
-+	0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069,
-+	0xb6c5, 0x7000, 0x206a, 0x708f, 0x0026, 0x7003, 0x0001, 0x20a9,
-+	0x0002, 0x1d04, 0x5bc9, 0x2091, 0x6000, 0x1f04, 0x5bc9, 0x0804,
-+	0x5c17, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009,
-+	0x1e00, 0xe000, 0x6024, 0xa10c, 0x0520, 0xa084, 0x1a00, 0x1508,
-+	0x1d04, 0x5bd5, 0x2091, 0x6000, 0x1f04, 0x5bd5, 0x2011, 0x0003,
-+	0x080c, 0x801f, 0x2011, 0x0002, 0x080c, 0x8029, 0x080c, 0x7f03,
-+	0x2019, 0x0000, 0x080c, 0x7f8e, 0x6803, 0x00a0, 0x2001, 0xb69f,
-+	0x2003, 0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0xa085, 0x0001,
-+	0x00b0, 0x080c, 0x2479, 0x6803, 0x0080, 0x2069, 0x0140, 0x60e3,
-+	0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-+	0x2001, 0xb68f, 0x2004, 0x080c, 0x2838, 0x60e2, 0xa006, 0x00ee,
-+	0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156,
-+	0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
-+	0x2071, 0xb400, 0x6020, 0xa084, 0x00c0, 0x01e0, 0x2011, 0x0003,
-+	0x080c, 0x801f, 0x2011, 0x0002, 0x080c, 0x8029, 0x080c, 0x7f03,
-+	0x2019, 0x0000, 0x080c, 0x7f8e, 0x2069, 0x0140, 0x6803, 0x00a0,
-+	0x2001, 0xb69f, 0x2003, 0x0001, 0x2001, 0xb400, 0x2003, 0x0001,
-+	0x0804, 0x5cbc, 0x2001, 0xb40c, 0x200c, 0xd1b4, 0x1160, 0xc1b5,
-+	0x2102, 0x080c, 0x594b, 0x2069, 0x0140, 0x080c, 0x2479, 0x6803,
-+	0x0080, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118,
-+	0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfdff, 0x602a, 0x6027,
-+	0x0200, 0x2069, 0xb6c5, 0x7000, 0x206a, 0x708f, 0x0027, 0x7003,
-+	0x0001, 0x20a9, 0x0002, 0x1d04, 0x5c73, 0x2091, 0x6000, 0x1f04,
-+	0x5c73, 0x0804, 0x5cbc, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000,
-+	0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0, 0x1d04, 0x5c7b,
-+	0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x68be, 0x00ee,
-+	0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0xb6f3, 0x7018,
-+	0x00ee, 0xa005, 0x1d00, 0x0500, 0x0026, 0x2011, 0x5963, 0x080c,
-+	0x6961, 0x2011, 0x5956, 0x080c, 0x6a21, 0x002e, 0x2069, 0x0140,
-+	0x60e3, 0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008,
-+	0x6886, 0x2001, 0xb68f, 0x2004, 0x080c, 0x2838, 0x60e2, 0x2001,
-+	0xb40c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e,
-+	0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
-+	0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb400, 0x7130,
-+	0xd184, 0x1180, 0x2011, 0xb453, 0x2214, 0xd2ec, 0x0138, 0xc18d,
-+	0x7132, 0x2011, 0xb453, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c,
-+	0x0904, 0x5d29, 0x7130, 0xc185, 0x7132, 0x2011, 0xb453, 0x220c,
-+	0xd1a4, 0x0530, 0x0016, 0x2019, 0x000e, 0x080c, 0xafe8, 0x0156,
-+	0x20a9, 0x007f, 0x2009, 0x0000, 0xa186, 0x007e, 0x01a0, 0xa186,
-+	0x0080, 0x0188, 0x080c, 0x4f6a, 0x1170, 0x8127, 0xa006, 0x0016,
-+	0x2009, 0x000e, 0x080c, 0xb06b, 0x2009, 0x0001, 0x2011, 0x0100,
-+	0x080c, 0x6adf, 0x001e, 0x8108, 0x1f04, 0x5cf4, 0x015e, 0x001e,
-+	0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c,
-+	0x2c33, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
-+	0x080c, 0x4f6a, 0x1110, 0x080c, 0x4bc5, 0x8108, 0x1f04, 0x5d20,
-+	0x015e, 0x080c, 0x1e18, 0x2011, 0x0003, 0x080c, 0x801f, 0x2011,
-+	0x0002, 0x080c, 0x8029, 0x080c, 0x7f03, 0x0036, 0x2019, 0x0000,
-+	0x080c, 0x7f8e, 0x003e, 0x60e3, 0x0000, 0x2001, 0xb400, 0x2003,
-+	0x0001, 0x080c, 0x59c8, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e,
-+	0x001e, 0x015e, 0x0005, 0x2071, 0xb4e2, 0x7003, 0x0000, 0x7007,
-+	0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053,
-+	0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b,
-+	0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071,
-+	0xb4e2, 0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085,
-+	0x0001, 0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e,
-+	0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032,
-+	0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f,
-+	0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028,
-+	0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee,
-+	0x0005, 0x2b78, 0x2071, 0xb4e2, 0x7004, 0x0043, 0x700c, 0x0002,
-+	0x5da5, 0x5d9c, 0x5d9c, 0x5d9c, 0x5d9c, 0x0005, 0x5dfb, 0x5dfc,
-+	0x5e2e, 0x5e2f, 0x5df9, 0x5e7d, 0x5e82, 0x5eb3, 0x5eb4, 0x5ecf,
-+	0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4, 0x5f8a, 0x5fb1, 0x700c,
-+	0x0002, 0x5dbe, 0x5df9, 0x5df9, 0x5dfa, 0x5dfa, 0x7830, 0x7930,
-+	0xa106, 0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a,
-+	0x01f8, 0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c,
-+	0x15db, 0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003,
-+	0x7057, 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xb712,
-+	0x2104, 0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x1657,
-+	0x0005, 0x080c, 0x15db, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15db,
-+	0x1108, 0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004,
-+	0x08f8, 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x5e03, 0x5e06,
-+	0x5e14, 0x5e2d, 0x5e2d, 0x080c, 0x5db7, 0x0005, 0x0126, 0x8001,
-+	0x700e, 0x7058, 0x0006, 0x080c, 0x6304, 0x0120, 0x2091, 0x8000,
-+	0x080c, 0x5db7, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c,
-+	0x6304, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807,
-+	0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db,
-+	0x012e, 0x0005, 0x012e, 0x080c, 0x5ed5, 0x0005, 0x0005, 0x0005,
-+	0x00e6, 0x2071, 0xb4e2, 0x700c, 0x0002, 0x5e3a, 0x5e3a, 0x5e3a,
-+	0x5e3c, 0x5e3f, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f,
-+	0x0002, 0x00ee, 0x0005, 0x5ed5, 0x5ed5, 0x5ef1, 0x5ed5, 0x606e,
-+	0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ef1, 0x60b0, 0x60f3,
-+	0x613c, 0x6150, 0x5ed5, 0x5ed5, 0x5f0d, 0x5ef1, 0x5ed5, 0x5ed5,
-+	0x5f67, 0x61fc, 0x6217, 0x5ed5, 0x5f0d, 0x5ed5, 0x5ed5, 0x5ed5,
-+	0x5ed5, 0x5f5d, 0x6217, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5,
-+	0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5f21, 0x5ed5, 0x5ed5, 0x5ed5,
-+	0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x6322, 0x5ed5,
-+	0x5ed5, 0x5ed5, 0x5ed5, 0x5ed5, 0x5f36, 0x7020, 0x2068, 0x080c,
-+	0x160b, 0x0005, 0x700c, 0x0002, 0x5e89, 0x5e8c, 0x5e9a, 0x5eb2,
-+	0x5eb2, 0x080c, 0x5db7, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058,
-+	0x0006, 0x080c, 0x6304, 0x0120, 0x2091, 0x8000, 0x080c, 0x5db7,
-+	0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x6304, 0x7058,
-+	0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834,
-+	0xa084, 0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005,
-+	0x012e, 0x0419, 0x0005, 0x0005, 0x0005, 0x5ed5, 0x5ef1, 0x605a,
-+	0x5ed5, 0x5ef1, 0x5ed5, 0x5ef1, 0x5ef1, 0x5ed5, 0x5ef1, 0x605a,
-+	0x5ef1, 0x5ef1, 0x5ef1, 0x5ef1, 0x5ef1, 0x5ed5, 0x5ef1, 0x605a,
-+	0x5ed5, 0x5ed5, 0x5ef1, 0x5ed5, 0x5ed5, 0x5ed5, 0x5ef1, 0x0005,
-+	0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838,
-+	0xa084, 0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
-+	0x53c9, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
-+	0xc0e5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x53c9, 0x012e,
-+	0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x53c9, 0x012e, 0x0005, 0x7007,
-+	0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x53c9, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084,
-+	0x00ff, 0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x601a,
-+	0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x601a,
-+	0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0904, 0x5ee3, 0x8001,
-+	0x1120, 0x7007, 0x0001, 0x0804, 0x6037, 0x7007, 0x0006, 0x7012,
-+	0x2d00, 0x7016, 0x701a, 0x704b, 0x6037, 0x0005, 0x6834, 0x8007,
-+	0xa084, 0x00ff, 0xa086, 0x0001, 0x1904, 0x5ee3, 0x7007, 0x0001,
-+	0x2009, 0xb431, 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff,
-+	0x683a, 0x6853, 0x0000, 0x080c, 0x4d3c, 0x1108, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x53c9,
-+	0x012e, 0x0ca0, 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0,
-+	0xa086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x622f, 0x2d00,
-+	0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
-+	0xb50d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5eff,
-+	0x6a84, 0xa28a, 0x0002, 0x1a04, 0x5eff, 0x82ff, 0x1138, 0x6888,
-+	0x698c, 0xa105, 0x0118, 0x2001, 0x5fed, 0x0018, 0xa280, 0x5fe3,
-+	0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, 0x5fcf, 0x080c, 0x15db,
-+	0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060,
-+	0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210,
-+	0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004,
-+	0x0108, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c,
-+	0x163f, 0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118,
-+	0x7007, 0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x160b, 0x7014,
-+	0x2068, 0x0804, 0x5eff, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
-+	0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x5f8a, 0x7014,
-+	0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c,
-+	0xa105, 0x0108, 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
-+	0x0904, 0x622f, 0x04b8, 0x5fe5, 0x5fe9, 0x0002, 0x0011, 0x0007,
-+	0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005,
-+	0x0004, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c,
-+	0x6804, 0x2060, 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005,
-+	0x700c, 0x7816, 0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802,
-+	0x7e0e, 0x7f0a, 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006,
-+	0x0c78, 0x6004, 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee,
-+	0x00fe, 0x0005, 0x2009, 0xb431, 0x210c, 0x81ff, 0x1198, 0x6838,
-+	0xa084, 0x00ff, 0x683a, 0x080c, 0x4c1e, 0x1108, 0x0005, 0x080c,
-+	0x549c, 0x0126, 0x2091, 0x8000, 0x080c, 0x9e5d, 0x080c, 0x53c9,
-+	0x012e, 0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009,
-+	0xb431, 0x210c, 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01c0, 0x6838,
-+	0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4ce0, 0x1108,
-+	0x0005, 0x0126, 0x2091, 0x8000, 0x684a, 0x6952, 0x080c, 0x53c9,
-+	0x012e, 0x0cb0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c90, 0x2001,
-+	0x0000, 0x0c78, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
-+	0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030, 0x7014,
-+	0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, 0x0001,
-+	0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9,
-+	0x0001, 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9, 0x00ff,
-+	0xa096, 0x0002, 0x0178, 0xa005, 0x11f0, 0x6944, 0x810f, 0xa18c,
-+	0x00ff, 0x080c, 0x4f6a, 0x11b8, 0x0066, 0x6e50, 0x080c, 0x5069,
-+	0x006e, 0x0088, 0x0046, 0x2011, 0xb40c, 0x2224, 0xc484, 0x2412,
-+	0x004e, 0x00c6, 0x080c, 0x4f6a, 0x1110, 0x080c, 0x51ca, 0x8108,
-+	0x1f04, 0x609a, 0x00ce, 0x684c, 0xd084, 0x1118, 0x080c, 0x160b,
-+	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x53c9, 0x012e, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xb453, 0x2004,
-+	0xd0a4, 0x0580, 0x2061, 0xb774, 0x6100, 0xd184, 0x0178, 0x6858,
-+	0xa084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0xa005,
-+	0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001,
-+	0x6860, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0x6858,
-+	0xa084, 0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff,
-+	0x0148, 0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e,
-+	0x0804, 0x62f3, 0x012e, 0x0804, 0x62ed, 0x012e, 0x0804, 0x62e7,
-+	0x012e, 0x0804, 0x62ea, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001,
-+	0x2001, 0xb453, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0xb774, 0x6000,
-+	0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, 0xa484,
-+	0x0003, 0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, 0x2100,
-+	0xa210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, 0x02f0,
-+	0xa484, 0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082,
-+	0x0004, 0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, 0x0004,
-+	0x1168, 0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, 0x8000,
-+	0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x62f3, 0x012e, 0x0804,
-+	0x62f0, 0x012e, 0x0804, 0x62ed, 0x0126, 0x2091, 0x8000, 0x7007,
-+	0x0001, 0x2061, 0xb774, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318,
-+	0x0220, 0x630a, 0x012e, 0x0804, 0x6301, 0x012e, 0x0804, 0x62f0,
-+	0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac,
-+	0x0148, 0x00c6, 0x2061, 0xb774, 0x6000, 0xa084, 0xfcff, 0x6002,
-+	0x00ce, 0x0448, 0x6858, 0xa005, 0x05d0, 0x685c, 0xa065, 0x0598,
-+	0x2001, 0xb431, 0x2004, 0xa005, 0x0118, 0x080c, 0x9dae, 0x0068,
-+	0x6013, 0x0400, 0x6057, 0x0000, 0x694c, 0xd1a4, 0x0110, 0x6950,
-+	0x6156, 0x2009, 0x0041, 0x080c, 0x85ef, 0x6958, 0xa18c, 0xff00,
-+	0xa186, 0x2000, 0x1140, 0x0026, 0x2009, 0x0000, 0x2011, 0xfdff,
-+	0x080c, 0x6adf, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061, 0xb774,
-+	0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce,
-+	0x012e, 0x0804, 0x62f3, 0x00ce, 0x012e, 0x0804, 0x62ed, 0x6954,
-+	0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186, 0x0045,
-+	0x0528, 0xa186, 0x002a, 0x1130, 0x2001, 0xb40c, 0x200c, 0xc194,
-+	0x2102, 0x08c8, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029, 0x1d18,
-+	0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4f6a, 0x1960, 0x6000,
-+	0xc0e4, 0x6002, 0x0840, 0x685c, 0xa065, 0x09a8, 0x6007, 0x0024,
-+	0x2001, 0xb6b6, 0x2004, 0x6016, 0x0804, 0x618b, 0x685c, 0xa065,
-+	0x0950, 0x00e6, 0x6860, 0xa075, 0x2001, 0xb431, 0x2004, 0xa005,
-+	0x0150, 0x080c, 0x9dae, 0x8eff, 0x0118, 0x2e60, 0x080c, 0x9dae,
-+	0x00ee, 0x0804, 0x618b, 0x6020, 0xc0dc, 0xc0d5, 0x6022, 0x2e60,
-+	0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b, 0x6874,
-+	0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x6c52, 0x080c,
-+	0x7134, 0x00ee, 0x0804, 0x618b, 0x2061, 0xb774, 0x6000, 0xd084,
-+	0x0190, 0xd08c, 0x1904, 0x6301, 0x0126, 0x2091, 0x8000, 0x6204,
-+	0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x6301, 0x012e, 0x6853,
-+	0x0016, 0x0804, 0x62fa, 0x6853, 0x0007, 0x0804, 0x62fa, 0x6834,
-+	0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5ee3, 0x0078, 0x2030,
-+	0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, 0x0006,
-+	0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x622f, 0x0005, 0x00e6,
-+	0x0126, 0x2091, 0x8000, 0xa03e, 0x2009, 0xb431, 0x210c, 0x81ff,
-+	0x1904, 0x62ad, 0x2009, 0xb40c, 0x210c, 0xd194, 0x1904, 0x62d7,
-+	0x6848, 0x2070, 0xae82, 0xbc00, 0x0a04, 0x62a1, 0x2001, 0xb417,
-+	0x2004, 0xae02, 0x1a04, 0x62a1, 0x711c, 0xa186, 0x0006, 0x1904,
-+	0x6290, 0x7018, 0xa005, 0x0904, 0x62ad, 0x2004, 0xd0e4, 0x1904,
-+	0x62d2, 0x2061, 0xb774, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001,
-+	0x1550, 0x7020, 0xd0dc, 0x1904, 0x62da, 0x6853, 0x0000, 0x6803,
-+	0x0000, 0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4,
-+	0x1904, 0x62dd, 0x2e60, 0x080c, 0x6a3b, 0x012e, 0x00ee, 0x0005,
-+	0x2068, 0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4,
-+	0x1904, 0x62dd, 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853,
-+	0x0006, 0x0804, 0x62fa, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8,
-+	0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4f6a, 0x15d8, 0x6000,
-+	0xd0e4, 0x15c0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002,
-+	0x0498, 0x6853, 0x0008, 0x0480, 0x6853, 0x000e, 0x0468, 0x6853,
-+	0x0017, 0x0450, 0x6853, 0x0035, 0x0438, 0x2001, 0xb472, 0x2004,
-+	0xd0fc, 0x01e8, 0x6848, 0x2070, 0xae82, 0xbc00, 0x02c0, 0x605c,
-+	0xae02, 0x12a8, 0x711c, 0xa186, 0x0006, 0x1188, 0x7018, 0xa005,
-+	0x0170, 0x2004, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0xa086,
-+	0x0007, 0x1904, 0x623a, 0x7003, 0x0002, 0x0804, 0x623a, 0x6853,
-+	0x0028, 0x0010, 0x6853, 0x0029, 0x012e, 0x00ee, 0x0418, 0x6853,
-+	0x002a, 0x0cd0, 0x6853, 0x0045, 0x0cb8, 0x2e60, 0x2019, 0x0002,
-+	0x6017, 0x0014, 0x080c, 0xac63, 0x012e, 0x00ee, 0x0005, 0x2009,
-+	0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028,
-+	0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00,
-+	0xa105, 0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x53c9, 0x012e,
-+	0x0005, 0x080c, 0x160b, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102,
-+	0x0230, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058, 0x7070,
-+	0xa080, 0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000, 0x7076,
-+	0xa085, 0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c, 0x6a32,
-+	0x00de, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x7007,
-+	0x0001, 0x6a44, 0xa282, 0x0004, 0x1a04, 0x636d, 0xd284, 0x0170,
-+	0x6a4c, 0xa290, 0xb535, 0x2204, 0xa065, 0x6004, 0x05e0, 0x8007,
-+	0xa084, 0x00ff, 0xa084, 0x0006, 0x1108, 0x04a8, 0x2c10, 0x080c,
-+	0x856a, 0x1118, 0x080c, 0x9e67, 0x05a0, 0x621a, 0x6844, 0x0002,
-+	0x634c, 0x6351, 0x6354, 0x635a, 0x2019, 0x0002, 0x080c, 0xafe8,
-+	0x0060, 0x080c, 0xaf7f, 0x0048, 0x2019, 0x0002, 0x6950, 0x080c,
-+	0xaf9a, 0x0018, 0x6950, 0x080c, 0xaf7f, 0x080c, 0x85c0, 0x6857,
-+	0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x53c9, 0x012e, 0x001e,
-+	0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0x6857, 0x0006, 0x0c88,
-+	0x6857, 0x0002, 0x0c70, 0x6857, 0x0005, 0x0c58, 0x6857, 0x0004,
-+	0x0c40, 0x6857, 0x0007, 0x0c28, 0x00d6, 0x2011, 0x0004, 0x2204,
-+	0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002, 0x3d08,
-+	0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086, 0x1000,
-+	0x1570, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084,
-+	0xf000, 0xa086, 0x3000, 0x1160, 0xa184, 0xff00, 0x8007, 0xa086,
-+	0x0008, 0x11e8, 0x080c, 0x2d83, 0x11d0, 0x080c, 0x65c4, 0x0098,
-+	0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, 0x0007,
-+	0x1170, 0xac82, 0xbc00, 0x0258, 0x685c, 0xac02, 0x1240, 0x2009,
-+	0x0047, 0x080c, 0x85ef, 0x7a1c, 0xd284, 0x1938, 0x0005, 0xa016,
-+	0x080c, 0x1856, 0x0cc0, 0x0cd8, 0x781c, 0xd08c, 0x0500, 0x0156,
-+	0x0136, 0x0146, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076,
-+	0x1538, 0xa484, 0x7000, 0xa086, 0x1000, 0x11a8, 0x080c, 0x643f,
-+	0x01f8, 0x20e1, 0x3000, 0x7828, 0x7828, 0x080c, 0x645b, 0x014e,
-+	0x013e, 0x015e, 0x2009, 0xb6e8, 0x2104, 0xa005, 0x1108, 0x0005,
-+	0x080c, 0x7134, 0x0ce0, 0xa484, 0x7000, 0x1548, 0x080c, 0x643f,
-+	0x01d8, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0d10, 0x00a0,
-+	0xd5a4, 0x0178, 0x0056, 0x0046, 0x080c, 0x1e3f, 0x080c, 0x2479,
-+	0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x004e, 0x005e,
-+	0x0048, 0x04a9, 0x6887, 0x0000, 0x080c, 0xb362, 0x20e1, 0x3000,
-+	0x7828, 0x7828, 0x00b9, 0x014e, 0x013e, 0x015e, 0x0880, 0x0439,
-+	0x1130, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x1d68, 0x080c,
-+	0xb362, 0x20e1, 0x3000, 0x7828, 0x7828, 0x0056, 0x080c, 0x6839,
-+	0x005e, 0x0c40, 0x2001, 0xb40e, 0x2004, 0xd08c, 0x0178, 0x2001,
-+	0xb400, 0x2004, 0xa086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011,
-+	0x8048, 0x2518, 0x080c, 0x3e8a, 0x003e, 0x002e, 0x0005, 0xa484,
-+	0x01ff, 0x6886, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8,
-+	0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005,
-+	0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
-+	0xa085, 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000,
-+	0x8007, 0xa196, 0x0000, 0x1118, 0x0804, 0x66c9, 0x0005, 0xa196,
-+	0x2000, 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x4449,
-+	0x0ca8, 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6779,
-+	0x0c68, 0x00c6, 0x6a84, 0x82ff, 0x0904, 0x65be, 0x7110, 0xa18c,
-+	0xff00, 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904,
-+	0x65be, 0xa08e, 0x0023, 0x1570, 0x080c, 0x6814, 0x0904, 0x65be,
-+	0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005,
-+	0x1904, 0x65be, 0x2009, 0x0015, 0x080c, 0x85ef, 0x0804, 0x65be,
-+	0xa08e, 0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015,
-+	0x080c, 0x85ef, 0x0804, 0x65be, 0xa08e, 0x0100, 0x1904, 0x65be,
-+	0x7034, 0xa005, 0x1904, 0x65be, 0x2009, 0x0016, 0x080c, 0x85ef,
-+	0x0804, 0x65be, 0xa08e, 0x0022, 0x1904, 0x65be, 0x7030, 0xa08e,
-+	0x0300, 0x1580, 0x68d4, 0xd0a4, 0x0528, 0xc0b5, 0x68d6, 0x7100,
-+	0xa18c, 0x00ff, 0x6972, 0x7004, 0x6876, 0x00f6, 0x2079, 0x0100,
-+	0x79e6, 0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c,
-+	0x280d, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x27e3,
-+	0x6952, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xb400,
-+	0x70a6, 0x00ee, 0x7034, 0xa005, 0x1904, 0x65be, 0x2009, 0x0017,
-+	0x0804, 0x6584, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904,
-+	0x65be, 0x68d4, 0xc0a5, 0x68d6, 0x2009, 0x0030, 0x0804, 0x6584,
-+	0xa08e, 0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x65be, 0x2009,
-+	0x0018, 0x0804, 0x6584, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019,
-+	0x0804, 0x6584, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804,
-+	0x6584, 0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x65be,
-+	0x2009, 0x001b, 0x0804, 0x6584, 0xa08e, 0x5000, 0x1140, 0x7034,
-+	0xa005, 0x1904, 0x65be, 0x2009, 0x001c, 0x0804, 0x6584, 0xa08e,
-+	0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x6584, 0xa08e, 0x1200,
-+	0x1140, 0x7034, 0xa005, 0x1904, 0x65be, 0x2009, 0x0024, 0x0804,
-+	0x6584, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d,
-+	0x04d8, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a,
-+	0x0498, 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e,
-+	0x5300, 0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xba8d,
-+	0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011,
-+	0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3e8a, 0x004e,
-+	0x8108, 0x1f04, 0x6567, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000,
-+	0x1118, 0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009,
-+	0x0045, 0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xba83, 0x2204,
-+	0x8211, 0x220c, 0x080c, 0x27e3, 0x1598, 0x080c, 0x4f0e, 0x1580,
-+	0x6612, 0x6516, 0x86ff, 0x01e8, 0x001e, 0x0016, 0xa186, 0x0017,
-+	0x1158, 0x6870, 0xa606, 0x11a8, 0x6874, 0xa506, 0xa084, 0xff00,
-+	0x1180, 0x6000, 0xc0f5, 0x6002, 0xa186, 0x0046, 0x1150, 0x6870,
-+	0xa606, 0x1138, 0x6874, 0xa506, 0xa084, 0xff00, 0x1110, 0x001e,
-+	0x0068, 0x00c6, 0x080c, 0x856a, 0x0168, 0x001e, 0x611a, 0x601f,
-+	0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x85ef, 0x00ce, 0x0005,
-+	0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046, 0x080c, 0x6618,
-+	0x1904, 0x6615, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6814, 0x0904,
-+	0x6615, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140, 0x7034,
-+	0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x85ef, 0x04b0, 0xa08e,
-+	0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016, 0x080c,
-+	0x85ef, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e, 0x1400,
-+	0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xba83, 0x2204, 0x8211,
-+	0x220c, 0x080c, 0x27e3, 0x11c0, 0x080c, 0x4f0e, 0x11a8, 0x6612,
-+	0x6516, 0x00c6, 0x080c, 0x856a, 0x0170, 0x001e, 0x611a, 0x080c,
-+	0x9fb8, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x85ef,
-+	0x080c, 0x7134, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x0005,
-+	0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156, 0x3c00,
-+	0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1efe, 0x1590,
-+	0x080c, 0x1da1, 0x05e0, 0x04f1, 0x1130, 0x7908, 0xa18c, 0x1fff,
-+	0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0,
-+	0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004,
-+	0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0419, 0x1120,
-+	0xa08a, 0x0140, 0x1a0c, 0x1511, 0x80ac, 0x20e1, 0x6000, 0x2099,
-+	0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, 0x0004,
-+	0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e, 0x001e,
-+	0x002e, 0x00de, 0x00fe, 0x0005, 0xa016, 0x080c, 0x1856, 0xa085,
-+	0x0001, 0x0c80, 0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003,
-+	0x000e, 0x0005, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696,
-+	0x00ff, 0x1198, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804,
-+	0x66c4, 0xa596, 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596,
-+	0xfffc, 0x1118, 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019,
-+	0xb435, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff,
-+	0x2071, 0xb535, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071,
-+	0xb5b6, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd,
-+	0x0080, 0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14,
-+	0x1120, 0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff,
-+	0x0d58, 0x8420, 0x8e70, 0x1f04, 0x66a1, 0x82ff, 0x1118, 0xa085,
-+	0x0001, 0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e,
-+	0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x66d5, 0x66d5, 0x66d5,
-+	0x6826, 0x66d5, 0x66d6, 0x66eb, 0x6764, 0x0005, 0x7110, 0xd1bc,
-+	0x0188, 0x7120, 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xbc00,
-+	0x0248, 0x685c, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046,
-+	0x080c, 0x85ef, 0x0005, 0x00c6, 0xa484, 0x01ff, 0x0904, 0x6742,
-+	0x7110, 0xd1bc, 0x1904, 0x6742, 0x2011, 0xba83, 0x2204, 0x8211,
-+	0x220c, 0x080c, 0x27e3, 0x1904, 0x6742, 0x080c, 0x4f0e, 0x1904,
-+	0x6742, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0, 0x6204, 0xa294,
-+	0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c, 0x5a90, 0x11d0,
-+	0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0, 0xa295, 0x0600,
-+	0x6206, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0530, 0x611a, 0x601f,
-+	0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009, 0x0044, 0x080c,
-+	0x85ef, 0x00c0, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0198, 0x611a,
-+	0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x1118, 0x6007,
-+	0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x6c98,
-+	0x080c, 0x7134, 0x00ce, 0x0005, 0x2001, 0xb40d, 0x2004, 0xd0ec,
-+	0x0120, 0x2011, 0x8049, 0x080c, 0x3e8a, 0x00c6, 0x080c, 0x9e67,
-+	0x001e, 0x0d80, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130,
-+	0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
-+	0x6c52, 0x080c, 0x7134, 0x08f0, 0x7110, 0xd1bc, 0x0188, 0x7020,
-+	0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xbc00, 0x0248, 0x685c,
-+	0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0x85ef,
-+	0x0005, 0x0006, 0x080c, 0x2d83, 0x000e, 0x1168, 0x7110, 0xa18c,
-+	0xff00, 0x810f, 0xa18e, 0x0000, 0x1130, 0xa084, 0x000f, 0xa08a,
-+	0x0006, 0x1208, 0x000b, 0x0005, 0x6792, 0x6793, 0x6792, 0x6792,
-+	0x67fc, 0x6808, 0x0005, 0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084,
-+	0x0904, 0x67fb, 0x700c, 0x7108, 0x080c, 0x27e3, 0x1904, 0x67fb,
-+	0x080c, 0x4f0e, 0x1904, 0x67fb, 0x6612, 0x6516, 0x6204, 0x7110,
-+	0xd1bc, 0x01f8, 0xa28c, 0x00ff, 0xa186, 0x0004, 0x0118, 0xa186,
-+	0x0006, 0x15c8, 0x00c6, 0x080c, 0x6814, 0x00ce, 0x0904, 0x67fb,
-+	0x00c6, 0x080c, 0x856a, 0x001e, 0x05f0, 0x611a, 0x080c, 0x9fb8,
-+	0x601f, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x85ef,
-+	0x0490, 0xa28c, 0x00ff, 0xa186, 0x0006, 0x0160, 0xa186, 0x0004,
-+	0x0148, 0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0118, 0xa286,
-+	0x0006, 0x1188, 0x00c6, 0x080c, 0x856a, 0x001e, 0x01e0, 0x611a,
-+	0x080c, 0x9fb8, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
-+	0x080c, 0x85ef, 0x0080, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0158,
-+	0x611a, 0x080c, 0x9fb8, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
-+	0x0001, 0x080c, 0x85ef, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1,
-+	0x0130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x85ef, 0x0005,
-+	0x7110, 0xd1bc, 0x0140, 0x0041, 0x0130, 0x7124, 0x610a, 0x2009,
-+	0x008a, 0x080c, 0x85ef, 0x0005, 0x7020, 0x2060, 0xac84, 0x0007,
-+	0x1158, 0xac82, 0xbc00, 0x0240, 0x2001, 0xb417, 0x2004, 0xac02,
-+	0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x7110, 0xd1bc,
-+	0x1178, 0x7024, 0x2060, 0xac84, 0x0007, 0x1150, 0xac82, 0xbc00,
-+	0x0238, 0x685c, 0xac02, 0x1220, 0x2009, 0x0051, 0x080c, 0x85ef,
-+	0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049,
-+	0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009,
-+	0x0005, 0x00c6, 0x00d6, 0x00f6, 0x7000, 0xa084, 0xf000, 0xa086,
-+	0xc000, 0x05b0, 0x080c, 0x856a, 0x0598, 0x0066, 0x00c6, 0x0046,
-+	0x2011, 0xba83, 0x2204, 0x8211, 0x220c, 0x080c, 0x27e3, 0x1580,
-+	0x080c, 0x4f0e, 0x1568, 0x6612, 0x6516, 0x2c00, 0x004e, 0x00ce,
-+	0x601a, 0x080c, 0x9fb8, 0x080c, 0x15f4, 0x01f0, 0x2d00, 0x6056,
-+	0x6803, 0x0000, 0x6837, 0x0000, 0x6c3a, 0xadf8, 0x000f, 0x20a9,
-+	0x000e, 0x2fa0, 0x2e98, 0x53a3, 0x006e, 0x6612, 0x6007, 0x003e,
-+	0x601f, 0x0001, 0x6003, 0x0001, 0x080c, 0x6c98, 0x080c, 0x7134,
-+	0x00fe, 0x00de, 0x00ce, 0x0005, 0x080c, 0x85c0, 0x006e, 0x0cc0,
-+	0x004e, 0x00ce, 0x0cc8, 0x2071, 0xb6f3, 0x7003, 0x0003, 0x700f,
-+	0x0361, 0xa006, 0x701a, 0x7076, 0x7012, 0x7017, 0xbc00, 0x7007,
-+	0x0000, 0x7026, 0x702b, 0x7d3b, 0x7032, 0x7037, 0x7d9b, 0x703b,
-+	0xffff, 0x703f, 0xffff, 0x7042, 0x7047, 0x4405, 0x704a, 0x705b,
-+	0x69f0, 0x2001, 0xb6a1, 0x2003, 0x0003, 0x2001, 0xb6a3, 0x2003,
-+	0x0100, 0x3a00, 0xa084, 0x0005, 0x706e, 0x0005, 0x2071, 0xb6f3,
-+	0x1d04, 0x6950, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1518,
-+	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x7040,
-+	0xa00d, 0x0128, 0x8109, 0x7142, 0x1110, 0x7044, 0x080f, 0x00c6,
-+	0x2061, 0xb400, 0x6034, 0x00ce, 0xd0cc, 0x0180, 0x3a00, 0xa084,
-+	0x0005, 0x726c, 0xa216, 0x0150, 0x706e, 0x2011, 0x8043, 0x2018,
-+	0x080c, 0x3e8a, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0xa00d,
-+	0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109,
-+	0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110,
-+	0x7028, 0x080f, 0x7030, 0xa00d, 0x0180, 0x702c, 0x8001, 0x702e,
-+	0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0xa184, 0x007f,
-+	0x090c, 0x7de0, 0x0010, 0x7034, 0x080f, 0x7038, 0xa005, 0x0118,
-+	0x0310, 0x8001, 0x703a, 0x703c, 0xa005, 0x0118, 0x0310, 0x8001,
-+	0x703e, 0x704c, 0xa00d, 0x0168, 0x7048, 0x8001, 0x704a, 0x1148,
-+	0x704b, 0x0009, 0x8109, 0x714e, 0x1120, 0x7150, 0x714e, 0x7058,
-+	0x080f, 0x7018, 0xa00d, 0x01d8, 0x0016, 0x7074, 0xa00d, 0x0158,
-+	0x7070, 0x8001, 0x7072, 0x1138, 0x7073, 0x0009, 0x8109, 0x7176,
-+	0x1110, 0x7078, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138,
-+	0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e,
-+	0x7004, 0x0002, 0x6976, 0x6977, 0x698f, 0x00e6, 0x2071, 0xb6f3,
-+	0x7018, 0xa005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
-+	0x0005, 0x00e6, 0x0006, 0x2071, 0xb6f3, 0x701c, 0xa206, 0x1110,
-+	0x701a, 0x701e, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xb6f3,
-+	0x6088, 0xa102, 0x0208, 0x618a, 0x00ee, 0x0005, 0x0005, 0x7110,
-+	0x080c, 0x4f6a, 0x1158, 0x6088, 0x8001, 0x0240, 0x608a, 0x1130,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x8108, 0xa182,
-+	0x00ff, 0x0218, 0xa00e, 0x7007, 0x0002, 0x7112, 0x0005, 0x7014,
-+	0x2060, 0x0126, 0x2091, 0x8000, 0x603c, 0xa005, 0x0128, 0x8001,
-+	0x603e, 0x1110, 0x080c, 0x9ea6, 0x6014, 0xa005, 0x0500, 0x8001,
-+	0x6016, 0x11e8, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006,
-+	0x11a0, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0270, 0xa082,
-+	0x1999, 0x6856, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003,
-+	0x800b, 0x810b, 0xa108, 0x6116, 0x0010, 0x080c, 0x997e, 0x012e,
-+	0xac88, 0x0018, 0x7116, 0x2001, 0xec00, 0xa102, 0x0220, 0x7017,
-+	0xbc00, 0x7007, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb6f3, 0x7027,
-+	0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0xb6fc, 0x2003,
-+	0x0000, 0x0005, 0x00e6, 0x2071, 0xb6f3, 0x7132, 0x702f, 0x0009,
-+	0x00ee, 0x0005, 0x2011, 0xb6ff, 0x2013, 0x0000, 0x0005, 0x00e6,
-+	0x2071, 0xb6f3, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005,
-+	0x00c6, 0x0026, 0x7054, 0x8000, 0x7056, 0x2061, 0xb6a1, 0x6008,
-+	0xa086, 0x0000, 0x0158, 0x7068, 0x6032, 0x7064, 0x602e, 0x7060,
-+	0x602a, 0x705c, 0x6026, 0x2c10, 0x080c, 0x163f, 0x002e, 0x00ce,
-+	0x0005, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c,
-+	0x68be, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x0005,
-+	0x00e6, 0x2071, 0xb6f3, 0x7176, 0x727a, 0x7073, 0x0009, 0x00ee,
-+	0x0005, 0x00e6, 0x0006, 0x2071, 0xb6f3, 0x7078, 0xa206, 0x1110,
-+	0x7076, 0x707a, 0x000e, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb774,
-+	0x00ce, 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080,
-+	0xb774, 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001,
-+	0x1999, 0xa005, 0x1150, 0x00c6, 0x2061, 0xb774, 0x6014, 0x00ce,
-+	0xa005, 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108,
-+	0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
-+	0x00c0, 0xa18e, 0x00c0, 0x05e8, 0xd0b4, 0x1138, 0xd0bc, 0x1550,
-+	0x2009, 0x0006, 0x080c, 0x6ab6, 0x0005, 0xd0fc, 0x0138, 0xa084,
-+	0x0003, 0x0120, 0xa086, 0x0003, 0x1904, 0x6ab0, 0x6020, 0xd0d4,
-+	0x0130, 0xc0d4, 0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009,
-+	0xb474, 0x2104, 0xd084, 0x0138, 0x87ff, 0x1120, 0x2009, 0x0042,
-+	0x080c, 0x85ef, 0x0005, 0x87ff, 0x1120, 0x2009, 0x0043, 0x080c,
-+	0x85ef, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003, 0x0118, 0xa086,
-+	0x0003, 0x11f0, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0x85ef,
-+	0x0005, 0xd0fc, 0x0160, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0148,
-+	0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0x85ef, 0x0005, 0x0061,
-+	0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0x85ef, 0x0cb0,
-+	0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x00d6, 0x6010,
-+	0xa0ec, 0xf000, 0x0510, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186,
-+	0x0001, 0x1188, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x1158,
-+	0x00c6, 0x2061, 0xb774, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210,
-+	0x0208, 0x6206, 0x00ce, 0x080c, 0x53c9, 0x6010, 0xa06d, 0x0076,
-+	0x2039, 0x0000, 0x190c, 0x6a3b, 0x007e, 0x00de, 0x0005, 0x0156,
-+	0x00c6, 0x2061, 0xb774, 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008,
-+	0xa204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138,
-+	0x6808, 0xa005, 0x0120, 0x8001, 0x680a, 0xa085, 0x0001, 0x0005,
-+	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
-+	0x1f04, 0x6afc, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
-+	0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
-+	0x1220, 0x1f04, 0x6b0c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
-+	0x6b0c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
-+	0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091,
-+	0x2800, 0x2079, 0xb6e0, 0x012e, 0x00d6, 0x2069, 0xb6e0, 0x6803,
-+	0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de,
-+	0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002,
-+	0x6b4a, 0x6b6b, 0x6bbe, 0x6b50, 0x6b6b, 0x6b4a, 0x6b48, 0x6b48,
-+	0x080c, 0x1511, 0x080c, 0x69d5, 0x080c, 0x7134, 0x00ce, 0x0005,
-+	0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x4a96, 0x080c,
-+	0x6961, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c,
-+	0x4ad0, 0x0c88, 0x080c, 0x4a96, 0x7807, 0x0003, 0x7827, 0x0000,
-+	0x782b, 0x0000, 0x0c40, 0x080c, 0x69d5, 0x3c00, 0x0006, 0x2011,
-+	0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178,
-+	0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c,
-+	0x1511, 0x2009, 0x0013, 0x080c, 0x85ef, 0x00ce, 0x0005, 0x3900,
-+	0xa082, 0xb82c, 0x1210, 0x080c, 0x82d5, 0x00c6, 0x7824, 0xa065,
-+	0x090c, 0x1511, 0x7804, 0xa086, 0x0004, 0x0904, 0x6bfe, 0x7828,
-+	0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7d17,
-+	0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xb400,
-+	0x70e0, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100,
-+	0x2071, 0xb400, 0x080c, 0x4ad9, 0x00ee, 0x00ce, 0x080c, 0xb3c7,
-+	0x2009, 0x0014, 0x080c, 0x85ef, 0x00ce, 0x0838, 0x2001, 0xb6fc,
-+	0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
-+	0xa065, 0x090c, 0x1511, 0x2009, 0x0013, 0x080c, 0x8643, 0x00ce,
-+	0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb82c, 0x1210, 0x080c,
-+	0x82d5, 0x7824, 0xa005, 0x090c, 0x1511, 0x781c, 0xa06d, 0x090c,
-+	0x1511, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x85c0,
-+	0x693c, 0x81ff, 0x090c, 0x1511, 0x8109, 0x693e, 0x6854, 0xa015,
-+	0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827,
-+	0x0000, 0x00de, 0x00ce, 0x080c, 0x7134, 0x0888, 0x6104, 0xa186,
-+	0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x6b97, 0x7808,
-+	0xac06, 0x0904, 0x6b97, 0x080c, 0x7055, 0x080c, 0x6c98, 0x00ce,
-+	0x080c, 0x7134, 0x0804, 0x6b85, 0x00c6, 0x6027, 0x0002, 0x62c8,
-+	0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009,
-+	0x0049, 0x080c, 0x85ef, 0x00ce, 0x0005, 0x2011, 0xb6ff, 0x2013,
-+	0x0000, 0x0cc8, 0x3908, 0xa192, 0xb82c, 0x1210, 0x080c, 0x82d5,
-+	0x793c, 0x81ff, 0x0d90, 0x7944, 0xa192, 0x7530, 0x12b8, 0x8108,
-+	0x7946, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x1138,
-+	0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016, 0x08e0, 0x6014,
-+	0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08a8, 0x7848, 0xc085,
-+	0x784a, 0x0888, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000,
-+	0x600f, 0x0000, 0x2c08, 0x2061, 0xb6e0, 0x6020, 0x8000, 0x6022,
-+	0x6010, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e,
-+	0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6,
-+	0x2069, 0xb6e0, 0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822,
-+	0xa086, 0x0001, 0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007,
-+	0x0804, 0x713a, 0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056,
-+	0x605b, 0x0000, 0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069,
-+	0xb6e0, 0x0c18, 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8,
-+	0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
-+	0x2c08, 0x2061, 0xb6e0, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005,
-+	0x0148, 0xa080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e,
-+	0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000,
-+	0x2c08, 0x2061, 0xb6e0, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003,
-+	0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6,
-+	0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026,
-+	0x0016, 0x0006, 0x0126, 0xa02e, 0x2071, 0xb6e0, 0x7638, 0x2660,
-+	0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x6d40, 0x6018, 0xa080,
-+	0x0028, 0x2004, 0xa206, 0x1904, 0x6d3b, 0x87ff, 0x0120, 0x6050,
-+	0xa106, 0x1904, 0x6d3b, 0x703c, 0xac06, 0x1190, 0x0036, 0x2019,
-+	0x0001, 0x080c, 0x7f8e, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043,
-+	0x0000, 0x7047, 0x0000, 0x704b, 0x0000, 0x003e, 0x2029, 0x0001,
-+	0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140,
-+	0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x080c, 0x9beb, 0x01c8, 0x6010, 0x2068, 0x601c,
-+	0xa086, 0x0003, 0x1580, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-+	0x0016, 0x0036, 0x0076, 0x080c, 0x9e5d, 0x080c, 0xb303, 0x080c,
-+	0x53c9, 0x007e, 0x003e, 0x001e, 0x080c, 0x9da2, 0x080c, 0x9dae,
-+	0x00ce, 0x0804, 0x6cdb, 0x2c78, 0x600c, 0x2060, 0x0804, 0x6cdb,
-+	0x85ff, 0x0120, 0x0036, 0x080c, 0x71f1, 0x003e, 0x012e, 0x000e,
-+	0x001e, 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de,
-+	0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1158, 0x0016,
-+	0x0036, 0x0076, 0x080c, 0xb303, 0x080c, 0xb01c, 0x007e, 0x003e,
-+	0x001e, 0x08a0, 0x601c, 0xa086, 0x000a, 0x0904, 0x6d25, 0x0804,
-+	0x6d23, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x00f6, 0x2031, 0x0000,
-+	0x0126, 0x2091, 0x8000, 0x2079, 0xb6e0, 0x7838, 0xa065, 0x0568,
-+	0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0xac06, 0x1180, 0x0036,
-+	0x2019, 0x0001, 0x080c, 0x7f8e, 0x7833, 0x0000, 0x783f, 0x0000,
-+	0x7843, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x003e, 0x080c,
-+	0x9beb, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x53c9, 0x080c,
-+	0x9da2, 0x080c, 0x9dae, 0x000e, 0x0888, 0x7e3a, 0x7e36, 0x012e,
-+	0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086,
-+	0x0006, 0x1118, 0x080c, 0xb01c, 0x0c60, 0x601c, 0xa086, 0x000a,
-+	0x0d08, 0x08f0, 0x0016, 0x0026, 0x0086, 0x2041, 0x0000, 0x0099,
-+	0x080c, 0x6e88, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126,
-+	0x2079, 0xb6e0, 0x2091, 0x8000, 0x080c, 0x6f15, 0x080c, 0x6f87,
-+	0x012e, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
-+	0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb6e0, 0x7614,
-+	0x2660, 0x2678, 0x8cff, 0x0904, 0x6e5e, 0x6018, 0xa080, 0x0028,
-+	0x2004, 0xa206, 0x1904, 0x6e59, 0x88ff, 0x0120, 0x6050, 0xa106,
-+	0x1904, 0x6e59, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0,
-+	0xa005, 0x01f0, 0x080c, 0x69d5, 0x080c, 0x7d24, 0x68c3, 0x0000,
-+	0x080c, 0x81f0, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-+	0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
-+	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020,
-+	0x6003, 0x0009, 0x630a, 0x04e8, 0x7014, 0xac36, 0x1110, 0x660c,
-+	0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
-+	0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06,
-+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x01b8, 0x601c, 0xa086, 0x0003, 0x1540, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c,
-+	0x9e5d, 0x080c, 0xb303, 0x080c, 0x53c9, 0x008e, 0x003e, 0x001e,
-+	0x080c, 0x9da2, 0x080c, 0x9dae, 0x080c, 0x80c8, 0x00ce, 0x0804,
-+	0x6de2, 0x2c78, 0x600c, 0x2060, 0x0804, 0x6de2, 0x012e, 0x000e,
-+	0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c,
-+	0xa086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xb303,
-+	0x080c, 0xb01c, 0x008e, 0x003e, 0x001e, 0x08e0, 0x601c, 0xa086,
-+	0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0908, 0x0898, 0x601c,
-+	0xa086, 0x0005, 0x1978, 0x6004, 0xa086, 0x0085, 0x0d20, 0x0850,
-+	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xb535, 0x2004,
-+	0xa065, 0x0904, 0x6f11, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071,
-+	0xb6e0, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c, 0xac06,
-+	0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0x6058,
-+	0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00, 0x685a,
-+	0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002,
-+	0x080c, 0x4e95, 0x0904, 0x6f0d, 0x7624, 0x86ff, 0x05e8, 0xa680,
-+	0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0,
-+	0xa005, 0x0548, 0x080c, 0x69d5, 0x080c, 0x7d24, 0x68c3, 0x0000,
-+	0x080c, 0x81f0, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-+	0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
-+	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de,
-+	0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c,
-+	0x9dae, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
-+	0x630a, 0x00ce, 0x0804, 0x6eb8, 0x8dff, 0x0158, 0x6837, 0x0103,
-+	0x6b4a, 0x6847, 0x0000, 0x080c, 0x9e5d, 0x080c, 0xb303, 0x080c,
-+	0x53c9, 0x080c, 0x80c8, 0x0804, 0x6eb8, 0x006e, 0x00de, 0x00ee,
-+	0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066, 0x00c6,
-+	0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6f67, 0x600c,
-+	0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069, 0x0100,
-+	0x68c0, 0xa005, 0x01f0, 0x080c, 0x69d5, 0x080c, 0x7d24, 0x68c3,
-+	0x0000, 0x080c, 0x81f0, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140,
-+	0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-+	0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x53c9, 0x080c, 0x9da2,
-+	0x080c, 0x9dae, 0x080c, 0x80c8, 0x000e, 0x0804, 0x6f1c, 0x7e16,
-+	0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086,
-+	0x0006, 0x1118, 0x080c, 0xb01c, 0x0c58, 0x601c, 0xa086, 0x0002,
-+	0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c, 0xa086,
-+	0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8, 0x0006,
-+	0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6fed, 0x6054,
-+	0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
-+	0x6002, 0x080c, 0x4e95, 0x0904, 0x6fea, 0x7e24, 0x86ff, 0x05e8,
-+	0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
-+	0x68c0, 0xa005, 0x0548, 0x080c, 0x69d5, 0x080c, 0x7d24, 0x68c3,
-+	0x0000, 0x080c, 0x81f0, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140,
-+	0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-+	0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
-+	0x080c, 0x9dae, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
-+	0x0009, 0x630a, 0x00ce, 0x0804, 0x6f99, 0x8dff, 0x0138, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x53c9, 0x080c, 0x80c8,
-+	0x0804, 0x6f99, 0x000e, 0x0804, 0x6f8c, 0x781e, 0x781a, 0x00de,
-+	0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000,
-+	0xd0dc, 0x01a0, 0x604c, 0xa06d, 0x0188, 0x6848, 0xa606, 0x1170,
-+	0x2071, 0xb6e0, 0x7024, 0xa035, 0x0148, 0xa080, 0x0004, 0x2004,
-+	0xad06, 0x1120, 0x6000, 0xc0dc, 0x6002, 0x0021, 0x006e, 0x00de,
-+	0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138,
-+	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c,
-+	0x7d24, 0x78c3, 0x0000, 0x080c, 0x81f0, 0x7027, 0x0000, 0x0036,
-+	0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100,
-+	0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827,
-+	0x0001, 0x080c, 0x81f0, 0x003e, 0x080c, 0x4e95, 0x00c6, 0x603c,
-+	0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x85c0, 0x00ce,
-+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x9e5d, 0x080c,
-+	0x53c9, 0x080c, 0x80c8, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071,
-+	0xb6e0, 0x7004, 0xa084, 0x0007, 0x0002, 0x7067, 0x706a, 0x7080,
-+	0x7099, 0x70d2, 0x7067, 0x7065, 0x7065, 0x080c, 0x1511, 0x00ce,
-+	0x00ee, 0x0005, 0x7024, 0xa065, 0x0148, 0x7020, 0x8001, 0x7022,
-+	0x600c, 0xa015, 0x0150, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000,
-+	0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0,
-+	0x6018, 0x2060, 0x080c, 0x4e95, 0x6000, 0xc0dc, 0x6002, 0x7020,
-+	0x8001, 0x7022, 0x0120, 0x6054, 0xa015, 0x0140, 0x721e, 0x7007,
-+	0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e,
-+	0x0cb0, 0x7024, 0xa065, 0x0598, 0x700c, 0xac06, 0x1160, 0x080c,
-+	0x80c8, 0x600c, 0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428,
-+	0x720e, 0x720a, 0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x80c8,
-+	0x600c, 0xa015, 0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216,
-+	0x7212, 0x0098, 0x6018, 0x2060, 0x080c, 0x4e95, 0x6000, 0xc0dc,
-+	0x6002, 0x080c, 0x80c8, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015,
-+	0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce,
-+	0x00ee, 0x0005, 0x7024, 0xa065, 0x0140, 0x080c, 0x80c8, 0x600c,
-+	0xa015, 0x0150, 0x720e, 0x600f, 0x0000, 0x080c, 0x81f0, 0x7027,
-+	0x0000, 0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6,
-+	0x2069, 0xb6e0, 0x6830, 0xa084, 0x0003, 0x0002, 0x70f4, 0x70f6,
-+	0x711a, 0x70f2, 0x080c, 0x1511, 0x00de, 0x0005, 0x00c6, 0x6840,
-+	0xa086, 0x0001, 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015,
-+	0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
-+	0x2011, 0xb6ff, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a,
-+	0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003,
-+	0x0003, 0x0c50, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x684b,
-+	0x0000, 0x683c, 0xa065, 0x0168, 0x600c, 0xa015, 0x0130, 0x6a3a,
-+	0x600f, 0x0000, 0x683f, 0x0000, 0x0020, 0x683f, 0x0000, 0x683a,
-+	0x6836, 0x00ce, 0x00de, 0x0005, 0x00d6, 0x2069, 0xb6e0, 0x6804,
-+	0xa084, 0x0007, 0x0002, 0x7145, 0x71e1, 0x71e1, 0x71e1, 0x71e1,
-+	0x71e3, 0x7143, 0x7143, 0x080c, 0x1511, 0x6820, 0xa005, 0x1110,
-+	0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0150, 0x6807, 0x0004,
-+	0x6826, 0x682b, 0x0000, 0x080c, 0x7233, 0x00ce, 0x00de, 0x0005,
-+	0x6814, 0xa065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000,
-+	0x080c, 0x7233, 0x00ce, 0x00de, 0x0005, 0x00e6, 0x0036, 0x6a1c,
-+	0xa2f5, 0x0000, 0x0904, 0x71dd, 0x704c, 0xa00d, 0x0118, 0x7088,
-+	0xa005, 0x01a0, 0x7054, 0xa075, 0x0120, 0xa20e, 0x0904, 0x71dd,
-+	0x0028, 0x6818, 0xa20e, 0x0904, 0x71dd, 0x2070, 0x704c, 0xa00d,
-+	0x0d88, 0x7088, 0xa005, 0x1d70, 0x2e00, 0x681e, 0x733c, 0x7038,
-+	0xa302, 0x1e40, 0x080c, 0x8597, 0x0904, 0x71dd, 0x8318, 0x733e,
-+	0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
-+	0x605a, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
-+	0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
-+	0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0, 0x2001, 0xb435,
-+	0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100, 0xd1f4, 0x0120,
-+	0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0,
-+	0x2d88, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x080c,
-+	0x785c, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
-+	0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
-+	0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e, 0x00ee, 0x00ce,
-+	0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0138, 0x6807,
-+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x7233, 0x00ce, 0x00de,
-+	0x0005, 0x00f6, 0x00d6, 0x2069, 0xb6e0, 0x6830, 0xa086, 0x0000,
-+	0x11d0, 0x2001, 0xb40c, 0x200c, 0xd1bc, 0x1560, 0x6838, 0xa07d,
-+	0x0190, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000,
-+	0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1ff2, 0x1130,
-+	0x012e, 0x080c, 0x7b95, 0x00de, 0x00fe, 0x0005, 0x012e, 0xe000,
-+	0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0140, 0x6a3a,
-+	0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c60, 0x683a,
-+	0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x0066, 0x2031, 0x0001, 0x080c,
-+	0x5b12, 0x006e, 0x0858, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005,
-+	0x7241, 0x7246, 0x76fd, 0x7819, 0x7246, 0x76fd, 0x7819, 0x7241,
-+	0x7246, 0x080c, 0x7055, 0x080c, 0x7134, 0x0005, 0x0156, 0x0136,
-+	0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x1511,
-+	0x6118, 0x2178, 0x79a0, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110,
-+	0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff,
-+	0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2d88, 0x2f0d, 0xa18c,
-+	0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04,
-+	0x72ba, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005,
-+	0x7369, 0x73b4, 0x73e1, 0x74ae, 0x74dc, 0x74e4, 0x750a, 0x751b,
-+	0x752c, 0x7534, 0x754a, 0x7534, 0x75a4, 0x751b, 0x75c5, 0x75cd,
-+	0x752c, 0x75cd, 0x75de, 0x72b8, 0x72b8, 0x72b8, 0x72b8, 0x72b8,
-+	0x72b8, 0x72b8, 0x72b8, 0x72b8, 0x72b8, 0x72b8, 0x7e2f, 0x7e54,
-+	0x7e69, 0x7e8c, 0x7ead, 0x750a, 0x72b8, 0x750a, 0x7534, 0x72b8,
-+	0x73e1, 0x74ae, 0x72b8, 0x82f2, 0x7534, 0x72b8, 0x8312, 0x7534,
-+	0x72b8, 0x752c, 0x7362, 0x72cd, 0x72b8, 0x8337, 0x83ac, 0x8483,
-+	0x72b8, 0x8494, 0x7505, 0x84b0, 0x72b8, 0x7ec2, 0x850b, 0x72b8,
-+	0x080c, 0x1511, 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e,
-+	0x015e, 0x0005, 0x72cb, 0x72cb, 0x72cb, 0x7301, 0x731f, 0x7335,
-+	0x72cb, 0x72cb, 0x72cb, 0x080c, 0x1511, 0x00d6, 0x20a1, 0x020b,
-+	0x080c, 0x75fb, 0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3, 0x0018,
-+	0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854, 0x20a2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7d11,
-+	0x00de, 0x0005, 0x00d6, 0x7818, 0x2068, 0x68a0, 0x2069, 0xb400,
-+	0x6ad4, 0xd2ac, 0x1110, 0xd0bc, 0x0110, 0xa085, 0x0001, 0x00de,
-+	0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x75fb, 0x20a3, 0x0500,
-+	0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2, 0x680c,
-+	0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, 0x681c,
-+	0x20a2, 0x60c3, 0x0010, 0x080c, 0x7d11, 0x00de, 0x0005, 0x0156,
-+	0x0146, 0x20a1, 0x020b, 0x080c, 0x75fb, 0x20a3, 0x7800, 0x20a3,
-+	0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0008,
-+	0x080c, 0x7d11, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1,
-+	0x020b, 0x080c, 0x7697, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3,
-+	0xdf10, 0x20a3, 0x0034, 0x2099, 0xb405, 0x20a9, 0x0004, 0x53a6,
-+	0x2099, 0xb401, 0x20a9, 0x0004, 0x53a6, 0x2099, 0xb6c6, 0x20a9,
-+	0x001a, 0x3304, 0x8007, 0x20a2, 0x9398, 0x1f04, 0x7351, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c, 0x080c, 0x7d11, 0x014e,
-+	0x015e, 0x0005, 0x2001, 0xb415, 0x2004, 0x609a, 0x080c, 0x7d11,
-+	0x0005, 0x20a1, 0x020b, 0x080c, 0x75fb, 0x20a3, 0x5200, 0x20a3,
-+	0x0000, 0x00d6, 0x2069, 0xb452, 0x6804, 0xd084, 0x0150, 0x6828,
-+	0x20a3, 0x0000, 0x0016, 0x080c, 0x27f7, 0x21a2, 0x001e, 0x00de,
-+	0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004,
-+	0x2099, 0xb405, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb401, 0x53a6,
-+	0x2001, 0xb435, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa082, 0x007f, 0x0238, 0x2001, 0xb41c, 0x20a6, 0x2001,
-+	0xb41d, 0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xb415, 0x2004,
-+	0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x001c, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c, 0x75fb,
-+	0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0xb435, 0x2004, 0xd0ac,
-+	0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238,
-+	0x2001, 0xb41c, 0x20a6, 0x2001, 0xb41d, 0x20a6, 0x0040, 0x20a3,
-+	0x0000, 0x2001, 0xb415, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a9,
-+	0x0004, 0x2099, 0xb405, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x7d11,
-+	0x0005, 0x20a1, 0x020b, 0x080c, 0x75fb, 0x00c6, 0x7818, 0x2060,
-+	0x2001, 0x0000, 0x080c, 0x52d4, 0x00ce, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0xa086, 0x007e, 0x1130, 0x20a3, 0x0400, 0x620c, 0xc2b4,
-+	0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, 0xa080,
-+	0x0028, 0x2004, 0xa086, 0x007e, 0x1904, 0x7470, 0x2001, 0xb435,
-+	0x2004, 0xd0a4, 0x01c8, 0x2099, 0xb68e, 0x33a6, 0x9398, 0x20a3,
-+	0x0000, 0x9398, 0x3304, 0xa084, 0x2000, 0x20a2, 0x9398, 0x33a6,
-+	0x9398, 0x20a3, 0x0000, 0x9398, 0x2001, 0x2710, 0x20a2, 0x9398,
-+	0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099, 0xb68e, 0x33a6, 0x9398,
-+	0x33a6, 0x9398, 0x3304, 0x080c, 0x5a90, 0x1118, 0xa084, 0x37ff,
-+	0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004,
-+	0x2099, 0xb405, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb401, 0x53a6,
-+	0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x744a, 0x20a9, 0x0008,
-+	0x20a3, 0x0000, 0x1f04, 0x7450, 0x2099, 0xb696, 0x3304, 0xc0dd,
-+	0x20a2, 0x2001, 0xb472, 0x2004, 0xd0e4, 0x0158, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004,
-+	0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x1f04, 0x746b, 0x0468,
-+	0x2001, 0xb435, 0x2004, 0xd0a4, 0x0140, 0x2001, 0xb68f, 0x2004,
-+	0x60e3, 0x0000, 0x080c, 0x2838, 0x60e2, 0x2099, 0xb68e, 0x20a9,
-+	0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb405, 0x53a6, 0x20a9,
-+	0x0004, 0x2099, 0xb401, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000,
-+	0x1f04, 0x748e, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x7494,
-+	0x2099, 0xb696, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3,
-+	0x0000, 0x1f04, 0x749f, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04,
-+	0x74a5, 0x60c3, 0x0074, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b,
-+	0x080c, 0x75fb, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800,
-+	0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
-+	0x00f6, 0x2079, 0xb452, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085,
-+	0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0xa085, 0x0002, 0x00d6,
-+	0x0804, 0x7586, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-+	0x0014, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c, 0x75fb,
-+	0x20a3, 0x5000, 0x0804, 0x73fc, 0x20a1, 0x020b, 0x080c, 0x75fb,
-+	0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c,
-+	0x768f, 0x0020, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3, 0x0200,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
-+	0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3,
-+	0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
-+	0x0008, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7697,
-+	0x20a3, 0x0200, 0x0804, 0x73fc, 0x20a1, 0x020b, 0x080c, 0x7697,
-+	0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0110, 0x20a2,
-+	0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c,
-+	0x7d11, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3,
-+	0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894,
-+	0xa086, 0x0014, 0x1178, 0x6998, 0xa184, 0xc000, 0x1140, 0xd1ec,
-+	0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3, 0x0100, 0x0028, 0x20a3,
-+	0x0400, 0x0010, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2,
-+	0x20a2, 0x20a2, 0x00f6, 0x2079, 0xb452, 0x7904, 0x00fe, 0xd1ac,
-+	0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009,
-+	0xb474, 0x210c, 0xd184, 0x1110, 0xa085, 0x0002, 0x0026, 0x2009,
-+	0xb472, 0x210c, 0xd1e4, 0x0130, 0xc0c5, 0xa094, 0x0030, 0xa296,
-+	0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094, 0x0030, 0xa296, 0x0010,
-+	0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014,
-+	0x080c, 0x7d11, 0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7697,
-+	0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x60c3, 0x0014, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c,
-+	0x7697, 0x20a3, 0x0200, 0x0804, 0x736f, 0x20a1, 0x020b, 0x080c,
-+	0x7697, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3,
-+	0x2a00, 0x60c3, 0x0008, 0x080c, 0x7d11, 0x0005, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008,
-+	0x080c, 0x7d11, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3200,
-+	0x2021, 0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2200,
-+	0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
-+	0x0028, 0x2014, 0xa286, 0x007e, 0x11a0, 0xa385, 0x00ff, 0x20a2,
-+	0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011, 0xb415, 0x2214, 0x2001,
-+	0xb69e, 0x2004, 0xa005, 0x0118, 0x2011, 0xb41d, 0x2214, 0x22a2,
-+	0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6, 0xa385, 0x00ff, 0x20a2,
-+	0x20a3, 0xfffd, 0x00c8, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x1110,
-+	0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, 0x1130, 0xa385, 0x00ff,
-+	0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8, 0xb535, 0x2d6c, 0x6810,
-+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68,
-+	0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8, 0xb535, 0x2d6c, 0x6810,
-+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
-+	0xb415, 0x2214, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x004e, 0x003e,
-+	0x20a3, 0x0000, 0x080c, 0x7d00, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
-+	0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
-+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011,
-+	0xfffc, 0x22a2, 0x00d6, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6,
-+	0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100,
-+	0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026,
-+	0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0038, 0x0026,
-+	0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb435,
-+	0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x02d8, 0x00d6, 0xa0e8,
-+	0xb535, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x6810,
-+	0xa005, 0x1140, 0x6814, 0xa005, 0x1128, 0x20a3, 0x00ff, 0x20a3,
-+	0xfffe, 0x0028, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-+	0x0080, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa305, 0x20a2,
-+	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415, 0x2214,
-+	0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x004e, 0x003e,
-+	0x080c, 0x7d00, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x080c, 0x7d00,
-+	0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6, 0x6004,
-+	0xa08a, 0x0085, 0x0a0c, 0x1511, 0xa08a, 0x008c, 0x1a0c, 0x1511,
-+	0x6118, 0x2178, 0x79a0, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110,
-+	0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff,
-+	0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2d88, 0x2f0d, 0xa18c,
-+	0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, 0x001b,
-+	0x00fe, 0x00ce, 0x0005, 0x7734, 0x773e, 0x7759, 0x7732, 0x7732,
-+	0x7732, 0x7734, 0x080c, 0x1511, 0x0146, 0x20a1, 0x020b, 0x04a1,
-+	0x60c3, 0x0000, 0x080c, 0x7d11, 0x014e, 0x0005, 0x0146, 0x20a1,
-+	0x020b, 0x080c, 0x77a5, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
-+	0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7d11, 0x014e,
-+	0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x77df, 0x20a3, 0x0003,
-+	0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
-+	0x080c, 0x7d11, 0x014e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb435, 0x2214,
-+	0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xb535,
-+	0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069,
-+	0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8,
-+	0xb535, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
-+	0x00de, 0x20a3, 0x0000, 0x2011, 0xb415, 0x2214, 0x22a2, 0x20a3,
-+	0x0009, 0x20a3, 0x0000, 0x0804, 0x7662, 0x0026, 0x20e1, 0x9080,
-+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb435,
-+	0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8,
-+	0xb535, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2,
-+	0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
-+	0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814,
-+	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415, 0x2214, 0x22a2,
-+	0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804, 0x76ee, 0x0026,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
-+	0x2011, 0xb435, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
-+	0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-+	0x0088, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x8500,
-+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415,
-+	0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804,
-+	0x76ee, 0x00c6, 0x00f6, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c,
-+	0x1511, 0xa08a, 0x0053, 0x1a0c, 0x1511, 0x7918, 0x2160, 0x61a0,
-+	0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100,
-+	0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000,
-+	0x0028, 0xa1e0, 0x2d88, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100,
-+	0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x785c,
-+	0x7968, 0x7905, 0x7b0a, 0x785a, 0x785a, 0x785a, 0x785a, 0x785a,
-+	0x785a, 0x785a, 0x8081, 0x8091, 0x80a1, 0x80b1, 0x785a, 0x84c1,
-+	0x785a, 0x8070, 0x080c, 0x1511, 0x00d6, 0x0156, 0x0146, 0x780b,
-+	0xffff, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7910, 0x2168, 0x6948,
-+	0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184,
-+	0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001,
-+	0x0004, 0x0018, 0xa084, 0x0006, 0x8004, 0x0016, 0x2008, 0x7858,
-+	0xa084, 0x00ff, 0x8007, 0xa105, 0x001e, 0x20a2, 0xd1ac, 0x0118,
-+	0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020,
-+	0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
-+	0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e,
-+	0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080,
-+	0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xb6fc,
-+	0x2003, 0x07d0, 0x2001, 0xb6fb, 0x2003, 0x0009, 0x080c, 0x17da,
-+	0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000,
-+	0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
-+	0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0x2019, 0xb435, 0x231c,
-+	0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb535, 0x2d6c,
-+	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb41c,
-+	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb535,
-+	0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x00de,
-+	0x20a3, 0x0000, 0x2009, 0xb415, 0x210c, 0x21a2, 0x20a3, 0x0829,
-+	0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156, 0x0136,
-+	0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, 0x2068, 0x6860, 0x20a2,
-+	0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2,
-+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x080c, 0x7d11, 0x014e,
-+	0x013e, 0x015e, 0x00de, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1,
-+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb435, 0x2214,
-+	0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb535, 0x2d6c,
-+	0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb41c,
-+	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb535,
-+	0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x00de,
-+	0x20a3, 0x0000, 0x2011, 0xb415, 0x2214, 0x22a2, 0x20a3, 0x0889,
-+	0x20a3, 0x0000, 0x080c, 0x7d00, 0x22a2, 0x20a3, 0x0000, 0x7a08,
-+	0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
-+	0x00d6, 0x0156, 0x0136, 0x0146, 0x7810, 0xa0ec, 0xf000, 0x0168,
-+	0xa06d, 0x080c, 0x52c2, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
-+	0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
-+	0x7ac0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
-+	0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
-+	0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
-+	0x79a2, 0x7a37, 0x7a40, 0x7a69, 0x7a7c, 0x7a97, 0x7aa0, 0x79a0,
-+	0x080c, 0x1511, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
-+	0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
-+	0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
-+	0x7a73, 0xa186, 0x0001, 0x190c, 0x1511, 0x6b78, 0x7820, 0xd0cc,
-+	0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
-+	0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
-+	0x0300, 0x0904, 0x7a31, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
-+	0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
-+	0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x79e0, 0x015e, 0x22a2,
-+	0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7a31, 0x20a1, 0x020b,
-+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
-+	0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-+	0x0088, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0700,
-+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415,
-+	0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
-+	0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7d00, 0x22a2, 0x20a3,
-+	0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7d11, 0x0005, 0x2011,
-+	0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488,
-+	0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016,
-+	0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
-+	0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
-+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7d11,
-+	0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
-+	0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
-+	0x0018, 0x080c, 0x7d11, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
-+	0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
-+	0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
-+	0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7d11, 0x0005, 0x2011,
-+	0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
-+	0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
-+	0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
-+	0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
-+	0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7a73,
-+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
-+	0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-+	0x0088, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0700,
-+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415,
-+	0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
-+	0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7d00, 0x22a2, 0x20a3,
-+	0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036,
-+	0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e,
-+	0x013e, 0x015e, 0x00de, 0x0005, 0x7b24, 0x7b24, 0x7b26, 0x7b24,
-+	0x7b24, 0x7b24, 0x7b48, 0x7b24, 0x080c, 0x1511, 0x7910, 0xa18c,
-+	0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
-+	0x00f9, 0x00d6, 0x2069, 0xb452, 0x6804, 0xd0bc, 0x0130, 0x682c,
-+	0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
-+	0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7d11, 0x0005,
-+	0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
-+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-+	0x2004, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
-+	0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
-+	0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-+	0x0088, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085, 0x0100,
-+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb415,
-+	0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
-+	0x7d00, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
-+	0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
-+	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xb400, 0x7154,
-+	0x7818, 0x2068, 0x68a0, 0x2028, 0x76d4, 0xd6ac, 0x1130, 0xd0bc,
-+	0x1120, 0x6910, 0x6a14, 0x7454, 0x0020, 0x6910, 0x6a14, 0x7370,
-+	0x7474, 0x781c, 0xa0be, 0x0006, 0x0904, 0x7c4b, 0xa0be, 0x000a,
-+	0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
-+	0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
-+	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
-+	0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
-+	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
-+	0x609f, 0x0000, 0x080c, 0x855c, 0x2009, 0x07d0, 0x60c4, 0xa084,
-+	0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x69da, 0x003e,
-+	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d4, 0xd0ac,
-+	0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
-+	0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
-+	0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
-+	0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
-+	0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
-+	0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
-+	0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120,
-+	0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c,
-+	0x855c, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110,
-+	0x2009, 0x1b58, 0x080c, 0x69da, 0x003e, 0x004e, 0x005e, 0x00ce,
-+	0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003,
-+	0xa086, 0x0002, 0x0904, 0x7ca1, 0x2001, 0xb435, 0x2004, 0xd0ac,
-+	0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
-+	0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
-+	0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
-+	0x00ff, 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086,
-+	0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
-+	0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928,
-+	0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
-+	0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
-+	0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8559, 0x0804,
-+	0x7c39, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
-+	0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
-+	0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x52c2,
-+	0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020,
-+	0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889,
-+	0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084,
-+	0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086,
-+	0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
-+	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
-+	0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
-+	0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120,
-+	0x080c, 0x855c, 0x0804, 0x7c39, 0x080c, 0x8559, 0x0804, 0x7c39,
-+	0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
-+	0x8217, 0x0005, 0x00d6, 0x2069, 0xb6e0, 0x6843, 0x0001, 0x00de,
-+	0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019,
-+	0x080c, 0x69cc, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085,
-+	0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061,
-+	0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0xa084, 0x0004, 0xa085,
-+	0x0008, 0x6016, 0x000e, 0xe000, 0xe000, 0xe000, 0xe000, 0x61a6,
-+	0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
-+	0x0100, 0x2069, 0x0140, 0x080c, 0x5a90, 0x1198, 0x2001, 0xb6fc,
-+	0x2004, 0xa005, 0x15b8, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b12,
-+	0x006e, 0x1118, 0x080c, 0x69cc, 0x0468, 0x00c6, 0x2061, 0xb6e0,
-+	0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x0831, 0x6803, 0x1000,
-+	0x6803, 0x0000, 0x00c6, 0x2061, 0xb6e0, 0x6128, 0xa192, 0x00c8,
-+	0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c,
-+	0x69cc, 0x080c, 0x7d1b, 0x0070, 0x6124, 0xa1e5, 0x0000, 0x0140,
-+	0x080c, 0xb3c7, 0x080c, 0x69d5, 0x2009, 0x0014, 0x080c, 0x85ef,
-+	0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001,
-+	0xb6fc, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061, 0xb6e0, 0x6128,
-+	0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x69cc,
-+	0x080c, 0x4ad9, 0x0c38, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026,
-+	0x080c, 0x69e2, 0x2071, 0xb6e0, 0x713c, 0x81ff, 0x0590, 0x2061,
-+	0x0100, 0x2069, 0x0140, 0x080c, 0x5a90, 0x11a8, 0x0036, 0x2019,
-+	0x0002, 0x080c, 0x7f8e, 0x003e, 0x713c, 0x2160, 0x080c, 0xb3c7,
-+	0x2009, 0x004a, 0x080c, 0x85ef, 0x0066, 0x2031, 0x0001, 0x080c,
-+	0x5b12, 0x006e, 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803,
-+	0x1000, 0x6803, 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7f8e,
-+	0x003e, 0x713c, 0x2160, 0x080c, 0xb3c7, 0x2009, 0x004a, 0x080c,
-+	0x85ef, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58,
-+	0x0026, 0x00e6, 0x2071, 0xb6e0, 0x7048, 0xd084, 0x01c0, 0x713c,
-+	0x81ff, 0x01a8, 0x2071, 0x0100, 0xa188, 0x0007, 0x2114, 0xa28e,
-+	0x0006, 0x1138, 0x7014, 0xa084, 0x0184, 0xa085, 0x0012, 0x7016,
-+	0x0030, 0x7014, 0xa084, 0x0184, 0xa085, 0x0016, 0x7016, 0x00ee,
-+	0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046,
-+	0x0006, 0x0126, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
-+	0xb6e0, 0x7018, 0x2068, 0x8dff, 0x0188, 0x68a0, 0xa406, 0x0118,
-+	0x6854, 0x2068, 0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648,
-+	0x2d60, 0x080c, 0x50db, 0x0110, 0xa085, 0x0001, 0x012e, 0x000e,
-+	0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1,
-+	0x020b, 0x080c, 0x75fb, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x781c, 0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001,
-+	0xb415, 0x2004, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9,
-+	0x0010, 0xa006, 0x20a2, 0x1f04, 0x7e4a, 0x20a2, 0x20a2, 0x60c3,
-+	0x002c, 0x080c, 0x7d11, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b,
-+	0x080c, 0x75fb, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d11, 0x014e, 0x015e,
-+	0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3,
-+	0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0xb440, 0x2019,
-+	0xb441, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04,
-+	0x7e79, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c,
-+	0x7d11, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026,
-+	0x20a1, 0x020b, 0x080c, 0x7670, 0x080c, 0x7686, 0x7810, 0xa080,
-+	0x0000, 0x2004, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002,
-+	0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7d11,
-+	0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1,
-+	0x020b, 0x080c, 0x75fb, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d11, 0x014e,
-+	0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
-+	0x080c, 0x75fb, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017,
-+	0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2,
-+	0x080c, 0x7d11, 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6,
-+	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb6e0, 0x700c,
-+	0x2060, 0x8cff, 0x0178, 0x080c, 0x9de9, 0x1110, 0x080c, 0x8bbc,
-+	0x600c, 0x0006, 0x080c, 0x9fb0, 0x080c, 0x85c0, 0x080c, 0x80c8,
-+	0x00ce, 0x0c78, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e,
-+	0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6,
-+	0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100,
-+	0x2079, 0x0140, 0x2071, 0xb6e0, 0x7024, 0x2060, 0x8cff, 0x05a0,
-+	0x080c, 0x7d24, 0x68c3, 0x0000, 0x080c, 0x69d5, 0x2009, 0x0013,
-+	0x080c, 0x85ef, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827,
-+	0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803,
-+	0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
-+	0x7f24, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803,
-+	0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
-+	0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0xb400, 0x2004, 0xa096,
-+	0x0001, 0x0590, 0xa096, 0x0004, 0x0578, 0x080c, 0x69d5, 0x6814,
-+	0xa084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3,
-+	0x0000, 0x2011, 0x4a96, 0x080c, 0x6961, 0x20a9, 0x01f4, 0x6824,
-+	0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
-+	0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827,
-+	0x0001, 0x0010, 0x1f04, 0x7f67, 0x7804, 0xa084, 0x1000, 0x0120,
-+	0x7803, 0x0100, 0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce,
-+	0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156,
-+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091,
-+	0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0xb6e0, 0x703c,
-+	0x2060, 0x8cff, 0x0904, 0x8015, 0xa386, 0x0002, 0x1128, 0x6814,
-+	0xa084, 0x0002, 0x0904, 0x8015, 0x68af, 0x95f5, 0x6817, 0x0010,
-+	0x2009, 0x00fa, 0x8109, 0x1df0, 0x68c7, 0x0000, 0x68cb, 0x0008,
-+	0x080c, 0x69e2, 0x080c, 0x21dd, 0x0046, 0x2009, 0x017f, 0x200b,
-+	0x00a5, 0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004,
-+	0x1500, 0x68af, 0x95f5, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6,
-+	0x00f6, 0x2079, 0x0020, 0x2071, 0xb74a, 0x6814, 0xa084, 0x0184,
-+	0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x00fe,
-+	0x00ee, 0xa386, 0x0002, 0x1128, 0x7884, 0xa005, 0x1110, 0x7887,
-+	0x0001, 0x2001, 0xb6b1, 0x2004, 0x200a, 0x004e, 0xa39d, 0x0000,
-+	0x1120, 0x2009, 0x0049, 0x080c, 0x85ef, 0x20a9, 0x03e8, 0x6824,
-+	0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
-+	0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827,
-+	0x0002, 0x0010, 0x1f04, 0x7ff7, 0x7804, 0xa084, 0x1000, 0x0120,
-+	0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
-+	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
-+	0x0126, 0x2091, 0x8000, 0x2069, 0xb6e0, 0x6a06, 0x012e, 0x00de,
-+	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xb6e0, 0x6a32,
-+	0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
-+	0x0126, 0x2071, 0xb6e0, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000,
-+	0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110,
-+	0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
-+	0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
-+	0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
-+	0x9dae, 0x080c, 0x80c8, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
-+	0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-+	0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7810, 0x20a2,
-+	0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
-+	0x80c0, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7810,
-+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
-+	0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7810,
-+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
-+	0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7810,
-+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
-+	0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x78bc, 0x7810,
-+	0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
-+	0x0089, 0x60c3, 0x0020, 0x080c, 0x7d11, 0x014e, 0x015e, 0x0005,
-+	0x00e6, 0x2071, 0xb6e0, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
-+	0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x80d4, 0x20a2,
-+	0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
-+	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb6e0, 0x7614, 0x2660,
-+	0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x8169, 0x8cff, 0x0904,
-+	0x8169, 0x601c, 0xa086, 0x0006, 0x1904, 0x8164, 0x88ff, 0x0138,
-+	0x2800, 0xac06, 0x1904, 0x8164, 0x2039, 0x0000, 0x0050, 0x6018,
-+	0xa206, 0x1904, 0x8164, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904,
-+	0x8164, 0x7024, 0xac06, 0x1560, 0x2069, 0x0100, 0x68c0, 0xa005,
-+	0x0518, 0x080c, 0x69d5, 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5,
-+	0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x81f0, 0x7027, 0x0000,
-+	0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803,
-+	0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-+	0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x0460,
-+	0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140,
-+	0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x89ff, 0x1158, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9beb,
-+	0x0110, 0x080c, 0xb01c, 0x080c, 0x9dae, 0x080c, 0x80c8, 0x88ff,
-+	0x1190, 0x00ce, 0x0804, 0x80eb, 0x2c78, 0x600c, 0x2060, 0x0804,
-+	0x80eb, 0xa006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de,
-+	0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001,
-+	0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006,
-+	0x0126, 0x2091, 0x8000, 0x2071, 0xb6e0, 0x7638, 0x2660, 0x2678,
-+	0x8cff, 0x0904, 0x81e0, 0x601c, 0xa086, 0x0006, 0x1904, 0x81db,
-+	0x87ff, 0x0128, 0x2700, 0xac06, 0x1904, 0x81db, 0x0048, 0x6018,
-+	0xa206, 0x1904, 0x81db, 0x85ff, 0x0118, 0x6050, 0xa106, 0x15d8,
-+	0x703c, 0xac06, 0x1180, 0x0036, 0x2019, 0x0001, 0x080c, 0x7f8e,
-+	0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000,
-+	0x704b, 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
-+	0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
-+	0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
-+	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c,
-+	0x9beb, 0x0110, 0x080c, 0xb01c, 0x080c, 0x9dae, 0x87ff, 0x1190,
-+	0x00ce, 0x0804, 0x8188, 0x2c78, 0x600c, 0x2060, 0x0804, 0x8188,
-+	0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
-+	0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88,
-+	0x00e6, 0x2071, 0xb6e0, 0x2001, 0xb400, 0x2004, 0xa086, 0x0002,
-+	0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
-+	0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
-+	0x8000, 0x2071, 0xb6e0, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff,
-+	0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c,
-+	0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
-+	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110,
-+	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020,
-+	0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e,
-+	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
-+	0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb6e0, 0x760c,
-+	0x2660, 0x2678, 0x8cff, 0x0904, 0x82c6, 0x6018, 0xa080, 0x0028,
-+	0x2004, 0xa206, 0x1904, 0x82c1, 0x7024, 0xac06, 0x1508, 0x2069,
-+	0x0100, 0x68c0, 0xa005, 0x0904, 0x829d, 0x080c, 0x7d24, 0x68c3,
-+	0x0000, 0x080c, 0x81f0, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
-+	0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-+	0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, 0xac36, 0x1140,
-+	0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x080c, 0x9dd8, 0x1158, 0x080c, 0x2c86, 0x080c,
-+	0x9de9, 0x11f0, 0x080c, 0x8bbc, 0x00d8, 0x080c, 0x81f0, 0x08c0,
-+	0x080c, 0x9de9, 0x1118, 0x080c, 0x8bbc, 0x0090, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837,
-+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x53c9, 0x080c, 0x9da2,
-+	0x080c, 0x9fb0, 0x080c, 0x9dae, 0x080c, 0x80c8, 0x00ce, 0x0804,
-+	0x824a, 0x2c78, 0x600c, 0x2060, 0x0804, 0x824a, 0x012e, 0x000e,
-+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
-+	0x0006, 0x1d30, 0x080c, 0xb01c, 0x0c18, 0x0036, 0x0156, 0x0136,
-+	0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x2a7d,
-+	0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020,
-+	0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e,
-+	0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3,
-+	0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x2099, 0xb6b9, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004,
-+	0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7d11,
-+	0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3, 0x0214,
-+	0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-+	0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7d11, 0x0005, 0x00d6,
-+	0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0xa09b, 0x1904, 0x83a5,
-+	0x20a1, 0x020b, 0x080c, 0x75fb, 0x20a3, 0x1300, 0x20a3, 0x0000,
-+	0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080,
-+	0x0028, 0x2014, 0x2001, 0xb435, 0x2004, 0xd0ac, 0x11d0, 0xa286,
-+	0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286,
-+	0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc,
-+	0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc,
-+	0x0428, 0xa2e8, 0xb535, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2,
-+	0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xb435,
-+	0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
-+	0x007e, 0x0240, 0x00d6, 0x2069, 0xb41c, 0x2da6, 0x8d68, 0x2da6,
-+	0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2,
-+	0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
-+	0x080c, 0x7d11, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803,
-+	0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168,
-+	0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x841b,
-+	0xa186, 0x0005, 0x0904, 0x8404, 0xa186, 0x0004, 0x05b8, 0xa186,
-+	0x0008, 0x0904, 0x840c, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c,
-+	0x8483, 0x002e, 0x00de, 0x0005, 0x080c, 0x843f, 0x2009, 0x4000,
-+	0x6800, 0x0002, 0x83e5, 0x83f0, 0x83e7, 0x83f0, 0x83ec, 0x83e5,
-+	0x83e5, 0x83f0, 0x83f0, 0x83f0, 0x83f0, 0x83e5, 0x83e5, 0x83e5,
-+	0x83e5, 0x83e5, 0x83f0, 0x83e5, 0x83f0, 0x080c, 0x1511, 0x6820,
-+	0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000,
-+	0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x8435, 0x080c, 0x843f,
-+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286,
-+	0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3,
-+	0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002,
-+	0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810,
-+	0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180,
-+	0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118,
-+	0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000,
-+	0x60c3, 0x0018, 0x080c, 0x7d11, 0x002e, 0x00de, 0x0005, 0x0036,
-+	0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x7697, 0xa006,
-+	0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818,
-+	0xa080, 0x0028, 0x2004, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1118,
-+	0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xb41c, 0x2d2c, 0x8d68,
-+	0x2d34, 0xa0e8, 0xb535, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030,
-+	0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080,
-+	0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2,
-+	0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e,
-+	0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7697, 0x20a3,
-+	0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3,
-+	0x0008, 0x080c, 0x7d11, 0x0005, 0x20a1, 0x020b, 0x080c, 0x75f3,
-+	0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2,
-+	0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007,
-+	0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7d11, 0x0005,
-+	0x20a1, 0x020b, 0x080c, 0x768f, 0x20a3, 0x0100, 0x20a3, 0x0000,
-+	0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d11,
-+	0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c,
-+	0x7d11, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
-+	0xa080, 0x0028, 0x2004, 0x2011, 0xb435, 0x2214, 0xd2ac, 0x1110,
-+	0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810, 0xa085,
-+	0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb41c, 0x2da6, 0x8d68,
-+	0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xb535, 0x2d6c, 0x6810,
-+	0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
-+	0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7d00,
-+	0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000,
-+	0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
-+	0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
-+	0x080c, 0x7d1b, 0x080c, 0x69cc, 0x0005, 0x0156, 0x0136, 0x0036,
-+	0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 0x2068,
-+	0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212,
-+	0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308,
-+	0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215,
-+	0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98,
-+	0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000,
-+	0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e,
-+	0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
-+	0x6116, 0x0005, 0x2061, 0xbc00, 0x2a70, 0x7068, 0x704a, 0x704f,
-+	0xbc00, 0x0005, 0x00e6, 0x0126, 0x2071, 0xb400, 0x2091, 0x8000,
-+	0x7548, 0xa582, 0x0010, 0x0608, 0x704c, 0x2060, 0x6000, 0xa086,
-+	0x0000, 0x0148, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0,
-+	0x2061, 0xbc00, 0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8,
-+	0x0018, 0x705c, 0xa502, 0x1230, 0x754e, 0xa085, 0x0001, 0x012e,
-+	0x00ee, 0x0005, 0x704f, 0xbc00, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
-+	0x2071, 0xb400, 0x7548, 0xa582, 0x0010, 0x0600, 0x704c, 0x2060,
-+	0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x705c, 0xac02,
-+	0x1208, 0x0cb0, 0x2061, 0xbc00, 0x0c98, 0x6003, 0x0008, 0x8529,
-+	0x754a, 0xaca8, 0x0018, 0x705c, 0xa502, 0x1228, 0x754e, 0xa085,
-+	0x0001, 0x00ee, 0x0005, 0x704f, 0xbc00, 0x0cc8, 0xa006, 0x0cc8,
-+	0xac82, 0xbc00, 0x0a0c, 0x1511, 0x2001, 0xb417, 0x2004, 0xac02,
-+	0x1a0c, 0x1511, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
-+	0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022,
-+	0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061,
-+	0xb400, 0x6048, 0x8000, 0x604a, 0xa086, 0x0001, 0x0108, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x0cc0, 0x601c,
-+	0xa084, 0x000f, 0x0002, 0x85fe, 0x860d, 0x8628, 0x8643, 0xa0df,
-+	0xa0fa, 0xa115, 0x85fe, 0x860d, 0x85fe, 0x865e, 0xa186, 0x0013,
-+	0x1128, 0x080c, 0x7055, 0x080c, 0x7134, 0x0005, 0xa18e, 0x0047,
-+	0x1118, 0xa016, 0x080c, 0x1856, 0x0005, 0x0066, 0x6000, 0xa0b2,
-+	0x0010, 0x1a0c, 0x1511, 0x0013, 0x006e, 0x0005, 0x8626, 0x8a3e,
-+	0x8bf6, 0x8626, 0x8c6b, 0x871c, 0x8626, 0x8626, 0x89d0, 0x908f,
-+	0x8626, 0x8626, 0x8626, 0x8626, 0x8626, 0x8626, 0x080c, 0x1511,
-+	0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1511, 0x0013, 0x006e,
-+	0x0005, 0x8641, 0x96bb, 0x8641, 0x8641, 0x8641, 0x8641, 0x8641,
-+	0x8641, 0x9666, 0x9827, 0x8641, 0x96e8, 0x975f, 0x96e8, 0x975f,
-+	0x8641, 0x080c, 0x1511, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
-+	0x1511, 0x0013, 0x006e, 0x0005, 0x865c, 0x90d0, 0x919a, 0x92ce,
-+	0x942a, 0x865c, 0x865c, 0x865c, 0x90aa, 0x9616, 0x9619, 0x865c,
-+	0x865c, 0x865c, 0x865c, 0x9643, 0x080c, 0x1511, 0x0066, 0x6000,
-+	0xa0b2, 0x0010, 0x1a0c, 0x1511, 0x0013, 0x006e, 0x0005, 0x8677,
-+	0x8677, 0x8677, 0x86a5, 0x86f2, 0x8677, 0x8677, 0x8677, 0x8679,
-+	0x8677, 0x8677, 0x8677, 0x8677, 0x8677, 0x8677, 0x8677, 0x080c,
-+	0x1511, 0xa186, 0x0003, 0x190c, 0x1511, 0x00d6, 0x6003, 0x0003,
-+	0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880,
-+	0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x6854, 0xa092, 0x199a,
-+	0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0xa210, 0x6216,
-+	0x00de, 0x2c10, 0x080c, 0x1f7a, 0x080c, 0x6cb5, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x71f1, 0x012e, 0x0005, 0xa182, 0x0047, 0x0002,
-+	0x86b1, 0x86b1, 0x86b3, 0x86cc, 0x86b1, 0x86b1, 0x86b1, 0x86b1,
-+	0x86de, 0x080c, 0x1511, 0x00d6, 0x0016, 0x080c, 0x70e7, 0x080c,
-+	0x71f1, 0x6003, 0x0004, 0x6110, 0x2168, 0x684f, 0x0020, 0x685c,
-+	0x685a, 0x6874, 0x687e, 0x6878, 0x6882, 0x6897, 0x0000, 0x689b,
-+	0x0000, 0x001e, 0x00de, 0x0005, 0x080c, 0x70e7, 0x00d6, 0x6110,
-+	0x2168, 0x080c, 0x9beb, 0x0120, 0x684b, 0x0006, 0x080c, 0x53c9,
-+	0x00de, 0x080c, 0x85c0, 0x080c, 0x71f1, 0x0005, 0x080c, 0x70e7,
-+	0x080c, 0x2c60, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9beb, 0x0120,
-+	0x684b, 0x0029, 0x080c, 0x53c9, 0x00de, 0x080c, 0x85c0, 0x080c,
-+	0x71f1, 0x0005, 0xa182, 0x0047, 0x0002, 0x8700, 0x870f, 0x86fe,
-+	0x86fe, 0x86fe, 0x86fe, 0x86fe, 0x86fe, 0x86fe, 0x080c, 0x1511,
-+	0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4, 0x684e, 0x00de, 0x20e1,
-+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856, 0x0005, 0x00d6,
-+	0x6110, 0x2168, 0x684b, 0x0000, 0x6853, 0x0000, 0x080c, 0x53c9,
-+	0x00de, 0x080c, 0x85c0, 0x0005, 0xa1b6, 0x0015, 0x1118, 0x080c,
-+	0x85c0, 0x0030, 0xa1b6, 0x0016, 0x190c, 0x1511, 0x080c, 0x85c0,
-+	0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9,
-+	0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e,
-+	0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0,
-+	0x0002, 0x1f04, 0x8737, 0x00e6, 0x080c, 0x9beb, 0x0130, 0x6010,
-+	0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x00ee, 0x080c, 0x85c0,
-+	0x0005, 0x00d6, 0x0036, 0x7330, 0xa386, 0x0200, 0x1130, 0x6018,
-+	0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0130,
-+	0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x080c, 0x85c0,
-+	0x003e, 0x00de, 0x0005, 0x0016, 0x20a9, 0x002a, 0xae80, 0x000c,
-+	0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a,
-+	0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
-+	0x00e6, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c,
-+	0x85c0, 0x001e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, 0xa086,
-+	0x0100, 0x0140, 0x7038, 0xa084, 0x00ff, 0x800c, 0x703c, 0xa084,
-+	0x00ff, 0x8004, 0xa080, 0x0004, 0xa108, 0x21a8, 0xae80, 0x000c,
-+	0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x080c, 0x4b49, 0x00e6,
-+	0x080c, 0x9beb, 0x0140, 0x6010, 0x2070, 0x7007, 0x0000, 0x7034,
-+	0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c, 0x85c0, 0x001e, 0x0005,
-+	0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035,
-+	0x080c, 0xa09b, 0x001e, 0x1168, 0x0026, 0x6228, 0x2268, 0x002e,
-+	0x2071, 0xba8c, 0x6b1c, 0xa386, 0x0003, 0x0130, 0xa386, 0x0006,
-+	0x0128, 0x080c, 0x85c0, 0x0020, 0x0031, 0x0010, 0x080c, 0x8899,
-+	0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810, 0x2078, 0xa186, 0x0015,
-+	0x0904, 0x8880, 0xa18e, 0x0016, 0x1904, 0x8897, 0x700c, 0xa08c,
-+	0xff00, 0xa186, 0x1700, 0x0120, 0xa186, 0x0300, 0x1904, 0x885f,
-+	0x8fff, 0x1138, 0x6800, 0xa086, 0x000f, 0x0904, 0x8843, 0x0804,
-+	0x8895, 0x6808, 0xa086, 0xffff, 0x1904, 0x8882, 0x784c, 0xa084,
-+	0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810, 0xa106, 0x1904,
-+	0x8882, 0x7980, 0x7814, 0xa106, 0x1904, 0x8882, 0x080c, 0x9da2,
-+	0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e, 0x0026,
-+	0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6b05, 0x7854, 0xa20a,
-+	0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60,
-+	0x080c, 0x99a2, 0x00ce, 0x0804, 0x8895, 0x00c6, 0x00d6, 0x2f68,
-+	0x6838, 0xd0fc, 0x1118, 0x080c, 0x4c1e, 0x0010, 0x080c, 0x4e0a,
-+	0x00de, 0x00ce, 0x1904, 0x8882, 0x00c6, 0x2d60, 0x080c, 0x85c0,
-+	0x00ce, 0x0804, 0x8895, 0x00c6, 0x080c, 0x9e67, 0x0190, 0x6013,
-+	0x0000, 0x6818, 0x601a, 0x080c, 0x9fb8, 0x601f, 0x0003, 0x6904,
-+	0x00c6, 0x2d60, 0x080c, 0x85c0, 0x00ce, 0x080c, 0x85ef, 0x00ce,
-+	0x04e0, 0x2001, 0xb6b8, 0x2004, 0x683e, 0x00ce, 0x04b0, 0x7008,
-+	0xa086, 0x000b, 0x11a0, 0x6018, 0x200c, 0xc1bc, 0x2102, 0x00c6,
-+	0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
-+	0x0002, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00ce, 0x00f0, 0x700c,
-+	0xa086, 0x2a00, 0x1138, 0x2001, 0xb6b8, 0x2004, 0x683e, 0x00a8,
-+	0x0481, 0x00a8, 0x8fff, 0x090c, 0x1511, 0x00c6, 0x00d6, 0x2d60,
-+	0x2f68, 0x6837, 0x0103, 0x684b, 0x0003, 0x080c, 0x9896, 0x080c,
-+	0x9da2, 0x080c, 0x9dae, 0x00de, 0x00ce, 0x080c, 0x85c0, 0x00fe,
-+	0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xb6b8, 0x2004, 0x683e,
-+	0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c,
-+	0xb2bd, 0x080c, 0x6ab4, 0x080c, 0x85c0, 0x00ce, 0x080c, 0x85c0,
-+	0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80, 0x7b7c, 0xd2f4,
-+	0x0130, 0x2001, 0xb6b8, 0x2004, 0x683e, 0x0804, 0x8913, 0x00c6,
-+	0x2d60, 0x080c, 0x98b6, 0x00ce, 0x6804, 0xa086, 0x0050, 0x1168,
-+	0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
-+	0x6c52, 0x080c, 0x7134, 0x00ce, 0x04f0, 0x6800, 0xa086, 0x000f,
-+	0x01c8, 0x8fff, 0x090c, 0x1511, 0x6820, 0xd0dc, 0x1198, 0x6800,
-+	0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180, 0x784c, 0xc0dc,
-+	0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001,
-+	0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0, 0x784c, 0xd0b4,
-+	0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0, 0x0c38, 0xd2ec,
-+	0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406, 0x0d58, 0x7020,
-+	0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x080c, 0x9ef4,
-+	0x080c, 0x7134, 0x0010, 0x080c, 0x85c0, 0x004e, 0x003e, 0x002e,
-+	0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068, 0x6a1c, 0xa286,
-+	0x0007, 0x0904, 0x8977, 0xa286, 0x0002, 0x0904, 0x8977, 0xa286,
-+	0x0000, 0x0904, 0x8977, 0x6808, 0x6338, 0xa306, 0x1904, 0x8977,
-+	0x2071, 0xba8c, 0xa186, 0x0015, 0x05e0, 0xa18e, 0x0016, 0x1190,
-+	0x6030, 0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086,
-+	0x2a00, 0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5,
-+	0x2102, 0x0438, 0x00c6, 0x6034, 0x2060, 0x6104, 0xa186, 0x004b,
-+	0x01a0, 0xa186, 0x004c, 0x0188, 0xa186, 0x004d, 0x0170, 0xa186,
-+	0x004e, 0x0158, 0xa186, 0x0052, 0x0140, 0x6010, 0x2068, 0x080c,
-+	0x9beb, 0x090c, 0x1511, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003,
-+	0x000b, 0x601f, 0x0002, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00ce,
-+	0x0030, 0x6034, 0x2070, 0x2001, 0xb6b8, 0x2004, 0x703e, 0x080c,
-+	0x85c0, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e,
-+	0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1558, 0x6018,
-+	0x2068, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c, 0xa290, 0x0004,
-+	0x20a9, 0x0004, 0xad98, 0x000a, 0x080c, 0x907a, 0x002e, 0x003e,
-+	0x015e, 0x11d8, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c, 0xa290,
-+	0x0008, 0x20a9, 0x0004, 0xad98, 0x0006, 0x080c, 0x907a, 0x002e,
-+	0x003e, 0x015e, 0x1150, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800,
-+	0xc08d, 0x6802, 0x00de, 0x0804, 0x8743, 0x080c, 0x2c60, 0x00c6,
-+	0x080c, 0x856a, 0x2f00, 0x601a, 0x6013, 0x0000, 0x601f, 0x0001,
-+	0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x4ebe,
-+	0x080c, 0x4eeb, 0x080c, 0x6c98, 0x080c, 0x7134, 0x00ce, 0x0c10,
-+	0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x1511, 0xa1b2, 0x0040, 0x1a04,
-+	0x8a34, 0x0002, 0x8a28, 0x8a1c, 0x8a28, 0x8a28, 0x8a28, 0x8a28,
-+	0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a28, 0x8a1a, 0x8a28, 0x8a28, 0x8a1a, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a1a, 0x8a28, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a28, 0x8a28, 0x8a1a, 0x8a1a,
-+	0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a1a, 0x8a28,
-+	0x8a1a, 0x8a1a, 0x080c, 0x1511, 0x6003, 0x0001, 0x6106, 0x080c,
-+	0x6c98, 0x0126, 0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x0005,
-+	0x6003, 0x0001, 0x6106, 0x080c, 0x6c98, 0x0126, 0x2091, 0x8000,
-+	0x080c, 0x7134, 0x012e, 0x0005, 0x2600, 0x0002, 0x8a28, 0x8a28,
-+	0x8a3c, 0x8a28, 0x8a28, 0x8a3c, 0x080c, 0x1511, 0x6004, 0xa0b2,
-+	0x0080, 0x1a0c, 0x1511, 0xa1b6, 0x0013, 0x0904, 0x8aee, 0xa1b6,
-+	0x0027, 0x1904, 0x8ab4, 0x080c, 0x7055, 0x6004, 0x080c, 0x9dd8,
-+	0x0190, 0x080c, 0x9de9, 0x0904, 0x8aae, 0xa08e, 0x0021, 0x0904,
-+	0x8ab1, 0xa08e, 0x0022, 0x0904, 0x8aae, 0xa08e, 0x003d, 0x0904,
-+	0x8ab1, 0x0804, 0x8aa7, 0x080c, 0x2c86, 0x2001, 0x0007, 0x080c,
-+	0x4ebe, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8bbc, 0xa186,
-+	0x007e, 0x1148, 0x2001, 0xb435, 0x2014, 0xc285, 0x080c, 0x5a90,
-+	0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, 0x0026,
-+	0x2019, 0x0028, 0x080c, 0x823c, 0x002e, 0x080c, 0xb310, 0x003e,
-+	0x002e, 0x001e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028,
-+	0x080c, 0x6dba, 0x0076, 0x2039, 0x0000, 0x080c, 0x6cc7, 0x00c6,
-+	0x6018, 0xa065, 0x0110, 0x080c, 0x516b, 0x00ce, 0x2c08, 0x080c,
-+	0xae05, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0x4f2d, 0x080c,
-+	0x9fb0, 0x080c, 0x85c0, 0x080c, 0x7134, 0x0005, 0x080c, 0x8bbc,
-+	0x0cb0, 0x080c, 0x8bea, 0x0c98, 0xa186, 0x0014, 0x1db0, 0x080c,
-+	0x7055, 0x080c, 0x2c60, 0x080c, 0x9dd8, 0x1188, 0x080c, 0x2c86,
-+	0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8bbc, 0xa186, 0x007e,
-+	0x1128, 0x2001, 0xb435, 0x200c, 0xc185, 0x2102, 0x08c0, 0x080c,
-+	0x9de9, 0x1118, 0x080c, 0x8bbc, 0x0890, 0x6004, 0xa08e, 0x0032,
-+	0x1158, 0x00e6, 0x00f6, 0x2071, 0xb482, 0x2079, 0x0000, 0x080c,
-+	0x2f93, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, 0x0021, 0x0d50,
-+	0xa08e, 0x0022, 0x090c, 0x8bbc, 0x0804, 0x8aa7, 0xa0b2, 0x0040,
-+	0x1a04, 0x8bb1, 0x2008, 0x0002, 0x8b36, 0x8b37, 0x8b3a, 0x8b3d,
-+	0x8b40, 0x8b43, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34,
-+	0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34,
-+	0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34,
-+	0x8b34, 0x8b34, 0x8b46, 0x8b55, 0x8b34, 0x8b57, 0x8b55, 0x8b34,
-+	0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b55, 0x8b55, 0x8b34, 0x8b34,
-+	0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b34, 0x8b91, 0x8b55,
-+	0x8b34, 0x8b51, 0x8b34, 0x8b34, 0x8b34, 0x8b52, 0x8b34, 0x8b34,
-+	0x8b34, 0x8b55, 0x8b88, 0x8b34, 0x080c, 0x1511, 0x00f0, 0x2001,
-+	0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001, 0x0005, 0x0430,
-+	0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400, 0x080c, 0x7055,
-+	0x6003, 0x0005, 0x2001, 0xb6b8, 0x2004, 0x603e, 0x080c, 0x7134,
-+	0x00a0, 0x0018, 0x0010, 0x080c, 0x4ebe, 0x0804, 0x8ba2, 0x080c,
-+	0x7055, 0x2001, 0xb6b6, 0x2004, 0x6016, 0x2001, 0xb6b8, 0x2004,
-+	0x603e, 0x6003, 0x0004, 0x080c, 0x7134, 0x0005, 0x080c, 0x4ebe,
-+	0x080c, 0x7055, 0x6003, 0x0002, 0x2001, 0xb6b8, 0x2004, 0x603e,
-+	0x0036, 0x2019, 0xb45d, 0x2304, 0xa084, 0xff00, 0x1120, 0x2001,
-+	0xb6b6, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004, 0x0ec0, 0x8003,
-+	0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c, 0x7134, 0x08e8,
-+	0x080c, 0x7055, 0x080c, 0x9fb0, 0x080c, 0x85c0, 0x080c, 0x7134,
-+	0x08a0, 0x00e6, 0x00f6, 0x2071, 0xb482, 0x2079, 0x0000, 0x080c,
-+	0x2f93, 0x00fe, 0x00ee, 0x080c, 0x7055, 0x080c, 0x85c0, 0x080c,
-+	0x7134, 0x0818, 0x080c, 0x7055, 0x2001, 0xb6b8, 0x2004, 0x603e,
-+	0x6003, 0x0002, 0x2001, 0xb6b6, 0x2004, 0x6016, 0x080c, 0x7134,
-+	0x0005, 0x2600, 0x2008, 0x0002, 0x8bba, 0x8bba, 0x8bba, 0x8ba2,
-+	0x8ba2, 0x8bba, 0x080c, 0x1511, 0x00e6, 0x0026, 0x0016, 0x080c,
-+	0x9beb, 0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148,
-+	0x2001, 0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0xa067,
-+	0x0090, 0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004,
-+	0xa08e, 0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037,
-+	0x0103, 0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e,
-+	0x0009, 0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070,
-+	0x7037, 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618,
-+	0x2668, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c,
-+	0x1511, 0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0xa023, 0x0804,
-+	0x8c5b, 0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9fd3, 0x0804,
-+	0x8c5b, 0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x9e19, 0x0804,
-+	0x8c5b, 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x9e30, 0x04d8,
-+	0x6604, 0xa6b6, 0x001f, 0x1118, 0x080c, 0x8729, 0x04a0, 0x6604,
-+	0xa6b6, 0x0000, 0x1118, 0x080c, 0x897d, 0x0468, 0x6604, 0xa6b6,
-+	0x0022, 0x1118, 0x080c, 0x8751, 0x0430, 0x6604, 0xa6b6, 0x0035,
-+	0x1118, 0x080c, 0x87b8, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118,
-+	0x080c, 0x8919, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c,
-+	0x876b, 0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x878b,
-+	0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016,
-+	0x1118, 0x0804, 0x8e1f, 0x0005, 0x080c, 0x8606, 0x0ce0, 0x8c82,
-+	0x8c85, 0x8c82, 0x8cc7, 0x8c82, 0x8dac, 0x8e2d, 0x8c82, 0x8c82,
-+	0x8dfb, 0x8c82, 0x8e0f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005,
-+	0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856, 0x0005, 0x00e6, 0xacf0,
-+	0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c,
-+	0x85c0, 0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xb400,
-+	0x7084, 0xa086, 0x0074, 0x1530, 0x080c, 0xaddc, 0x11b0, 0x00d6,
-+	0x6018, 0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110,
-+	0xc0c5, 0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4ebe,
-+	0x080c, 0x2c86, 0x080c, 0x85c0, 0x0078, 0x2001, 0x000a, 0x080c,
-+	0x4ebe, 0x080c, 0x2c86, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-+	0x6c98, 0x0010, 0x080c, 0x8d99, 0x00ee, 0x0005, 0x6800, 0xd084,
-+	0x0168, 0x2001, 0x0000, 0x080c, 0x4eac, 0x2069, 0xb452, 0x6804,
-+	0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x4eeb, 0x0005, 0x00d6,
-+	0x2011, 0xb421, 0x2204, 0xa086, 0x0074, 0x1904, 0x8d96, 0x6018,
-+	0x2068, 0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x8f42, 0x0804,
-+	0x8d35, 0x080c, 0x8f38, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014,
-+	0xa286, 0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010,
-+	0xa005, 0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833,
-+	0x0200, 0x2001, 0x0006, 0x080c, 0x4ebe, 0x080c, 0x2c86, 0x080c,
-+	0x85c0, 0x0804, 0x8d97, 0x00e6, 0x2071, 0xb435, 0x2e04, 0xd09c,
-+	0x0188, 0x2071, 0xba80, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118,
-+	0xa284, 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110,
-+	0x7112, 0x7216, 0x00ee, 0x6010, 0xa005, 0x0198, 0x2068, 0x6838,
-+	0xd0f4, 0x0178, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1958,
-+	0x2001, 0x0000, 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0xa067,
-+	0x0840, 0x2001, 0x0004, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0003, 0x080c, 0x6c98, 0x0804, 0x8d97, 0x685c, 0xd0e4, 0x01d8,
-+	0x080c, 0x9f63, 0x080c, 0x5a90, 0x0118, 0xd0dc, 0x1904, 0x8cf1,
-+	0x2011, 0xb435, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xb68f, 0x2004,
-+	0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x2838, 0x78e2,
-+	0x00fe, 0x0804, 0x8cf1, 0x080c, 0x9f99, 0x2011, 0xb435, 0x2204,
-+	0xc0a5, 0x2012, 0x0006, 0x080c, 0xaefe, 0x000e, 0x1904, 0x8cf1,
-+	0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x4ebe, 0x2001, 0x0000,
-+	0x080c, 0x4eac, 0x00c6, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100,
-+	0x79ea, 0x7932, 0x7936, 0x00fe, 0x080c, 0x280d, 0x00f6, 0x2079,
-+	0xb400, 0x7976, 0x2100, 0x2009, 0x0000, 0x080c, 0x27e3, 0x7952,
-+	0x00fe, 0x8108, 0x080c, 0x4f0e, 0x2c00, 0x00ce, 0x1904, 0x8cf1,
-+	0x601a, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x601f, 0x0001, 0x6003,
-+	0x0001, 0x6007, 0x0002, 0x080c, 0x6c98, 0x0008, 0x0011, 0x00de,
-+	0x0005, 0x2001, 0x0007, 0x080c, 0x4ebe, 0x2001, 0xb400, 0x2004,
-+	0xa086, 0x0003, 0x1120, 0x2001, 0x0007, 0x080c, 0x4eeb, 0x080c,
-+	0x2c86, 0x080c, 0x85c0, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
-+	0xb400, 0x7084, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003,
-+	0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3efc, 0x00d6, 0x6018,
-+	0x2068, 0x080c, 0x500c, 0x080c, 0x8cb6, 0x00de, 0x080c, 0x8ff1,
-+	0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518,
-+	0x2001, 0x0006, 0x080c, 0x4ebe, 0x00e6, 0x6010, 0xa075, 0x01a8,
-+	0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000,
-+	0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0xa067, 0x0030, 0x7007,
-+	0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2c86,
-+	0x080c, 0x85c0, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x8d99, 0x001e,
-+	0x002e, 0x00ee, 0x0005, 0x2011, 0xb421, 0x2204, 0xa086, 0x0014,
-+	0x1158, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x080c, 0x6c98, 0x0010, 0x080c, 0x8d99, 0x0005, 0x2011,
-+	0xb421, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c,
-+	0x4ebe, 0x080c, 0x85c0, 0x0010, 0x080c, 0x8d99, 0x0005, 0x000b,
-+	0x0005, 0x8c82, 0x8e38, 0x8c82, 0x8e6c, 0x8c82, 0x8ef4, 0x8e2d,
-+	0x8c82, 0x8c82, 0x8f07, 0x8c82, 0x8f17, 0x6604, 0xa686, 0x0003,
-+	0x0904, 0x8dac, 0xa6b6, 0x001e, 0x1110, 0x080c, 0x85c0, 0x0005,
-+	0x00d6, 0x00c6, 0x080c, 0x8f27, 0x1178, 0x2001, 0x0000, 0x080c,
-+	0x4eac, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0002, 0x080c, 0x6c98, 0x00e8, 0x2009, 0xba8e, 0x2104, 0xa086,
-+	0x0009, 0x1160, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005,
-+	0x0170, 0x8001, 0x6842, 0x6017, 0x000a, 0x0058, 0x2009, 0xba8f,
-+	0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x1108, 0x08d0, 0x080c,
-+	0x8d99, 0x00ce, 0x00de, 0x0005, 0x0026, 0x2011, 0x0000, 0x080c,
-+	0x8f35, 0x00d6, 0x2069, 0xb69e, 0x2d04, 0xa005, 0x0168, 0x6018,
-+	0x2068, 0x68a0, 0xa086, 0x007e, 0x1138, 0x2069, 0xb41d, 0x2d04,
-+	0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, 0x0000,
-+	0x080c, 0x4eac, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x6003, 0x0001,
-+	0x6007, 0x0002, 0x080c, 0x6c98, 0x0468, 0x00d6, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x00de, 0x0108, 0x6a34, 0x080c, 0x8bbc, 0x2009,
-+	0xba8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x01e8, 0xa686,
-+	0x000b, 0x01b0, 0x2009, 0xba8f, 0x2104, 0xa084, 0xff00, 0x1118,
-+	0xa686, 0x0009, 0x0188, 0xa086, 0x1900, 0x1150, 0xa686, 0x0009,
-+	0x0158, 0x2001, 0x0004, 0x080c, 0x4ebe, 0x080c, 0x85c0, 0x0010,
-+	0x080c, 0x8d99, 0x002e, 0x0005, 0x00d6, 0xa286, 0x0139, 0x0160,
-+	0x6010, 0x2068, 0x080c, 0x9beb, 0x0148, 0x6834, 0xa086, 0x0139,
-+	0x0118, 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c50, 0x6018, 0x2068,
-+	0x6840, 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842, 0x6017,
-+	0x000a, 0x6007, 0x0016, 0x00de, 0x08e8, 0x68a0, 0xa086, 0x007e,
-+	0x1138, 0x00e6, 0x2071, 0xb400, 0x080c, 0x4b80, 0x00ee, 0x0010,
-+	0x080c, 0x2c60, 0x00de, 0x0860, 0x080c, 0x8f35, 0x1158, 0x2001,
-+	0x0004, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c,
-+	0x6c98, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x8d99, 0x0005, 0x0469,
-+	0x1158, 0x2001, 0x0008, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0005, 0x080c, 0x6c98, 0x0010, 0x080c, 0x8d99, 0x0005, 0x00e9,
-+	0x1158, 0x2001, 0x000a, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x080c, 0x6c98, 0x0010, 0x080c, 0x8d99, 0x0005, 0x2009,
-+	0xba8e, 0x2104, 0xa086, 0x0003, 0x1138, 0x2009, 0xba8f, 0x2104,
-+	0xa084, 0xff00, 0xa086, 0x2a00, 0x0005, 0xa085, 0x0001, 0x0005,
-+	0x00c6, 0x0016, 0xac88, 0x0006, 0x2164, 0x080c, 0x4f79, 0x001e,
-+	0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6018,
-+	0x2068, 0x2071, 0xb435, 0x2e04, 0xa085, 0x0003, 0x2072, 0x080c,
-+	0x8fc6, 0x0560, 0x2009, 0xb435, 0x2104, 0xc0cd, 0x200a, 0x2001,
-+	0xb453, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
-+	0x080c, 0xb06b, 0x2001, 0xb40c, 0x200c, 0xc195, 0x2102, 0x2019,
-+	0x002a, 0x2009, 0x0001, 0x080c, 0x2c33, 0x2071, 0xb400, 0x080c,
-+	0x2a7e, 0x00c6, 0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c,
-+	0x2d5b, 0x8108, 0x1f04, 0x8f77, 0x015e, 0x00ce, 0x080c, 0x8f38,
-+	0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xba80, 0x2079, 0x0100,
-+	0x2e04, 0xa084, 0x00ff, 0x2069, 0xb41c, 0x206a, 0x78e6, 0x0006,
-+	0x8e70, 0x2e04, 0x2069, 0xb41d, 0x206a, 0x78ea, 0x7832, 0x7836,
-+	0x2010, 0xa084, 0xff00, 0x001e, 0xa105, 0x2009, 0xb428, 0x200a,
-+	0x2200, 0xa084, 0x00ff, 0x2008, 0x080c, 0x280d, 0x080c, 0x5a90,
-+	0x0170, 0x2069, 0xba8e, 0x2071, 0xb6b2, 0x6810, 0x2072, 0x6814,
-+	0x7006, 0x6818, 0x700a, 0x681c, 0x700e, 0x080c, 0x9f63, 0x0040,
-+	0x2001, 0x0006, 0x080c, 0x4ebe, 0x080c, 0x2c86, 0x080c, 0x85c0,
-+	0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036,
-+	0x00e6, 0x0156, 0x2019, 0xb428, 0x231c, 0x83ff, 0x01e8, 0x2071,
-+	0xba80, 0x2e14, 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205,
-+	0xa306, 0x1190, 0x2011, 0xba96, 0xad98, 0x000a, 0x20a9, 0x0004,
-+	0x080c, 0x907a, 0x1148, 0x2011, 0xba9a, 0xad98, 0x0006, 0x20a9,
-+	0x0004, 0x080c, 0x907a, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e,
-+	0x0005, 0x00e6, 0x2071, 0xba8c, 0x7004, 0xa086, 0x0014, 0x11a8,
-+	0x7008, 0xa086, 0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084,
-+	0x0f00, 0xa086, 0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac,
-+	0x0110, 0xa006, 0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6,
-+	0x00d6, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x2029, 0xb6e9, 0x252c, 0x2021, 0xb6ef, 0x2424,
-+	0x2061, 0xbc00, 0x2071, 0xb400, 0x7248, 0x7068, 0xa202, 0x16f0,
-+	0x080c, 0xb093, 0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786,
-+	0x0007, 0x0568, 0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538,
-+	0x00c6, 0x6000, 0xa086, 0x0004, 0x1110, 0x080c, 0x1944, 0xa786,
-+	0x0008, 0x1148, 0x080c, 0x9de9, 0x1130, 0x00ce, 0x080c, 0x8bbc,
-+	0x080c, 0x9dae, 0x00a0, 0x6010, 0x2068, 0x080c, 0x9beb, 0x0160,
-+	0xa786, 0x0003, 0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-+	0x080c, 0x53c9, 0x080c, 0x9da2, 0x080c, 0x9dae, 0x00ce, 0xace0,
-+	0x0018, 0x705c, 0xac02, 0x1210, 0x0804, 0x9024, 0x012e, 0x000e,
-+	0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005,
-+	0xa786, 0x0006, 0x1118, 0x080c, 0xb01c, 0x0c30, 0xa786, 0x000a,
-+	0x09e0, 0x08c8, 0x220c, 0x2304, 0xa106, 0x1130, 0x8210, 0x8318,
-+	0x1f04, 0x907a, 0xa006, 0x0005, 0x2304, 0xa102, 0x0218, 0x2001,
-+	0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001, 0x0005, 0x6004,
-+	0xa08a, 0x0080, 0x1a0c, 0x1511, 0x080c, 0x9dd8, 0x0120, 0x080c,
-+	0x9de9, 0x0168, 0x0028, 0x080c, 0x2c86, 0x080c, 0x9de9, 0x0138,
-+	0x080c, 0x7055, 0x080c, 0x85c0, 0x080c, 0x7134, 0x0005, 0x080c,
-+	0x8bbc, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x90c0, 0x90c0, 0x90c0,
-+	0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0, 0x90c0,
-+	0x90c2, 0x90c2, 0x90c2, 0x90c2, 0x90c0, 0x90c0, 0x90c0, 0x90c2,
-+	0x080c, 0x1511, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c,
-+	0x6c52, 0x0126, 0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x0005,
-+	0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x915c,
-+	0xa186, 0x0027, 0x11e8, 0x080c, 0x7055, 0x080c, 0x2c60, 0x00d6,
-+	0x6110, 0x2168, 0x080c, 0x9beb, 0x0168, 0x6837, 0x0103, 0x684b,
-+	0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x080c, 0x53c9,
-+	0x080c, 0x9da2, 0x00de, 0x080c, 0x85c0, 0x080c, 0x7134, 0x0005,
-+	0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040, 0x0428, 0xa186,
-+	0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186, 0x0047, 0x190c,
-+	0x1511, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198, 0x0126, 0x2091,
-+	0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6b39, 0x002e, 0x001e,
-+	0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002, 0x1110, 0x0804,
-+	0x919a, 0x080c, 0x8606, 0x0005, 0x0002, 0x913a, 0x9138, 0x9138,
-+	0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138, 0x9138,
-+	0x9155, 0x9155, 0x9155, 0x9155, 0x9138, 0x9155, 0x9138, 0x9155,
-+	0x080c, 0x1511, 0x080c, 0x7055, 0x00d6, 0x6110, 0x2168, 0x080c,
-+	0x9beb, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006, 0x6847, 0x0000,
-+	0x6850, 0xc0ec, 0x6852, 0x080c, 0x53c9, 0x080c, 0x9da2, 0x00de,
-+	0x080c, 0x85c0, 0x080c, 0x7134, 0x0005, 0x080c, 0x7055, 0x080c,
-+	0x85c0, 0x080c, 0x7134, 0x0005, 0x0002, 0x9172, 0x9170, 0x9170,
-+	0x9170, 0x9170, 0x9170, 0x9170, 0x9170, 0x9170, 0x9170, 0x9170,
-+	0x9184, 0x9184, 0x9184, 0x9184, 0x9170, 0x9193, 0x9170, 0x9184,
-+	0x080c, 0x1511, 0x080c, 0x7055, 0x2001, 0xb6b8, 0x2004, 0x603e,
-+	0x6003, 0x0002, 0x080c, 0x7134, 0x6010, 0xa088, 0x0013, 0x2104,
-+	0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x7055, 0x2001, 0xb6b6,
-+	0x2004, 0x6016, 0x2001, 0xb6b8, 0x2004, 0x603e, 0x6003, 0x000f,
-+	0x080c, 0x7134, 0x0005, 0x080c, 0x7055, 0x080c, 0x85c0, 0x080c,
-+	0x7134, 0x0005, 0xa182, 0x0040, 0x0002, 0x91b0, 0x91b0, 0x91b0,
-+	0x91b0, 0x91b0, 0x91b2, 0x9290, 0x92bf, 0x91b0, 0x91b0, 0x91b0,
-+	0x91b0, 0x91b0, 0x91b0, 0x91b0, 0x91b0, 0x91b0, 0x91b0, 0x91b0,
-+	0x080c, 0x1511, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xba80,
-+	0x7124, 0x610a, 0x2071, 0xba8c, 0x6110, 0x2168, 0x7614, 0xa6b4,
-+	0x0fff, 0x86ff, 0x0904, 0x925a, 0xa68c, 0x0c00, 0x01e8, 0x00f6,
-+	0x2c78, 0x080c, 0x52c6, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180,
-+	0x6020, 0xd0dc, 0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814,
-+	0xa306, 0x1904, 0x926c, 0x731c, 0x6810, 0xa306, 0x1904, 0x926c,
-+	0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002,
-+	0x0518, 0xa186, 0x0028, 0x1128, 0x080c, 0x9dc7, 0x684b, 0x001c,
-+	0x00e8, 0xd6dc, 0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170,
-+	0x6914, 0x6a10, 0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118,
-+	0x701c, 0xa206, 0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4,
-+	0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103,
-+	0x6e46, 0xa01e, 0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001,
-+	0xba99, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x0804, 0x91c1, 0x7328,
-+	0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019,
-+	0x0008, 0x0036, 0x2308, 0x2019, 0xba98, 0xad90, 0x0019, 0x080c,
-+	0x98a6, 0x003e, 0xd6cc, 0x0904, 0x927f, 0x7124, 0x695a, 0x81ff,
-+	0x0904, 0x927f, 0xa192, 0x0021, 0x1260, 0x2071, 0xba98, 0x831c,
-+	0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x98a6, 0x080c, 0xa0c8,
-+	0x04b0, 0x6838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c68,
-+	0x00f6, 0x2d78, 0x080c, 0x984b, 0x00fe, 0x080c, 0xa0c8, 0x080c,
-+	0x9896, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe, 0x0188,
-+	0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158, 0x6850, 0xd0bc,
-+	0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9ec6, 0x00de, 0x00ee,
-+	0x00f0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac,
-+	0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x941c, 0x080c,
-+	0x53c9, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e,
-+	0x080c, 0x9e94, 0x00de, 0x00ee, 0x1110, 0x080c, 0x85c0, 0x0005,
-+	0x00f6, 0x6003, 0x0003, 0x2079, 0xba8c, 0x7c04, 0x7b00, 0x7e0c,
-+	0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0138, 0x6003, 0x0002,
-+	0x00fe, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0x797c, 0xa10a,
-+	0x2300, 0x7a80, 0xa213, 0x2600, 0xa102, 0x2500, 0xa203, 0x0e90,
-+	0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f, 0x0000, 0x2c10,
-+	0x080c, 0x1f7a, 0x080c, 0x6cb5, 0x080c, 0x71f1, 0x0005, 0x2001,
-+	0xb6b8, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
-+	0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856, 0x0005, 0xa182, 0x0040,
-+	0x0002, 0x92e4, 0x92e4, 0x92e4, 0x92e4, 0x92e4, 0x92e6, 0x9379,
-+	0x92e4, 0x92e4, 0x938f, 0x93f3, 0x92e4, 0x92e4, 0x92e4, 0x92e4,
-+	0x9402, 0x92e4, 0x92e4, 0x92e4, 0x080c, 0x1511, 0x0076, 0x00f6,
-+	0x00e6, 0x00d6, 0x2071, 0xba8c, 0x6110, 0x2178, 0x7614, 0xa6b4,
-+	0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c,
-+	0x82ff, 0x0110, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x9374, 0xa694,
-+	0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e,
-+	0xa284, 0x0300, 0x0904, 0x9374, 0x080c, 0x15f4, 0x090c, 0x1511,
-+	0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
-+	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
-+	0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
-+	0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
-+	0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
-+	0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
-+	0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
-+	0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
-+	0x2019, 0xba98, 0xad90, 0x0019, 0x080c, 0x98a6, 0x003e, 0xd6cc,
-+	0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
-+	0x2071, 0xba98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
-+	0x98a6, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
-+	0x0c78, 0x2d78, 0x080c, 0x984b, 0x00de, 0x00ee, 0x00fe, 0x007e,
-+	0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xba8c, 0x7c04, 0x7b00,
-+	0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
-+	0x00fe, 0x2c10, 0x080c, 0x1f7a, 0x080c, 0x7d0a, 0x0005, 0x00d6,
-+	0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe, 0x0120, 0x2001, 0xb6b8,
-+	0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x70e7, 0x080c, 0x71f1,
-+	0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x93f1, 0xd1cc, 0x0540,
-+	0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850,
-+	0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156,
-+	0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x93b9, 0x015e,
-+	0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x161b,
-+	0x0418, 0x0016, 0x080c, 0x161b, 0x00de, 0x080c, 0x9896, 0x00e0,
-+	0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180,
-+	0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118,
-+	0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010,
-+	0x684b, 0x0000, 0x080c, 0x53c9, 0x080c, 0x9e94, 0x1110, 0x080c,
-+	0x85c0, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7f8e, 0x6003,
-+	0x0002, 0x2001, 0xb6b8, 0x2004, 0x603e, 0x080c, 0x70e7, 0x080c,
-+	0x71f1, 0x0005, 0x080c, 0x70e7, 0x080c, 0x2c60, 0x00d6, 0x6110,
-+	0x2168, 0x080c, 0x9beb, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
-+	0x6847, 0x0000, 0x080c, 0x53c9, 0x080c, 0x9da2, 0x00de, 0x080c,
-+	0x85c0, 0x080c, 0x71f1, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138,
-+	0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
-+	0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x9440, 0x9440, 0x9440,
-+	0x9440, 0x9440, 0x9442, 0x9440, 0x94fd, 0x9509, 0x9440, 0x9440,
-+	0x9440, 0x9440, 0x9440, 0x9440, 0x9440, 0x9440, 0x9440, 0x9440,
-+	0x080c, 0x1511, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xba8c,
-+	0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c,
-+	0x52c6, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4,
-+	0x0120, 0x080c, 0x9ec6, 0x0804, 0x94f8, 0x7e46, 0x7f4c, 0xc7e5,
-+	0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e,
-+	0x86ff, 0x0904, 0x94ee, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120,
-+	0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x94ec,
-+	0xa686, 0x0100, 0x1140, 0x2001, 0xba99, 0x2004, 0xa005, 0x1118,
-+	0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x15f4, 0x090c, 0x1511, 0x2d00,
-+	0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838,
-+	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
-+	0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
-+	0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
-+	0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
-+	0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
-+	0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
-+	0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
-+	0x2019, 0xba98, 0xad90, 0x0019, 0x080c, 0x98a6, 0x003e, 0xd6cc,
-+	0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
-+	0x2071, 0xba98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
-+	0x98a6, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
-+	0x0c78, 0x2d78, 0x080c, 0x984b, 0xd6dc, 0x1110, 0xa006, 0x0030,
-+	0x2001, 0x0001, 0x2071, 0xba8c, 0x7218, 0x731c, 0x080c, 0x18a9,
-+	0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x2001, 0xb6b8, 0x2004,
-+	0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856,
-+	0x0005, 0x2001, 0xb6b8, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002,
-+	0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x9614, 0x603f, 0x0000,
-+	0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe, 0x0560, 0x6814, 0x6910,
-+	0xa115, 0x0540, 0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x0510,
-+	0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f,
-+	0x0000, 0x6020, 0xd0f4, 0x1158, 0x697c, 0x6810, 0xa102, 0x603a,
-+	0x6980, 0x6814, 0xa103, 0x6036, 0x6020, 0xc0f5, 0x6022, 0x00d6,
-+	0x6018, 0x2068, 0x683c, 0x8000, 0x683e, 0x00de, 0x080c, 0x9ec6,
-+	0x0804, 0x9614, 0x694c, 0xd1cc, 0x0904, 0x95e4, 0x6948, 0x6838,
-+	0xd0fc, 0x0904, 0x95a7, 0x0016, 0x684c, 0x0006, 0x6850, 0x0006,
-+	0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01e0,
-+	0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c, 0x00e8,
-+	0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c, 0xa050,
-+	0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128, 0x684b,
-+	0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130, 0x6810,
-+	0x6914, 0xa115, 0x0110, 0x080c, 0x941c, 0x6848, 0x784a, 0x6860,
-+	0x7862, 0x685c, 0x785e, 0xad90, 0x000d, 0xaf98, 0x000d, 0x2009,
-+	0x0020, 0x0156, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04,
-+	0x9593, 0x015e, 0x00fe, 0x000e, 0x6852, 0x000e, 0x684e, 0x080c,
-+	0xa0c8, 0x001e, 0x2168, 0x080c, 0x161b, 0x0804, 0x960f, 0x0016,
-+	0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01e0,
-+	0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c, 0x00e8,
-+	0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c, 0xa050,
-+	0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128, 0x684b,
-+	0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130, 0x6810,
-+	0x6914, 0xa115, 0x0110, 0x080c, 0x941c, 0x6860, 0x7862, 0x685c,
-+	0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x161b, 0x00de, 0x080c,
-+	0xa0c8, 0x080c, 0x9896, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184,
-+	0x00ff, 0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b,
-+	0x001c, 0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0xa050,
-+	0x0118, 0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b,
-+	0x0007, 0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810,
-+	0x6914, 0xa115, 0x0110, 0x080c, 0x941c, 0x080c, 0x53c9, 0x080c,
-+	0x9e94, 0x1110, 0x080c, 0x85c0, 0x00de, 0x0005, 0x080c, 0x7055,
-+	0x0010, 0x080c, 0x70e7, 0x080c, 0x9beb, 0x01c0, 0x00d6, 0x6110,
-+	0x2168, 0x6837, 0x0103, 0x2009, 0xb40c, 0x210c, 0xd18c, 0x11c0,
-+	0xd184, 0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c,
-+	0xb303, 0x6847, 0x0000, 0x080c, 0x53c9, 0x00de, 0x080c, 0x85c0,
-+	0x080c, 0x7134, 0x080c, 0x71f1, 0x0005, 0x684b, 0x0004, 0x0c88,
-+	0x684b, 0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9659, 0x9659,
-+	0x9659, 0x9659, 0x9659, 0x965b, 0x9659, 0x965e, 0x9659, 0x9659,
-+	0x9659, 0x9659, 0x9659, 0x9659, 0x9659, 0x9659, 0x9659, 0x9659,
-+	0x9659, 0x080c, 0x1511, 0x080c, 0x85c0, 0x0005, 0x0006, 0x0026,
-+	0xa016, 0x080c, 0x1856, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085,
-+	0x0002, 0x9672, 0x9670, 0x9670, 0x967e, 0x9670, 0x9670, 0x9670,
-+	0x080c, 0x1511, 0x6003, 0x0001, 0x6106, 0x080c, 0x6c52, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x0005, 0x0026, 0x0056,
-+	0x00d6, 0x00e6, 0x2071, 0xba80, 0x7224, 0x6212, 0x7220, 0x080c,
-+	0x9bdb, 0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018,
-+	0x6d18, 0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x98b6, 0x00ce,
-+	0x0128, 0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087,
-+	0x6003, 0x0001, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00f6, 0x2278,
-+	0x080c, 0x52c6, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6,
-+	0x2260, 0x603f, 0x0000, 0x080c, 0x9ec6, 0x00ce, 0x00ee, 0x00de,
-+	0x005e, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a,
-+	0x0085, 0x0a0c, 0x1511, 0xa08a, 0x008c, 0x1a0c, 0x1511, 0xa082,
-+	0x0085, 0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
-+	0x1511, 0x080c, 0x7055, 0x080c, 0x9dae, 0x080c, 0x7134, 0x0005,
-+	0x96df, 0x96e1, 0x96e1, 0x96df, 0x96df, 0x96df, 0x96df, 0x080c,
-+	0x1511, 0x080c, 0x7055, 0x080c, 0x9dae, 0x080c, 0x7134, 0x0005,
-+	0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8,
-+	0xa186, 0x0027, 0x11e8, 0x080c, 0x7055, 0x080c, 0x2c60, 0x00d6,
-+	0x6010, 0x2068, 0x080c, 0x9beb, 0x0150, 0x6837, 0x0103, 0x6847,
-+	0x0000, 0x684b, 0x0029, 0x080c, 0x53c9, 0x080c, 0x9da2, 0x00de,
-+	0x080c, 0x85c0, 0x080c, 0x7134, 0x0005, 0x080c, 0x8606, 0x0ce0,
-+	0xa186, 0x0014, 0x1dd0, 0x080c, 0x7055, 0x00d6, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
-+	0x0006, 0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x972f, 0x972d,
-+	0x972d, 0x972d, 0x972d, 0x972d, 0x9747, 0x080c, 0x1511, 0x080c,
-+	0x7055, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118,
-+	0xa186, 0x0035, 0x1118, 0x2001, 0xb6b6, 0x0010, 0x2001, 0xb6b7,
-+	0x2004, 0x6016, 0x6003, 0x000c, 0x080c, 0x7134, 0x0005, 0x080c,
-+	0x7055, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118,
-+	0xa186, 0x0035, 0x1118, 0x2001, 0xb6b6, 0x0010, 0x2001, 0xb6b7,
-+	0x2004, 0x6016, 0x6003, 0x000e, 0x080c, 0x7134, 0x0005, 0xa182,
-+	0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x8606,
-+	0x0005, 0x9770, 0x9770, 0x9770, 0x9770, 0x9772, 0x97cb, 0x9770,
-+	0x080c, 0x1511, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe,
-+	0x0168, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118,
-+	0xa186, 0x0035, 0x1118, 0x00de, 0x0804, 0x97de, 0x080c, 0x9beb,
-+	0x1118, 0x080c, 0x9da2, 0x00f0, 0x6010, 0x2068, 0x684c, 0xd0e4,
-+	0x1110, 0x080c, 0x9da2, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
-+	0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118, 0x684b,
-+	0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9e63, 0x6847, 0x0000,
-+	0x080c, 0x53c9, 0x2c68, 0x080c, 0x856a, 0x01c0, 0x6003, 0x0001,
-+	0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xba8e, 0x210c, 0x6136,
-+	0x2009, 0xba8f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c, 0x9fb8,
-+	0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x6c52, 0x2d60, 0x080c,
-+	0x85c0, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe,
-+	0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035, 0x0130,
-+	0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6, 0x2c68,
-+	0x080c, 0xa09b, 0x1904, 0x9823, 0x080c, 0x856a, 0x01d8, 0x6106,
-+	0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928, 0x612a,
-+	0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136,
-+	0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9fb8, 0x080c, 0x6c52,
-+	0x080c, 0x7134, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068, 0x080c,
-+	0x9beb, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, 0xc0ec,
-+	0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b, 0x0002,
-+	0x0020, 0x684b, 0x0005, 0x080c, 0x9e63, 0x6847, 0x0000, 0x080c,
-+	0x53c9, 0x080c, 0x9da2, 0x00de, 0x080c, 0x85c0, 0x0005, 0x0016,
-+	0x00d6, 0x6010, 0x2068, 0x080c, 0x9beb, 0x0140, 0x6837, 0x0103,
-+	0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x53c9, 0x00de, 0x001e,
-+	0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, 0x0027,
-+	0x0118, 0x080c, 0x8606, 0x0030, 0x080c, 0x7055, 0x080c, 0x9dae,
-+	0x080c, 0x7134, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, 0x2029,
-+	0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130,
-+	0x2069, 0xba98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
-+	0x001d, 0x080c, 0x98a6, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0110,
-+	0x080c, 0x161b, 0x080c, 0x15f4, 0x0500, 0x8528, 0x6837, 0x0110,
-+	0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, 0x2608,
-+	0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, 0x003c,
-+	0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, 0xa5ad,
-+	0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, 0xa5ad,
-+	0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, 0x8dff,
-+	0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, 0x53c9,
-+	0x2f68, 0x0cb8, 0x080c, 0x53c9, 0x00fe, 0x0005, 0x0156, 0xa184,
-+	0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012,
-+	0x8318, 0x8210, 0x1f04, 0x98ad, 0x015e, 0x0005, 0x0066, 0x0126,
-+	0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f, 0x0083,
-+	0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031,
-+	0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005,
-+	0x98ed, 0x98ed, 0x98e8, 0x990f, 0x98db, 0x98e8, 0x990f, 0x98e8,
-+	0x98e8, 0x98db, 0x98e8, 0x080c, 0x1511, 0x0036, 0x2019, 0x0010,
-+	0x080c, 0xac63, 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005,
-+	0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8,
-+	0x6010, 0x2068, 0x080c, 0x9beb, 0x01c0, 0x6834, 0xa086, 0x0139,
-+	0x1128, 0x684b, 0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001,
-+	0x0005, 0x080c, 0x549c, 0x080c, 0x9e63, 0x080c, 0x53c9, 0x080c,
-+	0x85c0, 0xa085, 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000,
-+	0xa08a, 0x0010, 0x1a0c, 0x1511, 0x000b, 0x0005, 0x9926, 0x9947,
-+	0x9928, 0x9966, 0x9944, 0x9926, 0x98e8, 0x98ed, 0x98ed, 0x98e8,
-+	0x98e8, 0x98e8, 0x98e8, 0x98e8, 0x98e8, 0x98e8, 0x080c, 0x1511,
-+	0x86ff, 0x11b8, 0x601c, 0xa086, 0x0006, 0x0198, 0x00d6, 0x6010,
-+	0x2068, 0x080c, 0x9beb, 0x0110, 0x080c, 0x9e63, 0x00de, 0x6007,
-+	0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6c52, 0x080c,
-+	0x7134, 0xa085, 0x0001, 0x0005, 0x080c, 0x1944, 0x0c08, 0x00e6,
-+	0x2071, 0xb6e0, 0x7024, 0xac06, 0x1110, 0x080c, 0x7f03, 0x601c,
-+	0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049,
-+	0x0001, 0x2c40, 0x080c, 0x80da, 0x009e, 0x008e, 0x0010, 0x080c,
-+	0x7e02, 0x00ee, 0x1928, 0x080c, 0x98e8, 0x0005, 0x0036, 0x00e6,
-+	0x2071, 0xb6e0, 0x703c, 0xac06, 0x1140, 0x2019, 0x0000, 0x080c,
-+	0x7f8e, 0x00ee, 0x003e, 0x0804, 0x9928, 0x080c, 0x8200, 0x00ee,
-+	0x003e, 0x1904, 0x9928, 0x080c, 0x98e8, 0x0005, 0x00c6, 0x601c,
-+	0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9997, 0x9a04, 0x9b4a,
-+	0x99a2, 0x9dae, 0x9997, 0xac55, 0x85c0, 0x9a04, 0x9990, 0x9bb5,
-+	0x080c, 0x1511, 0x080c, 0x9de9, 0x1110, 0x080c, 0x8bbc, 0x0005,
-+	0x080c, 0x7055, 0x080c, 0x7134, 0x080c, 0x85c0, 0x0005, 0x6017,
-+	0x0001, 0x0005, 0x080c, 0x9beb, 0x0120, 0x6010, 0xa080, 0x0019,
-+	0x2c02, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1511, 0x000b, 0x0005,
-+	0x99c0, 0x99c2, 0x99e2, 0x99f4, 0x9a01, 0x99c0, 0x9997, 0x9997,
-+	0x9997, 0x99f4, 0x99f4, 0x99c0, 0x99c0, 0x99c0, 0x99c0, 0x99fe,
-+	0x080c, 0x1511, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052,
-+	0x2071, 0xb6e0, 0x7024, 0xac06, 0x0190, 0x080c, 0x7e02, 0x6007,
-+	0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xb6b7, 0x2004,
-+	0x6016, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00ee, 0x0005, 0x6017,
-+	0x0001, 0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852,
-+	0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c,
-+	0x6c52, 0x080c, 0x7134, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010,
-+	0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x85c0,
-+	0x0005, 0x080c, 0x1944, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c,
-+	0x1511, 0x000b, 0x0005, 0x9a1b, 0x999f, 0x9a1d, 0x9a1b, 0x9a1d,
-+	0x9a1d, 0x9998, 0x9a1b, 0x9992, 0x9992, 0x9a1b, 0x9a1b, 0x9a1b,
-+	0x9a1b, 0x9a1b, 0x9a1b, 0x080c, 0x1511, 0x00d6, 0x6018, 0x2068,
-+	0x6804, 0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x1511,
-+	0x000b, 0x0005, 0x9a36, 0x9af0, 0x9a38, 0x9a72, 0x9a38, 0x9a72,
-+	0x9a38, 0x9a42, 0x9a36, 0x9a72, 0x9a36, 0x9a5e, 0x080c, 0x1511,
-+	0x6004, 0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e,
-+	0x0002, 0x0558, 0x6004, 0x080c, 0x9de9, 0x0904, 0x9b09, 0xa08e,
-+	0x0021, 0x0904, 0x9b0d, 0xa08e, 0x0022, 0x0904, 0x9b09, 0xa08e,
-+	0x003d, 0x0904, 0x9b0d, 0xa08e, 0x0039, 0x0904, 0x9b11, 0xa08e,
-+	0x0035, 0x0904, 0x9b11, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001,
-+	0x1150, 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de,
-+	0xa086, 0x0006, 0x0110, 0x080c, 0x2c60, 0x080c, 0x8bbc, 0x080c,
-+	0x9dae, 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904,
-+	0x9ae1, 0xa186, 0x0002, 0x15d8, 0x2001, 0xb435, 0x2004, 0xd08c,
-+	0x1198, 0x080c, 0x5a90, 0x1180, 0x2001, 0xb69f, 0x2003, 0x0001,
-+	0x2001, 0xb400, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5ad4,
-+	0x080c, 0x59c8, 0x0804, 0x9b33, 0x6018, 0x2068, 0x2001, 0xb435,
-+	0x2004, 0xd0ac, 0x1904, 0x9b33, 0x68a0, 0xd0bc, 0x1904, 0x9b33,
-+	0x6840, 0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013,
-+	0x0000, 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c,
-+	0x856a, 0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de,
-+	0x00ce, 0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028,
-+	0x2004, 0xa086, 0x007e, 0x1170, 0x2009, 0xb435, 0x2104, 0xc085,
-+	0x200a, 0x00e6, 0x2071, 0xb400, 0x080c, 0x4b80, 0x00ee, 0x080c,
-+	0x8bbc, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x2c60, 0x00e6, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x2c86, 0x012e, 0x00ee, 0x080c, 0x9dae,
-+	0x0005, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x6003, 0x0001, 0x6007,
-+	0x0002, 0x080c, 0x6c98, 0x080c, 0x7134, 0x00de, 0x00ce, 0x0c80,
-+	0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068,
-+	0x6840, 0xa084, 0x00ff, 0xa005, 0x0904, 0x9ab7, 0x8001, 0x6842,
-+	0x6003, 0x0001, 0x080c, 0x6c98, 0x080c, 0x7134, 0x00de, 0x00ce,
-+	0x08b8, 0x080c, 0x8bbc, 0x0804, 0x9a6f, 0x080c, 0x8bea, 0x0804,
-+	0x9a6f, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xa09b, 0x00de, 0x0118,
-+	0x080c, 0x85c0, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff,
-+	0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
-+	0x6038, 0x600a, 0x2001, 0xb6b7, 0x2004, 0x6016, 0x080c, 0x6c52,
-+	0x080c, 0x7134, 0x0005, 0x00de, 0x00ce, 0x080c, 0x8bbc, 0x080c,
-+	0x2c60, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2c86, 0x6013,
-+	0x0000, 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e,
-+	0x00ee, 0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1511, 0x000b,
-+	0x0005, 0x9b61, 0x9b61, 0x9b61, 0x9b61, 0x9b61, 0x9b61, 0x9b61,
-+	0x9b61, 0x9b61, 0x9997, 0x9b61, 0x999f, 0x9b63, 0x999f, 0x9b70,
-+	0x9b61, 0x080c, 0x1511, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007,
-+	0x008b, 0x6003, 0x000d, 0x080c, 0x6c52, 0x080c, 0x7134, 0x0005,
-+	0x080c, 0x9da2, 0x080c, 0x9beb, 0x0580, 0x080c, 0x2c60, 0x00d6,
-+	0x080c, 0x9beb, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b,
-+	0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x53c9,
-+	0x2c68, 0x080c, 0x856a, 0x0150, 0x6818, 0x601a, 0x080c, 0x9fb8,
-+	0x00c6, 0x2d60, 0x080c, 0x9dae, 0x00ce, 0x0008, 0x2d60, 0x00de,
-+	0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001,
-+	0x080c, 0x6c98, 0x080c, 0x7134, 0x0078, 0x6030, 0xa08c, 0xff00,
-+	0x810f, 0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x080c,
-+	0x2c60, 0x08b0, 0x080c, 0x9dae, 0x0005, 0x6000, 0xa08a, 0x0010,
-+	0x1a0c, 0x1511, 0x000b, 0x0005, 0x9bcc, 0x9bcc, 0x9bcc, 0x9bce,
-+	0x9bce, 0x9bcc, 0x9bcc, 0x9bcc, 0x9bcc, 0x9bcc, 0x9bcc, 0x9bcc,
-+	0x9bcc, 0x9bcc, 0x9bcc, 0x9bcc, 0x080c, 0x1511, 0x080c, 0x8200,
-+	0x190c, 0x1511, 0x6110, 0x2168, 0x684b, 0x0006, 0x080c, 0x53c9,
-+	0x080c, 0x85c0, 0x0005, 0xa284, 0x0007, 0x1158, 0xa282, 0xbc00,
-+	0x0240, 0x2001, 0xb417, 0x2004, 0xa202, 0x1218, 0xa085, 0x0001,
-+	0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210, 0xa294, 0xf000, 0x002e,
-+	0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000,
-+	0x2061, 0xbc00, 0x2071, 0xb400, 0x7348, 0x7068, 0xa302, 0x12a8,
-+	0x601c, 0xa206, 0x1160, 0x080c, 0x9f43, 0x0148, 0x080c, 0x9de9,
-+	0x1110, 0x080c, 0x8bbc, 0x00c6, 0x080c, 0x85c0, 0x00ce, 0xace0,
-+	0x0018, 0x705c, 0xac02, 0x1208, 0x0c38, 0x012e, 0x000e, 0x003e,
-+	0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0xb535,
-+	0x210c, 0x81ff, 0x0128, 0x2061, 0xb7f4, 0x611a, 0x080c, 0x2c60,
-+	0xa006, 0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
-+	0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x856a,
-+	0x005e, 0x0180, 0x6612, 0x651a, 0x080c, 0x9fb8, 0x601f, 0x0003,
-+	0x2009, 0x004b, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x005e,
-+	0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091,
-+	0x8000, 0x62a0, 0x00c6, 0x080c, 0x9e67, 0x005e, 0x0550, 0x6013,
-+	0x0000, 0x651a, 0x080c, 0x9fb8, 0x601f, 0x0003, 0x0016, 0x00c6,
-+	0x2560, 0x080c, 0x516b, 0x00ce, 0x080c, 0x6dba, 0x0076, 0x2039,
-+	0x0000, 0x080c, 0x6cc7, 0x2c08, 0x080c, 0xae05, 0x007e, 0x001e,
-+	0xd184, 0x0128, 0x080c, 0x85c0, 0xa085, 0x0001, 0x0030, 0x2009,
-+	0x004c, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce,
-+	0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
-+	0x856a, 0x2c78, 0x00ce, 0x0180, 0x7e12, 0x2c00, 0x781a, 0x781f,
-+	0x0003, 0x2021, 0x0005, 0x080c, 0x9ce1, 0x2f60, 0x2009, 0x004d,
-+	0x080c, 0x85ef, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005,
-+	0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c, 0x856a, 0x2c78, 0x00ce,
-+	0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005,
-+	0x0481, 0x2f60, 0x2009, 0x004e, 0x080c, 0x85ef, 0xa085, 0x0001,
-+	0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6,
-+	0x080c, 0x856a, 0x2c78, 0x00ce, 0x01c0, 0x7e12, 0x2c00, 0x781a,
-+	0x781f, 0x0003, 0x2021, 0x0004, 0x00a1, 0x2001, 0xb6a0, 0x2004,
-+	0xd0fc, 0x0120, 0x2f60, 0x080c, 0x85c0, 0x0028, 0x2f60, 0x2009,
-+	0x0052, 0x080c, 0x85ef, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe,
-+	0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x510d,
-+	0x0118, 0x2001, 0x9ce6, 0x0028, 0x080c, 0x50dd, 0x0158, 0x2001,
-+	0x9cec, 0x0006, 0xa00e, 0x2400, 0x080c, 0x549c, 0x080c, 0x53c9,
-+	0x000e, 0x0807, 0x2418, 0x080c, 0x6ff4, 0x62a0, 0x0086, 0x2041,
-+	0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6dd3, 0x008e, 0x080c,
-+	0x6cc7, 0x2f08, 0x2648, 0x080c, 0xae05, 0x613c, 0x81ff, 0x090c,
-+	0x6e88, 0x080c, 0x7134, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
-+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0188,
-+	0x660a, 0x611a, 0x080c, 0x9fb8, 0x601f, 0x0001, 0x2d00, 0x6012,
-+	0x2009, 0x001f, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce,
-+	0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
-+	0x080c, 0x856a, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9fb8,
-+	0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x85ef,
-+	0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
-+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0188,
-+	0x660a, 0x611a, 0x080c, 0x9fb8, 0x601f, 0x0001, 0x2d00, 0x6012,
-+	0x2009, 0x003d, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce,
-+	0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
-+	0x080c, 0x9e67, 0x001e, 0x0180, 0x611a, 0x080c, 0x9fb8, 0x601f,
-+	0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x85ef, 0xa085,
-+	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
-+	0x2091, 0x8000, 0x00c6, 0x080c, 0x856a, 0x001e, 0x0188, 0x660a,
-+	0x611a, 0x080c, 0x9fb8, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
-+	0x0044, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
-+	0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff,
-+	0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000,
-+	0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001,
-+	0xb6b6, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004,
-+	0x6016, 0x080c, 0xb2bd, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066,
-+	0x00c6, 0x00d6, 0x2031, 0xb453, 0x2634, 0xd6e4, 0x0128, 0x6618,
-+	0x2660, 0x6e48, 0x080c, 0x5096, 0x00de, 0x00ce, 0x006e, 0x0005,
-+	0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003,
-+	0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e,
-+	0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086,
-+	0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085,
-+	0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
-+	0x00c6, 0x080c, 0x856a, 0x001e, 0x0190, 0x611a, 0x080c, 0x9fb8,
-+	0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2c60, 0x2009, 0x0028,
-+	0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
-+	0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xb421, 0x2204, 0xa086,
-+	0x0074, 0x1148, 0x080c, 0x8f38, 0x6003, 0x0001, 0x6007, 0x0029,
-+	0x080c, 0x6c98, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x85c0, 0x0005,
-+	0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4ebe, 0x00e8,
-+	0xa186, 0x0015, 0x11e8, 0x2011, 0xb421, 0x2204, 0xa086, 0x0014,
-+	0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x500c, 0x00de, 0x080c,
-+	0x8ff1, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
-+	0x0138, 0x2001, 0x0006, 0x080c, 0x4ebe, 0x080c, 0x8743, 0x0020,
-+	0x080c, 0x8bbc, 0x080c, 0x85c0, 0x0005, 0x6848, 0xa086, 0x0005,
-+	0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6,
-+	0x0126, 0x2071, 0xb400, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001,
-+	0x0608, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
-+	0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbc00, 0x0c98,
-+	0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, 0xa502,
-+	0x1230, 0x754e, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704f,
-+	0xbc00, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xba8c, 0x7014,
-+	0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
-+	0x080c, 0x6c52, 0x080c, 0x7134, 0x00ee, 0x0005, 0x00c6, 0x00f6,
-+	0x2c78, 0x080c, 0x52c6, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f,
-+	0x0013, 0x00ce, 0x0005, 0x9997, 0x9ebe, 0x9ec1, 0x9ec4, 0xb0aa,
-+	0xb0c5, 0xb0c8, 0x9997, 0x9997, 0x080c, 0x1511, 0xe000, 0xe000,
-+	0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78,
-+	0x080c, 0x52c6, 0x0538, 0x080c, 0x856a, 0x1128, 0x2001, 0xb6b8,
-+	0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9fb8, 0x781c,
-+	0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020,
-+	0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007,
-+	0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x6c52, 0x080c,
-+	0x7134, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032,
-+	0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a,
-+	0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078,
-+	0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834,
-+	0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
-+	0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001,
-+	0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x6c52, 0x6803, 0x0002,
-+	0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x52c6, 0x1118,
-+	0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022,
-+	0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x1944,
-+	0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034,
-+	0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e,
-+	0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140,
-+	0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001,
-+	0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
-+	0x2001, 0xb6b2, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
-+	0x6b05, 0x2001, 0xb6b6, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
-+	0x2001, 0xb6b4, 0x200c, 0x8000, 0x2014, 0x2071, 0xb68e, 0x711a,
-+	0x721e, 0x2001, 0x0064, 0x080c, 0x6b05, 0x2001, 0xb6b7, 0x82ff,
-+	0x1110, 0x2011, 0x0014, 0x2202, 0x2009, 0xb6b8, 0xa280, 0x000a,
-+	0x200a, 0x080c, 0x52eb, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
-+	0x0005, 0x0006, 0x00e6, 0x2001, 0xb6b6, 0x2003, 0x0028, 0x2001,
-+	0xb6b7, 0x2003, 0x0014, 0x2071, 0xb68e, 0x701b, 0x0000, 0x701f,
-+	0x07d0, 0x2001, 0xb6b8, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005,
-+	0x00d6, 0x6054, 0xa06d, 0x0110, 0x080c, 0x160b, 0x00de, 0x0005,
-+	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x856a,
-+	0x001e, 0x0178, 0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012,
-+	0x2009, 0x0033, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce,
-+	0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xb400,
-+	0xa186, 0x0015, 0x1500, 0x7084, 0xa086, 0x0018, 0x11e0, 0x6010,
-+	0x2068, 0x6a3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x72f2, 0x01d8,
-+	0x7070, 0x6a50, 0xa206, 0x1160, 0x7074, 0x6a54, 0xa206, 0x1140,
-+	0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2ca5,
-+	0x080c, 0x8743, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x85c0, 0x00fe,
-+	0x00ee, 0x00de, 0x0005, 0x7054, 0x6a54, 0xa206, 0x0d48, 0x0c80,
-+	0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x856a, 0x001e,
-+	0x0180, 0x611a, 0x080c, 0x9fb8, 0x601f, 0x0001, 0x2d00, 0x6012,
-+	0x2009, 0x0043, 0x080c, 0x85ef, 0xa085, 0x0001, 0x012e, 0x00ce,
-+	0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xb400,
-+	0xa186, 0x0015, 0x11c0, 0x7084, 0xa086, 0x0004, 0x11a0, 0x6010,
-+	0xa0e8, 0x000f, 0x2c78, 0x080c, 0x72f2, 0x01a8, 0x7070, 0x6a08,
-+	0xa206, 0x1130, 0x7074, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2c60,
-+	0x080c, 0x8743, 0x0020, 0x080c, 0x8bbc, 0x080c, 0x85c0, 0x00fe,
-+	0x00ee, 0x00de, 0x0005, 0x7054, 0x6a0c, 0xa206, 0x0d78, 0x0c80,
-+	0x0016, 0x0026, 0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100,
-+	0xa205, 0x0150, 0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120,
-+	0x6962, 0x6a5e, 0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6,
-+	0x0036, 0x6310, 0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x11a0,
-+	0x00c6, 0x6318, 0x2360, 0x2009, 0x0000, 0x6838, 0xd0f4, 0x1140,
-+	0x080c, 0x520b, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d,
-+	0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66, 0x3918, 0xa398, 0x0006,
-+	0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6, 0x6318, 0x2360, 0x6004,
-+	0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c, 0x53c9, 0x6013, 0x0000,
-+	0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186, 0x0035,
-+	0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9bdb, 0x01f0, 0x2260,
-+	0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190, 0x6834,
-+	0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834, 0xa106,
-+	0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018, 0x6918,
-+	0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001, 0x0cc8,
-+	0x6944, 0xd1cc, 0x0198, 0xa18c, 0x00ff, 0xa18e, 0x0002, 0x1170,
-+	0xad88, 0x001e, 0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001,
-+	0x1128, 0x6810, 0x6914, 0xa115, 0x190c, 0x941c, 0x0005, 0x0066,
-+	0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1511, 0x0013, 0x006e, 0x0005,
-+	0xa0f8, 0xa5cf, 0xa6f5, 0xa0f8, 0xa0f8, 0xa0f8, 0xa0f8, 0xa0f8,
-+	0xa130, 0xa779, 0xa0f8, 0xa0f8, 0xa0f8, 0xa0f8, 0xa0f8, 0xa0f8,
-+	0x080c, 0x1511, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1511,
-+	0x0013, 0x006e, 0x0005, 0xa113, 0xabfa, 0xa113, 0xa113, 0xa113,
-+	0xa113, 0xa113, 0xa113, 0xabbe, 0xac42, 0xa113, 0xb1ef, 0xb21f,
-+	0xb1ef, 0xb21f, 0xa113, 0x080c, 0x1511, 0x0066, 0x6000, 0xa0b2,
-+	0x0010, 0x1a0c, 0x1511, 0x0013, 0x006e, 0x0005, 0xa12e, 0xa8c5,
-+	0xa992, 0xa9bf, 0xaa43, 0xa12e, 0xab30, 0xaadb, 0xa785, 0xab94,
-+	0xaba9, 0xa12e, 0xa12e, 0xa12e, 0xa12e, 0xa12e, 0x080c, 0x1511,
-+	0xa1b2, 0x0080, 0x1a0c, 0x1511, 0x2100, 0xa1b2, 0x0040, 0x1a04,
-+	0xa543, 0x0002, 0xa17a, 0xa345, 0xa17a, 0xa17a, 0xa17a, 0xa34c,
-+	0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a,
-+	0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a,
-+	0xa17a, 0xa17c, 0xa1da, 0xa1e9, 0xa237, 0xa255, 0xa2d3, 0xa332,
-+	0xa17a, 0xa17a, 0xa34f, 0xa17a, 0xa17a, 0xa362, 0xa36d, 0xa17a,
-+	0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa3f8, 0xa17a, 0xa17a, 0xa407,
-+	0xa17a, 0xa17a, 0xa3c3, 0xa17a, 0xa17a, 0xa17a, 0xa41f, 0xa17a,
-+	0xa17a, 0xa17a, 0xa499, 0xa17a, 0xa17a, 0xa17a, 0xa17a, 0xa17a,
-+	0xa17a, 0xa50a, 0x080c, 0x1511, 0x080c, 0x52ca, 0x1150, 0x2001,
-+	0xb435, 0x2004, 0xd0cc, 0x1128, 0xa084, 0x0009, 0xa086, 0x0008,
-+	0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804,
-+	0xa340, 0x080c, 0x52ba, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
-+	0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x6dba,
-+	0x0076, 0x2039, 0x0000, 0x080c, 0x6cc7, 0x2c08, 0x080c, 0xae05,
-+	0x007e, 0x001e, 0x2e60, 0x080c, 0x516b, 0x001e, 0x002e, 0x003e,
-+	0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4f79, 0x00ce,
-+	0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278,
-+	0x080c, 0xad49, 0x1904, 0xa231, 0x080c, 0xace9, 0x1120, 0x6007,
-+	0x0008, 0x0804, 0xa340, 0x6007, 0x0009, 0x0804, 0xa340, 0x080c,
-+	0xaefe, 0x0128, 0x080c, 0xad49, 0x0d78, 0x0804, 0xa231, 0x6013,
-+	0x1900, 0x0c88, 0x080c, 0x2d83, 0x1904, 0xa540, 0x6106, 0x080c,
-+	0xaca3, 0x6007, 0x0006, 0x0804, 0xa340, 0x6007, 0x0007, 0x0804,
-+	0xa340, 0x080c, 0xb253, 0x1904, 0xa540, 0x080c, 0x2d83, 0x1904,
-+	0xa540, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082,
-+	0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x4eac, 0xa6b4, 0xff00,
-+	0x8637, 0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04,
-+	0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128,
-+	0xa686, 0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xada7, 0x11a0,
-+	0xa686, 0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214,
-+	0x2009, 0x0000, 0x080c, 0x2ca5, 0x002e, 0x080c, 0x500c, 0x6007,
-+	0x000a, 0x00de, 0x0804, 0xa340, 0x6007, 0x000b, 0x00de, 0x0804,
-+	0xa340, 0x080c, 0x2c60, 0x6007, 0x0001, 0x0804, 0xa340, 0x080c,
-+	0xb253, 0x1904, 0xa540, 0x080c, 0x2d83, 0x1904, 0xa540, 0x6618,
-+	0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d50, 0x0026,
-+	0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2ca5,
-+	0x002e, 0x6007, 0x000c, 0x0804, 0xa340, 0x080c, 0x52ca, 0x1140,
-+	0x2001, 0xb435, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x1110,
-+	0x0804, 0xa189, 0x080c, 0x52ba, 0x6618, 0xa6b0, 0x0001, 0x2634,
-+	0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8, 0x1138, 0x0026, 0x2001,
-+	0x0006, 0x080c, 0x4eeb, 0x002e, 0x0050, 0xa6b4, 0xff00, 0x8637,
-+	0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0xa231, 0x080c,
-+	0xadb4, 0x1120, 0x6007, 0x000e, 0x0804, 0xa340, 0x0046, 0x6418,
-+	0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046, 0x080c,
-+	0x2c60, 0x004e, 0x0016, 0xa006, 0x2009, 0xb453, 0x210c, 0xd1a4,
-+	0x0158, 0x2009, 0x0029, 0x080c, 0xb06b, 0x6018, 0x00d6, 0x2068,
-+	0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001,
-+	0x0804, 0xa340, 0x2001, 0x0001, 0x080c, 0x4eac, 0x0156, 0x0016,
-+	0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0xb405, 0x2011, 0xba90,
-+	0x080c, 0x907a, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0168,
-+	0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0xa231, 0xa682,
-+	0x0007, 0x0a04, 0xa27f, 0x0804, 0xa231, 0x6013, 0x1900, 0x6007,
-+	0x0009, 0x0804, 0xa340, 0x080c, 0x52ca, 0x1140, 0x2001, 0xb435,
-+	0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x1110, 0x0804, 0xa189,
-+	0x080c, 0x52ba, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
-+	0xa082, 0x0006, 0x06b8, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004,
-+	0x0120, 0xa686, 0x0006, 0x1904, 0xa231, 0x080c, 0xaddc, 0x1138,
-+	0x080c, 0xace9, 0x1120, 0x6007, 0x0010, 0x0804, 0xa340, 0x0046,
-+	0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046,
-+	0x080c, 0x2c60, 0x004e, 0x0016, 0xa006, 0x2009, 0xb453, 0x210c,
-+	0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xb06b, 0x6018, 0x00d6,
-+	0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007,
-+	0x0001, 0x00f0, 0x080c, 0xaefe, 0x0140, 0xa6b4, 0xff00, 0x8637,
-+	0xa686, 0x0006, 0x0950, 0x0804, 0xa231, 0x6013, 0x1900, 0x6007,
-+	0x0009, 0x0070, 0x080c, 0x2d83, 0x1904, 0xa540, 0x080c, 0xb253,
-+	0x1904, 0xa540, 0x080c, 0xa568, 0x1904, 0xa231, 0x6007, 0x0012,
-+	0x6003, 0x0001, 0x080c, 0x6c98, 0x0005, 0x6007, 0x0001, 0x6003,
-+	0x0001, 0x080c, 0x6c98, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c,
-+	0xb253, 0x1904, 0xa540, 0x080c, 0x2d83, 0x1904, 0xa540, 0x080c,
-+	0xa568, 0x1904, 0xa231, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c,
-+	0x6c98, 0x0005, 0x080c, 0x2d83, 0x1904, 0xa540, 0x6007, 0x0023,
-+	0x6003, 0x0001, 0x080c, 0x6c98, 0x0005, 0x080c, 0xb253, 0x1904,
-+	0xa540, 0x080c, 0x2d83, 0x1904, 0xa540, 0x080c, 0xa568, 0x1904,
-+	0xa231, 0x0016, 0x0026, 0x2011, 0xba91, 0x2214, 0xa286, 0xffff,
-+	0x0190, 0x2c08, 0x080c, 0x9bdb, 0x01e0, 0x2260, 0x2011, 0xba90,
-+	0x2214, 0x6008, 0xa206, 0x11a8, 0x6018, 0xa190, 0x0006, 0x2214,
-+	0xa206, 0x01e8, 0x0070, 0x2011, 0xba90, 0x2214, 0x2c08, 0xa006,
-+	0x080c, 0xb03d, 0x11a0, 0x2011, 0xba91, 0x2214, 0xa286, 0xffff,
-+	0x01c0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xba89,
-+	0x2214, 0xa296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x601c,
-+	0xa086, 0x0007, 0x1d70, 0x6004, 0xa086, 0x0024, 0x1110, 0x080c,
-+	0x85c0, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x6c98,
-+	0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x4eac, 0x0156,
-+	0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0xb405, 0x2011,
-+	0xba96, 0x080c, 0x907a, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120,
-+	0x6007, 0x0031, 0x0804, 0xa340, 0x080c, 0x8d99, 0x080c, 0x5a90,
-+	0x11b0, 0x0006, 0x0026, 0x0036, 0x080c, 0x5aac, 0x1158, 0x2001,
-+	0xb69f, 0x2003, 0x0001, 0x2001, 0xb400, 0x2003, 0x0001, 0x080c,
-+	0x59c8, 0x0010, 0x080c, 0x5a67, 0x003e, 0x002e, 0x000e, 0x0005,
-+	0x080c, 0x2d83, 0x1904, 0xa540, 0x6106, 0x080c, 0xa584, 0x6007,
-+	0x002b, 0x0804, 0xa340, 0x6007, 0x002c, 0x0804, 0xa340, 0x080c,
-+	0xb253, 0x1904, 0xa540, 0x080c, 0x2d83, 0x1904, 0xa540, 0x080c,
-+	0xa568, 0x1904, 0xa231, 0x6106, 0x080c, 0xa588, 0x1120, 0x6007,
-+	0x002e, 0x0804, 0xa340, 0x6007, 0x002f, 0x0804, 0xa340, 0x080c,
-+	0x2d83, 0x1904, 0xa540, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080,
-+	0x0001, 0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184,
-+	0xff00, 0x8007, 0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee,
-+	0x0804, 0xa345, 0x2001, 0xb472, 0x2004, 0xd0e4, 0x0904, 0xa496,
-+	0x2071, 0xba8c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c,
-+	0x2001, 0xb453, 0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810,
-+	0xa106, 0x1118, 0x6814, 0xa206, 0x01f8, 0x2001, 0xb453, 0x2004,
-+	0xd0ac, 0x1590, 0x2069, 0xb400, 0x6874, 0xa206, 0x1568, 0x6870,
-+	0xa106, 0x1550, 0x7210, 0x080c, 0x9bdb, 0x0558, 0x080c, 0xb0d7,
-+	0x0540, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x6c52,
-+	0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150,
-+	0x080c, 0x9bdb, 0x01b0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106,
-+	0x1180, 0x0c08, 0x7210, 0x2c08, 0xa085, 0x0001, 0x080c, 0xb03d,
-+	0x2c10, 0x2160, 0x0130, 0x08b8, 0x6007, 0x0037, 0x6013, 0x1500,
-+	0x08d8, 0x6007, 0x0037, 0x6013, 0x1700, 0x08b0, 0x6007, 0x0012,
-+	0x0898, 0x080c, 0x2d83, 0x1904, 0xa540, 0x6018, 0xa080, 0x0001,
-+	0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0xa345,
-+	0x00e6, 0x00d6, 0x00c6, 0x2001, 0xb472, 0x2004, 0xd0e4, 0x0904,
-+	0xa502, 0x2069, 0xb400, 0x2071, 0xba8c, 0x7008, 0x6036, 0x720c,
-+	0x623a, 0xa286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0xa085,
-+	0x0001, 0x080c, 0xb03d, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9bdb,
-+	0x0570, 0x00c6, 0x0026, 0x2260, 0x080c, 0x98b6, 0x002e, 0x00ce,
-+	0x7118, 0xa18c, 0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186,
-+	0x0005, 0x0118, 0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004,
-+	0xa005, 0x0150, 0x0056, 0x7510, 0x7614, 0x080c, 0xb0ee, 0x005e,
-+	0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009,
-+	0x6013, 0x2a00, 0x6003, 0x0001, 0x080c, 0x6c52, 0x0c88, 0x6007,
-+	0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c,
-+	0x6c52, 0x0c30, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000,
-+	0x0804, 0xa46c, 0x00e6, 0x0026, 0x080c, 0x52ca, 0x0558, 0x080c,
-+	0x52ba, 0x080c, 0xb2ce, 0x1520, 0x2071, 0xb400, 0x70d4, 0xc085,
-+	0x70d6, 0x00f6, 0x2079, 0x0100, 0x72a0, 0xa284, 0x00ff, 0x7072,
-+	0x78e6, 0xa284, 0xff00, 0x7274, 0xa205, 0x7076, 0x78ea, 0x00fe,
-+	0x70df, 0x0000, 0x2001, 0xb453, 0x2004, 0xd0a4, 0x0120, 0x2011,
-+	0xb6f9, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2a7e, 0x0010,
-+	0x080c, 0xb2fa, 0x002e, 0x00ee, 0x080c, 0x85c0, 0x0804, 0xa344,
-+	0x080c, 0x85c0, 0x0005, 0x2600, 0x0002, 0xa54e, 0xa54e, 0xa54e,
-+	0xa54e, 0xa54e, 0xa550, 0xa54e, 0xa54e, 0xa54e, 0x080c, 0x1511,
-+	0x080c, 0xb253, 0x1d68, 0x080c, 0x2d83, 0x1d50, 0x0089, 0x1138,
-+	0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x6c98, 0x0005, 0x080c,
-+	0x2c60, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x6c98, 0x0005,
-+	0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
-+	0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4,
-+	0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
-+	0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005,
-+	0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084,
-+	0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009,
-+	0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824,
-+	0x080c, 0x27e3, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2ca5,
-+	0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069,
-+	0xba8d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085,
-+	0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xba8c,
-+	0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084,
-+	0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004,
-+	0xa0b2, 0x0080, 0x1a0c, 0x1511, 0xa1b6, 0x0013, 0x1130, 0x2008,
-+	0xa1b2, 0x0040, 0x1a04, 0xa6cf, 0x0092, 0xa1b6, 0x0027, 0x0120,
-+	0xa1b6, 0x0014, 0x190c, 0x1511, 0x2001, 0x0007, 0x080c, 0x4eeb,
-+	0x080c, 0x7055, 0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0xa62f,
-+	0xa631, 0xa62f, 0xa62f, 0xa62f, 0xa631, 0xa643, 0xa6c8, 0xa693,
-+	0xa6c8, 0xa6a4, 0xa6c8, 0xa643, 0xa6c8, 0xa6c0, 0xa6c8, 0xa6c0,
-+	0xa6c8, 0xa6c8, 0xa62f, 0xa62f, 0xa62f, 0xa62f, 0xa62f, 0xa62f,
-+	0xa62f, 0xa62f, 0xa62f, 0xa62f, 0xa62f, 0xa631, 0xa62f, 0xa6c8,
-+	0xa62f, 0xa62f, 0xa6c8, 0xa62f, 0xa6c5, 0xa6c8, 0xa62f, 0xa62f,
-+	0xa62f, 0xa62f, 0xa6c8, 0xa6c8, 0xa62f, 0xa6c8, 0xa6c8, 0xa62f,
-+	0xa63d, 0xa62f, 0xa62f, 0xa62f, 0xa62f, 0xa6c4, 0xa6c8, 0xa62f,
-+	0xa62f, 0xa6c8, 0xa6c8, 0xa62f, 0xa62f, 0xa62f, 0xa62f, 0x080c,
-+	0x1511, 0x080c, 0x7055, 0x2001, 0xb6b6, 0x2004, 0x6016, 0x6003,
-+	0x0002, 0x080c, 0x7134, 0x0804, 0xa6ce, 0x2001, 0x0000, 0x080c,
-+	0x4eac, 0x0804, 0xa6c8, 0x00f6, 0x2079, 0xb452, 0x7804, 0x00fe,
-+	0xd0ac, 0x1904, 0xa6c8, 0x2001, 0x0000, 0x080c, 0x4eac, 0x6018,
-+	0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x1140, 0x00f6, 0x2079,
-+	0xb400, 0x7898, 0x8000, 0x789a, 0x00fe, 0x00e0, 0x00c6, 0x6018,
-+	0x2060, 0x6000, 0xd0f4, 0x1140, 0x6010, 0xa005, 0x0128, 0x00ce,
-+	0x080c, 0x3efc, 0x0804, 0xa6c8, 0x00ce, 0x2001, 0xb400, 0x2004,
-+	0xa086, 0x0002, 0x1138, 0x00f6, 0x2079, 0xb400, 0x7898, 0x8000,
-+	0x789a, 0x00fe, 0x2001, 0x0002, 0x080c, 0x4ebe, 0x080c, 0x7055,
-+	0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6c98,
-+	0x080c, 0x7134, 0x00c6, 0x6118, 0x2160, 0x2009, 0x0001, 0x080c,
-+	0x696d, 0x00ce, 0x04d8, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de,
-+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0550, 0xa686, 0x0004,
-+	0x0538, 0x2001, 0x0004, 0x0410, 0x2001, 0xb400, 0x2004, 0xa086,
-+	0x0003, 0x1110, 0x080c, 0x3efc, 0x2001, 0x0006, 0x04a1, 0x6618,
-+	0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686,
-+	0x0006, 0x0170, 0x2001, 0x0006, 0x0048, 0x2001, 0x0004, 0x0030,
-+	0x2001, 0x0006, 0x0401, 0x0020, 0x0018, 0x0010, 0x080c, 0x4eeb,
-+	0x080c, 0x7055, 0x080c, 0x85c0, 0x080c, 0x7134, 0x0005, 0x2600,
-+	0x0002, 0xa6da, 0xa6da, 0xa6da, 0xa6da, 0xa6da, 0xa6dc, 0xa6da,
-+	0xa6da, 0xa6da, 0x080c, 0x1511, 0x080c, 0x7055, 0x080c, 0x85c0,
-+	0x080c, 0x7134, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168, 0x6900,
-+	0xd184, 0x0140, 0x080c, 0x4ebe, 0x2001, 0x0000, 0x080c, 0x4eac,
-+	0x080c, 0x2c86, 0x00de, 0x001e, 0x0005, 0x00d6, 0x6618, 0x2668,
-+	0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, 0x000c, 0x1a0c,
-+	0x1511, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, 0xa1b6, 0x0016,
-+	0x190c, 0x1511, 0x006b, 0x0005, 0x8c82, 0x8c82, 0x8c82, 0x8c82,
-+	0x8c82, 0x8c82, 0xa765, 0xa724, 0x8c82, 0x8c82, 0x8c82, 0x8c82,
-+	0x8c82, 0x8c82, 0x8c82, 0x8c82, 0x8c82, 0x8c82, 0xa765, 0xa76c,
-+	0x8c82, 0x8c82, 0x8c82, 0x8c82, 0x00f6, 0x2079, 0xb452, 0x7804,
-+	0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800, 0xd0f4, 0x1118,
-+	0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c, 0x4eac, 0x2001,
-+	0x0002, 0x080c, 0x4ebe, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007,
-+	0x0002, 0x080c, 0x6c98, 0x080c, 0x7134, 0x00e8, 0x2011, 0xba83,
-+	0x2204, 0x8211, 0x220c, 0x080c, 0x27e3, 0x11a8, 0x00c6, 0x080c,
-+	0x4f6a, 0x0120, 0x00ce, 0x080c, 0x85c0, 0x0068, 0x6010, 0x0006,
-+	0x6014, 0x0006, 0x080c, 0x4bc5, 0x000e, 0x6016, 0x000e, 0x6012,
-+	0x00ce, 0x080c, 0x85c0, 0x00fe, 0x0005, 0x6604, 0xa6b6, 0x001e,
-+	0x1110, 0x080c, 0x85c0, 0x0005, 0x080c, 0x8f35, 0x1138, 0x6003,
-+	0x0001, 0x6007, 0x0001, 0x080c, 0x6c98, 0x0010, 0x080c, 0x85c0,
-+	0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x1511, 0x080c, 0x7055,
-+	0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0xa182, 0x0040, 0x0002,
-+	0xa79b, 0xa79b, 0xa79b, 0xa79b, 0xa79d, 0xa79b, 0xa79b, 0xa79b,
-+	0xa79b, 0xa79b, 0xa79b, 0xa79b, 0xa79b, 0xa79b, 0xa79b, 0xa79b,
-+	0xa79b, 0xa79b, 0xa79b, 0x080c, 0x1511, 0x00d6, 0x00e6, 0x00f6,
-+	0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005,
-+	0x0120, 0x2021, 0x0000, 0x080c, 0xb29f, 0x6106, 0x2071, 0xba80,
-+	0x7444, 0xa4a4, 0xff00, 0x0904, 0xa801, 0xa486, 0x2000, 0x1130,
-+	0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x6adf, 0x080c, 0x15f4,
-+	0x090c, 0x1511, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
-+	0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
-+	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x0016, 0xa084,
-+	0xff00, 0x6846, 0x684f, 0x0000, 0x6853, 0x0000, 0x6857, 0x0036,
-+	0x080c, 0x53c9, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017,
-+	0x080c, 0xafe8, 0x0804, 0xa85e, 0xa486, 0x0400, 0x1130, 0x2019,
-+	0x0002, 0x080c, 0xaf9a, 0x0804, 0xa85e, 0xa486, 0x0200, 0x1110,
-+	0x080c, 0xaf7f, 0xa486, 0x1000, 0x1110, 0x080c, 0xafcd, 0x0804,
-+	0xa85e, 0x2069, 0xb774, 0x6a00, 0xd284, 0x0904, 0xa8c1, 0xa284,
-+	0x0300, 0x1904, 0xa8ba, 0x6804, 0xa005, 0x0904, 0xa8a2, 0x2d78,
-+	0x6003, 0x0007, 0x080c, 0x15db, 0x0904, 0xa865, 0x7800, 0xd08c,
-+	0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000,
-+	0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a,
-+	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928,
-+	0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853,
-+	0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f,
-+	0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010,
-+	0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xba90, 0xad90, 0x0015,
-+	0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa850, 0x200c,
-+	0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x53c9, 0x002e, 0x004e,
-+	0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x2001, 0xb40e, 0x2004,
-+	0xd084, 0x0120, 0x080c, 0x15f4, 0x1904, 0xa816, 0x6013, 0x0100,
-+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x6c52, 0x080c, 0x7134,
-+	0x0c28, 0x2069, 0xba92, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200,
-+	0x11a8, 0x2069, 0xba80, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110,
-+	0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007,
-+	0x0043, 0x080c, 0x6c52, 0x080c, 0x7134, 0x0840, 0x6013, 0x0200,
-+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x6c52, 0x080c, 0x7134,
-+	0x0804, 0xa85e, 0x2001, 0xb40d, 0x2004, 0xd0ec, 0x0120, 0x2011,
-+	0x8049, 0x080c, 0x3e8a, 0x6013, 0x0300, 0x0010, 0x6013, 0x0100,
-+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x6c52, 0x080c, 0x7134,
-+	0x0804, 0xa85e, 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, 0x0804,
-+	0xa879, 0x6013, 0x0200, 0x0804, 0xa879, 0xa186, 0x0013, 0x1170,
-+	0x6004, 0xa08a, 0x0040, 0x0a0c, 0x1511, 0xa08a, 0x0053, 0x1a0c,
-+	0x1511, 0xa082, 0x0040, 0x2008, 0x0804, 0xa94f, 0xa186, 0x0051,
-+	0x0138, 0xa186, 0x0047, 0x11d8, 0x6004, 0xa086, 0x0041, 0x0518,
-+	0x2001, 0x0109, 0x2004, 0xd084, 0x01f0, 0x0126, 0x2091, 0x2800,
-+	0x0006, 0x0016, 0x0026, 0x080c, 0x6b39, 0x002e, 0x001e, 0x000e,
-+	0x012e, 0x6000, 0xa086, 0x0002, 0x1170, 0x0804, 0xa992, 0xa186,
-+	0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1511, 0x6004, 0xa082,
-+	0x0040, 0x2008, 0x001a, 0x080c, 0x8606, 0x0005, 0xa919, 0xa91b,
-+	0xa91b, 0xa93f, 0xa919, 0xa919, 0xa919, 0xa919, 0xa919, 0xa919,
-+	0xa919, 0xa919, 0xa919, 0xa919, 0xa919, 0xa919, 0xa919, 0xa919,
-+	0xa919, 0x080c, 0x1511, 0x080c, 0x7055, 0x080c, 0x7134, 0x0036,
-+	0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84, 0xf000, 0x01a8, 0x6003,
-+	0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
-+	0xb01c, 0x6013, 0x0000, 0x6014, 0xa005, 0x1120, 0x2001, 0xb6b7,
-+	0x2004, 0x6016, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0x00d6,
-+	0x080c, 0x7055, 0x080c, 0x7134, 0x080c, 0x9beb, 0x0120, 0x6010,
-+	0x2068, 0x080c, 0x160b, 0x080c, 0x9dae, 0x00de, 0x0005, 0x0002,
-+	0xa963, 0xa980, 0xa96c, 0xa98c, 0xa963, 0xa963, 0xa963, 0xa963,
-+	0xa963, 0xa963, 0xa963, 0xa963, 0xa963, 0xa963, 0xa963, 0xa963,
-+	0xa963, 0xa963, 0xa963, 0x080c, 0x1511, 0x6010, 0xa088, 0x0013,
-+	0x2104, 0xa085, 0x0400, 0x200a, 0x080c, 0x7055, 0x6010, 0xa080,
-+	0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
-+	0x080c, 0x85ef, 0x0010, 0x6003, 0x0002, 0x080c, 0x7134, 0x0005,
-+	0x080c, 0x7055, 0x080c, 0xb25a, 0x1120, 0x080c, 0x6ab4, 0x080c,
-+	0x85c0, 0x080c, 0x7134, 0x0005, 0x080c, 0x7055, 0x2009, 0x0041,
-+	0x0804, 0xaadb, 0xa182, 0x0040, 0x0002, 0xa9a8, 0xa9aa, 0xa9a8,
-+	0xa9a8, 0xa9a8, 0xa9a8, 0xa9a8, 0xa9ab, 0xa9a8, 0xa9a8, 0xa9a8,
-+	0xa9a8, 0xa9a8, 0xa9a8, 0xa9a8, 0xa9a8, 0xa9a8, 0xa9b6, 0xa9a8,
-+	0x080c, 0x1511, 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
-+	0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856, 0x0005, 0x00d6, 0x080c,
-+	0x6ab4, 0x00de, 0x080c, 0xb2bd, 0x080c, 0x85c0, 0x0005, 0xa182,
-+	0x0040, 0x0002, 0xa9d5, 0xa9d5, 0xa9d5, 0xa9d5, 0xa9d5, 0xa9d5,
-+	0xa9d5, 0xa9d7, 0xa9d5, 0xa9da, 0xaa13, 0xa9d5, 0xa9d5, 0xa9d5,
-+	0xa9d5, 0xaa13, 0xa9d5, 0xa9d5, 0xa9d5, 0x080c, 0x1511, 0x080c,
-+	0x8606, 0x0005, 0x2001, 0xb472, 0x2004, 0xd0e4, 0x0158, 0x2001,
-+	0x0100, 0x2004, 0xa082, 0x0005, 0x0228, 0x2001, 0x011f, 0x2004,
-+	0x6036, 0x0010, 0x6037, 0x0000, 0x080c, 0x70e7, 0x080c, 0x71f1,
-+	0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc, 0x0150, 0xa08c, 0x0003,
-+	0xa18e, 0x0002, 0x0168, 0x2009, 0x0041, 0x00de, 0x0804, 0xaadb,
-+	0x6003, 0x0007, 0x6017, 0x0000, 0x080c, 0x6ab4, 0x00de, 0x0005,
-+	0x080c, 0xb25a, 0x0110, 0x00de, 0x0005, 0x080c, 0x6ab4, 0x080c,
-+	0x85c0, 0x00de, 0x0ca0, 0x0036, 0x080c, 0x70e7, 0x080c, 0x71f1,
-+	0x6010, 0x00d6, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0188, 0x684c,
-+	0xa084, 0x0003, 0xa086, 0x0002, 0x0140, 0x687c, 0x632c, 0xa31a,
-+	0x632e, 0x6880, 0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0080,
-+	0x2019, 0x0004, 0x080c, 0xb01c, 0x6014, 0xa005, 0x1128, 0x2001,
-+	0xb6b7, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007,
-+	0x00de, 0x003e, 0x0005, 0xa186, 0x0013, 0x1150, 0x6004, 0xa086,
-+	0x0042, 0x190c, 0x1511, 0x080c, 0x7055, 0x080c, 0x7134, 0x0005,
-+	0xa186, 0x0027, 0x0118, 0xa186, 0x0014, 0x1180, 0x6004, 0xa086,
-+	0x0042, 0x190c, 0x1511, 0x2001, 0x0007, 0x080c, 0x4eeb, 0x080c,
-+	0x7055, 0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0xa182, 0x0040,
-+	0x0002, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c,
-+	0xaa7e, 0xaa8a, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c,
-+	0xaa7c, 0xaa7c, 0xaa7c, 0xaa7c, 0x080c, 0x1511, 0x0036, 0x0046,
-+	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1856, 0x004e,
-+	0x003e, 0x0005, 0x6010, 0x00d6, 0x2068, 0x6810, 0x6a14, 0x0006,
-+	0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c,
-+	0xa420, 0x642e, 0x6028, 0xa529, 0x652a, 0x005e, 0x004e, 0x000e,
-+	0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120, 0x2009, 0x0041, 0x00de,
-+	0x0490, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c, 0x6ab4, 0x00de,
-+	0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c, 0x52c6, 0x00fe, 0x000e,
-+	0x0120, 0x6003, 0x0002, 0x00de, 0x0005, 0x2009, 0xb40d, 0x210c,
-+	0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x0021,
-+	0x080c, 0x6ab6, 0x00de, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000,
-+	0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015,
-+	0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040, 0x0208, 0x0062, 0xa186,
-+	0x0013, 0x0120, 0xa186, 0x0014, 0x190c, 0x1511, 0x6020, 0xd0dc,
-+	0x090c, 0x1511, 0x0005, 0xaafe, 0xab05, 0xab11, 0xab1d, 0xaafe,
-+	0xaafe, 0xaafe, 0xab2c, 0xaafe, 0xab00, 0xab00, 0xaafe, 0xaafe,
-+	0xaafe, 0xaafe, 0xab00, 0xaafe, 0xab00, 0xaafe, 0x080c, 0x1511,
-+	0x6020, 0xd0dc, 0x090c, 0x1511, 0x0005, 0x6003, 0x0001, 0x6106,
-+	0x080c, 0x6c52, 0x0126, 0x2091, 0x8000, 0x080c, 0x7134, 0x012e,
-+	0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x6c52, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x7134, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106,
-+	0x2c10, 0x080c, 0x1f7a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6cb5,
-+	0x080c, 0x71f1, 0x012e, 0x0005, 0xa016, 0x080c, 0x1856, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0036, 0x00d6, 0xa182, 0x0040, 0x0023,
-+	0x00de, 0x003e, 0x012e, 0x0005, 0xab4c, 0xab4e, 0xab60, 0xab7b,
-+	0xab4c, 0xab4c, 0xab4c, 0xab90, 0xab4c, 0xab4c, 0xab4c, 0xab4c,
-+	0xab4c, 0xab4c, 0xab4c, 0xab4c, 0x080c, 0x1511, 0x6010, 0x2068,
-+	0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x01d0,
-+	0x6003, 0x0001, 0x6106, 0x080c, 0x6c52, 0x080c, 0x7134, 0x0498,
-+	0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168, 0xa09c, 0x0003, 0xa39e,
-+	0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x6c52, 0x080c,
-+	0x7134, 0x0408, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004,
-+	0x080c, 0xb01c, 0x00c0, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0d90,
-+	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68, 0x6003, 0x0003, 0x6106,
-+	0x2c10, 0x080c, 0x1f7a, 0x080c, 0x6cb5, 0x080c, 0x71f1, 0x0018,
-+	0xa016, 0x080c, 0x1856, 0x0005, 0x080c, 0x7055, 0x6110, 0x81ff,
-+	0x0158, 0x00d6, 0x2168, 0x080c, 0xb303, 0x0036, 0x2019, 0x0029,
-+	0x080c, 0xb01c, 0x003e, 0x00de, 0x080c, 0x9dae, 0x080c, 0x7134,
-+	0x0005, 0x080c, 0x70e7, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168,
-+	0x080c, 0xb303, 0x0036, 0x2019, 0x0029, 0x080c, 0xb01c, 0x003e,
-+	0x00de, 0x080c, 0x9dae, 0x080c, 0x71f1, 0x0005, 0xa182, 0x0085,
-+	0x0002, 0xabca, 0xabc8, 0xabc8, 0xabd6, 0xabc8, 0xabc8, 0xabc8,
-+	0x080c, 0x1511, 0x6003, 0x000b, 0x6106, 0x080c, 0x6c52, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x7134, 0x012e, 0x0005, 0x0026, 0x00e6,
-+	0x080c, 0xb253, 0x0118, 0x080c, 0x85c0, 0x00c8, 0x2071, 0xba80,
-+	0x7224, 0x6212, 0x7220, 0x080c, 0xaeca, 0x0118, 0x6007, 0x0086,
-+	0x0040, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x1110, 0x6007,
-+	0x0086, 0x6003, 0x0001, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00ee,
-+	0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
-+	0x0a0c, 0x1511, 0xa08a, 0x008c, 0x1a0c, 0x1511, 0xa082, 0x0085,
-+	0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, 0x0118, 0x080c,
-+	0x8606, 0x0050, 0x2001, 0x0007, 0x080c, 0x4eeb, 0x080c, 0x7055,
-+	0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0xac24, 0xac26, 0xac26,
-+	0xac24, 0xac24, 0xac24, 0xac24, 0x080c, 0x1511, 0x080c, 0x7055,
-+	0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0xa182, 0x0085, 0x0a0c,
-+	0x1511, 0xa182, 0x008c, 0x1a0c, 0x1511, 0xa182, 0x0085, 0x0002,
-+	0xac3f, 0xac3f, 0xac3f, 0xac41, 0xac3f, 0xac3f, 0xac3f, 0x080c,
-+	0x1511, 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130,
-+	0xa186, 0x0027, 0x0118, 0x080c, 0x8606, 0x0030, 0x080c, 0x7055,
-+	0x080c, 0x9dae, 0x080c, 0x7134, 0x0005, 0x0036, 0x080c, 0xb2bd,
-+	0x603f, 0x0000, 0x2019, 0x000b, 0x0031, 0x601f, 0x0006, 0x6003,
-+	0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x0086,
-+	0x2c40, 0x0096, 0x2049, 0x0000, 0x080c, 0x80da, 0x009e, 0x008e,
-+	0x1578, 0x0076, 0x2c38, 0x080c, 0x8179, 0x007e, 0x1548, 0x6000,
-+	0xa086, 0x0000, 0x0528, 0x601c, 0xa086, 0x0007, 0x0508, 0x00d6,
-+	0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xb2bd, 0x601f, 0x0007,
-+	0x2001, 0xb6b6, 0x2004, 0x6016, 0x080c, 0x1944, 0x6010, 0x2068,
-+	0x080c, 0x9beb, 0x0110, 0x080c, 0xb01c, 0x00de, 0x6013, 0x0000,
-+	0x080c, 0xb2bd, 0x601f, 0x0007, 0x2001, 0xb6b6, 0x2004, 0x6016,
-+	0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156, 0x2079,
-+	0xba80, 0x7938, 0x783c, 0x080c, 0x27e3, 0x15b0, 0x0016, 0x00c6,
-+	0x080c, 0x4f6a, 0x1578, 0x001e, 0x002e, 0x0026, 0x0016, 0x2019,
-+	0x0029, 0x080c, 0x823c, 0x080c, 0x6dba, 0x0076, 0x2039, 0x0000,
-+	0x080c, 0x6cc7, 0x007e, 0x001e, 0x0076, 0x2039, 0x0000, 0x080c,
-+	0xae05, 0x007e, 0x080c, 0x516b, 0x0026, 0x6204, 0xa294, 0xff00,
-+	0x8217, 0xa286, 0x0006, 0x0118, 0xa286, 0x0004, 0x1118, 0x62a0,
-+	0x080c, 0x2d19, 0x002e, 0x001e, 0x080c, 0x4bc5, 0x6612, 0x6516,
-+	0xa006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe,
-+	0x0005, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x2009, 0xb421, 0x2104,
-+	0xa086, 0x0074, 0x1904, 0xad3e, 0x2069, 0xba8e, 0x690c, 0xa182,
-+	0x0100, 0x06c0, 0x6908, 0xa184, 0x8000, 0x05e8, 0x2001, 0xb69e,
-+	0x2004, 0xa005, 0x1160, 0x6018, 0x2070, 0x7010, 0xa084, 0x00ff,
-+	0x0118, 0x7000, 0xd0f4, 0x0118, 0xa184, 0x0800, 0x0560, 0x6910,
-+	0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, 0xbaae, 0x6904, 0x81ff,
-+	0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178,
-+	0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, 0xa18a, 0x0001, 0x0298,
-+	0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, 0x0300, 0x0088, 0x6013,
-+	0x0500, 0x0070, 0x6013, 0x0700, 0x0058, 0x6013, 0x0900, 0x0040,
-+	0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00,
-+	0xa085, 0x0001, 0x0008, 0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce,
-+	0x0005, 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, 0x6218, 0x2268,
-+	0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, 0xa286, 0x0004,
-+	0x0178, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0148, 0xa286,
-+	0x0004, 0x0130, 0x00c6, 0x2d60, 0x080c, 0x4f79, 0x00ce, 0x04c0,
-+	0x2011, 0xba96, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x907a,
-+	0x1580, 0x2011, 0xba9a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c,
-+	0x907a, 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227,
-+	0xa006, 0x2009, 0xb453, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029,
-+	0x080c, 0xb06b, 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c,
-+	0x6dba, 0x0076, 0x2039, 0x0000, 0x080c, 0x6cc7, 0x2c08, 0x080c,
-+	0xae05, 0x007e, 0x2001, 0x0007, 0x080c, 0x4eeb, 0x001e, 0x004e,
-+	0xa006, 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6,
-+	0x2069, 0xba8e, 0x6800, 0xa086, 0x0800, 0x0118, 0x6013, 0x0000,
-+	0x0008, 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026,
-+	0x0036, 0x0156, 0x2079, 0xba8c, 0x7930, 0x7834, 0x080c, 0x27e3,
-+	0x11a0, 0x080c, 0x4f6a, 0x1188, 0x2011, 0xba90, 0xac98, 0x000a,
-+	0x20a9, 0x0004, 0x080c, 0x907a, 0x1140, 0x2011, 0xba94, 0xac98,
-+	0x0006, 0x20a9, 0x0004, 0x080c, 0x907a, 0x015e, 0x003e, 0x002e,
-+	0x001e, 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, 0x0016, 0x0026,
-+	0x0036, 0x0156, 0x2011, 0xba83, 0x2204, 0x8211, 0x220c, 0x080c,
-+	0x27e3, 0x11a0, 0x080c, 0x4f6a, 0x1188, 0x2011, 0xba96, 0xac98,
-+	0x000a, 0x20a9, 0x0004, 0x080c, 0x907a, 0x1140, 0x2011, 0xba9a,
-+	0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x907a, 0x015e, 0x003e,
-+	0x002e, 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086,
-+	0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000,
-+	0x2740, 0x2029, 0xb6e9, 0x252c, 0x2021, 0xb6ef, 0x2424, 0x2061,
-+	0xbc00, 0x2071, 0xb400, 0x7648, 0x7068, 0x81ff, 0x0150, 0x0006,
-+	0xa186, 0xb7f4, 0x000e, 0x0128, 0x8001, 0xa602, 0x1a04, 0xae86,
-+	0x0018, 0xa606, 0x0904, 0xae86, 0x2100, 0xac06, 0x0904, 0xae7d,
-+	0x080c, 0xb093, 0x0904, 0xae7d, 0x671c, 0xa786, 0x0001, 0x0904,
-+	0xaea1, 0xa786, 0x0004, 0x0904, 0xaea1, 0xa786, 0x0007, 0x05e8,
-+	0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xb0a3,
-+	0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000,
-+	0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1944, 0x001e, 0xa786,
-+	0x0008, 0x1148, 0x080c, 0x9de9, 0x1130, 0x080c, 0x8bbc, 0x00de,
-+	0x080c, 0x9dae, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9beb, 0x0190,
-+	0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-+	0x080c, 0xb303, 0x0016, 0x080c, 0x9e5d, 0x080c, 0x53c9, 0x001e,
-+	0x080c, 0x9da2, 0x00de, 0x080c, 0x9dae, 0xace0, 0x0018, 0x2001,
-+	0xb417, 0x2004, 0xac02, 0x1210, 0x0804, 0xae19, 0x012e, 0x002e,
-+	0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
-+	0xa786, 0x0006, 0x1150, 0xa386, 0x0005, 0x0128, 0x080c, 0xb303,
-+	0x080c, 0xb01c, 0x08f8, 0x00de, 0x0c00, 0xa786, 0x000a, 0x0968,
-+	0x0850, 0x080c, 0xb0a3, 0x19c8, 0x81ff, 0x09b8, 0xa180, 0x0001,
-+	0x2004, 0xa086, 0x0018, 0x0130, 0xa180, 0x0001, 0x2004, 0xa086,
-+	0x002d, 0x1958, 0x6000, 0xa086, 0x0002, 0x1938, 0x080c, 0x9dd8,
-+	0x0130, 0x080c, 0x9de9, 0x1908, 0x080c, 0x8bbc, 0x0038, 0x080c,
-+	0x2c86, 0x080c, 0x9de9, 0x1110, 0x080c, 0x8bbc, 0x080c, 0x9dae,
-+	0x0804, 0xae7d, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0xa006,
-+	0x080c, 0xb03d, 0x001e, 0x0120, 0x601c, 0xa084, 0x000f, 0x001b,
-+	0x00ee, 0x00ce, 0x0005, 0xaee3, 0xaee3, 0xaee3, 0xaee3, 0xaee3,
-+	0xaee3, 0xaee5, 0xaee3, 0xa006, 0x0005, 0x0046, 0x0016, 0x7018,
-+	0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009,
-+	0x0020, 0x080c, 0xb06b, 0x001e, 0x004e, 0x0036, 0x2019, 0x0002,
-+	0x080c, 0xac63, 0x003e, 0xa085, 0x0001, 0x0005, 0x2001, 0x0001,
-+	0x080c, 0x4eac, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004,
-+	0x2019, 0xb405, 0x2011, 0xba96, 0x080c, 0x907a, 0x003e, 0x002e,
-+	0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086,
-+	0x0076, 0x0066, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061,
-+	0xbc00, 0x2079, 0x0001, 0x8fff, 0x0904, 0xaf72, 0x2071, 0xb400,
-+	0x7648, 0x7068, 0x8001, 0xa602, 0x1a04, 0xaf72, 0x88ff, 0x0128,
-+	0x2800, 0xac06, 0x15b0, 0x2079, 0x0000, 0x080c, 0xb093, 0x0588,
-+	0x2400, 0xac06, 0x0570, 0x671c, 0xa786, 0x0006, 0x1550, 0xa786,
-+	0x0007, 0x0538, 0x88ff, 0x1140, 0x6018, 0xa206, 0x1510, 0x85ff,
-+	0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6, 0x6000, 0xa086, 0x0004,
-+	0x1150, 0x080c, 0xb2bd, 0x601f, 0x0007, 0x2001, 0xb6b6, 0x2004,
-+	0x6016, 0x080c, 0x1944, 0x6010, 0x2068, 0x080c, 0x9beb, 0x0120,
-+	0x0046, 0x080c, 0xb01c, 0x004e, 0x00de, 0x080c, 0x9dae, 0x88ff,
-+	0x1198, 0xace0, 0x0018, 0x2001, 0xb417, 0x2004, 0xac02, 0x1210,
-+	0x0804, 0xaf23, 0xa006, 0x012e, 0x002e, 0x006e, 0x007e, 0x008e,
-+	0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, 0x0001, 0x0ca0, 0x0076,
-+	0x0056, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20, 0x2019,
-+	0x0002, 0x6218, 0x0096, 0x2049, 0x0000, 0x080c, 0x80da, 0x009e,
-+	0x008e, 0x2039, 0x0000, 0x080c, 0x8179, 0x080c, 0xaf14, 0x005e,
-+	0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
-+	0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036,
-+	0x080c, 0x4f6a, 0x11b0, 0x2c10, 0x0056, 0x0086, 0x2041, 0x0000,
-+	0x2508, 0x2029, 0x0001, 0x0096, 0x2049, 0x0000, 0x080c, 0x80da,
-+	0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x8179, 0x080c, 0xaf14,
-+	0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xafa6, 0x015e, 0x00ce,
-+	0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0076, 0x0056, 0x6218,
-+	0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096,
-+	0x2049, 0x0000, 0x080c, 0x80da, 0x009e, 0x008e, 0x2039, 0x0000,
-+	0x080c, 0x8179, 0x2c20, 0x080c, 0xaf14, 0x005e, 0x007e, 0x0005,
-+	0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
-+	0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x4f6a, 0x11c0,
-+	0x2c10, 0x0086, 0x2041, 0x0000, 0x2828, 0x0046, 0x2021, 0x0001,
-+	0x080c, 0xb29f, 0x004e, 0x0096, 0x2049, 0x0000, 0x080c, 0x80da,
-+	0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x8179, 0x080c, 0xaf14,
-+	0x003e, 0x001e, 0x8108, 0x1f04, 0xaff3, 0x015e, 0x00ce, 0x007e,
-+	0x005e, 0x004e, 0x002e, 0x0005, 0x0016, 0x00f6, 0x3800, 0xd08c,
-+	0x0130, 0xad82, 0x1000, 0x02b0, 0xad82, 0xb400, 0x0230, 0xad82,
-+	0xec00, 0x0280, 0xad82, 0xffff, 0x1268, 0x6800, 0xa07d, 0x0138,
-+	0x6803, 0x0000, 0x6b52, 0x080c, 0x53c9, 0x2f68, 0x0cb0, 0x6b52,
-+	0x080c, 0x53c9, 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046, 0x0036,
-+	0x2061, 0xbc00, 0xa005, 0x1138, 0x2071, 0xb400, 0x7448, 0x7068,
-+	0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000, 0xa086,
-+	0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0, 0x0006,
-+	0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xb417, 0x2004,
-+	0xac02, 0x1220, 0x0c40, 0xa085, 0x0001, 0x0008, 0xa006, 0x003e,
-+	0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15f4, 0x000e,
-+	0x090c, 0x1511, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010, 0x080c,
-+	0x9bdb, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014, 0x2004,
-+	0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0x2001, 0xb6be,
-+	0x2004, 0x6852, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x080c,
-+	0x53c9, 0x00de, 0x0005, 0x6700, 0xa786, 0x0000, 0x0158, 0xa786,
-+	0x0001, 0x0140, 0xa786, 0x000a, 0x0128, 0xa786, 0x0009, 0x0110,
-+	0xa085, 0x0001, 0x0005, 0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206,
-+	0x00ee, 0x0005, 0x0016, 0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007,
-+	0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003,
-+	0x000b, 0x601f, 0x0005, 0x2001, 0xb6b7, 0x2004, 0x6016, 0x080c,
-+	0x6c52, 0x080c, 0x7134, 0x001e, 0x0005, 0xe000, 0xe000, 0x0005,
-+	0x6020, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0x9ec6, 0x0030,
-+	0x080c, 0xb2bd, 0x080c, 0x6ab4, 0x080c, 0x85c0, 0x0005, 0xa280,
-+	0x0007, 0x2004, 0xa084, 0x000f, 0x0002, 0xb0e6, 0xb0e6, 0xb0e6,
-+	0xb0eb, 0xb0e6, 0xb0e8, 0xb0e8, 0xb0e6, 0xb0e8, 0xa006, 0x0005,
-+	0x00c6, 0x2260, 0x00ce, 0xa085, 0x0001, 0x0005, 0xa280, 0x0007,
-+	0x2004, 0xa084, 0x000f, 0x0002, 0xb0fd, 0xb0fd, 0xb0fd, 0xb0fd,
-+	0xb0fd, 0xb0fd, 0xb108, 0xb0fd, 0xb0fd, 0x6007, 0x003b, 0x602b,
-+	0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x080c, 0x6c52, 0x0005,
-+	0x00c6, 0x2260, 0x080c, 0xb2bd, 0x603f, 0x0000, 0x6020, 0xc0f4,
-+	0xc0cc, 0x6022, 0x6037, 0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186,
-+	0x0007, 0x1904, 0xb163, 0x6810, 0xa005, 0x0138, 0xa080, 0x0013,
-+	0x2004, 0xd0fc, 0x1110, 0x00de, 0x08c0, 0x6007, 0x003a, 0x6003,
-+	0x0001, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00c6, 0x2d60, 0x6100,
-+	0xa186, 0x0002, 0x1904, 0xb1ec, 0x6010, 0xa005, 0x1138, 0x6000,
-+	0xa086, 0x0007, 0x190c, 0x1511, 0x0804, 0xb1ec, 0xa08c, 0xf000,
-+	0x1130, 0x0028, 0x2068, 0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080,
-+	0x0013, 0x2004, 0xa084, 0x0003, 0xa086, 0x0002, 0x1180, 0x6010,
-+	0x2068, 0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc,
-+	0x6852, 0x2009, 0x0043, 0x080c, 0xaadb, 0x0804, 0xb1ec, 0x2009,
-+	0x0041, 0x0804, 0xb1e6, 0xa186, 0x0005, 0x15f0, 0x6810, 0xa080,
-+	0x0013, 0x2004, 0xd0bc, 0x1118, 0x00de, 0x0804, 0xb0fd, 0xd0b4,
-+	0x0128, 0xd0fc, 0x090c, 0x1511, 0x0804, 0xb11b, 0x6007, 0x003a,
-+	0x6003, 0x0001, 0x080c, 0x6c52, 0x080c, 0x7134, 0x00c6, 0x2d60,
-+	0x6100, 0xa186, 0x0002, 0x0120, 0xa186, 0x0004, 0x1904, 0xb1ec,
-+	0x2071, 0xb723, 0x7000, 0xa086, 0x0003, 0x1128, 0x7004, 0xac06,
-+	0x1110, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4,
-+	0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102,
-+	0x2009, 0x0042, 0x0804, 0xb1e6, 0x0036, 0x00d6, 0x00d6, 0x080c,
-+	0x15f4, 0x003e, 0x090c, 0x1511, 0x6837, 0x010d, 0x6803, 0x0000,
-+	0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00,
-+	0x6862, 0x6034, 0x6872, 0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018,
-+	0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a,
-+	0x6846, 0x684f, 0x0000, 0x6853, 0x0000, 0x6d6a, 0x6e66, 0x686f,
-+	0x0001, 0x080c, 0x53c9, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c,
-+	0xac63, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, 0x6017,
-+	0x0000, 0x603f, 0x0000, 0x00de, 0x003e, 0x0038, 0x603f, 0x0000,
-+	0x6003, 0x0007, 0x080c, 0xaadb, 0x00ce, 0x00de, 0x0005, 0xa186,
-+	0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2, 0xa186,
-+	0x0027, 0x1178, 0x080c, 0x7055, 0x0036, 0x00d6, 0x6010, 0x2068,
-+	0x2019, 0x0004, 0x080c, 0xb01c, 0x00de, 0x003e, 0x080c, 0x7134,
-+	0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, 0x8606, 0x0005, 0xb218,
-+	0xb216, 0xb216, 0xb216, 0xb216, 0xb216, 0xb218, 0x080c, 0x1511,
-+	0x080c, 0x7055, 0x6003, 0x000c, 0x080c, 0x7134, 0x0005, 0xa182,
-+	0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x8606,
-+	0x0005, 0xb230, 0xb230, 0xb230, 0xb230, 0xb232, 0xb250, 0xb230,
-+	0x080c, 0x1511, 0x00d6, 0x2c68, 0x080c, 0x856a, 0x01a0, 0x6003,
-+	0x0001, 0x6007, 0x001e, 0x2009, 0xba8e, 0x210c, 0x6136, 0x2009,
-+	0xba8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a, 0x601f,
-+	0x0004, 0x080c, 0x6c52, 0x2d60, 0x080c, 0x85c0, 0x00de, 0x0005,
-+	0x080c, 0x85c0, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec,
-+	0x00ee, 0x0005, 0x6010, 0xa08c, 0xf000, 0x0904, 0xb29e, 0xa080,
-+	0x0013, 0x200c, 0xd1ec, 0x05d0, 0x2001, 0xb472, 0x2004, 0xd0ec,
-+	0x05a8, 0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180,
-+	0x00f6, 0x2c78, 0x080c, 0x52c2, 0x00fe, 0x0150, 0x2001, 0xb6b8,
-+	0x2004, 0x603e, 0x2009, 0xb472, 0x210c, 0xd1f4, 0x11e8, 0x0080,
-+	0x2009, 0xb472, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022,
-+	0xa006, 0x00a0, 0x2001, 0xb6b8, 0x200c, 0x8103, 0xa100, 0x603e,
-+	0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003,
-+	0x0cd0, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016,
-+	0x00c6, 0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff,
-+	0x0180, 0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072,
-+	0x080c, 0x6ab4, 0x080c, 0x85c0, 0x0010, 0xacf0, 0x0003, 0x2e64,
-+	0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8,
-+	0x002b, 0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8,
-+	0x0003, 0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036,
-+	0x0156, 0x2011, 0xb428, 0x2204, 0xa084, 0x00ff, 0x2019, 0xba8e,
-+	0x2334, 0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00,
-+	0xa636, 0x11a0, 0x2011, 0xba90, 0x6018, 0xa098, 0x000a, 0x20a9,
-+	0x0004, 0x080c, 0x907a, 0x1150, 0x2011, 0xba94, 0x6018, 0xa098,
-+	0x0006, 0x20a9, 0x0004, 0x080c, 0x907a, 0x1100, 0x015e, 0x003e,
-+	0x002e, 0x0005, 0x00e6, 0x2071, 0xb400, 0x080c, 0x4b80, 0x080c,
-+	0x2a7e, 0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc,
-+	0x0108, 0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005,
-+	0x00e6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016,
-+	0x0126, 0x2091, 0x8000, 0x2029, 0xb6e9, 0x252c, 0x2021, 0xb6ef,
-+	0x2424, 0x2061, 0xbc00, 0x2071, 0xb400, 0x7648, 0x7068, 0xa606,
-+	0x0578, 0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500,
-+	0x2500, 0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xb093,
-+	0x01b8, 0x080c, 0xb0a3, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120,
-+	0x0016, 0x080c, 0x1944, 0x001e, 0x080c, 0x9dd8, 0x1110, 0x080c,
-+	0x2c86, 0x080c, 0x9de9, 0x1110, 0x080c, 0x8bbc, 0x080c, 0x9dae,
-+	0xace0, 0x0018, 0x2001, 0xb417, 0x2004, 0xac02, 0x1208, 0x0858,
-+	0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce,
-+	0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
-+	0x2071, 0xb440, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
-+	0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500, 0xa084,
-+	0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130, 0xa08e,
-+	0x0005, 0x0118, 0x2071, 0xb44a, 0x04c9, 0x001e, 0x00ee, 0x000e,
-+	0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
-+	0x2071, 0xb440, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
-+	0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500, 0xa084,
-+	0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130, 0xa08e,
-+	0x0005, 0x0118, 0x2071, 0xb44a, 0x0089, 0x001e, 0x00ee, 0x000e,
-+	0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
-+	0xb442, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, 0x8000,
-+	0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, 0x00e6,
-+	0x2071, 0xb440, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xb444,
-+	0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
-+	0x2071, 0xb440, 0x7044, 0x8000, 0x7046, 0x00ee, 0x000e, 0x012e,
-+	0x0005, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040,
-+	0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000,
-+	0x8000, 0x622c
-+};
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/asm_2300.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,6195 @@
-+/* @(#)asm_2300.h 1.6 */
-+/*
-+ * Copyright (C) 2001 Qlogic, Inc.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms are permitted provided
-+ * that the following conditions are met:
-+ * 1. Redistribution of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistribution in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */ 
-+
-+/************************************************************************
-+ *									*
-+ *               --- ISP2300 Initiator/Target Firmware ---              *
-+ *             with Fabric (Public Loop), Point-point, and              *
-+ *             expanded LUN addressing for FCTAPE                       *
-+ *									*
-+ ************************************************************************/
-+/*
-+ *	Firmware Version 3.01.20 (15:30 Dec 19, 2002)
-+ */
-+static const u_int16_t isp_2300_risc_code[] = {
-+	0x0470, 0x0000, 0x0000, 0xc060, 0x0000, 0x0003, 0x0001, 0x0014,
-+	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
-+	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
-+	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
-+	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-+	0x332e, 0x3031, 0x2e32, 0x3020, 0x2020, 0x2020, 0x2400, 0x20a9,
-+	0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
-+	0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
-+	0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
-+	0x400f, 0x2091, 0x2800, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f,
-+	0x2091, 0x2a00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091,
-+	0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
-+	0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
-+	0x0000, 0x20c1, 0x0004, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9,
-+	0x14ff, 0x2059, 0x0000, 0x2b78, 0x7883, 0x0004, 0x2089, 0x240d,
-+	0x2051, 0x1100, 0x2a70, 0x20e1, 0x0001, 0x20e9, 0x0001, 0x2029,
-+	0x45c0, 0x2031, 0xffff, 0x2039, 0x45a9, 0x2021, 0x0200, 0x20e9,
-+	0x0001, 0x20a1, 0x1000, 0x900e, 0x20a9, 0x05c0, 0x4104, 0x7566,
-+	0x766a, 0x7762, 0x746e, 0x7472, 0x00e6, 0x2071, 0x13a1, 0x2472,
-+	0x00ee, 0x20a1, 0x15c0, 0x7168, 0x810d, 0x810d, 0x810d, 0x810d,
-+	0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104,
-+	0x8211, 0x1de0, 0x7168, 0x3400, 0x8001, 0x9102, 0x0120, 0x0218,
-+	0x20a8, 0x900e, 0x4104, 0x2009, 0x1100, 0x810d, 0x810d, 0x810d,
-+	0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9,
-+	0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211,
-+	0x1dd8, 0x2009, 0x1100, 0x3400, 0x9102, 0x0120, 0x0218, 0x20a8,
-+	0x900e, 0x4104, 0x080c, 0x0f11, 0x080c, 0x10cf, 0x080c, 0x15fe,
-+	0x080c, 0x0d19, 0x080c, 0x50f4, 0x080c, 0x8e7a, 0x080c, 0x0e85,
-+	0x080c, 0x2a8c, 0x080c, 0x65b0, 0x080c, 0x58d0, 0x080c, 0x7133,
-+	0x080c, 0x1c09, 0x080c, 0x7420, 0x080c, 0x6bb9, 0x080c, 0x19df,
-+	0x080c, 0x1b7a, 0x080c, 0x1bfe, 0x2091, 0x3009, 0x7883, 0x0000,
-+	0x1004, 0x0910, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000,
-+	0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, 0x0904, 0x2091, 0x5000,
-+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd,
-+	0x2a70, 0x7003, 0x0000, 0x2a70, 0x7000, 0x908e, 0x0003, 0x1168,
-+	0x080c, 0x3fa0, 0x080c, 0x2aa2, 0x080c, 0x6610, 0x080c, 0x5dab,
-+	0x080c, 0x715a, 0x080c, 0x23a5, 0x0c70, 0x000b, 0x0c88, 0x0931,
-+	0x0932, 0x0a98, 0x092f, 0x0b68, 0x0d18, 0x0d18, 0x0d18, 0x080c,
-+	0x0d7e, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086,
-+	0x0001, 0x1904, 0x0a76, 0x7034, 0xd0b4, 0x1130, 0x0026, 0x2011,
-+	0x0080, 0x080c, 0x0e3a, 0x002e, 0x080c, 0x62e4, 0x0150, 0x080c,
-+	0x630a, 0x1580, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
-+	0x0448, 0x080c, 0x621a, 0x7000, 0x9086, 0x0001, 0x1904, 0x0a76,
-+	0x7090, 0x9086, 0x0028, 0x1904, 0x0a76, 0x2001, 0x0161, 0x2003,
-+	0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x1e2f,
-+	0x7a2a, 0x2011, 0x61aa, 0x080c, 0x71fa, 0x2011, 0x619d, 0x080c,
-+	0x72bf, 0x2011, 0x4f57, 0x080c, 0x71fa, 0x2011, 0x8030, 0x901e,
-+	0x738e, 0x00d8, 0x080c, 0x483b, 0x2079, 0x0100, 0x7844, 0x9005,
-+	0x1904, 0x0a76, 0x2011, 0x4f57, 0x080c, 0x71fa, 0x2001, 0x0265,
-+	0x2001, 0x0205, 0x2003, 0x0000, 0x780f, 0x006b, 0x7840, 0x9084,
-+	0xfffb, 0x7842, 0x2011, 0x8010, 0x73d4, 0x080c, 0x2261, 0x080c,
-+	0x3f23, 0x7240, 0xc284, 0x7242, 0x2001, 0x110c, 0x200c, 0xc1ac,
-+	0xc1cc, 0x2102, 0x080c, 0x877f, 0x2011, 0x0004, 0x080c, 0xa948,
-+	0x080c, 0x57d9, 0x080c, 0x62e4, 0x1120, 0x080c, 0x22a5, 0x02f0,
-+	0x0410, 0x080c, 0x50b1, 0x0140, 0x708f, 0x0001, 0x70cf, 0x0000,
-+	0x080c, 0x49f2, 0x0804, 0x0a76, 0x2001, 0x1153, 0x2004, 0xd094,
-+	0x0190, 0x2011, 0x110c, 0x2204, 0xc0cd, 0x2012, 0x2001, 0x1172,
-+	0x2004, 0xd0d4, 0x1118, 0x080c, 0x22a5, 0x1278, 0x2011, 0x110c,
-+	0x2204, 0xc0bc, 0x00b0, 0x2001, 0x1172, 0x2004, 0xd0d4, 0x1db0,
-+	0x2011, 0x110c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x110c, 0x2204,
-+	0xc0bd, 0x2012, 0x080c, 0x58c6, 0x1128, 0xd0a4, 0x0118, 0x2204,
-+	0xc0fd, 0x2012, 0x080c, 0x588e, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
-+	0x00a8, 0x7077, 0x0000, 0x080c, 0x62e4, 0x1130, 0x70a8, 0x9005,
-+	0x1168, 0x080c, 0xad47, 0x0050, 0x080c, 0xad47, 0x70d8, 0xd09c,
-+	0x1128, 0x70a8, 0x9005, 0x0110, 0x080c, 0x5092, 0x70e3, 0x0000,
-+	0x70df, 0x0000, 0x709f, 0x0000, 0x72d8, 0x080c, 0x62e4, 0x1170,
-+	0x9016, 0x0016, 0x080c, 0x205d, 0x2019, 0x1298, 0x211a, 0x001e,
-+	0x7057, 0xffff, 0x705b, 0x00ef, 0x707b, 0x0000, 0x2079, 0x1152,
-+	0x7804, 0xd0ac, 0x0108, 0xc295, 0x72da, 0x080c, 0x62e4, 0x0118,
-+	0x9296, 0x0004, 0x0548, 0x2011, 0x0001, 0x080c, 0xa948, 0x70a3,
-+	0x0000, 0x70a7, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827,
-+	0x0003, 0x7828, 0x9085, 0x0003, 0x782a, 0x00fe, 0x080c, 0x2679,
-+	0x2011, 0x0005, 0x080c, 0x88e2, 0x080c, 0x7aa4, 0x080c, 0x62e4,
-+	0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x205d, 0x61e2,
-+	0x001e, 0x00ce, 0x012e, 0x0420, 0x70a3, 0x0000, 0x70a7, 0xffff,
-+	0x7003, 0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828,
-+	0x9085, 0x0003, 0x782a, 0x00fe, 0x2011, 0x0005, 0x080c, 0x88e2,
-+	0x080c, 0x7aa4, 0x080c, 0x62e4, 0x0148, 0x00c6, 0x2061, 0x0100,
-+	0x0016, 0x080c, 0x205d, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e,
-+	0x0005, 0x00c6, 0x080c, 0x62e4, 0x1118, 0x20a9, 0x0100, 0x0010,
-+	0x20a9, 0x0082, 0x080c, 0x62e4, 0x1110, 0x900e, 0x0010, 0x2009,
-+	0x007e, 0x080c, 0x2955, 0x8108, 0x1f04, 0x0a89, 0x00ce, 0x7077,
-+	0x0000, 0x7078, 0x9084, 0x00ff, 0x707a, 0x70ab, 0x0000, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, 0x0b66,
-+	0x70a4, 0x9086, 0xffff, 0x0130, 0x080c, 0x2679, 0x080c, 0x7aa4,
-+	0x0804, 0x0b66, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0518, 0xd084,
-+	0x0508, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c,
-+	0x01c8, 0x70dc, 0x9086, 0xffff, 0x0188, 0x080c, 0x27da, 0x080c,
-+	0x7aa4, 0x70d8, 0xd094, 0x1904, 0x0b66, 0x2011, 0x0001, 0x901e,
-+	0x080c, 0x2811, 0x080c, 0x7aa4, 0x0804, 0x0b66, 0x70e0, 0x9005,
-+	0x1904, 0x0b66, 0x70a0, 0x9005, 0x1904, 0x0b66, 0x70d8, 0xd0a4,
-+	0x0118, 0xd0b4, 0x0904, 0x0b66, 0x080c, 0x588e, 0x1904, 0x0b66,
-+	0x080c, 0x58c6, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
-+	0x0016, 0x080c, 0x5608, 0x1118, 0x6000, 0xd0ec, 0x1138, 0x001e,
-+	0x8108, 0x1f04, 0x0ae8, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce,
-+	0x015e, 0x0804, 0x0b66, 0x0006, 0x2001, 0x0103, 0x2003, 0x006b,
-+	0x000e, 0x20e9, 0x0001, 0x71b0, 0x81ff, 0x11b0, 0x9006, 0x2009,
-+	0x0200, 0x20a9, 0x0002, 0x20a1, 0x1302, 0x4001, 0x2009, 0x0700,
-+	0x20a9, 0x0002, 0x20a1, 0x12f2, 0x4001, 0x7074, 0x8007, 0x7178,
-+	0x810f, 0x20a9, 0x0002, 0x4001, 0x20a1, 0x12f6, 0x900e, 0x080c,
-+	0x0d65, 0x9006, 0x810f, 0x20a9, 0x0002, 0x4001, 0x7030, 0xc08c,
-+	0x7032, 0x7003, 0x0003, 0x70a7, 0xffff, 0x7034, 0xd0b4, 0x1130,
-+	0x0026, 0x2011, 0x0040, 0x080c, 0x0e3a, 0x002e, 0x9006, 0x080c,
-+	0x1f11, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c,
-+	0x4026, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x630a,
-+	0x0150, 0x080c, 0x62e4, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010,
-+	0x9084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0x1305, 0x2004, 0x9086,
-+	0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x88e2, 0x2011, 0x0000,
-+	0x080c, 0x88ec, 0x080c, 0x7aa4, 0x080c, 0x7b72, 0x012e, 0x0005,
-+	0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
-+	0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x507b,
-+	0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827,
-+	0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156,
-+	0x7954, 0xd1ac, 0x1904, 0x0bf6, 0x080c, 0x2328, 0x1148, 0x2001,
-+	0x0001, 0x080c, 0x2290, 0x2001, 0x0001, 0x080c, 0x2273, 0x00b8,
-+	0x080c, 0x2330, 0x1138, 0x9006, 0x080c, 0x2290, 0x9006, 0x080c,
-+	0x2273, 0x0068, 0x080c, 0x2338, 0x1d50, 0x2001, 0x12d2, 0x2004,
-+	0xd0fc, 0x0108, 0x0020, 0x080c, 0x2089, 0x0804, 0x0cda, 0x080c,
-+	0x62f6, 0x0158, 0x080c, 0x630a, 0x1128, 0x2001, 0x12a7, 0x2003,
-+	0x0000, 0x0070, 0x080c, 0x62ec, 0x0dc0, 0x2001, 0x12a7, 0x2003,
-+	0xaaaa, 0x2001, 0x12a8, 0x2003, 0x0001, 0x080c, 0x621a, 0x0058,
-+	0x080c, 0x62e4, 0x0140, 0x2009, 0x00f8, 0x080c, 0x507b, 0x7843,
-+	0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138,
-+	0x080c, 0x62e4, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0cdf, 0x1f04,
-+	0x0bd5, 0x0070, 0x7824, 0x080c, 0x6300, 0x0118, 0xd0ac, 0x1904,
-+	0x0cdf, 0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0cdf,
-+	0x2001, 0x0001, 0x080c, 0x1f11, 0x0804, 0x0cf2, 0x080c, 0x2328,
-+	0x1148, 0x2001, 0x0001, 0x080c, 0x2290, 0x2001, 0x0001, 0x080c,
-+	0x2273, 0x00b8, 0x080c, 0x2330, 0x1138, 0x9006, 0x080c, 0x2290,
-+	0x9006, 0x080c, 0x2273, 0x0068, 0x080c, 0x2338, 0x1d50, 0x2001,
-+	0x12d2, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x2089, 0x0804,
-+	0x0cda, 0x080c, 0x2346, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938,
-+	0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2340, 0x9085, 0x2000,
-+	0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c2c, 0x080c, 0x72a5,
-+	0x1f04, 0x0c2c, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852,
-+	0x793a, 0x080c, 0x62f6, 0x0158, 0x080c, 0x630a, 0x1128, 0x2001,
-+	0x12a7, 0x2003, 0x0000, 0x0070, 0x080c, 0x62ec, 0x0dc0, 0x2001,
-+	0x12a7, 0x2003, 0xaaaa, 0x2001, 0x12a8, 0x2003, 0x0001, 0x080c,
-+	0x621a, 0x0020, 0x2009, 0x00f8, 0x080c, 0x507b, 0x20a9, 0x0028,
-+	0xa001, 0x1f04, 0x0c58, 0x7850, 0x9085, 0x1400, 0x7852, 0x080c,
-+	0x62e4, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
-+	0x2019, 0xea60, 0x7820, 0xd09c, 0x15a0, 0x080c, 0x62e4, 0x0904,
-+	0x0cbf, 0x7824, 0xd0ac, 0x1904, 0x0cdf, 0x080c, 0x630a, 0x1548,
-+	0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800,
-+	0x080c, 0x2340, 0x7824, 0x9084, 0x1800, 0x1160, 0x9484, 0x0fff,
-+	0x1138, 0x2001, 0x110f, 0x2004, 0xd0fc, 0x0110, 0x080c, 0x0d01,
-+	0x8421, 0x1178, 0x1d04, 0x0c96, 0x080c, 0x72a5, 0x2001, 0x12a7,
-+	0x2003, 0xaaaa, 0x2001, 0x12a8, 0x2003, 0x0001, 0x7003, 0x0001,
-+	0x04f0, 0x8319, 0x1938, 0x1d04, 0x0ca7, 0x080c, 0x72a5, 0x2009,
-+	0x12d5, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b,
-+	0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2321, 0x7924,
-+	0x080c, 0x2340, 0xd19c, 0x0110, 0x080c, 0x2261, 0x00d8, 0x080c,
-+	0x62f6, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x62be, 0x7003,
-+	0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, 0x2340, 0x7824, 0x080c,
-+	0x6300, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800, 0x0950, 0x7003,
-+	0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x1f11, 0x0078, 0x2009,
-+	0x110c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906,
-+	0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a, 0x7850, 0x9085,
-+	0x0400, 0x7852, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x7034,
-+	0xd0b4, 0x1110, 0x080c, 0x0df3, 0x012e, 0x00fe, 0x004e, 0x001e,
-+	0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6,
-+	0x00e6, 0x00f6, 0x0156, 0x080c, 0x2aa2, 0x015e, 0x00fe, 0x00ee,
-+	0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005,
-+	0x0005, 0x2a70, 0x2061, 0x12e3, 0x2063, 0x0003, 0x6007, 0x0001,
-+	0x600b, 0x0014, 0x600f, 0x0017, 0x2001, 0x12a7, 0x900e, 0x2102,
-+	0x718e, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x7057,
-+	0xffff, 0x0008, 0x7156, 0x705f, 0xffff, 0x7176, 0x717a, 0x080c,
-+	0xad47, 0x2061, 0x1297, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
-+	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, 0x611a, 0x601f,
-+	0x07d0, 0x2061, 0x129f, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
-+	0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
-+	0x12c3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
-+	0x2020, 0x2001, 0x112a, 0x2102, 0x0005, 0x9016, 0x080c, 0x5608,
-+	0x1178, 0x6004, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
-+	0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
-+	0x8108, 0x9186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
-+	0x0e04, 0x0d80, 0x0006, 0x0016, 0x2079, 0x0000, 0x001e, 0x798e,
-+	0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a, 0x7883, 0x8002,
-+	0x7837, 0x8002, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6,
-+	0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x137c, 0x7a18, 0x226a,
-+	0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1389, 0x201a, 0x2019,
-+	0x138c, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210,
-+	0x8318, 0x9386, 0x13a1, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110,
-+	0x2011, 0xdead, 0x2019, 0x138a, 0x782c, 0x201a, 0x8318, 0x221a,
-+	0x7803, 0x0000, 0x2069, 0x135c, 0x901e, 0x20a9, 0x0020, 0x7b26,
-+	0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dc7, 0x002e, 0x003e,
-+	0x00de, 0x015e, 0x2079, 0x1100, 0x7803, 0x0005, 0x2091, 0x4080,
-+	0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1336, 0x2004,
-+	0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
-+	0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x7834, 0xd0b4, 0x1108,
-+	0x04b9, 0x0cd8, 0x0005, 0x00f6, 0x0006, 0x2079, 0x1125, 0x2f04,
-+	0x8000, 0x207a, 0x080c, 0x2338, 0x1150, 0x0006, 0x2001, 0x12d2,
-+	0x2004, 0xd0fc, 0x000e, 0x1118, 0x9082, 0x7530, 0x0010, 0x9082,
-+	0x000f, 0x0258, 0x9006, 0x207a, 0x2079, 0x1128, 0x2f04, 0x9084,
-+	0x0001, 0x9086, 0x0001, 0x207a, 0x0080, 0x2079, 0x1128, 0x2f7c,
-+	0x8fff, 0x1130, 0x0026, 0x2011, 0x0080, 0x00e1, 0x002e, 0x0028,
-+	0x0026, 0x2011, 0x0000, 0x00b1, 0x002e, 0x000e, 0x00fe, 0x0005,
-+	0x0026, 0x2011, 0x0080, 0x0071, 0x002e, 0x2009, 0x0fff, 0x00b9,
-+	0x0026, 0x2011, 0x0040, 0x0031, 0x002e, 0x2009, 0x0fff, 0x0079,
-+	0x0c78, 0x0005, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0,
-+	0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005, 0x0156,
-+	0x0126, 0x918c, 0x0fff, 0x21a8, 0x1d04, 0x0e4c, 0x2091, 0x6000,
-+	0x1f04, 0x0e4c, 0x012e, 0x015e, 0x0005, 0x890b, 0x810b, 0x810b,
-+	0x810b, 0x810b, 0x810b, 0x9994, 0xfc00, 0x8217, 0x8214, 0x8214,
-+	0x0005, 0x0006, 0x814c, 0x894c, 0x894c, 0x894c, 0x894c, 0x894c,
-+	0x9284, 0x003f, 0x8007, 0x8003, 0x8003, 0x994d, 0x000e, 0x0005,
-+	0x0016, 0x0026, 0x0096, 0x3348, 0x0c01, 0x2100, 0x9300, 0x2098,
-+	0x22e0, 0x009e, 0x002e, 0x001e, 0x3518, 0x20a9, 0x0001, 0x4002,
-+	0x8007, 0x4004, 0x8319, 0x1dd8, 0x0005, 0x2071, 0x1100, 0x7164,
-+	0x712e, 0x2021, 0x0001, 0x9190, 0x0040, 0x9298, 0x0040, 0x0240,
-+	0x7068, 0x9302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8,
-+	0x200b, 0x0000, 0x74ba, 0x74be, 0x0005, 0x00e6, 0x0126, 0x2091,
-+	0x8000, 0x2071, 0x1100, 0x70bc, 0x90ea, 0x0010, 0x0268, 0x8001,
-+	0x70be, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807,
-+	0x0000, 0x012e, 0x00ee, 0x0005, 0x906e, 0x0cd8, 0x00e6, 0x2071,
-+	0x1100, 0x0126, 0x2091, 0x8000, 0x70bc, 0x8001, 0x0270, 0x70be,
-+	0x702c, 0x2068, 0x9085, 0x0001, 0x2d04, 0x702e, 0x206b, 0x0000,
-+	0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x906e, 0x0cd8, 0x00e6,
-+	0x0126, 0x2091, 0x8000, 0x2071, 0x1100, 0x702c, 0x206a, 0x2d00,
-+	0x702e, 0x70bc, 0x8000, 0x70be, 0x012e, 0x00ee, 0x0005, 0x8dff,
-+	0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8,
-+	0x0005, 0x00d6, 0x0859, 0x0148, 0x0016, 0x0026, 0x2d08, 0x2011,
-+	0x0001, 0x080c, 0x0e61, 0x002e, 0x001e, 0x00de, 0x0005, 0x00d6,
-+	0x080c, 0x0e9d, 0x0148, 0x0016, 0x0026, 0x2d08, 0x2011, 0x0001,
-+	0x080c, 0x0e61, 0x002e, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0016,
-+	0x0026, 0x080c, 0x0e55, 0x2168, 0x002e, 0x001e, 0x0801, 0x00de,
-+	0x0005, 0x00e6, 0x2071, 0x1335, 0x7007, 0x0000, 0x9006, 0x701e,
-+	0x7022, 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8004, 0x7012,
-+	0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2270, 0x700b,
-+	0x0000, 0x2071, 0x1335, 0x701c, 0x9088, 0x133f, 0x220a, 0x8000,
-+	0x9084, 0x0007, 0x701e, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079,
-+	0x0080, 0x0089, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x00e6, 0x2071,
-+	0x1335, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0019,
-+	0x00fe, 0x00ee, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007,
-+	0x0006, 0x7000, 0x0002, 0x0f5d, 0x0f5b, 0x0f5b, 0x0f5b, 0x10be,
-+	0x10be, 0x10be, 0x10be, 0x080c, 0x0d7e, 0x701c, 0x7120, 0x9106,
-+	0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007,
-+	0x0000, 0x0005, 0x00d6, 0x9180, 0x133f, 0x2004, 0x700a, 0x2068,
-+	0x8108, 0x918c, 0x0007, 0x7122, 0x782b, 0x0026, 0x6828, 0x7802,
-+	0x682c, 0x7806, 0x6830, 0x780a, 0x6834, 0x780e, 0x6814, 0x700e,
-+	0x680c, 0x7016, 0x6810, 0x701a, 0x6804, 0x00de, 0xd084, 0x0120,
-+	0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005,
-+	0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210,
-+	0x2110, 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b, 0x0020,
-+	0x782b, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136,
-+	0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000,
-+	0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182,
-+	0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203,
-+	0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e,
-+	0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x1335, 0x2104,
-+	0xc095, 0x200a, 0x080c, 0x0f3e, 0x0005, 0x0016, 0x00e6, 0x2071,
-+	0x1335, 0x00f6, 0x2079, 0x0080, 0x792c, 0x782b, 0x0002, 0xd1fc,
-+	0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e,
-+	0x0005, 0x0f4b, 0x0ff2, 0x1024, 0x0ff0, 0x0ff0, 0x10ca, 0x0ff0,
-+	0x080c, 0x0d7e, 0x918c, 0x0700, 0x1548, 0x0136, 0x0146, 0x0156,
-+	0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088,
-+	0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e,
-+	0x014e, 0x013e, 0x700c, 0x9005, 0x0560, 0x7800, 0x7802, 0x7804,
-+	0x7806, 0x080c, 0x0f90, 0x0005, 0x7008, 0x9080, 0x0002, 0x2003,
-+	0x0100, 0x7007, 0x0000, 0x080c, 0x0f4b, 0x0005, 0x7008, 0x9080,
-+	0x0002, 0x2003, 0x0200, 0x0ca8, 0x918c, 0x0700, 0x1150, 0x700c,
-+	0x9005, 0x0178, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x0fa5,
-+	0x0005, 0x7008, 0x9080, 0x0002, 0x2003, 0x0200, 0x7007, 0x0000,
-+	0x0080, 0x00d6, 0x7008, 0x2068, 0x7800, 0x682a, 0x7804, 0x682e,
-+	0x7808, 0x6832, 0x780c, 0x6836, 0x680b, 0x0100, 0x00de, 0x7007,
-+	0x0000, 0x00c6, 0x00d6, 0x7008, 0x2060, 0x9086, 0x11fb, 0x1128,
-+	0x6038, 0x080f, 0x00de, 0x00ce, 0x0078, 0x00de, 0x00ce, 0x00c6,
-+	0x00d6, 0x7008, 0x2060, 0x0059, 0x0128, 0x6038, 0x080f, 0x00de,
-+	0x00ce, 0x0005, 0x00de, 0x00ce, 0x080c, 0x0f4b, 0x0005, 0x00e6,
-+	0x2071, 0x1100, 0x8cff, 0x0140, 0x7064, 0x9c02, 0x0238, 0x9c82,
-+	0xffff, 0x1220, 0x9085, 0x0001, 0x00ee, 0x0005, 0x9006, 0x0ce0,
-+	0x603c, 0x906d, 0x090c, 0x0d7e, 0x6008, 0x908e, 0x0100, 0x0130,
-+	0x687b, 0x0030, 0x6883, 0x0000, 0x6897, 0x4002, 0x080c, 0x5b76,
-+	0x603b, 0x0000, 0x603f, 0x0000, 0x2c00, 0x2068, 0x080c, 0x0ecf,
-+	0x0005, 0x00f6, 0x603c, 0x906d, 0x090c, 0x0d7e, 0x6008, 0x908e,
-+	0x0100, 0x0128, 0x687b, 0x0001, 0x6883, 0x0000, 0x0080, 0x680c,
-+	0x2078, 0x7804, 0x9005, 0x0158, 0x680e, 0x2078, 0x9080, 0x0002,
-+	0x6012, 0x7800, 0x6016, 0x2c10, 0x080c, 0x0f22, 0x0068, 0x00d6,
-+	0x080c, 0x5b76, 0x00de, 0x687c, 0xd0f4, 0x0130, 0x6894, 0x00c6,
-+	0x2060, 0x080c, 0x8ed9, 0x00ce, 0x00fe, 0x0005, 0x0126, 0x2091,
-+	0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002,
-+	0x012e, 0x0005, 0x7007, 0x0000, 0x080c, 0x0f4b, 0x0005, 0x0126,
-+	0x2091, 0x2200, 0x2079, 0x0300, 0x2071, 0x1347, 0x7003, 0x0000,
-+	0x78bf, 0x00f6, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9,
-+	0x01ea, 0x2061, 0xc47d, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002,
-+	0x7916, 0x1f04, 0x10e3, 0x7807, 0x0001, 0x7803, 0x0000, 0x7803,
-+	0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c,
-+	0x0110, 0x7820, 0x0cd8, 0x2001, 0x1348, 0x2003, 0x0000, 0x78ab,
-+	0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0001,
-+	0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x135c,
-+	0x781f, 0xff00, 0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc,
-+	0x0110, 0x781f, 0x0303, 0x2061, 0x135c, 0x602f, 0x15c0, 0x6033,
-+	0x3000, 0x603b, 0x18fe, 0x00ce, 0x0005, 0x0126, 0x2091, 0x2200,
-+	0x7808, 0xd09c, 0x0158, 0x7820, 0x908c, 0xf000, 0x1578, 0x908c,
-+	0x0fe0, 0x190c, 0x0d7e, 0x0043, 0x012e, 0x0005, 0x9084, 0x0070,
-+	0x190c, 0x0d7e, 0x012e, 0x0005, 0x115c, 0x115c, 0x1165, 0x116a,
-+	0x116e, 0x1173, 0x119a, 0x119e, 0x11ab, 0x11af, 0x115c, 0x1233,
-+	0x1237, 0x1296, 0x115c, 0x115c, 0x115c, 0x115c, 0x115c, 0x115c,
-+	0x115c, 0x115c, 0x115c, 0x115c, 0x115c, 0x115c, 0x115c, 0x1175,
-+	0x115c, 0x115c, 0x115c, 0x115c, 0x080c, 0x0d7e, 0x2009, 0x0048,
-+	0x2060, 0x080c, 0x8f53, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5,
-+	0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x129d,
-+	0x080c, 0x133c, 0x0005, 0x080c, 0x0d7e, 0x080c, 0x129d, 0x2060,
-+	0x6014, 0x9080, 0x000e, 0x2003, 0xffff, 0x2009, 0x0048, 0x080c,
-+	0x8f53, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109,
-+	0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218,
-+	0x2004, 0xd0ec, 0x1110, 0x080c, 0x12a2, 0x2001, 0x0307, 0x2003,
-+	0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x129d,
-+	0x2060, 0x6014, 0x9080, 0x000e, 0x2003, 0xffff, 0x2009, 0x0048,
-+	0x080c, 0x8f53, 0x0005, 0x080c, 0x129d, 0x080c, 0x0d7e, 0x080c,
-+	0x129d, 0x080c, 0x121e, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0540,
-+	0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0138, 0x2001,
-+	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0400, 0x7004, 0x9005,
-+	0x1180, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc,
-+	0x090c, 0x0d7e, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
-+	0x0460, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1237, 0x0005,
-+	0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0d7e, 0x6014, 0x2068,
-+	0x78ab, 0x0004, 0x918c, 0x0700, 0x0198, 0x080c, 0x1577, 0x080c,
-+	0xa942, 0x0158, 0x69ac, 0x6936, 0x69b0, 0x693a, 0x683f, 0xffff,
-+	0x6843, 0xffff, 0x6880, 0xc0bd, 0x6882, 0x080c, 0xa5f3, 0x0005,
-+	0x6010, 0x2004, 0xd0bc, 0x190c, 0xace0, 0x2029, 0x00c8, 0x8529,
-+	0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c,
-+	0xc426, 0xd5a4, 0x1118, 0x080c, 0x12a2, 0x0005, 0x080c, 0x1577,
-+	0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066,
-+	0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186,
-+	0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x130c, 0x00fe, 0x007e,
-+	0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
-+	0x9184, 0x0004, 0x190c, 0x0d7e, 0xd184, 0x1189, 0xd19c, 0x0158,
-+	0xc19c, 0x7106, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
-+	0x080c, 0x12a2, 0x0005, 0x81ff, 0x190c, 0x0d7e, 0x0005, 0xc184,
-+	0xd1b4, 0xc1b4, 0x7106, 0x0016, 0x00e6, 0x15c0, 0x2071, 0x0200,
-+	0x080c, 0x1330, 0x6014, 0x9005, 0x0588, 0x9080, 0x0019, 0x2004,
-+	0x9084, 0x00ff, 0x908e, 0x0029, 0x0148, 0x908e, 0x0048, 0x1530,
-+	0x00f6, 0x2c78, 0x080c, 0x137e, 0x00fe, 0x00a8, 0x00f6, 0x2c78,
-+	0x080c, 0x1436, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0160, 0x2001,
-+	0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec,
-+	0x1110, 0x0401, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c,
-+	0x10f3, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x2001, 0x020d,
-+	0x2003, 0x0050, 0x2003, 0x0020, 0x0069, 0x0ca8, 0x0031, 0x2060,
-+	0x2009, 0x0053, 0x080c, 0x8f53, 0x0005, 0x7808, 0xd09c, 0x0de8,
-+	0x7820, 0x0005, 0x080c, 0x121e, 0x00d6, 0x2069, 0x0200, 0x2009,
-+	0x01f4, 0x8109, 0x0508, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d,
-+	0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1520, 0x79b8, 0x918c, 0x0fff,
-+	0x0178, 0x9182, 0x0841, 0x1260, 0x9188, 0x0007, 0x918c, 0x0ff8,
-+	0x810c, 0x810c, 0x810c, 0x04d1, 0x6827, 0x0001, 0x8109, 0x1dd8,
-+	0x04a9, 0x6827, 0x0002, 0x0491, 0x6804, 0x9005, 0x1130, 0x682c,
-+	0xd0e4, 0x11d0, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1120,
-+	0x08c8, 0x080c, 0x1577, 0x0070, 0x7827, 0x0015, 0x782b, 0x0000,
-+	0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300,
-+	0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086,
-+	0x5400, 0x0d50, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, 0x0001,
-+	0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, 0x9084,
-+	0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021,
-+	0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006,
-+	0x7808, 0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c, 0x1125,
-+	0x00ce, 0x002e, 0x001e, 0x000e, 0x7832, 0x7936, 0x7a3a, 0x781b,
-+	0x8080, 0x2009, 0xff00, 0x8109, 0x0128, 0x7818, 0xd0bc, 0x1dd8,
-+	0x00fe, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d7e,
-+	0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc,
-+	0x1110, 0x7054, 0x2060, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200,
-+	0x0c79, 0x7358, 0x745c, 0x6014, 0x905d, 0x0568, 0x2b68, 0x6010,
-+	0x2004, 0xd0bc, 0x190c, 0xacbb, 0x6b42, 0x6c3e, 0x2001, 0x1174,
-+	0x2004, 0xd0b4, 0x1158, 0x601c, 0xd0e4, 0x1140, 0x6010, 0x2004,
-+	0xd0bc, 0x1120, 0x683b, 0x7fff, 0x6837, 0xffff, 0x080c, 0x191e,
-+	0x1190, 0x080c, 0x1484, 0x2a00, 0x6816, 0x0130, 0x2c00, 0x680e,
-+	0x2805, 0x680a, 0x2800, 0x6812, 0x7037, 0x0020, 0x781f, 0x0300,
-+	0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e,
-+	0x00ee, 0x080c, 0x12a2, 0x0005, 0x080c, 0x0d7e, 0x2ff0, 0x0126,
-+	0x2091, 0x2200, 0x3e60, 0x6014, 0x2068, 0x2d60, 0x903e, 0x2730,
-+	0x6964, 0x691a, 0x9184, 0x000f, 0x9088, 0x18fe, 0x2145, 0x0002,
-+	0x13a0, 0x1407, 0x13a0, 0x13a0, 0x13a0, 0x13e0, 0x13a0, 0x13a4,
-+	0x13a0, 0x13f5, 0x13a0, 0x13a0, 0x13a0, 0x13a0, 0x13ca, 0x13b6,
-+	0x9085, 0x0001, 0x0804, 0x142e, 0x687c, 0xd0bc, 0x0dc8, 0x6890,
-+	0x6842, 0x688c, 0x683e, 0x6888, 0x00d6, 0x2805, 0x9c68, 0x6b08,
-+	0x6a0c, 0x6d00, 0x6c04, 0x00de, 0x0804, 0x1416, 0x687c, 0xd0bc,
-+	0x0d38, 0x6890, 0x6842, 0x688c, 0x683e, 0x6888, 0x00d6, 0x2805,
-+	0x9c68, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x00de,
-+	0x0804, 0x1416, 0x687c, 0xd0bc, 0x0998, 0x6890, 0x6842, 0x688c,
-+	0x683e, 0x6804, 0x2060, 0x9080, 0x0019, 0x200c, 0x691a, 0x91cc,
-+	0x000f, 0x9980, 0x18fe, 0x2045, 0x6888, 0xd19c, 0x11e8, 0x0470,
-+	0x687c, 0xd0ac, 0x0904, 0x13a0, 0x6804, 0x2060, 0x9080, 0x0019,
-+	0x200c, 0x691a, 0x91cc, 0x000f, 0x9980, 0x18fe, 0x2045, 0x9006,
-+	0x6842, 0x683e, 0xd19c, 0x1140, 0x00c8, 0x687c, 0xd0ac, 0x0904,
-+	0x13a0, 0x9006, 0x6842, 0x683e, 0x00d6, 0x2805, 0x9c68, 0x6b10,
-+	0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x00de, 0x0078, 0x687c,
-+	0xd0ac, 0x0904, 0x13a0, 0x9006, 0x6842, 0x683e, 0x00d6, 0x2805,
-+	0x9c68, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00de, 0x6b2e, 0x6a32,
-+	0x6d1e, 0x6c22, 0x6f26, 0x6e2a, 0x6988, 0x8840, 0x281d, 0x68ac,
-+	0x6ab0, 0x6836, 0x6a3a, 0x8109, 0x6916, 0x1150, 0x3e60, 0x601c,
-+	0xc085, 0x601e, 0x687c, 0xc0dd, 0x687e, 0x9006, 0x012e, 0x0005,
-+	0x2c00, 0x680e, 0x6b0a, 0x2800, 0x6812, 0x0c80, 0x2ff0, 0x0126,
-+	0x2091, 0x2200, 0x3e60, 0x6014, 0x2068, 0x2d60, 0x680e, 0x2041,
-+	0x18fb, 0x680b, 0x18fb, 0x2805, 0x6812, 0x6964, 0x691a, 0x687c,
-+	0xd0ac, 0x090c, 0x0d7e, 0x9006, 0x6842, 0x683e, 0x00d6, 0x2805,
-+	0x9c68, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x00de,
-+	0x6b2e, 0x6a32, 0x6d1e, 0x6c22, 0x6f26, 0x6e2a, 0x68ac, 0x6ab0,
-+	0x6836, 0x6a3a, 0x6988, 0x918a, 0x0002, 0x6916, 0x1150, 0x3e60,
-+	0x601c, 0xc085, 0x601e, 0x687c, 0xc0dd, 0x687e, 0x9006, 0x012e,
-+	0x0005, 0x6804, 0x9065, 0x090c, 0x0d7e, 0x680e, 0x6064, 0x681a,
-+	0x9084, 0x000f, 0x9080, 0x18fe, 0x2015, 0x82ff, 0x090c, 0x0d7e,
-+	0x6a0a, 0x2205, 0x6812, 0x0c18, 0x903e, 0x2730, 0x6880, 0xd0fc,
-+	0x11a8, 0x00d6, 0x2805, 0x9c68, 0x2900, 0x0002, 0x14c6, 0x14ac,
-+	0x14ac, 0x14c6, 0x14c6, 0x14c0, 0x14c6, 0x14ac, 0x14c6, 0x14b1,
-+	0x14b1, 0x14c6, 0x14c6, 0x14c6, 0x14b8, 0x14b1, 0xc0fc, 0x6882,
-+	0x6b2c, 0x6a30, 0x6d1c, 0x6c20, 0x00d6, 0xd99c, 0x0510, 0x2805,
-+	0x9c68, 0x6f08, 0x6e0c, 0x00e8, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
-+	0x00c0, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0088,
-+	0x00de, 0x00d6, 0x6864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1130,
-+	0x00de, 0x080c, 0x18be, 0x1900, 0x900e, 0x0060, 0x00de, 0x080c,
-+	0x0d7e, 0x00de, 0x6b2e, 0x6a32, 0x6d1e, 0x6c22, 0x6f26, 0x6e2a,
-+	0x080c, 0x18be, 0x0005, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0110,
-+	0xd0d4, 0x1180, 0x6014, 0x9080, 0x0021, 0x6118, 0x810c, 0x810c,
-+	0x810c, 0x81ff, 0x1118, 0x2003, 0x0001, 0x0008, 0x2102, 0x601b,
-+	0x0002, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x2001,
-+	0x0037, 0x2c08, 0x080c, 0x130c, 0x7808, 0xd09c, 0x0140, 0x0016,
-+	0x0026, 0x00c6, 0x080c, 0x1125, 0x00ce, 0x002e, 0x001e, 0x6000,
-+	0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x8f53, 0x012e,
-+	0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c,
-+	0x0007, 0x9186, 0x0000, 0x0904, 0x156c, 0x9186, 0x0003, 0x0904,
-+	0x156c, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0190, 0x00c6,
-+	0x7808, 0xd09c, 0x190c, 0x1125, 0x00ce, 0x2001, 0x0038, 0x2c08,
-+	0x621c, 0x080c, 0x130c, 0x7930, 0x9186, 0x0040, 0x05c8, 0x9186,
-+	0x0042, 0x190c, 0x0d7e, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631,
-+	0x1d30, 0x080c, 0x15c6, 0x0026, 0x0056, 0x2001, 0x00d2, 0x8001,
-+	0x1df0, 0x2031, 0x2000, 0x8631, 0x1138, 0x0489, 0x601c, 0xc084,
-+	0x601e, 0x005e, 0x002e, 0x00e0, 0x2001, 0x020b, 0x2004, 0xd0e4,
-+	0x0d90, 0x2001, 0x015d, 0x2003, 0x0000, 0x78ab, 0x0004, 0x080c,
-+	0x10f3, 0x601c, 0xc084, 0x601e, 0x7803, 0x0000, 0x7803, 0x0001,
-+	0x005e, 0x002e, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
-+	0x000e, 0x6022, 0x012e, 0x0005, 0x601c, 0xc084, 0x601e, 0x7827,
-+	0x0015, 0x7828, 0x9c06, 0x1db0, 0x782b, 0x0000, 0x0c98, 0x00f6,
-+	0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c,
-+	0x62e4, 0x11b0, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
-+	0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
-+	0x0081, 0x0066, 0x2031, 0x0000, 0x080c, 0x6380, 0x006e, 0x0005,
-+	0x0469, 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
-+	0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, 0x235b, 0x2009, 0x003c,
-+	0x080c, 0x1b67, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084,
-+	0x003c, 0x1de0, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e,
-+	0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c,
-+	0x10f3, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138,
-+	0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
-+	0x080c, 0x62e4, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141,
-+	0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048,
-+	0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70,
-+	0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019,
-+	0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120,
-+	0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x00e6, 0x2071,
-+	0x134a, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0x9280, 0x0005,
-+	0x206c, 0x697c, 0xd1dc, 0x1904, 0x167b, 0x6964, 0x9184, 0x0007,
-+	0x0002, 0x1619, 0x1666, 0x1619, 0x1619, 0x1619, 0x164d, 0x162c,
-+	0x161b, 0x080c, 0x0d7e, 0x687c, 0xd0b4, 0x0904, 0x176d, 0x6890,
-+	0x6842, 0x683a, 0x688c, 0x683e, 0x6836, 0x68ac, 0x6846, 0x68b0,
-+	0x684a, 0x6988, 0x0804, 0x166e, 0x6864, 0x9084, 0x00ff, 0x9086,
-+	0x001e, 0x1d38, 0x687c, 0xd0b4, 0x0904, 0x176d, 0x6890, 0x6842,
-+	0x683a, 0x688c, 0x683e, 0x6836, 0x68ac, 0x6846, 0x68b0, 0x684a,
-+	0x6804, 0x685a, 0x9080, 0x0019, 0x2004, 0x9084, 0x000f, 0x9080,
-+	0x18fe, 0x2005, 0x6812, 0x6988, 0x0450, 0x918c, 0x00ff, 0x9186,
-+	0x0015, 0x1548, 0x687c, 0xd0b4, 0x0904, 0x176d, 0x6804, 0x685a,
-+	0x9080, 0x0019, 0x2004, 0x9084, 0x000f, 0x9080, 0x18fe, 0x2005,
-+	0x6812, 0x6988, 0x9006, 0x6842, 0x683e, 0x0088, 0x687c, 0xd0b4,
-+	0x0904, 0x176d, 0x6988, 0x9006, 0x6842, 0x683e, 0x2d00, 0x685a,
-+	0x6864, 0x9084, 0x000f, 0x9080, 0x18fe, 0x2005, 0x6812, 0x6916,
-+	0x687c, 0xc0dd, 0x687e, 0x00de, 0x0005, 0x00f6, 0x2079, 0x0090,
-+	0x782c, 0xd0fc, 0x190c, 0x17b0, 0x00e6, 0x00d6, 0x2071, 0x134a,
-+	0x7000, 0x9005, 0x1904, 0x16de, 0x00c6, 0x7206, 0x9280, 0x0005,
-+	0x205c, 0x7004, 0x2068, 0x782b, 0x0004, 0x2001, 0x0200, 0x2003,
-+	0x0040, 0x6810, 0x00d6, 0x2068, 0x686c, 0x7836, 0x6890, 0x00f6,
-+	0x2079, 0x0200, 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001,
-+	0xa001, 0xa001, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe,
-+	0x00de, 0x2b68, 0x6814, 0x2050, 0x6858, 0x2060, 0x6810, 0x2040,
-+	0x6064, 0x90cc, 0x000f, 0x6944, 0x791a, 0x7116, 0x6848, 0x781e,
-+	0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0x6940, 0x6838, 0x9106,
-+	0x11c8, 0x693c, 0x6834, 0x9106, 0x11a8, 0x8aff, 0x01f0, 0x0126,
-+	0x2091, 0x8000, 0x2079, 0x0090, 0x2009, 0x0001, 0x00d1, 0x0118,
-+	0x2009, 0x0001, 0x00b1, 0x012e, 0x00ce, 0x9006, 0x00de, 0x00ee,
-+	0x00fe, 0x0005, 0x0036, 0x0046, 0x6b38, 0x6c34, 0x080c, 0x191e,
-+	0x004e, 0x003e, 0x0d10, 0x00ce, 0x0c88, 0x00ce, 0x9085, 0x0001,
-+	0x0c68, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff,
-+	0x0904, 0x1766, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203,
-+	0x0a04, 0x1765, 0x9705, 0x0904, 0x1765, 0x903e, 0x2730, 0x6880,
-+	0xd0fc, 0x11a8, 0x00d6, 0x2805, 0x9c68, 0x2900, 0x0002, 0x1748,
-+	0x172d, 0x172d, 0x1748, 0x1748, 0x1741, 0x1748, 0x172d, 0x1748,
-+	0x1732, 0x1732, 0x1748, 0x1748, 0x1748, 0x1739, 0x1732, 0xc0fc,
-+	0x6882, 0x6b2c, 0x6a30, 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6,
-+	0x2805, 0x9c68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00,
-+	0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
-+	0x0090, 0x00de, 0x00d6, 0x6864, 0x9084, 0x00ff, 0x9086, 0x001e,
-+	0x1138, 0x00de, 0x080c, 0x18be, 0x1904, 0x16f7, 0x900e, 0x00f0,
-+	0x00de, 0x080c, 0x0d7e, 0x00de, 0x7b12, 0x7a16, 0x7d02, 0x7c06,
-+	0x7f0a, 0x7e0e, 0x792a, 0x7000, 0x8000, 0x7002, 0x683c, 0x9300,
-+	0x683e, 0x6840, 0x9201, 0x6842, 0x700c, 0x9300, 0x700e, 0x7010,
-+	0x9201, 0x7012, 0x080c, 0x18be, 0x0008, 0x9006, 0x002e, 0x003e,
-+	0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0d7e, 0x0026,
-+	0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000,
-+	0x7004, 0x2060, 0x00d6, 0x6014, 0x2068, 0x080c, 0xa942, 0x0118,
-+	0x6880, 0xc0bd, 0x6882, 0x6020, 0x9086, 0x0006, 0x1180, 0x2061,
-+	0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206,
-+	0x1dc0, 0x60c4, 0x689a, 0x60c8, 0x6896, 0x7004, 0x2060, 0x00de,
-+	0x00c6, 0x080c, 0xa5f3, 0x00ce, 0x2001, 0x1313, 0x2004, 0x9c06,
-+	0x1160, 0x2009, 0x0040, 0x080c, 0x1b67, 0x080c, 0x8a8d, 0x2011,
-+	0x0000, 0x080c, 0x88ec, 0x080c, 0x7b72, 0x002e, 0x0804, 0x186a,
-+	0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x00f6, 0x00e6, 0x00d6,
-+	0x00c6, 0x2079, 0x0090, 0x2071, 0x134a, 0x2b68, 0x6858, 0x2060,
-+	0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x176f, 0x7000,
-+	0x0002, 0x186a, 0x17cd, 0x183d, 0x1868, 0x8001, 0x7002, 0xd19c,
-+	0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001, 0x080c, 0x16f1, 0x0904,
-+	0x186a, 0x2009, 0x0001, 0x080c, 0x16f1, 0x0804, 0x186a, 0x782b,
-+	0x0004, 0xd194, 0x0148, 0x6880, 0xc0fc, 0x6882, 0x8aff, 0x11d8,
-+	0x687c, 0xc0f5, 0x687e, 0x00b8, 0x0026, 0x0036, 0x6b3c, 0x6a40,
-+	0x7810, 0x682e, 0x931a, 0x7814, 0x6832, 0x9213, 0x7800, 0x681e,
-+	0x7804, 0x6822, 0x6b3e, 0x6a42, 0x003e, 0x002e, 0x080c, 0x18d6,
-+	0x6880, 0xc0fd, 0x6882, 0x2a00, 0x6816, 0x2c00, 0x685a, 0x2800,
-+	0x6812, 0x7003, 0x0000, 0x0804, 0x186a, 0x00f6, 0x0026, 0x781c,
-+	0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984,
-+	0x9085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c,
-+	0x0d7e, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102,
-+	0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e,
-+	0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe,
-+	0x782b, 0x0008, 0x7003, 0x0000, 0x0468, 0x8001, 0x7002, 0xd194,
-+	0x0168, 0x782c, 0xd0fc, 0x1904, 0x17c0, 0xd19c, 0x11f8, 0x8aff,
-+	0x0508, 0x2009, 0x0001, 0x080c, 0x16f1, 0x00e0, 0x0026, 0x0036,
-+	0x6b3c, 0x6a40, 0x080c, 0x18d6, 0x00d6, 0x2805, 0x9c68, 0x6064,
-+	0xd09c, 0x1128, 0x6808, 0x931a, 0x680c, 0x9213, 0x0020, 0x6810,
-+	0x931a, 0x6814, 0x9213, 0x00de, 0x0804, 0x17f0, 0x0804, 0x17ec,
-+	0x080c, 0x0d7e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x001e, 0x000e,
-+	0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x134a, 0x7000, 0x9086,
-+	0x0000, 0x0904, 0x18bb, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c,
-+	0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188,
-+	0x080c, 0xc46f, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0d7e,
-+	0x0016, 0x2009, 0x0040, 0x080c, 0x1b67, 0x001e, 0x2001, 0x020c,
-+	0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106,
-+	0x1120, 0x2009, 0x0040, 0x080c, 0x1b67, 0x782c, 0xd0fc, 0x09a8,
-+	0x080c, 0x17b0, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004,
-+	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x1b67, 0x782b,
-+	0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x8840, 0x2805,
-+	0x9005, 0x0110, 0x8a51, 0x0005, 0x6004, 0x9005, 0x0168, 0x685a,
-+	0x2060, 0x6064, 0x9084, 0x000f, 0x9080, 0x18fe, 0x2045, 0x88ff,
-+	0x090c, 0x0d7e, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
-+	0x2805, 0x9005, 0x1190, 0x2c00, 0x9d06, 0x0120, 0x6000, 0x9005,
-+	0x1108, 0x2d00, 0x2060, 0x685a, 0x6064, 0x9084, 0x000f, 0x9080,
-+	0x190e, 0x2045, 0x88ff, 0x090c, 0x0d7e, 0x0005, 0x0000, 0x001d,
-+	0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b,
-+	0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0000, 0x18f3,
-+	0x18ef, 0x0000, 0x0000, 0x18fd, 0x0000, 0x18f3, 0x0000, 0x18fa,
-+	0x18f7, 0x0000, 0x0000, 0x0000, 0x18fd, 0x18fa, 0x0000, 0x18f5,
-+	0x18f5, 0x0000, 0x0000, 0x18fd, 0x0000, 0x18f5, 0x0000, 0x18fb,
-+	0x18fb, 0x0000, 0x0000, 0x0000, 0x18fd, 0x18fb, 0x00a6, 0x0096,
-+	0x0086, 0x6b42, 0x6c3e, 0x6888, 0x9055, 0x0904, 0x19af, 0x2d60,
-+	0x6064, 0x90cc, 0x000f, 0x99c0, 0x18fe, 0x9986, 0x0007, 0x0130,
-+	0x9986, 0x000e, 0x0118, 0x9986, 0x000f, 0x1120, 0x608c, 0x9422,
-+	0x6090, 0x931b, 0x2805, 0x9045, 0x1140, 0x0310, 0x0804, 0x19af,
-+	0x6004, 0x9065, 0x0904, 0x19af, 0x0c18, 0x2805, 0x9005, 0x01a8,
-+	0x9c68, 0xd99c, 0x1128, 0x6808, 0x9422, 0x680c, 0x931b, 0x0020,
-+	0x6810, 0x9422, 0x6814, 0x931b, 0x0620, 0x2300, 0x9405, 0x0150,
-+	0x8a51, 0x0904, 0x19af, 0x8840, 0x0c40, 0x6004, 0x9065, 0x0904,
-+	0x19af, 0x0830, 0x8a51, 0x0904, 0x19af, 0x8840, 0x2805, 0x9005,
-+	0x1158, 0x6004, 0x9065, 0x0904, 0x19af, 0x6064, 0x90cc, 0x000f,
-+	0x99c0, 0x18fe, 0x2805, 0x2040, 0x2b68, 0x6880, 0xc0fc, 0x6882,
-+	0x0458, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000, 0x00d6, 0x2b68,
-+	0x6c2e, 0x6b32, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0x9122,
-+	0x690c, 0x2300, 0x911b, 0x0a0c, 0x0d7e, 0x6800, 0x9420, 0x6804,
-+	0x9319, 0x0060, 0x6910, 0x2400, 0x9122, 0x6914, 0x2300, 0x911b,
-+	0x0a0c, 0x0d7e, 0x6800, 0x9420, 0x6804, 0x9319, 0x2b68, 0x6c1e,
-+	0x6b22, 0x6880, 0xc0fd, 0x6882, 0x2c00, 0x685a, 0x2800, 0x6812,
-+	0x2a00, 0x6816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e,
-+	0x009e, 0x00ae, 0x9085, 0x0001, 0x0005, 0x2008, 0x9026, 0x2410,
-+	0x780f, 0x0000, 0x7810, 0x9420, 0x9291, 0x0000, 0x7814, 0x9210,
-+	0x8109, 0x1dc0, 0x9284, 0x000f, 0x9405, 0x0005, 0x2001, 0x0005,
-+	0x2004, 0x9084, 0x0007, 0x0002, 0x19de, 0x17b0, 0x19de, 0x19d4,
-+	0x19d7, 0x19da, 0x19d7, 0x19da, 0x080c, 0x17b0, 0x0005, 0x080c,
-+	0x0fd5, 0x0005, 0x080c, 0x17b0, 0x080c, 0x0fd5, 0x0005, 0x0126,
-+	0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1100,
-+	0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410,
-+	0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f,
-+	0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600,
-+	0x781c, 0xd0a4, 0x190c, 0x1b64, 0x7900, 0xd1dc, 0x1118, 0x9084,
-+	0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x1a27, 0x1a1d, 0x6bd6,
-+	0x1a1f, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x6bba, 0x1a1d, 0x1a23,
-+	0x1a1d, 0x1a21, 0x1a1d, 0x1a21, 0x1a1d, 0x080c, 0x0d7e, 0x080c,
-+	0x0d7e, 0x0031, 0x0020, 0x080c, 0x6bba, 0x080c, 0x6bd6, 0x0005,
-+	0x0006, 0x0016, 0x0026, 0x080c, 0xc46f, 0x7930, 0x9184, 0x0003,
-+	0x01c0, 0x2001, 0x1313, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133,
-+	0x2004, 0x9005, 0x090c, 0x0d7e, 0x00c6, 0x2001, 0x1313, 0x2064,
-+	0x080c, 0xa5f3, 0x00ce, 0x0460, 0x2009, 0x0040, 0x080c, 0x1b67,
-+	0x0438, 0x9184, 0x0014, 0x01b0, 0x6a00, 0x9286, 0x0003, 0x0180,
-+	0x080c, 0x62e4, 0x1158, 0x2001, 0x12a8, 0x2003, 0x0001, 0x2001,
-+	0x1100, 0x2003, 0x0001, 0x080c, 0x621a, 0x0010, 0x080c, 0x4faa,
-+	0x0099, 0x0070, 0x9184, 0x1400, 0x0110, 0x0071, 0x0048, 0x9184,
-+	0x0140, 0x0110, 0x0049, 0x0020, 0x9184, 0x8000, 0x0108, 0x0021,
-+	0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, 0x0056,
-+	0x2071, 0x1347, 0x080c, 0x1577, 0x005e, 0x004e, 0x003e, 0x00ee,
-+	0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1100, 0x7128, 0x2001,
-+	0x129a, 0x2102, 0x2001, 0x12a2, 0x2102, 0x2001, 0x013b, 0x2102,
-+	0x2079, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x2320,
-+	0x9182, 0x0224, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0088,
-+	0x9182, 0x02d4, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0048,
-+	0x9182, 0x0444, 0x1220, 0x2011, 0x0002, 0x8423, 0x0010, 0x2011,
-+	0x0001, 0x9482, 0x0110, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110,
-+	0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x2001, 0x0201, 0x789e,
-+	0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0003, 0x2320,
-+	0x9182, 0x0204, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0088,
-+	0x9182, 0x02b4, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0048,
-+	0x9182, 0x041c, 0x1220, 0x2011, 0x0002, 0x8423, 0x0010, 0x2011,
-+	0x0001, 0x9482, 0x010c, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110,
-+	0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x78a3, 0x0200, 0x9198,
-+	0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, 0x9182,
-+	0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, 0x0488,
-+	0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, 0x9400,
-+	0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, 0x0006,
-+	0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, 0x1230,
-+	0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, 0x042c,
-+	0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, 0x059c,
-+	0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, 0x0002,
-+	0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, 0x0110,
-+	0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, 0x0005,
-+	0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, 0x910d,
-+	0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, 0x9005,
-+	0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005,
-+	0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, 0x910d,
-+	0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0d7e, 0x00f6,
-+	0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
-+	0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
-+	0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071,
-+	0x1100, 0x2009, 0x0000, 0x080c, 0x2355, 0x080c, 0x2261, 0x6054,
-+	0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150, 0x918c,
-+	0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000,
-+	0x6052, 0x2009, 0x12d7, 0x2011, 0x12d8, 0x6358, 0x939c, 0x38f0,
-+	0x2320, 0x080c, 0x22a5, 0x1238, 0x939d, 0x4003, 0x94a5, 0x8603,
-+	0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603, 0x230a,
-+	0x2412, 0x9006, 0x080c, 0x2290, 0x9006, 0x080c, 0x2273, 0x20a9,
-+	0x0012, 0x1d04, 0x1bb9, 0x2091, 0x6000, 0x1f04, 0x1bb9, 0x602f,
-+	0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff,
-+	0x6052, 0x6024, 0x6026, 0x080c, 0x1f7d, 0x2009, 0x00ef, 0x6132,
-+	0x6136, 0x080c, 0x1f8d, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008,
-+	0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000,
-+	0x6007, 0x049f, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000,
-+	0x1f04, 0x1be6, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012,
-+	0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e,
-+	0x600f, 0x006b, 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079,
-+	0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe,
-+	0x0005, 0x2001, 0x1134, 0x2003, 0x0000, 0x2001, 0x1133, 0x2003,
-+	0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
-+	0x6124, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x002a, 0x9195,
-+	0x0004, 0x9284, 0x0007, 0x0002, 0x1c46, 0x1c2c, 0x1c2f, 0x1c32,
-+	0x1c37, 0x1c39, 0x1c3d, 0x1c41, 0x080c, 0x745c, 0x00b8, 0x080c,
-+	0x752d, 0x00a0, 0x080c, 0x752d, 0x080c, 0x745c, 0x0078, 0x0099,
-+	0x0068, 0x080c, 0x745c, 0x0079, 0x0048, 0x080c, 0x752d, 0x0059,
-+	0x0028, 0x080c, 0x752d, 0x080c, 0x745c, 0x0029, 0x002e, 0x001e,
-+	0x000e, 0x012e, 0x0005, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c,
-+	0x1904, 0x1e92, 0xd1f4, 0x0110, 0x080c, 0x0d7e, 0x080c, 0x62e4,
-+	0x05d0, 0x7000, 0x9086, 0x0003, 0x01f0, 0x6024, 0x9084, 0x1800,
-+	0x01d0, 0x080c, 0x630a, 0x0118, 0x080c, 0x62f6, 0x11a0, 0x6027,
-+	0x0020, 0x6043, 0x0000, 0x709c, 0x9005, 0x1140, 0x709f, 0x0001,
-+	0x00d6, 0x2069, 0x0140, 0x080c, 0x633e, 0x00de, 0x2001, 0x12a7,
-+	0x2003, 0xaaaa, 0x0458, 0x080c, 0x630a, 0x15d0, 0x6024, 0x9084,
-+	0x1800, 0x1108, 0x04a8, 0x2001, 0x12a7, 0x2003, 0xaaaa, 0x2001,
-+	0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003, 0x0001, 0x080c,
-+	0x621a, 0x0804, 0x1e92, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170,
-+	0xd0e4, 0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7090, 0x9086,
-+	0x0028, 0x1110, 0x080c, 0x6492, 0x0804, 0x1e92, 0x2001, 0x12a8,
-+	0x2003, 0x0000, 0x0048, 0x2001, 0x12a8, 0x2003, 0x0002, 0x0020,
-+	0x080c, 0x6404, 0x0804, 0x1e92, 0x080c, 0x6531, 0x0804, 0x1e92,
-+	0xd1ac, 0x0904, 0x1db5, 0x080c, 0x62e4, 0x11d8, 0x6027, 0x0020,
-+	0x0006, 0x0026, 0x0036, 0x080c, 0x6300, 0x1170, 0x2001, 0x12a8,
-+	0x2003, 0x0001, 0x2001, 0x1100, 0x2003, 0x0001, 0x080c, 0x621a,
-+	0x003e, 0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c,
-+	0x62be, 0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138,
-+	0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74d6,
-+	0x948c, 0xff00, 0x7034, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160,
-+	0x7040, 0xd084, 0x1148, 0xc085, 0x7042, 0x0036, 0x2418, 0x2011,
-+	0x8016, 0x080c, 0x3f23, 0x003e, 0x9196, 0xff00, 0x05a8, 0x7058,
-+	0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130,
-+	0xd184, 0x1550, 0x080c, 0x2987, 0x0128, 0xc18d, 0x7132, 0x080c,
-+	0x58c6, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294,
-+	0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x1d83,
-+	0x7034, 0xd08c, 0x1140, 0x2001, 0x110c, 0x200c, 0xd1ac, 0x1904,
-+	0x1d83, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c,
-+	0x3f23, 0x003e, 0x0804, 0x1d83, 0x7034, 0xd08c, 0x1140, 0x2001,
-+	0x110c, 0x200c, 0xd1ac, 0x1904, 0x1d83, 0xc1ad, 0x2102, 0x0036,
-+	0x73d4, 0x2011, 0x8013, 0x080c, 0x3f23, 0x003e, 0x7130, 0xc185,
-+	0x7132, 0x2011, 0x1153, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009,
-+	0x0001, 0x2011, 0x0100, 0x080c, 0x73af, 0x2019, 0x000e, 0x00c6,
-+	0x2061, 0x0000, 0x080c, 0xc0b9, 0x00ce, 0x9484, 0x00ff, 0x9080,
-+	0x298c, 0x200d, 0x918c, 0xff00, 0x810f, 0x8127, 0x9006, 0x2009,
-+	0x000e, 0x080c, 0xc12f, 0x001e, 0xd1ac, 0x1140, 0x0016, 0x900e,
-+	0x2019, 0x0004, 0x080c, 0x2831, 0x001e, 0x0068, 0x0156, 0x20a9,
-+	0x007f, 0x900e, 0x080c, 0x5608, 0x1110, 0x080c, 0x5100, 0x8108,
-+	0x1f04, 0x1d7a, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c,
-+	0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec, 0x080c, 0x87a2, 0x0036,
-+	0x901e, 0x080c, 0x8847, 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001,
-+	0x1100, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0, 0x2011,
-+	0x110c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206,
-+	0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1124, 0x2003,
-+	0x0000, 0x080c, 0x483b, 0x6027, 0x0020, 0xd194, 0x0904, 0x1e92,
-+	0x0016, 0x6220, 0xd2b4, 0x0904, 0x1e3e, 0x080c, 0x7271, 0x080c,
-+	0x85a2, 0x6027, 0x0004, 0x00f6, 0x2019, 0x130d, 0x2304, 0x907d,
-+	0x0904, 0x1e0f, 0x7804, 0x9086, 0x0032, 0x1904, 0x1e0f, 0x00d6,
-+	0x00c6, 0x00e6, 0x2069, 0x0140, 0x7810, 0x685e, 0x7808, 0x685a,
-+	0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000,
-+	0x2001, 0x003c, 0x8001, 0x1df0, 0x2001, 0x1000, 0x080c, 0x2401,
-+	0x9006, 0x080c, 0x2401, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9,
-+	0x0009, 0x080c, 0x2321, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001,
-+	0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x080c, 0x79ab,
-+	0x080c, 0x7aa4, 0x7814, 0x2070, 0x7067, 0x0103, 0x2f60, 0x080c,
-+	0x8ed9, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe,
-+	0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0138, 0x2001,
-+	0x1000, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x00de, 0x00c6,
-+	0x2061, 0x1304, 0x6028, 0x909a, 0x00c8, 0x1238, 0x8000, 0x602a,
-+	0x00ce, 0x080c, 0x857e, 0x0804, 0x1e91, 0x2061, 0x0100, 0x62c0,
-+	0x080c, 0x8dc7, 0x2019, 0x130d, 0x2304, 0x9065, 0x0120, 0x2009,
-+	0x0027, 0x080c, 0x8f53, 0x00ce, 0x0804, 0x1e91, 0xd2bc, 0x05f0,
-+	0x080c, 0x727e, 0x6014, 0x9084, 0x1984, 0x9085, 0x0010, 0x6016,
-+	0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000,
-+	0x0138, 0x2001, 0x1000, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401,
-+	0x00de, 0x00c6, 0x2061, 0x1304, 0x6044, 0x909a, 0x00c8, 0x1608,
-+	0x8000, 0x6046, 0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0,
-+	0x080c, 0x7276, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138,
-+	0x6114, 0x918c, 0x1984, 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114,
-+	0x918c, 0x1984, 0x918d, 0x0016, 0x6116, 0x0098, 0x6027, 0x0004,
-+	0x0080, 0x0036, 0x2019, 0x0001, 0x080c, 0x8847, 0x003e, 0x2019,
-+	0x1313, 0x2304, 0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0x8f53,
-+	0x00ce, 0x001e, 0xd19c, 0x0904, 0x1f0d, 0x7034, 0xd0ac, 0x1904,
-+	0x1edb, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2346, 0x6050,
-+	0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c,
-+	0x2340, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x1eae,
-+	0x2091, 0x6000, 0x1f04, 0x1eae, 0x6050, 0x9085, 0x0400, 0x9084,
-+	0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x1ebc, 0x6150,
-+	0x9185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, 0x1ec5, 0x2091,
-+	0x6000, 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027,
-+	0x0008, 0x04d8, 0x080c, 0x2304, 0x1f04, 0x1ec5, 0x015e, 0x6152,
-+	0x001e, 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011,
-+	0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec, 0x080c,
-+	0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e, 0x60e3, 0x0000,
-+	0x080c, 0xc44e, 0x080c, 0xc469, 0x2001, 0x1172, 0x2004, 0xd0fc,
-+	0x1120, 0x9085, 0x0001, 0x080c, 0x6331, 0x9006, 0x080c, 0x2401,
-+	0x2009, 0x0002, 0x080c, 0x2355, 0x2001, 0x1100, 0x2003, 0x0004,
-+	0x6027, 0x0008, 0x080c, 0x0b68, 0x001e, 0x918c, 0xffd0, 0x6126,
-+	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126,
-+	0x2091, 0x8000, 0x2071, 0x1100, 0x71cc, 0x70ce, 0x9116, 0x05d8,
-+	0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2355, 0x2011, 0x8011,
-+	0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001,
-+	0x0010, 0x2019, 0x0000, 0x080c, 0x3f23, 0x0428, 0x2001, 0x12e0,
-+	0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118,
-+	0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x3f23,
-+	0x2001, 0x1172, 0x2004, 0xd0fc, 0x1170, 0x00c6, 0x080c, 0x1fd8,
-+	0x080c, 0x877f, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002,
-+	0x080c, 0x2831, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e,
-+	0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094,
-+	0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, 0x6e62, 0x0038, 0x9080,
-+	0x298c, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080,
-+	0x298c, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140,
-+	0x2001, 0x1116, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852,
-+	0x6856, 0x1f04, 0x1f88, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026,
-+	0x2069, 0x0140, 0x2001, 0x1116, 0x2102, 0x8114, 0x8214, 0x8214,
-+	0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128,
-+	0x9184, 0x000f, 0x9080, 0xc84f, 0x2005, 0x6856, 0x8211, 0x1f04,
-+	0x1f9d, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1100,
-+	0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005,
-+	0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980,
-+	0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001,
-+	0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x1fcd,
-+	0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005,
-+	0x2001, 0x1153, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006,
-+	0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xc12f, 0x004e, 0x0005,
-+	0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904,
-+	0x2045, 0x080c, 0x22a5, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600,
-+	0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120,
-+	0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016,
-+	0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009,
-+	0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004,
-+	0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040,
-+	0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058,
-+	0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x73f0, 0x928c, 0xff00,
-+	0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2,
-+	0x2009, 0x0138, 0x220a, 0x080c, 0x62e4, 0x1118, 0x2009, 0x1298,
-+	0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8,
-+	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170,
-+	0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e,
-+	0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004,
-+	0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e,
-+	0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e,
-+	0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108,
-+	0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108,
-+	0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000,
-+	0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x12ca,
-+	0x2004, 0x908a, 0x0007, 0x1a0c, 0x0d7e, 0x0033, 0x00ee, 0x002e,
-+	0x001e, 0x000e, 0x015e, 0x0005, 0x20a3, 0x20c1, 0x20e5, 0x20e7,
-+	0x2110, 0x2112, 0x2114, 0x2001, 0x0001, 0x080c, 0x1f11, 0x080c,
-+	0x22fd, 0x2001, 0x12cc, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7,
-+	0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x22b9, 0x2001, 0x12ca,
-+	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2115, 0x080c, 0x7283,
-+	0x0005, 0x2009, 0x12cf, 0x200b, 0x0000, 0x2001, 0x12d4, 0x2003,
-+	0x0036, 0x2001, 0x12d3, 0x2003, 0x002a, 0x2001, 0x12cc, 0x2003,
-+	0x0001, 0x9006, 0x080c, 0x2273, 0x2001, 0xffff, 0x20a9, 0x0009,
-+	0x080c, 0x22b9, 0x2001, 0x12ca, 0x2003, 0x0006, 0x2009, 0x001e,
-+	0x2011, 0x2115, 0x080c, 0x7283, 0x0005, 0x080c, 0x0d7e, 0x2001,
-+	0x12d4, 0x2003, 0x0036, 0x2001, 0x12cc, 0x2003, 0x0003, 0x7a38,
-+	0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001,
-+	0x0001, 0x080c, 0x2273, 0x2001, 0x12d0, 0x2003, 0x0000, 0x2001,
-+	0xffff, 0x20a9, 0x0009, 0x080c, 0x22b9, 0x2001, 0x12ca, 0x2003,
-+	0x0006, 0x2009, 0x001e, 0x2011, 0x2115, 0x080c, 0x7283, 0x0005,
-+	0x080c, 0x0d7e, 0x080c, 0x0d7e, 0x0005, 0x0006, 0x0016, 0x0026,
-+	0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
-+	0x2001, 0x12cc, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0d7e, 0x0043,
-+	0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005,
-+	0x2137, 0x2157, 0x2197, 0x21c7, 0x21eb, 0x21fb, 0x21fd, 0x080c,
-+	0x22ad, 0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x12d2,
-+	0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d,
-+	0x0008, 0xc085, 0x200a, 0x2001, 0x12ca, 0x2003, 0x0001, 0x0030,
-+	0x080c, 0x2221, 0x2001, 0xffff, 0x080c, 0x20b2, 0x0005, 0x080c,
-+	0x21ff, 0x05e0, 0x2009, 0x12d3, 0x2104, 0x8001, 0x200a, 0x080c,
-+	0x22ad, 0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38, 0x9294,
-+	0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x12d2, 0x2104, 0xc085,
-+	0x200a, 0x2009, 0x12cf, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005,
-+	0x0118, 0x080c, 0x2207, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294,
-+	0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
-+	0x080c, 0x2290, 0x2001, 0x12cc, 0x2003, 0x0002, 0x0028, 0x2001,
-+	0x12ca, 0x2003, 0x0003, 0x0010, 0x080c, 0x20d4, 0x0005, 0x080c,
-+	0x21ff, 0x0560, 0x2009, 0x12d3, 0x2104, 0x8001, 0x200a, 0x080c,
-+	0x22ad, 0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001, 0x12ca,
-+	0x2003, 0x0003, 0x2001, 0x12cb, 0x2003, 0x0000, 0x00b8, 0x2009,
-+	0x12d3, 0x2104, 0x9005, 0x1118, 0x080c, 0x2245, 0x0010, 0x080c,
-+	0x2214, 0x080c, 0x2207, 0x2009, 0x12cf, 0x200b, 0x0000, 0x2001,
-+	0x12cc, 0x2003, 0x0001, 0x080c, 0x20d4, 0x0000, 0x0005, 0x04b9,
-+	0x0508, 0x080c, 0x22ad, 0x11b8, 0x7850, 0x9084, 0xefff, 0x7852,
-+	0x2009, 0x12d0, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108,
-+	0x0078, 0x2001, 0x12d5, 0x2003, 0x000a, 0x2009, 0x12d2, 0x2104,
-+	0xc0fd, 0x200a, 0x0038, 0x0419, 0x2001, 0x12cc, 0x2003, 0x0004,
-+	0x080c, 0x20ff, 0x0005, 0x0099, 0x0168, 0x080c, 0x22ad, 0x1138,
-+	0x7850, 0x9084, 0xefff, 0x7852, 0x080c, 0x20eb, 0x0018, 0x0079,
-+	0x080c, 0x20ff, 0x0005, 0x080c, 0x0d7e, 0x080c, 0x0d7e, 0x2009,
-+	0x12d4, 0x2104, 0x8001, 0x200a, 0x090c, 0x2261, 0x0005, 0x7a38,
-+	0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001,
-+	0x0001, 0x080c, 0x2290, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296,
-+	0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2273,
-+	0x0005, 0x2009, 0x12cf, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005,
-+	0x0108, 0x0070, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296,
-+	0x0006, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, 0x04d9,
-+	0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
-+	0x2001, 0x0001, 0x080c, 0x2290, 0x0005, 0x0086, 0x2001, 0x12d2,
-+	0x2004, 0x9084, 0x7fff, 0x090c, 0x0d7e, 0x2009, 0x12d1, 0x2144,
-+	0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120,
-+	0x080c, 0x0d7e, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e,
-+	0x0005, 0x0006, 0x0156, 0x2001, 0x12ca, 0x20a9, 0x0009, 0x2003,
-+	0x0000, 0x8000, 0x1f04, 0x2267, 0x2001, 0x12d1, 0x2003, 0x8000,
-+	0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
-+	0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009,
-+	0x12d7, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085,
-+	0x0006, 0x783a, 0x2009, 0x12d8, 0x210c, 0x795a, 0x00fe, 0x0005,
-+	0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138, 0x7838, 0x9084,
-+	0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838, 0x9084, 0xfffb,
-+	0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006, 0x2001, 0x0100,
-+	0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0156, 0x20a9, 0x0064,
-+	0x7820, 0x080c, 0x2340, 0xd09c, 0x1110, 0x1f04, 0x22b0, 0x015e,
-+	0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c, 0x2346,
-+	0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852,
-+	0x080c, 0x2340, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186,
-+	0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118,
-+	0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005,
-+	0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006,
-+	0x1d04, 0x22e8, 0x080c, 0x72a5, 0x1f04, 0x22e8, 0x7850, 0x9085,
-+	0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2340, 0x9085, 0x1000,
-+	0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x080c, 0x2346, 0x7850,
-+	0x9084, 0xffcf, 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079,
-+	0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4,
-+	0x1140, 0x1f04, 0x230e, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04,
-+	0x2314, 0x00fe, 0x015e, 0x000e, 0x0005, 0x7820, 0x0409, 0xd09c,
-+	0x0005, 0x1d04, 0x2321, 0x080c, 0x72a5, 0x1f04, 0x2321, 0x0005,
-+	0x0006, 0x2001, 0x12d6, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
-+	0x0006, 0x2001, 0x12d6, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
-+	0x0006, 0x2001, 0x12d6, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
-+	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x0016,
-+	0x2009, 0x0140, 0x2104, 0x080c, 0x6300, 0x1110, 0xc0bd, 0x0008,
-+	0xc0bc, 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x2001, 0x12e0,
-+	0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140,
-+	0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a,
-+	0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00,
-+	0x9186, 0x2000, 0x0118, 0x9186, 0x0100, 0x1560, 0x2009, 0x017f,
-+	0x200b, 0x00a2, 0x2009, 0x0169, 0x2019, 0x0160, 0x2324, 0x2011,
-+	0x0003, 0x2104, 0x9084, 0x0007, 0x9086, 0x0003, 0x11b8, 0x2304,
-+	0x9402, 0x02a0, 0x1d98, 0x8211, 0x1da0, 0x84ff, 0x0170, 0x2001,
-+	0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009,
-+	0x110c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0419, 0x2001, 0x017f,
-+	0x2003, 0x0000, 0x004e, 0x003e, 0x0005, 0x2001, 0x110c, 0x2004,
-+	0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001,
-+	0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126,
-+	0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e,
-+	0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161,
-+	0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008,
-+	0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017,
-+	0x0040, 0x2001, 0x1000, 0x0429, 0x9006, 0x0419, 0x001e, 0x9184,
-+	0x0003, 0x01c0, 0x0036, 0x2019, 0x0141, 0x2304, 0x9084, 0xff00,
-+	0x9086, 0x0800, 0x1dd0, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118,
-+	0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012,
-+	0x6016, 0x003e, 0x2001, 0x110c, 0x200c, 0xc1dc, 0x2102, 0x00ce,
-+	0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001,
-+	0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x2678, 0x2678, 0x249d,
-+	0x249d, 0x24a9, 0x24a9, 0x24b5, 0x24b5, 0x24c3, 0x24c3, 0x24cf,
-+	0x24cf, 0x24dd, 0x24dd, 0x24eb, 0x24eb, 0x24fd, 0x24fd, 0x2509,
-+	0x2509, 0x2517, 0x2517, 0x2535, 0x2535, 0x2555, 0x2555, 0x2525,
-+	0x2525, 0x2545, 0x2545, 0x2563, 0x2563, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x2575, 0x2575, 0x2581,
-+	0x2581, 0x258f, 0x258f, 0x259d, 0x259d, 0x25ad, 0x25ad, 0x25bb,
-+	0x25bb, 0x25cb, 0x25cb, 0x25db, 0x25db, 0x25ed, 0x25ed, 0x25fb,
-+	0x25fb, 0x260b, 0x260b, 0x262d, 0x262d, 0x264f, 0x264f, 0x261b,
-+	0x261b, 0x263e, 0x263e, 0x265e, 0x265e, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb,
-+	0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x24fb, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1c12, 0x0804,
-+	0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-+	0x0156, 0x080c, 0x19c6, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c,
-+	0x1c12, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106,
-+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-+	0x1c12, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c, 0x1c12, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1125, 0x0804,
-+	0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-+	0x0156, 0x080c, 0x1c12, 0x080c, 0x1125, 0x0804, 0x2670, 0x0106,
-+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-+	0x19c6, 0x080c, 0x1125, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1c12, 0x080c,
-+	0x1125, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c,
-+	0x1c12, 0x080c, 0x1125, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c,
-+	0x1125, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1125, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x19c6, 0x080c, 0x1c12, 0x080c,
-+	0x1125, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x0804,
-+	0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-+	0x0156, 0x080c, 0x2048, 0x080c, 0x1c12, 0x0804, 0x2670, 0x0106,
-+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-+	0x2048, 0x080c, 0x19c6, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c,
-+	0x19c6, 0x080c, 0x1c12, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x1c12, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x19c6, 0x080c,
-+	0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x19c6, 0x080c,
-+	0x1c12, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c,
-+	0x1125, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x1c12, 0x080c,
-+	0x1125, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x19c6, 0x080c,
-+	0x1125, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-+	0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c, 0x1c12, 0x080c,
-+	0x1125, 0x080c, 0x19fe, 0x0804, 0x2670, 0x0106, 0x0006, 0x0126,
-+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048, 0x080c,
-+	0x19c6, 0x080c, 0x1c12, 0x080c, 0x1125, 0x0490, 0x0106, 0x0006,
-+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048,
-+	0x080c, 0x19c6, 0x080c, 0x1125, 0x080c, 0x19fe, 0x0408, 0x0106,
-+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-+	0x2048, 0x080c, 0x1125, 0x080c, 0x19fe, 0x0090, 0x0106, 0x0006,
-+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2048,
-+	0x080c, 0x19c6, 0x080c, 0x1c12, 0x080c, 0x1125, 0x080c, 0x19fe,
-+	0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e,
-+	0x000d, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x588e, 0x1904,
-+	0x275a, 0x72d8, 0x2001, 0x12a7, 0x2004, 0x9005, 0x1110, 0xd29c,
-+	0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x275a, 0x080c, 0x275e,
-+	0x0804, 0x275a, 0xd2cc, 0x1904, 0x275a, 0x080c, 0x62e4, 0x1120,
-+	0x70a7, 0xffff, 0x0804, 0x275a, 0xd294, 0x0120, 0x70a7, 0xffff,
-+	0x0804, 0x275a, 0x080c, 0x2982, 0x0120, 0x70a7, 0xffff, 0x0804,
-+	0x275a, 0x2001, 0x1116, 0x203c, 0x728c, 0xd284, 0x0904, 0x26fd,
-+	0xd28c, 0x1904, 0x26fd, 0x0036, 0x73a4, 0x938e, 0xffff, 0x1110,
-+	0x2019, 0x0001, 0x8314, 0x92e0, 0x1580, 0x2c04, 0x938c, 0x0001,
-+	0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e,
-+	0x0558, 0x908e, 0x0000, 0x0540, 0x908e, 0x00ff, 0x1150, 0x7230,
-+	0xd284, 0x1530, 0x728c, 0xc28d, 0x728e, 0x70a7, 0xffff, 0x003e,
-+	0x0420, 0x900e, 0x080c, 0x1f63, 0x080c, 0x55b3, 0x11b8, 0x6004,
-+	0x9084, 0x00ff, 0x9086, 0x0006, 0x1150, 0x7030, 0xd08c, 0x0118,
-+	0x6000, 0xd0bc, 0x0120, 0x080c, 0x2771, 0x0140, 0x0028, 0x080c,
-+	0x28a1, 0x080c, 0x279e, 0x0110, 0x8318, 0x0820, 0x73a6, 0x0010,
-+	0x70a7, 0xffff, 0x003e, 0x0804, 0x275a, 0x9780, 0x298c, 0x203d,
-+	0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70a4, 0x9096, 0xffff,
-+	0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802,
-+	0x20a8, 0x0020, 0x70a7, 0xffff, 0x0804, 0x275a, 0x2700, 0x0156,
-+	0x0016, 0x9106, 0x05a0, 0xc484, 0x080c, 0x5608, 0x0120, 0x080c,
-+	0x55b3, 0x15a8, 0x0008, 0xc485, 0x6004, 0x9084, 0x00ff, 0x9086,
-+	0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000, 0xd0bc, 0x11d0,
-+	0x728c, 0xd28c, 0x0188, 0x6004, 0x9084, 0x00ff, 0x9082, 0x0006,
-+	0x02b0, 0xd484, 0x1118, 0x080c, 0x55d0, 0x0028, 0x080c, 0x292a,
-+	0x0170, 0x080c, 0x2955, 0x0058, 0x080c, 0x28a1, 0x080c, 0x279e,
-+	0x0170, 0x0028, 0x080c, 0x292a, 0x0110, 0x0419, 0x0140, 0x001e,
-+	0x8108, 0x015e, 0x1f04, 0x2716, 0x70a7, 0xffff, 0x0018, 0x001e,
-+	0x015e, 0x71a6, 0x004e, 0x002e, 0x00ce, 0x0005, 0x00c6, 0x0016,
-+	0x70a7, 0x0001, 0x2009, 0x007e, 0x080c, 0x55b3, 0x1138, 0x080c,
-+	0x28a1, 0x04a1, 0x0118, 0x70d8, 0xc0bd, 0x70da, 0x001e, 0x00ce,
-+	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0x1157,
-+	0x2004, 0x9084, 0x00ff, 0x6842, 0x080c, 0x8f26, 0x01d0, 0x2d00,
-+	0x6012, 0x080c, 0xad70, 0x6023, 0x0001, 0x9006, 0x080c, 0x5556,
-+	0x2001, 0x0000, 0x080c, 0x5568, 0x0126, 0x2091, 0x8000, 0x70a0,
-+	0x8000, 0x70a2, 0x012e, 0x2009, 0x0004, 0x080c, 0x8f53, 0x9085,
-+	0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076,
-+	0x00d6, 0x00c6, 0x2c68, 0x2001, 0x1157, 0x2004, 0x9084, 0x00ff,
-+	0x6842, 0x080c, 0x8f26, 0x0548, 0x2d00, 0x6012, 0x6800, 0xc0c4,
-+	0x6802, 0x68a0, 0x9086, 0x007e, 0x0140, 0x6804, 0x9084, 0x00ff,
-+	0x9086, 0x0006, 0x1110, 0x080c, 0x2862, 0x080c, 0xad70, 0x6023,
-+	0x0001, 0x9006, 0x080c, 0x5556, 0x2001, 0x0002, 0x080c, 0x5568,
-+	0x0126, 0x2091, 0x8000, 0x70a0, 0x8000, 0x70a2, 0x012e, 0x2009,
-+	0x0002, 0x080c, 0x8f53, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e,
-+	0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x55b3,
-+	0x1120, 0x0031, 0x0110, 0x70df, 0xffff, 0x002e, 0x00ce, 0x0005,
-+	0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x8e83, 0x01e0,
-+	0x2d00, 0x6012, 0x080c, 0xad70, 0x6023, 0x0001, 0x9006, 0x080c,
-+	0x5556, 0x2001, 0x0002, 0x080c, 0x5568, 0x0126, 0x2091, 0x8000,
-+	0x080c, 0x2862, 0x70e0, 0x8000, 0x70e2, 0x012e, 0x2009, 0x0002,
-+	0x080c, 0x8f53, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
-+	0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f,
-+	0x080c, 0x55b3, 0x1190, 0x2c68, 0x080c, 0x8e83, 0x0170, 0x2d00,
-+	0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xad70, 0x2009,
-+	0x0022, 0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce,
-+	0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x21f0, 0x080c,
-+	0x76fb, 0x080c, 0x768d, 0x080c, 0x9ce7, 0x3e08, 0x2130, 0x81ff,
-+	0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
-+	0x0016, 0x080c, 0x5608, 0x1140, 0x9686, 0x0002, 0x1118, 0x6000,
-+	0xd0bc, 0x1110, 0x080c, 0x5100, 0x001e, 0x8108, 0x1f04, 0x2848,
-+	0x86ff, 0x1110, 0x080c, 0x0a79, 0x002e, 0x003e, 0x006e, 0x00ce,
-+	0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210,
-+	0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x76f0, 0x0076,
-+	0x2039, 0x0000, 0x080c, 0x75ee, 0x2c08, 0x080c, 0xbec2, 0x007e,
-+	0x001e, 0x2e60, 0x6210, 0x6314, 0x080c, 0x5100, 0x6212, 0x6316,
-+	0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006,
-+	0x6010, 0x9080, 0x0028, 0x2004, 0x9086, 0x0080, 0x0150, 0x2071,
-+	0x1100, 0x70a0, 0x9005, 0x0110, 0x8001, 0x70a2, 0x000e, 0x00ee,
-+	0x0005, 0x2071, 0x1100, 0x70e0, 0x9005, 0x0dc0, 0x8001, 0x70e2,
-+	0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-+	0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, 0x20a9,
-+	0x0001, 0x0090, 0x2001, 0x1153, 0x2004, 0xd0c4, 0x0150, 0xd0a4,
-+	0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c, 0xc12f,
-+	0x004e, 0x20a9, 0x00ff, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904,
-+	0x2909, 0x928e, 0x007f, 0x05e8, 0x928e, 0x0080, 0x05d0, 0x9288,
-+	0x1000, 0x210c, 0x81ff, 0x05a8, 0x8fff, 0x1148, 0x2001, 0x12c8,
-+	0x0006, 0x2003, 0x0001, 0x04c9, 0x000e, 0x2003, 0x0000, 0x00c6,
-+	0x2160, 0x2001, 0x0001, 0x080c, 0x5898, 0x00ce, 0x2019, 0x0029,
-+	0x080c, 0x76f0, 0x0076, 0x2039, 0x0000, 0x080c, 0x75ee, 0x00c6,
-+	0x0026, 0x2160, 0x6204, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118,
-+	0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0x6206,
-+	0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xbec2, 0x001e, 0x007e,
-+	0x2160, 0x002e, 0x8210, 0x1f04, 0x28c4, 0x015e, 0x001e, 0x002e,
-+	0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016,
-+	0x2001, 0x1153, 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0x9006,
-+	0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xc12f, 0x001e, 0x002e,
-+	0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x728c, 0x82ff,
-+	0x01e8, 0x080c, 0x58c6, 0x11d0, 0x2100, 0x080c, 0x1f77, 0x81ff,
-+	0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1580, 0x2c04, 0xd384,
-+	0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116,
-+	0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001,
-+	0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126,
-+	0x2091, 0x8000, 0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019,
-+	0x0029, 0x080c, 0x8ac9, 0x002e, 0x080c, 0xc3d4, 0x003e, 0x002e,
-+	0x001e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
-+	0x2061, 0x1389, 0x001e, 0x6112, 0x080c, 0x2862, 0x001e, 0x080c,
-+	0x55d0, 0x012e, 0x00ce, 0x001e, 0x0005, 0x2001, 0x1136, 0x2004,
-+	0xd0cc, 0x0005, 0x2001, 0x1174, 0x2004, 0xd0bc, 0x0005, 0x2011,
-+	0x1153, 0x2214, 0xd2ec, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2,
-+	0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4,
-+	0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca,
-+	0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9,
-+	0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad,
-+	0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3,
-+	0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f,
-+	0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079,
-+	0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d,
-+	0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863,
-+	0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252,
-+	0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047,
-+	0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35,
-+	0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b,
-+	0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e,
-+	0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004,
-+	0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000,
-+	0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00,
-+	0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00,
-+	0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500,
-+	0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00,
-+	0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000,
-+	0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800,
-+	0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200,
-+	0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00,
-+	0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000,
-+	0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000,
-+	0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-+	0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x1193, 0x7003, 0x0002,
-+	0x9006, 0x7012, 0x7016, 0x7042, 0x7046, 0x703a, 0x703e, 0x7033,
-+	0x11aa, 0x7037, 0x11aa, 0x7007, 0x0001, 0x2061, 0x11ea, 0x6003,
-+	0x0002, 0x0005, 0x2071, 0x1193, 0x7004, 0x0002, 0x2aaa, 0x2aab,
-+	0x2ab2, 0x2ac3, 0x0005, 0x1004, 0x2ab1, 0x0e04, 0x2ab1, 0x2b78,
-+	0x0430, 0x0005, 0x2b78, 0x2061, 0x11ea, 0x6008, 0x908e, 0x0100,
-+	0x0128, 0x9086, 0x0200, 0x0904, 0x2b92, 0x0005, 0x7014, 0x2068,
-+	0x2a60, 0x7018, 0x0807, 0x7010, 0x2068, 0x6864, 0x9094, 0x00ff,
-+	0x9296, 0x0029, 0x1120, 0x6a78, 0xd2fc, 0x0128, 0x0005, 0x9086,
-+	0x0103, 0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60,
-+	0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, 0x2100, 0x908a,
-+	0x003f, 0x1a04, 0x2b8f, 0x61cc, 0x0804, 0x2b26, 0x2b68, 0x2b9e,
-+	0x2ba8, 0x2bac, 0x2bb6, 0x2bbc, 0x2bc0, 0x2bd0, 0x2bd3, 0x2bdd,
-+	0x2be2, 0x2be7, 0x2bf2, 0x2bfd, 0x2c0c, 0x2c1b, 0x2c29, 0x2c40,
-+	0x2c5b, 0x2cf4, 0x2cf9, 0x2d37, 0x2de5, 0x2df6, 0x2e15, 0x2b8f,
-+	0x2b8f, 0x2b8f, 0x2e4d, 0x2e6b, 0x2e74, 0x2ea3, 0x2ea9, 0x2b8f,
-+	0x2ed2, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2edd, 0x2ee6,
-+	0x2eee, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f,
-+	0x2ef0, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2f0d, 0x2f64,
-+	0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x0002, 0x2f8e,
-+	0x2fe1, 0x303b, 0x3053, 0x3083, 0x3301, 0x2b8f, 0x44b5, 0x2b8f,
-+	0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2b8f, 0x2bdd,
-+	0x2be2, 0x376a, 0x2b8f, 0x3781, 0x454f, 0x45a5, 0x464b, 0x2b8f,
-+	0x46b0, 0x46e0, 0x4705, 0x4813, 0x4736, 0x478d, 0x2b8f, 0x3785,
-+	0x394a, 0x3960, 0x3980, 0x39e5, 0x3a4e, 0x3a59, 0x3ac1, 0x3ad0,
-+	0x3adf, 0x3ae2, 0x3b05, 0x3b77, 0x3bf0, 0x3bfd, 0x3cfe, 0x3e22,
-+	0x3e4b, 0x4032, 0x4054, 0x4060, 0x40d5, 0x419b, 0x2b8f, 0x2b8f,
-+	0x2b8f, 0x2b8f, 0x4203, 0x421e, 0x43b9, 0x4473, 0x7144, 0x0000,
-+	0x2021, 0x4000, 0x080c, 0x3eff, 0x0126, 0x2091, 0x8000, 0x0e04,
-+	0x2b72, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
-+	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
-+	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-+	0x0fcd, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005, 0x2021,
-+	0x4001, 0x08c0, 0x2021, 0x4002, 0x08a8, 0x2021, 0x4003, 0x0890,
-+	0x2021, 0x4005, 0x0878, 0x2021, 0x4006, 0x0860, 0x2039, 0x0001,
-+	0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x3f0c,
-+	0x7883, 0x0004, 0x7884, 0x0807, 0x2039, 0x0001, 0x902e, 0x2520,
-+	0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x3f0f, 0x7984, 0x7888,
-+	0x2114, 0x200a, 0x0804, 0x2b68, 0x7984, 0x2114, 0x0804, 0x2b68,
-+	0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
-+	0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x2b68,
-+	0x7884, 0x2060, 0x04d8, 0x2009, 0x0003, 0x2011, 0x0001, 0x2019,
-+	0x0014, 0x789b, 0x0017, 0x0804, 0x2b68, 0x2039, 0x0001, 0x7d98,
-+	0x7c9c, 0x0800, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0848, 0x79a0,
-+	0x9182, 0x0040, 0x0210, 0x0804, 0x2b9b, 0x2138, 0x7d98, 0x7c9c,
-+	0x0804, 0x2ba2, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x2b9b,
-+	0x2138, 0x7d98, 0x7c9c, 0x0804, 0x2bb0, 0x79a0, 0x9182, 0x0040,
-+	0x0210, 0x0804, 0x2b9b, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001,
-+	0x21a0, 0x4004, 0x0804, 0x2b68, 0x2061, 0x0800, 0xe10c, 0x9006,
-+	0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904,
-+	0x2b68, 0x0804, 0x2b95, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
-+	0x2b9b, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804,
-+	0x2b68, 0x2069, 0x1152, 0x7884, 0x7990, 0x911a, 0x1a04, 0x2b9b,
-+	0x8019, 0x0904, 0x2b9b, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888,
-+	0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x65bd, 0x0804, 0x2b68,
-+	0x2069, 0x1152, 0x7884, 0x7994, 0x911a, 0x1a04, 0x2b9b, 0x8019,
-+	0x0904, 0x2b9b, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866,
-+	0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x5946,
-+	0x012e, 0x0804, 0x2b68, 0x902e, 0x2520, 0x81ff, 0x1904, 0x2b98,
-+	0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1,
-+	0x119a, 0x4101, 0x080c, 0x3eb9, 0x0904, 0x2b98, 0x2009, 0x0020,
-+	0x2039, 0x0001, 0x080c, 0x3f0c, 0x701b, 0x2c77, 0x0005, 0x6864,
-+	0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0150, 0x9096, 0x0019,
-+	0x0138, 0x9096, 0x0015, 0x0120, 0x9096, 0x0029, 0x1904, 0x2b98,
-+	0x810f, 0x918c, 0x00ff, 0x0904, 0x2b98, 0x710e, 0x700c, 0x8001,
-+	0x0538, 0x700e, 0x080c, 0x3eb9, 0x0904, 0x2b98, 0x2009, 0x0020,
-+	0x2061, 0x11ea, 0x6228, 0x632c, 0x6430, 0x6534, 0x9290, 0x0040,
-+	0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, 0x2039, 0x0001,
-+	0x080c, 0x3f0c, 0x701b, 0x2cad, 0x0005, 0x6864, 0x9084, 0x00ff,
-+	0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x2b98, 0x08b0,
-+	0x7010, 0x2068, 0x6868, 0xc0fd, 0x686a, 0x6864, 0x9084, 0x00ff,
-+	0x9096, 0x0029, 0x1160, 0xc2fd, 0x6a7a, 0x080c, 0x51e5, 0x0150,
-+	0x0126, 0x2091, 0x8000, 0x687a, 0x6982, 0x012e, 0x0050, 0x080c,
-+	0x54d0, 0x1128, 0x7007, 0x0003, 0x701b, 0x2cd9, 0x0005, 0x080c,
-+	0x5d95, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001,
-+	0x2099, 0x119a, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1,
-+	0x0000, 0x95a9, 0x0000, 0x9d80, 0x0019, 0x2009, 0x0020, 0x012e,
-+	0x2039, 0x0001, 0x0804, 0x3f0f, 0x61b4, 0x7884, 0x60b6, 0x0804,
-+	0x2b68, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, 0x7883,
-+	0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, 0x2009,
-+	0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200,
-+	0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd,
-+	0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089,
-+	0x2004, 0xd084, 0x0180, 0x2001, 0x1336, 0x2004, 0x9005, 0x0128,
-+	0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003,
-+	0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff,
-+	0x1904, 0x2b98, 0x7984, 0x810f, 0x918c, 0x00ff, 0x080c, 0x5608,
-+	0x1904, 0x2b9b, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0210,
-+	0x0804, 0x2b9b, 0x7c88, 0x7d8c, 0x080c, 0x5758, 0x080c, 0x5728,
-+	0x0000, 0x1518, 0x2061, 0x15c0, 0x0126, 0x2091, 0x8000, 0x6000,
-+	0x9086, 0x0000, 0x0148, 0x6014, 0x906d, 0x0130, 0x686c, 0x9406,
-+	0x1118, 0x6870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001,
-+	0x1118, 0x2004, 0x9c02, 0x1a04, 0x2b98, 0x0c30, 0x080c, 0xa5f3,
-+	0x012e, 0x0904, 0x2b98, 0x0804, 0x2b68, 0x900e, 0x2001, 0x0005,
-+	0x080c, 0x5d95, 0x0126, 0x2091, 0x8000, 0x080c, 0xac07, 0x080c,
-+	0x5b76, 0x012e, 0x0804, 0x2b68, 0x00f6, 0x2d78, 0x7998, 0x810f,
-+	0x918c, 0x00ff, 0x080c, 0x5608, 0x1904, 0x2dd2, 0x7ea4, 0x9684,
-+	0x3fff, 0x9082, 0x4000, 0x0208, 0x04e8, 0x7c9c, 0x7da0, 0x080c,
-+	0x5758, 0x080c, 0x5728, 0x1520, 0x2061, 0x15c0, 0x0126, 0x2091,
-+	0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x906d, 0x0130,
-+	0x686c, 0x9406, 0x1118, 0x6870, 0x9506, 0x0158, 0x012e, 0x9ce0,
-+	0x0018, 0x2001, 0x1118, 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0,
-+	0x0c28, 0x080c, 0xa5f3, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0,
-+	0x900e, 0x2001, 0x0005, 0x080c, 0x5d95, 0x0126, 0x2091, 0x8000,
-+	0x080c, 0xac07, 0x080c, 0x5b76, 0x012e, 0x0070, 0x7897, 0x4005,
-+	0x799a, 0x0010, 0x7897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-+	0x0030, 0x2f68, 0x00fe, 0x0005, 0x7897, 0x4000, 0x9006, 0x918d,
-+	0x0001, 0x2008, 0x2f68, 0x00fe, 0x0005, 0x81ff, 0x1904, 0x2b98,
-+	0x080c, 0x3ece, 0x0904, 0x2b9b, 0x080c, 0x56ca, 0x0904, 0x2b98,
-+	0x080c, 0x575e, 0x0904, 0x2b98, 0x0804, 0x2b68, 0x81ff, 0x1904,
-+	0x2b98, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x080c, 0x57a6, 0x0904,
-+	0x2b98, 0x2019, 0x0005, 0x7984, 0x080c, 0x5779, 0x0904, 0x2b98,
-+	0x7888, 0x908a, 0x1000, 0x1a04, 0x2b9b, 0x8003, 0x800b, 0x810b,
-+	0x9108, 0x080c, 0x7206, 0x0804, 0x2b68, 0x0126, 0x2091, 0x8000,
-+	0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x00ff, 0x6454,
-+	0x2400, 0x9506, 0x01f8, 0x2508, 0x080c, 0x5608, 0x11d8, 0x080c,
-+	0x57a6, 0x1128, 0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019,
-+	0x0004, 0x900e, 0x080c, 0x5779, 0x1118, 0x2009, 0x0006, 0x0078,
-+	0x7884, 0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108,
-+	0x080c, 0x7206, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x2b68, 0x012e,
-+	0x0804, 0x2b98, 0x012e, 0x0804, 0x2b9b, 0x080c, 0x3ece, 0x0904,
-+	0x2b9b, 0x080c, 0x56ca, 0x0904, 0x2b98, 0x62a0, 0x2019, 0x0005,
-+	0x00c6, 0x2061, 0x0000, 0x080c, 0x76f0, 0x0076, 0x2039, 0x0000,
-+	0x080c, 0x75ee, 0x900e, 0x080c, 0xbec2, 0x007e, 0x00ce, 0x080c,
-+	0x5758, 0x0804, 0x2b68, 0x080c, 0x3ece, 0x0904, 0x2b9b, 0x080c,
-+	0x5758, 0x2208, 0x0804, 0x2b68, 0x0156, 0x00d6, 0x00e6, 0x2069,
-+	0x1240, 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016,
-+	0x901e, 0x20a9, 0x007e, 0x2069, 0x1000, 0x2d04, 0x9075, 0x0118,
-+	0x704c, 0x0059, 0x9210, 0x8d68, 0x1f04, 0x2e85, 0x2300, 0x9218,
-+	0x00ee, 0x00de, 0x015e, 0x0804, 0x2b68, 0x00f6, 0x0016, 0x907d,
-+	0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0,
-+	0x001e, 0x00fe, 0x0005, 0x2069, 0x1240, 0x6910, 0x62b8, 0x0804,
-+	0x2b68, 0x81ff, 0x1904, 0x2b98, 0x6154, 0x9190, 0x298c, 0x2215,
-+	0x9294, 0x00ff, 0x6374, 0x83ff, 0x0108, 0x6278, 0x67d8, 0xd79c,
-+	0x0118, 0x2031, 0x0001, 0x0090, 0xd7ac, 0x0118, 0x2031, 0x0003,
-+	0x0068, 0xd7a4, 0x0118, 0x2031, 0x0002, 0x0040, 0x080c, 0x62e4,
-+	0x1118, 0x2031, 0x0004, 0x0010, 0x2031, 0x0000, 0x7e9a, 0x7f9e,
-+	0x0804, 0x2b68, 0x6144, 0x6248, 0x2019, 0x12c0, 0x231c, 0x2001,
-+	0x12c1, 0x2004, 0x789a, 0x0804, 0x2b68, 0x0126, 0x2091, 0x8000,
-+	0x6134, 0x6238, 0x633c, 0x012e, 0x0804, 0x2b68, 0x080c, 0x3ef0,
-+	0x0904, 0x2b9b, 0x6244, 0x6338, 0x0804, 0x2b68, 0x080c, 0x0d7e,
-+	0x6144, 0x6248, 0x7884, 0x6046, 0x7b88, 0x634a, 0x2069, 0x1152,
-+	0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x12c0, 0x2d1c, 0x206a,
-+	0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x12c1,
-+	0x2d04, 0x266a, 0x789a, 0x0804, 0x2b68, 0x0126, 0x2091, 0x8000,
-+	0x7884, 0x6036, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x12d7,
-+	0x200a, 0x78ac, 0x2011, 0x12d8, 0x2012, 0x2069, 0x0100, 0x6838,
-+	0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a,
-+	0x00de, 0x7884, 0xd0b4, 0x0120, 0x3b00, 0x9084, 0xff3f, 0x20d8,
-+	0x7888, 0x603a, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118,
-+	0x918d, 0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x788c, 0x603e,
-+	0x012e, 0x0804, 0x2b68, 0x00f6, 0x2079, 0x1100, 0x7a34, 0x6898,
-+	0x9084, 0xfeff, 0x9215, 0x689c, 0x9084, 0xfeff, 0x8002, 0x9214,
-+	0xd2b4, 0x0120, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x7834, 0xd0c4,
-+	0x0108, 0xc2c5, 0x7a36, 0x6897, 0x4000, 0x900e, 0x9085, 0x0001,
-+	0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888,
-+	0x9025, 0x0904, 0x2b9b, 0x788c, 0x902d, 0x0904, 0x2b9b, 0x900e,
-+	0x080c, 0x5608, 0x1120, 0x6244, 0x6338, 0x6446, 0x653a, 0x9186,
-+	0x00ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x3ef0, 0x0904, 0x2b9b,
-+	0x7888, 0x900d, 0x0904, 0x2b9b, 0x788c, 0x9005, 0x0904, 0x2b9b,
-+	0x6244, 0x6146, 0x6338, 0x603a, 0x0804, 0x2b68, 0x2001, 0x1100,
-+	0x2004, 0x9086, 0x0003, 0x1904, 0x2b98, 0x00c6, 0x2061, 0x0100,
-+	0x7984, 0x810f, 0x918c, 0x00ff, 0x9196, 0x00ff, 0x1130, 0x2001,
-+	0x1116, 0x2004, 0x9085, 0xff00, 0x0078, 0x9182, 0x007f, 0x1698,
-+	0x9188, 0x298c, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1116, 0x2004,
-+	0x9116, 0x0548, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006,
-+	0x080c, 0x8e83, 0x000e, 0x01d8, 0x6012, 0x600b, 0xbc09, 0x6023,
-+	0x0001, 0x080c, 0x3eb9, 0x01d0, 0x9006, 0x6866, 0x7007, 0x0003,
-+	0x6832, 0x6868, 0xc0fd, 0x686a, 0x701b, 0x3034, 0x2d00, 0x6016,
-+	0x2009, 0x0032, 0x080c, 0x8f53, 0x012e, 0x00ce, 0x0005, 0x012e,
-+	0x00ce, 0x0804, 0x2b98, 0x00ce, 0x0804, 0x2b9b, 0x080c, 0x8ed9,
-+	0x0cb0, 0x2001, 0x1100, 0x2004, 0x9086, 0x0003, 0x1904, 0x2b98,
-+	0x00c6, 0x2061, 0x0100, 0x7984, 0x810f, 0x918c, 0x00ff, 0x9196,
-+	0x00ff, 0x1130, 0x2001, 0x1116, 0x2004, 0x9085, 0xff00, 0x0078,
-+	0x9182, 0x007f, 0x1698, 0x9188, 0x298c, 0x210d, 0x918c, 0x00ff,
-+	0x2001, 0x1116, 0x2004, 0x9116, 0x0548, 0x810f, 0x9105, 0x0126,
-+	0x2091, 0x8000, 0x0006, 0x080c, 0x8e83, 0x000e, 0x01d8, 0x6012,
-+	0x600b, 0xbc05, 0x6023, 0x0001, 0x080c, 0x3eb9, 0x01d0, 0x9006,
-+	0x6866, 0x7007, 0x0003, 0x6832, 0x6868, 0xc0fd, 0x686a, 0x701b,
-+	0x3034, 0x2d00, 0x6016, 0x2009, 0x0032, 0x080c, 0x8f53, 0x012e,
-+	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x2b98, 0x00ce, 0x0804,
-+	0x2b9b, 0x080c, 0x8ed9, 0x0cb0, 0x6830, 0x9086, 0x0100, 0x0904,
-+	0x2b98, 0x0804, 0x2b68, 0x2061, 0x1354, 0x0126, 0x2091, 0x8000,
-+	0x6000, 0xd084, 0x0168, 0x6104, 0x6208, 0x2a60, 0x634c, 0x606c,
-+	0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x2b68,
-+	0x900e, 0x2110, 0x0c90, 0x81ff, 0x1904, 0x2b98, 0x080c, 0x62e4,
-+	0x0904, 0x2b98, 0x0126, 0x2091, 0x8000, 0x624c, 0x606c, 0x9202,
-+	0x0248, 0x9085, 0x0001, 0x080c, 0x1fad, 0x080c, 0x49f2, 0x012e,
-+	0x0804, 0x2b68, 0x012e, 0x0804, 0x2b9b, 0x0006, 0x0016, 0x00c6,
-+	0x00e6, 0x2001, 0x12e1, 0x2070, 0x2061, 0x1152, 0x6008, 0x2072,
-+	0x900e, 0x2011, 0x1400, 0x080c, 0x73f0, 0x7206, 0x00ee, 0x00ce,
-+	0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128,
-+	0x012e, 0x2021, 0x400b, 0x0804, 0x2b6a, 0x7884, 0xd0fc, 0x0148,
-+	0x2001, 0x002a, 0x2004, 0x9082, 0x00e1, 0x02a8, 0x012e, 0x0804,
-+	0x2b9b, 0x2001, 0x002a, 0x2004, 0x2069, 0x1152, 0x6908, 0x9102,
-+	0x1218, 0x012e, 0x0804, 0x2b9b, 0x614c, 0x606c, 0x9106, 0x0118,
-+	0x012e, 0x0804, 0x2b98, 0x60d8, 0xd0ac, 0x0dd0, 0x7884, 0xd0fc,
-+	0x0904, 0x30fd, 0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x0d88, 0x6867,
-+	0x0000, 0x7884, 0x680a, 0x7898, 0x680e, 0x789c, 0x6812, 0x2001,
-+	0x002e, 0x2004, 0x681a, 0x2001, 0x002f, 0x2004, 0x681e, 0x2001,
-+	0x0030, 0x2004, 0x6822, 0x2001, 0x0031, 0x2004, 0x6826, 0x2001,
-+	0x0034, 0x2004, 0x682a, 0x2001, 0x0035, 0x2004, 0x682e, 0x2001,
-+	0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0x6816,
-+	0x080c, 0x3262, 0x0928, 0x7010, 0x2068, 0x6d2c, 0x6c28, 0x6b1c,
-+	0x6a18, 0x6930, 0x6808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021,
-+	0x0000, 0x9d80, 0x001b, 0x2039, 0x0001, 0x080c, 0x3f0c, 0x701b,
-+	0x31c0, 0x701f, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096,
-+	0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x306d,
-+	0x2001, 0x12d9, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100,
-+	0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012,
-+	0x080c, 0x32d2, 0x080c, 0x3290, 0x00f6, 0x00e6, 0x00c6, 0x2d60,
-+	0x2071, 0x134a, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884,
-+	0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034,
-+	0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x360c, 0x00ce,
-+	0x00ee, 0x00fe, 0x080c, 0x3542, 0x080c, 0x3472, 0x05b8, 0x2001,
-+	0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x3634, 0x00f6,
-+	0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071,
-+	0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200,
-+	0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100,
-+	0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106,
-+	0x1190, 0x2001, 0x111e, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061,
-+	0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x347c,
-+	0x080c, 0x328b, 0x0058, 0x080c, 0x328b, 0x080c, 0x35a4, 0x080c,
-+	0x3538, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a,
-+	0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106,
-+	0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108,
-+	0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102,
-+	0x080c, 0x10cf, 0x2009, 0x0028, 0x080c, 0x1b67, 0x2001, 0x0227,
-+	0x200c, 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
-+	0x009e, 0x008e, 0x004e, 0x2001, 0x12d9, 0x2004, 0x9005, 0x1118,
-+	0x012e, 0x0804, 0x2b68, 0x012e, 0x2021, 0x400c, 0x0804, 0x2b6a,
-+	0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x00d6, 0x0156,
-+	0x7010, 0x2068, 0x701c, 0x20a8, 0x8000, 0x701e, 0x6804, 0x9005,
-+	0x05d0, 0x2068, 0x1f04, 0x31ce, 0x2061, 0x11ea, 0x6228, 0x632c,
-+	0x6430, 0x6534, 0x6930, 0x6808, 0xd0b4, 0x1120, 0x2029, 0x0000,
-+	0x2021, 0x0000, 0x00d6, 0x7010, 0x2068, 0x6864, 0x00de, 0x9086,
-+	0x0103, 0x0148, 0x9d80, 0x001b, 0x2039, 0x0001, 0x080c, 0x3f0c,
-+	0x701b, 0x31c0, 0x0078, 0x9d80, 0x001b, 0x21a8, 0x20a0, 0x2098,
-+	0x0006, 0x080c, 0x504f, 0x000e, 0x2039, 0x0001, 0x080c, 0x3f0f,
-+	0x701b, 0x31c0, 0x015e, 0x00de, 0x007e, 0x005e, 0x004e, 0x003e,
-+	0x002e, 0x001e, 0x0005, 0x7010, 0x2068, 0x6864, 0x9086, 0x0103,
-+	0x1118, 0x701b, 0x3260, 0x0410, 0x7010, 0x2068, 0x6868, 0xc0fd,
-+	0x686a, 0x2009, 0x007f, 0x080c, 0x55b3, 0x0110, 0x9006, 0x0010,
-+	0x080c, 0xadbf, 0x015e, 0x00de, 0x007e, 0x005e, 0x004e, 0x003e,
-+	0x002e, 0x001e, 0x0904, 0x2b98, 0x0016, 0x0026, 0x0036, 0x0046,
-+	0x0056, 0x0076, 0x00d6, 0x0156, 0x701b, 0x3239, 0x7007, 0x0003,
-+	0x0848, 0x0076, 0x6830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904,
-+	0x2b6a, 0x6d10, 0x6c0c, 0x6b24, 0x6a20, 0x6930, 0x6808, 0xd0b4,
-+	0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x9d80, 0x001b, 0x21a8,
-+	0x20a0, 0x2098, 0x0006, 0x080c, 0x504f, 0x000e, 0x2039, 0x0001,
-+	0x080c, 0x3f0f, 0x007e, 0x701b, 0x31c0, 0x701f, 0x0001, 0x0005,
-+	0x0804, 0x2b68, 0x0156, 0x00c6, 0x6814, 0x908a, 0x001e, 0x0218,
-+	0x6833, 0x001e, 0x0010, 0x6832, 0x0078, 0x81ff, 0x0168, 0x0016,
-+	0x080c, 0x3eb9, 0x001e, 0x0130, 0x6800, 0x2060, 0x6008, 0x680a,
-+	0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e,
-+	0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044,
-+	0x00fe, 0x000e, 0x0005, 0x2001, 0x12d9, 0x2003, 0x0001, 0x0005,
-+	0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x12e2, 0x2004,
-+	0x601a, 0x2061, 0x0100, 0x2001, 0x12e1, 0x2004, 0x60ce, 0x6104,
-+	0xc1ac, 0x6106, 0x080c, 0x3eb9, 0x6813, 0x0019, 0x2070, 0x6817,
-+	0x0001, 0x2d00, 0x685a, 0x2001, 0x002e, 0x2004, 0x2072, 0x2001,
-+	0x002f, 0x2004, 0x7006, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001,
-+	0x12e1, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x1b67, 0x2001,
-+	0x002a, 0x2004, 0x9084, 0xfff8, 0x700a, 0x601a, 0x700f, 0x0000,
-+	0x601f, 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee,
-+	0x00fe, 0x0005, 0x00e6, 0x080c, 0x3eb9, 0x2d60, 0x6013, 0x0019,
-+	0x2070, 0x6017, 0x0001, 0x2c00, 0x605a, 0x2001, 0x0030, 0x2004,
-+	0x2072, 0x2001, 0x0031, 0x2004, 0x7006, 0x2001, 0x002a, 0x2004,
-+	0x9084, 0xfff8, 0x700a, 0x700f, 0x0000, 0x2001, 0x032a, 0x2003,
-+	0x0004, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003,
-+	0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee,
-+	0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2338,
-+	0x1130, 0x9006, 0x080c, 0x2290, 0x9006, 0x080c, 0x2273, 0x7884,
-+	0x9084, 0x0007, 0x0002, 0x331e, 0x3327, 0x3330, 0x331b, 0x331b,
-+	0x331b, 0x331b, 0x331b, 0x012e, 0x0804, 0x2b9b, 0x2009, 0x0114,
-+	0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x349a, 0x0080, 0x2009,
-+	0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, 0x349a, 0x0038,
-+	0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2b6a, 0x0086,
-+	0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c,
-+	0x306d, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0032, 0x2034,
-+	0x2001, 0x0033, 0x202c, 0x9006, 0x2048, 0x2050, 0x2058, 0x080c,
-+	0x3700, 0x080c, 0x3660, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x00c6,
-+	0x2d60, 0x2071, 0x134a, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000,
-+	0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001,
-+	0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x360c,
-+	0x080c, 0x360c, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x3542, 0x00f6,
-+	0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201,
-+	0x200c, 0x81ff, 0x0150, 0x080c, 0x3520, 0x2900, 0x9a05, 0x9b05,
-+	0x0120, 0x080c, 0x347c, 0x0804, 0x342b, 0x080c, 0x3634, 0x080c,
-+	0x35a4, 0x080c, 0x3503, 0x080c, 0x3538, 0x00f6, 0x2079, 0x0100,
-+	0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x347c, 0x00fe, 0x0804,
-+	0x342b, 0x00fe, 0x080c, 0x3472, 0x1150, 0x8948, 0x2001, 0x0032,
-+	0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x347c, 0x0080, 0x87ff,
-+	0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038,
-+	0x2001, 0x1347, 0x2004, 0x9086, 0x0000, 0x1904, 0x3377, 0x2001,
-+	0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605,
-+	0x0904, 0x342b, 0x7884, 0xd0bc, 0x0128, 0x2900, 0x9a05, 0x9b05,
-+	0x1904, 0x342b, 0x6013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004,
-+	0x7884, 0xd0ac, 0x1148, 0x2001, 0x1347, 0x2003, 0x0003, 0x2001,
-+	0x032a, 0x2003, 0x0009, 0x0040, 0x6017, 0x0001, 0x2001, 0x002d,
-+	0x2004, 0x9005, 0x0108, 0x6016, 0x2c00, 0x605a, 0x2009, 0x0040,
-+	0x080c, 0x1b67, 0x2d00, 0x685a, 0x6813, 0x0019, 0x7884, 0xd0a4,
-+	0x1180, 0x6817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090,
-+	0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3400, 0x00ce,
-+	0x0040, 0x6817, 0x0001, 0x2001, 0x002c, 0x2004, 0x9005, 0x0108,
-+	0x6816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827,
-+	0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006,
-+	0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce,
-+	0x00fe, 0x0804, 0x3355, 0x001e, 0x2001, 0x032a, 0x2003, 0x0004,
-+	0x2061, 0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013,
-+	0x0020, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c,
-+	0x10cf, 0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x01a0, 0x2009,
-+	0x0028, 0x080c, 0x1b67, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050,
-+	0x9084, 0xb7ef, 0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043,
-+	0x0090, 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0x9a05,
-+	0x9905, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-+	0x008e, 0x1118, 0x012e, 0x0804, 0x2b68, 0x012e, 0x2021, 0x400c,
-+	0x0804, 0x2b6a, 0x9085, 0x0001, 0x1d04, 0x347b, 0x2091, 0x6000,
-+	0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010,
-+	0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x009a, 0x2003, 0x0004,
-+	0x2001, 0x1347, 0x2003, 0x0000, 0x2001, 0x134a, 0x2003, 0x0000,
-+	0x2009, 0x0048, 0x080c, 0x1b67, 0x2001, 0x0227, 0x2024, 0x2402,
-+	0x9026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1116, 0x200c,
-+	0x7932, 0x7936, 0x080c, 0x1f8d, 0x7850, 0x9084, 0xfbff, 0x9085,
-+	0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf,
-+	0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x34b5, 0x2091,
-+	0x6000, 0x1f04, 0x34b5, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
-+	0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
-+	0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
-+	0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x34d5,
-+	0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001,
-+	0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
-+	0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
-+	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2401, 0x7827,
-+	0x0020, 0x7843, 0x0000, 0x2001, 0x0000, 0x080c, 0x2401, 0x7827,
-+	0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6,
-+	0x2071, 0x1347, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005,
-+	0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108,
-+	0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005,
-+	0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178,
-+	0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108,
-+	0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005,
-+	0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050,
-+	0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x12e2, 0x2004,
-+	0x70e2, 0x080c, 0x3281, 0x1188, 0x2001, 0x111e, 0x2004, 0x2009,
-+	0x111d, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d,
-+	0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002,
-+	0x702e, 0x2009, 0x1116, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166,
-+	0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078,
-+	0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa,
-+	0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af,
-+	0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x080c,
-+	0x3634, 0x00f6, 0x2071, 0x1347, 0x2079, 0x0320, 0x00d6, 0x2069,
-+	0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a,
-+	0x00de, 0x2011, 0x0011, 0x080c, 0x360c, 0x2011, 0x0001, 0x080c,
-+	0x360c, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1347,
-+	0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x3609, 0x782b, 0x0002,
-+	0x9026, 0xd19c, 0x1904, 0x3605, 0x7000, 0x0002, 0x3609, 0x35ba,
-+	0x35ea, 0x3605, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
-+	0x2011, 0x0001, 0x080c, 0x360c, 0x0904, 0x3609, 0x080c, 0x360c,
-+	0x0804, 0x3609, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
-+	0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
-+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x3520, 0x2009, 0x0001, 0x00f6,
-+	0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011,
-+	0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c,
-+	0xd0fc, 0x1904, 0x35ae, 0x2011, 0x0001, 0x00b1, 0x0090, 0x6010,
-+	0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0x6000, 0x605a, 0x2011,
-+	0x0031, 0x6212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003,
-+	0x0000, 0x00ee, 0x00fe, 0x0005, 0x6014, 0x9005, 0x0520, 0x8001,
-+	0x6016, 0x6058, 0x6110, 0x9140, 0x2804, 0x7802, 0x8840, 0x2804,
-+	0x7806, 0x8840, 0x2804, 0x7812, 0x8840, 0x2804, 0x7816, 0x8840,
-+	0x7a2a, 0x7000, 0x8000, 0x7002, 0x6058, 0x9802, 0x908a, 0x0029,
-+	0x1138, 0x6058, 0x9080, 0x0001, 0x2004, 0x605a, 0x2001, 0x0019,
-+	0x6012, 0x9085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2071,
-+	0x134a, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01f0, 0x782b, 0x0002,
-+	0x2d60, 0x9026, 0x7000, 0x0002, 0x365c, 0x3647, 0x3653, 0x8001,
-+	0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c, 0x360c, 0x0160,
-+	0x080c, 0x360c, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d30,
-+	0x2011, 0x0001, 0x080c, 0x360c, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-+	0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x12e2, 0x2004,
-+	0x601a, 0x2061, 0x0100, 0x2001, 0x12e1, 0x2004, 0x60ce, 0x6104,
-+	0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x01f8, 0x2038,
-+	0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x3eb9,
-+	0x6813, 0x0019, 0x6f16, 0x2d00, 0x685a, 0x978a, 0x0007, 0x0220,
-+	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x6858, 0x9080,
-+	0x0019, 0x04c1, 0x1d90, 0x2d00, 0x685a, 0x0088, 0x080c, 0x3eb9,
-+	0x6813, 0x0019, 0x2070, 0x6817, 0x0001, 0x2d00, 0x685a, 0x2001,
-+	0x002e, 0x2004, 0x2072, 0x2001, 0x002f, 0x2004, 0x7006, 0x2061,
-+	0x0090, 0x2079, 0x0100, 0x2001, 0x12e1, 0x2004, 0x6036, 0x2009,
-+	0x0040, 0x080c, 0x1b67, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-+	0x700a, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x700e, 0x601e,
-+	0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee,
-+	0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0x20e9, 0x0001, 0x20a0,
-+	0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306,
-+	0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112,
-+	0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b,
-+	0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0180, 0x00c6, 0x00d6,
-+	0x2d60, 0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x6058, 0x2070, 0x2d00,
-+	0x7006, 0x605a, 0x00de, 0x00ce, 0x9085, 0x0001, 0x00ee, 0x0005,
-+	0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0508, 0x2038, 0x2001,
-+	0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x3eb9, 0x2d60,
-+	0x6813, 0x0019, 0x6f16, 0x2d00, 0x685a, 0x978a, 0x0007, 0x0220,
-+	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x6858, 0x9080,
-+	0x0019, 0x080c, 0x36ca, 0x1d88, 0x2d00, 0x685a, 0x00e0, 0x080c,
-+	0x3eb9, 0x2d60, 0x6013, 0x0019, 0x2070, 0x6017, 0x0001, 0x2c00,
-+	0x605a, 0x2001, 0x0030, 0x2004, 0x2072, 0x2001, 0x0031, 0x2004,
-+	0x7006, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x700a, 0x2001,
-+	0x002b, 0x2004, 0x700e, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884,
-+	0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102,
-+	0x6017, 0x0000, 0x2001, 0x1347, 0x2003, 0x0003, 0x2001, 0x032a,
-+	0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d,
-+	0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102,
-+	0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0012, 0x2001,
-+	0x1140, 0x20e9, 0x0001, 0x20a0, 0x9006, 0x4004, 0x2009, 0x013c,
-+	0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, 0x0804,
-+	0x2b68, 0x7d98, 0x7c9c, 0x0804, 0x2c5d, 0x080c, 0x62e4, 0x0110,
-+	0x080c, 0x50b9, 0x2069, 0x1152, 0x2d00, 0x2009, 0x0030, 0x7a8c,
-+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x3f0c, 0x701b,
-+	0x379a, 0x0005, 0x2001, 0x110d, 0x2004, 0xd0b4, 0x1130, 0x3b00,
-+	0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, 0x1152, 0x6800,
-+	0x9005, 0x0904, 0x2b9b, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904,
-+	0x2b9b, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200,
-+	0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020,
-+	0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118,
-+	0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084,
-+	0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x2b9b, 0x9288, 0x298c,
-+	0x210d, 0x918c, 0x00ff, 0x615e, 0xd0dc, 0x0130, 0x6828, 0x908a,
-+	0x007f, 0x1a04, 0x2b9b, 0x6056, 0x6888, 0x9084, 0x0030, 0x8004,
-+	0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x12e8, 0x9080, 0x2081,
-+	0x2005, 0x200a, 0x000e, 0x2009, 0x12e9, 0x9080, 0x2085, 0x2005,
-+	0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x2b9b, 0x908a, 0x0841,
-+	0x1a04, 0x2b9b, 0x9084, 0x0007, 0x1904, 0x2b9b, 0x680c, 0x9005,
-+	0x0904, 0x2b9b, 0x6810, 0x9005, 0x0904, 0x2b9b, 0x6848, 0x6940,
-+	0x910a, 0x1a04, 0x2b9b, 0x8001, 0x0904, 0x2b9b, 0x684c, 0x6944,
-+	0x910a, 0x1a04, 0x2b9b, 0x8001, 0x0904, 0x2b9b, 0x6980, 0xd1e4,
-+	0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0x9085, 0x0100, 0x6006,
-+	0x00ce, 0x2009, 0x12bb, 0x200b, 0x0000, 0x2001, 0x1174, 0x2004,
-+	0xd0c4, 0x0140, 0x7884, 0x200a, 0x2009, 0x017f, 0x200a, 0x3b00,
-+	0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x6146, 0x8007, 0x9084,
-+	0x00ff, 0x604a, 0x080c, 0x65bd, 0x080c, 0x58f4, 0x080c, 0x5946,
-+	0x6808, 0x602a, 0x080c, 0x1a81, 0x2009, 0x0170, 0x200b, 0x0080,
-+	0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x1fe8,
-+	0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x393a, 0x6818, 0x691c,
-+	0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
-+	0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
-+	0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff,
-+	0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
-+	0x20a9, 0x0004, 0x20a1, 0x12ea, 0x20e9, 0x0001, 0x4001, 0x080c,
-+	0x72cb, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510,
-+	0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d,
-+	0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x6b21,
-+	0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a,
-+	0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010,
-+	0x6003, 0x0001, 0x1f04, 0x3891, 0x00ce, 0x00c6, 0x2061, 0x12d6,
-+	0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063,
-+	0x0000, 0x2001, 0x0001, 0x080c, 0x2290, 0x2001, 0x0001, 0x080c,
-+	0x2273, 0x0090, 0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006,
-+	0x080c, 0x2290, 0x9006, 0x080c, 0x2273, 0x0030, 0x9286, 0x8000,
-+	0x1d30, 0x2063, 0x0002, 0x0c98, 0x00ce, 0x6888, 0xd0ec, 0x0130,
-+	0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284,
-+	0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020,
-+	0x6a82, 0x2001, 0x12a7, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000,
-+	0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003,
-+	0xaaaa, 0x080c, 0x205d, 0x2001, 0x1298, 0x2102, 0x0008, 0x2102,
-+	0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce,
-+	0x080c, 0x62e4, 0x0128, 0x080c, 0x41f5, 0x0110, 0x080c, 0x1fad,
-+	0x60d0, 0x9005, 0x01d0, 0x6003, 0x0001, 0x2009, 0x3920, 0x00e0,
-+	0x080c, 0x62e4, 0x1178, 0x2011, 0x61aa, 0x080c, 0x71fa, 0x2011,
-+	0x619d, 0x080c, 0x72bf, 0x2001, 0x12a8, 0x2003, 0x0000, 0x080c,
-+	0x621a, 0x0040, 0x080c, 0x4faa, 0x0028, 0x6003, 0x0004, 0x2009,
-+	0x393a, 0x0010, 0x0804, 0x2b68, 0x2001, 0x0170, 0x2004, 0x9084,
-+	0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091,
-+	0x303d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x2b98, 0x2069,
-+	0x1152, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030,
-+	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x3f0f,
-+	0x9006, 0x080c, 0x1fad, 0x81ff, 0x1904, 0x2b98, 0x080c, 0x62e4,
-+	0x1188, 0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003,
-+	0x0001, 0x080c, 0x2987, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c,
-+	0x621a, 0x0020, 0x080c, 0x50b9, 0x080c, 0x4faa, 0x0804, 0x2b68,
-+	0x81ff, 0x1904, 0x2b98, 0x080c, 0x62e4, 0x1110, 0x0804, 0x2b98,
-+	0x618c, 0x81ff, 0x01a8, 0x7047, 0x0000, 0x2001, 0x1580, 0x2009,
-+	0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091, 0x8000,
-+	0x2039, 0x0001, 0x080c, 0x3f0f, 0x701b, 0x2b66, 0x012e, 0x0005,
-+	0x7047, 0x0001, 0x00d6, 0x2069, 0x1580, 0x20a9, 0x0040, 0x20e9,
-+	0x0001, 0x20a1, 0x1580, 0x2019, 0xffff, 0x4304, 0x6554, 0x9588,
-+	0x298c, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002,
-+	0x2100, 0x9506, 0x01a8, 0x080c, 0x5608, 0x1190, 0x6014, 0x821c,
-+	0x0238, 0x9398, 0x1580, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038,
-+	0x9398, 0x1580, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210,
-+	0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c,
-+	0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1580, 0x2099,
-+	0x1580, 0x080c, 0x504f, 0x0804, 0x398d, 0x080c, 0x3ef0, 0x0904,
-+	0x2b9b, 0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x1120, 0x2009, 0x0002,
-+	0x0804, 0x2b98, 0x2001, 0x1153, 0x2004, 0xd0b4, 0x0568, 0x7884,
-+	0x9084, 0xff00, 0x908e, 0x7e00, 0x0538, 0x908e, 0x7f00, 0x0520,
-+	0x908e, 0x8000, 0x0508, 0x080c, 0x2982, 0x1148, 0x6000, 0xd08c,
-+	0x11d8, 0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0x6867,
-+	0x0000, 0x6868, 0xc0fd, 0x686a, 0x080c, 0xaabe, 0x1120, 0x2009,
-+	0x0003, 0x0804, 0x2b98, 0x7007, 0x0003, 0x701b, 0x3a20, 0x0005,
-+	0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x20a9, 0x002b, 0x20e1, 0x0001,
-+	0x2c98, 0x9de8, 0x0002, 0x20e9, 0x0001, 0x2da0, 0x4003, 0x20a9,
-+	0x0004, 0x9d80, 0x0006, 0x20a0, 0x9c80, 0x0006, 0x2098, 0x080c,
-+	0x504f, 0x20a9, 0x0004, 0x9d80, 0x000a, 0x20a0, 0x9c80, 0x000a,
-+	0x2098, 0x080c, 0x504f, 0x2d00, 0x2039, 0x0001, 0x2009, 0x002b,
-+	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x3f0f, 0x81ff, 0x1904,
-+	0x2b98, 0x080c, 0x3ece, 0x0904, 0x2b9b, 0x080c, 0x5767, 0x0804,
-+	0x2b68, 0x81ff, 0x1904, 0x2b98, 0x7888, 0x908a, 0x1000, 0x1a04,
-+	0x2b9b, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x080c, 0x57a6, 0x0904,
-+	0x2b98, 0x2019, 0x0004, 0x900e, 0x080c, 0x5779, 0x7984, 0x810f,
-+	0x7a88, 0x0491, 0x0804, 0x2b68, 0x00f6, 0x2d78, 0x789c, 0x908a,
-+	0x1000, 0x12c0, 0x080c, 0x3eee, 0x01a8, 0x080c, 0x57a6, 0x2009,
-+	0x0002, 0x0160, 0x2019, 0x0004, 0x080c, 0x5779, 0x2009, 0x0003,
-+	0x0128, 0x7998, 0x7a9c, 0x810f, 0x00b9, 0x0070, 0x7897, 0x4005,
-+	0x799a, 0x0010, 0x7897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-+	0x0030, 0x2f68, 0x00fe, 0x0005, 0x7897, 0x4000, 0x900e, 0x9085,
-+	0x0001, 0x2f68, 0x00fe, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071,
-+	0x0060, 0x2029, 0x007e, 0x2061, 0x1100, 0x6454, 0x2400, 0x9506,
-+	0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x5608,
-+	0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x7206,
-+	0x0005, 0x81ff, 0x1904, 0x2b98, 0x080c, 0x3ece, 0x0904, 0x2b9b,
-+	0x080c, 0x56ca, 0x0904, 0x2b98, 0x080c, 0x5770, 0x0804, 0x2b68,
-+	0x81ff, 0x1904, 0x2b98, 0x080c, 0x3ece, 0x0904, 0x2b9b, 0x080c,
-+	0x56ca, 0x0904, 0x2b98, 0x080c, 0x575e, 0x0804, 0x2b68, 0x6100,
-+	0x0804, 0x2b68, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x2001, 0x1100,
-+	0x2004, 0x9086, 0x0003, 0x1904, 0x2b98, 0x00d6, 0x9ce8, 0x000a,
-+	0x7984, 0xd184, 0x0110, 0x9ce8, 0x0006, 0x680c, 0x8007, 0x789e,
-+	0x6808, 0x8007, 0x789a, 0x6b04, 0x831f, 0x6a00, 0x8217, 0x00de,
-+	0x6100, 0x918c, 0x0200, 0x0804, 0x2b68, 0x7884, 0x909c, 0x007f,
-+	0x939a, 0x0003, 0x1a04, 0x2b98, 0x6254, 0x9294, 0x00ff, 0x9084,
-+	0xff00, 0x8007, 0x9206, 0x1560, 0x2031, 0x1148, 0x2009, 0x013c,
-+	0x2136, 0x2001, 0x1140, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
-+	0x7d98, 0x2039, 0x0001, 0x0006, 0x7884, 0x9084, 0x0080, 0x1118,
-+	0x000e, 0x0804, 0x3f0f, 0x000e, 0x2031, 0x0000, 0x2061, 0x11ea,
-+	0x6606, 0x6116, 0x670e, 0x6012, 0x622a, 0x632e, 0x6432, 0x6536,
-+	0x2c10, 0x080c, 0x0f22, 0x7007, 0x0002, 0x701b, 0x3b62, 0x0005,
-+	0x81ff, 0x1904, 0x2b98, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x6004,
-+	0x9084, 0x00ff, 0x9086, 0x0006, 0x1904, 0x2b98, 0x00c6, 0x080c,
-+	0x3eb9, 0x00ce, 0x0904, 0x2b98, 0x6867, 0x0000, 0x6868, 0xc0fd,
-+	0x686a, 0x080c, 0xaa65, 0x0904, 0x2b98, 0x7007, 0x0003, 0x701b,
-+	0x3b66, 0x0005, 0x080c, 0x376a, 0x0804, 0x2b68, 0x6830, 0x9086,
-+	0x0100, 0x0904, 0x2b98, 0x9d80, 0x001b, 0x2009, 0x000c, 0x7a8c,
-+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x3f0f, 0x9006,
-+	0x080c, 0x1fad, 0x7884, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118,
-+	0x81ff, 0x1904, 0x2b98, 0x080c, 0x62e4, 0x0110, 0x080c, 0x50b9,
-+	0x7888, 0x908a, 0x1000, 0x1a04, 0x2b9b, 0x7984, 0x918c, 0xff00,
-+	0x810f, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x2b9b,
-+	0x2100, 0x080c, 0x1f77, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
-+	0x2061, 0x1317, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c, 0x62e4,
-+	0x1178, 0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003,
-+	0x0001, 0x9085, 0x0001, 0x080c, 0x6331, 0x080c, 0x621a, 0x0438,
-+	0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec,
-+	0x080c, 0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e, 0x2061,
-+	0x0100, 0x2001, 0x1116, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105,
-+	0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x12d3, 0x200b,
-+	0x0000, 0x2009, 0x002d, 0x2011, 0x4fe1, 0x080c, 0x7283, 0x7984,
-+	0x918c, 0xff00, 0x810f, 0x080c, 0x62e4, 0x1110, 0x2009, 0x00ff,
-+	0x7a88, 0x080c, 0x3aa4, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2b68,
-+	0x7984, 0x918c, 0xff00, 0x810f, 0x00c6, 0x080c, 0x55b3, 0x2c08,
-+	0x00ce, 0x1904, 0x2b9b, 0x0804, 0x2b68, 0x81ff, 0x0120, 0x2009,
-+	0x0001, 0x0804, 0x2b98, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120,
-+	0x2009, 0x0005, 0x0804, 0x2b98, 0x080c, 0x3eb9, 0x1120, 0x2009,
-+	0x0002, 0x0804, 0x2b98, 0x7984, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-+	0x2039, 0x0001, 0x080c, 0x3f0c, 0x701b, 0x3c1f, 0x0005, 0x2009,
-+	0x0080, 0x080c, 0x5608, 0x1130, 0x6004, 0x9084, 0x00ff, 0x9086,
-+	0x0006, 0x0120, 0x2021, 0x400a, 0x0804, 0x2b6a, 0x00d6, 0x9de8,
-+	0x0019, 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820,
-+	0x90be, 0x0100, 0x0904, 0x3c99, 0x90be, 0x0112, 0x0904, 0x3c99,
-+	0x90be, 0x0113, 0x0904, 0x3c99, 0x90be, 0x0114, 0x0904, 0x3c99,
-+	0x90be, 0x0117, 0x0904, 0x3c99, 0x90be, 0x011a, 0x0904, 0x3c99,
-+	0x90be, 0x011c, 0x0904, 0x3c99, 0x90be, 0x0121, 0x05c8, 0x90be,
-+	0x0131, 0x05b0, 0x90be, 0x0171, 0x05e0, 0x90be, 0x0173, 0x05c8,
-+	0x90be, 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832, 0x04b8, 0x90be,
-+	0x0212, 0x0558, 0x90be, 0x0213, 0x0540, 0x90be, 0x0214, 0x01c8,
-+	0x90be, 0x0217, 0x0180, 0x90be, 0x021a, 0x1120, 0x6838, 0x8007,
-+	0x683a, 0x00f8, 0x90be, 0x021f, 0x01e0, 0x90be, 0x0300, 0x01c8,
-+	0x00de, 0x0804, 0x2b9b, 0x9d80, 0x0010, 0x20a9, 0x0007, 0x080c,
-+	0x3cda, 0x9d80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3cda, 0x0048,
-+	0x9d80, 0x000c, 0x080c, 0x3ce8, 0x0048, 0x9d80, 0x000e, 0x080c,
-+	0x3ce8, 0x9d80, 0x000c, 0x20a9, 0x0001, 0x04e1, 0x00c6, 0x080c,
-+	0x3eb9, 0x0548, 0x6868, 0xc0fd, 0x686a, 0x6867, 0x0119, 0x9006,
-+	0x6882, 0x687f, 0x0020, 0x688b, 0x0001, 0x810b, 0x69ae, 0x68b2,
-+	0x6ab6, 0x6bba, 0x6cbe, 0x6dc2, 0x69c6, 0x68ca, 0x00ce, 0x00de,
-+	0x6866, 0x6822, 0x6868, 0xc0fd, 0x686a, 0x6804, 0x2068, 0x080c,
-+	0xaa81, 0x1120, 0x2009, 0x0003, 0x0804, 0x2b98, 0x7007, 0x0003,
-+	0x701b, 0x3cd1, 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804,
-+	0x2b98, 0x6820, 0x9086, 0x8001, 0x1904, 0x2b68, 0x2009, 0x0004,
-+	0x0804, 0x2b98, 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000,
-+	0x290a, 0x8108, 0x280a, 0x8108, 0x1f04, 0x3cdc, 0x001e, 0x0005,
-+	0x0016, 0x00a6, 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000,
-+	0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a,
-+	0x8108, 0x280a, 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120,
-+	0x2009, 0x0001, 0x0804, 0x2b98, 0x60d8, 0xd0ac, 0x1130, 0xd09c,
-+	0x1120, 0x2009, 0x0005, 0x0804, 0x2b98, 0x7984, 0x2140, 0x918c,
-+	0xff00, 0x810f, 0x60d8, 0xd0ac, 0x1120, 0x9182, 0x0080, 0x0a04,
-+	0x2b9b, 0x9182, 0x00ff, 0x1a04, 0x2b9b, 0x7a8c, 0x7b88, 0x6074,
-+	0x9306, 0x1140, 0x6078, 0x924e, 0x0904, 0x2b9b, 0x99cc, 0xff00,
-+	0x0904, 0x2b9b, 0x00c6, 0x080c, 0x3dc2, 0x2c68, 0x00ce, 0x0530,
-+	0x90c6, 0x4000, 0x1178, 0x00c6, 0x0006, 0x2d60, 0x900e, 0x080c,
-+	0x57d6, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
-+	0x00ce, 0x0088, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0060, 0x90c6,
-+	0x4008, 0x1118, 0x2708, 0x2610, 0x0030, 0x90c6, 0x4009, 0x1108,
-+	0x0010, 0x2001, 0x4006, 0x2020, 0x0804, 0x2b6a, 0x2d00, 0x7022,
-+	0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8f26, 0x05c0,
-+	0x2d00, 0x6012, 0x080c, 0xad70, 0x2e58, 0x00ee, 0x00e6, 0x00c6,
-+	0x080c, 0x3eb9, 0x00ce, 0x2b70, 0x1150, 0x080c, 0x8ed9, 0x00ee,
-+	0x00ce, 0x00be, 0x001e, 0x2009, 0x0002, 0x0804, 0x2b98, 0x900e,
-+	0x6966, 0x696a, 0x2d00, 0x6016, 0x6932, 0x6868, 0xc0fd, 0xd88c,
-+	0x0108, 0xc0f5, 0x686a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2862,
-+	0x012e, 0x6023, 0x0001, 0x9006, 0x080c, 0x5556, 0x2001, 0x0002,
-+	0x080c, 0x5568, 0x2009, 0x0002, 0x080c, 0x8f53, 0x9085, 0x0001,
-+	0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003, 0x0804,
-+	0x2b98, 0x7007, 0x0003, 0x701b, 0x3da6, 0x0005, 0x6830, 0x9086,
-+	0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204, 0x9294,
-+	0x00ff, 0x0804, 0x47e3, 0x900e, 0x6868, 0xd0f4, 0x1904, 0x2b68,
-+	0x080c, 0x57d6, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d,
-+	0x0804, 0x2b68, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0x1136,
-+	0x2004, 0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071,
-+	0x1000, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0x1080,
-+	0x2e04, 0x9005, 0x1130, 0x2100, 0x9406, 0x1570, 0x2428, 0xc5fd,
-+	0x0458, 0x2068, 0x6f10, 0x2700, 0x9306, 0x11b0, 0x6e14, 0x2600,
-+	0x9206, 0x1190, 0x2400, 0x9106, 0x1160, 0x2d60, 0xd884, 0x0568,
-+	0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1538, 0x2001, 0x4000,
-+	0x0428, 0x2001, 0x4007, 0x0410, 0x2400, 0x9106, 0x1168, 0x6e14,
-+	0x87ff, 0x1138, 0x86ff, 0x09d0, 0x2001, 0x1136, 0x2004, 0xd0ac,
-+	0x19a8, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x3dd8,
-+	0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030,
-+	0x080c, 0x55b3, 0x1dd0, 0x6312, 0x6216, 0x9006, 0x9005, 0x00de,
-+	0x00ee, 0x0005, 0x81ff, 0x1904, 0x2b98, 0x080c, 0x3eb9, 0x0904,
-+	0x2b98, 0x6867, 0x0000, 0x6868, 0xc0fd, 0x686a, 0x7884, 0x9005,
-+	0x0904, 0x2b9b, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04,
-+	0x2b9b, 0x2010, 0x2d18, 0x080c, 0x2811, 0x0904, 0x2b98, 0x7007,
-+	0x0003, 0x701b, 0x3e44, 0x0005, 0x6830, 0x9086, 0x0100, 0x0904,
-+	0x2b98, 0x0804, 0x2b68, 0x7984, 0x918c, 0xff00, 0x810f, 0x60d8,
-+	0xd0ac, 0x1120, 0x9182, 0x0080, 0x0a04, 0x2b9b, 0x9182, 0x00ff,
-+	0x1a04, 0x2b9b, 0x0126, 0x2091, 0x8000, 0x080c, 0xa972, 0x1188,
-+	0x9190, 0x1000, 0x2204, 0x9065, 0x0160, 0x080c, 0x5100, 0x2001,
-+	0x1136, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e, 0x0804,
-+	0x2b68, 0x012e, 0x0804, 0x2b98, 0x00f6, 0x2d78, 0x7998, 0x918c,
-+	0xff00, 0x810f, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x1118, 0x9182,
-+	0x0080, 0x02e8, 0x9182, 0x00ff, 0x12d0, 0x0126, 0x2091, 0x8000,
-+	0x080c, 0xa972, 0x1530, 0x9190, 0x1000, 0x2204, 0x9065, 0x0528,
-+	0x080c, 0x5100, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x0110, 0x6017,
-+	0x0000, 0x012e, 0x0070, 0x7897, 0x4005, 0x799a, 0x0010, 0x7897,
-+	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2f68, 0x00fe,
-+	0x0005, 0x7897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2f68, 0x00fe,
-+	0x0005, 0x012e, 0x2009, 0x0003, 0x0c30, 0x012e, 0x2009, 0x000a,
-+	0x0c10, 0x080c, 0x0eb6, 0x0188, 0x9006, 0x6802, 0x7010, 0x9005,
-+	0x1120, 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014, 0x6802, 0x2060,
-+	0x2d00, 0x6006, 0x7016, 0x9d80, 0x0019, 0x0005, 0x7984, 0x810f,
-+	0x918c, 0x00ff, 0x080c, 0x5608, 0x1130, 0x7e88, 0x9684, 0x3fff,
-+	0x9082, 0x4000, 0x0208, 0x9066, 0x8cff, 0x0005, 0x7998, 0x810f,
-+	0x918c, 0x00ff, 0x080c, 0x5608, 0x1130, 0x7e9c, 0x9684, 0x3fff,
-+	0x9082, 0x4000, 0x0208, 0x9066, 0x8cff, 0x0005, 0x7e98, 0x0008,
-+	0x7e84, 0x860f, 0x918c, 0x00ff, 0x080c, 0x5608, 0x1128, 0x96b4,
-+	0x00ff, 0x9682, 0x4000, 0x0208, 0x9066, 0x8cff, 0x0005, 0x0016,
-+	0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c, 0x0ecf, 0x0cc8,
-+	0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031,
-+	0x0000, 0x2061, 0x11ea, 0x6606, 0x6116, 0x670e, 0x6012, 0x622a,
-+	0x632e, 0x6432, 0x6536, 0x2c10, 0x080c, 0x0f22, 0x7007, 0x0002,
-+	0x701b, 0x2b68, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079,
-+	0x0000, 0x2001, 0x11a3, 0x2004, 0x9005, 0x1190, 0x0e04, 0x3f40,
-+	0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080,
-+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd, 0x0804, 0x3f9d,
-+	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0x1193, 0x703c, 0x9005,
-+	0x1540, 0x7140, 0x9182, 0x0010, 0x0288, 0x7030, 0x2060, 0x080c,
-+	0x0eb6, 0x0904, 0x3f96, 0x684b, 0x0000, 0x2d00, 0x703e, 0x2001,
-+	0x0002, 0x9080, 0x18fe, 0x2005, 0x6846, 0x0098, 0x7030, 0x90e0,
-+	0x0004, 0x2001, 0x11aa, 0x9c82, 0x11ea, 0x0210, 0x2061, 0x11aa,
-+	0x2c00, 0x7032, 0x7140, 0x81ff, 0x1108, 0x7036, 0x8108, 0x7142,
-+	0x0428, 0x7140, 0x8108, 0x7142, 0x703c, 0x2078, 0x7944, 0x2105,
-+	0x9f60, 0x8108, 0x2105, 0x9005, 0x7946, 0x11c0, 0x080c, 0x0eb6,
-+	0x1130, 0x8109, 0x7946, 0x7140, 0x8109, 0x7142, 0x0078, 0x9006,
-+	0x6806, 0x684a, 0x7846, 0x2f00, 0x6802, 0x2d00, 0x7806, 0x703e,
-+	0x2001, 0x0002, 0x9080, 0x18fe, 0x2005, 0x6846, 0x2262, 0x6306,
-+	0x640a, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x012e, 0x00fe, 0x0005,
-+	0x00e6, 0x2071, 0x1193, 0x7040, 0x9005, 0x0904, 0x4024, 0x0126,
-+	0x2091, 0x8000, 0x0e04, 0x4023, 0x00f6, 0x2079, 0x0000, 0x00c6,
-+	0x00d6, 0x0086, 0x9006, 0x2040, 0x7038, 0x2068, 0x9005, 0x01c0,
-+	0x6948, 0x2105, 0x9d60, 0x8108, 0x2105, 0x9005, 0x694a, 0x1190,
-+	0x6804, 0x9005, 0x090c, 0x0d7e, 0x703a, 0x2d40, 0x2068, 0x6803,
-+	0x0000, 0x2001, 0x0002, 0x9080, 0x18fe, 0x2005, 0x684a, 0x0010,
-+	0x7034, 0x2060, 0x2c04, 0x7836, 0x7833, 0x0012, 0x7882, 0x6004,
-+	0x7886, 0x6008, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-+	0xd084, 0x190c, 0x0fcd, 0x88ff, 0x0118, 0x2868, 0x080c, 0x0ecf,
-+	0x7040, 0x8001, 0x7042, 0x9005, 0x1170, 0x7038, 0x2068, 0x9005,
-+	0x0128, 0x080c, 0x0ecf, 0x9006, 0x703a, 0x703e, 0x7033, 0x11aa,
-+	0x7037, 0x11aa, 0x0420, 0x7038, 0x9005, 0x1508, 0x7230, 0x2c00,
-+	0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x11ea, 0x0210, 0x2001,
-+	0x11aa, 0x7036, 0x00a0, 0x9006, 0x7036, 0x7032, 0x703c, 0x9005,
-+	0x090c, 0x0d7e, 0x2068, 0x6800, 0x9005, 0x1de0, 0x2d00, 0x703a,
-+	0x2001, 0x0002, 0x9080, 0x18fe, 0x2005, 0x684a, 0x0000, 0x008e,
-+	0x00de, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
-+	0x1153, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3f23,
-+	0x002e, 0x0005, 0x81ff, 0x1904, 0x2b98, 0x0126, 0x2091, 0x8000,
-+	0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x62e4, 0x1178,
-+	0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003, 0x0001,
-+	0x9085, 0x0001, 0x080c, 0x6331, 0x080c, 0x621a, 0x0010, 0x080c,
-+	0x4faa, 0x012e, 0x0804, 0x2b68, 0x7884, 0x2008, 0x918c, 0xfffd,
-+	0x1128, 0x61e4, 0x910d, 0x61e6, 0x0804, 0x2b68, 0x0804, 0x2b9b,
-+	0x81ff, 0x1904, 0x2b98, 0x6000, 0x9086, 0x0003, 0x1904, 0x2b98,
-+	0x080c, 0x58c6, 0x1904, 0x2b98, 0x080c, 0x3ef0, 0x0904, 0x2b9b,
-+	0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1120, 0x7888, 0x9005,
-+	0x0904, 0x2b68, 0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x0904, 0x2b98,
-+	0x9006, 0x6866, 0x6832, 0x6868, 0xc0fd, 0x686a, 0x080c, 0xab41,
-+	0x0904, 0x2b98, 0x7007, 0x0003, 0x701b, 0x40ce, 0x0005, 0x00f6,
-+	0x2d78, 0x2061, 0x1100, 0x6000, 0x9086, 0x0003, 0x2009, 0x0007,
-+	0x11d0, 0x080c, 0x58c6, 0x2009, 0x0008, 0x11a8, 0x080c, 0x3eee,
-+	0x01b0, 0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0x789c,
-+	0x9005, 0x01b8, 0x2f68, 0x6868, 0xc0fc, 0x686a, 0x080c, 0xab41,
-+	0x11c8, 0x2009, 0x0003, 0x7897, 0x4005, 0x799a, 0x0010, 0x7897,
-+	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x2f68, 0x00fe,
-+	0x0005, 0x7897, 0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2f68,
-+	0x00fe, 0x0005, 0x9006, 0x2f68, 0x00fe, 0x0005, 0x6830, 0x9086,
-+	0x0100, 0x1904, 0x2b68, 0x0804, 0x47e3, 0x2001, 0x1100, 0x2004,
-+	0x9086, 0x0003, 0x1904, 0x2b98, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c,
-+	0x7d98, 0x080c, 0x3eb9, 0x0904, 0x2b98, 0x900e, 0x2130, 0x7122,
-+	0x712e, 0x9d80, 0x0005, 0x7026, 0x20a0, 0x20e1, 0x0001, 0x20e9,
-+	0x0001, 0x080c, 0x5608, 0x1904, 0x4149, 0x6004, 0x90c4, 0x00ff,
-+	0x98c6, 0x0006, 0x0130, 0x90c4, 0xff00, 0x98c6, 0x0600, 0x1904,
-+	0x4149, 0x080c, 0x58c6, 0x1130, 0x080c, 0x57d6, 0x1118, 0xd79c,
-+	0x0904, 0x4149, 0xd794, 0x1110, 0xd784, 0x0158, 0x9c80, 0x0006,
-+	0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, 0x080c, 0x3ce8, 0xd794,
-+	0x0148, 0x9c80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003,
-+	0x080c, 0x3ce8, 0x21a2, 0x3400, 0x8000, 0x20a0, 0xd794, 0x01d8,
-+	0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003,
-+	0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400,
-+	0x20a9, 0x0002, 0x4003, 0x080c, 0x3cda, 0x9c80, 0x0026, 0x2098,
-+	0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0,
-+	0x0005, 0x8108, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x0118, 0x9186,
-+	0x0100, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0100, 0x0170, 0x0018,
-+	0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010,
-+	0x9686, 0x0028, 0x0150, 0x0804, 0x40ed, 0x86ff, 0x1120, 0x7120,
-+	0x810b, 0x0804, 0x2b68, 0x702f, 0x0001, 0x711e, 0x7020, 0x9600,
-+	0x7022, 0x772a, 0x2061, 0x11ea, 0x6007, 0x0000, 0x6616, 0x7024,
-+	0x600f, 0x0001, 0x6012, 0x622a, 0x632e, 0x6432, 0x6536, 0x2c10,
-+	0x080c, 0x0f22, 0x7007, 0x0002, 0x701b, 0x4187, 0x0005, 0x702c,
-+	0x9005, 0x1168, 0x711c, 0x7024, 0x20a0, 0x7728, 0x9036, 0x2061,
-+	0x11ea, 0x6228, 0x632c, 0x6430, 0x6534, 0x0804, 0x40ed, 0x7120,
-+	0x810b, 0x0804, 0x2b68, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c,
-+	0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x2b9b,
-+	0x9502, 0x0a04, 0x2b9b, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-+	0x2b9b, 0x9502, 0x0a04, 0x2b9b, 0x9284, 0xff00, 0x8007, 0x90e2,
-+	0x0020, 0x0a04, 0x2b9b, 0x9502, 0x0a04, 0x2b9b, 0x9284, 0x00ff,
-+	0x90e2, 0x0020, 0x0a04, 0x2b9b, 0x9502, 0x0a04, 0x2b9b, 0x9384,
-+	0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x2b9b, 0x9502, 0x0a04,
-+	0x2b9b, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x2b9b, 0x9502,
-+	0x0a04, 0x2b9b, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04,
-+	0x2b9b, 0x9502, 0x0a04, 0x2b9b, 0x9484, 0x00ff, 0x90e2, 0x0020,
-+	0x0a04, 0x2b9b, 0x9502, 0x0a04, 0x2b9b, 0x2061, 0x12c3, 0x6102,
-+	0x6206, 0x630a, 0x640e, 0x0804, 0x2b68, 0x0006, 0x2001, 0x1153,
-+	0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, 0x1172, 0x2004,
-+	0xd0bc, 0x000e, 0x0005, 0x616c, 0x7a84, 0x6300, 0x82ff, 0x1118,
-+	0x7986, 0x0804, 0x2b68, 0x83ff, 0x1904, 0x2b9b, 0x2001, 0xfff0,
-+	0x9200, 0x1a04, 0x2b9b, 0x2019, 0xffff, 0x6070, 0x9302, 0x9200,
-+	0x0a04, 0x2b9b, 0x7986, 0x626e, 0x0804, 0x2b68, 0x2001, 0x1100,
-+	0x2004, 0x9086, 0x0003, 0x1904, 0x2b98, 0x7c88, 0x7d84, 0x7e98,
-+	0x7f8c, 0x080c, 0x3eb9, 0x0904, 0x2b98, 0x900e, 0x901e, 0x7322,
-+	0x732e, 0x9d80, 0x0003, 0x7026, 0x20a0, 0x91e0, 0x1000, 0x2c64,
-+	0x8cff, 0x01d8, 0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0130,
-+	0x6004, 0x9084, 0xff00, 0x9086, 0x0600, 0x1178, 0x00d6, 0x3468,
-+	0x6014, 0x206a, 0x8d68, 0x6010, 0x8007, 0x9105, 0x8007, 0x206a,
-+	0x8d68, 0x2da0, 0x00de, 0x9398, 0x0002, 0x8108, 0x9182, 0x00ff,
-+	0x0120, 0x9386, 0x002a, 0x0148, 0x08c0, 0x83ff, 0x1120, 0x7120,
-+	0x810c, 0x0804, 0x2b68, 0x702f, 0x0001, 0x711e, 0x7020, 0x9300,
-+	0x7022, 0x2061, 0x11ea, 0x6007, 0x0000, 0x6316, 0x7024, 0x6012,
-+	0x600f, 0x0001, 0x642a, 0x652e, 0x6632, 0x6736, 0x2c10, 0x080c,
-+	0x0f22, 0x7007, 0x0002, 0x701b, 0x427e, 0x0005, 0x702c, 0x9005,
-+	0x1160, 0x711c, 0x7024, 0x20a0, 0x901e, 0x2061, 0x11ea, 0x6428,
-+	0x652c, 0x6630, 0x6734, 0x0804, 0x4235, 0x7120, 0x810c, 0x0804,
-+	0x2b68, 0x00f6, 0x2d78, 0x00e6, 0x2001, 0x1100, 0x2004, 0x9086,
-+	0x0003, 0x2009, 0x0007, 0x1904, 0x4311, 0x2071, 0x1193, 0x7454,
-+	0x84ff, 0x2009, 0x000e, 0x1904, 0x4311, 0x7c9c, 0x7d98, 0x7ea4,
-+	0x7fa0, 0x080c, 0x0e9d, 0x2009, 0x0002, 0x0904, 0x4311, 0x2d00,
-+	0x7056, 0x900e, 0x901e, 0x734e, 0x735a, 0x9d80, 0x0003, 0x7052,
-+	0x20a0, 0x91e0, 0x1000, 0x2c64, 0x8cff, 0x01d8, 0x6004, 0x9084,
-+	0x00ff, 0x9086, 0x0006, 0x0130, 0x6004, 0x9084, 0xff00, 0x9086,
-+	0x0600, 0x1178, 0x00d6, 0x3468, 0x6014, 0x206a, 0x8d68, 0x6010,
-+	0x8007, 0x9105, 0x8007, 0x206a, 0x8d68, 0x2da0, 0x00de, 0x9398,
-+	0x0002, 0x8108, 0x9182, 0x00ff, 0x0120, 0x9386, 0x002a, 0x01b8,
-+	0x08c0, 0x83ff, 0x1190, 0x714c, 0x810c, 0x7897, 0x4000, 0x799a,
-+	0x7154, 0x81ff, 0x090c, 0x0d7e, 0x2168, 0x080c, 0x0ecf, 0x9006,
-+	0x7056, 0x918d, 0x0001, 0x2008, 0x0420, 0x705b, 0x0001, 0x714a,
-+	0x704c, 0x9300, 0x704e, 0x2061, 0x11fb, 0x6007, 0x0000, 0x6316,
-+	0x7050, 0x6012, 0x600f, 0x0001, 0x642a, 0x652e, 0x6632, 0x6736,
-+	0x603b, 0x431d, 0x2f00, 0x603e, 0x2c10, 0x080c, 0x0f22, 0x9006,
-+	0x0040, 0x7897, 0x4005, 0x799a, 0x900e, 0x9085, 0x0001, 0x2001,
-+	0x0030, 0x00ee, 0x2f68, 0x00fe, 0x0005, 0x00f6, 0x603c, 0x907d,
-+	0x090c, 0x0d7e, 0x00e6, 0x2071, 0x1193, 0x6008, 0x908e, 0x0100,
-+	0x0138, 0x787b, 0x0030, 0x7883, 0x0000, 0x7897, 0x4002, 0x00a8,
-+	0x7058, 0x9005, 0x1148, 0x7148, 0x7050, 0x20a0, 0x901e, 0x6428,
-+	0x652c, 0x6630, 0x6734, 0x0400, 0x787b, 0x0000, 0x7883, 0x0000,
-+	0x7897, 0x4000, 0x714c, 0x810c, 0x799a, 0x7154, 0x81ff, 0x090c,
-+	0x0d7e, 0x2168, 0x080c, 0x0ecf, 0x7057, 0x0000, 0x2f68, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x603b, 0x0000, 0x603f,
-+	0x0000, 0x00ee, 0x00fe, 0x0005, 0x91e0, 0x1000, 0x2c64, 0x8cff,
-+	0x01d8, 0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0130, 0x6004,
-+	0x9084, 0xff00, 0x9086, 0x0600, 0x1178, 0x00d6, 0x3468, 0x6014,
-+	0x206a, 0x8d68, 0x6010, 0x8007, 0x9105, 0x8007, 0x206a, 0x8d68,
-+	0x2da0, 0x00de, 0x9398, 0x0002, 0x8108, 0x9182, 0x00ff, 0x0120,
-+	0x9386, 0x002a, 0x0520, 0x08c0, 0x83ff, 0x11f8, 0x714c, 0x810c,
-+	0x799a, 0x7897, 0x4000, 0x7154, 0x81ff, 0x090c, 0x0d7e, 0x2168,
-+	0x080c, 0x0ecf, 0x9006, 0x7056, 0x918d, 0x0001, 0x2008, 0x2f68,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x2061, 0x11fb,
-+	0x603b, 0x0000, 0x603f, 0x0000, 0x0088, 0x705b, 0x0001, 0x714a,
-+	0x704c, 0x9300, 0x704e, 0x2061, 0x11fb, 0x6316, 0x642a, 0x652e,
-+	0x6632, 0x6736, 0x2c10, 0x080c, 0x0f22, 0x9006, 0x00ee, 0x00fe,
-+	0x0005, 0x81ff, 0x1904, 0x2b98, 0x60d8, 0xd0ac, 0x1118, 0xd09c,
-+	0x0904, 0x2b98, 0x080c, 0x3eb9, 0x0904, 0x2b98, 0x7984, 0x7a8c,
-+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x3f0c, 0x701b,
-+	0x43d2, 0x0005, 0x00d6, 0x9de8, 0x0019, 0x6828, 0x90be, 0x7000,
-+	0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x00de,
-+	0x0804, 0x2b9b, 0x6820, 0x6924, 0x080c, 0x1f63, 0x1510, 0x080c,
-+	0x55b3, 0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c,
-+	0x3eb9, 0x01b8, 0x080c, 0x3eb9, 0x01a0, 0x00ce, 0x00de, 0x6867,
-+	0x0000, 0x6868, 0xc0fd, 0x686a, 0x6823, 0x0000, 0x6804, 0x2068,
-+	0x080c, 0xaaa2, 0x0904, 0x2b98, 0x7007, 0x0003, 0x701b, 0x440c,
-+	0x0005, 0x00de, 0x0804, 0x2b98, 0x7120, 0x080c, 0x2955, 0x6820,
-+	0x9086, 0x8001, 0x0904, 0x2b98, 0x2d00, 0x701e, 0x6804, 0x9080,
-+	0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x504f,
-+	0x000e, 0x9de8, 0x0019, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061,
-+	0x11ea, 0x6007, 0x0000, 0x6e00, 0x6f28, 0x97c6, 0x7000, 0x1108,
-+	0x0018, 0x97c6, 0x7100, 0x1150, 0x96c2, 0x0004, 0x0a04, 0x2b9b,
-+	0x2009, 0x0004, 0x2039, 0x0001, 0x0804, 0x3f0f, 0x97c6, 0x7200,
-+	0x1904, 0x2b9b, 0x96c2, 0x0054, 0x0a04, 0x2b9b, 0x600f, 0x0001,
-+	0x6012, 0x6017, 0x002a, 0x622a, 0x632e, 0x6432, 0x6536, 0x2c10,
-+	0x080c, 0x0f22, 0x7007, 0x0002, 0x701b, 0x4457, 0x0005, 0x701c,
-+	0x2068, 0x6804, 0x9080, 0x0001, 0x2004, 0x9080, 0x0002, 0x0006,
-+	0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x504f, 0x000e, 0x2061,
-+	0x11ea, 0x6228, 0x632c, 0x6430, 0x6534, 0x2039, 0x0001, 0x2009,
-+	0x002a, 0x0804, 0x3f0f, 0x81ff, 0x1904, 0x2b98, 0x798c, 0x2001,
-+	0x12a9, 0x2102, 0x080c, 0x3ece, 0x0904, 0x2b9b, 0x080c, 0x56ca,
-+	0x0904, 0x2b98, 0x0126, 0x2091, 0x8000, 0x080c, 0x5782, 0x012e,
-+	0x0804, 0x2b68, 0x00f6, 0x69a0, 0x2001, 0x12a9, 0x2102, 0x2d78,
-+	0x080c, 0x3ede, 0x0170, 0x080c, 0x56ca, 0x2009, 0x0002, 0x0128,
-+	0x080c, 0x5782, 0x1180, 0x2009, 0x0003, 0x7897, 0x4005, 0x799a,
-+	0x0010, 0x7897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-+	0x2f68, 0x00fe, 0x0005, 0x7897, 0x4000, 0x900e, 0x9085, 0x0001,
-+	0x2001, 0x0000, 0x2f68, 0x00fe, 0x0005, 0x7884, 0xd08c, 0x1118,
-+	0xd084, 0x0904, 0x39e5, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x00c6,
-+	0x080c, 0x3eb9, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x2b98,
-+	0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0128, 0x908e, 0x0004,
-+	0x0110, 0x908e, 0x0005, 0x15b8, 0x7884, 0xd08c, 0x0120, 0x6000,
-+	0xc08c, 0x6002, 0x0030, 0x2001, 0x1153, 0x2004, 0xd0b4, 0x0904,
-+	0x3a24, 0x7884, 0x9084, 0xff00, 0x908e, 0x7e00, 0x0904, 0x3a24,
-+	0x908e, 0x7f00, 0x0904, 0x3a24, 0x908e, 0x8000, 0x0904, 0x3a24,
-+	0x6000, 0xd08c, 0x1904, 0x3a24, 0x6867, 0x0000, 0x6868, 0xc0fd,
-+	0x686a, 0x080c, 0xaabe, 0x1120, 0x2009, 0x0003, 0x0804, 0x2b98,
-+	0x7007, 0x0003, 0x701b, 0x4505, 0x0005, 0x080c, 0x3ef0, 0x0904,
-+	0x2b9b, 0x0804, 0x3a24, 0x080c, 0x2982, 0x0108, 0x0005, 0x2009,
-+	0x1133, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2b98,
-+	0x2001, 0x1100, 0x2004, 0x9086, 0x0003, 0x0120, 0x2009, 0x0007,
-+	0x0804, 0x2b98, 0x080c, 0x58c6, 0x0120, 0x2009, 0x0008, 0x0804,
-+	0x2b98, 0x609c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x3a24, 0x9006,
-+	0x6866, 0x6832, 0x6868, 0xc0fd, 0x686a, 0x080c, 0xab41, 0x1120,
-+	0x2009, 0x0003, 0x0804, 0x2b98, 0x7007, 0x0003, 0x701b, 0x4541,
-+	0x0005, 0x6830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804,
-+	0x47e3, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x0804, 0x44d4, 0x81ff,
-+	0x2009, 0x0001, 0x1904, 0x2b98, 0x6000, 0x9086, 0x0003, 0x2009,
-+	0x0007, 0x1904, 0x2b98, 0x080c, 0x58c6, 0x2009, 0x0008, 0x1904,
-+	0x2b98, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x6004, 0x9084, 0x00ff,
-+	0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2b98, 0x00c6, 0x080c,
-+	0x3eb9, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2b98, 0x9006, 0x6866,
-+	0x6832, 0x6868, 0xc0fd, 0x686a, 0x7988, 0x9194, 0xff00, 0x918c,
-+	0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x798c, 0x6956,
-+	0x0038, 0x928e, 0x0100, 0x1904, 0x2b9b, 0xc0e5, 0x6952, 0x6956,
-+	0x683e, 0x080c, 0xad71, 0x2009, 0x0003, 0x0904, 0x2b98, 0x7007,
-+	0x0003, 0x701b, 0x459c, 0x0005, 0x6830, 0x9086, 0x0100, 0x2009,
-+	0x0004, 0x0904, 0x2b98, 0x0804, 0x2b68, 0x81ff, 0x2009, 0x0001,
-+	0x1904, 0x2b98, 0x6000, 0x9086, 0x0003, 0x2009, 0x0007, 0x1904,
-+	0x2b98, 0x080c, 0x3ef0, 0x0904, 0x2b9b, 0x6004, 0x9084, 0x00ff,
-+	0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2b98, 0x00c6, 0x080c,
-+	0x3eb9, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2b98, 0x9d80, 0x001b,
-+	0x2039, 0x0001, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-+	0x080c, 0x3f0c, 0x701b, 0x45d5, 0x0005, 0x00d6, 0x9de8, 0x001b,
-+	0x6800, 0x9086, 0x0500, 0x1138, 0x6804, 0x9005, 0x1120, 0x6808,
-+	0x9084, 0xff00, 0x0118, 0x00de, 0x1904, 0x2b9b, 0x00de, 0x6866,
-+	0x6832, 0x6868, 0xc0fd, 0x686a, 0x00c6, 0x080c, 0x3ef0, 0x1118,
-+	0x00ce, 0x0804, 0x2b9b, 0x2009, 0x0043, 0x080c, 0xadda, 0x2009,
-+	0x0003, 0x00ce, 0x0904, 0x2b98, 0x7007, 0x0003, 0x701b, 0x4601,
-+	0x0005, 0x6830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x2b98,
-+	0x0804, 0x2b68, 0x00f6, 0x00c6, 0x2d78, 0x2061, 0x1100, 0x6000,
-+	0x9086, 0x0003, 0x2009, 0x0007, 0x1528, 0x080c, 0x3eee, 0x0530,
-+	0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x11d0,
-+	0x9fe8, 0x0031, 0x6800, 0x9086, 0x0500, 0x11c0, 0x6804, 0x9005,
-+	0x11a8, 0x6808, 0x9084, 0xff00, 0x1188, 0x080c, 0x3eee, 0x1108,
-+	0x0068, 0x2f68, 0x2009, 0x004b, 0x080c, 0xadda, 0x2009, 0x0003,
-+	0x0108, 0x0078, 0x7897, 0x4005, 0x799a, 0x0010, 0x7897, 0x4006,
-+	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce, 0x2f68, 0x00fe,
-+	0x0005, 0x9006, 0x0cd0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-+	0x2b98, 0x6000, 0x9086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
-+	0x2b98, 0x7e84, 0x860f, 0x918c, 0x00ff, 0x96b4, 0x00ff, 0x080c,
-+	0x5608, 0x1904, 0x2b9b, 0x9186, 0x007f, 0x0150, 0x6004, 0x9084,
-+	0x00ff, 0x9086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2b98,
-+	0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
-+	0x2b98, 0x6867, 0x0000, 0x6868, 0xc0fd, 0x686a, 0x2001, 0x0100,
-+	0x8007, 0x680a, 0x080c, 0xaad9, 0x1120, 0x2009, 0x0003, 0x0804,
-+	0x2b98, 0x7007, 0x0003, 0x701b, 0x468e, 0x0005, 0x6808, 0x8007,
-+	0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2b98, 0x68e0,
-+	0x6866, 0x6810, 0x8007, 0x9084, 0x00ff, 0x800c, 0x6814, 0x8007,
-+	0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x9d80, 0x0004,
-+	0x2039, 0x0001, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x3f0f,
-+	0x080c, 0x3eb9, 0x1120, 0x2009, 0x0002, 0x0804, 0x2b98, 0x7984,
-+	0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
-+	0x2b9b, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
-+	0x0001, 0x080c, 0x3f0c, 0x701b, 0x46ce, 0x0005, 0x2001, 0x112c,
-+	0x2003, 0x0001, 0x9d80, 0x0019, 0x2098, 0x20e1, 0x0001, 0x20a9,
-+	0x001a, 0x20a1, 0x12ea, 0x20e9, 0x0001, 0x4003, 0x0804, 0x2b68,
-+	0x080c, 0x3eb9, 0x1120, 0x2009, 0x0002, 0x0804, 0x2b98, 0x7984,
-+	0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
-+	0x2b9b, 0x2099, 0x12ea, 0x20a0, 0x20e9, 0x0001, 0x20a9, 0x001a,
-+	0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c,
-+	0x7d98, 0x2039, 0x0001, 0x0804, 0x3f0f, 0x7884, 0x908a, 0x1000,
-+	0x1a04, 0x2b9b, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b,
-+	0x9108, 0x00c6, 0x2061, 0x1317, 0x6142, 0x00ce, 0x012e, 0x0804,
-+	0x2b68, 0x00c6, 0x080c, 0x62e4, 0x1180, 0x2001, 0x12a8, 0x2003,
-+	0x0001, 0x2001, 0x1100, 0x2003, 0x0001, 0x9085, 0x0001, 0x080c,
-+	0x6331, 0x080c, 0x621a, 0x080c, 0x0d7e, 0x2061, 0x1100, 0x6030,
-+	0xc09d, 0x6032, 0x080c, 0x4faa, 0x00ce, 0x0005, 0x00c6, 0x2001,
-+	0x1100, 0x2004, 0x908e, 0x0000, 0x0904, 0x2b98, 0x7884, 0x9005,
-+	0x0188, 0x7888, 0x2061, 0x12d6, 0x2c0c, 0x2062, 0x080c, 0x2328,
-+	0x01a0, 0x080c, 0x2330, 0x0188, 0x080c, 0x2338, 0x0170, 0x2162,
-+	0x0804, 0x2b9b, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118,
-+	0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002,
-+	0x1548, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011,
-+	0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec, 0x002e,
-+	0x080c, 0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e, 0x60e3,
-+	0x0000, 0x080c, 0xc44e, 0x080c, 0xc469, 0x9085, 0x0001, 0x080c,
-+	0x6331, 0x9006, 0x080c, 0x2401, 0x2001, 0x1100, 0x2003, 0x0004,
-+	0x6027, 0x0008, 0x00ce, 0x0804, 0x2b68, 0x81ff, 0x0120, 0x2009,
-+	0x0001, 0x0804, 0x2b98, 0x6000, 0x9086, 0x0003, 0x0120, 0x2009,
-+	0x0007, 0x0804, 0x2b98, 0x7e84, 0x860f, 0x918c, 0x00ff, 0x96b4,
-+	0x00ff, 0x080c, 0x5608, 0x1904, 0x2b9b, 0x9186, 0x007f, 0x0150,
-+	0x6004, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0120, 0x2009, 0x0009,
-+	0x0804, 0x2b98, 0x00c6, 0x080c, 0x3eb9, 0x00ce, 0x1120, 0x2009,
-+	0x0002, 0x0804, 0x2b98, 0x6867, 0x0000, 0x6868, 0xc0fd, 0x686a,
-+	0x080c, 0xaaf5, 0x1120, 0x2009, 0x0003, 0x0804, 0x2b98, 0x7007,
-+	0x0003, 0x701b, 0x47cc, 0x0005, 0x6830, 0x9086, 0x0100, 0x1120,
-+	0x2009, 0x0004, 0x0804, 0x2b98, 0x68e0, 0x6866, 0x6834, 0x8007,
-+	0x800c, 0x9d80, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
-+	0x0001, 0x0804, 0x3f0f, 0x6898, 0x9086, 0x000d, 0x1904, 0x2b98,
-+	0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x47f0, 0x0010,
-+	0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011,
-+	0x0010, 0x7833, 0x0010, 0x7883, 0x4005, 0x6998, 0x7986, 0x69a4,
-+	0x799a, 0x69a8, 0x799e, 0x080c, 0x3eff, 0x2091, 0x4080, 0x2001,
-+	0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd, 0x7007, 0x0001, 0x2091,
-+	0x5000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061,
-+	0x1317, 0x7984, 0x6152, 0x614e, 0x6057, 0x0000, 0x604b, 0x0009,
-+	0x7898, 0x606a, 0x789c, 0x6066, 0x7888, 0x6062, 0x788c, 0x605e,
-+	0x2061, 0x12aa, 0x2001, 0x132c, 0x6012, 0x600f, 0x0001, 0x6017,
-+	0x0001, 0x601b, 0x0002, 0x6007, 0x0000, 0x603b, 0x0000, 0x00ce,
-+	0x012e, 0x0804, 0x2b68, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6,
-+	0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069,
-+	0x0200, 0x2071, 0x1100, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118,
-+	0x080c, 0x49ce, 0x0068, 0xd08c, 0x0118, 0x080c, 0x48e1, 0x0040,
-+	0xd094, 0x0118, 0x080c, 0x48b4, 0x0018, 0xd09c, 0x0108, 0x0099,
-+	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e,
-+	0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d,
-+	0x612a, 0x001e, 0x0c68, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048,
-+	0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010,
-+	0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7134, 0xd1a4,
-+	0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128,
-+	0x2009, 0x00f7, 0x080c, 0x507b, 0x00f0, 0x6040, 0x9084, 0x0010,
-+	0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x707f, 0x0000, 0x709b,
-+	0x0001, 0x70c3, 0x0000, 0x70db, 0x0000, 0x2009, 0x1580, 0x200b,
-+	0x0000, 0x708f, 0x0000, 0x7083, 0x000f, 0x2009, 0x000f, 0x2011,
-+	0x4f50, 0x080c, 0x7283, 0x0005, 0x2001, 0x1174, 0x2004, 0xd08c,
-+	0x0110, 0x7057, 0xffff, 0x7080, 0x9005, 0x1510, 0x2011, 0x4f50,
-+	0x080c, 0x71fa, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042,
-+	0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x48ca, 0x6242,
-+	0x7093, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042,
-+	0x6242, 0x0030, 0x6242, 0x7093, 0x0000, 0x7087, 0x0000, 0x0000,
-+	0x0005, 0x7084, 0x908a, 0x0003, 0x1a0c, 0x0d7e, 0x000b, 0x0005,
-+	0x48eb, 0x4932, 0x49cd, 0x00f6, 0x7087, 0x0001, 0x6803, 0x00fc,
-+	0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x48f2,
-+	0x080c, 0x0d7e, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a,
-+	0xa001, 0x6803, 0x1600, 0x6837, 0x0020, 0x080c, 0x50d5, 0x2079,
-+	0x1500, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099,
-+	0x1105, 0x20e9, 0x0001, 0x20a1, 0x150e, 0x20a9, 0x0004, 0x4003,
-+	0x080c, 0x8dc3, 0x20e1, 0x0001, 0x2099, 0x1500, 0x20e9, 0x0000,
-+	0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f,
-+	0x0000, 0x080c, 0x4f86, 0x00fe, 0x9006, 0x708a, 0x6043, 0x0008,
-+	0x6042, 0x0005, 0x00f6, 0x7088, 0x708b, 0x0000, 0x9025, 0x0904,
-+	0x49aa, 0x6020, 0xd0b4, 0x1904, 0x49a8, 0x7198, 0x81ff, 0x0904,
-+	0x4996, 0x9486, 0x000c, 0x1904, 0x49a3, 0x9480, 0x0018, 0x8004,
-+	0x20a8, 0x080c, 0x50ce, 0x2011, 0x0260, 0x2019, 0x1500, 0x220c,
-+	0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x494f, 0x6043,
-+	0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061,
-+	0x0100, 0x6043, 0x0006, 0x7087, 0x0002, 0x7093, 0x0002, 0x2009,
-+	0x07d0, 0x2011, 0x4f57, 0x080c, 0x7283, 0x080c, 0x50d5, 0x04c0,
-+	0x080c, 0x50ce, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558,
-+	0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804,
-+	0x9005, 0x0190, 0x080c, 0x50ce, 0x2011, 0x026e, 0x2019, 0x1105,
-+	0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210,
-+	0x8318, 0x1f04, 0x498a, 0x0078, 0x709b, 0x0000, 0x080c, 0x50ce,
-+	0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1500,
-+	0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010,
-+	0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4,
-+	0x1db8, 0x080c, 0x8dc3, 0x20e1, 0x0001, 0x2099, 0x1500, 0x20e9,
-+	0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c,
-+	0x2011, 0x130e, 0x2013, 0x0000, 0x708b, 0x0000, 0x60a3, 0x0056,
-+	0x60a7, 0x9575, 0x080c, 0x8599, 0x08d8, 0x0005, 0x7090, 0x908a,
-+	0x001d, 0x1a0c, 0x0d7e, 0x000b, 0x0005, 0x49ff, 0x4a12, 0x4a3b,
-+	0x4a5b, 0x4a81, 0x4ab0, 0x4ad6, 0x4b0e, 0x4b34, 0x4b62, 0x4b9b,
-+	0x4bd3, 0x4bf1, 0x4c1c, 0x4c3e, 0x4c55, 0x4c5d, 0x4c91, 0x4cb7,
-+	0x4ce6, 0x4d0c, 0x4d44, 0x4d7e, 0x4db3, 0x4dd1, 0x4e2a, 0x4e4c,
-+	0x4e76, 0x4e76, 0x00c6, 0x2061, 0x1100, 0x6003, 0x0007, 0x2061,
-+	0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061,
-+	0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043,
-+	0x0002, 0x7093, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4f57, 0x080c,
-+	0x7283, 0x0005, 0x00f6, 0x7088, 0x9086, 0x0014, 0x1510, 0x6042,
-+	0x6020, 0xd0b4, 0x11f0, 0x080c, 0x50ce, 0x2079, 0x0260, 0x7a30,
-+	0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc,
-+	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011, 0x4f57,
-+	0x080c, 0x71fa, 0x7093, 0x0010, 0x080c, 0x4c5d, 0x0010, 0x708b,
-+	0x0000, 0x00fe, 0x0005, 0x00f6, 0x7093, 0x0003, 0x6043, 0x0004,
-+	0x2011, 0x4f57, 0x080c, 0x71fa, 0x080c, 0x505d, 0x2079, 0x0240,
-+	0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e,
-+	0x200b, 0x0000, 0x8108, 0x1f04, 0x4a50, 0x60c3, 0x0014, 0x080c,
-+	0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x0500, 0x2011,
-+	0x4f57, 0x080c, 0x71fa, 0x9086, 0x0014, 0x11b8, 0x080c, 0x50ce,
-+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005,
-+	0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3,
-+	0x0001, 0x7093, 0x0004, 0x0029, 0x0010, 0x080c, 0x50aa, 0x00fe,
-+	0x0005, 0x00f6, 0x7093, 0x0005, 0x080c, 0x505d, 0x2079, 0x0240,
-+	0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x50ce, 0x080c, 0x50b1,
-+	0x1170, 0x707c, 0x9005, 0x1158, 0x7154, 0x9186, 0xffff, 0x0138,
-+	0x2011, 0x0008, 0x080c, 0x4f04, 0x0168, 0x080c, 0x5092, 0x20a9,
-+	0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
-+	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x4f86, 0x00fe, 0x0005,
-+	0x00f6, 0x7088, 0x9005, 0x0500, 0x2011, 0x4f57, 0x080c, 0x71fa,
-+	0x9086, 0x0014, 0x11b8, 0x080c, 0x50ce, 0x2079, 0x0260, 0x7a30,
-+	0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
-+	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7093, 0x0006,
-+	0x0029, 0x0010, 0x080c, 0x50aa, 0x00fe, 0x0005, 0x00f6, 0x7093,
-+	0x0007, 0x080c, 0x505d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837,
-+	0x0000, 0x080c, 0x50ce, 0x080c, 0x50b1, 0x11b8, 0x707c, 0x9005,
-+	0x11a0, 0x715c, 0x9186, 0xffff, 0x0180, 0x9180, 0x298c, 0x200d,
-+	0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x4f04, 0x0180,
-+	0x080c, 0x41fc, 0x0110, 0x080c, 0x1fad, 0x20a9, 0x0008, 0x20e1,
-+	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-+	0x60c3, 0x0014, 0x080c, 0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088,
-+	0x9005, 0x0500, 0x2011, 0x4f57, 0x080c, 0x71fa, 0x9086, 0x0014,
-+	0x11b8, 0x080c, 0x50ce, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
-+	0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
-+	0x9005, 0x1110, 0x70c3, 0x0001, 0x7093, 0x0008, 0x0029, 0x0010,
-+	0x080c, 0x50aa, 0x00fe, 0x0005, 0x00f6, 0x7093, 0x0009, 0x080c,
-+	0x505d, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c,
-+	0x50b1, 0x1150, 0x707c, 0x9005, 0x1138, 0x080c, 0x4e77, 0x1188,
-+	0x9085, 0x0001, 0x080c, 0x1fad, 0x20a9, 0x0008, 0x080c, 0x50ce,
-+	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-+	0x4003, 0x60c3, 0x0014, 0x080c, 0x4f86, 0x0010, 0x080c, 0x49f2,
-+	0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x0598, 0x2011, 0x4f57,
-+	0x080c, 0x71fa, 0x9086, 0x0014, 0x1550, 0x080c, 0x50ce, 0x2079,
-+	0x0260, 0x7a30, 0x9296, 0x1105, 0x1510, 0x7834, 0x2011, 0x0100,
-+	0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
-+	0x70c3, 0x0001, 0x7093, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178,
-+	0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
-+	0x708f, 0x0000, 0x7093, 0x000e, 0x080c, 0x4c3e, 0x0010, 0x080c,
-+	0x50aa, 0x00fe, 0x0005, 0x00f6, 0x7093, 0x000b, 0x2011, 0x150e,
-+	0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304,
-+	0x080c, 0x505d, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000,
-+	0x080c, 0x50b1, 0x0118, 0x2013, 0x0000, 0x0020, 0x7058, 0x9085,
-+	0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x150e,
-+	0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000,
-+	0x6812, 0x2009, 0x0240, 0x1f04, 0x4bc0, 0x60c3, 0x0084, 0x080c,
-+	0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x01c0, 0x2011,
-+	0x4f57, 0x080c, 0x71fa, 0x9086, 0x0084, 0x1178, 0x080c, 0x50ce,
-+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005,
-+	0x1120, 0x7093, 0x000c, 0x0029, 0x0010, 0x080c, 0x50aa, 0x00fe,
-+	0x0005, 0x00f6, 0x7093, 0x000d, 0x080c, 0x505d, 0x2079, 0x0240,
-+	0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x50ce, 0x20a9, 0x0040,
-+	0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186,
-+	0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814,
-+	0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x4c04, 0x60c3, 0x0084,
-+	0x080c, 0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x01e0,
-+	0x2011, 0x4f57, 0x080c, 0x71fa, 0x9086, 0x0084, 0x1198, 0x080c,
-+	0x50ce, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834,
-+	0x9005, 0x1140, 0x708f, 0x0001, 0x080c, 0x502f, 0x7093, 0x000e,
-+	0x0029, 0x0010, 0x080c, 0x50aa, 0x00fe, 0x0005, 0x7093, 0x000f,
-+	0x708b, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5,
-+	0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
-+	0x2011, 0x4f57, 0x080c, 0x71ee, 0x0005, 0x7088, 0x9005, 0x0120,
-+	0x2011, 0x4f57, 0x080c, 0x71fa, 0x0005, 0x7093, 0x0011, 0x080c,
-+	0x8dc3, 0x080c, 0x50ce, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
-+	0x0000, 0x20a1, 0x0240, 0x7488, 0x9480, 0x0018, 0x9080, 0x0007,
-+	0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x50b1, 0x11a0,
-+	0x7174, 0x81ff, 0x0188, 0x900e, 0x7078, 0x9084, 0x00ff, 0x0160,
-+	0x080c, 0x1f63, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120,
-+	0x2011, 0x0008, 0x080c, 0x4f04, 0x60c3, 0x0014, 0x080c, 0x4f86,
-+	0x0005, 0x00f6, 0x7088, 0x9005, 0x0500, 0x2011, 0x4f57, 0x080c,
-+	0x71fa, 0x9086, 0x0014, 0x11b8, 0x080c, 0x50ce, 0x2079, 0x0260,
-+	0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
-+	0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7093,
-+	0x0012, 0x0029, 0x0010, 0x708b, 0x0000, 0x00fe, 0x0005, 0x00f6,
-+	0x7093, 0x0013, 0x080c, 0x506b, 0x2079, 0x0240, 0x7833, 0x1103,
-+	0x7837, 0x0000, 0x080c, 0x50ce, 0x080c, 0x50b1, 0x1170, 0x707c,
-+	0x9005, 0x1158, 0x7154, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008,
-+	0x080c, 0x4f04, 0x0168, 0x080c, 0x5092, 0x20a9, 0x0008, 0x20e1,
-+	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-+	0x60c3, 0x0014, 0x080c, 0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088,
-+	0x9005, 0x0500, 0x2011, 0x4f57, 0x080c, 0x71fa, 0x9086, 0x0014,
-+	0x11b8, 0x080c, 0x50ce, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104,
-+	0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
-+	0x9005, 0x1110, 0x70c3, 0x0001, 0x7093, 0x0014, 0x0029, 0x0010,
-+	0x708b, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7093, 0x0015, 0x080c,
-+	0x506b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
-+	0x50ce, 0x080c, 0x50b1, 0x11b8, 0x707c, 0x9005, 0x11a0, 0x715c,
-+	0x9186, 0xffff, 0x0180, 0x9180, 0x298c, 0x200d, 0x918c, 0xff00,
-+	0x810f, 0x2011, 0x0008, 0x080c, 0x4f04, 0x0180, 0x080c, 0x41fc,
-+	0x0110, 0x080c, 0x1fad, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-+	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-+	0x080c, 0x4f86, 0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x05a0,
-+	0x2011, 0x4f57, 0x080c, 0x71fa, 0x9086, 0x0014, 0x1558, 0x080c,
-+	0x50ce, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1518, 0x7834,
-+	0x2011, 0x0100, 0x921e, 0x1148, 0x7a38, 0xd2fc, 0x0128, 0x70c0,
-+	0x9005, 0x1110, 0x70c3, 0x0001, 0x0060, 0x9005, 0x1198, 0x7a38,
-+	0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x708f,
-+	0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db, 0x0008, 0x7093, 0x0016,
-+	0x0029, 0x0010, 0x708b, 0x0000, 0x00fe, 0x0005, 0x080c, 0x8dc3,
-+	0x080c, 0x50ce, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
-+	0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026e, 0x7093,
-+	0x0017, 0x080c, 0x50b1, 0x1150, 0x707c, 0x9005, 0x1138, 0x080c,
-+	0x4e77, 0x1188, 0x9085, 0x0001, 0x080c, 0x1fad, 0x20a9, 0x0008,
-+	0x080c, 0x50ce, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-+	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x4f86, 0x0010,
-+	0x080c, 0x49f2, 0x0005, 0x00f6, 0x7088, 0x9005, 0x01c0, 0x2011,
-+	0x4f57, 0x080c, 0x71fa, 0x9086, 0x0084, 0x1178, 0x080c, 0x50ce,
-+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005,
-+	0x1120, 0x7093, 0x0018, 0x0029, 0x0010, 0x708b, 0x0000, 0x00fe,
-+	0x0005, 0x00f6, 0x7093, 0x0019, 0x080c, 0x506b, 0x2079, 0x0240,
-+	0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x50ce, 0x2009, 0x026e,
-+	0x2039, 0x150e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186,
-+	0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04,
-+	0x4de4, 0x2039, 0x150e, 0x080c, 0x50b1, 0x11e8, 0x2728, 0x2514,
-+	0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007,
-+	0x9205, 0x202a, 0x7058, 0x2310, 0x8214, 0x92a0, 0x150e, 0x2414,
-+	0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff,
-+	0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e,
-+	0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812,
-+	0x2009, 0x0240, 0x1f04, 0x4e17, 0x60c3, 0x0084, 0x080c, 0x4f86,
-+	0x00fe, 0x0005, 0x00f6, 0x7088, 0x9005, 0x01e0, 0x2011, 0x4f57,
-+	0x080c, 0x71fa, 0x9086, 0x0084, 0x1198, 0x080c, 0x50ce, 0x2079,
-+	0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140,
-+	0x708f, 0x0001, 0x080c, 0x502f, 0x7093, 0x001a, 0x0029, 0x0010,
-+	0x708b, 0x0000, 0x00fe, 0x0005, 0x7093, 0x001b, 0x080c, 0x8dc3,
-+	0x080c, 0x50ce, 0x2011, 0x0260, 0x2009, 0x0240, 0x7488, 0x9480,
-+	0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e,
-+	0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812,
-+	0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04,
-+	0x4e5f, 0x60c3, 0x0084, 0x080c, 0x4f86, 0x0005, 0x0005, 0x0086,
-+	0x0096, 0x2029, 0x1153, 0x252c, 0x20a9, 0x0008, 0x2041, 0x150e,
-+	0x20e9, 0x0001, 0x28a0, 0x080c, 0x50ce, 0x20e1, 0x0000, 0x2099,
-+	0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108,
-+	0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4,
-+	0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4e91, 0x0804, 0x4f00,
-+	0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020,
-+	0x91a6, 0x3fff, 0x0904, 0x4f00, 0x918d, 0xc000, 0x20a9, 0x0010,
-+	0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
-+	0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
-+	0x0008, 0x8318, 0x1f04, 0x4eb7, 0x04d8, 0x23a8, 0x2021, 0x0001,
-+	0x8426, 0x8425, 0x1f04, 0x4ec9, 0x2328, 0x8529, 0x92be, 0x0007,
-+	0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8,
-+	0x95a8, 0x0010, 0x1f04, 0x4ed8, 0x7556, 0x95c8, 0x298c, 0x292d,
-+	0x95ac, 0x00ff, 0x757a, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
-+	0x1f8d, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405,
-+	0x201a, 0x707f, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1,
-+	0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008,
-+	0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136,
-+	0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-+	0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce,
-+	0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218,
-+	0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010,
-+	0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319,
-+	0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8,
-+	0x9405, 0x203a, 0x7156, 0x91a0, 0x298c, 0x242d, 0x95ac, 0x00ff,
-+	0x757a, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x1f8d, 0x001e,
-+	0x60e7, 0x0000, 0x65ea, 0x707f, 0x0001, 0x9084, 0x0000, 0x0005,
-+	0x00e6, 0x2071, 0x1100, 0x7083, 0x0000, 0x00ee, 0x0005, 0x00e6,
-+	0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x501e, 0x080c,
-+	0x85a2, 0x7004, 0x9084, 0x4000, 0x0138, 0x2001, 0x1000, 0x080c,
-+	0x2401, 0x9006, 0x080c, 0x2401, 0x0126, 0x2091, 0x8000, 0x2071,
-+	0x1124, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7,
-+	0x080c, 0x507b, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842,
-+	0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091,
-+	0x8000, 0x2011, 0x130e, 0x2013, 0x0000, 0x708b, 0x0000, 0x012e,
-+	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x8599, 0x6144, 0xd184,
-+	0x0120, 0x7190, 0x918d, 0x2000, 0x0018, 0x7184, 0x918d, 0x1000,
-+	0x2011, 0x12d3, 0x2112, 0x2009, 0x07d0, 0x2011, 0x4f57, 0x080c,
-+	0x7283, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
-+	0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec,
-+	0x080c, 0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e, 0x2009,
-+	0x00f7, 0x080c, 0x507b, 0x2061, 0x1317, 0x900e, 0x611a, 0x611e,
-+	0x2061, 0x1100, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090,
-+	0x6043, 0x0010, 0x2009, 0x12d3, 0x200b, 0x0000, 0x2009, 0x002d,
-+	0x2011, 0x4fe1, 0x080c, 0x71ee, 0x012e, 0x00ce, 0x002e, 0x001e,
-+	0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x04b9, 0x2071,
-+	0x0100, 0x080c, 0x85a2, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000,
-+	0x0138, 0x2001, 0x1000, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401,
-+	0x080c, 0x62ec, 0x01a8, 0x080c, 0x630a, 0x1190, 0x2001, 0x12a7,
-+	0x2003, 0xaaaa, 0x0016, 0x080c, 0x205d, 0x2001, 0x1298, 0x2102,
-+	0x001e, 0x2001, 0x12a8, 0x2003, 0x0000, 0x080c, 0x621a, 0x0050,
-+	0x2009, 0x0001, 0x080c, 0x2355, 0x2001, 0x0001, 0x080c, 0x1f11,
-+	0x080c, 0x4faa, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x110d,
-+	0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001,
-+	0x12d3, 0x201c, 0x080c, 0x3f23, 0x003e, 0x002e, 0x0005, 0x20a9,
-+	0x0012, 0x20e9, 0x0001, 0x20a1, 0x1580, 0x080c, 0x50ce, 0x20e9,
-+	0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x50c8,
-+	0x2099, 0x0260, 0x20a1, 0x1592, 0x0051, 0x20a9, 0x000e, 0x080c,
-+	0x50cb, 0x2099, 0x0260, 0x20a1, 0x15b2, 0x0009, 0x0005, 0x0016,
-+	0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210,
-+	0x1f04, 0x5053, 0x002e, 0x001e, 0x0005, 0x080c, 0x8dc3, 0x20e1,
-+	0x0001, 0x2099, 0x1500, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-+	0x000c, 0x4003, 0x0005, 0x080c, 0x8dc3, 0x080c, 0x50ce, 0x20e1,
-+	0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-+	0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f,
-+	0x2001, 0x1133, 0x2004, 0x9005, 0x1138, 0x2001, 0x1116, 0x2004,
-+	0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e,
-+	0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x58cb, 0x0158, 0x9006,
-+	0x2020, 0x2009, 0x002a, 0x080c, 0xc12f, 0x2001, 0x110c, 0x200c,
-+	0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x2831, 0x004e,
-+	0x001e, 0x0005, 0x080c, 0x4faa, 0x7093, 0x0000, 0x708b, 0x0000,
-+	0x0005, 0x0006, 0x2001, 0x110c, 0x2004, 0xd09c, 0x0100, 0x000e,
-+	0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101,
-+	0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005,
-+	0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, 0x900e, 0x6814,
-+	0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, 0x0156, 0x0146,
-+	0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1, 0x1500,
-+	0x4004, 0x2079, 0x1500, 0x7803, 0x2200, 0x7807, 0x00ef, 0x780f,
-+	0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, 0xffff, 0x01de,
-+	0x014e, 0x015e, 0x00fe, 0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009,
-+	0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x50fa, 0x015e, 0x0005,
-+	0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1152, 0x9006,
-+	0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0x9198, 0x298c,
-+	0x231d, 0x939c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0x9c98, 0x0006,
-+	0x20e9, 0x0001, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9c98, 0x000a,
-+	0x23a0, 0x4004, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a,
-+	0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a,
-+	0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2,
-+	0x00d6, 0x60a4, 0x906d, 0x0110, 0x080c, 0x0ecf, 0x60a7, 0x0000,
-+	0x00de, 0x9006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814,
-+	0x9084, 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de,
-+	0x0005, 0x0126, 0x2091, 0x8000, 0x6974, 0x6e78, 0x9684, 0x3fff,
-+	0x9082, 0x4000, 0x1a04, 0x51c0, 0x918c, 0xff00, 0x810f, 0x9182,
-+	0x00ff, 0x1a04, 0x51c4, 0x2001, 0x110c, 0x2004, 0x9084, 0x0003,
-+	0x1904, 0x51ca, 0x9188, 0x1000, 0x2104, 0x9065, 0x0500, 0x6004,
-+	0x9084, 0x00ff, 0x908e, 0x0006, 0x11f0, 0x60a4, 0x900d, 0x1904,
-+	0x51df, 0x6050, 0x900d, 0x1148, 0x6802, 0x2d00, 0x6052, 0x604e,
-+	0x080c, 0x758b, 0x9006, 0x012e, 0x0005, 0x2d00, 0x200a, 0x6803,
-+	0x0000, 0x6052, 0x0ca8, 0x2001, 0x0005, 0x900e, 0x04c0, 0x2001,
-+	0x0028, 0x900e, 0x04a0, 0x9082, 0x0006, 0x1298, 0x2001, 0x1136,
-+	0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc,
-+	0x09a0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028,
-+	0x00a8, 0x2009, 0x110c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
-+	0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
-+	0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038,
-+	0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005,
-+	0x012e, 0x0005, 0x2001, 0x110c, 0x2004, 0xd084, 0x19d0, 0x9188,
-+	0x1000, 0x2104, 0x9065, 0x09a8, 0x6004, 0x9084, 0x00ff, 0x908e,
-+	0x0006, 0x1978, 0x6000, 0xd0c4, 0x0960, 0x0804, 0x5175, 0x080c,
-+	0x5791, 0x0904, 0x518b, 0x0804, 0x5179, 0x00e6, 0x0126, 0x2091,
-+	0x8000, 0x6874, 0x8007, 0x9084, 0x00ff, 0x2008, 0x9182, 0x00ff,
-+	0x1a04, 0x5247, 0x9188, 0x1000, 0x2104, 0x9065, 0x0538, 0x6004,
-+	0x908c, 0x00ff, 0x918e, 0x0006, 0x0128, 0x908c, 0xff00, 0x918e,
-+	0x0600, 0x11f8, 0x2c70, 0x687c, 0xd0fc, 0x0138, 0x6894, 0x9005,
-+	0x0120, 0x2060, 0x2d00, 0x6016, 0x0058, 0x080c, 0x8e83, 0x05e8,
-+	0x2e00, 0x6012, 0x2d00, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
-+	0x2009, 0x0003, 0x080c, 0x8f53, 0x9006, 0x0460, 0x2001, 0x0028,
-+	0x0440, 0x9082, 0x0006, 0x1298, 0x2001, 0x1136, 0x2004, 0xd0ac,
-+	0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x0998, 0x2001,
-+	0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009,
-+	0x110c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184,
-+	0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001,
-+	0x0029, 0x9005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c, 0x0cc8,
-+	0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x68e0, 0x9005, 0x1568,
-+	0x68dc, 0x9082, 0x0101, 0x1648, 0x68c8, 0x9005, 0x1530, 0x68c4,
-+	0x9082, 0x0101, 0x1610, 0x6974, 0x2079, 0x1100, 0x918c, 0xff00,
-+	0x810f, 0x9182, 0x00ff, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130,
-+	0x6a98, 0x6b94, 0x6878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c,
-+	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
-+	0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
-+	0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e,
-+	0x00ee, 0x00fe, 0x0005, 0x52e3, 0x529b, 0x52b4, 0x52e3, 0x52e3,
-+	0x52e3, 0x52e3, 0x52e3, 0x2100, 0x9082, 0x007e, 0x1280, 0x080c,
-+	0x55b3, 0x2c70, 0x0148, 0x7010, 0x9306, 0x1904, 0x52eb, 0x7014,
-+	0x9206, 0x1904, 0x52eb, 0x0028, 0x7312, 0x7216, 0x0010, 0x080c,
-+	0x3dc2, 0x2c70, 0x0158, 0x04b8, 0x080c, 0x5608, 0x15a0, 0x2c70,
-+	0x7010, 0x9306, 0x1580, 0x7014, 0x9206, 0x1568, 0x080c, 0x8e83,
-+	0x0530, 0x2e00, 0x6012, 0x080c, 0xad70, 0x2d00, 0x6016, 0x600b,
-+	0xffff, 0x6023, 0x000a, 0x6878, 0x9086, 0x0001, 0x1170, 0x080c,
-+	0x2862, 0x9006, 0x080c, 0x5556, 0x2001, 0x0002, 0x080c, 0x5568,
-+	0x2001, 0x0200, 0x706e, 0x7093, 0x0002, 0x2009, 0x0003, 0x080c,
-+	0x8f53, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001,
-+	0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000,
-+	0x012e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x0126, 0x2091,
-+	0x8000, 0x6894, 0x90c6, 0x0015, 0x0904, 0x54b0, 0x90c6, 0x0056,
-+	0x0904, 0x54b4, 0x90c6, 0x0066, 0x0904, 0x54b8, 0x90c6, 0x0071,
-+	0x0904, 0x54bc, 0x90c6, 0x0074, 0x0904, 0x54c0, 0x90c6, 0x007c,
-+	0x0904, 0x54c4, 0x90c6, 0x007e, 0x0904, 0x54c8, 0x90c6, 0x0037,
-+	0x0904, 0x54cc, 0x9016, 0x2079, 0x1100, 0x6974, 0x918c, 0xff00,
-+	0x810f, 0x9182, 0x00ff, 0x1a04, 0x54ab, 0x080c, 0x5608, 0x11a0,
-+	0x6004, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1270, 0x6894, 0x90c6,
-+	0x006f, 0x0150, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x1904, 0x5496,
-+	0x60a0, 0xd0bc, 0x1904, 0x5496, 0x6894, 0x90c6, 0x006f, 0x0158,
-+	0x90c6, 0x005e, 0x0904, 0x53df, 0x90c6, 0x0064, 0x0904, 0x5413,
-+	0x2008, 0x0804, 0x53aa, 0x6998, 0x2140, 0x918c, 0xff00, 0x810f,
-+	0x78d8, 0xd0ac, 0x1120, 0x9182, 0x0080, 0x0a04, 0x53aa, 0x9182,
-+	0x00ff, 0x1a04, 0x53aa, 0x6aa0, 0x6b9c, 0x7874, 0x9306, 0x1168,
-+	0x7878, 0x924e, 0x1120, 0x2208, 0x2310, 0x0804, 0x53aa, 0x99cc,
-+	0xff00, 0x1118, 0x2208, 0x2310, 0x04e8, 0x080c, 0x3dc2, 0x2c70,
-+	0x0904, 0x53b2, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1520, 0x0006,
-+	0x2e60, 0x080c, 0x57d6, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108,
-+	0xc18d, 0x20a9, 0x0004, 0x9d80, 0x0031, 0x20a0, 0x20e9, 0x0001,
-+	0x9e80, 0x0006, 0x2098, 0x080c, 0x504f, 0x20a9, 0x0004, 0x9d80,
-+	0x0035, 0x20a0, 0x20e9, 0x0001, 0x9e80, 0x000a, 0x2098, 0x080c,
-+	0x504f, 0x000e, 0x0088, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0060,
-+	0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0030, 0x90c6, 0x4009,
-+	0x1108, 0x0010, 0x2001, 0x4006, 0x6896, 0x699a, 0x6a9e, 0x2001,
-+	0x0030, 0x0440, 0x080c, 0x8e83, 0x1130, 0x2001, 0x4005, 0x2009,
-+	0x0003, 0x9016, 0x0c88, 0x2e00, 0x6012, 0x080c, 0xad70, 0x2d00,
-+	0x6016, 0x6023, 0x0001, 0x6868, 0xd88c, 0x0108, 0xc0f5, 0x686a,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x2862, 0x012e, 0x9006, 0x080c,
-+	0x5556, 0x2001, 0x0002, 0x080c, 0x5568, 0x2009, 0x0002, 0x080c,
-+	0x8f53, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x0005, 0x7800,
-+	0x9086, 0x0003, 0x0118, 0x2009, 0x0007, 0x0448, 0x6e98, 0x860f,
-+	0x918c, 0x00ff, 0x96b4, 0x00ff, 0x080c, 0x5608, 0x0120, 0x2009,
-+	0x000a, 0x0804, 0x53aa, 0x9186, 0x007f, 0x0148, 0x6004, 0x9084,
-+	0x00ff, 0x9086, 0x0006, 0x0118, 0x2009, 0x0009, 0x0080, 0x00d6,
-+	0x080c, 0x0e9d, 0x1120, 0x00de, 0x2009, 0x0002, 0x0040, 0x2d00,
-+	0x00de, 0x6806, 0x080c, 0xaaf5, 0x1960, 0x2009, 0x0003, 0x2001,
-+	0x4005, 0x0804, 0x53ac, 0x6e98, 0x860f, 0x918c, 0x00ff, 0x96b4,
-+	0x00ff, 0x080c, 0x5608, 0x0120, 0x2009, 0x000a, 0x0804, 0x53aa,
-+	0x00d6, 0x080c, 0x0e9d, 0x1128, 0x00de, 0x2009, 0x0002, 0x0804,
-+	0x547a, 0x2d00, 0x00de, 0x6806, 0x00d6, 0x2068, 0x20a9, 0x002b,
-+	0x20e1, 0x0001, 0x2c98, 0x9de8, 0x0002, 0x20e9, 0x0001, 0x2da0,
-+	0x4003, 0x20a9, 0x0004, 0x9d80, 0x0006, 0x20a0, 0x9c80, 0x0006,
-+	0x2098, 0x080c, 0x504f, 0x20a9, 0x0004, 0x9d80, 0x000a, 0x20a0,
-+	0x9c80, 0x000a, 0x2098, 0x080c, 0x504f, 0x00de, 0x687b, 0x0000,
-+	0x6883, 0x0000, 0x6897, 0x4000, 0xd684, 0x1170, 0x2001, 0x1153,
-+	0x2004, 0xd0b4, 0x1118, 0x689b, 0x000b, 0x0400, 0x6000, 0xd08c,
-+	0x0118, 0x689b, 0x000c, 0x00d0, 0x6004, 0x9084, 0x00ff, 0x9086,
-+	0x0006, 0x0118, 0x689b, 0x0009, 0x0088, 0x7800, 0x9086, 0x0003,
-+	0x0118, 0x689b, 0x0007, 0x0050, 0x080c, 0xaabe, 0x1904, 0x53d9,
-+	0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x53ac, 0x687b, 0x0030,
-+	0x6897, 0x4005, 0x6804, 0x2009, 0x002b, 0x6aa0, 0x6b9c, 0x6ca8,
-+	0x6da4, 0x2031, 0x0000, 0x2039, 0x0001, 0x2041, 0x1078, 0x080c,
-+	0x9367, 0x1904, 0x53d9, 0x2009, 0x0002, 0x0c20, 0x2001, 0x0028,
-+	0x900e, 0x0804, 0x53da, 0x2009, 0x110c, 0x210c, 0xd18c, 0x0118,
-+	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
-+	0x2001, 0x0029, 0x900e, 0x2001, 0x0029, 0x900e, 0x0804, 0x53da,
-+	0x080c, 0x2d84, 0x0804, 0x53db, 0x080c, 0x460a, 0x0804, 0x53db,
-+	0x080c, 0x3a74, 0x0804, 0x53db, 0x080c, 0x3e74, 0x0804, 0x53db,
-+	0x080c, 0x408f, 0x0804, 0x53db, 0x080c, 0x4291, 0x0804, 0x53db,
-+	0x080c, 0x448a, 0x0804, 0x53db, 0x080c, 0x2f43, 0x0804, 0x53db,
-+	0x6974, 0x6e78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1648, 0x918c,
-+	0xff00, 0x810f, 0x9182, 0x00ff, 0x1280, 0x9188, 0x1000, 0x2104,
-+	0x9065, 0x0158, 0x6004, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1148,
-+	0x00e1, 0x080c, 0x5721, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e,
-+	0x0090, 0x9082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d88, 0x2001,
-+	0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018,
-+	0x2001, 0x0029, 0x900e, 0x9005, 0x0005, 0x0126, 0x2091, 0x8000,
-+	0x6050, 0x900d, 0x0138, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
-+	0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0,
-+	0x0126, 0x2091, 0x8000, 0x604c, 0x9005, 0x0170, 0x00e6, 0x2071,
-+	0x1304, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0x604c, 0x6802,
-+	0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803,
-+	0x0000, 0x0cc0, 0x701c, 0x9c06, 0x1d80, 0x604c, 0x2070, 0x7000,
-+	0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091,
-+	0x8000, 0x604c, 0x906d, 0x0130, 0x6800, 0x9005, 0x1108, 0x6052,
-+	0x604e, 0x9d05, 0x012e, 0x0005, 0x604c, 0x906d, 0x0130, 0x6800,
-+	0x9005, 0x1108, 0x6052, 0x604e, 0x9d05, 0x0005, 0x0126, 0x00c6,
-+	0x0026, 0x2091, 0x8000, 0x6210, 0x2260, 0x6200, 0x9005, 0x0110,
-+	0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005,
-+	0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2260, 0x6204, 0x0006,
-+	0x9086, 0x0006, 0x1170, 0x609c, 0xd0ac, 0x0158, 0x080c, 0x58cb,
-+	0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011,
-+	0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0x6206, 0x0006, 0x9086,
-+	0x0006, 0x1120, 0x6290, 0x82ff, 0x090c, 0x0d7e, 0x000e, 0x00ce,
-+	0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2260,
-+	0x6204, 0x0006, 0x9086, 0x0006, 0x1168, 0x609c, 0xd0a4, 0x0150,
-+	0x080c, 0x58c6, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110,
-+	0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0x6206,
-+	0x00ce, 0x012e, 0x0005, 0x0026, 0x9182, 0x00ff, 0x0218, 0x9085,
-+	0x0001, 0x00a0, 0x9190, 0x1000, 0x2204, 0x9065, 0x1170, 0x0016,
-+	0x00d6, 0x080c, 0x0e9d, 0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00,
-+	0x2012, 0x9006, 0x60a6, 0x080c, 0x5100, 0x9006, 0x002e, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x00ff, 0x0218, 0x9085,
-+	0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x906d, 0x0518,
-+	0x2013, 0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0x906d, 0x0110,
-+	0x080c, 0x0ecf, 0x00ce, 0x00de, 0x00d6, 0x00c6, 0x68ac, 0x2060,
-+	0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2068, 0x080c, 0xa942,
-+	0x0110, 0x080c, 0x0edf, 0x080c, 0x8ed9, 0x00ce, 0x0c88, 0x00ce,
-+	0x00de, 0x080c, 0x0ecf, 0x00de, 0x9006, 0x002e, 0x012e, 0x0005,
-+	0x0016, 0x9182, 0x00ff, 0x0218, 0x9085, 0x0001, 0x0030, 0x9188,
-+	0x1000, 0x2104, 0x9065, 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6,
-+	0x0156, 0x0136, 0x0146, 0x9006, 0x600a, 0x600e, 0x6000, 0xc08c,
-+	0x6002, 0x080c, 0x62e4, 0x1520, 0x60a0, 0x9086, 0x007e, 0x0130,
-+	0x2001, 0x1136, 0x2004, 0xd0ac, 0x11d8, 0x0078, 0x7040, 0xd0e4,
-+	0x01b8, 0x00c6, 0x2061, 0x12bc, 0x7048, 0x2062, 0x704c, 0x6006,
-+	0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140,
-+	0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1100, 0x68ae,
-+	0x7040, 0x605e, 0x7048, 0x6062, 0x6138, 0x910a, 0x0208, 0x603a,
-+	0x704c, 0x6066, 0x20e1, 0x0000, 0x2099, 0x0276, 0x9c88, 0x000a,
-+	0x20e9, 0x0001, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a,
-+	0x9c88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200,
-+	0x6817, 0x0001, 0x7040, 0x606a, 0x7144, 0x616e, 0x7048, 0x6072,
-+	0x7050, 0x6076, 0x2069, 0x0200, 0x6817, 0x0000, 0x60a0, 0x9086,
-+	0x007e, 0x1110, 0x7144, 0x616e, 0x9182, 0x0211, 0x1218, 0x2009,
-+	0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
-+	0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349,
-+	0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009,
-+	0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
-+	0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
-+	0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0x6896, 0x703c,
-+	0x689a, 0x7054, 0x689e, 0x6a00, 0x2009, 0x1172, 0x210c, 0xd0bc,
-+	0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0120,
-+	0xd1e4, 0x0110, 0xc2bd, 0x0008, 0xc2bc, 0x6a02, 0x00ee, 0x002e,
-+	0x001e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0x906d,
-+	0x01c0, 0x6900, 0x81ff, 0x1540, 0x6a04, 0x9282, 0x0010, 0x1648,
-+	0x9d88, 0x0004, 0x20a9, 0x0010, 0x2104, 0x9086, 0xffff, 0x0128,
-+	0x8108, 0x1f04, 0x56dc, 0x080c, 0x0d7e, 0x260a, 0x8210, 0x6a06,
-+	0x0098, 0x080c, 0x0eb6, 0x01a8, 0x2d00, 0x60a6, 0x6803, 0x0000,
-+	0x9d88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04,
-+	0x56f4, 0x6807, 0x0001, 0x6e12, 0x9085, 0x0001, 0x012e, 0x00de,
-+	0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x00d6, 0x60a4,
-+	0x900d, 0x01a0, 0x2168, 0x6800, 0x9005, 0x1160, 0x080c, 0x5791,
-+	0x1168, 0x200b, 0xffff, 0x6804, 0x908a, 0x0002, 0x0218, 0x8001,
-+	0x6806, 0x0020, 0x080c, 0x0ecf, 0x60a7, 0x0000, 0x00de, 0x012e,
-+	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x758b, 0x012e, 0x0005,
-+	0x901e, 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000,
-+	0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01f8, 0x83ff,
-+	0x0120, 0x6878, 0x9606, 0x0158, 0x0030, 0x686c, 0x9406, 0x1118,
-+	0x6870, 0x9506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x080c,
-+	0x895e, 0x6a00, 0x604c, 0x9d06, 0x1110, 0x624e, 0x0018, 0x9180,
-+	0x0000, 0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005,
-+	0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x57d6,
-+	0x0118, 0x080c, 0xa9f4, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
-+	0x57d6, 0x0118, 0x080c, 0xa987, 0x0010, 0x9085, 0x0001, 0x0005,
-+	0x080c, 0x57d6, 0x0118, 0x080c, 0xa9d7, 0x0010, 0x9085, 0x0001,
-+	0x0005, 0x080c, 0x57d6, 0x0118, 0x080c, 0xa9a3, 0x0010, 0x9085,
-+	0x0001, 0x0005, 0x080c, 0x57d6, 0x0118, 0x080c, 0xaa10, 0x0010,
-+	0x9085, 0x0001, 0x0005, 0x60a4, 0x900d, 0x1118, 0x9085, 0x0001,
-+	0x0005, 0x00e6, 0x2170, 0x7000, 0x9005, 0x1168, 0x20a9, 0x0010,
-+	0x9e88, 0x0004, 0x2104, 0x9606, 0x0130, 0x8108, 0x1f04, 0x579a,
-+	0x9085, 0x0001, 0x0008, 0x9006, 0x00ee, 0x0005, 0x00d6, 0x0126,
-+	0x2091, 0x8000, 0x60a4, 0x906d, 0x1128, 0x080c, 0x0eb6, 0x01a0,
-+	0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0x9d88, 0x0004,
-+	0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x57ba, 0x9085,
-+	0x0001, 0x012e, 0x00de, 0x0005, 0x9006, 0x0cd8, 0x00d6, 0x0126,
-+	0x2091, 0x8000, 0x60a4, 0x906d, 0x0130, 0x60a7, 0x0000, 0x080c,
-+	0x0ecf, 0x9085, 0x0001, 0x012e, 0x00de, 0x0005, 0x609c, 0xd0a4,
-+	0x0005, 0x00f6, 0x080c, 0x62e4, 0x01b0, 0x71c0, 0x81ff, 0x1198,
-+	0x71d8, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004,
-+	0x907d, 0x0148, 0x7804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118,
-+	0x7800, 0xc0ed, 0x7802, 0x2079, 0x1152, 0x7804, 0xd0a4, 0x01e0,
-+	0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x5608,
-+	0x1168, 0x6004, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118,
-+	0x9086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108,
-+	0x1f04, 0x57fd, 0x00ce, 0x015e, 0x080c, 0x588e, 0x0120, 0x2001,
-+	0x12bf, 0x200c, 0x0038, 0x2079, 0x1152, 0x7804, 0xd0a4, 0x0130,
-+	0x2009, 0x07d0, 0x2011, 0x5828, 0x080c, 0x7283, 0x00fe, 0x0005,
-+	0x2011, 0x5828, 0x080c, 0x71fa, 0x080c, 0x588e, 0x01d8, 0x2001,
-+	0x107e, 0x2004, 0x9080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x080c,
-+	0x58cb, 0x0130, 0x2009, 0x07d0, 0x2011, 0x5828, 0x080c, 0x7283,
-+	0x00e6, 0x2071, 0x1100, 0x9006, 0x7076, 0x707a, 0x080c, 0x2679,
-+	0x00ee, 0x0498, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016,
-+	0x080c, 0x5608, 0x1520, 0x6000, 0xd0ec, 0x0508, 0x0046, 0x62a0,
-+	0x9294, 0x00ff, 0x8227, 0x9006, 0x2009, 0x0029, 0x080c, 0xc12f,
-+	0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0x9084, 0x00ff, 0x9085,
-+	0x0700, 0x6006, 0x2019, 0x0029, 0x080c, 0x76f0, 0x0076, 0x903e,
-+	0x080c, 0x75ee, 0x900e, 0x080c, 0xbec2, 0x007e, 0x004e, 0x001e,
-+	0x8108, 0x1f04, 0x584f, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6010,
-+	0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7810, 0x2004,
-+	0xd0ac, 0x0005, 0x7810, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001,
-+	0x107e, 0x2004, 0x907d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005,
-+	0x0126, 0x0026, 0x2091, 0x8000, 0x0006, 0x62a0, 0x9290, 0x1000,
-+	0x2204, 0x9c06, 0x190c, 0x0d7e, 0x000e, 0x6200, 0x9005, 0x0110,
-+	0xc2fd, 0x0008, 0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2011,
-+	0x1136, 0x2204, 0xd0cc, 0x0138, 0x2001, 0x12bd, 0x200c, 0x2011,
-+	0x58bc, 0x080c, 0x7283, 0x0005, 0x2011, 0x58bc, 0x080c, 0x71fa,
-+	0x2011, 0x1136, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x2001, 0x1153,
-+	0x2004, 0xd0ac, 0x0005, 0x2001, 0x1153, 0x2004, 0xd0a4, 0x0005,
-+	0x2071, 0x1240, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012,
-+	0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2071, 0x1286, 0x7003,
-+	0x1240, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0x0001, 0x7013,
-+	0x1266, 0x7017, 0x0020, 0x701b, 0x0040, 0x703b, 0x0000, 0x2001,
-+	0x1262, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1263,
-+	0x900e, 0x710a, 0x2001, 0x1153, 0x2004, 0xd0fc, 0x1148, 0x2001,
-+	0x1153, 0x2004, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x04d8,
-+	0x2001, 0x1172, 0x200c, 0x9184, 0x000f, 0x0002, 0x58ff, 0x58ff,
-+	0x58ff, 0x58ff, 0x58ff, 0x591e, 0x592c, 0x58ff, 0x592f, 0x58ff,
-+	0x58ff, 0x58ff, 0x58ff, 0x58ff, 0x58ff, 0x58ff, 0x7003, 0x0003,
-+	0x2009, 0x1173, 0x210c, 0x9184, 0xff00, 0x8007, 0x9005, 0x1110,
-+	0x2001, 0x0002, 0x7006, 0x00b8, 0x7003, 0x0005, 0x0c88, 0x7003,
-+	0x0004, 0x0136, 0x0146, 0x0156, 0x20e1, 0x0001, 0x2099, 0x1176,
-+	0x20e9, 0x0001, 0x20a1, 0x1290, 0x20a9, 0x0004, 0x4003, 0x015e,
-+	0x014e, 0x013e, 0x0000, 0x00ee, 0x001e, 0x0005, 0x00e6, 0x2071,
-+	0x0050, 0x684c, 0x9005, 0x1158, 0x00e6, 0x2071, 0x1240, 0x7028,
-+	0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0804, 0x5998, 0x6844,
-+	0x9005, 0x01d8, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011,
-+	0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
-+	0x3e08, 0x1f04, 0x595e, 0x015e, 0x6a60, 0x9200, 0x7002, 0x6864,
-+	0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864,
-+	0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110,
-+	0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e,
-+	0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1240, 0x7028,
-+	0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006,
-+	0x00ee, 0x0005, 0x6868, 0xd0fc, 0x11d0, 0x00e6, 0x0026, 0x2001,
-+	0x1263, 0x2004, 0x9005, 0x0904, 0x5b7b, 0x687c, 0xd0bc, 0x1904,
-+	0x5b7b, 0x6978, 0x6874, 0x9105, 0x1904, 0x5b7b, 0x2001, 0x1263,
-+	0x2004, 0x0002, 0x5b7b, 0x59dc, 0x5a16, 0x5a16, 0x5efd, 0x0005,
-+	0x6868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009, 0x1263, 0x210c,
-+	0x81ff, 0x0904, 0x5b7b, 0x687c, 0xd0cc, 0x0904, 0x5b7b, 0x6880,
-+	0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x5b7b, 0x9186, 0x0003,
-+	0x0904, 0x5a16, 0x9186, 0x0004, 0x0904, 0x5efd, 0x684f, 0x8021,
-+	0x6853, 0x0017, 0x0028, 0x0005, 0x684f, 0x8020, 0x6853, 0x0016,
-+	0x2071, 0x1240, 0x701c, 0x9005, 0x1904, 0x5d24, 0x0e04, 0x5d6d,
-+	0x2071, 0x0000, 0x684c, 0x7082, 0x6850, 0x7032, 0x686c, 0x7086,
-+	0x7036, 0x6870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-+	0xd084, 0x190c, 0x0fcd, 0x2071, 0x1100, 0x2011, 0x0001, 0x6804,
-+	0x900d, 0x702c, 0x1148, 0x206a, 0x2d00, 0x702e, 0x70bc, 0x9200,
-+	0x70be, 0x002e, 0x00ee, 0x0005, 0x00d6, 0x2168, 0x6904, 0x206a,
-+	0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x00de, 0x0c68, 0x684f, 0x0000,
-+	0x00f6, 0x2079, 0x0050, 0x2071, 0x1240, 0x206b, 0x0000, 0x7010,
-+	0x9005, 0x1904, 0x5b0a, 0x782c, 0x908c, 0x0780, 0x190c, 0x5f3b,
-+	0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x5a34, 0x5b0a,
-+	0x5a5a, 0x5aa3, 0x080c, 0x0d7e, 0x2071, 0x1100, 0x8d07, 0x8005,
-+	0x8005, 0xc0d5, 0x7822, 0x6804, 0x900d, 0x1170, 0x2071, 0x1317,
-+	0x703c, 0x9005, 0x1328, 0x2001, 0x1264, 0x2004, 0x8005, 0x703e,
-+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2168, 0x6904,
-+	0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
-+	0x70be, 0x0c20, 0x2071, 0x1100, 0x8d07, 0x8005, 0x8005, 0xc0d5,
-+	0x7822, 0x6804, 0x900d, 0x1588, 0x7824, 0x00e6, 0x2071, 0x0040,
-+	0x712c, 0xd19c, 0x1148, 0x2009, 0x112f, 0x210c, 0x918a, 0x0010,
-+	0x0218, 0x7022, 0x00ee, 0x0060, 0x00ee, 0xc0d4, 0x8006, 0x8006,
-+	0x806f, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70bc, 0x8000, 0x70be,
-+	0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4, 0x19e8, 0x2071,
-+	0x1317, 0x703c, 0x9005, 0x1328, 0x2001, 0x1264, 0x2004, 0x8005,
-+	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2168,
-+	0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
-+	0x9200, 0x70be, 0x0808, 0x00d6, 0x00e6, 0x7824, 0xc0d4, 0x8006,
-+	0x8006, 0x806f, 0x2071, 0x1100, 0x702c, 0x206a, 0x2d00, 0x702e,
-+	0x70bc, 0x8000, 0x70be, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b,
-+	0xd0a4, 0x1d58, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b,
-+	0xd09c, 0x11b8, 0x00de, 0x8d07, 0x8005, 0x8005, 0xc0d5, 0x7822,
-+	0x6804, 0x900d, 0x1560, 0x2071, 0x1317, 0x703c, 0x9005, 0x1328,
-+	0x2001, 0x1264, 0x2004, 0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee,
-+	0x0005, 0x00de, 0x2d08, 0x7010, 0x8000, 0x7012, 0x7018, 0x906d,
-+	0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x2168, 0x6804, 0x900d,
-+	0x1170, 0x2071, 0x1317, 0x703c, 0x9005, 0x1328, 0x2001, 0x1264,
-+	0x2004, 0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071,
-+	0x1100, 0x9016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00,
-+	0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x00fe, 0x002e,
-+	0x00ee, 0x0005, 0x2d08, 0x7010, 0x8000, 0x7012, 0x7018, 0x906d,
-+	0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x2168, 0x6804, 0x900d,
-+	0x1904, 0x5b63, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd09c,
-+	0x11b0, 0x701c, 0x906d, 0x0198, 0x7010, 0x8001, 0x7012, 0x1108,
-+	0x701a, 0x2d04, 0x701e, 0x8d07, 0x8005, 0x8005, 0xc0d5, 0x7822,
-+	0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd09c, 0x0d50, 0x782c,
-+	0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4, 0x01b8, 0x00e6, 0x7824,
-+	0xc0d4, 0x8006, 0x8006, 0x806f, 0x2071, 0x1100, 0x702c, 0x206a,
-+	0x2d00, 0x702e, 0x70bc, 0x8000, 0x70be, 0x782c, 0x9094, 0x0780,
-+	0x190c, 0x5f3b, 0xd0a4, 0x1d58, 0x00ee, 0x2071, 0x1317, 0x703c,
-+	0x9005, 0x1328, 0x2001, 0x1264, 0x2004, 0x8005, 0x703e, 0x00fe,
-+	0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1100, 0x9016, 0x702c,
-+	0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e,
-+	0x70bc, 0x9200, 0x70be, 0x00ee, 0x0804, 0x5b1a, 0x6868, 0xd0fc,
-+	0x1500, 0x00e6, 0x0026, 0x684f, 0x0000, 0x00f6, 0x2079, 0x0050,
-+	0x2071, 0x1240, 0x206b, 0x0000, 0x7010, 0x9005, 0x1904, 0x5c9c,
-+	0x782c, 0x908c, 0x0780, 0x190c, 0x5f3b, 0x8004, 0x8004, 0x8004,
-+	0x9084, 0x0003, 0x0002, 0x5b9a, 0x5c9c, 0x5bb6, 0x5c29, 0x080c,
-+	0x0d7e, 0x0005, 0x2071, 0x1100, 0x8d07, 0x8005, 0x8005, 0xc0d5,
-+	0x7822, 0x6804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005,
-+	0x9016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff,
-+	0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x0c70, 0x2071, 0x1100,
-+	0x8d07, 0x8005, 0x8005, 0xc0d5, 0x7822, 0x6804, 0x900d, 0x1904,
-+	0x5c1a, 0x7830, 0x8007, 0x9084, 0x001f, 0x9082, 0x0005, 0x1220,
-+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040,
-+	0x712c, 0xd19c, 0x1148, 0x2009, 0x112f, 0x210c, 0x918a, 0x0010,
-+	0x0218, 0x7022, 0x00ee, 0x0060, 0x00ee, 0xc0d4, 0x8006, 0x8006,
-+	0x806f, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70bc, 0x8000, 0x70be,
-+	0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4, 0x19e8, 0x0e04,
-+	0x5c11, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
-+	0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1251, 0x200c, 0xc184,
-+	0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-+	0x0fcd, 0x2009, 0x1262, 0x200b, 0x0000, 0x00fe, 0x002e, 0x00ee,
-+	0x0005, 0x2001, 0x1251, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e,
-+	0x00ee, 0x0005, 0x9016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210,
-+	0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x0804,
-+	0x5bcc, 0x00d6, 0x00e6, 0x7824, 0xc0d4, 0x8006, 0x8006, 0x806f,
-+	0x2071, 0x1100, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70bc, 0x8000,
-+	0x70be, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4, 0x1d58,
-+	0x00ee, 0x0e04, 0x5c71, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-+	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
-+	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-+	0x0fcd, 0x2009, 0x1262, 0x200b, 0x0000, 0x782c, 0x9094, 0x0780,
-+	0x190c, 0x5f3b, 0xd09c, 0x1188, 0x00de, 0x8d07, 0x8005, 0x8005,
-+	0xc0d5, 0x7822, 0x6804, 0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee,
-+	0x0005, 0x7044, 0xc085, 0x7046, 0x0c40, 0x00de, 0x2d08, 0x7010,
-+	0x8000, 0x7012, 0x7018, 0x906d, 0x711a, 0x0110, 0x6902, 0x0008,
-+	0x711e, 0x2168, 0x6804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee,
-+	0x0005, 0x2071, 0x1100, 0x9016, 0x702c, 0x2168, 0x6904, 0x206a,
-+	0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
-+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x2d08, 0x7010, 0x8000, 0x7012,
-+	0x7018, 0x906d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x2168,
-+	0x6804, 0x900d, 0x1904, 0x5d11, 0x782c, 0x9094, 0x0780, 0x190c,
-+	0x5f3b, 0xd09c, 0x11c8, 0x701c, 0x906d, 0x01b0, 0x684c, 0x9005,
-+	0x1198, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0x2d04, 0x701e,
-+	0x8d07, 0x8005, 0x8005, 0xc0d5, 0x7822, 0x782c, 0x9094, 0x0780,
-+	0x190c, 0x5f3b, 0xd09c, 0x0d38, 0x782c, 0x9094, 0x0780, 0x190c,
-+	0x5f3b, 0xd0a4, 0x05d0, 0x00e6, 0x7824, 0xc0d4, 0x8006, 0x8006,
-+	0x806f, 0x2071, 0x1100, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70bc,
-+	0x8000, 0x70be, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4,
-+	0x1d58, 0x00ee, 0x0e04, 0x5d0a, 0x7838, 0x7938, 0x910e, 0x1de0,
-+	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-+	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-+	0x190c, 0x0fcd, 0x2009, 0x1262, 0x200b, 0x0000, 0x00fe, 0x002e,
-+	0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee,
-+	0x0005, 0x00e6, 0x2071, 0x1100, 0x9016, 0x702c, 0x2168, 0x6904,
-+	0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
-+	0x70be, 0x00ee, 0x0804, 0x5cac, 0x2071, 0x1240, 0x206b, 0x0000,
-+	0x2d08, 0x7010, 0x8000, 0x7012, 0x7018, 0x906d, 0x711a, 0x0110,
-+	0x6902, 0x0008, 0x711e, 0x2168, 0x6804, 0x900d, 0x1128, 0x1e04,
-+	0x5d4d, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1100, 0x9016, 0x702c,
-+	0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e,
-+	0x70bc, 0x9200, 0x70be, 0x0e04, 0x5d39, 0x2071, 0x1240, 0x701c,
-+	0x2068, 0x684c, 0x900d, 0x0d28, 0x2071, 0x0000, 0x7182, 0x6850,
-+	0x7032, 0x686c, 0x7086, 0x7036, 0x6870, 0x708a, 0x2091, 0x4080,
-+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd, 0x2071, 0x1240,
-+	0x080c, 0x5f27, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1240, 0x206b,
-+	0x0000, 0x2d08, 0x7010, 0x8000, 0x7012, 0x7018, 0x906d, 0x711a,
-+	0x0110, 0x6902, 0x0008, 0x711e, 0x2168, 0x6804, 0x900d, 0x1118,
-+	0x002e, 0x00ee, 0x0005, 0x2071, 0x1100, 0x9016, 0x702c, 0x2168,
-+	0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
-+	0x9200, 0x70be, 0x002e, 0x00ee, 0x0005, 0x0006, 0x687c, 0x0006,
-+	0x6867, 0x0103, 0x20a9, 0x001c, 0x9d80, 0x001d, 0x20a0, 0x9006,
-+	0x20e9, 0x0001, 0x4004, 0x000e, 0x9084, 0x00ff, 0x687e, 0x000e,
-+	0x687a, 0x6982, 0x0005, 0x2071, 0x1240, 0x7004, 0x0002, 0x5db7,
-+	0x5db8, 0x5efc, 0x5eea, 0x5db5, 0x5efc, 0x080c, 0x0d7e, 0x0005,
-+	0x2001, 0x1263, 0x2004, 0x0002, 0x5dc2, 0x5dc2, 0x5e1a, 0x5e1b,
-+	0x5e85, 0x5e1b, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x5f40, 0x701c,
-+	0x906d, 0x01e0, 0x684c, 0x9005, 0x01d8, 0x0e04, 0x5de6, 0x694c,
-+	0x2071, 0x0000, 0x7182, 0x6850, 0x7032, 0x686c, 0x7086, 0x7036,
-+	0x6870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-+	0x190c, 0x0fcd, 0x2071, 0x1240, 0x080c, 0x5f27, 0x012e, 0x0488,
-+	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd09c,
-+	0x2071, 0x1240, 0x1528, 0x2071, 0x1240, 0x700f, 0x0001, 0x6964,
-+	0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
-+	0x8101, 0x0108, 0x710e, 0x8d07, 0x8005, 0x8005, 0xc0d5, 0x00d6,
-+	0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1240, 0x701c, 0x2068,
-+	0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0x9005, 0x1108, 0x701a,
-+	0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x1317, 0x683c,
-+	0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, 0x1113,
-+	0x2004, 0x2009, 0x13a1, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091,
-+	0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04,
-+	0x5e4d, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, 0x6883,
-+	0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-+	0x0fcd, 0x2069, 0x1317, 0x683f, 0xffff, 0x012e, 0x00de, 0x0126,
-+	0x2091, 0x8000, 0x1e0c, 0x5fb5, 0x701c, 0x906d, 0x0560, 0x2001,
-+	0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd09c, 0x1518,
-+	0x2071, 0x1240, 0x700f, 0x0001, 0x6964, 0x9184, 0x00ff, 0x9086,
-+	0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e,
-+	0x8d07, 0x8005, 0x8005, 0xc0d5, 0x00d6, 0x2069, 0x0050, 0x6822,
-+	0x00de, 0x701c, 0x2068, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e,
-+	0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
-+	0x1e0c, 0x5f40, 0x701c, 0x906d, 0x0548, 0x684c, 0x9086, 0x0004,
-+	0x1538, 0x0136, 0x0146, 0x0156, 0x2099, 0x1176, 0x20e1, 0x0001,
-+	0x20a1, 0x1290, 0x20e9, 0x0001, 0x20a9, 0x0004, 0x4003, 0x015e,
-+	0x014e, 0x013e, 0x2071, 0x1286, 0x9d80, 0x001b, 0x700f, 0x0001,
-+	0x7012, 0x7017, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
-+	0x080c, 0x0f22, 0x2071, 0x1240, 0x7007, 0x0003, 0x012e, 0x0005,
-+	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd09c,
-+	0x2071, 0x1240, 0x1d98, 0x2071, 0x1240, 0x700f, 0x0001, 0x6964,
-+	0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
-+	0x8101, 0x0108, 0x710e, 0x8d07, 0x8005, 0x8005, 0xc0d5, 0x00d6,
-+	0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1240, 0x701c, 0x2068,
-+	0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0x9005, 0x1978, 0x701a,
-+	0x012e, 0x0005, 0x2001, 0x1288, 0x2004, 0x908e, 0x0100, 0x1120,
-+	0x7007, 0x0001, 0x04a1, 0x0005, 0x908e, 0x0000, 0x0de0, 0x908e,
-+	0x0200, 0x1dc8, 0x080c, 0x5f3b, 0x0005, 0x684f, 0x0004, 0x206b,
-+	0x0000, 0x2d08, 0x2071, 0x1240, 0x7010, 0x8000, 0x7012, 0x7018,
-+	0x906d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x2168, 0x6804,
-+	0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1100, 0x9016,
-+	0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8,
-+	0x702e, 0x70bc, 0x9200, 0x70be, 0x002e, 0x00ee, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x701c, 0x906d, 0x0160, 0x7010, 0x8001, 0x7012,
-+	0x2d04, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x0ecf,
-+	0x0005, 0x012e, 0x0005, 0x2011, 0x8004, 0x080c, 0x3f23, 0x0cf8,
-+	0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01d8, 0xc084, 0x7046,
-+	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
-+	0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-+	0xd084, 0x190c, 0x0fcd, 0x2009, 0x1262, 0x200b, 0x0000, 0x00fe,
-+	0x0005, 0x782c, 0x9094, 0x0780, 0x19b1, 0xd0a4, 0x0dc0, 0x2001,
-+	0x1263, 0x2004, 0x9086, 0x0004, 0x0140, 0x2009, 0x1262, 0x2104,
-+	0x8000, 0x200a, 0x9082, 0x000f, 0x0e50, 0x00e6, 0x2071, 0x1100,
-+	0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009,
-+	0x112f, 0x210c, 0x918a, 0x0010, 0x0218, 0x7022, 0x00ee, 0x0060,
-+	0x00ee, 0xc0d4, 0x8006, 0x8006, 0x806f, 0x702c, 0x206a, 0x2d00,
-+	0x702e, 0x70bc, 0x8000, 0x70be, 0x782c, 0x9094, 0x0780, 0x190c,
-+	0x5f3b, 0xd0a4, 0x19e8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-+	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080,
-+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd, 0x2009, 0x1262,
-+	0x200b, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0050,
-+	0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e,
-+	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
-+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x0fcd,
-+	0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4,
-+	0x0db8, 0x00e6, 0x2071, 0x1100, 0x7824, 0xc0d4, 0x8006, 0x8006,
-+	0x806f, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70bc, 0x8000, 0x70be,
-+	0x782c, 0x9094, 0x0780, 0x190c, 0x5f3b, 0xd0a4, 0x1d68, 0x00d6,
-+	0x2069, 0x0050, 0x693c, 0x2069, 0x1263, 0x6808, 0x690a, 0x2069,
-+	0x1317, 0x9102, 0x1118, 0x683c, 0x9005, 0x1328, 0x2001, 0x1264,
-+	0x200c, 0x810d, 0x693e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7090,
-+	0x908a, 0x0029, 0x1a0c, 0x0d7e, 0x9082, 0x001d, 0x001b, 0x6027,
-+	0x1e00, 0x0005, 0x60da, 0x6064, 0x6080, 0x60a8, 0x60c9, 0x6109,
-+	0x611b, 0x6080, 0x60f1, 0x601f, 0x604d, 0x601e, 0x0005, 0x00d6,
-+	0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, 0x1518,
-+	0x7093, 0x0028, 0x2069, 0x12c9, 0x2d04, 0x7002, 0x080c, 0x6404,
-+	0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x7093, 0x0028, 0x2069,
-+	0x12c9, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, 0x00e6,
-+	0x0036, 0x0046, 0x0056, 0x2071, 0x1347, 0x080c, 0x1577, 0x005e,
-+	0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200,
-+	0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x7093, 0x0028,
-+	0x2069, 0x12c9, 0x2d04, 0x7002, 0x080c, 0x6492, 0x6028, 0x9085,
-+	0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c,
-+	0x2401, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x618c, 0xd1d4,
-+	0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x7093, 0x0020, 0x080c,
-+	0x618c, 0x0028, 0x7093, 0x001d, 0x0010, 0x7093, 0x001f, 0x0005,
-+	0x2001, 0x0088, 0x080c, 0x2401, 0x6124, 0xd1cc, 0x11d8, 0xd1dc,
-+	0x11b0, 0xd1e4, 0x1188, 0x9184, 0x1e00, 0x11c8, 0x60e3, 0x0001,
-+	0x600c, 0xc0b4, 0x600e, 0x080c, 0x6314, 0x2001, 0x0080, 0x080c,
-+	0x2401, 0x7093, 0x0028, 0x0058, 0x7093, 0x001e, 0x0040, 0x7093,
-+	0x001d, 0x0028, 0x7093, 0x0020, 0x0010, 0x7093, 0x001f, 0x0005,
-+	0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x6314, 0x2001,
-+	0x0080, 0x080c, 0x2401, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
-+	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x7093, 0x0028, 0x0040,
-+	0x7093, 0x001e, 0x0028, 0x7093, 0x001d, 0x0010, 0x7093, 0x001f,
-+	0x0005, 0x2001, 0x00a0, 0x080c, 0x2401, 0x6124, 0xd1dc, 0x1138,
-+	0xd1e4, 0x0138, 0x080c, 0x15a1, 0x7093, 0x001e, 0x0010, 0x7093,
-+	0x001d, 0x0005, 0x080c, 0x6205, 0x6124, 0xd1dc, 0x1188, 0x080c,
-+	0x618c, 0x0016, 0x080c, 0x15a1, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
-+	0x0138, 0x7093, 0x001e, 0x0020, 0x7093, 0x001f, 0x080c, 0x618c,
-+	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2401, 0x000e, 0x6124,
-+	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
-+	0x7093, 0x001e, 0x0028, 0x7093, 0x001d, 0x0010, 0x7093, 0x0021,
-+	0x0005, 0x080c, 0x6205, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
-+	0xd1e4, 0x0140, 0x7093, 0x001e, 0x0028, 0x7093, 0x001d, 0x0010,
-+	0x7093, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2401,
-+	0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
-+	0xd1e4, 0x0158, 0x7093, 0x001e, 0x0040, 0x7093, 0x001d, 0x0028,
-+	0x7093, 0x0020, 0x0010, 0x7093, 0x001f, 0x0005, 0x0016, 0x00c6,
-+	0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-+	0x1100, 0x2091, 0x8000, 0x080c, 0x62e4, 0x11f8, 0x2001, 0x110c,
-+	0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c,
-+	0x2340, 0x6024, 0xd0cc, 0x0168, 0x2001, 0x00a0, 0x080c, 0x2401,
-+	0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003, 0x0001,
-+	0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x6300, 0x0150,
-+	0x080c, 0x62f6, 0x1138, 0x2001, 0x0001, 0x080c, 0x1f11, 0x080c,
-+	0x62be, 0x00a0, 0x080c, 0x6202, 0x0178, 0x2001, 0x0001, 0x080c,
-+	0x1f11, 0x7090, 0x9086, 0x001e, 0x0120, 0x7090, 0x9086, 0x0022,
-+	0x1118, 0x7093, 0x0025, 0x0010, 0x7093, 0x0021, 0x012e, 0x00ee,
-+	0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x619d, 0x080c,
-+	0x72bf, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x619d,
-+	0x080c, 0x72b6, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016,
-+	0x080c, 0x85a2, 0x2071, 0x1100, 0x080c, 0x6136, 0x001e, 0x00fe,
-+	0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-+	0x00f6, 0x0126, 0x080c, 0x85a2, 0x2061, 0x0100, 0x2069, 0x0140,
-+	0x2071, 0x1100, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x2011,
-+	0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec, 0x080c,
-+	0x87a2, 0x080c, 0x7271, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e,
-+	0x60e3, 0x0000, 0x080c, 0xc44e, 0x080c, 0xc469, 0x2009, 0x0004,
-+	0x080c, 0x2355, 0x080c, 0x2261, 0x2001, 0x1100, 0x2003, 0x0004,
-+	0x6027, 0x0008, 0x080c, 0x0b68, 0x2001, 0x0001, 0x080c, 0x1f11,
-+	0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
-+	0x0005, 0x0026, 0x00e6, 0x2011, 0x61aa, 0x2071, 0x1317, 0x701c,
-+	0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee,
-+	0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe,
-+	0x9086, 0x00c0, 0x0170, 0x2001, 0x00c0, 0x080c, 0x2401, 0x0156,
-+	0x20a9, 0x002d, 0x1d04, 0x6212, 0x2091, 0x6000, 0x1f04, 0x6212,
-+	0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
-+	0x0140, 0x2071, 0x1100, 0x2001, 0x12a8, 0x200c, 0x9186, 0x0000,
-+	0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, 0x0158, 0x9186,
-+	0x0003, 0x0158, 0x0804, 0x62ac, 0x7093, 0x0022, 0x0040, 0x7093,
-+	0x0021, 0x0028, 0x7093, 0x0023, 0x0010, 0x7093, 0x0024, 0x60e3,
-+	0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x1fb8, 0x0026,
-+	0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec,
-+	0x080c, 0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e, 0x002e,
-+	0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
-+	0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
-+	0xd0ac, 0x0120, 0x012e, 0x015e, 0x0804, 0x62ba, 0x6800, 0x9084,
-+	0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2340, 0x6904, 0xd1d4, 0x1140,
-+	0x2001, 0x0100, 0x080c, 0x2401, 0x1f04, 0x6267, 0x080c, 0x633e,
-+	0x012e, 0x015e, 0x080c, 0x62f6, 0x01a8, 0x6044, 0x9005, 0x0168,
-+	0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x633e, 0x9006,
-+	0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110,
-+	0x080c, 0x633e, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
-+	0x2009, 0x00c8, 0x2011, 0x61aa, 0x080c, 0x7283, 0x002e, 0x001e,
-+	0x2001, 0x12a8, 0x2003, 0x0004, 0x080c, 0x6007, 0x080c, 0x62f6,
-+	0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0x12a8,
-+	0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-+	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1100, 0x2001,
-+	0x12a7, 0x2003, 0x0000, 0x2001, 0x1298, 0x2003, 0x0000, 0x9006,
-+	0x7092, 0x60e2, 0x6886, 0x080c, 0x1fb8, 0x9006, 0x080c, 0x2401,
-+	0x6043, 0x0090, 0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f,
-+	0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x12a7, 0x2004,
-+	0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x2001, 0x1172, 0x2004,
-+	0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x2001,
-+	0x1172, 0x2004, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005,
-+	0x0006, 0x2001, 0x1172, 0x2004, 0x9084, 0x0030, 0x9086, 0x0010,
-+	0x000e, 0x0005, 0x0006, 0x2001, 0x1172, 0x2004, 0x9084, 0x0030,
-+	0x9086, 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x110c,
-+	0x2004, 0x908c, 0x0013, 0x0190, 0x9084, 0x0011, 0x0120, 0x080c,
-+	0x1fd8, 0x900e, 0x0028, 0x080c, 0x58c6, 0x1dc8, 0x2009, 0x0002,
-+	0x2019, 0x0028, 0x080c, 0x2831, 0x9006, 0x0019, 0x001e, 0x003e,
-+	0x0005, 0x00e6, 0x2071, 0x110c, 0x2e04, 0x0118, 0x9085, 0x0010,
-+	0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006,
-+	0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006,
-+	0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052,
-+	0x613a, 0x20a9, 0x0012, 0x1d04, 0x6353, 0x2091, 0x6000, 0x1f04,
-+	0x6353, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400,
-+	0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f,
-+	0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
-+	0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
-+	0x1fb8, 0x2001, 0x00a0, 0x080c, 0x2401, 0x000e, 0x6052, 0x0005,
-+	0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
-+	0x0100, 0x2069, 0x0140, 0x2071, 0x1100, 0x6020, 0x9084, 0x0080,
-+	0x0138, 0x2001, 0x110c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x63fc,
-+	0x2001, 0x110c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff,
-+	0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2401, 0x20a9,
-+	0x0366, 0x6024, 0xd0cc, 0x1510, 0x1d04, 0x63a9, 0x2091, 0x6000,
-+	0x1f04, 0x63a9, 0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002,
-+	0x080c, 0x88ec, 0x080c, 0x87a2, 0x901e, 0x080c, 0x8847, 0x2001,
-+	0x00a0, 0x080c, 0x2401, 0x2001, 0x12a8, 0x2003, 0x0001, 0x2001,
-+	0x1100, 0x2003, 0x0001, 0x9085, 0x0001, 0x0470, 0x86ff, 0x1110,
-+	0x080c, 0x15a1, 0x60e3, 0x0000, 0x2001, 0x1298, 0x2004, 0x080c,
-+	0x1fb8, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2401, 0x20a9, 0x0366,
-+	0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2340, 0x6024, 0x910c,
-+	0x0138, 0x1d04, 0x63e0, 0x2091, 0x6000, 0x1f04, 0x63e0, 0x0810,
-+	0x6028, 0x9085, 0x1e00, 0x602a, 0x70ac, 0x9005, 0x1118, 0x6887,
-+	0x0001, 0x0008, 0x6886, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e,
-+	0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
-+	0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1100, 0x2069,
-+	0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904,
-+	0x6458, 0x2001, 0x0088, 0x080c, 0x2401, 0x9006, 0x60e2, 0x6886,
-+	0x080c, 0x1fb8, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
-+	0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x6027, 0x0400,
-+	0x2069, 0x12c9, 0x7000, 0x206a, 0x7093, 0x0026, 0x7003, 0x0001,
-+	0x20a9, 0x0002, 0x1d04, 0x643a, 0x2091, 0x6000, 0x1f04, 0x643a,
-+	0x0804, 0x648a, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00,
-+	0x2009, 0x1e00, 0x080c, 0x2340, 0x6024, 0x910c, 0x0528, 0x9084,
-+	0x1a00, 0x1510, 0x1d04, 0x6446, 0x2091, 0x6000, 0x1f04, 0x6446,
-+	0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c, 0x88ec,
-+	0x080c, 0x87a2, 0x901e, 0x080c, 0x8847, 0x2001, 0x00a0, 0x080c,
-+	0x2401, 0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003,
-+	0x0001, 0x9085, 0x0001, 0x00b0, 0x2001, 0x0080, 0x080c, 0x2401,
-+	0x2069, 0x0140, 0x60e3, 0x0000, 0x70ac, 0x9005, 0x1118, 0x6887,
-+	0x0001, 0x0008, 0x6886, 0x2001, 0x1298, 0x2004, 0x080c, 0x1fb8,
-+	0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
-+	0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-+	0x00e6, 0x2061, 0x0100, 0x2071, 0x1100, 0x6020, 0x9084, 0x00c0,
-+	0x01e8, 0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c,
-+	0x88ec, 0x080c, 0x87a2, 0x901e, 0x080c, 0x8847, 0x2069, 0x0140,
-+	0x2001, 0x00a0, 0x080c, 0x2401, 0x2001, 0x12a8, 0x2003, 0x0001,
-+	0x2001, 0x1100, 0x2003, 0x0001, 0x0804, 0x6529, 0x2001, 0x110c,
-+	0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x6192, 0x2069,
-+	0x0140, 0x2001, 0x0080, 0x080c, 0x2401, 0x60e3, 0x0000, 0x2069,
-+	0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0180, 0x6028,
-+	0x9084, 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0x12c9, 0x7000,
-+	0x206a, 0x7093, 0x0027, 0x7003, 0x0001, 0x0804, 0x6529, 0x6027,
-+	0x1e00, 0x2009, 0x1e00, 0x080c, 0x2340, 0x6024, 0x910c, 0x01c8,
-+	0x9084, 0x1c00, 0x11b0, 0x1d04, 0x64e7, 0x0006, 0x0016, 0x00c6,
-+	0x00d6, 0x00e6, 0x080c, 0x715a, 0x00ee, 0x00de, 0x00ce, 0x001e,
-+	0x000e, 0x00e6, 0x2071, 0x1317, 0x7018, 0x00ee, 0x9005, 0x19f8,
-+	0x0500, 0x0026, 0x2011, 0x61aa, 0x080c, 0x71fa, 0x2011, 0x619d,
-+	0x080c, 0x72bf, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70ac,
-+	0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x1298,
-+	0x2004, 0x080c, 0x1fb8, 0x60e2, 0x2001, 0x110c, 0x200c, 0xc1b4,
-+	0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
-+	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6,
-+	0x2061, 0x0100, 0x2071, 0x1100, 0x7130, 0xd184, 0x1170, 0x080c,
-+	0x2987, 0x0138, 0xc18d, 0x7132, 0x2011, 0x1153, 0x2214, 0xd2ac,
-+	0x1120, 0x7030, 0xd08c, 0x0904, 0x658f, 0x2011, 0x1153, 0x220c,
-+	0xd1a4, 0x0528, 0x0016, 0x2019, 0x000e, 0x080c, 0xc0b9, 0x0156,
-+	0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080,
-+	0x0188, 0x080c, 0x5608, 0x1170, 0x8127, 0x9006, 0x0016, 0x2009,
-+	0x000e, 0x080c, 0xc12f, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-+	0x73af, 0x001e, 0x8108, 0x1f04, 0x655b, 0x015e, 0x001e, 0xd1ac,
-+	0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x2831,
-+	0x001e, 0x0068, 0x0156, 0x20a9, 0x007f, 0x900e, 0x080c, 0x5608,
-+	0x1110, 0x080c, 0x5100, 0x8108, 0x1f04, 0x6586, 0x015e, 0x080c,
-+	0x15a1, 0x2011, 0x0003, 0x080c, 0x88e2, 0x2011, 0x0002, 0x080c,
-+	0x88ec, 0x080c, 0x87a2, 0x0036, 0x901e, 0x080c, 0x8847, 0x003e,
-+	0x60e3, 0x0000, 0x2001, 0x1100, 0x2003, 0x0001, 0x080c, 0x621a,
-+	0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
-+	0x2071, 0x120c, 0x7003, 0x0000, 0x7007, 0x0000, 0x708f, 0x0000,
-+	0x7093, 0x0001, 0x70c7, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040,
-+	0x6848, 0x9005, 0x1120, 0x9085, 0x0001, 0x0804, 0x660e, 0x6840,
-+	0x9005, 0x01d8, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011,
-+	0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
-+	0x3e08, 0x1f04, 0x65ce, 0x015e, 0x6a50, 0x9200, 0x7002, 0x6854,
-+	0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854,
-+	0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110,
-+	0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e,
-+	0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c,
-+	0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x120c,
-+	0x6807, 0x0001, 0x00de, 0x080c, 0x6b26, 0x9006, 0x00ee, 0x0005,
-+	0x2079, 0x0040, 0x2071, 0x120c, 0x7004, 0x0002, 0x6620, 0x6621,
-+	0x6bb3, 0x66b3, 0x67a9, 0x661e, 0x661e, 0x67d2, 0x080c, 0x0d7e,
-+	0x0005, 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x6bb4,
-+	0xd0a4, 0x0508, 0x7824, 0xc0d4, 0x8006, 0x8006, 0x806f, 0x9006,
-+	0x6802, 0x6806, 0x6864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x12c0,
-+	0x04d3, 0x2001, 0x1100, 0x200c, 0x9186, 0x0003, 0x1160, 0x7104,
-+	0x9186, 0x0004, 0x0140, 0x9186, 0x0007, 0x0128, 0x9186, 0x0003,
-+	0x19d0, 0x080c, 0x66b3, 0x782c, 0xd09c, 0x090c, 0x6b26, 0x0005,
-+	0x9082, 0x005a, 0x1218, 0x2100, 0x0023, 0x0c18, 0x080c, 0x66ec,
-+	0x0c90, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x670e, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66f8, 0x66ec, 0x688e,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66f8, 0x68cf, 0x6910,
-+	0x6957, 0x696b, 0x66ec, 0x66ec, 0x670e, 0x66f8, 0x66ec, 0x66ec,
-+	0x6782, 0x6a16, 0x6a31, 0x66ec, 0x670e, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x6778, 0x6a31, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x6722, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x6b59, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x66ec, 0x6736, 0x66ec, 0x66ec, 0x66ec,
-+	0x66ec, 0x66ec, 0x66ec, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
-+	0x11b0, 0x782c, 0x080c, 0x6b52, 0xd0a4, 0x0188, 0x7824, 0xc0d4,
-+	0x8006, 0x8006, 0x806f, 0x9006, 0x6802, 0x6806, 0x6864, 0x9084,
-+	0x00ff, 0x908a, 0x001a, 0x1210, 0x002b, 0x0c38, 0x00e9, 0x080c,
-+	0x6b26, 0x0005, 0x66ec, 0x66f8, 0x687a, 0x66ec, 0x66f8, 0x66ec,
-+	0x66f8, 0x66f8, 0x66ec, 0x66f8, 0x687a, 0x66f8, 0x66f8, 0x66f8,
-+	0x66f8, 0x66f8, 0x66ec, 0x66f8, 0x687a, 0x66ec, 0x66ec, 0x66f8,
-+	0x66ec, 0x66ec, 0x66ec, 0x66f8, 0x00e6, 0x2071, 0x120c, 0x2009,
-+	0x0400, 0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, 0x0005,
-+	0x2009, 0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009, 0x0005,
-+	0x7007, 0x0001, 0x6868, 0x9084, 0x00ff, 0x9105, 0x686a, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x0005, 0x6864, 0x8007,
-+	0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
-+	0x683b, 0x7007, 0x0003, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b,
-+	0x683b, 0x0005, 0x6864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001,
-+	0x1120, 0x7007, 0x0001, 0x0804, 0x6853, 0x7007, 0x0003, 0x7012,
-+	0x2d00, 0x7016, 0x701a, 0x704b, 0x6853, 0x0005, 0x6864, 0x8007,
-+	0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x66f4, 0x7007, 0x0001,
-+	0x2009, 0x1133, 0x210c, 0x81ff, 0x11a8, 0x6868, 0x9084, 0x00ff,
-+	0x686a, 0x6883, 0x0000, 0x080c, 0x52f4, 0x1108, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x6867, 0x0139, 0x687a, 0x6982, 0x080c, 0x5b76,
-+	0x012e, 0x0ca0, 0x6994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064,
-+	0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186,
-+	0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8,
-+	0x6897, 0x4005, 0x689b, 0x0001, 0x2001, 0x0030, 0x900e, 0x08b8,
-+	0x687c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001,
-+	0x0804, 0x6a48, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0x20e1,
-+	0x0001, 0x20e9, 0x0001, 0x9080, 0x0030, 0x2098, 0x20a1, 0x1239,
-+	0x4003, 0x6888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x66fc, 0x6ab4,
-+	0x928a, 0x0002, 0x1a04, 0x66fc, 0x82ff, 0x1138, 0x68b8, 0x69bc,
-+	0x9105, 0x0118, 0x2001, 0x680e, 0x0018, 0x9280, 0x6804, 0x2005,
-+	0x70ce, 0x7010, 0x9015, 0x0904, 0x67f0, 0x080c, 0x0e9d, 0x1118,
-+	0x7007, 0x0004, 0x0005, 0x2d00, 0x7022, 0x70cc, 0x2060, 0xe000,
-+	0x6866, 0xe004, 0x9d00, 0x709e, 0x709b, 0x0001, 0xe008, 0x920a,
-+	0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296,
-+	0x0004, 0x0108, 0x9108, 0x71a2, 0x810b, 0x71a6, 0x9e90, 0x0023,
-+	0x080c, 0x0f22, 0x7094, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200,
-+	0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2068, 0x080c, 0x0ecf,
-+	0x7014, 0x2068, 0x0804, 0x66fc, 0x7020, 0x2068, 0x7018, 0x6802,
-+	0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x67a9,
-+	0x7014, 0x2068, 0x7007, 0x0001, 0x68b4, 0x9005, 0x1128, 0x68b8,
-+	0x69bc, 0x9105, 0x0108, 0x00b1, 0x6864, 0x9084, 0x00ff, 0x9086,
-+	0x001e, 0x0904, 0x6a48, 0x04b8, 0x6806, 0x680a, 0x0002, 0x001d,
-+	0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d,
-+	0x0005, 0x0004, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6fb8,
-+	0x6ebc, 0x6804, 0x2060, 0x9cf0, 0x002d, 0x9cf8, 0x0033, 0x2009,
-+	0x0005, 0x700c, 0x7816, 0x7008, 0x7812, 0x7004, 0x7806, 0x7000,
-+	0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0128, 0x9ef2, 0x0004, 0x9ffa,
-+	0x0006, 0x0c78, 0x6004, 0x9065, 0x1d30, 0x006e, 0x007e, 0x00ce,
-+	0x00ee, 0x00fe, 0x0005, 0x2009, 0x1133, 0x210c, 0x81ff, 0x1178,
-+	0x080c, 0x5151, 0x1108, 0x0005, 0x080c, 0x5d95, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0xac01, 0x080c, 0x5b76, 0x012e, 0x0ca0, 0x2001,
-+	0x0028, 0x900e, 0x0c88, 0x2009, 0x1133, 0x210c, 0x81ff, 0x11d8,
-+	0x6888, 0x9005, 0x01e0, 0x6883, 0x0000, 0x687c, 0xd0f4, 0x0120,
-+	0x080c, 0x5250, 0x1138, 0x0005, 0x9006, 0x687a, 0x080c, 0x51e5,
-+	0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0x687a, 0x6982, 0x080c,
-+	0x5b76, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001,
-+	0x0000, 0x0c80, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
-+	0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003, 0x0030, 0x7014,
-+	0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, 0x0001,
-+	0x6974, 0x810f, 0x918c, 0x00ff, 0x6878, 0x9084, 0x00ff, 0x20a9,
-+	0x0001, 0x9096, 0x0001, 0x01a8, 0x900e, 0x20a9, 0x00ff, 0x9096,
-+	0x0002, 0x0178, 0x9005, 0x11f0, 0x6974, 0x810f, 0x918c, 0x00ff,
-+	0x080c, 0x5608, 0x11b8, 0x0066, 0x6e80, 0x080c, 0x5703, 0x006e,
-+	0x0088, 0x0046, 0x2011, 0x110c, 0x2224, 0xc484, 0x2412, 0x004e,
-+	0x00c6, 0x080c, 0x5608, 0x1110, 0x080c, 0x57c6, 0x8108, 0x1f04,
-+	0x68b9, 0x00ce, 0x687c, 0xd084, 0x1118, 0x080c, 0x0ecf, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x0005, 0x0126,
-+	0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x58cb, 0x0580, 0x2061,
-+	0x1354, 0x6100, 0xd184, 0x0178, 0x6888, 0x9084, 0x00ff, 0x1550,
-+	0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003, 0x0000,
-+	0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0x6890, 0x9005, 0x1110,
-+	0x2001, 0x001e, 0x8000, 0x6016, 0x6888, 0x9084, 0x00ff, 0x0178,
-+	0x6006, 0x6888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, 0x6888,
-+	0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x6b10, 0x012e,
-+	0x0804, 0x6b0a, 0x012e, 0x0804, 0x6b04, 0x012e, 0x0804, 0x6b07,
-+	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x58cb, 0x05e0,
-+	0x2061, 0x1354, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c,
-+	0x1530, 0x6c78, 0x9484, 0x0003, 0x0170, 0x6988, 0x918c, 0x00ff,
-+	0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001, 0x1508,
-+	0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0x6988, 0x810f,
-+	0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318, 0x0288,
-+	0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250, 0x6890,
-+	0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804,
-+	0x6b10, 0x012e, 0x0804, 0x6b0d, 0x012e, 0x0804, 0x6b0a, 0x0126,
-+	0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1354, 0x6300, 0xd38c,
-+	0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x6b1e,
-+	0x012e, 0x0804, 0x6b0d, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007,
-+	0x0001, 0x687c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1354, 0x6000,
-+	0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0x6888, 0x9005, 0x05c8,
-+	0x688c, 0x9065, 0x0590, 0x2001, 0x1133, 0x2004, 0x9005, 0x0118,
-+	0x080c, 0x8f09, 0x0068, 0x6017, 0x0400, 0x605b, 0x0000, 0x697c,
-+	0xd1a4, 0x0110, 0x6980, 0x615a, 0x2009, 0x0041, 0x080c, 0x8f53,
-+	0x6988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e,
-+	0x2011, 0xfdff, 0x080c, 0x73af, 0x002e, 0x687c, 0xd0c4, 0x0148,
-+	0x2061, 0x1354, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208,
-+	0x600a, 0x00ce, 0x012e, 0x0804, 0x6b10, 0x00ce, 0x012e, 0x0804,
-+	0x6b0a, 0x6984, 0x9186, 0x002e, 0x0d40, 0x9186, 0x002d, 0x0d28,
-+	0x9186, 0x0045, 0x0528, 0x9186, 0x002a, 0x1130, 0x2001, 0x110c,
-+	0x200c, 0xc194, 0x2102, 0x08c8, 0x9186, 0x0020, 0x0170, 0x9186,
-+	0x0029, 0x1d18, 0x6974, 0x918c, 0xff00, 0x810f, 0x080c, 0x5608,
-+	0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x688c, 0x9065, 0x09a8,
-+	0x6007, 0x0024, 0x2001, 0x12c0, 0x2004, 0x601a, 0x0804, 0x69a5,
-+	0x688c, 0x9065, 0x0950, 0x00e6, 0x6890, 0x9075, 0x2001, 0x1133,
-+	0x2004, 0x9005, 0x0150, 0x080c, 0x8f09, 0x8eff, 0x0118, 0x2e60,
-+	0x080c, 0x8f09, 0x00ee, 0x0804, 0x69a5, 0x6024, 0xc0dc, 0xc0d5,
-+	0x6026, 0x2e60, 0x6007, 0x003a, 0x68a0, 0x9005, 0x0130, 0x6007,
-+	0x003b, 0x68a4, 0x602e, 0x68a8, 0x6016, 0x6003, 0x0001, 0x080c,
-+	0x756e, 0x080c, 0x7aa4, 0x00ee, 0x0804, 0x69a5, 0x2061, 0x1354,
-+	0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x6b1e, 0x0126, 0x2091,
-+	0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x6b1e,
-+	0x012e, 0x6883, 0x0016, 0x0804, 0x6b17, 0x6883, 0x0007, 0x0804,
-+	0x6b17, 0x6864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138,
-+	0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x66f4, 0x0040, 0x7007,
-+	0x0003, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x6a48, 0x0005,
-+	0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1100, 0x61cc,
-+	0x81ff, 0x1904, 0x6aca, 0x6130, 0xd194, 0x1904, 0x6af4, 0x6878,
-+	0x2070, 0x9e82, 0x15c0, 0x0a04, 0x6abe, 0x6060, 0x9e02, 0x1a04,
-+	0x6abe, 0x7120, 0x9186, 0x0006, 0x1904, 0x6aad, 0x7010, 0x9005,
-+	0x0904, 0x6aca, 0x2004, 0xd0e4, 0x1904, 0x6aef, 0x2061, 0x1354,
-+	0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x1590, 0x7024, 0xd0dc,
-+	0x1904, 0x6af7, 0x6883, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7014,
-+	0x9005, 0x1198, 0x7116, 0x687c, 0xd0f4, 0x1904, 0x6afa, 0x2001,
-+	0x1153, 0x2004, 0xd09c, 0x1118, 0x687c, 0xc0cc, 0x687e, 0x2e60,
-+	0x080c, 0x72d9, 0x012e, 0x00ee, 0x0005, 0x2068, 0x6800, 0x9005,
-+	0x1de0, 0x6902, 0x2168, 0x687c, 0xd0f4, 0x1904, 0x6afa, 0x012e,
-+	0x00ee, 0x0005, 0x012e, 0x00ee, 0x6883, 0x0006, 0x0804, 0x6b17,
-+	0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6974, 0x918c, 0xff00,
-+	0x810f, 0x080c, 0x5608, 0x15d8, 0x6000, 0xd0e4, 0x15c0, 0x7120,
-+	0x9186, 0x0007, 0x1118, 0x6883, 0x0002, 0x0498, 0x6883, 0x0008,
-+	0x0480, 0x6883, 0x000e, 0x0468, 0x6883, 0x0017, 0x0450, 0x6883,
-+	0x0035, 0x0438, 0x2001, 0x1172, 0x2004, 0xd0fc, 0x01e8, 0x6878,
-+	0x2070, 0x9e82, 0x15c0, 0x02c0, 0x6060, 0x9e02, 0x12a8, 0x7120,
-+	0x9186, 0x0006, 0x1188, 0x7010, 0x9005, 0x0170, 0x2004, 0xd0bc,
-+	0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x6a53,
-+	0x7003, 0x0002, 0x0804, 0x6a53, 0x6883, 0x0028, 0x0010, 0x6883,
-+	0x0029, 0x012e, 0x00ee, 0x0418, 0x6883, 0x002a, 0x0cd0, 0x6883,
-+	0x0045, 0x0cb8, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c,
-+	0xbd23, 0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009,
-+	0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010,
-+	0x2009, 0x0001, 0x6884, 0x9084, 0xff00, 0x9105, 0x6886, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x0005, 0x080c, 0x0ecf,
-+	0x0005, 0x00d6, 0x080c, 0x72d0, 0x00de, 0x0005, 0x00d6, 0x00e6,
-+	0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01f0,
-+	0x908c, 0x0780, 0x190c, 0x6bb4, 0xd09c, 0x11c0, 0x2071, 0x1100,
-+	0x70bc, 0x90ea, 0x0010, 0x0290, 0x8001, 0x70be, 0x702c, 0x2068,
-+	0x2d04, 0x702e, 0x9006, 0x206a, 0x6806, 0x2071, 0x0040, 0x8d07,
-+	0x8005, 0x8005, 0xc0d5, 0x7022, 0x702c, 0x0c10, 0x012e, 0x00ee,
-+	0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x6bb4, 0x000e,
-+	0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x7007, 0x0001,
-+	0x6a74, 0x9282, 0x0004, 0x1a04, 0x6ba4, 0x697c, 0x9188, 0x1000,
-+	0x2104, 0x9065, 0x6004, 0xd284, 0x0140, 0x05e0, 0x8007, 0x9084,
-+	0x00ff, 0x9084, 0x0006, 0x1108, 0x04a8, 0x2c10, 0x080c, 0x8e83,
-+	0x1118, 0x080c, 0x8f26, 0x05a0, 0x6212, 0x6874, 0x0002, 0x6b83,
-+	0x6b88, 0x6b8b, 0x6b91, 0x2019, 0x0002, 0x080c, 0xc0b9, 0x0060,
-+	0x080c, 0xc05a, 0x0048, 0x2019, 0x0002, 0x6980, 0x080c, 0xc072,
-+	0x0018, 0x6980, 0x080c, 0xc05a, 0x080c, 0x8ed9, 0x6887, 0x0000,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x001e, 0x002e,
-+	0x003e, 0x00ce, 0x00de, 0x0005, 0x6887, 0x0006, 0x0c88, 0x6887,
-+	0x0002, 0x0c70, 0x6887, 0x0005, 0x0c58, 0x6887, 0x0004, 0x0c40,
-+	0x6887, 0x0007, 0x0c28, 0x0005, 0x2011, 0x8003, 0x080c, 0x3f23,
-+	0x0cf8, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c,
-+	0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120,
-+	0x080c, 0x12a2, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020,
-+	0x2001, 0x0307, 0x2003, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c,
-+	0x05d8, 0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1508, 0x9484, 0x7000,
-+	0x0138, 0x908a, 0x2000, 0x1258, 0x9584, 0x0700, 0x8007, 0x0498,
-+	0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0db0, 0x00b0, 0x9484,
-+	0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11b0,
-+	0x080c, 0xc426, 0x080c, 0x709e, 0x7817, 0x0140, 0x0098, 0x9584,
-+	0x0076, 0x1118, 0x080c, 0x70fb, 0x19c8, 0xd5a4, 0x0138, 0x0046,
-+	0x0056, 0x080c, 0x1a74, 0x005e, 0x004e, 0x0020, 0x080c, 0xc426,
-+	0x7817, 0x0140, 0x080c, 0x6c56, 0x2001, 0x130d, 0x2004, 0x9005,
-+	0x090c, 0x7aa4, 0x0005, 0x0002, 0x6c2d, 0x6eb5, 0x6c24, 0x6c24,
-+	0x6c24, 0x6c24, 0x6c24, 0x6c24, 0x7817, 0x0140, 0x2001, 0x130d,
-+	0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005, 0x7000, 0x908c, 0xff00,
-+	0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x688a, 0x9286, 0x2000,
-+	0x1148, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x483b, 0x0068,
-+	0x0451, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x6e02, 0x0028,
-+	0x9286, 0x8000, 0x1110, 0x080c, 0x6fc8, 0x7817, 0x0140, 0x2001,
-+	0x130d, 0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005, 0x2001, 0x110f,
-+	0x2004, 0xd08c, 0x0178, 0x2001, 0x1100, 0x2004, 0x9086, 0x0003,
-+	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x3f23,
-+	0x003e, 0x002e, 0x0005, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007,
-+	0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x6dd3, 0x9186,
-+	0x0023, 0x1550, 0x080c, 0x7061, 0x0904, 0x6dd3, 0x7124, 0x610a,
-+	0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0x8f53,
-+	0x0804, 0x6dd3, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130,
-+	0x2009, 0x0015, 0x080c, 0x8f53, 0x0804, 0x6dd3, 0x908e, 0x0100,
-+	0x1904, 0x6dd3, 0x7034, 0x9005, 0x1904, 0x6dd3, 0x2009, 0x0016,
-+	0x080c, 0x8f53, 0x0804, 0x6dd3, 0x9186, 0x0022, 0x1904, 0x6dd3,
-+	0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528, 0xc0b5,
-+	0x68da, 0x7100, 0x918c, 0x00ff, 0x6976, 0x7004, 0x687a, 0x00f6,
-+	0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016,
-+	0x2008, 0x080c, 0x1f8d, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe,
-+	0x080c, 0x1f63, 0x6956, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086,
-+	0x2071, 0x1100, 0x70ae, 0x00ee, 0x7034, 0x9005, 0x1904, 0x6dd3,
-+	0x2009, 0x0017, 0x0804, 0x6d92, 0x908e, 0x0400, 0x1158, 0x7034,
-+	0x9005, 0x1904, 0x6dd3, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030,
-+	0x0804, 0x6d92, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
-+	0x6dd3, 0x2009, 0x0018, 0x0804, 0x6d92, 0x908e, 0x2010, 0x1120,
-+	0x2009, 0x0019, 0x0804, 0x6d92, 0x908e, 0x2110, 0x1120, 0x2009,
-+	0x001a, 0x0804, 0x6d92, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
-+	0x1904, 0x6dd3, 0x2009, 0x001b, 0x0804, 0x6d92, 0x908e, 0x5000,
-+	0x1140, 0x7034, 0x9005, 0x1904, 0x6dd3, 0x2009, 0x001c, 0x0804,
-+	0x6d92, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x6d92,
-+	0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x6dd3, 0x2009,
-+	0x0024, 0x0804, 0x6d92, 0x908c, 0xff00, 0x918e, 0x2400, 0x1120,
-+	0x2009, 0x002d, 0x0804, 0x6d92, 0x908c, 0xff00, 0x918e, 0x5300,
-+	0x1120, 0x2009, 0x002a, 0x0804, 0x6d92, 0x908e, 0x0f00, 0x1120,
-+	0x2009, 0x0020, 0x0804, 0x6d92, 0x908e, 0x5300, 0x1108, 0x00d8,
-+	0x908e, 0x6104, 0x11c0, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
-+	0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
-+	0x0046, 0x2124, 0x080c, 0x3f23, 0x004e, 0x8108, 0x1f04, 0x6d54,
-+	0x2009, 0x0023, 0x0478, 0x908e, 0x6000, 0x1118, 0x2009, 0x003f,
-+	0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e,
-+	0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118,
-+	0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118,
-+	0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118,
-+	0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6834, 0xd0d4, 0x0110,
-+	0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
-+	0x080c, 0x1f63, 0x15d0, 0x080c, 0x55b3, 0x15b8, 0x6612, 0x6516,
-+	0x86ff, 0x01e8, 0x001e, 0x0016, 0x9186, 0x0017, 0x1158, 0x6874,
-+	0x9606, 0x11a8, 0x6878, 0x9506, 0x9084, 0xff00, 0x1180, 0x6000,
-+	0xc0f5, 0x6002, 0x9186, 0x0046, 0x1150, 0x6874, 0x9606, 0x1138,
-+	0x6878, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x00a0, 0x00c6,
-+	0x080c, 0x8e83, 0x001e, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120,
-+	0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016,
-+	0x001e, 0x080c, 0x8f53, 0x00ce, 0x0005, 0x001e, 0x0ce0, 0x2001,
-+	0x110d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x3f23,
-+	0x00c6, 0x080c, 0x8f26, 0x001e, 0x0d80, 0x6112, 0x6023, 0x0004,
-+	0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186,
-+	0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007,
-+	0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c,
-+	0x75be, 0x0898, 0x080c, 0x297d, 0x1140, 0x7010, 0x9084, 0xff00,
-+	0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00c6, 0x0046,
-+	0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c,
-+	0x7061, 0x0904, 0x6e5f, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200,
-+	0x1140, 0x7034, 0x9005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x8f53,
-+	0x04b0, 0x908e, 0x0100, 0x1598, 0x7034, 0x9005, 0x1580, 0x2009,
-+	0x0016, 0x080c, 0x8f53, 0x0458, 0x9186, 0x0032, 0x1540, 0x7030,
-+	0x908e, 0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263,
-+	0x2204, 0x8211, 0x220c, 0x080c, 0x1f63, 0x11c0, 0x080c, 0x55b3,
-+	0x11a8, 0x6612, 0x6516, 0x00c6, 0x080c, 0x8e83, 0x0170, 0x001e,
-+	0x6112, 0x080c, 0xad70, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
-+	0x080c, 0x8f53, 0x080c, 0x7aa4, 0x0010, 0x00ce, 0x001e, 0x004e,
-+	0x00ce, 0x0005, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696,
-+	0x00ff, 0x11a8, 0x9592, 0xfffc, 0x0290, 0x9596, 0xfffd, 0x1118,
-+	0x2009, 0x007f, 0x04e8, 0x9596, 0xfffe, 0x1118, 0x2009, 0x007e,
-+	0x04b8, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x0488, 0x9016,
-+	0x2019, 0x1136, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x00ff,
-+	0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071,
-+	0x1081, 0x2e1c, 0x93ed, 0x0000, 0x1128, 0x82ff, 0x1170, 0x2410,
-+	0xc2fd, 0x0058, 0x6f10, 0x2600, 0x9706, 0x6814, 0x1120, 0x9546,
-+	0x1110, 0x2408, 0x0068, 0x9745, 0x0d80, 0x8420, 0x8e70, 0x1f04,
-+	0x6e91, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
-+	0x9006, 0x00de, 0x00ee, 0x004e, 0x0005, 0x7000, 0x908c, 0xff00,
-+	0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x130d,
-+	0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005, 0x6ed5, 0x6ed5, 0x6ed5,
-+	0x7073, 0x6ed5, 0x6ede, 0x6f0b, 0x6f9b, 0x6ed5, 0x6ed5, 0x6ed5,
-+	0x6ed5, 0x6ed5, 0x6ed5, 0x6ed5, 0x6ed5, 0x7817, 0x0140, 0x2001,
-+	0x130d, 0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005, 0x7110, 0xd1bc,
-+	0x0508, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11e0, 0x9c8a, 0x15c0,
-+	0x02c8, 0x6860, 0x9c02, 0x12b0, 0x7008, 0x9084, 0x00ff, 0x6110,
-+	0x9188, 0x0004, 0x210c, 0x9106, 0x1168, 0x700c, 0x6110, 0x9188,
-+	0x0005, 0x210c, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046,
-+	0x080c, 0x8f53, 0x7817, 0x0140, 0x2001, 0x130d, 0x2004, 0x9005,
-+	0x090c, 0x7aa4, 0x0005, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x6f71,
-+	0x7110, 0xd1bc, 0x1904, 0x6f71, 0x7108, 0x700c, 0x2028, 0x918c,
-+	0x00ff, 0x2130, 0x9094, 0xff00, 0x15c0, 0x81ff, 0x15b0, 0x9080,
-+	0x298c, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106,
-+	0x0904, 0x6f71, 0x080c, 0x55b3, 0x1904, 0x6f71, 0x6612, 0x6516,
-+	0x6000, 0xd0ec, 0x15f0, 0x6204, 0x9294, 0xff00, 0x8217, 0x9286,
-+	0x0006, 0x1188, 0x00c6, 0x080c, 0x8e83, 0x001e, 0x05e0, 0x6112,
-+	0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044,
-+	0x080c, 0xb7dd, 0x0430, 0x6204, 0x9294, 0x00ff, 0x9286, 0x0006,
-+	0x1140, 0x9295, 0x0600, 0x6206, 0x0c28, 0x190c, 0x6e62, 0x11c8,
-+	0x0888, 0x00c6, 0x080c, 0x8e83, 0x001e, 0x0198, 0x6112, 0x6023,
-+	0x0004, 0x7120, 0x610a, 0x9286, 0x0004, 0x1118, 0x6007, 0x0005,
-+	0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x7817, 0x0140, 0x2001, 0x130d, 0x2004, 0x9005, 0x090c,
-+	0x7aa4, 0x00ce, 0x0005, 0x2001, 0x110d, 0x2004, 0xd0ec, 0x0120,
-+	0x2011, 0x8049, 0x080c, 0x3f23, 0x00c6, 0x080c, 0x8f26, 0x001e,
-+	0x0d40, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156,
-+	0x6017, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x756e,
-+	0x080c, 0x7aa4, 0x08b0, 0x7110, 0xd1bc, 0x0508, 0x7020, 0x2060,
-+	0x9c84, 0x0007, 0x11e0, 0x9c82, 0x15c0, 0x02c8, 0x6860, 0x9c02,
-+	0x12b0, 0x7008, 0x9084, 0x00ff, 0x6110, 0x9188, 0x0004, 0x210c,
-+	0x9106, 0x1168, 0x700c, 0x6110, 0x9188, 0x0005, 0x210c, 0x9106,
-+	0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0x8f53, 0x7817,
-+	0x0140, 0x2001, 0x130d, 0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005,
-+	0x080c, 0x297d, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
-+	0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b,
-+	0x0005, 0x6fdf, 0x6fe0, 0x6fdf, 0x6fdf, 0x7049, 0x7055, 0x0005,
-+	0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x7048, 0x700c,
-+	0x7108, 0x080c, 0x1f63, 0x1904, 0x7048, 0x080c, 0x55b3, 0x1904,
-+	0x7048, 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0x928c,
-+	0x00ff, 0x9186, 0x0004, 0x0118, 0x9186, 0x0006, 0x15c8, 0x00c6,
-+	0x080c, 0x7061, 0x00ce, 0x0904, 0x7048, 0x00c6, 0x080c, 0x8e83,
-+	0x001e, 0x05f0, 0x6112, 0x080c, 0xad70, 0x6023, 0x0002, 0x7120,
-+	0x610a, 0x2009, 0x0088, 0x080c, 0x8f53, 0x0490, 0x928c, 0x00ff,
-+	0x9186, 0x0006, 0x0160, 0x9186, 0x0004, 0x0148, 0x9294, 0xff00,
-+	0x8217, 0x9286, 0x0004, 0x0118, 0x9286, 0x0006, 0x1188, 0x00c6,
-+	0x080c, 0x8e83, 0x001e, 0x01e0, 0x6112, 0x080c, 0xad70, 0x6023,
-+	0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x8f53, 0x0080,
-+	0x00c6, 0x080c, 0x8e83, 0x001e, 0x0158, 0x6112, 0x080c, 0xad70,
-+	0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x8f53,
-+	0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a,
-+	0x2009, 0x0089, 0x080c, 0x8f53, 0x0005, 0x7110, 0xd1bc, 0x0140,
-+	0x0041, 0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x8f53,
-+	0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x15c0,
-+	0x0240, 0x2001, 0x1118, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001,
-+	0x0005, 0x9006, 0x0ce8, 0x7110, 0xd1bc, 0x11f8, 0x7024, 0x2060,
-+	0x9c84, 0x0007, 0x11d0, 0x9c82, 0x15c0, 0x02b8, 0x6860, 0x9c02,
-+	0x12a0, 0x7008, 0x9084, 0x00ff, 0x6110, 0x9188, 0x0004, 0x210c,
-+	0x9106, 0x1158, 0x700c, 0x6110, 0x9188, 0x0005, 0x210c, 0x9106,
-+	0x1120, 0x2009, 0x0051, 0x080c, 0x8f53, 0x7817, 0x0140, 0x2001,
-+	0x130d, 0x2004, 0x9005, 0x090c, 0x7aa4, 0x0005, 0x2031, 0x0105,
-+	0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207,
-+	0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6,
-+	0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05c8, 0x080c,
-+	0x8e83, 0x05b0, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204,
-+	0x8211, 0x220c, 0x080c, 0x1f63, 0x1598, 0x080c, 0x55b3, 0x1580,
-+	0x6612, 0x6516, 0x2c00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xad70,
-+	0x080c, 0x0eb6, 0x0508, 0x2d00, 0x605a, 0x9006, 0x6802, 0x6866,
-+	0x6c6a, 0x9df8, 0x001b, 0x20a9, 0x000e, 0x20e9, 0x0001, 0x20e1,
-+	0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e,
-+	0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4,
-+	0x00fe, 0x00de, 0x00ce, 0x0005, 0x080c, 0x8ed9, 0x006e, 0x0cc0,
-+	0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184,
-+	0xf000, 0x810f, 0x9086, 0x2000, 0x1540, 0x9186, 0x0022, 0x11d0,
-+	0x2001, 0x0111, 0x2004, 0x9005, 0x1510, 0x7030, 0x908e, 0x0400,
-+	0x01f0, 0x908e, 0x6000, 0x01d8, 0x908e, 0x5400, 0x01c0, 0x908e,
-+	0x0300, 0x1138, 0x2009, 0x1136, 0x210c, 0xd18c, 0x1180, 0xd1a4,
-+	0x1170, 0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x7061, 0x0128,
-+	0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085,
-+	0x0001, 0x00ce, 0x0005, 0x2071, 0x1317, 0x7003, 0x0003, 0x700f,
-+	0x0361, 0x9006, 0x701a, 0x7072, 0x7012, 0x7017, 0x15c0, 0x7007,
-+	0x0000, 0x7026, 0x702b, 0x85b8, 0x7032, 0x7037, 0x861b, 0x703b,
-+	0xffff, 0x703f, 0xffff, 0x7042, 0x7047, 0x4719, 0x704a, 0x705b,
-+	0x728c, 0x2001, 0x12aa, 0x2003, 0x0003, 0x2001, 0x12ac, 0x2003,
-+	0x0100, 0x0005, 0x2071, 0x1317, 0x1d04, 0x71e9, 0x2091, 0x6000,
-+	0x700c, 0x8001, 0x700e, 0x1500, 0x2001, 0x1174, 0x2004, 0xd0c4,
-+	0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001,
-+	0x20d1, 0x0000, 0x080c, 0x0d7e, 0x700f, 0x0361, 0x7007, 0x0001,
-+	0x0126, 0x2091, 0x8000, 0x7040, 0x900d, 0x0148, 0x8109, 0x7142,
-+	0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
-+	0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
-+	0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
-+	0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001,
-+	0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184,
-+	0x007f, 0x090c, 0x8696, 0x0010, 0x7034, 0x080f, 0x7038, 0x9005,
-+	0x0118, 0x0310, 0x8001, 0x703a, 0x703c, 0x9005, 0x0118, 0x0310,
-+	0x8001, 0x703e, 0x704c, 0x900d, 0x0168, 0x7048, 0x8001, 0x704a,
-+	0x1148, 0x704b, 0x0009, 0x8109, 0x714e, 0x1120, 0x7150, 0x714e,
-+	0x7058, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7070, 0x900d,
-+	0x0158, 0x706c, 0x8001, 0x706e, 0x1138, 0x706f, 0x0009, 0x8109,
-+	0x7172, 0x1110, 0x7074, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a,
-+	0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f,
-+	0x012e, 0x7004, 0x0002, 0x720f, 0x7210, 0x7228, 0x00e6, 0x2071,
-+	0x1317, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009,
-+	0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1317, 0x701c, 0x9206,
-+	0x1110, 0x701a, 0x701e, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071,
-+	0x1317, 0x6088, 0x9102, 0x0208, 0x618a, 0x00ee, 0x0005, 0x0005,
-+	0x7110, 0x080c, 0x5608, 0x1158, 0x6088, 0x8001, 0x0240, 0x608a,
-+	0x1130, 0x0126, 0x2091, 0x8000, 0x080c, 0x7aa4, 0x012e, 0x8108,
-+	0x9182, 0x00ff, 0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x0005,
-+	0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128,
-+	0x8001, 0x6042, 0x1110, 0x080c, 0xac18, 0x6018, 0x9005, 0x0518,
-+	0x8001, 0x601a, 0x1500, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186,
-+	0x0006, 0x11b8, 0x6014, 0x2068, 0x6884, 0x908a, 0x199a, 0x0288,
-+	0x9082, 0x1999, 0x6886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999,
-+	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x687c, 0x9084, 0x1000,
-+	0x0110, 0x080c, 0xa6b1, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001,
-+	0x45c0, 0x9102, 0x0220, 0x7017, 0x15c0, 0x7007, 0x0000, 0x0005,
-+	0x00e6, 0x2071, 0x1317, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
-+	0x0005, 0x2001, 0x1320, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
-+	0x1317, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1323,
-+	0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1317, 0x711a, 0x721e,
-+	0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x0026, 0x7054, 0x8000,
-+	0x7056, 0x2061, 0x12aa, 0x6008, 0x9086, 0x0000, 0x0158, 0x7068,
-+	0x6036, 0x7064, 0x6032, 0x7060, 0x602e, 0x705c, 0x602a, 0x2c10,
-+	0x080c, 0x0f22, 0x002e, 0x00ce, 0x0005, 0x0006, 0x0016, 0x00c6,
-+	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x715a, 0x015e, 0x00fe,
-+	0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071,
-+	0x1317, 0x7172, 0x7276, 0x706f, 0x0009, 0x00ee, 0x0005, 0x00e6,
-+	0x0006, 0x2071, 0x1317, 0x7074, 0x9206, 0x1110, 0x7072, 0x7076,
-+	0x000e, 0x00ee, 0x0005, 0x00c6, 0x2061, 0x1354, 0x00ce, 0x0005,
-+	0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1354, 0x2060,
-+	0x0005, 0x6884, 0x908a, 0x199a, 0x1630, 0x9005, 0x1150, 0x00c6,
-+	0x2061, 0x1354, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
-+	0x0018, 0x908e, 0xffff, 0x01a8, 0x8003, 0x800b, 0x810b, 0x9108,
-+	0x611a, 0x687c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x735c,
-+	0xd0b4, 0x1160, 0xd0bc, 0x15e0, 0x2009, 0x0006, 0x080c, 0x7386,
-+	0x0005, 0x900e, 0x0c68, 0x2001, 0x1999, 0x08b8, 0xd0fc, 0x0160,
-+	0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x7380, 0x908c,
-+	0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11d0, 0x2009,
-+	0x1174, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043,
-+	0x0804, 0x8f53, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804,
-+	0x8f53, 0x6110, 0x210c, 0xd1ac, 0x0d38, 0x6024, 0xc0cd, 0x6026,
-+	0x0c18, 0xc0d4, 0x6026, 0x6890, 0x602e, 0x688c, 0x6032, 0x08f8,
-+	0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904,
-+	0x7380, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6,
-+	0x2c78, 0x080c, 0x137e, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009,
-+	0x0042, 0x080c, 0x8f53, 0x0005, 0x6110, 0x210c, 0xd1ac, 0x0d70,
-+	0x6124, 0xc1cd, 0x6126, 0x0c50, 0xd0fc, 0x0188, 0x908c, 0x2020,
-+	0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148,
-+	0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0x8f53, 0x0005, 0x00a1,
-+	0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0x8f53, 0x0cb0,
-+	0x6110, 0x210c, 0xd1ac, 0x0d38, 0x6124, 0xc1cd, 0x6126, 0x0c18,
-+	0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x00d6, 0x6014,
-+	0x90ec, 0xf000, 0x0510, 0x2068, 0x6982, 0x6800, 0x6016, 0x9186,
-+	0x0001, 0x1188, 0x697c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158,
-+	0x00c6, 0x2061, 0x1354, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210,
-+	0x0208, 0x6206, 0x00ce, 0x080c, 0x59b8, 0x6014, 0x906d, 0x0076,
-+	0x2039, 0x0000, 0x190c, 0x72d9, 0x007e, 0x00de, 0x0005, 0x0156,
-+	0x00c6, 0x2061, 0x1354, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008,
-+	0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138,
-+	0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006,
-+	0x8004, 0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118, 0x8086,
-+	0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208, 0x9200,
-+	0x1f04, 0x73d1, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, 0x0020,
-+	0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e, 0x003e, 0x012e, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005,
-+	0x0510, 0x911a, 0x1600, 0x8213, 0x2039, 0x0100, 0x273c, 0x97be,
-+	0x0008, 0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x0228, 0x911a,
-+	0x1220, 0x1f04, 0x73fb, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04,
-+	0x73fb, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e,
-+	0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8,
-+	0x0126, 0x2091, 0x2800, 0x2079, 0x1304, 0x012e, 0x00d6, 0x2069,
-+	0x1304, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000,
-+	0x2069, 0x0200, 0x080c, 0x8dc3, 0x0401, 0x080c, 0x8dae, 0x00e9,
-+	0x080c, 0x8db1, 0x00d1, 0x080c, 0x8db4, 0x00b9, 0x080c, 0x8db7,
-+	0x00a1, 0x080c, 0x8dba, 0x0089, 0x080c, 0x8dbd, 0x0071, 0x080c,
-+	0x8dc0, 0x0059, 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04,
-+	0x9085, 0x8001, 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1,
-+	0x0240, 0x9006, 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804,
-+	0x9084, 0x0007, 0x0002, 0x746d, 0x7491, 0x74db, 0x7473, 0x7491,
-+	0x746d, 0x746b, 0x746b, 0x080c, 0x0d7e, 0x080c, 0x7271, 0x080c,
-+	0x7aa4, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005,
-+	0x2011, 0x4f57, 0x080c, 0x71fa, 0x7828, 0x9092, 0x00c8, 0x1228,
-+	0x8000, 0x782a, 0x080c, 0x4f94, 0x0c88, 0x62c0, 0x080c, 0x8dc7,
-+	0x080c, 0x4f57, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000,
-+	0x0c28, 0x080c, 0x7271, 0x6220, 0xd2a4, 0x0178, 0x62c0, 0x82ff,
-+	0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0d7e, 0x2009,
-+	0x0013, 0x080c, 0x8f53, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065,
-+	0x090c, 0x0d7e, 0x7804, 0x9086, 0x0004, 0x0904, 0x7517, 0x7828,
-+	0x9092, 0xc350, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x857e,
-+	0x0c50, 0x2011, 0x0130, 0x2214, 0x080c, 0x8dc7, 0x6104, 0x9186,
-+	0x0003, 0x1188, 0x00e6, 0x2071, 0x1100, 0x70e4, 0x00ee, 0xd08c,
-+	0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1100, 0x080c,
-+	0x4faa, 0x00ee, 0x00ce, 0x080c, 0xc463, 0x2009, 0x0014, 0x080c,
-+	0x8f53, 0x00ce, 0x0840, 0x2001, 0x1320, 0x2003, 0x0000, 0x62c0,
-+	0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0d7e,
-+	0x2009, 0x0013, 0x080c, 0x8fab, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-+	0x7824, 0x9005, 0x090c, 0x0d7e, 0x781c, 0x906d, 0x090c, 0x0d7e,
-+	0x080c, 0x8dc7, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c,
-+	0x8ed9, 0x693c, 0x81ff, 0x090c, 0x0d7e, 0x8109, 0x693e, 0x6854,
-+	0x9015, 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000,
-+	0x7827, 0x0000, 0x00de, 0x00ce, 0x080c, 0x7aa4, 0x08a8, 0x6104,
-+	0x9186, 0x0002, 0x0128, 0x9186, 0x0004, 0x0110, 0x0804, 0x74af,
-+	0x7808, 0x9c06, 0x0904, 0x74af, 0x080c, 0x79ab, 0x080c, 0x75be,
-+	0x00ce, 0x080c, 0x7aa4, 0x0804, 0x74a3, 0x00c6, 0x6024, 0x6027,
-+	0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c,
-+	0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0x8f53, 0x00ce, 0x0005,
-+	0x2011, 0x1323, 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0,
-+	0x7944, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7946, 0x793c, 0x9188,
-+	0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984,
-+	0x9085, 0x0012, 0x6016, 0x0c10, 0x6014, 0x9084, 0x1984, 0x9085,
-+	0x0016, 0x6016, 0x08d8, 0x793c, 0x2160, 0x2009, 0x004a, 0x080c,
-+	0x8f53, 0x08a0, 0x7848, 0xc085, 0x784a, 0x0880, 0x0006, 0x0016,
-+	0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
-+	0x1304, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, 0x9080,
-+	0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
-+	0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x1304, 0x6000, 0xd0d4,
-+	0x01b8, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, 0x2c00,
-+	0x681e, 0x2001, 0x110c, 0x2004, 0xd0fc, 0x0118, 0x00de, 0x0804,
-+	0x7aa4, 0x6804, 0x9084, 0x0007, 0x0804, 0x7abb, 0x00de, 0x0005,
-+	0xc0d5, 0x6002, 0x6818, 0x9005, 0x0158, 0x6056, 0x605b, 0x0000,
-+	0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0x1304, 0x08c8,
-+	0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x0898, 0x0006, 0x0016,
-+	0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
-+	0x1304, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, 0x9080,
-+	0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
-+	0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
-+	0x1304, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x6136,
-+	0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6,
-+	0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016,
-+	0x0006, 0x0126, 0x902e, 0x2071, 0x1304, 0x7638, 0x2660, 0x2678,
-+	0x2091, 0x8000, 0x8cff, 0x0904, 0x7664, 0x6010, 0x9080, 0x0028,
-+	0x2004, 0x9206, 0x1904, 0x765f, 0x87ff, 0x0120, 0x6054, 0x9106,
-+	0x1904, 0x765f, 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001,
-+	0x080c, 0x8847, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046,
-+	0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c,
-+	0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
-+	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
-+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xa942,
-+	0x01c8, 0x6014, 0x2068, 0x6020, 0x9086, 0x0003, 0x1580, 0x6867,
-+	0x0103, 0x6b7a, 0x6877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c,
-+	0xac01, 0x080c, 0xc3c7, 0x080c, 0x5b76, 0x007e, 0x003e, 0x001e,
-+	0x080c, 0xab11, 0x080c, 0x8f09, 0x00ce, 0x0804, 0x7602, 0x2c78,
-+	0x600c, 0x2060, 0x0804, 0x7602, 0x85ff, 0x0120, 0x0036, 0x080c,
-+	0x7b72, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
-+	0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020,
-+	0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, 0xc3c7,
-+	0x080c, 0xc0e9, 0x007e, 0x003e, 0x001e, 0x08a0, 0x6020, 0x9086,
-+	0x000a, 0x0904, 0x7649, 0x0804, 0x7647, 0x0006, 0x0066, 0x00c6,
-+	0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079, 0x1304,
-+	0x7838, 0x9065, 0x0904, 0x76db, 0x600c, 0x0006, 0x600f, 0x0000,
-+	0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0x8847,
-+	0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a, 0x003e,
-+	0x080c, 0xa942, 0x0518, 0x6014, 0x2068, 0x6020, 0x9086, 0x0003,
-+	0x1558, 0x3e08, 0x918e, 0x0002, 0x1180, 0x6010, 0x9005, 0x0168,
-+	0x9080, 0x0000, 0x2004, 0xd0bc, 0x0140, 0x6040, 0x9005, 0x1180,
-+	0x2001, 0x12c2, 0x2004, 0x6042, 0x0058, 0x6867, 0x0103, 0x6b7a,
-+	0x6877, 0x0000, 0x080c, 0x5b76, 0x080c, 0xab11, 0x080c, 0x8f09,
-+	0x000e, 0x0804, 0x7699, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de,
-+	0x00ce, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118,
-+	0x080c, 0xc0e9, 0x0c58, 0x6020, 0x9086, 0x000a, 0x0d00, 0x08e8,
-+	0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c, 0x77c0, 0x008e,
-+	0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x1304, 0x2091,
-+	0x8000, 0x080c, 0x7851, 0x080c, 0x78c5, 0x012e, 0x00fe, 0x0005,
-+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x2071, 0x1304, 0x7614, 0x2660, 0x2678, 0x8cff,
-+	0x0904, 0x7796, 0x6010, 0x9080, 0x0028, 0x2004, 0x9206, 0x1904,
-+	0x7791, 0x88ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x7791, 0x7024,
-+	0x9c06, 0x1550, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0508, 0x080c,
-+	0x7271, 0x080c, 0x85a2, 0x68c3, 0x0000, 0x080c, 0x8a7d, 0x7027,
-+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-+	0x2001, 0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x2069,
-+	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020,
-+	0x6003, 0x0009, 0x630a, 0x04e8, 0x7014, 0x9c36, 0x1110, 0x660c,
-+	0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
-+	0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
-+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2068,
-+	0x080c, 0xa942, 0x01b8, 0x6020, 0x9086, 0x0003, 0x1540, 0x6867,
-+	0x0103, 0x6b7a, 0x6877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c,
-+	0xac01, 0x080c, 0xc3c7, 0x080c, 0x5b76, 0x008e, 0x003e, 0x001e,
-+	0x080c, 0xab11, 0x080c, 0x8f09, 0x080c, 0x895e, 0x00ce, 0x0804,
-+	0x7717, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7717, 0x012e, 0x000e,
-+	0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020,
-+	0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xc3c7,
-+	0x080c, 0xc0e9, 0x008e, 0x003e, 0x001e, 0x08e0, 0x6020, 0x9086,
-+	0x0002, 0x1128, 0x6004, 0x9086, 0x0085, 0x0908, 0x0898, 0x6020,
-+	0x9086, 0x0005, 0x1978, 0x6004, 0x9086, 0x0085, 0x0d20, 0x0850,
-+	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004,
-+	0x9065, 0x0904, 0x784d, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071,
-+	0x1304, 0x6654, 0x7018, 0x9c06, 0x1108, 0x761a, 0x701c, 0x9c06,
-+	0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0x6058,
-+	0x907d, 0x0108, 0x7e56, 0x96ed, 0x0000, 0x0110, 0x2f00, 0x685a,
-+	0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002,
-+	0x080c, 0x554c, 0x0904, 0x7849, 0x7624, 0x86ff, 0x0904, 0x7838,
-+	0x9680, 0x0005, 0x2004, 0x9d06, 0x15d8, 0x00d6, 0x2069, 0x0100,
-+	0x68c0, 0x9005, 0x0560, 0x080c, 0x7271, 0x080c, 0x85a2, 0x68c3,
-+	0x0000, 0x080c, 0x8a7d, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
-+	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2401,
-+	0x9006, 0x080c, 0x2401, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-+	0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0x9005, 0x0110,
-+	0x8001, 0x603e, 0x2660, 0x080c, 0x8f09, 0x00ce, 0x0048, 0x00de,
-+	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x77f0,
-+	0x8dff, 0x0158, 0x6867, 0x0103, 0x6b7a, 0x6877, 0x0000, 0x080c,
-+	0xac01, 0x080c, 0xc3c7, 0x080c, 0x5b76, 0x080c, 0x895e, 0x0804,
-+	0x77f0, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce,
-+	0x0005, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065,
-+	0x0904, 0x78a5, 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06,
-+	0x1558, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0508, 0x080c, 0x7271,
-+	0x080c, 0x85a2, 0x68c3, 0x0000, 0x080c, 0x8a7d, 0x7827, 0x0000,
-+	0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
-+	0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x2069, 0x0100,
-+	0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003,
-+	0x0009, 0x630a, 0x2c30, 0x00b0, 0x6014, 0x2068, 0x080c, 0xa942,
-+	0x0168, 0x6020, 0x9086, 0x0003, 0x11b8, 0x6867, 0x0103, 0x6b7a,
-+	0x6877, 0x0000, 0x080c, 0x5b76, 0x080c, 0xab11, 0x080c, 0x8f09,
-+	0x080c, 0x895e, 0x000e, 0x0804, 0x7857, 0x7e16, 0x7e12, 0x00de,
-+	0x00ce, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118,
-+	0x080c, 0xc0e9, 0x0c58, 0x6020, 0x9086, 0x0002, 0x1128, 0x6004,
-+	0x9086, 0x0085, 0x09d0, 0x0c10, 0x6020, 0x9086, 0x0005, 0x19f0,
-+	0x6004, 0x9086, 0x0085, 0x0d60, 0x08c8, 0x0006, 0x0066, 0x00c6,
-+	0x00d6, 0x7818, 0x9065, 0x0904, 0x7940, 0x6054, 0x0006, 0x9006,
-+	0x6056, 0x605a, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x554c,
-+	0x0904, 0x793d, 0x7e24, 0x86ff, 0x0904, 0x7930, 0x9680, 0x0005,
-+	0x2004, 0x9d06, 0x1904, 0x7930, 0x00d6, 0x2069, 0x0100, 0x68c0,
-+	0x9005, 0x05e8, 0x080c, 0x7271, 0x080c, 0x85a2, 0x68c3, 0x0000,
-+	0x080c, 0x8a7d, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-+	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2401, 0x9006,
-+	0x080c, 0x2401, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-+	0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e, 0x0002, 0x1168,
-+	0x6000, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c, 0x81ff, 0x1508,
-+	0x2009, 0x12c2, 0x210c, 0x2102, 0x00e0, 0x603c, 0x9005, 0x0110,
-+	0x8001, 0x603e, 0x2660, 0x080c, 0x8f09, 0x00ce, 0x0048, 0x00de,
-+	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x78d6,
-+	0x8dff, 0x0138, 0x6867, 0x0103, 0x6b7a, 0x6877, 0x0000, 0x080c,
-+	0x5b76, 0x080c, 0x895e, 0x0804, 0x78d6, 0x000e, 0x0804, 0x78ca,
-+	0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6,
-+	0x00d6, 0x0066, 0x6000, 0xd0dc, 0x01a0, 0x604c, 0x906d, 0x0188,
-+	0x6878, 0x9606, 0x1170, 0x2071, 0x1304, 0x7024, 0x9035, 0x0148,
-+	0x9080, 0x0005, 0x2004, 0x9d06, 0x1120, 0x6000, 0xc0dc, 0x6002,
-+	0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100,
-+	0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
-+	0x00ce, 0x04b8, 0x080c, 0x85a2, 0x78c3, 0x0000, 0x080c, 0x8a7d,
-+	0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000,
-+	0x0138, 0x2001, 0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401,
-+	0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
-+	0x8a7d, 0x003e, 0x080c, 0x554c, 0x00c6, 0x603c, 0x9005, 0x0110,
-+	0x8001, 0x603e, 0x2660, 0x080c, 0x8ed9, 0x00ce, 0x6867, 0x0103,
-+	0x6b7a, 0x6877, 0x0000, 0x080c, 0xac01, 0x080c, 0x5b76, 0x080c,
-+	0x895e, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2001, 0x110c, 0x2014,
-+	0xc2e4, 0x2202, 0x2071, 0x1304, 0x7004, 0x9084, 0x0007, 0x0002,
-+	0x79c2, 0x79c5, 0x79db, 0x7a03, 0x7a40, 0x79c2, 0x79c0, 0x79c0,
-+	0x080c, 0x0d7e, 0x00ce, 0x00ee, 0x0005, 0x7024, 0x9065, 0x0148,
-+	0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0150, 0x7216, 0x600f,
-+	0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
-+	0x7216, 0x7212, 0x0cb0, 0x6010, 0x2060, 0x080c, 0x554c, 0x6000,
-+	0xc0dc, 0x6002, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001,
-+	0x7022, 0x1140, 0x2001, 0x110c, 0x2014, 0xd2ec, 0x1178, 0x00ce,
-+	0x00ee, 0x0005, 0x6054, 0x9015, 0x0120, 0x721e, 0x080c, 0x7aa4,
-+	0x0cb0, 0x7218, 0x721e, 0x080c, 0x7aa4, 0x0c88, 0xc2ec, 0x2202,
-+	0x080c, 0x7b72, 0x0c60, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06,
-+	0x1160, 0x080c, 0x895e, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f,
-+	0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160,
-+	0x080c, 0x895e, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000,
-+	0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198,
-+	0x6010, 0x2060, 0x080c, 0x554c, 0x6000, 0xc0dc, 0x6002, 0x080c,
-+	0x895e, 0x701c, 0x9065, 0x0138, 0x6054, 0x9015, 0x0110, 0x721e,
-+	0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
-+	0x7024, 0x9065, 0x0140, 0x080c, 0x895e, 0x600c, 0x9015, 0x0150,
-+	0x720e, 0x600f, 0x0000, 0x080c, 0x8a7d, 0x7027, 0x0000, 0x00ce,
-+	0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0x1304,
-+	0x6830, 0x9084, 0x0003, 0x0002, 0x7a62, 0x7a64, 0x7a88, 0x7a60,
-+	0x080c, 0x0d7e, 0x00de, 0x0005, 0x00c6, 0x6840, 0x9086, 0x0001,
-+	0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015, 0x0170, 0x6a3a,
-+	0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0x1323,
-+	0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
-+	0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003, 0x0003, 0x0c50,
-+	0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c, 0x9065, 0x0160,
-+	0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
-+	0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0xc1e5,
-+	0x2001, 0x110c, 0x2102, 0x0005, 0x2001, 0x110c, 0x200c, 0xd1ec,
-+	0x0138, 0xc1ec, 0x2102, 0x080c, 0x7b72, 0x2001, 0x110c, 0x200c,
-+	0x9184, 0x0600, 0x9086, 0x0600, 0x0d50, 0x00d6, 0x2069, 0x1304,
-+	0x6804, 0x9084, 0x0007, 0x0002, 0x7ac6, 0x7b51, 0x7b51, 0x7b51,
-+	0x7b51, 0x7b53, 0x7ac4, 0x7ac4, 0x080c, 0x0d7e, 0x6820, 0x9005,
-+	0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0150, 0x6807,
-+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x7bb7, 0x00ce, 0x00de,
-+	0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b,
-+	0x0000, 0x080c, 0x7bb7, 0x00ce, 0x00de, 0x0005, 0x00e6, 0x6a1c,
-+	0x92f5, 0x0000, 0x0904, 0x7b4e, 0x704c, 0x900d, 0x0118, 0x7088,
-+	0x9005, 0x01a0, 0x7054, 0x9075, 0x0120, 0x920e, 0x0904, 0x7b4e,
-+	0x0028, 0x6818, 0x920e, 0x0904, 0x7b4e, 0x2070, 0x704c, 0x900d,
-+	0x0d88, 0x7088, 0x9005, 0x1d70, 0x2e00, 0x681e, 0x733c, 0x7038,
-+	0x9302, 0x1e40, 0x080c, 0x8eb0, 0x0904, 0x7b4e, 0x8318, 0x733e,
-+	0x6116, 0x2e10, 0x6212, 0x9180, 0x0020, 0x2004, 0x9084, 0x00ff,
-+	0x605e, 0x9180, 0x0020, 0x2003, 0x0000, 0x9180, 0x0021, 0x2004,
-+	0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
-+	0x9318, 0x631a, 0x00f6, 0x2c78, 0x2061, 0x0100, 0x609b, 0x0000,
-+	0x00d6, 0x00e6, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x81a1,
-+	0x00ee, 0x00de, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18,
-+	0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807,
-+	0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x00ee, 0x00ce,
-+	0x0cd8, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x0138, 0x6807,
-+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x7bb7, 0x00ce, 0x00de,
-+	0x0005, 0x2001, 0x110c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe,
-+	0x0005, 0x2001, 0x110c, 0x2014, 0xd2e4, 0x0120, 0xc2e4, 0x2202,
-+	0x080c, 0x7ab5, 0x00f6, 0x00d6, 0x2069, 0x1304, 0x6830, 0x9086,
-+	0x0000, 0x11f0, 0x2001, 0x110c, 0x200c, 0xd1c4, 0x11e0, 0x6838,
-+	0x907d, 0x01b0, 0x6a04, 0x9296, 0x0000, 0x19d8, 0x6833, 0x0001,
-+	0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091,
-+	0x2400, 0x002e, 0x080c, 0x167d, 0x1178, 0x012e, 0x080c, 0x83f0,
-+	0x00de, 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x0066, 0x2031, 0x0001,
-+	0x080c, 0x6380, 0x006e, 0x08d8, 0x012e, 0x6843, 0x0000, 0x7803,
-+	0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833,
-+	0x0000, 0x683f, 0x0000, 0x0c20, 0x683a, 0x6836, 0x0cc0, 0x6020,
-+	0x9084, 0x000f, 0x000b, 0x0005, 0x7bcb, 0x7bd0, 0x8097, 0x8157,
-+	0x7bd0, 0x8097, 0x8157, 0x7bcb, 0x7bd0, 0x7bcb, 0x7bcb, 0x7bcb,
-+	0x7bcb, 0x7bcb, 0x7bcb, 0x080c, 0x79ab, 0x080c, 0x7aa4, 0x0005,
-+	0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6,
-+	0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053,
-+	0x1a0c, 0x0d7e, 0x6110, 0x2178, 0x79a0, 0x2011, 0x1136, 0x2214,
-+	0xd2ac, 0x1110, 0xd1bc, 0x0148, 0x7900, 0xd1f4, 0x0120, 0x7914,
-+	0x918c, 0x00ff, 0x0038, 0x900e, 0x0028, 0x91f8, 0x298c, 0x2f0d,
-+	0x918c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040,
-+	0x1a04, 0x7c4f, 0x0053, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
-+	0x01ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x7dc3, 0x7e04, 0x7e33,
-+	0x7ee5, 0x7f08, 0x7f0e, 0x7f1c, 0x7f25, 0x7f32, 0x7f38, 0x7f4a,
-+	0x7f38, 0x7fa1, 0x7f25, 0x7fae, 0x7fb4, 0x7f32, 0x7fb4, 0x7fc1,
-+	0x7c4d, 0x7c4d, 0x7c4d, 0x7c4d, 0x7c4d, 0x7c4d, 0x7c4d, 0x7c4d,
-+	0x7c4d, 0x7c4d, 0x7c4d, 0x86e5, 0x86fc, 0x8707, 0x8728, 0x8757,
-+	0x7f1c, 0x7c4d, 0x7f1c, 0x7f38, 0x7c4d, 0x7e33, 0x7ee5, 0x7c4d,
-+	0x8b65, 0x7f38, 0x7c4d, 0x8b81, 0x7f38, 0x7c4d, 0x7f32, 0x7dbc,
-+	0x7c6f, 0x7c4d, 0x8b98, 0x8c05, 0x8cda, 0x7c4d, 0x8ce7, 0x7f19,
-+	0x8cfd, 0x7c4d, 0x8762, 0x8d37, 0x7c4d, 0x080c, 0x0d7e, 0x2100,
-+	0x0053, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e,
-+	0x013e, 0x015e, 0x0005, 0x7c6d, 0x7c6d, 0x7c6d, 0x7c95, 0x7d39,
-+	0x7d49, 0x7c6d, 0x7c6d, 0x7c6d, 0x7d8e, 0x7d9d, 0x7caf, 0x7c6d,
-+	0x7cc9, 0x7cfa, 0x8de7, 0x8e2c, 0x7f38, 0x080c, 0x0d7e, 0x00d6,
-+	0x080c, 0x7fd5, 0x7003, 0x2414, 0x7007, 0x0018, 0x700b, 0x0800,
-+	0x7814, 0x2068, 0x683c, 0x700e, 0x6850, 0x7022, 0x6854, 0x7026,
-+	0x60c3, 0x0018, 0x080c, 0x8576, 0x00de, 0x0005, 0x00d6, 0x7810,
-+	0x2068, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac, 0x1110, 0xd0bc,
-+	0x0110, 0x9085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x080c, 0x7fd5,
-+	0x7003, 0x0500, 0x7814, 0x90e8, 0x001b, 0x6808, 0x700a, 0x680c,
-+	0x700e, 0x6810, 0x7012, 0x6814, 0x7016, 0x6818, 0x701a, 0x681c,
-+	0x701e, 0x60c3, 0x0010, 0x080c, 0x8576, 0x00de, 0x0005, 0x00d6,
-+	0x080c, 0x7fd5, 0x7003, 0x0500, 0x7814, 0x90e8, 0x0031, 0x6808,
-+	0x700a, 0x680c, 0x700e, 0x6810, 0x7012, 0x6814, 0x7016, 0x6818,
-+	0x701a, 0x681c, 0x701e, 0x60c3, 0x0010, 0x080c, 0x8576, 0x00de,
-+	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x080c, 0x7fd5, 0x20e9,
-+	0x0000, 0x20e1, 0x0001, 0x2001, 0x12dd, 0x2003, 0x0000, 0x7814,
-+	0x2068, 0x6814, 0x8003, 0x60c2, 0x6830, 0x20a8, 0x9d80, 0x001b,
-+	0x2098, 0x2001, 0x12dd, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c,
-+	0x1b4c, 0x080c, 0xb539, 0x9006, 0x080c, 0x1b4c, 0x001e, 0x6804,
-+	0x9005, 0x0110, 0x2068, 0x0c40, 0x04b9, 0x080c, 0x8576, 0x012e,
-+	0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x080c, 0x804b,
-+	0x20e9, 0x0000, 0x20e1, 0x0001, 0x2001, 0x12dd, 0x2003, 0x0000,
-+	0x7814, 0x2068, 0x686f, 0x0200, 0x6873, 0x0000, 0x6814, 0x8003,
-+	0x60c2, 0x6830, 0x20a8, 0x9d80, 0x001b, 0x2098, 0x2001, 0x12dd,
-+	0x0016, 0x200c, 0x080c, 0xb539, 0x001e, 0x6804, 0x9005, 0x0110,
-+	0x2068, 0x0c78, 0x0049, 0x7814, 0x2068, 0x080c, 0x0edf, 0x080c,
-+	0x8576, 0x012e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003,
-+	0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0,
-+	0x0005, 0x080c, 0x7fd5, 0x7003, 0x7800, 0x7007, 0x0000, 0x7808,
-+	0x8007, 0x700a, 0x700f, 0x0000, 0x60c3, 0x0008, 0x080c, 0x8576,
-+	0x0005, 0x00d6, 0x00e6, 0x080c, 0x804b, 0x2073, 0x0200, 0x8e70,
-+	0x2073, 0x0000, 0x8e70, 0x2073, 0xdf10, 0x8e70, 0x2073, 0x0034,
-+	0x8e70, 0x2069, 0x1105, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70,
-+	0x1f04, 0x7d5d, 0x2069, 0x1101, 0x20a9, 0x0004, 0x2d76, 0x8d68,
-+	0x8e70, 0x1f04, 0x7d66, 0x2069, 0x12ea, 0x20a9, 0x001a, 0x9e86,
-+	0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012,
-+	0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70,
-+	0x1f04, 0x7d6f, 0x2073, 0x0000, 0x8e70, 0x2073, 0x0000, 0x60c3,
-+	0x004c, 0x080c, 0x8576, 0x00ee, 0x00de, 0x0005, 0x080c, 0x7fd5,
-+	0x7003, 0x6300, 0x7007, 0x0028, 0x700b, 0x0000, 0x7808, 0x700e,
-+	0x60c3, 0x0008, 0x080c, 0x8576, 0x0005, 0x00d6, 0x0026, 0x0016,
-+	0x080c, 0x804b, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0,
-+	0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073, 0x0800, 0x8e70,
-+	0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0x8576,
-+	0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1116, 0x2004, 0x609a,
-+	0x080c, 0x8576, 0x0005, 0x080c, 0x7fd5, 0x7003, 0x5200, 0x2069,
-+	0x1152, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x1f77,
-+	0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1105,
-+	0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099,
-+	0x1101, 0x20a1, 0x0254, 0x4003, 0x2001, 0x1136, 0x2004, 0xd0ac,
-+	0x1138, 0x7810, 0x9080, 0x0028, 0x2004, 0x9082, 0x007f, 0x0248,
-+	0x2001, 0x111d, 0x2004, 0x7032, 0x2001, 0x111e, 0x2004, 0x7036,
-+	0x0030, 0x2001, 0x1116, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3,
-+	0x001c, 0x080c, 0x8576, 0x0005, 0x080c, 0x7fd5, 0x7003, 0x0500,
-+	0x2001, 0x1136, 0x2004, 0xd0ac, 0x1138, 0x7810, 0x9080, 0x0028,
-+	0x2004, 0x9082, 0x007f, 0x0248, 0x2001, 0x111d, 0x2004, 0x700a,
-+	0x2001, 0x111e, 0x2004, 0x700e, 0x0030, 0x2001, 0x1116, 0x2004,
-+	0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
-+	0x1105, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010,
-+	0x080c, 0x8576, 0x0005, 0x080c, 0x7fd5, 0x00c6, 0x7810, 0x2060,
-+	0x9006, 0x080c, 0x5898, 0x00ce, 0x7810, 0x9080, 0x0028, 0x2004,
-+	0x9086, 0x007e, 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e,
-+	0x0068, 0x7814, 0x00d6, 0x906d, 0x0130, 0x689b, 0x0000, 0x68a7,
-+	0x0000, 0x68ab, 0x0000, 0x00de, 0x7003, 0x0300, 0x7810, 0x9080,
-+	0x0028, 0x2004, 0x9086, 0x007e, 0x1904, 0x7eab, 0x00d6, 0x2069,
-+	0x1297, 0x2001, 0x1136, 0x2004, 0xd0a4, 0x0178, 0x6800, 0x700a,
-+	0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f, 0x2710,
-+	0x6818, 0x7022, 0x681c, 0x7026, 0x0080, 0x6800, 0x700a, 0x6804,
-+	0x700e, 0x6808, 0x080c, 0x62e4, 0x1118, 0x9084, 0x37ff, 0x0010,
-+	0x9084, 0x3fff, 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004,
-+	0x20e1, 0x0001, 0x2099, 0x1105, 0x20e9, 0x0000, 0x20a1, 0x0256,
-+	0x4003, 0x20a9, 0x0004, 0x2099, 0x1101, 0x20a1, 0x025a, 0x4003,
-+	0x00d6, 0x080c, 0x8dae, 0x2069, 0x129f, 0x2071, 0x024e, 0x6800,
-+	0xc0dd, 0x7002, 0x2001, 0x1172, 0x2004, 0xd0e4, 0x0110, 0x680c,
-+	0x700e, 0x00de, 0x04a8, 0x2001, 0x1136, 0x2004, 0xd0a4, 0x0170,
-+	0x0016, 0x2001, 0x1298, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100,
-+	0x60e3, 0x0000, 0x080c, 0x1fb8, 0x61e2, 0x001e, 0x20e1, 0x0001,
-+	0x2099, 0x1297, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008,
-+	0x4003, 0x20a9, 0x0004, 0x2099, 0x1105, 0x20a1, 0x0256, 0x4003,
-+	0x20a9, 0x0004, 0x2099, 0x1101, 0x20a1, 0x025a, 0x4003, 0x080c,
-+	0x8dae, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x129f, 0x4003,
-+	0x60c3, 0x0074, 0x080c, 0x8576, 0x0005, 0x080c, 0x7fd5, 0x7003,
-+	0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006,
-+	0x00f6, 0x2079, 0x1152, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085,
-+	0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6,
-+	0x0804, 0x7f85, 0x7026, 0x60c3, 0x0014, 0x080c, 0x8576, 0x0005,
-+	0x080c, 0x7fd5, 0x7003, 0x5000, 0x0804, 0x7e56, 0x080c, 0x7fd5,
-+	0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x080c, 0x8576,
-+	0x0005, 0x080c, 0x8042, 0x0010, 0x080c, 0x804b, 0x7003, 0x0200,
-+	0x60c3, 0x0004, 0x080c, 0x8576, 0x0005, 0x080c, 0x804b, 0x7003,
-+	0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x080c,
-+	0x8576, 0x0005, 0x080c, 0x804b, 0x7003, 0x0200, 0x0804, 0x7e56,
-+	0x080c, 0x804b, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a,
-+	0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x080c,
-+	0x8576, 0x0005, 0x00d6, 0x080c, 0x804b, 0x7003, 0x0210, 0x7007,
-+	0x0014, 0x700b, 0x0800, 0x7810, 0x2068, 0x6894, 0x9086, 0x0014,
-+	0x1198, 0x699c, 0x9184, 0x0030, 0x0190, 0x6998, 0x9184, 0xc000,
-+	0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100,
-+	0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f,
-+	0x0800, 0x00f6, 0x2079, 0x1152, 0x7904, 0x00fe, 0xd1ac, 0x1110,
-+	0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1174,
-+	0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1172,
-+	0x210c, 0xd1e4, 0x0130, 0xc0c5, 0x9094, 0x0030, 0x9296, 0x0010,
-+	0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108,
-+	0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x080c, 0x8576,
-+	0x0005, 0x080c, 0x804b, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f,
-+	0x0100, 0x60c3, 0x0014, 0x080c, 0x8576, 0x0005, 0x080c, 0x804b,
-+	0x7003, 0x0200, 0x0804, 0x7dc7, 0x080c, 0x804b, 0x7003, 0x0100,
-+	0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x8576,
-+	0x0005, 0x080c, 0x804b, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3,
-+	0x0008, 0x080c, 0x8576, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046,
-+	0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
-+	0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0x8dc3, 0x7810,
-+	0x2068, 0x6810, 0x9305, 0x7002, 0x6814, 0x7006, 0x6aa0, 0x2069,
-+	0x1100, 0x6858, 0x700e, 0x9286, 0x007e, 0x1168, 0x9385, 0x00ff,
-+	0x7002, 0x7007, 0xfffe, 0x2001, 0x12a7, 0x2004, 0x9005, 0x01e8,
-+	0x6a78, 0x720e, 0x00d0, 0x9286, 0x007f, 0x1130, 0x9385, 0x00ff,
-+	0x7002, 0x7007, 0xfffd, 0x0068, 0x68d8, 0xd0ac, 0x1110, 0xd2bc,
-+	0x0160, 0x9286, 0x0080, 0x1128, 0x9385, 0x00ff, 0x7002, 0x7007,
-+	0xfffc, 0x6874, 0x700a, 0x6878, 0x700e, 0x9485, 0x0029, 0x7012,
-+	0x004e, 0x003e, 0x00de, 0x080c, 0x8565, 0x721a, 0x9f95, 0x0000,
-+	0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026,
-+	0x080c, 0x8dc3, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069,
-+	0x1100, 0x6874, 0x700a, 0x6878, 0x700e, 0x00de, 0x7013, 0x2029,
-+	0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f,
-+	0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300,
-+	0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019,
-+	0x2300, 0x2021, 0x0100, 0x080c, 0x8dc3, 0x7810, 0x2068, 0x6810,
-+	0x9305, 0x7002, 0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6a58,
-+	0x720e, 0x6ad8, 0xd2ac, 0x1118, 0x9092, 0x007e, 0x02a0, 0x7810,
-+	0x00c6, 0x2060, 0x6010, 0x9005, 0x1140, 0x6014, 0x9005, 0x1128,
-+	0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x6874, 0x700a, 0x6878,
-+	0x700e, 0x00ce, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e,
-+	0x00de, 0x080c, 0x8565, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
-+	0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x8565, 0x721a, 0x7a08,
-+	0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00c6,
-+	0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004,
-+	0x908a, 0x0085, 0x0a0c, 0x0d7e, 0x908a, 0x0092, 0x1a0c, 0x0d7e,
-+	0x6110, 0x2178, 0x79a0, 0x2011, 0x1136, 0x2214, 0xd2ac, 0x1110,
-+	0xd1bc, 0x0148, 0x7900, 0xd1f4, 0x0120, 0x7914, 0x918c, 0x00ff,
-+	0x0038, 0x900e, 0x0028, 0x91f8, 0x298c, 0x2f0d, 0x918c, 0x00ff,
-+	0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x002b, 0x00fe,
-+	0x00ee, 0x00de, 0x00ce, 0x0005, 0x80db, 0x80e1, 0x80ed, 0x80d9,
-+	0x80d9, 0x80d9, 0x80db, 0x80d9, 0x80d9, 0x80d9, 0x80d9, 0x80d9,
-+	0x80d9, 0x080c, 0x0d7e, 0x00e1, 0x60c3, 0x0000, 0x080c, 0x8576,
-+	0x0005, 0x04a9, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff,
-+	0x60c3, 0x000c, 0x080c, 0x8576, 0x0005, 0x080c, 0x8137, 0x7003,
-+	0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x080c, 0x8576, 0x0005,
-+	0x0026, 0x080c, 0x8dc3, 0x7810, 0x2068, 0x6810, 0x9085, 0x8100,
-+	0x7002, 0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac,
-+	0x1118, 0x9092, 0x007e, 0x0240, 0x6874, 0x700a, 0x6878, 0x700e,
-+	0x7013, 0x0009, 0x0804, 0x801b, 0x6a58, 0x720e, 0x0cc8, 0x0026,
-+	0x080c, 0x8dc3, 0x7810, 0x2068, 0x6810, 0x9085, 0x8400, 0x7002,
-+	0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac, 0x1118,
-+	0x9092, 0x007e, 0x0248, 0x6874, 0x700a, 0x6878, 0x700e, 0x2001,
-+	0x0099, 0x7012, 0x0804, 0x808c, 0x6a58, 0x720e, 0x0cc0, 0x0026,
-+	0x080c, 0x8dc3, 0x7810, 0x2068, 0x6810, 0x9085, 0x8500, 0x7002,
-+	0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac, 0x1118,
-+	0x9092, 0x007e, 0x0248, 0x6874, 0x700a, 0x6878, 0x700e, 0x2001,
-+	0x0099, 0x7012, 0x0804, 0x808c, 0x6a58, 0x720e, 0x0cc0, 0x00c6,
-+	0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240,
-+	0x7804, 0x908a, 0x0040, 0x0a0c, 0x0d7e, 0x908a, 0x0054, 0x1a0c,
-+	0x0d7e, 0x7910, 0x2160, 0x61a0, 0x2011, 0x1136, 0x2214, 0xd2ac,
-+	0x1110, 0xd1bc, 0x0148, 0x6100, 0xd1f4, 0x0120, 0x6114, 0x918c,
-+	0x00ff, 0x0038, 0x900e, 0x0028, 0x91e0, 0x298c, 0x2c0d, 0x918c,
-+	0x00ff, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x002b, 0x00fe,
-+	0x00ee, 0x00de, 0x00ce, 0x0005, 0x81a1, 0x825f, 0x8226, 0x8391,
-+	0x819f, 0x819f, 0x819f, 0x819f, 0x819f, 0x819f, 0x819f, 0x893a,
-+	0x8942, 0x894a, 0x8952, 0x819f, 0x8d0a, 0x819f, 0x8932, 0x080c,
-+	0x0d7e, 0x780b, 0xffff, 0x080c, 0x81f4, 0x7914, 0x2168, 0x6978,
-+	0x7956, 0x7132, 0x697c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005,
-+	0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006,
-+	0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042,
-+	0xd1ac, 0x0128, 0x7047, 0x0002, 0x080c, 0x137e, 0x0050, 0xd1b4,
-+	0x0118, 0x7047, 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230,
-+	0x0010, 0x6ab0, 0x6eac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9,
-+	0x0000, 0x9d88, 0x0023, 0x20e1, 0x0001, 0x2198, 0x20a1, 0x0252,
-+	0x2069, 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3,
-+	0x0020, 0x6017, 0x0009, 0x2001, 0x1320, 0x2003, 0x07d0, 0x2001,
-+	0x131f, 0x2003, 0x0009, 0x0005, 0x00d6, 0x6813, 0x0008, 0x7a10,
-+	0x2268, 0x6a8c, 0x8210, 0x9294, 0x00ff, 0x6a8e, 0x8217, 0x721a,
-+	0x6a10, 0x9295, 0x0600, 0x7202, 0x6a14, 0x7206, 0x68a0, 0x6900,
-+	0x2069, 0x1100, 0x6bd8, 0xd3ac, 0x1138, 0xd0bc, 0x0188, 0xd1f4,
-+	0x0118, 0x9294, 0x00ff, 0x629a, 0x6a74, 0x720a, 0x6a78, 0x720e,
-+	0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x00de, 0x0005,
-+	0x9294, 0x00ff, 0x629a, 0x6a58, 0x720e, 0x0c90, 0x00d6, 0x0081,
-+	0x7814, 0x2068, 0x6890, 0x7002, 0x688c, 0x7006, 0x68b0, 0x700a,
-+	0x68ac, 0x700e, 0x60c3, 0x000c, 0x00de, 0x080c, 0x8576, 0x0005,
-+	0x00d6, 0x6813, 0x0008, 0x7810, 0x2068, 0x6810, 0x9085, 0x0500,
-+	0x7002, 0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac,
-+	0x1110, 0xd0bc, 0x0188, 0x6874, 0x700a, 0x6878, 0x700e, 0x7013,
-+	0x0889, 0x080c, 0x8565, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
-+	0x2071, 0x024c, 0x00de, 0x0005, 0x6a58, 0x720e, 0x0c80, 0x00d6,
-+	0x080c, 0x8364, 0x7814, 0x2068, 0x9084, 0xf000, 0x1130, 0x7814,
-+	0x9084, 0x0700, 0x8007, 0x002b, 0x0010, 0x9006, 0x0013, 0x00de,
-+	0x0005, 0x827b, 0x82e8, 0x82f8, 0x831f, 0x832c, 0x833e, 0x8346,
-+	0x8279, 0x080c, 0x0d7e, 0x0016, 0x0036, 0x697c, 0x918c, 0x0003,
-+	0x0118, 0x9186, 0x0003, 0x11a0, 0x6ba8, 0x7824, 0xd0cc, 0x1170,
-+	0x7316, 0x6898, 0x701a, 0x6894, 0x701e, 0x003e, 0x001e, 0x2001,
-+	0x12e8, 0x2004, 0x60c2, 0x080c, 0x8576, 0x0005, 0xc3e5, 0x0c80,
-+	0x9186, 0x0001, 0x190c, 0x0d7e, 0x6ba8, 0x7824, 0xd0cc, 0x1904,
-+	0x82e5, 0x7316, 0x6898, 0x701a, 0x6894, 0x701e, 0x68a4, 0x7026,
-+	0x68ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0580, 0xd3c4,
-+	0x0110, 0x68ac, 0x9108, 0xd3cc, 0x0110, 0x68a4, 0x9108, 0x2011,
-+	0x0258, 0x0156, 0x20a9, 0x0008, 0x9d80, 0x002c, 0x201c, 0x831f,
-+	0x2312, 0x8000, 0x8210, 0x1f04, 0x82be, 0x0016, 0x00d6, 0x2069,
-+	0x0200, 0x080c, 0x8dae, 0x00de, 0x001e, 0x2011, 0x0240, 0x20a9,
-+	0x0005, 0x201c, 0x831f, 0x2312, 0x8000, 0x8210, 0x1f04, 0x82d1,
-+	0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2,
-+	0x003e, 0x001e, 0x080c, 0x8576, 0x0005, 0xc3e5, 0x0804, 0x82a1,
-+	0x2011, 0x0008, 0x2001, 0x110e, 0x2004, 0xd0a4, 0x0110, 0x2011,
-+	0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0478, 0x0ce8, 0xc2e5,
-+	0x2011, 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105,
-+	0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216,
-+	0x7027, 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500,
-+	0x704f, 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240,
-+	0x700b, 0x2500, 0x60c3, 0x0032, 0x080c, 0x8576, 0x0005, 0x2011,
-+	0x0028, 0x7824, 0xd0cc, 0x1130, 0x7216, 0x60c3, 0x0018, 0x080c,
-+	0x8576, 0x0005, 0x0cc8, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc,
-+	0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff,
-+	0x7036, 0x60c3, 0x0020, 0x080c, 0x8576, 0x0005, 0x2011, 0x0008,
-+	0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x08f8, 0x0036, 0x7b14,
-+	0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824,
-+	0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0878, 0x0046, 0x2021,
-+	0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416,
-+	0x004e, 0x701e, 0x003e, 0x0808, 0x00d6, 0x6813, 0x0008, 0x7a10,
-+	0x2268, 0x6810, 0x9085, 0x0700, 0x7002, 0x6814, 0x7006, 0x68a0,
-+	0x2069, 0x1100, 0x6ad8, 0xd2ac, 0x1110, 0xd0bc, 0x01a0, 0x6874,
-+	0x700a, 0x6878, 0x700e, 0x7824, 0xd0cc, 0x1180, 0x7013, 0x0898,
-+	0x080c, 0x8565, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071,
-+	0x024c, 0x00de, 0x0005, 0x6a58, 0x720e, 0x0c68, 0x7013, 0x0889,
-+	0x0c78, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e,
-+	0x0005, 0x83a1, 0x83a1, 0x83a3, 0x83a1, 0x83a1, 0x83a1, 0x83c0,
-+	0x83a1, 0x080c, 0x0d7e, 0x7914, 0x918c, 0xf8ff, 0x918d, 0x0600,
-+	0x7916, 0x2009, 0x0003, 0x00d1, 0x00d6, 0x2069, 0x1152, 0x6804,
-+	0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010,
-+	0x7033, 0x3f00, 0x00de, 0x60c3, 0x0001, 0x080c, 0x8576, 0x0005,
-+	0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0ca8, 0x00d6, 0x0016,
-+	0x080c, 0x8dc3, 0x001e, 0x7810, 0x2068, 0x6810, 0x9085, 0x0100,
-+	0x7002, 0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac,
-+	0x1110, 0xd0bc, 0x0190, 0x6a74, 0x720a, 0x6a78, 0x720e, 0x7013,
-+	0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0x8565, 0x721a, 0x7a08,
-+	0x7222, 0x2f10, 0x7226, 0x00de, 0x0005, 0x6a58, 0x720e, 0x0c78,
-+	0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100,
-+	0x2071, 0x1100, 0x7158, 0x7810, 0x2068, 0x68a0, 0x2028, 0x6910,
-+	0x6a14, 0x76d8, 0xd6ac, 0x1128, 0xd0bc, 0x1118, 0x901e, 0x7458,
-+	0x0010, 0x7374, 0x7478, 0x7820, 0x90be, 0x0006, 0x0904, 0x84dd,
-+	0x90be, 0x000a, 0x1904, 0x8496, 0x609f, 0x0000, 0x7814, 0x2070,
-+	0x707c, 0xd0fc, 0x0904, 0x845d, 0x7790, 0x9784, 0xff00, 0x9105,
-+	0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x9080, 0x001e,
-+	0x2004, 0x9005, 0x000e, 0x1160, 0x7794, 0x87ff, 0x0548, 0x2039,
-+	0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0470,
-+	0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0x609f,
-+	0x0000, 0x2001, 0x1136, 0x2004, 0x9084, 0x0020, 0x11d8, 0x2001,
-+	0x1136, 0x2004, 0x9084, 0x0008, 0x0140, 0x7814, 0x9080, 0x001d,
-+	0x2004, 0x8007, 0x9082, 0x0080, 0x1268, 0x6814, 0x609e, 0x0050,
-+	0x2039, 0x0029, 0x9705, 0x6072, 0x0028, 0x9185, 0x0200, 0x6062,
-+	0x6073, 0x2029, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a,
-+	0x646e, 0x6077, 0x0000, 0x688c, 0x8000, 0x9084, 0x00ff, 0x688e,
-+	0x8007, 0x607a, 0x607f, 0x0000, 0x7038, 0x608a, 0x7034, 0x608e,
-+	0x7048, 0x60c6, 0x7044, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
-+	0x60d7, 0x0000, 0x080c, 0x8da8, 0x2009, 0x07d0, 0x60c4, 0x9084,
-+	0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x7276, 0x003e,
-+	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x9185, 0x0100,
-+	0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077, 0x0008,
-+	0x60af, 0x95d5, 0x60d7, 0x0000, 0x688c, 0x8000, 0x9084, 0x00ff,
-+	0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808,
-+	0x6086, 0x7814, 0x2070, 0x7038, 0x608a, 0x7034, 0x608e, 0x7048,
-+	0x60c6, 0x7044, 0x60ca, 0x686c, 0x60ce, 0x9582, 0x0080, 0x0240,
-+	0x6a00, 0xd2f4, 0x0120, 0x6a14, 0x9294, 0x00ff, 0x0008, 0x9016,
-+	0x629e, 0x080c, 0x8da8, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0,
-+	0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x7276, 0x003e, 0x004e,
-+	0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7814, 0x2070, 0x707c,
-+	0x9084, 0x0003, 0x9086, 0x0002, 0x05e8, 0x9185, 0x0100, 0x6062,
-+	0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c,
-+	0x8000, 0x9084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x7838, 0x607e,
-+	0x2f00, 0x6086, 0x7808, 0x6082, 0x7090, 0x608a, 0x708c, 0x608e,
-+	0x70b0, 0x60c6, 0x70ac, 0x60ca, 0x70ac, 0x7930, 0x9108, 0x7932,
-+	0x70b0, 0x792c, 0x9109, 0x792e, 0x686c, 0x60ce, 0x60af, 0x95d5,
-+	0x60d7, 0x0000, 0x9582, 0x0080, 0x0240, 0x6a00, 0xd2f4, 0x0120,
-+	0x6a14, 0x9294, 0x00ff, 0x0008, 0x9016, 0x629e, 0x080c, 0x8d83,
-+	0x0804, 0x84cb, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e,
-+	0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073,
-+	0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0x9084, 0x00ff, 0x688e,
-+	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082,
-+	0x7038, 0x608a, 0x7034, 0x608e, 0x7048, 0x60c6, 0x7044, 0x60ca,
-+	0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x9582, 0x0080,
-+	0x0240, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0x9294, 0x00ff, 0x0008,
-+	0x9016, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c, 0x8da8, 0x0804,
-+	0x84cb, 0x080c, 0x8d83, 0x0804, 0x84cb, 0x7a10, 0x9280, 0x0023,
-+	0x2014, 0x8210, 0x9294, 0x00ff, 0x2202, 0x8217, 0x0005, 0x00d6,
-+	0x2069, 0x1304, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056,
-+	0x60a7, 0x9575, 0x00f1, 0x080c, 0x7268, 0x0005, 0x0016, 0x2001,
-+	0x110c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089,
-+	0x080c, 0x7268, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x110c, 0x2102,
-+	0x2001, 0x1305, 0x2003, 0x0000, 0x2001, 0x130d, 0x2003, 0x0000,
-+	0x0c88, 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016,
-+	0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4,
-+	0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016,
-+	0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005,
-+	0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140,
-+	0x080c, 0x62e4, 0x1198, 0x2001, 0x1320, 0x2004, 0x9005, 0x15d0,
-+	0x0066, 0x2031, 0x0001, 0x080c, 0x6380, 0x006e, 0x1118, 0x080c,
-+	0x7268, 0x0480, 0x00c6, 0x2061, 0x1304, 0x00f0, 0x6904, 0x9194,
-+	0x4000, 0x0568, 0x0839, 0x2001, 0x1000, 0x080c, 0x2401, 0x9006,
-+	0x080c, 0x2401, 0x00c6, 0x2061, 0x1304, 0x6128, 0x9192, 0x00c8,
-+	0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c,
-+	0x7268, 0x080c, 0x8599, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140,
-+	0x080c, 0xc463, 0x080c, 0x7271, 0x2009, 0x0014, 0x080c, 0x8f53,
-+	0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001,
-+	0x1320, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x1304, 0x6128,
-+	0x9192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x7268,
-+	0x080c, 0x4faa, 0x0c38, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026,
-+	0x080c, 0x727e, 0x2071, 0x1304, 0x713c, 0x81ff, 0x0904, 0x868e,
-+	0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x62e4, 0x11b0, 0x0036,
-+	0x2019, 0x0002, 0x080c, 0x8847, 0x003e, 0x713c, 0x2160, 0x080c,
-+	0xc463, 0x2009, 0x004a, 0x080c, 0x8f53, 0x0066, 0x2031, 0x0001,
-+	0x080c, 0x6380, 0x006e, 0x0804, 0x868e, 0x6904, 0x9194, 0x4000,
-+	0x0904, 0x8694, 0x2001, 0x1000, 0x080c, 0x2401, 0x9006, 0x080c,
-+	0x2401, 0x00c6, 0x703c, 0x9065, 0x090c, 0x0d7e, 0x6020, 0x00ce,
-+	0x9086, 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009,
-+	0x110c, 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128,
-+	0x6224, 0x9294, 0x0002, 0x1510, 0x0030, 0xc0d4, 0x200a, 0xd0cc,
-+	0x0110, 0x080c, 0x2369, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010,
-+	0x6016, 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0x8f53, 0x0070,
-+	0x0036, 0x2019, 0x0001, 0x080c, 0x8847, 0x003e, 0x713c, 0x2160,
-+	0x080c, 0xc463, 0x2009, 0x004a, 0x080c, 0x8f53, 0x002e, 0x001e,
-+	0x00ee, 0x00de, 0x00ce, 0x0005, 0x0804, 0x8651, 0x0026, 0x00e6,
-+	0x2071, 0x1304, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, 0x01a8,
-+	0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138,
-+	0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0030, 0x7014,
-+	0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005,
-+	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x6010, 0x2068, 0x6ca0, 0x2071, 0x1304, 0x7018,
-+	0x2068, 0x8dff, 0x0188, 0x68a0, 0x9406, 0x0118, 0x6854, 0x2068,
-+	0x0cc0, 0x6014, 0x2060, 0x646c, 0x6570, 0x6678, 0x2d60, 0x080c,
-+	0x5728, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
-+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x080c, 0x7fd5, 0x7003,
-+	0x1200, 0x7820, 0x9086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001,
-+	0x1116, 0x2004, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3,
-+	0x002c, 0x080c, 0x8576, 0x0005, 0x080c, 0x7fd5, 0x7003, 0x0f00,
-+	0x7808, 0x700e, 0x60c3, 0x0008, 0x080c, 0x8576, 0x0005, 0x0156,
-+	0x080c, 0x804b, 0x7003, 0x0200, 0x2011, 0x1148, 0x63f0, 0x2312,
-+	0x20a9, 0x0006, 0x2011, 0x1140, 0x2019, 0x1141, 0x9ef0, 0x0002,
-+	0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
-+	0x1f04, 0x8718, 0x60c3, 0x001c, 0x080c, 0x8576, 0x015e, 0x0005,
-+	0x0016, 0x0026, 0x080c, 0x8027, 0x080c, 0x8039, 0x9e80, 0x0004,
-+	0x20e9, 0x0000, 0x20a0, 0x7814, 0x9080, 0x0000, 0x2004, 0x9080,
-+	0x0021, 0x20e1, 0x0001, 0x2098, 0x7808, 0x9088, 0x0002, 0x21a8,
-+	0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2,
-+	0x080c, 0x8576, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003,
-+	0x080c, 0x8dae, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c,
-+	0x7fd5, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x080c,
-+	0x8576, 0x0005, 0x0016, 0x0026, 0x080c, 0x7fd5, 0x20e9, 0x0000,
-+	0x20a1, 0x024c, 0x7814, 0x9080, 0x0000, 0x2004, 0x9080, 0x0023,
-+	0x20e1, 0x0001, 0x2098, 0x7808, 0x9088, 0x0002, 0x21a8, 0x4003,
-+	0x8003, 0x60c2, 0x080c, 0x8576, 0x002e, 0x001e, 0x0005, 0x00e6,
-+	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1304, 0x700c,
-+	0x2060, 0x8cff, 0x0178, 0x080c, 0xab2e, 0x1110, 0x080c, 0x97dc,
-+	0x600c, 0x0006, 0x080c, 0xad68, 0x080c, 0x8ed9, 0x080c, 0x895e,
-+	0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, 0x00ce,
-+	0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
-+	0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x110c, 0x200c,
-+	0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
-+	0x1304, 0x7024, 0x2060, 0x8cff, 0x0904, 0x87ff, 0x080c, 0x85a2,
-+	0x6ac0, 0x68c3, 0x0000, 0x080c, 0x7271, 0x00c6, 0x2061, 0x0100,
-+	0x080c, 0x8dc7, 0x00ce, 0x2009, 0x0013, 0x080c, 0x8f53, 0x20a9,
-+	0x01f4, 0x6824, 0xd094, 0x0170, 0x6827, 0x0004, 0x7804, 0x9084,
-+	0x4000, 0x01d0, 0x2001, 0x1000, 0x080c, 0x2401, 0x9006, 0x080c,
-+	0x2401, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
-+	0x87d1, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-+	0x2401, 0x9006, 0x080c, 0x2401, 0x6824, 0x000e, 0x001e, 0x002e,
-+	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001,
-+	0x1100, 0x2004, 0x9096, 0x0001, 0x05c0, 0x9096, 0x0004, 0x05a8,
-+	0x080c, 0x7271, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5,
-+	0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x4f57, 0x080c, 0x71fa,
-+	0x20a9, 0x01f4, 0x6824, 0xd094, 0x0170, 0x6827, 0x0004, 0x7804,
-+	0x9084, 0x4000, 0x01d0, 0x7803, 0x1000, 0x080c, 0x2401, 0x9006,
-+	0x080c, 0x2401, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
-+	0x1f04, 0x881a, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100,
-+	0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x000e, 0x001e, 0x002e,
-+	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126,
-+	0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006,
-+	0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2001, 0x110c,
-+	0x200c, 0x918c, 0xdbff, 0x2102, 0x2071, 0x1304, 0x703c, 0x2060,
-+	0x8cff, 0x0904, 0x88d8, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084,
-+	0x0002, 0x0904, 0x88d8, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009,
-+	0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x727e,
-+	0x080c, 0x1872, 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021,
-+	0x0169, 0x2404, 0x9084, 0x000f, 0x9086, 0x0004, 0x11f8, 0x68af,
-+	0x95f5, 0x68c6, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0090,
-+	0x2071, 0x134a, 0x6814, 0x9084, 0x1984, 0x9085, 0x0012, 0x6816,
-+	0x782b, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0x9386, 0x0002,
-+	0x1128, 0x7884, 0x9005, 0x1110, 0x7887, 0x0001, 0x2001, 0x12bb,
-+	0x2004, 0x200a, 0x004e, 0x939d, 0x0000, 0x1120, 0x2009, 0x0049,
-+	0x080c, 0x8f53, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0170, 0x6827,
-+	0x0004, 0x7804, 0x9084, 0x4000, 0x01d0, 0x2001, 0x1000, 0x080c,
-+	0x2401, 0x9006, 0x080c, 0x2401, 0x0090, 0xd08c, 0x0118, 0x6827,
-+	0x0002, 0x0010, 0x1f04, 0x88b4, 0x7804, 0x9084, 0x1000, 0x0138,
-+	0x2001, 0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401, 0x6824,
-+	0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
-+	0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x1304,
-+	0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
-+	0x2069, 0x1304, 0x6a32, 0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6,
-+	0x00c6, 0x0066, 0x0006, 0x0126, 0x2071, 0x1304, 0x7614, 0x2660,
-+	0x2678, 0x2091, 0x8000, 0x8cff, 0x0530, 0x6020, 0x9206, 0x11f8,
-+	0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140,
-+	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x080c, 0x8f09, 0x04c9, 0x00ce, 0x08e0, 0x2c78,
-+	0x600c, 0x2060, 0x08c0, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee,
-+	0x00fe, 0x0005, 0x080c, 0x81f4, 0x7814, 0x7032, 0x7042, 0x7047,
-+	0x1000, 0x00f8, 0x080c, 0x81f4, 0x7814, 0x7032, 0x7042, 0x7047,
-+	0x4000, 0x00b8, 0x080c, 0x81f4, 0x7814, 0x7032, 0x7042, 0x7047,
-+	0x2000, 0x0078, 0x080c, 0x81f4, 0x7814, 0x7032, 0x7042, 0x7047,
-+	0x0400, 0x0038, 0x080c, 0x81f4, 0x7814, 0x7032, 0x7042, 0x7047,
-+	0x0200, 0x60c3, 0x0020, 0x080c, 0x8576, 0x0005, 0x00e6, 0x2071,
-+	0x1304, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005,
-+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x2071, 0x1304, 0x7614, 0x2660, 0x2678, 0x2039,
-+	0x0001, 0x87ff, 0x0904, 0x89fa, 0x8cff, 0x0904, 0x89fa, 0x6020,
-+	0x9086, 0x0006, 0x1904, 0x89f5, 0x88ff, 0x0138, 0x2800, 0x9c06,
-+	0x1904, 0x89f5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9206, 0x1904,
-+	0x89f5, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x89f5, 0x7024,
-+	0x9c06, 0x1578, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0530, 0x080c,
-+	0x7271, 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
-+	0x68c3, 0x0000, 0x080c, 0x8a7d, 0x7027, 0x0000, 0x0036, 0x2069,
-+	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-+	0x2401, 0x9006, 0x080c, 0x2401, 0x2069, 0x0100, 0x6824, 0xd084,
-+	0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
-+	0x0460, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36,
-+	0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
-+	0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
-+	0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6014, 0x2068, 0x080c,
-+	0xa942, 0x0110, 0x080c, 0xc0e9, 0x080c, 0x8f09, 0x080c, 0x895e,
-+	0x88ff, 0x1190, 0x00ce, 0x0804, 0x8979, 0x2c78, 0x600c, 0x2060,
-+	0x0804, 0x8979, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce,
-+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5,
-+	0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
-+	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1304, 0x7638, 0x2660,
-+	0x2678, 0x8cff, 0x0904, 0x8a6d, 0x6020, 0x9086, 0x0006, 0x1904,
-+	0x8a68, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0x8a68, 0x0040,
-+	0x6010, 0x9206, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106, 0x15c0,
-+	0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0x8847,
-+	0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e,
-+	0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140,
-+	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x6014, 0x2068, 0x080c, 0xa942, 0x0110, 0x080c,
-+	0xc0e9, 0x080c, 0x8f09, 0x87ff, 0x1190, 0x00ce, 0x0804, 0x8a19,
-+	0x2c78, 0x600c, 0x2060, 0x0804, 0x8a19, 0x9006, 0x012e, 0x000e,
-+	0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
-+	0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c88, 0x00e6, 0x2071, 0x1304,
-+	0x2001, 0x1100, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005,
-+	0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-+	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1304,
-+	0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0x9c06,
-+	0x11e0, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36,
-+	0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
-+	0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060,
-+	0x08d8, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe,
-+	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x2071, 0x1304, 0x760c, 0x2660, 0x2678, 0x8cff,
-+	0x0904, 0x8b56, 0x6010, 0x9080, 0x0028, 0x2004, 0x9206, 0x1904,
-+	0x8b51, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005,
-+	0x0904, 0x8b2d, 0x080c, 0x85a2, 0x68c3, 0x0000, 0x080c, 0x8a7d,
-+	0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-+	0x0138, 0x2001, 0x0100, 0x080c, 0x2401, 0x9006, 0x080c, 0x2401,
-+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-+	0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140,
-+	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
-+	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-+	0x600f, 0x0000, 0x080c, 0xab1d, 0x1158, 0x080c, 0x2886, 0x080c,
-+	0xab2e, 0x11f0, 0x080c, 0x97dc, 0x00d8, 0x080c, 0x8a7d, 0x08c0,
-+	0x080c, 0xab2e, 0x1118, 0x080c, 0x97dc, 0x0090, 0x6014, 0x2068,
-+	0x080c, 0xa942, 0x0168, 0x6020, 0x9086, 0x0003, 0x11f8, 0x6867,
-+	0x0103, 0x6b7a, 0x6877, 0x0000, 0x080c, 0x5b76, 0x080c, 0xab11,
-+	0x080c, 0xad68, 0x080c, 0x8f09, 0x080c, 0x895e, 0x00ce, 0x0804,
-+	0x8ad7, 0x2c78, 0x600c, 0x2060, 0x0804, 0x8ad7, 0x012e, 0x000e,
-+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
-+	0x0006, 0x1d30, 0x080c, 0xc0e9, 0x0c18, 0x00d6, 0x080c, 0x804b,
-+	0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001,
-+	0x2099, 0x12c3, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004,
-+	0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0x8576, 0x00de,
-+	0x0005, 0x080c, 0x804b, 0x7003, 0x0214, 0x7007, 0x0018, 0x700b,
-+	0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff,
-+	0x7022, 0x782c, 0x7026, 0x60c3, 0x0018, 0x080c, 0x8576, 0x0005,
-+	0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xaf4e,
-+	0x00de, 0x1904, 0x8bfe, 0x080c, 0x7fd5, 0x7003, 0x1300, 0x782c,
-+	0x2068, 0x6820, 0x9086, 0x0003, 0x0570, 0x7810, 0x9080, 0x0028,
-+	0x2014, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x11d0, 0x9286, 0x007e,
-+	0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x04a8, 0x9286, 0x007f,
-+	0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0468, 0xd2bc, 0x0180,
-+	0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0418,
-+	0x92e8, 0x1000, 0x2d6c, 0x6810, 0x700a, 0x6814, 0x700e, 0x00d8,
-+	0x6098, 0x700e, 0x00c0, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x1138,
-+	0x7810, 0x9080, 0x0028, 0x2004, 0x9082, 0x007e, 0x0250, 0x00d6,
-+	0x2069, 0x111d, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de,
-+	0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3,
-+	0x000c, 0x001e, 0x00de, 0x080c, 0x8576, 0x0005, 0x781b, 0x0001,
-+	0x7803, 0x0006, 0x001e, 0x00de, 0x0005, 0x792c, 0x9180, 0x0008,
-+	0x200c, 0x9186, 0x0006, 0x01b0, 0x9186, 0x0003, 0x0904, 0x8c75,
-+	0x9186, 0x0005, 0x0904, 0x8c5e, 0x9186, 0x0004, 0x05c8, 0x9186,
-+	0x0008, 0x0904, 0x8c66, 0x7807, 0x0037, 0x7817, 0x1700, 0x080c,
-+	0x8cda, 0x0005, 0x080c, 0x8c9a, 0x00d6, 0x0026, 0x792c, 0x2168,
-+	0x2009, 0x4000, 0x6800, 0x0002, 0x8c3f, 0x8c4a, 0x8c41, 0x8c4a,
-+	0x8c46, 0x8c3f, 0x8c3f, 0x8c4a, 0x8c4a, 0x8c4a, 0x8c4a, 0x8c3f,
-+	0x8c3f, 0x8c3f, 0x8c3f, 0x8c3f, 0x8c4a, 0x8c3f, 0x8c4a, 0x080c,
-+	0x0d7e, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
-+	0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0x8c92,
-+	0x080c, 0x8c9a, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
-+	0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04a0, 0x04d9, 0x00d6,
-+	0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0460, 0x0499, 0x00d6,
-+	0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, 0x0118,
-+	0x9286, 0x0002, 0x1108, 0x900e, 0x00e8, 0x0421, 0x00d6, 0x0026,
-+	0x792c, 0x2168, 0x6814, 0x2068, 0x69ac, 0x6834, 0x9112, 0x69b0,
-+	0x6838, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004,
-+	0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000,
-+	0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x080c,
-+	0x8576, 0x0005, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x804b,
-+	0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810,
-+	0x9080, 0x0028, 0x2004, 0x2011, 0x1136, 0x2214, 0xd2ac, 0x1118,
-+	0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x111d, 0x2d2c, 0x8d68,
-+	0x2d34, 0x90e8, 0x1000, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0028,
-+	0x901e, 0x6498, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008,
-+	0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e,
-+	0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e,
-+	0x003e, 0x0005, 0x080c, 0x804b, 0x7003, 0x0100, 0x700b, 0x0009,
-+	0x7814, 0x700e, 0x60c3, 0x0008, 0x080c, 0x8576, 0x0005, 0x080c,
-+	0x7fcc, 0x7003, 0x1400, 0x7838, 0x700a, 0x783c, 0x700e, 0x782c,
-+	0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a,
-+	0x60c3, 0x0010, 0x080c, 0x8576, 0x0005, 0x080c, 0x8042, 0x7003,
-+	0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x080c,
-+	0x8576, 0x0005, 0x0029, 0x60c3, 0x0000, 0x080c, 0x8576, 0x0005,
-+	0x00d6, 0x080c, 0x8dc3, 0x7810, 0x2068, 0x6810, 0x9085, 0x0300,
-+	0x7002, 0x6814, 0x7006, 0x68a0, 0x2069, 0x1100, 0x6ad8, 0xd2ac,
-+	0x1110, 0xd0bc, 0x0188, 0x6874, 0x700a, 0x6878, 0x700e, 0x7013,
-+	0x0819, 0x080c, 0x8565, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226,
-+	0x2071, 0x024c, 0x00de, 0x0005, 0x6234, 0x720e, 0x0c80, 0x0059,
-+	0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x080c, 0x8599,
-+	0x080c, 0x7268, 0x0005, 0x0036, 0x00d6, 0x00e6, 0x7858, 0x2068,
-+	0x9df0, 0x001b, 0x7210, 0x9296, 0x00c0, 0x9294, 0xfffd, 0x7212,
-+	0x7214, 0x9294, 0x0300, 0x7216, 0x7100, 0x9194, 0x00ff, 0x7308,
-+	0x9384, 0x00ff, 0x908d, 0xc200, 0x7102, 0x9384, 0xff00, 0x9215,
-+	0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x00d6, 0x2069, 0x0200,
-+	0x080c, 0x8dc3, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-+	0x000a, 0x20e1, 0x0001, 0x2e98, 0x4003, 0x60a3, 0x0035, 0x6a68,
-+	0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee,
-+	0x00de, 0x003e, 0x0005, 0x900e, 0x7814, 0x9080, 0x001f, 0x2004,
-+	0xd0fc, 0x01d8, 0x9084, 0x0003, 0x11c0, 0x2001, 0x110c, 0x2004,
-+	0xd0bc, 0x0198, 0x7824, 0xd0cc, 0x1180, 0xd0c4, 0x1170, 0x7814,
-+	0x9080, 0x002a, 0x2004, 0x9005, 0x1140, 0x2001, 0x110c, 0x200c,
-+	0xc1d5, 0x2102, 0x2009, 0x12e9, 0x210c, 0x918d, 0x0092, 0x0010,
-+	0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009,
-+	0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009,
-+	0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028,
-+	0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x00d6,
-+	0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813,
-+	0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292,
-+	0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff,
-+	0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6,
-+	0x0156, 0x080c, 0x804b, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100,
-+	0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007,
-+	0x0000, 0x2069, 0x1100, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110,
-+	0xc38d, 0x0060, 0x080c, 0x62e4, 0x1110, 0xc3ad, 0x0008, 0xc3a5,
-+	0x6ad8, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x2011,
-+	0x1148, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, 0x1140, 0x2019,
-+	0x1141, 0x2071, 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398,
-+	0x0002, 0x9290, 0x0002, 0x1f04, 0x8e1b, 0x60c3, 0x0040, 0x080c,
-+	0x8576, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x804b, 0x7a14,
-+	0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238,
-+	0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x04b8, 0x7003,
-+	0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x12f4, 0x2204,
-+	0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x2001, 0x1136,
-+	0x2004, 0xd0ac, 0x1138, 0x7810, 0x9080, 0x0028, 0x2004, 0x9082,
-+	0x007f, 0x0248, 0x2001, 0x111d, 0x2004, 0x7022, 0x2001, 0x111e,
-+	0x2004, 0x7026, 0x0030, 0x2001, 0x1116, 0x2004, 0x9084, 0x00ff,
-+	0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1105, 0x20e9,
-+	0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x080c, 0x8576,
-+	0x015e, 0x0005, 0x2061, 0x15c0, 0x2071, 0x1100, 0x706c, 0x704e,
-+	0x7053, 0x15c0, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1100, 0x2091,
-+	0x8000, 0x754c, 0x9582, 0x0010, 0x0608, 0x7050, 0x2060, 0x6000,
-+	0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7060, 0x9c02, 0x1208,
-+	0x0cb0, 0x2061, 0x15c0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x754e,
-+	0x9ca8, 0x0018, 0x7060, 0x9502, 0x1230, 0x7552, 0x9085, 0x0001,
-+	0x012e, 0x00ee, 0x0005, 0x7053, 0x15c0, 0x0cc0, 0x9006, 0x0cc0,
-+	0x00e6, 0x2071, 0x1100, 0x754c, 0x9582, 0x0010, 0x0600, 0x7050,
-+	0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7060,
-+	0x9c02, 0x1208, 0x0cb0, 0x2061, 0x15c0, 0x0c98, 0x6003, 0x0008,
-+	0x8529, 0x754e, 0x9ca8, 0x0018, 0x7060, 0x9502, 0x1228, 0x7552,
-+	0x9085, 0x0001, 0x00ee, 0x0005, 0x7053, 0x15c0, 0x0cc8, 0x9006,
-+	0x0cc8, 0x9c82, 0x15c0, 0x0a0c, 0x0d7e, 0x2001, 0x1118, 0x2004,
-+	0x9c02, 0x1a0c, 0x0d7e, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016,
-+	0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056,
-+	0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e,
-+	0x6042, 0x2061, 0x1100, 0x604c, 0x8000, 0x604e, 0x9086, 0x0001,
-+	0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x7aa4, 0x012e,
-+	0x0cc0, 0x0006, 0x6000, 0x9086, 0x0000, 0x01b0, 0x601c, 0xd084,
-+	0x190c, 0x1509, 0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x12c0,
-+	0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a,
-+	0x080c, 0xc381, 0x6043, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126,
-+	0x2071, 0x1100, 0x2091, 0x8000, 0x754c, 0x9582, 0x0001, 0x0608,
-+	0x7050, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018,
-+	0x7060, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x15c0, 0x0c98, 0x6003,
-+	0x0008, 0x8529, 0x754e, 0x9ca8, 0x0018, 0x7060, 0x9502, 0x1230,
-+	0x7552, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7053, 0x15c0,
-+	0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0x8f66,
-+	0x8f75, 0x8f90, 0x8fab, 0xaf90, 0xafab, 0xafc6, 0x8f66, 0x8f75,
-+	0x8f66, 0x8fc7, 0x8f66, 0x8f66, 0x8f66, 0x8f66, 0x9186, 0x0013,
-+	0x1128, 0x080c, 0x79ab, 0x080c, 0x7aa4, 0x0005, 0x9186, 0x0047,
-+	0x1118, 0x9016, 0x080c, 0x137c, 0x0005, 0x0066, 0x6000, 0x90b2,
-+	0x0016, 0x1a0c, 0x0d7e, 0x0013, 0x006e, 0x0005, 0x8f8e, 0x9655,
-+	0x9815, 0x8f8e, 0x98a2, 0x9248, 0x8f8e, 0x8f8e, 0x95e1, 0x9d9e,
-+	0x8f8e, 0x8f8e, 0x8f8e, 0x8f8e, 0x8f8e, 0x8f8e, 0x080c, 0x0d7e,
-+	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d7e, 0x0013, 0x006e,
-+	0x0005, 0x8fa9, 0xa3c8, 0x8fa9, 0x8fa9, 0x8fa9, 0x8fa9, 0x8fa9,
-+	0x8fa9, 0xa36e, 0xa544, 0x8fa9, 0xa3fb, 0xa478, 0xa3fb, 0xa478,
-+	0x8fa9, 0x080c, 0x0d7e, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d7e,
-+	0x6000, 0x0002, 0x8fc5, 0x9ddf, 0x9eaf, 0x9fd9, 0xa13a, 0x8fc5,
-+	0x8fc5, 0x8fc5, 0x9db9, 0xa31e, 0xa321, 0x8fc5, 0x8fc5, 0x8fc5,
-+	0x8fc5, 0xa34b, 0x8fc5, 0x8fc5, 0x8fc5, 0x080c, 0x0d7e, 0x0066,
-+	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d7e, 0x0013, 0x006e, 0x0005,
-+	0x8fe0, 0x8fe0, 0x901f, 0x90ad, 0x910e, 0x8fe0, 0x8fe0, 0x8fe0,
-+	0x8fe2, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0,
-+	0x080c, 0x0d7e, 0x9186, 0x004c, 0x0588, 0x9186, 0x0003, 0x190c,
-+	0x0d7e, 0x00d6, 0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106,
-+	0x6014, 0x2068, 0x687c, 0x9084, 0x8000, 0xc0b5, 0x687e, 0x68ac,
-+	0x6846, 0x68b0, 0x684a, 0x9006, 0x6836, 0x683a, 0x6884, 0x9092,
-+	0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210,
-+	0x621a, 0x00de, 0x2c10, 0x080c, 0x1605, 0x080c, 0x75db, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x7b72, 0x012e, 0x0005, 0x6010, 0x9080,
-+	0x0028, 0x2024, 0x8427, 0x2c00, 0x080c, 0x912f, 0x0005, 0x00d6,
-+	0x00f6, 0x2079, 0x1100, 0x7a88, 0x9290, 0x0018, 0x6014, 0x2068,
-+	0x6c78, 0x0046, 0x68e0, 0x9005, 0x1140, 0x68dc, 0x921a, 0x0140,
-+	0x0220, 0x687b, 0x0007, 0x2010, 0x0028, 0x687b, 0x0015, 0x0010,
-+	0x687b, 0x0000, 0x8214, 0x6883, 0x0000, 0x6a02, 0x0006, 0x0016,
-+	0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108,
-+	0x009a, 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038,
-+	0x2100, 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4,
-+	0x0007, 0x8423, 0x9405, 0x0002, 0x907e, 0x907e, 0x9079, 0x907c,
-+	0x907e, 0x9076, 0x906c, 0x906c, 0x906c, 0x906c, 0x906c, 0x906c,
-+	0x906c, 0x906c, 0x906c, 0x906c, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-+	0x002e, 0x001e, 0x000e, 0x000e, 0x080c, 0x0d7e, 0x080c, 0x9a2c,
-+	0x0028, 0x080c, 0x9b03, 0x0010, 0x080c, 0x9bfa, 0x00fe, 0x00ee,
-+	0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0x6896, 0x000e, 0x080c,
-+	0x91df, 0x01e8, 0x6804, 0x680e, 0x200c, 0x9080, 0x0002, 0x6acc,
-+	0x6bd0, 0x6cd4, 0x6dd8, 0x2039, 0x0001, 0x2031, 0x0000, 0x2041,
-+	0x1091, 0x080c, 0x9367, 0x0158, 0x000e, 0x9005, 0x0118, 0x00fe,
-+	0x00de, 0x0005, 0x00fe, 0x00de, 0x080c, 0x8ed9, 0x0005, 0x2001,
-+	0x002c, 0x900e, 0x080c, 0x923d, 0x0c78, 0x9182, 0x0047, 0x0002,
-+	0x90b9, 0x90b9, 0x90bb, 0x90e8, 0x90b9, 0x90b9, 0x90b9, 0x90b9,
-+	0x90fa, 0x080c, 0x0d7e, 0x00d6, 0x0016, 0x080c, 0x7a55, 0x080c,
-+	0x7b72, 0x6003, 0x0004, 0x6114, 0x2168, 0x687c, 0xd0fc, 0x0188,
-+	0x6878, 0x9005, 0x1158, 0x6894, 0x9005, 0x0140, 0x2001, 0x0000,
-+	0x900e, 0x080c, 0x923d, 0x080c, 0x8ed9, 0x0078, 0x6003, 0x0002,
-+	0x0060, 0x687f, 0x0020, 0x688c, 0x688a, 0x68a4, 0x68ae, 0x68a8,
-+	0x68b2, 0x68c7, 0x0000, 0x68cb, 0x0000, 0x001e, 0x00de, 0x0005,
-+	0x080c, 0x7a55, 0x00d6, 0x6114, 0x2168, 0x080c, 0xa942, 0x0120,
-+	0x687b, 0x0006, 0x080c, 0x5b76, 0x00de, 0x080c, 0x8ed9, 0x080c,
-+	0x7b72, 0x0005, 0x080c, 0x7a55, 0x080c, 0x2862, 0x00d6, 0x6114,
-+	0x2168, 0x080c, 0xa942, 0x0120, 0x687b, 0x0029, 0x080c, 0x5b76,
-+	0x00de, 0x080c, 0x8ed9, 0x080c, 0x7b72, 0x0005, 0x9182, 0x0047,
-+	0x0002, 0x911e, 0x9120, 0x911e, 0x911e, 0x911e, 0x911e, 0x911e,
-+	0x911e, 0x911e, 0x911e, 0x911e, 0x911e, 0x9120, 0x080c, 0x0d7e,
-+	0x00d6, 0x080c, 0x1303, 0x6114, 0x2168, 0x687b, 0x0000, 0x6883,
-+	0x0000, 0x080c, 0x5b76, 0x00de, 0x080c, 0x8ed9, 0x0005, 0x0026,
-+	0x0036, 0x0056, 0x0066, 0x00d6, 0x00f6, 0x0006, 0x080c, 0x0eb6,
-+	0x000e, 0x090c, 0x0d7e, 0x20e9, 0x0001, 0x9d88, 0x0019, 0x21a0,
-+	0x900e, 0x20a9, 0x0020, 0x4104, 0x687a, 0x2079, 0x1100, 0x7988,
-+	0x9188, 0x0018, 0x918c, 0x0fff, 0x6972, 0x6c76, 0x2d78, 0x00f6,
-+	0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182,
-+	0x0034, 0x1228, 0x9f90, 0x001f, 0x080c, 0xa5c9, 0x04c0, 0x2130,
-+	0x2009, 0x0034, 0x9f90, 0x001f, 0x080c, 0xa5c9, 0x96b2, 0x0034,
-+	0x7804, 0x906d, 0x0110, 0x080c, 0x0edf, 0x080c, 0x0eb6, 0x01d0,
-+	0x8528, 0x6867, 0x0110, 0x686b, 0x0000, 0x2d20, 0x7c06, 0x968a,
-+	0x003d, 0x1230, 0x2608, 0x9d90, 0x001b, 0x080c, 0xa5c9, 0x00b8,
-+	0x96b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0x9d90, 0x001b, 0x080c,
-+	0xa5c9, 0x0c18, 0x2079, 0x0200, 0x7817, 0x0000, 0x00fe, 0x852f,
-+	0x95ad, 0x0050, 0x7d66, 0x7870, 0xc0fd, 0x7872, 0x0048, 0x2079,
-+	0x0200, 0x7817, 0x0000, 0x00fe, 0x852f, 0x95ad, 0x0050, 0x7d66,
-+	0x2f68, 0x6804, 0x6807, 0x0000, 0x0006, 0x080c, 0x5b76, 0x000e,
-+	0x2068, 0x9005, 0x1db0, 0x00fe, 0x00de, 0x006e, 0x005e, 0x003e,
-+	0x002e, 0x0005, 0x00d6, 0x00f6, 0x0006, 0x080c, 0x0eb6, 0x000e,
-+	0x090c, 0x0d7e, 0x20e9, 0x0001, 0x9d88, 0x0019, 0x21a0, 0x900e,
-+	0x20a9, 0x0020, 0x4104, 0x6a66, 0x687a, 0x2079, 0x1100, 0x7988,
-+	0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009, 0x001a,
-+	0x21a8, 0x810b, 0x6972, 0x6c76, 0x2e98, 0x9d80, 0x001f, 0x20a0,
-+	0x080c, 0x504f, 0x080c, 0x5b76, 0x00fe, 0x00de, 0x0005, 0x0016,
-+	0x00d6, 0x00f6, 0x2079, 0x0200, 0x2e98, 0x2021, 0x003e, 0x901e,
-+	0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486, 0x003e,
-+	0x1168, 0x00d6, 0x080c, 0x0e9d, 0x2d00, 0x00de, 0x05f0, 0x6806,
-+	0x2068, 0x20e9, 0x0001, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e,
-+	0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010,
-+	0x2100, 0x9318, 0x2200, 0x9402, 0x1220, 0x2410, 0x9006, 0x9398,
-+	0x0002, 0x2020, 0x22a8, 0x6800, 0x9200, 0x6802, 0x0016, 0x0026,
-+	0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04,
-+	0x921a, 0x22a0, 0x2198, 0x002e, 0x001e, 0x83ff, 0x0170, 0x3300,
-+	0x9086, 0x0280, 0x1120, 0x7814, 0x8000, 0x7816, 0x2e98, 0x2310,
-+	0x84ff, 0x0904, 0x91e5, 0x0804, 0x91e7, 0x9085, 0x0001, 0x7817,
-+	0x0000, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6314,
-+	0x2368, 0x687a, 0x6982, 0x080c, 0x5b76, 0x003e, 0x00de, 0x0005,
-+	0x91b6, 0x0015, 0x1118, 0x080c, 0x8ed9, 0x0030, 0x91b6, 0x0016,
-+	0x190c, 0x0d7e, 0x080c, 0x8ed9, 0x0005, 0x20a9, 0x000e, 0x20e1,
-+	0x0000, 0x2e98, 0x6014, 0x20e9, 0x0001, 0x20a0, 0x4003, 0x9080,
-+	0x001b, 0x2020, 0x20a9, 0x0006, 0x3310, 0x9298, 0x0001, 0x94a8,
-+	0x0001, 0x222e, 0x2326, 0x9290, 0x0002, 0x95a8, 0x0002, 0x9398,
-+	0x0002, 0x94a0, 0x0002, 0x1f04, 0x9269, 0x00e6, 0x080c, 0xa942,
-+	0x0130, 0x6014, 0x2070, 0x7007, 0x0000, 0x7067, 0x0103, 0x00ee,
-+	0x080c, 0x8ed9, 0x0005, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200,
-+	0x1130, 0x6010, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6014,
-+	0x9005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6867, 0x0103, 0x6b32,
-+	0x080c, 0x8ed9, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9, 0x0014,
-+	0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x9080, 0x0002,
-+	0x20e9, 0x0001, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001,
-+	0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0x6014,
-+	0x9080, 0x0001, 0x2004, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001,
-+	0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003,
-+	0x2003, 0x0000, 0x00e6, 0x6014, 0x2004, 0x2070, 0x7067, 0x0103,
-+	0x00ee, 0x080c, 0x8ed9, 0x001e, 0x0005, 0x0016, 0x900e, 0x7030,
-+	0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c,
-+	0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x9192, 0x0014,
-+	0x1218, 0x2011, 0x0000, 0x0010, 0x2009, 0x0014, 0x21a8, 0x9e80,
-+	0x000c, 0x2098, 0x6014, 0x9080, 0x0002, 0x20a0, 0x080c, 0x504f,
-+	0x82ff, 0x0170, 0x2009, 0x0205, 0x2104, 0x8000, 0x200a, 0x2e00,
-+	0x2098, 0x3400, 0x9080, 0x0014, 0x20a0, 0x22a8, 0x080c, 0x504f,
-+	0x00e6, 0x080c, 0xa942, 0x0140, 0x6014, 0x2070, 0x7007, 0x0000,
-+	0x7064, 0x70e2, 0x7067, 0x0103, 0x00ee, 0x080c, 0x8ed9, 0x001e,
-+	0x0005, 0x0016, 0x00d6, 0x7030, 0x9086, 0x0100, 0x1118, 0x2009,
-+	0x0004, 0x0010, 0x7034, 0x800c, 0x21a8, 0x9e80, 0x000c, 0x2098,
-+	0x6014, 0x2068, 0x6804, 0x9005, 0x1108, 0x2d00, 0x9080, 0x000c,
-+	0x20a0, 0x080c, 0x504f, 0x080c, 0xa942, 0x0148, 0x6804, 0x9005,
-+	0x1158, 0x6807, 0x0000, 0x6864, 0x68e2, 0x6867, 0x0103, 0x080c,
-+	0x8ed9, 0x00de, 0x001e, 0x0005, 0x00e6, 0x2070, 0x7030, 0x8007,
-+	0x9086, 0x0100, 0x1118, 0x080c, 0x97dc, 0x00b8, 0x7034, 0x8007,
-+	0x800c, 0x9e80, 0x000c, 0x687b, 0x0000, 0x6883, 0x0000, 0x6897,
-+	0x4000, 0x6aa0, 0x6b9c, 0x6ca8, 0x6da4, 0x2031, 0x0000, 0x2039,
-+	0x0001, 0x2041, 0x1078, 0x0019, 0x0d30, 0x00ee, 0x08c0, 0x00d6,
-+	0x0006, 0x080c, 0x0e9d, 0x000e, 0x0190, 0x6812, 0x000e, 0x683e,
-+	0x0006, 0x6e06, 0x2800, 0x683a, 0x6916, 0x6f0e, 0x6a2a, 0x6b2e,
-+	0x6c32, 0x6d36, 0x2d10, 0x080c, 0x0f22, 0x9085, 0x0001, 0x00de,
-+	0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210,
-+	0x9290, 0x0004, 0x2214, 0x9206, 0x1518, 0x700c, 0x6210, 0x9290,
-+	0x0005, 0x2214, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016,
-+	0x2009, 0x0035, 0x080c, 0xaf4e, 0x001e, 0x1158, 0x622c, 0x2268,
-+	0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006,
-+	0x0128, 0x080c, 0x8ed9, 0x0020, 0x0039, 0x0010, 0x080c, 0x946d,
-+	0x002e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6814, 0x2078, 0x9186,
-+	0x0015, 0x0904, 0x9454, 0x918e, 0x0016, 0x1904, 0x946b, 0x700c,
-+	0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904,
-+	0x9433, 0x8fff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0x9417,
-+	0x0804, 0x9469, 0x6808, 0x9086, 0xffff, 0x1904, 0x9456, 0x787c,
-+	0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0x783c, 0x7940, 0x9105,
-+	0x1904, 0x9456, 0x080c, 0xab11, 0x685c, 0x7882, 0x787c, 0xc0dc,
-+	0xc0f4, 0xc0d4, 0x787e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a,
-+	0x080c, 0x73f0, 0x7884, 0x920a, 0x0208, 0x8011, 0x7a86, 0x82ff,
-+	0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xa6d9, 0x00ce, 0x0804,
-+	0x9469, 0x00c6, 0x00d6, 0x2f68, 0x6868, 0xd0fc, 0x1118, 0x080c,
-+	0x5151, 0x0010, 0x080c, 0x54d0, 0x00de, 0x00ce, 0x1904, 0x9456,
-+	0x00c6, 0x2d60, 0x080c, 0x8ed9, 0x00ce, 0x0804, 0x9469, 0x00c6,
-+	0x080c, 0x8f26, 0x0190, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c,
-+	0xad70, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0x8ed9,
-+	0x00ce, 0x080c, 0x8f53, 0x00ce, 0x04e0, 0x2001, 0x12c2, 0x2004,
-+	0x6842, 0x00ce, 0x04b0, 0x7008, 0x9086, 0x000b, 0x11a0, 0x6010,
-+	0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7883, 0x0003, 0x6007,
-+	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x756e, 0x080c,
-+	0x7aa4, 0x00ce, 0x00f0, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001,
-+	0x12c2, 0x2004, 0x6842, 0x00a8, 0x0481, 0x00a8, 0x8fff, 0x090c,
-+	0x0d7e, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x6867, 0x0103, 0x687b,
-+	0x0003, 0x080c, 0xa5b9, 0x080c, 0xab11, 0x080c, 0x8f09, 0x00de,
-+	0x00ce, 0x080c, 0x8ed9, 0x00fe, 0x0005, 0x9186, 0x0015, 0x1128,
-+	0x2001, 0x12c2, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, 0x1160,
-+	0x00c6, 0x2d00, 0x2060, 0x080c, 0xc381, 0x080c, 0x7384, 0x080c,
-+	0x8ed9, 0x00ce, 0x080c, 0x8ed9, 0x0005, 0x0026, 0x0036, 0x0046,
-+	0x7228, 0x7cb0, 0x7bac, 0xd2f4, 0x0130, 0x2001, 0x12c2, 0x2004,
-+	0x6842, 0x0804, 0x94e9, 0x00c6, 0x2d60, 0x080c, 0xa5e6, 0x00ce,
-+	0x6804, 0x9086, 0x0050, 0x1170, 0x00c6, 0x2d00, 0x2060, 0x6003,
-+	0x0001, 0x6007, 0x0050, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x00ce,
-+	0x0804, 0x94e9, 0x6800, 0x9086, 0x000f, 0x01c8, 0x8fff, 0x090c,
-+	0x0d7e, 0x6824, 0xd0dc, 0x1198, 0x6800, 0x9086, 0x0004, 0x1198,
-+	0x787c, 0xd0ac, 0x0180, 0x7843, 0x0fff, 0x783f, 0x0fff, 0x7880,
-+	0xc0f4, 0xc0fc, 0x7882, 0x2001, 0x0001, 0x6832, 0x00e8, 0x2001,
-+	0x0007, 0x6832, 0x00c8, 0x787c, 0xd0b4, 0x1138, 0xd0ac, 0x0db8,
-+	0x7838, 0x7934, 0x9105, 0x0d98, 0x0c30, 0xd2ec, 0x1d80, 0x7024,
-+	0x9306, 0x1118, 0x7020, 0x9406, 0x0d50, 0x7020, 0x683e, 0x7024,
-+	0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xac68, 0x080c, 0x7aa4,
-+	0x0010, 0x080c, 0x8ed9, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6,
-+	0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x9290, 0x0004,
-+	0x2214, 0x9206, 0x1904, 0x9561, 0x700c, 0x6210, 0x9290, 0x0005,
-+	0x2214, 0x9206, 0x1904, 0x9561, 0x6038, 0x2068, 0x6a20, 0x9286,
-+	0x0007, 0x0904, 0x955f, 0x9286, 0x0002, 0x0904, 0x955f, 0x9286,
-+	0x0000, 0x0904, 0x955f, 0x6808, 0x633c, 0x9306, 0x1904, 0x955f,
-+	0x2071, 0x026c, 0x9186, 0x0015, 0x05e0, 0x918e, 0x0016, 0x1190,
-+	0x6034, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1160, 0x700c, 0x9086,
-+	0x2a00, 0x1140, 0x6038, 0x9080, 0x0009, 0x200c, 0xc1dd, 0xc1f5,
-+	0x2102, 0x0438, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b,
-+	0x01a0, 0x9186, 0x004c, 0x0188, 0x9186, 0x004d, 0x0170, 0x9186,
-+	0x004e, 0x0158, 0x9186, 0x0052, 0x0140, 0x6014, 0x2068, 0x080c,
-+	0xa942, 0x090c, 0x0d7e, 0x6883, 0x0003, 0x6007, 0x0085, 0x6003,
-+	0x000b, 0x6023, 0x0002, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x00ce,
-+	0x0030, 0x6038, 0x2070, 0x2001, 0x12c2, 0x2004, 0x7042, 0x080c,
-+	0x8ed9, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x00f6, 0x6014,
-+	0x2068, 0x6010, 0x2078, 0x91b6, 0x0015, 0x0130, 0x7a08, 0x7b0c,
-+	0x7c00, 0xc48c, 0x7c02, 0x0448, 0x0156, 0x0036, 0x0026, 0x9e90,
-+	0x000c, 0x9290, 0x0004, 0x20a9, 0x0004, 0x9f98, 0x000a, 0x080c,
-+	0x9d60, 0x002e, 0x003e, 0x015e, 0x15f0, 0x0156, 0x0036, 0x0026,
-+	0x9e90, 0x000c, 0x9290, 0x0008, 0x20a9, 0x0004, 0x9f98, 0x0006,
-+	0x080c, 0x9d60, 0x002e, 0x003e, 0x015e, 0x1568, 0x7238, 0x7a0a,
-+	0x733c, 0x7b0e, 0x7c00, 0xc48d, 0x7c02, 0x6804, 0x9005, 0x1120,
-+	0x00fe, 0x00de, 0x0804, 0x9275, 0x9080, 0x0002, 0x00d6, 0x2068,
-+	0x6a0a, 0x6b0e, 0x6c02, 0x00de, 0x2009, 0x002b, 0x6aa0, 0x6b9c,
-+	0x6ca8, 0x6da4, 0x2031, 0x0000, 0x2039, 0x0001, 0x2041, 0x1078,
-+	0x080c, 0x9367, 0x0128, 0x00fe, 0x00de, 0x080c, 0x8ed9, 0x0005,
-+	0x080c, 0x97dc, 0x0cc0, 0x00f6, 0x080c, 0x2862, 0x00fe, 0x00c6,
-+	0x080c, 0x8e83, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001,
-+	0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x5568,
-+	0x080c, 0x5592, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x00ce, 0x0804,
-+	0x959d, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d7e, 0x91b2, 0x0040,
-+	0x1a04, 0x963f, 0x0002, 0x962d, 0x962d, 0x962d, 0x962d, 0x962d,
-+	0x962d, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b,
-+	0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b,
-+	0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b,
-+	0x962b, 0x962b, 0x962d, 0x962b, 0x962d, 0x962d, 0x962b, 0x962b,
-+	0x962b, 0x962b, 0x962b, 0x962d, 0x962b, 0x962b, 0x962b, 0x962b,
-+	0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962d, 0x962d, 0x962b,
-+	0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b, 0x962b,
-+	0x962d, 0x962b, 0x962b, 0x080c, 0x0d7e, 0x6003, 0x0001, 0x6106,
-+	0x9186, 0x0032, 0x0118, 0x080c, 0x75be, 0x0010, 0x080c, 0x756e,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x7aa4, 0x012e, 0x0005, 0x2600,
-+	0x0002, 0x9653, 0x9653, 0x9653, 0x962d, 0x962d, 0x9653, 0x9653,
-+	0x9653, 0x9653, 0x962d, 0x9653, 0x962d, 0x9653, 0x962d, 0x9653,
-+	0x9653, 0x9653, 0x9653, 0x080c, 0x0d7e, 0x6004, 0x90b2, 0x0053,
-+	0x1a0c, 0x0d7e, 0x91b6, 0x0013, 0x0904, 0x9702, 0x91b6, 0x0027,
-+	0x1904, 0x96c8, 0x080c, 0x79ab, 0x6004, 0x080c, 0xab1d, 0x0190,
-+	0x080c, 0xab2e, 0x0904, 0x96c2, 0x908e, 0x0021, 0x0904, 0x96c5,
-+	0x908e, 0x0022, 0x0904, 0x96c2, 0x908e, 0x003d, 0x0904, 0x96c5,
-+	0x0804, 0x96bb, 0x080c, 0x2886, 0x2001, 0x0007, 0x080c, 0x5568,
-+	0x6010, 0x9080, 0x0028, 0x200c, 0x080c, 0x97dc, 0x9186, 0x007e,
-+	0x1148, 0x2001, 0x1136, 0x2014, 0xc285, 0x080c, 0x62e4, 0x1108,
-+	0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019,
-+	0x0028, 0x080c, 0x8ac9, 0x002e, 0x080c, 0xc3d4, 0x003e, 0x002e,
-+	0x001e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c,
-+	0x76f0, 0x0076, 0x903e, 0x080c, 0x75ee, 0x6010, 0x00c6, 0x9065,
-+	0x0100, 0x00ce, 0x2c08, 0x080c, 0xbec2, 0x007e, 0x003e, 0x002e,
-+	0x001e, 0x080c, 0x55d0, 0x080c, 0xad68, 0x080c, 0x8ed9, 0x080c,
-+	0x7aa4, 0x0005, 0x080c, 0x97dc, 0x0cb0, 0x080c, 0x9809, 0x0c98,
-+	0x9186, 0x0014, 0x1db0, 0x080c, 0x79ab, 0x080c, 0x2862, 0x080c,
-+	0xab1d, 0x1188, 0x080c, 0x2886, 0x6010, 0x9080, 0x0028, 0x200c,
-+	0x080c, 0x97dc, 0x9186, 0x007e, 0x1128, 0x2001, 0x1136, 0x200c,
-+	0xc185, 0x2102, 0x08c0, 0x080c, 0xab2e, 0x1118, 0x080c, 0x97dc,
-+	0x0890, 0x6004, 0x908e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071,
-+	0x1193, 0x2079, 0x0000, 0x080c, 0x2b98, 0x00fe, 0x00ee, 0x0818,
-+	0x6004, 0x908e, 0x0021, 0x0d50, 0x908e, 0x0022, 0x090c, 0x97dc,
-+	0x0804, 0x96bb, 0x90b2, 0x0040, 0x1a04, 0x97c5, 0x2008, 0x0002,
-+	0x974a, 0x974b, 0x974e, 0x9751, 0x9754, 0x9757, 0x9748, 0x9748,
-+	0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748,
-+	0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748,
-+	0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x975a, 0x9769,
-+	0x9748, 0x976b, 0x9769, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748,
-+	0x9769, 0x9769, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748, 0x9748,
-+	0x9748, 0x9748, 0x97a5, 0x9769, 0x9748, 0x9765, 0x9748, 0x9748,
-+	0x9748, 0x9766, 0x9748, 0x9748, 0x9748, 0x9769, 0x979c, 0x9748,
-+	0x080c, 0x0d7e, 0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003,
-+	0x0448, 0x2001, 0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001,
-+	0x0009, 0x0400, 0x080c, 0x79ab, 0x6003, 0x0005, 0x2001, 0x12c2,
-+	0x2004, 0x6042, 0x080c, 0x7aa4, 0x00a0, 0x0018, 0x0010, 0x080c,
-+	0x5568, 0x0804, 0x97b6, 0x080c, 0x79ab, 0x2001, 0x12c0, 0x2004,
-+	0x601a, 0x2001, 0x12c2, 0x2004, 0x6042, 0x6003, 0x0004, 0x080c,
-+	0x7aa4, 0x0005, 0x080c, 0x5568, 0x080c, 0x79ab, 0x6003, 0x0002,
-+	0x2001, 0x12c2, 0x2004, 0x6042, 0x0036, 0x2019, 0x115d, 0x2304,
-+	0x9084, 0xff00, 0x1120, 0x2001, 0x12c0, 0x201c, 0x0040, 0x8007,
-+	0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
-+	0x003e, 0x080c, 0x7aa4, 0x08e8, 0x080c, 0x79ab, 0x080c, 0xad68,
-+	0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x08a0, 0x00e6, 0x00f6, 0x2071,
-+	0x1193, 0x2079, 0x0000, 0x080c, 0x2b98, 0x00fe, 0x00ee, 0x080c,
-+	0x79ab, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0818, 0x080c, 0x79ab,
-+	0x2001, 0x12c2, 0x2004, 0x6042, 0x6003, 0x0002, 0x2001, 0x12c0,
-+	0x2004, 0x601a, 0x080c, 0x7aa4, 0x0005, 0x2600, 0x2008, 0x0002,
-+	0x97da, 0x97da, 0x97da, 0x97b6, 0x97b6, 0x97da, 0x97da, 0x97da,
-+	0x97da, 0x97b6, 0x97da, 0x97b6, 0x97da, 0x97b6, 0x97da, 0x97da,
-+	0x97da, 0x97da, 0x080c, 0x0d7e, 0x00e6, 0x0026, 0x0016, 0x080c,
-+	0xa942, 0x0500, 0x6014, 0x2070, 0x7064, 0x9086, 0x0139, 0x1140,
-+	0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xaec0, 0x0090,
-+	0x7068, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0x908e,
-+	0x0021, 0x0160, 0x908e, 0x003d, 0x0148, 0x001e, 0x7067, 0x0103,
-+	0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009,
-+	0x0cc8, 0x00e6, 0x9cf0, 0x0005, 0x2e74, 0x7000, 0x2070, 0x7067,
-+	0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6610, 0x2668,
-+	0x6804, 0x9084, 0x00ff, 0x00de, 0x90b2, 0x000c, 0x1a0c, 0x0d7e,
-+	0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xadf6, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xae39, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xae66, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xad8b, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xab5e, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xab9a, 0x0804, 0x9892,
-+	0x6604, 0x96b6, 0x001f, 0x1118, 0x080c, 0x9255, 0x04d8, 0x6604,
-+	0x96b6, 0x0000, 0x1118, 0x080c, 0x9565, 0x04a0, 0x6604, 0x96b6,
-+	0x0022, 0x1118, 0x080c, 0x9283, 0x0468, 0x6604, 0x96b6, 0x0035,
-+	0x1118, 0x080c, 0x9381, 0x0430, 0x6604, 0x96b6, 0x0039, 0x1118,
-+	0x080c, 0x94ef, 0x00f8, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c,
-+	0x929d, 0x00c0, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0x92d5,
-+	0x0088, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0x9319, 0x0050,
-+	0x91b6, 0x0015, 0x1110, 0x0053, 0x0028, 0x91b6, 0x0016, 0x1118,
-+	0x0804, 0x9ab5, 0x0005, 0x080c, 0x8f6e, 0x0ce0, 0x98b0, 0x98b3,
-+	0x98b0, 0x98f6, 0x98b0, 0x9a2c, 0x9ac3, 0x98b0, 0x98b0, 0x9a8f,
-+	0x98b0, 0x9aa5, 0x00e6, 0x080c, 0x1303, 0x9cf0, 0x0005, 0x2e74,
-+	0x7000, 0x2070, 0x7067, 0x0103, 0x00ee, 0x080c, 0x8ed9, 0x0005,
-+	0xa001, 0xa001, 0x0005, 0x00e6, 0x2071, 0x1100, 0x7088, 0x9086,
-+	0x0074, 0x1540, 0x080c, 0xbe99, 0x11b0, 0x6010, 0x00d6, 0x2068,
-+	0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5, 0x6802,
-+	0x00e9, 0x00de, 0x2001, 0x0006, 0x080c, 0x5568, 0x080c, 0x2886,
-+	0x080c, 0x8ed9, 0x0088, 0x2001, 0x000a, 0x080c, 0x5568, 0x080c,
-+	0x2886, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x0010, 0x080c, 0x9a13, 0x00ee, 0x0005, 0x6800, 0xd084,
-+	0x0160, 0x9006, 0x080c, 0x5556, 0x2069, 0x1152, 0x6804, 0xd0a4,
-+	0x0120, 0x2001, 0x0006, 0x080c, 0x5592, 0x0005, 0x00d6, 0x2011,
-+	0x1122, 0x2204, 0x9086, 0x0074, 0x1904, 0x9a10, 0x6010, 0x2068,
-+	0x6aa0, 0x9286, 0x007e, 0x1120, 0x080c, 0x9c04, 0x0804, 0x9971,
-+	0x080c, 0x9bfa, 0x6010, 0x2068, 0x6aa0, 0x9286, 0x0080, 0x1530,
-+	0x6813, 0x00ff, 0x6817, 0xfffc, 0x6014, 0x9005, 0x01a8, 0x2068,
-+	0x6864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000,
-+	0x900e, 0x2011, 0x4000, 0x080c, 0xaec0, 0x0030, 0x6807, 0x0000,
-+	0x6867, 0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x080c, 0x5568,
-+	0x080c, 0x2886, 0x080c, 0x8ed9, 0x0804, 0x9a11, 0x00e6, 0x2071,
-+	0x1136, 0x2e04, 0xd09c, 0x0188, 0x2071, 0x0260, 0x7108, 0x720c,
-+	0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0138, 0x6010, 0x2070,
-+	0x70a0, 0xd0bc, 0x1110, 0x7112, 0x7216, 0x00ee, 0x6014, 0x9005,
-+	0x0190, 0x2068, 0x6868, 0xd0f4, 0x0170, 0x6864, 0x9084, 0x00ff,
-+	0x9086, 0x0039, 0x1958, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
-+	0x080c, 0xaec0, 0x0848, 0x2001, 0x0004, 0x080c, 0x5568, 0x6003,
-+	0x0001, 0x6007, 0x0003, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0804,
-+	0x9a11, 0x685c, 0xd0e4, 0x01d8, 0x080c, 0xad0a, 0x080c, 0x62e4,
-+	0x0118, 0xd0dc, 0x1904, 0x992c, 0x2011, 0x1136, 0x2204, 0xc0ad,
-+	0x2012, 0x2001, 0x1298, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3,
-+	0x0000, 0x080c, 0x1fb8, 0x78e2, 0x00fe, 0x0804, 0x992c, 0x080c,
-+	0xad47, 0x2011, 0x1136, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c,
-+	0xbfdb, 0x000e, 0x1904, 0x992c, 0xc0b5, 0x2012, 0x2001, 0x0006,
-+	0x080c, 0x5568, 0x9006, 0x080c, 0x5556, 0x00c6, 0x2001, 0x110e,
-+	0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071,
-+	0x1100, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x7076, 0x7010, 0x78ea,
-+	0x707a, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe,
-+	0x080c, 0x1f8d, 0x00f6, 0x2100, 0x900e, 0x080c, 0x1f63, 0x7956,
-+	0x00fe, 0x9186, 0x0081, 0x01d8, 0x2009, 0x0081, 0x00c8, 0x2009,
-+	0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x780c,
-+	0xc0b5, 0x780e, 0x00fe, 0x080c, 0x1f8d, 0x00f6, 0x2079, 0x1100,
-+	0x797a, 0x2100, 0x900e, 0x080c, 0x1f63, 0x7956, 0x00fe, 0x8108,
-+	0x080c, 0x55b3, 0x2c00, 0x00ce, 0x1904, 0x992c, 0x6012, 0x2009,
-+	0x110e, 0x210c, 0xd19c, 0x0168, 0x2009, 0x027c, 0x9080, 0x0004,
-+	0x210c, 0x918c, 0x00ff, 0x2102, 0x2009, 0x027d, 0x210c, 0x8000,
-+	0x2102, 0x2001, 0x0002, 0x080c, 0x5568, 0x6023, 0x0001, 0x6003,
-+	0x0001, 0x6007, 0x0002, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0008,
-+	0x0011, 0x00de, 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x5568,
-+	0x2001, 0x1100, 0x2004, 0x9086, 0x0003, 0x1120, 0x2001, 0x0007,
-+	0x080c, 0x5592, 0x080c, 0x2886, 0x6020, 0x9086, 0x000a, 0x1108,
-+	0x0005, 0x080c, 0x8ed9, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
-+	0x1100, 0x7088, 0x9086, 0x0014, 0x1904, 0x9a87, 0x7000, 0x9086,
-+	0x0003, 0x1178, 0x6014, 0x9005, 0x1160, 0x0036, 0x0046, 0x6010,
-+	0x9080, 0x0028, 0x201c, 0x2021, 0x0006, 0x080c, 0x4026, 0x004e,
-+	0x003e, 0x00d6, 0x6010, 0x2068, 0x080c, 0x56a8, 0x080c, 0x98e6,
-+	0x00de, 0x080c, 0x9cc9, 0x1598, 0x6010, 0x00d6, 0x2068, 0x6890,
-+	0x00de, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x5568, 0x00e6,
-+	0x6014, 0x9075, 0x01d0, 0x7064, 0x9084, 0x00ff, 0x9086, 0x0039,
-+	0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xaec0,
-+	0x0060, 0x7064, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0x7007,
-+	0x0000, 0x7067, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2886,
-+	0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x8ed9, 0x0020, 0x080c,
-+	0x97dc, 0x080c, 0x9a13, 0x001e, 0x002e, 0x00ee, 0x0005, 0x2011,
-+	0x1122, 0x2204, 0x9086, 0x0014, 0x1168, 0x2001, 0x0002, 0x080c,
-+	0x5568, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x0010, 0x080c, 0x9a13, 0x0005, 0x2011, 0x1122, 0x2204,
-+	0x9086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c, 0x5568, 0x080c,
-+	0x8ed9, 0x0010, 0x080c, 0x9a13, 0x0005, 0x000b, 0x0005, 0x98b0,
-+	0x9ace, 0x98b0, 0x9b03, 0x98b0, 0x9bb0, 0x9ac3, 0x98b0, 0x98b0,
-+	0x9bc5, 0x98b0, 0x9bd7, 0x6604, 0x9686, 0x0003, 0x0904, 0x9a2c,
-+	0x96b6, 0x001e, 0x1110, 0x080c, 0x8ed9, 0x0005, 0x00d6, 0x00c6,
-+	0x080c, 0x9be9, 0x1180, 0x9006, 0x080c, 0x5556, 0x2001, 0x0002,
-+	0x080c, 0x5568, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x75be,
-+	0x080c, 0x7aa4, 0x00e8, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009,
-+	0x1160, 0x6010, 0x2068, 0x6840, 0x9084, 0x00ff, 0x9005, 0x0170,
-+	0x8001, 0x6842, 0x601b, 0x000a, 0x0058, 0x2009, 0x026f, 0x2104,
-+	0x9084, 0xff00, 0x9086, 0x1900, 0x1108, 0x08c0, 0x080c, 0x9a13,
-+	0x00ce, 0x00de, 0x0005, 0x0026, 0x9016, 0x080c, 0x9bf7, 0x00d6,
-+	0x2069, 0x12a7, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2068, 0x68a0,
-+	0x9086, 0x007e, 0x1138, 0x2069, 0x111e, 0x2d04, 0x8000, 0x206a,
-+	0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x5556, 0x2001,
-+	0x0002, 0x080c, 0x5568, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-+	0x75be, 0x080c, 0x7aa4, 0x0804, 0x9b7e, 0x080c, 0xa942, 0x01b0,
-+	0x6014, 0x9080, 0x0019, 0x2004, 0x2010, 0x9086, 0x0139, 0x1128,
-+	0x2001, 0x0002, 0x080c, 0xaf0f, 0x00c8, 0x6014, 0x9080, 0x001a,
-+	0x2004, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca0, 0x2001, 0x110d,
-+	0x2004, 0xd0dc, 0x0158, 0x6010, 0x00d6, 0x2068, 0x6840, 0x00de,
-+	0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c20, 0x080c, 0x97dc,
-+	0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0500,
-+	0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
-+	0x1118, 0x9686, 0x0009, 0x01a0, 0x9086, 0x1900, 0x1168, 0x9686,
-+	0x0009, 0x0170, 0x2001, 0x0004, 0x080c, 0x5568, 0x2001, 0x0028,
-+	0x601a, 0x6007, 0x0052, 0x0010, 0x080c, 0x9a13, 0x002e, 0x0005,
-+	0x00d6, 0x9286, 0x0139, 0x0160, 0x6014, 0x2068, 0x080c, 0xa942,
-+	0x0148, 0x6864, 0x9086, 0x0139, 0x0118, 0x6868, 0xd0fc, 0x0110,
-+	0x00de, 0x0c50, 0x6010, 0x2068, 0x6840, 0x9084, 0x00ff, 0x9005,
-+	0x0140, 0x8001, 0x6842, 0x601b, 0x000a, 0x6007, 0x0016, 0x00de,
-+	0x08e8, 0x68a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1100,
-+	0x080c, 0x5092, 0x00ee, 0x0010, 0x080c, 0x2862, 0x00de, 0x0860,
-+	0x080c, 0x9bf7, 0x1168, 0x2001, 0x0004, 0x080c, 0x5568, 0x6003,
-+	0x0001, 0x6007, 0x0003, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0020,
-+	0x080c, 0x97dc, 0x080c, 0x9a13, 0x0005, 0x0489, 0x1168, 0x2001,
-+	0x0008, 0x080c, 0x5568, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
-+	0x75be, 0x080c, 0x7aa4, 0x0010, 0x080c, 0x9a13, 0x0005, 0x00f9,
-+	0x1168, 0x2001, 0x000a, 0x080c, 0x5568, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0010, 0x080c, 0x9a13,
-+	0x0005, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009,
-+	0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085,
-+	0x0001, 0x0005, 0x00c6, 0x0016, 0x9c88, 0x0004, 0x2164, 0x080c,
-+	0x5617, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x0036,
-+	0x0016, 0x6010, 0x2068, 0x2009, 0x1136, 0x2104, 0x9085, 0x0003,
-+	0x200a, 0x080c, 0x9c9e, 0x0560, 0x2009, 0x1136, 0x2104, 0xc0cd,
-+	0x200a, 0x080c, 0x58cb, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a,
-+	0x080c, 0xc12f, 0x2001, 0x110c, 0x200c, 0xc195, 0x2102, 0x2019,
-+	0x002a, 0x2009, 0x0001, 0x080c, 0x2831, 0x00e6, 0x2071, 0x1100,
-+	0x080c, 0x2679, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0081, 0x2009,
-+	0x007f, 0x080c, 0x2955, 0x8108, 0x1f04, 0x9c39, 0x015e, 0x00ce,
-+	0x080c, 0x9bfa, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0x0260,
-+	0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1136, 0x200c, 0xc1c5,
-+	0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108,
-+	0xc1c4, 0x7817, 0x0000, 0x2001, 0x1136, 0x2102, 0x2079, 0x0100,
-+	0x2e04, 0x9084, 0x00ff, 0x2069, 0x111d, 0x206a, 0x78e6, 0x0006,
-+	0x8e70, 0x2e04, 0x2069, 0x111e, 0x206a, 0x78ea, 0x7832, 0x7836,
-+	0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x112a, 0x200a,
-+	0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x1f8d, 0x080c, 0x62e4,
-+	0x0170, 0x2071, 0x0260, 0x2069, 0x12bc, 0x7048, 0x206a, 0x704c,
-+	0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xad0a, 0x0040,
-+	0x2001, 0x0006, 0x080c, 0x5568, 0x080c, 0x2886, 0x080c, 0x8ed9,
-+	0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036,
-+	0x00e6, 0x0156, 0x2019, 0x112a, 0x231c, 0x83ff, 0x01e8, 0x2071,
-+	0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205,
-+	0x9306, 0x1190, 0x2011, 0x0276, 0x20a9, 0x0004, 0x9d98, 0x000a,
-+	0x080c, 0x9d60, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, 0x9d98,
-+	0x0006, 0x080c, 0x9d60, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e,
-+	0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8,
-+	0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084,
-+	0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac,
-+	0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6,
-+	0x00d6, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126,
-+	0x2091, 0x8000, 0x2029, 0x130d, 0x252c, 0x2021, 0x1313, 0x2424,
-+	0x2061, 0x15c0, 0x2071, 0x1100, 0x724c, 0x706c, 0x9202, 0x1a04,
-+	0x9d4c, 0x080c, 0xc15b, 0x0904, 0x9d45, 0x6720, 0x9786, 0x0001,
-+	0x05e0, 0x9786, 0x0007, 0x05c8, 0x2500, 0x9c06, 0x05b0, 0x2400,
-+	0x9c06, 0x0598, 0x3e08, 0x9186, 0x0002, 0x1140, 0x6010, 0x9005,
-+	0x0128, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x1538, 0x00c6, 0x6000,
-+	0x9086, 0x0004, 0x1110, 0x080c, 0x1509, 0x9786, 0x0008, 0x1148,
-+	0x080c, 0xab2e, 0x1130, 0x00ce, 0x080c, 0x97dc, 0x080c, 0x8f09,
-+	0x00a0, 0x6014, 0x2068, 0x080c, 0xa942, 0x0160, 0x9786, 0x0003,
-+	0x11e8, 0x6867, 0x0103, 0x6b7a, 0x6877, 0x0000, 0x080c, 0x5b76,
-+	0x080c, 0xab11, 0x080c, 0x8f09, 0x00ce, 0x9ce0, 0x0018, 0x7060,
-+	0x9c02, 0x1210, 0x0804, 0x9cfc, 0x012e, 0x000e, 0x002e, 0x004e,
-+	0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x9786, 0x0006,
-+	0x1118, 0x080c, 0xc0e9, 0x0c30, 0x9786, 0x000a, 0x09e0, 0x08c8,
-+	0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x9d60,
-+	0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008,
-+	0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906,
-+	0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300,
-+	0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140,
-+	0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005,
-+	0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000,
-+	0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x6004, 0x908a,
-+	0x0053, 0x1a0c, 0x0d7e, 0x080c, 0xab1d, 0x0120, 0x080c, 0xab2e,
-+	0x0168, 0x0028, 0x080c, 0x2886, 0x080c, 0xab2e, 0x0138, 0x080c,
-+	0x79ab, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x080c, 0x97dc,
-+	0x0cb0, 0x9182, 0x0040, 0x0002, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dcf,
-+	0x9dcf, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dd1,
-+	0x9dd1, 0x9dd1, 0x9dd1, 0x9dcf, 0x9dcf, 0x9dcf, 0x9dd1, 0x080c,
-+	0x0d7e, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x756e,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x7aa4, 0x012e, 0x0005, 0x9186,
-+	0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0x9e6c, 0x9186,
-+	0x0027, 0x11e8, 0x080c, 0x79ab, 0x080c, 0x2862, 0x00d6, 0x6114,
-+	0x2168, 0x080c, 0xa942, 0x0168, 0x6867, 0x0103, 0x687b, 0x0029,
-+	0x6877, 0x0000, 0x697c, 0xc1c5, 0x697e, 0x080c, 0x5b76, 0x080c,
-+	0xab11, 0x00de, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x9186,
-+	0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x0430, 0x9186, 0x0046,
-+	0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186,
-+	0x0048, 0x190c, 0x0d7e, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198,
-+	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x745c,
-+	0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002,
-+	0x1110, 0x0804, 0x9eaf, 0x0005, 0x0002, 0x9e4a, 0x9e48, 0x9e48,
-+	0x9e48, 0x9e48, 0x9e48, 0x9e48, 0x9e48, 0x9e48, 0x9e48, 0x9e48,
-+	0x9e65, 0x9e65, 0x9e65, 0x9e65, 0x9e48, 0x9e65, 0x9e48, 0x9e65,
-+	0x080c, 0x0d7e, 0x080c, 0x79ab, 0x00d6, 0x6114, 0x2168, 0x080c,
-+	0xa942, 0x0168, 0x6867, 0x0103, 0x687b, 0x0006, 0x6877, 0x0000,
-+	0x6880, 0xc0ec, 0x6882, 0x080c, 0x5b76, 0x080c, 0xab11, 0x00de,
-+	0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x080c, 0x79ab, 0x080c,
-+	0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x0002, 0x9e82, 0x9e80, 0x9e80,
-+	0x9e80, 0x9e80, 0x9e80, 0x9e80, 0x9e80, 0x9e80, 0x9e80, 0x9e80,
-+	0x9e99, 0x9e99, 0x9e99, 0x9e99, 0x9e80, 0x9ea8, 0x9e80, 0x9e99,
-+	0x080c, 0x0d7e, 0x00d6, 0x080c, 0x79ab, 0x6014, 0x2068, 0x2001,
-+	0x12c2, 0x2004, 0x6042, 0x697c, 0xd1ac, 0x0140, 0x6003, 0x0004,
-+	0x687c, 0x9085, 0x0400, 0x687e, 0x00de, 0x0005, 0x6003, 0x0002,
-+	0x0cb8, 0x080c, 0x79ab, 0x2001, 0x12c0, 0x2004, 0x601a, 0x2001,
-+	0x12c2, 0x2004, 0x6042, 0x6003, 0x000f, 0x080c, 0x7aa4, 0x0005,
-+	0x080c, 0x79ab, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x9182,
-+	0x0040, 0x0002, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec8,
-+	0x9fa9, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6,
-+	0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9ec6, 0x9fd8, 0x080c, 0x0d7e,
-+	0x00d6, 0x6114, 0x2168, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1518,
-+	0x6010, 0x2004, 0xd0bc, 0x1904, 0x9f94, 0x687b, 0x0000, 0x6867,
-+	0x0103, 0x6e76, 0x687c, 0xd0ac, 0x0128, 0x6834, 0x6938, 0x9115,
-+	0x190c, 0xa12c, 0x080c, 0x599a, 0x6210, 0x2268, 0x6a3c, 0x82ff,
-+	0x0110, 0x8211, 0x6a3e, 0x7044, 0xd0e4, 0x1904, 0x9f74, 0x080c,
-+	0x8ed9, 0x00de, 0x0005, 0x968c, 0x0c00, 0x0148, 0x6010, 0x2004,
-+	0xd0bc, 0x1904, 0x9f78, 0x7348, 0x6b92, 0x734c, 0x6b8e, 0x968c,
-+	0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0x687b,
-+	0x001c, 0x00e8, 0xd6dc, 0x01a0, 0x687b, 0x0015, 0x687c, 0xd0ac,
-+	0x0170, 0x6938, 0x6a34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
-+	0x1118, 0x704c, 0x9206, 0x0118, 0x6992, 0x6a8e, 0xc6dc, 0x0038,
-+	0xd6d4, 0x0118, 0x687b, 0x0007, 0x0010, 0x687b, 0x0000, 0x6867,
-+	0x0103, 0x6e76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
-+	0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0x9ece, 0x735c, 0x6b86,
-+	0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
-+	0x2308, 0x2019, 0x0018, 0x9d90, 0x0025, 0x080c, 0xa5c9, 0x003e,
-+	0xd6cc, 0x0904, 0x9ee2, 0x7154, 0x698a, 0x81ff, 0x0904, 0x9ee2,
-+	0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x9d90, 0x0029,
-+	0x080c, 0xa5c9, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xaf7b,
-+	0x0804, 0x9ee2, 0x6868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x698a,
-+	0x0c50, 0x00f6, 0x2d78, 0x080c, 0xa568, 0x00fe, 0x080c, 0xaf7b,
-+	0x080c, 0xa5b9, 0x0804, 0x9ee4, 0x080c, 0xac0b, 0x0804, 0x9ef1,
-+	0x687c, 0xd0ac, 0x0904, 0x9efb, 0x6024, 0xd0dc, 0x1904, 0x9efb,
-+	0x6880, 0xd0bc, 0x1904, 0x9efb, 0x7348, 0x6838, 0x9306, 0x11e8,
-+	0x734c, 0x6834, 0x931e, 0x0904, 0x9efb, 0xd6d4, 0x01b0, 0x6b38,
-+	0x9305, 0x0904, 0x9efb, 0x0088, 0x687c, 0xd0ac, 0x0904, 0x9ed5,
-+	0x6838, 0x6934, 0x9105, 0x0904, 0x9ed5, 0x6024, 0xd0dc, 0x1904,
-+	0x9ed5, 0x6880, 0xd0bc, 0x1904, 0x9ed5, 0x080c, 0xac39, 0x0804,
-+	0x9ef1, 0x00f6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00,
-+	0x7e0c, 0x7d08, 0x6014, 0x2078, 0x787c, 0xd0ac, 0x0138, 0x6003,
-+	0x0002, 0x00fe, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0x79ac,
-+	0x910a, 0x2300, 0x7ab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203,
-+	0x0e90, 0x7c36, 0x7b3a, 0x7e46, 0x7d4a, 0x00fe, 0x6043, 0x0000,
-+	0x2c10, 0x080c, 0x1605, 0x080c, 0x75db, 0x080c, 0x7b72, 0x0005,
-+	0x0005, 0x9182, 0x0040, 0x0002, 0x9fef, 0x9fef, 0x9fef, 0x9fef,
-+	0x9fef, 0x9ff1, 0xa085, 0x9fef, 0x9fef, 0xa09b, 0xa103, 0x9fef,
-+	0x9fef, 0x9fef, 0x9fef, 0xa112, 0x9fef, 0x9fef, 0x9fef, 0x080c,
-+	0x0d7e, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0x0260, 0x6114,
-+	0x2178, 0x7644, 0x7e76, 0x96b4, 0x0fff, 0x7f7c, 0xc7e5, 0x7f7e,
-+	0x6210, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x86ff,
-+	0x0904, 0xa080, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048,
-+	0x7892, 0x704c, 0x788e, 0x9284, 0x0300, 0x0904, 0xa080, 0x080c,
-+	0x0eb6, 0x090c, 0x0d7e, 0x2d00, 0x787a, 0x7f7c, 0xc7cd, 0x7f7e,
-+	0x6867, 0x0103, 0x7868, 0x686a, 0x786c, 0x686e, 0x7870, 0x6872,
-+	0x6e76, 0x968c, 0x0c00, 0x0120, 0x7348, 0x6b92, 0x734c, 0x6b8e,
-+	0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
-+	0x687b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x687b, 0x0015, 0x0038,
-+	0xd6d4, 0x0118, 0x687b, 0x0007, 0x0010, 0x687b, 0x0000, 0x6f7e,
-+	0x7880, 0x6882, 0x7884, 0x6886, 0x901e, 0xd6c4, 0x0190, 0x735c,
-+	0x6b86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
-+	0x0036, 0x2308, 0x2019, 0x0018, 0x9d90, 0x0025, 0x080c, 0xa5c9,
-+	0x003e, 0xd6cc, 0x01e8, 0x7154, 0x698a, 0x81ff, 0x01c8, 0x9192,
-+	0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x9d90, 0x0029, 0x080c,
-+	0xa5c9, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0x7868, 0xd0fc,
-+	0x0120, 0x2009, 0x0020, 0x698a, 0x0c68, 0x2d78, 0x080c, 0xa568,
-+	0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6, 0x6003, 0x0003,
-+	0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2078,
-+	0x7c36, 0x7b3a, 0x7e46, 0x7d4a, 0x00fe, 0x2c10, 0x080c, 0x1605,
-+	0x080c, 0x856f, 0x0005, 0x00d6, 0x2001, 0x12c2, 0x2004, 0x6042,
-+	0x6003, 0x0002, 0x080c, 0x7a55, 0x080c, 0x7b72, 0x6114, 0x2168,
-+	0x697c, 0xd1e4, 0x0904, 0xa0fe, 0xd1cc, 0x0570, 0x6978, 0x6868,
-+	0xd0fc, 0x0500, 0x0016, 0x687c, 0x0006, 0x6880, 0x0006, 0x9d90,
-+	0x0019, 0x9198, 0x0019, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304,
-+	0x2012, 0x8318, 0x8210, 0x1f04, 0xa0bf, 0x015e, 0x000e, 0x6882,
-+	0x000e, 0x687e, 0x001e, 0x6874, 0x0006, 0x2168, 0x080c, 0x0edf,
-+	0x001e, 0x0440, 0x0016, 0x080c, 0x0edf, 0x00de, 0x6974, 0x0016,
-+	0x080c, 0xa5b9, 0x001e, 0x00f0, 0x6867, 0x0103, 0x6974, 0x9184,
-+	0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, 0x0028, 0x1118, 0x687b,
-+	0x001c, 0x0060, 0xd1dc, 0x0118, 0x687b, 0x0015, 0x0038, 0xd1d4,
-+	0x0118, 0x687b, 0x0007, 0x0010, 0x687b, 0x0000, 0x0016, 0x080c,
-+	0x599a, 0x001e, 0xd1e4, 0x1120, 0x080c, 0x8ed9, 0x00de, 0x0005,
-+	0x080c, 0xac0b, 0x0cd8, 0x2019, 0x0001, 0x080c, 0x8847, 0x6003,
-+	0x0002, 0x2001, 0x12c2, 0x2004, 0x6042, 0x080c, 0x7a55, 0x080c,
-+	0x7b72, 0x0005, 0x080c, 0x7a55, 0x080c, 0x2862, 0x00d6, 0x6114,
-+	0x2168, 0x080c, 0xa942, 0x0150, 0x6867, 0x0103, 0x687b, 0x0029,
-+	0x6877, 0x0000, 0x080c, 0x5b76, 0x080c, 0xab11, 0x00de, 0x080c,
-+	0x8ed9, 0x080c, 0x7b72, 0x0005, 0x687b, 0x0015, 0xd1fc, 0x0138,
-+	0x687b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x6992,
-+	0x688e, 0x0005, 0x9182, 0x0040, 0x0002, 0xa151, 0xa151, 0xa151,
-+	0xa151, 0xa151, 0xa153, 0xa151, 0xa151, 0xa1f7, 0xa151, 0xa151,
-+	0xa151, 0xa151, 0xa151, 0xa151, 0xa151, 0xa151, 0xa151, 0xa151,
-+	0xa31d, 0x080c, 0x0d7e, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071,
-+	0x0260, 0x6114, 0x2178, 0x7644, 0x7e76, 0x96b4, 0x0fff, 0x7f7c,
-+	0xc7e5, 0x7f7e, 0x6210, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211,
-+	0x6a3e, 0x86ff, 0x0904, 0xa1f0, 0x9694, 0xff00, 0x9284, 0x0c00,
-+	0x0120, 0x7048, 0x7892, 0x704c, 0x788e, 0x9284, 0x0300, 0x0904,
-+	0xa1f0, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
-+	0x7e76, 0x0c38, 0x080c, 0x0eb6, 0x090c, 0x0d7e, 0x2d00, 0x787a,
-+	0x7f7c, 0x97bd, 0x0200, 0x7f7e, 0x6867, 0x0103, 0x7868, 0x686a,
-+	0x786c, 0x686e, 0x7870, 0x6872, 0x7044, 0x9084, 0xf000, 0x9635,
-+	0x6e76, 0x968c, 0x0c00, 0x0120, 0x7348, 0x6b92, 0x734c, 0x6b8e,
-+	0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
-+	0x687b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x687b, 0x0015, 0x0038,
-+	0xd6d4, 0x0118, 0x687b, 0x0007, 0x0010, 0x687b, 0x0000, 0x6f7e,
-+	0x7880, 0x6882, 0x7884, 0x6886, 0x901e, 0xd6c4, 0x0190, 0x735c,
-+	0x6b86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
-+	0x0036, 0x2308, 0x2019, 0x0018, 0x9d90, 0x0025, 0x080c, 0xa5c9,
-+	0x003e, 0xd6cc, 0x01e8, 0x7154, 0x698a, 0x81ff, 0x01c8, 0x9192,
-+	0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x9d90, 0x0029, 0x080c,
-+	0xa5c9, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0x7868, 0xd0fc,
-+	0x0120, 0x2009, 0x0020, 0x698a, 0x0c68, 0x2d78, 0x080c, 0xa568,
-+	0x080c, 0x14d3, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x2001,
-+	0x12c2, 0x2004, 0x6042, 0x00d6, 0x6114, 0x2168, 0x683c, 0x6940,
-+	0x9105, 0x1118, 0x687c, 0xc0dc, 0x687e, 0x6003, 0x0002, 0x697c,
-+	0xd1e4, 0x0904, 0xa318, 0x6043, 0x0000, 0x6010, 0x2004, 0xd0bc,
-+	0x11f8, 0xd1cc, 0x0904, 0xa2e7, 0x6978, 0x6868, 0xd0fc, 0x0904,
-+	0xa2a8, 0x0016, 0x687c, 0x0006, 0x6880, 0x0006, 0x00f6, 0x2178,
-+	0x7974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xa27b, 0x9086,
-+	0x0028, 0x15e8, 0x687b, 0x001c, 0x787b, 0x001c, 0x0804, 0xa283,
-+	0x6024, 0xd0f4, 0x11d0, 0x6838, 0x6a34, 0x9205, 0x09d0, 0x6838,
-+	0x6a90, 0x9206, 0x1120, 0x688c, 0x6a34, 0x9206, 0x0990, 0x6024,
-+	0xd0d4, 0x1148, 0x69ac, 0x6834, 0x9102, 0x603a, 0x69b0, 0x6838,
-+	0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00d6, 0x2068,
-+	0x683c, 0x8000, 0x683e, 0x00de, 0x9006, 0x6876, 0x6892, 0x688e,
-+	0x687c, 0xc0e4, 0x687e, 0xd0cc, 0x0130, 0x00d6, 0x6878, 0x2068,
-+	0x080c, 0x0edf, 0x00de, 0x080c, 0xac39, 0x0804, 0xa318, 0xd1dc,
-+	0x0158, 0x687b, 0x0015, 0x787b, 0x0015, 0x080c, 0xaea9, 0x0118,
-+	0x7974, 0xc1dc, 0x7976, 0x0078, 0xd1d4, 0x0128, 0x687b, 0x0007,
-+	0x787b, 0x0007, 0x0040, 0x687c, 0xd0ac, 0x0128, 0x6834, 0x6938,
-+	0x9115, 0x190c, 0xa12c, 0x687c, 0x787e, 0x6890, 0x7892, 0x688c,
-+	0x788e, 0x9d90, 0x0019, 0x9f98, 0x0019, 0x2009, 0x0020, 0x0156,
-+	0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0xa291, 0x015e,
-+	0x00fe, 0x000e, 0x6882, 0x000e, 0x687e, 0x080c, 0xaf7b, 0x001e,
-+	0x6874, 0x0006, 0x2168, 0x080c, 0x0edf, 0x001e, 0x0804, 0xa314,
-+	0x0016, 0x00f6, 0x2178, 0x7974, 0x9184, 0x00ff, 0x90b6, 0x0002,
-+	0x01e0, 0x9086, 0x0028, 0x1128, 0x687b, 0x001c, 0x787b, 0x001c,
-+	0x00e0, 0xd1dc, 0x0158, 0x687b, 0x0015, 0x787b, 0x0015, 0x080c,
-+	0xaea9, 0x0118, 0x7974, 0xc1dc, 0x7976, 0x0078, 0xd1d4, 0x0128,
-+	0x687b, 0x0007, 0x787b, 0x0007, 0x0040, 0x687c, 0xd0ac, 0x0128,
-+	0x6834, 0x6938, 0x9115, 0x190c, 0xa12c, 0x6890, 0x7892, 0x688c,
-+	0x788e, 0x687c, 0x787e, 0x00fe, 0x080c, 0x0edf, 0x00de, 0x080c,
-+	0xaf7b, 0x6974, 0x0016, 0x080c, 0xa5b9, 0x001e, 0x0468, 0x6867,
-+	0x0103, 0x6974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086,
-+	0x0028, 0x1118, 0x687b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0x687b,
-+	0x0015, 0x080c, 0xaea9, 0x0118, 0x6974, 0xc1dc, 0x6976, 0x0078,
-+	0xd1d4, 0x0118, 0x687b, 0x0007, 0x0050, 0x687b, 0x0000, 0x687c,
-+	0xd0ac, 0x0128, 0x6834, 0x6938, 0x9115, 0x190c, 0xa12c, 0x6974,
-+	0x0016, 0x080c, 0x599a, 0x001e, 0xd1e4, 0x1120, 0x080c, 0x8ed9,
-+	0x00de, 0x0005, 0x080c, 0xac0b, 0x0cd8, 0x0005, 0x080c, 0x79ab,
-+	0x0010, 0x080c, 0x7a55, 0x080c, 0xa942, 0x01c0, 0x00d6, 0x6114,
-+	0x2168, 0x6867, 0x0103, 0x2009, 0x110c, 0x210c, 0xd18c, 0x11c0,
-+	0xd184, 0x1198, 0x6108, 0x697a, 0x918e, 0x0029, 0x1110, 0x080c,
-+	0xc3c7, 0x6877, 0x0000, 0x080c, 0x5b76, 0x00de, 0x080c, 0x8ed9,
-+	0x080c, 0x7aa4, 0x080c, 0x7b72, 0x0005, 0x687b, 0x0004, 0x0c88,
-+	0x687b, 0x0004, 0x0c70, 0x9182, 0x0040, 0x0002, 0xa361, 0xa361,
-+	0xa361, 0xa361, 0xa361, 0xa363, 0xa361, 0xa366, 0xa361, 0xa361,
-+	0xa361, 0xa361, 0xa361, 0xa361, 0xa361, 0xa361, 0xa361, 0xa361,
-+	0xa361, 0x080c, 0x0d7e, 0x080c, 0x8ed9, 0x0005, 0x0006, 0x0026,
-+	0x9016, 0x080c, 0x137c, 0x002e, 0x000e, 0x0005, 0x9182, 0x0085,
-+	0x0002, 0xa380, 0xa37e, 0xa37e, 0xa38c, 0xa37e, 0xa37e, 0xa37e,
-+	0xa37e, 0xa37e, 0xa37e, 0xa37e, 0xa37e, 0xa37e, 0x080c, 0x0d7e,
-+	0x6003, 0x0001, 0x6106, 0x080c, 0x756e, 0x0126, 0x2091, 0x8000,
-+	0x080c, 0x7aa4, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6,
-+	0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xa932, 0x01a0,
-+	0x2268, 0x6800, 0x9086, 0x0000, 0x0178, 0x6010, 0x6d10, 0x952e,
-+	0x1158, 0x00c6, 0x2d60, 0x080c, 0xa5e6, 0x00ce, 0x0128, 0x6803,
-+	0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003, 0x0001,
-+	0x080c, 0x756e, 0x080c, 0x7aa4, 0x9280, 0x0004, 0x2004, 0xd0bc,
-+	0x0150, 0x6824, 0xd0ec, 0x0138, 0x00c6, 0x2260, 0x6043, 0x0000,
-+	0x080c, 0xac39, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005,
-+	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d7e,
-+	0x908a, 0x0092, 0x1a0c, 0x0d7e, 0x9082, 0x0085, 0x0072, 0x9186,
-+	0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d7e, 0x080c, 0x79ab,
-+	0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005, 0xa3f2, 0xa3f4, 0xa3f4,
-+	0xa3f2, 0xa3f2, 0xa3f2, 0xa3f2, 0xa3f2, 0xa3f2, 0xa3f2, 0xa3f2,
-+	0xa3f2, 0xa3f2, 0x080c, 0x0d7e, 0x080c, 0x79ab, 0x080c, 0x8f09,
-+	0x080c, 0x7aa4, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082,
-+	0x0085, 0x2008, 0x04a8, 0x9186, 0x0027, 0x11e8, 0x080c, 0x79ab,
-+	0x080c, 0x2862, 0x00d6, 0x6014, 0x2068, 0x080c, 0xa942, 0x0150,
-+	0x6867, 0x0103, 0x6877, 0x0000, 0x687b, 0x0029, 0x080c, 0x5b76,
-+	0x080c, 0xab11, 0x00de, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005,
-+	0x080c, 0x8f6e, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x79ab,
-+	0x00d6, 0x6014, 0x2068, 0x080c, 0xa942, 0x0d60, 0x6867, 0x0103,
-+	0x6877, 0x0000, 0x687b, 0x0006, 0x6880, 0xc0ec, 0x6882, 0x08f0,
-+	0x0002, 0xa448, 0xa446, 0xa446, 0xa446, 0xa446, 0xa446, 0xa460,
-+	0xa446, 0xa446, 0xa446, 0xa446, 0xa446, 0xa446, 0x080c, 0x0d7e,
-+	0x080c, 0x79ab, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039,
-+	0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x12c0, 0x0010, 0x2001,
-+	0x12c1, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x7aa4, 0x0005,
-+	0x080c, 0x79ab, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039,
-+	0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x12c0, 0x0010, 0x2001,
-+	0x12c1, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x7aa4, 0x0005,
-+	0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c,
-+	0x8f6e, 0x0005, 0xa48f, 0xa48f, 0xa48f, 0xa48f, 0xa491, 0xa4ea,
-+	0xa48f, 0xa48f, 0xa48f, 0xa48f, 0xa48f, 0xa48f, 0xa48f, 0x080c,
-+	0x0d7e, 0x00d6, 0x6010, 0x2004, 0xd0bc, 0x0168, 0x6034, 0x908c,
-+	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-+	0x00de, 0x0804, 0xa4fb, 0x080c, 0xa942, 0x1118, 0x080c, 0xab11,
-+	0x00f0, 0x6014, 0x2068, 0x687c, 0xd0e4, 0x1110, 0x080c, 0xab11,
-+	0x6867, 0x0103, 0x6880, 0xd0b4, 0x0128, 0x687b, 0x0006, 0xc0ec,
-+	0x6882, 0x0048, 0xd0bc, 0x0118, 0x687b, 0x0002, 0x0020, 0x687b,
-+	0x0005, 0x080c, 0xac07, 0x6877, 0x0000, 0x080c, 0x5b76, 0x2c68,
-+	0x080c, 0x8e83, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b,
-+	0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c,
-+	0x613e, 0x6910, 0x6112, 0x080c, 0xad70, 0x6954, 0x6156, 0x6023,
-+	0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x2d60, 0x080c, 0x8ed9,
-+	0x00de, 0x0005, 0x6010, 0x2004, 0xd0bc, 0x0598, 0x6034, 0x908c,
-+	0xff00, 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118,
-+	0x9186, 0x0039, 0x1530, 0x00d6, 0x2c68, 0x080c, 0xaf4e, 0x1904,
-+	0xa540, 0x080c, 0x8e83, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023,
-+	0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934,
-+	0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x6954,
-+	0x6156, 0x080c, 0xad70, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x2d60,
-+	0x00f8, 0x00d6, 0x6014, 0x2068, 0x080c, 0xa942, 0x01c8, 0x6867,
-+	0x0103, 0x6880, 0xd0b4, 0x0128, 0xc0ec, 0x6882, 0x687b, 0x0006,
-+	0x0048, 0xd0bc, 0x0118, 0x687b, 0x0002, 0x0020, 0x687b, 0x0005,
-+	0x080c, 0xac07, 0x6877, 0x0000, 0x080c, 0x5b76, 0x080c, 0xab11,
-+	0x00de, 0x080c, 0x8ed9, 0x0005, 0x0016, 0x00d6, 0x6014, 0x2068,
-+	0x080c, 0xa942, 0x0140, 0x6867, 0x0103, 0x687b, 0x0028, 0x6877,
-+	0x0000, 0x080c, 0x5b76, 0x00de, 0x001e, 0x9186, 0x0013, 0x0148,
-+	0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0x8f6e,
-+	0x0030, 0x080c, 0x79ab, 0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005,
-+	0x0056, 0x0066, 0x00d6, 0x00f6, 0x2029, 0x0001, 0x9182, 0x0101,
-+	0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018,
-+	0x2009, 0x0020, 0x9f90, 0x0029, 0x080c, 0xa5c9, 0x96b2, 0x0020,
-+	0x7804, 0x906d, 0x0110, 0x080c, 0x0edf, 0x080c, 0x0eb6, 0x0520,
-+	0x8528, 0x6867, 0x0110, 0x686b, 0x0000, 0x2d20, 0x7c06, 0x968a,
-+	0x003d, 0x1228, 0x2608, 0x9d90, 0x001b, 0x0499, 0x00a8, 0x96b2,
-+	0x003c, 0x2009, 0x003c, 0x2d78, 0x9d90, 0x001b, 0x0451, 0x0c28,
-+	0x2079, 0x0200, 0x7817, 0x0000, 0x00fe, 0x852f, 0x95ad, 0x0003,
-+	0x7d66, 0x95ac, 0x0000, 0x0048, 0x2079, 0x0200, 0x7817, 0x0000,
-+	0x00fe, 0x852f, 0x95ad, 0x0003, 0x7d66, 0x00de, 0x006e, 0x005e,
-+	0x0005, 0x00f6, 0x8dff, 0x0158, 0x6804, 0x907d, 0x0130, 0x6807,
-+	0x0000, 0x080c, 0x5b76, 0x2f68, 0x0cb8, 0x080c, 0x5b76, 0x00fe,
-+	0x0005, 0x00f6, 0x0156, 0x2079, 0x0200, 0x9184, 0x0001, 0x0108,
-+	0x8108, 0x810c, 0x21a8, 0x2300, 0x9e00, 0x2004, 0x8007, 0x2012,
-+	0x8318, 0x9386, 0x0020, 0x1120, 0x2018, 0x7814, 0x8000, 0x7816,
-+	0x8210, 0x1f04, 0xa5d3, 0x015e, 0x00fe, 0x0005, 0x0066, 0x0126,
-+	0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083,
-+	0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031,
-+	0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005,
-+	0xa621, 0xa621, 0xa61c, 0xa643, 0xa60f, 0xa61c, 0xa643, 0xa61c,
-+	0xa60f, 0xa60f, 0xa61c, 0xa61c, 0xa61c, 0xa60f, 0xa60f, 0x080c,
-+	0x0d7e, 0x0036, 0x2019, 0x0010, 0x080c, 0xbd23, 0x6023, 0x0006,
-+	0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001,
-+	0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6014, 0x2068, 0x080c, 0xa942,
-+	0x01c0, 0x6864, 0x9086, 0x0139, 0x1128, 0x687b, 0x0005, 0x6883,
-+	0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x5d95, 0x080c,
-+	0xac07, 0x080c, 0x5b76, 0x080c, 0x8f09, 0x9085, 0x0001, 0x00de,
-+	0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7e,
-+	0x000b, 0x0005, 0xa65a, 0xa67b, 0xa65c, 0xa69a, 0xa678, 0xa65a,
-+	0xa61c, 0xa621, 0xa621, 0xa61c, 0xa61c, 0xa61c, 0xa61c, 0xa61c,
-+	0xa61c, 0xa61c, 0x080c, 0x0d7e, 0x86ff, 0x11b8, 0x6020, 0x9086,
-+	0x0006, 0x0198, 0x00d6, 0x6014, 0x2068, 0x080c, 0xa942, 0x0110,
-+	0x080c, 0xac07, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-+	0x0002, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x9085, 0x0001, 0x0005,
-+	0x080c, 0x1509, 0x0c08, 0x00e6, 0x2071, 0x1304, 0x7024, 0x9c06,
-+	0x1110, 0x080c, 0x87a2, 0x6020, 0x9084, 0x000f, 0x9086, 0x0006,
-+	0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x8968,
-+	0x009e, 0x008e, 0x0010, 0x080c, 0x86b8, 0x00ee, 0x1928, 0x080c,
-+	0xa61c, 0x0005, 0x0036, 0x00e6, 0x2071, 0x1304, 0x703c, 0x9c06,
-+	0x1138, 0x901e, 0x080c, 0x8847, 0x00ee, 0x003e, 0x0804, 0xa65c,
-+	0x080c, 0x8a8d, 0x00ee, 0x003e, 0x1904, 0xa65c, 0x080c, 0xa61c,
-+	0x0005, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005,
-+	0xa6ce, 0xa759, 0xa8a3, 0xa6d9, 0x8f09, 0xa6ce, 0xbd15, 0x8ed9,
-+	0xa759, 0xa6c7, 0xa90e, 0xa6c7, 0xa6c7, 0xa6c7, 0xa6c7, 0x080c,
-+	0x0d7e, 0x080c, 0xab2e, 0x1110, 0x080c, 0x97dc, 0x0005, 0x080c,
-+	0x79ab, 0x080c, 0x7aa4, 0x080c, 0x8ed9, 0x0005, 0x601b, 0x0001,
-+	0x0005, 0x080c, 0xa942, 0x0120, 0x6014, 0x9080, 0x0025, 0x2c02,
-+	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7e, 0x000b, 0x0005, 0xa6f7,
-+	0xa6f9, 0xa719, 0xa72b, 0xa738, 0xa6f7, 0xa6ce, 0xa6ce, 0xa6ce,
-+	0xa72b, 0xa72b, 0xa6f7, 0xa6f7, 0xa6f7, 0xa6f7, 0xa735, 0x080c,
-+	0x0d7e, 0x00e6, 0x6014, 0x2070, 0x7080, 0xc0b5, 0x7082, 0x2071,
-+	0x1304, 0x7024, 0x9c06, 0x0190, 0x080c, 0x86b8, 0x6007, 0x0085,
-+	0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x12c1, 0x2004, 0x601a,
-+	0x080c, 0x756e, 0x080c, 0x7aa4, 0x00ee, 0x0005, 0x601b, 0x0001,
-+	0x0cd8, 0x00d6, 0x6014, 0x2068, 0x6880, 0xc0b5, 0x6882, 0x00de,
-+	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x756e,
-+	0x080c, 0x7aa4, 0x0005, 0x00d6, 0x601b, 0x0001, 0x6014, 0x2068,
-+	0x6880, 0xc0b5, 0x6882, 0x00de, 0x0005, 0x080c, 0x8ed9, 0x0005,
-+	0x6014, 0x9005, 0x01d8, 0x9088, 0x001f, 0x210c, 0xd1e4, 0x01b0,
-+	0x9080, 0x0021, 0x2004, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a,
-+	0x2001, 0x0037, 0x2c08, 0x080c, 0x130c, 0x6000, 0x9086, 0x0004,
-+	0x1120, 0x2009, 0x0048, 0x080c, 0x8f53, 0x0005, 0x080c, 0x1509,
-+	0x0800, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7e, 0x000b, 0x0005,
-+	0xa770, 0xa6d6, 0xa772, 0xa770, 0xa772, 0xa772, 0xa6cf, 0xa770,
-+	0xa6c9, 0xa6c9, 0xa770, 0xa770, 0xa770, 0xa770, 0xa770, 0xa770,
-+	0x080c, 0x0d7e, 0x6010, 0x00d6, 0x2068, 0x6804, 0x9084, 0x00ff,
-+	0x00de, 0x908a, 0x000c, 0x1a0c, 0x0d7e, 0x000b, 0x0005, 0xa78b,
-+	0xa849, 0xa78d, 0xa7cb, 0xa78d, 0xa7cb, 0xa78d, 0xa79b, 0xa78b,
-+	0xa7cb, 0xa78b, 0xa7b7, 0x080c, 0x0d7e, 0x6004, 0x908e, 0x0016,
-+	0x05a8, 0x908e, 0x0004, 0x0590, 0x908e, 0x0002, 0x0578, 0x908e,
-+	0x0052, 0x0904, 0xa845, 0x6004, 0x080c, 0xab2e, 0x0904, 0xa862,
-+	0x908e, 0x0021, 0x0904, 0xa866, 0x908e, 0x0022, 0x0904, 0xa862,
-+	0x908e, 0x003d, 0x0904, 0xa866, 0x908e, 0x0039, 0x0904, 0xa86a,
-+	0x908e, 0x0035, 0x0904, 0xa86a, 0x908e, 0x001e, 0x0188, 0x908e,
-+	0x0001, 0x1150, 0x6010, 0x00d6, 0x2068, 0x6804, 0x9084, 0x00ff,
-+	0x00de, 0x9086, 0x0006, 0x0110, 0x080c, 0x2862, 0x080c, 0x97dc,
-+	0x080c, 0x8f09, 0x0005, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
-+	0x0904, 0xa836, 0x9186, 0x0002, 0x15b8, 0x2001, 0x1136, 0x2004,
-+	0xd08c, 0x1178, 0x080c, 0x62e4, 0x1160, 0x2001, 0x12a8, 0x2003,
-+	0x0001, 0x2001, 0x1100, 0x2003, 0x0001, 0x080c, 0x621a, 0x0804,
-+	0xa88c, 0x6010, 0x2068, 0x2001, 0x1136, 0x2004, 0xd0ac, 0x1904,
-+	0xa88c, 0x68a0, 0xd0bc, 0x1904, 0xa88c, 0x6840, 0x9084, 0x00ff,
-+	0x9005, 0x0190, 0x8001, 0x6842, 0x6017, 0x0000, 0x6023, 0x0007,
-+	0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0x8e83, 0x0128, 0x2d00,
-+	0x6012, 0x6023, 0x0001, 0x0450, 0x00de, 0x00ce, 0x6004, 0x908e,
-+	0x0002, 0x11a8, 0x6010, 0x9080, 0x0028, 0x2004, 0x9086, 0x007e,
-+	0x1170, 0x2009, 0x1136, 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071,
-+	0x1100, 0x080c, 0x5092, 0x00ee, 0x080c, 0x97dc, 0x0020, 0x080c,
-+	0x97dc, 0x080c, 0x2862, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c,
-+	0x2886, 0x012e, 0x00ee, 0x080c, 0x8f09, 0x0005, 0x2001, 0x0002,
-+	0x080c, 0x5568, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x75be,
-+	0x080c, 0x7aa4, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x2886, 0x0804,
-+	0xa7c6, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010,
-+	0x2068, 0x6840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xa80c, 0x8001,
-+	0x6842, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x00de,
-+	0x00ce, 0x0898, 0x080c, 0x97dc, 0x0804, 0xa7c8, 0x080c, 0x9809,
-+	0x0804, 0xa7c8, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xaf4e, 0x00de,
-+	0x0118, 0x080c, 0x8ed9, 0x00b8, 0x6004, 0x8007, 0x6134, 0x918c,
-+	0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-+	0x0002, 0x603c, 0x600a, 0x2001, 0x12c1, 0x2004, 0x601a, 0x080c,
-+	0x756e, 0x080c, 0x7aa4, 0x0005, 0x00de, 0x00ce, 0x080c, 0x97dc,
-+	0x080c, 0x2862, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2886,
-+	0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000,
-+	0x012e, 0x00ee, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7e,
-+	0x00d6, 0x0013, 0x00de, 0x0005, 0xa8bc, 0xa8bc, 0xa8bc, 0xa8bc,
-+	0xa8bc, 0xa8bc, 0xa8bc, 0xa8bc, 0xa8bc, 0xa6ce, 0xa8bc, 0xa6d6,
-+	0xa8be, 0xa6d6, 0xa8cb, 0xa8bc, 0x080c, 0x0d7e, 0x6004, 0x9086,
-+	0x008b, 0x0148, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x756e,
-+	0x080c, 0x7aa4, 0x0005, 0x080c, 0xab11, 0x080c, 0xa942, 0x0570,
-+	0x080c, 0x2862, 0x080c, 0xa942, 0x0168, 0x6014, 0x2068, 0x6867,
-+	0x0103, 0x687b, 0x0006, 0x6877, 0x0000, 0x6880, 0xc0ed, 0x6882,
-+	0x080c, 0x5b76, 0x2c68, 0x080c, 0x8e83, 0x0150, 0x6810, 0x6012,
-+	0x080c, 0xad70, 0x00c6, 0x2d60, 0x080c, 0x8f09, 0x00ce, 0x0008,
-+	0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
-+	0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0078, 0x6034, 0x908c,
-+	0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118,
-+	0x080c, 0x2862, 0x08b8, 0x080c, 0x8f09, 0x0005, 0x6000, 0x908a,
-+	0x0016, 0x1a0c, 0x0d7e, 0x000b, 0x0005, 0xa925, 0xa925, 0xa927,
-+	0xa927, 0xa927, 0xa925, 0xa925, 0xa925, 0xa925, 0xa925, 0xa925,
-+	0xa925, 0xa925, 0xa925, 0xa925, 0xa925, 0x080c, 0x0d7e, 0x080c,
-+	0x8a8d, 0x6114, 0x2168, 0x687b, 0x0006, 0x080c, 0x5b76, 0x080c,
-+	0x8ed9, 0x0005, 0x9284, 0x0007, 0x1158, 0x9282, 0x15c0, 0x0240,
-+	0x2001, 0x1118, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005,
-+	0x9006, 0x0ce8, 0x0026, 0x6214, 0x9294, 0xf000, 0x002e, 0x0005,
-+	0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061,
-+	0x15c0, 0x2071, 0x1100, 0x734c, 0x706c, 0x9302, 0x12a8, 0x6020,
-+	0x9206, 0x1160, 0x080c, 0xacea, 0x0148, 0x080c, 0xab2e, 0x1110,
-+	0x080c, 0x97dc, 0x00c6, 0x080c, 0x8ed9, 0x00ce, 0x9ce0, 0x0018,
-+	0x7060, 0x9c02, 0x1208, 0x0c38, 0x012e, 0x000e, 0x003e, 0x00ce,
-+	0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c,
-+	0x81ff, 0x0128, 0x2061, 0x1389, 0x6112, 0x080c, 0x2862, 0x9006,
-+	0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6,
-+	0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83, 0x005e,
-+	0x0180, 0x6616, 0x6512, 0x080c, 0xad70, 0x6023, 0x0003, 0x2009,
-+	0x004b, 0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x005e, 0x00ce,
-+	0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000,
-+	0x62a0, 0x00c6, 0x080c, 0x8f26, 0x005e, 0x0538, 0x6017, 0x0000,
-+	0x6512, 0x080c, 0xad70, 0x6023, 0x0003, 0x0016, 0x00c6, 0x2560,
-+	0x00ce, 0x080c, 0x76f0, 0x0076, 0x903e, 0x080c, 0x75ee, 0x2c08,
-+	0x080c, 0xbec2, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x8ed9,
-+	0x9085, 0x0001, 0x0030, 0x2009, 0x004c, 0x080c, 0x8f53, 0x9085,
-+	0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00f6,
-+	0x00c6, 0x0046, 0x00c6, 0x080c, 0x8e83, 0x2c78, 0x00ce, 0x0180,
-+	0x7e16, 0x2c00, 0x7812, 0x7823, 0x0003, 0x2021, 0x0005, 0x080c,
-+	0xaa35, 0x2f60, 0x2009, 0x004d, 0x080c, 0x8f53, 0x9085, 0x0001,
-+	0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6,
-+	0x080c, 0x8e83, 0x2c78, 0x00ce, 0x0178, 0x7e16, 0x2c00, 0x7812,
-+	0x7823, 0x0003, 0x2021, 0x0005, 0x0481, 0x2f60, 0x2009, 0x004e,
-+	0x080c, 0x8f53, 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005,
-+	0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c, 0x8e83, 0x2c78, 0x00ce,
-+	0x01c0, 0x7e16, 0x2c00, 0x7812, 0x7823, 0x0003, 0x2021, 0x0004,
-+	0x00a1, 0x2001, 0x12a9, 0x2004, 0xd0fc, 0x0120, 0x2f60, 0x080c,
-+	0x8ed9, 0x0028, 0x2f60, 0x2009, 0x0052, 0x080c, 0x8f53, 0x9085,
-+	0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x572a, 0x0158, 0x2001, 0xaa3a, 0x0006,
-+	0x900e, 0x2400, 0x080c, 0x5d95, 0x080c, 0x5b76, 0x000e, 0x0807,
-+	0x2418, 0x080c, 0x7947, 0x62a0, 0x0086, 0x2041, 0x0001, 0x2039,
-+	0x0001, 0x2608, 0x080c, 0x7708, 0x008e, 0x080c, 0x75ee, 0x2f08,
-+	0x2648, 0x080c, 0xbec2, 0x613c, 0x81ff, 0x090c, 0x77c0, 0x080c,
-+	0x7aa4, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091,
-+	0x8000, 0x00c6, 0x080c, 0x8e83, 0x001e, 0x0188, 0x660a, 0x6112,
-+	0x080c, 0xad70, 0x6023, 0x0001, 0x2d00, 0x6016, 0x2009, 0x001f,
-+	0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-+	0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83,
-+	0x001e, 0x01b0, 0x660a, 0x6112, 0x080c, 0xad70, 0x6023, 0x0008,
-+	0x2d00, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x137e, 0x00fe, 0x2009,
-+	0x0021, 0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-+	0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
-+	0x8e83, 0x001e, 0x0188, 0x660a, 0x6112, 0x080c, 0xad70, 0x6023,
-+	0x0001, 0x2d00, 0x6016, 0x2009, 0x003d, 0x080c, 0x8f53, 0x9085,
-+	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126,
-+	0x2091, 0x8000, 0x00c6, 0x080c, 0x8f26, 0x001e, 0x0180, 0x6112,
-+	0x080c, 0xad70, 0x6023, 0x0001, 0x2d00, 0x6016, 0x2009, 0x0000,
-+	0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-+	0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83,
-+	0x001e, 0x0188, 0x660a, 0x6112, 0x080c, 0xad70, 0x6023, 0x0001,
-+	0x2d00, 0x6016, 0x2009, 0x0044, 0x080c, 0x8f53, 0x9085, 0x0001,
-+	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
-+	0x8000, 0x00c6, 0x080c, 0x8e83, 0x001e, 0x0188, 0x660a, 0x6112,
-+	0x080c, 0xad70, 0x6023, 0x0001, 0x2d00, 0x6016, 0x2009, 0x0049,
-+	0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
-+	0x0cd8, 0x0026, 0x00d6, 0x6210, 0x2268, 0x6a3c, 0x82ff, 0x0110,
-+	0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004,
-+	0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004,
-+	0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x00d6,
-+	0x6014, 0x906d, 0x0148, 0x6864, 0x9086, 0x0139, 0x0138, 0x6868,
-+	0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00de, 0x000e,
-+	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83,
-+	0x001e, 0x0190, 0x6112, 0x080c, 0xad70, 0x6023, 0x0001, 0x2d00,
-+	0x6016, 0x080c, 0x2862, 0x2009, 0x0028, 0x080c, 0x8f53, 0x9085,
-+	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015,
-+	0x1188, 0x2011, 0x1122, 0x2204, 0x9086, 0x0074, 0x1158, 0x080c,
-+	0x9bfa, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x0070, 0x6014, 0x9080, 0x001a, 0x2004, 0xd0fc, 0x0148,
-+	0x2001, 0x0001, 0x080c, 0xaf0f, 0x080c, 0x97dc, 0x080c, 0x8ed9,
-+	0x0005, 0x00d6, 0x6014, 0x906d, 0x090c, 0x0d7e, 0x687b, 0x0030,
-+	0x6883, 0x0000, 0x6897, 0x4005, 0x689b, 0x0004, 0x6867, 0x0139,
-+	0x0126, 0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x00de, 0x080c,
-+	0x8ed9, 0x0c30, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c,
-+	0x5568, 0x00e8, 0x9186, 0x0015, 0x1518, 0x2011, 0x1122, 0x2204,
-+	0x9086, 0x0014, 0x11e8, 0x6010, 0x00d6, 0x2068, 0x080c, 0x56a8,
-+	0x00de, 0x080c, 0x9cc9, 0x11a0, 0x6010, 0x00d6, 0x2068, 0x6890,
-+	0x00de, 0x9005, 0x0168, 0x2001, 0x0006, 0x080c, 0x5568, 0x6014,
-+	0x9080, 0x001a, 0x2004, 0xd0fc, 0x0170, 0x080c, 0x9275, 0x0050,
-+	0x6014, 0x9080, 0x001a, 0x2004, 0xd0fc, 0x01d0, 0x080c, 0x97dc,
-+	0x080c, 0x8ed9, 0x0005, 0x6014, 0x00d6, 0x906d, 0x090c, 0x0d7e,
-+	0x687b, 0x0000, 0x6883, 0x0000, 0x6897, 0x4000, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x5b76, 0x012e, 0x00de, 0x080c, 0x8ed9, 0x0c50,
-+	0x6014, 0x00d6, 0x906d, 0x090c, 0x0d7e, 0x687b, 0x0030, 0x6883,
-+	0x0000, 0x6897, 0x4005, 0x689b, 0x0004, 0x6867, 0x0139, 0x0126,
-+	0x2091, 0x8000, 0x080c, 0x5b76, 0x012e, 0x00de, 0x080c, 0x8ed9,
-+	0x0888, 0x6878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6880,
-+	0xc0ad, 0x6882, 0x0005, 0x6043, 0x0000, 0x6017, 0x0000, 0x6003,
-+	0x0001, 0x6007, 0x0050, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x0005,
-+	0x00c6, 0x6010, 0x2004, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f,
-+	0x0013, 0x00ce, 0x0005, 0xa6ce, 0xac34, 0xac34, 0xac37, 0xc172,
-+	0xc18d, 0xc190, 0xa6ce, 0xa6ce, 0xa6ce, 0xa6ce, 0xa6ce, 0xa6ce,
-+	0xa6ce, 0xa6ce, 0x080c, 0x0d7e, 0xa001, 0xa001, 0x0005, 0x0009,
-+	0x0005, 0x6010, 0x2004, 0xd0bc, 0x0550, 0x00f6, 0x2c78, 0x080c,
-+	0x8e83, 0x1128, 0x2001, 0x12c2, 0x2004, 0x7842, 0x00f8, 0x7810,
-+	0x6012, 0x080c, 0xad70, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808,
-+	0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a,
-+	0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7954,
-+	0x6156, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x2f60, 0x00fe, 0x0005,
-+	0x0016, 0x00f6, 0x6814, 0x2078, 0x787c, 0xd0e4, 0x0180, 0xc0e4,
-+	0x787e, 0x7877, 0x0000, 0x7893, 0x0000, 0x788f, 0x0000, 0xd0cc,
-+	0x0130, 0x7878, 0x00d6, 0x2068, 0x080c, 0x0edf, 0x00de, 0x6830,
-+	0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005,
-+	0x0168, 0x9006, 0x602e, 0x6032, 0x00c8, 0x681c, 0xc085, 0x681e,
-+	0x6803, 0x0004, 0x6824, 0xc0f4, 0xc0d5, 0x6826, 0x6814, 0x2078,
-+	0x78ac, 0x6938, 0x9102, 0x78b0, 0x693c, 0x9103, 0x1e50, 0x683c,
-+	0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a,
-+	0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156, 0x6023, 0x0001,
-+	0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4,
-+	0x00fe, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8,
-+	0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024,
-+	0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0x6c3e, 0x6b42, 0x0046,
-+	0x0036, 0x2400, 0x6cac, 0x9402, 0x6836, 0x2300, 0x6bb0, 0x9303,
-+	0x683a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005,
-+	0xd0f4, 0x1138, 0x683c, 0x603a, 0x6840, 0x603e, 0x6024, 0xc0f5,
-+	0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8,
-+	0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037,
-+	0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e,
-+	0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e,
-+	0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001,
-+	0x12bc, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x73f0,
-+	0x2001, 0x12c0, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001,
-+	0x12be, 0x200c, 0x8000, 0x2014, 0x2071, 0x1297, 0x711a, 0x721e,
-+	0x2001, 0x0064, 0x080c, 0x73f0, 0x2001, 0x12c1, 0x82ff, 0x1110,
-+	0x2011, 0x0014, 0x2202, 0x2001, 0x12c2, 0x9288, 0x000a, 0x2102,
-+	0x2001, 0x136b, 0x2102, 0x2001, 0x0032, 0x080c, 0x130c, 0x080c,
-+	0x58af, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
-+	0x0016, 0x00e6, 0x2001, 0x12c0, 0x2003, 0x0028, 0x2001, 0x12c1,
-+	0x2003, 0x0014, 0x2071, 0x1297, 0x701b, 0x0000, 0x701f, 0x07d0,
-+	0x2001, 0x12c2, 0x2009, 0x001e, 0x2102, 0x2001, 0x136b, 0x2102,
-+	0x2001, 0x0032, 0x080c, 0x130c, 0x00ee, 0x001e, 0x000e, 0x0005,
-+	0x00d6, 0x6058, 0x906d, 0x0110, 0x080c, 0x0ecf, 0x00de, 0x0005,
-+	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83,
-+	0x001e, 0x0178, 0x6112, 0x0ca1, 0x6023, 0x0001, 0x2d00, 0x6016,
-+	0x2009, 0x0033, 0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce,
-+	0x0005, 0x9006, 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0x1100,
-+	0x9186, 0x0015, 0x11f8, 0x7088, 0x9086, 0x0018, 0x11d8, 0x6014,
-+	0x2068, 0x6a3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x7c86, 0x01d0,
-+	0x7074, 0x6a50, 0x9206, 0x1158, 0x7078, 0x6a54, 0x9206, 0x1138,
-+	0x6210, 0x9290, 0x0028, 0x2214, 0x900e, 0x080c, 0x28a5, 0x080c,
-+	0x9275, 0x0020, 0x080c, 0x97dc, 0x080c, 0x8ed9, 0x00fe, 0x00ee,
-+	0x00de, 0x0005, 0x7058, 0x6a54, 0x9206, 0x0d50, 0x0c80, 0x00c6,
-+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8e83, 0x001e, 0x0180,
-+	0x6112, 0x080c, 0xad70, 0x6023, 0x0001, 0x2d00, 0x6016, 0x2009,
-+	0x004d, 0x080c, 0x8f53, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-+	0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x00c6,
-+	0x080c, 0x8e83, 0x001e, 0x0178, 0x6112, 0x080c, 0xad70, 0x6023,
-+	0x0001, 0x2d00, 0x6016, 0x001e, 0x080c, 0x8f53, 0x9085, 0x0001,
-+	0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026,
-+	0x0036, 0x0046, 0x0056, 0x0066, 0x00d6, 0x00e6, 0x00f6, 0x2071,
-+	0x1100, 0x9186, 0x0015, 0x1538, 0x7188, 0x6014, 0x2068, 0x6814,
-+	0x8003, 0x9106, 0x1500, 0x20e1, 0x0000, 0x2001, 0x12da, 0x2003,
-+	0x0000, 0x6014, 0x20e9, 0x0001, 0x2068, 0x6830, 0x20a8, 0x9d80,
-+	0x001b, 0x20a0, 0x2001, 0x12da, 0x0016, 0x200c, 0x080c, 0xb4ed,
-+	0x001e, 0x6804, 0x9005, 0x0110, 0x2068, 0x0c78, 0x6014, 0x2070,
-+	0x7067, 0x0103, 0x0010, 0x080c, 0x97dc, 0x080c, 0x8ed9, 0x00fe,
-+	0x00ee, 0x00de, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
-+	0x0005, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0x1100, 0x9186, 0x0015,
-+	0x11c0, 0x7088, 0x9086, 0x0004, 0x11a0, 0x6014, 0x90e8, 0x001b,
-+	0x2c78, 0x080c, 0x7c86, 0x01a8, 0x7074, 0x6a08, 0x9206, 0x1130,
-+	0x7078, 0x6a0c, 0x9206, 0x1110, 0x080c, 0x2862, 0x080c, 0x9275,
-+	0x0020, 0x080c, 0x97dc, 0x080c, 0x8ed9, 0x00fe, 0x00ee, 0x00de,
-+	0x0005, 0x7058, 0x6a0c, 0x9206, 0x0d78, 0x0c80, 0x00d6, 0x00e6,
-+	0x00f6, 0x2071, 0x1100, 0x9186, 0x0015, 0x11f0, 0x7088, 0x9086,
-+	0x0004, 0x11d0, 0x6014, 0x90e8, 0x0031, 0x2c78, 0x080c, 0x7c86,
-+	0x0558, 0x7074, 0x6a08, 0x9206, 0x1130, 0x7078, 0x6a0c, 0x9206,
-+	0x1110, 0x080c, 0x2862, 0x6014, 0x2068, 0x687b, 0x0000, 0x6883,
-+	0x0000, 0x6897, 0x4000, 0x0050, 0x6014, 0x2068, 0x687b, 0x0030,
-+	0x6883, 0x0000, 0x6897, 0x4005, 0x689b, 0x0004, 0x0126, 0x2091,
-+	0x8000, 0x6867, 0x0139, 0x080c, 0x5b76, 0x012e, 0x080c, 0x8ed9,
-+	0x00fe, 0x00ee, 0x00de, 0x0005, 0x7058, 0x6a0c, 0x9206, 0x09c8,
-+	0x08d0, 0x0016, 0x0026, 0x687c, 0xd0ac, 0x0178, 0x6938, 0x6a34,
-+	0x2100, 0x9205, 0x0150, 0x6890, 0x9106, 0x1118, 0x688c, 0x9206,
-+	0x0120, 0x6992, 0x6a8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005,
-+	0x00d6, 0x0036, 0x6314, 0x2368, 0x687a, 0x6982, 0x929e, 0x4000,
-+	0x1558, 0x6310, 0x00c6, 0x2360, 0x900e, 0x6868, 0xd0f4, 0x1140,
-+	0x080c, 0x57d6, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d,
-+	0x6a96, 0x699a, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x20e9, 0x0001,
-+	0x9d80, 0x0031, 0x20a0, 0x9c80, 0x0006, 0x2098, 0x080c, 0x504f,
-+	0x20a9, 0x0004, 0x9d80, 0x0035, 0x20a0, 0x9c80, 0x000a, 0x2098,
-+	0x080c, 0x504f, 0x00ce, 0x00a0, 0x6a96, 0x3918, 0x9398, 0x0006,
-+	0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0x689b, 0x0004, 0x6ba2,
-+	0x6310, 0x00c6, 0x2360, 0x6004, 0x00ce, 0x9084, 0x00ff, 0x689e,
-+	0x080c, 0x5b76, 0x6017, 0x0000, 0x003e, 0x00de, 0x0005, 0x0026,
-+	0x0036, 0x0046, 0x00e6, 0x00d6, 0x00f6, 0x6214, 0x2268, 0x6210,
-+	0x2270, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0x7014, 0x9084,
-+	0x00ff, 0x900e, 0x080c, 0x1f63, 0x2118, 0x831f, 0x939c, 0xff00,
-+	0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c,
-+	0x3f23, 0x00a8, 0x9096, 0x0001, 0x1148, 0x8dff, 0x0180, 0x689b,
-+	0x000d, 0x7838, 0x68a6, 0x783c, 0x68aa, 0x0048, 0x9096, 0x0002,
-+	0x1130, 0x689b, 0x000d, 0x7838, 0x68a6, 0x783c, 0x68aa, 0x00fe,
-+	0x00de, 0x00ee, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026,
-+	0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c,
-+	0xa932, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186,
-+	0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160,
-+	0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106,
-+	0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005,
-+	0x9085, 0x0001, 0x0cc8, 0x6974, 0xd1cc, 0x0188, 0x918c, 0x00ff,
-+	0x918e, 0x0002, 0x1160, 0x69a8, 0x918c, 0x0f00, 0x810f, 0x918e,
-+	0x0001, 0x1128, 0x6834, 0x6938, 0x9115, 0x190c, 0xa12c, 0x0005,
-+	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d7e, 0x0013, 0x006e,
-+	0x0005, 0xafa9, 0xb5ee, 0xb74e, 0xafa9, 0xafa9, 0xafa9, 0xafa9,
-+	0xafa9, 0xafe0, 0xb7d1, 0xafa9, 0xafa9, 0xafa9, 0xafa9, 0xafa9,
-+	0xafa9, 0x080c, 0x0d7e, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-+	0x0d7e, 0x0013, 0x006e, 0x0005, 0xafc4, 0xbcae, 0xafc4, 0xafc4,
-+	0xafc4, 0xafc4, 0xafc4, 0xafc4, 0xbc5d, 0xbd02, 0xafc4, 0xc2b5,
-+	0xc2eb, 0xc2b5, 0xc2eb, 0xafc4, 0x080c, 0x0d7e, 0x6000, 0x9082,
-+	0x0016, 0x1a0c, 0x0d7e, 0x6000, 0x000a, 0x0005, 0xafde, 0xb91e,
-+	0xba17, 0xba39, 0xbaf9, 0xafde, 0xbbd0, 0xbb7b, 0xb7dd, 0xbc33,
-+	0xbc48, 0xafde, 0xafde, 0xafde, 0xafde, 0xafde, 0x080c, 0x0d7e,
-+	0x91b2, 0x0053, 0x1a0c, 0x0d7e, 0x2100, 0x91b2, 0x0040, 0x1a04,
-+	0xb414, 0x0002, 0xb02a, 0xb214, 0xb02a, 0xb02a, 0xb02a, 0xb21d,
-+	0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a,
-+	0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a,
-+	0xb02a, 0xb02c, 0xb087, 0xb096, 0xb0f8, 0xb122, 0xb1a0, 0xb1ff,
-+	0xb02a, 0xb02a, 0xb220, 0xb02a, 0xb02a, 0xb235, 0xb242, 0xb02a,
-+	0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb2c9, 0xb02a, 0xb02a, 0xb2d8,
-+	0xb02a, 0xb02a, 0xb294, 0xb02a, 0xb02a, 0xb02a, 0xb2f0, 0xb02a,
-+	0xb02a, 0xb02a, 0xb368, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xb02a,
-+	0xb02a, 0xb3dd, 0x080c, 0x0d7e, 0x080c, 0x588e, 0x1150, 0x2001,
-+	0x1136, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008,
-+	0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804,
-+	0xb20d, 0x080c, 0x587e, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
-+	0x6210, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x76f0,
-+	0x0076, 0x903e, 0x080c, 0x75ee, 0x2c08, 0x080c, 0xbec2, 0x007e,
-+	0x001e, 0x2e60, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610,
-+	0x00c6, 0x2660, 0x080c, 0x5617, 0x00ce, 0x96b0, 0x0001, 0x2634,
-+	0x9684, 0x00ff, 0x9082, 0x0006, 0x0278, 0x080c, 0xbe06, 0x1904,
-+	0xb0f2, 0x080c, 0xbda3, 0x1120, 0x6007, 0x0008, 0x0804, 0xb20d,
-+	0x6007, 0x0009, 0x0804, 0xb20d, 0x080c, 0xbfdb, 0x0128, 0x080c,
-+	0xbe06, 0x0d78, 0x0804, 0xb0f2, 0x6017, 0x1900, 0x0c88, 0x080c,
-+	0x297d, 0x1904, 0xb411, 0x6106, 0x080c, 0xbd61, 0x6007, 0x0006,
-+	0x0804, 0xb20d, 0x6007, 0x0007, 0x0804, 0xb20d, 0x080c, 0xc327,
-+	0x1904, 0xb411, 0x080c, 0x297d, 0x1904, 0xb411, 0x00d6, 0x6610,
-+	0x2668, 0x6e04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001,
-+	0x0001, 0x080c, 0x5556, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006,
-+	0x0188, 0x9686, 0x0004, 0x0170, 0x6e04, 0x96b4, 0x00ff, 0x9686,
-+	0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110,
-+	0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003,
-+	0x1138, 0x90b2, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130,
-+	0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b8, 0x00ee, 0x080c,
-+	0xbe64, 0x1198, 0x9686, 0x0006, 0x1148, 0x0026, 0x6210, 0x9290,
-+	0x0028, 0x2214, 0x900e, 0x080c, 0x28a5, 0x002e, 0x080c, 0x56a8,
-+	0x6007, 0x000a, 0x00de, 0x0804, 0xb20d, 0x6007, 0x000b, 0x00de,
-+	0x0804, 0xb20d, 0x080c, 0x2862, 0x6007, 0x0001, 0x0804, 0xb20d,
-+	0x080c, 0xc327, 0x1904, 0xb411, 0x080c, 0x297d, 0x1904, 0xb411,
-+	0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1950, 0x90b2, 0x0014,
-+	0x0a38, 0x7030, 0x9084, 0x0003, 0x1918, 0x6610, 0x00d6, 0x2668,
-+	0x6e04, 0x00de, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x9290,
-+	0x0028, 0x2214, 0x900e, 0x080c, 0x28a5, 0x002e, 0x6007, 0x000c,
-+	0x0804, 0xb20d, 0x080c, 0x588e, 0x1140, 0x2001, 0x1136, 0x2004,
-+	0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xb039, 0x080c,
-+	0x587e, 0x6610, 0x96b0, 0x0001, 0x2634, 0x9684, 0x00ff, 0x9082,
-+	0x0006, 0x06e8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x5592,
-+	0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
-+	0x9686, 0x0006, 0x1904, 0xb0f2, 0x080c, 0xbe71, 0x1120, 0x6007,
-+	0x000e, 0x0804, 0xb20d, 0x0046, 0x6410, 0x94a0, 0x0028, 0x2424,
-+	0x94a4, 0x00ff, 0x8427, 0x0046, 0x080c, 0x2862, 0x004e, 0x0016,
-+	0x9006, 0x2009, 0x1153, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029,
-+	0x080c, 0xc12f, 0x6010, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802,
-+	0x00de, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xb20d, 0x2001,
-+	0x0001, 0x080c, 0x5556, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
-+	0x0004, 0x2019, 0x1105, 0x2011, 0x0270, 0x080c, 0x9d60, 0x003e,
-+	0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
-+	0x9682, 0x0004, 0x0a04, 0xb0f2, 0x9682, 0x0007, 0x0a04, 0xb14c,
-+	0x0804, 0xb0f2, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xb20d,
-+	0x080c, 0x588e, 0x1140, 0x2001, 0x1136, 0x2004, 0x9084, 0x0009,
-+	0x9086, 0x0008, 0x1110, 0x0804, 0xb039, 0x080c, 0x587e, 0x6610,
-+	0x96b0, 0x0001, 0x2634, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06b8,
-+	0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006,
-+	0x1904, 0xb0f2, 0x080c, 0xbe99, 0x1138, 0x080c, 0xbda3, 0x1120,
-+	0x6007, 0x0010, 0x0804, 0xb20d, 0x0046, 0x6410, 0x94a0, 0x0028,
-+	0x2424, 0x94a4, 0x00ff, 0x8427, 0x0046, 0x080c, 0x2862, 0x004e,
-+	0x0016, 0x9006, 0x2009, 0x1153, 0x210c, 0xd1a4, 0x0158, 0x2009,
-+	0x0029, 0x080c, 0xc12f, 0x6010, 0x00d6, 0x2068, 0x6800, 0xc0e5,
-+	0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001, 0x00f0, 0x080c,
-+	0xbfdb, 0x0140, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0950,
-+	0x0804, 0xb0f2, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c,
-+	0x297d, 0x1904, 0xb411, 0x080c, 0xc327, 0x1904, 0xb411, 0x080c,
-+	0xb588, 0x1904, 0xb0f2, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c,
-+	0x75be, 0x080c, 0x7aa4, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001,
-+	0x080c, 0x75be, 0x080c, 0x7aa4, 0x0cb0, 0x6007, 0x0005, 0x0c68,
-+	0x080c, 0xc327, 0x1904, 0xb411, 0x080c, 0x297d, 0x1904, 0xb411,
-+	0x080c, 0xb588, 0x1904, 0xb0f2, 0x6007, 0x0020, 0x6003, 0x0001,
-+	0x080c, 0x75be, 0x080c, 0x7aa4, 0x0005, 0x080c, 0x297d, 0x1904,
-+	0xb411, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x0005, 0x080c, 0xc327, 0x1904, 0xb411, 0x080c, 0x297d,
-+	0x1904, 0xb411, 0x080c, 0xb588, 0x1904, 0xb0f2, 0x0016, 0x0026,
-+	0x00e6, 0x2071, 0x0260, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08,
-+	0x080c, 0xa932, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188,
-+	0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240,
-+	0x2c08, 0x9006, 0x080c, 0xc101, 0x1180, 0x7244, 0x9286, 0xffff,
-+	0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296,
-+	0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007,
-+	0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0x8ed9, 0x2160,
-+	0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4,
-+	0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x5556,
-+	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1105,
-+	0x2011, 0x0276, 0x080c, 0x9d60, 0x003e, 0x002e, 0x001e, 0x015e,
-+	0x0120, 0x6007, 0x0031, 0x0804, 0xb20d, 0x080c, 0x9a13, 0x080c,
-+	0x62e4, 0x11b0, 0x0006, 0x0026, 0x0036, 0x080c, 0x6300, 0x1158,
-+	0x2001, 0x12a8, 0x2003, 0x0001, 0x2001, 0x1100, 0x2003, 0x0001,
-+	0x080c, 0x621a, 0x0010, 0x080c, 0x62be, 0x003e, 0x002e, 0x000e,
-+	0x0005, 0x080c, 0x297d, 0x1904, 0xb411, 0x6106, 0x080c, 0xb5a4,
-+	0x6007, 0x002b, 0x0804, 0xb20d, 0x6007, 0x002c, 0x0804, 0xb20d,
-+	0x080c, 0xc327, 0x1904, 0xb411, 0x080c, 0x297d, 0x1904, 0xb411,
-+	0x080c, 0xb588, 0x1904, 0xb0f2, 0x6106, 0x080c, 0xb5a8, 0x1120,
-+	0x6007, 0x002e, 0x0804, 0xb20d, 0x6007, 0x002f, 0x0804, 0xb20d,
-+	0x080c, 0x297d, 0x1904, 0xb411, 0x00e6, 0x00d6, 0x00c6, 0x6010,
-+	0x9080, 0x0001, 0x200c, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158,
-+	0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de,
-+	0x00ee, 0x0804, 0xb214, 0x2001, 0x1172, 0x2004, 0xd0e4, 0x0904,
-+	0xb365, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108,
-+	0x720c, 0x080c, 0x58cb, 0x0140, 0x6010, 0x2068, 0x6810, 0x9106,
-+	0x1118, 0x6814, 0x9206, 0x01f8, 0x080c, 0x58c6, 0x15a0, 0x2069,
-+	0x1100, 0x6878, 0x9206, 0x1578, 0x6874, 0x9106, 0x1560, 0x7210,
-+	0x080c, 0xa932, 0x0568, 0x080c, 0xc19f, 0x0550, 0x622e, 0x6007,
-+	0x0036, 0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x00ce,
-+	0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c,
-+	0xa932, 0x01b0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1180,
-+	0x08f8, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xc101, 0x2c10,
-+	0x2160, 0x0130, 0x08a8, 0x6007, 0x0037, 0x6017, 0x1500, 0x08c8,
-+	0x6007, 0x0037, 0x6017, 0x1700, 0x08a0, 0x6007, 0x0012, 0x0888,
-+	0x080c, 0x297d, 0x1904, 0xb411, 0x6010, 0x9080, 0x0001, 0x2004,
-+	0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xb214, 0x00e6,
-+	0x00d6, 0x00c6, 0x2001, 0x1172, 0x2004, 0xd0e4, 0x0904, 0xb3d5,
-+	0x2069, 0x1100, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e,
-+	0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001,
-+	0x080c, 0xc101, 0x2c10, 0x00ce, 0x0598, 0x080c, 0xa932, 0x0580,
-+	0x00c6, 0x0026, 0x2260, 0x080c, 0xa5e6, 0x002e, 0x00ce, 0x7118,
-+	0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0158, 0x9186, 0x0005,
-+	0x0118, 0x9186, 0x0007, 0x1178, 0x9280, 0x0005, 0x2004, 0x9005,
-+	0x0150, 0x0056, 0x7510, 0x7614, 0x080c, 0xc1b8, 0x005e, 0x00ce,
-+	0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017,
-+	0x2a00, 0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x0c78,
-+	0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x1700, 0x6003, 0x0001,
-+	0x080c, 0x756e, 0x080c, 0x7aa4, 0x0c10, 0x6007, 0x003b, 0x602f,
-+	0x000b, 0x6017, 0x0000, 0x0804, 0xb339, 0x00e6, 0x0026, 0x080c,
-+	0x588e, 0x0548, 0x080c, 0x587e, 0x080c, 0xc392, 0x1510, 0x2071,
-+	0x1100, 0x70d8, 0xc085, 0x70da, 0x00f6, 0x2079, 0x0100, 0x72a8,
-+	0x9284, 0x00ff, 0x7076, 0x78e6, 0x9284, 0xff00, 0x7278, 0x9205,
-+	0x707a, 0x78ea, 0x00fe, 0x70e3, 0x0000, 0x080c, 0x58cb, 0x0120,
-+	0x2011, 0x131d, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2679,
-+	0x0010, 0x080c, 0xc3be, 0x002e, 0x00ee, 0x080c, 0x8ed9, 0x0804,
-+	0xb213, 0x080c, 0x8ed9, 0x0005, 0x2600, 0x0002, 0xb428, 0xb428,
-+	0xb428, 0xb428, 0xb428, 0xb42a, 0xb428, 0xb428, 0xb428, 0xb428,
-+	0xb443, 0xb428, 0xb428, 0xb428, 0xb455, 0xb462, 0xb491, 0xb428,
-+	0x080c, 0x0d7e, 0x080c, 0xc327, 0x1d20, 0x080c, 0x297d, 0x1d08,
-+	0x080c, 0xb588, 0x1138, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c,
-+	0x75be, 0x0005, 0x080c, 0x2862, 0x6007, 0x0001, 0x6003, 0x0001,
-+	0x080c, 0x75be, 0x0005, 0x080c, 0xc327, 0x1958, 0x080c, 0x297d,
-+	0x1940, 0x080c, 0xb588, 0x1d70, 0x703c, 0x6016, 0x6007, 0x004a,
-+	0x6003, 0x0001, 0x080c, 0x75be, 0x0005, 0x080c, 0xb496, 0x0904,
-+	0xb411, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c,
-+	0x7aa4, 0x0005, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c,
-+	0x00ff, 0x81ff, 0x01f8, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001,
-+	0x12f4, 0x2004, 0x9106, 0x11a0, 0x7144, 0x2001, 0x12f5, 0x2004,
-+	0x9106, 0x0180, 0x9186, 0x0002, 0x1158, 0x2011, 0x0276, 0x20a9,
-+	0x0004, 0x6010, 0x6010, 0x9098, 0x000a, 0x080c, 0x9d60, 0x0110,
-+	0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4,
-+	0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00d6,
-+	0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1100,
-+	0x7088, 0x908a, 0x00f9, 0x16c8, 0x20e1, 0x0000, 0x20e9, 0x0001,
-+	0x2001, 0x12da, 0x2003, 0x0000, 0x080c, 0x0e9d, 0x0570, 0x2d00,
-+	0x6016, 0x7088, 0x8004, 0x6816, 0x908a, 0x001e, 0x02b8, 0x6833,
-+	0x001e, 0x20a9, 0x001e, 0x9d80, 0x001b, 0x20a0, 0x2001, 0x12da,
-+	0x0016, 0x200c, 0x0451, 0x001e, 0x2d70, 0x080c, 0x0e9d, 0x01a8,
-+	0x2d00, 0x7006, 0x2100, 0x81ff, 0x0168, 0x0c30, 0x6832, 0x20a8,
-+	0x9d80, 0x001b, 0x20a0, 0x2001, 0x12da, 0x0016, 0x200c, 0x00a9,
-+	0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1100, 0x708b,
-+	0x0000, 0x6014, 0x2068, 0x080c, 0x0edf, 0x9006, 0x012e, 0x01de,
-+	0x01ce, 0x00ee, 0x00de, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026,
-+	0x0036, 0x00c6, 0x918c, 0xffff, 0x11a8, 0x080c, 0x1b40, 0x2099,
-+	0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-+	0x00f8, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x1b40, 0x2099,
-+	0x0260, 0x0ca8, 0x080c, 0x1b40, 0x2061, 0x12da, 0x6004, 0x2098,
-+	0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8,
-+	0x4003, 0x22a8, 0x8108, 0x080c, 0x1b40, 0x2099, 0x0260, 0x0ca8,
-+	0x2061, 0x12da, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006,
-+	0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021,
-+	0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e,
-+	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8,
-+	0x080c, 0x1b58, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312,
-+	0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8,
-+	0x22a8, 0x8108, 0x080c, 0x1b58, 0x20a1, 0x0240, 0x0c98, 0x080c,
-+	0x1b58, 0x2061, 0x12dd, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312,
-+	0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138,
-+	0x22a8, 0x8108, 0x080c, 0x1b58, 0x20a1, 0x0240, 0x0c98, 0x2061,
-+	0x12dd, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020,
-+	0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296,
-+	0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
-+	0x00d6, 0x0066, 0x6610, 0x2668, 0x6e04, 0x96b4, 0xff00, 0x8637,
-+	0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0x6e04, 0x96b4,
-+	0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085,
-+	0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0441, 0x00de, 0x0005,
-+	0x00d6, 0x0489, 0x11e8, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084,
-+	0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0118, 0x2009,
-+	0x0001, 0x0058, 0xd1ec, 0x0160, 0x6920, 0x918c, 0x00ff, 0x6824,
-+	0x080c, 0x1f63, 0x1128, 0x2110, 0x900e, 0x080c, 0x28a5, 0x0018,
-+	0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x2069, 0x026d,
-+	0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001,
-+	0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808,
-+	0x9084, 0xff00, 0x9086, 0x0800, 0x1140, 0x6800, 0x9084, 0x00ff,
-+	0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2,
-+	0x0053, 0x1a0c, 0x0d7e, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2,
-+	0x0040, 0x1a04, 0xb720, 0x0092, 0x91b6, 0x0027, 0x0120, 0x91b6,
-+	0x0014, 0x190c, 0x0d7e, 0x2001, 0x0007, 0x080c, 0x5592, 0x080c,
-+	0x79ab, 0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005, 0xb64e, 0xb650,
-+	0xb64e, 0xb64e, 0xb64e, 0xb650, 0xb661, 0xb719, 0xb6b8, 0xb719,
-+	0xb6cc, 0xb719, 0xb661, 0xb719, 0xb711, 0xb719, 0xb711, 0xb719,
-+	0xb719, 0xb64e, 0xb64e, 0xb64e, 0xb64e, 0xb64e, 0xb64e, 0xb64e,
-+	0xb64e, 0xb64e, 0xb64e, 0xb64e, 0xb650, 0xb64e, 0xb719, 0xb64e,
-+	0xb64e, 0xb719, 0xb64e, 0xb716, 0xb719, 0xb64e, 0xb64e, 0xb64e,
-+	0xb64e, 0xb719, 0xb719, 0xb64e, 0xb719, 0xb719, 0xb64e, 0xb65c,
-+	0xb64e, 0xb64e, 0xb64e, 0xb64e, 0xb715, 0xb719, 0xb64e, 0xb64e,
-+	0xb719, 0xb719, 0xb64e, 0xb64e, 0xb64e, 0xb64e, 0x080c, 0x0d7e,
-+	0x080c, 0x79ab, 0x2001, 0x12c0, 0x2004, 0x601a, 0x6003, 0x0002,
-+	0x080c, 0x7aa4, 0x0804, 0xb71f, 0x9006, 0x080c, 0x5556, 0x0804,
-+	0xb719, 0x080c, 0x58c6, 0x1904, 0xb719, 0x9006, 0x080c, 0x5556,
-+	0x6010, 0x9080, 0x0004, 0x2004, 0x9086, 0x00ff, 0x1140, 0x00f6,
-+	0x2079, 0x1100, 0x78a0, 0x8000, 0x78a2, 0x00fe, 0x0438, 0x6010,
-+	0x00c6, 0x2060, 0x6000, 0xd0f4, 0x1178, 0x6010, 0x9005, 0x0160,
-+	0x0036, 0x0046, 0x63a0, 0x2021, 0x0007, 0x080c, 0x4026, 0x004e,
-+	0x003e, 0x00ce, 0x0804, 0xb719, 0x00ce, 0x080c, 0x2982, 0x1904,
-+	0xb719, 0x2001, 0x1100, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6,
-+	0x2079, 0x1100, 0x78a0, 0x8000, 0x78a2, 0x00fe, 0x2001, 0x0002,
-+	0x080c, 0x5568, 0x080c, 0x79ab, 0x6023, 0x0001, 0x6003, 0x0001,
-+	0x6007, 0x0002, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x6110, 0x00c6,
-+	0x2160, 0x2009, 0x0001, 0x080c, 0x7206, 0x00ce, 0x0804, 0xb71f,
-+	0x6610, 0x00d6, 0x2668, 0x6e04, 0x00de, 0x96b4, 0xff00, 0x8637,
-+	0x9686, 0x0006, 0x0904, 0xb719, 0x9686, 0x0004, 0x0904, 0xb719,
-+	0x2001, 0x0004, 0x0804, 0xb717, 0x2001, 0x1100, 0x2004, 0x9086,
-+	0x0003, 0x1160, 0x0036, 0x0046, 0x6010, 0x9080, 0x0028, 0x201c,
-+	0x2021, 0x0006, 0x080c, 0x4026, 0x004e, 0x003e, 0x2001, 0x0006,
-+	0x080c, 0xb73d, 0x6610, 0x00d6, 0x2668, 0x6e04, 0x00de, 0x0066,
-+	0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0120, 0x2001,
-+	0x0006, 0x080c, 0x5592, 0x080c, 0x58c6, 0x1518, 0x2001, 0x1136,
-+	0x2004, 0xd0a4, 0x01f0, 0x00d6, 0x6610, 0x2668, 0x6e04, 0x00de,
-+	0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, 0x2079, 0x1100,
-+	0x78a0, 0x8000, 0x78a2, 0x00fe, 0x0804, 0xb69e, 0x2001, 0x0004,
-+	0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, 0x0010, 0x080c,
-+	0x5592, 0x080c, 0x79ab, 0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005,
-+	0x2600, 0x0002, 0xb734, 0xb734, 0xb734, 0xb734, 0xb734, 0xb736,
-+	0xb734, 0xb734, 0xb734, 0xb734, 0xb736, 0xb734, 0xb734, 0xb734,
-+	0xb736, 0xb736, 0xb736, 0xb736, 0x080c, 0x0d7e, 0x080c, 0x79ab,
-+	0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x0016, 0x00d6, 0x6110,
-+	0x2168, 0x6900, 0xd184, 0x0138, 0x080c, 0x5568, 0x9006, 0x080c,
-+	0x5556, 0x080c, 0x2886, 0x00de, 0x001e, 0x0005, 0x6610, 0x00d6,
-+	0x2668, 0x6804, 0x9084, 0xff00, 0x8007, 0x00de, 0x90b2, 0x000c,
-+	0x1a0c, 0x0d7e, 0x91b6, 0x0015, 0x1110, 0x003b, 0x0028, 0x91b6,
-+	0x0016, 0x190c, 0x0d7e, 0x006b, 0x0005, 0x98b0, 0x98b0, 0x98b0,
-+	0x98b0, 0x98b0, 0x98b0, 0xb7bb, 0xb77d, 0x98b0, 0x98b0, 0x98b0,
-+	0x98b0, 0x98b0, 0x98b0, 0x98b0, 0x98b0, 0x98b0, 0x98b0, 0xb7bb,
-+	0xb7c2, 0x98b0, 0x98b0, 0x98b0, 0x98b0, 0x00f6, 0x080c, 0x58c6,
-+	0x11d8, 0x6010, 0x907d, 0x01c0, 0x7800, 0xd0f4, 0x1118, 0x7810,
-+	0x9005, 0x1190, 0x9006, 0x080c, 0x5556, 0x2001, 0x0002, 0x080c,
-+	0x5568, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-+	0x75be, 0x080c, 0x7aa4, 0x00e8, 0x2011, 0x0263, 0x2204, 0x8211,
-+	0x220c, 0x080c, 0x1f63, 0x11a8, 0x00c6, 0x080c, 0x5608, 0x0120,
-+	0x00ce, 0x080c, 0x8ed9, 0x0068, 0x6010, 0x0006, 0x6014, 0x0006,
-+	0x080c, 0x5100, 0x000e, 0x6016, 0x000e, 0x6012, 0x00ce, 0x080c,
-+	0x8ed9, 0x00fe, 0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c,
-+	0x8ed9, 0x0005, 0x080c, 0x9bf7, 0x1148, 0x6003, 0x0001, 0x6007,
-+	0x0001, 0x080c, 0x75be, 0x080c, 0x7aa4, 0x0010, 0x080c, 0x8ed9,
-+	0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d7e, 0x080c, 0x79ab,
-+	0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005, 0x9182, 0x0040, 0x0002,
-+	0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3, 0xb7f5, 0xb7f3, 0xb7f3, 0xb7f3,
-+	0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3, 0xb7f3,
-+	0xb7f3, 0xb7f3, 0xb7f3, 0x080c, 0x0d7e, 0x00d6, 0x00e6, 0x00f6,
-+	0x0046, 0x0026, 0x6210, 0x9280, 0x002b, 0x2004, 0x9005, 0x1190,
-+	0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xb858,
-+	0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c,
-+	0x73af, 0x0020, 0x9026, 0x080c, 0xc363, 0x0c50, 0x080c, 0x0eb6,
-+	0x090c, 0x0d7e, 0x6003, 0x0007, 0x2d00, 0x6867, 0x010d, 0x9006,
-+	0x6802, 0x686a, 0x6c8a, 0x2c00, 0x688e, 0x6008, 0x68e2, 0x6010,
-+	0x2078, 0x78a0, 0x8007, 0x7130, 0x697a, 0x0016, 0x9084, 0xff00,
-+	0x6876, 0x687f, 0x0000, 0x6883, 0x0000, 0x6887, 0x0036, 0x080c,
-+	0x5b76, 0x001e, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c,
-+	0xc0b9, 0x0804, 0xb8b2, 0x9486, 0x0400, 0x1130, 0x2019, 0x0002,
-+	0x080c, 0xc072, 0x0804, 0xb8b2, 0x9486, 0x0200, 0x1110, 0x080c,
-+	0xc05a, 0x9486, 0x1000, 0x1110, 0x080c, 0xc0a1, 0x0804, 0xb8b2,
-+	0x2069, 0x1354, 0x6a00, 0xd284, 0x0904, 0xb91a, 0x9284, 0x0300,
-+	0x1904, 0xb913, 0x6804, 0x9005, 0x0904, 0xb8fb, 0x2d78, 0x6003,
-+	0x0007, 0x080c, 0x0e9d, 0x0904, 0xb8bc, 0x7800, 0xd08c, 0x1118,
-+	0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x9006, 0x6802, 0x6867,
-+	0x0116, 0x686a, 0x6008, 0x68e2, 0x2c00, 0x687a, 0x6010, 0x2078,
-+	0x78a0, 0x8007, 0x7130, 0x69b6, 0x6876, 0x7928, 0x69ba, 0x792c,
-+	0x69be, 0x7930, 0x69c2, 0x7934, 0x69c6, 0x6883, 0x003d, 0x7044,
-+	0x9084, 0x0003, 0x9080, 0xb8b8, 0x2005, 0x687e, 0x20a9, 0x000a,
-+	0x2001, 0x0270, 0x9d90, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080,
-+	0x20e1, 0x0000, 0x20e9, 0x0001, 0x2098, 0x22a0, 0x4003, 0x200b,
-+	0x0000, 0x2001, 0x027a, 0x200c, 0x69b2, 0x8000, 0x200c, 0x69ae,
-+	0x080c, 0x5b76, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x0005,
-+	0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x110f, 0x2004, 0xd084,
-+	0x0120, 0x080c, 0x0eb6, 0x1904, 0xb86d, 0x6017, 0x0100, 0x6003,
-+	0x0001, 0x6007, 0x0041, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x0c10,
-+	0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198,
-+	0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0x0700, 0x910d,
-+	0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x756e,
-+	0x080c, 0x7aa4, 0x0838, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017,
-+	0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x756e, 0x080c,
-+	0x7aa4, 0x0804, 0xb8b2, 0x2001, 0x110d, 0x2004, 0xd0ec, 0x0120,
-+	0x2011, 0x8049, 0x080c, 0x3f23, 0x6017, 0x0300, 0x0010, 0x6017,
-+	0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x756e, 0x080c,
-+	0x7aa4, 0x0804, 0xb8b2, 0x6017, 0x0500, 0x0c98, 0x6017, 0x0600,
-+	0x0804, 0xb8d0, 0x6017, 0x0200, 0x0804, 0xb8d0, 0x9186, 0x0013,
-+	0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0d7e, 0x9082, 0x0040,
-+	0x0a0c, 0x0d7e, 0x2008, 0x0804, 0xb9ca, 0x9186, 0x0051, 0x0140,
-+	0x9186, 0x0047, 0x11e8, 0x6004, 0x9086, 0x0041, 0x0904, 0xb97e,
-+	0x2001, 0x0109, 0x2004, 0xd084, 0x0904, 0xb97e, 0x0126, 0x2091,
-+	0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x745c, 0x002e, 0x001e,
-+	0x000e, 0x012e, 0x6000, 0x9086, 0x0002, 0x1580, 0x0804, 0xba17,
-+	0x9186, 0x0027, 0x0530, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014,
-+	0x0500, 0x190c, 0x0d7e, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
-+	0x00c6, 0x0126, 0x2091, 0x2800, 0x00c6, 0x2061, 0x0100, 0x0006,
-+	0x0016, 0x0026, 0x080c, 0x745c, 0x002e, 0x001e, 0x000e, 0x00ce,
-+	0x012e, 0x00ce, 0x6000, 0x9086, 0x0004, 0x190c, 0x0d7e, 0x0804,
-+	0xbaf9, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0x8f6e,
-+	0x0005, 0xb994, 0xb996, 0xb996, 0xb9ba, 0xb994, 0xb994, 0xb994,
-+	0xb994, 0xb994, 0xb994, 0xb994, 0xb994, 0xb994, 0xb994, 0xb994,
-+	0xb994, 0xb994, 0xb994, 0xb994, 0x080c, 0x0d7e, 0x080c, 0x79ab,
-+	0x080c, 0x7aa4, 0x0036, 0x00d6, 0x6014, 0x906d, 0x01c0, 0x9d84,
-+	0xf000, 0x01a8, 0x6003, 0x0002, 0x6010, 0x2004, 0xd0bc, 0x1178,
-+	0x2019, 0x0004, 0x080c, 0xc0e9, 0x6017, 0x0000, 0x6018, 0x9005,
-+	0x1120, 0x2001, 0x12c1, 0x2004, 0x601a, 0x6003, 0x0007, 0x00de,
-+	0x003e, 0x0005, 0x00d6, 0x080c, 0x79ab, 0x080c, 0x7aa4, 0x080c,
-+	0xa942, 0x0120, 0x6014, 0x2068, 0x080c, 0x0ecf, 0x080c, 0x8f09,
-+	0x00de, 0x0005, 0x0002, 0xb9de, 0xb9fb, 0xb9e7, 0xba11, 0xb9de,
-+	0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de,
-+	0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de, 0xb9de, 0x080c, 0x0d7e,
-+	0x6014, 0x9088, 0x001f, 0x2104, 0x9085, 0x0400, 0x200a, 0x080c,
-+	0x79ab, 0x6014, 0x9080, 0x001f, 0x2004, 0xd0b4, 0x0138, 0x6003,
-+	0x0007, 0x2009, 0x0043, 0x080c, 0x8f53, 0x0010, 0x6003, 0x0004,
-+	0x080c, 0x7aa4, 0x0005, 0x080c, 0x79ab, 0x6114, 0x9184, 0xf000,
-+	0x0128, 0x9180, 0x001f, 0x200c, 0xd1ec, 0x1138, 0x080c, 0x7384,
-+	0x080c, 0x8ed9, 0x080c, 0x7aa4, 0x0005, 0x080c, 0xc32e, 0x0db0,
-+	0x0cc8, 0x080c, 0x79ab, 0x2009, 0x0041, 0x0804, 0xbb7b, 0x9182,
-+	0x0040, 0x0002, 0xba2d, 0xba2f, 0xba2d, 0xba2d, 0xba2d, 0xba2d,
-+	0xba2d, 0xba2d, 0xba2d, 0xba2d, 0xba2d, 0xba2d, 0xba2d, 0xba2d,
-+	0xba2d, 0xba2d, 0xba2d, 0xba30, 0xba2d, 0x080c, 0x0d7e, 0x0005,
-+	0x00d6, 0x080c, 0x7384, 0x00de, 0x080c, 0xc381, 0x080c, 0x8ed9,
-+	0x0005, 0x9182, 0x0040, 0x0002, 0xba4f, 0xba4f, 0xba4f, 0xba4f,
-+	0xba4f, 0xba4f, 0xba4f, 0xba51, 0xba4f, 0xba54, 0xbac4, 0xba4f,
-+	0xba4f, 0xba4f, 0xba4f, 0xbac4, 0xba4f, 0xba4f, 0xba4f, 0x080c,
-+	0x0d7e, 0x080c, 0x8f6e, 0x0005, 0x2001, 0x0105, 0x2004, 0x9084,
-+	0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004,
-+	0x9105, 0x1904, 0xbac4, 0x2009, 0x110c, 0x2104, 0xd0d4, 0x0904,
-+	0xbac4, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd,
-+	0x9085, 0x0010, 0x200a, 0x2001, 0x1172, 0x2004, 0xd0e4, 0x1528,
-+	0x603b, 0x0000, 0x080c, 0x7a55, 0x6014, 0x00d6, 0x2068, 0x687c,
-+	0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001,
-+	0x110c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x7b69, 0x2009, 0x0041,
-+	0x00de, 0x0804, 0xbb7b, 0x080c, 0x7b69, 0x6003, 0x0007, 0x601b,
-+	0x0000, 0x080c, 0x7384, 0x00de, 0x0005, 0x2001, 0x0100, 0x2004,
-+	0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890,
-+	0x2001, 0x110c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c,
-+	0x2369, 0x080c, 0x7b69, 0x6014, 0x9080, 0x001f, 0x200c, 0xd1ec,
-+	0x1130, 0x080c, 0x7384, 0x080c, 0x8ed9, 0x00de, 0x0005, 0x080c,
-+	0xc32e, 0x0db8, 0x00de, 0x0005, 0x2001, 0x110c, 0x200c, 0xc1d4,
-+	0x2102, 0x0036, 0x080c, 0x7a55, 0x080c, 0x7b69, 0x6014, 0x00d6,
-+	0x2068, 0x6010, 0x2004, 0xd0bc, 0x0188, 0x687c, 0x9084, 0x0003,
-+	0x9086, 0x0002, 0x0140, 0x68ac, 0x6330, 0x931a, 0x6332, 0x68b0,
-+	0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004,
-+	0x080c, 0xc0e9, 0x6018, 0x9005, 0x1128, 0x2001, 0x12c1, 0x2004,
-+	0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, 0x00de, 0x003e,
-+	0x0005, 0x9182, 0x0040, 0x0002, 0xbb10, 0xbb10, 0xbb10, 0xbb10,
-+	0xbb10, 0xbb10, 0xbb10, 0xbb10, 0xbb12, 0xbb10, 0xbb10, 0xbb10,
-+	0xbb10, 0xbb10, 0xbb10, 0xbb10, 0xbb10, 0xbb10, 0xbb10, 0xbb57,
-+	0x080c, 0x0d7e, 0x6014, 0x00d6, 0x2068, 0x6834, 0x6a38, 0x6110,
-+	0x210c, 0xd1bc, 0x1190, 0x920d, 0x1518, 0x687c, 0xd0fc, 0x0128,
-+	0x2009, 0x0041, 0x00de, 0x0804, 0xbb7b, 0x6003, 0x0007, 0x601b,
-+	0x0000, 0x080c, 0x7384, 0x00de, 0x0005, 0x6124, 0xd1f4, 0x1d58,
-+	0x0006, 0x0046, 0x6cac, 0x9422, 0x69b0, 0x2200, 0x910b, 0x6030,
-+	0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8,
-+	0x6110, 0x210c, 0xd1bc, 0x1178, 0x2009, 0x110d, 0x210c, 0xd19c,
-+	0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c,
-+	0x7386, 0x00de, 0x0005, 0x6003, 0x0002, 0x00de, 0x0005, 0x6024,
-+	0xd0f4, 0x0128, 0x080c, 0x1303, 0x1904, 0xbb12, 0x0005, 0x6014,
-+	0x00d6, 0x2068, 0x6834, 0x6938, 0x00de, 0x9105, 0x1120, 0x080c,
-+	0x1303, 0x1904, 0xbb12, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000,
-+	0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015,
-+	0x6a9a, 0x6896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186,
-+	0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d7e, 0x6024, 0xd0dc,
-+	0x090c, 0x0d7e, 0x0005, 0xbb9e, 0xbba5, 0xbbb1, 0xbbbd, 0xbb9e,
-+	0xbb9e, 0xbb9e, 0xbbcc, 0xbb9e, 0xbba0, 0xbba0, 0xbb9e, 0xbb9e,
-+	0xbb9e, 0xbb9e, 0xbba0, 0xbb9e, 0xbba0, 0xbb9e, 0x080c, 0x0d7e,
-+	0x6024, 0xd0dc, 0x090c, 0x0d7e, 0x0005, 0x6003, 0x0001, 0x6106,
-+	0x080c, 0x756e, 0x0126, 0x2091, 0x8000, 0x080c, 0x7aa4, 0x012e,
-+	0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x756e, 0x0126, 0x2091,
-+	0x8000, 0x080c, 0x7aa4, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106,
-+	0x2c10, 0x080c, 0x1605, 0x0126, 0x2091, 0x8000, 0x080c, 0x75db,
-+	0x080c, 0x7b72, 0x012e, 0x0005, 0x9016, 0x080c, 0x137c, 0x0005,
-+	0x0126, 0x2091, 0x8000, 0x0036, 0x00d6, 0x9182, 0x0040, 0x0023,
-+	0x00de, 0x003e, 0x012e, 0x0005, 0xbbec, 0xbbee, 0xbc00, 0xbc1a,
-+	0xbbec, 0xbbec, 0xbbec, 0xbc2f, 0xbbec, 0xbbec, 0xbbec, 0xbbec,
-+	0xbbec, 0xbbec, 0xbbec, 0xbbec, 0x080c, 0x0d7e, 0x6014, 0x2068,
-+	0x687c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0,
-+	0x6003, 0x0001, 0x6106, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x0490,
-+	0x6014, 0x2068, 0x687c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e,
-+	0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x756e, 0x080c,
-+	0x7aa4, 0x0400, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c,
-+	0xc0e9, 0x00c0, 0x6014, 0x2068, 0x687c, 0xd0fc, 0x0d98, 0x909c,
-+	0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10,
-+	0x080c, 0x1605, 0x080c, 0x75db, 0x080c, 0x7b72, 0x0018, 0x9016,
-+	0x080c, 0x137c, 0x0005, 0x080c, 0x79ab, 0x6114, 0x81ff, 0x0158,
-+	0x00d6, 0x2168, 0x080c, 0xc3c7, 0x0036, 0x2019, 0x0029, 0x080c,
-+	0xc0e9, 0x003e, 0x00de, 0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005,
-+	0x080c, 0x7a55, 0x6114, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c,
-+	0xc3c7, 0x0036, 0x2019, 0x0029, 0x080c, 0xc0e9, 0x003e, 0x00de,
-+	0x080c, 0x8f09, 0x080c, 0x7b72, 0x0005, 0x9182, 0x0085, 0x0002,
-+	0xbc6f, 0xbc6d, 0xbc6d, 0xbc7b, 0xbc6d, 0xbc6d, 0xbc6d, 0xbc6d,
-+	0xbc6d, 0xbc6d, 0xbc6d, 0xbc6d, 0xbc6d, 0x080c, 0x0d7e, 0x6003,
-+	0x000b, 0x6106, 0x080c, 0x756e, 0x0126, 0x2091, 0x8000, 0x080c,
-+	0x7aa4, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xc327, 0x0118,
-+	0x080c, 0x8ed9, 0x0440, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001,
-+	0x110d, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x9080, 0x0028, 0x2024,
-+	0x8427, 0x2c00, 0x2011, 0x014e, 0x080c, 0x91b2, 0x7220, 0x080c,
-+	0xbf8f, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224,
-+	0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c,
-+	0x756e, 0x080c, 0x7aa4, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013,
-+	0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d7e, 0x908a, 0x0092,
-+	0x1a0c, 0x0d7e, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130,
-+	0x9186, 0x0014, 0x0118, 0x080c, 0x8f6e, 0x0050, 0x2001, 0x0007,
-+	0x080c, 0x5592, 0x080c, 0x79ab, 0x080c, 0x8f09, 0x080c, 0x7aa4,
-+	0x0005, 0xbcde, 0xbce0, 0xbce0, 0xbcde, 0xbcde, 0xbcde, 0xbcde,
-+	0xbcde, 0xbcde, 0xbcde, 0xbcde, 0xbcde, 0xbcde, 0x080c, 0x0d7e,
-+	0x080c, 0x79ab, 0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005, 0x9182,
-+	0x0085, 0x0a0c, 0x0d7e, 0x9182, 0x0092, 0x1a0c, 0x0d7e, 0x9182,
-+	0x0085, 0x0002, 0xbcff, 0xbcff, 0xbcff, 0xbd01, 0xbcff, 0xbcff,
-+	0xbcff, 0xbcff, 0xbcff, 0xbcff, 0xbcff, 0xbcff, 0xbcff, 0x080c,
-+	0x0d7e, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130,
-+	0x9186, 0x0027, 0x0118, 0x080c, 0x8f6e, 0x0030, 0x080c, 0x79ab,
-+	0x080c, 0x8f09, 0x080c, 0x7aa4, 0x0005, 0x0036, 0x080c, 0xc381,
-+	0x6043, 0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003,
-+	0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x0086,
-+	0x2c40, 0x0096, 0x904e, 0x080c, 0x8968, 0x009e, 0x008e, 0x1570,
-+	0x0076, 0x2c38, 0x080c, 0x8a0a, 0x007e, 0x1540, 0x6000, 0x9086,
-+	0x0000, 0x0520, 0x6020, 0x9086, 0x0007, 0x0500, 0x00d6, 0x601c,
-+	0xd084, 0x0150, 0x080c, 0xc381, 0x2001, 0x12c0, 0x2004, 0x601a,
-+	0x080c, 0x1509, 0x6023, 0x0007, 0x6014, 0x2068, 0x080c, 0xa942,
-+	0x0110, 0x080c, 0xc0e9, 0x00de, 0x6017, 0x0000, 0x080c, 0xc381,
-+	0x6023, 0x0007, 0x2001, 0x12c0, 0x2004, 0x601a, 0x003e, 0x012e,
-+	0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938,
-+	0x783c, 0x080c, 0x1f63, 0x1590, 0x0016, 0x00c6, 0x080c, 0x5608,
-+	0x1558, 0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c,
-+	0x8ac9, 0x080c, 0x76f0, 0x0076, 0x903e, 0x080c, 0x75ee, 0x007e,
-+	0x001e, 0x0076, 0x903e, 0x080c, 0xbec2, 0x007e, 0x0026, 0x6204,
-+	0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004,
-+	0x1118, 0x62a0, 0x080c, 0x2915, 0x002e, 0x001e, 0x080c, 0x5100,
-+	0x6612, 0x6516, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e,
-+	0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x2009,
-+	0x1122, 0x2104, 0x9086, 0x0074, 0x1904, 0xbdfb, 0x2069, 0x0260,
-+	0x6944, 0x9182, 0x0100, 0x06d8, 0x6940, 0x9184, 0x8000, 0x0904,
-+	0xbdf8, 0x2001, 0x12a7, 0x2004, 0x9005, 0x1160, 0x6010, 0x2070,
-+	0x7010, 0x9084, 0x00ff, 0x0118, 0x7000, 0xd0f4, 0x0118, 0x9184,
-+	0x0800, 0x0570, 0x6948, 0x918a, 0x0001, 0x0620, 0x694c, 0x2009,
-+	0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182,
-+	0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001,
-+	0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100,
-+	0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017,
-+	0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028,
-+	0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008,
-+	0x9006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-+	0x0026, 0x0036, 0x0156, 0x6210, 0x2268, 0x6b04, 0x9394, 0x00ff,
-+	0x9286, 0x0006, 0x0190, 0x9286, 0x0004, 0x0178, 0x9394, 0xff00,
-+	0x8217, 0x9286, 0x0006, 0x0148, 0x9286, 0x0004, 0x0130, 0x00c6,
-+	0x2d60, 0x080c, 0x5617, 0x00ce, 0x04c0, 0x2011, 0x0276, 0x20a9,
-+	0x0004, 0x9d98, 0x000a, 0x080c, 0x9d60, 0x1580, 0x2011, 0x027a,
-+	0x20a9, 0x0004, 0x9d98, 0x0006, 0x080c, 0x9d60, 0x1538, 0x0046,
-+	0x0016, 0x6aa0, 0x9294, 0x00ff, 0x8227, 0x9006, 0x2009, 0x1153,
-+	0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xc12f, 0x6800,
-+	0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x76f0, 0x0076, 0x2039,
-+	0x0000, 0x080c, 0x75ee, 0x2c08, 0x080c, 0xbec2, 0x007e, 0x2001,
-+	0x0007, 0x080c, 0x5592, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e,
-+	0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800,
-+	0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de,
-+	0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
-+	0x026c, 0x7930, 0x7834, 0x080c, 0x1f63, 0x11a0, 0x080c, 0x5608,
-+	0x1188, 0x2011, 0x0270, 0x20a9, 0x0004, 0x9c98, 0x000a, 0x080c,
-+	0x9d60, 0x1140, 0x2011, 0x0274, 0x20a9, 0x0004, 0x9c98, 0x0006,
-+	0x080c, 0x9d60, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
-+	0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
-+	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x1f63, 0x11a0, 0x080c,
-+	0x5608, 0x1188, 0x2011, 0x0276, 0x20a9, 0x0004, 0x9c98, 0x000a,
-+	0x080c, 0x9d60, 0x1140, 0x2011, 0x027a, 0x20a9, 0x0004, 0x9c98,
-+	0x0006, 0x080c, 0x9d60, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
-+	0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
-+	0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x130d,
-+	0x252c, 0x2021, 0x1313, 0x2424, 0x2061, 0x15c0, 0x2071, 0x1100,
-+	0x764c, 0x706c, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1389, 0x000e,
-+	0x0128, 0x8001, 0x9602, 0x1a04, 0xbf4b, 0x0018, 0x9606, 0x0904,
-+	0xbf4b, 0x2100, 0x9c06, 0x0904, 0xbf42, 0x080c, 0xc15b, 0x0904,
-+	0xbf42, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x2982, 0x0904,
-+	0xbf66, 0x6004, 0x9086, 0x0000, 0x1904, 0xbf66, 0x9786, 0x0004,
-+	0x0904, 0xbf66, 0x9786, 0x0007, 0x05e8, 0x2500, 0x9c06, 0x05d0,
-+	0x2400, 0x9c06, 0x05b8, 0x080c, 0xc16b, 0x15a0, 0x88ff, 0x0118,
-+	0x6054, 0x9906, 0x1578, 0x00d6, 0x6000, 0x9086, 0x0004, 0x1120,
-+	0x0016, 0x080c, 0x1509, 0x001e, 0x9786, 0x0008, 0x1148, 0x080c,
-+	0xab2e, 0x1130, 0x080c, 0x97dc, 0x00de, 0x080c, 0x8f09, 0x00d0,
-+	0x6014, 0x2068, 0x080c, 0xa942, 0x0190, 0x9786, 0x0003, 0x1528,
-+	0x6867, 0x0103, 0x6b7a, 0x6877, 0x0000, 0x080c, 0xc3c7, 0x0016,
-+	0x080c, 0xac01, 0x080c, 0x5b76, 0x001e, 0x080c, 0xab11, 0x00de,
-+	0x080c, 0x8f09, 0x9ce0, 0x0018, 0x2001, 0x1118, 0x2004, 0x9c02,
-+	0x1210, 0x0804, 0xbed6, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e,
-+	0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150,
-+	0x9386, 0x0005, 0x0128, 0x080c, 0xc3c7, 0x080c, 0xc0e9, 0x08f8,
-+	0x00de, 0x0c00, 0x9786, 0x000a, 0x0968, 0x0850, 0x080c, 0xc16b,
-+	0x19c8, 0x81ff, 0x09b8, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018,
-+	0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1958, 0x6000,
-+	0x9086, 0x0002, 0x1938, 0x080c, 0xab1d, 0x0130, 0x080c, 0xab2e,
-+	0x1908, 0x080c, 0x97dc, 0x0038, 0x080c, 0x2886, 0x080c, 0xab2e,
-+	0x1110, 0x080c, 0x97dc, 0x080c, 0x8f09, 0x0804, 0xbf42, 0x00c6,
-+	0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xc101, 0x001e,
-+	0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005,
-+	0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfb0, 0xbfae,
-+	0xbfae, 0xbfae, 0xbfae, 0x8f09, 0x8f09, 0xbfae, 0x9006, 0x0005,
-+	0x0046, 0x0016, 0x7010, 0x9080, 0x0028, 0x2024, 0x94a4, 0x00ff,
-+	0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xc12f, 0x001e, 0x004e,
-+	0x0036, 0x2019, 0x0002, 0x080c, 0xbd23, 0x003e, 0x9085, 0x0001,
-+	0x0005, 0x00d6, 0x6014, 0x906d, 0x9084, 0xf000, 0x0130, 0x080c,
-+	0xa5f3, 0x687b, 0x0005, 0x080c, 0x5b76, 0x00de, 0x080c, 0x8f09,
-+	0x9085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x5556, 0x0156,
-+	0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1105, 0x2011,
-+	0x0276, 0x080c, 0x9d60, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005,
-+	0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026,
-+	0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x15c0, 0x2079, 0x0001,
-+	0x8fff, 0x0904, 0xc04d, 0x2071, 0x1100, 0x764c, 0x706c, 0x8001,
-+	0x9602, 0x1a04, 0xc04d, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0,
-+	0x2078, 0x080c, 0xc15b, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720,
-+	0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1140,
-+	0x6010, 0x9206, 0x1508, 0x85ff, 0x0118, 0x6054, 0x9106, 0x11e0,
-+	0x00d6, 0x601c, 0xd084, 0x0150, 0x080c, 0xc381, 0x2001, 0x12c0,
-+	0x2004, 0x601a, 0x080c, 0x1509, 0x6023, 0x0007, 0x6014, 0x2068,
-+	0x080c, 0xa942, 0x0120, 0x0046, 0x080c, 0xc0e9, 0x004e, 0x00de,
-+	0x080c, 0x8f09, 0x88ff, 0x1198, 0x9ce0, 0x0018, 0x2001, 0x1118,
-+	0x2004, 0x9c02, 0x1210, 0x0804, 0xc000, 0x9006, 0x012e, 0x002e,
-+	0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5,
-+	0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001,
-+	0x2c20, 0x2019, 0x0002, 0x6210, 0x0096, 0x904e, 0x080c, 0x8968,
-+	0x009e, 0x008e, 0x903e, 0x080c, 0x8a0a, 0x080c, 0xbff1, 0x005e,
-+	0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
-+	0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c,
-+	0x5608, 0x1198, 0x2c10, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029,
-+	0x0001, 0x0096, 0x904e, 0x080c, 0x8968, 0x009e, 0x008e, 0x903e,
-+	0x080c, 0x8a0a, 0x080c, 0xbff1, 0x005e, 0x003e, 0x001e, 0x8108,
-+	0x1f04, 0xc07d, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e,
-+	0x0005, 0x0076, 0x0056, 0x6210, 0x0086, 0x9046, 0x2029, 0x0001,
-+	0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0x8968, 0x009e, 0x008e,
-+	0x903e, 0x080c, 0x8a0a, 0x2c20, 0x080c, 0xbff1, 0x005e, 0x007e,
-+	0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20,
-+	0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x5608, 0x11a8,
-+	0x2c10, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c,
-+	0xc363, 0x004e, 0x0096, 0x904e, 0x080c, 0x8968, 0x009e, 0x008e,
-+	0x903e, 0x080c, 0x8a0a, 0x080c, 0xbff1, 0x003e, 0x001e, 0x8108,
-+	0x1f04, 0xc0c3, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e,
-+	0x0005, 0x0016, 0x00f6, 0x9d82, 0x45c0, 0x0280, 0x9d82, 0xffff,
-+	0x1268, 0x6800, 0x907d, 0x0138, 0x6803, 0x0000, 0x6b82, 0x080c,
-+	0x5b76, 0x2f68, 0x0cb0, 0x6b82, 0x080c, 0x5b76, 0x00fe, 0x001e,
-+	0x0005, 0x00e6, 0x0046, 0x0036, 0x2061, 0x15c0, 0x9005, 0x1138,
-+	0x2071, 0x1100, 0x744c, 0x706c, 0x8001, 0x9402, 0x12d8, 0x2100,
-+	0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206,
-+	0x1130, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0,
-+	0x0018, 0x2001, 0x1118, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085,
-+	0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6,
-+	0x0006, 0x080c, 0x0eb6, 0x000e, 0x090c, 0x0d7e, 0x6867, 0x010d,
-+	0x688e, 0x0026, 0x2010, 0x080c, 0xa932, 0x2001, 0x0000, 0x0120,
-+	0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0x687a, 0x6986, 0x6c76,
-+	0x687f, 0x0000, 0x2001, 0x12c8, 0x2004, 0x6882, 0x9006, 0x68e2,
-+	0x6802, 0x686a, 0x688a, 0x0126, 0x2091, 0x8000, 0x080c, 0x5b76,
-+	0x012e, 0x00de, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786,
-+	0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110,
-+	0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x2070, 0x70a0, 0x9206,
-+	0x00ee, 0x0005, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007,
-+	0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003,
-+	0x000b, 0x6023, 0x0005, 0x2001, 0x12c1, 0x2004, 0x601a, 0x080c,
-+	0x756e, 0x080c, 0x7aa4, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005,
-+	0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xac39, 0x0030,
-+	0x080c, 0xc381, 0x080c, 0x7384, 0x080c, 0x8ed9, 0x0005, 0x9280,
-+	0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xc1b3, 0xc1b3, 0xc1b3,
-+	0xc1b5, 0xc1b3, 0xc1b5, 0xc1b5, 0xc1b3, 0xc1b5, 0xc1b3, 0xc1b3,
-+	0xc1b3, 0xc1b3, 0xc1b3, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005,
-+	0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xc1cc, 0xc1cc,
-+	0xc1cc, 0xc1cc, 0xc1cc, 0xc1cc, 0xc1d9, 0xc1cc, 0xc1cc, 0xc1cc,
-+	0xc1cc, 0xc1cc, 0xc1cc, 0xc1cc, 0x6007, 0x003b, 0x602f, 0x0009,
-+	0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4,
-+	0x0005, 0x00c6, 0x2260, 0x080c, 0xc381, 0x6043, 0x0000, 0x6024,
-+	0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268,
-+	0x9186, 0x0007, 0x1904, 0xc234, 0x6814, 0x9005, 0x0138, 0x9080,
-+	0x001f, 0x2004, 0xd0fc, 0x1110, 0x00de, 0x08b0, 0x6007, 0x003a,
-+	0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x00c6, 0x2d60,
-+	0x6100, 0x9186, 0x0002, 0x1904, 0xc2b2, 0x6014, 0x9005, 0x1138,
-+	0x6000, 0x9086, 0x0007, 0x190c, 0x0d7e, 0x0804, 0xc2b2, 0x908c,
-+	0xf000, 0x1130, 0x0028, 0x2068, 0x6800, 0x9005, 0x1de0, 0x2d00,
-+	0x9080, 0x001f, 0x2004, 0x9084, 0x0003, 0x9086, 0x0002, 0x1180,
-+	0x6014, 0x2068, 0x687c, 0xc0dc, 0xc0f4, 0x687e, 0x6880, 0xc0f4,
-+	0xc0fc, 0x6882, 0x2009, 0x0043, 0x080c, 0xbb7b, 0x0804, 0xc2b2,
-+	0x2009, 0x0041, 0x0804, 0xc2ac, 0x9186, 0x0005, 0x15b8, 0x6814,
-+	0x9080, 0x001f, 0x2004, 0xd0bc, 0x1118, 0x00de, 0x0804, 0xc1cc,
-+	0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d7e, 0x0804, 0xc1ec, 0x6007,
-+	0x003a, 0x6003, 0x0001, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x00c6,
-+	0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904,
-+	0xc2b2, 0x6814, 0x9080, 0x001f, 0x200c, 0xc1f4, 0xc1dc, 0x2102,
-+	0x8000, 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x00f6, 0x2c78,
-+	0x080c, 0x137e, 0x00fe, 0x2009, 0x0042, 0x04f0, 0x0036, 0x00d6,
-+	0x00d6, 0x080c, 0x0eb6, 0x003e, 0x090c, 0x0d7e, 0x6867, 0x010d,
-+	0x9006, 0x6802, 0x686a, 0x688a, 0x6b8e, 0x6887, 0x0045, 0x2c00,
-+	0x6892, 0x6038, 0x68a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010,
-+	0x9080, 0x0028, 0x2004, 0x9084, 0x00ff, 0x8007, 0x6354, 0x6b7a,
-+	0x6876, 0x9006, 0x687e, 0x6882, 0x6d9a, 0x6e96, 0x689f, 0x0001,
-+	0x080c, 0x5b76, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xbd23,
-+	0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a,
-+	0x6342, 0x00de, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, 0x0007,
-+	0x080c, 0xbb7b, 0x00ce, 0x00de, 0x0005, 0x9186, 0x0013, 0x1128,
-+	0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178,
-+	0x080c, 0x79ab, 0x0036, 0x00d6, 0x6014, 0x2068, 0x2019, 0x0004,
-+	0x080c, 0xc0e9, 0x00de, 0x003e, 0x080c, 0x7aa4, 0x0005, 0x9186,
-+	0x0014, 0x0d70, 0x080c, 0x8f6e, 0x0005, 0xc2e4, 0xc2e2, 0xc2e2,
-+	0xc2e2, 0xc2e2, 0xc2e2, 0xc2e4, 0xc2e2, 0xc2e2, 0xc2e2, 0xc2e2,
-+	0xc2e2, 0xc2e2, 0x080c, 0x0d7e, 0x080c, 0x79ab, 0x6003, 0x000c,
-+	0x080c, 0x7aa4, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085,
-+	0x0208, 0x001a, 0x080c, 0x8f6e, 0x0005, 0xc302, 0xc302, 0xc302,
-+	0xc302, 0xc304, 0xc324, 0xc302, 0xc302, 0xc302, 0xc302, 0xc302,
-+	0xc302, 0xc302, 0x080c, 0x0d7e, 0x00d6, 0x2c68, 0x080c, 0x8e83,
-+	0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c,
-+	0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910,
-+	0x6112, 0x6023, 0x0004, 0x080c, 0x756e, 0x080c, 0x7aa4, 0x2d60,
-+	0x080c, 0x8ed9, 0x00de, 0x0005, 0x080c, 0x8ed9, 0x0005, 0x00e6,
-+	0x6010, 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1172,
-+	0x210c, 0xd1ec, 0x0578, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026,
-+	0xd0cc, 0x0150, 0x2001, 0x12c2, 0x2004, 0x6042, 0x2009, 0x1172,
-+	0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009, 0x1172, 0x210c, 0xd1f4,
-+	0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00a0, 0x2001, 0x12c2,
-+	0x200c, 0x8103, 0x9100, 0x6042, 0x6010, 0x9088, 0x002b, 0x2104,
-+	0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000,
-+	0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0x92f0,
-+	0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x6054,
-+	0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x7384, 0x080c, 0x8ed9,
-+	0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e,
-+	0x0005, 0x00d6, 0x6010, 0x90e8, 0x002b, 0x2d04, 0x9005, 0x0140,
-+	0x9c06, 0x0120, 0x2d04, 0x90e8, 0x0003, 0x0cb8, 0x600c, 0x206a,
-+	0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x112a, 0x2204,
-+	0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x9636, 0x11d8, 0x8318,
-+	0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11a0, 0x2011, 0x0270,
-+	0x20a9, 0x0004, 0x6010, 0x9098, 0x000a, 0x080c, 0x9d60, 0x1150,
-+	0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x9098, 0x0006, 0x080c,
-+	0x9d60, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071,
-+	0x1100, 0x080c, 0x5092, 0x080c, 0x2679, 0x00ee, 0x0005, 0x00e6,
-+	0x6010, 0x2070, 0x7000, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005,
-+	0x6880, 0xc0e5, 0x6882, 0x0005, 0x00e6, 0x00c6, 0x0076, 0x0066,
-+	0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029,
-+	0x130d, 0x252c, 0x2021, 0x1313, 0x2424, 0x2061, 0x15c0, 0x2071,
-+	0x1100, 0x764c, 0x706c, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001,
-+	0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400,
-+	0x9c06, 0x01d0, 0x080c, 0xc15b, 0x01b8, 0x080c, 0xc16b, 0x11a0,
-+	0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1509, 0x001e,
-+	0x080c, 0xab1d, 0x1110, 0x080c, 0x2886, 0x080c, 0xab2e, 0x1110,
-+	0x080c, 0x97dc, 0x080c, 0x8f09, 0x9ce0, 0x0018, 0x2001, 0x1118,
-+	0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e,
-+	0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0006,
-+	0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1140, 0xd5a4, 0x0118,
-+	0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032,
-+	0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148,
-+	0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0x114a,
-+	0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006,
-+	0x00e6, 0x2091, 0x8000, 0x2071, 0x1142, 0x0021, 0x00ee, 0x000e,
-+	0x012e, 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04,
-+	0x8000, 0x2072, 0x0005, 0x00e6, 0x2071, 0x1140, 0x0c99, 0x00ee,
-+	0x0005, 0x00e6, 0x2071, 0x1144, 0x0c69, 0x00ee, 0x0005, 0x0126,
-+	0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1140, 0x7044, 0x8000,
-+	0x7046, 0x00ee, 0x000e, 0x012e, 0x0005, 0x8064, 0x0008, 0x0010,
-+	0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4404, 0x0003, 0x8060,
-+	0x0000, 0x0400, 0x0000, 0x580a, 0x0003, 0x7933, 0x0003, 0x5089,
-+	0x0003, 0x4c07, 0x000b, 0xbac0, 0x0009, 0x0082, 0x0008, 0x0c07,
-+	0x0003, 0x15fe, 0x0008, 0x3407, 0x000b, 0x808c, 0x0008, 0x0001,
-+	0x0000, 0x0000, 0x0007, 0x4047, 0x000a, 0x808c, 0x0008, 0x0002,
-+	0x0000, 0x0819, 0x000b, 0x4022, 0x0000, 0x001a, 0x0003, 0x4122,
-+	0x0008, 0x4447, 0x0002, 0x0de5, 0x000b, 0x0bfe, 0x0008, 0x11a0,
-+	0x0001, 0x11c7, 0x0003, 0x0ca0, 0x0001, 0x11c7, 0x0003, 0x9180,
-+	0x0001, 0x0004, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009,
-+	0x0008, 0x4426, 0x0003, 0x8080, 0x0001, 0x0004, 0x0000, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x0411, 0x0000, 0x442c, 0x0003, 0x808c,
-+	0x0008, 0x0000, 0x0008, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0dc4,
-+	0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0dc4,
-+	0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, 0x0008, 0x8066,
-+	0x0000, 0x0019, 0x0000, 0x443b, 0x0003, 0x0240, 0x0002, 0x09c1,
-+	0x0003, 0x00fe, 0x0000, 0x31c4, 0x000b, 0x112a, 0x0000, 0x002e,
-+	0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x0c07, 0x0003, 0x9780,
-+	0x0001, 0x000f, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0011,
-+	0x0008, 0x444a, 0x0003, 0x808c, 0x0008, 0x0002, 0x0000, 0x01fe,
-+	0x0008, 0x42e0, 0x0009, 0x0db7, 0x0003, 0x00fe, 0x0000, 0x43e0,
-+	0x0001, 0x0db7, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, 0x1632,
-+	0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x445c, 0x000b, 0x808a,
-+	0x0008, 0x0003, 0x0008, 0x9a80, 0x0009, 0x0002, 0x0000, 0x7f62,
-+	0x0008, 0x5862, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4465,
-+	0x000b, 0x5866, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074,
-+	0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x3007, 0x0003, 0x006f,
-+	0x0004, 0x0007, 0x0003, 0x1cfe, 0x0008, 0x1b80, 0x0009, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x0231, 0x0008, 0x4474, 0x000b, 0x5875,
-+	0x000b, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c7f,
-+	0x0003, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a,
-+	0x0008, 0x0083, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548,
-+	0x0008, 0x064a, 0x0000, 0x5883, 0x000b, 0x8054, 0x0008, 0x0001,
-+	0x0000, 0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40,
-+	0x000a, 0x0c0a, 0x000b, 0x2b24, 0x0008, 0x2b24, 0x0008, 0x588d,
-+	0x0003, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08d7,
-+	0x0003, 0x3a45, 0x000a, 0x08c8, 0x000b, 0x1e10, 0x000a, 0x7f3c,
-+	0x0000, 0x08c5, 0x0003, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60,
-+	0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x449d,
-+	0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x00fe, 0x0000, 0x34c2,
-+	0x000b, 0x1cfe, 0x0008, 0xff80, 0x0009, 0x0001, 0x0000, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44a8, 0x0003, 0x00fe,
-+	0x0000, 0x31a0, 0x0003, 0x0038, 0x0000, 0x00fe, 0x0000, 0xff80,
-+	0x0009, 0x0019, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009,
-+	0x0008, 0x44b2, 0x000b, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e,
-+	0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44bc, 0x0003, 0x8060,
-+	0x0000, 0x0400, 0x0000, 0x003a, 0x0008, 0x1dfe, 0x0000, 0x0099,
-+	0x000b, 0x0036, 0x0008, 0x006f, 0x0004, 0x00d7, 0x000b, 0x8074,
-+	0x0000, 0x2000, 0x0000, 0x00d7, 0x000b, 0x3a44, 0x0002, 0x09ca,
-+	0x000b, 0x8074, 0x0000, 0x1000, 0x0000, 0x2d0e, 0x0000, 0x2d0e,
-+	0x0000, 0x35a0, 0x000b, 0x26fe, 0x0008, 0x26fe, 0x0008, 0x2700,
-+	0x0008, 0x2700, 0x0008, 0x00d0, 0x0009, 0x0ce5, 0x0003, 0x8074,
-+	0x0000, 0x4040, 0x0008, 0x58d7, 0x0003, 0x5089, 0x0003, 0x3a46,
-+	0x000a, 0x0ce5, 0x0003, 0x3a47, 0x0002, 0x08e2, 0x0003, 0x8054,
-+	0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0126,
-+	0x000b, 0x92c0, 0x0009, 0x0f88, 0x0008, 0x0807, 0x000b, 0x9a80,
-+	0x0009, 0x0002, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x362a,
-+	0x0000, 0x44ea, 0x0003, 0x2000, 0x0000, 0x2000, 0x0000, 0x2102,
-+	0x0000, 0x2102, 0x0000, 0x2204, 0x0000, 0x2204, 0x0000, 0x2306,
-+	0x0000, 0x2306, 0x0000, 0x2408, 0x0000, 0x2408, 0x0000, 0x250a,
-+	0x0000, 0x250a, 0x0000, 0x260c, 0x0000, 0x260c, 0x0000, 0x270e,
-+	0x0000, 0x270e, 0x0000, 0x2810, 0x0000, 0x2810, 0x0000, 0x2912,
-+	0x0000, 0x2912, 0x0000, 0x9a80, 0x0009, 0x0007, 0x0000, 0x7f62,
-+	0x0008, 0x8066, 0x0000, 0x0052, 0x0000, 0x4504, 0x000b, 0x92c0,
-+	0x0009, 0x0780, 0x0008, 0x0db1, 0x0003, 0x124b, 0x0002, 0x090d,
-+	0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x09a0, 0x000b, 0x3a46,
-+	0x000a, 0x0d1a, 0x000b, 0x590f, 0x000b, 0x8054, 0x0008, 0x0004,
-+	0x0000, 0x1243, 0x000a, 0x0924, 0x000b, 0x8010, 0x0008, 0x000d,
-+	0x0000, 0x0191, 0x0004, 0x1810, 0x0000, 0x0191, 0x0004, 0x0124,
-+	0x0003, 0x194d, 0x000a, 0x091e, 0x000b, 0x1243, 0x000a, 0x09a7,
-+	0x0003, 0x591e, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000, 0x0188,
-+	0x000c, 0x1810, 0x0000, 0x0191, 0x0004, 0x8074, 0x0000, 0xf000,
-+	0x0008, 0x3a42, 0x0002, 0x0d2c, 0x000b, 0x15fe, 0x0008, 0x3445,
-+	0x000b, 0x0d30, 0x0000, 0x0007, 0x0003, 0x0d30, 0x0000, 0x8074,
-+	0x0000, 0x0501, 0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0191,
-+	0x0004, 0x0007, 0x0003, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d43,
-+	0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0940, 0x0003, 0x15fe,
-+	0x0008, 0x3ce0, 0x0009, 0x0940, 0x0003, 0x0183, 0x0004, 0x8076,
-+	0x0008, 0x0040, 0x0000, 0x0180, 0x000b, 0x8076, 0x0008, 0x0041,
-+	0x0008, 0x0180, 0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d48,
-+	0x0003, 0x3c1e, 0x0008, 0x0180, 0x000b, 0xbbe0, 0x0009, 0x0037,
-+	0x0000, 0x0d65, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d40,
-+	0x000b, 0x1afe, 0x0008, 0xff80, 0x0009, 0x000d, 0x0000, 0x7f62,
-+	0x0008, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008, 0x2706,
-+	0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000, 0x290a,
-+	0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x455c, 0x0003, 0x0188,
-+	0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000,
-+	0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0126, 0x000b, 0xbbe0,
-+	0x0009, 0x0038, 0x0000, 0x0d77, 0x0003, 0x18fe, 0x0000, 0x3ce0,
-+	0x0009, 0x0974, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0d3c,
-+	0x0003, 0x0183, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072,
-+	0x0000, 0x8000, 0x0000, 0x01c1, 0x000b, 0x8076, 0x0008, 0x0042,
-+	0x0008, 0x0180, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x0d80,
-+	0x000b, 0x3a44, 0x0002, 0x0c09, 0x000b, 0x8072, 0x0000, 0x8000,
-+	0x0000, 0x8000, 0x000f, 0x0007, 0x0003, 0x8072, 0x0000, 0x8000,
-+	0x0000, 0x0007, 0x0003, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80,
-+	0x0001, 0x0007, 0x0000, 0x018c, 0x000b, 0x1930, 0x000a, 0x7f00,
-+	0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x7f62, 0x0008, 0x8066,
-+	0x0000, 0x000a, 0x0008, 0x458f, 0x000b, 0x4000, 0x000f, 0x2191,
-+	0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0, 0x0009, 0x0090,
-+	0x0008, 0x099a, 0x000b, 0x8074, 0x0000, 0x0706, 0x0000, 0x019c,
-+	0x0003, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000, 0x000f, 0x8010,
-+	0x0008, 0x0008, 0x0000, 0x01cf, 0x0003, 0x0188, 0x000c, 0x8010,
-+	0x0008, 0x0007, 0x0000, 0x0191, 0x0004, 0x1810, 0x0000, 0x0191,
-+	0x0004, 0x01d9, 0x000b, 0x0188, 0x000c, 0x8010, 0x0008, 0x001b,
-+	0x0008, 0x0191, 0x0004, 0x1810, 0x0000, 0x0191, 0x0004, 0x8074,
-+	0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x0007, 0x0003, 0x8010,
-+	0x0008, 0x0009, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0005,
-+	0x0008, 0x01cf, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010,
-+	0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x0853, 0x0003, 0x3a44,
-+	0x0002, 0x0c07, 0x0003, 0x0d2a, 0x0008, 0x01cf, 0x0003, 0x8010,
-+	0x0008, 0x0003, 0x0008, 0x01d1, 0x0003, 0x8010, 0x0008, 0x000b,
-+	0x0000, 0x01d1, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01d1,
-+	0x0003, 0x3a47, 0x0002, 0x0cd7, 0x000b, 0x8010, 0x0008, 0x0006,
-+	0x0008, 0x01d1, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0191,
-+	0x0004, 0x0194, 0x0004, 0x3a40, 0x000a, 0x0807, 0x000b, 0x8010,
-+	0x0008, 0x000c, 0x0008, 0x0191, 0x0004, 0x0007, 0x0003, 0x8074,
-+	0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d,
-+	0x0002, 0x09e2, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000, 0x0007,
-+	0x0003, 0x8054, 0x0008, 0x0009, 0x0008, 0x0007, 0x0003, 0x3a44,
-+	0x0002, 0x0c07, 0x0003, 0x01c4, 0x000b, 0xde59, 0xf666, 0x0001,
-+	0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
-+	0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0xfe91
-+};
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp.c	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,6714 @@
-+/* @(#)isp.c 1.86 */
-+/*
-+ * Machine and OS Independent (well, as best as possible)
-+ * code for the Qlogic ISP SCSI adapters.
-+ *
-+ * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
-+ * Feral Software
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Inspiration and ideas about this driver are from Erik Moe's Linux driver
-+ * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
-+ * ideas dredged from the Solaris driver.
-+ */
-+
-+/*
-+ * Include header file appropriate for platform we're building on.
-+ */
-+
-+#ifdef	__NetBSD__
-+#include <dev/ic/isp_netbsd.h>
-+#endif
-+#ifdef	__FreeBSD__
-+#include <dev/isp/isp_freebsd.h>
-+#endif
-+#ifdef	__OpenBSD__
-+#include <dev/ic/isp_openbsd.h>
-+#endif
-+#ifdef	__linux__
-+#include "isp_linux.h"
-+#endif
-+#ifdef	__svr4__
-+#include "isp_solaris.h"
-+#endif
-+
-+/*
-+ * General defines
-+ */
-+
-+#define	MBOX_DELAY_COUNT	1000000 / 100
-+
-+/*
-+ * Local static data
-+ */
-+static const char portshift[] =
-+    "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
-+static const char portdup[] =
-+    "Target %d duplicates Target %d- killing off both";
-+static const char retained[] =
-+    "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
-+static const char lretained[] =
-+    "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
-+static const char plogout[] =
-+    "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
-+static const char plogierr[] =
-+    "Command Error in PLOGI for Port 0x%x (0x%x)";
-+static const char nopdb[] =
-+    "Could not get PDB for Device @ Port 0x%x";
-+static const char pdbmfail1[] =
-+    "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
-+static const char pdbmfail2[] =
-+    "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
-+static const char ldumped[] =
-+    "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
-+static const char notresp[] =
-+  "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
-+static const char xact1[] =
-+    "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
-+static const char xact2[] =
-+    "HBA attempted queued transaction to target routine %d on target %d bus %d";
-+static const char xact3[] =
-+    "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
-+static const char pskip[] =
-+    "SCSI phase skipped for target %d.%d.%d";
-+static const char topology[] =
-+    "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
-+static const char swrej[] =
-+    "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
-+static const char finmsg[] =
-+    "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
-+static const char sc0[] =
-+    "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
-+static const char sc1[] =
-+    "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
-+static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
-+static const char sc3[] = "Generated";
-+static const char sc4[] = "NVRAM";
-+static const char bun[] =
-+    "bad underrun for %d.%d (count %d, resid %d, status %s)";
-+
-+/*
-+ * Local function prototypes.
-+ */
-+static int isp_parse_async(struct ispsoftc *, u_int16_t);
-+static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
-+    u_int16_t *);
-+static void
-+isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
-+static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
-+static int isp_mbox_continue(struct ispsoftc *);
-+static void isp_scsi_init(struct ispsoftc *);
-+static void isp_scsi_channel_init(struct ispsoftc *, int);
-+static void isp_fibre_init(struct ispsoftc *);
-+static void isp_mark_getpdb_all(struct ispsoftc *);
-+static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
-+static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
-+static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
-+static int isp_fclink_test(struct ispsoftc *, int);
-+static char *isp2100_fw_statename(int);
-+static int isp_pdb_sync(struct ispsoftc *);
-+static int isp_scan_loop(struct ispsoftc *);
-+static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
-+static int isp_scan_fabric(struct ispsoftc *, int);
-+static void isp_register_fc4_type(struct ispsoftc *);
-+static void isp_fw_state(struct ispsoftc *);
-+static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
-+static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
-+
-+static void isp_update(struct ispsoftc *);
-+static void isp_update_bus(struct ispsoftc *, int);
-+static void isp_setdfltparm(struct ispsoftc *, int);
-+static int isp_read_nvram(struct ispsoftc *);
-+static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
-+static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
-+static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
-+static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
-+static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
-+
-+/*
-+ * Reset Hardware.
-+ *
-+ * Hit the chip over the head, download new f/w if available and set it running.
-+ *
-+ * Locking done elsewhere.
-+ */
-+
-+void
-+isp_reset(struct ispsoftc *isp)
-+{
-+	mbreg_t mbs;
-+	u_int16_t code_org;
-+	int loops, i, dodnld = 1;
-+	char *btype = "????";
-+
-+	isp->isp_state = ISP_NILSTATE;
-+
-+	/*
-+	 * Basic types (SCSI, FibreChannel and PCI or SBus)
-+	 * have been set in the MD code. We figure out more
-+	 * here. Possibly more refined types based upon PCI
-+	 * identification. Chip revision has been gathered.
-+	 *
-+	 * After we've fired this chip up, zero out the conf1 register
-+	 * for SCSI adapters and do other settings for the 2100.
-+	 */
-+
-+	/*
-+	 * Get the current running firmware revision out of the
-+	 * chip before we hit it over the head (if this is our
-+	 * first time through). Note that we store this as the
-+	 * 'ROM' firmware revision- which it may not be. In any
-+	 * case, we don't really use this yet, but we may in
-+	 * the future.
-+	 */
-+	if (isp->isp_touched == 0) {
-+		/*
-+		 * First see whether or not we're sitting in the ISP PROM.
-+		 * If we've just been reset, we'll have the string "ISP   "
-+		 * spread through outgoing mailbox registers 1-3. We do
-+		 * this for PCI cards because otherwise we really don't
-+		 * know what state the card is in and we could hang if
-+		 * we try this command otherwise.
-+		 *
-+		 * For SBus cards, we just do this because they almost
-+		 * certainly will be running firmware by now.
-+		 */
-+		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
-+		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
-+		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
-+			/*
-+			 * Just in case it was paused...
-+			 */
-+			ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
-+			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
-+			isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+				isp->isp_romfw_rev[0] = mbs.param[1];
-+				isp->isp_romfw_rev[1] = mbs.param[2];
-+				isp->isp_romfw_rev[2] = mbs.param[3];
-+			}
-+		}
-+		isp->isp_touched = 1;
-+	}
-+
-+	DISABLE_INTS(isp);
-+
-+	/*
-+	 * Set up default request/response queue in-pointer/out-pointer
-+	 * register indices.
-+	 */
-+	if (IS_23XX(isp)) {
-+		isp->isp_rqstinrp = BIU_REQINP;
-+		isp->isp_rqstoutrp = BIU_REQOUTP;
-+		isp->isp_respinrp = BIU_RSPINP;
-+		isp->isp_respoutrp = BIU_RSPOUTP;
-+	} else {
-+		isp->isp_rqstinrp = INMAILBOX4;
-+		isp->isp_rqstoutrp = OUTMAILBOX4;
-+		isp->isp_respinrp = OUTMAILBOX5;
-+		isp->isp_respoutrp = INMAILBOX5;
-+	}
-+
-+	/*
-+	 * Put the board into PAUSE mode (so we can read the SXP registers
-+	 * or write FPM/FBM registers).
-+	 */
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+
-+	if (IS_FC(isp)) {
-+		switch (isp->isp_type) {
-+		case ISP_HA_FC_2100:
-+			btype = "2100";
-+			break;
-+		case ISP_HA_FC_2200:
-+			btype = "2200";
-+			break;
-+		case ISP_HA_FC_2300:
-+			btype = "2300";
-+			break;
-+		case ISP_HA_FC_2312:
-+			btype = "2312";
-+			break;
-+		default:
-+			break;
-+		}
-+		/*
-+		 * While we're paused, reset the FPM module and FBM fifos.
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
-+		ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
-+		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
-+		ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
-+		ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
-+	} else if (IS_1240(isp)) {
-+		sdparam *sdp = isp->isp_param;
-+		btype = "1240";
-+		isp->isp_clock = 60;
-+		sdp->isp_ultramode = 1;
-+		sdp++;
-+		sdp->isp_ultramode = 1;
-+		/*
-+		 * XXX: Should probably do some bus sensing.
-+		 */
-+	} else if (IS_ULTRA2(isp)) {
-+		static const char m[] = "bus %d is in %s Mode";
-+		u_int16_t l;
-+		sdparam *sdp = isp->isp_param;
-+
-+		isp->isp_clock = 100;
-+
-+		if (IS_1280(isp))
-+			btype = "1280";
-+		else if (IS_1080(isp))
-+			btype = "1080";
-+		else if (IS_10160(isp))
-+			btype = "10160";
-+		else if (IS_12160(isp))
-+			btype = "12160";
-+		else
-+			btype = "<UNKLVD>";
-+
-+		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
-+		switch (l) {
-+		case ISP1080_LVD_MODE:
-+			sdp->isp_lvdmode = 1;
-+			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
-+			break;
-+		case ISP1080_HVD_MODE:
-+			sdp->isp_diffmode = 1;
-+			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
-+			break;
-+		case ISP1080_SE_MODE:
-+			sdp->isp_ultramode = 1;
-+			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
-+			break;
-+		default:
-+			isp_prt(isp, ISP_LOGERR,
-+			    "unknown mode on bus %d (0x%x)", 0, l);
-+			break;
-+		}
-+
-+		if (IS_DUALBUS(isp)) {
-+			sdp++;
-+			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
-+			l &= ISP1080_MODE_MASK;
-+			switch(l) {
-+			case ISP1080_LVD_MODE:
-+				sdp->isp_lvdmode = 1;
-+				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
-+				break;
-+			case ISP1080_HVD_MODE:
-+				sdp->isp_diffmode = 1;
-+				isp_prt(isp, ISP_LOGCONFIG,
-+				    m, 1, "Differential");
-+				break;
-+			case ISP1080_SE_MODE:
-+				sdp->isp_ultramode = 1;
-+				isp_prt(isp, ISP_LOGCONFIG,
-+				    m, 1, "Single-Ended");
-+				break;
-+			default:
-+				isp_prt(isp, ISP_LOGERR,
-+				    "unknown mode on bus %d (0x%x)", 1, l);
-+				break;
-+			}
-+		}
-+	} else {
-+		sdparam *sdp = isp->isp_param;
-+		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
-+		switch (i) {
-+		default:
-+			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
-+			/* FALLTHROUGH */
-+		case 1:
-+			btype = "1020";
-+			isp->isp_type = ISP_HA_SCSI_1020;
-+			isp->isp_clock = 40;
-+			break;
-+		case 2:
-+			/*
-+			 * Some 1020A chips are Ultra Capable, but don't
-+			 * run the clock rate up for that unless told to
-+			 * do so by the Ultra Capable bits being set.
-+			 */
-+			btype = "1020A";
-+			isp->isp_type = ISP_HA_SCSI_1020A;
-+			isp->isp_clock = 40;
-+			break;
-+		case 3:
-+			btype = "1040";
-+			isp->isp_type = ISP_HA_SCSI_1040;
-+			isp->isp_clock = 60;
-+			break;
-+		case 4:
-+			btype = "1040A";
-+			isp->isp_type = ISP_HA_SCSI_1040A;
-+			isp->isp_clock = 60;
-+			break;
-+		case 5:
-+			btype = "1040B";
-+			isp->isp_type = ISP_HA_SCSI_1040B;
-+			isp->isp_clock = 60;
-+			break;
-+		case 6:
-+			btype = "1040C";
-+			isp->isp_type = ISP_HA_SCSI_1040C;
-+			isp->isp_clock = 60;
-+                        break;
-+		}
-+		/*
-+		 * Now, while we're at it, gather info about ultra
-+		 * and/or differential mode.
-+		 */
-+		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
-+			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
-+			sdp->isp_diffmode = 1;
-+		} else {
-+			sdp->isp_diffmode = 0;
-+		}
-+		i = ISP_READ(isp, RISC_PSR);
-+		if (isp->isp_bustype == ISP_BT_SBUS) {
-+			i &= RISC_PSR_SBUS_ULTRA;
-+		} else {
-+			i &= RISC_PSR_PCI_ULTRA;
-+		}
-+		if (i != 0) {
-+			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
-+			sdp->isp_ultramode = 1;
-+			/*
-+			 * If we're in Ultra Mode, we have to be 60MHz clock-
-+			 * even for the SBus version.
-+			 */
-+			isp->isp_clock = 60;
-+		} else {
-+			sdp->isp_ultramode = 0;
-+			/*
-+			 * Clock is known. Gronk.
-+			 */
-+		}
-+
-+		/*
-+		 * Machine dependent clock (if set) overrides
-+		 * our generic determinations.
-+		 */
-+		if (isp->isp_mdvec->dv_clock) {
-+			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
-+				isp->isp_clock = isp->isp_mdvec->dv_clock;
-+			}
-+		}
-+
-+	}
-+
-+	/*
-+	 * Clear instrumentation
-+	 */
-+	isp->isp_intcnt = isp->isp_intbogus = 0;
-+
-+	/*
-+	 * Do MD specific pre initialization
-+	 */
-+	ISP_RESET0(isp);
-+
-+again:
-+
-+	/*
-+	 * Hit the chip over the head with hammer,
-+	 * and give the ISP a chance to recover.
-+	 */
-+
-+	if (IS_SCSI(isp)) {
-+		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
-+		/*
-+		 * A slight delay...
-+		 */
-+		USEC_DELAY(100);
-+
-+		/*
-+		 * Clear data && control DMA engines.
-+		 */
-+		ISP_WRITE(isp, CDMA_CONTROL,
-+		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
-+		ISP_WRITE(isp, DDMA_CONTROL,
-+		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
-+
-+
-+	} else {
-+		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
-+		/*
-+		 * A slight delay...
-+		 */
-+		USEC_DELAY(100);
-+
-+		/*
-+		 * Clear data && control DMA engines.
-+		 */
-+		ISP_WRITE(isp, CDMA2100_CONTROL,
-+			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
-+		ISP_WRITE(isp, TDMA2100_CONTROL,
-+			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
-+		ISP_WRITE(isp, RDMA2100_CONTROL,
-+			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
-+	}
-+
-+	/*
-+	 * Wait for ISP to be ready to go...
-+	 */
-+	loops = MBOX_DELAY_COUNT;
-+	for (;;) {
-+		if (IS_SCSI(isp)) {
-+			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
-+				break;
-+		} else {
-+			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
-+				break;
-+		}
-+		USEC_DELAY(100);
-+		if (--loops < 0) {
-+			ISP_DUMPREGS(isp, "chip reset timed out");
-+			return;
-+		}
-+	}
-+
-+	/*
-+	 * After we've fired this chip up, zero out the conf1 register
-+	 * for SCSI adapters and other settings for the 2100.
-+	 */
-+
-+	if (IS_SCSI(isp)) {
-+		ISP_WRITE(isp, BIU_CONF1, 0);
-+	} else {
-+		ISP_WRITE(isp, BIU2100_CSR, 0);
-+	}
-+
-+	/*
-+	 * Reset RISC Processor
-+	 */
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
-+	USEC_DELAY(100);
-+	/* Clear semaphore register (just to be sure) */
-+	ISP_WRITE(isp, BIU_SEMA, 0);
-+
-+	/*
-+	 * Establish some initial burst rate stuff.
-+	 * (only for the 1XX0 boards). This really should
-+	 * be done later after fetching from NVRAM.
-+	 */
-+	if (IS_SCSI(isp)) {
-+		u_int16_t tmp = isp->isp_mdvec->dv_conf1;
-+		/*
-+		 * Busted FIFO. Turn off all but burst enables.
-+		 */
-+		if (isp->isp_type == ISP_HA_SCSI_1040A) {
-+			tmp &= BIU_BURST_ENABLE;
-+		}
-+		ISP_SETBITS(isp, BIU_CONF1, tmp);
-+		if (tmp & BIU_BURST_ENABLE) {
-+			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
-+			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
-+		}
-+#ifdef	PTI_CARDS
-+		if (((sdparam *) isp->isp_param)->isp_ultramode) {
-+			while (ISP_READ(isp, RISC_MTR) != 0x1313) {
-+				ISP_WRITE(isp, RISC_MTR, 0x1313);
-+				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
-+			}
-+		} else {
-+			ISP_WRITE(isp, RISC_MTR, 0x1212);
-+		}
-+		/*
-+		 * PTI specific register
-+		 */
-+		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
-+#else
-+		ISP_WRITE(isp, RISC_MTR, 0x1212);
-+#endif
-+	} else {
-+		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
-+		if (IS_2200(isp) || IS_23XX(isp)) {
-+			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
-+		}
-+	}
-+
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
-+
-+	/*
-+	 * Do MD specific post initialization
-+	 */
-+	ISP_RESET1(isp);
-+
-+	/*
-+	 * Wait for everything to finish firing up.
-+	 *
-+	 * Avoid doing this on the 2312 because you can generate a PCI
-+	 * parity error (chip breakage).
-+	 */
-+	if (IS_23XX(isp)) {
-+		USEC_DELAY(5);
-+	} else {
-+		loops = MBOX_DELAY_COUNT;
-+		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
-+			USEC_DELAY(100);
-+			if (--loops < 0) {
-+				isp_prt(isp, ISP_LOGERR,
-+				    "MBOX_BUSY never cleared on reset");
-+				return;
-+			}
-+		}
-+	}
-+
-+	/*
-+	 * Up until this point we've done everything by just reading or
-+	 * setting registers. From this point on we rely on at least *some*
-+	 * kind of firmware running in the card.
-+	 */
-+
-+	/*
-+	 * Do some sanity checking.
-+	 */
-+	mbs.param[0] = MBOX_NO_OP;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+
-+	if (IS_SCSI(isp)) {
-+		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
-+		mbs.param[1] = 0xdead;
-+		mbs.param[2] = 0xbeef;
-+		mbs.param[3] = 0xffff;
-+		mbs.param[4] = 0x1111;
-+		mbs.param[5] = 0xa5a5;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			return;
-+		}
-+		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
-+		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
-+		    mbs.param[5] != 0xa5a5) {
-+			isp_prt(isp, ISP_LOGERR,
-+			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
-+			    mbs.param[1], mbs.param[2], mbs.param[3],
-+			    mbs.param[4], mbs.param[5]);
-+			return;
-+		}
-+
-+	}
-+
-+	/*
-+	 * Download new Firmware, unless requested not to do so.
-+	 * This is made slightly trickier in some cases where the
-+	 * firmware of the ROM revision is newer than the revision
-+	 * compiled into the driver. So, where we used to compare
-+	 * versions of our f/w and the ROM f/w, now we just see
-+	 * whether we have f/w at all and whether a config flag
-+	 * has disabled our download.
-+	 */
-+	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
-+	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
-+		dodnld = 0;
-+	}
-+
-+	if (IS_23XX(isp))
-+		code_org = ISP_CODE_ORG_2300;
-+	else
-+		code_org = ISP_CODE_ORG;
-+
-+	if (dodnld) {
-+		isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
-+		isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
-+		isp->isp_mbxwrk1 = code_org + 1;
-+		mbs.param[0] = MBOX_WRITE_RAM_WORD;
-+		mbs.param[1] = code_org;
-+		mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
-+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			isp_prt(isp, ISP_LOGERR,
-+			    "F/W download failed at word %d",
-+			    isp->isp_mbxwrk1 - code_org);
-+			dodnld = 0;
-+			goto again;
-+		}
-+		/*
-+		 * Verify that it downloaded correctly.
-+		 */
-+		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
-+		mbs.param[1] = code_org;
-+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
-+			return;
-+		}
-+		isp->isp_loaded_fw = 1;
-+	} else {
-+		isp->isp_loaded_fw = 0;
-+		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
-+	}
-+
-+	/*
-+	 * Now start it rolling.
-+	 *
-+	 * If we didn't actually download f/w,
-+	 * we still need to (re)start it.
-+	 */
-+
-+
-+	mbs.param[0] = MBOX_EXEC_FIRMWARE;
-+	mbs.param[1] = code_org;
-+	isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+	/*
-+	 * Give it a chance to start.
-+	 */
-+	USEC_DELAY(500);
-+
-+	if (IS_SCSI(isp)) {
-+		/*
-+		 * Set CLOCK RATE, but only if asked to.
-+		 */
-+		if (isp->isp_clock) {
-+			mbs.param[0] = MBOX_SET_CLOCK_RATE;
-+			mbs.param[1] = isp->isp_clock;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL);
-+			/* we will try not to care if this fails */
-+		}
-+	}
-+
-+	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+
-+	/*
-+	 * The SBus firmware that we are using apparently does not return
-+	 * major, minor, micro revisions in the mailbox registers, which
-+	 * is really, really, annoying.
-+	 */
-+	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
-+		if (dodnld) {
-+#ifdef	ISP_TARGET_MODE
-+			isp->isp_fwrev[0] = 7;
-+			isp->isp_fwrev[1] = 55;
-+#else
-+			isp->isp_fwrev[0] = 1;
-+			isp->isp_fwrev[1] = 37;
-+#endif
-+			isp->isp_fwrev[2] = 0;
-+		} 
-+	} else {
-+		isp->isp_fwrev[0] = mbs.param[1];
-+		isp->isp_fwrev[1] = mbs.param[2];
-+		isp->isp_fwrev[2] = mbs.param[3];
-+	}
-+	isp_prt(isp, ISP_LOGCONFIG,
-+	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
-+	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
-+	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
-+
-+	if (IS_FC(isp)) {
-+		/*
-+		 * We do not believe firmware attributes for 2100 code less
-+		 * than 1.17.0, unless it's the firmware we specifically
-+		 * are loading.
-+		 *
-+		 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
-+		 */
-+		if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
-+#ifdef	USE_SMALLER_2100_FIRMWARE
-+			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
-+#else
-+			FCPARAM(isp)->isp_fwattr = 0;
-+#endif
-+		} else {
-+			FCPARAM(isp)->isp_fwattr = mbs.param[6];
-+			isp_prt(isp, ISP_LOGDEBUG0,
-+			    "Firmware Attributes = 0x%x", mbs.param[6]);
-+		}
-+		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
-+			isp_prt(isp, ISP_LOGCONFIG,
-+			    "Installed in 64-Bit PCI slot");
-+		}
-+	}
-+
-+	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
-+	    isp->isp_romfw_rev[2]) {
-+		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
-+		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
-+		    isp->isp_romfw_rev[2]);
-+	}
-+
-+	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+	isp->isp_maxcmds = mbs.param[2];
-+	isp_prt(isp, ISP_LOGINFO,
-+	    "%d max I/O commands supported", mbs.param[2]);
-+	isp_fw_state(isp);
-+
-+	/*
-+	 * Set up DMA for the request and result mailboxes.
-+	 */
-+	if (ISP_MBOXDMASETUP(isp) != 0) {
-+		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
-+		return;
-+	}
-+	isp->isp_state = ISP_RESETSTATE;
-+
-+	/*
-+	 * Okay- now that we have new firmware running, we now (re)set our
-+	 * notion of how many luns we support. This is somewhat tricky because
-+	 * if we haven't loaded firmware, we sometimes do not have an easy way
-+	 * of knowing how many luns we support.
-+	 *
-+	 * Expanded lun firmware gives you 32 luns for SCSI cards and
-+	 * 16384 luns for Fibre Channel cards.
-+	 *
-+	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
-+	 * we do get a firmware attributes word returned in mailbox register 6.
-+	 *
-+	 * Because the lun is in a different position in the Request Queue
-+	 * Entry structure for Fibre Channel with expanded lun firmware, we
-+	 * can only support one lun (lun zero) when we don't know what kind
-+	 * of firmware we're running.
-+	 */
-+	if (IS_SCSI(isp)) {
-+		if (dodnld) {
-+			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
-+				isp->isp_maxluns = 32;
-+			} else {
-+				isp->isp_maxluns = 8;
-+			}
-+		} else {
-+			isp->isp_maxluns = 8;
-+		}
-+	} else {
-+		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
-+			isp->isp_maxluns = 16384;
-+		} else {
-+			isp->isp_maxluns = 16;
-+		}
-+	}
-+}
-+
-+/*
-+ * Initialize Parameters of Hardware to a known state.
-+ *
-+ * Locks are held before coming here.
-+ */
-+
-+void
-+isp_init(struct ispsoftc *isp)
-+{
-+	/*
-+	 * Must do this first to get defaults established.
-+	 */
-+	isp_setdfltparm(isp, 0);
-+	if (IS_DUALBUS(isp)) {
-+		isp_setdfltparm(isp, 1);
-+	}
-+	if (IS_FC(isp)) {
-+		isp_fibre_init(isp);
-+	} else {
-+		isp_scsi_init(isp);
-+	}
-+}
-+
-+static void
-+isp_scsi_init(struct ispsoftc *isp)
-+{
-+	sdparam *sdp_chan0, *sdp_chan1;
-+	mbreg_t mbs;
-+
-+	sdp_chan0 = isp->isp_param;
-+	sdp_chan1 = sdp_chan0;
-+	if (IS_DUALBUS(isp)) {
-+		sdp_chan1++;
-+	}
-+
-+	/*
-+	 * If we have no role (neither target nor initiator), return.
-+	 */
-+	if (isp->isp_role == ISP_ROLE_NONE) {
-+		return;
-+	}
-+
-+	/* First do overall per-card settings. */
-+
-+	/*
-+	 * If we have fast memory timing enabled, turn it on.
-+	 */
-+	if (sdp_chan0->isp_fast_mttr) {
-+		ISP_WRITE(isp, RISC_MTR, 0x1313);
-+	}
-+
-+	/*
-+	 * Set Retry Delay and Count.
-+	 * You set both channels at the same time.
-+	 */
-+	mbs.param[0] = MBOX_SET_RETRY_COUNT;
-+	mbs.param[1] = sdp_chan0->isp_retry_count;
-+	mbs.param[2] = sdp_chan0->isp_retry_delay;
-+	mbs.param[6] = sdp_chan1->isp_retry_count;
-+	mbs.param[7] = sdp_chan1->isp_retry_delay;
-+
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+
-+	/*
-+	 * Set ASYNC DATA SETUP time. This is very important.
-+	 */
-+	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
-+	mbs.param[1] = sdp_chan0->isp_async_data_setup;
-+	mbs.param[2] = sdp_chan1->isp_async_data_setup;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+
-+	/*
-+	 * Set ACTIVE Negation State.
-+	 */
-+	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
-+	mbs.param[1] =
-+	    (sdp_chan0->isp_req_ack_active_neg << 4) |
-+	    (sdp_chan0->isp_data_line_active_neg << 5);
-+	mbs.param[2] =
-+	    (sdp_chan1->isp_req_ack_active_neg << 4) |
-+	    (sdp_chan1->isp_data_line_active_neg << 5);
-+
-+	isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "failed to set active negation state (%d,%d), (%d,%d)",
-+		    sdp_chan0->isp_req_ack_active_neg,
-+		    sdp_chan0->isp_data_line_active_neg,
-+		    sdp_chan1->isp_req_ack_active_neg,
-+		    sdp_chan1->isp_data_line_active_neg);
-+		/*
-+		 * But don't return.
-+		 */
-+	}
-+
-+	/*
-+	 * Set the Tag Aging limit
-+	 */
-+	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
-+	mbs.param[1] = sdp_chan0->isp_tag_aging;
-+	mbs.param[2] = sdp_chan1->isp_tag_aging;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
-+		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
-+		return;
-+	}
-+
-+	/*
-+	 * Set selection timeout.
-+	 */
-+	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
-+	mbs.param[1] = sdp_chan0->isp_selection_timeout;
-+	mbs.param[2] = sdp_chan1->isp_selection_timeout;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+
-+	/* now do per-channel settings */
-+	isp_scsi_channel_init(isp, 0);
-+	if (IS_DUALBUS(isp))
-+		isp_scsi_channel_init(isp, 1);
-+
-+	/*
-+	 * Now enable request/response queues
-+	 */
-+
-+	if (IS_ULTRA2(isp) || IS_1240(isp)) {
-+		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
-+		mbs.param[1] = RESULT_QUEUE_LEN(isp);
-+		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
-+		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
-+		mbs.param[4] = 0;
-+		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
-+		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			return;
-+		}
-+		isp->isp_residx = mbs.param[5];
-+
-+		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
-+		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
-+		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
-+		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
-+		mbs.param[5] = 0;
-+		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
-+		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			return;
-+		}
-+		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
-+	} else {
-+		mbs.param[0] = MBOX_INIT_RES_QUEUE;
-+		mbs.param[1] = RESULT_QUEUE_LEN(isp);
-+		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
-+		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
-+		mbs.param[4] = 0;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			return;
-+		}
-+		isp->isp_residx = mbs.param[5];
-+
-+		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
-+		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
-+		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
-+		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
-+		mbs.param[5] = 0;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			return;
-+		}
-+		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
-+	}
-+
-+	/*
-+	 * Turn on Fast Posting, LVD transitions
-+	 *
-+	 * Ultra2 F/W always has had fast posting (and LVD transitions)
-+	 *
-+	 * Ultra and older (i.e., SBus) cards may not. It's just safer
-+	 * to assume not for them.
-+	 */
-+
-+	mbs.param[0] = MBOX_SET_FW_FEATURES;
-+	mbs.param[1] = 0;
-+	if (IS_ULTRA2(isp))
-+		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
-+#ifndef	ISP_NO_RIO
-+	if (IS_ULTRA2(isp) || IS_1240(isp))
-+		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
-+#else
-+#ifndef	ISP_NO_FASTPOST
-+	if (IS_ULTRA2(isp) || IS_1240(isp))
-+		mbs.param[1] |= FW_FEATURE_FAST_POST;
-+#endif
-+#endif
-+	if (mbs.param[1] != 0) {
-+		u_int16_t sfeat = mbs.param[1];
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "Enabled FW features (0x%x)", sfeat);
-+		}
-+	}
-+
-+	/*
-+	 * Let the outer layers decide whether to issue a SCSI bus reset.
-+	 */
-+	isp->isp_state = ISP_INITSTATE;
-+}
-+
-+static void
-+isp_scsi_channel_init(struct ispsoftc *isp, int channel)
-+{
-+	sdparam *sdp;
-+	mbreg_t mbs;
-+	int tgt;
-+
-+	sdp = isp->isp_param;
-+	sdp += channel;
-+
-+	/*
-+	 * Set (possibly new) Initiator ID.
-+	 */
-+	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
-+	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+	isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
-+	    sdp->isp_initiator_id, channel);
-+
-+
-+	/*
-+	 * Set current per-target parameters to an initial safe minimum.
-+	 */
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		int lun;
-+		u_int16_t sdf;
-+
-+		if (sdp->isp_devparam[tgt].dev_enable == 0) {
-+			continue;
-+		}
-+#ifndef	ISP_TARGET_MODE
-+		sdf = sdp->isp_devparam[tgt].goal_flags;
-+		sdf &= DPARM_SAFE_DFLT;
-+		/*
-+		 * It is not quite clear when this changed over so that
-+		 * we could force narrow and async for 1000/1020 cards,
-+		 * but assume that this is only the case for loaded
-+		 * firmware.
-+		 */
-+		if (isp->isp_loaded_fw) {
-+			sdf |= DPARM_NARROW | DPARM_ASYNC;
-+		}
-+#else
-+		/*
-+		 * The !$*!)$!$)* f/w uses the same index into some
-+		 * internal table to decide how to respond to negotiations,
-+		 * so if we've said "let's be safe" for ID X, and ID X
-+		 * selects *us*, the negotiations will back to 'safe'
-+		 * (as in narrow/async). What the f/w *should* do is
-+		 * use the initiator id settings to decide how to respond.
-+		 */
-+		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
-+#endif
-+		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
-+		mbs.param[1] = (channel << 15) | (tgt << 8);
-+		mbs.param[2] = sdf;
-+		if ((sdf & DPARM_SYNC) == 0) {
-+			mbs.param[3] = 0;
-+		} else {
-+			mbs.param[3] =
-+			    (sdp->isp_devparam[tgt].goal_offset << 8) |
-+			    (sdp->isp_devparam[tgt].goal_period);
-+		}
-+		isp_prt(isp, ISP_LOGDEBUG0,
-+		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
-+		    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
-+		    mbs.param[3] & 0xff);
-+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			sdf = DPARM_SAFE_DFLT;
-+			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
-+			mbs.param[1] = (tgt << 8) | (channel << 15);
-+			mbs.param[2] = sdf;
-+			mbs.param[3] = 0;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL);
-+			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+				continue;
-+			}
-+		}
-+
-+		/*
-+		 * We don't update any information directly from the f/w
-+		 * because we need to run at least one command to cause a
-+		 * new state to be latched up. So, we just assume that we
-+		 * converge to the values we just had set.
-+		 *
-+		 * Ensure that we don't believe tagged queuing is enabled yet.
-+		 * It turns out that sometimes the ISP just ignores our
-+		 * attempts to set parameters for devices that it hasn't
-+		 * seen yet.
-+		 */
-+		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
-+		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
-+			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
-+			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
-+			mbs.param[2] = sdp->isp_max_queue_depth;
-+			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL);
-+			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+				break;
-+			}
-+		}
-+	}
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		if (sdp->isp_devparam[tgt].dev_refresh) {
-+			isp->isp_sendmarker |= (1 << channel);
-+			isp->isp_update |= (1 << channel);
-+			break;
-+		}
-+	}
-+}
-+
-+/*
-+ * Fibre Channel specific initialization.
-+ *
-+ * Locks are held before coming here.
-+ */
-+static void
-+isp_fibre_init(struct ispsoftc *isp)
-+{
-+	fcparam *fcp;
-+	isp_icb_t local, *icbp = &local;
-+	mbreg_t mbs;
-+	int loopid;
-+	u_int64_t nwwn, pwwn;
-+
-+	fcp = isp->isp_param;
-+
-+	/*
-+	 * Do this *before* initializing the firmware.
-+	 */
-+	isp_mark_getpdb_all(isp);
-+	fcp->isp_fwstate = FW_CONFIG_WAIT;
-+	fcp->isp_loopstate = LOOP_NIL;
-+
-+	/*
-+	 * If we have no role (neither target nor initiator), return.
-+	 */
-+	if (isp->isp_role == ISP_ROLE_NONE) {
-+		return;
-+	}
-+
-+	loopid = fcp->isp_loopid;
-+	MEMZERO(icbp, sizeof (*icbp));
-+	icbp->icb_version = ICB_VERSION1;
-+
-+	/*
-+	 * Firmware Options are either retrieved from NVRAM or
-+	 * are patched elsewhere. We check them for sanity here
-+	 * and make changes based on board revision, but otherwise
-+	 * let others decide policy.
-+	 */
-+
-+	/*
-+	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
-+	 */
-+	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
-+		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
-+	}
-+
-+	/*
-+	 * We have to use FULL LOGIN even though it resets the loop too much
-+	 * because otherwise port database entries don't get updated after
-+	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
-+	 */
-+	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
-+		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
-+	}
-+
-+	/*
-+	 * Insist on Port Database Update Async notifications
-+	 */
-+	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
-+
-+	/*
-+	 * Make sure that target role reflects into fwoptions.
-+	 */
-+	if (isp->isp_role & ISP_ROLE_TARGET) {
-+		fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
-+	} else {
-+		fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
-+	}
-+
-+	/*
-+	 * Propagate all of this into the ICB structure.
-+	 */
-+	icbp->icb_fwoptions = fcp->isp_fwoptions;
-+	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
-+	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
-+	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "bad frame length (%d) from NVRAM- using %d",
-+		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
-+		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
-+	}
-+	icbp->icb_maxalloc = fcp->isp_maxalloc;
-+	if (icbp->icb_maxalloc < 1) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
-+		icbp->icb_maxalloc = 16;
-+	}
-+	icbp->icb_execthrottle = fcp->isp_execthrottle;
-+	if (icbp->icb_execthrottle < 1) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "bad execution throttle of %d- using 16",
-+		    fcp->isp_execthrottle);
-+		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
-+	}
-+	icbp->icb_retry_delay = fcp->isp_retry_delay;
-+	icbp->icb_retry_count = fcp->isp_retry_count;
-+	icbp->icb_hardaddr = loopid;
-+	/*
-+	 * Right now we just set extended options to prefer point-to-point
-+	 * over loop based upon some soft config options.
-+	 * 
-+	 * NB: for the 2300, ICBOPT_EXTENDED is required.
-+	 */
-+	if (IS_2200(isp) || IS_23XX(isp)) {
-+		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
-+		/*
-+		 * Prefer or force Point-To-Point instead Loop?
-+		 */
-+		switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
-+		case ISP_CFG_NPORT:
-+			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
-+			break;
-+		case ISP_CFG_NPORT_ONLY:
-+			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
-+			break;
-+		case ISP_CFG_LPORT_ONLY:
-+			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
-+			break;
-+		default:
-+			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
-+			break;
-+		}
-+		if (IS_23XX(isp)) {
-+			/*
-+			 * QLogic recommends that FAST Posting be turned
-+			 * off for 23XX cards and instead allow the HBA
-+			 * to write response queue entries and interrupt
-+			 * after a delay (ZIO).
-+			 *
-+			 * If we set ZIO, it will disable fast posting,
-+			 * so we don't need to clear it in fwoptions.
-+			 */
-+#ifndef	ISP_NO_ZIO
-+			icbp->icb_xfwoptions |= ICBXOPT_ZIO;
-+#else
-+			icbp->icb_fwoptions |= ICBOPT_FAST_POST;
-+#endif
-+#if	0
-+			/*
-+			 * Values, in 100us increments. The default
-+			 * is 2 (200us) if a value 0 (default) is
-+			 * selected.
-+			 */
-+			icbp->icb_idelaytimer = 2;
-+#endif
-+
-+			if (isp->isp_confopts & ISP_CFG_ONEGB) {
-+				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
-+			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
-+				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
-+			} else {
-+				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
-+			}
-+		}
-+	}
-+
-+#ifndef	ISP_NO_RIO_FC
-+	/*
-+	 * RIO seems to be enabled in 2100s for fw >= 1.17.0.
-+	 *
-+	 * I've had some questionable problems with RIO on 2200.
-+	 * More specifically, on a 2204 I had problems with RIO
-+	 * on a Linux system where I was dropping commands right
-+	 * and left. It's not clear to me what the actual problem
-+	 * was.
-+	 *
-+	 * 23XX Cards do not support RIO. Instead they support ZIO.
-+	 */
-+#if	0
-+	if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
-+		icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
-+		icbp->icb_racctimer = 4;
-+		icbp->icb_idelaytimer = 8;
-+	}
-+#endif
-+#endif
-+
-+	/*
-+	 * For 22XX > 2.1.26 && 23XX, set someoptions.
-+	 * XXX: Probably okay for newer 2100 f/w too.
-+	 */
-+	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
-+		/*
-+		 * Turn on LIP F8 async event (1)
-+		 * Turn on generate AE 8013 on all LIP Resets (2)
-+		 * Disable LIP F7 switching (8)
-+		 */
-+		mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
-+		mbs.param[1] = 0xb;
-+		mbs.param[2] = 0;
-+		mbs.param[3] = 0;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	}
-+	icbp->icb_logintime = 30;	/* 30 second login timeout */
-+
-+	if (IS_23XX(isp)) {
-+		ISP_WRITE(isp, isp->isp_rqstinrp, 0);
-+        	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
-+        	ISP_WRITE(isp, isp->isp_respinrp, 0);
-+		ISP_WRITE(isp, isp->isp_respoutrp, 0);
-+	}
-+
-+	nwwn = ISP_NODEWWN(isp);
-+	pwwn = ISP_PORTWWN(isp);
-+	if (nwwn && pwwn) {
-+		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
-+		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
-+		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
-+		isp_prt(isp, ISP_LOGDEBUG1,
-+		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
-+		    ((u_int32_t) (nwwn >> 32)),
-+		    ((u_int32_t) (nwwn & 0xffffffff)),
-+		    ((u_int32_t) (pwwn >> 32)),
-+		    ((u_int32_t) (pwwn & 0xffffffff)));
-+	} else {
-+		isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
-+		icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
-+	}
-+	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
-+	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
-+	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
-+	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
-+	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
-+	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
-+	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
-+	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
-+	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
-+	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
-+	isp_prt(isp, ISP_LOGDEBUG0,
-+	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
-+	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
-+
-+	FC_SCRATCH_ACQUIRE(isp);
-+	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
-+
-+	/*
-+	 * Init the firmware
-+	 */
-+	mbs.param[0] = MBOX_INIT_FIRMWARE;
-+	mbs.param[1] = 0;
-+	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+	mbs.param[4] = 0;
-+	mbs.param[5] = 0;
-+	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	FC_SCRATCH_RELEASE(isp);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return;
-+	}
-+	isp->isp_reqidx = isp->isp_reqodx = 0;
-+	isp->isp_residx = 0;
-+	isp->isp_sendmarker = 1;
-+
-+	/*
-+	 * Whatever happens, we're now committed to being here.
-+	 */
-+	isp->isp_state = ISP_INITSTATE;
-+}
-+
-+/*
-+ * Fibre Channel Support- get the port database for the id.
-+ *
-+ * Locks are held before coming here. Return 0 if success,
-+ * else failure.
-+ */
-+
-+static int
-+isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
-+{
-+	fcparam *fcp = (fcparam *) isp->isp_param;
-+	mbreg_t mbs;
-+
-+	mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
-+	mbs.param[1] = 0;
-+	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+	/*
-+	 * Unneeded. For the 2100, except for initializing f/w, registers
-+	 * 4/5 have to not be written to.
-+	 *	mbs.param[4] = 0;
-+	 *	mbs.param[5] = 0;
-+	 *
-+	 */
-+	mbs.param[6] = 0;
-+	mbs.param[7] = 0;
-+	FC_SCRATCH_ACQUIRE(isp);
-+	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
-+	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+		MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
-+		map->fwmap = mbs.param[1] != 0;
-+		FC_SCRATCH_RELEASE(isp);
-+		return (0);
-+	}
-+	FC_SCRATCH_RELEASE(isp);
-+	return (-1);
-+}
-+
-+static void
-+isp_mark_getpdb_all(struct ispsoftc *isp)
-+{
-+	fcparam *fcp = (fcparam *) isp->isp_param;
-+	int i;
-+	for (i = 0; i < MAX_FC_TARG; i++) {
-+		fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
-+	}
-+}
-+
-+static int
-+isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
-+{
-+	fcparam *fcp = (fcparam *) isp->isp_param;
-+	mbreg_t mbs;
-+
-+	mbs.param[0] = MBOX_GET_PORT_DB;
-+	mbs.param[1] = id << 8;
-+	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+	/*
-+	 * Unneeded. For the 2100, except for initializing f/w, registers
-+	 * 4/5 have to not be written to.
-+	 *	mbs.param[4] = 0;
-+	 *	mbs.param[5] = 0;
-+	 *
-+	 */
-+	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+	FC_SCRATCH_ACQUIRE(isp);
-+	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
-+	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+		isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
-+		FC_SCRATCH_RELEASE(isp);
-+		return (0);
-+	}
-+	FC_SCRATCH_RELEASE(isp);
-+	return (-1);
-+}
-+
-+static u_int64_t
-+isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
-+{
-+	u_int64_t wwn = 0;
-+	mbreg_t mbs;
-+
-+	mbs.param[0] = MBOX_GET_PORT_NAME;
-+	mbs.param[1] = loopid << 8;
-+	if (nodename)
-+		mbs.param[1] |= 1;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
-+	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+		wwn =
-+		    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
-+		    (((u_int64_t)(mbs.param[2] >> 8))	<< 48) |
-+		    (((u_int64_t)(mbs.param[3] & 0xff))	<< 40) |
-+		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |
-+		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |
-+		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |
-+		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |
-+		    (((u_int64_t)(mbs.param[7] >> 8)));
-+	}
-+	return (wwn);
-+}
-+
-+/*
-+ * Make sure we have good FC link and know our Loop ID.
-+ */
-+
-+static int
-+isp_fclink_test(struct ispsoftc *isp, int usdelay)
-+{
-+	static char *toponames[] = {
-+		"Private Loop",
-+		"FL Port",
-+		"N-Port to N-Port",
-+		"F Port",
-+		"F Port (no FLOGI_ACC response)"
-+	};
-+	mbreg_t mbs;
-+	int count, check_for_fabric;
-+	u_int8_t lwfs;
-+	fcparam *fcp;
-+	struct lportdb *lp;
-+	isp_pdb_t pdb;
-+
-+	fcp = isp->isp_param;
-+
-+	/*
-+	 * XXX: Here is where we would start a 'loop dead' timeout
-+	 */
-+
-+	/*
-+	 * Wait up to N microseconds for F/W to go to a ready state.
-+	 */
-+	lwfs = FW_CONFIG_WAIT;
-+	count = 0;
-+	while (count < usdelay) {
-+		u_int64_t enano;
-+		u_int32_t wrk;
-+		NANOTIME_T hra, hrb;
-+
-+		GET_NANOTIME(&hra);
-+		isp_fw_state(isp);
-+		if (lwfs != fcp->isp_fwstate) {
-+			isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
-+			    isp2100_fw_statename((int)lwfs),
-+			    isp2100_fw_statename((int)fcp->isp_fwstate));
-+			lwfs = fcp->isp_fwstate;
-+		}
-+		if (fcp->isp_fwstate == FW_READY) {
-+			break;
-+		}
-+		GET_NANOTIME(&hrb);
-+
-+		/*
-+		 * Get the elapsed time in nanoseconds.
-+		 * Always guaranteed to be non-zero.
-+		 */
-+		enano = NANOTIME_SUB(&hrb, &hra);
-+
-+		isp_prt(isp, ISP_LOGDEBUG1,
-+		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
-+		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
-+		    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
-+
-+		/*
-+		 * If the elapsed time is less than 1 millisecond,
-+		 * delay a period of time up to that millisecond of
-+		 * waiting.
-+		 *
-+		 * This peculiar code is an attempt to try and avoid
-+		 * invoking u_int64_t math support functions for some
-+		 * platforms where linkage is a problem.
-+		 */
-+		if (enano < (1000 * 1000)) {
-+			count += 1000;
-+			enano = (1000 * 1000) - enano;
-+			while (enano > (u_int64_t) 4000000000U) {
-+				USEC_SLEEP(isp, 4000000);
-+				enano -= (u_int64_t) 4000000000U;
-+			}
-+			wrk = enano;
-+			wrk /= 1000;
-+			USEC_SLEEP(isp, wrk);
-+		} else {
-+			while (enano > (u_int64_t) 4000000000U) {
-+				count += 4000000;
-+				enano -= (u_int64_t) 4000000000U;
-+			}
-+			wrk = enano;
-+			count += (wrk / 1000);
-+		}
-+	}
-+
-+	/*
-+	 * If we haven't gone to 'ready' state, return.
-+	 */
-+	if (fcp->isp_fwstate != FW_READY) {
-+		return (-1);
-+	}
-+
-+	/*
-+	 * Get our Loop ID (if possible). We really need to have it.
-+	 */
-+	mbs.param[0] = MBOX_GET_LOOP_ID;
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		return (-1);
-+	}
-+	fcp->isp_loopid = mbs.param[1];
-+	if (IS_2200(isp) || IS_23XX(isp)) {
-+		int topo = (int) mbs.param[6];
-+		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
-+			topo = TOPO_PTP_STUB;
-+		fcp->isp_topo = topo;
-+	} else {
-+		fcp->isp_topo = TOPO_NL_PORT;
-+	}
-+	fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
-+
-+	/*
-+	 * Check to see if we're on a fabric by trying to see if we
-+	 * can talk to the fabric name server. This can be a bit
-+	 * tricky because if we're a 2100, we should check always
-+	 * (in case we're connected to a server doing aliasing).
-+	 */
-+	fcp->isp_onfabric = 0;
-+
-+	if (IS_2100(isp)) {
-+		/*
-+		 * Don't bother with fabric if we are using really old
-+		 * 2100 firmware. It's just not worth it.
-+		 */
-+		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
-+			check_for_fabric = 1;
-+		} else {
-+			check_for_fabric = 0;
-+		}
-+	} else if (fcp->isp_topo == TOPO_FL_PORT ||
-+	    fcp->isp_topo == TOPO_F_PORT) {
-+		check_for_fabric = 1;
-+	} else
-+		check_for_fabric = 0;
-+
-+	if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
-+		int loopid = FL_PORT_ID;
-+		if (IS_2100(isp)) {
-+			fcp->isp_topo = TOPO_FL_PORT;
-+		}
-+
-+		if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
-+			/*
-+			 * Crock.
-+			 */
-+			fcp->isp_topo = TOPO_NL_PORT;
-+			goto not_on_fabric;
-+		}
-+		fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
-+
-+		/*
-+		 * Save the Fabric controller's port database entry.
-+		 */
-+		lp = &fcp->portdb[loopid];
-+		lp->node_wwn =
-+		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_nodename[7]));
-+		lp->port_wwn =
-+		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_portname[7]));
-+		lp->roles =
-+		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
-+		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
-+		lp->loopid = pdb.pdb_loopid;
-+		lp->loggedin = lp->valid = 1;
-+		fcp->isp_onfabric = 1;
-+		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
-+		isp_register_fc4_type(isp);
-+	} else {
-+not_on_fabric:
-+		fcp->isp_onfabric = 0;
-+		fcp->portdb[FL_PORT_ID].valid = 0;
-+	}
-+
-+	fcp->isp_gbspeed = 1;
-+	if (IS_23XX(isp)) {
-+		mbs.param[0] = MBOX_GET_SET_DATA_RATE;
-+		mbs.param[1] = MBGSD_GET_RATE;
-+		/* mbs.param[2] undefined if we're just getting rate */
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+			if (mbs.param[1] == MBGSD_TWOGB) {
-+				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
-+				fcp->isp_gbspeed = 2;
-+			}
-+		}
-+	}
-+
-+	isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
-+	    fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
-+
-+	/*
-+	 * Announce ourselves, too. This involves synthesizing an entry.
-+	 */
-+	if (fcp->isp_iid_set == 0) {
-+		fcp->isp_iid_set = 1;
-+		fcp->isp_iid = fcp->isp_loopid;
-+		lp = &fcp->portdb[fcp->isp_iid];
-+	} else {
-+		lp = &fcp->portdb[fcp->isp_iid];
-+		if (fcp->isp_portid != lp->portid ||
-+		    fcp->isp_loopid != lp->loopid ||
-+		    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
-+		    fcp->isp_portwwn != ISP_PORTWWN(isp)) {
-+			lp->valid = 0;
-+			count = fcp->isp_iid;
-+			(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
-+		}
-+	}
-+	lp->loopid = fcp->isp_loopid;
-+	lp->portid = fcp->isp_portid;
-+	lp->node_wwn = ISP_NODEWWN(isp);
-+	lp->port_wwn = ISP_PORTWWN(isp);
-+	switch (isp->isp_role) {
-+	case ISP_ROLE_NONE:
-+		lp->roles = 0;
-+		break;
-+	case ISP_ROLE_TARGET:
-+		lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
-+		break;
-+	case ISP_ROLE_INITIATOR:
-+		lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
-+		break;
-+	case ISP_ROLE_BOTH:
-+		lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
-+		break;
-+	}
-+	lp->loggedin = lp->valid = 1;
-+	count = fcp->isp_iid;
-+	(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
-+	return (0);
-+}
-+
-+static char *
-+isp2100_fw_statename(int state)
-+{
-+	switch(state) {
-+	case FW_CONFIG_WAIT:	return "Config Wait";
-+	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";
-+	case FW_WAIT_LOGIN:	return "Wait Login";
-+	case FW_READY:		return "Ready";
-+	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
-+	case FW_ERROR:		return "Error";
-+	case FW_REINIT:		return "Re-Init";
-+	case FW_NON_PART:	return "Nonparticipating";
-+	default:		return "?????";
-+	}
-+}
-+
-+/*
-+ * Synchronize our soft copy of the port database with what the f/w thinks
-+ * (with a view toward possibly for a specific target....)
-+ */
-+
-+static int
-+isp_pdb_sync(struct ispsoftc *isp)
-+{
-+	struct lportdb *lp;
-+	fcparam *fcp = isp->isp_param;
-+	isp_pdb_t pdb;
-+	int loopid, base, lim;
-+
-+	/*
-+	 * Make sure we're okay for doing this right now.
-+	 */
-+	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
-+	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
-+	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
-+		return (-1);
-+	}
-+
-+	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
-+	    fcp->isp_topo == TOPO_N_PORT) {
-+		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
-+			if (isp_scan_loop(isp) != 0) {
-+				return (-1);
-+			}
-+		}
-+	}
-+	fcp->isp_loopstate = LOOP_SYNCING_PDB;
-+
-+	/*
-+	 * If we get this far, we've settled our differences with the f/w
-+	 * (for local loop device) and we can say that the loop state is ready.
-+	 */
-+
-+	if (fcp->isp_topo == TOPO_NL_PORT) {
-+		fcp->loop_seen_once = 1;
-+		fcp->isp_loopstate = LOOP_READY;
-+		return (0);
-+	}
-+
-+	/*
-+	 * Find all Fabric Entities that didn't make it from one scan to the
-+	 * next and let the world know they went away. Scan the whole database.
-+	 */
-+	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
-+		if (lp->was_fabric_dev && lp->fabric_dev == 0) {
-+			loopid = lp - fcp->portdb;
-+			lp->valid = 0;	/* should already be set */
-+			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
-+			MEMZERO((void *) lp, sizeof (*lp));
-+			continue;
-+		}
-+		lp->was_fabric_dev = lp->fabric_dev;
-+	}
-+
-+	if (fcp->isp_topo == TOPO_FL_PORT)
-+		base = FC_SNS_ID+1;
-+	else
-+		base = 0;
-+
-+	if (fcp->isp_topo == TOPO_N_PORT)
-+		lim = 1;
-+	else
-+		lim = MAX_FC_TARG;
-+
-+	/*
-+	 * Now log in any fabric devices that the outer layer has
-+	 * left for us to see. This seems the most sane policy
-+	 * for the moment.
-+	 */
-+	for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
-+		u_int32_t portid;
-+		mbreg_t mbs;
-+
-+		loopid = lp - fcp->portdb;
-+		if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
-+			continue;
-+		}
-+
-+		/*
-+		 * Anything here?
-+		 */
-+		if (lp->port_wwn == 0) {
-+			continue;
-+		}
-+
-+		/*
-+		 * Don't try to log into yourself.
-+		 */
-+		if ((portid = lp->portid) == fcp->isp_portid) {
-+			continue;
-+		}
-+
-+
-+		/*
-+		 * If we'd been logged in- see if we still are and we haven't
-+		 * changed. If so, no need to log ourselves out, etc..
-+		 *
-+		 * Unfortunately, our charming Qlogic f/w has decided to
-+		 * return a valid port database entry for a fabric device
-+		 * that has, in fact, gone away. And it hangs trying to
-+		 * log it out.
-+		 */
-+		if (lp->loggedin && lp->force_logout == 0 &&
-+		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
-+			int nrole;
-+			u_int64_t nwwnn, nwwpn;
-+			nwwnn =
-+			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
-+			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
-+			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
-+			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
-+			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
-+			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
-+			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
-+			    (((u_int64_t)pdb.pdb_nodename[7]));
-+			nwwpn =
-+			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
-+			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
-+			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
-+			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
-+			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
-+			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
-+			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
-+			    (((u_int64_t)pdb.pdb_portname[7]));
-+			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
-+			    SVC3_ROLE_SHIFT;
-+			if (pdb.pdb_loopid == lp->loopid && lp->portid ==
-+			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
-+			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
-+			    lp->roles == nrole && lp->force_logout == 0) {
-+				lp->loggedin = lp->valid = 1;
-+				isp_prt(isp, ISP_LOGCONFIG, lretained,
-+				    (int) (lp - fcp->portdb),
-+				    (int) lp->loopid, lp->portid);
-+				continue;
-+			}
-+		}
-+
-+		if (fcp->isp_fwstate != FW_READY ||
-+		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
-+			return (-1);
-+		}
-+
-+		/*
-+		 * Force a logout if we were logged in.
-+		 */
-+		if (lp->loggedin) {
-+			if (lp->force_logout ||
-+			    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
-+				mbs.param[0] = MBOX_FABRIC_LOGOUT;
-+				mbs.param[1] = lp->loopid << 8;
-+				mbs.param[2] = 0;
-+				mbs.param[3] = 0;
-+				isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+				isp_prt(isp, ISP_LOGINFO, plogout,
-+				    (int) (lp - fcp->portdb), lp->loopid,
-+				    lp->portid);
-+			}
-+			lp->force_logout = lp->loggedin = 0;
-+			if (fcp->isp_fwstate != FW_READY ||
-+			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
-+				return (-1);
-+			}
-+		}
-+
-+		/*
-+		 * And log in....
-+		 */
-+		loopid = lp - fcp->portdb;
-+		lp->loopid = FL_PORT_ID;
-+		do {
-+			mbs.param[0] = MBOX_FABRIC_LOGIN;
-+			mbs.param[1] = loopid << 8;
-+			mbs.param[2] = portid >> 16;
-+			mbs.param[3] = portid & 0xffff;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
-+			    MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
-+			if (fcp->isp_fwstate != FW_READY ||
-+			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
-+				return (-1);
-+			}
-+			switch (mbs.param[0]) {
-+			case MBOX_LOOP_ID_USED:
-+				/*
-+				 * Try the next available loop id.
-+				 */
-+				loopid++;
-+				break;
-+			case MBOX_PORT_ID_USED:
-+				/*
-+				 * This port is already logged in.
-+				 * Snaffle the loop id it's using if it's
-+				 * nonzero, otherwise we're hosed.
-+				 */
-+				if (mbs.param[1] != 0) {
-+					loopid = mbs.param[1];
-+					isp_prt(isp, ISP_LOGINFO, retained,
-+					    loopid, (int) (lp - fcp->portdb),
-+					    lp->portid);
-+				} else {
-+					loopid = MAX_FC_TARG;
-+					break;
-+				}
-+				/* FALLTHROUGH */
-+			case MBOX_COMMAND_COMPLETE:
-+				lp->loggedin = 1;
-+				lp->loopid = loopid;
-+				break;
-+			case MBOX_COMMAND_ERROR:
-+				isp_prt(isp, ISP_LOGINFO, plogierr,
-+				    portid, mbs.param[1]);
-+				/* FALLTHROUGH */
-+			case MBOX_ALL_IDS_USED: /* We're outta IDs */
-+			default:
-+				loopid = MAX_FC_TARG;
-+				break;
-+			}
-+		} while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
-+
-+		/*
-+		 * If we get here and we haven't set a Loop ID,
-+		 * we failed to log into this device.
-+		 */
-+
-+		if (lp->loopid == FL_PORT_ID) {
-+			lp->loopid = 0;
-+			continue;
-+		}
-+
-+		/*
-+		 * Make sure we can get the approriate port information.
-+		 */
-+		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
-+			isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
-+			goto dump_em;
-+		}
-+
-+		if (fcp->isp_fwstate != FW_READY ||
-+		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
-+			return (-1);
-+		}
-+
-+		if (pdb.pdb_loopid != lp->loopid) {
-+			isp_prt(isp, ISP_LOGWARN, pdbmfail1,
-+			    lp->portid, pdb.pdb_loopid);
-+			goto dump_em;
-+		}
-+
-+		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
-+			isp_prt(isp, ISP_LOGWARN, pdbmfail2,
-+			    lp->portid, BITS2WORD(pdb.pdb_portid_bits));
-+			goto dump_em;
-+		}
-+
-+		lp->roles =
-+		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
-+		lp->node_wwn =
-+		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_nodename[7]));
-+		lp->port_wwn =
-+		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_portname[7]));
-+		/*
-+		 * Check to make sure this all makes sense.
-+		 */
-+		if (lp->node_wwn && lp->port_wwn) {
-+			lp->valid = 1;
-+			loopid = lp - fcp->portdb;
-+			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
-+			continue;
-+		}
-+dump_em:
-+		lp->valid = 0;
-+		isp_prt(isp, ISP_LOGINFO,
-+		    ldumped, loopid, lp->loopid, lp->portid);
-+		mbs.param[0] = MBOX_FABRIC_LOGOUT;
-+		mbs.param[1] = lp->loopid << 8;
-+		mbs.param[2] = 0;
-+		mbs.param[3] = 0;
-+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+		if (fcp->isp_fwstate != FW_READY ||
-+		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
-+			return (-1);
-+		}
-+	}
-+	/*
-+	 * If we get here, we've for sure seen not only a valid loop
-+	 * but know what is or isn't on it, so mark this for usage
-+	 * in isp_start.
-+	 */
-+	fcp->loop_seen_once = 1;
-+	fcp->isp_loopstate = LOOP_READY;
-+	return (0);
-+}
-+
-+static int
-+isp_scan_loop(struct ispsoftc *isp)
-+{
-+	struct lportdb *lp;
-+	fcparam *fcp = isp->isp_param;
-+	isp_pdb_t pdb;
-+	int loopid, lim, hival;
-+
-+	switch (fcp->isp_topo) {
-+	case TOPO_NL_PORT:
-+		hival = FL_PORT_ID;
-+		break;
-+	case TOPO_N_PORT:
-+		hival = 2;
-+		break;
-+	case TOPO_FL_PORT:
-+		hival = FC_PORT_ID;
-+		break;
-+	default:
-+		fcp->isp_loopstate = LOOP_LSCAN_DONE;
-+		return (0);
-+	}
-+	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
-+
-+	/*
-+	 * make sure the temp port database is clean...
-+	 */
-+	MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
-+
-+	/*
-+	 * Run through the local loop ports and get port database info
-+	 * for each loop ID.
-+	 *
-+	 * There's a somewhat unexplained situation where the f/w passes back
-+	 * the wrong database entity- if that happens, just restart (up to
-+	 * FL_PORT_ID times).
-+	 */
-+	for (lim = loopid = 0; loopid < hival; loopid++) {
-+		lp = &fcp->tport[loopid];
-+
-+		/*
-+		 * Don't even try for ourselves...
-+	 	 */
-+		if (loopid == fcp->isp_loopid)
-+			continue;
-+
-+		lp->node_wwn = isp_get_portname(isp, loopid, 1);
-+		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
-+			return (-1);
-+		if (lp->node_wwn == 0)
-+			continue;
-+		lp->port_wwn = isp_get_portname(isp, loopid, 0);
-+		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
-+			return (-1);
-+		if (lp->port_wwn == 0) {
-+			lp->node_wwn = 0;
-+			continue;
-+		}
-+
-+		/*
-+		 * Get an entry....
-+		 */
-+		if (isp_getpdb(isp, loopid, &pdb) != 0) {
-+			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
-+				return (-1);
-+			continue;
-+		}
-+		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
-+			return (-1);
-+		}
-+
-+		/*
-+		 * If the returned database element doesn't match what we
-+		 * asked for, restart the process entirely (up to a point...).
-+		 */
-+		if (pdb.pdb_loopid != loopid) {
-+			loopid = 0;
-+			if (lim++ < hival) {
-+				continue;
-+			}
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "giving up on synchronizing the port database");
-+			return (-1);
-+		}
-+
-+		/*
-+		 * Save the pertinent info locally.
-+		 */
-+		lp->node_wwn =
-+		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_nodename[7]));
-+		lp->port_wwn =
-+		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
-+		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
-+		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
-+		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
-+		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
-+		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
-+		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
-+		    (((u_int64_t)pdb.pdb_portname[7]));
-+		lp->roles =
-+		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
-+		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
-+		lp->loopid = pdb.pdb_loopid;
-+	}
-+
-+	/*
-+	 * Mark all of the permanent local loop database entries as invalid
-+	 * (except our own entry).
-+	 */
-+	for (loopid = 0; loopid < hival; loopid++) {
-+		if (loopid == fcp->isp_iid) {
-+			fcp->portdb[loopid].valid = 1;
-+			fcp->portdb[loopid].loopid = fcp->isp_loopid;
-+			continue;
-+		}
-+		fcp->portdb[loopid].valid = 0;
-+	}
-+
-+	/*
-+	 * Now merge our local copy of the port database into our saved copy.
-+	 * Notify the outer layers of new devices arriving.
-+	 */
-+	for (loopid = 0; loopid < hival; loopid++) {
-+		int i;
-+
-+		/*
-+		 * If we don't have a non-zero Port WWN, we're not here.
-+		 */
-+		if (fcp->tport[loopid].port_wwn == 0) {
-+			continue;
-+		}
-+
-+		/*
-+		 * Skip ourselves.
-+		 */
-+		if (loopid == fcp->isp_iid) {
-+			continue;
-+		}
-+
-+		/*
-+		 * For the purposes of deciding whether this is the
-+		 * 'same' device or not, we only search for an identical
-+		 * Port WWN. Node WWNs may or may not be the same as
-+		 * the Port WWN, and there may be multiple different
-+		 * Port WWNs with the same Node WWN. It would be chaos
-+		 * to have multiple identical Port WWNs, so we don't
-+		 * allow that.
-+		 */
-+
-+		for (i = 0; i < hival; i++) {
-+			int j;
-+			if (fcp->portdb[i].port_wwn == 0)
-+				continue;
-+			if (fcp->portdb[i].port_wwn !=
-+			    fcp->tport[loopid].port_wwn)
-+				continue;
-+			/*
-+			 * We found this WWN elsewhere- it's changed
-+			 * loopids then. We don't change it's actual
-+			 * position in our cached port database- we
-+			 * just change the actual loop ID we'd use.
-+			 */
-+			if (fcp->portdb[i].loopid != loopid) {
-+				isp_prt(isp, ISP_LOGINFO, portshift, i,
-+				    fcp->portdb[i].loopid,
-+				    fcp->portdb[i].portid, loopid,
-+				    fcp->tport[loopid].portid);
-+			}
-+			fcp->portdb[i].portid = fcp->tport[loopid].portid;
-+			fcp->portdb[i].loopid = loopid;
-+			fcp->portdb[i].valid = 1;
-+			fcp->portdb[i].roles = fcp->tport[loopid].roles;
-+
-+			/*
-+			 * Now make sure this Port WWN doesn't exist elsewhere
-+			 * in the port database.
-+			 */
-+			for (j = i+1; j < hival; j++) {
-+				if (fcp->portdb[i].port_wwn !=
-+				    fcp->portdb[j].port_wwn) {
-+					continue;
-+				}
-+				isp_prt(isp, ISP_LOGWARN, portdup, j, i);
-+				/*
-+				 * Invalidate the 'old' *and* 'new' ones.
-+				 * This is really harsh and not quite right,
-+				 * but if this happens, we really don't know
-+				 * who is what at this point.
-+				 */
-+				fcp->portdb[i].valid = 0;
-+				fcp->portdb[j].valid = 0;
-+			}
-+			break;
-+		}
-+
-+		/*
-+		 * If we didn't traverse the entire port database,
-+		 * then we found (and remapped) an existing entry.
-+		 * No need to notify anyone- go for the next one.
-+		 */
-+		if (i < hival) {
-+			isp_prt(isp, ISP_LOGINFO, retained,
-+			    fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
-+			continue;
-+		}
-+
-+		/*
-+		 * We've not found this Port WWN anywhere. It's a new entry.
-+		 * See if we can leave it where it is (with target == loopid).
-+		 */
-+		if (fcp->portdb[loopid].port_wwn != 0) {
-+			for (lim = 0; lim < hival; lim++) {
-+				if (fcp->portdb[lim].port_wwn == 0)
-+					break;
-+			}
-+			/* "Cannot Happen" */
-+			if (lim == hival) {
-+				isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
-+				continue;
-+			}
-+			i = lim;
-+		} else {
-+			i = loopid;
-+		}
-+
-+		/*
-+		 * NB:	The actual loopid we use here is loopid- we may
-+		 *	in fact be at a completely different index (target).
-+		 */
-+		fcp->portdb[i].loopid = loopid;
-+		fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
-+		fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
-+		fcp->portdb[i].roles = fcp->tport[loopid].roles;
-+		fcp->portdb[i].portid = fcp->tport[loopid].portid;
-+		fcp->portdb[i].valid = 1;
-+
-+		/*
-+		 * Tell the outside world we've arrived.
-+		 */
-+		(void) isp_async(isp, ISPASYNC_PROMENADE, &i);
-+	}
-+
-+	/*
-+	 * Now find all previously used targets that are now invalid and
-+	 * notify the outer layers that they're gone.
-+	 */
-+	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
-+		if (lp->valid || lp->port_wwn == 0) {
-+			continue;
-+		}
-+
-+		/*
-+		 * Tell the outside world we've gone
-+		 * away and erase our pdb entry.
-+		 *
-+		 */
-+		loopid = lp - fcp->portdb;
-+		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
-+		MEMZERO((void *) lp, sizeof (*lp));
-+	}
-+	fcp->isp_loopstate = LOOP_LSCAN_DONE;
-+	return (0);
-+}
-+
-+
-+static int
-+isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
-+{
-+	isp_mboxcmd(isp, mbp, MBLOGNONE);
-+	if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
-+		if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
-+			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
-+		}
-+		if (mbp->param[0] == MBOX_COMMAND_ERROR) {
-+			char tbuf[16];
-+			char *m;
-+			switch (mbp->param[1]) {
-+			case 1:
-+				m = "No Loop";
-+				break;
-+			case 2:
-+				m = "Failed to allocate IOCB buffer";
-+				break;
-+			case 3:
-+				m = "Failed to allocate XCB buffer";
-+				break;
-+			case 4:
-+				m = "timeout or transmit failed";
-+				break;
-+			case 5:
-+				m = "no fabric loop";
-+				break;
-+			case 6:
-+				m = "remote device not a target";
-+				break;
-+			default:
-+				SNPRINTF(tbuf, sizeof tbuf, "%x",
-+				    mbp->param[1]);
-+				m = tbuf;
-+				break;
-+			}
-+			isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
-+		}
-+		return (-1);
-+	}
-+
-+	if (FCPARAM(isp)->isp_fwstate != FW_READY ||
-+	    FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
-+		return (-1);
-+	}
-+	return(0);
-+}
-+
-+#ifdef	ISP_USE_GA_NXT
-+static int
-+isp_scan_fabric(struct ispsoftc *isp, int ftype)
-+{
-+	fcparam *fcp = isp->isp_param;
-+	u_int32_t portid, first_portid, last_portid;
-+	int hicap, last_port_same;
-+
-+	if (fcp->isp_onfabric == 0) {
-+		fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+		return (0);
-+	}
-+
-+	FC_SCRATCH_ACQUIRE(isp);
-+
-+	/*
-+	 * Since Port IDs are 24 bits, we can check against having seen
-+	 * anything yet with this value.
-+	 */
-+	last_port_same = 0;
-+	last_portid = 0xffffffff;	/* not a port */
-+	first_portid = portid = fcp->isp_portid;
-+	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
-+
-+	for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
-+		mbreg_t mbs;
-+		sns_screq_t *rq;
-+		sns_ga_nxt_rsp_t *rs0, *rs1;
-+		struct lportdb lcl;
-+		u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
-+
-+		rq = (sns_screq_t *)sc;
-+		MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
-+		rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
-+		rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
-+		rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
-+		rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
-+		rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
-+		rq->snscb_sblen = 6;
-+		rq->snscb_data[0] = SNS_GA_NXT;
-+		rq->snscb_data[4] = portid & 0xffff;
-+		rq->snscb_data[5] = (portid >> 16) & 0xff;
-+		isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
-+		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
-+		mbs.param[0] = MBOX_SEND_SNS;
-+		mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
-+		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+		/*
-+		 * Leave 4 and 5 alone
-+		 */
-+		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+		if (isp_fabric_mbox_cmd(isp, &mbs)) {
-+			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
-+				fcp->isp_loopstate = LOOP_PDB_RCVD;
-+			}
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
-+		rs1 = (sns_ga_nxt_rsp_t *) sc;
-+		rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
-+		isp_get_ga_nxt_response(isp, rs0, rs1);
-+		if (rs1->snscb_cthdr.ct_response != FS_ACC) {
-+			int level;
-+			if (rs1->snscb_cthdr.ct_reason == 9 &&
-+			    rs1->snscb_cthdr.ct_explanation == 7)
-+				level = ISP_LOGDEBUG0;
-+			else
-+				level = ISP_LOGWARN;
-+			isp_prt(isp, level, swrej, "GA_NXT",
-+			    rs1->snscb_cthdr.ct_reason,
-+			    rs1->snscb_cthdr.ct_explanation, portid);
-+			FC_SCRATCH_RELEASE(isp);
-+			fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+			return (0);
-+		}
-+		portid =
-+		    (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
-+		    (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
-+		    (((u_int32_t) rs1->snscb_port_id[2]));
-+
-+		/*
-+		 * XXX: We should check to make sure that this entry
-+		 * XXX: supports the type(s) we are interested in.
-+		 */
-+		/*
-+		 * Okay, we now have information about a fabric object.
-+		 * If it is the type we're interested in, tell the outer layers
-+		 * about it. The outer layer needs to  know: Port ID, WWNN,
-+		 * WWPN, FC4 type, and port type.
-+		 *
-+		 * The lportdb structure is adequate for this.
-+		 */
-+		MEMZERO(&lcl, sizeof (lcl));
-+		lcl.port_type = rs1->snscb_port_type;
-+		lcl.fc4_type = ftype;
-+		lcl.portid = portid;
-+		lcl.node_wwn =
-+		    (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
-+		    (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
-+		    (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
-+		    (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
-+		    (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
-+		    (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
-+		    (((u_int64_t)rs1->snscb_nodename[6]) <<  8) |
-+		    (((u_int64_t)rs1->snscb_nodename[7]));
-+		lcl.port_wwn =
-+		    (((u_int64_t)rs1->snscb_portname[0]) << 56) |
-+		    (((u_int64_t)rs1->snscb_portname[1]) << 48) |
-+		    (((u_int64_t)rs1->snscb_portname[2]) << 40) |
-+		    (((u_int64_t)rs1->snscb_portname[3]) << 32) |
-+		    (((u_int64_t)rs1->snscb_portname[4]) << 24) |
-+		    (((u_int64_t)rs1->snscb_portname[5]) << 16) |
-+		    (((u_int64_t)rs1->snscb_portname[6]) <<  8) |
-+		    (((u_int64_t)rs1->snscb_portname[7]));
-+
-+		/*
-+		 * Does this fabric object support the type we want?
-+		 * If not, skip it.
-+		 */
-+		if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
-+			if (first_portid == portid) {
-+				lcl.last_fabric_dev = 1;
-+			} else {
-+				lcl.last_fabric_dev = 0;
-+			}
-+			(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
-+		} else {
-+			isp_prt(isp, ISP_LOGDEBUG0,
-+			    "PortID 0x%x doesn't support FC4 type 0x%x",
-+			    portid, ftype);
-+		}
-+		if (first_portid == portid) {
-+			fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+			FC_SCRATCH_RELEASE(isp);
-+			return (0);
-+		}
-+		if (portid == last_portid) {
-+			if (last_port_same++ > 20) {
-+				isp_prt(isp, ISP_LOGWARN,
-+				    "tangled fabric database detected");
-+				break;
-+			}
-+		} else {
-+			last_port_same = 0 ;
-+			last_portid = portid;
-+		}
-+	}
-+	FC_SCRATCH_RELEASE(isp);
-+	if (hicap >= GA_NXT_MAX) {
-+		isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
-+	}
-+	fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+	return (0);
-+}
-+#else
-+#define	GIDLEN	((ISP2100_SCRLEN >> 1) + 16)
-+#define	NGENT	((GIDLEN - 16) >> 2)
-+
-+#define	IGPOFF	(ISP2100_SCRLEN - GIDLEN)
-+#define	GXOFF	(256)
-+
-+static int
-+isp_scan_fabric(struct ispsoftc *isp, int ftype)
-+{
-+	fcparam *fcp = FCPARAM(isp);
-+	mbreg_t mbs;
-+	int i;
-+	sns_gid_ft_req_t *rq;
-+	sns_gid_ft_rsp_t *rs0, *rs1;
-+
-+	if (fcp->isp_onfabric == 0) {
-+		fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+		return (0);
-+	}
-+
-+	FC_SCRATCH_ACQUIRE(isp);
-+	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
-+
-+	rq = (sns_gid_ft_req_t *)fcp->tport;
-+	MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
-+	rq->snscb_rblen = GIDLEN >> 1;
-+	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
-+	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
-+	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
-+	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
-+	rq->snscb_sblen = 6;
-+	rq->snscb_cmd = SNS_GID_FT;
-+	rq->snscb_mword_div_2 = NGENT;
-+	rq->snscb_fc4_type = ftype;
-+	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
-+	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
-+	mbs.param[0] = MBOX_SEND_SNS;
-+	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
-+	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+
-+	/*
-+	 * Leave 4 and 5 alone
-+	 */
-+	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+	if (isp_fabric_mbox_cmd(isp, &mbs)) {
-+		if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
-+			fcp->isp_loopstate = LOOP_PDB_RCVD;
-+		}
-+		FC_SCRATCH_RELEASE(isp);
-+		return (-1);
-+	}
-+	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+		FC_SCRATCH_RELEASE(isp);
-+		return (-1);
-+	}
-+	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
-+	rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
-+	rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
-+	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
-+	if (rs1->snscb_cthdr.ct_response != FS_ACC) {
-+		int level;
-+		if (rs1->snscb_cthdr.ct_reason == 9 &&
-+		    rs1->snscb_cthdr.ct_explanation == 7)
-+			level = ISP_LOGDEBUG0;
-+		else
-+			level = ISP_LOGWARN;
-+		isp_prt(isp, level, swrej, "GID_FT",
-+		    rs1->snscb_cthdr.ct_reason,
-+		    rs1->snscb_cthdr.ct_explanation, 0);
-+		FC_SCRATCH_RELEASE(isp);
-+		fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+		return (0);
-+	}
-+
-+	/*
-+	 * Okay, we now have a list of Port IDs for this class of device.
-+	 * Go through the list and for each one get the WWPN/WWNN for it
-+	 * and tell the outer layers about it. The outer layer needs to
-+	 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
-+	 *
-+	 * The lportdb structure is adequate for this.
-+	 */
-+	i = -1;
-+	do {
-+		sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
-+		sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
-+		struct lportdb lcl;
-+#if	0
-+		sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
-+#endif
-+
-+		i++;
-+		MEMZERO(&lcl, sizeof (lcl));
-+		lcl.fc4_type = ftype;
-+		lcl.portid =
-+		    (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
-+		    (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
-+		    (((u_int32_t) rs1->snscb_ports[i].portid[2]));
-+
-+		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
-+		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
-+		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
-+		gq->snscb_sblen = 6;
-+		gq->snscb_cmd = SNS_GPN_ID;
-+		gq->snscb_portid = lcl.portid;
-+		isp_put_gxn_id_request(isp, gq,
-+		    (sns_gxn_id_req_t *) fcp->isp_scratch);
-+		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
-+		mbs.param[0] = MBOX_SEND_SNS;
-+		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
-+		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+		/*
-+		 * Leave 4 and 5 alone
-+		 */
-+		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+		if (isp_fabric_mbox_cmd(isp, &mbs)) {
-+			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
-+				fcp->isp_loopstate = LOOP_PDB_RCVD;
-+			}
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
-+		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
-+		isp_get_gxn_id_response(isp, gs0, gs1);
-+		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
-+			isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
-+			    gs1->snscb_cthdr.ct_reason,
-+			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
-+			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+				FC_SCRATCH_RELEASE(isp);
-+				return (-1);
-+			}
-+			continue;
-+		}
-+		lcl.port_wwn = 
-+		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
-+		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
-+		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
-+		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
-+		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
-+		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
-+		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
-+		    (((u_int64_t)gs1->snscb_wwn[7]));
-+
-+		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
-+		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
-+		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
-+		gq->snscb_sblen = 6;
-+		gq->snscb_cmd = SNS_GNN_ID;
-+		gq->snscb_portid = lcl.portid;
-+		isp_put_gxn_id_request(isp, gq,
-+		    (sns_gxn_id_req_t *) fcp->isp_scratch);
-+		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
-+		mbs.param[0] = MBOX_SEND_SNS;
-+		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
-+		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+		/*
-+		 * Leave 4 and 5 alone
-+		 */
-+		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+		if (isp_fabric_mbox_cmd(isp, &mbs)) {
-+			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
-+				fcp->isp_loopstate = LOOP_PDB_RCVD;
-+			}
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
-+		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
-+		isp_get_gxn_id_response(isp, gs0, gs1);
-+		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
-+			isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
-+			    gs1->snscb_cthdr.ct_reason,
-+			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
-+			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+				FC_SCRATCH_RELEASE(isp);
-+				return (-1);
-+			}
-+			continue;
-+		}
-+		lcl.node_wwn = 
-+		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
-+		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
-+		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
-+		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
-+		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
-+		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
-+		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
-+		    (((u_int64_t)gs1->snscb_wwn[7]));
-+
-+		/*
-+		 * The QLogic f/w is bouncing this with a parameter error.
-+		 */
-+#if	0
-+		/*
-+		 * Try and get FC4 Features (FC-GS-3 only).
-+		 * We can use the sns_gxn_id_req_t for this request.
-+		 */
-+		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
-+		gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
-+		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
-+		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
-+		gq->snscb_sblen = 6;
-+		gq->snscb_cmd = SNS_GFF_ID;
-+		gq->snscb_portid = lcl.portid;
-+		isp_put_gxn_id_request(isp, gq,
-+		    (sns_gxn_id_req_t *) fcp->isp_scratch);
-+		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
-+		mbs.param[0] = MBOX_SEND_SNS;
-+		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
-+		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+		/*
-+		 * Leave 4 and 5 alone
-+		 */
-+		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+		if (isp_fabric_mbox_cmd(isp, &mbs)) {
-+			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
-+				fcp->isp_loopstate = LOOP_PDB_RCVD;
-+			}
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+			FC_SCRATCH_RELEASE(isp);
-+			return (-1);
-+		}
-+		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
-+		fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
-+		isp_get_gff_id_response(isp, fs0, fs1);
-+		if (fs1->snscb_cthdr.ct_response != FS_ACC) {
-+			isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
-+			    swrej, "GFF_ID",
-+			    fs1->snscb_cthdr.ct_reason,
-+			    fs1->snscb_cthdr.ct_explanation, lcl.portid);
-+			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
-+				FC_SCRATCH_RELEASE(isp);
-+				return (-1);
-+			}
-+		} else {
-+			int index = (ftype >> 3);
-+			int bshft = (ftype & 0x7) * 4;
-+			int fc4_fval =
-+			    (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
-+			if (fc4_fval & 0x1) {
-+				lcl.roles |=
-+				    (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
-+			}
-+			if (fc4_fval & 0x2) {
-+				lcl.roles |=
-+				    (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
-+			}
-+		}
-+#endif
-+
-+		/*
-+		 * If we really want to know what kind of port type this is,
-+		 * we have to run another CT command. Otherwise, we'll leave
-+		 * it as undefined.
-+		 *
-+		lcl.port_type = 0;
-+		 */
-+		if (rs1->snscb_ports[i].control & 0x80) {
-+			lcl.last_fabric_dev = 1;
-+		} else {
-+			lcl.last_fabric_dev = 0;
-+		}
-+		(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
-+
-+	} while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
-+
-+	/*
-+	 * If we're not at the last entry, our list isn't big enough.
-+	 */
-+	if ((rs1->snscb_ports[i].control & 0x80) == 0) {
-+		isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
-+	}
-+
-+	FC_SCRATCH_RELEASE(isp);
-+	fcp->isp_loopstate = LOOP_FSCAN_DONE;
-+	return (0);
-+}
-+#endif
-+
-+static void
-+isp_register_fc4_type(struct ispsoftc *isp)
-+{
-+	fcparam *fcp = isp->isp_param;
-+	u_int8_t local[SNS_RFT_ID_REQ_SIZE];
-+	sns_screq_t *reqp = (sns_screq_t *) local;
-+	mbreg_t mbs;
-+
-+	MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
-+	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
-+	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
-+	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
-+	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
-+	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
-+	reqp->snscb_sblen = 22;
-+	reqp->snscb_data[0] = SNS_RFT_ID;
-+	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
-+	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
-+	reqp->snscb_data[6] = (1 << FC4_SCSI);
-+#if	0
-+	reqp->snscb_data[6] |= (1 << FC4_IP);	/* ISO/IEC 8802-2 LLC/SNAP */
-+#endif
-+	FC_SCRATCH_ACQUIRE(isp);
-+	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
-+	mbs.param[0] = MBOX_SEND_SNS;
-+	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
-+	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-+	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-+	/*
-+	 * Leave 4 and 5 alone
-+	 */
-+	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-+	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-+	isp_mboxcmd(isp, &mbs, MBLOGALL);
-+	FC_SCRATCH_RELEASE(isp);
-+	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
-+	}
-+}
-+
-+/*
-+ * Start a command. Locking is assumed done in the caller.
-+ */
-+
-+int
-+isp_start(XS_T *xs)
-+{
-+	struct ispsoftc *isp;
-+	u_int16_t nxti, optr, handle;
-+	u_int8_t local[QENTRY_LEN];
-+	ispreq_t *reqp, *qep;
-+	int target, i;
-+
-+	XS_INITERR(xs);
-+	isp = XS_ISP(xs);
-+
-+	/*
-+	 * Check to make sure we're supporting initiator role.
-+	 */
-+	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
-+		XS_SETERR(xs, HBA_SELTIMEOUT);
-+		return (CMD_COMPLETE);
-+	}
-+
-+	/*
-+	 * Now make sure we're running.
-+	 */
-+
-+	if (isp->isp_state != ISP_RUNSTATE) {
-+		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
-+		XS_SETERR(xs, HBA_BOTCH);
-+		return (CMD_COMPLETE);
-+	}
-+
-+	/*
-+	 * Check command CDB length, etc.. We really are limited to 16 bytes
-+	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
-+	 * but probably only if we're running fairly new firmware (we'll
-+	 * let the old f/w choke on an extended command queue entry).
-+	 */
-+
-+	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "unsupported cdb length (%d, CDB[0]=0x%x)",
-+		    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
-+		XS_SETERR(xs, HBA_BOTCH);
-+		return (CMD_COMPLETE);
-+	}
-+
-+	/*
-+	 * Check to see whether we have good firmware state still or
-+	 * need to refresh our port database for this target.
-+	 */
-+	target = XS_TGT(xs);
-+	if (IS_FC(isp)) {
-+		fcparam *fcp = isp->isp_param;
-+		struct lportdb *lp;
-+#ifdef	HANDLE_LOOPSTATE_IN_OUTER_LAYERS
-+		if (fcp->isp_fwstate != FW_READY ||
-+		    fcp->isp_loopstate != LOOP_READY) {
-+			return (CMD_RQLATER);
-+		}
-+
-+		/*
-+		 * If we're not on a Fabric, we can't have a target
-+		 * above FL_PORT_ID-1.
-+		 *
-+		 * If we're on a fabric and *not* connected as an F-port,
-+		 * we can't have a target less than FC_SNS_ID+1. This
-+		 * keeps us from having to sort out the difference between
-+		 * local public loop devices and those which we might get
-+		 * from a switch's database.
-+		 */
-+		if (fcp->isp_onfabric == 0) {
-+			if (target >= FL_PORT_ID) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				return (CMD_COMPLETE);
-+			}
-+		} else {
-+			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				return (CMD_COMPLETE);
-+			}
-+			/*
-+			 * We used to exclude having local loop ports
-+			 * at the same time that we have fabric ports.
-+			 * That is, we used to exclude having ports
-+			 * at < FL_PORT_ID if we're FL-port.
-+			 *
-+			 * That's wrong. The only thing that could be
-+			 * dicey is if the switch you're connected to
-+			 * has these local loop ports appear on the
-+			 * fabric and we somehow attach them twice.
-+			 */
-+		}
-+#else
-+		/*
-+		 * Check for f/w being in ready state. If the f/w
-+		 * isn't in ready state, then we don't know our
-+		 * loop ID and the f/w hasn't completed logging
-+		 * into all targets on the loop. If this is the
-+		 * case, then bounce the command. We pretend this is
-+		 * a SELECTION TIMEOUT error if we've never gone to
-+		 * FW_READY state at all- in this case we may not
-+		 * be hooked to a loop at all and we shouldn't hang
-+		 * the machine for this. Otherwise, defer this command
-+		 * until later.
-+		 */
-+		if (fcp->isp_fwstate != FW_READY) {
-+			/*
-+			 * Give ourselves at most a 250ms delay.
-+			 */
-+			if (isp_fclink_test(isp, 250000)) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				if (fcp->loop_seen_once) {
-+					return (CMD_RQLATER);
-+				} else {
-+					return (CMD_COMPLETE);
-+				}
-+			}
-+		}
-+
-+		/*
-+		 * If we're not on a Fabric, we can't have a target
-+		 * above FL_PORT_ID-1.
-+		 *
-+		 * If we're on a fabric and *not* connected as an F-port,
-+		 * we can't have a target less than FC_SNS_ID+1. This
-+		 * keeps us from having to sort out the difference between
-+		 * local public loop devices and those which we might get
-+		 * from a switch's database.
-+		 */
-+		if (fcp->isp_onfabric == 0) {
-+			if (target >= FL_PORT_ID) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				return (CMD_COMPLETE);
-+			}
-+		} else {
-+			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				return (CMD_COMPLETE);
-+			}
-+			if (fcp->isp_topo != TOPO_F_PORT &&
-+			    target < FL_PORT_ID) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+				return (CMD_COMPLETE);
-+			}
-+		}
-+
-+		/*
-+		 * If our loop state is such that we haven't yet received
-+		 * a "Port Database Changed" notification (after a LIP or
-+		 * a Loop Reset or firmware initialization), then defer
-+		 * sending commands for a little while, but only if we've
-+		 * seen a valid loop at one point (otherwise we can get
-+		 * stuck at initialization time).
-+		 */
-+		if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
-+			XS_SETERR(xs, HBA_SELTIMEOUT);
-+			if (fcp->loop_seen_once) {
-+				return (CMD_RQLATER);
-+			} else {
-+				return (CMD_COMPLETE);
-+			}
-+		}
-+
-+		/*
-+		 * If we're in the middle of loop or fabric scanning
-+		 * or merging the port databases, retry this command later.
-+		 */
-+		if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
-+		    fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
-+		    fcp->isp_loopstate == LOOP_SYNCING_PDB) {
-+			return (CMD_RQLATER);
-+		}
-+
-+		/*
-+		 * If our loop state is now such that we've just now
-+		 * received a Port Database Change notification, then
-+		 * we have to go off and (re)scan the fabric. We back
-+		 * out and try again later if this doesn't work.
-+		 */
-+		if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
-+			if (isp_scan_fabric(isp, FC4_SCSI)) {
-+				return (CMD_RQLATER);
-+			}
-+			if (fcp->isp_fwstate != FW_READY ||
-+			    fcp->isp_loopstate < LOOP_FSCAN_DONE) {
-+				return (CMD_RQLATER);
-+			}
-+		}
-+
-+		/*
-+		 * If our loop state is now such that we've just now
-+		 * received a Port Database Change notification, then
-+		 * we have to go off and (re)synchronize our port
-+		 * database.
-+		 */
-+		if (fcp->isp_loopstate < LOOP_READY) {
-+			if (isp_pdb_sync(isp)) {
-+				return (CMD_RQLATER);
-+			}
-+			if (fcp->isp_fwstate != FW_READY ||
-+			    fcp->isp_loopstate != LOOP_READY) {
-+				return (CMD_RQLATER);
-+			}
-+		}
-+
-+		/*
-+		 * XXX: Here's were we would cancel any loop_dead flag
-+		 * XXX: also cancel in dead_loop timeout that's running
-+		 */
-+#endif
-+
-+		/*
-+		 * Now check whether we should even think about pursuing this.
-+		 */
-+		lp = &fcp->portdb[target];
-+		if (lp->valid == 0) {
-+			XS_SETERR(xs, HBA_SELTIMEOUT);
-+			return (CMD_COMPLETE);
-+		}
-+		if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
-+			isp_prt(isp, ISP_LOGDEBUG2,
-+			    "Target %d does not have target service", target);
-+			XS_SETERR(xs, HBA_SELTIMEOUT);
-+			return (CMD_COMPLETE);
-+		}
-+		/*
-+		 * Now turn target into what the actual Loop ID is.
-+		 */
-+		target = lp->loopid;
-+	}
-+
-+	/*
-+	 * Next check to see if any HBA or Device
-+	 * parameters need to be updated.
-+	 */
-+	if (isp->isp_update != 0) {
-+		isp_update(isp);
-+	}
-+
-+	if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
-+		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
-+		XS_SETERR(xs, HBA_BOTCH);
-+		return (CMD_EAGAIN);
-+	}
-+
-+	/*
-+	 * Now see if we need to synchronize the ISP with respect to anything.
-+	 * We do dual duty here (cough) for synchronizing for busses other
-+	 * than which we got here to send a command to.
-+	 */
-+	reqp = (ispreq_t *) local;
-+	if (isp->isp_sendmarker) {
-+		u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
-+		/*
-+		 * Check ports to send markers for...
-+		 */
-+		for (i = 0; i < n; i++) {
-+			if ((isp->isp_sendmarker & (1 << i)) == 0) {
-+				continue;
-+			}
-+			MEMZERO((void *) reqp, QENTRY_LEN);
-+			reqp->req_header.rqs_entry_count = 1;
-+			reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
-+			reqp->req_modifier = SYNC_ALL;
-+			reqp->req_target = i << 7;	/* insert bus number */
-+			isp_put_request(isp, reqp, qep);
-+			ISP_ADD_REQUEST(isp, nxti);
-+			isp->isp_sendmarker &= ~(1 << i);
-+			if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) {
-+				isp_prt(isp, ISP_LOGDEBUG0,
-+				    "Request Queue Overflow+");
-+				XS_SETERR(xs, HBA_BOTCH);
-+				return (CMD_EAGAIN);
-+			}
-+		}
-+	}
-+
-+	MEMZERO((void *)reqp, QENTRY_LEN);
-+	reqp->req_header.rqs_entry_count = 1;
-+	if (IS_FC(isp)) {
-+		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
-+	} else {
-+		if (XS_CDBLEN(xs) > 12)
-+			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
-+		else
-+			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
-+	}
-+	/* reqp->req_header.rqs_flags = 0; */
-+	/* reqp->req_header.rqs_seqno = 0; */
-+	if (IS_FC(isp)) {
-+		/*
-+		 * See comment in isp_intr
-+		 */
-+		/* XS_RESID(xs) = 0; */
-+
-+		/*
-+		 * Fibre Channel always requires some kind of tag.
-+		 * The Qlogic drivers seem be happy not to use a tag,
-+		 * but this breaks for some devices (IBM drives).
-+		 */
-+		if (XS_TAG_P(xs)) {
-+			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
-+		} else {
-+			/*
-+			 * If we don't know what tag to use, use HEAD OF QUEUE
-+			 * for Request Sense or Simple.
-+			 */
-+			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
-+				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
-+			else
-+				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
-+		}
-+	} else {
-+		sdparam *sdp = (sdparam *)isp->isp_param;
-+		sdp += XS_CHANNEL(xs);
-+		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
-+		    XS_TAG_P(xs)) {
-+			reqp->req_flags = XS_TAG_TYPE(xs);
-+		}
-+	}
-+	reqp->req_target = target | (XS_CHANNEL(xs) << 7);
-+	if (IS_SCSI(isp)) {
-+		reqp->req_lun_trn = XS_LUN(xs);
-+		reqp->req_cdblen = XS_CDBLEN(xs);
-+	} else {
-+		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
-+			((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
-+		else
-+			((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
-+	}
-+	MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
-+
-+	reqp->req_time = XS_TIME(xs) / 1000;
-+	if (reqp->req_time == 0 && XS_TIME(xs)) {
-+		reqp->req_time = 1;
-+	}
-+
-+	if (isp_save_xs(isp, xs, &handle)) {
-+		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
-+		XS_SETERR(xs, HBA_BOTCH);
-+		return (CMD_EAGAIN);
-+	}
-+	reqp->req_handle = handle;
-+
-+	/*
-+	 * Set up DMA and/or do any bus swizzling of the request entry
-+	 * so that the Qlogic F/W understands what is being asked of it.
-+	 */
-+	i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
-+	if (i != CMD_QUEUED) {
-+		isp_destroy_handle(isp, handle);
-+		/*
-+		 * dmasetup sets actual error in packet, and
-+		 * return what we were given to return.
-+		 */
-+		return (i);
-+	}
-+	XS_SETERR(xs, HBA_NOERROR);
-+	isp_prt(isp, ISP_LOGDEBUG2,
-+	    "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
-+	    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
-+	    (long) XS_XFRLEN(xs));
-+	ISP_ADD_REQUEST(isp, nxti);
-+	isp->isp_nactive++;
-+	return (CMD_QUEUED);
-+}
-+
-+/*
-+ * isp control
-+ * Locks (ints blocked) assumed held.
-+ */
-+
-+int
-+isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
-+{
-+	XS_T *xs;
-+	mbreg_t mbs;
-+	int bus, tgt;
-+	u_int16_t handle;
-+
-+	switch (ctl) {
-+	default:
-+		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
-+		break;
-+
-+	case ISPCTL_RESET_BUS:
-+		/*
-+		 * Issue a bus reset.
-+		 */
-+		mbs.param[0] = MBOX_BUS_RESET;
-+		mbs.param[2] = 0;
-+		if (IS_SCSI(isp)) {
-+			mbs.param[1] =
-+			    ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
-+			if (mbs.param[1] < 2)
-+				mbs.param[1] = 2;
-+			bus = *((int *) arg);
-+			if (IS_DUALBUS(isp))
-+				mbs.param[2] = bus;
-+		} else {
-+			mbs.param[1] = 10;
-+			bus = 0;
-+		}
-+		isp->isp_sendmarker |= (1 << bus);
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			break;
-+		}
-+		isp_prt(isp, ISP_LOGINFO,
-+		    "driver initiated bus reset of bus %d", bus);
-+		return (0);
-+
-+	case ISPCTL_RESET_DEV:
-+		tgt = (*((int *) arg)) & 0xffff;
-+		bus = (*((int *) arg)) >> 16;
-+		mbs.param[0] = MBOX_ABORT_TARGET;
-+		mbs.param[1] = (tgt << 8) | (bus << 15);
-+		mbs.param[2] = 3;	/* 'delay', in seconds */
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			break;
-+		}
-+		isp_prt(isp, ISP_LOGINFO,
-+		    "Target %d on Bus %d Reset Succeeded", tgt, bus);
-+		isp->isp_sendmarker |= (1 << bus);
-+		return (0);
-+
-+	case ISPCTL_ABORT_CMD:
-+		xs = (XS_T *) arg;
-+		tgt = XS_TGT(xs);
-+		handle = isp_find_handle(isp, xs);
-+		if (handle == 0) {
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "cannot find handle for command to abort");
-+			break;
-+		}
-+		bus = XS_CHANNEL(xs);
-+		mbs.param[0] = MBOX_ABORT;
-+		if (IS_FC(isp)) {
-+			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)  {
-+				mbs.param[1] = tgt << 8;
-+				mbs.param[4] = 0;
-+				mbs.param[5] = 0;
-+				mbs.param[6] = XS_LUN(xs);
-+			} else {
-+				mbs.param[1] = tgt << 8 | XS_LUN(xs);
-+			}
-+		} else {
-+			mbs.param[1] =
-+			    (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
-+		}
-+		mbs.param[3] = 0;
-+		mbs.param[2] = handle;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
-+		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+			return (0);
-+		}
-+		/*
-+		 * XXX: Look for command in the REQUEST QUEUE. That is,
-+		 * XXX: It hasen't been picked up by firmware yet.
-+		 */
-+		break;
-+
-+	case ISPCTL_UPDATE_PARAMS:
-+
-+		isp_update(isp);
-+		return (0);
-+
-+	case ISPCTL_FCLINK_TEST:
-+
-+		if (IS_FC(isp)) {
-+			int usdelay = (arg)? *((int *) arg) : 250000;
-+			return (isp_fclink_test(isp, usdelay));
-+		}
-+		break;
-+
-+	case ISPCTL_SCAN_FABRIC:
-+
-+		if (IS_FC(isp)) {
-+			int ftype = (arg)? *((int *) arg) : FC4_SCSI;
-+			return (isp_scan_fabric(isp, ftype));
-+		}
-+		break;
-+
-+	case ISPCTL_SCAN_LOOP:
-+
-+		if (IS_FC(isp)) {
-+			return (isp_scan_loop(isp));
-+		}
-+		break;
-+
-+	case ISPCTL_PDB_SYNC:
-+
-+		if (IS_FC(isp)) {
-+			return (isp_pdb_sync(isp));
-+		}
-+		break;
-+
-+	case ISPCTL_SEND_LIP:
-+
-+		if (IS_FC(isp)) {
-+			mbs.param[0] = MBOX_INIT_LIP;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL);
-+			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+				return (0);
-+			}
-+		}
-+		break;
-+
-+	case ISPCTL_GET_POSMAP:
-+
-+		if (IS_FC(isp) && arg) {
-+			return (isp_getmap(isp, arg));
-+		}
-+		break;
-+
-+	case ISPCTL_RUN_MBOXCMD:
-+
-+		isp_mboxcmd(isp, arg, MBLOGALL);
-+		return(0);
-+
-+#ifdef	ISP_TARGET_MODE
-+	case ISPCTL_TOGGLE_TMODE:
-+	{
-+
-+		/*
-+		 * We don't check/set against role here- that's the
-+		 * responsibility for the outer layer to coordinate.
-+		 */
-+		if (IS_SCSI(isp)) {
-+			int param = *(int *)arg;
-+			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
-+			mbs.param[1] = param & 0xffff;
-+			mbs.param[2] = param >> 16;
-+			isp_mboxcmd(isp, &mbs, MBLOGALL);
-+			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+				break;
-+			}
-+		}
-+		return (0);
-+	}
-+#endif
-+	}
-+	return (-1);
-+}
-+
-+/*
-+ * Interrupt Service Routine(s).
-+ *
-+ * External (OS) framework has done the appropriate locking,
-+ * and the locking will be held throughout this function.
-+ */
-+
-+/*
-+ * Limit our stack depth by sticking with the max likely number
-+ * of completions on a request queue at any one time.
-+ */
-+#ifndef	MAX_REQUESTQ_COMPLETIONS
-+#define	MAX_REQUESTQ_COMPLETIONS	64
-+#endif
-+
-+void
-+isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
-+{
-+	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
-+	u_int16_t iptr, optr, junk;
-+	int i, nlooked = 0, ndone = 0;
-+
-+again:
-+	/*
-+	 * Is this a mailbox related interrupt?
-+	 * The mailbox semaphore will be nonzero if so.
-+	 */
-+	if (sema) {
-+		if (mbox & 0x4000) {
-+			isp->isp_intmboxc++;
-+			if (isp->isp_mboxbsy) {
-+				int i = 0, obits = isp->isp_obits;
-+				isp->isp_mboxtmp[i++] = mbox;
-+				for (i = 1; i < MAX_MAILBOX; i++) {
-+					if ((obits & (1 << i)) == 0) {
-+						continue;
-+					}
-+					isp->isp_mboxtmp[i] =
-+					    ISP_READ(isp, MBOX_OFF(i));
-+				}
-+				if (isp->isp_mbxwrk0) {
-+					if (isp_mbox_continue(isp) == 0) {
-+						return;
-+					}
-+				}
-+				MBOX_NOTIFY_COMPLETE(isp);
-+			} else {
-+				isp_prt(isp, ISP_LOGWARN,
-+				    "Mbox Command Async (0x%x) with no waiters",
-+				    mbox);
-+			}
-+		} else if (isp_parse_async(isp, mbox) < 0) {
-+			return;
-+		}
-+		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
-+		    isp->isp_state != ISP_RUNSTATE) {
-+			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+			ISP_WRITE(isp, BIU_SEMA, 0);
-+			return;
-+		}
-+	}
-+
-+	/*
-+	 * We can't be getting this now.
-+	 */
-+	if (isp->isp_state != ISP_RUNSTATE) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
-+		/*
-+		 * Thank you very much!  *Burrrp*!
-+		 */
-+		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
-+		    READ_RESPONSE_QUEUE_IN_POINTER(isp));
-+
-+		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+		ISP_WRITE(isp, BIU_SEMA, 0);
-+		return;
-+	}
-+
-+	/*
-+	 * Get the current Response Queue Out Pointer.
-+	 *
-+	 * If we're a 2300, we can ask what hardware what it thinks.
-+	 */
-+	if (IS_23XX(isp)) {
-+		optr = ISP_READ(isp, isp->isp_respoutrp);
-+		/*
-+		 * Debug: to be taken out eventually
-+		 */
-+		if (isp->isp_residx != optr) {
-+			isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
-+			    optr, isp->isp_residx);
-+		}
-+	} else {
-+		optr = isp->isp_residx;
-+	}
-+
-+	/*
-+	 * You *must* read the Response Queue In Pointer
-+	 * prior to clearing the RISC interrupt.
-+	 *
-+	 * Debounce the 2300 if revision less than 2.
-+	 */
-+	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
-+		i = 0;
-+		do {
-+			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
-+			junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
-+		} while (junk != iptr && ++i < 1000);
-+
-+		if (iptr != junk) {
-+			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "Response Queue Out Pointer Unstable (%x, %x)",
-+			    iptr, junk);
-+			return;
-+		}
-+	} else {
-+		iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
-+	}
-+	isp->isp_resodx = iptr;
-+
-+
-+	if (optr == iptr && sema == 0) {
-+		/*
-+		 * There are a lot of these- reasons unknown- mostly on
-+		 * faster Alpha machines.
-+		 *
-+		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
-+		 * make sure the old interrupt went away (to avoid 'ringing'
-+		 * effects), but that didn't stop this from occurring.
-+		 */
-+		if (IS_23XX(isp)) {
-+			USEC_DELAY(100);
-+			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
-+			junk = ISP_READ(isp, BIU_R2HSTSLO);
-+		} else {
-+			junk = ISP_READ(isp, BIU_ISR);
-+		}
-+		if (optr == iptr) {
-+			if (IS_23XX(isp)) {
-+				;
-+			} else {
-+				sema = ISP_READ(isp, BIU_SEMA);
-+				mbox = ISP_READ(isp, OUTMAILBOX0);
-+				if ((sema & 0x3) && (mbox & 0x8000)) {
-+					goto again;
-+				}
-+			}
-+			isp->isp_intbogus++;
-+			isp_prt(isp, ISP_LOGDEBUG1,
-+			    "bogus intr- isr %x (%x) iptr %x optr %x",
-+			    isr, junk, iptr, optr);
-+		}
-+	}
-+	isp->isp_resodx = iptr;
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+	ISP_WRITE(isp, BIU_SEMA, 0);
-+
-+	if (isp->isp_rspbsy) {
-+		return;
-+	}
-+	isp->isp_rspbsy = 1;
-+
-+	while (optr != iptr) {
-+		ispstatusreq_t local, *sp = &local;
-+		isphdr_t *hp;
-+		int type;
-+		u_int16_t oop;
-+		int buddaboom = 0;
-+
-+		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
-+		oop = optr;
-+		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
-+		nlooked++;
-+		/*
-+		 * Synchronize our view of this response queue entry.
-+		 */
-+		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
-+
-+		type = isp_get_response_type(isp, hp);
-+
-+		if (type == RQSTYPE_RESPONSE) {
-+			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
-+		} else if (type == RQSTYPE_RIO2) {
-+			isp_rio2_t rio;
-+			isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
-+			for (i = 0; i < rio.req_header.rqs_seqno; i++) {
-+				isp_fastpost_complete(isp, rio.req_handles[i]);
-+			}
-+			if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
-+				isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
-+			MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+			continue;
-+		} else {
-+			/*
-+			 * Somebody reachable via isp_handle_other_response
-+			 * may have updated the response queue pointers for
-+			 * us, so we reload our goal index.
-+			 */
-+			if (isp_handle_other_response(isp, type, hp, &optr)) {
-+				iptr = isp->isp_resodx;
-+				MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+				continue;
-+			}
-+
-+			/*
-+			 * After this point, we'll just look at the header as
-+			 * we don't know how to deal with the rest of the
-+			 * response.
-+			 */
-+			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
-+
-+			/*
-+			 * It really has to be a bounced request just copied
-+			 * from the request queue to the response queue. If
-+			 * not, something bad has happened.
-+			 */
-+			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
-+				isp_prt(isp, ISP_LOGERR, notresp,
-+				    sp->req_header.rqs_entry_type, oop, optr,
-+				    nlooked);
-+				if (isp->isp_dblev & ISP_LOGDEBUG0) {
-+					isp_print_bytes(isp, "Queue Entry",
-+					    QENTRY_LEN, sp);
-+				}
-+				MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+				continue;
-+			}
-+			buddaboom = 1;
-+		}
-+
-+		if (sp->req_header.rqs_flags & 0xf) {
-+#define	_RQS_OFLAGS	\
-+	~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
-+			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
-+				isp_prt(isp, ISP_LOGWARN,
-+				    "continuation segment");
-+				WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
-+				continue;
-+			}
-+			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
-+				isp_prt(isp, ISP_LOGDEBUG1,
-+				    "internal queues full");
-+				/*
-+				 * We'll synthesize a QUEUE FULL message below.
-+				 */
-+			}
-+			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
-+				isp_prt(isp, ISP_LOGERR,  "bad header flag");
-+				buddaboom++;
-+			}
-+			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
-+				isp_prt(isp, ISP_LOGERR, "bad request packet");
-+				buddaboom++;
-+			}
-+			if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
-+				isp_prt(isp, ISP_LOGERR,
-+				    "unknown flags (0x%x) in response",
-+				    sp->req_header.rqs_flags);
-+				buddaboom++;
-+			}
-+#undef	_RQS_OFLAGS
-+		}
-+		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
-+			MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+			isp_prt(isp, ISP_LOGERR,
-+			    "bad request handle %d (type 0x%x, flags 0x%x)",
-+			    sp->req_handle, sp->req_header.rqs_entry_type,
-+			    sp->req_header.rqs_flags);
-+			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
-+			continue;
-+		}
-+		xs = isp_find_xs(isp, sp->req_handle);
-+		if (xs == NULL) {
-+			u_int8_t ts = sp->req_completion_status & 0xff;
-+			MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+			/*
-+			 * Only whine if this isn't the expected fallout of
-+			 * aborting the command.
-+			 */
-+			if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
-+				isp_prt(isp, ISP_LOGERR,
-+				    "cannot find handle 0x%x (type 0x%x)",
-+				    sp->req_handle,
-+				    sp->req_header.rqs_entry_type);
-+			} else if (ts != RQCS_ABORTED) {
-+				isp_prt(isp, ISP_LOGERR,
-+				    "cannot find handle 0x%x (status 0x%x)",
-+				    sp->req_handle, ts);
-+			}
-+			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
-+			continue;
-+		}
-+		isp_destroy_handle(isp, sp->req_handle);
-+		if (sp->req_status_flags & RQSTF_BUS_RESET) {
-+			XS_SETERR(xs, HBA_BUSRESET);
-+			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
-+		}
-+		if (buddaboom) {
-+			XS_SETERR(xs, HBA_BOTCH);
-+		}
-+
-+		if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
-+			/*
-+			 * Fibre Channel F/W doesn't say we got status
-+			 * if there's Sense Data instead. I guess they
-+			 * think it goes w/o saying.
-+			 */
-+			sp->req_state_flags |= RQSF_GOT_STATUS;
-+		}
-+		if (sp->req_state_flags & RQSF_GOT_STATUS) {
-+			*XS_STSP(xs) = sp->req_scsi_status & 0xff;
-+		}
-+
-+		switch (sp->req_header.rqs_entry_type) {
-+		case RQSTYPE_RESPONSE:
-+			XS_SET_STATE_STAT(isp, xs, sp);
-+			isp_parse_status(isp, sp, xs);
-+			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
-+			    (*XS_STSP(xs) == SCSI_BUSY)) {
-+				XS_SETERR(xs, HBA_TGTBSY);
-+			}
-+			if (IS_SCSI(isp)) {
-+				XS_RESID(xs) = sp->req_resid;
-+				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
-+				    (*XS_STSP(xs) == SCSI_CHECK) &&
-+				    (sp->req_state_flags & RQSF_GOT_SENSE)) {
-+					XS_SAVE_SENSE(xs, sp);
-+				}
-+				/*
-+				 * A new synchronous rate was negotiated for
-+				 * this target. Mark state such that we'll go
-+				 * look up that which has changed later.
-+				 */
-+				if (sp->req_status_flags & RQSTF_NEGOTIATION) {
-+					int t = XS_TGT(xs);
-+					sdparam *sdp = isp->isp_param;
-+					sdp += XS_CHANNEL(xs);
-+					sdp->isp_devparam[t].dev_refresh = 1;
-+					isp->isp_update |=
-+					    (1 << XS_CHANNEL(xs));
-+				}
-+			} else {
-+				if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
-+					XS_RESID(xs) = 0;
-+				} else if (sp->req_scsi_status & RQCS_RESID) {
-+					XS_RESID(xs) = sp->req_resid;
-+				} else {
-+					XS_RESID(xs) = 0;
-+				}
-+				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
-+				    (*XS_STSP(xs) == SCSI_CHECK) &&
-+				    (sp->req_scsi_status & RQCS_SV)) {
-+					XS_SAVE_SENSE(xs, sp);
-+					/* solely for the benefit of debug */
-+					sp->req_state_flags |= RQSF_GOT_SENSE;
-+				}
-+			}
-+			isp_prt(isp, ISP_LOGDEBUG2,
-+			   "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
-+			   (long) sp->req_resid);
-+			break;
-+		case RQSTYPE_REQUEST:
-+			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
-+				/*
-+				 * Force Queue Full status.
-+				 */
-+				*XS_STSP(xs) = SCSI_QFULL;
-+				XS_SETERR(xs, HBA_NOERROR);
-+			} else if (XS_NOERR(xs)) {
-+				/*
-+				 * ????
-+				 */
-+				isp_prt(isp, ISP_LOGDEBUG0,
-+				    "Request Queue Entry bounced back");
-+				XS_SETERR(xs, HBA_BOTCH);
-+			}
-+			XS_RESID(xs) = XS_XFRLEN(xs);
-+			break;
-+		default:
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "unhandled response queue type 0x%x",
-+			    sp->req_header.rqs_entry_type);
-+			if (XS_NOERR(xs)) {
-+				XS_SETERR(xs, HBA_BOTCH);
-+			}
-+			break;
-+		}
-+
-+		/*
-+		 * Free any dma resources. As a side effect, this may
-+		 * also do any cache flushing necessary for data coherence.			 */
-+		if (XS_XFRLEN(xs)) {
-+			ISP_DMAFREE(isp, xs, sp->req_handle);
-+		}
-+
-+		if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
-+		    ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
-+		    (*XS_STSP(xs) != SCSI_GOOD)))) {
-+			char skey;
-+			if (sp->req_state_flags & RQSF_GOT_SENSE) {
-+				skey = XS_SNSKEY(xs) & 0xf;
-+				if (skey < 10)
-+					skey += '0';
-+				else
-+					skey += 'a' - 10;
-+			} else if (*XS_STSP(xs) == SCSI_CHECK) {
-+				skey = '?';
-+			} else {
-+				skey = '.';
-+			}
-+			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
-+			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
-+			    *XS_STSP(xs), skey, XS_ERR(xs));
-+		}
-+
-+		if (isp->isp_nactive > 0)
-+		    isp->isp_nactive--;
-+		complist[ndone++] = xs;	/* defer completion call until later */
-+		MEMZERO(hp, QENTRY_LEN);	/* PERF */
-+		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
-+			break;
-+		}
-+	}
-+
-+	/*
-+	 * If we looked at any commands, then it's valid to find out
-+	 * what the outpointer is. It also is a trigger to update the
-+	 * ISP's notion of what we've seen so far.
-+	 */
-+	if (nlooked) {
-+		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
-+		/*
-+		 * While we're at it, read the requst queue out pointer.
-+		 */
-+		isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
-+		if (isp->isp_rscchiwater < ndone)
-+			isp->isp_rscchiwater = ndone;
-+	}
-+
-+	isp->isp_residx = optr;
-+	isp->isp_rspbsy = 0;
-+	for (i = 0; i < ndone; i++) {
-+		xs = complist[i];
-+		if (xs) {
-+			isp->isp_rsltccmplt++;
-+			isp_done(xs);
-+		}
-+	}
-+}
-+
-+/*
-+ * Support routines.
-+ */
-+
-+static int
-+isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
-+{
-+	int rval = 0;
-+	int bus;
-+
-+	if (IS_DUALBUS(isp)) {
-+		bus = ISP_READ(isp, OUTMAILBOX6);
-+	} else {
-+		bus = 0;
-+	}
-+	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
-+
-+	switch (mbox) {
-+	case ASYNC_BUS_RESET:
-+		isp->isp_sendmarker |= (1 << bus);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
-+		break;
-+	case ASYNC_SYSTEM_ERROR:
-+#ifdef	ISP_FW_CRASH_DUMP
-+		/*
-+		 * If we have crash dumps enabled, it's up to the handler
-+		 * for isp_async to reinit stuff and restart the firmware
-+		 * after performing the crash dump. The reason we do things
-+		 * this way is that we may need to activate a kernel thread
-+		 * to do all the crash dump goop.
-+		 */
-+		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-+#else
-+		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-+		isp_reinit(isp);
-+		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-+#endif
-+		rval = -1;
-+		break;
-+
-+	case ASYNC_RQS_XFER_ERR:
-+		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
-+		break;
-+
-+	case ASYNC_RSP_XFER_ERR:
-+		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
-+		break;
-+
-+	case ASYNC_QWAKEUP:
-+		/*
-+		 * We've just been notified that the Queue has woken up.
-+		 * We don't need to be chatty about this- just unlatch things
-+		 * and move on.
-+		 */
-+		mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
-+		break;
-+
-+	case ASYNC_TIMEOUT_RESET:
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "timeout initiated SCSI bus reset of bus %d", bus);
-+		isp->isp_sendmarker |= (1 << bus);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		break;
-+
-+	case ASYNC_DEVICE_RESET:
-+		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
-+		isp->isp_sendmarker |= (1 << bus);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		break;
-+
-+	case ASYNC_EXTMSG_UNDERRUN:
-+		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
-+		break;
-+
-+	case ASYNC_SCAM_INT:
-+		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
-+		break;
-+
-+	case ASYNC_HUNG_SCSI:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "stalled SCSI Bus after DATA Overrun");
-+		/* XXX: Need to issue SCSI reset at this point */
-+		break;
-+
-+	case ASYNC_KILLED_BUS:
-+		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
-+		break;
-+
-+	case ASYNC_BUS_TRANSIT:
-+		mbox = ISP_READ(isp, OUTMAILBOX2);
-+		switch (mbox & 0x1c00) {
-+		case SXP_PINS_LVD_MODE:
-+			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
-+			SDPARAM(isp)->isp_diffmode = 0;
-+			SDPARAM(isp)->isp_ultramode = 0;
-+			SDPARAM(isp)->isp_lvdmode = 1;
-+			break;
-+		case SXP_PINS_HVD_MODE:
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "Transition to Differential mode");
-+			SDPARAM(isp)->isp_diffmode = 1;
-+			SDPARAM(isp)->isp_ultramode = 0;
-+			SDPARAM(isp)->isp_lvdmode = 0;
-+			break;
-+		case SXP_PINS_SE_MODE:
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "Transition to Single Ended mode");
-+			SDPARAM(isp)->isp_diffmode = 0;
-+			SDPARAM(isp)->isp_ultramode = 1;
-+			SDPARAM(isp)->isp_lvdmode = 0;
-+			break;
-+		default:
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "Transition to Unknown Mode 0x%x", mbox);
-+			break;
-+		}
-+		/*
-+		 * XXX: Set up to renegotiate again!
-+		 */
-+		/* Can only be for a 1080... */
-+		isp->isp_sendmarker |= (1 << bus);
-+		break;
-+
-+	/*
-+	 * We can use bus, which will always be zero for FC cards,
-+	 * as a mailbox pattern accumulator to be checked below.
-+	 */
-+	case ASYNC_RIO5:
-+		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
-+		break;
-+
-+	case ASYNC_RIO4:
-+		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
-+		break;
-+
-+	case ASYNC_RIO3:
-+		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
-+		break;
-+
-+	case ASYNC_RIO2:
-+		bus = 0x106;	/* outgoing mailbox regs 1-2 */
-+		break;
-+
-+	case ASYNC_RIO1:
-+	case ASYNC_CMD_CMPLT:
-+		bus = 0x102;	/* outgoing mailbox regs 1 */
-+		break;
-+
-+	case ASYNC_RIO_RESP:
-+		return (rval);
-+
-+	case ASYNC_CTIO_DONE:
-+	{
-+#ifdef	ISP_TARGET_MODE
-+		int handle =
-+		    (ISP_READ(isp, OUTMAILBOX2) << 16) | 
-+		    (ISP_READ(isp, OUTMAILBOX1));
-+		if (isp_target_async(isp, handle, mbox))
-+			rval = -1;
-+#else
-+		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
-+#endif
-+		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
-+		break;
-+	}
-+	case ASYNC_LIP_F8:
-+	case ASYNC_LIP_OCCURRED:
-+		FCPARAM(isp)->isp_lipseq =
-+		    ISP_READ(isp, OUTMAILBOX1);
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
-+		isp->isp_sendmarker = 1;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_LIP, NULL);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		/*
-+		 * We've had problems with data corruption occuring on
-+		 * commands that complete (with no apparent error) after
-+		 * we receive a LIP. This has been observed mostly on
-+		 * Local Loop topologies. To be safe, let's just mark
-+		 * all active commands as dead.
-+		 */
-+		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
-+		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
-+			int i, j;
-+			for (i = j = 0; i < isp->isp_maxcmds; i++) {
-+				XS_T *xs;
-+				xs = isp->isp_xflist[i];
-+				if (xs != NULL) {
-+					j++;
-+					XS_SETERR(xs, HBA_BUSRESET);
-+				}
-+			}
-+			if (j) {
-+				isp_prt(isp, ISP_LOGERR,
-+				    "LIP destroyed %d active commands", j);
-+			}
-+		}
-+		break;
-+
-+	case ASYNC_LOOP_UP:
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		break;
-+
-+	case ASYNC_LOOP_DOWN:
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		break;
-+
-+	case ASYNC_LOOP_RESET:
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		break;
-+
-+	case ASYNC_PDB_CHANGED:
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
-+		break;
-+
-+	case ASYNC_CHANGE_NOTIFY:
-+		/*
-+		 * Not correct, but it will force us to rescan the loop.
-+		 */
-+		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
-+		break;
-+
-+	case ASYNC_PTPMODE:
-+		if (FCPARAM(isp)->isp_onfabric)
-+			FCPARAM(isp)->isp_topo = TOPO_F_PORT;
-+		else
-+			FCPARAM(isp)->isp_topo = TOPO_N_PORT;
-+		isp_mark_getpdb_all(isp);
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
-+		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_async(isp, bus, mbox))
-+			rval = -1;
-+#endif
-+		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
-+		break;
-+
-+	case ASYNC_CONNMODE:
-+		mbox = ISP_READ(isp, OUTMAILBOX1);
-+		isp_mark_getpdb_all(isp);
-+		switch (mbox) {
-+		case ISP_CONN_LOOP:
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "Point-to-Point -> Loop mode");
-+			break;
-+		case ISP_CONN_PTP:
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "Loop -> Point-to-Point mode");
-+			break;
-+		case ISP_CONN_BADLIP:
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "Point-to-Point -> Loop mode (BAD LIP)");
-+			break;
-+		case ISP_CONN_FATAL:
-+			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
-+#ifdef	ISP_FW_CRASH_DUMP
-+			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-+#else
-+			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-+			isp_reinit(isp);
-+			isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-+#endif
-+			return (-1);
-+		case ISP_CONN_LOOPBACK:
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "Looped Back in Point-to-Point mode");
-+			break;
-+		default:
-+			isp_prt(isp, ISP_LOGWARN,
-+			    "Unknown connection mode (0x%x)", mbox);
-+			break;
-+		}
-+		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
-+		break;
-+
-+	default:
-+		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
-+		break;
-+	}
-+
-+	if (bus & 0x100) {
-+		int i, nh;
-+		u_int16_t handles[5];
-+
-+		for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
-+			if ((bus & (1 << i)) == 0) {
-+				continue;
-+			}
-+			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
-+		}
-+		for (i = 0; i < nh; i++) {
-+			isp_fastpost_complete(isp, handles[i]);
-+			isp_prt(isp,  ISP_LOGDEBUG3,
-+			    "fast post completion of %u", handles[i]);
-+		}
-+		if (isp->isp_fpcchiwater < nh)
-+			isp->isp_fpcchiwater = nh;
-+	} else {
-+		isp->isp_intoasync++;
-+	}
-+	return (rval);
-+}
-+
-+/*
-+ * Handle other response entries. A pointer to the request queue output
-+ * index is here in case we want to eat several entries at once, although
-+ * this is not used currently.
-+ */
-+
-+static int
-+isp_handle_other_response(struct ispsoftc *isp, int type,
-+    isphdr_t *hp, u_int16_t *optrp)
-+{
-+	switch (type) {
-+	case RQSTYPE_STATUS_CONT:
-+		isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
-+		return (1);
-+	case RQSTYPE_ATIO:
-+	case RQSTYPE_CTIO:
-+	case RQSTYPE_ENABLE_LUN:
-+	case RQSTYPE_MODIFY_LUN:
-+	case RQSTYPE_NOTIFY:
-+	case RQSTYPE_NOTIFY_ACK:
-+	case RQSTYPE_CTIO1:
-+	case RQSTYPE_ATIO2:
-+	case RQSTYPE_CTIO2:
-+	case RQSTYPE_CTIO3:
-+		isp->isp_rsltccmplt++;	/* count as a response completion */
-+#ifdef	ISP_TARGET_MODE
-+		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
-+			return (1);
-+		}
-+#endif
-+		/* FALLTHROUGH */
-+	case RQSTYPE_REQUEST:
-+	default:
-+		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
-+			return (1);
-+		}
-+		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
-+		    isp_get_response_type(isp, hp));
-+		return (0);
-+	}
-+}
-+
-+static void
-+isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
-+{
-+	switch (sp->req_completion_status & 0xff) {
-+	case RQCS_COMPLETE:
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_NOERROR);
-+		}
-+		return;
-+
-+	case RQCS_INCOMPLETE:
-+		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
-+			isp_prt(isp, ISP_LOGDEBUG1,
-+			    "Selection Timeout for %d.%d.%d",
-+			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+			if (XS_NOERR(xs)) {
-+				XS_SETERR(xs, HBA_SELTIMEOUT);
-+			}
-+			return;
-+		}
-+		isp_prt(isp, ISP_LOGERR,
-+		    "command incomplete for %d.%d.%d, state 0x%x",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
-+		    sp->req_state_flags);
-+		break;
-+
-+	case RQCS_DMA_ERROR:
-+		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_TRANSPORT_ERROR:
-+	{
-+		char buf[172];
-+		SNPRINTF(buf, sizeof (buf), "states=>");
-+		if (sp->req_state_flags & RQSF_GOT_BUS) {
-+			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_GOT_TARGET) {
-+			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_SENT_CDB) {
-+			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_XFRD_DATA) {
-+			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_GOT_STATUS) {
-+			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_GOT_SENSE) {
-+			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
-+		}
-+		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
-+			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
-+		}
-+		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
-+		if (sp->req_status_flags & RQSTF_DISCONNECT) {
-+			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
-+			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
-+			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_BUS_RESET) {
-+			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
-+			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_ABORTED) {
-+			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_TIMEOUT) {
-+			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
-+		}
-+		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
-+			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
-+		}
-+		isp_prt(isp, ISP_LOGERR, "%s", buf);
-+		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
-+		break;
-+	}
-+	case RQCS_RESET_OCCURRED:
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "bus reset destroyed command for %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_BUSRESET);
-+		}
-+		return;
-+
-+	case RQCS_ABORTED:
-+		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_ABORTED);
-+		}
-+		return;
-+
-+	case RQCS_TIMEOUT:
-+		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		/*
-+	 	 * Check to see if we logged out the device.
-+		 */
-+		if (IS_FC(isp)) {
-+			if ((sp->req_completion_status & RQSTF_LOGOUT) &&
-+			    FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
-+			    FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
-+				FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
-+			}
-+		}
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_CMDTIMEOUT);
-+		}
-+		return;
-+
-+	case RQCS_DATA_OVERRUN:
-+		XS_RESID(xs) = sp->req_resid;
-+		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_DATAOVR);
-+		}
-+		return;
-+
-+	case RQCS_COMMAND_OVERRUN:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "command overrun for command on %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_STATUS_OVERRUN:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "status overrun for command on %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_BAD_MESSAGE:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "msg not COMMAND COMPLETE after status %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_NO_MESSAGE_OUT:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "No MESSAGE OUT phase after selection on %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_EXT_ID_FAILED:
-+		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_IDE_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_ABORT_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_REJECT_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_NOP_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_PARITY_ERROR_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_DEVICE_RESET_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "BUS DEVICE RESET rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_ID_MSG_FAILED:
-+		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_UNEXP_BUS_FREE:
-+		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_DATA_UNDERRUN:
-+	{
-+		if (IS_FC(isp)) {
-+			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
-+			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
-+				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
-+				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
-+				    (ru_marked)? "marked" : "not marked");
-+				if (XS_NOERR(xs)) {
-+					XS_SETERR(xs, HBA_BOTCH);
-+				}
-+				return;
-+			}
-+		}
-+		XS_RESID(xs) = sp->req_resid;
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_NOERROR);
-+		}
-+		return;
-+	}
-+
-+	case RQCS_XACT_ERR1:
-+		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
-+		    XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_XACT_ERR2:
-+		isp_prt(isp, ISP_LOGERR, xact2,
-+		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
-+		break;
-+
-+	case RQCS_XACT_ERR3:
-+		isp_prt(isp, ISP_LOGERR, xact3,
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_BAD_ENTRY:
-+		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
-+		break;
-+
-+	case RQCS_QUEUE_FULL:
-+		isp_prt(isp, ISP_LOGDEBUG0,
-+		    "internal queues full for %d.%d.%d status 0x%x",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
-+
-+		/*
-+		 * If QFULL or some other status byte is set, then this
-+		 * isn't an error, per se.
-+		 *
-+		 * Unfortunately, some QLogic f/w writers have, in
-+		 * some cases, ommitted to *set* status to QFULL.
-+		 *
-+
-+		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_NOERROR);
-+			return;
-+		}
-+
-+		 *
-+		 *
-+		 */
-+
-+		*XS_STSP(xs) = SCSI_QFULL;
-+		XS_SETERR(xs, HBA_NOERROR);
-+		return;
-+
-+	case RQCS_PHASE_SKIPPED:
-+		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
-+		    XS_TGT(xs), XS_LUN(xs));
-+		break;
-+
-+	case RQCS_ARQS_FAILED:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Auto Request Sense failed for %d.%d.%d",
-+		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_ARQFAIL);
-+		}
-+		return;
-+
-+	case RQCS_WIDE_FAILED:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Wide Negotiation failed for %d.%d.%d",
-+		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
-+		if (IS_SCSI(isp)) {
-+			sdparam *sdp = isp->isp_param;
-+			sdp += XS_CHANNEL(xs);
-+			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
-+			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
-+			isp->isp_update |= (1 << XS_CHANNEL(xs));
-+		}
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_NOERROR);
-+		}
-+		return;
-+
-+	case RQCS_SYNCXFER_FAILED:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "SDTR Message failed for target %d.%d.%d",
-+		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
-+		if (IS_SCSI(isp)) {
-+			sdparam *sdp = isp->isp_param;
-+			sdp += XS_CHANNEL(xs);
-+			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
-+			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
-+			isp->isp_update |= (1 << XS_CHANNEL(xs));
-+		}
-+		break;
-+
-+	case RQCS_LVD_BUSERR:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Bad LVD condition while talking to %d.%d.%d",
-+		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
-+		break;
-+
-+	case RQCS_PORT_UNAVAILABLE:
-+		/*
-+		 * No such port on the loop. Moral equivalent of SELTIMEO
-+		 */
-+	case RQCS_PORT_LOGGED_OUT:
-+		/*
-+		 * It was there (maybe)- treat as a selection timeout.
-+		 */
-+		if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "port unavailable for target %d", XS_TGT(xs));
-+		else
-+			isp_prt(isp, ISP_LOGINFO,
-+			    "port logout for target %d", XS_TGT(xs));
-+		/*
-+		 * If we're on a local loop, force a LIP (which is overkill)
-+		 * to force a re-login of this unit. If we're on fabric,
-+		 * then we'll have to relogin as a matter of course.
-+		 */
-+		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
-+		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
-+			mbreg_t mbs;
-+			mbs.param[0] = MBOX_INIT_LIP;
-+			isp_mboxcmd_qnw(isp, &mbs, 1);
-+		}
-+
-+		/*
-+		 * Probably overkill.
-+		 */
-+		isp->isp_sendmarker = 1;
-+		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
-+		isp_mark_getpdb_all(isp);
-+		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_SELTIMEOUT);
-+		}
-+		return;
-+
-+	case RQCS_PORT_CHANGED:
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "port changed for target %d", XS_TGT(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_SELTIMEOUT);
-+		}
-+		return;
-+
-+	case RQCS_PORT_BUSY:
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "port busy for target %d", XS_TGT(xs));
-+		if (XS_NOERR(xs)) {
-+			XS_SETERR(xs, HBA_TGTBSY);
-+		}
-+		return;
-+
-+	default:
-+		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
-+		    sp->req_completion_status);
-+		break;
-+	}
-+	if (XS_NOERR(xs)) {
-+		XS_SETERR(xs, HBA_BOTCH);
-+	}
-+}
-+
-+static void
-+isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
-+{
-+	XS_T *xs;
-+
-+	if (fph == 0) {
-+		return;
-+	}
-+	xs = isp_find_xs(isp, fph);
-+	if (xs == NULL) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "Command for fast post handle 0x%x not found", fph);
-+		return;
-+	}
-+	isp_destroy_handle(isp, fph);
-+
-+	/*
-+	 * Since we don't have a result queue entry item,
-+	 * we must believe that SCSI status is zero and
-+	 * that all data transferred.
-+	 */
-+	XS_SET_STATE_STAT(isp, xs, NULL);
-+	XS_RESID(xs) = 0;
-+	*XS_STSP(xs) = SCSI_GOOD;
-+	if (XS_XFRLEN(xs)) {
-+		ISP_DMAFREE(isp, xs, fph);
-+	}
-+	if (isp->isp_nactive)
-+		isp->isp_nactive--;
-+	isp->isp_fphccmplt++;
-+	isp_done(xs);
-+}
-+
-+static int
-+isp_mbox_continue(struct ispsoftc *isp)
-+{
-+	mbreg_t mbs;
-+	u_int16_t *ptr;
-+
-+	switch (isp->isp_lastmbxcmd) {
-+	case MBOX_WRITE_RAM_WORD:
-+	case MBOX_READ_RAM_WORD:
-+	case MBOX_READ_RAM_WORD_EXTENDED:
-+		break;
-+	default:
-+		return (1);
-+	}
-+	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
-+		isp->isp_mbxwrk0 = 0;
-+		return (-1);
-+	}
-+
-+
-+	/*
-+	 * Clear the previous interrupt.
-+	 */
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+	ISP_WRITE(isp, BIU_SEMA, 0);
-+
-+	/*
-+	 * Continue with next word.
-+	 */
-+	ptr = isp->isp_mbxworkp;
-+	switch (isp->isp_lastmbxcmd) {
-+	case MBOX_WRITE_RAM_WORD:
-+		mbs.param[2] = *ptr++;
-+		mbs.param[1] = isp->isp_mbxwrk1++;
-+		break;
-+	case MBOX_READ_RAM_WORD:
-+	case MBOX_READ_RAM_WORD_EXTENDED:
-+		*ptr++ = isp->isp_mboxtmp[2];
-+		mbs.param[1] = isp->isp_mbxwrk1++;
-+		break;
-+	}
-+	isp->isp_mbxworkp = ptr;
-+	mbs.param[0] = isp->isp_lastmbxcmd;
-+	isp->isp_mbxwrk0 -= 1;
-+	isp_mboxcmd_qnw(isp, &mbs, 0);
-+	return (0);
-+}
-+
-+
-+#define	HIBYT(x)			((x) >> 0x8)
-+#define	LOBYT(x)			((x)  & 0xff)
-+#define	ISPOPMAP(a, b)			(((a) << 8) | (b))
-+static const u_int16_t mbpscsi[] = {
-+	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
-+	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
-+	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
-+	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
-+	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
-+	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
-+	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
-+	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
-+	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
-+	ISPOPMAP(0x00, 0x00),	/* 0x09: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
-+	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
-+	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
-+	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
-+	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
-+	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
-+	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
-+	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
-+	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
-+	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
-+	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
-+	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
-+	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
-+	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
-+	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
-+	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
-+	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
-+	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
-+	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
-+	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
-+	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
-+	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
-+	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
-+	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
-+	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
-+	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
-+	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
-+	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
-+	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
-+	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
-+	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
-+	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
-+	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
-+	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
-+	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
-+	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
-+	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
-+	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
-+	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
-+	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
-+	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
-+	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
-+	ISPOPMAP(0x00, 0x00),	/* 0x43: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x44: */
-+	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
-+	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
-+	ISPOPMAP(0x00, 0x00),	/* 0x47: */
-+	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
-+	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
-+	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
-+	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
-+	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
-+	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
-+	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
-+	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
-+	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
-+	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x57: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x58: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x59: */
-+	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
-+	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
-+	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
-+	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
-+};
-+
-+#ifndef	ISP_STRIPPED
-+static char *scsi_mbcmd_names[] = {
-+	"NO-OP",
-+	"LOAD RAM",
-+	"EXEC FIRMWARE",
-+	"DUMP RAM",
-+	"WRITE RAM WORD",
-+	"READ RAM WORD",
-+	"MAILBOX REG TEST",
-+	"VERIFY CHECKSUM",
-+	"ABOUT FIRMWARE",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"CHECK FIRMWARE",
-+	NULL,
-+	"INIT REQUEST QUEUE",
-+	"INIT RESULT QUEUE",
-+	"EXECUTE IOCB",
-+	"WAKE UP",
-+	"STOP FIRMWARE",
-+	"ABORT",
-+	"ABORT DEVICE",
-+	"ABORT TARGET",
-+	"BUS RESET",
-+	"STOP QUEUE",
-+	"START QUEUE",
-+	"SINGLE STEP QUEUE",
-+	"ABORT QUEUE",
-+	"GET DEV QUEUE STATUS",
-+	NULL,
-+	"GET FIRMWARE STATUS",
-+	"GET INIT SCSI ID",
-+	"GET SELECT TIMEOUT",
-+	"GET RETRY COUNT",
-+	"GET TAG AGE LIMIT",
-+	"GET CLOCK RATE",
-+	"GET ACT NEG STATE",
-+	"GET ASYNC DATA SETUP TIME",
-+	"GET PCI PARAMS",
-+	"GET TARGET PARAMS",
-+	"GET DEV QUEUE PARAMS",
-+	"GET RESET DELAY PARAMS",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"SET INIT SCSI ID",
-+	"SET SELECT TIMEOUT",
-+	"SET RETRY COUNT",
-+	"SET TAG AGE LIMIT",
-+	"SET CLOCK RATE",
-+	"SET ACT NEG STATE",
-+	"SET ASYNC DATA SETUP TIME",
-+	"SET PCI CONTROL PARAMS",
-+	"SET TARGET PARAMS",
-+	"SET DEV QUEUE PARAMS",
-+	"SET RESET DELAY PARAMS",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"RETURN BIOS BLOCK ADDR",
-+	"WRITE FOUR RAM WORDS",
-+	"EXEC BIOS IOCB",
-+	NULL,
-+	NULL,
-+	"SET SYSTEM PARAMETER",
-+	"GET SYSTEM PARAMETER",
-+	NULL,
-+	"GET SCAM CONFIGURATION",
-+	"SET SCAM CONFIGURATION",
-+	"SET FIRMWARE FEATURES",
-+	"GET FIRMWARE FEATURES",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"LOAD RAM A64",
-+	"DUMP RAM A64",
-+	"INITIALIZE REQUEST QUEUE A64",
-+	"INITIALIZE RESPONSE QUEUE A64",
-+	"EXECUTE IOCB A64",
-+	"ENABLE TARGET MODE",
-+	"GET TARGET MODE STATE",
-+	NULL,
-+	NULL,
-+	NULL,
-+	"SET DATA OVERRUN RECOVERY MODE",
-+	"GET DATA OVERRUN RECOVERY MODE",
-+	"SET HOST DATA",
-+	"GET NOST DATA",
-+};
-+#endif
-+
-+static const u_int16_t mbpfc[] = {
-+	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
-+	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
-+	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
-+	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
-+	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
-+	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
-+	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
-+	ISPOPMAP(0x03, 0x05),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
-+	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
-+	ISPOPMAP(0xdf, 0x01),	/* 0x09: LOAD RAM */
-+	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
-+	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
-+	ISPOPMAP(0x03, 0x07),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
-+	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
-+	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
-+	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
-+	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
-+	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
-+	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
-+	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
-+	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
-+	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
-+	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
-+	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
-+	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
-+	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
-+	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
-+	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
-+	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
-+	ISPOPMAP(0x00, 0x00),	/* 0x21: */
-+	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
-+	ISPOPMAP(0x00, 0x00),	/* 0x23: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x24: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x25: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x26: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x27: */
-+	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
-+	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x30: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x31: */
-+	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
-+	ISPOPMAP(0x00, 0x00),	/* 0x33: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x34: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x35: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x36: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x37: */
-+	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
-+	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
-+	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
-+	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
-+	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNTS */
-+	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
-+	ISPOPMAP(0x00, 0x00),	/* 0x44: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x45: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x46: */
-+	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
-+	ISPOPMAP(0x00, 0x00),	/* 0x48: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x49: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x50: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x51: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x52: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x53: */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
-+	ISPOPMAP(0x00, 0x00),	/* 0x55: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x56: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x57: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x58: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x59: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
-+	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
-+	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
-+	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
-+	ISPOPMAP(0xfd, 0x31),	/* 0x60: MBOX_INIT_FIRMWARE */
-+	ISPOPMAP(0x00, 0x00),	/* 0x61: */
-+	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
-+	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
-+	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
-+	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
-+	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
-+	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
-+	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
-+	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
-+	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
-+	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
-+	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
-+	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
-+	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
-+	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
-+	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
-+	ISPOPMAP(0x00, 0x00),	/* 0x73: */
-+	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
-+	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
-+	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
-+	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
-+	ISPOPMAP(0x00, 0x00),	/* 0x78: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x79: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
-+	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
-+	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
-+	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
-+	ISPOPMAP(0x07, 0x01)	/* 0x7e: Lun RESET */
-+};
-+/*
-+ * Footnotes
-+ *
-+ * (1): this sets bits 21..16 in mailbox register #8, which we nominally 
-+ *	do not access at this time in the core driver. The caller is
-+ *	responsible for setting this register first (Gross!).
-+ */
-+
-+#ifndef	ISP_STRIPPED
-+static char *fc_mbcmd_names[] = {
-+	"NO-OP",
-+	"LOAD RAM",
-+	"EXEC FIRMWARE",
-+	"DUMP RAM",
-+	"WRITE RAM WORD",
-+	"READ RAM WORD",
-+	"MAILBOX REG TEST",
-+	"VERIFY CHECKSUM",
-+	"ABOUT FIRMWARE",
-+	"LOAD RAM",
-+	"DUMP RAM",
-+	NULL,
-+	NULL,
-+	"READ RAM WORD EXTENDED",
-+	"CHECK FIRMWARE",
-+	NULL,
-+	"INIT REQUEST QUEUE",
-+	"INIT RESULT QUEUE",
-+	"EXECUTE IOCB",
-+	"WAKE UP",
-+	"STOP FIRMWARE",
-+	"ABORT",
-+	"ABORT DEVICE",
-+	"ABORT TARGET",
-+	"BUS RESET",
-+	"STOP QUEUE",
-+	"START QUEUE",
-+	"SINGLE STEP QUEUE",
-+	"ABORT QUEUE",
-+	"GET DEV QUEUE STATUS",
-+	NULL,
-+	"GET FIRMWARE STATUS",
-+	"GET LOOP ID",
-+	NULL,
-+	"GET RETRY COUNT",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"GET FIRMWARE OPTIONS",
-+	"GET PORT QUEUE PARAMS",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"SET RETRY COUNT",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"SET FIRMWARE OPTIONS",
-+	"SET PORT QUEUE PARAMS",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"LOOP PORT BYPASS",
-+	"LOOP PORT ENABLE",
-+	"GET RESOURCE COUNTS",
-+	"REQUEST NON PARTICIPATING MODE",
-+	NULL,
-+	NULL,
-+	NULL,
-+	"GET PORT DATABASE,, ENHANCED",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"EXECUTE IOCB A64",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"DRIVER HEARTBEAT",
-+	NULL,
-+	"GET/SET DATA RATE",
-+	NULL,
-+	NULL,
-+	"INIT FIRMWARE",
-+	NULL,
-+	"INIT LIP",
-+	"GET FC-AL POSITION MAP",
-+	"GET PORT DATABASE",
-+	"CLEAR ACA",
-+	"TARGET RESET",
-+	"CLEAR TASK SET",
-+	"ABORT TASK SET",
-+	"GET FW STATE",
-+	"GET PORT NAME",
-+	"GET LINK STATUS",
-+	"INIT LIP RESET",
-+	NULL,
-+	"SEND SNS",
-+	"FABRIC LOGIN",
-+	"SEND CHANGE REQUEST",
-+	"FABRIC LOGOUT",
-+	"INIT LIP LOGIN",
-+	NULL,
-+	"LOGIN LOOP PORT",
-+	"GET PORT/NODE NAME LIST",
-+	"SET VENDOR ID",
-+	"INITIALIZE IP MAILBOX",
-+	NULL,
-+	NULL,
-+	NULL,
-+	NULL,
-+	"Get ID List",
-+	"SEND LFA",
-+	"Lun RESET"
-+};
-+#endif
-+
-+static void
-+isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
-+{
-+	unsigned int ibits, obits, box, opcode;
-+	const u_int16_t *mcp;
-+
-+	if (IS_FC(isp)) {
-+		mcp = mbpfc;
-+	} else {
-+		mcp = mbpscsi;
-+	}
-+	opcode = mbp->param[0];
-+	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
-+	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
-+	for (box = 0; box < MAX_MAILBOX; box++) {
-+		if (ibits & (1 << box)) {
-+			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
-+		}
-+		if (nodelay == 0) {
-+			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
-+		}
-+	}
-+	if (nodelay == 0) {
-+		isp->isp_lastmbxcmd = opcode;
-+		isp->isp_obits = obits;
-+		isp->isp_mboxbsy = 1;
-+	}
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
-+	/*
-+	 * Oddly enough, if we're not delaying for an answer,
-+	 * delay a bit to give the f/w a chance to pick up the
-+	 * command.
-+	 */
-+	if (nodelay) {
-+		USEC_DELAY(1000);
-+	}
-+}
-+
-+static void
-+isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
-+{
-+	char *cname, *xname, tname[16], mname[16];
-+	unsigned int lim, ibits, obits, box, opcode;
-+	const u_int16_t *mcp;
-+
-+	if (IS_FC(isp)) {
-+		mcp = mbpfc;
-+		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
-+	} else {
-+		mcp = mbpscsi;
-+		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
-+	}
-+
-+	if ((opcode = mbp->param[0]) >= lim) {
-+		mbp->param[0] = MBOX_INVALID_COMMAND;
-+		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
-+		return;
-+	}
-+
-+	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
-+	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
-+
-+	if (ibits == 0 && obits == 0) {
-+		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
-+		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
-+		return;
-+	}
-+
-+	/*
-+	 * Get exclusive usage of mailbox registers.
-+	 */
-+	MBOX_ACQUIRE(isp);
-+
-+	for (box = 0; box < MAX_MAILBOX; box++) {
-+		if (ibits & (1 << box)) {
-+			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
-+		}
-+		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
-+	}
-+
-+	isp->isp_lastmbxcmd = opcode;
-+
-+	/*
-+	 * We assume that we can't overwrite a previous command.
-+	 */
-+	isp->isp_obits = obits;
-+	isp->isp_mboxbsy = 1;
-+
-+	/*
-+	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
-+	 */
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
-+
-+	/*
-+	 * While we haven't finished the command, spin our wheels here.
-+	 */
-+	MBOX_WAIT_COMPLETE(isp);
-+
-+	if (isp->isp_mboxbsy) {
-+		/*
-+		 * Command timed out.
-+		 */
-+		isp->isp_mboxbsy = 0;
-+		MBOX_RELEASE(isp);
-+		return;
-+	}
-+
-+	/*
-+	 * Copy back output registers.
-+	 */
-+	for (box = 0; box < MAX_MAILBOX; box++) {
-+		if (obits & (1 << box)) {
-+			mbp->param[box] = isp->isp_mboxtmp[box];
-+		}
-+	}
-+
-+	MBOX_RELEASE(isp);
-+
-+	if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
-+		return;
-+	}
-+#ifdef	ISP_STRIPPED
-+	cname = NULL;
-+#else
-+	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
-+#endif
-+	if (cname == NULL) {
-+		cname = tname;
-+		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
-+	}
-+
-+	/*
-+	 * Just to be chatty here...
-+	 */
-+	xname = NULL;
-+	switch (mbp->param[0]) {
-+	case MBOX_COMMAND_COMPLETE:
-+		break;
-+	case MBOX_INVALID_COMMAND:
-+		if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
-+			xname = "INVALID COMMAND";
-+		break;
-+	case MBOX_HOST_INTERFACE_ERROR:
-+		if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
-+			xname = "HOST INTERFACE ERROR";
-+		break;
-+	case MBOX_TEST_FAILED:
-+		if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
-+			xname = "TEST FAILED";
-+		break;
-+	case MBOX_COMMAND_ERROR:
-+		if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
-+			xname = "COMMAND ERROR";
-+		break;
-+	case MBOX_COMMAND_PARAM_ERROR:
-+		if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
-+			xname = "COMMAND PARAMETER ERROR";
-+		break;
-+	case MBOX_LOOP_ID_USED:
-+		if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
-+			xname = "LOOP ID ALREADY IN USE";
-+		break;
-+	case MBOX_PORT_ID_USED:
-+		if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
-+			xname = "PORT ID ALREADY IN USE";
-+		break;
-+	case MBOX_ALL_IDS_USED:
-+		if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
-+			xname = "ALL LOOP IDS IN USE";
-+		break;
-+	case 0:		/* special case */
-+		xname = "TIMEOUT";
-+		break;
-+	default:
-+		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
-+		xname = mname;
-+		break;
-+	}
-+	if (xname)
-+		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
-+		    cname, xname);
-+}
-+
-+static void
-+isp_fw_state(struct ispsoftc *isp)
-+{
-+	if (IS_FC(isp)) {
-+		mbreg_t mbs;
-+		fcparam *fcp = isp->isp_param;
-+
-+		mbs.param[0] = MBOX_GET_FW_STATE;
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-+			fcp->isp_fwstate = mbs.param[1];
-+		}
-+	}
-+}
-+
-+static void
-+isp_update(struct ispsoftc *isp)
-+{
-+	int bus, upmask;
-+
-+	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
-+		if (upmask & (1 << bus)) {
-+			isp_update_bus(isp, bus);
-+		}
-+		upmask &= ~(1 << bus);
-+	}
-+}
-+
-+static void
-+isp_update_bus(struct ispsoftc *isp, int bus)
-+{
-+	int tgt;
-+	mbreg_t mbs;
-+	sdparam *sdp;
-+
-+	isp->isp_update &= ~(1 << bus);
-+	if (IS_FC(isp)) {
-+		/*
-+		 * There are no 'per-bus' settings for Fibre Channel.
-+		 */
-+		return;
-+	}
-+	sdp = isp->isp_param;
-+	sdp += bus;
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		u_int16_t flags, period, offset;
-+		int get;
-+
-+		if (sdp->isp_devparam[tgt].dev_enable == 0) {
-+			sdp->isp_devparam[tgt].dev_update = 0;
-+			sdp->isp_devparam[tgt].dev_refresh = 0;
-+			isp_prt(isp, ISP_LOGDEBUG0,
-+	 		    "skipping target %d bus %d update", tgt, bus);
-+			continue;
-+		}
-+		/*
-+		 * If the goal is to update the status of the device,
-+		 * take what's in goal_flags and try and set the device
-+		 * toward that. Otherwise, if we're just refreshing the
-+		 * current device state, get the current parameters.
-+		 */
-+
-+		/*
-+		 * Refresh overrides set
-+		 */
-+		if (sdp->isp_devparam[tgt].dev_refresh) {
-+			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
-+			sdp->isp_devparam[tgt].dev_refresh = 0;
-+			get = 1;
-+		} else if (sdp->isp_devparam[tgt].dev_update) {
-+			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
-+			/*
-+			 * Make sure goal_flags has "Renegotiate on Error"
-+			 * on and "Freeze Queue on Error" off.
-+			 */
-+			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
-+			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
-+
-+			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
-+
-+			/*
-+			 * Insist that PARITY must be enabled
-+			 * if SYNC or WIDE is enabled.
-+			 */
-+			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
-+				mbs.param[2] |= DPARM_PARITY;
-+			}
-+
-+			if ((mbs.param[2] & DPARM_SYNC) == 0) {
-+				mbs.param[3] = 0;
-+			} else {
-+				mbs.param[3] =
-+				    (sdp->isp_devparam[tgt].goal_offset << 8) |
-+				    (sdp->isp_devparam[tgt].goal_period);
-+			}
-+			/*
-+			 * A command completion later that has
-+			 * RQSTF_NEGOTIATION set can cause
-+			 * the dev_refresh/announce cycle also.
-+			 *
-+			 * Note: It is really important to update our current
-+			 * flags with at least the state of TAG capabilities-
-+			 * otherwise we might try and send a tagged command
-+			 * when we have it all turned off. So change it here
-+			 * to say that current already matches goal.
-+			 */
-+			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
-+			sdp->isp_devparam[tgt].actv_flags |=
-+			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
-+			isp_prt(isp, ISP_LOGDEBUG0,
-+			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
-+			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
-+			    mbs.param[3] & 0xff);
-+			sdp->isp_devparam[tgt].dev_update = 0;
-+			sdp->isp_devparam[tgt].dev_refresh = 1;
-+			get = 0;
-+		} else {
-+			continue;
-+		}
-+		mbs.param[1] = (bus << 15) | (tgt << 8);
-+		isp_mboxcmd(isp, &mbs, MBLOGALL);
-+		if (get == 0) {
-+			isp->isp_sendmarker |= (1 << bus);
-+			continue;
-+		}
-+		flags = mbs.param[2];
-+		period = mbs.param[3] & 0xff;
-+		offset = mbs.param[3] >> 8;
-+		sdp->isp_devparam[tgt].actv_flags = flags;
-+		sdp->isp_devparam[tgt].actv_period = period;
-+		sdp->isp_devparam[tgt].actv_offset = offset;
-+		get = (bus << 16) | tgt;
-+		(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
-+	}
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		if (sdp->isp_devparam[tgt].dev_update ||
-+		    sdp->isp_devparam[tgt].dev_refresh) {
-+			isp->isp_update |= (1 << bus);
-+			break;
-+		}
-+	}
-+}
-+
-+#ifndef	DEFAULT_FRAMESIZE
-+#define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
-+#endif
-+#ifndef	DEFAULT_EXEC_THROTTLE
-+#define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
-+#endif
-+
-+static void
-+isp_setdfltparm(struct ispsoftc *isp, int channel)
-+{
-+	int tgt;
-+	mbreg_t mbs;
-+	sdparam *sdp;
-+
-+	if (IS_FC(isp)) {
-+		fcparam *fcp = (fcparam *) isp->isp_param;
-+		int nvfail;
-+
-+		fcp += channel;
-+		if (fcp->isp_gotdparms) {
-+			return;
-+		}
-+		fcp->isp_gotdparms = 1;
-+		fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
-+		fcp->isp_maxalloc = ICB_DFLT_ALLOC;
-+		fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
-+		fcp->isp_retry_delay = ICB_DFLT_RDELAY;
-+		fcp->isp_retry_count = ICB_DFLT_RCOUNT;
-+		/* Platform specific.... */
-+		fcp->isp_loopid = DEFAULT_LOOPID(isp);
-+		fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
-+		fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
-+		fcp->isp_fwoptions = 0;
-+		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
-+		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
-+		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
-+#ifndef	ISP_NO_FASTPOST_FC
-+		fcp->isp_fwoptions |= ICBOPT_FAST_POST;
-+#endif
-+		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
-+			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
-+
-+		/*
-+		 * Make sure this is turned off now until we get
-+		 * extended options from NVRAM
-+		 */
-+		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
-+
-+		/*
-+		 * Now try and read NVRAM unless told to not do so.
-+		 * This will set fcparam's isp_nodewwn && isp_portwwn.
-+		 */
-+		if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
-+		    	nvfail = isp_read_nvram(isp);
-+			if (nvfail)
-+				isp->isp_confopts |= ISP_CFG_NONVRAM;
-+		} else {
-+			nvfail = 1;
-+		}
-+		/*
-+		 * Set node && port to override platform set defaults
-+		 * unless the nvram read failed (or none was done),
-+		 * or the platform code wants to use what had been
-+		 * set in the defaults.
-+		 */
-+		if (nvfail) {
-+			isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
-+		}
-+		if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
-+			isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
-+			    (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
-+			    (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
-+			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
-+		} else {
-+			/*
-+			 * We always start out with values derived
-+			 * from NVRAM or our platform default.
-+			 */
-+			ISP_NODEWWN(isp) = fcp->isp_nodewwn;
-+		}
-+		if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
-+			isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
-+			    (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
-+			    (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
-+			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
-+		} else {
-+			/*
-+			 * We always start out with values derived
-+			 * from NVRAM or our platform default.
-+			 */
-+			ISP_PORTWWN(isp) = fcp->isp_portwwn;
-+		}
-+		return;
-+	}
-+
-+	sdp = (sdparam *) isp->isp_param;
-+	sdp += channel;
-+
-+	/*
-+	 * Been there, done that, got the T-shirt...
-+	 */
-+	if (sdp->isp_gotdparms) {
-+		return;
-+	}
-+	sdp->isp_gotdparms = 1;
-+
-+	/*
-+	 * Establish some default parameters.
-+	 */
-+	sdp->isp_cmd_dma_burst_enable = 0;
-+	sdp->isp_data_dma_burst_enabl = 1;
-+	sdp->isp_fifo_threshold = 0;
-+	sdp->isp_initiator_id = DEFAULT_IID(isp);
-+	if (isp->isp_type >= ISP_HA_SCSI_1040) {
-+		sdp->isp_async_data_setup = 9;
-+	} else {
-+		sdp->isp_async_data_setup = 6;
-+	}
-+	sdp->isp_selection_timeout = 250;
-+	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
-+	sdp->isp_tag_aging = 8;
-+	sdp->isp_bus_reset_delay = 5;
-+	/*
-+	 * Don't retry selection, busy or queue full automatically- reflect
-+	 * these back to us.
-+	 */
-+	sdp->isp_retry_count = 0;
-+	sdp->isp_retry_delay = 0;
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
-+		sdp->isp_devparam[tgt].dev_enable = 1;
-+	}
-+
-+	/*
-+	 * If we've not been told to avoid reading NVRAM, try and read it.
-+	 * If we're successful reading it, we can then return because NVRAM
-+	 * will tell us what the desired settings are. Otherwise, we establish
-+	 * some reasonable 'fake' nvram and goal defaults.
-+	 */
-+
-+	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
-+		if (isp_read_nvram(isp) == 0) {
-+			return;
-+		}
-+	}
-+
-+	/*
-+	 * Now try and see whether we have specific values for them.
-+	 */
-+	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
-+		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
-+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
-+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+			sdp->isp_req_ack_active_neg = 1;
-+			sdp->isp_data_line_active_neg = 1;
-+		} else {
-+			sdp->isp_req_ack_active_neg =
-+			    (mbs.param[1+channel] >> 4) & 0x1;
-+			sdp->isp_data_line_active_neg =
-+			    (mbs.param[1+channel] >> 5) & 0x1;
-+		}
-+	}
-+
-+	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
-+	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
-+	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
-+	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
-+	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
-+	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
-+	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
-+	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-+
-+	/*
-+	 * The trick here is to establish a default for the default (honk!)
-+	 * state (goal_flags). Then try and get the current status from
-+	 * the card to fill in the current state. We don't, in fact, set
-+	 * the default to the SAFE default state- that's not the goal state.
-+	 */
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		u_int8_t off, per;
-+		sdp->isp_devparam[tgt].actv_offset = 0;
-+		sdp->isp_devparam[tgt].actv_period = 0;
-+		sdp->isp_devparam[tgt].actv_flags = 0;
-+
-+		sdp->isp_devparam[tgt].goal_flags =
-+		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
-+
-+		/*
-+		 * We default to Wide/Fast for versions less than a 1040
-+		 * (unless it's SBus).
-+		 */
-+		if (IS_ULTRA3(isp)) {
-+			off = ISP_80M_SYNCPARMS >> 8;
-+			per = ISP_80M_SYNCPARMS & 0xff;
-+		} else if (IS_ULTRA2(isp)) {
-+			off = ISP_40M_SYNCPARMS >> 8;
-+			per = ISP_40M_SYNCPARMS & 0xff;
-+		} else if (IS_1240(isp)) {
-+			off = ISP_20M_SYNCPARMS >> 8;
-+			per = ISP_20M_SYNCPARMS & 0xff;
-+		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
-+		    isp->isp_type < ISP_HA_SCSI_1020A) ||
-+		    (isp->isp_bustype == ISP_BT_PCI &&
-+		    isp->isp_type < ISP_HA_SCSI_1040) ||
-+		    (isp->isp_clock && isp->isp_clock < 60) ||
-+		    (sdp->isp_ultramode == 0)) {
-+			off = ISP_10M_SYNCPARMS >> 8;
-+			per = ISP_10M_SYNCPARMS & 0xff;
-+		} else {
-+			off = ISP_20M_SYNCPARMS_1040 >> 8;
-+			per = ISP_20M_SYNCPARMS_1040 & 0xff;
-+		}
-+		sdp->isp_devparam[tgt].goal_offset =
-+		    sdp->isp_devparam[tgt].nvrm_offset = off;
-+		sdp->isp_devparam[tgt].goal_period =
-+		    sdp->isp_devparam[tgt].nvrm_period = per;
-+
-+		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
-+		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
-+		    sdp->isp_devparam[tgt].nvrm_offset,
-+		    sdp->isp_devparam[tgt].nvrm_period);
-+	}
-+}
-+
-+/*
-+ * Re-initialize the ISP and complete all orphaned commands
-+ * with a 'botched' notice. The reset/init routines should
-+ * not disturb an already active list of commands.
-+ *
-+ * Locks held prior to coming here.
-+ */
-+
-+void
-+isp_reinit(struct ispsoftc *isp)
-+{
-+	XS_T *xs;
-+	u_int16_t handle;
-+
-+	if (IS_FC(isp)) {
-+		isp_mark_getpdb_all(isp);
-+	}
-+	isp_reset(isp);
-+	if (isp->isp_state != ISP_RESETSTATE) {
-+		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
-+	} else if (isp->isp_role != ISP_ROLE_NONE) {
-+		isp_init(isp);
-+		if (isp->isp_state == ISP_INITSTATE) {
-+			isp->isp_state = ISP_RUNSTATE;
-+		}
-+		if (isp->isp_state != ISP_RUNSTATE) {
-+			isp_prt(isp, ISP_LOGERR,
-+			    "isp_reinit cannot restart card");
-+		}
-+	}
-+	isp->isp_nactive = 0;
-+
-+	for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
-+		xs = isp_find_xs(isp, handle);
-+		if (xs == NULL) {
-+			continue;
-+		}
-+		isp_destroy_handle(isp, handle);
-+		if (XS_XFRLEN(xs)) {
-+			ISP_DMAFREE(isp, xs, handle);
-+			XS_RESID(xs) = XS_XFRLEN(xs);
-+		} else {
-+			XS_RESID(xs) = 0;
-+		}
-+		XS_SETERR(xs, HBA_BUSRESET);
-+		isp_done(xs);
-+	}
-+}
-+
-+/*
-+ * NVRAM Routines
-+ */
-+static int
-+isp_read_nvram(struct ispsoftc *isp)
-+{
-+	int i, amt;
-+	u_int8_t csum, minversion;
-+	union {
-+		u_int8_t _x[ISP2100_NVRAM_SIZE];
-+		u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
-+	} _n;
-+#define	nvram_data	_n._x
-+#define	nvram_words	_n._s
-+
-+	if (IS_FC(isp)) {
-+		amt = ISP2100_NVRAM_SIZE;
-+		minversion = 1;
-+	} else if (IS_ULTRA2(isp)) {
-+		amt = ISP1080_NVRAM_SIZE;
-+		minversion = 0;
-+	} else {
-+		amt = ISP_NVRAM_SIZE;
-+		minversion = 2;
-+	}
-+
-+	/*
-+	 * Just read the first two words first to see if we have a valid
-+	 * NVRAM to continue reading the rest with.
-+	 */
-+	for (i = 0; i < 2; i++) {
-+		isp_rdnvram_word(isp, i, &nvram_words[i]);
-+	}
-+	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
-+	    nvram_data[2] != 'P') {
-+		if (isp->isp_bustype != ISP_BT_SBUS) {
-+			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
-+			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
-+			    nvram_data[0], nvram_data[1], nvram_data[2]);
-+		}
-+		return (-1);
-+	}
-+	for (i = 2; i < amt>>1; i++) {
-+		isp_rdnvram_word(isp, i, &nvram_words[i]);
-+	}
-+	for (csum = 0, i = 0; i < amt; i++) {
-+		csum += nvram_data[i];
-+	}
-+	if (csum != 0) {
-+		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
-+		return (-1);
-+	}
-+	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
-+		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
-+		    ISP_NVRAM_VERSION(nvram_data));
-+		return (-1);
-+	}
-+
-+	if (IS_ULTRA3(isp)) {
-+		isp_parse_nvram_12160(isp, 0, nvram_data);
-+		if (IS_12160(isp))
-+			isp_parse_nvram_12160(isp, 1, nvram_data);
-+	} else if (IS_1080(isp)) {
-+		isp_parse_nvram_1080(isp, 0, nvram_data);
-+	} else if (IS_1280(isp) || IS_1240(isp)) {
-+		isp_parse_nvram_1080(isp, 0, nvram_data);
-+		isp_parse_nvram_1080(isp, 1, nvram_data);
-+	} else if (IS_SCSI(isp)) {
-+		isp_parse_nvram_1020(isp, nvram_data);
-+	} else {
-+		isp_parse_nvram_2100(isp, nvram_data);
-+	}
-+	return (0);
-+#undef	nvram_data
-+#undef	nvram_words
-+}
-+
-+static void
-+isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
-+{
-+	int i, cbits;
-+	u_int16_t bit, rqst;
-+
-+	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
-+	USEC_DELAY(2);
-+	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
-+	USEC_DELAY(2);
-+
-+	if (IS_FC(isp)) {
-+		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
-+		if (IS_2312(isp) && isp->isp_port) {
-+			wo += 128;
-+		}
-+		rqst = (ISP_NVRAM_READ << 8) | wo;
-+		cbits = 10;
-+	} else if (IS_ULTRA2(isp)) {
-+		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
-+		rqst = (ISP_NVRAM_READ << 8) | wo;
-+		cbits = 10;
-+	} else {
-+		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
-+		rqst = (ISP_NVRAM_READ << 6) | wo;
-+		cbits = 8;
-+	}
-+
-+	/*
-+	 * Clock the word select request out...
-+	 */
-+	for (i = cbits; i >= 0; i--) {
-+		if ((rqst >> i) & 1) {
-+			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
-+		} else {
-+			bit = BIU_NVRAM_SELECT;
-+		}
-+		ISP_WRITE(isp, BIU_NVRAM, bit);
-+		USEC_DELAY(2);
-+		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
-+		USEC_DELAY(2);
-+		ISP_WRITE(isp, BIU_NVRAM, bit);
-+		USEC_DELAY(2);
-+	}
-+	/*
-+	 * Now read the result back in (bits come back in MSB format).
-+	 */
-+	*rp = 0;
-+	for (i = 0; i < 16; i++) {
-+		u_int16_t rv;
-+		*rp <<= 1;
-+		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
-+		USEC_DELAY(2);
-+		rv = ISP_READ(isp, BIU_NVRAM);
-+		if (rv & BIU_NVRAM_DATAIN) {
-+			*rp |= 1;
-+		}
-+		USEC_DELAY(2);
-+		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
-+		USEC_DELAY(2);
-+	}
-+	ISP_WRITE(isp, BIU_NVRAM, 0);
-+	USEC_DELAY(2);
-+	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
-+}
-+
-+static void
-+isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
-+{
-+	sdparam *sdp = (sdparam *) isp->isp_param;
-+	int tgt;
-+
-+	sdp->isp_fifo_threshold =
-+		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
-+		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
-+
-+	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
-+		sdp->isp_initiator_id =
-+			ISP_NVRAM_INITIATOR_ID(nvram_data);
-+
-+	sdp->isp_bus_reset_delay =
-+		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
-+
-+	sdp->isp_retry_count =
-+		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
-+
-+	sdp->isp_retry_delay =
-+		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
-+
-+	sdp->isp_async_data_setup =
-+		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
-+
-+	if (isp->isp_type >= ISP_HA_SCSI_1040) {
-+		if (sdp->isp_async_data_setup < 9) {
-+			sdp->isp_async_data_setup = 9;
-+		}
-+	} else {
-+		if (sdp->isp_async_data_setup != 6) {
-+			sdp->isp_async_data_setup = 6;
-+		}
-+	}
-+
-+	sdp->isp_req_ack_active_neg =
-+		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
-+
-+	sdp->isp_data_line_active_neg =
-+		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
-+
-+	sdp->isp_data_dma_burst_enabl =
-+		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_cmd_dma_burst_enable =
-+		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_tag_aging =
-+		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
-+
-+	sdp->isp_selection_timeout =
-+		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
-+
-+	sdp->isp_max_queue_depth =
-+		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
-+
-+	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
-+
-+	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
-+	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
-+	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
-+	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
-+	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
-+	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
-+	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
-+	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		sdp->isp_devparam[tgt].dev_enable =
-+			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
-+		sdp->isp_devparam[tgt].exc_throttle =
-+			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
-+		sdp->isp_devparam[tgt].nvrm_offset =
-+			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
-+		sdp->isp_devparam[tgt].nvrm_period =
-+			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
-+		/*
-+		 * We probably shouldn't lie about this, but it
-+		 * it makes it much safer if we limit NVRAM values
-+		 * to sanity.
-+		 */
-+		if (isp->isp_type < ISP_HA_SCSI_1040) {
-+			/*
-+			 * If we're not ultra, we can't possibly
-+			 * be a shorter period than this.
-+			 */
-+			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
-+				sdp->isp_devparam[tgt].nvrm_period = 0x19;
-+			}
-+			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
-+				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
-+			}
-+		} else {
-+			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
-+				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
-+			}
-+		}
-+		sdp->isp_devparam[tgt].nvrm_flags = 0;
-+		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
-+		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
-+		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
-+		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
-+		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
-+		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
-+		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
-+		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
-+		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
-+		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
-+		    sdp->isp_devparam[tgt].nvrm_offset,
-+		    sdp->isp_devparam[tgt].nvrm_period);
-+		sdp->isp_devparam[tgt].goal_offset =
-+		    sdp->isp_devparam[tgt].nvrm_offset;
-+		sdp->isp_devparam[tgt].goal_period =
-+		    sdp->isp_devparam[tgt].nvrm_period;
-+		sdp->isp_devparam[tgt].goal_flags =
-+		    sdp->isp_devparam[tgt].nvrm_flags;
-+	}
-+}
-+
-+static void
-+isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
-+{
-+	sdparam *sdp = (sdparam *) isp->isp_param;
-+	int tgt;
-+
-+	sdp += bus;
-+
-+	sdp->isp_fifo_threshold =
-+	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
-+
-+	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
-+		sdp->isp_initiator_id =
-+		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
-+
-+	sdp->isp_bus_reset_delay =
-+	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
-+
-+	sdp->isp_retry_count =
-+	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
-+
-+	sdp->isp_retry_delay =
-+	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
-+
-+	sdp->isp_async_data_setup =
-+	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
-+
-+	sdp->isp_req_ack_active_neg =
-+	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
-+
-+	sdp->isp_data_line_active_neg =
-+	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
-+
-+	sdp->isp_data_dma_burst_enabl =
-+	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_cmd_dma_burst_enable =
-+	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_selection_timeout =
-+	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
-+
-+	sdp->isp_max_queue_depth =
-+	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
-+
-+	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
-+	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
-+	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
-+	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
-+	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
-+	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
-+	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
-+	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-+
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		sdp->isp_devparam[tgt].dev_enable =
-+		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].exc_throttle =
-+			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_offset =
-+			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_period =
-+			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_flags = 0;
-+		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
-+		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
-+		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
-+		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
-+		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
-+		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
-+		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
-+		sdp->isp_devparam[tgt].actv_flags = 0;
-+		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
-+		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
-+		    sdp->isp_devparam[tgt].nvrm_offset,
-+		    sdp->isp_devparam[tgt].nvrm_period);
-+		sdp->isp_devparam[tgt].goal_offset =
-+		    sdp->isp_devparam[tgt].nvrm_offset;
-+		sdp->isp_devparam[tgt].goal_period =
-+		    sdp->isp_devparam[tgt].nvrm_period;
-+		sdp->isp_devparam[tgt].goal_flags =
-+		    sdp->isp_devparam[tgt].nvrm_flags;
-+	}
-+}
-+
-+static void
-+isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
-+{
-+	sdparam *sdp = (sdparam *) isp->isp_param;
-+	int tgt;
-+
-+	sdp += bus;
-+
-+	sdp->isp_fifo_threshold =
-+	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
-+
-+	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
-+		sdp->isp_initiator_id =
-+		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
-+
-+	sdp->isp_bus_reset_delay =
-+	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
-+
-+	sdp->isp_retry_count =
-+	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
-+
-+	sdp->isp_retry_delay =
-+	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
-+
-+	sdp->isp_async_data_setup =
-+	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
-+
-+	sdp->isp_req_ack_active_neg =
-+	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
-+
-+	sdp->isp_data_line_active_neg =
-+	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
-+
-+	sdp->isp_data_dma_burst_enabl =
-+	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_cmd_dma_burst_enable =
-+	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
-+
-+	sdp->isp_selection_timeout =
-+	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
-+
-+	sdp->isp_max_queue_depth =
-+	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
-+
-+	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
-+	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
-+	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
-+	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
-+	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
-+	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
-+	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
-+	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-+
-+	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
-+		sdp->isp_devparam[tgt].dev_enable =
-+		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].exc_throttle =
-+			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_offset =
-+			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_period =
-+			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
-+		sdp->isp_devparam[tgt].nvrm_flags = 0;
-+		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
-+		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
-+		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
-+		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
-+		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
-+		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
-+		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
-+			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
-+		sdp->isp_devparam[tgt].actv_flags = 0;
-+		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
-+		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
-+		    sdp->isp_devparam[tgt].nvrm_offset,
-+		    sdp->isp_devparam[tgt].nvrm_period);
-+		sdp->isp_devparam[tgt].goal_offset =
-+		    sdp->isp_devparam[tgt].nvrm_offset;
-+		sdp->isp_devparam[tgt].goal_period =
-+		    sdp->isp_devparam[tgt].nvrm_period;
-+		sdp->isp_devparam[tgt].goal_flags =
-+		    sdp->isp_devparam[tgt].nvrm_flags;
-+	}
-+}
-+
-+static void
-+isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
-+{
-+	fcparam *fcp = (fcparam *) isp->isp_param;
-+	u_int64_t wwn;
-+
-+	/*
-+	 * There is NVRAM storage for both Port and Node entities-
-+	 * but the Node entity appears to be unused on all the cards
-+	 * I can find. However, we should account for this being set
-+	 * at some point in the future.
-+	 *
-+	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
-+	 * bits 48..60. In the case of the 2202, it appears that they do
-+	 * use bit 48 to distinguish between the two instances on the card.
-+	 * The 2204, which I've never seen, *probably* extends this method.
-+	 */
-+	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
-+	if (wwn) {
-+		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
-+		    (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
-+		if ((wwn >> 60) == 0) {
-+			wwn |= (((u_int64_t) 2)<< 60);
-+		}
-+	}
-+	fcp->isp_portwwn = wwn;
-+	if (IS_2200(isp) || IS_23XX(isp)) {
-+		wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
-+		if (wwn) {
-+			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
-+			    (u_int32_t) (wwn >> 32),
-+			    (u_int32_t) (wwn & 0xffffffff));
-+			if ((wwn >> 60) == 0) {
-+				wwn |= (((u_int64_t) 2)<< 60);
-+			}
-+		}
-+	} else {
-+		wwn &= ~((u_int64_t) 0xfff << 48);
-+	}
-+	fcp->isp_nodewwn = wwn;
-+
-+	/*
-+	 * Make sure we have both Node and Port as non-zero values.
-+	 */
-+	if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
-+		fcp->isp_portwwn = fcp->isp_nodewwn;
-+	} else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
-+		fcp->isp_nodewwn = fcp->isp_portwwn;
-+	}
-+
-+	/*
-+	 * Make the Node and Port values sane if they're NAA == 2.
-+	 * This means to clear bits 48..56 for the Node WWN and
-+	 * make sure that there's some non-zero value in 48..56
-+	 * for the Port WWN.
-+	 */
-+	if (fcp->isp_nodewwn && fcp->isp_portwwn) {
-+		if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
-+		    (fcp->isp_nodewwn >> 60) == 2) {
-+			fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
-+		}
-+		if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
-+		    (fcp->isp_portwwn >> 60) == 2) {
-+			fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
-+		}
-+	}
-+
-+	isp_prt(isp, ISP_LOGDEBUG0,
-+	    "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
-+	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
-+	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
-+	    ISP2100_NVRAM_OPTIONS(nvram_data),
-+	    ISP2100_NVRAM_HARDLOOPID(nvram_data));
-+
-+	fcp->isp_maxalloc =
-+		ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
-+	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
-+		fcp->isp_maxfrmlen =
-+			ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
-+	fcp->isp_retry_delay =
-+		ISP2100_NVRAM_RETRY_DELAY(nvram_data);
-+	fcp->isp_retry_count =
-+		ISP2100_NVRAM_RETRY_COUNT(nvram_data);
-+	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
-+		fcp->isp_loopid =
-+			ISP2100_NVRAM_HARDLOOPID(nvram_data);
-+	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
-+		fcp->isp_execthrottle =
-+			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
-+	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
-+}
-+
-+#ifdef	ISP_FW_CRASH_DUMP
-+static void isp2200_fw_dump(struct ispsoftc *);
-+static void isp2300_fw_dump(struct ispsoftc *);
-+
-+static void
-+isp2200_fw_dump(struct ispsoftc *isp)
-+{
-+	int i, j;
-+	mbreg_t mbs;
-+	u_int16_t *ptr;
-+
-+	ptr = FCPARAM(isp)->isp_dump_data;
-+	if (ptr == NULL) {
-+		isp_prt(isp, ISP_LOGERR,
-+		   "No place to dump RISC registers and SRAM");
-+		return;
-+	}
-+	if (*ptr++) {
-+		isp_prt(isp, ISP_LOGERR,
-+		   "dump area for RISC registers and SRAM already used");
-+		return;
-+	}
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
-+			break;
-+		}
-+	}
-+	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
-+		/*
-+		 * PBIU Registers
-+		 */
-+		for (i = 0; i < 8; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
-+		}
-+
-+		/*
-+		 * Mailbox Registers
-+		 */
-+		for (i = 0; i < 8; i++) {
-+			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
-+		}
-+
-+		/*
-+		 * DMA Registers
-+		 */
-+		for (i = 0; i < 48; i++) {
-+			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
-+		}
-+
-+		/*
-+		 * RISC H/W Registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0);
-+		for (i = 0; i < 16; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
-+		}
-+
-+		/*
-+		 * RISC GP Registers
-+		 */
-+		for (j = 0; j < 8; j++) {
-+			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
-+			for (i = 0; i < 16; i++) {
-+				*ptr++ =
-+				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+			}
-+		}
-+
-+		/*
-+		 * Frame Buffer Hardware Registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x10);
-+		for (i = 0; i < 16; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * Fibre Protocol Module 0 Hardware Registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x20);
-+		for (i = 0; i < 64; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * Fibre Protocol Module 1 Hardware Registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x30);
-+		for (i = 0; i < 64; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+	} else {
-+		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
-+		return;
-+	}
-+	isp_prt(isp, ISP_LOGALL,
-+	   "isp_fw_dump: RISC registers dumped successfully");
-+	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
-+			break;
-+		}
-+	}
-+	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
-+		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
-+		return;
-+	}
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
-+			break;
-+		}
-+	}
-+	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
-+		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
-+		return;
-+	}
-+	ISP_WRITE(isp, RISC_EMB, 0xf2);
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
-+			break;
-+		}
-+	}
-+	ENABLE_INTS(isp);
-+	mbs.param[0] = MBOX_READ_RAM_WORD;
-+	mbs.param[1] = 0x1000;
-+	isp->isp_mbxworkp = (void *) ptr;
-+	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
-+	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
-+	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
-+		return;
-+	}
-+	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
-+	*ptr++ = isp->isp_mboxtmp[2];
-+	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
-+	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
-+	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
-+}
-+
-+static void
-+isp2300_fw_dump(struct ispsoftc *isp)
-+{
-+	int i, j;
-+	mbreg_t mbs;
-+	u_int16_t *ptr;
-+
-+	ptr = FCPARAM(isp)->isp_dump_data;
-+	if (ptr == NULL) {
-+		isp_prt(isp, ISP_LOGERR,
-+		   "No place to dump RISC registers and SRAM");
-+		return;
-+	}
-+	if (*ptr++) {
-+		isp_prt(isp, ISP_LOGERR,
-+		   "dump area for RISC registers and SRAM already used");
-+		return;
-+	}
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
-+			break;
-+		}
-+	}
-+	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
-+		/*
-+		 * PBIU registers
-+		 */
-+		for (i = 0; i < 8; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
-+		}
-+
-+		/*
-+		 * ReqQ-RspQ-Risc2Host Status registers
-+		 */
-+		for (i = 0; i < 8; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
-+		}
-+
-+		/*
-+		 * Mailbox Registers
-+		 */
-+		for (i = 0; i < 32; i++) {
-+			*ptr++ =
-+			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
-+		}
-+
-+		/*
-+		 * Auto Request Response DMA registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x40);
-+		for (i = 0; i < 32; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * DMA registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x50);
-+		for (i = 0; i < 48; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * RISC hardware registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0);
-+		for (i = 0; i < 16; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
-+		}
-+
-+		/*
-+		 * RISC GP? registers
-+		 */
-+		for (j = 0; j < 8; j++) {
-+			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
-+			for (i = 0; i < 16; i++) {
-+				*ptr++ =
-+				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+			}
-+		}
-+
-+		/*
-+		 * frame buffer hardware registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x10);
-+		for (i = 0; i < 64; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * FPM B0 hardware registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x20);
-+		for (i = 0; i < 64; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+
-+		/*
-+		 * FPM B1 hardware registers
-+		 */
-+		ISP_WRITE(isp, BIU2100_CSR, 0x30);
-+		for (i = 0; i < 64; i++) {
-+			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
-+		}
-+	} else {
-+		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
-+		return;
-+	}
-+	isp_prt(isp, ISP_LOGALL,
-+	   "isp_fw_dump: RISC registers dumped successfully");
-+	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
-+	for (i = 0; i < 100; i++) {
-+		USEC_DELAY(100);
-+		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
-+			break;
-+		}
-+	}
-+	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
-+		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
-+		return;
-+	}
-+	ENABLE_INTS(isp);
-+	mbs.param[0] = MBOX_READ_RAM_WORD;
-+	mbs.param[1] = 0x800;
-+	isp->isp_mbxworkp = (void *) ptr;
-+	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
-+	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
-+	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
-+		return;
-+	}
-+	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
-+	*ptr++ = isp->isp_mboxtmp[2];
-+
-+	/*
-+	 * We don't have access to mailbox registers 8.. onward
-+	 * in our 'common' device model- so we have to set it
-+	 * here and hope it stays the same!
-+	 */
-+	ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
-+
-+	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
-+	mbs.param[1] = 0;
-+	isp->isp_mbxworkp = (void *) ptr;
-+	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
-+	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
-+	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
-+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
-+		return;
-+	}
-+	ptr = isp->isp_mbxworkp;	/* finish final word */
-+	*ptr++ = mbs.param[2];
-+	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
-+	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
-+	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
-+}
-+
-+void
-+isp_fw_dump(struct ispsoftc *isp)
-+{
-+	if (IS_2200(isp))
-+		isp2200_fw_dump(isp);
-+	else if (IS_23XX(isp))
-+		isp2300_fw_dump(isp);
-+}
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_cb_ops.c	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,646 @@
-+/* %W% */
-+/*
-+ * Qlogic ISP Host Adapter procfs and open/close entry points
-+ *---------------------------------------
-+ *
-+ * Copyright (c) 2003 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification, immediately at the beginning of the file.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * Alternatively, this software may be distributed under the terms of the
-+ * the GNU Public License ("GPL").
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * 
-+ * Matthew Jacob
-+ * Feral Software
-+ * PMB #825
-+ * 5214-F Diamond Hts Blvd
-+ * San Francisco, CA, 94131
-+ * mjacob@feral.com
-+ *
-+ *----
-+ * proc safe pretty print code courtesy of Gerard Roudier (groudier@free.fr)
-+ *
-+ */
-+
-+#include "isp_linux.h"
-+#include "isp_ioctl.h"
-+#include <asm/uaccess.h>
-+#ifdef	CONFIG_PROC_FS
-+
-+/*
-+ * 'safe' proc pretty print code 
-+ */
-+struct info_str {
-+    char *buffer;
-+    int length;
-+    off_t offset;
-+    int pos;
-+};
-+
-+static void
-+copy_mem_info(struct info_str *info, char *data, int len)
-+{
-+	if (info->pos + len > info->offset + info->length)
-+		len = info->offset + info->length - info->pos;
-+
-+	if (info->pos + len < info->offset) {
-+		info->pos += len;
-+		return;
-+	}
-+
-+	if (info->pos < info->offset) {
-+		off_t partial;
-+
-+		partial = info->offset - info->pos;
-+		data += partial;
-+		info->pos += partial;
-+		len  -= partial;
-+	}
-+
-+	if (len > 0) {
-+		memcpy(info->buffer, data, len);
-+		info->pos += len;
-+		info->buffer += len;
-+	}
-+}
-+
-+static int
-+copy_info(struct info_str *info, char *fmt, ...)
-+{
-+	va_list args;
-+	char buf[256];
-+	int len;
-+
-+	va_start(args, fmt);
-+	len = vsprintf(buf, fmt, args);
-+	va_end(args);
-+
-+	copy_mem_info(info, buf, len);
-+	return (len);
-+}
-+
-+
-+int
-+isplinux_proc_info(char *buf, char **st, off_t off, int len, int host, int io)
-+{
-+    int i;
-+    struct info_str info;
-+    struct ispsoftc *isp;
-+
-+    isp = isplist;
-+    while (isp) {
-+	if (isp->isp_host->host_no == host) {
-+	    break;
-+	}
-+	isp = isp->isp_next;
-+    }
-+    if (isp == NULL) {
-+	return (-ENODEV);
-+    }
-+
-+    if (io) {
-+	buf[len] = 0;
-+	io = -ENOSYS;
-+	if (strncmp(buf, "debug=", 6) == 0) {
-+	    unsigned long debug;
-+	    char *p = &buf[6], *q;
-+	    debug = simple_strtoul(p, &q, 16);
-+	    if (q == &buf[6]) {
-+		isp_prt(isp, ISP_LOGERR, "Garbled Debug Line '%s'", buf);
-+		return (-EINVAL);
-+	    }
-+	    isp_prt(isp, ISP_LOGINFO, "setting debug level to 0x%lx", debug);
-+	    ISP_LOCKU_SOFTC(isp);
-+	    isp->isp_dblev = debug;
-+	    ISP_UNLKU_SOFTC(isp);
-+	    io = len;
-+	} else if (strncmp(buf, "rescan", 6) == 0) {
-+	    if (IS_FC(isp)) {
-+		SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 1);
-+		io = len;
-+	    }
-+	} else if (strncmp(buf, "lip", 3) == 0) {
-+	    if (IS_FC(isp)) {
-+		ISP_LOCKU_SOFTC(isp);
-+		(void) isp_control(isp, ISPCTL_SEND_LIP, 0);
-+		ISP_UNLKU_SOFTC(isp);
-+		io = len;
-+	    }
-+	} else if (strncmp(buf, "busreset=", 9) == 0) {
-+	    char *p = &buf[6], *q;
-+	    int bus = (int) simple_strtoul(p, &q, 16);
-+	    if (q == &buf[6]) {
-+		isp_prt(isp, ISP_LOGERR, "Garbled Bus Reset Line '%s'", buf);
-+		return (-EINVAL);
-+	    }
-+	    ISP_LOCKU_SOFTC(isp);
-+	    (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
-+	    ISP_UNLKU_SOFTC(isp);
-+	    io = len;
-+	} else if (strncmp(buf, "devreset=", 9) == 0) {
-+	    char *p = &buf[6], *q;
-+	    int dev = (int) simple_strtoul(p, &q, 16);
-+	    if (q == &buf[6]) {
-+		isp_prt(isp, ISP_LOGERR, "Garbled Dev Reset Line '%s'", buf);
-+		return (-EINVAL);
-+	    }
-+	    /* always bus 0 */
-+	    ISP_LOCKU_SOFTC(isp);
-+	    (void) isp_control(isp, ISPCTL_RESET_DEV, &dev);
-+	    ISP_UNLKU_SOFTC(isp);
-+	    io = len;
-+	} else if (strncmp(buf, "reset", 5) == 0) {
-+	    ISP_LOCKU_SOFTC(isp);
-+	    io = isp_drain_reset(isp, "proc_reset");
-+	    ISP_UNLKU_SOFTC(isp);
-+	    if (io == 0)
-+		io = len;
-+	    else
-+		io = -EIO;
-+	} else if (strncmp(buf, "drain", 5) == 0) {
-+	    ISP_LOCKU_SOFTC(isp);
-+	    io = isp_drain(isp, "proc_reset");
-+	    ISP_UNLKU_SOFTC(isp);
-+	    if (io == 0)
-+		io = len;
-+	    else
-+		io = -EIO;
-+	}
-+#ifdef	ISP_FW_CRASH_DUMP
-+	else if (strncmp(buf, "fwcrash", 7) == 0) {
-+	    if (IS_FC(isp)) {
-+		ISP_LOCKU_SOFTC(isp);
-+		SEND_THREAD_EVENT(isp, ISP_THREAD_FW_CRASH_DUMP, 0);
-+		ISP_UNLKU_SOFTC(isp);
-+		io = len;
-+	    }
-+	}
-+#endif
-+	return (io);
-+    }
-+
-+    ISP_LOCKU_SOFTC(isp);
-+    if (st)
-+	*st = buf;
-+    info.buffer	= buf;
-+    info.length	= len;
-+    info.offset	= off;
-+    info.pos	= 0;
-+    
-+    copy_info(&info, (char *)isplinux_info(isp->isp_host));
-+#ifdef	HBA_VERSION
-+    copy_info(&info, "\n HBA Version %s, built %s, %s",
-+	HBA_VERSION, __DATE__, __TIME__);
-+#endif
-+    copy_info(&info, "\n DEVID %x role %d\n",
-+	isp->isp_osinfo.device_id, isp->isp_role);
-+    copy_info(&info,
-+        " Interrupt Stats:\n"
-+	"  total=0x%08x%08x bogus=0x%08x%08x\n"
-+	"  MboxC=0x%08x%08x async=0x%08x%08x\n"
-+	"  CRslt=0x%08x%08x CPost=0x%08x%08x\n"
-+	"  RspnsCHiWater=0x%04x FastPostC_Hiwater=0x%04x\n",
-+	(u_int32_t) (isp->isp_intcnt >> 32),
-+	(u_int32_t) (isp->isp_intcnt & 0xffffffff),
-+	(u_int32_t) (isp->isp_intbogus >> 32),
-+	(u_int32_t) (isp->isp_intbogus & 0xffffffff),
-+	(u_int32_t) (isp->isp_intmboxc >> 32),
-+	(u_int32_t) (isp->isp_intmboxc & 0xffffffff),
-+	(u_int32_t) (isp->isp_intoasync >> 32),
-+	(u_int32_t) (isp->isp_intoasync & 0xffffffff),
-+	(u_int32_t) (isp->isp_rsltccmplt >> 32),
-+	(u_int32_t) (isp->isp_rsltccmplt & 0xffffffff),
-+	(u_int32_t) (isp->isp_fphccmplt >> 32),
-+	(u_int32_t) (isp->isp_fphccmplt & 0xffffffff),
-+	isp->isp_rscchiwater, isp->isp_fpcchiwater);
-+    copy_info(&info,
-+	" Request In %d Request Out %d Result %d Nactv %d"
-+	" HiWater %u QAVAIL %d WtQHi %d\n",
-+	isp->isp_reqidx, isp->isp_reqodx, isp->isp_residx, isp->isp_nactive,
-+	isp->isp_osinfo.hiwater, ISP_QAVAIL(isp),
-+	isp->isp_osinfo.wqhiwater);
-+    for (i = 0; i < isp->isp_maxcmds; i++) {
-+	if (isp->isp_xflist[i]) {
-+	    copy_info(&info, " %d:%p", i, isp->isp_xflist[i]);
-+	}
-+    }
-+    copy_info(&info, "\n");
-+    if (isp->isp_osinfo.wqnext) {
-+	Scsi_Cmnd *f = isp->isp_osinfo.wqnext;
-+	copy_info(&info, "WaitQ(%d)", isp->isp_osinfo.wqcnt);
-+	while (f) {
-+	    copy_info(&info, "->%p", f);
-+	    f = (Scsi_Cmnd *) f->host_scribble;
-+	}
-+	copy_info(&info, "\n");
-+    }
-+    if (isp->isp_osinfo.dqnext) {
-+	Scsi_Cmnd *f = isp->isp_osinfo.dqnext;
-+	copy_info(&info, "DoneQ");
-+	while (f) {
-+	    copy_info(&info, "->%p", f);
-+	    f = (Scsi_Cmnd *) f->host_scribble;
-+	}
-+        copy_info(&info, "\n");
-+    }
-+    if (IS_FC(isp)) {
-+	fcparam *fcp = isp->isp_param;
-+	copy_info(&info,
-+	    "Loop ID: %d AL_PA 0x%x Port ID 0x%x FW State %x Loop State %x\n",
-+	    fcp->isp_loopid, fcp->isp_alpa, fcp->isp_portid, fcp->isp_fwstate,
-+	    fcp->isp_loopstate);
-+	copy_info(&info, "Port WWN 0x%08x%08x Node WWN 0x%08x%08x\n",
-+	    (unsigned int) (ISP_PORTWWN(isp) >> 32),
-+	    (unsigned int) (ISP_PORTWWN(isp) & 0xffffffff),
-+	    (unsigned int) (ISP_NODEWWN(isp) >> 32),
-+	    (unsigned int) (ISP_NODEWWN(isp) & 0xffffffff));
-+	for (i = 0; i < MAX_FC_TARG; i++) {
-+	    if (fcp->portdb[i].valid == 0 && i < FL_PORT_ID)
-+		continue;
-+	    if (fcp->portdb[i].port_wwn == 0)
-+		continue;
-+	    copy_info(&info, "TGT % 3d Loop ID % 3d Port id 0x%04x, role %s"
-+		"\n Port WWN 0x%08x%08x Node WWN 0x%08x%08x\n\n", i,
-+		fcp->portdb[i].loopid,
-+		fcp->portdb[i].portid, class3_roles[fcp->portdb[i].roles],
-+		(unsigned int) (fcp->portdb[i].port_wwn >> 32),
-+		(unsigned int) (fcp->portdb[i].port_wwn & 0xffffffff),
-+		(unsigned int) (fcp->portdb[i].node_wwn >> 32),
-+		(unsigned int) (fcp->portdb[i].node_wwn & 0xffffffff));
-+	}
-+    } else {
-+	sdparam *sdp = (sdparam *)isp->isp_param;
-+
-+	copy_info(&info, "Initiator ID: %d\n", sdp->isp_initiator_id);
-+	copy_info(&info, "Target Flag  Period Offset\n");
-+	for (i = 0; i < MAX_TARGETS; i++) {
-+	    copy_info(&info, "%6d: 0x%04x 0x%04x 0x%x\n",
-+		i, sdp->isp_devparam[i].actv_flags,
-+		sdp->isp_devparam[i].actv_offset,
-+		sdp->isp_devparam[i].actv_period);
-+	}
-+	if (IS_DUALBUS(isp)) {
-+	    sdp++;
-+  	    copy_info(&info, "\nInitiator ID: %d, Channel B\n",
-+		sdp->isp_initiator_id);
-+	    copy_info(&info,
-+		"Target     CurFlag    DevFlag  Period Offset B-Channel\n");
-+	    for (i = 0; i < MAX_TARGETS; i++) {
-+		    copy_info(&info, "%6d: 0x%04x 0x%04x 0x%x\n",
-+			i, sdp->isp_devparam[i].actv_flags,
-+			sdp->isp_devparam[i].actv_offset,
-+			sdp->isp_devparam[i].actv_period);
-+	    }
-+	}
-+    }
-+    ISP_UNLKU_SOFTC(isp);
-+    return (info.pos > info.offset ? info.pos - info.offset : 0);
-+}
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+static int isp_open(struct inode *, struct file *);
-+static int isp_close(struct inode *, struct file *);
-+static int
-+isp_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+
-+struct file_operations isp_procfs_operations = {
-+ owner:		THIS_MODULE,
-+ open:		isp_open,
-+ release:	isp_close,
-+ ioctl:		isp_ioctl,
-+};
-+
-+static struct proc_dir_entry *isp_root = 0;
-+
-+void
-+isplinux_init_proc(struct ispsoftc *isp)
-+{
-+    struct proc_dir_entry *isp_entry;
-+    char tbuf[64];
-+
-+    SNPRINTF(tbuf, sizeof(tbuf), "isp%d@0x%x", isp->isp_unit,
-+	isp->isp_osinfo.device_id);
-+    if (isp_root == NULL) {
-+	isp_root = proc_mkdir("isp", 0);
-+    }
-+    if (isp_root) {
-+	isp_entry = create_proc_entry(tbuf, S_IFREG|S_IRUGO|S_IWUSR, isp_root);
-+	if (isp_entry == NULL) {
-+	    return;
-+	}
-+	isp_entry->proc_fops = &isp_procfs_operations;
-+    }
-+}
-+
-+void
-+isplinux_undo_proc(struct ispsoftc *isp)
-+{
-+    char tbuf[64];
-+    SNPRINTF(tbuf, sizeof(tbuf), "isp/isp%d@0x%x", isp->isp_unit,
-+	isp->isp_osinfo.device_id);
-+    remove_proc_entry(tbuf, 0);
-+    remove_proc_entry("isp", 0);
-+}
-+
-+static struct ispsoftc *
-+get_isp_from_procname(const unsigned char *name)
-+{
-+    struct ispsoftc *isp;
-+
-+    for (isp = isplist; isp; isp = isp->isp_next) {
-+	char tbuf[32];
-+	SNPRINTF(tbuf, sizeof(tbuf), "isp%d@0x%x", isp->isp_unit,
-+	   isp->isp_osinfo.device_id);
-+	if (strcmp(name, tbuf) == 0) {
-+	    return (isp);
-+	}
-+    }
-+    return (0);
-+}
-+
-+static int
-+isp_open(struct inode *ip, struct file *fp)
-+{
-+    struct ispsoftc *isp = get_isp_from_procname(fp->f_dentry->d_name.name);
-+    if (isp == NULL) {
-+	return (-ENXIO);
-+    }
-+    if (isp->isp_isopen) {
-+	return (-EBUSY);
-+    }
-+    isp->isp_isopen = 1;
-+    fp->private_data = isp;
-+    return (0);
-+}
-+
-+static int
-+isp_close(struct inode *ip, struct file *fp)
-+{
-+    struct ispsoftc *isp = fp->private_data;
-+    isp->isp_isopen = 0;
-+    return (0);
-+}
-+
-+static int
-+isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
-+{
-+    struct ispsoftc *isp = fp->private_data;
-+    int rv, inarg, outarg;
-+    fcparam *fcp;
-+
-+    if (isp == (struct ispsoftc *)NULL) {
-+    	return -ENXIO;
-+    }
-+
-+    if (IS_SCSI(isp)) {
-+    	switch (c) {
-+    	case ISP_SDBLEV:
-+    	case ISP_RESCAN:
-+    	case ISP_GETROLE:
-+    	case ISP_SETROLE:
-+    	case ISP_RESETHBA:
-+    		break;
-+    	default:
-+		return (-EINVAL);
-+    	}
-+    	fcp = NULL;
-+    } else {
-+    	fcp = isp->isp_param;
-+    }
-+
-+    rv = 0;
-+    isp_prt(isp, ISP_LOGDEBUG0, "isp_ioctl: cmd=%x", c);
-+
-+    switch (c) {
-+    case ISP_GET_STATS:
-+    {
-+    	isp_stats_t stats;
-+
-+    	MEMZERO(&stats, sizeof stats);
-+    	stats.isp_stat_version = ISP_STATS_VERSION;
-+    	stats.isp_type = isp->isp_type;
-+    	stats.isp_revision = isp->isp_revision;
-+    	ISP_LOCK_SOFTC(isp);
-+    	stats.isp_stats[ISP_INTCNT] = isp->isp_intcnt;
-+    	stats.isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
-+    	stats.isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
-+    	stats.isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
-+    	stats.isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
-+    	stats.isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
-+    	stats.isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
-+    	stats.isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
-+    	ISP_UNLK_SOFTC(isp);
-+    	if (COPYOUT(&stats, (void *)arg, sizeof (stats), 0)) {
-+    		rv = EFAULT;
-+    	}
-+    	break;
-+    }
-+    case ISP_CLR_STATS:
-+    	ISP_LOCK_SOFTC(isp);
-+    	isp->isp_intcnt = 0;
-+    	isp->isp_intbogus = 0;
-+    	isp->isp_intmboxc = 0;
-+    	isp->isp_intoasync = 0;
-+    	isp->isp_rsltccmplt = 0;
-+    	isp->isp_fphccmplt = 0;
-+    	isp->isp_rscchiwater = 0;
-+    	isp->isp_fpcchiwater = 0;
-+    	ISP_UNLK_SOFTC(isp);
-+    	break;
-+#ifdef	ISP_FW_CRASH_DUMP
-+    case ISP_GET_FW_CRASH_DUMP:
-+    {
-+    	u_int16_t *ptr = fcp->isp_dump_data;
-+    	size_t sz;
-+    	if (IS_2200(isp))
-+    		sz = QLA2200_RISC_IMAGE_DUMP_SIZE;
-+    	else
-+    		sz = QLA2300_RISC_IMAGE_DUMP_SIZE;
-+    	ISP_LOCK_SOFTC(isp);
-+    	if (ptr && *ptr) {
-+    		if (COPYOUT(ptr, (void *)arg, sz, mode)) {
-+    			rv = EFAULT;
-+    		} else {
-+    			*ptr = 0;
-+    		}
-+    	} else {
-+    		rv = ENXIO;
-+    	}
-+    	ISP_UNLK_SOFTC(isp);
-+    	break;
-+    }
-+
-+    case ISP_FORCE_CRASH_DUMP:
-+    	ISP_LOCK_SOFTC(isp);
-+    	isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-+    	ISP_UNLK_SOFTC(isp);
-+    	break;
-+#endif
-+    case ISP_SDBLEV:
-+    	if (COPYIN((void *)arg, &inarg, sizeof (inarg), 0)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	outarg = isp->isp_dblev;
-+    	isp->isp_dblev = inarg;
-+    	if (COPYOUT(&outarg, (void *)arg, sizeof (outarg), 0)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	break;
-+
-+    case ISP_RESCAN:
-+    	if (IS_FC(isp)) {
-+	    ISP_LOCKU_SOFTC(isp);
-+	    SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0)
-+	    ISP_UNLKU_SOFTC(isp);
-+    	}
-+    	break;
-+
-+    case ISP_GETROLE:
-+    	outarg = isp->isp_role;
-+    	if (COPYOUT(&outarg, (void *)arg, sizeof (outarg), 0)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	break;
-+
-+    case ISP_SETROLE:
-+    	if (COPYIN((void *)arg, &inarg, sizeof (inarg), 0)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	if (inarg & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
-+    		rv = EINVAL;
-+    		break;
-+    	}
-+    	/*
-+    	 * Check to see if we're already in that role.
-+    	 */
-+    	if (isp->isp_role == inarg) {
-+    		outarg = isp->isp_role;
-+    		if (COPYOUT(&outarg, (void *)arg, sizeof (outarg), mode)) {
-+    			rv = EFAULT;
-+    		}
-+    		break;
-+    	}
-+    	/*FALLTHROUGH*/
-+    case ISP_RESETHBA:
-+    {
-+    	ISP_LOCK_SOFTC(isp);
-+    	if (c == ISP_SETROLE) {
-+    		outarg = isp->isp_role;
-+    		isp->isp_role = inarg;
-+    	}
-+    	if (isp_drain_reset(isp, "isp_ioctl")) {
-+    		ISP_UNLK_SOFTC(isp);
-+    		rv = EIO;
-+    		break;
-+    	}
-+    	isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-+    	ISP_UNLK_SOFTC(isp);
-+    	if (c == ISP_SETROLE &&
-+    	    COPYOUT(&outarg, (void *)arg, sizeof (outarg), mode)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	break;
-+    }
-+    case ISP_FC_LIP:
-+    	ISP_LOCK_SOFTC(isp);
-+    	if (isp_control(isp, ISPCTL_SEND_LIP, NULL)) {
-+    		rv = EIO;
-+    	}
-+    	ISP_UNLK_SOFTC(isp);
-+    	break;
-+    case ISP_FC_GETDINFO:
-+    {
-+    	struct isp_fc_device local, *ifc = &local;
-+    	struct lportdb *lp;
-+
-+    	if (COPYIN((void *)arg, ifc, sizeof (*ifc), mode)) {
-+    		rv = EFAULT;
-+    		break;
-+    	}
-+    	if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) {
-+    		rv = EINVAL;
-+    		break;
-+    	}
-+    	ISP_LOCK_SOFTC(isp);
-+    	lp = &FCPARAM(isp)->portdb[ifc->loopid];
-+    	if (lp->valid) {
-+    		ifc->loopid = lp->loopid;
-+    		ifc->portid = lp->portid;
-+    		ifc->node_wwn = lp->node_wwn;
-+    		ifc->port_wwn = lp->port_wwn;
-+    		rv = 0;
-+    	} else {
-+    		rv = ENODEV;
-+    	}
-+    	ISP_UNLK_SOFTC(isp);
-+    	if (rv == 0) {
-+    		if (COPYOUT((void *)ifc, (void *)arg,
-+    		    sizeof (*ifc), mode)) {
-+    			rv = EFAULT;
-+    		}
-+    	}
-+    	break;
-+    }
-+    case ISP_FC_GETHINFO:
-+    {
-+	struct isp_hba_device local, *hba = &local;
-+	MEMZERO(hba, sizeof (*hba));
-+	ISP_LOCK_SOFTC(isp);
-+	hba->fc_speed = FCPARAM(isp)->isp_gbspeed;
-+	hba->fc_scsi_supported = 1;
-+	hba->fc_topology = FCPARAM(isp)->isp_topo + 1;
-+	hba->fc_loopid = FCPARAM(isp)->isp_loopid;
-+	hba->active_node_wwn = FCPARAM(isp)->isp_nodewwn;
-+	hba->active_port_wwn = FCPARAM(isp)->isp_portwwn;
-+	ISP_UNLK_SOFTC(isp);
-+	if (COPYOUT(hba, (void *)arg, sizeof (*hba), mode)) {
-+	    rv = EFAULT;
-+	    break;
-+	}
-+	break;
-+    }
-+    default:
-+    	rv = EINVAL;
-+    	break;
-+    }
-+    return(rv? -rv : 0);
-+}
-+#endif	/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) */
-+#endif
-+/*
-+ * mode: c
-+ * Local variables:
-+ * c-indent-level: 4
-+ * c-brace-imaginary-offset: 0
-+ * c-brace-offset: -4
-+ * c-argdecl-indent: 4
-+ * c-label-offset: -4
-+ * c-continued-statement-offset: 4
-+ * c-continued-brace-offset: 0
-+ * End:
-+ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_inline.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,1495 @@
-+/* @(#)isp_inline.h 1.20 */
-+/*
-+ * Qlogic Host Adapter Inline Functions
-+ *
-+ * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
-+ * Feral Software
-+ * All rights reserved.
-+ * mjacob@feral.com
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+#ifndef	_ISP_INLINE_H
-+#define	_ISP_INLINE_H
-+
-+/*
-+ * Handle Functions.
-+ * For each outstanding command there will be a non-zero handle.
-+ * There will be at most isp_maxcmds handles, and isp_lasthdls
-+ * will be a seed for the last handled allocated.
-+ */
-+
-+static INLINE int isp_save_xs(struct ispsoftc *, XS_T *, u_int16_t *);
-+static INLINE XS_T *isp_find_xs(struct ispsoftc *, u_int16_t);
-+static INLINE u_int16_t isp_find_handle(struct ispsoftc *, XS_T *);
-+static INLINE int isp_handle_index(u_int16_t);
-+static INLINE void isp_destroy_handle(struct ispsoftc *, u_int16_t);
-+static INLINE void isp_remove_handle(struct ispsoftc *, XS_T *);
-+
-+static INLINE int
-+isp_save_xs(struct ispsoftc *isp, XS_T *xs, u_int16_t *handlep)
-+{
-+	int i, j;
-+
-+	for (j = isp->isp_lasthdls, i = 0; i < (int) isp->isp_maxcmds; i++) {
-+		if (isp->isp_xflist[j] == NULL) {
-+			break;
-+		}
-+		if (++j == isp->isp_maxcmds) {
-+			j = 0;
-+		}
-+	}
-+	if (i == isp->isp_maxcmds) {
-+		return (-1);
-+	}
-+	isp->isp_xflist[j] = xs;
-+	*handlep = j+1;
-+	if (++j == isp->isp_maxcmds)
-+		j = 0;
-+	isp->isp_lasthdls = (u_int16_t)j;
-+	return (0);
-+}
-+
-+static INLINE XS_T *
-+isp_find_xs(struct ispsoftc *isp, u_int16_t handle)
-+{
-+	if (handle < 1 || handle > (u_int16_t) isp->isp_maxcmds) {
-+		return (NULL);
-+	} else {
-+		return (isp->isp_xflist[handle - 1]);
-+	}
-+}
-+
-+static INLINE u_int16_t
-+isp_find_handle(struct ispsoftc *isp, XS_T *xs)
-+{
-+	int i;
-+	if (xs != NULL) {
-+		for (i = 0; i < isp->isp_maxcmds; i++) {
-+			if (isp->isp_xflist[i] == xs) {
-+				return ((u_int16_t) i+1);
-+			}
-+		}
-+	}
-+	return (0);
-+}
-+
-+static INLINE int
-+isp_handle_index(u_int16_t handle)
-+{
-+	return (handle-1);
-+}
-+
-+static INLINE void
-+isp_destroy_handle(struct ispsoftc *isp, u_int16_t handle)
-+{
-+	if (handle > 0 && handle <= (u_int16_t) isp->isp_maxcmds) {
-+		isp->isp_xflist[isp_handle_index(handle)] = NULL;
-+	}
-+}
-+
-+static INLINE void
-+isp_remove_handle(struct ispsoftc *isp, XS_T *xs)
-+{
-+	isp_destroy_handle(isp, isp_find_handle(isp, xs));
-+}
-+
-+static INLINE int
-+isp_getrqentry(struct ispsoftc *, u_int16_t *, u_int16_t *, void **);
-+
-+static INLINE int
-+isp_getrqentry(struct ispsoftc *isp, u_int16_t *iptrp,
-+    u_int16_t *optrp, void **resultp)
-+{
-+	volatile u_int16_t iptr, optr;
-+
-+	optr = isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
-+	iptr = isp->isp_reqidx;
-+	*resultp = ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
-+	iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN(isp));
-+	if (iptr == optr) {
-+		return (1);
-+	}
-+	if (optrp)
-+		*optrp = optr;
-+	if (iptrp)
-+		*iptrp = iptr;
-+	return (0);
-+}
-+
-+static INLINE void isp_print_qentry (struct ispsoftc *, char *, int, void *);
-+
-+
-+#define	TBA	(4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1)
-+static INLINE void
-+isp_print_qentry(struct ispsoftc *isp, char *msg, int idx, void *arg)
-+{
-+	char buf[TBA];
-+	int amt, i, j;
-+	u_int8_t *ptr = arg;
-+
-+	isp_prt(isp, ISP_LOGALL, "%s index %d=>", msg, idx);
-+	for (buf[0] = 0, amt = i = 0; i < 4; i++) {
-+		buf[0] = 0;
-+		SNPRINTF(buf, TBA, "  ");
-+		for (j = 0; j < (QENTRY_LEN >> 2); j++) {
-+			SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff);
-+		}
-+		isp_prt(isp, ISP_LOGALL, buf);
-+	}
-+}
-+
-+static INLINE void isp_print_bytes(struct ispsoftc *, char *, int, void *);
-+
-+static INLINE void
-+isp_print_bytes(struct ispsoftc *isp, char *msg, int amt, void *arg)
-+{
-+	char buf[128];
-+	u_int8_t *ptr = arg;
-+	int off;
-+
-+	if (msg)
-+		isp_prt(isp, ISP_LOGALL, "%s:", msg);
-+	off = 0;
-+	buf[0] = 0;
-+	while (off < amt) {
-+		int j, to;
-+		to = off;
-+		for (j = 0; j < 16; j++) {
-+			SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff);
-+			if (off == amt)
-+				break;
-+		}
-+		isp_prt(isp, ISP_LOGALL, "0x%08x:%s", to, buf);
-+		buf[0] = 0;
-+	}
-+}
-+
-+/*
-+ * Do the common path to try and ensure that link is up, we've scanned
-+ * the fabric (if we're on a fabric), and that we've synchronized this
-+ * all with our own database and done the appropriate logins.
-+ *
-+ * We repeatedly check for firmware state and loop state after each
-+ * action because things may have changed while we were doing this.
-+ * Any failure or change of state causes us to return a nonzero value.
-+ *
-+ * We honor HBA roles in that if we're not in Initiator mode, we don't
-+ * attempt to sync up the database (that's for somebody else to do,
-+ * if ever).
-+ *
-+ * We assume we enter here with any locks held.
-+ */
-+
-+static INLINE int isp_fc_runstate(struct ispsoftc *, int);
-+
-+static INLINE int
-+isp_fc_runstate(struct ispsoftc *isp, int tval)
-+{
-+	fcparam *fcp;
-+	int *tptr;
-+
-+	if (IS_SCSI(isp))
-+		return (0);
-+
-+	tptr = tval? &tval : NULL;
-+	if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) {
-+		return (-1);
-+	}
-+	fcp = FCPARAM(isp);
-+	if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_PDB_RCVD)
-+		return (-1);
-+	if (isp_control(isp, ISPCTL_SCAN_FABRIC, NULL) != 0) {
-+		return (-1);
-+	}
-+	if (isp_control(isp, ISPCTL_SCAN_LOOP, NULL) != 0) {
-+		return (-1);
-+	}
-+	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
-+		return (0);
-+	}
-+	if (isp_control(isp, ISPCTL_PDB_SYNC, NULL) != 0) {
-+		return (-1);
-+	}
-+	if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
-+		return (-1);
-+	}
-+	return (0);
-+}
-+
-+/*
-+ * Functions to move stuff to a form that the QLogic RISC engine understands
-+ * and functions to move stuff back to a form the processor understands.
-+ *
-+ * Each platform is required to provide the 8, 16 and 32 bit
-+ * swizzle and unswizzle macros (ISP_IOX{PUT|GET}_{8,16,32})
-+ *
-+ * The assumption is that swizzling and unswizzling is mostly done 'in place'
-+ * (with a few exceptions for efficiency).
-+ */
-+
-+static INLINE void isp_copy_out_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
-+static INLINE void isp_copy_in_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
-+static INLINE int isp_get_response_type(struct ispsoftc *, isphdr_t *);
-+
-+static INLINE void
-+isp_put_request(struct ispsoftc *, ispreq_t *, ispreq_t *);
-+static INLINE void
-+isp_put_request_t2(struct ispsoftc *, ispreqt2_t *, ispreqt2_t *);
-+static INLINE void
-+isp_put_request_t3(struct ispsoftc *, ispreqt3_t *, ispreqt3_t *);
-+static INLINE void
-+isp_put_extended_request(struct ispsoftc *, ispextreq_t *, ispextreq_t *);
-+static INLINE void
-+isp_put_cont_req(struct ispsoftc *, ispcontreq_t *, ispcontreq_t *);
-+static INLINE void
-+isp_put_cont64_req(struct ispsoftc *, ispcontreq64_t *, ispcontreq64_t *);
-+static INLINE void
-+isp_get_response(struct ispsoftc *, ispstatusreq_t *, ispstatusreq_t *);
-+static INLINE void
-+isp_get_response_x(struct ispsoftc *, ispstatus_cont_t *, ispstatus_cont_t *);
-+static INLINE void
-+isp_get_rio2(struct ispsoftc *, isp_rio2_t *, isp_rio2_t *);
-+static INLINE void
-+isp_put_icb(struct ispsoftc *, isp_icb_t *, isp_icb_t *);
-+static INLINE void
-+isp_get_pdb(struct ispsoftc *, isp_pdb_t *, isp_pdb_t *);
-+static INLINE void
-+isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *, ct_hdr_t *);
-+static INLINE void
-+isp_put_sns_request(struct ispsoftc *, sns_screq_t *, sns_screq_t *);
-+static INLINE void
-+isp_put_gid_ft_request(struct ispsoftc *, sns_gid_ft_req_t *,
-+    sns_gid_ft_req_t *);
-+static INLINE void
-+isp_put_gxn_id_request(struct ispsoftc *, sns_gxn_id_req_t *,
-+    sns_gxn_id_req_t *);
-+static INLINE void
-+isp_get_sns_response(struct ispsoftc *, sns_scrsp_t *, sns_scrsp_t *, int);
-+static INLINE void
-+isp_get_gid_ft_response(struct ispsoftc *, sns_gid_ft_rsp_t *,
-+    sns_gid_ft_rsp_t *, int);
-+static INLINE void
-+isp_get_gxn_id_response(struct ispsoftc *, sns_gxn_id_rsp_t *,
-+    sns_gxn_id_rsp_t *);
-+static INLINE void
-+isp_get_gff_id_response(struct ispsoftc *, sns_gff_id_rsp_t *,
-+    sns_gff_id_rsp_t *);
-+static INLINE void
-+isp_get_ga_nxt_response(struct ispsoftc *, sns_ga_nxt_rsp_t *,
-+    sns_ga_nxt_rsp_t *);
-+#ifdef	ISP_TARGET_MODE
-+#ifndef	_ISP_TARGET_H
-+#include "isp_target.h"
-+#endif
-+static INLINE void
-+isp_put_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
-+static INLINE void
-+isp_get_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
-+static INLINE void
-+isp_put_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
-+static INLINE void
-+isp_get_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
-+static INLINE void
-+isp_put_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
-+static INLINE void
-+isp_get_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
-+static INLINE void
-+isp_put_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
-+static INLINE void
-+isp_get_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
-+static INLINE void
-+isp_put_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
-+static INLINE void
-+isp_get_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
-+static INLINE void
-+isp_put_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
-+static INLINE void
-+isp_get_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
-+static INLINE void
-+isp_put_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
-+static INLINE void
-+isp_get_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
-+static INLINE void
-+isp_put_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
-+static INLINE void
-+isp_get_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
-+static INLINE void
-+isp_put_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
-+static INLINE void
-+isp_get_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
-+#endif
-+
-+#define	ISP_IS_SBUS(isp)	\
-+	(ISP_SBUS_SUPPORTED && (isp)->isp_bustype == ISP_BT_SBUS)
-+
-+/*
-+ * Swizzle/Copy Functions
-+ */
-+static INLINE void
-+isp_copy_out_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
-+{
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type,
-+		    &hpdst->rqs_entry_count);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_entry_count,
-+		    &hpdst->rqs_entry_type);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_seqno,
-+		    &hpdst->rqs_flags);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_flags,
-+		    &hpdst->rqs_seqno);
-+	} else {
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type,
-+		    &hpdst->rqs_entry_type);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_entry_count,
-+		    &hpdst->rqs_entry_count);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_seqno,
-+		    &hpdst->rqs_seqno);
-+		ISP_IOXPUT_8(isp, hpsrc->rqs_flags,
-+		    &hpdst->rqs_flags);
-+	}
-+}
-+
-+static INLINE void
-+isp_copy_in_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
-+{
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type,
-+		    hpdst->rqs_entry_count);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_entry_count,
-+		    hpdst->rqs_entry_type);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_seqno,
-+		    hpdst->rqs_flags);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_flags,
-+		    hpdst->rqs_seqno);
-+	} else {
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type,
-+		    hpdst->rqs_entry_type);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_entry_count,
-+		    hpdst->rqs_entry_count);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_seqno,
-+		    hpdst->rqs_seqno);
-+		ISP_IOXGET_8(isp, &hpsrc->rqs_flags,
-+		    hpdst->rqs_flags);
-+	}
-+}
-+
-+static INLINE int
-+isp_get_response_type(struct ispsoftc *isp, isphdr_t *hp)
-+{
-+	u_int8_t type;
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &hp->rqs_entry_count, type);
-+	} else {
-+		ISP_IOXGET_8(isp, &hp->rqs_entry_type, type);
-+	}
-+	return ((int)type);
-+}
-+
-+static INLINE void
-+isp_put_request(struct ispsoftc *isp, ispreq_t *rqsrc, ispreq_t *rqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &rqsrc->req_header, &rqdst->req_header);
-+	ISP_IOXPUT_32(isp, rqsrc->req_handle, &rqdst->req_handle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_target);
-+		ISP_IOXPUT_8(isp, rqsrc->req_target, &rqdst->req_lun_trn);
-+	} else {
-+		ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_lun_trn);
-+		ISP_IOXPUT_8(isp, rqsrc->req_target, &rqdst->req_target);
-+	}
-+	ISP_IOXPUT_16(isp, rqsrc->req_cdblen, &rqdst->req_cdblen);
-+	ISP_IOXPUT_16(isp, rqsrc->req_flags, &rqdst->req_flags);
-+	ISP_IOXPUT_16(isp, rqsrc->req_time, &rqdst->req_time);
-+	ISP_IOXPUT_16(isp, rqsrc->req_seg_count, &rqdst->req_seg_count);
-+	for (i = 0; i < 12; i++) {
-+		ISP_IOXPUT_8(isp, rqsrc->req_cdb[i], &rqdst->req_cdb[i]);
-+	}
-+	for (i = 0; i < ISP_RQDSEG; i++) {
-+		ISP_IOXPUT_32(isp, rqsrc->req_dataseg[i].ds_base,
-+		    &rqdst->req_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, rqsrc->req_dataseg[i].ds_count,
-+		    &rqdst->req_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_request_t2(struct ispsoftc *isp, ispreqt2_t *tqsrc, ispreqt2_t *tqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
-+	ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
-+	ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
-+	ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target);
-+	ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
-+	ISP_IOXPUT_16(isp, tqsrc->req_flags,  &tqdst->req_flags);
-+	ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2);
-+	ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
-+	ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
-+	for (i = 0; i < 16; i++) {
-+		ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
-+	}
-+	ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
-+	for (i = 0; i < ISP_RQDSEG_T2; i++) {
-+		ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
-+		    &tqdst->req_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
-+		    &tqdst->req_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_request_t3(struct ispsoftc *isp, ispreqt3_t *tqsrc, ispreqt3_t *tqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
-+	ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
-+	ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
-+	ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target);
-+	ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
-+	ISP_IOXPUT_16(isp, tqsrc->req_flags,  &tqdst->req_flags);
-+	ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2);
-+	ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
-+	ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
-+	for (i = 0; i < 16; i++) {
-+		ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
-+	}
-+	ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
-+	for (i = 0; i < ISP_RQDSEG_T3; i++) {
-+		ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
-+		    &tqdst->req_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_basehi,
-+		    &tqdst->req_dataseg[i].ds_basehi);
-+		ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
-+		    &tqdst->req_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_extended_request(struct ispsoftc *isp, ispextreq_t *xqsrc,
-+    ispextreq_t *xqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &xqsrc->req_header, &xqdst->req_header);
-+	ISP_IOXPUT_32(isp, xqsrc->req_handle, &xqdst->req_handle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_target);
-+		ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_lun_trn);
-+	} else {
-+		ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_lun_trn);
-+		ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_target);
-+	}
-+	ISP_IOXPUT_16(isp, xqsrc->req_cdblen, &xqdst->req_cdblen);
-+	ISP_IOXPUT_16(isp, xqsrc->req_flags, &xqdst->req_flags);
-+	ISP_IOXPUT_16(isp, xqsrc->req_time, &xqdst->req_time);
-+	ISP_IOXPUT_16(isp, xqsrc->req_seg_count, &xqdst->req_seg_count);
-+	for (i = 0; i < 44; i++) {
-+		ISP_IOXPUT_8(isp, xqsrc->req_cdb[i], &xqdst->req_cdb[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_cont_req(struct ispsoftc *isp, ispcontreq_t *cqsrc, ispcontreq_t *cqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
-+	for (i = 0; i < ISP_CDSEG; i++) {
-+		ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
-+		    &cqdst->req_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
-+		    &cqdst->req_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_cont64_req(struct ispsoftc *isp, ispcontreq64_t *cqsrc,
-+    ispcontreq64_t *cqdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
-+	for (i = 0; i < ISP_CDSEG64; i++) {
-+		ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
-+		    &cqdst->req_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_basehi,
-+		    &cqdst->req_dataseg[i].ds_basehi);
-+		ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
-+		    &cqdst->req_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_response(struct ispsoftc *isp, ispstatusreq_t *spsrc,
-+    ispstatusreq_t *spdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &spsrc->req_header, &spdst->req_header);
-+	ISP_IOXGET_32(isp, &spsrc->req_handle, spdst->req_handle);
-+	ISP_IOXGET_16(isp, &spsrc->req_scsi_status, spdst->req_scsi_status);
-+	ISP_IOXGET_16(isp, &spsrc->req_completion_status,
-+	    spdst->req_completion_status);
-+	ISP_IOXGET_16(isp, &spsrc->req_state_flags, spdst->req_state_flags);
-+	ISP_IOXGET_16(isp, &spsrc->req_status_flags, spdst->req_status_flags);
-+	ISP_IOXGET_16(isp, &spsrc->req_time, spdst->req_time);
-+	ISP_IOXGET_16(isp, &spsrc->req_sense_len, spdst->req_sense_len);
-+	ISP_IOXGET_32(isp, &spsrc->req_resid, spdst->req_resid);
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &spsrc->req_response[i],
-+		    spdst->req_response[i]);
-+	}
-+	for (i = 0; i < 32; i++) {
-+		ISP_IOXGET_8(isp, &spsrc->req_sense_data[i],
-+		    spdst->req_sense_data[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_response_x(struct ispsoftc *isp, ispstatus_cont_t *cpsrc,
-+    ispstatus_cont_t *cpdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &cpsrc->req_header, &cpdst->req_header);
-+	for (i = 0; i < 60; i++) {
-+		ISP_IOXGET_8(isp, &cpsrc->req_sense_data[i],
-+		    cpdst->req_sense_data[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_rio2(struct ispsoftc *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &r2src->req_header, &r2dst->req_header);
-+	if (r2dst->req_header.rqs_seqno > 30)
-+		r2dst->req_header.rqs_seqno = 30;
-+	for (i = 0; i < r2dst->req_header.rqs_seqno; i++) {
-+		ISP_IOXGET_16(isp, &r2src->req_handles[i],
-+		    r2dst->req_handles[i]);
-+	}
-+	while (i < 30) {
-+		r2dst->req_handles[i++] = 0;
-+	}
-+}
-+
-+static INLINE void
-+isp_put_icb(struct ispsoftc *isp, isp_icb_t *Is, isp_icb_t *Id)
-+{
-+	int i;
-+	ISP_SWAP8(Is->icb_version, Is->_reserved0);
-+	ISP_IOXPUT_8(isp, Is->icb_version, &Id->icb_version);
-+	ISP_IOXPUT_8(isp, Is->_reserved0, &Id->_reserved0);
-+	ISP_IOXPUT_16(isp, Is->icb_fwoptions, &Id->icb_fwoptions);
-+	ISP_IOXPUT_16(isp, Is->icb_maxfrmlen, &Id->icb_maxfrmlen);
-+	ISP_IOXPUT_16(isp, Is->icb_maxalloc, &Id->icb_maxalloc);
-+	ISP_IOXPUT_16(isp, Is->icb_execthrottle, &Id->icb_execthrottle);
-+	ISP_SWAP8(Is->icb_retry_count, Is->icb_retry_delay);
-+	ISP_IOXPUT_8(isp, Is->icb_retry_count, &Id->icb_retry_count);
-+	ISP_IOXPUT_8(isp, Is->icb_retry_delay, &Id->icb_retry_delay);
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXPUT_8(isp, Is->icb_portname[i], &Id->icb_portname[i]);
-+	}
-+	ISP_IOXPUT_16(isp, Is->icb_hardaddr, &Id->icb_hardaddr);
-+	ISP_SWAP8(Is->icb_iqdevtype, Is->icb_logintime);
-+	ISP_IOXPUT_8(isp, Is->icb_iqdevtype, &Id->icb_iqdevtype);
-+	ISP_IOXPUT_8(isp, Is->icb_logintime, &Id->icb_logintime);
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXPUT_8(isp, Is->icb_nodename[i], &Id->icb_nodename[i]);
-+	}
-+	ISP_IOXPUT_16(isp, Is->icb_rqstout, &Id->icb_rqstout);
-+	ISP_IOXPUT_16(isp, Is->icb_rspnsin, &Id->icb_rspnsin);
-+	ISP_IOXPUT_16(isp, Is->icb_rqstqlen, &Id->icb_rqstqlen);
-+	ISP_IOXPUT_16(isp, Is->icb_rsltqlen, &Id->icb_rsltqlen);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXPUT_16(isp, Is->icb_rqstaddr[i], &Id->icb_rqstaddr[i]);
-+	}
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXPUT_16(isp, Is->icb_respaddr[i], &Id->icb_respaddr[i]);
-+	}
-+	ISP_IOXPUT_16(isp, Is->icb_lunenables, &Id->icb_lunenables);
-+	ISP_SWAP8(Is->icb_ccnt, Is->icb_icnt);
-+	ISP_IOXPUT_8(isp, Is->icb_ccnt, &Id->icb_ccnt);
-+	ISP_IOXPUT_8(isp, Is->icb_icnt, &Id->icb_icnt);
-+	ISP_IOXPUT_16(isp, Is->icb_lunetimeout, &Id->icb_lunetimeout);
-+	ISP_IOXPUT_16(isp, Is->icb_xfwoptions, &Id->icb_xfwoptions);
-+	ISP_SWAP8(Is->icb_racctimer, Is->icb_idelaytimer);
-+	ISP_IOXPUT_8(isp, Is->icb_racctimer, &Id->icb_racctimer);
-+	ISP_IOXPUT_8(isp, Is->icb_idelaytimer, &Id->icb_idelaytimer);
-+	ISP_IOXPUT_16(isp, Is->icb_zfwoptions, &Id->icb_zfwoptions);
-+}
-+
-+static INLINE void
-+isp_get_pdb(struct ispsoftc *isp, isp_pdb_t *src, isp_pdb_t *dst)
-+{
-+	int i;
-+	ISP_IOXGET_16(isp, &src->pdb_options, dst->pdb_options);
-+        ISP_IOXGET_8(isp, &src->pdb_mstate, dst->pdb_mstate);
-+        ISP_IOXGET_8(isp, &src->pdb_sstate, dst->pdb_sstate);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXGET_8(isp, &src->pdb_hardaddr_bits[i],
-+		    dst->pdb_hardaddr_bits[i]);
-+	}
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXGET_8(isp, &src->pdb_portid_bits[i],
-+		    dst->pdb_portid_bits[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->pdb_nodename[i], dst->pdb_nodename[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->pdb_portname[i], dst->pdb_portname[i]);
-+	}
-+	ISP_IOXGET_16(isp, &src->pdb_execthrottle, dst->pdb_execthrottle);
-+	ISP_IOXGET_16(isp, &src->pdb_exec_count, dst->pdb_exec_count);
-+	ISP_IOXGET_8(isp, &src->pdb_retry_count, dst->pdb_retry_count);
-+	ISP_IOXGET_8(isp, &src->pdb_retry_delay, dst->pdb_retry_delay);
-+	ISP_IOXGET_16(isp, &src->pdb_resalloc, dst->pdb_resalloc);
-+	ISP_IOXGET_16(isp, &src->pdb_curalloc, dst->pdb_curalloc);
-+	ISP_IOXGET_16(isp, &src->pdb_qhead, dst->pdb_qhead);
-+	ISP_IOXGET_16(isp, &src->pdb_qtail, dst->pdb_qtail);
-+	ISP_IOXGET_16(isp, &src->pdb_tl_next, dst->pdb_tl_next);
-+	ISP_IOXGET_16(isp, &src->pdb_tl_last, dst->pdb_tl_last);
-+	ISP_IOXGET_16(isp, &src->pdb_features, dst->pdb_features);
-+	ISP_IOXGET_16(isp, &src->pdb_pconcurrnt, dst->pdb_pconcurrnt);
-+	ISP_IOXGET_16(isp, &src->pdb_roi, dst->pdb_roi);
-+	ISP_IOXGET_8(isp, &src->pdb_target, dst->pdb_target);
-+	ISP_IOXGET_8(isp, &src->pdb_initiator, dst->pdb_initiator);
-+	ISP_IOXGET_16(isp, &src->pdb_rdsiz, dst->pdb_rdsiz);
-+	ISP_IOXGET_16(isp, &src->pdb_ncseq, dst->pdb_ncseq);
-+	ISP_IOXGET_16(isp, &src->pdb_noseq, dst->pdb_noseq);
-+	ISP_IOXGET_16(isp, &src->pdb_labrtflg, dst->pdb_labrtflg);
-+	ISP_IOXGET_16(isp, &src->pdb_lstopflg, dst->pdb_lstopflg);
-+	ISP_IOXGET_16(isp, &src->pdb_sqhead, dst->pdb_sqhead);
-+	ISP_IOXGET_16(isp, &src->pdb_sqtail, dst->pdb_sqtail);
-+	ISP_IOXGET_16(isp, &src->pdb_ptimer, dst->pdb_ptimer);
-+	ISP_IOXGET_16(isp, &src->pdb_nxt_seqid, dst->pdb_nxt_seqid);
-+	ISP_IOXGET_16(isp, &src->pdb_fcount, dst->pdb_fcount);
-+	ISP_IOXGET_16(isp, &src->pdb_prli_len, dst->pdb_prli_len);
-+	ISP_IOXGET_16(isp, &src->pdb_prli_svc0, dst->pdb_prli_svc0);
-+	ISP_IOXGET_16(isp, &src->pdb_prli_svc3, dst->pdb_prli_svc3);
-+	ISP_IOXGET_16(isp, &src->pdb_loopid, dst->pdb_loopid);
-+	ISP_IOXGET_16(isp, &src->pdb_il_ptr, dst->pdb_il_ptr);
-+	ISP_IOXGET_16(isp, &src->pdb_sl_ptr, dst->pdb_sl_ptr);
-+}
-+
-+
-+/*
-+ * CT_HDR canonicalization- only needed for SNS responses
-+ */
-+static INLINE void
-+isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *src, ct_hdr_t *dst)
-+{
-+	ISP_IOXGET_8(isp, &src->ct_revision, dst->ct_revision);
-+	ISP_IOXGET_8(isp, &src->ct_portid[0], dst->ct_portid[0]);
-+	ISP_IOXGET_8(isp, &src->ct_portid[1], dst->ct_portid[1]);
-+	ISP_IOXGET_8(isp, &src->ct_portid[2], dst->ct_portid[2]);
-+	ISP_IOXGET_8(isp, &src->ct_fcs_type, dst->ct_fcs_type);
-+	ISP_IOXGET_8(isp, &src->ct_fcs_subtype, dst->ct_fcs_subtype);
-+	ISP_IOXGET_8(isp, &src->ct_options, dst->ct_options);
-+	ISP_IOXGET_8(isp, &src->ct_res0, dst->ct_res0);
-+	ISP_IOXGET_16(isp, &src->ct_response, dst->ct_response);
-+	dst->ct_response = (dst->ct_response << 8) | (dst->ct_response >> 8);
-+	ISP_IOXGET_16(isp, &src->ct_resid, dst->ct_resid);
-+	dst->ct_resid = (dst->ct_resid << 8) | (dst->ct_resid >> 8);
-+	ISP_IOXGET_8(isp, &src->ct_res1, dst->ct_res1);
-+	ISP_IOXGET_8(isp, &src->ct_reason, dst->ct_reason);
-+	ISP_IOXGET_8(isp, &src->ct_explanation, dst->ct_explanation);
-+	ISP_IOXGET_8(isp, &src->ct_vunique, dst->ct_vunique);
-+}
-+
-+/*
-+ * Generic SNS request - not particularly useful since the per-command data
-+ * isn't always 16 bit words.
-+ */
-+static INLINE void
-+isp_put_sns_request(struct ispsoftc *isp, sns_screq_t *src, sns_screq_t *dst)
-+{
-+	int i, nw = (int) src->snscb_sblen;
-+	ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXPUT_16(isp, src->snscb_addr[i], &dst->snscb_addr[i]);
-+	}
-+	ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen);
-+	for (i = 0; i < nw; i++) {
-+		ISP_IOXPUT_16(isp, src->snscb_data[i], &dst->snscb_data[i]);
-+	}
-+	
-+}
-+
-+static INLINE void
-+isp_put_gid_ft_request(struct ispsoftc *isp, sns_gid_ft_req_t *src,
-+    sns_gid_ft_req_t *dst)
-+{
-+	ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
-+	ISP_IOXPUT_16(isp, src->snscb_res0, &dst->snscb_res0);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[0], &dst->snscb_addr[0]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[1], &dst->snscb_addr[1]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[2], &dst->snscb_addr[2]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[3], &dst->snscb_addr[3]);
-+	ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen);
-+	ISP_IOXPUT_16(isp, src->snscb_res1, &dst->snscb_res1);
-+	ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd);
-+	ISP_IOXPUT_16(isp, src->snscb_mword_div_2, &dst->snscb_mword_div_2);
-+	ISP_IOXPUT_32(isp, src->snscb_res3, &dst->snscb_res3);
-+	ISP_IOXPUT_32(isp, src->snscb_fc4_type, &dst->snscb_fc4_type);
-+}
-+
-+static INLINE void
-+isp_put_gxn_id_request(struct ispsoftc *isp, sns_gxn_id_req_t *src,
-+    sns_gxn_id_req_t *dst)
-+{
-+	ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
-+	ISP_IOXPUT_16(isp, src->snscb_res0, &dst->snscb_res0);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[0], &dst->snscb_addr[0]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[1], &dst->snscb_addr[1]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[2], &dst->snscb_addr[2]);
-+	ISP_IOXPUT_16(isp, src->snscb_addr[3], &dst->snscb_addr[3]);
-+	ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen);
-+	ISP_IOXPUT_16(isp, src->snscb_res1, &dst->snscb_res1);
-+	ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd);
-+	ISP_IOXPUT_16(isp, src->snscb_res2, &dst->snscb_res2);
-+	ISP_IOXPUT_32(isp, src->snscb_res3, &dst->snscb_res3);
-+	ISP_IOXPUT_32(isp, src->snscb_portid, &dst->snscb_portid);
-+}
-+
-+/*
-+ * Generic SNS response - not particularly useful since the per-command data
-+ * isn't always 16 bit words.
-+ */
-+static INLINE void
-+isp_get_sns_response(struct ispsoftc *isp, sns_scrsp_t *src,
-+    sns_scrsp_t *dst, int nwords)
-+{
-+	int i;
-+	isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
-+	ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type);
-+	for (i = 0; i < 3; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_port_id[i],
-+		    dst->snscb_port_id[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_portname[i],
-+		    dst->snscb_portname[i]);
-+	}
-+	for (i = 0; i < nwords; i++) {
-+		ISP_IOXGET_16(isp, &src->snscb_data[i], dst->snscb_data[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_gid_ft_response(struct ispsoftc *isp, sns_gid_ft_rsp_t *src,
-+    sns_gid_ft_rsp_t *dst, int nwords)
-+{
-+	int i;
-+	isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
-+	for (i = 0; i < nwords; i++) {
-+		int j;
-+		ISP_IOXGET_8(isp,
-+		    &src->snscb_ports[i].control,
-+		    dst->snscb_ports[i].control);
-+		for (j = 0; j < 3; j++) {
-+			ISP_IOXGET_8(isp,
-+			    &src->snscb_ports[i].portid[j],
-+			    dst->snscb_ports[i].portid[j]);
-+		}
-+		if (dst->snscb_ports[i].control & 0x80) {
-+			break;
-+		}
-+	}
-+}
-+
-+static INLINE void
-+isp_get_gxn_id_response(struct ispsoftc *isp, sns_gxn_id_rsp_t *src,
-+    sns_gxn_id_rsp_t *dst)
-+{
-+	int i;
-+	isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
-+	for (i = 0; i < 8; i++)
-+		ISP_IOXGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]);
-+}
-+
-+static INLINE void
-+isp_get_gff_id_response(struct ispsoftc *isp, sns_gff_id_rsp_t *src,
-+    sns_gff_id_rsp_t *dst)
-+{
-+	int i;
-+	isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
-+	for (i = 0; i < 32; i++) {
-+		ISP_IOXGET_32(isp, &src->snscb_fc4_features[i],
-+		    dst->snscb_fc4_features[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_ga_nxt_response(struct ispsoftc *isp, sns_ga_nxt_rsp_t *src,
-+    sns_ga_nxt_rsp_t *dst)
-+{
-+	int i;
-+	isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
-+	ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type);
-+	for (i = 0; i < 3; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_port_id[i],
-+		    dst->snscb_port_id[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_portname[i],
-+		    dst->snscb_portname[i]);
-+	}
-+	ISP_IOXGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen);
-+	for (i = 0; i < 255; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_nodename[i],
-+		    dst->snscb_nodename[i]);
-+	}
-+	ISP_IOXGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen);
-+	for (i = 0; i < 255; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_ipassoc[i],
-+		    dst->snscb_ipassoc[i]);
-+	}
-+	for (i = 0; i < 16; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]);
-+	}
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_svc_class[i],
-+		    dst->snscb_svc_class[i]);
-+	}
-+	for (i = 0; i < 32; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_fc4_types[i],
-+		    dst->snscb_fc4_types[i]);
-+	}
-+	for (i = 0; i < 8; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]);
-+	}
-+	ISP_IOXGET_8(isp, &src->snscb_reserved, dst->snscb_reserved);
-+	for (i = 0; i < 3; i++) {
-+		ISP_IOXGET_8(isp, &src->snscb_hardaddr[i],
-+		    dst->snscb_hardaddr[i]);
-+	}
-+}
-+
-+#ifdef	ISP_TARGET_MODE
-+static INLINE void
-+isp_put_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
-+	ISP_IOXPUT_16(isp, atsrc->at_reserved, &atdst->at_reserved);
-+	ISP_IOXPUT_16(isp, atsrc->at_handle, &atdst->at_handle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_iid);
-+		ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_lun);
-+		ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_tgt);
-+		ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_cdblen);
-+		ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_scsi_status);
-+		ISP_IOXPUT_8(isp, atsrc->at_scsi_status, &atdst->at_status);
-+		ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_type);
-+		ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_val);
-+	} else {
-+		ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_lun);
-+		ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_iid);
-+		ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_cdblen);
-+		ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_tgt);
-+		ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_status);
-+		ISP_IOXPUT_8(isp, atsrc->at_scsi_status,
-+		    &atdst->at_scsi_status);
-+		ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_val);
-+		ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_type);
-+	}
-+	ISP_IOXPUT_32(isp, atsrc->at_flags, &atdst->at_flags);
-+	for (i = 0; i < ATIO_CDBLEN; i++) {
-+		ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
-+	}
-+	for (i = 0; i < QLTM_SENSELEN; i++) {
-+		ISP_IOXPUT_8(isp, atsrc->at_sense[i], &atdst->at_sense[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
-+	ISP_IOXGET_16(isp, &atsrc->at_reserved, atdst->at_reserved);
-+	ISP_IOXGET_16(isp, &atsrc->at_handle, atdst->at_handle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_iid);
-+		ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_lun);
-+		ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_tgt);
-+		ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_cdblen);
-+		ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_scsi_status);
-+		ISP_IOXGET_8(isp, &atsrc->at_scsi_status, atdst->at_status);
-+		ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_type);
-+		ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_val);
-+	} else {
-+		ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
-+		ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_iid);
-+		ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_cdblen);
-+		ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_tgt);
-+		ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_status);
-+		ISP_IOXGET_8(isp, &atsrc->at_scsi_status,
-+		    atdst->at_scsi_status);
-+		ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_val);
-+		ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_type);
-+	}
-+	ISP_IOXGET_32(isp, &atsrc->at_flags, atdst->at_flags);
-+	for (i = 0; i < ATIO_CDBLEN; i++) {
-+		ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
-+	}
-+	for (i = 0; i < QLTM_SENSELEN; i++) {
-+		ISP_IOXGET_8(isp, &atsrc->at_sense[i], atdst->at_sense[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
-+	ISP_IOXPUT_32(isp, atsrc->at_reserved, &atdst->at_reserved);
-+	ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_lun);
-+	ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_iid);
-+	ISP_IOXPUT_16(isp, atsrc->at_rxid, &atdst->at_rxid);
-+	ISP_IOXPUT_16(isp, atsrc->at_flags, &atdst->at_flags);
-+	ISP_IOXPUT_16(isp, atsrc->at_status, &atdst->at_status);
-+	ISP_IOXPUT_8(isp, atsrc->at_crn, &atdst->at_crn);
-+	ISP_IOXPUT_8(isp, atsrc->at_taskcodes, &atdst->at_taskcodes);
-+	ISP_IOXPUT_8(isp, atsrc->at_taskflags, &atdst->at_taskflags);
-+	ISP_IOXPUT_8(isp, atsrc->at_execodes, &atdst->at_execodes);
-+	for (i = 0; i < ATIO2_CDBLEN; i++) {
-+		ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
-+	}
-+	ISP_IOXPUT_32(isp, atsrc->at_datalen, &atdst->at_datalen);
-+	ISP_IOXPUT_16(isp, atsrc->at_scclun, &atdst->at_scclun);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXPUT_16(isp, atsrc->at_wwpn[i], &atdst->at_wwpn[i]);
-+	}
-+	for (i = 0; i < 6; i++) {
-+		ISP_IOXPUT_16(isp, atsrc->at_reserved2[i],
-+		    &atdst->at_reserved2[i]);
-+	}
-+	ISP_IOXPUT_16(isp, atsrc->at_oxid, &atdst->at_oxid);
-+}
-+
-+static INLINE void
-+isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
-+	ISP_IOXGET_32(isp, &atsrc->at_reserved, atdst->at_reserved);
-+	ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
-+	ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_iid);
-+	ISP_IOXGET_16(isp, &atsrc->at_rxid, atdst->at_rxid);
-+	ISP_IOXGET_16(isp, &atsrc->at_flags, atdst->at_flags);
-+	ISP_IOXGET_16(isp, &atsrc->at_status, atdst->at_status);
-+	ISP_IOXGET_8(isp, &atsrc->at_crn, atdst->at_crn);
-+	ISP_IOXGET_8(isp, &atsrc->at_taskcodes, atdst->at_taskcodes);
-+	ISP_IOXGET_8(isp, &atsrc->at_taskflags, atdst->at_taskflags);
-+	ISP_IOXGET_8(isp, &atsrc->at_execodes, atdst->at_execodes);
-+	for (i = 0; i < ATIO2_CDBLEN; i++) {
-+		ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
-+	}
-+	ISP_IOXGET_32(isp, &atsrc->at_datalen, atdst->at_datalen);
-+	ISP_IOXGET_16(isp, &atsrc->at_scclun, atdst->at_scclun);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXGET_16(isp, &atsrc->at_wwpn[i], atdst->at_wwpn[i]);
-+	}
-+	for (i = 0; i < 6; i++) {
-+		ISP_IOXGET_16(isp, &atsrc->at_reserved2[i],
-+		    atdst->at_reserved2[i]);
-+	}
-+	ISP_IOXGET_16(isp, &atsrc->at_oxid, atdst->at_oxid);
-+}
-+
-+static INLINE void
-+isp_put_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_reserved, &ctdst->ct_reserved);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_fwhandle, &ctdst->ct_fwhandle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_lun);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_iid);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_reserved2);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_tgt);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_scsi_status);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status, &ctdst->ct_status);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_val);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_type);
-+	} else {
-+		ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_iid);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_tgt);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_reserved2);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status,
-+		    &ctdst->ct_scsi_status);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_status);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_type);
-+		ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_val);
-+	}
-+	ISP_IOXPUT_32(isp, ctsrc->ct_flags, &ctdst->ct_flags);
-+	ISP_IOXPUT_32(isp, ctsrc->ct_xfrlen, &ctdst->ct_xfrlen);
-+	ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
-+	for (i = 0; i < ISP_RQDSEG; i++) {
-+		ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_base,
-+		    &ctdst->ct_dataseg[i].ds_base);
-+		ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_count,
-+		    &ctdst->ct_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_reserved, ctdst->ct_reserved);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_fwhandle, ctdst->ct_fwhandle);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_iid);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_lun);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_tgt);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_reserved2);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_scsi_status);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status, ctdst->ct_status);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_type);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_val);
-+	} else {
-+		ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_iid);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_reserved2);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_tgt);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_status);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status,
-+		    ctdst->ct_scsi_status);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_val);
-+		ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_type);
-+	}
-+	ISP_IOXGET_32(isp, &ctsrc->ct_flags, ctdst->ct_flags);
-+	ISP_IOXGET_32(isp, &ctsrc->ct_xfrlen, ctdst->ct_xfrlen);
-+	ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
-+	for (i = 0; i < ISP_RQDSEG; i++) {
-+		ISP_IOXGET_32(isp,
-+		    &ctsrc->ct_dataseg[i].ds_base,
-+		    ctdst->ct_dataseg[i].ds_base);
-+		ISP_IOXGET_32(isp,
-+		    &ctsrc->ct_dataseg[i].ds_count,
-+		    ctdst->ct_dataseg[i].ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_reserved, &ctdst->ct_reserved);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_fwhandle, &ctdst->ct_fwhandle);
-+	ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
-+	ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_iid);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_rxid, &ctdst->ct_rxid);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_flags, &ctdst->ct_flags);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
-+	ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
-+	ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
-+	ISP_IOXPUT_32(isp, ctsrc->ct_reloff, &ctdst->ct_reloff);
-+	if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m0._reserved,
-+		    &ctdst->rsp.m0._reserved);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m0._reserved2,
-+		    &ctdst->rsp.m0._reserved2);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_scsi_status,
-+		    &ctdst->rsp.m0.ct_scsi_status);
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_xfrlen,
-+		    &ctdst->rsp.m0.ct_xfrlen);
-+		if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
-+			for (i = 0; i < ISP_RQDSEG_T2; i++) {
-+				ISP_IOXPUT_32(isp,
-+				    ctsrc->rsp.m0.ct_dataseg[i].ds_base,
-+				    &ctdst->rsp.m0.ct_dataseg[i].ds_base);
-+				ISP_IOXPUT_32(isp,
-+				    ctsrc->rsp.m0.ct_dataseg[i].ds_count,
-+				    &ctdst->rsp.m0.ct_dataseg[i].ds_count);
-+			}
-+		} else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
-+			for (i = 0; i < ISP_RQDSEG_T3; i++) {
-+				ISP_IOXPUT_32(isp,
-+				    ctsrc->rsp.m0.ct_dataseg64[i].ds_base,
-+				    &ctdst->rsp.m0.ct_dataseg64[i].ds_base);
-+				ISP_IOXPUT_32(isp,
-+				    ctsrc->rsp.m0.ct_dataseg64[i].ds_basehi,
-+				    &ctdst->rsp.m0.ct_dataseg64[i].ds_basehi);
-+				ISP_IOXPUT_32(isp,
-+				    ctsrc->rsp.m0.ct_dataseg64[i].ds_count,
-+				    &ctdst->rsp.m0.ct_dataseg64[i].ds_count);
-+			}
-+		} else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
-+			ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_dslist.ds_type,
-+			    &ctdst->rsp.m0.ct_dslist.ds_type);
-+			ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_segment,
-+			    &ctdst->rsp.m0.ct_dslist.ds_segment);
-+			ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_base,
-+			    &ctdst->rsp.m0.ct_dslist.ds_base);
-+		}
-+	} else if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved,
-+		    &ctdst->rsp.m1._reserved);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved2,
-+		    &ctdst->rsp.m1._reserved2);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_senselen,
-+		    &ctdst->rsp.m1.ct_senselen);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_scsi_status,
-+		    &ctdst->rsp.m1.ct_scsi_status);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_resplen,
-+		    &ctdst->rsp.m1.ct_resplen);
-+		for (i = 0; i < MAXRESPLEN; i++) {
-+			ISP_IOXPUT_8(isp, ctsrc->rsp.m1.ct_resp[i],
-+			    &ctdst->rsp.m1.ct_resp[i]);
-+		}
-+	} else {
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m2._reserved,
-+		    &ctdst->rsp.m2._reserved);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved2,
-+		    &ctdst->rsp.m2._reserved2);
-+		ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved3,
-+		    &ctdst->rsp.m2._reserved3);
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_datalen,
-+		    &ctdst->rsp.m2.ct_datalen);
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_base,
-+		    &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
-+		ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_count,
-+		    &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_reserved, ctdst->ct_reserved);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_fwhandle, ctdst->ct_fwhandle);
-+	ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
-+	ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_iid);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_rxid, ctdst->ct_rxid);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_flags, ctdst->ct_flags);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_status, ctdst->ct_status);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
-+	ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
-+	ISP_IOXGET_32(isp, &ctsrc->ct_reloff, ctdst->ct_reloff);
-+	ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
-+	for (i = 0; i < 4; i++) {
-+		ISP_IOXGET_32(isp, &ctsrc->rsp.fw._reserved[i],
-+		    ctdst->rsp.fw._reserved[i]);
-+	}
-+	ISP_IOXGET_16(isp, &ctsrc->rsp.fw.ct_scsi_status,
-+	    ctdst->rsp.fw.ct_scsi_status);
-+	for (i = 0; i < QLTM_SENSELEN; i++) {
-+		ISP_IOXGET_8(isp, &ctsrc->rsp.fw.ct_sense[i],
-+		    ctdst->rsp.fw.ct_sense[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &lesrc->le_header, &ledst->le_header);
-+	ISP_IOXPUT_32(isp, lesrc->le_reserved, &ledst->le_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_rsvd);
-+		ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_lun);
-+		ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_tgt);
-+		ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_ops);
-+		ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_reserved2);
-+		ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_status);
-+		ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_in_count);
-+		ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_cmd_count);
-+		ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb7len);
-+		ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb6len);
-+	} else {
-+		ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_lun);
-+		ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_rsvd);
-+		ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_ops);
-+		ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_tgt);
-+		ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_status);
-+		ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_reserved2);
-+		ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_cmd_count);
-+		ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_in_count);
-+		ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb6len);
-+		ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb7len);
-+	}
-+	ISP_IOXPUT_32(isp, lesrc->le_flags, &ledst->le_flags);
-+	ISP_IOXPUT_16(isp, lesrc->le_timeout, &ledst->le_timeout);
-+	for (i = 0; i < 20; i++) {
-+		ISP_IOXPUT_8(isp, lesrc->le_reserved3[i],
-+		    &ledst->le_reserved3[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &lesrc->le_header, &ledst->le_header);
-+	ISP_IOXGET_32(isp, &lesrc->le_reserved, ledst->le_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_rsvd);
-+		ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_lun);
-+		ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_tgt);
-+		ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_ops);
-+		ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_reserved2);
-+		ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_status);
-+		ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_in_count);
-+		ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_cmd_count);
-+		ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb7len);
-+		ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb6len);
-+	} else {
-+		ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_lun);
-+		ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_rsvd);
-+		ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_ops);
-+		ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_tgt);
-+		ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_status);
-+		ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_reserved2);
-+		ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_cmd_count);
-+		ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_in_count);
-+		ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb6len);
-+		ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb7len);
-+	}
-+	ISP_IOXGET_32(isp, &lesrc->le_flags, ledst->le_flags);
-+	ISP_IOXGET_16(isp, &lesrc->le_timeout, ledst->le_timeout);
-+	for (i = 0; i < 20; i++) {
-+		ISP_IOXGET_8(isp, &lesrc->le_reserved3[i],
-+		    ledst->le_reserved3[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
-+	ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_iid);
-+		ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_lun);
-+		ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_tgt);
-+		ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_reserved2);
-+		ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_rsvd2);
-+		ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_status);
-+		ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_type);
-+		ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_val);
-+	} else {
-+		ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_lun);
-+		ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_iid);
-+		ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_reserved2);
-+		ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_tgt);
-+		ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_status);
-+		ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_rsvd2);
-+		ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_val);
-+		ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_type);
-+	}
-+	ISP_IOXPUT_32(isp, insrc->in_flags, &indst->in_flags);
-+	ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
-+	for (i = 0; i < IN_MSGLEN; i++) {
-+		ISP_IOXPUT_8(isp, insrc->in_msg[i], &indst->in_msg[i]);
-+	}
-+	for (i = 0; i < IN_RSVDLEN; i++) {
-+		ISP_IOXPUT_8(isp, insrc->in_reserved3[i],
-+		    &indst->in_reserved3[i]);
-+	}
-+	for (i = 0; i < QLTM_SENSELEN; i++) {
-+		ISP_IOXPUT_8(isp, insrc->in_sense[i],
-+		    &indst->in_sense[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
-+	ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_iid);
-+		ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_lun);
-+		ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_tgt);
-+		ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_reserved2);
-+		ISP_IOXGET_8(isp, &insrc->in_status, indst->in_rsvd2);
-+		ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_status);
-+		ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_type);
-+		ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_val);
-+	} else {
-+		ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
-+		ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_iid);
-+		ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_reserved2);
-+		ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_tgt);
-+		ISP_IOXGET_8(isp, &insrc->in_status, indst->in_status);
-+		ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_rsvd2);
-+		ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_val);
-+		ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_type);
-+	}
-+	ISP_IOXGET_32(isp, &insrc->in_flags, indst->in_flags);
-+	ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
-+	for (i = 0; i < IN_MSGLEN; i++) {
-+		ISP_IOXGET_8(isp, &insrc->in_msg[i], indst->in_msg[i]);
-+	}
-+	for (i = 0; i < IN_RSVDLEN; i++) {
-+		ISP_IOXGET_8(isp, &insrc->in_reserved3[i],
-+		    indst->in_reserved3[i]);
-+	}
-+	for (i = 0; i < QLTM_SENSELEN; i++) {
-+		ISP_IOXGET_8(isp, &insrc->in_sense[i],
-+		    indst->in_sense[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
-+    in_fcentry_t *indst)
-+{
-+	isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
-+	ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
-+	ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_lun);
-+	ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_iid);
-+	ISP_IOXPUT_16(isp, insrc->in_scclun, &indst->in_scclun);
-+	ISP_IOXPUT_32(isp, insrc->in_reserved2, &indst->in_reserved2);
-+	ISP_IOXPUT_16(isp, insrc->in_status, &indst->in_status);
-+	ISP_IOXPUT_16(isp, insrc->in_task_flags, &indst->in_task_flags);
-+	ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
-+}
-+
-+static INLINE void
-+isp_get_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
-+    in_fcentry_t *indst)
-+{
-+	isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
-+	ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
-+	ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
-+	ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_iid);
-+	ISP_IOXGET_16(isp, &insrc->in_scclun, indst->in_scclun);
-+	ISP_IOXGET_32(isp, &insrc->in_reserved2, indst->in_reserved2);
-+	ISP_IOXGET_16(isp, &insrc->in_status, indst->in_status);
-+	ISP_IOXGET_16(isp, &insrc->in_task_flags, indst->in_task_flags);
-+	ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
-+}
-+
-+static INLINE void
-+isp_put_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc,  na_entry_t *nadst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
-+	ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_iid);
-+		ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_lun);
-+		ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_event);
-+		ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_status);
-+	} else {
-+		ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_lun);
-+		ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_iid);
-+		ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_status);
-+		ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_event);
-+	}
-+	ISP_IOXPUT_32(isp, nasrc->na_flags, &nadst->na_flags);
-+	for (i = 0; i < NA_RSVDLEN; i++) {
-+		ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
-+		    &nadst->na_reserved3[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc, na_entry_t *nadst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &nasrc->na_header, &nadst->na_header);
-+	ISP_IOXGET_32(isp, &nasrc->na_reserved, nadst->na_reserved);
-+	if (ISP_IS_SBUS(isp)) {
-+		ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_iid);
-+		ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_lun);
-+		ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_event);
-+		ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_status);
-+	} else {
-+		ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_lun);
-+		ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_iid);
-+		ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_status);
-+		ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_event);
-+	}
-+	ISP_IOXGET_32(isp, &nasrc->na_flags, nadst->na_flags);
-+	for (i = 0; i < NA_RSVDLEN; i++) {
-+		ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
-+		    nadst->na_reserved3[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_put_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
-+    na_fcentry_t *nadst)
-+{
-+	int i;
-+	isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
-+	ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
-+	ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_lun);
-+	ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_iid);
-+	ISP_IOXPUT_16(isp, nasrc->na_scclun, &nadst->na_scclun);
-+	ISP_IOXPUT_16(isp, nasrc->na_flags, &nadst->na_flags);
-+	ISP_IOXPUT_16(isp, nasrc->na_reserved2, &nadst->na_reserved2);
-+	ISP_IOXPUT_16(isp, nasrc->na_status, &nadst->na_status);
-+	ISP_IOXPUT_16(isp, nasrc->na_task_flags, &nadst->na_task_flags);
-+	ISP_IOXPUT_16(isp, nasrc->na_seqid, &nadst->na_seqid);
-+	for (i = 0; i < NA2_RSVDLEN; i++) {
-+		ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
-+		    &nadst->na_reserved3[i]);
-+	}
-+}
-+
-+static INLINE void
-+isp_get_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
-+    na_fcentry_t *nadst)
-+{
-+	int i;
-+	isp_copy_in_hdr(isp, &nasrc->na_header, &nadst->na_header);
-+	ISP_IOXGET_32(isp, &nasrc->na_reserved, nadst->na_reserved);
-+	ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_lun);
-+	ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_iid);
-+	ISP_IOXGET_16(isp, &nasrc->na_scclun, nadst->na_scclun);
-+	ISP_IOXGET_16(isp, &nasrc->na_flags, nadst->na_flags);
-+	ISP_IOXGET_16(isp, &nasrc->na_reserved2, nadst->na_reserved2);
-+	ISP_IOXGET_16(isp, &nasrc->na_status, nadst->na_status);
-+	ISP_IOXGET_16(isp, &nasrc->na_task_flags, nadst->na_task_flags);
-+	ISP_IOXGET_16(isp, &nasrc->na_seqid, nadst->na_seqid);
-+	for (i = 0; i < NA2_RSVDLEN; i++) {
-+		ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
-+		    nadst->na_reserved3[i]);
-+	}
-+}
-+#endif
-+#endif	/* _ISP_INLINE_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_ioctl.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,128 @@
-+/* %W% */
-+/*
-+ * ioctl definitions for Qlogic FC/SCSI HBA driver
-+ */
-+#define	ISP_IOC		(0x4D4A5100)	/* 'MJQ' << 8 */
-+
-+/*
-+ * This ioctl sets/retrieves the debugging level for this hba instance.
-+ * Note that this is not a simple integer level- see ispvar.h for definitions.
-+ *
-+ * The arguments is a pointer to an integer with the new debugging level.
-+ * The old value is written into this argument.
-+ */
-+
-+#define	ISP_SDBLEV	(ISP_IOC | 1)
-+
-+/*
-+ * This ioctl resets the HBA. Use with caution.
-+ */
-+#define	ISP_RESETHBA	(ISP_IOC | 2)
-+
-+/*
-+ * This ioctl performs a fibre chanel rescan.
-+ */
-+#define	ISP_RESCAN	(ISP_IOC | 3)
-+
-+/*
-+ * This ioctl performs a reset and then will set the adapter to the
-+ * role that was passed in (the old role will be returned). It almost
-+ * goes w/o saying: use with caution.
-+ */
-+#define ISP_SETROLE     (ISP_IOC | 4)
-+
-+#define ISP_ROLE_NONE           0x0
-+#define ISP_ROLE_INITIATOR      0x1
-+#define ISP_ROLE_TARGET         0x2
-+#define ISP_ROLE_BOTH           (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
-+#ifndef ISP_DEFAULT_ROLES
-+#define ISP_DEFAULT_ROLES       ISP_ROLE_BOTH
-+#endif
-+
-+/*
-+ * Get the current adapter role
-+ */
-+#define ISP_GETROLE     (ISP_IOC | 5)
-+
-+/*
-+ * Get/Clear Stats
-+ */
-+#define	ISP_STATS_VERSION	0
-+typedef struct {
-+	u_int8_t	isp_stat_version;
-+	u_int8_t	isp_type;		/* (ro) reflects chip type */
-+	u_int8_t	isp_revision;		/* (ro) reflects chip version */
-+	u_int8_t	unused1;
-+	u_int32_t	unused2;
-+	/*
-+	 * Statistics Counters
-+	 */
-+#define	ISP_NSTATS	16
-+#define	ISP_INTCNT	0
-+#define	ISP_INTBOGUS	1
-+#define	ISP_INTMBOXC	2
-+#define	ISP_INGOASYNC	3
-+#define	ISP_RSLTCCMPLT	4
-+#define	ISP_FPHCCMCPLT	5
-+#define	ISP_RSCCHIWAT	6
-+#define	ISP_FPCCHIWAT	7
-+	u_int64_t	isp_stats[ISP_NSTATS];
-+} isp_stats_t;
-+
-+#define	ISP_GET_STATS	(ISP_IOC | 6)
-+#define	ISP_CLR_STATS	(ISP_IOC | 7)
-+
-+/*
-+ * Initiate a LIP
-+ */
-+#define	ISP_FC_LIP	(ISP_IOC | 8)
-+
-+/*
-+ * Return the Port Database structure for the named device, or ENODEV if none.
-+ * Caller fills in virtual loopid (0..255), aka 'target'. The driver returns
-+ * ENODEV (if nothing valid there) or the actual loopid (for local loop devices
-+ * only), 24 bit Port ID and Node and Port WWNs.
-+ */
-+struct isp_fc_device {
-+	u_int32_t	loopid;	/* 0..255 */
-+	u_int32_t	portid;	/* 24 bit Port ID */
-+	u_int64_t	node_wwn;
-+	u_int64_t	port_wwn;
-+};
-+#define	ISP_FC_GETDINFO	(ISP_IOC | 9)
-+
-+/*
-+ * Get F/W crash dump
-+ */
-+#define	ISP_GET_FW_CRASH_DUMP	(ISP_IOC | 10)
-+#define	ISP_FORCE_CRASH_DUMP	(ISP_IOC | 11)
-+
-+/*
-+ * Get information about this Host Adapter, including current connection
-+ * topology and capabilities.
-+ */
-+struct isp_hba_device {
-+	u_int32_t
-+					: 8,
-+					: 4,
-+		fc_speed		: 4,	/* Gbps */
-+					: 2,
-+		fc_class2		: 1,
-+		fc_ip_supported		: 1,
-+		fc_scsi_supported	: 1,
-+		fc_topology		: 3,
-+		fc_loopid		: 8;
-+	u_int64_t	nvram_node_wwn;
-+	u_int64_t	nvram_port_wwn;
-+	u_int64_t	active_node_wwn;
-+	u_int64_t	active_port_wwn;
-+};
-+
-+#define	ISP_TOPO_UNKNOWN	0	/* connection topology unknown */
-+#define	ISP_TOPO_FCAL		1	/* private or PL_DA */
-+#define	ISP_TOPO_LPORT		2	/* public loop */
-+#define	ISP_TOPO_NPORT		3	/* N-port */
-+#define	ISP_TOPO_FPORT		4	/* F-port */
-+
-+#define	ISP_FC_GETHINFO		(ISP_IOC|12)
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_linux.c	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,3015 @@
-+/* @(#)isp_linux.c 1.66 */
-+/*
-+ * Qlogic ISP Host Adapter Common Bus Linux routies
-+ *---------------------------------------
-+ *
-+ * Copyright (c) 1998, 1999, 2000, 2001 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification, immediately at the beginning of the file.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * Alternatively, this software may be distributed under the terms of the
-+ * the GNU Public License ("GPL").
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * 
-+ * Matthew Jacob
-+ * Feral Software
-+ * PMB #825
-+ * 5214-F Diamond Hts Blvd
-+ * San Francisco, CA, 94131
-+ * mjacob@feral.com
-+ *
-+ *--------
-+ * Bug fixes from Janice McLaughlin (janus@somemore.com)
-+ * gratefully acknowledged.
-+ *
-+ */
-+
-+#define	ISP_MODULE	1
-+#include "isp_linux.h"
-+#include "linux/smp_lock.h"
-+
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+#define	scsi_add_timer		_scsi_add_timer
-+#define	scsi_delete_timer	_scsi_delete_timer
-+static INLINE void _scsi_add_timer(Scsi_Cmnd *, int, void ((*)(Scsi_Cmnd *)));
-+static INLINE int _scsi_delete_timer(Scsi_Cmnd *);
-+
-+static INLINE void
-+scsi_add_timer(Scsi_Cmnd *SCset, int timeout, void (*complete)(Scsi_Cmnd *))
-+{
-+    if (SCset->eh_timeout.function != NULL) {
-+	del_timer(&SCset->eh_timeout);
-+    }
-+    SCset->eh_timeout.data = (unsigned long) SCset;
-+    SCset->eh_timeout.expires = jiffies + timeout;
-+    SCset->eh_timeout.function = (void (*)(unsigned long))complete;
-+    add_timer(&SCset->eh_timeout);
-+}
-+static INLINE int
-+scsi_delete_timer(Scsi_Cmnd *SCset)
-+{
-+    if (SCset->eh_timeout.function != NULL) {
-+	del_timer(&SCset->eh_timeout);
-+    }
-+    SCset->eh_timeout.data = 0UL;
-+    SCset->eh_timeout.function = NULL;
-+    return 0;
-+}
-+#else
-+extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*)(Scsi_Cmnd *)));
-+extern int scsi_delete_timer(Scsi_Cmnd *);
-+#endif
-+static int isp_task_thread(void *);
-+
-+struct ispsoftc *isplist = NULL;
-+const char *class3_roles[4] = {
-+    "None", "Target", "Initiator", "Target/Initiator"
-+};
-+int isp_debug = 0;
-+int isp_throttle = 0;
-+int isp_cmd_per_lun = 0;
-+int isp_unit_seed = 0;
-+int isp_disable = 0;
-+int isp_nofwreload = 0;
-+int isp_nonvram = 0;
-+int isp_maxluns = 8;
-+int isp_fcduplex = 0;
-+int isp_nport_only = 0;
-+int isp_loop_only = 0;
-+int isp_deadloop_time = 30;	/* how long to wait before assume loop dead */
-+int isp_xtime = 0;
-+int isp_default_frame_size;
-+int isp_default_exec_throttle;
-+
-+static char *isp_roles;
-+static char *isp_wwpns;
-+static char *isp_wwnns;
-+
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+#ifndef	ISP_PARENT_TARGET
-+#define	ISP_PARENT_TARGET	scsi_target_handler
-+#endif
-+extern void ISP_PARENT_TARGET (qact_e, void *);
-+static void isp_taction(qact_e, void *);
-+static INLINE int nolunsenabled(struct ispsoftc *, int);
-+static void isp_target_start_ctio(struct ispsoftc *, tmd_cmd_t *);
-+static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *);
-+static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *);
-+static int isp_handle_platform_ctio(struct ispsoftc *, void *);
-+static int isp_handle_platform_ctio_fastpost(struct ispsoftc *, u_int32_t);
-+static void isp_target_putback_atio(struct ispsoftc *, tmd_cmd_t *);
-+static void isp_complete_ctio(struct ispsoftc *, tmd_cmd_t *);
-+#endif
-+
-+extern int isplinux_pci_detect(Scsi_Host_Template *);
-+extern void isplinux_pci_release(struct Scsi_Host *);
-+
-+int
-+isplinux_detect(Scsi_Host_Template *tmpt)
-+{
-+    int rval;
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+    extern struct proc_dir_entry proc_scsi_qlc;
-+    tmpt->proc_dir = &proc_scsi_qlc;
-+#else
-+    tmpt->proc_name = "isp";
-+#endif
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+    spin_unlock_irq(&io_request_lock);
-+    rval = isplinux_pci_detect(tmpt);
-+    spin_lock_irq(&io_request_lock);
-+#else
-+    rval = isplinux_pci_detect(tmpt);
-+#endif
-+    return (rval);
-+}
-+
-+/* io_request_lock *not* held here */
-+int
-+isplinux_release(struct Scsi_Host *host)
-+{
-+    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;
-+#ifdef	ISP_TARGET_MODE
-+    isp_detach_target(isp);
-+#endif
-+    if (isp->isp_osinfo.task_thread) {
-+        SEND_THREAD_EVENT(isp, ISP_THREAD_EXIT, 1);
-+    }
-+    ISP_LOCKU_SOFTC(isp);
-+    isp->isp_role = ISP_ROLE_NONE;
-+    ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+    if (IS_FC(isp)) {
-+	ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
-+	ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
-+	ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
-+	ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
-+	ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
-+    }
-+    isp->dogactive = 0;
-+    del_timer(&isp->isp_osinfo.timer);
-+    DISABLE_INTS(isp);
-+    if (isp->isp_bustype == ISP_BT_PCI) {
-+	isplinux_pci_release(host);
-+    }
-+    ISP_UNLKU_SOFTC(isp);
-+#ifdef	ISP_FW_CRASH_DUMP
-+    if (FCPARAM(isp)->isp_dump_data) {
-+	size_t amt;
-+	if (IS_2200(isp))
-+	    amt = QLA2200_RISC_IMAGE_DUMP_SIZE;
-+	else
-+	    amt = QLA2200_RISC_IMAGE_DUMP_SIZE;
-+	isp_prt(isp, ISP_LOGCONFIG, "freeing crash dump area");
-+	isp_kfree(FCPARAM(isp)->isp_dump_data, amt);
-+	FCPARAM(isp)->isp_dump_data = 0;
-+    }
-+#if defined(CONFIG_PROC_FS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    /*
-+     * Undo any PROCFS stuff
-+     */
-+    isplinux_undo_proc(isp);
-+#endif
-+    return (1);
-+#endif
-+}
-+
-+const char *
-+isplinux_info(struct Scsi_Host *host)
-+{
-+    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;
-+    if (IS_FC(isp)) {
-+	static char *foo = "Driver for a Qlogic ISP 2X00 Host Adapter";
-+	foo[26] = '0';
-+	foo[27] = '0';
-+	if (isp->isp_type == ISP_HA_FC_2100)
-+	    foo[25] = '1';
-+	else if (isp->isp_type == ISP_HA_FC_2200)
-+	    foo[25] = '2';
-+	else if (isp->isp_type == ISP_HA_FC_2300)
-+	    foo[25] = '3';
-+	else if (isp->isp_type == ISP_HA_FC_2312) {
-+	    foo[25] = '3';
-+	    foo[26] = '1';
-+	    foo[27] = '2';
-+	}
-+	return (foo);
-+    } else if (IS_1240(isp)) {
-+	return ("Driver for a Qlogic ISP 1240 Host Adapter");
-+    } else if (IS_1080(isp)) {
-+	return ("Driver for a Qlogic ISP 1080 Host Adapter");
-+    } else if (IS_1280(isp)) {
-+	return ("Driver for a Qlogic ISP 1280 Host Adapter");
-+    } else if (IS_10160(isp)) {
-+	return ("Driver for a Qlogic ISP 10160 Host Adapter");
-+    } else if (IS_12160(isp)) {
-+	return ("Driver for a Qlogic ISP 12160 Host Adapter");
-+    } else {
-+	return ("Driver for a Qlogic ISP 1020/1040 Host Adapter");
-+    }
-+}
-+
-+static INLINE void
-+isplinux_append_to_waitq(struct ispsoftc *isp, Scsi_Cmnd *Cmnd)
-+{
-+    /*
-+     * If we're a fibre channel card and we consider the loop to be
-+     * down, we just finish the command here and now.
-+     */
-+    if (IS_FC(isp) && isp->isp_deadloop) {
-+	XS_INITERR(Cmnd);
-+	XS_SETERR(Cmnd, DID_NO_CONNECT);
-+
-+	/*
-+	 * Add back a timer else scsi_done drops this on the floor.
-+	 */
-+	scsi_add_timer(Cmnd, Cmnd->timeout_per_command, Cmnd->done);
-+	isp_prt(isp, ISP_LOGDEBUG0, "giving up on target %d", XS_TGT(Cmnd));
-+	ISP_UNLK_SOFTC(isp);
-+	ISP_LOCK_SCSI_DONE(isp);
-+	(*Cmnd->scsi_done)(Cmnd);
-+	ISP_UNLK_SCSI_DONE(isp);
-+	ISP_LOCK_SOFTC(isp);
-+	return;
-+    }
-+
-+    isp->isp_osinfo.wqcnt++;
-+    if (isp->isp_osinfo.wqhiwater < isp->isp_osinfo.wqcnt)
-+	isp->isp_osinfo.wqhiwater = isp->isp_osinfo.wqcnt;
-+    if (isp->isp_osinfo.wqnext == NULL) {
-+	isp->isp_osinfo.wqtail = isp->isp_osinfo.wqnext = Cmnd;
-+    } else {
-+	isp->isp_osinfo.wqtail->host_scribble = (unsigned char *) Cmnd;
-+	isp->isp_osinfo.wqtail = Cmnd;
-+    }
-+    Cmnd->host_scribble = NULL;
-+
-+
-+    /*
-+     * Stop the clock for this command.
-+     */
-+    (void) scsi_delete_timer(Cmnd);
-+}
-+
-+static INLINE void
-+isplinux_insert_head_waitq(struct ispsoftc *isp, Scsi_Cmnd *Cmnd)
-+{
-+    isp->isp_osinfo.wqcnt++;
-+    if (isp->isp_osinfo.wqnext == NULL) {
-+	isp->isp_osinfo.wqtail = isp->isp_osinfo.wqnext = Cmnd;
-+	Cmnd->host_scribble = NULL;
-+    } else {
-+	Cmnd->host_scribble = (unsigned char *) isp->isp_osinfo.wqnext;
-+	isp->isp_osinfo.wqnext = Cmnd;
-+    }
-+}
-+
-+static INLINE Scsi_Cmnd *
-+isp_remove_from_waitq(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp;
-+    Scsi_Cmnd *f;
-+    if (Cmnd == NULL)
-+	return (Cmnd);
-+    isp = XS_ISP(Cmnd);
-+    if ((f = isp->isp_osinfo.wqnext) == Cmnd) {
-+	isp->isp_osinfo.wqnext = (Scsi_Cmnd *) Cmnd->host_scribble;
-+    } else {
-+	Scsi_Cmnd *b = f;
-+	while (f) {
-+	    f = (Scsi_Cmnd *) b->host_scribble;
-+	    if (f == Cmnd) {
-+		b->host_scribble = f->host_scribble;
-+		if (isp->isp_osinfo.wqtail == Cmnd)
-+		     isp->isp_osinfo.wqtail = b;
-+		break;
-+	    }
-+	    b = f;
-+	}
-+    }
-+    if (f) {
-+	f->host_scribble = NULL;
-+	isp->isp_osinfo.wqcnt -= 1;
-+    }
-+    return (f);
-+}
-+
-+static INLINE void
-+isplinux_runwaitq(struct ispsoftc *isp)
-+{
-+    Scsi_Cmnd *f;
-+    if (isp->isp_blocked || isp->isp_draining)
-+	return;
-+    while ((f = isp_remove_from_waitq(isp->isp_osinfo.wqnext)) != NULL) {
-+	int result = isp_start(f);
-+	/*
-+	 * Restart the timer for this command if it is queued or completing.
-+	 */
-+	if (result == CMD_QUEUED || result == CMD_COMPLETE) {
-+	    int ntime = f->timeout_per_command * (isp_xtime? isp_xtime : 1);
-+	    scsi_add_timer(f, ntime, f->done);
-+	}
-+	if (result == CMD_QUEUED) {
-+	    if (isp->isp_osinfo.hiwater < isp->isp_nactive)
-+		isp->isp_osinfo.hiwater = isp->isp_nactive;
-+	    continue;
-+	}
-+
-+	/*
-+	 * If we cannot start a command on a fibre channel card, it means
-+	 * that loop state isn't ready for us to do so. Activate the FC
-+	 * thread to rediscover loop and fabric residency- but not if
-+	 * we consider the loop to be dead. If the loop is considered dead,
-+	 * we wait until a PDB Changed after a Loop UP activates the FC
-+	 * thread.
-+	 */
-+	if (result == CMD_RQLATER && IS_FC(isp) && isp->isp_deadloop == 0) {
-+	    SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);
-+	}
-+
-+	/*
-+	 * Put the command back on the wait queue. Don't change any
-+	 * timer parameters for it because they were established
-+	 * when we originally put the command on the waitq in the first
-+	 * place.
-+	 */
-+	if (result == CMD_EAGAIN || result == CMD_RQLATER) {
-+	    isplinux_insert_head_waitq(isp, f);
-+	    break;
-+	}
-+	if (result == CMD_COMPLETE) {
-+	    isp_done(f);
-+	} else {
-+	    panic("isplinux_runwaitq: result %d", result);
-+	}
-+    }
-+}
-+
-+static INLINE void
-+isplinux_flushwaitq(struct ispsoftc *isp)
-+{
-+    Scsi_Cmnd *Cmnd, *Ncmnd;
-+   
-+    if ((Cmnd = isp->isp_osinfo.wqnext) == NULL) {
-+	return;
-+    }
-+    isp->isp_osinfo.wqnext = isp->isp_osinfo.wqtail = NULL;
-+    isp->isp_osinfo.wqcnt = 0;
-+    ISP_UNLK_SOFTC(isp);
-+    do {
-+        Ncmnd = (Scsi_Cmnd *) Cmnd->host_scribble;
-+        Cmnd->host_scribble = NULL;
-+	XS_INITERR(Cmnd);
-+	XS_SETERR(Cmnd, DID_NO_CONNECT);
-+	/*
-+	 * Add back a timer else scsi_done drops this on the floor.
-+	 */
-+	scsi_add_timer(Cmnd, Cmnd->timeout_per_command, Cmnd->done);
-+	ISP_LOCK_SCSI_DONE(isp);
-+	(*Cmnd->scsi_done)(Cmnd);
-+	ISP_UNLK_SCSI_DONE(isp);
-+    } while ((Cmnd = Ncmnd) != NULL);
-+    ISP_LOCK_SOFTC(isp);
-+}
-+
-+static INLINE Scsi_Cmnd *
-+isplinux_remove_from_doneq(Scsi_Cmnd *Cmnd)
-+{
-+    Scsi_Cmnd *f;
-+    struct ispsoftc *isp;
-+
-+    if (Cmnd == NULL)
-+	return (NULL);
-+    isp = XS_ISP(Cmnd);
-+    if (isp->isp_osinfo.dqnext == NULL)
-+	return (NULL);
-+    if ((f = isp->isp_osinfo.dqnext) == Cmnd) {
-+	isp->isp_osinfo.dqnext = (Scsi_Cmnd *) Cmnd->host_scribble;
-+    } else {
-+	Scsi_Cmnd *b = f;
-+	while (f) {
-+	    f = (Scsi_Cmnd *) b->host_scribble;
-+	    if (f == Cmnd) {
-+		b->host_scribble = f->host_scribble;
-+		if (isp->isp_osinfo.dqtail == Cmnd)
-+		     isp->isp_osinfo.dqtail = b;
-+		break;
-+	    }
-+	    b = f;
-+	}
-+    }
-+    if (f) {
-+	f->host_scribble = NULL;
-+    }
-+    return (f);
-+}
-+
-+int
-+isplinux_queuecommand(Scsi_Cmnd *Cmnd, void (*donecmd)(Scsi_Cmnd *))
-+{
-+    struct Scsi_Host *host = XS_HOST(Cmnd);
-+    struct ispsoftc *isp = (struct ispsoftc *) (host->hostdata);
-+    int result;
-+
-+
-+    Cmnd->scsi_done = donecmd;
-+    Cmnd->sense_buffer[0] = 0;
-+    if (isp_xtime) {
-+	Cmnd->timeout *= isp_xtime;
-+    }
-+
-+    ISP_DRIVER_ENTRY_LOCK(isp);
-+    ISP_LOCK_SOFTC(isp);
-+
-+    /*
-+     * First off, see whether we need to (re)init the HBA.
-+     * If we need to and fail to, pretend that this was a selection timeout.
-+     */
-+    if (isp->isp_state != ISP_RUNSTATE) {
-+	if (isp->isp_role != ISP_ROLE_NONE) {
-+	    isplinux_reinit(isp);
-+	}
-+	if (isp->isp_state != ISP_RUNSTATE) {
-+	    ISP_UNLK_SOFTC(isp);
-+	    ISP_DRIVER_EXIT_LOCK(isp);
-+	    XS_INITERR(Cmnd);
-+	    XS_SETERR(Cmnd, DID_NO_CONNECT);
-+	    (*Cmnd->scsi_done)(Cmnd);
-+	    return (0);
-+	}
-+    }
-+
-+
-+   /*
-+    * See if we're currently blocked. If we are, just queue up the command
-+    * to be run later.
-+    */
-+   if (isp->isp_blocked || isp->isp_draining) {
-+	isplinux_append_to_waitq(isp, Cmnd);
-+	ISP_UNLK_SOFTC(isp);
-+	ISP_DRIVER_EXIT_LOCK(isp);
-+	return (0);
-+   }
-+
-+   /*
-+    * Next see if we have any stored up commands to run. If so, run them.
-+    * If we get back from this with commands still ready to run, put the
-+    * current command at the tail of waiting commands to be run later.
-+    */
-+
-+    isplinux_runwaitq(isp);
-+    if (isp->isp_osinfo.wqnext) {
-+	isplinux_append_to_waitq(isp, Cmnd);
-+	ISP_UNLK_SOFTC(isp);
-+	ISP_DRIVER_EXIT_LOCK(isp);
-+	return (0);
-+    }
-+
-+   /*
-+    * Finally, try and run this command.
-+    */
-+
-+    result = isp_start(Cmnd);
-+    if (result == CMD_QUEUED) {
-+	if (isp->isp_osinfo.hiwater < isp->isp_nactive)
-+	    isp->isp_osinfo.hiwater = isp->isp_nactive;
-+	result = 0;
-+	if (isp_xtime) {
-+		int ntime = isp_xtime * Cmnd->timeout_per_command;
-+		scsi_delete_timer(Cmnd);
-+		scsi_add_timer(Cmnd, ntime, Cmnd->done);
-+	}
-+    } else if (result == CMD_EAGAIN) {
-+	/*
-+	 * We ran out of request queue space (or could not
-+	 * get DMA resources). Tell the upper layer to try
-+	 * later.
-+	 */
-+	result = 1;
-+    } else if (result == CMD_RQLATER) {
-+	/*
-+	 * Temporarily hold off on this one.
-+	 * Typically this means for fibre channel
-+	 * that the loop is down or we're processing
-+	 * some other change (e.g., fabric membership
-+	 * change)
-+	 */
-+	isplinux_append_to_waitq(isp, Cmnd);
-+	if (IS_FC(isp) && isp->isp_deadloop == 0) {
-+	    SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);
-+	}
-+	result = 0;
-+    } else if (result == CMD_COMPLETE) {
-+	result = -1;
-+    } else {
-+	panic("unknown return code %d from isp_start", result);
-+    }
-+    ISP_UNLK_SOFTC(isp);
-+    ISP_DRIVER_EXIT_LOCK(isp);
-+    if (result == -1) {
-+	Cmnd->result &= ~0xff;
-+	Cmnd->result |= Cmnd->SCp.Status;
-+        Cmnd->host_scribble = NULL;
-+	(*Cmnd->scsi_done)(Cmnd);
-+	result = 0;
-+    }
-+    return (result);
-+}
-+
-+static INLINE void isplinux_scsi_probe_done(Scsi_Cmnd *);
-+
-+static INLINE void
-+isplinux_scsi_probe_done(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp = XS_ISP(Cmnd);
-+
-+    /*
-+     * If we haven't seen this target yet, check the command result. If
-+     * it was an inquiry and it succeeded okay, then we can update our
-+     * notions about this target's capabilities.
-+     *
-+     * If the command did *not* succeed, we also update our notions about
-+     * this target's capabilities (pessimistically) - it's probably not there.
-+     * All of this so we can know when we're done so we stop wasting cycles
-+     * seeing whether we can enable sync mode or not.
-+     */
-+
-+    if (isp->isp_psco[XS_CHANNEL(Cmnd)][XS_TGT(Cmnd)] == 0) {
-+	int i, b;
-+	caddr_t iqd;
-+	sdparam *sdp = (sdparam *) isp->isp_param;
-+
-+	sdp += XS_CHANNEL(Cmnd);
-+	if (Cmnd->cmnd[0] == 0x12 && host_byte(Cmnd->result) == DID_OK) {
-+	    if (Cmnd->use_sg == 0) {
-+		iqd = (caddr_t) Cmnd->buffer;
-+	    } else {
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+		iqd = ((struct scatterlist *) Cmnd->request_buffer)->address;
-+#else
-+		struct scatterlist *sg;
-+		sg = (struct scatterlist *) Cmnd->request_buffer;
-+		iqd = page_address(sg->page) + sg->offset;
-+#endif
-+	    }
-+	    sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags &=
-+		~(DPARM_TQING|DPARM_SYNC|DPARM_WIDE);
-+	    if (iqd[7] & 0x2) {
-+		sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags |= DPARM_TQING;
-+	    }
-+	    if (iqd[7] & 0x10) {
-+		sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags |= DPARM_SYNC;
-+	    }
-+	    if (iqd[7] & 0x20) {
-+		sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags |= DPARM_WIDE;
-+	    }
-+	    sdp->isp_devparam[XS_TGT(Cmnd)].dev_update = 1;
-+	    isp->isp_psco[XS_CHANNEL(Cmnd)][XS_TGT(Cmnd)] = 1;
-+	} else if (host_byte(Cmnd->result) != DID_OK) {
-+	    isp->isp_psco[XS_CHANNEL(Cmnd)][XS_TGT(Cmnd)] = 1;
-+	}
-+
-+	isp->isp_dutydone = 1;
-+	for (b = 0; b < (IS_DUALBUS(isp)?2 : 1) && isp->isp_dutydone; b++) {
-+	    for (i = 0; i < MAX_TARGETS; i++) {
-+		if (i != sdp->isp_initiator_id) {
-+		    if (isp->isp_psco[b][i] == 0) {
-+			isp->isp_dutydone = 0;
-+			break;
-+		    }
-+		}
-+	    }
-+	}
-+
-+	/*
-+	 * Have we scanned all busses and all targets? You only get
-+	 * one chance (per reset) to see what devices on this bus have
-+	 * to offer.
-+	 */
-+	if (isp->isp_dutydone) {
-+	    for (b = 0; b < (IS_DUALBUS(isp)?2 : 1) && isp->isp_dutydone; b++) {
-+		for (i = 0; i < MAX_TARGETS; i++) {
-+		    isp->isp_psco[b][i] = 0;
-+		}
-+		isp->isp_update |= (1 << b);
-+	    }
-+	}	    
-+    }
-+}
-+
-+void
-+isp_done(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp = XS_ISP(Cmnd);
-+
-+    if (IS_SCSI(isp) && isp->isp_dutydone == 0)  {
-+	isplinux_scsi_probe_done(Cmnd);
-+    }
-+
-+    Cmnd->result &= ~0xff;
-+    Cmnd->result |= Cmnd->SCp.Status;
-+
-+    if (Cmnd->SCp.Status != GOOD) {
-+	isp_prt(isp, ISP_LOGDEBUG0, "%d.%d.%d: cmd finishes with status 0x%x",
-+	    XS_CHANNEL(Cmnd), XS_TGT(Cmnd), XS_LUN(Cmnd), Cmnd->SCp.Status);
-+    }
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,99)
-+    Cmnd->resid = XS_RESID(Cmnd);
-+#endif
-+    /*
-+     * Queue command on completion queue.
-+     */
-+    if (isp->isp_osinfo.dqnext == NULL) {
-+	isp->isp_osinfo.dqnext = Cmnd;
-+    } else {
-+	isp->isp_osinfo.dqtail->host_scribble = (unsigned char *) Cmnd;
-+    }
-+    isp->isp_osinfo.dqtail = Cmnd;
-+    Cmnd->host_scribble = NULL;
-+}
-+
-+/*
-+ * Error handling routines
-+ */
-+
-+int
-+isplinux_abort(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp;
-+    u_int16_t handle;
-+
-+    if (Cmnd == NULL || XS_HOST(Cmnd) == NULL) {
-+	return (FAILED);
-+    }
-+
-+    isp = XS_ISP(Cmnd);
-+    if (Cmnd->serial_number != Cmnd->serial_number_at_timeout) {
-+	isp_prt(isp, ISP_LOGWARN, "isplinux_abort: serial number mismatch");
-+	return (FAILED);
-+    }
-+    ISP_DRIVER_ENTRY_LOCK(isp);
-+    ISP_LOCKU_SOFTC(isp);
-+    handle = isp_find_handle(isp, Cmnd);
-+    if (handle == 0) {
-+	int wqfnd = 0;
-+	Scsi_Cmnd *NewCmnd = isp_remove_from_waitq(Cmnd);
-+	if (NewCmnd == NULL) {
-+		NewCmnd = isplinux_remove_from_doneq(Cmnd);
-+		wqfnd++;
-+	}
-+	ISP_UNLKU_SOFTC(isp);
-+	isp_prt(isp, ISP_LOGINFO,
-+	    "isplinux_abort: found %d:%p for non-running cmd for %d.%d.%d",
-+	    wqfnd, NewCmnd, XS_CHANNEL(Cmnd), XS_TGT(Cmnd), XS_LUN(Cmnd));
-+	if (NewCmnd == NULL) {
-+	    ISP_DRIVER_EXIT_LOCK(isp);
-+	    return (FAILED);
-+	}
-+    } else {
-+	if (isp_control(isp, ISPCTL_ABORT_CMD, Cmnd)) {
-+	    ISP_UNLKU_SOFTC(isp);
-+	    ISP_DRIVER_EXIT_LOCK(isp);
-+	    return (FAILED);
-+	}
-+	if (isp->isp_nactive > 0)
-+	    isp->isp_nactive--;
-+	isp_destroy_handle(isp, handle);
-+	ISP_UNLKU_SOFTC(isp);
-+	ISP_DRIVER_EXIT_LOCK(isp);
-+	isp_prt(isp, ISP_LOGINFO,
-+	    "isplinux_abort: aborted running cmd (handle 0x%x) for %d.%d.%d",
-+	    handle, XS_CHANNEL(Cmnd), XS_TGT(Cmnd), XS_LUN(Cmnd));
-+    }
-+    Cmnd->result = DID_ABORT << 16;
-+    (*Cmnd->scsi_done)(Cmnd);
-+    return (SUCCESS);
-+}
-+
-+/*
-+ * XXX: What does the midlayer expect for commands in process?
-+ * XXX: Are we supposed to clean up dead commands ourselves?
-+ */
-+int
-+isplinux_bdr(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp;
-+    int arg;
-+
-+    if (Cmnd == NULL || XS_HOST(Cmnd) == NULL) {
-+	return (FAILED);
-+    }
-+
-+    isp = XS_ISP(Cmnd);
-+    arg = XS_CHANNEL(Cmnd) << 16 | XS_TGT(Cmnd);
-+    ISP_DRIVER_ENTRY_LOCK(isp);
-+    ISP_LOCKU_SOFTC(isp);
-+    arg = isp_control(isp, ISPCTL_RESET_DEV, &arg);
-+    ISP_UNLKU_SOFTC(isp);
-+    ISP_DRIVER_EXIT_LOCK(isp);
-+    isp_prt(isp, ISP_LOGINFO, "Bus Device Reset %succesfully sent to %d.%d.%d",
-+	arg == 0? "s" : "uns", XS_CHANNEL(Cmnd), XS_TGT(Cmnd), XS_LUN(Cmnd));
-+    return ((arg == 0)? SUCCESS : FAILED);
-+}
-+
-+/*
-+ * XXX: What does the midlayer expect for commands in process?
-+ */
-+int
-+isplinux_sreset(Scsi_Cmnd *Cmnd)
-+{
-+    struct ispsoftc *isp;
-+    int arg;
-+
-+    if (Cmnd == NULL || XS_HOST(Cmnd) == NULL)
-+	return (FAILED);
-+
-+    isp = XS_ISP(Cmnd);
-+    arg = XS_CHANNEL(Cmnd);
-+    ISP_DRIVER_ENTRY_LOCK(isp);
-+    ISP_LOCKU_SOFTC(isp);
-+    arg = isp_control(isp, ISPCTL_RESET_BUS, &arg);
-+    ISP_UNLKU_SOFTC(isp);
-+    ISP_DRIVER_EXIT_LOCK(isp);
-+    isp_prt(isp, ISP_LOGINFO, "SCSI Bus Reset on Channel %d %succesful",
-+	XS_CHANNEL(Cmnd), arg == 0? "s" : "uns");
-+    return ((arg == 0)? SUCCESS : FAILED);
-+}
-+
-+/*
-+ * We call completion on any commands owned here-
-+ * except the one we were called with.
-+ */
-+int
-+isplinux_hreset(Scsi_Cmnd *Cmnd)
-+{
-+    Scsi_Cmnd *tmp, *dq, *wq, *xqf, *xql;
-+    struct ispsoftc *isp;
-+    u_int16_t handle;
-+
-+    if (Cmnd == NULL || XS_HOST(Cmnd) == NULL)
-+	return (FAILED);
-+
-+    isp = XS_ISP(Cmnd);
-+
-+    isp_prt(isp, ISP_LOGINFO, "Resetting Host Adapter");
-+
-+    ISP_DRIVER_ENTRY_LOCK(isp);
-+    ISP_LOCKU_SOFTC(isp);
-+
-+    /*
-+     * Save pending, running, and completed commands.
-+     */
-+    xql = xqf = NULL;
-+    for (handle = 1; handle <= isp->isp_maxcmds; handle++) {
-+	tmp = isp_find_xs(isp, handle);
-+	if (tmp == NULL) {
-+	    continue;
-+        }
-+	isp_destroy_handle(isp, handle);
-+	tmp->host_scribble = NULL;
-+	if (xqf) {
-+	    xql->host_scribble = (unsigned char *) tmp;
-+	} else {
-+	    xqf = xql = tmp;
-+	}
-+        xql = tmp;
-+    }
-+    dq = isp->isp_osinfo.dqnext;
-+    isp->isp_osinfo.dqnext = NULL;
-+    wq = isp->isp_osinfo.wqnext;
-+    isp->isp_osinfo.wqnext = NULL;
-+    isp->isp_nactive = 0;
-+
-+    isplinux_reinit(isp);
-+
-+    ISP_UNLKU_SOFTC(isp);
-+    ISP_DRIVER_EXIT_LOCK(isp);
-+
-+    /*
-+     * Call completion on the detritus, skipping the one we were called with.
-+     */
-+    while ((tmp = xqf) != NULL) {
-+	xqf = (Scsi_Cmnd *) tmp->host_scribble;
-+	tmp->host_scribble = NULL;
-+	if (tmp == Cmnd)
-+	    continue;
-+	tmp->result = DID_RESET << 16;
-+	/*
-+	 * Get around silliness in midlayer.
-+	 */
-+	tmp->flags |= IS_RESETTING;
-+	if (tmp->scsi_done)
-+	    (*tmp->scsi_done)(tmp);
-+    }
-+    while ((tmp = wq) != NULL) {
-+	wq = (Scsi_Cmnd *) tmp->host_scribble;
-+	tmp->host_scribble = NULL;
-+	if (tmp == Cmnd)
-+	    continue;
-+	tmp->result = DID_RESET << 16;
-+	/*
-+	 * Get around silliness in midlayer.
-+	 */
-+	tmp->flags |= IS_RESETTING;
-+	if (tmp->scsi_done)
-+	    (*tmp->scsi_done)(tmp);
-+    }
-+    while ((tmp = dq) != NULL) {
-+	dq = (Scsi_Cmnd *) tmp->host_scribble;
-+	tmp->host_scribble = NULL;
-+	if (tmp == Cmnd)
-+	    continue;
-+	tmp->result = DID_RESET << 16;
-+	/*
-+	 * Get around silliness in midlayer.
-+	 */
-+	tmp->flags |= IS_RESETTING;
-+	if (tmp->scsi_done)
-+	    (*tmp->scsi_done)(tmp);
-+    }
-+    Cmnd->result = DID_RESET << 16;
-+    return (SUCCESS);
-+}
-+
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+void
-+isp_attach_target(struct ispsoftc *isp)
-+{
-+    int i;
-+    hba_register_t hba;
-+
-+    isp->isp_osinfo.pool = isp_kzalloc(NTGT_CMDS * TMD_SIZE, GFP_KERNEL);
-+    if (isp->isp_osinfo.pool == NULL) {
-+	isp_prt(isp, ISP_LOGERR, "cannot allocate TMD structures");
-+	return;
-+    }
-+    for (i = 0; i < NTGT_CMDS-1; i++) {
-+	isp->isp_osinfo.pool[i].cd_private = &isp->isp_osinfo.pool[i+1];
-+    }
-+    isp->isp_osinfo.pending_t = NULL;
-+    isp->isp_osinfo.tfreelist = isp->isp_osinfo.pool;
-+
-+    hba.r_identity = isp;
-+    sprintf(hba.r_name, "isp");
-+    hba.r_inst = isp->isp_unit;
-+    hba.r_version = QR_VERSION;
-+    hba.r_action = (void (*)(tact_e, void *))isp_taction;
-+    if (IS_FC(isp)) {
-+	hba.r_type = R_FC;
-+    } else{
-+	hba.r_type = R_SCSI;
-+    }
-+    ISP_UNLKU_SOFTC(isp);
-+    ISP_PARENT_TARGET(QOUT_HBA_REG, &hba);
-+    ISP_LOCKU_SOFTC(isp);
-+}
-+
-+void
-+isp_detach_target(struct ispsoftc *isp)
-+{
-+    hba_register_t hba;
-+
-+    hba.r_identity = isp;
-+    sprintf(hba.r_name, "isp");
-+    hba.r_inst = isp->isp_unit;
-+    hba.r_version = QR_VERSION;
-+    hba.r_action = (void (*)(tact_e, void *))isp_taction;
-+    if (IS_FC(isp)) {
-+	hba.r_type = R_FC;
-+    } else{
-+	hba.r_type = R_SCSI;
-+    }
-+    ISP_PARENT_TARGET(QOUT_HBA_UNREG, &hba);
-+    if (isp->isp_osinfo.pool) {
-+	isp_kfree(isp->isp_osinfo.pool, NTGT_CMDS * TMD_SIZE);
-+	isp->isp_osinfo.pool = 0;
-+    }
-+}
-+
-+static void
-+isp_taction(qact_e action, void *arg)
-+{
-+    tmd_cmd_t *tmd;
-+    struct ispsoftc *isp;
-+
-+    switch (action) {
-+    case QIN_HBA_REG:
-+    {
-+	hba_register_t *hp = (hba_register_t *) arg;
-+	isp = hp->r_identity;
-+	isp_prt(isp, ISP_LOGINFO, "completed target registration");
-+	ISP_LOCK_SOFTC(isp);
-+	isp->isp_osinfo.hcb = 1;
-+	ISP_UNLK_SOFTC(isp);
-+	ISP_PARENT_TARGET(QOUT_HBA_REG, hp);
-+	break;
-+    }
-+    case QIN_ENABLE:
-+    case QIN_DISABLE:
-+    {
-+	enadis_t *ep = arg;
-+	int bus, lun, tgt, chan;
-+
-+	isp = ep->cd_hba;
-+	bus = (int) ep->cd_chan;
-+	lun = (int) ep->cd_lun;
-+	tgt = (int) ep->cd_tgt;
-+	chan = (int) ep->cd_chan;
-+	ep->cd_error = isp_en_dis_lun(isp, (action == QIN_ENABLE)? 1 : chan,
-+	    bus, tgt, lun);
-+	ISP_PARENT_TARGET(action, ep);
-+	break;
-+    }
-+    case QIN_TMD_CONT:
-+	tmd = (tmd_cmd_t *) arg;
-+	isp = tmd->cd_hba;
-+	isp_target_start_ctio(isp, tmd);
-+	break;
-+
-+    case QIN_TMD_FIN:
-+	tmd = (tmd_cmd_t *) arg;
-+	isp = tmd->cd_hba;
-+	MEMZERO(tmd, TMD_SIZE);
-+	ISP_LOCK_SOFTC(isp);
-+	tmd->cd_private = isp->isp_osinfo.tfreelist;
-+	isp->isp_osinfo.tfreelist = tmd;
-+	ISP_UNLK_SOFTC(isp);
-+	break;
-+
-+    case QIN_IOCTL:
-+    {
-+	ioctl_cmd_t *ip = arg;
-+	ip->i_errno = ENOTTY;
-+	ISP_PARENT_TARGET(QOUT_IOCTL, ip);
-+  	break;
-+    }
-+    case QIN_HBA_UNREG:
-+    {
-+	hba_register_t *hp = (hba_register_t *) arg;
-+	isp = hp->r_identity;
-+	isp->isp_osinfo.hcb = 0;
-+	ISP_PARENT_TARGET(QOUT_HBA_REG, hp);
-+	break;
-+    }
-+    default:
-+	break;
-+   }
-+}
-+
-+static INLINE int
-+nolunsenabled(struct ispsoftc *isp, int port)
-+{
-+    int i, wbase, wend;
-+
-+    if (IS_FC(isp)) {
-+	wbase = 0;
-+	wend = TM_MAX_LUN_FC >> 5;
-+    } else {
-+	if (port) {
-+		wend = TM_MAX_LUN_FC >> 5;
-+		wbase = wend >> 1;
-+	} else {
-+		wend = (TM_MAX_LUN_FC >> 5) >> 1;
-+		wbase = 0;
-+	}
-+    }
-+    for (i = wbase; i < wend; i++) {
-+	if (isp->isp_osinfo.lunbmap[i]) {
-+	    return (0);
-+	}
-+    }
-+    return (1);
-+}
-+
-+
-+
-+static void
-+isp_target_start_ctio(struct ispsoftc *isp, tmd_cmd_t *tmd)
-+{
-+    void *qe;
-+    u_int16_t *hp, save_handle;
-+    u_int32_t *rp;
-+    u_int16_t nxti, optr;
-+    u_int8_t local[QENTRY_LEN];
-+
-+    /*
-+     * If the transfer length is zero, we have to be sending status.
-+     * If we're sending data, we have to have one and only one data
-+     * direction set.
-+     */
-+    if (tmd->cd_xfrlen == 0) {
-+	if ((tmd->cd_hflags & CDFH_STSVALID) == 0) {
-+	    isp_prt(isp, ISP_LOGERR, "CTIO, no data, and no status is wrong");
-+	    tmd->cd_error = -EINVAL;
-+	    tmd->cd_lflags |= CDFL_ERROR;
-+	    return;
-+	}
-+    } else {
-+	if ((tmd->cd_hflags & CDFH_DATA_MASK) == 0) {
-+	    isp_prt(isp, ISP_LOGERR, "data CTIO with no direction is wrong");
-+	    tmd->cd_error = -EINVAL;
-+	    tmd->cd_lflags |= CDFL_ERROR;
-+	    return;
-+	}
-+	if ((tmd->cd_hflags & CDFH_DATA_MASK) == CDFH_DATA_MASK) {
-+	    isp_prt(isp, ISP_LOGERR, "data CTIO with both directions is wrong");
-+	    tmd->cd_error = -EINVAL;
-+	    tmd->cd_lflags |= CDFL_ERROR;
-+	    return;
-+	}
-+    }
-+    tmd->cd_lflags &= ~CDFL_ERROR;
-+    MEMZERO(local, QENTRY_LEN);
-+
-+    ISP_LOCK_SOFTC(isp);
-+    if (isp_getrqentry(isp, &nxti, &optr, &qe)) {
-+	isp_prt(isp, ISP_LOGWARN,
-+	    "isp_target_start_ctio: request queue overflow");
-+	tmd->cd_error = -ENOMEM;
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	ISP_UNLK_SOFTC(isp);
-+	return;
-+    }
-+
-+    /*
-+     * We're either moving data or completing a command here (or both).
-+     */
-+
-+    if (IS_FC(isp)) {
-+	ct2_entry_t *cto = (ct2_entry_t *) local;
-+	u_int16_t *ssptr = NULL;
-+
-+	cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
-+	cto->ct_header.rqs_entry_count = 1;
-+	cto->ct_iid = tmd->cd_iid;
-+	if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0)
-+		cto->ct_lun = tmd->cd_lun;
-+	else
-+		cto->ct_lun = 0;
-+	cto->ct_rxid = tmd->cd_tagval;
-+	if (cto->ct_rxid == 0) {
-+	    isp_prt(isp, ISP_LOGERR, "a tagval of zero is not acceptable");
-+	    tmd->cd_error = -EINVAL;
-+	    tmd->cd_lflags |= CDFL_ERROR;
-+	    ISP_UNLK_SOFTC(isp);
-+	    return;
-+	}
-+	cto->ct_flags = CT2_FASTPOST;
-+
-+	if (tmd->cd_xfrlen == 0) {
-+	    cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA | CT2_SENDSTATUS;
-+	    ssptr = &cto->rsp.m1.ct_scsi_status;
-+	    *ssptr = tmd->cd_scsi_status;
-+	    if ((tmd->cd_hflags & CDFH_SNSVALID) != 0) {
-+		MEMCPY(cto->rsp.m1.ct_resp, tmd->cd_sense, QLTM_SENSELEN);
-+		cto->rsp.m1.ct_senselen = QLTM_SENSELEN;
-+		cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
-+	    }
-+	} else {
-+	    cto->ct_flags |= CT2_FLAG_MODE0;
-+	    if (tmd->cd_hflags & CDFH_DATA_IN) {
-+		cto->ct_flags |= CT2_DATA_IN;
-+	    } else {
-+		cto->ct_flags |= CT2_DATA_OUT;
-+	    }
-+	    if (tmd->cd_hflags & CDFH_STSVALID) {
-+		ssptr = &cto->rsp.m0.ct_scsi_status;
-+		cto->ct_flags |= CT2_SENDSTATUS;
-+		cto->rsp.m0.ct_scsi_status = tmd->cd_scsi_status;
-+		/*
-+		 * It will be up to the low level mapping routine
-+		 * to check for sense data.
-+		 */
-+	    }
-+	    /*
-+	     * We assume we'll transfer what we say we'll transfer.
-+	     * It should get added back in if we fail.
-+	     */
-+	    tmd->cd_resid -= tmd->cd_xfrlen;
-+	}
-+
-+	if (ssptr && tmd->cd_resid) {
-+	    cto->ct_resid = tmd->cd_resid;
-+	    *ssptr |= CT2_DATA_UNDER;
-+	} else {
-+	    cto->ct_resid = 0;
-+	}
-+	isp_prt(isp, ISP_LOGTDEBUG0,
-+	    "CTIO2[%x] ssts %x flags %x resid %d",
-+	    cto->ct_rxid, tmd->cd_scsi_status, cto->ct_flags, cto->ct_resid);
-+	hp = &cto->ct_syshandle;
-+	rp = &cto->ct_resid;
-+	if (cto->ct_flags & CT2_SENDSTATUS) {
-+	    cto->ct_flags |= CT2_CCINCR;
-+	}
-+    } else {
-+	ct_entry_t *cto = (ct_entry_t *) local;
-+
-+	cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
-+	cto->ct_header.rqs_entry_count = 1;
-+	cto->ct_iid = tmd->cd_iid;
-+	cto->ct_tgt = tmd->cd_tgt;
-+	cto->ct_lun = tmd->cd_lun;
-+	cto->ct_flags = 0;
-+	cto->ct_fwhandle = AT_GET_HANDLE(tmd->cd_tagval);
-+	if (AT_HAS_TAG(tmd->cd_tagval)) {
-+	    cto->ct_tag_val = AT_GET_TAG(tmd->cd_tagval);
-+	    cto->ct_flags |= CT_TQAE;
-+	}
-+	if (tmd->cd_lflags & CDFL_NODISC) {
-+	    cto->ct_flags |= CT_NODISC;
-+	}
-+	if (tmd->cd_xfrlen == 0) {
-+	    cto->ct_flags |= CT_NO_DATA | CT_SENDSTATUS;
-+	    cto->ct_scsi_status = tmd->cd_scsi_status;
-+	    cto->ct_resid = 0;
-+	} else {
-+	    if (tmd->cd_hflags & CDFH_STSVALID) {
-+		cto->ct_flags |= CT_SENDSTATUS;
-+	    }
-+	    if (tmd->cd_hflags & CDFH_DATA_IN) {
-+		cto->ct_flags |= CT_DATA_IN;
-+	    } else {
-+		cto->ct_flags |= CT_DATA_OUT;
-+	    }
-+	    /*
-+	     * We assume we'll transfer what we say we'll transfer.
-+	     * Otherwise, the command is dead.
-+	     */
-+	    tmd->cd_resid -= tmd->cd_xfrlen;
-+	    if (tmd->cd_hflags & CDFH_STSVALID) {
-+		cto->ct_resid = tmd->cd_resid;
-+	    }
-+	}
-+	isp_prt(isp, ISP_LOGTDEBUG0, "CTIO[%x] ssts %x resid %d cd_hflags %x",
-+	    AT_GET_HANDLE(tmd->cd_tagval), tmd->cd_scsi_status, tmd->cd_resid,
-+	    tmd->cd_hflags);
-+	hp = &cto->ct_syshandle;
-+	rp = &cto->ct_resid;
-+	if (cto->ct_flags & CT_SENDSTATUS) {
-+	    cto->ct_flags |= CT_CCINCR;
-+	}
-+    }
-+
-+    if (isp_save_xs(isp, (XS_T *)tmd, hp)) {
-+	isp_prt(isp, ISP_LOGERR, "isp_target_start_ctio: No XFLIST pointers");
-+	tmd->cd_error = -ENOMEM;
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	ISP_UNLK_SOFTC(isp);
-+	ISP_PARENT_TARGET(QOUT_TMD_DONE, tmd);
-+	return;
-+    }
-+
-+    /*
-+     * Call the dma setup routines for this entry (and any subsequent
-+     * CTIOs) if there's data to move, and then tell the f/w it's got
-+     * new things to play with. As with isp_start's usage of DMA setup,
-+     * any swizzling is done in the machine dependent layer. Because
-+     * of this, we put the request onto the queue area first in native
-+     * format.
-+     */
-+
-+    save_handle = *hp;
-+    switch (ISP_DMASETUP(isp, (XS_T *)tmd, (ispreq_t *) local, &nxti, optr)) {
-+    case CMD_QUEUED:
-+	ISP_ADD_REQUEST(isp, nxti);
-+	ISP_UNLK_SOFTC(isp);
-+	return;
-+
-+    case CMD_EAGAIN:
-+	tmd->cd_error = -ENOMEM;
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	isp_destroy_handle(isp, save_handle);
-+	break;
-+
-+    case CMD_COMPLETE:
-+	tmd->cd_error = *rp;	/* propagated back */
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	isp_destroy_handle(isp, save_handle);
-+	break;
-+
-+    default:
-+	tmd->cd_error = -EFAULT;	/* probably dma mapping failure */
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	isp_destroy_handle(isp, save_handle);
-+	break;
-+    }
-+    ISP_UNLK_SOFTC(isp);
-+    ISP_PARENT_TARGET(QOUT_TMD_DONE, tmd);
-+}
-+
-+/*
-+ * Handle ATIO stuff that the generic code can't.
-+ * This means handling CDBs.
-+ */
-+
-+static int
-+isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep)
-+{
-+    tmd_cmd_t *tmd;
-+    int status;
-+
-+    /*
-+     * The firmware status (except for the QLTM_SVALID bit)
-+     * indicates why this ATIO was sent to us.
-+     *
-+     * If QLTM_SVALID is set, the firware has recommended Sense Data.
-+     *
-+     * If the DISCONNECTS DISABLED bit is set in the flags field,
-+     * we're still connected on the SCSI bus.
-+     */
-+    status = aep->at_status;
-+
-+    if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
-+	/*
-+	 * Bus Phase Sequence error. We should have sense data
-+	 * suggested by the f/w. I'm not sure quite yet what
-+	 * to do about this.
-+	 */
-+	isp_prt(isp, ISP_LOGERR, "PHASE ERROR in atio");
-+	isp_endcmd(isp, aep, SCSI_BUSY, 0);
-+	return (0);
-+    }
-+
-+    if ((status & ~QLTM_SVALID) != AT_CDB) {
-+	isp_prt(isp, ISP_LOGERR, "bad atio (0x%x) leaked to platform", status);
-+	isp_endcmd(isp, aep, SCSI_BUSY, 0);
-+	return (0);
-+    }
-+
-+    if ((tmd = isp->isp_osinfo.tfreelist) == NULL) {
-+	/*
-+	 * We're out of resources.
-+	 *
-+	 * Because we can't autofeed sense data back with a command for
-+	 * parallel SCSI, we can't give back a CHECK CONDITION. We'll give
-+	 * back a QUEUE FULL or BUSY status instead.
-+	 */
-+	isp_prt(isp, ISP_LOGERR,
-+	    "no ATIOS for lun %d from initiator %d on channel %d",
-+	    aep->at_lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
-+	if (aep->at_flags & AT_TQAE)
-+	    isp_endcmd(isp, aep, SCSI_QFULL, 0);
-+	else
-+	    isp_endcmd(isp, aep, SCSI_BUSY, 0);
-+	return (0);
-+    }
-+    isp->isp_osinfo.tfreelist = tmd->cd_private;
-+    tmd->cd_lflags = CDFL_BUSY;
-+    tmd->cd_chan = GET_BUS_VAL(aep->at_iid);
-+    tmd->cd_iid = GET_IID_VAL(aep->at_iid);
-+    tmd->cd_tgt = aep->at_tgt;
-+    tmd->cd_lun = aep->at_lun;
-+    if (aep->at_flags & AT_NODISC) {
-+	tmd->cd_lflags |= CDFL_NODISC;
-+    }
-+    if (status & QLTM_SVALID) {
-+	MEMCPY(tmd->cd_sense, aep->at_sense, QLTM_SENSELEN);
-+	tmd->cd_lflags |= CDFL_SNSVALID;
-+    }
-+    MEMCPY(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO_CDBLEN));
-+    AT_MAKE_TAGID(tmd->cd_tagval, aep);
-+    tmd->cd_tagtype = aep->at_tag_type;
-+    tmd->cd_hba = isp;
-+    tmd->cd_data = NULL;
-+    tmd->cd_hflags = 0;
-+    tmd->cd_totlen = tmd->cd_resid = tmd->cd_xfrlen = tmd->cd_error = 0;
-+    tmd->cd_scsi_status = 0;
-+    isp_prt(isp, ISP_LOGTDEBUG1,
-+        "ATIO[%x] CDB=0x%x bus %d iid%d->lun%d tag 0x%x ttype 0x%x %s",
-+	aep->at_handle, aep->at_cdb[0] & 0xff, GET_BUS_VAL(aep->at_iid),
-+	GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_val & 0xff,
-+	aep->at_tag_type, (aep->at_flags & AT_NODISC)?
-+	"nondisc" : "disconnecting");
-+    if (isp->isp_osinfo.hcb == 0) {
-+	isp_endcmd(isp, aep, SCSI_BUSY, 0);
-+    } else {
-+	isp->isp_osinfo.tfreelist = tmd->cd_private;
-+	tmd->cd_lreserved[0].bytes[0] = QOUT_TMD_START;
-+	tmd->cd_lreserved[1].ptrs[0] = isp->isp_osinfo.pending_t;
-+	isp->isp_osinfo.pending_t = tmd;
-+    }
-+    return (0);
-+}
-+
-+static int
-+isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
-+{
-+    tmd_cmd_t *tmd;
-+    int lun;
-+
-+    /*
-+     * The firmware status (except for the QLTM_SVALID bit)
-+     * indicates why this ATIO was sent to us.
-+     *
-+     * If QLTM_SVALID is set, the firware has recommended Sense Data.
-+     */
-+    if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) {
-+	isp_prt(isp, ISP_LOGERR, "bad atio (0x%x) leaked to platform",
-+	    aep->at_status);
-+	isp_endcmd(isp, aep, SCSI_BUSY, 0);
-+	return (0);
-+    }
-+    if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
-+	lun = aep->at_scclun;
-+    else
-+	lun = aep->at_lun;
-+
-+    /*
-+     * If we're out of resources, just send a QFULL status back.
-+     */
-+    if ((tmd = isp->isp_osinfo.tfreelist) == NULL) {
-+	isp_endcmd(isp, aep, SCSI_QFULL, 0);
-+	return (0);
-+    }
-+    tmd->cd_lflags = CDFL_BUSY;
-+    tmd->cd_iid = aep->at_iid;
-+    tmd->cd_tgt = ((fcparam *)isp->isp_param)->isp_loopid;
-+    tmd->cd_lun = lun;
-+    tmd->cd_chan = 0;
-+    MEMCPY(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO2_CDBLEN));
-+    switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
-+    case ATIO2_TC_ATTR_SIMPLEQ:
-+	tmd->cd_tagtype = MSG_SIMPLE_Q_TAG;
-+	break;
-+    case ATIO2_TC_ATTR_HEADOFQ:
-+	tmd->cd_tagtype = MSG_HEAD_OF_Q_TAG;
-+	break;
-+    case ATIO2_TC_ATTR_ORDERED:
-+	tmd->cd_tagtype = MSG_ORDERED_Q_TAG;
-+	break;
-+    case ATIO2_TC_ATTR_ACAQ:		/* ?? */
-+    case ATIO2_TC_ATTR_UNTAGGED:
-+    default:
-+	tmd->cd_tagtype = 0;
-+	break;
-+    }
-+    switch (aep->at_execodes & (ATIO2_EX_WRITE|ATIO2_EX_READ)) {
-+    case ATIO2_EX_WRITE:
-+	tmd->cd_lflags |= CDFL_DATA_OUT;
-+	break;
-+    case ATIO2_EX_READ:
-+	tmd->cd_lflags |= CDFL_DATA_IN;
-+	break;
-+    case ATIO2_EX_WRITE|ATIO2_EX_READ:
-+	tmd->cd_lflags |= CDFL_BIDIR;
-+	isp_prt(isp, ISP_LOGWARN, "ATIO2 with both read/write set");
-+	break;
-+    default:
-+	break;
-+    }
-+    tmd->cd_tagval = aep->at_rxid;
-+    tmd->cd_hba = isp;
-+    tmd->cd_data = NULL;
-+    tmd->cd_hflags = 0;
-+    tmd->cd_totlen = aep->at_datalen;
-+    tmd->cd_resid = tmd->cd_xfrlen = tmd->cd_error = 0;
-+    tmd->cd_scsi_status = 0;
-+    if ((isp->isp_dblev & ISP_LOGTDEBUG0) || isp->isp_osinfo.hcb == 0) {
-+	const char *sstr;
-+	switch (tmd->cd_lflags & CDFL_BIDIR) {
-+	default:
-+	    sstr = "nodatadir";
-+	    break;
-+	case CDFL_DATA_OUT:
-+	    sstr = "DATA OUT";
-+	    break;
-+	case CDFL_DATA_IN:
-+	    sstr = "DATA IN";
-+	    break;
-+	case CDFL_DATA_OUT|CDFL_DATA_IN:
-+	    sstr = "BIDIR";
-+	    break;
-+	}
-+	isp_prt(isp, ISP_LOGALL,
-+	    "ATIO2[%x] CDB=0x%x iid %d for lun %d tcode 0x%x dlen %d %s",
-+	    aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid,
-+	    lun, aep->at_taskcodes, aep->at_datalen, sstr);
-+    }
-+    if (isp->isp_osinfo.hcb == 0) {
-+	if (aep->at_cdb[0] == INQUIRY && lun == 0) {
-+	    if (aep->at_cdb[1] == 0 && aep->at_cdb[2] == 0) {
-+		static u_int8_t inqdata[] = {
-+		    DEFAULT_DEVICE_TYPE, 0x0, 0x2, 0x2, 32, 0, 0, 0x40,
-+		    'L', 'I', 'N', 'U', 'X', ' ', ' ', ' ',
-+		    'T', 'A', 'R', 'G', 'E', 'T', ' ', 'D',
-+		    'D', 'E', 'V', 'I', 'C', 'E', ' ', ' ',
-+		    '0', '0', '0', '1'
-+		};
-+		struct scatterlist single, *dp = &single;
-+		MEMZERO(dp, sizeof (*dp));
-+		dp->address = inqdata;
-+		dp->length = sizeof (inqdata);
-+		tmd->cd_data = dp;
-+		tmd->cd_resid = tmd->cd_xfrlen = sizeof (inqdata);
-+		tmd->cd_hflags |= CDFH_DATA_IN|CDFH_STSVALID;
-+		ISP_DROP_LK_SOFTC(isp);
-+		isp_target_start_ctio(isp, tmd);
-+		ISP_IGET_LK_SOFTC(isp);
-+	    } else {
-+		/*
-+		 * Illegal field in CDB
-+		 *  0x24 << 24 | 0x5 << 12 | ECMD_SVALID | SCSI_CHECK
-+		 */
-+		isp_endcmd(isp, aep, 0x24005102, 0);
-+	    }
-+	} else if (lun == 0) {
-+		/*
-+		 * Not Ready, Cause Not Reportable
-+		 *
-+		 *  0x4 << 24 | 0x2 << 12 | ECMD_SVALID | SCSI_CHECK
-+		 */
-+		isp_endcmd(isp, aep, 0x04002102, 0);
-+	} else {
-+	    /*
-+	     * Logical Unit Not Supported:
-+	     * 	0x25 << 24 | 0x5 << 12 | ECMD_SVALID | SCSI_CHECK
-+	     */
-+	    isp_endcmd(isp, aep, 0x25005102, 0);
-+	}
-+	MEMZERO(tmd, TMD_SIZE);
-+	return (0);
-+    }
-+    isp->isp_osinfo.tfreelist = tmd->cd_private;
-+    tmd->cd_lreserved[0].bytes[0] = QOUT_TMD_START;
-+    tmd->cd_lreserved[1].ptrs[0] = isp->isp_osinfo.pending_t;
-+    isp->isp_osinfo.pending_t = tmd;
-+    return (0);
-+}
-+
-+static int
-+isp_handle_platform_ctio(struct ispsoftc *isp, void *arg)
-+{
-+    tmd_cmd_t *tmd;
-+    int sentstatus, ok, resid = 0, sts;
-+
-+    /*
-+     * CTIO and CTIO2 are close enough....
-+     */
-+    tmd = (tmd_cmd_t *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_syshandle);
-+    if (tmd == NULL) {
-+	isp_prt(isp, ISP_LOGERR, "isp_handle_platform_ctio: null tmd");
-+	return (0);
-+    }
-+    isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
-+
-+    if (IS_FC(isp)) {
-+	ct2_entry_t *ct = arg;
-+	sentstatus = ct->ct_flags & CT2_SENDSTATUS;
-+	if (sentstatus) {
-+	    tmd->cd_lflags |= CDFL_SENTSTATUS;
-+	}
-+	sts = ct->ct_status & ~QLTM_SVALID;
-+	ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
-+	if (ok && sentstatus && (tmd->cd_hflags & CDFH_SNSVALID)) {
-+	    tmd->cd_lflags |= CDFL_SENTSENSE;
-+	}
-+	isp_prt(isp, ISP_LOGTDEBUG1,
-+	    "CTIO2[%x] sts 0x%x flg 0x%x sns %d %s",
-+	    ct->ct_rxid, ct->ct_status, ct->ct_flags,
-+	    (tmd->cd_lflags & CDFL_SENTSENSE) != 0,
-+	    sentstatus? "FIN" : "MID");
-+	if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
-+	    resid = ct->ct_resid;
-+	}
-+    } else {
-+	ct_entry_t *ct = arg;
-+	sts = ct->ct_status & ~QLTM_SVALID;
-+	sentstatus = ct->ct_flags & CT_SENDSTATUS;
-+	if (sentstatus) {
-+	    tmd->cd_lflags |= CDFL_SENTSTATUS;
-+	}
-+	ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
-+	if (ok && sentstatus && (tmd->cd_hflags & CDFH_SNSVALID)) {
-+	    tmd->cd_lflags |= CDFL_SENTSENSE;
-+	}
-+	isp_prt(isp, ISP_LOGTDEBUG1,
-+	    "CTIO[%x] tag %x iid %x tgt %d lun %d sts 0x%x flg %x %s",
-+	    ct->ct_fwhandle, ct->ct_tag_val, ct->ct_iid, ct->ct_tgt,
-+	    ct->ct_lun, ct->ct_status, ct->ct_flags,
-+	    sentstatus? "FIN" : "MID");
-+	if (ct->ct_status & QLTM_SVALID) {
-+	    char *sp = (char *)ct;
-+	    sp += CTIO_SENSE_OFFSET;
-+	    MEMCPY(tmd->cd_sense, sp, QLTM_SENSELEN);
-+	    tmd->cd_lflags |= CDFL_SNSVALID;
-+	}
-+	if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
-+	    resid = ct->ct_resid;
-+	}
-+    }
-+    tmd->cd_resid += resid;
-+
-+    /*
-+     * We're here either because intermediate data transfers are done
-+     * and/or the final status CTIO (which may have joined with a
-+     * Data Transfer) is done.
-+     *
-+     * In any case, for this platform, the upper layers figure out
-+     * what to do next, so all we do here is collect status and
-+     * pass information along.
-+     */
-+    isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO done (resid %d)",
-+	(sentstatus)? "  FINAL " : "MIDTERM ", tmd->cd_resid);
-+
-+    if (!ok) {
-+	isp_prt(isp, ISP_LOGERR, "CTIO ended with badstate (0x%x)", sts);
-+	tmd->cd_lflags |= CDFL_ERROR;
-+	tmd->cd_error = -EIO;
-+	isp_target_putback_atio(isp, tmd);
-+    } else {
-+	isp_complete_ctio(isp, tmd);
-+    }
-+    return (0);
-+}
-+
-+static int
-+isp_handle_platform_ctio_fastpost(struct ispsoftc *isp, u_int32_t token)
-+{
-+    tmd_cmd_t *tmd;
-+    u_int16_t handle;
-+
-+    handle = token & 0xffff;
-+    tmd = (tmd_cmd_t *) isp_find_xs(isp, handle);
-+    if (tmd == NULL) {
-+	isp_prt(isp, ISP_LOGERR,
-+	    "isp_handle_platform_ctio_fastpost: null tmd");
-+	return (0);
-+    }
-+    isp_destroy_handle(isp, handle);
-+    isp_prt(isp, ISP_LOGTDEBUG1, "CTIOx[%x] fastpost complete", tmd->cd_tagval);
-+    /*
-+     * In this implementation we only set fast posting for the last ctio2
-+     * of a command where we haven't sent sense data as well.
-+     */
-+    tmd->cd_lflags |= CDFL_SENTSTATUS;
-+    isp_complete_ctio(isp, tmd);
-+    return (0);
-+}
-+
-+static void
-+isp_target_putback_atio(struct ispsoftc *isp, tmd_cmd_t *tmd)
-+{
-+    u_int16_t nxti;
-+    u_int8_t local[QENTRY_LEN];
-+    void *qe;
-+
-+    if (isp_getrqentry(isp, &nxti, NULL, &qe)) {
-+	isp_prt(isp, ISP_LOGWARN,
-+	    "isp_target_putback_atio: Request Queue Overflow");
-+	/* XXXX */
-+	isp_complete_ctio(isp, tmd);
-+	return;
-+    }
-+    MEMZERO(local, sizeof (local));
-+    if (IS_FC(isp)) {
-+	at2_entry_t *at = (at2_entry_t *) local;
-+	at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
-+	at->at_header.rqs_entry_count = 1;
-+	if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
-+	    at->at_scclun = (uint16_t) tmd->cd_lun;
-+	else
-+	    at->at_lun = (uint8_t) tmd->cd_lun;
-+	at->at_status = CT_OK;
-+	at->at_rxid = tmd->cd_tagval;
-+	isp_put_atio2(isp, at, qe);
-+    } else {
-+	at_entry_t *at = (at_entry_t *)local;
-+	at->at_header.rqs_entry_type = RQSTYPE_ATIO;
-+	at->at_header.rqs_entry_count = 1;
-+	at->at_iid = tmd->cd_iid;
-+	at->at_iid |= tmd->cd_chan << 7;
-+	at->at_tgt = tmd->cd_tgt;
-+	at->at_lun = tmd->cd_lun;
-+	at->at_status = CT_OK;
-+	at->at_tag_val = AT_GET_TAG(tmd->cd_tagval);
-+	at->at_handle = AT_GET_HANDLE(tmd->cd_tagval);
-+	isp_put_atio(isp, at, qe);
-+    }
-+    ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe);
-+    ISP_ADD_REQUEST(isp, nxti);
-+    isp_complete_ctio(isp, tmd);
-+}
-+
-+static void
-+isp_complete_ctio(struct ispsoftc *isp, tmd_cmd_t *tmd)
-+{
-+    if (isp->isp_osinfo.hcb == 0) {
-+	isp_prt(isp, ISP_LOGWARN, "nobody to tell about completing command");
-+	MEMZERO(tmd, TMD_SIZE);
-+	tmd->cd_private = isp->isp_osinfo.tfreelist;
-+	isp->isp_osinfo.tfreelist = tmd;
-+    } else {
-+	tmd->cd_lreserved[0].bytes[0] = QOUT_TMD_DONE;
-+	tmd->cd_lreserved[1].ptrs[0] = isp->isp_osinfo.pending_t;
-+	isp->isp_osinfo.pending_t = tmd;
-+    }
-+}
-+
-+int
-+isp_en_dis_lun(struct ispsoftc *isp, int enable, int bus, int tgt, int lun)
-+{
-+    DECLARE_MUTEX_LOCKED(rsem);
-+    u_int16_t rstat;
-+    int rv, enabled, cmd;
-+
-+    /*
-+     * First, we can't do anything unless we have an upper
-+     * level target driver to route commands to.
-+     */
-+    if (isp->isp_osinfo.hcb == 0) {
-+	return (-EINVAL);
-+    }
-+
-+    /*
-+     * Second, check for sanity of enable argument.
-+     */
-+    enabled = ((isp->isp_osinfo.tmflags & (1 << bus)) != 0);
-+    if (enable == 0 && enabled == 0) {
-+	return (-EINVAL);
-+    }
-+
-+    /*
-+     * Third, check to see if we're enabling on fibre channel
-+     * and don't yet have a notion of who the heck we are (no
-+     * loop yet).
-+     */
-+    if (IS_FC(isp) && !enabled) {
-+	ISP_LOCK_SOFTC(isp);
-+	if ((isp->isp_role & ISP_ROLE_TARGET) == 0) {
-+	    isp->isp_role |= ISP_ROLE_TARGET;
-+	    if (isp_drain_reset(isp, "lun enables")) {
-+		return (-EIO);
-+	    }
-+	}
-+	ISP_UNLK_SOFTC(isp);
-+	SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 1);
-+    }
-+
-+    /*
-+     * If this is a wildcard target, select our initiator
-+     * id/loop id for use as what we enable as.
-+     */
-+
-+    if (tgt == -1) {
-+	if (IS_FC(isp)) {
-+	    tgt = ((fcparam *)isp->isp_param)->isp_loopid;
-+	} else {
-+	    tgt = ((sdparam *)isp->isp_param)->isp_initiator_id;
-+	}
-+    }
-+
-+    /*
-+     * Do some sanity checking on lun arguments.
-+     */
-+
-+    if (lun < 0 || lun >= (IS_FC(isp)? TM_MAX_LUN_FC : TM_MAX_LUN_SCSI)) {
-+	return (-EINVAL);
-+    }
-+
-+    /*
-+     * Snag the semaphore on the return state value on enables/disables.
-+     */
-+    if (down_interruptible(&isp->isp_osinfo.tgt_inisem)) {
-+	return (-EINTR);
-+    }
-+
-+    if (enable && LUN_BTST(isp, bus, lun)) {
-+	up(&isp->isp_osinfo.tgt_inisem);
-+	return (-EEXIST);
-+    }
-+    if (!enable && !LUN_BTST(isp, bus, lun)) {
-+	up(&isp->isp_osinfo.tgt_inisem);
-+	return (-NODEV);
-+    }
-+
-+    if (enable && nolunsenabled(isp, bus)) {
-+	int av = (bus << 31) | ENABLE_TARGET_FLAG;
-+	ISP_LOCK_SOFTC(isp);
-+	rv = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
-+	ISP_UNLK_SOFTC(isp);
-+	if (rv) {
-+	    up(&isp->isp_osinfo.tgt_inisem);
-+	    return (-EIO);
-+	}
-+    }
-+
-+    ISP_LOCK_SOFTC(isp);
-+    isp->isp_osinfo.rsemap = &rsem;
-+    if (enable) {
-+	u_int32_t seq = isp->isp_osinfo.rollinfo++;
-+	int n, ulun = lun;
-+
-+	cmd = RQSTYPE_ENABLE_LUN;
-+	n = DFLT_INOT_CNT;
-+	if (IS_FC(isp) && lun != 0) {
-+	    cmd = RQSTYPE_MODIFY_LUN;
-+	    n = 0;
-+	    /*
-+	     * For SCC firmware, we only deal with setting
-+	     * (enabling or modifying) lun 0.
-+	     */
-+	    ulun = 0;
-+	}
-+	rstat = LUN_ERR;
-+	if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, DFLT_CMND_CNT, n, seq)) {
-+	    isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
-+	    goto out;
-+	}
-+	ISP_UNLK_SOFTC(isp);
-+	down(isp->isp_osinfo.rsemap);
-+	ISP_LOCK_SOFTC(isp);
-+	isp->isp_osinfo.rsemap = NULL;
-+	rstat = isp->isp_osinfo.rstatus;
-+	if (rstat != LUN_OK) {
-+	    isp_prt(isp, ISP_LOGERR, "MODIFY/ENABLE LUN returned 0x%x", rstat);
-+	    goto out;
-+	}
-+    } else {
-+	int n, ulun = lun;
-+	u_int32_t seq;
-+
-+	rstat = LUN_ERR;
-+	seq = isp->isp_osinfo.rollinfo++;
-+	cmd = -RQSTYPE_MODIFY_LUN;
-+
-+	n = DFLT_INOT_CNT;
-+	if (IS_FC(isp) && lun != 0) {
-+	    n = 0;
-+	    /*
-+	     * For SCC firmware, we only deal with setting
-+	     * (enabling or modifying) lun 0.
-+	     */
-+	    ulun = 0;
-+	}
-+	if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, DFLT_CMND_CNT, n, seq)) {
-+	    isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
-+	    goto out;
-+	}
-+	ISP_UNLK_SOFTC(isp);
-+	down(isp->isp_osinfo.rsemap);
-+	ISP_LOCK_SOFTC(isp);
-+	isp->isp_osinfo.rsemap = NULL;
-+	rstat = isp->isp_osinfo.rstatus;
-+	if (rstat != LUN_OK) {
-+	    isp_prt(isp, ISP_LOGERR, "MODIFY LUN returned 0x%x", rstat);
-+	    goto out;
-+	}
-+	if (IS_FC(isp) && lun) {
-+	    goto out;
-+	}
-+	seq = isp->isp_osinfo.rollinfo++;
-+	isp->isp_osinfo.rsemap = &rsem;
-+
-+	rstat = LUN_ERR;
-+	cmd = -RQSTYPE_ENABLE_LUN;
-+	if (isp_lun_cmd(isp, cmd, bus, tgt, lun, 0, 0, seq)) {
-+	    isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
-+	    goto out;
-+	}
-+	ISP_UNLK_SOFTC(isp);
-+	down(isp->isp_osinfo.rsemap);
-+	ISP_LOCK_SOFTC(isp);
-+	isp->isp_osinfo.rsemap = NULL;
-+	rstat = isp->isp_osinfo.rstatus;
-+	if (rstat != LUN_OK) {
-+	    isp_prt(isp, ISP_LOGERR, "DISABLE LUN returned 0x%x", rstat);
-+	    goto out;
-+	}
-+    }
-+out:
-+
-+    if (rstat != LUN_OK) {
-+	isp_prt(isp, ISP_LOGERR, "lun %d %sable failed", lun,
-+	    (enable) ? "en" : "dis");
-+	ISP_UNLK_SOFTC(isp);
-+	up(&isp->isp_osinfo.tgt_inisem);
-+	return (-EIO);
-+    } else {
-+	isp_prt(isp, ISP_LOGINFO,
-+	    "lun %d now %sabled for target mode on channel %d", lun,
-+	    (enable)? "en" : "dis", bus);
-+	if (enable == 0) {
-+	    LUN_BCLR(isp, bus, lun);
-+	    if (nolunsenabled(isp, bus)) {
-+		int av = bus << 31;
-+		rv = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
-+		if (rv) {
-+		    isp_prt(isp, ISP_LOGERR,
-+			"failed to disable target mode on channel %d", bus);
-+		    /* but proceed */
-+		    ISP_UNLK_SOFTC(isp);
-+		    return (-EIO);
-+		}
-+		isp->isp_osinfo.tmflags &= ~(1 << bus);
-+		isp->isp_role &= ~ISP_ROLE_TARGET;
-+		if (IS_FC(isp)) {
-+		    if (isp_drain_reset(isp, "lun disables")) {
-+			return (-EIO);
-+		    }
-+		    if ((isp->isp_role & ISP_ROLE_INITIATOR) != 0) {
-+			ISP_UNLK_SOFTC(isp);
-+			SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 1);
-+			ISP_LOCK_SOFTC(isp);
-+		    }
-+		}
-+	    }
-+	} else {
-+	    isp->isp_osinfo.tmflags |= (1 << bus);
-+	    LUN_BSET(isp, bus, lun);
-+	}
-+	ISP_UNLK_SOFTC(isp);
-+	up(&isp->isp_osinfo.tgt_inisem);
-+	return (0);
-+    }
-+}
-+#endif
-+
-+#ifdef	ISP_PRIVATE_ASYNC
-+#define	ISP_ASYNC	isp_async_level1
-+#else
-+#define	ISP_ASYNC	isp_async
-+#endif
-+
-+int
-+ISP_ASYNC(struct ispsoftc *isp, ispasync_t cmd, void *arg)
-+{
-+    switch (cmd) {
-+    case ISPASYNC_NEW_TGT_PARAMS:
-+	if (IS_SCSI(isp)) {
-+	    sdparam *sdp = isp->isp_param;
-+	    char *wt;
-+	    int mhz, flags, bus, tgt, period;
-+
-+	    tgt = *((int *) arg);
-+	    bus = (tgt >> 16) & 0xffff;
-+	    tgt &= 0xffff;
-+
-+	    sdp += bus;
-+	    flags = sdp->isp_devparam[tgt].actv_flags;
-+	    period = sdp->isp_devparam[tgt].actv_period;
-+	    if ((flags & DPARM_SYNC) && period &&
-+		(sdp->isp_devparam[tgt].actv_offset) != 0) {
-+		if (sdp->isp_lvdmode || period < 0xc) {
-+		    switch (period) {
-+		    case 0x9:
-+			mhz = 80;
-+			break;
-+		    case 0xa:
-+			mhz = 40;
-+			break;
-+		    case 0xb:
-+			mhz = 33;
-+			break;
-+		    case 0xc:
-+			mhz = 25;
-+			break;
-+		    default:
-+			mhz = 1000 / (period * 4);
-+			break;
-+		    }
-+		} else {
-+		    mhz = 1000 / (period * 4);
-+		}
-+	    } else {
-+		mhz = 0;
-+	    }
-+	    switch (flags & (DPARM_WIDE|DPARM_TQING)) {
-+	    case DPARM_WIDE:
-+		wt = ", 16 bit wide";
-+		break;
-+	    case DPARM_TQING:
-+		wt = ", Tagged Queueing Enabled";
-+		break;
-+	    case DPARM_WIDE|DPARM_TQING:
-+		wt = ", 16 bit wide, Tagged Queueing Enabled";
-+		break;
-+	    default:
-+		wt = " ";
-+		break;
-+	    }
-+	    if (mhz) {
-+		isp_prt(isp, ISP_LOGINFO,
-+		    "Channel %d Target %d at %dMHz Max Offset %d%s",
-+		    bus, tgt, mhz, sdp->isp_devparam[tgt].actv_offset, wt);
-+	    } else {
-+		isp_prt(isp, ISP_LOGINFO, "Channel %d Target %d Async Mode%s",
-+		    bus, tgt, wt);
-+	    }
-+	}
-+	break;
-+    case ISPASYNC_LIP:
-+	isp_prt(isp, ISP_LOGINFO, "LIP Received");
-+	break;
-+    case ISPASYNC_LOOP_RESET:
-+	isp_prt(isp, ISP_LOGINFO, "Loop Reset Received");
-+	break;
-+    case ISPASYNC_BUS_RESET:
-+	isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", *((int *) arg));
-+	break;
-+    case ISPASYNC_LOOP_DOWN:
-+	isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
-+	break;
-+    case ISPASYNC_LOOP_UP:
-+	isp_prt(isp, ISP_LOGINFO, "Loop UP");
-+	break;
-+    case ISPASYNC_PROMENADE:
-+    {
-+	fcparam *fcp = isp->isp_param;
-+	struct lportdb *lp;
-+	int tgt;
-+
-+	tgt = *((int *) arg);
-+	lp = &fcp->portdb[tgt];
-+
-+	if (lp->valid) {
-+	    isp_prt(isp, ISP_LOGINFO,
-+		"ID %d (Loop 0x%x) Port WWN 0x%08x%08x @ 0x%x arrived, role %s",
-+		tgt, lp->loopid, (unsigned int) (lp->port_wwn >> 32),
-+		(unsigned int) (lp->port_wwn & 0xffffffff), lp->portid,
-+		class3_roles[fcp->portdb[tgt].roles]);
-+	} else {
-+	    isp_prt(isp, ISP_LOGINFO,
-+		"ID %d (Loop 0x%x) Port WWN 0x%08x%08x @ 0x%x departed", tgt,
-+		lp->loopid, (unsigned int) (lp->port_wwn >> 32),
-+		(unsigned int) (lp->port_wwn & 0xffffffff), lp->portid);
-+#ifdef	DEVICE_POLICY_IS_FLUID
-+		MEMZERO((void *) lp, sizeof (*lp));
-+#endif
-+	}
-+	break;
-+    }
-+    case ISPASYNC_CHANGE_NOTIFY:
-+	if (arg == ISPASYNC_CHANGE_PDB) {
-+		isp_prt(isp, ISP_LOGINFO,
-+		    "Port Database Changed");
-+	} else if (arg == ISPASYNC_CHANGE_SNS) {
-+		isp_prt(isp, ISP_LOGINFO,
-+		    "Name Server Database Changed");
-+	}
-+	SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);
-+	break;
-+    case ISPASYNC_FABRIC_DEV:
-+    {
-+	int target, base, lim;
-+	fcparam *fcp = isp->isp_param;
-+	struct lportdb *lp = NULL;
-+	struct lportdb *clp = (struct lportdb *) arg;
-+	char *pt;
-+
-+	switch (clp->port_type) {
-+	case 1:
-+		pt = "   N_Port";
-+		break;
-+	case 2:
-+		pt = "  NL_Port";
-+		break;
-+	case 3:
-+		pt = "F/NL_Port";
-+		break;
-+	case 0x7f:
-+		pt = "  Nx_Port";
-+		break;
-+	case 0x81:
-+		pt = "  F_port";
-+		break;
-+	case 0x82:
-+		pt = "  FL_Port";
-+		break;
-+	case 0x84:
-+		pt = "   E_port";
-+		break;
-+	default:
-+		pt = " ";
-+		break;
-+	}
-+
-+	isp_prt(isp, ISP_LOGINFO,
-+	    "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
-+
-+	/*
-+	 * If we don't have an initiator role we bail.
-+	 *
-+	 * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
-+	 */
-+
-+	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
-+		break;
-+	}
-+
-+	/*
-+	 * Is this entry for us? If so, we bail.
-+	 */
-+
-+	if (fcp->isp_portid == clp->portid) {
-+		break;
-+	}
-+
-+	/*
-+	 * Else, the default policy is to find room for it in
-+	 * our local port database. Later, when we execute
-+	 * the call to isp_pdb_sync either this newly arrived
-+	 * or already logged in device will be (re)announced.
-+	 */
-+
-+	if (fcp->isp_topo == TOPO_FL_PORT)
-+		base = FC_SNS_ID+1;
-+	else
-+		base = 0;
-+
-+	if (fcp->isp_topo == TOPO_N_PORT)
-+		lim = 1;
-+	else
-+		lim = MAX_FC_TARG;
-+
-+	/*
-+	 * Is it already in our list?
-+	 */
-+	for (target = base; target < lim; target++) {
-+		if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
-+			continue;
-+		}
-+		lp = &fcp->portdb[target];
-+		if (lp->port_wwn == clp->port_wwn &&
-+		    lp->node_wwn == clp->node_wwn) {
-+			lp->fabric_dev = 1;
-+			/*
-+			 * Propagate possibly new port id.
-+			 */
-+			lp->portid = clp->portid;
-+			break;
-+		}
-+	}
-+	if (target < lim) {
-+		break;
-+	}
-+	for (target = base; target < lim; target++) {
-+		if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
-+			continue;
-+		}
-+		lp = &fcp->portdb[target];
-+		if (lp->port_wwn == 0) {
-+			break;
-+		}
-+	}
-+	if (target == lim) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "out of space for fabric devices");
-+		break;
-+	}
-+	lp->port_type = clp->port_type;
-+	lp->fc4_type = clp->fc4_type;
-+	lp->node_wwn = clp->node_wwn;
-+	lp->port_wwn = clp->port_wwn;
-+	lp->portid = clp->portid;
-+	lp->fabric_dev = 1;
-+	break;
-+    }
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    case ISPASYNC_TARGET_MESSAGE:
-+    {
-+	tmd_msg_t *mp = arg;
-+	isp_prt(isp, ISP_LOGTDEBUG2,
-+	    "bus %d iid %d tgt %d lun %d ttype %x tval %x msg[0]=%x",
-+	    mp->nt_bus, (int) mp->nt_iid, (int) mp->nt_tgt, (int) mp->nt_lun,
-+	    mp->nt_tagtype, mp->nt_tagval, mp->nt_msg[0]);
-+	break;
-+    }
-+    case ISPASYNC_TARGET_EVENT:
-+    {
-+	tmd_event_t *ep = arg;
-+	switch (ep->ev_event) {
-+	case  ASYNC_CTIO_DONE:
-+	    /*
-+	     * ACK the interrupt first
-+	     */
-+	    ISP_WRITE(isp, BIU_SEMA, 0);
-+	    ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
-+	    isp_handle_platform_ctio_fastpost(isp, ep->ev_bus);
-+	    break;
-+	default:
-+	    isp_prt(isp, ISP_LOGTDEBUG2,
-+		"bus %d event code 0x%x", ep->ev_bus, ep->ev_event);
-+	}
-+	break;
-+    }
-+    case ISPASYNC_TARGET_ACTION:
-+	switch (((isphdr_t *)arg)->rqs_entry_type) {
-+	default:
-+	    isp_prt(isp, ISP_LOGWARN, "event 0x%x for unhandled target action",
-+		((isphdr_t *)arg)->rqs_entry_type);
-+	    break;
-+	case RQSTYPE_ATIO:
-+	    (void) isp_handle_platform_atio(isp, (at_entry_t *) arg);
-+	    break;
-+	case RQSTYPE_ATIO2:
-+	    (void) isp_handle_platform_atio2(isp, (at2_entry_t *)arg);
-+	    break;
-+	case RQSTYPE_CTIO2:
-+	case RQSTYPE_CTIO:
-+	    (void) isp_handle_platform_ctio(isp, arg);
-+	    break;
-+	case RQSTYPE_ENABLE_LUN:
-+	case RQSTYPE_MODIFY_LUN:
-+	    isp->isp_osinfo.rstatus = ((lun_entry_t *)arg)->le_status;
-+	    if (isp->isp_osinfo.rsemap) {
-+		up(isp->isp_osinfo.rsemap);
-+	    }
-+	    break;
-+	}
-+	break;
-+#endif
-+    case ISPASYNC_UNHANDLED_RESPONSE:
-+	break;
-+    case ISPASYNC_FW_CRASH:
-+    {
-+	u_int16_t mbox1, mbox6;
-+	mbox1 = ISP_READ(isp, OUTMAILBOX1);
-+	if (IS_DUALBUS(isp)) {
-+	    mbox6 = ISP_READ(isp, OUTMAILBOX6);
-+	} else {
-+	    mbox6 = 0;
-+	}
-+	isp_prt(isp, ISP_LOGERR,
-+	    "Internal F/W Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);
-+#ifdef	ISP_FW_CRASH_DUMP
-+	if (IS_FC(isp)) {
-+	    isp->isp_blocked = 1;
-+	    SEND_THREAD_EVENT(isp, ISP_THREAD_FW_CRASH_DUMP, 0);
-+	} else {
-+	    isp_reinit(isp);
-+	    isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-+	}
-+#endif
-+	break;
-+    }
-+    case ISPASYNC_FW_RESTARTED:
-+    {
-+	if (IS_FC(isp)) {
-+	    SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);
-+	}
-+	break;
-+    }
-+    default:
-+	return (-1);
-+    }
-+    return (0);
-+}
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#include "sd.h"
-+int
-+isplinux_biosparam(Disk *disk, kdev_t n, int ip[])
-+{
-+    int size = disk->capacity;
-+    ip[0] = 64;
-+    ip[1] = 32;
-+    ip[2] = size >> 11;
-+    if (ip[2] > 1024) {
-+	ip[0] = 255;
-+	ip[1] = 63;
-+	ip[2] = size / (ip[0] * ip[1]);
-+    }
-+    return (0);
-+}
-+
-+/*
-+ * Set the queue depth for this device.
-+ */
-+
-+void
-+isplinux_sqd(struct Scsi_Host *host, Scsi_Device *devs)
-+{
-+    while (devs) {
-+	if (devs->host == host && devs->tagged_supported == 0) {
-+	    /*
-+	     * If this device doesn't support tagged operations, don't waste
-+	     * queue space for it, even if it has multiple luns.
-+	     */
-+	    devs->queue_depth = 2;
-+	} else if (devs->host == host) {
-+	    int depth = 2;
-+	    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;
-+
-+	    if (IS_SCSI(isp)) {
-+		sdparam *sdp = isp->isp_param;
-+		sdp += devs->channel;
-+		depth = sdp->isp_devparam[devs->id].exc_throttle;
-+	    } else {
-+		depth = FCPARAM(isp)->isp_execthrottle;
-+	    }
-+	    if (isp_throttle) {
-+		/*
-+		 * This limit is due to the size of devs->queue_depth
-+		 */
-+		depth = (unsigned char) min(isp_throttle, 255);;
-+	    }
-+	    if (depth < 4) {
-+		depth = 4;
-+	    }
-+	    devs->queue_depth = depth;
-+	}
-+	devs = devs->next;
-+    }
-+}
-+
-+#else
-+int
-+isplinux_biosparam(struct scsi_device *sdev, struct block_device *n,
-+		   sector_t capacity, int ip[])
-+{
-+    int size = capacity;
-+    ip[0] = 64;
-+    ip[1] = 32;
-+    ip[2] = size >> 11;
-+    if (ip[2] > 1024) {
-+	ip[0] = 255;
-+	ip[1] = 63;
-+	ip[2] = size / (ip[0] * ip[1]);
-+    }
-+    return (0);
-+}
-+
-+static int
-+isplinux_slave_configure(Scsi_Device * device)
-+{
-+    if (device->tagged_supported) {
-+	/*
-+	 *  FIX LATER
-+	 */
-+	scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, 63);
-+    }
-+    return 0;
-+}
-+#endif
-+
-+/*
-+ * Periodic watchdog timer.. the main purpose here is to restart
-+ * commands that were pegged on resources, etc...
-+ */
-+void
-+isplinux_timer(unsigned long arg)
-+{
-+    Scsi_Cmnd *Cmnd;
-+    struct ispsoftc *isp = (struct ispsoftc *) arg;
-+
-+    ISP_ILOCK_SOFTC(isp);
-+    if (IS_FC(isp)) {
-+	int rql;
-+	if (isp->isp_role & ISP_ROLE_INITIATOR)
-+	    rql = LOOP_READY;
-+	else
-+	    rql = LOOP_LSCAN_DONE;
-+	if (isp->isp_fcrswdog || FCPARAM(isp)->isp_fwstate != FW_READY ||
-+	    FCPARAM(isp)->isp_loopstate < rql) {
-+	    isp->isp_fcrswdog = 0;
-+	    if (isp->isp_deadloop == 0 && isp->isp_role != ISP_ROLE_NONE) {
-+		SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);
-+	    }
-+	}
-+    }
-+    isplinux_runwaitq(isp);
-+    if ((Cmnd = isp->isp_osinfo.dqnext) != NULL) {
-+	isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL;
-+    }
-+    if (isp->dogactive) {
-+	isp->isp_osinfo.timer.expires = jiffies + ISP_WATCH_TIME;
-+	add_timer(&isp->isp_osinfo.timer);
-+    }
-+    ISP_IUNLK_SOFTC(isp);
-+    if (Cmnd) {
-+	ISP_LOCK_SCSI_DONE(isp);
-+        while (Cmnd) {
-+	    Scsi_Cmnd *f = (Scsi_Cmnd *) Cmnd->host_scribble;
-+	    Cmnd->host_scribble = NULL;
-+	    /*
-+	     * Get around silliness in midlayer.
-+	     */
-+	    if (host_byte(Cmnd->result) == DID_RESET) {
-+		Cmnd->flags |= IS_RESETTING;
-+	    }
-+	    (*Cmnd->scsi_done)(Cmnd);
-+	    Cmnd = f;
-+	}
-+	ISP_UNLK_SCSI_DONE(isp);
-+    }
-+}
-+
-+void
-+isplinux_mbtimer(unsigned long arg)
-+{
-+    struct ispsoftc *isp = (struct ispsoftc *) arg;
-+    ISP_ILOCK_SOFTC(isp);
-+    if (isp->mbox_waiting) {
-+	isp->mbox_waiting = 0;
-+	up(&isp->mbox_c_sem);
-+    }
-+    ISP_IUNLK_SOFTC(isp);
-+}
-+
-+irqreturn_t
-+isplinux_intr(int irq, void *arg, struct pt_regs *pt)
-+{
-+    struct ispsoftc *isp = arg;
-+    u_int16_t isr, sema, mbox;
-+    Scsi_Cmnd *Cmnd;
-+
-+    ISP_ILOCK_SOFTC(isp);
-+    isp->isp_intcnt++;
-+    if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
-+	isp->isp_intbogus++;
-+	ISP_IUNLK_SOFTC(isp);
-+	return IRQ_NONE;
-+    }
-+    isp_intr(isp, isr, sema, mbox);
-+    isplinux_runwaitq(isp);
-+    if ((Cmnd = isp->isp_osinfo.dqnext) != NULL) {
-+	isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL;
-+    }
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    if (isp->isp_osinfo.pending_t) {
-+	struct tmd_cmd *tmd = isp->isp_osinfo.pending_t;
-+	isp->isp_osinfo.pending_t = NULL;
-+	ISP_IUNLK_SOFTC(isp);
-+	do {
-+	    struct tmd_cmd *next = tmd->cd_lreserved[1].ptrs[0];
-+	    tmd->cd_lreserved[1].ptrs[0] = NULL;
-+	    ISP_PARENT_TARGET(tmd->cd_lreserved[0].bytes[0], tmd);
-+	    tmd = next;
-+	} while (tmd != NULL);
-+    } else {
-+	ISP_IUNLK_SOFTC(isp);
-+    }
-+#else
-+    ISP_IUNLK_SOFTC(isp);
-+#endif
-+    if (Cmnd) {
-+	ISP_LOCK_SCSI_DONE(isp);
-+        while (Cmnd) {
-+	    Scsi_Cmnd *f = (Scsi_Cmnd *) Cmnd->host_scribble;
-+	    Cmnd->host_scribble = NULL;
-+	    /*
-+	     * Get around silliness in midlayer.
-+	     */
-+	    if (host_byte(Cmnd->result) == DID_RESET) {
-+		Cmnd->flags |= IS_RESETTING;
-+	    }
-+	    (*Cmnd->scsi_done)(Cmnd);
-+	    Cmnd = f;
-+	}
-+	ISP_UNLK_SCSI_DONE(isp);
-+    }
-+    return IRQ_HANDLED;
-+}
-+
-+static INLINE int
-+isp_parse_rolearg(struct ispsoftc *isp, char *roles)
-+{
-+    char *role = roles;
-+
-+    while (role && *role) {
-+	unsigned int id;
-+	char *eqtok, *commatok, *p, *q;
-+	
-+	eqtok = role;
-+	eqtok = strchr(role, '=');
-+	if (eqtok == NULL)
-+	   break;
-+	*eqtok = 0;
-+	commatok = strchr(eqtok+1, ',');
-+	if (commatok)
-+	    *commatok = 0;
-+	if (strncmp(role, "0x", 2) == 0)
-+	    q = role + 2;
-+	else
-+	    q = role;
-+	if (*q == '*')
-+	    id = isp->isp_osinfo.device_id;
-+	else
-+	    id = simple_strtoul(q, &p, 16);
-+	*eqtok = '=';
-+	if (p != q && id == isp->isp_osinfo.device_id) {
-+	    p = eqtok + 1;
-+	    if (strcmp(p, "none") == 0) {
-+		if (commatok) {
-+		    *commatok = ',';
-+		}
-+		return (ISP_ROLE_NONE);
-+	    }
-+	    if (strcmp(p, "target") == 0) {
-+		if (commatok) {
-+		    *commatok = ',';
-+		}
-+		return (ISP_ROLE_TARGET);
-+	    }
-+	    if (strcmp(p, "initiator") == 0) {
-+		if (commatok) {
-+		    *commatok = ',';
-+		}
-+		return (ISP_ROLE_INITIATOR);
-+	    }
-+	    if (strcmp(p, "both") == 0) {
-+		if (commatok) {
-+		    *commatok = ',';
-+		}
-+		return (ISP_ROLE_BOTH);
-+	    }
-+	    break;
-+	}
-+        if (commatok) {
-+	    role = commatok+1;
-+	    *commatok = ',';
-+	} else {
-+	    break;
-+	}
-+    }
-+    return (ISP_DEFAULT_ROLES);
-+}
-+
-+static INLINE u_int64_t
-+isp_parse_wwnarg(struct ispsoftc *isp, char *wwns)
-+{
-+    char *wwnt = wwns;
-+    u_int64_t wwn = 0;
-+
-+    while (wwn == 0 && wwnt && *wwnt) {
-+	unsigned int id;
-+	char *eqtok, *commatok, *p, *q;
-+	
-+	eqtok = wwnt;
-+	eqtok = strchr(wwnt, '=');
-+	if (eqtok == NULL)
-+	   break;
-+	*eqtok = 0;
-+	commatok = strchr(eqtok+1, ',');
-+	if (commatok)
-+	    *commatok = 0;
-+	if (strncmp(wwnt, "0x", 2) == 0)
-+	    q = wwnt + 2;
-+	else
-+	    q = wwnt;
-+	id = simple_strtoul(q, &p, 16);
-+	if (p != q && id == isp->isp_osinfo.device_id) {
-+	    unsigned long t, t2;
-+	    p = eqtok + 1;
-+	    while (*p) {
-+		p++;
-+	    }
-+	    p -= 8;
-+	    if (p > eqtok + 1) {
-+		char *q;
-+		char c;
-+		q = p;
-+		t = simple_strtoul(p, &q, 16);
-+		c = *p;
-+		*p = 0;
-+		t2 = simple_strtoul(eqtok+1, NULL, 16);
-+		*p = c;
-+	    } else {
-+		t = simple_strtoul(eqtok+1, NULL, 16);
-+		t2 = 0;
-+	    }
-+	    wwn = (((u_int64_t) t2) << 32) | (u_int64_t) t;
-+	}
-+	*eqtok = '=';
-+        if (commatok) {
-+	    wwnt = commatok+1;
-+	    *commatok = ',';
-+	} else {
-+	    break;
-+	}
-+    }
-+    return (wwn);
-+}
-+
-+void
-+isplinux_common_init(struct ispsoftc *isp)
-+{
-+    /*
-+     * Set up config options, etc...
-+     */
-+    if (isp_debug) {
-+	isp->isp_dblev = isp_debug;
-+    } else {
-+	isp->isp_dblev = ISP_LOGCONFIG|ISP_LOGWARN|ISP_LOGERR;
-+    }
-+
-+    if (isp_nofwreload & (1 << isp->isp_unit)) {
-+	isp->isp_confopts |= ISP_CFG_NORELOAD;
-+    }
-+    if (isp_nonvram & (1 << isp->isp_unit)) {
-+	isp->isp_confopts |= ISP_CFG_NONVRAM;
-+    }
-+    if (IS_FC(isp)) {
-+	if (isp_fcduplex & (1 << isp->isp_unit)) {
-+	    isp->isp_confopts |= ISP_CFG_FULL_DUPLEX;
-+	}
-+        isp->isp_defwwpn = isp_parse_wwnarg(isp, isp_wwpns);
-+	if (isp->isp_defwwpn == 0) {
-+	    isp->isp_defwwpn = (u_int64_t) 0x400000007F7F7F01;
-+	} else {
-+	    isp->isp_confopts |= ISP_CFG_OWNWWPN;
-+	}
-+        isp->isp_defwwnn = isp_parse_wwnarg(isp, isp_wwnns);
-+	if (isp->isp_defwwnn == 0) {
-+	    isp->isp_defwwnn = (u_int64_t) 0x400000007F7F7F02;
-+	} else {
-+	    isp->isp_confopts |= ISP_CFG_OWNWWNN;
-+	}
-+	isp->isp_osinfo.host->max_id = MAX_FC_TARG; 
-+	if (IS_2200(isp) || IS_2300(isp)) {
-+	    if (isp_nport_only & (1 << isp->isp_unit)) {
-+		isp->isp_confopts |= ISP_CFG_NPORT_ONLY;
-+	    } else if (isp_loop_only & (1 << isp->isp_unit)) {
-+		isp->isp_confopts |= ISP_CFG_LPORT_ONLY;
-+	    } else {
-+		isp->isp_confopts |= ISP_CFG_NPORT;
-+	    }
-+	}
-+	isp->isp_osinfo.host->this_id = MAX_FC_TARG+1;
-+#ifdef	ISP_FW_CRASH_DUMP
-+	if (IS_2200(isp))
-+	    FCPARAM(isp)->isp_dump_data =
-+		isp_kalloc(QLA2200_RISC_IMAGE_DUMP_SIZE, GFP_KERNEL);
-+	else if (IS_23XX(isp))
-+	    FCPARAM(isp)->isp_dump_data =
-+		isp_kalloc(QLA2300_RISC_IMAGE_DUMP_SIZE, GFP_KERNEL);
-+	if (FCPARAM(isp)->isp_dump_data) {
-+	    isp_prt(isp, ISP_LOGCONFIG, "f/w crash dump area allocated");
-+	    FCPARAM(isp)->isp_dump_data[0] = 0;
-+	}
-+#endif
-+	if (isp_default_frame_size) {
-+	    if (isp_default_frame_size != 512 &&
-+		isp_default_frame_size != 1024 &&
-+		isp_default_frame_size != 2048) {
-+		    isp_prt(isp, ISP_LOGERR,
-+			"bad frame size (%d), defaulting to (%d)",
-+			isp_default_frame_size, ICB_DFLT_FRMLEN);
-+		isp_default_frame_size = 0;
-+	    }
-+	}
-+	if (isp_default_frame_size) {
-+	    isp->isp_confopts |= ISP_CFG_OWNFSZ;
-+	    isp->isp_osinfo.storep->fibre_scsi.default_frame_size =
-+		isp_default_frame_size;
-+	} else {
-+	    isp->isp_osinfo.storep->fibre_scsi.default_frame_size =
-+		isp_default_frame_size = ICB_DFLT_FRMLEN;
-+	}
-+	if (isp_default_exec_throttle) {
-+	    if (isp_default_exec_throttle < 16 ||
-+		isp_default_exec_throttle > 255) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "bad execution throttle size (%d), defaulting to (%d)",
-+		    isp_default_exec_throttle, ICB_DFLT_THROTTLE);
-+		isp_default_exec_throttle = 0;
-+	    }
-+	}
-+	if (isp_default_exec_throttle) {
-+	    isp->isp_confopts |= ISP_CFG_OWNEXCTHROTTLE;
-+	    isp->isp_osinfo.storep->fibre_scsi.default_exec_throttle =
-+		isp_default_exec_throttle;
-+	} else {
-+	    isp->isp_osinfo.storep->fibre_scsi.default_exec_throttle =
-+		ICB_DFLT_THROTTLE;
-+	}
-+    } else {
-+	isp->isp_osinfo.host->max_id = MAX_TARGETS;
-+	isp->isp_osinfo.host->this_id = 7;	/* temp default */
-+    }
-+    isp->isp_role = isp_parse_rolearg(isp, isp_roles);
-+
-+
-+    /*
-+     * Initialize locks
-+     */
-+    ISP_LOCK_INIT(isp);
-+    ISP_TLOCK_INIT(isp);
-+    sema_init(&isp->mbox_sem, 1);
-+    sema_init(&isp->mbox_c_sem, 0);
-+    sema_init(&isp->fcs_sem, 1);
-+
-+#if defined(CONFIG_PROC_FS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    /*
-+     * Initialize any PROCFS stuff
-+     */
-+    isplinux_init_proc(isp);
-+#endif
-+
-+    /*
-+     * Start watchdog timer
-+     */
-+    ISP_LOCK_SOFTC(isp);
-+    init_timer(&isp->isp_osinfo.timer);
-+    isp->isp_osinfo.timer.data = (unsigned long) isp;
-+    isp->isp_osinfo.timer.function = isplinux_timer;
-+    isp->isp_osinfo.timer.expires = jiffies + ISP_WATCH_TIME;
-+    add_timer(&isp->isp_osinfo.timer);
-+    isp->dogactive = 1;
-+    if (IS_FC(isp)) {
-+	DECLARE_MUTEX_LOCKED(sem);
-+	ISP_UNLK_SOFTC(isp);
-+	isp->isp_osinfo.task_ctl_sem = &sem;
-+	kernel_thread(isp_task_thread, isp, 0);
-+	down(&sem);
-+	isp->isp_osinfo.task_ctl_sem = NULL;
-+	ISP_LOCK_SOFTC(isp);
-+    }
-+    isplinux_reinit(isp);
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    sema_init(&isp->isp_osinfo.tgt_inisem, 1);
-+#endif
-+#ifdef	ISP_TARGET_MODE
-+    isp_attach_target(isp);
-+#endif
-+    ISP_UNLK_SOFTC(isp);
-+}
-+
-+void
-+isplinux_reinit(struct ispsoftc *isp)
-+{
-+    int maxluns = isp_maxluns;
-+    isp_reset(isp);
-+    if (isp->isp_state != ISP_RESETSTATE) {
-+	isp_prt(isp, ISP_LOGERR, "failed to enter RESET state");
-+	return;
-+    } 
-+    /*
-+     * Until the midlayer starts using REPORT LUNS to dertermine how many
-+     * luns there are for SCSI-3 devices and sets a reasonable limit for
-+     * SCSI-2 devices, we'll follow this ruleset:
-+     * 
-+     * 	If our isp_maxluns parameter is unchanged from its default, we
-+     * 	limit ourselves to 8 luns for parallel SCSI, 256 for FC-SCSI.
-+     *
-+     * 	If somebody has set isp_maxluns away from the fefault, we follow that.
-+     *
-+     * 	We filter any value through the HBA maximum
-+     */
-+    if (isp_maxluns == 8) {
-+	if (IS_FC(isp)) {
-+		maxluns = 256;
-+	}
-+    }
-+    isp->isp_osinfo.host->max_lun = min(maxluns, ISP_MAX_LUNS(isp));
-+    isp_init(isp);
-+    if (isp->isp_role == ISP_ROLE_NONE) {
-+	return;
-+    }
-+    if (isp->isp_state != ISP_INITSTATE) {
-+	isp_prt(isp, ISP_LOGERR, "failed to enter INIT state");
-+	return;
-+    }
-+    isp->isp_state = ISP_RUNSTATE;
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    isp->isp_osinfo.host->can_queue = isp->isp_maxcmds;
-+#else
-+    isp->isp_osinfo.host->can_queue = min(255, isp->isp_maxcmds);
-+#endif
-+    if (isp->isp_osinfo.host->can_queue == 0)
-+	isp->isp_osinfo.host->can_queue = 1;
-+
-+    if (IS_FC(isp)) {
-+	isp->isp_osinfo.host->this_id = MAX_FC_TARG;
-+	/*
-+	 * This is *not* the same as execution throttle- that is set
-+	 * in isplinux_sqd and is per-device.
-+	 *
-+	 * What we try and do here is take how much we can queue at
-+	 * a given time and spread it, reasonably, over all the luns
-+	 * we expect to run at a time.
-+	 */
-+	if (isp_cmd_per_lun) {
-+	    isp->isp_osinfo.host->cmd_per_lun = isp_cmd_per_lun;
-+	} else {
-+	    /*
-+	     * JAWAG.
-+	     */
-+	    isp->isp_osinfo.host->cmd_per_lun = isp->isp_maxcmds >> 3;
-+	}
-+
-+	/*
-+	 * We seem to need a bit of settle time.
-+	 */
-+	USEC_DELAY(1 * 1000000);
-+    } else {
-+	int bus;
-+
-+	if (isp_cmd_per_lun) {
-+	    isp->isp_osinfo.host->cmd_per_lun = isp_cmd_per_lun;
-+	} else {
-+	    /*
-+	     * Maximum total commands spread over either 8 targets,
-+	     * or 4 targets, 2 luns, etc.
-+	     */
-+	    isp->isp_osinfo.host->cmd_per_lun = isp->isp_maxcmds >> 3;
-+	}
-+
-+	/*
-+	 * No way to give different ID's for the second bus.
-+	 */
-+	isp->isp_osinfo.host->this_id = SDPARAM(isp)->isp_initiator_id;
-+	bus = 0;
-+	(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
-+	if (IS_DUALBUS(isp)) {
-+	    bus = 1;
-+	    (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
-+	}
-+	/*
-+	 * Bus Reset delay handled by firmware.
-+	 */
-+    }
-+}
-+
-+int
-+isp_drain_reset(struct ispsoftc *isp, char *msg)
-+{
-+    isp->isp_blocked = 1;
-+    /*
-+     * Drain active commands.
-+     */
-+    if (isp_drain(isp, msg)) {
-+	isp->isp_failed = 1;
-+	isp->isp_blocked = 0;
-+	return (-1);
-+    }
-+    isp_reinit(isp);
-+    if ((isp->isp_role == ISP_ROLE_NONE && isp->isp_state < ISP_RESETSTATE) ||
-+        (isp->isp_role != ISP_ROLE_NONE && isp->isp_state < ISP_RUNSTATE)) {
-+	isp->isp_blocked = 0;
-+	return (-1);
-+    }
-+    isp->isp_failed = 0;
-+    isp->isp_blocked = 0;
-+    return (0);
-+}
-+
-+int
-+isp_drain(struct ispsoftc *isp, char *whom)
-+{
-+    int nslept;
-+
-+    if (isp->isp_nactive == 0)
-+	return (0);
-+
-+    isp->isp_draining = 1;
-+    nslept = 0;
-+    isp_prt(isp, ISP_LOGDEBUG0, "draining %d commands", isp->isp_nactive);
-+    while (isp->isp_nactive) {
-+        USEC_SLEEP(isp, 100000);	/* drops lock */
-+	if (++nslept >= (60 * 10)) {	/* 60 seconds */
-+		isp_prt(isp, ISP_LOGERR, "%s: command drain timed out", whom);
-+		isp->isp_draining = 0;
-+		return (-1);
-+	}
-+    }
-+    isp_prt(isp, ISP_LOGDEBUG0, "done draining commands");
-+    isp->isp_draining = 0;
-+    isplinux_runwaitq(isp);
-+    return (0);
-+}
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#define	ISP_THREAD_CAN_EXIT	isp->isp_host->loaded_as_module
-+#else
-+#define	ISP_THREAD_CAN_EXIT	0
-+#endif
-+
-+static int
-+isp_task_thread(void *arg)
-+{
-+    DECLARE_MUTEX_LOCKED(thread_sleep_semaphore);
-+    struct ispsoftc *isp = arg;
-+    unsigned long flags;
-+    int action, nactions, exit_thread = 0;
-+    isp_thread_action_t curactions[MAX_THREAD_ACTION];
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+    /* XXX: Not really sure why the 2.5.X changes do this */
-+    if (ISP_THREAD_CAN_EXIT) {
-+	siginitsetinv(&current->blocked, sigmask(SIGHUP));
-+    } else {
-+	siginitsetinv(&current->blocked, 0);
-+    }
-+    lock_kernel();
-+    daemonize();
-+    sprintf(current->comm, "isp_thrd%d", isp->isp_unit);
-+#else
-+    lock_kernel();
-+    daemonize("isp_thrd%d", isp->isp_unit);
-+#endif
-+    isp->isp_osinfo.task_thread = current;
-+    isp->isp_osinfo.task_request = &thread_sleep_semaphore;
-+    unlock_kernel();
-+
-+    if (isp->isp_osinfo.task_ctl_sem) {
-+	up(isp->isp_osinfo.task_ctl_sem);
-+    }
-+    isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread starting");
-+
-+    while (exit_thread == 0) {
-+	isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread sleeping");
-+	down_interruptible(&thread_sleep_semaphore);
-+	if (ISP_THREAD_CAN_EXIT) {
-+	    if (signal_pending(current))
-+		break;
-+	}
-+	isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread running");
-+
-+	spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
-+	nactions = isp->isp_osinfo.nt_actions;
-+	isp->isp_osinfo.nt_actions = 0;
-+	for (action = 0; action < nactions; action++) {
-+		curactions[action] = isp->isp_osinfo.t_actions[action];
-+		isp->isp_osinfo.t_actions[action].thread_action = 0;
-+		isp->isp_osinfo.t_actions[action].thread_waiter = 0;
-+	}
-+	spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
-+
-+	for (action = 0; action < nactions; action++) {
-+	    isp_thread_action_t *tap = &curactions[action];
-+	    isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread[%d]: action %d (%p)",
-+		action, tap->thread_action, tap->thread_waiter);
-+	    switch (tap->thread_action) {
-+	    case ISP_THREAD_NIL:
-+		break;
-+#ifdef	ISP_FW_CRASH_DUMP
-+	    case ISP_THREAD_FW_CRASH_DUMP:
-+		ISP_LOCKU_SOFTC(isp);
-+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
-+		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
-+		isp_fw_dump(isp);
-+		SEND_THREAD_EVENT(isp, ISP_THREAD_REINIT, 0);
-+		ISP_UNLKU_SOFTC(isp);
-+		break;
-+#endif
-+	    case ISP_THREAD_REINIT:
-+	    {
-+		int level;
-+		ISP_LOCKU_SOFTC(isp);
-+		level = (isp->isp_role == ISP_ROLE_NONE)?
-+		    ISP_RESETSTATE : ISP_INITSTATE;
-+		isp_reinit(isp);
-+		if (isp->isp_state >= level) {
-+		    isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-+		} else {
-+		    SEND_THREAD_EVENT(isp, ISP_THREAD_REINIT, 0);
-+		}
-+		ISP_UNLKU_SOFTC(isp);
-+		break;
-+	    }
-+	    case ISP_THREAD_FC_RESCAN:
-+		ISP_LOCKU_SOFTC(isp);
-+		if (isp_fc_runstate(isp, 250000) == 0) {
-+		    isp->isp_deadloop = 0;
-+		    isp->isp_downcnt = 0;
-+		    isp->isp_fcrspend = 0;
-+	    	    isp->isp_blocked = 0;
-+		    isplinux_runwaitq(isp);
-+		} else {
-+		    /*
-+		     * Try again in a little while.
-+		     */
-+		    isp->isp_fcrspend = 0;
-+		    if (++isp->isp_downcnt == isp_deadloop_time) {
-+			isp_prt(isp, ISP_LOGWARN, "assuming loop is dead");
-+			FCPARAM(isp)->loop_seen_once = 0;
-+			isp->isp_deadloop = 1;
-+			isp->isp_downcnt = 0;
-+			isp->isp_blocked = 0;	/* unblock anyway */
-+			isplinux_flushwaitq(isp);
-+		    } else {
-+			isp->isp_fcrswdog = 1;
-+		    }
-+		}
-+		ISP_UNLKU_SOFTC(isp);
-+		break;
-+	    case ISP_THREAD_EXIT:
-+		if (ISP_THREAD_CAN_EXIT) {
-+		    exit_thread = 1;
-+		}
-+		break;
-+	   default:
-+		break;
-+	   }
-+	   if (tap->thread_waiter) {
-+		isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread signalling %p",
-+		    tap->thread_waiter);
-+		up(tap->thread_waiter);
-+	   }
-+	}
-+    }
-+    isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread exiting");
-+    isp->isp_osinfo.task_request = NULL;
-+    return (0);
-+}
-+
-+void
-+isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
-+{
-+    char buf[256];
-+    char *prefl;
-+    va_list ap;
-+
-+    if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
-+	return;
-+    }
-+    if (level & ISP_LOGERR) {
-+	prefl = KERN_ERR "%s: ";
-+    } else if (level & ISP_LOGWARN) {
-+	prefl = KERN_WARNING "%s: ";
-+    } else if (level & ISP_LOGINFO) {
-+	prefl = KERN_NOTICE "%s: ";
-+    } else if (level & ISP_LOGCONFIG) {
-+	prefl = KERN_INFO "%s: ";
-+    } else {
-+	prefl = "%s: ";
-+    }
-+    printk(prefl, isp->isp_name);
-+    va_start(ap, fmt);
-+    vsprintf(buf, fmt, ap);
-+    va_end(ap);
-+    printk("%s\n", buf);
-+}
-+
-+char *
-+isp_snprintf(char *buf, size_t amt, const char *fmt, ...)
-+{
-+    va_list ap;
-+    ARGSUSED(amt);
-+    va_start(ap, fmt);
-+    (void) vsprintf(buf, fmt, ap);
-+    va_end(ap);
-+    return (buf);
-+}
-+
-+#ifdef MODULE
-+#ifndef	ISP_LICENSE
-+#define	ISP_LICENSE	"Dual BSD/GPL"
-+#endif
-+#ifdef	MODULE_LICENSE
-+MODULE_LICENSE( ISP_LICENSE );
-+#endif
-+MODULE_PARM(isp_debug, "i");
-+MODULE_PARM(isp_disable, "i");
-+MODULE_PARM(isp_nonvram, "i");
-+MODULE_PARM(isp_nofwreload, "i");
-+MODULE_PARM(isp_maxluns, "i");
-+MODULE_PARM(isp_throttle, "i");
-+MODULE_PARM(isp_cmd_per_lun, "i");
-+MODULE_PARM(isp_roles, "s");
-+MODULE_PARM(isp_fcduplex, "i");
-+MODULE_PARM(isp_wwpns, "s");
-+MODULE_PARM(isp_wwnns, "s");
-+MODULE_PARM(isp_nport_only, "i");
-+MODULE_PARM(isp_loop_only, "i");
-+MODULE_PARM(isp_deadloop_time, "i");
-+MODULE_PARM(isp_xtime, "i");
-+MODULE_PARM(isp_default_frame_size, "i");
-+MODULE_PARM(isp_default_exec_throttle, "i");
-+#endif
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,3,27)
-+struct proc_dir_entry proc_scsi_qlc = {
-+    PROC_SCSI_QLOGICISP, 3, "isp", S_IFDIR | S_IRUGO | S_IXUGO, 2
-+};
-+#endif
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) || defined(MODULE)
-+Scsi_Host_Template driver_template = QLOGICISP;
-+#include "scsi_module.c"
-+#endif
-+/*
-+ * mode: c
-+ * Local variables:
-+ * c-indent-level: 4
-+ * c-brace-imaginary-offset: 0
-+ * c-brace-offset: -4
-+ * c-argdecl-indent: 4
-+ * c-label-offset: -4
-+ * c-continued-statement-offset: 4
-+ * c-continued-brace-offset: 0
-+ * End:
-+ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_linux.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,1035 @@
-+/* @(#)isp_linux.h 1.51 */
-+/*
-+ * Qlogic ISP SCSI Host Adapter Linux Wrapper Definitions
-+ *---------------------------------------
-+ * Copyright (c) 1998, 1999, 2000, 2001 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification, immediately at the beginning of the file.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * Alternatively, this software may be distributed under the terms of the
-+ * the GNU Public License ("GPL").
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * 
-+ * Matthew Jacob
-+ * Feral Software
-+ * PMB #825
-+ * 5214-F Diamond Hts Blvd
-+ * San Francisco, CA, 94131
-+ * mjacob@feral.com
-+ */
-+
-+#ifndef _ISP_LINUX_H
-+#define _ISP_LINUX_H
-+
-+#include <linux/vmalloc.h>
-+
-+#ifndef	ISP_MODULE
-+#define	__NO_VERSION__
-+#endif
-+#ifdef	LINUX_ISP_TARGET_MODE
-+#define	EXPORT_SYMTAB
-+#endif
-+
-+#include <linux/version.h>
-+#ifndef	KERNEL_VERSION
-+#define KERNEL_VERSION(v,p,s)		(((v)<<16)+(p<<8)+s)
-+#endif
-+#define	_KVC	KERNEL_VERSION
-+
-+#if LINUX_VERSION_CODE <= _KVC(2,2,0)
-+#error	"Linux 2.0 and 2.1 kernels are not supported anymore"
-+#endif
-+#if LINUX_VERSION_CODE >= _KVC(2,3,0) && LINUX_VERSION_CODE < _KVC(2,4,0)
-+#error	"Linux 2.3 kernels are not supported"
-+#endif
-+
-+#ifndef	UNUSED_PARAMETER
-+#define	UNUSED_PARAMETER(x)	(void) x
-+#endif
-+
-+#include <linux/autoconf.h>
-+#ifdef	CONFIG_SMP
-+#define	__SMP__	1
-+#endif
-+
-+#define COPYIN(u, k, n, m) \
-+	copy_from_user((void*)(k), (const void*)(u), (n))
-+#define COPYOUT(k, u, n, m) \
-+	copy_to_user((void*)(u), (const void*)(k), (n))
-+
-+/*
-+ * Be nice and get ourselves out of the way of other drivers.
-+ * Note that if all the other drivers are there, then the only
-+ * thing we'd attach to that they wouldn't would be the obsolete
-+ *  and unavailable 1240 or the 23XX.
-+ */
-+#ifdef	CONFIG_SCSI_QLOGIC_ISP
-+#define	ISP_DISABLE_1020_SUPPORT 1
-+#endif
-+#ifdef	CONFIG_SCSI_QLOGIC_FC
-+#define	ISP_DISABLE_2100_SUPPORT 1
-+#define	ISP_DISABLE_2200_SUPPORT 1
-+#endif
-+#ifdef	CONFIG_SCSI_QLOGIC_1280
-+#define	ISP_DISABLE_1080_SUPPORT 1
-+#define	ISP_DISABLE_12160_SUPPORT 1
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/blk.h>
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+#include <linux/stat.h>
-+#include <linux/pci.h>
-+#include <asm/dma.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+#include <linux/smp.h>
-+#include <linux/spinlock.h>
-+#else
-+#include <asm/spinlock.h>
-+#endif
-+#include <asm/system.h>
-+#include <asm/byteorder.h>
-+#include <linux/interrupt.h>
-+#include "scsi.h"
-+#include "hosts.h"
-+
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,14)
-+#define	DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED
-+#define	__set_current_state(state_value)			\
-+	do { current->state = (state_value); } while (0)
-+static __inline void daemonize(void);
-+static __inline void daemonize(void)
-+{
-+	struct fs_struct *fs;
-+
-+	exit_mm(current);
-+	current->session = 1;
-+	current->pgrp = 1;
-+	current->tty = NULL;
-+	exit_fs(current);	/* current->fs->count--; */
-+	fs = init_task.fs;
-+	current->fs = fs;
-+	atomic_inc(&fs->count);
-+}
-+#endif
-+/*
-+ * These bits and pieces of keeping track of Linux versions
-+ * and some of the various foo items for locking/unlocking
-+ * gratefully borrowed from (amongst others) Doug Ledford
-+ * and Gerard Roudier.
-+ */
-+
-+#define	PWRB(p, o, r)	pci_write_config_byte(p->pci_dev, o, r)
-+#define	PWRW(p, o, r)	pci_write_config_word(p->pci_dev, o, r)
-+#define	PWRL(p, o, r)	pci_write_config_dword(p->pci_dev, o, r)
-+#define	PRDW(p, o, r)	pci_read_config_word(p->pci_dev, o, r)
-+#define	PRDD(p, o, r)	pci_read_config_dword(p->pci_dev, o, r)
-+#define	PRDB(p, o, r)	pci_read_config_byte(p->pci_dev, o, r)
-+
-+#ifndef	bus_dvma_to_mem
-+#if defined (__alpha__)
-+#define bus_dvma_to_mem(p)              ((p) & 0xfffffffful)
-+#else
-+#define bus_dvma_to_mem(p)              (p)
-+#endif
-+#endif
-+
-+#if defined (__powerpc__)
-+#undef	__pa
-+#define	__pa(x)	x
-+#endif
-+#if defined (__i386__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+#undef	__pa
-+#define	__pa(x)	x
-+#endif
-+#if defined (__sparc__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+#undef	__pa
-+#define	__pa(x)	x
-+#endif
-+#if defined (__alpha__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+#undef	__pa
-+#define	__pa(x)	x
-+#endif
-+
-+/*
-+ * Efficiency- get rid of SBus code && tests unless we need them.
-+ */
-+#if	defined(__sparcv9__ ) || defined(__sparc__)
-+#define	ISP_SBUS_SUPPORTED	1
-+#else
-+#define	ISP_SBUS_SUPPORTED	0
-+#endif
-+
-+#define	ISP_PLATFORM_VERSION_MAJOR	2
-+#define	ISP_PLATFORM_VERSION_MINOR	1
-+
-+#ifndef	BIG_ENDIAN
-+#define	BIG_ENDIAN	4321
-+#endif
-+#ifndef	LITTLE_ENDIAN
-+#define	LITTLE_ENDIAN	1234
-+#endif
-+
-+#ifdef	__BIG_ENDIAN
-+#define	BYTE_ORDER	BIG_ENDIAN
-+#endif
-+#ifdef	__LITTLE_ENDIAN
-+#define	BYTE_ORDER	LITTLE_ENDIAN
-+#endif
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+#define	DMA_ADDR_T		unsigned long
-+#define	QLA_SG_C(sg)		sg->length
-+#define	QLA_SG_A(sg)		virt_to_bus(sg->address)
-+#else
-+#define	DMA_ADDR_T		dma_addr_t
-+#define	QLA_SG_C(sg)		sg_dma_len(sg)
-+#define	QLA_SG_A(sg)		sg_dma_address(sg)
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,4,16)
-+#define	DMA_HTYPE_T		char *
-+#define	QLA_HANDLE(cmd)		(cmd)->SCp.ptr
-+#else
-+#define	DMA_HTYPE_T		dma_addr_t
-+#define	QLA_HANDLE(cmd)		(cmd)->SCp.dma_handle
-+#endif
-+#endif
-+
-+#define	HANDLE_LOOPSTATE_IN_OUTER_LAYERS	1
-+#ifdef	min
-+#undef	min
-+#endif
-+#ifdef	max
-+#undef	max
-+#endif
-+
-+
-+/*
-+ * Normally this should be taken care of by typedefs,
-+ * but linux includes are a complete dog's breakfast.
-+ */
-+
-+#define	u_int8_t	unsigned char
-+#define	u_int16_t	unsigned short
-+#define	u_int32_t	unsigned int
-+#if BITS_PER_LONG == 64
-+#define	u_int64_t	unsigned long
-+#else
-+#define	u_int64_t	unsigned long long
-+#endif
-+#define	int8_t		char
-+#define	int16_t		short
-+#define	int32_t		int
-+#define	u_long		unsigned long
-+#define	u_int		unsigned int
-+#define	u_char		unsigned char
-+typedef u_long vm_offset_t;
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+#define	DEFAULT_DEVICE_TYPE	3
-+#define	NTGT_CMDS		256
-+
-+#define	_WIX(isp, b, ix)	(((b << 6)) | (ix >> 5))
-+#define	_BIX(isp, ix)		(1 << (ix & 0x1f))
-+
-+#define	LUN_BTST(isp, b, ix)	\
-+	(((isp)->isp_osinfo.lunbmap[_WIX(isp, b, ix)] & _BIX(isp, ix)) != 0)
-+
-+#define	LUN_BSET(isp, b, ix)	\
-+	isp->isp_osinfo.lunbmap[_WIX(isp, b, ix)] |= _BIX(isp, ix)
-+
-+#define	LUN_BCLR(isp, b, ix)	\
-+	isp->isp_osinfo.lunbmap[_WIX(isp, b, ix)] &= ~_BIX(isp, ix)
-+
-+#endif
-+
-+typedef struct {
-+	enum {
-+	    ISP_THREAD_NIL=1,
-+	    ISP_THREAD_FC_RESCAN,
-+	    ISP_THREAD_REINIT,
-+	    ISP_THREAD_FW_CRASH_DUMP,
-+	    ISP_THREAD_EXIT
-+	}			thread_action;
-+	struct semaphore *	thread_waiter;
-+} isp_thread_action_t;
-+#define	MAX_THREAD_ACTION	10
-+
-+union pstore;
-+struct isposinfo {
-+    struct ispsoftc *		isp_next;
-+    struct Scsi_Host *		host;
-+    Scsi_Cmnd			*wqnext, *wqtail;
-+    Scsi_Cmnd			*dqnext, *dqtail;
-+    union pstore		*storep;
-+    char			hbaname[16];
-+    unsigned short		instance;
-+    unsigned short		wqcnt;
-+    unsigned short		wqhiwater;
-+    unsigned short		hiwater;
-+    struct timer_list		timer;
-+    struct timer_list		_mbtimer;
-+    struct semaphore		_mbox_sem;
-+    struct semaphore		_mbox_c_sem;
-+    struct semaphore		_fcs_sem;
-+    spinlock_t			slock;
-+    unsigned volatile int
-+		_downcnt	: 8,
-+				: 15,
-+		_isopen		: 1,
-+		_deadloop	: 1,
-+		_draining	: 1,
-+		_blocked	: 1,
-+		_fcrswdog	: 1,
-+		_fcrspend	: 1,
-+    		_dogactive	: 1,
-+		_mbox_waiting	: 1,
-+    		_mbintsok	: 1;
-+    void *			misc[8]; /* private platform variant usage */
-+    unsigned long		_iflags;
-+    struct task_struct *	task_thread;
-+    struct semaphore *		task_request;
-+    struct semaphore *		task_ctl_sem;
-+    spinlock_t			tlock;
-+    unsigned int		nt_actions;
-+    unsigned int		device_id;
-+    isp_thread_action_t		t_actions[MAX_THREAD_ACTION];
-+#ifdef	LINUX_ISP_TARGET_MODE
-+#define	TM_WANTED		0x08
-+#define	TM_BUSY			0x04
-+#define	TM_TMODE_ENABLED	0x03
-+    u_int32_t		rollinfo	: 16,
-+    			rstatus		: 8,
-+					: 3,
-+			hcb		: 1,
-+			tmflags		: 4;
-+    struct semaphore		tgt_inisem;
-+    struct semaphore *		rsemap;
-+   /*
-+    * This is very inefficient, but is in fact big enough
-+    * to cover a complete bitmap for Fibre Channel, as well
-+    * as the dual bus SCSI cards. This works out without
-+    * overflow easily because the most you can enable
-+    * for the SCSI cards is 64 luns (x 2 busses).
-+    *
-+    * For Fibre Channel, we can run the max luns up to 16384
-+    * but we'll default to the minimum we can support here.
-+    */
-+#define	TM_MAX_LUN_FC		128
-+#define	TM_MAX_LUN_SCSI		64
-+    u_int32_t			lunbmap[TM_MAX_LUN_FC >> 5];
-+    struct tmd_cmd *		pending_t;
-+    struct tmd_cmd *		tfreelist;
-+    struct tmd_cmd *		pool;
-+#endif
-+};
-+#define	mbtimer		isp_osinfo._mbtimer
-+#define	dogactive	isp_osinfo._dogactive
-+#define	mbox_sem	isp_osinfo._mbox_sem
-+#define	mbox_c_sem	isp_osinfo._mbox_c_sem
-+#define	fcs_sem		isp_osinfo._fcs_sem
-+#define	mbintsok	isp_osinfo._mbintsok
-+#define	mbox_waiting	isp_osinfo._mbox_waiting
-+#define	isp_pbuf	isp_osinfo._pbuf
-+#define	isp_fcrspend	isp_osinfo._fcrspend
-+#define	isp_fcrswdog	isp_osinfo._fcrswdog
-+#define	isp_blocked	isp_osinfo._blocked
-+#define	isp_draining	isp_osinfo._draining
-+#define	isp_downcnt	isp_osinfo._downcnt
-+#define	isp_isopen	isp_osinfo._isopen
-+#define	isp_deadloop	isp_osinfo._deadloop
-+
-+#define	iflags		isp_osinfo._iflags
-+
-+#define	SEND_THREAD_EVENT(isp, action, dowait)				\
-+if (isp->isp_osinfo.task_request) {					\
-+    unsigned long flags;						\
-+    spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);			\
-+    if (isp->isp_osinfo.nt_actions >= MAX_THREAD_ACTION) {		\
-+	spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);		\
-+	isp_prt(isp, ISP_LOGERR, "thread event overflow");		\
-+    } else if (action == ISP_THREAD_FC_RESCAN && isp->isp_fcrspend) {	\
-+	spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);		\
-+    } else {								\
-+	DECLARE_MUTEX_LOCKED(sem);					\
-+	isp_thread_action_t *tap;					\
-+	tap = &isp->isp_osinfo.t_actions[isp->isp_osinfo.nt_actions++];	\
-+	tap->thread_action = action;					\
-+	if (dowait)							\
-+	    tap->thread_waiter = &sem;					\
-+	else								\
-+	    tap->thread_waiter = 0;					\
-+	if (action == ISP_THREAD_FC_RESCAN)				\
-+	    isp->isp_fcrspend = 1;					\
-+	up(isp->isp_osinfo.task_request);				\
-+	spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);		\
-+	if (dowait) {							\
-+	    down(&sem);							\
-+	    isp_prt(isp, ISP_LOGDEBUG1,					\
-+		"action %d done from %p", action, &sem);		\
-+	} else {							\
-+	    isp_prt(isp, ISP_LOGDEBUG1,					\
-+		"action %d sent", action);				\
-+	}								\
-+    }									\
-+}
-+
-+/*
-+ * Locking macros...
-+ */
-+#define	ISP_LOCK_INIT(isp)		spin_lock_init(&isp->isp_osinfo.slock)
-+#define	ISP_LOCK_SOFTC(isp)		{				\
-+		unsigned long _flags;					\
-+		spin_lock_irqsave(&isp->isp_osinfo.slock, _flags);	\
-+		isp->iflags = _flags;					\
-+	}
-+#define	ISP_UNLK_SOFTC(isp)		{				\
-+		unsigned long _flags = isp->iflags;			\
-+		spin_unlock_irqrestore(&isp->isp_osinfo.slock, _flags);	\
-+	}
-+
-+#define	ISP_ILOCK_SOFTC			ISP_LOCK_SOFTC
-+#define	ISP_IUNLK_SOFTC			ISP_UNLK_SOFTC
-+#define	ISP_IGET_LK_SOFTC		ISP_LOCK_SOFTC
-+#define	ISP_DROP_LK_SOFTC		ISP_UNLK_SOFTC
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+#define	ISP_LOCK_SCSI_DONE(isp)		{				\
-+		unsigned long _flags;					\
-+		spin_lock_irqsave(&io_request_lock, _flags);		\
-+		isp->iflags = _flags;					\
-+	}
-+#define	ISP_UNLK_SCSI_DONE(isp)		{				\
-+		unsigned long _flags = isp->iflags;			\
-+		spin_unlock_irqrestore(&io_request_lock, _flags);	\
-+	}
-+#else
-+#define	ISP_LOCK_SCSI_DONE(isp)		do { } while(0)
-+#define	ISP_UNLK_SCSI_DONE(isp)		do { } while(0)
-+#endif
-+#define	ISP_LOCKU_SOFTC			ISP_ILOCK_SOFTC
-+#define	ISP_UNLKU_SOFTC			ISP_IUNLK_SOFTC
-+#define	ISP_TLOCK_INIT(isp)		spin_lock_init(&isp->isp_osinfo.tlock)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#define	ISP_DRIVER_ENTRY_LOCK(isp)	spin_unlock_irq(&io_request_lock)
-+#define	ISP_DRIVER_EXIT_LOCK(isp)	spin_lock_irq(&io_request_lock)
-+#else
-+#define	ISP_DRIVER_ENTRY_LOCK(isp)	\
-+	spin_unlock_irq(isp->isp_osinfo.host->host_lock)
-+#define	ISP_DRIVER_EXIT_LOCK(isp)	\
-+	spin_lock_irq(isp->isp_osinfo.host->host_lock)
-+#endif
-+
-+#define	ISP_MUST_POLL(isp)	(in_interrupt() || isp->mbintsok == 0)
-+/*
-+ * Misc SCSI defines
-+ */
-+#define	MSG_SIMPLE_Q_TAG	0x21
-+#define	MSG_HEAD_OF_Q_TAG	0x22
-+#define	MSG_ORDERED_Q_TAG	0x23
-+
-+/*
-+ * Required Macros/Defines
-+ */
-+
-+#define	INLINE			__inline
-+
-+#if	LINUX_VERSION_CODE > KERNEL_VERSION(2,4,18) && \
-+    defined(CONFIG_HIGHMEM64G) && !defined(LINUX_ISP_TARGET_MODE)
-+#define	ISP_DAC_SUPPORTED	1
-+#else
-+#define	ISP_DAC_SUPPORTED	0
-+#endif
-+
-+#define	ISP2100_SCRLEN		0x800
-+
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+#define	MEMZERO			_isp_memzero
-+#define	MEMCPY			_isp_memcpy
-+#else
-+#define	MEMZERO(b, a)		memset(b, 0, a)
-+#define	MEMCPY			memcpy
-+#endif
-+#define	SNPRINTF		isp_snprintf
-+#define	USEC_DELAY		_isp_usec_delay
-+#define	USEC_SLEEP(isp, x)						\
-+		ISP_DROP_LK_SOFTC(isp);					\
-+		__set_current_state(TASK_UNINTERRUPTIBLE);		\
-+		(void) schedule_timeout(_usec_to_jiffies(x));		\
-+		ISP_IGET_LK_SOFTC(isp)
-+
-+#define	NANOTIME_T		struct timeval
-+/* for prior to 2.2.19, use do_gettimeofday, and, well, it'll be inaccurate */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
-+#define	GET_NANOTIME(ptr)	\
-+	(ptr)->tv_sec = 0, (ptr)->tv_usec = 0, get_fast_time(ptr)
-+#else
-+#define	GET_NANOTIME(ptr)	\
-+	(ptr)->tv_sec = 0, (ptr)->tv_usec = 0, do_gettimeofday(ptr)
-+#endif
-+#define	GET_NANOSEC(x)		\
-+  ((u_int64_t) ((((u_int64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)))
-+#define	NANOTIME_SUB		_isp_microtime_sub
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+#define	MAXISPREQUEST(isp)	256
-+#else
-+#define	MAXISPREQUEST(isp)	((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
-+#endif
-+
-+#if	defined(__i386__)
-+#define	MEMORYBARRIER(isp, type, offset, size)	barrier()
-+#elif	defined(__alpha__)
-+#define	MEMORYBARRIER(isp, type, offset, size)	mb()
-+#elif	defined(__sparc__)
-+#define	MEMORYBARRIER(isp, type, offset, size)	mb()
-+#elif	defined(__powerpc__)
-+#define	MEMORYBARRIER(isp, type, offset, size)	\
-+	__asm__ __volatile__("eieio" ::: "memory")
-+#else
-+#  ifdef mb
-+#    define	MEMORYBARRIER(isp, type, offset, size)	mb()
-+#  else
-+#    define	MEMORYBARRIER(isp, type, offset, size)	barrier()
-+#  endif
-+#endif
-+
-+#define	MBOX_ACQUIRE(isp)						\
-+	/*								\
-+	 * Try and acquire semaphore the easy way first-		\
-+	 * with our lock already held.					\
-+	 */								\
-+	if (down_trylock(&isp->mbox_sem)) {				\
-+	    if (in_interrupt()) {					\
-+		mbp->param[0] = MBOX_HOST_INTERFACE_ERROR;		\
-+		isp_prt(isp, ISP_LOGERR, "cannot acquire MBOX sema");	\
-+		return;							\
-+	    }								\
-+	    ISP_DROP_LK_SOFTC(isp);					\
-+	    down(&isp->mbox_sem);					\
-+	    ISP_IGET_LK_SOFTC(isp);					\
-+	}
-+
-+#define	MBOX_WAIT_COMPLETE(isp)						\
-+	if (ISP_MUST_POLL(isp)) {					\
-+		int j, lim = 5000000;					\
-+		if (isp->isp_mbxwrk0) {					\
-+			lim *= 12;					\
-+		}							\
-+		for (j = 0; j < 5000000; j += 100) {			\
-+			u_int16_t isr, sema, mbox;			\
-+			if (isp->isp_mboxbsy == 0) {			\
-+				break;					\
-+			}						\
-+			if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {	\
-+				isp_intr(isp, isr, sema, mbox);		\
-+				if (isp->isp_mboxbsy == 0) {		\
-+					break;				\
-+				}					\
-+			}						\
-+			ISP_DROP_LK_SOFTC(isp);				\
-+			udelay(100);					\
-+			ISP_IGET_LK_SOFTC(isp);				\
-+		}							\
-+		if (isp->isp_mboxbsy != 0) {				\
-+			isp_prt(isp, ISP_LOGWARN,			\
-+			    "Polled Mailbox Command (0x%x) Timeout",	\
-+			    isp->isp_lastmbxcmd);			\
-+			isp->isp_mboxbsy = 0;				\
-+		}							\
-+	} else {							\
-+		int lim = (isp->isp_mbxwrk0)? 60 : 5;			\
-+		init_timer(&isp->mbtimer);				\
-+		isp->mbtimer.data = (unsigned long) isp;		\
-+		isp->mbtimer.function = isplinux_mbtimer;		\
-+    		isp->mbtimer.expires = jiffies + (lim * HZ);		\
-+    		add_timer(&isp->mbtimer);				\
-+		isp->mbox_waiting = 1;					\
-+		ISP_DROP_LK_SOFTC(isp);					\
-+		down(&isp->mbox_c_sem);					\
-+		ISP_IGET_LK_SOFTC(isp);					\
-+		isp->mbox_waiting = 0;					\
-+    		del_timer(&isp->mbtimer);				\
-+		if (isp->isp_mboxbsy != 0) {				\
-+			isp_prt(isp, ISP_LOGWARN,			\
-+			    "Interrupting Mailbox Command (0x%x) Timeout",\
-+			    isp->isp_lastmbxcmd);			\
-+			isp->isp_mboxbsy = 0;				\
-+		}							\
-+	}
-+
-+#define	MBOX_NOTIFY_COMPLETE(isp)					\
-+	if (isp->mbox_waiting) {					\
-+		isp->mbox_waiting = 0;					\
-+		up(&isp->mbox_c_sem);					\
-+	}								\
-+	isp->isp_mboxbsy = 0
-+
-+#define	MBOX_RELEASE(isp)	up(&isp->mbox_sem)
-+
-+#define	FC_SCRATCH_ACQUIRE(isp)						\
-+	/*								\
-+	 * Try and acquire semaphore the easy way first-		\
-+	 * with our lock already held.					\
-+	 */								\
-+	if (in_interrupt()) {						\
-+		while (down_trylock(&isp->fcs_sem)) {			\
-+			ISP_DROP_LK_SOFTC(isp);				\
-+			USEC_DELAY(5000);				\
-+			ISP_IGET_LK_SOFTC(isp);				\
-+		}							\
-+	} else {							\
-+	    ISP_DROP_LK_SOFTC(isp);					\
-+	    down(&isp->fcs_sem);					\
-+	    ISP_IGET_LK_SOFTC(isp);					\
-+	}
-+
-+#define	FC_SCRATCH_RELEASE(isp)	up(&isp->fcs_sem)
-+
-+
-+#ifndef	SCSI_GOOD
-+#define	SCSI_GOOD	0x0
-+#endif
-+#ifndef	SCSI_CHECK
-+#define	SCSI_CHECK	0x2
-+#endif
-+#ifndef	SCSI_BUSY
-+#define	SCSI_BUSY	0x8
-+#endif
-+#ifndef	SCSI_QFULL
-+#define	SCSI_QFULL	0x28
-+#endif
-+
-+#define	XS_T			Scsi_Cmnd
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#define	XS_HOST(Cmnd)		Cmnd->device->host
-+#define	XS_ISP(Cmnd)		((struct ispsoftc *) (Cmnd)->host->hostdata)
-+#define	XS_CHANNEL(Cmnd)	(Cmnd)->channel
-+#define	XS_TGT(Cmnd)		(Cmnd)->target
-+#define	XS_LUN(Cmnd)		(Cmnd)->lun
-+#else
-+#define	XS_HOST(Cmnd)		Cmnd->device->host
-+#define	XS_ISP(Cmnd)		\
-+	((struct ispsoftc *) (Cmnd)->device->host->hostdata)
-+#define	XS_CHANNEL(Cmnd)	(Cmnd)->device->channel
-+#define	XS_TGT(Cmnd)		(Cmnd)->device->id
-+#define	XS_LUN(Cmnd)		(Cmnd)->device->lun
-+#endif
-+#define	XS_CDBP(Cmnd)		(Cmnd)->cmnd
-+#define	XS_CDBLEN(Cmnd)		(Cmnd)->cmd_len
-+#define	XS_XFRLEN(Cmnd)		(Cmnd)->request_bufflen
-+#define	XS_TIME(Cmnd)		(Cmnd)->timeout
-+#define	XS_RESID(Cmnd)		(Cmnd)->SCp.this_residual
-+#define	XS_STSP(Cmnd)		(&(Cmnd)->SCp.Status)
-+#define	XS_SNSP(Cmnd)		(Cmnd)->sense_buffer
-+#define	XS_SNSLEN(Cmnd)		(sizeof (Cmnd)->sense_buffer)
-+#define	XS_SNSKEY(Cmnd)		((Cmnd)->sense_buffer[2] & 0xf)
-+#define	XS_TAG_P(Cmnd)		(Cmnd->device->tagged_supported != 0)
-+#define	XS_TAG_TYPE(xs)		REQFLAG_STAG
-+
-+#define	XS_SETERR(xs, v)	\
-+	if ((v) == HBA_TGTBSY) { \
-+		(xs)->SCp.Status = SCSI_BUSY; \
-+	} else { \
-+		(xs)->result &= ~0xff0000; \
-+		(xs)->result |= ((v) << 16); \
-+	}
-+
-+#	define	HBA_NOERROR		DID_OK
-+#	define	HBA_BOTCH		DID_ERROR
-+#	define	HBA_CMDTIMEOUT		DID_TIME_OUT
-+#	define	HBA_SELTIMEOUT		DID_NO_CONNECT
-+#	define	HBA_TGTBSY		123456 /* special handling */
-+#	define	HBA_BUSRESET		DID_RESET
-+#	define	HBA_ABORTED		DID_ABORT
-+#	define	HBA_DATAOVR		DID_ERROR
-+#	define	HBA_ARQFAIL		DID_ERROR
-+
-+#define	XS_ERR(xs)		host_byte((xs)->result)
-+
-+#define	XS_NOERR(xs)		host_byte((xs)->result) == DID_OK
-+
-+#define	XS_INITERR(xs)		(xs)->result = 0, (xs)->SCp.Status = 0
-+
-+#define	XS_SAVE_SENSE(Cmnd, sp)				\
-+	MEMCPY(&Cmnd->sense_buffer, sp->req_sense_data, \
-+	    min(sizeof Cmnd->sense_buffer, sp->req_sense_len))
-+
-+#define	XS_SET_STATE_STAT(a, b, c)
-+
-+#define	DEFAULT_IID(x)		7
-+#define	DEFAULT_LOOPID(x)	111
-+#define	DEFAULT_NODEWWN(isp)	(isp)->isp_defwwnn
-+#define	DEFAULT_PORTWWN(isp)	(isp)->isp_defwwpn
-+#define	DEFAULT_FRAME_SIZE(isp)	\
-+    (IS_SCSI(isp)? 0 : isp->isp_osinfo.storep->fibre_scsi.default_frame_size)
-+#define	DEFAULT_EXEC_ALLOC(isp)	\
-+    (IS_SCSI(isp)? 0 : isp->isp_osinfo.storep->fibre_scsi.default_exec_alloc)
-+#define	ISP_NODEWWN(isp)	(isp)->isp_nvramwwnn
-+#define	ISP_PORTWWN(isp)	(isp)->isp_nvramwwpn
-+
-+#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
-+#define	ISP_IOXPUT_16(isp, s, d)	*(d) = cpu_to_le16(s)
-+#define	ISP_IOXPUT_32(isp, s, d)	*(d) = cpu_to_le32(s)
-+
-+#define	ISP_IOXGET_8(isp, s, d)		d = *(s)
-+#define	ISP_IOXGET_16(isp, s, d)	d = le16_to_cpu(*((u_int16_t *)s))
-+#define	ISP_IOXGET_32(isp, s, d)	d = le32_to_cpu(*((u_int32_t *)s))
-+
-+#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)	*rp = le16_to_cpu(*rp)
-+
-+
-+/*
-+ * Includes of common header files
-+ */
-+#include "ispreg.h"
-+#include "ispvar.h"
-+#include "ispmbox.h"
-+
-+/*
-+ * isp_osinfo definitions, extensions and shorthand.
-+ */
-+
-+/*
-+ * Parameter storage. The order of tags is important- sdparam && fcp
-+ * must come first because isp->isp_params is set to point there...
-+ */
-+union pstore {
-+    struct {
-+	sdparam _sdp[2];	/* they need to be sequential */
-+	u_char psc_opts[2][MAX_TARGETS];
-+	u_char dutydone;
-+    } parallel_scsi;
-+    struct {
-+	fcparam fcp;
-+	u_int64_t wwnn;
-+	u_int64_t wwpn;
-+	u_int64_t nvram_wwnn;
-+	u_int64_t nvram_wwpn;
-+	u_int16_t default_frame_size;
-+	u_int16_t default_exec_throttle;
-+    } fibre_scsi;
-+};
-+#define	isp_next	isp_osinfo.isp_next
-+#define	isp_name	isp_osinfo.hbaname
-+#define	isp_host	isp_osinfo.host
-+#define	isp_unit	isp_osinfo.instance
-+#define	isp_psco	isp_osinfo.storep->parallel_scsi.psc_opts
-+#define	isp_dutydone	isp_osinfo.storep->parallel_scsi.dutydone
-+#define	isp_defwwnn	isp_osinfo.storep->fibre_scsi.wwnn
-+#define	isp_defwwpn	isp_osinfo.storep->fibre_scsi.wwpn
-+#define	isp_nvramwwnn	isp_osinfo.storep->fibre_scsi.nvram_wwnn
-+#define	isp_nvramwwpn	isp_osinfo.storep->fibre_scsi.nvram_wwpn
-+
-+/*
-+ * Driver prototypes..
-+ */
-+void isplinux_timer(unsigned long);
-+void isplinux_mbtimer(unsigned long);
-+irqreturn_t isplinux_intr(int, void *, struct pt_regs *);
-+void isplinux_common_init(struct ispsoftc *);
-+#ifdef	CONFIG_PROC_FS
-+void isplinux_init_proc(struct ispsoftc *);
-+void isplinux_undo_proc(struct ispsoftc *);
-+#endif
-+void isplinux_reinit(struct ispsoftc *);
-+void isplinux_sqd(struct Scsi_Host *, Scsi_Device *);
-+
-+int isp_drain_reset(struct ispsoftc *, char *);
-+int isp_drain(struct ispsoftc *, char *);
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+static INLINE void _isp_memcpy(void *, void *, size_t);
-+static INLINE void _isp_memzero(void *,  size_t);
-+#endif
-+static INLINE u_int64_t _isp_microtime_sub(struct timeval *, struct timeval *);
-+static INLINE void _isp_usec_delay(unsigned int);
-+static INLINE unsigned long _usec_to_jiffies(unsigned int);
-+
-+int isplinux_proc_info(char *, char **, off_t, int, int, int);
-+int isplinux_detect(Scsi_Host_Template *);
-+int isplinux_release(struct Scsi_Host *);
-+#define	ISPLINUX_RELEASE	isplinux_release
-+const char *isplinux_info(struct Scsi_Host *);
-+int isplinux_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+int isplinux_biosparam(Disk *, kdev_t, int[]);
-+#else
-+int isplinux_biosparam(struct scsi_device *, struct block_device *,
-+    sector_t, int[]); 
-+#endif
-+
-+
-+/*
-+ * Driver wide data...
-+ */
-+extern int isp_debug;
-+extern int isp_unit_seed;
-+extern int isp_disable;
-+extern int isp_nofwreload;
-+extern int isp_nonvram;
-+extern int isp_fcduplex;
-+extern struct ispsoftc *isplist;
-+extern const char *class3_roles[4];
-+
-+/*
-+ * Platform private flags
-+ */
-+#ifndef NULL
-+#define NULL ((void *) 0)
-+#endif
-+
-+#define	ISP_WATCH_TIME		HZ
-+
-+#ifndef	min
-+#define min(a,b) (((a)<(b))?(a):(b))
-+#endif
-+#ifndef	max
-+#define	max(a, b)		(((a) > (b)) ? (a) : (b))
-+#endif
-+#ifndef	roundup
-+#define	roundup(x, y)	((((x)+((y)-1))/(y))*(y))
-+#endif
-+#ifndef	ARGSUSED
-+#define	ARGSUSED(x)	x = x
-+#endif
-+
-+
-+
-+
-+/*
-+ * Platform specific 'inline' or support functions
-+ */
-+
-+#ifdef	__sparc__
-+#define	_SBSWAP(isp, b, c)						\
-+	if (isp->isp_bustype == ISP_BT_SBUS) {				\
-+		u_int8_t tmp = b;					\
-+		b = c;							\
-+		c = tmp;						\
-+	}
-+#else
-+#define	_SBSWAP(a, b, c)
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-+static INLINE void
-+_isp_memcpy(void *to, void *from, size_t amt)
-+{
-+	unsigned char *x = to; unsigned char *y = from;
-+	while (amt-- != 0) *x++ = *y++;
-+}
-+
-+static INLINE void
-+_isp_memzero(void *to, size_t amt)
-+{
-+	unsigned char *x = to;
-+	while (amt-- != 0) *x++ = 0;
-+}
-+
-+static INLINE unsigned long IspOrder(int);
-+static INLINE unsigned long
-+IspOrder(int nelem)
-+{
-+    unsigned long order, rsize;
-+
-+    order = 0;
-+    rsize = PAGE_SIZE;
-+    while (rsize < (unsigned long) ISP_QUEUE_SIZE(nelem)) {
-+	order++;
-+	rsize <<= 1;
-+    }
-+    return (order);
-+}
-+#endif
-+
-+static INLINE u_int64_t
-+_isp_microtime_sub(struct timeval *b, struct timeval *a)
-+{
-+	u_int64_t elapsed;
-+	struct timeval x = *b;
-+	x.tv_sec -= a->tv_sec;
-+	x.tv_usec -= a->tv_usec;
-+        if (x.tv_usec < 0) {
-+                x.tv_sec--;
-+                x.tv_usec += 1000000;
-+        }
-+        if (x.tv_usec >= 1000000) {
-+                x.tv_sec++;
-+                x.tv_usec -= 1000000;
-+        }
-+	elapsed = GET_NANOSEC(&x);
-+	if (elapsed == 0)
-+		elapsed++;
-+	if ((int64_t) elapsed < 0)	/* !!!! */
-+		return (1000);
-+	return (elapsed * 1000);
-+}
-+
-+static INLINE void
-+_isp_usec_delay(unsigned int usecs)
-+{
-+    while (usecs > 1000) {
-+	mdelay(1);
-+	usecs -= 1000;
-+    }
-+    if (usecs)
-+	udelay(usecs);
-+}
-+
-+static INLINE unsigned long
-+_usec_to_jiffies(unsigned int usecs)
-+{
-+	struct timespec lt;
-+	if (usecs == 0)
-+		usecs++;
-+	lt.tv_sec = 0;
-+	lt.tv_nsec = usecs * 1000;
-+	return (timespec_to_jiffies(&lt));
-+}
-+
-+#define	GetPages(a)	__get_dma_pages(GFP_ATOMIC|GFP_DMA, a)
-+#define	RlsPages(a, b)	free_pages((unsigned long) a, b)
-+
-+char *isp_snprintf(char *, size_t, const char *, ...);
-+
-+static INLINE void *isp_kalloc(size_t, int);
-+static INLINE void *isp_kzalloc(size_t, int);
-+static INLINE void isp_kfree(void *, size_t);
-+
-+static INLINE void *
-+isp_kalloc(size_t size, int flags)
-+{
-+    void *ptr;
-+    if (size > PAGE_SIZE) {
-+        ptr = vmalloc(size);
-+    } else {
-+        ptr = kmalloc(size, flags);
-+    }
-+    return (ptr);
-+}
-+
-+static INLINE void *
-+isp_kzalloc(size_t size, int flags)
-+{
-+    void *ptr = isp_kalloc(size, flags);
-+    if (ptr != NULL){
-+        memset(ptr, 0, size);
-+    }
-+    return (ptr);
-+}
-+
-+static INLINE void
-+isp_kfree(void *ptr, size_t size)
-+{
-+    if (size > PAGE_SIZE) {
-+        vfree(ptr);
-+    } else {
-+        kfree(ptr);
-+    }
-+}
-+
-+/*
-+ * Common inline functions
-+ */
-+
-+#include "isp_inline.h"
-+
-+#ifdef	ISP_TARGET_MODE
-+void isp_attach_target(ispsoftc_t *);
-+void isp_detach_target(ispsoftc_t *);
-+int isp_target_async(struct ispsoftc *, int, int);
-+int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
-+#endif
-+#ifdef	LINUX_ISP_TARGET_MODE
-+int isp_en_dis_lun(struct ispsoftc *, int, int, int, int);
-+#endif
-+/*
-+ * Config data
-+ */
-+
-+int isplinux_abort(Scsi_Cmnd *);
-+int isplinux_bdr(Scsi_Cmnd *);
-+int isplinux_sreset(Scsi_Cmnd *);
-+int isplinux_hreset(Scsi_Cmnd *);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#define QLOGICISP {							\
-+	next:				NULL,				\
-+	module:				NULL,				\
-+	proc_info:			isplinux_proc_info,		\
-+	name:				"Qlogic ISP 10X0/2X00",		\
-+	detect:				isplinux_detect,		\
-+	release:			ISPLINUX_RELEASE,		\
-+	info:				isplinux_info,			\
-+	queuecommand:			isplinux_queuecommand,		\
-+	use_new_eh_code:		1,				\
-+	eh_abort_handler:		isplinux_abort,			\
-+	eh_device_reset_handler:	isplinux_bdr,			\
-+	eh_bus_reset_handler:		isplinux_sreset,		\
-+	eh_host_reset_handler:		isplinux_hreset,		\
-+	bios_param:			isplinux_biosparam,		\
-+	can_queue:			1,	   			\
-+	sg_tablesize:			SG_ALL,				\
-+	use_clustering:			ENABLE_CLUSTERING,		\
-+	cmd_per_lun:			1				\
-+}
-+#else
-+#define QLOGICISP {							\
-+	module:				NULL,				\
-+	proc_info:			isplinux_proc_info,		\
-+	name:				"Qlogic ISP 10X0/2X00",		\
-+	detect:				isplinux_detect,		\
-+	release:			ISPLINUX_RELEASE,		\
-+	info:				isplinux_info,			\
-+	queuecommand:			isplinux_queuecommand,		\
-+	eh_abort_handler:		isplinux_abort,			\
-+	eh_device_reset_handler:	isplinux_bdr,			\
-+	eh_bus_reset_handler:		isplinux_sreset,		\
-+	eh_host_reset_handler:		isplinux_hreset,		\
-+	bios_param:			isplinux_biosparam,		\
-+	can_queue:			1,	   			\
-+	sg_tablesize:			SG_ALL,				\
-+	use_clustering:			ENABLE_CLUSTERING,		\
-+	cmd_per_lun:			1,				\
-+	slave_configure:		isplinux_slave_configure,	\
-+}
-+#endif
-+/*
-+ * mode: c
-+ * Local variables:
-+ * c-indent-level: 4
-+ * c-brace-imaginary-offset: 0
-+ * c-brace-offset: -4
-+ * c-argdecl-indent: 4
-+ * c-label-offset: -4
-+ * c-continued-statement-offset: 4
-+ * c-continued-brace-offset: 0
-+ * End:
-+ */
-+#endif /* _ISP_LINUX_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/ispmbox.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,938 @@
-+/* @(#)ispmbox.h 1.24 */
-+/*
-+ * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
-+ *
-+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+#ifndef	_ISPMBOX_H
-+#define	_ISPMBOX_H
-+
-+/*
-+ * Mailbox Command Opcodes
-+ */
-+#define MBOX_NO_OP			0x0000
-+#define MBOX_LOAD_RAM			0x0001
-+#define MBOX_EXEC_FIRMWARE		0x0002
-+#define MBOX_DUMP_RAM			0x0003
-+#define MBOX_WRITE_RAM_WORD		0x0004
-+#define MBOX_READ_RAM_WORD		0x0005
-+#define MBOX_MAILBOX_REG_TEST		0x0006
-+#define MBOX_VERIFY_CHECKSUM		0x0007
-+#define MBOX_ABOUT_FIRMWARE		0x0008
-+					/*   9 */
-+					/*   a */
-+					/*   b */
-+					/*   c */
-+					/*   d */
-+#define MBOX_CHECK_FIRMWARE		0x000e
-+#define	MBOX_READ_RAM_WORD_EXTENDED	0x000f
-+#define MBOX_INIT_REQ_QUEUE		0x0010
-+#define MBOX_INIT_RES_QUEUE		0x0011
-+#define MBOX_EXECUTE_IOCB		0x0012
-+#define MBOX_WAKE_UP			0x0013
-+#define MBOX_STOP_FIRMWARE		0x0014
-+#define MBOX_ABORT			0x0015
-+#define MBOX_ABORT_DEVICE		0x0016
-+#define MBOX_ABORT_TARGET		0x0017
-+#define MBOX_BUS_RESET			0x0018
-+#define MBOX_STOP_QUEUE			0x0019
-+#define MBOX_START_QUEUE		0x001a
-+#define MBOX_SINGLE_STEP_QUEUE		0x001b
-+#define MBOX_ABORT_QUEUE		0x001c
-+#define MBOX_GET_DEV_QUEUE_STATUS	0x001d
-+					/*  1e */
-+#define MBOX_GET_FIRMWARE_STATUS	0x001f
-+#define MBOX_GET_INIT_SCSI_ID		0x0020
-+#define MBOX_GET_SELECT_TIMEOUT		0x0021
-+#define MBOX_GET_RETRY_COUNT		0x0022
-+#define MBOX_GET_TAG_AGE_LIMIT		0x0023
-+#define MBOX_GET_CLOCK_RATE		0x0024
-+#define MBOX_GET_ACT_NEG_STATE		0x0025
-+#define MBOX_GET_ASYNC_DATA_SETUP_TIME	0x0026
-+#define MBOX_GET_SBUS_PARAMS		0x0027
-+#define		MBOX_GET_PCI_PARAMS	MBOX_GET_SBUS_PARAMS
-+#define MBOX_GET_TARGET_PARAMS		0x0028
-+#define MBOX_GET_DEV_QUEUE_PARAMS	0x0029
-+#define	MBOX_GET_RESET_DELAY_PARAMS	0x002a
-+					/*  2b */
-+					/*  2c */
-+					/*  2d */
-+					/*  2e */
-+					/*  2f */
-+#define MBOX_SET_INIT_SCSI_ID		0x0030
-+#define MBOX_SET_SELECT_TIMEOUT		0x0031
-+#define MBOX_SET_RETRY_COUNT		0x0032
-+#define MBOX_SET_TAG_AGE_LIMIT		0x0033
-+#define MBOX_SET_CLOCK_RATE		0x0034
-+#define MBOX_SET_ACT_NEG_STATE		0x0035
-+#define MBOX_SET_ASYNC_DATA_SETUP_TIME	0x0036
-+#define MBOX_SET_SBUS_CONTROL_PARAMS	0x0037
-+#define		MBOX_SET_PCI_PARAMETERS	0x0037
-+#define MBOX_SET_TARGET_PARAMS		0x0038
-+#define MBOX_SET_DEV_QUEUE_PARAMS	0x0039
-+#define	MBOX_SET_RESET_DELAY_PARAMS	0x003a
-+					/*  3b */
-+					/*  3c */
-+					/*  3d */
-+					/*  3e */
-+					/*  3f */
-+#define	MBOX_RETURN_BIOS_BLOCK_ADDR	0x0040
-+#define	MBOX_WRITE_FOUR_RAM_WORDS	0x0041
-+#define	MBOX_EXEC_BIOS_IOCB		0x0042
-+#define	MBOX_SET_FW_FEATURES		0x004a
-+#define	MBOX_GET_FW_FEATURES		0x004b
-+#define		FW_FEATURE_FAST_POST	0x1
-+#define		FW_FEATURE_LVD_NOTIFY	0x2
-+#define		FW_FEATURE_RIO_32BIT	0x4
-+#define		FW_FEATURE_RIO_16BIT	0x8
-+
-+#define	MBOX_INIT_REQ_QUEUE_A64		0x0052
-+#define	MBOX_INIT_RES_QUEUE_A64		0x0053
-+
-+#define	MBOX_ENABLE_TARGET_MODE		0x0055
-+#define		ENABLE_TARGET_FLAG	0x8000
-+#define		ENABLE_TQING_FLAG	0x0004
-+#define		ENABLE_MANDATORY_DISC	0x0002
-+#define	MBOX_GET_TARGET_STATUS		0x0056
-+
-+/* These are for the ISP2X00 FC cards */
-+#define	MBOX_GET_LOOP_ID		0x0020
-+#define	MBOX_GET_FIRMWARE_OPTIONS	0x0028
-+#define	MBOX_SET_FIRMWARE_OPTIONS	0x0038
-+#define	MBOX_GET_RESOURCE_COUNT		0x0042
-+#define	MBOX_ENHANCED_GET_PDB		0x0047
-+#define	MBOX_EXEC_COMMAND_IOCB_A64	0x0054
-+#define	MBOX_INIT_FIRMWARE		0x0060
-+#define	MBOX_GET_INIT_CONTROL_BLOCK	0x0061
-+#define	MBOX_INIT_LIP			0x0062
-+#define	MBOX_GET_FC_AL_POSITION_MAP	0x0063
-+#define	MBOX_GET_PORT_DB		0x0064
-+#define	MBOX_CLEAR_ACA			0x0065
-+#define	MBOX_TARGET_RESET		0x0066
-+#define	MBOX_CLEAR_TASK_SET		0x0067
-+#define	MBOX_ABORT_TASK_SET		0x0068
-+#define	MBOX_GET_FW_STATE		0x0069
-+#define	MBOX_GET_PORT_NAME		0x006A
-+#define	MBOX_GET_LINK_STATUS		0x006B
-+#define	MBOX_INIT_LIP_RESET		0x006C
-+#define	MBOX_SEND_SNS			0x006E
-+#define	MBOX_FABRIC_LOGIN		0x006F
-+#define	MBOX_SEND_CHANGE_REQUEST	0x0070
-+#define	MBOX_FABRIC_LOGOUT		0x0071
-+#define	MBOX_INIT_LIP_LOGIN		0x0072
-+
-+#define	MBOX_DRIVER_HEARTBEAT		0x005B
-+#define	MBOX_FW_HEARTBEAT		0x005C
-+
-+#define	MBOX_GET_SET_DATA_RATE		0x005D	/* 23XX only */
-+#define		MBGSD_GET_RATE	0
-+#define		MBGSD_SET_RATE	1
-+#define		MBGSD_ONEGB	0
-+#define		MBGSD_TWOGB	1
-+#define		MBGSD_AUTO	2
-+
-+
-+#define	ISP2100_SET_PCI_PARAM		0x00ff
-+
-+#define	MBOX_BUSY			0x04
-+
-+typedef struct {
-+	u_int16_t param[8];
-+} mbreg_t;
-+
-+/*
-+ * Mailbox Command Complete Status Codes
-+ */
-+#define	MBOX_COMMAND_COMPLETE		0x4000
-+#define	MBOX_INVALID_COMMAND		0x4001
-+#define	MBOX_HOST_INTERFACE_ERROR	0x4002
-+#define	MBOX_TEST_FAILED		0x4003
-+#define	MBOX_COMMAND_ERROR		0x4005
-+#define	MBOX_COMMAND_PARAM_ERROR	0x4006
-+#define	MBOX_PORT_ID_USED		0x4007
-+#define	MBOX_LOOP_ID_USED		0x4008
-+#define	MBOX_ALL_IDS_USED		0x4009
-+#define	MBOX_NOT_LOGGED_IN		0x400A
-+#define	MBLOGALL			0x000f
-+#define	MBLOGNONE			0x0000
-+#define	MBLOGMASK(x)			((x) & 0xf)
-+
-+/*
-+ * Asynchronous event status codes
-+ */
-+#define	ASYNC_BUS_RESET			0x8001
-+#define	ASYNC_SYSTEM_ERROR		0x8002
-+#define	ASYNC_RQS_XFER_ERR		0x8003
-+#define	ASYNC_RSP_XFER_ERR		0x8004
-+#define	ASYNC_QWAKEUP			0x8005
-+#define	ASYNC_TIMEOUT_RESET		0x8006
-+#define	ASYNC_DEVICE_RESET		0x8007
-+#define	ASYNC_EXTMSG_UNDERRUN		0x800A
-+#define	ASYNC_SCAM_INT			0x800B
-+#define	ASYNC_HUNG_SCSI			0x800C
-+#define	ASYNC_KILLED_BUS		0x800D
-+#define	ASYNC_BUS_TRANSIT		0x800E	/* LVD -> HVD, eg. */
-+#define	ASYNC_LIP_OCCURRED		0x8010
-+#define	ASYNC_LOOP_UP			0x8011
-+#define	ASYNC_LOOP_DOWN			0x8012
-+#define	ASYNC_LOOP_RESET		0x8013
-+#define	ASYNC_PDB_CHANGED		0x8014
-+#define	ASYNC_CHANGE_NOTIFY		0x8015
-+#define	ASYNC_LIP_F8			0x8016
-+#define	ASYNC_CMD_CMPLT			0x8020
-+#define	ASYNC_CTIO_DONE			0x8021
-+#define	ASYNC_IP_XMIT_DONE		0x8022
-+#define	ASYNC_IP_RECV_DONE		0x8023
-+#define	ASYNC_IP_BROADCAST		0x8024
-+#define	ASYNC_IP_RCVQ_LOW		0x8025
-+#define	ASYNC_IP_RCVQ_EMPTY		0x8026
-+#define	ASYNC_IP_RECV_DONE_ALIGNED	0x8027
-+#define	ASYNC_PTPMODE			0x8030
-+#define	ASYNC_RIO1			0x8031
-+#define	ASYNC_RIO2			0x8032
-+#define	ASYNC_RIO3			0x8033
-+#define	ASYNC_RIO4			0x8034
-+#define	ASYNC_RIO5			0x8035
-+#define	ASYNC_CONNMODE			0x8036
-+#define		ISP_CONN_LOOP		1
-+#define		ISP_CONN_PTP		2
-+#define		ISP_CONN_BADLIP		3
-+#define		ISP_CONN_FATAL		4
-+#define		ISP_CONN_LOOPBACK	5
-+#define	ASYNC_RIO_RESP			0x8040
-+#define	ASYNC_RIO_COMP			0x8042
-+/*
-+ * 2.01.31 2200 Only. Need Bit 13 in Mailbox 1 for Set Firmware Options
-+ * mailbox command to enable this.
-+ */
-+#define	ASYNC_QFULL_SENT		0x8049
-+
-+/*
-+ * Mailbox Usages
-+ */
-+
-+#define	WRITE_REQUEST_QUEUE_IN_POINTER(isp, value)	\
-+	ISP_WRITE(isp, isp->isp_rqstinrp, value)
-+
-+#define	READ_REQUEST_QUEUE_OUT_POINTER(isp)		\
-+	ISP_READ(isp, isp->isp_rqstoutrp)
-+
-+#define	READ_RESPONSE_QUEUE_IN_POINTER(isp)		\
-+	ISP_READ(isp, isp->isp_respinrp)
-+
-+#define	WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, value)	\
-+	ISP_WRITE(isp, isp->isp_respoutrp, value)
-+
-+/*
-+ * Command Structure Definitions
-+ */
-+
-+typedef struct {
-+	u_int32_t	ds_base;
-+	u_int32_t	ds_count;
-+} ispds_t;
-+
-+typedef struct {
-+	u_int32_t	ds_base;
-+	u_int32_t	ds_basehi;
-+	u_int32_t	ds_count;
-+} ispds64_t;
-+
-+#define	DSTYPE_32BIT	0
-+#define	DSTYPE_64BIT	1
-+typedef struct {
-+	u_int16_t	ds_type;	/* 0-> ispds_t, 1-> ispds64_t */
-+	u_int32_t	ds_segment;	/* unused */
-+	u_int32_t	ds_base;	/* 32 bit address of DSD list */
-+} ispdslist_t;
-+
-+
-+/*
-+ * These elements get swizzled around for SBus instances.
-+ */
-+#define	ISP_SWAP8(a, b)	{		\
-+	u_int8_t tmp;			\
-+	tmp = a;			\
-+	a = b;				\
-+	b = tmp;			\
-+}
-+typedef struct {
-+	u_int8_t	rqs_entry_type;
-+	u_int8_t	rqs_entry_count;
-+	u_int8_t	rqs_seqno;
-+	u_int8_t	rqs_flags;
-+} isphdr_t;
-+
-+/* RQS Flag definitions */
-+#define	RQSFLAG_CONTINUATION	0x01
-+#define	RQSFLAG_FULL		0x02
-+#define	RQSFLAG_BADHEADER	0x04
-+#define	RQSFLAG_BADPACKET	0x08
-+
-+/* RQS entry_type definitions */
-+#define	RQSTYPE_REQUEST		0x01
-+#define	RQSTYPE_DATASEG		0x02
-+#define	RQSTYPE_RESPONSE	0x03
-+#define	RQSTYPE_MARKER		0x04
-+#define	RQSTYPE_CMDONLY		0x05
-+#define	RQSTYPE_ATIO		0x06	/* Target Mode */
-+#define	RQSTYPE_CTIO		0x07	/* Target Mode */
-+#define	RQSTYPE_SCAM		0x08
-+#define	RQSTYPE_A64		0x09
-+#define	RQSTYPE_A64_CONT	0x0a
-+#define	RQSTYPE_ENABLE_LUN	0x0b	/* Target Mode */
-+#define	RQSTYPE_MODIFY_LUN	0x0c	/* Target Mode */
-+#define	RQSTYPE_NOTIFY		0x0d	/* Target Mode */
-+#define	RQSTYPE_NOTIFY_ACK	0x0e	/* Target Mode */
-+#define	RQSTYPE_CTIO1		0x0f	/* Target Mode */
-+#define	RQSTYPE_STATUS_CONT	0x10
-+#define	RQSTYPE_T2RQS		0x11
-+#define	RQSTYPE_IP_XMIT		0x13
-+#define	RQSTYPE_T4RQS		0x15
-+#define	RQSTYPE_ATIO2		0x16	/* Target Mode */
-+#define	RQSTYPE_CTIO2		0x17	/* Target Mode */
-+#define	RQSTYPE_CSET0		0x18
-+#define	RQSTYPE_T3RQS		0x19
-+#define	RQSTYPE_IP_XMIT_64	0x1b
-+#define	RQSTYPE_CTIO4		0x1e	/* Target Mode */
-+#define	RQSTYPE_CTIO3		0x1f	/* Target Mode */
-+#define	RQSTYPE_RIO1		0x21
-+#define	RQSTYPE_RIO2		0x22
-+#define	RQSTYPE_IP_RECV		0x23
-+#define	RQSTYPE_IP_RECV_CONT	0x24
-+
-+
-+#define	ISP_RQDSEG	4
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handle;
-+	u_int8_t	req_lun_trn;
-+	u_int8_t	req_target;
-+	u_int16_t	req_cdblen;
-+#define	req_modifier	req_cdblen	/* marker packet */
-+	u_int16_t	req_flags;
-+	u_int16_t	req_reserved;
-+	u_int16_t	req_time;
-+	u_int16_t	req_seg_count;
-+	u_int8_t	req_cdb[12];
-+	ispds_t		req_dataseg[ISP_RQDSEG];
-+} ispreq_t;
-+
-+#define	ispreq64_t	ispreqt3_t	/* same as.... */
-+#define	ISP_RQDSEG_A64	2
-+
-+/*
-+ * A request packet can also be a marker packet.
-+ */
-+#define SYNC_DEVICE	0
-+#define SYNC_TARGET	1
-+#define SYNC_ALL	2
-+
-+#define	ISP_RQDSEG_T2		3
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handle;
-+	u_int8_t	req_lun_trn;
-+	u_int8_t	req_target;
-+	u_int16_t	req_scclun;
-+	u_int16_t	req_flags;
-+	u_int16_t	_res2;
-+	u_int16_t	req_time;
-+	u_int16_t	req_seg_count;
-+	u_int8_t	req_cdb[16];
-+	u_int32_t	req_totalcnt;
-+	ispds_t		req_dataseg[ISP_RQDSEG_T2];
-+} ispreqt2_t;
-+
-+#define	ISP_RQDSEG_T3		2
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handle;
-+	u_int8_t	req_lun_trn;
-+	u_int8_t	req_target;
-+	u_int16_t	req_scclun;
-+	u_int16_t	req_flags;
-+	u_int16_t	_res2;
-+	u_int16_t	req_time;
-+	u_int16_t	req_seg_count;
-+	u_int8_t	req_cdb[16];
-+	u_int32_t	req_totalcnt;
-+	ispds64_t	req_dataseg[ISP_RQDSEG_T3];
-+} ispreqt3_t;
-+
-+/* req_flag values */
-+#define	REQFLAG_NODISCON	0x0001
-+#define	REQFLAG_HTAG		0x0002
-+#define	REQFLAG_OTAG		0x0004
-+#define	REQFLAG_STAG		0x0008
-+#define	REQFLAG_TARGET_RTN	0x0010
-+
-+#define	REQFLAG_NODATA		0x0000
-+#define	REQFLAG_DATA_IN		0x0020
-+#define	REQFLAG_DATA_OUT	0x0040
-+#define	REQFLAG_DATA_UNKNOWN	0x0060
-+
-+#define	REQFLAG_DISARQ		0x0100
-+#define	REQFLAG_FRC_ASYNC	0x0200
-+#define	REQFLAG_FRC_SYNC	0x0400
-+#define	REQFLAG_FRC_WIDE	0x0800
-+#define	REQFLAG_NOPARITY	0x1000
-+#define	REQFLAG_STOPQ		0x2000
-+#define	REQFLAG_XTRASNS		0x4000
-+#define	REQFLAG_PRIORITY	0x8000
-+
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handle;
-+	u_int8_t	req_lun_trn;
-+	u_int8_t	req_target;
-+	u_int16_t	req_cdblen;
-+	u_int16_t	req_flags;
-+	u_int16_t	_res1;
-+	u_int16_t	req_time;
-+	u_int16_t	req_seg_count;
-+	u_int8_t	req_cdb[44];
-+} ispextreq_t;
-+
-+#define	ISP_CDSEG	7
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	_res1;
-+	ispds_t		req_dataseg[ISP_CDSEG];
-+} ispcontreq_t;
-+
-+#define	ISP_CDSEG64	5
-+typedef struct {
-+	isphdr_t	req_header;
-+	ispds64_t	req_dataseg[ISP_CDSEG64];
-+} ispcontreq64_t;
-+
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handle;
-+	u_int16_t	req_scsi_status;
-+	u_int16_t	req_completion_status;
-+	u_int16_t	req_state_flags;
-+	u_int16_t	req_status_flags;
-+	u_int16_t	req_time;
-+#define	req_response_len	req_time	/* FC only */
-+	u_int16_t	req_sense_len;
-+	u_int32_t	req_resid;
-+	u_int8_t	req_response[8];	/* FC only */
-+	u_int8_t	req_sense_data[32];
-+} ispstatusreq_t;
-+
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int8_t	req_sense_data[60];
-+} ispstatus_cont_t;
-+
-+/* 
-+ * For Qlogic 2X00, the high order byte of SCSI status has
-+ * additional meaning.
-+ */
-+#define	RQCS_RU	0x800	/* Residual Under */
-+#define	RQCS_RO	0x400	/* Residual Over */
-+#define	RQCS_RESID	(RQCS_RU|RQCS_RO)
-+#define	RQCS_SV	0x200	/* Sense Length Valid */
-+#define	RQCS_RV	0x100	/* FCP Response Length Valid */
-+
-+/* 
-+ * Completion Status Codes.
-+ */
-+#define RQCS_COMPLETE			0x0000
-+#define RQCS_DMA_ERROR			0x0002
-+#define RQCS_RESET_OCCURRED		0x0004
-+#define RQCS_ABORTED			0x0005
-+#define RQCS_TIMEOUT			0x0006
-+#define RQCS_DATA_OVERRUN		0x0007
-+#define RQCS_DATA_UNDERRUN		0x0015
-+#define	RQCS_QUEUE_FULL			0x001C
-+
-+/* 1X00 Only Completion Codes */
-+#define RQCS_INCOMPLETE			0x0001
-+#define RQCS_TRANSPORT_ERROR		0x0003
-+#define RQCS_COMMAND_OVERRUN		0x0008
-+#define RQCS_STATUS_OVERRUN		0x0009
-+#define RQCS_BAD_MESSAGE		0x000a
-+#define RQCS_NO_MESSAGE_OUT		0x000b
-+#define RQCS_EXT_ID_FAILED		0x000c
-+#define RQCS_IDE_MSG_FAILED		0x000d
-+#define RQCS_ABORT_MSG_FAILED		0x000e
-+#define RQCS_REJECT_MSG_FAILED		0x000f
-+#define RQCS_NOP_MSG_FAILED		0x0010
-+#define RQCS_PARITY_ERROR_MSG_FAILED	0x0011
-+#define RQCS_DEVICE_RESET_MSG_FAILED	0x0012
-+#define RQCS_ID_MSG_FAILED		0x0013
-+#define RQCS_UNEXP_BUS_FREE		0x0014
-+#define	RQCS_XACT_ERR1			0x0018
-+#define	RQCS_XACT_ERR2			0x0019
-+#define	RQCS_XACT_ERR3			0x001A
-+#define	RQCS_BAD_ENTRY			0x001B
-+#define	RQCS_PHASE_SKIPPED		0x001D
-+#define	RQCS_ARQS_FAILED		0x001E
-+#define	RQCS_WIDE_FAILED		0x001F
-+#define	RQCS_SYNCXFER_FAILED		0x0020
-+#define	RQCS_LVD_BUSERR			0x0021
-+
-+/* 2X00 Only Completion Codes */
-+#define	RQCS_PORT_UNAVAILABLE		0x0028
-+#define	RQCS_PORT_LOGGED_OUT		0x0029
-+#define	RQCS_PORT_CHANGED		0x002A
-+#define	RQCS_PORT_BUSY			0x002B
-+
-+/*
-+ * 1X00 specific State Flags 
-+ */
-+#define RQSF_GOT_BUS			0x0100
-+#define RQSF_GOT_TARGET			0x0200
-+#define RQSF_SENT_CDB			0x0400
-+#define RQSF_XFRD_DATA			0x0800
-+#define RQSF_GOT_STATUS			0x1000
-+#define RQSF_GOT_SENSE			0x2000
-+#define	RQSF_XFER_COMPLETE		0x4000
-+
-+/*
-+ * 2X00 specific State Flags
-+ * (same as 1X00 except RQSF_GOT_BUS/RQSF_GOT_TARGET are not available)
-+ */
-+#define	RQSF_DATA_IN			0x0020
-+#define	RQSF_DATA_OUT			0x0040
-+#define	RQSF_STAG			0x0008
-+#define	RQSF_OTAG			0x0004
-+#define	RQSF_HTAG			0x0002
-+/*
-+ * 1X00 Status Flags
-+ */
-+#define RQSTF_DISCONNECT		0x0001
-+#define RQSTF_SYNCHRONOUS		0x0002
-+#define RQSTF_PARITY_ERROR		0x0004
-+#define RQSTF_BUS_RESET			0x0008
-+#define RQSTF_DEVICE_RESET		0x0010
-+#define RQSTF_ABORTED			0x0020
-+#define RQSTF_TIMEOUT			0x0040
-+#define RQSTF_NEGOTIATION		0x0080
-+
-+/*
-+ * 2X00 specific state flags
-+ */
-+/* RQSF_SENT_CDB	*/
-+/* RQSF_XFRD_DATA	*/
-+/* RQSF_GOT_STATUS	*/
-+/* RQSF_XFER_COMPLETE	*/
-+
-+/*
-+ * 2X00 specific status flags
-+ */
-+/* RQSTF_ABORTED */
-+/* RQSTF_TIMEOUT */
-+#define	RQSTF_DMA_ERROR			0x0080
-+#define	RQSTF_LOGOUT			0x2000
-+
-+/*
-+ * Miscellaneous
-+ */
-+#ifndef	ISP_EXEC_THROTTLE
-+#define	ISP_EXEC_THROTTLE	16
-+#endif
-+
-+/*
-+ * About Firmware returns an 'attribute' word in mailbox 6.
-+ */
-+#define	ISP_FW_ATTR_TMODE	0x01
-+#define	ISP_FW_ATTR_SCCLUN	0x02
-+#define	ISP_FW_ATTR_FABRIC	0x04
-+#define	ISP_FW_ATTR_CLASS2	0x08
-+#define	ISP_FW_ATTR_FCTAPE	0x10
-+#define	ISP_FW_ATTR_IP		0x20
-+
-+/*
-+ * Reduced Interrupt Operation Response Queue Entreis
-+ */
-+
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int32_t	req_handles[15];
-+} isp_rio1_t;
-+
-+typedef struct {
-+	isphdr_t	req_header;
-+	u_int16_t	req_handles[30];
-+} isp_rio2_t;
-+
-+/*
-+ * FC (ISP2100) specific data structures
-+ */
-+
-+/*
-+ * Initialization Control Block
-+ *
-+ * Version One (prime) format.
-+ */
-+typedef struct isp_icb {
-+	u_int8_t	icb_version;
-+	u_int8_t	_reserved0;
-+	u_int16_t	icb_fwoptions;
-+	u_int16_t	icb_maxfrmlen;
-+	u_int16_t	icb_maxalloc;
-+	u_int16_t	icb_execthrottle;
-+	u_int8_t	icb_retry_count;
-+	u_int8_t	icb_retry_delay;
-+	u_int8_t	icb_portname[8];
-+	u_int16_t	icb_hardaddr;
-+	u_int8_t	icb_iqdevtype;
-+	u_int8_t	icb_logintime;
-+	u_int8_t	icb_nodename[8];
-+	u_int16_t	icb_rqstout;
-+	u_int16_t	icb_rspnsin;
-+	u_int16_t	icb_rqstqlen;
-+	u_int16_t	icb_rsltqlen;
-+	u_int16_t	icb_rqstaddr[4];
-+	u_int16_t	icb_respaddr[4];
-+	u_int16_t	icb_lunenables;
-+	u_int8_t	icb_ccnt;
-+	u_int8_t	icb_icnt;
-+	u_int16_t	icb_lunetimeout;
-+	u_int16_t	_reserved1;
-+	u_int16_t	icb_xfwoptions;
-+	u_int8_t	icb_racctimer;
-+	u_int8_t	icb_idelaytimer;
-+	u_int16_t	icb_zfwoptions;
-+	u_int16_t	_reserved2[13];
-+} isp_icb_t;
-+#define	ICB_VERSION1	1
-+
-+#define	ICBOPT_HARD_ADDRESS	0x0001
-+#define	ICBOPT_FAIRNESS		0x0002
-+#define	ICBOPT_FULL_DUPLEX	0x0004
-+#define	ICBOPT_FAST_POST	0x0008
-+#define	ICBOPT_TGT_ENABLE	0x0010
-+#define	ICBOPT_INI_DISABLE	0x0020
-+#define	ICBOPT_INI_ADISC	0x0040
-+#define	ICBOPT_INI_TGTTYPE	0x0080
-+#define	ICBOPT_PDBCHANGE_AE	0x0100
-+#define	ICBOPT_NOLIP		0x0200
-+#define	ICBOPT_SRCHDOWN		0x0400
-+#define	ICBOPT_PREVLOOP		0x0800
-+#define	ICBOPT_STOP_ON_QFULL	0x1000
-+#define	ICBOPT_FULL_LOGIN	0x2000
-+#define	ICBOPT_BOTH_WWNS	0x4000
-+#define	ICBOPT_EXTENDED		0x8000
-+
-+#define	ICBXOPT_CLASS2_ACK0	0x0200
-+#define	ICBXOPT_CLASS2		0x0100
-+#define	ICBXOPT_LOOP_ONLY	(0 << 4)
-+#define	ICBXOPT_PTP_ONLY	(1 << 4)
-+#define	ICBXOPT_LOOP_2_PTP	(2 << 4)
-+#define	ICBXOPT_PTP_2_LOOP	(3 << 4)
-+
-+/*
-+ * The lower 4 bits of the xfwoptions field are the OPERATION MODE bits.
-+ * RIO is not defined for the 23XX cards
-+ */
-+#define	ICBXOPT_RIO_OFF		0
-+#define	ICBXOPT_RIO_16BIT	1
-+#define	ICBXOPT_RIO_32BIT	2
-+#define	ICBXOPT_RIO_16BIT_IOCB	3
-+#define	ICBXOPT_RIO_32BIT_IOCB	4
-+#define	ICBXOPT_ZIO		5	
-+
-+#define	ICBZOPT_ENA_RDXFR_RDY	0x01
-+#define	ICBZOPT_ENA_OOF		(1 << 6) /* out of order frame handling */
-+/* These 3 only apply to the 2300 */
-+#define	ICBZOPT_RATE_ONEGB	(MBGSD_ONEGB << 14)
-+#define	ICBZOPT_RATE_TWOGB	(MBGSD_TWOGB << 14)
-+#define	ICBZOPT_RATE_AUTO	(MBGSD_AUTO << 14)
-+
-+
-+#define	ICB_MIN_FRMLEN		256
-+#define	ICB_MAX_FRMLEN		2112
-+#define	ICB_DFLT_FRMLEN		1024
-+#define	ICB_DFLT_ALLOC		256
-+#define	ICB_DFLT_THROTTLE	16
-+#define	ICB_DFLT_RDELAY		5
-+#define	ICB_DFLT_RCOUNT		3
-+
-+
-+#define	RQRSP_ADDR0015	0
-+#define	RQRSP_ADDR1631	1
-+#define	RQRSP_ADDR3247	2
-+#define	RQRSP_ADDR4863	3
-+
-+
-+#define	ICB_NNM0	7
-+#define	ICB_NNM1	6
-+#define	ICB_NNM2	5
-+#define	ICB_NNM3	4
-+#define	ICB_NNM4	3
-+#define	ICB_NNM5	2
-+#define	ICB_NNM6	1
-+#define	ICB_NNM7	0
-+
-+#define	MAKE_NODE_NAME_FROM_WWN(array, wwn)	\
-+	array[ICB_NNM0] = (u_int8_t) ((wwn >>  0) & 0xff), \
-+	array[ICB_NNM1] = (u_int8_t) ((wwn >>  8) & 0xff), \
-+	array[ICB_NNM2] = (u_int8_t) ((wwn >> 16) & 0xff), \
-+	array[ICB_NNM3] = (u_int8_t) ((wwn >> 24) & 0xff), \
-+	array[ICB_NNM4] = (u_int8_t) ((wwn >> 32) & 0xff), \
-+	array[ICB_NNM5] = (u_int8_t) ((wwn >> 40) & 0xff), \
-+	array[ICB_NNM6] = (u_int8_t) ((wwn >> 48) & 0xff), \
-+	array[ICB_NNM7] = (u_int8_t) ((wwn >> 56) & 0xff)
-+
-+/*
-+ * FC-AL Position Map
-+ *
-+ * This is an at most 128 byte map that returns either
-+ * the LILP or Firmware generated list of ports.
-+ *
-+ * We deviate a bit from the returned qlogic format to
-+ * use an extra bit to say whether this was a LILP or
-+ * f/w generated map.
-+ */
-+typedef struct {
-+	u_int8_t	fwmap	: 1,
-+			count	: 7;
-+	u_int8_t	map[127];
-+} fcpos_map_t;
-+
-+/*
-+ * Port Data Base Element
-+ */
-+
-+typedef struct {
-+	u_int16_t	pdb_options;
-+	u_int8_t	pdb_mstate;
-+	u_int8_t	pdb_sstate;
-+#define	BITS2WORD(x)	((x)[0] << 16 | (x)[3] << 8 | (x)[2])
-+	u_int8_t	pdb_hardaddr_bits[4];
-+	u_int8_t	pdb_portid_bits[4];
-+	u_int8_t	pdb_nodename[8];
-+	u_int8_t	pdb_portname[8];
-+	u_int16_t	pdb_execthrottle;
-+	u_int16_t	pdb_exec_count;
-+	u_int8_t	pdb_retry_count;
-+	u_int8_t	pdb_retry_delay;
-+	u_int16_t	pdb_resalloc;
-+	u_int16_t	pdb_curalloc;
-+	u_int16_t	pdb_qhead;
-+	u_int16_t	pdb_qtail;
-+	u_int16_t	pdb_tl_next;
-+	u_int16_t	pdb_tl_last;
-+	u_int16_t	pdb_features;	/* PLOGI, Common Service */
-+	u_int16_t	pdb_pconcurrnt;	/* PLOGI, Common Service */
-+	u_int16_t	pdb_roi;	/* PLOGI, Common Service */
-+	u_int8_t	pdb_target;
-+	u_int8_t	pdb_initiator;	/* PLOGI, Class 3 Control Flags */
-+	u_int16_t	pdb_rdsiz;	/* PLOGI, Class 3 */
-+	u_int16_t	pdb_ncseq;	/* PLOGI, Class 3 */
-+	u_int16_t	pdb_noseq;	/* PLOGI, Class 3 */
-+	u_int16_t	pdb_labrtflg;
-+	u_int16_t	pdb_lstopflg;
-+	u_int16_t	pdb_sqhead;
-+	u_int16_t	pdb_sqtail;
-+	u_int16_t	pdb_ptimer;
-+	u_int16_t	pdb_nxt_seqid;
-+	u_int16_t	pdb_fcount;
-+	u_int16_t	pdb_prli_len;
-+	u_int16_t	pdb_prli_svc0;
-+	u_int16_t	pdb_prli_svc3;
-+	u_int16_t	pdb_loopid;
-+	u_int16_t	pdb_il_ptr;
-+	u_int16_t	pdb_sl_ptr;
-+} isp_pdb_t;
-+
-+#define	PDB_OPTIONS_XMITTING	(1<<11)
-+#define	PDB_OPTIONS_LNKXMIT	(1<<10)
-+#define	PDB_OPTIONS_ABORTED	(1<<9)
-+#define	PDB_OPTIONS_ADISC	(1<<1)
-+
-+#define	PDB_STATE_DISCOVERY	0
-+#define	PDB_STATE_WDISC_ACK	1
-+#define	PDB_STATE_PLOGI		2
-+#define	PDB_STATE_PLOGI_ACK	3
-+#define	PDB_STATE_PRLI		4
-+#define	PDB_STATE_PRLI_ACK	5
-+#define	PDB_STATE_LOGGED_IN	6
-+#define	PDB_STATE_PORT_UNAVAIL	7
-+#define	PDB_STATE_PRLO		8
-+#define	PDB_STATE_PRLO_ACK	9
-+#define	PDB_STATE_PLOGO		10
-+#define	PDB_STATE_PLOG_ACK	11
-+
-+#define		SVC3_TGT_ROLE		0x10
-+#define 	SVC3_INI_ROLE		0x20
-+#define			SVC3_ROLE_MASK	0x30
-+#define			SVC3_ROLE_SHIFT	4
-+
-+/*
-+ * CT definition
-+ *
-+ * This is as the QLogic f/w documentations defines it- which is just opposite,
-+ * bit wise, from what the specification defines it as. Additionally, the
-+ * ct_response and ct_resid (really from FC-GS-2) need to be byte swapped.
-+ */
-+
-+typedef struct {
-+	u_int8_t	ct_revision;
-+	u_int8_t	ct_portid[3];
-+	u_int8_t	ct_fcs_type;
-+	u_int8_t	ct_fcs_subtype;
-+	u_int8_t	ct_options;
-+	u_int8_t	ct_res0;
-+	u_int16_t	ct_response;
-+	u_int16_t	ct_resid;
-+	u_int8_t	ct_res1;
-+	u_int8_t	ct_reason;
-+	u_int8_t	ct_explanation;
-+	u_int8_t	ct_vunique;
-+} ct_hdr_t;
-+#define	FS_ACC	0x8002
-+#define	FS_RJT	0x8001
-+
-+#define	FC4_IP		5 /* ISO/EEC 8802-2 LLC/SNAP "Out of Order Delivery" */
-+#define	FC4_SCSI	8 /* SCSI-3 via Fivre Channel Protocol (FCP) */
-+#define	FC4_FC_SVC	0x20	/* Fibre Channel Services */
-+
-+#define	SNS_GA_NXT	0x100
-+#define	SNS_GPN_ID	0x112
-+#define	SNS_GNN_ID	0x113
-+#define	SNS_GFF_ID	0x11F
-+#define	SNS_GID_FT	0x171
-+#define	SNS_RFT_ID	0x217
-+typedef struct {
-+	u_int16_t	snscb_rblen;	/* response buffer length (words) */
-+	u_int16_t	snscb_res0;
-+	u_int16_t	snscb_addr[4];	/* response buffer address */
-+	u_int16_t	snscb_sblen;	/* subcommand buffer length (words) */
-+	u_int16_t	snscb_res1;
-+	u_int16_t	snscb_data[1];	/* variable data */
-+} sns_screq_t;	/* Subcommand Request Structure */
-+
-+typedef struct {
-+	u_int16_t	snscb_rblen;	/* response buffer length (words) */
-+	u_int16_t	snscb_res0;
-+	u_int16_t	snscb_addr[4];	/* response buffer address */
-+	u_int16_t	snscb_sblen;	/* subcommand buffer length (words) */
-+	u_int16_t	snscb_res1;
-+	u_int16_t	snscb_cmd;
-+	u_int16_t	snscb_res2;
-+	u_int32_t	snscb_res3;
-+	u_int32_t	snscb_port;
-+} sns_ga_nxt_req_t;
-+#define	SNS_GA_NXT_REQ_SIZE	(sizeof (sns_ga_nxt_req_t))
-+
-+typedef struct {
-+	u_int16_t	snscb_rblen;	/* response buffer length (words) */
-+	u_int16_t	snscb_res0;
-+	u_int16_t	snscb_addr[4];	/* response buffer address */
-+	u_int16_t	snscb_sblen;	/* subcommand buffer length (words) */
-+	u_int16_t	snscb_res1;
-+	u_int16_t	snscb_cmd;
-+	u_int16_t	snscb_res2;
-+	u_int32_t	snscb_res3;
-+	u_int32_t	snscb_portid;
-+} sns_gxn_id_req_t;
-+#define	SNS_GXN_ID_REQ_SIZE	(sizeof (sns_gxn_id_req_t))
-+
-+typedef struct {
-+	u_int16_t	snscb_rblen;	/* response buffer length (words) */
-+	u_int16_t	snscb_res0;
-+	u_int16_t	snscb_addr[4];	/* response buffer address */
-+	u_int16_t	snscb_sblen;	/* subcommand buffer length (words) */
-+	u_int16_t	snscb_res1;
-+	u_int16_t	snscb_cmd;
-+	u_int16_t	snscb_mword_div_2;
-+	u_int32_t	snscb_res3;
-+	u_int32_t	snscb_fc4_type;
-+} sns_gid_ft_req_t;
-+#define	SNS_GID_FT_REQ_SIZE	(sizeof (sns_gid_ft_req_t))
-+
-+typedef struct {
-+	u_int16_t	snscb_rblen;	/* response buffer length (words) */
-+	u_int16_t	snscb_res0;
-+	u_int16_t	snscb_addr[4];	/* response buffer address */
-+	u_int16_t	snscb_sblen;	/* subcommand buffer length (words) */
-+	u_int16_t	snscb_res1;
-+	u_int16_t	snscb_cmd;
-+	u_int16_t	snscb_res2;
-+	u_int32_t	snscb_res3;
-+	u_int32_t	snscb_port;
-+	u_int32_t	snscb_fc4_types[8];
-+} sns_rft_id_req_t;
-+#define	SNS_RFT_ID_REQ_SIZE	(sizeof (sns_rft_id_req_t))
-+
-+typedef struct {
-+	ct_hdr_t	snscb_cthdr;
-+	u_int8_t	snscb_port_type;
-+	u_int8_t	snscb_port_id[3];
-+	u_int8_t	snscb_portname[8];
-+	u_int16_t	snscb_data[1];	/* variable data */
-+} sns_scrsp_t;	/* Subcommand Response Structure */
-+
-+typedef struct {
-+	ct_hdr_t	snscb_cthdr;
-+	u_int8_t	snscb_port_type;
-+	u_int8_t	snscb_port_id[3];
-+	u_int8_t	snscb_portname[8];
-+	u_int8_t	snscb_pnlen;		/* symbolic port name length */
-+	u_int8_t	snscb_pname[255];	/* symbolic port name */
-+	u_int8_t	snscb_nodename[8];
-+	u_int8_t	snscb_nnlen;		/* symbolic node name length */
-+	u_int8_t	snscb_nname[255];	/* symbolic node name */
-+	u_int8_t	snscb_ipassoc[8];
-+	u_int8_t	snscb_ipaddr[16];
-+	u_int8_t	snscb_svc_class[4];
-+	u_int8_t	snscb_fc4_types[32];
-+	u_int8_t	snscb_fpname[8];
-+	u_int8_t	snscb_reserved;
-+	u_int8_t	snscb_hardaddr[3];
-+} sns_ga_nxt_rsp_t;	/* Subcommand Response Structure */
-+#define	SNS_GA_NXT_RESP_SIZE	(sizeof (sns_ga_nxt_rsp_t))
-+
-+typedef struct {
-+	ct_hdr_t	snscb_cthdr;
-+	u_int8_t	snscb_wwn[8];
-+} sns_gxn_id_rsp_t;
-+#define	SNS_GXN_ID_RESP_SIZE	(sizeof (sns_gxn_id_rsp_t))
-+
-+typedef struct {
-+	ct_hdr_t	snscb_cthdr;
-+	u_int32_t	snscb_fc4_features[32];
-+} sns_gff_id_rsp_t;
-+#define	SNS_GFF_ID_RESP_SIZE	(sizeof (sns_gff_id_rsp_t))
-+
-+typedef struct {
-+	ct_hdr_t	snscb_cthdr;
-+	struct {
-+		u_int8_t	control;
-+		u_int8_t	portid[3];
-+	} snscb_ports[1];
-+} sns_gid_ft_rsp_t;
-+#define	SNS_GID_FT_RESP_SIZE(x)	((sizeof (sns_gid_ft_rsp_t)) + ((x - 1) << 2))
-+
-+#define	SNS_RFT_ID_RESP_SIZE	(sizeof (ct_hdr_t))
-+
-+#endif	/* _ISPMBOX_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_pci.c	2003-07-19 17:06:34.000000000 -0700
-@@ -0,0 +1,2363 @@
-+/* @(#)isp_pci.c 1.39 */
-+/*
-+ * Qlogic ISP Host Adapter PCI specific probe and attach routines
-+ *---------------------------------------
-+ * Copyright (c) 1998, 1999, 2000, 2001 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification, immediately at the beginning of the file.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * Alternatively, this software may be distributed under the terms of the
-+ * the GNU Public License ("GPL").
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * 
-+ * Matthew Jacob
-+ * Feral Software
-+ * PMB #825
-+ * 5214-F Diamond Hts Blvd
-+ * San Francisco, CA, 94131
-+ * mjacob@feral.com
-+ */
-+
-+#include "isp_linux.h"
-+#if	defined(__powerpc__) || defined(__sparc__)
-+static int isp_pci_mapmem = 0xffffffff;
-+#else
-+static int isp_pci_mapmem = 0;
-+#endif
-+#if	defined(__sparc__)
-+#undef	ioremap_nocache
-+#define	ioremap_nocache	ioremap
-+#endif
-+static int isplinux_pci_init(struct Scsi_Host *);
-+static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
-+static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);
-+#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
-+static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);
-+static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
-+#endif
-+static int
-+isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+static int
-+isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-+#endif
-+static int isp_pci_mbxdma(struct ispsoftc *);
-+static int
-+isp_pci_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+static void isp_pci_dmateardown(struct ispsoftc *, XS_T *, u_int16_t);
-+#define	IS_HIGH_ISP_ADDR(addr)	(addr >= (u_int64_t) 0x100000000)
-+#else
-+#define	isp_pci_dmateardown	NULL
-+#define	IS_HIGH_ISP_ADDR(addr)	0
-+#define	sg_dma_address(sg)	virt_to_bus(sg->address)
-+#define	sg_dma_len(sg)		sg->length
-+#endif
-+
-+#if	ISP_DAC_SUPPORTED == 1
-+#define	ISP_A64			1
-+#define	HIWD(x)			((x) >> 32)
-+#else
-+#define	ISP_A64			0
-+#define	HIWD(x)			0
-+#endif
-+#define	LOWD(x)			x
-+
-+static void isp_pci_reset1(struct ispsoftc *);
-+static void isp_pci_dumpregs(struct ispsoftc *, const char *);
-+
-+#ifndef	ISP_CODE_ORG
-+#define	ISP_CODE_ORG		0x1000
-+#endif
-+
-+#ifndef	ISP_DISABLE_1020_SUPPORT
-+#include "asm_1040.h"
-+#define	ISP_1040_RISC_CODE	(u_int16_t *) isp_1040_risc_code
-+#else
-+#define	ISP_1040_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_1080_SUPPORT
-+#include "asm_1080.h"
-+#define	ISP_1080_RISC_CODE	(u_int16_t *) isp_1080_risc_code
-+#else
-+#define	ISP_1080_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_12160_SUPPORT
-+#include "asm_12160.h"
-+#define	ISP_12160_RISC_CODE	(u_int16_t *) isp_12160_risc_code
-+#else
-+#define	ISP_12160_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_2100_SUPPORT
-+#include "asm_2100.h"
-+#define	ISP_2100_RISC_CODE	(u_int16_t *) isp_2100_risc_code
-+#else
-+#define	ISP_2100_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_2200_SUPPORT
-+#include "asm_2200.h"
-+#define	ISP_2200_RISC_CODE	(u_int16_t *) isp_2200_risc_code
-+#else
-+#define	ISP_2200_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+#include "asm_2300.h"
-+#define	ISP_2300_RISC_CODE	(u_int16_t *) isp_2300_risc_code
-+#else
-+#define	ISP_2300_RISC_CODE	NULL
-+#endif
-+
-+#ifndef	ISP_DISABLE_1020_SUPPORT
-+static struct ispmdvec mdvec = {
-+    isp_pci_rd_isr,
-+    isp_pci_rd_reg,
-+    isp_pci_wr_reg,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_1040_RISC_CODE,
-+    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
-+};
-+#endif
-+
-+#ifndef	ISP_DISABLE_1080_SUPPORT
-+static struct ispmdvec mdvec_1080 = {
-+    isp_pci_rd_isr,
-+    isp_pci_rd_reg_1080,
-+    isp_pci_wr_reg_1080,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_1080_RISC_CODE,
-+    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_128
-+};
-+#endif
-+
-+#ifndef	ISP_DISABLE_12160_SUPPORT
-+static struct ispmdvec mdvec_12160 = {
-+    isp_pci_rd_isr,
-+    isp_pci_rd_reg_1080,
-+    isp_pci_wr_reg_1080,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_12160_RISC_CODE,
-+    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_128
-+};
-+#endif
-+
-+#ifndef	ISP_DISABLE_2100_SUPPORT
-+static struct ispmdvec mdvec_2100 = {
-+    isp_pci_rd_isr,
-+    isp_pci_rd_reg,
-+    isp_pci_wr_reg,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_2100_RISC_CODE
-+};
-+#endif
-+
-+#ifndef	ISP_DISABLE_2200_SUPPORT
-+static struct ispmdvec mdvec_2200 = {
-+    isp_pci_rd_isr,
-+    isp_pci_rd_reg,
-+    isp_pci_wr_reg,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_2200_RISC_CODE
-+};
-+#endif
-+
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+static struct ispmdvec mdvec_2300 = {
-+    isp_pci_rd_isr_2300,
-+    isp_pci_rd_reg,
-+    isp_pci_wr_reg,
-+    isp_pci_mbxdma,
-+    isp_pci_dmasetup,
-+    isp_pci_dmateardown,
-+    NULL,
-+    isp_pci_reset1,
-+    isp_pci_dumpregs,
-+    ISP_2300_RISC_CODE
-+};
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1020
-+#define	PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1020
-+#define	PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1080
-+#define	PCI_DEVICE_ID_QLOGIC_ISP1080	0x1080
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP10160
-+#define	PCI_DEVICE_ID_QLOGIC_ISP10160	0x1016
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP12160
-+#define	PCI_DEVICE_ID_QLOGIC_ISP12160	0x1216
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1240
-+#define	PCI_DEVICE_ID_QLOGIC_ISP1240	0x1240
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1280
-+#define	PCI_DEVICE_ID_QLOGIC_ISP1280	0x1280
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2100
-+#define	PCI_DEVICE_ID_QLOGIC_ISP2100	0x2100
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2200
-+#define	PCI_DEVICE_ID_QLOGIC_ISP2200	0x2200
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2300
-+#define	PCI_DEVICE_ID_QLOGIC_ISP2300	0x2300
-+#endif
-+
-+#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2312
-+#define	PCI_DEVICE_ID_QLOGIC_ISP2312	0x2312
-+#endif
-+
-+#define	PCI_DFLT_LTNCY	0x40
-+#define	PCI_DFLT_LNSZ	0x10
-+#define	PCI_CMD_ISP	\
-+ (PCI_COMMAND_MASTER|PCI_COMMAND_INVALIDATE|PCI_COMMAND_PARITY|PCI_COMMAND_SERR)
-+
-+/*
-+ * Encapsulating softc... Order of elements is important. The tag
-+ * pci_isp must come first because of multiple structure punning
-+ * (Scsi_Host * == struct isp_pcisoftc * == struct ispsofct *).
-+ */
-+struct isp_pcisoftc {
-+    struct ispsoftc	pci_isp;
-+    struct pci_dev *	pci_dev;
-+    vm_offset_t		port;	/* I/O port address */
-+    vm_offset_t		paddr;	/* Physical Memory Address */
-+    vm_offset_t		vaddr;	/* Mapped Memory Address */
-+    vm_offset_t		poff[_NREG_BLKS];
-+    union pstore	params;
-+};
-+
-+/*
-+ * Gratefully borrowed from Gerard Roudier's sym53c8xx driver
-+ */
-+static INLINE vm_offset_t
-+map_pci_mem(u_long base, u_long size)
-+{
-+    u_long page_base	= ((u_long) base) & PAGE_MASK;
-+    u_long page_offs	= ((u_long) base) - page_base;
-+    u_long map_size =  roundup(page_offs+size, PAGE_SIZE);
-+    u_long page_remapped = (u_long) ioremap_nocache(page_base, map_size);
-+    (void) map_size;
-+    return (vm_offset_t) (page_remapped ? (page_remapped + page_offs) : 0);
-+}
-+
-+static INLINE
-+void unmap_pci_mem(vm_offset_t vaddr, u_long size)
-+{
-+    if (vaddr)
-+	iounmap((void *) (vaddr & PAGE_MASK));
-+}
-+
-+static INLINE int 
-+map_isp_mem(struct isp_pcisoftc *isp_pci, u_short cmd, vm_offset_t mem_base)
-+{
-+    if (cmd & PCI_COMMAND_MEMORY) {
-+	isp_pci->paddr = __pa(mem_base);
-+	isp_pci->paddr &= PCI_BASE_ADDRESS_MEM_MASK;
-+	isp_pci->vaddr = map_pci_mem(isp_pci->paddr, 0xff);
-+	return (isp_pci->vaddr != (vm_offset_t) 0);
-+    }
-+    return (0);
-+}
-+
-+static INLINE int 
-+map_isp_io(struct isp_pcisoftc *isp_pci, u_short cmd, vm_offset_t io_base)
-+{
-+    if ((cmd & PCI_COMMAND_IO) && (io_base & 3) == 1) {
-+   	isp_pci->port = io_base & PCI_BASE_ADDRESS_IO_MASK;
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-+	if (check_region(isp_pci->port, 0xff)) {
-+	    return (0);
-+	}
-+#endif
-+	request_region(isp_pci->port, 0xff, "isp");
-+	return (1);
-+    }
-+    return (0);
-+}
-+
-+#define	ISP_PCI_BUS	pcidev->bus->number
-+#define	ISP_PCI_DEVICE	pcidev->devfn
-+#define	ISEARCH_RESET	pcidev = NULL
-+#define	ISEARCH(x)	\
-+  (pcidev = pci_find_device(PCI_VENDOR_ID_QLOGIC, x, pcidev)) != NULL
-+#define	ISEARCH_NEXT
-+#define	ISTORE_ARGS		struct pci_dev *pcidev
-+#define	ISTORE_FNDARGS		ISTORE_ARGS
-+#define	ISTORE_FNCARGS		pcidev
-+#define	ISTORE_ISP_INFO(x)	(x)->pci_dev = pcidev
-+
-+static INLINE struct isp_pcisoftc *
-+isplinux_pci_addhost(Scsi_Host_Template *tmpt, ISTORE_FNDARGS)
-+{
-+    struct Scsi_Host *host;
-+    struct ispsoftc *isp;
-+    struct isp_pcisoftc *pci_isp;
-+
-+    host = scsi_register(tmpt, sizeof(struct isp_pcisoftc));
-+    if (host == NULL) {
-+	printk("isplinux_pci_addhost: scsi_register failed\n");
-+	return (NULL);
-+    }
-+    pci_isp = (struct isp_pcisoftc *) host->hostdata;
-+    if (pci_isp == NULL) {
-+	printk("isplinux_pci_addhost: cannot get softc out of scsi_register\n");
-+	return (NULL);
-+    }
-+    ISTORE_ISP_INFO(pci_isp);
-+    isp = (struct ispsoftc *) pci_isp;
-+    isp->isp_host = host;
-+    isp->isp_osinfo.storep = &pci_isp->params;
-+    if (isplinux_pci_init(host)) {
-+	scsi_unregister(host);
-+	return (NULL);
-+    }
-+    isp->isp_next = isplist;
-+    isplist = isp;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,61)
-+    scsi_set_device(host, &pci_isp->pci_dev->dev);
-+#else
-+    scsi_set_pci_device(host, pci_isp->pci_dev);
-+#endif
-+#endif
-+    return (pci_isp);
-+}
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) && \
-+    	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+#include <linux/reboot.h>
-+static int
-+isp_notify_reboot(struct notifier_block *ispnb, unsigned long Event, void *b)
-+{
-+    struct ispsoftc *isp;
-+    switch (Event) {
-+    case SYS_RESTART:
-+    case SYS_HALT:
-+    case SYS_POWER_OFF:
-+	break;
-+    default:
-+	return (NOTIFY_DONE);
-+    }
-+    for (isp = isplist; isp != NULL; isp = isp->isp_next) {
-+	ISP_LOCKU_SOFTC(isp);
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+	if (IS_FC(isp)) {
-+	    ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
-+	    ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
-+	    ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
-+	    ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
-+	    ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
-+	}
-+	ISP_UNLKU_SOFTC(isp);
-+    }
-+    return (NOTIFY_OK);
-+}
-+static struct notifier_block isp_notifier = {
-+	notifier_call:	isp_notify_reboot,
-+	next:		NULL,
-+	priority:	0
-+};
-+#endif
-+
-+static int isp_nfound = 0;
-+int
-+isplinux_pci_detect(Scsi_Host_Template *tmpt)
-+{
-+    static const char *fmt =
-+	"ISP SCSI and Fibre Channel Host Adapter Driver\n"
-+	"      Linux Platform Version %d.%d\n"
-+	"      Common Core Code Version %d.%d\n"
-+	"      Built on %s, %s\n";
-+    struct isp_pcisoftc *pci_isp;
-+    ISTORE_ARGS;
-+
-+    printk(fmt, ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
-+	ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR, __DATE__ , __TIME__ );
-+
-+#ifndef	ISP_DISABLE_1020_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1020); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+
-+#ifndef	ISP_DISABLE_1080_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1240); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1080); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1280); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+
-+#ifndef	ISP_DISABLE_12160_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP10160); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP12160); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+
-+#ifndef	ISP_DISABLE_2100_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2100); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+
-+#ifndef	ISP_DISABLE_2200_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2200); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2300); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2312); ISEARCH_NEXT) {
-+	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);
-+        if (pci_isp) {
-+		isp_nfound++;
-+	}
-+    }
-+#endif
-+    /*
-+     * Don't do reboot notifier stuff for 2.5.X yet
-+     */
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) && \
-+    	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+    if (isp_nfound) {
-+	register_reboot_notifier(&isp_notifier);
-+    }
-+#endif
-+    return (isp_nfound);
-+}
-+
-+void
-+isplinux_pci_release(struct Scsi_Host *host)
-+{
-+    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) host->hostdata;
-+    free_irq(host->irq, pcs);
-+    if (pcs->vaddr != 0) {
-+	unmap_pci_mem(pcs->vaddr, 0xff);
-+	pcs->vaddr = 0;
-+    } else {
-+	release_region(pcs->port, 0xff);
-+	pcs->port = 0;
-+    }
-+    kfree(isp->isp_xflist);
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    pci_free_consistent(pcs->pci_dev, RQUEST_QUEUE_LEN(isp) * QENTRY_LEN,
-+	isp->isp_rquest, isp->isp_rquest_dma);
-+    pci_free_consistent(pcs->pci_dev, RESULT_QUEUE_LEN(isp) * QENTRY_LEN,
-+	isp->isp_result, isp->isp_result_dma);
-+    if (IS_FC(isp)) {
-+	pci_free_consistent(pcs->pci_dev, ISP2100_SCRLEN,
-+	    FCPARAM(isp)->isp_scratch, FCPARAM(isp)->isp_scdma);
-+    }
-+#else
-+    RlsPages(isp->isp_rquest, IspOrder(RQUEST_QUEUE_LEN(isp)));
-+    RlsPages(isp->isp_result, IspOrder(RESULT_QUEUE_LEN(isp)));
-+    if (IS_FC(isp) && FCPARAM(isp)->isp_scratch) {
-+	RlsPages(FCPARAM(isp)->isp_scratch, 1);
-+    }
-+#endif
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) && \
-+    	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+    if (--isp_nfound <= 0) {
-+        unregister_reboot_notifier(&isp_notifier);
-+    }
-+#endif
-+}
-+
-+static int
-+isplinux_pci_init(struct Scsi_Host *host)
-+{
-+    static char *nomap = "cannot map either memory or I/O space";
-+    unsigned long io_base, mem_base;
-+    unsigned int irq, pci_cmd_isp = PCI_CMD_ISP;
-+    struct isp_pcisoftc *isp_pci;
-+    u_char rev, lnsz, timer;
-+    u_short vid, did, cmd;
-+    char loc[32];
-+    struct ispsoftc *isp;
-+
-+    isp_pci = (struct isp_pcisoftc *) host->hostdata;
-+    isp = (struct ispsoftc *) isp_pci;
-+    sprintf(loc, "isp@<PCI%d,Slot%d,Func%d>", isp_pci->pci_dev->bus->number,
-+	PCI_SLOT(isp_pci->pci_dev->devfn), PCI_FUNC(isp_pci->pci_dev->devfn));
-+    if (PRDW(isp_pci, PCI_COMMAND, &cmd) ||
-+	PRDB(isp_pci, PCI_CACHE_LINE_SIZE, &lnsz) ||
-+	PRDB(isp_pci, PCI_LATENCY_TIMER, &timer) ||
-+	PRDB(isp_pci, PCI_CLASS_REVISION, &rev)) {
-+	printk("%s: error reading PCI configuration", loc);
-+	return (1);
-+    }
-+    vid = isp_pci->pci_dev->vendor;
-+    did = isp_pci->pci_dev->device;
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    io_base = pci_resource_start(isp_pci->pci_dev, 0);
-+    if (pci_resource_flags(isp_pci->pci_dev, 0) & PCI_BASE_ADDRESS_MEM_TYPE_64)
-+	irq = 2;
-+    else
-+	irq = 1;
-+    mem_base = pci_resource_start(isp_pci->pci_dev, irq);
-+    if (pci_resource_flags(isp_pci->pci_dev, irq) &
-+	PCI_BASE_ADDRESS_MEM_TYPE_64) {
-+#if	BITS_PER_LONG == 64
-+	mem_base |= pci_resource_start(isp_pci->pci_dev, irq+1) << 32;
-+#else
-+	isp_pci_mapmem &= ~(1 << isp->isp_unit);
-+#endif
-+    }
-+#else	/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) */
-+    io_base = isp_pci->pci_dev->base_address[0];
-+    mem_base = isp_pci->pci_dev->base_address[1];
-+    if (mem_base & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-+#if	BITS_PER_LONG == 64
-+	mem_base |= isp_pci->pci_dev->base_address[2] << 32;
-+#else
-+	isp_pci_mapmem &= ~(1 << isp->isp_unit);
-+#endif
-+    }
-+#endif	/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) */
-+    irq = isp_pci->pci_dev->irq;
-+
-+    if (vid != PCI_VENDOR_ID_QLOGIC) {
-+	printk("%s: 0x%04x is not QLogic's PCI Vendor ID\n", loc, vid);
-+	return (1);
-+    }
-+
-+    isp_pci->poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
-+    isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
-+    isp_pci->poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
-+    isp_pci->poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
-+    isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
-+    switch (did) {
-+    case PCI_DEVICE_ID_QLOGIC_ISP1020:
-+	break;
-+    case PCI_DEVICE_ID_QLOGIC_ISP1080:
-+    case PCI_DEVICE_ID_QLOGIC_ISP1240:
-+    case PCI_DEVICE_ID_QLOGIC_ISP1280:
-+    case PCI_DEVICE_ID_QLOGIC_ISP10160:
-+    case PCI_DEVICE_ID_QLOGIC_ISP12160:
-+	isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF;
-+	break;
-+    case PCI_DEVICE_ID_QLOGIC_ISP2200:
-+    case PCI_DEVICE_ID_QLOGIC_ISP2100:
-+	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2100_OFF;
-+	break;
-+    case PCI_DEVICE_ID_QLOGIC_ISP2300:
-+	pci_cmd_isp &= ~PCI_COMMAND_INVALIDATE;	/* per errata */
-+	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF;
-+	break;
-+    case PCI_DEVICE_ID_QLOGIC_ISP2312:
-+	isp->isp_port = PCI_FUNC(isp_pci->pci_dev->devfn);
-+	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF;
-+	break;
-+    default:
-+	printk("%s: Device ID 0x%04x is not a known Qlogic Device", loc, did);
-+	return (1);
-+    }
-+
-+    /*
-+     * Bump unit seed- we're here, whether we complete the attachment or not.
-+     */
-+    isp->isp_unit = isp_unit_seed++;
-+    sprintf(isp->isp_name, "isp%d", isp->isp_unit);
-+
-+    isp->isp_osinfo.device_id =
-+	((isp_pci->pci_dev->bus->number) << 16)		|
-+        (PCI_SLOT(isp_pci->pci_dev->devfn) << 8)	|
-+	(PCI_FUNC(isp_pci->pci_dev->devfn));
-+
-+    if (isp_disable & (1 << isp->isp_unit)) {
-+	isp_prt(isp, ISP_LOGALL, "disabled at user request");
-+	return (1);
-+    }
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    if (pci_enable_device(isp_pci->pci_dev)) {
-+	printk("%s: fails to be PCI_ENABLEd\n", loc);
-+	return (1);
-+    }
-+    (void) PRDW(isp_pci, PCI_COMMAND, &cmd);
-+#endif
-+
-+    if ((cmd & PCI_CMD_ISP) != pci_cmd_isp) {
-+	if (isp_debug & ISP_LOGINFO)
-+	    printk("%s: rewriting command register from 0x%x to 0x%x\n",
-+		loc, cmd, (cmd & ~PCI_CMD_ISP) | pci_cmd_isp);
-+	cmd &= ~PCI_CMD_ISP;
-+	cmd |= pci_cmd_isp;
-+	PWRW(isp_pci, PCI_COMMAND, cmd);
-+    }
-+
-+    if (lnsz != PCI_DFLT_LNSZ) {
-+	if (isp_debug & ISP_LOGINFO)
-+	    printk("%s: rewriting cache line size from 0x%x to 0x%x\n",
-+		loc, lnsz, PCI_DFLT_LNSZ);
-+	lnsz = PCI_DFLT_LNSZ;
-+	PWRB(isp_pci, PCI_CACHE_LINE_SIZE, lnsz);
-+    }
-+
-+#ifdef	__sparc__
-+    if (PRDB(isp_pci, PCI_MIN_GNT, &rev)) {
-+	printk("%s: unable to read min grant\n", loc);
-+	return (1);
-+    }
-+    if (rev) {
-+	rev = (rev << 3) & 0xff;
-+    }
-+    if (rev == 0) {
-+	rev = 64;
-+    }
-+    if (isp_debug & ISP_LOGINFO) {
-+	printk("%s: rewriting latency timer from 0x%x to 0x%x\n",
-+	    loc, timer, rev);
-+    }
-+    PWRB(isp_pci, PCI_LATENCY_TIMER, rev);
-+#else
-+    if (timer < PCI_DFLT_LTNCY) {
-+	if (isp_debug & ISP_LOGINFO)
-+	    printk("%s: rewriting latency timer from 0x%x to 0x%x\n",
-+		loc, timer, PCI_DFLT_LTNCY);
-+	timer = PCI_DFLT_LTNCY;
-+	PWRB(isp_pci, PCI_LATENCY_TIMER, timer);
-+    }
-+#endif
-+
-+    if ((cmd & (PCI_COMMAND_MEMORY|PCI_COMMAND_IO)) == 0) {
-+#ifdef	__powerpc__
-+	if (io_base == 0 && mem_base == 0) {
-+	    printk("%s: you lose- no register access defined.\n", loc);
-+	    return (1);
-+	}
-+	if (io_base)
-+		cmd |= PCI_COMMAND_IO;
-+	if (mem_base)
-+		cmd |= PCI_COMMAND_MEMORY;
-+	PWRW(isp_pci, PCI_COMMAND, cmd);
-+#else
-+	printk("%s: you lose- no register access defined.\n", loc);
-+	return (1);
-+#endif
-+    }
-+
-+    /*
-+     * Disable the ROM.
-+     */
-+    PWRL(isp_pci, PCI_ROM_ADDRESS, 0);
-+
-+    /*
-+     * Set up stuff...
-+     */
-+    isp_pci->port = isp_pci->vaddr = 0;
-+
-+    /*
-+     * If we prefer to map memory space over I/O, try that first.
-+     */
-+    if (isp_pci_mapmem & (1 << isp->isp_unit)) {
-+	if (map_isp_mem(isp_pci, cmd, mem_base) == 0) {
-+	    if (map_isp_io(isp_pci, cmd, io_base) == 0) {
-+		isp_prt(isp, ISP_LOGERR, nomap);
-+		return (1);
-+	    }
-+	}
-+    } else {
-+	if (map_isp_io(isp_pci, cmd, io_base) == 0) {
-+	    if (map_isp_mem(isp_pci, cmd, mem_base) == 0) {
-+		isp_prt(isp, ISP_LOGERR, nomap);
-+		return (1);
-+	    }
-+	}
-+    }
-+    if (isp_pci->vaddr) {
-+	isp_prt(isp, ISP_LOGCONFIG,
-+	    "mapped memory 0x%lx at 0x%lx\n", isp_pci->paddr, isp_pci->vaddr);
-+	host->io_port = isp_pci->paddr;
-+    } else {
-+        isp_prt(isp, ISP_LOGCONFIG,
-+	    "mapped I/O space at 0x%lx\n", isp_pci->port);
-+	host->io_port = isp_pci->port;
-+    }
-+    host->irq = 0;
-+    isp_pci->pci_isp.isp_revision = rev;
-+#ifndef	ISP_DISABLE_1020_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP1020) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_UNKNOWN;
-+    } 
-+#endif
-+#ifndef	ISP_DISABLE_1080_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP1080) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1080;
-+    }
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP1240) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1240;
-+	host->max_channel = 1;
-+    }
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP1280) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1280;
-+	host->max_channel = 1;
-+    }
-+#endif
-+#ifndef	ISP_DISABLE_12160_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP10160) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_12160;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_12160;
-+    }
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP12160) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_12160;
-+	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_12160;
-+	host->max_channel = 1;
-+    }
-+#endif
-+#ifndef	ISP_DISABLE_2100_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP2100) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_2100;
-+	isp_pci->pci_isp.isp_type = ISP_HA_FC_2100;
-+    }
-+#endif
-+#ifndef	ISP_DISABLE_2200_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP2200) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_2200;
-+	isp_pci->pci_isp.isp_type = ISP_HA_FC_2200;
-+    }
-+#endif
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP2300) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_2300;
-+	isp_pci->pci_isp.isp_type = ISP_HA_FC_2300;
-+    }
-+    if (did == PCI_DEVICE_ID_QLOGIC_ISP2312) {
-+	isp_pci->pci_isp.isp_mdvec = &mdvec_2300;
-+	isp_pci->pci_isp.isp_type = ISP_HA_FC_2312;
-+    }
-+
-+    if (IS_23XX(isp)) {
-+	/*
-+	 * Can't tell if the ROM will hang on 'ABOUT FIRMWARE' command
-+	 */
-+	isp->isp_touched = 1;
-+    }
-+#endif
-+
-+    if (request_irq(irq, isplinux_intr, SA_SHIRQ, isp->isp_name, isp_pci)) {
-+	isp_prt(isp, ISP_LOGERR, "could not snag irq %u (0x%x)", irq, irq);
-+	goto bad;
-+    }
-+    host->irq = irq;
-+#if	LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+    host->select_queue_depths = isplinux_sqd;
-+#endif
-+    isp->isp_param = &isp_pci->params;
-+#if	LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)
-+    host->highmem_io = 0;
-+    if (IS_FC(isp) || IS_ULTRA2(isp) || IS_1240(isp)) {
-+	if (!ISP_A64 || pci_set_dma_mask(isp_pci->pci_dev, (u64) 0xffffffffffffffffULL)) {
-+	    if (pci_set_dma_mask(isp_pci->pci_dev, (u64)0xffffffff)) {
-+		isp_prt(isp, ISP_LOGERR, "cannot set 32 bit dma mask");
-+		goto bad;
-+	    } else {
-+	    	isp_prt(isp, ISP_LOGCONFIG, "enabling 32 bit DMA");
-+        	host->highmem_io = 1;
-+	    }
-+	} else {
-+	    isp_prt(isp, ISP_LOGCONFIG, "enabling 64 bit DMA");
-+	}
-+        host->highmem_io = 1;
-+    }
-+#endif
-+
-+    /*
-+     * At this point, we're committed to keeping this adapter around.
-+     */
-+    isplinux_common_init(isp);
-+    return (0);
-+bad:
-+    if (host->irq) {
-+	DISABLE_INTS(isp);
-+	free_irq(host->irq, isp_pci);
-+	host->irq = 0;
-+    }
-+    if (isp_pci->vaddr != 0) {
-+	unmap_pci_mem(isp_pci->vaddr, 0xff);
-+	isp_pci->vaddr = 0;
-+    } else {
-+	release_region(isp_pci->port, 0xff);
-+	isp_pci->port = 0;
-+    }
-+    return (1);
-+}
-+
-+static INLINE u_int16_t
-+ispregrd(struct isp_pcisoftc *pcs, vm_offset_t offset)
-+{
-+    u_int16_t rv;
-+    if (pcs->vaddr) {
-+	offset += pcs->vaddr;
-+	rv = readw(offset);
-+    } else {
-+	offset += pcs->port;
-+	rv = inw(offset);
-+    }
-+    return (rv);
-+}
-+
-+static INLINE void
-+ispregwr(struct isp_pcisoftc *pcs, vm_offset_t offset, u_int16_t val)
-+{
-+    if (pcs->vaddr) {
-+	offset += pcs->vaddr;
-+	writew(val, offset);
-+    } else {
-+	offset += pcs->port;
-+	outw(val, offset);
-+    }
-+    MEMORYBARRIER(isp, SYNC_REG, offset, 2);
-+}
-+
-+static INLINE int
-+isp_pci_rd_debounced(struct isp_pcisoftc *pcs, vm_offset_t off, u_int16_t *rp)
-+{
-+    u_int16_t val0, val1;
-+    int i = 0;
-+    do {
-+	val0 = ispregrd(pcs, off);
-+	val1 = ispregrd(pcs, off);
-+    } while (val0 != val1 && ++i < 1000);
-+    if (val0 != val1) {
-+	return (1);
-+    }
-+    *rp = val0;
-+    return (0);
-+}
-+
-+#define	IspVirt2Off(a, x)	\
-+	((a)->poff[((x) & _BLK_REG_MASK) >> _BLK_REG_SHFT] + ((x) & 0xff))
-+
-+static int
-+isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
-+    u_int16_t *semap, u_int16_t *mbp)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+    u_int16_t isr, sema;
-+
-+    if (IS_2100(isp)) {
-+	if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, BIU_ISR), &isr)) {
-+	    return (0);
-+        }
-+	if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, BIU_SEMA), &sema)) {
-+	    return (0);
-+        }
-+    } else {
-+	isr = ispregrd(pcs, IspVirt2Off(pcs, BIU_ISR));
-+	sema = ispregrd(pcs, IspVirt2Off(pcs, BIU_SEMA));
-+    }
-+    isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
-+    isr &= INT_PENDING_MASK(isp);
-+    sema &= BIU_SEMA_LOCK;
-+    if (isr == 0 && sema == 0) {
-+	return (0);
-+    }
-+    *isrp = isr;
-+    if ((*semap = sema) != 0) {
-+	if (IS_2100(isp)) {
-+	    if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, OUTMAILBOX0), mbp)) {
-+		return (0);
-+	    }
-+	} else {
-+	    *mbp = ispregrd(pcs, IspVirt2Off(pcs, OUTMAILBOX0));
-+	}
-+    }
-+    return (1);
-+}
-+
-+#ifndef	ISP_DISABLE_2300_SUPPORT
-+static INLINE u_int32_t
-+ispregrd32(struct isp_pcisoftc *pcs, vm_offset_t offset)
-+{
-+    u_int32_t rv;
-+    if (pcs->vaddr) {
-+	offset += pcs->vaddr;
-+	rv = readl(offset);
-+    } else {
-+	offset += pcs->port;
-+	rv = inl(offset);
-+    }
-+    return (rv);
-+}
-+
-+static int
-+isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
-+    u_int16_t *semap, u_int16_t *mbox0p)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+    u_int32_t r2hisr;
-+
-+   /*
-+    * Avoid parity errors on the 2312.
-+    */
-+    if (!(ispregrd(pcs, IspVirt2Off(pcs, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {
-+	*isrp = 0;
-+	return (0);
-+    }
-+
-+    r2hisr = ispregrd32(pcs, IspVirt2Off(pcs, BIU_R2HSTSLO));
-+    isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
-+    if ((r2hisr & BIU_R2HST_INTR) == 0) {
-+	*isrp = 0;
-+	return (0);
-+    }
-+    switch (r2hisr & BIU_R2HST_ISTAT_MASK) {
-+    case ISPR2HST_ROM_MBX_OK:
-+    case ISPR2HST_ROM_MBX_FAIL:
-+    case ISPR2HST_MBX_OK:
-+    case ISPR2HST_MBX_FAIL:
-+    case ISPR2HST_ASYNC_EVENT:
-+	*isrp = r2hisr & 0xffff;
-+	*mbox0p = (r2hisr >> 16);
-+	*semap = 1;
-+	return (1);
-+    case ISPR2HST_RIO_16:
-+	*isrp = r2hisr & 0xffff;
-+	*mbox0p = ASYNC_RIO1;
-+	*semap = 1;
-+	return (1);
-+    case ISPR2HST_FPOST:
-+	*isrp = r2hisr & 0xffff;
-+	*mbox0p = ASYNC_CMD_CMPLT;
-+	*semap = 1;
-+	return (1);
-+    case ISPR2HST_FPOST_CTIO:
-+	*isrp = r2hisr & 0xffff;
-+	*mbox0p = ASYNC_CTIO_DONE;
-+	*semap = 1;
-+	return (1);
-+    case ISPR2HST_RSPQ_UPDATE:
-+	*isrp = r2hisr & 0xffff;
-+	*mbox0p = 0;
-+	*semap = 0;
-+	return (1);
-+   default:
-+	return (0);
-+   }
-+}
-+#endif
-+
-+static u_int16_t
-+isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
-+{
-+    u_int16_t rv, oldconf = 0;
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
-+	/*
-+	 * We will assume that someone has paused the RISC processor.
-+	 */
-+	oldconf = ispregrd(pcs, IspVirt2Off(pcs, BIU_CONF1));
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP);
-+    }
-+    rv = ispregrd(pcs, IspVirt2Off(pcs, regoff));
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);
-+    }
-+    return (rv);
-+}
-+
-+static void
-+isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+    u_int16_t oldconf = 0;
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
-+	/*
-+	 * We will assume that someone has paused the RISC processor.
-+	 */
-+	oldconf = ispregrd(pcs, IspVirt2Off(pcs, BIU_CONF1));
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP);
-+    }
-+    ispregwr(pcs, IspVirt2Off(pcs, regoff), val);
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);
-+    }
-+}
-+
-+#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
-+static u_int16_t
-+isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+    u_int16_t rv, oldconf = 0;
-+
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
-+	(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
-+	u_int16_t tmpconf;
-+	/*
-+	 * We will assume that someone has paused the RISC processor.
-+	 */
-+	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));
-+	tmpconf = oldconf & ~BIU_PCI1080_CONF1_DMA;
-+	if (IS_1280(isp)) {
-+	    if (regoff & SXP_BANK1_SELECT) {
-+		tmpconf |= BIU_PCI1080_CONF1_SXP0;
-+	    } else {
-+		tmpconf |= BIU_PCI1080_CONF1_SXP1;
-+	    }
-+	} else {
-+	    tmpconf |= BIU_PCI1080_CONF1_SXP0;
-+	}
-+	ispregwr(pcs,  IspVirt2Off(pcs, BIU_CONF1), tmpconf);
-+    } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
-+	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1),
-+	    oldconf | BIU_PCI1080_CONF1_DMA);
-+    }
-+    rv = ispregrd(pcs, IspVirt2Off(pcs, regoff));
-+    if (oldconf) {
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);
-+    }
-+    return (rv);
-+}
-+
-+static void
-+isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+    u_int16_t oldconf = 0;
-+
-+    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
-+	(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
-+	u_int16_t tmpconf;
-+	/*
-+	 * We will assume that someone has paused the RISC processor.
-+	 */
-+	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));
-+	tmpconf = oldconf & ~BIU_PCI1080_CONF1_DMA;
-+	if (IS_1280(isp)) {
-+	    if (regoff & SXP_BANK1_SELECT) {
-+		tmpconf |= BIU_PCI1080_CONF1_SXP0;
-+	    } else {
-+		tmpconf |= BIU_PCI1080_CONF1_SXP1;
-+	    }
-+	} else {
-+	    tmpconf |= BIU_PCI1080_CONF1_SXP0;
-+	}
-+	ispregwr(pcs,  IspVirt2Off(pcs, BIU_CONF1), tmpconf);
-+    } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
-+	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1),
-+	    oldconf | BIU_PCI1080_CONF1_DMA);
-+    }
-+    ispregwr(pcs, IspVirt2Off(pcs, regoff), val);
-+    if (oldconf) {
-+	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);
-+    }
-+}
-+#endif
-+
-+static int
-+isp_pci_mbxdma(struct ispsoftc *isp)
-+{
-+    if (isp->isp_xflist == NULL) {
-+	size_t amt = isp->isp_maxcmds * sizeof (XS_T **);
-+	isp->isp_xflist = kmalloc(amt, GFP_KERNEL);
-+	if (isp->isp_xflist == NULL) {
-+	    isp_prt(isp, ISP_LOGERR, "unable to allocate xflist array");
-+	    return (1);
-+	}
-+	MEMZERO(isp->isp_xflist, amt);
-+    }
-+    if (isp->isp_rquest == NULL) {
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	dma_addr_t busaddr;
-+	isp->isp_rquest =
-+	    pci_alloc_consistent(pcs->pci_dev,
-+		RQUEST_QUEUE_LEN(isp) * QENTRY_LEN, &busaddr);
-+	if (isp->isp_rquest == NULL) {
-+	    isp_prt(isp, ISP_LOGERR, "unable to allocate request queue");
-+	    return (1);
-+	}
-+	isp->isp_rquest_dma = busaddr;
-+#else
-+	isp->isp_rquest = (caddr_t) GetPages(IspOrder(RQUEST_QUEUE_LEN(isp)));
-+	if (isp->isp_rquest == NULL) {
-+	    isp_prt(isp, ISP_LOGERR, "unable to allocate request queue");
-+	    return (1);
-+	}
-+	/*
-+	 * Map the Request queue.
-+	 */
-+	isp->isp_rquest_dma = virt_to_bus(isp->isp_rquest);
-+#endif
-+	if (isp->isp_rquest_dma & 0x3f) {
-+	    isp_prt(isp, ISP_LOGERR, "Request Queue not on 64 byte boundary");
-+	    return (1);
-+        }
-+	MEMZERO(isp->isp_rquest, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
-+    }
-+
-+    if (isp->isp_result == NULL) {
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	dma_addr_t busaddr;
-+	isp->isp_result =
-+	    pci_alloc_consistent(pcs->pci_dev,
-+		RESULT_QUEUE_LEN(isp) * QENTRY_LEN, &busaddr);
-+	if (isp->isp_result == NULL) {
-+	    isp_prt(isp, ISP_LOGERR, "unable to allocate result queue");
-+	    return (1);
-+	}
-+	isp->isp_result_dma = busaddr;
-+#else
-+	isp->isp_result = (caddr_t) GetPages(IspOrder(RESULT_QUEUE_LEN(isp)));
-+	if (isp->isp_result == NULL) {
-+	    isp_prt(isp, ISP_LOGERR, "unable to allocate result queue");
-+	    free_pages((unsigned long)isp->isp_rquest,
-+		IspOrder(RQUEST_QUEUE_LEN(isp)));
-+	    return (1);
-+	}
-+	/*
-+	 * Map the result queue.
-+	 */
-+	isp->isp_result_dma = virt_to_bus(isp->isp_result);
-+#endif
-+	if (isp->isp_rquest_dma & 0x3f) {
-+	    isp_prt(isp, ISP_LOGERR, "Result Queue not on 64 byte boundary");
-+	    return (1);
-+        }
-+	MEMZERO(isp->isp_result, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
-+    }
-+
-+    if (IS_FC(isp)) {
-+	fcparam *fcp = isp->isp_param;
-+	if (fcp->isp_scratch == NULL) {
-+#if	LINUX_VERSION_CODE > KERNEL_VERSION(2,3,92)
-+	    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	    dma_addr_t busaddr;
-+	    fcp->isp_scratch =
-+		pci_alloc_consistent(pcs->pci_dev, ISP2100_SCRLEN, &busaddr);
-+	    if (fcp->isp_scratch == NULL) {
-+		isp_prt(isp, ISP_LOGERR, "unable to allocate scratch space");
-+		return (1);
-+	    }
-+	    fcp->isp_scdma = busaddr;
-+#else
-+	   /*
-+	    * Just get a page....
-+	    */
-+	    fcp->isp_scratch = (void *) GetPages(1);
-+	    if (fcp->isp_scratch == NULL) {
-+		isp_prt(isp, ISP_LOGERR, "unable to allocate scratch space");
-+		return (1);
-+	    }
-+	    fcp->isp_scdma = virt_to_bus((void *)fcp->isp_scratch);
-+#endif
-+	    MEMZERO(fcp->isp_scratch, ISP2100_SCRLEN);
-+	    if (fcp->isp_scdma & 0x7) {
-+		isp_prt(isp, ISP_LOGERR, "scratch space not 8 byte aligned");
-+		return (1);
-+	    }
-+	}
-+    }
-+    return (0);
-+}
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+/*
-+ * We need to handle DMA for target mode differently from initiator mode.
-+ * 
-+ * DMA mapping and construction and submission of CTIO Request Entries
-+ * and rendevous for completion are very tightly coupled because we start
-+ * out by knowing (per platform) how much data we have to move, but we
-+ * don't know, up front, how many DMA mapping segments will have to be used
-+ * cover that data, so we don't know how many CTIO Request Entries we
-+ * will end up using. Further, for performance reasons we may want to
-+ * (on the last CTIO for Fibre Channel), send status too (if all went well).
-+ *
-+ * The standard vector still goes through isp_pci_dmasetup, but the callback
-+ * for the DMA mapping routines comes here instead with the whole transfer
-+ * mapped and a pointer to a partially filled in already allocated request
-+ * queue entry. We finish the job.
-+ */
-+
-+static int tdma_mk(struct ispsoftc *, tmd_cmd_t *, ct_entry_t *,
-+    u_int16_t *, u_int16_t);
-+#define	STATUS_WITH_DATA        1
-+    
-+static int
-+tdma_mk(struct ispsoftc *isp, tmd_cmd_t *tcmd, ct_entry_t *cto,
-+    u_int16_t *nxtip, u_int16_t optr)
-+{
-+    static const char ctx[] =
-+	"CTIO[%x] lun %d for iid%d flgs 0x%x sts 0x%x ssts 0x%x res %u %s";
-+    struct scatterlist *sg;
-+    ct_entry_t *qe;
-+    u_int8_t scsi_status;
-+    u_int16_t curi, nxti, handle;
-+    u_int32_t sflags;
-+    int32_t resid;
-+    int nth_ctio, nctios, send_status, nseg;
-+
-+
-+    curi = isp->isp_reqidx;
-+    qe = (ct_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
-+
-+    cto->ct_xfrlen = 0;
-+    cto->ct_seg_count = 0;
-+    cto->ct_header.rqs_entry_count = 1;
-+    MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg));
-+
-+    if (tcmd->cd_xfrlen == 0) {
-+	ISP_TDQE(isp, "tdma_mk[no data]", curi, cto);
-+	isp_prt(isp, ISP_LOGTDEBUG1, ctx, cto->ct_fwhandle, (int) tcmd->cd_lun,
-+	    (int) cto->ct_iid, cto->ct_flags, cto->ct_status,
-+	    cto->ct_scsi_status, cto->ct_resid, "<END>");
-+	isp_put_ctio(isp, cto, qe);
-+	return (CMD_QUEUED);
-+    }
-+
-+    sg = tcmd->cd_data;
-+    nseg = 0;
-+    resid = (int32_t) tcmd->cd_xfrlen;
-+    while (resid > 0) {
-+	nseg++;
-+	resid -= sg_dma_len(sg);
-+	sg++;
-+    }
-+    sg = tcmd->cd_data;
-+#if	 LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	int new_seg_cnt;
-+	new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg,
-+	  (cto->ct_flags & CT_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
-+	if (new_seg_cnt == 0) {
-+	    isp_prt(isp, ISP_LOGWARN, "unable to dma map request");
-+	    cto->ct_resid = -ENOMEM;
-+	    return (CMD_COMPLETE);
-+	}
-+	if (new_seg_cnt != nseg) {
-+	    isp_prt(isp, ISP_LOGERR, "new seg cnt != old");
-+	    cto->ct_resid = -EINVAL;
-+	    return (CMD_COMPLETE);
-+	}
-+    }
-+#endif
-+    nctios = nseg / ISP_RQDSEG;
-+    if (nseg % ISP_RQDSEG) {
-+	nctios++;
-+    }
-+
-+    /*
-+     * Save handle, and potentially any SCSI status, which
-+     * we'll reinsert on the last CTIO we're going to send.
-+     */
-+    handle = cto->ct_syshandle;
-+    cto->ct_syshandle = 0;
-+    cto->ct_header.rqs_seqno = 0;
-+    send_status = (cto->ct_flags & CT_SENDSTATUS) != 0;
-+
-+    if (send_status) {
-+	sflags = cto->ct_flags & (CT_SENDSTATUS | CT_CCINCR);
-+	cto->ct_flags &= ~(CT_SENDSTATUS|CT_CCINCR);
-+	/*
-+	 * Preserve residual.
-+	 */
-+	resid = cto->ct_resid;
-+
-+	/*
-+	 * Save actual SCSI status.
-+	 */
-+	scsi_status = cto->ct_scsi_status;
-+
-+#ifndef	STATUS_WITH_DATA
-+	sflags |= CT_NO_DATA;
-+	/*
-+	 * We can't do a status at the same time as a data CTIO, so
-+	 * we need to synthesize an extra CTIO at this level.
-+	 */
-+	nctios++;
-+#endif
-+    } else {
-+	sflags = scsi_status = resid = 0;
-+    }
-+
-+    cto->ct_resid = 0;
-+    cto->ct_scsi_status = 0;
-+
-+    nxti = *nxtip;
-+
-+    for (nth_ctio = 0; nth_ctio < nctios; nth_ctio++) {
-+	int seglim;
-+
-+	seglim = nseg;
-+	if (seglim) {
-+	    int seg;
-+
-+	    if (seglim > ISP_RQDSEG)
-+		seglim = ISP_RQDSEG;
-+
-+	    for (seg = 0; seg < seglim; seg++, nseg--) {
-+		/*
-+		 * Unlike normal initiator commands, we don't do
-+		 * any swizzling here.
-+		 */
-+		cto->ct_dataseg[seg].ds_base = (u_int32_t) sg_dma_address(sg);
-+		cto->ct_dataseg[seg].ds_count = (u_int32_t) sg_dma_len(sg);
-+		cto->ct_xfrlen += sg_dma_len(sg);
-+		sg++;
-+	    }
-+	    cto->ct_seg_count = seg;
-+	} else {
-+	    /*
-+	     * This case should only happen when we're
-+	     * sending an extra CTIO with final status.
-+	     */
-+	    if (send_status == 0) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "tdma_mk ran out of segments, no status to send");
-+		return (CMD_EAGAIN);
-+	    }
-+	}
-+
-+	/*
-+	 * At this point, the fields ct_lun, ct_iid, ct_tagval, ct_tagtype, and
-+	 * ct_timeout have been carried over unchanged from what our caller had
-+	 * set.
-+	 *
-+	 * The dataseg fields and the seg_count fields we just got through
-+	 * setting. The data direction we've preserved all along and only
-+	 * clear it if we're now sending status.
-+	 */
-+
-+	if (nth_ctio == nctios - 1) {
-+	    /*
-+	     * We're the last in a sequence of CTIOs, so mark this
-+	     * CTIO and save the handle to the command such that when
-+	     * this CTIO completes we can free dma resources and
-+	     * do whatever else we need to do to finish the rest
-+	     * of the command.
-+	     */
-+	    cto->ct_syshandle = handle;
-+	    cto->ct_header.rqs_seqno = 1;
-+
-+	    if (send_status) {
-+		cto->ct_scsi_status = scsi_status;
-+		cto->ct_flags |= sflags;
-+		cto->ct_resid = resid;
-+	    }
-+	    if (send_status) {
-+		isp_prt(isp, ISP_LOGTDEBUG1, ctx, 
-+		    cto->ct_fwhandle, (int) tcmd->cd_lun, (int) cto->ct_iid,
-+		    cto->ct_flags, cto->ct_status, cto->ct_scsi_status,
-+		    cto->ct_resid, "<END>");
-+	    } else {
-+		isp_prt(isp, ISP_LOGTDEBUG1, ctx, 
-+		    cto->ct_fwhandle, (int) tcmd->cd_lun, (int) cto->ct_iid,
-+		    cto->ct_flags, cto->ct_status, cto->ct_scsi_status,
-+		    cto->ct_resid, "<MID>");
-+	    }
-+	    isp_put_ctio(isp, cto, qe);
-+	    ISP_TDQE(isp, "last tdma_mk", curi, cto);
-+	    if (nctios > 1) {
-+		MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
-+	    }
-+	} else {
-+	    ct_entry_t *oqe = qe;
-+
-+	    /*
-+	     * Make sure handle fields are clean
-+	     */
-+	    cto->ct_syshandle = 0;
-+	    cto->ct_header.rqs_seqno = 0;
-+
-+	    isp_prt(isp, ISP_LOGTDEBUG1,
-+		"CTIO[%x] lun%d for ID%d ct_flags 0x%x",
-+		cto->ct_fwhandle, (int) tcmd->cd_lun,
-+		(int) cto->ct_iid, cto->ct_flags);
-+
-+	    /*
-+	     * Get a new CTIO
-+	     */
-+	    qe = (ct_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
-+	    nxti = ISP_NXT_QENTRY(nxti, RQUEST_QUEUE_LEN(isp));
-+	    if (nxti == optr) {
-+		isp_prt(isp, ISP_LOGERR, "queue overflow in tdma_mk");
-+		return (CMD_EAGAIN);
-+	    }
-+
-+	   /*
-+	    * Now that we're done with the old CTIO,
-+	    * flush it out to the request queue.
-+	    */
-+	    ISP_TDQE(isp, "tdma_mk", curi, cto);
-+	    isp_put_ctio(isp, cto, oqe);
-+	    if (nth_ctio != 0) {
-+		MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
-+	    }
-+	    curi = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp));
-+
-+	    /*
-+	     * Reset some fields in the CTIO so we can reuse
-+	     * for the next one we'll flush to the request
-+	     * queue.
-+	     */
-+	    cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
-+	    cto->ct_header.rqs_entry_count = 1;
-+	    cto->ct_header.rqs_flags = 0;
-+	    cto->ct_status = 0;
-+	    cto->ct_scsi_status = 0;
-+	    cto->ct_xfrlen = 0;
-+	    cto->ct_resid = 0;
-+	    cto->ct_seg_count = 0;
-+	    MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg));
-+	}
-+    }
-+    *nxtip = nxti;
-+    return (CMD_QUEUED);
-+}
-+
-+static int tdma_mkfc(struct ispsoftc *, tmd_cmd_t *, ct2_entry_t *,
-+    u_int16_t *, u_int16_t);
-+
-+
-+/*
-+ * We're passed a pointer to a prototype ct2_entry_t.
-+ *
-+ * If it doesn't contain any data movement, it has to be for sending status,
-+ * possibly with Sense Data as well, so we send a single CTIO2. This should
-+ * be a Mode 1 CTIO2, and it's up to the caller to set up the Sense Data
-+ * and flags appropriately.
-+ *
-+ * If it does contain data movement, it may *also* be for sending status
-+ * (possibly with Sense Data also). It's possible to describe to the firmware
-+ * what we want in one CTIO2. However, under some conditions it is not,
-+ * so we must also send a *second* CTIO2 after the first one.
-+ *
-+ * If the data to be sent is in segments that exceeds that which we can
-+ * fit into a CTIO2 (likely, as there's only room for 3 segments), we
-+ * utilize normal continuation entries, which get pushed after the
-+ * first CTIO2, and possibly are followed by a final CTIO2.
-+ *
-+ * In any case, it's up to the caller to send us a Mode 0 CTIO2 describing
-+ * the data to be moved (if any) and the appropriate flags indicating
-+ * status. We'll clear and set as appropriate. We'll also check to see
-+ * whether Sense Data is attempting to be sent and retrieve it as appropriate.
-+ *
-+ * In all cases the caller should not assume that the prototype CTIO2
-+ * has been left unchanged.
-+ */
-+
-+static int
-+tdma_mkfc(struct ispsoftc *isp, tmd_cmd_t *tmd, ct2_entry_t *cto,
-+    u_int16_t *nxtip, u_int16_t optr)
-+{
-+    static const char ctx[] = 
-+	"CTIO2[%x] lun %d for iid %d flgs 0x%x sts 0x%x ssts 0x%x res %d %s";
-+    struct scatterlist *sg;
-+    void *qe;
-+    ct2_entry_t ct2, *cto2;
-+    u_int16_t swd, curi, nxti;
-+    u_int32_t bc;
-+    long xfcnt;	/* must be signed */
-+    int nseg, seg;
-+
-+    nxti = *nxtip;
-+    curi = isp->isp_reqidx;
-+    qe = ISP_QUEUE_ENTRY(isp->isp_rquest, curi);
-+    if (cto->ct_flags & CT2_FASTPOST) {
-+	if ((tmd->cd_hflags & (CDFH_STSVALID|CDFH_SNSVALID)) != CDFH_STSVALID) {
-+	    cto->ct_flags &= ~CT2_FASTPOST;
-+	}
-+    }
-+
-+    /*
-+     * Handle commands that transfer no data right away.
-+     */
-+    if (tmd->cd_xfrlen == 0) {
-+	if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE1) {
-+	    isp_prt(isp, ISP_LOGERR,
-+		"tdma_mkfc, a status CTIO2 without MODE1 set (0x%x)",
-+		cto->ct_flags);
-+	    cto->ct_resid = -EINVAL;
-+	    return (CMD_COMPLETE);
-+	}
-+	cto->ct_header.rqs_entry_count = 1;
-+	cto->ct_header.rqs_seqno = 1;
-+
-+	/* ct_syshandle contains the synchronization handle set by caller */
-+	/*
-+	 * We preserve ct_lun, ct_iid, ct_rxid. We set the data movement
-+	 * flags to NO DATA and clear relative offset flags. We preserve
-+	 * ct_resid and the response area. We assume that if there is
-+	 * associated sense data that it has been appropriately set by
-+	 * the caller.
-+	 */
-+	cto->ct_flags |= CT2_NO_DATA;
-+	if (cto->ct_resid > 0)
-+	    cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
-+	else if (cto->ct_resid < 0)
-+	    cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER;
-+	cto->ct_seg_count = 0;
-+	cto->ct_reloff = 0;
-+	isp_prt(isp, ISP_LOGTDEBUG1, ctx, cto->ct_rxid, (int) tmd->cd_lun,
-+	    cto->ct_iid, cto->ct_flags, cto->ct_status,
-+	    cto->rsp.m1.ct_scsi_status, cto->ct_resid, "<END>");
-+	isp_put_ctio2(isp, cto, qe);
-+	ISP_TDQE(isp, "tdma_mkfc[no data]", curi, qe);
-+	return (CMD_QUEUED);
-+    }
-+
-+    if ((cto->ct_flags & CT2_FLAG_MMASK) != CT2_FLAG_MODE0) {
-+	isp_prt(isp, ISP_LOGERR,
-+	    "tdma_mkfc, a data CTIO2 without MODE0 set (0x%x)", cto->ct_flags);
-+	cto->ct_resid = -EINVAL;
-+	return (CMD_COMPLETE);
-+    }
-+
-+   /*
-+    * First, count and map all S/G segments
-+    *
-+    * The byte counter has to be signed because
-+    * we can have descriptors that are, in fact,
-+    * longer than our data transfer count.
-+    */
-+    sg = tmd->cd_data;
-+    nseg = 0;
-+    xfcnt = tmd->cd_xfrlen;
-+    while (xfcnt > 0) {
-+        nseg++;
-+        xfcnt -= sg_dma_len(sg);
-+        sg++;
-+    }
-+    sg = tmd->cd_data;
-+#if	 LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+    {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	int new_seg_cnt;
-+	new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg,
-+	  (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
-+	if (new_seg_cnt == 0) {
-+	    isp_prt(isp, ISP_LOGWARN, "unable to dma map request");
-+	    cto->ct_resid = -ENOMEM;
-+	    return (CMD_COMPLETE);
-+	}
-+	if (new_seg_cnt != nseg) {
-+	    isp_prt(isp, ISP_LOGERR, "new seg cnt != old");
-+	    cto->ct_resid = -EINVAL;
-+	    return (CMD_COMPLETE);
-+	}
-+    }
-+#endif
-+
-+   /*
-+    * Second, figure out whether we need to send a final separate CTIO2
-+    *
-+    * The 2100/2200 firmware documentation indicates that if we have
-+    * good SCSI status (0), but still have a residual, we can still
-+    * describe this as part of a Mode 0 CTIO2. The 2300 firmware docs
-+    * seem to indicate that if we wish to convey a non-zero residual,
-+    * we can't do it as part of a Mode 0 CTIO2. To be safe, as well
-+    * as follow the most likely occurrences, we'll push a second
-+    * Mode 1 CTIO2 in any case that we have nonzero SCSI status
-+    * or a residual.
-+    */
-+    swd = cto->rsp.m0.ct_scsi_status;
-+
-+    if ((cto->ct_flags & CT2_SENDSTATUS) && ((swd & 0xf) || cto->ct_resid)) {
-+	cto2 = &ct2;
-+	/*
-+	 * Copy over CTIO2
-+	 */
-+	MEMCPY(cto2, cto, sizeof (ct2_entry_t));
-+
-+	/*
-+	 * Clear fields from first CTIO2 that now need to be cleared
-+	 */
-+	cto->ct_flags &= ~(CT2_SENDSTATUS|CT2_CCINCR|CT2_FASTPOST);
-+	cto->ct_resid = 0;
-+	cto->ct_syshandle = 0;
-+	cto->rsp.m0.ct_scsi_status = 0;
-+
-+	/*
-+	 * Reset fields in the second CTIO2 as appropriate.
-+	 */
-+	cto2->ct_flags &= ~(CT2_FLAG_MMASK|CT2_DATAMASK);
-+	cto2->ct_flags |= CT2_NO_DATA|CT2_NO_DATA|CT2_FLAG_MODE1;
-+	cto2->ct_seg_count = 0;
-+	cto2->ct_reloff = 0;
-+    	MEMZERO(&cto2->rsp, sizeof (cto2->rsp));
-+	cto2->rsp.m1.ct_scsi_status = swd;
-+	if ((swd & 0xf) == SCSI_CHECK && (swd & CT2_SNSLEN_VALID)) {
-+		MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, QLTM_SENSELEN);
-+                cto2->rsp.m1.ct_senselen = QLTM_SENSELEN;
-+                cto2->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
-+	}
-+    } else {
-+	cto2 = NULL;
-+    }
-+
-+    /*
-+     * Third, Fill in the data segments in the first CTIO2 itself.
-+     */
-+    xfcnt = tmd->cd_xfrlen;
-+    cto->ct_seg_count = nseg;
-+
-+    for (seg = 0; seg < min(nseg, ISP_RQDSEG_T2); seg++) {
-+	cto->rsp.m0.ct_dataseg[seg].ds_base = sg_dma_address(sg);
-+	bc = min(sg_dma_len(sg), xfcnt);
-+	cto->rsp.m0.ct_dataseg[seg].ds_count = bc;
-+	cto->rsp.m0.ct_xfrlen += bc;
-+	xfcnt -= bc;
-+	isp_prt(isp, ISP_LOGTDEBUG1, "  ent0[%d]%lx:%lu", seg,
-+	    (unsigned long)sg_dma_address(sg), (unsigned long)sg_dma_len(sg));
-+	sg++;
-+    }
-+
-+    /*
-+     * Now do any continuation segments that are required.
-+     */
-+    while (seg < nseg) {
-+	int curseg;
-+	ispcontreq_t local, *crq = &local;
-+
-+	qe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
-+	curi = nxti;
-+	nxti = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp));
-+	if (nxti == optr) {
-+	    isp_prt(isp, ISP_LOGTDEBUG0, 
-+		"tdma_mkfc: request queue overflow");
-+	    cto->ct_resid = -EAGAIN;
-+	    return (CMD_COMPLETE);
-+        }
-+	cto->ct_header.rqs_entry_count++;
-+	MEMZERO((void *)crq, sizeof (*crq));
-+	crq->req_header.rqs_entry_count = 1;
-+	crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
-+	for (curseg = 0; seg < nseg && curseg < ISP_CDSEG; curseg++, seg++) {
-+	    crq->req_dataseg[curseg].ds_base = sg_dma_address(sg);
-+	    bc = min(sg_dma_len(sg), xfcnt);
-+	    crq->req_dataseg[curseg].ds_count = bc;
-+	    cto->rsp.m0.ct_xfrlen += bc;
-+	    xfcnt -= bc;
-+	    isp_prt(isp, ISP_LOGTDEBUG1, "  ent%d[%d]%lx:%lu",
-+		cto->ct_header.rqs_entry_count - 1, curseg,
-+		(unsigned long)sg_dma_address(sg), (unsigned long)bc);
-+	    sg++;
-+	}
-+	isp_put_cont_req(isp, crq, (ispcontreq_t *)qe);
-+	MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
-+	ISP_TDQE(isp, "tdma_mkfc:cont", curi, cto);
-+    }
-+
-+    /*
-+     * If we have a final CTIO2, allocate and push *that*
-+     * onto the request queue.
-+     */
-+    if (cto2) {
-+	qe = (ct2_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
-+	curi = nxti;
-+	nxti = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp));
-+	if (nxti == optr) {
-+	    isp_prt(isp, ISP_LOGTDEBUG0, 
-+		"tdma_mkfc: request queue overflow");
-+	    cto->ct_resid = -EAGAIN;
-+	    return (CMD_COMPLETE);
-+        }
-+	MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
-+	isp_put_ctio2(isp, cto2, (ct2_entry_t *)qe);
-+	ISP_TDQE(isp, "tdma_mkfc:final", curi, cto2);
-+    }
-+    qe = ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
-+    isp_put_ctio2(isp, cto, qe);
-+    ISP_TDQE(isp, "tdma_mkfc", isp->isp_reqidx, cto);
-+    *nxtip = nxti;
-+    return (CMD_QUEUED);
-+}
-+#endif
-+
-+#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-+#define	FOURG_SEG(x)	(((u64) (x)) & 0xffffffff00000000ULL)
-+
-+static int
-+isp_pci_dmasetup(struct ispsoftc *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq,
-+    u_int16_t *nxi, u_int16_t optr)
-+{
-+    struct scatterlist *sg, *savesg;
-+    DMA_ADDR_T one_shot_addr, last_synthetic_addr;
-+    unsigned int one_shot_length, last_synthetic_count;
-+    int segcnt, seg, ovseg, seglim;
-+    void *h;
-+    u_int16_t nxti;
-+
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    if (rq->req_header.rqs_entry_type == RQSTYPE_CTIO ||
-+        rq->req_header.rqs_entry_type == RQSTYPE_CTIO2) {
-+	int s;
-+	if (IS_SCSI(isp))
-+	    s = tdma_mk(isp, (tmd_cmd_t *)Cmnd, (ct_entry_t *)rq, nxi, optr);
-+	else
-+	    s = tdma_mkfc(isp, (tmd_cmd_t *)Cmnd, (ct2_entry_t *)rq, nxi, optr);
-+	return (s);
-+   }
-+#endif
-+
-+    nxti = *nxi;
-+    h = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
-+
-+    if (Cmnd->sc_data_direction == SCSI_DATA_NONE ||
-+        Cmnd->request_bufflen == 0) {
-+	rq->req_seg_count = 1;
-+	goto mbxsync;
-+    }
-+
-+    if (IS_FC(isp)) {
-+	seglim = ISP_RQDSEG_T2;
-+	((ispreqt2_t *)rq)->req_totalcnt = Cmnd->request_bufflen;
-+	if (Cmnd->sc_data_direction == SCSI_DATA_WRITE) {
-+	    ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_OUT;
-+	} else if (Cmnd->sc_data_direction == SCSI_DATA_READ) {
-+	    ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_IN;
-+	} else {
-+	    isp_prt(isp, ISP_LOGERR,
-+		"unkown data direction (%x) for %d byte request (opcode 0x%x)",
-+	        Cmnd->sc_data_direction, Cmnd->request_bufflen, Cmnd->cmnd[0]);
-+	    XS_SETERR(Cmnd, HBA_BOTCH);
-+	    return (CMD_COMPLETE);
-+	}
-+    } else {
-+	if (Cmnd->cmd_len > 12)
-+	    seglim = 0;
-+	else
-+	    seglim = ISP_RQDSEG;
-+	if (Cmnd->sc_data_direction == SCSI_DATA_WRITE) {
-+	    rq->req_flags |= REQFLAG_DATA_OUT;
-+	} else if (Cmnd->sc_data_direction == SCSI_DATA_READ) {
-+	    rq->req_flags |= REQFLAG_DATA_IN;
-+	} else {
-+	    isp_prt(isp, ISP_LOGERR,
-+		"unkown data direction (%x) for %d byte request (opcode 0x%x)",
-+	        Cmnd->sc_data_direction, Cmnd->request_bufflen, Cmnd->cmnd[0]);
-+	    XS_SETERR(Cmnd, HBA_BOTCH);
-+	    return (CMD_COMPLETE);
-+	}
-+    }
-+
-+    one_shot_addr = (DMA_ADDR_T) 0;
-+    one_shot_length = 0;
-+    if ((segcnt = Cmnd->use_sg) == 0) {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	segcnt = 1;
-+	sg = NULL;
-+	one_shot_length = Cmnd->request_bufflen;
-+	one_shot_addr = pci_map_single(pcs->pci_dev,
-+	    Cmnd->request_buffer, Cmnd->request_bufflen,
-+	    scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
-+	QLA_HANDLE(Cmnd) = (DMA_HTYPE_T) one_shot_addr;
-+    } else {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
-+	sg = (struct scatterlist *) Cmnd->request_buffer;
-+	segcnt = pci_map_sg(pcs->pci_dev, sg, Cmnd->use_sg,
-+	    scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
-+    }
-+    if (segcnt == 0) {
-+	isp_prt(isp, ISP_LOGWARN, "unable to dma map request");
-+	XS_SETERR(Cmnd, HBA_BOTCH);
-+	return (CMD_EAGAIN);
-+    }
-+    savesg = sg;
-+
-+again:
-+    last_synthetic_count = 0;
-+    last_synthetic_addr = 0;
-+    for (seg = 0, rq->req_seg_count = 0;
-+	 seg < segcnt && rq->req_seg_count < seglim;
-+	 seg++, rq->req_seg_count++) {
-+	DMA_ADDR_T addr;
-+	unsigned int length;
-+
-+	if (sg) {
-+		length = QLA_SG_C(sg);
-+		addr = QLA_SG_A(sg);
-+		sg++;
-+	} else {
-+		length = one_shot_length;
-+		addr = one_shot_addr;
-+	}
-+
-+	if (ISP_A64 && IS_HIGH_ISP_ADDR(addr)) {
-+	   if (IS_FC(isp)) {
-+		if (rq->req_header.rqs_entry_type != RQSTYPE_T3RQS) {
-+			rq->req_header.rqs_entry_type = RQSTYPE_T3RQS;
-+			seglim = ISP_RQDSEG_T3;
-+			sg = savesg;
-+			goto again;
-+		}
-+	   } else {
-+		if (rq->req_header.rqs_entry_type != RQSTYPE_A64) {
-+			rq->req_header.rqs_entry_type = RQSTYPE_A64;
-+			seglim = ISP_RQDSEG_A64;
-+			sg = savesg;
-+			goto again;
-+		}
-+	   }
-+	}
-+	if (ISP_A64 && rq->req_header.rqs_entry_type == RQSTYPE_T3RQS) {
-+	    ispreqt3_t *rq3 = (ispreqt3_t *)rq;
-+	    rq3->req_dataseg[rq3->req_seg_count].ds_count = length;
-+	    rq3->req_dataseg[rq3->req_seg_count].ds_base = LOWD(addr);
-+	    rq3->req_dataseg[rq3->req_seg_count].ds_basehi = HIWD(addr);
-+	    /*
-+	     * Make sure we don't cross a 4GB boundary.
-+	     */
-+	    if (FOURG_SEG(addr) != FOURG_SEG(addr + length)) {
-+		isp_prt(isp, ISP_LOGDEBUG1, "seg0[%d]%llx:%u (TRUNC'd)",
-+		    rq->req_seg_count, (long long)addr, length);
-+		rq3->req_dataseg[rq3->req_seg_count].ds_count =
-+		    (unsigned int) (FOURG_SEG(addr + length) - addr);
-+		addr += rq3->req_dataseg[rq3->req_seg_count].ds_count;
-+		length -= rq3->req_dataseg[rq3->req_seg_count].ds_count;
-+		/*
-+		 * Do we have space to split it here?
-+		 */
-+		if (rq3->req_seg_count == seglim - 1) {
-+		    last_synthetic_count = length;
-+		    last_synthetic_addr = addr;
-+		} else {
-+		    rq3->req_seg_count++;
-+		    rq3->req_dataseg[rq3->req_seg_count].ds_count = length;
-+		    rq3->req_dataseg[rq3->req_seg_count].ds_base = LOWD(addr);
-+		    rq3->req_dataseg[rq3->req_seg_count].ds_basehi = HIWD(addr);
-+		}
-+	    }
-+	} else if (ISP_A64 && rq->req_header.rqs_entry_type == RQSTYPE_A64) {
-+	    ispreq64_t *rq6 = (ispreq64_t *)rq;
-+	    rq6->req_dataseg[rq6->req_seg_count].ds_count = length;
-+	    rq6->req_dataseg[rq6->req_seg_count].ds_base = LOWD(addr);
-+	    rq6->req_dataseg[rq6->req_seg_count].ds_basehi = HIWD(addr);
-+	    /*
-+	     * Make sure we don't cross a 4GB boundary.
-+	     */
-+	    if (FOURG_SEG(addr) != FOURG_SEG(addr + length)) {
-+		isp_prt(isp, ISP_LOGDEBUG1, "seg0[%d]%llx:%u (TRUNC'd)",
-+		    rq->req_seg_count, (long long)addr, length);
-+		rq6->req_dataseg[rq6->req_seg_count].ds_count =
-+		    (unsigned int) (FOURG_SEG(addr + length) - addr);
-+		addr += rq6->req_dataseg[rq6->req_seg_count].ds_count;
-+		length -= rq6->req_dataseg[rq6->req_seg_count].ds_count;
-+		/*
-+		 * Do we have space to split it here?
-+		 */
-+		if (rq6->req_seg_count == seglim - 1) {
-+		    last_synthetic_count = length;
-+		    last_synthetic_addr = LOWD(addr);
-+		} else {
-+		    rq6->req_seg_count++;
-+		    rq6->req_dataseg[rq6->req_seg_count].ds_count = length;
-+		    rq6->req_dataseg[rq6->req_seg_count].ds_base = LOWD(addr);
-+		    rq6->req_dataseg[rq6->req_seg_count].ds_basehi = HIWD(addr);
-+		}
-+	    }
-+	} else if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
-+	    ispreqt2_t *rq2 = (ispreqt2_t *)rq;
-+	    rq2->req_dataseg[rq2->req_seg_count].ds_count = length;
-+	    rq2->req_dataseg[rq2->req_seg_count].ds_base = addr;
-+	} else {
-+	    rq->req_dataseg[rq->req_seg_count].ds_count = length;
-+	    rq->req_dataseg[rq->req_seg_count].ds_base = addr;
-+	}
-+	isp_prt(isp, ISP_LOGDEBUG1, "seg0[%d]%llx:%u",
-+	    rq->req_seg_count, (long long)addr, length);
-+    }
-+
-+    if (seg == segcnt && last_synthetic_count == 0) {
-+	goto mbxsync;
-+    }
-+
-+    do {
-+	int lim;
-+	u_int16_t curip;
-+	ispcontreq_t local, *crq = &local, *qep;
-+
-+	curip = nxti;
-+	qep = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip);
-+	nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp));
-+	if (nxti == optr) {
-+	    isp_pci_dmateardown(isp, Cmnd, 0);
-+	    isp_prt(isp, ISP_LOGDEBUG0, "out of space for continuations");
-+	    XS_SETERR(Cmnd, HBA_BOTCH);
-+	    return (CMD_EAGAIN);
-+	}
-+	rq->req_header.rqs_entry_count++;
-+	MEMZERO((void *)crq, sizeof (*crq));
-+	crq->req_header.rqs_entry_count = 1;
-+	if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS ||
-+	    rq->req_header.rqs_entry_type == RQSTYPE_A64) {
-+	    crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
-+	    lim = ISP_CDSEG64;
-+	} else {
-+	    crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
-+	    lim = ISP_CDSEG;
-+	}
-+
-+	for (ovseg = 0; (seg < segcnt || last_synthetic_count) && ovseg < lim;
-+	    rq->req_seg_count++, seg++, ovseg++, sg++) {
-+	    DMA_ADDR_T addr;
-+	    unsigned int length;
-+
-+	    if (last_synthetic_count) {
-+		addr = last_synthetic_addr;
-+		length = last_synthetic_count;
-+		last_synthetic_count = 0;
-+		sg--;
-+		seg--;
-+	    } else {
-+		addr = QLA_SG_A(sg);
-+		length = QLA_SG_C(sg);
-+	    }
-+
-+	    if (length == 0) {
-+		panic("zero length s-g element at line %d", __LINE__);
-+	    }
-+	    isp_prt(isp, ISP_LOGDEBUG1, "seg%d[%d]%llx:%u",
-+		rq->req_header.rqs_entry_count-1, ovseg,
-+	    	(unsigned long long) addr, length);
-+
-+	    if (crq->req_header.rqs_entry_type == RQSTYPE_A64_CONT) {
-+		ispcontreq64_t *xrq = (ispcontreq64_t *) crq;
-+		xrq->req_dataseg[ovseg].ds_count = length;
-+		xrq->req_dataseg[ovseg].ds_base = LOWD(addr);
-+		xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
-+		/*
-+		 * Make sure we don't cross a 4GB boundary.
-+		 */
-+		if (FOURG_SEG(addr) != FOURG_SEG(addr + length)) {
-+		    isp_prt(isp, ISP_LOGDEBUG1, "seg0[%d]%llx:%u (TRUNC'd)",
-+			rq->req_seg_count, (long long)addr, length);
-+		    xrq->req_dataseg[ovseg].ds_count =
-+			(unsigned int) (FOURG_SEG(addr + length) - addr);
-+		    addr += xrq->req_dataseg[ovseg].ds_count;
-+		    length -= xrq->req_dataseg[ovseg].ds_count;
-+		    /*
-+		     * Do we have space to split it here?
-+		     */
-+		    if (ovseg == lim - 1) {
-+			last_synthetic_count = length;
-+			last_synthetic_addr = addr;
-+		    } else {
-+			ovseg++;
-+			xrq->req_dataseg[ovseg].ds_count = length;
-+			xrq->req_dataseg[ovseg].ds_base = LOWD(addr);
-+			xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
-+		    }
-+		}
-+		continue;
-+	    }
-+	    /*
-+	     * We get here if we're a 32 bit continuation entry.
-+	     * We also check for being over 32 bits with our PCI
-+	     * address. If we are, we set ourselves up to do 64
-+	     * bit addressing and start the whole mapping process
-+	     * all over again- we apparently can't really mix types
-+	     */
-+	    if (ISP_A64 && IS_HIGH_ISP_ADDR(addr)) {
-+		if (IS_FC(isp)) {
-+		    rq->req_header.rqs_entry_type = RQSTYPE_T3RQS;
-+		    seglim = ISP_RQDSEG_T3;
-+		} else {
-+		    rq->req_header.rqs_entry_type = RQSTYPE_A64;
-+		    seglim = ISP_RQDSEG_A64;
-+		}
-+		sg = savesg;
-+		nxti = *nxi;
-+		rq->req_header.rqs_entry_count = 1;
-+		goto again;
-+	    }
-+	    crq->req_dataseg[ovseg].ds_count = length;
-+	    crq->req_dataseg[ovseg].ds_base = addr;
-+	}
-+	MEMORYBARRIER(isp, SYNC_REQUEST, curip, QENTRY_LEN);
-+	if (crq->req_header.rqs_entry_type == RQSTYPE_A64_CONT) {
-+	    isp_put_cont64_req(isp,
-+		(ispcontreq64_t *)crq, (ispcontreq64_t *)qep);
-+	} else {
-+	    isp_put_cont_req(isp, crq, qep);
-+	}
-+    } while (seg < segcnt || last_synthetic_count);
-+mbxsync:
-+    if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS) {
-+	isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) h);
-+    } else if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
-+	isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) h);
-+    } else {
-+	isp_put_request(isp, (ispreq_t *) rq, (ispreq_t *) h);
-+    }
-+    *nxi = nxti;
-+    return (CMD_QUEUED);
-+}
-+
-+static void
-+isp_pci_dmateardown(struct ispsoftc *isp, Scsi_Cmnd *Cmnd, u_int16_t handle)
-+{
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    if (Cmnd->sc_magic != SCSI_CMND_MAGIC) {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
-+	tmd_cmd_t *tmd = (tmd_cmd_t *) Cmnd;
-+	struct scatterlist *sg = tmd->cd_data;
-+	int nseg = 0;
-+
-+	while (sg->address) {
-+		nseg++;
-+		sg++;
-+	}
-+        pci_unmap_sg(pcs->pci_dev, tmd->cd_data, nseg,
-+	    (tmd->cd_hflags & CDFH_DATA_IN)? PCI_DMA_TODEVICE :
-+	    PCI_DMA_FROMDEVICE);
-+    } else
-+#endif
-+    if (Cmnd->sc_data_direction != SCSI_DATA_NONE) {
-+	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
-+	if (Cmnd->use_sg) {
-+	    pci_unmap_sg(pcs->pci_dev, (struct scatterlist *)Cmnd->buffer,
-+		Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
-+	} else if (Cmnd->request_bufflen) {
-+	    DMA_ADDR_T handle = (DMA_ADDR_T) QLA_HANDLE(Cmnd);
-+	    pci_unmap_single(pcs->pci_dev, handle, Cmnd->request_bufflen,
-+		scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
-+	}
-+    }
-+}
-+
-+#else
-+
-+static int
-+isp_pci_dmasetup(struct ispsoftc *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq,
-+    u_int16_t *nxi, u_int16_t optr)
-+{
-+    struct scatterlist *sg;
-+    DMA_ADDR_T one_shot_addr;
-+    unsigned int one_shot_length;
-+    int segcnt, seg, ovseg, seglim;
-+    void *h;
-+    u_int16_t nxti;
-+
-+#ifdef	LINUX_ISP_TARGET_MODE
-+    if (rq->req_header.rqs_entry_type == RQSTYPE_CTIO ||
-+        rq->req_header.rqs_entry_type == RQSTYPE_CTIO2) {
-+	int s;
-+	if (IS_SCSI(isp))
-+	    s = tdma_mk(isp, (tmd_cmd_t *)Cmnd, (ct_entry_t *)rq, nxi, optr);
-+	else
-+	    s = tdma_mkfc(isp, (tmd_cmd_t *)Cmnd, (ct2_entry_t *)rq, nxi, optr);
-+	return (s);
-+   }
-+#endif
-+
-+    nxti = *nxi;
-+    h = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
-+
-+    if (Cmnd->request_bufflen == 0) {
-+	rq->req_seg_count = 1;
-+	goto mbxsync;
-+    }
-+
-+    if (IS_FC(isp)) {
-+	if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS)
-+	    seglim = ISP_RQDSEG_T3;
-+	else
-+	    seglim = ISP_RQDSEG_T2;
-+	((ispreqt2_t *)rq)->req_totalcnt = Cmnd->request_bufflen;
-+	/*
-+	 * Linux doesn't make it easy to tell which direction
-+	 * the data is expected to go, and you really need to
-+	 * know this for FC. We'll have to assume that some
-+	 * of these commands that might be used for writes
-+	 * our outbounds and all else are inbound.
-+	 */
-+	switch (Cmnd->cmnd[0]) {
-+	case FORMAT_UNIT:
-+	case WRITE_6:
-+	case MODE_SELECT:
-+	case SEND_DIAGNOSTIC:
-+	case WRITE_10:
-+	case WRITE_BUFFER:
-+	case WRITE_LONG:
-+	case WRITE_SAME:
-+	case MODE_SELECT_10:
-+	case WRITE_12:
-+	case WRITE_VERIFY_12:
-+	case SEND_VOLUME_TAG:
-+	    ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_OUT;
-+	    break;
-+	default:
-+	    ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_IN;
-+	}
-+    } else {
-+	if (Cmnd->cmd_len > 12)
-+	    seglim = 0;
-+	else
-+	    seglim = ISP_RQDSEG;
-+	rq->req_flags |=  REQFLAG_DATA_OUT | REQFLAG_DATA_IN;
-+    }
-+
-+    one_shot_addr = (DMA_ADDR_T) 0;
-+    one_shot_length = 0;
-+    if ((segcnt = Cmnd->use_sg) == 0) {
-+	segcnt = 1;
-+	sg = NULL;
-+	one_shot_length = Cmnd->request_bufflen;
-+	one_shot_addr = virt_to_bus(Cmnd->request_buffer);
-+    } else {
-+	sg = (struct scatterlist *) Cmnd->request_buffer;
-+    }
-+    if (segcnt == 0) {
-+	isp_prt(isp, ISP_LOGWARN, "unable to dma map request");
-+	XS_SETERR(Cmnd, HBA_BOTCH);
-+	return (CMD_EAGAIN);
-+    }
-+
-+    for (seg = 0, rq->req_seg_count = 0;
-+	 seg < segcnt && rq->req_seg_count < seglim;
-+	 seg++, rq->req_seg_count++) {
-+	DMA_ADDR_T addr;
-+	unsigned int length;
-+
-+	if (sg) {
-+		length = QLA_SG_C(sg);
-+		addr = QLA_SG_A(sg);
-+		sg++;
-+	} else {
-+		length = one_shot_length;
-+		addr = one_shot_addr;
-+	}
-+
-+	if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
-+	    ispreqt2_t *rq2 = (ispreqt2_t *)rq;
-+	    rq2->req_dataseg[rq2->req_seg_count].ds_count = length;
-+	    rq2->req_dataseg[rq2->req_seg_count].ds_base = addr;
-+	} else {
-+	    rq->req_dataseg[rq->req_seg_count].ds_count = length;
-+	    rq->req_dataseg[rq->req_seg_count].ds_base = addr;
-+	}
-+	isp_prt(isp, ISP_LOGDEBUG1, "seg0[%d]%llx:%u from %p", seg,
-+	    (long long)addr, length, sg? sg->address : Cmnd->request_buffer);
-+    }
-+
-+    if (seg == segcnt) {
-+	goto mbxsync;
-+    }
-+
-+    do {
-+	int lim;
-+	u_int16_t curip;
-+	ispcontreq_t local, *crq = &local, *qep;
-+
-+	curip = nxti;
-+	qep = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip);
-+	nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp));
-+	if (nxti == optr) {
-+	    isp_prt(isp, ISP_LOGDEBUG0, "out of space for continuations");
-+	    XS_SETERR(Cmnd, HBA_BOTCH);
-+	    return (CMD_EAGAIN);
-+	}
-+	rq->req_header.rqs_entry_count++;
-+	MEMZERO((void *)crq, sizeof (*crq));
-+	crq->req_header.rqs_entry_count = 1;
-+	if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS) {
-+	    lim = ISP_CDSEG64;
-+	    crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
-+	} else {
-+	    lim = ISP_CDSEG;
-+	    crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
-+	}
-+
-+	for (ovseg = 0; seg < segcnt && ovseg < lim;
-+	     rq->req_seg_count++, seg++, ovseg++, sg++) {
-+	    if (sg_dma_len(sg) == 0) {
-+		panic("zero length s-g element at line %d", __LINE__);
-+	    }
-+	    crq->req_dataseg[ovseg].ds_count = QLA_SG_C(sg);
-+	    crq->req_dataseg[ovseg].ds_base = QLA_SG_A(sg);
-+	    isp_prt(isp, ISP_LOGDEBUG1, "seg%d[%d]%llx:%u from %p",
-+		rq->req_header.rqs_entry_count-1, ovseg,
-+	    	(unsigned long long) QLA_SG_A(sg), QLA_SG_C(sg), sg->address);
-+	}
-+	MEMORYBARRIER(isp, SYNC_REQUEST, curip, QENTRY_LEN);
-+	isp_put_cont_req(isp, crq, qep);
-+    } while (seg < segcnt);
-+mbxsync:
-+    if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS) {
-+	isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) h);
-+    } else if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
-+	isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) h);
-+    } else {
-+	isp_put_request(isp, (ispreq_t *) rq, (ispreq_t *) h);
-+    }
-+    *nxi = nxti;
-+    return (CMD_QUEUED);
-+}
-+#endif
-+
-+static void
-+isp_pci_reset1(struct ispsoftc *isp)
-+{
-+    isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
-+    ENABLE_INTS(isp);
-+    isp->mbintsok = 1;
-+}
-+
-+static void
-+isp_pci_dumpregs(struct ispsoftc *isp, const char *msg)
-+{
-+    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    
-+    u_int16_t csr;
-+
-+    pci_read_config_word(pcs->pci_dev, PCI_COMMAND, &csr);
-+    printk("%s: ", isp->isp_name);
-+    if (msg)
-+	printk("%s\n", msg);
-+    if (IS_SCSI(isp))
-+	printk("    biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
-+    else
-+	printk("    biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
-+    printk(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
-+	   ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
-+    printk("risc_hccr=%x\n", ISP_READ(isp, HCCR));
-+    if (IS_SCSI(isp)) {
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
-+	printk("    cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
-+	       ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
-+	       ISP_READ(isp, CDMA_FIFO_STS));
-+	printk("    ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n",
-+	       ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS),
-+	       ISP_READ(isp, DDMA_FIFO_STS));
-+	printk("    sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n",
-+	       ISP_READ(isp, SXP_INTERRUPT),
-+	       ISP_READ(isp, SXP_GROSS_ERR),
-+	       ISP_READ(isp, SXP_PINS_CTRL));
-+	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
-+    }
-+    printk("    mbox regs: %x %x %x %x %x\n",
-+	   ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1),
-+	   ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3),
-+	   ISP_READ(isp, OUTMAILBOX4));
-+    printk("    PCI Status Command/Status=%x\n", csr);
-+}
-+
-+#ifdef	MODULE
-+MODULE_PARM(isp_pci_mapmem, "i");
-+#endif
-+/*
-+ * mode: c
-+ * Local variables:
-+ * c-indent-level: 4
-+ * c-brace-imaginary-offset: 0
-+ * c-brace-offset: -4
-+ * c-argdecl-indent: 4
-+ * c-label-offset: -4
-+ * c-continued-statement-offset: 4
-+ * c-continued-brace-offset: 0
-+ * End:
-+ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/ispreg.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,1011 @@
-+/* @(#)ispreg.h 1.6 */
-+/*
-+ * Machine Independent (well, as best as possible) register
-+ * definitions for Qlogic ISP SCSI adapters.
-+ *
-+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+#ifndef	_ISPREG_H
-+#define	_ISPREG_H
-+
-+/*
-+ * Hardware definitions for the Qlogic ISP  registers.
-+ */
-+
-+/*
-+ * This defines types of access to various registers.
-+ *
-+ *  	R:		Read Only
-+ *	W:		Write Only
-+ *	RW:		Read/Write
-+ *
-+ *	R*, W*, RW*:	Read Only, Write Only, Read/Write, but only
-+ *			if RISC processor in ISP is paused.
-+ */
-+
-+/*
-+ * Offsets for various register blocks.
-+ *
-+ * Sad but true, different architectures have different offsets.
-+ *
-+ * Don't be alarmed if none of this makes sense. The original register
-+ * layout set some defines in a certain pattern. Everything else has been
-+ * grafted on since. For example, the ISP1080 manual will state that DMA
-+ * registers start at 0x80 from the base of the register address space.
-+ * That's true, but for our purposes, we define DMA_REGS_OFF for the 1080
-+ * to start at offset 0x60 because the DMA registers are all defined to
-+ * be DMA_BLOCK+0x20 and so on. Clear?
-+ */
-+
-+#define	BIU_REGS_OFF			0x00
-+
-+#define	PCI_MBOX_REGS_OFF		0x70
-+#define	PCI_MBOX_REGS2100_OFF		0x10
-+#define	PCI_MBOX_REGS2300_OFF		0x40
-+#define	SBUS_MBOX_REGS_OFF		0x80
-+
-+#define	PCI_SXP_REGS_OFF		0x80
-+#define	SBUS_SXP_REGS_OFF		0x200
-+
-+#define	PCI_RISC_REGS_OFF		0x80
-+#define	SBUS_RISC_REGS_OFF		0x400
-+
-+/* Bless me! Chip designers have putzed it again! */
-+#define	ISP1080_DMA_REGS_OFF		0x60
-+#define	DMA_REGS_OFF			0x00	/* same as BIU block */
-+
-+#define	SBUS_REGSIZE			0x450
-+#define	PCI_REGSIZE			0x100
-+
-+/*
-+ * NB:	The *_BLOCK definitions have no specific hardware meaning.
-+ *	They serve simply to note to the MD layer which block of
-+ *	registers offsets are being accessed.
-+ */
-+#define	_NREG_BLKS	5
-+#define	_BLK_REG_SHFT	13
-+#define	_BLK_REG_MASK	(7 << _BLK_REG_SHFT)
-+#define	BIU_BLOCK	(0 << _BLK_REG_SHFT)
-+#define	MBOX_BLOCK	(1 << _BLK_REG_SHFT)
-+#define	SXP_BLOCK	(2 << _BLK_REG_SHFT)
-+#define	RISC_BLOCK	(3 << _BLK_REG_SHFT)
-+#define	DMA_BLOCK	(4 << _BLK_REG_SHFT)
-+
-+/*
-+ * Bus Interface Block Register Offsets
-+ */
-+
-+#define	BIU_ID_LO	(BIU_BLOCK+0x0)		/* R  : Bus ID, Low */
-+#define		BIU2100_FLASH_ADDR	(BIU_BLOCK+0x0)
-+#define	BIU_ID_HI	(BIU_BLOCK+0x2)		/* R  : Bus ID, High */
-+#define		BIU2100_FLASH_DATA	(BIU_BLOCK+0x2)
-+#define	BIU_CONF0	(BIU_BLOCK+0x4)		/* R  : Bus Configuration #0 */
-+#define	BIU_CONF1	(BIU_BLOCK+0x6)		/* R  : Bus Configuration #1 */
-+#define		BIU2100_CSR		(BIU_BLOCK+0x6)
-+#define	BIU_ICR		(BIU_BLOCK+0x8)		/* RW : Bus Interface Ctrl */
-+#define	BIU_ISR		(BIU_BLOCK+0xA)		/* R  : Bus Interface Status */
-+#define	BIU_SEMA	(BIU_BLOCK+0xC)		/* RW : Bus Semaphore */
-+#define	BIU_NVRAM	(BIU_BLOCK+0xE)		/* RW : Bus NVRAM */
-+/*
-+ * These are specific to the 2300.
-+ *
-+ * They *claim* you can read BIU_R2HSTSLO with a full 32 bit access
-+ * and get both registers, but I'm a bit dubious about that. But the
-+ * point here is that the top 16 bits are firmware defined bits that
-+ * the RISC processor uses to inform the host about something- usually
-+ * something which was nominally in a mailbox register.
-+ */
-+#define	BIU_REQINP	(BIU_BLOCK+0x10)	/* Request Queue In */
-+#define	BIU_REQOUTP	(BIU_BLOCK+0x12)	/* Request Queue Out */
-+#define	BIU_RSPINP	(BIU_BLOCK+0x14)	/* Response Queue In */
-+#define	BIU_RSPOUTP	(BIU_BLOCK+0x16)	/* Response Queue Out */
-+
-+#define	BIU_R2HSTSLO	(BIU_BLOCK+0x18)
-+#define	BIU_R2HSTSHI	(BIU_BLOCK+0x1A)
-+
-+#define	BIU_R2HST_INTR		(1 << 15)	/* RISC to Host Interrupt */
-+#define	BIU_R2HST_PAUSED	(1 <<  8)	/* RISC paused */
-+#define	BIU_R2HST_ISTAT_MASK	0x3f		/* intr information && status */
-+#define		ISPR2HST_ROM_MBX_OK	0x1	/* ROM mailbox cmd done ok */
-+#define		ISPR2HST_ROM_MBX_FAIL	0x2	/* ROM mailbox cmd done fail */
-+#define		ISPR2HST_MBX_OK		0x10	/* mailbox cmd done ok */
-+#define		ISPR2HST_MBX_FAIL	0x11	/* mailbox cmd done fail */
-+#define		ISPR2HST_ASYNC_EVENT	0x12	/* Async Event */
-+#define		ISPR2HST_RSPQ_UPDATE	0x13	/* Response Queue Update */
-+#define		ISPR2HST_RQST_UPDATE	0x14	/* Resquest Queue Update */
-+#define		ISPR2HST_RIO_16		0x15	/* RIO 1-16 */
-+#define		ISPR2HST_FPOST		0x16	/* Low 16 bits fast post */
-+#define		ISPR2HST_FPOST_CTIO	0x17	/* Low 16 bits fast post ctio */
-+
-+#define	DFIFO_COMMAND	(BIU_BLOCK+0x60)	/* RW : Command FIFO Port */
-+#define		RDMA2100_CONTROL	DFIFO_COMMAND
-+#define	DFIFO_DATA	(BIU_BLOCK+0x62)	/* RW : Data FIFO Port */
-+
-+/*
-+ * Putzed DMA register layouts.
-+ */
-+#define	CDMA_CONF	(DMA_BLOCK+0x20)	/* RW*: DMA Configuration */
-+#define		CDMA2100_CONTROL	CDMA_CONF
-+#define	CDMA_CONTROL	(DMA_BLOCK+0x22)	/* RW*: DMA Control */
-+#define	CDMA_STATUS 	(DMA_BLOCK+0x24)	/* R  : DMA Status */
-+#define	CDMA_FIFO_STS	(DMA_BLOCK+0x26)	/* R  : DMA FIFO Status */
-+#define	CDMA_COUNT	(DMA_BLOCK+0x28)	/* RW*: DMA Transfer Count */
-+#define	CDMA_ADDR0	(DMA_BLOCK+0x2C)	/* RW*: DMA Address, Word 0 */
-+#define	CDMA_ADDR1	(DMA_BLOCK+0x2E)	/* RW*: DMA Address, Word 1 */
-+#define	CDMA_ADDR2	(DMA_BLOCK+0x30)	/* RW*: DMA Address, Word 2 */
-+#define	CDMA_ADDR3	(DMA_BLOCK+0x32)	/* RW*: DMA Address, Word 3 */
-+
-+#define	DDMA_CONF	(DMA_BLOCK+0x40)	/* RW*: DMA Configuration */
-+#define		TDMA2100_CONTROL	DDMA_CONF
-+#define	DDMA_CONTROL	(DMA_BLOCK+0x42)	/* RW*: DMA Control */
-+#define	DDMA_STATUS	(DMA_BLOCK+0x44)	/* R  : DMA Status */
-+#define	DDMA_FIFO_STS	(DMA_BLOCK+0x46)	/* R  : DMA FIFO Status */
-+#define	DDMA_COUNT_LO	(DMA_BLOCK+0x48)	/* RW*: DMA Xfer Count, Low */
-+#define	DDMA_COUNT_HI	(DMA_BLOCK+0x4A)	/* RW*: DMA Xfer Count, High */
-+#define	DDMA_ADDR0	(DMA_BLOCK+0x4C)	/* RW*: DMA Address, Word 0 */
-+#define	DDMA_ADDR1	(DMA_BLOCK+0x4E)	/* RW*: DMA Address, Word 1 */
-+/* these are for the 1040A cards */
-+#define	DDMA_ADDR2	(DMA_BLOCK+0x50)	/* RW*: DMA Address, Word 2 */
-+#define	DDMA_ADDR3	(DMA_BLOCK+0x52)	/* RW*: DMA Address, Word 3 */
-+
-+
-+/*
-+ * Bus Interface Block Register Definitions
-+ */
-+/* BUS CONFIGURATION REGISTER #0 */
-+#define	BIU_CONF0_HW_MASK		0x000F	/* Hardware revision mask */
-+/* BUS CONFIGURATION REGISTER #1 */
-+
-+#define	BIU_SBUS_CONF1_PARITY		0x0100 	/* Enable parity checking */
-+#define	BIU_SBUS_CONF1_FCODE_MASK	0x00F0	/* Fcode cycle mask */
-+
-+#define	BIU_PCI_CONF1_FIFO_128		0x0040	/* 128 bytes FIFO threshold */
-+#define	BIU_PCI_CONF1_FIFO_64		0x0030	/* 64 bytes FIFO threshold */
-+#define	BIU_PCI_CONF1_FIFO_32		0x0020	/* 32 bytes FIFO threshold */
-+#define	BIU_PCI_CONF1_FIFO_16		0x0010	/* 16 bytes FIFO threshold */
-+#define	BIU_BURST_ENABLE		0x0004	/* Global enable Bus bursts */
-+#define	BIU_SBUS_CONF1_FIFO_64		0x0003	/* 64 bytes FIFO threshold */
-+#define	BIU_SBUS_CONF1_FIFO_32		0x0002	/* 32 bytes FIFO threshold */
-+#define	BIU_SBUS_CONF1_FIFO_16		0x0001	/* 16 bytes FIFO threshold */
-+#define	BIU_SBUS_CONF1_FIFO_8		0x0000	/* 8 bytes FIFO threshold */
-+#define	BIU_SBUS_CONF1_BURST8		0x0008 	/* Enable 8-byte  bursts */
-+#define	BIU_PCI_CONF1_SXP		0x0008	/* SXP register select */
-+
-+#define	BIU_PCI1080_CONF1_SXP0		0x0100	/* SXP bank #1 select */
-+#define	BIU_PCI1080_CONF1_SXP1		0x0200	/* SXP bank #2 select */
-+#define	BIU_PCI1080_CONF1_DMA		0x0300	/* DMA bank select */
-+
-+/* ISP2100 Bus Control/Status Register */
-+
-+#define	BIU2100_ICSR_REGBSEL		0x30	/* RW: register bank select */
-+#define		BIU2100_RISC_REGS	(0 << 4)	/* RISC Regs */
-+#define		BIU2100_FB_REGS		(1 << 4)	/* FrameBuffer Regs */
-+#define		BIU2100_FPM0_REGS	(2 << 4)	/* FPM 0 Regs */
-+#define		BIU2100_FPM1_REGS	(3 << 4)	/* FPM 1 Regs */
-+#define	BIU2100_PCI64			0x04	/*  R: 64 Bit PCI slot */
-+#define	BIU2100_FLASH_ENABLE		0x02	/* RW: Enable Flash RAM */
-+#define	BIU2100_SOFT_RESET		0x01
-+/* SOFT RESET FOR ISP2100 is same bit, but in this register, not ICR */
-+
-+
-+/* BUS CONTROL REGISTER */
-+#define	BIU_ICR_ENABLE_DMA_INT		0x0020	/* Enable DMA interrupts */
-+#define	BIU_ICR_ENABLE_CDMA_INT		0x0010	/* Enable CDMA interrupts */
-+#define	BIU_ICR_ENABLE_SXP_INT		0x0008	/* Enable SXP interrupts */
-+#define	BIU_ICR_ENABLE_RISC_INT		0x0004	/* Enable Risc interrupts */
-+#define	BIU_ICR_ENABLE_ALL_INTS		0x0002	/* Global enable all inter */
-+#define	BIU_ICR_SOFT_RESET		0x0001	/* Soft Reset of ISP */
-+
-+#define	BIU2100_ICR_ENABLE_ALL_INTS	0x8000
-+#define	BIU2100_ICR_ENA_FPM_INT		0x0020
-+#define	BIU2100_ICR_ENA_FB_INT		0x0010
-+#define	BIU2100_ICR_ENA_RISC_INT	0x0008
-+#define	BIU2100_ICR_ENA_CDMA_INT	0x0004
-+#define	BIU2100_ICR_ENABLE_RXDMA_INT	0x0002
-+#define	BIU2100_ICR_ENABLE_TXDMA_INT	0x0001
-+#define	BIU2100_ICR_DISABLE_ALL_INTS	0x0000
-+
-+#define	ENABLE_INTS(isp)	(IS_SCSI(isp))?  \
-+ ISP_WRITE(isp, BIU_ICR, BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS) : \
-+ ISP_WRITE(isp, BIU_ICR, BIU2100_ICR_ENA_RISC_INT | BIU2100_ICR_ENABLE_ALL_INTS)
-+
-+#define	INTS_ENABLED(isp)	((IS_SCSI(isp))?  \
-+ (ISP_READ(isp, BIU_ICR) & (BIU_ICR_ENABLE_RISC_INT|BIU_ICR_ENABLE_ALL_INTS)) :\
-+ (ISP_READ(isp, BIU_ICR) & \
-+	(BIU2100_ICR_ENA_RISC_INT|BIU2100_ICR_ENABLE_ALL_INTS)))
-+
-+#define	DISABLE_INTS(isp)	ISP_WRITE(isp, BIU_ICR, 0)
-+
-+/* BUS STATUS REGISTER */
-+#define	BIU_ISR_DMA_INT			0x0020	/* DMA interrupt pending */
-+#define	BIU_ISR_CDMA_INT		0x0010	/* CDMA interrupt pending */
-+#define	BIU_ISR_SXP_INT			0x0008	/* SXP interrupt pending */
-+#define	BIU_ISR_RISC_INT		0x0004	/* Risc interrupt pending */
-+#define	BIU_ISR_IPEND			0x0002	/* Global interrupt pending */
-+
-+#define	BIU2100_ISR_INT_PENDING		0x8000	/* Global interrupt pending */
-+#define	BIU2100_ISR_FPM_INT		0x0020	/* FPM interrupt pending */
-+#define	BIU2100_ISR_FB_INT		0x0010	/* FB interrupt pending */
-+#define	BIU2100_ISR_RISC_INT		0x0008	/* Risc interrupt pending */
-+#define	BIU2100_ISR_CDMA_INT		0x0004	/* CDMA interrupt pending */
-+#define	BIU2100_ISR_RXDMA_INT_PENDING	0x0002	/* Global interrupt pending */
-+#define	BIU2100_ISR_TXDMA_INT_PENDING	0x0001	/* Global interrupt pending */
-+
-+#define	INT_PENDING(isp, isr)	(IS_FC(isp)? \
-+	((isr & BIU2100_ISR_RISC_INT) != 0) : ((isr & BIU_ISR_RISC_INT) != 0))
-+
-+#define	INT_PENDING_MASK(isp)	\
-+	(IS_FC(isp)? BIU2100_ISR_RISC_INT: BIU_ISR_RISC_INT)
-+
-+/* BUS SEMAPHORE REGISTER */
-+#define	BIU_SEMA_STATUS		0x0002	/* Semaphore Status Bit */
-+#define	BIU_SEMA_LOCK  		0x0001	/* Semaphore Lock Bit */
-+
-+/* NVRAM SEMAPHORE REGISTER */
-+#define	BIU_NVRAM_CLOCK		0x0001
-+#define	BIU_NVRAM_SELECT	0x0002
-+#define	BIU_NVRAM_DATAOUT	0x0004
-+#define	BIU_NVRAM_DATAIN	0x0008
-+#define		ISP_NVRAM_READ		6
-+
-+/* COMNMAND && DATA DMA CONFIGURATION REGISTER */
-+#define	DMA_ENABLE_SXP_DMA		0x0008	/* Enable SXP to DMA Data */
-+#define	DMA_ENABLE_INTS			0x0004	/* Enable interrupts to RISC */
-+#define	DMA_ENABLE_BURST		0x0002	/* Enable Bus burst trans */
-+#define	DMA_DMA_DIRECTION		0x0001	/*
-+						 * Set DMA direction:
-+						 *	0 - DMA FIFO to host
-+						 *	1 - Host to DMA FIFO
-+						 */
-+
-+/* COMMAND && DATA DMA CONTROL REGISTER */
-+#define	DMA_CNTRL_SUSPEND_CHAN		0x0010	/* Suspend DMA transfer */
-+#define	DMA_CNTRL_CLEAR_CHAN		0x0008	/*
-+						 * Clear FIFO and DMA Channel,
-+						 * reset DMA registers
-+						 */
-+#define	DMA_CNTRL_CLEAR_FIFO		0x0004	/* Clear DMA FIFO */
-+#define	DMA_CNTRL_RESET_INT		0x0002	/* Clear DMA interrupt */
-+#define	DMA_CNTRL_STROBE		0x0001	/* Start DMA transfer */
-+
-+/*
-+ * Variants of same for 2100
-+ */
-+#define	DMA_CNTRL2100_CLEAR_CHAN	0x0004
-+#define	DMA_CNTRL2100_RESET_INT		0x0002
-+
-+
-+
-+/* DMA STATUS REGISTER */
-+#define	DMA_SBUS_STATUS_PIPE_MASK	0x00C0	/* DMA Pipeline status mask */
-+#define	DMA_SBUS_STATUS_CHAN_MASK	0x0030	/* Channel status mask */
-+#define	DMA_SBUS_STATUS_BUS_PARITY	0x0008	/* Parity Error on bus */
-+#define	DMA_SBUS_STATUS_BUS_ERR		0x0004	/* Error Detected on bus */
-+#define	DMA_SBUS_STATUS_TERM_COUNT	0x0002	/* DMA Transfer Completed */
-+#define	DMA_SBUS_STATUS_INTERRUPT	0x0001	/* Enable DMA channel inter */
-+
-+#define	DMA_PCI_STATUS_INTERRUPT	0x8000	/* Enable DMA channel inter */
-+#define	DMA_PCI_STATUS_RETRY_STAT	0x4000	/* Retry status */
-+#define	DMA_PCI_STATUS_CHAN_MASK	0x3000	/* Channel status mask */
-+#define	DMA_PCI_STATUS_FIFO_OVR		0x0100	/* DMA FIFO overrun cond */
-+#define	DMA_PCI_STATUS_FIFO_UDR		0x0080	/* DMA FIFO underrun cond */
-+#define	DMA_PCI_STATUS_BUS_ERR		0x0040	/* Error Detected on bus */
-+#define	DMA_PCI_STATUS_BUS_PARITY	0x0020	/* Parity Error on bus */
-+#define	DMA_PCI_STATUS_CLR_PEND		0x0010	/* DMA clear pending */
-+#define	DMA_PCI_STATUS_TERM_COUNT	0x0008	/* DMA Transfer Completed */
-+#define	DMA_PCI_STATUS_DMA_SUSP		0x0004	/* DMA suspended */
-+#define	DMA_PCI_STATUS_PIPE_MASK	0x0003	/* DMA Pipeline status mask */
-+
-+/* DMA Status Register, pipeline status bits */
-+#define	DMA_SBUS_PIPE_FULL		0x00C0	/* Both pipeline stages full */
-+#define	DMA_SBUS_PIPE_OVERRUN		0x0080	/* Pipeline overrun */
-+#define	DMA_SBUS_PIPE_STAGE1		0x0040	/*
-+						 * Pipeline stage 1 Loaded,
-+						 * stage 2 empty
-+						 */
-+#define	DMA_PCI_PIPE_FULL		0x0003	/* Both pipeline stages full */
-+#define	DMA_PCI_PIPE_OVERRUN		0x0002	/* Pipeline overrun */
-+#define	DMA_PCI_PIPE_STAGE1		0x0001	/*
-+						 * Pipeline stage 1 Loaded,
-+						 * stage 2 empty
-+						 */
-+#define	DMA_PIPE_EMPTY			0x0000	/* All pipeline stages empty */
-+
-+/* DMA Status Register, channel status bits */
-+#define	DMA_SBUS_CHAN_SUSPEND	0x0030	/* Channel error or suspended */
-+#define	DMA_SBUS_CHAN_TRANSFER	0x0020	/* Chan transfer in progress */
-+#define	DMA_SBUS_CHAN_ACTIVE	0x0010	/* Chan trans to host active */
-+#define	DMA_PCI_CHAN_TRANSFER	0x3000	/* Chan transfer in progress */
-+#define	DMA_PCI_CHAN_SUSPEND	0x2000	/* Channel error or suspended */
-+#define	DMA_PCI_CHAN_ACTIVE	0x1000	/* Chan trans to host active */
-+#define	ISP_DMA_CHAN_IDLE	0x0000	/* Chan idle (normal comp) */
-+
-+
-+/* DMA FIFO STATUS REGISTER */
-+#define	DMA_FIFO_STATUS_OVERRUN		0x0200	/* FIFO Overrun Condition */
-+#define	DMA_FIFO_STATUS_UNDERRUN	0x0100	/* FIFO Underrun Condition */
-+#define	DMA_FIFO_SBUS_COUNT_MASK	0x007F	/* FIFO Byte count mask */
-+#define	DMA_FIFO_PCI_COUNT_MASK		0x00FF	/* FIFO Byte count mask */
-+
-+/*
-+ * Mailbox Block Register Offsets
-+ */
-+
-+#define	INMAILBOX0	(MBOX_BLOCK+0x0)
-+#define	INMAILBOX1	(MBOX_BLOCK+0x2)
-+#define	INMAILBOX2	(MBOX_BLOCK+0x4)
-+#define	INMAILBOX3	(MBOX_BLOCK+0x6)
-+#define	INMAILBOX4	(MBOX_BLOCK+0x8)
-+#define	INMAILBOX5	(MBOX_BLOCK+0xA)
-+#define	INMAILBOX6	(MBOX_BLOCK+0xC)
-+#define	INMAILBOX7	(MBOX_BLOCK+0xE)
-+
-+#define	OUTMAILBOX0	(MBOX_BLOCK+0x0)
-+#define	OUTMAILBOX1	(MBOX_BLOCK+0x2)
-+#define	OUTMAILBOX2	(MBOX_BLOCK+0x4)
-+#define	OUTMAILBOX3	(MBOX_BLOCK+0x6)
-+#define	OUTMAILBOX4	(MBOX_BLOCK+0x8)
-+#define	OUTMAILBOX5	(MBOX_BLOCK+0xA)
-+#define	OUTMAILBOX6	(MBOX_BLOCK+0xC)
-+#define	OUTMAILBOX7	(MBOX_BLOCK+0xE)
-+
-+#define	MBOX_OFF(n)	(MBOX_BLOCK + ((n) << 1))
-+#define	NMBOX(isp)	\
-+	(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
-+	 ((isp)->isp_type & ISP_HA_FC))? 8 : 6)
-+#define	NMBOX_BMASK(isp)	\
-+	(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
-+	 ((isp)->isp_type & ISP_HA_FC))? 0xff : 0x3f)
-+
-+#define	MAX_MAILBOX	8
-+
-+/*
-+ * Fibre Protocol Module and Frame Buffer Register Offsets/Definitions (2X00).
-+ * NB: The RISC processor must be paused and the appropriate register
-+ * bank selected via BIU2100_CSR bits.
-+ */
-+
-+#define	FPM_DIAG_CONFIG	(BIU_BLOCK + 0x96)
-+#define		FPM_SOFT_RESET		0x0100
-+
-+#define	FBM_CMD		(BIU_BLOCK + 0xB8)
-+#define		FBMCMD_FIFO_RESET_ALL	0xA000
-+
-+
-+/*
-+ * SXP Block Register Offsets
-+ */
-+#define	SXP_PART_ID	(SXP_BLOCK+0x0)		/* R  : Part ID Code */
-+#define	SXP_CONFIG1	(SXP_BLOCK+0x2)		/* RW*: Configuration Reg #1 */
-+#define	SXP_CONFIG2	(SXP_BLOCK+0x4)		/* RW*: Configuration Reg #2 */
-+#define	SXP_CONFIG3	(SXP_BLOCK+0x6)		/* RW*: Configuration Reg #2 */
-+#define	SXP_INSTRUCTION	(SXP_BLOCK+0xC)		/* RW*: Instruction Pointer */
-+#define	SXP_RETURN_ADDR	(SXP_BLOCK+0x10)	/* RW*: Return Address */
-+#define	SXP_COMMAND	(SXP_BLOCK+0x14)	/* RW*: Command */
-+#define	SXP_INTERRUPT	(SXP_BLOCK+0x18)	/* R  : Interrupt */
-+#define	SXP_SEQUENCE	(SXP_BLOCK+0x1C)	/* RW*: Sequence */
-+#define	SXP_GROSS_ERR	(SXP_BLOCK+0x1E)	/* R  : Gross Error */
-+#define	SXP_EXCEPTION	(SXP_BLOCK+0x20)	/* RW*: Exception Enable */
-+#define	SXP_OVERRIDE	(SXP_BLOCK+0x24)	/* RW*: Override */
-+#define	SXP_LIT_BASE	(SXP_BLOCK+0x28)	/* RW*: Literal Base */
-+#define	SXP_USER_FLAGS	(SXP_BLOCK+0x2C)	/* RW*: User Flags */
-+#define	SXP_USER_EXCEPT	(SXP_BLOCK+0x30)	/* RW*: User Exception */
-+#define	SXP_BREAKPOINT	(SXP_BLOCK+0x34)	/* RW*: Breakpoint */
-+#define	SXP_SCSI_ID	(SXP_BLOCK+0x40)	/* RW*: SCSI ID */
-+#define	SXP_DEV_CONFIG1	(SXP_BLOCK+0x42)	/* RW*: Device Config Reg #1 */
-+#define	SXP_DEV_CONFIG2	(SXP_BLOCK+0x44)	/* RW*: Device Config Reg #2 */
-+#define	SXP_PHASE_PTR	(SXP_BLOCK+0x48)	/* RW*: SCSI Phase Pointer */
-+#define	SXP_BUF_PTR	(SXP_BLOCK+0x4C)	/* RW*: SCSI Buffer Pointer */
-+#define	SXP_BUF_CTR	(SXP_BLOCK+0x50)	/* RW*: SCSI Buffer Counter */
-+#define	SXP_BUFFER	(SXP_BLOCK+0x52)	/* RW*: SCSI Buffer */
-+#define	SXP_BUF_BYTE	(SXP_BLOCK+0x54)	/* RW*: SCSI Buffer Byte */
-+#define	SXP_BUF_WD	(SXP_BLOCK+0x56)	/* RW*: SCSI Buffer Word */
-+#define	SXP_BUF_WD_TRAN	(SXP_BLOCK+0x58)	/* RW*: SCSI Buffer Wd xlate */
-+#define	SXP_FIFO	(SXP_BLOCK+0x5A)	/* RW*: SCSI FIFO */
-+#define	SXP_FIFO_STATUS	(SXP_BLOCK+0x5C)	/* RW*: SCSI FIFO Status */
-+#define	SXP_FIFO_TOP	(SXP_BLOCK+0x5E)	/* RW*: SCSI FIFO Top Resid */
-+#define	SXP_FIFO_BOTTOM	(SXP_BLOCK+0x60)	/* RW*: SCSI FIFO Bot Resid */
-+#define	SXP_TRAN_REG	(SXP_BLOCK+0x64)	/* RW*: SCSI Transferr Reg */
-+#define	SXP_TRAN_CNT_LO	(SXP_BLOCK+0x68)	/* RW*: SCSI Trans Count */
-+#define	SXP_TRAN_CNT_HI	(SXP_BLOCK+0x6A)	/* RW*: SCSI Trans Count */
-+#define	SXP_TRAN_CTR_LO	(SXP_BLOCK+0x6C)	/* RW*: SCSI Trans Counter */
-+#define	SXP_TRAN_CTR_HI	(SXP_BLOCK+0x6E)	/* RW*: SCSI Trans Counter */
-+#define	SXP_ARB_DATA	(SXP_BLOCK+0x70)	/* R  : SCSI Arb Data */
-+#define	SXP_PINS_CTRL	(SXP_BLOCK+0x72)	/* RW*: SCSI Control Pins */
-+#define	SXP_PINS_DATA	(SXP_BLOCK+0x74)	/* RW*: SCSI Data Pins */
-+#define	SXP_PINS_DIFF	(SXP_BLOCK+0x76)	/* RW*: SCSI Diff Pins */
-+
-+/* for 1080/1280/1240 only */
-+#define	SXP_BANK1_SELECT	0x100
-+
-+
-+/* SXP CONF1 REGISTER */
-+#define	SXP_CONF1_ASYNCH_SETUP		0xF000	/* Asynchronous setup time */
-+#define	SXP_CONF1_SELECTION_UNIT	0x0000	/* Selection time unit */
-+#define	SXP_CONF1_SELECTION_TIMEOUT	0x0600	/* Selection timeout */
-+#define	SXP_CONF1_CLOCK_FACTOR		0x00E0	/* Clock factor */
-+#define	SXP_CONF1_SCSI_ID		0x000F	/* SCSI id */
-+
-+/* SXP CONF2 REGISTER */
-+#define	SXP_CONF2_DISABLE_FILTER	0x0040	/* Disable SCSI rec filters */
-+#define	SXP_CONF2_REQ_ACK_PULLUPS	0x0020	/* Enable req/ack pullups */
-+#define	SXP_CONF2_DATA_PULLUPS		0x0010	/* Enable data pullups */
-+#define	SXP_CONF2_CONFIG_AUTOLOAD	0x0008	/* Enable dev conf auto-load */
-+#define	SXP_CONF2_RESELECT		0x0002	/* Enable reselection */
-+#define	SXP_CONF2_SELECT		0x0001	/* Enable selection */
-+
-+/* SXP INTERRUPT REGISTER */
-+#define	SXP_INT_PARITY_ERR		0x8000	/* Parity error detected */
-+#define	SXP_INT_GROSS_ERR		0x4000	/* Gross error detected */
-+#define	SXP_INT_FUNCTION_ABORT		0x2000	/* Last cmd aborted */
-+#define	SXP_INT_CONDITION_FAILED	0x1000	/* Last cond failed test */
-+#define	SXP_INT_FIFO_EMPTY		0x0800	/* SCSI FIFO is empty */
-+#define	SXP_INT_BUF_COUNTER_ZERO	0x0400	/* SCSI buf count == zero */
-+#define	SXP_INT_XFER_ZERO		0x0200	/* SCSI trans count == zero */
-+#define	SXP_INT_INT_PENDING		0x0080	/* SXP interrupt pending */
-+#define	SXP_INT_CMD_RUNNING		0x0040	/* SXP is running a command */
-+#define	SXP_INT_INT_RETURN_CODE		0x000F	/* Interrupt return code */
-+
-+
-+/* SXP GROSS ERROR REGISTER */
-+#define	SXP_GROSS_OFFSET_RESID		0x0040	/* Req/Ack offset not zero */
-+#define	SXP_GROSS_OFFSET_UNDERFLOW	0x0020	/* Req/Ack offset underflow */
-+#define	SXP_GROSS_OFFSET_OVERFLOW	0x0010	/* Req/Ack offset overflow */
-+#define	SXP_GROSS_FIFO_UNDERFLOW	0x0008	/* SCSI FIFO underflow */
-+#define	SXP_GROSS_FIFO_OVERFLOW		0x0004	/* SCSI FIFO overflow */
-+#define	SXP_GROSS_WRITE_ERR		0x0002	/* SXP and RISC wrote to reg */
-+#define	SXP_GROSS_ILLEGAL_INST		0x0001	/* Bad inst loaded into SXP */
-+
-+/* SXP EXCEPTION REGISTER */
-+#define	SXP_EXCEPT_USER_0		0x8000	/* Enable user exception #0 */
-+#define	SXP_EXCEPT_USER_1		0x4000	/* Enable user exception #1 */
-+#define	PCI_SXP_EXCEPT_SCAM		0x0400	/* SCAM Selection enable */
-+#define	SXP_EXCEPT_BUS_FREE		0x0200	/* Enable Bus Free det */
-+#define	SXP_EXCEPT_TARGET_ATN		0x0100	/* Enable TGT mode atten det */
-+#define	SXP_EXCEPT_RESELECTED		0x0080	/* Enable ReSEL exc handling */
-+#define	SXP_EXCEPT_SELECTED		0x0040	/* Enable SEL exc handling */
-+#define	SXP_EXCEPT_ARBITRATION		0x0020	/* Enable ARB exc handling */
-+#define	SXP_EXCEPT_GROSS_ERR		0x0010	/* Enable gross error except */
-+#define	SXP_EXCEPT_BUS_RESET		0x0008	/* Enable Bus Reset except */
-+
-+	/* SXP OVERRIDE REGISTER */
-+#define	SXP_ORIDE_EXT_TRIGGER		0x8000	/* Enable external trigger */
-+#define	SXP_ORIDE_STEP			0x4000	/* Enable single step mode */
-+#define	SXP_ORIDE_BREAKPOINT		0x2000	/* Enable breakpoint reg */
-+#define	SXP_ORIDE_PIN_WRITE		0x1000	/* Enable write to SCSI pins */
-+#define	SXP_ORIDE_FORCE_OUTPUTS		0x0800	/* Force SCSI outputs on */
-+#define	SXP_ORIDE_LOOPBACK		0x0400	/* Enable SCSI loopback mode */
-+#define	SXP_ORIDE_PARITY_TEST		0x0200	/* Enable parity test mode */
-+#define	SXP_ORIDE_TRISTATE_ENA_PINS	0x0100	/* Tristate SCSI enable pins */
-+#define	SXP_ORIDE_TRISTATE_PINS		0x0080	/* Tristate SCSI pins */
-+#define	SXP_ORIDE_FIFO_RESET		0x0008	/* Reset SCSI FIFO */
-+#define	SXP_ORIDE_CMD_TERMINATE		0x0004	/* Terminate cur SXP com */
-+#define	SXP_ORIDE_RESET_REG		0x0002	/* Reset SXP registers */
-+#define	SXP_ORIDE_RESET_MODULE		0x0001	/* Reset SXP module */
-+
-+/* SXP COMMANDS */
-+#define	SXP_RESET_BUS_CMD		0x300b
-+
-+/* SXP SCSI ID REGISTER */
-+#define	SXP_SELECTING_ID		0x0F00	/* (Re)Selecting id */
-+#define	SXP_SELECT_ID			0x000F	/* Select id */
-+
-+/* SXP DEV CONFIG1 REGISTER */
-+#define	SXP_DCONF1_SYNC_HOLD		0x7000	/* Synchronous data hold */
-+#define	SXP_DCONF1_SYNC_SETUP		0x0F00	/* Synchronous data setup */
-+#define	SXP_DCONF1_SYNC_OFFSET		0x000F	/* Synchronous data offset */
-+
-+
-+/* SXP DEV CONFIG2 REGISTER */
-+#define	SXP_DCONF2_FLAGS_MASK		0xF000	/* Device flags */
-+#define	SXP_DCONF2_WIDE			0x0400	/* Enable wide SCSI */
-+#define	SXP_DCONF2_PARITY		0x0200	/* Enable parity checking */
-+#define	SXP_DCONF2_BLOCK_MODE		0x0100	/* Enable blk mode xfr count */
-+#define	SXP_DCONF2_ASSERTION_MASK	0x0007	/* Assersion period mask */
-+
-+
-+/* SXP PHASE POINTER REGISTER */
-+#define	SXP_PHASE_STATUS_PTR		0x1000	/* Status buffer offset */
-+#define	SXP_PHASE_MSG_IN_PTR		0x0700	/* Msg in buffer offset */
-+#define	SXP_PHASE_COM_PTR		0x00F0	/* Command buffer offset */
-+#define	SXP_PHASE_MSG_OUT_PTR		0x0007	/* Msg out buffer offset */
-+
-+
-+/* SXP FIFO STATUS REGISTER */
-+#define	SXP_FIFO_TOP_RESID		0x8000	/* Top residue reg full */
-+#define	SXP_FIFO_ACK_RESID		0x4000	/* Wide transfers odd resid */
-+#define	SXP_FIFO_COUNT_MASK		0x001C	/* Words in SXP FIFO */
-+#define	SXP_FIFO_BOTTOM_RESID		0x0001	/* Bottom residue reg full */
-+
-+
-+/* SXP CONTROL PINS REGISTER */
-+#define	SXP_PINS_CON_PHASE		0x8000	/* Scsi phase valid */
-+#define	SXP_PINS_CON_PARITY_HI		0x0400	/* Parity pin */
-+#define	SXP_PINS_CON_PARITY_LO		0x0200	/* Parity pin */
-+#define	SXP_PINS_CON_REQ		0x0100	/* SCSI bus REQUEST */
-+#define	SXP_PINS_CON_ACK		0x0080	/* SCSI bus ACKNOWLEDGE */
-+#define	SXP_PINS_CON_RST		0x0040	/* SCSI bus RESET */
-+#define	SXP_PINS_CON_BSY		0x0020	/* SCSI bus BUSY */
-+#define	SXP_PINS_CON_SEL		0x0010	/* SCSI bus SELECT */
-+#define	SXP_PINS_CON_ATN		0x0008	/* SCSI bus ATTENTION */
-+#define	SXP_PINS_CON_MSG		0x0004	/* SCSI bus MESSAGE */
-+#define	SXP_PINS_CON_CD 		0x0002	/* SCSI bus COMMAND */
-+#define	SXP_PINS_CON_IO 		0x0001	/* SCSI bus INPUT */
-+
-+/*
-+ * Set the hold time for the SCSI Bus Reset to be 250 ms
-+ */
-+#define	SXP_SCSI_BUS_RESET_HOLD_TIME	250
-+
-+/* SXP DIFF PINS REGISTER */
-+#define	SXP_PINS_DIFF_SENSE		0x0200	/* DIFFSENS sig on SCSI bus */
-+#define	SXP_PINS_DIFF_MODE		0x0100	/* DIFFM signal */
-+#define	SXP_PINS_DIFF_ENABLE_OUTPUT	0x0080	/* Enable SXP SCSI data drv */
-+#define	SXP_PINS_DIFF_PINS_MASK		0x007C	/* Differential control pins */
-+#define	SXP_PINS_DIFF_TARGET		0x0002	/* Enable SXP target mode */
-+#define	SXP_PINS_DIFF_INITIATOR		0x0001	/* Enable SXP initiator mode */
-+
-+/* Ultra2 only */
-+#define	SXP_PINS_LVD_MODE		0x1000
-+#define	SXP_PINS_HVD_MODE		0x0800
-+#define	SXP_PINS_SE_MODE		0x0400
-+
-+/* The above have to be put together with the DIFFM pin to make sense */
-+#define	ISP1080_LVD_MODE		(SXP_PINS_LVD_MODE)
-+#define	ISP1080_HVD_MODE		(SXP_PINS_HVD_MODE|SXP_PINS_DIFF_MODE)
-+#define	ISP1080_SE_MODE			(SXP_PINS_SE_MODE)
-+#define	ISP1080_MODE_MASK	\
-+    (SXP_PINS_LVD_MODE|SXP_PINS_HVD_MODE|SXP_PINS_SE_MODE|SXP_PINS_DIFF_MODE)
-+
-+/*
-+ * RISC and Host Command and Control Block Register Offsets
-+ */
-+
-+#define	RISC_ACC	RISC_BLOCK+0x0	/* RW*: Accumulator */
-+#define	RISC_R1		RISC_BLOCK+0x2	/* RW*: GP Reg R1  */
-+#define	RISC_R2		RISC_BLOCK+0x4	/* RW*: GP Reg R2  */
-+#define	RISC_R3		RISC_BLOCK+0x6	/* RW*: GP Reg R3  */
-+#define	RISC_R4		RISC_BLOCK+0x8	/* RW*: GP Reg R4  */
-+#define	RISC_R5		RISC_BLOCK+0xA	/* RW*: GP Reg R5  */
-+#define	RISC_R6		RISC_BLOCK+0xC	/* RW*: GP Reg R6  */
-+#define	RISC_R7		RISC_BLOCK+0xE	/* RW*: GP Reg R7  */
-+#define	RISC_R8		RISC_BLOCK+0x10	/* RW*: GP Reg R8  */
-+#define	RISC_R9		RISC_BLOCK+0x12	/* RW*: GP Reg R9  */
-+#define	RISC_R10	RISC_BLOCK+0x14	/* RW*: GP Reg R10 */
-+#define	RISC_R11	RISC_BLOCK+0x16	/* RW*: GP Reg R11 */
-+#define	RISC_R12	RISC_BLOCK+0x18	/* RW*: GP Reg R12 */
-+#define	RISC_R13	RISC_BLOCK+0x1a	/* RW*: GP Reg R13 */
-+#define	RISC_R14	RISC_BLOCK+0x1c	/* RW*: GP Reg R14 */
-+#define	RISC_R15	RISC_BLOCK+0x1e	/* RW*: GP Reg R15 */
-+#define	RISC_PSR	RISC_BLOCK+0x20	/* RW*: Processor Status */
-+#define	RISC_IVR	RISC_BLOCK+0x22	/* RW*: Interrupt Vector */
-+#define	RISC_PCR	RISC_BLOCK+0x24	/* RW*: Processor Ctrl */
-+#define	RISC_RAR0	RISC_BLOCK+0x26	/* RW*: Ram Address #0 */
-+#define	RISC_RAR1	RISC_BLOCK+0x28	/* RW*: Ram Address #1 */
-+#define	RISC_LCR	RISC_BLOCK+0x2a	/* RW*: Loop Counter */
-+#define	RISC_PC		RISC_BLOCK+0x2c	/* R  : Program Counter */
-+#define	RISC_MTR	RISC_BLOCK+0x2e	/* RW*: Memory Timing */
-+#define		RISC_MTR2100	RISC_BLOCK+0x30
-+
-+#define	RISC_EMB	RISC_BLOCK+0x30	/* RW*: Ext Mem Boundary */
-+#define		DUAL_BANK	8
-+#define	RISC_SP		RISC_BLOCK+0x32	/* RW*: Stack Pointer */
-+#define	RISC_HRL	RISC_BLOCK+0x3e	/* R *: Hardware Rev Level */
-+#define	HCCR		RISC_BLOCK+0x40	/* RW : Host Command & Ctrl */
-+#define	BP0		RISC_BLOCK+0x42	/* RW : Processor Brkpt #0 */
-+#define	BP1		RISC_BLOCK+0x44	/* RW : Processor Brkpt #1 */
-+#define	TCR		RISC_BLOCK+0x46	/*  W : Test Control */
-+#define	TMR		RISC_BLOCK+0x48	/*  W : Test Mode */
-+
-+
-+/* PROCESSOR STATUS REGISTER */
-+#define	RISC_PSR_FORCE_TRUE		0x8000
-+#define	RISC_PSR_LOOP_COUNT_DONE	0x4000
-+#define	RISC_PSR_RISC_INT		0x2000
-+#define	RISC_PSR_TIMER_ROLLOVER		0x1000
-+#define	RISC_PSR_ALU_OVERFLOW		0x0800
-+#define	RISC_PSR_ALU_MSB		0x0400
-+#define	RISC_PSR_ALU_CARRY		0x0200
-+#define	RISC_PSR_ALU_ZERO		0x0100
-+
-+#define	RISC_PSR_PCI_ULTRA		0x0080
-+#define	RISC_PSR_SBUS_ULTRA		0x0020
-+
-+#define	RISC_PSR_DMA_INT		0x0010
-+#define	RISC_PSR_SXP_INT		0x0008
-+#define	RISC_PSR_HOST_INT		0x0004
-+#define	RISC_PSR_INT_PENDING		0x0002
-+#define	RISC_PSR_FORCE_FALSE  		0x0001
-+
-+
-+/* Host Command and Control */
-+#define	HCCR_CMD_NOP			0x0000	/* NOP */
-+#define	HCCR_CMD_RESET			0x1000	/* Reset RISC */
-+#define	HCCR_CMD_PAUSE			0x2000	/* Pause RISC */
-+#define	HCCR_CMD_RELEASE		0x3000	/* Release Paused RISC */
-+#define	HCCR_CMD_STEP			0x4000	/* Single Step RISC */
-+#define	HCCR_2X00_DISABLE_PARITY_PAUSE	0x4001	/*
-+						 * Disable RISC pause on FPM
-+						 * parity error.
-+						 */
-+#define	HCCR_CMD_SET_HOST_INT		0x5000	/* Set Host Interrupt */
-+#define	HCCR_CMD_CLEAR_HOST_INT		0x6000	/* Clear Host Interrupt */
-+#define	HCCR_CMD_CLEAR_RISC_INT		0x7000	/* Clear RISC interrupt */
-+#define	HCCR_CMD_BREAKPOINT		0x8000	/* Change breakpoint enables */
-+#define	PCI_HCCR_CMD_BIOS		0x9000	/* Write BIOS (disable) */
-+#define	PCI_HCCR_CMD_PARITY		0xA000	/* Write parity enable */
-+#define	PCI_HCCR_CMD_PARITY_ERR		0xE000	/* Generate parity error */
-+#define	HCCR_CMD_TEST_MODE		0xF000	/* Set Test Mode */
-+
-+#define	ISP2100_HCCR_PARITY_ENABLE_2	0x0400
-+#define	ISP2100_HCCR_PARITY_ENABLE_1	0x0200
-+#define	ISP2100_HCCR_PARITY_ENABLE_0	0x0100
-+#define	ISP2100_HCCR_PARITY		0x0001
-+
-+#define	PCI_HCCR_PARITY			0x0400	/* Parity error flag */
-+#define	PCI_HCCR_PARITY_ENABLE_1	0x0200	/* Parity enable bank 1 */
-+#define	PCI_HCCR_PARITY_ENABLE_0	0x0100	/* Parity enable bank 0 */
-+
-+#define	HCCR_HOST_INT			0x0080	/* R  : Host interrupt set */
-+#define	HCCR_RESET			0x0040	/* R  : reset in progress */
-+#define	HCCR_PAUSE			0x0020	/* R  : RISC paused */
-+
-+#define	PCI_HCCR_BIOS			0x0001	/*  W : BIOS enable */
-+
-+/*
-+ * NVRAM Definitions (PCI cards only)
-+ */
-+
-+#define	ISPBSMX(c, byte, shift, mask)	\
-+	(((c)[(byte)] >> (shift)) & (mask))
-+/*
-+ * Qlogic 1020/1040 NVRAM is an array of 128 bytes.
-+ *
-+ * Some portion of the front of this is for general host adapter properties
-+ * This is followed by an array of per-target parameters, and is tailed off
-+ * with a checksum xor byte at offset 127. For non-byte entities data is
-+ * stored in Little Endian order.
-+ */
-+
-+#define	ISP_NVRAM_SIZE	128
-+
-+#define	ISP_NVRAM_VERSION(c)			(c)[4]
-+#define	ISP_NVRAM_FIFO_THRESHOLD(c)		ISPBSMX(c, 5, 0, 0x03)
-+#define	ISP_NVRAM_BIOS_DISABLE(c)		ISPBSMX(c, 5, 2, 0x01)
-+#define	ISP_NVRAM_HBA_ENABLE(c)			ISPBSMX(c, 5, 3, 0x01)
-+#define	ISP_NVRAM_INITIATOR_ID(c)		ISPBSMX(c, 5, 4, 0x0f)
-+#define	ISP_NVRAM_BUS_RESET_DELAY(c)		(c)[6]
-+#define	ISP_NVRAM_BUS_RETRY_COUNT(c)		(c)[7]
-+#define	ISP_NVRAM_BUS_RETRY_DELAY(c)		(c)[8]
-+#define	ISP_NVRAM_ASYNC_DATA_SETUP_TIME(c)	ISPBSMX(c, 9, 0, 0x0f)
-+#define	ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(c)	ISPBSMX(c, 9, 4, 0x01)
-+#define	ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(c)	ISPBSMX(c, 9, 5, 0x01)
-+#define	ISP_NVRAM_DATA_DMA_BURST_ENABLE(c)	ISPBSMX(c, 9, 6, 0x01)
-+#define	ISP_NVRAM_CMD_DMA_BURST_ENABLE(c)	ISPBSMX(c, 9, 7, 0x01)
-+#define	ISP_NVRAM_TAG_AGE_LIMIT(c)		(c)[10]
-+#define	ISP_NVRAM_LOWTRM_ENABLE(c)		ISPBSMX(c, 11, 0, 0x01)
-+#define	ISP_NVRAM_HITRM_ENABLE(c)		ISPBSMX(c, 11, 1, 0x01)
-+#define	ISP_NVRAM_PCMC_BURST_ENABLE(c)		ISPBSMX(c, 11, 2, 0x01)
-+#define	ISP_NVRAM_ENABLE_60_MHZ(c)		ISPBSMX(c, 11, 3, 0x01)
-+#define	ISP_NVRAM_SCSI_RESET_DISABLE(c)		ISPBSMX(c, 11, 4, 0x01)
-+#define	ISP_NVRAM_ENABLE_AUTO_TERM(c)		ISPBSMX(c, 11, 5, 0x01)
-+#define	ISP_NVRAM_FIFO_THRESHOLD_128(c)		ISPBSMX(c, 11, 6, 0x01)
-+#define	ISP_NVRAM_AUTO_TERM_SUPPORT(c)		ISPBSMX(c, 11, 7, 0x01)
-+#define	ISP_NVRAM_SELECTION_TIMEOUT(c)		(((c)[12]) | ((c)[13] << 8))
-+#define	ISP_NVRAM_MAX_QUEUE_DEPTH(c)		(((c)[14]) | ((c)[15] << 8))
-+#define	ISP_NVRAM_SCSI_BUS_SIZE(c)		ISPBSMX(c, 16, 0, 0x01)
-+#define	ISP_NVRAM_SCSI_BUS_TYPE(c)		ISPBSMX(c, 16, 1, 0x01)
-+#define	ISP_NVRAM_ADAPTER_CLK_SPEED(c)		ISPBSMX(c, 16, 2, 0x01)
-+#define	ISP_NVRAM_SOFT_TERM_SUPPORT(c)		ISPBSMX(c, 16, 3, 0x01)
-+#define	ISP_NVRAM_FLASH_ONBOARD(c)		ISPBSMX(c, 16, 4, 0x01)
-+#define	ISP_NVRAM_FAST_MTTR_ENABLE(c)		ISPBSMX(c, 22, 0, 0x01)
-+
-+#define	ISP_NVRAM_TARGOFF			28
-+#define	ISP_NVARM_TARGSIZE			6
-+#define	_IxT(tgt, tidx)			\
-+	(ISP_NVRAM_TARGOFF + (ISP_NVARM_TARGSIZE * (tgt)) + (tidx))
-+#define	ISP_NVRAM_TGT_RENEG(c, t)		ISPBSMX(c, _IxT(t, 0), 0, 0x01)
-+#define	ISP_NVRAM_TGT_QFRZ(c, t)		ISPBSMX(c, _IxT(t, 0), 1, 0x01)
-+#define	ISP_NVRAM_TGT_ARQ(c, t)			ISPBSMX(c, _IxT(t, 0), 2, 0x01)
-+#define	ISP_NVRAM_TGT_TQING(c, t)		ISPBSMX(c, _IxT(t, 0), 3, 0x01)
-+#define	ISP_NVRAM_TGT_SYNC(c, t)		ISPBSMX(c, _IxT(t, 0), 4, 0x01)
-+#define	ISP_NVRAM_TGT_WIDE(c, t)		ISPBSMX(c, _IxT(t, 0), 5, 0x01)
-+#define	ISP_NVRAM_TGT_PARITY(c, t)		ISPBSMX(c, _IxT(t, 0), 6, 0x01)
-+#define	ISP_NVRAM_TGT_DISC(c, t)		ISPBSMX(c, _IxT(t, 0), 7, 0x01)
-+#define	ISP_NVRAM_TGT_EXEC_THROTTLE(c, t)	ISPBSMX(c, _IxT(t, 1), 0, 0xff)
-+#define	ISP_NVRAM_TGT_SYNC_PERIOD(c, t)		ISPBSMX(c, _IxT(t, 2), 0, 0xff)
-+#define	ISP_NVRAM_TGT_SYNC_OFFSET(c, t)		ISPBSMX(c, _IxT(t, 3), 0, 0x0f)
-+#define	ISP_NVRAM_TGT_DEVICE_ENABLE(c, t)	ISPBSMX(c, _IxT(t, 3), 4, 0x01)
-+#define	ISP_NVRAM_TGT_LUN_DISABLE(c, t)		ISPBSMX(c, _IxT(t, 3), 5, 0x01)
-+
-+/*
-+ * Qlogic 1080/1240 NVRAM is an array of 256 bytes.
-+ *
-+ * Some portion of the front of this is for general host adapter properties
-+ * This is followed by an array of per-target parameters, and is tailed off
-+ * with a checksum xor byte at offset 256. For non-byte entities data is
-+ * stored in Little Endian order.
-+ */
-+
-+#define	ISP1080_NVRAM_SIZE	256
-+
-+#define	ISP1080_NVRAM_VERSION(c)		ISP_NVRAM_VERSION(c)
-+
-+/* Offset 5 */
-+/*
-+	u_int8_t bios_configuration_mode     :2;
-+	u_int8_t bios_disable                :1;
-+	u_int8_t selectable_scsi_boot_enable :1;
-+	u_int8_t cd_rom_boot_enable          :1;
-+	u_int8_t disable_loading_risc_code   :1;
-+	u_int8_t enable_64bit_addressing     :1;
-+	u_int8_t unused_7                    :1;
-+ */
-+
-+/* Offsets 6, 7 */
-+/*
-+        u_int8_t boot_lun_number    :5;
-+        u_int8_t scsi_bus_number    :1;
-+        u_int8_t unused_6           :1;
-+        u_int8_t unused_7           :1;
-+        u_int8_t boot_target_number :4;
-+        u_int8_t unused_12          :1;
-+        u_int8_t unused_13          :1;
-+        u_int8_t unused_14          :1;
-+        u_int8_t unused_15          :1;
-+ */
-+
-+#define	ISP1080_NVRAM_HBA_ENABLE(c)			ISPBSMX(c, 16, 3, 0x01)
-+
-+#define	ISP1080_NVRAM_BURST_ENABLE(c)			ISPBSMX(c, 16, 1, 0x01)
-+#define	ISP1080_NVRAM_FIFO_THRESHOLD(c)			ISPBSMX(c, 16, 4, 0x0f)
-+
-+#define	ISP1080_NVRAM_AUTO_TERM_SUPPORT(c)		ISPBSMX(c, 17, 7, 0x01)
-+#define	ISP1080_NVRAM_BUS0_TERM_MODE(c)			ISPBSMX(c, 17, 0, 0x03)
-+#define	ISP1080_NVRAM_BUS1_TERM_MODE(c)			ISPBSMX(c, 17, 2, 0x03)
-+
-+#define	ISP1080_ISP_PARAMETER(c)			\
-+	(((c)[18]) | ((c)[19] << 8))
-+
-+#define	ISP1080_FAST_POST(c)				ISPBSMX(c, 20, 0, 0x01)
-+#define	ISP1080_REPORT_LVD_TRANSITION(c)		ISPBSMX(c, 20, 1, 0x01)
-+
-+#define	ISP1080_BUS1_OFF				112
-+
-+#define	ISP1080_NVRAM_INITIATOR_ID(c, b)		\
-+	ISPBSMX(c, ((b == 0)? 0 : ISP1080_BUS1_OFF) + 24, 0, 0x0f)
-+#define	ISP1080_NVRAM_BUS_RESET_DELAY(c, b)		\
-+	(c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 25]
-+#define	ISP1080_NVRAM_BUS_RETRY_COUNT(c, b)		\
-+	(c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 26]
-+#define	ISP1080_NVRAM_BUS_RETRY_DELAY(c, b)		\
-+	(c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 27]
-+
-+#define	ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(c, b)	\
-+	ISPBSMX(c, ((b == 0)? 0 : ISP1080_BUS1_OFF) + 28, 0, 0x0f)
-+#define	ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(c, b)	\
-+	ISPBSMX(c, ((b == 0)? 0 : ISP1080_BUS1_OFF) + 28, 4, 0x01)
-+#define	ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(c, b)	\
-+	ISPBSMX(c, ((b == 0)? 0 : ISP1080_BUS1_OFF) + 28, 5, 0x01)
-+#define	ISP1080_NVRAM_SELECTION_TIMEOUT(c, b)		\
-+	(((c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 30]) | \
-+	((c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 31] << 8))
-+#define	ISP1080_NVRAM_MAX_QUEUE_DEPTH(c, b)		\
-+	(((c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 32]) | \
-+	((c)[((b == 0)? 0 : ISP1080_BUS1_OFF) + 33] << 8))
-+
-+#define	ISP1080_NVRAM_TARGOFF(b)		\
-+	((b == 0)? 40: (40 + ISP1080_BUS1_OFF))
-+#define	ISP1080_NVRAM_TARGSIZE			6
-+#define	_IxT8(tgt, tidx, b)			\
-+	(ISP1080_NVRAM_TARGOFF((b)) + (ISP1080_NVRAM_TARGSIZE * (tgt)) + (tidx))
-+
-+#define	ISP1080_NVRAM_TGT_RENEG(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 0, 0x01)
-+#define	ISP1080_NVRAM_TGT_QFRZ(c, t, b)			\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 1, 0x01)
-+#define	ISP1080_NVRAM_TGT_ARQ(c, t, b)			\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 2, 0x01)
-+#define	ISP1080_NVRAM_TGT_TQING(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 3, 0x01)
-+#define	ISP1080_NVRAM_TGT_SYNC(c, t, b)			\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 4, 0x01)
-+#define	ISP1080_NVRAM_TGT_WIDE(c, t, b)			\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 5, 0x01)
-+#define	ISP1080_NVRAM_TGT_PARITY(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 6, 0x01)
-+#define	ISP1080_NVRAM_TGT_DISC(c, t, b)			\
-+	ISPBSMX(c, _IxT8(t, 0, (b)), 7, 0x01)
-+#define	ISP1080_NVRAM_TGT_EXEC_THROTTLE(c, t, b)	\
-+	ISPBSMX(c, _IxT8(t, 1, (b)), 0, 0xff)
-+#define	ISP1080_NVRAM_TGT_SYNC_PERIOD(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 2, (b)), 0, 0xff)
-+#define	ISP1080_NVRAM_TGT_SYNC_OFFSET(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 3, (b)), 0, 0x0f)
-+#define	ISP1080_NVRAM_TGT_DEVICE_ENABLE(c, t, b)	\
-+	ISPBSMX(c, _IxT8(t, 3, (b)), 4, 0x01)
-+#define	ISP1080_NVRAM_TGT_LUN_DISABLE(c, t, b)		\
-+	ISPBSMX(c, _IxT8(t, 3, (b)), 5, 0x01)
-+
-+#define	ISP12160_NVRAM_HBA_ENABLE	ISP1080_NVRAM_HBA_ENABLE
-+#define	ISP12160_NVRAM_BURST_ENABLE	ISP1080_NVRAM_BURST_ENABLE
-+#define	ISP12160_NVRAM_FIFO_THRESHOLD	ISP1080_NVRAM_FIFO_THRESHOLD
-+#define	ISP12160_NVRAM_AUTO_TERM_SUPPORT	ISP1080_NVRAM_AUTO_TERM_SUPPORT
-+#define	ISP12160_NVRAM_BUS0_TERM_MODE	ISP1080_NVRAM_BUS0_TERM_MODE
-+#define	ISP12160_NVRAM_BUS1_TERM_MODE	ISP1080_NVRAM_BUS1_TERM_MODE
-+#define	ISP12160_ISP_PARAMETER		ISP12160_ISP_PARAMETER
-+#define	ISP12160_FAST_POST		ISP1080_FAST_POST
-+#define	ISP12160_REPORT_LVD_TRANSITION	ISP1080_REPORT_LVD_TRANSTION
-+
-+#define	ISP12160_NVRAM_INITIATOR_ID			\
-+	ISP1080_NVRAM_INITIATOR_ID
-+#define	ISP12160_NVRAM_BUS_RESET_DELAY			\
-+	ISP1080_NVRAM_BUS_RESET_DELAY
-+#define	ISP12160_NVRAM_BUS_RETRY_COUNT			\
-+	ISP1080_NVRAM_BUS_RETRY_COUNT
-+#define	ISP12160_NVRAM_BUS_RETRY_DELAY			\
-+	ISP1080_NVRAM_BUS_RETRY_DELAY
-+#define	ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME		\
-+	ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME
-+#define	ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION		\
-+	ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION
-+#define	ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION	\
-+	ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION
-+#define	ISP12160_NVRAM_SELECTION_TIMEOUT		\
-+	ISP1080_NVRAM_SELECTION_TIMEOUT
-+#define	ISP12160_NVRAM_MAX_QUEUE_DEPTH			\
-+	ISP1080_NVRAM_MAX_QUEUE_DEPTH
-+
-+
-+#define	ISP12160_BUS0_OFF	24
-+#define	ISP12160_BUS1_OFF	136
-+
-+#define	ISP12160_NVRAM_TARGOFF(b)		\
-+	(((b == 0)? ISP12160_BUS0_OFF : ISP12160_BUS1_OFF) + 16)
-+
-+#define	ISP12160_NVRAM_TARGSIZE			6
-+#define	_IxT16(tgt, tidx, b)			\
-+	(ISP12160_NVRAM_TARGOFF((b))+(ISP12160_NVRAM_TARGSIZE * (tgt))+(tidx))
-+
-+#define	ISP12160_NVRAM_TGT_RENEG(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 0, 0x01)
-+#define	ISP12160_NVRAM_TGT_QFRZ(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 1, 0x01)
-+#define	ISP12160_NVRAM_TGT_ARQ(c, t, b)			\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 2, 0x01)
-+#define	ISP12160_NVRAM_TGT_TQING(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 3, 0x01)
-+#define	ISP12160_NVRAM_TGT_SYNC(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 4, 0x01)
-+#define	ISP12160_NVRAM_TGT_WIDE(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 5, 0x01)
-+#define	ISP12160_NVRAM_TGT_PARITY(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 6, 0x01)
-+#define	ISP12160_NVRAM_TGT_DISC(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 0, (b)), 7, 0x01)
-+
-+#define	ISP12160_NVRAM_TGT_EXEC_THROTTLE(c, t, b)	\
-+	ISPBSMX(c, _IxT16(t, 1, (b)), 0, 0xff)
-+#define	ISP12160_NVRAM_TGT_SYNC_PERIOD(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 2, (b)), 0, 0xff)
-+
-+#define	ISP12160_NVRAM_TGT_SYNC_OFFSET(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 3, (b)), 0, 0x1f)
-+#define	ISP12160_NVRAM_TGT_DEVICE_ENABLE(c, t, b)	\
-+	ISPBSMX(c, _IxT16(t, 3, (b)), 5, 0x01)
-+
-+#define	ISP12160_NVRAM_PPR_OPTIONS(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 4, (b)), 0, 0x0f)
-+#define	ISP12160_NVRAM_PPR_WIDTH(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 4, (b)), 4, 0x03)
-+#define	ISP12160_NVRAM_PPR_ENABLE(c, t, b)		\
-+	ISPBSMX(c, _IxT16(t, 4, (b)), 7, 0x01)
-+
-+/*
-+ * Qlogic 2XXX NVRAM is an array of 256 bytes.
-+ *
-+ * Some portion of the front of this is for general RISC engine parameters,
-+ * mostly reflecting the state of the last INITIALIZE FIRMWARE mailbox command.
-+ *
-+ * This is followed by some general host adapter parameters, and ends with
-+ * a checksum xor byte at offset 255. For non-byte entities data is stored
-+ * in Little Endian order.
-+ */
-+#define	ISP2100_NVRAM_SIZE	256
-+/* ISP_NVRAM_VERSION is in same overall place */
-+#define	ISP2100_NVRAM_RISCVER(c)		(c)[6]
-+#define	ISP2100_NVRAM_OPTIONS(c)		(c)[8]
-+#define	ISP2100_NVRAM_MAXFRAMELENGTH(c)		(((c)[10]) | ((c)[11] << 8))
-+#define	ISP2100_NVRAM_MAXIOCBALLOCATION(c)	(((c)[12]) | ((c)[13] << 8))
-+#define	ISP2100_NVRAM_EXECUTION_THROTTLE(c)	(((c)[14]) | ((c)[15] << 8))
-+#define	ISP2100_NVRAM_RETRY_COUNT(c)		(c)[16]
-+#define	ISP2100_NVRAM_RETRY_DELAY(c)		(c)[17]
-+
-+#define	ISP2100_NVRAM_PORT_NAME(c)	(\
-+		(((u_int64_t)(c)[18]) << 56) | \
-+		(((u_int64_t)(c)[19]) << 48) | \
-+		(((u_int64_t)(c)[20]) << 40) | \
-+		(((u_int64_t)(c)[21]) << 32) | \
-+		(((u_int64_t)(c)[22]) << 24) | \
-+		(((u_int64_t)(c)[23]) << 16) | \
-+		(((u_int64_t)(c)[24]) <<  8) | \
-+		(((u_int64_t)(c)[25]) <<  0))
-+
-+#define	ISP2100_NVRAM_HARDLOOPID(c)		(c)[26]
-+
-+#define	ISP2200_NVRAM_NODE_NAME(c)	(\
-+		(((u_int64_t)(c)[30]) << 56) | \
-+		(((u_int64_t)(c)[31]) << 48) | \
-+		(((u_int64_t)(c)[32]) << 40) | \
-+		(((u_int64_t)(c)[33]) << 32) | \
-+		(((u_int64_t)(c)[34]) << 24) | \
-+		(((u_int64_t)(c)[35]) << 16) | \
-+		(((u_int64_t)(c)[36]) <<  8) | \
-+		(((u_int64_t)(c)[37]) <<  0))
-+
-+#define	ISP2100_NVRAM_HBA_OPTIONS(c)		(c)[70]
-+#define	ISP2100_NVRAM_HBA_DISABLE(c)		ISPBSMX(c, 70, 0, 0x01)
-+#define	ISP2100_NVRAM_BIOS_DISABLE(c)		ISPBSMX(c, 70, 1, 0x01)
-+#define	ISP2100_NVRAM_LUN_DISABLE(c)		ISPBSMX(c, 70, 2, 0x01)
-+#define	ISP2100_NVRAM_ENABLE_SELECT_BOOT(c)	ISPBSMX(c, 70, 3, 0x01)
-+#define	ISP2100_NVRAM_DISABLE_CODELOAD(c)	ISPBSMX(c, 70, 4, 0x01)
-+#define	ISP2100_NVRAM_SET_CACHELINESZ(c)	ISPBSMX(c, 70, 5, 0x01)
-+
-+#define	ISP2100_NVRAM_BOOT_NODE_NAME(c)	(\
-+		(((u_int64_t)(c)[72]) << 56) | \
-+		(((u_int64_t)(c)[73]) << 48) | \
-+		(((u_int64_t)(c)[74]) << 40) | \
-+		(((u_int64_t)(c)[75]) << 32) | \
-+		(((u_int64_t)(c)[76]) << 24) | \
-+		(((u_int64_t)(c)[77]) << 16) | \
-+		(((u_int64_t)(c)[78]) <<  8) | \
-+		(((u_int64_t)(c)[79]) <<  0))
-+
-+#define	ISP2100_NVRAM_BOOT_LUN(c)		(c)[80]
-+
-+#define	ISP2200_HBA_FEATURES(c)			(c)[232] | ((c)[233] << 8)
-+
-+/*
-+ * Firmware Crash Dump
-+ *
-+ * QLogic needs specific information format when they look at firmware crashes.
-+ *
-+ * This is incredibly kernel memory consumptive (to say the least), so this
-+ * code is only compiled in when needed.
-+ */
-+
-+#define	QLA2200_RISC_IMAGE_DUMP_SIZE					\
-+	(1 * sizeof (u_int16_t)) +	/* 'used' flag (also HBA type) */ \
-+	(352 * sizeof (u_int16_t)) +	/* RISC registers */		\
-+ 	(61440 * sizeof (u_int16_t))	/* RISC SRAM (offset 0x1000..0xffff) */
-+#define	QLA2300_RISC_IMAGE_DUMP_SIZE					\
-+	(1 * sizeof (u_int16_t)) +	/* 'used' flag (also HBA type) */ \
-+	(464 * sizeof (u_int16_t)) +	/* RISC registers */		\
-+ 	(63488 * sizeof (u_int16_t)) +	/* RISC SRAM (0x0800..0xffff) */ \
-+	(4096 * sizeof (u_int16_t)) +	/* RISC SRAM (0x10000..0x10FFF) */ \
-+	(61440 * sizeof (u_int16_t))	/* RISC SRAM (0x11000..0x1FFFF) */
-+/* the larger of the two */
-+#define	ISP_CRASH_IMAGE_SIZE	QLA2300_RISC_IMAGE_DUMP_SIZE
-+#endif	/* _ISPREG_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_target.c	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,1195 @@
-+/* @(#)isp_target.c 1.21 */
-+/*
-+ * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
-+ *
-+ * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
-+ * All rights reserved.
-+ * mjacob@feral.com
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Bug fixes gratefully acknowledged from:
-+ *	Oded Kedem <oded@kashya.com>
-+ */
-+/*
-+ * Include header file appropriate for platform we're building on.
-+ */
-+
-+#ifdef	__NetBSD__
-+#include <dev/ic/isp_netbsd.h>
-+#endif
-+#ifdef	__FreeBSD__
-+#include <dev/isp/isp_freebsd.h>
-+#endif
-+#ifdef	__OpenBSD__
-+#include <dev/ic/isp_openbsd.h>
-+#endif
-+#ifdef	__linux__
-+#include "isp_linux.h"
-+#endif
-+
-+#ifdef	ISP_TARGET_MODE
-+static const char atiocope[] =
-+    "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
-+    "on bus %d";
-+static const char atior[] =
-+    "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
-+    "on bus %d";
-+
-+static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
-+static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
-+static void isp_notify_ack(struct ispsoftc *, void *);
-+static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
-+static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
-+static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
-+static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
-+
-+/*
-+ * The Qlogic driver gets an interrupt to look at response queue entries.
-+ * Some of these are status completions for initiatior mode commands, but
-+ * if target mode is enabled, we get a whole wad of response queue entries
-+ * to be handled here.
-+ *
-+ * Basically the split into 3 main groups: Lun Enable/Modification responses,
-+ * SCSI Command processing, and Immediate Notification events.
-+ *
-+ * You start by writing a request queue entry to enable target mode (and
-+ * establish some resource limitations which you can modify later).
-+ * The f/w responds with a LUN ENABLE or LUN MODIFY response with
-+ * the status of this action. If the enable was successful, you can expect...
-+ *
-+ * Response queue entries with SCSI commands encapsulate show up in an ATIO
-+ * (Accept Target IO) type- sometimes with enough info to stop the command at
-+ * this level. Ultimately the driver has to feed back to the f/w's request
-+ * queue a sequence of CTIOs (continue target I/O) that describe data to
-+ * be moved and/or status to be sent) and finally finishing with sending
-+ * to the f/w's response queue an ATIO which then completes the handshake
-+ * with the f/w for that command. There's a lot of variations on this theme,
-+ * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
-+ * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
-+ * gist of it.
-+ *
-+ * The third group that can show up in the response queue are Immediate
-+ * Notification events. These include things like notifications of SCSI bus
-+ * resets, or Bus Device Reset messages or other messages received. This
-+ * a classic oddbins area. It can get  a little weird because you then turn
-+ * around and acknowledge the Immediate Notify by writing an entry onto the
-+ * request queue and then the f/w turns around and gives you an acknowledgement
-+ * to *your* acknowledgement on the response queue (the idea being to let
-+ * the f/w tell you when the event is *really* over I guess).
-+ *
-+ */
-+
-+
-+/*
-+ * A new response queue entry has arrived. The interrupt service code
-+ * has already swizzled it into the platform dependent from canonical form.
-+ *
-+ * Because of the way this driver is designed, unfortunately most of the
-+ * actual synchronization work has to be done in the platform specific
-+ * code- we have no synchroniation primitives in the common code.
-+ */
-+
-+int
-+isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
-+{
-+	u_int16_t status, seqid;
-+	union {
-+		at_entry_t	*atiop;
-+		at2_entry_t	*at2iop;
-+		ct_entry_t	*ctiop;
-+		ct2_entry_t	*ct2iop;
-+		lun_entry_t	*lunenp;
-+		in_entry_t	*inotp;
-+		in_fcentry_t	*inot_fcp;
-+		na_entry_t	*nackp;
-+		na_fcentry_t	*nack_fcp;
-+		isphdr_t	*hp;
-+		void *		*vp;
-+#define	atiop		unp.atiop
-+#define	at2iop		unp.at2iop
-+#define	ctiop		unp.ctiop
-+#define	ct2iop		unp.ct2iop
-+#define	lunenp		unp.lunenp
-+#define	inotp		unp.inotp
-+#define	inot_fcp	unp.inot_fcp
-+#define	nackp		unp.nackp
-+#define	nack_fcp	unp.nack_fcp
-+#define	hdrp		unp.hp
-+	} unp;
-+	u_int8_t local[QENTRY_LEN];
-+	int bus, type, rval = 1;
-+
-+	type = isp_get_response_type(isp, (isphdr_t *)vptr);
-+	unp.vp = vptr;
-+
-+	ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
-+
-+	switch(type) {
-+	case RQSTYPE_ATIO:
-+		isp_get_atio(isp, atiop, (at_entry_t *) local);
-+		isp_handle_atio(isp, (at_entry_t *) local);
-+		break;
-+	case RQSTYPE_CTIO:
-+		isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
-+		isp_handle_ctio(isp, (ct_entry_t *) local);
-+		break;
-+	case RQSTYPE_ATIO2:
-+		isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
-+		isp_handle_atio2(isp, (at2_entry_t *) local);
-+		break;
-+	case RQSTYPE_CTIO2:
-+		isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
-+		isp_handle_ctio2(isp, (ct2_entry_t *) local);
-+		break;
-+	case RQSTYPE_ENABLE_LUN:
-+	case RQSTYPE_MODIFY_LUN:
-+		isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
-+		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
-+		break;
-+
-+	case RQSTYPE_NOTIFY:
-+		/*
-+		 * Either the ISP received a SCSI message it can't
-+		 * handle, or it's returning an Immed. Notify entry
-+		 * we sent. We can send Immed. Notify entries to
-+		 * increment the firmware's resource count for them
-+		 * (we set this initially in the Enable Lun entry).
-+		 */
-+		bus = 0;
-+		if (IS_FC(isp)) {
-+			isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
-+			inot_fcp = (in_fcentry_t *) local;
-+			status = inot_fcp->in_status;
-+			seqid = inot_fcp->in_seqid;
-+		} else {
-+			isp_get_notify(isp, inotp, (in_entry_t *)local);
-+			inotp = (in_entry_t *) local;
-+			status = inotp->in_status & 0xff;
-+			seqid = inotp->in_seqid;
-+			if (IS_DUALBUS(isp)) {
-+				bus = GET_BUS_VAL(inotp->in_iid);
-+				SET_BUS_VAL(inotp->in_iid, 0);
-+			}
-+		}
-+		isp_prt(isp, ISP_LOGTDEBUG0,
-+		    "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
-+		    bus, status, seqid);
-+
-+		/*
-+		 * ACK it right away.
-+		 */
-+		isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
-+		switch (status) {
-+		case IN_RESET:
-+			(void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
-+			break;
-+		case IN_MSG_RECEIVED:
-+		case IN_IDE_RECEIVED:
-+			if (IS_FC(isp)) {
-+				isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
-+			} else {
-+				isp_got_msg(isp, bus, (in_entry_t *)local);
-+			}
-+			break;
-+		case IN_RSRC_UNAVAIL:
-+			isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
-+			break;
-+		case IN_PORT_LOGOUT:
-+		case IN_ABORT_TASK:
-+		case IN_PORT_CHANGED:
-+		case IN_GLOBAL_LOGO:
-+			(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
-+			break;
-+		default:
-+			isp_prt(isp, ISP_LOGERR,
-+			    "bad status (0x%x) in isp_target_notify", status);
-+			break;
-+		}
-+		break;
-+
-+	case RQSTYPE_NOTIFY_ACK:
-+		/*
-+		 * The ISP is acknowledging our acknowledgement of an
-+		 * Immediate Notify entry for some asynchronous event.
-+		 */
-+		if (IS_FC(isp)) {
-+			isp_get_notify_ack_fc(isp, nack_fcp,
-+			    (na_fcentry_t *)local);
-+			nack_fcp = (na_fcentry_t *)local;
-+			isp_prt(isp, ISP_LOGTDEBUG1,
-+			    "Notify Ack status=0x%x seqid 0x%x",
-+			    nack_fcp->na_status, nack_fcp->na_seqid);
-+		} else {
-+			isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
-+			nackp = (na_entry_t *)local;
-+			isp_prt(isp, ISP_LOGTDEBUG1,
-+			    "Notify Ack event 0x%x status=0x%x seqid 0x%x",
-+			    nackp->na_event, nackp->na_status, nackp->na_seqid);
-+		}
-+		break;
-+	default:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Unknown entry type 0x%x in isp_target_notify", type);
-+		rval = 0;
-+		break;
-+	}
-+#undef	atiop
-+#undef	at2iop
-+#undef	ctiop
-+#undef	ct2iop
-+#undef	lunenp
-+#undef	inotp
-+#undef	inot_fcp
-+#undef	nackp
-+#undef	nack_fcp
-+#undef	hdrp
-+	return (rval);
-+}
-+
-+ 
-+/*
-+ * Toggle (on/off) target mode for bus/target/lun
-+ *
-+ * The caller has checked for overlap and legality.
-+ *
-+ * Note that not all of bus, target or lun can be paid attention to.
-+ * Note also that this action will not be complete until the f/w writes
-+ * response entry. The caller is responsible for synchronizing this.
-+ */
-+int
-+isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
-+    int cmd_cnt, int inot_cnt, u_int32_t opaque)
-+{
-+	lun_entry_t el;
-+	u_int16_t nxti, optr;
-+	void *outp;
-+
-+
-+	MEMZERO(&el, sizeof (el));
-+	if (IS_DUALBUS(isp)) {
-+		el.le_rsvd = (bus & 0x1) << 7;
-+	}
-+	el.le_cmd_count = cmd_cnt;
-+	el.le_in_count = inot_cnt;
-+	if (cmd == RQSTYPE_ENABLE_LUN) {
-+		if (IS_SCSI(isp)) {
-+			el.le_flags = LUN_TQAE|LUN_DISAD;
-+			el.le_cdb6len = 12;
-+			el.le_cdb7len = 12;
-+		}
-+	} else if (cmd == -RQSTYPE_ENABLE_LUN) {
-+		cmd = RQSTYPE_ENABLE_LUN;
-+		el.le_cmd_count = 0;
-+		el.le_in_count = 0;
-+	} else if (cmd == -RQSTYPE_MODIFY_LUN) {
-+		cmd = RQSTYPE_MODIFY_LUN;
-+		el.le_ops = LUN_CCDECR | LUN_INDECR;
-+	} else {
-+		el.le_ops = LUN_CCINCR | LUN_ININCR;
-+	}
-+	el.le_header.rqs_entry_type = cmd;
-+	el.le_header.rqs_entry_count = 1;
-+	el.le_reserved = opaque;
-+	if (IS_SCSI(isp)) {
-+		el.le_tgt = tgt;
-+		el.le_lun = lun;
-+	} else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
-+		el.le_lun = lun;
-+	}
-+	el.le_timeout = 2;
-+
-+	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Request Queue Overflow in isp_lun_cmd");
-+		return (-1);
-+	}
-+	ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
-+	isp_put_enable_lun(isp, &el, outp);
-+	ISP_ADD_REQUEST(isp, nxti);
-+	return (0);
-+}
-+
-+
-+int
-+isp_target_put_entry(struct ispsoftc *isp, void *ap)
-+{
-+	void *outp;
-+	u_int16_t nxti, optr;
-+	u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
-+
-+	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "Request Queue Overflow in isp_target_put_entry");
-+		return (-1);
-+	}
-+	switch (etype) {
-+	case RQSTYPE_ATIO:
-+		isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
-+		break;
-+	case RQSTYPE_ATIO2:
-+		isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
-+		break;
-+	case RQSTYPE_CTIO:
-+		isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
-+		break;
-+	case RQSTYPE_CTIO2:
-+		isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
-+		break;
-+	default:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Unknown type 0x%x in isp_put_entry", etype);
-+		return (-1);
-+	}
-+
-+	ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
-+	ISP_ADD_REQUEST(isp, nxti);
-+	return (0);
-+}
-+
-+int
-+isp_target_put_atio(struct ispsoftc *isp, void *arg)
-+{
-+	union {
-+		at_entry_t _atio;
-+		at2_entry_t _atio2;
-+	} atun;
-+
-+	MEMZERO(&atun, sizeof atun);
-+	if (IS_FC(isp)) {
-+		at2_entry_t *aep = arg;
-+		atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
-+		atun._atio2.at_header.rqs_entry_count = 1;
-+		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
-+			atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
-+		} else {
-+			atun._atio2.at_lun = (u_int8_t) aep->at_lun;
-+		}
-+		atun._atio2.at_iid = aep->at_iid;
-+		atun._atio2.at_rxid = aep->at_rxid;
-+		atun._atio2.at_status = CT_OK;
-+	} else {
-+		at_entry_t *aep = arg;
-+		atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
-+		atun._atio.at_header.rqs_entry_count = 1;
-+		atun._atio.at_handle = aep->at_handle;
-+		atun._atio.at_iid = aep->at_iid;
-+		atun._atio.at_tgt = aep->at_tgt;
-+		atun._atio.at_lun = aep->at_lun;
-+		atun._atio.at_tag_type = aep->at_tag_type;
-+		atun._atio.at_tag_val = aep->at_tag_val;
-+		atun._atio.at_status = (aep->at_flags & AT_TQAE);
-+		atun._atio.at_status |= CT_OK;
-+	}
-+	return (isp_target_put_entry(isp, &atun));
-+}
-+
-+/*
-+ * Command completion- both for handling cases of no resources or
-+ * no blackhole driver, or other cases where we have to, inline,
-+ * finish the command sanely, or for normal command completion.
-+ *
-+ * The 'completion' code value has the scsi status byte in the low 8 bits.
-+ * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
-+ * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
-+ * values.
-+ *
-+ * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
-+ * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
-+ *
-+ * For both parallel && fibre channel, we use the feature that does
-+ * an automatic resource autoreplenish so we don't have then later do
-+ * put of an atio to replenish the f/w's resource count.
-+ */
-+
-+int
-+isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
-+{
-+	int sts;
-+	union {
-+		ct_entry_t _ctio;
-+		ct2_entry_t _ctio2;
-+	} un;
-+
-+	MEMZERO(&un, sizeof un);
-+	sts = code & 0xff;
-+
-+	if (IS_FC(isp)) {
-+		at2_entry_t *aep = arg;
-+		ct2_entry_t *cto = &un._ctio2;
-+
-+		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
-+		cto->ct_header.rqs_entry_count = 1;
-+		cto->ct_iid = aep->at_iid;
-+		if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
-+			cto->ct_lun = aep->at_lun;
-+		}
-+		cto->ct_rxid = aep->at_rxid;
-+		cto->rsp.m1.ct_scsi_status = sts & 0xff;
-+		cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
-+		if (hdl == 0) {
-+			cto->ct_flags |= CT2_CCINCR;
-+		}
-+		if (aep->at_datalen) {
-+			cto->ct_resid = aep->at_datalen;
-+			cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
-+		}
-+		if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
-+			cto->rsp.m1.ct_resp[0] = 0xf0;
-+			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
-+			cto->rsp.m1.ct_resp[7] = 8;
-+			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
-+			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
-+			cto->rsp.m1.ct_senselen = 16;
-+			cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
-+		}
-+		cto->ct_syshandle = hdl;
-+	} else {
-+		at_entry_t *aep = arg;
-+		ct_entry_t *cto = &un._ctio;
-+
-+		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
-+		cto->ct_header.rqs_entry_count = 1;
-+		cto->ct_fwhandle = aep->at_handle;
-+		cto->ct_iid = aep->at_iid;
-+		cto->ct_tgt = aep->at_tgt;
-+		cto->ct_lun = aep->at_lun;
-+		cto->ct_tag_type = aep->at_tag_type;
-+		cto->ct_tag_val = aep->at_tag_val;
-+		if (aep->at_flags & AT_TQAE) {
-+			cto->ct_flags |= CT_TQAE;
-+		}
-+		cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
-+		if (hdl == 0) {
-+			cto->ct_flags |= CT_CCINCR;
-+		}
-+		cto->ct_scsi_status = sts;
-+		cto->ct_syshandle = hdl;
-+	}
-+	return (isp_target_put_entry(isp, &un));
-+}
-+
-+int
-+isp_target_async(struct ispsoftc *isp, int bus, int event)
-+{
-+	tmd_event_t evt;
-+	tmd_msg_t msg;
-+
-+	switch (event) {
-+	/*
-+	 * These three we handle here to propagate an effective bus reset
-+	 * upstream, but these do not require any immediate notify actions
-+	 * so we return when done.
-+	 */
-+	case ASYNC_LIP_F8:
-+	case ASYNC_LIP_OCCURRED:
-+	case ASYNC_LOOP_UP:
-+	case ASYNC_LOOP_DOWN:
-+	case ASYNC_LOOP_RESET:
-+	case ASYNC_PTPMODE:
-+		/*
-+		 * These don't require any immediate notify actions. We used
-+		 * treat them like SCSI Bus Resets, but that was just plain
-+		 * wrong. Let the normal CTIO completion report what occurred.
-+		 */
-+                return (0);
-+
-+	case ASYNC_BUS_RESET:
-+	case ASYNC_TIMEOUT_RESET:
-+		if (IS_FC(isp)) {
-+			return (0); /* we'll be getting an inotify instead */
-+		}
-+		evt.ev_bus = bus;
-+		evt.ev_event = event;
-+		(void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
-+		break;
-+	case ASYNC_DEVICE_RESET:
-+		/*
-+		 * Bus Device Reset resets a specific target, so
-+		 * we pass this as a synthesized message.
-+		 */
-+		MEMZERO(&msg, sizeof msg);
-+		if (IS_FC(isp)) {
-+			msg.nt_iid = FCPARAM(isp)->isp_loopid;
-+		} else {
-+			msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
-+		}
-+		msg.nt_bus = bus;
-+		msg.nt_msg[0] = MSG_BUS_DEV_RESET;
-+		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
-+		break;
-+	case ASYNC_CTIO_DONE:
-+		evt.ev_bus = bus;
-+		evt.ev_event = event;
-+		(void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
-+		return (0);
-+	default:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "isp_target_async: unknown event 0x%x", event);
-+		break;
-+	}
-+	if (isp->isp_state == ISP_RUNSTATE)
-+		isp_notify_ack(isp, NULL);
-+	return(0);
-+}
-+
-+
-+/*
-+ * Process a received message.
-+ * The ISP firmware can handle most messages, there are only
-+ * a few that we need to deal with:
-+ * - abort: clean up the current command
-+ * - abort tag and clear queue
-+ */
-+
-+static void
-+isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
-+{
-+	u_int8_t status = inp->in_status & ~QLTM_SVALID;
-+
-+	if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
-+		tmd_msg_t msg;
-+
-+		MEMZERO(&msg, sizeof (msg));
-+		msg.nt_bus = bus;
-+		msg.nt_iid = inp->in_iid;
-+		msg.nt_tgt = inp->in_tgt;
-+		msg.nt_lun = inp->in_lun;
-+		msg.nt_tagtype = inp->in_tag_type;
-+		msg.nt_tagval = inp->in_tag_val;
-+		MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
-+		(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
-+	} else {
-+		isp_prt(isp, ISP_LOGERR,
-+		    "unknown immediate notify status 0x%x", inp->in_status);
-+	}
-+}
-+
-+/*
-+ * Synthesize a message from the task management flags in a FCP_CMND_IU.
-+ */
-+static void
-+isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
-+{
-+	int lun;
-+	static const char f1[] = "%s from iid %d lun %d seq 0x%x";
-+	static const char f2[] = 
-+	    "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
-+
-+	if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
-+		lun = inp->in_scclun;
-+	} else {
-+		lun = inp->in_lun;
-+	}
-+
-+	if (inp->in_status != IN_MSG_RECEIVED) {
-+		isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
-+		    inp->in_status, lun, inp->in_iid,
-+		    inp->in_task_flags,  inp->in_seqid);
-+	} else {
-+		tmd_msg_t msg;
-+
-+		MEMZERO(&msg, sizeof (msg));
-+		msg.nt_bus = bus;
-+		msg.nt_iid = inp->in_iid;
-+		msg.nt_tagval = inp->in_seqid;
-+		msg.nt_lun = lun;
-+
-+		if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
-+			isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
-+			    inp->in_iid, lun, inp->in_seqid);
-+			msg.nt_msg[0] = MSG_ABORT_TAG;
-+		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
-+			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
-+			    inp->in_iid, lun, inp->in_seqid);
-+			msg.nt_msg[0] = MSG_CLEAR_QUEUE;
-+		} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
-+			isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
-+			    inp->in_iid, lun, inp->in_seqid);
-+			msg.nt_msg[0] = MSG_BUS_DEV_RESET;
-+		} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
-+			isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
-+			    inp->in_iid, lun, inp->in_seqid);
-+			/* ???? */
-+			msg.nt_msg[0] = MSG_REL_RECOVERY;
-+		} else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
-+			isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
-+			    inp->in_iid, lun, inp->in_seqid);
-+			msg.nt_msg[0] = MSG_TERM_IO_PROC;
-+		} else {
-+			isp_prt(isp, ISP_LOGWARN, f2, "task flag",
-+			    inp->in_status, lun, inp->in_iid,
-+			    inp->in_task_flags,  inp->in_seqid);
-+		}
-+		if (msg.nt_msg[0]) {
-+			(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
-+		}
-+	}
-+}
-+
-+static void
-+isp_notify_ack(struct ispsoftc *isp, void *arg)
-+{
-+	char storage[QENTRY_LEN];
-+	u_int16_t nxti, optr;
-+	void *outp;
-+
-+	if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
-+		isp_prt(isp, ISP_LOGWARN,
-+		    "Request Queue Overflow For isp_notify_ack");
-+		return;
-+	}
-+
-+	MEMZERO(storage, QENTRY_LEN);
-+
-+	if (IS_FC(isp)) {
-+		na_fcentry_t *na = (na_fcentry_t *) storage;
-+		if (arg) {
-+			in_fcentry_t *inp = arg;
-+			MEMCPY(storage, arg, sizeof (isphdr_t));
-+			na->na_iid = inp->in_iid;
-+			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
-+				na->na_lun = inp->in_scclun;
-+			} else {
-+				na->na_lun = inp->in_lun;
-+			}
-+			na->na_task_flags = inp->in_task_flags;
-+			na->na_seqid = inp->in_seqid;
-+			na->na_flags = NAFC_RCOUNT;
-+			na->na_status = inp->in_status;
-+			if (inp->in_status == IN_RESET) {
-+				na->na_flags |= NAFC_RST_CLRD;
-+			}
-+		} else {
-+			na->na_flags = NAFC_RST_CLRD;
-+		}
-+		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
-+		na->na_header.rqs_entry_count = 1;
-+		isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
-+	} else {
-+		na_entry_t *na = (na_entry_t *) storage;
-+		if (arg) {
-+			in_entry_t *inp = arg;
-+			MEMCPY(storage, arg, sizeof (isphdr_t));
-+			na->na_iid = inp->in_iid;
-+			na->na_lun = inp->in_lun;
-+			na->na_tgt = inp->in_tgt;
-+			na->na_seqid = inp->in_seqid;
-+			if (inp->in_status == IN_RESET) {
-+				na->na_event = NA_RST_CLRD;
-+			}
-+		} else {
-+			na->na_event = NA_RST_CLRD;
-+		}
-+		na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
-+		na->na_header.rqs_entry_count = 1;
-+		isp_put_notify_ack(isp, na, (na_entry_t *)outp);
-+	}
-+	ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
-+	ISP_ADD_REQUEST(isp, nxti);
-+}
-+
-+static void
-+isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
-+{
-+	int lun;
-+	lun = aep->at_lun;
-+	/*
-+	 * The firmware status (except for the QLTM_SVALID bit) indicates
-+	 * why this ATIO was sent to us.
-+	 *
-+	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
-+	 *
-+	 * If the DISCONNECTS DISABLED bit is set in the flags field,
-+	 * we're still connected on the SCSI bus - i.e. the initiator
-+	 * did not set DiscPriv in the identify message. We don't care
-+	 * about this so it's ignored.
-+	 */
-+
-+	switch(aep->at_status & ~QLTM_SVALID) {
-+	case AT_PATH_INVALID:
-+		/*
-+		 * ATIO rejected by the firmware due to disabled lun.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "rejected ATIO for disabled lun %d", lun);
-+		break;
-+	case AT_NOCAP:
-+		/*
-+		 * Requested Capability not available
-+		 * We sent an ATIO that overflowed the firmware's
-+		 * command resource count.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "rejected ATIO for lun %d because of command count"
-+		    " overflow", lun);
-+		break;
-+
-+	case AT_BDR_MSG:
-+		/*
-+		 * If we send an ATIO to the firmware to increment
-+		 * its command resource count, and the firmware is
-+		 * recovering from a Bus Device Reset, it returns
-+		 * the ATIO with this status. We set the command
-+		 * resource count in the Enable Lun entry and do
-+		 * not increment it. Therefore we should never get
-+		 * this status here.
-+		 */
-+		isp_prt(isp, ISP_LOGERR, atiocope, lun,
-+		    GET_BUS_VAL(aep->at_iid));
-+		break;
-+
-+	case AT_CDB:		/* Got a CDB */
-+	case AT_PHASE_ERROR:	/* Bus Phase Sequence Error */
-+		/*
-+		 * Punt to platform specific layer.
-+		 */
-+		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
-+		break;
-+
-+	case AT_RESET:
-+		/*
-+		 * A bus reset came along and blew away this command. Why
-+		 * they do this in addition the async event code stuff,
-+		 * I dunno.
-+		 *
-+		 * Ignore it because the async event will clear things
-+		 * up for us.
-+		 */
-+		isp_prt(isp, ISP_LOGWARN, atior, lun,
-+		    GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
-+		break;
-+
-+
-+	default:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Unknown ATIO status 0x%x from initiator %d for lun %d",
-+		    aep->at_status, aep->at_iid, lun);
-+		(void) isp_target_put_atio(isp, aep);
-+		break;
-+	}
-+}
-+
-+static void
-+isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
-+{
-+	int lun;
-+
-+	if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
-+		lun = aep->at_scclun;
-+	} else {
-+		lun = aep->at_lun;
-+	}
-+
-+	/*
-+	 * The firmware status (except for the QLTM_SVALID bit) indicates
-+	 * why this ATIO was sent to us.
-+	 *
-+	 * If QLTM_SVALID is set, the firware has recommended Sense Data.
-+	 *
-+	 * If the DISCONNECTS DISABLED bit is set in the flags field,
-+	 * we're still connected on the SCSI bus - i.e. the initiator
-+	 * did not set DiscPriv in the identify message. We don't care
-+	 * about this so it's ignored.
-+	 */
-+
-+	switch(aep->at_status & ~QLTM_SVALID) {
-+	case AT_PATH_INVALID:
-+		/*
-+		 * ATIO rejected by the firmware due to disabled lun.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "rejected ATIO2 for disabled lun %d", lun);
-+		break;
-+	case AT_NOCAP:
-+		/*
-+		 * Requested Capability not available
-+		 * We sent an ATIO that overflowed the firmware's
-+		 * command resource count.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "rejected ATIO2 for lun %d- command count overflow", lun);
-+		break;
-+
-+	case AT_BDR_MSG:
-+		/*
-+		 * If we send an ATIO to the firmware to increment
-+		 * its command resource count, and the firmware is
-+		 * recovering from a Bus Device Reset, it returns
-+		 * the ATIO with this status. We set the command
-+		 * resource count in the Enable Lun entry and no
-+		 * not increment it. Therefore we should never get
-+		 * this status here.
-+		 */
-+		isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
-+		break;
-+
-+	case AT_CDB:		/* Got a CDB */
-+		/*
-+		 * Punt to platform specific layer.
-+		 */
-+		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
-+		break;
-+
-+	case AT_RESET:
-+		/*
-+		 * A bus reset came along an blew away this command. Why
-+		 * they do this in addition the async event code stuff,
-+		 * I dunno.
-+		 *
-+		 * Ignore it because the async event will clear things
-+		 * up for us.
-+		 */
-+		isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
-+		break;
-+
-+
-+	default:
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
-+		    aep->at_status, aep->at_iid, lun);
-+		(void) isp_target_put_atio(isp, aep);
-+		break;
-+	}
-+}
-+
-+static void
-+isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
-+{
-+	void *xs;
-+	int pl = ISP_LOGTDEBUG2;
-+	char *fmsg = NULL;
-+
-+	if (ct->ct_syshandle) {
-+		xs = isp_find_xs(isp, ct->ct_syshandle);
-+		if (xs == NULL)
-+			pl = ISP_LOGALL;
-+	} else {
-+		xs = NULL;
-+	}
-+
-+	switch(ct->ct_status & ~QLTM_SVALID) {
-+	case CT_OK:
-+		/*
-+		 * There are generally 3 possibilities as to why we'd get
-+		 * this condition:
-+		 * 	We disconnected after receiving a CDB.
-+		 * 	We sent or received data.
-+		 * 	We sent status & command complete.
-+		 */
-+
-+		if (ct->ct_flags & CT_SENDSTATUS) {
-+			break;
-+		} else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
-+			/*
-+			 * Nothing to do in this case.
-+			 */
-+			isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
-+			    ct->ct_iid);
-+			return;
-+		}
-+		break;
-+
-+	case CT_BDR_MSG:
-+		/*
-+		 * Bus Device Reset message received or the SCSI Bus has
-+		 * been Reset; the firmware has gone to Bus Free.
-+		 *
-+		 * The firmware generates an async mailbox interupt to
-+		 * notify us of this and returns outstanding CTIOs with this
-+		 * status. These CTIOs are handled in that same way as
-+		 * CT_ABORTED ones, so just fall through here.
-+		 */
-+		fmsg = "Bus Device Reset";
-+		/*FALLTHROUGH*/
-+	case CT_RESET:
-+		if (fmsg == NULL)
-+			fmsg = "Bus Reset";
-+		/*FALLTHROUGH*/
-+	case CT_ABORTED:
-+		/*
-+		 * When an Abort message is received the firmware goes to
-+		 * Bus Free and returns all outstanding CTIOs with the status
-+		 * set, then sends us an Immediate Notify entry.
-+		 */
-+		if (fmsg == NULL)
-+			fmsg = "ABORT TAG message sent by Initiator";
-+
-+		isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
-+		break;
-+
-+	case CT_INVAL:
-+		/*
-+		 * CTIO rejected by the firmware due to disabled lun.
-+		 * "Cannot Happen".
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Firmware rejected CTIO for disabled lun %d",
-+		    ct->ct_lun);
-+		break;
-+
-+	case CT_NOPATH:
-+		/*
-+		 * CTIO rejected by the firmware due "no path for the
-+		 * nondisconnecting nexus specified". This means that
-+		 * we tried to access the bus while a non-disconnecting
-+		 * command is in process.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "Firmware rejected CTIO for bad nexus %d/%d/%d",
-+		    ct->ct_iid, ct->ct_tgt, ct->ct_lun);
-+		break;
-+
-+	case CT_RSELTMO:
-+		fmsg = "Reselection";
-+		/*FALLTHROUGH*/
-+	case CT_TIMEOUT:
-+		if (fmsg == NULL)
-+			fmsg = "Command";
-+		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
-+		break;
-+
-+	case	CT_PANIC:
-+		if (fmsg == NULL)
-+			fmsg = "Unrecoverable Error";
-+		/*FALLTHROUGH*/
-+	case CT_ERR:
-+		if (fmsg == NULL)
-+			fmsg = "Completed with Error";
-+		/*FALLTHROUGH*/
-+	case CT_PHASE_ERROR:
-+		if (fmsg == NULL)
-+			fmsg = "Phase Sequence Error";
-+		/*FALLTHROUGH*/
-+	case CT_TERMINATED:
-+		if (fmsg == NULL)
-+			fmsg = "terminated by TERMINATE TRANSFER";
-+		/*FALLTHROUGH*/
-+	case CT_NOACK:
-+		if (fmsg == NULL)
-+			fmsg = "unacknowledged Immediate Notify pending";
-+		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
-+		break;
-+	default:
-+		isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
-+		    ct->ct_status & ~QLTM_SVALID);
-+		break;
-+	}
-+
-+	if (xs == NULL) {
-+		/*
-+		 * There may be more than one CTIO for a data transfer,
-+		 * or this may be a status CTIO we're not monitoring.
-+		 *
-+		 * The assumption is that they'll all be returned in the
-+		 * order we got them.
-+		 */
-+		if (ct->ct_syshandle == 0) {
-+			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
-+				isp_prt(isp, pl,
-+				    "intermediate CTIO completed ok");
-+			} else {
-+				isp_prt(isp, pl,
-+				    "unmonitored CTIO completed ok");
-+			}
-+		} else {
-+			isp_prt(isp, pl,
-+			    "NO xs for CTIO (handle 0x%x) status 0x%x",
-+			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
-+		}
-+	} else {
-+		/*
-+		 * Final CTIO completed. Release DMA resources and
-+		 * notify platform dependent layers.
-+		 */
-+		if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
-+			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
-+		}
-+		isp_prt(isp, pl, "final CTIO complete");
-+		/*
-+		 * The platform layer will destroy the handle if appropriate.
-+		 */
-+		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
-+	}
-+}
-+
-+static void
-+isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
-+{
-+	XS_T *xs;
-+	int pl = ISP_LOGTDEBUG2;
-+	char *fmsg = NULL;
-+
-+	if (ct->ct_syshandle) {
-+		xs = isp_find_xs(isp, ct->ct_syshandle);
-+		if (xs == NULL)
-+			pl = ISP_LOGALL;
-+	} else {
-+		xs = NULL;
-+	}
-+
-+	switch(ct->ct_status & ~QLTM_SVALID) {
-+	case CT_BUS_ERROR:
-+		isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
-+		/* FALL Through */
-+	case CT_DATA_OVER:
-+	case CT_DATA_UNDER:
-+	case CT_OK:
-+		/*
-+		 * There are generally 2 possibilities as to why we'd get
-+		 * this condition:
-+		 * 	We sent or received data.
-+		 * 	We sent status & command complete.
-+		 */
-+
-+		break;
-+
-+	case CT_BDR_MSG:
-+		/*
-+		 * Target Reset function received.
-+		 *
-+		 * The firmware generates an async mailbox interupt to
-+		 * notify us of this and returns outstanding CTIOs with this
-+		 * status. These CTIOs are handled in that same way as
-+		 * CT_ABORTED ones, so just fall through here.
-+		 */
-+		fmsg = "TARGET RESET Task Management Function Received";
-+		/*FALLTHROUGH*/
-+	case CT_RESET:
-+		if (fmsg == NULL)
-+			fmsg = "LIP Reset";
-+		/*FALLTHROUGH*/
-+	case CT_ABORTED:
-+		/*
-+		 * When an Abort message is received the firmware goes to
-+		 * Bus Free and returns all outstanding CTIOs with the status
-+		 * set, then sends us an Immediate Notify entry.
-+		 */
-+		if (fmsg == NULL)
-+			fmsg = "ABORT Task Management Function Received";
-+
-+		isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
-+		break;
-+
-+	case CT_INVAL:
-+		/*
-+		 * CTIO rejected by the firmware - invalid data direction.
-+		 */
-+		isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
-+		break;
-+
-+	case CT_RSELTMO:
-+		fmsg = "failure to reconnect to initiator";
-+		/*FALLTHROUGH*/
-+	case CT_TIMEOUT:
-+		if (fmsg == NULL)
-+			fmsg = "command";
-+		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
-+		break;
-+
-+	case CT_ERR:
-+		fmsg = "Completed with Error";
-+		/*FALLTHROUGH*/
-+	case CT_LOGOUT:
-+		if (fmsg == NULL)
-+			fmsg = "Port Logout";
-+		/*FALLTHROUGH*/
-+	case CT_PORTNOTAVAIL:
-+		if (fmsg == NULL)
-+			fmsg = "Port not available";
-+		/*FALLTHROUGH*/
-+	case CT_PORTCHANGED:
-+		if (fmsg == NULL)
-+			fmsg = "Port Changed";
-+		/*FALLTHROUGH*/
-+	case CT_NOACK:
-+		if (fmsg == NULL)
-+			fmsg = "unacknowledged Immediate Notify pending";
-+		isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
-+		break;
-+
-+	case CT_INVRXID:
-+		/*
-+		 * CTIO rejected by the firmware because an invalid RX_ID.
-+		 * Just print a message.
-+		 */
-+		isp_prt(isp, ISP_LOGERR,
-+		    "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
-+		break;
-+
-+	default:
-+		isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
-+		    ct->ct_status & ~QLTM_SVALID);
-+		break;
-+	}
-+
-+	if (xs == NULL) {
-+		/*
-+		 * There may be more than one CTIO for a data transfer,
-+		 * or this may be a status CTIO we're not monitoring.
-+		 *
-+		 * The assumption is that they'll all be returned in the
-+		 * order we got them.
-+		 */
-+		if (ct->ct_syshandle == 0) {
-+			if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
-+				isp_prt(isp, pl,
-+				    "intermediate CTIO completed ok");
-+			} else {
-+				isp_prt(isp, pl,
-+				    "unmonitored CTIO completed ok");
-+			}
-+		} else {
-+			isp_prt(isp, pl,
-+			    "NO xs for CTIO (handle 0x%x) status 0x%x",
-+			    ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
-+		}
-+	} else {
-+		if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
-+			ISP_DMAFREE(isp, xs, ct->ct_syshandle);
-+		}
-+		if (ct->ct_flags & CT_SENDSTATUS) {
-+			/*
-+			 * Sent status and command complete.
-+			 *
-+			 * We're now really done with this command, so we
-+			 * punt to the platform dependent layers because
-+			 * only there can we do the appropriate command
-+			 * complete thread synchronization.
-+			 */
-+			isp_prt(isp, pl, "status CTIO complete");
-+		} else {
-+			/*
-+			 * Final CTIO completed. Release DMA resources and
-+			 * notify platform dependent layers.
-+			 */
-+			isp_prt(isp, pl, "data CTIO complete");
-+		}
-+		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
-+		/*
-+		 * The platform layer will destroy the handle if appropriate.
-+		 */
-+	}
-+}
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_target.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,562 @@
-+/* @(#)isp_target.h 1.18 */
-+/*
-+ * Qlogic Target Mode Structure and Flag Definitions
-+ *
-+ * Copyright (c) 1997, 1998
-+ * Patrick Stirling
-+ * pms@psconsult.com
-+ * All rights reserved.
-+ *
-+ * Additional Copyright (c) 1999, 2000, 2001
-+ * Matthew Jacob
-+ * mjacob@feral.com
-+ * All rights reserved.
-+ *
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+#ifndef	_ISP_TARGET_H
-+#define	_ISP_TARGET_H
-+
-+/*
-+ * Defines for all entry types
-+ */
-+#define QLTM_SVALID	0x80
-+#define	QLTM_SENSELEN	18
-+
-+/*
-+ * Structure for Enable Lun and Modify Lun queue entries
-+ */
-+typedef struct {
-+	isphdr_t	le_header;
-+	u_int32_t	le_reserved;
-+	u_int8_t	le_lun;
-+	u_int8_t	le_rsvd;
-+	u_int8_t	le_ops;		/* Modify LUN only */
-+	u_int8_t	le_tgt;		/* Not for FC */
-+	u_int32_t	le_flags;	/* Not for FC */
-+	u_int8_t	le_status;
-+	u_int8_t	le_reserved2;
-+	u_int8_t	le_cmd_count;
-+	u_int8_t	le_in_count;
-+	u_int8_t	le_cdb6len;	/* Not for FC */
-+	u_int8_t	le_cdb7len;	/* Not for FC */
-+	u_int16_t	le_timeout;
-+	u_int16_t	le_reserved3[20];
-+} lun_entry_t;
-+
-+/*
-+ * le_flags values
-+ */
-+#define LUN_TQAE	0x00000002	/* bit1  Tagged Queue Action Enable */
-+#define LUN_DSSM	0x01000000	/* bit24 Disable Sending SDP Message */
-+#define	LUN_DISAD	0x02000000	/* bit25 Disable autodisconnect */
-+#define LUN_DM		0x40000000	/* bit30 Disconnects Mandatory */
-+
-+/*
-+ * le_ops values
-+ */
-+#define LUN_CCINCR	0x01	/* increment command count */
-+#define LUN_CCDECR	0x02	/* decrement command count */
-+#define LUN_ININCR	0x40	/* increment immed. notify count */
-+#define LUN_INDECR	0x80	/* decrement immed. notify count */
-+
-+/*
-+ * le_status values
-+ */
-+#define	LUN_OK		0x01	/* we be rockin' */
-+#define LUN_ERR		0x04	/* request completed with error */
-+#define LUN_INVAL	0x06	/* invalid request */
-+#define LUN_NOCAP	0x16	/* can't provide requested capability */
-+#define LUN_ENABLED	0x3E	/* LUN already enabled */
-+
-+/*
-+ * Immediate Notify Entry structure
-+ */
-+#define IN_MSGLEN	8	/* 8 bytes */
-+#define IN_RSVDLEN	8	/* 8 words */
-+typedef struct {
-+	isphdr_t	in_header;
-+	u_int32_t	in_reserved;
-+	u_int8_t	in_lun;		/* lun */
-+	u_int8_t	in_iid;		/* initiator */
-+	u_int8_t	in_reserved2;
-+	u_int8_t	in_tgt;		/* target */
-+	u_int32_t	in_flags;
-+	u_int8_t	in_status;
-+	u_int8_t	in_rsvd2;
-+	u_int8_t	in_tag_val;	/* tag value */
-+	u_int8_t	in_tag_type;	/* tag type */
-+	u_int16_t	in_seqid;	/* sequence id */
-+	u_int8_t	in_msg[IN_MSGLEN];	/* SCSI message bytes */
-+	u_int16_t	in_reserved3[IN_RSVDLEN];
-+	u_int8_t	in_sense[QLTM_SENSELEN];/* suggested sense data */
-+} in_entry_t;
-+
-+typedef struct {
-+	isphdr_t	in_header;
-+	u_int32_t	in_reserved;
-+	u_int8_t	in_lun;		/* lun */
-+	u_int8_t	in_iid;		/* initiator */
-+	u_int16_t	in_scclun;
-+	u_int32_t	in_reserved2;
-+	u_int16_t	in_status;
-+	u_int16_t	in_task_flags;
-+	u_int16_t	in_seqid;	/* sequence id */
-+} in_fcentry_t;
-+
-+/*
-+ * Values for the in_status field
-+ */
-+#define	IN_REJECT	0x0D	/* Message Reject message received */
-+#define IN_RESET	0x0E	/* Bus Reset occurred */
-+#define IN_NO_RCAP	0x16	/* requested capability not available */
-+#define IN_IDE_RECEIVED	0x33	/* Initiator Detected Error msg received */
-+#define IN_RSRC_UNAVAIL	0x34	/* resource unavailable */
-+#define IN_MSG_RECEIVED	0x36	/* SCSI message received */
-+#define	IN_ABORT_TASK	0x20	/* task named in RX_ID is being aborted (FC) */
-+#define	IN_PORT_LOGOUT	0x29	/* port has logged out (FC) */
-+#define	IN_PORT_CHANGED	0x2A	/* port changed */
-+#define	IN_GLOBAL_LOGO	0x2E	/* all ports logged out */
-+#define	IN_NO_NEXUS	0x3B	/* Nexus not established */
-+
-+/*
-+ * Values for the in_task_flags field- should only get one at a time!
-+ */
-+#define	TASK_FLAGS_ABORT_TASK		(1<<9)
-+#define	TASK_FLAGS_CLEAR_TASK_SET	(1<<10)
-+#define	TASK_FLAGS_TARGET_RESET		(1<<13)
-+#define	TASK_FLAGS_CLEAR_ACA		(1<<14)
-+#define	TASK_FLAGS_TERMINATE_TASK	(1<<15)
-+
-+#ifndef	MSG_ABORT_TAG
-+#define	MSG_ABORT_TAG		0x06
-+#endif
-+#ifndef	MSG_CLEAR_QUEUE
-+#define	MSG_CLEAR_QUEUE		0x0e
-+#endif
-+#ifndef	MSG_BUS_DEV_RESET
-+#define	MSG_BUS_DEV_RESET	0x0b
-+#endif
-+#ifndef	MSG_REL_RECOVERY
-+#define	MSG_REL_RECOVERY	0x10
-+#endif
-+#ifndef	MSG_TERM_IO_PROC
-+#define	MSG_TERM_IO_PROC	0x11
-+#endif
-+
-+
-+/*
-+ * Notify Acknowledge Entry structure
-+ */
-+#define NA_RSVDLEN	22
-+typedef struct {
-+	isphdr_t	na_header;
-+	u_int32_t	na_reserved;
-+	u_int8_t	na_lun;		/* lun */
-+	u_int8_t	na_iid;		/* initiator */
-+	u_int8_t	na_reserved2;
-+	u_int8_t	na_tgt;		/* target */
-+	u_int32_t	na_flags;
-+	u_int8_t	na_status;
-+	u_int8_t	na_event;
-+	u_int16_t	na_seqid;	/* sequence id */
-+	u_int16_t	na_reserved3[NA_RSVDLEN];
-+} na_entry_t;
-+
-+/*
-+ * Value for the na_event field
-+ */
-+#define NA_RST_CLRD	0x80	/* Clear an async event notification */
-+#define	NA_OK		0x01	/* Notify Acknowledge Succeeded */
-+#define	NA_INVALID	0x06	/* Invalid Notify Acknowledge */
-+
-+#define	NA2_RSVDLEN	21
-+typedef struct {
-+	isphdr_t	na_header;
-+	u_int32_t	na_reserved;
-+	u_int8_t	na_lun;		/* lun */
-+	u_int8_t	na_iid;		/* initiator */
-+	u_int16_t	na_scclun;
-+	u_int16_t	na_flags;
-+	u_int16_t	na_reserved2;
-+	u_int16_t	na_status;
-+	u_int16_t	na_task_flags;
-+	u_int16_t	na_seqid;	/* sequence id */
-+	u_int16_t	na_reserved3[NA2_RSVDLEN];
-+} na_fcentry_t;
-+#define	NAFC_RCOUNT	0x80	/* increment resource count */
-+#define NAFC_RST_CLRD	0x20	/* Clear LIP Reset */
-+/*
-+ * Accept Target I/O Entry structure
-+ */
-+#define ATIO_CDBLEN	26
-+
-+typedef struct {
-+	isphdr_t	at_header;
-+	u_int16_t	at_reserved;
-+	u_int16_t	at_handle;
-+	u_int8_t	at_lun;		/* lun */
-+	u_int8_t	at_iid;		/* initiator */
-+	u_int8_t	at_cdblen; 	/* cdb length */
-+	u_int8_t	at_tgt;		/* target */
-+	u_int32_t	at_flags;
-+	u_int8_t	at_status;	/* firmware status */
-+	u_int8_t	at_scsi_status;	/* scsi status */
-+	u_int8_t	at_tag_val;	/* tag value */
-+	u_int8_t	at_tag_type;	/* tag type */
-+	u_int8_t	at_cdb[ATIO_CDBLEN];	/* received CDB */
-+	u_int8_t	at_sense[QLTM_SENSELEN];/* suggested sense data */
-+} at_entry_t;
-+
-+/*
-+ * at_flags values
-+ */
-+#define AT_NODISC	0x00008000	/* disconnect disabled */
-+#define AT_TQAE		0x00000002	/* Tagged Queue Action enabled */
-+
-+/*
-+ * at_status values
-+ */
-+#define AT_PATH_INVALID	0x07	/* ATIO sent to firmware for disabled lun */
-+#define	AT_RESET	0x0E	/* SCSI Bus Reset Occurred */
-+#define AT_PHASE_ERROR	0x14	/* Bus phase sequence error */
-+#define AT_NOCAP	0x16	/* Requested capability not available */
-+#define AT_BDR_MSG	0x17	/* Bus Device Reset msg received */
-+#define AT_CDB		0x3D	/* CDB received */
-+
-+/*
-+ * Macros to create and fetch and test concatenated handle and tag value macros
-+ */
-+
-+#define	AT_MAKE_TAGID(tid, aep)						\
-+	tid = ((aep)->at_handle << 16);					\
-+	if ((aep)->at_flags & AT_TQAE)					\
-+		(tid) |= ((aep)->at_tag_val + 1)
-+
-+#define	CT_MAKE_TAGID(tid, ct)						\
-+	tid = ((ct)->ct_fwhandle << 16);				\
-+	if ((ct)->ct_flags & CT_TQAE)					\
-+		(tid) |= ((ct)->ct_tag_val + 1)
-+
-+#define	AT_HAS_TAG(val)		((val) & 0xffff)
-+#define	AT_GET_TAG(val)		AT_HAS_TAG(val) - 1
-+#define	AT_GET_HANDLE(val)	((val) >> 16)
-+
-+/*
-+ * Accept Target I/O Entry structure, Type 2
-+ */
-+#define ATIO2_CDBLEN	16
-+
-+typedef struct {
-+	isphdr_t	at_header;
-+	u_int32_t	at_reserved;
-+	u_int8_t	at_lun;		/* lun or reserved */
-+	u_int8_t	at_iid;		/* initiator */
-+	u_int16_t	at_rxid; 	/* response ID */
-+	u_int16_t	at_flags;
-+	u_int16_t	at_status;	/* firmware status */
-+	u_int8_t	at_crn;		/* command reference number */
-+	u_int8_t	at_taskcodes;
-+	u_int8_t	at_taskflags;
-+	u_int8_t	at_execodes;
-+	u_int8_t	at_cdb[ATIO2_CDBLEN];	/* received CDB */
-+	u_int32_t	at_datalen;		/* allocated data len */
-+	u_int16_t	at_scclun;		/* SCC Lun or reserved */
-+	u_int16_t	at_wwpn[4];		/* WWPN of initiator */
-+	u_int16_t	at_reserved2[6];
-+	u_int16_t	at_oxid;
-+} at2_entry_t;
-+
-+#define	ATIO2_WWPN_OFFSET	0x2A
-+#define	ATIO2_OXID_OFFSET	0x3E
-+
-+#define	ATIO2_TC_ATTR_MASK	0x7
-+#define	ATIO2_TC_ATTR_SIMPLEQ	0
-+#define	ATIO2_TC_ATTR_HEADOFQ	1
-+#define	ATIO2_TC_ATTR_ORDERED	2
-+#define	ATIO2_TC_ATTR_ACAQ	4
-+#define	ATIO2_TC_ATTR_UNTAGGED	5
-+
-+#define	ATIO2_EX_WRITE		0x1
-+#define	ATIO2_EX_READ		0x2
-+
-+/*
-+ * Continue Target I/O Entry structure
-+ * Request from driver. The response from the
-+ * ISP firmware is the same except that the last 18
-+ * bytes are overwritten by suggested sense data if
-+ * the 'autosense valid' bit is set in the status byte.
-+ */
-+typedef struct {
-+	isphdr_t	ct_header;
-+	u_int16_t	ct_reserved;
-+#define	ct_syshandle	ct_reserved	/* we use this */
-+	u_int16_t	ct_fwhandle;	/* required by f/w */
-+	u_int8_t	ct_lun;	/* lun */
-+	u_int8_t	ct_iid;	/* initiator id */
-+	u_int8_t	ct_reserved2;
-+	u_int8_t	ct_tgt;	/* our target id */
-+	u_int32_t	ct_flags;
-+	u_int8_t 	ct_status;	/* isp status */
-+	u_int8_t 	ct_scsi_status;	/* scsi status */
-+	u_int8_t 	ct_tag_val;	/* tag value */
-+	u_int8_t 	ct_tag_type;	/* tag type */
-+	u_int32_t	ct_xfrlen;	/* transfer length */
-+	u_int32_t	ct_resid;	/* residual length */
-+	u_int16_t	ct_timeout;
-+	u_int16_t	ct_seg_count;
-+	/*
-+	 * This is so we can share tag name space with
-+	 * CTIO{2,3,4} with the minimum of pain.
-+	 */
-+	union {
-+		ispds_t		ct_a[ISP_RQDSEG];
-+	} _u;
-+#define	ct_dataseg	_u.ct_a
-+} ct_entry_t;
-+
-+/*
-+ * For some of the dual port SCSI adapters, port (bus #) is reported
-+ * in the MSbit of ct_iid. Bit fields are a bit too awkward here.
-+ *
-+ * Note that this does not apply to FC adapters at all which can and
-+ * do report IIDs between 129 && 255 (these represent devices that have
-+ * logged in across a SCSI fabric).
-+ */
-+#define	GET_IID_VAL(x)		(x & 0x3f)
-+#define	GET_BUS_VAL(x)		((x >> 7) & 0x1)
-+#define	SET_IID_VAL(y, x)	y = ((y & ~0x3f) | (x & 0x3f))
-+#define	SET_BUS_VAL(y, x)	y = ((y & 0x3f) | ((x & 0x1) << 7))
-+
-+/*
-+ * ct_flags values
-+ */
-+#define CT_TQAE		0x00000002	/* bit  1, Tagged Queue Action enable */
-+#define CT_DATA_IN	0x00000040	/* bits 6&7, Data direction */
-+#define CT_DATA_OUT	0x00000080	/* bits 6&7, Data direction */
-+#define CT_NO_DATA	0x000000C0	/* bits 6&7, Data direction */
-+#define	CT_CCINCR	0x00000100	/* bit 8, autoincrement atio count */
-+#define CT_DATAMASK	0x000000C0	/* bits 6&7, Data direction */
-+#define	CT_INISYNCWIDE	0x00004000	/* bit 14, Do Sync/Wide Negotiation */
-+#define CT_NODISC	0x00008000	/* bit 15, Disconnects disabled */
-+#define CT_DSDP		0x01000000	/* bit 24, Disable Save Data Pointers */
-+#define CT_SENDRDP	0x04000000	/* bit 26, Send Restore Pointers msg */
-+#define CT_SENDSTATUS	0x80000000	/* bit 31, Send SCSI status byte */
-+
-+/*
-+ * ct_status values
-+ * - set by the firmware when it returns the CTIO
-+ */
-+#define CT_OK		0x01	/* completed without error */
-+#define CT_ABORTED	0x02	/* aborted by host */
-+#define CT_ERR		0x04	/* see sense data for error */
-+#define CT_INVAL	0x06	/* request for disabled lun */
-+#define CT_NOPATH	0x07	/* invalid ITL nexus */
-+#define	CT_INVRXID	0x08	/* (FC only) Invalid RX_ID */
-+#define	CT_DATA_OVER	0x09	/* (FC only) Data Overrun */
-+#define CT_RSELTMO	0x0A	/* reselection timeout after 2 tries */
-+#define CT_TIMEOUT	0x0B	/* timed out */
-+#define CT_RESET	0x0E	/* SCSI Bus Reset occurred */
-+#define	CT_PARITY	0x0F	/* Uncorrectable Parity Error */
-+#define	CT_BUS_ERROR	0x10	/* (FC Only) DMA PCI Error */
-+#define	CT_PANIC	0x13	/* Unrecoverable Error */
-+#define CT_PHASE_ERROR	0x14	/* Bus phase sequence error */
-+#define CT_BDR_MSG	0x17	/* Bus Device Reset msg received */
-+#define	CT_DATA_UNDER	0x15	/* (FC only) Data Underrun */
-+#define CT_TERMINATED	0x19	/* due to Terminate Transfer mbox cmd */
-+#define	CT_PORTNOTAVAIL	0x28	/* port not available */
-+#define	CT_LOGOUT	0x29	/* port logout */
-+#define	CT_PORTCHANGED	0x2A	/* port changed */
-+#define	CT_IDE		0x33	/* Initiator Detected Error */
-+#define CT_NOACK	0x35	/* Outstanding Immed. Notify. entry */
-+
-+/*
-+ * When the firmware returns a CTIO entry, it may overwrite the last
-+ * part of the structure with sense data. This starts at offset 0x2E
-+ * into the entry, which is in the middle of ct_dataseg[1]. Rather
-+ * than define a new struct for this, I'm just using the sense data
-+ * offset.
-+ */
-+#define CTIO_SENSE_OFFSET	0x2E
-+
-+/*
-+ * Entry length in u_longs. All entries are the same size so
-+ * any one will do as the numerator.
-+ */
-+#define UINT32_ENTRY_SIZE	(sizeof(at_entry_t)/sizeof(u_int32_t))
-+
-+/*
-+ * QLA2100 CTIO (type 2) entry
-+ */
-+#define	MAXRESPLEN	26
-+typedef struct {
-+	isphdr_t	ct_header;
-+	u_int16_t	ct_reserved;
-+	u_int16_t	ct_fwhandle;	/* just to match CTIO */
-+	u_int8_t	ct_lun;		/* lun */
-+	u_int8_t	ct_iid;		/* initiator id */
-+	u_int16_t	ct_rxid;	/* response ID */
-+	u_int16_t	ct_flags;
-+	u_int16_t 	ct_status;	/* isp status */
-+	u_int16_t	ct_timeout;
-+	u_int16_t	ct_seg_count;
-+	u_int32_t	ct_reloff;	/* relative offset */
-+	int32_t		ct_resid;	/* residual length */
-+	union {
-+		/*
-+		 * The three different modes that the target driver
-+		 * can set the CTIO{2,3,4} up as.
-+		 *
-+		 * The first is for sending FCP_DATA_IUs as well as
-+		 * (optionally) sending a terminal SCSI status FCP_RSP_IU.
-+		 *
-+		 * The second is for sending SCSI sense data in an FCP_RSP_IU.
-+		 * Note that no FCP_DATA_IUs will be sent.
-+		 *
-+		 * The third is for sending FCP_RSP_IUs as built specifically
-+		 * in system memory as located by the isp_dataseg.
-+		 */
-+		struct {
-+			u_int32_t _reserved;
-+			u_int16_t _reserved2;
-+			u_int16_t ct_scsi_status;
-+			u_int32_t ct_xfrlen;
-+			union {
-+				ispds_t ct_a[ISP_RQDSEG_T2];	/* CTIO2 */
-+				ispds64_t ct_b[ISP_RQDSEG_T3];	/* CTIO3 */
-+				ispdslist_t ct_c;		/* CTIO4 */
-+			} _u;
-+#define	ct_dataseg	_u.ct_a
-+#define	ct_dataseg64	_u.ct_b
-+#define	ct_dslist	_u.ct_c
-+		} m0;
-+		struct {
-+			u_int16_t _reserved;
-+			u_int16_t _reserved2;
-+			u_int16_t ct_senselen;
-+			u_int16_t ct_scsi_status;
-+			u_int16_t ct_resplen;
-+			u_int8_t  ct_resp[MAXRESPLEN];
-+		} m1;
-+		struct {
-+			u_int32_t _reserved;
-+			u_int16_t _reserved2;
-+			u_int16_t _reserved3;
-+			u_int32_t ct_datalen;
-+			ispds_t ct_fcp_rsp_iudata;
-+		} m2;
-+		/*
-+		 * CTIO2 returned from F/W...
-+		 */
-+		struct {
-+			u_int32_t _reserved[4];
-+			u_int16_t ct_scsi_status;
-+			u_int8_t  ct_sense[QLTM_SENSELEN];
-+		} fw;
-+	} rsp;
-+} ct2_entry_t;
-+
-+/*
-+ * ct_flags values for CTIO2
-+ */
-+#define	CT2_FLAG_MMASK	0x0003
-+#define	CT2_FLAG_MODE0	0x0000
-+#define	CT2_FLAG_MODE1	0x0001
-+#define	CT2_FLAG_MODE2	0x0002
-+#define CT2_DATA_IN	CT_DATA_IN
-+#define CT2_DATA_OUT	CT_DATA_OUT
-+#define CT2_NO_DATA	CT_NO_DATA
-+#define CT2_DATAMASK	CT_DATAMASK
-+#define	CT2_CCINCR	0x0100
-+#define	CT2_FASTPOST	0x0200
-+#define	CT2_TERMINATE	0x4000
-+#define CT2_SENDSTATUS	0x8000
-+
-+/*
-+ * ct_status values are (mostly) the same as that for ct_entry.
-+ */
-+
-+/*
-+ * ct_scsi_status values- the low 8 bits are the normal SCSI status
-+ * we know and love. The upper 8 bits are validity markers for FCP_RSP_IU
-+ * fields.
-+ */
-+#define	CT2_RSPLEN_VALID	0x0100
-+#define	CT2_SNSLEN_VALID	0x0200
-+#define	CT2_DATA_OVER		0x0400
-+#define	CT2_DATA_UNDER		0x0800
-+
-+/*
-+ * Debug macros
-+ */
-+
-+#define	ISP_TDQE(isp, msg, idx, arg)	\
-+    if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
-+
-+#ifdef	ISP_TARGET_FUNCTIONS
-+/*
-+ * The functions below are for the publicly available
-+ * target mode functions that are internal to the Qlogic driver.
-+ */
-+
-+/*
-+ * This function handles new response queue entry appropriate for target mode.
-+ */
-+int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
-+
-+/*
-+ * Enable/Disable/Modify a logical unit.
-+ * (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
-+ */
-+#define	DFLT_CMND_CNT	0xfe	/* unmonitored */
-+#define	DFLT_INOT_CNT	16
-+int isp_lun_cmd(struct ispsoftc *, int, int, int, int, int, int, u_int32_t);
-+
-+/*
-+ * General request queue 'put' routine for target mode entries.
-+ */
-+int isp_target_put_entry(struct ispsoftc *isp, void *);
-+
-+/*
-+ * General routine to put back an ATIO entry-
-+ * used for replenishing f/w resource counts.
-+ * The argument is a pointer to a source ATIO
-+ * or ATIO2.
-+ */
-+int isp_target_put_atio(struct ispsoftc *, void *);
-+
-+/*
-+ * General routine to send a final CTIO for a command- used mostly for
-+ * local responses.
-+ */
-+int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
-+#define	ECMD_SVALID	0x100
-+
-+/*
-+ * Handle an asynchronous event
-+ *
-+ * Return nonzero if the interrupt that generated this event has been dismissed.
-+ */
-+
-+int isp_target_async(struct ispsoftc *, int, int);
-+#endif
-+#endif	/* _ISP_TARGET_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/isp_tpublic.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,396 @@
-+/* @(#)isp_tpublic.h 1.11 */
-+/*
-+ * Qlogic ISP Host Adapter Public Target Interface Structures && Routines
-+ *---------------------------------------
-+ * Copyright (c) 2000, 2001, 2002, 2003 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification, immediately at the beginning of the file.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ * 
-+ * Matthew Jacob
-+ * Feral Software
-+ * mjacob@feral.com
-+ */
-+
-+/*
-+ * Required software target mode message and event handling structures.
-+ *
-+ * The message and event structures are used by the MI layer
-+ * to propagate messages and events upstream.
-+ */
-+
-+#ifndef	IN_MSGLEN
-+#define	IN_MSGLEN	8
-+#endif
-+typedef struct {
-+	void *		nt_hba;			/* HBA tag */
-+	u_int64_t	nt_iid;			/* inititator id */
-+	u_int64_t	nt_tgt;			/* target id */
-+	u_int64_t	nt_lun;			/* logical unit */
-+	u_int32_t	nt_tagval;		/* tag value */
-+	u_int8_t	nt_bus;			/* bus */
-+	u_int8_t	nt_tagtype;		/* tag type */
-+	u_int8_t	nt_msg[IN_MSGLEN];	/* message content */
-+} tmd_msg_t;
-+
-+typedef struct {
-+	void *		ev_hba;			/* HBA tag */
-+	u_int32_t	ev_bus;			/* bus */
-+	u_int32_t	ev_event;		/* type of async event */
-+} tmd_event_t;
-+
-+/*
-+ * Suggested Software Target Mode Command Handling structure.
-+ *
-+ * A note about terminology:
-+ *
-+ *   MD stands for "Machine Dependent".
-+ *
-+ *    This driver is structured in three layers: Outer MD, core, and inner MD.
-+ *    The latter also is bus dependent (i.e., is cognizant of PCI bus issues
-+ *    as well as platform issues).
-+ *
-+ *
-+ *   "Outer Layer" means "Other Module"
-+ *
-+ *    Some additional module that actually implements SCSI target command
-+ *    policy is the recipient of incoming commands and the source of the
-+ *    disposition for them.
-+ *
-+ * The command structure below is one suggested possible MD command structure,
-+ * but since the handling of thbis is entirely in the MD layer, there is
-+ * no explicit or implicit requirement that it be used.
-+ *
-+ * The cd_private tag should be used by the MD layer to keep a free list
-+ * of these structures. Code outside of this driver can then use this
-+ * to identify it's own unit structures. That is, when not on the MD
-+ * layer's freelist, the MD layer should shove into it the identifier
-+ * that the outer layer has for it- passed in on an initial QIN_HBA_REG
-+ * call (see below).
-+ *
-+ * The cd_hba tag is a tag that uniquely identifies the HBA this target
-+ * mode command is coming from. The outer layer has to pass this back
-+ * unchanged to avoid chaos.
-+ *
-+ * The cd_iid, cd_tgt, cd_lun and cd_bus tags are used to identify the
-+ * id of the initiator who sent us a command, the target claim to be, the
-+ * lun on the target we claim to be, and the bus instance (for multiple
-+ * bus host adapters) that this applies to (consider it an extra Port
-+ * parameter). The iid, tgt and lun values are deliberately chosen to be
-+ * fat so that, for example, World Wide Names can be used instead of
-+ * the units that the Qlogic firmware uses (in the case where the MD
-+ * layer maintains a port database, for example).
-+ *
-+ * The cd_tagtype field specifies what kind of command tag has been
-+ * sent with the command. The cd_tagval is the tag's value (low 16
-+ * bits). It also contains (in the upper 16 bits) any command handle.
-+ *
-+ *
-+ * N.B.: when the MD layer sends this command to outside software
-+ * the outside software likely *MUST* return the same cd_tagval that
-+ * was in place because this value is likely what the Qlogic f/w uses
-+ * to identify a command.
-+ *
-+ * The cd_cdb contains storage for the passed in command descriptor block.
-+ * This is the maximum size we can get out of the Qlogic f/w. There's no
-+ * passed in length because whoever decodes the command to act upon it
-+ * will know what the appropriate length is.
-+ *
-+ * The tag cd_lflags are the flags set by the MD driver when it gets
-+ * command incoming or when it needs to inform any outside entities
-+ * that the last requested action failed.
-+ *
-+ * The tag cd_hflags should be set by any outside software to indicate
-+ * the validity of sense and status fields (defined below) and to indicate
-+ * the direction data is expected to move. It is an error to have both
-+ * CDFH_DATA_IN and CDFH_DATA_OUT set.
-+ *
-+ * If the CDFH_STSVALID flag is set, the command should be completed (after
-+ * sending any data and/or status). If CDFH_SNSVALID is set and the MD layer
-+ * can also handle sending the associated sense data (either back with an
-+ * FCP RESPONSE IU for Fibre Channel or otherwise automatically handling a
-+ * REQUEST SENSE from the initator for this target/lun), the MD layer will
-+ * set the CDFL_SENTSENSE flag on successful transmission of the sense data.
-+ * It is an error for the CDFH_SNSVALID bit to be set and CDFH_STSVALID not
-+ * to be set. It is an error for the CDFH_SNSVALID be set and the associated
-+ * SCSI status (cd_scsi_status) not be set to CHECK CONDITON.
-+ * 
-+ * The tag cd_data points to a data segment to either be filled or
-+ * read from depending on the direction of data movement. The tag
-+ * is undefined if no data direction is set. The MD layer and outer
-+ * layers must agree on the meaning of cd_data.
-+ *
-+ * The tag cd_totlen is the total data amount expected to be moved
-+ * over the life of the command. It *may* be set by the MD layer, possibly
-+ * from the datalen field of an FCP CMND IU unit. If it shows up in the outer
-+ * layers set to zero and the CDB indicates data should be moved, the outer
-+ * layer should set it to the amount expected to be moved.
-+ *
-+ * The tag cd_resid should be the total residual of data not transferred.
-+ * The outer layers need to set this at the begining of command processing
-+ * to equal cd_totlen. As data is successfully moved, this value is decreased.
-+ * At the end of a command, any nonzero residual indicates the number of bytes
-+ * requested but not moved. XXXXXXXXXXXXXXXXXXXXXXX TOO VAGUE!!! 
-+ *
-+ * The tag cd_xfrlen is the length of the currently active data transfer.
-+ * This allows several interations between any outside software and the
-+ * MD layer to move data.
-+ *
-+ * The reason that total length and total residual have to be tracked
-+ * is that fibre channel FCP DATA IU units have to have a relative
-+ * offset field.
-+ *
-+ * N.B.: there is no necessary 1-to-1 correspondence between any one
-+ * data transfer segment and the number of CTIOs that will be generated
-+ * satisfy the current data transfer segment. It's not also possible to
-+ * predict how big a transfer can be before it will be 'too big'. Be
-+ * reasonable- a 64KB transfer is 'reasonable'. A 1MB transfer may not
-+ * be. A 32MB transfer is unreasonable. The problem here has to do with
-+ * how CTIOs can be used to map passed data pointers. In systems which
-+ * have page based scatter-gather requirements, each PAGESIZEd chunk will
-+ * consume one data segment descriptor- you get 3 or 4 of them per CTIO.
-+ * The size of the REQUEST QUEUE you drop a CTIO onto is finite (typically
-+ * it's 256, but on some systems it's even smaller, and note you have to
-+ * sure this queue with the initiator side of this driver).
-+ *
-+ * The tags cd_sense and cd_scsi_status are pretty obvious.
-+ *
-+ * The tag cd_error is to communicate between the MD layer and outer software
-+ * the current error conditions.
-+ *
-+ * The tag cd_lreserved, cd_hreserved are scratch areas for use for the MD
-+ * and outer layers respectively.
-+ * 
-+ */
-+
-+#ifndef	TMD_CDBLEN
-+#define	TMD_CDBLEN	18	/* 16 bytes, plus pad for alignment */
-+#endif
-+#ifndef	QLTM_SENSELEN
-+#define	QLTM_SENSELEN	18
-+#endif
-+#ifndef	QCDS
-+#define	QCDS	8
-+#endif
-+
-+typedef struct tmd_cmd {
-+	void *			cd_private;	/* private data pointer */
-+	void *			cd_hba;		/* HBA tag */
-+	void *			cd_data;	/* 'pointer' to data */
-+	u_int64_t		cd_iid;		/* initiator ID */
-+	u_int64_t		cd_tgt;		/* target id */
-+	u_int64_t		cd_lun;		/* logical unit */
-+	u_int32_t		cd_tagval;	/* tag value */
-+	u_int32_t		cd_lflags;	/* flags lower level sets */
-+	u_int32_t		cd_hflags;	/* flags higher level sets */
-+	u_int32_t		cd_totlen;	/* total data requirement */
-+	u_int32_t		cd_resid;	/* total data residual */
-+	u_int32_t		cd_xfrlen;	/* current data requirement */
-+	int32_t			cd_error;	/* current error */
-+	u_int16_t		cd_scsi_status;	/* closing SCSI status */
-+	u_int8_t		cd_chan;	/* channel on card */
-+	u_int8_t		cd_tagtype;	/* tag type */
-+	u_int8_t		cd_sense[QLTM_SENSELEN];
-+	u_int8_t		cd_cdb[TMD_CDBLEN];	/* Command */
-+	union {
-+		void *		ptrs[QCDS / sizeof (void *)];
-+		u_int64_t	llongs[QCDS / sizeof (u_int64_t)];
-+		u_int32_t	longs[QCDS / sizeof (u_int32_t)];
-+		u_int16_t	shorts[QCDS / sizeof (u_int16_t)];
-+		u_int8_t	bytes[QCDS];
-+	} cd_lreserved[2], cd_hreserved[2];
-+} tmd_cmd_t;
-+
-+#ifndef	TMD_SIZE
-+#define	TMD_SIZE	(sizeof (tmd_cmd_t))
-+#endif
-+
-+/*
-+ * Note that NODISC (obviously) doesn't apply to non-SPI transport.
-+ *
-+ * Note that knowing the data direction and lengh at the time of receipt of
-+ * a command from the initiator is a feature only of Fibre Channel.
-+ *
-+ * The CDFL_BIDIR is in anticipation of the adoption of some newer
-+ * features required by OSD.
-+ *
-+ * The principle selector for MD layer to know whether data is to
-+ * be transferred in any QOUT_TMD_CONT call is cd_xfrlen- the
-+ * flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction.
-+ */
-+#define	CDFL_SNSVALID	0x01		/* sense data (from f/w) good */
-+#define	CDFL_SENTSTATUS	0x02		/* last action sent status */
-+#define	CDFL_DATA_IN	0x04		/* target (us) -> initiator (them) */
-+#define	CDFL_DATA_OUT	0x08		/* initiator (them) -> target (us) */
-+#define	CDFL_BIDIR	0x0C		/* bidirectional data */
-+#define	CDFL_ERROR	0x10		/* last action ended in error */
-+#define	CDFL_NODISC	0x20		/* disconnects disabled */
-+#define	CDFL_SENTSENSE	0x40		/* last action sent sense data */
-+#define	CDFL_BUSY	0x80		/* this command is not on a free list */
-+#define	CDFL_PRIVATE	0xFF000000	/* private layer flags */
-+
-+#define	CDFH_SNSVALID	0x01		/* sense data (from outer layer) good */
-+#define	CDFH_STSVALID	0x02		/* status valid */
-+#define	CDFH_DATA_IN	0x04		/* target (us) -> initiator (them) */
-+#define	CDFH_DATA_OUT	0x08		/* initiator (them) -> target (us) */
-+#define	CDFH_DATA_MASK	0x0C		/* mask to cover data direction */
-+#define	CDFH_PRIVATE	0xFF000000	/* private layer flags */
-+
-+
-+/*
-+ * Action codes set by the Qlogic MD target driver for
-+ * the external layer to figure out what to do with.
-+ */
-+typedef enum {
-+	QOUT_HBA_REG=0,	/* the argument is a pointer to a hba_register_t */
-+	QOUT_ENABLE,	/* the argument is a pointer to a enadis_t */
-+	QOUT_DISABLE,	/* the argument is a pointer to a enadis_t */
-+	QOUT_TMD_START,	/* the argument is a pointer to a tmd_cmd_t */
-+	QOUT_TMD_DONE,	/* the argument is a pointer to a tmd_cmd_t */
-+	QOUT_TEVENT,	/* the argument is a pointer to a tmd_event_t */
-+	QOUT_TMSG,	/* the argument is a pointer to a tmd_msg_t */
-+	QOUT_IOCTL,	/* the argument is a pointer to a ioctl_cmd_t */
-+	QOUT_HBA_UNREG	/* the argument is a pointer to a hba_register_t */
-+} tact_e;
-+
-+/*
-+ * Action codes set by the external layer for the
-+ * MD Qlogic driver to figure out what to do with.
-+ */
-+typedef enum {
-+	QIN_HBA_REG=99,	/* the argument is a pointer to a hba_register_t */
-+	QIN_ENABLE,	/* the argument is a pointer to a enadis_t */
-+	QIN_DISABLE,	/* the argument is a pointer to a enadis_t */
-+	QIN_TMD_CONT,	/* the argument is a pointer to a tmd_cmd_t */
-+	QIN_TMD_FIN,	/* the argument is a pointer to a tmd_cmd_t */
-+	QIN_IOCTL,	/* the argument is a pointer to a ioctl_cmd_t */
-+	QIN_HBA_UNREG,	/* the argument is a pointer to a hba_register_t */
-+} qact_e;
-+
-+
-+/*
-+ * A word about the START/CONT/DONE/FIN dance:
-+ *
-+ *	When the HBA is enabled for receiving commands, one may	show up
-+ *	without notice. When that happens, the Qlogic target mode driver
-+ *	gets a tmd_cmd_t, fills it with the info that just arrived, and
-+ *	calls the outer layer with a QOUT_TMD_START code and pointer to
-+ *	the tmd_cmd_t.
-+ *
-+ *	The outer layer decodes the command, fetches data, prepares stuff,
-+ *	whatever, and starts by passing back the pointer with a QIN_TMD_CONT
-+ *	code which causes the Qlogic target mode driver to generate CTIOs to
-+ *	satisfy whatever action needs to be taken. When those CTIOs complete,
-+ *	the Qlogic target driver sends the pointer to the cmd_tmd_t back with
-+ *	a QOUT_TMD_DONE code. This repeats for as long as necessary.
-+ *
-+ *	The outer layer signals it wants to end the command by settings within
-+ *	the tmd_cmd_t itself. When the final QIN_TMD_CONT is reported completed,
-+ *	the outer layer frees the tmd_cmd_t by sending the pointer to it
-+ *	back with a QIN_TMD_FIN code.
-+ *
-+ *	The graph looks like:
-+ *
-+ *	QOUT_TMD_START -> [ QIN_TMD_CONT -> QOUT_TMD_DONE ] * -> QIN_TMD_FIN.
-+ *
-+ */
-+
-+/*
-+ * A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
-+ * with cd_hba, cd_iid, cd_chan, cd_tgt and cd_lun filled out.
-+ *
-+ * If an error occurs in either enabling or disabling the described lun
-+ * cd_error is set with an appropriate non-zero value.
-+ *
-+ * Logical unit zero must be the first enabled and the last disabled.
-+ */
-+typedef struct {
-+	void *			cd_private;	/* for outer layer usage */
-+	void *			cd_hba;		/* HBA tag */
-+	u_int64_t		cd_iid;		/* initiator ID */
-+	u_int64_t		cd_tgt;		/* target id */
-+	u_int64_t		cd_lun;		/* logical unit */
-+	u_int8_t		cd_chan;	/* channel on card */
-+	int32_t			cd_error;
-+} enadis_t;
-+
-+/*
-+ * This structure is used to register to other software modules the
-+ * binding of an HBA identifier, driver name and instance and the
-+ * lun width capapbilities of this target driver. It's up to each
-+ * platform to figure out how it wants to do this, but a typical
-+ * sequence would be for the MD layer to find some external module's
-+ * entry point and start by sending a QOUT_HBA_REG with info filled
-+ * in, and the external module to call back with a QIN_HBA_REG that
-+ * passes back the corresponding information.
-+ */
-+#define	QR_VERSION	1
-+typedef struct {
-+	void *	r_identity;
-+	void   (*r_action)(qact_e, void *);
-+	char	r_name[8];
-+	int	r_inst;
-+	int	r_version;
-+	enum { R_FC, R_SCSI } r_type;
-+} hba_register_t;
-+
-+/*
-+ * This structure is used to pass an encapsulated ioctl through to the
-+ * MD layer. In many implementations it's often convenient to open just
-+ * one device, but actions you want to take need to be taken on the
-+ * underlying HBA. Rather than invent a separate protocol for each action,
-+ * an ioctl passthrough seems simpler.
-+ *
-+ * In order to avoid cross domain copy problems, though, the caller will
-+ * be responsible for allocating and providing a staging area for all ioctl
-+ * related data. This, unavoidably, requires some ioctl decode capability
-+ * in the outer layer code.`
-+ *
-+ * And also, albeit being cheesy, we'll define a few internal ioctls here.
-+ */
-+typedef struct {
-+	void *	i_identity;	/* HBA tag */
-+	void *	i_syncptr;	/* synchronization pointer */
-+	int	i_cmd;		/* ioctl command */
-+	void *	i_arg;		/* ioctl argument area */
-+	int	i_errno;	/* ioctl error return */
-+} ioctl_cmd_t;
-+
-+#define	QI_IOC	('Q' << 8)
-+#define	QI_SCSI_TINI	QI_IOC|0
-+#define	QI_SCSI_CMD	QI_IOC|1
-+#define	QI_WWPN_XLT	QI_IOC|2
-+
-+/*
-+ * Target handler functions.
-+ *
-+ * The MD target handler function (the outer layer calls this)
-+ * should be be prototyped like:
-+ *
-+ *	void target_action(qact_e, void *arg)
-+ *
-+ * The outer layer target handler function (the MD layer calls this)
-+ * should be be prototyped like:
-+ *
-+ *	void system_target_handler(tact_e, void *arg)
-+ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/ispvar.h	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,902 @@
-+/* @(#)ispvar.h 1.44 */
-+/*
-+ * Soft Definitions for for Qlogic ISP SCSI adapters.
-+ *
-+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice immediately at the beginning of the file, without modification,
-+ *    this list of conditions, and the following disclaimer.
-+ * 2. The name of the author may not be used to endorse or promote products
-+ *    derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+
-+#ifndef	_ISPVAR_H
-+#define	_ISPVAR_H
-+
-+#if defined(__NetBSD__) || defined(__OpenBSD__)
-+#include <dev/ic/ispmbox.h>
-+#ifdef	ISP_TARGET_MODE
-+#include <dev/ic/isp_target.h>
-+#include <dev/ic/isp_tpublic.h>
-+#endif
-+#endif
-+#ifdef	__FreeBSD__
-+#include <dev/isp/ispmbox.h>
-+#ifdef	ISP_TARGET_MODE
-+#include <dev/isp/isp_target.h>
-+#include <dev/isp/isp_tpublic.h>
-+#endif
-+#endif
-+#ifdef	__linux__
-+#include "ispmbox.h"
-+#ifdef	ISP_TARGET_MODE
-+#include "isp_target.h"
-+#include "isp_tpublic.h"
-+#endif
-+#endif
-+
-+#define	ISP_CORE_VERSION_MAJOR	2
-+#define	ISP_CORE_VERSION_MINOR	7
-+
-+/*
-+ * Vector for bus specific code to provide specific services.
-+ */
-+struct ispsoftc;
-+struct ispmdvec {
-+	int		(*dv_rd_isr)
-+	    (struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-+	u_int16_t	(*dv_rd_reg) (struct ispsoftc *, int);
-+	void		(*dv_wr_reg) (struct ispsoftc *, int, u_int16_t);
-+	int		(*dv_mbxdma) (struct ispsoftc *);
-+	int		(*dv_dmaset) (struct ispsoftc *,
-+	    XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
-+	void		(*dv_dmaclr)
-+	    (struct ispsoftc *, XS_T *, u_int16_t);
-+	void		(*dv_reset0) (struct ispsoftc *);
-+	void		(*dv_reset1) (struct ispsoftc *);
-+	void		(*dv_dregs) (struct ispsoftc *, const char *);
-+	u_int16_t	*dv_ispfw;	/* ptr to f/w */
-+	u_int16_t	dv_conf1;
-+	u_int16_t	dv_clock;	/* clock frequency */
-+};
-+
-+/*
-+ * Overall parameters
-+ */
-+#define	MAX_TARGETS		16
-+#define	MAX_FC_TARG		256
-+#define	ISP_MAX_TARGETS(isp)	(IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
-+#define	ISP_MAX_LUNS(isp)	(isp)->isp_maxluns
-+
-+/*
-+ * 'Types'
-+ */
-+#ifdef	ISP_DAC_SUPPORTED
-+typedef	u_int64_t	isp_dma_addr_t;
-+#else
-+typedef	u_int32_t	isp_dma_addr_t;
-+#endif
-+
-+/*
-+ * Macros to access ISP registers through bus specific layers-
-+ * mostly wrappers to vector through the mdvec structure.
-+ */
-+#define	ISP_READ_ISR(isp, isrp, semap, mbox0p)	\
-+	(*(isp)->isp_mdvec->dv_rd_isr)(isp, isrp, semap, mbox0p)
-+
-+#define	ISP_READ(isp, reg)	\
-+	(*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
-+
-+#define	ISP_WRITE(isp, reg, val)	\
-+	(*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val))
-+
-+#define	ISP_MBOXDMASETUP(isp)	\
-+	(*(isp)->isp_mdvec->dv_mbxdma)((isp))
-+
-+#define	ISP_DMASETUP(isp, xs, req, iptrp, optr)	\
-+	(*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr))
-+
-+#define	ISP_DMAFREE(isp, xs, hndl)	\
-+	if ((isp)->isp_mdvec->dv_dmaclr) \
-+	    (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (hndl))
-+
-+#define	ISP_RESET0(isp)	\
-+	if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp))
-+#define	ISP_RESET1(isp)	\
-+	if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp))
-+#define	ISP_DUMPREGS(isp, m)	\
-+	if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp),(m))
-+
-+#define	ISP_SETBITS(isp, reg, val)	\
-+ (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val))
-+
-+#define	ISP_CLRBITS(isp, reg, val)	\
-+ (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val))
-+
-+/*
-+ * The MEMORYBARRIER macro is defined per platform (to provide synchronization
-+ * on Request and Response Queues, Scratch DMA areas, and Registers)
-+ *
-+ * Defined Memory Barrier Synchronization Types
-+ */
-+#define	SYNC_REQUEST	0	/* request queue synchronization */
-+#define	SYNC_RESULT	1	/* result queue synchronization */
-+#define	SYNC_SFORDEV	2	/* scratch, sync for ISP */
-+#define	SYNC_SFORCPU	3	/* scratch, sync for CPU */
-+#define	SYNC_REG	4	/* for registers */
-+
-+/*
-+ * Request/Response Queue defines and macros.
-+ * The maximum is defined per platform (and can be based on board type).
-+ */
-+/* This is the size of a queue entry (request and response) */
-+#define	QENTRY_LEN			64
-+/* Both request and result queue length must be a power of two */
-+#define	RQUEST_QUEUE_LEN(x)		MAXISPREQUEST(x)
-+#ifdef	ISP_TARGET_MODE
-+#define	RESULT_QUEUE_LEN(x)		MAXISPREQUEST(x)
-+#else
-+#define	RESULT_QUEUE_LEN(x)		\
-+	(((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2)
-+#endif
-+#define	ISP_QUEUE_ENTRY(q, idx)		((q) + ((idx) * QENTRY_LEN))
-+#define	ISP_QUEUE_SIZE(n)		((n) * QENTRY_LEN)
-+#define	ISP_NXT_QENTRY(idx, qlen)	(((idx) + 1) & ((qlen)-1))
-+#define	ISP_QFREE(in, out, qlen)	\
-+	((in == out)? (qlen - 1) : ((in > out)? \
-+	((qlen - 1) - (in - out)) : (out - in - 1)))
-+#define	ISP_QAVAIL(isp)	\
-+	ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp))
-+
-+#define	ISP_ADD_REQUEST(isp, nxti)					\
-+	MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN);	\
-+	WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti);			\
-+	isp->isp_reqidx = nxti
-+
-+/*
-+ * SCSI Specific Host Adapter Parameters- per bus, per target
-+ */
-+
-+typedef struct {
-+	u_int		isp_gotdparms		: 1,
-+			isp_req_ack_active_neg	: 1,
-+			isp_data_line_active_neg: 1,
-+			isp_cmd_dma_burst_enable: 1,
-+			isp_data_dma_burst_enabl: 1,
-+			isp_fifo_threshold	: 3,
-+			isp_ultramode		: 1,
-+			isp_diffmode		: 1,
-+			isp_lvdmode		: 1,
-+			isp_fast_mttr		: 1,	/* fast sram */
-+			isp_initiator_id	: 4,
-+			isp_async_data_setup	: 4;
-+	u_int16_t	isp_selection_timeout;
-+	u_int16_t	isp_max_queue_depth;
-+	u_int8_t	isp_tag_aging;
-+	u_int8_t	isp_bus_reset_delay;
-+	u_int8_t	isp_retry_count;
-+	u_int8_t	isp_retry_delay;
-+	struct {
-+		u_int32_t	
-+			exc_throttle	:	8,
-+					:	1,
-+			dev_enable	:	1,	/* ignored */
-+			dev_update	:	1,
-+			dev_refresh	:	1,
-+			actv_offset	:	4,
-+			goal_offset	:	4,
-+			nvrm_offset	:	4;
-+		u_int8_t	actv_period;	/* current sync period */
-+		u_int8_t	goal_period;	/* goal sync period */
-+		u_int8_t	nvrm_period;	/* nvram sync period */
-+		u_int16_t	actv_flags;	/* current device flags */
-+		u_int16_t	goal_flags;	/* goal device flags */
-+		u_int16_t	nvrm_flags;	/* nvram device flags */
-+	} isp_devparam[MAX_TARGETS];
-+} sdparam;
-+
-+/*
-+ * Device Flags
-+ */
-+#define	DPARM_DISC	0x8000
-+#define	DPARM_PARITY	0x4000
-+#define	DPARM_WIDE	0x2000
-+#define	DPARM_SYNC	0x1000
-+#define	DPARM_TQING	0x0800
-+#define	DPARM_ARQ	0x0400
-+#define	DPARM_QFRZ	0x0200
-+#define	DPARM_RENEG	0x0100
-+#define	DPARM_NARROW	0x0080
-+#define	DPARM_ASYNC	0x0040
-+#define	DPARM_PPR	0x0020
-+#define	DPARM_DEFAULT	(0xFF00 & ~DPARM_QFRZ)
-+#define	DPARM_SAFE_DFLT	(DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
-+
-+
-+/* technically, not really correct, as they need to be rated based upon clock */
-+#define	ISP_80M_SYNCPARMS	0x0c09
-+#define	ISP_40M_SYNCPARMS	0x0c0a
-+#define	ISP_20M_SYNCPARMS	0x0c0c
-+#define	ISP_20M_SYNCPARMS_1040	0x080c
-+#define	ISP_10M_SYNCPARMS	0x0c19
-+#define	ISP_08M_SYNCPARMS	0x0c25
-+#define	ISP_05M_SYNCPARMS	0x0c32
-+#define	ISP_04M_SYNCPARMS	0x0c41
-+
-+/*
-+ * Fibre Channel Specifics
-+ */
-+#define	FL_PORT_ID		0x7e	/* FL_Port Special ID */
-+#define	FC_PORT_ID		0x7f	/* Fabric Controller Special ID */
-+#define	FC_SNS_ID		0x80	/* SNS Server Special ID */
-+
-+/* #define	ISP_USE_GA_NXT	1 */	/* Use GA_NXT with switches */
-+#ifndef	GA_NXT_MAX
-+#define	GA_NXT_MAX	256
-+#endif
-+
-+typedef struct {
-+	u_int32_t		isp_fwoptions	: 16,
-+				isp_gbspeed	: 2,
-+				isp_iid_set	: 1,
-+				loop_seen_once	: 1,
-+				isp_loopstate	: 4,	/* Current Loop State */
-+				isp_fwstate	: 3,	/* ISP F/W state */
-+				isp_gotdparms	: 1,
-+				isp_topo	: 3,
-+				isp_onfabric	: 1;
-+	u_int8_t		isp_iid;	/* 'initiator' id */
-+	u_int8_t		isp_loopid;	/* hard loop id */
-+	u_int8_t		isp_alpa;	/* ALPA */
-+	u_int32_t		isp_portid;
-+	volatile u_int16_t	isp_lipseq;	/* LIP sequence # */
-+	u_int16_t		isp_fwattr;	/* firmware attributes */
-+	u_int8_t		isp_execthrottle;
-+	u_int8_t		isp_retry_delay;
-+	u_int8_t		isp_retry_count;
-+	u_int8_t		isp_reserved;
-+	u_int16_t		isp_maxalloc;
-+	u_int16_t		isp_maxfrmlen;
-+	u_int64_t		isp_nodewwn;
-+	u_int64_t		isp_portwwn;
-+	/*
-+	 * Port Data Base. This is indexed by 'target', which is invariate.
-+	 * However, elements within can move around due to loop changes,
-+	 * so the actual loop ID passed to the F/W is in this structure.
-+	 * The first time the loop is seen up, loopid will match the index
-+	 * (except for fabric nodes which are above mapped above FC_SNS_ID
-+	 * and are completely virtual), but subsequent LIPs can cause things
-+	 * to move around.
-+	 */
-+	struct lportdb {
-+		u_int32_t
-+					port_type	: 8,
-+					loopid		: 8,
-+					fc4_type	: 4,
-+					last_fabric_dev	: 1,
-+							: 2,
-+					relogin		: 1,
-+					force_logout	: 1,
-+					was_fabric_dev	: 1,
-+					fabric_dev	: 1,
-+					loggedin	: 1,
-+					roles		: 2,
-+					valid		: 1;
-+		u_int32_t		portid;
-+		u_int64_t		node_wwn;
-+		u_int64_t		port_wwn;
-+	} portdb[MAX_FC_TARG], tport[FC_PORT_ID];
-+
-+	/*
-+	 * Scratch DMA mapped in area to fetch Port Database stuff, etc.
-+	 */
-+	caddr_t			isp_scratch;
-+	isp_dma_addr_t		isp_scdma;
-+#ifdef	ISP_FW_CRASH_DUMP
-+	u_int16_t		*isp_dump_data;
-+#endif
-+} fcparam;
-+
-+#define	FW_CONFIG_WAIT		0
-+#define	FW_WAIT_AL_PA		1
-+#define	FW_WAIT_LOGIN		2
-+#define	FW_READY		3
-+#define	FW_LOSS_OF_SYNC		4
-+#define	FW_ERROR		5
-+#define	FW_REINIT		6
-+#define	FW_NON_PART		7
-+
-+#define	LOOP_NIL		0
-+#define	LOOP_LIP_RCVD		1
-+#define	LOOP_PDB_RCVD		2
-+#define	LOOP_SCANNING_FABRIC	3
-+#define	LOOP_FSCAN_DONE		4
-+#define	LOOP_SCANNING_LOOP	5
-+#define	LOOP_LSCAN_DONE		6
-+#define	LOOP_SYNCING_PDB	7
-+#define	LOOP_READY		8
-+
-+#define	TOPO_NL_PORT		0
-+#define	TOPO_FL_PORT		1
-+#define	TOPO_N_PORT		2
-+#define	TOPO_F_PORT		3
-+#define	TOPO_PTP_STUB		4
-+
-+/*
-+ * Soft Structure per host adapter
-+ */
-+typedef struct ispsoftc {
-+	/*
-+	 * Platform (OS) specific data
-+	 */
-+	struct isposinfo	isp_osinfo;
-+
-+	/*
-+	 * Pointer to bus specific functions and data
-+	 */
-+	struct ispmdvec *	isp_mdvec;
-+
-+	/*
-+	 * (Mostly) nonvolatile state. Board specific parameters
-+	 * may contain some volatile state (e.g., current loop state).
-+	 */
-+
-+	void * 			isp_param;	/* type specific */
-+	u_int16_t		isp_fwrev[3];	/* Loaded F/W revision */
-+	u_int16_t		isp_romfw_rev[3]; /* PROM F/W revision */
-+	u_int16_t		isp_maxcmds;	/* max possible I/O cmds */
-+	u_int8_t		isp_type;	/* HBA Chip Type */
-+	u_int8_t		isp_revision;	/* HBA Chip H/W Revision */
-+	u_int32_t		isp_maxluns;	/* maximum luns supported */
-+
-+	u_int32_t		isp_clock	: 8,	/* input clock */
-+						: 4,
-+				isp_port	: 1,	/* 23XX only */
-+				isp_failed	: 1,	/* board failed */
-+				isp_open	: 1,	/* opened (ioctl) */
-+				isp_touched	: 1,	/* board ever seen? */
-+				isp_bustype	: 1,	/* SBus or PCI */
-+				isp_loaded_fw	: 1,	/* loaded firmware */
-+				isp_role	: 2,	/* roles supported */
-+				isp_dblev	: 12;	/* debug log mask */
-+
-+	u_int32_t		isp_confopts;		/* config options */
-+
-+	u_int16_t		isp_rqstinrp;	/* register for REQINP */
-+	u_int16_t		isp_rqstoutrp;	/* register for REQOUTP */
-+	u_int16_t		isp_respinrp;	/* register for RESINP */
-+	u_int16_t		isp_respoutrp;	/* register for RESOUTP */
-+
-+	/*
-+	 * Instrumentation
-+	 */
-+	u_int64_t		isp_intcnt;		/* total int count */
-+	u_int64_t		isp_intbogus;		/* spurious int count */
-+	u_int64_t		isp_intmboxc;		/* mbox completions */
-+	u_int64_t		isp_intoasync;		/* other async */
-+	u_int64_t		isp_rsltccmplt;		/* CMDs on result q */
-+	u_int64_t		isp_fphccmplt;		/* CMDs via fastpost */
-+	u_int16_t		isp_rscchiwater;
-+	u_int16_t		isp_fpcchiwater;
-+
-+	/*
-+	 * Volatile state
-+	 */
-+
-+	volatile u_int32_t
-+		isp_obits	:	8,	/* mailbox command output */
-+		isp_mboxbsy	:	1,	/* mailbox command active */
-+		isp_state	:	3,
-+		isp_sendmarker	:	2,	/* send a marker entry */
-+		isp_update	:	2,	/* update parameters */
-+		isp_nactive	:	16;	/* how many commands active */
-+	volatile u_int16_t	isp_reqodx;	/* index of last ISP pickup */
-+	volatile u_int16_t	isp_reqidx;	/* index of next request */
-+	volatile u_int16_t	isp_residx;	/* index of next result */
-+	volatile u_int16_t	isp_resodx;	/* index of next result */
-+	volatile u_int16_t	isp_rspbsy;
-+	volatile u_int16_t	isp_lasthdls;	/* last handle seed */
-+	volatile u_int16_t	isp_mboxtmp[MAX_MAILBOX];
-+	volatile u_int16_t	isp_lastmbxcmd;	/* last mbox command sent */
-+	volatile u_int16_t	isp_mbxwrk0;
-+	volatile u_int16_t	isp_mbxwrk1;
-+	volatile u_int16_t	isp_mbxwrk2;
-+	void *			isp_mbxworkp;
-+
-+	/*
-+	 * Active commands are stored here, indexed by handle functions.
-+	 */
-+	XS_T **isp_xflist;
-+
-+	/*
-+	 * request/result queue pointers and dma handles for them.
-+	 */
-+	caddr_t			isp_rquest;
-+	caddr_t			isp_result;
-+	isp_dma_addr_t		isp_rquest_dma;
-+	isp_dma_addr_t		isp_result_dma;
-+} ispsoftc_t;
-+
-+#define	SDPARAM(isp)	((sdparam *) (isp)->isp_param)
-+#define	FCPARAM(isp)	((fcparam *) (isp)->isp_param)
-+
-+/*
-+ * ISP Driver Run States
-+ */
-+#define	ISP_NILSTATE	0
-+#define	ISP_RESETSTATE	1
-+#define	ISP_INITSTATE	2
-+#define	ISP_RUNSTATE	3
-+
-+/*
-+ * ISP Configuration Options
-+ */
-+#define	ISP_CFG_NORELOAD	0x80	/* don't download f/w */
-+#define	ISP_CFG_NONVRAM		0x40	/* ignore NVRAM */
-+#define	ISP_CFG_TWOGB		0x20	/* force 2GB connection (23XX only) */
-+#define	ISP_CFG_ONEGB		0x10	/* force 1GB connection (23XX only) */
-+#define	ISP_CFG_FULL_DUPLEX	0x01	/* Full Duplex (Fibre Channel only) */
-+#define	ISP_CFG_PORT_PREF	0x0C	/* Mask for Port Prefs (2200 only) */
-+#define	ISP_CFG_LPORT		0x00	/* prefer {N/F}L-Port connection */
-+#define	ISP_CFG_NPORT		0x04	/* prefer {N/F}-Port connection */
-+#define	ISP_CFG_NPORT_ONLY	0x08	/* insist on {N/F}-Port connection */
-+#define	ISP_CFG_LPORT_ONLY	0x0C	/* insist on {N/F}L-Port connection */
-+#define	ISP_CFG_OWNWWPN		0x100	/* override NVRAM wwpn */
-+#define	ISP_CFG_OWNWWNN		0x200	/* override NVRAM wwnn */
-+#define	ISP_CFG_OWNFSZ		0x400	/* override NVRAM frame size */
-+#define	ISP_CFG_OWNLOOPID	0x800	/* override NVRAM loopid */
-+#define	ISP_CFG_OWNEXCTHROTTLE	0x1000	/* override NVRAM execution throttle */
-+
-+/*
-+ * Prior to calling isp_reset for the first time, the outer layer
-+ * should set isp_role to one of NONE, INITIATOR, TARGET, BOTH.
-+ *
-+ * If you set ISP_ROLE_NONE, the cards will be reset, new firmware loaded,
-+ * NVRAM read, and defaults set, but any further initialization (e.g.
-+ * INITIALIZE CONTROL BLOCK commands for 2X00 cards) won't be done.
-+ *
-+ * If INITIATOR MODE isn't set, attempts to run commands will be stopped
-+ * at isp_start and completed with the moral equivalent of SELECTION TIMEOUT.
-+ *
-+ * If TARGET MODE is set, it doesn't mean that the rest of target mode support
-+ * needs to be enabled, or will even work. What happens with the 2X00 cards
-+ * here is that if you have enabled it with TARGET MODE as part of the ICB
-+ * options, but you haven't given the f/w any ram resources for ATIOs or
-+ * Immediate Notifies, the f/w just handles what it can and you never see
-+ * anything. Basically, it sends a single byte of data (the first byte,
-+ * which you can set as part of the INITIALIZE CONTROL BLOCK command) for
-+ * INQUIRY, and sends back QUEUE FULL status for any other command.
-+ *
-+ */
-+#define	ISP_ROLE_NONE		0x0
-+#define	ISP_ROLE_INITIATOR	0x1
-+#define	ISP_ROLE_TARGET		0x2
-+#define	ISP_ROLE_BOTH		(ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
-+#define	ISP_ROLE_EITHER		ISP_ROLE_BOTH
-+#ifndef	ISP_DEFAULT_ROLES
-+#define	ISP_DEFAULT_ROLES	ISP_ROLE_INITIATOR
-+#endif
-+
-+
-+/*
-+ * Firmware related defines
-+ */
-+#define	ISP_CODE_ORG			0x1000	/* default f/w code start */
-+#define	ISP_CODE_ORG_2300		0x0800	/* ..except for 2300s */
-+#define	ISP_FW_REV(maj, min, mic)	((maj << 24) | (min << 16) | mic)
-+#define	ISP_FW_MAJOR(code)		((code >> 24) & 0xff)
-+#define	ISP_FW_MINOR(code)		((code >> 16) & 0xff)
-+#define	ISP_FW_MICRO(code)		((code >>  8) & 0xff)
-+#define	ISP_FW_REVX(xp)			((xp[0]<<24) | (xp[1] << 16) | xp[2])
-+#define	ISP_FW_MAJORX(xp)		(xp[0])
-+#define	ISP_FW_MINORX(xp)		(xp[1])
-+#define	ISP_FW_MICROX(xp)		(xp[2])
-+#define	ISP_FW_NEWER_THAN(i, major, minor, micro)		\
-+ (ISP_FW_REVX((i)->isp_fwrev) > ISP_FW_REV(major, minor, micro))
-+
-+/*
-+ * Bus (implementation) types
-+ */
-+#define	ISP_BT_PCI		0	/* PCI Implementations */
-+#define	ISP_BT_SBUS		1	/* SBus Implementations */
-+
-+/*
-+ * If we have not otherwise defined SBus support away make sure
-+ * it is defined here such that the code is included as default
-+ */
-+#ifndef	ISP_SBUS_SUPPORTED
-+#define	ISP_SBUS_SUPPORTED	1
-+#endif
-+
-+/*
-+ * Chip Types
-+ */
-+#define	ISP_HA_SCSI		0xf
-+#define	ISP_HA_SCSI_UNKNOWN	0x1
-+#define	ISP_HA_SCSI_1020	0x2
-+#define	ISP_HA_SCSI_1020A	0x3
-+#define	ISP_HA_SCSI_1040	0x4
-+#define	ISP_HA_SCSI_1040A	0x5
-+#define	ISP_HA_SCSI_1040B	0x6
-+#define	ISP_HA_SCSI_1040C	0x7
-+#define	ISP_HA_SCSI_1240	0x8
-+#define	ISP_HA_SCSI_1080	0x9
-+#define	ISP_HA_SCSI_1280	0xa
-+#define	ISP_HA_SCSI_10160	0xb
-+#define	ISP_HA_SCSI_12160	0xc
-+#define	ISP_HA_FC		0xf0
-+#define	ISP_HA_FC_2100		0x10
-+#define	ISP_HA_FC_2200		0x20
-+#define	ISP_HA_FC_2300		0x30
-+#define	ISP_HA_FC_2312		0x40
-+
-+#define	IS_SCSI(isp)	(isp->isp_type & ISP_HA_SCSI)
-+#define	IS_1240(isp)	(isp->isp_type == ISP_HA_SCSI_1240)
-+#define	IS_1080(isp)	(isp->isp_type == ISP_HA_SCSI_1080)
-+#define	IS_1280(isp)	(isp->isp_type == ISP_HA_SCSI_1280)
-+#define	IS_10160(isp)	(isp->isp_type == ISP_HA_SCSI_10160)
-+#define	IS_12160(isp)	(isp->isp_type == ISP_HA_SCSI_12160)
-+
-+#define	IS_12X0(isp)	(IS_1240(isp) || IS_1280(isp))
-+#define	IS_1X160(isp)	(IS_10160(isp) || IS_12160(isp))
-+#define	IS_DUALBUS(isp)	(IS_12X0(isp) || IS_12160(isp))
-+#define	IS_ULTRA2(isp)	(IS_1080(isp) || IS_1280(isp) || IS_1X160(isp))
-+#define	IS_ULTRA3(isp)	(IS_1X160(isp))
-+
-+#define	IS_FC(isp)	((isp)->isp_type & ISP_HA_FC)
-+#define	IS_2100(isp)	((isp)->isp_type == ISP_HA_FC_2100)
-+#define	IS_2200(isp)	((isp)->isp_type == ISP_HA_FC_2200)
-+#define	IS_23XX(isp)	((isp)->isp_type >= ISP_HA_FC_2300)
-+#define	IS_2300(isp)	((isp)->isp_type == ISP_HA_FC_2300)
-+#define	IS_2312(isp)	((isp)->isp_type == ISP_HA_FC_2312)
-+
-+/*
-+ * DMA cookie macros
-+ */
-+#ifdef	ISP_DAC_SUPPORTRED
-+#define	DMA_WD3(x)	(((x) >> 48) & 0xffff)
-+#define	DMA_WD2(x)	(((x) >> 32) & 0xffff)
-+#else
-+#define	DMA_WD3(x)	0
-+#define	DMA_WD2(x)	0
-+#endif
-+#define	DMA_WD1(x)	(((x) >> 16) & 0xffff)
-+#define	DMA_WD0(x)	(((x) & 0xffff))
-+
-+/*
-+ * Core System Function Prototypes
-+ */
-+
-+/*
-+ * Reset Hardware. Totally. Assumes that you'll follow this with
-+ * a call to isp_init.
-+ */
-+void isp_reset(struct ispsoftc *);
-+
-+/*
-+ * Initialize Hardware to known state
-+ */
-+void isp_init(struct ispsoftc *);
-+
-+/*
-+ * Reset the ISP and call completion for any orphaned commands.
-+ */
-+void isp_reinit(struct ispsoftc *);
-+
-+#ifdef	ISP_FW_CRASH_DUMP
-+/*
-+ * Dump firmware entry point.
-+ */
-+void isp_fw_dump(struct ispsoftc *isp);
-+#endif
-+
-+/*
-+ * Internal Interrupt Service Routine
-+ *
-+ * The outer layers do the spade work to get the appropriate status register,
-+ * semaphore register and first mailbox register (if appropriate). This also
-+ * means that most spurious/bogus interrupts not for us can be filtered first.
-+ */
-+void isp_intr(struct ispsoftc *, u_int16_t, u_int16_t, u_int16_t);
-+
-+
-+/*
-+ * Command Entry Point- Platform Dependent layers call into this
-+ */
-+int isp_start(XS_T *);
-+/* these values are what isp_start returns */
-+#define	CMD_COMPLETE	101	/* command completed */
-+#define	CMD_EAGAIN	102	/* busy- maybe retry later */
-+#define	CMD_QUEUED	103	/* command has been queued for execution */
-+#define	CMD_RQLATER 	104	/* requeue this command later */
-+
-+/*
-+ * Command Completion Point- Core layers call out from this with completed cmds
-+ */
-+void isp_done(XS_T *);
-+
-+/*
-+ * Platform Dependent to External to Internal Control Function
-+ *
-+ * Assumes locks are held on entry. You should note that with many of
-+ * these commands and locks may be released while this is occurring.
-+ *
-+ * A few notes about some of these functions:
-+ *
-+ * ISPCTL_FCLINK_TEST tests to make sure we have good fibre channel link.
-+ * The argument is a pointer to an integer which is the time, in microseconds,
-+ * we should wait to see whether we have good link. This test, if successful,
-+ * lets us know our connection topology and our Loop ID/AL_PA and so on.
-+ * You can't get anywhere without this.
-+ *
-+ * ISPCTL_SCAN_FABRIC queries the name server (if we're on a fabric) for
-+ * all entities using the FC Generic Services subcommand GET ALL NEXT.
-+ * For each found entity, an ISPASYNC_FABRICDEV event is generated (see
-+ * below).
-+ *
-+ * ISPCTL_SCAN_LOOP does a local loop scan. This is only done if the connection
-+ * topology is NL or FL port (private or public loop). Since the Qlogic f/w
-+ * 'automatically' manages local loop connections, this function essentially
-+ * notes the arrival, departure, and possible shuffling around of local loop
-+ * entities. Thus for each arrival and departure this generates an isp_async
-+ * event of ISPASYNC_PROMENADE (see below).
-+ *
-+ * ISPCTL_PDB_SYNC is somewhat misnamed. It actually is the final step, in
-+ * order, of ISPCTL_FCLINK_TEST, ISPCTL_SCAN_FABRIC, and ISPCTL_SCAN_LOOP.
-+ * The main purpose of ISPCTL_PDB_SYNC is to complete management of logging
-+ * and logging out of fabric devices (if one is on a fabric) and then marking
-+ * the 'loop state' as being ready to now be used for sending commands to
-+ * devices. Originally fabric name server and local loop scanning were
-+ * part of this function. It's now been separated to allow for finer control.
-+ */
-+typedef enum {
-+	ISPCTL_RESET_BUS,		/* Reset Bus */
-+	ISPCTL_RESET_DEV,		/* Reset Device */
-+	ISPCTL_ABORT_CMD,		/* Abort Command */
-+	ISPCTL_UPDATE_PARAMS,		/* Update Operating Parameters (SCSI) */
-+	ISPCTL_FCLINK_TEST,		/* Test FC Link Status */
-+	ISPCTL_SCAN_FABRIC,		/* (Re)scan Fabric Name Server */
-+	ISPCTL_SCAN_LOOP,		/* (Re)scan Local Loop */
-+	ISPCTL_PDB_SYNC,		/* Synchronize Port Database */
-+	ISPCTL_SEND_LIP,		/* Send a LIP */
-+	ISPCTL_GET_POSMAP,		/* Get FC-AL position map */
-+	ISPCTL_RUN_MBOXCMD,		/* run a mailbox command */
-+	ISPCTL_TOGGLE_TMODE		/* toggle target mode */
-+} ispctl_t;
-+int isp_control(struct ispsoftc *, ispctl_t, void *);
-+
-+
-+/*
-+ * Platform Dependent to Internal to External Control Function
-+ * (each platform must provide such a function)
-+ *
-+ * Assumes locks are held.
-+ *
-+ * A few notes about some of these functions:
-+ *
-+ * ISPASYNC_CHANGE_NOTIFY notifies the outer layer that a change has
-+ * occurred that invalidates the list of fabric devices known and/or
-+ * the list of known loop devices. The argument passed is a pointer
-+ * whose values are defined below  (local loop change, name server
-+ * change, other). 'Other' may simply be a LIP, or a change in
-+ * connection topology.
-+ *
-+ * ISPASYNC_FABRIC_DEV announces the next element in a list of
-+ * fabric device names we're getting out of the name server. The
-+ * argument points to a GET ALL NEXT response structure. The list
-+ * is known to terminate with an entry that refers to ourselves.
-+ * One of the main purposes of this function is to allow outer
-+ * layers, which are OS dependent, to set policy as to which fabric
-+ * devices might actually be logged into (and made visible) later
-+ * at ISPCTL_PDB_SYNC time. Since there's a finite number of fabric
-+ * devices that we can log into (256 less 3 'reserved' for F-port
-+ * topologies), and fabrics can grow up to 8 million or so entries
-+ * (24 bits of Port Address, less a wad of reserved spaces), clearly
-+ * we had better let the OS determine login policy.
-+ *
-+ * ISPASYNC_PROMENADE has an argument that is a pointer to an integer which
-+ * is an index into the portdb in the softc ('target'). Whether that entry's
-+ * valid tag is set or not says whether something has arrived or departed.
-+ * The name refers to a favorite pastime of many city dwellers- watching
-+ * people come and go, talking of Michaelangelo, and so on..
-+ *
-+ * ISPASYNC_UNHANDLED_RESPONSE gives outer layers a chance to parse a
-+ * response queue entry not otherwise handled. The outer layer should
-+ * return non-zero if it handled it. The 'arg' points to an unmassaged
-+ * response queue entry.
-+ */
-+
-+typedef enum {
-+	ISPASYNC_NEW_TGT_PARAMS,	/* New Target Parameters Negotiated */
-+	ISPASYNC_BUS_RESET,		/* Bus Was Reset */
-+	ISPASYNC_LOOP_DOWN,		/* FC Loop Down */
-+	ISPASYNC_LOOP_UP,		/* FC Loop Up */
-+	ISPASYNC_LIP,			/* LIP Received */
-+	ISPASYNC_LOOP_RESET,		/* Loop Reset Received */
-+	ISPASYNC_CHANGE_NOTIFY,		/* FC Change Notification */
-+	ISPASYNC_FABRIC_DEV,		/* FC Fabric Device Arrival */
-+	ISPASYNC_PROMENADE,		/* FC Objects coming && going */
-+	ISPASYNC_TARGET_MESSAGE,	/* target message */
-+	ISPASYNC_TARGET_EVENT,		/* target asynchronous event */
-+	ISPASYNC_TARGET_ACTION,		/* other target command action */
-+	ISPASYNC_CONF_CHANGE,		/* Platform Configuration Change */
-+	ISPASYNC_UNHANDLED_RESPONSE,	/* Unhandled Response Entry */
-+	ISPASYNC_FW_CRASH,		/* Firmware has crashed */
-+	ISPASYNC_FW_DUMPED,		/* Firmware crashdump taken */
-+	ISPASYNC_FW_RESTARTED		/* Firmware has been restarted */
-+} ispasync_t;
-+int isp_async(struct ispsoftc *, ispasync_t, void *);
-+
-+#define	ISPASYNC_CHANGE_PDB	((void *) 0)
-+#define	ISPASYNC_CHANGE_SNS	((void *) 1)
-+#define	ISPASYNC_CHANGE_OTHER	((void *) 2)
-+
-+/*
-+ * Platform Dependent Error and Debug Printout
-+ */
-+#ifdef	__GNUC__
-+void isp_prt(struct ispsoftc *, int level, const char *, ...)
-+	__attribute__((__format__(__printf__,3,4)));
-+#else
-+void isp_prt(struct ispsoftc *, int level, const char *, ...);
-+#endif
-+
-+#define	ISP_LOGALL	0x0	/* log always */
-+#define	ISP_LOGCONFIG	0x1	/* log configuration messages */
-+#define	ISP_LOGINFO	0x2	/* log informational messages */
-+#define	ISP_LOGWARN	0x4	/* log warning messages */
-+#define	ISP_LOGERR	0x8	/* log error messages */
-+#define	ISP_LOGDEBUG0	0x10	/* log simple debug messages */
-+#define	ISP_LOGDEBUG1	0x20	/* log intermediate debug messages */
-+#define	ISP_LOGDEBUG2	0x40	/* log most debug messages */
-+#define	ISP_LOGDEBUG3	0x80	/* log high frequency debug messages */
-+#define	ISP_LOGDEBUG4	0x100	/* log high frequency debug messages */
-+#define	ISP_LOGTDEBUG0	0x200	/* log simple debug messages (target mode) */
-+#define	ISP_LOGTDEBUG1	0x400	/* log intermediate debug messages (target) */
-+#define	ISP_LOGTDEBUG2	0x800	/* log all debug messages (target) */
-+
-+/*
-+ * Each Platform provides it's own isposinfo substructure of the ispsoftc
-+ * defined above.
-+ *
-+ * Each platform must also provide the following macros/defines:
-+ *
-+ *
-+ *	INLINE		-	platform specific define for 'inline' functions
-+ *
-+ *	ISP_DAC_SUPPORTED -	Is DAC (Dual Address Cycle) is supported?
-+ *				Basically means whether or not DMA for PCI
-+ *				PCI cards (Ultra2 or better or FC) works
-+ *				above 4GB.
-+ *
-+ *	ISP2100_SCRLEN	-	length for the Fibre Channel scratch DMA area
-+ *
-+ *	MEMZERO(dst, src)			platform zeroing function
-+ *	MEMCPY(dst, src, count)			platform copying function
-+ *	SNPRINTF(buf, bufsize, fmt, ...)	snprintf
-+ *	USEC_DELAY(usecs)			microsecond spindelay function
-+ *	USEC_SLEEP(isp, usecs)			microsecond sleep function
-+ *
-+ *	NANOTIME_T				nanosecond time type
-+ *
-+ *	GET_NANOTIME(NANOTIME_T *)		get current nanotime.
-+ *
-+ *	GET_NANOSEC(NANOTIME_T *)		get u_int64_t from NANOTIME_T
-+ *
-+ *	NANOTIME_SUB(NANOTIME_T *, NANOTIME_T *)
-+ *						subtract two NANOTIME_T values
-+ *
-+ *
-+ *	MAXISPREQUEST(struct ispsoftc *)	maximum request queue size
-+ *						for this particular board type
-+ *
-+ *	MEMORYBARRIER(struct ispsoftc *, barrier_type, offset, size)
-+ *
-+ *		Function/Macro the provides memory synchronization on
-+ *		various objects so that the ISP's and the system's view
-+ *		of the same object is consistent.
-+ *
-+ *	MBOX_ACQUIRE(struct ispsoftc *)		acquire lock on mailbox regs
-+ *	MBOX_WAIT_COMPLETE(struct ispsoftc *)	wait for mailbox cmd to be done
-+ *	MBOX_NOTIFY_COMPLETE(struct ispsoftc *)	notification of mbox cmd donee
-+ *	MBOX_RELEASE(struct ispsoftc *)		release lock on mailbox regs
-+ *
-+ *	FC_SCRATCH_ACQUIRE(struct ispsoftc *)	acquire lock on FC scratch area
-+ *	FC_SCRATCH_RELEASE(struct ispsoftc *)	acquire lock on FC scratch area
-+ *
-+ *	SCSI_GOOD	SCSI 'Good' Status
-+ *	SCSI_CHECK	SCSI 'Check Condition' Status
-+ *	SCSI_BUSY	SCSI 'Busy' Status
-+ *	SCSI_QFULL	SCSI 'Queue Full' Status
-+ *
-+ *	XS_T		Platform SCSI transaction type (i.e., command for HBA)
-+ *	XS_ISP(xs)	gets an instance out of an XS_T
-+ *	XS_CHANNEL(xs)	gets the channel (bus # for DUALBUS cards) ""
-+ *	XS_TGT(xs)	gets the target ""
-+ *	XS_LUN(xs)	gets the lun ""
-+ *	XS_CDBP(xs)	gets a pointer to the scsi CDB ""
-+ *	XS_CDBLEN(xs)	gets the CDB's length ""
-+ *	XS_XFRLEN(xs)	gets the associated data transfer length ""
-+ *	XS_TIME(xs)	gets the time (in milliseconds) for this command
-+ *	XS_RESID(xs)	gets the current residual count
-+ *	XS_STSP(xs)	gets a pointer to the SCSI status byte ""
-+ *	XS_SNSP(xs)	gets a pointer to the associate sense data
-+ *	XS_SNSLEN(xs)	gets the length of sense data storage
-+ *	XS_SNSKEY(xs)	dereferences XS_SNSP to get the current stored Sense Key
-+ *	XS_TAG_P(xs)	predicate of whether this command should be tagged
-+ *	XS_TAG_TYPE(xs)	which type of tag to use
-+ *	XS_SETERR(xs)	set error state
-+ *
-+ *		HBA_NOERROR	command has no erros
-+ *		HBA_BOTCH	hba botched something
-+ *		HBA_CMDTIMEOUT	command timed out
-+ *		HBA_SELTIMEOUT	selection timed out (also port logouts for FC)
-+ *		HBA_TGTBSY	target returned a BUSY status
-+ *		HBA_BUSRESET	bus reset destroyed command
-+ *		HBA_ABORTED	command was aborted (by request)
-+ *		HBA_DATAOVR	a data overrun was detected
-+ *		HBA_ARQFAIL	Automatic Request Sense failed
-+ *
-+ *	XS_ERR(xs)	return current error state
-+ *	XS_NOERR(xs)	there is no error currently set
-+ *	XS_INITERR(xs)	initialize error state
-+ *
-+ *	XS_SAVE_SENSE(xs, sp)		save sense data
-+ *
-+ *	XS_SET_STATE_STAT(isp, sp, xs)	platform dependent interpreter of
-+ *					response queue entry status bits
-+ *
-+ *
-+ *	DEFAULT_IID(struct ispsoftc *)		Default SCSI initiator ID
-+ *	DEFAULT_LOOPID(struct ispsoftc *)	Default FC Loop ID
-+ *	DEFAULT_NODEWWN(struct ispsoftc *)	Default Node WWN
-+ *	DEFAULT_PORTWWN(struct ispsoftc *)	Default Port WWN
-+ *	DEFAULT_FRAMESIZE(struct ispsoftc *)	Default Frame Size
-+ *	DEFAULT_EXEC_THROTTLE(struct ispsoftc *) Default Execution Throttle
-+ *		These establish reasonable defaults for each platform.
-+ * 		These must be available independent of card NVRAM and are
-+ *		to be used should NVRAM not be readable.
-+ *
-+ *	ISP_NODEWWN(struct ispsoftc *)	FC Node WWN to use
-+ *	ISP_PORTWWN(struct ispsoftc *)	FC Port WWN to use
-+ *
-+ *		These are to be used after NVRAM is read. The tags
-+ *		in fcparam.isp_{node,port}wwn reflect the values
-+ *		read from NVRAM (possibly corrected for card botches).
-+ *		Each platform can take that information and override
-+ *		it or ignore and return the Node and Port WWNs to be
-+ * 		used when sending the Qlogic f/w the Initialization Control
-+ *		Block.
-+ *
-+ *	(XXX these do endian specific transformations- in transition XXX)
-+ *
-+ *	ISP_IOXPUT_8(struct ispsoftc *, u_int8_t srcval, u_int8_t *dstptr)
-+ *	ISP_IOXPUT_16(struct ispsoftc *, u_int16_t srcval, u_int16_t *dstptr)
-+ *	ISP_IOXPUT_32(struct ispsoftc *, u_int32_t srcval, u_int32_t *dstptr)
-+ *
-+ *	ISP_IOXGET_8(struct ispsoftc *, u_int8_t *srcptr, u_int8_t dstrval)
-+ *	ISP_IOXGET_16(struct ispsoftc *, u_int16_t *srcptr, u_int16_t dstrval)
-+ *	ISP_IOXGET_32(struct ispsoftc *, u_int32_t *srcptr, u_int32_t dstrval)
-+ *
-+ *	ISP_SWIZZLE_NVRAM_WORD(struct ispsoftc *, u_int16_t *)
-+ */
-+
-+#endif	/* _ISPVAR_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/scsi/isp/Makefile	2003-07-19 17:06:33.000000000 -0700
-@@ -0,0 +1,7 @@
-+obj-$(CONFIG_SCSI_FERAL_ISP)	+= isp_mod.o
-+
-+EXTRA_CFLAGS			+= -Idrivers/scsi -g
-+EXTRA_LDFLAGS			+= -g
-+
-+isp_mod-y			+= isp_pci.o isp_linux.o isp.o \
-+				isp_cb_ops.o isp_target.o
---- linux-2.6.0-test1/drivers/scsi/jazz_esp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/jazz_esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -11,7 +11,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- 
---- linux-2.6.0-test1/drivers/scsi/Kconfig	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/Kconfig	2003-07-19 17:06:33.000000000 -0700
-@@ -1834,6 +1834,15 @@ config WD33C93_PIO
- 
- #      bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
- #      bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI
-+
-+config SCSI_FERAL_ISP
-+	tristate "Feral ISP driver for 10x0/12x0/2x00"
-+	depends on SCSI
-+	help
-+	  Feral Driver for the following qlogic ISP chips
-+	  1020/1040/1080/1280/12160/2100/2200/2300
-+	  If this doesn't work, there are other drivers for these chips
-+	  below.
- endmenu
- 
- source "drivers/scsi/pcmcia/Kconfig"
---- linux-2.6.0-test1/drivers/scsi/lasi700.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/lasi700.c	2003-07-19 17:03:50.000000000 -0700
-@@ -128,7 +128,8 @@ lasi700_driver_callback(struct parisc_de
- 	}
- 
- 	dev_set_drvdata(&dev->dev, host);
--	scsi_add_host(host, &dev->dev);
-+	scsi_add_host(host, &dev->dev); /* XXX handle failure */
-+	scsi_scan_host(host);
- 
- 	return 0;
- 
-@@ -165,7 +166,6 @@ static void __exit
- lasi700_exit(void)
- {
- 	unregister_parisc_driver(&lasi700_driver);
--	scsi_sysfs_release_attributes(&lasi700_template);
- }
- 
- module_init(lasi700_init);
---- linux-2.6.0-test1/drivers/scsi/mac53c94.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/mac53c94.c	2003-07-19 17:03:50.000000000 -0700
-@@ -12,7 +12,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/spinlock.h>
---- linux-2.6.0-test1/drivers/scsi/mac_esp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/mac_esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -19,7 +19,7 @@
- #include <linux/ctype.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/mac_scsi.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/mac_scsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -39,7 +39,7 @@
- #include <linux/sched.h>
- #include <linux/ioport.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- 
- #include <asm/io.h>
---- linux-2.6.0-test1/drivers/scsi/Makefile	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/Makefile	2003-07-19 17:06:33.000000000 -0700
-@@ -70,6 +70,7 @@ obj-$(CONFIG_SCSI_NCR53C406A)	+= NCR53c4
- obj-$(CONFIG_SCSI_NCR_D700)	+= NCR_D700.o 53c700.o
- obj-$(CONFIG_SCSI_NCR_Q720)	+= NCR_Q720_mod.o
- obj-$(CONFIG_SCSI_SYM53C416)	+= sym53c416.o
-+obj-$(CONFIG_SCSI_FERAL_ISP)	+= isp/
- obj-$(CONFIG_SCSI_QLOGIC_FAS)	+= qlogicfas.o
- obj-$(CONFIG_SCSI_QLOGIC_ISP)	+= qlogicisp.o 
- obj-$(CONFIG_SCSI_QLOGIC_FC)	+= qlogicfc.o 
---- linux-2.6.0-test1/drivers/scsi/mca_53c9x.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/scsi/mca_53c9x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -37,7 +37,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/mca-legacy.h>
---- linux-2.6.0-test1/drivers/scsi/megaraid.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/megaraid.c	2003-07-19 17:03:50.000000000 -0700
-@@ -32,7 +32,7 @@
- 
- #include <linux/mm.h>
- #include <linux/fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/uaccess.h>
- #include <asm/io.h>
- #include <linux/delay.h>
---- linux-2.6.0-test1/drivers/scsi/mesh.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/mesh.c	2003-07-19 17:03:50.000000000 -0700
-@@ -21,7 +21,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/mvme147.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/scsi/mvme147.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,6 +1,6 @@
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/interrupt.h>
---- linux-2.6.0-test1/drivers/scsi/mvme16x.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/mvme16x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -5,7 +5,7 @@
-  */
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- 
---- linux-2.6.0-test1/drivers/scsi/NCR53c406a.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/NCR53c406a.c	2003-07-19 17:05:05.000000000 -0700
-@@ -51,7 +51,7 @@
- #include <asm/bitops.h>
- #include <asm/irq.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- #include "scsi.h"
- #include "hosts.h"
-@@ -450,6 +450,7 @@ static __inline__ int NCR53c406a_pio_wri
- 
- static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
- {
-+	int present = 0;
- 	struct Scsi_Host *shpnt = NULL;
- #ifndef PORT_BASE
- 	int i;
-@@ -522,7 +523,7 @@ static int __init NCR53c406a_detect(Scsi
- 
- 	DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base));
- 
--	tpnt->present = 1;
-+	present = 1;
- 	tpnt->proc_name = "NCR53c406a";
- 
- 	shpnt = scsi_register(tpnt, 0);
-@@ -576,7 +577,7 @@ static int __init NCR53c406a_detect(Scsi
- 	sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow");
- #endif
- 
--	return (tpnt->present);
-+	return (present);
- 
- #if USE_DMA
-       err_free_irq:
---- linux-2.6.0-test1/drivers/scsi/ncr53c8xx.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/ncr53c8xx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -140,7 +140,7 @@
- #include <linux/timer.h>
- #include <linux/stat.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,35)
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/NCR53C9x.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/NCR53C9x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -29,7 +29,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
---- linux-2.6.0-test1/drivers/scsi/NCR_D700.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/NCR_D700.c	2003-07-19 17:03:50.000000000 -0700
-@@ -218,7 +218,8 @@ NCR_D700_probe_one(struct NCR_D700_priva
- 		goto irq_failed;
- 	}
- 
--	scsi_add_host(host, p->dev);
-+	scsi_add_host(host, p->dev); /* XXX handle failure */
-+	scsi_scan_host(host);
- 
- 	p->hosts[siop] = host;
- 	hostdata->dev = p->dev;
-@@ -387,7 +388,6 @@ static int __init NCR_D700_init(void)
- static void __exit NCR_D700_exit(void)
- {
- 	mca_unregister_driver(&NCR_D700_driver);
--	scsi_sysfs_release_attributes(&NCR_D700_driver_template);
- }
- 
- module_init(NCR_D700_init);
---- linux-2.6.0-test1/drivers/scsi/NCR_Q720.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/NCR_Q720.c	2003-07-19 17:03:50.000000000 -0700
-@@ -85,6 +85,7 @@ NCR_Q720_probe_one(struct NCR_Q720_priva
- 	__u8 scsr1 = readb(vaddr + NCR_Q720_SCSR_OFFSET + 1);
- 	__u8 differential = readb(vaddr + NCR_Q720_SCSR_OFFSET) & 0x20;
- 	__u8 version;
-+	int error;
- 
- 	scsi_id = scsr1 >> 4;
- 	/* enable burst length 16 (FIXME: should allow this) */
-@@ -120,9 +121,12 @@ NCR_Q720_probe_one(struct NCR_Q720_priva
- 	scsr1 &= ~0x01;
- 	writeb(scsr1, vaddr + NCR_Q720_SCSR_OFFSET + 1);
- 
--	scsi_add_host(p->hosts[siop], p->dev);
--
--	return 0;
-+	error = scsi_add_host(p->hosts[siop], p->dev);
-+	if (error)
-+		ncr53c8xx_release(p->hosts[siop]);
-+	else
-+		scsi_scan_host(p->hosts[siop]);
-+	return error;
- 
-  fail:
- 	return -ENODEV;
-@@ -347,7 +351,6 @@ static void __exit
- NCR_Q720_exit(void)
- {
- 	mca_unregister_driver(&NCR_Q720_driver);
--	//scsi_sysfs_release_attributes(&NCR_Q720_driver_template);
- }
- 
- module_init(NCR_Q720_init);
---- linux-2.6.0-test1/drivers/scsi/nsp32.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/nsp32.c	2003-07-19 17:03:50.000000000 -0700
-@@ -25,7 +25,7 @@
- #include <linux/timer.h>
- #include <linux/ioport.h>
- #include <linux/major.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/pci.h>
- #include <linux/delay.h>
-@@ -1820,7 +1820,8 @@ static int nsp32_detect(struct pci_dev *
- 		goto free_irq;
-         }
- 
--	scsi_add_host(host, &pdev->dev);
-+	scsi_add_host(host, &pdev->dev); /* XXX handle failure */
-+	scsi_scan_host(host);
- 	pci_set_drvdata(pdev, host);
- 	return 0;
- 
---- linux-2.6.0-test1/drivers/scsi/oktagon_esp.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/scsi/oktagon_esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -20,7 +20,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/reboot.h>
---- linux-2.6.0-test1/drivers/scsi/osst.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/osst.c	2003-07-19 17:03:50.000000000 -0700
-@@ -46,7 +46,7 @@ const char * osst_version = "0.99.0";
- #include <linux/spinlock.h>
- #include <linux/vmalloc.h>
- #include <linux/version.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/devfs_fs_kernel.h>
- #include <asm/uaccess.h>
- #include <asm/dma.h>
---- linux-2.6.0-test1/drivers/scsi/pas16.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/pas16.c	2003-07-19 17:03:50.000000000 -0700
-@@ -117,7 +117,8 @@
- #include <linux/proc_fs.h>
- #include <linux/sched.h>
- #include <asm/io.h>
--#include <linux/blk.h>
-+#include <asm/dma.h>
-+#include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/stat.h>
---- linux-2.6.0-test1/drivers/scsi/pc980155.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/pc980155.c	2003-07-19 17:03:50.000000000 -0700
-@@ -11,7 +11,7 @@
-  */
- 
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/ioport.h>
- #include <linux/interrupt.h>
- #include <linux/types.h>
---- linux-2.6.0-test1/drivers/scsi/pci2000.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/pci2000.c	2003-07-19 17:03:50.000000000 -0700
-@@ -35,7 +35,7 @@
-  ****************************************************************************/
- #define PCI2000_VERSION		"1.20"
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
---- linux-2.6.0-test1/drivers/scsi/pci2220i.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/pci2220i.c	2003-07-19 17:03:50.000000000 -0700
-@@ -50,7 +50,7 @@
- #include <linux/sched.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/timer.h>
- #include <linux/spinlock.h>
- 
---- linux-2.6.0-test1/drivers/scsi/pcmcia/aha152x_stub.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/drivers/scsi/pcmcia/aha152x_stub.c	2003-07-19 17:03:50.000000000 -0700
-@@ -44,7 +44,7 @@
- #include <linux/ioport.h>
- #include <scsi/scsi.h>
- #include <linux/major.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <scsi/scsi_ioctl.h>
- 
- #include "scsi.h"
-@@ -278,7 +278,8 @@ static void aha152x_config_cs(dev_link_t
- 	goto cs_failed;
-     }
- 
--    scsi_add_host(host, NULL);
-+    scsi_add_host(host, NULL); /* XXX handle failure */
-+    scsi_scan_host(host);
- 
-     sprintf(info->node.dev_name, "scsi%d", host->host_no);
-     link->dev = &info->node;
---- linux-2.6.0-test1/drivers/scsi/pcmcia/fdomain_stub.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/scsi/pcmcia/fdomain_stub.c	2003-07-19 17:03:50.000000000 -0700
-@@ -41,7 +41,7 @@
- #include <linux/ioport.h>
- #include <scsi/scsi.h>
- #include <linux/major.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <scsi/scsi_ioctl.h>
- 
- #include "scsi.h"
-@@ -254,7 +254,8 @@ static void fdomain_config(dev_link_t *l
- 	goto cs_failed;
-     }
-  
--    scsi_add_host(host, NULL);
-+    scsi_add_host(host, NULL); /* XXX handle failure */
-+    scsi_scan_host(host);
- 
-     sprintf(info->node.dev_name, "scsi%d", host->host_no);
-     link->dev = &info->node;
---- linux-2.6.0-test1/drivers/scsi/pcmcia/nsp_cs.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/pcmcia/nsp_cs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -44,7 +44,7 @@
- #include <linux/interrupt.h>
- #include <linux/module.h>
- #include <linux/major.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/stat.h>
- 
- #include <asm/io.h>
-@@ -1773,7 +1773,8 @@ static void nsp_cs_config(dev_link_t *li
- 		       req.Base+req.Size-1);
- 	printk("\n");
- 
--	scsi_add_host(host, NULL);
-+	scsi_add_host(host, NULL); /* XXX handle failure */
-+	scsi_scan_host(host);
- 	link->state &= ~DEV_CONFIG_PENDING;
- 	return;
- 
---- linux-2.6.0-test1/drivers/scsi/pcmcia/qlogic_stub.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/scsi/pcmcia/qlogic_stub.c	2003-07-19 17:03:50.000000000 -0700
-@@ -42,7 +42,7 @@
- #include <asm/io.h>
- #include <scsi/scsi.h>
- #include <linux/major.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <scsi/scsi_ioctl.h>
- 
- #include "scsi.h"
-@@ -270,7 +270,8 @@ static void qlogic_config(dev_link_t * l
- 	link->dev = &info->node;
- 	info->host = host;
- 
--	scsi_add_host(host, NULL);
-+	scsi_add_host(host, NULL); /* XXX handle failure */
-+	scsi_scan_host(host);
- 
- out:
- 	link->state &= ~DEV_CONFIG_PENDING;
---- linux-2.6.0-test1/drivers/scsi/pluto.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/scsi/pluto.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/ppa.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/ppa.c	2003-07-19 17:03:50.000000000 -0700
-@@ -15,7 +15,7 @@
- /* The following #define is to avoid a clash with hosts.c */
- #define PPA_CODE 1
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/io.h>
- #include <linux/parport.h>
- #include <linux/workqueue.h>
---- linux-2.6.0-test1/drivers/scsi/ppa.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/scsi/ppa.h	2003-07-19 17:03:50.000000000 -0700
-@@ -82,7 +82,7 @@
- #include  <linux/delay.h>
- #include  <linux/proc_fs.h>
- #include  <linux/stat.h>
--#include  <linux/blk.h>
-+#include  <linux/blkdev.h>
- #include  <linux/sched.h>
- #include  <linux/interrupt.h>
- 
---- linux-2.6.0-test1/drivers/scsi/psi240i.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/psi240i.c	2003-07-19 17:03:50.000000000 -0700
-@@ -26,7 +26,7 @@
- 
- #include <linux/module.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/qla1280.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/scsi/qla1280.c	2003-07-19 17:03:50.000000000 -0700
-@@ -252,7 +252,7 @@
- #include <linux/timer.h>
- #include <linux/pci.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/workqueue.h>
- #include <linux/stat.h>
- #include <linux/slab.h>
-@@ -327,7 +327,7 @@
- /* 3.16 */
- #ifdef QLA_64BIT_PTR
- #define pci_dma_lo32(a)		(a & 0xffffffff)
--#define pci_dma_hi32(a)		(a >> 32)
-+#define pci_dma_hi32(a)		((a >> 16)>>16)
- #else
- #define pci_dma_lo32(a)		(a & 0xffffffff)
- #define pci_dma_hi32(a)		0
---- linux-2.6.0-test1/drivers/scsi/qlogicfas.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/qlogicfas.c	2003-07-19 17:03:50.000000000 -0700
-@@ -127,7 +127,7 @@
- #endif
- 
- #include <linux/module.h>
--#include <linux/blk.h>		/* to get disk capacity */
-+#include <linux/blkdev.h>		/* to get disk capacity */
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/init.h>
-@@ -140,6 +140,7 @@
- 
- #include <asm/io.h>
- #include <asm/irq.h>
-+#include <asm/dma.h>
- 
- #include "scsi.h"
- #include "hosts.h"
---- linux-2.6.0-test1/drivers/scsi/qlogicfc.c	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/scsi/qlogicfc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -50,7 +50,7 @@
-  *
-  */
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/ioport.h>
---- linux-2.6.0-test1/drivers/scsi/qlogicisp.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/scsi/qlogicisp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -20,7 +20,7 @@
-  * General Public License for more details.
-  */
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/qlogicpti.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/scsi/qlogicpti.c	2003-07-19 17:03:50.000000000 -0700
-@@ -17,7 +17,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/scsicam.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/scsi/scsicam.c	2003-07-19 17:03:50.000000000 -0700
-@@ -15,7 +15,7 @@
- #include <linux/fs.h>
- #include <linux/genhd.h>
- #include <linux/kernel.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/buffer_head.h>
- #include <asm/unaligned.h>
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/scsi_debug.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/scsi_debug.c	2003-07-19 17:03:50.000000000 -0700
-@@ -41,7 +41,7 @@
- #include <linux/vmalloc.h>
- #include <linux/moduleparam.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <scsi/scsicam.h>
-@@ -687,7 +687,7 @@ static int resp_mode_sense(unsigned char
- 	pcontrol = (cmd[2] & 0xc0) >> 6;
- 	pcode = cmd[2] & 0x3f;
- 	msense_6 = (MODE_SENSE == cmd[0]);
--	alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[6]);
-+	alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
- 	/* printk(KERN_INFO "msense: dbd=%d pcontrol=%d pcode=%d "
- 		"msense_6=%d alloc_len=%d\n", dbd, pcontrol, pcode, "
- 		"msense_6, alloc_len); */
-@@ -1701,7 +1701,8 @@ static int sdebug_driver_probe(struct de
-                 printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
-                 error = -ENODEV;
- 		scsi_host_put(hpnt);
--        }
-+        } else
-+		scsi_scan_host(hpnt);
- 
- 
-         return error;
---- linux-2.6.0-test1/drivers/scsi/scsi.h	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/scsi.h	2003-07-19 17:03:50.000000000 -0700
-@@ -174,11 +174,6 @@ extern const char *scsi_extd_sense_forma
- #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
- #define SCSI_MLQUEUE_EH_RETRY    0x1057
- 
--extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
--					    struct device_attribute *attr);
--extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
--					     struct class_device_attribute *attr);
--
- /*
-  * Legacy dma direction interfaces.
-  *
---- linux-2.6.0-test1/drivers/scsi/scsi_ioctl.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/scsi_ioctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -18,7 +18,7 @@
- #include <linux/mm.h>
- #include <linux/string.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <scsi/scsi_ioctl.h>
---- linux-2.6.0-test1/drivers/scsi/scsi_lib.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/scsi_lib.c	2003-07-19 17:03:50.000000000 -0700
-@@ -8,7 +8,7 @@
-  */
- 
- #include <linux/bio.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/completion.h>
- #include <linux/kernel.h>
- #include <linux/mempool.h>
-@@ -444,22 +444,8 @@ static void scsi_run_queue(struct reques
-  */
- static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
- {
--	unsigned long flags;
--
--	spin_lock_irqsave(q->queue_lock, flags);
--	cmd->request->special = cmd;
--	if (blk_rq_tagged(cmd->request))
--		blk_queue_end_tag(q, cmd->request);
--
--	/*
--	 * set REQ_SPECIAL - we have a command
--	 * clear REQ_DONTPREP - we assume the sg table has been 
--	 *	nuked so we need to set it up again.
--	 */
--	cmd->request->flags |= REQ_SPECIAL;
- 	cmd->request->flags &= ~REQ_DONTPREP;
--	__elv_add_request(q, cmd->request, 0, 0);
--	spin_unlock_irqrestore(q->queue_lock, flags);
-+	blk_insert_request(q, cmd->request, 1, cmd);
- 
- 	scsi_run_queue(q);
- }
-@@ -1213,9 +1199,7 @@ static void scsi_request_fn(struct reque
- 	 * later time.
- 	 */
- 	spin_lock_irq(q->queue_lock);
--	if (blk_rq_tagged(req))
--		blk_queue_end_tag(q, req);
--	__elv_add_request(q, req, 0, 0);
-+	blk_requeue_request(q, req);
- 	sdev->device_busy--;
- 	if(sdev->device_busy == 0)
- 		blk_plug_device(q);
-@@ -1426,17 +1410,17 @@ __scsi_mode_sense(struct scsi_request *s
- 	if(scsi_status_is_good(sreq->sr_result)) {
- 		data->header_length = header_length;
- 		if(use_10_for_ms) {
--			data->length = buffer[0]*256 + buffer[1];
-+			data->length = buffer[0]*256 + buffer[1] + 2;
- 			data->medium_type = buffer[2];
- 			data->device_specific = buffer[3];
- 			data->longlba = buffer[4] & 0x01;
- 			data->block_descriptor_length = buffer[6]*256
- 				+ buffer[7];
- 		} else {
--			data->length = buffer[0];
-+			data->length = buffer[0] + 1;
- 			data->medium_type = buffer[1];
--			data->device_specific = buffer[3];
--			data->block_descriptor_length = buffer[4];
-+			data->device_specific = buffer[2];
-+			data->block_descriptor_length = buffer[3];
- 		}
- 	}
- 
---- linux-2.6.0-test1/drivers/scsi/scsi_module.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/scsi_module.c	2003-07-19 17:05:05.000000000 -0700
-@@ -33,13 +33,14 @@ static int __init init_this_scsi_driver(
- 	INIT_LIST_HEAD(&sht->legacy_hosts);
- 
- 	sht->detect(sht);
--	if (!sht->present)
-+	if (list_empty(&sht->legacy_hosts))
- 		return -ENODEV;
- 
- 	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
- 		error = scsi_add_host(shost, NULL);
- 		if (error)
- 			goto fail;
-+		scsi_scan_host(shost);
- 	}
- 	return 0;
-  fail:
---- linux-2.6.0-test1/drivers/scsi/scsi_pc98.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/scsi/scsi_pc98.c	2003-07-19 17:03:50.000000000 -0700
-@@ -8,7 +8,7 @@
- #include <linux/fs.h>
- #include <linux/kernel.h>
- #include <linux/genhd.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/pc9800.h>
- 
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/scsi_priv.h	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/scsi_priv.h	2003-07-19 17:05:05.000000000 -0700
-@@ -90,11 +90,15 @@ extern void scsi_exit_queue(void);
- 
- /* scsi_proc.c */
- #ifdef CONFIG_PROC_FS
-+extern void scsi_proc_hostdir_add(struct scsi_host_template *);
-+extern void scsi_proc_hostdir_rm(struct scsi_host_template *);
- extern void scsi_proc_host_add(struct Scsi_Host *);
- extern void scsi_proc_host_rm(struct Scsi_Host *);
- extern int scsi_init_procfs(void);
- extern void scsi_exit_procfs(void);
- #else
-+# define scsi_proc_hostdir_add(sht)	do { } while (0)
-+# define scsi_proc_hostdir_rm(sht)	do { } while (0)
- # define scsi_proc_host_add(shost)	do { } while (0)
- # define scsi_proc_host_rm(shost)	do { } while (0)
- # define scsi_init_procfs()		(0)
-@@ -102,7 +106,6 @@ extern void scsi_exit_procfs(void);
- #endif /* CONFIG_PROC_FS */
- 
- /* scsi_scan.c */
--extern void scsi_scan_host(struct Scsi_Host *);
- extern void scsi_forget_host(struct Scsi_Host *);
- extern void scsi_free_sdev(struct scsi_device *);
- extern void scsi_free_shost(struct Scsi_Host *);
-@@ -117,11 +120,6 @@ extern void scsi_sysfs_remove_host(struc
- extern int scsi_sysfs_register(void);
- extern void scsi_sysfs_unregister(void);
- 
--/* definitions for the linker default sections covering the host
-- * class and device attributes */
--extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
--extern struct device_attribute *scsi_sysfs_sdev_attrs[];
--
- extern struct class shost_class;
- extern struct bus_type scsi_bus_type;
- 
---- linux-2.6.0-test1/drivers/scsi/scsi_proc.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/scsi_proc.c	2003-07-19 17:05:05.000000000 -0700
-@@ -23,7 +23,7 @@
- #include <linux/slab.h>
- #include <linux/proc_fs.h>
- #include <linux/errno.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/seq_file.h>
- #include <asm/uaccess.h>
- 
-@@ -41,6 +41,8 @@
- struct proc_dir_entry *proc_scsi;
- EXPORT_SYMBOL(proc_scsi);
- 
-+/* Protect sht->present and sht->proc_dir */
-+static DECLARE_MUTEX(global_host_template_sem);
- 
- static int proc_scsi_read(char *buffer, char **start, off_t offset,
- 			  int length, int *eof, void *data)
-@@ -77,16 +79,10 @@ out:
- 	return ret;
- }
- 
--void scsi_proc_host_add(struct Scsi_Host *shost)
-+void scsi_proc_hostdir_add(struct scsi_host_template *sht)
- {
--	struct scsi_host_template *sht = shost->hostt;
--	struct proc_dir_entry *p;
--	char name[10];
--
--	if (!sht->proc_info)
--		return;
--
--	if (!sht->proc_dir) {
-+	down(&global_host_template_sem);
-+	if (!sht->present++) {
- 		sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
-         	if (!sht->proc_dir) {
- 			printk(KERN_ERR "%s: proc_mkdir failed for %s\n",
-@@ -95,6 +91,27 @@ void scsi_proc_host_add(struct Scsi_Host
- 		}
- 		sht->proc_dir->owner = sht->module;
- 	}
-+	up(&global_host_template_sem);
-+}
-+
-+void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
-+{
-+	down(&global_host_template_sem);
-+	if (!--sht->present && sht->proc_dir) {
-+		remove_proc_entry(sht->proc_name, proc_scsi);
-+		sht->proc_dir = NULL;
-+	}
-+	up(&global_host_template_sem);
-+}
-+
-+void scsi_proc_host_add(struct Scsi_Host *shost)
-+{
-+	struct scsi_host_template *sht = shost->hostt;
-+	struct proc_dir_entry *p;
-+	char name[10];
-+
-+	if (!sht->proc_dir)
-+		return;
- 
- 	sprintf(name,"%d", shost->host_no);
- 	p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
-@@ -107,20 +124,18 @@ void scsi_proc_host_add(struct Scsi_Host
- 	} 
- 
- 	p->write_proc = proc_scsi_write_proc;
--	p->owner = shost->hostt->module;
-+	p->owner = sht->module;
- }
- 
- void scsi_proc_host_rm(struct Scsi_Host *shost)
- {
--	struct scsi_host_template *sht = shost->hostt;
- 	char name[10];
- 
--	if (sht->proc_info) {
--		sprintf(name,"%d", shost->host_no);
--		remove_proc_entry(name, sht->proc_dir);
--		if (!sht->present)
--			remove_proc_entry(sht->proc_name, proc_scsi);
--	}
-+	if (!shost->hostt->proc_dir)
-+		return;
-+
-+	sprintf(name,"%d", shost->host_no);
-+	remove_proc_entry(name, shost->hostt->proc_dir);
- }
- 
- static int proc_print_scsidevice(struct device *dev, void *data)
---- linux-2.6.0-test1/drivers/scsi/scsi_scan.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/scsi/scsi_scan.c	2003-07-19 17:03:50.000000000 -0700
-@@ -29,7 +29,7 @@
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include "scsi.h"
- #include "hosts.h"
-@@ -464,8 +464,7 @@ static void scsi_set_name(struct scsi_de
- 	while (i >= 0 && type[i] == ' ')
- 		type[i--] = '\0';
- 
--	snprintf(sdev->sdev_driverfs_dev.name, DEVICE_NAME_SIZE, "SCSI %s",
--		 type);
-+	snprintf(sdev->sdev_gendev.name, DEVICE_NAME_SIZE, "SCSI %s", type);
- }
- 
- /**
---- linux-2.6.0-test1/drivers/scsi/scsi_syms.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/scsi_syms.c	2003-07-19 17:03:50.000000000 -0700
-@@ -11,7 +11,7 @@
- #include <linux/slab.h>
- #include <linux/ioport.h>
- #include <linux/kernel.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/fs.h>
- 
- #include <asm/system.h>
-@@ -34,6 +34,7 @@ EXPORT_SYMBOL(scsi_register_driver);
- EXPORT_SYMBOL(scsi_register_interface);
- EXPORT_SYMBOL(scsi_host_alloc);
- EXPORT_SYMBOL(scsi_add_host);
-+EXPORT_SYMBOL(scsi_scan_host);
- EXPORT_SYMBOL(scsi_remove_host);
- EXPORT_SYMBOL(scsi_host_get);
- EXPORT_SYMBOL(scsi_host_put);
---- linux-2.6.0-test1/drivers/scsi/scsi_sysfs.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/scsi_sysfs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -45,7 +45,7 @@ shost_rd_attr(cmd_per_lun, "%hd\n");
- shost_rd_attr(sg_tablesize, "%hu\n");
- shost_rd_attr(unchecked_isa_dma, "%d\n");
- 
--struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
-+static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
- 	&class_device_attr_unique_id,
- 	&class_device_attr_host_busy,
- 	&class_device_attr_cmd_per_lun,
-@@ -204,7 +204,7 @@ store_rescan_field (struct device *dev, 
- static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
- 
- /* Default template for device attributes.  May NOT be modified */
--struct device_attribute *scsi_sysfs_sdev_attrs[] = {
-+static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
- 	&dev_attr_device_blocked,
- 	&dev_attr_queue_depth,
- 	&dev_attr_type,
-@@ -228,6 +228,42 @@ static void scsi_device_release(struct d
- 	scsi_free_sdev(sdev);
- }
- 
-+static struct device_attribute *attr_overridden(
-+		struct device_attribute **attrs,
-+		struct device_attribute *attr)
-+{
-+	int i;
-+
-+	if (!attrs)
-+		return NULL;
-+	for (i = 0; attrs[i]; i++)
-+		if (!strcmp(attrs[i]->attr.name, attr->attr.name))
-+			return attrs[i];
-+	return NULL;
-+}
-+
-+static int attr_add(struct device *dev, struct device_attribute *attr)
-+{
-+	struct device_attribute *base_attr;
-+
-+	/*
-+	 * Spare the caller from having to copy things it's not interested in.
-+	 */
-+	base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr);
-+	if (base_attr) {
-+		/* extend permissions */
-+		attr->attr.mode |= base_attr->attr.mode;
-+
-+		/* override null show/store with default */
-+		if (!attr->show)
-+			attr->show = base_attr->show;
-+		if (!attr->store)
-+			attr->store = base_attr->store;
-+	}
-+
-+	return device_create_file(dev, attr);
-+}
-+
- /**
-  * scsi_device_register - register a scsi device with the scsi bus
-  * @sdev:	scsi_device to register
-@@ -239,20 +275,20 @@ int scsi_device_register(struct scsi_dev
- {
- 	int error = 0, i;
- 
--	device_initialize(&sdev->sdev_driverfs_dev);
--	sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
-+	device_initialize(&sdev->sdev_gendev);
-+	sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
- 		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
--	sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev;
--	sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
--	sdev->sdev_driverfs_dev.release = scsi_device_release;
-+	sdev->sdev_gendev.parent = &sdev->host->shost_gendev;
-+	sdev->sdev_gendev.bus = &scsi_bus_type;
-+	sdev->sdev_gendev.release = scsi_device_release;
- 
- 	class_device_initialize(&sdev->sdev_classdev);
--	sdev->sdev_classdev.dev = &sdev->sdev_driverfs_dev;
-+	sdev->sdev_classdev.dev = &sdev->sdev_gendev;
- 	sdev->sdev_classdev.class = &sdev_class;
- 	snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d",
- 		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
- 
--	error = device_add(&sdev->sdev_driverfs_dev);
-+	error = device_add(&sdev->sdev_gendev);
- 	if (error) {
- 		printk(KERN_INFO "error 1\n");
- 		return error;
-@@ -260,16 +296,28 @@ int scsi_device_register(struct scsi_dev
- 	error = class_device_add(&sdev->sdev_classdev);
- 	if (error) {
- 		printk(KERN_INFO "error 2\n");
--		device_unregister(&sdev->sdev_driverfs_dev);
-+		device_unregister(&sdev->sdev_gendev);
- 		return error;
- 	}
- 
--	for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
--		error = device_create_file(&sdev->sdev_driverfs_dev,
--					   sdev->host->hostt->sdev_attrs[i]);
--
--	if (error)
--		scsi_device_unregister(sdev);
-+	if (sdev->host->hostt->sdev_attrs) {
-+		for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
-+			error = attr_add(&sdev->sdev_gendev,
-+					sdev->host->hostt->sdev_attrs[i]);
-+			if (error)
-+				scsi_device_unregister(sdev);
-+		}
-+	}
-+	
-+	for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
-+		if (!attr_overridden(sdev->host->hostt->sdev_attrs,
-+					scsi_sysfs_sdev_attrs[i])) {
-+			error = device_create_file(&sdev->sdev_gendev,
-+					scsi_sysfs_sdev_attrs[i]);
-+			if (error)
-+				scsi_device_unregister(sdev);
-+		}
-+	}
- 
- 	return error;
- }
-@@ -280,12 +328,8 @@ int scsi_device_register(struct scsi_dev
-  **/
- void scsi_device_unregister(struct scsi_device *sdev)
- {
--	int i;
--
--	for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
--		device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]);
- 	class_device_unregister(&sdev->sdev_classdev);
--	device_unregister(&sdev->sdev_driverfs_dev);
-+	device_unregister(&sdev->sdev_gendev);
- }
- 
- int scsi_register_driver(struct device_driver *drv)
-@@ -315,20 +359,57 @@ static void scsi_host_release(struct dev
- 
- void scsi_sysfs_init_host(struct Scsi_Host *shost)
- {
--	device_initialize(&shost->host_gendev);
--	snprintf(shost->host_gendev.bus_id, BUS_ID_SIZE, "host%d",
-+	device_initialize(&shost->shost_gendev);
-+	snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
- 		shost->host_no);
--	snprintf(shost->host_gendev.name, DEVICE_NAME_SIZE, "%s",
-+	snprintf(shost->shost_gendev.name, DEVICE_NAME_SIZE, "%s",
- 		shost->hostt->proc_name);
--	shost->host_gendev.release = scsi_host_release;
-+	shost->shost_gendev.release = scsi_host_release;
- 
--	class_device_initialize(&shost->class_dev);
--	shost->class_dev.dev = &shost->host_gendev;
--	shost->class_dev.class = &shost_class;
--	snprintf(shost->class_dev.class_id, BUS_ID_SIZE, "host%d",
-+	class_device_initialize(&shost->shost_classdev);
-+	shost->shost_classdev.dev = &shost->shost_gendev;
-+	shost->shost_classdev.class = &shost_class;
-+	snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
- 		  shost->host_no);
- }
- 
-+static struct class_device_attribute *class_attr_overridden(
-+		struct class_device_attribute **attrs,
-+		struct class_device_attribute *attr)
-+{
-+	int i;
-+
-+	if (!attrs)
-+		return NULL;
-+	for (i = 0; attrs[i]; i++)
-+		if (!strcmp(attrs[i]->attr.name, attr->attr.name))
-+			return attrs[i];
-+	return NULL;
-+}
-+
-+static int class_attr_add(struct class_device *classdev,
-+		struct class_device_attribute *attr)
-+{
-+	struct class_device_attribute *base_attr;
-+
-+	/*
-+	 * Spare the caller from having to copy things it's not interested in.
-+	 */
-+	base_attr = class_attr_overridden(scsi_sysfs_shost_attrs, attr);
-+	if (base_attr) {
-+		/* extend permissions */
-+		attr->attr.mode |= base_attr->attr.mode;
-+
-+		/* override null show/store with default */
-+		if (!attr->show)
-+			attr->show = base_attr->show;
-+		if (!attr->store)
-+			attr->store = base_attr->store;
-+	}
-+
-+	return class_device_create_file(classdev, attr);
-+}
-+
- /**
-  * scsi_sysfs_add_host - add scsi host to subsystem
-  * @shost:     scsi host struct to add to subsystem
-@@ -336,31 +417,44 @@ void scsi_sysfs_init_host(struct Scsi_Ho
-  **/
- int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
- {
--	int i, error;
-+	int error, i;
- 
--	if (!shost->host_gendev.parent)
--		shost->host_gendev.parent = dev ? dev : &legacy_bus;
-+	if (!shost->shost_gendev.parent)
-+		shost->shost_gendev.parent = dev ? dev : &legacy_bus;
- 
--	error = device_add(&shost->host_gendev);
-+	error = device_add(&shost->shost_gendev);
- 	if (error)
- 		return error;
- 
--	error = class_device_add(&shost->class_dev);
-+	error = class_device_add(&shost->shost_classdev);
- 	if (error)
- 		goto clean_device;
- 
--	for (i = 0; !error && shost->hostt->shost_attrs[i] != NULL; i++)
--		error = class_device_create_file(&shost->class_dev,
--					   shost->hostt->shost_attrs[i]);
--	if (error)
--		goto clean_class;
-+	if (shost->hostt->shost_attrs) {
-+		for (i = 0; shost->hostt->shost_attrs[i]; i++) {
-+			error = class_attr_add(&shost->shost_classdev,
-+					shost->hostt->shost_attrs[i]);
-+			if (error)
-+				goto clean_class;
-+		}
-+	}
-+
-+	for (i = 0; scsi_sysfs_shost_attrs[i]; i++) {
-+		if (!class_attr_overridden(shost->hostt->shost_attrs,
-+					scsi_sysfs_shost_attrs[i])) {
-+			error = class_device_create_file(&shost->shost_classdev,
-+					scsi_sysfs_shost_attrs[i]);
-+			if (error)
-+				goto clean_class;
-+		}
-+	}
- 
- 	return error;
- 
- clean_class:
--	class_device_del(&shost->class_dev);
-+	class_device_del(&shost->shost_classdev);
- clean_device:
--	device_del(&shost->host_gendev);
-+	device_del(&shost->shost_gendev);
- 
- 	return error;
- }
-@@ -371,133 +465,6 @@ clean_device:
-  **/
- void scsi_sysfs_remove_host(struct Scsi_Host *shost)
- {
--	class_device_del(&shost->class_dev);
--	device_del(&shost->host_gendev);
--}
--
--/** scsi_sysfs_modify_shost_attribute - modify or add a host class attribute
-- *
-- * @class_attrs:host class attribute list to be added to or modified
-- * @attr:	individual attribute to change or added
-- *
-- * returns zero if successful or error if not
-- **/
--int scsi_sysfs_modify_shost_attribute(
--			struct class_device_attribute ***class_attrs,
--			struct class_device_attribute *attr)
--{
--	int modify = -1;
--	int num_attrs;
--
--	if(*class_attrs == NULL)
--		*class_attrs = scsi_sysfs_shost_attrs;
--
--	for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++)
--		if(strcmp((*class_attrs)[num_attrs]->attr.name,
--				attr->attr.name) == 0)
--			modify = num_attrs;
--
--	if(*class_attrs == scsi_sysfs_shost_attrs || modify < 0) {
--		/* note: need space for null at the end as well */
--		struct class_device_attribute **tmp_attrs =
--				kmalloc(sizeof(*tmp_attrs) *
--					  (num_attrs + (modify >= 0 ? 1 : 2)),
--					GFP_KERNEL);
--		if(tmp_attrs == NULL)
--			return -ENOMEM;
--		memcpy(tmp_attrs, *class_attrs, sizeof(*tmp_attrs) *
--				(num_attrs + 1));
--		if(*class_attrs != scsi_sysfs_shost_attrs)
--			kfree(*class_attrs);
--		*class_attrs = tmp_attrs;
--	}
--	if(modify >= 0) {
--		/* spare the caller from having to copy things it's
--		 * not interested in */
--		struct class_device_attribute *old_attr =
--			(*class_attrs)[modify];
--		/* extend permissions */
--		attr->attr.mode |= old_attr->attr.mode;
--
--		/* override null show/store with default */
--		if(attr->show == NULL)
--			attr->show = old_attr->show;
--		if(attr->store == NULL)
--			attr->store = old_attr->store;
--		(*class_attrs)[modify] = attr;
--	} else {
--		(*class_attrs)[num_attrs++] = attr;
--		(*class_attrs)[num_attrs] = NULL;
--	}
--
--	return 0;
--}
--EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute);
--
--/** scsi_sysfs_modify_sdev_attribute - modify or add a host device attribute
-- *
-- * @dev_attrs:	pointer to the attribute list to be added to or modified
-- * @attr:	individual attribute to change or added
-- *
-- * returns zero if successful or error if not
-- **/
--int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
--				     struct device_attribute *attr)
--{
--	int modify = -1;
--	int num_attrs;
--
--	if(*dev_attrs == NULL)
--		*dev_attrs = scsi_sysfs_sdev_attrs;
--
--	for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++)
--		if(strcmp((*dev_attrs)[num_attrs]->attr.name,
--				attr->attr.name) == 0)
--			modify = num_attrs;
--
--	if(*dev_attrs == scsi_sysfs_sdev_attrs || modify < 0) {
--		/* note: need space for null at the end as well */
--		struct device_attribute **tmp_attrs =
--				kmalloc(sizeof(*tmp_attrs) *
--					  (num_attrs + (modify >= 0 ? 1 : 2)),
--					GFP_KERNEL);
--		if(tmp_attrs == NULL)
--			return -ENOMEM;
--		memcpy(tmp_attrs, *dev_attrs, sizeof(*tmp_attrs) *
--				(num_attrs + 1));
--		if(*dev_attrs != scsi_sysfs_sdev_attrs)
--			kfree(*dev_attrs);
--		*dev_attrs = tmp_attrs;
--	}
--	if(modify >= 0) {
--		/* spare the caller from having to copy things it's
--		 * not interested in */
--		struct device_attribute *old_attr =
--			(*dev_attrs)[modify];
--		/* extend permissions */
--		attr->attr.mode |= old_attr->attr.mode;
--
--		/* override null show/store with default */
--		if(attr->show == NULL)
--			attr->show = old_attr->show;
--		if(attr->store == NULL)
--			attr->store = old_attr->store;
--		(*dev_attrs)[modify] = attr;
--	} else {
--		(*dev_attrs)[num_attrs++] = attr;
--		(*dev_attrs)[num_attrs] = NULL;
--	}
--
--	return 0;
--}
--EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
--
--void scsi_sysfs_release_attributes(struct scsi_host_template *hostt)
--{
--	if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs)
--		kfree(hostt->sdev_attrs);
--
--	if(hostt->shost_attrs != scsi_sysfs_shost_attrs)
--		kfree(hostt->shost_attrs);
-+	class_device_del(&shost->shost_classdev);
-+	device_del(&shost->shost_gendev);
- }
--EXPORT_SYMBOL(scsi_sysfs_release_attributes);
---- linux-2.6.0-test1/drivers/scsi/sd.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/sd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -43,7 +43,7 @@
- #include <linux/init.h>
- #include <linux/reboot.h>
- #include <linux/vmalloc.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <asm/uaccess.h>
- 
-@@ -606,35 +606,8 @@ not_present:
- 
- static void sd_rescan(struct device *dev)
- {
--	struct scsi_device *sdp = to_scsi_device(dev);
- 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
--	struct gendisk *gd;
--	struct scsi_request *SRpnt;
--	unsigned char *buffer;
--
--	if (!sdkp || sdp->online == FALSE || !sdkp->media_present)
--		return;
--		
--	gd = sdkp->disk;
--	
--	SCSI_LOG_HLQUEUE(3, printk("sd_rescan: disk=%s\n", gd->disk_name));
--	
--	SRpnt = scsi_allocate_request(sdp);
--	if (!SRpnt) {
--		printk(KERN_WARNING "(sd_rescan:) Request allocation "
--		       "failure.\n");
--		return;
--	}
--
--	if (sdkp->device->host->unchecked_isa_dma)
--		buffer = kmalloc(512, GFP_DMA);
--	else
--		buffer = kmalloc(512, GFP_KERNEL);
--
--    	sd_read_capacity(sdkp, gd->disk_name, SRpnt, buffer);
--	set_capacity(gd, sdkp->capacity);	
--	scsi_release_request(SRpnt);
--	kfree(buffer);
-+	sd_revalidate_disk(sdkp->disk);
- }
- 
- static struct block_device_operations sd_fops = {
-@@ -1318,7 +1291,7 @@ static int sd_probe(struct device *dev)
- 
- 	sd_revalidate_disk(gd);
- 
--	gd->driverfs_dev = &sdp->sdev_driverfs_dev;
-+	gd->driverfs_dev = &sdp->sdev_gendev;
- 	gd->flags = GENHD_FL_DRIVERFS;
- 	if (sdp->removable)
- 		gd->flags |= GENHD_FL_REMOVABLE;
---- linux-2.6.0-test1/drivers/scsi/seagate.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/seagate.c	2003-07-19 17:03:50.000000000 -0700
-@@ -95,7 +95,7 @@
- #include <linux/proc_fs.h>
- #include <linux/init.h>
- #include <linux/delay.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/stat.h>
- 
- #include <asm/io.h>
---- linux-2.6.0-test1/drivers/scsi/sg.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/sg.c	2003-07-19 17:06:39.000000000 -0700
-@@ -61,7 +61,7 @@ static int sg_version_num = 30529;	/* 2 
- #include <asm/uaccess.h>
- #include <asm/system.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <scsi/scsi_driver.h>
-@@ -83,7 +83,7 @@ static void sg_proc_cleanup(void);
- #define SG_ALLOW_DIO_DEF 0
- #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
- 
--#define SG_MAX_DEVS_MASK ((1U << KDEV_MINOR_BITS) - 1)
-+#define SG_MAX_DEVS_MASK 255
- 
- /*
-  * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
---- linux-2.6.0-test1/drivers/scsi/sgiwd93.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/scsi/sgiwd93.c	2003-07-19 17:03:50.000000000 -0700
-@@ -15,7 +15,7 @@
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/version.h>
- #include <linux/delay.h>
- #include <linux/spinlock.h>
---- linux-2.6.0-test1/drivers/scsi/sim710.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/sim710.c	2003-07-19 17:03:50.000000000 -0700
-@@ -29,7 +29,7 @@
- #include <linux/config.h>
- #include <linux/module.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/device.h>
- #include <linux/init.h>
- #include <linux/mca.h>
-@@ -138,7 +138,8 @@ sim710_probe_common(struct device *dev, 
- 		goto out_unregister;
- 	}
- 
--	scsi_add_host(host, dev);
-+	scsi_add_host(host, dev); /* XXX handle failure */
-+	scsi_scan_host(host);
- 	hostdata->dev = dev;
- 
- 	return 0;
---- linux-2.6.0-test1/drivers/scsi/sr.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/sr.c	2003-07-19 17:06:39.000000000 -0700
-@@ -43,7 +43,7 @@
- #include <linux/cdrom.h>
- #include <linux/interrupt.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/uaccess.h>
- 
- #include "scsi.h"
-@@ -59,7 +59,7 @@
- MODULE_PARM(xa_test, "i");	/* see sr_ioctl.c */
- 
- 
--#define SR_DISKS	(1 << KDEV_MINOR_BITS)
-+#define SR_DISKS	256
- 
- #define MAX_RETRIES	3
- #define SR_TIMEOUT	(30 * HZ)
-@@ -533,7 +533,7 @@ static int sr_probe(struct device *dev)
- 
- 	snprintf(disk->devfs_name, sizeof(disk->devfs_name),
- 			"%s/cd", sdev->devfs_name);
--	disk->driverfs_dev = &sdev->sdev_driverfs_dev;
-+	disk->driverfs_dev = &sdev->sdev_gendev;
- 	register_cdrom(&cd->cdi);
- 	set_capacity(disk, cd->capacity);
- 	disk->private_data = &cd->driver;
---- linux-2.6.0-test1/drivers/scsi/sr_ioctl.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/scsi/sr_ioctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -4,7 +4,7 @@
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <linux/cdrom.h>
- #include <asm/io.h>
---- linux-2.6.0-test1/drivers/scsi/sr_vendor.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/scsi/sr_vendor.c	2003-07-19 17:03:50.000000000 -0700
-@@ -39,7 +39,7 @@
- #include <linux/string.h>
- #include <linux/bcd.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- #include <scsi/scsi_ioctl.h>
---- linux-2.6.0-test1/drivers/scsi/st.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/st.c	2003-07-19 17:03:50.000000000 -0700
-@@ -32,7 +32,7 @@ static char *verstr = "20030622";
- #include <linux/ioctl.h>
- #include <linux/fcntl.h>
- #include <linux/spinlock.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/moduleparam.h>
- #include <linux/devfs_fs_kernel.h>
- #include <asm/uaccess.h>
---- linux-2.6.0-test1/drivers/scsi/sun3_scsi.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/scsi/sun3_scsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -61,7 +61,7 @@
- #include <linux/sched.h>
- #include <linux/ioport.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <asm/io.h>
- #include <asm/system.h>
---- linux-2.6.0-test1/drivers/scsi/sun3_scsi_vme.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/scsi/sun3_scsi_vme.c	2003-07-19 17:03:50.000000000 -0700
-@@ -23,7 +23,7 @@
- #include <linux/sched.h>
- #include <linux/ioport.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #include <asm/io.h>
- #include <asm/system.h>
---- linux-2.6.0-test1/drivers/scsi/sun3x_esp.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/sun3x_esp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/slab.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/proc_fs.h>
- #include <linux/stat.h>
- #include <linux/delay.h>
---- linux-2.6.0-test1/drivers/scsi/sym53c416.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/sym53c416.c	2003-07-19 17:03:50.000000000 -0700
-@@ -40,7 +40,7 @@
- #include <asm/dma.h>
- #include <asm/system.h>
- #include <asm/io.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/version.h>
- #include <linux/isapnp.h>
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1110,6 +1110,7 @@ static int sym_eh_handler(int op, char *
- 	int sts = -1;
- 	struct sym_eh_wait eh, *ep = &eh;
- 	char devname[20];
-+	unsigned long flags;
- 
- 	sprintf(devname, "%s:%d:%d", sym_name(np), cmd->device->id, cmd->device->lun);
- 
-@@ -1201,7 +1202,11 @@ finish:
- 		ep->timer.data = (u_long)cmd;
- 		ep->timed_out = 1;	/* Be pessimistic for once :) */
- 		add_timer(&ep->timer);
-+		local_save_flags(flags);
-+		spin_unlock_irq(cmd->device->host->host_lock);
- 		down(&ep->sem);
-+		local_irq_restore(flags);
-+		spin_lock(cmd->device->host->host_lock);
- 		if (ep->timed_out)
- 			sts = -2;
- 	}
---- linux-2.6.0-test1/drivers/scsi/sym53c8xx_2/sym_glue.h	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/scsi/sym53c8xx_2/sym_glue.h	2003-07-19 17:03:50.000000000 -0700
-@@ -84,7 +84,7 @@
- #include <linux/stat.h>
- #include <linux/interrupt.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #ifdef __sparc__
- #  include <asm/irq.h>
---- linux-2.6.0-test1/drivers/scsi/sym53c8xx_2/sym_hipd.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/sym53c8xx_2/sym_hipd.c	2003-07-19 17:04:52.000000000 -0700
-@@ -800,7 +800,8 @@ static int sym_prepare_setting(hcb_p np,
- 	 * Btw, 'period' is in tenths of nanoseconds.
- 	 */
- 	period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
--	if	(period <= 250)		np->minsync = 10;
-+	if	(period == 250)		np->minsync = 9;
-+	else if	(period <= 250)		np->minsync = 10;
- 	else if	(period <= 303)		np->minsync = 11;
- 	else if	(period <= 500)		np->minsync = 12;
- 	else				np->minsync = (period + 40 - 1) / 40;
---- linux-2.6.0-test1/drivers/scsi/sym53c8xx.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/scsi/sym53c8xx.c	2003-07-19 17:03:50.000000000 -0700
-@@ -123,7 +123,7 @@
- #include <linux/timer.h>
- #include <linux/stat.h>
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,35)
- #include <linux/init.h>
-@@ -1327,7 +1327,7 @@ MODULE_PARM(sym53c8xx, "s");
- #define SetScsiAbortResult(cmd) SetScsiResult(cmd, DID_ABORT, 0xff)
- #endif
- 
--static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
-+static irqreturn_t sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
- static void sym53c8xx_timeout(unsigned long np);
- 
- #define initverbose (driver_setup.verbose)
-@@ -7374,7 +7374,7 @@ void ncr_complete (ncb_p np, ccb_p cp)
- 		}
- 		if (cp->xerr_status & XE_BAD_PHASE) {
- 			PRINT_ADDR(cmd);
--			printk ("illegal scsi phase (4/5).\n");
-+			printk ("invalid scsi phase (4/5).\n");
- 		}
- 		if (cp->xerr_status & XE_SODL_UNRUN) {
- 			PRINT_ADDR(cmd);
-@@ -13660,7 +13660,7 @@ printk("sym53c8xx : command successfully
- **   routine for each host that uses this IRQ.
- */
- 
--static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
-+static irqreturn_t sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
- {
-      unsigned long flags;
-      ncb_p np = (ncb_p) dev_id;
-@@ -13685,6 +13685,7 @@ static void sym53c8xx_intr(int irq, void
-           ncr_flush_done_cmds(done_list);
-           NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags);
-      }
-+     return IRQ_HANDLED;
- }
- 
- /*
---- linux-2.6.0-test1/drivers/scsi/t128.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/t128.c	2003-07-19 17:03:50.000000000 -0700
-@@ -110,7 +110,7 @@
- #include <linux/signal.h>
- #include <linux/sched.h>
- #include <asm/io.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/stat.h>
- #include <linux/init.h>
---- linux-2.6.0-test1/drivers/scsi/tmscsim.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/scsi/tmscsim.c	2003-07-19 17:03:50.000000000 -0700
-@@ -224,7 +224,7 @@
- #include <linux/mm.h>
- #include <linux/config.h>
- #include <linux/version.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/timer.h>
- 
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/u14-34f.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/u14-34f.c	2003-07-19 17:03:50.000000000 -0700
-@@ -414,7 +414,7 @@
- #include <asm/system.h>
- #include <asm/byteorder.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/stat.h>
- #include <linux/pci.h>
---- linux-2.6.0-test1/drivers/scsi/ultrastor.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/ultrastor.c	2003-07-19 17:03:50.000000000 -0700
-@@ -128,7 +128,7 @@
-  */
- 
- #include <linux/module.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/interrupt.h>
- #include <linux/stddef.h>
- #include <linux/string.h>
---- linux-2.6.0-test1/drivers/scsi/wd33c93.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/scsi/wd33c93.c	2003-07-19 17:03:50.000000000 -0700
-@@ -79,7 +79,7 @@
- #include <linux/delay.h>
- #include <linux/version.h>
- #include <linux/init.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <asm/irq.h>
- 
- #include "scsi.h"
---- linux-2.6.0-test1/drivers/scsi/wd7000.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/scsi/wd7000.c	2003-07-19 17:03:50.000000000 -0700
-@@ -174,7 +174,7 @@
- #include <linux/spinlock.h>
- #include <linux/ioport.h>
- #include <linux/proc_fs.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/init.h>
- #include <linux/stat.h>
- 
---- linux-2.6.0-test1/drivers/scsi/zalon.c	2003-07-02 14:53:15.000000000 -0700
-+++ 25/drivers/scsi/zalon.c	2003-07-19 17:03:50.000000000 -0700
-@@ -7,7 +7,7 @@
- #include <linux/types.h>
- #include <linux/stat.h>
- #include <linux/mm.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/sched.h>
- #include <linux/version.h>
- #include <linux/config.h>
-@@ -85,7 +85,7 @@ zalon_scsi_callback(struct parisc_device
- {
- 	struct gsc_irq gsc_irq;
- 	u32 zalon_vers;
--	int irq;
-+	int irq, error = -ENODEV;
- 	unsigned long zalon = dev->hpa;
- 	unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET;
- 	static int unit = 0;
-@@ -147,11 +147,18 @@ zalon_scsi_callback(struct parisc_device
- 
- 	dev_set_drvdata(&dev->dev, host);
- 
--	scsi_add_host(host, &dev->dev);
-+	error = scsi_add_host(host, &dev->dev);
-+	if (error)
-+		goto fail_free_irq;
- 
-+	scsi_scan_host(host);
- 	return 0;
-+
-+ fail_free_irq:
-+	free_irq(irq, host);
-  fail:
--	return -ENODEV;
-+	ncr53c8xx_release(host);
-+	return error;
- }
- 
- static struct parisc_device_id zalon_tbl[] = {
---- linux-2.6.0-test1/drivers/serial/8250.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/serial/8250.c	2003-07-19 17:04:02.000000000 -0700
-@@ -823,7 +823,7 @@ receive_chars(struct uart_8250_port *up,
- 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
- 			tty->flip.work.func((void *)tty);
- 			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
--				return; // if TTY_DONT_FLIP is set
-+				return;	/* if TTY_DONT_FLIP is set */
- 		}
- 		ch = serial_inp(up, UART_RX);
- 		*tty->flip.char_buf_ptr = ch;
-@@ -1183,13 +1183,20 @@ static void serial8250_break_ctl(struct 
- 	serial_out(up, UART_LCR, up->lcr);
- 	spin_unlock_irqrestore(&up->port.lock, flags);
- }
-+#ifdef CONFIG_KGDB
-+static int kgdb_irq = -1;
-+#endif
- 
- static int serial8250_startup(struct uart_port *port)
- {
- 	struct uart_8250_port *up = (struct uart_8250_port *)port;
- 	unsigned long flags;
- 	int retval;
--
-+#ifdef CONFIG_KGDB
-+	if ( up->port.irq == kgdb_irq){
-+		return -EBUSY;
-+	}
-+#endif
- 	if (up->port.type == PORT_16C950) {
- 		/* Wake up and initialize UART */
- 		up->acr = 0;
-@@ -1853,6 +1860,11 @@ static void __init serial8250_register_p
- 	for (i = 0; i < UART_NR; i++) {
- 		struct uart_8250_port *up = &serial8250_ports[i];
- 
-+#ifdef CONFIG_KGDB
-+		if(up->port.irq == kgdb_irq){
-+			up->port.iobase = up->port.mapbase = 0;
-+		}
-+#endif
- 		up->port.line = i;
- 		up->port.ops = &serial8250_pops;
- 		init_timer(&up->timer);
-@@ -2116,7 +2128,31 @@ void serial8250_resume_port(int line, u3
- {
- 	uart_resume_port(&serial8250_reg, &serial8250_ports[line].port, level);
- }
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * Find all the ports using the given irq and shut them down.
-+ * Result should be that the irq will be released.
-+ */
-+void shutdown_for_kgdb(struct async_struct * info)
-+{
-+        int irq = info->state->irq;
-+        struct uart_8250_port *up;
-+	int ttyS;
-+
-+	kgdb_irq = irq;			/* save for later init */
-+	for (ttyS = 0; ttyS < UART_NR; ttyS++){
-+		up =  &serial8250_ports[ttyS];
-+		if( up->port.irq == irq && (irq_lists + irq)->head){
-+#ifdef CONFIG_DEBUG_SPINLOCK   /* ugly business... */
-+			if(up->port.lock.magic != SPINLOCK_MAGIC){
-+				spin_lock_init(&up->port.lock);
-+			}
-+#endif
-+			serial8250_shutdown(&up->port);
-+		}
-+        }
-+}
-+#endif
- static int __init serial8250_init(void)
- {
- 	int ret, i;
---- linux-2.6.0-test1/drivers/serial/core.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/drivers/serial/core.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1667,23 +1667,25 @@ static int uart_line_info(char *buf, str
- 		return ret + 1;
- 	}
- 
--	status = port->ops->get_mctrl(port);
--
--	ret += sprintf(buf + ret, " tx:%d rx:%d",
--			port->icount.tx, port->icount.rx);
--	if (port->icount.frame)
--		ret += sprintf(buf + ret, " fe:%d",
--			port->icount.frame);
--	if (port->icount.parity)
--		ret += sprintf(buf + ret, " pe:%d",
--			port->icount.parity);
--	if (port->icount.brk)
--		ret += sprintf(buf + ret, " brk:%d",
--			port->icount.brk);
--	if (port->icount.overrun)
--		ret += sprintf(buf + ret, " oe:%d",
--			port->icount.overrun);
--
-+	if(capable(CAP_SYS_ADMIN))
-+	{
-+		status = port->ops->get_mctrl(port);
-+
-+		ret += sprintf(buf + ret, " tx:%d rx:%d",
-+				port->icount.tx, port->icount.rx);
-+		if (port->icount.frame)
-+			ret += sprintf(buf + ret, " fe:%d",
-+				port->icount.frame);
-+		if (port->icount.parity)
-+			ret += sprintf(buf + ret, " pe:%d",
-+				port->icount.parity);
-+		if (port->icount.brk)
-+			ret += sprintf(buf + ret, " brk:%d",
-+				port->icount.brk);
-+		if (port->icount.overrun)
-+			ret += sprintf(buf + ret, " oe:%d",
-+				port->icount.overrun);
-+	
- #define INFOBIT(bit,str) \
- 	if (port->mctrl & (bit)) \
- 		strncat(stat_buf, (str), sizeof(stat_buf) - \
-@@ -1693,19 +1695,22 @@ static int uart_line_info(char *buf, str
- 		strncat(stat_buf, (str), sizeof(stat_buf) - \
- 		       strlen(stat_buf) - 2)
- 
--	stat_buf[0] = '\0';
--	stat_buf[1] = '\0';
--	INFOBIT(TIOCM_RTS, "|RTS");
--	STATBIT(TIOCM_CTS, "|CTS");
--	INFOBIT(TIOCM_DTR, "|DTR");
--	STATBIT(TIOCM_DSR, "|DSR");
--	STATBIT(TIOCM_CAR, "|CD");
--	STATBIT(TIOCM_RNG, "|RI");
--	if (stat_buf[0])
--		stat_buf[0] = ' ';
--	strcat(stat_buf, "\n");
--
--	ret += sprintf(buf + ret, stat_buf);
-+		stat_buf[0] = '\0';
-+		stat_buf[1] = '\0';
-+		INFOBIT(TIOCM_RTS, "|RTS");
-+		STATBIT(TIOCM_CTS, "|CTS");
-+		INFOBIT(TIOCM_DTR, "|DTR");
-+		STATBIT(TIOCM_DSR, "|DSR");
-+		STATBIT(TIOCM_CAR, "|CD");
-+		STATBIT(TIOCM_RNG, "|RI");
-+		if (stat_buf[0])
-+			stat_buf[0] = ' ';
-+		strcat(stat_buf, "\n");
-+	
-+		ret += sprintf(buf + ret, stat_buf);
-+	}
-+#undef STATBIT
-+#undef INFOBIT
- 	return ret;
- }
- 
---- linux-2.6.0-test1/drivers/serial/Kconfig	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/serial/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -404,14 +404,19 @@ config SERIAL_SUNSAB_CONSOLE
- 	  on your Sparc system as the console, you can do so by answering
- 	  Y to this option.
- 
--config V850E_NB85E_UART
-+config V850E_UART
- 	bool "NEC V850E on-chip UART support"
--	depends on V850E_NB85E || V850E2_ANNA || V850E_AS85EP1
-+	depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
- 	default y
- 
--config V850E_NB85E_UART_CONSOLE
-+config V850E_UARTB
-+        bool
-+	depends V850E_UART && V850E_ME2
-+	default y
-+
-+config V850E_UART_CONSOLE
- 	bool "Use NEC V850E on-chip UART for console"
--	depends on V850E_NB85E_UART
-+	depends on V850E_UART
- 
- config SERIAL98
- 	tristate "PC-9800 8251-based primary serial port support"
-@@ -426,12 +431,12 @@ config SERIAL98_CONSOLE
- 
- config SERIAL_CORE
- 	tristate
--	default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_NB85E_UART && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m)
--	default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_NB85E_UART || SERIAL98=y
-+	default m if SERIAL_AMBA!=y && SERIAL_CLPS711X!=y && SERIAL_21285!=y && !SERIAL_SA1100 && !SERIAL_ANAKIN && !SERIAL_UART00 && SERIAL_8250!=y && SERIAL_MUX!=y && !SERIAL_ROCKETPORT && !SERIAL_SUNCORE && !V850E_UART && (SERIAL_AMBA=m || SERIAL_CLPS711X=m || SERIAL_21285=m || SERIAL_8250=m || SERIAL_MUX=m || SERIAL98=m)
-+	default y if SERIAL_AMBA=y || SERIAL_CLPS711X=y || SERIAL_21285=y || SERIAL_SA1100 || SERIAL_ANAKIN || SERIAL_UART00 || SERIAL_8250=y || SERIAL_MUX=y || SERIAL_ROCKETPORT || SERIAL_SUNCORE || V850E_UART || SERIAL98=y
- 
- config SERIAL_CORE_CONSOLE
- 	bool
--	depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE
-+	depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_UART_CONSOLE || SERIAL98_CONSOLE
- 	default y
- 
- config SERIAL_68328
---- linux-2.6.0-test1/drivers/serial/Makefile	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/serial/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -29,5 +29,5 @@ obj-$(CONFIG_SERIAL_MUX) += mux.o
- obj-$(CONFIG_SERIAL_68328) += 68328serial.o
- obj-$(CONFIG_SERIAL_68360) += 68360serial.o
- obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
--obj-$(CONFIG_V850E_NB85E_UART) += nb85e_uart.o
-+obj-$(CONFIG_V850E_UART) += v850e_uart.o
- obj-$(CONFIG_SERIAL98) += serial98.o
---- linux-2.6.0-test1/drivers/serial/nb85e_uart.c	2003-06-14 12:18:30.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,610 +0,0 @@
--/*
-- * drivers/serial/nb85e_uart.c -- Serial I/O using V850E/NB85E on-chip UART
-- *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/module.h>
--#include <linux/console.h>
--#include <linux/tty.h>
--#include <linux/tty_flip.h>
--#include <linux/serial.h>
--#include <linux/serial_core.h>
--
--#include <asm/nb85e_uart.h>
--#include <asm/nb85e_utils.h>
--
--/* Initial UART state.  This may be overridden by machine-dependent headers. */
--#ifndef NB85E_UART_INIT_BAUD
--#define NB85E_UART_INIT_BAUD	115200
--#endif
--#ifndef NB85E_UART_INIT_CFLAGS
--#define NB85E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
--#endif
--
--/* XXX This should be in a header file.  */
--#define NB85E_UART_BRGC_MIN	8
--
--/* A string used for prefixing printed descriptions; since the same UART
--   macro is actually used on other chips than the V850E/NB85E.  This must
--   be a constant string.  */
--#ifndef NB85E_UART_CHIP_NAME
--#define NB85E_UART_CHIP_NAME "V850E/NB85E"
--#endif
--
--
--/* Helper functions for doing baud-rate/frequency calculations.  */
--
--/* Calculate the minimum value for CKSR on this processor.  */
--static inline unsigned cksr_min (void)
--{
--	int min = 0;
--	unsigned freq = NB85E_UART_BASE_FREQ;
--	while (freq > NB85E_UART_CKSR_MAX_FREQ) {
--		freq >>= 1;
--		min++;
--	}
--	return min;
--}
--
--/* Minimum baud rate possible.  */
--#define min_baud() \
--   ((NB85E_UART_BASE_FREQ >> NB85E_UART_CKSR_MAX) / (2 * 255) + 1)
--
--/* Maximum baud rate possible.  The error is quite high at max, though.  */
--#define max_baud() \
--   ((NB85E_UART_BASE_FREQ >> cksr_min()) / (2 * NB85E_UART_BRGC_MIN))
--
--
--/* Low-level UART functions.  */
--
--/* These masks define which control bits affect TX/RX modes, respectively.  */
--#define RX_BITS \
--  (NB85E_UART_ASIM_PS_MASK | NB85E_UART_ASIM_CL_8 | NB85E_UART_ASIM_ISRM)
--#define TX_BITS \
--  (NB85E_UART_ASIM_PS_MASK | NB85E_UART_ASIM_CL_8 | NB85E_UART_ASIM_SL_2)
--
--/* The UART require various delays after writing control registers.  */
--static inline void nb85e_uart_delay (unsigned cycles)
--{
--	/* The loop takes 2 insns, so loop CYCLES / 2 times.  */
--	register unsigned count = cycles >> 1;
--	while (--count != 0)
--		/* nothing */;
--}
--
--/* Configure and turn on uart channel CHAN, using the termios `control
--   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
--void nb85e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
--{
--	int flags;
--	unsigned new_config = 0; /* What we'll write to the control reg. */
--	unsigned new_clk_divlog2; /* New baud-rate generate clock divider. */
--	unsigned new_brgen_count; /* New counter max for baud-rate generator.*/
--	/* These are the current values corresponding to the above.  */
--	unsigned old_config, old_clk_divlog2, old_brgen_count;
--
--	/* Calculate new baud-rate generator config values.  */
--
--	/* Calculate the log2 clock divider and baud-rate counter values
--	   (note that the UART divides the resulting clock by 2, so
--	   multiply BAUD by 2 here to compensate).  */
--	calc_counter_params (NB85E_UART_BASE_FREQ, baud * 2,
--			     cksr_min(), NB85E_UART_CKSR_MAX, 8/*bits*/,
--			     &new_clk_divlog2, &new_brgen_count);
--
--	/* Figure out new configuration of control register.  */
--	if (cflags & CSTOPB)
--		/* Number of stop bits, 1 or 2.  */
--		new_config |= NB85E_UART_ASIM_SL_2;
--	if ((cflags & CSIZE) == CS8)
--		/* Number of data bits, 7 or 8.  */
--		new_config |= NB85E_UART_ASIM_CL_8;
--	if (! (cflags & PARENB))
--		/* No parity check/generation.  */
--		new_config |= NB85E_UART_ASIM_PS_NONE;
--	else if (cflags & PARODD)
--		/* Odd parity check/generation.  */
--		new_config |= NB85E_UART_ASIM_PS_ODD;
--	else
--		/* Even parity check/generation.  */
--		new_config |= NB85E_UART_ASIM_PS_EVEN;
--	if (cflags & CREAD)
--		/* Reading enabled.  */
--		new_config |= NB85E_UART_ASIM_RXE;
--
--	new_config |= NB85E_UART_ASIM_TXE; /* Writing is always enabled.  */
--	new_config |= NB85E_UART_ASIM_CAE;
--	new_config |= NB85E_UART_ASIM_ISRM; /* Errors generate a read-irq.  */
--
--	/* Disable interrupts while we're twiddling the hardware.  */
--	local_irq_save (flags);
--
--#ifdef NB85E_UART_PRE_CONFIGURE
--	NB85E_UART_PRE_CONFIGURE (chan, cflags, baud);
--#endif
--
--	old_config = NB85E_UART_ASIM (chan);
--	old_clk_divlog2 = NB85E_UART_CKSR (chan);
--	old_brgen_count = NB85E_UART_BRGC (chan);
--
--	if (new_clk_divlog2 != old_clk_divlog2
--	    || new_brgen_count != old_brgen_count)
--	{
--		/* The baud rate has changed.  First, disable the UART.  */
--		NB85E_UART_ASIM (chan) = 0;
--		old_config = 0;
--		/* Reprogram the baud-rate generator.  */
--		NB85E_UART_CKSR (chan) = new_clk_divlog2;
--		NB85E_UART_BRGC (chan) = new_brgen_count;
--	}
--
--	if (! (old_config & NB85E_UART_ASIM_CAE)) {
--		/* If we are enabling the uart for the first time, start
--		   by turning on the enable bit, which must be done
--		   before turning on any other bits.  */
--		NB85E_UART_ASIM (chan) = NB85E_UART_ASIM_CAE;
--		/* Enabling the uart also resets it.  */
--		old_config = NB85E_UART_ASIM_CAE;
--	}
--
--	if (new_config != old_config) {
--		/* Which of the TXE/RXE bits we'll temporarily turn off
--		   before changing other control bits.  */
--		unsigned temp_disable = 0;
--		/* Which of the TXE/RXE bits will be enabled.  */
--		unsigned enable = 0;
--		unsigned changed_bits = new_config ^ old_config;
--
--		/* Which of RX/TX will be enabled in the new configuration.  */
--		if (new_config & RX_BITS)
--			enable |= (new_config & NB85E_UART_ASIM_RXE);
--		if (new_config & TX_BITS)
--			enable |= (new_config & NB85E_UART_ASIM_TXE);
--
--		/* Figure out which of RX/TX needs to be disabled; note
--		   that this will only happen if they're not already
--		   disabled.  */
--		if (changed_bits & RX_BITS)
--			temp_disable |= (old_config & NB85E_UART_ASIM_RXE);
--		if (changed_bits & TX_BITS)
--			temp_disable |= (old_config & NB85E_UART_ASIM_TXE);
--
--		/* We have to turn off RX and/or TX mode before changing
--		   any associated control bits.  */
--		if (temp_disable)
--			NB85E_UART_ASIM (chan) = old_config & ~temp_disable;
--
--		/* Write the new control bits, while RX/TX are disabled. */ 
--		if (changed_bits & ~enable)
--			NB85E_UART_ASIM (chan) = new_config & ~enable;
--
--		/* The UART may not be reset properly unless we
--		   wait at least 2 `basic-clocks' until turning
--		   on the TXE/RXE bits again.  A `basic clock'
--		   is the clock used by the baud-rate generator, i.e.,
--		   the cpu clock divided by the 2^new_clk_divlog2.  */
--		nb85e_uart_delay (1 << (new_clk_divlog2 + 1));
--
--		/* Write the final version, with enable bits turned on.  */
--		NB85E_UART_ASIM (chan) = new_config;
--	}
--
--	local_irq_restore (flags);
--}
--
--
--/*  Low-level console. */
--
--#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
--
--static void nb85e_uart_cons_write (struct console *co,
--				   const char *s, unsigned count)
--{
--	if (count > 0) {
--		unsigned chan = co->index;
--		unsigned irq = IRQ_INTST (chan);
--		int irq_was_enabled, irq_was_pending, flags;
--
--		/* We don't want to get `transmission completed' (INTST)
--		   interrupts, since we're busy-waiting, so we disable
--		   them while sending (we don't disable interrupts
--		   entirely because sending over a serial line is really
--		   slow).  We save the status of INTST and restore it
--		   when we're done so that using printk doesn't
--		   interfere with normal serial transmission (other than
--		   interleaving the output, of course!).  This should
--		   work correctly even if this function is interrupted
--		   and the interrupt printks something.  */
--
--		/* Disable interrupts while fiddling with INTST.  */
--		local_irq_save (flags);
--		/* Get current INTST status.  */
--		irq_was_enabled = nb85e_intc_irq_enabled (irq);
--		irq_was_pending = nb85e_intc_irq_pending (irq);
--		/* Disable INTST if necessary.  */
--		if (irq_was_enabled)
--			nb85e_intc_disable_irq (irq);
--		/* Turn interrupts back on.  */
--		local_irq_restore (flags);
--
--		/* Send characters.  */
--		while (count > 0) {
--			int ch = *s++;
--
--			if (ch == '\n') {
--				/* We don't have the benefit of a tty
--				   driver, so translate NL into CR LF.  */
--				nb85e_uart_wait_for_xmit_ok (chan);
--				nb85e_uart_putc (chan, '\r');
--			}
--
--			nb85e_uart_wait_for_xmit_ok (chan);
--			nb85e_uart_putc (chan, ch);
--
--			count--;
--		}
--
--		/* Restore saved INTST status.  */
--		if (irq_was_enabled) {
--			/* Wait for the last character we sent to be
--			   completely transmitted (as we'll get an INTST
--			   interrupt at that point).  */
--			nb85e_uart_wait_for_xmit_done (chan);
--			/* Clear pending interrupts received due
--			   to our transmission, unless there was already
--			   one pending, in which case we want the
--			   handler to be called.  */
--			if (! irq_was_pending)
--				nb85e_intc_clear_pending_irq (irq);
--			/* ... and then turn back on handling.  */
--			nb85e_intc_enable_irq (irq);
--		}
--	}
--}
--
--extern struct uart_driver nb85e_uart_driver;
--static struct console nb85e_uart_cons =
--{
--    .name	= "ttyS",
--    .write	= nb85e_uart_cons_write,
--    .device	= uart_console_device,
--    .flags	= CON_PRINTBUFFER,
--    .cflag	= NB85E_UART_INIT_CFLAGS,
--    .index	= -1,
--    .data	= &nb85e_uart_driver,
--};
--
--void nb85e_uart_cons_init (unsigned chan)
--{
--	nb85e_uart_configure (chan, NB85E_UART_INIT_CFLAGS,
--			      NB85E_UART_INIT_BAUD);
--	nb85e_uart_cons.index = chan;
--	register_console (&nb85e_uart_cons);
--	printk ("Console: %s on-chip UART channel %d\n",
--		NB85E_UART_CHIP_NAME, chan);
--}
--
--#define NB85E_UART_CONSOLE &nb85e_uart_cons
--
--#else /* !CONFIG_V850E_NB85E_UART_CONSOLE */
--#define NB85E_UART_CONSOLE 0
--#endif /* CONFIG_V850E_NB85E_UART_CONSOLE */
--
--/* TX/RX interrupt handlers.  */
--
--static void nb85e_uart_stop_tx (struct uart_port *port, unsigned tty_stop);
--
--void nb85e_uart_tx (struct uart_port *port)
--{
--	struct circ_buf *xmit = &port->info->xmit;
--	int stopped = uart_tx_stopped (port);
--
--	if (nb85e_uart_xmit_ok (port->line)) {
--		int tx_ch;
--
--		if (port->x_char) {
--			tx_ch = port->x_char;
--			port->x_char = 0;
--		} else if (!uart_circ_empty (xmit) && !stopped) {
--			tx_ch = xmit->buf[xmit->tail];
--			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
--		} else
--			goto no_xmit;
--
--		nb85e_uart_putc (port->line, tx_ch);
--		port->icount.tx++;
--
--		if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
--			uart_write_wakeup (port);
--	}
--
-- no_xmit:
--	if (uart_circ_empty (xmit) || stopped)
--		nb85e_uart_stop_tx (port, stopped);
--}
--
--static void nb85e_uart_tx_irq (int irq, void *data, struct pt_regs *regs)
--{
--	struct uart_port *port = data;
--	nb85e_uart_tx (port);
--}
--
--static void nb85e_uart_rx_irq (int irq, void *data, struct pt_regs *regs)
--{
--	struct uart_port *port = data;
--	unsigned ch_stat = TTY_NORMAL;
--	unsigned ch = NB85E_UART_RXB (port->line);
--	unsigned err = NB85E_UART_ASIS (port->line);
--
--	if (err) {
--		if (err & NB85E_UART_ASIS_OVE) {
--			ch_stat = TTY_OVERRUN;
--			port->icount.overrun++;
--		} else if (err & NB85E_UART_ASIS_FE) {
--			ch_stat = TTY_FRAME;
--			port->icount.frame++;
--		} else if (err & NB85E_UART_ASIS_PE) {
--			ch_stat = TTY_PARITY;
--			port->icount.parity++;
--		}
--	}
--
--	port->icount.rx++;
--
--	tty_insert_flip_char (port->info->tty, ch, ch_stat);
--	tty_schedule_flip (port->info->tty);
--}
--
--/* Control functions for the serial framework.  */
--
--static void nb85e_uart_nop (struct uart_port *port) { }
--static int nb85e_uart_success (struct uart_port *port) { return 0; }
--
--static unsigned nb85e_uart_tx_empty (struct uart_port *port)
--{
--	return TIOCSER_TEMT;	/* Can't detect.  */
--}
--
--static void nb85e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
--{
--#ifdef NB85E_UART_SET_RTS
--	NB85E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
--#endif
--}
--
--static unsigned nb85e_uart_get_mctrl (struct uart_port *port)
--{
--	/* We don't support DCD or DSR, so consider them permanently active. */
--	int mctrl = TIOCM_CAR | TIOCM_DSR;
--
--	/* We may support CTS.  */
--#ifdef NB85E_UART_CTS
--	mctrl |= NB85E_UART_CTS(port->line) ? TIOCM_CTS : 0;
--#else
--	mctrl |= TIOCM_CTS;
--#endif
--
--	return mctrl;
--}
--
--static void nb85e_uart_start_tx (struct uart_port *port, unsigned tty_start)
--{
--	nb85e_intc_disable_irq (IRQ_INTST (port->line));
--	nb85e_uart_tx (port);
--	nb85e_intc_enable_irq (IRQ_INTST (port->line));
--}
--
--static void nb85e_uart_stop_tx (struct uart_port *port, unsigned tty_stop)
--{
--	nb85e_intc_disable_irq (IRQ_INTST (port->line));
--}
--
--static void nb85e_uart_start_rx (struct uart_port *port)
--{
--	nb85e_intc_enable_irq (IRQ_INTSR (port->line));
--}
--
--static void nb85e_uart_stop_rx (struct uart_port *port)
--{
--	nb85e_intc_disable_irq (IRQ_INTSR (port->line));
--}
--
--static void nb85e_uart_break_ctl (struct uart_port *port, int break_ctl)
--{
--	/* Umm, do this later.  */
--}
--
--static int nb85e_uart_startup (struct uart_port *port)
--{
--	int err;
--
--	/* Alloc RX irq.  */
--	err = request_irq (IRQ_INTSR (port->line), nb85e_uart_rx_irq,
--			   SA_INTERRUPT, "nb85e_uart", port);
--	if (err)
--		return err;
--
--	/* Alloc TX irq.  */
--	err = request_irq (IRQ_INTST (port->line), nb85e_uart_tx_irq,
--			   SA_INTERRUPT, "nb85e_uart", port);
--	if (err) {
--		free_irq (IRQ_INTSR (port->line), port);
--		return err;
--	}
--
--	nb85e_uart_start_rx (port);
--
--	return 0;
--}
--
--static void nb85e_uart_shutdown (struct uart_port *port)
--{
--	/* Disable port interrupts.  */
--	free_irq (IRQ_INTST (port->line), port);
--	free_irq (IRQ_INTSR (port->line), port);
--
--	/* Turn off xmit/recv enable bits.  */
--	NB85E_UART_ASIM (port->line)
--		&= ~(NB85E_UART_ASIM_TXE | NB85E_UART_ASIM_RXE);
--	/* Then reset the channel.  */
--	NB85E_UART_ASIM (port->line) = 0;
--}
--
--static void
--nb85e_uart_set_termios (struct uart_port *port, struct termios *termios,
--		        struct termios *old)
--{
--	unsigned cflags = termios->c_cflag;
--
--	/* Restrict flags to legal values.  */
--	if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
--		/* The new value of CSIZE is invalid, use the old value.  */
--		cflags = (cflags & ~CSIZE)
--			| (old ? (old->c_cflag & CSIZE) : CS8);
--
--	termios->c_cflag = cflags;
--
--	nb85e_uart_configure (port->line, cflags,
--			      uart_get_baud_rate (port, termios, old,
--						  min_baud(), max_baud()));
--}
--
--static const char *nb85e_uart_type (struct uart_port *port)
--{
--	return port->type == PORT_NB85E_UART ? "nb85e_uart" : 0;
--}
--
--static void nb85e_uart_config_port (struct uart_port *port, int flags)
--{
--	if (flags & UART_CONFIG_TYPE)
--		port->type = PORT_NB85E_UART;
--}
--
--static int
--nb85e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
--{
--	if (ser->type != PORT_UNKNOWN && ser->type != PORT_NB85E_UART)
--		return -EINVAL;
--	if (ser->irq != IRQ_INTST (port->line))
--		return -EINVAL;
--	return 0;
--}
--
--static struct uart_ops nb85e_uart_ops = {
--	.tx_empty	= nb85e_uart_tx_empty,
--	.get_mctrl	= nb85e_uart_get_mctrl,
--	.set_mctrl	= nb85e_uart_set_mctrl,
--	.start_tx	= nb85e_uart_start_tx,
--	.stop_tx	= nb85e_uart_stop_tx,
--	.stop_rx	= nb85e_uart_stop_rx,
--	.enable_ms	= nb85e_uart_nop,
--	.break_ctl	= nb85e_uart_break_ctl,
--	.startup	= nb85e_uart_startup,
--	.shutdown	= nb85e_uart_shutdown,
--	.set_termios	= nb85e_uart_set_termios,
--	.type		= nb85e_uart_type,
--	.release_port	= nb85e_uart_nop,
--	.request_port	= nb85e_uart_success,
--	.config_port	= nb85e_uart_config_port,
--	.verify_port	= nb85e_uart_verify_port,
--};
--
--/* Initialization and cleanup.  */
--
--static struct uart_driver nb85e_uart_driver = {
--	.owner			= THIS_MODULE,
--	.driver_name		= "nb85e_uart",
--	.devfs_name		= "tts/",
--	.dev_name		= "ttyS",
--	.major			= TTY_MAJOR,
--	.minor			= NB85E_UART_MINOR_BASE,
--	.nr			= NB85E_UART_NUM_CHANNELS,
--	.cons			= NB85E_UART_CONSOLE,
--};
--
--
--static struct uart_port nb85e_uart_ports[NB85E_UART_NUM_CHANNELS];
--
--static int __init nb85e_uart_init (void)
--{
--	int rval;
--
--	printk (KERN_INFO "%s on-chip UART\n", NB85E_UART_CHIP_NAME);
--
--	rval = uart_register_driver (&nb85e_uart_driver);
--	if (rval == 0) {
--		unsigned chan;
--
--		for (chan = 0; chan < NB85E_UART_NUM_CHANNELS; chan++) {
--			struct uart_port *port = &nb85e_uart_ports[chan];
--			
--			memset (port, 0, sizeof *port);
--
--			port->ops = &nb85e_uart_ops;
--			port->line = chan;
--			port->iotype = SERIAL_IO_MEM;
--			port->flags = UPF_BOOT_AUTOCONF;
--
--			/* We actually use multiple IRQs, but the serial
--			   framework seems to mainly use this for
--			   informational purposes anyway.  Here we use the TX
--			   irq.  */
--			port->irq = IRQ_INTST (chan);
--
--			/* The serial framework doesn't really use these
--			   membase/mapbase fields for anything useful, but
--			   it requires that they be something non-zero to
--			   consider the port `valid', and also uses them
--			   for informational purposes.  */
--			port->membase = (void *)NB85E_UART_BASE_ADDR (chan);
--			port->mapbase = NB85E_UART_BASE_ADDR (chan);
--
--			/* The framework insists on knowing the uart's master
--			   clock freq, though it doesn't seem to do anything
--			   useful for us with it.  We must make it at least
--			   higher than (the maximum baud rate * 16), otherwise
--			   the framework will puke during its internal
--			   calculations, and force the baud rate to be 9600.
--			   To be accurate though, just repeat the calculation
--			   we use when actually setting the speed.
--
--			   The `* 8' means `* 16 / 2':  16 to account for for
--			   the serial framework's built-in bias, and 2 because
--			   there's an additional / 2 in the hardware.  */
--			port->uartclk =
--				(NB85E_UART_BASE_FREQ >> cksr_min()) * 8;
--
--			uart_add_one_port (&nb85e_uart_driver, port);
--		}
--	}
--
--	return rval;
--}
--
--static void __exit nb85e_uart_exit (void)
--{
--	unsigned chan;
--
--	for (chan = 0; chan < NB85E_UART_NUM_CHANNELS; chan++)
--		uart_remove_one_port (&nb85e_uart_driver,
--				      &nb85e_uart_ports[chan]);
--
--	uart_unregister_driver (&nb85e_uart_driver);
--}
--
--module_init (nb85e_uart_init);
--module_exit (nb85e_uart_exit);
--
--MODULE_AUTHOR ("Miles Bader");
--MODULE_DESCRIPTION ("NEC " NB85E_UART_CHIP_NAME " on-chip UART");
--MODULE_LICENSE ("GPL");
---- linux-2.6.0-test1/drivers/serial/sunsu.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/serial/sunsu.c	2003-07-19 17:03:50.000000000 -0700
-@@ -102,6 +102,7 @@ struct uart_sunsu_port {
- 	int			l1_down;
- #ifdef CONFIG_SERIO
- 	struct serio		serio;
-+	int			serio_open;
- #endif
- };
- 
-@@ -1021,12 +1022,13 @@ static int sunsu_serio_write(struct seri
- 
- static int sunsu_serio_open(struct serio *serio)
- {
-+	struct uart_sunsu_port *up = serio->driver;
- 	unsigned long flags;
- 	int ret;
- 
- 	spin_lock_irqsave(&sunsu_serio_lock, flags);
--	if (serio->private == NULL) {
--		serio->private = (void *) -1L;
-+	if (!up->serio_open) {
-+		up->serio_open = 1;
- 		ret = 0;
- 	} else
- 		ret = -EBUSY;
-@@ -1037,10 +1039,11 @@ static int sunsu_serio_open(struct serio
- 
- static void sunsu_serio_close(struct serio *serio)
- {
-+	struct uart_sunsu_port *up = serio->driver;
- 	unsigned long flags;
- 
- 	spin_lock_irqsave(&sunsu_serio_lock, flags);
--	serio->private = NULL;
-+	up->serio_open = 0;
- 	spin_unlock_irqrestore(&sunsu_serio_lock, flags);
- }
- 
---- linux-2.6.0-test1/drivers/serial/sunzilog.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/serial/sunzilog.c	2003-07-19 17:03:50.000000000 -0700
-@@ -112,6 +112,7 @@ struct uart_sunzilog_port {
- 
- #ifdef CONFIG_SERIO
- 	struct serio			serio;
-+	int				serio_open;
- #endif
- };
- 
-@@ -1311,12 +1312,13 @@ static int sunzilog_serio_write(struct s
- 
- static int sunzilog_serio_open(struct serio *serio)
- {
-+	struct uart_sunzilog_port *up = serio->driver;
- 	unsigned long flags;
- 	int ret;
- 
- 	spin_lock_irqsave(&sunzilog_serio_lock, flags);
--	if (serio->private == NULL) {
--		serio->private = (void *) -1L;
-+	if (!up->serio_open) {
-+		up->serio_open = 1;
- 		ret = 0;
- 	} else
- 		ret = -EBUSY;
-@@ -1327,10 +1329,11 @@ static int sunzilog_serio_open(struct se
- 
- static void sunzilog_serio_close(struct serio *serio)
- {
-+	struct uart_sunzilog_port *up = serio->driver;
- 	unsigned long flags;
- 
- 	spin_lock_irqsave(&sunzilog_serio_lock, flags);
--	serio->private = NULL;
-+	up->serio_open = 0;
- 	spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
- }
- 
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/serial/v850e_uart.c	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,549 @@
-+/*
-+ * drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* This driver supports both the original V850E UART interface (called
-+   merely `UART' in the docs) and the newer `UARTB' interface, which is
-+   roughly a superset of the first one.  The selection is made at
-+   configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
-+   presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
-+   can never have both.
-+
-+   The UARTB interface also has a 16-entry FIFO mode, which is not
-+   yet supported by this driver.  */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/console.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/serial.h>
-+#include <linux/serial_core.h>
-+
-+#include <asm/v850e_uart.h>
-+
-+/* Initial UART state.  This may be overridden by machine-dependent headers. */
-+#ifndef V850E_UART_INIT_BAUD
-+#define V850E_UART_INIT_BAUD	115200
-+#endif
-+#ifndef V850E_UART_INIT_CFLAGS
-+#define V850E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
-+#endif
-+
-+/* A string used for prefixing printed descriptions; since the same UART
-+   macro is actually used on other chips than the V850E.  This must be a
-+   constant string.  */
-+#ifndef V850E_UART_CHIP_NAME
-+#define V850E_UART_CHIP_NAME	"V850E"
-+#endif
-+
-+#define V850E_UART_MINOR_BASE	64	   /* First tty minor number */
-+
-+
-+/* Low-level UART functions.  */
-+
-+/* Configure and turn on uart channel CHAN, using the termios `control
-+   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
-+void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
-+{
-+	int flags;
-+	v850e_uart_speed_t old_speed;
-+	v850e_uart_config_t old_config;
-+	v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
-+	v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);
-+
-+	/* Disable interrupts while we're twiddling the hardware.  */
-+	local_irq_save (flags);
-+
-+#ifdef V850E_UART_PRE_CONFIGURE
-+	V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
-+#endif
-+
-+	old_config = V850E_UART_CONFIG (chan);
-+	old_speed = v850e_uart_speed (chan);
-+
-+	if (! v850e_uart_speed_eq (old_speed, new_speed)) {
-+		/* The baud rate has changed.  First, disable the UART.  */
-+		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
-+		old_config = 0;	/* Force the uart to be re-initialized. */
-+
-+		/* Reprogram the baud-rate generator.  */
-+		v850e_uart_set_speed (chan, new_speed);
-+	}
-+
-+	if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
-+		/* If we are using the uart for the first time, start by
-+		   enabling it, which must be done before turning on any
-+		   other bits.  */
-+		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
-+		/* See the initial state.  */
-+		old_config = V850E_UART_CONFIG (chan);
-+	}
-+
-+	if (new_config != old_config) {
-+		/* Which of the TXE/RXE bits we'll temporarily turn off
-+		   before changing other control bits.  */
-+		unsigned temp_disable = 0;
-+		/* Which of the TXE/RXE bits will be enabled.  */
-+		unsigned enable = 0;
-+		unsigned changed_bits = new_config ^ old_config;
-+
-+		/* Which of RX/TX will be enabled in the new configuration.  */
-+		if (new_config & V850E_UART_CONFIG_RX_BITS)
-+			enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
-+		if (new_config & V850E_UART_CONFIG_TX_BITS)
-+			enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);
-+
-+		/* Figure out which of RX/TX needs to be disabled; note
-+		   that this will only happen if they're not already
-+		   disabled.  */
-+		if (changed_bits & V850E_UART_CONFIG_RX_BITS)
-+			temp_disable
-+				|= (old_config & V850E_UART_CONFIG_RX_ENABLE);
-+		if (changed_bits & V850E_UART_CONFIG_TX_BITS)
-+			temp_disable
-+				|= (old_config & V850E_UART_CONFIG_TX_ENABLE);
-+
-+		/* We have to turn off RX and/or TX mode before changing
-+		   any associated control bits.  */
-+		if (temp_disable)
-+			V850E_UART_CONFIG (chan) = old_config & ~temp_disable;
-+
-+		/* Write the new control bits, while RX/TX are disabled. */ 
-+		if (changed_bits & ~enable)
-+			V850E_UART_CONFIG (chan) = new_config & ~enable;
-+
-+		v850e_uart_config_delay (new_config, new_speed);
-+
-+		/* Write the final version, with enable bits turned on.  */
-+		V850E_UART_CONFIG (chan) = new_config;
-+	}
-+
-+	local_irq_restore (flags);
-+}
-+
-+
-+/*  Low-level console. */
-+
-+#ifdef CONFIG_V850E_UART_CONSOLE
-+
-+static void v850e_uart_cons_write (struct console *co,
-+				   const char *s, unsigned count)
-+{
-+	if (count > 0) {
-+		unsigned chan = co->index;
-+		unsigned irq = V850E_UART_TX_IRQ (chan);
-+		int irq_was_enabled, irq_was_pending, flags;
-+
-+		/* We don't want to get `transmission completed'
-+		   interrupts, since we're busy-waiting, so we disable them
-+		   while sending (we don't disable interrupts entirely
-+		   because sending over a serial line is really slow).  We
-+		   save the status of the tx interrupt and restore it when
-+		   we're done so that using printk doesn't interfere with
-+		   normal serial transmission (other than interleaving the
-+		   output, of course!).  This should work correctly even if
-+		   this function is interrupted and the interrupt printks
-+		   something.  */
-+
-+		/* Disable interrupts while fiddling with tx interrupt.  */
-+		local_irq_save (flags);
-+		/* Get current tx interrupt status.  */
-+		irq_was_enabled = v850e_intc_irq_enabled (irq);
-+		irq_was_pending = v850e_intc_irq_pending (irq);
-+		/* Disable tx interrupt if necessary.  */
-+		if (irq_was_enabled)
-+			v850e_intc_disable_irq (irq);
-+		/* Turn interrupts back on.  */
-+		local_irq_restore (flags);
-+
-+		/* Send characters.  */
-+		while (count > 0) {
-+			int ch = *s++;
-+
-+			if (ch == '\n') {
-+				/* We don't have the benefit of a tty
-+				   driver, so translate NL into CR LF.  */
-+				v850e_uart_wait_for_xmit_ok (chan);
-+				v850e_uart_putc (chan, '\r');
-+			}
-+
-+			v850e_uart_wait_for_xmit_ok (chan);
-+			v850e_uart_putc (chan, ch);
-+
-+			count--;
-+		}
-+
-+		/* Restore saved tx interrupt status.  */
-+		if (irq_was_enabled) {
-+			/* Wait for the last character we sent to be
-+			   completely transmitted (as we'll get an
-+			   interrupt interrupt at that point).  */
-+			v850e_uart_wait_for_xmit_done (chan);
-+			/* Clear pending interrupts received due
-+			   to our transmission, unless there was already
-+			   one pending, in which case we want the
-+			   handler to be called.  */
-+			if (! irq_was_pending)
-+				v850e_intc_clear_pending_irq (irq);
-+			/* ... and then turn back on handling.  */
-+			v850e_intc_enable_irq (irq);
-+		}
-+	}
-+}
-+
-+extern struct uart_driver v850e_uart_driver;
-+static struct console v850e_uart_cons =
-+{
-+    .name	= "ttyS",
-+    .write	= v850e_uart_cons_write,
-+    .device	= uart_console_device,
-+    .flags	= CON_PRINTBUFFER,
-+    .cflag	= V850E_UART_INIT_CFLAGS,
-+    .index	= -1,
-+    .data	= &v850e_uart_driver,
-+};
-+
-+void v850e_uart_cons_init (unsigned chan)
-+{
-+	v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
-+			      V850E_UART_INIT_BAUD);
-+	v850e_uart_cons.index = chan;
-+	register_console (&v850e_uart_cons);
-+	printk ("Console: %s on-chip UART channel %d\n",
-+		V850E_UART_CHIP_NAME, chan);
-+}
-+
-+/* This is what the init code actually calls.  */
-+static int v850e_uart_console_init (void)
-+{
-+	v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
-+	return 0;
-+}
-+console_initcall(v850e_uart_console_init);
-+
-+#define V850E_UART_CONSOLE &v850e_uart_cons
-+
-+#else /* !CONFIG_V850E_UART_CONSOLE */
-+#define V850E_UART_CONSOLE 0
-+#endif /* CONFIG_V850E_UART_CONSOLE */
-+
-+/* TX/RX interrupt handlers.  */
-+
-+static void v850e_uart_stop_tx (struct uart_port *port, unsigned tty_stop);
-+
-+void v850e_uart_tx (struct uart_port *port)
-+{
-+	struct circ_buf *xmit = &port->info->xmit;
-+	int stopped = uart_tx_stopped (port);
-+
-+	if (v850e_uart_xmit_ok (port->line)) {
-+		int tx_ch;
-+
-+		if (port->x_char) {
-+			tx_ch = port->x_char;
-+			port->x_char = 0;
-+		} else if (!uart_circ_empty (xmit) && !stopped) {
-+			tx_ch = xmit->buf[xmit->tail];
-+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+		} else
-+			goto no_xmit;
-+
-+		v850e_uart_putc (port->line, tx_ch);
-+		port->icount.tx++;
-+
-+		if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
-+			uart_write_wakeup (port);
-+	}
-+
-+ no_xmit:
-+	if (uart_circ_empty (xmit) || stopped)
-+		v850e_uart_stop_tx (port, stopped);
-+}
-+
-+static irqreturn_t v850e_uart_tx_irq(int irq, void *data, struct pt_regs *regs)
-+{
-+	struct uart_port *port = data;
-+	v850e_uart_tx (port);
-+	return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t v850e_uart_rx_irq(int irq, void *data, struct pt_regs *regs)
-+{
-+	struct uart_port *port = data;
-+	unsigned ch_stat = TTY_NORMAL;
-+	unsigned ch = v850e_uart_getc (port->line);
-+	unsigned err = v850e_uart_err (port->line);
-+
-+	if (err) {
-+		if (err & V850E_UART_ERR_OVERRUN) {
-+			ch_stat = TTY_OVERRUN;
-+			port->icount.overrun++;
-+		} else if (err & V850E_UART_ERR_FRAME) {
-+			ch_stat = TTY_FRAME;
-+			port->icount.frame++;
-+		} else if (err & V850E_UART_ERR_PARITY) {
-+			ch_stat = TTY_PARITY;
-+			port->icount.parity++;
-+		}
-+	}
-+
-+	port->icount.rx++;
-+
-+	tty_insert_flip_char (port->info->tty, ch, ch_stat);
-+	tty_schedule_flip (port->info->tty);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+
-+/* Control functions for the serial framework.  */
-+
-+static void v850e_uart_nop (struct uart_port *port) { }
-+static int v850e_uart_success (struct uart_port *port) { return 0; }
-+
-+static unsigned v850e_uart_tx_empty (struct uart_port *port)
-+{
-+	return TIOCSER_TEMT;	/* Can't detect.  */
-+}
-+
-+static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
-+{
-+#ifdef V850E_UART_SET_RTS
-+	V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
-+#endif
-+}
-+
-+static unsigned v850e_uart_get_mctrl (struct uart_port *port)
-+{
-+	/* We don't support DCD or DSR, so consider them permanently active. */
-+	int mctrl = TIOCM_CAR | TIOCM_DSR;
-+
-+	/* We may support CTS.  */
-+#ifdef V850E_UART_CTS
-+	mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
-+#else
-+	mctrl |= TIOCM_CTS;
-+#endif
-+
-+	return mctrl;
-+}
-+
-+static void v850e_uart_start_tx (struct uart_port *port, unsigned tty_start)
-+{
-+	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
-+	v850e_uart_tx (port);
-+	v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
-+}
-+
-+static void v850e_uart_stop_tx (struct uart_port *port, unsigned tty_stop)
-+{
-+	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
-+}
-+
-+static void v850e_uart_start_rx (struct uart_port *port)
-+{
-+	v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
-+}
-+
-+static void v850e_uart_stop_rx (struct uart_port *port)
-+{
-+	v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
-+}
-+
-+static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
-+{
-+	/* Umm, do this later.  */
-+}
-+
-+static int v850e_uart_startup (struct uart_port *port)
-+{
-+	int err;
-+
-+	/* Alloc RX irq.  */
-+	err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
-+			   SA_INTERRUPT, "v850e_uart", port);
-+	if (err)
-+		return err;
-+
-+	/* Alloc TX irq.  */
-+	err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
-+			   SA_INTERRUPT, "v850e_uart", port);
-+	if (err) {
-+		free_irq (V850E_UART_RX_IRQ (port->line), port);
-+		return err;
-+	}
-+
-+	v850e_uart_start_rx (port);
-+
-+	return 0;
-+}
-+
-+static void v850e_uart_shutdown (struct uart_port *port)
-+{
-+	/* Disable port interrupts.  */
-+	free_irq (V850E_UART_TX_IRQ (port->line), port);
-+	free_irq (V850E_UART_RX_IRQ (port->line), port);
-+
-+	/* Turn off xmit/recv enable bits.  */
-+	V850E_UART_CONFIG (port->line)
-+		&= ~(V850E_UART_CONFIG_TX_ENABLE
-+		     | V850E_UART_CONFIG_RX_ENABLE);
-+	/* Then reset the channel.  */
-+	V850E_UART_CONFIG (port->line) = 0;
-+}
-+
-+static void
-+v850e_uart_set_termios (struct uart_port *port, struct termios *termios,
-+		        struct termios *old)
-+{
-+	unsigned cflags = termios->c_cflag;
-+
-+	/* Restrict flags to legal values.  */
-+	if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
-+		/* The new value of CSIZE is invalid, use the old value.  */
-+		cflags = (cflags & ~CSIZE)
-+			| (old ? (old->c_cflag & CSIZE) : CS8);
-+
-+	termios->c_cflag = cflags;
-+
-+	v850e_uart_configure (port->line, cflags,
-+			      uart_get_baud_rate (port, termios, old,
-+						  v850e_uart_min_baud(),
-+						  v850e_uart_max_baud()));
-+}
-+
-+static const char *v850e_uart_type (struct uart_port *port)
-+{
-+	return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
-+}
-+
-+static void v850e_uart_config_port (struct uart_port *port, int flags)
-+{
-+	if (flags & UART_CONFIG_TYPE)
-+		port->type = PORT_V850E_UART;
-+}
-+
-+static int
-+v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
-+{
-+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
-+		return -EINVAL;
-+	if (ser->irq != V850E_UART_TX_IRQ (port->line))
-+		return -EINVAL;
-+	return 0;
-+}
-+
-+static struct uart_ops v850e_uart_ops = {
-+	.tx_empty	= v850e_uart_tx_empty,
-+	.get_mctrl	= v850e_uart_get_mctrl,
-+	.set_mctrl	= v850e_uart_set_mctrl,
-+	.start_tx	= v850e_uart_start_tx,
-+	.stop_tx	= v850e_uart_stop_tx,
-+	.stop_rx	= v850e_uart_stop_rx,
-+	.enable_ms	= v850e_uart_nop,
-+	.break_ctl	= v850e_uart_break_ctl,
-+	.startup	= v850e_uart_startup,
-+	.shutdown	= v850e_uart_shutdown,
-+	.set_termios	= v850e_uart_set_termios,
-+	.type		= v850e_uart_type,
-+	.release_port	= v850e_uart_nop,
-+	.request_port	= v850e_uart_success,
-+	.config_port	= v850e_uart_config_port,
-+	.verify_port	= v850e_uart_verify_port,
-+};
-+
-+/* Initialization and cleanup.  */
-+
-+static struct uart_driver v850e_uart_driver = {
-+	.owner			= THIS_MODULE,
-+	.driver_name		= "v850e_uart",
-+	.devfs_name		= "tts/",
-+	.dev_name		= "ttyS",
-+	.major			= TTY_MAJOR,
-+	.minor			= V850E_UART_MINOR_BASE,
-+	.nr			= V850E_UART_NUM_CHANNELS,
-+	.cons			= V850E_UART_CONSOLE,
-+};
-+
-+
-+static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];
-+
-+static int __init v850e_uart_init (void)
-+{
-+	int rval;
-+
-+	printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);
-+
-+	rval = uart_register_driver (&v850e_uart_driver);
-+	if (rval == 0) {
-+		unsigned chan;
-+
-+		for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
-+			struct uart_port *port = &v850e_uart_ports[chan];
-+			
-+			memset (port, 0, sizeof *port);
-+
-+			port->ops = &v850e_uart_ops;
-+			port->line = chan;
-+			port->iotype = SERIAL_IO_MEM;
-+			port->flags = UPF_BOOT_AUTOCONF;
-+
-+			/* We actually use multiple IRQs, but the serial
-+			   framework seems to mainly use this for
-+			   informational purposes anyway.  Here we use the TX
-+			   irq.  */
-+			port->irq = V850E_UART_TX_IRQ (chan);
-+
-+			/* The serial framework doesn't really use these
-+			   membase/mapbase fields for anything useful, but
-+			   it requires that they be something non-zero to
-+			   consider the port `valid', and also uses them
-+			   for informational purposes.  */
-+			port->membase = (void *)V850E_UART_BASE_ADDR (chan);
-+			port->mapbase = V850E_UART_BASE_ADDR (chan);
-+
-+			/* The framework insists on knowing the uart's master
-+			   clock freq, though it doesn't seem to do anything
-+			   useful for us with it.  We must make it at least
-+			   higher than (the maximum baud rate * 16), otherwise
-+			   the framework will puke during its internal
-+			   calculations, and force the baud rate to be 9600.
-+			   To be accurate though, just repeat the calculation
-+			   we use when actually setting the speed.  */
-+			port->uartclk = v850e_uart_max_clock() * 16;
-+
-+			uart_add_one_port (&v850e_uart_driver, port);
-+		}
-+	}
-+
-+	return rval;
-+}
-+
-+static void __exit v850e_uart_exit (void)
-+{
-+	unsigned chan;
-+
-+	for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
-+		uart_remove_one_port (&v850e_uart_driver,
-+				      &v850e_uart_ports[chan]);
-+
-+	uart_unregister_driver (&v850e_uart_driver);
-+}
-+
-+module_init (v850e_uart_init);
-+module_exit (v850e_uart_exit);
-+
-+MODULE_AUTHOR ("Miles Bader");
-+MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
-+MODULE_LICENSE ("GPL");
---- linux-2.6.0-test1/drivers/telephony/ixj.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/telephony/ixj.c	2003-07-19 17:03:50.000000000 -0700
-@@ -23,6 +23,7 @@
-  * Fixes:           David Huggins-Daines, <dhd@cepstral.com>
-  *                  Fabio Ferrari, <fabio.ferrari@digitro.com.br>
-  *                  Artis Kugevics, <artis@mt.lv>
-+ *                  Daniele Bellucci, <bellucda@tiscali.it>
-  *
-  * More information about the hardware related to this driver can be found  
-  * at our website:    http://www.quicknet.net
-@@ -45,6 +46,10 @@ static char ixj_c_revision[] = "$Revisio
- 
- /*
-  * $Log: 2.6.0-test1-mm2.patch,v $
-  * Revision 1.1.2.2  2003/07/22 07:20:21  braam
-  * - these should apply, but they don't quite compile (something with netdump)
-  *
-+ *
-+ * Revision 4.8  2003/07/09 19:39:00  Daniele Bellucci
-+ * Audit some copy_*_user and minor cleanup.
-+ *
-  * Revision 4.7  2001/08/13 06:19:33  craigs
-  * Added additional changes from Alan Cox and John Anderson for
-  * 2.2 to 2.4 cleanup and bounds checking
-@@ -363,12 +368,9 @@ static IXJ ixj[IXJMAX];
- static IXJ *ixj_alloc(void)
- {
- 	int cnt;
--	for(cnt=0; cnt<IXJMAX; cnt++)
--	{
-+	for(cnt=0; cnt<IXJMAX; cnt++) {
- 		if(!ixj[cnt].DSPbase)
--		{
- 			return &ixj[cnt];
--		}
- 	}
- 	return NULL;
- }
-@@ -6260,9 +6262,11 @@ static int ixj_ioctl(struct inode *inode
- 		break;
- 	case IXJCTL_CIDCW:
- 		if(arg) {
--			copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
--		}
--		else {
-+			if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
-+				retval = -EFAULT;
-+				break;
-+			}
-+		} else {
- 			memset(&j->cid_send, 0, sizeof(PHONE_CID));
- 		}
- 		ixj_write_cidcw(j);
-@@ -6273,14 +6277,12 @@ static int ixj_ioctl(struct inode *inode
-                 /* Fall through */
-  	case PHONE_RING_START:
- 		if(arg) {
--			if(copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID)))
--			{
-+			if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
- 				retval = -EFAULT;
- 				break;
- 			}
- 			ixj_write_cid(j);
--		}
--		else {
-+		} else {
- 			memset(&j->cid_send, 0, sizeof(PHONE_CID));
- 		}
- 		ixj_ring_start(j);
-@@ -6696,7 +6698,8 @@ static int ixj_ioctl(struct inode *inode
- 	case IXJCTL_SET_FILTER_RAW:
- 		if (copy_from_user(&jfr, (char *) arg, sizeof(jfr))) 
- 			retval = -EFAULT;
--		retval = ixj_init_filter_raw(j, &jfr);
-+		else
-+			retval = ixj_init_filter_raw(j, &jfr);
- 		break;
- 	case IXJCTL_GET_FILTER_HIST:
- 		if(arg<0||arg>3)
-@@ -6705,8 +6708,10 @@ static int ixj_ioctl(struct inode *inode
- 			retval = j->filter_hist[arg];
- 		break;
- 	case IXJCTL_INIT_TONE:
--		copy_from_user(&ti, (char *) arg, sizeof(ti));
--		retval = ixj_init_tone(j, &ti);
-+		if (copy_from_user(&ti, (char *) arg, sizeof(ti)))
-+			retval = -EFAULT;
-+		else
-+			retval = ixj_init_tone(j, &ti);
- 		break;
- 	case IXJCTL_TONE_CADENCE:
- 		retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg);
-@@ -6715,8 +6720,10 @@ static int ixj_ioctl(struct inode *inode
- 		retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
- 		break;
- 	case IXJCTL_SIGCTL:
--		if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF)))
-+		if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF))) {
- 			retval = -EFAULT;
-+			break;
-+		}
- 		j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
- 		if(j->sigdef.event < 33) {
- 			raise = 1;
-@@ -7693,7 +7700,7 @@ MODULE_DESCRIPTION("Quicknet VoIP Teleph
- MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
- MODULE_LICENSE("GPL");
- 
--void ixj_exit(void)
-+static void __exit ixj_exit(void)
- {
-         cleanup();
- }
-@@ -7852,7 +7859,7 @@ int __init ixj_probe_pci(int *cnt)
- 	return probe;
- }
- 
--int __init ixj_init(void)
-+static int __init ixj_init(void)
- {
- 	int cnt = 0;
- 	int probe = 0;   
---- linux-2.6.0-test1/drivers/telephony/Kconfig	2003-06-14 12:18:00.000000000 -0700
-+++ 25/drivers/telephony/Kconfig	2003-07-19 17:03:50.000000000 -0700
-@@ -39,7 +39,7 @@ config PHONE_IXJ
- 
- config PHONE_IXJ_PCMCIA
- 	tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support"
--	depends on PHONE_IXJ
-+	depends on PHONE_IXJ && PCMCIA
- 	help
- 	  Say Y here to configure in PCMCIA service support for the Quicknet
- 	  cards manufactured by Quicknet Technologies, Inc.  This changes the
---- linux-2.6.0-test1/drivers/usb/class/bluetty.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/class/bluetty.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1320,7 +1320,8 @@ int usb_bluetooth_init(void)
- 
- 	bluetooth_tty_driver->owner = THIS_MODULE;
- 	bluetooth_tty_driver->driver_name = "usb-bluetooth";
--	bluetooth_tty_driver->name = "usb/ttub/";
-+	bluetooth_tty_driver->name = "ttyUB";
-+	bluetooth_tty_driver->devfs_name = "usb/ttub/";
- 	bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR;
- 	bluetooth_tty_driver->minor_start = 0;
- 	bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
---- linux-2.6.0-test1/drivers/usb/class/cdc-acm.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/class/cdc-acm.c	2003-07-19 17:03:50.000000000 -0700
-@@ -765,7 +765,8 @@ static int __init acm_init(void)
- 		return -ENOMEM;
- 	acm_tty_driver->owner = THIS_MODULE,
- 	acm_tty_driver->driver_name = "acm",
--	acm_tty_driver->name = "usb/acm/",
-+	acm_tty_driver->name = "ttyACM",
-+	acm_tty_driver->devfs_name = "usb/acm/",
- 	acm_tty_driver->major = ACM_TTY_MAJOR,
- 	acm_tty_driver->minor_start = 0,
- 	acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
---- linux-2.6.0-test1/drivers/usb/class/usblp.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/class/usblp.c	2003-07-19 17:03:50.000000000 -0700
-@@ -359,7 +359,6 @@ static int usblp_open(struct inode *inod
- 	file->private_data = usblp;
- 
- 	usblp->writeurb->transfer_buffer_length = 0;
--	usblp->writeurb->status = 0;
- 	usblp->wcomplete = 1; /* we begin writeable */
- 	usblp->rcomplete = 0;
- 
-@@ -833,22 +832,15 @@ static int usblp_probe(struct usb_interf
- 	init_waitqueue_head(&usblp->wait);
- 	usblp->ifnum = intf->altsetting->desc.bInterfaceNumber;
- 
--	retval = usb_register_dev(intf, &usblp_class);
--	if (retval) {
--		err("Not able to get a minor for this device.");
--		goto abort;
--	}
--	usblp->minor = intf->minor;
--
- 	usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
- 	if (!usblp->writeurb) {
- 		err("out of memory");
--		goto abort_minor;
-+		goto abort;
- 	}
- 	usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
- 	if (!usblp->readurb) {
- 		err("out of memory");
--		goto abort_minor;
-+		goto abort;
- 	}
- 
- 	/* Malloc device ID string buffer to the largest expected length,
-@@ -856,7 +848,7 @@ static int usblp_probe(struct usb_interf
- 	 * could change in length. */
- 	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
- 		err("out of memory for device_id_string");
--		goto abort_minor;
-+		goto abort;
- 	}
- 
- 	usblp->writebuf = usblp->readbuf = NULL;
-@@ -868,19 +860,19 @@ static int usblp_probe(struct usb_interf
- 	if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
- 				GFP_KERNEL, &usblp->writeurb->transfer_dma))) {
- 		err("out of memory for write buf");
--		goto abort_minor;
-+		goto abort;
- 	}
- 	if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
- 				GFP_KERNEL, &usblp->readurb->transfer_dma))) {
- 		err("out of memory for read buf");
--		goto abort_minor;
-+		goto abort;
- 	}
- 
- 	/* Allocate buffer for printer status */
- 	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
- 	if (!usblp->statusbuf) {
- 		err("out of memory for statusbuf");
--		goto abort_minor;
-+		goto abort;
- 	}
- 
- 	/* Lookup quirks for this printer. */
-@@ -894,12 +886,12 @@ static int usblp_probe(struct usb_interf
- 		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
- 			dev->descriptor.idVendor,
- 			dev->descriptor.idProduct);
--		goto abort_minor;
-+		goto abort;
- 	}
- 
- 	/* Setup the selected alternate setting and endpoints. */
- 	if (usblp_set_protocol(usblp, protocol) < 0)
--		goto abort_minor;
-+		goto abort;
- 
- 	/* Retrieve and store the device ID string. */
- 	usblp_cache_device_id_string(usblp);
-@@ -920,10 +912,17 @@ static int usblp_probe(struct usb_interf
- 
- 	usblp->present = 1;
- 
-+	retval = usb_register_dev(intf, &usblp_class);
-+	if (retval) {
-+		err("Not able to get a minor for this device.");
-+		goto abort_intfdata;
-+	}
-+	usblp->minor = intf->minor;
-+
- 	return 0;
- 
--abort_minor:
--	usb_deregister_dev(intf, &usblp_class);
-+abort_intfdata:
-+	usb_set_intfdata (intf, NULL);
- abort:
- 	if (usblp) {
- 		if (usblp->writebuf)
---- linux-2.6.0-test1/drivers/usb/core/file.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/drivers/usb/core/file.c	2003-07-19 17:06:13.000000000 -0700
-@@ -93,7 +93,7 @@ static ssize_t show_dev(struct class_dev
- {
- 	struct usb_interface *intf = class_dev_to_usb_interface(class_dev);
- 	dev_t dev = MKDEV(USB_MAJOR, intf->minor);
--	return sprintf(buf, "%04x\n", dev);
-+	return print_dev_t(buf, dev);
- }
- static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
- 
---- linux-2.6.0-test1/drivers/usb/core/hcd.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/core/hcd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1293,7 +1293,8 @@ rescan:
- 	}
- 
- 	/* then kill any current requests */
--	spin_lock_irqsave (&hcd_data_lock, flags);
-+	local_irq_save (flags);
-+	spin_lock (&hcd_data_lock);
- 	list_for_each_entry (urb, &dev->urb_list, urb_list) {
- 		int	tmp = urb->pipe;
- 
-@@ -1311,13 +1312,13 @@ rescan:
- 		if (urb->status != -EINPROGRESS)
- 			continue;
- 		usb_get_urb (urb);
--		spin_unlock_irqrestore (&hcd_data_lock, flags);
-+		spin_unlock (&hcd_data_lock);
- 
--		spin_lock_irqsave (&urb->lock, flags);
-+		spin_lock (&urb->lock);
- 		tmp = urb->status;
- 		if (tmp == -EINPROGRESS)
- 			urb->status = -ESHUTDOWN;
--		spin_unlock_irqrestore (&urb->lock, flags);
-+		spin_unlock (&urb->lock);
- 
- 		/* kick hcd unless it's already returning this */
- 		if (tmp == -EINPROGRESS) {
-@@ -1340,7 +1341,8 @@ rescan:
- 		/* list contents may have changed */
- 		goto rescan;
- 	}
--	spin_unlock_irqrestore (&hcd_data_lock, flags);
-+	spin_unlock (&hcd_data_lock);
-+	local_irq_restore (flags);
- 
- 	/* synchronize with the hardware, so old configuration state
- 	 * clears out immediately (and will be freed).
---- linux-2.6.0-test1/drivers/usb/core/hcd-pci.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/core/hcd-pci.c	2003-07-19 17:03:50.000000000 -0700
-@@ -81,7 +81,7 @@ int usb_hcd_pci_probe (struct pci_dev *d
- 	
-         if (!dev->irq) {
-         	err ("Found HC with no IRQ.  Check BIOS/PCI %s setup!",
--			dev->slot_name);
-+			pci_name(dev));
-    	        return -ENODEV;
-         }
- 	
-@@ -99,7 +99,7 @@ int usb_hcd_pci_probe (struct pci_dev *d
- 			retval = -EFAULT;
- clean_1:
- 			release_mem_region (resource, len);
--			err ("init %s fail, %d", dev->slot_name, retval);
-+			err ("init %s fail, %d", pci_name(dev), retval);
- 			return retval;
- 		}
- 
-@@ -136,7 +136,7 @@ clean_2:
- 			goto clean_1;
- 		} else {
- 			release_region (resource, len);
--			err ("init %s fail, %d", dev->slot_name, retval);
-+			err ("init %s fail, %d", pci_name(dev), retval);
- 			return retval;
- 		}
- 	}
-@@ -144,7 +144,7 @@ clean_2:
- 	hcd->driver = driver;
- 	hcd->description = driver->description;
- 	hcd->pdev = dev;
--	hcd->self.bus_name = dev->slot_name;
-+	hcd->self.bus_name = pci_name(dev);
- 	hcd->product_desc = dev->dev.name;
- 	hcd->self.controller = &dev->dev;
- 	hcd->controller = hcd->self.controller;
-@@ -279,6 +279,7 @@ EXPORT_SYMBOL (usb_hcd_pci_remove);
- /**
-  * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
-  * @dev: USB Host Controller being suspended
-+ * @state: state that the controller is going into
-  *
-  * Store this function in the HCD's struct pci_driver as suspend().
-  */
---- linux-2.6.0-test1/drivers/usb/core/usb.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/core/usb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -80,6 +80,23 @@ static struct device_driver usb_generic_
- 
- static int usb_generic_driver_data;
- 
-+/* deallocate hcd/hardware state ... and nuke all pending urbs */
-+static void nuke_urbs(struct usb_device *dev)
-+{
-+	void (*disable)(struct usb_device *, int);
-+	int i;
-+
-+	if (!dev || !dev->bus || !dev->bus->op || !dev->bus->op->disable)
-+		return;
-+	dbg("nuking urbs assigned to %s", dev->dev.bus_id);
-+
-+	disable = dev->bus->op->disable;
-+	for (i = 0; i < 15; i++) {
-+		disable(dev, i);
-+		disable(dev, USB_DIR_IN | i);
-+	}
-+}
-+
- /* needs to be called with BKL held */
- int usb_device_probe(struct device *dev)
- {
-@@ -116,6 +133,9 @@ int usb_device_remove(struct device *dev
- 
- 	down(&driver->serialize);
- 
-+	/* release all urbs for this device */
-+	nuke_urbs(interface_to_usbdev(intf));
-+
- 	if (intf->driver && intf->driver->disconnect)
- 		intf->driver->disconnect(intf);
- 
-@@ -896,6 +916,9 @@ void usb_disconnect(struct usb_device **
- 			usb_disconnect(child);
- 	}
- 
-+	/* deallocate hcd/hardware state ... and nuke all pending urbs */
-+	nuke_urbs(dev);
-+
- 	/* disconnect() drivers from interfaces (a key side effect) */
- 	dev_dbg (&dev->dev, "unregistering interfaces\n");
- 	if (dev->actconfig) {
-@@ -908,16 +931,6 @@ void usb_disconnect(struct usb_device **
- 		}
- 	}
- 
--	/* deallocate hcd/hardware state */
--	if (ops->disable) {
--		void	(*disable)(struct usb_device *, int) = ops->disable;
--
--		for (i = 0; i < 15; i++) {
--			disable (dev, i);
--			disable (dev, USB_DIR_IN | i);
--		}
--	}
--
- 	dev_dbg (&dev->dev, "unregistering device\n");
- 	/* Free the device number and remove the /proc/bus/usb entry */
- 	if (dev->devnum > 0) {
---- linux-2.6.0-test1/drivers/usb/gadget/ether.c	2003-06-14 12:18:35.000000000 -0700
-+++ 25/drivers/usb/gadget/ether.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,5 +1,5 @@
- /*
-- * ether.c -- CDC 1.1 Ethernet gadget driver
-+ * ether.c -- Ethernet gadget driver, with CDC and non-CDC options
-  *
-  * Copyright (C) 2003 David Brownell
-  *
-@@ -58,21 +58,23 @@
- /*-------------------------------------------------------------------------*/
- 
- /*
-- * "Communications Device Class" (CDC) Ethernet class driver
-+ * Ethernet gadget driver -- with CDC and non-CDC options
-  *
-  * CDC Ethernet is the standard USB solution for sending Ethernet frames
-  * using USB.  Real hardware tends to use the same framing protocol but look
-  * different for control features.  And Microsoft pushes their own approach
-  * (RNDIS) instead of the standard.
-+ *
-+ * There's some hardware that can't talk CDC.  We make that hardware
-+ * implement a "minimalist" vendor-agnostic CDC core:  same framing, but
-+ * link-level setup only requires activating the configuration.
-  */
- 
--#define DRIVER_DESC		"CDC Ethernet Gadget"
--#define DRIVER_VERSION		"29 April 2003"
-+#define DRIVER_DESC		"Ethernet Gadget"
-+#define DRIVER_VERSION		"Bastille Day 2003"
- 
- static const char shortname [] = "ether";
- static const char driver_desc [] = DRIVER_DESC;
--static const char control_name [] = "Communications Control";
--static const char data_name [] = "CDC Ethernet Data";
- 
- #define MIN_PACKET	sizeof(struct ethhdr)
- #define	MAX_PACKET	ETH_DATA_LEN	/* biggest packet we'll rx/tx */
-@@ -92,8 +94,7 @@ struct eth_dev {
- 	const struct usb_endpoint_descriptor
- 				*in, *out, *status;
- 
--	struct semaphore	mutex;
--	struct net_device	net;
-+	struct net_device	*net;
- 	struct net_device_stats	stats;
- 	atomic_t		tx_qlen;
- 
-@@ -112,7 +113,7 @@ struct eth_dev {
- 
- static unsigned qmult = 4;
- 
--#define HS_FACTOR	15
-+#define HS_FACTOR	5
- 
- #define qlen(gadget) \
- 	(qmult*((gadget->speed == USB_SPEED_HIGH) ? HS_FACTOR : 1))
-@@ -128,7 +129,7 @@ module_param (qmult, uint, S_IRUGO|S_IWU
- 
- /* Thanks to NetChip Technologies for donating this product ID.
-  *
-- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
-+ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
-  * Instead:  allocate your own, using normal USB-IF procedures.
-  */
- #define DRIVER_VENDOR_NUM	0x0525		/* NetChip */
-@@ -158,6 +159,11 @@ module_param (qmult, uint, S_IRUGO|S_IWU
-  * for some reason doesn't handle full speed bulk maxpacket of 64.
-  */
- 
-+#define DEV_CONFIG_VALUE	3	/* some hardware cares */
-+
-+/* #undef on hardware that can't implement CDC */
-+#define	DEV_CONFIG_CDC
-+
- /*
-  * NetChip 2280, PCI based.
-  *
-@@ -172,7 +178,7 @@ module_param (qmult, uint, S_IRUGO|S_IWU
- #define DRIVER_VERSION_NUM	0x0101
- #define EP0_MAXPACKET		64
- static const char EP_OUT_NAME [] = "ep-a";
--#define EP_OUT_NUM	2
-+#define EP_OUT_NUM	1
- static const char EP_IN_NAME [] = "ep-b";
- #define EP_IN_NUM	2
- static const char EP_STATUS_NAME [] = "ep-f";
-@@ -194,22 +200,21 @@ static inline void hw_optimize (struct u
- #endif
- 
- /*
-- * PXA-250 UDC:  widely used in second gen Linux-capable PDAs.
-+ * PXA-2xx UDC:  widely used in second gen Linux-capable ARM PDAs
-+ * and other products.
-  *
-- * no limitations except from set_interface: docs say "no" to a third
-- * interface. and the interrupt-only endpoints don't toggle, so we'll
-- * just use a bulk-capable one instead.
-+ * multiple interfaces (or altsettings) aren't usable.  so this hardware
-+ * can't implement CDC, which needs both capabilities.
-  */
--#ifdef	CONFIG_USB_ETH_PXA250
--#define CHIP			"pxa250"
-+#ifdef	CONFIG_USB_ETH_PXA2XX
-+#undef	DEV_CONFIG_CDC
-+#define CHIP			"pxa2xx"
- #define DRIVER_VERSION_NUM	0x0103
- #define EP0_MAXPACKET		16
--static const char EP_OUT_NAME [] = "ep12out-bulk";
--#define EP_OUT_NUM	12
--static const char EP_IN_NAME [] = "ep11in-bulk";
--#define EP_IN_NUM	11
--static const char EP_STATUS_NAME [] = "ep6in-bulk";
--#define EP_STATUS_NUM	6
-+static const char EP_OUT_NAME [] = "ep2out-bulk";
-+#define EP_OUT_NUM	2
-+static const char EP_IN_NAME [] = "ep1in-bulk";
-+#define EP_IN_NUM	1
- /* doesn't support bus-powered operation */
- #define SELFPOWER USB_CONFIG_ATT_SELFPOWER
- /* supports remote wakeup, but this driver doesn't */
-@@ -247,6 +252,29 @@ static const char EP_IN_NAME [] = "ep2in
- #	error Configure some USB peripheral controller driver!
- #endif
- 
-+/* We normally expect hardware that can talk CDC.  That involves
-+ * using multiple interfaces and altsettings, and maybe a status
-+ * interrupt.  Driver binding to be done according to USB-IF class,
-+ * though you can use different VENDOR and PRODUCT numbers if you
-+ * want (and they're officially assigned).
-+ * 
-+ * For hardware that can't talk CDC, we use the same vendor ID that
-+ * ARM Linux has used for ethernet-over-usb, both with sa1100 and
-+ * with pxa250.  We're protocol-compatible, if the host-side drivers
-+ * use the endpoint descriptors.  DRIVER_VERSION_NUM is nonzero, so
-+ * drivers that need to hard-wire endpoint numbers have a hook.
-+ */
-+#ifdef	DEV_CONFIG_CDC
-+#define	DEV_CONFIG_CLASS	USB_CLASS_COMM
-+#else	
-+#define	DEV_CONFIG_CLASS	USB_CLASS_VENDOR_SPEC
-+#undef	EP_STATUS_NUM
-+#undef	DRIVER_VENDOR_NUM
-+#undef	DRIVER_PRODUCT_NUM
-+#define	DRIVER_VENDOR_NUM	0x049f
-+#define	DRIVER_PRODUCT_NUM	0x505a
-+#endif /* CONFIG_CDC_ETHER */
-+
- /* power usage is config specific.
-  * hardware that supports remote wakeup defaults to disabling it.
-  */
-@@ -274,7 +302,8 @@ static const char EP_IN_NAME [] = "ep2in
- /*-------------------------------------------------------------------------*/
- 
- #define xprintk(d,level,fmt,args...) \
--	dev_printk(level , &(d)->gadget->dev , fmt , ## args)
-+	printk(level "%s %s: " fmt , shortname , (d)->gadget->dev.bus_id , \
-+		## args)
- 
- #ifdef DEBUG
- #undef DEBUG
-@@ -309,7 +338,7 @@ static const char EP_IN_NAME [] = "ep2in
- /*
-  * DESCRIPTORS ... most are static, but strings and (full) configuration
-  * descriptors are built on demand.  Notice how most of the cdc descriptors
-- * add no value to simple (typical) configurations.
-+ * aren't needed in the "minimalist" mode.
-  */
- 
- #define STRING_MANUFACTURER		1
-@@ -323,15 +352,14 @@ static const char EP_IN_NAME [] = "ep2in
- /*
-  * This device advertises one configuration.
-  */
--#define	CONFIG_CDC_ETHER	3
--
- static const struct usb_device_descriptor
- device_desc = {
- 	.bLength =		sizeof device_desc,
- 	.bDescriptorType =	USB_DT_DEVICE,
- 
- 	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
--	.bDeviceClass =		USB_CLASS_COMM,
-+
-+	.bDeviceClass =		DEV_CONFIG_CLASS,
- 	.bDeviceSubClass =	0,
- 	.bDeviceProtocol =	0,
- 	.bMaxPacketSize0 =	EP0_MAXPACKET,
-@@ -350,13 +378,26 @@ eth_config = {
- 	.bDescriptorType =	USB_DT_CONFIG,
- 
- 	/* compute wTotalLength on the fly */
-+#ifdef	DEV_CONFIG_CDC
- 	.bNumInterfaces =	2,
--	.bConfigurationValue =	CONFIG_CDC_ETHER,
-+#else
-+	.bNumInterfaces =	1,
-+#endif
-+	.bConfigurationValue =	DEV_CONFIG_VALUE,
- 	.iConfiguration =	STRING_PRODUCT,
- 	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP,
- 	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
- };
- 
-+#ifdef	DEV_CONFIG_CDC
-+
-+/*
-+ * Compared to the "minimalist" non-CDC model, the CDC model adds
-+ * three class descriptors, two interface descrioptors, and a status
-+ * endpoint.  Both have a "data" interface and two bulk endpoints.
-+ * There are also differences in how control requests are handled.
-+ */
-+
- /* master comm interface optionally has a status notification endpoint */
- 
- static const struct usb_interface_descriptor
-@@ -446,7 +487,7 @@ static const struct ether_desc ether_des
-  * some drivers (like current Linux cdc-ether!) "need" it to exist even
-  * if they ignore the connect/disconnect notifications that real aether
-  * can provide.  more advanced cdc configurations might want to support
-- * encapsulated commands.
-+ * encapsulated commands (vendor-specific, using control-OUT).
-  */
-  
- #define LOG2_STATUS_INTERVAL_MSEC	6
-@@ -494,6 +535,29 @@ data_intf = {
- 	.bInterfaceProtocol =	0,
- 	.iInterface =		STRING_DATA,
- };
-+#else
-+
-+/*
-+ * "Minimalist" non-CDC option is a simple vendor-neutral model that most
-+ * full speed controllers can handle:  one interface, two bulk endpoints.
-+ */
-+
-+static const struct usb_interface_descriptor
-+data_intf = {
-+	.bLength =		sizeof data_intf,
-+	.bDescriptorType =	USB_DT_INTERFACE,
-+
-+	.bInterfaceNumber =	0,
-+	.bAlternateSetting =	0,
-+	.bNumEndpoints =	2,
-+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
-+	.bInterfaceSubClass =	0,
-+	.bInterfaceProtocol =	0,
-+	.iInterface =		STRING_DATA,
-+};
-+
-+#endif	/* DEV_CONFIG_CDC */
-+
- 
- static const struct usb_endpoint_descriptor
- fs_source_desc = {
-@@ -563,12 +627,12 @@ dev_qualifier = {
- 	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
- 
- 	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
--	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
-+	.bDeviceClass =		DEV_CONFIG_CLASS,
- 
- 	/* assumes ep0 uses the same value for both speeds ... */
- 	.bMaxPacketSize0 =	EP0_MAXPACKET,
- 
--	.bNumConfigurations =	2,
-+	.bNumConfigurations =	1,
- };
- 
- /* maxpacket and other transfer characteristics vary by speed. */
-@@ -581,16 +645,24 @@ dev_qualifier = {
- 
- #endif	/* !HIGHSPEED */
- 
-+/*-------------------------------------------------------------------------*/
-+
-+/* descriptors that are built on-demand */
-+
-+#ifdef	DEV_CONFIG_CDC
- /* address that the host will use ... usually assigned at random */
- static char				ethaddr [2 * ETH_ALEN + 1];
-+#endif
- 
- /* static strings, in iso 8859/1 */
- static struct usb_string		strings [] = {
- 	{ STRING_MANUFACTURER,	UTS_SYSNAME " " UTS_RELEASE "/" CHIP, },
- 	{ STRING_PRODUCT,	driver_desc, },
-+#ifdef	DEV_CONFIG_CDC
- 	{ STRING_ETHADDR,	ethaddr, },
--	{ STRING_CONTROL,	control_name, },
--	{ STRING_DATA,		data_name, },
-+	{ STRING_CONTROL,	"CDC Communications Control", },
-+#endif
-+	{ STRING_DATA,		"Ethernet Data", },
- 	{  }		/* end of list */
- };
- 
-@@ -607,14 +679,18 @@ static int
- config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index)
- {
- 	const unsigned	config_len = USB_DT_CONFIG_SIZE
--				+ 3 * USB_DT_INTERFACE_SIZE
-+#ifdef DEV_CONFIG_CDC
-+				+ 2 * USB_DT_INTERFACE_SIZE
- 				+ sizeof header_desc
- 				+ sizeof union_desc
- 				+ sizeof ether_desc
- #ifdef	EP_STATUS_NUM
- 				+ USB_DT_ENDPOINT_SIZE
- #endif
-+#endif /* DEV_CONFIG_CDC */
-+				+ USB_DT_INTERFACE_SIZE
- 				+ 2 * USB_DT_ENDPOINT_SIZE;
-+
- #ifdef HIGHSPEED
- 	int		hs;
- #endif
-@@ -636,6 +712,7 @@ config_buf (enum usb_device_speed speed,
- 		hs = !hs;
- #endif
- 
-+#ifdef DEV_CONFIG_CDC
- 	/* control interface, class descriptors, optional status endpoint */
- 	memcpy (buf, &control_intf, USB_DT_INTERFACE_SIZE);
- 	buf += USB_DT_INTERFACE_SIZE;
-@@ -660,6 +737,7 @@ config_buf (enum usb_device_speed speed,
- 	/* default data altsetting has no endpoints */
- 	memcpy (buf, &data_nop_intf, USB_DT_INTERFACE_SIZE);
- 	buf += USB_DT_INTERFACE_SIZE;
-+#endif /* DEV_CONFIG_CDC */
- 
- 	/* the "real" data interface has two endpoints */
- 	memcpy (buf, &data_intf, USB_DT_INTERFACE_SIZE);
-@@ -684,6 +762,8 @@ config_buf (enum usb_device_speed speed,
- 
- /*-------------------------------------------------------------------------*/
- 
-+static void eth_start (struct eth_dev *dev, int gfp_flags);
-+
- static int
- set_ether_config (struct eth_dev *dev, int gfp_flags)
- {
-@@ -694,7 +774,8 @@ set_ether_config (struct eth_dev *dev, i
- 	gadget_for_each_ep (ep, gadget) {
- 		const struct usb_endpoint_descriptor	*d;
- 
--		/* NOTE:  the host isn't allowed to use these two data
-+#ifdef	DEV_CONFIG_CDC
-+		/* With CDC,  the host isn't allowed to use these two data
- 		 * endpoints in the default altsetting for the interface.
- 		 * so we don't activate them yet.
- 		 */
-@@ -714,10 +795,11 @@ set_ether_config (struct eth_dev *dev, i
- 			dev->out_ep = ep;
- 			dev->out = d;
- 			continue;
-+		}
- 
- #ifdef	EP_STATUS_NUM
- 		/* optional status/notification endpoint */
--		} else if (strcmp (ep->name, EP_STATUS_NAME) == 0) {
-+		else if (strcmp (ep->name, EP_STATUS_NAME) == 0) {
- 			d = ep_desc (gadget, &hs_status_desc, &fs_status_desc);
- 			result = usb_ep_enable (ep, d);
- 			if (result == 0) {
-@@ -726,16 +808,57 @@ set_ether_config (struct eth_dev *dev, i
- 				dev->status = d;
- 				continue;
- 			}
-+		}
- #endif
- 
-+#else	/* !CONFIG_CDC_ETHER */
-+
-+		/* non-CDC is simpler:  if the device is there,
-+		 * it's live with rx and tx endpoints.
-+		 */
-+		/* one endpoint writes data back IN to the host */
-+		if (strcmp (ep->name, EP_IN_NAME) == 0) {
-+			d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
-+			result = usb_ep_enable (ep, d);
-+			if (result == 0) {
-+				ep->driver_data = dev;
-+				dev->in_ep = ep;
-+				dev->in = d;
-+				continue;
-+			}
-+
-+		/* one endpoint just reads OUT packets */
-+		} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
-+			d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
-+			result = usb_ep_enable (ep, d);
-+			if (result == 0) {
-+				ep->driver_data = dev;
-+				dev->out_ep = ep;
-+				dev->out = d;
-+				continue;
-+			}
-+		}
-+
-+#endif /* !CONFIG_CDC_ETHER */
-+
- 		/* ignore any other endpoints */
--		} else
-+		else
- 			continue;
- 
- 		/* stop on error */
- 		ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
- 		break;
- 	}
-+	if (!result && (!dev->in_ep || !dev->out_ep))
-+		result = -ENODEV;
-+
-+#ifndef	DEV_CONFIG_CDC
-+	if (result == 0) {
-+		netif_carrier_on (dev->net);
-+		if (netif_running (dev->net))
-+			eth_start (dev, GFP_ATOMIC);
-+	}
-+#endif /* !CONFIG_CDC_ETHER */
- 
- 	if (result == 0)
- 		DEBUG (dev, "qlen %d\n", qlen (gadget));
-@@ -751,8 +874,8 @@ static void eth_reset_config (struct eth
- 
- 	DEBUG (dev, "%s\n", __FUNCTION__);
- 
--	netif_stop_queue (&dev->net);
--	netif_carrier_off (&dev->net);
-+	netif_stop_queue (dev->net);
-+	netif_carrier_off (dev->net);
- 
- 	/* just disable endpoints, forcing completion of pending i/o.
- 	 * all our completion handlers free their requests in this case.
-@@ -797,7 +920,7 @@ eth_set_config (struct eth_dev *dev, uns
- 	hw_optimize (gadget);
- 
- 	switch (number) {
--	case CONFIG_CDC_ETHER:
-+	case DEV_CONFIG_VALUE:
- 		result = set_ether_config (dev, gfp_flags);
- 		break;
- 	default:
-@@ -807,8 +930,6 @@ eth_set_config (struct eth_dev *dev, uns
- 		return result;
- 	}
- 
--	if (!result && (!dev->in_ep || !dev->out_ep))
--		result = -ENODEV;
- 	if (result)
- 		eth_reset_config (dev);
- 	else {
-@@ -896,6 +1017,7 @@ static void issue_start_status (struct e
- 	 * FIXME ugly idiom, maybe we'd be better with just
- 	 * a "cancel the whole queue" primitive since any
- 	 * unlink-one primitive has way too many error modes.
-+	 * here, we "know" toggle is already clear...
- 	 */
- 	usb_ep_disable (dev->status_ep);
- 	usb_ep_enable (dev->status_ep, dev->status);
-@@ -953,8 +1075,6 @@ static void eth_setup_complete (struct u
-  */
- #define CDC_SET_ETHERNET_PACKET_FILTER	0x43	/* required */
- 
--static void eth_start (struct eth_dev *dev, int gfp_flags);
--
- /*
-  * The setup() callback implements all the ep0 functionality that's not
-  * handled lower down.  CDC has a number of less-common features:
-@@ -1018,6 +1138,17 @@ eth_setup (struct usb_gadget *gadget, co
- 		value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
- 		spin_unlock (&dev->lock);
- 		break;
-+#ifdef	CONFIG_USB_ETH_PXA2XX
-+	/* PXA UDC prevents us from using SET_INTERFACE in normal ways.
-+	 * And it hides GET_CONFIGURATION and GET_INTERFACE too.
-+	 */
-+	case USB_REQ_SET_INTERFACE:
-+		spin_lock (&dev->lock);
-+		value = eth_set_config (dev, DEV_CONFIG_VALUE, GFP_ATOMIC);
-+		spin_unlock (&dev->lock);
-+		break;
-+
-+#else	/* hardware that that stays out of our way */
- 	case USB_REQ_GET_CONFIGURATION:
- 		if (ctrl->bRequestType != USB_DIR_IN)
- 			break;
-@@ -1056,15 +1187,15 @@ eth_setup (struct usb_gadget *gadget, co
- 			if (ctrl->wValue == 1) {
- 				usb_ep_enable (dev->in_ep, dev->in);
- 				usb_ep_enable (dev->out_ep, dev->out);
--				netif_carrier_on (&dev->net);
-+				netif_carrier_on (dev->net);
- #ifdef	EP_STATUS_NUM
- 				issue_start_status (dev);
- #endif
--				if (netif_running (&dev->net))
-+				if (netif_running (dev->net))
- 					eth_start (dev, GFP_ATOMIC);
- 			} else {
--				netif_stop_queue (&dev->net);
--				netif_carrier_off (&dev->net);
-+				netif_stop_queue (dev->net);
-+				netif_carrier_off (dev->net);
- 			}
- 			value = 0;
- 			break;
-@@ -1079,12 +1210,14 @@ eth_setup (struct usb_gadget *gadget, co
- 
- 		/* if carrier is on, data interface is active. */
- 		*(u8 *)req->buf =
--			((ctrl->wIndex == 1) && netif_carrier_ok (&dev->net))
-+			((ctrl->wIndex == 1) && netif_carrier_ok (dev->net))
- 				? 1
- 				: 0,
- 		value = min (ctrl->wLength, (u16) 1);
- 		break;
-+#endif
- 
-+#ifdef DEV_CONFIG_CDC
- 	case CDC_SET_ETHERNET_PACKET_FILTER:
- 		/* see 6.2.30: no data, wIndex = interface,
- 		 * wValue = packet filter bitmap
-@@ -1099,6 +1232,7 @@ eth_setup (struct usb_gadget *gadget, co
- 		 */
- 		value = 0;
- 		break;
-+#endif /* DEV_CONFIG_CDC */
- 
- 	default:
- 		VDEBUG (dev,
-@@ -1129,8 +1263,8 @@ eth_disconnect (struct usb_gadget *gadge
- 	unsigned long		flags;
- 
- 	spin_lock_irqsave (&dev->lock, flags);
--	netif_stop_queue (&dev->net);
--	netif_carrier_off (&dev->net);
-+	netif_stop_queue (dev->net);
-+	netif_carrier_off (dev->net);
- 	eth_reset_config (dev);
- 	spin_unlock_irqrestore (&dev->lock, flags);
- 
-@@ -1175,10 +1309,10 @@ static int eth_ethtool_ioctl (struct net
- 
- 		memset (&info, 0, sizeof info);
- 		info.cmd = ETHTOOL_GDRVINFO;
--		strncpy (info.driver, shortname, sizeof info.driver);
--		strncpy (info.version, DRIVER_VERSION, sizeof info.version);
--		strncpy (info.fw_version, CHIP, sizeof info.fw_version);
--		strncpy (info.bus_info, dev->gadget->dev.bus_id,
-+		strlcpy (info.driver, shortname, sizeof info.driver);
-+		strlcpy (info.version, DRIVER_VERSION, sizeof info.version);
-+		strlcpy (info.fw_version, CHIP, sizeof info.fw_version);
-+		strlcpy (info.bus_info, dev->gadget->dev.bus_id,
- 			sizeof info.bus_info);
- 		if (copy_to_user (useraddr, &info, sizeof (info)))
- 			return -EFAULT;
-@@ -1227,7 +1361,7 @@ rx_submit (struct eth_dev *dev, struct u
- 	int			retval = 0;
- 	size_t			size;
- 
--	size = (sizeof (struct ethhdr) + dev->net.mtu + RX_EXTRA);
-+	size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
- 
- 	if ((skb = alloc_skb (size, gfp_flags)) == 0) {
- 		DEBUG (dev, "no rx skb\n");
-@@ -1241,16 +1375,9 @@ rx_submit (struct eth_dev *dev, struct u
- 	req->complete = rx_complete;
- 	req->context = skb;
- 
--	if (netif_running (&dev->net)) {
--		retval = usb_ep_queue (dev->out_ep, req, gfp_flags);
--		if (retval == -ENOMEM)
--			defer_kevent (dev, WORK_RX_MEMORY);
--		if (retval)
--			DEBUG (dev, "%s %d\n", __FUNCTION__, retval);
--	} else {
--		DEBUG (dev, "%s stopped\n", __FUNCTION__);
--		retval = -ENOLINK;
--	}
-+	retval = usb_ep_queue (dev->out_ep, req, gfp_flags);
-+	if (retval == -ENOMEM)
-+		defer_kevent (dev, WORK_RX_MEMORY);
- 	if (retval) {
- 		DEBUG (dev, "rx submit --> %d\n", retval);
- 		dev_kfree_skb_any (skb);
-@@ -1278,8 +1405,8 @@ static void rx_complete (struct usb_ep *
- 			break;
- 		}
- 
--		skb->dev = &dev->net;
--		skb->protocol = eth_type_trans (skb, &dev->net);
-+		skb->dev = dev->net;
-+		skb->protocol = eth_type_trans (skb, dev->net);
- 		dev->stats.rx_packets++;
- 		dev->stats.rx_bytes += skb->len;
- 
-@@ -1294,9 +1421,7 @@ static void rx_complete (struct usb_ep *
- 	case -ECONNRESET:		// unlink
- 	case -ESHUTDOWN:		// disconnect etc
- 		VDEBUG (dev, "rx shutdown, code %d\n", status);
--		usb_ep_free_request (dev->out_ep, req);
--		req = 0;
--		break;
-+		goto clean;
- 
- 	/* data overrun */
- 	case -EOVERFLOW:
-@@ -1311,7 +1436,11 @@ static void rx_complete (struct usb_ep *
- 
- 	if (skb)
- 		dev_kfree_skb_any (skb);
--
-+	if (!netif_running (dev->net)) {
-+clean:
-+		usb_ep_free_request (dev->out_ep, req);
-+		req = 0;
-+	}
- 	if (req)
- 		rx_submit (dev, req, GFP_ATOMIC);
- }
-@@ -1323,7 +1452,7 @@ static void eth_work (void *_dev)
- 	if (test_bit (WORK_RX_MEMORY, &dev->todo)) {
- 		struct usb_request	*req = 0;
- 
--		if (netif_running (&dev->net))
-+		if (netif_running (dev->net))
- 			req = usb_ep_alloc_request (dev->in_ep, GFP_KERNEL);
- 		else
- 			clear_bit (WORK_RX_MEMORY, &dev->todo);
-@@ -1342,18 +1471,25 @@ static void tx_complete (struct usb_ep *
- 	struct sk_buff	*skb = req->context;
- 	struct eth_dev	*dev = ep->driver_data;
- 
--	if (req->status)
-+	switch (req->status) {
-+	default:
- 		dev->stats.tx_errors++;
--	else
-+		VDEBUG (dev, "tx err %d\n", req->status);
-+		/* FALLTHROUGH */
-+	case -ECONNRESET:		// unlink
-+	case -ESHUTDOWN:		// disconnect etc
-+		break;
-+	case 0:
- 		dev->stats.tx_bytes += skb->len;
-+	}
- 	dev->stats.tx_packets++;
- 
- 	usb_ep_free_request (ep, req);
- 	dev_kfree_skb_any (skb);
- 
- 	atomic_inc (&dev->tx_qlen);
--	if (netif_carrier_ok (&dev->net))
--		netif_wake_queue (&dev->net);
-+	if (netif_carrier_ok (dev->net))
-+		netif_wake_queue (dev->net);
- }
- 
- static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
-@@ -1437,7 +1573,7 @@ static void eth_start (struct eth_dev *d
- 
- 	/* and open the tx floodgates */ 
- 	atomic_set (&dev->tx_qlen, size);
--	netif_wake_queue (&dev->net);
-+	netif_wake_queue (dev->net);
- }
- 
- static int eth_open (struct net_device *net)
-@@ -1445,10 +1581,8 @@ static int eth_open (struct net_device *
- 	struct eth_dev		*dev = (struct eth_dev *) net->priv;
- 
- 	DEBUG (dev, "%s\n", __FUNCTION__);
--	down (&dev->mutex);
--	if (netif_carrier_ok (&dev->net))
-+	if (netif_carrier_ok (dev->net))
- 		eth_start (dev, GFP_KERNEL);
--	up (&dev->mutex);
- 	return 0;
- }
- 
-@@ -1457,7 +1591,6 @@ static int eth_stop (struct net_device *
- 	struct eth_dev		*dev = (struct eth_dev *) net->priv;
- 
- 	DEBUG (dev, "%s\n", __FUNCTION__);
--	down (&dev->mutex);
- 	netif_stop_queue (net);
- 
- 	DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
-@@ -1469,7 +1602,7 @@ static int eth_stop (struct net_device *
- 	if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
- 		usb_ep_disable (dev->in_ep);
- 		usb_ep_disable (dev->out_ep);
--		if (netif_carrier_ok (&dev->net)) {
-+		if (netif_carrier_ok (dev->net)) {
- 			DEBUG (dev, "host still using in/out endpoints\n");
- 			usb_ep_enable (dev->in_ep, dev->in);
- 			usb_ep_enable (dev->out_ep, dev->out);
-@@ -1480,7 +1613,6 @@ static int eth_stop (struct net_device *
- #endif
- 	}
- 
--	up (&dev->mutex);
- 	return 0;
- }
- 
-@@ -1492,7 +1624,6 @@ eth_unbind (struct usb_gadget *gadget)
- 	struct eth_dev		*dev = get_gadget_data (gadget);
- 
- 	DEBUG (dev, "unbind\n");
--	down (&dev->mutex);
- 
- 	/* we've already been disconnected ... no i/o is active */
- 	if (dev->req) {
-@@ -1500,15 +1631,13 @@ eth_unbind (struct usb_gadget *gadget)
- 				dev->req->buf, dev->req->dma,
- 				USB_BUFSIZ);
- 		usb_ep_free_request (gadget->ep0, dev->req);
-+		dev->req = 0;
- 	}
- 
--	unregister_netdev (&dev->net);
--	up (&dev->mutex);
-+	unregister_netdev (dev->net);
- 
- 	/* assuming we used keventd, it must quiesce too */
- 	flush_scheduled_work ();
--
--	kfree (dev);
- 	set_gadget_data (gadget, 0);
- }
- 
-@@ -1517,22 +1646,24 @@ eth_bind (struct usb_gadget *gadget)
- {
- 	struct eth_dev		*dev;
- 	struct net_device	*net;
-+	int			status = -ENOMEM;
-+#ifdef	DEV_CONFIG_CDC
- 	u8			node_id [ETH_ALEN];
- 
- 	/* just one upstream link at a time */
- 	if (ethaddr [0] != 0)
- 		return -ENODEV;
-+#endif
- 
--	dev = kmalloc (sizeof *dev, SLAB_KERNEL);
--	if (!dev)
--		return -ENOMEM;
--	memset (dev, 0, sizeof *dev);
-+ 	net = alloc_etherdev (sizeof *dev);
-+ 	if (!net)
-+		return status;
-+	dev = net->priv;
- 	spin_lock_init (&dev->lock);
--	init_MUTEX_LOCKED (&dev->mutex);
- 	INIT_WORK (&dev->work, eth_work, dev);
- 
- 	/* network device setup */
--	net = &dev->net;
-+	dev->net = net;
- 	SET_MODULE_OWNER (net);
- 	net->priv = dev;
- 	strcpy (net->name, "usb%d");
-@@ -1545,6 +1676,7 @@ eth_bind (struct usb_gadget *gadget)
- 	net->dev_addr [0] &= 0xfe;	// clear multicast bit
- 	net->dev_addr [0] |= 0x02;	// set local assignment bit (IEEE802)
- 
-+#ifdef	DEV_CONFIG_CDC
- 	/* ... another address for the host, on the other end of the
- 	 * link, gets exported through CDC (see CDC spec table 41)
- 	 */
-@@ -1554,6 +1686,7 @@ eth_bind (struct usb_gadget *gadget)
- 	snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
- 		node_id [0], node_id [1], node_id [2],
- 		node_id [3], node_id [4], node_id [5]);
-+#endif
- 
- 	net->change_mtu = eth_change_mtu;
- 	net->get_stats = eth_get_stats;
-@@ -1567,36 +1700,38 @@ eth_bind (struct usb_gadget *gadget)
- 	/* preallocate control response and buffer */
- 	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
- 	if (!dev->req)
--		goto enomem;
-+		goto fail;
- 	dev->req->complete = eth_setup_complete;
- 	dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
- 				&dev->req->dma, GFP_KERNEL);
- 	if (!dev->req->buf) {
- 		usb_ep_free_request (gadget->ep0, dev->req);
--		goto enomem;
-+		goto fail;
- 	}
- 
- 	/* finish hookup to lower layer ... */
- 	dev->gadget = gadget;
- 	set_gadget_data (gadget, dev);
- 	gadget->ep0->driver_data = dev;
--
-+	INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n", driver_desc);
-+#ifdef	DEV_CONFIG_CDC
-+	INFO (dev, "CDC host enet %s\n", ethaddr);
-+#endif
-+	
- 	/* two kinds of host-initiated state changes:
- 	 *  - iff DATA transfer is active, carrier is "on"
- 	 *  - tx queueing enabled if open *and* carrier is "on"
- 	 */
--	INFO (dev, "%s, host enet %s, version: " DRIVER_VERSION "\n",
--			driver_desc, ethaddr);
--	register_netdev (&dev->net);
--	netif_stop_queue (&dev->net);
--	netif_carrier_off (&dev->net);
--
--	up (&dev->mutex);
--	return 0;
-+	netif_stop_queue (dev->net);
-+	netif_carrier_off (dev->net);
- 
--enomem:
-+ 	// SET_NETDEV_DEV (dev->net, &gadget->dev);
-+ 	status = register_netdev (dev->net);
-+ 	if (status == 0)
-+ 		return status;
-+fail:
- 	eth_unbind (gadget);
--	return -ENOMEM;
-+	return status;
- }
- 
- /*-------------------------------------------------------------------------*/
---- linux-2.6.0-test1/drivers/usb/gadget/net2280.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/gadget/net2280.c	2003-07-19 17:03:50.000000000 -0700
-@@ -2496,7 +2496,7 @@ static void net2280_remove (struct pci_d
- 	device_remove_file (&pdev->dev, &dev_attr_registers);
- 	pci_set_drvdata (pdev, 0);
- 
--	INFO (dev, "unbind from pci %s\n", pdev->slot_name);
-+	INFO (dev, "unbind from pci %s\n", pci_name(pdev));
- 
- 	kfree (dev);
- 	the_controller = 0;
-@@ -2518,7 +2518,7 @@ static int net2280_probe (struct pci_dev
- 	 * usb_gadget_driver_{register,unregister}() must change.
- 	 */
- 	if (the_controller) {
--		WARN (the_controller, "ignoring %s\n", pdev->slot_name);
-+		WARN (the_controller, "ignoring %s\n", pci_name(pdev));
- 		return -EBUSY;
- 	}
- 
-@@ -2534,7 +2534,7 @@ static int net2280_probe (struct pci_dev
- 	dev->pdev = pdev;
- 	dev->gadget.ops = &net2280_ops;
- 
--	strcpy (dev->gadget.dev.bus_id, pdev->slot_name);
-+	strcpy (dev->gadget.dev.bus_id, pci_name(pdev));
- 	strcpy (dev->gadget.dev.name, pdev->dev.name);
- 	dev->gadget.dev.parent = &pdev->dev;
- 	dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
---- linux-2.6.0-test1/drivers/usb/gadget/net2280.h	2003-06-14 12:18:29.000000000 -0700
-+++ 25/drivers/usb/gadget/net2280.h	2003-07-19 17:03:50.000000000 -0700
-@@ -654,7 +654,7 @@ static inline void net2280_led_shutdown 
- 
- #define xprintk(dev,level,fmt,args...) \
- 	printk(level "%s %s: " fmt , driver_name , \
--			dev->pdev->slot_name , ## args)
-+			pci_name(dev->pdev) , ## args)
- 
- #ifdef DEBUG
- #undef DEBUG
---- linux-2.6.0-test1/drivers/usb/gadget/zero.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/usb/gadget/zero.c	2003-07-19 17:03:50.000000000 -0700
-@@ -92,7 +92,7 @@
- 
- /*-------------------------------------------------------------------------*/
- 
--#define DRIVER_VERSION		"19 Feb 2003"
-+#define DRIVER_VERSION		"Bastille Day 2003"
- 
- static const char shortname [] = "zero";
- static const char longname [] = "Gadget Zero";
-@@ -160,18 +160,18 @@ static inline void hw_optimize (struct u
- #endif
- 
- /*
-- * PXA-250 UDC:  widely used in second gen Linux-capable PDAs.
-+ * PXA-2xx UDC:  widely used in second gen Linux-capable PDAs.
-  *
-  * This has fifteen fixed-function full speed endpoints, and it
-  * can support all USB transfer types.
-  *
-- * It only supports three configurations (numbered 1, 2, or 3)
-- * with two interfaces each ... there's partial hardware support
-- * for set_configuration and set_interface, preventing some more
-- * interesting config/interface/endpoint arrangements.
-+ * These supports three or four configurations, with fixed numbers.
-+ * The hardware interprets SET_INTERFACE, net effect is that you
-+ * can't use altsettings or reset the interfaces independently.
-+ * So stick to a single interface.
-  */
--#ifdef	CONFIG_USB_ZERO_PXA250
--#define CHIP			"pxa250"
-+#ifdef	CONFIG_USB_ZERO_PXA2XX
-+#define CHIP			"pxa2xx"
- #define DRIVER_VERSION_NUM	0x0103
- #define EP0_MAXPACKET		16
- static const char EP_OUT_NAME [] = "ep12out-bulk";
-@@ -291,9 +291,12 @@ struct zero_dev {
- 
- static unsigned buflen = 4096;
- static unsigned qlen = 32;
-+static unsigned pattern = 0;
- 
- module_param (buflen, uint, S_IRUGO|S_IWUSR);
- module_param (qlen, uint, S_IRUGO|S_IWUSR);
-+module_param (pattern, uint, S_IRUGO|S_IWUSR);
-+
- 
- /*
-  * Normally the "loopback" configuration is second (index 1) so
-@@ -497,8 +500,8 @@ static struct usb_gadget_strings	stringt
- 
- /*
-  * config descriptors are also handcrafted.  these must agree with code
-- * that sets configurations, and with code managing interface altsettings.
-- * other complexity may come from:
-+ * that sets configurations, and with code managing interfaces and their
-+ * altsettings.  other complexity may come from:
-  *
-  *  - high speed support, including "other speed config" rules
-  *  - multiple configurations
-@@ -506,7 +509,7 @@ static struct usb_gadget_strings	stringt
-  *  - embedded class or vendor-specific descriptors
-  *
-  * this handles high speed, and has a second config that could as easily
-- * have been an alternate interface setting.
-+ * have been an alternate interface setting (on most hardware).
-  *
-  * NOTE:  to demonstrate (and test) more USB capabilities, this driver
-  * should include an altsetting to test interrupt transfers, including
-@@ -608,16 +611,29 @@ check_read_data (
- 	struct usb_request	*req
- )
- {
--	int i;
-+	unsigned	i;
-+	u8		*buf = req->buf;
- 
--	for (i = 0; i < req->actual; i++) {
--		if (((u8 *)req->buf) [i] != 0) {
--			ERROR (dev, "nonzero OUT byte from host, "
--					"buf [%d] = %d\n",
--					i, ((u8 *)req->buf) [i]);
--			usb_ep_set_halt (ep);
--			return -EINVAL;
-+	for (i = 0; i < req->actual; i++, buf++) {
-+		switch (pattern) {
-+		/* all-zeroes has no synchronization issues */
-+		case 0:
-+			if (*buf == 0)
-+				continue;
-+			break;
-+		/* mod63 stays in sync with short-terminated transfers,
-+		 * or otherwise when host and gadget agree on how large
-+		 * each usb transfer request should be.  resync is done
-+		 * with set_interface or set_config.
-+		 */
-+		case 1:
-+			if (*buf == (u8)(i % 63))
-+				continue;
-+			break;
- 		}
-+		ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);
-+		usb_ep_set_halt (ep);
-+		return -EINVAL;
- 	}
- 	return 0;
- }
-@@ -629,7 +645,18 @@ reinit_write_data (
- 	struct usb_request	*req
- )
- {
--	memset (req->buf, 0, req->length);
-+	unsigned	i;
-+	u8		*buf = req->buf;
-+
-+	switch (pattern) {
-+	case 0:
-+		memset (req->buf, 0, req->length);
-+		break;
-+	case 1:
-+		for  (i = 0; i < req->length; i++)
-+			*buf++ = (u8) (i % 63);
-+		break;
-+	}
- }
- 
- /* if there is only one request in the queue, there'll always be an
-@@ -651,10 +678,13 @@ static void source_sink_complete (struct
- 		break;
- 
- 	/* this endpoint is normally active while we're configured */
-+	case -ECONNABORTED: 		/* hardware forced ep reset */
- 	case -ECONNRESET:		/* request dequeued */
- 	case -ESHUTDOWN:		/* disconnect from host */
- 		VDEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
- 				req->actual, req->length);
-+		if (ep == dev->out_ep)
-+			check_read_data (dev, ep, req);
- 		free_ep_req (ep, req);
- 		return;
- 
-@@ -693,6 +723,9 @@ source_sink_start_ep (struct usb_ep *ep,
- 	memset (req->buf, 0, req->length);
- 	req->complete = source_sink_complete;
- 
-+	if (strcmp (ep->name, EP_IN_NAME) == 0)
-+		reinit_write_data (ep->driver_data, ep, req);
-+
- 	status = usb_ep_queue (ep, req, gfp_flags);
- 	if (status) {
- 		struct zero_dev	*dev = ep->driver_data;
-@@ -801,6 +834,8 @@ static void loopback_complete (struct us
- 	 * rely on the hardware driver to clean up on disconnect or
- 	 * endpoint disable.
- 	 */
-+	case -ECONNABORTED: 		/* hardware forced ep reset */
-+	case -ECONNRESET:		/* request dequeued */
- 	case -ESHUTDOWN:		/* disconnect from host */
- 		free_ep_req (ep, req);
- 		return;
-@@ -905,7 +940,7 @@ static void zero_reset_config (struct ze
-  *
-  * note that some device controller hardware will constrain what this
-  * code can do, perhaps by disallowing more than one configuration or
-- * by limiting configuration choices (like the pxa250).
-+ * by limiting configuration choices (like the pxa2xx).
-  */
- static int
- zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
-@@ -1046,7 +1081,8 @@ zero_setup (struct usb_gadget *gadget, c
- 		break;
- 
- 	/* until we add altsetting support, or other interfaces,
--	 * only 0/0 are possible.
-+	 * only 0/0 are possible.  pxa2xx only supports 0/0 (poorly)
-+	 * and already killed pending endpoint I/O.
- 	 */
- 	case USB_REQ_SET_INTERFACE:
- 		if (ctrl->bRequestType != USB_RECIP_INTERFACE)
---- linux-2.6.0-test1/drivers/usb/host/ohci-hcd.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/usb/host/ohci-hcd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -319,6 +319,7 @@ ohci_endpoint_disable (struct usb_hcd *h
- 	int			epnum = ep & USB_ENDPOINT_NUMBER_MASK;
- 	unsigned long		flags;
- 	struct ed		*ed;
-+	unsigned		limit = 1000;
- 
- 	/* ASSERT:  any requests/urbs are being unlinked */
- 	/* ASSERT:  nobody can be submitting urbs for this any more */
-@@ -337,6 +338,8 @@ rescan:
- 		ed->state = ED_IDLE;
- 	switch (ed->state) {
- 	case ED_UNLINK:		/* wait for hw to finish? */
-+		/* major IRQ delivery trouble loses INTR_SF too... */
-+		WARN_ON (limit-- == 0);
- 		spin_unlock_irqrestore (&ohci->lock, flags);
- 		set_current_state (TASK_UNINTERRUPTIBLE);
- 		schedule_timeout (1);
---- linux-2.6.0-test1/drivers/usb/host/ohci-q.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/drivers/usb/host/ohci-q.c	2003-07-19 17:03:50.000000000 -0700
-@@ -43,6 +43,16 @@ finish_urb (struct ohci_hcd *ohci, struc
- 	spin_lock (&urb->lock);
- 	if (likely (urb->status == -EINPROGRESS))
- 		urb->status = 0;
-+	/* report short control reads right even though the data TD always
-+	 * has TD_R set.  (much simpler, but creates the 1-td limit.)
-+	 */
-+	if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK)
-+			&& unlikely (usb_pipecontrol (urb->pipe))
-+			&& urb->actual_length < urb->transfer_buffer_length
-+			&& usb_pipein (urb->pipe)
-+			&& urb->status == 0) {
-+		urb->status = -EREMOTEIO;
-+	}
- 	spin_unlock (&urb->lock);
- 
- 	// what lock protects these?
---- linux-2.6.0-test1/drivers/usb/host/uhci-hcd.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/host/uhci-hcd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -2007,19 +2007,17 @@ static int suspend_allowed(struct uhci_h
- 	unsigned int io_addr = uhci->io_addr;
- 	int i;
- 
--	if (!uhci->hcd.pdev ||
--	     uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL ||
--	     uhci->hcd.pdev->device != PCI_DEVICE_ID_INTEL_82371AB_2)
-+	if (!uhci->hcd.pdev || uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL)
- 		return 1;
- 
--	/* This is a 82371AB/EB/MB USB controller which has a bug that
--	 * causes false resume indications if any port has an
--	 * over current condition.  To prevent problems, we will not
--	 * allow a global suspend if any ports are OC.
-+	/* Some of Intel's USB controllers have a bug that causes false
-+	 * resume indications if any port has an over current condition.
-+	 * To prevent problems, we will not allow a global suspend if
-+	 * any ports are OC.
- 	 *
--	 * Some motherboards using the 82371AB/EB/MB (but not the USB portion)
--	 * appear to hardwire the over current inputs active to disable
--	 * the USB ports.
-+	 * Some motherboards using Intel's chipsets (but not using all
-+	 * the USB ports) appear to hardwire the over current inputs active
-+	 * to disable the USB ports.
- 	 */
- 
- 	/* check for over current condition on any port */
---- linux-2.6.0-test1/drivers/usb/image/hpusbscsi.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/image/hpusbscsi.c	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
- #include <linux/smp_lock.h>
- #include <linux/usb.h>
- #include <asm/atomic.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "../../scsi/scsi.h"
- #include "../../scsi/hosts.h"
- 
-@@ -109,7 +109,8 @@ hpusbscsi_usb_probe(struct usb_interface
- 		goto out_unlink_controlurb;
- 
- 	new->host->hostdata[0] = (unsigned long)new;
--	scsi_add_host(new->host, &intf->dev);
-+	scsi_add_host(new->host, &intf->dev); /* XXX handle failure */
-+	scsi_scan_host(new->host);
- 
- 	new->sense_command[0] = REQUEST_SENSE;
- 	new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
-@@ -306,7 +307,10 @@ DEBUG("Getting status byte %d \n",hpusbs
- 	if(unlikely(u->status < 0)) {
-                 if (likely(hpusbscsi->state != HP_STATE_FREE))
-                         handle_usb_error(hpusbscsi);
--		return;
-+		if (u->status == -ECONNRESET || u->status == -ENOENT || u->status == -ESHUTDOWN)
-+			return;
-+		else
-+			goto resub;
- 	}
- 
- 	scsi_state = hpusbscsi->scsi_state_byte;
-@@ -348,6 +352,8 @@ DEBUG("Getting status byte %d \n",hpusbs
- 	TRACE_STATE;
- 		break;
- 	}
-+resub:
-+	usb_submit_urb(u, GFP_ATOMIC);
- }
- 
- static void simple_command_callback(struct urb *u, struct pt_regs *regs)
-@@ -427,7 +433,7 @@ static void simple_done (struct urb *u, 
- 				hpusbscsi->state = HP_STATE_WAIT;
- 			} else {
- 				issue_request_sense(hpusbscsi);
--			}			
-+			}
- 		}
- 	} else {
- 		if (likely(hpusbscsi->scallback != NULL))
---- linux-2.6.0-test1/drivers/usb/image/microtek.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/image/microtek.c	2003-07-19 17:03:50.000000000 -0700
-@@ -134,7 +134,7 @@
- #include <linux/proc_fs.h>
- 
- #include <asm/atomic.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "../../scsi/scsi.h"
- #include "../../scsi/hosts.h"
- 
-@@ -817,7 +817,8 @@ static int mts_usb_probe(struct usb_inte
- 		goto out_free_urb;
- 
- 	new_desc->host->hostdata[0] = (unsigned long)new_desc;
--	scsi_add_host(new_desc->host, NULL);
-+	scsi_add_host(new_desc->host, NULL); /* XXX handle failure */
-+	scsi_scan_host(new_desc->host);
- 
- 	usb_set_intfdata(intf, new_desc);
- 	return 0;
---- linux-2.6.0-test1/drivers/usb/image/scanner.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/usb/image/scanner.c	2003-07-19 17:03:50.000000000 -0700
-@@ -364,6 +364,11 @@
-  *      Mustek, Pacific Image Electronics, Plustek, and Visioneer scanners.
-  *      Fixed names of some other scanners.
-  *
-+ * 0.4.14  2003-07-15
-+ *    - Fixed race between open and probe (Oliver Neukum).
-+ *    - Added vendor/product ids for Avision, Canon, HP, Microtek and Relisys scanners.
-+ *    - Clean up irq urb when not enough memory is available.
-+ *
-  * TODO
-  *    - Performance
-  *    - Select/poll methods
-@@ -1068,6 +1073,9 @@ probe_scanner(struct usb_interface *intf
- /* Ok, now initialize all the relevant values */
- 	if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {
- 		err("probe_scanner(%d): Not enough memory for the output buffer.", intf->minor);
-+		if (have_intr)
-+			usb_unlink_urb(scn->scn_irq);
-+		usb_free_urb(scn->scn_irq);
- 		kfree(scn);
- 		up(&scn_mutex);
- 		return -ENOMEM;
-@@ -1076,6 +1084,9 @@ probe_scanner(struct usb_interface *intf
- 
- 	if (!(scn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) {
- 		err("probe_scanner(%d): Not enough memory for the input buffer.", intf->minor);
-+		if (have_intr)
-+			usb_unlink_urb(scn->scn_irq);
-+		usb_free_urb(scn->scn_irq);
- 		kfree(scn->obuf);
- 		kfree(scn);
- 		up(&scn_mutex);
-@@ -1117,10 +1128,9 @@ probe_scanner(struct usb_interface *intf
- 	info ("USB scanner device (0x%04x/0x%04x) now attached to %s",
- 	      dev->descriptor.idVendor, dev->descriptor.idProduct, name);
- 
--	up(&scn_mutex);
--
- 	usb_set_intfdata(intf, scn);
--
-+	up(&scn_mutex);
-+	
- 	return 0;
- }
- 
---- linux-2.6.0-test1/drivers/usb/image/scanner.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/usb/image/scanner.h	2003-07-19 17:03:50.000000000 -0700
-@@ -43,7 +43,7 @@
- 
- // #define DEBUG
- 
--#define DRIVER_VERSION "0.4.13"
-+#define DRIVER_VERSION "0.4.14"
- #define DRIVER_DESC "USB Scanner Driver"
- 
- #include <linux/usb.h>
-@@ -103,6 +103,7 @@ static struct usb_device_id scanner_devi
- 	/* Avision */
- 	{ USB_DEVICE(0x0638, 0x0268) }, /* iVina 1200U */
- 	{ USB_DEVICE(0x0638, 0x0a10) },	/* iVina FB1600 (=Umax Astra 4500) */
-+	{ USB_DEVICE(0x0638, 0x0a20) }, /* iVina FB1800 (=Umax Astra 4700) */
- 	/* Benq: see Acer */
- 	/* Brother */
- 	{ USB_DEVICE(0x04f9, 0x010f) },	/* MFC 5100C */
-@@ -115,10 +116,12 @@ static struct usb_device_id scanner_devi
- 	{ USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */
- 	{ USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */
- 	{ USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ 
-+	{ USB_DEVICE(0x04a9, 0x220a) },	/* CanoScan D2400UF */
- 	{ USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */
- 	{ USB_DEVICE(0x04a9, 0x220c) },	/* CanoScan D1250U2 */
- 	{ USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */
- 	{ USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */
-+	{ USB_DEVICE(0x04a9, 0x220f) },	/* CanoScan 8000F */
- 	{ USB_DEVICE(0x04a9, 0x2213) },	/* LIDE 50 */
- 	{ USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */
- 	/* Colorado -- See Primax/Colorado below */
-@@ -158,6 +161,7 @@ static struct usb_device_id scanner_devi
- 	{ USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */
- 	{ USB_DEVICE(0x03F0, 0x1005) },	/* ScanJet 5400C */
- 	{ USB_DEVICE(0x03F0, 0x1105) },	/* ScanJet 5470C */
-+	{ USB_DEVICE(0x03f0, 0x1205) }, /* ScanJet 5550C */
- 	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
- 	{ USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 */
- 	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
-@@ -173,6 +177,7 @@ static struct usb_device_id scanner_devi
- 	/* Memorex */
- 	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
- 	/* Microtek */
-+	{ USB_DEVICE(0x05da, 0x20c9) }, /* ScanMaker 6700 */
- 	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
- 	{ USB_DEVICE(0x05da, 0x30cf) },	/* ScanMaker 4800 */
- 	{ USB_DEVICE(0x04a7, 0x0224) },	/* Scanport 3000 (actually Visioneer?)*/
-@@ -250,6 +255,7 @@ static struct usb_device_id scanner_devi
- 	{ USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */
- 	/* Relisis */
- 	// { USB_DEVICE(0x0475, 0x0103) },	/* Episode - undetected endpoint */
-+	{ USB_DEVICE(0x0475, 0x0210) }, /* Scorpio Ultra 3 */
- 	/* Seiko/Epson Corp. */
- 	{ USB_DEVICE(0x04b8, 0x0101) },	/* Perfection 636U and 636Photo */
- 	{ USB_DEVICE(0x04b8, 0x0102) }, /* GT-2200 */
---- linux-2.6.0-test1/drivers/usb/media/dabusb.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/usb/media/dabusb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -721,7 +721,7 @@ static struct usb_class_driver dabusb_cl
- 
- 
- /* --------------------------------------------------------------------- */
--static int dabusb_probe (struct usb_interface *intf, 
-+static int dabusb_probe (struct usb_interface *intf,
- 			 const struct usb_device_id *id)
- {
- 	struct usb_device *usbdev = interface_to_usbdev(intf);
-@@ -738,9 +738,7 @@ static int dabusb_probe (struct usb_inte
- 	if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
- 		return -ENODEV;
- 
--	retval = usb_register_dev(intf, &dabusb_class);
--	if (retval)
--		return -ENOMEM;
-+
- 
- 	s = &dabusb[intf->minor];
- 
-@@ -766,8 +764,15 @@ static int dabusb_probe (struct usb_inte
- 		}
- 	}
- 	dbg("bound to interface: %d", ifnum);
--	up (&s->mutex);
- 	usb_set_intfdata (intf, s);
-+	up (&s->mutex);
-+
-+	retval = usb_register_dev(intf, &dabusb_class);
-+	if (retval) {
-+		usb_set_intfdata (intf, NULL);
-+		return -ENOMEM;
-+	}
-+
- 	return 0;
- 
-       reject:
---- linux-2.6.0-test1/drivers/usb/media/vicam.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/drivers/usb/media/vicam.c	2003-07-19 17:04:54.000000000 -0700
-@@ -611,15 +611,20 @@ vicam_ioctl(struct inode *inode, struct 
- 
- 	case VIDIOCSPICT:
- 		{
--			struct video_picture *vp = (struct video_picture *) arg;
-+			struct video_picture vp;
- 
--			DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp->depth,
--			    vp->palette);
-+			if (copy_from_user(&vp, arg, sizeof (vp))) {
-+				retval = -EFAULT;
-+				break;
-+			}
- 
--			cam->gain = vp->brightness >> 8;
-+			DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
-+			    vp.palette);
- 
--			if (vp->depth != 24
--			    || vp->palette != VIDEO_PALETTE_RGB24)
-+			cam->gain = vp.brightness >> 8;
-+
-+			if (vp.depth != 24
-+			    || vp.palette != VIDEO_PALETTE_RGB24)
- 				retval = -EINVAL;
- 
- 			break;
-@@ -652,10 +657,15 @@ vicam_ioctl(struct inode *inode, struct 
- 	case VIDIOCSWIN:
- 		{
- 
--			struct video_window *vw = (struct video_window *) arg;
--			DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height);
-+			struct video_window vw;
-+
-+			if (copy_from_user(&vw, arg, sizeof (vw))) {
-+				retval = -EFAULT;
-+				break;
-+			}
-+			DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
- 
--			if ( vw->width != 320 || vw->height != 240 )
-+			if ( vw.width != 320 || vw.height != 240 )
- 				retval = -EFAULT;
- 			
- 			break;
---- linux-2.6.0-test1/drivers/usb/misc/usblcd.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/misc/usblcd.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1,4 +1,4 @@
--/***************************************************************************** 
-+/*****************************************************************************
-  *                          USBLCD Kernel Driver                             *
-  *        See http://www.usblcd.de for Hardware and Documentation.           *
-  *                            Version 1.03                                   *
-@@ -18,7 +18,7 @@
- #include <asm/uaccess.h>
- #include <linux/usb.h>
- 
--#define DRIVER_VERSION "USBLCD Driver Version 1.03"
-+#define DRIVER_VERSION "USBLCD Driver Version 1.04"
- 
- #define USBLCD_MINOR		144
- 
-@@ -257,7 +257,7 @@ static int probe_lcd(struct usb_interfac
- 	struct lcd_usb_data *lcd = &lcd_instance;
- 	int i;
- 	int retval;
--	
-+
- 	if (dev->descriptor.idProduct != 0x0001  ) {
- 		warn(KERN_INFO "USBLCD model not supported.");
- 		return -ENODEV;
-@@ -274,30 +274,32 @@ static int probe_lcd(struct usb_interfac
- 		(i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
- 		dev->devnum);
- 
--	retval = usb_register_dev(intf, &usb_lcd_class);
--	if (retval) {
--		err("Not able to get a minor for this device.");
--		return -ENOMEM;
--	}
-+
- 
- 	lcd->present = 1;
- 	lcd->lcd_dev = dev;
- 
- 	if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
- 		err("probe_lcd: Not enough memory for the output buffer");
--		usb_deregister_dev(intf, &usb_lcd_class);
- 		return -ENOMEM;
- 	}
- 	dbg("probe_lcd: obuf address:%p", lcd->obuf);
- 
- 	if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
- 		err("probe_lcd: Not enough memory for the input buffer");
--		usb_deregister_dev(intf, &usb_lcd_class);
- 		kfree(lcd->obuf);
- 		return -ENOMEM;
- 	}
- 	dbg("probe_lcd: ibuf address:%p", lcd->ibuf);
- 
-+	retval = usb_register_dev(intf, &usb_lcd_class);
-+	if (retval) {
-+		err("Not able to get a minor for this device.");
-+		kfree(lcd->obuf);
-+		kfree(lcd->ibuf);
-+		return -ENOMEM;
-+	}
-+
- 	usb_set_intfdata (intf, lcd);
- 	return 0;
- }
---- linux-2.6.0-test1/drivers/usb/misc/usbtest.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/misc/usbtest.c	2003-07-19 17:03:50.000000000 -0700
-@@ -47,6 +47,7 @@ struct usbtest_info {
- 	const char		*name;
- 	u8			ep_in;		/* bulk/intr source */
- 	u8			ep_out;		/* bulk/intr sink */
-+	unsigned		autoconf : 1;
- 	int			alt;
- };
- 
-@@ -78,6 +79,61 @@ static struct usb_device *testdev_to_usb
- 
- /*-------------------------------------------------------------------------*/
- 
-+static int
-+get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf)
-+{
-+	int				tmp;
-+	struct usb_host_interface	*alt;
-+	struct usb_host_endpoint	*in, *out;
-+	struct usb_device		*udev;
-+
-+	for (tmp = 0; tmp < intf->max_altsetting; tmp++) {
-+		unsigned	ep;
-+
-+		in = out = 0;
-+		alt = intf->altsetting + tmp;
-+
-+		/* take the first altsetting with in-bulk + out-bulk;
-+		 * ignore other endpoints and altsetttings.
-+		 */
-+		for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
-+			struct usb_host_endpoint	*e;
-+
-+			e = alt->endpoint + ep;
-+			if (e->desc.bmAttributes != USB_ENDPOINT_XFER_BULK)
-+				continue;
-+			if (e->desc.bEndpointAddress & USB_DIR_IN) {
-+				if (!in)
-+					in = e;
-+			} else {
-+				if (!out)
-+					out = e;
-+			}
-+			if (in && out)
-+				goto found;
-+		}
-+	}
-+	return -EINVAL;
-+
-+found:
-+	udev = testdev_to_usbdev (dev);
-+	if (alt->desc.bAlternateSetting != 0) {
-+		tmp = usb_set_interface (udev,
-+				alt->desc.bInterfaceNumber,
-+				alt->desc.bAlternateSetting);
-+		if (tmp < 0)
-+			return tmp;
-+	}
-+
-+	dev->in_pipe = usb_rcvbulkpipe (udev,
-+			in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-+	dev->out_pipe = usb_sndbulkpipe (udev,
-+			out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-+	return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
- /* Support for testing basic non-queued I/O streams.
-  *
-  * These just package urbs as requests that can be easily canceled.
-@@ -1275,14 +1331,26 @@ usbtest_probe (struct usb_interface *int
- 			wtest = " intr-out";
- 		}
- 	} else {
--		if (info->ep_in) {
--			dev->in_pipe = usb_rcvbulkpipe (udev, info->ep_in);
--			rtest = " bulk-in";
-+		if (info->autoconf) {
-+			int status;
-+
-+			status = get_endpoints (dev, intf);
-+			if (status < 0) {
-+				dbg ("couldn't get endpoints, %d\n", status);
-+				return status;
-+			}
-+		} else {
-+			if (info->ep_in)
-+				dev->in_pipe = usb_rcvbulkpipe (udev,
-+							info->ep_in);
-+			if (info->ep_out)
-+				dev->out_pipe = usb_sndbulkpipe (udev,
-+							info->ep_out);
- 		}
--		if (info->ep_out) {
--			dev->out_pipe = usb_sndbulkpipe (udev, info->ep_out);
-+		if (dev->in_pipe)
-+			rtest = " bulk-in";
-+		if (dev->out_pipe)
- 			wtest = " bulk-out";
--		}
- 	}
- 
- 	usb_set_intfdata (intf, dev);
-@@ -1336,11 +1404,6 @@ static struct usbtest_info ez2_info = {
- };
- 
- /* ezusb family device with dedicated usb test firmware,
-- * or a peripheral running Linux and 'zero.c' test firmware.
-- *
-- * FIXME usbtest should read the descriptors, since compatible
-- * test firmware might run on hardware (pxa250 for one) that
-- * can't configure an ep2in-bulk.
-  */
- static struct usbtest_info fw_info = {
- 	.name		= "usb test device",
-@@ -1349,10 +1412,20 @@ static struct usbtest_info fw_info = {
- 	.alt		= 0,
- };
- 
-+/* peripheral running Linux and 'zero.c' test firmware, or
-+ * its user-mode cousin. different versions of this use
-+ * different hardware with the same vendor/product codes.
-+ * host side MUST rely on the endpoint descriptors.
-+ */
-+static struct usbtest_info gz_info = {
-+	.name		= "Linux gadget zero",
-+	.autoconf	= 1,
-+	.alt		= 0,
-+};
-+
- static struct usbtest_info um_info = {
--	.name		= "user mode test driver",
--	.ep_in		= 7,
--	.ep_out		= 3,
-+	.name		= "Linux user mode test driver",
-+	.autoconf	= 1,
- 	.alt		= -1,
- };
- 
-@@ -1418,7 +1491,7 @@ static struct usb_device_id id_table [] 
- 
- 	/* "Gadget Zero" firmware runs under Linux */
- 	{ USB_DEVICE (0x0525, 0xa4a0),
--		.driver_info = (unsigned long) &fw_info,
-+		.driver_info = (unsigned long) &gz_info,
- 		},
- 
- 	/* so does a user-mode variant */
---- linux-2.6.0-test1/drivers/usb/net/ax8817x.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/net/ax8817x.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1208,6 +1208,7 @@ static int ax8817x_bind(struct usb_inter
- 	net->init = ax8817x_net_init;
- 	net->priv = ax_info;
- 
-+	SET_NETDEV_DEV(net, &intf->dev);
- 	ret = register_netdev(net);
- 	if (ret < 0) {
- 		err("%s: Failed net init (%d)\n", __FUNCTION__, ret);
---- linux-2.6.0-test1/drivers/usb/net/catc.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/net/catc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -936,6 +936,7 @@ static int catc_probe(struct usb_interfa
- 	printk("%2.2x.\n", netdev->dev_addr[i]);
- 	usb_set_intfdata(intf, catc);
- 
-+	SET_NETDEV_DEV(netdev, &intf->dev);
- 	if (register_netdev(netdev) != 0) {
- 		usb_set_intfdata(intf, NULL);
- 		usb_free_urb(catc->ctrl_urb);
---- linux-2.6.0-test1/drivers/usb/net/kaweth.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/net/kaweth.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1123,8 +1123,9 @@ static int kaweth_probe(
- 	if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
- 		kaweth->net->features |= NETIF_F_HIGHDMA;
- 
-+	SET_NETDEV_DEV(netdev, &intf->dev);
- 	if (register_netdev(netdev) != 0) {
--		kaweth_err("Error calling init_etherdev.");
-+		kaweth_err("Error registering netdev.");
- 		goto err_intfdata;
- 	}
- 
---- linux-2.6.0-test1/drivers/usb/net/pegasus.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/net/pegasus.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1262,7 +1262,6 @@ static int pegasus_probe(struct usb_inte
- 	}
- 	set_ethernet_addr(pegasus);
- 	fill_skb_pool(pegasus);
--	printk("%s: %s\n", net->name, usb_dev_id[dev_index].name);
- 	if (pegasus->features & PEGASUS_II) {
- 		info("setup Pegasus II specific registers");
- 		setup_pegasus_II(pegasus);
-@@ -1273,9 +1272,11 @@ static int pegasus_probe(struct usb_inte
- 		pegasus->phy = 1;
- 	}
- 	usb_set_intfdata(intf, pegasus);
-+	SET_NETDEV_DEV(net, &intf->dev);
- 	res = register_netdev(net);
- 	if (res)
- 		goto out4;
-+	printk("%s: %s\n", net->name, usb_dev_id[dev_index].name);
- 	return 0;
- 
- out4:
---- linux-2.6.0-test1/drivers/usb/net/rtl8150.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/net/rtl8150.c	2003-07-19 17:03:50.000000000 -0700
-@@ -830,6 +830,7 @@ static int rtl8150_probe(struct usb_inte
- 	
- 	usb_set_intfdata(intf, dev);
- 
-+	SET_NETDEV_DEV(netdev, &intf->dev);
- 	if (register_netdev(netdev) != 0) {
- 		err("couldn't register the device");
- 		goto out2;
---- linux-2.6.0-test1/drivers/usb/net/usbnet.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/net/usbnet.c	2003-07-19 17:03:50.000000000 -0700
-@@ -2602,7 +2602,7 @@ usbnet_probe (struct usb_interface *udev
- 
- 	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
- 	
--	SET_NETDEV_DEV(dev->net, &dev->udev->dev);
-+	SET_NETDEV_DEV(dev->net, &udev->dev);
- 	status = register_netdev (dev->net);
- 	if (status)
- 		goto out3;
---- linux-2.6.0-test1/drivers/usb/serial/ftdi_sio.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/serial/ftdi_sio.c	2003-07-19 17:03:50.000000000 -0700
-@@ -257,6 +257,7 @@ static struct usb_device_id id_table_8U2
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) },
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) },
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) },
-+	{ USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0, 0x3ff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0, 0x3ff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0, 0x3ff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0, 0x3ff) },
-@@ -321,6 +322,7 @@ static struct usb_device_id id_table_FT2
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) },
-+	{ USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
-@@ -396,6 +398,7 @@ static __devinitdata struct usb_device_i
- 	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
-+	{ USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
- 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
- 	{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
- 	{ USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID) },
---- linux-2.6.0-test1/drivers/usb/serial/ftdi_sio.h	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/serial/ftdi_sio.h	2003-07-19 17:03:50.000000000 -0700
-@@ -105,7 +105,13 @@
- #define SEALEVEL_2803_6_PID	0X2863 	/* SeaLINK+8 (2803) Port 6 */
- #define SEALEVEL_2803_7_PID	0X2873 	/* SeaLINK+8 (2803) Port 7 */
- #define SEALEVEL_2803_8_PID	0X2883 	/* SeaLINK+8 (2803) Port 8 */
-+
-+/*
-+ * DSS-20 Sync Station for Sony Ericsson P800
-+ */
-  
-+#define FTDI_DSS20_PID          0xFC82  
-+
- /*
-  * Home Electronics (www.home-electro.com) USB gadgets
-  */
---- linux-2.6.0-test1/drivers/usb/serial/ipaq.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/usb/serial/ipaq.c	2003-07-19 17:03:50.000000000 -0700
-@@ -125,10 +125,13 @@ static struct usb_device_id ipaq_id_tabl
- 	{ USB_DEVICE(LINKUP_VENDOR_ID, LINKUP_PRODUCT_ID) },
- 	{ USB_DEVICE(MICROSOFT_VENDOR_ID, MICROSOFT_00CE_ID) },
- 	{ USB_DEVICE(PORTATEC_VENDOR_ID, PORTATEC_PRODUCT_ID) },
-+	{ USB_DEVICE(ROVER_VENDOR_ID, ROVER_P5_ID) },
- 	{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) },
- 	{ USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) },
- 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) },
-+	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E310_ID) },
- 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) },
-+	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E335_ID) },
- 	{ USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) },
- 	{ USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) },
- 	{ USB_DEVICE(ASUS_VENDOR_ID, ASUS_A600_PRODUCT_ID) },
---- linux-2.6.0-test1/drivers/usb/serial/ipaq.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/usb/serial/ipaq.h	2003-07-19 17:03:50.000000000 -0700
-@@ -61,6 +61,9 @@
- #define PORTATEC_VENDOR_ID	0x0961
- #define PORTATEC_PRODUCT_ID	0x0010
- 
-+#define ROVER_VENDOR_ID		0x047b
-+#define ROVER_P5_ID		0x3000
-+
- #define SAGEM_VENDOR_ID		0x5e04
- #define SAGEM_WIRELESS_ID	0xce00
- 
-@@ -69,7 +72,9 @@
- 
- #define TOSHIBA_VENDOR_ID	0x0930
- #define TOSHIBA_PRODUCT_ID	0x0700
-+#define TOSHIBA_E310_ID		0x0705
- #define TOSHIBA_E740_ID		0x0706
-+#define TOSHIBA_E335_ID		0x0707
- 
- #define HTC_VENDOR_ID		0x0bb4
- #define HTC_PRODUCT_ID		0x00ce
---- linux-2.6.0-test1/drivers/usb/serial/usb-serial.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/usb/serial/usb-serial.c	2003-07-19 17:03:50.000000000 -0700
-@@ -530,7 +530,9 @@ static void serial_close(struct tty_stru
- 	/* if disconnect beat us to the punch here, there's nothing to do */
- 	if (tty && tty->driver_data) {
- 		__serial_close(port, filp);
-+		tty->driver_data = NULL;
- 	}
-+	port->tty = NULL;
- }
- 
- static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
---- linux-2.6.0-test1/drivers/usb/serial/visor.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/serial/visor.c	2003-07-19 17:03:50.000000000 -0700
-@@ -509,18 +509,17 @@ static void visor_write_bulk_callback (s
- {
- 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- 
-+	/* free up the transfer buffer, as usb_free_urb() does not do this */
-+	kfree (urb->transfer_buffer);
-+
- 	if (port_paranoia_check (port, __FUNCTION__))
- 		return;
- 	
- 	dbg("%s - port %d", __FUNCTION__, port->number);
- 	
--	if (urb->status) {
--		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
--		return;
--	}
--
--	/* free up the transfer buffer, as usb_free_urb() does not do this */
--	kfree (urb->transfer_buffer);
-+	if (urb->status)
-+		dbg("%s - nonzero write bulk status received: %d",
-+		    __FUNCTION__, urb->status);
- 
- 	schedule_work(&port->work);
- }
---- linux-2.6.0-test1/drivers/usb/storage/debug.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/usb/storage/debug.h	2003-07-19 17:03:50.000000000 -0700
-@@ -46,7 +46,6 @@
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
--#include <linux/blk.h>
- #include <linux/cdrom.h>
- #include "usb.h"
- 
---- linux-2.6.0-test1/drivers/usb/storage/isd200.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/storage/isd200.c	2003-07-19 17:03:50.000000000 -0700
-@@ -280,6 +280,7 @@ struct isd200_info {
- 
- 	/* maximum number of LUNs supported */
- 	unsigned char MaxLUNs;
-+	struct scsi_cmnd srb;
- };
- 
- 
-@@ -404,15 +405,15 @@ static int isd200_action( struct us_data
- 			  void* pointer, int value )
- {
- 	union ata_cdb ata;
--	struct scsi_cmnd srb;
- 	struct scsi_device srb_dev;
- 	struct isd200_info *info = (struct isd200_info *)us->extra;
-+	struct scsi_cmnd *srb = &info->srb;
- 	int status;
- 
- 	memset(&ata, 0, sizeof(ata));
--	memset(&srb, 0, sizeof(srb));
- 	memset(&srb_dev, 0, sizeof(srb_dev));
--	srb.device = &srb_dev;
-+	srb->device = &srb_dev;
-+	++srb->serial_number;
- 
- 	ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
- 	ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
-@@ -425,9 +426,9 @@ static int isd200_action( struct us_data
- 		ata.generic.RegisterSelect =
- 		  REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
- 		  REG_STATUS | REG_ERROR;
--		srb.sc_data_direction = SCSI_DATA_READ;
--		srb.request_buffer = pointer;
--		srb.request_bufflen = value;
-+		srb->sc_data_direction = SCSI_DATA_READ;
-+		srb->request_buffer = pointer;
-+		srb->request_bufflen = value;
- 		break;
- 
- 	case ACTION_ENUM:
-@@ -437,7 +438,7 @@ static int isd200_action( struct us_data
- 					   ACTION_SELECT_5;
- 		ata.generic.RegisterSelect = REG_DEVICE_HEAD;
- 		ata.write.DeviceHeadByte = value;
--		srb.sc_data_direction = SCSI_DATA_NONE;
-+		srb->sc_data_direction = SCSI_DATA_NONE;
- 		break;
- 
- 	case ACTION_RESET:
-@@ -446,7 +447,7 @@ static int isd200_action( struct us_data
- 					   ACTION_SELECT_3|ACTION_SELECT_4;
- 		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
- 		ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER;
--		srb.sc_data_direction = SCSI_DATA_NONE;
-+		srb->sc_data_direction = SCSI_DATA_NONE;
- 		break;
- 
- 	case ACTION_REENABLE:
-@@ -455,7 +456,7 @@ static int isd200_action( struct us_data
- 					   ACTION_SELECT_3|ACTION_SELECT_4;
- 		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
- 		ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER;
--		srb.sc_data_direction = SCSI_DATA_NONE;
-+		srb->sc_data_direction = SCSI_DATA_NONE;
- 		break;
- 
- 	case ACTION_SOFT_RESET:
-@@ -464,16 +465,16 @@ static int isd200_action( struct us_data
- 		ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
- 		ata.write.DeviceHeadByte = info->DeviceHead;
- 		ata.write.CommandByte = WIN_SRST;
--		srb.sc_data_direction = SCSI_DATA_NONE;
-+		srb->sc_data_direction = SCSI_DATA_NONE;
- 		break;
- 
- 	case ACTION_IDENTIFY:
- 		US_DEBUGP("   isd200_action(IDENTIFY)\n");
- 		ata.generic.RegisterSelect = REG_COMMAND;
- 		ata.write.CommandByte = WIN_IDENTIFY;
--		srb.sc_data_direction = SCSI_DATA_READ;
--		srb.request_buffer = (void *)&info->drive;
--		srb.request_bufflen = sizeof(struct hd_driveid);
-+		srb->sc_data_direction = SCSI_DATA_READ;
-+		srb->request_buffer = (void *)&info->drive;
-+		srb->request_bufflen = sizeof(struct hd_driveid);
- 		break;
- 
- 	default:
-@@ -481,9 +482,9 @@ static int isd200_action( struct us_data
- 		break;
- 	}
- 
--	memcpy(srb.cmnd, &ata, sizeof(ata.generic));
--	srb.cmd_len = sizeof(ata.generic);
--	status = usb_stor_Bulk_transport(&srb, us);
-+	memcpy(srb->cmnd, &ata, sizeof(ata.generic));
-+	srb->cmd_len = sizeof(ata.generic);
-+	status = usb_stor_Bulk_transport(srb, us);
- 	if (status == USB_STOR_TRANSPORT_GOOD)
- 		status = ISD200_GOOD;
- 	else {
-@@ -834,7 +835,7 @@ static int isd200_try_enum(struct us_dat
- 			   int detect )
- {
- 	int status = ISD200_GOOD;
--	unsigned char regs[8];
-+	unsigned char *regs = us->iobuf;
- 	unsigned long endTime;
- 	struct isd200_info *info = (struct isd200_info *)us->extra;
- 	int recheckAsMaster = FALSE;
-@@ -856,7 +857,7 @@ static int isd200_try_enum(struct us_dat
- 			break;
- 
- 		status = isd200_action( us, ACTION_READ_STATUS, 
--					regs, sizeof(regs) );
-+					regs, 8 );
- 		if ( status != ISD200_GOOD )
- 			break;
- 
---- linux-2.6.0-test1/drivers/usb/storage/jumpshot.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/usb/storage/jumpshot.c	2003-07-19 17:03:50.000000000 -0700
-@@ -86,7 +86,6 @@ static inline int jumpshot_bulk_write(st
- 
- static int jumpshot_get_status(struct us_data  *us)
- {
--	unsigned char reply;
- 	int rc;
- 
- 	if (!us)
-@@ -94,14 +93,14 @@ static int jumpshot_get_status(struct us
- 
- 	// send the setup
- 	rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
--				   0, 0xA0, 0, 7, &reply, 1);
-+				   0, 0xA0, 0, 7, us->iobuf, 1);
- 
- 	if (rc != USB_STOR_XFER_GOOD)
- 		return USB_STOR_TRANSPORT_ERROR;
- 
--	if (reply != 0x50) {
-+	if (us->iobuf[0] != 0x50) {
- 		US_DEBUGP("jumpshot_get_status:  0x%2x\n",
--			  (unsigned short) (reply));
-+			  us->iobuf[0]);
- 		return USB_STOR_TRANSPORT_ERROR;
- 	}
- 
-@@ -115,7 +114,7 @@ static int jumpshot_read_data(struct us_
- 			      unsigned char *dest, 
- 			      int use_sg)
- {
--	unsigned char command[] = { 0, 0, 0, 0, 0, 0xe0, 0x20 };
-+	unsigned char *command = us->iobuf;
- 	unsigned char *buffer = NULL;
- 	unsigned char *ptr;
- 	unsigned char  thistime;
-@@ -154,7 +153,8 @@ static int jumpshot_read_data(struct us_
- 		command[3] = (sector >>  8) & 0xFF;
- 		command[4] = (sector >> 16) & 0xFF;
- 
--		command[5] |= (sector >> 24) & 0x0F;
-+		command[5] = 0xE0 | ((sector >> 24) & 0x0F);
-+		command[6] = 0x20;
- 
- 		// send the setup + command
- 		result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
-@@ -199,7 +199,7 @@ static int jumpshot_write_data(struct us
- 			       unsigned char *src, 
- 			       int use_sg)
- {
--	unsigned char command[7] = { 0, 0, 0, 0, 0, 0xE0, 0x30 };
-+	unsigned char *command = us->iobuf;
- 	unsigned char *buffer = NULL;
- 	unsigned char *ptr;
- 	unsigned char  thistime;
-@@ -240,7 +240,8 @@ static int jumpshot_write_data(struct us
- 		command[3] = (sector >>  8) & 0xFF;
- 		command[4] = (sector >> 16) & 0xFF;
- 
--		command[5] |= (sector >> 24) & 0x0F;
-+		command[5] = 0xE0 | ((sector >> 24) & 0x0F);
-+		command[6] = 0x30;
- 
- 		// send the setup + command
- 		result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
-@@ -291,13 +292,19 @@ static int jumpshot_write_data(struct us
- static int jumpshot_id_device(struct us_data *us,
- 			      struct jumpshot_info *info)
- {
--	unsigned char command[2] = { 0xe0, 0xec };
--	unsigned char reply[512];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *reply;
- 	int 	 rc;
- 
- 	if (!us || !info)
- 		return USB_STOR_TRANSPORT_ERROR;
- 
-+	command[0] = 0xE0;
-+	command[1] = 0xEC;
-+	reply = kmalloc(512, GFP_NOIO);
-+	if (!reply)
-+		return USB_STOR_TRANSPORT_ERROR;
-+
- 	// send the setup
- 	rc = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
- 				   0, 0x20, 0, 6, command, 2);
-@@ -305,20 +312,27 @@ static int jumpshot_id_device(struct us_
- 	if (rc != USB_STOR_XFER_GOOD) {
- 		US_DEBUGP("jumpshot_id_device:  Gah! "
- 			  "send_control for read_capacity failed\n");
--		return rc;
-+		rc = USB_STOR_TRANSPORT_ERROR;
-+		goto leave;
- 	}
- 
- 	// read the reply
- 	rc = jumpshot_bulk_read(us, reply, sizeof(reply));
--	if (rc != USB_STOR_XFER_GOOD)
--		return USB_STOR_TRANSPORT_ERROR;
-+	if (rc != USB_STOR_XFER_GOOD) {
-+		rc = USB_STOR_TRANSPORT_ERROR;
-+		goto leave;
-+	}
- 
- 	info->sectors = ((u32)(reply[117]) << 24) |
- 			((u32)(reply[116]) << 16) |
- 			((u32)(reply[115]) <<  8) |
- 			((u32)(reply[114])      );
- 
--	return USB_STOR_TRANSPORT_GOOD;
-+	rc = USB_STOR_TRANSPORT_GOOD;
-+
-+ leave:
-+	kfree(reply);
-+	return rc;
- }
- 
- static int jumpshot_handle_mode_sense(struct us_data *us,
---- linux-2.6.0-test1/drivers/usb/storage/protocol.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/storage/protocol.c	2003-07-19 17:03:50.000000000 -0700
-@@ -130,8 +130,9 @@ static void fix_read_capacity(Scsi_Cmnd 
- void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us)
- {
- 	/* Pad the ATAPI command with zeros 
-+	 *
- 	 * NOTE: This only works because a Scsi_Cmnd struct field contains
--	 * a unsigned char cmnd[12], so we know we have storage available
-+	 * a unsigned char cmnd[16], so we know we have storage available
- 	 */
- 	for (; srb->cmd_len<12; srb->cmd_len++)
- 		srb->cmnd[srb->cmd_len] = 0;
-@@ -149,13 +150,10 @@ void usb_stor_qic157_command(Scsi_Cmnd *
- 
- void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
- {
--	int old_cmnd = 0;
--
--	/* Fix some commands -- this is a form of mode translation
--	 * ATAPI devices only accept 12 byte long commands 
-+	/* Pad the ATAPI command with zeros 
- 	 *
- 	 * NOTE: This only works because a Scsi_Cmnd struct field contains
--	 * a unsigned char cmnd[12], so we know we have storage available
-+	 * a unsigned char cmnd[16], so we know we have storage available
- 	 */
- 
- 	/* Pad the ATAPI command with zeros */
-@@ -165,60 +163,10 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *s
- 	/* set command length to 12 bytes */
- 	srb->cmd_len = 12;
- 
--	/* determine the correct (or minimum) data length for these commands */
--	switch (srb->cmnd[0]) {
--
--		/* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
--	case MODE_SENSE:
--	case MODE_SELECT:
--		/* save the command so we can tell what it was */
--		old_cmnd = srb->cmnd[0];
--
--		srb->cmnd[11] = 0;
--		srb->cmnd[10] = 0;
--		srb->cmnd[9] = 0;
--		srb->cmnd[8] = srb->cmnd[4];
--		srb->cmnd[7] = 0;
--		srb->cmnd[6] = 0;
--		srb->cmnd[5] = 0;
--		srb->cmnd[4] = 0;
--		srb->cmnd[3] = 0;
--		srb->cmnd[2] = srb->cmnd[2];
--		srb->cmnd[1] = srb->cmnd[1];
--		srb->cmnd[0] = srb->cmnd[0] | 0x40;
--		break;
--
--		/* change READ_6/WRITE_6 to READ_10/WRITE_10, which 
--		 * are ATAPI commands */
--	case WRITE_6:
--	case READ_6:
--		srb->cmnd[11] = 0;
--		srb->cmnd[10] = 0;
--		srb->cmnd[9] = 0;
--		srb->cmnd[8] = srb->cmnd[4];
--		srb->cmnd[7] = 0;
--		srb->cmnd[6] = 0;
--		srb->cmnd[5] = srb->cmnd[3];
--		srb->cmnd[4] = srb->cmnd[2];
--		srb->cmnd[3] = srb->cmnd[1] & 0x1F;
--		srb->cmnd[2] = 0;
--		srb->cmnd[1] = srb->cmnd[1] & 0xE0;
--		srb->cmnd[0] = srb->cmnd[0] | 0x20;
--		break;
--	} /* end switch on cmnd[0] */
--
--	/* convert MODE_SELECT data here */
--	if (old_cmnd == MODE_SELECT)
--		usb_stor_scsiSense6to10(srb);
--
- 	/* send the command to the transport layer */
- 	usb_stor_invoke_transport(srb, us);
--	if (srb->result == SAM_STAT_GOOD) {
--
--		/* Fix the MODE_SENSE data if we translated the command */
--		if (old_cmnd == MODE_SENSE)
--			usb_stor_scsiSense10to6(srb);
- 
-+	if (srb->result == SAM_STAT_GOOD) {
- 		/* fix the INQUIRY data if necessary */
- 		fix_inquiry_data(srb);
- 	}
-@@ -227,19 +175,23 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *s
- 
- void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us)
- {
--	int old_cmnd = 0;
--
- 	/* fix some commands -- this is a form of mode translation
- 	 * UFI devices only accept 12 byte long commands 
- 	 *
- 	 * NOTE: This only works because a Scsi_Cmnd struct field contains
--	 * a unsigned char cmnd[12], so we know we have storage available
-+	 * a unsigned char cmnd[16], so we know we have storage available
- 	 */
- 
-+	/* Pad the ATAPI command with zeros */
-+	for (; srb->cmd_len<12; srb->cmd_len++)
-+		srb->cmnd[srb->cmd_len] = 0;
-+
- 	/* set command length to 12 bytes (this affects the transport layer) */
- 	srb->cmd_len = 12;
- 
--	/* determine the correct (or minimum) data length for these commands */
-+	/* XXX We should be constantly re-evaluating the need for these */
-+
-+	/* determine the correct data length for these commands */
- 	switch (srb->cmnd[0]) {
- 
- 		/* for INQUIRY, UFI devices only ever return 36 bytes */
-@@ -247,33 +199,6 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb
- 		srb->cmnd[4] = 36;
- 		break;
- 
--		/* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
--	case MODE_SENSE:
--	case MODE_SELECT:
--		/* save the command so we can tell what it was */
--		old_cmnd = srb->cmnd[0];
--
--		srb->cmnd[11] = 0;
--		srb->cmnd[10] = 0;
--		srb->cmnd[9] = 0;
--
--		/* if we're sending data, we send all.	If getting data, 
--		 * get the minimum */
--		if (srb->cmnd[0] == MODE_SELECT)
--			srb->cmnd[8] = srb->cmnd[4];
--		else
--			srb->cmnd[8] = 8;
--
--		srb->cmnd[7] = 0;
--		srb->cmnd[6] = 0;
--		srb->cmnd[5] = 0;
--		srb->cmnd[4] = 0;
--		srb->cmnd[3] = 0;
--		srb->cmnd[2] = srb->cmnd[2];
--		srb->cmnd[1] = srb->cmnd[1];
--		srb->cmnd[0] = srb->cmnd[0] | 0x40;
--		break;
--
- 		/* again, for MODE_SENSE_10, we get the minimum (8) */
- 	case MODE_SENSE_10:
- 		srb->cmnd[7] = 0;
-@@ -284,38 +209,12 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb
- 	case REQUEST_SENSE:
- 		srb->cmnd[4] = 18;
- 		break;
--
--		/* change READ_6/WRITE_6 to READ_10/WRITE_10, which 
--		 * are UFI commands */
--	case WRITE_6:
--	case READ_6:
--		srb->cmnd[11] = 0;
--		srb->cmnd[10] = 0;
--		srb->cmnd[9] = 0;
--		srb->cmnd[8] = srb->cmnd[4];
--		srb->cmnd[7] = 0;
--		srb->cmnd[6] = 0;
--		srb->cmnd[5] = srb->cmnd[3];
--		srb->cmnd[4] = srb->cmnd[2];
--		srb->cmnd[3] = srb->cmnd[1] & 0x1F;
--		srb->cmnd[2] = 0;
--		srb->cmnd[1] = srb->cmnd[1] & 0xE0;
--		srb->cmnd[0] = srb->cmnd[0] | 0x20;
--		break;
- 	} /* end switch on cmnd[0] */
- 
--	/* convert MODE_SELECT data here */
--	if (old_cmnd == MODE_SELECT)
--		usb_stor_scsiSense6to10(srb);
--
- 	/* send the command to the transport layer */
- 	usb_stor_invoke_transport(srb, us);
--	if (srb->result == SAM_STAT_GOOD) {
--
--		/* Fix the MODE_SENSE data if we translated the command */
--		if (old_cmnd == MODE_SENSE)
--			usb_stor_scsiSense10to6(srb);
- 
-+	if (srb->result == SAM_STAT_GOOD) {
- 		/* Fix the data for an INQUIRY, if necessary */
- 		fix_inquiry_data(srb);
- 	}
-@@ -323,68 +222,10 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb
- 
- void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
- {
--	int old_cmnd = 0;
--
--	/* This code supports devices which do not support {READ|WRITE}_6
--	 * Apparently, neither Windows or MacOS will use these commands,
--	 * so some devices do not support them
--	 */
--	if (us->flags & US_FL_MODE_XLATE) {
--		US_DEBUGP("Invoking Mode Translation\n");
--		/* save the old command for later */
--		old_cmnd = srb->cmnd[0];
--
--		switch (srb->cmnd[0]) {
--		/* change READ_6/WRITE_6 to READ_10/WRITE_10 */
--		case WRITE_6:
--		case READ_6:
--			srb->cmd_len = 12;
--			srb->cmnd[11] = 0;
--			srb->cmnd[10] = 0;
--			srb->cmnd[9] = 0;
--			srb->cmnd[8] = srb->cmnd[4];
--			srb->cmnd[7] = 0;
--			srb->cmnd[6] = 0;
--			srb->cmnd[5] = srb->cmnd[3];
--			srb->cmnd[4] = srb->cmnd[2];
--			srb->cmnd[3] = srb->cmnd[1] & 0x1F;
--			srb->cmnd[2] = 0;
--			srb->cmnd[1] = srb->cmnd[1] & 0xE0;
--			srb->cmnd[0] = srb->cmnd[0] | 0x20;
--			break;
--
--		/* convert MODE_SELECT data here */
--		case MODE_SENSE:
--		case MODE_SELECT:
--			srb->cmd_len = 12;
--			srb->cmnd[11] = 0;
--			srb->cmnd[10] = 0;
--			srb->cmnd[9] = 0;
--			srb->cmnd[8] = srb->cmnd[4];
--			srb->cmnd[7] = 0;
--			srb->cmnd[6] = 0;
--			srb->cmnd[5] = 0;
--			srb->cmnd[4] = 0;
--			srb->cmnd[3] = 0;
--			srb->cmnd[2] = srb->cmnd[2];
--			srb->cmnd[1] = srb->cmnd[1];
--			srb->cmnd[0] = srb->cmnd[0] | 0x40;
--			break;
--		} /* switch (srb->cmnd[0]) */
--	} /* if (us->flags & US_FL_MODE_XLATE) */
--
--	/* convert MODE_SELECT data here */
--	if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SELECT))
--		usb_stor_scsiSense6to10(srb);
--
- 	/* send the command to the transport layer */
- 	usb_stor_invoke_transport(srb, us);
--	if (srb->result == SAM_STAT_GOOD) {
--
--		/* Fix the MODE_SENSE data if we translated the command */
--		if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE))
--			usb_stor_scsiSense10to6(srb);
- 
-+	if (srb->result == SAM_STAT_GOOD) {
- 		/* Fix the INQUIRY data if necessary */
- 		fix_inquiry_data(srb);
- 
---- linux-2.6.0-test1/drivers/usb/storage/protocol.h	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/storage/protocol.h	2003-07-19 17:03:50.000000000 -0700
-@@ -41,7 +41,7 @@
- #ifndef _PROTOCOL_H_
- #define _PROTOCOL_H_
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "usb.h"
- 
---- linux-2.6.0-test1/drivers/usb/storage/scsiglue.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/storage/scsiglue.c	2003-07-19 17:03:50.000000000 -0700
-@@ -263,7 +263,6 @@ static int proc_info (struct Scsi_Host *
- 
- #define DO_FLAG(a)  	if (f & US_FL_##a)  pos += sprintf(pos, " " #a)
- 		DO_FLAG(SINGLE_LUN);
--		DO_FLAG(MODE_XLATE);
- 		DO_FLAG(SCM_MULT_TARG);
- 		DO_FLAG(FIX_INQUIRY);
- 		DO_FLAG(FIX_CAPACITY);
-@@ -346,499 +345,3 @@ unsigned char usb_stor_sense_invalidCDB[
- 	[12]	= 0x24			    /* Invalid Field in CDB */
- };
- 
--#define USB_STOR_SCSI_SENSE_HDRSZ 4
--#define USB_STOR_SCSI_SENSE_10_HDRSZ 8
--
--struct usb_stor_scsi_sense_hdr
--{
--  __u8* dataLength;
--  __u8* mediumType;
--  __u8* devSpecParms;
--  __u8* blkDescLength;
--};
--
--typedef struct usb_stor_scsi_sense_hdr Usb_Stor_Scsi_Sense_Hdr;
--
--union usb_stor_scsi_sense_hdr_u
--{
--  Usb_Stor_Scsi_Sense_Hdr hdr;
--  __u8* array[USB_STOR_SCSI_SENSE_HDRSZ];
--};
--
--typedef union usb_stor_scsi_sense_hdr_u Usb_Stor_Scsi_Sense_Hdr_u;
--
--struct usb_stor_scsi_sense_hdr_10
--{
--  __u8* dataLengthMSB;
--  __u8* dataLengthLSB;
--  __u8* mediumType;
--  __u8* devSpecParms;
--  __u8* reserved1;
--  __u8* reserved2;
--  __u8* blkDescLengthMSB;
--  __u8* blkDescLengthLSB;
--};
--
--typedef struct usb_stor_scsi_sense_hdr_10 Usb_Stor_Scsi_Sense_Hdr_10;
--
--union usb_stor_scsi_sense_hdr_10_u
--{
--  Usb_Stor_Scsi_Sense_Hdr_10 hdr;
--  __u8* array[USB_STOR_SCSI_SENSE_10_HDRSZ];
--};
--
--typedef union usb_stor_scsi_sense_hdr_10_u Usb_Stor_Scsi_Sense_Hdr_10_u;
--
--void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* , Usb_Stor_Scsi_Sense_Hdr_u*,
--				    Usb_Stor_Scsi_Sense_Hdr_10_u*, int* );
--
--int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 )
--{
--  __u8 *buffer=0;
--  int outputBufferSize = 0;
--  int length=0;
--  struct scatterlist *sg = 0;
--  int i=0, j=0, element=0;
--  Usb_Stor_Scsi_Sense_Hdr_u the6Locations;
--  Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations;
--  int sb=0,si=0,db=0,di=0;
--  int sgLength=0;
--
--  US_DEBUGP("-- converting 10 byte sense data to 6 byte\n");
--  the10->cmnd[0] = the10->cmnd[0] & 0xBF;
--
--  /* Determine buffer locations */
--  usb_stor_scsiSenseParseBuffer( the10, &the6Locations, &the10Locations,
--				 &length );
--
--  /* Work out minimum buffer to output */
--  outputBufferSize = *the10Locations.hdr.dataLengthLSB;
--  outputBufferSize += USB_STOR_SCSI_SENSE_HDRSZ;
--
--  /* Check to see if we need to trucate the output */
--  if ( outputBufferSize > length )
--    {
--      printk( KERN_WARNING USB_STORAGE 
--	      "Had to truncate MODE_SENSE_10 buffer into MODE_SENSE.\n" );
--      printk( KERN_WARNING USB_STORAGE
--	      "outputBufferSize is %d and length is %d.\n",
--	      outputBufferSize, length );
--    }
--  outputBufferSize = length;
--
--  /* Data length */
--  if ( *the10Locations.hdr.dataLengthMSB != 0 ) /* MSB must be zero */
--    {
--      printk( KERN_WARNING USB_STORAGE 
--	      "Command will be truncated to fit in SENSE6 buffer.\n" );
--      *the6Locations.hdr.dataLength = 0xff;
--    }
--  else
--    {
--      *the6Locations.hdr.dataLength = *the10Locations.hdr.dataLengthLSB;
--    }
--
--  /* Medium type and DevSpecific parms */
--  *the6Locations.hdr.mediumType = *the10Locations.hdr.mediumType;
--  *the6Locations.hdr.devSpecParms = *the10Locations.hdr.devSpecParms;
--
--  /* Block descriptor length */
--  if ( *the10Locations.hdr.blkDescLengthMSB != 0 ) /* MSB must be zero */
--    {
--      printk( KERN_WARNING USB_STORAGE 
--	      "Command will be truncated to fit in SENSE6 buffer.\n" );
--      *the6Locations.hdr.blkDescLength = 0xff;
--    }
--  else
--    {
--      *the6Locations.hdr.blkDescLength = *the10Locations.hdr.blkDescLengthLSB;
--    }
--
--  if ( the10->use_sg == 0 )
--    {
--      buffer = the10->request_buffer;
--      /* Copy the rest of the data */
--      memmove( &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]),
--	       &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
--	       outputBufferSize - USB_STOR_SCSI_SENSE_HDRSZ );
--      /* initialise last bytes left in buffer due to smaller header */
--      memset( &(buffer[outputBufferSize
--	    -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ)]),
--	      0,
--	      USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ );
--    }
--  else
--    {
--      sg = (struct scatterlist *) the10->request_buffer;
--      /* scan through this scatterlist and figure out starting positions */
--      for ( i=0; i < the10->use_sg; i++)
--	{
--	  sgLength = sg[i].length;
--	  for ( j=0; j<sgLength; j++ )
--	    {
--	      /* get to end of header */
--	      if ( element == USB_STOR_SCSI_SENSE_HDRSZ )
--		{
--		  db=i;
--		  di=j;
--		}
--	      if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ )
--		{
--		  sb=i;
--		  si=j;
--		  /* we've found both sets now, exit loops */
--		  j=sgLength;
--		  i=the10->use_sg;
--		}
--	      element++;
--	    }
--	}
--
--      /* Now we know where to start the copy from */
--      element = USB_STOR_SCSI_SENSE_HDRSZ;
--      while ( element < outputBufferSize
--	      -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) )
--	{
--	  /* check limits */
--	  if ( sb >= the10->use_sg ||
--	       si >= sg[sb].length ||
--	       db >= the10->use_sg ||
--	       di >= sg[db].length )
--	    {
--	      printk( KERN_ERR USB_STORAGE
--		      "Buffer overrun averted, this shouldn't happen!\n" );
--	      break;
--	    }
--
--	  /* copy one byte */
--	  {
--		char *src = sg_address(sg[sb]) + si;
--		char *dst = sg_address(sg[db]) + di;
--
--		 *dst = *src;
--	  }
--
--	  /* get next destination */
--	  if ( sg[db].length-1 == di )
--	    {
--	      db++;
--	      di=0;
--	    }
--	  else
--	    {
--	      di++;
--	    }
--
--	  /* get next source */
--	  if ( sg[sb].length-1 == si )
--	    {
--	      sb++;
--	      si=0;
--	    }
--	  else
--	    {
--	      si++;
--	    }
--
--	  element++;
--	}
--      /* zero the remaining bytes */
--      while ( element < outputBufferSize )
--	{
--	  /* check limits */
--	  if ( db >= the10->use_sg ||
--	       di >= sg[db].length )
--	    {
--	      printk( KERN_ERR USB_STORAGE
--		      "Buffer overrun averted, this shouldn't happen!\n" );
--	      break;
--	    }
--
--	  *(char*)(sg_address(sg[db])) = 0;
--
--	  /* get next destination */
--	  if ( sg[db].length-1 == di )
--	    {
--	      db++;
--	      di=0;
--	    }
--	  else
--	    {
--	      di++;
--	    }
--	  element++;
--	}
--    }
--
--  /* All done any everything was fine */
--  return 0;
--}
--
--int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
--{
--  /* will be used to store part of buffer */  
--  __u8 tempBuffer[USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ],
--    *buffer=0;
--  int outputBufferSize = 0;
--  int length=0;
--  struct scatterlist *sg = 0;
--  int i=0, j=0, element=0;
--  Usb_Stor_Scsi_Sense_Hdr_u the6Locations;
--  Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations;
--  int sb=0,si=0,db=0,di=0;
--  int lsb=0,lsi=0,ldb=0,ldi=0;
--
--  US_DEBUGP("-- converting 6 byte sense data to 10 byte\n");
--  the6->cmnd[0] = the6->cmnd[0] | 0x40;
--
--  /* Determine buffer locations */
--  usb_stor_scsiSenseParseBuffer( the6, &the6Locations, &the10Locations,
--				 &length );
--
--  /* Work out minimum buffer to output */
--  outputBufferSize = *the6Locations.hdr.dataLength;
--  outputBufferSize += USB_STOR_SCSI_SENSE_10_HDRSZ;
--
--  /* Check to see if we need to trucate the output */
--  if ( outputBufferSize > length )
--    {
--      printk( KERN_WARNING USB_STORAGE 
--	      "Had to truncate MODE_SENSE into MODE_SENSE_10 buffer.\n" );
--      printk( KERN_WARNING USB_STORAGE
--	      "outputBufferSize is %d and length is %d.\n",
--	      outputBufferSize, length );
--    }
--  outputBufferSize = length;
--
--  /* Block descriptor length - save these before overwriting */
--  tempBuffer[2] = *the10Locations.hdr.blkDescLengthMSB;
--  tempBuffer[3] = *the10Locations.hdr.blkDescLengthLSB;
--  *the10Locations.hdr.blkDescLengthLSB = *the6Locations.hdr.blkDescLength;
--  *the10Locations.hdr.blkDescLengthMSB = 0;
--
--  /* reserved - save these before overwriting */
--  tempBuffer[0] = *the10Locations.hdr.reserved1;
--  tempBuffer[1] = *the10Locations.hdr.reserved2;
--  *the10Locations.hdr.reserved1 = *the10Locations.hdr.reserved2 = 0;
--
--  /* Medium type and DevSpecific parms */
--  *the10Locations.hdr.devSpecParms = *the6Locations.hdr.devSpecParms;
--  *the10Locations.hdr.mediumType = *the6Locations.hdr.mediumType;
--
--  /* Data length */
--  *the10Locations.hdr.dataLengthLSB = *the6Locations.hdr.dataLength;
--  *the10Locations.hdr.dataLengthMSB = 0;
--
--  if ( !the6->use_sg )
--    {
--      buffer = the6->request_buffer;
--      /* Copy the rest of the data */
--      memmove( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
--	      &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]),
--	      outputBufferSize-USB_STOR_SCSI_SENSE_10_HDRSZ );
--      /* Put the first four bytes (after header) in place */
--      memcpy( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
--	      tempBuffer,
--	      USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ );
--    }
--  else
--    {
--      sg = (struct scatterlist *) the6->request_buffer;
--      /* scan through this scatterlist and figure out ending positions */
--      for ( i=0; i < the6->use_sg; i++)
--	{
--	  for ( j=0; j<sg[i].length; j++ )
--	    {
--	      /* get to end of header */
--	      if ( element == USB_STOR_SCSI_SENSE_HDRSZ )
--		{
--		  ldb=i;
--		  ldi=j;
--		}
--	      if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ )
--		{
--		  lsb=i;
--		  lsi=j;
--		  /* we've found both sets now, exit loops */
--		  j=sg[i].length;
--		  i=the6->use_sg;
--		  break;
--		}
--	      element++;
--	    }
--	}
--      /* scan through this scatterlist and figure out starting positions */
--      element = length-1;
--      /* destination is the last element */
--      db=the6->use_sg-1;
--      di=sg[db].length-1;
--      for ( i=the6->use_sg-1; i >= 0; i--)
--	{
--	  for ( j=sg[i].length-1; j>=0; j-- )
--	    {
--	      /* get to end of header and find source for copy */
--	      if ( element == length - 1
--		   - (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) )
--		{
--		  sb=i;
--		  si=j;
--		  /* we've found both sets now, exit loops */
--		  j=-1;
--		  i=-1;
--		}
--	      element--;
--	    }
--	}
--      /* Now we know where to start the copy from */
--      element = length-1
--	- (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ);
--      while ( element >= USB_STOR_SCSI_SENSE_10_HDRSZ )
--	{
--	  /* check limits */
--	  if ( ( sb <= lsb && si < lsi ) ||
--	       ( db <= ldb && di < ldi ) )
--	    {
--	      printk( KERN_ERR USB_STORAGE
--		      "Buffer overrun averted, this shouldn't happen!\n" );
--	      break;
--	    }
--
--	  /* copy one byte */
--	  {
--		char *src = sg_address(sg[sb]) + si;
--		char *dst = sg_address(sg[db]) + di;
--
--		 *dst = *src;
--	  }
--
--	  /* get next destination */
--	  if ( di == 0 )
--	    {
--	      db--;
--	      di=sg[db].length-1;
--	    }
--	  else
--	    {
--	      di--;
--	    }
--
--	  /* get next source */
--	  if ( si == 0 )
--	    {
--	      sb--;
--	      si=sg[sb].length-1;
--	    }
--	  else
--	    {
--	      si--;
--	    }
--
--	  element--;
--	}
--      /* copy the remaining four bytes */
--      while ( element >= USB_STOR_SCSI_SENSE_HDRSZ )
--	{
--	  /* check limits */
--	  if ( db <= ldb && di < ldi )
--	    {
--	      printk( KERN_ERR USB_STORAGE
--		      "Buffer overrun averted, this shouldn't happen!\n" );
--	      break;
--	    }
--
--	 {
--		 char *dst = sg_address(sg[db]) + di;
--
--		 *dst = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ];
--	 }
--
--
--	  /* get next destination */
--	  if ( di == 0 )
--	    {
--	      db--;
--	      di=sg[db].length-1;
--	    }
--	  else
--	    {
--	      di--;
--	    }
--	  element--;
--	}
--    }
--
--  /* All done and everything was fine */
--  return 0;
--}
--
--void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* the6,
--			       Usb_Stor_Scsi_Sense_Hdr_10_u* the10,
--			       int* length_p )
--
--{
--  int i = 0, j=0, element=0;
--  struct scatterlist *sg = 0;
--  int length = 0;
--  __u8* buffer=0;
--
--  /* are we scatter-gathering? */
--  if ( srb->use_sg != 0 )
--    {
--      /* loop over all the scatter gather structures and 
--       * get pointer to the data members in the headers
--       * (also work out the length while we're here)
--       */
--      sg = (struct scatterlist *) srb->request_buffer;
--      for (i = 0; i < srb->use_sg; i++)
--	{
--	  length += sg[i].length;
--	  /* We only do the inner loop for the headers */
--	  if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ )
--	    {
--	      /* scan through this scatterlist */
--	      for ( j=0; j<sg[i].length; j++ )
--		{
--		  if ( element < USB_STOR_SCSI_SENSE_HDRSZ )
--		    {
--		      /* fill in the pointers for both header types */
--		      the6->array[element] = sg_address(sg[i]) + j;
--		      the10->array[element] = sg_address(sg[i]) + j;
--
--		    }
--		  else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ )
--		    {
--		      /* only the longer headers still cares now */
--		      the10->array[element] = sg_address(sg[i]) + j;
--		       
--		    }
--		  /* increase element counter */
--		  element++;
--		}
--	    }
--	}
--    }
--  else
--    {
--      length = srb->request_bufflen;
--      buffer = srb->request_buffer;
--      if ( length < USB_STOR_SCSI_SENSE_10_HDRSZ )
--	printk( KERN_ERR USB_STORAGE
--		"Buffer length smaller than header!!" );
--      for( i=0; i<USB_STOR_SCSI_SENSE_10_HDRSZ; i++ )
--	{
--	  if ( i < USB_STOR_SCSI_SENSE_HDRSZ )
--	    {
--	      the6->array[i] = &(buffer[i]);
--	      the10->array[i] = &(buffer[i]);
--	    }
--	  else
--	    {
--	      the10->array[i] = &(buffer[i]);
--	    }
--	}
--    }
--
--  /* Set value of length passed in */
--  *length_p = length;
--}
--
---- linux-2.6.0-test1/drivers/usb/storage/scsiglue.h	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/storage/scsiglue.h	2003-07-19 17:03:50.000000000 -0700
-@@ -41,7 +41,7 @@
- #ifndef _SCSIGLUE_H_
- #define _SCSIGLUE_H_
- 
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "scsi.h"
- #include "hosts.h"
- 
---- linux-2.6.0-test1/drivers/usb/storage/sddr09.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/usb/storage/sddr09.c	2003-07-19 17:03:50.000000000 -0700
-@@ -261,12 +261,13 @@ sddr09_send_scsi_command(struct us_data 
-  */
- static int
- sddr09_test_unit_ready(struct us_data *us) {
--	unsigned char command[6] = {
--		0, LUNBITS, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result;
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	memset(command, 0, 6);
-+	command[1] = LUNBITS;
-+
-+	result = sddr09_send_scsi_command(us, command, 6);
- 
- 	US_DEBUGP("sddr09_test_unit_ready returns %d\n", result);
- 
-@@ -281,12 +282,15 @@ sddr09_test_unit_ready(struct us_data *u
-  */
- static int
- sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) {
--	unsigned char command[12] = {
--		0x03, LUNBITS, 0, 0, buflen, 0, 0, 0, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result;
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	memset(command, 0, 12);
-+	command[0] = 0x03;
-+	command[1] = LUNBITS;
-+	command[4] = buflen;
-+
-+	result = sddr09_send_scsi_command(us, command, 12);
- 	if (result != USB_STOR_TRANSPORT_GOOD) {
- 		US_DEBUGP("request sense failed\n");
- 		return result;
-@@ -331,20 +335,23 @@ sddr09_readX(struct us_data *us, int x, 
- 	     int nr_of_pages, int bulklen, unsigned char *buf,
- 	     int use_sg) {
- 
--	unsigned char command[12] = {
--		0xe8, LUNBITS | x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result;
- 
-+	command[0] = 0xE8;
-+	command[1] = LUNBITS | x;
- 	command[2] = MSB_of(fromaddress>>16);
- 	command[3] = LSB_of(fromaddress>>16); 
- 	command[4] = MSB_of(fromaddress & 0xFFFF);
- 	command[5] = LSB_of(fromaddress & 0xFFFF); 
--
-+	command[6] = 0;
-+	command[7] = 0;
-+	command[8] = 0;
-+	command[9] = 0;
- 	command[10] = MSB_of(nr_of_pages);
- 	command[11] = LSB_of(nr_of_pages);
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	result = sddr09_send_scsi_command(us, command, 12);
- 
- 	if (result != USB_STOR_TRANSPORT_GOOD) {
- 		US_DEBUGP("Result for send_control in sddr09_read2%d %d\n",
-@@ -458,17 +465,18 @@ sddr09_read23(struct us_data *us, unsign
-  */
- static int
- sddr09_erase(struct us_data *us, unsigned long Eaddress) {
--	unsigned char command[12] = {
--		0xea, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result;
- 
-+	memset(command, 0, 12);
-+	command[0] = 0xEA;
-+	command[1] = LUNBITS;
- 	command[6] = MSB_of(Eaddress>>16);
- 	command[7] = LSB_of(Eaddress>>16);
- 	command[8] = MSB_of(Eaddress & 0xFFFF);
- 	command[9] = LSB_of(Eaddress & 0xFFFF);
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	result = sddr09_send_scsi_command(us, command, 12);
- 
- 	if (result != USB_STOR_TRANSPORT_GOOD)
- 		US_DEBUGP("Result for send_control in sddr09_erase %d\n",
-@@ -493,11 +501,12 @@ sddr09_writeX(struct us_data *us,
- 	      unsigned long Waddress, unsigned long Eaddress,
- 	      int nr_of_pages, int bulklen, unsigned char *buf, int use_sg) {
- 
--	unsigned char command[12] = {
--		0xe9, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result;
- 
-+	command[0] = 0xE9;
-+	command[1] = LUNBITS;
-+
- 	command[2] = MSB_of(Waddress>>16);
- 	command[3] = LSB_of(Waddress>>16);
- 	command[4] = MSB_of(Waddress & 0xFFFF);
-@@ -511,7 +520,7 @@ sddr09_writeX(struct us_data *us,
- 	command[10] = MSB_of(nr_of_pages);
- 	command[11] = LSB_of(nr_of_pages);
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	result = sddr09_send_scsi_command(us, command, 12);
- 
- 	if (result != USB_STOR_TRANSPORT_GOOD) {
- 		US_DEBUGP("Result for send_control in sddr09_writeX %d\n",
-@@ -554,15 +563,15 @@ sddr09_write_inplace(struct us_data *us,
-  */
- static int
- sddr09_read_sg_test_only(struct us_data *us) {
--	unsigned char command[15] = {
--		0xe7, LUNBITS, 0
--	};
-+	unsigned char *command = us->iobuf;
- 	int result, bulklen, nsg, ct;
- 	unsigned char *buf;
- 	unsigned long address;
- 
- 	nsg = bulklen = 0;
--
-+	command[0] = 0xE7;
-+	command[1] = LUNBITS;
-+	command[2] = 0;
- 	address = 040000; ct = 1;
- 	nsg++;
- 	bulklen += (ct << 9);
-@@ -628,20 +637,22 @@ sddr09_read_sg_test_only(struct us_data 
- static int
- sddr09_read_status(struct us_data *us, unsigned char *status) {
- 
--	unsigned char command[12] = {
--		0xec, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
--	unsigned char data[64];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *data = us->iobuf;
- 	int result;
- 
- 	US_DEBUGP("Reading status...\n");
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	memset(command, 0, 12);
-+	command[0] = 0xEC;
-+	command[1] = LUNBITS;
-+
-+	result = sddr09_send_scsi_command(us, command, 12);
- 	if (result != USB_STOR_TRANSPORT_GOOD)
- 		return result;
- 
- 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
--				       data, sizeof(data), NULL);
-+				       data, 64, NULL);
- 	*status = data[0];
- 	return (result == USB_STOR_XFER_GOOD ?
- 			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
-@@ -953,13 +964,15 @@ sddr09_read_control(struct us_data *us,
-  */
- static int
- sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) {
--	unsigned char command[12] = {
--		0xed, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
--	unsigned char content[64];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *content = us->iobuf;
- 	int result, i;
- 
--	result = sddr09_send_scsi_command(us, command, sizeof(command));
-+	memset(command, 0, 12);
-+	command[0] = 0xED;
-+	command[1] = LUNBITS;
-+
-+	result = sddr09_send_scsi_command(us, command, 12);
- 	if (result != USB_STOR_TRANSPORT_GOOD)
- 		return result;
- 
-@@ -1006,11 +1019,13 @@ sddr09_get_wp(struct us_data *us, struct
- static int
- sddr09_reset(struct us_data *us) {
- 
--	unsigned char command[12] = {
--		0xeb, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
--	};
-+	unsigned char *command = us->iobuf;
-+
-+	memset(command, 0, 12);
-+	command[0] = 0xEB;
-+	command[1] = LUNBITS;
- 
--	return sddr09_send_scsi_command(us, command, sizeof(command));
-+	return sddr09_send_scsi_command(us, command, 12);
- }
- #endif
- 
-@@ -1313,7 +1328,7 @@ sddr09_init_card_info(struct us_data *us
- int
- sddr09_init(struct us_data *us) {
- 	int result;
--	unsigned char data[18];
-+	unsigned char *data = us->iobuf;
- 
- 	result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2);
- 	if (result != USB_STOR_TRANSPORT_GOOD) {
-@@ -1333,10 +1348,10 @@ sddr09_init(struct us_data *us) {
- 	US_DEBUGP("SDDR09init: %02X %02X\n", data[0], data[1]);
- 	// get 07 00
- 
--	result = sddr09_request_sense(us, data, sizeof(data));
-+	result = sddr09_request_sense(us, data, 18);
- 	if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) {
- 		int j;
--		for (j=0; j<sizeof(data); j++)
-+		for (j=0; j<18; j++)
- 			printk(" %02X", data[j]);
- 		printk("\n");
- 		// get 70 00 00 00 00 00 00 * 00 00 00 00 00 00
---- linux-2.6.0-test1/drivers/usb/storage/sddr55.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/usb/storage/sddr55.c	2003-07-19 17:03:50.000000000 -0700
-@@ -91,13 +91,14 @@ sddr55_bulk_transport(struct us_data *us
- static int sddr55_status(struct us_data *us)
- {
- 	int result;
--	unsigned char command[8] = {
--		0, 0, 0, 0, 0, 0xb0, 0, 0x80
--	};
--	unsigned char status[8];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *status = us->iobuf;
- 	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
- 
- 	/* send command */
-+	memset(command, 0, 8);
-+	command[5] = 0xB0;
-+	command[7] = 0x80;
- 	result = sddr55_bulk_transport(us,
- 		SCSI_DATA_WRITE, command, 8);
- 
-@@ -158,10 +159,8 @@ static int sddr55_read_data(struct us_da
- 		int use_sg) {
- 
- 	int result = USB_STOR_TRANSPORT_GOOD;
--	unsigned char command[8] = {
--		0, 0, 0, 0, 0, 0xb0, 0, 0x85
--	};
--	unsigned char status[8];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *status = us->iobuf;
- 	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
- 
- 	unsigned int pba;
-@@ -205,11 +204,15 @@ static int sddr55_read_data(struct us_da
- 
- 			address = (pba << info->blockshift) + page;
- 
-+			command[0] = 0;
- 			command[1] = LSB_of(address>>16);
- 			command[2] = LSB_of(address>>8);
- 			command[3] = LSB_of(address);
- 
-+			command[4] = 0;
-+			command[5] = 0xB0;
- 			command[6] = LSB_of(pages << (1 - info->smallpageshift));
-+			command[7] = 0x85;
- 
- 			/* send command */
- 			result = sddr55_bulk_transport(us,
-@@ -274,10 +277,8 @@ static int sddr55_write_data(struct us_d
- 		int use_sg) {
- 
- 	int result = USB_STOR_TRANSPORT_GOOD;
--	unsigned char command[8] = {
--		0, 0, 0, 0, 0, 0xb0, 0, 0x86
--	};
--	unsigned char status[8];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *status = us->iobuf;
- 	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
- 
- 	unsigned int pba;
-@@ -380,6 +381,8 @@ static int sddr55_write_data(struct us_d
- 		command[6] = MSB_of(lba % 1000);
- 
- 		command[4] |= LSB_of(pages >> info->smallpageshift);
-+		command[5] = 0xB0;
-+		command[7] = 0x86;
- 
- 		/* send command */
- 		result = sddr55_bulk_transport(us,
-@@ -473,11 +476,12 @@ static int sddr55_read_deviceID(struct u
- 		unsigned char *deviceID) {
- 
- 	int result;
--	unsigned char command[8] = {
--		0, 0, 0, 0, 0, 0xb0, 0, 0x84
--	};
--	unsigned char content[64];
-+	unsigned char *command = us->iobuf;
-+	unsigned char *content = us->iobuf;
- 
-+	memset(command, 0, 8);
-+	command[5] = 0xB0;
-+	command[7] = 0x84;
- 	result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8);
- 
- 	US_DEBUGP("Result of send_control for device ID is %d\n",
-@@ -598,7 +602,7 @@ static int sddr55_read_map(struct us_dat
- 	struct sddr55_card_info *info = (struct sddr55_card_info *)(us->extra);
- 	int numblocks;
- 	unsigned char *buffer;
--	unsigned char command[8] = { 0, 0, 0, 0, 0, 0xb0, 0, 0x8a};	
-+	unsigned char *command = us->iobuf;
- 	int i;
- 	unsigned short lba;
- 	unsigned short max_lba;
-@@ -614,7 +618,10 @@ static int sddr55_read_map(struct us_dat
- 	if (!buffer)
- 		return -1;
- 
-+	memset(command, 0, 8);
-+	command[5] = 0xB0;
- 	command[6] = numblocks * 2 / 256;
-+	command[7] = 0x8A;
- 
- 	result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8);
- 
---- linux-2.6.0-test1/drivers/usb/storage/transport.h	2003-06-22 12:04:44.000000000 -0700
-+++ 25/drivers/usb/storage/transport.h	2003-07-19 17:03:50.000000000 -0700
-@@ -42,7 +42,7 @@
- #define _TRANSPORT_H_
- 
- #include <linux/config.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include "usb.h"
- #include "scsi.h"
- 
---- linux-2.6.0-test1/drivers/usb/storage/unusual_devs.h	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/storage/unusual_devs.h	2003-07-19 17:03:50.000000000 -0700
-@@ -119,7 +119,7 @@ UNUSUAL_DEV(  0x04b8, 0x0602, 0x0110, 0x
- UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
- 		"Fujifilm",
- 		"FinePix 1400Zoom",
--		US_SC_8070, US_PR_CBI, NULL, US_FL_FIX_INQUIRY),
-+		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
- 
- /* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
-  * The device needs the flags only.
-@@ -236,7 +236,7 @@ UNUSUAL_DEV(  0x0525, 0xa140, 0x0100, 0x
- UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450, 
- 		"Sony",
- 		"DSC-S30/S70/S75/505V/F505/F707/F717/P8", 
--		US_SC_SCSI, US_PR_CB, NULL,
-+		US_SC_SCSI, US_PR_DEVICE, NULL,
- 		US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
- 
- /* Reported by wim@geeks.nl */
-@@ -555,7 +555,7 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0
- UNUSUAL_DEV(  0x08ca, 0x2011, 0x0000, 0x9999,
- 		"AIPTEK",
- 		"PocketCAM 3Mega",
--		US_SC_SCSI, US_PR_BULK, NULL,
-+		US_SC_DEVICE, US_PR_DEVICE, NULL,
- 		US_FL_MODE_XLATE ),
- 
- /* aeb */
---- linux-2.6.0-test1/drivers/usb/storage/usb.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/storage/usb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -958,6 +958,8 @@ static int storage_probe(struct usb_inte
- 		goto BadDevice;
- 	}
- 
-+	scsi_scan_host(us->host);
-+
- 	printk(KERN_DEBUG 
- 	       "WARNING: USB Mass Storage data integrity not assured\n");
- 	printk(KERN_DEBUG 
---- linux-2.6.0-test1/drivers/usb/storage/usb.h	2003-07-02 14:53:16.000000000 -0700
-+++ 25/drivers/usb/storage/usb.h	2003-07-19 17:03:50.000000000 -0700
-@@ -45,7 +45,7 @@
- #define _USB_H_
- 
- #include <linux/usb.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/smp_lock.h>
- #include <linux/completion.h>
- #include <linux/version.h>
-@@ -69,11 +69,10 @@ struct us_unusual_dev {
- 
- /* Flag definitions: these entries are static */
- #define US_FL_SINGLE_LUN      0x00000001 /* allow access to only LUN 0	    */
--#define US_FL_MODE_XLATE      0x00000002 /* translate _6 to _10 commands for
--						    Win/MacOS compatibility */
-+#define US_FL_MODE_XLATE      0          /* [no longer used]                */
- #define US_FL_IGNORE_SER      0		 /* [no longer used]		    */
- #define US_FL_SCM_MULT_TARG   0x00000020 /* supports multiple targets	    */
--#define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs fixing   */
-+#define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs faking   */
- #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
- 
- /* Dynamic flag definitions: used in set_bit() etc. */
---- linux-2.6.0-test1/drivers/usb/usb-skeleton.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/usb/usb-skeleton.c	2003-07-19 17:03:50.000000000 -0700
-@@ -507,7 +507,7 @@ static int skel_probe(struct usb_interfa
- 	struct usb_endpoint_descriptor *endpoint;
- 	size_t buffer_size;
- 	int i;
--	int retval;
-+	int retval = -ENOMEM;
- 
- 	/* See if the device offered us matches what we can accept */
- 	if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
-@@ -515,18 +515,11 @@ static int skel_probe(struct usb_interfa
- 		return -ENODEV;
- 	}
- 
--	retval = usb_register_dev (interface, &skel_class);
--	if (retval) {
--		/* something prevented us from registering this driver */
--		err ("Not able to get a minor for this device.");
--		goto exit;
--	}
--
- 	/* allocate memory for our device state and initialize it */
- 	dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
- 	if (dev == NULL) {
- 		err ("Out of memory");
--		goto exit_minor;
-+		goto error;
- 	}
- 	memset (dev, 0x00, sizeof (*dev));
- 
-@@ -603,24 +596,24 @@ static int skel_probe(struct usb_interfa
- 	/* allow device read, write and ioctl */
- 	dev->present = 1;
- 
-+	/* we can register the device now, as it is ready */
-+	usb_set_intfdata (interface, dev);
-+	retval = usb_register_dev (interface, &skel_class);
-+	if (retval) {
-+		/* something prevented us from registering this driver */
-+		err ("Not able to get a minor for this device.");
-+		usb_set_intfdata (interface, NULL);
-+		goto error;
-+	}
-+
-+
- 	/* let the user know what node this device is now attached to */
- 	info ("USB Skeleton device now attached to USBSkel-%d", dev->minor);
--
--	goto exit;
-+	return 0;
- 
- error:
- 	skel_delete (dev);
--	dev = NULL;
--
--exit_minor:
--	usb_deregister_dev (interface, &skel_class);
--
--exit:
--	if (dev) {
--		usb_set_intfdata (interface, dev);
--		return 0;
--	}
--	return -ENODEV;
-+	return retval;
- }
- 
- 
---- linux-2.6.0-test1/drivers/video/cfbimgblt.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/drivers/video/cfbimgblt.c	2003-07-19 17:04:55.000000000 -0700
-@@ -325,7 +325,7 @@ void cfb_imageblit(struct fb_info *p, co
- 		else 
- 			slow_imageblit(image, p, dst1, fgcolor, bgcolor,
- 					start_index, pitch_index);
--	} else if (image->depth == bpp) 
-+	} else if (image->depth <= bpp) 
- 		color_imageblit(image, p, dst1, start_index, pitch_index);
- }
- 
---- linux-2.6.0-test1/drivers/video/chipsfb.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/drivers/video/chipsfb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -85,7 +85,7 @@ static struct pmu_sleep_notifier chips_s
- /*
-  * Exported functions
-  */
--int chips_init(void);
-+int chipsfb_init(void);
- 
- static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
- static int chipsfb_check_var(struct fb_var_screeninfo *var,
-@@ -460,7 +460,7 @@ static struct pci_driver chipsfb_driver 
- 	.remove =	__devexit_p(chipsfb_remove),
- };
- 
--int __init chips_init(void)
-+int __init chipsfb_init(void)
- {
- 	return pci_module_init(&chipsfb_driver);
- }
---- linux-2.6.0-test1/drivers/video/console/fbcon.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/video/console/fbcon.c	2003-07-19 17:04:55.000000000 -0700
-@@ -195,8 +195,7 @@ static void fb_flashcursor(void *private
- {
- 	struct fb_info *info = (struct fb_info *) private;
- 
--	/* Test to see if the cursor is erased but still on */
--	if (!info || (info->cursor.rop == ROP_COPY))
-+	if (!info)
- 		return;
- 	info->cursor.enable ^= 1;
- 	info->fbops->fb_cursor(info, &info->cursor);
-@@ -226,8 +225,7 @@ static void cursor_timer_handler(unsigne
- 	struct fb_info *info = (struct fb_info *) dev_addr;
- 	
- 	schedule_work(&info->queue);	
--	cursor_timer.expires = jiffies + HZ / 5;
--	add_timer(&cursor_timer);
-+	mod_timer(&cursor_timer, jiffies + HZ/5);
- }
- 
- int __init fb_console_setup(char *this_opt)
-@@ -308,97 +306,6 @@ int set_con2fb_map(int unit, int newidx)
- }
- 
- /*
-- * drawing helpers
-- */
--static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
--			    struct fb_image *image, int count,
--			    const unsigned short *s)
--{
--	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
--	unsigned int width = (vc->vc_font.width + 7) >> 3;
--	unsigned int cellsize = vc->vc_font.height * width;
--	unsigned int maxcnt = info->pixmap.size/cellsize;
--	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
--	unsigned int shift_high = 8, size, pitch, cnt, k;
--	unsigned int buf_align = info->pixmap.buf_align - 1;
--	unsigned int scan_align = info->pixmap.scan_align - 1;
--	unsigned int idx = vc->vc_font.width >> 3;
--	u8 mask, *src, *dst, *dst0;
--
--	while (count) {
--		if (count > maxcnt)
--			cnt = k = maxcnt;
--		else
--			cnt = k = count;
--
--		image->width = vc->vc_font.width * cnt;
--		pitch = ((image->width + 7) >> 3) + scan_align;
--		pitch &= ~scan_align;
--		size = pitch * vc->vc_font.height + buf_align;
--		size &= ~buf_align;
--		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
--		image->data = dst0;
--		while (k--) {
--			src = vc->vc_font.data + (scr_readw(s++) & charmask)*
--			cellsize;
--			dst = dst0;
--			mask = (u8) (0xfff << shift_high);
--			move_buf_unaligned(info, dst, src, pitch, image->height,
--					mask, shift_high, shift_low, mod, idx);
--			shift_low += mod;
--			dst0 += (shift_low >= 8) ? width : width - 1;
--			shift_low &= 7;
--			shift_high = 8 - shift_low;
--		}
--		info->fbops->fb_imageblit(info, image);
--		image->dx += cnt * vc->vc_font.width;
--		count -= cnt;
--		atomic_dec(&info->pixmap.count);
--		smp_mb__after_atomic_dec();
--	}
--}
--
--static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
--			  struct fb_image *image, int count,
--			  const unsigned short *s)
--{
--	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
--	unsigned int width = vc->vc_font.width >> 3;
--	unsigned int cellsize = vc->vc_font.height * width;
--	unsigned int maxcnt = info->pixmap.size/cellsize;
--	unsigned int scan_align = info->pixmap.scan_align - 1;
--	unsigned int buf_align = info->pixmap.buf_align - 1;
--	unsigned int pitch, cnt, size, k;
--	u8 *src, *dst, *dst0;
--
--	while (count) {
--		if (count > maxcnt)
--			cnt = k = maxcnt;
--		else
--			cnt = k = count;
--		
--		pitch = width * cnt + scan_align;
--		pitch &= ~scan_align;
--		size = pitch * vc->vc_font.height + buf_align;
--		size &= ~buf_align;
--		image->width = vc->vc_font.width * cnt;
--		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
--		image->data = dst0;
--		while (k--) {
--			src = vc->vc_font.data + (scr_readw(s++)&charmask)*cellsize;
--			dst = dst0;
--			move_buf_aligned(info, dst, src, pitch, width, image->height);
--			dst0 += width;
--		}
--		info->fbops->fb_imageblit(info, image);
--		image->dx += cnt * vc->vc_font.width;
--		count -= cnt;
--		atomic_dec(&info->pixmap.count);
--		smp_mb__after_atomic_dec();
--	}
--}
--
--/*
-  * Accelerated handlers.
-  */
- void accel_bmove(struct vc_data *vc, struct fb_info *info, int sy, 
-@@ -432,48 +339,21 @@ void accel_clear(struct vc_data *vc, str
- 	info->fbops->fb_fillrect(info, &region);
- }	
- 
--static void accel_putc(struct vc_data *vc, struct fb_info *info,
--                      int c, int ypos, int xpos)
-+void accel_putcs(struct vc_data *vc, struct fb_info *info,
-+			const unsigned short *s, int count, int yy, int xx)
- {
- 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- 	unsigned int width = (vc->vc_font.width + 7) >> 3;
-+	unsigned int cellsize = vc->vc_font.height * width;
-+	unsigned int maxcnt = info->pixmap.size/cellsize;
- 	unsigned int scan_align = info->pixmap.scan_align - 1;
- 	unsigned int buf_align = info->pixmap.buf_align - 1;
-+	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
-+	unsigned int shift_high = 8, pitch, cnt, size, k;
- 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- 	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
--	unsigned int size, pitch;
--	struct fb_image image;
--	u8 *src, *dst;
--
--	image.dx = xpos * vc->vc_font.width;
--	image.dy = ypos * vc->vc_font.height;
--	image.width = vc->vc_font.width;
--	image.height = vc->vc_font.height;
--	image.fg_color = attr_fgcol(fgshift, c);
--	image.bg_color = attr_bgcol(bgshift, c);
--	image.depth = 1;
--
--	pitch = width + scan_align;
--	pitch &= ~scan_align;
--	size = pitch * vc->vc_font.height;
--	size += buf_align;
--	size &= ~buf_align;
--	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
--	image.data = dst;
--	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
--
--	move_buf_aligned(info, dst, src, pitch, width, image.height);
--
--	info->fbops->fb_imageblit(info, &image);
--	atomic_dec(&info->pixmap.count);
--	smp_mb__after_atomic_dec();
--}
--
--void accel_putcs(struct vc_data *vc, struct fb_info *info,
--			const unsigned short *s, int count, int yy, int xx)
--{
--	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
--	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
-+	unsigned int idx = vc->vc_font.width >> 3;
-+	u8 *src, *dst, *dst0, mask;
- 	struct fb_image image;
- 	u16 c = scr_readw(s);
- 
-@@ -484,10 +364,44 @@ void accel_putcs(struct vc_data *vc, str
- 	image.height = vc->vc_font.height;
- 	image.depth = 1;
- 
--	if (!(vc->vc_font.width & 7))
--               putcs_aligned(vc, info, &image, count, s);
--        else
--               putcs_unaligned(vc, info, &image, count, s);
-+	while (count) {
-+		if (count > maxcnt)
-+			cnt = k = maxcnt;
-+		else
-+			cnt = k = count;
-+
-+		image.width = vc->vc_font.width * cnt;
-+		pitch = ((image.width + 7) >> 3) + scan_align;
-+		pitch &= ~scan_align;
-+		size = pitch * vc->vc_font.height + buf_align;
-+		size &= ~buf_align;
-+		dst0 = fb_get_buffer_offset(info, &info->pixmap, size);
-+		image.data = dst0;
-+		while (k--) {
-+			src = vc->vc_font.data + (scr_readw(s++) & charmask)*cellsize;
-+			dst = dst0;
-+		
-+			if (mod) {
-+				mask = (u8) (0xfff << shift_high);
-+				move_buf_unaligned(info, &info->pixmap, dst, src, pitch,
-+						   image.height, mask, shift_high, 
-+						   shift_low, mod, idx);
-+				shift_low += mod;
-+				dst0 += (shift_low >= 8) ? width : width - 1;
-+				shift_low &= 7;
-+				shift_high = 8 - shift_low;
-+			} else {
-+				move_buf_aligned(info, &info->pixmap, dst, src, pitch, idx, 
-+						 image.height);
-+				dst0 += width;
-+			}	
-+		}
-+		info->fbops->fb_imageblit(info, &image);
-+		image.dx += cnt * vc->vc_font.width;
-+		count -= cnt;
-+		atomic_dec(&info->pixmap.count);
-+		smp_mb__after_atomic_dec();
-+	}
- }
- 
- void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
-@@ -676,7 +590,7 @@ static const char *fbcon_startup(void)
- 	if (!info->queue.func) {
- 		INIT_WORK(&info->queue, fb_flashcursor, info);
- 		
--		cursor_timer.expires = jiffies + HZ / 50;
-+		cursor_timer.expires = jiffies + HZ / 5;
- 		cursor_timer.data = (unsigned long ) info;
- 		add_timer(&cursor_timer);
- 	}
-@@ -728,15 +642,13 @@ static __inline__ void updatescrollmode(
- static void fbcon_set_display(struct vc_data *vc, int init, int logo)
- {
- 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+	int nr_rows, nr_cols, old_rows, old_cols, i, charcnt = 256;
- 	struct display *p = &fb_display[vc->vc_num];
--	int nr_rows, nr_cols;
--	int old_rows, old_cols;
- 	unsigned short *save = NULL, *r, *q;
--	int i, charcnt = 256;
- 	struct font_desc *font;
- 
- 	if (vc->vc_num != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
--	    info->fix.type == FB_TYPE_TEXT)
-+	    (info->fix.type == FB_TYPE_TEXT))
- 		logo = 0;
- 
- 	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
-@@ -960,19 +872,51 @@ static void fbcon_clear(struct vc_data *
- 		accel_clear(vc, info, real_y(p, sy), sx, height, width);
- }
- 
--
- static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
- {
- 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-+	unsigned int scan_align = info->pixmap.scan_align - 1;
-+	unsigned int buf_align = info->pixmap.buf_align - 1;
-+	unsigned int width = (vc->vc_font.width + 7) >> 3;
-+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-+	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
- 	struct display *p = &fb_display[vc->vc_num];
--
-+	unsigned int size, pitch;
-+	struct fb_image image;
-+	u8 *src, *dst;
-+	
- 	if (!info->fbops->fb_blank && console_blanked)
- 		return;
- 
- 	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
- 		return;
- 
--	accel_putc(vc, info, c, real_y(p, ypos), xpos);
-+	image.dx = xpos * vc->vc_font.width;
-+	image.dy = real_y(p, ypos) * vc->vc_font.height;
-+	image.width = vc->vc_font.width;
-+	image.height = vc->vc_font.height;
-+	image.fg_color = attr_fgcol(fgshift, c);
-+	image.bg_color = attr_bgcol(bgshift, c);
-+	image.depth = 1;
-+
-+	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
-+
-+	pitch = width + scan_align;
-+	pitch &= ~scan_align;
-+	size = pitch * vc->vc_font.height;
-+	size += buf_align;
-+	size &= ~buf_align;
-+
-+	dst = fb_get_buffer_offset(info, &info->pixmap, size);
-+	image.data = dst;
-+	
-+	move_buf_aligned(info, &info->pixmap, dst, src, pitch, width,
-+			image.height);
-+
-+	info->fbops->fb_imageblit(info, &image);
-+	atomic_dec(&info->pixmap.count);
-+	smp_mb__after_atomic_dec();
- }
- 
- static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
-@@ -994,12 +938,16 @@ static void fbcon_cursor(struct vc_data 
- {
- 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
- 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-+	unsigned int scan_align = info->sprite.scan_align - 1;
-+	unsigned int buf_align = info->sprite.buf_align - 1;
- 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- 	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
- 	struct display *p = &fb_display[vc->vc_num];
--	int w = (vc->vc_font.width + 7) >> 3, c;
--	int y = real_y(p, vc->vc_y);
-+	int y = real_y(p, vc->vc_y), d_pitch, dsize;
-+	int s_pitch = (vc->vc_font.width + 7) >> 3;
-+	int size = s_pitch * vc->vc_font.height, c;
- 	struct fb_cursor cursor;
-+	u8 *src, *dst;
- 	
- 	if (mode & CM_SOFTBACK) {
- 		mode &= ~CM_SOFTBACK;
-@@ -1012,28 +960,27 @@ static void fbcon_cursor(struct vc_data 
- 	} else if (softback_lines)
- 		fbcon_set_origin(vc);
- 
-- 	c = scr_readw((u16 *) vc->vc_pos);
--
--	cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
--	cursor.set = FB_CUR_SETCUR;
--	cursor.image.depth = 1;
--	
- 	switch (mode) {
- 	case CM_ERASE:
--		if (info->cursor.rop == ROP_XOR) {
-+		del_timer(&cursor_timer);
-+		if (info->cursor.enable) {
- 			info->cursor.enable = 0;
--			info->cursor.rop = ROP_COPY;
--			info->fbops->fb_cursor(info, &cursor);
--		}	
-+			info->fbops->fb_cursor(info, &info->cursor);
-+		}
- 		break;
- 	case CM_MOVE:
- 	case CM_DRAW:
-+		memset(&cursor, 0, sizeof(struct fb_cursor));
- 		info->cursor.enable = 1;
--		
-+
-+ 		c = scr_readw((u16 *) vc->vc_pos);
-+
-+		src = vc->vc_font.data + ((c & charmask) * size);
- 		if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
- 	    	    info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
- 			cursor.image.fg_color = attr_fgcol(fgshift, c);
- 			cursor.image.bg_color = attr_bgcol(bgshift, c);
-+			cursor.image.depth = 1;
- 			cursor.set |= FB_CUR_SETCMAP;
- 		}
- 		
-@@ -1056,18 +1003,29 @@ static void fbcon_cursor(struct vc_data 
- 			cursor.set |= FB_CUR_SETHOT;
- 		}
- 
-+		src = vc->vc_font.data + ((c & charmask) * size);
-+
-+		d_pitch = (s_pitch + scan_align) & ~scan_align;
-+		dsize = d_pitch * vc->vc_font.height + buf_align;
-+		dsize &= ~buf_align;
-+		dst = fb_get_buffer_offset(info, &info->sprite, dsize);
-+		move_buf_aligned(info, &info->sprite, dst, src, d_pitch, s_pitch, vc->vc_font.height);
-+		info->cursor.image.data = dst;
-+		cursor.set |= FB_CUR_SETSHAPE;
-+		
- 		if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
--			char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
--			int cur_height, size, i = 0;
-+			char *mask = kmalloc(dsize, GFP_ATOMIC);
-+			int cur_height, i, j, k;
- 
- 			if (!mask)	return;	
--		
-+	
-+			memset(mask, 0, dsize);
-+			
- 			if (info->cursor.mask)
- 				kfree(info->cursor.mask);
- 			info->cursor.mask = mask;
- 	
- 			p->cursor_shape = vc->vc_cursor_type & 0x0f;
--			cursor.set |= FB_CUR_SETSHAPE;
- 
- 			switch (vc->vc_cursor_type & 0x0f) {
- 			case CUR_NONE:
-@@ -1090,15 +1048,18 @@ static void fbcon_cursor(struct vc_data 
- 				cur_height = vc->vc_font.height;
- 				break;
- 			}
--			size = (vc->vc_font.height - cur_height) * w;
--			while (size--)
--				mask[i++] = 0;
--			size = cur_height * w;
--			while (size--)
--				mask[i++] = 0xff;
-+			i = (vc->vc_font.height - cur_height) * d_pitch;
-+			for (j = 0; j < cur_height; j++) {
-+				for (k = 0; k < s_pitch; k++)	
-+					mask[i++] = 0xff;
-+				i += (d_pitch - s_pitch);
-+			}
- 		}
-         	info->cursor.rop = ROP_XOR;
- 		info->fbops->fb_cursor(info, &cursor);
-+		atomic_dec(&info->sprite.count);
-+		smp_mb__after_atomic_dec();
-+		mod_timer(&cursor_timer, jiffies + HZ/5);
- 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
- 		break;
- 	}
-@@ -1826,9 +1787,11 @@ static int fbcon_do_set_font(struct vc_d
- 	vc->vc_font.height = h;
- 	if (vc->vc_hi_font_mask && cnt == 256) {
- 		vc->vc_hi_font_mask = 0;
--		if (vc->vc_can_do_color)
-+		if (vc->vc_can_do_color) {
- 			vc->vc_complement_mask >>= 1;
--
-+			vc->vc_s_complement_mask >>= 1;
-+		}
-+			
- 		/* ++Edmund: reorder the attribute bits */
- 		if (vc->vc_can_do_color) {
- 			unsigned short *cp =
-@@ -1847,9 +1810,11 @@ static int fbcon_do_set_font(struct vc_d
- 		}
- 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
- 		vc->vc_hi_font_mask = 0x100;
--		if (vc->vc_can_do_color)
-+		if (vc->vc_can_do_color) {
- 			vc->vc_complement_mask <<= 1;
--
-+			vc->vc_s_complement_mask <<= 1;
-+		}
-+			
- 		/* ++Edmund: reorder the attribute bits */
- 		{
- 			unsigned short *cp =
---- linux-2.6.0-test1/drivers/video/controlfb.c	2003-06-14 12:18:00.000000000 -0700
-+++ 25/drivers/video/controlfb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -136,8 +136,8 @@ static int controlfb_check_var (struct f
- /*
-  * inititialization
-  */
--int control_init(void);
--void control_setup(char *);
-+int controlfb_init(void);
-+void controlfb_setup(char *);
- 
- /******************** Prototypes for internal functions **********************/
- 
-@@ -475,7 +475,7 @@ try_again:
- 
- 	/* Apply default var */
- 	var.activate = FB_ACTIVATE_NOW;
--	rc = fb_set_var(&var, &p->info);
-+	rc = fb_set_var(&p->info, &var);
- 	if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8))
- 		goto try_again;
- 
-@@ -553,7 +553,7 @@ static void control_set_hardware(struct 
- /*
-  * Called from fbmem.c for probing & initializing
-  */
--int __init control_init(void)
-+int __init controlfb_init(void)
- {
- 	struct device_node *dp;
- 
-@@ -1057,7 +1057,7 @@ static void control_cleanup(void)
- /*
-  * Parse user speficied options (`video=controlfb:')
-  */
--void __init control_setup(char *options)
-+void __init controlfb_setup(char *options)
- {
- 	char *this_opt;
- 
---- linux-2.6.0-test1/drivers/video/epson1355fb.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/video/epson1355fb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,541 +1,714 @@
- /*
-- * linux/drivers/video/epson1355fb.c
-- *	-- Support for the Epson SED1355 LCD/CRT controller
-+ * linux/drivers/video/epson1355fb.c -- Epson S1D13505 frame buffer for 2.5.
-  *
-- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
-+ * Epson Research S1D13505 Embedded RAMDAC LCD/CRT Controller
-+ *   (previously known as SED1355)
-  *
-- * based on linux/drivers/video/skeletonfb.c, which was
-+ * Cf. http://www.erd.epson.com/vdc/html/S1D13505.html
-+ *
-+ *
-+ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
-+ *
-+ * Written by Christopher Hoover <ch@hpl.hp.com>
-+ *
-+ * Adapted from:
-+ *
-+ *  linux/drivers/video/skeletonfb.c
-+ *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
-  *  Created 28 Dec 1997 by Geert Uytterhoeven
-  *
-+ *  linux/drivers/video/epson1355fb.c (2.4 driver)
-+ *  Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
-+ *
-  * This file is subject to the terms and conditions of the GNU General Public
-- * License.  See the file COPYING in the main directory of this archive
-- * for more details.
-- */
--/* TODO (roughly in order of priority):
-- * 16 bpp support
-- * crt support
-- * hw cursor support
-- * SwivelView
-+ * License. See the file COPYING in the main directory of this archive for
-+ * more details.
-+ *
-+ *
-+ * Noteworthy Issues
-+ * -----------------
-+ *
-+ * This driver is complicated by the fact that this is a 16-bit chip
-+ * and, on at least one platform (ceiva), we can only do 16-bit reads
-+ * and writes to the framebuffer.  We hide this from user space
-+ * except in the case of mmap().
-+ *
-+ *
-+ * To Do
-+ * -----
-+ *
-+ * - Test 8-bit pseudocolor mode
-+ * - Allow setting bpp, virtual resolution 
-+ * - Implement horizontal panning
-+ * - (maybe) Implement hardware cursor
-  */
- 
--#include <asm/io.h>
--#include <linux/config.h>
--#include <linux/delay.h>
--#include <linux/errno.h>
--#include <linux/fb.h>
--#include <linux/init.h>
--#include <linux/kernel.h>
--#include <linux/slab.h>
--#include <linux/mm.h>
- #include <linux/module.h>
--#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
- #include <linux/string.h>
-+#include <linux/mm.h>
- #include <linux/tty.h>
--#include <video/fbcon-cfb8.h>
--#include <video/fbcon-mfb.h>
--#include <video/fbcon.h>
--
--/* Register defines.  The docs don't seem to provide nice mnemonic names
-- * so I made them up myself ... */
--
--#define E1355_PANEL	0x02
--#define E1355_DISPLAY	0x0D
--#define E1355_MISC	0x1B
--#define E1355_GPIO	0x20
--#define E1355_LUT_INDEX 0x24
--#define E1355_LUT_DATA	0x26
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <asm/types.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+
-+#include <video/epson1355.h>
-+
-+static struct fb_info info;
-+
-+static struct epson1355fb_par {
-+	unsigned long reg_addr;
-+} par;
-+
-+static u32 pseudo_palette[16];
-+
-+/* ------------------------------------------------------------------------- */
- 
- #ifdef CONFIG_SUPERH
--#define E1355_REG_BASE	CONFIG_E1355_REG_BASE
--#define E1355_FB_BASE	CONFIG_E1355_FB_BASE
- 
--static inline u8 e1355_read_reg(int index)
-+static inline u8 epson1355_read_reg(int index)
- {
--	return ctrl_inb(E1355_REG_BASE + index);
-+	return ctrl_inb(par.reg_addr + index);
- }
- 
--static inline void e1355_write_reg(u8 data, int index)
-+static inline void epson1355_write_reg(u8 data, int index)
- {
--	ctrl_outb(data, E1355_REG_BASE + index);
-+	ctrl_outb(data, par.reg_addr + index);
- }
- 
--static inline u16 e1355_read_reg16(int index)
-+#elif defined(CONFIG_ARM)
-+
-+# ifdef CONFIG_ARCH_CEIVA
-+#  include <asm/arch/hardware.h>
-+#  define EPSON1355FB_BASE_PHYS	(CEIVA_PHYS_SED1355)
-+# endif
-+
-+static inline u8 epson1355_read_reg(int index)
- {
--	return e1355_read_reg(index) + (e1355_read_reg(index+1) << 8);
-+	return __raw_readb(par.reg_addr + index);
- }
- 
--static inline void e1355_write_reg16(u16 data, int index)
-+static inline void epson1355_write_reg(u8 data, int index)
- {
--	e1355_write_reg((data&0xff), index);
--	e1355_write_reg(((data>>8)&0xff), index + 1);
-+	__raw_writeb(data, par.reg_addr + index);
- }
-+
- #else
--#error unknown architecture
-+# error "no architecture-specific epson1355_{read,write}_reg"
- #endif
- 
--struct e1355fb_info {
--	struct fb_info_gen gen;
--};
--
--static int current_par_valid = 0;
--static struct display disp;
-+#ifndef EPSON1355FB_BASE_PHYS
-+# error  "EPSON1355FB_BASE_PHYS is not defined"
-+#endif
- 
--static struct fb_var_screeninfo default_var;
-+#define EPSON1355FB_REGS_OFS	(0)
-+#define EPSON1355FB_REGS_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_REGS_OFS)
-+#define EPSON1355FB_REGS_LEN	(64)
- 
--int e1355fb_init(void);
--int e1355fb_setup(char*);
--static int e1355_encode_var(struct fb_var_screeninfo *var, const void *par,
--			    struct fb_info_gen *info);
--/* ------------------- chipset specific functions -------------------------- */
-+#define EPSON1355FB_FB_OFS	(0x00200000)
-+#define EPSON1355FB_FB_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_FB_OFS)
-+#define EPSON1355FB_FB_LEN	(2 * 1024 * 1024)
- 
-+/* ------------------------------------------------------------------------- */
- 
--static void disable_hw_cursor(void)
-+static inline u16 epson1355_read_reg16(int index)
- {
--	u8 curs;
-+	u8 lo = epson1355_read_reg(index);
-+	u8 hi = epson1355_read_reg(index + 1);
- 
--	curs = e1355_read_reg(0x27);
--	curs &= ~0xc0;
--	e1355_write_reg(curs, 0x27);
-+	return (hi << 8) | lo;
- }
- 
--static void e1355_detect(void)
-+static inline void epson1355_write_reg16(u16 data, int index)
- {
--	u8 rev;
-+	u8 lo = data & 0xff;
-+	u8 hi = (data >> 8) & 0xff;
- 
--	e1355_write_reg(0x00, E1355_MISC);
-+	epson1355_write_reg(lo, index);
-+	epson1355_write_reg(hi, index + 1);
-+}
- 
--	rev = e1355_read_reg(0x00);
-+static inline u32 epson1355_read_reg20(int index)
-+{
-+	u8 b0 = epson1355_read_reg(index);
-+	u8 b1 = epson1355_read_reg(index + 1);
-+	u8 b2 = epson1355_read_reg(index + 2);
- 
--	if ((rev & 0xfc) != 0x0c) {
--		printk(KERN_WARNING "Epson 1355 not detected\n");
--	}
-+	return (b2 & 0x0f) << 16 | (b1 << 8) | b0;
-+}
- 
--	/* XXX */
--	disable_hw_cursor();
-+static inline void epson1355_write_reg20(u32 data, int index)
-+{
-+	u8 b0 = data & 0xff;
-+	u8 b1 = (data >> 8) & 0xff;
-+	u8 b2 = (data >> 16) & 0x0f;
- 
--	e1355_encode_var(&default_var, NULL, NULL);
-+	epson1355_write_reg(b0, index);
-+	epson1355_write_reg(b1, index + 1);
-+	epson1355_write_reg(b2, index + 2);
- }
- 
--struct e1355_par {
--	u32 xres;
--	u32 yres;
-+/* ------------------------------------------------------------------------- */
- 
--	int bpp;
--	int mem_bpp;
-+static void set_lut(u8 index, u8 r, u8 g, u8 b)
-+{
-+	epson1355_write_reg(index, REG_LUT_ADDR);
-+	epson1355_write_reg(r, REG_LUT_DATA);
-+	epson1355_write_reg(g, REG_LUT_DATA);
-+	epson1355_write_reg(b, REG_LUT_DATA);
-+}
- 
--	u32 panel_xres;
--	u32 panel_yres;
--	
--	int panel_width;
--	int panel_ymul;
--};
- 
--static int e1355_encode_fix(struct fb_fix_screeninfo *fix,
--			    const void *raw_par,
--			    struct fb_info_gen *info)
--{
--	const struct e1355_par *par = raw_par;
--	
--	memset(fix, 0, sizeof *fix);
--	
--	fix->type= FB_TYPE_PACKED_PIXELS;
-+/**
-+ *  	epson1355fb_setcolreg - sets a color register.
-+ *      @regno: Which register in the CLUT we are programming 
-+ *      @red: The red value which can be up to 16 bits wide 
-+ *	@green: The green value which can be up to 16 bits wide 
-+ *	@blue:  The blue value which can be up to 16 bits wide.
-+ *	@transp: If supported the alpha value which can be up to 16 bits wide.
-+ *      @info: frame buffer info structure
-+ * 
-+ *	Returns negative errno on error, or zero on success.
-+ */
-+static int epson1355fb_setcolreg(unsigned regno, unsigned r, unsigned g,
-+				 unsigned b, unsigned transp,
-+				 struct fb_info *info)
-+{
-+	if (info->var.grayscale)
-+		r = g = b = (19595 * r + 38470 * g + 7471 * b) >> 16;
-+
-+	switch (info->fix.visual) {
-+	case FB_VISUAL_TRUECOLOR:
-+		if (regno >= 16)
-+			return -EINVAL;
- 
--	if (!par)
--		BUG();
-+		((u32 *) info->pseudo_palette)[regno] =
-+		    (r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;
- 
--	if (par->bpp == 1) {
--		fix->visual = FB_VISUAL_MONO10;
--	} else if (par->bpp <= 8) {
--		fix->visual = FB_VISUAL_PSEUDOCOLOR;
--	} else {
--		fix->visual = FB_VISUAL_TRUECOLOR;
--	}
-+		break;
-+	case FB_VISUAL_PSEUDOCOLOR:
-+		if (regno >= 256)
-+			return -EINVAL;
- 
--	return 0;
--}
-+		set_lut(regno, r >> 8, g >> 8, b >> 8);
- 
--static int e1355_set_bpp(struct e1355_par *par, int bpp)
--{
--	int code;
--	u8 disp;
--	u16 bytes_per_line;
--
--	switch(bpp) {
--	case 1:
--		code = 0; break;
--	case 2:
--		code = 1; break;
--	case 4:
--		code = 2; break;
--	case 8:
--		code = 3; break;
--	case 16:
--		code = 5; break;
-+		break;
- 	default:
--		return -EINVAL; break;
-+		return -ENOSYS;
- 	}
--
--	disp = e1355_read_reg(E1355_DISPLAY);
--	disp &= ~0x1c;
--	disp |= code << 2;
--	e1355_write_reg(disp, E1355_DISPLAY);
--	
--	bytes_per_line = (par->xres * bpp) >> 3;
--	
--	e1355_write_reg16(bytes_per_line, 0x16);
--
--	par->bpp = bpp;
--
- 	return 0;
- }
--		
--static int e1355_decode_var(const struct fb_var_screeninfo *var,
--			    void *raw_par,
--			    struct fb_info_gen *info)
-+
-+/* ------------------------------------------------------------------------- */
-+
-+/**
-+ *      epson1355fb_pan_display - Pans the display.
-+ *      @var: frame buffer variable screen structure
-+ *      @info: frame buffer structure that represents a single frame buffer
-+ *
-+ *	Pan (or wrap, depending on the `vmode' field) the display using the
-+ *  	`xoffset' and `yoffset' fields of the `var' structure.
-+ *  	If the values don't fit, return -EINVAL.
-+ *
-+ *      Returns negative errno on error, or zero on success.
-+ */
-+static int epson1355fb_pan_display(struct fb_var_screeninfo *var,
-+				   struct fb_info *info)
- {
--	struct e1355_par *par = raw_par;
--	int ret;
-+	u32 start;
- 
--	if (!par)
--		BUG();
-+	if (var->xoffset != 0)	/* not yet ... */
-+		return -EINVAL;
- 
--	/*
--	 * Don't allow setting any of these yet: xres and yres don't
--	 * make sense for LCD panels; xres_virtual and yres_virtual
--	 * should be supported fine by our hardware though.
--	 */
--	if (var->xres != par->xres ||
--	    var->yres != par->yres ||
--	    var->xres != var->xres_virtual ||
--	    var->yres != var->yres_virtual ||
--	    var->xoffset != 0 ||
--	    var->yoffset != 0)
-+	if (var->yoffset + info->var.yres > info->var.yres_virtual)
- 		return -EINVAL;
- 
--	if(var->bits_per_pixel != par->bpp) {
--		ret = e1355_set_bpp(par, var->bits_per_pixel);
-+	start = (info->fix.line_length >> 1) * var->yoffset;
- 
--		if (ret)
--			goto out_err;
--	}
--		
--	return 0;
-+	epson1355_write_reg20(start, REG_SCRN1_DISP_START_ADDR0);
- 
-- out_err:
--	return ret;
-+	return 0;
- }
- 
--static void dump_panel_data(void)
-+/* ------------------------------------------------------------------------- */
-+
-+static void lcd_enable(int enable)
- {
--	u8 panel = e1355_read_reg(E1355_PANEL);
--	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
-+	u8 mode = epson1355_read_reg(REG_DISPLAY_MODE);
- 
--	printk("%s %s %s panel, width %d bits\n",
--	       panel & 2 ? "dual" : "single",
--	       panel & 4 ? "color" : "mono",
--	       panel & 1 ? "TFT" : "passive",
--	       width[panel&1][(panel>>4)&3]);
-+	if (enable)
-+		mode |= 1;
-+	else
-+		mode &= ~1;
- 
--	printk("resolution %d x %d\n",
--	       (e1355_read_reg(0x04) + 1) * 8,
--	       ((e1355_read_reg16(0x08) + 1) * (1 + ((panel & 3) == 2))));
-+	epson1355_write_reg(mode, REG_DISPLAY_MODE);
- }
- 
--static int e1355_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
-+#if defined(CONFIG_ARCH_CEIVA)
-+static void backlight_enable(int enable)
- {
--	switch(bpp) {
--	case 1:
--	case 2:
--	case 4:
--	case 8:
--		var->bits_per_pixel = bpp;
--		var->red.offset = var->green.offset = var->blue.offset = 0;
--		var->red.length = var->green.length = var->blue.length = bpp;
-+	/* ### this should be protected by a spinlock ... */
-+	u8 pddr = clps_readb(PDDR);
-+	if (enable)
-+		pddr |= (1 << 5);
-+	else
-+		pddr &= ~(1 << 5);
-+	clps_writeb(pddr, PDDR);
-+}
-+#else
-+static void backlight_enable(int enable)
-+{
-+}
-+#endif
-+
-+
-+/**
-+ *      epson1355fb_blank - blanks the display.
-+ *      @blank_mode: the blank mode we want. 
-+ *      @info: frame buffer structure that represents a single frame buffer
-+ *
-+ *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
-+ *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a 
-+ *      video mode which doesn't support it. Implements VESA suspend
-+ *      and powerdown modes on hardware that supports disabling hsync/vsync:
-+ *      blank_mode == 2: suspend vsync
-+ *      blank_mode == 3: suspend hsync
-+ *      blank_mode == 4: powerdown
-+ *
-+ *      Returns negative errno on error, or zero on success.
-+ *
-+ */
-+static int epson1355fb_blank(int blank_mode, struct fb_info *info)
-+{
-+	switch (blank_mode) {
-+	case VESA_NO_BLANKING:
-+		lcd_enable(1);
-+		backlight_enable(1);
- 		break;
--	case 16:
--		var->bits_per_pixel = 16;
--		var->red.offset = 11;
--		var->red.length = 5;
--		var->green.offset = 5;
--		var->green.length = 6;
--		var->blue.offset = 0;
--		var->blue.length = 5;
-+	case VESA_VSYNC_SUSPEND:
-+	case VESA_HSYNC_SUSPEND:
-+		backlight_enable(0);
- 		break;
-+	case VESA_POWERDOWN:
-+		backlight_enable(0);
-+		lcd_enable(0);
-+		break;
-+	default:
-+		return -EINVAL;
- 	}
--
- 	return 0;
- }
- 
--static int e1355_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
--			    struct fb_info_gen *info)
-+/* ------------------------------------------------------------------------- */
-+
-+/*
-+ * We can't use the cfb generic routines, as we have to limit
-+ * ourselves to 16-bit or 8-bit loads and stores to this 16-bit
-+ * chip.
-+ */
-+
-+static inline void epson1355fb_fb_writel(unsigned long v, unsigned long *a)
- {
--	u8 panel, display;
--	u32 xres, xres_virtual, yres;
--	static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
--	static int bpp_tab[8] = { 1, 2, 4, 8, 15, 16 };
--	int bpp, hw_bpp;
--	int is_color, is_dual, is_tft;
--	int lcd_enabled, crt_enabled;
-+	u16 *p = (u16 *) a;
-+	u16 l = v & 0xffff;
-+	u16 h = v >> 16;
- 
--	panel = e1355_read_reg(E1355_PANEL);
--	display = e1355_read_reg(E1355_DISPLAY);
-+	fb_writew(l, p);
-+	fb_writew(h, p + 1);
-+}
- 
--	is_color = (panel & 0x04) != 0;
--	is_dual  = (panel & 0x02) != 0;
--	is_tft   = (panel & 0x01) != 0;
-+static inline unsigned long epson1355fb_fb_readl(const unsigned long *a)
-+{
-+	const u16 *p = (u16 *) a;
-+	u16 l = fb_readw(p);
-+	u16 h = fb_readw(p + 1);
- 
--	bpp = bpp_tab[(display>>2)&7]; 
--	e1355_bpp_to_var(bpp, var);
-+	return (h << 16) | l;
-+}
- 
--	crt_enabled = (display & 0x02) != 0;
--	lcd_enabled = (display & 0x02) != 0;
-+#define FB_READL epson1355fb_fb_readl
-+#define FB_WRITEL epson1355fb_fb_writel
- 
--	hw_bpp = width[is_tft][(panel>>4)&3];
-+/* ------------------------------------------------------------------------- */
- 
--	xres = e1355_read_reg(0x04) + 1;
--	yres = e1355_read_reg16(0x08) + 1;
--	
--	xres *= 8;
--	/* talk about weird hardware .. */
--	yres *= (is_dual && !crt_enabled) ? 2 : 1;
--
--	xres_virtual = e1355_read_reg16(0x16);
--	/* it's in 2-byte words initially */
--	xres_virtual *= 16;
--	xres_virtual /= var->bits_per_pixel;
-+static inline unsigned long copy_from_user16(void *to, const void *from,
-+					     unsigned long n)
-+{
-+	u16 *dst = (u16 *) to;
-+	u16 *src = (u16 *) from;
- 
--	var->xres = xres;
--	var->yres = yres;
--	var->xres_virtual = xres_virtual;
--	var->yres_virtual = yres;
-+	if (!access_ok(VERIFY_READ, from, n))
-+		return n;
- 
--	var->xoffset = var->yoffset = 0;
-+	while (n > 1) {
-+		u16 v;
-+		if (__get_user(v, src))
-+			return n;
- 
--	var->grayscale = !is_color;
--	
--	return 0;
--}
-+		fb_writew(v, dst);
- 
--#define is_dual(panel) (((panel)&3)==2)
-+		src++, dst++;
-+		n -= 2;
-+	}
- 
--static void get_panel_data(struct e1355_par *par)
--{
--	u8 panel;
--	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
-+	if (n) {
-+		u8 v;
- 
--	panel = e1355_read_reg(E1355_PANEL);
-+		if (__get_user(v, ((u8 *) src)))
-+			return n;
- 
--	par->panel_width = width[panel&1][(panel>>4)&3];
--	par->panel_xres = (e1355_read_reg(0x04) + 1) * 8;
--	par->panel_ymul = is_dual(panel) ? 2 : 1;
--	par->panel_yres = ((e1355_read_reg16(0x08) + 1)
--			   * par->panel_ymul);
-+		fb_writeb(v, dst);
-+	}
-+	return 0;
- }
- 
--static void e1355_get_par(void *raw_par, struct fb_info_gen *info)
-+static inline unsigned long copy_to_user16(void *to, const void *from,
-+					   unsigned long n)
- {
--	struct e1355_par *par = raw_par;
-+	u16 *dst = (u16 *) to;
-+	u16 *src = (u16 *) from;
- 
--	get_panel_data(par);
--}
-+	if (!access_ok(VERIFY_WRITE, to, n))
-+		return n;
- 
--static void e1355_set_par(const void *par, struct fb_info_gen *info)
--{
--}
-+	while (n > 1) {
-+		u16 v = fb_readw(src);
- 
--static int e1355_getcolreg(unsigned regno, unsigned *red, unsigned *green,
--			   unsigned *blue, unsigned *transp,
--			   struct fb_info *info)
--{
--	u8 r, g, b;
-+		if (__put_user(v, dst))
-+			return n;
- 
--	e1355_write_reg(regno, E1355_LUT_INDEX);
--	r = e1355_read_reg(E1355_LUT_DATA);
--	g = e1355_read_reg(E1355_LUT_DATA);
--	b = e1355_read_reg(E1355_LUT_DATA);
-+		src++, dst++;
-+		n -= 2;
-+	}
- 
--	*red = r << 8;
--	*green = g << 8;
--	*blue = b << 8;
-+	if (n) {
-+		u8 v = fb_readb(src);
- 
-+		if (__put_user(v, ((u8 *) dst)))
-+			return n;
-+	}
- 	return 0;
- }
- 
--static int e1355fb_setcolreg(unsigned regno, unsigned red, unsigned green,
--			     unsigned blue, unsigned transp,
--			     struct fb_info *info)
--{
--	u8 r = (red >> 8) & 0xf0;
--	u8 g = (green>>8) & 0xf0;
--	u8 b = (blue>> 8) & 0xf0;
--
--	e1355_write_reg(regno, E1355_LUT_INDEX);
--	e1355_write_reg(r, E1355_LUT_DATA);
--	e1355_write_reg(g, E1355_LUT_DATA);
--	e1355_write_reg(b, E1355_LUT_DATA);
--	
--	return 0;
--}
- 
--static int e1355_pan_display(const struct fb_var_screeninfo *var,
--			     struct fb_info_gen *info)
-+static ssize_t
-+epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
- {
--	BUG();
--	
--	return -EINVAL;
-+	unsigned long p = *ppos;
-+
-+	/* from fbmem.c except for our own copy_*_user */
-+	if (p >= info.fix.smem_len)
-+		return 0;
-+	if (count >= info.fix.smem_len)
-+		count = info.fix.smem_len;
-+	if (count + p > info.fix.smem_len)
-+		count = info.fix.smem_len - p;
-+
-+	if (count) {
-+		char *base_addr;
-+
-+		base_addr = info.screen_base;
-+		count -= copy_to_user16(buf, base_addr + p, count);
-+		if (!count)
-+			return -EFAULT;
-+		*ppos += count;
-+	}
-+	return count;
- }
- 
--/*
-- * The AERO_HACKS parts disable/enable the backlight on the Compaq Aero 8000.
-- * I'm not sure they aren't dangerous to the hardware, so be warned.
-- */
--#undef AERO_HACKS
-+static ssize_t
-+epson1355fb_write(struct file *file, const char *buf,
-+		  size_t count, loff_t * ppos)
-+{
-+	unsigned long p = *ppos;
-+	int err;
-+
-+	/* from fbmem.c except for our own copy_*_user */
-+	if (p > info.fix.smem_len)
-+		return -ENOSPC;
-+	if (count >= info.fix.smem_len)
-+		count = info.fix.smem_len;
-+	err = 0;
-+	if (count + p > info.fix.smem_len) {
-+		count = info.fix.smem_len - p;
-+		err = -ENOSPC;
-+	}
- 
--static int e1355_blank(int blank_mode, struct fb_info_gen *info)
--{
--	u8 disp;
-+	if (count) {
-+		char *base_addr;
- 
--	switch (blank_mode) {
--	case VESA_NO_BLANKING:
--		disp = e1355_read_reg(E1355_DISPLAY);
--		disp |= 1;
--		e1355_write_reg(disp, E1355_DISPLAY);
-- 		
--#ifdef AERO_HACKS
--		e1355_write_reg(0x6, 0x20);
--#endif
--		break;
-+		base_addr = info.screen_base;
-+		count -= copy_from_user16(base_addr + p, buf, count);
-+		*ppos += count;
-+		err = -EFAULT;
-+	}
-+	if (count)
-+		return count;
-+	return err;
-+}
-+
-+/* ------------------------------------------------------------------------- */
-+
-+static struct fb_ops epson1355fb_fbops = {
-+	.owner 		= THIS_MODULE,
-+	.fb_setcolreg 	= epson1355fb_setcolreg,
-+	.fb_pan_display = epson1355fb_pan_display,
-+	.fb_blank 	= epson1355fb_blank,
-+	.fb_fillrect 	= cfb_fillrect,
-+	.fb_copyarea 	= cfb_copyarea,
-+	.fb_imageblit 	= cfb_imageblit,
-+	.fb_read 	= epson1355fb_read,
-+	.fb_write 	= epson1355fb_write,
-+	.fb_cursor 	= soft_cursor,
-+};
- 
--	case VESA_VSYNC_SUSPEND:
--	case VESA_HSYNC_SUSPEND:
--	case VESA_POWERDOWN:
--		disp = e1355_read_reg(E1355_DISPLAY);
--		disp &= ~1;
--		e1355_write_reg(disp, E1355_DISPLAY);
-+/* ------------------------------------------------------------------------- */
- 
--#ifdef AERO_HACKS
--		e1355_write_reg(0x0, 0x20);
--#endif
--		break;
-+static __init unsigned int get_fb_size(struct fb_info *info)
-+{
-+	unsigned int size = 2 * 1024 * 1024;
-+	char *p = info->screen_base;
- 
--	default:
--		return -EINVAL;
--	}
-+	/* the 512k framebuffer is aliased at start + 0x80000 * n */
-+	fb_writeb(1, p);
-+	fb_writeb(0, p + 0x80000);
-+	if (!fb_readb(p))
-+		size = 512 * 1024;
- 
--	return 0;
-+	fb_writeb(0, p);
-+
-+	return size;
- }
- 
--static struct display_switch e1355_dispsw;
-+static int epson1355_width_tab[2][4] __initdata =
-+    { {4, 8, 16, -1}, {9, 12, 16, -1} };
-+static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 };
- 
--static void e1355_set_disp(const void *unused, struct display *disp,
--			   struct fb_info_gen *info)
-+static void __init fetch_hw_state(struct fb_info *info)
- {
--	struct display_switch *d;
-+	struct fb_var_screeninfo *var = &info->var;
-+	struct fb_fix_screeninfo *fix = &info->fix;
-+	u8 panel, display;
-+	u16 offset;
-+	u32 xres, yres;
-+	u32 xres_virtual, yres_virtual;
-+	int bpp, lcd_bpp;
-+	int is_color, is_dual, is_tft;
-+	int lcd_enabled, crt_enabled;
-+
-+	fix->type = FB_TYPE_PACKED_PIXELS;
-+
-+	display = epson1355_read_reg(REG_DISPLAY_MODE);
-+	bpp = epson1355_bpp_tab[(display >> 2) & 7];
- 
--	disp->dispsw = &e1355_dispsw;
--	
--	switch(disp->var.bits_per_pixel) {
--#ifdef FBCON_HAS_MFB
--	case 1:
--		d = &fbcon_mfb; break;
--#endif	       
--#ifdef FBCON_HAS_CFB8
-+	switch (bpp) {
- 	case 8:
--		d = &fbcon_cfb8; break;
--#endif
-+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
-+		var->bits_per_pixel = 8;
-+		var->red.offset = var->green.offset = var->blue.offset = 0;
-+		var->red.length = var->green.length = var->blue.length = 8;
-+		break;
-+	case 16:
-+		/* 5-6-5 RGB */
-+		fix->visual = FB_VISUAL_TRUECOLOR;
-+		var->bits_per_pixel = 16;
-+		var->red.offset = 11;
-+		var->red.length = 5;
-+		var->green.offset = 5;
-+		var->green.length = 6;
-+		var->blue.offset = 0;
-+		var->blue.length = 5;
-+		break;
- 	default:
--		BUG(); break;
-+		BUG();
- 	}
- 
--	memcpy(&e1355_dispsw, d, sizeof *d);
-+	if (fix->visual == FB_VISUAL_TRUECOLOR) {
-+		info->pseudo_palette = &pseudo_palette;
-+		fb_alloc_cmap(&(info->cmap), 16, 0);
-+	} else
-+		fb_alloc_cmap(&(info->cmap), 1 << bpp, 0);
-+
-+	panel = epson1355_read_reg(REG_PANEL_TYPE);
-+	is_color = (panel & 0x04) != 0;
-+	is_dual = (panel & 0x02) != 0;
-+	is_tft = (panel & 0x01) != 0;
-+	crt_enabled = (display & 0x02) != 0;
-+	lcd_enabled = (display & 0x01) != 0;
-+	lcd_bpp = epson1355_width_tab[is_tft][(panel >> 4) & 3];
-+
-+	xres = (epson1355_read_reg(REG_HORZ_DISP_WIDTH) + 1) * 8;
-+	yres = (epson1355_read_reg16(REG_VERT_DISP_HEIGHT0) + 1) *
-+	    ((is_dual && !crt_enabled) ? 2 : 1);
-+	offset = epson1355_read_reg16(REG_MEM_ADDR_OFFSET0) & 0x7ff;
-+	xres_virtual = offset * 16 / bpp;
-+	yres_virtual = fix->smem_len / (offset * 2);
-+
-+	var->xres = xres;
-+	var->yres = yres;
-+	var->xres_virtual = xres_virtual;
-+	var->yres_virtual = yres_virtual;
-+	var->xoffset = var->yoffset = 0;
-+
-+	fix->line_length = offset * 2;
-+
-+	fix->xpanstep = 0;	/* no pan yet */
-+	fix->ypanstep = 1;
-+	fix->ywrapstep = 0;
-+	fix->accel = FB_ACCEL_NONE;
-+
-+	var->grayscale = !is_color;
- 
--	/* reading is terribly slow for us */
--#if 0 /* XXX: need to work out why this doesn't work */
--	e1355_dispsw.bmove = fbcon_redraw_bmove;
-+#ifdef DEBUG
-+	printk(KERN_INFO
-+	       "epson1355fb: xres=%d, yres=%d, "
-+	       "is_color=%d, is_dual=%d, is_tft=%d\n",
-+	       xres, yres, is_color, is_dual, is_tft);
-+	printk(KERN_INFO
-+	       "epson1355fb: bpp=%d, lcd_bpp=%d, "
-+	       "crt_enabled=%d, lcd_enabled=%d\n",
-+	       bpp, lcd_bpp, crt_enabled, lcd_enabled);
- #endif
- }
- 
--/* ------------ Interfaces to hardware functions ------------ */
- 
-+static void clearfb16(struct fb_info *info)
-+{
-+	u16 *dst = (u16 *) info->screen_base;
-+	unsigned long n = info->fix.smem_len;
- 
--struct fbgen_hwswitch e1355_switch = {
--	.detect =	e1355_detect,
--	.encode_fix =	e1355_encode_fix,
--	.decode_var =	e1355_decode_var,
--	.encode_var =	e1355_encode_var,
--	.get_par =	e1355_get_par,
--	.set_par =	e1355_set_par,
--	.getcolreg =	e1355_getcolreg,
--	.pan_display =	e1355_pan_display,
--	.blank =	e1355_blank,
--	.set_disp =	e1355_set_disp,
--};
-+	while (n > 1) {
-+		fb_writew(0, dst);
-+		dst++, n -= 2;
-+	}
- 
-+	if (n)
-+		fb_writeb(0, dst);
-+}
- 
--/* ------------ Hardware Independent Functions ------------ */
-+static void epson1355fb_deinit(void);
- 
-+int __init epson1355fb_init(void)
-+{
-+	u8 revision;
-+	int rc = 0;
- 
--static struct fb_ops e1355fb_ops = {
--	.owner =	THIS_MODULE,
--	.fb_get_fix =	fbgen_get_fix,
--	.fb_get_var =	fbgen_get_var,
--	.fb_set_var =	fbgen_set_var,
--	.fb_get_cmap =	fbgen_get_cmap,
--	.fb_set_cmap =	gen_set_cmap,
--	.fb_setcolreg =	e1355fb_setcolreg,
--	.fb_pan_display =fbgen_pan_display,
--	.fb_blank =	fbgen_blank,
--};
-+	if (!request_mem_region
-+	    (EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN,
-+	     "S1D13505 registers")) {
-+		printk(KERN_ERR "epson1355fb: unable to reserve "
-+		       "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS);
-+		rc = -EBUSY;
-+		goto bail;
-+	}
- 
--static struct e1355fb_info fb_info;
-+	if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN,
-+				"S1D13505 framebuffer")) {
-+		printk(KERN_ERR "epson1355fb: unable to reserve "
-+		       "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS);
-+		rc = -EBUSY;
-+		goto bail;
-+	}
-+
-+	par.reg_addr = (unsigned long)
-+	    ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
-+	if (!par.reg_addr) {
-+		printk(KERN_ERR "epson1355fb: unable to map registers\n");
-+		rc = -ENOMEM;
-+		goto bail;
-+	}
-+
-+	info.screen_base =
-+	    ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
-+	if (!info.screen_base) {
-+		printk(KERN_ERR
-+		       "epson1355fb: unable to map framebuffer\n");
-+		rc = -ENOMEM;
-+		goto bail;
-+	}
-+
-+	revision = epson1355_read_reg(REG_REVISION_CODE);
-+	if ((revision >> 2) != 3) {
-+		printk(KERN_INFO "epson1355fb: epson1355 not found\n");
-+		rc = -ENODEV;
-+		goto bail;
-+	}
-+
-+	info.fix.mmio_start = EPSON1355FB_REGS_PHYS;
-+	info.fix.mmio_len = EPSON1355FB_REGS_LEN;
-+	info.fix.smem_start = EPSON1355FB_FB_PHYS;
-+	info.fix.smem_len = get_fb_size(&info);
-+
-+	printk(KERN_INFO
-+	       "epson1355fb: regs mapped at 0x%lx, fb %d KiB mapped at 0x%p\n",
-+	       par.reg_addr, info.fix.smem_len / 1024, info.screen_base);
-+
-+	strcpy(info.fix.id, "S1D13505");
-+	info.par = &par;
-+	info.node = NODEV;
-+	info.fbops = &epson1355fb_fbops;
-+	info.flags = FBINFO_FLAG_DEFAULT;
-+
-+	/* we expect the boot loader to have initialized the chip
-+	   with appropriate parameters from which we can determinte
-+	   the flavor of lcd panel attached */
-+	fetch_hw_state(&info);
-+
-+	/* turn this puppy on ... */
-+	clearfb16(&info);
-+	backlight_enable(1);
-+	lcd_enable(1);
-+
-+	if (register_framebuffer(&info) < 0) {
-+		rc = -EINVAL;
-+		goto bail;
-+	}
-+
-+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-+	       minor(info.node), info.fix.id);
- 
--int __init e1355fb_setup(char *str)
--{
- 	return 0;
-+
-+      bail:
-+	epson1355fb_deinit();
-+	return rc;
- }
- 
--int __init e1355fb_init(void)
-+static void epson1355fb_deinit(void)
- {
--	fb_info.gen.fbhw = &e1355_switch;
--	fb_info.gen.fbhw->detect();
--	strcpy(fb_info.gen.info.modename, "SED1355");
--	fb_info.gen.info.changevar = NULL;
--	fb_info.gen.info.fbops = &e1355fb_ops;
--	fb_info.gen.info.screen_base = (void *)E1355_FB_BASE;
--	fb_info.gen.currcon = -1;
--	fb_info.gen.info.disp = &disp;
--	fb_info.gen.parsize = sizeof(struct e1355_par);
--	fb_info.gen.info.switch_con = &fbgen_switch;
--	fb_info.gen.info.updatevar = &fbgen_update_var;
--	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
--	/* This should give a reasonable default video mode */
--	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
--	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
--	fbgen_set_disp(-1, &fb_info.gen);
--	if (disp.var.bits_per_pixel > 1) 
--		do_install_cmap(0, &fb_info.gen);
--	if (register_framebuffer(&fb_info.gen.info) < 0)
--		return -EINVAL;
--	printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.gen.info.node,
--	       fb_info.gen.info.modename);
-+	fb_dealloc_cmap(&info.cmap);
- 
--	return 0;
-+	if (info.screen_base)
-+		iounmap(info.screen_base);
-+	if (par.reg_addr)
-+		iounmap((void *) par.reg_addr);
-+
-+	release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
-+	release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
- }
- 
-+static void __exit epson1355fb_cleanup(void)
-+{
-+	backlight_enable(0);
-+	lcd_enable(0);
- 
--    /*
--     *  Cleanup
--     */
--
--void e1355fb_cleanup(struct fb_info *info)
--{
--	/*
--	 *  If your driver supports multiple boards, you should unregister and
--	 *  clean up all instances.
--	 */
--	
--	unregister_framebuffer(info);
--	/* ... */
-+	unregister_framebuffer(&info);
-+	epson1355fb_deinit();
- }
- 
-+/* ------------------------------------------------------------------------- */
-+
-+#ifdef MODULE
-+module_init(epson1355fb_init);
-+#endif
-+module_exit(epson1355fb_cleanup);
-+
-+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
-+MODULE_DESCRIPTION("Framebuffer driver for Epson S1D13505");
- MODULE_LICENSE("GPL");
---- linux-2.6.0-test1/drivers/video/fbmem.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/video/fbmem.c	2003-07-19 17:04:55.000000000 -0700
-@@ -25,7 +25,6 @@
- #include <linux/mman.h>
- #include <linux/tty.h>
- #include <linux/init.h>
--#include <linux/linux_logo.h>
- #include <linux/proc_fs.h>
- #ifdef CONFIG_KMOD
- #include <linux/kmod.h>
-@@ -102,13 +101,13 @@ extern int hgafb_setup(char*);
- extern int matroxfb_init(void);
- extern int matroxfb_setup(char*);
- extern int hpfb_init(void);
--extern int control_init(void);
--extern int control_setup(char*);
--extern int platinum_init(void);
--extern int platinum_setup(char*);
-+extern int controlfb_init(void);
-+extern int controlfb_setup(char*);
-+extern int platinumfb_init(void);
-+extern int platinumfb_setup(char*);
- extern int valkyriefb_init(void);
- extern int valkyriefb_setup(char*);
--extern int chips_init(void);
-+extern int chipsfb_init(void);
- extern int g364fb_init(void);
- extern int sa1100fb_init(void);
- extern int fm2fb_init(void);
-@@ -135,8 +134,7 @@ extern int tx3912fb_init(void);
- extern int tx3912fb_setup(char*);
- extern int radeonfb_init(void);
- extern int radeonfb_setup(char*);
--extern int e1355fb_init(void);
--extern int e1355fb_setup(char*);
-+extern int epson1355fb_init(void);
- extern int pvr2fb_init(void);
- extern int pvr2fb_setup(char*);
- extern int sstfb_init(void);
-@@ -218,16 +216,16 @@ static struct {
- 	{ "radeonfb", radeonfb_init, radeonfb_setup },
- #endif
- #ifdef CONFIG_FB_CONTROL
--	{ "controlfb", control_init, control_setup },
-+	{ "controlfb", controlfb_init, controlfb_setup },
- #endif
- #ifdef CONFIG_FB_PLATINUM
--	{ "platinumfb", platinum_init, platinum_setup },
-+	{ "platinumfb", platinumfb_init, platinumfb_setup },
- #endif
- #ifdef CONFIG_FB_VALKYRIE
- 	{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
- #endif
- #ifdef CONFIG_FB_CT65550
--	{ "chipsfb", chips_init, NULL },
-+	{ "chipsfb", chipsfb_init, NULL },
- #endif
- #ifdef CONFIG_FB_IMSTT
- 	{ "imsttfb", imsttfb_init, imsttfb_setup },
-@@ -342,8 +340,8 @@ static struct {
- #ifdef CONFIG_FB_TX3912
- 	{ "tx3912fb", tx3912fb_init, tx3912fb_setup },
- #endif
--#ifdef CONFIG_FB_E1355
--	{ "e1355fb", e1355fb_init, e1355fb_setup },
-+#ifdef CONFIG_FB_EPSON1355
-+	{ "s1d1355fb", epson1355fb_init, NULL },
- #endif
- #ifdef CONFIG_FB_PVR2
- 	{ "pvr2fb", pvr2fb_init, pvr2fb_setup },
-@@ -409,20 +407,20 @@ void sys_outbuf(u8 *src, u8 *dst, unsign
- 	memcpy(dst, src, size);
- }	
- 
--void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
--			u32 s_pitch, u32 height)
-+void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
-+			u32 d_pitch, u32 s_pitch, u32 height)
- {
- 	int i;
- 
- 	for (i = height; i--; ) {
--		info->pixmap.outbuf(src, dst, s_pitch);
-+		buf->outbuf(src, dst, s_pitch);
- 		src += s_pitch;
- 		dst += d_pitch;
- 	}
- }
- 
--void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
--			u32 height, u32 mask, u32 shift_high, u32 shift_low,
-+void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src, 
-+			u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
- 			u32 mod, u32 idx)
- {
- 	int i, j;
-@@ -430,21 +428,21 @@ void move_buf_unaligned(struct fb_info *
- 
- 	for (i = height; i--; ) {
- 		for (j = 0; j < idx; j++) {
--			tmp = info->pixmap.inbuf(dst+j);
-+			tmp = buf->inbuf(dst+j);
- 			tmp &= mask;
- 			tmp |= *src >> shift_low;
--			info->pixmap.outbuf(&tmp, dst+j, 1);
-+			buf->outbuf(&tmp, dst+j, 1);
- 			tmp = *src << shift_high;
--			info->pixmap.outbuf(&tmp, dst+j+1, 1);
-+			buf->outbuf(&tmp, dst+j+1, 1);
- 			src++;
- 		}
--		tmp = info->pixmap.inbuf(dst+idx);
-+		tmp = buf->inbuf(dst+idx);
- 		tmp &= mask;
- 		tmp |= *src >> shift_low;
--		info->pixmap.outbuf(&tmp, dst+idx, 1);
-+		buf->outbuf(&tmp, dst+idx, 1);
- 		if (shift_high < mod) {
- 			tmp = *src << shift_high;
--			info->pixmap.outbuf(&tmp, dst+idx+1, 1);
-+			buf->outbuf(&tmp, dst+idx+1, 1);
- 		}	
- 		src++;
- 		dst += d_pitch;
-@@ -455,26 +453,29 @@ void move_buf_unaligned(struct fb_info *
-  * we need to lock this section since fb_cursor
-  * may use fb_imageblit()
-  */
--u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
-+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
- {
--	u32 align = info->pixmap.buf_align - 1;
-+	u32 align = buf->buf_align - 1;
- 	u32 offset, count = 1000;
-+	char *addr = buf->addr;
- 
--	spin_lock(&info->pixmap.lock);
--	offset = info->pixmap.offset + align;
--	offset &= ~align;
--	if (offset + size > info->pixmap.size) {
--		while (atomic_read(&info->pixmap.count) && count--);
--		if (info->fbops->fb_sync && 
--		    info->pixmap.flags & FB_PIXMAP_SYNC)
--			info->fbops->fb_sync(info);
--		offset = 0;
-+	spin_lock(&buf->lock);
-+	if (!(buf->flags & FB_PIXMAP_IO)) { 
-+		offset = buf->offset + align;
-+		offset &= ~align;
-+		if (offset + size > buf->size) {
-+			while (atomic_read(&buf->count) && count--);
-+			if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
-+				info->fbops->fb_sync(info);
-+			offset = 0;
-+		}
-+		buf->offset = offset + size;
-+		addr += offset;	
- 	}
--	info->pixmap.offset = offset + size;
--	atomic_inc(&info->pixmap.count);	
-+	atomic_inc(&buf->count);
- 	smp_mb__after_atomic_inc();
--	spin_unlock(&info->pixmap.lock);
--	return offset;
-+	spin_unlock(&buf->lock);
-+	return addr;
- }
- 
- #ifdef CONFIG_LOGO
-@@ -656,7 +657,7 @@ int fb_prepare_logo(struct fb_info *info
- 	}
- 
- 	/* Return if no suitable logo was found */
--	fb_logo.logo = fb_find_logo(info->var.bits_per_pixel);
-+	fb_logo.logo = find_logo(info->var.bits_per_pixel);
- 	
- 	if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
- 		fb_logo.logo = NULL;
-@@ -726,8 +727,6 @@ int fb_show_logo(struct fb_info *info)
- 	     x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
- 		image.dx = x;
- 		info->fbops->fb_imageblit(info, &image);
--		//atomic_dec(&info->pixmap.count);
--		//smp_mb__after_atomic_dec();
- 	}
- 	
- 	if (palette != NULL)
-@@ -1238,6 +1237,22 @@ register_framebuffer(struct fb_info *fb_
- 		fb_info->pixmap.inbuf = sys_inbuf;
- 	spin_lock_init(&fb_info->pixmap.lock);
- 
-+	if (fb_info->sprite.addr == NULL) {
-+		fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
-+		if (fb_info->sprite.addr) {
-+			fb_info->sprite.size = FBPIXMAPSIZE;
-+			fb_info->sprite.buf_align = 1;
-+			fb_info->sprite.scan_align = 1;
-+			fb_info->sprite.flags = FB_PIXMAP_IO;
-+		}
-+	}	
-+	fb_info->sprite.offset = 0;
-+	if (fb_info->sprite.outbuf == NULL)
-+		fb_info->sprite.outbuf = sys_outbuf;
-+	if (fb_info->sprite.inbuf == NULL)
-+		fb_info->sprite.inbuf = sys_inbuf;
-+	spin_lock_init(&fb_info->sprite.lock);
-+
- 	registered_fb[i] = fb_info;
- 
- 	devfs_mk_cdev(MKDEV(FB_MAJOR, i),
---- linux-2.6.0-test1/drivers/video/g364fb.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/video/g364fb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -127,20 +127,55 @@ static struct fb_ops g364fb_ops = {
- 
- int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
- {
-+
-+	/* Turn the cursor off before we start changing it. */
-+	*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
-+
-+	if (cursor->set & FB_CUR_SETHOT)
-+		info->cursor.hot = cursor->hot;
- 	
--	switch (cursor->enable) {
--	case CM_ERASE:
--		*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
--		break;
-+	if (cursor->set & FB_CUR_SETPOS) {
-+		unsigned int tmp;
-+		
-+		info->cursor.image.dx = cursor->image.dx;
-+		info->cursor.image.dy = cursor->image.dy;
-+
-+		tmp = cursor->image.dy - info->var.yoffset;
-+		tmp |= (cursor->image.dx - info->var.xoffset) << 12;	
-+		
-+		*(unsigned int *) CURS_POS_REG = tmp;
-+	}
- 
--	case CM_MOVE:
--	case CM_DRAW:
-+	if (cursor->set & FB_CUR_SETSIZE) {
-+		info->cursor.image.height = cursor->image.height;
-+		info->cursor.image.width = cursor->image.width;
-+	
-+	 	/* set the whole cursor to transparent */
-+		for (i = 0; i < 512; i++)
-+			*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
-+	}	
-+
-+	if (cursor->set & FB_CUR_SETCMAP) {
-+		volatile unsigned int *curs_pal_ptr =
-+	    			(volatile unsigned int *) CURS_PAL_REG;
-+
-+		/* setup cursor */
-+		curs_pal_ptr[0] |= 0x00ffffff;
-+		curs_pal_ptr[2] |= 0x00ffffff;
-+		curs_pal_ptr[4] |= 0x00ffffff;
-+	}	
-+	
-+	if (cursor->set & FB_CUR_SETSHAPE) {
-+		/*
-+	 	 * switch the last two lines to cursor palette 3
-+	 	 * we assume here, that FONTSIZE_X is 8
-+	 	 */
-+		*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
-+		*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
-+	}	
-+	
-+	if (info->cursor.enable)
- 		*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
--		*(unsigned int *) CURS_POS_REG =
--		    ((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
--						  info->var.yoffset);
--		break;
--	}
- 	return 0;
- }
- 
-@@ -196,10 +231,6 @@ static int g364fb_setcolreg(u_int regno,
-  */
- int __init g364fb_init(void)
- {
--	volatile unsigned int *pal_ptr =
--	    (volatile unsigned int *) CLR_PAL_REG;
--	volatile unsigned int *curs_pal_ptr =
--	    (volatile unsigned int *) CURS_PAL_REG;
- 	int mem, i, j;
- 
- 	/* TBD: G364 detection */
-@@ -212,23 +243,6 @@ int __init g364fb_init(void)
- 	    (*((volatile unsigned int *) VDISPLAY_REG) & 0x00ffffff) / 2;
- 	*(volatile unsigned int *) CTLA_REG |= ENABLE_VTG;
- 
--	/* setup cursor */
--	curs_pal_ptr[0] |= 0x00ffffff;
--	curs_pal_ptr[2] |= 0x00ffffff;
--	curs_pal_ptr[4] |= 0x00ffffff;
--
--	/*
--	 * first set the whole cursor to transparent
--	 */
--	for (i = 0; i < 512; i++)
--		*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
--
--	/*
--	 * switch the last two lines to cursor palette 3
--	 * we assume here, that FONTSIZE_X is 8
--	 */
--	*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
--	*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
- 	fb_var.xres_virtual = fbvar.xres;
- 	fb_fix.line_length = (xres / 8) * fb_var.bits_per_pixel;
- 	fb_fix.smem_start = 0x40000000;	/* physical address */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/video/i2c.c	2003-07-19 17:04:55.000000000 -0700
-@@ -0,0 +1,333 @@
-+/*
-+ *   Generic i2c interface for the framebuffer layer 
-+ *
-+ *   (c) 2003 "Crazy" James Simmons <jsimmons@infradead.org>
-+ * 	Based on the ALSA i2c interface 
-+ *   		Gerd Knorr <kraxel@cs.tu-berlin.de>
-+ *   		Jaroslav Kysela <perex@suse.cz>
-+ *
-+ *   This program 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.
-+ *
-+ *   This program is distributed in the hope that it will be useful,
-+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *   GNU General Public License for more details.
-+ *
-+ *   You should have received a copy of the GNU General Public License
-+ *   along with this program; if not, write to the Free Software
-+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/fb.h>
-+#include "i2c.h"
-+
-+MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
-+MODULE_DESCRIPTION("Generic i2c interface for the Framebuffer layer");
-+MODULE_LICENSE("GPL");
-+
-+static int fb_i2c_bit_sendbytes(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+static int fb_i2c_bit_readbytes(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+static int fb_i2c_bit_probeaddr(fb_i2c_bus_t *bus, unsigned short addr);
-+
-+static fb_i2c_ops_t fb_i2c_bit_ops = {
-+	.sendbytes = fb_i2c_bit_sendbytes,
-+	.readbytes = fb_i2c_bit_readbytes,
-+	.probeaddr = fb_i2c_bit_probeaddr,
-+};
-+
-+static int fb_i2c_bus_free(fb_i2c_bus_t *bus)
-+{
-+	fb_i2c_bus_t *slave;
-+	fb_i2c_device_t *device;
-+
-+	fb_assert(bus != NULL, return -EINVAL);
-+	while (!list_empty(&bus->devices)) {
-+		device = fb_i2c_device(bus->devices.next);
-+		fb_i2c_device_free(device);
-+	}
-+	if (bus->master)
-+		list_del(&bus->buses);
-+	else {
-+		while (!list_empty(&bus->buses)) {
-+			slave = fb_i2c_slave_bus(bus->buses.next);
-+			fb_device_free(bus->card, slave);
-+		}
-+	}
-+	if (bus->private_free)
-+		bus->private_free(bus);
-+	fb_magic_kfree(bus);
-+	return 0;
-+}
-+
-+static int fb_i2c_bus_dev_free(fb_device_t *device)
-+{
-+	fb_i2c_bus_t *bus = fb_magic_cast(fb_i2c_bus_t, device->device_data, return -ENXIO);
-+	return fb_i2c_bus_free(bus);
-+}
-+
-+int fb_i2c_bus_create(fb_card_t *card, const char *name, fb_i2c_bus_t *master, fb_i2c_bus_t **ri2c)
-+{
-+	static fb_device_ops_t ops = {
-+		.dev_free =	fb_i2c_bus_dev_free,
-+	};
-+	fb_i2c_bus_t *bus;
-+	int err;
-+	
-+	*ri2c = NULL;
-+	bus = (fb_i2c_bus_t *)fb_magic_kcalloc(fb_i2c_bus_t, 0, GFP_KERNEL);
-+	if (bus == NULL)
-+		return -ENOMEM;
-+	spin_lock_init(&bus->lock);
-+	INIT_LIST_HEAD(&bus->devices);
-+	INIT_LIST_HEAD(&bus->buses);
-+	bus->card = card;
-+	bus->ops = &fb_i2c_bit_ops;
-+	if (master) {
-+		list_add_tail(&bus->buses, &master->buses);
-+		bus->master = master;
-+	}
-+	strlcpy(bus->name, name, sizeof(bus->name));
-+	if ((err = fb_device_new(card, SNDRV_DEV_LOWLEVEL, bus, &ops)) < 0) {
-+		fb_i2c_bus_free(bus);
-+		return err;
-+	}
-+	*ri2c = bus;
-+	return 0;
-+}
-+
-+int fb_i2c_device_create(fb_i2c_bus_t *bus, const char *name, unsigned char addr, fb_i2c_device_t **rdevice)
-+{
-+	fb_i2c_device_t *device;
-+
-+	*rdevice = NULL;
-+	fb_assert(bus != NULL, return -EINVAL);
-+	device = (fb_i2c_device_t *)fb_magic_kcalloc(fb_i2c_device_t, 0, GFP_KERNEL);
-+	if (device == NULL)
-+		return -ENOMEM;
-+	device->addr = addr;
-+	strlcpy(device->name, name, sizeof(device->name));
-+	list_add_tail(&device->list, &bus->devices);
-+	device->bus = bus;
-+	*rdevice = device;
-+	return 0;
-+}
-+
-+int fb_i2c_device_free(fb_i2c_device_t *device)
-+{
-+	if (device->bus)
-+		list_del(&device->list);
-+	if (device->private_free)
-+		device->private_free(device);
-+	fb_magic_kfree(device);
-+	return 0;
-+}
-+
-+int fb_i2c_sendbytes(fb_i2c_device_t *device, unsigned char *bytes, int count)
-+{
-+	return device->bus->ops->sendbytes(device, bytes, count);
-+}
-+
-+
-+int fb_i2c_readbytes(fb_i2c_device_t *device, unsigned char *bytes, int count)
-+{
-+	return device->bus->ops->readbytes(device, bytes, count);
-+}
-+
-+int fb_i2c_probeaddr(fb_i2c_bus_t *bus, unsigned short addr)
-+{
-+	return bus->ops->probeaddr(bus, addr);
-+}
-+
-+/*
-+ *  bit-operations
-+ */
-+
-+static inline void fb_i2c_bit_hw_start(fb_i2c_bus_t *bus)
-+{
-+	if (bus->hw_ops.bit->start)
-+		bus->hw_ops.bit->start(bus);
-+}
-+
-+static inline void fb_i2c_bit_hw_stop(fb_i2c_bus_t *bus)
-+{
-+	if (bus->hw_ops.bit->stop)
-+		bus->hw_ops.bit->stop(bus);
-+}
-+
-+static void fb_i2c_bit_direction(fb_i2c_bus_t *bus, int clock, int data)
-+{
-+	if (bus->hw_ops.bit->direction)
-+		bus->hw_ops.bit->direction(bus, clock, data);
-+}
-+
-+static void fb_i2c_bit_set(fb_i2c_bus_t *bus, int clock, int data)
-+{
-+	bus->hw_ops.bit->setlines(bus, clock, data);
-+}
-+
-+#if 0
-+static int fb_i2c_bit_clock(fb_i2c_bus_t *bus)
-+{
-+	if (bus->hw_ops.bit->getclock)
-+		return bus->hw_ops.bit->getclock(bus);
-+	return -ENXIO;
-+}
-+#endif
-+
-+static int fb_i2c_bit_data(fb_i2c_bus_t *bus, int ack)
-+{
-+	return bus->hw_ops.bit->getdata(bus, ack);
-+}
-+
-+static void fb_i2c_bit_start(fb_i2c_bus_t *bus)
-+{
-+	fb_i2c_bit_hw_start(bus);
-+	fb_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
-+	fb_i2c_bit_set(bus, 1, 1);
-+	fb_i2c_bit_set(bus, 1, 0);
-+	fb_i2c_bit_set(bus, 0, 0);
-+}
-+
-+static void fb_i2c_bit_stop(fb_i2c_bus_t *bus)
-+{
-+	fb_i2c_bit_set(bus, 0, 0);
-+	fb_i2c_bit_set(bus, 1, 0);
-+	fb_i2c_bit_set(bus, 1, 1);
-+	fb_i2c_bit_hw_stop(bus);
-+}
-+
-+static void fb_i2c_bit_send(fb_i2c_bus_t *bus, int data)
-+{
-+	fb_i2c_bit_set(bus, 0, data);
-+	fb_i2c_bit_set(bus, 1, data);
-+	fb_i2c_bit_set(bus, 0, data);
-+}
-+
-+static int fb_i2c_bit_ack(fb_i2c_bus_t *bus)
-+{
-+	int ack;
-+
-+	fb_i2c_bit_set(bus, 0, 1);
-+	fb_i2c_bit_set(bus, 1, 1);
-+	fb_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
-+	ack = fb_i2c_bit_data(bus, 1);
-+	fb_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
-+	fb_i2c_bit_set(bus, 0, 1);
-+	return ack ? -EIO : 0;
-+}
-+
-+static int fb_i2c_bit_sendbyte(fb_i2c_bus_t *bus, unsigned char data)
-+{
-+	int i, err;
-+
-+	for (i = 7; i >= 0; i--)
-+		fb_i2c_bit_send(bus, !!(data & (1 << i)));
-+	if ((err = fb_i2c_bit_ack(bus)) < 0)
-+		return err;
-+	return 0;
-+}
-+
-+static int fb_i2c_bit_readbyte(fb_i2c_bus_t *bus, int last)
-+{
-+	int i;
-+	unsigned char data = 0;
-+
-+	fb_i2c_bit_set(bus, 0, 1);
-+	fb_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
-+	for (i = 7; i >= 0; i--) {
-+		fb_i2c_bit_set(bus, 1, 1);
-+		if (fb_i2c_bit_data(bus, 0))
-+			data |= (1 << i);
-+		fb_i2c_bit_set(bus, 0, 1);
-+	}
-+	fb_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
-+	fb_i2c_bit_send(bus, !!last);
-+	return data;
-+}
-+
-+static int fb_i2c_bit_sendbytes(fb_i2c_device_t *device, unsigned char *bytes, int count)
-+{
-+	fb_i2c_bus_t *bus = device->bus;
-+	int err, res = 0;
-+
-+	if (device->flags & FB_I2C_DEVICE_ADDRTEN)
-+		return -EIO;		/* not yet implemented */
-+	fb_i2c_bit_start(bus);
-+	if ((err = fb_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) {
-+		fb_i2c_bit_hw_stop(bus);
-+		return err;
-+	}
-+	while (count-- > 0) {
-+		if ((err = fb_i2c_bit_sendbyte(bus, *bytes++)) < 0) {
-+			fb_i2c_bit_hw_stop(bus);
-+			return err;
-+		}
-+		res++;
-+	}
-+	fb_i2c_bit_stop(bus);
-+	return res;
-+}
-+
-+static int fb_i2c_bit_readbytes(fb_i2c_device_t *device, unsigned char *bytes, int count)
-+{
-+	fb_i2c_bus_t *bus = device->bus;
-+	int err, res = 0;
-+
-+	if (device->flags & FB_I2C_DEVICE_ADDRTEN)
-+		return -EIO;		/* not yet implemented */
-+	fb_i2c_bit_start(bus);
-+	if ((err = fb_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) {
-+		fb_i2c_bit_hw_stop(bus);
-+		return err;
-+	}
-+	while (count-- > 0) {
-+		if ((err = fb_i2c_bit_readbyte(bus, count == 0)) < 0) {
-+			fb_i2c_bit_hw_stop(bus);
-+			return err;
-+		}
-+		*bytes++ = (unsigned char)err;
-+		res++;
-+	}
-+	fb_i2c_bit_stop(bus);
-+	return res;
-+}
-+
-+static int fb_i2c_bit_probeaddr(fb_i2c_bus_t *bus, unsigned short addr)
-+{
-+	int err;
-+
-+	if (addr & 0x8000)	/* 10-bit address */
-+		return -EIO;	/* not yet implemented */
-+	if (addr & 0x7f80)	/* invalid address */
-+		return -EINVAL;
-+	fb_i2c_bit_start(bus);
-+	err = fb_i2c_bit_sendbyte(bus, addr << 1);
-+	fb_i2c_bit_stop(bus);
-+	return err;
-+}
-+
-+EXPORT_SYMBOL(fb_i2c_bus_create);
-+EXPORT_SYMBOL(fb_i2c_device_create);
-+EXPORT_SYMBOL(fb_i2c_device_free);
-+EXPORT_SYMBOL(fb_i2c_sendbytes);
-+EXPORT_SYMBOL(fb_i2c_readbytes);
-+EXPORT_SYMBOL(fb_i2c_probeaddr);
-+
-+static int __init alsa_i2c_init(void)
-+{
-+	return 0;
-+}
-+
-+static void __exit alsa_i2c_exit(void)
-+{
-+}
-+
-+module_init(alsa_i2c_init)
-+module_exit(alsa_i2c_exit)
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/drivers/video/i2c.h	2003-07-19 17:04:55.000000000 -0700
-@@ -0,0 +1,102 @@
-+#ifndef __FB_I2C_H
-+#define __FB_I2C_H
-+
-+/*
-+ *
-+ *
-+ *   This program 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.
-+ *
-+ *   This program is distributed in the hope that it will be useful,
-+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *   GNU General Public License for more details.
-+ *
-+ *   You should have received a copy of the GNU General Public License
-+ *   along with this program; if not, write to the Free Software
-+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ *
-+ *
-+ */
-+
-+typedef struct _fb_i2c_device fb_i2c_device_t;
-+typedef struct _fb_i2c_bus fb_i2c_bus_t;
-+
-+#define FB_I2C_DEVICE_ADDRTEN	(1<<0)	/* 10-bit I2C address */
-+
-+struct _fb_i2c_device {
-+	struct list_head list;
-+	fb_i2c_bus_t *bus;	/* I2C bus */
-+	char name[32];		/* some useful device name */
-+	unsigned short flags;	/* device flags */
-+	unsigned short addr;	/* device address (might be 10-bit) */
-+	unsigned long private_value;
-+	void *private_data;
-+	void (*private_free)(fb_i2c_device_t *device);
-+};
-+
-+#define fb_i2c_device(n) list_entry(n, fb_i2c_device_t, list)
-+
-+typedef struct _fb_i2c_bit_ops {
-+	void (*start)(fb_i2c_bus_t *bus);	/* transfer start */
-+	void (*stop)(fb_i2c_bus_t *bus);	/* transfer stop */
-+	void (*direction)(fb_i2c_bus_t *bus, int clock, int data);  /* set line direction (0 = write, 1 = read) */
-+	void (*setlines)(fb_i2c_bus_t *bus, int clock, int data);
-+	int (*getclock)(fb_i2c_bus_t *bus);
-+	int (*getdata)(fb_i2c_bus_t *bus, int ack);
-+} fb_i2c_bit_ops_t;
-+
-+typedef struct _fb_i2c_ops {
-+	int (*sendbytes)(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+	int (*readbytes)(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+	int (*probeaddr)(fb_i2c_bus_t *bus, unsigned short addr);
-+} fb_i2c_ops_t;
-+
-+struct _fb_i2c_bus {
-+	fb_card_t *card;	/* card which I2C belongs to */
-+	char name[32];		/* some useful label */
-+
-+	spinlock_t lock;
-+
-+	fb_i2c_bus_t *master;	/* master bus when SCK/SCL is shared */
-+	struct list_head buses;	/* master: slave buses sharing SCK/SCL, slave: link list */
-+
-+	struct list_head devices; /* attached devices to this bus */
-+
-+	union {
-+		fb_i2c_bit_ops_t *bit;
-+		void *ops;
-+	} hw_ops;		/* lowlevel operations */
-+	fb_i2c_ops_t *ops;	/* midlevel operations */
-+
-+	unsigned long private_value;
-+	void *private_data;
-+	void (*private_free)(fb_i2c_bus_t *bus);
-+};
-+
-+#define fb_i2c_slave_bus(n) list_entry(n, fb_i2c_bus_t, buses)
-+
-+int fb_i2c_bus_create(fb_card_t *card, const char *name, fb_i2c_bus_t *master, fb_i2c_bus_t **ri2c);
-+int fb_i2c_device_create(fb_i2c_bus_t *bus, const char *name, unsigned char addr, fb_i2c_device_t **rdevice);
-+int fb_i2c_device_free(fb_i2c_device_t *device);
-+
-+static inline void fb_i2c_lock(fb_i2c_bus_t *bus) {
-+	if (bus->master)
-+		spin_lock(&bus->master->lock);
-+	else
-+		spin_lock(&bus->lock);
-+}
-+static inline void fb_i2c_unlock(fb_i2c_bus_t *bus) {
-+	if (bus->master)
-+		spin_unlock(&bus->master->lock);
-+	else
-+		spin_unlock(&bus->lock);
-+}
-+
-+int fb_i2c_sendbytes(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+int fb_i2c_readbytes(fb_i2c_device_t *device, unsigned char *bytes, int count);
-+int fb_i2c_probeaddr(fb_i2c_bus_t *bus, unsigned short addr);
-+
-+#endif /* __FB_I2C_H */
---- linux-2.6.0-test1/drivers/video/Kconfig	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/video/Kconfig	2003-07-19 17:04:55.000000000 -0700
-@@ -423,35 +423,15 @@ config FB_PVR2_DEBUG
- 	  messages. Most people will want to say N here. If unsure, you will
- 	  also want to say N.
- 
--config FB_E1355
-+config FB_EPSON1355
- 	bool "Epson 1355 framebuffer support"
--	depends on FB && SUPERH
-+	depends on FB && (SUPERH || ARCH_CEIVA)
- 	help
- 	  Build in support for the SED1355 Epson Research Embedded RAMDAC
- 	  LCD/CRT Controller (since redesignated as the S1D13505) as a
- 	  framebuffer.  Product specs at
- 	  <http://www.erd.epson.com/vdc/html/products.htm>.
- 
--config E1355_REG_BASE
--	hex "Register Base Address"
--	depends on FB_E1355
--	default "a8000000"
--	help
--	  Epson SED1355/S1D13505 LCD/CRT controller register base address.
--	  See the manuals at
--	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
--	  discussion.
--
--config E1355_FB_BASE
--	hex "Framebuffer Base Address"
--	depends on FB_E1355
--	default "a8200000"
--	help
--	  Epson SED1355/S1D13505 LCD/CRT controller memory base address.  See
--	  the manuals at
--	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
--	  discussion.
--
- config FB_RIVA
- 	tristate "nVidia Riva support"
- 	depends on FB && PCI
-@@ -725,23 +705,43 @@ config FB_SIS
- 	tristate "SIS acceleration"
- 	depends on FB && PCI
- 	help
--	  This is the frame buffer device driver for the SiS 630 and 640 Super
--	  Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
-+	  This is the frame buffer device driver for SiS VGA chipsets. It
-+	  supports the SiS 300, 540, 630, 730, 315, 550, 650, M650, 651,
-+	  740 and possibly (because untested) the Xabre (SiS330).
-+
-+	  Specs available at <http://www.sis.com.tw/>.
-+
-+	  See <http://www.winischhofer.net/linuxsisvga.shtml> for
-+	  documentation and updates.
-+
-+	  The driver is also available as a module ( = code which can be
-+	  inserted and removed from the running kernel whenever you want). The
-+	  module will be called sisfb. If you want to compile it as a
-+	  module, say M here and read Documentation/modules.txt.
- 
- config FB_SIS_300
--	bool "SIS 630/540/730 support"
-+	bool "SIS 300/630/540/730 support"
- 	depends on FB_SIS
- 	help
--	  This is the frame buffer device driver for the SiS 630 and related
--	  Super Socket 7 UMA cards.  Specs available at
--	  <http://www.sis.com.tw/>.
-+	  This is the frame buffer device driver for the SiS 300, 540, 630
-+	  and 730 VGA controllers.
-+
-+	  Specs available at <http://www.sis.com.tw/>.
-+
-+	  See <http://www.winischhofer.net/linuxsisvga.shtml> for
-+	  documentation and updates.
- 
- config FB_SIS_315
--	bool "SIS 315H/315 support"
-+	bool "SIS 315/550/65x/740/330 support"
- 	depends on FB_SIS
- 	help
--	  This is the frame buffer device driver for the SiS 315 graphics
--	  card.  Specs available at <http://www.sis.com.tw/>.
-+	  This is the frame buffer device driver for the SiS 315, 550, 65x
-+	  (650, 651, M650), 740 and Xabre (330) VGA controllers.
-+
-+	  Specs available at <http://www.sis.com.tw/>.
-+
-+	  See <http://www.winischhofer.net/linuxsisvga.shtml> for
-+	  documentation and updates.
- 
- config FB_NEOMAGIC
- 	tristate "NeoMagic display support"
---- linux-2.6.0-test1/drivers/video/logo/logo.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/video/logo/logo.c	2003-07-19 17:04:55.000000000 -0700
-@@ -32,8 +32,7 @@ extern const struct linux_logo logo_supe
- extern const struct linux_logo logo_superh_vga16;
- extern const struct linux_logo logo_superh_clut224;
- 
--
--const struct linux_logo *fb_find_logo(int depth)
-+const struct linux_logo *find_logo(int depth)
- {
- 	const struct linux_logo *logo = 0;
- 
-@@ -66,7 +65,7 @@ const struct linux_logo *fb_find_logo(in
- #endif
- #ifdef CONFIG_LOGO_DEC_CLUT224
- 		/* DEC Linux logo on MIPS/MIPS64 */
--		if (mips_machgroup == MACH_GROUP_SGI)
-+		if (mips_machgroup == MACH_GROUP_DEC)
- 			logo = &logo_dec_clut224;
- #endif
- #ifdef CONFIG_LOGO_MAC_CLUT224
---- linux-2.6.0-test1/drivers/video/macfb.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/video/macfb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -233,11 +233,11 @@ static int dafb_setpalette (unsigned int
- 		
- 		/* Loop until we get to the register we want */
- 		for (i = 0; i < regno; i++) {
--			nubus_writeb(info->cmap[i].red >> 8, &dafb_cmap_regs->lut);
-+			nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
- 			nop();
--			nubus_writeb(info->cmap[i].green >> 8, &dafb_cmap_regs->lut);
-+			nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
- 			nop();
--			nubus_writeb(info->cmap[i].blue >> 8, &dafb_cmap_regs->lut);
-+			nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
- 			nop();
- 		}
- 	}
-@@ -528,10 +528,10 @@ static int macfb_setcolreg(unsigned regn
- 	 *  != 0 for invalid regno.
- 	 */
- 	
--	if (regno >= info->cmap.len)
-+	if (regno >= fb_info->cmap.len)
- 		return 1;
- 
--	switch (info->var.bits_per_pixel) {
-+	switch (fb_info->var.bits_per_pixel) {
- 	case 1:
- 		/* We shouldn't get here */
- 		break;
-@@ -539,21 +539,21 @@ static int macfb_setcolreg(unsigned regn
- 	case 4:
- 	case 8:
- 		if (macfb_setpalette)
--			macfb_setpalette(regno, red, green, blue, info);
-+			macfb_setpalette(regno, red, green, blue, fb_info);
- 		else
- 			return 1;
- 		break;
- 	case 16:
--		if (info->var.red.offset == 10) {
-+		if (fb_info->var.red.offset == 10) {
- 			/* 1:5:5:5 */
--			((u32*) (info->pseudo_palette))[regno] =
-+			((u32*) (fb_info->pseudo_palette))[regno] =
- 					((red   & 0xf800) >>  1) |
- 					((green & 0xf800) >>  6) |
- 					((blue  & 0xf800) >> 11) |
- 					((transp != 0) << 15);
- 		} else {
- 			/* 0:5:6:5 */
--			((u32*) (info->pseudo_palette))[regno] =
-+			((u32*) (fb_info->pseudo_palette))[regno] =
- 					((red   & 0xf800)      ) |
- 					((green & 0xfc00) >>  5) |
- 					((blue  & 0xf800) >> 11);
-@@ -565,19 +565,19 @@ static int macfb_setcolreg(unsigned regn
- 		red   >>= 8;
- 		green >>= 8;
- 		blue  >>= 8;
--		((u32 *)(info->pseudo_palette))[regno] =
--			(red   << info->var.red.offset)   |
--			(green << info->var.green.offset) |
--			(blue  << info->var.blue.offset);
-+		((u32 *)(fb_info->pseudo_palette))[regno] =
-+			(red   << fb_info->var.red.offset)   |
-+			(green << fb_info->var.green.offset) |
-+			(blue  << fb_info->var.blue.offset);
- 		break;
- 	case 32:
- 		red   >>= 8;
- 		green >>= 8;
- 		blue  >>= 8;
--		((u32 *)(info->pseudo_palette))[regno] =
--			(red   << info->var.red.offset)   |
--			(green << info->var.green.offset) |
--			(blue  << info->var.blue.offset);
-+		((u32 *)(fb_info->pseudo_palette))[regno] =
-+			(red   << fb_info->var.red.offset)   |
-+			(green << fb_info->var.green.offset) |
-+			(blue  << fb_info->var.blue.offset);
- 		break;
-     }
-     return 0;
---- linux-2.6.0-test1/drivers/video/Makefile	2003-06-14 12:17:58.000000000 -0700
-+++ 25/drivers/video/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -69,7 +69,7 @@ obj-$(CONFIG_FB_SA1100)           += sa1
- obj-$(CONFIG_FB_VIRTUAL)          += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
- obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
- obj-$(CONFIG_FB_E1355)            += epson1355fb.o
--obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
-+obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
- obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
- 
- obj-$(CONFIG_FB_FFB)               += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o
---- linux-2.6.0-test1/drivers/video/neofb.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/video/neofb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -81,9 +81,10 @@ extern int tosh_smm(SMMRegisters *regs);
- #include <asm/mtrr.h>
- #endif
- 
-+#include <video/vga.h>
- #include <video/neomagic.h>
- 
--#define NEOFB_VERSION "0.4.1"
-+#define NEOFB_VERSION "0.4.2"
- 
- /* --------------------------------------------------------------------- */
- 
-@@ -370,37 +371,55 @@ static int vgaHWInit(const struct fb_var
- static void vgaHWLock(void)
- {
- 	/* Protect CRTC[0-7] */
--	VGAwCR(0x11, VGArCR(0x11) | 0x80);
-+	vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) | 0x80);
- }
- 
- static void vgaHWUnlock(void)
- {
- 	/* Unprotect CRTC[0-7] */
--	VGAwCR(0x11, VGArCR(0x11) & ~0x80);
-+	vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) & ~0x80);
- }
- 
- static void neoLock(void)
- {
--	VGAwGR(0x09, 0x00);
-+	vga_wgfx(NULL, 0x09, 0x00);
- 	vgaHWLock();
- }
- 
- static void neoUnlock(void)
- {
- 	vgaHWUnlock();
--	VGAwGR(0x09, 0x26);
-+	vga_wgfx(NULL, 0x09, 0x26);
- }
- 
- /*
-- * vgaHWSeqReset
-- *      perform a sequencer reset.
-+ * VGA Palette management
-  */
--void vgaHWSeqReset(int start)
-+static int paletteEnabled = 0;
-+
-+inline void VGAenablePalette(void)
-+{
-+	vga_r(NULL, VGA_IS1_RC);
-+	vga_w(NULL, VGA_ATT_W, 0x00);
-+	paletteEnabled = 1;
-+}
-+
-+inline void VGAdisablePalette(void)
- {
--	if (start)
--		VGAwSEQ(0x00, 0x01);	/* Synchronous Reset */
-+	vga_r(NULL, VGA_IS1_RC);
-+	vga_w(NULL, VGA_ATT_W, 0x20);
-+	paletteEnabled = 0;
-+}
-+
-+inline void VGAwATTR(u8 index, u8 value)
-+{
-+	if (paletteEnabled)
-+		index &= ~0x20;
- 	else
--		VGAwSEQ(0x00, 0x03);	/* End Reset */
-+		index |= 0x20;
-+
-+	vga_r(NULL, VGA_IS1_RC);
-+	vga_wattr(NULL, index, value);
- }
- 
- void vgaHWProtect(int on)
-@@ -411,21 +430,18 @@ void vgaHWProtect(int on)
- 		/*
- 		 * Turn off screen and disable sequencer.
- 		 */
--		tmp = VGArSEQ(0x01);
--
--		vgaHWSeqReset(1);	/* start synchronous reset */
--		VGAwSEQ(0x01, tmp | 0x20);	/* disable the display */
-+		tmp = vga_rseq(NULL, 0x01);
-+		vga_wseq(NULL, 0x00, 0x01);		/* Synchronous Reset */
-+		vga_wseq(NULL, 0x01, tmp | 0x20);	/* disable the display */
- 
- 		VGAenablePalette();
- 	} else {
- 		/*
- 		 * Reenable sequencer, then turn on screen.
- 		 */
--
--		tmp = VGArSEQ(0x01);
--
--		VGAwSEQ(0x01, tmp & ~0x20);	/* reenable display */
--		vgaHWSeqReset(0);	/* clear synchronousreset */
-+		tmp = vga_rseq(NULL, 0x01);
-+		vga_wseq(NULL, 0x01, tmp & ~0x20);	/* reenable display */
-+		vga_wseq(NULL, 0x00, 0x03);		/* clear synchronousreset */
- 
- 		VGAdisablePalette();
- 	}
-@@ -436,19 +452,19 @@ static void vgaHWRestore(const struct fb
- {
- 	int i;
- 
--	VGAwMISC(par->MiscOutReg);
-+	vga_w(NULL, VGA_MIS_W, par->MiscOutReg);
- 
- 	for (i = 1; i < 5; i++)
--		VGAwSEQ(i, par->Sequencer[i]);
-+		vga_wseq(NULL, i, par->Sequencer[i]);
- 
- 	/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
--	VGAwCR(17, par->CRTC[17] & ~0x80);
-+	vga_wcrt(NULL, 17, par->CRTC[17] & ~0x80);
- 
- 	for (i = 0; i < 25; i++)
--		VGAwCR(i, par->CRTC[i]);
-+		vga_wcrt(NULL, i, par->CRTC[i]);
- 
- 	for (i = 0; i < 9; i++)
--		VGAwGR(i, par->Graphics[i]);
-+		vga_wgfx(NULL, i, par->Graphics[i]);
- 
- 	VGAenablePalette();
- 
-@@ -981,13 +997,13 @@ static int neofb_set_par(struct fb_info 
- 	}
- 
- 	/* alread unlocked above */
--	/* BOGUS  VGAwGR (0x09, 0x26); */
-+	/* BOGUS  vga_wgfx(NULL, 0x09, 0x26); */
- 
- 	/* don't know what this is, but it's 0 from bootup anyway */
--	VGAwGR(0x15, 0x00);
-+	vga_wgfx(NULL, 0x15, 0x00);
- 
- 	/* was set to 0x01 by my bios in text and vesa modes */
--	VGAwGR(0x0A, par->GeneralLockReg);
-+	vga_wgfx(NULL, 0x0A, par->GeneralLockReg);
- 
- 	/*
- 	 * The color mode needs to be set before calling vgaHWRestore
-@@ -996,7 +1012,7 @@ static int neofb_set_par(struct fb_info 
- 	 * NOTE: Make sure we don't change bits make sure we don't change
- 	 * any reserved bits.
- 	 */
--	temp = VGArGR(0x90);
-+	temp = vga_rgfx(NULL, 0x90);
- 	switch (info->fix.accel) {
- 	case FB_ACCEL_NEOMAGIC_NM2070:
- 		temp &= 0xF0;	/* Save bits 7:4 */
-@@ -1015,7 +1031,7 @@ static int neofb_set_par(struct fb_info 
- 		break;
- 	}
- 
--	VGAwGR(0x90, temp);
-+	vga_wgfx(NULL, 0x90, temp);
- 
- 	/*
- 	 * In some rare cases a lockup might occur if we don't delay
-@@ -1027,9 +1043,9 @@ static int neofb_set_par(struct fb_info 
- 	 * Disable horizontal and vertical graphics and text expansions so
- 	 * that vgaHWRestore works properly.
- 	 */
--	temp = VGArGR(0x25);
-+	temp = vga_rgfx(NULL, 0x25);
- 	temp &= 0x39;
--	VGAwGR(0x25, temp);
-+	vga_wgfx(NULL, 0x25, temp);
- 
- 	/*
- 	 * Sleep for 200ms to make sure that the two operations above have
-@@ -1041,19 +1057,18 @@ static int neofb_set_par(struct fb_info 
- 	 * This function handles restoring the generic VGA registers.  */
- 	vgaHWRestore(info, par);
- 
--
--	VGAwGR(0x0E, par->ExtCRTDispAddr);
--	VGAwGR(0x0F, par->ExtCRTOffset);
--	temp = VGArGR(0x10);
-+	vga_wgfx(NULL, 0x0E, par->ExtCRTDispAddr);
-+	vga_wgfx(NULL, 0x0F, par->ExtCRTOffset);
-+	temp = vga_rgfx(NULL, 0x10);
- 	temp &= 0x0F;		/* Save bits 3:0 */
- 	temp |= (par->SysIfaceCntl1 & ~0x0F);	/* VESA Bios sets bit 1! */
--	VGAwGR(0x10, temp);
-+	vga_wgfx(NULL, 0x10, temp);
- 
--	VGAwGR(0x11, par->SysIfaceCntl2);
--	VGAwGR(0x15, 0 /*par->SingleAddrPage */ );
--	VGAwGR(0x16, 0 /*par->DualAddrPage */ );
-+	vga_wgfx(NULL, 0x11, par->SysIfaceCntl2);
-+	vga_wgfx(NULL, 0x15, 0 /*par->SingleAddrPage */ );
-+	vga_wgfx(NULL, 0x16, 0 /*par->DualAddrPage */ );
- 
--	temp = VGArGR(0x20);
-+	temp = vga_rgfx(NULL, 0x20);
- 	switch (info->fix.accel) {
- 	case FB_ACCEL_NEOMAGIC_NM2070:
- 		temp &= 0xFC;	/* Save bits 7:2 */
-@@ -1074,73 +1089,72 @@ static int neofb_set_par(struct fb_info 
- 		temp |= (par->PanelDispCntlReg1 & ~0x98);
- 		break;
- 	}
--	VGAwGR(0x20, temp);
-+	vga_wgfx(NULL, 0x20, temp);
- 
--	temp = VGArGR(0x25);
-+	temp = vga_rgfx(NULL, 0x25);
- 	temp &= 0x38;		/* Save bits 5:3 */
- 	temp |= (par->PanelDispCntlReg2 & ~0x38);
--	VGAwGR(0x25, temp);
-+	vga_wgfx(NULL, 0x25, temp);
- 
- 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
--		temp = VGArGR(0x30);
-+		temp = vga_rgfx(NULL, 0x30);
- 		temp &= 0xEF;	/* Save bits 7:5 and bits 3:0 */
- 		temp |= (par->PanelDispCntlReg3 & ~0xEF);
--		VGAwGR(0x30, temp);
-+		vga_wgfx(NULL, 0x30, temp);
- 	}
- 
--	VGAwGR(0x28, par->PanelVertCenterReg1);
--	VGAwGR(0x29, par->PanelVertCenterReg2);
--	VGAwGR(0x2a, par->PanelVertCenterReg3);
-+	vga_wgfx(NULL, 0x28, par->PanelVertCenterReg1);
-+	vga_wgfx(NULL, 0x29, par->PanelVertCenterReg2);
-+	vga_wgfx(NULL, 0x2a, par->PanelVertCenterReg3);
- 
- 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
--		VGAwGR(0x32, par->PanelVertCenterReg4);
--		VGAwGR(0x33, par->PanelHorizCenterReg1);
--		VGAwGR(0x34, par->PanelHorizCenterReg2);
--		VGAwGR(0x35, par->PanelHorizCenterReg3);
-+		vga_wgfx(NULL, 0x32, par->PanelVertCenterReg4);
-+		vga_wgfx(NULL, 0x33, par->PanelHorizCenterReg1);
-+		vga_wgfx(NULL, 0x34, par->PanelHorizCenterReg2);
-+		vga_wgfx(NULL, 0x35, par->PanelHorizCenterReg3);
- 	}
- 
- 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160)
--		VGAwGR(0x36, par->PanelHorizCenterReg4);
-+		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
- 
- 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
--		VGAwGR(0x36, par->PanelHorizCenterReg4);
--		VGAwGR(0x37, par->PanelVertCenterReg5);
--		VGAwGR(0x38, par->PanelHorizCenterReg5);
-+		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
-+		vga_wgfx(NULL, 0x37, par->PanelVertCenterReg5);
-+		vga_wgfx(NULL, 0x38, par->PanelHorizCenterReg5);
- 
- 		clock_hi = 1;
- 	}
- 
- 	/* Program VCLK3 if needed. */
--	if (par->ProgramVCLK && ((VGArGR(0x9B) != par->VCLK3NumeratorLow)
--				 || (VGArGR(0x9F) != par->VCLK3Denominator)
--				 || (clock_hi && ((VGArGR(0x8F) & ~0x0f)
--						  != (par->
--						      VCLK3NumeratorHigh &
-+	if (par->ProgramVCLK && ((vga_rgfx(NULL, 0x9B) != par->VCLK3NumeratorLow)
-+				 || (vga_rgfx(NULL, 0x9F) != par->VCLK3Denominator)
-+				 || (clock_hi && ((vga_rgfx(NULL, 0x8F) & ~0x0f)
-+						  != (par->VCLK3NumeratorHigh &
- 						      ~0x0F))))) {
--		VGAwGR(0x9B, par->VCLK3NumeratorLow);
-+		vga_wgfx(NULL, 0x9B, par->VCLK3NumeratorLow);
- 		if (clock_hi) {
--			temp = VGArGR(0x8F);
-+			temp = vga_rgfx(NULL, 0x8F);
- 			temp &= 0x0F;	/* Save bits 3:0 */
- 			temp |= (par->VCLK3NumeratorHigh & ~0x0F);
--			VGAwGR(0x8F, temp);
-+			vga_wgfx(NULL, 0x8F, temp);
- 		}
--		VGAwGR(0x9F, par->VCLK3Denominator);
-+		vga_wgfx(NULL, 0x9F, par->VCLK3Denominator);
- 	}
- 
- 	if (par->biosMode)
--		VGAwCR(0x23, par->biosMode);
-+		vga_wcrt(NULL, 0x23, par->biosMode);
- 
--	VGAwGR(0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
-+	vga_wgfx(NULL, 0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
- 
- 	/* Program vertical extension register */
- 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
- 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
--		VGAwCR(0x70, par->VerticalExt);
-+		vga_wcrt(NULL, 0x70, par->VerticalExt);
- 	}
- 
- 	vgaHWProtect(0);	/* Turn on screen */
-@@ -1180,16 +1194,16 @@ static void neofb_update_start(struct fb
- 	/*
- 	 * These are the generic starting address registers.
- 	 */
--	VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
--	VGAwCR(0x0D, (Base & 0x00FF));
-+	vga_wcrt(NULL, 0x0C, (Base & 0x00FF00) >> 8);
-+	vga_wcrt(NULL, 0x0D, (Base & 0x00FF));
- 
- 	/*
- 	 * Make sure we don't clobber some other bits that might already
- 	 * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
- 	 * be needed.
- 	 */
--	oldExtCRTDispAddr = VGArGR(0x0E);
--	VGAwGR(0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
-+	oldExtCRTDispAddr = vga_rgfx(NULL, 0x0E);
-+	vga_wgfx(NULL, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
- 
- 	neoLock();
- }
-@@ -1353,7 +1367,7 @@ neo2200_fillrect(struct fb_info *info, c
- 	}
- 
- 	par->neo2200->dstStart =
--	    dst * ((info->var.bits_per_pixel + 7) / 8);
-+	    dst * ((info->var.bits_per_pixel + 7) >> 3);
- 	par->neo2200->xyExt =
- 	    (rect->height << 16) | (rect->width & 0xffff);
- }
-@@ -1361,26 +1375,22 @@ neo2200_fillrect(struct fb_info *info, c
- static void
- neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
- {
--	struct neofb_par *par = (struct neofb_par *) info->par;
- 	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
-+	struct neofb_par *par = (struct neofb_par *) info->par;
- 	u_long src, dst, bltCntl;
--
-+	
- 	bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
- 
--	if (sy < dy) {
-+	if ((dy > sy) || ((dy == sy) && (dx > sx))) {	
-+		/* Start with the lower right corner */
- 		sy += (area->height - 1);
- 		dy += (area->height - 1);
--
--		bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
--	}
--
--	if (area->sx < area->dx) {
- 		sx += (area->width - 1);
--		dx += (area->width - 1);
--
--		bltCntl |= NEO_BC0_X_DEC;
--	}
--
-+		dx += (area->width - 1);	
-+		
-+		bltCntl |= NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
-+	}		
-+				
- 	src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
- 	dst = dx * (info->var.bits_per_pixel >> 3) + dy*info->fix.line_length;
- 
-@@ -1725,16 +1735,16 @@ static int __devinit neo_init_hw(struct 
- 	printk(KERN_DEBUG "--- Neo extended register dump ---\n");
- 	for (w = 0; w < 0x85; w++)
- 		printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
--		       (void *) VGArCR(w));
-+		       (void *) vga_rcrt(NULL, w);
- 	for (w = 0; w < 0xC7; w++)
- 		printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
--		       (void *) VGArGR(w));
-+		       (void *) vga_rgfx(NULL, w));
- #endif
- 
- 	/* Determine the panel type */
--	VGAwGR(0x09, 0x26);
--	type = VGArGR(0x21);
--	display = VGArGR(0x20);
-+	vga_wgfx(NULL, 0x09, 0x26);
-+	type = vga_rgfx(NULL, 0x21);
-+	display = vga_rgfx(NULL, 0x20);
- 	if (!par->internal_display && !par->external_display) {
- 		par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
- 		par->external_display = display & 1;
-@@ -1744,8 +1754,8 @@ static int __devinit neo_init_hw(struct 
- 	}
- 
- 	/* Determine panel width -- used in NeoValidMode. */
--	w = VGArGR(0x20);
--	VGAwGR(0x09, 0x00);
-+	w = vga_rgfx(NULL, 0x20);
-+	vga_wgfx(NULL, 0x09, 0x00);
- 	switch ((w & 0x18) >> 3) {
- 	case 0x00:
- 		par->NeoPanelWidth = 640;
---- linux-2.6.0-test1/drivers/video/platinumfb.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/drivers/video/platinumfb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -104,8 +104,8 @@ static int platinum_var_to_par(const str
-  * Interface used by the world
-  */
- 
--int platinum_init(void);
--int platinum_setup(char*);
-+int platinumfb_init(void);
-+int platinumfb_setup(char*);
- 
- static struct fb_ops platinumfb_ops = {
- 	.owner =	THIS_MODULE,
-@@ -399,7 +399,7 @@ try_again:
- 	/* Apply default var */
- 	p->info.var = var;
- 	var.activate = FB_ACTIVATE_NOW;
--	rc = fb_set_var(&var, &p->info);
-+	rc = fb_set_var(&p->info, &var);
- 	if (rc && (default_vmode != VMODE_640_480_60 || default_cmode != CMODE_8))
- 		goto try_again;
- 
-@@ -413,7 +413,7 @@ try_again:
- 	return 1;
- }
- 
--int __init platinum_init(void)
-+int __init platinumfb_init(void)
- {
- 	struct device_node *dp;
- 
-@@ -597,7 +597,7 @@ static int platinum_par_to_var(struct fb
- /* 
-  * Parse user speficied options (`video=platinumfb:')
-  */
--int __init platinum_setup(char *options)
-+int __init platinumfb_setup(char *options)
- {
- 	char *this_opt;
- 
---- linux-2.6.0-test1/drivers/video/pvr2fb.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/video/pvr2fb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Dreamcast.
-  *
-  * Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org>
-- * Copyright (c) 2001 Paul Mundt  <lethal@chaoticdreams.org>
-+ * Copyright (c) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org>
-  *
-  * This file is part of the LinuxDC project (linuxdc.sourceforge.net).
-  *
-@@ -12,14 +12,15 @@
- 
- /*
-  * This driver is mostly based on the excellent amifb and vfb sources.  It uses
-- * an odd scheme for converting hardware values to/from framebuffer values, here are
-- * some hacked-up formulas:
-+ * an odd scheme for converting hardware values to/from framebuffer values,
-+ * here are some hacked-up formulas:
-  *
-- *  The Dreamcast has screen offsets from each side of its four borders and the start
-- *  offsets of the display window.  I used these values to calculate 'pseudo' values
-- *  (think of them as placeholders) for the fb video mode, so that when it came time
-- *  to convert these values back into their hardware values, I could just add mode-
-- *  specific offsets to get the correct mode settings:
-+ *  The Dreamcast has screen offsets from each side of its four borders and
-+ *  the start offsets of the display window.  I used these values to calculate
-+ *  'pseudo' values (think of them as placeholders) for the fb video mode, so
-+ *  that when it came time to convert these values back into their hardware
-+ *  values, I could just add mode- specific offsets to get the correct mode
-+ *  settings:
-  *
-  *      left_margin = diwstart_h - borderstart_h;
-  *      right_margin = borderstop_h - (diwstart_h + xres);
-@@ -29,9 +30,9 @@
-  *      hsync_len = borderstart_h + (hsync_total - borderstop_h);
-  *      vsync_len = borderstart_v + (vsync_total - borderstop_v);
-  *
-- *  Then, when it's time to convert back to hardware settings, the only constants
-- *  are the borderstart_* offsets, all other values are derived from the fb video
-- *  mode:
-+ *  Then, when it's time to convert back to hardware settings, the only
-+ *  constants are the borderstart_* offsets, all other values are derived from
-+ *  the fb video mode:
-  *  
-  *      // PAL
-  *      borderstart_h = 116;
-@@ -57,7 +58,6 @@
- #include <linux/interrupt.h>
- #include <linux/fb.h>
- #include <linux/init.h>
--#include <linux/console.h>
- 
- #ifdef CONFIG_SH_DREAMCAST
- #include <asm/io.h>
-@@ -66,14 +66,9 @@
- #endif
- 
- #ifdef CONFIG_MTRR
--  #include <asm/mtrr.h>
-+#include <asm/mtrr.h>
- #endif
- 
--#include <video/fbcon.h>
--#include <video/fbcon-cfb16.h>
--#include <video/fbcon-cfb24.h>
--#include <video/fbcon-cfb32.h>
--
- #ifdef CONFIG_FB_PVR2_DEBUG
- #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
- #else
-@@ -124,16 +119,6 @@ static struct pvr2_params outputs[] __in
-  */
- 
- static struct pvr2fb_par {
--
--	int xres;
--	int yres;
--	int vxres;
--	int vyres;
--	int xoffset;
--	int yoffset;
--	u_short bpp;
--
--	u_long pixclock;
- 	u_short hsync_total;	/* Clocks/line */
- 	u_short vsync_total;	/* Lines/field */
- 	u_short borderstart_h;
-@@ -144,53 +129,49 @@ static struct pvr2fb_par {
- 	u_short diwstart_v;	/* Vertical offset of the display field, for
- 				   interlaced modes, this is the long field */
- 	u_long disp_start;	/* Address of image within VRAM */
--
--	u_long next_line;	/* Modulo for next line */
--
- 	u_char is_interlaced;	/* Is the display interlaced? */
- 	u_char is_doublescan;	/* Are scanlines output twice? (doublescan) */
- 	u_char is_lowres;	/* Is horizontal pixel-doubling enabled? */
-+} *currentpar;
- 
--	u_long bordercolor;	/* RGB888 format border color */
--
--	u_long vmode;
--	
--} currentpar;
--
--static int currbpp;
--static struct display disp;
--static struct fb_info fb_info;
-+static struct fb_info *fb_info;
- static int pvr2fb_inverse = 0;
- 
--static struct { u_short red, green, blue, alpha; } palette[256];
--static union {
--#ifdef FBCON_HAS_CFB16
--	u16 cfb16[16];
--#endif
--#ifdef FBCON_HAS_CFB24
--	u32 cfb24[16];
--#endif
--#ifdef FBCON_HAS_CFB32
--	u32 cfb32[16];
--#endif
--} fbcon_cmap;
-+static struct fb_fix_screeninfo pvr2_fix __initdata = {
-+	.id =		"NEC PowerVR2",
-+	.type = 	FB_TYPE_PACKED_PIXELS,
-+	.visual = 	FB_VISUAL_TRUECOLOR,
-+	.ypanstep =	1,
-+	.ywrapstep =	1,
-+	.accel = 	FB_ACCEL_NONE,
-+};
- 
--static char pvr2fb_name[16] = "NEC PowerVR2";
-+static struct fb_var_screeninfo pvr2_var __initdata = {
-+	.xres =		640,
-+	.yres =		480,
-+	.xres_virtual =	640,
-+	.yres_virtual = 480,
-+	.bits_per_pixel	=16,
-+	.red =		{ 11, 5, 0 },
-+	.green =	{  5, 6, 0 },
-+	.blue =		{  0, 5, 0 },
-+	.activate =	FB_ACTIVATE_NOW,
-+	.height =	-1,
-+	.width =	-1,
-+	.vmode =	FB_VMODE_NONINTERLACED,
-+};
- 
- #define VIDEOMEMSIZE (8*1024*1024)
- static u_long videomemory = 0xa5000000, videomemorysize = VIDEOMEMSIZE;
- static int cable_type = -1;
- static int video_output = -1;
- 
--#ifdef CONFIG_MTRR
--static int enable_mtrr = 1;
--static int mtrr_handle;
--#endif
-+static int nopan = 0;
-+static int nowrap = 1;
- 
- /*
-  * We do all updating, blanking, etc. during the vertical retrace period
-  */
--
- static u_short do_vmode_full = 0;	/* Change the video mode */
- static u_short do_vmode_pan = 0;	/* Update the video mode */
- static short do_blank = 0;		/* (Un)Blank the screen */
-@@ -201,50 +182,15 @@ static u_short is_blanked = 0;		/* Is th
- 
- int pvr2fb_setup(char*);
- 
--static int pvr2fb_get_fix(struct fb_fix_screeninfo *fix, int con,
--                            struct fb_info *info);
--static int pvr2fb_get_var(struct fb_var_screeninfo *var, int con,
--                            struct fb_info *info);
--static int pvr2fb_set_var(struct fb_var_screeninfo *var, int con,
--                            struct fb_info *info);
--static int pvr2fb_pan_display(struct fb_var_screeninfo *var, int con,
--                                struct fb_info *info);
--static int pvr2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
--                             struct fb_info *info);
--static int pvr2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
--                             struct fb_info *info);
- static int pvr2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                             u_int transp, struct fb_info *info);
- static int pvr2fb_blank(int blank, struct fb_info *info);
--
--	/*
--	 * Interface to the low level console driver
--	 */
--
--static int pvr2fbcon_switch(int con, struct fb_info *info);
--static int pvr2fbcon_updatevar(int con, struct fb_info *info);
--
--	/*
--	 * Internal/hardware-specific routines
--	 */
--
- static u_long get_line_length(int xres_virtual, int bpp);
- static void set_color_bitfields(struct fb_var_screeninfo *var);
--static int pvr2_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
--                            u_int *transp, struct fb_info *info);
--
--static int pvr2_encode_fix(struct fb_fix_screeninfo *fix,
--                             struct pvr2fb_par *par);
--static int pvr2_decode_var(struct fb_var_screeninfo *var,
--                          struct pvr2fb_par *par);
--static int pvr2_encode_var(struct fb_var_screeninfo *var,
--                          struct pvr2fb_par *par);
--static void pvr2_get_par(struct pvr2fb_par *par);
--static void pvr2_set_var(struct fb_var_screeninfo *var);
--static void pvr2_pan_var(struct fb_var_screeninfo *var);
--static int pvr2_update_par(void);
--static void pvr2_update_display(void);
--static void pvr2_init_display(void);
-+static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
-+static int pvr2fb_set_par(struct fb_info *info);
-+static void pvr2_update_display(struct fb_info *info);
-+static void pvr2_init_display(struct fb_info *info);
- static void pvr2_do_blank(void);
- static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
- static int pvr2_init_cable(void);
-@@ -252,19 +198,18 @@ static int pvr2_get_param(const struct p
-                             int val, int size);
- 
- static struct fb_ops pvr2fb_ops = {
--	.owner =	THIS_MODULE,
--	.fb_get_fix =	pvr2fb_get_fix,
--	.fb_get_var =	pvr2fb_get_var,
--	.fb_set_var =	pvr2fb_set_var,
--	.fb_get_cmap =	pvr2fb_get_cmap,
--	.fb_set_cmap =	pvr2fb_set_cmap,
--	.fb_setcolreg =	pvr2fb_setcolreg,
--	.fb_pan_display = pvr2fb_pan_display,
--	.fb_blank =	pvr2fb_blank,
-+	.owner 		= THIS_MODULE,
-+	.fb_setcolreg 	= pvr2fb_setcolreg,
-+	.fb_blank 	= pvr2fb_blank,
-+	.fb_check_var 	= pvr2fb_check_var,
-+	.fb_set_par 	= pvr2fb_set_par,
-+	.fb_fillrect 	= cfb_fillrect,
-+	.fb_copyarea	= cfb_copyarea,
-+	.fb_imageblit	= cfb_imageblit,
-+	.fb_cursor	= soft_cursor,
- };
- 
- static struct fb_videomode pvr2_modedb[] __initdata = {
--
-     /*
-      * Broadcast video modes (PAL and NTSC).  I'm unfamiliar with
-      * PAL-M and PAL-N, but from what I've read both modes parallel PAL and
-@@ -275,21 +220,16 @@ static struct fb_videomode pvr2_modedb[]
- 	/* 640x480 @ 60Hz interlaced (NTSC) */
- 	"ntsc_640x480i", 60, 640, 480, TV_CLK, 38, 33, 0, 18, 146, 26,
- 	FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
--    },
--
--    {
-+    }, {
- 	/* 640x240 @ 60Hz (NTSC) */
- 	/* XXX: Broken! Don't use... */
- 	"ntsc_640x240", 60, 640, 240, TV_CLK, 38, 33, 0, 0, 146, 22,
- 	FB_SYNC_BROADCAST, FB_VMODE_YWRAP
--    },
--
--    {
-+    }, {
- 	/* 640x480 @ 60hz (VGA) */
- 	"vga_640x480", 60, 640, 480, VGA_CLK, 38, 33, 0, 18, 146, 26,
- 	0, FB_VMODE_YWRAP
--    },
--
-+    }, 
- };
- 
- #define NUM_TOTAL_MODES  ARRAY_SIZE(pvr2_modedb)
-@@ -301,222 +241,10 @@ static struct fb_videomode pvr2_modedb[]
- static int defmode = DEFMODE_NTSC;
- static char *mode_option __initdata = NULL;
- 
--/* Get the fixed part of the display */
--
--static int pvr2fb_get_fix(struct fb_fix_screeninfo *fix, int con,
--                            struct fb_info *info)
--{
--	struct pvr2fb_par par;
--
--	if (con == -1)
--		pvr2_get_par(&par);
--	else {
--		int err;
--
--		if ((err = pvr2_decode_var(&fb_display[con].var, &par)))
--			return err;
--	}
--	return pvr2_encode_fix(fix, &par);
--}
--
--/* Get the user-defined part of the display */
--
--static int pvr2fb_get_var(struct fb_var_screeninfo *var, int con,
--                            struct fb_info *info)
--{
--	int err = 0;
--
--	if (con == -1) {
--		struct pvr2fb_par par;
--
--		pvr2_get_par(&par);
--		err = pvr2_encode_var(var, &par);
--	} else
--		*var = fb_display[con].var;
--	
--	return err;
--}
--
--/* Set the user-defined part of the display */
--
--static int pvr2fb_set_var(struct fb_var_screeninfo *var, int con,
--                            struct fb_info *info)
--{
--	int err, activate = var->activate;
--	int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
--	struct pvr2fb_par par;
--
--	struct display *display;
--	if (con >= 0)
--		display = &fb_display[con];
--	else
--		display = &disp;        /* used during initialization */
--
--	/*
--	 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
--	 * as FB_VMODE_SMOOTH_XPAN is only used internally
--	 */
--
--	if (var->vmode & FB_VMODE_CONUPDATE) {
--		var->vmode |= FB_VMODE_YWRAP;
--		var->xoffset = display->var.xoffset;
--		var->yoffset = display->var.yoffset;
--	}
--	if ((err = pvr2_decode_var(var, &par)))
--		return err;
--	pvr2_encode_var(var, &par);
--
--	/* Do memory check and bitfield set here?? */
--
--	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
--		oldxres = display->var.xres;
--		oldyres = display->var.yres;
--		oldvxres = display->var.xres_virtual;
--		oldvyres = display->var.yres_virtual;
--		oldbpp = display->var.bits_per_pixel;
--		display->var = *var;
--		if (oldxres != var->xres || oldyres != var->yres ||
--		    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
--		    oldbpp != var->bits_per_pixel) {
--			struct fb_fix_screeninfo fix;
--
--			pvr2_encode_fix(&fix, &par);
--			display->scrollmode = SCROLL_YREDRAW;
--			display->visual = fix.visual;
--			display->type = fix.type;
--			display->type_aux = fix.type_aux;
--			display->ypanstep = fix.ypanstep;
--			display->ywrapstep = fix.ywrapstep;
--			display->line_length = fix.line_length;
--			display->can_soft_blank = 1;
--			display->inverse = pvr2fb_inverse;
--			switch (var->bits_per_pixel) {
--#ifdef FBCON_HAS_CFB16
--			    case 16:
--				display->dispsw = &fbcon_cfb16;
--				display->dispsw_data = fbcon_cmap.cfb16;
--				break;
--#endif
--#ifdef FBCON_HAS_CFB24
--			    case 24:
--				display->dispsw = &fbcon_cfb24;
--				display->dispsw_data = fbcon_cmap.cfb24;
--				break;
--#endif
--#ifdef FBCON_HAS_CFB32
--			    case 32:
--				display->dispsw = &fbcon_cfb32;
--				display->dispsw_data = fbcon_cmap.cfb32;
--				break;
--#endif
--			    default:
--				display->dispsw = &fbcon_dummy;
--				break;
--			}
--			if (fb_info.changevar)
--				(*fb_info.changevar)(con);
--		}
--		if (oldbpp != var->bits_per_pixel) {
--			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
--				return err;
--			do_install_cmap(con, info);
--		}
--		if (con == info->currcon)
--			pvr2_set_var(&display->var);
--	}
--
--	return 0;
--}
--
--/*
-- * Pan or wrap the display.
-- * This call looks only at xoffset, yoffset and the FB_VMODE_YRAP flag
-- */
--
--static int pvr2fb_pan_display(struct fb_var_screeninfo *var, int con,
--                                struct fb_info *info)
--{
--	if (var->vmode & FB_VMODE_YWRAP) {
--		if (var->yoffset<0 || var->yoffset >=
--		    fb_display[con].var.yres_virtual || var->xoffset)
--			return -EINVAL;
--	 } else {
--		if (var->xoffset+fb_display[con].var.xres >
--		    fb_display[con].var.xres_virtual ||
--		    var->yoffset+fb_display[con].var.yres >
--		    fb_display[con].var.yres_virtual)
--		    return -EINVAL;
--	}
--	if (con == info->currcon)
--		pvr2_pan_var(var);
--	fb_display[con].var.xoffset = var->xoffset;
--	fb_display[con].var.yoffset = var->yoffset;
--	if (var->vmode & FB_VMODE_YWRAP)
--		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
--	else
--		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
--			
--	return 0;
--}
--
--/* Get the colormap */
--
--static int pvr2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
--                             struct fb_info *info)
--{
--	if (con == info->currcon) /* current console? */
--		return fb_get_cmap(cmap, kspc, pvr2_getcolreg, info);
--	else if (fb_display[con].cmap.len) /* non default colormap? */
--		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
--	else
--		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
--		             cmap, kspc ? 0 : 2);
--	return 0;
--}
--
--/* Set the colormap */
--
--static int pvr2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
--	                     struct fb_info *info)
--{
--	int err;
--
--	if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
--		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
--		                         1<<fb_display[con].var.bits_per_pixel,
--					 0)))
--			 return err;
--	}
--	if (con == info->currcon)                     /* current console? */
--		return fb_set_cmap(cmap, kspc, info);
--	else
--		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
--
--	return 0;
--}
--
--static int pvr2fbcon_switch(int con, struct fb_info *info)
--{
--	/* Do we have to save the colormap? */
--	if (fb_display[info->currcon].cmap.len)
--		fb_get_cmap(&fb_display[info->currcon].cmap, 1, pvr2_getcolreg, info);
--
--	info->currcon = con;
--	pvr2_set_var(&fb_display[con].var);
--	/* Install new colormap */
--	do_install_cmap(con, info);
--	return 0;
--}
--
--static int pvr2fbcon_updatevar(int con, struct fb_info *info)
--{
--	pvr2_pan_var(&fb_display[con].var);
--	return 0;
--}
--
- static int pvr2fb_blank(int blank, struct fb_info *info)
- {
- 	do_blank = blank ? blank : -1;
-+	return 0;
- }
- 
- static inline u_long get_line_length(int xres_virtual, int bpp)
-@@ -548,52 +276,29 @@ static void set_color_bitfields(struct f
- 	}
- }
- 
--static int pvr2_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
--                            u_int *transp, struct fb_info *info)
--{
--	if (regno > 255)
--	    return 1;
--	
--	*red = palette[regno].red;
--	*green = palette[regno].green;
--	*blue = palette[regno].blue;
--	*transp = 0;
--	return 0;
--}
--	
- static int pvr2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                             u_int transp, struct fb_info *info)
- {
- 	if (regno > 255)
- 		return 1;
- 
--	palette[regno].red = red;
--	palette[regno].green = green;
--	palette[regno].blue = blue;
--
- 	if (regno < 16) {
--		switch (currbpp) {
--#ifdef FBCON_HAS_CFB16
-+		switch (info->var.bits_per_pixel) {
- 		    case 16: /* RGB 565 */
--			fbcon_cmap.cfb16[regno] = (red & 0xf800) |
--			                          ((green & 0xfc00) >> 5) |
-+			((u16*)(info->pseudo_palette))[regno] = (red & 0xf800) |
-+						((green & 0xfc00) >> 5) |
- 						  ((blue & 0xf800) >> 11);
- 			break;
--#endif
--#ifdef FBCON_HAS_CFB24
- 		    case 24: /* RGB 888 */
- 			red >>= 8; green >>= 8; blue >>= 8;
--			fbcon_cmap.cfb24[regno] = (red << 16) | (green << 8) | blue;
-+			((u32*)(info->pseudo_palette))[regno] = (red << 16) | (green << 8) | blue;
- 			break;
--#endif
--#ifdef FBCON_HAS_CFB32
- 		    case 32: /* ARGB 8888 */
- 			red >>= 8; green >>= 8; blue >>= 8;
--			fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | blue;
-+			((u32*)(info->pseudo_palette))[regno] = (transp << 24) |(red << 16) | (green << 8) | blue;
- 			break;
--#endif
- 		    default:
--			DPRINTK("Invalid bit depth %d?!?\n", currbpp);
-+			DPRINTK("Invalid bit depth %d?!?\n", info->var.bits_per_pixel);
- 			return 1;
- 		}
- 	}
-@@ -601,85 +306,33 @@ static int pvr2fb_setcolreg(u_int regno,
- 	return 0;
- }
- 
--
--static int pvr2_encode_fix(struct fb_fix_screeninfo *fix,
--                             struct pvr2fb_par *par)
--{
--	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
--	strcpy(fix->id, pvr2fb_name);
--	fix->smem_start = videomemory;
--	fix->smem_len = videomemorysize;
--	fix->type = FB_TYPE_PACKED_PIXELS;
--	fix->type_aux = 0;
--	fix->visual = FB_VISUAL_TRUECOLOR;
--
--	if (par->vmode & FB_VMODE_YWRAP) {
--		fix->ywrapstep = 1;
--		fix->xpanstep = fix->ypanstep = 0;
--	} else {
--		fix->ywrapstep = 0;
--		fix->xpanstep = 1;
--		fix->ypanstep = 1;
--	}
--	fix->line_length = par->next_line;
--
--	return 0;
--}
--
--/*
-- * Create a hardware video mode using the framebuffer values.  If a value needs
-- * to be clipped or constrained it's done here.  This routine needs a bit more
-- * work to make sure we're doing the right tests at the right time.
-- */
--static int pvr2_decode_var(struct fb_var_screeninfo *var,
--                             struct pvr2fb_par *par)
-+static int pvr2fb_set_par(struct fb_info *info)
- {
-+	struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
-+	struct fb_var_screeninfo *var = &info->var;
- 	u_long line_length;
- 	u_short vtotal;
- 
--	if (var->pixclock != TV_CLK && var->pixclock != VGA_CLK) {
--		DPRINTK("Invalid pixclock value %d\n", var->pixclock);
--		return -EINVAL;
--	}
--	par->pixclock = var->pixclock;
--	
--	if ((par->xres = var->xres) < 320)
--		par->xres = 320;
--	if ((par->yres = var->yres) < 240)
--		par->yres = 240;
--	if ((par->vxres = var->xres_virtual) < par->xres)
--		par->vxres = par->xres;
--	if ((par->vyres = var->yres_virtual) < par->yres)
--		par->vyres = par->yres;
--
--	if ((par->bpp = var->bits_per_pixel) <= 16)
--		par->bpp = 16;
--	else if ((par->bpp = var->bits_per_pixel) <= 24)
--		par->bpp = 24;
--	else if ((par->bpp = var->bits_per_pixel) <= 32)
--		par->bpp = 32;
--
--	currbpp = par->bpp;
--
- 	/*
- 	 * XXX: It's possible that a user could use a VGA box, change the cable
--	 * type in hardware (i.e. switch from VGA<->composite), then change modes
--	 * (i.e. switching to another VT).  If that happens we should automagically
--	 * change the output format to cope, but currently I don't have a VGA box
--	 * to make sure this works properly.
-+	 * type in hardware (i.e. switch from VGA<->composite), then change
-+	 * modes (i.e. switching to another VT).  If that happens we should
-+	 * automagically change the output format to cope, but currently I
-+	 * don't have a VGA box to make sure this works properly.
- 	 */
- 	cable_type = pvr2_init_cable();
- 	if (cable_type == CT_VGA && video_output != VO_VGA)
- 		video_output = VO_VGA;
- 
--	par->vmode = var->vmode & FB_VMODE_MASK;
--	if (par->vmode & FB_VMODE_INTERLACED && video_output != VO_VGA)
-+	var->vmode &= FB_VMODE_MASK;
-+	if (var->vmode & FB_VMODE_INTERLACED && video_output != VO_VGA)
- 		par->is_interlaced = 1;
- 	/* 
- 	 * XXX: Need to be more creative with this (i.e. allow doublecan for
- 	 * PAL/NTSC output).
- 	 */
--	par->is_doublescan = (par->yres < 480 && video_output == VO_VGA);
-+	if (var->vmode & FB_VMODE_DOUBLE && video_output == VO_VGA)
-+		par->is_doublescan = 1;
- 	
- 	par->hsync_total = var->left_margin + var->xres + var->right_margin +
- 	                   var->hsync_len;
-@@ -691,22 +344,12 @@ static int pvr2_decode_var(struct fb_var
- 		if (par->is_interlaced)
- 			vtotal /= 2;
- 		if (vtotal > (PAL_VTOTAL + NTSC_VTOTAL)/2) {
--			/* PAL video output */
--			/* XXX: Should be using a range here ... ? */
--			if (par->hsync_total != PAL_HTOTAL) {
--				DPRINTK("invalid hsync total for PAL\n");
--				return -EINVAL;
--			}
- 			/* XXX: Check for start values here... */
- 			/* XXX: Check hardware for PAL-compatibility */
- 			par->borderstart_h = 116;
- 			par->borderstart_v = 44;
- 		} else {
- 			/* NTSC video output */
--			if (par->hsync_total != NTSC_HTOTAL) {
--				DPRINTK("invalid hsync total for NTSC\n");
--				return -EINVAL;
--			}
- 			par->borderstart_h = 126;
- 			par->borderstart_v = 18;
- 		}
-@@ -714,155 +357,123 @@ static int pvr2_decode_var(struct fb_var
- 		/* VGA mode */
- 		/* XXX: What else needs to be checked? */
- 		/* 
--		 * XXX: We have a little freedom in VGA modes, what ranges should
--		 * be here (i.e. hsync/vsync totals, etc.)?
-+		 * XXX: We have a little freedom in VGA modes, what ranges
-+		 * should be here (i.e. hsync/vsync totals, etc.)?
- 		 */
- 		par->borderstart_h = 126;
- 		par->borderstart_v = 40;
- 	}
- 
- 	/* Calculate the remainding offsets */
--	par->borderstop_h = par->borderstart_h + par->hsync_total -
--	                    var->hsync_len;
--	par->borderstop_v = par->borderstart_v + par->vsync_total -
--	                    var->vsync_len;
- 	par->diwstart_h = par->borderstart_h + var->left_margin;
- 	par->diwstart_v = par->borderstart_v + var->upper_margin;
-+	par->borderstop_h = par->diwstart_h + var->xres + 
-+			    var->right_margin;    
-+	par->borderstop_v = par->diwstart_v + var->yres +
-+			    var->lower_margin;
-+
- 	if (!par->is_interlaced)
- 		par->borderstop_v /= 2;
--
--	if (par->xres < 640)
-+	if (info->var.xres < 640)
- 		par->is_lowres = 1;
- 
--	/* XXX: Needs testing. */
--	if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
--		par->xoffset = var->xoffset;
--		par->yoffset = var->yoffset;
--		if (par->vmode & FB_VMODE_YWRAP) {
--			if (par->xoffset || par->yoffset < 0 || par->yoffset >=
--			    par->vyres)
--				par->xoffset = par->yoffset = 0;
--		} else {
--			if (par->xoffset < 0 || par->xoffset > par->vxres-par->xres ||
--			    par->yoffset < 0 || par->yoffset > par->vyres-par->yres)
--				par->xoffset = par->yoffset = 0;
--		}
--	} else
--		par->xoffset = par->yoffset = 0;
--
--	/* Check memory sizes */
- 	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
--	if (line_length * var->yres_virtual > videomemorysize)
--		return -ENOMEM;
--	par->disp_start = videomemory + (get_line_length(par->vxres, par->bpp) *
--	                  par->yoffset) * get_line_length(par->xoffset, par->bpp);
--	par->next_line = line_length;
--	
-+	par->disp_start = videomemory + (line_length * var->yoffset) * line_length;
-+	info->fix.line_length = line_length;
- 	return 0;
- }
- 
--static int pvr2_encode_var(struct fb_var_screeninfo *var,
--                             struct pvr2fb_par *par)
-+static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
- {
--	memset(var, 0, sizeof(struct fb_var_screeninfo));
-+	u_short vtotal, hsync_total;
-+	u_long line_length;
- 
--	var->xres = par->xres;
--	var->yres = par->yres;
--	var->xres_virtual = par->vxres;
--	var->yres_virtual = par->vyres;
--	var->xoffset = par->xoffset;
--	var->yoffset = par->yoffset;
-+	if (var->pixclock != TV_CLK || var->pixclock != VGA_CLK) {
-+		DPRINTK("Invalid pixclock value %d\n", var->pixclock);
-+		return -EINVAL;
-+	}
- 
--	var->bits_per_pixel = par->bpp;
--	set_color_bitfields(var);
-+	if (var->xres < 320)
-+		var->xres = 320;
-+	if (var->yres < 240)
-+		var->yres = 240;
-+	if (var->xres_virtual < var->xres)
-+		var->xres_virtual = var->xres;
-+	if (var->yres_virtual < var->yres)
-+		var->yres_virtual = var->yres;
-+
-+	if (var->bits_per_pixel <= 16)
-+		var->bits_per_pixel = 16;
-+	else if (var->bits_per_pixel <= 24)
-+		var->bits_per_pixel = 24;
-+	else if (var->bits_per_pixel <= 32)
-+		var->bits_per_pixel = 32;
- 
--	var->activate = FB_ACTIVATE_NOW;
--	var->height = -1;
--	var->width = -1;
-+	set_color_bitfields(var);
- 
--	var->pixclock = par->pixclock;
-+	if (var->vmode & FB_VMODE_YWRAP) {
-+		if (var->xoffset || var->yoffset < 0 || 
-+		    var->yoffset >= var->yres_virtual) {
-+			var->xoffset = var->yoffset = 0;
-+		} else {
-+			if (var->xoffset > var->xres_virtual - var->xres ||
-+		    	    var->yoffset > var->yres_virtual - var->yres || 
-+			    var->xoffset < 0 || var->yoffset < 0)
-+				var->xoffset = var->yoffset = 0;
-+		}
-+	} else {
-+		var->xoffset = var->yoffset = 0;
-+	}
- 
--	if (par->is_doublescan)
-+	/* 
-+	 * XXX: Need to be more creative with this (i.e. allow doublecan for
-+	 * PAL/NTSC output).
-+	 */
-+	if (var->yres < 480 && video_output == VO_VGA)
- 		var->vmode = FB_VMODE_DOUBLE;
- 
--	if (par->is_interlaced)
--		var->vmode |= FB_VMODE_INTERLACED;
--	else
--		var->vmode |= FB_VMODE_NONINTERLACED;
--
--	var->right_margin = par->borderstop_h - (par->diwstart_h + par->xres);
--	var->left_margin = par->diwstart_h - par->borderstart_h;
--	var->hsync_len = par->borderstart_h + (par->hsync_total - par->borderstop_h);
--	var->upper_margin = par->diwstart_v - par->borderstart_v;
--	var->lower_margin = par->borderstop_v - (par->diwstart_v + par->yres);
--	var->vsync_len = par->borderstart_v + (par->vsync_total - par->borderstop_v);
- 	if (video_output != VO_VGA)
--		var->sync = FB_SYNC_BROADCAST;
--
--	if (par->vmode & FB_VMODE_YWRAP)
--		var->vmode |= FB_VMODE_YWRAP;
--	
--	return 0;
--}
--
--static void pvr2_get_par(struct pvr2fb_par *par)
--{
--	*par = currentpar;
--}
--
--/* Setup the new videomode in hardware */
--
--static void pvr2_set_var(struct fb_var_screeninfo *var)
--{
--	do_vmode_pan = 0;
--	do_vmode_full = 0;
--	pvr2_decode_var(var, &currentpar);
--
--	do_vmode_full = 1;
--}
--
--/* 
-- * Pan or wrap the display
-- * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag in `var'.
-- */
--static void pvr2_pan_var(struct fb_var_screeninfo *var)
--{
--	struct pvr2fb_par *par = &currentpar;
-+		var->sync = FB_SYNC_BROADCAST | FB_VMODE_INTERLACED;
- 
--	par->xoffset = var->xoffset;
--	par->yoffset = var->yoffset;
--	if (var->vmode & FB_VMODE_YWRAP)
--		par->vmode |= FB_VMODE_YWRAP;
--	else
--		par->vmode &= ~FB_VMODE_YWRAP;
--
--	do_vmode_pan = 0;
--	pvr2_update_par();
--	do_vmode_pan = 1;
--}
--
--static int pvr2_update_par(void)
--{
--	struct pvr2fb_par *par = &currentpar;
--	u_long move;
--
--	move = get_line_length(par->xoffset, par->bpp);
--	if (par->yoffset) {
--		par->disp_start += (par->next_line * par->yoffset) + move;
--	} else
--		par->disp_start += move;
-+	hsync_total = var->left_margin + var->xres + var->right_margin +
-+		      var->hsync_len;
-+	vtotal = var->upper_margin + var->yres + var->lower_margin +
-+		 var->vsync_len;
- 
-+	if (var->sync & FB_SYNC_BROADCAST) {
-+		if (var->vmode & FB_VMODE_INTERLACED)
-+			vtotal /= 2;
-+		if (vtotal > (PAL_VTOTAL + NTSC_VTOTAL)/2) {
-+			/* PAL video output */
-+			/* XXX: Should be using a range here ... ? */
-+			if (hsync_total != PAL_HTOTAL) {
-+				DPRINTK("invalid hsync total for PAL\n");
-+				return -EINVAL;
-+			}
-+		} else {
-+			/* NTSC video output */
-+			if (hsync_total != NTSC_HTOTAL) {
-+				DPRINTK("invalid hsync total for NTSC\n");
-+				return -EINVAL;
-+			}
-+		}
-+	}
-+	/* Check memory sizes */
-+	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-+	if (line_length * var->yres_virtual > videomemorysize)
-+		return -ENOMEM;
- 	return 0;
- }
- 
--static void pvr2_update_display(void)
-+static void pvr2_update_display(struct fb_info *info)
- {
--	struct pvr2fb_par *par = &currentpar;
-+	struct pvr2fb_par *par = (struct pvr2fb_par *) info->par;
-+	struct fb_var_screeninfo *var = &info->var;
- 
- 	/* Update the start address of the display image */
- 	ctrl_outl(par->disp_start, DISP_DIWADDRL);
- 	ctrl_outl(par->disp_start +
--		  get_line_length(par->xoffset + par->xres, par->bpp),
-+		  get_line_length(var->xoffset+var->xres, var->bits_per_pixel),
- 	          DISP_DIWADDRS);
- }
- 
-@@ -872,11 +483,12 @@ static void pvr2_update_display(void)
-  * registers are still undocumented.
-  */
- 
--static void pvr2_init_display(void)
-+static void pvr2_init_display(struct fb_info *info)
- {
--	struct pvr2fb_par *par = &currentpar;
-+	struct pvr2fb_par *par = (struct pvr2fb_par *) info->par;
-+	struct fb_var_screeninfo *var = &info->var;
- 	u_short diw_height, diw_width, diw_modulo = 1;
--	u_short bytesperpixel = par->bpp / 8;
-+	u_short bytesperpixel = var->bits_per_pixel >> 3;
- 
- 	/* hsync and vsync totals */
- 	ctrl_outl((par->vsync_total << 16) | par->hsync_total, DISP_SYNCSIZE);
-@@ -885,16 +497,16 @@ static void pvr2_init_display(void)
- 	/* since we're "panning" within vram, we need to offset things based
- 	 * on the offset from the virtual x start to our real gfx. */
- 	if (video_output != VO_VGA && par->is_interlaced)
--		diw_modulo += par->next_line / 4;
--	diw_height = (par->is_interlaced ? par->yres / 2 : par->yres);
--	diw_width = get_line_length(par->xres, par->bpp) / 4;
-+		diw_modulo += info->fix.line_length / 4;
-+	diw_height = (par->is_interlaced ? var->yres / 2 : var->yres);
-+	diw_width = get_line_length(var->xres, var->bits_per_pixel) / 4;
- 	ctrl_outl((diw_modulo << 20) | (--diw_height << 10) | --diw_width,
- 	          DISP_DIWSIZE);
- 
- 	/* display address, long and short fields */
- 	ctrl_outl(par->disp_start, DISP_DIWADDRL);
- 	ctrl_outl(par->disp_start +
--	          get_line_length(par->xoffset + par->xres, par->bpp),
-+	          get_line_length(var->xoffset+var->xres, var->bits_per_pixel),
- 	          DISP_DIWADDRS);
- 
- 	/* border horizontal, border vertical, border color */
-@@ -919,7 +531,6 @@ static void pvr2_init_display(void)
- 	/* video enable, color sync, interlace, 
- 	 * hsync and vsync polarity (currently unused) */
- 	ctrl_outl(0x100 | ((par->is_interlaced /*|4*/) << 4), DISP_SYNCCONF);
--
- }
- 
- /* Simulate blanking by making the border cover the entire screen */
-@@ -941,23 +552,20 @@ static void pvr2_do_blank(void)
- 
- static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
- {
--	if (do_vmode_pan || do_vmode_full)
--		pvr2_update_display();
-+	struct fb_info *info = dev_id;
- 
-+	if (do_vmode_pan || do_vmode_full)
-+		pvr2_update_display(info);
- 	if (do_vmode_full)
--		pvr2_init_display();
--
-+		pvr2_init_display(info);
- 	if (do_vmode_pan)
- 		do_vmode_pan = 0;
--
-+	if (do_vmode_full)
-+		do_vmode_full = 0;
- 	if (do_blank) {
- 		pvr2_do_blank();
- 		do_blank = 0;
- 	}
--
--	if (do_vmode_full) {
--		do_vmode_full = 0;
--	}
- 	return IRQ_HANDLED;
- }
- 
-@@ -991,94 +599,120 @@ static int pvr2_init_cable(void)
- 
- int __init pvr2fb_init(void)
- {
--	struct fb_var_screeninfo var;
- 	u_long modememused;
-+	int err = -EINVAL;
- 
--	if (!MACH_DREAMCAST)
-+	if (!mach_is_dreamcast())
- 		return -ENXIO;
- 
-+	fb_info = kmalloc(sizeof(struct fb_info) + sizeof(struct pvr2fb_par) +
-+			  sizeof(u32) * 16, GFP_KERNEL);
-+	
-+	if (!fb_info) {
-+		printk(KERN_ERR "Failed to allocate memory for fb_info\n");
-+		return -ENOMEM;
-+	}
-+
-+	memset(fb_info, 0, sizeof(fb_info) + sizeof(struct pvr2fb_par) + sizeof(u32) * 16);
-+
-+	currentpar = (struct pvr2fb_par *)(fb_info + 1);
-+
- 	/* Make a guess at the monitor based on the attached cable */
- 	if (pvr2_init_cable() == CT_VGA) {
--		fb_info.monspecs.hfmin = 30000;
--		fb_info.monspecs.hfmax = 70000;
--		fb_info.monspecs.vfmin = 60;
--		fb_info.monspecs.vfmax = 60;
--	}
--	else { /* Not VGA, using a TV (taken from acornfb) */
--		fb_info.monspecs.hfmin = 15469;
--		fb_info.monspecs.hfmax = 15781;
--		fb_info.monspecs.vfmin = 49;
--		fb_info.monspecs.vfmax = 51;
-+		fb_info->monspecs.hfmin = 30000;
-+		fb_info->monspecs.hfmax = 70000;
-+		fb_info->monspecs.vfmin = 60;
-+		fb_info->monspecs.vfmax = 60;
-+	} else {
-+		/* Not VGA, using a TV (taken from acornfb) */
-+		fb_info->monspecs.hfmin = 15469;
-+		fb_info->monspecs.hfmax = 15781;
-+		fb_info->monspecs.vfmin = 49;
-+		fb_info->monspecs.vfmax = 51;
- 	}
- 
--	/* XXX: This needs to pull default video output via BIOS or other means */
-+	/*
-+	 * XXX: This needs to pull default video output via BIOS or other means
-+	 */
- 	if (video_output < 0) {
--		if (cable_type == CT_VGA)
-+		if (cable_type == CT_VGA) {
- 			video_output = VO_VGA;
--		else
-+		} else {
- 			video_output = VO_NTSC;
-+		}
- 	}
- 	
--	strcpy(fb_info.modename, pvr2fb_name);
--	fb_info.changevar = NULL;
--	fb_info.fbops = &pvr2fb_ops;
--	fb_info.screen_base = (char *) videomemory;
--	fb_info.disp = &disp;
--	fb_info.currcon = -1;
--	fb_info.switch_con = &pvr2fbcon_switch;
--	fb_info.updatevar = &pvr2fbcon_updatevar;
--	fb_info.flags = FBINFO_FLAG_DEFAULT;
--	memset(&var, 0, sizeof(var));
-+	pvr2_fix.smem_start = videomemory;
-+	pvr2_fix.smem_len = videomemorysize;
-+
-+	fb_info->screen_base = ioremap_nocache(pvr2_fix.smem_start,
-+					       pvr2_fix.smem_len);
-+	
-+	if (!fb_info->screen_base) {
-+		printk("Failed to remap MMIO space\n");
-+		err = -ENXIO;
-+		goto out_err;
-+	}
-+
-+	memset_io((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len);
-+
-+	pvr2_fix.ypanstep	= nopan  ? 0 : 1;
-+	pvr2_fix.ywrapstep	= nowrap ? 0 : 1;
-+
-+	fb_info->fbops		= &pvr2fb_ops;
-+	fb_info->fix		= pvr2_fix;
-+	fb_info->par		= currentpar;
-+	fb_info->pseudo_palette	= (void *)(fb_info->par + 1);
-+	fb_info->flags		= FBINFO_FLAG_DEFAULT;
- 
- 	if (video_output == VO_VGA)
- 		defmode = DEFMODE_VGA;
- 
--	if (!fb_find_mode(&var, &fb_info, mode_option, pvr2_modedb,
--	                  NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16)) {
--		return -EINVAL;
--	}
-+	if (!mode_option)
-+		mode_option = "640x480@60";
- 
--	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,
--	                "pvr2 VBL handler", &currentpar)) {
--		DPRINTK("couldn't register VBL int\n");
--		return -EBUSY;
--	}
-+	if (!fb_find_mode(&fb_info->var, fb_info, mode_option, pvr2_modedb,
-+	                  NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16))
-+		fb_info->var = pvr2_var;
- 
--#ifdef CONFIG_MTRR
--	if (enable_mtrr) {
--		mtrr_handle = mtrr_add(videomemory, videomemorysize, MTRR_TYPE_WRCOMB, 1);
--		printk("pvr2fb: MTRR turned on\n");
-+	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,
-+	                "pvr2 VBL handler", fb_info)) {
-+		err = -EBUSY;
-+		goto out_err;
- 	}
--#endif
- 
--	pvr2fb_set_var(&var, -1, &fb_info);
-+	if (register_framebuffer(fb_info) < 0)
-+		goto reg_failed;
- 
--	if (register_framebuffer(&fb_info) < 0)
--		return -EINVAL;
-+	modememused = get_line_length(fb_info->var.xres_virtual,
-+				      fb_info->var.bits_per_pixel);
-+	modememused *= fb_info->var.yres_virtual;
- 
--	modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
--	modememused *= var.yres_virtual;
- 	printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
--	       fb_info.node, fb_info.modename, modememused>>10,
-+	       fb_info->node, fb_info->fix.id, modememused>>10,
- 	       videomemorysize>>10);
- 	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 
--	       fb_info.node, var.xres, var.yres, var.bits_per_pixel, 
--	       get_line_length(var.xres, var.bits_per_pixel),
-+	       fb_info->node, fb_info->var.xres, fb_info->var.yres,
-+	       fb_info->var.bits_per_pixel, 
-+	       get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
- 	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),
- 	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));
- 
- 	return 0;
-+
-+reg_failed:
-+	free_irq(HW_EVENT_VSYNC, 0);
-+out_err:
-+	kfree(fb_info);
-+
-+	return err;
- }
- 
- static void __exit pvr2fb_exit(void)
- {
--#ifdef CONFIG_MTRR
--	if (enable_mtrr) {
--		mtrr_del(mtrr_handle, videomemory, videomemorysize);
--		printk("pvr2fb: MTRR turned off\n");
--	}
--#endif
--	unregister_framebuffer(&fb_info);
-+	unregister_framebuffer(fb_info);
-+	free_irq(HW_EVENT_VSYNC, 0);
-+	kfree(fb_info);
- }
- 
- static int __init pvr2_get_param(const struct pvr2_params *p, const char *s,
-@@ -1102,7 +736,6 @@ static int __init pvr2_get_param(const s
-  * Parse command arguments.  Supported arguments are:
-  *    inverse                             Use inverse color maps
-  *    nomtrr                              Disable MTRR usage
-- *    font:<fontname>                     Specify console font
-  *    cable:composite|rgb|vga             Override the video cable type
-  *    output:NTSC|PAL|VGA                 Override the video output format
-  *
-@@ -1117,8 +750,6 @@ int __init pvr2fb_setup(char *options)
- 	char cable_arg[80];
- 	char output_arg[80];
- 
--	fb_info.fontname[0] = '\0';
--
- 	if (!options || !*options)
- 		return 0;
- 
-@@ -1128,23 +759,21 @@ int __init pvr2fb_setup(char *options)
- 		if (!strcmp(this_opt, "inverse")) {
- 			pvr2fb_inverse = 1;
- 			fb_invert_cmaps();
--		} else if (!strncmp(this_opt, "font:", 5))
--			strcpy(fb_info.fontname, this_opt + 5);
--		else if (!strncmp(this_opt, "cable:", 6))
-+		} else if (!strncmp(this_opt, "cable:", 6)) {
- 			strcpy(cable_arg, this_opt + 6);
--		else if (!strncmp(this_opt, "output:", 7))
-+		} else if (!strncmp(this_opt, "output:", 7)) {
- 			strcpy(output_arg, this_opt + 7);
--#ifdef CONFIG_MTRR
--		else if (!strncmp(this_opt, "nomtrr", 6))
--			enable_mtrr = 0;
--#endif
--		else
-+		} else if (!strncmp(this_opt, "nopan", 5)) {
-+			nopan = 1;
-+		} else if (!strncmp(this_opt, "nowrap", 6)) {
-+			nowrap = 1;
-+		} else {
- 			mode_option = this_opt;
-+		}
- 	}
- 
- 	if (*cable_arg)
- 		cable_type = pvr2_get_param(cables, cable_arg, 0, 3);
--
- 	if (*output_arg)
- 		video_output = pvr2_get_param(outputs, output_arg, 0, 3);
- 
---- linux-2.6.0-test1/drivers/video/sis/300vtbl.h	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/video/sis/300vtbl.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,7 +1,30 @@
--
--
--/* Register settings for SiS 300 series */
--
-+/* $XFree86$ */
-+/*
-+ * Register settings for SiS 300 series
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ */
- 
- typedef struct _SiS300_StStruct
- {
-@@ -39,470 +62,109 @@ static const SiS300_StStruct  SiS300_SMo
- 	{0xff,     0,   0,   0,   0,   0,   0,   0}
- };
- 
--typedef struct _SiS300_StandTableStruct
--{
--	UCHAR CRT_COLS;
--	UCHAR ROWS;
--	UCHAR CHAR_HEIGHT;
--	USHORT CRT_LEN;
--	UCHAR SR[4];
--	UCHAR MISC;
--	UCHAR CRTC[0x19];
--	UCHAR ATTR[0x14];
--	UCHAR GRC[9];
--} SiS300_StandTableStruct;
--
--static const SiS300_StandTableStruct  SiS300_StandTable[] =
--{
-- {0x28,0x18,0x08,0x0800,			/* 0x00 */
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x28,0x18,0x08,0x0800,			/* 0x01 */
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x08,0x1000,			/* 0x02 */
--  {0x01,0x03,0x00,0x02},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x08,0x1000,			/* 0x03 */
--  {0x01,0x03,0x00,0x02},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x28,0x18,0x08,0x4000,			/* 0x04 */
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
--   0xff},
--  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x03,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
--   0xff} },
-- {0x28,0x18,0x08,0x4000,			/* 0x05 */
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
--   0xff},
--  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x03,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
--   0xff} },
-- {0x50,0x18,0x08,0x4000,			/* 0x06 */
--  {0x01,0x01,0x00,0x06},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
--   0xff},
--  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
--   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
--   0x01,0x00,0x01,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
--   0xff} },
-- {0x50,0x18,0x0e,0x1000,			/* 0x07 */
--  {0x00,0x03,0x00,0x03},
--  0xa6,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
--   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
--   0x0e,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
--   0xff} },
--/* MDA_DAC*/
-- {0x00,0x00,0x00,0x0000,			/* 0x08 */
--  {0x00,0x00,0x00,0x15},
--  0x15,
--  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
--   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
--   0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15},
--  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x3f} },
--/* CGA_DAC*/
-- {0x00,0x10,0x04,0x0114,			/* 0x09 */
--  {0x11,0x09,0x15,0x00},
--  0x10,
--  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
--   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
--   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
--   0x04},
--  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
--   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
--   0x3e,0x2b,0x3b,0x2f},
--  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
--   0x3f} },
--/* EGA_DAC*/
-- {0x00,0x10,0x04,0x0114,			/* 0x0a */
--  {0x11,0x05,0x15,0x20},
--  0x30,
--  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
--   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
--   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
--   0x06},
--  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
--   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
--   0x1e,0x0b,0x1b,0x0f},
--  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
--   0x3f} },
--/* VGA_DAC*/
-- {0x00,0x10,0x04,0x0114,			/* 0x0b */
--  {0x11,0x09,0x15,0x2a},
--  0x3a,
--  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
--   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
--   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
--   0x1f},
--  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
--   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
--   0x1c,0x0e,0x11,0x15},
--  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
--   0x04} },
-- {0x08,0x0c,0x10,0x0a08,			/* 0x0c */
--  {0x0c,0x0e,0x10,0x0b},
--  0x0c,
--  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
--   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
--   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
--   0x06},
--  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
--   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
--   0x00,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00} },
-- {0x28,0x18,0x08,0x2000,			/* 0x0d */
--  {0x09,0x0f,0x00,0x06},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff} },
-- {0x50,0x18,0x08,0x4000,			/* 0x0e */
--  {0x01,0x0f,0x00,0x06},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff} },
-- {0x00,0x00,0x00,0x0000,			/* 0x0f */	/* TW: Standtable for VGA modes */
--  {0x01,0x0f,0x00,0x0e},
--  0x23,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
--   0x01,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
--   0xff} },
-- {0x4a,0x36,0x00,0x00c0,			/* 0x10 */
--  {0x00,0x00,0x00,0x00},
--  0x00,
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
--   0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00} },
-- {0x50,0x18,0x0e,0x8000,			/* 0x11 */
--  {0x01,0x0f,0x00,0x06},
--  0xa2,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
--   0xff},
--  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
--   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
--   0x0b,0x00,0x05,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
--   0xff} },
-- {0x50,0x18,0x0e,0x8000,			/* 0x12 */
--  {0x01,0x0f,0x00,0x06},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff} },
-- {0x28,0x18,0x0e,0x0800,			/* 0x13 */
--  {0x09,0x03,0x00,0x02},
--  0xa3,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x28,0x18,0x0e,0x0800,			/* 0x14 */
--  {0x09,0x03,0x00,0x02},
--  0xa3,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x0e,0x1000,			/* 0x15 */
--  {0x01,0x03,0x00,0x02},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x0e,0x1000,			/* 0x16 */
--  {0x01,0x03,0x00,0x02},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x28,0x18,0x10,0x0800,			/* 0x17 */
--  {0x08,0x03,0x00,0x02},
--  0x67,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x0c,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x10,0x1000,			/* 0x18 */
--  {0x00,0x03,0x00,0x02},
--  0x67,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x0c,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff} },
-- {0x50,0x18,0x10,0x1000,			/* 0x19 */
--  {0x00,0x03,0x00,0x02},
--  0x66,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
--   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
--   0x0e,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
--   0xff} },
-- {0x50,0x1d,0x10,0xa000,			/* 0x1a */
--  {0x01,0x0f,0x00,0x06},
--  0xe3,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
--   0xff},
--  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
--   0xff} },
-- {0x50,0x1d,0x10,0xa000,			/* 0x1b */
--  {0x01,0x0f,0x00,0x06},
--  0xe3,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff} },
-- {0x28,0x18,0x08,0x2000,			/* 0x1c */
--  {0x01,0x0f,0x00,0x0e},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
--   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
--   0x41,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
--   0xff} }
--};
--
- typedef struct _SiS300_ExtStruct
- {
--	UCHAR Ext_ModeID;
-+	UCHAR  Ext_ModeID;
- 	USHORT Ext_ModeFlag;
- 	USHORT Ext_ModeInfo;
--	USHORT Ext_Point;
- 	USHORT Ext_VESAID;
--	UCHAR Ext_VESAMEMSize;
--	UCHAR Ext_RESINFO;
--	UCHAR VB_ExtTVFlickerIndex;
--	UCHAR VB_ExtTVEdgeIndex;
--	UCHAR VB_ExtTVYFilterIndex;
--	UCHAR REFindex;
-+	UCHAR  Ext_RESINFO;
-+	UCHAR  VB_ExtTVFlickerIndex;
-+	UCHAR  VB_ExtTVEdgeIndex;
-+	UCHAR  VB_ExtTVYFilterIndex;
-+	UCHAR  REFindex;
- } SiS300_ExtStruct;
- 
- static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
- {
--	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x? */
--	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
--	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x8 */
--	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
--	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x8 */
--	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x8 */
--	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x16 */
--	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x16 */
--	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x32 */
--	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x32 */
--	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x? */
--	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
--	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
--	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
--	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
--	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
--	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
--	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
--	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
--	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
--	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
--	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
--	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
--	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
--	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
--	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
--	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
--	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
--	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
--	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
--	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  
--	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, 
--	{0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26},  /* TW: inserted 512x384x32 */
--	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x16 */
-- 	{0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10},  /* TW: inserted 640x400x32 */
--	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
--	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
--	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
--	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
--	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
--	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
--	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
--	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
--	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x8 - not in BIOS! */
--	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x16 - not in BIOS! */
--	{0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
--	{0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
--	/* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
--	{0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x8 */
--	{0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x8 */
--	{0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x16 */
--	{0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x16 */
--	{0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x32 */
--	{0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},	   /* 1024x576x32 */
--	{0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x32 */
--	{0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x8 */
--	{0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x16 */
--	/* TW: End of new 16:9 modes */
--	{0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},    /* 1280x960x32 */
--	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},    /* 1024x600 */
--	{0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
--	{0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
--	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},    /* 1152x768 */
--	{0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
--	{0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
--	{0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},    /* TW: NEW 1152x864 - not in BIOS */
--	{0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
--	{0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
--	{0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},    /* TW: NEW 848x480 - not in BIOS */
--	{0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
--	{0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
--	{0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},    /* TW: NEW 856x480 - not in BIOS */
--	{0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
--	{0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
--	{0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},    /* TW: NEW 1360x768 - not in BIOS */
--	{0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
--	{0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
--	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
-+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x? */
-+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
-+	{0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x8 */
-+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00},
-+	{0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x8 */
-+	{0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x8 */
-+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x16 */
-+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x16 */
-+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x32 */
-+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x32 */
-+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x? */
-+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x8 */
-+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
-+	{0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
-+	{0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
-+	{0x40,0x921c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x15 */
-+	{0x41,0x921d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x16 */
-+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
-+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
-+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x15 */
-+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x16 */
-+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
-+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
-+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
-+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
-+	{0x50,0x921b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x8  */
-+	{0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x8  */
-+	{0x52,0x921b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x8  */
-+	{0x56,0x921d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x16 */
-+	{0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x16 */
-+	{0x58,0x921d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x16 */
-+	{0x59,0x921b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x8  */
-+	{0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x32 */
-+	{0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x16 */
-+ 	{0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x32 */
-+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
-+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x32 */
-+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
-+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
-+	{0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
-+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
-+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
-+	{0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
-+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
-+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
-+	{0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x8 */
-+	{0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x8 */
-+	{0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x16 */
-+	{0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x16 */
-+	{0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x32 */
-+	{0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x32 */
-+	{0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x32 */
-+	{0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x8 */
-+	{0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x16 */
-+	{0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x8 */
-+	{0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x16 */
-+	{0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x32 */
-+	{0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},  /* 1024x600 */
-+	{0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
-+	{0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
-+	{0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},  /* 1152x768 */
-+	{0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
-+	{0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
-+	{0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},  /* 1152x864 */
-+	{0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
-+	{0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
-+	{0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},  /* 848x480 */
-+	{0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
-+	{0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
-+	{0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},  /* 856x480 */
-+	{0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
-+	{0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
-+	{0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},  /* 1360x768 */
-+	{0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
-+	{0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
-+	{0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x32 */
-+	{0x53,0x921f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x32 */
-+	{0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x32 */
-+	{0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},  /* 1280x768   */
-+	{0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
-+	{0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
-+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x8 */
-+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x16 */
-+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x32 */
-+	{0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
-+	{0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
-+	{0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
-+	{0xff,0x0000,0x0000,0xffff,0x00,            0x00,0x00,0x00,0x00}
- };
- 
- typedef struct _SiS300_Ext2Struct
-@@ -514,76 +176,77 @@ typedef struct _SiS300_Ext2Struct
- 	UCHAR  ModeID;
- 	USHORT XRes;
- 	USHORT YRes;
--	USHORT ROM_OFFSET;
- } SiS300_Ext2Struct;
- 
- static const SiS300_Ext2Struct  SiS300_RefIndex[] =
- { /* TW: Don't ever insert anything here, table is indexed */
--	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
--	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
--	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
--	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
--	{0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
--	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
--	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
--	{0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
--	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
--	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
--	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
--	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
--	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
--	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
--	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
--	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
--	{0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
--	{0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
--	{0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
--	{0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
--        {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
--	{0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
--	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
--	{0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
--	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
--	{0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
--	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
--	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
--	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
--	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
--	{0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
--	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
--	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
--	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
--	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
--	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
--	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
--	{0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
--	{0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */  /* was c077 */
--	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
--	{0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
--	{0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
--	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
--	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
--	{0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */	/* VCLK 0x09 */
--	{0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
--	{0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
--	{0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
--	{0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
--	{0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
--	{0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
--	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
--	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
--	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
--	{0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
--	{0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
--	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
--	{0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz  - Non-BIOS, new */
--	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
--	{0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz  - Non-BIOS, new */
--	{0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
--	{0xffff,0,0,0,0,0,0,0}
-+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */
-+	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */
-+	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */
-+	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */
-+	{0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */
-+	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */
-+	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */
-+	{0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */
-+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */
-+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */
-+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */
-+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */
-+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */
-+	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */
-+	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */
-+	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */
-+	{0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */
-+	{0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */
-+	{0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */
-+	{0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */
-+        {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */
-+	{0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */
-+	{0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */
-+	{0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */
-+	{0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */
-+	{0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */
-+	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */
-+	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */
-+	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */
-+	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */
-+	{0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */
-+	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */
-+	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */
-+	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */
-+	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */
-+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */
-+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */
-+	{0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */
-+	{0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */  /* was c077 */
-+	{0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */
-+	{0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */
-+	{0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */
-+	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */
-+	{0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */
-+	{0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */	/* VCLK 0x09 */
-+	{0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */
-+	{0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */
-+	{0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */
-+	{0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */
-+	{0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */
-+	{0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */
-+	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */
-+	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */
-+	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */
-+	{0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */
-+	{0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */
-+	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */
-+	{0xc047,0x40,0x3d,0x00,0x39, 848, 480}, /* 39 848x480-60Hz  */
-+	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */
-+	{0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz  */
-+	{0x0047,0x43,0x3e,0x00,0x48,1360, 768}, /* 3c 1360x768-60Hz */
-+	{0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */
-+	{0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */
-+	{0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
-+	{0xffff,   0,   0,   0,   0,   0,   0}
- };
- 
--/*add for 300 oem util*/
- typedef struct _SiS_VBModeIDTableStruct
- {
- 	UCHAR  ModeID;
-@@ -649,9 +312,8 @@ static const SiS_VBModeIDTableStruct  Si
- 	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
- 	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
- 	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
--	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* TW: added! */
-+	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
- };
--/*end*/
- 
- typedef struct _SiS300_CRT1TableStruct
- {
-@@ -660,15 +322,32 @@ typedef struct _SiS300_CRT1TableStruct
- 
- static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
- {
-- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 */
--  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
-+#if 1
-+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 - 320x200 */
-+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
-+  0x00}},
-+#endif
-+#if 0
-+ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f,    /* 0x00 - corrected 320x200-72 - does not work */
-+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
-   0x00}},
-- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
--  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
-+#endif
-+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,    /* 0x01 */
-+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
-   0x00}},
-- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
-+#if 0
-+ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e,    /* 0x01 - corrected 320x240-60 - does not work */
-+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
-+  0x00}},
-+#endif
-+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 */
-+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
-+  0x01}},
-+#if 0
-+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 - corrected 400x300-60 */
-   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
-   0x01}},
-+#endif  
-  {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-   0x01}},
-@@ -683,7 +362,7 @@ static const SiS300_CRT1TableStruct  SiS
-  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
-   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
-   0x00}},
-- #if 0  
-+#if 0  
-  {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
-   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
-   0x00}},
-@@ -841,15 +520,10 @@ static const SiS300_CRT1TableStruct  SiS
-  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
-   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
-   0x01}},
--#if 0
-- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
--  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
--  0x01}},
--#endif
-- {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - TW: corrected */
-+ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - corrected */
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
-- {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
-+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 */
-    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
-    0x01}}, /* 0x35 */
-  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
-@@ -864,7 +538,7 @@ static const SiS300_CRT1TableStruct  SiS
-  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
-    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
-    0x01}}, /* 0x39 */
-- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   	/* TW: 95 was 15 - illegal HBE! */
-+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,  /* 95 was 15 - illegal HBE! */
-    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
-    0x01}}, /* 0x3a */
-  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
-@@ -875,36 +549,40 @@ static const SiS300_CRT1TableStruct  SiS
-    0x01}}, /* 0x3c */
-  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
-    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
--   0x01}}, /* 0x3d */			     /* TW: End of 16:9 modes --------------- */
-- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* TW: New, 1152x864-75 (not in any BIOS)   */
-+   0x01}}, /* 0x3d */
-+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* 1152x864-75 */
-    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
-    0x01}},  /* 0x3e */
-- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 848x480-38i, not in BIOS */
-+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* 848x480-38i */
-    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
-    0x00}}, /* 0x3f */
--#if 0
-- {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
--   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
--   0x00}}, /* 0x40 */
--#endif
-- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* TW: New, 848x480-60, not in BIOS */
-+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* 848x480-60  */
-    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
-    0x00}}, /* 0x40 */
-- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 856x480-38i, not in BIOS */
-+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* 856x480-38i */
-    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
-    0x00}}, /* 0x41 */
-- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 856x480-60, not in BIOS */
-+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* 856x480-60  */
-    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
-    0x00}}, /* 0x42 */
-- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* TW: New, 1360x768-60, not in BIOS */
-+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* 1360x768-60 */
-    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
-    0x01}}, /* 0x43 */
-- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* TW: New, 1152x864-84 (not in any BIOS)   */
-+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* 1152x864-84 */
-    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
--   0x01}}, /* 0x44 */   
-- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* TW: New, 1280x960-85 (not in any BIOS)   */
-+   0x01}}, /* 0x44 */
-+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* 1280x960-85 */
-    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
--   0x01}}  /* 0x45 */
-+   0x01}}, /* 0x45 */
-+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
-+   0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
-+   0x01}},  /* 0x46 */
-+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
-+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-+   0x01}},  /* 0x47 */
-+ {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
-+   0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
-+   0x00}}   /* 0x48 */
- };
- 
- typedef struct _SiS300_MCLKDataStruct
-@@ -913,8 +591,8 @@ typedef struct _SiS300_MCLKDataStruct
- 	USHORT CLOCK;
- } SiS300_MCLKDataStruct;
- 
--static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =	/* 630 */
--{ /* TW: at 0x54 in BIOS */
-+static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
-+{
- 	{ 0x5a,0x64,0x80, 66},
- 	{ 0xb3,0x45,0x80, 83},
- 	{ 0x37,0x61,0x80,100},
-@@ -925,8 +603,8 @@ static const SiS300_MCLKDataStruct  SiS3
- 	{ 0x37,0x61,0x80,100}
- };
- 
--static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =  /* 300 */
--{ /* TW: at 0x54 in BIOS */
-+static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
-+{
- 	{ 0x68,0x43,0x80,125},
- 	{ 0x68,0x43,0x80,125},
- 	{ 0x68,0x43,0x80,125},
-@@ -937,6 +615,7 @@ static const SiS300_MCLKDataStruct  SiS3
- 	{ 0x37,0x61,0x80,100}
- };
- 
-+#ifdef LINUXBIOS
- typedef struct _SiS300_ECLKDataStruct
- {
- 	UCHAR SR2E,SR2F,SR30;
-@@ -954,6 +633,7 @@ static const SiS300_ECLKDataStruct  SiS3
- 	{ 0x54,0x43,0x80,100},
- 	{ 0x54,0x43,0x80,100}
- };
-+#endif
- 
- typedef struct _SiS300_VCLKDataStruct
- {
-@@ -964,71 +644,77 @@ typedef struct _SiS300_VCLKDataStruct
- static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
- {
- 	{ 0x1b,0xe1, 25}, /* 0x00 */
--	{ 0x4e,0xe4, 28},
-+	{ 0x4e,0xe4, 28}, /* 0x01 */
- 	{ 0x57,0xe4, 32}, /* 0x02 */
--	{ 0xc3,0xc8, 36},
-+	{ 0xc3,0xc8, 36}, /* 0x03 */
- 	{ 0x42,0xc3, 40}, /* 0x04 */
--	{ 0x5d,0xc4, 45},
-+	{ 0x5d,0xc4, 45}, /* 0x05 */
- 	{ 0x52,0x65, 50}, /* 0x06 */
--	{ 0x53,0x65, 50},
-+	{ 0x53,0x65, 50}, /* 0x07 */
- 	{ 0x6d,0x66, 56}, /* 0x08 */
--	{ 0x5a,0x64, 65},
-+	{ 0x5a,0x64, 65}, /* 0x09 */
- 	{ 0x46,0x44, 68}, /* 0x0a */
--	{ 0x3e,0x43, 75},
--	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
--	{ 0x41,0x43, 79},
-+	{ 0x3e,0x43, 75}, /* 0x0b */
-+	{ 0x6d,0x46, 76}, /* 0x0c */  /* 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
-+	{ 0x41,0x43, 79}, /* 0x0d */
- 	{ 0x31,0x42, 79}, /* 0x0e */
--	{ 0x46,0x25, 85},
-+	{ 0x46,0x25, 85}, /* 0x0f */
- 	{ 0x78,0x29, 87}, /* 0x10 */
--	{ 0x62,0x44, 95},
-+	{ 0x62,0x44, 95}, /* 0x11 */
- 	{ 0x2b,0x22,105}, /* 0x12 */
--	{ 0x49,0x24,106},
-+	{ 0x49,0x24,106}, /* 0x13 */
- 	{ 0xc3,0x28,108}, /* 0x14 */
--	{ 0x3c,0x23,109},
-+	{ 0x3c,0x23,109}, /* 0x15 */
- 	{ 0xf7,0x2c,132}, /* 0x16 */
--	{ 0xd4,0x28,136},
-+	{ 0xd4,0x28,136}, /* 0x17 */
- 	{ 0x41,0x05,158}, /* 0x18 */
--	{ 0x43,0x05,162},
-+	{ 0x43,0x05,162}, /* 0x19 */
- 	{ 0xe1,0x0f,175}, /* 0x1a */
- 	{ 0xfc,0x12,189}, /* 0x1b */
- 	{ 0xde,0x26,194}, /* 0x1c */
--	{ 0x54,0x05,203},
-+	{ 0x54,0x05,203}, /* 0x1d */
- 	{ 0x3f,0x03,230}, /* 0x1e */
--	{ 0x30,0x02,234},
-+	{ 0x30,0x02,234}, /* 0x1f */
- 	{ 0x24,0x01,266}, /* 0x20 */
--	{ 0x52,0x2a, 54}, /* 301 TV */
--	{ 0x52,0x6a, 27}, /* 301 TV */
--	{ 0x62,0x24, 70}, /* 301 TV */
--	{ 0x62,0x64, 70}, /* 301 TV */
--	{ 0xa8,0x4c, 30}, /* 301 TV */
--	{ 0x20,0x26, 33}, /* 301 TV */
--	{ 0x31,0xc2, 39},
--	{ 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
--	{ 0x60,0x36, 30}, /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
--	{ 0x40,0x4a, 28},
--	{ 0x9f,0x46, 44},
--	{ 0x97,0x2c, 26},
--	{ 0x44,0xe4, 25},
--	{ 0x7e,0x32, 47},
--	{ 0x8a,0x24, 31}, /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
--	{ 0x97,0x2c, 26},
--	{ 0xce,0x3c, 39},
--	{ 0x52,0x4a, 36}, /* 0x32  CH/PAL 800x600 5/6 */
--	{ 0x34,0x61, 95},
--	{ 0x78,0x27,108},
--	{ 0xce,0x25,189}, /* 0x35 */
--	{ 0x45,0x6b, 21}, /* 0x36 */  /* TW: Added from Mitac */
--	{ 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
--	{ 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
--	{ 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
--	{ 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
--	{ 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
--	{ 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
--	{ 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
--	{ 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
--	{ 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
--	{ 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
--	{ 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
-+	{ 0x52,0x2a, 54}, /* 0x21 */  /* 301 TV */
-+	{ 0x52,0x6a, 27}, /* 0x22 */  /* 301 TV */
-+	{ 0x62,0x24, 70}, /* 0x23 */  /* 301 TV */
-+	{ 0x62,0x64, 70}, /* 0x24 */  /* 301 TV */
-+	{ 0xa8,0x4c, 30}, /* 0x25 */  /* 301 TV */
-+	{ 0x20,0x26, 33}, /* 0x26 */  /* 301 TV */
-+	{ 0x31,0xc2, 39}, /* 0x27 */
-+	{ 0xbf,0xc8, 35}, /* 0x28 */  /* 856x480 */
-+	{ 0x60,0x36, 30}, /* 0x29 */  /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
-+	{ 0x40,0x4a, 28}, /* 0x2a */
-+	{ 0x9f,0x46, 44}, /* 0x2b */
-+	{ 0x97,0x2c, 26}, /* 0x2c */
-+	{ 0x44,0xe4, 25}, /* 0x2d */
-+	{ 0x7e,0x32, 47}, /* 0x2e */
-+	{ 0x8a,0x24, 31}, /* 0x2f */  /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
-+	{ 0x97,0x2c, 26}, /* 0x30 */
-+	{ 0xce,0x3c, 39}, /* 0x31 */
-+	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
-+	{ 0x34,0x61, 95}, /* 0x33 */
-+	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
-+	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
-+	{ 0x45,0x6b, 21}, /* 0x36 */
-+	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
-+	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
-+	{ 0x70,0x44,108}, /* 0x39 */  /* 16:9 modes  */
-+	{ 0x54,0x42,135}, /* 0x3a */  /* 16:9 modes  */
-+	{ 0x41,0x22,157}, /* 0x3b */  /* 16:9 modes  */
-+	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
-+	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
-+	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
-+#if 0
-+	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
-+#endif
-+        { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
-+	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
-+	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
-+	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
-+	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
-+	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
- 	{ 0xff,0x00,  0}   
- };
- 
-@@ -1089,66 +775,10 @@ static const SiS300_VCLKDataStruct  SiS3
- static const UCHAR  SiS300_ScreenOffset[] =
- {
- 	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
--        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,  /* 0x35 for 848 and 856 */
--	0x55,0xff			     /* 0x55 for 1360 */	
-+        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
-+	0x55,0x30,0xff
- };
- 
--typedef struct _SiS300_StResInfoStruct
--{
--	USHORT HTotal;
--	USHORT VTotal;
--} SiS300_StResInfoStruct;
--
--static const SiS300_StResInfoStruct  SiS300_StResInfo[] =
--{
--	{ 640,400},
--	{ 640,350},
--	{ 720,400},
--	{ 720,350},
--	{ 640,480}
--};
--
--typedef struct _SiS300_ModeResInfoStruct
--{
--	USHORT HTotal;
--	USHORT VTotal;
--	UCHAR  XChar;
--	UCHAR  YChar;
--} SiS300_ModeResInfoStruct;
--
--static const SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
--{
--	{  320, 200, 8, 8},  /* 0x00 */
--	{  320, 240, 8, 8},  /* 0x01 */
--	{  320, 400, 8, 8},  /* 0x02 */
--	{  400, 300, 8, 8},  /* 0x03 */
--	{  512, 384, 8, 8},  /* 0x04 */
--	{  640, 400, 8,16},  /* 0x05 */
--	{  640, 480, 8,16},  /* 0x06 */
--	{  800, 600, 8,16},  /* 0x07 */
--	{ 1024, 768, 8,16},  /* 0x08 */
--	{ 1280,1024, 8,16},  /* 0x09 */
--	{ 1600,1200, 8,16},  /* 0x0a */
--	{ 1920,1440, 8,16},  /* 0x0b */
--	{  720, 480, 8,16},  /* 0x0c */
--	{  720, 576, 8,16},  /* 0x0d */
--	{ 1280, 960, 8,16},  /* 0x0e */
--	{ 1024, 600, 8,16},  /* 0x0f */
--	{ 1152, 768, 8,16},  /* 0x10 */
--	{ 2048,1536, 8,16},  /* 0x11 - TW: Not in BIOS! */
--	{  800, 480, 8,16},  /* 0x12 - TW: New, not in any BIOS */
--	{ 1024, 576, 8,16},  /* 0x13 - TW: New, not in any BIOS */
--	{ 1280, 720, 8,16},  /* 0x14 - TW: New, not in any BIOS */
--	{ 1152, 864, 8,16},  /* 0x15 - TW: New, not in any BIOS */
--	{  848, 480, 8,16},  /* 0x16 - TW: New, not in any BIOS */
--	{  856, 480, 8,16},  /* 0x17 - TW: New, not in any BIOS */
--	{ 1360, 768, 8,16}   /* 0x18 - TW: New, not in any BIOS */
--};
--
--static const UCHAR SiS300_OutputSelect = 0x40;
--
--static const UCHAR SiS300_SoftSetting  = 0x30;
--
- #ifndef LINUX_XF86
- static UCHAR SiS300_SR07 = 0x10;
- #endif
-@@ -1183,7 +813,7 @@ static UCHAR SiS300_CRT2Data_4_10 = 0x80
- static const USHORT SiS300_RGBSenseData = 0xd1;
- static const USHORT SiS300_VideoSenseData = 0xb3;
- static const USHORT SiS300_YCSenseData = 0xb9;
--static const USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
-+static const USHORT SiS300_RGBSenseData2 = 0x0190;
- static const USHORT SiS300_VideoSenseData2 = 0x0174;
- static const USHORT SiS300_YCSenseData2 = 0x016b;
- 
-@@ -1192,15 +822,6 @@ static const UCHAR SiS300_CR40[5][4];
- static UCHAR SiS300_CR49[2];
- #endif
- 
--static const UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
--static const UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00};  */
--static const UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
--static const UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
--static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
--static const UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
--static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
--static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
--
- typedef struct _SiS300_PanelDelayTblStruct
- {
- 	UCHAR timer[2];
-@@ -1208,7 +829,7 @@ typedef struct _SiS300_PanelDelayTblStru
- 
- static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
- {
--	{{0x05,0xaa}}, /* TW: From 2.04.5a */
-+	{{0x05,0xaa}},
- 	{{0x05,0x14}},
- 	{{0x05,0x36}},
- 	{{0x05,0x14}},
-@@ -1355,309 +976,6 @@ static const SiS300_LCDDataStruct  SiS30
- 	{    1,   1,1688,1066,1688,1066}
- };
- 
--static const SiS300_LCDDataStruct  SiS300_LCD1280x960Data[] =
--{
--	{    9,   2, 800, 500,1800,1000},
--	{    9,   2, 800, 500,1800,1000},
--	{    4,   1, 900, 500,1800,1000},
--	{    4,   1, 900, 500,1800,1000},
--	{    9,   2, 800, 500,1800,1000},
--	{   30,  11,1056, 625,1800,1000},
--	{    5,   3,1350, 800,1800,1000},
--	{    1,   1,1576,1050,1576,1050},
--	{    1,   1,1800,1000,1800,1000}
--};
--
--static const SiS300_LCDDataStruct  SiS300_ExtLCD1400x1050Data[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS300_LCDDataStruct  SiS300_ExtLCD1600x1200Data[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS300_LCDDataStruct  SiS300_StLCD1400x1050Data[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS300_LCDDataStruct  SiS300_StLCD1600x1200Data[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS300_LCDDataStruct  SiS300_NoScaleData1400x1050[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS300_LCDDataStruct  SiS300_NoScaleData1600x1200[] =  /* TW: New */
--{
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0},
--	{    0,   0,   0,   0,   0,   0}
--};
--
--
--typedef struct _SiS300_TVDataStruct
--{
--	USHORT RVBHCMAX;
--	USHORT RVBHCFACT;
--	USHORT VGAHT;
--	USHORT VGAVT;
--	USHORT TVHDE;
--	USHORT TVVDE;
--	USHORT RVBHRS;
--	UCHAR FlickerMode;
--	USHORT HALFRVBHRS;
--	UCHAR RY1COE;
--	UCHAR RY2COE;
--	UCHAR RY3COE;
--	UCHAR RY4COE;
--} SiS300_TVDataStruct;
--
--static const SiS300_TVDataStruct  SiS300_StPALData[] =
--{
--	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
--	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
--	{    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
--	{    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
--	{    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
--	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
--};
--
--static const SiS300_TVDataStruct  SiS300_ExtPALData[] =
--{
--	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
--	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
--	{   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
--	{    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
--	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
--	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
--	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
--	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}
--
--};
--
--static const SiS300_TVDataStruct  SiS300_StNTSCData[] =
--{
--	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
--	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
--	{    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
--	{    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
--	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
--};
--
--static const SiS300_TVDataStruct  SiS300_ExtNTSCData[] =
--{
--	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
--	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
--	{  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
--	{  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
--	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
--	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
--	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
--	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
--};
--
--#if 0
--static const SiS300_TVDataStruct  SiS300_St1HiTVData[]=
--{
--  
--};
--#endif
--
--static const SiS300_TVDataStruct  SiS300_St2HiTVData[]=
--{
-- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
-- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
--};
--
--static const SiS300_TVDataStruct  SiS300_ExtHiTVData[]=
--{
-- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
-- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
-- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
-- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
-- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
--};
--
--static const UCHAR SiS300_NTSCTiming[] =
--{
--	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
--	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
--	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
--	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,  /* (in 2.06.50) */
--/*	0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17,     (in 2.04.5a) */
--	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,  /* (in 2.06.50) */
--/*	0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02,     (in 2.04.5a) */
--	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
--	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
--};
--
--static const UCHAR SiS300_PALTiming[] =
--{
--	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
--	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
--        0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,  /* (in 2.06.50) */
--/*	0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17,     (in 2.04.5a) */
--	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,  /* (in 2.06.50) */
--/*	0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02,     (in 2.04.5a) */
--	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
--	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
--};
--
--static const UCHAR SiS300_HiTVExtTiming[] =	 /* TW: New */
--{
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
--	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
--	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
--	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
--};
--
--static const UCHAR SiS300_HiTVSt1Timing[] =   	/* TW: New */
--{
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
--	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
--	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
--	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
--};
--
--static const UCHAR SiS300_HiTVSt2Timing[] =	/* TW: New */
--{
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
--	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
--	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
--	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
--};
--
--static const UCHAR SiS300_HiTVTextTiming[] =   	/* TW: New */
--{
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
--	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
--	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
--        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
--	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
--};
--
--static const UCHAR SiS300_HiTVGroup3Data[] =   	/* TW: New */
--{
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
--	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
--	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
--static const UCHAR SiS300_HiTVGroup3Simu[] =   	/* TW: New */
--{
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
--	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
--	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
--static const UCHAR SiS300_HiTVGroup3Text[] =   	/* TW: New */
--{
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
--	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
--	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
- typedef struct _SiS300_LVDSDataStruct
- {
- 	USHORT VGAHT;
-@@ -1666,366 +984,14 @@ typedef struct _SiS300_LVDSDataStruct
- 	USHORT LCDVT;
- } SiS300_LVDSDataStruct;
- 
--static const SiS300_LVDSDataStruct  SiS300_LVDS320x480Data_1[] =
--{
--	{848, 433,400, 525},
--	{848, 389,400, 525},
--	{848, 433,400, 525},
--	{848, 389,400, 525},
--	{848, 518,400, 525},
--	{1056,628,400, 525},
--	{400, 525,400, 525},
--	{800, 449,1000, 644},
--	{800, 525,1000, 635}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[] =
--{
--	{848, 433,1060, 629},
--	{848, 389,1060, 629},
--	{848, 433,1060, 629},
--	{848, 389,1060, 629},
--	{848, 518,1060, 629},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{800, 449,1000, 644},
--	{800, 525,1000, 635}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[] =
--{
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{800, 449,1000, 644},
--	{800, 525,1000, 635}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[] =
--{
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 518,1344, 806},
--	{1050, 638,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[] =
--{
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=  
--{	
--	{1048, 442,1688,1066},
--	{1048, 392,1688,1066},
--	{1048, 442,1688,1066},
--	{1048, 392,1688,1066},
--	{1048, 522,1688,1066},
--	{1208, 642,1688,1066},
--	{1432, 810,1688,1066},
--	{1688,1066,1688,1066}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=  
--{	
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_1[] =   
--{
--        {928, 416, 1688, 1066},
--	{928, 366, 1688, 1066},
--	{928, 416, 1688, 1066},
--	{928, 366, 1688, 1066},
--	{928, 496, 1688, 1066},
--	{1088, 616, 1688, 1066},
--	{1312, 784, 1688, 1066},
--	{1568, 1040, 1688, 1066},
--	{1688, 1066, 1688, 1066}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_2[] =  
--{
--        {1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_1[]=  
--{
--        {1088, 450, 2048,1250},
--	{1088, 400, 2048,1250},
--	{1088, 450, 2048,1250},
--	{1088, 400, 2048,1250},
--	{1088, 530, 2048,1250},
--	{1248, 650, 2048,1250},
--	{1472, 818, 2048,1250},
--	{1728,1066, 2048,1250},
--	{1848,1066, 2048,1250},
--	{2048,1250, 2048,1250}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_2[]= 
--{
--        {2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_1[]= 
--{	
--	{ 768, 438, 1408, 806},
--	{ 768, 388, 1408, 806},
--	{ 768, 438, 1408, 806},
--	{ 768, 388, 1408, 806},
--	{ 768, 518, 1408, 806},
--	{ 928, 638, 1408, 806},
--	{1152, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_2[]=  
--{	
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[] =
--{
--	{840, 604,1344, 800},
--	{840, 560,1344, 800},
--	{840, 604,1344, 800},
--	{840, 560,1344, 800},
--	{840, 689,1344, 800},
--	{1050, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{800, 449,1280, 789},
--	{800, 525,1280, 785}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[] =
--{
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{1344, 800,1344, 800},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[] =
--{
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 518,1344, 806},
--	{1050, 638,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[] =
--{
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--/* TW: pass 1:1 data */
--static const SiS300_LVDSDataStruct  SiS300_LVDSXXXxXXXData_1[]=  
--{
--        { 800, 449,  800, 449},
--	{ 800, 449,  800, 449},
--	{ 900, 449,  900, 449},
--	{ 900, 449,  900, 449},
--	{ 800, 525,  800, 525},  /*  640x480   */
--	{1056, 628, 1056, 628},  /*  800x600   */
--	{1344, 806, 1344, 806},  /* 1024x768   */
--	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
-- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
--	/* No other panels ! */
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[] =
--{
--	{800, 449, 800, 449},
--	{800, 449, 800, 449},
--	{800, 449, 800, 449},
--	{800, 449, 800, 449},
--	{800, 525, 800, 525},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_1[] =   /* TW: New */
--{
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 438,1344, 806},
--	{840, 409,1344, 806},
--	{840, 518,1344, 806},
--	{1050, 638,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_2[] =   /* TW: New */
--{
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_1[] =   /* TW: New */
--{	/* TW: Might be temporary (invalid) data */
--        {928, 416, 1688, 1066},
--	{928, 366, 1688, 1066},
--	{1008, 416, 1688, 1066},
--	{1008, 366, 1688, 1066},
--	{1200, 530, 1688, 1066},
--	{1088, 616, 1688, 1066},
--	{1312, 784, 1688, 1066},
--	{1568, 1040, 1688, 1066},
--	{1688, 1066, 1688, 1066}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_2[] =   /* TW: New */
--{	/* TW: Temporary data. Not valid */
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_1[] =   /* TW: New */
--{	/* TW: Temporary data. Not valid */
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{800, 449,1280, 801},
--	{800, 525,1280, 813}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_2[] =   /* TW: New */
--{	/* TW: Temporary data. Not valid */
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0}
--};
--
--
--/* TW: New: */
--static const SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[] =
--{
--	{840, 600, 840, 600},
--	{840, 600, 840, 600},
--	{840, 600, 840, 600},
--	{840, 600, 840, 600},
--	{784, 600, 784, 600},
--	{1064, 750,1064, 750}
--};
--
--static const SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[] =
--{
--	{840, 525, 840, 525},
--	{840, 525, 840, 525},
--	{840, 525, 840, 525},
--	{840, 525, 840, 525},
--	{784, 525, 784, 525},
--	{1040, 700,1040, 700}
--};
--
- static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
- {
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
--	{840, 750, 840, 750},
--	{936, 836, 936, 836}
-+	{ 840, 750, 840, 750},
-+	{ 936, 836, 936, 836}
- };
- 
- static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
-@@ -2034,8 +1000,8 @@ static const SiS300_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
--	{840, 625, 840, 625},
--	{960, 750, 960, 750}
-+	{ 840, 625, 840, 625},
-+	{ 960, 750, 960, 750}
- };
- 
- static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
-@@ -2044,12 +1010,10 @@ static const SiS300_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
--	{840, 500, 840, 500},
--	{944, 625, 944, 625}
-+	{ 840, 500, 840, 500},
-+	{ 944, 625, 944, 625}
- };
- 
--/* TW: new end */
--
- typedef struct _SiS300_LVDSDesStruct
- {
- 	USHORT LCDHDES;
-@@ -2058,57 +1022,90 @@ typedef struct _SiS300_LVDSDesStruct
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
- {
-+	{ 1059, 626 },   /* 2.08 */
-+	{ 1059, 624 },
-+	{ 1059, 626 },
-+	{ 1059, 624 },
-+	{ 1059, 624 },
-+	{    0, 627 },
-+	{    0, 627 },
-+	{    0,   0 },
-+	{    0,   0 }
-+#if 0
- 	{0, 626},
- 	{0, 624},
- 	{0, 626},
- 	{0, 624},
- 	{0, 624},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{0, 627},
-+	{0, 627},
-+	{0,   0},
-+	{0,   0}
-+#endif
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
- {
-+	{   0,   0 },  /* 2.08 */
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 },
-+	{   0,   0 }
-+#if 0
- 	{1343, 798},
- 	{1343, 794},
- 	{1343, 798},
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
-+#endif
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
- {
-+	{ 1059, 626 },  /* 2.08 */
-+	{ 1059, 624 },
-+	{ 1059, 626 },
-+	{ 1059, 624 },
-+	{ 1059, 624 },
-+	{    0, 627 },
-+	{    0, 627 },
-+	{    0,   0 },
-+	{    0,   0 }
-+#if 0
- 	{0, 626},
- 	{0, 624},
- 	{0, 626},
- 	{0, 624},
- 	{0, 624},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{0, 627},
-+	{0, 627},
-+	{0,   0},
-+	{0,   0}
-+#endif
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
- {
--	{ 8, 436},
--	{ 8, 440},
--	{ 8, 436},
--	{ 8, 440},
--	{ 8, 512},
-+	{   8, 436},
-+	{   8, 440},
-+	{   8, 436},
-+	{   8, 440},
-+	{   8, 512},
- 	{1343, 798},
- 	{1343, 794},
- 	{1343, 798},
- 	{1343, 794}
- };
- 
--static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =
-+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =	/* 1280x1024 */
- {
- 	{1343, 798},
- 	{1343, 794},
-@@ -2116,9 +1113,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
-@@ -2129,9 +1126,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
-@@ -2142,9 +1139,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
-@@ -2155,9 +1152,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
-@@ -2167,10 +1164,10 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1059, 626},
- 	{1059, 624},
- 	{1059, 624},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{   0, 627},
-+	{   0, 627},
-+	{   0,   0},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
-@@ -2181,9 +1178,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
-@@ -2193,23 +1190,23 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1059, 626},
- 	{1059, 624},
- 	{1059, 624},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{   0, 627},
-+	{   0, 627},
-+	{   0,   0},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
- {
--	{1343, 0},
--	{1343, 0},
--	{1343, 0},
--	{1343, 0},
--	{1343, 0},   /* 640x480 - BIOS 1343, 0 */
--	{1343, 0},
--	{ 0, 799},
--	{ 0, 0},
--	{ 0, 0}
-+	{1343,   0},
-+	{1343,   0},
-+	{1343,   0},
-+	{1343,   0},
-+	{1343,   0},
-+	{1343,   0},
-+	{   0, 799},
-+	{   0,   0},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
-@@ -2220,9 +1217,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
-@@ -2233,9 +1230,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
-@@ -2244,11 +1241,11 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343, 798},
- 	{1343, 794},
--	{1343,   0},  /* 640x480 */
--	{1343,   0},  /* 800x600 */
--	{ 0, 805},    /* 1024x768 */
--	{ 0, 794},    /* 1280x1024 */
--	{ 0,   0}     /* 1280x960 - not applicable */
-+	{1343,   0},    /* 640x480 */
-+	{1343,   0},    /* 800x600 */
-+	{   0, 805},    /* 1024x768 */
-+	{   0, 794},    /* 1280x1024 */
-+	{   0,   0}     /* 1280x960 - not applicable */
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
-@@ -2259,9 +1256,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1343, 794},
- 	{1343,   0},
- 	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
-@@ -2271,10 +1268,10 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{976, 527},
- 	{976, 502},
- 	{976, 567},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{  0, 627},
-+	{  0, 627},
-+	{  0,   0},
-+	{  0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
-@@ -2285,9 +1282,9 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{1152, 597},
- 	{1152, 662},
- 	{1232, 722},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{   0, 805},
-+	{   0, 794},
-+	{   0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
-@@ -2297,10 +1294,10 @@ static const SiS300_LVDSDesStruct  SiS30
- 	{976, 527},
- 	{976, 502},
- 	{976, 567},
--	{ 0, 627},
--	{ 0, 627},
--	{ 0,   0},
--	{ 0,   0}
-+	{  0, 627},
-+	{  0, 627},
-+	{  0,   0},
-+	{  0,   0}
- };
- 
- static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
-@@ -2472,156 +1469,57 @@ static const SiS300_LVDSDesStruct  SiS30
-  	{   0,   0}
- };
- 
--static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_1[]= 
-+/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
-+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =	/* 1280x1024 (1366x1024) */
- {
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0, 806},
--	{ 0, 0 }
--};
--
--static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_2[] = 
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] =   /* TW: New */
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] =   /* TW: New */
--{
--	{ 1152, 622 },
--	{ 1152, 597 },
--	{ 1152, 622 },
--	{ 1152, 597 },
--	{ 1152, 622 },
--	{ 1232, 722 },
--	{    0, 0   },
--	{    0, 794 },
--	{    0, 0   }
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] =   /* TW: New */
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] =   /* TW: New */
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] =   /* TW: New */
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] =   /* TW: New */
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--
--/* TW: New */
--static const SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[] =
--{
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0}
--};
--
--static const SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[] =
--{
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0},
-- 	{ 0,   0}
--};
--
--static const SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[] =
--{
-- 	{256,   0},
-- 	{256,   0},
-- 	{256,   0},
-- 	{256,   0},
-- 	{  0,   0},
-- 	{  0,   0}
-+	{1330, 798},  /* 320x200 */
-+	{1330, 794},
-+	{1330, 798},
-+	{1330, 794},
-+	{1330,   0},  /* 640x480 / 320x240  */
-+	{1343,   0},  /* 800x600 / 400x300  */
-+	{   0, 805},  /* 1024x768 / 512x384 */
-+	{1688,1066},  /* 1280x1024          */
-+	{   0,   0}   /* 1360x1024          */
- };
- 
--static const SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[] =
-+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
- {
-- 	{256,   0},
-- 	{256,   0},
-- 	{256,   0},
-- 	{256,   0},
-- 	{  0,   0},
-- 	{  0,   0}
-+	{1152, 622},
-+	{1152, 597},
-+	{1152, 622},
-+	{1152, 597},
-+	{1152, 662},
-+	{1232, 722},
-+	{   0, 805},
-+	{1688,1066},
-+	{   0,   0}
-+};
-+
-+/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
-+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =	/* 1024x768 */
-+{
-+	{1330, 798},  /* 320x200 */
-+	{1330, 794},
-+	{1330, 798},
-+	{1330, 794},
-+	{1330,   0},  /* 640x480 / 320x240  */
-+	{1343,   0},  /* 800x600 / 400x300  */
-+	{   0, 805}   /* 1024x768 / 512x384 */
-+};
-+
-+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
-+{
-+	{1152, 622},
-+	{1152, 597},
-+	{1152, 622},
-+	{1152, 597},
-+	{1152, 662},
-+	{1232, 722},
-+	{   0, 805}
- };
--/* TW: New end */
- 
--/* TW: New for SiS300+301LV */
-+
- typedef struct _SiS300_Part2PortTblStruct
- {
-  	UCHAR CR[12];
-@@ -2726,6 +1624,28 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01 }}
- };
- 
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
-+{
-+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-+	  0x00 }},
-+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-+	  0x00 }},
-+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-+	  0x00 }},
-+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-+	  0x00 }},
-+	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
-+	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
-+	  0x00 }},
-+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-+	  0x01 }}
-+};
-+
- static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
- { 
- 	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-@@ -2751,55 +1671,31 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01}}
- };
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
--{
--	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00 }},
--	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00 }},
--	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00 }},
--	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00 }},
--	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
--	  0x00 }},
--	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
--	  0x01 }},
--	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01 }}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
- {
--	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
--	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
--	  0x00 }},
--	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
--	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
--	  0x00 }},
--	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
--	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
--	  0x00 }},
--	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
--	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
--	  0x00 }},
--	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
--	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
-+	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 	  0x00 }},
--	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
--	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-+	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
-+	  0x00}},
-+	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-+	  0x00}},
-+	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
-+	  0x00}},
-+	{{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-+	  0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
-+	  0x00}},
-+	{{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-+	  0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
-+	  0x01}},
-+	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 	  0x01 }}
--};
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
--{
-+#if 0
- 	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
- 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 	  0x00 }},
-@@ -2821,6 +1717,32 @@ static const SiS300_LVDSCRT1DataStruct  
- 	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
- 	  0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
- 	  0x01 }}
-+#endif
-+};
-+
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
-+{
-+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+	  0x00 }},
-+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-+	  0x00 }},
-+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+	  0x00 }},
-+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-+	  0x00 }},
-+	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
-+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-+	  0x00 }},
-+	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-+	  0x01 }},
-+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	  0x01 }}
- };
- 
- static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
-@@ -2870,32 +1792,29 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01 }}
- };
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
- {
--	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
- 	  0x00 }},
--	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
- 	  0x00 }},
--	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
- 	  0x00 }},
--	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
-+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
- 	  0x00 }},
--	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
-+	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
- 	  0x00 }},
--	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
--	  0x01 }},
--	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
- 	  0x01 }}
- };
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
- {
- 	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-@@ -2920,28 +1839,6 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01 }}
- };
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
--{
--	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
--	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
--	  0x00 }},
--	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
--	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
--	  0x00 }},
--	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
--	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
--	  0x00 }},
--	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
--	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
--	  0x00 }},
--	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
--	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
--	  0x00 }},
--	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
--	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
--	  0x01 }}
--};
--
- static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
- {
- 	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-@@ -2967,6 +1864,31 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01 }}
- };
- 
-+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
-+{
-+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00 }},
-+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00 }},
-+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00 }},
-+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00 }},
-+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-+	  0x00 }},
-+	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-+	  0x01 }},
-+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	  0x01 }}
-+};
-+
- static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
- {
- 	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-@@ -2992,207 +1914,6 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x01}}
- };
- 
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
--{
--        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
--	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
--	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
--	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
--	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
--	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
--	  0x00}},
--        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
--	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
--	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
--{
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--          0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
--	  0x00}},
--        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
--{
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
--{
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
--{
--        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
--	  0x00}},
--        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
--{
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
--	  0x00}},
--        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
--{
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
--{
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--/* TW: New */
- static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
- {
- 	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-@@ -3302,9 +2023,7 @@ static const SiS300_LVDSCRT1DataStruct  
- 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
- 	  0x01 }}
- };
--/* TW: New end */
- 
--/* TW: New */
- typedef struct _SiS300_CHTVRegDataStruct
- {
- 	UCHAR Reg[16];
-@@ -3361,9 +2080,7 @@ static const SiS300_CHTVRegDataStruct Si
- 	{{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
- 	{{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
- };
--/* TW: New end */
- 
--/* TW: New */
- static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
- 
- static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
-@@ -3375,6 +2092,5 @@ static const UCHAR SiS300_CHTVVCLKUPAL[]
- static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
- 
- static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
--/* TW: New end */
- 
- 
---- linux-2.6.0-test1/drivers/video/sis/310vtbl.h	2003-06-14 12:18:23.000000000 -0700
-+++ 25/drivers/video/sis/310vtbl.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,7 +1,30 @@
--
--
--/* Register settings for SiS 310/325/330 series */
--
-+/* $XFree86$ */
-+/*
-+ * Register settings for SiS 315/330 series
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ */
- 
- typedef struct _SiS310_StStruct
- {
-@@ -39,466 +62,12 @@ static const SiS310_StStruct SiS310_SMod
- 	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
- };
- 
--typedef struct _SiS310_StandTableStruct
--{
--	UCHAR CRT_COLS;
--	UCHAR ROWS;
--	UCHAR CHAR_HEIGHT;
--	USHORT CRT_LEN;
--	UCHAR SR[4];
--	UCHAR MISC;
--	UCHAR CRTC[0x19];
--	UCHAR ATTR[0x14];
--	UCHAR GRC[9];
--} SiS310_StandTableStruct;
--
--static const SiS310_StandTableStruct SiS310_StandTable[]=
--{
--/* 0x00: MD_0_200 */
-- {
--  0x28,0x18,0x08,0x0800,
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x01: MD_1_200 */
-- {
--  0x28,0x18,0x08,0x0800,
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x02: MD_2_200 */
-- {
--  0x50,0x18,0x08,0x1000,
--  {0x01,0x03,0x00,0x02},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x03: MD_3_200 - mode 0x03 - 0 */
-- {
--  0x50,0x18,0x08,0x1000,
--  {0x01,0x03,0x00,0x02},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x04: MD_4 */
-- {
--  0x28,0x18,0x08,0x4000,
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
--   0xff},
--  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x03,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
--   0xff}
-- },
--/* 0x05: MD_5 */
-- {
--  0x28,0x18,0x08,0x4000,
--  {0x09,0x03,0x00,0x02},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
--   0xff},
--  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x03,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
--   0xff}
-- },
--/* 0x06: MD_6 */
-- {
--  0x50,0x18,0x08,0x4000,
--  {0x01,0x01,0x00,0x06},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
--   0xff},
--  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
--   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
--   0x01,0x00,0x01,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
--   0xff}
-- },
--/* 0x07: MD_7 */
-- {
--  0x50,0x18,0x0e,0x1000,
--  {0x00,0x03,0x00,0x03},
--  0xa6,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
--   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
--   0x0e,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
--   0xff}
-- },
--/* 0x08: MDA_DAC */
-- {
--  0x00,0x00,0x00,0x0000,
--  {0x00,0x00,0x00,0x15},
--  0x15,
--  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
--   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
--   0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
--   0x15,0x15,0x15,0x15},
--  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x3f}
-- },
--/* 0x09: CGA_DAC */
-- {
--  0x00,0x10,0x04,0x0114,
--  {0x11,0x09,0x15,0x00},
--  0x10,
--  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
--   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
--   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
--   0x04},
--  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
--   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
--   0x3e,0x2b,0x3b,0x2f},
--  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
--   0x3f}
-- },
--/* 0x0a: EGA_DAC */
-- {
--  0x00,0x10,0x04,0x0114,
--  {0x11,0x05,0x15,0x20},
--  0x30,
--  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
--   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
--   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
--   0x06},
--  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
--   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
--   0x1e,0x0b,0x1b,0x0f},
--  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
--   0x3f}
-- },
--/* 0x0b: VGA_DAC */
-- {
--  0x00,0x10,0x04,0x0114,
--  {0x11,0x09,0x15,0x2a},
--  0x3a,
--  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
--   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
--   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
--   0x1f},
--  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
--   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
--   0x1c,0x0e,0x11,0x15},
--  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
--   0x04}
-- },
--/* 0x0c */ 
-- {
--  0x08,0x0c,0x10,0x0a08,
--  {0x0c,0x0e,0x10,0x0b},
--  0x0c,
--  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
--   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
--   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
--   0x06},
--  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
--   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
--   0x00,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00}
-- },
--/* 0x0d: MD_D */
-- {
--  0x28,0x18,0x08,0x2000,
--  {0x09,0x0f,0x00,0x06},
--  0x63,
--  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff}
-- },
--/* 0x0e: MD_E */
-- {
--  0x50,0x18,0x08,0x4000,
--  {0x01,0x0f,0x00,0x06},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff}
-- },
--/* 0x0f: ExtVGATable - modes > 0x13 */
-- {
--  0x00,0x00,0x00,0x0000,
--  {0x01,0x0f,0x00,0x0e},
--  0x23,
--  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
--   0x01,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
--   0xff}
-- },
--/* 0x10: ROM_SAVEPTR */
-- {
--  0x9f,0x3b,0x00,0x00c0,
--  {0x00,0x00,0x00,0x00},
--  0x00,
--  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
--   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
--   0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00,0x00,0x00,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x00}
-- },
--/* 0x11: MD_F */
-- {
--  0x50,0x18,0x0e,0x8000,
--  {0x01,0x0f,0x00,0x06},
--  0xa2,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
--   0xff},
--  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
--   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
--   0x0b,0x00,0x05,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
--   0xff}
-- },
--/* 0x12: MD_10 */
-- {
--  0x50,0x18,0x0e,0x8000,
--  {0x01,0x0f,0x00,0x06},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff}
-- },
--/* 0x13: MD_0_350 */
-- {
--  0x28,0x18,0x0e,0x0800,
--  {0x09,0x03,0x00,0x02},
--  0xa3,
--  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x14: MD_1_350 */
-- {
--  0x28,0x18,0x0e,0x0800,
--  {0x09,0x03,0x00,0x02},
--  0xa3,
--  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x15: MD_2_350 */
-- {
--  0x50,0x18,0x0e,0x1000,
--  {0x01,0x03,0x00,0x02},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x16: MD_3_350 - mode 0x03 - 1 */
-- {
--  0x50,0x18,0x0e,0x1000,
--  {0x01,0x03,0x00,0x02},
--  0xa3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
--   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x08,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x17: MD_0_1_400 */
-- {
--  0x28,0x18,0x10,0x0800,
--  {0x08,0x03,0x00,0x02},
--  0x67,
--  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x0c,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
-- {
--  0x50,0x18,0x10,0x1000,
--  {0x00,0x03,0x00,0x02},
--  0x67,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x0c,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
--   0xff}
-- },
--/* 0x19: MD_7_400 */
-- {
--  0x50,0x18,0x10,0x1000,
--  {0x00,0x03,0x00,0x02},
--  0x66,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
--   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
--   0x0e,0x00,0x0f,0x08},
--  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
--   0xff}
-- },
--/* 0x1a: MD_11 */
-- {
--  0x50,0x1d,0x10,0xa000,
--  {0x01,0x0f,0x00,0x06},
--  0xe3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
--   0xff},
--  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
--   0xff}
-- },
--/* 0x1b: ExtEGATable - Modes <= 0x02 */
-- {
--  0x50,0x1d,0x10,0xa000,
--  {0x01,0x0f,0x00,0x06},
--  0xe3,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
--   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
--   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
--   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
--   0x01,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
--   0xff}
-- },
--/* 0x1c: MD_13 */
-- {
--  0x28,0x18,0x08,0x2000,
--  {0x01,0x0f,0x00,0x0e},
--  0x63,
--  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
--   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
--   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
--   0xff},
--  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
--   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
--   0x41,0x00,0x0f,0x00},
--  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
--   0xff}
-- }
--};
--
- typedef struct _SiS310_ExtStruct
- {
- 	UCHAR Ext_ModeID;
- 	USHORT Ext_ModeFlag;
- 	USHORT Ext_ModeInfo;
--	USHORT Ext_Point;    /* TW: Address of table entry in (older) BIOS image */
- 	USHORT Ext_VESAID;
--	UCHAR Ext_VESAMEMSize;
- 	UCHAR Ext_RESINFO;
- 	UCHAR VB_ExtTVFlickerIndex;
- 	UCHAR VB_ExtTVEdgeIndex;
-@@ -506,93 +75,93 @@ typedef struct _SiS310_ExtStruct
- 	UCHAR REFindex;
- } SiS310_ExtStruct;
- 
--/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
- static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
- {
--	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x? */
--	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x8 */
--/*	{0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},    */    /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
--	{0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},          /* 640x400x8 */
--/*	{0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},    */    /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
--	{0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x8 */
--/*	{0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},    */    /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
--/*      {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},    */    /* 720x480x8 */
--        {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x8 BIOS (301/LVDS) */
--	{0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x8 */
--	{0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x16 */
--	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x16 */
--	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x32 */
--	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x32 */
--	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x? */
--	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x8 */
--	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
--	{0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
--	{0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
--	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
--	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
--	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
--	{0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x16 */
--	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
--	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x16 */
--	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
--	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x16 */
--	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
--	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x16 */
--	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240 */
--	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
--  	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 650/301 BIOS */
--	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
--	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
-- 	{0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},          /* BIOS (301+LVDS) */
--	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200 */
--	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x8 fstn add new mode*/
--	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x16 fstn add new mode*/
--	{0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28},          /* TW: inserted 512x384x32 */
--	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
--	{0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10},          /* TW: Inserted 640x400x32 */
--	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x32 */
--	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x32 */
--	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x32 */
--	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
--	{0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
--	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x8 */
--	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x16 */
--	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x32 */
--	{0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x8 */
--	{0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x16 */
--	{0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x32 */
--	{0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x8 */
--	{0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x8 */
--	{0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x16 */
--	{0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x16 */
--	{0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x32 */
--	{0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},	   /* 1024x576x32 */
--	{0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x32 */
--	{0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x8 */
--	{0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x16 */
--	{0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x8 - TW */
--	{0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x16 - TW */
--	{0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x32 - TW */
--        /* TW: 650/LVDS BIOS new modes */
--	{0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x8 */
--	{0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x16 */
--	{0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x32 */
--	{0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x8 */
--	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
--	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
--	{0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},    /* TW: NEW 1152x864 - not in BIOS */
--	{0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
--	{0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
--	{0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},    /* TW: NEW 848x480 - not in BIOS */
--	{0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
--	{0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
--	{0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},    /* TW: NEW 856x480 - not in BIOS */
--	{0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
--	{0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
--	{0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},    /* TW: NEW 1360x768 - not in BIOS */
--	{0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
--	{0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
--	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
-+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x? */
-+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x8 */
-+        {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x10}, /* 640x400x8 */
-+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x8 */
-+        {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x8 */
-+	{0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x8 */
-+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x16 */
-+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x16 */
-+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x32 */
-+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x32 */
-+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */
-+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */
-+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
-+	{0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
-+	{0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
-+	{0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x15 */
-+	{0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x16 */
-+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x08},
-+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x16 */
-+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x00},
-+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x16 */
-+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
-+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */
-+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
-+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
-+	{0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x8  */
-+	{0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x8  */
-+  	{0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x8  */
-+	{0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x16 */
-+	{0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x16 */
-+ 	{0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x16 */
-+	{0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x8  */
-+	{0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x8  fstn */
-+	{0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */
-+	{0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x32 */
-+	{0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x07,0x10},
-+	{0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x07,0x10}, /* 640x400x32 */
-+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x32 */
-+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x32 */
-+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */
-+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
-+	{0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
-+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
-+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
-+	{0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
-+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
-+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
-+	{0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
-+	{0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x8 */
-+	{0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */
-+	{0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */
-+	{0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
-+	{0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x32 */
-+	{0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */
-+	{0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
-+	{0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
-+	{0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x16 */
-+	{0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
-+	{0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
-+	{0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
-+	{0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */
-+	{0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */
-+	{0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */
-+	{0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
-+	{0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
-+	{0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
-+	{0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */
-+	{0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
-+	{0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
-+	{0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45}, /* 848x480 */
-+	{0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
-+	{0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
-+	{0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47}, /* 856x480 */
-+	{0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
-+	{0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
-+	{0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */
-+	{0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
-+	{0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
-+	{0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x32 */
-+	{0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x32 */
-+	{0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x32 */
-+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x8 */
-+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x16 */
-+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x32 */
-+	{0xff,0x0000,0x0000,0x0000,0x00,            0x00,0x00,0x00,0x00}
- };
- 
- typedef struct _SiS310_Ext2Struct
-@@ -604,89 +173,87 @@ typedef struct _SiS310_Ext2Struct
- 	UCHAR  ModeID;
- 	USHORT XRes;
- 	USHORT YRes;
--	USHORT ROM_OFFSET;
- } SiS310_Ext2Struct;
- 
- static const SiS310_Ext2Struct SiS310_RefIndex[]=
- {
--/*	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81},    0x0 - TW: Patch for Chrontel 7019  */
--	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
--	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
--	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
--	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
--	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
--	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
--	{0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
--	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
--/*	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57},    0x8 - TW: Patch for Chrontel 7019  */
--	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
--	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
--	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
--	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
--	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
--	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
--	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
--	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
--	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
--	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
--	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
--	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
--	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
--	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
--	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
--	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
--	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
--	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
--	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
--	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
--	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
--	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
--	{0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
--	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
--	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
--	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
--	{0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
--	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
--	{0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
--	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
--	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
--	{0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
--	{0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
--	{0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
--	{0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
--	{0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
--	{0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
--	{0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
--	{0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
--	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
--	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
--	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
--	{0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
--	{0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
--	{0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
--	{0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
--	{0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
--	{0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
--	{0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
--	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
--	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
--	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
--	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
--	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
--	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
--	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
--        {0x0077,0x42,0x12,0x08,0x23,1280, 768,0x0000}, /* 0x40 */  
--	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */  
--	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */    /* TW: new, not in any BIOS */
--	{0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
--	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
--	{0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
--	{0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
--	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
--	{0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
--	{0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
--	{0xffff,0x00,0x00,0x00,0x00,   0,   0,0x0000}
--}; 
-+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */
-+	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */
-+	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */
-+	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */
-+	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */
-+	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */
-+	{0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */
-+	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */
-+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */
-+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */
-+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */
-+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */
-+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */
-+	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */
-+	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */
-+	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */
-+	{0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */
-+	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */
-+	{0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */
-+	{0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */
-+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */
-+	{0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */
-+	{0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */
-+	{0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */
-+	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */
-+	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */
-+	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */
-+	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */
-+	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */
-+	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */
-+	{0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */
-+	{0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */
-+	{0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */
-+	{0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */
-+	{0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */
-+	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */
-+	{0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */
-+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */
-+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */
-+	{0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */
-+	{0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */
-+	{0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */
-+	{0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */
-+	{0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */
-+	{0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */
-+	{0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */
-+	{0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */
-+	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */
-+	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */
-+	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */
-+	{0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */
-+	{0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */
-+	{0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */
-+	{0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */
-+	{0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */
-+	{0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */
-+	{0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */
-+	{0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */
-+	{0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */
-+	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */
-+	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */
-+	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */
-+	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */
-+	{0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */    /* FSTN 320x240 */
-+        {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */    /* TW: 0x5b was 0x12 */
-+	{0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */
-+	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */
-+	{0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */
-+	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */
-+	{0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
-+	{0xc047,0x46,0x55,0x00,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
-+	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
-+	{0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
-+	{0x0047,0x49,0x58,0x00,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
-+	{0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */
-+	{0xffff,0x00,0x00,0x00,0x00,   0,   0}
-+};
- 
- typedef struct _SiS310_CRT1TableStruct
- {
-@@ -710,7 +277,7 @@ static const SiS310_CRT1TableStruct SiS3
-  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
-    0x00}}, /* 0x4 */
--#if 0   
-+#if 0
-  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-    0x00}}, /* 0x5 */
-@@ -940,19 +507,25 @@ static const SiS310_CRT1TableStruct SiS3
-    0x00}},  /* 0x4b */ 
-  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
-    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
--   0x01}}   /* 0x4c */
-+   0x01}},  /* 0x4c */
-+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
-+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-+   0x01}},  /* 0x4d */
-+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
-+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}   /* 0x4e */
- };
- 
--
- typedef struct _SiS310_MCLKDataStruct
- {
- 	UCHAR SR28,SR29,SR2A;
- 	USHORT CLOCK;
- } SiS310_MCLKDataStruct;
- 
-+#ifdef LINUXBIOS
- static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
- {
--	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
-+	{ 0x3b,0x22,0x01,143},
- 	{ 0x5c,0x23,0x01,166},
- 	{ 0x5c,0x23,0x01,166},
- 	{ 0x5c,0x23,0x01,166},
-@@ -962,7 +535,7 @@ static const SiS310_MCLKDataStruct SiS31
- 	{ 0x5c,0x23,0x01,166}
- };
- 
--static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
-+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
- {
- 	{ 0x5a,0x64,0x82, 66},
- 	{ 0xb3,0x45,0x82, 83},
-@@ -973,8 +546,22 @@ static const SiS310_MCLKDataStruct SiS31
- 	{ 0x37,0x22,0x82,133},
- 	{ 0x37,0x22,0x82,133}
- };
-+#endif
-+
-+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
-+{
-+	{ 0x5c,0x23,0x01,166},
-+	{ 0x5c,0x23,0x01,166},
-+	{ 0x7c,0x08,0x01,200},
-+	{ 0x79,0x06,0x01,250},
-+	{ 0x7c,0x08,0x01,200},
-+	{ 0x7c,0x08,0x01,200},
-+	{ 0x7c,0x08,0x01,200},
-+	{ 0x79,0x06,0x01,250}
-+};
- 
--static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =   /* @ 0x54 */
-+#ifdef LINUXBIOS
-+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
- {
- 	{ 0x5c,0x23,0x01,166},
- 	{ 0x5c,0x23,0x01,166},
-@@ -985,8 +572,9 @@ static const SiS310_MCLKDataStruct SiS31
- 	{ 0x7c,0x08,0x01,200},
- 	{ 0x79,0x06,0x01,250}
- };
-+#endif
- 
--static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
-+static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
- {
-         { 0x29,0x21,0x82,150},
- 	{ 0x5c,0x23,0x82,166},
-@@ -998,6 +586,7 @@ static const SiS310_MCLKDataStruct SiS31
- 	{ 0x37,0x22,0x82,133}
- };
- 
-+#ifdef LINUXBIOS
- typedef struct _SiS310_ECLKDataStruct
- {
-  	UCHAR SR2E,SR2F,SR30;
-@@ -1011,6 +600,7 @@ static const SiS310_ECLKDataStruct SiS31
- 	{ 0x5c,0x23,0x01,166},
- 	{ 0x5c,0x23,0x01,166}
- };
-+#endif
- 
- typedef struct _SiS310_VCLKDataStruct
- {
-@@ -1020,22 +610,22 @@ typedef struct _SiS310_VCLKDataStruct
- 
- static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
- {
--	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x5647 */
--	{ 0x4e,0xe4, 28}, /* 0x1 */
--	{ 0x57,0xe4, 31}, /* 0x2 */
--	{ 0xc3,0xc8, 36}, /* 0x3 */
--	{ 0x42,0xe2, 40}, /* 0x4 */
--	{ 0xfe,0xcd, 43}, /* 0x5 */
--	{ 0x5d,0xc4, 44}, /* 0x6 */
--	{ 0x52,0xe2, 49}, /* 0x7 */
--	{ 0x53,0xe2, 50}, /* 0x8 */
--	{ 0x74,0x67, 52}, /* 0x9 */
--	{ 0x6d,0x66, 56}, /* 0xa */
--	{ 0x5a,0x64, 65}, /* 0xb */   /* TW: was 6c c3 - WRONG */
--	{ 0x46,0x44, 67}, /* 0xc */
--	{ 0xb1,0x46, 68}, /* 0xd */
--	{ 0xd3,0x4a, 72}, /* 0xe */
--	{ 0x29,0x61, 75}, /* 0xf */
-+	{ 0x1b,0xe1, 25}, /* 0x00 */
-+	{ 0x4e,0xe4, 28}, /* 0x01 */
-+	{ 0x57,0xe4, 31}, /* 0x02 */
-+	{ 0xc3,0xc8, 36}, /* 0x03 */
-+	{ 0x42,0xe2, 40}, /* 0x04 */
-+	{ 0xfe,0xcd, 43}, /* 0x05 */
-+	{ 0x5d,0xc4, 44}, /* 0x06 */
-+	{ 0x52,0xe2, 49}, /* 0x07 */
-+	{ 0x53,0xe2, 50}, /* 0x08 */
-+	{ 0x74,0x67, 52}, /* 0x09 */
-+	{ 0x6d,0x66, 56}, /* 0x0a */
-+	{ 0x5a,0x64, 65}, /* 0x0b */  /* TW: was 6c c3 - WRONG */
-+	{ 0x46,0x44, 67}, /* 0x0c */
-+	{ 0xb1,0x46, 68}, /* 0x0d */
-+	{ 0xd3,0x4a, 72}, /* 0x0e */
-+	{ 0x29,0x61, 75}, /* 0x0f */
- 	{ 0x6e,0x46, 76}, /* 0x10 */
- 	{ 0x2b,0x61, 78}, /* 0x11 */
- 	{ 0x31,0x42, 79}, /* 0x12 */
-@@ -1045,7 +635,7 @@ static const SiS310_VCLKDataStruct SiS31
- 	{ 0x62,0x44, 94}, /* 0x16 */
- 	{ 0x2b,0x41,104}, /* 0x17 */
- 	{ 0x3a,0x23,105}, /* 0x18 */
--	{ 0x70,0x44,108}, /* 0x19 */
-+	{ 0x70,0x44,108}, /* 0x19 */  /* 1400x1050 LCD */
- 	{ 0x3c,0x23,109}, /* 0x1a */
- 	{ 0x5e,0x43,113}, /* 0x1b */
- 	{ 0xbc,0x44,116}, /* 0x1c */
-@@ -1078,12 +668,12 @@ static const SiS310_VCLKDataStruct SiS31
- 	{ 0xea,0x08,340}, /* 0x37 */
- 	{ 0xe8,0x07,376}, /* 0x38 */
- 	{ 0xde,0x06,389}, /* 0x39 */
--	{ 0x52,0x2a, 54}, /* 0x3a */
--	{ 0x52,0x6a, 27}, /* 0x3b */
--	{ 0x62,0x24, 70}, /* 0x3c */
--	{ 0x62,0x64, 70}, /* 0x3d */
--	{ 0xa8,0x4c, 30}, /* 0x3e */
--	{ 0x20,0x26, 33}, /* 0x3f */
-+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
-+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
-+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
-+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
-+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
-+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
- 	{ 0x31,0xc2, 39}, /* 0x40 */
- 	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
- 	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
-@@ -1096,7 +686,7 @@ static const SiS310_VCLKDataStruct SiS31
- 	{ 0xce,0x3c, 39}, /* 0x49 */
- 	{ 0x52,0x4a, 36}, /* 0x4a */  /* Chrontel */
- 	{ 0x34,0x61, 95}, /* 0x4b */
--	{ 0x78,0x27,108}, /* 0x4c - was 102 */  /* TW: Last entry in 650/301 BIOS */
-+	{ 0x78,0x27,108}, /* 0x4c - was 102 */
- 	{ 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
- 	{ 0x41,0x4e, 21}, /* 0x4e */
- 	{ 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
-@@ -1110,7 +700,8 @@ static const SiS310_VCLKDataStruct SiS31
- 	{ 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
- 	{ 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
- 	{ 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
--	{ 0x56,0x07,156}  /* 0x5a - added for 1400x1050-75 */
-+	{ 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
-+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
- };
- 
- typedef struct _SiS310_VBVCLKDataStruct
-@@ -1121,22 +712,22 @@ typedef struct _SiS310_VBVCLKDataStruct
- 
- static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
- {
--	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x579c */
--	{ 0x4e,0xe4, 28}, /* 0x1 */
--	{ 0x57,0xe4, 31}, /* 0x2 */
--	{ 0xc3,0xc8, 36}, /* 0x3 */
--	{ 0x42,0x47, 40}, /* 0x4 */
--	{ 0xfe,0xcd, 43}, /* 0x5 */
--	{ 0x5d,0xc4, 44}, /* 0x6 */
--	{ 0x52,0x47, 49}, /* 0x7 */
--	{ 0x53,0x47, 50}, /* 0x8 */
--	{ 0x74,0x67, 52}, /* 0x9 */
--	{ 0x6d,0x66, 56}, /* 0xa */
--	{ 0x35,0x62, 65}, /* 0xb */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
--	{ 0x46,0x44, 67}, /* 0xc */
--	{ 0xb1,0x46, 68}, /* 0xd */
--	{ 0xd3,0x4a, 72}, /* 0xe */
--	{ 0x29,0x61, 75}, /* 0xf */
-+	{ 0x1b,0xe1, 25}, /* 0x00 */
-+	{ 0x4e,0xe4, 28}, /* 0x01 */
-+	{ 0x57,0xe4, 31}, /* 0x02 */
-+	{ 0xc3,0xc8, 36}, /* 0x03 */
-+	{ 0x42,0x47, 40}, /* 0x04 */
-+	{ 0xfe,0xcd, 43}, /* 0x05 */
-+	{ 0x5d,0xc4, 44}, /* 0x06 */
-+	{ 0x52,0x47, 49}, /* 0x07 */
-+	{ 0x53,0x47, 50}, /* 0x08 */
-+	{ 0x74,0x67, 52}, /* 0x09 */
-+	{ 0x6d,0x66, 56}, /* 0x0a */
-+	{ 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
-+	{ 0x46,0x44, 67}, /* 0x0c */
-+	{ 0xb1,0x46, 68}, /* 0x0d */
-+	{ 0xd3,0x4a, 72}, /* 0x0e */
-+	{ 0x29,0x61, 75}, /* 0x0f */
- 	{ 0x6d,0x46, 75}, /* 0x10 */
- 	{ 0x41,0x43, 78}, /* 0x11 */
- 	{ 0x31,0x42, 79}, /* 0x12 */
-@@ -1146,7 +737,7 @@ static const SiS310_VBVCLKDataStruct SiS
- 	{ 0x62,0x44, 94}, /* 0x16 */
- 	{ 0x2b,0x22,104}, /* 0x17 */
- 	{ 0x49,0x24,105}, /* 0x18 */
--	{ 0xf8,0x2f,108}, /* 0x19 */
-+	{ 0xf8,0x2f,108}, /* 0x19 */  /* 1400x1050 LCD */
- 	{ 0x3c,0x23,109}, /* 0x1a */
- 	{ 0x5e,0x43,113}, /* 0x1b */
- 	{ 0xbc,0x44,116}, /* 0x1c */
-@@ -1179,19 +770,19 @@ static const SiS310_VBVCLKDataStruct SiS
- 	{ 0xea,0x08,340}, /* 0x37 */
- 	{ 0xe8,0x07,376}, /* 0x38 */
- 	{ 0xde,0x06,389}, /* 0x39 */
--	{ 0x52,0x2a, 54}, /* 0x3a */
--	{ 0x52,0x6a, 27}, /* 0x3b */
--	{ 0x62,0x24, 70}, /* 0x3c */
--	{ 0x62,0x64, 70}, /* 0x3d */
--	{ 0xa8,0x4c, 30}, /* 0x3e */
--	{ 0x20,0x26, 33}, /* 0x3f */
-+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
-+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
-+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
-+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
-+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
-+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
- 	{ 0x31,0xc2, 39}, /* 0x40 */
--	{ 0x2e,0x48, 25}, /* 0x41 */
--	{ 0x24,0x46, 25}, /* 0x42 */
--	{ 0x26,0x64, 28}, /* 0x43 */
--	{ 0x37,0x64, 40}, /* 0x44 */
--	{ 0xa1,0x42,108}, /* 0x45 */
--	{ 0x37,0x61,100}, /* 0x46 */
-+	{ 0x2e,0x48, 25}, /* 0x41 */  /* Replacement for LCD on 315 for index 0 */
-+	{ 0x24,0x46, 25}, /* 0x42 */  /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
-+	{ 0x26,0x64, 28}, /* 0x43 */  /* Replacement for LCD on 315 for index 1 */
-+	{ 0x37,0x64, 40}, /* 0x44 */  /* Replacement for LCD on 315 for index 4 */
-+	{ 0xa1,0x42,108}, /* 0x45 */  /* 1280x960 LCD */
-+	{ 0x37,0x61,100}, /* 0x46 */  /* 1280x960 LCD */
- 	{ 0x78,0x27,108}, /* 0x47 */
- 	{ 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
- 	{ 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
-@@ -1211,72 +802,17 @@ static const SiS310_VBVCLKDataStruct SiS
- 	{ 0xbf,0xc8, 35}, /* 0x57 */  /* 856x480-38i,60  */
- 	{ 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
- 	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  - UNUSED */
--	{ 0x56,0x07,156}  /* 0x5a */  /* 1400x1050-75 - UNUSED */
-+	{ 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 - UNUSED */
-+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
- };
- 
- static const UCHAR SiS310_ScreenOffset[] = 
- {
-         0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
--	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
-+	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
- 	0xff
--};      /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
--
--typedef struct _SiS310_StResInfoStruct
--{
--	USHORT HTotal;
--	USHORT VTotal;
--} SiS310_StResInfoStruct;
--
--static const SiS310_StResInfoStruct SiS310_StResInfo[]=
--{
--	{ 640,400},
--	{ 640,350},
--	{ 720,400},
--	{ 720,350},
--	{ 640,480}
--};
--
--typedef struct _SiS310_ModeResInfoStruct
--{
--	USHORT HTotal;
--	USHORT VTotal;
--	UCHAR  XChar;
--	UCHAR  YChar;
--} SiS310_ModeResInfoStruct;
--
--static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
--{
--	{  320, 200, 8, 8},   /* 0x00 */
--	{  320, 240, 8, 8},   /* 0x01 */
--	{  320, 400, 8, 8},   /* 0x02 */
--	{  400, 300, 8, 8},   /* 0x03 */
--	{  512, 384, 8, 8},   /* 0x04 */
--	{  640, 400, 8,16},   /* 0x05 */
--	{  640, 480, 8,16},   /* 0x06 */
--	{  800, 600, 8,16},   /* 0x07 */
--	{ 1024, 768, 8,16},   /* 0x08 */
--	{ 1280,1024, 8,16},   /* 0x09 */
--	{ 1600,1200, 8,16},   /* 0x0a */
--	{ 1920,1440, 8,16},   /* 0x0b */
--	{ 2048,1536, 8,16},   /* 0x0c */
--	{  720, 480, 8,16},   /* 0x0d */
--	{  720, 576, 8,16},   /* 0x0e */
--	{ 1280, 960, 8,16},   /* 0x0f */
--	{  800, 480, 8,16},   /* 0x10 */
--	{ 1024, 576, 8,16},   /* 0x11 */
--	{ 1280, 720, 8,16},   /* 0x12 */
--	{  856, 480, 8,16},   /* 0x13 - TW: New, not in any BIOS */
--	{ 1280, 768, 8,16},   /* 0x14 20; TW: New */
--	{ 1400,1050, 8,16},   /* 0x15 21; TW: New */
--	{ 1152, 864, 8,16},   /* 0x16 - TW: New, not in any BIOS */
--	{  848, 480, 8,16},   /* 0x17 - TW: New, not in any BIOS */
--	{ 1360, 768, 8,16}    /* 0x18 - TW: New, not in any BIOS */
- };
- 
--static const UCHAR SiS310_OutputSelect = 0x40;
--
--static const UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
--
- static const UCHAR SiS310_SR15[8][4]={
- 	{0x00,0x04,0x60,0x60},
- 	{0x0f,0x0f,0x0f,0x0f},
-@@ -1322,16 +858,6 @@ static const USHORT SiS310_VideoSenseDat
- static const USHORT SiS310_YCSenseData2    = 0x016b;
- #endif
- 
--static const UCHAR SiS310_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
--static const UCHAR SiS310_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
--static const UCHAR SiS310_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};  /* TW: palm*/
--static const UCHAR SiS310_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};  /* TW: paln*/
--static const UCHAR SiS310_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
--static const UCHAR SiS310_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
--static const UCHAR SiS310_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};  /* TW: palm 301b*/
--static const UCHAR SiS310_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};  /* TW: paln 301b*/
--static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
--
- typedef struct _SiS310_LCDDataStruct
- {
- 	USHORT RVBHCMAX;
-@@ -1353,25 +879,6 @@ static const SiS310_LCDDataStruct  SiS31
- 	{    1,   1,1344, 806,1344, 806}
- };
- 
--#if 0   /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
--static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] = 
--{
--	{   12,   5, 896, 512,1344, 806},
--	{   12,   5, 896, 510,1344, 806},
--	{   32,  15,1008, 505,1344, 806},
--	{   32,  15,1008, 514,1344, 806},
--	{   12,   5, 896, 500,1344, 806},
--	{   42,  25,1024, 625,1344, 806},
--	{    1,   1,1344, 806,1344, 806},
--	{   12,   5, 896, 500,1344, 806},
--	{   42,  25,1024, 625,1344, 806},
--	{    1,   1,1344, 806,1344, 806},
--	{   12,   5, 896, 500,1344, 806},
--	{   42,  25,1024, 625,1344, 806},
--	{    1,   1,1344, 806,1344, 806}
--};
--#endif
--
- static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
- {
- 	{   42,  25,1536, 419,1344, 806},
-@@ -1463,272 +970,14 @@ static const SiS310_LCDDataStruct  SiS31
- 	{    1,   1,1688,1066,1688,1066}
- };
- 
--static const SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
--{
--	{    9,   2, 800, 500,1800,1000},
--	{    9,   2, 800, 500,1800,1000},
--	{    4,   1, 900, 500,1800,1000},
--	{    4,   1, 900, 500,1800,1000},
--	{    9,   2, 800, 500,1800,1000},
--	{   30,  11,1056, 625,1800,1000},
--	{    5,   3,1350, 800,1800,1000},
--	{    1,   1,1576,1050,1576,1050},
--	{    1,   1,1800,1000,1800,1000}
--};
--
--static const SiS310_LCDDataStruct  SiS310_StLCD1400x1050Data[] = 
--{  /* TW: New from 1.11.6s */
--	{ 211,  100, 2100,  408, 1688, 1066 },
--	{ 211,   64, 1536,  358, 1688, 1066 },
--	{ 211,  100, 2100,  408, 1688, 1066 },
--	{ 211,   64, 1536,  358, 1688, 1066 },
--	{ 211,   48,  840,  488, 1688, 1066 },
--	{ 211,   72, 1008,  609, 1688, 1066 },
--	{ 211,  128, 1400,  776, 1688, 1066 },
--	{ 211,  205, 1680, 1041, 1688, 1066 },
--	{   1,    1, 1688, 1066, 1688, 1066 }
--};
--
--static const SiS310_LCDDataStruct  SiS310_ExtLCD1400x1050Data[] = 
--{  /* TW: New from 1.11.6s */
--	{ 211,  100, 2100,  408, 1688, 1066 },
--	{ 211,   64, 1536,  358, 1688, 1066 },
--	{ 211,  100, 2100,  408, 1688, 1066 },
--	{ 211,   64, 1536,  358, 1688, 1066 },
--	{ 211,   48,  840,  488, 1688, 1066 },
--	{ 211,   72, 1008,  609, 1688, 1066 },
--	{ 211,  128, 1400,  776, 1688, 1066 },
--	{ 211,  205, 1680, 1041, 1688, 1066 },
--	{   1,    1, 1688, 1066, 1688, 1066 }
--};
--
--static const SiS310_LCDDataStruct  SiS310_NoScaleData1400x1050[] = 
--{  /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 },
--	{ 1, 1, 1688, 1066, 1688, 1066 }
--};
--
--static const SiS310_LCDDataStruct  SiS310_StLCD1600x1200Data[] = 
--{  /* TODO */
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS310_LCDDataStruct  SiS310_ExtLCD1600x1200Data[] = 
--{  /* TODO */
--	{    0,   0,   0,   0,   0,   0}
--};
--
--static const SiS310_LCDDataStruct  SiS310_NoScaleData1600x1200[] = 
--{  /* TODO */
--	{    0,   0,   0,   0,   0,   0}
--};
--
--typedef struct _SiS310_TVDataStruct
--{
--	USHORT RVBHCMAX;
--	USHORT RVBHCFACT;
--	USHORT VGAHT;
--	USHORT VGAVT;
--	USHORT TVHDE;
--	USHORT TVVDE;
--	USHORT RVBHRS;
--	UCHAR FlickerMode;
--	USHORT HALFRVBHRS;
--	UCHAR RY1COE;
--	UCHAR RY2COE;
--	UCHAR RY3COE;
--	UCHAR RY4COE;
--} SiS310_TVDataStruct;
--
--static const SiS310_TVDataStruct  SiS310_StPALData[]=
--{
-- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
-- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
--};
--
--static const SiS310_TVDataStruct  SiS310_ExtPALData[] =   
--{
-- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
-- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
-- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480 */
-- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600 */
-- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x480/576 */
-- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
--};
--
--static const SiS310_TVDataStruct  SiS310_StNTSCData[]=
--{
-- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
-- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
-- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
--};
--
--static const SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
--{
-- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
-- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
-- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},  /* 640x480 */
-- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},  /* 800x600  */
-- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},  /* 720x480/576 */
-- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08}   /* 1024x768 */
--};
--
--#if 0
--static const SiS310_TVDataStruct  SiS310_St1HiTVData[]=
--{
--  
--};
--#endif
--
--static const SiS310_TVDataStruct  SiS310_St2HiTVData[]=
--{
-- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
-- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
--};
--
--static const SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
--{
-- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
-- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
-- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
-- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
-- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
--};
--
--static const UCHAR SiS310_NTSCTiming[] = { 
--	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
--	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
--	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
--	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
--	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
--	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
--	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
--};
--
--static const UCHAR SiS310_PALTiming[] = {  
--	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
--	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
--	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
--	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
--	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
--	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
--};
--
--static const UCHAR SiS310_HiTVExtTiming[] = {  
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
--	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
--	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
--	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
--};
--
--static const UCHAR SiS310_HiTVSt1Timing[] = {  
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
--	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
--	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
--	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
--};
--
--static const UCHAR SiS310_HiTVSt2Timing[] = {  
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
--	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
--	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
--	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
--	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
--};
--
--static const UCHAR SiS310_HiTVTextTiming[] = {  
--        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
--	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
--	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
--	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
--	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
--	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
--        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
--	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
--};
--
--static const UCHAR SiS310_HiTVGroup3Data[] = {  
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
--	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
--	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
--static const UCHAR SiS310_HiTVGroup3Simu[] = {  
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
--	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
--	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
--static const UCHAR SiS310_HiTVGroup3Text[] = {  
--        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
--	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
--	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
--	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
--	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
--	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
--	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
--	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
--};
--
- typedef struct _SiS310_PanelDelayTblStruct
- {
-  	UCHAR timer[2];
- } SiS310_PanelDelayTblStruct;
- 
--static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  
-+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
- {
--        {{0x10,0x40}},		/* TW: from 650/301LVx 1.10.6s BIOS */
-+        {{0x10,0x40}},
- 	{{0x10,0x40}},
- 	{{0x10,0x40}},
- 	{{0x10,0x40}},
-@@ -1744,24 +993,6 @@ static const SiS310_PanelDelayTblStruct 
- 	{{0x10,0x40}},
- 	{{0x10,0x40}},
- 	{{0x10,0x40}}
--#if 0
--	{{0x28,0xc8}},		/* TW: from 650/301LV BIOS */
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}},
--	{{0x28,0xc8}}
--#endif
- };
- 
- static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
-@@ -1792,363 +1023,7 @@ typedef struct _SiS310_LVDSDataStruct
- 	USHORT LCDVT;
- } SiS310_LVDSDataStruct;
- 
--static const SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
--{
--	{ 848, 433, 400, 525},
--	{ 848, 389, 400, 525},
--	{ 848, 433, 400, 525},
--	{ 848, 389, 400, 525},
--	{ 848, 518, 400, 525},
--	{1056, 628, 400, 525},
--	{ 400, 525, 400, 525},
--	{ 800, 449,1000, 644},
--	{ 800, 525,1000, 635}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]= 
--{
--	{ 848, 433,1060, 629},
--	{ 848, 389,1060, 629},
--	{ 848, 433,1060, 629},
--	{ 848, 389,1060, 629},
--	{ 848, 518,1060, 629},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{ 800, 449,1000, 644},
--	{ 800, 525,1000, 635}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=  
--{
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{ 800, 449,1000, 644},
--	{ 800, 525,1000, 635}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=  
--{
--	{ 840, 438,1344, 806},
--	{ 840, 409,1344, 806},
--	{ 840, 438,1344, 806},
--	{ 840, 409,1344, 806},
--	{ 840, 518,1344, 806},   /* 640x480 */
--	{1050, 638,1344, 806},   /* 800x600 */
--	{1344, 806,1344, 806},   /* 1024x768 */
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]= 
--{
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=  
--{	
--	{1048, 442,1688,1066},
--	{1048, 392,1688,1066},
--	{1048, 442,1688,1066},
--	{1048, 392,1688,1066},
--	{1048, 522,1688,1066},
--	{1208, 642,1688,1066},
--	{1432, 810,1688,1066},
--	{1688,1066,1688,1066}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=  
--{	
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066},
--	{1688,1066,1688,1066}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=  
--{
--        { 928, 416, 1688,1066},
--	{ 928, 366, 1688,1066},
--	{ 928, 416, 1688,1066},
--	{ 928, 366, 1688,1066},
--	{ 928, 496, 1688,1066},
--	{1088, 616, 1688,1066},
--	{1312, 784, 1688,1066},
--	{1568,1040, 1688,1066},
--	{1688,1066, 1688,1066}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]= 
--{
--        {1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--	{1688,1066, 1688,1066},
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_1[]=  
--{
--        {1088, 450, 2048,1250},
--	{1088, 400, 2048,1250},
--	{1088, 450, 2048,1250},
--	{1088, 400, 2048,1250},
--	{1088, 530, 2048,1250},
--	{1248, 650, 2048,1250},
--	{1472, 818, 2048,1250},
--	{1728,1066, 2048,1250},
--	{1848,1066, 2048,1250},
--	{2048,1250, 2048,1250}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_2[]= 
--{
--        {2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250},
--	{2048,1250, 2048,1250}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_1[]= 
--{	
--	{ 768, 438, 1408, 806},
--	{ 768, 388, 1408, 806},
--	{ 768, 438, 1408, 806},
--	{ 768, 388, 1408, 806},
--	{ 768, 518, 1408, 806},
--	{ 928, 638, 1408, 806},
--	{1152, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_2[]=  
--{	
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806},
--	{1408, 806, 1408, 806}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
--{
--	{ 840, 604, 1344, 800},
--	{ 840, 560, 1344, 800},
--	{ 840, 604, 1344, 800},
--	{ 840, 560, 1344, 800},
--	{ 840, 689, 1344, 800},
--	{1050, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{ 800, 449, 1280, 801},
--	{ 800, 525, 1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
--{
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{1344, 800, 1344, 800},
--	{ 800, 449, 1280, 801},
--	{ 800, 525, 1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
--{
--	{ 840, 438, 1344, 806},
--	{ 840, 409, 1344, 806},
--	{ 840, 438, 1344, 806},
--	{ 840, 409, 1344, 806},
--	{ 840, 518, 1344, 806},
--	{1050, 638, 1344, 806},
--	{1344, 806, 1344, 806},
--	{ 800, 449, 1280, 801},
--	{ 800, 525, 1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
--{
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{1344, 806, 1344, 806},
--	{ 800, 449, 1280, 801},
--	{ 800, 525, 1280, 813}
--};
--
--/* TW: Pass 1:1 data */
--static const SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=  
--{
--        { 800, 449,  800, 449},
--	{ 800, 449,  800, 449},
--	{ 900, 449,  900, 449},
--	{ 900, 449,  900, 449},
--	{ 800, 525,  800, 525},  /*  640x480   */
--	{1056, 628, 1056, 628},  /*  800x600   */
--	{1344, 806, 1344, 806},  /* 1024x768   */
--	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
-- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
--	/* No other panels ! */
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=  
--{
--	{ 800, 449, 800, 449},
--	{ 800, 449, 800, 449},
--	{ 800, 449, 800, 449},
--	{ 800, 449, 800, 449},
--	{ 800, 525, 800, 525},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628},
--	{1056, 628,1056, 628}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   
--{
--	{ 840, 438,1344, 806},
--	{ 840, 409,1344, 806},
--	{ 840, 438,1344, 806},
--	{ 840, 409,1344, 806},
--	{ 840, 518,1344, 806},
--	{1050, 638,1344, 806},
--	{1344, 806,1344, 806},
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=  
--{
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--/* LCDA */
--
--static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_1[]=   
--{	/* TW: Might be temporary (invalid) data */
--        { 928, 416, 1688,1066},
--	{ 928, 366, 1688,1066},
--	{1008, 416, 1688,1066},
--	{1008, 366, 1688,1066},
--	{1200, 530, 1688,1066},
--	{1088, 616, 1688,1066},
--	{1312, 784, 1688,1066},
--	{1568,1040, 1688,1066},
--	{1688,1066, 1688,1066}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_2[]=   
--{	/* TW: Temporary data. Not valid */
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_1[]=  
--{	/* TW: Temporary data. Not valid */
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{1344, 806,1344, 806},
--	{ 800, 449,1280, 801},
--	{ 800, 525,1280, 813}
--};
--
--static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_2[]=  
--{	/* TW: Temporary data. Not valid */
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0},
--	{0, 0, 0, 0}
--};
--
--/* Chrontel TV */
--
--static const SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   
--{
--	{ 840, 600, 840, 600},
--	{ 840, 600, 840, 600},
--	{ 840, 600, 840, 600},
--	{ 840, 600, 840, 600},
--	{ 784, 600, 784, 600},
--	{1064, 750,1064, 750},
--        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
--};
--
--static const SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   
--{
--	{ 840, 525, 840, 525},
--	{ 840, 525, 840, 525},
--	{ 840, 525, 840, 525},
--	{ 840, 525, 840, 525},
--	{ 784, 525, 784, 525},
--	{1040, 700,1040, 700},
--        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
--};
--
--static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   
-+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
- {
- 	{1008, 625,1008, 625},
- 	{1008, 625,1008, 625},
-@@ -2156,7 +1031,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{ 840, 625, 840, 625},
- 	{ 960, 750, 960, 750},
--	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
-+	{1400,1000,1400,1000}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
-@@ -2167,7 +1042,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{ 840, 625, 840, 625},
- 	{ 944, 625, 944, 625},
--        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
-+        {1400, 875,1400, 875}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
-@@ -2178,7 +1053,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{ 840, 600, 840, 600},
- 	{ 784, 600, 784, 600},
- 	{1064, 750,1064, 750},
--        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
-+        {1160, 945,1160, 945}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
-@@ -2189,7 +1064,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{ 840, 525, 840, 525},
- 	{ 784, 525, 784, 525},
- 	{1040, 700,1040, 700},
--        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
-+        {1160, 840,1160, 840}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
-@@ -2200,7 +1075,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{ 840, 625, 840, 625},
- 	{ 960, 750, 960, 750},
--	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
-+	{1400,1000,1400,1000}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
-@@ -2211,7 +1086,7 @@ static const SiS310_LVDSDataStruct  SiS3
- 	{1008, 625,1008, 625},
- 	{ 840, 625, 840, 625},
- 	{ 944, 625, 944, 625},
--        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
-+        {1400, 875,1400, 875}
- };
- 
- static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
-@@ -2231,7 +1106,7 @@ typedef struct _SiS310_LVDSDesStruct
- 	USHORT LCDVDES;
- } SiS310_LVDSDesStruct;
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  
-+static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
- {
- 	{ 0, 0},
- 	{ 0, 0},
-@@ -2244,7 +1119,7 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{ 0, 0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   
-+static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
- {
- 	{ 0, 0},
- 	{ 0, 0},
-@@ -2257,7 +1132,7 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{ 0, 0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  
-+static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
- {
- 	{ 0, 0},
- 	{ 0, 0},
-@@ -2382,33 +1257,31 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{ 0, 0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]= 
--{
--	{1343, 798},
--	{1343, 794},
--	{1343, 798},
--	{1343, 794},
--	{1343,   0},
--	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
--};
--
--static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  
-+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
- {
--	{1343, 798},
--	{1343, 794},
--	{1343, 798},
--	{1343, 794},
--	{1343,   0},
--	{1343,   0},
--	{ 0, 805},
--	{ 0, 794},
--	{ 0,   0}
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 8, 524},
-+	{ 0, 524}
-+};
-+
-+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
-+{
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 0, 524},
-+	{ 8, 524},
-+	{ 0, 524}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]= 
-+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
- {
- 	{1343, 798},
- 	{1343, 794},
-@@ -2604,7 +1477,7 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{   0,   0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  
-+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
- {
- 	{1152, 622},
- 	{1152, 597},
-@@ -2617,7 +1490,7 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{ 0,   0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]= 
-+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
- {
- 	{1152, 622},
- 	{1152, 597},
-@@ -2669,184 +1542,6 @@ static const SiS310_LVDSDesStruct  SiS31
- 	{ 0,   0}
- };
- 
--static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_1[]= 
--{
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 8,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0, 806},
--	{ 0, 0 }
--};
--
--static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_2[] = 
--{
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=  
--{  /* 1024x768 - Checked (1.10.6s) */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=  
--{  /* 1024x768 - Checked (1.10.6s) */
--	{ 1184, 622 },
--	{ 1184, 597 },
--	{ 1184, 622 },
--	{ 1184, 597 },
--	{ 1152, 622 },
--	{ 1232, 722 },
--	{    0, 0   },
--	{    0, 794 },
--	{    0, 0   }
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=  
--{  /* 1280x1024 - Checked (1.10.6s) */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=  
--{  /* 1280x1024 - Checked (1.10.6s) */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=  
--{  /* 1400x1050 - Checked (1.10.6s) */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=  
--{  /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
--	{ 808 , 740},
--	{ 0   , 715},
--	{ 632 , 740},
--	{ 632 , 715},
--	{ 1307, 780},
--	{ 1387,1157},
--	{ 1499, 924},
--	{ 1627,1052},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= 
--{  /* 1600x1200 - Checked (1.10.6s) */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= 
--{  /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0},
--	{ 0 , 0}
--};
--
--static const SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
--{
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0}
--};
--
--static const SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
--{
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0}
--};
--
--static const SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
--{
--	{256,   0},
--	{256,   0},
--	{256,   0},
--	{256,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0}
--};
--
--static const SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
--{
--	{256,   0},
--	{256,   0},
--	{256,   0},
--	{256,   0},
--	{ 0,   0},
--	{ 0,   0},
--	{ 0,   0}
--};
--
- typedef struct _SiS310_Part2PortTblStruct
- {
-  	UCHAR CR[12];
-@@ -2866,16 +1561,15 @@ static const SiS310_Part2PortTblStruct S
- };
- 
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
--{	/* TW: Temporary data, invalid */
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-+{	/* TW: BIOS data invalid, last row taken from _3 */
-+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
-+ {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
-+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
-+ {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
-+ {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
-+ {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
-+ {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
-+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
- };
- 
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
-@@ -2912,7 +1606,8 @@ static const SiS310_Part2PortTblStruct S
-  {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
-  {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
-  {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
-- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},  /* old  */
-+/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24        new? */
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
- };
-@@ -2959,6 +1654,7 @@ static const SiS310_Part2PortTblStruct S
- 
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
- {	/* TW: Data from 650/301LVx 1.10.6s */
-+#if 0
-  {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-  {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-  {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-@@ -2968,56 +1664,55 @@ static const SiS310_Part2PortTblStruct S
-  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
-  {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
--#if 0	/* TW: Data from 650/301LV */
-- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
-- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
-- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
--#endif
-+#endif	/* Data from my 301LV */
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},   /* @@@@@ TEST */
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
-+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
- };
- 
- /*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
--{	/* TW: Temporary data, invalid */
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
-+{
-+ {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
-+ {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
-+ {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
-+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
-+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
-+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
-+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
-+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
- };
- 
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
- {	
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
- };
- 
- static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
- {	/* TW: Temporary data, invalid */
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
--  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
- };
- 
- typedef struct _SiS310_LCDACRT1DataStruct
-@@ -3054,7 +1749,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
--{  /* TW: Checked (1.10.6s) */
-+{
-  {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-    0x00}},
-@@ -3079,7 +1774,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
--{  /* Checked (1.10.6s) */
-+{
-  {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
-    0x00}},
-@@ -3107,7 +1802,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
--{    /* Checked (1.10.6s) */
-+{
-  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-@@ -3200,7 +1895,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
--{  /* TW: Checked (1.10.6s) */
-+{
-  {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-    0x00}},
-@@ -3225,7 +1920,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
--{   /* Checked (1.10.6s) */
-+{
-  {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
-    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
-    0x00}},
-@@ -3250,7 +1945,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
--{   /* Checked (1.10.6s) */
-+{
-   {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-     0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-     0x00}},
-@@ -3343,7 +2038,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
--{   /* Checked (1.10.6s) */
-+{
-  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-    0x00}},
-@@ -3368,7 +2063,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
--{   /* Checked (1.10.6s) */
-+{
-  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
-    0x00}},
-@@ -3393,7 +2088,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
--{    /* Checked (1.10.6s) */
-+{
-  {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
-    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
-    0x00}},
-@@ -3486,7 +2181,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
--{   /* Checked (1.10.6s) */
-+{
-  {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-    0x00 }},
-@@ -3511,7 +2206,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
--{   /* Checked (1.10.6s) */
-+{
-  {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-    0x00 }},
-@@ -3536,7 +2231,7 @@ static const SiS310_LCDACRT1DataStruct  
- };
- 
- static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
--{  /* Checked (1.10.6s) */
-+{
-  {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
-    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
-    0x00}},
-@@ -3605,32 +2300,7 @@ typedef struct _SiS310_LVDSCRT1DataStruc
-  	UCHAR CR[15];
- } SiS310_LVDSCRT1DataStruct;
- 
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
--{
-- {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
--   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
--   0x00 }},
-- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
--   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
--   0x00 }},
-- {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
--   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--   0x00 }},
-- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
--   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
--   0x00 }},
-- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
--   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
--   0x00 }},
-- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
--   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
--   0x01 }},
-- {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
--   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
--   0x00 }}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   
-+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
- {
-  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
-    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-@@ -3924,63 +2594,7 @@ static const SiS310_LVDSCRT1DataStruct  
-    0x01}}
- };
- 
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =  
--{
-- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
--   0x00}},
-- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
--   0x00}},
-- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
--   0x00}},
-- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
--   0x00}},
-- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
--   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
--   0x00}},
-- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
--   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
--   0x01}},
-- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--   0x01}},
-- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
--   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
--   0x01}},
-- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
--   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] = 
--{
-- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
--   0x00}},
-- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
--   0x00}},
-- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
--   0x00}},
-- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
--   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
--   0x00}},
-- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
--   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
--   0x00}},
-- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
--   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
--   0x01}},
-- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
--   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =  
-+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
- {
-   {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-     0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
-@@ -4220,332 +2834,8 @@ static const SiS310_LVDSCRT1DataStruct  
- #endif   
- };
- 
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1[] =  
--{	
-- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
--   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
--   0x00}},
-- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
--   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
--   0x00}},
-- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
--   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
--   0x00}},
-- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
--   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
--   0x00}},
-- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
--   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
--   0x00}},
-- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
--   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
--   0x01}},
-- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
--   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
--   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
--   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1_H[] = 
--{
-- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
--   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
--   0x00}},
-- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
--   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
--   0x00}},
-- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
--   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
--   0x00}},
-- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
--   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
--   0x00}},
-- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
--   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
--   0x00}},
-- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
--   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
--   0x01}},
-- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
--   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
--   0x01}},
-- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
--   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
--   0x01}},
-- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
--   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2[] = 
-+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
- {
-- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
--   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
--   0x00}},
-- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
--   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
--   0x00}},
-- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
--   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
--   0x00}},
-- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
--   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
--   0x00}},
-- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
--   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
--   0x01}},
-- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
--   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
--   0x01}},
-- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2_H[] =
--{
-- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
--   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
--   0x00}},
-- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
--   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
--   0x00}},
-- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
--   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
--   0x00}},
-- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
--   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
--   0x00}},
-- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
--   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
--   0x01}},
-- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
--   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
--   0x01}},
-- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
--   0x01}},
-- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
--   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
--   0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
--{
--        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
--	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
--	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
--	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
--	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
--	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
--	  0x00}},
--        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
--	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
--	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
--{
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--          0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
--	  0x00}},
--        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
--{
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
--{
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
--{
--        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
--	  0x00}},
--        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
--	  0x00}},
--        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
--{
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
--	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
--	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
--	  0x00}},
--        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
--	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
--	  0x00}},
--        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
--	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
--{
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
--	  0x00}},
--        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
--	  0x01}},
--        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
--{
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
--	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
--	  0x00}},
--        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
--	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
--	  0x01}},
--        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
--	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
--	  0x01}}
--};
--
--static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =  
--{    
-  {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
-    0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
-    0x00}},
-@@ -4701,7 +2991,7 @@ static const SiS310_LVDSCRT1DataStruct  
- 	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
- 	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
- 	  0x01 }},
--	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
-+	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
- 	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
- 	  0x01}}
- };
-@@ -4726,7 +3016,7 @@ static const SiS310_LVDSCRT1DataStruct  
- 	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
- 	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
- 	  0x01 }},
--	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
-+	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
- 	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
- 	  0x01 }}
- };
-@@ -4751,7 +3041,7 @@ static const SiS310_LVDSCRT1DataStruct  
- 	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
- 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
- 	  0x01 }},
--	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
-+	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
- 	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
- 	  0x01}}
- };
-@@ -4776,7 +3066,7 @@ static const SiS310_LVDSCRT1DataStruct  
- 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
- 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
- 	  0x01 }},
--	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
-+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
- 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
- 	  0x01 }}
- };
-@@ -4801,12 +3091,11 @@ static const SiS310_LVDSCRT1DataStruct  
- 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
- 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
- 	  0x01 }},
--	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
-+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
- 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
- 	  0x01 }}
- };
- 
--/* TW: Data for Chrontel 7019  */
- typedef struct _SiS310_CHTVRegDataStruct
- {
-  	UCHAR Reg[16];
---- linux-2.6.0-test1/drivers/video/sis/init301.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/drivers/video/sis/init301.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,27 +1,11 @@
- /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
- /*
-- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
-- * (Universal module for Linux kernel framebuffer, XFree86 4.x)
-+ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330/660
-+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
-  *
-  * Assembler-To-C translation
-  * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
-- * Minor parts Copyright SiS, Inc.
-- *
-- * Based on BIOS
-- *     1.10.07, 1.10a for 650/CH7019
-- *     1.11.21a for 740/CH7019
-- *     1.11.05 for 650/LVDS (w/o Chrontel)
-- *     1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
-- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
-- *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
-- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
-- *     1.09b for 315/301(B)
-- *     1.16.51 for 300+301LV (ECS A907)
-- *     1.01.03 for 330 (Xabre 400)
-- *
-- * Known bugs:
-- *   1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
-- *       therefore, we always do the scaling ourselves for now.
-+ * Formerly based on non-functional code-fragements by SiS, Inc.
-  *
-  * Permission to use, copy, modify, distribute, and sell this software and its
-  * documentation for any purpose is hereby granted without fee, provided that
-@@ -73,8 +57,8 @@
- #define SiS_I2CDELAYSHORT  150
- 
- BOOLEAN
--SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
--                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-+SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-+                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-    USHORT ModeIdIndex;
-    USHORT RefreshRateTableIndex;
-@@ -85,9 +69,9 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
-       SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
-    } else {
-       ModeIdIndex = 0;
--   }      
-+   }
- 
--   /* TW: Used for shifting CR33 */
-+   /* Used for shifting CR33 */
-    SiS_Pr->SiS_SelectCRT2Rate = 4;
- 
-    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
-@@ -110,8 +94,6 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
-       return(TRUE);
-    }
- 
--   if(SiS_Pr->UseCustomMode) return(FALSE);
--   
-    SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                    HwDeviceExtension);
- 
-@@ -153,9 +135,9 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
-       	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
- 	                 ModeNo,ModeIdIndex);
- 
--	   /* TW: For 301BDH (Panel link initialization): */
-+	   /* For 301BDH (Panel link initialization): */
- 	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
--	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {	 
-+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- 		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
- 		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- 		       SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-@@ -176,10 +158,10 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
- 	                      RefreshRateTableIndex,HwDeviceExtension);
- 	   }
- 	}
--        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
--     	   SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
--	 	           RefreshRateTableIndex,HwDeviceExtension);
--	}
-+
-+        SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-+	                RefreshRateTableIndex,HwDeviceExtension);
-+
- 	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-@@ -199,74 +181,64 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
-    }
- 
- #ifdef SIS300
--   if ( (HwDeviceExtension->jChipType == SIS_540) ||
--        (HwDeviceExtension->jChipType == SIS_630) ||
--        (HwDeviceExtension->jChipType == SIS_730) ||
--        (HwDeviceExtension->jChipType == SIS_300) )
--    {
--	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
--	   if(SiS_Pr->SiS_UseOEM) {
--	      if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
--	         if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
--	            SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
--	         }
--	      } else {
--       	         SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
--	      }
--	   }
--	}
--    }
--#endif
--
--#ifdef SIS315H
--   if ( (HwDeviceExtension->jChipType == SIS_315H)  ||
--        (HwDeviceExtension->jChipType == SIS_315)   ||
--	(HwDeviceExtension->jChipType == SIS_315PRO)||
--        (HwDeviceExtension->jChipType == SIS_550)   ||
--        (HwDeviceExtension->jChipType == SIS_740)   ||
--        (HwDeviceExtension->jChipType == SIS_650)   ||
--	(HwDeviceExtension->jChipType == SIS_330) )
--   {
--        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
--	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
--#if 0      /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
--	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
--#endif
--           if(SiS_Pr->SiS_UseOEM) {
--              SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
--           }
--           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
--        }
--   }
--#endif
--
-    if(HwDeviceExtension->jChipType < SIS_315H) {
-+      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-+	 if(SiS_Pr->SiS_UseOEM) {
-+	    if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
-+	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-+	          SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-+	       			    RefreshRateTableIndex);
-+	       }
-+	    } else {
-+       	       SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-+	       			 RefreshRateTableIndex);
-+	    }
-+	 }
-+	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-+            if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-+	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+	       SetOEMLCDData2(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,
-+	                      ModeIdIndex,RefreshRateTableIndex);
-+	    }
-+            if(HwDeviceExtension->jChipType == SIS_730) {
-+               SiS_DisplayOn(SiS_Pr);
-+	    }
-+         }
-+      }
-       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-           if(HwDeviceExtension->jChipType != SIS_730) {
-              SiS_DisplayOn(SiS_Pr);
- 	  }
-       }
-    }
-+#endif
- 
--   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--         if(HwDeviceExtension->jChipType == SIS_730) {
--            SiS_DisplayOn(SiS_Pr);
--	 }
-+#ifdef SIS315H
-+   if(HwDeviceExtension->jChipType >= SIS_315H) {
-+      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-+	 SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
-+         if(SiS_Pr->SiS_UseOEM) {
-+            SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-+         }
-+         SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
-       }
-+   }
-+#endif
-+
-+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-       SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
-    }
- 
-    SiS_DisplayOn(SiS_Pr);
- 
-    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
--	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--	     /* TW: Disable LCD panel when using TV */
--	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
--	} else {
--	     /* TW: Disable TV when using LCD */
--	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
--	}
-+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+	 /* Disable LCD panel when using TV */
-+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
-+      } else {
-+	 /* Disable TV when using LCD */
-+	 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
-+      }
-    }
- 
-    if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-@@ -283,7 +255,7 @@ SiS_LowModeStuff(SiS_Private *SiS_Pr, US
-     USHORT temp,temp1,temp2;
- 
-     if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
--         return(1);
-+       return(1);
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
-     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
-     temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
-@@ -304,7 +276,7 @@ SiS_LowModeStuff(SiS_Private *SiS_Pr, US
-     }
- }
- 
--/* TW: Set Part1 registers */
-+/* Set Part1 registers */
- void
- SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-@@ -313,25 +285,29 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
-   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
-   USHORT  pushbx=0, CRT1Index=0;
- #ifdef SIS315H
--  USHORT  pushcx=0, tempbl=0;
-+  USHORT  tempbl=0;
- #endif
-   USHORT  modeflag, resinfo=0;
- 
--  if(ModeNo<=0x13) {
--	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+  if(ModeNo <= 0x13) {
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   } else {
-+     if(SiS_Pr->UseCustomMode) {
-+	modeflag = SiS_Pr->CModeFlag;
-+     } else {
-     	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- 	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+     }
-   }
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
--
--	   SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
--                           RefreshRateTableIndex,HwDeviceExtension);
- #ifdef SIS315H
--	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
--     	                      HwDeviceExtension,RefreshRateTableIndex);
-+     SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-+                     RefreshRateTableIndex,HwDeviceExtension);
-+
-+     SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-+                        HwDeviceExtension,RefreshRateTableIndex);
- #endif
-   } else {
- 
-@@ -367,13 +343,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- #ifdef SIS300   /* ------------- 300 series --------------*/
- 
-     		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
--    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
-+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
- 
-     		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
--    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
-+    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
- 
-     		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
--    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
-+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
- 
-     		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
-     		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
-@@ -382,108 +358,129 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
-     		tempcx += tempbx;
- 
-     		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
--			        /* CRT1Index &= 0x3F; - Not any longer */
--        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
--        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
--        			tempbx = (tempbx - 1) << 3;
--        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
--        			tempcx &= 0x1F;
--        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
--        			temp = (temp & 0x04) << (6-2);
--        			tempcx = (tempcx | temp);
--				tempcx--;
--				tempcx <<= 3;
--      			}
--
--    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
--        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
--      					tempbx = 1040;
--      					tempcx = 1042;
--      				}
--    			}
-+
-+		   if(SiS_Pr->UseCustomMode) {
-+		      tempbx = SiS_Pr->CHSyncStart + 12;
-+		      tempcx = SiS_Pr->CHSyncEnd + 12;
-+		   }
-+
-+      		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-+		      unsigned char cr4, cr14, cr5, cr15;
-+		      if(SiS_Pr->UseCustomMode) {
-+		         cr4  = SiS_Pr->CCRT1CRTC[4];
-+			 cr14 = SiS_Pr->CCRT1CRTC[14];
-+			 cr5  = SiS_Pr->CCRT1CRTC[5];
-+			 cr15 = SiS_Pr->CCRT1CRTC[15];
-+		      } else {
-+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-+		      }
-+        	      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
-+        	      tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
-+      		   }
-+
-+    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
-+        	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-+      			 tempbx = 1040;
-+      			 tempcx = 1042;
-+      		      }
-+    		   }
- 	        }
- 
-     		temp = tempbx & 0x00FF;
--    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
-+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
- #endif /* SIS300 */
- 
-  	} else {
- 
--#ifdef SIS315H  /* ----------------- 310/325/330 series ------------- */
-+#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
- 
- 	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
--		pushcx = tempcx;
- 		if(modeflag & HalfDCLK) {
--#ifndef NEWCH701x		
--		    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
--#endif		    
-+		    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- 		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
- 			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
- 			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- 			      tempcx = SiS_Pr->SiS_HT - tempax;
- 			  }
--#ifndef NEWCH701x					  
- 		    } else {
- 			  tempcx >>= 1;
- 		    }
--#endif		    
- 		}
- 		tempcx--;
- 
- 		temp = tempcx & 0xff;
--		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
-+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
- 
- 		temp = ((tempcx & 0xff00) >> 8) << 4;
--		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
-+		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
- 
--		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
-+		tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HDEE 0x0A,0x0C */
- 		tempbx = SiS_Pr->SiS_VGAHDE;
- 		tempcx -= tempbx;
- 		tempcx >>= 2;
- 		if(modeflag & HalfDCLK) {
--		    tempbx >>= 1;
--		    tempcx >>= 1;
-+		   tempbx >>= 1;
-+		   tempcx >>= 1;
- 		}
- 		tempbx += 16;
- 
- 		temp = tempbx & 0xff;
--		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
-+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
- 
- 		pushbx = tempbx;
- 		tempcx >>= 1;
- 		tempbx += tempcx;
- 		tempcx += tempbx;
- 
--		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
-+		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+
-+		   if(SiS_Pr->UseCustomMode) {
-+		      tempbx = SiS_Pr->CHSyncStart + 16;
-+		      tempcx = SiS_Pr->CHSyncEnd + 16;
-+		      tempax = SiS_Pr->SiS_VGAHT;
-+		      if(modeflag & HalfDCLK) tempax >>= 1;
-+		      tempax--;
-+		      if(tempcx > tempax)  tempcx = tempax;
-+		   }
-+
-              	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
--                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
--                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
--                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
--                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
--               		tempcx &= 0x1F;
--                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
--                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
--                	tempcx = (tempcx | temp);	  	  	/* (VGAHRE-3)*8 */
--			tempcx -= 3;
--			tempcx <<= 3;
--			tempcx &= 0x00FF;
--			tempcx |= (tempbx & 0xFF00);
--                	tempbx += 16;
--                	tempcx += 16;
--			tempax = SiS_Pr->SiS_VGAHT;
--			if(modeflag & HalfDCLK)  tempax >>= 1;
--			tempax--;
--			if(tempcx > tempax)  tempcx = tempax;
-+		      unsigned char cr4, cr14, cr5, cr15;
-+		      if(SiS_Pr->UseCustomMode) {
-+		         cr4  = SiS_Pr->CCRT1CRTC[4];
-+			 cr14 = SiS_Pr->CCRT1CRTC[14];
-+			 cr5  = SiS_Pr->CCRT1CRTC[5];
-+			 cr15 = SiS_Pr->CCRT1CRTC[15];
-+		      } else {
-+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-+		      }
-+                      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		/* (VGAHRS-3)*8 */
-+                      tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; 	/* (VGAHRE-3)*8 */
-+		      tempcx &= 0x00FF;
-+		      tempcx |= (tempbx & 0xFF00);
-+                      tempbx += 16;
-+                      tempcx += 16;
-+		      tempax = SiS_Pr->SiS_VGAHT;
-+		      if(modeflag & HalfDCLK) tempax >>= 1;
-+		      tempax--;
-+		      if(tempcx > tempax)  tempcx = tempax;
-              	   }
--         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
--             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
--      		 	 tempbx = 1040;
--      		 	 tempcx = 1042;
--      	     	      }
-+         	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+		      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+		         if(resinfo == SIS_RI_1024x768) {
-+      		 	    tempbx = 1040;
-+      		 	    tempcx = 1042;
-+      	     	         }
-+		      }
-          	   }
--		   /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
--         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-+#if 0
-+		   /* Makes no sense, but is in 650/30xLV 1.10.6s */
-+         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
- 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-              	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-       		 	    tempbx = 1040;
-@@ -491,25 +488,26 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
-       	     	         }
- 		      }
-          	   }
-+#endif
-                 }
- 
- 		temp = tempbx & 0xff;
--	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
-+	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
- #endif  /* SIS315H */
- 
--     	}  /* 310/325/330 series */
-+     	}  /* 315/330 series */
- 
--  	/* TW: The following is done for all bridge/chip types/series */
-+  	/* The following is done for all bridge/chip types/series */
- 
-   	tempax = tempbx & 0xFF00;
-   	tempbx = pushbx;
-   	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-   	tempax |= (tempbx & 0xFF00);
-   	temp = (tempax & 0xFF00) >> 8;
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
- 
-   	temp = tempcx & 0x00FF;
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
- 
-   	/* 2. Vertical setup */
- 
-@@ -517,30 +515,30 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
-   	temp = tempcx & 0x00FF;
- 
-         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--	     if(HwDeviceExtension->jChipType < SIS_315H) {
--	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
--		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
--		           temp--;
--		       }
--                  }
--	     } else {
-- 		      temp--;
--             }
-+	   if(HwDeviceExtension->jChipType < SIS_315H) {
-+	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-+	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
-+	            temp--;
-+	         }
-+              }
-+	   } else {
-+ 	      temp--;
-+           }
-         } else if(HwDeviceExtension->jChipType >= SIS_315H) {
--	    /* TW: 650/30xLV 1.10.6s */
--	    temp--;
-+	   /* 650/30xLV 1.10.6s */
-+	   temp--;
- 	}
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
- 
-   	tempbx = SiS_Pr->SiS_VGAVDE - 1;
-   	temp = tempbx & 0x00FF;
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
- 
-   	temp = ((tempbx & 0xFF00) << 3) >> 8;
-   	temp |= ((tempcx & 0xFF00) >> 8);
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
- 
--	/* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
-+	/* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
- 	if(HwDeviceExtension->jChipType >= SIS_315H) {
-            tempbx++;
-    	   tempax = tempbx;
-@@ -553,29 +551,44 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 	   tempcx += tempbx;
- 	   tempcx++;
- 	} else {
--	   /* TW: 300 series, LVDS/301B: */
-+	   /* 300 series, LVDS/301B: */
-   	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
-   	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
- 	}
- 
-   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
--      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
--      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
--      		if(temp & 0x04) tempbx |= 0x0100;
--      		if(temp & 0x80) tempbx |= 0x0200;
--      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
--      		if(temp & 0x08) tempbx |= 0x0400;
--      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
--      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
-+
-+	   if(SiS_Pr->UseCustomMode) {
-+	      tempbx = SiS_Pr->CVSyncStart;
-+	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
-+	   }
-+
-+    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-+	      unsigned char cr8, cr7, cr13, cr9;
-+	      if(SiS_Pr->UseCustomMode) {
-+	         cr8  = SiS_Pr->CCRT1CRTC[8];
-+		 cr7  = SiS_Pr->CCRT1CRTC[7];
-+		 cr13 = SiS_Pr->CCRT1CRTC[13];
-+		 cr9  = SiS_Pr->CCRT1CRTC[9];
-+	      } else {
-+	         cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
-+		 cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-+		 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-+		 cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
-+	      }
-+      	      tempbx = cr8;
-+      	      if(cr7 & 0x04)  tempbx |= 0x0100;
-+      	      if(cr7 & 0x80)  tempbx |= 0x0200;
-+      	      if(cr13 & 0x08) tempbx |= 0x0400;
-+      	      tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
-     	   }
-   	}
-   	temp = tempbx & 0x00FF;
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
- 
-   	temp = ((tempbx & 0xFF00) >> 8) << 4;
-   	temp |= (tempcx & 0x000F);
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
- 
-   	/* 3. Panel compensation delay */
- 
-@@ -590,18 +603,18 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 		   temp = 0x10;
- 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
- 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
--		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
- 		}
- 		if(SiS_Pr->SiS_VBType & VB_SIS301) {
- 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
- 		}
- 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
-+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
- 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
- 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-       		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
-       		   else 					temp = 0x20;
-     	        }
--		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-+		if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
- 		    if(ROMAddr[0x220] & 0x80) {
- 		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
- 				temp = ROMAddr[0x221];
-@@ -636,19 +649,20 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 		}
- 	   }
- 
--    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
-+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
- 
- #endif  /* SIS300 */
- 
-   	} else {
- 
--#ifdef SIS315H   /* ----------- 310/325/330 series ---------------*/
-+#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
- 
- 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-                 temp = 0x10;
-                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
-     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
-+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
- 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- 		   temp = 0x08;
- 		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-@@ -664,7 +678,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 		      }
-     	           }
- 		}
--		if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-+		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
- 		   tempbl = 0x00;
- 		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
- 		      if(HwDeviceExtension->jChipType < SIS_330) {
-@@ -689,8 +703,16 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
- 		   }
- 		}
-+		
-+		if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
-+		   temp = 0x08;
-+		   tempbl = 0;
-+		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-+		      if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
-+		   }
-+		}
- 	   }
--	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
-+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
- 
-     	   tempax = 0;
-     	   if (modeflag & DoubleScanMode) tempax |= 0x80;
-@@ -705,14 +727,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
- 
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
--        /* TW: For 301BDH, we set up the Panel Link */
--        if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
--	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
-+        /* For 301BDH with LCD, we set up the Panel Link */
-+        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
- 
- 	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
- 	                       HwDeviceExtension,RefreshRateTableIndex);
- 
--        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {                             
-+        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- 
-     	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
- 	                      HwDeviceExtension,RefreshRateTableIndex);
-@@ -749,23 +770,27 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
-   USHORT  push1,push2;
-   USHORT  tempax,tempbx,tempcx,temp;
-   USHORT  resinfo,modeflag;
-+  unsigned char p1_7, p1_8;
- 
-   if(ModeNo <= 0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-   } else {
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+	resinfo = 0;
-+     } else {
-     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+     }
-   }
- 
--  /* TW: The following is only done if bridge is in slave mode: */
-+  /* The following is only done if bridge is in slave mode: */
- 
-   tempax = 0xFFFF;
-   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
- 
--  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--  	modeflag |= Charx8Dot;
--  }
-+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
- 
-   if(modeflag & Charx8Dot) tempcx = 0x08;
-   else                     tempcx = 0x09;
-@@ -777,8 +802,7 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
-   tempax = (tempax / tempcx) - 5;
-   tempbx = tempax & 0x00FF;
- 
--  temp = 0xFF;                                                  /* set MAX HT */
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff);                 /* set MAX HT */
- 
-   tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
-   if(modeflag & HalfDCLK) tempax >>= 1;
-@@ -789,13 +813,13 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
- 
-   temp = (tempbx & 0xFF00) >> 8;
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {        
--    	    temp += 2;
--        }
--  }	
-+     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-+        temp += 2;
-+     }
-+  }
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      if(SiS_Pr->SiS_HiVision == 3) {
--              if(resinfo == 7) temp -= 2;
-+        if(resinfo == SIS_RI_800x600) temp -= 2;
-      }
-   }
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
-@@ -804,140 +828,133 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
- 
-   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3)) {
--    temp = (tempbx & 0x00FF) - 1;
--    if(!(modeflag & HalfDCLK)) {
--      temp -= 6;
--      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--        temp -= 2;
--        if(ModeNo > 0x13) temp -= 10;
--      }
--    }
-+     temp = (tempbx & 0x00FF) - 1;
-+     if(!(modeflag & HalfDCLK)) {
-+        temp -= 6;
-+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-+           temp -= 2;
-+           if(ModeNo > 0x13) temp -= 10;
-+        }
-+     }
-   } else {
--    tempcx = tempbx & 0x00FF;
--    tempbx = (tempbx & 0xFF00) >> 8;
--    tempcx = (tempcx + tempbx) >> 1;
--    temp = (tempcx & 0x00FF) + 2;
--    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
--       temp--;
--       if(!(modeflag & HalfDCLK)){
--          if((modeflag & Charx8Dot)){
--             temp += 4;
--             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
--             if(HwDeviceExtension->jChipType >= SIS_315H) {
--	        if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
--             }
--          }
--       }
--    } else {
--       if(!(modeflag & HalfDCLK)) {
--          temp -= 4;
--          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
--             if(SiS_Pr->SiS_VGAHDE >= 800) {
--                temp -= 7;
--	        if(HwDeviceExtension->jChipType < SIS_315H) {
--	           /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
--                   if(SiS_Pr->SiS_ModeType == ModeEGA) {
--                      if(SiS_Pr->SiS_VGAVDE == 1024) {
--                         temp += 15;
--                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) 
--			    temp += 7;
--                      }
--                   }
--	        }
--                if(SiS_Pr->SiS_VGAHDE >= 1280) {
--                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
--                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
--                   }
--                }
--             }
--          }
--       }
--    }
-+     tempcx = tempbx & 0x00FF;
-+     tempbx = (tempbx & 0xFF00) >> 8;
-+     tempcx = (tempcx + tempbx) >> 1;
-+     temp = (tempcx & 0x00FF) + 2;
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        temp--;
-+        if(!(modeflag & HalfDCLK)) {
-+           if((modeflag & Charx8Dot)) {
-+              temp += 4;
-+              if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
-+              if(HwDeviceExtension->jChipType >= SIS_315H) {
-+	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
-+              }
-+           }
-+        }
-+     } else {
-+        if(!(modeflag & HalfDCLK)) {
-+           temp -= 4;
-+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-+              if(SiS_Pr->SiS_VGAHDE >= 800) {
-+                 temp -= 7;
-+	         if(HwDeviceExtension->jChipType < SIS_315H) {
-+	            /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
-+                    if(SiS_Pr->SiS_ModeType == ModeEGA) {
-+                       if(SiS_Pr->SiS_VGAVDE == 1024) {
-+                          temp += 15;
-+                          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
-+		  	     temp += 7;
-+                       }
-+                    }
-+	         }
-+                 if(SiS_Pr->SiS_VGAHDE >= 1280) {
-+                    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
-+                 }
-+              }
-+           }
-+        }
-+     }
-   }
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
- 
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
-+  p1_7 = temp;
-+  p1_8 = 0x00;
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--            if(ModeNo <= 0x01) {
--	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
--		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
--		} else {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
--		}
--	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
--	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
--		} else {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
--		}
--		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
--	    } else if(ModeNo <= 0x13) {
--	        if(modeflag & HalfDCLK) {
--		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
--			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
--		    } else {
--		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
--			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
--		    }
--		} else {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
--		}
--	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
--	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
--	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
--		} else {
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
--		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
--		}
--	    }
--
-+        if(ModeNo <= 0x01) {
-+	   p1_7 = 0x2a;
-+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61;
-+	   else 	      			p1_8 = 0x41;
-+	} else if(SiS_Pr->SiS_ModeType == ModeText) {
-+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54;
-+	   else 	    			p1_7 = 0x55;
-+	   p1_8 = 0x00;
-+	} else if(ModeNo <= 0x13) {
-+	   if(modeflag & HalfDCLK) {
-+	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+		 p1_7 = 0x30;
-+		 p1_8 = 0x03;
-+	      } else {
-+	 	 p1_7 = 0x2f;
-+		 p1_8 = 0x02;
-+	      }
-+	   } else {
-+	      p1_7 = 0x5b;
-+	      p1_8 = 0x03;
-+	   }
-+	} else if( ((HwDeviceExtension->jChipType >= SIS_315H) &&
-+	            ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
-+	           ((HwDeviceExtension->jChipType < SIS_315H) &&
-+		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
-+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+	      p1_7 = 0x30,
-+	      p1_8 = 0x03;
-+	   } else {
-+	      p1_7 = 0x2f;
-+	      p1_8 = 0x03;
-+	   }
-+        }
-      }
-   }
-+
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      if(SiS_Pr->SiS_HiVision & 0x03) {
--        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
-+	p1_7 = 0xb2;
- 	if(SiS_Pr->SiS_HiVision & 0x02) {
--	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
-+	   p1_7 = 0xab;
- 	}
-      }
-   }
- 
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
-+
-+
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
- 
-   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
- 
--  tempbx = SiS_Pr->SiS_VGAVT;
--  push1 = tempbx;
--
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
- 
-   tempcx = 0x121;
-   tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
--  if(tempbx == 357) tempbx = 350;
--  if(tempbx == 360) tempbx = 350;
--  if(tempbx == 375) tempbx = 350;
--  if(tempbx == 405) tempbx = 400;
--  if(tempbx == 420) tempbx = 400;
--  if(tempbx == 525) tempbx = 480;
-+  if     (tempbx == 357) tempbx = 350;
-+  else if(tempbx == 360) tempbx = 350;
-+  else if(tempbx == 375) tempbx = 350;
-+  else if(tempbx == 405) tempbx = 400;
-+  else if(tempbx == 420) tempbx = 400;
-+  else if(tempbx == 525) tempbx = 480;
-   push2 = tempbx;
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
--        		if(tempbx == 350) tempbx += 5;
--        		if(tempbx == 480) tempbx += 5;
--      		}
--    	}
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+      	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-+           if     (tempbx == 350) tempbx += 5;
-+           else if(tempbx == 480) tempbx += 5;
-+      	}
-+     }
-   }
--  tempbx--;
--  temp = tempbx & 0x00FF;
--  tempbx--;
-+  tempbx -= 2;
-   temp = tempbx & 0x00FF;
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
- 
-@@ -945,126 +962,91 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
-   tempbx--;
-   temp = tempbx & 0x00FF;
- #if 0
--  /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
-+  /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
-   if(xxx()) {
-       if(temp == 0xdf) temp = 0xda;
-   }
- #endif
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
- 
--  if(tempbx & 0x0100) {
--  	tempcx |= 0x0002;
--	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
--  }
-+  if(tempbx & 0x0100)  tempcx |= 0x0002;
- 
-   tempax = 0x000B;
-   if(modeflag & DoubleScanMode) tempax |= 0x8000;
- 
--  if(tempbx & 0x0200) {
--  	tempcx |= 0x0040;
--	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
--  }
--
--  if(SiS_Pr->SiS_VBType & VB_SIS301) {
--        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--	      if(SiS_Pr->SiS_VGAVDE == 480) {
--	             tempax = (tempax & 0x00ff) | 0x2000;
--		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
--	      }
--	}
--  }
-+  if(tempbx & 0x0200)  tempcx |= 0x0040;
- 
-   temp = (tempax & 0xFF00) >> 8;
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
- 
--  if(tempbx & 0x0400) tempcx |= 0x0600;
-+  if(tempbx & 0x0400)  tempcx |= 0x0600;
- 
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
- 
--  tempax = push1;
--  tempax -= tempbx;
--  tempax >>= 2;
--  push1 = tempax;
-+  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
- 
--  if(HwDeviceExtension->jChipType >= SIS_315H) {
--        /* TW: 650/30xLV 1.10.6s */
--        if(ModeNo > 0x13) {
--	    if(resinfo != 0x09) {  /* 1280x1024 */
--	        tempax <<= 1;
--		tempbx += tempax;
--	    }
--	} else {
--	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
--	        tempax <<= 1;
--		tempbx += tempax;
--	    }
--	}
--  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
--    	tempax <<= 1;
--    	tempbx += tempax;
-+  if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) {
-+     if(resinfo != SIS_RI_1280x1024) {
-+	tempbx += (tempax << 1);
-+     }
-+  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
-+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-+	tempbx += (tempax << 1);
-+     }
-   }
- 
--  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
--      (SiS_Pr->SiS_HiVision == 3) ) {
--    	tempbx -= 10;
-+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-+     (SiS_Pr->SiS_HiVision == 3)) {
-+     tempbx -= 10;
-   } else {
--    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
--                    tempbx += 40;
--		    if(HwDeviceExtension->jChipType >= SIS_315H) {
--		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
--		    }
--      	       }
--	   }
--    	}
-+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-+	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-+              tempbx += 40;
-+	      if(HwDeviceExtension->jChipType >= SIS_315H) {
-+	         if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
-+	      }
-+      	   }
-+	}
-+     }
-   }
--  tempax = push1;
-   tempax >>= 2;
-   tempax++;
-   tempax += tempbx;
-   push1 = tempax;
-   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--    	if(tempbx <= 513)  {
--      		if(tempax >= 513) tempbx = 513;
--    	}
-+     if(tempbx <= 513)  {
-+     	if(tempax >= 513) tempbx = 513;
-+     }
-   }
-   temp = tempbx & 0x00FF;
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
- 
--  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
--  	tempbx--;
--  	temp = tempbx & 0x00FF;
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
--
--	if(tempbx & 0x0100) tempcx |= 0x0008;
-+  tempbx--;
-+  temp = tempbx & 0x00FF;
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
- 
--  	if(tempbx & 0x0200) {
--    	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
--	}
-+  if(tempbx & 0x0100) tempcx |= 0x0008;
- 
--  	tempbx++;
-+  if(tempbx & 0x0200) {
-+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
-   }
-+  tempbx++;
-+
-   if(tempbx & 0x0100) tempcx |= 0x0004;
-   if(tempbx & 0x0200) tempcx |= 0x0080;
-   if(tempbx & 0x0400) {
--        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
--  	else                               tempcx |= 0x0C00;
-+     if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
-+     else                               tempcx |= 0x0C00;
-   }
- 
-   tempbx = push1;
--  temp = tempbx & 0x00FF;
--  temp &= 0x0F;
-+  temp = tempbx & 0x000F;
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
- 
-   if(tempbx & 0x0010) tempcx |= 0x2000;
- 
-   temp = tempcx & 0x00FF;
--  if(SiS_Pr->SiS_VBType & VB_SIS301) {
--	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
--	}
--  }
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
- 
-   temp = (tempcx & 0xFF00) >> 8;
-@@ -1074,8 +1056,8 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
-   temp = (tempax & 0xFF00) >> 8;
-   temp = (temp >> 1) & 0x09;
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
--       /* Only use 8 dot clock */
--       temp |= 0x01;
-+     /* Only use 8 dot clock */
-+     temp |= 0x01;
-   }
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
- 
-@@ -1084,16 +1066,15 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
- 
-   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
--       if(IS_SIS650) {
--           /* TW: 650/30xLV 1.10.6s */
--           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
--	       temp = 0x80;
--	   }
--       } else temp = 0x80;
--  } else  temp = 0x00;
-+     if(IS_SIS650) {
-+        /* 650/30xLV 1.10.6s */
-+        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-+	   temp = 0x80;
-+	}
-+     } else temp = 0x80;
-+  } else temp = 0x00;
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
- 
--  return;
- }
- 
- void
-@@ -1108,40 +1089,52 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- #endif
-   ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
- 
-+  /* This is not supported on LVDS */
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-+  if(SiS_Pr->UseCustomMode) return;
-+
-   if(ModeNo <= 0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-   } else {
--    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
--    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-   }
- 
--  /* TW: Set up Panel Link */
-+  /* Set up Panel Link */
- 
-   /* 1. Horizontal setup */
- 
-   tempax = SiS_Pr->SiS_LCDHDES;
- 
--  if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
--      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
--  	tempax -= 8;
-+  if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-+     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
-+         (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
-+  	   tempax -= 8;
-+     }
-   }
- 
-   tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
- 
-   tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
- 
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-+     tempbx >>= 1;
-+  }
-+
-   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
-- 	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx =  800;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW */
--    	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW */
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx = 1280;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; 
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400; 
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600; 
-+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-+	   tempbx = SiS_Pr->PanelXRes;
-+	} else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-+	   tempbx = SiS_Pr->PanelXRes;
-+	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-+	      tempbx = 800;
-+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-+	         tempbx = 1024;
-+	      }
-+	   }
-         }
-      }
-   }
-@@ -1154,13 +1147,17 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
-   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
- 
-   push2 = tempax;
--  
--  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 
--     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
--     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
--     	   else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-+
-+  if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
-+     (!SiS_Pr->SiS_IF_DEF_DSTN) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-+     	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
-+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
-+     	      else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- 	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
- 	  	   if(HwDeviceExtension->jChipType < SIS_315H) {
- 		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-@@ -1174,11 +1171,12 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 		   } else {
- 		      tempcx = 0x0018;
- 		   }
-+	      }
-+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
-+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
-+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
-+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
- 	   }
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
-         }
-      }
-   }
-@@ -1188,14 +1186,17 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   tempax = tempcx >> 3;                          /* BPLHRS */
-   temp = tempax & 0x00FF;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; Panel Link Horizontal Retrace Start  */
- 
-   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-      temp = (tempax & 0x00FF) + 2;
-   } else {
-      temp = (tempax & 0x00FF) + 10;
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
-+        if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
-+	   (!SiS_Pr->SiS_IF_DEF_FSTN) &&
-+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- 	      temp += 6;
-               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-@@ -1219,47 +1220,57 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   temp &= 0x1F;
-   temp |= ((tempcx & 0x0007) << 5);
--  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
-+#if 0
-+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
-+#endif  
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
- 
-   tempbx = push2;
-   tempcx = push1;                                /* lcdhdes  */
- 
-   temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
- 
-   tempcx >>= 3;                                  /* BPLHDES */
-   temp = (tempcx & 0x00FF);
--  if(ModeNo == 0x5b) temp--;                     
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
-+#if 0 /* Not 550 FSTN */
-+  if(HwDeviceExtension->jChipType >= SIS_315H) {
-+     if(ModeNo == 0x5b) temp--; */
-+  }
-+#endif
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; Panel Link Horizontal Display Enable Start  */
- 
--  if(HwDeviceExtension->jChipType < SIS_315H) {  
-+  if((HwDeviceExtension->jChipType < SIS_315H) ||
-+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
-+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
-      if(tempbx & 0x07) tempbx += 8;              
-   }
-   tempbx >>= 3;                                  /* BPLHDEE  */
-   temp = tempbx & 0x00FF;
--  if(ModeNo == 0x5b) temp--;			 
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
--
-+#if 0 /* Not 550 FSTN */
-+  if(HwDeviceExtension->jChipType >= SIS_315H) {
-+     if(ModeNo == 0x5b) temp--;
-+  }
-+#endif
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; Panel Link Horizontal Display Enable End  */
-+
-   /* 2. Vertical setup */
- 
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      tempcx = SiS_Pr->SiS_VGAVT;
-      tempbx = SiS_Pr->SiS_VGAVDE;
--     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
--	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)       tempbx =  600;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx =  600;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx =  768;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx =  768;
--	   else								tempbx = 1024;
--        }
-+     if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-+	      tempbx = SiS_Pr->PanelYRes;
-+           }
-+	}
-      }
-      tempcx -= tempbx;
- 
-   } else {
- 
--     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
-+     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
- 
-   }
- 
-@@ -1268,18 +1279,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   tempax = SiS_Pr->SiS_VGAVDE;
- 
--  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
--     if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   && 
--         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
--         (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
--        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax =  600;
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax =  600;  
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax =  768;
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax =  768;  
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempax =  768;  
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; 
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; 
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; 
-+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+     if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-+           tempax = 600;
-+	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-+	      tempax = 768;
-+	   }
-+	}
-+     } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
-+                (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-+                ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
-+	         (SiS_Pr->SiS_IF_DEF_FSTN) ||
-+	         (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
-+	tempax = SiS_Pr->PanelYRes;
-      }
-   }
- 
-@@ -1290,11 +1303,24 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   tempcx >>= 1;
- 
--  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
--     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
--        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
--     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0001;
--	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0001;
-+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-+	tempcx = 0x0017;
-+     } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
-+  	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-+	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
-+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
-+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
-+	   else 							  tempcx = 0x0057;
-+        } else  {
-+     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
-+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
-      	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- 	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
- 		   if(HwDeviceExtension->jChipType < SIS_315H) {
-@@ -1304,7 +1330,7 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 			    tempcx = 0x0003;
- #endif
- 		      } else {
--		            tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
-+		            tempcx = 0x0002;   /* A901; sometimes 0x0003; */
- 		      }
- 		   } else tempcx = 0x0003;
-            }
-@@ -1319,26 +1345,32 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   tempbx += tempcx;			 	/* BPLVRS  */
- 
--  if(HwDeviceExtension->jChipType < SIS_315H) {
--      tempbx++;
-+  if((HwDeviceExtension->jChipType < SIS_315H) ||
-+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
-+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
-+     tempbx++;
-   }
- 
-   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
- 
-   temp = tempbx & 0x00FF;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
- 
-   tempcx >>= 3;
- 
--  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-+  if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
-+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if( (HwDeviceExtension->jChipType < SIS_315H) &&
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
-+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
-+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
-         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
-         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
-         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
- 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
--        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;	 
-+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
-         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
-         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
-         else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-@@ -1360,26 +1392,36 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 
-   tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
-   temp = tempcx & 0x000F;
--  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
-+  if(SiS_Pr->SiS_IF_DEF_FSTN ||
-+     SiS_Pr->SiS_IF_DEF_DSTN ||
-+     (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+     temp |= 0x30;
-+  }
-+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
- 
-   temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
--  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
--  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
-+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-+     if(SiS_Pr->SiS_HDE != 640) {
-+        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
-+     }
-+  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
-+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
-   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
--      if(HwDeviceExtension->jChipType >= SIS_315H) {
--         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
--            temp |= 0x80;
--         }
--      } else {
--	 if( (HwDeviceExtension->jChipType == SIS_630) ||
--	     (HwDeviceExtension->jChipType == SIS_730) ) {
--	    if(HwDeviceExtension->jChipRevision >= 0x30) {
--	       temp |= 0x80;
--	    }
--	 }
--      }
-+     if(HwDeviceExtension->jChipType >= SIS_315H) {
-+        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-+           temp |= 0x80;
-+        }
-+     } else {
-+	if( (HwDeviceExtension->jChipType == SIS_630) ||
-+	    (HwDeviceExtension->jChipType == SIS_730) ) {
-+	   if(HwDeviceExtension->jChipRevision >= 0x30) {
-+	      temp |= 0x80;
-+	   }
-+	}
-+     }
-   }
--  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
-+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
- 
-   if (HwDeviceExtension->jChipType < SIS_315H) {
- 
-@@ -1396,19 +1438,19 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
- 	}
- 
-   	temp = (USHORT)(tempebx & 0x00FF);
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
-+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
- 
- #endif /* SIS300 */
- 
-   } else {
- 
--#ifdef SIS315H  /* 310/325 series */
-+#ifdef SIS315H  /* 315 series */
- 
--#ifdef NEWCH701x
--        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
--#else
--	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
--#endif	
-+        if(HwDeviceExtension->jChipType == SIS_740) {
-+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
-+        } else {
-+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
-+	}
- 
- 	tempeax = SiS_Pr->SiS_VGAVDE << 18;
-     	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
-@@ -1417,12 +1459,13 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
-     	tempebx = tempeax;                         /* BPLVCFACT  */
-         tempvcfact = tempeax;
-     	temp = (USHORT)(tempebx & 0x00FF);
--    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
-+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
-     	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
--    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
-+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
-     	temp = (USHORT)((tempebx & 0x00030000) >> 16);
-+	temp &= 0x03;
-     	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
--    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
-+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
- 
- #endif /* SIS315H */
- 
-@@ -1434,47 +1477,50 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
-   push1 = temp;					   
- 
-   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
-+   	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
- 		if(HwDeviceExtension->jChipType < SIS_315H) {
- 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
--      				if(resinfo == 15) tempcx++;
-+      				if(resinfo == SIS_RI_1024x600) tempcx++;
- 				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--					if(resinfo == 7) tempcx++;
-+					if(resinfo == SIS_RI_800x600) tempcx++;
- 		    		}
- 			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--      				if(resinfo == 7) tempcx++;
--				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
--			} else  if(resinfo == 8) tempcx++;
-+      				if(resinfo == SIS_RI_800x600)  tempcx++;
-+				if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
-+			} else  if(resinfo == SIS_RI_1024x768) tempcx++;
- 		} else {
- 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--      				if(resinfo == 7) tempcx++;
-+      				if(resinfo == SIS_RI_800x600)  tempcx++;
- 			}
- 		}
- 	}
-   }
- 
-   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
--     tempcx = SiS_Pr->SiS_VGAVDE;
--     tempbx = SiS_Pr->SiS_VGAVDE - 1;
-+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-+        tempcx = SiS_Pr->SiS_VGAVDE;
-+        tempbx = SiS_Pr->SiS_VGAVDE - 1;
-+     }
-   }
- 
-   temp = ((tempbx & 0x0700) >> 8) << 3;
-   temp |= ((tempcx & 0x0700) >> 8);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
- 
-   temp = tempbx & 0x00FF;
--  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
-+  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; Panel Link Vertical Display Enable End  */
- 
-   temp = tempcx & 0x00FF;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
- 
-   /* 3. Additional horizontal setup (scaling, etc) */
- 
-   tempecx = SiS_Pr->SiS_VGAHDE;
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--     if(modeflag & HalfDCLK)
--        tempecx >>= 1;
-+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-+        if(modeflag & HalfDCLK) tempecx >>= 1;
-+     }
-   }
-   tempebx = SiS_Pr->SiS_HDE;
-   if(tempecx == tempebx) tempeax = 0xFFFF;
-@@ -1484,134 +1530,162 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
-      temp = (USHORT)(tempeax % tempebx);
-      tempeax = tempeax / tempebx;
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
--         if(temp) tempeax++;
-+        if(temp) tempeax++;
-      }
-   }
-   tempecx = tempeax;
- 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--      tempeax = SiS_Pr->SiS_VGAHDE;
--      if(modeflag & HalfDCLK) tempeax >>= 1;
--      tempeax <<= 16;
--      tempeax = (tempeax / tempecx) - 1;
-+     tempeax = SiS_Pr->SiS_VGAHDE;
-+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-+        if(modeflag & HalfDCLK) tempeax >>= 1;
-+     }
-+     tempeax <<= 16;
-+     tempeax = (tempeax / tempecx) - 1;
-   } else {
--      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
-+     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
-   }
-   tempecx <<= 16;
-   tempecx |= (tempeax & 0xFFFF);
-   temp = (USHORT)(tempecx & 0x00FF);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
- 
-   tempbx = SiS_Pr->SiS_VDE;
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
--      tempbx = (USHORT)(tempeax & 0x0FFFF);
-+     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-+     tempbx = (USHORT)(tempeax & 0x0FFFF);
-   } else {
--      tempax = SiS_Pr->SiS_VGAVDE << 6;
--      tempbx = push1;
--      tempbx &= 0x3f;
--      if(tempbx == 0) tempbx = 64;
--      tempax = tempax / tempbx;
--      tempbx = tempax;
-+     tempeax = SiS_Pr->SiS_VGAVDE << 6;
-+     tempbx = push1 & 0x3f;
-+     if(tempbx == 0) tempbx = 64;
-+     tempeax /= tempbx;
-+     tempbx = (USHORT)(tempeax & 0x0FFFF);
-   }
-   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
--  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
-+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
-+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
-+     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
-+  }
- 
-   temp = ((tempbx & 0xFF00) >> 8) << 3;
-   temp |= (USHORT)((tempecx & 0x0700) >> 8);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; Overflow register */
- 
-   temp = tempbx & 0x00FF;
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; Panel Link Vertical Accumulator Register */
- 
-   tempecx >>= 16;                               /* BPLHCFACT  */
--  if(HwDeviceExtension->jChipType < SIS_315H) {
--      if(modeflag & HalfDCLK) tempecx >>= 1;
-+  if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
-+     if(modeflag & HalfDCLK) tempecx >>= 1;
-   }
-   temp = (USHORT)((tempecx & 0xFF00) >> 8);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; Panel Link Horizontal Scaling Factor High */
- 
-   temp = (USHORT)(tempecx & 0x00FF);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
-+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
- 
-   /* 630/301B and 630/LVDS do something for 640x480 panels here */
- 
- #ifdef SIS315H
--  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
--  if(SiS_Pr->SiS_IF_DEF_DSTN) {
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
--     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
--     	temp = tempbx & 0x00FF;
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
--     	temp=((tempbx & 0xFF00) >> 8) << 3;
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
--     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
--     	temp = tempbx & 0x00FF;
--     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
--     	tempbx = SiS_Pr->SiS_VDE / 2;
--     	temp = tempbx & 0x00FF;
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
--     	temp = ((tempbx & 0xFF00) >> 8) << 3;
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
--     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
--     	tempebx = 128;
--     	temp = (USHORT)(tempeax % tempebx);
--     	tempeax = tempeax / tempebx;
--     	if(temp != 0)  tempeax++;
--     	temp = (USHORT)(tempeax & 0x003F);
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
--     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
--     	pushcx = tempax;
--     	temp = tempax & 0x00FF;
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
--     	temp = ((tempax & 0xFF00) >> 8) << 3;
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
--     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
--     	tempeax = (tempax * pushcx);
--     	tempebx = 0x00100000 + tempeax;
--     	temp = (USHORT)tempebx & 0x000000FF;
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
--     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
--     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
--     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
--     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
--     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
--     	if(SiS_Pr->SiS_IF_DEF_FSTN){
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
--         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
--         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
--         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
--         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
--     	}
--     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
--     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
-+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
-+     tempax = SiS_Pr->SiS_HDE;                       		/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
-+     tempax += 64;
-+     temp = tempax & 0x00FF;
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
-+     temp = ((tempax & 0xFF00) >> 8) << 3;
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
-+     tempax += 32;		                     		/* Blpe=lBlps+32 */
-+     temp = tempax & 0x00FF;
-+     if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/* Bflml=0 */
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
-+
-+     tempax = SiS_Pr->SiS_VDE;
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
-+     tempax >>= 1;
-+     temp = tempax & 0x00FF;
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
-+     temp = ((tempax & 0xFF00) >> 8) << 3;
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
-+
-+     tempeax = SiS_Pr->SiS_HDE;
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
-+     tempeax <<= 2;                       			/* BDxFIFOSTOP = (HDE*4)/128 */
-+     tempebx = 128;
-+     temp = (USHORT)(tempeax % tempebx);
-+     tempeax = tempeax / tempebx;
-+     if(temp) tempeax++;
-+     temp = (USHORT)(tempeax & 0x003F);
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
-+
-+     tempax = SiS_Pr->SiS_HDE;
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
-+     tempax >>= 4;                        			/* BDxWadroff = HDE*4/8/8 */
-+     pushcx = tempax;
-+     temp = tempax & 0x00FF;
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
-+     temp = ((tempax & 0xFF00) >> 8) << 3;
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
-+
-+     tempax = SiS_Pr->SiS_VDE;                             	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
-+     tempeax = (tempax * pushcx);
-+     tempebx = 0x00100000 + tempeax;
-+     temp = (USHORT)tempebx & 0x000000FF;
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
-+     temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
-+     temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
-+     temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
-+
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0x38);
-+
-+     if(SiS_Pr->SiS_IF_DEF_FSTN) {
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03);
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a);
-+     }
-   }
- #endif  /* SIS315H */
- 
-@@ -1629,7 +1703,7 @@ SiS_CRT2AutoThreshold(SiS_Private *SiS_P
- 
- 
- #ifdef SIS315H
--/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
-+/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */
- void
- SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
-@@ -1638,6 +1712,10 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-   USHORT push1,push2,tempax,tempbx,tempcx,temp;
-   ULONG tempeax=0,tempebx,tempecx,tempvcfact;
- 
-+  /* This is not supported with LCDA */
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-+  if(SiS_Pr->UseCustomMode) return;
-+
-   if(IS_SIS330) {
-      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
-   } else if(IS_SIS740) {
-@@ -1645,7 +1723,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
- 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
-      } else {
--        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV 1.10.1i */
-+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV, 301BDH */
-      }
-   } else {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
-@@ -1669,10 +1747,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-   tempcx = SiS_Pr->SiS_HT;
- 
-   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
--	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
--	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
--	else 							      tempbx = 1280;
-+        tempbx = SiS_Pr->PanelXRes;
-   }
-   tempcx -= tempbx;                        	            	/* HT-HDE  */
-   push1 = tempax;
-@@ -1684,7 +1759,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
- 
-   tempcx >>= 2;
- 
--  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
-+  /* 650/30xLV 1.10.6s, 740/LVDS */
-   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-@@ -1748,13 +1823,10 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-   tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
-   push1 = tempbx;                                      		
-   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempax = 768;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
--    else                                                           tempax = 960;
--  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
-+     tempax = SiS_Pr->PanelYRes;
-+  } else {
-+     tempax = SiS_Pr->SiS_VGAVDE;
-+  }
- 
-   tempbx += tempax;
-   tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
-@@ -1764,7 +1836,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-  
-   tempcx >>= 2;	
- 
--  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
-+  /* 650/30xLV 1.10.6s, 740/LVDS */
-   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-@@ -1806,7 +1878,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
-   } else {
--     /* TW: 650/30xLV 1.10.6s, Xabre */
-+     /* 650/30xLV 1.10.6s, Xabre */
-      temp |= 0xC0;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
-   }
-@@ -1823,7 +1895,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-      }
-   } else {
-      if(IS_SIS650) {
--        /* TW: 650/30xLV 1.10.6s */
-+        /* 650/30xLV 1.10.6s */
-         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-         }
-@@ -1839,7 +1911,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
- 
-   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--      if(resinfo == 7) tempcx++;
-+      if(resinfo == SIS_RI_800x600) tempcx++;
-     }
-   }
-   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-@@ -1925,15 +1997,15 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
- 
- #if 0
--  /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
-+  /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
-   if(xxx()) {
-       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
-   }
- #endif
- 
--  /* TW: Only for LVDS and 301LV/302LV */
-+  /* Only for LVDS and 301LV/302LV */
-   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
--  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
-   }
- 
-   return;
-@@ -1951,10 +2023,10 @@ void SiS_SetCRT2Offset(SiS_Private *SiS_
- 
-   offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                          HwDeviceExtension);
--#if 0
--  if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
--  if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
--#endif			 
-+
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
-+
-   temp = (UCHAR)(offset & 0xFF);
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
-   temp = (UCHAR)((offset & 0xFF00) >> 8);
-@@ -1976,13 +2048,7 @@ SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR
-   } else {
-      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-      modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
--  
--     if(HwDeviceExtension->jChipType < SIS_315H ) {
--    	index = (modeinfo >> 4) & 0xFF;
--     } else {
--    	index = (modeinfo >> 8) & 0xFF;
--     }
--
-+     index = (modeinfo >> 8) & 0xFF;
-      temp = SiS_Pr->SiS_ScreenOffset[index];
-   }
-   
-@@ -1992,9 +2058,8 @@ SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR
- 
-   temp *= colordepth;
- 
--  /* TW: For 1400x1050 and 856x480 */
--  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || 
--        ModeNo == 0x3f || 
-+  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
-+        ModeNo == 0x3f ||
- 	ModeNo == 0x42 || 
- 	ModeNo == 0x45 ) ||
-       (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
-@@ -2012,7 +2077,8 @@ SiS_GetColorDepth(SiS_Private *SiS_Pr, U
-   SHORT  index;
-   USHORT modeflag;
- 
--  if(SiS_Pr->UseCustomMode) {
-+  /* Do NOT check UseCustomMode, will skrew up FIFO */
-+  if(ModeNo == 0xfe) {
-      modeflag = SiS_Pr->CModeFlag;
-   } else {
-      if(ModeNo <= 0x13)
-@@ -2035,7 +2101,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
-   flag = 0;
-   tempbl = 0xC0;
- 
--  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-+  if(SiS_Pr->UseCustomMode) {
-+     infoflag = SiS_Pr->CInfoFlag;
-+  } else {
-+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-+  }
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
- 
-@@ -2044,12 +2114,19 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
-     } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
-        tempah = SiS_Pr->SiS_LCDInfo;
-     } else tempah = infoflag >> 8;
--    
-+
-     tempah &= 0xC0;
--    
-+
-     tempah |= 0x20;
-     if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- 
-+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-+          (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+	  tempah |= 0xc0;
-+       }
-+    }
-+
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(HwDeviceExtension->jChipType >= SIS_315H) {
-           tempah >>= 3;
-@@ -2079,9 +2156,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
-             tempah |= 0x20;
-             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- 
-+#if 0
-             if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
--	       	/* TW: BIOS does something here @@@ */
-+	       	/* BIOS does something here @@@ */
-             }
-+#endif
- 
-  	    tempah &= 0x3f;
-   	    tempah |= tempbl;
-@@ -2089,16 +2168,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
- 
-          } else {							/* 630 - 301 */
- 
--            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--               tempah = SiS_Pr->SiS_LCDInfo;
--	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
--	          flag = 1;
--	       }
--            }
--            if(flag != 1) tempah = infoflag >> 8;
-+            tempah = infoflag >> 8;
-             tempah &= 0xC0;
--            tempah |= 0x30;
--            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
-+            tempah |= 0x20;
-+	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- 
-          }
- 
-@@ -2106,9 +2180,9 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
- 
-       } else {
- 
--#ifdef SIS315H  /* ----- 310/325 series ---- */
-+#ifdef SIS315H  /* ------- 315 series ------ */
- 
--         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 310/325 - 30xLV */
-+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
- 
-             tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-             tempah &= 0xC0;
-@@ -2116,24 +2190,33 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
-             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- 
--         } else {							/* 310/325 - 301, 301B */
-+         } else {							/* 315 - 301, 301B */
- 
-             tempah = infoflag >> 8;
-             tempah &= 0xC0;
--	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
--	          tempah = SiS_Pr->SiS_LCDInfo;
--	          tempah &= 0xC0;
-+	    if(!SiS_Pr->UseCustomMode) {
-+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+	          if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-+	             tempah = SiS_Pr->SiS_LCDInfo;
-+	             tempah &= 0xC0;
-+	          }
- 	       }
- 	    }
- 	    
-             tempah |= 0x20;
-             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-+	    
- #if 0
-             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
--		/* TW: BIOS does something here @@@ */
-+		/* BIOS does something here @@@ */
-             }
--#endif	    
-+#endif
-+
-+	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* TEST, imitate BIOS bug */
-+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+	          tempah |= 0xc0;
-+	       }
-+	    }
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- 
-          } 
-@@ -2143,7 +2226,7 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
-    }
- }
- 
--/* TW: Set CRT2 FIFO on 300/630/730 */
-+/* Set CRT2 FIFO on 300/630/730 */
- #ifdef SIS300
- void
- SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-@@ -2197,7 +2280,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
- 
-   if(!SiS_Pr->CRT1UsesCustomMode) {
-   
--     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
-+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 	/* get CRT1 ModeNo */
-      SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
-      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-      SiS_Pr->SiS_SelectCRT2Rate = 0;
-@@ -2205,20 +2288,32 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
- 						modeidindex,HwDeviceExtension);
- 
-      if(CRT1ModeNo >= 0x13) {
--       index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
--       index &= 0x3F;
--       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
--       data2 = SiS_Pr->SiS_ModeType - 2;
-+        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-+        index &= 0x3F;
-+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
-+
-+	colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
-+        colorth >>= 1;
-+        if(!colorth) colorth++;
-      }
--     
-+
-   } else {
-   
-      CRT1ModeNo = 0xfe;
--     VCLK = SiS_Pr->CSRClock;						/* Get VCLK */
--     data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
--  
--  }			
--     
-+     VCLK = SiS_Pr->CSRClock_CRT1;						/* Get VCLK */
-+     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
-+     switch(data2) {								/* Get color depth */
-+        case 0 : colorth = 1; break;
-+        case 1 : colorth = 1; break;
-+        case 2 : colorth = 2; break;
-+        case 3 : colorth = 2; break;
-+        case 4 : colorth = 3; break;
-+        case 5 : colorth = 4; break;
-+        default: colorth = 2;
-+     }
-+
-+  }
-+
-   if(CRT1ModeNo >= 0x13) {
-     if(HwDeviceExtension->jChipType == SIS_300) {
-        index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-@@ -2227,22 +2322,8 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
-     }
-     index &= 0x07;
-     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
--    
--#ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
--    	CRT1ModeNo, VCLK, MCLK, data2);
--#endif  
--  
--    switch(data2) {							/* Get color depth */
--      case 0 : 	colorth = 1; break;
--      case 1 : 	colorth = 1; break;
--      case 2 : 	colorth = 2; break;
--      case 3 : 	colorth = 2; break;
--      case 4 : 	colorth = 3; break;
--      case 5 : 	colorth = 4; break;
--      default:  colorth = 2; break;
--    }
--    data2 = (colorth * VCLK) / MCLK;  
-+
-+    data2 = (colorth * VCLK) / MCLK;
- 
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-     temp = ((temp & 0x00FF) >> 6) << 1;
-@@ -2252,22 +2333,12 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
- 
-     data2 = temp - data2;
-     
--#ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
--    	data2);
--#endif    
--
-     if((28 * 16) % data2) {
-       	data2 = (28 * 16) / data2;
-       	data2++;
-     } else {
-       	data2 = (28 * 16) / data2;
-     }
--    
--#ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
--    	data2);
--#endif
- 
-     if(HwDeviceExtension->jChipType == SIS_300) {
- 
-@@ -2313,10 +2384,6 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
-        temp &= 0x0F;   
-        tempal |= temp;
- 
--#ifdef TWDEBUG
--       xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
--#endif
--      
-        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
-        tempbx = 0;        /* -- do it like the BIOS anyway... */
-        tempax = tempbx;
-@@ -2341,7 +2408,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
-        SiS_SetReg4(0xcf8,0x800000A0);
-        eax = SiS_GetReg3(0xcfc);
- #else
--       /* TW: We use pci functions X offers. We use tag 0, because
-+       /* We use pci functions X offers. We use tag 0, because
-         * we want to read/write to the host bridge (which is always
-         * 00:00.0 on 630, 730 and 540), not the VGA device.
-         */
-@@ -2368,43 +2435,41 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
-        if(!(temp & 0x80)) data += 5;
-     }
-     
--#ifdef TWDEBUG    
--    xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
--#endif
--
-     data += data2;				/* CRT1 Request Period */
-     
--#ifdef TWDEBUG    
--    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
--#endif
--
--    CRT2ModeNo = ModeNo;
-     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
--    SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);    
- 
--    refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
--                                               modeidindex,HwDeviceExtension);
-+    if(!SiS_Pr->UseCustomMode) {
-+
-+       CRT2ModeNo = ModeNo;
-+       SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
-+
-+       refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-+                                                  modeidindex,HwDeviceExtension);
-+
-+       index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
-+                               refreshratetableindex,HwDeviceExtension);
-+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
-+
-+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-+	     if(ROMAddr[0x220] & 0x01) {
-+                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
-+	     }
-+          }
-+       }
-+
-+    } else {
-+
-+       CRT2ModeNo = 0xfe;
-+       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
- 
--    index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
--                            refreshratetableindex,HwDeviceExtension);
--    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
--    
--    data2 = SiS_Pr->SiS_ModeType - 2;
--    switch(data2) {							/* Get color depth */
--      case 0 : 	colorth = 1; break;
--      case 1 : 	colorth = 1; break;
--      case 2 : 	colorth = 2; break;
--      case 3 : 	colorth = 2; break;
--      case 4 : 	colorth = 3; break;
--      case 5 : 	colorth = 4; break;
--      default:  colorth = 2; break;
-     }
--    
--#ifdef TWDEBUG    
--    xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
--    	CRT2ModeNo, VCLK, MCLK, data2, colorth);
--#endif
-+
-+    colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
-+    colorth >>= 1;
-+    if(!colorth) colorth++;
- 
-     data = data * VCLK * colorth;
-     if(data % (MCLK << 4)) {
-@@ -2414,10 +2479,6 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
-       	data = data / (MCLK << 4);
-     }
-     
--#ifdef TWDEBUG    
--    xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
--#endif    
--    
-     if(data <= 6) data = 6;
-     if(data > 0x14) data = 0x14;
- 
-@@ -2456,13 +2517,13 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
- }
- #endif
- 
--/* TW: Set FIFO on 310/325/330 series */
-+/* Set FIFO on 315/330 series */
- #ifdef SIS315H
- void
- SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
--
-+#if 0   /* This code is obsolete */
-   UCHAR CombCode[]  = { 1, 1, 1, 4, 3, 1, 3, 4,
-                         4, 1, 4, 4, 5, 1, 5, 4};
-   UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
-@@ -2474,11 +2535,13 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
-   USHORT ModeIdIndex;
-   USHORT RefreshRateTableIndex;
-   USHORT SelectRate_backup;
--  
-+
-   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
--  
-+#endif
-+
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
- 
-+#if 0
-   if(!SiS_Pr->CRT1UsesCustomMode) {
-   
-      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
-@@ -2489,28 +2552,27 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
- 
-      /* Get REFIndex for crt1 refreshrate */
-      RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
--                                             ModeIdIndex,HwDeviceExtension);
-+                                                ModeIdIndex,HwDeviceExtension);
-+     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-+     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
- 
--     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
--                          RefreshRateTableIndex,HwDeviceExtension);
--     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                        /* Get VCLK */
--     
-      tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
-      tempbx >>= 1;
--     if(!tempbx) tempbx++; 
--     
-+     if(!tempbx) tempbx++;
-+
-   } else {
--  
--     tempax = SiS_Pr->CSRClock;						/* Get VCLK */
--     tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
-+
-+     CRT1ModeNo = 0xfe;
-+     tempax = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
-+     tempbx = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
-      switch(tempbx) {							/* Get color depth */
--       case 0 : 	tempbx = 1; break;
--       case 1 : 	tempbx = 1; break;
--       case 2 : 	tempbx = 2; break;
--       case 3 : 	tempbx = 2; break;
--       case 4 : 	tempbx = 3; break;
--       case 5 : 	tempbx = 4; break;
--       default:  	tempbx = 2; break;
-+       case 0 : tempbx = 1; break;
-+       case 1 : tempbx = 1; break;
-+       case 2 : tempbx = 2; break;
-+       case 3 : tempbx = 2; break;
-+       case 4 : tempbx = 3; break;
-+       case 5 : tempbx = 4; break;
-+       default: tempbx = 2;
-      }
-   
-   }
-@@ -2523,13 +2585,6 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
- 
-   tempbx = tempax;
- 
--#if 0 /* TW: BIOS code is skrewed */
--  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
--   	tempax = 16;
--  } else {
--    	tempax = 8;
--  }
--#endif
-   tempax = 16;
- 
-   tempax -= tempbx;
-@@ -2556,24 +2611,33 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
- 
-   tempcx +=  temp3;                                      /* CRT1 Request Period */
- 
--  CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
--  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);           /* Get ModeID Table */
--
-   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-   SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
- 
--  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
--                                           ModeIdIndex,HwDeviceExtension);
-+  if(!SiS_Pr->UseCustomMode) {
-+
-+     CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
-+     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);
-+
-+     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-+                                                ModeIdIndex,HwDeviceExtension);
-+
-+     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
-+                             RefreshRateTableIndex,HwDeviceExtension);
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-+        tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
-+     } else {
-+        tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;
-+     }
- 
--  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
--                          RefreshRateTableIndex,HwDeviceExtension);
--  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
--     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
-   } else {
--     tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;                     /* Get VCLK  */
-+
-+     CRT2ModeNo = 0xfe;							  /* Get VCLK  */
-+     tempax = SiS_Pr->CSRClock;
-+
-   }
- 
--  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   /* Get colordepth */
-+  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   	  /* Get colordepth */
-   tempbx >>= 1;
-   if(!tempbx) tempbx++;
- 
-@@ -2590,12 +2654,16 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
- 
-   if (tempax > 0x37)  tempax = 0x37;
- 
--  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
-+  /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */
-   if(HwDeviceExtension->jChipType >= SIS_650) {
-   	tempax = 0x04;
-   }
--  
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
-+#else
-+
-+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
-+
-+#endif
- }
- 
- USHORT
-@@ -2611,9 +2679,10 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *
-     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
-   }
- }
-+
- #endif
- 
--/* TW: Checked against 650/LVDS 1.10.07 BIOS */
-+/* Checked against 650/LVDS 1.10.07 BIOS */
- void
- SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                    USHORT RefreshRateTableIndex,
-@@ -2623,6 +2692,13 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
-   USHORT PanelIndex,ResIndex;
-   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
- 
-+  if((SiS_Pr->UseCustomMode) ||
-+     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)) {
-+     SiS_Pr->SiS_LCDHDES = 0;
-+     SiS_Pr->SiS_LCDVDES = 0;
-+     return;
-+  }
-+
-   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
- 
- #ifdef SIS315H  
-@@ -2689,11 +2765,11 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
-      	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
-      	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
- 	default:
--		if(HwDeviceExtension->jChipType < SIS_315H)
--		   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
--		else
--		   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
--		break;
-+		 if(HwDeviceExtension->jChipType < SIS_315H)
-+		    PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
-+		 else
-+		    PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
-+		 break;
-      }
-   }
-   SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
-@@ -2710,7 +2786,7 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
-      } else {
-         if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-            if( (HwDeviceExtension->jChipType < SIS_315H) || 
--	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {  
-+	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
-               if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
-                  if(ModeNo <= 0x13) {
- 	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-@@ -2737,7 +2813,7 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
-         }
-      }
-   }
--  return;
-+
- }
- 
- void
-@@ -2757,11 +2833,11 @@ SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, U
- 
-   tempbx = 0;
-   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
--     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-         tempbx = 50;
-         if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
-         if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
--        /* TW: Nothing special needed for SOverscan    */
-+        /* Nothing special needed for SOverscan    */
-         /*     PALM uses NTSC data, PALN uses PAL data */
-      }
-   }
-@@ -2773,7 +2849,7 @@ SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, U
-         if(modeflag & HalfDCLK) tempbx++;
-      }
-   }
--  /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
-+  /* 630/LVDS and 650/LVDS (1.10.07) BIOS */
-   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-         tempal = 0x07;
-@@ -2833,14 +2909,13 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-      }
-   }
-   
--  /* TW: BIOS does not do this (neither 301 nor LVDS) */
-+  /* BIOS does not do this (neither 301 nor LVDS) */
-   /*     (But it's harmless; see SetCRT2Offset) */
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
- 
--  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- 
--	/* TW:   1. for LVDS/302B/302LV **LCDA** */
-+	/*   1. for LVDS/302B/302LV **LCDA** */
- 
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
-       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
-@@ -2855,23 +2930,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
- #ifdef SIS300    /* ---- 300 series ---- */
- 
--      /* For 301BDH: */
-+      /* For 301BDH: (with LCD via LVDS) */
-       if(SiS_Pr->SiS_VBType & VB_NoLCD) {
--	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
--	  temp &= 0xef;
--	  temp |= 0x02;
--	  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
--	     temp |= 0x10;
--	     temp &= 0xfd;
--	  }
--	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-+	 temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
-+	 temp &= 0xef;
-+	 temp |= 0x02;
-+	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-+	    temp |= 0x10;
-+	    temp &= 0xfd;
-+	 }
-+	 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-       }
- 
-       if(ModeNo > 0x13) {
--        tempcl -= ModeVGA;
--        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
--           tempah = ((0x10 >> tempcl) | 0x80);
--        }
-+         tempcl -= ModeVGA;
-+         if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
-+            tempah = ((0x10 >> tempcl) | 0x80);
-+         }
-       } else tempah = 0x80;
- 
-       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
-@@ -2880,7 +2955,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
-     } else {
- 
--#ifdef SIS315H    /* ---- 310/325/330 series ---- */
-+#ifdef SIS315H    /* ------- 315/330 series ------ */
- 
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-          if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
-@@ -2889,12 +2964,12 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-       }
- 
-       if(ModeNo > 0x13) {
--        tempcl -= ModeVGA;
--        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
--           tempah = (0x08 >> tempcl);
--           if (tempah == 0) tempah = 1;
--           tempah |= 0x40;
--        }
-+         tempcl -= ModeVGA;
-+         if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
-+            tempah = (0x08 >> tempcl);
-+            if (tempah == 0) tempah = 1;
-+            tempah |= 0x40;
-+         }
-       } else tempah = 0x40;
- 
-       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
-@@ -2921,7 +2996,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
--	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
-+	/*   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
- 
-     	tempah = 0x01;
-     	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-@@ -2938,7 +3013,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
-     	if(HwDeviceExtension->jChipType < SIS_315H) {
- 
--		/* --- 300 series --- */
-+		/* ---- 300 series ---- */
- 
-       		tempah = (tempah << 5) & 0xFF;
-       		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
-@@ -2946,7 +3021,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
-     	} else {
- 
--		/* --- 310 series --- */
-+		/* ---- 315 series ---- */
- 
-       		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
- 
-@@ -2956,9 +3031,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-       		tempah |= 0x10;
- 	}
- 
--	/* TW: 630/301 BIOS */
- 	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
--		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-+		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
- 			tempah |= 0x80;
- 		}
- 	} else {
-@@ -2996,28 +3071,31 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-       	      }
- 	   }
-     	}
--	/* TW: For 302LV dual-channel */
-+
-+	/* For 302LV dual-channel */
- 	if(HwDeviceExtension->jChipType >= SIS_315H) {
--	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
--		    tempah |= 0x40;
--	    }
-+	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+	      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
-+	         tempah |= 0x40;
-+	   }
- 	}
- 
- 	if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
--	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
--		tempah |= 0x80;
-+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
-+	   ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
-+	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
-+	   tempah |= 0x80;
- 	}
- 
-     	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
- 
-     } else {
- 
--    	/* TW: 3. for LVDS */
-+    	/* 3. for LVDS */
- 
- 	if(HwDeviceExtension->jChipType >= SIS_315H) {
- 
--	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
-+	   /* Inserted this entire section (BIOS 650/LVDS); added ModeType check
- 	    *     (LVDS can only be slave in 8bpp modes)
- 	    */
- 	   tempah = 0x80;
-@@ -3043,7 +3121,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
- 	} else {
- 
--	   /* TW: (added ModeType check) */
-+	   /* (added ModeType check) */
- 	   tempah = 0;
- 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
-                	  tempah |= 0x02;
-@@ -3060,50 +3138,69 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 
-   }
- 
--  /* TW: Inserted the entire following section */
-+  /* Inserted the entire following section */
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
- 
- #ifdef SIS315H
-+
-+         unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);;
-+
-+	 /* The following is nearly unpreditable and varies from machine
-+	  * to machine. Especially the 301DH seems to be a real trouble
-+	  * maker. Some BIOSes simply set the registers (like in the
-+	  * NoLCD-if-statements here), some set them according to the
-+	  * LCDA stuff. It is very likely that some machines are not
-+	  * treated correctly in the following, very case-orientated
-+	  * code. What do I do then...?
-+	  */
-+
-+	 /* 740 variants match for 30xB, 301B-DH, 30xLV */
-+
-          if(!(IS_SIS740)) {
-             tempah = 0x04;						   /* For all bridges */
-             tempbl = 0xfb;
-             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-                tempah = 0x00;
--	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
-+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
- 	          tempbl = 0xff;
-+	       }
-             }
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);   
- 	 }
--	 
--	 if(IS_SIS740) {						
-+
-+	 /* The following two are responsible for eventually wrong colors
-+	  * in TV output. The DH (VB_NoLCD) conditions are unknown; the
-+	  * b0 was found in some 651 machine (Pim); the b1 version in a
-+	  * 650 box (Jake). What is the criteria?
-+	  */
-+
-+	 if(IS_SIS740) {
- 	    tempah = 0x30;
- 	    tempbl = 0xcf;
- 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- 	       tempah = 0x00;
- 	    }
--	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
-+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
-+	    /* Fixes "TV-blue-bug" on 315+301 */
-+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);          /* For 301   */
-+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
-+	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xB-DH rev b0 (or "DH on 651"?) */
- 	 } else {
--	    /* TW: This in order to fix "TV-blue-bug" on 315+301 */
--            if(SiS_Pr->SiS_VBType & VB_SIS301) {
--	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);             /* For 301   */
--	    } else {
--	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
--	       } else {
--	          tempah = 0x30;					   /* For 301B  */
--	          tempbl = 0xcf;
--	          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
--	             tempah = 0x00;
--		     if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
--		        tempbl = 0xff;
--		     }
--	          }
--	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
-+	    tempah = 0x30;					     /* For 30xB (and 301BDH rev b1) */
-+	    tempbl = 0xcf;
-+	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-+	       tempah = 0x00;
-+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-+		  tempbl = 0xff;
- 	       }
- 	    }
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
- 	 }
- 
- 	 if(IS_SIS740) {
-@@ -3111,25 +3208,25 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-   	    tempbl = 0x3f;
- 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- 	       tempah = 0x00;
--	    } 
--	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
-+	    }
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
-+	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xLV */
-+	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xB-DH rev b0 (or "DH on 651"? */
- 	 } else {
--	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* For 30xLV */
--	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
--	    } else {							/* For 301, 301B */ 
--	        tempah = 0xc0;
--	        tempbl = 0x3f;
--	        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
--	           tempah = 0x00;
--		   if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
--		      tempbl = 0xff;
--		   }
--	        }
--	        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
-+	    tempah = 0xc0;						/* For 301, 301B (and 301BDH rev b1) */
-+	    tempbl = 0x3f;
-+	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-+	       tempah = 0x00;
-+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-+		  tempbl = 0xff;
-+	       }
- 	    }
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
- 	 }
- 
--	 if(IS_SIS740) {						
-+	 if(IS_SIS740) {
- 	    tempah = 0x80;
- 	    tempbl = 0x7f;
- 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-@@ -3141,8 +3238,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
-             tempbl = 0x7f;
-             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-                tempbl = 0xff;
--	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
-+	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
- 	          tempah |= 0x80;
-+	       }
-             }
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
- 	 }
-@@ -3174,16 +3272,32 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
- 	    tempbl = 0xfb;
-             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-                tempah = 0x00;
--	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
-+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
- 	          tempbl = 0xff;
-+	       }
-             }
- 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
- 
--	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
-+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
-+	    }
- 
- 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
- 
-+	 } else if(HwDeviceExtension->jChipType == SIS_550) {
-+
-+#if 0
-+	    tempah = 0x00;
-+	    tempbl = 0xfb;
-+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-+	       tempah = 0x00;
-+	       tempbl = 0xfb;
-+	    }
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
-+#endif
-+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
-+
-+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
- 	 }
- 
-       }
-@@ -3209,10 +3323,9 @@ SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCH
- 	                      HwDeviceExtension);
-         } else {
- 
--	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
--	       (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
--	       
--	      /* TW: Need LVDS Data for LCD on 301BDH */
-+	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-+
-+	      /* Need LVDS Data for LCD on 301B-DH */
- 	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
- 	                          HwDeviceExtension);
- 				  
-@@ -3282,18 +3395,16 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
- 
-    } else {
- 
--      /* TW: 301BDH needs LVDS Data */
--      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
--          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-+      /* 301BDH needs LVDS Data */
-+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
- 	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
-       }
- 
-       SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                      &CRT2Index,&ResIndex,HwDeviceExtension);
- 
--      /* TW: 301BDH needs LVDS Data */
--      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
--          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-+      /* 301BDH needs LVDS Data */
-+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-               SiS_Pr->SiS_IF_DEF_LVDS = 0;
-       }
- 
-@@ -3321,11 +3432,16 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
- 	case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
- 	case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
- 	case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
-+	case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
-+	case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
-+	case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
-+	case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
-+	case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
- 	case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
-       	case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
-       	case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
-       	case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
--	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* TW: Super Overscan */
-+	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* Super Overscan */
- 	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-      }
-    }
-@@ -3337,67 +3453,36 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
--    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
--         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
--           SiS_Pr->SiS_HDE = 1024;
--           SiS_Pr->SiS_VDE =  768;
--         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
--           SiS_Pr->SiS_HDE = 1280;
--           SiS_Pr->SiS_VDE = 1024;
--	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
--           SiS_Pr->SiS_HDE = 1400;
--           SiS_Pr->SiS_VDE = 1050;
--	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
--           SiS_Pr->SiS_HDE = 1600;
--           SiS_Pr->SiS_VDE = 1200;
--         } else {
--	   SiS_Pr->SiS_HDE = 1280;
--	   SiS_Pr->SiS_VDE =  960;
--	 }
--    }
-+     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-+        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-+        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-+     }
- 
-   } else {
- 
--    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
--      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
--        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
--          if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
--            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--              SiS_Pr->SiS_HDE =  800;
--              SiS_Pr->SiS_VDE =  600;
--	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
--	      SiS_Pr->SiS_HDE = 1024;
--              SiS_Pr->SiS_VDE =  600;  
--            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--              SiS_Pr->SiS_HDE = 1024;
--              SiS_Pr->SiS_VDE =  768;
-- 	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
--	      SiS_Pr->SiS_HDE = 1152;
--	      SiS_Pr->SiS_VDE =  768;	
--	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
--	      SiS_Pr->SiS_HDE = 1152;
--	      SiS_Pr->SiS_VDE =  864;  
--	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
--	      SiS_Pr->SiS_HDE = 1280;
--	      SiS_Pr->SiS_VDE =  768;        
--            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--              SiS_Pr->SiS_HDE = 1280;
--              SiS_Pr->SiS_VDE = 1024;
--	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--	      SiS_Pr->SiS_HDE = 1400;
--              SiS_Pr->SiS_VDE = 1050;
--	    } else {
--	      SiS_Pr->SiS_HDE = 1600;
--	      SiS_Pr->SiS_VDE = 1200;
--	    }
--            if(SiS_Pr->SiS_IF_DEF_FSTN) {
--              SiS_Pr->SiS_HDE = 320;
--              SiS_Pr->SiS_VDE = 480;
--            }
--          }
-+     if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-+        if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
-+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-+              if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-+	         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
-+                 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-+
-+		 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-+		    if(ResIndex < 0x08) {
-+		       SiS_Pr->SiS_HDE = 1280;
-+                       SiS_Pr->SiS_VDE = 1024;
-+		    }
-+		 }
-+#if 0
-+                 if(SiS_Pr->SiS_IF_DEF_FSTN) {
-+                    SiS_Pr->SiS_HDE = 320;
-+                    SiS_Pr->SiS_VDE = 480;
-+                 }
-+#endif		 
-+              }
-+           }
-         }
--      }
--    }
-+     }
-   }
- }
- 
-@@ -3413,11 +3498,16 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
-   const SiS_TVDataStruct  *TVPtr  = NULL;
- 
-   if(ModeNo <= 0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-   } else {
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+	resinfo = 0;
-+     } else {
-     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+     }
-   }
-   
-   SiS_Pr->SiS_NewFlickerMode = 0;
-@@ -3429,20 +3519,29 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
- 
-   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
- 
--  /* TW: For VGA2 ("RAMDAC2") */
--
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
--     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
--                        HwDeviceExtension);
--     return;
--  }
- 
--  /* TW: For TV */
-+     if(SiS_Pr->UseCustomMode) {
- 
--  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        SiS_Pr->SiS_RVBHCMAX  = 1;
-+        SiS_Pr->SiS_RVBHCFACT = 1;
-+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
-+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
-+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
-+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
-+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
-+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
- 
--    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
--                   &CRT2Index,&ResIndex,HwDeviceExtension);
-+     } else {
-+
-+        SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-+                           HwDeviceExtension);
-+     }
-+
-+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+
-+    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-+                   &CRT2Index,&ResIndex,HwDeviceExtension);
- 
-     switch (CRT2Index) {
-       case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
-@@ -3452,7 +3551,7 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
-       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
-       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
-       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
--      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
-+      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* Just to avoid a crash */
-     }
- 
-     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
-@@ -3464,18 +3563,16 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
-     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
-     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
-     if(modeflag & HalfDCLK) {
--	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->HALFRVBHRS;
-+	SiS_Pr->SiS_RVBHRS     = (TVPtr+ResIndex)->HALFRVBHRS;
-     }
- 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
-     
-        if(SiS_Pr->SiS_HiVision != 3) {
--       
--      	  if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
--      	  if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
--	  if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
--	  
--       } 
-+      	  if(resinfo == SIS_RI_1024x768)  SiS_Pr->SiS_NewFlickerMode = 0x40;
-+      	  if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40;
-+	  if(resinfo == SIS_RI_1280x720)  SiS_Pr->SiS_NewFlickerMode = 0x40;
-+       }
-        
-        switch(SiS_Pr->SiS_HiVision) {
-        case 2:
-@@ -3504,119 +3601,127 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
- 
-     } else {
- 
--      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
--      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
--      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
--      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
--
--      if(modeflag & HalfDCLK) {
--         SiS_Pr->SiS_RY1COE = 0x00;
--         SiS_Pr->SiS_RY2COE = 0xf4;
--         SiS_Pr->SiS_RY3COE = 0x10;
--         SiS_Pr->SiS_RY4COE = 0x38;
--      }
--
--      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--        SiS_Pr->SiS_HT = NTSCHT;
--	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
--	   if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
--	}  
--        SiS_Pr->SiS_VT = NTSCVT;
--      } else {
--        SiS_Pr->SiS_HT = PALHT;
--        SiS_Pr->SiS_VT = PALVT;
--      }
-+       SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
-+       SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
-+       SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
-+       SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
-+
-+       if(modeflag & HalfDCLK) {
-+          SiS_Pr->SiS_RY1COE = 0x00;
-+          SiS_Pr->SiS_RY2COE = 0xf4;
-+          SiS_Pr->SiS_RY3COE = 0x10;
-+          SiS_Pr->SiS_RY4COE = 0x38;
-+       }
-+
-+       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+          SiS_Pr->SiS_HT = NTSCHT;
-+	  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+	     if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
-+	  }
-+          SiS_Pr->SiS_VT = NTSCVT;
-+       } else {
-+          SiS_Pr->SiS_HT = PALHT;
-+          SiS_Pr->SiS_VT = PALVT;
-+       }
- 
-     }
- 
--    return;
--  }
-+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+
-+     if(SiS_Pr->UseCustomMode) {
- 
--  /* TW: For LCD */
-+        SiS_Pr->SiS_RVBHCMAX  = 1;
-+        SiS_Pr->SiS_RVBHCFACT = 1;
-+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
-+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
-+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
-+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
-+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
-+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
- 
--  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+     } else {
- 
--    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
--                   &CRT2Index,&ResIndex,HwDeviceExtension);
-+        SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-+                      &CRT2Index,&ResIndex,HwDeviceExtension);
-+
-+        switch(CRT2Index) {
-+         case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
-+         case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
-+         case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
-+         case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
-+         case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
-+         case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
-+         case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
-+         case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
-+         case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
-+         case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
-+         case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
-+         case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
-+         case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
-+         case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
-+         case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
-+         case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
-+         case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
-+         case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
-+         case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;	          break; /* Generic no-scale data */
-+         default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	  break; /* Just to avoid a crash */
-+        }
-+
-+        SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-+        SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-+        SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-+        SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-+        SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-+        SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
- 
--    switch (CRT2Index) {
--      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
--      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
--      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
--      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
--      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
--      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
--      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
--      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
--      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
--      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
--      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
--      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing (let panel scale) */
--      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
--      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
--      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
--      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
--    }
--
--    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
--    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
--    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
--    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
--    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
--    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
--    
- #ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO,
--    	"GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
--#endif    
-+        xf86DrvMsg(0, X_INFO,
-+    	    "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
-+#endif
- 
--    tempax = 1024;
--    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
--      if(HwDeviceExtension->jChipType < SIS_315H) {
--         if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
--         else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
--         else                               tempbx = 768;
--      } else {      
--         tempbx = 768; 
--      }
--    } else {
--      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
--      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
--      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
--      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
--      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
--      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
--      else                               tempbx = 768;
--    }
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--      tempax = 1280;
--      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
--      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
--      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
--      else                               tempbx = 1024;
--    }
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
--      tempax = 1280;
--      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
--      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
--      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
--      else                                tempbx = 960;
--    }
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--      tempax = 1400;
--      tempbx = 1050;
--    }
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
--      tempax = 1600;
--      tempbx = 1200;
--    }
--    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--       tempax = SiS_Pr->SiS_VGAHDE;
--       tempbx = SiS_Pr->SiS_VGAVDE;
--    }
--    SiS_Pr->SiS_HDE = tempax;
--    SiS_Pr->SiS_VDE = tempbx;
--    return;
-+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+           tempax = 1024;
-+           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-+              if(HwDeviceExtension->jChipType < SIS_315H) {
-+                 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-+                 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-+                 else                               tempbx = 768;
-+              } else {
-+                 tempbx = 768;
-+              }
-+           } else {
-+              if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
-+              else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
-+              else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
-+              else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
-+              else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-+              else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-+              else                               tempbx = 768;
-+           }
-+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+           tempax = 1280;
-+           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
-+           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
-+           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
-+           else                               tempbx = 1024;
-+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-+           tempax = 1280;
-+           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
-+           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
-+           else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
-+           else                                tempbx = 960;
-+        } else {
-+	   tempax = SiS_Pr->PanelXRes;
-+           tempbx = SiS_Pr->PanelYRes;
-+	}
-+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-+           tempax = SiS_Pr->SiS_VGAHDE;
-+           tempbx = SiS_Pr->SiS_VGAVDE;
-+        }
-+        SiS_Pr->SiS_HDE = tempax;
-+        SiS_Pr->SiS_VDE = tempbx;
-+        return;
-+     }
-   }
- }
- 
-@@ -3626,9 +3731,9 @@ SiS_GetResInfo(SiS_Private *SiS_Pr, UCHA
-   USHORT resindex;
- 
-   if(ModeNo <= 0x13)
--    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+     resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-   else
--    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+     resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- 
-   return(resindex);
- }
-@@ -3639,41 +3744,46 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
- {
-   USHORT xres,yres,modeflag=0,resindex;
- 
-+  if(SiS_Pr->UseCustomMode) {
-+     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
-+     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
-+     return;
-+  }
-+
-   resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
- 
-   if(ModeNo <= 0x13) {
--    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
--    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
-+     xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-+     yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
-   } else {
--	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
--    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
--    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+     xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-+     yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
-+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-   }
- 
--  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
--      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
--          if(yres == 350) yres = 400;
--      }
--      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
-- 	  if(ModeNo == 0x12) yres = 400;
--      }
--  }
-+  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
-+
-+     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
-+        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-+           if(yres == 350) yres = 400;
-+        }
-+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
-+ 	   if(ModeNo == 0x12) yres = 400;
-+        }
-+     }
-+
-+     if(ModeNo > 0x13) {
-+  	if(modeflag & HalfDCLK)       xres *= 2;
-+  	if(modeflag & DoubleScanMode) yres *= 2;
-+     }
- 
--  if(ModeNo > 0x13) {
--      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
--            xres *= 2;
--            yres *= 2;
--      } else {
--  	    if(modeflag & HalfDCLK)       xres *= 2;
--  	    if(modeflag & DoubleScanMode) yres *= 2;
--      }
-   }
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-            if(xres == 720) xres = 640;
- 	} else {
--	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* TW: 301BDH */
-+	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
- 	        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                    if(xres == 720) xres = 640;
- 		}
-@@ -3694,9 +3804,8 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
- 	         if(xres == 720) xres = 640;
- 	      }
- 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+		 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- 		    if(ModeNo <= 0x13) {
--		       /* TW: This is wrong for 640x400 *graphics* mode */
-       		       if(yres == 400) yres = 405;
- 		    }
-       		    if(yres == 350) yres = 360;
-@@ -3719,12 +3828,15 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
-   } else {
-     	if(xres == 720) xres = 640;
- 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
--	      yres = 400;
--	      if(HwDeviceExtension->jChipType >= SIS_315H) {
--	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
--	      } else {
--	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
--	      }
-+	   yres = 400;
-+	   if(HwDeviceExtension->jChipType >= SIS_315H) {
-+	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-+	   } else {
-+	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-+	   }
-+	   if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
-+	      yres = 480;
-+	   }
- 	}
-   }
-   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
-@@ -3739,6 +3851,13 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
-   USHORT tempbx=0,tempal=0;
-   USHORT Flag,resinfo=0;
- 
-+  if(ModeNo <= 0x13) {
-+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-+  } else {
-+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+  }
-+
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
-     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
-@@ -3753,15 +3872,32 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
- 		        tempbx = 23;
- 			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
- 			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
-+#if 0
-+	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-+		        tempbx = 26;
-+			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 27;
-+			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
-+#endif
- 		} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--			tempbx = 13;
--			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
-+			if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+			   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 13;
-+			   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
-+			   else 							 tempbx = 29;
-+			} else {
-+			   tempbx = 29;
-+			   if(ModeNo >= 0x13) {
-+			      /* 1280x768 and 1280x960 have same CRT2CRTC,
-+			       * so we change it here if 1280x960 is chosen
-+			       */
-+			      if(resinfo == SIS_RI_1280x960) tempal = 10;
-+			   }
-+			}
- 		} else {
-       		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
-       		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-         		tempbx += 5;
-                         /* GetRevisionID();  */
--			/* TW: BIOS only adds 5 once */
-+			/* BIOS only adds 5 once */
-         		tempbx += 5;
-        		   }
- 	        }
-@@ -3783,34 +3919,18 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
- 		
-      	}
- 
--     	if(ModeNo <= 0x13) {
--       		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
--     	} else {
--       		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
--		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
--        }
--
--     	tempal &= 0x3F;
--
--      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
--           (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
--      		if(tempal == 0x06) tempal = 0x07;
--        }
--
--	/* TW: 300/301LV BIOS */
--	if((HwDeviceExtension->jChipType == SIS_300) &&
--	   (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
--	    if(ModeNo > 0x13) {
--	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 (index diff. on 310/325!) */
--		    tempal = 6;
--	    }
--	}
-+        tempal &= 0x3F;
- 
--	if(HwDeviceExtension->jChipType != SIS_300) {
--           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--              if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
-+      	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
-+	   if(ModeNo > 0x13) {
-+      	      if(tempal == 6) tempal = 7;
-+              if((resinfo == SIS_RI_720x480) ||
-+	         (resinfo == SIS_RI_720x576) ||
-+	         (resinfo == SIS_RI_768x576)) {
-+		 tempal = 6;
-+	      }
- 	   }
--	}
-+        }
- 
-      	*CRT2Index = tempbx;
-      	*ResIndex = tempal;
-@@ -3820,25 +3940,22 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
-     	Flag = 1;
-     	tempbx = 0;
-     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
--	
--      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
--        		Flag = 0;
--        		tempbx = 10;
--			if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
--        		if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--				tempbx += 2;
--				if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
--				if(SiS_Pr->SiS_CHPALM) {
--					tempbx = 90;
--					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
--				} else if(SiS_Pr->SiS_CHPALN) {
--					tempbx = 92;
--					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
--				}
--				
--			}
--      		}
--		
-+      	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-+              Flag = 0;
-+              tempbx = 10;
-+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-+              if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-+		 tempbx += 2;
-+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-+		 if(SiS_Pr->SiS_CHPALM) {
-+		    tempbx = 90;
-+		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-+		 } else if(SiS_Pr->SiS_CHPALN) {
-+		    tempbx = 92;
-+		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-+	 	 }
-+              }
-+           }
-     	}
- 
-     	if(Flag) {
-@@ -3846,11 +3963,19 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
- 		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
- 		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
-    	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
-+		   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-+		      tempbx = 82;
-+		      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-+		   }
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- 		   tempbx = 18;
- 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++; 
--	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { 
-+	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
- 		   tempbx = 6;
-+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
-+		   tempbx = 30;
-+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-+		   tempbx = 30;
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- 		   tempbx = 15;
-   		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
-@@ -3863,27 +3988,25 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- 		   tempbx = 21;
- 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
-+		   tempbx = 80;
-+   	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
- 		}
--		
-+
- 		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- 		   tempbx = 7;
-         	}
- 		
- 	}
- 
--    	if(ModeNo <= 0x13)
--      		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
--    	else {
--      		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
--		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
--	}
--
-+#if 0
- 	if(SiS_Pr->SiS_IF_DEF_FSTN){
-        	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-          		tempbx = 14;
-          		tempal = 6;
-         	}
-     	}
-+#endif	
- 
- 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- 	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
-@@ -3895,13 +4018,10 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
- 
- 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- 	    if(ModeNo > 0x13) {
--	        if(HwDeviceExtension->jChipType < SIS_315H) {
--	           if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
--		       tempal = 6;
--	        } else {
--		   if((resinfo == 0x0d) || (resinfo == 0x0e))  /* 720 */
--		       tempal = 6;
--		}
-+	       if((resinfo == SIS_RI_720x480) ||
-+	          (resinfo == SIS_RI_720x576) ||
-+		  (resinfo == SIS_RI_768x576))
-+		  tempal = 6;
- 	    }
- 	}
- 
-@@ -3969,8 +4089,9 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
-   USHORT RefreshRateTableIndex,i,backup_i;
-   USHORT modeflag,index,temp,backupindex;
- 
--  if(SiS_Pr->UseCustomMode) return 0;
--  
-+  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
-+  if(ModeNo == 0xfe) return 0;
-+
-   if(ModeNo <= 0x13)
-     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   else
-@@ -3984,7 +4105,7 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
- 
-   if(ModeNo < 0x14) return(0xFFFF);
- 
-- /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
-+ /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
-   *     On LVDS machines, CRT2 index is always 0 and will be
-   *     set to 0 by the following code; this causes the function
-   *     to take the first non-interlaced mode in SiS_Ext2Struct
-@@ -3998,40 +4119,38 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
-   if(index > 0) index--;
- 
-   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
--      } else {
-+     } else {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--	    if(SiS_Pr->SiS_VBType & VB_NoLCD)
--	       	    index = 0;
--	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
--	    	    index = backupindex = 0;
-+	   if(SiS_Pr->SiS_VBType & VB_NoLCD)
-+	      index = 0;
-+	   else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
-+	      index = backupindex = 0;
- 	}
--      }
--  }
-+     }
- 
--  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
--    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
--      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--        		index = 0;
--      		}
--    	}
--    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
--      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--			if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
--           		   temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
--        		   if(index > temp) index = temp;
--			}
--      		} else {
--        		index = 0;
--      		}
--    	}
-+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+           index = 0;
-+        }
-+     }
-+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-+        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+	   if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
-+              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
-+              if(index > temp) index = temp;
-+	   }
-+      	} else {
-+           index = 0;
-+      	}
-+     }
-   }
- 
-   RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-   ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
- 
--  /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
-+  /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
-         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
-@@ -4066,7 +4185,7 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
-     	backup_i = i;
-     	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
- 	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
--		/* TW: This is for avoiding random data to be used; i is
-+		/* This is for avoiding random data to be used; i is
- 		 *     in an undefined state if no matching CRT2 mode is
- 		 *     found.
- 		 */
-@@ -4085,196 +4204,199 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
-   USHORT tempax,tempbx,resinfo;
-   USHORT modeflag,infoflag;
- 
--  if (ModeNo <= 0x13)
-+  if(ModeNo <= 0x13) {
-     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--  else
-+	resinfo = 0;
-+  } else {
-     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+        resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+  }
- 
--  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-   tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
- 
-   tempax = 0;
-+
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+
-     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-       		tempax |= SupportRAMDAC2;
- 		if(HwDeviceExtension->jChipType >= SIS_315H) {
--		    tempax |= SupportTV;
--		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--			    if(resinfo == 0x0a) tempax |= SupportTV1024;
--			}
--		    }
-+		   tempax |= SupportTV;
-+		   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+		      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+			 if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024;
-+		      }
-+		   }
- 		}
--    	}
--    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-+    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-       		tempax |= SupportLCD;
- 		if(HwDeviceExtension->jChipType >= SIS_315H) {
-                    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
- 		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
--		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-+		         if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- 			    (*i) = 0;
-                             return(1);
- 		         } else {
-       		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
--        		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
--           			if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
--				    return(0);
--				} else {
--             			    if((resinfo >= 9) && (resinfo != 0x14)) {
-+        		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-+           			  if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-+				     return(0);
-+				  } else {
-+             			     if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) {
-                				return(0);
--             			    }
--           			}
--        		      }
-+             			     }
-+           			  }
-+        		       }
- 		            }
- 		         }
- 		      }
-       		   }
- 		} else {
- 		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
--		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
-+		     if( (resinfo != SIS_RI_1024x600) &&
-+		         ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
--		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
-+		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
--		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
-+		     if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--		     if(resinfo > 9) return(0);
-+		     if(resinfo > SIS_RI_1280x1024) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--		     if(resinfo > 8) return(0);
-+		     if(resinfo > SIS_RI_1024x768) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--		     if((resinfo == 4) || (resinfo > 7)) return(0);
-+		     if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0);
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
--		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
-+		     if((resinfo == SIS_RI_512x384) ||
-+		        (resinfo == SIS_RI_400x300) ||
-+			(resinfo > SIS_RI_640x480)) return(0);
- 		  }
- 		}
--    	}
--    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { 
-+    	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
- 	        if(SiS_Pr->SiS_HiVision == 3) {
- 		      	tempax |= SupportHiVisionTV2;
-       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
--        			if(resinfo == 4) return(0);
--        			if(resinfo == 3) return(0);
--				if(resinfo == 7) {
-+        			if(resinfo == SIS_RI_512x384) return(0);
-+        			if(resinfo == SIS_RI_400x300) return(0);
-+				if(resinfo == SIS_RI_800x600) {
- 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
-         			}
--        			if(resinfo > 7) return(0);
-+        			if(resinfo > SIS_RI_800x600) return(0);
- 			}
- 		} else {  
-       			tempax |= SupportHiVisionTV;
-       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
--        			if(resinfo == 4) return(0);
--        			if((resinfo == 3) || (resinfo == 7)) {
-+        			if(resinfo == SIS_RI_512x384) return(0);
-+        			if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) {
- 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
-         			}
--        			if(resinfo > 7) return(0);
-+        			if(resinfo > SIS_RI_800x600) return(0);
- 			}
- 		}
--    	} else {
--      	   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
-+    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
-         	tempax |= SupportTV;
- 		tempax |= SupportTV1024;
- 		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
--			     if(resinfo != 8) {
--			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
--				     tempax &= ~(SupportTV1024);
--				     if(HwDeviceExtension->jChipType >= SIS_315H) {
--                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
--			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
--		                             }
--				         }
--		                     } else {
--				         if( (resinfo != 3) ||
--					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
--					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--						     if(resinfo == 3) return(0);
--						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
--						 }
--		                             }
--                                         } else return(0);
--				     }
--				 }
--			     }
--			} else {
--			    tempax &= ~(SupportTV1024);
--			    if(HwDeviceExtension->jChipType >= SIS_315H) {
--			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-+		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+		      if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+		         if(resinfo != SIS_RI_1024x768) {
-+			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) {
-+			       tempax &= ~(SupportTV1024);
-+			       if(HwDeviceExtension->jChipType >= SIS_315H) {
-+                                  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+			             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+			                 ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
- 			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
--		                    }
--		                }
--			    } else {
--			        if( (resinfo != 3) ||
--				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
--				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--					     if(resinfo == 3) return(0);
--					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
--					 }
- 		                     }
--                                } else return(0);
--                            }
--			}
--		    } else {  /* slavemode */
--			if(resinfo != 8) {
--			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
--				 tempax &= ~(SupportTV1024);
--				 if(HwDeviceExtension->jChipType >= SIS_315H) {
--				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
--			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
--		                         }
-+				  }
-+		               } else {
-+				  if( (resinfo != SIS_RI_400x300) ||
-+				      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+				      (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-+				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+					if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+					   if(resinfo == SIS_RI_400x300) return(0);
-+					   if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-+					}
- 		                     }
--			        } else {
--				    if( (resinfo != 3) ||
--				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
--				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--					         if(resinfo == 3) return(0);
--					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
--					     }
--		                         }
--                                    } else return(0);
--				}
-+                                  } else return(0);
-+			       }
- 			    }
--			}
--		    }
--		} else {   /* 301 */
--		    tempax &= ~(SupportTV1024);
--		    if(HwDeviceExtension->jChipType >= SIS_315H) {
--		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
--			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
--			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
--		            }
--		        }
--		    } else {
--		        if( (resinfo != 3) ||
--			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
--			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--				    if(resinfo == 3) return(0);
--				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
--				}
-+			 }
-+		      } else {
-+			 tempax &= ~(SupportTV1024);
-+			 if(HwDeviceExtension->jChipType >= SIS_315H) {
-+			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+			       if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+			           ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
-+			          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-+		               }
- 		            }
--                        } else return(0);
--		    }
--		}
--           }
--    	}
--	
--  } else {	/* TW: for LVDS  */
-+			 } else {
-+			    if( (resinfo != SIS_RI_400x300) ||
-+			        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+				(SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-+			       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+				  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+				     if(resinfo == SIS_RI_400x300) return(0);
-+				     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-+				  }
-+		               }
-+                            } else return(0);
-+                         }
-+		      }
-+		   } else {  /* slavemode */
-+		      if(resinfo != SIS_RI_1024x768) {
-+			 if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+			     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
-+			    tempax &= ~(SupportTV1024);
-+			    if(HwDeviceExtension->jChipType >= SIS_315H) {
-+			       if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+			          if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+			              ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
-+			             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
-+		                  }
-+		               }
-+			    } else {
-+			       if( (resinfo != SIS_RI_400x300) ||
-+			           (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+			           (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-+			          if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+				        if(resinfo == SIS_RI_400x300) return(0);
-+				        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-+				     }
-+		                  }
-+                               } else return(0);
-+			    }
-+		  	 }
-+		      }
-+		   }
-+	        } else {   /* 301 */
-+		   tempax &= ~(SupportTV1024);
-+		   if(HwDeviceExtension->jChipType >= SIS_315H) {
-+		      if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+		         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-+		             ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
-+		            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-+		         }
-+		      }
-+		   } else {
-+		      if( (resinfo != SIS_RI_400x300) ||
-+			  (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+			  (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-+		         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+			       if(resinfo == SIS_RI_400x300) return(0);
-+			       if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-+			    }
-+		         }
-+                      } else return(0);
-+		   }
-+	        }
-+        }
-+
-+  } else {	/* for LVDS  */
- 
-     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-       		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-@@ -4284,24 +4406,29 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
-     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       		tempax |= SupportLCD;
- 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
--		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
-+		     if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0);
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
--		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
-+		     if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768))  return(0);
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
--		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
-+		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768))   return(0);
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
-+		     if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0);
-+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-+                     if(resinfo > SIS_RI_1600x1200) return(0);
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--                     if(resinfo > 0x09) return(0);
-+                     if(resinfo > SIS_RI_1280x1024) return(0);
-                 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--		     if(resinfo > 0x08) return(0);
-+		     if(resinfo > SIS_RI_1024x768)  return(0);
- 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
--		     if(resinfo > 0x07) return(0);
--		     if(resinfo == 0x04) return(0);
-+		     if(resinfo > SIS_RI_800x600)   return(0);
-+		     if(resinfo == SIS_RI_512x384)  return(0);
-+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
-+                     if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0);
- 		}
-     	}
-   }
--  /* TW: Look backwards in table for matching CRT2 mode */
-+  
-+  /* Look backwards in table for matching CRT2 mode */
-   for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
-      	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-      	if(infoflag & tempax) {
-@@ -4309,7 +4436,7 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
-      	}
-      	if ((*i) == 0) break;
-   }
--  /* TW: Look through the whole mode-section of the table from the beginning
-+  /* Look through the whole mode-section of the table from the beginning
-    *     for a matching CRT2 mode if no mode was found yet.
-    */
-   for((*i) = 0; ; (*i)++) {
-@@ -4329,7 +4456,7 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, US
- {
-   USHORT temp1,temp2;
- 
--  /* TW: We store CRT1 ModeNo in CR34 */
-+  /* We store CRT1 ModeNo in CR34 */
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
-   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
-   temp2 = ~(SetInSlaveMode >> 8);
-@@ -4345,16 +4472,16 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-   USHORT modeflag, resinfo=0;
-   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
- 
--  if(SiS_Pr->UseCustomMode) {
--        modeflag = SiS_Pr->CModeFlag;
-+  if(ModeNo <= 0x13) {
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   } else {
--    if (ModeNo <= 0x13)
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--    else {
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+     } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
--    }
--  }    
-+     }
-+  }
- 
-   SiS_Pr->SiS_SetFlag = 0;
- 
-@@ -4364,22 +4491,24 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-   if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {  
-     	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
- #if 0	
--	/* SiS_HiVision is only used on 310/325/330+30xLV */
-+	/* SiS_HiVision is only used on 315/330+30xLV */
- 	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
--	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/30xLV 1.10.6s */
-+	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* New from 650/30xLV 1.10.6s */
- 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
- 	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
- 	   }
--	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/30xLV 1.10.6s */
-+	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* New from 650/30xLV 1.10.6s */
- 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
- 	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
- 	   }
- 	}
--#endif	
-+#endif
-+#if 0
-     	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
-        		temp = (SetCRT2ToLCD | SetSimuScanMode);
-        		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
-     	}
-+#endif	
-     	tempbx |= temp;
-     	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
-         tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
-@@ -4519,7 +4648,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-       		tempbx |= SetSimuScanMode;
-     	}
- 
--	/* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
-+	/* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
- 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
- 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
- 	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
-@@ -4527,12 +4656,12 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
- 	   }
- 	}
- 	
--    	if(!(tempbx & SetSimuScanMode)){
-+    	if(!(tempbx & SetSimuScanMode)) {
-       	    if(tempbx & SwitchToCRT2) {
-         	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
- 		     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
- 			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
--			 if(resinfo != 0x0a)
-+			 if(resinfo != SIS_RI_1600x1200)
-                               tempbx |= SetSimuScanMode;
- 		     } else {
-             		      tempbx |= SetSimuScanMode;
-@@ -4555,7 +4684,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-           	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
- 	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
- 			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
--			     if(resinfo != 0x0a) {  /* TW: 650/301 BIOS */
-+			     if(resinfo != SIS_RI_1600x1200) {  /* 650/301 BIOS */
- 			          tempbx |= SetInSlaveMode;
-             		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-               		 	     if(tempbx & SetCRT2ToTV) {
-@@ -4563,7 +4692,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
- 					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
-               			     }
-                                   }
--			     }                      /* TW: 650/301 BIOS */
-+			     }                      /* 650/301 BIOS */
- 		        } else {
-             		    tempbx |= SetInSlaveMode;
-             		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-@@ -4621,7 +4750,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-      	if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
- 		    OutputSelect = ROMAddr[0xf3];
--		    if(HwDeviceExtension->jChipType == SIS_330) {
-+		    if(HwDeviceExtension->jChipType >= SIS_330) {
- 			OutputSelect = ROMAddr[0x11b];
- 		    }
-                 }
-@@ -4652,7 +4781,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
-   SiS_Pr->SiS_VBInfo = tempbx;
- 
-   if(HwDeviceExtension->jChipType == SIS_630) {
--       SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
-+       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
-   }
- 
- #ifdef TWDEBUG
-@@ -4666,61 +4795,35 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
- #endif
- #endif
- 
--#if 0  /* TW: Incomplete! (But does not seem to be required) */
--  if(HwDeviceExtension->jChipType < SIS_315H) {
--     /* TW: From A901/630+301B BIOS */
--     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
--     }
--     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
--         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
--	     if( [si] == 3) ModeIdIndex = 0x3f2b;
--	 }
--     }
--     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
--     if(ModeNo == 0x13) bp+4 = 0x03;
--  } else {
--     /* From 650/30xLV BIOS: */
--     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
--     if(ModeNo == 0x13) bp+4 = 0x03;
--     else bp+4 = ModeNo;
--  }
--#endif
--
--  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
--
- }
- 
-+/* Setup general purpose IO for Chrontel communication */
- void
--SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
-+SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
- {
--   unsigned long eax, temp;
--   unsigned short temp1;
-+   unsigned long  acpibase;
-+   unsigned short temp;
- 
-    if(!(SiS_Pr->SiS_ChSW)) return;
- 
- #ifndef LINUX_XF86
--   SiS_SetReg4(0xcf8,0x80000874);
--   eax = SiS_GetReg3(0xcfc);
-+   SiS_SetReg4(0xcf8,0x80000874);		   /* get ACPI base */
-+   acpibase = SiS_GetReg3(0xcfc);
- #else
--   eax = pciReadLong(0x00000800, 0x74);
-+   acpibase = pciReadLong(0x00000800, 0x74);
- #endif
--   eax &= 0xFFFF;
--   temp = eax;
--   eax += 0x3c;
--   temp1 = SiS_GetReg4((USHORT)eax);
--   temp1 &= 0xFEFF;
--   SiS_SetReg5((USHORT)eax, temp1);
--   temp1 = SiS_GetReg4((USHORT)eax);
--   eax = temp;
--   eax += 0x3a;
--   temp1 = SiS_GetReg4((USHORT)eax);
--   temp1 &= 0xFEFF;
-+   acpibase &= 0xFFFF;
-+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
-+   temp &= 0xFEFF;
-+   SiS_SetReg5((USHORT)(acpibase + 0x3c), temp);
-+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));
-+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
-+   temp &= 0xFEFF;
-    if(!(myvbinfo & SetCRT2ToTV)) {
--      temp1 |= 0x0100;
-+      temp |= 0x0100;
-    }
--   SiS_SetReg5((USHORT)eax, temp1);
--   temp1 = SiS_GetReg4((USHORT)eax);
-+   SiS_SetReg5((USHORT)(acpibase + 0x3a), temp);
-+   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));
- }
- 
- void
-@@ -4731,14 +4834,14 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
-   USHORT temp1=0,modeflag=0,tempcx=0;
-   USHORT StandTableIndex,CRT1Index;
- #ifdef SIS315H   
--  USHORT ResInfo,DisplayType,temp=0;
-+  USHORT ResIndex,DisplayType,temp=0;
-   const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
- #endif
- 
-   SiS_Pr->SiS_RVBHCMAX  = 1;
-   SiS_Pr->SiS_RVBHCFACT = 1;
- 
--  if(ModeNo <= 0x13){
-+  if(ModeNo <= 0x13) {
- 
-     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-@@ -4752,7 +4855,7 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
- 
- #ifdef SIS315H     
-     	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
--			RefreshRateTableIndex,&ResInfo,&DisplayType);
-+			RefreshRateTableIndex,&ResIndex,&DisplayType);
- 
-     	if(temp == 0)  return;
- 
-@@ -4795,16 +4898,16 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
- 		case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
- 		default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-     	}
--	tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
--	tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
-+	tempax = (LVDSCRT1Ptr+ResIndex)->CR[0];
-+	tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8;
- 	tempax &= 0x03FF;
--    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
--    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
-+    	tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6];
-+    	tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8;
-     	tempcx &= 0x0100;
-     	tempcx <<= 2;
-     	tempbx |= tempcx;
--	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
--#endif	
-+	temp1  = (LVDSCRT1Ptr+ResIndex)->CR[7];
-+#endif
- 
-     } else {
- 
-@@ -4840,11 +4943,12 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
-   if(modeflag & Charx8Dot) tempax *= 8;
-   else                     tempax *= 9;
- 
--  /* TW: From 650/30xLV 1.10.6s */
-+  /* From 650/30xLV 1.10.6s */
-   if(modeflag & HalfDCLK)  tempax <<= 1;
- 
--  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
-   tempbx++;
-+
-+  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
-   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
- }
- 
-@@ -4852,18 +4956,18 @@ void
- SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
- {
-   if(HwDeviceExtension->jChipType >= SIS_315H)
--    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
-+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
-   else
--    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
-+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
- }
- 
- void
- SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
- {
-   if(HwDeviceExtension->jChipType >= SIS_315H)
--    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
-+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
-   else
--     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
-+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
- }
- 
- void
-@@ -4872,7 +4976,6 @@ SiS_EnableCRT2(SiS_Private *SiS_Pr)
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
- }
- 
--/* Checked against all BIOSes */
- void
- SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
- {
-@@ -4882,9 +4985,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
-   USHORT temp=0;
-   UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
- 
--  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
--      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
-+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
- 
-         if(HwDeviceExtension->jChipType < SIS_315H) {
- 
-@@ -4940,9 +5043,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
-         } else {
- 
--#ifdef SIS315H	   /* 310/325 series */
-+#ifdef SIS315H	   /* 315 series */
- 
--           if(IS_SIS650740) {		/* 650, 740 */
-+           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
- 
- #if 0
- 	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-@@ -4966,22 +5069,35 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 	         SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
- 
-                  pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
--		 
-+
- 		 if(IS_SIS740) {
- 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
- 		 }
- 
- 	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
--		 
--		 if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	            tempah = 0xef;
--	            if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	               tempah = 0xf7;
--                    }
--	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-+
-+		 if(!(IS_SIS740)) {
-+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	               tempah = 0xef;
-+	               if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+	                  tempah = 0xf7;
-+                       }
-+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-+		    }
- 	         }
- 
--              }
-+              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-+	         if(HwDeviceExtension->jChipType == SIS_650) {
-+	            if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
-+	            }
-+		    if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-+		       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-+	     	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-+	            }
-+		    SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3);
-+		 }
-+	      }
- 
-               if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
- 	         tempah = 0x3f;
-@@ -5046,8 +5162,8 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- 
--		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    /* 1.10.8r */
--		 
-+		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    		/* 1.10.8r, 8m */
-+
- 	         tempah = 0x3f;
- 	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
- 	            tempah = 0x7f;
-@@ -5057,9 +5173,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 	         }
- 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- 
--		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r */
-+		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r, 8m */
- 	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
--		 }								/* 1.10.8r */
-+		 }								/* 1.10.8r, 8m */
- 
- 	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-@@ -5075,81 +5191,33 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
- 
--  	      }
--
--#if 0
--          } else if(IS_SIS740) {	/* 740 */
--	  
--	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* 30xLV */
--	     
--	        if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
--		    (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
--	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
--	        }
--		
--		SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-+  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-+	         if(HwDeviceExtension->jChipType == SIS_650) {
-+		    if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-+		       (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
-+		       if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-+		          (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
-+			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
-+	     	          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
-+			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
-+	               }
-+		    }
-+		 }
-+	      } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-+	         if(HwDeviceExtension->jChipType == SIS_650) {
-+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	               tempah = 0xef;
-+	               if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+		          if(modenum > 0x13) {
-+	                     tempah = 0xf7;
-+			  }
-+                       }
-+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-+		    }
-+		 }
-+	      }
- 
--                pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
--		
--		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
--
--	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
--		
--		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--		   SiS_DisplayOff(SiS_Pr);
--	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
--	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
--	           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
--		} else {
--		   SiS_DisplayOff(SiS_Pr);
--	           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
--	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
--	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
--	           temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
--                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
--	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
--	           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
--		}
--		
--		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
--		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF);  /* (from 650) */
--		
--		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
--		
--		if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
--	        }
--		
--		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--		   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	              if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
--	                 if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--		            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
--                         }
--                      }
--	           }
--		}
--	        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
--	     
--	     } else {	/* (301,) 301B */
--	  
--	        if(SiS_Is301B(SiS_Pr,BaseAddr)) {
--	           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
--	        }
--	     
--	        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
--	        SiS_DisplayOff(SiS_Pr);
--	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
--	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
--
--	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
--                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
--	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
--	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
--		
--	     }
--#endif	  
--	  } else {			/* 315, 330 - all bridge types */
-+	  } else {			/* 315, 330 - all bridge types */
- 
- 	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
- 	        tempah = 0x3f;
-@@ -5193,13 +5261,13 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	}
- 
--      } else {     /* ============ TW: For 301 ================ */
-+      } else {     /* ============ For 301 ================ */
- 
-         if(HwDeviceExtension->jChipType < SIS_315H) {
--            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
--                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
--	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
--	    }
-+            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-+	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-+	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-+	   }
- 	}
- 
-         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
-@@ -5218,18 +5286,23 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
- 	} else {
-             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
-+	    if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
-+	        (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
-+		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
-+	    }
- 	}
- 
-       }
- 
--  } else {     /* ============ TW: For LVDS =============*/
-+  } else {     /* ============ For LVDS =============*/
- 
-     if(HwDeviceExtension->jChipType < SIS_315H) {
- 
- #ifdef SIS300	/* 300 series */
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
--	    SiS_SetCH700x(SiS_Pr,0x090E);
-+	   SiS_SetCH700x(SiS_Pr,0x090E);
- 	}
- 
- 	if(HwDeviceExtension->jChipType == SIS_730) {
-@@ -5245,17 +5318,17 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-   
--  	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-+  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
- 
--                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-+                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
- 
--		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
--		         SiS_DisplayOff(SiS_Pr);
--	             }
-+		    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
-+		        SiS_DisplayOff(SiS_Pr);
-+	            }
- 
--	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
--	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
--                  }
-+	            SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-+	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-+                 }
-               }
- 	   }
- 	}
-@@ -5279,29 +5352,40 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
-     } else {
- 
--#ifdef SIS315H	/* 310/325 series */
-+#ifdef SIS315H	/* 315 series */
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
--		temp = SiS_GetCH701x(SiS_Pr,0x61);
--		if(temp < 1) {
--		   SiS_SetCH701x(SiS_Pr,0xac76);
--		   SiS_SetCH701x(SiS_Pr,0x0066);
--		}
--		
--		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+
-+		if(HwDeviceExtension->jChipType == SIS_740) {
-+		   temp = SiS_GetCH701x(SiS_Pr,0x61);
-+		   if(temp < 1) {
-+		      SiS_SetCH701x(SiS_Pr,0xac76);
-+		      SiS_SetCH701x(SiS_Pr,0x0066);
-+		   }
-+
-+		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 			SiS_SetCH701x(SiS_Pr,0x3e49);
--		} else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-+		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
- 			SiS_SetCH701x(SiS_Pr,0x3e49);
-+		   }
- 		}
--		
-+
- 		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 			SiS_Chrontel701xBLOff(SiS_Pr);
--			SiS_Chrontel701xOff(SiS_Pr);
-+			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
- 		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
- 			SiS_Chrontel701xBLOff(SiS_Pr);
--			SiS_Chrontel701xOff(SiS_Pr);
-+			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
- 		}
--		
-+
-+		if(HwDeviceExtension->jChipType != SIS_740) {
-+		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+			SiS_SetCH701x(SiS_Pr,0x0149);
-+		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-+			SiS_SetCH701x(SiS_Pr,0x0149);
-+		   }
-+		}
-+
- 	}
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-@@ -5325,6 +5409,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- 	}
- 
-+	if(HwDeviceExtension->jChipType == SIS_740) {
-+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-+	}
-+
- 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-@@ -5337,15 +5425,27 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- 	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
--			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-+		   if(HwDeviceExtension->jChipType == SIS_550) {
-+		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
-+		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
-+		   }
-+		}
-+	} else {
-+	   if(HwDeviceExtension->jChipType == SIS_740) {
-+	        if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
- 		}
--	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-+	   } else {
-+	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-+	        }
-+	   }
- 	}
- 
- 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- 	    	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
-+			/* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
- 		} else {
- 			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
- 		}
-@@ -5353,7 +5453,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- 	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
- 
--	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-+	if(HwDeviceExtension->jChipType == SIS_550) {
-+	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
-+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
-+	} else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
- 	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
-@@ -5361,7 +5464,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
- 	}
- 
--#if 0  /* TW: BIOS code makes no sense */
-+#if 0  /* BIOS code makes no sense */
-        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-            if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 	        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-@@ -5387,7 +5490,6 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
- 
- }
- 
--/* TW: Checked against all BIOSes */
- void
- SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
- {
-@@ -5400,7 +5502,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
- 
--    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
-+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
- 
-       if(HwDeviceExtension->jChipType < SIS_315H) {
- 
-@@ -5497,9 +5599,9 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 
-       } else {
- 
--#ifdef SIS315H    /* 310/325 series */
-+#ifdef SIS315H    /* 315 series */
- 
--	 if(IS_SIS650740) {		/* 650 */
-+	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
- 
- #if 0
- 	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-@@ -5541,7 +5643,32 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 		  delaylong = TRUE;
- 	       }
- 
--	    }
-+	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-+	       if(HwDeviceExtension->jChipType == SIS_650) {
-+	          if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
-+	          }
-+		  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-+		      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-+		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
-+		  }
-+	       }
-+  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-+
-+	         if(HwDeviceExtension->jChipType == SIS_650) {
-+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	               tempah = 0x10;
-+		       if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
-+		          tempah = 0x18;
-+		          if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
-+			     tempah = 0x08;
-+			  }
-+		       }
-+	               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-+		    }
-+		 }
-+	      }
- 
- 	    if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-                temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-@@ -5595,11 +5722,24 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);	/* All this from 1.10.7u */
- 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
- 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
--	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);  
--	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);  
--	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);  
--	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
--	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
-+
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
-+	       if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) {
-+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
-+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
-+	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40);
-+		  if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) {
-+		     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
-+	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
-+	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33);  /* 00 */
-+		  }
-+	       }
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-+	       if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
-+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
-+	       }
- 	       
- 	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
- 	    
-@@ -5610,127 +5750,44 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
- 	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
--		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
--		    if(delaylong) {
-+		     SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-+		     if(delaylong) {
- 			SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
--		    }
--                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
--		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
--	         }
--	      }
-+		     }
-+                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-+		     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-+	          }
-+	       }
- 
--	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
--	      SiS_DisplayOn(SiS_Pr);
--	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
-+	       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-+	       SiS_DisplayOn(SiS_Pr);
-+	       SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
- 
--	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
--	      }
-+	       }
- #if 0
--              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
--	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
--	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
--	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
--	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
--	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
--	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
--	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
-+               SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
-+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
- #endif	      
-+	    } if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-+	       if(HwDeviceExtension->jChipType == SIS_650) {
-+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+		     if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-+		         (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-+			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-+		     }
-+		  }
-+	       }
-+  	    }
- 
--	  }
--
--#if 0
--         } else if(IS_SIS740) {		/* 740 */
--	 
--	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* 30xLV */
--	   
--	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
--	      SiS_DisplayOff(SiS_Pr);
--	      pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
--	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
--	      
--	      if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
--	          (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
--                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
--		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
--	              SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
--		   }
--	      }
--	      
--	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
--	         if(SiS_BridgeInSlave(SiS_Pr)) {
--                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
--                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
--                 }
--                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
--
--	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);  	
--		 SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
--	      }
--	      
--	      if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
--	      }
--	      
--	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
--	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
--	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10);  /* (taken from 650 1.10.8r) */
--	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
--	      
--	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	         if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
--	             (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
--		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
--		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
--		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
--		    }
--		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
--		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
--		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
--	         }
--              }
--	      
--	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
--	      SiS_DisplayOn(SiS_Pr);
--	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
--	      
--	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
--	      }
--	   
--	   } else {	/* (301), 301B */
--	 
--	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
--	         if(SiS_BridgeInSlave(SiS_Pr)) {
--                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
--                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
--                 }
--                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
--
--	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
--
--	         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
--                 if(!(temp & 0x80))
--                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
--              }
--
--	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
--
--	      if(SiS_Is301B(SiS_Pr,BaseAddr)) { 
--	         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
--	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
--	      } else {
--	         SiS_VBLongWait(SiS_Pr);
--                 SiS_DisplayOn(SiS_Pr);
--	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
--                 SiS_VBLongWait(SiS_Pr);
--	      }
--	      
--	   }
--#endif
--	  
- 	 } else {			/* 315, 330 */
- 
- 	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-@@ -5782,11 +5839,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 
-       }
- 
--    } else {	/* ============  TW: For 301 ================ */
-+    } else {	/* ============  For 301 ================ */
- 
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
--                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
-+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
- 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
- 	    }
-        }
-@@ -5818,13 +5875,13 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
- 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
--                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
-+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
- 	    }
-        }
- 
-     }
- 
--  } else {   /* =================== TW: For LVDS ================== */
-+  } else {   /* =================== For LVDS ================== */
- 
-     if(HwDeviceExtension->jChipType < SIS_315H) {
- 
-@@ -5875,7 +5932,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 
-     } else {
- 
--#ifdef SIS315H    /* 310/325 series */
-+#ifdef SIS315H    /* 315 series */
- 
- #if 0  /* BIOS code makes no sense */
-        if(SiS_IsVAMode()) {
-@@ -5902,36 +5959,41 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
- 	  SiS_Chrontel701xBLOff(SiS_Pr);
-        }
- 
--       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
--       
--#ifdef NEWCH701x
--       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
--           if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
-+       if(HwDeviceExtension->jChipType != SIS_550) {
-+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-+       }
-+
-+       if(HwDeviceExtension->jChipType == SIS_740) {
-+          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-+             if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
- 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
--	   }
-+	     }
-+	  }
-        }
--#endif       
- 
-        temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
--       if (!(temp1 & 0x80))
-+       if(!(temp1 & 0x80))
-            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
- 
-        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-            if(temp) {
--	       SiS_Chrontel701xBLOn(SiS_Pr);
-+	       SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
- 	   }
-        }
- 
-        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
- 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-+		if(HwDeviceExtension->jChipType == SIS_550) {
-+		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
-+		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
-+		}
-+	   }
-+       } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+           if(HwDeviceExtension->jChipType != SIS_740) {
-+              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
- 	   }
--       } 
--#ifndef NEWCH701x       
--         else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-        }
--#endif       
- 
-        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-@@ -5954,10 +6016,10 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
-        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-        	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-  	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	            		SiS_Chrontel701xBLOn(SiS_Pr);
-+	            		SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
- 	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
-            		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
--       				SiS_Chrontel701xBLOn(SiS_Pr);
-+       				SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
-        				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
- 	   		}
-        		}
-@@ -5983,7 +6045,7 @@ SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS
- {
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
- 
--  /* TW: Switch on LCD backlight on SiS30xLV */
-+  /* Switch on LCD backlight on SiS30xLV */
-   if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-     if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-@@ -6001,7 +6063,7 @@ SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSI
- {
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
- 
--  /* TW: Switch off LCD backlight on SiS30xLV */
-+  /* Switch off LCD backlight on SiS30xLV */
-   if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
- 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-@@ -6023,12 +6085,14 @@ SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr,
-   UCHAR *ROMAddr;
- 
-   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
--     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
--     temp >>= 4;
--     temp = 1 << temp;
--     temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
--     if(temp1 & temp) return(1);
--     else return(0);
-+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-+        temp >>= 4;
-+        temp = 1 << temp;
-+        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
-+        if(temp1 & temp) return(1);
-+        else return(0);
-+     } else return(0);
-   } else {
-      return(0);
-   }
-@@ -6041,12 +6105,14 @@ SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr,
-   UCHAR *ROMAddr;
- 
-   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
--     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
--     temp >>= 4;
--     temp = 1 << temp;
--     temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
--     if(temp1 & temp) return(1);
--     else return(0);
-+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-+        temp >>= 4;
-+        temp = 1 << temp;
-+        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
-+        if(temp1 & temp) return(1);
-+        else return(0);
-+     } else return(0);
-   } else {
-      return(0);
-   }
-@@ -6143,7 +6209,7 @@ SiS_SetPanelDelay(SiS_Private *SiS_Pr, U
- 
- #ifdef SIS315H
- 
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
-+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS */
- 
-           if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-               PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-@@ -6171,7 +6237,7 @@ SiS_SetPanelDelay(SiS_Private *SiS_Pr, U
- 	      SiS_ShortDelay(SiS_Pr,Delay);
- 	  }
- 
--      } else {							/* 310/325 series, 301(B) */
-+      } else {							/* 315 series, 301(B) */
- 
-           PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
- 	  DelayIndex = PanelID >> 4;
-@@ -6271,14 +6337,7 @@ SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_H
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-      if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
--#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
--     else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--       if(flag) return(1);
--       else     return(0);   			         
--     }
--#endif
--     else
--       return(0);
-+     else return(0);
-   } else
- #endif
-      return(0);
-@@ -6325,7 +6384,9 @@ SiS_IsNotM650or651(SiS_Private *SiS_Pr, 
-   if(HwDeviceExtension->jChipType == SIS_650) {
-      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
-      flag &= 0xF0;
--     if((flag == 0xb0) || (flag == 0x90)) return 0;
-+     /* Check for revision != A0 only */
-+     if((flag == 0xe0) || (flag == 0xc0) ||
-+        (flag == 0xb0) || (flag == 0x90)) return 0;
-      else return 1;
-   } else
- #endif
-@@ -6443,7 +6504,7 @@ SiS_BridgeIsEnable(SiS_Private *SiS_Pr, 
-       if((flag == 0x80) || (flag == 0x20)) return 0;
-       else	                           return 1;
-     } else {
--      /* 310/325 series (650/30xLV 1.10.6s) */
-+      /* 315 series (650/30xLV 1.10.6s) */
-       flag &= 0x50;
-       if((flag == 0x40) || (flag == 0x10)) return 0;
-       else                                 return 1;
-@@ -6493,8 +6554,8 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
- {
-   USHORT temp,modeflag,resinfo=0;
-   const unsigned char SiS300SeriesLCDRes[] =
--         { 0, 1, 2, 3, 7, 4, 5, 8,
--	   0, 0, 0, 0, 0, 0, 0, 0 };
-+         { 0,  1,  2,  3,  7,  4,  5,  8,
-+	   0,  0, 10,  0,  0,  0,  0, 15 };
- 
-   SiS_Pr->SiS_LCDResInfo = 0;
-   SiS_Pr->SiS_LCDTypeInfo = 0;
-@@ -6517,11 +6578,13 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
- 
-   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
- 
-+#if 0
-   /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
-   if(SiS_Pr->SiS_IF_DEF_FSTN) {
-    	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
-    	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
-   }
-+#endif
- 
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-   	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
-@@ -6530,14 +6593,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
-   }
-   temp &= 0x0f;
-   if(HwDeviceExtension->jChipType < SIS_315H) {
--      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
-+      /* Translate 300 series LCDRes to 315 series for unified usage */
-       temp = SiS300SeriesLCDRes[temp];
-   }
-   SiS_Pr->SiS_LCDResInfo = temp;
- 
-+#if 0
-   if(SiS_Pr->SiS_IF_DEF_FSTN){
-        	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
-   }
-+#endif
- 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-     	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
-@@ -6547,75 +6612,109 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
- 		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
-   }
- 
--  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
-+  if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
-+     if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
-   	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
-+  }
-+
-+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-+     SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
-+  }
-+
-+  switch(SiS_Pr->SiS_LCDResInfo) {
-+     case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
-+     case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
-+     case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
-+     case Panel_640x480_3:
-+     case Panel_640x480_2:
-+     case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
-+     case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
-+     case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
-+     case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
-+     case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
-+     case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
-+     case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
-+     case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
-+     case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
-+     case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
-+    			   SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
-+			   break;
-+     case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
-+     default:		   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
-+  }
- 
-   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-+#if 0
-   if(SiS_Pr->SiS_IF_DEF_FSTN){
--        /* TW: Fake LVDS bridge for FSTN */
-+        /* Fake LVDS bridge for FSTN */
-       	temp = 0x04;
-       	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
-   }
-+#endif
-   SiS_Pr->SiS_LCDInfo = temp;
-   
-   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- 
--  /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
-+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+        /* For non-standard LCD resolution, we let the panel scale */
-+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
-+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
-+	      /* Bridge does not scale to 1280x960 */
-+              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+	   } else if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
-+	      if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-+	         /* Bridge does not scale to 640x400 */
-+	         SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+	      }
-+	   }
-+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-+           /* TEMP - no idea about the timing and zoom factors */
-+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-+	   if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-+	      /* Bridge does not scale to 1280x1024 */
-+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+	   }
-+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-+	   /* TEMP - no idea about the timing and zoom factors */
-+	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-+	}
-+     }
-+  }
-+
-+
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
- #ifdef SIS315H
--     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
--		     /* Bridge does not scale to 1280x1024 */
--		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
--		 }
--	     }
--	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--	         if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
--		     /* TW: Bridge does not scale to 1280x960 */
--		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
--		 }
--		 if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
--		     /* TW: Bridge does not scale to 640x400 */
--		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
--		 }
--	     }
--	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--	         if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
--		     /* TW: Most panels can't scale to 640x400 */
--		     SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
--		 }
--	     }
--	 }
--     }
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
--         SiS_Pr->SiS_LCDInfo &= 0xFFEF;    
--	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
-+        SiS_Pr->SiS_LCDInfo &= 0xFFEF;
-+	SiS_Pr->SiS_LCDInfo |= LCDPass11;
-      }
- #endif
-   } else {
- #ifdef SIS300
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if((ROMAddr) && SiS_Pr->SiS_UseROM) {
--           if(!(ROMAddr[0x235] & 0x02)) {
--	      SiS_Pr->SiS_LCDInfo &= 0xEF;
-+	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-+              if(!(ROMAddr[0x235] & 0x02)) {
-+	         SiS_Pr->SiS_LCDInfo &= 0xEF;
-+ 	      }
- 	   }
-         }
--     } else {
--        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--	   if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
--               SiS_Pr->SiS_LCDInfo &= 0xEF;
--	   }
-+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
-+           SiS_Pr->SiS_LCDInfo &= 0xEF;
- 	}
-      }
- #endif
-   }
--  
--  /* TW: With Trumpion, always Expanding */
--  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
--       SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
-+
-+  /* Trumpion: Assume non-expanding */
-+  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-+     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
-   }
- 
-   if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
-@@ -6624,7 +6723,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- 	   if(ModeNo > 0x13) {
- 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
--                 if((resinfo == 7) || (resinfo == 3)) {
-+                 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
-                     SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- 		 }
-               }
-@@ -6644,9 +6743,9 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
- 	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
-                  if(ModeNo > 0x13) {
-                     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
-+                       if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-                     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
--                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
-+                       if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-                     }
-                  }
- 	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-@@ -6665,19 +6764,21 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
-   }
- 
- #ifdef SIS315H
--  /* TW: 650/30xLV 1.10.6s */
-+  /* 650/30xLV 1.10.6s */
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--    if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
--      /* Enable 302B/302LV dual link mode */
--      /* (302B is a theory - not in any BIOS */
--      temp = 0x00;
--      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
--      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
--      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
--      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
--    } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
--    }
-+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
-+        if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
-+           /* Enable 302B/302LV dual link mode.
-+            * (302B is a theory - not in any BIOS)
-+	    */
-+           if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-+              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-+              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-+	      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
-+	   }
-+  	}
-+     }
-   }
- #endif
- 
-@@ -6697,19 +6798,6 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
- }
- 
- void
--SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
--{
--  return;
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
--  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
--}
--
--void
- SiS_LongWait(SiS_Private *SiS_Pr)
- {
-   USHORT i;
-@@ -6803,7 +6891,7 @@ SiS_WaitRetrace1(SiS_Private *SiS_Pr, PS
- #endif
-   } else {
- #ifdef SIS300
--#if 0  /* TW: Not done in A901 BIOS */
-+#if 0  /* Not done in A901 BIOS */
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-      }
-@@ -6898,7 +6986,51 @@ void SiS_SetRegOR(USHORT Port,USHORT Ind
- 
- /* ========================================================= */
- 
--/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
-+static void
-+SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
-+{
-+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-+           if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);   /* 48 */
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);   /* de */
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-+	      if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
-+	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14);
-+	      } else {
-+	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15);
-+	      }
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b);
-+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-+           }
-+        } else {
-+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21);
-+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a);
-+	}
-+     }
-+  }
-+}
-+
-+/* Set 301 TV Encoder (and some LCD relevant) registers */
- void
- SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
-               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-@@ -6911,67 +7043,46 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
- #ifdef SIS315H   
-   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
-   USHORT      resindex, CRT2Index;
--#endif  
-+#endif
-   USHORT      modeflag, resinfo, crt2crtc;
--  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
-+  ULONG       longtemp, tempeax;
-+#ifdef SIS300
-   const UCHAR atable[] = {
-                  0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
- 	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
-   };
-+#endif  
- 
- #ifdef SIS315H   
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
--     /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
-+     /* 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
--	   temp = 1;
--	   if(ModeNo <= 0x13) temp = 3;
-+	   temp = 0x01;
-+	   if(ModeNo <= 0x13) temp = 0x03;
- 	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
- 	}
-      }
--     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
--               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
--           }
--         }
--       }
--     }
-+     SiS_SetTVSpecial(SiS_Pr, ModeNo);
-      return;
-   }
--#endif  
-+#endif
- 
--  if(ModeNo<=0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
--    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
--    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-+  if(ModeNo <= 0x13) {
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-   } else {
--    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+	resinfo = 0;
-+	crt2crtc = 0;
-+     } else {
-+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-     	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-+     }
-   }
- 
-   tempcx = SiS_Pr->SiS_VBInfo;
-@@ -6984,9 +7095,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   temp |= ((tempbx & 0x00FF) >> 3);
-   temp ^= 0x0C;
- 
--  /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
-+  /* From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
-   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--  	temp |= 0x0c;
-+     temp |= 0x0c;
-   }
- 
-   PhasePoint  = SiS_Pr->SiS_PALPhase;
-@@ -6994,44 +7105,44 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          
-   
--    temp ^= 0x01;
--    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
--      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
--        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
--      }
--    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
--    
--    if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
--    
-+     temp ^= 0x01;
-+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
-+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-+           if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-+           else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
-+        }
-+     } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
-+
-+     if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
-+
-   } else {
--  
--    if(SiS_Pr->SiS_VBInfo & SetPALTV){
- 
--      TimingPoint = SiS_Pr->SiS_PALTiming;
--      PhasePoint  = SiS_Pr->SiS_PALPhase;
-+     if(SiS_Pr->SiS_VBInfo & SetPALTV){
- 
--      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
--          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
--         PhasePoint = SiS_Pr->SiS_PALPhase2;
--      }
-+        TimingPoint = SiS_Pr->SiS_PALTiming;
-+        PhasePoint  = SiS_Pr->SiS_PALPhase;
- 
--    } else {
-+        if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-+            ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-+           PhasePoint = SiS_Pr->SiS_PALPhase2;
-+        }
-+
-+     } else {
- 
-         temp |= 0x10;
--	TimingPoint = SiS_Pr->SiS_NTSCTiming;
--	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
-+        TimingPoint = SiS_Pr->SiS_NTSCTiming;
-+        PhasePoint  = SiS_Pr->SiS_NTSCPhase;
- 
-         if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
- 	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
- 	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
--        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
-+           PhasePoint = SiS_Pr->SiS_NTSCPhase2;
-         }
- 
--    }
--    
-+     }
-+
-   }
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
- 
-@@ -7044,36 +7155,35 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-      temp = 0x38;
-   }
-   if(temp) {
--    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
--          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
--          if(temp1 & EnablePALM) {	/* 0x40 */
--              	PhasePoint = SiS_Pr->SiS_PALMPhase;
--		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
--		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
--	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
--		}
--	  }
--          if(temp1 & EnablePALN) {	/* 0x80 */
--               	PhasePoint = SiS_Pr->SiS_PALNPhase;
--		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
--		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
--		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
--	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
--		}
--	  }
--      }
--    }
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-+           temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
-+           if(temp1 & EnablePALM) {	/* 0x40 */
-+              PhasePoint = SiS_Pr->SiS_PALMPhase;
-+	      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-+	         PhasePoint = SiS_Pr->SiS_PALMPhase2;
-+	      }
-+	   }
-+           if(temp1 & EnablePALN) {	/* 0x80 */
-+              PhasePoint = SiS_Pr->SiS_PALNPhase;
-+	      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-+	         PhasePoint = SiS_Pr->SiS_PALNPhase2;
-+	      }
-+	   }
-+        }
-+     }
-   }
- 
- #ifdef SIS315H
--  /* TW: 650/301LV BIOS */
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-            if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-+              if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
- 	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
- 	      }
-            }
-@@ -7094,12 +7204,12 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   }
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--    if(HwDeviceExtension->jChipType >= SIS_315H) {
--      if(!(SiS_Pr->SiS_ModeType & 0x07))
-+     if(HwDeviceExtension->jChipType >= SIS_315H) {
-+        if(!(SiS_Pr->SiS_ModeType & 0x07))
-+           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-+     } else {
-         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
--    } else {
--      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
--    }
-+     }
-   }
- 
-   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
-@@ -7110,11 +7220,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
--      if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
--      else tempax = 440;
-+     if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
-+     else tempax = 440;
-   } else {
--    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
--    else tempax = 440;
-+     if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
-+     else tempax = 440;
-   }
- 
-   if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
-@@ -7134,18 +7244,18 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
- 
-      if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
--        (SiS_Pr->SiS_HiVision != 3) &&
--        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
-+         (SiS_Pr->SiS_HiVision != 3) &&
-+         (SiS_Pr->SiS_VGAHDE >= 1024) ) {
-         if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
-            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
-         } else {
-            if(HwDeviceExtension->jChipType >= SIS_315H) {
--             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
--             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
- 	   } else {
--             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
--             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
- 	   }
-         }
-      }
-@@ -7154,7 +7264,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
- 
-   tempcx = SiS_Pr->SiS_HT;
- 
--  /* TW: 650/30xLV 1.10.6s */
-+  /* 650/30xLV 1.10.6s */
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-       	   tempcx >>= 1;
-@@ -7181,7 +7291,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   tempcx += 7;
-   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3)) {
--       tempcx -= 4;
-+     tempcx -= 4;
-   }
-   temp = (tempcx & 0x00FF) << 4;
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
-@@ -7201,8 +7311,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   tempbx += 8;
-   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3)) {
--    tempbx -= 4;
--    tempcx = tempbx;
-+     tempbx -= 4;
-+     tempcx = tempbx;
-   }
-   temp = (tempbx & 0x00FF) << 4;
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
-@@ -7231,8 +7341,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
- 
-   tempcx -= 11;
-   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
--    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
--    tempcx = tempax;
-+     tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
-+     tempcx = tempax;
-   }
-   temp = tempcx & 0x00FF;
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
-@@ -7242,38 +7352,38 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
-   if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
-   if(HwDeviceExtension->jChipType < SIS_315H) {
--  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
-   } else {
--	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
--	   tempbx >>= 1;
--	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--	      if(ModeNo <= 0x13) {
--	         if(crt2crtc == 1) {
--	            tempbx++;
--                 }
--	      }
--	   } else {
--              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
--                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
--	      }
-+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-+	tempbx >>= 1;
-+	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-+	   if(ModeNo <= 0x13) {
-+	      if(crt2crtc == 1) {
-+	         tempbx++;
-+              }
- 	   }
--        }
-+	} else {
-+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+	      if(crt2crtc == 4)   /* BIOS calls GetRatePtrCRT2 here - does not make sense */
-+                 if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
-+	   }
-+	}
-+     }
-   }
-   tempbx -= 2;
-   temp = tempbx & 0x00FF;
-   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3)) {
--    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--      if(ModeNo == 0x2f) temp++;
--    }
-+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+        if(ModeNo == 0x2f) temp++;
-+     }
-   }
--  /* TW: From 1.10.7w - doesn't make sense */
-+  /* From 1.10.7w - doesn't make sense */
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
- 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
--	       if(ModeNo == 0x03) temp++;
-+	      if(ModeNo == 0x03) temp++;
- 	   }
- 	}
-      }
-@@ -7285,15 +7395,15 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   tempax |= (tempbx & 0xFF00);
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
--        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
-+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* New from 630/301B (II) BIOS */
-            tempax |= 0x1000;
-            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
-         }
-      }
-   } else {
-      /* TODO Check this with other BIOSes */
--     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) && 
--        (SiS_Pr->SiS_HiVision == 3)) {
-+     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV))
-+         /* && (SiS_Pr->SiS_HiVision == 3) */ ) {
- 	tempax |= 0x1000;
-         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
-      }
-@@ -7301,12 +7411,12 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   temp = (tempax & 0xFF00) >> 8;
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
- 
--  /* TW: 650/30xLV 1.10.6s */
-+  /* 650/30xLV 1.10.6s */
-   if(HwDeviceExtension->jChipType > SIS_315H) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
--            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
-+           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
-         }
-      }
-   }
-@@ -7322,79 +7432,70 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-      }
-   }
- 
--  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {     
--    tempbx = SiS_Pr->SiS_VDE;
--    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
--         tempbx >>= 1;
--    }
--    tempbx -= 3;
--    tempbx &= 0x03ff;
--    temp = ((tempbx & 0xFF00) >> 8) << 5;
--    temp |= 0x18;
--    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
--    temp = tempbx & 0x00FF;
--    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
--    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: 650/30xLV 1.10.6s */
--       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--          tempax = 0;
--          if(SiS_Pr->SiS_HiVision & 0x03) {
--	     tempax = 0x3000;
--	     if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
--	  }
--	  temp = (tempax & 0xFF00) >> 8;
--          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
--       }
--    }
-+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+     tempbx = SiS_Pr->SiS_VDE;
-+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-+        tempbx >>= 1;
-+     }
-+     tempbx -= 3;
-+     tempbx &= 0x03ff;
-+     temp = ((tempbx & 0xFF00) >> 8) << 5;
-+     temp |= 0x18;
-+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
-+     temp = tempbx & 0x00FF;
-+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
-+     if(HwDeviceExtension->jChipType >= SIS_315H) {
-+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+           tempax = 0;
-+           if(SiS_Pr->SiS_HiVision & 0x03) {
-+ 	      tempax = 0x3000;
-+	      if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
-+	   }
-+	   temp = (tempax & 0xFF00) >> 8;
-+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
-+        }
-+     }
-   }
- 
-   tempbx &= 0x00FF;
-   if(!(modeflag & HalfDCLK)) {
--    tempcx = SiS_Pr->SiS_VGAHDE;
--    if(tempcx >= SiS_Pr->SiS_HDE) {
--      tempbx |= 0x2000;
--      tempax &= 0x00FF;
--    }
-+     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
-+        tempbx |= 0x2000;
-+        tempax &= 0x00FF;
-+     }
-   }
- 
-   tempcx = 0x0101;
--/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /*301b- TW: BIOS BUG? */
-+/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /* BIOS BUG? */
-   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
--    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
--      if(SiS_Pr->SiS_VGAHDE >= 1024) {
--        if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {   /* TW: This check not in 630/301B */
--          tempcx = 0x1920;
--          if(SiS_Pr->SiS_VGAHDE >= 1280) {
--            tempcx = 0x1420;
--            tempbx &= 0xDFFF;
--          }
-+     if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
-+           if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {
-+              tempcx = 0x1920;
-+              if(SiS_Pr->SiS_VGAHDE >= 1280) {
-+                 tempcx = 0x1420;
-+                 tempbx &= 0xDFFF;
-+              }
-+           }
-         }
--      }
--    }
-+     }
-   }
- 
-   if(!(tempbx & 0x2000)) {
--    if(modeflag & HalfDCLK) {
--         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
--    }
--    push1 = tempbx;
--    tempeax = SiS_Pr->SiS_VGAHDE;
--    tempebx = (tempcx & 0xFF00) >> 8;
--    longtemp = tempeax * tempebx;
--    tempecx = tempcx & 0x00FF;
--    longtemp /= tempecx;
--    longtemp <<= 0x0d;
--    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+     if(modeflag & HalfDCLK) {
-+        tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
-+     }
-+     longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
-+     longtemp <<= 13;
-+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      	longtemp <<= 3;
--    }
--    tempecx = SiS_Pr->SiS_HDE;
--    temp2 = longtemp % tempecx;
--    tempeax = longtemp / tempecx;
--    if(temp2 != 0) tempeax++;
--    tempax = (USHORT)tempeax;
--    tempbx = push1;
--    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
--    tempbx |= (tempax & 0x1F00);
--    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
-+     }
-+     tempeax = longtemp / SiS_Pr->SiS_HDE;
-+     if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
-+     tempax = (USHORT)tempeax;
-+     tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5));
-+     tempbx |= (tempax & 0x1F00);
-+     tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
-   }
- 
-   temp = (tempax & 0xFF00) >> 8;
-@@ -7403,33 +7504,32 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
- 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--       temp = tempcx & 0x00FF;
--       if(tempbx & 0x2000) temp = 0;
--       temp |= 0x18;
--       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
--       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--             tempbx = 0x0382;  
--             tempcx = 0x007e;  
--       } else {
--             tempbx = 0x0369;  
--             tempcx = 0x0061;  
--       }
--       temp = (tempbx & 0x00FF) ;
--       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
--       temp = (tempcx & 0x00FF) ;
--       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
--       tempbx &= 0x03FF;
--       temp = (tempcx & 0xFF00) >> 8;
--       temp = (temp & 0x0003) << 2;
--       temp |= (tempbx >> 8);
--       if(HwDeviceExtension->jChipType < SIS_315H) {
--          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
--       } else {
--          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
--       }
-+     temp = tempcx & 0x00FF;
-+     if(tempbx & 0x2000) temp = 0;
-+     temp |= 0x18;
-+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
-+
-+     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-+        tempbx = 0x0382;
-+        tempcx = 0x007e;
-+     } else {
-+        tempbx = 0x0369;
-+        tempcx = 0x0061;
-+     }
-+     temp = (tempbx & 0x00FF) ;
-+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
-+     temp = (tempcx & 0x00FF) ;
-+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
-+     temp = (tempcx & 0x0300) >> (8 - 2);
-+     temp |= ((tempbx >> 8) & 0x03);
-+     if(HwDeviceExtension->jChipType < SIS_315H) {
-+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
-+     } else {
-+        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
-+     }
- 
--       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
--       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
-+     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
-+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
-   }
- 
-   temp = 0;
-@@ -7440,23 +7540,33 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-      temp = 0x38;
-   }
-   if(temp) {
--      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
--               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
--                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
--                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
--                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
--               }
--          }
--      }
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-+           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
-+              SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
-+              temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
-+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
-+           }
-+        }
-+     }
-+  }
-+
-+  if(HwDeviceExtension->jChipType >= SIS_315H) {
-+     if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
-+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
-+        }
-+     }
-   }
- 
-+#if 0  /* Old: Why HiVision? */
-   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-       (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
--    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
--    }
-+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
-+     }
-   }
-+#endif
- 
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-@@ -7465,74 +7575,43 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
- 	return;
-      }
-   } else {
--     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
-+     /* !!! The following is a duplicate, done for LCDA as well (see above) */
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    
--         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
--               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
--	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
--	     }
--           }
--         }
--       }
--       return;
-+        SiS_SetTVSpecial(SiS_Pr, ModeNo);
-+        return;
-      }
-   }
- 
--  /* TW: From here: Part2 LCD setup */
-+  /* From here: Part2 LCD setup */
- 
-   tempbx = SiS_Pr->SiS_HDE;
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--      /* TW: 650/30xLV 1.10.6s */
--      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
-+     /* 650/30xLV 1.10.6s */
-+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
-   }
-   tempbx--;			         	/* RHACTE=HDE-1 */
-   temp = tempbx & 0x00FF;
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
--  temp = (tempbx & 0xFF00) >> 8;
--  temp <<= 4;
-+  temp = (tempbx & 0xFF00) >> 4;
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
- 
-   temp = 0x01;
-   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--    if(SiS_Pr->SiS_ModeType == ModeEGA) {
--      if(SiS_Pr->SiS_VGAHDE >= 1024) {
--        temp = 0x02;
--	if(HwDeviceExtension->jChipType >= SIS_315H) {
--           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
--             temp = 0x01;
-+     if(SiS_Pr->SiS_ModeType == ModeEGA) {
-+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
-+           temp = 0x02;
-+	   if(HwDeviceExtension->jChipType >= SIS_315H) {
-+              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-+                 temp = 0x01;
-+	      }
- 	   }
--	}
--      }
--    }
-+        }
-+     }
-   }
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
- 
--  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
--  push1 = tempbx;
--
-+  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO = VDE - 1 */
-+  /* push1 = tempbx; */
-   tempbx--;
-   temp = tempbx & 0x00FF;
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
-@@ -7540,10 +7619,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
- 
-   tempcx = SiS_Pr->SiS_VT;
--  push2 = tempcx;
--
-+  /* push2 = tempcx; */
-   tempcx--;
--  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
-+  temp = tempcx & 0x00FF;  			 /* RVTVT = VT - 1 */
-   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
- 
-   temp = (tempcx & 0xFF00) >> 8;
-@@ -7551,30 +7629,26 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   
-   /* Enable dithering; newer versions only do this for 32bpp mode */
-   if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
--    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
-+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
-   } else if(HwDeviceExtension->jChipType < SIS_315H) {
--    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
--    else {
--      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
--         temp |= 0x10;
--    }
-+     temp |= 0x10;
-   } else {
--      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--         /* TW: 650/30xLV 1.10.6s */
--         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
--            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
--      	       temp |= 0x10;
--	    }
--         }
--      } else {
--         temp |= 0x10;
--      }
-+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+        /* 650/30xLV 1.10.6s */
-+        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-+           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
-+              temp |= 0x10;
-+	   }
-+        }
-+     } else {
-+        temp |= 0x10;
-+     }
-   }
- 
-   /* 630/301 does not do all this */
-   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-      if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
--        /* TW: 650/30xLV 1.10.6s */
-+        /* 650/30xLV 1.10.6s */
-         temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
- 	temp |= 0x08;   					/* From 1.10.7w */
- 	if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
-@@ -7595,17 +7669,15 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
-   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
- 
--  /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
--  if((HwDeviceExtension->jChipType >= SIS_315H)             && 
--     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)                &&  
--     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
--     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
--     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
-+  /* much data invalid/missing in tables, use old calculation in such case */
-+  if((HwDeviceExtension->jChipType >= SIS_315H)         &&
-+     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
-+     ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
-+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) ) {
-      
--#ifdef SIS315H 							/* ------------- 310/325/330 series ------------ */
-+#ifdef SIS315H 							/* ------------- 315/330 series ------------ */
- 
--      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
--      
-       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
-        * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
-        * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
-@@ -7664,7 +7736,6 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
- 	}
-      }
- 
--     /* TW: 650/30xLV 1.10.6s: */
-      /* !!! This is a duplicate, done for LCDA as well - see above */
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-@@ -7683,15 +7754,12 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-        * the bridge scales all modes to 1024.
-        * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
-        */
--  
-+
-+    /* cx = VT - 1 */
-+
-     tempcx++;
--    
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx =  768;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
--    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
--    else if(SiS_Pr->SiS_VDE != 1024) 				  tempbx =  960;
--    else            						  tempbx = 1024;
--    
-+
-+    tempbx = SiS_Pr->PanelYRes;
- #if 0  /* old */
-     tempbx = 768;
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-@@ -7706,36 +7774,40 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-       }
-     }
- #endif
--    
-+
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
--      tempbx = SiS_Pr->SiS_VDE - 1;
--      tempcx--;
-+       tempbx = SiS_Pr->SiS_VDE - 1;
-+       tempcx--;
-     }
--    
-+
-     tempax = 1;
-     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
--      if(tempbx != SiS_Pr->SiS_VDE) {
--        tempax = tempbx;
--/*	if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60;   in 650/301B BIOS */
--        if(tempax < SiS_Pr->SiS_VDE) {
--          tempax = 0;
--          tempcx = 0;
--        } else {
--          tempax -= SiS_Pr->SiS_VDE;
--        }
--        tempax >>= 1;
--      }
--      tempcx -= tempax; /* lcdvdes */
--      tempbx -= tempax; /* lcdvdee */
--    } else {
--      tempax >>= 1;
--      tempcx -= tempax; /* lcdvdes */
--      tempbx -= tempax; /* lcdvdee */
-+       if(tempbx != SiS_Pr->SiS_VDE) {
-+          tempax = tempbx;
-+          if(tempax < SiS_Pr->SiS_VDE) {
-+             tempax = 0;
-+             tempcx = 0;
-+          } else {
-+             tempax -= SiS_Pr->SiS_VDE;
-+          }
-+          tempax >>= 1;
-+       }
-+       tempcx -= tempax; /* lcdvdes */
-+       tempbx -= tempax; /* lcdvdee */
-     }
--    
-+#if 0  /* meaningless: 1 / 2 = 0... */
-+    else {
-+       tempax >>= 1;
-+       tempcx -= tempax; /* lcdvdes */
-+       tempbx -= tempax; /* lcdvdee */
-+    }
-+#endif
-+
-+    /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
-+
- #ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
--#endif    
-+    xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
-+#endif
- 
-     temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
-@@ -7746,140 +7818,183 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
-     temp |= ((tempcx & 0xFF00) >> 8);
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
- 
--    tempbx = push2;
--    tempax = push1;
--    tempcx = tempbx;
--    tempcx -= tempax;
--    tempcx >>= 4;
-+    tempbx = SiS_Pr->SiS_VT;    /* push2; */
-+    tempax = SiS_Pr->SiS_VDE;   /* push1; */
-+    tempcx = (tempbx - tempax) >> 4;
-     tempbx += tempax;
-     tempbx >>= 1;
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx -= 10;
--    
-+
-+    /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
-+
-+    if(SiS_Pr->UseCustomMode) {
-+       tempbx = SiS_Pr->CVSyncStart;
-+    }
-+
- #ifdef TWDEBUG
-     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
- #endif
- 
--    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
-+    temp = tempbx & 0x00FF;   				/* RTVACTEE = lcdvrs */
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
- 
-     temp = ((tempbx & 0xFF00) >> 8) << 4;
-     tempbx += (tempcx + 1);
-     temp |= (tempbx & 0x000F);
-+
-+    if(SiS_Pr->UseCustomMode) {
-+       temp &= 0xf0;
-+       temp |= (SiS_Pr->CVSyncEnd & 0x0f);
-+    }
-+
-+#ifdef TWDEBUG
-+    xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
-+#endif
-+
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
- 
--    /* TW: Code from 630/301B (I+II) BIOS */
-+    /* Code from 630/301B (I+II) BIOS */
- 
--    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
--            (HwDeviceExtension->jChipType == SIS_730) ) &&
--          (HwDeviceExtension->jChipRevision > 2) )  &&
--        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
--        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
--        (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
--            if(ModeNo == 0x13) {
--              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
--              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
--              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
--            } else {
--              if((crt2crtc & 0x3F) == 4) {
-+    if(!SiS_Pr->UseCustomMode) {
-+       if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
-+               (HwDeviceExtension->jChipType == SIS_730) ) &&
-+             (HwDeviceExtension->jChipRevision > 2) )  &&
-+           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
-+           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
-+           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-+          if(ModeNo == 0x13) {
-+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
-+          } else {
-+             if((crt2crtc & 0x3F) == 4) {
-                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
-                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
-                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
-                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
-                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
--              }
--            }
-+             }
-+          }
-+       }
-     }
- 
--    /* TW: Inserted missing code from 630/301B BIOS;
-+    /* Inserted missing code from 630/301B BIOS;
-      *     Strangely, this is done in all 650 BIOSes as
-      *     well (although LCDTypeInfo is not used there
-      *     in the same way as on 300 series)
-      */
-+#ifdef SIS300
-+    if(HwDeviceExtension->jChipType < SIS_315H) {
-+       if(!SiS_Pr->UseCustomMode) {
-+          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
-+             crt2crtc &= 0x1f;
-+             tempcx = 0;
-+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+                   tempcx += 7;
-+                }
-+             }
-+             tempcx += crt2crtc;
-+             if(crt2crtc >= 4) {
-+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
-+             }
- 
--    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
--         crt2crtc &= 0x1f;
--         tempcx = 0;
--         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
--           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--              tempcx += 7;
--           }
--         }
--         tempcx += crt2crtc;
--         if (crt2crtc >= 4) {
--           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
--         }
--
--         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
--           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--             if(crt2crtc == 4) {
--                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
-+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+                   if(crt2crtc == 4) {
-+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
-+                   }
-+                }
-              }
--           }
--         }
--         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
--         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
-+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
-+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
-+          }
-+       }
-     }
-+#endif
- 
--    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
-+    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
-     tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--         tempbx += 2;
-+       tempbx += 2;
-     }
-     push1 = tempbx;
-+
- #ifdef TWDEBUG
--    xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
--#endif    
--    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
-+    xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
-+#endif
-+
-+    temp = tempbx & 0x00FF;    			          /* RHEQPLE = lcdhdee */
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
-     temp = (tempbx & 0xFF00) >> 8;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
- 
-     temp = 7;
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--         temp += 2;
-+       temp += 2;
-     }
--    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes[7:0] */
-+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE = lcdhdes[7:0] */
-     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);	  /* lcdhdes [11:8] */
- 
-     tempbx += tempcx;
-     push2 = tempbx;
-+
-+    if(SiS_Pr->UseCustomMode) {
-+       tempbx = SiS_Pr->CHSyncStart + 7;
-+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+          tempbx += 2;
-+       }
-+    }
-+
- #ifdef TWDEBUG
-     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
- #endif
--    temp = tempbx & 0x00FF;            		          /* RHBURSTS=lcdhrs */
--    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 
--          if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
-+
-+    temp = tempbx & 0x00FF;            		          /* RHBURSTS = lcdhrs */
-+    if(!SiS_Pr->UseCustomMode) {
-+       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-+             if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
-+          }
-        }
-     }
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
--    temp = ((tempbx & 0xFF00) >> 8) << 4;
-+    temp = (tempbx & 0x0F00) >> 4;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
- 
-     tempbx = push2;
-     tempcx <<= 1;
-     tempbx += tempcx;
-+
-+    if(SiS_Pr->UseCustomMode) {
-+       tempbx = SiS_Pr->CHSyncEnd + 7;
-+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+          tempbx += 2;
-+       }
-+    }
-+
- #ifdef TWDEBUG
-     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
--#endif    
--    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
-+#endif
-+
-+    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S = lcdhre */
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
- 
-     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
--      if(SiS_Pr->SiS_VGAVDE == 525) {
--        if(SiS_Pr->SiS_ModeType <= ModeVGA)
--    	   temp=0xC6;
--        else
--       	   temp=0xC3;
--        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
--        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
--      } else if(SiS_Pr->SiS_VGAVDE == 420) {
--        if(SiS_Pr->SiS_ModeType <= ModeVGA)
--	   temp=0x4F;
--        else
--       	   temp=0x4D;   
--        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
--      }
-+       if(SiS_Pr->SiS_VGAVDE == 525) {
-+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
-+    	     temp=0xC6;
-+          else
-+       	     temp=0xC3;
-+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
-+       } else if(SiS_Pr->SiS_VGAVDE == 420) {
-+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
-+	     temp=0x4F;
-+          else
-+       	     temp=0x4D;
-+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-+       }
-     }
-     SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
-                         RefreshRateTableIndex, BaseAddr, ModeNo);
-@@ -7898,7 +8013,7 @@ SiS_GetVGAHT2(SiS_Private *SiS_Pr)
-   return((USHORT) tempax);
- }
- 
--/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
-+/* New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
- void
- SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-     			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-@@ -7910,18 +8025,19 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr,
- 
-   if(HwDeviceExtension->jChipType != SIS_300) return;
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
-+  if(SiS_Pr->UseCustomMode) return;
- 
--  if(ModeNo<=0x13) {
--    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-+  if(ModeNo <= 0x13) {
-+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-   } else {
--    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-+     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-   }
- 
-   resindex = crt2crtc & 0x3F;
-   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
- 
--  /* TW: The BIOS code (1.16.51) is obviously a fragment! */
-+  /* The BIOS code (1.16.51) is obviously a fragment! */
-   if(ModeNo > 0x13) {
-      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-      resindex = 4;
-@@ -7942,7 +8058,6 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr,
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
- }
- 
--/* TW: Set 301 Macrovision(tm) registers */
- void
- SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-@@ -7954,24 +8069,35 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHOR
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
- 
--  if(ModeNo<=0x13)
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--  else
-+  if(ModeNo<=0x13) {
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+  } else {
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+     } else {
-     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+     }
-+  }
- 
-+#ifndef SIS_CP
-   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
-+#endif  
-+
-+#ifdef SIS_CP
-+  SIS_CP_INIT301_CP
-+#endif
- 
-   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
--    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
-+     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-+     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
-   } else {
--    if(HwDeviceExtension->jChipType >= SIS_315H) {
--      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
--      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
--    } else {
--      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
--      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
--    }
-+     if(HwDeviceExtension->jChipType >= SIS_315H) {
-+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
-+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
-+     } else {
-+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
-+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
-+     }
-   }
- 
-   temp = 0;
-@@ -7982,38 +8108,41 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHOR
-      temp = 0x38;
-   }
-   if(temp) {
--      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
--              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
--                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
--                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
--                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
--              }
--          }
--      }
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-+           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
-+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
-+              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
-+           }
-+        }
-+     }
-   }
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
--    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
--    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
--      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
--      if(!(modeflag & Charx8Dot)) {
--        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
--      }
--    }
--    if(SiS_Pr->SiS_HiVision & 0x03) {
--       tempdi = SiS_HiTVGroup3_1;
--       if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
--    }
--    for(i=0; i<=0x3E; i++){
--       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
--    }
-+     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
-+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-+        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
-+        if(!(modeflag & Charx8Dot)) {
-+           tempdi = SiS_Pr->SiS_HiTVGroup3Text;
-+        }
-+     }
-+     if(SiS_Pr->SiS_HiVision & 0x03) {
-+        tempdi = SiS_HiTVGroup3_1;
-+        if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
-+     }
-+     for(i=0; i<=0x3E; i++){
-+        SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
-+     }
-   }
- 
--  return;
-+#ifdef SIS_CP
-+  SIS_CP_INIT301_CP2
-+#endif
-+
- }
- 
--/* TW: Set 301 VGA2 registers */
-+/* Set 301 VGA2 registers */
- void
- SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-@@ -8022,17 +8151,20 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
-   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
-   ULONG tempebx,tempeax,templong;
- 
--
--  if(ModeNo<=0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
--	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-+  if(ModeNo <= 0x13) {
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-   } else {
-+     if(SiS_Pr->UseCustomMode) {
-+        modeflag = SiS_Pr->CModeFlag;
-+	resinfo = 0;
-+     } else {
-     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-+     }
-   }
- 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--      /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
-      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-            SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
-@@ -8049,10 +8181,10 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--	   /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
--  	   /* TW: This is a duplicate; done at the end, too */
-+	   /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
-+  	   /* This is a duplicate; done at the end, too */
- 	   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
--		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
- 	   }
- 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
- 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-@@ -8090,39 +8222,33 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
-   tempbx = SiS_Pr->SiS_VGAHDE;
-   if(modeflag & HalfDCLK)  tempbx >>= 1;
- 
--  /* TW: New for 650/301LV and 630/301B */
-   temp = 0xA0;
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
--       temp = 0;
--       if(tempbx > 800) {
--          temp = 0xA0;
--          if(tempbx != 1024) {
--             temp = 0xC0;
--             if(tempbx != 1280) temp = 0;
--	  }
--       }
--  } else
--    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--      if(tempbx <= 800) {
--         temp = 0x80;
--	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--            temp = 0;
--            if(tempbx > 800) temp = 0x60;
--         }
--      }
-+     temp = 0;
-+     if(tempbx > 800) {
-+        temp = 0xA0;
-+        if(tempbx != 1024) {
-+           temp = 0xC0;
-+           if(tempbx != 1280) temp = 0;
-+	}
-+     }
-+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-+     if(tempbx <= 800) {
-+        temp = 0x80;
-+     }
-   } else {
--      temp = 0x80;
--      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--            temp = 0;
--            if(tempbx > 800) temp = 0x60;
--      }
-+     temp = 0x80;
-+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-+        temp = 0;
-+        if(tempbx > 800) temp = 0x60;
-+     }
-   }
-   if(SiS_Pr->SiS_HiVision & 0x03) {
-         temp = 0;
- 	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
-   }
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
--  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
-+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
-   }
- 
-   if(SiS_Pr->SiS_VBType & VB_SIS301) {
-@@ -8144,10 +8270,10 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
- 
-   tempeax = SiS_Pr->SiS_VGAVDE;
-   tempcx |= 0x4000;
--  if(tempeax <= tempebx){
--    tempcx ^= 0x4000;
-+  if(tempeax <= tempebx) {
-+     tempcx ^= 0x4000;
-   } else {
--    tempeax -= tempebx;
-+     tempeax -= tempebx;
-   }
- 
-   templong = (tempeax * 256 * 1024) % tempebx;
-@@ -8173,64 +8299,64 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
-          tempax = SiS_Pr->SiS_VGAHDE;
-          if(modeflag & HalfDCLK) tempax >>= 1;
-          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
--	     if(HwDeviceExtension->jChipType >= SIS_315H) {
--	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
--		 else if(tempax > 800) tempax -= 800;
--	     } else {
--                 if(tempax > 800) tempax -= 800;
--             }
-+	    if(HwDeviceExtension->jChipType >= SIS_315H) {
-+	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
-+	       else if(tempax > 800) tempax -= 800;
-+	    } else {
-+               if(tempax > 800) tempax -= 800;
-+            }
-          }
- 
- /*       if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {  */
-  	 if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
--           if(tempax > 800) {
--	      tempbx = 8;
--              if(tempax == 1024)
--	        tempax *= 25;
--              else
--	        tempax *= 20;
--
--	      temp = tempax % 32;
--	      tempax /= 32;
--	      tempax--;
--	      if (temp!=0) tempax++;
--           }
-+            if(tempax > 800) {
-+	       tempbx = 8;
-+               if(tempax == 1024)
-+	          tempax *= 25;
-+               else
-+	          tempax *= 20;
-+
-+	       temp = tempax % 32;
-+	       tempax /= 32;
-+	       tempax--;
-+	       if (temp!=0) tempax++;
-+            }
-          }
- 	 tempax--;
-          temp = (tempax & 0xFF00) >> 8;
-          temp &= 0x03;
--	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {		/* From 1.10.7w */
--	 	if(ModeNo > 0x13) {			/* From 1.10.7w */
--			if(resinfo == 8) tempax = 0x1f;	/* From 1.10.7w */
--		}					/* From 1.10.7w */
--	 }						/* From 1.10.7w */
-+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* From 1.10.7w */
-+	    if(ModeNo > 0x13) {					/* From 1.10.7w */
-+	       if(resinfo == SIS_RI_1024x768) tempax = 0x1f;	/* From 1.10.7w */
-+	    }							/* From 1.10.7w */
-+	 }							/* From 1.10.7w */
- 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
- 	 temp <<= 4;
- 	 temp |= tempbx;
- 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
- 
- 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--	    if(IS_SIS650740) {
--	        temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
-+	    if(IS_SIS550650740660) {
-+	       temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
- 	    } else {
--	        temp = 0x0036;
-+	       temp = 0x0036;
- 	    }
- 	 } else {
--	     temp = 0x0036;
-+	    temp = 0x0036;
- 	 }
-          if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
- 	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
--		temp |= 0x01;
--	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
--	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
--  	                  temp &= 0xFE;
--		}
-+	    temp |= 0x01;
-+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-+	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
-+  	          temp &= 0xFE;
-+	    }
-          }
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
- 
- 	 tempbx = SiS_Pr->SiS_HT;
- 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
--	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
-+	    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
- 	 }
-          tempbx >>= 1;
- 	 tempbx -= 2;
-@@ -8238,7 +8364,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
-          temp = tempbx & 0x00FF;
-          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
--	 
-+
-          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
-@@ -8246,24 +8372,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
- 	 }
- 
- 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
--	     /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
--	     /* 315, 330, 650+301B BIOS don't do this at all */
--             /* TW: This is a duplicate; done for LCDA as well (see above) */
--	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
--		   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
--	        }
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
--	     }
-+	    /* 650/LV BIOS does this for all bridge types - assumingly wrong */
-+	    /* 315, 330, 650+301B BIOS don't do this at all */
-+            /* This is a duplicate; done for LCDA as well (see above) */
-+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-+		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-+	       }
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-+	    }
-          } else if(HwDeviceExtension->jChipType == SIS_300) {
--	     /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
--	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
--	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
--	     }
-+	    /* 300/301LV BIOS does this for all bridge types - assumingly wrong */
-+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-+	    }
- 	 }
- 
-   }  /* 301B */
-@@ -8278,21 +8404,26 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USH
-                  USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-   USHORT vclkindex;
--  USHORT tempah;
-+  USHORT temp, reg1, reg2;
- 
--  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
--                              HwDeviceExtension);
-+  if(SiS_Pr->UseCustomMode) {
-+     reg1 = SiS_Pr->CSR2B;
-+     reg2 = SiS_Pr->CSR2C;
-+  } else {
-+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-+                                 HwDeviceExtension);
-+     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-+     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-+  }
- 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
--     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
--     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
--     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
-+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
-+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- 	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
--                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-+                 if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
- 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
- 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
- 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
-@@ -8303,15 +8434,13 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USH
-      }
-   } else {	
-      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
--     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
--     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
--     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
--     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
-+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
-+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
-   }
-   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
--  tempah = 0x08;
--  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
--  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
-+  temp = 0x08;
-+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
-+  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
- }
- 
- USHORT
-@@ -8319,23 +8448,24 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-   USHORT tempbx;
--  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
--  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
-+  const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
-+  const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
-+  const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
- #ifdef SIS300
--  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
--  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
--  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
--  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-+  const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
-+  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
-+  const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
-+  const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
- #endif
- #ifdef SIS315H
--  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
--  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
--  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
--  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-+  const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
-+  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
-+  const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
-+  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
- #endif
-   USHORT CRT2Index,VCLKIndex=0;
-   USHORT modeflag,resinfo;
--  const UCHAR *CHTVVCLKPtr=NULL;
-+  const UCHAR  *CHTVVCLKPtr = NULL;
-   const USHORT *LCDXlatVCLK1 = NULL;
-   const USHORT *LCDXlatVCLK2 = NULL;
-   const USHORT *LVDSXlatVCLK2 = NULL;
-@@ -8372,33 +8502,40 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
- 
-         CRT2Index >>= 6;
--        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
-+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
-             if(HwDeviceExtension->jChipType < SIS_315H) {
--	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
-+	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- 	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
--	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
--	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
-+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
--	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
-+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
- 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
--	       else
-+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-+	                VCLKIndex = VCLK81_300;	/* guessed */
-+	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-+		        VCLKIndex = VCLK108_3_300;
-+		        if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
-+	       } else {
- 	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
-+	       }
- 	    } else {
--               /* TW: 330, 650/301LV BIOS does not check expanding, 315 does  */
--	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
-+	       if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
- 	           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-       	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--		     VCLKIndex = 0x19;
-+		     VCLKIndex = VCLK108_2_315;
-+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-+		     VCLKIndex = VCLK81_315;  	/* guessed */
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--		     VCLKIndex = 0x19;
-+		     VCLKIndex = VCLK108_2_315;
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
--		     VCLKIndex = 0x21;
-+		     VCLKIndex = VCLK162_315;
-+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-+		     VCLKIndex = VCLK108_3_315;
-+		     if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
- 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- 		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
--                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
--		     VCLKIndex = 0x45;  /* TW: in VBVCLK table */
--		     if(resinfo == 0x09) VCLKIndex++;
- 	          } else {
- 		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
-       	          }
-@@ -8408,12 +8545,18 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-         	   if(ModeNo > 0x13) {
-           		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-         	   }
--		   if(ModeNo <= 0x13) {  /* TW: 315 BIOS */
--		      if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
-+		   if(ModeNo <= 0x13) {
-+		      if(HwDeviceExtension->jChipType <= SIS_315PRO) {
-+		         if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
-+	              } else {
-+		         if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
-+		      }
-+		   }
-+		   if(HwDeviceExtension->jChipType <= SIS_315PRO) {
-+		      if(VCLKIndex == 0) VCLKIndex = 0x41;
-+		      if(VCLKIndex == 1) VCLKIndex = 0x43;
-+		      if(VCLKIndex == 4) VCLKIndex = 0x44;
- 		   }
--		   if(VCLKIndex == 0) VCLKIndex = 0x41;
--		   if(VCLKIndex == 1) VCLKIndex = 0x43;
--		   if(VCLKIndex == 4) VCLKIndex = 0x44;
- 	       }
- 	    }
-         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
-@@ -8429,9 +8572,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-        			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
-             		else         		              VCLKIndex = TVVCLK;
-           	}
--		if(HwDeviceExtension->jChipType >= SIS_315H) {
--              		VCLKIndex += 25;
--  		}
-+		if(HwDeviceExtension->jChipType < SIS_315H) {
-+              		VCLKIndex += TVCLKBASE_300;
-+  		} else {
-+			VCLKIndex += TVCLKBASE_315;
-+		}
-         } else {         					/* RAMDAC2 */
-         	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-         	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-@@ -8441,7 +8586,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-           			VCLKIndex &= 0x3f;
- 				if( (HwDeviceExtension->jChipType == SIS_630) &&
- 				    (HwDeviceExtension->jChipRevision >= 0x30)) {
--				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
-+				     /* This is certainly wrong: It replaces clock
-+				      * 108 by 47...
-+				      */
-+				     /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
-+				     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
- 				}
- 			}
-         	}
-@@ -8505,6 +8654,10 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-      		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
- 		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
-      			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-+		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
-+		        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
-+			SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
-+			VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
-      		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-      			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
- 		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
-@@ -8513,6 +8666,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
-                         VCLKIndex = LVDSXlatVCLK2[VCLKIndex];			
-      		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
- 
-+		if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-+		   /* Special Timing: Barco iQ Pro R300/400 */
-+		   VCLKIndex = 0x44;
-+		}
-+
- 	   } else {
- 
- 	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-@@ -8556,11 +8714,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
- #ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
- #endif
--  return (VCLKIndex);
-+  return(VCLKIndex);
- }
- 
--/* TW: Set 301 Palette address port registers */
--/* TW: Checked against 650/301LV BIOS */
-+/* Set 301 Palette address port registers */
-+/* Checked against 650/301LV BIOS */
- void
- SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-               UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
-@@ -8568,7 +8726,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
- 
--  if(SiS_Pr->SiS_ModeType == ModeVGA){
-+  if(SiS_Pr->SiS_ModeType == ModeVGA) {
-      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
-         SiS_EnableCRT2(SiS_Pr);
-         SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
-@@ -8581,17 +8739,21 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
-                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-   USHORT temp,tempah,i,modeflag,j;
--  USHORT ResInfo,DisplayType;
-+  USHORT ResIndex,DisplayType;
-   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
- 
-   if(ModeNo <= 0x13) {
--    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   } else {
--    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-   }
- 
-+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
-+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024))
-+     return;
-+
-   temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
--                            &ResInfo,&DisplayType);
-+                            &ResIndex,&DisplayType);
- 
-   if(temp == 0) return;
- 
-@@ -8639,47 +8801,53 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
-     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
-     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
-     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
-+    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
-+    case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
-+    case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
-+    case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
-+    case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
-+    case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
-     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
-     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-   }
- 
-   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
- 
--  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
-+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
- 
-   for(i=0x02,j=1;i<=0x05;i++,j++){
--    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-   }
-   for(i=0x06,j=5;i<=0x07;i++,j++){
--    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-   }
-   for(i=0x10,j=7;i<=0x11;i++,j++){
--    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-   }
-   for(i=0x15,j=9;i<=0x16;i++,j++){
--    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-   }
-   for(i=0x0A,j=11;i<=0x0C;i++,j++){
--    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
-   }
- 
--  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
-+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
-   tempah &= 0xE0;
--  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     
-+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
- 
--  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
-+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
-   tempah &= 0x01;
-   tempah <<= 5;
-   if(modeflag & DoubleScanMode)  tempah |= 0x080;
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
- 
--  /* TW: 650/LVDS BIOS - doesn't make sense */
-+  /* 650/LVDS BIOS - doesn't make sense */
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(modeflag & HalfDCLK)
-         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
-@@ -8688,7 +8856,7 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
- 
- BOOLEAN
- SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
--		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-+		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
- 		   USHORT *DisplayType)
-  {
-   USHORT tempbx,modeflag=0;
-@@ -8757,19 +8925,33 @@ SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, 
-            tempbx = 40;
- 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- 	   if(modeflag & HalfDCLK) tempbx++;
-+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
-+           tempbx = 54;
-+	   if(modeflag & HalfDCLK) tempbx++;
-+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
-+           tempbx = 52;
-+	   if(modeflag & HalfDCLK) tempbx++;
-+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-+           tempbx = 50;
-+	   if(modeflag & HalfDCLK) tempbx++;
-         }
-+
-      }
-      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-         tempbx = 12;
- 	if(modeflag & HalfDCLK) tempbx++;
-      }
-   }
--  if(SiS_Pr->SiS_IF_DEF_FSTN){
-+
-+#if 0
-+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-         tempbx = 22;
-      }
-   }
--  *ResInfo = CRT2CRTC & 0x3F;
-+#endif
-+
-+  *ResIndex = CRT2CRTC & 0x3F;
-   *DisplayType = tempbx;
-   return 1;
- }
-@@ -8778,54 +8960,54 @@ void
- SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
--  USHORT tempah,tempal,pushax;
--  USHORT vclkindex=0;
--    
-+  USHORT clkbase, vclkindex=0;
-+  UCHAR  sr2b, sr2c;
-+
-   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
- 	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
--        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
--    	tempal &= 0x3F;
--	if(tempal == 2) RefreshRateTableIndex--;
-+        if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
-+	   RefreshRateTableIndex--;
-+	}
- 	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
--                               RefreshRateTableIndex,HwDeviceExtension);
-+                                    RefreshRateTableIndex,HwDeviceExtension);
- 	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-   } else {
-         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
--                               RefreshRateTableIndex,HwDeviceExtension);
-+                                    RefreshRateTableIndex,HwDeviceExtension);
-   }
--  
--  tempal = 0x02B;
-+
-+  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-+  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-+
-+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
-+     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-+	if(ROMAddr[0x220] & 0x01) {
-+           sr2b = ROMAddr[0x227];
-+	   sr2c = ROMAddr[0x228];
-+	}
-+     }
-+  }
-+
-+  clkbase = 0x02B;
-   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
--    	tempal += 3;
-+    	clkbase += 3;
-      }
-   }
-+
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
--  pushax = tempal;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
--  tempal++;
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
--  tempal = pushax;
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
--  tempal++;
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
--  tempal = pushax;
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
--  tempal++;
--  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
--  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
--  return;
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
-+  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
- }
- 
--#if 0  /* TW: Not used */
-+#if 0  /* Not used */
- void
- SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
- {
-@@ -8844,7 +9026,7 @@ SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_P
- }
- #endif
- 
--/* TW: Start of Chrontel 70xx functions ---------------------- */
-+/* Start of Chrontel 70xx functions ---------------------- */
- 
- /* Set-up the Chrontel Registers */
- void
-@@ -8890,44 +9072,44 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
- 
- #ifdef SIS300
--  
--     /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
- 
--     /* TW: We don't support modes >800x600 */
-+     /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
-+
-+     /* We don't support modes >800x600 */
-      if (resindex > 5) return;
- 
-      if(SiS_Pr->SiS_VBInfo & SetPALTV) {
--    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
--    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
-+    	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
-+    	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
-      } else {
--    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
--    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
-+    	SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
-+    	SiS_SetCH700x(SiS_Pr,0x7109);	/* Black level for NTSC (113)*/
-      }
- 
-      temp = CHTVRegData[resindex].Reg[0];
--     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
-+     tempbx=((temp&0x00FF)<<8)|0x00;	/* Mode register */
-      SiS_SetCH700x(SiS_Pr,tempbx);
-      temp = CHTVRegData[resindex].Reg[1];
--     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
-+     tempbx=((temp&0x00FF)<<8)|0x07;	/* Start active video register */
-      SiS_SetCH700x(SiS_Pr,tempbx);
-      temp = CHTVRegData[resindex].Reg[2];
--     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
-+     tempbx=((temp&0x00FF)<<8)|0x08;	/* Position overflow register */
-      SiS_SetCH700x(SiS_Pr,tempbx);
-      temp = CHTVRegData[resindex].Reg[3];
--     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
-+     tempbx=((temp&0x00FF)<<8)|0x0A;	/* Horiz Position register */
-      SiS_SetCH700x(SiS_Pr,tempbx);
-      temp = CHTVRegData[resindex].Reg[4];
--     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
-+     tempbx=((temp&0x00FF)<<8)|0x0B;	/* Vertical Position register */
-      SiS_SetCH700x(SiS_Pr,tempbx);
- 
--     /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
-+     /* Set minimum flicker filter for Luma channel (SR1-0=00),
-                 minimum text enhancement (S3-2=10),
-    	        maximum flicker filter for Chroma channel (S5-4=10)
- 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
-       */
-      SiS_SetCH700x(SiS_Pr,0x2801);
- 
--     /* TW: Set video bandwidth
-+     /* Set video bandwidth
-             High bandwith Luma composite video filter(S0=1)
-             low bandwith Luma S-video filter (S2-1=00)
- 	    disable peak filter in S-video channel (S3=0)
-@@ -8936,22 +9118,24 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
-      */
-      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
- 
--     /* TW: Register 0x3D does not exist in non-macrovision register map
-+     /* Register 0x3D does not exist in non-macrovision register map
-             (Maybe this is a macrovision register?)
-       */
--     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
-+#ifndef SIS_CP
-+     SiS_SetCH70xx(SiS_Pr,0x003D);
-+#endif     
- 
--     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
-+     /* Register 0x10 only contains 1 writable bit (S0) for sensing,
-             all other bits a read-only. Macrovision?
-       */
-      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
- 
--     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
-+     /* Register 0x11 only contains 3 writable bits (S0-S2) for
-             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
-       */
-      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
- 
--     /* TW: Clear DSEN
-+     /* Clear DSEN
-       */
-      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
- 
-@@ -8994,7 +9178,7 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
-          }
-        }
-      } else {				/* ---- PAL ---- */
--           /* TW: We don't play around with FSCI in PAL mode */
-+           /* We don't play around with FSCI in PAL mode */
-          if (resindex == 0x04) {
-            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
-            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
-@@ -9012,7 +9196,7 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
- 
- #ifdef SIS315H
- 
--     /* TW: We don't support modes >1024x768 */
-+     /* We don't support modes >1024x768 */
-      if (resindex > 6) return;
- 
-      temp = CHTVRegData[resindex].Reg[0];
-@@ -9082,26 +9266,29 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
- #endif	/* 315 */
- 
-   }
-+
-+#ifdef SIS_CP
-+  SIS_CP_INIT301_CP3
-+#endif
-+
- }
- 
--/* TW: Chrontel 701x functions ================================= */
-+/* Chrontel 701x functions ================================= */
- 
- void
--SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
-+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
--#ifndef NEWCH701x
-   USHORT temp;
--#endif  
- 
--  /* TW: Enable Chrontel 7019 LCD panel backlight */
-+  /* Enable Chrontel 7019 LCD panel backlight */
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
--#ifdef NEWCH701x
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-         SiS_SetCH701x(SiS_Pr,0x6566);
--#else  
-+     } else {
-         temp = SiS_GetCH701x(SiS_Pr,0x66);
-         temp |= 0x20;
- 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
--#endif	
-+     }
-   }
- }
- 
-@@ -9110,7 +9297,7 @@ SiS_Chrontel701xBLOff(SiS_Private *SiS_P
- {
-   USHORT temp;
- 
--  /* TW: Disable Chrontel 7019 LCD panel backlight */
-+  /* Disable Chrontel 7019 LCD panel backlight */
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-         temp = SiS_GetCH701x(SiS_Pr,0x66);
-         temp &= 0xDF;
-@@ -9118,47 +9305,54 @@ SiS_Chrontel701xBLOff(SiS_Private *SiS_P
-   }
- }
- 
--#ifdef SIS315H  /* -------- 310/325 series only --------- */
-+#ifdef SIS315H  /* ----------- 315 series only ---------- */
- 
- void
- SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
- {
--#ifdef NEWCH701x  
--  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
--                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
--  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
--                        0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; 
--  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
--   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 			
--  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,         
--                        0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 
--  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
--  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
--#else
--  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
--                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
--  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
--                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; 
--  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
--   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; 			
--  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,   
--                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; 
--  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
--  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
--#endif			
-+  UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-+                            0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
-+  UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-+                            0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
-+  UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-+   			    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
-+  UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-+                            0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
-+  UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
-+  UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-+                            0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
-+  UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-+   		   	    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
-+  UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
-+                            0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
-+  UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
-   UCHAR *tableptr = NULL;
-   USHORT tempbh;
-   int i;
- 
--  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--     tableptr = table1024;
--  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
--     tableptr = table1280;
--  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
--     tableptr = table1400;
--  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
--     tableptr = table1600;
--  } else return;
-+  if(HwDeviceExtension->jChipType == SIS_740) {
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+        tableptr = table1024_740;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+        tableptr = table1280_740;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-+        tableptr = table1400_740;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-+        tableptr = table1600_740;
-+     } else return;
-+  } else {
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+        tableptr = table1024_650;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-+        tableptr = table1280_650;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-+        tableptr = table1400_650;
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-+        tableptr = table1600_650;
-+     } else return;
-+  }
- 
-   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
-   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
-@@ -9172,54 +9366,64 @@ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr,
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
-      }
-   }
--#ifdef NEWCH701x     /* New from 740/LVDS: */    
--  for(i=0; i<0x0d; i++) {	
--#else
--  for(i=0; i<0x0c; i++) {
--#endif  
-+
-+  if(HwDeviceExtension->jChipType == SIS_740) {
-+     tempbh = 0x0d;
-+  } else {
-+     tempbh = 0x0c;
-+  }
-+  for(i = 0; i < tempbh; i++) {
-      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
-   }
--  SiS_ChrontelPowerSequencing(SiS_Pr);
-+  SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension);
-   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
-   tempbh |= 0xc0;
-   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
--  
--#ifdef NEWCH701x     /* 740/LVDS: */
--  tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
--  tempbh &= 0xfb;
--  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
--  SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
--  tempbh = SiS_GetCH701x(SiS_Pr,0x64);
--  tempbh |= 0x40;
--  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
--  tempbh = SiS_GetCH701x(SiS_Pr,0x03);
--  tempbh &= 0x3f;
--  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
--#endif  /* End 740/LVDS */
-+
-+  if(HwDeviceExtension->jChipType == SIS_740) {
-+     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
-+     tempbh &= 0xfb;
-+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
-+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
-+     tempbh = SiS_GetCH701x(SiS_Pr,0x64);
-+     tempbh |= 0x40;
-+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
-+     tempbh = SiS_GetCH701x(SiS_Pr,0x03);
-+     tempbh &= 0x3f;
-+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
-+  }
- }
- 
- void
--SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
--{
--  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
--#ifdef NEWCH701x  
--  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
--  UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
--#else
--  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
--  UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
--#endif  
-+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-+{
-+  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-+  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
-+  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
-+  UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-+  UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-   UCHAR *tableptr = NULL;
-   int i;
- 
-   /* Set up Power up/down timing */
--  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--     tableptr = table1024;
--  } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
--            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
--	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
--     tableptr = table1400;
--  } else return;
-+
-+  if(HwDeviceExtension->jChipType == SIS_740) {
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+        tableptr = table1024_740;
-+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-+        tableptr = table1400_740;
-+     } else return;
-+  } else {
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-+        tableptr = table1024_650;
-+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-+        tableptr = table1400_650;
-+     } else return;
-+  }
-   
-   for(i=0; i<5; i++) {
-      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
-@@ -9232,66 +9436,72 @@ SiS_Chrontel701xOn(SiS_Private *SiS_Pr, 
-   USHORT temp;
- 
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
--#ifdef NEWCH701x
--     temp = SiS_GetCH701x(SiS_Pr,0x1c);
--     temp |= 0x04;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
--#endif 
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
-+        temp |= 0x04;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-+     }
-      if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-         temp = SiS_GetCH701x(SiS_Pr,0x01);
- 	temp &= 0x3f;
--	temp |= 0x80;	/* TW: Enable YPrPb (HDTV) */
-+	temp |= 0x80;	/* Enable YPrPb (HDTV) */
- 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
-      }
-      if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-         temp = SiS_GetCH701x(SiS_Pr,0x01);
- 	temp &= 0x3f;
--	temp |= 0xc0;	/* TW: Enable SCART + CVBS */
-+	temp |= 0xc0;	/* Enable SCART + CVBS */
- 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
-      }
--#ifdef NEWCH701x
--     SiS_ChrontelDoSomething5(SiS_Pr);
--     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
--#else      
--     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
--     temp = SiS_GetCH701x(SiS_Pr,0x49);
--     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--        temp = SiS_GetCH701x(SiS_Pr,0x73);
--	temp |= 0x60;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+        SiS_ChrontelDoSomething5(SiS_Pr);
-+        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
-+     } else {
-+        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
-+        temp = SiS_GetCH701x(SiS_Pr,0x49);
-+        if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+           temp = SiS_GetCH701x(SiS_Pr,0x73);
-+	   temp |= 0x60;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
-+        }
-+        temp = SiS_GetCH701x(SiS_Pr,0x47);
-+        temp &= 0x7f;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-+        SiS_LongDelay(SiS_Pr,2);
-+        temp = SiS_GetCH701x(SiS_Pr,0x47);
-+        temp |= 0x80;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-      }
--     temp = SiS_GetCH701x(SiS_Pr,0x47);
--     temp &= 0x7f;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
--     SiS_LongDelay(SiS_Pr,2);
--     temp = SiS_GetCH701x(SiS_Pr,0x47);
--     temp |= 0x80;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
--#endif     
-   }
- }
- 
- void
--SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
-+SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-   USHORT temp;
- 
-+  /* Complete power down of LVDS */
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+        SiS_LongDelay(SiS_Pr,1);
-+	SiS_GenericDelay(SiS_Pr,0x16ff);
-+	SiS_SetCH701x(SiS_Pr,0xac76);
-+	SiS_SetCH701x(SiS_Pr,0x0066);
-+     } else {
-         SiS_LongDelay(SiS_Pr,2);
--	/* TW: Complete power down of LVDS */
- 	temp = SiS_GetCH701x(SiS_Pr,0x76);
- 	temp &= 0xfc;
- 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
- 	SiS_SetCH701x(SiS_Pr,0x0066);
-+     }
-   }
- }
- 
--#ifdef NEWCH701x
- void
- SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
- {
-      unsigned char temp, temp1;
--     
-+
-      temp1 = SiS_GetCH701x(SiS_Pr,0x49);
-      SiS_SetCH701x(SiS_Pr,0x3e49);
-      temp = SiS_GetCH701x(SiS_Pr,0x47);
-@@ -9303,130 +9513,134 @@ SiS_ChrontelDoSomething5(SiS_Private *Si
-      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-      SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
- }
--#endif
- 
- void
- SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
- {
--#ifdef NEWCH701x
-      USHORT temp;
--     
--     /* 740/LVDS: */
--     temp = SiS_GetCH701x(SiS_Pr,0x4a);
--     temp &= 0x01;
--     if(!(temp)) {
--     
--        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	   temp = SiS_GetCH701x(SiS_Pr,0x49);
--	   SiS_SetCH701x(SiS_Pr,0x3e49);
--	}
--	/* TW: Reset Chrontel 7019 datapath */
-+
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+        temp = SiS_GetCH701x(SiS_Pr,0x4a);
-+        temp &= 0x01;
-+        if(!(temp)) {
-+
-+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+	      temp = SiS_GetCH701x(SiS_Pr,0x49);
-+	      SiS_SetCH701x(SiS_Pr,0x3e49);
-+	   }
-+	   /* Reset Chrontel 7019 datapath */
-+           SiS_SetCH701x(SiS_Pr,0x1048);
-+           SiS_LongDelay(SiS_Pr,1);
-+           SiS_SetCH701x(SiS_Pr,0x1848);
-+
-+	   if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+	      SiS_ChrontelDoSomething5(SiS_Pr);
-+	      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
-+	   }
-+
-+        } else {
-+
-+           temp = SiS_GetCH701x(SiS_Pr,0x5c);
-+	   temp &= 0xef;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
-+	   temp |= 0x10;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
-+	   temp &= 0xef;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-+	   temp = SiS_GetCH701x(SiS_Pr,0x61);
-+	   if(!temp) {
-+	      SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
-+	   }
-+        }
-+     } else { /* 650 */
-+        /* Reset Chrontel 7019 datapath */
-         SiS_SetCH701x(SiS_Pr,0x1048);
-         SiS_LongDelay(SiS_Pr,1);
-         SiS_SetCH701x(SiS_Pr,0x1848);
--	
--	if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	   SiS_ChrontelDoSomething5(SiS_Pr);
--	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
--	}    
--     } else {
--     
--        temp = SiS_GetCH701x(SiS_Pr,0x5c);
--	temp &= 0xef;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
--	temp = SiS_GetCH701x(SiS_Pr,0x5c);
--	temp |= 0x10;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
--	temp = SiS_GetCH701x(SiS_Pr,0x5c);
--	temp &= 0xef;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
--	temp = SiS_GetCH701x(SiS_Pr,0x61);
--	if(!temp) {
--	   SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
--	}
--     }
--#else /* pre 740/LVDS code */     
--     /* TW: Reset Chrontel 7019 datapath */
--     SiS_SetCH701x(SiS_Pr,0x1048);
--     SiS_LongDelay(SiS_Pr,1);
--     SiS_SetCH701x(SiS_Pr,0x1848);
--#endif     
-+     }
- }
- 
- void
- SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
- {
--#ifdef NEWCH701x
--     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
--        SiS_ChrontelDoSomething5(SiS_Pr);
--     }
--#else
-      USHORT temp;
- 
--     SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
--     temp = SiS_GetCH701x(SiS_Pr,0x49);
--     temp &= 1;
--     if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
--	temp = SiS_GetCH701x(SiS_Pr,0x47);
--	temp &= 0x70;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
--	SiS_LongDelay(SiS_Pr,3);
--	temp = SiS_GetCH701x(SiS_Pr,0x47);
--	temp |= 0x80;
--	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+
-+        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+           SiS_ChrontelDoSomething5(SiS_Pr);
-+        }
-+
-+     } else {
-+
-+        SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
-+        temp = SiS_GetCH701x(SiS_Pr,0x49);
-+        temp &= 1;
-+        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
-+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
-+	   temp &= 0x70;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
-+	   SiS_LongDelay(SiS_Pr,3);
-+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
-+	   temp |= 0x80;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
-+        }
-+
-      }
--#endif     
- }
- 
- void
- SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                          USHORT BaseAddr)
- {
--#ifdef NEWCH701x
--     USHORT temp;
--     
--     temp = SiS_GetCH701x(SiS_Pr,0x61);
--     if(temp < 1) {
--          temp++;
--	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
--     }
--     SiS_SetCH701x(SiS_Pr,0x4566);
--     SiS_SetCH701x(SiS_Pr,0xaf76);
--     SiS_LongDelay(SiS_Pr,1);
--     SiS_GenericDelay(SiS_Pr,0x16ff);
--
--#else
-      USHORT temp,temp1;
--     
--     temp1 = 0;
--     temp = SiS_GetCH701x(SiS_Pr,0x61);
--     if(temp < 2) {
--          temp++;
--	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
--	  temp1 = 1;
--     }
--     SiS_SetCH701x(SiS_Pr,0xac76);
--     temp = SiS_GetCH701x(SiS_Pr,0x66);
--     temp |= 0x5f;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
--     if(ModeNo > 0x13) {
--         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
--	    SiS_GenericDelay(SiS_Pr,0x3ff);
--	 } else {
--	    SiS_GenericDelay(SiS_Pr,0x2ff);
--	 }
--     } else {
--         if(!temp1)
--	    SiS_GenericDelay(SiS_Pr,0x2ff);
-+
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+
-+        temp = SiS_GetCH701x(SiS_Pr,0x61);
-+        if(temp < 1) {
-+           temp++;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-+        }
-+        SiS_SetCH701x(SiS_Pr,0x4566);
-+        SiS_SetCH701x(SiS_Pr,0xaf76);
-+        SiS_LongDelay(SiS_Pr,1);
-+        SiS_GenericDelay(SiS_Pr,0x16ff);
-+
-+     } else {  /* 650 */
-+
-+        temp1 = 0;
-+        temp = SiS_GetCH701x(SiS_Pr,0x61);
-+        if(temp < 2) {
-+           temp++;
-+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-+	   temp1 = 1;
-+        }
-+        SiS_SetCH701x(SiS_Pr,0xac76);
-+        temp = SiS_GetCH701x(SiS_Pr,0x66);
-+        temp |= 0x5f;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-+        if(ModeNo > 0x13) {
-+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-+	      SiS_GenericDelay(SiS_Pr,0x3ff);
-+	   } else {
-+	      SiS_GenericDelay(SiS_Pr,0x2ff);
-+	   }
-+        } else {
-+           if(!temp1)
-+	      SiS_GenericDelay(SiS_Pr,0x2ff);
-+        }
-+        temp = SiS_GetCH701x(SiS_Pr,0x76);
-+        temp |= 0x03;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-+        temp = SiS_GetCH701x(SiS_Pr,0x66);
-+        temp &= 0x7f;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-+        SiS_LongDelay(SiS_Pr,1);
-+
-      }
--     temp = SiS_GetCH701x(SiS_Pr,0x76);
--     temp |= 0x03;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
--     temp = SiS_GetCH701x(SiS_Pr,0x66);
--     temp &= 0x7f;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
--     SiS_LongDelay(SiS_Pr,1);
--#endif     
- }
- 
- void
-@@ -9443,9 +9657,9 @@ SiS_ChrontelDoSomething2(SiS_Private *Si
-        temp &= 0x04;
-        if(temp == 0x04) break;
-        
--#ifdef NEWCH701x
--       SiS_SetCH701x(SiS_Pr,0xac76);    /* 740/LVDS */
--#endif       
-+       if(HwDeviceExtension->jChipType == SIS_740) {
-+          SiS_SetCH701x(SiS_Pr,0xac76);
-+       }
- 
-        SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
- 
-@@ -9463,11 +9677,11 @@ SiS_ChrontelDoSomething2(SiS_Private *Si
-        temp = SiS_GetCH701x(SiS_Pr,0x76);
-        temp |= 0x04;
-        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
--#ifdef NEWCH701x
--       SiS_SetCH701x(SiS_Pr,0xe078);
--#else       
--       SiS_SetCH701x(SiS_Pr,0x6078);
--#endif       
-+       if(HwDeviceExtension->jChipType == SIS_740) {
-+          SiS_SetCH701x(SiS_Pr,0xe078);
-+       } else {
-+          SiS_SetCH701x(SiS_Pr,0x6078);
-+       }
-        SiS_LongDelay(SiS_Pr,2);
-     } while(0);
- 
-@@ -9485,51 +9699,52 @@ SiS_ChrontelDoSomething1(SiS_Private *Si
-      temp &= 0xbf;	/* Set datapath 2 to LVDS */
-      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-      
--#ifdef NEWCH701x   /* 740/LVDS: */
-+     if(HwDeviceExtension->jChipType == SIS_740) {
-+
-+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
-+        temp &= 0xfb;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-+
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
-+
-+        temp = SiS_GetCH701x(SiS_Pr,0x64);
-+        temp |= 0x40;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
-+
-+        temp = SiS_GetCH701x(SiS_Pr,0x03);
-+        temp &= 0x3f;
-+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-+
-+        temp = SiS_GetCH701x(SiS_Pr,0x66);
-+        if(temp != 0x45) {
-+           SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
-+           SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
-+	   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-+           SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
-+        }
-+
-+     } else { /* 650 */
- 
--     temp = SiS_GetCH701x(SiS_Pr,0x1c);
--     temp &= 0xfb;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
--     
--     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
--     
--     temp = SiS_GetCH701x(SiS_Pr,0x64);
--     temp |= 0x40;
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
--     
--     temp = SiS_GetCH701x(SiS_Pr,0x03);
--     temp &= 0x3f;	
--     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
--     
--     temp = SiS_GetCH701x(SiS_Pr,0x66);
--     if(temp != 0x45) {
-         SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
--        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
--	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
--        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
--     }     
- 
--#else  /* pre-740/LVDS: */     
-+        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
- 
--     SiS_ChrontelResetDB(SiS_Pr);
-+        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-+        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
- 
--     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
-+        SiS_SetCH701x(SiS_Pr,0xaf76);
- 
--     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
--     SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
-+     }
- 
--     SiS_SetCH701x(SiS_Pr,0xaf76);
--     
--#endif  /* End of pre-740/LVDS */
- }
- 
--#endif  /* 310/325 series --------------------------------- */
-+#endif  /* 315 series ------------------------------------ */
- 
--/* TW: End of Chrontel 701x functions ==================================== */
-+/* End of Chrontel 701x functions ==================================== */
- 
--/* TW: Generic Read/write routines for Chrontel ========================== */
-+/* Generic Read/write routines for Chrontel ========================== */
- 
--/* TW: The Chrontel is connected to the 630/730 via
-+/* The Chrontel is connected to the 630/730 via
-  * the 630/730's DDC/I2C port.
-  *
-  * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
-@@ -9539,13 +9754,13 @@ SiS_ChrontelDoSomething1(SiS_Private *Si
- void
- SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
- {
--   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-       SiS_SetCH700x(SiS_Pr,tempbx);
-    else
-       SiS_SetCH701x(SiS_Pr,tempbx);
- }
- 
--/* TW: Write to Chrontel 700x */
-+/* Write to Chrontel 700x */
- /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
- void
- SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
-@@ -9553,100 +9768,100 @@ SiS_SetCH700x(SiS_Private *SiS_Pr, USHOR
-   USHORT tempah,temp,i;
- 
-   if(!(SiS_Pr->SiS_ChrontelInit)) {
--     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
-+     SiS_Pr->SiS_DDC_Index = 0x11;		   /* Bit 0 = SC;  Bit 1 = SD */
-      SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
-      SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
-      SiS_Pr->SiS_DDC_DataShift = 0x00;
--     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
-+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* DAB (Device Address Byte) */
-   }
- 
--  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-+  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-     /* SiS_SetSwitchDDC2(SiS_Pr); */
--    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
--    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
--    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-+    tempah = tempbx & 0x00FF;			/* Write RAB */
-+    tempah |= 0x80;                             /* (set bit 7, see datasheet) */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-     tempah = (tempbx & 0xFF00) >> 8;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
--    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-+    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
-     SiS_Pr->SiS_ChrontelInit = 1;
-     return;
-   }
- 
--  /* TW: For 630ST */
-+  /* For 630ST */
-   if(!(SiS_Pr->SiS_ChrontelInit)) {
--     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
-+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 7 = SC;  Bit 6 = SD */
-      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
-      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
-      SiS_Pr->SiS_DDC_DataShift = 0x00;
--     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
-+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
- 
--     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-+     for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-        /* SiS_SetSwitchDDC2(SiS_Pr); */
--       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
-+       if (SiS_SetStart(SiS_Pr)) continue;	/* Set start condition */
-        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
--       if(temp) continue;			/* TW:    (ERROR: no ack) */
--       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
--       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
-+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
-+       if(temp) continue;			/*    (ERROR: no ack) */
-+       tempah = tempbx & 0x00FF;		/* Write RAB */
-+       tempah |= 0x80;                          /* (set bit 7, see datasheet) */
-        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
--       if(temp) continue;			/* TW:    (ERROR: no ack) */
-+       if(temp) continue;			/*    (ERROR: no ack) */
-        tempah = (tempbx & 0xFF00) >> 8;
--       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
--       if(temp) continue;			/* TW:    (ERROR: no ack) */
--       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
-+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
-+       if(temp) continue;			/*    (ERROR: no ack) */
-+       if(SiS_SetStop(SiS_Pr)) continue;	/* Set stop condition */
-        SiS_Pr->SiS_ChrontelInit = 1;
-        return;
-     }
-   }
- }
- 
--/* TW: Write to Chrontel 701x */
-+/* Write to Chrontel 701x */
- /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
- void
- SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
- {
-   USHORT tempah,temp,i;
- 
--  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
-+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
-   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
-   SiS_Pr->SiS_DDC_DataShift = 0x00;
--  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
-+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
- 
--  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
--    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-+  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
-+    if (SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-     tempah = tempbx & 0x00FF;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write RAB */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-     tempah = (tempbx & 0xFF00) >> 8;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
--    if(temp) continue;				/* TW:    (ERROR: no ack) */
--    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
-+    if(temp) continue;				/*    (ERROR: no ack) */
-+    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
-     return;
-   }
- }
- 
--/* TW: Read from Chrontel 70xx */
-+/* Read from Chrontel 70xx */
- /* Parameter is [Register no (S7-S0)] */
- USHORT
- SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
- {
--   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-       return(SiS_GetCH700x(SiS_Pr,tempbx));
-    else
-       return(SiS_GetCH701x(SiS_Pr,tempbx));
- }
- 
--/* TW: Read from Chrontel 700x */
-+/* Read from Chrontel 700x */
- /* Parameter is [Register no (S7-S0)] */
- USHORT
- SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
-@@ -9654,57 +9869,57 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHOR
-   USHORT tempah,temp,i;
- 
-   if(!(SiS_Pr->SiS_ChrontelInit)) {
--     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
-+     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
-      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
-      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
-      SiS_Pr->SiS_DDC_DataShift = 0x00;
--     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
-+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
-   }
- 
-   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
- 
--  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-+  for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-     /* SiS_SetSwitchDDC2(SiS_Pr); */
--    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
--    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
-+    if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
-     SiS_Pr->SiS_ChrontelInit = 1;
-     return(tempah);
-   }
- 
--  /* TW: For 630ST */
-+  /* For 630ST */
-   if(!SiS_Pr->SiS_ChrontelInit) {
--     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
-+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 0 = SC;  Bit 1 = SD */
-      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
-      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
-      SiS_Pr->SiS_DDC_DataShift = 0x00;
--     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
-+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
- 
--     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-+     for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-        /* SiS_SetSwitchDDC2(SiS_Pr); */
--       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-+       if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
-        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
--       if(temp) continue;				/* TW:        (ERROR: no ack) */
--       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
-+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* Write DAB (S0=0=write) */
-+       if(temp) continue;				/*        (ERROR: no ack) */
-+       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
-        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
--       if(temp) continue;				/* TW:        (ERROR: no ack) */
--       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-+       if(temp) continue;				/*        (ERROR: no ack) */
-+       if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
-        tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
--       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
--       if(temp) continue;				/* TW:        (ERROR: no ack) */
--       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
--       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
-+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* DAB (S0=1=read) */
-+       if(temp) continue;				/*        (ERROR: no ack) */
-+       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
-+       if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
-        SiS_Pr->SiS_ChrontelInit = 1;
-        return(tempah);
-      }
-@@ -9712,52 +9927,51 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHOR
-   return(0xFFFF);
- }
- 
--/* TW: Read from Chrontel 701x */
-+/* Read from Chrontel 701x */
- /* Parameter is [Register no (S7-S0)] */
- USHORT
- SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
- {
-   USHORT tempah,temp,i;
- 
--  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
-+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
-   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
-   SiS_Pr->SiS_DDC_DataShift = 0x00;
--  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
-+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
-   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
- 
--   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
--    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-+   for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
-+    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* Write RAB */
-     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
-     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
--    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
--    if(temp) continue;				/* TW:        (ERROR: no ack) */
--    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
--    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
-+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
-+    if(temp) continue;				/*        (ERROR: no ack) */
-+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
-+    SiS_SetStop(SiS_Pr);			/* Stop condition */
-     return(tempah);
-    }
-   return 0xFFFF;
- }
- 
--#ifdef LINUX_XF86
--/* TW: Our own DDC functions */
-+/* Our own DDC functions */
- USHORT
--SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
--		BOOLEAN checkcr32)
-+SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-+                USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
- {
-      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
-      unsigned char flag, cr32;
-      USHORT        temp = 0, myadaptnum = adaptnum;
- 
-      if(adaptnum != 0) {
--        if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
--	if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
-+        if(!(VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
-+	if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
-      }	
-      
-      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
-@@ -9771,8 +9985,9 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
-      flag = 0xff;
- 
-      cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
--  
--     if(pSiS->VBFlags & VB_SISBRIDGE) {
-+
-+#if 0
-+     if(VBFlags & VB_SISBRIDGE) {
- 	if(myadaptnum == 0) {
- 	   if(!(cr32 & 0x20)) {
- 	      myadaptnum = 2;
-@@ -9785,18 +10000,19 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
- 	   }
-         }
-      }
-+#endif
- 
--     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
-+     if(VGAEngine == SIS_300_VGA) {		/* 300 series */
- 	
-         if(myadaptnum != 0) {
- 	   flag = 0;
--	   if(pSiS->VBFlags & VB_SISBRIDGE) {
-+	   if(VBFlags & VB_SISBRIDGE) {
- 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
-               SiS_Pr->SiS_DDC_Index = 0x0f;
- 	   }
-         }
- 
--	if(!(pSiS->VBFlags & VB_301)) {
-+	if(!(VBFlags & VB_301)) {
- 	   if((cr32 & 0x80) && (checkcr32)) {
-               if(myadaptnum >= 1) {
- 	         if(!(cr32 & 0x08)) {
-@@ -9810,11 +10026,11 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
- 	temp = 4 - (myadaptnum * 2);
- 	if(flag) temp = 0;
- 
--     } else {						/* 310/325/330 series */
-+     } else {						/* 315/330 series */
- 
-      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
- 	
--	if(pSiS->VBFlags & VB_SISBRIDGE) {
-+	if(VBFlags & VB_SISBRIDGE) {
- 	   if(myadaptnum == 2) {
- 	      myadaptnum = 1;
-            }
-@@ -9822,7 +10038,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
- 
-         if(myadaptnum == 1) {
-      	   flag = 0;
--	   if(pSiS->VBFlags & VB_SISBRIDGE) {
-+	   if(VBFlags & VB_SISBRIDGE) {
- 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
-               SiS_Pr->SiS_DDC_Index = 0x0f;
- 	   }
-@@ -9840,7 +10056,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
-         temp = myadaptnum;
-         if(myadaptnum == 1) {
-            temp = 0;
--	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
-+	   if(VBFlags & VB_LVDS) flag = 0xff;
-         }
- 
- 	if(flag) temp = 0;
-@@ -9852,7 +10068,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
- #ifdef TWDEBUG
-     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
-     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
--#endif	 
-+#endif
-     
-     return 0;
- }
-@@ -9862,15 +10078,9 @@ SiS_WriteDABDDC(SiS_Private *SiS_Pr)
- {
-    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
-    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
--#ifdef TWDEBUG
--        xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
--#endif	 
-   	return 0xFFFF;
-    }
-    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
--#ifdef TWDEBUG
--        xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
--#endif	 
-    	return 0xFFFF;
-    }
-    return(0);
-@@ -9881,9 +10091,6 @@ SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
- {
-    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
-    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
--#ifdef TWDEBUG
--        xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
--#endif	 
-    	return 0xFFFF;
-    }
-    return(0);
-@@ -9921,9 +10128,6 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
-     SiS_SetSwitchDDC2(SiS_Pr);
-     if(SiS_PrepareDDC(SiS_Pr)) {
-          SiS_SetStop(SiS_Pr);
--#ifdef TWDEBUG
--	 xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
--#endif	 
-          return(0xFFFF);
-     }
-     mask = 0xf0;
-@@ -9972,7 +10176,7 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
- }
- 
- USHORT
--SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
-+SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
- {
-    USHORT flag, length, i;
-    unsigned char chksum,gotcha;
-@@ -10004,28 +10208,7 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr 
-    return(flag);
- }
- 
--USHORT
--SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
--{
--   USHORT i=0, flag=0;
--
--   length--;
--   
--   SiS_SetSwitchDDC2(SiS_Pr);
--   if(!(SiS_PrepareDDC(SiS_Pr))) {
--      for(i=0; i<length; i++) {
--         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
--         SiS_SendACK(SiS_Pr, 0);
--      }
--      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
--      SiS_SendACK(SiS_Pr, 1);
--   } else flag = 0xFFFF;
--   
--   SiS_SetStop(SiS_Pr);
--   return(0);
--}
--
--/* TW: Our private DDC function
-+/* Our private DDC functions
- 
-    It complies somewhat with the corresponding VESA function
-    in arguments and return values.
-@@ -10036,7 +10219,7 @@ SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHO
- 
-    Arguments:
-        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
--                 CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
-+                 CRT2 DDC is only supported on SiS301, 301B, 302B.
-        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
-        buffer: ptr to 256 data bytes which will be filled with read data.
- 
-@@ -10046,43 +10229,48 @@ SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHO
- 
-  */
- USHORT
--SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
--              USHORT DDCdatatype, unsigned char *buffer)
-+SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-+              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
- {
-    if(adaptnum > 2) return 0xFFFF;
-    if(DDCdatatype > 4) return 0xFFFF;
--   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
--   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
-+   if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
-+   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
-    if(DDCdatatype == 0) {
-        return(SiS_ProbeDDC(SiS_Pr));
-    } else {
--       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
-+       return(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer));
-    }
- }
- 
-+#ifdef LINUX_XF86
- /* Sense the LCD parameters (CR36, CR37) via DDC */
- /* SiS30x(B) only */
- USHORT
- SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
- {
--   USHORT DDCdatatype, paneltype, flag, xres, yres;
-+   USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
-    USHORT index, myindex, lumsize, numcodes;
-    unsigned char cr37=0, seekcode;
-    BOOLEAN checkexpand = FALSE;
-    int retry, i;
-    unsigned char buffer[256];
--   
-+
-+   for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
-+   SiS_Pr->CP_HaveCustomData = FALSE;
-+   SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
-+
-    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
-    if(pSiS->VBFlags & VB_30xBDH) return 0;
-   
--   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
-+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
-    
-    SiS_Pr->SiS_DDC_SecAddr = 0x00;
-    
-    /* Probe supported DA's */
-    flag = SiS_ProbeDDC(SiS_Pr);
- #ifdef TWDEBUG   
--   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
-+   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
-    	"CRT2 DDC capabilities 0x%x\n", flag);
- #endif	
-    if(flag & 0x10) {
-@@ -10099,7 +10287,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
-    /* Read the entire EDID */
-    retry = 2;
-    do {
--      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
-+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
- 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
- 		(3-retry), (retry == 1) ? "giving up" : "retrying");
-@@ -10132,7 +10320,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
-       }
-       
-       if((buffer[0x18] & 0x18) != 0x08) {
--         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- 	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", 
- 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
- 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : 
-@@ -10140,103 +10328,226 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
- 		buffer[0x18]);
- 	 return 0;
-       }
--      
--      /* Now analyze the first Detailed Timing Block and hope
--       * that the preferred timing mode is stored there.
--       */	
--      xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
--      yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
-+
-+      /* Now analyze the first Detailed Timing Block and see
-+       * if the preferred timing mode is stored there. If so,
-+       * check if this is a standard panel for which we already
-+       * know the timing.
-+       */
-+
-+      paneltype = Panel_Custom;
-       checkexpand = FALSE;
--      switch(xres) {
--         case 800:
--	     if(yres == 600) {
--	     	paneltype = Panel310_800x600;
--	     	checkexpand = TRUE;
--	     }
--	     break;
--         case 1024:
--	     if(yres == 768) {
--	     	paneltype = Panel310_1024x768;
--	     	checkexpand = FALSE;    /* expand causes error at 640x480, should otherwise be TRUE; */
--	     }
--	     break;
--	 case 1280:
--	     if(yres == 960) {
--	        if(pSiS->VGAEngine == SIS_300_VGA) {
--		   paneltype = Panel300_1280x960;
--		} else {
--		   paneltype = Panel310_1280x960; 
--		}
--	     } else if(yres == 1024) {
--	     	paneltype = Panel310_1280x1024;  
--		checkexpand = TRUE;
--	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
-+
-+      if(buffer[0x18] & 0x02) {
-+
-+         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
-+         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
-+
-+	 SiS_Pr->CP_PreferredX = xres;
-+	 SiS_Pr->CP_PreferredY = yres;
-+
-+         switch(xres) {
-+            case 800:
-+	        if(yres == 600) {
-+	     	   paneltype = Panel_800x600;
-+	     	   checkexpand = TRUE;
-+	        }
-+	        break;
-+            case 1024:
- 	        if(yres == 768) {
--	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
--		   checkexpand = TRUE;	
--	        }	
--	     }
--	     break;
--	 case 1400:
--	     if(pSiS->VGAEngine == SIS_315_VGA) {
--	        if(yres == 1050) {
--	           paneltype = Panel310_1400x1050;
--		   checkexpand = TRUE; 
--	        } 
--	     }
--      	     break;
--	 case 1600:
--	     if(pSiS->VGAEngine == SIS_315_VGA) {
--	        if(yres == 1200) {
--	           paneltype = Panel310_1600x1200;
-+	     	   paneltype = Panel_1024x768;
-+	     	   checkexpand = TRUE;
-+	        }
-+	        break;
-+	    case 1280:
-+	        if(yres == 1024) {
-+	     	   paneltype = Panel_1280x1024;
- 		   checkexpand = TRUE;
--	        } 
--	     }
--      	     break;
-+	        } else if(yres == 960) {
-+	           if(pSiS->VGAEngine == SIS_300_VGA) {
-+		      paneltype = Panel300_1280x960;
-+		   } else {
-+		      paneltype = Panel310_1280x960;
-+		   }
-+	        } else if(yres == 768) {
-+	       	   paneltype = Panel_1280x768;
-+		   checkexpand = FALSE;
-+		   cr37 |= 0x10;
-+	        }
-+	        break;
-+	    case 1400:
-+	        if(pSiS->VGAEngine == SIS_315_VGA) {
-+	           if(yres == 1050) {
-+	              paneltype = Panel310_1400x1050;
-+		      checkexpand = TRUE;
-+	           }
-+	        }
-+      	        break;
-+#if 0	    /* Treat this as custom, as we have no valid timing data yet */
-+	    case 1600:
-+	        if(pSiS->VGAEngine == SIS_315_VGA) {
-+	           if(yres == 1200) {
-+	              paneltype = Panel310_1600x1200;
-+		      checkexpand = TRUE;
-+	           }
-+	        }
-+      	        break;
-+#endif
-+         }
-+
-+	 if(paneltype != Panel_Custom) {
-+	    if((buffer[0x47] & 0x18) == 0x18) {
-+	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
-+	    } else {
-+	       /* What now? There is no digital separate output timing... */
-+	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-+	    }
-+	 }
-+
-       }
- 
--      if(buffer[0x18] & 0x02) {
--         /* If the preferred timing mode is stored in the first
--	  * detailed timing block, we now can extract the sync
--	  * polarisation information as well. This only works
--	  * if the Flags indicate a digital separate output.
--	  */
--	  if((buffer[0x47] & 0x18) == 0x18) {
--	     cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
--	  } else {
--	     /* What now? There is no digital separate output timing... */
--	     xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
--	     	"CRT2: Unable to retrieve Sync polarity information\n");
--	  }
--	  
--      } else {
--         /* If the preferred timing mode is *not* stored in the first
--	  * detailed timing block, we need to guess the resolution
--	  * from the supported Established Timings and assume the
--	  * default sync polarity
--	  */
-+      /* If we still don't know what panel this is, we take it
-+       * as a custom panel and derive the timing data from the
-+       * detailed timing blocks
-+       */
-+      if(paneltype == Panel_Custom) {
-+
-+         BOOLEAN havesync = FALSE;
-+	 int i, temp, base = 0x36;
-+	 unsigned long estpack;
-+	 unsigned short estx[] = {
-+	 	720, 720, 640, 640, 640, 640, 800, 800,
-+		800, 800, 832,1024,1024,1024,1024,1280,
-+		1152
-+	 };
-+	 unsigned short esty[] = {
-+	 	400, 400, 480, 480, 480, 480, 600, 600,
-+		600, 600, 624, 768, 768, 768, 768,1024,
-+		870
-+	 };
-+
- 	 paneltype = 0;
--	 if(buffer[0x24] & 0x01) { 	
--	 	paneltype = Panel310_1280x1024;
--		checkexpand = TRUE;
--		cr37 |= 0x20;
--	 } else if(buffer[0x24] & 0x0e) {
--	 	paneltype = Panel310_1024x768;
--		cr37 |= 0xe0;
--		checkexpand = FALSE;		/* Bug at 640x480 */
--	 } else if(buffer[0x23] & 0x01) {
--	 	paneltype = Panel310_800x600;
--		cr37 |= 0xe0;
--		checkexpand = TRUE;
--         }
-+
-+	 /* Find the maximum resolution */
-+
-+	 /* 1. From Established timings */
-+	 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
-+	 for(i=16; i>=0; i--) {
-+	     if(estpack & (1 << i)) {
-+	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
-+		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
-+	     }
-+	 }
-+
-+	 /* 2. From Standard Timings */
-+	 for(i=0x26; i < 0x36; i+=2) {
-+	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
-+	       temp = (buffer[i] + 31) * 8;
-+	       if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
-+	       switch((buffer[i+1] & 0xc0) >> 6) {
-+	       case 0x03: temp = temp * 9 / 16; break;
-+	       case 0x02: temp = temp * 4 / 5;  break;
-+	       case 0x01: temp = temp * 3 / 4;  break;
-+	       }
-+	       if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
-+	    }
-+	 }
-+
-+	 /* Now extract the Detailed Timings and convert them into modes */
-+
-+         for(i = 0; i < 4; i++, base += 18) {
-+
-+	    /* Is this a detailed timing block or a monitor descriptor? */
-+	    if(buffer[base] || buffer[base+1] || buffer[base+2]) {
-+
-+      	       xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
-+               yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
-+
-+	       SiS_Pr->CP_HDisplay[i] = xres;
-+	       SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
-+               SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
-+	       SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
-+	       SiS_Pr->CP_HBlankStart[i] = xres + 1;
-+	       SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-+
-+	       SiS_Pr->CP_VDisplay[i] = yres;
-+               SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
-+               SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
-+	       SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
-+	       SiS_Pr->CP_VBlankStart[i] = yres + 1;
-+	       SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-+
-+	       SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
-+
-+	       SiS_Pr->CP_DataValid[i] = TRUE;
-+
-+	       /* Sort out invalid timings, interlace and too high clocks */
-+	       if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
-+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
-+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
-+	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
-+	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
-+	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
-+	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
-+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
-+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
-+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
-+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
-+	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
-+	          (SiS_Pr->CP_Clock[i] > 108000)                       ||
-+		  (buffer[base+17] & 0x80)) {
-+
-+	          SiS_Pr->CP_DataValid[i] = FALSE;
-+
-+	       } else {
-+
-+	          paneltype = Panel_Custom;
-+
-+		  SiS_Pr->CP_HaveCustomData = TRUE;
-+
-+		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
-+	          if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
-+		  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-+
-+		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
-+		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
-+
-+	          /* We must assume the panel can scale, since we have
-+	           * no scaling data
-+		   */
-+	          checkexpand = FALSE;
-+	          cr37 |= 0x10;
-+
-+	          /* Extract the sync polarisation information. This only works
-+	           * if the Flags indicate a digital separate output.
-+	           */
-+	          if((buffer[base+17] & 0x18) == 0x18) {
-+		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
-+		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
-+		     SiS_Pr->CP_SyncValid[i] = TRUE;
-+		     if(!havesync) {
-+	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
-+			havesync = TRUE;
-+	   	     }
-+	          } else {
-+		     SiS_Pr->CP_SyncValid[i] = FALSE;
-+		  }
-+	       }
-+            }
-+	 }
-+	 if(!havesync) {
-+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
-+   	 }
-       }
--      
--      if(checkexpand) {
--         /* If any of the Established low-res modes is supported, the 
-+
-+      if(paneltype && checkexpand) {
-+         /* If any of the Established low-res modes is supported, the
- 	  * panel can scale automatically. For 800x600 panels, we only 
- 	  * check the even lower ones.
- 	  */
--	 if(paneltype == Panel310_800x600) {
-+	 if(paneltype == Panel_800x600) {
- 	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
- 	 } else {
-             if(buffer[0x23])	    cr37 |= 0x10;
-@@ -10262,20 +10573,31 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
- 		buffer[0x41]);
- 	 return 0;
-       }
--   
--      xres = buffer[0x76] | (buffer[0x77] << 8);
--      yres = buffer[0x78] | (buffer[0x79] << 8);
-+
-+      paneltype = Panel_Custom;
-+      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
-+      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
-       switch(xres) {
-          case 800:
- 	     if(yres == 600) {
--	     	paneltype = Panel310_800x600;
-+	     	paneltype = Panel_800x600;
- 	     	checkexpand = TRUE;
- 	     }
- 	     break;
-          case 1024:
- 	     if(yres == 768) {
--	     	paneltype = Panel310_1024x768;
--	     	checkexpand = FALSE;			/* Bug at 640x480; we do the scaling ourselves */
-+	     	paneltype = Panel_1024x768;
-+	     	checkexpand = TRUE;
-+	     }
-+	     break;
-+	 case 1152:
-+	     if(yres == 768) {
-+	        if(pSiS->VGAEngine == SIS_300_VGA) {
-+		   paneltype = Panel300_1152x768;
-+		} else {
-+		   paneltype = Panel310_1152x768;
-+		}
-+	     	checkexpand = TRUE;
- 	     }
- 	     break;
- 	 case 1280:
-@@ -10286,45 +10608,46 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
- 		   paneltype = Panel300_1280x960;
- 		}
- 	     } else if(yres == 1024) {
--	     	paneltype = Panel310_1280x1024;  
-+	     	paneltype = Panel_1280x1024;
- 		checkexpand = TRUE;
--	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
--	        if(yres == 768) {
--	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
--		   checkexpand = TRUE;
--	        }
--	     } 
-+	     } else if(yres == 768) {
-+	        paneltype = Panel_1280x768;
-+		checkexpand = FALSE;
-+		cr37 |= 0x10;
-+	     }
- 	     break;
- 	 case 1400:
- 	     if(pSiS->VGAEngine == SIS_315_VGA) {
- 	        if(yres == 1050) {
- 	           paneltype = Panel310_1400x1050;
- 		   checkexpand = TRUE;
--	        } 
-+	        }
- 	     }
-       	     break;
-+#if 0    /* Treat this one as custom since we have no timing data yet */
- 	 case 1600:
- 	     if(pSiS->VGAEngine == SIS_315_VGA) {
- 	        if(yres == 1200) {
- 	           paneltype = Panel310_1600x1200;
- 		   checkexpand = TRUE;
--	        } 
-+	        }
- 	     }
-       	     break;
-+#endif
-       }
--                 
-+
-       /* Determine if RGB18 or RGB24 */
-       if(index) {
-          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
- 	    cr37 |= 0x01;
- 	 }
-       }
--      
-+
-       if(checkexpand) {
-          /* TODO - for now, we let the panel scale */
- 	 cr37 |= 0x10;
-       }
--     
-+
-       /* Now seek 4-Byte Timing codes and extract sync pol info */
-       index = 0x80;
-       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
-@@ -10346,28 +10669,117 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
- 	 if(buffer[myindex] == seekcode) {
- 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
- 	 } else {
--	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
--	    	"CRT2: Unable to retrieve Sync polarity information\n");    
-+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-+	        "CRT2: Unable to retrieve Sync polarity information\n");
- 	 }
-       } else {
--         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
--	    	"CRT2: Unable to retrieve Sync polarity information\n");
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
-+	     "CRT2: Unable to retrieve Sync polarity information\n");
-+      }
-+
-+      /* Now seek the detailed timing descriptions for custom panels */
-+      if(paneltype == Panel_Custom) {
-+         index += (numcodes * 4);
-+	 numcodes = buffer[0x7f] & 0x07;
-+	 for(i=0; i<numcodes; i++) {
-+	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
-+            yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
-+
-+	    SiS_Pr->CP_HDisplay[i] = xres;
-+	    SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
-+            SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
-+	    SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
-+	    SiS_Pr->CP_HBlankStart[i] = xres + 1;
-+	    SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-+
-+	    SiS_Pr->CP_VDisplay[i] = yres;
-+            SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
-+            SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
-+	    SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
-+	    SiS_Pr->CP_VBlankStart[i] = yres + 1;
-+	    SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-+
-+	    SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
-+
-+	    SiS_Pr->CP_DataValid[i] = TRUE;
-+
-+	    if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
-+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
-+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
-+	       (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
-+	       (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
-+	       (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
-+	       (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
-+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
-+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
-+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
-+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
-+	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
-+	       (SiS_Pr->CP_Clock[i] > 108000)                       ||
-+	       (buffer[index + 17] & 0x80)) {
-+
-+	       SiS_Pr->CP_DataValid[i] = FALSE;
-+
-+	    } else {
-+
-+	       SiS_Pr->CP_HaveCustomData = TRUE;
-+
-+	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-+
-+	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
-+	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
-+	       SiS_Pr->CP_SyncValid[i] = TRUE;
-+
-+	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
-+	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
-+
-+	       /* We must assume the panel can scale, since we have
-+	        * no scaling data
-+    	        */
-+	       cr37 |= 0x10;
-+
-+	    }
-+	 }
-+
-       }
- 
-       break;
--     
-+
-    }
--   
-+
-    /* 1280x960 panels are always RGB24, unable to scale and use
-     * high active sync polarity
-     */
-    if(pSiS->VGAEngine == SIS_315_VGA) {
--      if(paneltype == Panel310_1280x960) cr37 &= 0x0e; 
-+      if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
-    } else {
--      if(paneltype == Panel300_1280x960) cr37 &= 0x0e; 
-+      if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
-    }
--   
-+
-+   for(i = 0; i < 7; i++) {
-+      if(SiS_Pr->CP_DataValid[i]) {
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-+            "Non-standard LCD timing data no. %d:\n", i);
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-+	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
-+	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
-+	    SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-+            "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
-+            SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
-+   	    SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
-+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-+	    "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
-+	 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
-+	    "   To use this, add \"%dx%d\" to the list of Modes in the Display section\n",
-+	    SiS_Pr->CP_HDisplay[i],
-+	    SiS_Pr->CP_VDisplay[i]);
-+      }
-+   }
-+
-    if(paneltype) {
-+       if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
-+       if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
-        cr37 &= 0xf1;
-        cr37 |= 0x02;    /* SiS301 */
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
-@@ -10392,7 +10804,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
-    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
- /* if(pSiS->VBFlags & VB_30xBDH) return 0;  */
-    
--   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
-+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
-    
-    SiS_Pr->SiS_DDC_SecAddr = 0x00;
-    
-@@ -10416,7 +10828,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
-    /* Read the entire EDID */
-    retry = 2;
-    do {
--      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
-+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
-          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
- 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
- 		(3-retry), (retry == 1) ? "giving up" : "retrying");
-@@ -10435,6 +10847,8 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
- 	  	"CRT2: Attached display expects digital input\n");
-       	  return 0;  	
-       }
-+      SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
-+      SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
-       foundcrt = TRUE;
-       break;
-    case 3:
-@@ -10448,198 +10862,19 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
- 		buffer[0x41]);
- 	  return 0;
-       }
-+      SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
-+      SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
-       foundcrt = TRUE;
--      break;	  
-+      break;
-    }
--   
-+
-    if(foundcrt) {
-        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
-    }
-    return(0);
- }
- 
--#if 0
--   /* ----- */
--USHORT
--SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
--{
--   USHORT DDCdatatype, paneltype, flag;
--   unsigned char cr36=0, cr37=0;
--   unsigned char tempal, tempah, tempbl, tempbh;
--   USHORT tempax, tempbx, tempcx, push1, push2, push3;
--   unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
--   int i;
--   unsigned char buffer[256];
--   
--   if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
--   if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
--   
--   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;   
--   
--   flag = SiS_ProbeDDC(SiS_Pr);
--   if(flag & 0x02) {
--      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
--      DDCdatatype = 1;
--      SiS_Pr->SiS_DDC_SecAddr = 0x3a;
--   } else if(flag & 0x08) {
--      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
--      DDCdatatype = 3;
--      SiS_Pr->SiS_DDC_SecAddr = 0x76;
--   } else if(flag & 0x10) {
--      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
--      DDCdatatype = 4;
--      SiS_Pr->SiS_DDC_SecAddr = 0x76;
--   } else return 0xFFFF;
--   
--   
--   SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
--   tempbl = buffer[0];  /* 3a - 76 */
--   tempbh = buffer[1];  /* 3b - 77 */
--   
--   if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
--   
--      /* Read and analyze EDID V1 (res) */
--   
--      tempah = 0x02;				/* 1024x768 by default */
--      tempbl &= 0xf0;
--      if(tempbl != 0x40) {			
--         tempah = 0x03;				/* 1280x1024 by default */
--	 if(tempbl == 0x50) {
--	    if(!tempbh) {
--	       tempbh = buffer[3] & 0xf0;
--	       if(tempbh == 0x30) {
--	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
--      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
--		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--		   tempbl = buffer[0];  /* 0x23 */
--		   tempbh = buffer[1];  /* 0x24 */
--		   if(tempbl) cr37 |= 0x10;
--		   tempah = 0x0a;		/* 1280x768 */
--	       }
--	       if(tempbh == 0x40) {
--	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
--      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
--		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--		   tempbl = buffer[0];  /* 0x23 */
--		   tempbh = buffer[1];  /* 0x24 */
--		   if(tempbl) cr37 |= 0x10;
--		   tempah = 0x03;		/* 1280x1024 */
--	       }
--	       tempbh = 0x00;
--	    }
--	 }
--	 if(tempbh == 0x00) goto cr36ready;
--	 tempah = 0x07;				/* 1280x960 */
--	 if(tempbh == 0xc0) goto cr36ready;
--      }
--      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
--      SiS_Pr->SiS_DDC_SecAddr = 0x18;		/* feature support */
--      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--      tempbl = buffer[0];
--      tempbh = buffer[1];
--      if(tempbl & 0x02) goto cr36ready;
--      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
--      SiS_Pr->SiS_DDC_SecAddr = 0x23;		/* Established Timings */
--      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--      tempbl = buffer[0];
--      tempbh = buffer[1];
--      tempah = 0x03;
--      if(!(tempbh & 0x01)) tempah = 0x02;
--      if(!tempbl) cr37 |= 0x10;
--      
--  } else {
--  
--      /* Read and analyze EDID V2 (res) */
--      
--      tempah = 0x02;
--      tempbx = tempbl | (tempbh << 8);
--      if(tempbx != 1024) tempah = 0x03;
--      
--  }     
--
--cr36ready:
--  cr36 = tempah;      
--  
--  if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
--  
--     /* Read and analyze EDID V1 (pol) */
--  
--     SiS_Pr->SiS_DDC_SecAddr = 0x47;
--     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--     tempah = buffer[0];
--     tempah &= 0x06;
--     tempah ^= 0x06;
--     tempah <<= 5;
--     tempah |= 0x20;
--     cr37 &= 0x1f;
--     cr37 |= tempah;
--     if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
--     
--  } else {
--  
--     /* Read and analyze EDID V2 (depth, pol) */
--  
--     push1 = tempah;
--     SiS_Pr->SiS_DDC_SecAddr = 0x45;
--     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--     tempah = 0x01;
--     if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {   /* RGB18 or 24? */
--        tempah = 0x00;
--     }
--     cr37 &= 0xfe;
--     cr37 |= tempah;
--     
--     SiS_Pr->SiS_DDC_SecAddr = 0x7e;
--     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--     tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
--     push2 = tempax;
--     tempax &= 0x0003;
--     tempax *= 0x1b;
--     push3 = tempax;
--     tempax = (USHORT)buffer[0];
--     tempax &= 0x001c;
--     tempax >>= 2;
--     tempax *= 8;
--     tempbx = push3;
--     tempbx += tempax;
--     if(buffer[0] & 0x20) {		/* Luminance table provided? */
--        SiS_Pr->SiS_DDC_SecAddr = 0x80;
--	SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--	tempax = buffer[0] | (buffer[1] << 8);
--	tempax &= 0x1f;
--	if(buffer[0] & 0x70) tempax <<= 1;
--	tempax++;	
--	tempbx += tempax;        	/* yes -> skip it */
--     }
--     tempcx = push2;
--     tempax = push1 << 8;
--     tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
--     if(tempcx & 0xf800) {
--        tempal = addresstable[((tempax & 0xff00) >> 8)];
--	tempcx &= 0xf8ff;
--	tempcx >>= 11;
--	for(i=0; i<tempcx; i++) {
--	   SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
--	   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
--	   tempbx += 0x04;
--	   if(buffer[0] == tempal) break;
--	}
--	tempah = buffer[1];
--	tempah &= 0x0c;
--	tempah ^= 0x0c;
--	tempah <<= 4;
--	tempah |= 0x20;
--        cr37 &= 0x1f;
--        cr37 |= tempah;
--	if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
--     }
--  }
--  xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
--  return 0;
--}
--#endif
--
--/* TW: Generic I2C functions (compliant to i2c library) */
-+/* Generic I2C functions (compliant to i2c library) */
- 
- #if 0
- USHORT
-@@ -10684,7 +10919,7 @@ SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, 
-   SiS_SetCH70xx(SiS_Pr,tempbl);
- }
- 
--/* TW: Generic I2C functions for Chrontel --------- */
-+/* Generic I2C functions for Chrontel --------- */
- 
- void
- SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
-@@ -10698,37 +10933,37 @@ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
-   SiS_WaitRetraceDDC(SiS_Pr);
- }
- 
--/* TW: Set I2C start condition */
--/* TW: This is done by a SD high-to-low transition while SC is high */
-+/* Set I2C start condition */
-+/* This is done by a SD high-to-low transition while SC is high */
- USHORT
- SiS_SetStart(SiS_Private *SiS_Pr)
- {
--  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
-+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
-   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
--  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
-+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* SD->high */
-+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high */
-   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
--  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
-+                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* SD->low = start condition */
-+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
-   return 0;
- }
- 
--/* TW: Set I2C stop condition */
--/* TW: This is done by a SD low-to-high transition while SC is high */
-+/* Set I2C stop condition */
-+/* This is done by a SD low-to-high transition while SC is high */
- USHORT
- SiS_SetStop(SiS_Private *SiS_Pr)
- {
--  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
-+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
-   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
--  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
-+                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* SD->low   */
-+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high  */
-   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
--  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
-+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* SD->high = stop condition */
-+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->high) */
-   return 0;
- }
- 
--/* TW: Write 8 bits of data */
-+/* Write 8 bits of data */
- USHORT
- SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
- {
-@@ -10736,18 +10971,18 @@ SiS_WriteDDC2Data(SiS_Private *SiS_Pr, U
- 
-   flag=0x80;
-   for(i=0;i<8;i++) {
--    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
-+    SiS_SetSCLKLow(SiS_Pr);				                      /* SC->low */
-     if(tempax & flag) {
-       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
-+                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* Write bit (1) to SD */
-     } else {
-       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
-+                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* Write bit (0) to SD */
-     }
--    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
-+    SiS_SetSCLKHigh(SiS_Pr);				                      /* SC->high */
-     flag >>= 1;
-   }
--  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
-+  temp = SiS_CheckACK(SiS_Pr);				                      /* Check acknowledge */
-   return(temp);
- }
- 
-@@ -10808,27 +11043,27 @@ SiS_DDC2Delay(SiS_Private *SiS_Pr, USHOR
-   }
- }
- 
--/* TW: Check I2C acknowledge */
-+/* Check I2C acknowledge */
- /* Returns 0 if ack ok, non-0 if ack not ok */
- USHORT
- SiS_CheckACK(SiS_Private *SiS_Pr)
- {
-   USHORT tempah;
- 
--  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
-+  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
-   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
--                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
--  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
--  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
--  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
--  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
-+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* (SD->high) */
-+  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
-+  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
-+  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
-+  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* Ack OK if bit = 0 */
-   else return(0);
- }
- 
--/* TW: End of I2C functions ----------------------- */
-+/* End of I2C functions ----------------------- */
- 
- 
--/* =============== SiS 310/325/330 O.E.M. ================= */
-+/* =============== SiS 315/330 O.E.M. ================= */
- 
- #ifdef SIS315H
- 
-@@ -10838,11 +11073,11 @@ GetRAMDACromptr(SiS_Private *SiS_Pr, PSI
-   USHORT romptr;
- 
-   if(HwDeviceExtension->jChipType < SIS_330) {
--     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);  
-+     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
-      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
-         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
-   } else {
--     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);  
-+     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
-      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
-         romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
-   }
-@@ -10855,11 +11090,11 @@ GetLCDromptr(SiS_Private *SiS_Pr, PSIS_H
-   USHORT romptr;
- 
-   if(HwDeviceExtension->jChipType < SIS_330) {
--     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  
-+     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
-   } else {
--     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);  
-+     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
-         romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
-   }
-@@ -10884,10 +11119,22 @@ GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW
- }
- 
- static USHORT
--GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
-+GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
- {
-   USHORT index;
--  
-+
-+  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-+     if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-+        if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
-+	   index >>= 4;
-+	   index *= 3;
-+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
-+           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
-+           return index;
-+	}
-+     }
-+  }
-+
-   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
-   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
-   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
-@@ -10895,7 +11142,6 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
-   index *= 3;
-   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
-   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
--
-   return index;
- }
- 
-@@ -10946,7 +11192,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
-              UCHAR *ROMAddr, USHORT ModeNo)
- {
-   USHORT delay,index,myindex,temp,romptr=0;
--  
-+
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
-      
-      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-@@ -10971,8 +11217,10 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
-      }
-   
-   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
-+
-+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-   
--     index = GetLCDPtrIndexBIOS(SiS_Pr);
-+     index = GetLCDPtrIndexBIOS(SiS_Pr, HwDeviceExtension, BaseAddr);
-      myindex = GetLCDPtrIndex(SiS_Pr);
-      
-      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
-@@ -10980,7 +11228,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
-           if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- #if 0	     /* Always use the second pointer on 650; some BIOSes */
-              /* still carry old 301 data at the first location    */  
--	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); 
-+	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
- 	     if(SiS_Pr->SiS_VBType & VB_SIS302LV) 
- #endif		
- 	        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
-@@ -10994,13 +11242,13 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
- #endif		
- 	  }
-        } else {
--          delay = SiS310_LCDDelayCompensation_651301LV[myindex];     
-+          delay = SiS310_LCDDelayCompensation_651301LV[myindex];
- 	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
--	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];  
-+	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];
-        }
-      } else {
-         if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
--	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { 
-+	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
-            romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
- 	   if(!romptr) return;
- 	   delay = ROMAddr[(romptr + index)];
-@@ -11008,7 +11256,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
-            delay = SiS310_LCDDelayCompensation_301[myindex];
-            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- #if 0 	      /* This data is (like the one in the BIOS) wrong. */	   
--	      if(IS_SIS650740) {  /* V */
-+	      if(IS_SIS550650740660) {
- 	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
- 	      } else {
- #endif	      
-@@ -11088,14 +11336,16 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
-   } else {
-      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-         temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
--        if(temp == 8) {
-+        if(temp == 8) {		/* 1400x1050 BIOS */
- 	   delay &= 0x0f;
- 	   delay |= 0xb0;
-         } else if(temp == 6) {
-            delay &= 0x0f;
- 	   delay |= 0xc0;
-+        } else if(temp > 7) {	/* 1280x1024 BIOS */
-+	   delay = 0x35;
-         }
--        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);
-      } else {
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
-      }
-@@ -11118,7 +11368,7 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS
- 
-   if(ROMAddr && SiS_Pr->SiS_UseROM) {
-      romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
--     if(HwDeviceExtension->jChipType == SIS_330) {
-+     if(HwDeviceExtension->jChipType >= SIS_330) {
-         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
-      }
-   }
-@@ -11150,7 +11400,7 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS
- 
-   if(ROMAddr && SiS_Pr->SiS_UseROM) {
-      romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
--     if(HwDeviceExtension->jChipType == SIS_330) {
-+     if(HwDeviceExtension->jChipType >= SIS_330) {
-         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
-      }
-   }
-@@ -11198,7 +11448,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_
- 
-   if(ROMAddr && SiS_Pr->SiS_UseROM) {
-   	OutputSelect = ROMAddr[0xf3];
--	if(HwDeviceExtension->jChipType == SIS_330) {
-+	if(HwDeviceExtension->jChipType >= SIS_330) {
- 	    OutputSelect = ROMAddr[0x11b];
- 	}
-   }
-@@ -11262,17 +11512,17 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
-    */
-   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-      romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
--     if(HwDeviceExtension->jChipType == SIS_330) {
-+     if(HwDeviceExtension->jChipType >= SIS_330) {
-         romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
-      }
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
--	if(HwDeviceExtension->jChipType == SIS_330) {
-+	if(HwDeviceExtension->jChipType >= SIS_330) {
- 	   romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
- 	}
- 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
- 	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
--	   if(HwDeviceExtension->jChipType == SIS_330) {
-+	   if(HwDeviceExtension->jChipType >= SIS_330) {
-               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
-            }
- 	}
-@@ -11296,19 +11546,19 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
-      }
-   }
- 
--  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
-+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
-      if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
--        if(resinfo == 6) {
-+        if(resinfo == SIS_RI_640x480) {
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
--	} else if (resinfo == 7) {
-+	} else if (resinfo == SIS_RI_800x600) {
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
--	} else if (resinfo == 8) {
-+	} else if (resinfo == SIS_RI_1024x768) {
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
-@@ -11323,7 +11573,9 @@ SiS_OEM310Setting(SiS_Private *SiS_Pr, P
-                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
- {
-    SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
--   /* TW: The TV functions are not for LVDS */
-+
-+   if(SiS_Pr->UseCustomMode) return;
-+
-    if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
-        SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-        SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-@@ -11335,7 +11587,7 @@ SiS_OEM310Setting(SiS_Private *SiS_Pr, P
- }
- 
- /* FinalizeLCD
-- * This finalizes some Part1 registers for the very panel used.
-+ * This finalizes some CRT2 registers for the very panel used.
-  * If we have a backup if these registers, we use it; otherwise
-  * we set the register according to most BIOSes. However, this
-  * function looks quite different in every BIOS, so you better
-@@ -11350,6 +11602,9 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
- 
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
- 
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-+  if(SiS_Pr->UseCustomMode) return;
-+
-   if(ModeNo <= 0x13) {
- 	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
- 	modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-@@ -11358,20 +11613,31 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
- 	modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-   }
- 
-+  if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
-+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
-+  }
-+
-   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
- 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
- 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {   /* For all panels? */
-+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
-      }
-      tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-      tempch &= 0xf0;
-      tempch >>= 4;
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-+        if(tempch == 0x03) {
-+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
-+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
-+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
-+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
-+	}
- 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- 	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
--	}
--	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {	
-+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
- 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
- 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
-@@ -11387,14 +11653,14 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
- 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
- 	       if(ModeNo <= 0x13) {
- 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
--		  if((resinfo == 0) && (resinfo == 2)) return;
-+		  if((resinfo == 0) || (resinfo == 2)) return;
- 		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
--		  if((resinfo == 1) && (resinfo == 3)) return;
-+		  if((resinfo == 1) || (resinfo == 3)) return;
- 	       }
- 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
--	       if((ModeNo > 0x13) && (resinfo == 8)) {
-+	       if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
- 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
--#if 0	       
-+#if 0
- 	          tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
- 		  tempbx--;
- 		  temp = tempbx & 0xff;
-@@ -11449,7 +11715,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
- 	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
- 	tempbx = (tempbh << 8) | tempbl;
- 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
--	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
-+	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
- 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
- 	      	tempbx = 770;
- 	      } else {
-@@ -11477,67 +11743,56 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
-   }
- }
- 
--#if 0
--/* TW: New and checked from 650/301LV BIOS */
--/* This might clash with newer "FinalizeLCD()" function */
-+#endif
-+
-+
-+/*  =================  SiS 300 O.E.M. ================== */
-+
-+#ifdef SIS300
-+
- void
--SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
--                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
-+SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
- {
--   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
--
--   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
-+  USHORT crt2crtc=0, modeflag, myindex=0;
-+  UCHAR  temp;
-+  int i;
- 
--   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
--      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
--      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
--      tempbh &= 0x38;
--      tempbh >>= 3;
--      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
--      tempbx = (tempbh << 8) | tempbl;
--      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
--      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
--      tempah = (tempbx & 0xff00) >> 8;
--      tempah &= 0x07;
--      tempah <<= 3;
--      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
--      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
--      tempah &= 0x0f;
--      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
--      tempah &= 0x0f;
--      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
--      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
--      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
--      tempah -= 8;
--      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
--   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
--      tempbh &= 0x70;
--      tempbh >>= 4;
--      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
--      tempbx = (tempbh << 8) | tempbl;
--      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
--           tempbx -= 0x1e;
--	   tempcl &= 0x0f;
--	   tempcl -= 4;
--	   tempcl &= 0x0f;
--      }
--      tempbl = tempbx & 0x00ff;
--      tempbh = (tempbx >> 8) & 0x00ff;
--      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
--      tempbh <<= 4;
--      tempbh |= tempcl;
--      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
--   }
--}
--#endif
-+  if(ModeNo <= 0x13) {
-+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-+	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-+  } else {
-+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-+	crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
-+  }
- 
--#endif
-+  crt2crtc &= 0x3f;
- 
-+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
-+  }
- 
--/*  =================  SiS 300 O.E.M. ================== */
-+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-+     if(modeflag & HalfDCLK) myindex = 1;
- 
--#ifdef SIS300
-+     if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-+        for(i=0; i<7; i++) {
-+           if(barco_p1[myindex][crt2crtc][i][0]) {
-+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
-+	                      barco_p1[myindex][crt2crtc][i][0],
-+	   	   	      barco_p1[myindex][crt2crtc][i][2],
-+			      barco_p1[myindex][crt2crtc][i][1]);
-+	   }
-+        }
-+     }
-+     temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-+     if(temp & 0x80) {
-+        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
-+        temp++;
-+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);
-+     }
-+  }
-+}
- 
- #if 0   /* Not used */
- static USHORT
-@@ -11582,7 +11837,7 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_H
- 
-   if(HwDeviceExtension->jChipType == SIS_300) {
- 
--    tempbx = SiS_Pr->SiS_LCDResInfo - 2;
-+    tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
-     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
-@@ -11636,24 +11891,29 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS
- {
-   USHORT index,temp,romptr=0;
- 
-+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
-+
-   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-      if(!(ROMAddr[0x237] & 0x01)) return;
-      if(!(ROMAddr[0x237] & 0x02)) return;
-      romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
-   }
- 
--  /* TW: The Panel Compensation Delay should be set according to tables
--   *     here. Unfortunately, various BIOS versions don't case about
--   *     a uniform way using eg. ROM byte 0x220, but use different
--   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
--   *     Thus we don't set this if the user select a custom pdc or if
--   *     we otherwise detected a valid pdc.
-+  /* The Panel Compensation Delay should be set according to tables
-+   * here. Unfortunately, various BIOS versions don't case about
-+   * a uniform way using eg. ROM byte 0x220, but use different
-+   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
-+   * Thus we don't set this if the user select a custom pdc or if
-+   * we otherwise detected a valid pdc.
-    */
-   if(HwDeviceExtension->pdc) return;
- 
-   temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
- 
--  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
-+  if(SiS_Pr->UseCustomMode)
-+     index = 0;
-+  else
-+     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
- 
-   if(HwDeviceExtension->jChipType != SIS_300) {
- 	if(romptr) {
-@@ -11700,9 +11960,9 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS
- 
- static void
- SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
--               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
-+              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
- {
--#if 0  /* TW: Unfinished; VData table missing */
-+#if 0  /* Unfinished; Data table missing */
-   USHORT index,temp;
- 
-   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-@@ -11899,25 +12159,29 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_
- 
- void
- SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
--		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
-+		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-+		  USHORT RefTableIndex)
- {
--  USHORT ModeIdIndex;
-+  USHORT OEMModeIdIndex=0;
- 
--  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
--  if(!(ModeIdIndex)) return;
-+  if(!SiS_Pr->UseCustomMode) {
-+     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
-+     if(!(OEMModeIdIndex)) return;
-+  }
- 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
--       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-+       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-+            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-        }
-   }
-+  if(SiS_Pr->UseCustomMode) return;
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
--       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-+       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
--       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
--    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
--       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-+       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-+    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-+       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
-        }
-   }
- }
---- linux-2.6.0-test1/drivers/video/sis/init301.h	2003-06-14 12:18:21.000000000 -0700
-+++ 25/drivers/video/sis/init301.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,20 +1,39 @@
--/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
-+/* $XFree86$ */
-+/*
-+ * Data and prototypes for init301.c
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ */
-+
- #ifndef  _INIT301_
- #define  _INIT301_
- 
- #include "osdef.h"
-+
- #include "initdef.h"
- #include "vgatypes.h"
- #include "vstruct.h"
- 
--#ifdef TC
--#include <stdio.h>
--#include <string.h>
--#include <conio.h>
--#include <dos.h>
--#include <stdlib.h>
--#endif
--
- #ifdef LINUX_XF86
- #include "xf86.h"
- #include "xf86Pci.h"
-@@ -24,6 +43,9 @@
- #endif
- 
- #ifdef LINUX_KERNEL
-+#ifdef SIS_CP
-+#undef SIS_CP
-+#endif
- #include <linux/config.h>
- #include <linux/version.h>
- #include <asm/io.h>
-@@ -35,24 +57,60 @@
- #endif
- #endif
- 
--#ifdef WIN2000
--#include <stdio.h>
--#include <string.h>
--#include <miniport.h>
--#include "dderror.h"
--#include "devioctl.h"
--#include "miniport.h"
--#include "ntddvdeo.h"
--#include "video.h"
--#include "sisv.h"
--#endif
-+const UCHAR SiS_HiVisionTable[3][64] = {
-+  {
-+    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
-+    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
-+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
-+    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
-+    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
-+    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
-+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
-+    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
-+  },
-+  {
-+    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
-+    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
-+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
-+    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
-+    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
-+    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
-+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
-+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
-+  },
-+  {
-+    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
-+    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
-+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
-+    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
-+    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
-+    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
-+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
-+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
-+  }
-+};
- 
--#if 0
--extern   const USHORT   SiS_MDA_DAC[];
--extern   const USHORT   SiS_CGA_DAC[];
--extern   const USHORT   SiS_EGA_DAC[];
--extern   const USHORT   SiS_VGA_DAC[];
--#endif
-+const UCHAR SiS_HiTVGroup3_1[] = {
-+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
-+    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
-+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
-+    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
-+    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
-+    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
-+    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
-+    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
-+};
-+
-+const UCHAR SiS_HiTVGroup3_2[] = {
-+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
-+    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
-+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
-+    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
-+    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
-+    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
-+    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
-+    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
-+};
- 
- extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
- 
-@@ -129,7 +187,6 @@ void     SiS_GetVBInfo(SiS_Private *SiS_
- BOOLEAN  SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
- BOOLEAN  SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
- BOOLEAN  SiS_BridgeInSlave(SiS_Private *SiS_Pr);
--void     SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SetTVSystem(SiS_Private *SiS_Pr);
- void     SiS_LongWait(SiS_Private *SiS_Pr);
- USHORT   SiS_GetQueueConfig(SiS_Private *SiS_Pr);
-@@ -149,7 +206,7 @@ void     SiS_GetLVDSDesPtrA(SiS_Private 
-                             USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
- #endif			    
- void     SiS_SetTPData(SiS_Private *SiS_Pr);
--void     SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
-+void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
- void     SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                          USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-@@ -178,20 +235,18 @@ USHORT   SiS_SetSCLKHigh(SiS_Private *Si
- USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
- USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
- USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
--USHORT   SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
--#ifdef LINUX_XF86
--USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
--USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
--#endif
-+
- #ifdef SIS315H
- void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
- void     SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
--                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-+                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
- #endif
- #ifdef SIS300
- void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
--                           UCHAR *ROMAddr,USHORT ModeNo);
-+                           UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-+void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-+			UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
- #endif
- BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
- 
-@@ -200,8 +255,8 @@ BOOLEAN  SiS_GetLCDResInfo(SiS_Private *
- /* void    SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex); */
- 
--BOOLEAN  SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
--                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-+BOOLEAN  SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-+                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
- void     SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-@@ -237,19 +292,19 @@ void     SiS_VBWait(SiS_Private *SiS_Pr)
- void     SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- 
--void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
-+void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
- #ifdef SIS315H
- void     SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                             USHORT BaseAddr);
--void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
-+void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- void     SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- void     SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- void     SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- void     SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- BOOLEAN  SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
--void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
-+void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr,  PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
- #ifdef NEWCH701x
- void     SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
-@@ -289,73 +344,21 @@ extern   void     SiS_LoadDAC(SiS_Privat
- extern   UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
- #endif
- 
--#ifdef LINUX_XF86
- /* DDC functions */
--USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-+USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-+                         USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
- USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
- USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
- USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
- void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
- USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
- USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
--USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
--USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
--                       USHORT DDCdatatype, unsigned char *buffer);
-+USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
-+USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-+		       USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
-+#ifdef LINUX_XF86
-+USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-+USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
- #endif
- 
--const UCHAR SiS_HiVisionTable[3][64] = {
--  { 
--    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
--    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
--    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
--    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
--    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
--    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
--    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
--    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
--  },
--  { 
--    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
--    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
--    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
--    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
--    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
--    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
--    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
--    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
--  },
--  { 
--    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 
--    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 
--    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, 
--    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, 
--    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, 
--    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, 
--    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, 
--    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 
--  }
--};
--
--const UCHAR SiS_HiTVGroup3_1[] = {
--    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
--    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
--    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
--    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
--    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
--    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
--    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
--    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
--};
--
--const UCHAR SiS_HiTVGroup3_2[] = {
--    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
--    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
--    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
--    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
--    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
--    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
--    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
--    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
--};
--
- #endif
---- linux-2.6.0-test1/drivers/video/sis/init.c	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/video/sis/init.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,24 +1,11 @@
- /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
- /*
-- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
-+ * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330/660
-  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
-  *
-  * Assembler-To-C translation
-- * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
-- * Minor parts Copyright SiS, Inc.
-- *
-- * Based on BIOS
-- *     1.10.07, 1.10a for 650/CH7019
-- *     1.11.21a for 740/CH7019
-- *     1.11.05 for 650/LVDS (w/o Chrontel)
-- *     1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
-- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
-- *     2.06.50 for 630/301B (dual VGA)
-- *     2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
-- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
-- *     1.09b for 315/301(B)
-- *     1.16.51 for 300+301LV (ECS A907)
-- *     1.01.03 for 330 (Xabre 400)
-+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
-+ * Formerly based on non-functional code-fragements by SiS, Inc.
-  *
-  * Permission to use, copy, modify, distribute, and sell this software and its
-  * documentation for any purpose is hereby granted without fee, provided that
-@@ -61,12 +48,12 @@
- #ifdef LINUX_XF86
- BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
--DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
--#ifdef SISDUALHEAD /* TW: For dual head */
-+DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
-+#ifdef SISDUALHEAD
- BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
- BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
--                       ScrnInfoPtr pScrn, DisplayModePtr mode);
-+                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
- #endif /* dual head */
- #endif /* linux_xf86 */
- 
-@@ -90,49 +77,199 @@ BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, 
- static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
-                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
- 
--static void DelaySeconds(int seconds);
--void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
--
- static void
--DelaySeconds(int seconds)
-+InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
--  int i;
--#ifdef WIN2000
--  int j;
--#endif
--
--  for (i=0;i<seconds;i++) {
--#ifdef TC
--    delay(1000);
--#endif
--
--#ifdef WIN2000
--    for (j=0;j<20000;j++)
--      VideoPortStallExecution(50);
--#endif
--
--#ifdef WINCE_HEADER
--#endif
--
--#ifdef LINUX_KERNEL
--#endif
--  }
--}
--
--void
--SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
--{
--  OutPortByte(0x80, code);
--  DelaySeconds(0x3);
-+   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
-+   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
-+   SiS_Pr->SiS_StandTable    = SiS_StandTable;
-+   if(HwDeviceExtension->jChipType < SIS_315H) {
-+      SiS_StandTable[0x04].CRTC[4] = 0x2b;
-+      SiS_StandTable[0x05].CRTC[4] = 0x2b;
-+      SiS_StandTable[0x06].CRTC[4] = 0x54;
-+      SiS_StandTable[0x06].CRTC[5] = 0x80;
-+      SiS_StandTable[0x0d].CRTC[4] = 0x2b;
-+      SiS_StandTable[0x0e].CRTC[4] = 0x54;
-+      SiS_StandTable[0x0e].CRTC[5] = 0x80;
-+      SiS_StandTable[0x11].CRTC[4] = 0x54;
-+      SiS_StandTable[0x11].CRTC[5] = 0x80;
-+      SiS_StandTable[0x11].CRTC[16] = 0x83;
-+      SiS_StandTable[0x11].CRTC[17] = 0x85;
-+      SiS_StandTable[0x12].CRTC[4] = 0x54;
-+      SiS_StandTable[0x12].CRTC[5] = 0x80;
-+      SiS_StandTable[0x12].CRTC[16] = 0x83;
-+      SiS_StandTable[0x12].CRTC[17] = 0x85;
-+      SiS_StandTable[0x13].CRTC[5] = 0xa0;
-+      SiS_StandTable[0x17].CRTC[5] = 0xa0;
-+      SiS_StandTable[0x1a].CRTC[4] = 0x54;
-+      SiS_StandTable[0x1a].CRTC[5] = 0x80;
-+      SiS_StandTable[0x1a].CRTC[16] = 0xea;
-+      SiS_StandTable[0x1a].CRTC[17] = 0x8c;
-+      SiS_StandTable[0x1b].CRTC[4] = 0x54;
-+      SiS_StandTable[0x1b].CRTC[5] = 0x80;
-+      SiS_StandTable[0x1b].CRTC[16] = 0xea;
-+      SiS_StandTable[0x1b].CRTC[17] = 0x8c;
-+      SiS_StandTable[0x1c].CRTC[4] = 0x54;
-+      SiS_StandTable[0x1c].CRTC[5] = 0x80;
-+   } else {
-+      SiS_StandTable[0x04].CRTC[4] = 0x2c;
-+      SiS_StandTable[0x05].CRTC[4] = 0x2c;
-+      SiS_StandTable[0x06].CRTC[4] = 0x55;
-+      SiS_StandTable[0x06].CRTC[5] = 0x81;
-+      SiS_StandTable[0x0d].CRTC[4] = 0x2c;
-+      SiS_StandTable[0x0e].CRTC[4] = 0x55;
-+      SiS_StandTable[0x0e].CRTC[5] = 0x81;
-+      SiS_StandTable[0x11].CRTC[4] = 0x55;
-+      SiS_StandTable[0x11].CRTC[5] = 0x81;
-+      SiS_StandTable[0x11].CRTC[16] = 0x82;
-+      SiS_StandTable[0x11].CRTC[17] = 0x84;
-+      SiS_StandTable[0x12].CRTC[4] = 0x55;
-+      SiS_StandTable[0x12].CRTC[5] = 0x81;
-+      SiS_StandTable[0x12].CRTC[16] = 0x82;
-+      SiS_StandTable[0x12].CRTC[17] = 0x84;
-+      SiS_StandTable[0x13].CRTC[5] = 0xb1;
-+      SiS_StandTable[0x17].CRTC[5] = 0xb1;
-+      SiS_StandTable[0x1a].CRTC[4] = 0x55;
-+      SiS_StandTable[0x1a].CRTC[5] = 0x81;
-+      SiS_StandTable[0x1a].CRTC[16] = 0xe9;
-+      SiS_StandTable[0x1a].CRTC[17] = 0x8b;
-+      SiS_StandTable[0x1b].CRTC[4] = 0x55;
-+      SiS_StandTable[0x1b].CRTC[5] = 0x81;
-+      SiS_StandTable[0x1b].CRTC[16] = 0xe9;
-+      SiS_StandTable[0x1b].CRTC[17] = 0x8b;
-+      SiS_StandTable[0x1c].CRTC[4] = 0x55;
-+      SiS_StandTable[0x1c].CRTC[5] = 0x81;
-+   }
-+
-+   SiS_Pr->SiS_NTSCPhase    = SiS_NTSCPhase;
-+   SiS_Pr->SiS_PALPhase     = SiS_PALPhase;
-+   SiS_Pr->SiS_NTSCPhase2   = SiS_NTSCPhase2;
-+   SiS_Pr->SiS_PALPhase2    = SiS_PALPhase2;
-+   SiS_Pr->SiS_PALMPhase    = SiS_PALMPhase;
-+   SiS_Pr->SiS_PALNPhase    = SiS_PALNPhase;
-+   SiS_Pr->SiS_PALMPhase2   = SiS_PALMPhase2;
-+   SiS_Pr->SiS_PALNPhase2   = SiS_PALNPhase2;
-+   SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
-+
-+   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
-+   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
-+   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
-+   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
-+   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
-+   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
-+   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
-+   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
-+   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
-+
-+   SiS_Pr->SiS_StPALData   = SiS_StPALData;
-+   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
-+   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
-+   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
-+/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData;  */
-+   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
-+   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
-+
-+   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
-+   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
-+
-+   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
-+   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
-+   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
-+   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
-+   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
-+   SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
-+   SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
-+   SiS_Pr->SiS_ExtLCD1280x768Data   = SiS_ExtLCD1280x768Data;
-+   SiS_Pr->SiS_StLCD1280x768Data    = SiS_StLCD1280x768Data;
-+   SiS_Pr->SiS_NoScaleData1280x768  = SiS_NoScaleData1280x768;
-+   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
-+
-+   SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
-+   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
-+   SiS_Pr->SiS_LVDS800x600Data_2   = SiS_LVDS800x600Data_2;
-+   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
-+   SiS_Pr->SiS_LVDS1024x768Data_2  = SiS_LVDS1024x768Data_2;
-+   SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
-+   SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
-+   SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
-+   SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
-+   SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
-+   SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
-+   SiS_Pr->SiS_LVDS1280x768Data_1  = SiS_LVDS1280x768Data_1;
-+   SiS_Pr->SiS_LVDS1280x768Data_2  = SiS_LVDS1280x768Data_2;
-+   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
-+   SiS_Pr->SiS_LVDS1024x600Data_2  = SiS_LVDS1024x600Data_2;
-+   SiS_Pr->SiS_LVDS1152x768Data_1  = SiS_LVDS1152x768Data_1;
-+   SiS_Pr->SiS_LVDS1152x768Data_2  = SiS_LVDS1152x768Data_2;
-+   SiS_Pr->SiS_LVDSXXXxXXXData_1   = SiS_LVDSXXXxXXXData_1;
-+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x960Data_1;
-+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x960Data_2;
-+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
-+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x1024Data_1;
-+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x1024Data_2;
-+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
-+   SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
-+
-+   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
-+   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
-+   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
-+   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
-+
-+   SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
-+   SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
-+   SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
-+   SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
-+   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
-+   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
-+
-+   SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
-+   SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
-+   SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
-+   SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
-+   SiS_Pr->LVDS1024x768Des_2  = SiS_PanelType1076_2;
-+   SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
-+   SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
-+   SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
-+
-+   SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
-+   SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
-+
-+   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
-+   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
-+   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
-+   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
-+
-+   SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
-+   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
-+   SiS_Pr->SiS_LVDSCRT11152x768_1    = SiS_LVDSCRT11152x768_1;
-+   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = SiS_LVDSCRT11280x768_1_H;
-+   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
-+   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = SiS_LVDSCRT11152x768_1_H;
-+   SiS_Pr->SiS_LVDSCRT11280x768_2    = SiS_LVDSCRT11280x768_2;
-+   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
-+   SiS_Pr->SiS_LVDSCRT11152x768_2    = SiS_LVDSCRT11152x768_2;
-+   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = SiS_LVDSCRT11280x768_2_H;
-+   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
-+   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
-+   SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
-+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS_LVDSCRT1XXXxXXX_1;
-+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS_LVDSCRT1XXXxXXX_1_H;
-+   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
-+   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
-+   SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
-+   SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
-+   SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
-+   SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
- }
- 
- #ifdef SIS300
- static void
- InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-+   InitCommonPointer(SiS_Pr, HwDeviceExtension);
-+
-    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
-    SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
--   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
-    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
-    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
-    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
-@@ -141,15 +278,12 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    } else {
-       SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
-    }
-+#ifdef LINUXBIOS
-    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
-+#endif
-    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
-    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
-    SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
--   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
--   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
--
--   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
--   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
- 
-    SiS_Pr->SiS_SR15  = SiS300_SR15;
- 
-@@ -178,15 +312,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
- #endif
- 
--   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
--   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
--   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
--   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
--   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
--   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
--   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
--   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
--
-    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
-    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
-    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
-@@ -195,68 +320,18 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
-    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
-    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
--   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
--   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
--   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
--   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
--   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
--   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
--   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
--
--   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
--   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
--   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
--   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
--/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;  */
--   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
--   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
--
--   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
--   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
--   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
--   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
--   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
--   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
--   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
--   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
- 
-    SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
-    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
- 
--   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
--   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
--   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
--   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
--   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
--   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
--   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
--   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
--   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
--   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
--   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
--   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
--   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
--   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
--   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
--   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
--   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
--   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
--   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
--   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
--   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
--   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
--   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
--   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
--   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
--   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
--   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
-    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
-    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
--   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
--   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
-+   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; 			   /* not supported on 300 series */
-+   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; 			   /* not supported on 300 series */
-    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
-    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
-    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
-+
-    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
-    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
-    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
-@@ -289,32 +364,28 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
-    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
-    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
--   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
--   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
--   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
--   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
--   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
--   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
-+
-+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
-+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
-+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
-+   }
-+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
-+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
-+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
-+   }
-+
-    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
-    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
-    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
--   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
--   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
-    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
-    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
-    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
--   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
--   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
-    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
-    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
-    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
--   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
--   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
-    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
-    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
-    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
--   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
--   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
-    SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
-    SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
-    SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
-@@ -339,7 +410,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
-    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
- 
--   /* TW: New from 300/301LV BIOS */
-    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
-    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
-    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
-@@ -353,7 +423,7 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
-    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
- 
--   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
-+   /* TW: LCDResInfo will on 300 series be translated to 315 series definitions */
-    SiS_Pr->SiS_Panel320x480   = Panel_320x480;
-    SiS_Pr->SiS_Panel640x480   = Panel_640x480;
-    SiS_Pr->SiS_Panel800x600   = Panel_800x600;
-@@ -362,13 +432,17 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
-    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
-    SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
--   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
--   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
--   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
--   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
-+   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
-+   SiS_Pr->SiS_Panel1600x1200 = 255;  		/* TW: Something illegal */
-+   SiS_Pr->SiS_Panel1400x1050 = 255;  		/* TW: Something illegal */
-+   SiS_Pr->SiS_Panel640x480_2 = 255;  		/* TW: Something illegal */
-+   SiS_Pr->SiS_Panel640x480_3 = 255;  		/* TW: Something illegal */
-+   SiS_Pr->SiS_Panel1152x864  = 255;   		/* TW: Something illegal */
-    SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
-    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
-    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
-+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
-+   SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
- }
- #endif
- 
-@@ -376,29 +450,33 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
- static void
- InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
- {
-+   InitCommonPointer(SiS_Pr, HwDeviceExtension);
-+
-    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
--   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
-    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
-    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
-    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
-    /* TW: MCLK is different */
--   if(HwDeviceExtension->jChipType == SIS_330) {
-+#ifdef LINUXBIOS
-+   if(HwDeviceExtension->jChipType == SIS_660) {
-+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 660 */
-+   } else if(HwDeviceExtension->jChipType == SIS_330) {
-+#endif
-       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
-+#ifdef LINUXBIOS
-    } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
-       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
-    } else {
-       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
-    }
-+#endif
-    SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
-+#ifdef LINUXBIOS
-    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
-+#endif
-    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
-    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
-    SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
--   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
--   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
--
--   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
--   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
- 
-    SiS_Pr->SiS_SR15  = SiS310_SR15;
- 
-@@ -427,16 +505,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
- #endif
- 
--   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
--   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
--   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
--   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
--   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
--   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
--   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
--   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
--   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
--
-    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
-    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
-    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
-@@ -445,62 +513,10 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
-    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
-    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
--   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
--   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
--   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
--   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
--   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
--   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
--   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
--
--   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
--   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
--   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
--   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
--/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;  */
--   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
--   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
--
--   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
--   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
--   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
--   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
--   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
--   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
--   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
--   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
--   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
- 
--   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
-+   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
-    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
- 
--   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
--   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
--   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
--   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
--   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
--   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
--   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
--   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
--   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
--   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
--   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
--   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
--   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
--   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
--   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
--   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
--   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
--   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
--   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
--   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
--   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
--   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
--   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
--   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
--   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
--   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
--   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
-    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
-    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
-    SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
-@@ -508,6 +524,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
-    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
-    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
-+
-    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
-    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
-    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
-@@ -540,19 +557,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
-    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
-    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
--   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
--   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
--
--   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
--   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
--   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
--   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
--   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
--   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
--   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
--   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
- 
--   /* TW: New from 650/301LV BIOS */
-    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
-    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
-    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
-@@ -566,51 +571,32 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
-    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
- 
--   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
--   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
--   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
--   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
--
-    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
-    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
-    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
-    SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
--   SiS_Pr->SiS_LVDSCRT11280x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
--   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
--   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
-    SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
-    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
-    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
-    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
-    SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
--   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
--   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
--   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
-    SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
-    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
-    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
-    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
-    SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
--   SiS_Pr->SiS_LVDSCRT11280x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
--   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
--   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
-    SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
-    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
-    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
-    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
-    SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
--   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
--   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
--   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
-    SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
--   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
--   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
--   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
--   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
--   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
--   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
--   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
--   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
-+   SiS_Pr->SiS_CHTVCRT1UNTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
-+   SiS_Pr->SiS_CHTVCRT1ONTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
-+   SiS_Pr->SiS_CHTVCRT1UPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
-+   SiS_Pr->SiS_CHTVCRT1OPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-+   SiS_Pr->SiS_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
-+
-    SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
-    SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
-    SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
-@@ -620,6 +606,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
-    SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
-    SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
-+
-    SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
-    SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
-    SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
-@@ -640,6 +627,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
-    SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
-    SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
-+
-    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
-    SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
-    SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
-@@ -662,9 +650,13 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
-    SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
-    SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
-    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
-+   SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
-+   SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
-    SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
-    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
-    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
-+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
-+   SiS_Pr->SiS_PanelBarco1366 = 255;
- }
- #endif
- 
-@@ -727,7 +719,8 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
-       (HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330))
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660))
-      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
- #endif
- 
-@@ -896,7 +889,8 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
-       (HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330)) {
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660)) {
-    	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
-    	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
-    }
-@@ -953,14 +947,15 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
-    if((HwDeviceExtension->jChipType == SIS_315H)   ||
-       (HwDeviceExtension->jChipType == SIS_315)    ||
-       (HwDeviceExtension->jChipType == SIS_315PRO) ||
--      (HwDeviceExtension->jChipType == SIS_330) ) {
-+      (HwDeviceExtension->jChipType == SIS_330)) {
-       	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
-           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
-         }
-    }
-    if((HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_650)) {
-+      (HwDeviceExtension->jChipType == SIS_650) ||
-+      (HwDeviceExtension->jChipType == SIS_660)) {
-         if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
-           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
-         }
-@@ -977,7 +972,7 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
-    if((HwDeviceExtension->jChipType != SIS_540) &&
-       (HwDeviceExtension->jChipType != SIS_630) &&
-       (HwDeviceExtension->jChipType != SIS_730)){
--     	for(i=0x15;i<0x1C;i++) {
-+     	for(i=0x15; i<0x1C; i++) {
-        	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
-      	}
-    }
-@@ -1023,7 +1018,8 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
-       (HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330))
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660))
-      	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
- #endif
- 
-@@ -1180,7 +1176,8 @@ SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_P
- #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
--     (HwDeviceExtension->jChipType == SIS_330)) {
-+     (HwDeviceExtension->jChipType == SIS_330) ||
-+     (HwDeviceExtension->jChipType == SIS_660)) {
- #if 0 /* TW: This is not required */
-         /* TW: Read POWER_ON_TRAP and copy to CR37 */
-     	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-@@ -1299,7 +1296,7 @@ SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr,
- #endif
- /* ===============  SiS 300 dram sizing end    =============== */
- 
--/* ============  SiS 310/325 dram sizing begin  ============== */
-+/* ============  SiS 315 dram sizing begin  ============== */
- #ifdef SIS315H
- 
- /* TW: Moved Get310DRAMType further down */
-@@ -1893,8 +1890,7 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, 
-    if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
-      data = *SiS_Pr->pSiS_SoftSetting & 0x03;
-    } else {
--     if((HwDeviceExtension->jChipType > SIS_315PRO) &&
--        (HwDeviceExtension->jChipType < SIS_330)) {
-+     if(IS_SIS550650740660) {
-         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
-      } else {	/* TW: 315, 330 */
-         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
-@@ -1934,13 +1930,17 @@ void SiSRegInit(SiS_Private *SiS_Pr, USH
-    SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
-    SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
-    SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
--   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
--   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
--   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
--   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
--   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
--   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
--   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
-+   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
-+   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
-+   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
-+   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;     /* Digital video interface registers (LCD) */
-+   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;     /* 301 TV Encoder registers */
-+   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;     /* 301 Macrovision registers */
-+   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;     /* 301 VGA2 (and LCD) registers */
-+   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
-+   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                  /* DDC Port ( = P3C4, SR11/0A) */
-+   SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
-+   SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
- }
- 
- void
-@@ -1965,7 +1965,8 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_
-       (HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330)) {
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660)) {
-       /* TW: This seems to be done the same way on these chipsets */
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
-@@ -1987,10 +1988,14 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_
- 
-    SiS_Pr->SiS_ChrontelInit = 0;
- 
--   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
--   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
--   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
-+#if 0
-+   if(HwDeviceExtension->jChipType >= SIS_315H) {
-+      if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
-+   	 SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
-+   	 SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
-+      }
-    }
-+#endif
- 
- #ifdef SIS300
-    if((HwDeviceExtension->jChipType == SIS_540) ||
-@@ -2015,11 +2020,14 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_
-    if((HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330))
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660))
-     {
--        /* TW: CR37 is different on 310/325 series */
-+        /* TW: CR37 is different on 315 series */
-+#if 0
-         if(SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
-              SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
-+#endif
- 
- 	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-       	temp = (temp & 0x0E) >> 1;
-@@ -2044,7 +2052,8 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_
-       (HwDeviceExtension->jChipType == SIS_550) ||
-       (HwDeviceExtension->jChipType == SIS_650) ||
-       (HwDeviceExtension->jChipType == SIS_740) ||
--      (HwDeviceExtension->jChipType == SIS_330))
-+      (HwDeviceExtension->jChipType == SIS_330) ||
-+      (HwDeviceExtension->jChipType == SIS_660))
-      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
- #endif
- 
-@@ -2073,14 +2082,21 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr
- 	      SiS_Pr->SiS_UseROM = TRUE;
- 	 else SiS_Pr->SiS_UseROM = FALSE;
-      } else if(HwDeviceExtension->jChipType < SIS_315H) {
-+#if 0
-         /* TW: Rest of 300 series: We don't use the ROM image if
- 	 *     the BIOS version < 2.0.0 as such old BIOSes don't
- 	 *     have the needed data at the expected locations.
- 	 */
-         if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
- 	else                     SiS_Pr->SiS_UseROM = TRUE;
-+#else
-+	/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
-+	 * the others do as well
-+	 */
-+	SiS_Pr->SiS_UseROM = TRUE;
-+#endif
-      } else {
--        /* TW: 310/325/330 series stick to the standard */
-+        /* TW: 315/330 series stick to the standard */
- 	SiS_Pr->SiS_UseROM = TRUE;
-      }
-    } else SiS_Pr->SiS_UseROM = FALSE;
-@@ -2104,24 +2120,27 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS
-    SiS_Pr->UseCustomMode = FALSE;
- 
-    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
--   
--         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 
--	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
--		
-+
-+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
-+	 	SiS_Pr->CHDisplay,
-+		(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
-+		   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
-+		      SiS_Pr->CVDisplay)));
-+
- 	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
--   
-+
-    }
--   
--   ModeNo = SiS_CalcModeIndex(pScrn, mode);
-+
-+   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
-    if(!ModeNo) return FALSE;
- 
--   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
-+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
- 
-    return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));   
- }
- 
- #ifdef SISDUALHEAD
--/* TW: Set CRT1 mode (used for dual head) */
-+/* TW: Set CRT1 mode (used for dual head and MergedFB) */
- BOOLEAN
- SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-                DisplayModePtr mode, BOOLEAN IsCustom)
-@@ -2134,31 +2153,37 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
-    SISEntPtr pSiSEnt = pSiS->entityPrivate;
-    unsigned char backupreg=0;
-    BOOLEAN backupcustom;
--
-    UShort  ModeNo=0;
-    
-    SiS_Pr->UseCustomMode = FALSE;
--   
-+
-    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
--   
-+
-+         USHORT temptemp = SiS_Pr->CVDisplay;
-+
-+         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-+         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-+
-          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
--	 	"Setting custom mode %dx%d in CRT1\n", 
--	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
-+	 	"Setting custom mode %dx%d on CRT1\n",
-+	 	SiS_Pr->CHDisplay, temptemp);
- 	 ModeNo = 0xfe;
--	 
-+
-    } else {
- 
--         ModeNo = SiS_CalcModeIndex(pScrn, mode);
-+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
-          if(!ModeNo) return FALSE;
- 
-          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
--	 	"Setting mode 0x%x on CRT1\n", ModeNo);
-+	 	"Setting standard mode 0x%x on CRT1\n", ModeNo);
-    }
- 
-    SiSInitPtr(SiS_Pr, HwDeviceExtension);
- 
-    SiSRegInit(SiS_Pr, BaseAddr);
- 
-+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
-+
-    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
- 
-    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
-@@ -2167,7 +2192,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
- 
-    SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
- 
--   /* TW: We don't clear the buffer under X */
-+   /* We don't clear the buffer under X */
-    SiS_Pr->SiS_flag_clearbuffer = 0;
- 
-    /* 1.Openkey */
-@@ -2175,8 +2200,8 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
- 
-    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
- 
-+   /* 2.Get ModeID Table  */
-    if(!SiS_Pr->UseCustomMode) {
--      /* 2.Get ModeID Table  */
-       temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-       if(temp == 0)  return(0);
-    } else {
-@@ -2201,53 +2226,65 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
-    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
- 
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
-+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
-          }
-       }
- 
--      /* TW: New from 650/LV 1.10.6x */
-       if(IS_SIS650) {
--          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
--	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
--	  }
-+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
-+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-+	 }
-       }
-    }
- 
--   /* TW: Set mode on CRT1 */
-+   /* Set mode on CRT1 */
-    SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
- 
--   pSiSEnt->CRT1ModeNo = ModeNo;
--   pSiSEnt->CRT1DMode = mode;
--
--   /* TW: SetPitch: Adapt to virtual size & position */
-+   /* SetPitch: Adapt to virtual size & position */
-    SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
- 
-+   if(pSiS->DualHeadMode) {
-+      pSiSEnt->CRT1ModeNo = ModeNo;
-+      pSiSEnt->CRT1DMode = mode;
-+   }
-+
-+   if(SiS_Pr->UseCustomMode) {
-+      SiS_Pr->CRT1UsesCustomMode = TRUE;
-+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
-+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
-+   } else {
-+      SiS_Pr->CRT1UsesCustomMode = FALSE;
-+   }
-+
-    /* We have to reset CRT2 if changing mode on CRT1 */
--   if(pSiSEnt->CRT2ModeNo != -1) {
--        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
--				"(Re-)Setting mode 0x%x on CRT2\n",
--				pSiSEnt->CRT2ModeNo);
--	backupcustom = SiS_Pr->UseCustomMode;
--	if(SiS_Pr->UseCustomMode) {
--	   SiS_Pr->CRT1UsesCustomMode = TRUE;
--	} else {
--	   SiS_Pr->CRT1UsesCustomMode = FALSE;
--	}
--	SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
--				pSiSEnt->CRT2DMode);
--	SiS_Pr->UseCustomMode = backupcustom;
--	SiS_Pr->CRT1UsesCustomMode = FALSE;
-+   if(pSiS->DualHeadMode) {
-+      if(pSiSEnt->CRT2ModeNo != -1) {
-+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-+				"(Re-)Setting mode for CRT2\n");
-+	 backupcustom = SiS_Pr->UseCustomMode;
-+	 SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
-+			    pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
-+	 SiS_Pr->UseCustomMode = backupcustom;
-+      }
-    }
--   
-+
-+   /* Warning: From here, the custom mode entries in SiS_Pr are
-+    * possibly overwritten
-+    */
-+
-    SiS_HandleCRT1(SiS_Pr);
- 
-+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
-+
-    SiS_DisplayOn(SiS_Pr);
-    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
- 
--   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
-@@ -2266,7 +2303,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
- /* TW: Set CRT2 mode (used for dual head) */
- BOOLEAN
- SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
--               DisplayModePtr mode)
-+               DisplayModePtr mode, BOOLEAN IsCustom)
- {
-    ULONG   temp;
-    USHORT  ModeIdIndex;
-@@ -2276,16 +2313,52 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-    SISPtr  pSiS     = SISPTR(pScrn);
-    SISEntPtr pSiSEnt = pSiS->entityPrivate;
-    unsigned char tempr1, tempr2, backupreg=0;
--   
-+
-    SiS_Pr->UseCustomMode = FALSE;
--   
--   ModeNo = SiS_CalcModeIndex(pScrn, mode);
--   if(!ModeNo) return FALSE;
-+
-+   /* Remember: Custom modes for CRT2 are ONLY supported
-+    * 		-) on 315/330 series,
-+    *           -) on the 301 and 30xB, and
-+    *           -) if CRT2 is LCD or VGA
-+    */
-+
-+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-+
-+	 ModeNo = 0xfe;
-+
-+   } else {
-+
-+         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
-+
-+#ifdef SISMERGED
-+	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
-+#endif
-+
-+         ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes);
-+         if(!ModeNo) return FALSE;
-+
-+   }
-+
-+   /* Save mode info so we can set it from within SetMode for CRT1 */
-+   if(pSiS->DualHeadMode) {
-+      pSiSEnt->CRT2ModeNo = ModeNo;
-+      pSiSEnt->CRT2DMode = mode;
-+      pSiSEnt->CRT2IsCustom = IsCustom;
-+
-+      /* We can't set CRT2 mode before CRT1 mode is set */
-+      if(pSiSEnt->CRT1ModeNo == -1) {
-+    	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-+		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
-+   	 return TRUE;
-+      }
-+   }
- 
-    SiSInitPtr(SiS_Pr, HwDeviceExtension);
- 
-    SiSRegInit(SiS_Pr, BaseAddr);
- 
-+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
-+
-    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
- 
-    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
-@@ -2294,22 +2367,26 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
- 
-    SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
- 
--   /* TW: We don't clear the buffer under X */
-+   /* We don't clear the buffer under X */
-    SiS_Pr->SiS_flag_clearbuffer=0;
- 
--   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
--   pSiSEnt->CRT2ModeNo = ModeNo;
--   pSiSEnt->CRT2DMode = mode;
--
--   /* TW: We can't set CRT2 mode before CRT1 mode is set */
--   if(pSiSEnt->CRT1ModeNo == -1) {
--   	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
--		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
--   	return TRUE;
--   }
-+   if(SiS_Pr->UseCustomMode) {
-+
-+      USHORT temptemp = SiS_Pr->CVDisplay;
-+
-+      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-+      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-+
-+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-+	  "Setting custom mode %dx%d on CRT2\n",
-+	  SiS_Pr->CHDisplay, temptemp);
-+
-+   } else {
- 
--   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
--   		"Setting mode 0x%x on CRT2\n", ModeNo);
-+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-+   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
-+
-+   }
- 
-    /* 1.Openkey */
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-@@ -2317,10 +2394,14 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
- 
-    /* 2.Get ModeID */
--   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
--   if(temp == 0)  return(0);
-+   if(!SiS_Pr->UseCustomMode) {
-+      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-+      if(temp == 0)  return(0);
-+   } else {
-+      ModeIdIndex = 0;
-+   }
- 
--   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-+   /* Determine VBType (301,301B,301LV,302B,302LV) */
-    SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
- 
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-@@ -2343,15 +2424,22 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-       }
-    }
- 
--   /* TW: Get VB information (connectors, connected devices) */
--   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-+   /* Get VB information (connectors, connected devices) */
-+   if(!SiS_Pr->UseCustomMode) {
-+      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-+   } else {
-+      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
-+      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
-+   }
-    SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
-    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
- 
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
-+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
-          }
-       }
-    }
-@@ -2364,17 +2452,19 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-      case VB_CHIP_302:
-      case VB_CHIP_302B:
-      case VB_CHIP_302LV:
--        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-+        SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-         break;
-      case VB_CHIP_UNKNOWN:
--        if (SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
--	    SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
--	    SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
--             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-+        if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
-+	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
-+	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-+           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-   	}
-         break;
-    }
- 
-+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
-+
-    SiS_DisplayOn(SiS_Pr);
-    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
- 
-@@ -2386,7 +2476,6 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-       }
-    }
- 
--   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-@@ -2412,7 +2501,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
-       }
-    }
- 
--   /* TW: SetPitch: Adapt to virtual size & position */
-+   /* SetPitch: Adapt to virtual size & position */
-    SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
- 
-    return TRUE;
-@@ -2448,6 +2537,8 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
- 
-    SiSRegInit(SiS_Pr, BaseAddr);
- 
-+   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
-+
- #ifdef LINUX_XF86
-    if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-    else
-@@ -2458,7 +2549,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
- #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
- #endif
--#endif	 	 
-+#endif
- 
-    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
- 
-@@ -2472,7 +2563,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-    }      
- 
- #ifdef LINUX_XF86
--   /* TW: We never clear the buffer in X */
-+   /* We never clear the buffer in X */
-    ModeNo |= 0x8000;
- #endif
- 
-@@ -2501,10 +2592,10 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-       
-    }
-     
--   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-+   /* Determine VBType (301,301B,301LV,302B,302LV) */
-    SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
- 
--   /* TW: Init/restore some VB registers */
-+   /* Init/restore some VB registers */
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        if(HwDeviceExtension->jChipType >= SIS_315H) {
-          SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-@@ -2525,8 +2616,12 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-        }
-    }
-    
--   /* TW: Get VB information (connectors, connected devices) */
--   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-+   /* Get VB information (connectors, connected devices) */
-+   if(SiS_Pr->UseCustomMode) {
-+      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
-+   } else {
-+      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-+   }
-    SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
-    SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
- 
-@@ -2535,22 +2630,32 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-    if(!temp) return(0);
- 
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
--      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
--         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
-+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
-          }
-       }
- 
--      /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
-       if(IS_SIS650) {
--          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
--	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
--	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
--	  }
-+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
-+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-+	 }
-       }
-    }
- 
--   /* TW: Set mode on CRT1 */
-+   if(SiS_Pr->UseCustomMode) {
-+      SiS_Pr->CRT1UsesCustomMode = TRUE;
-+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
-+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
-+   } else {
-+      SiS_Pr->CRT1UsesCustomMode = FALSE;
-+   }
-+
-+   /* Set mode on CRT1 */
-    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
-    	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
-    } else {
-@@ -2559,7 +2664,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-      }
-    }
- 
--   /* TW: Set mode on CRT2 */
-+   /* Set mode on CRT2 */
-    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
-      switch (HwDeviceExtension->ujVBChipID) {
-      case VB_CHIP_301:
-@@ -2568,18 +2673,20 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-      case VB_CHIP_302:
-      case VB_CHIP_302B:
-      case VB_CHIP_302LV:
--        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-+        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-         break;
-      case VB_CHIP_UNKNOWN:
- 	if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
- 	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
- 	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
--             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-+           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-         break;
-      }
-    }
-    
-    SiS_HandleCRT1(SiS_Pr);
-+
-+   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
-    
-    SiS_DisplayOn(SiS_Pr);
-    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
-@@ -2592,7 +2699,6 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-       }
-    }
- 
--   /* TW: New from 650/LV 1.10.6x and 1.10.7w */
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-@@ -2627,7 +2733,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
- 
- #ifdef LINUX_XF86
-    if(pScrn) {
--      /* TW: SetPitch: Adapt to virtual size & position */
-+      /* SetPitch: Adapt to virtual size & position */
-       if((ModeNo > 0x13) && (dosetpitch)) {
-          SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
-       }
-@@ -2637,7 +2743,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
-    }
- #endif
- 
--#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
-+#ifndef LINUX_XF86  /* We never lock registers in XF86 */
-    if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-    else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
- #endif
-@@ -2646,10 +2752,15 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
- }
- 
- void
--SiS_SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
-+SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
-+{
-+   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
-+}
-+
-+void
-+SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
- {
--   /* For 550 dstn */
--   SiS_Pr->SiS_IF_DEF_DSTN = 1;
-+   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
- }
- 
- void
-@@ -2663,13 +2774,73 @@ SiS_HandleCRT1(SiS_Private *SiS_Pr)
-   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
- 
- #if 0
--  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
--     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
-+  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
-+     if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
-+        (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
-+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
-+     }
-   }
- #endif
- }
- 
- void
-+SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-+{
-+   unsigned char cr5f, temp1, temp2;
-+
-+   /* You should use the macros, not these flags directly */
-+
-+   SiS_Pr->SiS_SysFlags = 0;
-+   if(HwDeviceExtension->jChipType == SIS_650) {
-+      cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
-+      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
-+      temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
-+      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
-+      temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
-+      if((!temp1) || (temp2)) {
-+         switch(cr5f) {
-+	    case 0x80:
-+	    case 0x90:
-+	    case 0xc0:
-+	       SiS_Pr->SiS_SysFlags |= SF_IsM650;  break;
-+	    case 0xa0:
-+	    case 0xb0:
-+	    case 0xe0:
-+	       SiS_Pr->SiS_SysFlags |= SF_Is651;   break;
-+	 }
-+      } else {
-+         switch(cr5f) {
-+	    case 0x90:
-+	       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
-+	       switch(temp1) {
-+	          case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
-+		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
-+		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
-+	       }
-+	       break;
-+	    case 0xb0:
-+	       SiS_Pr->SiS_SysFlags |= SF_Is652;  break;
-+	    default:
-+	       SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
-+	 }
-+      }
-+   }
-+}
-+
-+void
-+SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-+{
-+   if((IS_SIS651) || (IS_SISM650)) {
-+      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
-+      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
-+      SiS_SetReg1(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
-+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
-+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
-+   }
-+   /* !!! This does not support modes < 0x13 !!! */
-+}
-+
-+void
- SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                  USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
- {
-@@ -2683,6 +2854,9 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, UC
-     }
-   }
- 
-+  /* 550, 651 */
-+  SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr);
-+
-   SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
-   SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
-   SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
-@@ -2759,15 +2933,20 @@ void
- SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
- {
-    SISPtr pSiS = SISPTR(pScrn);
-+   BOOLEAN isslavemode = FALSE;
-+
-+   if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
-+       ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-+         ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
-+      isslavemode = TRUE;
-+   }
- 
--   /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
--   if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
--       ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
--         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
--           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
-+   /* We need to set pitch for CRT1 if bridge is in slave mode, too */
-+   if( (pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode) ) {
-    	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
-    }
--   if (pSiS->VBFlags & DISPTYPE_DISP2) {
-+   /* We must not set the pitch for CRT2 if bridge is in slave mode */
-+   if( (pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode) ) {
-    	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
-    }
- }
-@@ -2790,7 +2969,7 @@ SiS_SetPitchCRT2(SiS_Private *SiS_Pr, Sc
-     SISPtr pSiS = SISPTR(pScrn);
-     ULong  HDisplay,temp;
- 
--    HDisplay = pSiS->scrnPitch / 8;
-+    HDisplay = pSiS->scrnPitch2 / 8;
- 
-     /* Unlock CRT2 */
-     if (pSiS->VGAEngine == SIS_315_VGA)
-@@ -2880,7 +3059,6 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UC
-    return TRUE;
- }
- 
--/* For SiS 300 oem util: Search VBModeID */
- BOOLEAN
- SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
- {
-@@ -2946,6 +3124,81 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, UCHA
-    return index;
- }
- 
-+static void
-+SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue)
-+{
-+   USHORT temp, tempbl, tempbh;
-+
-+   tempbl = tempbh = somevalue;
-+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
-+   temp &= 0xf0;
-+   tempbl >>= 4;
-+   temp |= tempbl;
-+   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
-+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
-+   temp &= 0xf0;
-+   tempbh &= 0x0f;
-+   temp |= tempbh;
-+   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
-+}
-+
-+static void
-+SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue)
-+{
-+   USHORT temp, tempbl, tempbh;
-+
-+   tempbl = tempbh = somevalue;
-+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
-+   temp &= 0x0f;
-+   tempbl &= 0xf0;
-+   temp |= tempbl;
-+   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
-+   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
-+   temp &= 0x0f;
-+   tempbh <<= 4;
-+   temp |= tempbh;
-+   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
-+}
-+
-+static void
-+SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue)
-+{
-+   SiS_WhatIsThis1a(SiS_Pr, somevalue);
-+   SiS_WhatIsThis1b(SiS_Pr, somevalue);
-+}
-+
-+static void
-+SiS_WhatIsThis1(SiS_Private *SiS_Pr)
-+{
-+   SiS_WhatIsThis2b(SiS_Pr, 0);
-+}
-+
-+static void
-+SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue)
-+{
-+   USHORT temp = somevalue >> 8;
-+
-+   temp &= 0x07;
-+   temp |= (temp << 4);
-+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp);
-+   SiS_WhatIsThis2b(SiS_Pr, somevalue);
-+}
-+
-+static void
-+SiS_WhatIsThis2(SiS_Private *SiS_Pr)
-+{
-+   SiS_WhatIsThis2a(SiS_Pr, 0);
-+}
-+
-+void
-+SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-+{
-+   if(IS_SIS65x) {
-+      SiS_WhatIsThis1(SiS_Pr);
-+      SiS_WhatIsThis2(SiS_Pr);
-+   }
-+}
-+
- void
- SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
- {
-@@ -3027,7 +3280,7 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCH
-       (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
--        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
-+         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
-       }
-     }
-   }
-@@ -3065,7 +3318,7 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHA
-       }
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-          if(HwDeviceExtension->jChipType >= SIS_315H) {
--	    if(IS_SIS650740 || IS_SIS550) {  
-+	    if(IS_SIS550650740660) {
- 	       /* 315, 330 don't do this */
- 	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 
- 	          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
-@@ -3148,7 +3401,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
-   USHORT tempah,i,modeflag,j;
- #ifdef SIS315H
-   USHORT temp;
--  USHORT ResInfo,DisplayType;
-+  USHORT ResIndex,DisplayType;
-   const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
- #endif
- 
-@@ -3171,7 +3424,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
-      /* LCDA */
- 
-      temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
--                       RefreshRateTableIndex,&ResInfo,&DisplayType);
-+                       RefreshRateTableIndex,&ResIndex,&DisplayType);
- 
-      switch(DisplayType) {
-       case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;      break;
-@@ -3197,30 +3450,30 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
-       default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
-      }
- 
--     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
-+     tempah = (LCDACRT1Ptr+ResIndex)->CR[0];
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
-      for(i=0x01,j=1;i<=0x07;i++,j++){
--       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-      }
-      for(i=0x10,j=8;i<=0x12;i++,j++){
--       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-      }
-      for(i=0x15,j=11;i<=0x16;i++,j++){
--       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
-+       tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-      }
-      for(i=0x0A,j=13;i<=0x0C;i++,j++){
--       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
-      }
- 
--     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
-+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
-      tempah &= 0x0E0;
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
- 
--     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
-+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
-      tempah &= 0x01;
-      tempah <<= 5;
-      if(modeflag & DoubleScanMode)  tempah |= 0x080;
-@@ -3301,7 +3554,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
- 
- BOOLEAN
- SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
--		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-+		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
- 		   USHORT *DisplayType)
-  {
-   USHORT tempbx=0,modeflag=0;
-@@ -3320,7 +3573,7 @@ SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, 
-   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
-   if(modeflag & HalfDCLK)                 tempbx += 16;
- 
--  *ResInfo = CRT2CRTC & 0x3F;
-+  *ResIndex = CRT2CRTC & 0x3F;
-   *DisplayType = tempbx;
- 
-   return 1;
-@@ -3490,11 +3743,11 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
- 
-   data2 = 0;
-   if(ModeNo > 0x13) {
--    if(SiS_Pr->SiS_ModeType > 0x02) {
--       data2 |= 0x02;
--       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
--       data2 |= data3;
--    }
-+     if(SiS_Pr->SiS_ModeType > 0x02) {
-+        data2 |= 0x02;
-+        data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
-+        data2 |= data3;
-+     }
-   }
- #ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", 
-@@ -3517,7 +3770,8 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
-   if(HwDeviceExtension->jChipType != SIS_300) {
-      data = 0x0000;
-      if(infoflag & InterlaceMode) {
--        if(xres == 1024) data = 0x0035;
-+        if(xres <= 800)  data = 0x0020;
-+        else if(xres <= 1024) data = 0x0035;
-         else data = 0x0048;
-      }
-      data2 = data & 0x00FF;
-@@ -3549,6 +3803,7 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
-      } else {
-         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
-      }
-+     /* 651 BIOS does something for mode 0x12 here */
-   }
- 
-   if(HwDeviceExtension->jChipType != SIS_300) {
-@@ -3679,7 +3934,7 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UC
-     if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
- 
--  } else { 						/* 310/325 series */
-+  } else { 						/* 315 series */
- 
-     data = 0;
-     if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
-@@ -3688,12 +3943,6 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UC
-     if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
-     }
--#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
--    data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);	  	/* DAC pedestal */
--    data &= 0xE7;
--    if(VCLK<200) data |= 0x10;
--    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
--#endif
-   }
- 
-   data2 = 0x03;
-@@ -3918,7 +4167,8 @@ GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW
- 
-   } else if((HwDeviceExtension->jChipType == SIS_550) ||
-             (HwDeviceExtension->jChipType == SIS_740) ||
--            (HwDeviceExtension->jChipType == SIS_650)) {
-+            (HwDeviceExtension->jChipType == SIS_650) ||
-+	    (HwDeviceExtension->jChipType == SIS_660)) {
- 
-   	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-       	counter++;
-@@ -4728,7 +4978,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
-           SiS_Pr->SiS_SetFlag = 0x00;
-           SiS_Pr->SiS_ModeType = ModeVGA;
-           SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
--          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
-+          SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
-           for(i=0;i<20;i++) {
-             SiS_LongWait(SiS_Pr);
-           }
-@@ -4766,7 +5016,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
- #ifdef SIS315H
- 	   if(HwDeviceExtension->jChipType >= SIS_315H) {
- 	        OutputSelect = ROMAddr[0xf3];
--		if(HwDeviceExtension->jChipType == SIS_330) {
-+		if(HwDeviceExtension->jChipType >= SIS_330) {
- 		     OutputSelect = ROMAddr[0x11b];
- 		}
- 	   }
-@@ -4814,7 +5064,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
-       if(!(P2reg0 & 0x20)) {
-         SiS_Pr->SiS_VBInfo = DisableCRT2Display;
--        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
-+        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
-       }
-     }
-   }
-@@ -4884,111 +5134,6 @@ SiS_SenseCHTV(SiS_Private *SiS_Pr)
- }
- #endif /* LINUXBIOS */
- 
--/*  ================ for TC only =================  */
--
--#ifdef TC
--
--int
--INT1AReturnCode(union REGS regs)
--{
--  if (regs.x.cflag)
--  {
--    /*printf("Error to find pci device!\n"); */
--    return 1;
--  }
--
--  switch(regs.h.ah)
--  {
--    case 0: return 0;
--            break;
--    case 0x81: printf("Function not support\n");
--               break;
--    case 0x83: printf("bad vendor id\n");
--               break;
--    case 0x86: printf("device not found\n");
--               break;
--    case 0x87: printf("bad register number\n");
--               break;
--    case 0x88: printf("set failed\n");
--               break;
--    case 0x89: printf("buffer too small");
--               break;
--  }
--  return 1;
--}
--
--unsigned
--FindPCIIOBase(unsigned index,unsigned deviceid)
--{
--  union REGS regs;
--
--  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
--  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
--  regs.x.cx = deviceid;
--  regs.x.dx = 0x1039;
--  regs.x.si = index;  /* find n-th device */
--
--  int86(0x1A, &regs, &regs);
--
--  if (INT1AReturnCode(regs)!=0)
--    return 0;
--
--  /* regs.h.bh *//* bus number */
--  /* regs.h.bl *//* device number */
--  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
--  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
--  regs.x.cx = deviceid;
--  regs.x.dx = 0x1039;
--  regs.x.di = 0x18;  /* register number */
--  int86(0x1A, &regs, &regs);
--
--  if (INT1AReturnCode(regs)!=0)
--    return 0;
--  return regs.x.cx;
--}
--
--
--void
--main(int argc, char *argv[])
--{
--  SIS_HW_DEVICE_INFO  HwDeviceExtension;
--  USHORT temp;
--  USHORT ModeNo;
--
--  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
--  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
--
--#ifdef SIS300  
--  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
--  HwDeviceExtension.jChipType = SIS_630;
--#endif
--
--#ifdef SIS315H  
--//  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
--//  HwDeviceExtension.jChipType = SIS_550;
--  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
--  HwDeviceExtension.jChipType = SIS_315H;
--#endif
--
--  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
--  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
--  HwDeviceExtension.bSkipDramSizing = FALSE;
--  HwDeviceExtension.ulVideoMemorySize = 0;
--  if(argc==2) {
--    ModeNo=atoi(argv[1]);
--  }
--  else {
--    ModeNo=0x2e;
--    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
--    /*ModeNo=0x38; *//* 1024x768x 8bpp */
--    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
--    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
--  }
-- /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
--  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
--}
--#endif /* TC END */
--
- /* ================ XFREE86 ================= */
- 
- /* Helper functions */
-@@ -5000,44 +5145,78 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
-    SISPtr pSiS = SISPTR(pScrn);
-    int    out_n, out_dn, out_div, out_sbit, out_scale;
-    int    depth = pSiS->CurrentLayout.bitsPerPixel;
--   
--#ifdef SISDUALHEAD
--   if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
--       ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
--#else      
--   if(VBFlags & DISPTYPE_DISP2) return 0; 
--#endif   
-+   unsigned int vclk[5];
-+
-+#define Midx         0
-+#define Nidx         1
-+#define VLDidx       2
-+#define Pidx         3
-+#define PSNidx       4
-+
-+   pSiS->SiS_Pr->CModeFlag = 0;
-    
-    pSiS->SiS_Pr->CDClock = mode->Clock;
--   
-+
-    pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
-    pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
-    pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
-    pSiS->SiS_Pr->CHTotal = mode->HTotal;
--   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
--   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
--   
-+
-    pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
-    pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
-    pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
-    pSiS->SiS_Pr->CVTotal = mode->VTotal;
-+
-+   pSiS->SiS_Pr->CFlags = mode->Flags;
-+
-+   if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
-+         pSiS->SiS_Pr->CVDisplay >>= 1;
-+	 pSiS->SiS_Pr->CVSyncStart >>= 1;
-+	 pSiS->SiS_Pr->CVSyncEnd >>= 1;
-+	 pSiS->SiS_Pr->CVTotal >>= 1;
-+   }
-+   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
-+         /* pSiS->SiS_Pr->CDClock <<= 1; */
-+	 pSiS->SiS_Pr->CVDisplay <<= 1;
-+	 pSiS->SiS_Pr->CVSyncStart <<= 1;
-+	 pSiS->SiS_Pr->CVSyncEnd <<= 1;
-+	 pSiS->SiS_Pr->CVTotal <<= 1;
-+   }
-+
-+   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
-+   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
-    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
-    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
--   
--   pSiS->SiS_Pr->CFlags = mode->Flags;
- 
--   SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
--   
-+   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
-+      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
-+      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
-+      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
-+      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
-+      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
-+#ifdef TWDEBUG
-+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
-+        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-+#endif
-+   } else {
-+      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
-+      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
-+      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
-+      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
-+      if(vclk[Pidx] <= 4) {
-+         /* postscale 1,2,3,4 */
-+         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
-+      } else {
-+         /* postscale 6,8 */
-+         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
-+	 pSiS->SiS_Pr->CSR2C |= 0x80;
-+      }
- #ifdef TWDEBUG
--   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
--      	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
--#endif	
--
--   pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
--   pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
--   pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
--   pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
--   pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
-+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
-+        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
-+#endif
-+   }
-+
-    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
- 
-    pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
-@@ -5045,9 +5224,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
-    pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
-    pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
-    pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
--   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | 
-+   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
-        				  (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
--   
-+
-    pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
-    pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
-  	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
-@@ -5057,50 +5236,50 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
- 	 			| (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
- 	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
- 	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
--    
-+
-    pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* cr9 */
--    
--#if 0    
-+
-+#if 0
-    if (mode->VScan >= 32)
- 	regp->CRTC[9] |= 0x1F;
-    else if (mode->VScan > 1)
- 	regp->CRTC[9] |= mode->VScan - 1;
--#endif	
-+#endif
- 
--   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF;	/* cr10 */
--   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80;	/* cr11 */
--   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF;		/* cr12 */
--   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;	/* cr15 */
--   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF;		/* cr16 */
--   
--   pSiS->SiS_Pr->CCRT1CRTC[13] = 
-+   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart     ) & 0xFF;		/* cr10 */
-+   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;	/* cr11 */
-+   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay    - 1) & 0xFF;		/* cr12 */
-+   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;		/* cr15 */
-+   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd   - 1) & 0xFF;		/* cr16 */
-+
-+   pSiS->SiS_Pr->CCRT1CRTC[13] =
-                         GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
-                         GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
-                         GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
-                         GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
-                         GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
--                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd   -1),   4:4, 5:5) ;  
-+                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
- 
--   pSiS->SiS_Pr->CCRT1CRTC[14] = 
-+   pSiS->SiS_Pr->CCRT1CRTC[14] =
-                         GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
-                         GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
-                         GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
-                         GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
- 
--        
-+
-    pSiS->SiS_Pr->CCRT1CRTC[15] =
-                         GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
--                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ; 
--			
-+                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
-+
-    switch(depth) {
--   case 8: 			
--      	pSiS->SiS_Pr->CModeFlag = 0x223b;
-+   case 8:
-+      	pSiS->SiS_Pr->CModeFlag |= 0x223b;
- 	break;
--   case 16: 			
--      	pSiS->SiS_Pr->CModeFlag = 0x227d;
-+   case 16:
-+      	pSiS->SiS_Pr->CModeFlag |= 0x227d;
- 	break;
--   case 32: 			
--      	pSiS->SiS_Pr->CModeFlag = 0x22ff;
-+   case 32:
-+      	pSiS->SiS_Pr->CModeFlag |= 0x22ff;
- 	break;		
-    default: 
-    	return 0;	
-@@ -5114,9 +5293,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
- 	pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
-    if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
-         pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
--   
-+
-    pSiS->SiS_Pr->CInfoFlag = 0x0007;
--   if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 
-+   if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
-    	pSiS->SiS_Pr->CInfoFlag |= 0x4000;
-    if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 
-    	pSiS->SiS_Pr->CInfoFlag |= 0x8000;
-@@ -5152,13 +5331,13 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
-    	pSiS->SiS_Pr->CSR2B,
- 	pSiS->SiS_Pr->CSR2C,
- 	pSiS->SiS_Pr->CSRClock);
--#endif   	
-+#endif
-    return 1;
- }
- 
- /* TW: Build a list of supported modes */
- DisplayModePtr
--SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
-+SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
- {
-    SISPtr         pSiS = SISPTR(pScrn);
-    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
-@@ -5166,11 +5345,16 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
-    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
-    unsigned char  sr2b, sr2c;
-    float          num, denum, postscalar, divider;
--   int            A, B, C, D, E, F, temp, i, j, index, vclkindex;
--   DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
-+   int            A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
-+   DisplayModePtr new = NULL, current = NULL, first = NULL;
-+   BOOLEAN        done = FALSE;
-+#if 0
-+   DisplayModePtr backup = NULL;
-+#endif
- 
-    pSiS->backupmodelist = NULL;
--   
-+   pSiS->AddedPlasmaModes = FALSE;
-+
-    /* Initialize our pointers */
-    if(pSiS->VGAEngine == SIS_300_VGA) {
- #ifdef SIS300
-@@ -5194,15 +5378,20 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
-       if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
- #endif      
- 
--      if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
--      	 ((pSiS->DSTN) &&
--	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
--	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
--	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480)))  {
-+      /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
-+      if((!pSiS->FSTN) &&
-+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a))  {
-            i++;
-       	   continue;
-       }
--      
-+      if((pSiS->FSTN) &&
-+         (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
-+	 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
-+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
-+	   i++;
-+	   continue;
-+      }
-+
-       if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-       memset(new, 0, sizeof(DisplayModeRec));
-       if(!(new->name = xalloc(10))) {
-@@ -5216,13 +5405,13 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
-       }
- 
-       current = new;
--      
-+
-       sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
-                                       pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
- 
-       current->status = MODE_OK;
- 
--      current->type = M_T_DEFAULT; 
-+      current->type = M_T_DEFAULT;
- 
-       vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
-       if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
-@@ -5235,7 +5424,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
-               ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
-       num = (sr2b & 0x7f) + 1.0;
-       denum = (sr2c & 0x1f) + 1.0;
--      
-+
- #ifdef TWDEBUG
-       xf86DrvMsg(0, X_INFO, "------------\n");
-       xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
-@@ -5303,10 +5492,29 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
- 
-       D = B - F - C;
- 
--      current->HDisplay   = (E * 8);
--      current->HSyncStart = (E * 8) + (F * 8);
--      current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
--      current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-+      if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
-+	 ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
-+	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
-+
-+	 /* Terrible hack, but correct CRTC data for
-+	  * these modes only produces a black screen...
-+	  * (HRE is 0, leading into a too large C and
-+	  * a negative D. The CRT controller does not
-+	  * seem to like correcting HRE to 50
-+	  */
-+	 current->HDisplay   = 320;
-+         current->HSyncStart = 328;
-+         current->HSyncEnd   = 376;
-+         current->HTotal     = 400;
-+
-+      } else {
-+
-+         current->HDisplay   = (E * 8);
-+         current->HSyncStart = (E * 8) + (F * 8);
-+         current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
-+         current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-+
-+      }
- 
- #ifdef TWDEBUG
-       xf86DrvMsg(0, X_INFO,
-@@ -5430,7 +5638,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
- 	 current->VSyncStart <<= 1;
- 	 current->VSyncEnd <<= 1;
- 	 current->VTotal <<= 1;
--	 current->VTotal |= 1; 
-+	 current->VTotal |= 1;
-       }
-       if(current->Flags & V_DBLSCAN) {
-          current->Clock >>= 1;
-@@ -5440,6 +5648,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
- 	 current->VTotal >>= 1;
-       }
- 
-+#if 0
-       if((backup = xalloc(sizeof(DisplayModeRec)))) {
-          if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
- 	 else {
-@@ -5458,6 +5667,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
- 	 backup->Flags = current->Flags;
- 	 backup->Clock = current->Clock;
-       }
-+#endif
- 
- #ifdef TWDEBUG
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-@@ -5470,6 +5680,187 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
-       i++;
-    }
- 
-+   /* Add non-standard LCD modes for panel's detailed timings */
-+
-+   if(!includelcdmodes) return first;
-+
-+   xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
-+      pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
-+
-+   i = 0;
-+   while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
-+
-+     if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
-+
-+        for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
-+
-+	    if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
-+
-+	       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
-+	       	  "Identified %s panel, adding specific modes\n",
-+		  SiS_PlasmaTable[i].plasmaname);
-+
-+	       for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
-+
-+	          if(isfordvi) {
-+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
-+		  } else {
-+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
-+		  }
-+
-+	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-+
-+                  memset(new, 0, sizeof(DisplayModeRec));
-+                  if(!(new->name = xalloc(10))) {
-+      		     xfree(new);
-+		     return first;
-+                  }
-+                  if(!first) first = new;
-+                  if(current) {
-+                     current->next = new;
-+	             new->prev = current;
-+                  }
-+
-+                  current = new;
-+
-+		  pSiS->AddedPlasmaModes = TRUE;
-+
-+		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
-+
-+	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
-+                                                  SiS_PlasmaMode[l].VDisplay);
-+
-+                  current->status = MODE_OK;
-+
-+                  current->type = M_T_BUILTIN;
-+
-+		  current->Clock = SiS_PlasmaMode[l].clock;
-+            	  current->SynthClock = current->Clock;
-+
-+                  current->HDisplay   = SiS_PlasmaMode[l].HDisplay;
-+                  current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
-+                  current->HSyncEnd   = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
-+                  current->HTotal     = SiS_PlasmaMode[l].HTotal;
-+
-+		  current->VDisplay   = SiS_PlasmaMode[l].VDisplay;
-+                  current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
-+                  current->VSyncEnd   = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
-+                  current->VTotal     = SiS_PlasmaMode[l].VTotal;
-+
-+                  current->CrtcHDisplay = current->HDisplay;
-+                  current->CrtcHBlankStart = current->HSyncStart;
-+                  current->CrtcHSyncStart = current->HSyncStart;
-+                  current->CrtcHSyncEnd = current->HSyncEnd;
-+                  current->CrtcHBlankEnd = current->HSyncEnd;
-+                  current->CrtcHTotal = current->HTotal;
-+
-+                  current->CrtcVDisplay = current->VDisplay;
-+                  current->CrtcVBlankStart = current->VSyncStart;
-+                  current->CrtcVSyncStart = current->VSyncStart;
-+                  current->CrtcVSyncEnd = current->VSyncEnd;
-+                  current->CrtcVBlankEnd = current->VSyncEnd;
-+                  current->CrtcVTotal = current->VTotal;
-+
-+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
-+                     current->Flags |= V_PHSYNC;
-+                  else
-+                     current->Flags |= V_NHSYNC;
-+
-+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
-+                     current->Flags |= V_PVSYNC;
-+                  else
-+                     current->Flags |= V_NVSYNC;
-+
-+		  if(current->HDisplay > pSiS->LCDwidth)
-+		     pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
-+	          if(current->VDisplay > pSiS->LCDheight)
-+		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
-+
-+               }
-+	       done = TRUE;
-+	       break;
-+	    }
-+	}
-+     }
-+
-+     i++;
-+
-+   }
-+
-+   if(pSiS->SiS_Pr->CP_HaveCustomData) {
-+
-+      for(i=0; i<7; i++) {
-+
-+         if(pSiS->SiS_Pr->CP_DataValid[i]) {
-+
-+            if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-+
-+            memset(new, 0, sizeof(DisplayModeRec));
-+            if(!(new->name = xalloc(10))) {
-+      		xfree(new);
-+		return first;
-+            }
-+            if(!first) first = new;
-+            if(current) {
-+               current->next = new;
-+	       new->prev = current;
-+            }
-+
-+            current = new;
-+
-+            sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
-+                                            pSiS->SiS_Pr->CP_VDisplay[i]);
-+
-+            current->status = MODE_OK;
-+
-+            current->type = M_T_BUILTIN;
-+
-+            current->Clock = pSiS->SiS_Pr->CP_Clock[i];
-+            current->SynthClock = current->Clock;
-+
-+            current->HDisplay   = pSiS->SiS_Pr->CP_HDisplay[i];
-+            current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
-+            current->HSyncEnd   = pSiS->SiS_Pr->CP_HSyncEnd[i];
-+            current->HTotal     = pSiS->SiS_Pr->CP_HTotal[i];
-+
-+            current->VDisplay   = pSiS->SiS_Pr->CP_VDisplay[i];
-+            current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
-+            current->VSyncEnd   = pSiS->SiS_Pr->CP_VSyncEnd[i];
-+            current->VTotal     = pSiS->SiS_Pr->CP_VTotal[i];
-+
-+            current->CrtcHDisplay = current->HDisplay;
-+            current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
-+            current->CrtcHSyncStart = current->HSyncStart;
-+            current->CrtcHSyncEnd = current->HSyncEnd;
-+            current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
-+            current->CrtcHTotal = current->HTotal;
-+
-+            current->CrtcVDisplay = current->VDisplay;
-+            current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
-+            current->CrtcVSyncStart = current->VSyncStart;
-+            current->CrtcVSyncEnd = current->VSyncEnd;
-+            current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
-+            current->CrtcVTotal = current->VTotal;
-+
-+	    if(pSiS->SiS_Pr->CP_SyncValid[i]) {
-+               if(pSiS->SiS_Pr->CP_HSync_P[i])
-+                  current->Flags |= V_PHSYNC;
-+               else
-+                  current->Flags |= V_NHSYNC;
-+
-+               if(pSiS->SiS_Pr->CP_VSync_P[i])
-+                  current->Flags |= V_PVSYNC;
-+               else
-+                  current->Flags |= V_NVSYNC;
-+	    } else {
-+	       /* No sync data? Use positive sync... */
-+	       current->Flags |= V_PHSYNC;
-+	       current->Flags |= V_PVSYNC;
-+	    }
-+         }
-+      }
-+   }
-+
-    return first;
- 
- }
-@@ -5486,25 +5877,25 @@ sisfb_mode_rate_to_dclock(SiS_Private *S
-     UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-     ULONG  temp = 0;
-     int    Clock;
--    
-+
-     if(HwDeviceExtension->jChipType < SIS_315H) {
- #ifdef SIS300
-        InitTo300Pointer(SiS_Pr, HwDeviceExtension);
- #else
--       return 65;
-+       return 65 * 1000 * 1000;
- #endif
-     } else {
- #ifdef SIS315H
-        InitTo310Pointer(SiS_Pr, HwDeviceExtension);
- #else
--       return 65;
-+       return 65 * 1000 * 1000;
- #endif
-     }
--    
-+
-     temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
-     if(!temp) {
-     	printk(KERN_ERR "Could not find mode %x\n", ModeNo);
--    	return 65;
-+    	return 65 * 1000 * 1000;
-     }
-     
-     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-@@ -5518,6 +5909,56 @@ sisfb_mode_rate_to_dclock(SiS_Private *S
-     return(Clock);
- }
- 
-+BOOLEAN
-+sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
-+{
-+    USHORT ModeNo = modeno;
-+    USHORT ModeIdIndex = 0, CRT1Index = 0;
-+    USHORT RefreshRateTableIndex = 0;
-+    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-+    ULONG  temp = 0;
-+    unsigned char  sr_data, cr_data, cr_data2;
-+
-+    if(HwDeviceExtension->jChipType < SIS_315H) {
-+#ifdef SIS300
-+       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
-+#else
-+       return FALSE;
-+#endif
-+    } else {
-+#ifdef SIS315H
-+       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
-+#else
-+       return FALSE;
-+#endif
-+    }
-+
-+    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
-+    if(!temp) return FALSE;
-+
-+    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-+    RefreshRateTableIndex += (rateindex - 1);
-+    CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-+
-+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
-+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
-+    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
-+
-+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
-+    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-+    *vtotal = ((cr_data & 0xFF) |
-+               ((unsigned short)(cr_data2 & 0x01) <<  8) |
-+	       ((unsigned short)(cr_data2 & 0x20) <<  4) |
-+	       ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
-+
-+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
-+       *vtotal *= 2;
-+
-+    return TRUE;
-+}
-+
- int
- sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- 			 unsigned char modeno, unsigned char rateindex,
-@@ -5606,17 +6047,32 @@ sisfb_mode_rate_to_ddata(SiS_Private *Si
-     C = (temp > 0) ? temp : (temp + 64);
- 
-     D = B - F - C;
--    
--    *left_margin = D * 8;
--    *right_margin = F * 8;
--    *hsync_len = C * 8;
-+
-+    if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
-+       ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
-+	(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
-+
-+	 /* Terrible hack, but the correct CRTC data for
-+	  * these modes only produces a black screen...
-+	  */
-+       *left_margin = (400 - 376);
-+       *right_margin = (328 - 320);
-+       *hsync_len = (376 - 328);
-+
-+    } else {
-+
-+       *left_margin = D * 8;
-+       *right_margin = F * 8;
-+       *hsync_len = C * 8;
-+
-+    }
- 
-     sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
- 
-     cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
--    
-+
-     cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
--    
-+
-     /* Vertical total */
-     VT = (cr_data & 0xFF) |
-          ((unsigned short) (cr_data2 & 0x01) << 8) |
-@@ -5699,19 +6155,19 @@ sisfb_mode_rate_to_ddata(SiS_Private *Si
- 	  j++;
-       }
-     }       
--       
--#if 0  /* That's bullshit, only the resolution needs to be shifted */    
-+
-     if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-+#if 0  /* Do this? */
-        *upper_margin <<= 1;
-        *lower_margin <<= 1;
-        *vsync_len <<= 1;
-+#endif
-     } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-        *upper_margin >>= 1;
-        *lower_margin >>= 1;
-        *vsync_len >>= 1;
--    }  
--#endif
--          
-+    }
-+
-     return 1;       
- }			  
- 
---- linux-2.6.0-test1/drivers/video/sis/initdef.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/drivers/video/sis/initdef.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,5 +1,29 @@
- /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
--
-+/*
-+ * Global definitions for init.c and init301.c
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ */
- 
- #ifndef _INITDEF_
- #define _INITDEF_
-@@ -22,12 +46,18 @@
- #define VB_SIS301B302B          (VB_SIS301B|VB_SIS302B)
- #define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
- 
--#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
--
- #define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
- #define IS_SIS740		(HwDeviceExtension->jChipType == SIS_740)
- #define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
- #define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
-+#define IS_SIS651	        (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
-+#define IS_SISM650	        (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
-+#define IS_SIS65x               (IS_SIS651 || IS_SISM650)
-+#define IS_SIS660		(HwDeviceExtension->jChipType == SIS_660)
-+#define IS_SIS650660            (IS_SIS650 || IS_SIS660)
-+#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
-+#define IS_SIS650740660         (IS_SIS650 || IS_SIS660 || IS_SIS740)
-+#define IS_SIS550650740660      (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740)
- 
- #define CRT1Len                 17
- #define LVDSCRT1Len             15
-@@ -63,7 +93,7 @@
- #define SupportTV               0x0008
- #define SupportHiVisionTV       0x0010
- #define SupportLCD              0x0020
--#define SupportRAMDAC2          0x0040  
-+#define SupportRAMDAC2          0x0040
- #define NoSupportTV             0x0070
- #define NoSupportHiVisionTV     0x0060
- #define NoSupportLCD            0x0058
-@@ -105,6 +135,24 @@
- #define HotKeySwitch            0x8000  /* TW: ? */
- #define SetCRT2ToLCDA           0x8000
- 
-+/* SetFlag */
-+#define ProgrammingCRT2         0x01
-+#define TVSimuMode              0x02
-+#define RPLLDIV2XO              0x04
-+#define LCDVESATiming           0x08
-+#define EnableLVDSDDA           0x10
-+#define SetDispDevSwitchFlag    0x20
-+#define CheckWinDos             0x40
-+#define SetDOSMode              0x80
-+
-+/* SysFlags */
-+#define SF_Is651                0x0001
-+#define SF_IsM650               0x0002
-+#define SF_Is652		0x0004
-+#define SF_IsM652		0x0008
-+#define SF_IsM653		0x0010
-+#define SF_Is660		0x8000
-+
- #define PanelRGB18Bit           0x0100
- #define PanelRGB24Bit           0x0000
- 
-@@ -112,7 +160,7 @@
- #define TVOverScanShift         4
- #define ClearBufferFlag         0x20
- 
--/* CR32 (Newer 630, and 310/325 series)
-+/* CR32 (Newer 630, and 315 series)
- 
-    [0]   VB connected with CVBS
-    [1]   VB connected with SVHS
-@@ -134,7 +182,7 @@
- 	    011   LVDS + Tumpion Zurac
- 	    100   LVDS + Chrontel 7005
- 	    110   Chrontel 7005
--	  310/325 series
-+	  315 series
- 	    001   SiS30x (never seen)
- 	    010   LVDS
- 	    011   LVDS + Chrontel 7019
-@@ -163,14 +211,15 @@
- #define LCDSyncBit            0x00e0
- #define LCDSyncShift               6
- 
--/* CR38 (310/325 series) */
-+/* CR38 (315 series) */
- #define EnableDualEdge 		0x01   
- #define SetToLCDA		0x02   /* LCD channel A (302B/LV and 650+LVDS only) */
- #define EnableSiSHiVision       0x04   /* HiVision (HDTV) on SiS bridge */
- #define EnableLVDSScart         0x04   /* Scart on Ch7019 (unofficial definition - TW) */
- #define EnableLVDSHiVision      0x08   /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
--#define SiSHiVision1            0x10   /* See SetHiVision() */
--#define SiSHiVision2            0x20
-+#define EnableHiVision750       0x08   /* Enable 750P HiVision mode (30xLV only) */
-+#define EnableHiVision525       0x10   /* Enable 525P HiVision mode (30xLV only) */
-+#define SiSHiVision2            0x20   /* ? - |  --- mask 0x38 combinations have different meaning! */
- #define EnablePALM              0x40   /* 1 = Set PALM */
- #define EnablePALN              0x80   /* 1 = Set PALN */
- 
-@@ -184,7 +233,7 @@
- #define Enable302LV_DualLink    0x04   /* 30xNEW (302LV) only; set by mode switching function */
- 
- 
--/* CR79 (310/325 series only)
-+/* CR79 (315 series only)
-    [3-0] Notify driver
-          0001 Mode Switch event (set by BIOS)
- 	 0010 Epansion On/Off event
-@@ -202,16 +251,6 @@
-    [7]   TV UnderScan/OverScan (set by BIOS)
- */
- 
--/* SetFlag */
--#define ProgrammingCRT2         0x01
--#define TVSimuMode              0x02
--#define RPLLDIV2XO              0x04
--#define LCDVESATiming           0x08
--#define EnableLVDSDDA           0x10
--#define SetDispDevSwitchFlag    0x20
--#define CheckWinDos             0x40
--#define SetDOSMode              0x80
--
- /* LCDResInfo */
- #define Panel300_800x600        0x01	/* CR36 */
- #define Panel300_1024x768       0x02
-@@ -220,7 +259,10 @@
- #define Panel300_640x480        0x05
- #define Panel300_1024x600       0x06
- #define Panel300_1152x768       0x07
--#define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
-+#define Panel300_1280x768       0x0a
-+#define Panel300_320x480        0x0e 	/* fstn - TW: This is fake, can be any */
-+#define Panel300_Custom		0x0f
-+#define Panel300_Barco1366      0x10
- 
- #define Panel310_800x600        0x01
- #define Panel310_1024x768       0x02
-@@ -231,9 +273,12 @@
- #define Panel310_1280x960       0x07
- #define Panel310_1152x768       0x08	/* LVDS only */
- #define Panel310_1400x1050      0x09
--#define Panel310_1280x768       0x0a    /* LVDS only */
-+#define Panel310_1280x768       0x0a
- #define Panel310_1600x1200      0x0b
--#define Panel310_320x480        0x0c    /* fstn - TW: This is fake, can be any */
-+#define Panel310_640x480_2      0x0c
-+#define Panel310_640x480_3      0x0d
-+#define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
-+#define Panel310_Custom		0x0f
- 
- #define Panel_800x600           0x01	/* Unified values */
- #define Panel_1024x768          0x02
-@@ -246,7 +291,42 @@
- #define Panel_1400x1050         0x09
- #define Panel_1280x768          0x0a    /* LVDS only */
- #define Panel_1600x1200         0x0b
--#define Panel_320x480           0x0c    /* fstn - TW: This is fake, can be any */
-+#define Panel_640x480_2		0x0c
-+#define Panel_640x480_3		0x0d
-+#define Panel_320x480           0x0e    /* fstn - TW: This is fake, can be any */
-+#define Panel_Custom		0x0f
-+#define Panel_Barco1366         0x10
-+
-+/* Index in ModeResInfo table */
-+#define SIS_RI_320x200 0
-+#define SIS_RI_320x240 1
-+#define SIS_RI_320x400 2
-+#define SIS_RI_400x300 3
-+#define SIS_RI_512x384 4
-+#define SIS_RI_640x400 5
-+#define SIS_RI_640x480 6
-+#define SIS_RI_800x600 7
-+#define SIS_RI_1024x768 8
-+#define SIS_RI_1280x1024 9
-+#define SIS_RI_1600x1200 10
-+#define SIS_RI_1920x1440 11
-+#define SIS_RI_2048x1536 12
-+#define SIS_RI_720x480 13
-+#define SIS_RI_720x576 14
-+#define SIS_RI_1280x960 15
-+#define SIS_RI_800x480 16
-+#define SIS_RI_1024x576 17
-+#define SIS_RI_1280x720 18
-+#define SIS_RI_856x480 19
-+#define SIS_RI_1280x768 20
-+#define SIS_RI_1400x1050 21
-+#define SIS_RI_1152x864 22
-+#define SIS_RI_848x480 23
-+#define SIS_RI_1360x768 24
-+#define SIS_RI_1024x600 25
-+#define SIS_RI_1152x768 26
-+#define SIS_RI_768x576 27
-+#define SIS_RI_1360x1024 28
- 
- #define ExtChipType             0x0e
- #define ExtChip301              0x02
-@@ -278,15 +358,32 @@
- #define VCLKStartFreq           25
- #define SoftDramType            0x80
- 
--#define VCLK40                  0x04   /* Index in VCLKData array */
--#define VCLK65                  0x09   /* Index in VCLKData array */
--#define VCLK108_2               0x14   /* Index in VCLKData array */
--#define TVVCLKDIV2              0x21   /* Indices in (VB)VCLKData arrays */
--#define TVVCLK                  0x22
--#define HiTVVCLKDIV2            0x23
--#define HiTVVCLK                0x24
--#define HiTVSimuVCLK            0x25
--#define HiTVTextVCLK            0x26
-+/* Indices in (VB)VCLKData tables */
-+
-+#define VCLK28                  0x00   /* Index in VCLKData table (300 and 315) */
-+#define VCLK40                  0x04   /* Index in VCLKData table (300 and 315) */
-+#define VCLK65_300              0x09   /* Index in VCLKData table (300) */
-+#define VCLK108_2_300           0x14   /* Index in VCLKData table (300) */
-+#define VCLK81_300		0x3f   /* Index in VCLKData table (300) */
-+#define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
-+#define VCLK100_300             0x43   /* Index in VCLKData table (300) */
-+#define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
-+#define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
-+#define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
-+#define VCLK162_315             0x21   /* Index in (VB)VCLKData table (315) */
-+#define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
-+#define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
-+
-+#define TVCLKBASE_300		0x21   /* Indices on TV clocks in VCLKData table (300) */
-+#define TVCLKBASE_315	        0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
-+#define TVVCLKDIV2              0x00   /* Index relative to TVCLKBASE */
-+#define TVVCLK                  0x01   /* Index relative to TVCLKBASE */
-+#define HiTVVCLKDIV2            0x02   /* Index relative to TVCLKBASE */
-+#define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
-+#define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
-+#define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
-+
-+/* ------------------------------ */
- 
- #define LoadDACFlag             0x1000
- #define AfterLockCRT2           0x4000
-@@ -306,6 +403,8 @@
- #define HotPlugFunction         0x08
- #define StStructSize            0x06
- 
-+#define SIS_VIDEO_CAPTURE       0x00 - 0x30
-+#define SIS_VIDEO_PLAYBACK      0x02 - 0x30
- #define SIS_CRT2_PORT_04        0x04 - 0x30
- #define SIS_CRT2_PORT_10        0x10 - 0x30
- #define SIS_CRT2_PORT_12        0x12 - 0x30
-@@ -393,7 +492,7 @@
- 
- /*
-   =============================================================
--   			for 310/325 series
-+   			  for 315 series
-   =============================================================
- */
- #define SoftDRAMType        0x80
---- linux-2.6.0-test1/drivers/video/sis/init.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/video/sis/init.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,19 +1,39 @@
-+/* $XFree86$ */
-+/*
-+ * Data and prototypes for init.c
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ */
-+
- #ifndef _INIT_
- #define _INIT_
- 
- #include "osdef.h"
-+
- #include "initdef.h"
- #include "vgatypes.h"
- #include "vstruct.h"
- 
--#ifdef TC
--#include <stdio.h>
--#include <string.h>
--#include <conio.h>
--#include <dos.h>
--#include <stdlib.h>
--#endif
--
- #ifdef LINUX_XF86
- #include "xf86.h"
- #include "xf86Pci.h"
-@@ -24,6 +44,9 @@
- #endif
- 
- #ifdef LINUX_KERNEL
-+#ifdef SIS_CP
-+#undef SIS_CP
-+#endif
- #include <linux/config.h>
- #include <linux/version.h>
- #include <linux/types.h>
-@@ -36,19 +59,6 @@
- #endif
- #endif
- 
--#ifdef WIN2000
--#include <stdio.h>
--#include <string.h>
--#include <miniport.h>
--#include "dderror.h"
--#include "devioctl.h"
--#include "miniport.h"
--#include "ntddvdeo.h"
--#include "video.h"
--#include "sisv.h"
--#include "tools.h"
--#endif
--
- const USHORT SiS_DRAMType[17][5]={
- 	{0x0C,0x0A,0x02,0x40,0x39},
- 	{0x0D,0x0A,0x01,0x40,0x48},
-@@ -144,6 +154,2175 @@ const USHORT SiS_VGA_DAC[] =
- 	0x0B,0x0C,0x0D,0x0F,0x10
- };
- 
-+static const SiS_StResInfoStruct SiS_StResInfo[]=
-+{
-+	{ 640,400},
-+	{ 640,350},
-+	{ 720,400},
-+	{ 720,350},
-+	{ 640,480}
-+};
-+
-+static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
-+{
-+	{  320, 200, 8, 8},   /* 0x00 */
-+	{  320, 240, 8, 8},   /* 0x01 */
-+	{  320, 400, 8, 8},   /* 0x02 */
-+	{  400, 300, 8, 8},   /* 0x03 */
-+	{  512, 384, 8, 8},   /* 0x04 */
-+	{  640, 400, 8,16},   /* 0x05 */
-+	{  640, 480, 8,16},   /* 0x06 */
-+	{  800, 600, 8,16},   /* 0x07 */
-+	{ 1024, 768, 8,16},   /* 0x08 */
-+	{ 1280,1024, 8,16},   /* 0x09 */
-+	{ 1600,1200, 8,16},   /* 0x0a */
-+	{ 1920,1440, 8,16},   /* 0x0b */
-+	{ 2048,1536, 8,16},   /* 0x0c */
-+	{  720, 480, 8,16},   /* 0x0d */
-+	{  720, 576, 8,16},   /* 0x0e */
-+	{ 1280, 960, 8,16},   /* 0x0f */
-+	{  800, 480, 8,16},   /* 0x10 */
-+	{ 1024, 576, 8,16},   /* 0x11 */
-+	{ 1280, 720, 8,16},   /* 0x12 */
-+	{  856, 480, 8,16},   /* 0x13 */
-+	{ 1280, 768, 8,16},   /* 0x14 */
-+	{ 1400,1050, 8,16},   /* 0x15 */
-+	{ 1152, 864, 8,16},   /* 0x16 */
-+	{  848, 480, 8,16},   /* 0x17 */
-+	{ 1360, 768, 8,16},   /* 0x18 */
-+	{ 1024, 600, 8,16},   /* 0x19 */
-+	{ 1152, 768, 8,16},   /* 0x1a */
-+	{  768, 576, 8,16},   /* 0x1b */
-+	{ 1360,1024, 8,16}    /* 0x1c */
-+};
-+
-+static SiS_StandTableStruct SiS_StandTable[]=
-+{
-+/* 0x00: MD_0_200 */
-+ {
-+  0x28,0x18,0x08,0x0800,
-+  {0x09,0x03,0x00,0x02},
-+  0x63,
-+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x01: MD_1_200 */
-+ {
-+  0x28,0x18,0x08,0x0800,
-+  {0x09,0x03,0x00,0x02},
-+  0x63,
-+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x02: MD_2_200 */
-+ {
-+  0x50,0x18,0x08,0x1000,
-+  {0x01,0x03,0x00,0x02},
-+  0x63,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x03: MD_3_200 - mode 0x03 - 0 */
-+ {
-+  0x50,0x18,0x08,0x1000,
-+  {0x01,0x03,0x00,0x02},
-+  0x63,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x04: MD_4 */
-+ {
-+  0x28,0x18,0x08,0x4000,
-+  {0x09,0x03,0x00,0x02},
-+  0x63,
-+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
-+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-+   0xff},
-+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x01,0x00,0x03,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-+   0xff}
-+ },
-+/* 0x05: MD_5 */
-+ {
-+  0x28,0x18,0x08,0x4000,
-+  {0x09,0x03,0x00,0x02},
-+  0x63,
-+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
-+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-+   0xff},
-+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x01,0x00,0x03,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-+   0xff}
-+ },
-+/* 0x06: MD_6 */
-+ {
-+  0x50,0x18,0x08,0x4000,
-+  {0x01,0x01,0x00,0x06},
-+  0x63,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,   /* 55,81 is 54,80 for 300 */
-+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-+   0xff},
-+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-+   0x01,0x00,0x01,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-+   0xff}
-+ },
-+/* 0x07: MD_7 */
-+ {
-+  0x50,0x18,0x0e,0x1000,
-+  {0x00,0x03,0x00,0x03},
-+  0xa6,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-+   0xff},
-+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-+   0x0e,0x00,0x0f,0x08},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-+   0xff}
-+ },
-+/* 0x08: MDA_DAC */
-+ {
-+  0x00,0x00,0x00,0x0000,
-+  {0x00,0x00,0x00,0x15},
-+  0x15,
-+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-+   0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-+   0x15,0x15,0x15,0x15},
-+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-+   0x3f}
-+ },
-+/* 0x09: CGA_DAC */
-+ {
-+  0x00,0x10,0x04,0x0114,
-+  {0x11,0x09,0x15,0x00},
-+  0x10,
-+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-+   0x04},
-+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-+   0x3e,0x2b,0x3b,0x2f},
-+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-+   0x3f}
-+ },
-+/* 0x0a: EGA_DAC */
-+ {
-+  0x00,0x10,0x04,0x0114,
-+  {0x11,0x05,0x15,0x20},
-+  0x30,
-+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-+   0x06},
-+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-+   0x1e,0x0b,0x1b,0x0f},
-+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-+   0x3f}
-+ },
-+/* 0x0b: VGA_DAC */
-+ {
-+  0x00,0x10,0x04,0x0114,
-+  {0x11,0x09,0x15,0x2a},
-+  0x3a,
-+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-+   0x1f},
-+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-+   0x1c,0x0e,0x11,0x15},
-+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-+   0x04}
-+ },
-+/* 0x0c */
-+ {
-+  0x08,0x0c,0x10,0x0a08,
-+  {0x0c,0x0e,0x10,0x0b},
-+  0x0c,
-+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-+   0x06},
-+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-+   0x00,0x00,0x00,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x00}
-+ },
-+/* 0x0d: MD_D */
-+ {
-+  0x28,0x18,0x08,0x2000,
-+  {0x09,0x0f,0x00,0x06},
-+  0x63,
-+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,     /* 2c is 2b for 300 */
-+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x01,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-+   0xff}
-+ },
-+/* 0x0e: MD_E */
-+ {
-+  0x50,0x18,0x08,0x4000,
-+  {0x01,0x0f,0x00,0x06},
-+  0x63,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,     /* 55,81 is 54,80 for 300 */
-+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-+   0x01,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-+   0xff}
-+ },
-+/* 0x0f: ExtVGATable - modes > 0x13 */
-+ {
-+  0x00,0x00,0x00,0x0000,
-+  {0x01,0x0f,0x00,0x0e},
-+  0x23,
-+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-+   0x01,0x00,0x00,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-+   0xff}
-+ },
-+/* 0x10: ROM_SAVEPTR - totally different for 300 */
-+ {
-+  0x9f,0x3b,0x00,0x00c0,
-+  {0x00,0x00,0x00,0x00},
-+  0x00,
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
-+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
-+   0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x00,0x00,0x00,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x00}
-+ },
-+/* 0x11: MD_F */
-+ {
-+  0x50,0x18,0x0e,0x8000,
-+  {0x01,0x0f,0x00,0x06},
-+  0xa2,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
-+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
-+   0xff},
-+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-+   0x0b,0x00,0x05,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-+   0xff}
-+ },
-+/* 0x12: MD_10 */
-+ {
-+  0x50,0x18,0x0e,0x8000,
-+  {0x01,0x0f,0x00,0x06},
-+  0xa3,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
-+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x01,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-+   0xff}
-+ },
-+/* 0x13: MD_0_350 */
-+ {
-+  0x28,0x18,0x0e,0x0800,
-+  {0x09,0x03,0x00,0x02},
-+  0xa3,
-+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
-+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x14: MD_1_350 */
-+ {
-+  0x28,0x18,0x0e,0x0800,
-+  {0x09,0x03,0x00,0x02},
-+  0xa3,
-+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x15: MD_2_350 */
-+ {
-+  0x50,0x18,0x0e,0x1000,
-+  {0x01,0x03,0x00,0x02},
-+  0xa3,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x16: MD_3_350 - mode 0x03 - 1 */
-+ {
-+  0x50,0x18,0x0e,0x1000,
-+  {0x01,0x03,0x00,0x02},
-+  0xa3,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x08,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x17: MD_0_1_400 */
-+ {
-+  0x28,0x18,0x10,0x0800,
-+  {0x08,0x03,0x00,0x02},
-+  0x67,
-+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
-+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x0c,0x00,0x0f,0x08},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
-+ {
-+  0x50,0x18,0x10,0x1000,
-+  {0x00,0x03,0x00,0x02},
-+  0x67,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x0c,0x00,0x0f,0x08},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-+   0xff}
-+ },
-+/* 0x19: MD_7_400 */
-+ {
-+  0x50,0x18,0x10,0x1000,
-+  {0x00,0x03,0x00,0x02},
-+  0x66,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-+   0x0e,0x00,0x0f,0x08},
-+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-+   0xff}
-+ },
-+/* 0x1a: MD_11 */
-+ {
-+  0x50,0x1d,0x10,0xa000,
-+  {0x01,0x0f,0x00,0x06},
-+  0xe3,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
-+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,    /* e9,8b is ea,8c on 300 */
-+   0xff},
-+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-+   0x01,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-+   0xff}
-+ },
-+/* 0x1b: ExtEGATable - Modes <= 0x02 */
-+ {
-+  0x50,0x1d,0x10,0xa000,
-+  {0x01,0x0f,0x00,0x06},
-+  0xe3,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
-+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,    /* e9,8b is ea,8c on 300 */
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-+   0x01,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-+   0xff}
-+ },
-+/* 0x1c: MD_13 */
-+ {
-+  0x28,0x18,0x08,0x2000,
-+  {0x01,0x0f,0x00,0x0e},
-+  0x63,
-+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
-+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-+   0xff},
-+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-+   0x41,0x00,0x0f,0x00},
-+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-+   0xff}
-+ }
-+};
-+
-+static const UCHAR SiS_NTSCTiming[] = {
-+	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-+	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-+	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-+	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-+	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
-+};
-+
-+static const UCHAR SiS_PALTiming[] = {
-+	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-+	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-+	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-+	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
-+	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-+	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
-+};
-+
-+static const UCHAR SiS_HiTVExtTiming[] = {
-+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-+};
-+
-+static const UCHAR SiS_HiTVSt1Timing[] = {
-+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-+	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
-+	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
-+	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
-+	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
-+	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
-+};
-+
-+static const UCHAR SiS_HiTVSt2Timing[] = {
-+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-+};
-+
-+static const UCHAR SiS_HiTVTextTiming[] = {
-+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-+	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
-+	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-+	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
-+        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
-+	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
-+};
-+
-+static const UCHAR SiS_HiTVGroup3Data[] = {
-+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
-+	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
-+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-+	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
-+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-+	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
-+	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
-+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-+};
-+
-+static const UCHAR SiS_HiTVGroup3Simu[] = {
-+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
-+	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
-+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-+	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
-+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-+	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
-+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-+};
-+
-+static const UCHAR SiS_HiTVGroup3Text[] = {
-+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
-+	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
-+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-+	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
-+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-+	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
-+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-+};
-+
-+static const UCHAR SiS_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* Was {0x21,0xed,0x8a,0x08}; */
-+static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* Was {0x2a,0x05,0xd3,0x00};  */
-+static const UCHAR SiS_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};
-+static const UCHAR SiS_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};
-+static const UCHAR SiS_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
-+static const UCHAR SiS_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
-+static const UCHAR SiS_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};
-+static const UCHAR SiS_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};
-+static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
-+
-+static const SiS_TVDataStruct  SiS_StPALData[]=
-+{
-+ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-+ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-+ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-+ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-+ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
-+ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-+};
-+
-+static const SiS_TVDataStruct  SiS_ExtPALData[] =
-+{
-+ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
-+ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-+ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
-+ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
-+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
-+ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 */
-+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
-+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
-+};
-+
-+static const SiS_TVDataStruct  SiS_StNTSCData[]=
-+{
-+ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
-+ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
-+ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-+ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-+ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-+};
-+
-+static const SiS_TVDataStruct  SiS_ExtNTSCData[]=
-+{
-+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
-+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
-+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
-+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
-+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
-+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
-+/*{   2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},*/  /* 720x480  (old, from 650) */
-+ {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08}     /* 1024x768 CORRECTED */
-+/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 */
-+#if 0  /* 300 series was: */
-+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
-+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
-+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
-+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
-+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
-+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
-+#endif
-+};
-+
-+
-+static const SiS_TVDataStruct  SiS_St2HiTVData[]=
-+{
-+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
-+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
-+};
-+
-+static const SiS_TVDataStruct  SiS_ExtHiTVData[]=
-+{
-+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
-+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},  /* 640x480   */
-+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x600   */
-+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
-+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
-+ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
-+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
-+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
-+};
-+
-+static const UCHAR SiS_OutputSelect = 0x40;
-+
-+static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
-+
-+static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
-+{
-+	{    9,   2, 800, 500,1800,1000},
-+	{    9,   2, 800, 500,1800,1000},
-+	{    4,   1, 900, 500,1800,1000},
-+	{    4,   1, 900, 500,1800,1000},
-+	{    9,   2, 800, 500,1800,1000},
-+	{   30,  11,1056, 625,1800,1000},
-+	{    5,   3,1350, 800,1800,1000},
-+	{    1,   1,1576,1050,1576,1050},
-+	{    1,   1,1800,1000,1800,1000}
-+};
-+
-+static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
-+{
-+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
-+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
-+	{ 211,  100, 2100,  408, 1688,  802 },
-+	{ 211,   64, 1536,  358, 1688,  802 },
-+	{ 211,   48,  840,  488, 1688,  802 },
-+	{ 211,   72, 1008,  609, 1688,  802 },
-+	{ 211,  128, 1400,  776, 1688,  802 },
-+	{ 211,  205, 1680, 1041, 1688,  802 },
-+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
-+};
-+
-+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
-+{
-+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
-+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
-+	{ 211,  100, 2100,  408, 1688,  802 },
-+	{ 211,   64, 1536,  358, 1688,  802 },
-+	{ 211,   48,  840,  488, 1688,  802 },
-+	{ 211,   72, 1008,  609, 1688,  802 },
-+	{ 211,  128, 1400,  776, 1688,  802 },
-+	{ 211,  205, 1680, 1041, 1688,  802 },
-+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
-+};
-+
-+static const SiS_LCDDataStruct  SiS_NoScaleData1280x768[] =
-+{  /* All values guessed */
-+        { 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802},
-+	{ 1, 1, 1688,  802, 1688,  802}
-+};
-+
-+static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
-+{
-+	{ 211,  100, 2100,  408, 1688, 1066 },
-+	{ 211,   64, 1536,  358, 1688, 1066 },
-+	{ 211,  100, 2100,  408, 1688, 1066 },
-+	{ 211,   64, 1536,  358, 1688, 1066 },
-+	{ 211,   48,  840,  488, 1688, 1066 },
-+	{ 211,   72, 1008,  609, 1688, 1066 },
-+	{ 211,  128, 1400,  776, 1688, 1066 },
-+	{ 211,  205, 1680, 1041, 1688, 1066 },
-+	{   1,    1, 1688, 1066, 1688, 1066 }
-+};
-+
-+static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
-+{
-+	{ 211,  100, 2100,  408, 1688, 1066 },
-+	{ 211,   64, 1536,  358, 1688, 1066 },
-+	{ 211,  100, 2100,  408, 1688, 1066 },
-+	{ 211,   64, 1536,  358, 1688, 1066 },
-+	{ 211,   48,  840,  488, 1688, 1066 },
-+	{ 211,   72, 1008,  609, 1688, 1066 },
-+	{ 211,  128, 1400,  776, 1688, 1066 },
-+	{ 211,  205, 1680, 1041, 1688, 1066 },
-+	{   1,    1, 1688, 1066, 1688, 1066 }
-+};
-+
-+static const SiS_LCDDataStruct  SiS_NoScaleData1400x1050[] =
-+{
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 },
-+	{ 1, 1, 1688, 1066, 1688, 1066 }
-+};
-+
-+static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
-+{  /* TODO */
-+	{    0,   0,   0,   0,   0,   0}
-+};
-+
-+static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
-+{  /* TODO */
-+	{    0,   0,   0,   0,   0,   0}
-+};
-+
-+static const SiS_LCDDataStruct  SiS_NoScaleData1600x1200[] =
-+{  /* TODO - values guessed */
-+        {1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250},
-+	{1,  1, 2048, 1250, 2048, 1250}
-+};
-+
-+static const SiS_LCDDataStruct  SiS_NoScaleData[] =
-+{
-+	{ 1, 1, 800, 449, 800, 449 },
-+	{ 1, 1, 800, 449, 800, 449 },
-+	{ 1, 1, 900, 449, 900, 449 },
-+	{ 1, 1, 900, 449, 900, 449 },
-+	{ 1, 1, 800, 525, 800, 525 },
-+	{ 1, 1,1056, 628,1056, 628 },
-+	{ 1, 1,1344, 806,1344, 806 },
-+	{ 1, 1,1688,1066,1688,1066 },
-+        { 1, 1,1688, 802,1688, 802 },  /* 1280x768: 802 was 806 in both cases */
-+        { 1, 1,2048,1250,2048,1250 },  /* 1600x1200 (guessed) */
-+	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
-+{
-+	{ 848, 433, 400, 525},
-+	{ 848, 389, 400, 525},
-+	{ 848, 433, 400, 525},
-+	{ 848, 389, 400, 525},
-+	{ 848, 518, 400, 525},
-+	{1056, 628, 400, 525},
-+	{ 400, 525, 400, 525},
-+	{ 800, 449,1000, 644},
-+	{ 800, 525,1000, 635}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
-+{
-+	{ 848, 433,1060, 629},
-+	{ 848, 389,1060, 629},
-+	{ 848, 433,1060, 629},
-+	{ 848, 389,1060, 629},
-+	{ 848, 518,1060, 629},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{ 800, 449,1000, 644},
-+	{ 800, 525,1000, 635}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
-+{
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{1056, 628,1056, 628},
-+	{ 800, 449,1000, 644},
-+	{ 800, 525,1000, 635}
-+};
-+
-+
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
-+{
-+	{1048, 442,1688,1066},
-+	{1048, 392,1688,1066},
-+	{1048, 442,1688,1066},
-+	{1048, 392,1688,1066},
-+	{1048, 522,1688,1066},
-+	{1208, 642,1688,1066},
-+	{1432, 810,1688,1066},
-+	{1688,1066,1688,1066}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
-+{
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
-+{
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 518,1344, 806},   /* 640x480 */
-+	{1050, 638,1344, 806},   /* 800x600 */
-+	{1344, 806,1344, 806},   /* 1024x768 */
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
-+{
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+/* Custom data for Barco iQ R300 */
-+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_1[]=
-+{
-+	{ 832, 438,1331, 806},
-+	{ 832, 388,1331, 806},
-+	{ 832, 438,1331, 806},
-+	{ 832, 388,1331, 806},
-+	{ 832, 518,1331, 806},
-+	{1050, 638,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066}   /* 1360x1024 */
-+};
-+
-+/* Custom data for Barco iQ R300 */
-+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_2[]=
-+{
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1688,1066,1688,1066},
-+	{1688,1066,1688,1066}   /* 1360x1024 */
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_1[]=
-+{
-+	{ 832, 438,1331, 806},
-+	{ 832, 409,1331, 806},
-+	{ 832, 438,1331, 806},
-+	{ 832, 409,1331, 806},
-+	{ 832, 518,1331, 806},   /* 640x480 */
-+	{1050, 638,1344, 806},   /* 800x600 */
-+	{1344, 806,1344, 806},   /* 1024x768 */
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
-+{
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
-+{
-+        { 928, 416, 1688,1066},
-+	{ 928, 366, 1688,1066},
-+	{ 928, 416, 1688,1066},
-+	{ 928, 366, 1688,1066},
-+	{ 928, 496, 1688,1066},
-+	{1088, 616, 1688,1066},
-+	{1312, 784, 1688,1066},
-+	{1568,1040, 1688,1066},
-+	{1688,1066, 1688,1066}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
-+{
-+        {1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+	{1688,1066, 1688,1066},
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
-+{
-+        {1088, 450, 2048,1250},
-+	{1088, 400, 2048,1250},
-+	{1088, 450, 2048,1250},
-+	{1088, 400, 2048,1250},
-+	{1088, 530, 2048,1250},
-+	{1248, 650, 2048,1250},
-+	{1472, 818, 2048,1250},
-+	{1728,1066, 2048,1250},
-+	{1848,1066, 2048,1250},
-+	{2048,1250, 2048,1250}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
-+{
-+        {2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250},
-+	{2048,1250, 2048,1250}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
-+{
-+	{ 768, 438, 1408, 806},
-+	{ 768, 388, 1408, 806},
-+	{ 768, 438, 1408, 806},
-+	{ 768, 388, 1408, 806},
-+	{ 768, 518, 1408, 806},
-+	{ 928, 638, 1408, 806},
-+	{1152, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
-+{
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806},
-+	{1408, 806, 1408, 806}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
-+{
-+	{840, 604,1344, 800},
-+	{840, 560,1344, 800},
-+	{840, 604,1344, 800},
-+	{840, 560,1344, 800},
-+	{840, 689,1344, 800},
-+	{1050, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{800, 449,1280, 789},
-+	{800, 525,1280, 785}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
-+{
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{1344, 800,1344, 800},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
-+{
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 518,1344, 806},
-+	{1050, 638,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
-+{
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+/* TW: Pass 1:1 data */
-+static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
-+{
-+        { 800, 449,  800, 449},
-+	{ 800, 449,  800, 449},
-+	{ 900, 449,  900, 449},
-+	{ 900, 449,  900, 449},
-+	{ 800, 525,  800, 525},  /*  640x480   */
-+	{1056, 628, 1056, 628},  /*  800x600   */
-+	{1344, 806, 1344, 806},  /* 1024x768   */
-+	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
-+ 	{1688, 806, 1688, 806},  /* 1280x768   */
-+	/* No other panels ! */
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_1[]=
-+{
-+	{ 800, 445, 800, 525},   /* 800, 449, 800, 449 */
-+	{ 800, 395, 800, 525},
-+	{ 800, 445, 800, 525},
-+	{ 800, 395, 800, 525},
-+	{ 800, 525, 800, 525},
-+	{ 800, 525, 800, 525},   /* pseudo */
-+	{ 800, 525, 800, 525}    /* pseudo */
-+};
-+
-+/* FSTN 320x240 */
-+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_2[]=
-+{
-+	{ 800, 445, 800, 525},
-+	{ 800, 395, 800, 525},
-+	{ 800, 445, 800, 525},
-+	{ 800, 395, 800, 525},
-+	{ 800, 525, 800, 525},
-+        { 800, 525, 800, 525},   /* pseudo */
-+	{ 800, 525, 800, 525}    /* pseudo */
-+};
-+
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
-+{
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 438,1344, 806},
-+	{ 840, 409,1344, 806},
-+	{ 840, 518,1344, 806},
-+	{1050, 638,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
-+{
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+/* LCDA */
-+
-+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
-+{	/* TW: Might be temporary (invalid) data */
-+        { 928, 416, 1688,1066},
-+	{ 928, 366, 1688,1066},
-+	{1008, 416, 1688,1066},
-+	{1008, 366, 1688,1066},
-+	{1200, 530, 1688,1066},
-+	{1088, 616, 1688,1066},
-+	{1312, 784, 1688,1066},
-+	{1568,1040, 1688,1066},
-+	{1688,1066, 1688,1066}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
-+{	/* TW: Temporary data. Not valid */
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
-+{	/* TW: Temporary data. Not valid */
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{1344, 806,1344, 806},
-+	{ 800, 449,1280, 801},
-+	{ 800, 525,1280, 813}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_2[]=
-+{	/* TW: Temporary data. Not valid */
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0},
-+	{0, 0, 0, 0}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
-+{
-+	{ 840, 600, 840, 600},
-+	{ 840, 600, 840, 600},
-+	{ 840, 600, 840, 600},
-+	{ 840, 600, 840, 600},
-+	{ 784, 600, 784, 600},
-+	{1064, 750,1064, 750},
-+        {1160, 945,1160, 945}
-+};
-+
-+static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
-+{
-+	{ 840, 525, 840, 525},
-+	{ 840, 525, 840, 525},
-+	{ 840, 525, 840, 525},
-+	{ 840, 525, 840, 525},
-+	{ 784, 525, 784, 525},
-+	{1040, 700,1040, 700},
-+        {1160, 840,1160, 840}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
-+{  /* 1024x768 */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
-+{  /* 1024x768 */
-+	{ 1184, 622 },
-+	{ 1184, 597 },
-+	{ 1184, 622 },
-+	{ 1184, 597 },
-+	{ 1152, 622 },
-+	{ 1232, 722 },
-+	{    0, 0   },
-+	{    0, 794 },
-+	{    0, 0   }
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
-+{  /* 1280x1024 */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
-+{  /* 1280x1024 */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
-+{  /* 1400x1050 */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
-+{  /* 1400x1050 - looks heavily invalid */
-+	{ 808 , 740},
-+	{ 0   , 715},
-+	{ 632 , 740},
-+	{ 632 , 715},
-+	{ 1307, 780},
-+	{ 1387,1157},
-+	{ 1499, 924},
-+	{ 1627,1052},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
-+{  /* 1600x1200 */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
-+{  /* 1600x1200 - BIOS looks heavily invalid, not copied */
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
-+{
-+	{ 8,   0},
-+	{ 8,   0},
-+	{ 8,   0},
-+	{ 8,   0},
-+	{ 8,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0, 806},
-+	{ 0, 0 }
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
-+{
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0},
-+	{ 0 , 0}
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
-+{
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0}
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_CHTVONTSCDesData[]=
-+{
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0}
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
-+{
-+	{256,   0},
-+	{256,   0},
-+	{256,   0},
-+	{256,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0}
-+};
-+
-+static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
-+{
-+	{256,   0},
-+	{256,   0},
-+	{256,   0},
-+	{256,   0},
-+	{ 0,   0},
-+	{ 0,   0},
-+	{ 0,   0}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
-+{
-+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
-+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-+   0x00 }},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00 }},
-+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
-+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+   0x00 }},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00 }},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-+   0x00 }},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01 }},
-+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00 }}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1[] =
-+{
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-+	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-+	  0x01}},
-+        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1_H[] =
-+{
-+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-+          0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-+	  0x00}},
-+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-+	  0x01}},
-+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2[] =
-+{
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-+	  0x01}},
-+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2_H[] =
-+{
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-+	  0x01}},
-+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1[] =
-+{
-+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-+	  0x00}},
-+        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-+	  0x00}},
-+        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-+	  0x01}},
-+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1_H[] =
-+{
-+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-+	  0x00}},
-+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-+	  0x00}},
-+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-+	  0x01}},
-+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2[] =
-+{
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-+	  0x00}},
-+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-+	  0x01}},
-+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2_H[] =
-+{
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-+	  0x00}},
-+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-+	  0x01}},
-+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-+	  0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1[] =
-+{
-+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-+   0x00}},
-+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-+   0x00}},
-+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-+   0x00}},
-+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-+   0x00}},
-+ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
-+   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
-+   0x00}},
-+ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
-+   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
-+   0x01}},
-+ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
-+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1_H[] =
-+{
-+ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-+   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-+   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-+   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
-+   0x01}},
-+ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-+   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
-+   0x01}},
-+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-+   0x01}},
-+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2[] =
-+{
-+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-+   0x00}},
-+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-+   0x00}},
-+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-+   0x00}},
-+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-+   0x00}},
-+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
-+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
-+   0x01}},
-+ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
-+   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
-+   0x01}},
-+ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
-+{
-+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-+   0x00}},
-+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-+   0x00}},
-+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-+   0x00}},
-+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-+   0x00}},
-+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
-+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
-+   0x01}},
-+ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
-+   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
-+   0x01}},
-+ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-+   0x01}},
-+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1[] =
-+{
-+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}},
-+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-+   0x01}},
-+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-+   0x01}},
-+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1_H[] =
-+{
-+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-+   0x00}},
-+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-+   0x00}},
-+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-+   0x00}},
-+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-+   0x00}},
-+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}},
-+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-+   0x01}},
-+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1[] =
-+{
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1_H[] =
-+{
-+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
-+   0x00}},
-+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
-+   0x00}},
-+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
-+   0x00}},
-+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
-+   0x00}},
-+ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
-+{
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}},
-+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
-+{
-+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
-+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
-+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}},
-+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
-+{
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}},
-+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}
-+};
-+
-+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
-+{
-+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
-+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
-+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-+   0x00}},
-+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-+   0x01}},
-+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-+   0x00}}
-+};
-+
-+#define SIS_PL_HSYNCP 0x01
-+#define SIS_PL_HSYNCN 0x02
-+#define SIS_PL_VSYNCP 0x04
-+#define SIS_PL_VSYNCN 0x08
-+#define SIS_PL_DVI    0x80
-+
-+typedef struct _SiS_PlasmaModes
-+{
-+  const char *name;
-+  ULONG  clock;
-+  USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
-+  USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
-+  UCHAR  SyncFlags;
-+} SiS_PlasmaModes;
-+
-+
-+typedef struct _SiS_PlasmaTables
-+{
-+   USHORT vendor;
-+   UCHAR  productnum;
-+   USHORT product[5];
-+   const char *plasmaname;
-+   UCHAR  modenum;
-+   UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
-+} SiS_PlasmaTables;
-+
-+static const SiS_PlasmaModes SiS_PlasmaMode[] = {
-+   {  "640x400",		/* 00: IBM 400@70 */
-+      25175,
-+       640,  800, 17,  64,
-+       400,  449, 13,   2,
-+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-+   {  "640x480",		/* 01: VESA 480@72 */
-+      31500,
-+       640,  832, 24,  40,
-+       480,  520,  9,   3,
-+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-+   {  "800x600",		/* 02: VESA 600@72 */
-+      50000,
-+       800, 1040, 56, 120,
-+       600,  666, 37,   6,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "864x480",		/* 03: Cereb wide 1 */
-+      42526,
-+       864, 1134, 22,  86,
-+       480,  500,  1,   3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
-+   {  "848x480",		/* 04: VESA wide (NEC1) */
-+      33750,
-+       848, 1088, 16, 112,
-+       480,  517,  6,   8,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1024x576",		/* 05: VESA wide (NEC2) */
-+      47250,
-+      1024, 1320, 16, 144,
-+       576,  596,  2,   4,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1280x720",		/* 06: VESA wide (NEC3) */
-+      76500,
-+      1280, 1696, 48, 176,
-+       720,  750,  4,   8,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1360x765",		/* 07: VESA wide (NEC4) */
-+      85500,
-+      1360, 1792, 64, 176,
-+       765,  795,  4,   8,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1024x600",		/* 08: CEREB wide 2 */
-+      51200,
-+      1024, 1352, 51, 164,
-+       600,  628,  1,   4,
-+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
-+   {  "1024x768",		/* 09: VESA 768@75 */
-+      78750,
-+      1024, 1312,  16, 96,
-+       768,  800,   1,  3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1152x864",		/* 10: VESA 1152x864@75 */
-+      108000,
-+      1152, 1600, 64, 128,
-+       864,  900,  1,   3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1280x1024",		/* 11: VESA 1024@60 */
-+      108000,
-+      1280, 1688, 48, 112,
-+      1024, 1066,  1,   3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1280x768",		/* 12: W_XGA */
-+      81000,
-+      1280, 1688, 48, 112,
-+       768,  802,  3,   6,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
-+   {  "1280x768",		/* 13: I/O Data W_XGA@56Hz */
-+      76064,
-+      1280, 1688, 48, 112,
-+       768,  802,  2,   3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1376x768",		/* 14: I/O Wide XGA */
-+      87340,
-+      1376, 1808, 32, 128,
-+       768,  806,  3,   6,
-+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
-+   {  "1280x960",		/* 15: VESA 960@60 */
-+      108000,
-+      1280, 1800, 96, 112,
-+       960, 1000,  1,   3,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "1400x1050",		/* 16: VESA 1050@60Hz */
-+      108000,
-+      1400, 1688, 48, 112,
-+      1050, 1066,  1,   3,
-+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
-+   {  "1360x768",		/* 17: VESA wide (NEC4/2) */
-+      85500,
-+      1360, 1792, 64, 112,
-+       765,  795,  3,   6,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
-+   {  "800x600",		/* 18: VESA 600@56 */
-+      36000,
-+       800, 1024, 24,   2,
-+       600,  625,  1,   2,
-+      SIS_PL_HSYNCP | SIS_PL_VSYNCP }
-+};
-+
-+static const SiS_PlasmaTables SiS_PlasmaTable[] = {
-+#if 0  /* Product IDs missing */
-+   { 0x38a3, 4,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
-+     14,   /* All DVI, except 0, 7, 13; 3, 15, 16 unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,12|0xc0,
-+      13|0x40,14|0xc0,15|0xc0,16|0xc0, 0     , 0     , 0     , 0     , 0     , 0 }
-+   },
-+   { 0x38a3, 3,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42PD1/50PD1/50PD2",
-+     5,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42PD3",
-+     10,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 2,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42VM3/61XM1",
-+     11,  /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
-+      17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 2,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42MP1/42MP2",
-+     6,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 50MP1",
-+     10,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+#endif
-+   { 0x38a3, 4,
-+     { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
-+     11,   /* All DVI except 0, 7, 13, 17 */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
-+      17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+#if 0  /* Product IDs missing */
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 3300W",
-+     3,
-+     { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 4200W",
-+     4,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0     , 0     , 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 4210W",
-+     6,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x38a3, 1,
-+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "NEC PlasmaSync 5000W",
-+     7,   /* DVI entirely unknown */
-+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+#endif
-+   { 0x412f, 1,
-+     { 0x000c, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "Pioneer 503CMX",
-+     6,   /* DVI unknown */
-+     { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x34a9, 1,
-+     { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
-+     "Panasonic TH-42",
-+     5,   /* No DVI output */
-+     { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
-+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
-+   },
-+   { 0x0000 }
-+};
-+
- void     SiS_SetReg1(USHORT, USHORT, USHORT);
- void     SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
- void     SiS_SetReg3(USHORT, USHORT);
-@@ -158,6 +2337,7 @@ void     SiS_SetMemoryClock(SiS_Private 
- void     SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
- BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
- void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-+void     SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- 
- #ifdef SIS300
- void     SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-@@ -192,12 +2372,15 @@ void     SiS_VerifyMclk(SiS_Private *SiS
- 
- void     SiS_HandleCRT1(SiS_Private *SiS_Pr);
- void     SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
--void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
-+void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-+void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
- void     SiS_Delay15us(SiS_Private *SiS_Pr);
- BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
- BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                              USHORT ModeNo,USHORT ModeIdIndex);
- UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-+void     SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-+void     SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- void     SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
- void     SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
- void     SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-@@ -267,19 +2450,19 @@ void    	SiS_SetPitchCRT1(SiS_Private *S
- void    	SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
- extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
- 	     	 		    int *out_sbit, int *out_scale);
-+extern void 	SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
-+
- extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
- extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
--extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
-+extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm);
- #endif
- 
- extern USHORT    SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
- extern USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
- extern void      SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
--extern BOOLEAN   SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
--                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
--extern void      SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
--                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
-+extern BOOLEAN   SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-+                                  PSIS_HW_DEVICE_INFO HwDeviceExtension);
- extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
- extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
- extern BOOLEAN   SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
-@@ -321,10 +2504,12 @@ int    sisfb_mode_rate_to_dclock(SiS_Pri
- 			      unsigned char modeno, unsigned char rateindex);
- int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- 			 unsigned char modeno, unsigned char rateindex,
--			 ULONG *left_margin, ULONG *right_margin, 
-+			 ULONG *left_margin, ULONG *right_margin,
- 			 ULONG *upper_margin, ULONG *lower_margin,
- 			 ULONG *hsync_len, ULONG *vsync_len,
- 			 ULONG *sync, ULONG *vmode);
-+BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
- #endif
- 
- #endif
---- linux-2.6.0-test1/drivers/video/sis/oem300.h	2003-06-14 12:18:05.000000000 -0700
-+++ 25/drivers/video/sis/oem300.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,5 +1,30 @@
--
--/* OEM Data for 300 series */
-+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
-+/*
-+ * OEM Data for 300 series
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ */
- 
- const UCHAR SiS300_OEMTVDelay301[8][4] =
- {
-@@ -680,325 +705,147 @@ const UCHAR SiS300_Filter2[10][9][7] =
-     }
- };
- 
--const UCHAR SiS300_LCDHData[24][11][5] = {
-+/* Custom data for Barco iQ Pro R300 */
-+const UCHAR barco_p1[2][9][7][3] = {
-     {
--        {0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x8a,0x14,0x00,0x80,0x00},
--	{0x8a,0x14,0x00,0x80,0x00}
--    },
--    {
--        {0x4e,0x18,0x90,0x38,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9a,0x56,0x00},
--        {0x67,0x11,0x9a,0x56,0x00},
--	{0x8a,0x14,0x00,0x80,0x00},
--	{0x8a,0x14,0x00,0x80,0x00}
--    },
--    {
--        {0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x8a,0x14,0x00,0x80,0x00},
--	{0x8a,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4e,0x18,0x90,0x38,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x8e,0x18,0x28,0x78,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x4e,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9a,0x56,0x00},
--	{0x67,0x11,0x9a,0x56,0x00},
--	{0x8a,0x14,0x00,0x80,0x00},
--	{0x8a,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x67,0x91,0x84,0x5e,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x65,0xef,0x83,0x5c,0x00},
--	{0x8a,0x14,0x00,0x80,0x00},
--	{0x8a,0x14,0x00,0x80,0x00}
--    },
--    {
--        {0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--    	{0x67,0x91,0x84,0x5E,0x00},
--    	{0x67,0x91,0x84,0x5E,0x00},
--    	{0x67,0x91,0x84,0x5E,0x00},
--    	{0x67,0x91,0x84,0x5E,0x00},
--    	{0x65,0xEF,0x83,0x5C,0x00},
--    	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x67,0x91,0x84,0x5E,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x65,0xEF,0x83,0x5C,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
--    },
--    {
--    	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x8E,0x18,0x28,0x78,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x4E,0x18,0x90,0x38,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x67,0x11,0x9A,0x56,0x00},
--	{0x8A,0x14,0x00,0x80,0x00},
--	{0x8A,0x14,0x00,0x80,0x00}
-+	{  { 0x16, 0xcf, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x19, 0x00 }
-+	},
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x1e, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x16, 0x00 }
-+	},
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x19, 0x00 },
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x1e, 0x00 },
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0xd1, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x11, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x26, 0x00 }
-+	},
-+	{
-+	   { 0x16, 0xd1, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x30, 0x00 },
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0x00, 0x00 },
-+	   { 0x17, 0xa0, 0x00 },
-+	   { 0x1a, 0xa0, 0x00 },
-+	   { 0x1b, 0x2a, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0x00, 0x00 },
-+	   { 0x17, 0xaa, 0x00 },
-+	   { 0x1a, 0xa0, 0x00 },
-+	   { 0x1b, 0x2a, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   {    0,    0,    0 }
-+	}
-+    },
-+    {
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x19, 0x00 }
-+	},
-+	{
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x19, 0x00 },
-+	},
-+	{
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   { 0x16, 0xcf, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe7, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x1e, 0x00 }
-+	},
-+	{
-+	   { 0x16, 0xd1, 0x00 },
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe6, 0x00 },
-+	   { 0x1b, 0x11, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x26, 0x00 }
-+	},
-+	{
-+	   { 0x18, 0x00, 0x00 },
-+	   { 0x1a, 0xe0, 0x00 },
-+	   { 0x1b, 0x26, 0x00 },
-+	   { 0x1c, 0xff, 0x00 },
-+	   { 0x1d, 0x1c, 0x00 },
-+	   { 0x1e, 0x30, 0x00 },
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   {    0,    0,    0 }
-+	},
-+	{
-+	   {    0,    0,    0 }
-+	}
-     }
- };
- 
--#if 0
--const UCHAR SiS300_LCDVData[24][11][6] = {
--    {
--        {
--    },
--};
--#endif
-+
-+
-+
-+
-+
---- linux-2.6.0-test1/drivers/video/sis/oem310.h	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/video/sis/oem310.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,5 +1,30 @@
--
--/* OEM Data for 310/325/330 series */
-+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
-+/*
-+ * OEM Data for 315/330 series
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ */
- 
- const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
- {
-@@ -100,7 +125,7 @@ const UCHAR SiS310_LCDDelayCompensation_
- 
- const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
- {
--                 0x33,0x33,0x33,    /*   800x600 (guessed) */
-+                 0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
- 		 0x33,0x33,0x33,    /*  1024x768 */
- 		 0x33,0x33,0x33,    /* 1280x1024 */
- 		 0x33,0x33,0x33,    /*   640x480 (unknown) */
---- linux-2.6.0-test1/drivers/video/sis/osdef.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/drivers/video/sis/osdef.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,79 +1,43 @@
--/* #define WINCE_HEADER */
--/* #define WIN2000 */
--/* #define TC */
-+
-+/* OS depending defines */
-+
-+/* The choices are: */
-+
- #define LINUX_KERNEL	   /* Kernel framebuffer */
- /* #define LINUX_XF86 */   /* XFree86 */
- 
- /**********************************************************************/
--#ifdef LINUX_KERNEL
--	#include <linux/config.h>
--	#include <linux/version.h>
--	#ifdef CONFIG_FB_SIS_300
-- 		#define SIS300
--	#endif
--
--	#ifdef CONFIG_FB_SIS_315
--		#define SIS315H
--	#endif
--	#if 1
--		#define SISFBACCEL	/* Include 2D acceleration */
--	#endif
--	#if 1
--		#define SISFB_PAN	/* Include Y-Panning code */
--	#endif
--#else
--/*	#define SIS300*/
--	#define SIS315H
--#endif
--#ifdef LINUX_XF86
--	#define SIS300
--	/* #define SIS315H */ /* TW: done above */
--#endif
-+#ifdef LINUX_KERNEL  /* -------------------------- */
-+#include <linux/config.h>
-+#include <linux/version.h>
- 
--/**********************************************************************/
--#ifdef TC
--#endif
--#ifdef WIN2000
--#endif
--#ifdef WINCE_HEADER
--#endif
--#ifdef LINUX_XF86
-+#ifdef CONFIG_FB_SIS_300
-+#define SIS300
- #endif
--#ifdef LINUX_KERNEL
--#endif
--/**********************************************************************/
--#ifdef TC
--#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
--#endif
--#ifdef WIN2000
--#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
-+
-+#ifdef CONFIG_FB_SIS_315
-+#define SIS315H
- #endif
--#ifdef WINCE_HEADER
--#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
-+
-+#if 1
-+#define SISFBACCEL	/* Include 2D acceleration */
- #endif
--#ifdef LINUX_XF86
--#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-+
- #endif
--#ifdef LINUX_KERNEL
--#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-+
-+#ifdef LINUX_XF86 /* ----------------------------- */
-+#define SIS300
-+#define SIS315H
- #endif
--/**********************************************************************/
- 
- /**********************************************************************/
--
--#ifdef TC
--#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
--#endif
--#ifdef WIN2000
--#define SiS_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
--#endif
--#ifdef WINCE_HEADER
--#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
--#endif
- #ifdef LINUX_XF86
-+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
- #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
- #endif
-+
- #ifdef LINUX_KERNEL
-+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
- #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
- #endif
- 
-@@ -104,19 +68,6 @@
- #endif /* InPortLong */
- 
- /**********************************************************************/
--/*  TC                                                                */
--/**********************************************************************/
--
--#ifdef TC
--#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
--#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
--#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
--#define InPortByte(p)    inp((unsigned short)(p))
--#define InPortWord(p)    inp((unsigned short)(p))
--#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
--#endif
--
--/**********************************************************************/
- /*  LINUX XF86                                                        */
- /**********************************************************************/
- 
-@@ -142,29 +93,4 @@
- #define InPortLong(p)    inl((u16)(p))
- #endif
- 
--/**********************************************************************/
--/*  WIN 2000                                                          */
--/**********************************************************************/
--
--#ifdef WIN2000
--#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
--#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
--#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
--#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
--#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
--#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
--#endif
- 
--
--/**********************************************************************/
--/*  WIN CE                                                            */
--/**********************************************************************/
--
--#ifdef WINCE_HEADER
--#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
--#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
--#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
--#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
--#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
--#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
--#endif
---- linux-2.6.0-test1/drivers/video/sis/sis_accel.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/drivers/video/sis/sis_accel.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,5 +1,5 @@
- /*
-- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
-+ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
-  * for Linux kernels 2.4.x and 2.5.x
-  *
-  * 2D acceleration part
-@@ -211,7 +211,7 @@ SiS300SubsequentSolidFillRect(int x, int
- 	SiS300DoCMD
- }
- 
--/* 310/325 series ------------------------------------------------ */
-+/* 315 series ---------------------------------------------------- */
- 
- static void
- SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-@@ -230,7 +230,7 @@ SiS310SetupForScreenToScreenCopy(int xdi
- 		/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
- 	}
- 	SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
--	/* TW: The 310/325 series is smart enough to know the direction */
-+	/* TW: The 315 series is smart enough to know the direction */
- }
- 
- static void
-@@ -328,11 +328,13 @@ void sisfb_syncaccel(void)
-     }
- }
- 
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
- 
- int fbcon_sis_sync(struct fb_info *info)
- {
--   if(!sisfb_accel) return 0;
-+   if(!ivideo.accel)
-+   	return 0;
-+   
-    CRITFLAGS
-    if(sisvga_engine == SIS_300_VGA) {
-       SiS300Sync();
-@@ -352,7 +354,7 @@ void fbcon_sis_fillrect(struct fb_info *
-    if(!rect->width || !rect->height)
-    	return;
- 
--   if(!sisfb_accel) {
-+   if(!ivideo.accel) {
- 	cfb_fillrect(info, rect);
- 	return;
-    }
-@@ -388,7 +390,7 @@ void fbcon_sis_copyarea(struct fb_info *
-    CRITFLAGS
- 
-    TWDEBUG("Inside sis_copyarea");
--   if(!sisfb_accel) {
-+   if(!ivideo.accel) {
-    	cfb_copyarea(info, area);
- 	return;
-    }
-@@ -418,7 +420,7 @@ void fbcon_sis_copyarea(struct fb_info *
- 
- #endif
- 
--#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)  /* ------ KERNEL <2.5.34 ------ */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
- 
- void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
- 			    int dsty, int dstx, int height, int width)
-@@ -591,38 +593,38 @@ void fbcon_sis_revc(struct display *p, i
- 
- #ifdef FBCON_HAS_CFB8
- struct display_switch fbcon_sis8 = {
--	setup:			fbcon_cfb8_setup,
--	bmove:			fbcon_sis_bmove,
--	clear:			fbcon_sis_clear8,
--	putc:			fbcon_cfb8_putc,
--	putcs:			fbcon_cfb8_putcs,
--	revc:			fbcon_cfb8_revc,
--	clear_margins:		fbcon_cfb8_clear_margins,
--	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-+	.setup			= fbcon_cfb8_setup,
-+	.bmove			= fbcon_sis_bmove,
-+	.clear			= fbcon_sis_clear8,
-+	.putc			= fbcon_cfb8_putc,
-+	.putcs			= fbcon_cfb8_putcs,
-+	.revc			= fbcon_cfb8_revc,
-+	.clear_margins		= fbcon_cfb8_clear_margins,
-+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
- };
- #endif
- #ifdef FBCON_HAS_CFB16
- struct display_switch fbcon_sis16 = {
--	setup:			fbcon_cfb16_setup,
--	bmove:			fbcon_sis_bmove,
--	clear:			fbcon_sis_clear16,
--	putc:			fbcon_cfb16_putc,
--	putcs:			fbcon_cfb16_putcs,
--	revc:			fbcon_sis_revc,
--	clear_margins:		fbcon_cfb16_clear_margins,
--	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-+	.setup			= fbcon_cfb16_setup,
-+	.bmove			= fbcon_sis_bmove,
-+	.clear			= fbcon_sis_clear16,
-+	.putc			= fbcon_cfb16_putc,
-+	.putcs			= fbcon_cfb16_putcs,
-+	.revc			= fbcon_sis_revc,
-+	.clear_margins		= fbcon_cfb16_clear_margins,
-+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
- };
- #endif
- #ifdef FBCON_HAS_CFB32
- struct display_switch fbcon_sis32 = {
--	setup:			fbcon_cfb32_setup,
--	bmove:			fbcon_sis_bmove,
--	clear:			fbcon_sis_clear32,
--	putc:			fbcon_cfb32_putc,
--	putcs:			fbcon_cfb32_putcs,
--	revc:			fbcon_sis_revc,
--	clear_margins:		fbcon_cfb32_clear_margins,
--	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-+	.setup			= fbcon_cfb32_setup,
-+	.bmove			= fbcon_sis_bmove,
-+	.clear			= fbcon_sis_clear32,
-+	.putc			= fbcon_cfb32_putc,
-+	.putcs			= fbcon_cfb32_putcs,
-+	.revc			= fbcon_sis_revc,
-+	.clear_margins		= fbcon_cfb32_clear_margins,
-+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
- };
- #endif
- 
---- linux-2.6.0-test1/drivers/video/sis/sis_accel.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/drivers/video/sis/sis_accel.h	2003-07-19 17:04:55.000000000 -0700
-@@ -47,7 +47,7 @@
- #define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
- #define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
- 
--/* Additional engine commands for 310/325 */
-+/* Additional engine commands for 315 */
- #define ALPHA_BLEND		0x00000007  /* Alpha blend ? */
- #define A3D_FUNCTION		0x00000008  /* 3D command ? */
- #define	CLEAR_Z_BUFFER		0x00000009  /* ? */
-@@ -90,11 +90,11 @@
- #define NO_RESET_COUNTER        0x00400000
- #define NO_LAST_PIXEL           0x00200000
- 
--/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
-+/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
- #define COLOR_TO_MONO		0x00100000
- #define AA_TEXT			0x00200000
- 
--/* Some general registers for 310/325 series */
-+/* Some general registers for 315 series */
- #define SRC_ADDR		0x8200
- #define SRC_PITCH		0x8204
- #define AGP_BASE		0x8206 /* color-depth dependent value */
-@@ -326,7 +326,7 @@ int     CmdQueLen;
- 
- 
- 
--/* ----------- SiS 310/325 series --------------- */
-+/* -------------- SiS 315 series --------------- */
- 
- /* Q_STATUS:
-    bit 31 = 1: All engines idle and all queues empty
-@@ -342,7 +342,7 @@ int     CmdQueLen;
-    bits 7:0:   2D counter 1
- 
-    Where is the command queue length (current amount of commands the queue
--   can accept) on the 310/325 series? (The current implementation is taken
-+   can accept) on the 315 series? (The current implementation is taken
-    from 300 series and certainly wrong...)
- */
- 
---- linux-2.6.0-test1/drivers/video/sis/sis_main.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/video/sis/sis_main.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,25 +1,18 @@
- /*
-- * SiS 300/630/730/540/315/550/650/740 frame buffer device
-+ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer device
-  * for Linux kernels 2.4.x and 2.5.x
-  *
-- * Partly based on the VBE 2.0 compliant graphic boards framebuffer driver,
-- * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-+ * (C) 1999 Silicon Integrated Systems, Inc.
-+ * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
-  *
-  * Authors:   	SiS (www.sis.com.tw)
-- *		(Various others)
-- *		Thomas Winischhofer <thomas@winischhofer.net>:
-- *			- SiS Xabre (330) support
-- *			- many fixes and enhancements for all chipset series,
-- *			- extended bridge handling, TV output for Chrontel 7005
-- *                      - 650/LVDS support (for LCD panels up to 1600x1200)
-- *                      - 650/740/Chrontel 7019 support
-- *                      - 30xB/30xLV LCD, TV and VGA2 support
-- *			- memory queue handling enhancements,
-- *                      - 2D acceleration and y-panning,
-- *                      - portation to 2.5 API
-- *			- etc.
-- *			(see http://www.winischhofer.net/
-- *			for more information and updates)
-+ *		Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ * See http://www.winischhofer.net/ for more information and updates
-+ *
-+ * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
-+ * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-+ *
-  */
- 
- #include <linux/config.h>
-@@ -43,6 +36,7 @@
- #include <linux/fs.h>
- #include <linux/agp_backend.h>
- #include <linux/types.h>
-+#include <asm/uaccess.h>
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- #include <linux/spinlock.h>
-@@ -79,6 +73,12 @@
- #endif
- #endif
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
-+#error "This version of sisfb requires at least 2.5.69"
-+#endif
-+#endif
-+
- /* -------------------- Macro definitions ---------------------------- */
- 
- #undef SISFBDEBUG 	/* TW: no debugging */
-@@ -178,9 +178,12 @@ BOOLEAN sisfb_query_north_bridge_space(P
- 		case SIS_650:
- 			nbridge_id = PCI_DEVICE_ID_SI_650;
- 			break;
--		case SIS_740:			
-+		case SIS_740:
- 			nbridge_id = PCI_DEVICE_ID_SI_740;
- 			break;
-+		case SIS_660:
-+			nbridge_id = PCI_DEVICE_ID_SI_660;
-+			break;
- 		default:
- 			nbridge_id = 0;
- 			break;
-@@ -207,64 +210,288 @@ BOOLEAN sisfb_query_north_bridge_space(P
- 
- /* ------------------ Internal helper routines ----------------- */
- 
--static void sisfb_search_mode(const char *name)
-+static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
- {
--	int i = 0, j = 0;
-+	int htotal, vtotal;
-+	unsigned int dclock, hsync;
- 
--	if(name == NULL) {
--	   printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
--	   sisfb_mode_idx = DEFAULT_MODE;
--	   return;
-+	if(!monitor->datavalid) return TRUE;
-+
-+	if(mode_idx < 0) return FALSE;
-+
-+	if(rate < (monitor->vmin - 1)) return FALSE;
-+	if(rate > (monitor->vmax + 1)) return FALSE;
-+
-+	if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
-+	                          &htotal, &vtotal, rate_idx)) {
-+		dclock = (htotal * vtotal * rate) / 1000;
-+		if(dclock > (monitor->dclockmax + 1000)) return FALSE;
-+		hsync = dclock / htotal;
-+		if(hsync < (monitor->hmin - 1)) return FALSE;
-+		if(hsync > (monitor->hmax + 1)) return FALSE;
-+        } else {
-+	  	return FALSE;
- 	}
--		
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		
--        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
--	   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
--	   sisfb_mode_idx = DEFAULT_MODE;
--	   return;
-+	return TRUE;
-+};
-+
-+static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer)
-+{
-+	int i, j, xres, yres, refresh, index;
-+	u32 emodes;
-+
-+	if(buffer[0] != 0x00 || buffer[1] != 0xff ||
-+	   buffer[2] != 0xff || buffer[3] != 0xff ||
-+	   buffer[4] != 0xff || buffer[5] != 0xff ||
-+	   buffer[6] != 0xff || buffer[7] != 0x00) {
-+	   printk(KERN_INFO "sisfb: Bad EDID header\n");
-+	   return FALSE;
- 	}
--#endif		
- 
--	while(sisbios_mode[i].mode_no != 0) {
--		if (!strcmp(name, sisbios_mode[i].name)) {
--			sisfb_mode_idx = i;
--			j = 1;
--			break;
--		}
--		i++;
-+	if(buffer[0x12] != 0x01) {
-+	   printk(KERN_INFO "sisfb: EDID version %d not supported\n",
-+	   	buffer[0x12]);
-+	   return FALSE;
-+	}
-+
-+	monitor->feature = buffer[0x18];
-+
-+	if(!buffer[0x14] & 0x80) {
-+	   if(!(buffer[0x14] & 0x08)) {
-+	      printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
-+	   }
-+	}
-+
-+	if(buffer[0x13] >= 0x01) {
-+	   /* EDID V1 rev 1 and 2: Search for monitor descriptor
-+	    * to extract ranges
-+	    */
-+	    j = 0x36;
-+	    for(i=0; i<4; i++) {
-+	       if(buffer[j]     == 0x00 && buffer[j + 1] == 0x00 &&
-+	          buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
-+		  buffer[j + 4] == 0x00) {
-+		  monitor->hmin = buffer[j + 7];
-+		  monitor->hmax = buffer[j + 8];
-+		  monitor->vmin = buffer[j + 5];
-+		  monitor->vmax = buffer[j + 6];
-+		  monitor->dclockmax = buffer[j + 9] * 10 * 1000;
-+		  monitor->datavalid = TRUE;
-+		  break;
-+	       }
-+	       j += 18;
-+	    }
-+	}
-+
-+	if(!monitor->datavalid) {
-+	   /* Otherwise: Get a range from the list of supported
-+	    * Estabished Timings. This is not entirely accurate,
-+	    * because fixed frequency monitors are not supported
-+	    * that way.
-+	    */
-+	   monitor->hmin = 65535; monitor->hmax = 0;
-+	   monitor->vmin = 65535; monitor->vmax = 0;
-+	   monitor->dclockmax = 0;
-+	   emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
-+	   for(i = 0; i < 13; i++) {
-+	      if(emodes & sisfb_ddcsmodes[i].mask) {
-+	         if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
-+		 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
-+		 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
-+		 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
-+		 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
-+	      }
-+	   }
-+	   index = 0x26;
-+	   for(i = 0; i < 8; i++) {
-+	      xres = (buffer[index] + 31) * 8;
-+	      switch(buffer[index + 1] & 0xc0) {
-+	         case 0xc0: yres = (xres * 9) / 16; break;
-+	         case 0x80: yres = (xres * 4) /  5; break;
-+	         case 0x40: yres = (xres * 3) /  4; break;
-+	         default:   yres = xres;	    break;
-+	      }
-+	      refresh = (buffer[index + 1] & 0x3f) + 60;
-+	      if((xres >= 640) && (yres >= 480)) {
-+                 for(j = 0; j < 8; j++) {
-+	            if((xres == sisfb_ddcfmodes[j].x) &&
-+	               (yres == sisfb_ddcfmodes[j].y) &&
-+		       (refresh == sisfb_ddcfmodes[j].v)) {
-+		      if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
-+		      if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
-+		      if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
-+		      if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
-+		      if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
-+	            }
-+	         }
-+	      }
-+	      index += 2;
-+           }
-+	   if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
-+	      monitor->datavalid = TRUE;
-+	   }
-+	}
-+
-+ 	return(monitor->datavalid);
-+}
-+
-+static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
-+{
-+	USHORT        temp, i, realcrtno = crtno;
-+   	unsigned char buffer[256];
-+
-+	monitor->datavalid = FALSE;
-+
-+	if(crtno) {
-+       	   if(ivideo.vbflags & CRT2_LCD)      realcrtno = 1;
-+      	   else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
-+      	   else return;
-+   	}
-+
-+	if((sisfb_crt1off) && (!crtno)) return;
-+
-+    	temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
-+   	if((!temp) || (temp == 0xffff)) {
-+      	   printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
-+	   return;
-+   	} else {
-+      	   printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
-+      	   printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
-+	   	crtno + 1,
-+	   	(temp & 0x1a) ? "" : "[none of the supported]",
-+	   	(temp & 0x02) ? "2 " : "",
-+	   	(temp & 0x08) ? "D&P" : "",
-+           	(temp & 0x10) ? "FPDI-2" : "");
-+      	   if(temp & 0x02) {
-+	      i = 3;  /* Number of retrys */
-+	      do {
-+	    	 temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
-+				     realcrtno, 1, &buffer[0]);
-+	      } while((temp) && i--);
-+              if(!temp) {
-+	    	 if(sisfb_interpret_edid(monitor, &buffer[0])) {
-+		    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
-+		    	monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
-+			monitor->dclockmax / 1000);
-+		 } else {
-+	       	    printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
-+	    	 }
-+	      } else {
-+            	 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
-+	      }
-+	   } else {
-+	      printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
-+	   }
- 	}
--	if(!j) printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
- }
- 
--static void sisfb_search_vesamode(unsigned int vesamode)
-+static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
- {
- 	int i = 0, j = 0;
- 
- 	if(vesamode == 0) {
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- 		sisfb_mode_idx = MODE_INDEX_NONE;
- #else
--		printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
-+		if(!quiet)
-+		   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
- 		sisfb_mode_idx = DEFAULT_MODE;
--#endif		
-+#endif
- 		return;
- 	}
- 
- 	vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
- 
-+	while(sisbios_mode[i++].mode_no != 0) {
-+		if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
-+		    (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
-+		    if(sisfb_fstn) {
-+		       if(sisbios_mode[i-1].mode_no == 0x50 ||
-+		          sisbios_mode[i-1].mode_no == 0x56 ||
-+		          sisbios_mode[i-1].mode_no == 0x53) continue;
-+	            } else {
-+		       if(sisbios_mode[i-1].mode_no == 0x5a ||
-+		          sisbios_mode[i-1].mode_no == 0x5b) continue;
-+		    }
-+		    sisfb_mode_idx = i - 1;
-+		    j = 1;
-+		    break;
-+		}
-+	}
-+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
-+}
-+
-+static void sisfb_search_mode(char *name, BOOLEAN quiet)
-+{
-+	int i = 0;
-+	unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
-+	char strbuf[16], strbuf1[20];
-+	char *nameptr = name;
-+
-+	if(name == NULL) {
-+	   if(!quiet)
-+	      printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
-+	   sisfb_mode_idx = DEFAULT_MODE;
-+	   return;
-+	}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
-+	   if(!quiet)
-+	      printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
-+	   sisfb_mode_idx = DEFAULT_MODE;
-+	   return;
-+	}
-+#endif
-+	if(strlen(name) <= 19) {
-+	   strcpy(strbuf1, name);
-+	   for(i=0; i<strlen(strbuf1); i++) {
-+	      if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
-+	   }
-+
-+	   /* This does some fuzzy mode naming detection */
-+	   if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
-+	      if((rate <= 32) || (depth > 32)) {
-+	         j = rate; rate = depth; depth = j;
-+	      }
-+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-+	      nameptr = strbuf;
-+	      ivideo.refresh_rate = sisfb_parm_rate = rate;
-+	   } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
-+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
-+	      nameptr = strbuf;
-+	   } else {
-+	      xres = 0;
-+	      if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
-+	         sprintf(strbuf, "%ux%ux8", xres, yres);
-+	         nameptr = strbuf;
-+	      } else {
-+	         sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
-+	         return;
-+	      }
-+	   }
-+	}
-+
-+	i = 0; j = 0;
- 	while(sisbios_mode[i].mode_no != 0) {
--		if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
--		    (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
--			sisfb_mode_idx = i;
--			j = 1;
--			break;
-+		if(!strcmp(nameptr, sisbios_mode[i++].name)) {
-+		   if(sisfb_fstn) {
-+		      if(sisbios_mode[i-1].mode_no == 0x50 ||
-+		         sisbios_mode[i-1].mode_no == 0x56 ||
-+		         sisbios_mode[i-1].mode_no == 0x53) continue;
-+	           } else {
-+		      if(sisbios_mode[i-1].mode_no == 0x5a ||
-+		         sisbios_mode[i-1].mode_no == 0x5b) continue;
-+		   }
-+		   sisfb_mode_idx = i - 1;
-+		   j = 1;
-+		   break;
- 		}
--		i++;
- 	}
--	if(!j) printk(KERN_INFO "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
-+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
- }
- 
--static int sisfb_validate_mode(int myindex)
-+static int sisfb_validate_mode(int myindex, unsigned long vbflags)
- {
-    u16 xres, yres;
- 
-@@ -283,8 +510,8 @@ static int sisfb_validate_mode(int myind
-    }
- #endif
- 
--   switch (ivideo.disp_state & DISPTYPE_DISP2) {
--     case DISPTYPE_LCD:
-+   switch (vbflags & VB_DISPTYPE_DISP2) {
-+     case CRT2_LCD:
- 	switch (sishw_ext.ulCRT2LCDType) {
- 	case LCD_640x480:
- 		xres =  640; yres =  480;  break;
-@@ -306,24 +533,49 @@ static int sisfb_validate_mode(int myind
- 		xres = 1400; yres = 1050;  break;		
- 	case LCD_1600x1200:
- 		xres = 1600; yres = 1200;  break;
--	case LCD_320x480:				/* TW: FSTN */
-+	case LCD_320x480:				/* FSTN (old) */
- 		xres =  320; yres =  480;  break;
-+	case LCD_640x480_2:				/* FSTN (new) */
-+	case LCD_640x480_3:
-+		xres =  640; yres =  480;  break;
- 	default:
- 	        xres =    0; yres =    0;  break;
- 	}
-+	if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
-+	   	xres = 1360; yres = 1024;
-+	}
- 	if(sisbios_mode[myindex].xres > xres) {
- 	        return(-1);
- 	}
-         if(sisbios_mode[myindex].yres > yres) {
- 	        return(-1);
- 	}
--	if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
--           (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
--	   (sishw_ext.Is301BDH)) {		   /* 301B-DH */
-+	if(vbflags & (VB_LVDS | VB_30xBDH)) {
- 	   switch (sisbios_mode[myindex].xres) {
-+	   	case 320:
-+			if((sisbios_mode[myindex].yres != 200) &&
-+	           	   (sisbios_mode[myindex].yres != 240))
-+		          	return(-1);
-+			if((sisbios_mode[myindex].yres == 240) ||
-+			   (sisbios_mode[myindex].yres == 480)) {
-+			   	if(!sisfb_fstn) {
-+				   if(sisbios_mode[myindex].mode_no == 0x5a ||
-+				      sisbios_mode[myindex].mode_no == 0x5b)
-+					return(-1);
-+			        } else {
-+				   if(sisbios_mode[myindex].mode_no == 0x50 ||
-+				      sisbios_mode[myindex].mode_no == 0x56 ||
-+				      sisbios_mode[myindex].mode_no == 0x53)
-+					return(-1);
-+				}
-+			}
-+			break;
-+		case 400:
-+	       		if(sisbios_mode[myindex].yres != 300) return(-1);
-+	       		break;
- 	   	case 512:
--	       		if(sisbios_mode[myindex].yres != 512) return -1;
--			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
-+	       		if(sisbios_mode[myindex].yres != 384) return(-1);
-+			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return(-1);
- 	       		break;
- 	   	case 640:
- 		       	if((sisbios_mode[myindex].yres != 400) &&
-@@ -331,115 +583,130 @@ static int sisfb_validate_mode(int myind
- 		          	return -1;
- 	       		break;
- 	   	case 800:
--		       	if(sisbios_mode[myindex].yres != 600) return -1;
-+		       	if(sisbios_mode[myindex].yres != 600) return(-1);
- 	       		break;
- 	   	case 1024:
- 		       	if((sisbios_mode[myindex].yres != 600) &&
- 	           	   (sisbios_mode[myindex].yres != 768))
--		          	return -1;
-+		          	return(-1);
- 			if((sisbios_mode[myindex].yres == 600) &&
- 			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
--			   	return -1;
-+			   	return(-1);
- 			break;
- 		case 1152:
--			if((sisbios_mode[myindex].yres) != 768) return -1;
--			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
-+			if((sisbios_mode[myindex].yres) != 768) return(-1);
-+			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
- 			break;
- 	   	case 1280:
- 		   	if((sisbios_mode[myindex].yres != 768) &&
- 	           	   (sisbios_mode[myindex].yres != 1024))
--		          	return -1;
-+		          	return(-1);
- 			if((sisbios_mode[myindex].yres == 768) &&
- 			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
--			   	return -1;				
-+			   	return(-1);
-+			break;
-+		case 1360:
-+			if(SiS_Pr.SiS_CustomT != CUT_BARCO1366) return(-1);
-+			if(sisbios_mode[myindex].yres != 1024) return(-1);
- 			break;
- 	   	case 1400:
--		   	if(sisbios_mode[myindex].yres != 1050) return -1;
-+		   	if(sisbios_mode[myindex].yres != 1050) return(-1);
- 			break;
- 	   	case 1600:
--		   	if(sisbios_mode[myindex].yres != 1200) return -1;
-+		   	if(sisbios_mode[myindex].yres != 1200) return(-1);
- 			break;
- 	   	default:
--		        return -1;		
-+		        return(-1);
- 	   }
- 	} else {
- 	   switch (sisbios_mode[myindex].xres) {
-+	   	case 320:
-+			if((sisbios_mode[myindex].yres != 200) &&
-+	           	   (sisbios_mode[myindex].yres != 240))
-+		          	return -1;
-+			break;
-+		case 400:
-+	       		if(sisbios_mode[myindex].yres != 300) return(-1);
-+	       		break;
- 	   	case 512:
--	       		if(sisbios_mode[myindex].yres != 512) return -1;
-+	       		if(sisbios_mode[myindex].yres != 384) return(-1);
- 	       		break;
- 	   	case 640:
- 		       	if((sisbios_mode[myindex].yres != 400) &&
- 	           	   (sisbios_mode[myindex].yres != 480))
--		          	return -1;
-+		          	return(-1);
- 	       		break;
- 	   	case 800:
--		       	if(sisbios_mode[myindex].yres != 600) return -1;
-+		       	if(sisbios_mode[myindex].yres != 600) return(-1);
- 	       		break;
- 	   	case 1024:
--		       	if(sisbios_mode[myindex].yres != 768) return -1;
-+		       	if(sisbios_mode[myindex].yres != 768) return(-1);
- 			break;
- 	   	case 1280:
- 		   	if((sisbios_mode[myindex].yres != 960) &&
-+			   (sisbios_mode[myindex].yres != 768) &&
- 	           	   (sisbios_mode[myindex].yres != 1024))
--		          	return -1;
--			if(sisbios_mode[myindex].yres == 960) {
--			    if(sishw_ext.ulCRT2LCDType == LCD_1400x1050) 
--			   	return -1;
-+		          	return(-1);
-+			if((sisbios_mode[myindex].yres == 768) ||
-+			   (sisbios_mode[myindex].yres == 960)) {
-+			    	if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
-+			   		return(-1);
-+			}
-+			if(sisbios_mode[myindex].yres == 768) {
-+			    	if(sishw_ext.ulCRT2LCDType == LCD_1280x960)
-+			   		return(-1);
- 			}
- 			break;
- 	   	case 1400:
--		   	if(sisbios_mode[myindex].yres != 1050) return -1;
-+		   	if(sisbios_mode[myindex].yres != 1050) return(-1);
- 			break;
- 	   	case 1600:
--		   	if(sisbios_mode[myindex].yres != 1200) return -1;
-+		   	if(sisbios_mode[myindex].yres != 1200) return(-1);
- 			break;
- 	   	default:
--		        return -1;		
-+		        return(-1);
- 	   }
- 	}
- 	break;
--     case DISPTYPE_TV:
-+     case CRT2_TV:
- 	switch (sisbios_mode[myindex].xres) {
- 	case 512:
-+		if(vbflags & VB_CHRONTEL) return(-1);
-+		if((vbflags & VB_SISBRIDGE) && (vbflags & TV_NTSC))
-+		   	return(-1);
-+		/* fall through */
- 	case 640:
- 	case 800:
- 		break;
- 	case 720:
--		if (ivideo.TV_type == TVMODE_NTSC) {
-+		if(vbflags & VB_CHRONTEL) return -1;
-+		if(vbflags & TV_NTSC) {
- 			if (sisbios_mode[myindex].yres != 480) {
- 				return(-1);
- 			}
--		} else if (ivideo.TV_type == TVMODE_PAL) {
-+		} else if(vbflags & TV_PAL) {
- 			if (sisbios_mode[myindex].yres != 576) {
- 				return(-1);
- 			}
- 		}
--		/* TW: LVDS/CHRONTEL does not support 720 */
--		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
--					ivideo.hasVB == HASVB_CHRONTEL) {
--				return(-1);
--		}
- 		break;
- 	case 1024:
--		if (ivideo.TV_type == TVMODE_NTSC) {
--			if(sisbios_mode[myindex].bpp == 32) {
--			       return(-1);
--			}
--		}
--		/* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
--		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
--					ivideo.hasVB == HASVB_CHRONTEL) {
--		    if(ivideo.chip < SIS_315H) {
-+		if(vbflags & VB_301) return(-1);
-+		if(vbflags & VB_CHRONTEL) {
-+		    	if(ivideo.chip < SIS_315H) {
- 				return(-1);
--		    }
-+		    	}
- 		}
- 		break;
- 	default:
- 		return(-1);
- 	}
- 	break;
--     case DISPTYPE_CRT2:	
--        if(sisbios_mode[myindex].xres > 1280) return -1;
-+     case CRT2_VGA:	
-+        if(sisbios_mode[myindex].xres > 1600) return(-1);
-+	if(!(vbflags & (VB_301B|VB_302B))) {
-+	   if(sisbios_mode[myindex].xres > 1400) return(-1);
-+	}
- 	break;	
-      }
-      return(myindex);
-@@ -456,12 +723,17 @@ static void sisfb_search_crt2type(const 
- 		if (!strcmp(name, sis_crt2type[i].name)) {
- 			sisfb_crt2type = sis_crt2type[i].type_no;
- 			sisfb_tvplug = sis_crt2type[i].tvplug_no;
-+			sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
-+			sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
- 			break;
- 		}
- 		i++;
- 	}
- 	if(sisfb_crt2type < 0)
--		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
-+		printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
-+        if(ivideo.chip != SIS_550) {
-+	   sisfb_dstn = sisfb_fstn = 0;
-+	}
- }
- 
- static void sisfb_search_queuemode(const char *name)
-@@ -479,16 +751,16 @@ static void sisfb_search_queuemode(const
- 		i++;
- 	}
- 	if (sisfb_queuemode < 0)
--		printk(KERN_INFO "sisfb: Invalid queuemode type: %s\n", name);
-+		printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
- }
- 
--static u8 sisfb_search_refresh_rate(unsigned int rate)
-+static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
- {
- 	u16 xres, yres;
- 	int i = 0;
- 
--	xres = sisbios_mode[sisfb_mode_idx].xres;
--	yres = sisbios_mode[sisfb_mode_idx].yres;
-+	xres = sisbios_mode[mode_idx].xres;
-+	yres = sisbios_mode[mode_idx].yres;
- 
- 	sisfb_rate_idx = 0;
- 	while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
-@@ -537,7 +809,7 @@ static void sisfb_search_tvstd(const cha
- 
- 	while (sis_tvtype[i].type_no != -1) {
- 		if (!strcmp(name, sis_tvtype[i].name)) {
--			sisfb_tvmode = sis_tvtype[i].type_no;
-+			ivideo.vbflags |= sis_tvtype[i].type_no;
- 			break;
- 		}
- 		i++;
-@@ -546,13 +818,13 @@ static void sisfb_search_tvstd(const cha
- 
- static BOOLEAN sisfb_bridgeisslave(void)
- {
--   unsigned char usScratchP1_00;
-+   unsigned char P1_00;
- 
--   if(ivideo.hasVB == HASVB_NONE) return FALSE;
-+   if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
- 
--   inSISIDXREG(SISPART1,0x00,usScratchP1_00);
--   if( ((sisvga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
--       ((sisvga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
-+   inSISIDXREG(SISPART1,0x00,P1_00);
-+   if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
-+       ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
- 	   return TRUE;
-    } else {
-            return FALSE;
-@@ -597,7 +869,7 @@ static BOOLEAN sisfbcheckvretracecrt2(vo
- 
- static BOOLEAN sisfb_CheckVBRetrace(void) 
- {
--   if(ivideo.disp_state & DISPTYPE_DISP2) {
-+   if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
-       if(sisfb_bridgeisslave()) {
-          return(sisfbcheckvretracecrt1());
-       } else {
-@@ -607,60 +879,195 @@ static BOOLEAN sisfb_CheckVBRetrace(void
-    return(sisfbcheckvretracecrt1());
- }
- 
-+static int sisfb_myblank(int blank)
-+{
-+   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
-+   BOOLEAN backlight = TRUE;
-+
-+   switch(blank) {
-+   case 0:	/* on */
-+      sr01  = 0x00;
-+      sr11  = 0x00;
-+      sr1f  = 0x00;
-+      cr63  = 0x00;
-+      p2_0  = 0x20;
-+      p1_13 = 0x00;
-+      backlight = TRUE;
-+      break;
-+   case 1:	/* blank */
-+      sr01  = 0x20;
-+      sr11  = 0x00;
-+      sr1f  = 0x00;
-+      cr63  = 0x00;
-+      p2_0  = 0x20;
-+      p1_13 = 0x00;
-+      backlight = TRUE;
-+      break;
-+   case 2:	/* no vsync */
-+      sr01  = 0x20;
-+      sr11  = 0x08;
-+      sr1f  = 0x80;
-+      cr63  = 0x40;
-+      p2_0  = 0x40;
-+      p1_13 = 0x80;
-+      backlight = FALSE;
-+      break;
-+   case 3:	/* no hsync */
-+      sr01  = 0x20;
-+      sr11  = 0x08;
-+      sr1f  = 0x40;
-+      cr63  = 0x40;
-+      p2_0  = 0x80;
-+      p1_13 = 0x40;
-+      backlight = FALSE;
-+      break;
-+   case 4:	/* off */
-+      sr01  = 0x20;
-+      sr11  = 0x08;
-+      sr1f  = 0xc0;
-+      cr63  = 0x40;
-+      p2_0  = 0xc0;
-+      p1_13 = 0xc0;
-+      backlight = FALSE;
-+      break;
-+   default:
-+      return 1;
-+   }
-+
-+   if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
-+
-+      setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
-+
-+      if( (!sisfb_thismonitor.datavalid) ||
-+          ((sisfb_thismonitor.datavalid) &&
-+           (sisfb_thismonitor.feature & 0xe0))) {
-+
-+	 if(sisvga_engine == SIS_315_VGA) {
-+	    setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
-+	 }
-+
-+	 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
-+      }
-+
-+   }
-+
-+   if(ivideo.currentvbflags & CRT2_LCD) {
-+
-+      if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-+	 if(backlight) {
-+	    SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
-+	 } else {
-+	    SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
-+	 }
-+      } else if(sisvga_engine == SIS_315_VGA) {
-+	 if(ivideo.vbflags & VB_CHRONTEL) {
-+	    if(backlight) {
-+	       SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
-+	    } else {
-+	       SiS_Chrontel701xBLOff(&SiS_Pr);
-+	    }
-+	 }
-+      }
-+
-+      if(((sisvga_engine == SIS_300_VGA) &&
-+          (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
-+         ((sisvga_engine == SIS_315_VGA) &&
-+          ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
-+          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
-+      }
-+
-+      if(sisvga_engine == SIS_300_VGA) {
-+         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
-+            (!(ivideo.vbflags & VB_30xBDH))) {
-+	    setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
-+	 }
-+      } else if(sisvga_engine == SIS_315_VGA) {
-+         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
-+            (!(ivideo.vbflags & VB_30xBDH))) {
-+	    setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
-+	 }
-+      }
-+
-+   } else if(ivideo.currentvbflags & CRT2_VGA) {
-+
-+      if(ivideo.vbflags & (VB_301B|VB_302B)) {
-+         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
-+      }
-+
-+   }
-+
-+   return(0);
-+}
-+
- /* ----------- FBDev related routines for all series ----------- */
- 
-+static void sisfb_set_vparms(void)
-+{
-+   switch(ivideo.video_bpp) {
-+   case 8:
-+       	ivideo.DstColor = 0x0000;
-+	ivideo.SiS310_AccelDepth = 0x00000000;
-+	ivideo.video_cmap_len = 256;
-+       	break;
-+   case 16:
-+       	ivideo.DstColor = 0x8000;
-+       	ivideo.SiS310_AccelDepth = 0x00010000;
-+	ivideo.video_cmap_len = 16;
-+       	break;
-+   case 32:
-+       	ivideo.DstColor = 0xC000;
-+	ivideo.SiS310_AccelDepth = 0x00020000;
-+	ivideo.video_cmap_len = 16;
-+       	break;
-+   default:
-+ 	ivideo.video_cmap_len = 16;
-+	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
-+	ivideo.accel = 0;
-+	break;
-+   }
-+}
-+
- static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
- 		      struct fb_info *info)
- {
--	unsigned int htotal =
--		var->left_margin + var->xres + var->right_margin +
--		var->hsync_len;
--	unsigned int vtotal = 0; 
-+	unsigned int htotal = 0, vtotal = 0; 
- 	double drate = 0, hrate = 0;
- 	int found_mode = 0;
- 	int old_mode;
--	unsigned char reg;
-+	u32 pixclock;
- 
--	TWDEBUG("Inside do_set_var");
--	
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
--	inSISIDXREG(SISCR,0x34,reg);
--	if(reg & 0x80) {
--	   printk(KERN_INFO "sisfb: Cannot change display mode, X server is active\n");
--	   return -EBUSY;
--	}
--#endif	
-+	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
-+
-+	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
-+
-+	pixclock = var->pixclock;
- 
- 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
--		vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;
-+		vtotal += var->yres;
- 		vtotal <<= 1;
- 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
--		vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;
-+		vtotal += var->yres;
- 		vtotal <<= 2;
- 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
--		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
--		         var->vsync_len; 
--	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;
-+		vtotal += var->yres;
-+		vtotal <<= 1;
-+	} else 	vtotal += var->yres;
- 
- 	if(!(htotal) || !(vtotal)) {
- 		DPRINTK("sisfb: Invalid 'var' information\n");
- 		return -EINVAL;
- 	}
- 
--	if(var->pixclock && htotal && vtotal) {
--	   drate = 1E12 / var->pixclock;
-+	if(pixclock && htotal && vtotal) {
-+	   drate = 1E12 / pixclock;
- 	   hrate = drate / htotal;
- 	   ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
- 	} else ivideo.refresh_rate = 60;
- 
--	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
--	if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;
--
-+#if 0
- 	printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
- 		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
-+#endif		
- 
- 	old_mode = sisfb_mode_idx;
- 	sisfb_mode_idx = 0;
-@@ -678,7 +1085,7 @@ static int sisfb_do_set_var(struct fb_va
- 	}
- 
- 	if(found_mode)
--		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
-+		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
- 	else
- 		sisfb_mode_idx = -1;
- 
-@@ -689,12 +1096,21 @@ static int sisfb_do_set_var(struct fb_va
- 		return -EINVAL;
- 	}
- 
--	if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
-+	if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
- 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
- 		ivideo.refresh_rate = 60;
- 	}
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	if(sisfb_thismonitor.datavalid) {
-+	   if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
-+	                         sisfb_rate_idx, ivideo.refresh_rate)) {
-+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-+	   }
-+	}
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- 	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
- #else
- 	if(isactive) {
-@@ -707,15 +1123,7 @@ static int sisfb_do_set_var(struct fb_va
- 		}
- 
- 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
--
--		sisfb_post_setmode();
--
--		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",
--			sisbios_mode[sisfb_mode_idx].xres,
--			sisbios_mode[sisfb_mode_idx].yres,
--			sisbios_mode[sisfb_mode_idx].bpp,
--			ivideo.refresh_rate);
--
-+		
- 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
- 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
- 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
-@@ -725,54 +1133,39 @@ static int sisfb_do_set_var(struct fb_va
- 		if(sisfb_accel) {
- 		   ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
- 		}
--		switch(ivideo.video_bpp) {
--        	case 8:
--            		ivideo.DstColor = 0x0000;
--	    		ivideo.SiS310_AccelDepth = 0x00000000;
--			ivideo.video_cmap_len = 256;
--            		break;
--        	case 16:
--            		ivideo.DstColor = 0x8000;
--            		ivideo.SiS310_AccelDepth = 0x00010000;
--			ivideo.video_cmap_len = 16;
--            		break;
--        	case 32:
--            		ivideo.DstColor = 0xC000;
--	    		ivideo.SiS310_AccelDepth = 0x00020000;
--			ivideo.video_cmap_len = 16;
--            		break;
--		default:
--			ivideo.video_cmap_len = 16;
--		        printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
--			ivideo.accel = 0;
--			break;
--    		}
-+
-+		sisfb_set_vparms();
-+		
-+		ivideo.current_width = ivideo.video_width;
-+		ivideo.current_height = ivideo.video_height;
-+		ivideo.current_bpp = ivideo.video_bpp;
-+		ivideo.current_htotal = htotal;
-+		ivideo.current_vtotal = vtotal;
-+		ivideo.current_pixclock = var->pixclock;
-+		ivideo.current_refresh_rate = ivideo.refresh_rate;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+                sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
-+#endif
-+		
-+		sisfb_post_setmode();
- 
- 	}
--	TWDEBUG("End of do_set_var");
- 	return 0;
- }
- 
--#ifdef SISFB_PAN
- static int sisfb_pan_var(struct fb_var_screeninfo *var)
- {
- 	unsigned int base;
- 
--	TWDEBUG("Inside pan_var");
--	
- 	if (var->xoffset > (var->xres_virtual - var->xres)) {
--	        printk(KERN_INFO "Pan: xo: %d xv %d xr %d\n",
--			var->xoffset, var->xres_virtual, var->xres);
- 		return -EINVAL;
- 	}
- 	if(var->yoffset > (var->yres_virtual - var->yres)) {
--		printk(KERN_INFO "Pan: yo: %d yv %d yr %d\n",
--			var->yoffset, var->yres_virtual, var->yres);
- 		return -EINVAL;
--	}
--
--        base = var->yoffset * var->xres_virtual + var->xoffset;
--
-+	}	
-+		
-+	base = var->yoffset * var->xres_virtual + var->xoffset;
-+		
-         /* calculate base bpp dep. */
-         switch(var->bits_per_pixel) {
-         case 16:
-@@ -794,7 +1187,7 @@ static int sisfb_pan_var(struct fb_var_s
- 	if(sisvga_engine == SIS_315_VGA) {
- 		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
- 	}
--        if(ivideo.disp_state & DISPTYPE_DISP2) {
-+        if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
- 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
-         	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
-         	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
-@@ -803,10 +1196,8 @@ static int sisfb_pan_var(struct fb_var_s
- 			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
- 		}
-         }
--	TWDEBUG("End of pan_var");
- 	return 0;
- }
--#endif
- 
- static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
- {
-@@ -843,22 +1234,24 @@ static void sisfb_bpp_to_var(struct fb_v
- 
- void sis_dispinfo(struct ap_data *rec)
- {
--	rec->minfo.bpp    = ivideo.video_bpp;
--	rec->minfo.xres   = ivideo.video_width;
--	rec->minfo.yres   = ivideo.video_height;
--	rec->minfo.v_xres = ivideo.video_vwidth;
--	rec->minfo.v_yres = ivideo.video_vheight;
--	rec->minfo.org_x  = ivideo.org_x;
--	rec->minfo.org_y  = ivideo.org_y;
--	rec->minfo.vrate  = ivideo.refresh_rate;
--	rec->iobase       = ivideo.vga_base - 0x30;
--	rec->mem_size     = ivideo.video_size;
--	rec->disp_state   = ivideo.disp_state; 
--	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
--	rec->hasVB        = ivideo.hasVB; 
--	rec->TV_type      = ivideo.TV_type; 
--	rec->TV_plug      = ivideo.TV_plug; 
--	rec->chip         = ivideo.chip;
-+	rec->minfo.bpp      = ivideo.video_bpp;
-+	rec->minfo.xres     = ivideo.video_width;
-+	rec->minfo.yres     = ivideo.video_height;
-+	rec->minfo.v_xres   = ivideo.video_vwidth;
-+	rec->minfo.v_yres   = ivideo.video_vheight;
-+	rec->minfo.org_x    = ivideo.org_x;
-+	rec->minfo.org_y    = ivideo.org_y;
-+	rec->minfo.vrate    = ivideo.refresh_rate;
-+	rec->iobase         = ivideo.vga_base - 0x30;
-+	rec->mem_size       = ivideo.video_size;
-+	rec->disp_state     = ivideo.disp_state; 
-+	rec->version        = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
-+	rec->hasVB          = ivideo.hasVB;
-+	rec->TV_type        = ivideo.TV_type; 
-+	rec->TV_plug        = ivideo.TV_plug; 
-+	rec->chip           = ivideo.chip;
-+	rec->vbflags	    = ivideo.vbflags;
-+	rec->currentvbflags = ivideo.currentvbflags;
- }
- 
- /* ------------ FBDev related routines for 2.4 series ----------- */
-@@ -873,7 +1266,6 @@ static void sisfb_crtc_to_var(struct fb_
- 	int A, B, C, D, E, F, temp;
- 	double hrate, drate;
- 
--	TWDEBUG("Inside crtc_to_var");
- 	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
- 
- 	if (sr_data & SIS_INTERLACED_MODE)
-@@ -921,6 +1313,8 @@ static void sisfb_crtc_to_var(struct fb_
- 
- 	inSISIDXREG(SISCR, 0x09, cr_data3);
- 
-+	if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
-+
- 	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
- 	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
- 
-@@ -939,26 +1333,22 @@ static void sisfb_crtc_to_var(struct fb_
- 	D = B - F - C;
- 
-         var->yres = E;
--#ifndef SISFB_PAN
--	var->yres_virtual = E;
--#endif
--	/* TW: We have to report the physical dimension to the console! */
-+	var->upper_margin = D;
-+	var->lower_margin = F;
-+	var->vsync_len = C;
-+
- 	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- 		var->yres <<= 1;
--#ifndef SISFB_PAN
--		var->yres_virtual <<= 1;
--#endif
-+		var->upper_margin <<= 1;
-+		var->lower_margin <<= 1;
-+		var->vsync_len <<= 1;
- 	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- 		var->yres >>= 1;
--#ifndef SISFB_PAN
--		var->yres_virtual >>= 1;
--#endif
-+		var->upper_margin >>= 1;
-+		var->lower_margin >>= 1;
-+		var->vsync_len >>= 1;
- 	}
- 
--	var->upper_margin = D;
--	var->lower_margin = F;
--	var->vsync_len = C;
--
- 	inSISIDXREG(SISSR, 0x0b, sr_data);
- 
- 	inSISIDXREG(SISCR, 0x00, cr_data);
-@@ -999,10 +1389,20 @@ static void sisfb_crtc_to_var(struct fb_
- 	D = B - F - C;
- 
- 	var->xres = var->xres_virtual = E * 8;
--	var->left_margin = D * 8;
--	var->right_margin = F * 8;
--	var->hsync_len = C * 8;
- 
-+	if((var->xres == 320) &&
-+	   (var->yres == 200 || var->yres == 240)) {
-+		/* Terrible hack, but the correct CRTC data for
-+	  	 * these modes only produces a black screen...
-+	  	 */
-+       		var->left_margin = (400 - 376);
-+       		var->right_margin = (328 - 320);
-+       		var->hsync_len = (376 - 328);
-+	} else {
-+	   	var->left_margin = D * 8;
-+	   	var->right_margin = F * 8;
-+	   	var->hsync_len = C * 8;
-+	}
- 	var->activate = FB_ACTIVATE_NOW;
- 
- 	var->sync = 0;
-@@ -1022,21 +1422,21 @@ static void sisfb_crtc_to_var(struct fb_
- 	VT <<= 1;
- 	HT = (HT + 5) * 8;
- 
-+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-+		VT <<= 1;
-+	}
- 	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
- 	drate = hrate * HT;
- 	var->pixclock = (u32) (1E12 / drate);
- 
--#ifdef SISFB_PAN
- 	if(sisfb_ypan) {
- 	    var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
- 	    if(var->yres_virtual <= var->yres) {
- 	        var->yres_virtual = var->yres;
- 	    }
- 	} else
--#endif
--	   var->yres_virtual = var->yres;
-+	    var->yres_virtual = var->yres;
- 
--        TWDEBUG("end of crtc_to_var");
- }
- 
- static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-@@ -1069,7 +1469,7 @@ static int sisfb_setcolreg(unsigned regn
- 		outSISREG(SISDACD, (red >> 10));
- 		outSISREG(SISDACD, (green >> 10));
- 		outSISREG(SISDACD, (blue >> 10));
--		if (ivideo.disp_state & DISPTYPE_DISP2) {
-+		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
- 		        outSISREG(SISDAC2A, regno);
- 			outSISREG(SISDAC2D, (red >> 8));
- 			outSISREG(SISDAC2D, (green >> 8));
-@@ -1118,7 +1518,7 @@ static void sisfb_set_disp(int con, stru
- 	display->ywrapstep = fix.ywrapstep;
- 	display->line_length = fix.line_length;
- 	display->next_line = fix.line_length;
--	display->can_soft_blank = 0;
-+	display->can_soft_blank = 1;
- 	display->inverse = sisfb_inverse;
- 	display->var = *var;
- 
-@@ -1162,17 +1562,12 @@ static void sisfb_set_disp(int con, stru
- 	display->dispsw = &sisfb_sw;
- 	restore_flags(flags);
- 
--#ifdef SISFB_PAN
--        if((ivideo.accel) && (sisfb_ypan)) {
--  	    /* display->scrollmode = SCROLL_YPAN; - not defined */
-+        if(sisfb_ypan) {
-+  	    /* display->scrollmode = 0;  */
- 	} else {
- 	    display->scrollmode = SCROLL_YREDRAW;
- 	    sisfb_sw.bmove = fbcon_redraw_bmove;
- 	}
--#else
--	display->scrollmode = SCROLL_YREDRAW;
--	sisfb_sw.bmove = fbcon_redraw_bmove;
--#endif
- }
- 
- static void sisfb_do_install_cmap(int con, struct fb_info *info)
-@@ -1191,17 +1586,16 @@ static void sisfb_do_install_cmap(int co
- static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
- 			 struct fb_info *info)
- {
--	TWDEBUG("inside get_var");
- 	if(con == -1)
- 		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
- 	else
- 		*var = fb_display[con].var;
- 
-- 	/* For FSTN, DSTN */
--	if (var->xres == 320 && var->yres == 480)
-+	if(sisfb_fstn) {
-+	   if (var->xres == 320 && var->yres == 480)
- 		var->yres = 240;
--		
--	TWDEBUG("end of get_var");
-+        }
-+
- 	return 0;
- }
- 
-@@ -1211,8 +1605,6 @@ static int sisfb_set_var(struct fb_var_s
- 	int err;
- 	unsigned int cols, rows;
- 
--	TWDEBUG("inside set_var");
--
- 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-         if(sisfb_do_set_var(var, con == currcon, info)) {
- 		sisfb_crtc_to_var(var);
-@@ -1233,16 +1625,17 @@ static int sisfb_set_var(struct fb_var_s
- 
- 	cols = sisbios_mode[sisfb_mode_idx].cols;
- 	rows = sisbios_mode[sisfb_mode_idx].rows;
--	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-+#if 0
-+	/* Why was this called here? */
-+ 	vc_resize_con(rows, cols, fb_display[con].conp->vc_num); 
-+#endif	
- 
--	TWDEBUG("end of set_var");
- 	return 0;
- }
- 
- static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- 			  struct fb_info *info)
- {
--	TWDEBUG("inside get_cmap");
-         if (con == currcon)
- 		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
- 
-@@ -1251,7 +1644,6 @@ static int sisfb_get_cmap(struct fb_cmap
- 	else
- 		fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
- 
--	TWDEBUG("end of get_cmap");
- 	return 0;
- }
- 
-@@ -1260,7 +1652,6 @@ static int sisfb_set_cmap(struct fb_cmap
- {
- 	int err;
- 
--	TWDEBUG("inside set_cmap");
- 	if (!fb_display[con].cmap.len) {
- 		err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
- 		if (err)
-@@ -1272,17 +1663,15 @@ static int sisfb_set_cmap(struct fb_cmap
- 
- 	else
- 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
--	TWDEBUG("end of set_cmap");
-+
- 	return 0;
- }
- 
--#ifdef SISFB_PAN
- static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
- 			     struct fb_info* info)
- {
- 	int err;
--	
--	TWDEBUG("inside pan_display");
-+
- 	if (var->vmode & FB_VMODE_YWRAP) {
- 		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
- 			return -EINVAL;
-@@ -1303,10 +1692,8 @@ static int sisfb_pan_display(struct fb_v
- 	else
- 		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
- 
--	TWDEBUG("end of pan_display");
- 	return 0;
- }
--#endif
- 
- static int sisfb_mmap(struct fb_info *info, struct file *file,
- 		      struct vm_area_struct *vma)
-@@ -1316,7 +1703,6 @@ static int sisfb_mmap(struct fb_info *in
- 	unsigned long off;
- 	u32 len, mmio_off;
- 
--	TWDEBUG("inside mmap");
- 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
- 
- 	off = vma->vm_pgoff << PAGE_SHIFT;
-@@ -1355,7 +1741,6 @@ static int sisfb_mmap(struct fb_info *in
- 				vma->vm_page_prot))
- 		return -EAGAIN;
- 
--        TWDEBUG("end of mmap");
- 	return 0;
- }
- 
-@@ -1368,7 +1753,6 @@ static void sis_get_glyph(struct fb_info
- 	u8 *gbuf = gly->gmask;
- 	int size;
- 
--	TWDEBUG("Inside get_glyph");
- 	gly->fontheight = fontheight(p);
- 	gly->fontwidth = fontwidth(p);
- 	widthb = (fontwidth(p) + 7) / 8;
-@@ -1382,16 +1766,11 @@ static void sis_get_glyph(struct fb_info
- 	size = fontheight(p) * widthb;
- 	memcpy(gbuf, cdat, size);
- 	gly->ngmask = size;
--	TWDEBUG("End of get_glyph");
- }
- 
- static int sisfb_update_var(int con, struct fb_info *info)
- {
--#ifdef SISFB_PAN
-         return(sisfb_pan_var(&fb_display[con].var));
--#else
--	return 0;
--#endif	
- }
- 
- static int sisfb_switch(int con, struct fb_info *info)
-@@ -1428,157 +1807,37 @@ static int sisfb_switch(int con, struct 
- 
- static void sisfb_blank(int blank, struct fb_info *info)
- {
--	u8 reg;
-+	sisfb_myblank(blank);
-+}
-+#endif
- 
--	inSISIDXREG(SISCR, 0x17, reg);
-+/* ------------ FBDev related routines for 2.5 series ----------- */
- 
--	if(blank > 0)
--		reg &= 0x7f;
--	else
--		reg |= 0x80;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- 
--        outSISIDXREG(SISCR, 0x17, reg);		
--	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
--	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
--	printk(KERN_DEBUG "sisfb_blank() called (%d)\n", blank);
-+static int sisfb_open(struct fb_info *info, int user)
-+{
-+    return 0;
- }
- 
-+static int sisfb_release(struct fb_info *info, int user)
-+{
-+    return 0;
-+}
- 
--static int sisfb_ioctl(struct inode *inode, struct file *file,
--		       unsigned int cmd, unsigned long arg, int con,
--		       struct fb_info *info)
-+static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
- {
--	TWDEBUG("inside ioctl");
--	switch (cmd) {
--	   case FBIO_ALLOC:
--		if (!capable(CAP_SYS_RAWIO))
--			return -EPERM;
--		sis_malloc((struct sis_memreq *) arg);
--		break;
--	   case FBIO_FREE:
--		if (!capable(CAP_SYS_RAWIO))
--			return -EPERM;
--		sis_free(*(unsigned long *) arg);
-+	int rc = 16;		
-+
-+	switch(var->bits_per_pixel) {
-+	case 8:
-+		rc = 256;	
- 		break;
--	   case FBIOGET_GLYPH:
--                sis_get_glyph(info,(SIS_GLYINFO *) arg);
--		break;	
--	   case FBIOGET_HWCINFO:
--		{
--			unsigned long *hwc_offset = (unsigned long *) arg;
--
--			if (sisfb_caps & HW_CURSOR_CAP)
--				*hwc_offset = sisfb_hwcursor_vbase -
--				    (unsigned long) ivideo.video_vbase;
--			else
--				*hwc_offset = 0;
--
--			break;
--		}
--	   case FBIOPUT_MODEINFO:
--		{
--			struct mode_info *x = (struct mode_info *)arg;
--
--			ivideo.video_bpp        = x->bpp;
--			ivideo.video_width      = x->xres;
--			ivideo.video_height     = x->yres;
--			ivideo.video_vwidth     = x->v_xres;
--			ivideo.video_vheight    = x->v_yres;
--			ivideo.org_x            = x->org_x;
--			ivideo.org_y            = x->org_y;
--			ivideo.refresh_rate     = x->vrate;
--			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
--			switch(ivideo.video_bpp) {
--        		case 8:
--            			ivideo.DstColor = 0x0000;
--	    			ivideo.SiS310_AccelDepth = 0x00000000;
--				ivideo.video_cmap_len = 256;
--            			break;
--        		case 16:
--            			ivideo.DstColor = 0x8000;
--            			ivideo.SiS310_AccelDepth = 0x00010000;
--				ivideo.video_cmap_len = 16;
--            			break;
--        		case 32:
--            			ivideo.DstColor = 0xC000;
--	    			ivideo.SiS310_AccelDepth = 0x00020000;
--				ivideo.video_cmap_len = 16;
--            			break;
--			default:
--				ivideo.video_cmap_len = 16;
--		       	 	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
--				ivideo.accel = 0;
--				break;
--    			}
--
--			break;
--		}
--	   case FBIOGET_DISPINFO:
--		sis_dispinfo((struct ap_data *)arg);
--		break;
--	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
--	        {
--			sisfb_info *x = (sisfb_info *)arg;
--
--			x->sisfb_id = SISFB_ID;
--			x->sisfb_version = VER_MAJOR;
--			x->sisfb_revision = VER_MINOR;
--			x->sisfb_patchlevel = VER_LEVEL;
--			x->chip_id = ivideo.chip_id;
--			x->memory = ivideo.video_size / 1024;
--			x->heapstart = ivideo.heapstart / 1024;
--			x->fbvidmode = sisfb_mode_no;
--			x->sisfb_caps = sisfb_caps;
--			x->sisfb_tqlen = 512; /* yet unused */
--			x->sisfb_pcibus = ivideo.pcibus;
--			x->sisfb_pcislot = ivideo.pcislot;
--			x->sisfb_pcifunc = ivideo.pcifunc;
--			x->sisfb_lcdpdc = sisfb_detectedpdc;
--			x->sisfb_lcda = sisfb_detectedlcda;
--	                break;
--		}
--	   case SISFB_GET_VBRSTATUS:
--	        {
--			unsigned long *vbrstatus = (unsigned long *) arg;
--			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
--			else		           *vbrstatus = 0;
--		}
--	   default:
--		return -EINVAL;
--	}
--	TWDEBUG("end of ioctl");
--	return 0;
--
--}
--#endif
--
--/* ------------ FBDev related routines for 2.5 series ----------- */
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
--
--static int sisfb_open(struct fb_info *info, int user)
--{
--    return 0;
--}
--
--static int sisfb_release(struct fb_info *info, int user)
--{
--    return 0;
--}
--
--static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
--{
--	int rc = 16;		
--
--	switch(var->bits_per_pixel) {
--	case 8:
--		rc = 256;	
--		break;
--	case 16:
--		rc = 16;	
--		break;		
--	case 32:
--		rc = 16;
-+	case 16:
-+		rc = 16;	
-+		break;		
-+	case 32:
-+		rc = 16;
- 		break;	
- 	}
- 	return rc;
-@@ -1596,7 +1855,7 @@ static int sisfb_setcolreg(unsigned regn
- 		outSISREG(SISDACD, (red >> 10));
- 		outSISREG(SISDACD, (green >> 10));
- 		outSISREG(SISDACD, (blue >> 10));
--		if (ivideo.disp_state & DISPTYPE_DISP2) {
-+		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
- 		        outSISREG(SISDAC2A, regno);
- 			outSISREG(SISDAC2D, (red >> 8));
- 			outSISREG(SISDAC2D, (green >> 8));
-@@ -1622,63 +1881,52 @@ static int sisfb_set_par(struct fb_info 
- {
- 	int err;
- 
--	TWDEBUG("inside set_par");
-         if((err = sisfb_do_set_var(&info->var, 1, info)))
- 		return err;
- 
- 	sisfb_get_fix(&info->fix, info->currcon, info);
- 
--	TWDEBUG("end of set_par");
- 	return 0;
- }
- 
- static int sisfb_check_var(struct fb_var_screeninfo *var,
-                            struct fb_info *info)
- {
--	unsigned int htotal =
--		var->left_margin + var->xres + var->right_margin +
--		var->hsync_len;
--	unsigned int vtotal = 0;
-+	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
- 	double drate = 0, hrate = 0;
- 	int found_mode = 0;
- 	int refresh_rate, search_idx;
-+	BOOLEAN recalc_clock = FALSE;
-+	u32 pixclock;
-+
-+	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
- 
--	TWDEBUG("Inside check_var");
-+	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
-+
-+	pixclock = var->pixclock;
- 
- 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
--		vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;   
-+		vtotal += var->yres;
- 		vtotal <<= 1;
- 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
--		vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;   
-+		vtotal += var->yres;
- 		vtotal <<= 2;
- 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
--		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
--		         var->vsync_len;   
--	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
--		         var->vsync_len;
-+		vtotal += var->yres;
-+		vtotal <<= 1;
-+	} else 	vtotal += var->yres;
- 
- 	if(!(htotal) || !(vtotal)) {
- 		SISFAIL("sisfb: no valid timing data");
- 	}
- 
--	if((var->pixclock) && (htotal)) {
--	   drate = 1E12 / var->pixclock;
--	   hrate = drate / htotal;
--	   refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
--	} else refresh_rate = 60;
--
--	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
--	if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
--
- 	search_idx = 0;
- 	while( (sisbios_mode[search_idx].mode_no != 0) &&
- 	       (sisbios_mode[search_idx].xres <= var->xres) ) {
- 		if( (sisbios_mode[search_idx].xres == var->xres) &&
- 		    (sisbios_mode[search_idx].yres == var->yres) &&
- 		    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
--		        if(sisfb_validate_mode(search_idx) > 0) {
-+		        if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
- 			   found_mode = 1;
- 			   break;
- 			}
-@@ -1687,38 +1935,95 @@ static int sisfb_check_var(struct fb_var
- 	}
- 
- 	if(!found_mode) {
--	
--		printk(KERN_ERR "sisfb: %dx%dx%d is no valid mode\n", 
--			var->xres, var->yres, var->bits_per_pixel);
--			
-+
-                 search_idx = 0;
- 		while(sisbios_mode[search_idx].mode_no != 0) {
--		       
- 		   if( (var->xres <= sisbios_mode[search_idx].xres) &&
--		       (var->yres <= sisbios_mode[search_idx].yres) && 
-+		       (var->yres <= sisbios_mode[search_idx].yres) &&
- 		       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
--		          if(sisfb_validate_mode(search_idx) > 0) {
-+		          if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
- 			     found_mode = 1;
- 			     break;
- 			  }
- 		   }
- 		   search_idx++;
--	        }			
-+	        }
- 		if(found_mode) {
-+			printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
-+		   		var->xres, var->yres, var->bits_per_pixel,
-+				sisbios_mode[search_idx].xres,
-+				sisbios_mode[search_idx].yres,
-+				var->bits_per_pixel);
- 			var->xres = sisbios_mode[search_idx].xres;
- 		      	var->yres = sisbios_mode[search_idx].yres;
--		      	printk(KERN_DEBUG "sisfb: Adapted to mode %dx%dx%d\n",
--		   		var->xres, var->yres, var->bits_per_pixel);
--		   
-+
-+
- 		} else {
--		   	printk(KERN_ERR "sisfb: Failed to find similar mode to %dx%dx%d\n", 
-+		   	printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
- 				var->xres, var->yres, var->bits_per_pixel);
- 		   	return -EINVAL;
- 		}
- 	}
- 
--	/* TW: TODO: Check the refresh rate */		
--	
-+	if( ((ivideo.vbflags & VB_LVDS) ||			/* Slave modes on LVDS and 301B-DH */
-+	     ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
-+	    (var->bits_per_pixel == 8) ) {
-+	    	refresh_rate = 60;
-+		recalc_clock = TRUE;
-+	} else if( (ivideo.current_htotal == htotal) &&		/* x=x & y=y & c=c -> assume depth change */
-+	    	   (ivideo.current_vtotal == vtotal) &&
-+	    	   (ivideo.current_pixclock == pixclock) ) {
-+		drate = 1E12 / pixclock;
-+	   	hrate = drate / htotal;
-+	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
-+	} else if( ( (ivideo.current_htotal != htotal) ||	/* x!=x | y!=y & c=c -> invalid pixclock */
-+	    	     (ivideo.current_vtotal != vtotal) ) &&
-+	    	   (ivideo.current_pixclock == var->pixclock) ) {
-+		if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
-+			refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
-+		} else if(sisfb_parm_rate != -1) {
-+			refresh_rate = sisfb_parm_rate;
-+		} else {
-+			refresh_rate = 60;
-+		}
-+		recalc_clock = TRUE;
-+	} else if((pixclock) && (htotal) && (vtotal)) {
-+	   	drate = 1E12 / pixclock;
-+	   	hrate = drate / htotal;
-+	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
-+	} else if(ivideo.current_refresh_rate) {
-+		refresh_rate = ivideo.current_refresh_rate;
-+		recalc_clock = TRUE;
-+	} else {
-+		refresh_rate = 60;
-+		recalc_clock = TRUE;
-+	}
-+
-+	myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
-+
-+	/* Eventually recalculate timing and clock */
-+	if(recalc_clock) {
-+	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
-+	   var->pixclock = (u32) (1E12 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
-+						sisbios_mode[search_idx].mode_no, myrateindex));
-+	   sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
-+		 			sisbios_mode[search_idx].mode_no, myrateindex,
-+		 			&var->left_margin, &var->right_margin,
-+		 			&var->upper_margin, &var->lower_margin,
-+		 			&var->hsync_len, &var->vsync_len,
-+		 			&var->sync, &var->vmode);
-+	   if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-+		var->pixclock <<= 1;
-+	   }
-+	}
-+
-+	if(sisfb_thismonitor.datavalid) {
-+	   if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
-+	                         myrateindex, refresh_rate)) {
-+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-+	   }
-+	}
-+
- 	/* Adapt RGB settings */
- 	sisfb_bpp_to_var(var);	
- 	
-@@ -1731,18 +2036,20 @@ static int sisfb_check_var(struct fb_var
- 	/* Horiz-panning not supported */
- 	if(var->xres != var->xres_virtual)
- 		var->xres_virtual = var->xres;
--
--	if(!sisfb_ypan) {
--		if(var->yres != var->yres_virtual)
--			var->yres_virtual = var->yres;
--	} else {
-+	
-+	if(sisfb_ypan) {
- 	   /* TW: Now patch yres_virtual if we use panning */
- 	   /* *** May I do this? *** */
- 	   var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
--	    if(var->yres_virtual <= var->yres) {
-+	   if(var->yres_virtual <= var->yres) {
- 	    	/* TW: Paranoia check */
- 	        var->yres_virtual = var->yres;
--	    }
-+	   }
-+	} else {
-+	   if(var->yres != var->yres_virtual)
-+		var->yres_virtual = var->yres;
-+	   var->xoffset = 0;
-+	   var->yoffset = 0;
- 	}
- 	
- 	/* Truncate offsets to maximum if too high */
-@@ -1757,28 +2064,25 @@ static int sisfb_check_var(struct fb_var
- 	    var->green.msb_right =
- 	    var->blue.msb_right =
- 	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;		
--		
--	TWDEBUG("end of check_var");
-+
- 	return 0;
- }
- 
--#ifdef SISFB_PAN
- static int sisfb_pan_display(struct fb_var_screeninfo *var,
- 			     struct fb_info* info)
- {
- 	int err;
--	
--	TWDEBUG("inside pan_display");
--	
-+
- 	if (var->xoffset > (var->xres_virtual - var->xres))
- 		return -EINVAL;
- 	if (var->yoffset > (var->yres_virtual - var->yres))
- 		return -EINVAL;
- 
- 	if (var->vmode & FB_VMODE_YWRAP) {
--		if (var->yoffset < 0
--		    || var->yoffset >= info->var.yres_virtual
--		    || var->xoffset) return -EINVAL;
-+		if (var->yoffset < 0 ||
-+		    var->yoffset >= info->var.yres_virtual ||
-+		    var->xoffset)
-+		    	return -EINVAL;
- 	} else {
- 		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
- 		    var->yoffset + info->var.yres > info->var.yres_virtual)
-@@ -1794,10 +2098,8 @@ static int sisfb_pan_display(struct fb_v
- 	else
- 		info->var.vmode &= ~FB_VMODE_YWRAP;
- 
--	TWDEBUG("end of pan_display");
- 	return 0;
- }
--#endif
- 
- static int sisfb_mmap(struct fb_info *info, struct file *file,
- 		      struct vm_area_struct *vma)
-@@ -1806,7 +2108,6 @@ static int sisfb_mmap(struct fb_info *in
- 	unsigned long off;
- 	u32 len, mmio_off;
- 
--	TWDEBUG("inside mmap");
- 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
- 
- 	off = vma->vm_pgoff << PAGE_SHIFT;
-@@ -1844,139 +2145,141 @@ static int sisfb_mmap(struct fb_info *in
- 				vma->vm_page_prot))
- 		return -EAGAIN;
- 
--        TWDEBUG("end of mmap");
- 	return 0;
- }
- 
- static int sisfb_blank(int blank, struct fb_info *info)
- {
--	u8 reg;
-+	return(sisfb_myblank(blank));
-+}
- 
--	inSISIDXREG(SISCR, 0x17, reg);
-+#endif
- 
--	if(blank > 0)
--		reg &= 0x7f;
--	else
--		reg |= 0x80;
-+/* ----------- FBDev related routines for all series ---------- */
- 
--        outSISIDXREG(SISCR, 0x17, reg);		
--	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
--	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
--        return(0);
--}
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- static int sisfb_ioctl(struct inode *inode, struct file *file,
--		       unsigned int cmd, unsigned long arg, 
-+		       unsigned int cmd, unsigned long arg,
- 		       struct fb_info *info)
-+#else
-+static int sisfb_ioctl(struct inode *inode, struct file *file,
-+		       unsigned int cmd, unsigned long arg, int con,
-+		       struct fb_info *info)
-+#endif
- {
--	TWDEBUG("inside ioctl");
-+	struct sis_memreq sismemreq;
-+	struct ap_data sisapdata;
-+	unsigned long sismembase = 0;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	SIS_GLYINFO sisglyinfo;
-+#endif
-+
- 	switch (cmd) {
- 	   case FBIO_ALLOC:
--		if (!capable(CAP_SYS_RAWIO))
-+		if(!capable(CAP_SYS_RAWIO))
- 			return -EPERM;
--		sis_malloc((struct sis_memreq *) arg);
-+		if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
-+		   	return -EFAULT;
-+        	sis_malloc(&sismemreq);
-+		if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
-+			sis_free(sismemreq.offset);
-+		    	return -EFAULT;
-+		}
- 		break;
- 	   case FBIO_FREE:
--		if (!capable(CAP_SYS_RAWIO))
-+		if(!capable(CAP_SYS_RAWIO))
- 			return -EPERM;
--		sis_free(*(unsigned long *) arg);
-+		if(get_user(sismembase, (unsigned long *) arg))
-+			return -EFAULT;
-+		sis_free(sismembase);
- 		break;
--	   case FBIOGET_HWCINFO:
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	   case FBIOGET_GLYPH:
-+	        if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
-+			return -EFAULT;
-+                sis_get_glyph(info, &sisglyinfo);
-+		break;
-+	   case FBIOPUT_MODEINFO:
- 		{
--			unsigned long *hwc_offset = (unsigned long *) arg;
-+			struct mode_info x;
- 
--			if (sisfb_caps & HW_CURSOR_CAP)
--				*hwc_offset = sisfb_hwcursor_vbase -
--				    (unsigned long) ivideo.video_vbase;
--			else
--				*hwc_offset = 0;
-+			if(copy_from_user(&x, (void *)arg, sizeof(x)))
-+				return -EFAULT;
- 
-+			ivideo.video_bpp        = x.bpp;
-+			ivideo.video_width      = x.xres;
-+			ivideo.video_height     = x.yres;
-+			ivideo.video_vwidth     = x.v_xres;
-+			ivideo.video_vheight    = x.v_yres;
-+			ivideo.org_x            = x.org_x;
-+			ivideo.org_y            = x.org_y;
-+			ivideo.refresh_rate     = x.vrate;
-+			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
-+			sisfb_set_vparms();
- 			break;
- 		}
--	   case FBIOPUT_MODEINFO:
-+#endif
-+	   case FBIOGET_HWCINFO:
- 		{
--			struct mode_info *x = (struct mode_info *)arg;
-+			unsigned long myhwcoffset = 0;
- 
--			ivideo.video_bpp        = x->bpp;
--			ivideo.video_width      = x->xres;
--			ivideo.video_height     = x->yres;
--			ivideo.video_vwidth     = x->v_xres;
--			ivideo.video_vheight    = x->v_yres;
--			ivideo.org_x            = x->org_x;
--			ivideo.org_y            = x->org_y;
--			ivideo.refresh_rate     = x->vrate;
--			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
--			switch(ivideo.video_bpp) {
--        		case 8:
--            			ivideo.DstColor = 0x0000;
--	    			ivideo.SiS310_AccelDepth = 0x00000000;
--				ivideo.video_cmap_len = 256;
--            			break;
--        		case 16:
--            			ivideo.DstColor = 0x8000;
--            			ivideo.SiS310_AccelDepth = 0x00010000;
--				ivideo.video_cmap_len = 16;
--            			break;
--        		case 32:
--            			ivideo.DstColor = 0xC000;
--	    			ivideo.SiS310_AccelDepth = 0x00020000;
--				ivideo.video_cmap_len = 16;
--            			break;
--			default:
--				ivideo.video_cmap_len = 16;
--		       	 	printk(KERN_ERR "sisfb: Unsupported accel depth %d", ivideo.video_bpp);
--				ivideo.accel = 0;
--				break;
--    			}
-+			if(sisfb_caps & HW_CURSOR_CAP)
-+				myhwcoffset = sisfb_hwcursor_vbase -
-+				    (unsigned long) ivideo.video_vbase;
-+
-+			return put_user(myhwcoffset, (unsigned long *)arg);
- 
- 			break;
- 		}
- 	   case FBIOGET_DISPINFO:
--		sis_dispinfo((struct ap_data *)arg);
-+	   	sis_dispinfo(&sisapdata);
-+		if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
-+			return -EFAULT;
- 		break;
--	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
-+	   case SISFB_GET_INFO:  /* New for communication with X driver */
- 	        {
--			sisfb_info *x = (sisfb_info *)arg;
-+			sisfb_info x;
- 
--			x->sisfb_id = SISFB_ID;
--			x->sisfb_version = VER_MAJOR;
--			x->sisfb_revision = VER_MINOR;
--			x->sisfb_patchlevel = VER_LEVEL;
--			x->chip_id = ivideo.chip_id;
--			x->memory = ivideo.video_size / 1024;
--			x->heapstart = ivideo.heapstart / 1024;
--			x->fbvidmode = sisfb_mode_no;
--			x->sisfb_caps = sisfb_caps;
--			x->sisfb_tqlen = 512; /* yet unused */
--			x->sisfb_pcibus = ivideo.pcibus;
--			x->sisfb_pcislot = ivideo.pcislot;
--			x->sisfb_pcifunc = ivideo.pcifunc;
--			x->sisfb_lcdpdc = sisfb_detectedpdc;
--			x->sisfb_lcda = sisfb_detectedlcda;
-+			x.sisfb_id = SISFB_ID;
-+			x.sisfb_version = VER_MAJOR;
-+			x.sisfb_revision = VER_MINOR;
-+			x.sisfb_patchlevel = VER_LEVEL;
-+			x.chip_id = ivideo.chip_id;
-+			x.memory = ivideo.video_size / 1024;
-+			x.heapstart = ivideo.heapstart / 1024;
-+			x.fbvidmode = sisfb_mode_no;
-+			x.sisfb_caps = sisfb_caps;
-+			x.sisfb_tqlen = 512; /* yet unused */
-+			x.sisfb_pcibus = ivideo.pcibus;
-+			x.sisfb_pcislot = ivideo.pcislot;
-+			x.sisfb_pcifunc = ivideo.pcifunc;
-+			x.sisfb_lcdpdc = sisfb_detectedpdc;
-+			x.sisfb_lcda = sisfb_detectedlcda;
-+			x.sisfb_vbflags = ivideo.vbflags;
-+			x.sisfb_currentvbflags = ivideo.currentvbflags;
-+			if(copy_to_user((void *)arg, &x, sizeof(x)))
-+				return -EFAULT;
- 	                break;
- 		}
- 	   case SISFB_GET_VBRSTATUS:
- 	        {
--			unsigned long *vbrstatus = (unsigned long *) arg;
--			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
--			else		           *vbrstatus = 0;
-+			if(sisfb_CheckVBRetrace())
-+				return put_user(1UL, (unsigned long *) arg);
-+			else
-+				return put_user(0UL, (unsigned long *) arg);
-+			break;
- 		}
- 	   default:
- 		return -EINVAL;
- 	}
--	TWDEBUG("end of ioctl");
- 	return 0;
--
- }
- 
--#endif
--
--/* ----------- FBDev related routines for all series ---------- */
- 
- static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- 			 struct fb_info *info)
- {
--	TWDEBUG("inside get_fix");
- 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-@@ -1987,45 +2290,47 @@ static int sisfb_get_fix(struct fb_fix_s
- 
- 	fix->smem_start = ivideo.video_base;
- 
--        /* TW */
-         if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
--	    if (ivideo.video_size > 0x1000000) {
--	        fix->smem_len = 0xc00000;
--	    } else if (ivideo.video_size > 0x800000)
--		fix->smem_len = 0x800000;
--	    else
--		fix->smem_len = 0x400000;
-+	    if(sisvga_engine == SIS_300_VGA) {
-+	       if(ivideo.video_size > 0x1000000) {
-+	          	fix->smem_len = 0xc00000;
-+	       } else if(ivideo.video_size > 0x800000)
-+		  	fix->smem_len = 0x800000;
-+	       else
-+		  	fix->smem_len = 0x400000;
-+            } else {
-+	       	fix->smem_len = ivideo.video_size - 0x100000;
-+	    }
-         } else
- 		fix->smem_len = sisfb_mem * 1024;
- 
--	fix->type        = video_type;
-+	fix->type        = FB_TYPE_PACKED_PIXELS;
- 	fix->type_aux    = 0;
- 	if(ivideo.video_bpp == 8)
- 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
- 	else
- 		fix->visual = FB_VISUAL_TRUECOLOR;
- 	fix->xpanstep    = 0;
--#ifdef SISFB_PAN
-+
-         if(sisfb_ypan) 	 fix->ypanstep = 1;
--#endif
-+
- 	fix->ywrapstep   = 0;
- 	fix->line_length = ivideo.video_linelength;
- 	fix->mmio_start  = ivideo.mmio_base;
- 	fix->mmio_len    = sisfb_mmio_size;
- 	if(sisvga_engine == SIS_300_VGA) 
- 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
--	else if(ivideo.chip == SIS_330)
-+	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660))
- 	   fix->accel    = FB_ACCEL_SIS_XABRE;
--	else 
-+	else
- 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
--	
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- 	fix->reserved[0] = ivideo.video_size & 0xFFFF;
- 	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
- 	fix->reserved[2] = sisfb_caps;
--#endif	
-+#endif
- 
--	TWDEBUG("end of get_fix");
- 	return 0;
- }
- 
-@@ -2033,17 +2338,15 @@ static int sisfb_get_fix(struct fb_fix_s
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- static struct fb_ops sisfb_ops = {
--	owner:		THIS_MODULE,
--	fb_get_fix:	sisfb_get_fix,
--	fb_get_var:	sisfb_get_var,
--	fb_set_var:	sisfb_set_var,
--	fb_get_cmap:	sisfb_get_cmap,
--	fb_set_cmap:	sisfb_set_cmap,
--#ifdef SISFB_PAN
--        fb_pan_display:	sisfb_pan_display,
--#endif
--	fb_ioctl:	sisfb_ioctl,
--	fb_mmap:	sisfb_mmap,
-+	.owner		= THIS_MODULE,
-+	.fb_get_fix	= sisfb_get_fix,
-+	.fb_get_var	= sisfb_get_var,
-+	.fb_set_var	= sisfb_set_var,
-+	.fb_get_cmap	= sisfb_get_cmap,
-+	.fb_set_cmap	= sisfb_set_cmap,
-+        .fb_pan_display = sisfb_pan_display,
-+	.fb_ioctl	= sisfb_ioctl,
-+	.fb_mmap	= sisfb_mmap,
- };
- #endif
- 
-@@ -2056,9 +2359,7 @@ static struct fb_ops sisfb_ops = {
- 	.fb_check_var = sisfb_check_var,
- 	.fb_set_par   = sisfb_set_par,
- 	.fb_setcolreg = sisfb_setcolreg,
--#ifdef SISFB_PAN
-         .fb_pan_display = sisfb_pan_display,
--#endif	
-         .fb_blank     = sisfb_blank,
- 	.fb_fillrect  = fbcon_sis_fillrect,
- 	.fb_copyarea  = fbcon_sis_copyarea,
-@@ -2106,12 +2407,12 @@ static int sisfb_get_dram_size_300(void)
- 	} else {		/* 540, 630, 730 */
- 
- 		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
--		if (pdev) {
-+		if (pdev) { 
- 			pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
- 			pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
- 			ivideo.video_size = (unsigned int)(1 << (pci_data+21));
- 			pdev_valid = 1;
--
-+	
- 			reg = SIS_DATA_BUS_64 << 6;
- 			switch (pci_data) {
- 			   case BRI_DRAM_SIZE_2MB:
-@@ -2134,174 +2435,13 @@ static int sisfb_get_dram_size_300(void)
- 				break;
- 			}
- 			outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
--		}
-+		}   
- 	
- 		if (!pdev_valid)  return -1;
- 	}
- 	return 0;
- }
- 
--static void sisfb_detect_VB_connect_300()
--{
--	u8 sr16, sr17, cr32, temp;
--
--	ivideo.TV_plug = ivideo.TV_type = 0;
--
--        switch(ivideo.hasVB) {
--	  case HASVB_LVDS_CHRONTEL:
--	  case HASVB_CHRONTEL:
--	     SiS_SenseCh();
--	     break;
--	  case HASVB_301:
--	  case HASVB_302:
--	     SiS_Sense30x();
--	     break;
--	}
--
--	inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
--        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
--
--	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
--
--		if ((sr17 & 0x01) && !sisfb_crt1off)
--			sisfb_crt1off = 0;
--		else {
--			if (sr17 & 0x0E)
--				sisfb_crt1off = 1;
--			else
--				sisfb_crt1off = 0;
--		}
--
--		if (sisfb_crt2type != -1)
--			/* TW: override detected CRT2 type */
--			ivideo.disp_state = sisfb_crt2type;
--                else if (sr17 & 0x04)
--			ivideo.disp_state = DISPTYPE_TV;			
--		else if (sr17 & 0x02)
--			ivideo.disp_state = DISPTYPE_LCD;			
--		else if (sr17 & 0x08 )
--			ivideo.disp_state = DISPTYPE_CRT2;
--		else
--			ivideo.disp_state = 0;
--
--		if(sisfb_tvplug != -1)
--			/* PR/TW: override detected TV type */
--			ivideo.TV_plug = sisfb_tvplug;
--		else if (sr17 & 0x20)
--			ivideo.TV_plug = TVPLUG_SVIDEO;
--		else if (sr17 & 0x10)
--			ivideo.TV_plug = TVPLUG_COMPOSITE;
--
--		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
--		if (sr16 & 0x20)
--			ivideo.TV_type = TVMODE_PAL;
--		else
--			ivideo.TV_type = TVMODE_NTSC;
--
--	} else {
--
--		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
--			sisfb_crt1off = 0;
--		else {
--			if (cr32 & 0x5F)
--				sisfb_crt1off = 1;
--			else
--				sisfb_crt1off = 0;
--		}
--
--		if (sisfb_crt2type != -1)
--			/* TW: override detected CRT2 type */
--			ivideo.disp_state = sisfb_crt2type;
--		else if (cr32 & SIS_VB_TV)
--			ivideo.disp_state = DISPTYPE_TV;
--		else if (cr32 & SIS_VB_LCD)
--			ivideo.disp_state = DISPTYPE_LCD;
--		else if (cr32 & SIS_VB_CRT2)
--			ivideo.disp_state = DISPTYPE_CRT2;
--		else
--			ivideo.disp_state = 0;
--
--		/* TW: Detect TV plug & type */
--		if(sisfb_tvplug != -1)
--			/* PR/TW: override with option */
--		        ivideo.TV_plug = sisfb_tvplug;
--		else if (cr32 & SIS_VB_HIVISION) {
--			ivideo.TV_type = TVMODE_HIVISION;
--			ivideo.TV_plug = TVPLUG_SVIDEO;
--		}
--		else if (cr32 & SIS_VB_SVIDEO)
--			ivideo.TV_plug = TVPLUG_SVIDEO;
--		else if (cr32 & SIS_VB_COMPOSITE)
--			ivideo.TV_plug = TVPLUG_COMPOSITE;
--		else if (cr32 & SIS_VB_SCART)
--			ivideo.TV_plug = TVPLUG_SCART;
--
--		if (ivideo.TV_type == 0) {
--		        inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
--			if (temp & 0x01)
--				ivideo.TV_type = TVMODE_PAL;
--			else
--				ivideo.TV_type = TVMODE_NTSC;
--		}
--
--	}
--
--	/* TW: Copy forceCRT1 option to CRT1off if option is given */
--    	if (sisfb_forcecrt1 != -1) {
--    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
--		else                sisfb_crt1off = 1;
--    	}
--}
--
--static void sisfb_get_VB_type_300(void)
--{
--	u8 reg;
--
--	if(ivideo.chip != SIS_300) {
--		if(!sisfb_has_VB_300()) {
--		        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
--			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
--			   case SIS_EXTERNAL_CHIP_LVDS:
--				ivideo.hasVB = HASVB_LVDS;
--				break;
--			   case SIS_EXTERNAL_CHIP_TRUMPION:
--				ivideo.hasVB = HASVB_TRUMPION;
--				break;
--			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
--				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
--				break;
--			   case SIS_EXTERNAL_CHIP_CHRONTEL:
--				ivideo.hasVB = HASVB_CHRONTEL;
--				break;
--			   default:
--				break;
--			}
--		}
--	} else {
--		sisfb_has_VB_300();
--	}
--}
--
--static int sisfb_has_VB_300(void)
--{
--	u8 vb_chipid;
--
--	inSISIDXREG(SISPART4, 0x00, vb_chipid);
--	switch (vb_chipid) {
--	   case 0x01:
--		ivideo.hasVB = HASVB_301;
--		break;
--	   case 0x02:
--		ivideo.hasVB = HASVB_302;
--		break;
--	   default:
--		ivideo.hasVB = HASVB_NONE;
--		return FALSE;
--	}
--	return TRUE;
--
--}
--
- #endif  /* CONFIG_FB_SIS_300 */
- 
- 
-@@ -2314,14 +2454,18 @@ static int sisfb_get_dram_size_315(void)
- 	u8  pci_data;
- 	u8  reg = 0;
- 
--	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
-+	if (ivideo.chip == SIS_550 ||
-+	    ivideo.chip == SIS_650 ||
-+	    ivideo.chip == SIS_740 ||
-+	    ivideo.chip == SIS_660) {
- 
- #ifdef LINUXBIOS
- 
- 		while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev)) != NULL) {
- 			if ((pdev->device == PCI_DEVICE_ID_SI_550) ||
--			     (pdev->device == PCI_DEVICE_ID_SI_650) ||
--			     (pdev->device == PCI_DEVICE_ID_SI_740)) {
-+			    (pdev->device == PCI_DEVICE_ID_SI_650) ||
-+			     (pdev->device == PCI_DEVICE_ID_SI_740) ||
-+			     (pdev->device == PCI_DEVICE_ID_SI_660)) {
- 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
- 				                     &pci_data);
- 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-@@ -2425,7 +2569,7 @@ static int sisfb_get_dram_size_315(void)
- #endif
- 		return 0;
- 
--	} else {	/* 315 */
-+	} else {	/* 315, 330 */
- 
- 	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
- 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
-@@ -2470,7 +2614,7 @@ static int sisfb_get_dram_size_315(void)
- 		      case SIS315_DUAL_CHANNEL_1_RANK:
- 			   ivideo.video_size <<= 1;
- 			   break;
--		      case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
-+		      case SIS315_ASYM_DDR:		/* TW: DDR asymetric */
- 			   ivideo.video_size += (ivideo.video_size/2);
- 			   break;
- 		   }
-@@ -2483,128 +2627,242 @@ static int sisfb_get_dram_size_315(void)
- 	
- }
- 
--static void sisfb_detect_VB_connect_315(void)
-+#endif   /* CONFIG_FB_SIS_315 */
-+
-+
-+/* -------------- video bridge detection --------------- */
-+
-+static void sisfb_detect_VB_connect()
- {
--	u8 cr32, temp=0;
-+	u8 sr16, sr17, cr32, temp;
- 
--	ivideo.TV_plug = ivideo.TV_type = 0;
-+	if(sisvga_engine == SIS_300_VGA) {
-+	
-+		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17); 
-+	      
-+		if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
-+	
-+			/* Old BIOSes store the detected CRT2 type in SR17
-+		 	 * instead of CR32. However, since our detection
-+			 * routines store their results to CR32, we now copy
-+			 * the remaining bits (for LCD and VGA) to CR32 for
-+			 * unified usage.
-+			 * SR17[0] CRT1    [1] LCD     [2] TV    [3] VGA2
-+			 *     [4] AVIDEO  [5] SVIDEO
-+			 */
- 
--        switch(ivideo.hasVB) {
--	  case HASVB_LVDS_CHRONTEL:
--	  case HASVB_CHRONTEL:
--	     SiS_SenseCh();
--	     break;
--	  case HASVB_301:
--	  case HASVB_302:
--	     SiS_Sense30x();
--	     break;
--	}
-+#if 0
-+			if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
-+			else		 andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
-+
-+			if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
-+			else		 andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
-+
-+			/* no HiVision and no DVI connector here */
-+			andSISIDXREG(SISCR, 0x32, ~0xc0);
-+#endif
-+		
-+			/* PAL/NTSC is stored on SR16 on such machines */
-+			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
-+		   		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
-+				if (sr16 & 0x20)
-+					ivideo.vbflags |= TV_PAL;
-+				else
-+					ivideo.vbflags |= TV_NTSC;
-+			}
- 
-+		} 
-+		
-+	}
-+	
- 	inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
- 
--	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
-+	if (cr32 & SIS_CRT1)
- 		sisfb_crt1off = 0;
- 	else {
--		if (cr32 & 0x5F)   
-+		if (cr32 & 0x5F)
- 			sisfb_crt1off = 1;
- 		else
- 			sisfb_crt1off = 0;
- 	}
- 
--	if (sisfb_crt2type != -1)
--		/* TW: Override with option */
--		ivideo.disp_state = sisfb_crt2type;
--	else if (cr32 & SIS_VB_TV)
--		ivideo.disp_state = DISPTYPE_TV;		
--	else if (cr32 & SIS_VB_LCD)
--		ivideo.disp_state = DISPTYPE_LCD;		
--	else if (cr32 & SIS_VB_CRT2)
--		ivideo.disp_state = DISPTYPE_CRT2;
--	else
--		ivideo.disp_state = 0;
-+	ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
- 
-+	if (cr32 & SIS_VB_TV)
-+		ivideo.vbflags |= CRT2_TV;
-+	if (cr32 & SIS_VB_LCD)
-+		ivideo.vbflags |= CRT2_LCD;
-+	if (cr32 & SIS_VB_CRT2)
-+		ivideo.vbflags |= CRT2_VGA;
-+		
-+	/* TW: Detect/set TV plug & type */
- 	if(sisfb_tvplug != -1)
--		/* PR/TW: Override with option */
--	        ivideo.TV_plug = sisfb_tvplug;
--	else if (cr32 & SIS_VB_HIVISION) {
--		ivideo.TV_type = TVMODE_HIVISION;
--		ivideo.TV_plug = TVPLUG_SVIDEO;
--	}
-+	        ivideo.vbflags |= sisfb_tvplug;
-+	if (cr32 & SIS_VB_HIVISION) 
-+		ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);
- 	else if (cr32 & SIS_VB_SVIDEO)
--		ivideo.TV_plug = TVPLUG_SVIDEO;
-+		ivideo.vbflags |= TV_SVIDEO;
- 	else if (cr32 & SIS_VB_COMPOSITE)
--		ivideo.TV_plug = TVPLUG_COMPOSITE;
-+		ivideo.vbflags |= TV_AVIDEO;
- 	else if (cr32 & SIS_VB_SCART)
--		ivideo.TV_plug = TVPLUG_SCART;
--
--	if(ivideo.TV_type == 0) {
--	    /* TW: PAL/NTSC changed for 650 */
--	    if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
--
--                inSISIDXREG(SISCR, 0x38, temp);
--		if(temp & 0x10)
--			ivideo.TV_type = TVMODE_PAL;
--		else
--			ivideo.TV_type = TVMODE_NTSC;
-+		ivideo.vbflags |= TV_SCART;
-+		
-+	if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
-+		if(sisvga_engine == SIS_300_VGA) {
-+	        	inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
-+			if (temp & 0x01)
-+				ivideo.vbflags |= TV_PAL;
-+			else
-+				ivideo.vbflags |= TV_NTSC;
-+		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
- 
--	    } else {
-+                	inSISIDXREG(SISCR, 0x38, temp);
-+			if(temp & 0x10)
-+				ivideo.vbflags |= TV_PAL;
-+			else
-+				ivideo.vbflags |= TV_NTSC;
-+		
-+	    	} else {
- 
--	        inSISIDXREG(SISCR, 0x79, temp);
--		if(temp & 0x20)
--			ivideo.TV_type = TVMODE_PAL;
--		else
--			ivideo.TV_type = TVMODE_NTSC;
--	    }
-+	        	inSISIDXREG(SISCR, 0x79, temp);
-+			if(temp & 0x20)
-+				ivideo.vbflags |= TV_PAL;
-+			else
-+				ivideo.vbflags |= TV_NTSC;
-+	    	}
- 	}
- 
- 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
-     	if (sisfb_forcecrt1 != -1) {
--    		if (sisfb_forcecrt1) sisfb_crt1off = 0;
--		else   	             sisfb_crt1off = 1;
-+    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
-+		else                sisfb_crt1off = 1;
-     	}
--}
--
--static void sisfb_get_VB_type_315(void)
--{
--	u8 reg;
- 
--	if (!sisfb_has_VB_315()) {
--	        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
--		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
--	 	   case SIS310_EXTERNAL_CHIP_LVDS:
--			ivideo.hasVB = HASVB_LVDS;
--			break;
--		   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
--			ivideo.hasVB = HASVB_LVDS_CHRONTEL;
--			break;
--		   default:
--			break;
--		}
--	}
- }
- 
--
--static int sisfb_has_VB_315(void)
-+static void sisfb_get_VB_type(void)
- {
- 	u8 vb_chipid;
-+	u8 reg;
-+	char stdstr[]    = "sisfb: Detected";
-+	char bridgestr[] = "video bridge";
-+	char lvdsstr[]   = "LVDS transmitter";
-+  	char chrstr[]    = "Chrontel TV encoder";
-+	
-+	ivideo.hasVB = HASVB_NONE;
-+	sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
-+	sishw_ext.Is301BDH = FALSE;
-+	sishw_ext.usExternalChip = 0;
- 
- 	inSISIDXREG(SISPART4, 0x00, vb_chipid);
- 	switch (vb_chipid) {
- 	   case 0x01:
- 		ivideo.hasVB = HASVB_301;
-+		inSISIDXREG(SISPART4, 0x01, reg);
-+		if(reg < 0xb0) { 
-+			ivideo.vbflags |= VB_301;
-+			sishw_ext.ujVBChipID = VB_CHIP_301;
-+			printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
-+		} else if(reg < 0xd0) {
-+		 	ivideo.vbflags |= VB_301B;
-+			sishw_ext.ujVBChipID = VB_CHIP_301B;
-+			printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
-+		} else if(reg < 0xe0) {
-+			ivideo.vbflags |= VB_301LV;
-+			sishw_ext.ujVBChipID = VB_CHIP_301LV;
-+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
-+		} else if(reg <= 0xe1) {
-+			ivideo.vbflags |= VB_302LV;
-+			sishw_ext.ujVBChipID = VB_CHIP_302LV;
-+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
-+		}
- 		break;
- 	   case 0x02:
- 		ivideo.hasVB = HASVB_302;
-+		inSISIDXREG(SISPART4, 0x01, reg);
-+		if(reg < 0xd0) {
-+			ivideo.vbflags |= VB_302B;
-+			sishw_ext.ujVBChipID = VB_CHIP_302B;
-+			printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
-+		} else if(reg < 0xe0) {
-+		 	ivideo.vbflags |= VB_301LV;
-+			sishw_ext.ujVBChipID = VB_CHIP_301LV;
-+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
-+		} else if(reg <= 0xe1) {
-+			ivideo.vbflags |= VB_302LV;
-+			sishw_ext.ujVBChipID = VB_CHIP_302LV;
-+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
-+		}
- 		break;
--	   default:
--		ivideo.hasVB = HASVB_NONE;
--		return FALSE;
- 	}
--	return TRUE;
-+	
-+	if(ivideo.vbflags & (VB_301B | VB_302B)) {
-+		inSISIDXREG(SISPART4,0x23,reg);
-+		if(!(reg & 0x02)) {
-+			sishw_ext.Is301BDH = TRUE;
-+			ivideo.vbflags |= VB_30xBDH;
-+			printk(KERN_INFO "This %s does not support LCD output\n", bridgestr);
-+		}
-+	}
-+	
-+	if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
-+		inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
-+		reg &= SIS_EXTERNAL_CHIP_MASK;
-+		reg >>= 1;
-+		if(sisvga_engine == SIS_300_VGA) {
-+			switch (reg) {
-+			   case SIS_EXTERNAL_CHIP_LVDS:
-+				ivideo.hasVB = HASVB_LVDS;
-+				ivideo.vbflags |= VB_LVDS;
-+				sishw_ext.usExternalChip = 0x01;
-+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
-+				break;
-+			   case SIS_EXTERNAL_CHIP_TRUMPION:
-+				ivideo.hasVB = HASVB_TRUMPION;
-+				ivideo.vbflags |= VB_TRUMPION;
-+				sishw_ext.usExternalChip = 0x02;
-+				printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
-+				break;	   
-+			   case SIS_EXTERNAL_CHIP_CHRONTEL:
-+				ivideo.hasVB = HASVB_CHRONTEL;
-+				ivideo.vbflags |= VB_CHRONTEL;
-+				sishw_ext.usExternalChip = 0x04;
-+				printk(KERN_INFO "%s %s\n", stdstr, chrstr);
-+				break;
-+			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
-+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-+				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
-+				sishw_ext.usExternalChip = 0x05;
-+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
-+				break;
-+			}
-+		} else {
-+			switch (reg) {
-+	 	   	   case SIS310_EXTERNAL_CHIP_LVDS:
-+				ivideo.hasVB = HASVB_LVDS;
-+				ivideo.vbflags |= VB_LVDS;
-+				sishw_ext.usExternalChip = 0x01;
-+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
-+				break;
-+		   	   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-+				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
-+				sishw_ext.usExternalChip = 0x05;
-+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
-+				break;
-+			}
-+		}
-+	
-+	}
-+	
-+	if(ivideo.vbflags & VB_SISBRIDGE) {
-+		SiS_Sense30x();
-+	} else if(ivideo.vbflags & VB_CHRONTEL) {
-+		SiS_SenseCh();
-+	}
-+	
- }
- 
--#endif   /* CONFIG_FB_SIS_315 */
--
- /* ------------------ Sensing routines ------------------ */
- 
- /* TW: Determine and detect attached devices on SiS30x */
-@@ -2621,34 +2879,39 @@ SISDoSense(int tempbl, int tempbh, int t
-     inSISIDXREG(SISPART4,0x03,temp);
-     temp ^= 0x0e;
-     temp &= tempch;
--    return(temp);
-+    return((temp == tempch));
- }
- 
- void
- SiS_Sense30x(void)
- {
--  u8 backupP4_0d;
-+  u8 backupP4_0d,backupP2_00;
-   u8 testsvhs_tempbl, testsvhs_tempbh;
-   u8 testsvhs_tempcl, testsvhs_tempch;
-   u8 testcvbs_tempbl, testcvbs_tempbh;
-   u8 testcvbs_tempcl, testcvbs_tempch;
-   u8 testvga2_tempbl, testvga2_tempbh;
-   u8 testvga2_tempcl, testvga2_tempch;
--  int myflag, result;
-+  int myflag, result, haveresult, i, j;
-+  char stdstr[] = "sisfb: Detected";
-+  char tvstr[]  = "TV connected to";
- 
-   inSISIDXREG(SISPART4,0x0d,backupP4_0d);
-   outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
- 
-+  inSISIDXREG(SISPART2,0x00,backupP2_00);
-+  outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
-+
-   if(sisvga_engine == SIS_300_VGA) {
- 
--  	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
--        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
--	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
--	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
--	   (sishw_ext.ujVBChipID != VB_CHIP_302) ) {
--	   testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
--	   testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
--	   testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
-+	if(ivideo.vbflags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) {
-+	   	testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-+	   	testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-+	   	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
-+	} else {
-+		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-+        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-+		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
- 	}
- 	inSISIDXREG(SISPART4,0x01,myflag);
- 	if(myflag & 0x04) {
-@@ -2657,35 +2920,36 @@ SiS_Sense30x(void)
- 	   testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
- 	}
- 	testvga2_tempch = 0x0e;	testvga2_tempcl = 0x08;
--	testsvhs_tempch = 0x06;	testsvhs_tempcl = 0x04;
-+	testsvhs_tempch = 0x04;	testsvhs_tempcl = 0x04;
- 	testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
-+	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-+	   	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-+	   	testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
-+	 }
- 	if(ivideo.chip == SIS_300) {
- 	   inSISIDXREG(SISSR,0x3b,myflag);
- 	   if(!(myflag & 0x01)) {
--	      testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
--	      testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
-+	      	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-+	      	testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
- 	   }
- 	}
- 
-   } else {
- 
--	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
--        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
--	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
--	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
--	   (sishw_ext.ujVBChipID != VB_CHIP_302)) {
--	      testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
--	      testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
--	      testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
--	      if(sishw_ext.ujVBChipID == VB_CHIP_301LV ||
--	         sishw_ext.ujVBChipID == VB_CHIP_302LV) {
--	         testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
--	         testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
--	         testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
--	      }
-+	if(ivideo.vbflags & (VB_301B|VB_302B)) {
-+		testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-+		testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-+		testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
-+	} else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
-+	      	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-+	      	testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
-+	      	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
-+	} else {
-+		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-+        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-+		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
- 	}
--	if(sishw_ext.ujVBChipID != VB_CHIP_301LV &&
--	   sishw_ext.ujVBChipID != VB_CHIP_302LV) {
-+	if(ivideo.vbflags & (VB_301|VB_301B|VB_302B)) {
- 	   inSISIDXREG(SISPART4,0x01,myflag);
- 	   if(myflag & 0x04) {
- 	      testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
-@@ -2693,49 +2957,78 @@ SiS_Sense30x(void)
- 	      testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
- 	   }
- 	}
--	if((sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
--	   (sishw_ext.ujVBChipID == VB_CHIP_302LV) ) {
-+	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
- 	   testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
- 	   testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
- 	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
- 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
- 	} else {
- 	   testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
--	   testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
-+	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04;
- 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
- 	}
-     } 
- 
-     if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
--        result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
--                            testvga2_tempcl, testvga2_tempch);
-- 	if(result) {
--        	printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
--		orSISIDXREG(SISCR, 0x32, 0x10);
--	}
-+       haveresult = 0;
-+       for(j = 0; j < 10; j++) {
-+          result = 0;
-+          for(i = 0; i < 3; i++) {
-+             if(SISDoSense(testvga2_tempbl, testvga2_tempbh,
-+                           testvga2_tempcl, testvga2_tempch))
-+	        result++;
-+          }
-+	  if((result == 0) || (result >= 2)) break;
-+       }
-+       if(result) {
-+          printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
-+	  orSISIDXREG(SISCR, 0x32, 0x10);
-+       } else {
-+	  andSISIDXREG(SISCR, 0x32, ~0x10);
-+       }
-+    }
-+
-+    haveresult = 0;
-+    for(j = 0; j < 10; j++) {
-+       result = 0;
-+       for(i = 0; i < 3; i++) {
-+          if(SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
-+                        testsvhs_tempcl, testsvhs_tempch))
-+	        result++;
-+       }
-+       if((result == 0) || (result >= 2)) break;
-     }
--    
--    result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
--                        testsvhs_tempcl, testsvhs_tempch);
-     if(result) {
--        printk(KERN_INFO "sisfb: Detected TV connected to SVHS output\n");
--        /* TW: So we can be sure that there IS a SVHS output */
--	ivideo.TV_plug = TVPLUG_SVIDEO;
-+        printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
-+	ivideo.vbflags |= TV_SVIDEO;
- 	orSISIDXREG(SISCR, 0x32, 0x02);
-+	andSISIDXREG(SISCR, 0x32, ~0x05);
-     }
- 
-     if(!result) {
--        result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
--	                    testcvbs_tempcl, testcvbs_tempch);
-+
-+	haveresult = 0;
-+       	for(j = 0; j < 10; j++) {
-+           result = 0;
-+           for(i = 0; i < 3; i++) {
-+              if(SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
-+	                    testcvbs_tempcl, testcvbs_tempch))
-+	        result++;
-+           }
-+           if((result == 0) || (result >= 2)) break;
-+        }
- 	if(result) {
--	    printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
--	    /* TW: So we can be sure that there IS a CVBS output */
--	    ivideo.TV_plug = TVPLUG_COMPOSITE;
-+	    printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
-+	    ivideo.vbflags |= TV_AVIDEO;
- 	    orSISIDXREG(SISCR, 0x32, 0x01);
-+	    andSISIDXREG(SISCR, 0x32, ~0x06);
-+	} else {
-+	    andSISIDXREG(SISCR, 0x32, ~0x07);
- 	}
-     }
-     SISDoSense(0, 0, 0, 0);
- 
-+    outSISIDXREG(SISPART2,0x00,backupP2_00);
-     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
- }
- 
-@@ -2744,51 +3037,84 @@ void
- SiS_SenseCh(void)
- {
- 
--   u8 temp1;
--#ifdef CONFIG_FB_SIS_315
--   u8 temp2;
-+   u8 temp1, temp2;
-+#ifdef CONFIG_FB_SIS_300
-+   unsigned char test[3];
-+   int i;
- #endif
-+   char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
- 
-    if(ivideo.chip < SIS_315H) {
- 
- #ifdef CONFIG_FB_SIS_300
--       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* TW: Chrontel 7005 */
-+       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* Chrontel 700x */
-+       SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);	/* Set general purpose IO for Chrontel communication */
-+       SiS_DDC2Delay(&SiS_Pr, 1000);
-        temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
--       if ((temp1 >= 50) && (temp1 <= 100)) {
--	   /* TW: Read power status */
-+       /* TW: See Chrontel TB31 for explanation */
-+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
-+       if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
-+	  SiS_SetCH700x(&SiS_Pr, 0x0b0e);
-+	  SiS_DDC2Delay(&SiS_Pr, 300);
-+       }
-+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
-+       if(temp2 != temp1) temp1 = temp2;
-+
-+       if((temp1 >= 0x22) && (temp1 <= 0x50)) {
-+	   /* Read power status */
- 	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
- 	   if((temp1 & 0x03) != 0x03) {
--     	        /* TW: Power all outputs */
--		SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
-+     	        /* Power all outputs */
-+		SiS_SetCH700x(&SiS_Pr, 0x0B0E);
-+		SiS_DDC2Delay(&SiS_Pr, 300);
- 	   }
--	   /* TW: Sense connected TV devices */
--	   SiS_SetCH700x(&SiS_Pr, 0x0110);
--	   SiS_SetCH700x(&SiS_Pr, 0x0010);
--	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
--	   if(!(temp1 & 0x08)) {
--		printk(KERN_INFO
--		   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
--		/* TW: So we can be sure that there IS a SVHS output */
--		ivideo.TV_plug = TVPLUG_SVIDEO;
-+	   /* Sense connected TV devices */
-+	   for(i = 0; i < 3; i++) {
-+	       SiS_SetCH700x(&SiS_Pr, 0x0110);
-+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
-+	       SiS_SetCH700x(&SiS_Pr, 0x0010);
-+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
-+	       temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
-+	       if(!(temp1 & 0x08))       test[i] = 0x02;
-+	       else if(!(temp1 & 0x02))  test[i] = 0x01;
-+	       else                      test[i] = 0;
-+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
-+	   }
-+
-+	   if(test[0] == test[1])      temp1 = test[0];
-+	   else if(test[0] == test[2]) temp1 = test[0];
-+	   else if(test[1] == test[2]) temp1 = test[1];
-+	   else {
-+	   	printk(KERN_INFO
-+			"sisfb: TV detection unreliable - test results varied\n");
-+		temp1 = test[2];
-+	   }
-+	   if(temp1 == 0x02) {
-+		printk(KERN_INFO "%s SVIDEO output\n", stdstr);
-+		ivideo.vbflags |= TV_SVIDEO;
- 		orSISIDXREG(SISCR, 0x32, 0x02);
--	   } else if (!(temp1 & 0x02)) {
--		printk(KERN_INFO
--		   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
--		/* TW: So we can be sure that there IS a CVBS output */
--		ivideo.TV_plug = TVPLUG_COMPOSITE;
-+		andSISIDXREG(SISCR, 0x32, ~0x05);
-+	   } else if (temp1 == 0x01) {
-+		printk(KERN_INFO "%s CVBS output\n", stdstr);
-+		ivideo.vbflags |= TV_AVIDEO;
- 		orSISIDXREG(SISCR, 0x32, 0x01);
-+		andSISIDXREG(SISCR, 0x32, ~0x06);
- 	   } else {
-  		SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
-+		andSISIDXREG(SISCR, 0x32, ~0x07);
- 	   }
-        } else if(temp1 == 0) {
- 	  SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
-+	  andSISIDXREG(SISCR, 0x32, ~0x07);
-        }
-+       /* Set general purpose IO for Chrontel communication */
-+       SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
- #endif
- 
-    } else {
- 
- #ifdef CONFIG_FB_SIS_315
--	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* TW: Chrontel 7019 */
-+	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* Chrontel 7019 */
-         temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
- 	SiS_SetCH701x(&SiS_Pr, 0x2049);
- 	SiS_DDC2Delay(&SiS_Pr, 0x96);
-@@ -2808,22 +3134,24 @@ SiS_SenseCh(void)
- 	if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
- 	switch(temp1) {
- 	case 0x01:
--	     printk(KERN_INFO
--		"sisfb: Chrontel: Detected TV connected to CVBS output\n");
--	     ivideo.TV_plug = TVPLUG_COMPOSITE;
-+	     printk(KERN_INFO "%s CVBS output\n", stdstr);
-+	     ivideo.vbflags |= TV_AVIDEO;
- 	     orSISIDXREG(SISCR, 0x32, 0x01);
-+	     andSISIDXREG(SISCR, 0x32, ~0x06);
-              break;
- 	case 0x02:
--	     printk(KERN_INFO
--		"sisfb: Chrontel: Detected TV connected to SVHS output\n");
--	     ivideo.TV_plug = TVPLUG_SVIDEO;
-+	     printk(KERN_INFO "%s SVIDEO output\n", stdstr);
-+	     ivideo.vbflags |= TV_SVIDEO;
- 	     orSISIDXREG(SISCR, 0x32, 0x02);
-+	     andSISIDXREG(SISCR, 0x32, ~0x05);
-              break;
- 	case 0x04:
--	     /* TW: This should not happen */
--	     printk(KERN_INFO
--		"sisfb: Chrontel: Detected TV connected to SCART output\n");
-+	     printk(KERN_INFO "%s SCART output\n", stdstr);
-+	     orSISIDXREG(SISCR, 0x32, 0x04);
-+	     andSISIDXREG(SISCR, 0x32, ~0x03);		
-              break;
-+	default:
-+	     andSISIDXREG(SISCR, 0x32, ~0x07);
- 	}
- #endif
- 
-@@ -2860,14 +3188,20 @@ static int sisfb_heap_init(void)
-  *     in XF86Config-4.
-  *     The heap start can also be specified by parameter "mem" when starting the sisfb
-  *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
-+ *     On the 315 series, the default is a 1MB heap since DRI is not supported
-+ *     there.
-  */
-      if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
--        if (ivideo.video_size > 0x1000000) {
-+        if(sisvga_engine == SIS_300_VGA) {
-+           if (ivideo.video_size > 0x1000000) {
- 	        ivideo.heapstart = 0xc00000;
--	} else if (ivideo.video_size > 0x800000) {
-+	   } else if (ivideo.video_size > 0x800000) {
- 	        ivideo.heapstart = 0x800000;
--	} else {
-+	   } else {
- 		ivideo.heapstart = 0x400000;
-+	   }
-+	} else {
-+	   ivideo.heapstart = ivideo.video_size - 0x100000;
- 	}
-      } else {
-            ivideo.heapstart = sisfb_mem * 1024;
-@@ -2883,7 +3217,7 @@ static int sisfb_heap_init(void)
- #ifdef CONFIG_FB_SIS_315
-      if (sisvga_engine == SIS_315_VGA) {
-         /* TW: Now initialize the 310 series' command queue mode.
--	 * On 310/325, there are three queue modes available which
-+	 * On 315, there are three queue modes available which
- 	 * are chosen by setting bits 7:5 in SR26:
- 	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
- 	 *    track of the queue, the FIFO, command parsing and so
-@@ -3333,7 +3667,6 @@ void sis_malloc(struct sis_memreq *req)
- 		req->offset = poh->offset;
- 		req->size = poh->size;
- 	}
--
- }
- 
- void sis_free(unsigned long base)
-@@ -3352,35 +3685,70 @@ void sis_free(unsigned long base)
- 
- static void sisfb_pre_setmode(void)
- {
--	u8 cr30 = 0, cr31 = 0;
-+	u8 cr30 = 0, cr31 = 0, cr33 = 0;
-+	
-+	ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
- 
- 	inSISIDXREG(SISCR, 0x31, cr31);
- 	cr31 &= ~0x60;
-+	cr31 |= 0x04;
-+	
-+	cr33 = sisfb_rate_idx & 0x0F;
- 
--	switch (ivideo.disp_state & DISPTYPE_DISP2) {
--	   case DISPTYPE_CRT2:
--		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
--		cr31 |= SIS_DRIVER_MODE;
--		break;
--	   case DISPTYPE_LCD:
--		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
--		cr31 |= SIS_DRIVER_MODE;
--		break;
--	   case DISPTYPE_TV:
--		if (ivideo.TV_type == TVMODE_HIVISION)
-+	SiS_SetEnableDstn(&SiS_Pr, FALSE);
-+	SiS_SetEnableFstn(&SiS_Pr, FALSE);
-+
-+	switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
-+	   case CRT2_TV:
-+		ivideo.disp_state = DISPTYPE_TV;
-+		if (ivideo.vbflags & TV_HIVISION) {
- 			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
--		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
-+			ivideo.currentvbflags |= (TV_HIVISION | TV_SVIDEO);
-+			ivideo.TV_type = TVMODE_HIVISION;
-+			ivideo.TV_plug = TVPLUG_SVIDEO;
-+		} else if (ivideo.vbflags & TV_SVIDEO) {
- 			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
--		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
-+			ivideo.currentvbflags |= TV_SVIDEO;
-+			ivideo.TV_plug = TVPLUG_SVIDEO;
-+		} else if (ivideo.vbflags & TV_AVIDEO) {
- 			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
--		else if (ivideo.TV_plug == TVPLUG_SCART)
-+			ivideo.currentvbflags |= TV_AVIDEO;
-+			ivideo.TV_plug = TVPLUG_COMPOSITE;
-+		} else if (ivideo.vbflags & TV_SCART) {
- 			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
-+			ivideo.currentvbflags |= TV_SCART;
-+			ivideo.TV_plug = TVPLUG_SCART;
-+		}
- 		cr31 |= SIS_DRIVER_MODE;
- 
--	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
--			cr31 |= 0x01;
--                else
--                        cr31 &= ~0x01;
-+		if(!(ivideo.vbflags & TV_HIVISION)) {
-+	        	if (ivideo.vbflags & TV_PAL) {
-+		 		cr31 |= 0x01;
-+				ivideo.currentvbflags |= TV_PAL;
-+				ivideo.TV_type = TVMODE_PAL;
-+                	} else {
-+		       		cr31 &= ~0x01;
-+				ivideo.currentvbflags |= TV_NTSC;
-+				ivideo.TV_type = TVMODE_NTSC;
-+			}
-+		}
-+		break;
-+	   case CRT2_LCD:
-+		ivideo.disp_state = DISPTYPE_LCD;
-+		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
-+		cr31 |= SIS_DRIVER_MODE;
-+		SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
-+	        SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
-+		break;		
-+	   case CRT2_VGA:
-+		ivideo.disp_state = DISPTYPE_CRT2;
-+		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
-+		cr31 |= SIS_DRIVER_MODE;
-+		if(sisfb_nocrt2rate) {
-+			cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
-+		} else {
-+			cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
-+		}
- 		break;
- 	   default:	/* disable CRT2 */
- 		cr30 = 0x00;
-@@ -3389,8 +3757,7 @@ static void sisfb_pre_setmode(void)
- 
- 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
- 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
--
--        outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, (sisfb_rate_idx & 0x0F));
-+	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
- 
- 	if(ivideo.accel) sisfb_syncaccel();
- 
-@@ -3400,67 +3767,89 @@ static void sisfb_pre_setmode(void)
- static void sisfb_post_setmode(void)
- {
- 	u8 reg;
-+	BOOLEAN crt1isoff = FALSE;
-+#ifdef CONFIG_FB_SIS_315
-+	u8 reg1;
-+#endif
-+#ifdef CONFIG_FB_SIS_300
- 	BOOLEAN doit = TRUE;
--#if 0	/* TW: Wrong: Is not in MMIO space, but in RAM */
--	/* Backup mode number to MMIO space */
--	if(ivideo.mmio_vbase) {
--	  *(volatile u8 *)(((u8*)ivideo.mmio_vbase) + 0x449) = (unsigned char)sisfb_mode_no;
--	}
--#endif	
--
--	if (ivideo.video_bpp == 8) {
--		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
--		if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
--			doit = FALSE;
--		}
--		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
--		if ( (sishw_ext.Is301BDH) && (ivideo.disp_state & DISPTYPE_LCD) ) {
--	        	doit = FALSE;
--	        }
--	}
--
-+#endif
- 	/* TW: We can't switch off CRT1 if bridge is in slave mode */
--	if(ivideo.hasVB != HASVB_NONE) {
--		inSISIDXREG(SISPART1, 0x00, reg);
-+	if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-+#ifdef CONFIG_FB_SIS_300
- 		if(sisvga_engine == SIS_300_VGA) {
-+			inSISIDXREG(SISPART1, 0x00, reg);
- 			if((reg & 0xa0) == 0x20) {
- 				doit = FALSE;
- 			}
- 		}
--		if(sisvga_engine == SIS_315_VGA) {
--			if((reg & 0x50) == 0x10) {
--				doit = FALSE;
--			}
--		}
-+#endif
- 	} else sisfb_crt1off = 0;
- 
--	inSISIDXREG(SISCR, 0x17, reg);
--	if((sisfb_crt1off) && (doit))
--		reg &= ~0x80;
--	else 	      
--		reg |= 0x80;
--	outSISIDXREG(SISCR, 0x17, reg);
-+	if(sisvga_engine == SIS_300_VGA) {
- 
--        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
-+#ifdef CONFIG_FB_SIS_300
-+	   if((sisfb_crt1off) && (doit)) {
-+	        crt1isoff = TRUE;
-+		reg = 0x00;
-+	   } else {
-+	        crt1isoff = FALSE;
-+		reg = 0x80;
-+	   }
-+	   setSISIDXREG(SISCR, 0x17, 0x7f, reg);
-+#endif
- 
--	if((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
-+	} else {
-+
-+#ifdef CONFIG_FB_SIS_315
-+	   if(sisfb_crt1off) {
-+	        crt1isoff = TRUE;
-+		reg  = 0x40;
-+		reg1 = 0xc0;
-+	   } else {
-+	        crt1isoff = FALSE;
-+		reg  = 0x00;
-+		reg1 = 0x00;
-+
-+	   }
-+	   setSISIDXREG(SISCR, 0x63, ~0x40, reg);
-+	   setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
-+#endif
-+
-+	}
-+
-+	if(crt1isoff) {
-+	   ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
-+	   ivideo.currentvbflags |= VB_SINGLE_MODE;
-+	   ivideo.disp_state |= DISPMODE_SINGLE;
-+	} else {
-+	   ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
-+	   ivideo.disp_state |= DISPTYPE_CRT1;
-+	   if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
-+	  	ivideo.currentvbflags |= VB_MIRROR_MODE;
-+		ivideo.disp_state |= DISPMODE_MIRROR;
-+	   } else {
-+	 	ivideo.currentvbflags |= VB_SINGLE_MODE;
-+		ivideo.disp_state |= DISPMODE_SINGLE;
-+	   }
-+	}
- 
--	   inSISIDXREG(SISPART4, 0x01, reg);
-+        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
- 
--	   if(reg < 0xB0) {        	/* Set filter for SiS301 */
-+	if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) {  /* Set filter for SiS301 */
- 
- 		switch (ivideo.video_width) {
- 		   case 320:
--			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
-+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
- 			break;
- 		   case 640:
--			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
-+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
- 			break;
- 		   case 720:
--			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
-+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
- 			break;
- 		   case 800:
--			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
-+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
- 			break;
- 		   default:
- 			filter = -1;
-@@ -3469,15 +3858,15 @@ static void sisfb_post_setmode(void)
- 
- 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
- 
--		if(ivideo.TV_type == TVMODE_NTSC) {
-+		if(ivideo.vbflags & TV_NTSC) {
- 
- 		        andSISIDXREG(SISPART2, 0x3a, 0x1f);
- 
--			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-+			if (ivideo.vbflags & TV_SVIDEO) {
- 
- 			        andSISIDXREG(SISPART2, 0x30, 0xdf);
- 
--			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-+			} else if (ivideo.vbflags & TV_AVIDEO) {
- 
- 			        orSISIDXREG(SISPART2, 0x30, 0x20);
- 
-@@ -3503,15 +3892,15 @@ static void sisfb_post_setmode(void)
- 				}
- 			}
- 
--		} else if(ivideo.TV_type == TVMODE_PAL) {
-+		} else if(ivideo.vbflags & TV_PAL) {
- 
- 			andSISIDXREG(SISPART2, 0x3A, 0x1F);
- 
--			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-+			if (ivideo.vbflags & TV_SVIDEO) {
- 
- 			        andSISIDXREG(SISPART2, 0x30, 0xDF);
- 
--			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-+			} else if (ivideo.vbflags & TV_AVIDEO) {
- 
- 			        orSISIDXREG(SISPART2, 0x30, 0x20);
- 
-@@ -3539,7 +3928,7 @@ static void sisfb_post_setmode(void)
- 		}
- 
- 		if ((filter >= 0) && (filter <=7)) {
--			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 
-+			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
- 				sis_TV_filter[filter_tb].filter[filter][0],
- 				sis_TV_filter[filter_tb].filter[filter][1],
- 				sis_TV_filter[filter_tb].filter[filter][2],
-@@ -3550,8 +3939,6 @@ static void sisfb_post_setmode(void)
- 			outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
- 			outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
- 		}
--
--	     }
- 	  
- 	}
- 
-@@ -3578,24 +3965,22 @@ int sisfb_setup(char *options)
- 		if (!*this_opt)	continue;
- 
- 		if (!strncmp(this_opt, "mode:", 5)) {
--			sisfb_search_mode(this_opt + 5);
-+			sisfb_search_mode(this_opt + 5, FALSE);
- 		} else if (!strncmp(this_opt, "vesa:", 5)) {
--			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
-+			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)			
- 		} else if (!strcmp(this_opt, "inverse")) {
- 			sisfb_inverse = 1;
- 			/* fb_invert_cmaps(); */
- 		} else if (!strncmp(this_opt, "font:", 5)) {
- 			strcpy(sis_fb_info.fontname, this_opt + 5);
--#endif			
--		} else if (!strncmp(this_opt, "mode:", 5)) {
--			sisfb_search_mode(this_opt + 5);
--		} else if (!strncmp(this_opt, "vesa:", 5)) {
--			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
-+#endif
- 		} else if (!strncmp(this_opt, "vrate:", 6)) {
- 			ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
-+			sisfb_parm_rate = ivideo.refresh_rate;
- 		} else if (!strncmp(this_opt, "rate:", 5)) {
- 			ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
-+			sisfb_parm_rate = ivideo.refresh_rate;
- 		} else if (!strncmp(this_opt, "off", 3)) {
- 			sisfb_off = 1;
- 		} else if (!strncmp(this_opt, "crt1off", 7)) {
-@@ -3612,10 +3997,6 @@ int sisfb_setup(char *options)
- 			sisfb_search_tvstd(this_opt + 7);
-                 } else if (!strncmp(this_opt, "mem:",4)) {
- 		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
--                } else if (!strncmp(this_opt, "dstn", 4)) {
--			enable_dstn = 1;
--			/* TW: DSTN overrules forcecrt2type */
--			sisfb_crt2type = DISPTYPE_LCD;
- 		} else if (!strncmp(this_opt, "queuemode:", 10)) {
- 			sisfb_search_queuemode(this_opt + 10);
- 		} else if (!strncmp(this_opt, "pdc:", 4)) {
-@@ -3632,17 +4013,18 @@ int sisfb_setup(char *options)
- 			sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
- 		} else if (!strncmp(this_opt, "useoem:", 7)) {
- 			sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
-+		} else if (!strncmp(this_opt, "nocrt2rate", 10)) {
-+			sisfb_nocrt2rate = 1;			
-+		} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
-+			sisfb_search_mode(this_opt, TRUE);
- 		} else {
- 			printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
- 		}
- 
- 		/* TW: Acceleration only with MMIO mode */
- 		if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
--			sisfb_ypan = 0;
- 			sisfb_accel = 0;
- 		}
--		/* TW: Panning only with acceleration */
--		if(sisfb_accel == 0) sisfb_ypan = 0;
- 
- 	}
- 	return 0;
-@@ -3661,14 +4043,14 @@ static char *sis_find_rom(void)
-         char *sis_sig_300[4] = {
-           "300", "540", "630", "730"
-         };
--        char *sis_sig_310[7] = {
--          "315", "315", "315", "5315", "6325", "6325", "Xabre"
-+        char *sis_sig_310[8] = {
-+          "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330"
-         };
- 	ushort sis_nums_300[4] = {
- 	  SIS_300, SIS_540, SIS_630, SIS_730
- 	};
--	unsigned short sis_nums_310[7] = {
--	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
-+	unsigned short sis_nums_310[8] = {
-+	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660
- 	};
- 
-         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
-@@ -3705,7 +4087,7 @@ static char *sis_find_rom(void)
-                     }
-                 }
- 		if(stage != 4) {
--                   for(i = 0;(i < 7) && (stage != 4); i++) {
-+                   for(i = 0;(i < 8) && (stage != 4); i++) {
-                       if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
- 		          if(sis_nums_310[i] == ivideo.chip) {
-                              stage = 4;
-@@ -3735,7 +4117,7 @@ int __init sisfb_init(void)
- 	int pdev_valid = 0;
- 	u32 reg32;
- 	u16 reg16;
--	u8  reg, reg1;
-+	u8  reg;
- 
- 	/* outb(0x77, 0x80); */  /* What is this? */
- 
-@@ -3751,12 +4133,14 @@ int __init sisfb_init(void)
- 	if (sisfb_off)
- 		return -ENXIO;
- 
--	if (enable_dstn)
--		SiS_SetEnableDstn(&SiS_Pr);
--		
- 	sisfb_registered = 0;
-+	sisfb_thismonitor.datavalid = FALSE;
- 
- 	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+        memset(&sisfb_lastrates[0], 0, 128);
-+#endif
- 	
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
- 	memset(&sis_disp, 0, sizeof(sis_disp));
-@@ -3877,6 +4261,12 @@ int __init sisfb_init(void)
- 		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- 		break;
-+	   case PCI_DEVICE_ID_SI_660_VGA:
-+		ivideo.chip = SIS_660;
-+		sisvga_engine = SIS_315_VGA;
-+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
-+		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
-+		break;
- #endif
-            default:
- 	        return -ENODEV;
-@@ -3902,30 +4292,34 @@ int __init sisfb_init(void)
- 	SiS_Pr.SiS_Backup70xx = 0xff;
-         SiS_Pr.SiS_CHOverScan = -1;
-         SiS_Pr.SiS_ChSW = FALSE;
-+	SiS_Pr.SiS_CustomT = CUT_NONE;
- 	SiS_Pr.SiS_UseLCDA = FALSE;
- 	SiS_Pr.UsePanelScaler = -1;
- 	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
- 
- #ifdef CONFIG_FB_SIS_300
--	/* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
-+	/* TW: Find PCI systems for Chrontel/GPIO communication setup */
- 	if(ivideo.chip == SIS_630) {
--	  int i=0;
--          do {
--	    if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
--	       mychswtable[i].subsysCard   == ivideo.subsysdevice) {
--		SiS_Pr.SiS_ChSW = TRUE;
--            }
--            i++;
--          } while(mychswtable[i].subsysVendor != 0);
-+	   int i=0;
-+           do {
-+	      if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
-+	         mychswtable[i].subsysCard   == ivideo.subsysdevice) {
-+		 SiS_Pr.SiS_ChSW = TRUE;
-+		 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
-+		        mychswtable[i].vendorName, mychswtable[i].cardName);
-+		 break;
-+              }
-+              i++;
-+           } while(mychswtable[i].subsysVendor != 0);
- 	}
- #endif
- 
-         outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
--#ifdef MODULE	
-+#ifdef MODULE
- 	inSISIDXREG(SISCR,0x34,reg);
--	if(reg & 0x80) {
-+	if((reg & 0x80) && (reg != 0xff)) {
- 	   if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
- 	      printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
- 	      return -EBUSY;
-@@ -3938,7 +4332,7 @@ int __init sisfb_init(void)
- 
- #ifdef CONFIG_FB_SIS_300
- 	if (sisvga_engine == SIS_300_VGA) {
--	        outSISIDXREG(SISSR, 0x28, 0x37);
-+	        outSISIDXREG(SISSR, 0x28, 0x37);	/* Reset memory clock */
- 
-                 outSISIDXREG(SISSR, 0x29, 0x61);
- 
-@@ -3946,7 +4340,8 @@ int __init sisfb_init(void)
- 	}
- #endif
- #ifdef CONFIG_FB_SIS_315
--	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
-+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 ||
-+	    ivideo.chip == SIS_740 || ivideo.chip == SIS_660) {
- 	        outSISIDXREG(SISSR, 0x28, 0x5a);
- 
-                 outSISIDXREG(SISSR, 0x29, 0x64);
-@@ -3967,6 +4362,7 @@ int __init sisfb_init(void)
- 		   case SIS_550:
- 		   case SIS_650:
- 		   case SIS_740:
-+		   case SIS_660:
- 			sishw_ext.bIntegratedMMEnabled = TRUE;
- 			break;
- 		   default:
-@@ -4006,13 +4402,45 @@ int __init sisfb_init(void)
- 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
- 	strcpy(sishw_ext.szVBIOSVer, "0.84");
- 
--	/* TW: Mode numbers for 1280x960 are different for 300 and 310/325 series */
-+        /* Find systems for special custom timing */
-+	if(sishw_ext.UseROM) {
-+	   int i=0,j;
-+	   unsigned char *biosver = sishw_ext.pjVirtualRomBase + 0x06;
-+           unsigned char *biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
-+	   BOOLEAN footprint;
-+           do {
-+	      if( (mycustomttable[i].chipID == ivideo.chip) &&
-+	          (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))) &&
-+	          (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))) ) {
-+		 footprint = TRUE;
-+	         for(j=0; j<5; j++) {
-+	           if(mycustomttable[i].biosFootprintAddr[j]) {
-+	              if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
-+		      		mycustomttable[i].biosFootprintData[j])
-+		         footprint = FALSE;
-+		   }
-+	         }
-+	         if(footprint) {
-+	 	    SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
-+		    printk(KERN_DEBUG "sisfb: Identified [%s %s] for non-standard timing\n",
-+		        mycustomttable[i].vendorName,
-+			mycustomttable[i].cardName);
-+	            break;
-+                 }
-+	      }
-+              i++;
-+           } while(mycustomttable[i].chipID);
-+	}
-+
-+#ifdef CONFIG_FB_SIS_300
-+	/* TW: Mode numbers for 1280x768 are different for 300 and 315 series */
- 	if(sisvga_engine == SIS_300_VGA) {
--		sisbios_mode[MODEINDEX_1280x960].mode_no = 0x6e;
--		sisbios_mode[MODEINDEX_1280x960+1].mode_no = 0x6f;
--		sisbios_mode[MODEINDEX_1280x960+2].mode_no = 0x7b;
--		sisbios_mode[MODEINDEX_1280x960+3].mode_no = 0x7b;
-+		sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
-+		sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
-+		sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
-+		sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
- 	}
-+#endif
- 
- 	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
- 	if (sishw_ext.pSR == NULL) {
-@@ -4167,121 +4595,54 @@ int __init sisfb_init(void)
- 	}
- 
- 	ivideo.mtrr = (unsigned int) 0;
-+	
-+	ivideo.vbflags = 0;
- 
- 	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
--
--#ifdef CONFIG_FB_SIS_300
--		if (sisvga_engine == SIS_300_VGA) {
--			sisfb_get_VB_type_300();
--		}
--#endif
--
--#ifdef CONFIG_FB_SIS_315
--		if (sisvga_engine == SIS_315_VGA) {
--			sisfb_get_VB_type_315();
--		}
--#endif
--
-+	
- 		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
- 		sishw_ext.Is301BDH = FALSE;
- 		sishw_ext.usExternalChip = 0;
--
--		switch (ivideo.hasVB) {
--
--		case HASVB_301:
--		        inSISIDXREG(SISPART4, 0x01, reg);
--			if (reg >= 0xE0) {
--				sishw_ext.ujVBChipID = VB_CHIP_302LV;
--				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
--	  		} else if (reg >= 0xD0) {
--				sishw_ext.ujVBChipID = VB_CHIP_301LV;
--				printk(KERN_INFO "sisfb: SiS301LV bridge detected (revision 0x%02x)\n",reg);
--	  		} else if (reg >= 0xB0) {
--				sishw_ext.ujVBChipID = VB_CHIP_301B;
--				inSISIDXREG(SISPART4,0x23,reg1);
--				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
--				printk(KERN_INFO "sisfb: SiS301B%s bridge detected (revision 0x%02x)\n",
--					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
--			} else {
--				sishw_ext.ujVBChipID = VB_CHIP_301;
--				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
--			}
--			break;
--		case HASVB_302:
--		        inSISIDXREG(SISPART4, 0x01, reg);
--			if (reg >= 0xE0) {
--				sishw_ext.ujVBChipID = VB_CHIP_302LV;
--				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
--	  		} else if (reg >= 0xD0) {
--				sishw_ext.ujVBChipID = VB_CHIP_301LV;
--				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
--	  		} else if (reg >= 0xB0) {
--				inSISIDXREG(SISPART4,0x23,reg1);
--				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
--			        sishw_ext.ujVBChipID = VB_CHIP_302B;
--				printk(KERN_INFO "sisfb: SiS302B%s bridge detected (revision 0x%02x)\n",
--					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
--			} else {
--			        sishw_ext.ujVBChipID = VB_CHIP_302;
--				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
--			}
--			break;
--		case HASVB_LVDS:
--			sishw_ext.usExternalChip = 0x1;
--			printk(KERN_INFO "sisfb: LVDS transmitter detected\n");
--			break;
--		case HASVB_TRUMPION:
--			sishw_ext.usExternalChip = 0x2;
--			printk(KERN_INFO "sisfb: Trumpion Zurac LVDS scaler detected\n");
--			break;
--		case HASVB_CHRONTEL:
--			sishw_ext.usExternalChip = 0x4;
--			printk(KERN_INFO "sisfb: Chrontel TV encoder detected\n");
--			break;
--		case HASVB_LVDS_CHRONTEL:
--			sishw_ext.usExternalChip = 0x5;
--			printk(KERN_INFO "sisfb: LVDS transmitter and Chrontel TV encoder detected\n");
--			break;
--		default:
--			printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
--			break;
--		}
--
--		if (ivideo.hasVB != HASVB_NONE) {
--#ifdef CONFIG_FB_SIS_300
--		      if (sisvga_engine == SIS_300_VGA) {
--				sisfb_detect_VB_connect_300();
--                      }
--#endif
--#ifdef CONFIG_FB_SIS_315
--		      if (sisvga_engine == SIS_315_VGA) {
--				sisfb_detect_VB_connect_315();
--                      }
--#endif
-+	
-+		sisfb_get_VB_type();
-+		
-+		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-+			sisfb_detect_VB_connect();
- 		}
--
--		if (ivideo.disp_state & DISPTYPE_DISP2) {
--			if (sisfb_crt1off)
--				ivideo.disp_state |= DISPMODE_SINGLE;
--			else
--				ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
--		} else {
--			ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
-+		
-+		ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
-+		
-+		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-+		   if(sisfb_crt2type != -1) {
-+		      if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
-+		         ivideo.currentvbflags |= CRT2_LCD;
-+		      } else if(sisfb_crt2type != CRT2_LCD) {
-+		         ivideo.currentvbflags |= sisfb_crt2type;
-+		      }
-+		   } else {
-+		      /* Chrontel 700x TV detection often unreliable, therefore use a
-+		       * different default order on such machines
-+		       */
-+		      if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
-+		         if(ivideo.vbflags & CRT2_LCD)      ivideo.currentvbflags |= CRT2_LCD;
-+		         else if(ivideo.vbflags & CRT2_TV)  ivideo.currentvbflags |= CRT2_TV;
-+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
-+		      } else {
-+		         if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
-+		         else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
-+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
-+		      }
-+		   }
- 		}
- 
--		if (ivideo.disp_state & DISPTYPE_LCD) {
--		    if (!enable_dstn) {
--		        inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
--			reg &= 0x0f;
--			if (sisvga_engine == SIS_300_VGA) {
--			    sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
--			} else {
--			    sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
--			}
--		    } else {
--		        /* TW: FSTN/DSTN */
--			sishw_ext.ulCRT2LCDType = LCD_320x480;
--		    }
-+		if(ivideo.vbflags & CRT2_LCD) {
-+		   inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
-+		   reg &= 0x0f;
-+		   if(sisvga_engine == SIS_300_VGA) {
-+		      sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
-+		   } else {
-+		      sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
-+		   }
- 		}
- 		
- 		sisfb_detectedpdc = 0;
-@@ -4289,9 +4650,7 @@ int __init sisfb_init(void)
- #ifdef CONFIG_FB_SIS_300
-                 /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
- 		if(sisvga_engine == SIS_300_VGA) {
--	          if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
--		     (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
--		     (sishw_ext.Is301BDH)) {		     /* 301B-DH */
-+	          if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
- 		       int tmp;
- 		       inSISIDXREG(SISCR,0x30,tmp);
- 		       if(tmp & 0x20) {
-@@ -4320,54 +4679,57 @@ int __init sisfb_init(void)
- #ifdef CONFIG_FB_SIS_315
-                 /* TW: Try to find about LCDA */
- 		if(sisvga_engine == SIS_315_VGA) {
--	          if((sishw_ext.ujVBChipID == VB_CHIP_302B) ||
--		     (sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
--		     (sishw_ext.ujVBChipID == VB_CHIP_302LV)) {
--		       int tmp;
--		       inSISIDXREG(SISCR,0x34,tmp);
--		       if(tmp <= 0x13) {	
--		          /* Currently on LCDA? (Some BIOSes leave CR38) */
--		          inSISIDXREG(SISCR,0x38,tmp);
--			  if((tmp & 0x03) == 0x03) {
--			     SiS_Pr.SiS_UseLCDA = TRUE;
--			  } else {
--			     /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
--			     inSISIDXREG(SISCR,0x35,tmp);
--			     if(tmp & 0x01) {
--			        SiS_Pr.SiS_UseLCDA = TRUE;
--			     } else {
--			        /* Currently on LCD? If so, we can find out 
--				   by peeking the mode register 
--				 */
--			        inSISIDXREG(SISCR,0x30,tmp);
--			        if(tmp & 0x20) {
--			           inSISIDXREG(SISPART1,0x13,tmp);
--				   if(tmp & 0x04) {
--				      SiS_Pr.SiS_UseLCDA = TRUE;
--				   }
--			        }
--			     }
--			  }
--		       } 
--		       if(SiS_Pr.SiS_UseLCDA) {
--		          sisfb_detectedlcda = 0x03;
--		          printk(KERN_INFO
--			         "sisfb: Bridge uses LCDA for low resolution and text modes\n");
--		       }
-+		   if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
-+		      int tmp;
-+		      inSISIDXREG(SISCR,0x34,tmp);
-+		      if((tmp <= 0x13) || (tmp == 0xff)) {
-+		         /* Currently on LCDA? (Some BIOSes leave CR38) */
-+		         inSISIDXREG(SISCR,0x38,tmp);
-+			 if((tmp & 0x03) == 0x03)  SiS_Pr.SiS_UseLCDA = TRUE;
-+			 else {
-+			    /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
-+			    inSISIDXREG(SISCR,0x35,tmp);
-+			    if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
-+			    else {
-+			       /* Currently on LCD? If so, we can find out
-+			        * by peeking the mode register
-+				*/
-+			       inSISIDXREG(SISCR,0x30,tmp);
-+			       if(tmp & 0x20) {
-+			          inSISIDXREG(SISPART1,0x13,tmp);
-+				  if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
-+			       }
-+			    }
-+			 }
-+		      }
-+		      if(SiS_Pr.SiS_UseLCDA) {
-+		         sisfb_detectedlcda = 0x03;
-+		         printk(KERN_INFO
-+			        "sisfb: Bridge uses LCDA for low resolution and text modes\n");
-+		      }
- 	          }
- 		}
- #endif
- #endif
- 
-+		if (!sisfb_crt1off) {
-+		   	sisfb_handle_ddc(&sisfb_thismonitor, 0);
-+		} else {
-+		   	if ((ivideo.vbflags & (VB_301|VB_301B|VB_302B)) &&
-+		      	    (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
-+		      		sisfb_handle_ddc(&sisfb_thismonitor, 1);
-+		   	}
-+		}
-+
- 		if (sisfb_mode_idx >= 0)
--			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
-+			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
- 
- 		if (sisfb_mode_idx < 0) {
--			switch (ivideo.disp_state & DISPTYPE_DISP2) {
--			   case DISPTYPE_LCD:
-+			switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
-+			   case CRT2_LCD:
- 				sisfb_mode_idx = DEFAULT_LCDMODE;
- 				break;
--			   case DISPTYPE_TV:
-+			   case CRT2_TV:
- 				sisfb_mode_idx = DEFAULT_TVMODE;
- 				break;
- 			   default:
-@@ -4379,39 +4741,27 @@ int __init sisfb_init(void)
- 		sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
- 
- 		if (ivideo.refresh_rate != 0)
--			sisfb_search_refresh_rate(ivideo.refresh_rate);
-+			sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
- 
- 		if (sisfb_rate_idx == 0) {
- 			sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
- 			ivideo.refresh_rate = 60;
- 		}
- 
-+		if (sisfb_thismonitor.datavalid) {
-+			if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
-+			                      sisfb_rate_idx, ivideo.refresh_rate)) {
-+				printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-+			}
-+		}
-+
- 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
- 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
- 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
- 		ivideo.org_x = ivideo.org_y = 0;
- 		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
--		switch(ivideo.video_bpp) {
--        	case 8:
--            		ivideo.DstColor = 0x0000;
--	    		ivideo.SiS310_AccelDepth = 0x00000000;
--			ivideo.video_cmap_len = 256;
--            		break;
--        	case 16:
--            		ivideo.DstColor = 0x8000;
--            		ivideo.SiS310_AccelDepth = 0x00010000;
--			ivideo.video_cmap_len = 16;
--            		break;
--        	case 32:
--            		ivideo.DstColor = 0xC000;
--	    		ivideo.SiS310_AccelDepth = 0x00020000;
--			ivideo.video_cmap_len = 16;
--            		break;
--		default:
--			ivideo.video_cmap_len = 16;
--		        printk(KERN_INFO "sisfb: Unsupported depth %d", ivideo.video_bpp);
--			break;
--    		}
-+		
-+		sisfb_set_vparms();
- 		
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
- 
-@@ -4424,23 +4774,45 @@ int __init sisfb_init(void)
- 		sisfb_pre_setmode();
- 
- 		if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
--			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed, using default mode\n", 
-+			printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
- 				sisfb_mode_no);
--			return -1;
-+			vfree(sishw_ext.pSR);
-+			vfree(sishw_ext.pCR);
-+			release_mem_region(ivideo.video_base, ivideo.video_size);
-+			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-+			return -EINVAL;
- 		}
- 
- 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- 
- 		sisfb_post_setmode();
-+		
-+		ivideo.accel = 0;
-+		if(sisfb_accel) {
-+		   ivideo.accel = -1;
-+		   default_var.accel_flags |= FB_ACCELF_TEXT;
-+		   sisfb_initaccel();
-+		}
- 
- 		sisfb_crtc_to_var(&default_var);
- 		
-+		sis_fb_info.node = -1;
-+		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
-+		sis_fb_info.blank = &sisfb_blank;
-+		sis_fb_info.fbops = &sisfb_ops;
-+		sis_fb_info.switch_con = &sisfb_switch;
-+		sis_fb_info.updatevar = &sisfb_update_var;
-+		sis_fb_info.changevar = NULL;
-+		sis_fb_info.disp = &sis_disp;
-+			
-+		sisfb_set_disp(-1, &default_var, &sis_fb_info);
-+		
- #else		/* --------- For 2.5: Setup a somewhat sane default var ------------ */
- 
- 		printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
- 	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
- 			ivideo.refresh_rate);
--			
-+
- 		default_var.xres = default_var.xres_virtual = ivideo.video_width;
- 		default_var.yres = default_var.yres_virtual = ivideo.video_height;
- 		default_var.bits_per_pixel = ivideo.video_bpp;
-@@ -4457,50 +4829,26 @@ int __init sisfb_init(void)
- 			 &default_var.upper_margin, &default_var.lower_margin,
- 			 &default_var.hsync_len, &default_var.vsync_len,
- 			 &default_var.sync, &default_var.vmode)) {
--			 
--		   if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
--		      default_var.yres <<= 1;
--		      default_var.yres_virtual <<= 1;
--		   } else if((default_var.vmode	& FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
--		      default_var.pixclock >>= 1;
--		      default_var.yres >>= 1;
--		      default_var.yres_virtual >>= 1;
--		   }
--		   
-+			if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-+				default_var.pixclock <<= 1;
-+	   		}
- 	        }
--#ifdef SISFB_PAN
--		if(sisfb_ypan) {
--	    		default_var.yres_virtual = 
--				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
--	    		if(default_var.yres_virtual <= default_var.yres) {
--	        		default_var.yres_virtual = default_var.yres;
--	    		}
--		} 
--#endif
- 		
--#endif
--
- 		ivideo.accel = 0;
- 		if(sisfb_accel) {
- 		   ivideo.accel = -1;
- 		   default_var.accel_flags |= FB_ACCELF_TEXT;
- 		   sisfb_initaccel();
- 		}
-+		
-+		if(sisfb_ypan) {
-+	    		default_var.yres_virtual = 
-+				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
-+	    		if(default_var.yres_virtual <= default_var.yres) {
-+	        		default_var.yres_virtual = default_var.yres;
-+	    		}
-+		} 
- 
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		/* ---- 2.4 series init ---- */
--		sis_fb_info.node = -1;
--		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
--		sis_fb_info.blank = &sisfb_blank;
--		sis_fb_info.fbops = &sisfb_ops;
--		sis_fb_info.switch_con = &sisfb_switch;
--		sis_fb_info.updatevar = &sisfb_update_var;
--		sis_fb_info.changevar = NULL;
--		sis_fb_info.disp = &sis_disp;
--			
--		sisfb_set_disp(-1, &default_var, &sis_fb_info);
--#endif
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		/* ---- 2.5 series init ---- */
- 		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
- 		sis_fb_info.var = default_var;
- 		sis_fb_info.fix = sisfb_fix;
-@@ -4513,6 +4861,8 @@ int __init sisfb_init(void)
- 		fb_alloc_cmap(&sis_fb_info.cmap, 256 , 0);
- #endif
- 
-+		printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
-+
- #ifdef CONFIG_MTRR
- 		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
- 				(unsigned int) ivideo.video_size,
-@@ -4526,11 +4876,17 @@ int __init sisfb_init(void)
- 		vc_resize_con(1, 1, 0);
- #endif
- 
--		TWDEBUG("Before calling register_framebuffer");
--		
--		if(register_framebuffer(&sis_fb_info) < 0)
-+		if(register_framebuffer(&sis_fb_info) < 0) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+			vfree(sishw_ext.pSR);
-+			vfree(sishw_ext.pCR);
-+			release_mem_region(ivideo.video_base, ivideo.video_size);
-+			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-+#endif
-+			printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
- 			return -EINVAL;
--			
-+		}
-+
- 		sisfb_registered = 1;			
- 
- 		printk(KERN_INFO "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
-@@ -4547,9 +4903,11 @@ int __init sisfb_init(void)
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
--	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);			     
-+	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
- #endif
- 
-+		printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer. All rights reserved.\n");
-+
- 	}	/* TW: if mode = "none" */
- 	return 0;
- }
-@@ -4562,7 +4920,6 @@ static int          vesa = -1;
- static unsigned int rate = 0;
- static unsigned int crt1off = 1;
- static unsigned int mem = 0;
--static unsigned int dstn = 0;
- static char         *forcecrt2type = NULL;
- static int          forcecrt1 = -1;
- static char         *queuemode = NULL;
-@@ -4575,25 +4932,31 @@ static int          inverse = 0;
- static int          userom = 1;
- static int          useoem = -1;
- static char         *tvstandard = NULL;
-+static int	    nocrt2rate = 0;
- 
--MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
-+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330/660 framebuffer driver");
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("SiS; Thomas Winischhofer <thomas@winischhofer.net>; Various others");
-+MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- MODULE_PARM(mode, "s");
- MODULE_PARM_DESC(mode,
-        "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
--         "800x600x16 (default: none if sisfb is a module; this leaves the\n"
--	 "console untouched and the driver will only do the video memory\n"
--	 "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
-+         "1024x768x16. Other formats supported include XxY-Depth and\n"
-+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
-+	 "number, it will be interpreted as a VESA mode number. (default: none if\n"
-+	 "sisfb is a module; this leaves the console untouched and the driver will\n"
-+	 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
-+	 "is in the kernel)");
- #endif
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
- MODULE_PARM(mode, "s");
- MODULE_PARM_DESC(mode,
--       "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
--         "eg. 1024x768x16 (default: 800x600x8)");
--#endif	 
-+       "\nSelects the desired default display mode in the format XxYxDepth,\n"
-+         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
-+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
-+	 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
-+#endif
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- MODULE_PARM(vesa, "i");
-@@ -4603,17 +4966,18 @@ MODULE_PARM_DESC(vesa,
- 	 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
- 	 "0x0103 if sisfb is in the kernel)");
- #endif
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- MODULE_PARM(vesa, "i");
- MODULE_PARM_DESC(vesa,
-        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
-          "0x117 (default: 0x0103)");
--#endif	 
-+#endif
- 
- MODULE_PARM(rate, "i");
- MODULE_PARM_DESC(rate,
- 	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
--	"(default: 60)");
-+	  "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
-+	  "will be ignored (default: 60)");
- 
- MODULE_PARM(crt1off,   "i");
- MODULE_PARM_DESC(crt1off,
-@@ -4624,14 +4988,9 @@ MODULE_PARM_DESC(filter,
- 	"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
- 	  "(Possible values 0-7, default: [no filter])");
- 
--MODULE_PARM(dstn,   "i");
--MODULE_PARM_DESC(dstn,
--	"\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
--	  "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
--
- MODULE_PARM(queuemode,   "s");
- MODULE_PARM_DESC(queuemode,
--	"\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
-+	"\nSelects the queue mode on 315/550/650/740/330/660. Possible choices are AGP, VRAM,\n"
-   	  "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
- 	  "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
- 	  "require a totally different way of programming the engines. If any mode than\n"
-@@ -4673,56 +5032,61 @@ MODULE_PARM_DESC(pdc,
- MODULE_PARM(noaccel, "i");
- MODULE_PARM_DESC(noaccel,
-         "\nIf set to anything other than 0, 2D acceleration and y-panning will be\n"
--	"disabled. (default: 0)");
-+	  "disabled. (default: 0)");
- 
- MODULE_PARM(noypan, "i");
- MODULE_PARM_DESC(noypan,
-         "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
--	"will be performed by redrawing the screen. This required 2D acceleration, so\n"
--	"if the option noaccel is set, y-panning will be disabled. (default: 0)");
-+ 	  "will be performed by redrawing the screen. This required 2D acceleration, so\n"
-+	  "if the option noaccel is set, y-panning will be disabled. (default: 0)");
- 
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
- MODULE_PARM(inverse, "i");
- MODULE_PARM_DESC(inverse,
-         "\nSetting this to anything but 0 should invert the display colors, but this\n"
--	"does not seem to work. (default: 0)");
-+	  "does not seem to work. (default: 0)");
- #endif	
- 
- MODULE_PARM(userom, "i");
- MODULE_PARM_DESC(userom,
-         "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
--	"for some LCD and TV setup. (default: 1)");
-+	  "for some LCD and TV setup. (default: 1)");
- 
- MODULE_PARM(useoem, "i");
- MODULE_PARM_DESC(useoem,
-         "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
--	"panels and TV connector types. (default: auto)");
-+	  "panels and TV connector types. (default: auto)");
- 
- MODULE_PARM(tvstandard, "s");
- MODULE_PARM_DESC(tvstandard,
- 	"\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
--	"pal and ntsc. (default: auto)");
-+	  "pal and ntsc. (default: auto)");
- 
-+MODULE_PARM(nocrt2rate, "i");
-+MODULE_PARM_DESC(nocrt2rate,
-+	"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
-+	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as crt1)");
-+	
- int init_module(void)
- {
- 	int err;
--	
-+
-+	ivideo.refresh_rate = sisfb_parm_rate = rate;
-+
- 	if(mode)
--		sisfb_search_mode(mode);
-+		sisfb_search_mode(mode, FALSE);
- 	else if(vesa != -1)
--		sisfb_search_vesamode(vesa);
--	else  
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-+		sisfb_search_vesamode(vesa, FALSE);
-+	else
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- 		/* For 2.4, set mode=none if no mode is given  */
- 		sisfb_mode_idx = MODE_INDEX_NONE;
- #endif
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
--		/* For 2.5, we don't need this "mode=none" stuff anymore */	
-+		/* For 2.5, we don't need this "mode=none" stuff anymore */
- 		sisfb_mode_idx = DEFAULT_MODE;
- #endif
- 
--	ivideo.refresh_rate = rate;
--
- 	if(forcecrt2type)
- 		sisfb_search_crt2type(forcecrt2type);
- 
-@@ -4745,9 +5109,6 @@ int init_module(void)
- 
- 	if(noypan == 1)       sisfb_ypan = 0;
- 	else if(noypan == 0)  sisfb_ypan = 1;
--
--	/* TW: Panning only with acceleration */
--	if(sisfb_accel == 0)  sisfb_ypan = 0;
- 	
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- 	if(inverse)           sisfb_inverse = 1;
-@@ -4759,17 +5120,11 @@ int init_module(void)
- 
- 	sisfb_useoem = useoem;
- 
--	enable_dstn = dstn;
--
--	/* TW: DSTN overrules forcecrt2type */
--	if (enable_dstn)      sisfb_crt2type = DISPTYPE_LCD;
--
- 	if (queuemode)        sisfb_search_queuemode(queuemode);
- 	
- 	/* TW: If other queuemode than MMIO, disable 2D accel and ypan */
- 	if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
- 	        sisfb_accel = 0;
--		sisfb_ypan = 0;
- 	}
- 
-         if(pdc) {
-@@ -4777,6 +5132,8 @@ int init_module(void)
- 	        sisfb_pdc = pdc & 0x3c;
- 	   }
- 	}
-+	
-+	sisfb_nocrt2rate = nocrt2rate;
- 
- 	if((err = sisfb_init()) < 0) return err;
- 
-@@ -4788,7 +5145,7 @@ void cleanup_module(void)
- 	/* TW: Release mem regions */
- 	release_mem_region(ivideo.video_base, ivideo.video_size);
- 	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
--	
-+
- #ifdef CONFIG_MTRR
- 	/* TW: Release MTRR region */
- 	if(ivideo.mtrr) {
-@@ -4802,11 +5159,17 @@ void cleanup_module(void)
- 	if(sisfb_registered) {
- 		unregister_framebuffer(&sis_fb_info);
- 	}
--	
-+
- 	if(sishw_ext.pSR) vfree(sishw_ext.pSR);
- 	if(sishw_ext.pCR) vfree(sishw_ext.pCR);
- 	
--	/* TODO: Restore the initial mode */
-+	/* TODO: Restore the initial mode 
-+	 * This sounds easy but is as good as impossible
-+	 * on many machines with SiS chip and video bridge
-+	 * since text modes are always set up differently
-+	 * from machine to machine. Depends on the type
-+	 * of integration between chipset and bridge.
-+	 */
- 	
- 	printk(KERN_INFO "sisfb: Module unloaded\n");
- }
---- linux-2.6.0-test1/drivers/video/sis/sis_main.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/drivers/video/sis/sis_main.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,8 +1,6 @@
- #ifndef _SISFB_MAIN
- #define _SISFB_MAIN
- 
--/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
--
- #include "vstruct.h"
- 
- /* ------------------- Constant Definitions ------------------------- */
-@@ -14,11 +12,11 @@
- 
- #define VER_MAJOR                 1
- #define VER_MINOR                 6
--#define VER_LEVEL                 1
-+#define VER_LEVEL                 11
- 
- #include "sis.h"
- 
--/* TW: To be included in pci_ids.h */
-+/* To be included in pci_ids.h */
- #ifndef PCI_DEVICE_ID_SI_650_VGA
- #define PCI_DEVICE_ID_SI_650_VGA  0x6325
- #endif
-@@ -31,6 +29,12 @@
- #ifndef PCI_DEVICE_ID_SI_330
- #define PCI_DEVICE_ID_SI_330      0x0330
- #endif
-+#ifndef PCI_DEVICE_ID_SI_660
-+#define PCI_DEVICE_ID_SI_660      0x0660
-+#endif
-+#ifndef PCI_DEVICE_ID_SI_660_VGA
-+#define PCI_DEVICE_ID_SI_660_VGA  0x6330
-+#endif
- 
- /* To be included in fb.h */
- #ifndef FB_ACCEL_SIS_GLAMOUR_2
-@@ -59,7 +63,6 @@
- #define COMMAND_QUEUE_THRESHOLD   0x1F
- #endif
- 
--/* TW */
- #define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
- #define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
- 
-@@ -283,45 +286,43 @@
- /* Fbcon variables */
- static struct fb_info sis_fb_info;
- 
--static int    video_type = FB_TYPE_PACKED_PIXELS;
--
- static struct fb_var_screeninfo default_var = {
--	.xres		= 0,
--	.yres		= 0,
--	.xres_virtual	= 0,
--	.yres_virtual	= 0,
--	.xoffset	= 0,
--	.yoffset	= 0,
--	.bits_per_pixel	= 0,
--	.grayscale	= 0,
--	.red		= {0, 8, 0},
--	.green		= {0, 8, 0},
--	.blue		= {0, 8, 0},
--	.transp		= {0, 0, 0},
--	.nonstd		= 0,
--	.activate	= FB_ACTIVATE_NOW,
--	.height		= -1,
--	.width		= -1,
--	.accel_flags	= 0,
--	.pixclock	= 0,
--	.left_margin	= 0,
--	.right_margin	= 0,
--	.upper_margin	= 0,
--	.lower_margin	= 0,
--	.hsync_len	= 0,
--	.vsync_len	= 0,
--	.sync		= 0,
--	.vmode		= FB_VMODE_NONINTERLACED,
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
--	.reserved	= {0, 0, 0, 0, 0, 0}
--#endif	
-+	.xres            = 0,
-+	.yres            = 0,
-+	.xres_virtual    = 0,
-+	.yres_virtual    = 0,
-+	.xoffset         = 0,
-+	.yoffset         = 0,
-+	.bits_per_pixel  = 0,
-+	.grayscale       = 0,
-+	.red             = {0, 8, 0},
-+	.green           = {0, 8, 0},
-+	.blue            = {0, 8, 0},
-+	.transp          = {0, 0, 0},
-+	.nonstd          = 0,
-+	.activate        = FB_ACTIVATE_NOW,
-+	.height          = -1,
-+	.width           = -1,
-+	.accel_flags     = 0,
-+	.pixclock        = 0,
-+	.left_margin     = 0,
-+	.right_margin    = 0,
-+	.upper_margin    = 0,
-+	.lower_margin    = 0,
-+	.hsync_len       = 0,
-+	.vsync_len       = 0,
-+	.sync            = 0,
-+	.vmode           = FB_VMODE_NONINTERLACED,
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-+	.reserved        = {0, 0, 0, 0, 0, 0}
-+#endif
- };
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- static struct fb_fix_screeninfo sisfb_fix = {
- 	.id		= "SiS",
- 	.type		= FB_TYPE_PACKED_PIXELS,
--	.xpanstep	= 1,
-+	.xpanstep	= 0,
- 	.ypanstep	= 1,
- };
- static char myid[20];
-@@ -347,26 +348,24 @@ static union {
- } sis_fbcon_cmap;
- 
- static int sisfb_inverse = 0;
-+static int currcon = 0;
- #endif
- 
--/* display status */
-+/* global flags */
- static int sisfb_off = 0;
- static int sisfb_crt1off = 0;
- static int sisfb_forcecrt1 = -1;
- static int sisvga_enabled = 0;
- static int sisfb_userom = 1;
- static int sisfb_useoem = -1;
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
--static int currcon = 0;
--#endif
--
--/* global flags */
--static int sisfb_registered;
--static int sisfb_tvmode = 0;
-+static int sisfb_parm_rate = -1;
-+static int sisfb_registered = 0;
- static int sisfb_mem = 0;
- static int sisfb_pdc = 0;
--static int enable_dstn = 0;
- static int sisfb_ypan = -1;
-+static int sisfb_nocrt2rate = 0;
-+static int sisfb_dstn = 0;
-+static int sisfb_fstn = 0;
- 
- VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
- int 	   sisfb_accel = -1;
-@@ -375,22 +374,22 @@ int 	   sisfb_accel = -1;
- static int sisfb_hwcursor_size = 0;
- static int sisfb_CRT2_write_enable = 0;
- 
--int sisfb_crt2type  = -1;	/* TW: CRT2 type (for overriding autodetection) */
--int sisfb_tvplug    = -1;	/* PR: Tv plug type (for overriding autodetection) */
-+int sisfb_crt2type  = -1;	/* CRT2 type (for overriding autodetection) */
-+int sisfb_tvplug    = -1;	/* Tv plug type (for overriding autodetection) */
- 
--int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310/325 series only) */
-+int sisfb_queuemode = -1; 	/* Use MMIO queue mode by default (315 series only) */
- 
- unsigned char sisfb_detectedpdc = 0;
- 
- unsigned char sisfb_detectedlcda = 0xff;
- 
--/* data for sis components */
-+/* data for sis hardware ("par") */
- struct video_info ivideo;
- 
--/* TW: For ioctl SISFB_GET_INFO */
-+/* For ioctl SISFB_GET_INFO */
- sisfb_info sisfbinfo;
- 
--/* TW: Hardware extension; contains data on hardware */
-+/* Hardware extension; contains data on hardware */
- HW_DEVICE_EXTENSION sishw_ext = {
- 	NULL, NULL, FALSE, NULL, NULL,
- 	0, 0, 0, 0, 0, 0, 0, 0, 0,
-@@ -399,10 +398,10 @@ HW_DEVICE_EXTENSION sishw_ext = {
- 	0
- };
- 
--/* TW: SiS private structure */
-+/* SiS private structure */
- SiS_Private  SiS_Pr;
- 
--/* card parameters */
-+/* Card parameters */
- static unsigned long sisfb_mmio_size = 0;
- static u8            sisfb_caps = 0;
- 
-@@ -412,7 +411,7 @@ typedef enum _SIS_CMDTYPE {
- 	VM_CMD_QUEUE,
- } SIS_CMDTYPE;
- 
--/* Supported SiS Chips list */
-+/* List of supported chips */
- static struct board {
- 	u16 vendor, device;
- 	const char *name;
-@@ -426,14 +425,15 @@ static struct board {
- 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
- 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
- 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
-+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 660 VGA"},
- 	{0, 0, NULL}
- };
- 
- #define MD_SIS300 1
- #define MD_SIS315 2
- 
--/* mode table */
--/* NOT const - will be patched for 1280x960 mode number chaos reasons */
-+/* Mode table */
-+/* NOT const - will be patched for 1280x768 mode number chaos reasons */
- struct _sisbios_mode {
- 	char name[15];
- 	u8 mode_no;
-@@ -447,14 +447,33 @@ struct _sisbios_mode {
- 	u16 rows;
- 	u8  chipset;
- } sisbios_mode[] = {
--#define MODE_INDEX_NONE           0  /* TW: index for mode=none */
--	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},  /* TW: for mode "none" */
--	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,           MD_SIS315},
--	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
--	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
--	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
-+#define MODE_INDEX_NONE           0  /* index for mode=none */
-+	{"none",         0xff, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},
-+	{"320x200x8",    0x59, 0x0138, 0x0000,  320,  200,  8, 1,  40, 12, MD_SIS300|MD_SIS315},
-+	{"320x200x16",   0x41, 0x010e, 0x0000,  320,  200, 16, 1,  40, 12, MD_SIS300|MD_SIS315},
-+	{"320x200x24",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
-+	{"320x200x32",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},
-+	{"320x240x8",    0x50, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15, MD_SIS300|MD_SIS315},
-+	{"320x240x16",   0x56, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
-+	{"320x240x24",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-+	{"320x240x32",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
-+	{"320x240x8",    0x5a, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-+	{"320x240x16",   0x5b, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-+	{"400x300x8",    0x51, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
-+	{"400x300x16",   0x57, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
-+	{"400x300x24",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
-+	{"400x300x32",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
-+	{"512x384x8",    0x52, 0x0000, 0x0000,  512,  384,  8, 1,  64, 24, MD_SIS300|MD_SIS315},
-+	{"512x384x16",   0x58, 0x0000, 0x0000,  512,  384, 16, 1,  64, 24, MD_SIS300|MD_SIS315},
-+	{"512x384x24",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
-+	{"512x384x32",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
-+	{"640x400x8",    0x2f, 0x0000, 0x0000,  640,  400,  8, 1,  80, 25, MD_SIS300|MD_SIS315},
-+	{"640x400x16",   0x5d, 0x0000, 0x0000,  640,  400, 16, 1,  80, 25, MD_SIS300|MD_SIS315},
-+	{"640x400x24",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
-+	{"640x400x32",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
-+	{"640x480x8",    0x2e, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
- 	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
--	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
-+	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
- 	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
- 	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
- 	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
-@@ -468,59 +487,79 @@ struct _sisbios_mode {
- 	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
- 	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
- 	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
--#define DEFAULT_MODE              20 /* TW: index for 800x600x8 */
--#define DEFAULT_LCDMODE           20 /* TW: index for 800x600x8 */
--#define DEFAULT_TVMODE            20 /* TW: index for 800x600x8 */
-+#define DEFAULT_MODE              39 /* index for 800x600x8 */
-+#define DEFAULT_LCDMODE           39 /* index for 800x600x8 */
-+#define DEFAULT_TVMODE            39 /* index for 800x600x8 */
- 	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
- 	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
- 	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
- 	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
-+	{"848x480x8",    0x39, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
-+	{"848x480x16",   0x3b, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
-+	{"848x480x24",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
-+	{"848x480x32",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
-+	{"856x480x8",    0x3f, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
-+	{"856x480x16",   0x42, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
-+	{"856x480x24",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
-+	{"856x480x32",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
- 	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
- 	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
- 	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
- 	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
--	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },  /* TW: 300 series only */
-+	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
- 	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
- 	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
- 	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
- 	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
--	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
-+	{"1024x768x16",  0x4a, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
- 	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
- 	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
--	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },  /* TW: 300 series only */
-+	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
- 	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
- 	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
- 	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
-+	{"1152x864x8",   0x29, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
-+	{"1152x864x16",  0x2a, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
-+	{"1152x864x24",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
-+	{"1152x864x32",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
- 	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
- 	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
- 	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
- 	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
--	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_SIS315},  /* TW: 310/325 series only */
--	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_SIS315},
--	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
--	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
--#define MODEINDEX_1280x960 48
--	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},  /* TW: Modenumbers being patched */
--	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
--	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
--	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
--	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
--	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
-+#define MODEINDEX_1280x768 75
-+	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
-+	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
-+	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-+	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
-+	{"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315}, 
-+	{"1280x960x16",  0x7d, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
-+	{"1280x960x24",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-+	{"1280x960x32",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-+	{"1280x1024x8",  0x3a, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
-+	{"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
- 	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
- 	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
--	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},  /* TW: 310/325 series only */
-+	{"1360x768x8",   0x48, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
-+	{"1360x768x16",  0x4b, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
-+	{"1360x768x24",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
-+	{"1360x768x32",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
-+	{"1360x1024x8",  0x67, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
-+	{"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
-+	{"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-+	{"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
-+	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
- 	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
- 	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
- 	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
--	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
--	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
-+	{"1600x1200x8",  0x3c, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
-+	{"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
- 	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
- 	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
- 	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
- 	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
--	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
--	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
--	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},  /* TW: 310/325 series only */
-+	{"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-+	{"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-+	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
- 	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
- 	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
- 	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
-@@ -538,37 +577,45 @@ u8  sisfb_rate_idx = 0;
- 
- /* TW: CR36 evaluation */
- const USHORT sis300paneltype[] =
--    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
--      LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
--      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768,
--      LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
-+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
-+      LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
-+      LCD_1024x768,   LCD_1024x768,  LCD_1024x768,  LCD_1024x768,
-+      LCD_1024x768,  LCD_1024x768,  LCD_320x480,   LCD_1024x768 };
- 
- const USHORT sis310paneltype[] =
--    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
--      LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
--      LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
--      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
-+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
-+      LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
-+      LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
-+      LCD_640x480_2, LCD_640x480_3, LCD_320x480,   LCD_1024x768 };
-+
-+#define FL_550_DSTN 0x01
-+#define FL_550_FSTN 0x02
- 
- static const struct _sis_crt2type {
- 	char name[10];
- 	int type_no;
- 	int tvplug_no;
-+	unsigned short flags;
- } sis_crt2type[] = {
--	{"NONE", 	0, 		-1},
--	{"LCD",  	DISPTYPE_LCD, 	-1},
--	{"TV",   	DISPTYPE_TV, 	-1},
--	{"VGA",  	DISPTYPE_CRT2, 	-1},
--	{"SVIDEO", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
--	{"COMPOSITE", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
--	{"SCART", 	DISPTYPE_TV, 	TVPLUG_SCART},
--	{"none", 	0, 		-1},
--	{"lcd",  	DISPTYPE_LCD, 	-1},
--	{"tv",   	DISPTYPE_TV, 	-1},
--	{"vga",  	DISPTYPE_CRT2, 	-1},
--	{"svideo", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
--	{"composite", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
--	{"scart", 	DISPTYPE_TV, 	TVPLUG_SCART},
--	{"\0",  	-1, 		-1}
-+	{"NONE", 	0, 		-1,        0},
-+	{"LCD",  	CRT2_LCD, 	-1,        0},
-+	{"TV",   	CRT2_TV, 	-1,        0},
-+	{"VGA",  	CRT2_VGA, 	-1,        0},
-+	{"SVIDEO", 	CRT2_TV, 	TV_SVIDEO, 0},
-+	{"COMPOSITE", 	CRT2_TV, 	TV_AVIDEO, 0},
-+	{"SCART", 	CRT2_TV, 	TV_SCART,  0},
-+	{"none", 	0, 		-1,        0},
-+	{"lcd",  	CRT2_LCD, 	-1,        0},
-+	{"tv",   	CRT2_TV, 	-1,        0},
-+	{"vga",  	CRT2_VGA, 	-1,        0},
-+	{"svideo", 	CRT2_TV, 	TV_SVIDEO, 0},
-+	{"composite", 	CRT2_TV, 	TV_AVIDEO, 0},
-+	{"scart", 	CRT2_TV, 	TV_SCART,  0},
-+	{"DSTN",        CRT2_LCD,       -1,        FL_550_DSTN},
-+	{"dstn",        CRT2_LCD,       -1,        FL_550_DSTN},
-+	{"FSTN",        CRT2_LCD,       -1,        FL_550_FSTN},
-+	{"fstn",        CRT2_LCD,       -1,        FL_550_FSTN},
-+	{"\0",  	-1, 		-1,        0}
- };
- 
- /* Queue mode selection for 310 series */
-@@ -590,10 +637,10 @@ static const struct _sis_tvtype {
- 	char name[6];
- 	int type_no;
- } sis_tvtype[] = {
--	{"PAL",  	1},
--	{"NTSC", 	2},
--	{"pal", 	1},
--	{"ntsc",  	2},
-+	{"PAL",  	TV_PAL},
-+	{"NTSC", 	TV_NTSC},
-+	{"pal", 	TV_PAL},
-+	{"ntsc",  	TV_NTSC},
- 	{"\0",   	-1}
- };
- 
-@@ -602,33 +649,102 @@ static const struct _sis_vrate {
- 	u16 xres;
- 	u16 yres;
- 	u16 refresh;
-+	BOOLEAN SiS730valid32bpp;
- } sisfb_vrate[] = {
--	{1,  640,  480, 60}, {2,  640,  480,  72}, {3, 640,   480,  75}, {4,  640, 480,  85},
--	{5,  640,  480,100}, {6,  640,  480, 120}, {7, 640,   480, 160}, {8,  640, 480, 200},
--	{1,  720,  480, 60},
--	{1,  720,  576, 58},
--	{1,  800,  480, 60}, {2,  800,  480,  75}, {3, 800,   480,  85},
--	{1,  800,  600, 56}, {2,  800,  600,  60}, {3, 800,   600,  72}, {4,  800, 600,  75},
--	{5,  800,  600, 85}, {6,  800,  600, 100}, {7, 800,   600, 120}, {8,  800, 600, 160},
--	{1, 1024,  768, 43}, {2, 1024,  768,  60}, {3, 1024,  768,  70}, {4, 1024, 768,  75},
--	{5, 1024,  768, 85}, {6, 1024,  768, 100}, {7, 1024,  768, 120},
--	{1, 1024,  576, 60}, {2, 1024,  576,  75}, {3, 1024,  576,  85},
--	{1, 1024,  600, 60},
--	{1, 1152,  768, 60},
--	{1, 1280,  720, 60}, {2, 1280,  720,  75}, {3, 1280,  720,  85},
--	{1, 1280,  768, 60},
--	{1, 1280, 1024, 43}, {2, 1280, 1024,  60}, {3, 1280, 1024,  75}, {4, 1280, 1024,  85},
--	{1, 1280,  960, 70},
--	{1, 1400, 1050, 60},
--	{1, 1600, 1200, 60}, {2, 1600, 1200,  65}, {3, 1600, 1200,  70}, {4, 1600, 1200,  75},
--	{5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
--	{1, 1920, 1440, 60}, {2, 1920, 1440,  65}, {3, 1920, 1440,  70}, {4, 1920, 1440,  75},
--	{5, 1920, 1440, 85}, {6, 1920, 1440, 100},
--	{1, 2048, 1536, 60}, {2, 2048, 1536,  65}, {3, 2048, 1536,  70}, {4, 2048, 1536,  75},
--	{5, 2048, 1536, 85},
--	{0, 0, 0, 0}
-+	{1,  320,  200,  70,  TRUE},
-+	{1,  320,  240,  60,  TRUE},
-+	{1,  320,  480,  60,  TRUE},
-+	{1,  400,  300,  60,  TRUE},
-+	{1,  512,  384,  60,  TRUE},
-+	{1,  640,  400,  72,  TRUE},
-+	{1,  640,  480,  60,  TRUE}, {2,  640,  480,  72,  TRUE}, {3,  640,  480,  75,  TRUE},
-+	{4,  640,  480,  85,  TRUE}, {5,  640,  480, 100,  TRUE}, {6,  640,  480, 120,  TRUE},
-+	{7,  640,  480, 160,  TRUE}, {8,  640,  480, 200,  TRUE},
-+	{1,  720,  480,  60,  TRUE},
-+	{1,  720,  576,  58,  TRUE},
-+	{1,  800,  480,  60,  TRUE}, {2,  800,  480,  75,  TRUE}, {3,  800,  480,  85,  TRUE},
-+	{1,  800,  600,  56,  TRUE}, {2,  800,  600,  60,  TRUE}, {3,  800,  600,  72,  TRUE},
-+	{4,  800,  600,  75,  TRUE}, {5,  800,  600,  85,  TRUE}, {6,  800,  600, 105,  TRUE},
-+	{7,  800,  600, 120,  TRUE}, {8,  800,  600, 160,  TRUE},
-+	{1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
-+	{1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
-+	{1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
-+	{1, 1024,  600,  60,  TRUE},
-+	{1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
-+	{4, 1024,  768,  75, FALSE}, {5, 1024,  768,  85,  TRUE}, {6, 1024,  768, 100,  TRUE},
-+	{7, 1024,  768, 120,  TRUE},
-+	{1, 1152,  768,  60,  TRUE},
-+	{1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
-+	{1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
-+	{1, 1280,  768,  60,  TRUE},
-+	{1, 1280,  960,  60,  TRUE}, {2, 1280,  960,  85,  TRUE},
-+	{1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
-+	{4, 1280, 1024,  85,  TRUE},
-+	{1, 1360,  768,  60,  TRUE},
-+	{1, 1360, 1024,  59,  TRUE},
-+	{1, 1400, 1050,  60,  TRUE}, {2, 1400, 1050,  75,  TRUE},
-+	{1, 1600, 1200,  60,  TRUE}, {2, 1600, 1200,  65,  TRUE}, {3, 1600, 1200,  70,  TRUE},
-+	{4, 1600, 1200,  75,  TRUE}, {5, 1600, 1200,  85,  TRUE}, {6, 1600, 1200, 100,  TRUE},
-+	{7, 1600, 1200, 120,  TRUE},
-+	{1, 1920, 1440,  60,  TRUE}, {2, 1920, 1440,  65,  TRUE}, {3, 1920, 1440,  70,  TRUE},
-+	{4, 1920, 1440,  75,  TRUE}, {5, 1920, 1440,  85,  TRUE}, {6, 1920, 1440, 100,  TRUE},
-+	{1, 2048, 1536,  60,  TRUE}, {2, 2048, 1536,  65,  TRUE}, {3, 2048, 1536,  70,  TRUE},
-+	{4, 2048, 1536,  75,  TRUE}, {5, 2048, 1536,  85,  TRUE},
-+	{0,    0,    0,   0, FALSE}
-+};
-+
-+static struct sisfb_monitor {
-+	u16 hmin;
-+	u16 hmax;
-+	u16 vmin;
-+	u16 vmax;
-+	u32 dclockmax;
-+	u8  feature;
-+	BOOLEAN datavalid;
-+} sisfb_thismonitor;
-+
-+static const struct _sisfbddcsmodes {
-+	u32 mask;
-+	u16 h;
-+	u16 v;
-+	u32 d;
-+} sisfb_ddcsmodes[] = {
-+	{ 0x10000, 67, 75, 108000},
-+	{ 0x08000, 48, 72,  50000},
-+	{ 0x04000, 46, 75,  49500},
-+	{ 0x01000, 35, 43,  44900},
-+	{ 0x00800, 48, 60,  65000},
-+	{ 0x00400, 56, 70,  75000},
-+	{ 0x00200, 60, 75,  78800},
-+	{ 0x00100, 80, 75, 135000},
-+	{ 0x00020, 31, 60,  25200},
-+	{ 0x00008, 38, 72,  31500},
-+	{ 0x00004, 37, 75,  31500},
-+	{ 0x00002, 35, 56,  36000},
-+	{ 0x00001, 38, 60,  40000}
-+};
-+
-+static const struct _sisfbddcfmodes {
-+	u16 x;
-+	u16 y;
-+	u16 v;
-+	u16 h;
-+	u32 d;
-+} sisfb_ddcfmodes[] = {
-+       { 1280, 1024, 85, 92, 157500},
-+       { 1600, 1200, 60, 75, 162000},
-+       { 1600, 1200, 65, 82, 175500},
-+       { 1600, 1200, 70, 88, 189000},
-+       { 1600, 1200, 75, 94, 202500},
-+       { 1600, 1200, 85, 107,229500},
-+       { 1920, 1440, 60, 90, 234000},
-+       { 1920, 1440, 75, 113,297000}
- };
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-+static u8 sisfb_lastrates[128];
-+#endif
-+
- static const struct _chswtable {
-     int subsysVendor;
-     int subsysCard;
-@@ -636,9 +752,38 @@ static const struct _chswtable {
-     char *cardName;
- } mychswtable[] = {
-         { 0x1631, 0x1002, "Mitachi", "0x1002" },
-+	{ 0x1071, 0x7521, "Mitac"  , "7521P"  },
- 	{ 0,      0,      ""       , ""       }
- };
- 
-+static const struct _customttable {
-+    unsigned short chipID;
-+    char *biosversion;
-+    char *biosdate;
-+    unsigned short biosFootprintAddr[5];
-+    unsigned char biosFootprintData[5];
-+    char *vendorName;
-+    char *cardName;
-+    unsigned long SpecialID;
-+    char *optionName;
-+} mycustomttable[] = {
-+        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
-+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
-+	  {  0x01,  0xe3,  0x9a,  0x6a,  0x00 },
-+	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
-+	},
-+	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
-+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
-+	  {  0x00,  0x5a,  0x64,  0x41,  0x00 },
-+	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
-+	},
-+	{ 0, "", "",
-+	  { 0, 0, 0, 0 },
-+	  { 0, 0, 0, 0 },
-+	  "", "", CUT_NONE, ""
-+	}
-+};
-+
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- /* Offscreen layout */
- typedef struct _SIS_GLYINFO {
-@@ -677,7 +822,6 @@ static unsigned long sisfb_heap_end;
- static unsigned long sisfb_heap_size;
- static SIS_HEAP      sisfb_heap;
- 
--// Eden Chen
- static const struct _sis_TV_filter {
- 	u8 filter[9][4];
- } sis_TV_filter[] = {
-@@ -829,9 +973,8 @@ static const struct _sis_TV_filter {
- 
- static int           filter = -1;
- static unsigned char filter_tb;
--//~Eden Chen
- 
--/* ---------------------- Routine prototypes ------------------------- */
-+/* ---------------------- Prototypes ------------------------- */
- 
- /* Interface used by the world */
- #ifndef MODULE
-@@ -894,10 +1037,6 @@ extern void     fbcon_sis_fillrect(struc
-                                    const struct fb_fillrect *rect);
- extern void     fbcon_sis_copyarea(struct fb_info *info, 
-                                    const struct fb_copyarea *area);
--#if 0				   
--extern void     cfb_imageblit(struct fb_info *info, 
--                              const struct fb_image *image);
--#endif			      
- extern int      fbcon_sis_sync(struct fb_info *info);
- static int      sisfb_ioctl(struct inode *inode, 
- 	 		    struct file *file,
-@@ -912,7 +1051,7 @@ extern int      sisfb_mode_rate_to_ddata
- 			 unsigned int *left_margin, unsigned int *right_margin, 
- 			 unsigned int *upper_margin, unsigned int *lower_margin,
- 			 unsigned int *hsync_len, unsigned int *vsync_len,
--			 unsigned int *sync, unsigned int *vmode);			      		    			      
-+			 unsigned int *sync, unsigned int *vmode);
- #endif
- 			
- static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-@@ -923,9 +1062,9 @@ extern int      sisfb_initaccel(void);
- extern void     sisfb_syncaccel(void);
- 
- /* Internal general routines */
--static void     sisfb_search_mode(const char *name);
--static int      sisfb_validate_mode(int modeindex);
--static u8       sisfb_search_refresh_rate(unsigned int rate);
-+static void     sisfb_search_mode(char *name, BOOLEAN quiet);
-+static int      sisfb_validate_mode(int modeindex, unsigned long vbflags);
-+static u8       sisfb_search_refresh_rate(unsigned int rate, int index);
- static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- 			unsigned blue, unsigned transp,
- 			struct fb_info *fb_info);
-@@ -939,6 +1078,12 @@ static BOOLEAN  sisfb_CheckVBRetrace(voi
- static BOOLEAN  sisfbcheckvretracecrt2(void);
- static BOOLEAN  sisfbcheckvretracecrt1(void);
- static BOOLEAN  sisfb_bridgeisslave(void);
-+static void     sisfb_detect_VB_connect(void);
-+static void     sisfb_get_VB_type(void);
-+
-+static void     sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
-+static BOOLEAN  sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
-+
- 
- /* SiS-specific Export functions */
- void            sis_dispinfo(struct ap_data *rec);
-@@ -952,15 +1097,9 @@ u32             sisfb_get_reg3(u16 port)
- /* Chipset-dependent internal routines */
- #ifdef CONFIG_FB_SIS_300
- static int      sisfb_get_dram_size_300(void);
--static void     sisfb_detect_VB_connect_300(void);
--static void     sisfb_get_VB_type_300(void);
--static int      sisfb_has_VB_300(void);
- #endif
- #ifdef CONFIG_FB_SIS_315
- static int      sisfb_get_dram_size_315(void);
--static void     sisfb_detect_VB_connect_315(void);
--static void     sisfb_get_VB_type_315(void);
--static int      sisfb_has_VB_315(void);
- #endif
- 
- /* Internal heap routines */
-@@ -978,23 +1117,33 @@ BOOLEAN         sisfb_query_VGA_config_s
- BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
- 	         	unsigned long offset, unsigned long set, unsigned long *value);
- 
--
- /* Routines from init.c/init301.c */
- extern void 	SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
- extern BOOLEAN  SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
- extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
--extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
-+extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-+extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
- extern void     SiS_LongWait(SiS_Private *SiS_Pr);
- 
--/* TW: Chrontel TV functions */
-+extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
-+
-+/* Chrontel TV functions */
- extern USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
- extern void 	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
- extern USHORT 	SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
- extern void 	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
- extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
- extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
--
--/* TW: Sensing routines */
-+extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-+extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
-+		              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
-+extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-+extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-+extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-+extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-+			      
-+/* Sensing routines */
- void            SiS_Sense30x(void);
- int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
- void            SiS_SenseCh(void);			
---- linux-2.6.0-test1/drivers/video/sis/vgatypes.h	2003-06-14 12:17:55.000000000 -0700
-+++ 25/drivers/video/sis/vgatypes.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,3 +1,30 @@
-+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
-+/*
-+ * General type definitions for universal mode switching modules
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *
-+ */
- #ifndef _VGATYPES_
- #define _VGATYPES_
- 
-@@ -5,7 +32,7 @@
- #include "xf86Pci.h"
- #endif
- 
--#ifdef LINUX_KERNEL  /* TW: We don't want the X driver to depend on kernel source */
-+#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
- #include <linux/ioctl.h>
- #endif
- 
-@@ -72,18 +99,15 @@ typedef void VOID;
- typedef UCHAR BOOLEAN;
- #endif
- 
--#ifndef WINCE_HEADER
- #ifndef bool
- typedef UCHAR bool;
- #endif
--#endif /*WINCE_HEADER*/
- 
- #ifndef VBIOS_VER_MAX_LENGTH
- #define VBIOS_VER_MAX_LENGTH         4
- #endif
- 
- #ifndef LINUX_KERNEL   /* For kernel, this is defined in sisfb.h */
--#ifndef WIN2000
- #ifndef SIS_CHIP_TYPE
- typedef enum _SIS_CHIP_TYPE {
-     SIS_VGALegacy = 0,
-@@ -101,19 +125,18 @@ typedef enum _SIS_CHIP_TYPE {
-     SIS_550,
-     SIS_650,
-     SIS_740,
--    SIS_330, 
-+    SIS_330,
-+    SIS_660,
-     MAX_SIS_CHIP
- } SIS_CHIP_TYPE;
- #endif
- #endif
--#endif
- 
--#ifndef WIN2000
- #ifndef SIS_VB_CHIP_TYPE
- typedef enum _SIS_VB_CHIP_TYPE {
-     VB_CHIP_Legacy = 0,
-     VB_CHIP_301,
--    VB_CHIP_301B,      
-+    VB_CHIP_301B,
-     VB_CHIP_301LV,
-     VB_CHIP_302,
-     VB_CHIP_302B,
-@@ -122,9 +145,7 @@ typedef enum _SIS_VB_CHIP_TYPE {
-     MAX_VB_CHIP
- } SIS_VB_CHIP_TYPE;
- #endif
--#endif
- 
--#ifndef WIN2000
- #ifndef SIS_LCD_TYPE
- typedef enum _SIS_LCD_TYPE {
-     LCD_INVALID = 0,
-@@ -136,18 +157,19 @@ typedef enum _SIS_LCD_TYPE {
-     LCD_1600x1200,
-     LCD_1920x1440,
-     LCD_2048x1536,
--    LCD_320x480,       /* TW: FSTN */
-+    LCD_320x480,       /* FSTN, DSTN */
-     LCD_1400x1050,
-     LCD_1152x864,
-     LCD_1152x768,
-     LCD_1280x768,
-     LCD_1024x600,
-+    LCD_640x480_2,     /* FSTN, DSTN */
-+    LCD_640x480_3,     /* FSTN, DSTN */
-+    LCD_CUSTOM,
-     LCD_UNKNOWN
- } SIS_LCD_TYPE;
- #endif
--#endif
- 
--#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
- #ifndef PSIS_DSReg
- typedef struct _SIS_DSReg
- {
-@@ -162,7 +184,6 @@ typedef struct _SIS_HW_DEVICE_INFO  SIS_
- 
- typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
- 
--
- struct _SIS_HW_DEVICE_INFO
- {
-     PVOID  pDevice;              /* The pointer to the physical device data structure
-@@ -173,7 +194,7 @@ struct _SIS_HW_DEVICE_INFO
-                                  /* Note:ROM image file is the file of VBIOS ROM */
- 
-     BOOLEAN UseROM;		 /* TW: Use the ROM image if provided */
-- 
-+
-     UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
-                                  /* wincE:ROM image file is the file for OEM */
-                                  /*       customized table */
-@@ -195,7 +216,7 @@ struct _SIS_HW_DEVICE_INFO
-                                  /* defined in the data structure type */
-                                  /* "SIS_VB_CHIP_TYPE" */
- 
--    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
-+    USHORT usExternalChip;       /* NO VB or other video bridge (other than  */
-                                  /* SiS video bridge) */
-                                  /* if ujVBChipID = VB_CHIP_UNKNOWN, */
-                                  /* then bit0=1 : LVDS,bit1=1 : trumpion, */
-@@ -207,7 +228,7 @@ struct _SIS_HW_DEVICE_INFO
-                                  /*             011:Trumpion LVDS Scaling Chip */
-                                  /*             100:LVDS(LCD-out)+Chrontel 7005 */
-                                  /*             101:Single Chrontel 7005 */
--				 /* TW: This has changed on 310/325 series! */
-+				 /* TW: This has changed on 315 series! */
- 
-     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
-                                  /* "SIS_LCD_TYPE" */
-@@ -244,7 +265,6 @@ struct _SIS_HW_DEVICE_INFO
- #endif
- };
- #endif
--#endif 
- 
- 
- /* TW: Addtional IOCTL for communication sisfb <> X driver        */
-@@ -288,8 +308,6 @@ struct _SISFB_INFO {
- };
- #endif
- 
--#ifndef WIN2000
--#ifndef WINCE_HEADER
- #ifndef BUS_DATA_TYPE
- typedef enum _BUS_DATA_TYPE {
-     ConfigurationSpaceUndefined = -1,
-@@ -307,7 +325,6 @@ typedef enum _BUS_DATA_TYPE {
-     MaximumBusDataType
- } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
- #endif
--#endif /* WINCE_HEADER */
- 
- #ifndef PCI_TYPE0_ADDRESSES
- #define PCI_TYPE0_ADDRESSES             6
-@@ -317,7 +334,6 @@ typedef enum _BUS_DATA_TYPE {
- #define PCI_TYPE1_ADDRESSES             2
- #endif
- 
--#ifndef WINCE_HEADER
- #ifndef PCI_COMMON_CONFIG
- typedef struct _PCI_COMMON_CONFIG {
-     USHORT  VendorID;                   /* (ro)                 */
-@@ -355,7 +371,6 @@ typedef struct _PCI_COMMON_CONFIG {
- 
- } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
- #endif
--#endif /* WINCE_HEADER */
- 
- #ifndef FIELD_OFFSET
- #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
-@@ -364,6 +379,6 @@ typedef struct _PCI_COMMON_CONFIG {
- #ifndef PCI_COMMON_HDR_LENGTH
- #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
- #endif
--#endif
- 
- #endif
-+
---- linux-2.6.0-test1/drivers/video/sis/vstruct.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/drivers/video/sis/vstruct.h	2003-07-19 17:04:55.000000000 -0700
-@@ -1,3 +1,32 @@
-+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
-+/*
-+ * General structure definitions for universal mode switching modules
-+ *
-+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
-+ *
-+ * Permission to use, copy, modify, distribute, and sell this software and its
-+ * documentation for any purpose is hereby granted without fee, provided that
-+ * the above copyright notice appear in all copies and that both that
-+ * copyright notice and this permission notice appear in supporting
-+ * documentation, and that the name of the copyright holder not be used in
-+ * advertising or publicity pertaining to distribution of the software without
-+ * specific, written prior permission.  The copyright holder makes no representations
-+ * about the suitability of this software for any purpose.  It is provided
-+ * "as is" without express or implied warranty.
-+ *
-+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-+ * PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
-+ *              ?
-+ *
-+ */
-+ 
- #ifdef _INIT_
- #define EXTERN
- #else
-@@ -58,7 +87,6 @@ typedef struct _SiS_LVDSCRT1DataStruct
- 	UCHAR  CR[15];
- } SiS_LVDSCRT1DataStruct;
- 
--/*add for LCDA*/
- typedef struct _SiS_LCDACRT1DataStruct
- {
- 	UCHAR  CR[17];
-@@ -111,9 +139,7 @@ typedef struct _SiS_ExtStruct
- 	UCHAR  Ext_ModeID;
- 	USHORT Ext_ModeFlag;
- 	USHORT Ext_ModeInfo;
--	USHORT Ext_Point;
- 	USHORT Ext_VESAID;
--	UCHAR  Ext_VESAMEMSize;
- 	UCHAR  Ext_RESINFO;
- 	UCHAR  VB_ExtTVFlickerIndex;
- 	UCHAR  VB_ExtTVEdgeIndex;
-@@ -130,7 +156,6 @@ typedef struct _SiS_Ext2Struct
- 	UCHAR  ModeID;
- 	USHORT XRes;
- 	USHORT YRes;
--	USHORT ROM_OFFSET;
- } SiS_Ext2Struct;
- 
- typedef struct _SiS_Part2PortTblStruct
-@@ -183,6 +208,12 @@ typedef struct _SiS_ModeResInfoStruct
- 
- typedef UCHAR DRAM4Type[4];
- 
-+/* Defines for SiS_Customt */
-+#define CUT_NONE       0
-+#define CUT_FORCENONE  1
-+#define CUT_BARCO1366  2
-+#define CUT_BARCO1024  3
-+
- typedef struct _SiS_Private
- {
- #ifdef LINUX_KERNEL
-@@ -198,25 +229,34 @@ typedef struct _SiS_Private
- 	USHORT SiS_P3c7;
- 	USHORT SiS_P3c8;
- 	USHORT SiS_P3c9;
-+	USHORT SiS_P3cb;
-+	USHORT SiS_P3cd;
- 	USHORT SiS_P3da;
- 	USHORT SiS_Part1Port;
- 	USHORT SiS_Part2Port;
- 	USHORT SiS_Part3Port;
- 	USHORT SiS_Part4Port;
- 	USHORT SiS_Part5Port;
-+	USHORT SiS_VidCapt;
-+	USHORT SiS_VidPlay;
- 	USHORT SiS_IF_DEF_LVDS;
- 	USHORT SiS_IF_DEF_TRUMPION;
- 	USHORT SiS_IF_DEF_DSTN;
- 	USHORT SiS_IF_DEF_FSTN;
- 	USHORT SiS_IF_DEF_CH70xx;
- 	USHORT SiS_IF_DEF_HiVision;
-+	USHORT SiS_SysFlags;
- 	UCHAR  SiS_VGAINFO;
-+#ifndef LINUX_KERNEL
-+        USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
-+#endif
- 	BOOLEAN SiS_UseROM;
- 	int    SiS_CHOverScan;
- 	BOOLEAN SiS_CHSOverScan;
- 	BOOLEAN SiS_ChSW;
- 	BOOLEAN SiS_UseLCDA;
- 	int    SiS_UseOEM;
-+	ULONG  SiS_CustomT;
- 	USHORT SiS_Backup70xx;
- 	USHORT SiS_CRT1Mode;
- 	USHORT SiS_flag_clearbuffer;
-@@ -270,15 +310,18 @@ typedef struct _SiS_Private
- 	USHORT SiS_Panel1280x768;
- 	USHORT SiS_Panel1024x600;
- 	USHORT SiS_Panel640x480;
-+	USHORT SiS_Panel640x480_2;
-+	USHORT SiS_Panel640x480_3;
- 	USHORT SiS_Panel1152x864;
-+	USHORT SiS_PanelCustom;
-+	USHORT SiS_PanelBarco1366;
- 	USHORT SiS_PanelMax;
- 	USHORT SiS_PanelMinLVDS;
- 	USHORT SiS_PanelMin301;
- 	USHORT SiS_ChrontelInit;
- 	
--	/* Pointers: */
- 	const SiS_StStruct          *SiS_SModeIDTable;
--	const SiS_StandTableStruct  *SiS_StandTable;
-+	SiS_StandTableStruct        *SiS_StandTable;
- 	const SiS_ExtStruct         *SiS_EModeIDTable;
- 	const SiS_Ext2Struct        *SiS_RefIndex;
- 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
-@@ -316,7 +359,7 @@ typedef struct _SiS_Private
- 	const USHORT *pSiS_RGBSenseData;
- 	const USHORT *pSiS_VideoSenseData;
- 	const USHORT *pSiS_YCSenseData;
--	const USHORT *pSiS_RGBSenseData2; /*301b*/
-+	const USHORT *pSiS_RGBSenseData2;
- 	const USHORT *pSiS_VideoSenseData2;
- 	const USHORT *pSiS_YCSenseData2;
- #endif
-@@ -340,15 +383,18 @@ typedef struct _SiS_Private
- 	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
- 	const SiS_LCDDataStruct  *SiS_NoScaleData1400x1050;
- 	const SiS_LCDDataStruct  *SiS_NoScaleData1600x1200;
-+	const SiS_LCDDataStruct  *SiS_NoScaleData1280x768;
- 	const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
- 	const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
-+	const SiS_LCDDataStruct  *SiS_StLCD1280x768Data;
- 	const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
- 	const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
-+	const SiS_LCDDataStruct  *SiS_ExtLCD1280x768Data;
-+	const SiS_LCDDataStruct  *SiS_NoScaleData;
- 	const SiS_TVDataStruct   *SiS_StPALData;
- 	const SiS_TVDataStruct   *SiS_ExtPALData;
- 	const SiS_TVDataStruct   *SiS_StNTSCData;
- 	const SiS_TVDataStruct   *SiS_ExtNTSCData;
--/*	const SiS_TVDataStruct   *SiS_St1HiTVData;  */
- 	const SiS_TVDataStruct   *SiS_St2HiTVData;
- 	const SiS_TVDataStruct   *SiS_ExtHiTVData;
- 	const UCHAR *SiS_NTSCTiming;
-@@ -381,12 +427,17 @@ typedef struct _SiS_Private
- 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
- 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
- 	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
-+	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
- 	const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
- 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
- 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
- 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
- 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
- 	const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
-+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
-+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
-+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_1;
-+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_2;
- 	const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
- 	const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
- 	const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
-@@ -478,6 +529,12 @@ typedef struct _SiS_Private
- 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
- 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
- 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1_H;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
-+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
- 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
- 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
- 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
-@@ -507,7 +564,6 @@ typedef struct _SiS_Private
- 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
- 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
- 
--	/* TW: New for 650/301LV */
- 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
- 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
- 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
-@@ -539,6 +595,9 @@ typedef struct _SiS_Private
- 	const UCHAR *SiS_CHTVVCLKUPALN;
- 	const UCHAR *SiS_CHTVVCLKOPALN;
- 	const UCHAR *SiS_CHTVVCLKSOPAL;
-+
-+	USHORT  PanelXRes;
-+	USHORT  PanelYRes;
- 	
- 	BOOLEAN UseCustomMode;
- 	BOOLEAN CRT1UsesCustomMode;
-@@ -560,8 +619,11 @@ typedef struct _SiS_Private
- 	UCHAR   CSR2B;
- 	UCHAR   CSR2C;
- 	USHORT  CSRClock;
-+	USHORT  CSRClock_CRT1;
- 	USHORT  CModeFlag;
-+	USHORT  CModeFlag_CRT1;
- 	USHORT  CInfoFlag;
-+
- 	BOOLEAN SiS_CHPALM;
- 	BOOLEAN SiS_CHPALN;
- 	
-@@ -578,7 +640,21 @@ typedef struct _SiS_Private
- 	UCHAR Backup_1c;
- 	UCHAR Backup_1d;
- 	
--	int    UsePanelScaler;
-+	int     UsePanelScaler;
-+
-+	USHORT  CP_Vendor, CP_Product;
-+	BOOLEAN CP_HaveCustomData;
-+	int     CP_PreferredX, CP_PreferredY;
-+	int	CP_MaxX, CP_MaxY, CP_MaxClock;
-+	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
-+    	int     CP_HTotal[7], CP_VTotal[7];
-+    	int     CP_HSyncStart[7], CP_VSyncStart[7];
-+    	int     CP_HSyncEnd[7], CP_VSyncEnd[7];
-+	int     CP_HBlankStart[7], CP_VBlankStart[7];
-+	int     CP_HBlankEnd[7], CP_VBlankEnd[7];
-+    	int     CP_Clock[7];
-+	BOOLEAN CP_DataValid[7];
-+	BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
- } SiS_Private;
- 
- #endif
---- linux-2.6.0-test1/drivers/video/skeletonfb.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/drivers/video/skeletonfb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
-  *
-- *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
-+ *  Modified to new api Jan 2001 by James Simmons (jsimmons@infradead.org)
-  *
-  *  Created 28 Dec 1997 by Geert Uytterhoeven
-  *
-@@ -469,15 +469,71 @@ void xxxfb_imageblit(struct fb_info *p, 
- int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
- {
- /*
-- *      @set: 	Which fields we are altering in struct fb_cursor 
-+ *      @set: 	 Which fields we are altering in struct fb_cursor 
-  *	@enable: Disable or enable the cursor 
-- *      @rop: 	The bit operation we want to do. 
-- *      @mask:  This is the cursor mask bitmap. 
-- *      @dest:  A image of the area we are going to display the cursor.
-- *		Used internally by the driver.	 
-- *      @hot:	The hot spot. 
-- *	@image:	The actual data for the cursor image.
-+ *      @rop: 	 The bit operation we want to do. 
-+ *      @hot:	 The hot spot. 
-+ *	@image:	 The actual data for the cursor image.
-+ *      @mask:   This is the cursor mask bitmap. 
-  */
-+
-+   /* Disable hardware cursor. We don't want to display the cursor 
-+      while changing it. Note we use the enable and rop fields in
-+      struct fb_cursor that is apart of struct fb_info. Not the 
-+      cursor data passed in from userland. */	
-+
-+   if (cursor->set & FB_CUR_SETHOT) {
-+	info->cursor.hot = cursor->hot;
-+   	/* Set the hardware cursor's hot spot  */	   	 	
-+   }
-+	
-+   if (cursor->set & FB_CUR_SETPOS) {
-+	info->cursor.image.dx = cursor->image.dx;
-+	info->cursor.image.dy = cursor->image.dy;
-+   	/* Set the hardware cursor's position */
-+   }
-+
-+   if (cursor->set & FB_CUR_SETSIZE) {
-+	info->cursor.image.height = cursor->image.height;
-+	info->cursor.image.width = cursor->image.width;
-+   	/* Set the hardware cursor's size */	
-+   }
-+  
-+   if (cursor->set & FB_CUR_SETCMAP) {
-+	if (cursor->image.depth == 1) {
-+		info->cursor.image.fg_color = cursor->image.fg_color;
-+		info->cursor.image.bg_color = cursor->image.bg_color;
-+	} else {
-+		if (cursor->image.cmap.len)
-+			fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
-+	}
-+	info->curosr.image.depth = cursor->image.depth;
-+
-+   	/* Set the hardware cursor's color map */
-+   }
-+
-+   /* 
-+    * Set the cursor shape. The two pieces needed to create
-+    * the final image is mask and image.data. The mask is 
-+    * combined with image.data according to the rop field.
-+    */
-+   if (cursor->set & FB_CUR_SETSHAPE) {
-+ 	switch (info->cursor.rop) {
-+	case ROP_XOR:
-+		/* ... */
-+		break;
-+	case ROP_COPY:
-+	default:
-+		/* ... */
-+		break;
-+   	}
-+	/* ... */
-+   }
-+   
-+   if (info->cursor.enable) {
-+	/* Now we turn the hardware cursor on */
-+   }
-+   return 0;						
- }
- 
- /**
---- linux-2.6.0-test1/drivers/video/softcursor.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/drivers/video/softcursor.c	2003-07-19 17:04:55.000000000 -0700
-@@ -21,9 +21,14 @@ int soft_cursor(struct fb_info *info, st
- {
- 	unsigned int scan_align = info->pixmap.scan_align - 1;
- 	unsigned int buf_align = info->pixmap.buf_align - 1;
--	unsigned int i, size, dsize, s_pitch, d_pitch;
--	u8 *dst, src[64];
--
-+	u8 *dst = (u8 *) info->cursor.image.data;
-+	unsigned int i, size, pitch;
-+		
-+	pitch = ((info->cursor.image.width + 7) >> 3) + scan_align;
-+	pitch &= ~scan_align;
-+	size = pitch * info->cursor.image.height + buf_align;
-+	size &= ~buf_align;
-+	
- 	if (cursor->set & FB_CUR_SETSIZE) {
- 		info->cursor.image.height = cursor->image.height;
- 		info->cursor.image.width = cursor->image.width;
-@@ -48,34 +53,27 @@ int soft_cursor(struct fb_info *info, st
- 		info->cursor.image.depth = cursor->image.depth;
- 	}	
- 
--	s_pitch = (info->cursor.image.width + 7) >> 3;
--	dsize = s_pitch * info->cursor.image.height;
--	d_pitch = (s_pitch + scan_align) & ~scan_align;
--	size = d_pitch * info->cursor.image.height + buf_align;
--	size &= ~buf_align;
--	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
--
--	if (info->cursor.enable) {
-+	if (cursor->set & FB_CUR_SETSHAPE) {
- 		switch (info->cursor.rop) {
- 		case ROP_XOR:
--			for (i = 0; i < dsize; i++)
--				src[i] = cursor->image.data[i] ^ info->cursor.mask[i]; 
-+			for (i = 0; i < size; i++)
-+				dst[i] ^= info->cursor.mask[i]; 
- 			break;
- 		case ROP_COPY:
- 		default:
--			for (i = 0; i < dsize; i++)
--				src[i] = cursor->image.data[i] & info->cursor.mask[i];
-+			for (i = 0; i < size; i++)
-+				dst[i] &= info->cursor.mask[i];
- 			break;
- 		}
--	} else 
--		memcpy(src, cursor->image.data, dsize);
--	
--	move_buf_aligned(info, dst, src, d_pitch, s_pitch, info->cursor.image.height);
--	info->cursor.image.data = dst;
-+	}
- 	
--	info->fbops->fb_imageblit(info, &info->cursor.image);
--	atomic_dec(&info->pixmap.count);
--	smp_mb__after_atomic_dec();
-+	if (!info->cursor.enable) {
-+		for (i = 0; i < size; i++)
-+			dst[i] ^= info->cursor.mask[i]; 
-+	}
-+		
-+	if (info->cursor.image.data)
-+		info->fbops->fb_imageblit(info, &info->cursor.image);
- 	return 0;
- }
- 
---- linux-2.6.0-test1/drivers/video/valkyriefb.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/drivers/video/valkyriefb.c	2003-07-19 17:04:55.000000000 -0700
-@@ -51,7 +51,6 @@
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/fb.h>
--#include <linux/selection.h>
- #include <linux/init.h>
- #include <linux/pci.h>
- #include <linux/nvram.h>
-@@ -66,15 +65,9 @@
- #endif
- #include <asm/pgtable.h>
- 
--#include <video/fbcon.h>
--#include <video/fbcon-cfb8.h>
--#include <video/fbcon-cfb16.h>
--#include <video/macmodes.h>
--
-+#include "macmodes.h"
- #include "valkyriefb.h"
- 
--static int can_soft_blank = 1;
--
- #ifdef CONFIG_MAC
- /* We don't yet have functions to read the PRAM... perhaps we can
-    adapt them from the PPC code? */
-@@ -84,27 +77,17 @@ static int default_cmode = CMODE_8;
- static int default_vmode = VMODE_NVRAM;
- static int default_cmode = CMODE_NVRAM;
- #endif
--static char fontname[40] __initdata = { 0 };
--
--static int switching = 0;
- 
- struct fb_par_valkyrie {
- 	int	vmode, cmode;
- 	int	xres, yres;
- 	int	vxres, vyres;
--	int	xoffset, yoffset;
-+	struct valkyrie_regvals *init;
- };
- 
- struct fb_info_valkyrie {
--	struct fb_info			info;
--	struct fb_fix_screeninfo	fix;
--	struct fb_var_screeninfo	var;
--	struct display			disp;
--	struct fb_par_valkyrie		par;
--	struct {
--	    __u8 red, green, blue;
--	}			palette[256];
--	
-+	struct fb_info		info;
-+	struct fb_par_valkyrie	par;
- 	struct cmap_regs	*cmap_regs;
- 	unsigned long		cmap_regs_phys;
- 	
-@@ -116,9 +99,8 @@ struct fb_info_valkyrie {
- 	
- 	int			sense;
- 	unsigned long		total_vram;
--#ifdef FBCON_HAS_CFB16
--	u16 fbcon_cfb16_cmap[16];
--#endif
-+
-+	u32			pseudo_palette[16];
- };
- 
- /*
-@@ -127,10 +109,9 @@ struct fb_info_valkyrie {
- int valkyriefb_init(void);
- int valkyriefb_setup(char*);
- 
--static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
--			 struct fb_info *info);
--static int valkyrie_get_cmap(struct fb_cmap *cmap, int kspc, int con,
--			  struct fb_info *info);
-+static int valkyriefb_check_var(struct fb_var_screeninfo *var,
-+				struct fb_info *info);
-+static int valkyriefb_set_par(struct fb_info *info);
- static int valkyriefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- 			     u_int transp, struct fb_info *info);
- static int valkyriefb_blank(int blank_mode, struct fb_info *info);
-@@ -138,136 +119,69 @@ static int valkyriefb_blank(int blank_mo
- static int read_valkyrie_sense(struct fb_info_valkyrie *p);
- static inline int valkyrie_vram_reqd(int video_mode, int color_mode);
- static void set_valkyrie_clock(unsigned char *params);
--static void valkyrie_set_par(const struct fb_par_valkyrie *p, struct fb_info_valkyrie *info);
- static inline int valkyrie_par_to_var(struct fb_par_valkyrie *par, struct fb_var_screeninfo *var);
- static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
- 	struct fb_par_valkyrie *par, const struct fb_info *fb_info);
- 
- static void valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
--static void valkyrie_par_to_display(struct fb_par_valkyrie *par,
--  struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p);
--static void valkyrie_init_display(struct display *disp);
--static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix,
--	struct fb_info_valkyrie *p);
-+static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix);
- static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p);
- 
- static struct fb_ops valkyriefb_ops = {
- 	.owner =	THIS_MODULE,
--	.fb_set_var =	valkyrie_set_var,
--	.fb_get_cmap =	valkyrie_get_cmap,
--	.fb_set_cmap =	gen_set_cmap,
-+	.fb_check_var =	valkyriefb_check_var,
-+	.fb_set_par =	valkyriefb_set_par,
- 	.fb_setcolreg =	valkyriefb_setcolreg,
- 	.fb_blank =	valkyriefb_blank,
-+	.fb_fillrect	= cfb_fillrect,
-+	.fb_copyarea	= cfb_copyarea,
-+	.fb_imageblit	= cfb_imageblit,
-+	.fb_cursor	= soft_cursor,
- };
- 
--static int valkyriefb_getcolreg(u_int regno, u_int *red, u_int *green,
--			     u_int *blue, u_int *transp, struct fb_info *info);
--
--/* Sets everything according to var */
--static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
--			 struct fb_info *info)
-+/* Sets the video mode according to info->var */
-+static int valkyriefb_set_par(struct fb_info *info)
- {
- 	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info;
--	struct display *disp;
--	struct fb_par_valkyrie par;
--	int depthchange, err;
-+	volatile struct valkyrie_regs *valkyrie_regs = p->valkyrie_regs;
-+	struct fb_par_valkyrie *par = info->par;
-+	struct valkyrie_regvals	*init;
-+	int err;
- 
--	disp = (con >= 0) ? &fb_display[con] : &p->disp;
--	if ((err = valkyrie_var_to_par(var, &par, info))) {
--		 /* printk (KERN_ERR "Error in valkyrie_set_var, calling valkyrie_var_to_par: %d.\n", err); */
-+	if ((err = valkyrie_var_to_par(&info->var, par, info)))
- 		return err;
--	}
--	
--	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
--		/* printk(KERN_ERR "Not activating, in valkyrie_set_var.\n"); */
--		valkyrie_par_to_var(&par, var);
--		return 0;
--	}
- 
--	/*
--	 * I know, we want to use fb_display[con], but grab certain info
--	 * from p->var instead.
--	 */
--#define DIRTY(x) (p->var.x != var->x)
--	depthchange = DIRTY(bits_per_pixel);
--	/* adding "&& !DIRTY(pixclock)" corrects vmode-switching problems */
--	if(!DIRTY(xres) && !DIRTY(yres) && !DIRTY(xres_virtual) &&
--	   !DIRTY(yres_virtual) && !DIRTY(bits_per_pixel) && !DIRTY(pixclock)) {
--	   	valkyrie_par_to_var(&par, var);
--		p->var = disp->var = *var;
--		return 0;
--	}
-+	valkyrie_par_to_fix(par, &info->fix);
- 
--	p->par = par;
--	valkyrie_par_to_var(&par, var);
--	p->var = *var;
--	valkyrie_par_to_fix(&par, &p->fix, p);
--	valkyrie_par_to_display(&par, disp, &p->fix, p);
--	p->disp = *disp;
--	
--	if (info->changevar && !switching) {
--		/* Don't want to do this if just switching consoles. */
--		(*info->changevar)(con);
--	}
--	if (con == info->currcon)
--		valkyrie_set_par(&par, p);
--	if (depthchange)
--		if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
--			return err;
--	if (depthchange || switching)
--		do_install_cmap(con, info);
--	return 0;
--}
-+	/* Reset the valkyrie */
-+	out_8(&valkyrie_regs->status.r, 0);
-+	udelay(100);
- 
--static int valkyrie_get_cmap(struct fb_cmap *cmap, int kspc, int con,
--			  struct fb_info *info)
--{
--	if (con == info->currcon)	{
--		/* current console? */
--		return fb_get_cmap(cmap, kspc, valkyriefb_getcolreg, info);
--	}
--	if (fb_display[con].cmap.len) { /* non default colormap? */
--		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
--	}
--	else {
--		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
--		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
--	}
--	return 0;
--}
-+	/* Initialize display timing registers */
-+	init = par->init;
-+	out_8(&valkyrie_regs->mode.r, init->mode | 0x80);
-+	out_8(&valkyrie_regs->depth.r, par->cmode + 3);
-+	set_valkyrie_clock(init->clock_params);
-+	udelay(100);
- 
--static int valkyriefb_switch(int con, struct fb_info *fb)
--{
--	struct fb_info_valkyrie *info = (struct fb_info_valkyrie *) fb;
--	struct fb_par_valkyrie par;
-+	/* Turn on display */
-+	out_8(&valkyrie_regs->mode.r, init->mode);
- 
--	if (fb_display[fb->currcon].cmap.len)
--		fb_get_cmap(&fb_display[fb->currcon].cmap, 1, valkyriefb_getcolreg,
--			    fb);
--	fb->currcon = con;
--#if 1
--	valkyrie_var_to_par(&fb_display[fb->currcon].var, &par, fb);
--	valkyrie_set_par(&par, info);
--	do_install_cmap(con, fb);
--#else
--	/* I see no reason not to do this.  Minus info->changevar(). */
--	/* DOH.  This makes valkyrie_set_var compare, you guessed it, */
--	/* fb_display[con].var (first param), and fb_display[con].var! */
--	/* Perhaps I just fixed that... */
--	switching = 1;
--	valkyrie_set_var(&fb_display[con].var, con, info);
--	switching = 0;
--#endif
- 	return 0;
- }
- 
--static int valkyriefb_updatevar(int con, struct fb_info *info)
-+static int
-+valkyriefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
- {
-+	int err;
-+	struct fb_par_valkyrie par;
-+
-+	if ((err = valkyrie_var_to_par(var, &par, info)))
-+		return err;
-+	valkyrie_par_to_var(&par, var);
- 	return 0;
- }
- 
--static int valkyriefb_blank(int blank_mode, struct fb_info *info)
--{
- /*
-  *  Blank the screen if blank_mode != 0, else unblank. If blank_mode == NULL
-  *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
-@@ -278,48 +192,34 @@ static int valkyriefb_blank(int blank_mo
-  *    blank_mode == 3: suspend hsync
-  *    blank_mode == 4: powerdown
-  */
--	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info;
--	struct valkyrie_regvals	*init;
--	unsigned char vmode;
--
--	if (p->disp.can_soft_blank
--	 && ((vmode = p->par.vmode) > 0)
--	 && (vmode <= VMODE_MAX)
--	 && ((init = valkyrie_reg_init[vmode - 1]) != NULL)) {
--		if (blank_mode)
--			--blank_mode;
--		switch (blank_mode) {
--		default:	/* unblank */
--			out_8(&p->valkyrie_regs->mode.r, init->mode);
--			break;
--		case VESA_VSYNC_SUSPEND:
--		case VESA_HSYNC_SUSPEND:
--			/*
--			 * [kps] Value extracted from MacOS. I don't know
--			 * whether this bit disables hsync or vsync, or
--			 * whether the hardware can do the other as well.
--			 */
--			out_8(&p->valkyrie_regs->mode.r, init->mode | 0x40);
--			break;
--		case VESA_POWERDOWN:
--			out_8(&p->valkyrie_regs->mode.r, 0x66);
--			break;
--		}
--	}
--	return 0;
--}
--
--static int valkyriefb_getcolreg(u_int regno, u_int *red, u_int *green,
--			     u_int *blue, u_int *transp, struct fb_info *info)
-+static int valkyriefb_blank(int blank_mode, struct fb_info *info)
- {
- 	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info;
-+	struct fb_par_valkyrie *par = info->par;
-+	struct valkyrie_regvals	*init = par->init;
- 
--	if (regno > 255)
-+	if (init == NULL)
- 		return 1;
--	*red = (p->palette[regno].red<<8) | p->palette[regno].red;
--	*green = (p->palette[regno].green<<8) | p->palette[regno].green;
--	*blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
- 
-+	switch (blank_mode) {
-+	case 0:			/* unblank */
-+		out_8(&p->valkyrie_regs->mode.r, init->mode);
-+		break;
-+	case 1:
-+		return 1;	/* get caller to set CLUT to all black */
-+	case VESA_VSYNC_SUSPEND+1:
-+	case VESA_HSYNC_SUSPEND+1:
-+		/*
-+		 * [kps] Value extracted from MacOS. I don't know
-+		 * whether this bit disables hsync or vsync, or
-+		 * whether the hardware can do the other as well.
-+		 */
-+		out_8(&p->valkyrie_regs->mode.r, init->mode | 0x40);
-+		break;
-+	case VESA_POWERDOWN+1:
-+		out_8(&p->valkyrie_regs->mode.r, 0x66);
-+		break;
-+	}
- 	return 0;
- }
- 
-@@ -328,16 +228,13 @@ static int valkyriefb_setcolreg(u_int re
- {
- 	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) info;
- 	volatile struct cmap_regs *cmap_regs = p->cmap_regs;
--
-+	struct fb_par_valkyrie *par = info->par;
- 
- 	if (regno > 255)
- 		return 1;
- 	red >>= 8;
- 	green >>= 8;
- 	blue >>= 8;
--	p->palette[regno].red = red;
--	p->palette[regno].green = green;
--	p->palette[regno].blue = blue;
- 
- 	/* tell clut which address to fill */
- 	out_8(&p->cmap_regs->addr, regno);
-@@ -347,11 +244,9 @@ static int valkyriefb_setcolreg(u_int re
- 	out_8(&cmap_regs->lut, green);
- 	out_8(&cmap_regs->lut, blue);
- 
--	if (regno < 16) {
--#ifdef FBCON_HAS_CFB16
--		p->fbcon_cfb16_cmap[regno] = (regno << 10) | (regno << 5) | regno;
--#endif
--	}
-+	if (regno < 16 && par->cmode == CMODE_16)
-+		((u32 *)info->pseudo_palette)[regno] =
-+			(regno << 10) | (regno << 5) | regno;
- 
- 	return 0;
- }
-@@ -359,10 +254,11 @@ static int valkyriefb_setcolreg(u_int re
- static int valkyrie_vram_reqd(int video_mode, int color_mode)
- {
- 	int pitch;
-+	struct valkyrie_regvals *init = valkyrie_reg_init[video_mode-1];
- 	
--	if ((pitch = valkyrie_reg_init[video_mode-1]->pitch[color_mode]) == 0)
--		pitch = 2 * valkyrie_reg_init[video_mode-1]->pitch[0];
--	return valkyrie_reg_init[video_mode-1]->vres * pitch;
-+	if ((pitch = init->pitch[color_mode]) == 0)
-+		pitch = 2 * init->pitch[0];
-+	return init->vres * pitch;
- }
- 
- static void set_valkyrie_clock(unsigned char *params)
-@@ -380,14 +276,10 @@ static void set_valkyrie_clock(unsigned 
- #endif
- }
- 
--static void __init init_valkyrie(struct fb_info_valkyrie *p)
-+static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p)
- {
--	struct fb_par_valkyrie *par = &p->par;
--	struct fb_var_screeninfo var;
--	int j, k;
--
- 	p->sense = read_valkyrie_sense(p);
--	printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
-+	printk(KERN_INFO "Monitor sense value = 0x%x\n", p->sense);
- 
- 	/* Try to pick a video mode out of NVRAM if we have one. */
- #ifndef CONFIG_MAC
-@@ -409,80 +301,22 @@ static void __init init_valkyrie(struct 
- #endif
- 
- 	/*
--	 * Reduce the pixel size if we don't have enough VRAM or bandwitdh.
-+	 * Reduce the pixel size if we don't have enough VRAM or bandwidth.
- 	 */
--	if (default_cmode < CMODE_8
--	 || default_cmode > CMODE_16
--	 || valkyrie_reg_init[default_vmode-1]->pitch[default_cmode] == 0
--	 || valkyrie_vram_reqd(default_vmode, default_cmode) > p->total_vram)
-+	if (default_cmode < CMODE_8 || default_cmode > CMODE_16
-+	    || valkyrie_reg_init[default_vmode-1]->pitch[default_cmode] == 0
-+	    || valkyrie_vram_reqd(default_vmode, default_cmode) > p->total_vram)
- 		default_cmode = CMODE_8;
--	
--	printk(KERN_INFO "using video mode %d and color mode %d.\n", default_vmode, default_cmode);
- 
--	mac_vmode_to_var(default_vmode, default_cmode, &var);
--	if (valkyrie_var_to_par(&var, par, &p->info)) {
--	    printk(KERN_ERR "valkyriefb: can't set default video mode\n");
--	    return ;
--	}
--	
--	valkyrie_init_fix(&p->fix, p);
--	valkyrie_par_to_fix(&p->par, &p->fix, p);
--	valkyrie_par_to_var(&p->par, &p->var);
--	valkyrie_init_display(&p->disp);
--	valkyrie_par_to_display(&p->par, &p->disp, &p->fix, p);
--	valkyrie_init_info(&p->info, p);
--
--	/* Initialize colormap */
--	for (j = 0; j < 16; j++) {
--		k = color_table[j];
--		p->palette[j].red = default_red[k];
--		p->palette[j].green = default_grn[k];
--		p->palette[j].blue = default_blu[k];
--	}
--	
--	valkyrie_set_var (&var, -1, &p->info);
--
--	if (register_framebuffer(&p->info) < 0) {
--		kfree(p);
--		return;
--	}
--	
--	printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node);	
--}
--
--static void valkyrie_set_par(const struct fb_par_valkyrie *par,
--			     struct fb_info_valkyrie *p)
--{
--	struct valkyrie_regvals	*init;
--	volatile struct valkyrie_regs *valkyrie_regs = p->valkyrie_regs;
--	int vmode, cmode;
--	
--	vmode = par->vmode;
--	cmode = par->cmode;
--	
--	if (vmode <= 0
--	 || vmode > VMODE_MAX
--	 || (init = valkyrie_reg_init[vmode - 1]) == NULL)
--		panic("valkyrie: display mode %d not supported", vmode);
--
--	/* Reset the valkyrie */
--	out_8(&valkyrie_regs->status.r, 0);
--	udelay(100);
--
--	/* Initialize display timing registers */
--	out_8(&valkyrie_regs->mode.r, init->mode | 0x80);
--	out_8(&valkyrie_regs->depth.r, cmode + 3);
--	set_valkyrie_clock(init->clock_params);
--	udelay(100);
--
--	/* Turn on display */
--	out_8(&valkyrie_regs->mode.r, init->mode);
-+	printk(KERN_INFO "using video mode %d and color mode %d.\n",
-+	       default_vmode, default_cmode);
- }
- 
- int __init valkyriefb_init(void)
- {
- 	struct fb_info_valkyrie	*p;
- 	unsigned long frame_buffer_phys, cmap_regs_phys, flags;
-+	int err;
- 
- #ifdef CONFIG_MAC
- 	if (!MACH_IS_MAC)
-@@ -503,10 +337,11 @@ int __init valkyriefb_init(void)
- 	if (dp == 0)
- 		return 0;
- 
--	if(dp->n_addrs != 1) {
--		printk(KERN_ERR "expecting 1 address for valkyrie (got %d)", dp->n_addrs);
-+	if (dp->n_addrs != 1) {
-+		printk(KERN_ERR "expecting 1 address for valkyrie (got %d)\n",
-+		       dp->n_addrs);
- 		return 0;
--	}	
-+	}
- 
- 	frame_buffer_phys = dp->addrs[0].address;
- 	cmap_regs_phys = dp->addrs[0].address+0x304000;
-@@ -515,7 +350,7 @@ int __init valkyriefb_init(void)
- 
- 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
- 	if (p == 0)
--		return 0;
-+		return -ENOMEM;
- 	memset(p, 0, sizeof(*p));
- 
- 	/* Map in frame buffer and registers */
-@@ -524,14 +359,42 @@ int __init valkyriefb_init(void)
- 		return 0;
- 	}
- 	p->total_vram = 0x100000;
--	p->frame_buffer_phys  = frame_buffer_phys;
-+	p->frame_buffer_phys = frame_buffer_phys;
- 	p->frame_buffer = __ioremap(frame_buffer_phys, p->total_vram, flags);
- 	p->cmap_regs_phys = cmap_regs_phys;
- 	p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
- 	p->valkyrie_regs_phys = cmap_regs_phys+0x6000;
- 	p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, 0x1000);
--	init_valkyrie(p);
-+	err = -ENOMEM;
-+	if (p->frame_buffer == NULL || p->cmap_regs == NULL
-+	    || p->valkyrie_regs == NULL) {
-+		printk(KERN_ERR "valkyriefb: couldn't map resources\n");
-+		goto out_free;
-+	}
-+
-+	valkyrie_choose_mode(p);
-+	mac_vmode_to_var(default_vmode, default_cmode, &p->info.var);
-+	valkyrie_init_info(&p->info, p);
-+	valkyrie_init_fix(&p->info.fix, p);
-+	if (valkyriefb_set_par(&p->info))
-+		/* "can't happen" */
-+		printk(KERN_ERR "valkyriefb: can't set default video mode\n");
-+
-+	if ((err = register_framebuffer(&p->info)) != 0)
-+		goto out_free;
-+
-+	printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node);
- 	return 0;
-+
-+ out_free:
-+	if (p->frame_buffer)
-+		iounmap(p->frame_buffer);
-+	if (p->cmap_regs)
-+		iounmap(p->cmap_regs);
-+	if (p->valkyrie_regs)
-+		iounmap(p->valkyrie_regs);
-+	kfree(p);
-+	return err;
- }
- 
- /*
-@@ -541,22 +404,22 @@ static int read_valkyrie_sense(struct fb
- {
- 	int sense, in;
- 
--    out_8(&p->valkyrie_regs->msense.r, 0);   /* release all lines */
--    __delay(20000);
--    sense = ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x70) << 4;
--    /* drive each sense line low in turn and collect the other 2 */
--    out_8(&p->valkyrie_regs->msense.r, 4);   /* drive A low */
--    __delay(20000);
--    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x30);
--    out_8(&p->valkyrie_regs->msense.r, 2);   /* drive B low */
--    __delay(20000);
--    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x40) >> 3;
-+	out_8(&p->valkyrie_regs->msense.r, 0);   /* release all lines */
-+	__delay(20000);
-+	sense = ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x70) << 4;
-+	/* drive each sense line low in turn and collect the other 2 */
-+	out_8(&p->valkyrie_regs->msense.r, 4);   /* drive A low */
-+	__delay(20000);
-+	sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x30);
-+	out_8(&p->valkyrie_regs->msense.r, 2);   /* drive B low */
-+	__delay(20000);
-+	sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x40) >> 3;
- 	sense |= (in & 0x10) >> 2;
--    out_8(&p->valkyrie_regs->msense.r, 1);   /* drive C low */
--    __delay(20000);
--    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x60) >> 5;
-+	out_8(&p->valkyrie_regs->msense.r, 1);   /* drive C low */
-+	__delay(20000);
-+	sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x60) >> 5;
- 
--    out_8(&p->valkyrie_regs->msense.r, 7);
-+	out_8(&p->valkyrie_regs->msense.r, 7);
- 
- 	return sense;
- }
-@@ -565,8 +428,6 @@ static int read_valkyrie_sense(struct fb
-  * This routine takes a user-supplied var,
-  * and picks the best vmode/cmode from it.
-  */
--static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
--	struct fb_par_valkyrie *par, const struct fb_info *fb_info)
- 
- /* [bkn] I did a major overhaul of this function.
-  *
-@@ -589,55 +450,56 @@ static int valkyrie_var_to_par(struct fb
-  * good start...
-  */
- 
-+static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
-+	struct fb_par_valkyrie *par, const struct fb_info *fb_info)
- {
--	int bpp = var->bits_per_pixel;
-+	int vmode, cmode;
- 	struct valkyrie_regvals *init;
- 	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) fb_info;
- 
--
--	if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0) {
--		printk(KERN_ERR "valkyrie_var_to_par: %dx%dx%d unsuccessful.\n",var->xres,var->yres,var->bits_per_pixel);
-+	if (mac_var_to_vmode(var, &vmode, &cmode) != 0) {
-+		printk(KERN_ERR "valkyriefb: can't do %dx%dx%d.\n",
-+		       var->xres, var->yres, var->bits_per_pixel);
- 		return -EINVAL;
- 	}
- 
- 	/* Check if we know about the wanted video mode */
--	if(!valkyrie_reg_init[par->vmode-1]) {
--		printk(KERN_ERR "valkyrie_var_to_par: vmode %d not valid.\n", par->vmode);
-+	if (vmode < 1 || vmode > VMODE_MAX || !valkyrie_reg_init[vmode-1]) {
-+		printk(KERN_ERR "valkyriefb: vmode %d not valid.\n", vmode);
- 		return -EINVAL;
- 	}
--
--	par->xres = var->xres;
--	par->yres = var->yres;
--	par->xoffset = 0;
--	par->yoffset = 0;
--	par->vxres = par->xres;
--	par->vyres = par->yres;
- 	
--	if (var->xres_virtual > var->xres || var->yres_virtual > var->yres
--		|| var->xoffset != 0 || var->yoffset != 0) {
-+	if (cmode != CMODE_8 && cmode != CMODE_16) {
-+		printk(KERN_ERR "valkyriefb: cmode %d not valid.\n", cmode);
- 		return -EINVAL;
- 	}
- 
--	if (bpp <= 8)
--		par->cmode = CMODE_8;
--	else if (bpp <= 16)
--		par->cmode = CMODE_16;
--	else {
--		printk(KERN_ERR "valkyrie_var_to_par: cmode %d not supported.\n", par->cmode);
-+	if (var->xres_virtual > var->xres || var->yres_virtual > var->yres
-+	    || var->xoffset != 0 || var->yoffset != 0) {
- 		return -EINVAL;
- 	}
- 
--	init = valkyrie_reg_init[par->vmode-1];
--	if (init->pitch[par->cmode] == 0) {
--		printk(KERN_ERR "valkyrie_var_to_par: vmode %d does not support cmode %d.\n", par->vmode, par->cmode);
-+	init = valkyrie_reg_init[vmode-1];
-+	if (init->pitch[cmode] == 0) {
-+		printk(KERN_ERR "valkyriefb: vmode %d does not support "
-+		       "cmode %d.\n", vmode, cmode);
- 		return -EINVAL;
- 	}
- 
--	if (valkyrie_vram_reqd(par->vmode, par->cmode) > p->total_vram) {
--		printk(KERN_ERR "valkyrie_var_to_par: not enough ram for vmode %d, cmode %d.\n", par->vmode, par->cmode);
-+	if (valkyrie_vram_reqd(vmode, cmode) > p->total_vram) {
-+		printk(KERN_ERR "valkyriefb: not enough ram for vmode %d, "
-+		       "cmode %d.\n", vmode, cmode);
- 		return -EINVAL;
- 	}
- 
-+	par->vmode = vmode;
-+	par->cmode = cmode;
-+	par->init = init;
-+	par->xres = var->xres;
-+	par->yres = var->yres;
-+	par->vxres = par->xres;
-+	par->vyres = par->yres;
-+
- 	return 0;
- }
- 
-@@ -653,7 +515,9 @@ static void valkyrie_init_fix(struct fb_
- 	fix->mmio_start = p->valkyrie_regs_phys;
- 	fix->mmio_len = sizeof(struct valkyrie_regs);
- 	fix->type = FB_TYPE_PACKED_PIXELS;
--	
-+	fix->smem_start = p->frame_buffer_phys + 0x1000;
-+	fix->smem_len = p->total_vram;
-+
- 	fix->type_aux = 0;
- 	fix->ywrapstep = 0;
- 	fix->ypanstep = 0;
-@@ -663,67 +527,23 @@ static void valkyrie_init_fix(struct fb_
- 
- /* Fix must already be inited above */
- static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,
--	struct fb_fix_screeninfo *fix,
--	struct fb_info_valkyrie *p)
-+	struct fb_fix_screeninfo *fix)
- {
--	fix->smem_start = p->frame_buffer_phys + 0x1000;
--#if 1
- 	fix->smem_len = valkyrie_vram_reqd(par->vmode, par->cmode);
--#else
--	fix->smem_len = p->total_vram;
--#endif
- 	fix->visual = (par->cmode == CMODE_8) ?
- 		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
- 	fix->line_length = par->vxres << par->cmode;
- 		/* ywrapstep, xpanstep, ypanstep */
- }
- 
--static void valkyrie_init_display(struct display *disp)
--{
--	memset(disp, 0, sizeof(*disp));
--	disp->can_soft_blank = can_soft_blank;
--	disp->scrollmode = SCROLL_YREDRAW;
--}
--
--static void valkyrie_par_to_display(struct fb_par_valkyrie *par,
--  struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p)
--{
--	disp->var = p->var;
--
--	if(disp->scrollmode != SCROLL_YREDRAW) {
--		printk(KERN_ERR "Scroll mode not YREDRAW in valkyrie_par_to_display\n");
--		disp->scrollmode = SCROLL_YREDRAW;
--	}
--	switch (par->cmode) {
--#ifdef FBCON_HAS_CFB8
--                case CMODE_8:
--                        disp->dispsw = &fbcon_cfb8;
--                        break;
--#endif
--#ifdef FBCON_HAS_CFB16
--                case CMODE_16:
--                        disp->dispsw = &fbcon_cfb16;
--                        disp->dispsw_data = p->fbcon_cfb16_cmap;
--                        break;
--#endif
--                default:
--                        disp->dispsw = &fbcon_dummy;
--                        break;
--        }
--}
--
- static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p)
- {
--	strcpy(info->modename, p->fix.id);
- 	info->fbops = &valkyriefb_ops;
- 	info->screen_base = (char *) p->frame_buffer + 0x1000;
--	info->disp = &p->disp;
--	info->currcon = -1;
--	strcpy(info->fontname, fontname);
--	info->changevar = NULL;
--	info->switch_con = &valkyriefb_switch;
--	info->updatevar = &valkyriefb_updatevar;
- 	info->flags = FBINFO_FLAG_DEFAULT;
-+	info->pseudo_palette = p->pseudo_palette;
-+	fb_alloc_cmap(&info->cmap, 256, 0);
-+	info->par = &p->par;
- }
- 
- 
-@@ -738,41 +558,23 @@ int __init valkyriefb_setup(char *option
- 		return 0;
- 
- 	while ((this_opt = strsep(&options, ",")) != NULL) {
--		if (!strncmp(this_opt, "font:", 5)) {
--			char *p;
--			int i;
--
--			p = this_opt + 5;
--			for (i = 0; i < sizeof(fontname) - 1; i++)
--				if (!*p || *p == ' ' || *p == ',')
--					break;
--			memcpy(fontname, this_opt + 5, i);
--			fontname[i] = 0;
--		}
--		else if (!strncmp(this_opt, "vmode:", 6)) {
-+		if (!strncmp(this_opt, "vmode:", 6)) {
- 	    		int vmode = simple_strtoul(this_opt+6, NULL, 0);
--	    	if (vmode > 0 && vmode <= VMODE_MAX)
-+			if (vmode > 0 && vmode <= VMODE_MAX)
- 				default_vmode = vmode;
- 		}
- 		else if (!strncmp(this_opt, "cmode:", 6)) {
- 			int depth = simple_strtoul(this_opt+6, NULL, 0);
- 			switch (depth) {
--			 case 8:
--			    default_cmode = CMODE_8;
--			    break;
--			 case 15:
--			 case 16:
--			    default_cmode = CMODE_16;
--			    break;
-+			case 8:
-+				default_cmode = CMODE_8;
-+				break;
-+			case 15:
-+			case 16:
-+				default_cmode = CMODE_16;
-+				break;
- 			}
- 		}
--		/* XXX - remove these options once blanking has been tested */
--		else if (!strncmp(this_opt, "noblank", 7)) {
--			can_soft_blank = 0;
--		}
--		else if (!strncmp(this_opt, "blank", 5)) {
--			can_soft_blank = 1;
--		}
- 	}
- 	return 0;
- }
---- linux-2.6.0-test1/drivers/video/vesafb.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/drivers/video/vesafb.c	2003-07-19 17:03:50.000000000 -0700
-@@ -51,7 +51,7 @@ static struct fb_info fb_info;
- static u32 pseudo_palette[17];
- 
- static int             inverse   = 0;
--static int             mtrr      = 0;
-+static int             mtrr      = 1;
- 
- static int             pmi_setpal = 0;	/* pmi for palette changes ??? */
- static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */
-@@ -208,6 +208,8 @@ int __init vesafb_setup(char *options)
- 			pmi_setpal=1;
- 		else if (! strcmp(this_opt, "mtrr"))
- 			mtrr=1;
-+		else if (! strcmp(this_opt, "nomtrr"))
-+			mtrr=0;
- 	}
- 	return 0;
- }
-@@ -231,6 +233,12 @@ int __init vesafb_init(void)
- 	vesafb_fix.visual   = (vesafb_defined.bits_per_pixel == 8) ?
- 		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- 
-+	/* limit framebuffer size to 16 MB.  Otherwise we'll eat tons of
-+	 * kernel address space for nothing if the gfx card has alot of
-+	 * memory (>= 128 MB isn't uncommon these days ...) */
-+	if (vesafb_fix.smem_len > 16 * 1024 * 1024)
-+		vesafb_fix.smem_len = 16 * 1024 * 1024;
-+
- #ifndef __i386__
- 	screen_info.vesapm_seg = 0;
- #endif
---- linux-2.6.0-test1/fs/aio.c	2003-07-13 21:44:34.000000000 -0700
-+++ 25/fs/aio.c	2003-07-19 17:07:03.000000000 -0700
-@@ -28,6 +28,8 @@
- #include <linux/module.h>
- #include <linux/highmem.h>
- #include <linux/workqueue.h>
-+#include <linux/writeback.h>
-+#include <linux/pagemap.h>
- 
- #include <asm/kmap_types.h>
- #include <asm/uaccess.h>
-@@ -39,6 +41,9 @@
- #define dprintk(x...)	do { ; } while (0)
- #endif
- 
-+long aio_run = 0; /* for testing only */
-+long aio_wakeups = 0; /* for testing only */
-+
- /*------ sysctl variables----*/
- atomic_t aio_nr = ATOMIC_INIT(0);	/* current system wide number of aio requests */
- unsigned aio_max_nr = 0x10000;	/* system wide maximum number of aio requests */
-@@ -48,6 +53,7 @@ static kmem_cache_t	*kiocb_cachep;
- static kmem_cache_t	*kioctx_cachep;
- 
- static struct workqueue_struct *aio_wq;
-+static struct workqueue_struct *aio_fput_wq;
- 
- /* Used for rare fput completion. */
- static void aio_fput_routine(void *);
-@@ -75,6 +81,7 @@ static int __init aio_setup(void)
- 		panic("unable to create kioctx cache");
- 
- 	aio_wq = create_workqueue("aio");
-+	aio_fput_wq = create_workqueue("aio_fput");
- 
- 	pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
- 
-@@ -281,6 +288,7 @@ static void aio_cancel_all(struct kioctx
- 		struct kiocb *iocb = list_kiocb(pos);
- 		list_del_init(&iocb->ki_list);
- 		cancel = iocb->ki_cancel;
-+		kiocbSetCancelled(iocb);
- 		if (cancel) {
- 			iocb->ki_users++;
- 			spin_unlock_irq(&ctx->ctx_lock);
-@@ -341,6 +349,11 @@ void exit_aio(struct mm_struct *mm)
- 		aio_cancel_all(ctx);
- 
- 		wait_for_all_aios(ctx);
-+		/*
-+		 * this is an overkill, but ensures we don't leave
-+		 * the ctx on the aio_wq
-+		 */
-+		flush_workqueue(aio_wq);
- 
- 		if (1 != atomic_read(&ctx->users))
- 			printk(KERN_DEBUG
-@@ -395,6 +408,7 @@ static struct kiocb *__aio_get_req(struc
- 	req->ki_cancel = NULL;
- 	req->ki_retry = NULL;
- 	req->ki_user_obj = NULL;
-+	INIT_LIST_HEAD(&req->ki_run_list);
- 
- 	/* Check if the completion queue has enough free space to
- 	 * accept an event from this io.
-@@ -494,7 +508,7 @@ static int __aio_put_req(struct kioctx *
- 		spin_lock(&fput_lock);
- 		list_add(&req->ki_list, &fput_head);
- 		spin_unlock(&fput_lock);
--		queue_work(aio_wq, &fput_work);
-+		queue_work(aio_fput_wq, &fput_work);
- 	} else
- 		really_put_req(ctx, req);
- 	return 1;
-@@ -536,65 +550,302 @@ struct kioctx *lookup_ioctx(unsigned lon
- 	return ioctx;
- }
- 
-+/*
-+ * use_mm
-+ * 	Makes the calling kernel thread take on the specified
-+ * 	mm context.
-+ * 	Called by the retry thread execute retries within the
-+ * 	iocb issuer's mm context, so that copy_from/to_user
-+ * 	operations work seamlessly for aio.
-+ * 	(Note: this routine is intended to be called only
-+ * 	from a kernel thread context)
-+ */
- static void use_mm(struct mm_struct *mm)
- {
--	struct mm_struct *active_mm = current->active_mm;
-+	struct mm_struct *active_mm;
-+	struct task_struct *tsk = current;
-+
-+	task_lock(tsk);
-+	active_mm = tsk->active_mm;
- 	atomic_inc(&mm->mm_count);
--	current->mm = mm;
--	if (mm != active_mm) {
--		current->active_mm = mm;
--		activate_mm(active_mm, mm);
--	}
-+	tsk->mm = mm;
-+	tsk->active_mm = mm;
-+	activate_mm(active_mm, mm);
-+	task_unlock(tsk);
-+
- 	mmdrop(active_mm);
- }
- 
--static void unuse_mm(struct mm_struct *mm)
-+/*
-+ * unuse_mm
-+ * 	Reverses the effect of use_mm, i.e. releases the
-+ * 	specified mm context which was earlier taken on
-+ * 	by the calling kernel thread
-+ * 	(Note: this routine is intended to be called only
-+ * 	from a kernel thread context)
-+ *
-+ * Comments: Called with ctx->ctx_lock held. This nests
-+ * task_lock instead ctx_lock.
-+ */
-+void unuse_mm(struct mm_struct *mm)
- {
--	current->mm = NULL;
-+	struct task_struct *tsk = current;
-+
-+	task_lock(tsk);
-+	tsk->mm = NULL;
- 	/* active_mm is still 'mm' */
--	enter_lazy_tlb(mm, current);
-+	enter_lazy_tlb(mm, tsk);
-+	task_unlock(tsk);
- }
- 
--/* Run on kevent's context.  FIXME: needs to be per-cpu and warn if an
-- * operation blocks.
-+/*
-+ * Queue up a kiocb to be retried. Assumes that the kiocb
-+ * has already been marked as kicked, and places it on
-+ * the retry run list for the corresponding ioctx, if it
-+ * isn't already queued. Returns 1 if it actually queued
-+ * the kiocb (to tell the caller to activate the work
-+ * queue to process it), or 0, if it found that it was
-+ * already queued.
-+ *
-+ * Should be called with the spin lock iocb->ki_ctx->ctx_lock
-+ * held
-  */
--static void aio_kick_handler(void *data)
-+static inline int __queue_kicked_iocb(struct kiocb *iocb)
- {
--	struct kioctx *ctx = data;
-+	struct kioctx	*ctx = iocb->ki_ctx;
- 
--	use_mm(ctx->mm);
-+	if (list_empty(&iocb->ki_run_list)) {
-+		list_add_tail(&iocb->ki_run_list,
-+			&ctx->run_list);
-+		iocb->ki_queued++;
-+		return 1;
-+	}
-+	return 0;
-+}
- 
--	spin_lock_irq(&ctx->ctx_lock);
--	while (!list_empty(&ctx->run_list)) {
--		struct kiocb *iocb;
--		long ret;
-+/* aio_run_iocb
-+ * 	 This is the core aio execution routine. It is
-+ * 	 invoked both for initial i/o submission and
-+ * 	 subsequent retries via the aio_kick_handler.
-+ *       Expects to be invoked with iocb->ki_ctx->lock
-+ *       already held. The lock is released and reaquired
-+ *       as needed during processing.
-+ *
-+ * Calls the iocb retry method (already setup for the
-+ * iocb on initial submission) for operation specific
-+ * handling, but takes care of most of common retry
-+ * execution details for a given iocb. The retry method
-+ * needs to be non-blocking as far as possible, to avoid
-+ * holding up other iocbs waiting to be serviced by the
-+ * retry kernel thread.
-+ *
-+ * The trickier parts in this code have to do with
-+ * ensuring that only one retry instance is in progress
-+ * for a given iocb at any time. Providing that guarantee
-+ * simplifies the coding of individual aio operations as
-+ * it avoids various potential races.
-+ */
-+static ssize_t aio_run_iocb(struct kiocb *iocb)
-+{
-+	struct kioctx	*ctx = iocb->ki_ctx;
-+	ssize_t (*retry)(struct kiocb *);
-+	ssize_t ret;
- 
--		iocb = list_entry(ctx->run_list.next, struct kiocb,
--				  ki_run_list);
--		list_del(&iocb->ki_run_list);
--		iocb->ki_users ++;
--		spin_unlock_irq(&ctx->ctx_lock);
-+	if (iocb->ki_retried++ > 1024*1024) {
-+		printk("Maximal retry count.  Bytes done %Zd\n",
-+			iocb->ki_nbytes - iocb->ki_left);
-+		return -EAGAIN;
-+	}
-+
-+	if (!(iocb->ki_retried & 0xff)) {
-+		pr_debug("%ld retry: %d of %d (kick %ld, Q %ld run %ld, wake %ld)\n",
-+			iocb->ki_retried,
-+			iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
-+			iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
-+	}
-+
-+	if (!(retry = iocb->ki_retry)) {
-+		printk("aio_run_iocb: iocb->ki_retry = NULL\n");
-+		return 0;
-+	}
-+
-+	/*
-+	 * We don't want the next retry iteration for this
-+	 * operation to start until this one has returned and
-+	 * updated the iocb state. However, wait_queue functions
-+	 * can trigger a kick_iocb from interrupt context in the
-+	 * meantime, indicating that data is available for the next
-+	 * iteration. We want to remember that and enable the
-+	 * next retry iteration _after_ we are through with
-+	 * this one.
-+	 *
-+	 * So, in order to be able to register a "kick", but
-+	 * prevent it from being queued now, we clear the kick
-+	 * flag, but make the kick code *think* that the iocb is
-+	 * still on the run list until we are actually done.
-+	 * When we are done with this iteration, we check if
-+	 * the iocb was kicked in the meantime and if so, queue
-+	 * it up afresh.
-+	 */
-+
-+	kiocbClearKicked(iocb);
-+
-+	/*
-+	 * This is so that aio_complete knows it doesn't need to
-+	 * pull the iocb off the run list (We can't just call
-+	 * INIT_LIST_HEAD because we don't want a kick_iocb to
-+	 * queue this on the run list yet)
-+	 */
-+	iocb->ki_run_list.next = iocb->ki_run_list.prev = NULL;
-+	iocb->ki_retry = NULL;
-+	spin_unlock_irq(&ctx->ctx_lock);
-+
-+	/* Quit retrying if the i/o has been cancelled */
-+	if (kiocbIsCancelled(iocb)) {
-+		ret = -EINTR;
-+		aio_complete(iocb, ret, 0);
-+		/* must not access the iocb after this */
-+		goto out;
-+	}
-+
-+	/*
-+	 * Now we are all set to call the retry method in async
-+	 * context. By setting this thread's io_wait context
-+	 * to point to the wait queue entry inside the currently
-+	 * running iocb for the duration of the retry, we ensure
-+	 * that async notification wakeups are queued by the
-+	 * operation instead of blocking waits, and when notified,
-+	 * cause the iocb to be kicked for continuation (through
-+	 * the aio_wake_function callback).
-+	 */
-+	BUG_ON(current->io_wait != NULL);
-+	current->io_wait = &iocb->ki_wait;
-+	ret = retry(iocb);
-+	current->io_wait = NULL;
- 
--		kiocbClearKicked(iocb);
--		ret = iocb->ki_retry(iocb);
-+	if (-EIOCBRETRY != ret) {
- 		if (-EIOCBQUEUED != ret) {
-+			BUG_ON(!list_empty(&iocb->ki_wait.task_list));
- 			aio_complete(iocb, ret, 0);
--			iocb = NULL;
-+			/* must not access the iocb after this */
- 		}
-+	} else {
-+		/*
-+		 * Issue an additional retry to avoid waiting forever if
-+		 * no waits were queued (e.g. in case of a short read).
-+		 */
-+		if (list_empty(&iocb->ki_wait.task_list))
-+			kiocbSetKicked(iocb);
-+	}
-+out:
-+	spin_lock_irq(&ctx->ctx_lock);
- 
--		spin_lock_irq(&ctx->ctx_lock);
--		if (NULL != iocb)
--			__aio_put_req(ctx, iocb);
-+	if (-EIOCBRETRY == ret) {
-+		/*
-+		 * OK, now that we are done with this iteration
-+		 * and know that there is more left to go,
-+		 * this is where we let go so that a subsequent
-+		 * "kick" can start the next iteration
-+		 */
-+		iocb->ki_retry = retry;
-+		/* will make __queue_kicked_iocb succeed from here on */
-+		INIT_LIST_HEAD(&iocb->ki_run_list);
-+		/* we must queue the next iteration ourselves, if it
-+		 * has already been kicked */
-+		if (kiocbIsKicked(iocb)) {
-+			__queue_kicked_iocb(iocb);
-+		}
- 	}
-+	return ret;
-+}
-+
-+/*
-+ * __aio_run_iocbs:
-+ * 	Process all pending retries queued on the ioctx
-+ * 	run list.
-+ * Assumes it is operating within the aio issuer's mm
-+ * context. Expects to be called with ctx->ctx_lock held
-+ */
-+static void __aio_run_iocbs(struct kioctx *ctx)
-+{
-+	struct kiocb *iocb;
-+	ssize_t ret;
-+	int count = 0;
-+
-+	while (!list_empty(&ctx->run_list)) {
-+		iocb = list_entry(ctx->run_list.next, struct kiocb,
-+			ki_run_list);
-+		list_del(&iocb->ki_run_list);
-+		ret = aio_run_iocb(iocb);
-+		count++;
-+	}
-+	aio_run++;
-+}
-+
-+/*
-+ * aio_run_iocbs:
-+ * 	Process all pending retries queued on the ioctx
-+ * 	run list.
-+ * Assumes it is operating within the aio issuer's mm
-+ * context.
-+ */
-+static inline void aio_run_iocbs(struct kioctx *ctx)
-+{
-+	spin_lock_irq(&ctx->ctx_lock);
-+	__aio_run_iocbs(ctx);
- 	spin_unlock_irq(&ctx->ctx_lock);
-+}
- 
-+/*
-+ * aio_kick_handler:
-+ * 	Work queue handler triggered to process pending
-+ * 	retries on an ioctx. Takes on the aio issuer's
-+ * 	mm context before running the iocbs.
-+ * Run on aiod's context.
-+ */
-+static void aio_kick_handler(void *data)
-+{
-+	struct kioctx *ctx = data;
-+
-+	use_mm(ctx->mm);
-+	spin_lock_irq(&ctx->ctx_lock);
-+	__aio_run_iocbs(ctx);
- 	unuse_mm(ctx->mm);
-+	spin_unlock_irq(&ctx->ctx_lock);
- }
- 
--void kick_iocb(struct kiocb *iocb)
-+
-+/*
-+ * Called by kick_iocb to queue the kiocb for retry
-+ * and if required activate the aio work queue to process
-+ * it
-+ */
-+void queue_kicked_iocb(struct kiocb *iocb)
- {
- 	struct kioctx	*ctx = iocb->ki_ctx;
-+	unsigned long flags;
-+	int run = 0;
-+
-+	WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
-+
-+	spin_lock_irqsave(&ctx->ctx_lock, flags);
-+	run = __queue_kicked_iocb(iocb);
-+	spin_unlock_irqrestore(&ctx->ctx_lock, flags);
-+	if (run) {
-+		queue_work(aio_wq, &ctx->wq);
-+		aio_wakeups++;
-+	}
-+}
- 
-+/*
-+ * kick_iocb:
-+ * 	Called typically from a wait queue callback context
-+ * 	(aio_wake_function) to trigger a retry of the iocb.
-+ * 	The retry is usually executed by aio workqueue
-+ * 	threads (See aio_kick_handler).
-+ */
-+void kick_iocb(struct kiocb *iocb)
-+{
- 	/* sync iocbs are easy: they can only ever be executing from a 
- 	 * single context. */
- 	if (is_sync_kiocb(iocb)) {
-@@ -603,12 +854,10 @@ void kick_iocb(struct kiocb *iocb)
- 		return;
- 	}
- 
-+	iocb->ki_kicked++;
-+	/* If its already kicked we shouldn't queue it again */
- 	if (!kiocbTryKick(iocb)) {
--		unsigned long flags;
--		spin_lock_irqsave(&ctx->ctx_lock, flags);
--		list_add_tail(&iocb->ki_run_list, &ctx->run_list);
--		spin_unlock_irqrestore(&ctx->ctx_lock, flags);
--		schedule_work(&ctx->wq);
-+		queue_kicked_iocb(iocb);
- 	}
- }
- 
-@@ -661,6 +910,9 @@ int aio_complete(struct kiocb *iocb, lon
- 	 */
- 	spin_lock_irqsave(&ctx->ctx_lock, flags);
- 
-+	if (iocb->ki_run_list.prev && !list_empty(&iocb->ki_run_list))
-+		list_del_init(&iocb->ki_run_list);
-+
- 	ring = kmap_atomic(info->ring_pages[0], KM_IRQ1);
- 
- 	tail = info->tail;
-@@ -689,6 +941,11 @@ int aio_complete(struct kiocb *iocb, lon
- 
- 	pr_debug("added to ring %p at [%lu]\n", iocb, tail);
- 
-+	pr_debug("%ld retries: %d of %d (kicked %ld, Q %ld run %ld wake %ld)\n",
-+		iocb->ki_retried,
-+		iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
-+		iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
-+
- 	/* everything turned out well, dispose of the aiocb. */
- 	ret = __aio_put_req(ctx, iocb);
- 
-@@ -803,6 +1060,7 @@ static int read_events(struct kioctx *ct
- 	int			i = 0;
- 	struct io_event		ent;
- 	struct timeout		to;
-+	int 			event_loop = 0; /* testing only */
- 
- 	/* needed to zero any padding within an entry (there shouldn't be 
- 	 * any, but C is fun!
-@@ -852,7 +1110,6 @@ static int read_events(struct kioctx *ct
- 		add_wait_queue_exclusive(&ctx->wait, &wait);
- 		do {
- 			set_task_state(tsk, TASK_INTERRUPTIBLE);
--
- 			ret = aio_read_evt(ctx, &ent);
- 			if (ret)
- 				break;
-@@ -862,6 +1119,7 @@ static int read_events(struct kioctx *ct
- 			if (to.timed_out)	/* Only check after read evt */
- 				break;
- 			schedule();
-+			event_loop++;
- 			if (signal_pending(tsk)) {
- 				ret = -EINTR;
- 				break;
-@@ -889,6 +1147,9 @@ static int read_events(struct kioctx *ct
- 	if (timeout)
- 		clear_timeout(&to);
- out:
-+	pr_debug("event loop executed %d times\n", event_loop);
-+	pr_debug("aio_run %ld\n", aio_run);
-+	pr_debug("aio_wakeups %ld\n", aio_wakeups);
- 	return i ? i : ret;
- }
- 
-@@ -918,6 +1179,11 @@ static void io_destroy(struct kioctx *io
- 
- 	aio_cancel_all(ioctx);
- 	wait_for_all_aios(ioctx);
-+	/*
-+	 * this is an overkill, but ensures we don't leave
-+	 * the ctx on the aio_wq
-+	 */
-+	flush_workqueue(aio_wq);
- 	put_ioctx(ioctx);	/* once for the lookup */
- }
- 
-@@ -980,13 +1246,191 @@ asmlinkage long sys_io_destroy(aio_conte
- 	return -EINVAL;
- }
- 
-+/*
-+ * Retry method for aio_read (also used for first time submit)
-+ * Responsible for updating iocb state as retries progress
-+ */
-+static ssize_t aio_pread(struct kiocb *iocb)
-+{
-+	struct file *file = iocb->ki_filp;
-+	ssize_t ret = 0;
-+
-+	ret = file->f_op->aio_read(iocb, iocb->ki_buf,
-+		iocb->ki_left, iocb->ki_pos);
-+
-+	/*
-+	 * Can't just depend on iocb->ki_left to determine
-+	 * whether we are done. This may have been a short read.
-+	 */
-+	if (ret > 0) {
-+		iocb->ki_buf += ret;
-+		iocb->ki_left -= ret;
-+
-+		ret = -EIOCBRETRY;
-+	}
-+
-+	/* This means we must have transferred all that we could */
-+	/* No need to retry anymore */
-+	if ((ret == 0) || (iocb->ki_left == 0))
-+		ret = iocb->ki_nbytes - iocb->ki_left;
-+
-+	return ret;
-+}
-+
-+/*
-+ * Retry method for aio_write (also used for first time submit)
-+ * Responsible for updating iocb state as retries progress
-+ */
-+static ssize_t aio_pwrite(struct kiocb *iocb)
-+{
-+	struct file *file = iocb->ki_filp;
-+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-+	struct inode *inode = mapping->host;
-+	ssize_t ret = 0;
-+
-+	ret = file->f_op->aio_write(iocb, iocb->ki_buf,
-+				iocb->ki_left, iocb->ki_pos);
-+
-+	/*
-+	 * Even if iocb->ki_left = 0, we may need to wait
-+	 * for a balance_dirty_pages to complete
-+	 */
-+	if (ret > 0) {
-+		iocb->ki_buf += iocb->ki_buf ? ret : 0;
-+		iocb->ki_left -= ret;
-+
-+		ret = -EIOCBRETRY;
-+	}
-+
-+	/* This means we must have transferred all that we could */
-+	/* No need to retry anymore unless we need to osync data */
-+	if (ret == 0) {
-+		ret = iocb->ki_nbytes - iocb->ki_left;
-+		if (!iocb->ki_buf)
-+			return ret;
-+
-+		/* Set things up for potential O_SYNC */
-+		if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-+			iocb->ki_buf = NULL;
-+			iocb->ki_pos -= ret; /* back up fpos */
-+			iocb->ki_left = ret; /* sync what we have written out */
-+			iocb->ki_nbytes = ret;
-+			ret = -EIOCBRETRY;
-+		}
-+	}
-+
-+	return ret;
-+}
-+
-+static ssize_t aio_fdsync(struct kiocb *iocb)
-+{
-+	struct file *file = iocb->ki_filp;
-+	ssize_t ret = -EINVAL;
-+
-+	if (file->f_op->aio_fsync)
-+		ret = file->f_op->aio_fsync(iocb, 1);
-+	return ret;
-+}
-+
-+static ssize_t aio_fsync(struct kiocb *iocb)
-+{
-+	struct file *file = iocb->ki_filp;
-+	ssize_t ret = -EINVAL;
-+
-+	if (file->f_op->aio_fsync)
-+		ret = file->f_op->aio_fsync(iocb, 0);
-+	return ret;
-+}
-+
-+/*
-+ * aio_setup_iocb:
-+ *	Performs the initial checks and aio retry method
-+ *	setup for the kiocb at the time of io submission.
-+ */
-+ssize_t aio_setup_iocb(struct kiocb *kiocb)
-+{
-+	struct file *file = kiocb->ki_filp;
-+	ssize_t ret = 0;
-+
-+	switch (kiocb->ki_opcode) {
-+	case IOCB_CMD_PREAD:
-+		ret = -EBADF;
-+		if (unlikely(!(file->f_mode & FMODE_READ)))
-+			break;
-+		ret = -EFAULT;
-+		if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
-+			kiocb->ki_left)))
-+			break;
-+		ret = -EINVAL;
-+		if (file->f_op->aio_read)
-+			kiocb->ki_retry = aio_pread;
-+		break;
-+	case IOCB_CMD_PWRITE:
-+		ret = -EBADF;
-+		if (unlikely(!(file->f_mode & FMODE_WRITE)))
-+			break;
-+		ret = -EFAULT;
-+		if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
-+			kiocb->ki_left)))
-+			break;
-+		ret = -EINVAL;
-+		if (file->f_op->aio_write)
-+			kiocb->ki_retry = aio_pwrite;
-+		break;
-+	case IOCB_CMD_FDSYNC:
-+		ret = -EINVAL;
-+		if (file->f_op->aio_fsync)
-+			kiocb->ki_retry = aio_fdsync;
-+		break;
-+	case IOCB_CMD_FSYNC:
-+		ret = -EINVAL;
-+		if (file->f_op->aio_fsync)
-+			kiocb->ki_retry = aio_fsync;
-+		break;
-+	default:
-+		dprintk("EINVAL: io_submit: no operation provided\n");
-+		ret = -EINVAL;
-+	}
-+
-+	if (!kiocb->ki_retry)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+/*
-+ * aio_wake_function:
-+ * 	wait queue callback function for aio notification,
-+ * 	Simply triggers a retry of the operation via kick_iocb.
-+ *
-+ * 	This callback is specified in the wait queue entry in
-+ *	a kiocb	(current->io_wait points to this wait queue
-+ *	entry when an aio operation executes; it is used
-+ * 	instead of a synchronous wait when an i/o blocking
-+ *	condition is encountered during aio).
-+ *
-+ * Note:
-+ * This routine is executed with the wait queue lock held.
-+ * Since kick_iocb acquires iocb->ctx->ctx_lock, it nests
-+ * the ioctx lock inside the wait queue lock. This is safe
-+ * because this callback isn't used for wait queues which
-+ * are nested inside ioctx lock (i.e. ctx->wait)
-+ */
-+int aio_wake_function(wait_queue_t *wait, unsigned mode, int sync)
-+{
-+	struct kiocb *iocb = container_of(wait, struct kiocb, ki_wait);
-+
-+	list_del_init(&wait->task_list);
-+	kick_iocb(iocb);
-+	return 1;
-+}
-+
- int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
- 			 struct iocb *iocb)
- {
- 	struct kiocb *req;
- 	struct file *file;
- 	ssize_t ret;
--	char *buf;
- 
- 	/* enforce forwards compatibility on users */
- 	if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
-@@ -1027,51 +1471,31 @@ int io_submit_one(struct kioctx *ctx, st
- 	req->ki_user_data = iocb->aio_data;
- 	req->ki_pos = iocb->aio_offset;
- 
--	buf = (char *)(unsigned long)iocb->aio_buf;
-+	req->ki_buf = (char *)(unsigned long)iocb->aio_buf;
-+	req->ki_left = req->ki_nbytes = iocb->aio_nbytes;
-+	req->ki_opcode = iocb->aio_lio_opcode;
-+	init_waitqueue_func_entry(&req->ki_wait, aio_wake_function);
-+	INIT_LIST_HEAD(&req->ki_wait.task_list);
-+	req->ki_run_list.next = req->ki_run_list.prev = NULL;
-+	req->ki_retry = NULL;
-+	req->ki_retried = 0;
-+	req->ki_kicked = 0;
-+	req->ki_queued = 0;
-+	aio_run = 0;
-+	aio_wakeups = 0;
- 
--	switch (iocb->aio_lio_opcode) {
--	case IOCB_CMD_PREAD:
--		ret = -EBADF;
--		if (unlikely(!(file->f_mode & FMODE_READ)))
--			goto out_put_req;
--		ret = -EFAULT;
--		if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
--			goto out_put_req;
--		ret = -EINVAL;
--		if (file->f_op->aio_read)
--			ret = file->f_op->aio_read(req, buf,
--					iocb->aio_nbytes, req->ki_pos);
--		break;
--	case IOCB_CMD_PWRITE:
--		ret = -EBADF;
--		if (unlikely(!(file->f_mode & FMODE_WRITE)))
--			goto out_put_req;
--		ret = -EFAULT;
--		if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
--			goto out_put_req;
--		ret = -EINVAL;
--		if (file->f_op->aio_write)
--			ret = file->f_op->aio_write(req, buf,
--					iocb->aio_nbytes, req->ki_pos);
--		break;
--	case IOCB_CMD_FDSYNC:
--		ret = -EINVAL;
--		if (file->f_op->aio_fsync)
--			ret = file->f_op->aio_fsync(req, 1);
--		break;
--	case IOCB_CMD_FSYNC:
--		ret = -EINVAL;
--		if (file->f_op->aio_fsync)
--			ret = file->f_op->aio_fsync(req, 0);
--		break;
--	default:
--		dprintk("EINVAL: io_submit: no operation provided\n");
--		ret = -EINVAL;
--	}
-+	ret = aio_setup_iocb(req);
-+
-+	if (ret)
-+		goto out_put_req;
-+
-+	spin_lock_irq(&ctx->ctx_lock);
-+	ret = aio_run_iocb(req);
-+	spin_unlock_irq(&ctx->ctx_lock);
-+
-+	if (-EIOCBRETRY == ret)
-+		queue_work(aio_wq, &ctx->wq);
- 
--	if (likely(-EIOCBQUEUED == ret))
--		return 0;
--	aio_complete(req, ret, 0);
- 	return 0;
- 
- out_put_req:
---- linux-2.6.0-test1/fs/binfmt_elf.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/binfmt_elf.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1158,7 +1158,7 @@ static int elf_dump_thread_status(long s
- 	t->num_notes++;
- 	sz += notesize(&t->notes[0]);
- 
--	if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, &t->fpu))) {
-+	if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu))) {
- 		fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu), &(t->fpu));
- 		t->num_notes++;
- 		sz += notesize(&t->notes[1]);
-@@ -1286,7 +1286,7 @@ static int elf_core_dump(long signr, str
- 	fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
-   
-   	/* Try to dump the FPU. */
--	if ((prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, fpu)))
-+	if ((prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, fpu)))
- 		fill_note(notes +3, "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
- 	else
- 		--numnote;
---- linux-2.6.0-test1/fs/bio.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/bio.c	2003-07-19 17:03:50.000000000 -0700
-@@ -18,7 +18,7 @@
- #include <linux/mm.h>
- #include <linux/swap.h>
- #include <linux/bio.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
---- linux-2.6.0-test1/fs/buffer.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/buffer.c	2003-07-19 17:06:53.000000000 -0700
-@@ -91,6 +91,7 @@ void wake_up_buffer(struct buffer_head *
- {
- 	wait_queue_head_t *wq = bh_waitq_head(bh);
- 
-+	smp_mb();
- 	if (waitqueue_active(wq))
- 		wake_up_all(wq);
- }
-@@ -115,27 +116,50 @@ void unlock_buffer(struct buffer_head *b
- }
- 
- /*
-- * Block until a buffer comes unlocked.  This doesn't stop it
-+ * Wait until a buffer comes unlocked.  This doesn't stop it
-  * from becoming locked again - you have to lock it yourself
-  * if you want to preserve its state.
-+ * If the wait queue parameter specifies an async i/o callback,
-+ * then instead of blocking, we just queue up the callback
-+ * on the wait queue for async notification when the buffer gets
-+ * unlocked.
-+ * A NULL wait queue parameter defaults to synchronous behaviour
-  */
--void __wait_on_buffer(struct buffer_head * bh)
-+int __wait_on_buffer_wq(struct buffer_head * bh, wait_queue_t *wait)
- {
- 	wait_queue_head_t *wqh = bh_waitq_head(bh);
--	DEFINE_WAIT(wait);
-+	DEFINE_WAIT(local_wait);
-+
-+	if (!wait)
-+		wait = &local_wait;
- 
- 	if (atomic_read(&bh->b_count) == 0 &&
- 			(!bh->b_page || !PageLocked(bh->b_page)))
- 		buffer_error();
- 
- 	do {
--		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
- 		if (buffer_locked(bh)) {
- 			blk_run_queues();
-+			if (!is_sync_wait(wait)) {
-+				/*
-+				 * if we've queued an async wait queue
-+				 * callback do not block; just tell the
-+				 * caller to return and retry later when
-+				 * the callback is notified
-+				 */
-+				return -EIOCBRETRY;
-+			}
- 			io_schedule();
- 		}
- 	} while (buffer_locked(bh));
--	finish_wait(wqh, &wait);
-+	finish_wait(wqh, wait);
-+	return 0;
-+}
-+
-+void __wait_on_buffer(struct buffer_head * bh)
-+{
-+	__wait_on_buffer_wq(bh, NULL);
- }
- 
- static void
-@@ -414,6 +438,9 @@ __find_get_block_slow(struct block_devic
- 		bh = bh->b_this_page;
- 	} while (bh != head);
- 	buffer_error();
-+	printk("block=%llu, b_blocknr=%llu\n",
-+		(unsigned long long)block, (unsigned long long)bh->b_blocknr);
-+	printk("b_state=0x%08lx, b_size=%u\n", bh->b_state, bh->b_size);
- out_unlock:
- 	spin_unlock(&bd_mapping->private_lock);
- 	page_cache_release(page);
-@@ -1274,9 +1301,12 @@ void __bforget(struct buffer_head *bh)
- 	__brelse(bh);
- }
- 
--static struct buffer_head *__bread_slow(struct buffer_head *bh)
-+static struct buffer_head *__bread_slow_wq(struct buffer_head *bh,
-+		wait_queue_t *wait)
- {
--	lock_buffer(bh);
-+	if (-EIOCBRETRY == lock_buffer_wq(bh, wait))
-+		return ERR_PTR(-EIOCBRETRY);
-+
- 	if (buffer_uptodate(bh)) {
- 		unlock_buffer(bh);
- 		return bh;
-@@ -1286,7 +1316,8 @@ static struct buffer_head *__bread_slow(
- 		get_bh(bh);
- 		bh->b_end_io = end_buffer_io_sync;
- 		submit_bh(READ, bh);
--		wait_on_buffer(bh);
-+		if (-EIOCBRETRY == wait_on_buffer_wq(bh, wait))
-+			return ERR_PTR(-EIOCBRETRY);
- 		if (buffer_uptodate(bh))
- 			return bh;
- 	}
-@@ -1294,6 +1325,11 @@ static struct buffer_head *__bread_slow(
- 	return NULL;
- }
- 
-+static inline struct buffer_head *__bread_slow(struct buffer_head *bh)
-+{
-+	return __bread_slow_wq(bh, NULL);
-+}
-+
- /*
-  * Per-cpu buffer LRU implementation.  To reduce the cost of __find_get_block().
-  * The bhs[] array is sorted - newest buffer is at bhs[0].  Buffers have their
-@@ -1481,6 +1517,18 @@ __bread(struct block_device *bdev, secto
- }
- EXPORT_SYMBOL(__bread);
- 
-+struct buffer_head *
-+__bread_wq(struct block_device *bdev, sector_t block, int size,
-+	wait_queue_t *wait)
-+{
-+	struct buffer_head *bh = __getblk(bdev, block, size);
-+
-+	if (!buffer_uptodate(bh))
-+		bh = __bread_slow_wq(bh, wait);
-+	return bh;
-+}
-+EXPORT_SYMBOL(__bread_wq);
-+
- /*
-  * invalidate_bh_lrus() is called rarely - at unmount.  Because it is only for
-  * unmount it only needs to ensure that all buffers from the target device are
-@@ -1958,8 +2006,9 @@ static int __block_prepare_write(struct 
- 	/*
- 	 * If we issued read requests - let them complete.
- 	 */
--	while(wait_bh > wait) {
--		wait_on_buffer(*--wait_bh);
-+	while (wait_bh > wait) {
-+		if ((err = wait_on_buffer_wq(*--wait_bh, current->io_wait)))
-+			return err;
- 		if (!buffer_uptodate(*wait_bh))
- 			return -EIO;
- 	}
---- linux-2.6.0-test1/fs/cifs/CHANGES	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/cifs/CHANGES	2003-07-19 17:03:50.000000000 -0700
-@@ -1,3 +1,12 @@
-+Version 0.83
-+------------
-+Fix oops when mounting to long server names caused by inverted parms to kmalloc.
-+Fix MultiuserMount (/proc/fs/cifs configuration setting) so that when enabled
-+we will choose a cifs user session (smb uid) that better matches the local
-+uid if a) the mount uid does not match the current uid and b) we have another
-+session to the same server (ip address) for a different mount which
-+matches the current local uid.
-+
- Version 0.82
- ------------
- Add support for mknod of block or character devices.  Fix oplock
---- linux-2.6.0-test1/fs/cifs/cifsfs.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/cifs/cifsfs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -230,7 +230,7 @@ cifs_show_options(struct seq_file *s, st
- 	if (cifs_sb) {
- 		if (cifs_sb->tcon) {
- 			seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
--			if (cifs_sb->tcon->ses->userName)
-+			if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->userName))
- 				seq_printf(s, ",username=%s",
- 					   cifs_sb->tcon->ses->userName);
- 			if(cifs_sb->tcon->ses->domainName)
---- linux-2.6.0-test1/fs/cifs/cifsglob.h	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/cifs/cifsglob.h	2003-07-19 17:03:50.000000000 -0700
-@@ -155,7 +155,8 @@ struct cifsSesInfo {
- 	char *serverOS;		/* name of operating system underlying the server */
- 	char *serverNOS;	/* name of network operating system that the server is running */
- 	char *serverDomain;	/* security realm of server */
--	int Suid;		/* needed for user level security */
-+	int Suid;		/* remote smb uid  */
-+	uid_t linux_uid;        /* local Linux uid */
- 	int capabilities;
- 	char serverName[SERVER_NAME_LEN_WITH_NULL * 2];	/* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */
- 	char userName[MAX_USERNAME_SIZE + 1];
---- linux-2.6.0-test1/fs/cifs/connect.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/cifs/connect.c	2003-07-19 17:03:50.000000000 -0700
-@@ -405,7 +405,7 @@ parse_mount_options(char *options, const
- 				return 1;	/* needs_arg; */
- 			}
- 			if ((temp_len = strnlen(value, 300)) < 300) {
--				vol->UNC = kmalloc(GFP_KERNEL, temp_len);
-+				vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
- 				strcpy(vol->UNC,value);
- 				if (strncmp(vol->UNC, "//", 2) == 0) {
- 					vol->UNC[0] = '\\';
-@@ -482,7 +482,7 @@ parse_mount_options(char *options, const
- 			return 1;
- 		}
- 		if ((temp_len = strnlen(devname, 300)) < 300) {
--			vol->UNC = kmalloc(GFP_KERNEL, temp_len);
-+			vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
- 			strcpy(vol->UNC,devname);
- 			if (strncmp(vol->UNC, "//", 2) == 0) {
- 				vol->UNC[0] = '\\';
-@@ -860,7 +860,7 @@ cifs_mount(struct super_block *sb, struc
- 		FreeXid(xid);
- 		return -EINVAL;
- 	}
--	/* BB add support to use the multiuser_mount flag BB */
-+
- 	existingCifsSes =
- 	    find_tcp_session(sin_server.sin_addr.s_addr,
- 			     volume_info.username, &srvTcp);
-@@ -926,6 +926,7 @@ cifs_mount(struct super_block *sb, struc
- 			if (volume_info.domainname)
- 				strncpy(pSesInfo->domainName,
- 					volume_info.domainname,MAX_USERNAME_SIZE);
-+			pSesInfo->linux_uid = volume_info.linux_uid;
- 
- 			rc = setup_session(xid,pSesInfo, cifs_sb->local_nls);
- 			if(!rc)
---- linux-2.6.0-test1/fs/cifs/misc.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/cifs/misc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -190,6 +190,8 @@ header_assemble(struct smb_hdr *buffer, 
- {
- 	int i;
- 	__u32 tmp;
-+	struct list_head* temp_item;
-+	struct cifsSesInfo * ses;
- 	char *temp = (char *) buffer;
- 
- 	for (i = 0; i < MAX_CIFS_HDR_SIZE; i++) {
-@@ -225,7 +227,52 @@ header_assemble(struct smb_hdr *buffer, 
- 			if (treeCon->ses->capabilities & CAP_STATUS32) {
- 				buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- 			}
-+
- 			buffer->Uid = treeCon->ses->Suid;	/* always in LE format */
-+			if(multiuser_mount != 0) {
-+		/* For the multiuser case, there are few obvious technically  */
-+		/* possible mechanisms to match the local linux user (uid)    */
-+		/* to a valid remote smb user (smb_uid):		      */
-+		/* 	1) Query Winbind (or other local pam/nss daemon       */
-+		/* 	  for userid/password/logon_domain or credential      */
-+		/*      2) Query Winbind for uid to sid to username mapping   */
-+		/* 	   and see if we have a matching password for existing*/
-+		/*         session for that user perhas getting password by   */
-+		/*         adding a new pam_cifs module that stores passwords */
-+		/*         so that the cifs vfs can get at that for all logged*/
-+		/*	   on users					      */
-+		/*	3) (Which is the mechanism we have chosen)	      */
-+		/*	   Search through sessions to the same server for a   */
-+		/*	   a match on the uid that was passed in on mount     */
-+		/*         with the current processes uid (or euid?) and use  */
-+		/* 	   that smb uid.   If no existing smb session for     */
-+		/* 	   that uid found, use the default smb session ie     */
-+		/*         the smb session for the volume mounted which is    */
-+		/* 	   the same as would be used if the multiuser mount   */
-+		/* 	   flag were disabled.  */
-+
-+		/*  BB Add support for establishing new tCon and SMB Session  */
-+		/*      with userid/password pairs found on the smb session   */ 
-+		/*	for other target tcp/ip addresses 		BB    */
-+				if(current->uid != treeCon->ses->linux_uid) {
-+					cFYI(1,("Multiuser mode and UID did not match tcon uid "));
-+					read_lock(&GlobalSMBSeslock);
-+					list_for_each(temp_item, &GlobalSMBSessionList) {
-+						ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
-+						if(ses->linux_uid == current->uid) {
-+							if(ses->server == treeCon->ses->server) {
-+								cFYI(1,("found matching uid substitute right smb_uid"));  
-+								buffer->Uid = ses->Suid;
-+								break;
-+							} else {
-+								/* BB eventually call setup_session here */
-+								cFYI(1,("local UID found but smb sess with this server does not exist"));  
-+							}
-+						}
-+					}
-+					read_unlock(&GlobalSMBSeslock);
-+				}
-+			}
- 		}
- 		if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
- 			buffer->Flags2 |= SMBFLG2_DFS;
---- linux-2.6.0-test1/fs/cifs/TODO	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/cifs/TODO	2003-07-19 17:03:50.000000000 -0700
-@@ -17,9 +17,12 @@ c) multi-user mounts - multiplexed sessi
- 
- d) Kerberos/SPNEGO session setup support - (started)
- 
--e) NTLMv2 authentication and MD5-HMAC signing SMB PDUs - (mostly implemented)
--	signing necessary for some Windows 2003 servers in domain 
--	mode.
-+e) NTLMv2 authentication (mostly implemented)
-+
-+f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup 
-+used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
-+	and raw NTLMSSP already. This is important when enabling
-+	extended security and mounting to Windows 2003 Servers
- 
- f) Directory entry caching relies on a 1 second timer, rather than 
- using FindNotify or equivalent.  - (started)
-@@ -43,11 +46,9 @@ extra copy in/out of the socket buffers 
- 
- m) finish support for IPv6
- 
--n) send oplock break response when sent (oplock currently disabled in
--/proc/fs/cifs)
--
--o) reduces the oplock breaks coming from windows).  Piggyback identical
--file opens on top of each other by incrementing reference count rather
-+o) Better optimize open (and pathbased setfilesize) to reduce the
-+oplock breaks coming from windows srv.  Piggyback identical file
-+opens on top of each other by incrementing reference count rather
- than resending (helps reduce server resource utilization and avoid
- spurious oplock breaks).
- 
---- linux-2.6.0-test1/fs/cifs/transport.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/cifs/transport.c	2003-07-19 17:03:50.000000000 -0700
-@@ -45,6 +45,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffe
- 		cERROR(1, ("Null session passed in to AllocMidQEntry "));
- 		return NULL;
- 	}
-+	if (ses->server == NULL) {
-+		cERROR(1, ("Null TCP session in AllocMidQEntry"));
-+		return NULL;
-+	}
-+	
- 	temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
- 						       SLAB_KERNEL);
- 	if (temp == NULL)
-@@ -65,7 +70,6 @@ AllocMidQEntry(struct smb_hdr *smb_buffe
- 		/* Should we wake up tcp thread first? BB  */
- 		timeout = wait_event_interruptible_timeout(ses->server->response_q,
- 			(ses->server->tcpStatus == CifsGood), timeout);
--        cFYI(1,("timeout (after reconnection wait) %d",timeout));
- 	}
- 
- 	if (ses->server->tcpStatus == CifsGood) {
---- linux-2.6.0-test1/fs/compat_ioctl.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/fs/compat_ioctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -52,7 +52,7 @@
- #include <linux/raw.h>
- #include <linux/smb_fs.h>
- #include <linux/blkpg.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/elevator.h>
- #include <linux/rtc.h>
- #include <linux/pci.h>
---- linux-2.6.0-test1/fs/devfs/base.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/devfs/base.c	2003-07-19 17:03:50.000000000 -0700
-@@ -676,6 +676,7 @@
- #include <linux/smp.h>
- #include <linux/version.h>
- #include <linux/rwsem.h>
-+#include <linux/sched.h>
- 
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -1325,8 +1326,20 @@ static void free_dentry (struct devfs_en
- 
- static int is_devfsd_or_child (struct fs_info *fs_info)
- {
--    if (current == fs_info->devfsd_task) return (TRUE);
--    if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
-+    struct task_struct *p = current;
-+
-+    if (p == fs_info->devfsd_task) return (TRUE);
-+    if (p->pgrp == fs_info->devfsd_pgrp) return (TRUE);
-+    read_lock(&tasklist_lock);
-+    for ( ; p != &init_task; p = p->real_parent)
-+    {
-+	if (p == fs_info->devfsd_task)
-+	{
-+	    read_unlock (&tasklist_lock);
-+	    return (TRUE);
-+	}
-+    }
-+    read_unlock (&tasklist_lock);
-     return (FALSE);
- }   /*  End Function is_devfsd_or_child  */
- 
-@@ -1432,12 +1445,6 @@ int devfs_mk_bdev(dev_t dev, umode_t mod
- 	va_list args;
- 	int error, n;
- 
--	if (!S_ISBLK(mode)) {
--		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
--				__FUNCTION__, mode, buf);
--		return -EINVAL;
--	}
--
- 	va_start(args, fmt);
- 	n = vsnprintf(buf, 64, fmt, args);
- 	if (n >= 64 || !buf[0]) {
-@@ -1445,6 +1452,12 @@ int devfs_mk_bdev(dev_t dev, umode_t mod
- 				__FUNCTION__);
- 		return -EINVAL;
- 	}
-+	
-+	if (!S_ISBLK(mode)) {
-+		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-+				__FUNCTION__, mode, buf);
-+		return -EINVAL;
-+	}
- 
- 	de = _devfs_prepare_leaf(&dir, buf, mode);
- 	if (!de) {
-@@ -1478,12 +1491,6 @@ int devfs_mk_cdev(dev_t dev, umode_t mod
- 	va_list args;
- 	int error, n;
- 
--	if (!S_ISCHR(mode)) {
--		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
--				__FUNCTION__, mode, buf);
--		return -EINVAL;
--	}
--
- 	va_start(args, fmt);
- 	n = vsnprintf(buf, 64, fmt, args);
- 	if (n >= 64 || !buf[0]) {
-@@ -1492,6 +1499,12 @@ int devfs_mk_cdev(dev_t dev, umode_t mod
- 		return -EINVAL;
- 	}
- 
-+	if (!S_ISCHR(mode)) {
-+		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-+				__FUNCTION__, mode, buf);
-+		return -EINVAL;
-+	}
-+
- 	de = _devfs_prepare_leaf(&dir, buf, mode);
- 	if (!de) {
- 		printk(KERN_WARNING "%s: could not prepare leaf for %s\n",
---- linux-2.6.0-test1/fs/exec.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/exec.c	2003-07-19 17:07:16.000000000 -0700
-@@ -305,10 +305,10 @@ void put_dirty_page(struct task_struct *
- 	if (!pte_chain)
- 		goto out_sig;
- 	spin_lock(&tsk->mm->page_table_lock);
--	pmd = pmd_alloc(tsk->mm, pgd, address);
-+	pmd = pmd_alloc_map(tsk->mm, pgd, address);
- 	if (!pmd)
- 		goto out;
--	pte = pte_alloc_map(tsk->mm, pmd, address);
-+	pte = pte_alloc_map(tsk->mm, pgd, &pmd, address);
- 	if (!pte)
- 		goto out;
- 	if (!pte_none(*pte)) {
-@@ -320,6 +320,7 @@ void put_dirty_page(struct task_struct *
- 	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot))));
- 	pte_chain = page_add_rmap(page, pte, pte_chain);
- 	pte_unmap(pte);
-+	pmd_unmap(pmd);
- 	tsk->mm->rss++;
- 	spin_unlock(&tsk->mm->page_table_lock);
- 
-@@ -327,6 +328,8 @@ void put_dirty_page(struct task_struct *
- 	pte_chain_free(pte_chain);
- 	return;
- out:
-+	if (pmd)
-+		pmd_unmap(pmd);
- 	spin_unlock(&tsk->mm->page_table_lock);
- out_sig:
- 	__free_page(page);
---- linux-2.6.0-test1/fs/ext2/inode.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/ext2/inode.c	2003-07-19 17:06:55.000000000 -0700
-@@ -257,11 +257,12 @@ static int ext2_block_to_path(struct ino
-  *	or when it reads all @depth-1 indirect blocks successfully and finds
-  *	the whole chain, all way to the data (returns %NULL, *err == 0).
-  */
--static Indirect *ext2_get_branch(struct inode *inode,
-+static Indirect *ext2_get_branch_wq(struct inode *inode,
- 				 int depth,
- 				 int *offsets,
- 				 Indirect chain[4],
--				 int *err)
-+				 int *err,
-+				 wait_queue_t *wait)
- {
- 	struct super_block *sb = inode->i_sb;
- 	Indirect *p = chain;
-@@ -273,8 +274,8 @@ static Indirect *ext2_get_branch(struct 
- 	if (!p->key)
- 		goto no_block;
- 	while (--depth) {
--		bh = sb_bread(sb, le32_to_cpu(p->key));
--		if (!bh)
-+		bh = sb_bread_wq(sb, le32_to_cpu(p->key), wait);
-+		if (!bh || IS_ERR(bh))
- 			goto failure;
- 		read_lock(&EXT2_I(inode)->i_meta_lock);
- 		if (!verify_chain(chain, p))
-@@ -292,11 +293,21 @@ changed:
- 	*err = -EAGAIN;
- 	goto no_block;
- failure:
--	*err = -EIO;
-+	*err = IS_ERR(bh) ? PTR_ERR(bh) : -EIO;
- no_block:
- 	return p;
- }
- 
-+static Indirect *ext2_get_branch(struct inode *inode,
-+				 int depth,
-+				 int *offsets,
-+				 Indirect chain[4],
-+				 int *err)
-+{
-+	return ext2_get_branch_wq(inode, depth, offsets, chain,
-+		err, NULL);
-+}
-+
- /**
-  *	ext2_find_near - find a place for allocation with sufficient locality
-  *	@inode: owner
-@@ -536,7 +547,8 @@ changed:
-  * reachable from inode.
-  */
- 
--static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
-+static int ext2_get_block_wq(struct inode *inode, sector_t iblock,
-+	struct buffer_head *bh_result, int create, wait_queue_t *wait)
- {
- 	int err = -EIO;
- 	int offsets[4];
-@@ -551,7 +563,8 @@ static int ext2_get_block(struct inode *
- 		goto out;
- 
- reread:
--	partial = ext2_get_branch(inode, depth, offsets, chain, &err);
-+	partial = ext2_get_branch_wq(inode, depth, offsets, chain, &err,
-+		wait);
- 
- 	/* Simplest case - block found, no allocation needed */
- 	if (!partial) {
-@@ -565,7 +578,7 @@ got_it:
- 	}
- 
- 	/* Next simple case - plain lookup or failed read of indirect block */
--	if (!create || err == -EIO) {
-+	if (!create || err == -EIO || err == -EIOCBRETRY) {
- cleanup:
- 		while (partial > chain) {
- 			brelse(partial->bh);
-@@ -606,6 +619,19 @@ changed:
- 	goto reread;
- }
- 
-+static int ext2_get_block_async(struct inode *inode, sector_t iblock,
-+	struct buffer_head *bh_result, int create)
-+{
-+	return ext2_get_block_wq(inode, iblock, bh_result, create,
-+		current->io_wait);
-+}
-+
-+static int ext2_get_block(struct inode *inode, sector_t iblock,
-+	struct buffer_head *bh_result, int create)
-+{
-+	return ext2_get_block_wq(inode, iblock, bh_result, create, NULL);
-+}
-+
- static int ext2_writepage(struct page *page, struct writeback_control *wbc)
- {
- 	return block_write_full_page(page, ext2_get_block, wbc);
-@@ -627,7 +653,7 @@ static int
- ext2_prepare_write(struct file *file, struct page *page,
- 			unsigned from, unsigned to)
- {
--	return block_prepare_write(page,from,to,ext2_get_block);
-+	return block_prepare_write(page,from,to,ext2_get_block_async);
- }
- 
- static int
-@@ -1125,9 +1151,16 @@ void ext2_read_inode (struct inode * ino
- 				inode->i_mapping->a_ops = &ext2_aops;
- 		}
- 	} else {
-+		dev_t devno = le32_to_cpu(raw_inode->i_block[0]);
-+
-+		if (devno == 0) {
-+			unsigned int lo = le32_to_cpu(raw_inode->i_block[1]);
-+			unsigned int hi = le32_to_cpu(raw_inode->i_block[2]);
-+
-+			devno = ((unsigned long long) hi << 32) | lo;
-+		}
- 		inode->i_op = &ext2_special_inode_operations;
--		init_special_inode(inode, inode->i_mode,
--				   le32_to_cpu(raw_inode->i_block[0]));
-+		init_special_inode(inode, inode->i_mode, devno);
- 	}
- 	brelse (bh);
- 	ext2_set_inode_flags(inode);
-@@ -1215,10 +1248,22 @@ static int ext2_update_inode(struct inod
- 	}
- 	
- 	raw_inode->i_generation = cpu_to_le32(inode->i_generation);
--	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
--		raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
--	else for (n = 0; n < EXT2_N_BLOCKS; n++)
--		raw_inode->i_block[n] = ei->i_data[n];
-+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
-+		dev_t devno = kdev_t_to_nr(inode->i_rdev);
-+		unsigned int hi = (sizeof(dev_t) > 4) ? (devno >> 32) : 0;
-+		unsigned int lo = (devno & 0xffffffff);
-+
-+		if (hi == 0 && lo != 0) {
-+			raw_inode->i_block[0] = cpu_to_le32(lo);
-+		} else {
-+			raw_inode->i_block[0] = 0;
-+			raw_inode->i_block[1] = cpu_to_le32(lo);
-+			raw_inode->i_block[2] = cpu_to_le32(hi);
-+		}
-+	} else {
-+		for (n = 0; n < EXT2_N_BLOCKS; n++)
-+			raw_inode->i_block[n] = ei->i_data[n];
-+	}
- 	mark_buffer_dirty(bh);
- 	if (do_sync) {
- 		sync_dirty_buffer(bh);
---- linux-2.6.0-test1/fs/ext3/acl.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/ext3/acl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -425,7 +425,7 @@ ext3_acl_chmod(struct inode *inode)
- 	if (!error) {
- 		handle_t *handle;
- 
--		handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+		handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
- 		if (IS_ERR(handle)) {
- 			error = PTR_ERR(handle);
- 			ext3_std_error(inode->i_sb, error);
-@@ -531,7 +531,7 @@ ext3_xattr_set_acl(struct inode *inode, 
- 	} else
- 		acl = NULL;
- 
--	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
- 	if (IS_ERR(handle))
- 		return PTR_ERR(handle);
- 	error = ext3_set_acl(handle, inode, type, acl);
---- linux-2.6.0-test1/fs/ext3/balloc.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/fs/ext3/balloc.c	2003-07-19 17:07:17.000000000 -0700
-@@ -279,7 +279,8 @@ error_return:
- 	return;
- }
- 
--/* For ext3 allocations, we must not reuse any blocks which are
-+/*
-+ * For ext3 allocations, we must not reuse any blocks which are
-  * allocated in the bitmap buffer's "last committed data" copy.  This
-  * prevents deletes from freeing up the page for reuse until we have
-  * committed the delete transaction.
-@@ -294,14 +295,21 @@ error_return:
-  * data-writes at some point, and disable it for metadata allocations or
-  * sync-data inodes.
-  */
--static inline int ext3_test_allocatable(int nr, struct buffer_head *bh,
--					int have_access)
-+static inline int ext3_test_allocatable(int nr, struct buffer_head *bh)
- {
-+	int ret;
-+	struct journal_head *jh = bh2jh(bh);
-+
- 	if (ext3_test_bit(nr, bh->b_data))
- 		return 0;
--	if (!have_access || !buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
--		return 1;
--	return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
-+
-+	jbd_lock_bh_state(bh);
-+	if (!jh->b_committed_data)
-+		ret = 1;
-+	else
-+		ret = !ext3_test_bit(nr, jh->b_committed_data);
-+	jbd_unlock_bh_state(bh);
-+	return ret;
- }
- 
- /*
-@@ -311,11 +319,12 @@ static inline int ext3_test_allocatable(
-  * the initial goal; then for a free byte somewhere in the bitmap; then
-  * for any free bit in the bitmap.
-  */
--static int find_next_usable_block(int start, struct buffer_head *bh,
--				int maxblocks, int have_access)
-+static int
-+find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
- {
- 	int here, next;
- 	char *p, *r;
-+	struct journal_head *jh = bh2jh(bh);
- 
- 	if (start > 0) {
- 		/*
-@@ -328,48 +337,38 @@ static int find_next_usable_block(int st
- 		 */
- 		int end_goal = (start + 63) & ~63;
- 		here = ext3_find_next_zero_bit(bh->b_data, end_goal, start);
--		if (here < end_goal &&
--			ext3_test_allocatable(here, bh, have_access))
-+		if (here < end_goal && ext3_test_allocatable(here, bh))
- 			return here;
--	
--		ext3_debug ("Bit not found near goal\n");
-+		ext3_debug("Bit not found near goal\n");
- 	}
- 
- 	here = start;
- 	if (here < 0)
- 		here = 0;
- 
--	/*
--	 * There has been no free block found in the near vicinity of
--	 * the goal: do a search forward through the block groups,
--	 * searching in each group first for an entire free byte in the
--	 * bitmap and then for any free bit.
--	 * 
--	 * Search first in the remainder of the current group 
--	 */
--	p = ((char *) bh->b_data) + (here >> 3);
-+	p = ((char *)bh->b_data) + (here >> 3);
- 	r = memscan(p, 0, (maxblocks - here + 7) >> 3);
--	next = (r - ((char *) bh->b_data)) << 3;
-+	next = (r - ((char *)bh->b_data)) << 3;
- 
--	if (next < maxblocks && ext3_test_allocatable(next, bh, have_access))
-+	if (next < maxblocks && ext3_test_allocatable(next, bh))
- 		return next;
- 
--	/* The bitmap search --- search forward alternately
--	 * through the actual bitmap and the last-committed copy
--	 * until we find a bit free in both. */
--
-+	/*
-+	 * The bitmap search --- search forward alternately through the actual
-+	 * bitmap and the last-committed copy until we find a bit free in
-+	 * both
-+	 */
- 	while (here < maxblocks) {
--		next  = ext3_find_next_zero_bit ((unsigned long *) bh->b_data, 
--						 maxblocks, here);
-+		next = ext3_find_next_zero_bit(bh->b_data, maxblocks, here);
- 		if (next >= maxblocks)
- 			return -1;
--		if (ext3_test_allocatable(next, bh, have_access))
-+		if (ext3_test_allocatable(next, bh))
- 			return next;
--
--		if (have_access)
--			here = ext3_find_next_zero_bit
--				((unsigned long *) bh2jh(bh)->b_committed_data, 
--			 	maxblocks, next);
-+		jbd_lock_bh_state(bh);
-+		if (jh->b_committed_data)
-+			here = ext3_find_next_zero_bit(jh->b_committed_data,
-+						 	maxblocks, next);
-+		jbd_unlock_bh_state(bh);
- 	}
- 	return -1;
- }
-@@ -384,14 +383,20 @@ static int find_next_usable_block(int st
- static inline int
- claim_block(spinlock_t *lock, int block, struct buffer_head *bh)
- {
-+	struct journal_head *jh = bh2jh(bh);
-+	int ret;
-+
- 	if (ext3_set_bit_atomic(lock, block, bh->b_data))
- 		return 0;
--	if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data &&
--			ext3_test_bit(block, bh2jh(bh)->b_committed_data)) {
-+	jbd_lock_bh_state(bh);
-+	if (jh->b_committed_data && ext3_test_bit(block,jh->b_committed_data)) {
- 		ext3_clear_bit_atomic(lock, block, bh->b_data);
--		return 0;
-+		ret = 0;
-+	} else {
-+		ret = 1;
- 	}
--	return 1;
-+	jbd_unlock_bh_state(bh);
-+	return ret;
- }
- 
- /*
-@@ -403,43 +408,34 @@ static int
- ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
- 		struct buffer_head *bitmap_bh, int goal, int *errp)
- {
--	int i, fatal = 0;
--	int have_access = 0;
-+	int i;
-+	int fatal;
- 	int credits = 0;
- 
- 	*errp = 0;
- 
--	if (goal >= 0 && ext3_test_allocatable(goal, bitmap_bh, 0))
--		goto got;
--
--repeat:
--	goal = find_next_usable_block(goal, bitmap_bh,
--				EXT3_BLOCKS_PER_GROUP(sb), have_access);
--	if (goal < 0)
-+	/*
-+	 * Make sure we use undo access for the bitmap, because it is critical
-+	 * that we do the frozen_data COW on bitmap buffers in all cases even
-+	 * if the buffer is in BJ_Forget state in the committing transaction.
-+	 */
-+	BUFFER_TRACE(bitmap_bh, "get undo access for new block");
-+	fatal = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
-+	if (fatal) {
-+		*errp = fatal;
- 		goto fail;
-+	}
- 
--	for (i = 0;
--		i < 7 && goal > 0 && 
--			ext3_test_allocatable(goal - 1, bitmap_bh, have_access);
--		i++, goal--);
--
--got:
--	if (!have_access) {
--		/*
--		 * Make sure we use undo access for the bitmap, because it is
--	 	 * critical that we do the frozen_data COW on bitmap buffers in
--	 	 * all cases even if the buffer is in BJ_Forget state in the
--	 	 * committing transaction.
--		 */
--		BUFFER_TRACE(bitmap_bh, "get undo access for new block");
--		fatal = ext3_journal_get_undo_access(handle, bitmap_bh,
--							&credits);
--		if (fatal) {
--			*errp = fatal;
--			goto fail;
--		}
--		jbd_lock_bh_state(bitmap_bh);
--		have_access = 1;
-+repeat:
-+	if (goal < 0 || !ext3_test_allocatable(goal, bitmap_bh)) {
-+		goal = find_next_usable_block(goal, bitmap_bh,
-+					EXT3_BLOCKS_PER_GROUP(sb));
-+		if (goal < 0)
-+			goto fail_access;
-+
-+		for (i = 0; i < 7 && goal > 0 &&
-+				ext3_test_allocatable(goal - 1, bitmap_bh);
-+			i++, goal--);
- 	}
- 
- 	if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) {
-@@ -449,29 +445,25 @@ got:
- 		 */
- 		goal++;
- 		if (goal >= EXT3_BLOCKS_PER_GROUP(sb))
--			goto fail;
-+			goto fail_access;
- 		goto repeat;
- 	}
- 
- 	BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
--	jbd_unlock_bh_state(bitmap_bh);
- 	fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
- 	if (fatal) {
- 		*errp = fatal;
- 		goto fail;
- 	}
--
- 	return goal;
-+
-+fail_access:
-+	BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
-+	ext3_journal_release_buffer(handle, bitmap_bh, credits);
- fail:
--	if (have_access) {
--		BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
--		jbd_unlock_bh_state(bitmap_bh);
--		ext3_journal_release_buffer(handle, bitmap_bh, credits);
--	}
- 	return -1;
- }
- 
--
- /*
-  * ext3_new_block uses a goal block to assist allocation.  If the goal is
-  * free, or there is a free block within 32 blocks of the goal, that block
---- linux-2.6.0-test1/fs/ext3/inode.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/ext3/inode.c	2003-07-19 17:07:19.000000000 -0700
-@@ -936,12 +936,14 @@ struct buffer_head *ext3_getblk(handle_t
- 			   ext3_get_block instead, so it's not a
- 			   problem. */
- 			lock_buffer(bh);
--			BUFFER_TRACE(bh, "call get_create_access");
--			fatal = ext3_journal_get_create_access(handle, bh);
--			if (!fatal) {
--				memset(bh->b_data, 0,
--				       inode->i_sb->s_blocksize);
--				set_buffer_uptodate(bh);
-+			if (!buffer_uptodate(bh)) {
-+				BUFFER_TRACE(bh, "call get_create_access");
-+				fatal = ext3_journal_get_create_access(handle, bh);
-+				if (!fatal) {
-+					memset(bh->b_data, 0,
-+							inode->i_sb->s_blocksize);
-+					set_buffer_uptodate(bh);
-+				}
- 			}
- 			unlock_buffer(bh);
- 			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
-@@ -2337,26 +2339,114 @@ static unsigned long ext3_get_inode_bloc
- }
- 
- /* 
-- * ext3_get_inode_loc returns with an extra refcount against the
-- * inode's underlying buffer_head on success. 
-+ * ext3_get_inode_loc returns with an extra refcount against the inode's
-+ * underlying buffer_head on success.  If `in_mem' is false then we're purely
-+ * trying to determine the inode's location on-disk and no read need be
-+ * performed.
-  */
--
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+static int ext3_get_inode_loc(struct inode *inode,
-+				struct ext3_iloc *iloc, int in_mem)
- {
- 	unsigned long block;
-+	struct buffer_head *bh;
- 
- 	block = ext3_get_inode_block(inode->i_sb, inode->i_ino, iloc);
--	if (block) {
--		struct buffer_head *bh = sb_bread(inode->i_sb, block);
--		if (bh) {
--			iloc->bh = bh;
--			return 0;
--		}
-+	if (!block)
-+		return -EIO;
-+
-+	bh = sb_getblk(inode->i_sb, block);
-+	if (!bh) {
- 		ext3_error (inode->i_sb, "ext3_get_inode_loc",
--			    "unable to read inode block - "
--			    "inode=%lu, block=%lu", inode->i_ino, block);
-+				"unable to read inode block - "
-+				"inode=%lu, block=%lu", inode->i_ino, block);
-+		return -EIO;
- 	}
--	return -EIO;
-+	if (!buffer_uptodate(bh)) {
-+		lock_buffer(bh);
-+		if (buffer_uptodate(bh)) {
-+			/* someone brought it uptodate while we waited */
-+			unlock_buffer(bh);
-+			goto has_buffer;
-+		}
-+
-+		/* we can't skip I/O if inode is on a disk only */
-+		if (in_mem) {
-+			struct buffer_head *bitmap_bh;
-+			struct ext3_group_desc *desc;
-+			int inodes_per_buffer;
-+			int inode_offset, i;
-+			int block_group;
-+			int start;
-+
-+			/*
-+			 * If this is the only valid inode in the block we
-+			 * need not read the block.
-+			 */
-+			block_group = (inode->i_ino - 1) /
-+					EXT3_INODES_PER_GROUP(inode->i_sb);
-+			inodes_per_buffer = bh->b_size /
-+				EXT3_INODE_SIZE(inode->i_sb);
-+			inode_offset = ((inode->i_ino - 1) %
-+					EXT3_INODES_PER_GROUP(inode->i_sb));
-+			start = inode_offset & ~(inodes_per_buffer - 1);
-+
-+			/* Is the inode bitmap in cache? */
-+			desc = ext3_get_group_desc(inode->i_sb,
-+						block_group, NULL);
-+			if (!desc)
-+				goto make_io;
-+
-+			bitmap_bh = sb_getblk(inode->i_sb,
-+					le32_to_cpu(desc->bg_inode_bitmap));
-+			if (!bitmap_bh)
-+				goto make_io;
-+
-+			/*
-+			 * If the inode bitmap isn't in cache then the
-+			 * optimisation may end up performing two reads instead
-+			 * of one, so skip it.
-+			 */
-+			if (!buffer_uptodate(bitmap_bh)) {
-+				brelse(bitmap_bh);
-+				goto make_io;
-+			}
-+			for (i = start; i < start + inodes_per_buffer; i++) {
-+				if (i == inode_offset)
-+					continue;
-+				if (ext3_test_bit(i, bitmap_bh->b_data))
-+					break;
-+			}
-+			brelse(bitmap_bh);
-+			if (i == start + inodes_per_buffer) {
-+				/* all other inodes are free, so skip I/O */
-+				memset(bh->b_data, 0, bh->b_size);
-+				set_buffer_uptodate(bh);
-+				unlock_buffer(bh);
-+				goto has_buffer;
-+			}
-+		}
-+
-+make_io:
-+		/*
-+		 * There are another valid inodes in the buffer so we must
-+		 * read the block from disk
-+		 */
-+		get_bh(bh);
-+		bh->b_end_io = end_buffer_io_sync;
-+		submit_bh(READ, bh);
-+		wait_on_buffer(bh);
-+		if (!buffer_uptodate(bh)) {
-+			ext3_error(inode->i_sb, "ext3_get_inode_loc",
-+					"unable to read inode block - "
-+					"inode=%lu, block=%lu",
-+					inode->i_ino, block);
-+			brelse(bh);
-+			return -EIO;
-+		}
-+	}
-+has_buffer:
-+	iloc->bh = bh;
-+	return 0;
- }
- 
- void ext3_set_inode_flags(struct inode *inode)
-@@ -2376,7 +2466,6 @@ void ext3_set_inode_flags(struct inode *
- 		inode->i_flags |= S_DIRSYNC;
- }
- 
--
- void ext3_read_inode(struct inode * inode)
- {
- 	struct ext3_iloc iloc;
-@@ -2389,7 +2478,7 @@ void ext3_read_inode(struct inode * inod
- 	ei->i_acl = EXT3_ACL_NOT_CACHED;
- 	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
- #endif
--	if (ext3_get_inode_loc(inode, &iloc))
-+	if (ext3_get_inode_loc(inode, &iloc, 0))
- 		goto bad_inode;
- 	bh = iloc.bh;
- 	raw_inode = ext3_raw_inode(&iloc);
-@@ -2476,9 +2565,15 @@ void ext3_read_inode(struct inode * inod
- 			ext3_set_aops(inode);
- 		}
- 	} else {
-+		dev_t devno = le32_to_cpu(raw_inode->i_block[0]);
-+		if (devno == 0) {
-+			unsigned int lo = le32_to_cpu(raw_inode->i_block[1]);
-+			unsigned int hi = le32_to_cpu(raw_inode->i_block[2]);
-+			devno = ((unsigned long long) hi << 32) | lo;
-+		}
-+
- 		inode->i_op = &ext3_special_inode_operations;
--		init_special_inode(inode, inode->i_mode,
--				   le32_to_cpu(raw_inode->i_block[0]));
-+		init_special_inode(inode, inode->i_mode, devno);
- 	}
- 	brelse (iloc.bh);
- 	ext3_set_inode_flags(inode);
-@@ -2578,12 +2673,22 @@ static int ext3_do_update_inode(handle_t
- 		}
- 	}
- 	raw_inode->i_generation = cpu_to_le32(inode->i_generation);
--	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
--		raw_inode->i_block[0] =
--			cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
--	else for (block = 0; block < EXT3_N_BLOCKS; block++)
--		raw_inode->i_block[block] = ei->i_data[block];
-+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
-+		dev_t devno = kdev_t_to_nr(inode->i_rdev);
-+		unsigned int hi = (sizeof(dev_t) > 4) ? (devno >> 32) : 0;
-+		unsigned int lo = (devno & 0xffffffff);
- 
-+		if (hi == 0 && lo != 0) {
-+			raw_inode->i_block[0] = cpu_to_le32(lo);
-+		} else {
-+			raw_inode->i_block[0] = 0;
-+			raw_inode->i_block[1] = cpu_to_le32(lo);
-+			raw_inode->i_block[2] = cpu_to_le32(hi);
-+		}
-+	} else {
-+		for (block = 0; block < EXT3_N_BLOCKS; block++)
-+			raw_inode->i_block[block] = ei->i_data[block];
-+	}
- 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
- 	rc = ext3_journal_dirty_metadata(handle, bh);
- 	if (!err)
-@@ -2793,7 +2898,7 @@ ext3_reserve_inode_write(handle_t *handl
- {
- 	int err = 0;
- 	if (handle) {
--		err = ext3_get_inode_loc(inode, iloc);
-+		err = ext3_get_inode_loc(inode, iloc, 1);
- 		if (!err) {
- 			BUFFER_TRACE(iloc->bh, "get_write_access");
- 			err = ext3_journal_get_write_access(handle, iloc->bh);
-@@ -2891,7 +2996,7 @@ ext3_pin_inode(handle_t *handle, struct 
- 
- 	int err = 0;
- 	if (handle) {
--		err = ext3_get_inode_loc(inode, &iloc);
-+		err = ext3_get_inode_loc(inode, &iloc, 1);
- 		if (!err) {
- 			BUFFER_TRACE(iloc.bh, "get_write_access");
- 			err = journal_get_write_access(handle, iloc.bh);
---- linux-2.6.0-test1/fs/ext3/super.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/ext3/super.c	2003-07-19 17:07:20.000000000 -0700
-@@ -1811,7 +1811,10 @@ void ext3_write_super (struct super_bloc
- 	if (down_trylock(&sb->s_lock) == 0)
- 		BUG();
- 	sb->s_dirt = 0;
-+#if 0
-+	/* we really don't need this because of log's nature -bzzz */
- 	journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
-+#endif
- }
- 
- static int ext3_sync_fs(struct super_block *sb, int wait)
---- linux-2.6.0-test1/fs/ext3/xattr.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/ext3/xattr.c	2003-07-19 17:03:50.000000000 -0700
-@@ -875,7 +875,7 @@ ext3_xattr_set(struct inode *inode, int 
- 	handle_t *handle;
- 	int error, error2;
- 
--	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-+	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
- 	if (IS_ERR(handle))
- 		error = PTR_ERR(handle);
- 	else
-@@ -1050,12 +1050,10 @@ ext3_xattr_cache_find(handle_t *handle, 
- 			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
- 				"inode %ld: block %ld read error",
- 				inode->i_ino, (unsigned long) ce->e_block);
--		} else {
-+		} else if (ext3_journal_get_write_access_credits(
-+				handle, bh, credits) == 0) {
- 			/* ext3_journal_get_write_access() requires an unlocked
- 			 * bh, which complicates things here. */
--			if (ext3_journal_get_write_access_credits(handle, bh,
--								  credits) != 0)
--				return NULL;
- 			lock_buffer(bh);
- 			if (le32_to_cpu(HDR(bh)->h_refcount) >
- 				   EXT3_XATTR_REFCOUNT_MAX) {
-@@ -1070,6 +1068,7 @@ ext3_xattr_cache_find(handle_t *handle, 
- 			}
- 			unlock_buffer(bh);
- 			journal_release_buffer(handle, bh, *credits);
-+			*credits = 0;
- 			brelse(bh);
- 		}
- 		ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
---- linux-2.6.0-test1/fs/inode.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/inode.c	2003-07-19 17:07:03.000000000 -0700
-@@ -184,6 +184,7 @@ void inode_init_once(struct inode *inode
- 	INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
- 	spin_lock_init(&inode->i_data.page_lock);
- 	init_MUTEX(&inode->i_data.i_shared_sem);
-+	atomic_set(&inode->i_data.truncate_count, 0);
- 	INIT_LIST_HEAD(&inode->i_data.private_list);
- 	spin_lock_init(&inode->i_data.private_lock);
- 	INIT_LIST_HEAD(&inode->i_data.i_mmap);
---- linux-2.6.0-test1/fs/intermezzo/sysctl.c	2003-06-14 12:17:59.000000000 -0700
-+++ 25/fs/intermezzo/sysctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -36,7 +36,6 @@
- #include <asm/segment.h>
- #include <asm/uaccess.h>
- #include <linux/utsname.h>
--#include <linux/blk.h>
- 
- #include "intermezzo_fs.h"
- #include "intermezzo_psdev.h"
---- linux-2.6.0-test1/fs/intermezzo/vfs.c	2003-07-10 18:50:31.000000000 -0700
-+++ 25/fs/intermezzo/vfs.c	2003-07-19 17:03:50.000000000 -0700
-@@ -66,7 +66,7 @@
- #include <linux/file.h>
- #include <linux/fs.h>
- #include <linux/namei.h>
--#include <linux/blk.h>
-+#include <linux/genhd.h>
- 
- #include "intermezzo_fs.h"
- #include "intermezzo_psdev.h"
---- linux-2.6.0-test1/fs/jbd/journal.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/jbd/journal.c	2003-07-19 17:07:09.000000000 -0700
-@@ -119,19 +119,16 @@ void __journal_internal_check(void)
-  *    the disk.  Flushing these old buffers to reclaim space in the log is
-  *    known as checkpointing, and this thread is responsible for that job.
-  */
--
--journal_t *current_journal;		// AKPM: debug
--
- int kjournald(void *arg)
- {
- 	journal_t *journal = (journal_t *) arg;
- 	transaction_t *transaction;
- 	struct timer_list timer;
- 
--	current_journal = journal;
--
- 	daemonize("kjournald");
- 
-+	current->flags |= PF_SYNCWRITE;	/* Anticipatory scheduler hint */
-+
- 	/* Set up an interval timer which can be used to trigger a
-            commit wakeup after the commit interval expires */
- 	init_timer(&timer);
---- linux-2.6.0-test1/fs/jbd/transaction.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/jbd/transaction.c	2003-07-19 17:04:15.000000000 -0700
-@@ -742,7 +742,7 @@ int journal_get_write_access(handle_t *h
- 	/* We do not want to get caught playing with fields which the
- 	 * log thread also manipulates.  Make sure that the buffer
- 	 * completes any outstanding IO before proceeding. */
--	rc = do_get_write_access(handle, jh, 0, NULL);
-+	rc = do_get_write_access(handle, jh, 0, credits);
- 	journal_put_journal_head(jh);
- 	return rc;
- }
-@@ -1106,16 +1106,6 @@ int journal_dirty_metadata(handle_t *han
- 	if (jh->b_transaction == handle->h_transaction &&
- 					jh->b_jlist == BJ_Metadata) {
- 		JBUFFER_TRACE(jh, "fastpath");
--		console_verbose();
--		if (jh->b_transaction != journal->j_running_transaction) {
--			printk("jh->b_transaction=%p\n", jh->b_transaction);
--			printk("journal->j_running_transaction=%p\n",
--				journal->j_running_transaction);
--			printk("handle->h_transaction=%p\n",
--				handle->h_transaction);
--			printk("journal->j_committing_transaction=%p\n",
--				journal->j_committing_transaction);
--		}
- 		J_ASSERT_JH(jh, jh->b_transaction ==
- 					journal->j_running_transaction);
- 		goto out_unlock_bh;
-@@ -1328,9 +1318,6 @@ int journal_stop(handle_t *handle)
- 	journal_t *journal = transaction->t_journal;
- 	int old_handle_count, err;
- 
--	if (!handle)
--		return 0;
--
- 	J_ASSERT(transaction->t_updates > 0);
- 	J_ASSERT(journal_current_handle() == handle);
- 
---- linux-2.6.0-test1/fs/jffs2/Makefile	2003-06-14 12:18:03.000000000 -0700
-+++ 25/fs/jffs2/Makefile	2003-07-19 17:03:50.000000000 -0700
-@@ -13,6 +13,7 @@ JFFS2_OBJS	:= dir.o file.o ioctl.o nodel
- 
- LINUX_OBJS-24	:= super-v24.o crc32.o
- LINUX_OBJS-25	:= super.o
-+LINUX_OBJS-26	:= super.o
- 
- NAND_OBJS-$(CONFIG_JFFS2_FS_NAND)	:= wbuf.o
- 
---- linux-2.6.0-test1/fs/Kconfig	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/Kconfig	2003-07-19 17:07:09.000000000 -0700
-@@ -1323,6 +1323,31 @@ config NFS_V4
- 
- 	  If unsure, say N.
- 
-+config NFS_DIRECTIO
-+	bool
-+	depends on NFS_FS
-+	default y
-+	help
-+	  This option enables applications to perform uncached I/O on files
-+	  in NFS file systems using the O_DIRECT open() flag.  When O_DIRECT
-+	  is set for a file, its data is not cached in the system's page
-+	  cache.  Data is moved to and from user-level application buffers
-+	  directly.  Unlike local disk-based file systems, NFS O_DIRECT has
-+	  no alignment restrictions.
-+
-+	  Unless your program is designed to use O_DIRECT properly, you are
-+	  much better off allowing the NFS client to manage data caching for
-+	  you.  Misusing O_DIRECT can cause poor server performance or network
-+	  storms.  This kernel build option defaults OFF to avoid exposing
-+	  system administrators unwittingly to a potentially hazardous
-+	  feature.
-+
-+	  For more details on NFS O_DIRECT, see fs/nfs/direct.c.
-+
-+	  If unsure, say N.  This reduces the size of the NFS client, and
-+	  causes open() to return EINVAL if a file residing in NFS is
-+	  opened with the O_DIRECT flag.
-+
- config NFSD
- 	tristate "NFS server support"
- 	depends on INET
---- linux-2.6.0-test1/fs/lockd/clntlock.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/fs/lockd/clntlock.c	2003-07-19 17:03:50.000000000 -0700
-@@ -187,8 +187,9 @@ nlmclnt_recovery(struct nlm_host *host, 
- 	} else {
- 		nlmclnt_prepare_reclaim(host, newstate);
- 		nlm_get_host(host);
--		MOD_INC_USE_COUNT;
--		kernel_thread(reclaimer, host, CLONE_KERNEL);
-+		__module_get(THIS_MODULE);
-+		if (kernel_thread(reclaimer, host, CLONE_KERNEL))
-+			module_put(THIS_MODULE);
- 	}
- }
- 
-@@ -244,7 +245,5 @@ restart:
- 	nlm_release_host(host);
- 	lockd_down();
- 	unlock_kernel();
--	MOD_DEC_USE_COUNT;
--
--	return 0;
-+	module_put_and_exit(0);
- }
---- linux-2.6.0-test1/fs/lockd/svc.c	2003-07-02 14:53:16.000000000 -0700
-+++ 25/fs/lockd/svc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -88,7 +88,11 @@ lockd(struct svc_rqst *rqstp)
- 	unsigned long grace_period_expire;
- 
- 	/* Lock module and set up kernel thread */
--	MOD_INC_USE_COUNT;
-+	/* lockd_up is waiting for us to startup, so will
-+	 * be holding a reference to this module, so it
-+	 * is safe to just claim another reference
-+	 */
-+	__module_get(THIS_MODULE);
- 	lock_kernel();
- 
- 	/*
-@@ -183,7 +187,7 @@ lockd(struct svc_rqst *rqstp)
- 
- 	/* Release module */
- 	unlock_kernel();
--	MOD_DEC_USE_COUNT;
-+	module_put_and_exit(0);
- }
- 
- /*
---- linux-2.6.0-test1/fs/namei.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/namei.c	2003-07-19 17:06:37.000000000 -0700
-@@ -1424,11 +1424,12 @@ int vfs_mknod(struct inode *dir, struct 
- 	return error;
- }
- 
--asmlinkage long sys_mknod(const char __user * filename, int mode, dev_t dev)
-+static long
-+do_mknod(const char __user *filename, int mode, dev_t dev)
- {
- 	int error = 0;
--	char * tmp;
--	struct dentry * dentry;
-+	char *tmp;
-+	struct dentry *dentry;
- 	struct nameidata nd;
- 
- 	if (S_ISDIR(mode))
-@@ -1469,6 +1470,27 @@ out:
- 	return error;
- }
- 
-+asmlinkage long
-+sys_mknod(const char __user *filename, int mode, unsigned int devnr)
-+{
-+	dev_t dev = devnr;
-+
-+	if (dev != devnr)
-+		return -EOVERFLOW;
-+	return do_mknod(filename, mode, dev);
-+}
-+
-+asmlinkage long
-+sys_mknod64(const char __user *filename, int mode,
-+	    unsigned int major, unsigned int minor)
-+{
-+	dev_t dev = MKDEV(major, minor);
-+
-+	if (MAJOR(dev) != major || MINOR(dev) != minor)
-+		return -EOVERFLOW;
-+	return do_mknod(filename, mode, dev);
-+}
-+
- int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
- {
- 	int error = may_create(dir, dentry, NULL);
---- linux-2.6.0-test1/fs/namespace.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/namespace.c	2003-07-19 17:03:50.000000000 -0700
-@@ -1158,3 +1158,13 @@ void __init mnt_init(unsigned long mempa
- 	init_rootfs();
- 	init_mount_tree();
- }
-+
-+void __put_namespace(struct namespace *namespace)
-+{
-+	down_write(&namespace->sem);
-+	spin_lock(&vfsmount_lock);
-+	umount_tree(namespace->root);
-+	spin_unlock(&vfsmount_lock);
-+	up_write(&namespace->sem);
-+	kfree(namespace);
-+}
---- linux-2.6.0-test1/fs/nfs/direct.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/direct.c	2003-07-19 17:07:08.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * linux/fs/nfs/direct.c
-  *
-- * Copyright (C) 2001 by Chuck Lever <cel@netapp.com>
-+ * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
-  *
-  * High-performance uncached I/O for the Linux NFS client
-  *
-@@ -26,19 +26,23 @@
-  * also supports uncaching whole NFS partitions with "-o forcedirectio,"
-  * an undocumented mount option.
-  *
-- * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust.
-+ * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust, with
-+ * help from Andrew Morton.
-  *
-  * 18 Dec 2001	Initial implementation for 2.4  --cel
-  * 08 Jul 2002	Version for 2.4.19, with bug fixes --trondmy
-- * 24 Sep 2002	Rewrite to use asynchronous RPCs, port to 2.5  --cel
-+ * 08 Jun 2003	Port to 2.5 APIs  --cel
-  *
-  */
- 
- #include <linux/config.h>
-+#include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/kernel.h>
-+#include <linux/smp_lock.h>
- #include <linux/file.h>
--#include <linux/errno.h>
-+#include <linux/pagemap.h>
-+
- #include <linux/nfs_fs.h>
- #include <linux/nfs_page.h>
- #include <linux/sunrpc/clnt.h>
-@@ -46,35 +50,41 @@
- #include <asm/system.h>
- #include <asm/uaccess.h>
- 
--#define NFSDBG_FACILITY		(NFSDBG_PAGECACHE | NFSDBG_VFS)
-+#define NFSDBG_FACILITY		NFSDBG_VFS
- #define VERF_SIZE		(2 * sizeof(__u32))
-+#define MAX_DIRECTIO_SIZE	(4096UL << PAGE_SHIFT)
- 
- 
- /**
-- * nfs_get_user_pages - find and set up page representing user buffer
-- * addr: user-space address of target buffer
-- * size: total size in bytes of target buffer
-- * @pages: returned array of page struct pointers underlying target buffer
-- * write: whether or not buffer is target of a write operation
-+ * nfs_get_user_pages - find and set up pages underlying user's buffer
-+ * rw: direction (read or write)
-+ * user_addr: starting address of this segment of user's buffer
-+ * count: size of this segment
-+ * @pages: returned array of page struct pointers underlying user's buffer
-  */
- static inline int
--nfs_get_user_pages(unsigned long addr, size_t size,
--		struct page ***pages, int rw)
-+nfs_get_user_pages(int rw, unsigned long user_addr, size_t size,
-+		struct page ***pages)
- {
- 	int result = -ENOMEM;
--	unsigned page_count = (unsigned) size >> PAGE_SHIFT;
--	unsigned array_size = (page_count * sizeof(struct page *)) + 2U;
-+	unsigned long page_count;
-+	size_t array_size;
-+
-+	/* set an arbitrary limit to prevent arithmetic overflow */
-+	if (size > MAX_DIRECTIO_SIZE)
-+		return -EFBIG;
- 
--	*pages = (struct page **) kmalloc(array_size, GFP_KERNEL);
-+	page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+	page_count -= user_addr >> PAGE_SHIFT;
-+
-+	array_size = (page_count * sizeof(struct page *));
-+	*pages = kmalloc(array_size, GFP_KERNEL);
- 	if (*pages) {
- 		down_read(&current->mm->mmap_sem);
--		result = get_user_pages(current, current->mm, addr,
--					page_count, (rw == WRITE), 0,
-+		result = get_user_pages(current, current->mm, user_addr,
-+					page_count, (rw == READ), 0,
- 					*pages, NULL);
- 		up_read(&current->mm->mmap_sem);
--		if (result < 0)
--			printk(KERN_ERR "%s: get_user_pages result %d\n",
--					__FUNCTION__, result);
- 	}
- 	return result;
- }
-@@ -84,176 +94,349 @@ nfs_get_user_pages(unsigned long addr, s
-  * @pages: array of page struct pointers underlying target buffer
-  */
- static inline void
--nfs_free_user_pages(struct page **pages, unsigned count)
-+nfs_free_user_pages(struct page **pages)
- {
--	unsigned page = 0;
-+	kfree(pages);
-+}
- 
--	while (count--)
--		page_cache_release(pages[page++]);
-+/**
-+ * nfs_direct_read_seg - Read in one iov segment.  Generate separate
-+ *                        read RPCs for each "rsize" bytes.
-+ * @inode: target inode
-+ * @cred: user's credential
-+ * user_addr: starting address of this segment of user's buffer
-+ * count: size of this segment
-+ * file_offset: offset in file to begin the operation
-+ * @pages: array of addresses of page structs defining user's buffer
-+ * nr_pages: size of pages array
-+ */
-+static int
-+nfs_direct_read_seg(struct inode *inode, struct rpc_cred *cred,
-+		unsigned long user_addr, size_t count, loff_t file_offset,
-+		struct page **pages, int nr_pages)
-+{
-+	const unsigned int rsize = NFS_SERVER(inode)->rsize;
-+	int tot_bytes = 0;
-+	int curpage = 0;
-+	struct nfs_read_data	rdata = {
-+		.flags		= 0,
-+		.cred		= cred,
-+		.inode		= inode,
-+		.args		= {
-+			.fh		= NFS_FH(inode),
-+		},
-+		.res		= {
-+			.fattr		= &rdata.fattr,
-+		},
-+	};
-+
-+        do {
-+		int request, result;
-+
-+                request = count;
-+                if (count > rsize)
-+                        request = rsize;
-+		rdata.args.count = request,
-+		rdata.args.pgbase = user_addr & ~PAGE_MASK;
-+		rdata.args.offset = file_offset;
-+		rdata.args.pages = &pages[curpage];
-+
-+		dprintk("NFS: direct read: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
-+			rdata.args.count, (long long) rdata.args.offset,
-+			user_addr, rdata.args.pgbase, curpage);
-+
-+		lock_kernel();
-+		result = NFS_PROTO(inode)->read(&rdata);
-+		unlock_kernel();
-+
-+		if (result < 0) {
-+			if (result == -EISDIR)
-+				result = -EINVAL;
-+			return result;
-+		}
- 
--	kfree(pages);
-+                tot_bytes += result;
-+                count -= result;
-+                file_offset += result;
-+		user_addr += result;
-+
-+		if (rdata.res.eof)
-+			break;
-+
-+		curpage += (rdata.args.pgbase + result) >> PAGE_SHIFT;
-+	} while (count);
-+
-+	/* XXX: should we zero the rest of the user's buffer if we
-+	 *      hit eof? */
-+
-+	return tot_bytes;
- }
- 
- /**
-- * nfs_iov2pagelist - convert an array of iovecs to a list of page requests
-- * @inode: inode of target file
-- * @cred: credentials of user who requested I/O
-+ * nfs_direct_read - For each iov segment, map the user's buffer
-+ *                   then generate read RPCs.
-+ * @inode: target inode
-+ * @cred: user's credential
-  * @iov: array of vectors that define I/O buffer
-- * offset: where in file to begin the read
-+ * file_offset: offset in file to begin the operation
-  * nr_segs: size of iovec array
-- * @requests: append new page requests to this list head
-+ *
-+ * generic_file_direct_IO has already pushed out any non-direct
-+ * writes so that this read will see them when we read from the
-+ * server.
-  */
- static int
--nfs_iov2pagelist(int rw, const struct inode *inode,
--		const struct rpc_cred *cred,
--		const struct iovec *iov, loff_t offset,
--		unsigned long nr_segs, struct list_head *requests)
-+nfs_direct_read(struct inode *inode, struct rpc_cred *cred,
-+		const struct iovec *iov, loff_t file_offset,
-+		unsigned long nr_segs)
- {
--	unsigned seg;
- 	int tot_bytes = 0;
--	struct page **pages;
-+	unsigned long seg = 0;
- 
--	/* for each iovec in the array... */
--	for (seg = 0; seg < nr_segs; seg++) {
--		const unsigned long user_addr =
--					(unsigned long) iov[seg].iov_base;
--		size_t bytes = iov[seg].iov_len;
--		unsigned int pg_offset = (user_addr & ~PAGE_MASK);
--		int page_count, page = 0;
--
--		page_count = nfs_get_user_pages(user_addr, bytes, &pages, rw);
--		if (page_count < 0) {
--			nfs_release_list(requests);
--			return page_count;
-+	while ((seg < nr_segs) && (tot_bytes >= 0)) {
-+		int result, page_count;
-+		struct page **pages;
-+		const struct iovec *vec = &iov[seg++];
-+		unsigned long user_addr = (unsigned long) vec->iov_base;
-+		size_t size = vec->iov_len;
-+
-+                page_count = nfs_get_user_pages(READ, user_addr, size, &pages);
-+                if (page_count < 0) {
-+                        nfs_free_user_pages(pages);
-+                        return page_count;
-+                }
-+
-+		result = nfs_direct_read_seg(inode, cred, user_addr, size,
-+				file_offset, pages, page_count);
-+		if (result < 0)
-+			tot_bytes = result;
-+		else {
-+			tot_bytes += result;
-+			file_offset += result;
- 		}
- 
--		/* ...build as many page requests as required */
--		while (bytes > 0) {
--			struct nfs_page *new;
--			const unsigned int pg_bytes = (bytes > PAGE_SIZE) ?
--							PAGE_SIZE : bytes;
--
--			new = nfs_create_request((struct rpc_cred *) cred,
--						 (struct inode *) inode,
--						 pages[page],
--						 pg_offset, pg_bytes);
--			if (IS_ERR(new)) {
--				nfs_free_user_pages(pages, page_count);
--				nfs_release_list(requests);
--				return PTR_ERR(new);
--			}
--			new->wb_index = offset;
--			nfs_list_add_request(new, requests);
--
--			/* after the first page */
--			pg_offset = 0;
--			offset += PAGE_SIZE;
--			tot_bytes += pg_bytes;
--			bytes -= pg_bytes;
--			page++;
-+		nfs_free_user_pages(pages);
-+	}
-+
-+	return tot_bytes;
-+}
-+
-+/**
-+ * nfs_direct_write_seg - Write out one iov segment.  Generate separate
-+ *                        write RPCs for each "wsize" bytes, then commit.
-+ * @inode: target inode
-+ * @cred: user's credential
-+ * user_addr: starting address of this segment of user's buffer
-+ * count: size of this segment
-+ * file_offset: offset in file to begin the operation
-+ * @pages: array of addresses of page structs defining user's buffer
-+ * nr_pages: size of pages array
-+ */
-+static int
-+nfs_direct_write_seg(struct inode *inode, struct rpc_cred *cred,
-+		unsigned long user_addr, size_t count, loff_t file_offset,
-+		struct page **pages, int nr_pages)
-+{
-+	const unsigned int wsize = NFS_SERVER(inode)->wsize;
-+	loff_t save_offset = file_offset;
-+	size_t save_count = count;
-+	int need_commit = 0;
-+	int tot_bytes = 0;
-+	int curpage = 0;
-+	struct nfs_writeverf first_verf;
-+	struct nfs_write_data	wdata = {
-+		.cred		= cred,
-+		.inode		= inode,
-+		.args		= {
-+			.fh		= NFS_FH(inode),
-+		},
-+		.res		= {
-+			.fattr		= &wdata.fattr,
-+			.verf		= &wdata.verf,
-+		},
-+	};
-+
-+	wdata.args.stable = NFS_UNSTABLE;
-+	if (IS_SYNC(inode) || NFS_PROTO(inode)->version == 2 || count <= wsize)
-+		wdata.args.stable = NFS_FILE_SYNC;
-+
-+retry:
-+        do {
-+		int request, result;
-+
-+                request = count;
-+                if (count > wsize)
-+                        request = wsize;
-+		wdata.args.count = request,
-+		wdata.args.pgbase = user_addr & ~PAGE_MASK;
-+		wdata.args.offset = file_offset;
-+		wdata.args.pages = &pages[curpage];
-+
-+		dprintk("NFS: direct write: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
-+			wdata.args.count, (long long) wdata.args.offset,
-+			user_addr, wdata.args.pgbase, curpage);
-+
-+		lock_kernel();
-+		result = NFS_PROTO(inode)->write(&wdata);
-+		unlock_kernel();
-+
-+		if (result < 0)
-+			return result;
-+
-+		if (!tot_bytes)
-+			memcpy(&first_verf.verifier, &wdata.verf.verifier,
-+								VERF_SIZE);
-+		if (wdata.verf.committed != NFS_FILE_SYNC) {
-+			need_commit = 1;
-+			if (memcmp(&first_verf.verifier,
-+					&wdata.verf.verifier, VERF_SIZE))
-+				goto sync_retry;
- 		}
- 
--		/* don't release pages here -- I/O completion will do that */
--		nfs_free_user_pages(pages, 0);
-+                tot_bytes += result;
-+                count -= result;
-+                file_offset += result;
-+		user_addr += result;
-+
-+		curpage += (wdata.args.pgbase + result) >> PAGE_SHIFT;
-+	} while (count);
-+
-+	/*
-+	 * Commit data written so far, even in the event of an error
-+	 */
-+	if (need_commit) {
-+		int result;
-+
-+		wdata.args.count = tot_bytes;
-+		wdata.args.offset = save_offset;
-+
-+		lock_kernel();
-+		result = NFS_PROTO(inode)->commit(&wdata);
-+		unlock_kernel();
-+
-+		if (result < 0)
-+			goto sync_retry;
-+		if (memcmp(&first_verf.verifier, &wdata.verf.verifier,
-+								VERF_SIZE))
-+			goto sync_retry;
- 	}
- 
- 	return tot_bytes;
-+
-+sync_retry:
-+	wdata.args.stable = NFS_FILE_SYNC;
-+	file_offset = save_offset;
-+	count = save_count;
-+	goto retry;
- }
- 
- /**
-- * do_nfs_direct_IO - Read or write data without caching
-- * @inode: inode of target file
-- * @cred: credentials of user who requested I/O
-+ * nfs_direct_write - For each iov segment, map the user's buffer
-+ *                    then generate write and commit RPCs.
-+ * @inode: target inode
-+ * @cred: user's credential
-  * @iov: array of vectors that define I/O buffer
-- * offset: where in file to begin the read
-+ * file_offset: offset in file to begin the operation
-  * nr_segs: size of iovec array
-  *
-- * Break the passed-in iovec into a series of page-sized or smaller
-- * requests, where each page is mapped for direct user-land I/O.
-- *
-- * For each of these pages, create an NFS page request and
-- * append it to an automatic list of page requests.
-- *
-- * When all page requests have been queued, start the I/O on the
-- * whole list.  The underlying routines coalesce the pages on the
-- * list into a bunch of asynchronous "r/wsize" network requests.
-- *
-- * I/O completion automatically unmaps and releases the pages.
-+ * Upon return, generic_file_direct_IO invalidates any cached pages
-+ * that non-direct readers might access, so they will pick up these
-+ * writes immediately.
-  */
- static int
--do_nfs_direct_IO(int rw, const struct inode *inode,
--		const struct rpc_cred *cred, const struct iovec *iov,
--		loff_t offset, unsigned long nr_segs)
-+nfs_direct_write(struct inode *inode, struct rpc_cred *cred,
-+		const struct iovec *iov, loff_t file_offset,
-+		unsigned long nr_segs)
- {
--	LIST_HEAD(requests);
--	int result, tot_bytes;
-+	int tot_bytes = 0;
-+	unsigned long seg = 0;
- 
--	result = nfs_iov2pagelist(rw, inode, cred, iov, offset, nr_segs,
--								&requests);
--	if (result < 0)
--		return result;
--	tot_bytes = result;
-+	while ((seg < nr_segs) && (tot_bytes >= 0)) {
-+		int result, page_count;
-+		struct page **pages;
-+		const struct iovec *vec = &iov[seg++];
-+		unsigned long user_addr = (unsigned long) vec->iov_base;
-+		size_t size = vec->iov_len;
-+
-+                page_count = nfs_get_user_pages(WRITE, user_addr, size, &pages);
-+                if (page_count < 0) {
-+                        nfs_free_user_pages(pages);
-+                        return page_count;
-+                }
- 
--	switch (rw) {
--	case READ:
--		if (IS_SYNC(inode) || (NFS_SERVER(inode)->rsize < PAGE_SIZE)) {
--			result = nfs_direct_read_sync(inode, cred, iov, offset, nr_segs);
--			break;
-+		result = nfs_direct_write_seg(inode, cred, user_addr, size,
-+				file_offset, pages, page_count);
-+		if (result < 0)
-+			tot_bytes = result;
-+		else {
-+			tot_bytes += result;
-+			file_offset += result;
- 		}
--		result = nfs_pagein_list(&requests, NFS_SERVER(inode)->rpages);
--		nfs_wait_for_reads(&requests);
--		break;
--	case WRITE:
--		if (IS_SYNC(inode) || (NFS_SERVER(inode)->wsize < PAGE_SIZE))
--			result = nfs_direct_write_sync(inode, cred, iov, offset, nr_segs);
--		else
--			result = nfs_flush_list(&requests,
--					NFS_SERVER(inode)->wpages, FLUSH_WAIT);
- 
--		/* invalidate cache so non-direct readers pick up changes */
--		invalidate_inode_pages((struct inode *) inode);
--		break;
--	default:
--		result = -EINVAL;
--		break;
-+		nfs_free_user_pages(pages);
- 	}
- 
--	if (result < 0)
--		return result;
- 	return tot_bytes;
- }
- 
- /**
-  * nfs_direct_IO - NFS address space operation for direct I/O
-  * rw: direction (read or write)
-- * @file: file struct of target file
-+ * @iocb: target I/O control block
-  * @iov: array of vectors that define I/O buffer
-- * offset: offset in file to begin the operation
-+ * file_offset: offset in file to begin the operation
-  * nr_segs: size of iovec array
-  *
-+ * Usually a file system implements direct I/O by calling out to
-+ * blockdev_direct_IO.  The NFS client doesn't have a backing block
-+ * device, so we do everything by hand instead.
-+ *
-  * The inode's i_sem is no longer held by the VFS layer before it calls
-  * this function to do a write.
-  */
- int
- nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
--		loff_t offset, unsigned long nr_segs)
-+		loff_t file_offset, unsigned long nr_segs)
- {
--	/* None of this works yet, so prevent it from compiling. */
--#if 0
--	int result;
-+	int result = -EINVAL;
-+	struct file *file = iocb->ki_filp;
- 	struct dentry *dentry = file->f_dentry;
--	const struct inode *inode = dentry->d_inode->i_mapping->host;
--	const struct rpc_cred *cred = nfs_file_cred(file);
--#endif
--
--	dfprintk(VFS, "NFS: direct_IO(%s) (%s/%s) off/no(%Lu/%lu)\n",
--				((rw == READ) ? "READ" : "WRITE"),
--				dentry->d_parent->d_name.name,
--				dentry->d_name.name, offset, nr_segs);
-+	struct inode *inode = dentry->d_inode;
-+	struct rpc_cred *cred;
-+
-+	/*
-+	 * No support for async yet
-+	 */
-+	if (!is_sync_kiocb(iocb))
-+		goto out;
-+
-+	cred = get_rpccred(nfs_file_cred(file));
-+	if (!cred)
-+		cred = get_rpccred(NFS_I(inode)->mm_cred);
-+
-+	switch (rw) {
-+	case READ:
-+		dprintk("NFS: direct_IO(read) (%s) off/no(%Lu/%lu)\n",
-+				dentry->d_name.name, file_offset, nr_segs);
-+
-+		result = nfs_direct_read(inode, cred, iov,
-+						file_offset, nr_segs);
-+		break;
-+	case WRITE:
-+		dprintk("NFS: direct_IO(write) (%s) off/no(%Lu/%lu)\n",
-+				dentry->d_name.name, file_offset, nr_segs);
- 
--	result = do_nfs_direct_IO(rw, inode, cred, iov, offset, nr_segs);
-+		result = nfs_direct_write(inode, cred, iov,
-+						file_offset, nr_segs);
-+		break;
-+	default:
-+		break;
-+	}
- 
--	dfprintk(VFS, "NFS: direct_IO result = %d\n", result);
-+	if (cred)
-+		put_rpccred(cred);
- 
-+out:
-+	dprintk("NFS: direct_IO result=%d\n", result);
- 	return result;
- }
---- linux-2.6.0-test1/fs/nfsd/nfssvc.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/nfsd/nfssvc.c	2003-07-19 17:03:50.000000000 -0700
-@@ -116,9 +116,12 @@ nfsd_svc(unsigned short port, int nrserv
- 	nrservs -= (nfsd_serv->sv_nrthreads-1);
- 	while (nrservs > 0) {
- 		nrservs--;
-+		__module_get(THIS_MODULE);
- 		error = svc_create_thread(nfsd, nfsd_serv);
--		if (error < 0)
-+		if (error < 0) {
-+			module_put(THIS_MODULE);
- 			break;
-+		}
- 	}
- 	victim = nfsd_list.next;
- 	while (nrservs < 0 && victim != &nfsd_list) {
-@@ -175,7 +178,6 @@ nfsd(struct svc_rqst *rqstp)
- 	sigset_t shutdown_mask, allowed_mask;
- 
- 	/* Lock module and set up kernel thread */
--	MOD_INC_USE_COUNT;
- 	lock_kernel();
- 	daemonize("nfsd");
- 	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
-@@ -281,7 +283,7 @@ out:
- 	svc_exit_thread(rqstp);
- 
- 	/* Release module */
--	MOD_DEC_USE_COUNT;
-+	module_put_and_exit(0);
- }
- 
- int
---- linux-2.6.0-test1/fs/nfs/inode.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/nfs/inode.c	2003-07-19 17:03:50.000000000 -0700
-@@ -151,15 +151,16 @@ void
- nfs_put_super(struct super_block *sb)
- {
- 	struct nfs_server *server = NFS_SB(sb);
--	struct rpc_clnt	*rpc;
- 
- #ifdef CONFIG_NFS_V4
- 	if (server->idmap != NULL)
- 		nfs_idmap_delete(server);
- #endif /* CONFIG_NFS_V4 */
- 
--	if ((rpc = server->client) != NULL)
--		rpc_shutdown_client(rpc);
-+	if (server->client != NULL)
-+		rpc_shutdown_client(server->client);
-+	if (server->client_sys != NULL)
-+		rpc_shutdown_client(server->client_sys);
- 
- 	if (!(server->flags & NFS_MOUNT_NONLM))
- 		lockd_down();	/* release rpc.lockd */
-@@ -226,27 +227,57 @@ nfs_block_size(unsigned long bsize, unsi
- /*
-  * Obtain the root inode of the file system.
-  */
--static struct inode *
--nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh)
-+static int
-+nfs_get_root(struct inode **rooti, rpc_authflavor_t authflavor, struct super_block *sb, struct nfs_fh *rootfh)
- {
- 	struct nfs_server	*server = NFS_SB(sb);
--	struct nfs_fattr	fattr;
--	struct inode		*inode;
-+	struct nfs_fattr	fattr = { };
- 	int			error;
- 
--	if ((error = server->rpc_ops->getroot(server, rootfh, &fattr)) < 0) {
-+	error = server->rpc_ops->getroot(server, rootfh, &fattr);
-+	if (error == -EACCES && authflavor > RPC_AUTH_MAXFLAVOR) {
-+		/*
-+		 * Some authentication types (gss/krb5, most notably)
-+		 * are such that root won't be able to present a
-+		 * credential for GETATTR (ie, getroot()).
-+		 *
-+		 * We still want the mount to succeed.
-+		 * 
-+		 * So we fake the attr values and mark the inode as such.
-+		 * On the first succesful traversal, we fix everything.
-+		 * The auth type test isn't quite correct, but whatever.
-+		 */
-+		dfprintk(VFS, "NFS: faking root inode\n");
-+
-+		fattr.fileid = 1;
-+		fattr.nlink = 2;	/* minimum for a dir */
-+		fattr.type = NFDIR;
-+		fattr.mode = S_IFDIR|S_IRUGO|S_IXUGO;
-+		fattr.size = 4096;
-+		fattr.du.nfs3.used = 1;
-+		fattr.valid = NFS_ATTR_FATTR|NFS_ATTR_FATTR_V3;
-+	} else if (error < 0) {
- 		printk(KERN_NOTICE "nfs_get_root: getattr error = %d\n", -error);
--		return NULL;
-+		*rooti = NULL;	/* superfluous ... but safe */
-+		return error;
- 	}
- 
--	inode = __nfs_fhget(sb, rootfh, &fattr);
--	return inode;
-+	*rooti = __nfs_fhget(sb, rootfh, &fattr);
-+	if (error == -EACCES && authflavor > RPC_AUTH_MAXFLAVOR) {
-+		if (*rooti) {
-+			NFS_FLAGS(*rooti) |= NFS_INO_FAKE_ROOT;
-+			NFS_CACHEINV((*rooti));
-+			error = 0;
-+		}
-+	}
-+	return error;
- }
- 
- /*
-  * Do NFS version-independent mount processing, and sanity checking
-  */
--int nfs_sb_init(struct super_block *sb)
-+static int
-+nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
- {
- 	struct nfs_server	*server;
- 	struct inode		*root_inode = NULL;
-@@ -267,8 +298,7 @@ int nfs_sb_init(struct super_block *sb)
- 	sb->s_op         = &nfs_sops;
- 
- 	/* Did getting the root inode fail? */
--	root_inode = nfs_get_root(sb, &server->fh);
--	if (!root_inode)
-+	if (nfs_get_root(&root_inode, authflavor, sb, &server->fh) < 0)
- 		goto out_no_root;
- 	sb->s_root = d_alloc_root(root_inode);
- 	if (!sb->s_root)
-@@ -346,19 +376,66 @@ out_no_root:
- }
- 
- /*
-+ * Create an RPC client handle.
-+ */
-+static struct rpc_clnt *
-+nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
-+{
-+	struct rpc_timeout	timeparms;
-+	struct rpc_xprt		*xprt = NULL;
-+	struct rpc_clnt		*clnt = NULL;
-+	int			tcp   = (data->flags & NFS_MOUNT_TCP);
-+
-+	/* Initialize timeout values */
-+	timeparms.to_initval = data->timeo * HZ / 10;
-+	timeparms.to_retries = data->retrans;
-+	timeparms.to_maxval  = tcp ? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
-+	timeparms.to_exponential = 1;
-+
-+	if (!timeparms.to_initval)
-+		timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
-+	if (!timeparms.to_retries)
-+		timeparms.to_retries = 5;
-+
-+	/* create transport and client */
-+	xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
-+				 &server->addr, &timeparms);
-+	if (xprt == NULL) {
-+		printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
-+		goto out_fail;
-+	}
-+	clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
-+				 server->rpc_ops->version, data->pseudoflavor);
-+	if (clnt == NULL) {
-+		printk(KERN_WARNING "NFS: cannot create RPC client.\n");
-+		goto out_fail;
-+	}
-+
-+	clnt->cl_intr     = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
-+	clnt->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
-+	clnt->cl_droppriv = (server->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0;
-+	clnt->cl_chatty   = 1;
-+
-+	return clnt;
-+
-+out_fail:
-+	if (xprt)
-+		xprt_destroy(xprt);
-+	return NULL;
-+}
-+
-+/*
-  * The way this works is that the mount process passes a structure
-  * in the data argument which contains the server's IP address
-  * and the root file handle obtained from the server's mount
-  * daemon. We stash these away in the private superblock fields.
-  */
--int nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
-+static int
-+nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
- {
- 	struct nfs_server	*server;
--	struct rpc_xprt		*xprt = NULL;
--	struct rpc_clnt		*clnt = NULL;
--	struct rpc_timeout	timeparms;
--	int			tcp, err = -EIO;
--	u32			authflavor;
-+	int			err = -EIO;
-+	rpc_authflavor_t	authflavor;
- 
- 	server           = NFS_SB(sb);
- 	sb->s_blocksize_bits = 0;
-@@ -400,46 +477,20 @@ int nfs_fill_super(struct super_block *s
- 		server->rpc_ops = &nfs_v2_clientops;
- 	}
- 
--	/* Which protocol do we use? */
--	tcp   = (data->flags & NFS_MOUNT_TCP);
--
--	/* Initialize timeout values */
--	timeparms.to_initval = data->timeo * HZ / 10;
--	timeparms.to_retries = data->retrans;
--	timeparms.to_maxval  = tcp? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
--	timeparms.to_exponential = 1;
--
--	if (!timeparms.to_initval)
--		timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
--	if (!timeparms.to_retries)
--		timeparms.to_retries = 5;
--
--	/* Now create transport and client */
--	xprt = xprt_create_proto(tcp? IPPROTO_TCP : IPPROTO_UDP,
--						&server->addr, &timeparms);
--	if (xprt == NULL) {
--		printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
--		goto out_fail;
--	}
--
--	if (data->flags & NFS_MOUNT_SECFLAVOUR)
--		authflavor = data->pseudoflavor;
--	else
--		authflavor = RPC_AUTH_UNIX;
--
--	clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
--				 server->rpc_ops->version, authflavor);
--	if (clnt == NULL) {
--		printk(KERN_WARNING "NFS: cannot create RPC client.\n");
--		xprt_destroy(xprt);
-+	/* Fill in pseudoflavor for mount version < 5 */
-+	if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
-+		data->pseudoflavor = RPC_AUTH_UNIX;
-+	authflavor = data->pseudoflavor;	/* save for sb_init() */
-+	/* XXX maybe we want to add a server->pseudoflavor field */
-+
-+	/* Create RPC client handles */
-+	server->client = nfs_create_client(server, data);
-+	if (server->client == NULL)
- 		goto out_fail;
--	}
--
--	clnt->cl_intr     = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
--	clnt->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
--	clnt->cl_droppriv = (server->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0;
--	clnt->cl_chatty   = 1;
--	server->client    = clnt;
-+	data->pseudoflavor = RPC_AUTH_UNIX;	/* RFC 2623, sec 2.3.2 */
-+	server->client_sys = nfs_create_client(server, data);
-+	if (server->client_sys == NULL)
-+		goto out_shutdown;
- 
- 	/* Fire up rpciod if not yet running */
- 	if (rpciod_up() != 0) {
-@@ -447,7 +498,7 @@ int nfs_fill_super(struct super_block *s
- 		goto out_shutdown;
- 	}
- 
--	err = nfs_sb_init(sb);
-+	err = nfs_sb_init(sb, authflavor);
- 	if (err != 0)
- 		goto out_noinit;
- 
-@@ -466,7 +517,10 @@ int nfs_fill_super(struct super_block *s
- out_noinit:
- 	rpciod_down();
- out_shutdown:
--	rpc_shutdown_client(server->client);
-+	if (server->client)
-+		rpc_shutdown_client(server->client);
-+	if (server->client_sys)
-+		rpc_shutdown_client(server->client_sys);
- out_fail:
- 	if (server->hostname)
- 		kfree(server->hostname);
-@@ -904,6 +958,11 @@ __nfs_revalidate_inode(struct nfs_server
-  		goto out_nowait;
- 	if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode)
-  		goto out_nowait;
-+	if (NFS_FAKE_ROOT(inode)) {
-+		dfprintk(VFS, "NFS: not revalidating fake root\n");
-+		status = 0;
-+		goto out_nowait;
-+	}
- 
- 	while (NFS_REVALIDATING(inode)) {
- 		status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
-@@ -1007,6 +1066,13 @@ __nfs_refresh_inode(struct inode *inode,
- 			inode->i_sb->s_id, inode->i_ino,
- 			atomic_read(&inode->i_count), fattr->valid);
- 
-+	/* First successful call after mount, fill real data. */
-+	if (NFS_FAKE_ROOT(inode)) {
-+		dfprintk(VFS, "NFS: updating fake root\n");
-+		nfsi->fileid = fattr->fileid;
-+		NFS_FLAGS(inode) &= ~NFS_INO_FAKE_ROOT;
-+	}
-+
- 	if (nfsi->fileid != fattr->fileid) {
- 		printk(KERN_ERR "nfs_refresh_inode: inode number mismatch\n"
- 		       "expected (%s/0x%Lx), got (%s/0x%Lx)\n",
-@@ -1229,6 +1295,8 @@ static struct super_block *nfs_get_sb(st
- 			root->size = NFS2_FHSIZE;
- 			memcpy(root->data, data->old_root.data, NFS2_FHSIZE);
- 		}
-+		if (data->version < 5)
-+			data->flags &= ~NFS_MOUNT_SECFLAVOUR;
- 	}
- 
- 	if (root->size > sizeof(root->data)) {
-@@ -1373,7 +1441,7 @@ static int nfs4_fill_super(struct super_
- 	if ((server->idmap = nfs_idmap_new(server)) == NULL)
- 		printk(KERN_WARNING "NFS: couldn't start IDmap\n");
- 
--	err = nfs_sb_init(sb);
-+	err = nfs_sb_init(sb, authflavour);
- 	if (err == 0)
- 		return 0;
- 	rpciod_down();
---- linux-2.6.0-test1/fs/nfs/nfs3proc.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/nfs3proc.c	2003-07-19 17:07:07.000000000 -0700
-@@ -225,81 +225,74 @@ nfs3_proc_readlink(struct inode *inode, 
- }
- 
- static int
--nfs3_proc_read(struct inode *inode, struct rpc_cred *cred,
--	       struct nfs_fattr *fattr, int flags,
--	       unsigned int base, unsigned int count, struct page *page,
--	       int *eofp)
--{
--	u64			offset = page_offset(page) + base;
--	struct nfs_readargs	arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.pgbase		= base,
--		.pages		= &page
--	};
--	struct nfs_readres	res = {
--		.fattr		= fattr,
--		.count		= count,
--	};
-+nfs3_proc_read(struct nfs_read_data *rdata)
-+{
-+	int			flags = rdata->flags;
-+	struct inode *		inode = rdata->inode;
-+	struct nfs_fattr *	fattr = rdata->res.fattr;
- 	struct rpc_message	msg = {
- 		.rpc_proc	= &nfs3_procedures[NFS3PROC_READ],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred
-+		.rpc_argp	= &rdata->args,
-+		.rpc_resp	= &rdata->res,
-+		.rpc_cred	= rdata->cred,
- 	};
- 	int			status;
- 
--	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
-+			(long long) rdata->args.offset);
- 	fattr->valid = 0;
- 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
- 	if (status >= 0)
- 		nfs_refresh_inode(inode, fattr);
- 	dprintk("NFS reply read: %d\n", status);
--	*eofp = res.eof;
- 	return status;
- }
- 
- static int
--nfs3_proc_write(struct inode *inode, struct rpc_cred *cred,
--		struct nfs_fattr *fattr, int flags,
--		unsigned int base, unsigned int count,
--		struct page *page, struct nfs_writeverf *verf)
-+nfs3_proc_write(struct nfs_write_data *wdata)
- {
--	u64			offset = page_offset(page) + base;
--	struct nfs_writeargs	arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.stable		= NFS_FILE_SYNC,
--		.pgbase		= base,
--		.pages		= &page
--	};
--	struct nfs_writeres	res = {
--		.fattr		= fattr,
--		.verf		= verf,
--	};
-+	int			rpcflags = wdata->flags;
-+	struct inode *		inode = wdata->inode;
-+	struct nfs_fattr *	fattr = wdata->res.fattr;
- 	struct rpc_message	msg = {
- 		.rpc_proc	= &nfs3_procedures[NFS3PROC_WRITE],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred
-+		.rpc_argp	= &wdata->args,
-+		.rpc_resp	= &wdata->res,
-+		.rpc_cred	= wdata->cred,
- 	};
--	int			status, rpcflags = 0;
-+	int			status;
- 
--	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
-+			(long long) wdata->args.offset);
- 	fattr->valid = 0;
--	if (flags & NFS_RW_SWAP)
--		rpcflags |= NFS_RPC_SWAPFLAGS;
--	arg.stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE;
--
- 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
--
- 	if (status >= 0)
- 		nfs3_write_refresh_inode(inode, fattr);
-+	dprintk("NFS reply write: %d\n", status);
-+	return status < 0? status : wdata->res.count;
-+}
- 
--	dprintk("NFS reply read: %d\n", status);
--	return status < 0? status : res.count;
-+static int
-+nfs3_proc_commit(struct nfs_write_data *cdata)
-+{
-+	struct inode *		inode = cdata->inode;
-+	struct nfs_fattr *	fattr = cdata->res.fattr;
-+	struct rpc_message	msg = {
-+		.rpc_proc	= &nfs3_procedures[NFS3PROC_COMMIT],
-+		.rpc_argp	= &cdata->args,
-+		.rpc_resp	= &cdata->res,
-+		.rpc_cred	= cdata->cred,
-+	};
-+	int			status;
-+
-+	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
-+			(long long) cdata->args.offset);
-+	fattr->valid = 0;
-+	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
-+	if (status >= 0)
-+		nfs3_write_refresh_inode(inode, fattr);
-+	dprintk("NFS reply commit: %d\n", status);
-+	return status;
- }
- 
- /*
-@@ -681,7 +674,7 @@ nfs3_proc_fsinfo(struct nfs_server *serv
- 
- 	dprintk("NFS call  fsinfo\n");
- 	info->fattr->valid = 0;
--	status = rpc_call(server->client, NFS3PROC_FSINFO, fhandle, info, 0);
-+	status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
- 	dprintk("NFS reply fsinfo: %d\n", status);
- 	return status;
- }
-@@ -862,6 +855,7 @@ struct nfs_rpc_ops	nfs_v3_clientops = {
- 	.readlink	= nfs3_proc_readlink,
- 	.read		= nfs3_proc_read,
- 	.write		= nfs3_proc_write,
-+	.commit		= nfs3_proc_commit,
- 	.create		= nfs3_proc_create,
- 	.remove		= nfs3_proc_remove,
- 	.unlink_setup	= nfs3_proc_unlink_setup,
---- linux-2.6.0-test1/fs/nfs/nfs3xdr.c	2003-06-14 12:18:51.000000000 -0700
-+++ 25/fs/nfs/nfs3xdr.c	2003-07-19 17:03:50.000000000 -0700
-@@ -124,8 +124,6 @@ xdr_decode_fhandle(u32 *p, struct nfs_fh
- 
- /*
-  * Encode/decode time.
-- * Since the VFS doesn't care for fractional times, we ignore the
-- * nanosecond field.
-  */
- static inline u32 *
- xdr_encode_time3(u32 *p, struct timespec *timep)
---- linux-2.6.0-test1/fs/nfs/nfs4proc.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/nfs4proc.c	2003-07-19 17:07:07.000000000 -0700
-@@ -1012,45 +1012,36 @@ nfs4_proc_readlink(struct inode *inode, 
- }
- 
- static int
--nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
--	       struct nfs_fattr *fattr, int flags,
--	       unsigned int base, unsigned int count,
--	       struct page *page, int *eofp)
-+nfs4_proc_read(struct nfs_read_data *rdata)
- {
-+	int flags = rdata->flags;
-+	struct inode *inode = rdata->inode;
-+	struct nfs_fattr *fattr = rdata->res.fattr;
-+	nfs4_stateid *stateid = &rdata->args.stateid;
- 	struct nfs_server *server = NFS_SERVER(inode);
- 	struct nfs4_shareowner	*sp;
--	uint64_t offset = page_offset(page) + base;
--	struct nfs_readargs arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.pgbase		= base,
--		.pages		= &page,
--	};
--	struct nfs_readres res = {
--		.fattr		= fattr,
--		.count		= count,
--	};
- 	struct rpc_message msg = {
- 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_READ],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred,
-+		.rpc_argp	= &rdata->args,
-+		.rpc_resp	= &rdata->res,
-+		.rpc_cred	= rdata->cred,
- 	};
- 	unsigned long timestamp = jiffies;
- 	int status;
- 
--	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
-+			(long long) rdata->args.offset);
-+
- 	/*
--	* Try first to use O_RDONLY, then O_RDWR stateid.
--	*/
-+	 * Try first to use O_RDONLY, then O_RDWR stateid.
-+	 */
- 	sp = nfs4_get_inode_share(inode, O_RDONLY);
- 	if (!sp)
- 		sp = nfs4_get_inode_share(inode, O_RDWR);
- 	if (sp)
--		memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
-+		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
- 	else
--		memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
-+		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
- 
- 	fattr->valid = 0;
- 	status = rpc_call_sync(server->client, &msg, flags);
-@@ -1061,56 +1052,82 @@ nfs4_proc_read(struct inode *inode, stru
- 			nfs_zap_caches(inode);
- 	}
- 	dprintk("NFS reply read: %d\n", status);
--	*eofp = res.eof;
- 	return status;
- }
- 
- static int
--nfs4_proc_write(struct inode *inode, struct rpc_cred *cred,
--		struct nfs_fattr *fattr, int flags,
--		unsigned int base, unsigned int count,
--		struct page *page, struct nfs_writeverf *verf)
-+nfs4_proc_write(struct nfs_write_data *wdata)
- {
-+	int rpcflags = wdata->flags;
-+	struct inode *inode = wdata->inode;
-+	struct nfs_fattr *fattr = wdata->res.fattr;
-+	nfs4_stateid *stateid = &wdata->args.stateid;
- 	struct nfs_server *server = NFS_SERVER(inode);
--	struct nfs4_shareowner	*sp;
--	uint64_t offset = page_offset(page) + base;
--	struct nfs_writeargs arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.stable		= (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE,
--		.pgbase		= base,
--		.pages		= &page,
--	};
--	struct nfs_writeres res = {
--		.fattr		= fattr,
--		.count		= count,
--		.verf		= verf,
--	};
-+	struct nfs4_shareowner *sp;
- 	struct rpc_message msg = {
- 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_WRITE],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred,
-+		.rpc_argp	= &wdata->args,
-+		.rpc_resp	= &wdata->res,
-+		.rpc_cred	= wdata->cred,
-+	};
-+	int status;
-+
-+	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
-+			(long long) wdata->args.offset);
-+
-+	/*
-+	 * Try first to use O_WRONLY, then O_RDWR stateid.
-+	 */
-+	sp = nfs4_get_inode_share(inode, O_WRONLY);
-+	if (!sp)
-+		sp = nfs4_get_inode_share(inode, O_RDWR);
-+
-+	if (sp)
-+		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
-+	else
-+		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
-+
-+	fattr->valid = 0;
-+	status = rpc_call_sync(server->client, &msg, rpcflags);
-+	dprintk("NFS reply write: %d\n", status);
-+	return status;
-+}
-+
-+static int
-+nfs4_proc_commit(struct nfs_write_data *cdata)
-+{
-+	struct inode *inode = cdata->inode;
-+	struct nfs_fattr *fattr = cdata->res.fattr;
-+	nfs4_stateid *stateid = &cdata->args.stateid;
-+	struct nfs_server *server = NFS_SERVER(inode);
-+	struct nfs4_shareowner *sp;
-+	struct rpc_message msg = {
-+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
-+		.rpc_argp	= &cdata->args,
-+		.rpc_resp	= &cdata->res,
-+		.rpc_cred	= cdata->cred,
- 	};
--	int			rpcflags = (flags & NFS_RW_SWAP) ? NFS_RPC_SWAPFLAGS : 0;
-+	int status;
- 
--	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
-+			(long long) cdata->args.offset);
- 
- 	/*
--	* Try first to use O_WRONLY, then O_RDWR stateid.
--	*/
-+	 * Try first to use O_WRONLY, then O_RDWR stateid.
-+	 */
- 	sp = nfs4_get_inode_share(inode, O_WRONLY);
- 	if (!sp)
- 		sp = nfs4_get_inode_share(inode, O_RDWR);
- 
- 	if (sp)
--		memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
-+		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
- 	else
--		memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
-+		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
- 
- 	fattr->valid = 0;
--	return rpc_call_sync(server->client, &msg, rpcflags);
-+	status = rpc_call_sync(server->client, &msg, 0);
-+	dprintk("NFS reply commit: %d\n", status);
-+	return status;
- }
- 
- /*
-@@ -1752,7 +1769,7 @@ struct nfs_rpc_ops	nfs_v4_clientops = {
- 	.readlink	= nfs4_proc_readlink,
- 	.read		= nfs4_proc_read,
- 	.write		= nfs4_proc_write,
--	.commit		= NULL,
-+	.commit		= nfs4_proc_commit,
- 	.create		= nfs4_proc_create,
- 	.remove		= nfs4_proc_remove,
- 	.unlink_setup	= nfs4_proc_unlink_setup,
---- linux-2.6.0-test1/fs/nfs/pagelist.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/pagelist.c	2003-07-19 17:07:05.000000000 -0700
-@@ -154,26 +154,6 @@ nfs_release_request(struct nfs_page *req
- }
- 
- /**
-- * nfs_release_list - cleanly dispose of an unattached list of page requests
-- * @list: list of doomed page requests
-- */
--void
--nfs_release_list(struct list_head *list)
--{
--	while (!list_empty(list)) {
--		struct nfs_page *req = nfs_list_entry(list);
--
--		nfs_list_remove_request(req);
--
--		page_cache_release(req->wb_page);
--
--		/* Release struct file or cached credential */
--		nfs_clear_request(req);
--		nfs_page_free(req);
--	}
--}
--
--/**
-  * nfs_list_add_request - Insert a request into a sorted list
-  * @req: request
-  * @head: head of list into which to insert the request.
-@@ -222,37 +202,6 @@ nfs_wait_on_request(struct nfs_page *req
- }
- 
- /**
-- * nfs_wait_for_reads - wait for outstanding requests to complete
-- * @head: list of page requests to wait for
-- */
--int
--nfs_wait_for_reads(struct list_head *head)
--{
--	struct list_head *p = head->next;
--	unsigned int res = 0;
--
--	while (p != head) {
--		struct nfs_page *req = nfs_list_entry(p);
--		int error;
--
--		if (!NFS_WBACK_BUSY(req))
--			continue;
--
--		req->wb_count++;
--		error = nfs_wait_on_request(req);
--		if (error < 0)
--			return error;
--		nfs_list_remove_request(req);
--		nfs_clear_request(req);
--		nfs_page_free(req);
--
--		p = head->next;
--		res++;
--	}
--	return res;
--}
--
--/**
-  * nfs_coalesce_requests - Split coalesced requests out from a list.
-  * @head: source list
-  * @dst: destination list
---- linux-2.6.0-test1/fs/nfs/proc.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/proc.c	2003-07-19 17:07:07.000000000 -0700
-@@ -149,82 +149,62 @@ nfs_proc_readlink(struct inode *inode, s
- }
- 
- static int
--nfs_proc_read(struct inode *inode, struct rpc_cred *cred,
--	      struct nfs_fattr *fattr, int flags,
--	      unsigned int base, unsigned int count, struct page *page,
--	      int *eofp)
--{
--	u64			offset = page_offset(page) + base;
--	struct nfs_readargs	arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.pgbase		= base,
--		.pages		= &page
--	};
--	struct nfs_readres	res = {
--		.fattr		= fattr,
--		.count		= count
--	};
-+nfs_proc_read(struct nfs_read_data *rdata)
-+{
-+	int			flags = rdata->flags;
-+	struct inode *		inode = rdata->inode;
-+	struct nfs_fattr *	fattr = rdata->res.fattr;
- 	struct rpc_message	msg = {
- 		.rpc_proc	= &nfs_procedures[NFSPROC_READ],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred
-+		.rpc_argp	= &rdata->args,
-+		.rpc_resp	= &rdata->res,
-+		.rpc_cred	= rdata->cred,
- 	};
- 	int			status;
- 
--	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
-+			(long long) rdata->args.offset);
- 	fattr->valid = 0;
- 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
--
--	if (status >= 0)
-+	if (status >= 0) {
- 		nfs_refresh_inode(inode, fattr);
-+		/* NFSv2 reads don't return an eof flag, so we make
-+		 * up a value here.  XDR has already set eof to 0. */
-+		if (status < rdata->args.count)
-+			rdata->res.eof = 1;
-+	}
- 	dprintk("NFS reply read: %d\n", status);
--	*eofp = res.eof;
- 	return status;
- }
- 
- static int
--nfs_proc_write(struct inode *inode, struct rpc_cred *cred,
--	       struct nfs_fattr *fattr, int how,
--	       unsigned int base, unsigned int count,
--	       struct page *page, struct nfs_writeverf *verf)
-+nfs_proc_write(struct nfs_write_data *wdata)
- {
--	u64			offset = page_offset(page) + base;
--	struct nfs_writeargs	arg = {
--		.fh		= NFS_FH(inode),
--		.offset		= offset,
--		.count		= count,
--		.stable		= NFS_FILE_SYNC,
--		.pgbase		= base,
--		.pages		= &page
--	};
--	struct nfs_writeres     res = {
--		.fattr		= fattr,
--		.verf		= verf,
--		.count		= count
--	};
-+	int			flags = wdata->flags;
-+	struct inode *		inode = wdata->inode;
-+	struct nfs_fattr *	fattr = wdata->res.fattr;
- 	struct rpc_message	msg = {
- 		.rpc_proc	= &nfs_procedures[NFSPROC_WRITE],
--		.rpc_argp	= &arg,
--		.rpc_resp	= &res,
--		.rpc_cred	= cred
-+		.rpc_argp	= &wdata->args,
-+		.rpc_resp	= &wdata->res,
-+		.rpc_cred	= wdata->cred
- 	};
--	int			status, flags = 0;
-+	int			status;
- 
--	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
-+	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
-+			(long long) wdata->args.offset);
- 	fattr->valid = 0;
--	if (how & NFS_RW_SWAP)
--		flags |= NFS_RPC_SWAPFLAGS;
- 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
--
--	if (status >= 0)
-+	if (status >= 0) {
- 		nfs_write_refresh_inode(inode, fattr);
--
-+		/* NFSv2 writes don't return a byte count or write
-+		 * verifier, so we make up values here.  Note that
-+		 * v2 writes are always NFS_FILE_SYNC writes. */
-+		wdata->res.count = wdata->args.count;
-+		wdata->verf.committed = NFS_FILE_SYNC;
-+	}
- 	dprintk("NFS reply write: %d\n", status);
--	verf->committed = NFS_FILE_SYNC;      /* NFSv2 always syncs data */
--	return status < 0? status : count;
-+	return status < 0? status : wdata->res.count;
- }
- 
- static int
---- linux-2.6.0-test1/fs/nfs/read.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/nfs/read.c	2003-07-19 17:07:06.000000000 -0700
-@@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_tas
- static int
- nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
- {
--	struct rpc_cred	*cred = NULL;
--	struct nfs_fattr fattr;
--	unsigned int	offset = 0;
- 	unsigned int	rsize = NFS_SERVER(inode)->rsize;
- 	unsigned int	count = PAGE_CACHE_SIZE;
- 	int		result;
--	int		flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0;
--	int		eof;
-+	struct nfs_read_data	rdata = {
-+		.flags		= (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0),
-+		.cred		= NULL,
-+		.inode		= inode,
-+		.args		= {
-+			.fh		= NFS_FH(inode),
-+			.pages		= &page,
-+			.pgbase		= 0UL,
-+			.count		= rsize,
-+		},
-+		.res		= {
-+			.fattr		= &rdata.fattr,
-+		}
-+	};
- 
- 	dprintk("NFS: nfs_readpage_sync(%p)\n", page);
- 
- 	if (file)
--		cred = nfs_file_cred(file);
-+		rdata.cred = nfs_file_cred(file);
- 
- 	/*
- 	 * This works now because the socket layer never tries to DMA
-@@ -89,17 +98,19 @@ nfs_readpage_sync(struct file *file, str
- 	 */
- 	do {
- 		if (count < rsize)
--			rsize = count;
-+			rdata.args.count = count;
-+		rdata.res.count = rdata.args.count;
-+		rdata.args.offset = page_offset(page) + rdata.args.pgbase;
- 
- 		dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
- 			NFS_SERVER(inode)->hostname,
- 			inode->i_sb->s_id,
- 			(long long)NFS_FILEID(inode),
--			(unsigned long long)offset, rsize);
-+			(unsigned long long)rdata.args.pgbase,
-+			rdata.args.count);
- 
- 		lock_kernel();
--		result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
--						offset, rsize, page, &eof);
-+		result = NFS_PROTO(inode)->read(&rdata);
- 		unlock_kernel();
- 
- 		/*
-@@ -111,14 +122,15 @@ nfs_readpage_sync(struct file *file, str
- 				result = -EINVAL;
- 			goto io_error;
- 		}
--		count  -= result;
--		offset += result;
--		if (result < rsize)	/* NFSv2ism */
-+		count -= result;
-+		rdata.args.pgbase += result;
-+
-+		if (rdata.res.eof)
- 			break;
- 	} while (count);
- 
- 	if (count)
--		memclear_highpage_flush(page, offset, count);
-+		memclear_highpage_flush(page, rdata.args.pgbase, count);
- 	SetPageUptodate(page);
- 	if (PageError(page))
- 		ClearPageError(page);
---- linux-2.6.0-test1/fs/nfs/write.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/nfs/write.c	2003-07-19 17:07:07.000000000 -0700
-@@ -132,66 +132,73 @@ static int
- nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
- 		   unsigned int offset, unsigned int count)
- {
--	struct rpc_cred	*cred = NULL;
--	loff_t		base;
- 	unsigned int	wsize = NFS_SERVER(inode)->wsize;
--	int		result, refresh = 0, written = 0, flags;
--	u8		*buffer;
--	struct nfs_fattr fattr;
--	struct nfs_writeverf verf;
--
-+	int		result, written = 0;
-+	int		swapfile = IS_SWAPFILE(inode);
-+	struct nfs_write_data	wdata = {
-+		.flags		= swapfile ? NFS_RPC_SWAPFLAGS : 0,
-+		.cred		= NULL,
-+		.inode		= inode,
-+		.args		= {
-+			.fh		= NFS_FH(inode),
-+			.pages		= &page,
-+			.stable		= NFS_FILE_SYNC,
-+			.pgbase		= offset,
-+			.count		= wsize,
-+		},
-+		.res		= {
-+			.fattr		= &wdata.fattr,
-+			.verf		= &wdata.verf,
-+		},
-+	};
- 
- 	if (file)
--		cred = get_rpccred(nfs_file_cred(file));
--	if (!cred)
--		cred = get_rpccred(NFS_I(inode)->mm_cred);
-+		wdata.cred = get_rpccred(nfs_file_cred(file));
-+	if (!wdata.cred)
-+		wdata.cred = get_rpccred(NFS_I(inode)->mm_cred);
- 
- 	dprintk("NFS:      nfs_writepage_sync(%s/%Ld %d@%Ld)\n",
- 		inode->i_sb->s_id,
- 		(long long)NFS_FILEID(inode),
- 		count, (long long)(page_offset(page) + offset));
- 
--	base = page_offset(page) + offset;
--
--	flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC;
--
- 	do {
--		if (count < wsize && !IS_SWAPFILE(inode))
--			wsize = count;
-+		if (count < wsize && !swapfile)
-+			wdata.args.count = count;
-+		wdata.args.offset = page_offset(page) + wdata.args.pgbase;
- 
--		result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags,
--						 offset, wsize, page, &verf);
-+		result = NFS_PROTO(inode)->write(&wdata);
- 
- 		if (result < 0) {
- 			/* Must mark the page invalid after I/O error */
- 			ClearPageUptodate(page);
- 			goto io_error;
- 		}
--		if (result != wsize)
--			printk("NFS: short write, wsize=%u, result=%d\n",
--			wsize, result);
--		refresh = 1;
--		buffer  += wsize;
--		base    += wsize;
--	        offset  += wsize;
--		written += wsize;
--		count   -= wsize;
-+		if (result < wdata.args.count)
-+			printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n",
-+					wdata.args.count, result);
-+
-+		wdata.args.offset += result;
-+	        wdata.args.pgbase += result;
-+		written += result;
-+		count -= result;
-+
- 		/*
- 		 * If we've extended the file, update the inode
- 		 * now so we don't invalidate the cache.
- 		 */
--		if (base > i_size_read(inode))
--			i_size_write(inode, base);
-+		if (wdata.args.offset > i_size_read(inode))
-+			i_size_write(inode, wdata.args.offset);
- 	} while (count);
- 
- 	if (PageError(page))
- 		ClearPageError(page);
- 
- io_error:
--	if (cred)
--		put_rpccred(cred);
-+	if (wdata.cred)
-+		put_rpccred(wdata.cred);
- 
--	return written? written : result;
-+	return written ? written : result;
- }
- 
- static int
---- linux-2.6.0-test1/fs/partitions/check.c	2003-06-22 12:04:44.000000000 -0700
-+++ 25/fs/partitions/check.c	2003-07-19 17:03:50.000000000 -0700
-@@ -16,7 +16,6 @@
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
--#include <linux/blk.h>
- #include <linux/kmod.h>
- #include <linux/ctype.h>
- #include <linux/devfs_fs_kernel.h>
-@@ -348,6 +347,9 @@ void register_disk(struct gendisk *disk)
- 		return;
- 	}
- 
-+	/* always add handle for the whole disk */
-+	devfs_add_partitioned(disk);
-+
- 	/* No such device (e.g., media were just removed) */
- 	if (!get_capacity(disk))
- 		return;
-@@ -356,7 +358,6 @@ void register_disk(struct gendisk *disk)
- 	if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0)
- 		return;
- 	state = check_partition(disk, bdev);
--	devfs_add_partitioned(disk);
- 	if (state) {
- 		for (j = 1; j < state->limit; j++) {
- 			sector_t size = state->parts[j].size;
---- linux-2.6.0-test1/fs/partitions/efi.h	2003-06-14 12:18:28.000000000 -0700
-+++ 25/fs/partitions/efi.h	2003-07-19 17:03:50.000000000 -0700
-@@ -32,7 +32,6 @@
- #include <linux/kernel.h>
- #include <linux/major.h>
- #include <linux/string.h>
--#include <linux/blk.h>
- #include <linux/efi.h>
- 
- #define MSDOS_MBR_SIGNATURE 0xaa55
---- linux-2.6.0-test1/fs/partitions/nec98.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/fs/partitions/nec98.c	2003-07-19 17:03:50.000000000 -0700
-@@ -8,7 +8,6 @@
- #include <linux/fs.h>
- #include <linux/genhd.h>
- #include <linux/kernel.h>
--#include <linux/blk.h>
- #include <linux/hdreg.h>
- 
- #include "check.h"
---- linux-2.6.0-test1/fs/proc/array.c	2003-06-26 22:07:25.000000000 -0700
-+++ 25/fs/proc/array.c	2003-07-19 17:06:42.000000000 -0700
-@@ -300,7 +300,7 @@ int proc_pid_stat(struct task_struct *ta
- 	task_lock(task);
- 	mm = task->mm;
- 	if(mm)
--		atomic_inc(&mm->mm_users);
-+		mm = mmgrab(mm);
- 	if (task->tty) {
- 		tty_pgrp = task->tty->pgrp;
- 		tty_nr = task->tty->device;
---- linux-2.6.0-test1/fs/proc/proc_misc.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/fs/proc/proc_misc.c	2003-07-19 17:06:40.000000000 -0700
-@@ -274,6 +274,18 @@ static struct file_operations proc_cpuin
- 	.release	= seq_release,
- };
- 
-+extern struct seq_operations rcu_op;
-+static int rcu_open(struct inode *inode, struct file *file)
-+{
-+	return seq_open(file, &rcu_op);
-+}
-+static struct file_operations proc_rcu_operations = {
-+	.open		= rcu_open,
-+	.read		= seq_read,
-+	.llseek		= seq_lseek,
-+	.release	= seq_release,
-+};
-+
- extern struct seq_operations vmstat_op;
- static int vmstat_open(struct inode *inode, struct file *file)
- {
-@@ -388,10 +400,8 @@ static int kstat_read_proc(char *page, c
- 		system += kstat_cpu(i).cpustat.system;
- 		idle += kstat_cpu(i).cpustat.idle;
- 		iowait += kstat_cpu(i).cpustat.iowait;
--#if !defined(CONFIG_ARCH_S390)
- 		for (j = 0 ; j < NR_IRQS ; j++)
- 			sum += kstat_cpu(i).irqs[j];
--#endif
- 	}
- 
- 	len = sprintf(page, "cpu  %u %u %u %u %u\n",
-@@ -412,7 +422,7 @@ static int kstat_read_proc(char *page, c
- 	}
- 	len += sprintf(page + len, "intr %u", sum);
- 
--#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA)
-+#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA)
- 	for (i = 0 ; i < NR_IRQS ; i++)
- 		len += sprintf(page + len, " %u", kstat_irqs(i));
- #endif
-@@ -440,7 +450,6 @@ static int devices_read_proc(char *page,
- 	return proc_calc_metrics(page, start, off, count, eof, len);
- }
- 
--#if !defined(CONFIG_ARCH_S390)
- extern int show_interrupts(struct seq_file *p, void *v);
- static int interrupts_open(struct inode *inode, struct file *file)
- {
-@@ -466,7 +475,6 @@ static struct file_operations proc_inter
- 	.llseek		= seq_lseek,
- 	.release	= single_release,
- };
--#endif
- 
- static int filesystems_read_proc(char *page, char **start, off_t off,
- 				 int count, int *eof, void *data)
-@@ -536,7 +544,8 @@ static ssize_t read_profile(struct file 
- 		buf++; p++; count--; read++;
- 	}
- 	pnt = (char *)prof_buffer + p - sizeof(unsigned int);
--	copy_to_user(buf,(void *)pnt,count);
-+	if (copy_to_user(buf,(void *)pnt,count))
-+		return -EFAULT;
- 	read += count;
- 	*ppos += read;
- 	return read;
-@@ -606,6 +615,36 @@ static void create_seq_entry(char *name,
- 		entry->proc_fops = f;
- }
- 
-+#ifdef CONFIG_LOCKMETER
-+extern ssize_t get_lockmeter_info(char *, size_t, loff_t *);
-+extern ssize_t put_lockmeter_info(const char *, size_t);
-+extern int get_lockmeter_info_size(void);
-+
-+/*
-+ * This function accesses lock metering information.
-+ */
-+static ssize_t read_lockmeter(struct file *file, char *buf,
-+			      size_t count, loff_t *ppos)
-+{
-+	return get_lockmeter_info(buf, count, ppos);
-+}
-+
-+/*
-+ * Writing to /proc/lockmeter resets the counters
-+ */
-+static ssize_t write_lockmeter(struct file * file, const char * buf,
-+			       size_t count, loff_t *ppos)
-+{
-+	return put_lockmeter_info(buf, count);
-+}
-+
-+static struct file_operations proc_lockmeter_operations = {
-+	NULL,           /* lseek */
-+	read:		read_lockmeter,
-+	write:		write_lockmeter,
-+};
-+#endif  /* CONFIG_LOCKMETER */
-+
- void __init proc_misc_init(void)
- {
- 	struct proc_dir_entry *entry;
-@@ -644,10 +683,9 @@ void __init proc_misc_init(void)
- 	if (entry)
- 		entry->proc_fops = &proc_kmsg_operations;
- 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
-+	create_seq_entry("rcu", 0, &proc_rcu_operations);
- 	create_seq_entry("partitions", 0, &proc_partitions_operations);
--#if !defined(CONFIG_ARCH_S390)
- 	create_seq_entry("interrupts", 0, &proc_interrupts_operations);
--#endif
- 	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
- 	create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
- 	create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
-@@ -673,6 +711,13 @@ void __init proc_misc_init(void)
- 	if (entry)
- 		entry->proc_fops = &proc_sysrq_trigger_operations;
- #endif
-+#ifdef CONFIG_LOCKMETER
-+	entry = create_proc_entry("lockmeter", S_IWUSR | S_IRUGO, NULL);
-+	if (entry) {
-+		entry->proc_fops = &proc_lockmeter_operations;
-+		entry->size = get_lockmeter_info_size();
-+	}
-+#endif
- #ifdef CONFIG_PPC32
- 	{
- 		extern struct file_operations ppc_htab_operations;
---- linux-2.6.0-test1/fs/stat.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/fs/stat.c	2003-07-19 17:06:16.000000000 -0700
-@@ -123,6 +123,7 @@ static int cp_old_stat(struct kstat *sta
- 	SET_OLDSTAT_UID(tmp, stat->uid);
- 	SET_OLDSTAT_GID(tmp, stat->gid);
- 	tmp.st_rdev = stat->rdev;
-+	tmp.__pad_16bit = 0;  /* don't leak kernel stack data! */
- #if BITS_PER_LONG == 32
- 	if (stat->size > MAX_NON_LFS)
- 		return -EOVERFLOW;
---- linux-2.6.0-test1/fs/umsdos/ioctl.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/fs/umsdos/ioctl.c	2003-07-19 17:03:50.000000000 -0700
-@@ -4,6 +4,10 @@
-  *  Written 1993 by Jacques Gelinas
-  *
-  *  Extended MS-DOS ioctl directory handling functions
-+ *
-+ *  Changes:
-+ *  11/07/2003      Daniele Bellucci <bellucda@tiscali.it>
-+ *                  - audit copy_to_user/put_user in umsdos_ioctl_fill.
-  */
- 
- #include <asm/uaccess.h>
-@@ -36,11 +40,12 @@ static int umsdos_ioctl_fill (
- 	struct UMSDOS_DIR_ONCE *d = (struct UMSDOS_DIR_ONCE *) buf;
- 
- 	if (d->count == 0) {
--		copy_to_user (d->ent->d_name, name, name_len);
--		put_user ('\0', d->ent->d_name + name_len);
--		put_user (name_len, &d->ent->d_reclen);
--		put_user (ino, &d->ent->d_ino);
--		put_user (offset, &d->ent->d_off);
-+		if (copy_to_user (d->ent->d_name, name, name_len) ||
-+		    put_user ('\0', d->ent->d_name + name_len) ||
-+		    put_user (name_len, &d->ent->d_reclen) ||
-+		    put_user (ino, &d->ent->d_ino) ||
-+		    put_user (offset, &d->ent->d_off))
-+			return -EFAULT;
- 		d->count = 1;
- 		ret = 0;
- 	}
---- linux-2.6.0-test1/fs/vfat/namei.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/fs/vfat/namei.c	2003-07-19 17:03:50.000000000 -0700
-@@ -375,7 +375,7 @@ shortname_info_to_lcase(struct shortname
- }
- 
- static inline int to_shortname_char(struct nls_table *nls,
--				    char *buf, int buf_size, wchar_t *src,
-+				    unsigned char *buf, int buf_size, wchar_t *src,
- 				    struct shortname_info *info)
- {
- 	int len;
---- linux-2.6.0-test1/include/acpi/acconfig.h	2003-06-22 12:04:44.000000000 -0700
-+++ 25/include/acpi/acconfig.h	2003-07-19 17:03:50.000000000 -0700
-@@ -64,7 +64,7 @@
- 
- /* Version string */
- 
--#define ACPI_CA_VERSION                 0x20030619
-+#define ACPI_CA_VERSION                 0x20030714
- 
- /* Maximum objects in the various object caches */
- 
---- linux-2.6.0-test1/include/acpi/platform/acenv.h	2003-06-14 12:18:03.000000000 -0700
-+++ 25/include/acpi/platform/acenv.h	2003-07-19 17:03:50.000000000 -0700
-@@ -134,6 +134,9 @@
- #elif defined(__FreeBSD__)
- #include "acfreebsd.h"
- 
-+#elif defined(__NetBSD__)
-+#include "acnetbsd.h"
-+
- #elif defined(MODESTO)
- #include "acmodesto.h"
- 
-@@ -187,13 +190,14 @@
- #define DEBUGGER_SINGLE_THREADED    0
- #define DEBUGGER_MULTI_THREADED     1
- 
-+#ifndef DEBUGGER_THREADING
- #ifdef ACPI_APPLICATION
- #define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
- 
- #else
- #define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
- #endif
--
-+#endif /* !DEBUGGER_THREADING */
- 
- /******************************************************************************
-  *
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-alpha/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,90 @@
-+/*
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ *
-+ *  Modified by Peter Rival (frival@zk3.dec.com)
-+ */
-+
-+#ifndef _ALPHA_LOCKMETER_H
-+#define _ALPHA_LOCKMETER_H
-+
-+#include <asm/hwrpb.h>
-+#define CPU_CYCLE_FREQUENCY	hwrpb->cycle_freq
-+
-+#define get_cycles64()		get_cycles()
-+
-+#define THIS_CPU_NUMBER		smp_processor_id()
-+
-+#include <linux/version.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-+#define local_irq_save(x) \
-+	__save_and_cli(x)
-+#define local_irq_restore(x) \
-+	__restore_flags(x)
-+#endif	/* Linux version 2.2.x */
-+
-+#define SPINLOCK_MAGIC_INIT /**/
-+
-+/*
-+ * Macros to cache and retrieve an index value inside of a lock
-+ * these macros assume that there are less than 65536 simultaneous
-+ * (read mode) holders of a rwlock.
-+ * We also assume that the hash table has less than 32767 entries.
-+ * the high order bit is used for write locking a rw_lock
-+ * Note: although these defines and macros are the same as what is being used
-+ *       in include/asm-i386/lockmeter.h, they are present here to easily
-+ *	 allow an alternate Alpha implementation.
-+ */
-+/*
-+ * instrumented spinlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a spinlock_t
-+ */
-+typedef struct inst_spinlock_s {
-+	/* remember, Alpha is little endian */
-+	unsigned short lock;
-+	unsigned short index;
-+} inst_spinlock_t;
-+#define PUT_INDEX(lock_ptr,indexv)	((inst_spinlock_t *)(lock_ptr))->index = indexv
-+#define GET_INDEX(lock_ptr)		((inst_spinlock_t *)(lock_ptr))->index
-+
-+/*
-+ * macros to cache and retrieve an index value in a read/write lock
-+ * as well as the cpu where a reader busy period started
-+ * we use the 2nd word (the debug word) for this, so require the
-+ * debug word to be present
-+ */
-+/*
-+ * instrumented rwlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a rwlock_t
-+ */
-+typedef struct inst_rwlock_s {
-+	volatile int lock;
-+	unsigned short index;
-+	unsigned short cpu;
-+} inst_rwlock_t;
-+#define PUT_RWINDEX(rwlock_ptr,indexv)	((inst_rwlock_t *)(rwlock_ptr))->index = indexv
-+#define GET_RWINDEX(rwlock_ptr)		((inst_rwlock_t *)(rwlock_ptr))->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)	((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
-+#define GET_RW_CPU(rwlock_ptr)		((inst_rwlock_t *)(rwlock_ptr))->cpu
-+
-+/*
-+ * return true if rwlock is write locked
-+ * (note that other lock attempts can cause the lock value to be negative)
-+ */
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) (((inst_rwlock_t *)rwlock_ptr)->lock & 1)
-+#define IABS(x) ((x) > 0 ? (x) : -(x))
-+
-+#define RWLOCK_READERS(rwlock_ptr)	rwlock_readers(rwlock_ptr)
-+extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
-+{
-+	int tmp = (int) ((inst_rwlock_t *)rwlock_ptr)->lock;
-+	/* readers subtract 2, so we have to:		*/
-+	/* 	- andnot off a possible writer (bit 0)	*/
-+	/*	- get the absolute value		*/
-+	/*	- divide by 2 (right shift by one)	*/
-+	/* to find the number of readers		*/
-+	if (tmp == 0) return(0);
-+	else return(IABS(tmp & ~1)>>1);
-+}
-+
-+#endif /* _ALPHA_LOCKMETER_H */
---- linux-2.6.0-test1/include/asm-alpha/pgalloc.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-alpha/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -24,9 +24,9 @@ pmd_populate_kernel(struct mm_struct *mm
- }
- 
- static inline void
--pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-+pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd)
- {
--	pgd_set(pgd, pmd);
-+	pgd_set(pgd, page_address(pmd));
- }
- 
- extern pgd_t *pgd_alloc(struct mm_struct *mm);
-@@ -37,19 +37,29 @@ pgd_free(pgd_t *pgd)
- 	free_page((unsigned long)pgd);
- }
- 
--static inline pmd_t *
-+static inline struct page *
- pmd_alloc_one(struct mm_struct *mm, unsigned long address)
- {
--	pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
--	if (ret)
--		clear_page(ret);
--	return ret;
-+	struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
-+	if (page)
-+		clear_highpage(page);
-+	return page;
-+}
-+
-+static inline pmd_t *
-+pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
-+{
-+	struct page *page = pmd_alloc_one(mm, addr);
-+	if (page)
-+		return page_address(page);
-+	else
-+		return NULL;
- }
- 
- static inline void
--pmd_free(pmd_t *pmd)
-+pmd_free(struct page *pmd)
- {
--	free_page((unsigned long)pmd);
-+	__free_page(pmd);
- }
- 
- extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
---- linux-2.6.0-test1/include/asm-alpha/pgtable.h	2003-06-14 12:18:06.000000000 -0700
-+++ 25/include/asm-alpha/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -229,9 +229,11 @@ pmd_page_kernel(pmd_t pmd)
- #define pmd_page(pmd)	(mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
- #endif
- 
--extern inline unsigned long pgd_page(pgd_t pgd)
-+extern inline unsigned long __pgd_page(pgd_t pgd)
- { return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
- 
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
-+
- extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
- extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
- extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
-@@ -280,9 +282,15 @@ extern inline pte_t pte_mkyoung(pte_t pt
- /* Find an entry in the second-level page table.. */
- extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
- {
--	return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
-+	return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- /* Find an entry in the third-level page table.. */
- extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
- {
---- linux-2.6.0-test1/include/asm-alpha/posix_types.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/include/asm-alpha/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned int	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned int	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-alpha/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-alpha/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -3,6 +3,7 @@
- 
- #include <linux/config.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <linux/bitops.h>
- #include <asm/pal.h>
- 
-@@ -44,27 +45,12 @@ extern struct cpuinfo_alpha cpu_data[NR_
- #define hard_smp_processor_id()	__hard_smp_processor_id()
- #define smp_processor_id()	(current_thread_info()->cpu)
- 
--extern unsigned long cpu_present_mask;
--extern volatile unsigned long cpu_online_map;
-+extern cpumask_t cpu_present_mask;
-+extern cpumask_t long cpu_online_map;
- extern int smp_num_cpus;
- 
--#define cpu_possible(cpu)	(cpu_present_mask & (1UL << (cpu)))
--#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
--
--static inline int
--num_online_cpus(void)
--{
--	return hweight64(cpu_online_map);
--}
--
--extern inline int
--any_online_cpu(unsigned int mask)
--{
--        if (mask & cpu_online_map)
--                return __ffs(mask & cpu_online_map);
--
--        return -1;
--}
-+#define cpu_possible(cpu)	cpu_isset(cpu, cpu_present_mask)
-+#define cpu_online(cpu)		cpu_isset(cpu, cpu_online_map)
- 
- extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
- 
---- linux-2.6.0-test1/include/asm-alpha/spinlock.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-alpha/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -6,6 +6,10 @@
- #include <linux/kernel.h>
- #include <asm/current.h>
- 
-+#ifdef CONFIG_LOCKMETER
-+#undef DEBUG_SPINLOCK
-+#undef DEBUG_RWLOCK
-+#endif
- 
- /*
-  * Simple spin lock operations.  There are two variants, one clears IRQ's
-@@ -95,9 +99,18 @@ static inline int _raw_spin_trylock(spin
- 
- typedef struct {
- 	volatile int write_lock:1, read_counter:31;
-+#ifdef CONFIG_LOCKMETER
-+	/* required for LOCKMETER since all bits in lock are used */
-+	/* need this storage for CPU and lock INDEX ............. */
-+	unsigned magic;
-+#endif
- } /*__attribute__((aligned(32)))*/ rwlock_t;
- 
-+#ifdef CONFIG_LOCKMETER
-+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
-+#else
- #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-+#endif
- 
- #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
- #define rwlock_is_locked(x)	(*(volatile int *)(x) != 0)
-@@ -169,4 +182,41 @@ static inline void _raw_read_unlock(rwlo
- 	: "m" (*lock) : "memory");
- }
- 
-+#ifdef CONFIG_LOCKMETER
-+static inline int _raw_write_trylock(rwlock_t *lock)
-+{
-+	long temp,result;
-+
-+	__asm__ __volatile__(
-+	"	ldl_l %1,%0\n"
-+	"	mov $31,%2\n"
-+	"	bne %1,1f\n"
-+	"	or $31,1,%2\n"
-+	"	stl_c %2,%0\n"
-+	"1:	mb\n"
-+	: "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
-+	: "m" (*(volatile int *)lock)
-+	);
-+
-+	return (result);
-+}
-+
-+static inline int _raw_read_trylock(rwlock_t *lock)
-+{
-+	unsigned long temp,result;
-+
-+	__asm__ __volatile__(
-+	"	ldl_l %1,%0\n"
-+	"	mov $31,%2\n"
-+	"	blbs %1,1f\n"
-+	"	subl %1,2,%2\n"
-+	"	stl_c %2,%0\n"
-+	"1:	mb\n"
-+	: "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
-+	: "m" (*(volatile int *)lock)
-+	);
-+	return (result);
-+}
-+#endif /* CONFIG_LOCKMETER */
-+
- #endif /* _ALPHA_SPINLOCK_H */
---- linux-2.6.0-test1/include/asm-arm26/pgalloc.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-arm26/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -55,7 +55,8 @@ pmd_populate_kernel(struct mm_struct *mm
-  * is thrown away. It just cant be zero. -IM
-  */
- 
--#define pmd_alloc_one(mm,addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm,addr)		((struct page *)2); BUG()
-+#define pmd_alloc_one_kernel(mm,addr)	((pmd_t *)2); BUG()
- #define pmd_free(pmd)			do { } while (0)
- #define pgd_populate(mm,pmd,pte)	BUG()
- 
---- linux-2.6.0-test1/include/asm-arm26/pgtable.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-arm26/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -99,7 +99,7 @@ extern struct page *empty_zero_page;
-  * on arm26 we have no 2nd level page table. we simulate this by removing the
-  * PMD.
-  *
-- * pgd_none is 0 to prevernt pmd_alloc() calling __pmd_alloc(). This causes it
-+ * pgd_none is 0 to prevernt pmd_alloc_map() calling __pmd_alloc(). This causes it
-  * to return pmd_offset(pgd,addr) which is a pointer to the pgd (IOW, a no-op).
-  *
-  * however, to work this way, whilst we are allocating 32 pgds, containing 32
-@@ -134,7 +134,7 @@ extern struct page *empty_zero_page;
- 
- #define _PMD_PRESENT     (0x01)
- 
--/* These definitions allow us to optimise out stuff like pmd_alloc() */
-+/* These definitions allow us to optimise out stuff like pmd_alloc_map() */
- #define pgd_none(pgd)		(0) 
- #define pgd_bad(pgd)		(0)
- #define pgd_present(pgd)	(1)
-@@ -189,6 +189,12 @@ extern struct page *empty_zero_page;
- #define pte_unmap(pte)                  do { } while (0)
- #define pte_unmap_nested(pte)           do { } while (0)
- 
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pgd, addr)			do { } while (0)
-+#define pmd_unmap_nested(pgd, addr)		do { } while (0)
-+
- 
- #define _PAGE_PRESENT   0x01
- #define _PAGE_READONLY  0x02
---- linux-2.6.0-test1/include/asm-arm26/posix_types.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/include/asm-arm26/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -19,7 +19,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short		__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long		__kernel_ino_t;
- typedef unsigned short		__kernel_mode_t;
- typedef unsigned short		__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-arm/pgalloc.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/asm-arm/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -16,7 +16,8 @@
- /*
-  * Since we have only two-level page tables, these are trivial
-  */
--#define pmd_alloc_one(mm,addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm,addr)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm,addr)	({ BUG(); ((pmd_t *)2); })
- #define pmd_free(pmd)			do { } while (0)
- #define pgd_populate(mm,pmd,pte)	BUG()
- 
---- linux-2.6.0-test1/include/asm-arm/pgtable.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/include/asm-arm/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -125,6 +125,11 @@ extern struct page *empty_zero_page;
- 
- /* Find an entry in the second-level page table.. */
- #define pmd_offset(dir, addr)	((pmd_t *)(dir))
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
- 
- /* Find an entry in the third-level page table.. */
- #define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
---- linux-2.6.0-test1/include/asm-arm/posix_types.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/asm-arm/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -19,7 +19,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short		__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long		__kernel_ino_t;
- typedef unsigned short		__kernel_mode_t;
- typedef unsigned short		__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-cris/pgalloc.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-cris/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -57,7 +57,8 @@ extern inline void pte_free(struct page 
-  * the pgd will always be present..
-  */
- 
--#define pmd_alloc_one(mm, addr)    ({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)         ({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)  ({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)                do { } while (0)
- #define __pmd_free_tlb(tlb,x)      do { } while (0)
- #define pgd_populate(mm, pmd, pte) BUG()
---- linux-2.6.0-test1/include/asm-cris/pgtable.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-cris/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -339,4 +339,10 @@ extern inline void update_mmu_cache(stru
- 
- typedef pte_t *pte_addr_t;
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- #endif /* _CRIS_PGTABLE_H */
---- linux-2.6.0-test1/include/asm-cris/posix_types.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-cris/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -14,7 +14,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned short	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-generic/cpumask_array.h	2003-07-19 17:04:07.000000000 -0700
-@@ -0,0 +1,41 @@
-+#ifndef __ASM_GENERIC_CPUMASK_ARRAY_H
-+#define __ASM_GENERIC_CPUMASK_ARRAY_H
-+
-+#define CPU_ARRAY_SIZE		BITS_TO_LONGS(NR_CPUS)
-+
-+#define cpu_set(cpu, map)		set_bit(cpu, (map).mask)
-+#define cpu_clear(cpu, map)		clear_bit(cpu, (map).mask)
-+#define cpu_isset(cpu, map)		test_bit(cpu, (map).mask)
-+#define cpu_test_and_set(cpu, map)	test_and_set_bit(cpu, (map).mask)
-+
-+#define cpus_and(dst,src1,src2)	bitmap_and((dst).mask,(src1).mask, (src2).mask, NR_CPUS)
-+#define cpus_or(dst,src1,src2)	bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS)
-+#define cpus_clear(map)		bitmap_clear((map).mask, NR_CPUS)
-+#define cpus_complement(map)	bitmap_complement((map).mask, NR_CPUS)
-+#define cpus_equal(map1, map2)	bitmap_equal((map1).mask, (map2).mask, NR_CPUS)
-+#define cpus_empty(map)		bitmap_empty(map.mask, NR_CPUS)
-+#define cpus_weight(map)		bitmap_weight((map).mask, NR_CPUS)
-+#define cpus_shift_right(d, s, n)	bitmap_shift_right((d).mask, (s).mask, n, NR_CPUS)
-+#define cpus_shift_left(d, s, n)	bitmap_shift_left((d).mask, (s).mask, n, NR_CPUS)
-+#define first_cpu(map)		find_first_bit((map).mask, NR_CPUS)
-+#define next_cpu(cpu, map)	find_next_bit((map).mask, NR_CPUS, cpu)
-+
-+/* only ever use this for things that are _never_ used on large boxen */
-+#define cpus_coerce(map)	((map).mask[0])
-+#define cpus_promote(map)	({ cpumask_t __cpu_mask = CPU_MASK_NONE;\
-+					__cpu_mask.mask[0] = map;	\
-+					__cpu_mask;			\
-+				})
-+#define cpumask_of_cpu(cpu)	({ cpumask_t __cpu_mask = CPU_MASK_NONE;\
-+					cpu_set(cpu, __cpu_mask);	\
-+					__cpu_mask;			\
-+				})
-+#define any_online_cpu(map)	find_first_bit((map).mask, NR_CPUS)
-+
-+/*
-+ * um, these need to be usable as static initializers
-+ */
-+#define CPU_MASK_ALL	{ {[0 ... CPU_ARRAY_SIZE-1] = ~0UL} }
-+#define CPU_MASK_NONE	{ {[0 ... CPU_ARRAY_SIZE-1] =  0UL} }
-+
-+#endif /* __ASM_GENERIC_CPUMASK_ARRAY_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-generic/cpumask_const_reference.h	2003-07-19 17:04:07.000000000 -0700
-@@ -0,0 +1,29 @@
-+#ifndef __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H
-+#define __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H
-+
-+struct cpumask_ref {
-+	const cpumask_t *val;
-+};
-+
-+typedef const struct cpumask_ref cpumask_const_t;
-+
-+#define mk_cpumask_const(map)		((cpumask_const_t){ &(map) })
-+#define cpu_isset_const(cpu, map)	cpu_isset(cpu, *(map).val)
-+
-+#define cpus_and_const(dst,src1,src2)	cpus_and(dst,*(src1).val,*(src2).val)
-+#define cpus_or_const(dst,src1,src2)	cpus_or(dst,*(src1).val,*(src2).val)
-+
-+#define cpus_equal_const(map1, map2)	cpus_equal(*(map1).val, *(map2).val)
-+
-+#define cpus_copy_const(map1, map2)	bitmap_copy((map1).mask, (map2).val->mask, NR_CPUS)
-+
-+#define cpus_empty_const(map)		cpus_empty(*(map).val)
-+#define cpus_weight_const(map)		cpus_weight(*(map).val)
-+#define first_cpu_const(map)		first_cpu(*(map).val)
-+#define next_cpu_const(cpu, map)	next_cpu(cpu, *(map).val)
-+
-+/* only ever use this for things that are _never_ used on large boxen */
-+#define cpus_coerce_const(map)		cpus_coerce(*(map).val)
-+#define any_online_cpu_const(map)	any_online_cpu(*(map).val)
-+
-+#endif /* __ASM_GENERIC_CPUMASK_CONST_REFERENCE_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-generic/cpumask_const_value.h	2003-07-19 17:04:07.000000000 -0700
-@@ -0,0 +1,21 @@
-+#ifndef __ASM_GENERIC_CPUMASK_CONST_VALUE_H
-+#define __ASM_GENERIC_CPUMASK_CONST_VALUE_H
-+
-+typedef const cpumask_t cpumask_const_t;
-+
-+#define mk_cpumask_const(map)		((cpumask_const_t)(map))
-+#define cpu_isset_const(cpu, map)	cpu_isset(cpu, map)
-+#define cpus_and_const(dst,src1,src2)	cpus_and(dst, src1, src2)
-+#define cpus_or_const(dst,src1,src2)	cpus_or(dst, src1, src2)
-+#define cpus_equal_const(map1, map2)	cpus_equal(map1, map2)
-+#define cpus_empty_const(map)		cpus_empty(map)
-+#define cpus_copy_const(map1, map2)	do { map1 = (cpumask_t)map2; } while (0)
-+#define cpus_weight_const(map)		cpus_weight(map)
-+#define first_cpu_const(map)		first_cpu(map)
-+#define next_cpu_const(cpu, map)	next_cpu(cpu, map)
-+
-+/* only ever use this for things that are _never_ used on large boxen */
-+#define cpus_coerce_const(map)		cpus_coerce(map)
-+#define any_online_cpu_const(map)	any_online_cpu(map)
-+
-+#endif /* __ASM_GENERIC_CPUMASK_CONST_VALUE_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-generic/cpumask_up.h	2003-07-19 17:04:07.000000000 -0700
-@@ -0,0 +1,60 @@
-+#ifndef __ASM_GENERIC_CPUMASK_UP_H
-+#define __ASM_GENERIC_CPUMASK_UP_H
-+
-+#define CPU_ARRAY_SIZE		BITS_TO_LONGS(NR_CPUS)
-+
-+#define cpus_coerce(map)	((map).mask[0])
-+
-+#define cpu_set(cpu, map)		do { cpus_coerce(map) = 1UL; } while (0)
-+#define cpu_clear(cpu, map)		do { cpus_coerce(map) = 0UL; } while (0)
-+#define cpu_isset(cpu, map)		(cpus_coerce(map) != 0UL)
-+#define cpu_test_and_set(cpu, map)	test_and_set_bit(0, (map).mask)
-+
-+#define cpus_and(dst, src1, src2)					\
-+	do {								\
-+		if (cpus_coerce(src1) && cpus_coerce(src2))		\
-+			cpus_coerce(dst) = 1UL;				\
-+		else							\
-+			cpus_coerce(dst) = 0UL;				\
-+	} while (0)
-+
-+#define cpus_or(dst, src1, src2)					\
-+	do {								\
-+		if (cpus_coerce(src1) || cpus_coerce(src2))		\
-+			cpus_coerce(dst) = 1UL;				\
-+		else							\
-+			cpus_coerce(dst) = 0UL;				\
-+	} while (0)
-+
-+#define cpus_clear(map)			do { cpus_coerce(map) = 0UL; } while (0)
-+
-+#define cpus_complement(map)						\
-+	do {								\
-+		cpus_coerce(map) = !cpus_coerce(map);			\
-+	} while (0)
-+
-+#define cpus_equal(map1, map2)		(cpus_coerce(map1) == cpus_coerce(map2))
-+#define cpus_empty(map)			(cpus_coerce(map) == 0UL)
-+#define cpus_weight(map)		(cpus_coerce(map) ? 1UL : 0UL)
-+#define cpus_shift_right(d, s, n)	do { cpus_coerce(d) = 0UL; } while (0)
-+#define cpus_shift_left(d, s, n)	do { cpus_coerce(d) = 0UL; } while (0)
-+#define first_cpu(map)			(cpus_coerce(map) ? 0 : 1)
-+#define next_cpu(cpu, map)		1
-+
-+/* only ever use this for things that are _never_ used on large boxen */
-+#define cpus_promote(map)						\
-+	({								\
-+		cpumask_t __tmp__;					\
-+		cpus_coerce(__tmp__) = map;				\
-+		__tmp__;						\
-+	})
-+#define cpumask_of_cpu(cpu)		cpus_promote(1)
-+#define any_online_cpu(map)		(cpus_coerce(map) ? 0 : 1)
-+
-+/*
-+ * um, these need to be usable as static initializers
-+ */
-+#define CPU_MASK_ALL	{ {[0 ... CPU_ARRAY_SIZE-1] =  1UL} }
-+#define CPU_MASK_NONE	{ {[0 ... CPU_ARRAY_SIZE-1] =  0UL} }
-+
-+#endif /* __ASM_GENERIC_CPUMASK_UP_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-generic/local.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,118 @@
-+#ifndef _ASM_GENERIC_LOCAL_H
-+#define _ASM_GENERIC_LOCAL_H
-+
-+#include <linux/config.h>
-+#include <linux/percpu.h>
-+#include <asm/types.h>
-+#include <asm/hardirq.h>
-+
-+/* An unsigned long type for operations which are atomic for a single
-+ * CPU.  Usually used in combination with per-cpu variables. */
-+
-+#if BITS_PER_LONG == 32 && !defined(CONFIG_SPARC32)
-+/* Implement in terms of atomics. */
-+
-+/* Don't use typedef: don't want them to be mixed with atomic_t's. */
-+typedef struct
-+{
-+	atomic_t a;
-+} local_t;
-+
-+#define LOCAL_INIT(i)	{ ATOMIC_INIT(i) }
-+
-+#define local_read(l)	((unsigned long)atomic_read(&(l)->a))
-+#define local_set(l,i)	atomic_set((&(l)->a),(i))
-+#define local_inc(l)	atomic_inc(&(l)->a)
-+#define local_dec(l)	atomic_dec(&(l)->a)
-+#define local_add(i,l)	atomic_add((i),(&(l)->a))
-+#define local_sub(i,l)	atomic_sub((i),(&(l)->a))
-+
-+/* Non-atomic variants, ie. preemption disabled and won't be touched
-+ * in interrupt, etc.  Some archs can optimize this case well. */
-+#define __local_inc(l)		local_set((l), local_read(l) + 1)
-+#define __local_dec(l)		local_set((l), local_read(l) - 1)
-+#define __local_add(i,l)	local_set((l), local_read(l) + (i))
-+#define __local_sub(i,l)	local_set((l), local_read(l) - (i))
-+
-+#else /* ... can't use atomics. */
-+/* Implement in terms of three variables.
-+   Another option would be to use local_irq_save/restore. */
-+
-+typedef struct
-+{
-+	/* 0 = in hardirq, 1 = in softirq, 2 = usermode. */
-+	unsigned long v[3];
-+} local_t;
-+
-+#define _LOCAL_VAR(l)	((l)->v[!in_interrupt() + !in_irq()])
-+
-+#define LOCAL_INIT(i)	{ { (i), 0, 0 } }
-+
-+static inline unsigned long local_read(local_t *l)
-+{
-+	return l->v[0] + l->v[1] + l->v[2];
-+}
-+
-+static inline void local_set(local_t *l, unsigned long v)
-+{
-+	l->v[0] = v;
-+	l->v[1] = l->v[2] = 0;
-+}
-+
-+static inline void local_inc(local_t *l)
-+{
-+	preempt_disable();
-+	_LOCAL_VAR(l)++;
-+	preempt_enable();
-+}
-+
-+static inline void local_dec(local_t *l)
-+{
-+	preempt_disable();
-+	_LOCAL_VAR(l)--;
-+	preempt_enable();
-+}
-+
-+static inline void local_add(unsigned long v, local_t *l)
-+{
-+	preempt_disable();
-+	_LOCAL_VAR(l) += v;
-+	preempt_enable();
-+}
-+
-+static inline void local_sub(unsigned long v, local_t *l)
-+{
-+	preempt_disable();
-+	_LOCAL_VAR(l) -= v;
-+	preempt_enable();
-+}
-+
-+/* Non-atomic variants, ie. preemption disabled and won't be touched
-+ * in interrupt, etc.  Some archs can optimize this case well. */
-+#define __local_inc(l)		((l)->v[0]++)
-+#define __local_dec(l)		((l)->v[0]--)
-+#define __local_add(i,l)	((l)->v[0] += (i))
-+#define __local_sub(i,l)	((l)->v[0] -= (i))
-+
-+#endif /* Non-atomic implementation */
-+
-+/* Use these for per-cpu local_t variables: on some archs they are
-+ * much more efficient than these naive implementations.  Note they take
-+ * a variable (eg. mystruct.foo), not an address.
-+ */
-+#define cpu_local_read(v)	local_read(&__get_cpu_var(v))
-+#define cpu_local_set(v, i)	local_set(&__get_cpu_var(v), (i))
-+#define cpu_local_inc(v)	local_inc(&__get_cpu_var(v))
-+#define cpu_local_dec(v)	local_dec(&__get_cpu_var(v))
-+#define cpu_local_add(i, v)	local_add((i), &__get_cpu_var(v))
-+#define cpu_local_sub(i, v)	local_sub((i), &__get_cpu_var(v))
-+
-+/* Non-atomic increments, ie. preemption disabled and won't be touched
-+ * in interrupt, etc.  Some archs can optimize this case well.
-+ */
-+#define __cpu_local_inc(v)	__local_inc(&__get_cpu_var(v))
-+#define __cpu_local_dec(v)	__local_dec(&__get_cpu_var(v))
-+#define __cpu_local_add(i, v)	__local_add((i), &__get_cpu_var(v))
-+#define __cpu_local_sub(i, v)	__local_sub((i), &__get_cpu_var(v))
-+
-+#endif /* _ASM_GENERIC_LOCAL_H */
---- linux-2.6.0-test1/include/asm-generic/percpu.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/include/asm-generic/percpu.h	2003-07-19 17:03:50.000000000 -0700
-@@ -9,33 +9,34 @@ extern unsigned long __per_cpu_offset[NR
- 
- /* Separate out the type, so (int[3], foo) works. */
- #define DEFINE_PER_CPU(type, name) \
--    __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
-+    __attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
- 
- /* var is in discarded region: offset to particular copy we want */
--#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))
-+#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
- #define __get_cpu_var(var) per_cpu(var, smp_processor_id())
- 
--static inline void percpu_modcopy(void *pcpudst, const void *src,
--				  unsigned long size)
--{
--	unsigned int i;
--	for (i = 0; i < NR_CPUS; i++)
--		if (cpu_possible(i))
--			memcpy(pcpudst + __per_cpu_offset[i], src, size);
--}
-+/* A macro to avoid #include hell... */
-+#define percpu_modcopy(pcpudst, src, size)			\
-+do {								\
-+	unsigned int __i;					\
-+	for (__i = 0; __i < NR_CPUS; __i++)			\
-+		if (cpu_possible(__i))				\
-+			memcpy((pcpudst)+__per_cpu_offset[__i],	\
-+			       (src), (size));			\
-+} while (0)
- #else /* ! SMP */
- 
- #define DEFINE_PER_CPU(type, name) \
--    __typeof__(type) name##__per_cpu
-+    __typeof__(type) per_cpu__##name
- 
--#define per_cpu(var, cpu)			((void)cpu, var##__per_cpu)
--#define __get_cpu_var(var)			var##__per_cpu
-+#define per_cpu(var, cpu)			((void)cpu, per_cpu__##var)
-+#define __get_cpu_var(var)			per_cpu__##var
- 
- #endif	/* SMP */
- 
--#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
-+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
- 
--#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
--#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
-+#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
-+#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
- 
- #endif /* _ASM_GENERIC_PERCPU_H_ */
---- linux-2.6.0-test1/include/asm-generic/sections.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-generic/sections.h	2003-07-19 17:03:50.000000000 -0700
-@@ -3,9 +3,10 @@
- 
- /* References to section boundaries */
- 
--extern char _text, _etext;
--extern char _data, _edata;
--extern char __bss_start;
--extern char __init_begin, __init_end;
-+extern char _text[], _stext[], _etext[];
-+extern char _data[], _sdata[], _edata[];
-+extern char __bss_start[];
-+extern char __init_begin[], __init_end[];
-+extern char _sinittext[], _einittext[];
- 
- #endif /* _ASM_GENERIC_SECTIONS_H_ */
---- linux-2.6.0-test1/include/asm-h8300/pgtable.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-h8300/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -15,6 +15,11 @@ typedef pte_t *pte_addr_t;
- #define pgd_clear(pgdp)
- #define kern_addr_valid(addr)	(1)
- #define	pmd_offset(a, b)	((void *)0)
-+#define pmd_offset_kernel(a,b)		pmd_offset(a,b)
-+#define pmd_offset_map(a,b)		pmd_offset(a,b)
-+#define pmd_offset_map_nested(a,b)	pmd_offset(a,b)
-+#define pmd_unmap(pmd)			do { } while (0)
-+#define pmd_unmap_nested(pmd)		do { } while (0)
- 
- #define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */
- #define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */
---- linux-2.6.0-test1/include/asm-h8300/posix_types.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-h8300/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned short	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-i386/atomic.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/include/asm-i386/atomic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -193,7 +193,7 @@ __asm__ __volatile__(LOCK "andl %0,%1" \
- 
- #define atomic_set_mask(mask, addr) \
- __asm__ __volatile__(LOCK "orl %0,%1" \
--: : "r" (mask),"m" (*addr) : "memory")
-+: : "r" (mask),"m" (*(addr)) : "memory")
- 
- /* Atomic operations are already serializing on x86 */
- #define smp_mb__before_atomic_dec()	barrier()
---- linux-2.6.0-test1/include/asm-i386/bitops.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/include/asm-i386/bitops.h	2003-07-19 17:04:07.000000000 -0700
-@@ -270,7 +270,7 @@ static __inline__ int variable_test_bit(
-  * Returns the bit-number of the first zero bit, not the number of the byte
-  * containing a bit.
-  */
--static __inline__ int find_first_zero_bit(unsigned long * addr, unsigned size)
-+static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned size)
- {
- 	int d0, d1, d2;
- 	int res;
-@@ -302,7 +302,7 @@ static __inline__ int find_first_zero_bi
-  * Returns the bit-number of the first set bit, not the number of the byte
-  * containing a bit.
-  */
--static __inline__ int find_first_bit(unsigned long * addr, unsigned size)
-+static __inline__ int find_first_bit(const unsigned long *addr, unsigned size)
- {
- 	int d0, d1;
- 	int res;
-@@ -328,7 +328,7 @@ static __inline__ int find_first_bit(uns
-  * @offset: The bitnumber to start searching at
-  * @size: The maximum size to search
-  */
--static __inline__ int find_next_zero_bit(unsigned long * addr, int size, int offset)
-+static __inline__ int find_next_zero_bit(const unsigned long *addr, int size, int offset)
- {
- 	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
- 	int set = 0, bit = offset & 31, res;
-@@ -361,9 +361,9 @@ static __inline__ int find_next_zero_bit
-  * @offset: The bitnumber to start searching at
-  * @size: The maximum size to search
-  */
--static __inline__ int find_next_bit(unsigned long *addr, int size, int offset)
-+static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset)
- {
--	unsigned long * p = addr + (offset >> 5);
-+	const unsigned long *p = addr + (offset >> 5);
- 	int set = 0, bit = offset & 31, res;
- 
- 	if (bit) {
-@@ -430,7 +430,7 @@ static __inline__ unsigned long __ffs(un
-  * unlikely to be set. It's guaranteed that at least one of the 140
-  * bits is cleared.
-  */
--static inline int sched_find_first_bit(unsigned long *b)
-+static inline int sched_find_first_bit(const unsigned long *b)
- {
- 	if (unlikely(b[0]))
- 		return __ffs(b[0]);
---- linux-2.6.0-test1/include/asm-i386/bugs.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/bugs.h	2003-07-19 17:04:02.000000000 -0700
-@@ -1,11 +1,11 @@
- /*
-  *  include/asm-i386/bugs.h
-  *
-- *  Copyright (C) 1994  Linus Torvalds
-+ *  Copyright (C) 1994	Linus Torvalds
-  *
-  *  Cyrix stuff, June 1998 by:
-  *	- Rafael R. Reilova (moved everything from head.S),
-- *        <rreilova@ececs.uc.edu>
-+ *	  <rreilova@ececs.uc.edu>
-  *	- Channing Corn (tests & fixes),
-  *	- Andrew D. Balsa (code cleanup).
-  *
-@@ -25,7 +25,20 @@
- #include <asm/processor.h>
- #include <asm/i387.h>
- #include <asm/msr.h>
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * Provied the command line "gdb" initial break
-+ */
-+int __init kgdb_initial_break(char * str)
-+{
-+	if (*str == '\0'){
-+		breakpoint();
-+		return 1;
-+	}
-+	return 0;
-+}
-+__setup("gdb",kgdb_initial_break);
-+#endif
- static int __init no_halt(char *s)
- {
- 	boot_cpu_data.hlt_works_ok = 0;
-@@ -140,7 +153,7 @@ static void __init check_popad(void)
- 	  : "ecx", "edi" );
- 	/* If this fails, it means that any user program may lock the CPU hard. Too bad. */
- 	if (res != 12345678) printk( "Buggy.\n" );
--		        else printk( "OK.\n" );
-+			else printk( "OK.\n" );
- #endif
- }
- 
---- linux-2.6.0-test1/include/asm-i386/genapic.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-i386/genapic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,13 +1,13 @@
- #ifndef _ASM_GENAPIC_H
- #define _ASM_GENAPIC_H 1
- 
--/* 
-+/*
-  * Generic APIC driver interface.
-- *  
-- * An straight forward mapping of the APIC related parts of the 
-+ *
-+ * An straight forward mapping of the APIC related parts of the
-  * x86 subarchitecture interface to a dynamic object.
-- *	
-- * This is used by the "generic" x86 subarchitecture. 
-+ *
-+ * This is used by the "generic" x86 subarchitecture.
-  *
-  * Copyright 2003 Andi Kleen, SuSE Labs.
-  */
-@@ -22,23 +22,23 @@ struct genapic { 
- 	int (*probe)(void); 
- 
- 	int (*apic_id_registered)(void);
--	unsigned long (*target_cpus)(void); 
-+	cpumask_t (*target_cpus)(void);
- 	int int_delivery_mode;
- 	int int_dest_mode; 
- 	int apic_broadcast_id; 
- 	int esr_disable;
--	unsigned long (*check_apicid_used)(unsigned long bitmap, int apicid); 
-+	unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
- 	unsigned long (*check_apicid_present)(int apicid); 
- 	int no_balance_irq;
- 	void (*init_apic_ldr)(void);
--	unsigned long (*ioapic_phys_id_map)(unsigned long map); 
-+	physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
- 
- 	void (*clustered_apic_check)(void);
- 	int (*multi_timer_check)(int apic, int irq);
- 	int (*apicid_to_node)(int logical_apicid); 
- 	int (*cpu_to_logical_apicid)(int cpu);
- 	int (*cpu_present_to_apicid)(int mps_cpu);
--	unsigned long (*apicid_to_cpu_present)(int phys_apicid); 
-+	physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
- 	int (*mpc_apic_id)(struct mpc_config_processor *m, 
- 			   struct mpc_config_translation *t); 
- 	void (*setup_portio_remap)(void); 
-@@ -59,11 +59,11 @@ struct genapic { 
- 	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
- 
- 	unsigned (*get_apic_id)(unsigned long x);
--	unsigned long apic_id_mask; 
--	unsigned int (*cpu_mask_to_apicid)(unsigned long cpumask);
-+	unsigned long apic_id_mask;
-+	unsigned int (*cpu_mask_to_apicid)(cpumask_const_t cpumask);
- 	
- 	/* ipi */
--	void (*send_IPI_mask)(int mask, int vector);
-+	void (*send_IPI_mask)(cpumask_t mask, int vector);
- 	void (*send_IPI_allbutself)(int vector);
- 	void (*send_IPI_all)(int vector);
- }; 
---- linux-2.6.0-test1/include/asm-i386/highmem.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/asm-i386/highmem.h	2003-07-19 17:07:16.000000000 -0700
-@@ -22,6 +22,7 @@
- 
- #include <linux/config.h>
- #include <linux/interrupt.h>
-+#include <linux/threads.h>
- #include <asm/kmap_types.h>
- #include <asm/tlbflush.h>
- 
-@@ -39,7 +40,11 @@ extern void kmap_init(void);
-  * easily, subsequent pte tables have to be allocated in one physical
-  * chunk of RAM.
-  */
--#define PKMAP_BASE (0xff800000UL)
-+#if NR_CPUS <= 32
-+#define PKMAP_BASE (0xff400000UL)
-+#else
-+#define PKMAP_BASE (0xfe800000UL)
-+#endif
- #ifdef CONFIG_X86_PAE
- #define LAST_PKMAP 512
- #else
---- linux-2.6.0-test1/include/asm-i386/hw_irq.h	2003-06-14 12:18:51.000000000 -0700
-+++ 25/include/asm-i386/hw_irq.h	2003-07-19 17:04:07.000000000 -0700
-@@ -16,6 +16,7 @@
- #include <linux/profile.h>
- #include <asm/atomic.h>
- #include <asm/irq.h>
-+#include <asm/sections.h>
- 
- /*
-  * Various low-level irq details needed by irq.c, process.c,
-@@ -30,41 +31,39 @@ extern int irq_vector[NR_IRQS];
- extern void (*interrupt[NR_IRQS])(void);
- 
- #ifdef CONFIG_SMP
--extern asmlinkage void reschedule_interrupt(void);
--extern asmlinkage void invalidate_interrupt(void);
--extern asmlinkage void call_function_interrupt(void);
-+asmlinkage void reschedule_interrupt(void);
-+asmlinkage void invalidate_interrupt(void);
-+asmlinkage void call_function_interrupt(void);
- #endif
- 
- #ifdef CONFIG_X86_LOCAL_APIC
--extern asmlinkage void apic_timer_interrupt(void);
--extern asmlinkage void error_interrupt(void);
--extern asmlinkage void spurious_interrupt(void);
--extern asmlinkage void thermal_interrupt(struct pt_regs);
-+asmlinkage void apic_timer_interrupt(void);
-+asmlinkage void error_interrupt(void);
-+asmlinkage void spurious_interrupt(void);
-+asmlinkage void thermal_interrupt(struct pt_regs);
- #endif
- 
--extern void mask_irq(unsigned int irq);
--extern void unmask_irq(unsigned int irq);
--extern void disable_8259A_irq(unsigned int irq);
--extern void enable_8259A_irq(unsigned int irq);
--extern int i8259A_irq_pending(unsigned int irq);
--extern void make_8259A_irq(unsigned int irq);
--extern void init_8259A(int aeoi);
--extern void FASTCALL(send_IPI_self(int vector));
--extern void init_VISWS_APIC_irqs(void);
--extern void setup_IO_APIC(void);
--extern void disable_IO_APIC(void);
--extern void print_IO_APIC(void);
--extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
--extern void send_IPI(int dest, int vector);
--extern void setup_ioapic_dest(unsigned long mask);
-+void mask_irq(unsigned int irq);
-+void unmask_irq(unsigned int irq);
-+void disable_8259A_irq(unsigned int irq);
-+void enable_8259A_irq(unsigned int irq);
-+int i8259A_irq_pending(unsigned int irq);
-+void make_8259A_irq(unsigned int irq);
-+void init_8259A(int aeoi);
-+void FASTCALL(send_IPI_self(int vector));
-+void init_VISWS_APIC_irqs(void);
-+void setup_IO_APIC(void);
-+void disable_IO_APIC(void);
-+void print_IO_APIC(void);
-+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
-+void send_IPI(int dest, int vector);
-+void setup_ioapic_dest(cpumask_t mask);
- 
- extern unsigned long io_apic_irqs;
- 
- extern atomic_t irq_err_count;
- extern atomic_t irq_mis_count;
- 
--extern char _stext, _etext;
--
- #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
- 
- /*
-@@ -95,7 +94,7 @@ static inline void x86_do_profile(struct
- 	if (!((1<<smp_processor_id()) & prof_cpu_mask))
- 		return;
- 
--	eip -= (unsigned long) &_stext;
-+	eip -= (unsigned long)_stext;
- 	eip >>= prof_shift;
- 	/*
- 	 * Don't ignore out-of-bounds EIP values silently,
-@@ -107,7 +106,7 @@ static inline void x86_do_profile(struct
- 	atomic_inc((atomic_t *)&prof_buffer[eip]);
- }
-  
--#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP)
-+#if defined(CONFIG_X86_IO_APIC)
- static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
- {
- 	if (IO_APIC_IRQ(i))
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-i386/kgdb.h	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,59 @@
-+#ifndef __KGDB
-+#define __KGDB
-+
-+/*
-+ * This file should not include ANY others.  This makes it usable
-+ * most anywhere without the fear of include order or inclusion.
-+ * Make it so!
-+ *
-+ * This file may be included all the time.  It is only active if 
-+ * CONFIG_KGDB is defined, otherwise it stubs out all the macros
-+ * and entry points.
-+ */
-+#if defined(CONFIG_KGDB) && !defined(__ASSEMBLY__)
-+
-+extern void breakpoint(void);
-+#define INIT_KGDB_INTS kgdb_enable_ints()
-+
-+#ifndef BREAKPOINT
-+#define BREAKPOINT   asm("   int $3")
-+#endif
-+/*
-+ * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
-+ * pointer to its routine and it will be entered as the first thing
-+ * when a trap occurs.
-+ *
-+ * Return values are, at present, undefined.
-+ *
-+ * The debug hook routine does not necessarily return to its caller.
-+ * It has the register image and thus may choose to resume execution
-+ * anywhere it pleases. 
-+ */
-+struct pt_regs;
-+
-+extern int kgdb_handle_exception(int trapno,
-+				 int signo, int err_code, struct pt_regs *regs);
-+extern int in_kgdb(struct pt_regs *regs);
-+
-+#ifdef CONFIG_KGDB_TS
-+void kgdb_tstamp(int line, char *source, int data0, int data1);
-+/*
-+ * This is the time stamp function.  The macro adds the source info and
-+ * does a cast on the data to allow most any 32-bit value.
-+ */
-+
-+#define kgdb_ts(data0,data1) kgdb_tstamp(__LINE__,__FILE__,(int)data0,(int)data1)
-+#else
-+#define kgdb_ts(data0,data1)
-+#endif
-+#else				/* CONFIG_KGDB  && ! __ASSEMBLY__ ,stubs follow... */
-+#ifndef BREAKPOINT
-+#define BREAKPOINT
-+#endif
-+#define kgdb_ts(data0,data1)
-+#define in_kgdb
-+#define kgdb_handle_exception
-+#define breakpoint
-+#define INIT_KGDB_INTS
-+#endif
-+#endif				/* __KGDB */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-i386/kgdb_local.h	2003-07-19 17:04:02.000000000 -0700
-@@ -0,0 +1,102 @@
-+#ifndef __KGDB_LOCAL
-+#define ___KGDB_LOCAL
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/serial.h>
-+#include <linux/serialP.h>
-+#include <linux/spinlock.h>
-+#include <asm/processor.h>
-+#include <asm/msr.h>
-+#include <asm/kgdb.h>
-+
-+#define PORT 0x3f8
-+#ifdef CONFIG_KGDB_PORT
-+#undef PORT
-+#define PORT CONFIG_KGDB_PORT
-+#endif
-+#define IRQ 4
-+#ifdef CONFIG_KGDB_IRQ
-+#undef IRQ
-+#define IRQ CONFIG_KGDB_IRQ
-+#endif
-+#define SB_CLOCK 1843200
-+#define SB_BASE (SB_CLOCK/16)
-+#define SB_BAUD9600 SB_BASE/9600
-+#define SB_BAUD192  SB_BASE/19200
-+#define SB_BAUD384  SB_BASE/38400
-+#define SB_BAUD576  SB_BASE/57600
-+#define SB_BAUD1152 SB_BASE/115200
-+#ifdef CONFIG_KGDB_9600BAUD
-+#define SB_BAUD SB_BAUD9600
-+#endif
-+#ifdef CONFIG_KGDB_19200BAUD
-+#define SB_BAUD SB_BAUD192
-+#endif
-+#ifdef CONFIG_KGDB_38400BAUD
-+#define SB_BAUD SB_BAUD384
-+#endif
-+#ifdef CONFIG_KGDB_57600BAUD
-+#define SB_BAUD SB_BAUD576
-+#endif
-+#ifdef CONFIG_KGDB_115200BAUD
-+#define SB_BAUD SB_BAUD1152
-+#endif
-+#ifndef SB_BAUD
-+#define SB_BAUD SB_BAUD1152	/* Start with this if not given */
-+#endif
-+
-+#ifndef CONFIG_X86_TSC
-+#undef rdtsc
-+#define rdtsc(a,b) if (a++ > 10000){a = 0; b++;}
-+#undef rdtscll
-+#define rdtscll(s) s++
-+#endif
-+
-+#ifdef _raw_read_unlock		/* must use a name that is "define"ed, not an inline */
-+#undef spin_lock
-+#undef spin_trylock
-+#undef spin_unlock
-+#define spin_lock	 _raw_spin_lock
-+#define spin_trylock	 _raw_spin_trylock
-+#define spin_unlock	 _raw_spin_unlock
-+#else
-+#endif
-+#undef spin_unlock_wait
-+#define spin_unlock_wait(x)  do { cpu_relax(); barrier();} \
-+                                     while(spin_is_locked(x))
-+
-+#define SB_IER 1
-+#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
-+
-+#define FLAGS 0
-+#define SB_STATE { \
-+     magic: SSTATE_MAGIC, \
-+     baud_base: SB_BASE,  \
-+     port:      PORT,     \
-+     irq:       IRQ,      \
-+     flags:     FLAGS,    \
-+     custom_divisor:SB_BAUD}
-+#define SB_INFO  { \
-+      magic: SERIAL_MAGIC, \
-+      port:  PORT,0,FLAGS, \
-+      state: &state,       \
-+      tty:   (struct tty_struct *)&state, \
-+      IER:   SB_IER,       \
-+      MCR:   SB_MCR}
-+extern void putDebugChar(int);
-+/* RTAI support needs us to really stop/start interrupts */
-+
-+#define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
-+#define kgdb_cli() __asm__ __volatile__("cli": : :"memory")
-+#define kgdb_local_save_flags(x) __asm__ __volatile__(\
-+                                   "pushfl ; popl %0":"=g" (x): /* no input */)
-+#define kgdb_local_irq_restore(x) __asm__ __volatile__(\
-+                                   "pushl %0 ; popfl": \
-+                                     /* no output */ :"g" (x):"memory", "cc")
-+#define kgdb_local_irq_save(x) kgdb_local_save_flags(x); kgdb_cli()
-+
-+#ifdef CONFIG_SERIAL
-+extern void shutdown_for_kgdb(struct async_struct *info);
-+#endif
-+#define INIT_KDEBUG putDebugChar("+");
-+#endif				/* __KGDB_LOCAL */
---- linux-2.6.0-test1/include/asm-i386/kmap_types.h	2003-06-14 12:18:28.000000000 -0700
-+++ 25/include/asm-i386/kmap_types.h	2003-07-19 17:07:16.000000000 -0700
-@@ -17,14 +17,16 @@ D(3)	KM_USER0,
- D(4)	KM_USER1,
- D(5)	KM_BIO_SRC_IRQ,
- D(6)	KM_BIO_DST_IRQ,
--D(7)	KM_PTE0,
--D(8)	KM_PTE1,
--D(9)	KM_PTE2,
--D(10)	KM_IRQ0,
--D(11)	KM_IRQ1,
--D(12)	KM_SOFTIRQ0,
--D(13)	KM_SOFTIRQ1,
--D(14)	KM_TYPE_NR
-+D(7)	KM_PMD0,
-+D(8)	KM_PMD1,
-+D(9)	KM_PTE0,
-+D(10)	KM_PTE1,
-+D(11)	KM_PTE2,
-+D(12)	KM_IRQ0,
-+D(13)	KM_IRQ1,
-+D(14)	KM_SOFTIRQ0,
-+D(15)	KM_SOFTIRQ1,
-+D(16)	KM_TYPE_NR
- };
- 
- #undef D
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-i386/local.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,70 @@
-+#ifndef _ARCH_I386_LOCAL_H
-+#define _ARCH_I386_LOCAL_H
-+
-+#include <linux/percpu.h>
-+
-+typedef struct
-+{
-+	volatile unsigned long counter;
-+} local_t;
-+
-+#define LOCAL_INIT(i)	{ (i) }
-+
-+#define local_read(v)	((v)->counter)
-+#define local_set(v,i)	(((v)->counter) = (i))
-+
-+static __inline__ void local_inc(local_t *v)
-+{
-+	__asm__ __volatile__(
-+		"incl %0"
-+		:"=m" (v->counter)
-+		:"m" (v->counter));
-+}
-+
-+static __inline__ void local_dec(local_t *v)
-+{
-+	__asm__ __volatile__(
-+		"decl %0"
-+		:"=m" (v->counter)
-+		:"m" (v->counter));
-+}
-+
-+static __inline__ void local_add(unsigned long i, local_t *v)
-+{
-+	__asm__ __volatile__(
-+		"addl %1,%0"
-+		:"=m" (v->counter)
-+		:"ir" (i), "m" (v->counter));
-+}
-+
-+static __inline__ void local_sub(unsigned long i, local_t *v)
-+{
-+	__asm__ __volatile__(
-+		"subl %1,%0"
-+		:"=m" (v->counter)
-+		:"ir" (i), "m" (v->counter));
-+}
-+
-+/* On x86, these are no better than the atomic variants. */
-+#define __local_inc(l)		local_inc(l)
-+#define __local_dec(l)		local_dec(l)
-+#define __local_add(i,l)	local_add((i),(l))
-+#define __local_sub(i,l)	local_sub((i),(l))
-+
-+/* Use these for per-cpu local_t variables: on some archs they are
-+ * much more efficient than these naive implementations.  Note they take
-+ * a variable, not an address.
-+ */
-+#define cpu_local_read(v)	local_read(&__get_cpu_var(v))
-+#define cpu_local_set(v, i)	local_set(&__get_cpu_var(v), (i))
-+#define cpu_local_inc(v)	local_inc(&__get_cpu_var(v))
-+#define cpu_local_dec(v)	local_dec(&__get_cpu_var(v))
-+#define cpu_local_add(i, v)	local_add((i), &__get_cpu_var(v))
-+#define cpu_local_sub(i, v)	local_sub((i), &__get_cpu_var(v))
-+
-+#define __cpu_local_inc(v)	cpu_local_inc(v)
-+#define __cpu_local_dec(v)	cpu_local_dec(v)
-+#define __cpu_local_add(i, v)	cpu_local_add((i), (v))
-+#define __cpu_local_sub(i, v)	cpu_local_sub((i), (v))
-+
-+#endif /* _ARCH_I386_LOCAL_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-i386/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,127 @@
-+/*
-+ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ *
-+ *  Modified by Ray Bryant (raybry@us.ibm.com)
-+ *  Changes Copyright (C) 2000 IBM, Inc.
-+ *  Added save of index in spinlock_t to improve efficiency
-+ *  of "hold" time reporting for spinlocks.
-+ *  Added support for hold time statistics for read and write
-+ *  locks.
-+ *  Moved machine dependent code here from include/lockmeter.h.
-+ *
-+ */
-+
-+#ifndef _I386_LOCKMETER_H
-+#define _I386_LOCKMETER_H
-+
-+#include <asm/spinlock.h>
-+#include <asm/rwlock.h>
-+
-+#include <linux/version.h>
-+
-+#ifdef __KERNEL__
-+extern unsigned long cpu_khz;
-+#define CPU_CYCLE_FREQUENCY	(cpu_khz * 1000)
-+#else
-+#define CPU_CYCLE_FREQUENCY	450000000
-+#endif
-+
-+#define THIS_CPU_NUMBER		smp_processor_id()
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-+#define local_irq_save(x) \
-+    __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
-+
-+#define local_irq_restore(x) \
-+    __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
-+#endif	/* Linux version 2.2.x */
-+
-+/*
-+ * macros to cache and retrieve an index value inside of a spin lock
-+ * these macros assume that there are less than 65536 simultaneous
-+ * (read mode) holders of a rwlock.  Not normally a problem!!
-+ * we also assume that the hash table has less than 65535 entries.
-+ */
-+/*
-+ * instrumented spinlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a spinlock_t
-+ */
-+typedef struct inst_spinlock_s {
-+	/* remember, Intel is little endian */
-+	unsigned short lock;
-+	unsigned short index;
-+} inst_spinlock_t;
-+#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
-+#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
-+
-+/*
-+ * macros to cache and retrieve an index value in a read/write lock
-+ * as well as the cpu where a reader busy period started
-+ * we use the 2nd word (the debug word) for this, so require the
-+ * debug word to be present
-+ */
-+/*
-+ * instrumented rwlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a rwlock_t
-+ */
-+typedef struct inst_rwlock_s {
-+	volatile int lock;
-+	unsigned short index;
-+	unsigned short cpu;
-+} inst_rwlock_t;
-+#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
-+#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
-+#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
-+
-+/*
-+ * return the number of readers for a rwlock_t
-+ */
-+#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
-+
-+extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
-+{
-+	int tmp = (int) rwlock_ptr->lock;
-+	/* read and write lock attempts may cause the lock value to temporarily */
-+	/* be negative.  Until it is >= 0 we know nothing (i. e. can't tell if  */
-+	/* is -1 because it was write locked and somebody tried to read lock it */
-+	/* or if it is -1 because it was read locked and somebody tried to write*/
-+	/* lock it. ........................................................... */
-+	do {
-+		tmp = (int) rwlock_ptr->lock;
-+	} while (tmp < 0);
-+	if (tmp == 0) return(0);
-+	else return(RW_LOCK_BIAS-tmp);
-+}
-+
-+/*
-+ * return true if rwlock is write locked
-+ * (note that other lock attempts can cause the lock value to be negative)
-+ */
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock <= 0)
-+#define IABS(x) ((x) > 0 ? (x) : -(x))
-+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((IABS((rwlock_ptr)->lock) % RW_LOCK_BIAS) != 0)
-+
-+/* this is a lot of typing just to get gcc to emit "rdtsc" */
-+static inline long long get_cycles64 (void)
-+{
-+#ifndef CONFIG_X86_TSC
-+	#error this code requires CONFIG_X86_TSC
-+#else
-+	union longlong_u {
-+		long long intlong;
-+		struct intint_s {
-+			uint32_t eax;
-+			uint32_t edx;
-+		} intint;
-+	} longlong;
-+
-+	rdtsc(longlong.intint.eax,longlong.intint.edx);
-+	return longlong.intlong;
-+#endif
-+}
-+
-+#endif /* _I386_LOCKMETER_H */
---- linux-2.6.0-test1/include/asm-i386/mach-bigsmp/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-bigsmp/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -20,7 +20,7 @@ static inline int apic_id_registered(voi
- }
- 
- #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
--static inline unsigned long target_cpus(void)
-+static inline cpumask_t target_cpus(void)
- { 
- 	return cpu_online_map;
- }
-@@ -29,14 +29,15 @@ static inline unsigned long target_cpus(
- #define INT_DELIVERY_MODE dest_LowestPrio
- #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
- 
--#define APIC_BROADCAST_ID     (0x0f)
--static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) 
--{ 
-+#define APIC_BROADCAST_ID     (0xff)
-+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-+{
- 	return 0;
--} 
-+}
-+
- static inline unsigned long check_apicid_present(int bit) 
- {
--	return (phys_cpu_present_map & (1 << bit));
-+	return physid_isset(bit, phys_cpu_present_map);
- }
- 
- #define apicid_cluster(apicid) (apicid & 0xF0)
-@@ -88,9 +89,9 @@ static inline int cpu_present_to_apicid(
- 	return (int) bios_cpu_apicid[mps_cpu];
- }
- 
--static inline unsigned long apicid_to_cpu_present(int phys_apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
- {
--	return (1ul << phys_apicid);
-+	return physid_mask_of_physid(phys_apicid);
- }
- 
- extern volatile u8 cpu_2_logical_apicid[];
-@@ -108,13 +109,13 @@ static inline int mpc_apic_id(struct mpc
- 	        (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
- 	        (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
- 	        m->mpc_apicver);
--	return (m->mpc_apicid);
-+	return m->mpc_apicid;
- }
- 
--static inline ulong ioapic_phys_id_map(ulong phys_map)
-+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
- {
- 	/* For clustered we don't have a good way to do this yet - hack */
--	return (0x0F);
-+	return physids_promote(0xFUL);
- }
- 
- #define WAKE_SECONDARY_VIA_INIT
-@@ -132,25 +133,25 @@ static inline int check_phys_apicid_pres
- 	return (1);
- }
- 
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
- 	int num_bits_set;
- 	int cpus_found = 0;
- 	int cpu;
- 	int apicid;	
- 
--	num_bits_set = hweight32(cpumask); 
-+	num_bits_set = cpus_weight_const(cpumask);
- 	/* Return id to all */
--	if (num_bits_set == 32)
-+	if (num_bits_set == NR_CPUS)
- 		return (int) 0xFF;
- 	/* 
- 	 * The cpus in the mask must all be on the apic cluster.  If are not 
- 	 * on the same apicid cluster return default value of TARGET_CPUS. 
- 	 */
--	cpu = ffs(cpumask)-1;
-+	cpu = first_cpu_const(cpumask);
- 	apicid = cpu_to_logical_apicid(cpu);
- 	while (cpus_found < num_bits_set) {
--		if (cpumask & (1 << cpu)) {
-+		if (cpu_isset_const(cpu, cpumask)) {
- 			int new_apicid = cpu_to_logical_apicid(cpu);
- 			if (apicid_cluster(apicid) != 
- 					apicid_cluster(new_apicid)){
---- linux-2.6.0-test1/include/asm-i386/mach-bigsmp/mach_ipi.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-i386/mach-bigsmp/mach_ipi.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,18 +1,19 @@
- #ifndef __ASM_MACH_IPI_H
- #define __ASM_MACH_IPI_H
- 
--inline void send_IPI_mask_sequence(int mask, int vector);
-+inline void send_IPI_mask_sequence(cpumask_t mask, int vector);
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t mask, int vector)
- {
- 	send_IPI_mask_sequence(mask, vector);
- }
- 
- static inline void send_IPI_allbutself(int vector)
- {
--	unsigned long mask = cpu_online_map & ~(1 << smp_processor_id());
-+	cpumask_t mask = cpu_online_map;
-+	cpu_clear(smp_processor_id(), mask);
- 
--	if (mask)
-+	if (!cpus_empty(mask))
- 		send_IPI_mask(mask, vector);
- }
- 
---- linux-2.6.0-test1/include/asm-i386/mach-default/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-default/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -5,12 +5,12 @@
- 
- #define APIC_DFR_VALUE	(APIC_DFR_FLAT)
- 
--static inline unsigned long target_cpus(void)
-+static inline cpumask_t target_cpus(void)
- { 
- #ifdef CONFIG_SMP
- 	return cpu_online_map;
- #else
--	return 1; 
-+	return cpumask_of_cpu(0);
- #endif
- } 
- #define TARGET_CPUS (target_cpus())
-@@ -21,16 +21,20 @@ static inline unsigned long target_cpus(
- #define INT_DELIVERY_MODE dest_LowestPrio
- #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
- 
-+/*
-+ * this isn't really broadcast, just a (potentially inaccurate) upper
-+ * bound for valid physical APIC id's
-+ */
- #define APIC_BROADCAST_ID      0x0F
- 
--static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) 
--{ 
--	return (bitmap & (1UL << apicid)); 
--} 
-+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-+{
-+	return physid_isset(apicid, bitmap);
-+}
- 
--static inline unsigned long check_apicid_present(int bit) 
-+static inline unsigned long check_apicid_present(int bit)
- {
--	return (phys_cpu_present_map & (1UL << bit));
-+	return physid_isset(bit, phys_cpu_present_map);
- }
- 
- /*
-@@ -50,7 +54,7 @@ static inline void init_apic_ldr(void)
- 	apic_write_around(APIC_LDR, val);
- }
- 
--static inline unsigned long ioapic_phys_id_map(unsigned long phys_map)
-+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
- {
- 	return phys_map;
- }
-@@ -82,9 +86,9 @@ static inline int cpu_present_to_apicid(
- 	return  mps_cpu;
- }
- 
--static inline unsigned long apicid_to_cpu_present(int phys_apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
- {
--	return (1ul << phys_apicid);
-+	return physid_mask_of_physid(phys_apicid);
- }
- 
- static inline int mpc_apic_id(struct mpc_config_processor *m, 
-@@ -104,18 +108,17 @@ static inline void setup_portio_remap(vo
- 
- static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
- {
--	return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map);
-+	return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
- }
- 
- static inline int apic_id_registered(void)
- {
--	return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), 
--						&phys_cpu_present_map));
-+	return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map);
- }
- 
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
--	return cpumask;
-+	return cpus_coerce_const(cpumask);
- }
- 
- static inline void enable_apic_mode(void)
---- linux-2.6.0-test1/include/asm-i386/mach-default/mach_ipi.h	2003-06-14 12:18:33.000000000 -0700
-+++ 25/include/asm-i386/mach-default/mach_ipi.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,10 +1,10 @@
- #ifndef __ASM_MACH_IPI_H
- #define __ASM_MACH_IPI_H
- 
--inline void send_IPI_mask_bitmask(int mask, int vector);
-+inline void send_IPI_mask_bitmask(cpumask_t mask, int vector);
- inline void __send_IPI_shortcut(unsigned int shortcut, int vector);
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t mask, int vector)
- {
- 	send_IPI_mask_bitmask(mask, vector);
- }
---- linux-2.6.0-test1/include/asm-i386/mach-es7000/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-es7000/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -11,12 +11,12 @@ static inline int apic_id_registered(voi
- 	        return (1);
- }
- 
--static inline unsigned long target_cpus(void)
-+static inline cpumask_t target_cpus(void)
- { 
- #if defined CONFIG_ES7000_CLUSTERED_APIC
--	return (0xff);
-+	return CPU_MASK_ALL;
- #else
--	return (bios_cpu_apicid[smp_processor_id()]);
-+	return cpumask_of_cpu(bios_cpu_apicid[smp_processor_id()]);
- #endif
- }
- #define TARGET_CPUS	(target_cpus())
-@@ -40,13 +40,13 @@ static inline unsigned long target_cpus(
- 
- #define APIC_BROADCAST_ID	(0xff)
- 
--static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) 
-+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
- { 
- 	return 0;
- } 
- static inline unsigned long check_apicid_present(int bit) 
- {
--	return (phys_cpu_present_map & (1 << bit));
-+	return physid_isset(bit, phys_cpu_present_map);
- }
- 
- #define apicid_cluster(apicid) (apicid & 0xF0)
-@@ -88,7 +88,7 @@ static inline void clustered_apic_check(
- 	int apic = bios_cpu_apicid[smp_processor_id()];
- 	printk("Enabling APIC mode:  %s.  Using %d I/O APICs, target cpus %lx\n",
- 		(apic_version[apic] == 0x14) ? 
--		"Physical Cluster" : "Logical Cluster", nr_ioapics, TARGET_CPUS);
-+		"Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_coerce(TARGET_CPUS));
- }
- 
- static inline int multi_timer_check(int apic, int irq)
-@@ -110,10 +110,13 @@ static inline int cpu_present_to_apicid(
- 		return (int) bios_cpu_apicid[mps_cpu];
- }
- 
--static inline unsigned long apicid_to_cpu_present(int phys_apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
- {
--	static int cpu = 0;
--	return (1ul << cpu++);
-+	static int id = 0;
-+	physid_mask_t mask;
-+	mask = physid_mask_of_physid(id);
-+	++id;
-+	return mask;
- }
- 
- extern volatile u8 cpu_2_logical_apicid[];
-@@ -123,7 +126,7 @@ static inline int cpu_to_logical_apicid(
-        return (int)cpu_2_logical_apicid[cpu];
- }
- 
--static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
-+static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused)
- {
- 	printk("Processor #%d %ld:%ld APIC version %d\n",
- 	        m->mpc_apicid,
-@@ -133,10 +136,10 @@ static inline int mpc_apic_id(struct mpc
- 	return (m->mpc_apicid);
- }
- 
--static inline ulong ioapic_phys_id_map(ulong phys_map)
-+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
- {
- 	/* For clustered we don't have a good way to do this yet - hack */
--	return (0xff);
-+	return physids_promote(0xff);
- }
- 
- 
-@@ -151,32 +154,30 @@ static inline int check_phys_apicid_pres
- 	return (1);
- }
- 
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
- 	int num_bits_set;
- 	int cpus_found = 0;
- 	int cpu;
- 	int apicid;	
- 
--	if (cpumask == TARGET_CPUS)
--		return cpumask;
--	num_bits_set = hweight32(cpumask); 
-+	num_bits_set = cpus_weight_const(cpumask);
- 	/* Return id to all */
--	if (num_bits_set == 32)
--		return TARGET_CPUS;
-+	if (num_bits_set == NR_CPUS)
-+		return 0xFF;
- 	/* 
- 	 * The cpus in the mask must all be on the apic cluster.  If are not 
- 	 * on the same apicid cluster return default value of TARGET_CPUS. 
- 	 */
--	cpu = ffs(cpumask)-1;
-+	cpu = first_cpu_const(cpumask);
- 	apicid = cpu_to_logical_apicid(cpu);
- 	while (cpus_found < num_bits_set) {
--		if (cpumask & (1 << cpu)) {
-+		if (cpu_isset_const(cpu, cpumask)) {
- 			int new_apicid = cpu_to_logical_apicid(cpu);
- 			if (apicid_cluster(apicid) != 
- 					apicid_cluster(new_apicid)){
- 				printk ("%s: Not a valid mask!\n",__FUNCTION__);
--				return TARGET_CPUS;
-+				return 0xFF;
- 			}
- 			apicid = new_apicid;
- 			cpus_found++;
---- linux-2.6.0-test1/include/asm-i386/mach-es7000/mach_ipi.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-es7000/mach_ipi.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,18 +1,19 @@
- #ifndef __ASM_MACH_IPI_H
- #define __ASM_MACH_IPI_H
- 
--static inline void send_IPI_mask_sequence(int mask, int vector);
-+static inline void send_IPI_mask_sequence(cpumask_t mask, int vector);
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t mask, int vector)
- {
- 	send_IPI_mask_sequence(mask, vector);
- }
- 
- static inline void send_IPI_allbutself(int vector)
- {
--	unsigned long mask = cpu_online_map & ~(1 << smp_processor_id());
--
--	if (mask)
-+	cpumask_t mask = cpumask_of_cpu(smp_processor_id());
-+	cpus_complement(mask);
-+	cpus_and(mask, mask, cpu_online_map);
-+	if (!cpus_empty(mask))
- 		send_IPI_mask(mask, vector);
- }
- 
---- linux-2.6.0-test1/include/asm-i386/mach-numaq/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-numaq/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -6,7 +6,13 @@
- 
- #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
- 
--#define TARGET_CPUS (~0UL)
-+static inline cpumask_t target_cpus(void)
-+{
-+	cpumask_t tmp = CPU_MASK_ALL;
-+	return tmp;
-+}
-+
-+#define TARGET_CPUS (target_cpus())
- 
- #define NO_BALANCE_IRQ (1)
- #define esr_disable (1)
-@@ -15,13 +21,13 @@
- #define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
-  
- #define APIC_BROADCAST_ID      0x0F
--#define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid)))
--#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
-+#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap)
-+#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map)
- #define apicid_cluster(apicid) (apicid & 0xF0)
- 
- static inline int apic_id_registered(void)
- {
--	return (1);
-+	return 1;
- }
- 
- static inline void init_apic_ldr(void)
-@@ -41,13 +47,13 @@ static inline void clustered_apic_check(
-  */
- static inline int multi_timer_check(int apic, int irq)
- {
--	return (apic != 0 && irq == 0);
-+	return apic != 0 && irq == 0;
- }
- 
--static inline ulong ioapic_phys_id_map(ulong phys_map)
-+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
- {
- 	/* We don't have a good way to do this yet - hack */
--	return 0xf;
-+	return physids_promote(0xFUL);
- }
- 
- /* Mapping from cpu number to logical apicid */
-@@ -59,22 +65,25 @@ static inline int cpu_to_logical_apicid(
- 
- static inline int cpu_present_to_apicid(int mps_cpu)
- {
--	return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) );
-+	return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
- }
- 
- static inline int generate_logical_apicid(int quad, int phys_apicid)
- {
--	return ( (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1) );
-+	return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
- }
- 
- static inline int apicid_to_node(int logical_apicid) 
- {
--	return (logical_apicid >> 4);
-+	return logical_apicid >> 4;
- }
- 
--static inline unsigned long apicid_to_cpu_present(int logical_apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int logical_apicid)
- {
--	return ( (logical_apicid&0xf) << (4*apicid_to_node(logical_apicid)) );
-+	int node = apicid_to_node(logical_apicid);
-+	int cpu = __ffs(logical_apicid & 0xf);
-+
-+	return physid_mask_of_physid(cpu + 4*node);
- }
- 
- static inline int mpc_apic_id(struct mpc_config_processor *m, 
-@@ -115,7 +124,7 @@ static inline void enable_apic_mode(void
-  * We use physical apicids here, not logical, so just return the default
-  * physical broadcast to stop people from breaking us
-  */
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
- 	return (int) 0xF;
- }
---- linux-2.6.0-test1/include/asm-i386/mach-numaq/mach_ipi.h	2003-06-14 12:18:29.000000000 -0700
-+++ 25/include/asm-i386/mach-numaq/mach_ipi.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,18 +1,19 @@
- #ifndef __ASM_MACH_IPI_H
- #define __ASM_MACH_IPI_H
- 
--static inline void send_IPI_mask_sequence(int mask, int vector);
-+static inline void send_IPI_mask_sequence(cpumask_t, int vector);
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t mask, int vector)
- {
- 	send_IPI_mask_sequence(mask, vector);
- }
- 
- static inline void send_IPI_allbutself(int vector)
- {
--	unsigned long mask = cpu_online_map & ~(1 << smp_processor_id());
-+	cpumask_t mask = cpu_online_map;
-+	cpu_clear(smp_processor_id(), mask);
- 
--	if (mask)
-+	if (!cpus_empty(mask))
- 		send_IPI_mask(mask, vector);
- }
- 
---- linux-2.6.0-test1/include/asm-i386/mach-summit/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-summit/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -18,17 +18,18 @@ static inline unsigned long xapic_phys_t
- 
- #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
- 
--static inline unsigned long target_cpus(void)
-+static inline cpumask_t target_cpus(void)
- {
--	return (~0UL);
-+	cpumask_t tmp = CPU_MASK_ALL;
-+	return tmp;
- } 
- #define TARGET_CPUS	(target_cpus())
- 
- #define INT_DELIVERY_MODE (dest_Fixed)
- #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
- 
--#define APIC_BROADCAST_ID     (0x0F)
--static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) 
-+#define APIC_BROADCAST_ID     (0xFF)
-+static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
- {
- 	return 0;
- } 
-@@ -72,7 +73,7 @@ static inline void clustered_apic_check(
- 
- static inline int apicid_to_node(int logical_apicid)
- {
--	return (logical_apicid >> 5);          /* 2 clusterids per CEC */
-+	return logical_apicid >> 5;          /* 2 clusterids per CEC */
- }
- 
- /* Mapping from cpu number to logical apicid */
-@@ -87,15 +88,15 @@ static inline int cpu_present_to_apicid(
- 	return (int) bios_cpu_apicid[mps_cpu];
- }
- 
--static inline ulong ioapic_phys_id_map(ulong phys_map)
-+static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map)
- {
- 	/* For clustered we don't have a good way to do this yet - hack */
--	return 0x0F;
-+	return physids_promote(0x0F);
- }
- 
--static inline unsigned long apicid_to_cpu_present(int apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int apicid)
- {
--	return 1;
-+	return physid_mask_of_physid(0);
- }
- 
- static inline int mpc_apic_id(struct mpc_config_processor *m, 
-@@ -122,25 +123,25 @@ static inline void enable_apic_mode(void
- {
- }
- 
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
- 	int num_bits_set;
- 	int cpus_found = 0;
- 	int cpu;
- 	int apicid;	
- 
--	num_bits_set = hweight32(cpumask); 
-+	num_bits_set = cpus_weight_const(cpumask);
- 	/* Return id to all */
--	if (num_bits_set == 32)
-+	if (num_bits_set == NR_CPUS)
- 		return (int) 0xFF;
- 	/* 
- 	 * The cpus in the mask must all be on the apic cluster.  If are not 
- 	 * on the same apicid cluster return default value of TARGET_CPUS. 
- 	 */
--	cpu = ffs(cpumask)-1;
-+	cpu = first_cpu_const(cpumask);
- 	apicid = cpu_to_logical_apicid(cpu);
- 	while (cpus_found < num_bits_set) {
--		if (cpumask & (1 << cpu)) {
-+		if (cpu_isset_const(cpu, cpumask)) {
- 			int new_apicid = cpu_to_logical_apicid(cpu);
- 			if (apicid_cluster(apicid) != 
- 					apicid_cluster(new_apicid)){
---- linux-2.6.0-test1/include/asm-i386/mach-summit/mach_ipi.h	2003-06-14 12:17:59.000000000 -0700
-+++ 25/include/asm-i386/mach-summit/mach_ipi.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,18 +1,19 @@
- #ifndef __ASM_MACH_IPI_H
- #define __ASM_MACH_IPI_H
- 
--inline void send_IPI_mask_sequence(int mask, int vector);
-+inline void send_IPI_mask_sequence(cpumask_t mask, int vector);
- 
--static inline void send_IPI_mask(int mask, int vector)
-+static inline void send_IPI_mask(cpumask_t mask, int vector)
- {
- 	send_IPI_mask_sequence(mask, vector);
- }
- 
- static inline void send_IPI_allbutself(int vector)
- {
--	unsigned long mask = cpu_online_map & ~(1 << smp_processor_id());
-+	cpumask_t mask = cpu_online_map;
-+	cpu_clear(smp_processor_id(), mask);
- 
--	if (mask)
-+	if (!cpus_empty(mask))
- 		send_IPI_mask(mask, vector);
- }
- 
---- linux-2.6.0-test1/include/asm-i386/mach-visws/mach_apic.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mach-visws/mach_apic.h	2003-07-19 17:04:07.000000000 -0700
-@@ -12,17 +12,16 @@
- #ifdef CONFIG_SMP
-  #define TARGET_CPUS cpu_online_map
- #else
-- #define TARGET_CPUS 0x01
-+ #define TARGET_CPUS cpumask_of_cpu(0)
- #endif
- 
- #define APIC_BROADCAST_ID      0x0F
--#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid))
--#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
-+#define check_apicid_used(bitmap, apicid)	physid_isset(apicid, bitmap)
-+#define check_apicid_present(bit)		physid_isset(bit, phys_cpu_present_map)
- 
- static inline int apic_id_registered(void)
- {
--	return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), 
--						&phys_cpu_present_map));
-+	return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map);
- }
- 
- /*
-@@ -61,9 +60,9 @@ static inline int cpu_present_to_apicid(
- 	return mps_cpu;
- }
- 
--static inline unsigned long apicid_to_cpu_present(int apicid)
-+static inline physid_mask_t apicid_to_cpu_present(int apicid)
- {
--	return (1ul << apicid);
-+	return physid_mask_of_physid(apicid);
- }
- 
- #define WAKE_SECONDARY_VIA_INIT
-@@ -78,11 +77,11 @@ static inline void enable_apic_mode(void
- 
- static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
- {
--	return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map);
-+	return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
- }
- 
--static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
-+static inline unsigned int cpu_mask_to_apicid(cpumask_const_t cpumask)
- {
--	return cpumask;
-+	return cpus_coerce_const(cpumask);
- }
- #endif /* __ASM_MACH_APIC_H */
---- linux-2.6.0-test1/include/asm-i386/mmu_context.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-i386/mmu_context.h	2003-07-19 17:04:07.000000000 -0700
-@@ -31,12 +31,12 @@ static inline void switch_mm(struct mm_s
- 
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
--		clear_bit(cpu, &prev->cpu_vm_mask);
-+		cpu_clear(cpu, prev->cpu_vm_mask);
- #ifdef CONFIG_SMP
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
- 		cpu_tlbstate[cpu].active_mm = next;
- #endif
--		set_bit(cpu, &next->cpu_vm_mask);
-+		cpu_set(cpu, next->cpu_vm_mask);
- 
- 		/* Re-load page tables */
- 		load_cr3(next->pgd);
-@@ -52,7 +52,7 @@ static inline void switch_mm(struct mm_s
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
- 		BUG_ON(cpu_tlbstate[cpu].active_mm != next);
- 
--		if (!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
-+		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload %cr3.
- 			 */
---- linux-2.6.0-test1/include/asm-i386/mpspec.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-i386/mpspec.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,6 +1,7 @@
- #ifndef __ASM_MPSPEC_H
- #define __ASM_MPSPEC_H
- 
-+#include <linux/cpumask.h>
- #include <asm/mpspec_def.h>
- #include <mach_mpspec.h>
- 
-@@ -11,7 +12,6 @@ extern int quad_local_to_mp_bus_id [NR_C
- extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
- 
- extern unsigned int boot_cpu_physical_apicid;
--extern unsigned long phys_cpu_present_map;
- extern int smp_found_config;
- extern void find_smp_config (void);
- extern void get_smp_config (void);
-@@ -41,5 +41,49 @@ extern void mp_config_ioapic_for_sci(int
- extern void mp_parse_prt (void);
- #endif /*CONFIG_ACPI_BOOT*/
- 
-+#define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
-+
-+struct physid_mask
-+{
-+	unsigned long mask[PHYSID_ARRAY_SIZE];
-+};
-+
-+typedef struct physid_mask physid_mask_t;
-+
-+#define physid_set(physid, map)			set_bit(physid, (map).mask)
-+#define physid_clear(physid, map)		clear_bit(physid, (map).mask)
-+#define physid_isset(physid, map)		test_bit(physid, (map).mask)
-+#define physid_test_and_set(physid, map)	test_and_set_bit(physid, (map).mask)
-+
-+#define physids_and(dst, src1, src2)		bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS)
-+#define physids_or(dst, src1, src2)		bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS)
-+#define physids_clear(map)			bitmap_clear((map).mask, MAX_APICS)
-+#define physids_complement(map)			bitmap_complement((map).mask, MAX_APICS)
-+#define physids_empty(map)			bitmap_empty((map).mask, MAX_APICS)
-+#define physids_equal(map1, map2)		bitmap_equal((map1).mask, (map2).mask, MAX_APICS)
-+#define physids_weight(map)			bitmap_weight((map).mask, MAX_APICS)
-+#define physids_shift_right(d, s, n)		bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS)
-+#define physids_shift_left(d, s, n)		bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS)
-+#define physids_coerce(map)			((map).mask[0])
-+
-+#define physids_promote(physids)						\
-+	({									\
-+		physid_mask_t __physid_mask = PHYSID_MASK_NONE;			\
-+		__physid_mask.mask[0] = physids;				\
-+		__physid_mask;							\
-+	})
-+
-+#define physid_mask_of_physid(physid)						\
-+	({									\
-+		physid_mask_t __physid_mask = PHYSID_MASK_NONE;			\
-+		physid_set(physid, __physid_mask);				\
-+		__physid_mask;							\
-+	})
-+
-+#define PHYSID_MASK_ALL		{ {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} }
-+#define PHYSID_MASK_NONE	{ {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} }
-+
-+extern physid_mask_t phys_cpu_present_map;
-+
- #endif
- 
---- linux-2.6.0-test1/include/asm-i386/numaq.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/asm-i386/numaq.h	2003-07-19 17:04:07.000000000 -0700
-@@ -28,7 +28,7 @@
- 
- #ifdef CONFIG_X86_NUMAQ
- 
--#define MAX_NUMNODES		8
-+#define MAX_NUMNODES		16
- extern void get_memcfg_numaq(void);
- #define get_memcfg_numa() get_memcfg_numaq()
- 
-@@ -159,7 +159,7 @@ struct sys_cfg_data {
- 
- static inline unsigned long *get_zholes_size(int nid)
- {
--	return 0;
-+	return NULL;
- }
- #endif /* CONFIG_X86_NUMAQ */
- #endif /* NUMAQ_H */
---- linux-2.6.0-test1/include/asm-i386/pgalloc.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/asm-i386/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -45,7 +45,8 @@ static inline void pte_free(struct page 
-  * (In the PAE case we free the pmds as part of the pgd.)
-  */
- 
--#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)	({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)			do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- #define pgd_populate(mm, pmd, pte)	BUG()
---- linux-2.6.0-test1/include/asm-i386/pgtable-2level.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/asm-i386/pgtable-2level.h	2003-07-19 17:07:16.000000000 -0700
-@@ -48,13 +48,15 @@ static inline int pgd_present(pgd_t pgd)
- #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
- #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
- 
--#define pgd_page(pgd) \
--((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+#define pgd_page(pgd)		pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
-+
-+#define pmd_offset_map(pgd, addr)		({ (pmd_t *)(pgd); })
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset_map(pgd, addr)
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset_map(pgd, addr)
-+
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
- 
--static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
--{
--	return (pmd_t *) dir;
--}
- #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte_low, 0))
- #define pte_same(a, b)		((a).pte_low == (b).pte_low)
- #define pte_page(x)		pfn_to_page(pte_pfn(x))
---- linux-2.6.0-test1/include/asm-i386/pgtable-3level.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/pgtable-3level.h	2003-07-19 17:07:16.000000000 -0700
-@@ -64,12 +64,32 @@ static inline void set_pte(pte_t *ptep, 
-  */
- static inline void pgd_clear (pgd_t * pgd) { }
- 
--#define pgd_page(pgd) \
--((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+static inline unsigned long pgd_pfn(pgd_t pgd)
-+{
-+	return pgd_val(pgd) >> PAGE_SHIFT;
-+}
-+
-+#define pgd_page(pgd)		pfn_to_page(pgd_pfn(pgd))
-+
-+#define pmd_offset_kernel(pgd, addr)					\
-+	((pmd_t *)__va(pgd_val(*(pgd)) & PAGE_MASK) + pmd_index(addr))
- 
- /* Find an entry in the second-level page table.. */
--#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
--			pmd_index(address))
-+#ifdef CONFIG_HIGHPMD
-+#define __pmd_offset(pgd, addr, type)					\
-+	((pmd_t *)kmap_atomic(pgd_page(*(pgd)), type) + pmd_index(addr))
-+#define __pmd_unmap(pmd, type)		kunmap_atomic(pmd, type)
-+#else
-+#define __pmd_offset(pgd, addr, type)					\
-+	((pmd_t *)__va(pgd_val(*(pgd)) & PAGE_MASK) + pmd_index(addr))
-+#define __pmd_unmap(pmd, type)		do { } while (0)
-+#endif
-+
-+#define pmd_offset_map(pgd, addr)		__pmd_offset(pgd, addr, KM_PMD0)
-+#define pmd_offset_map_nested(pgd, addr)	__pmd_offset(pgd, addr, KM_PMD1)
-+
-+#define pmd_unmap(pmd)				__pmd_unmap(pmd, KM_PMD0);
-+#define pmd_unmap_nested(pmd)			__pmd_unmap(pmd, KM_PMD1);
- 
- static inline pte_t ptep_get_and_clear(pte_t *ptep)
- {
-@@ -123,6 +143,4 @@ static inline pmd_t pfn_pmd(unsigned lon
- #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
- #define PTE_FILE_MAX_BITS       32
- 
--extern struct kmem_cache_s *pae_pgd_cachep;
--
- #endif /* _I386_PGTABLE_3LEVEL_H */
---- linux-2.6.0-test1/include/asm-i386/pgtable.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -21,15 +21,25 @@
- #include <asm/bitops.h>
- #endif
- 
--extern pgd_t swapper_pg_dir[1024];
--extern void paging_init(void);
-+#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
- 
- /*
-  * ZERO_PAGE is a global shared page that is always zero: used
-  * for zero-mapped memory areas etc..
-  */
--extern unsigned long empty_zero_page[1024];
- #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-+extern unsigned long empty_zero_page[1024];
-+extern pgd_t swapper_pg_dir[1024];
-+extern kmem_cache_t *pgd_cache;
-+extern spinlock_t pgd_lock;
-+extern struct list_head pgd_list;
-+
-+void pgd_ctor(void *, kmem_cache_t *, unsigned long);
-+void pgd_dtor(void *, kmem_cache_t *, unsigned long);
-+void pgtable_cache_init(void);
-+void paging_init(void);
- 
- #endif /* !__ASSEMBLY__ */
- 
-@@ -41,20 +51,8 @@ extern unsigned long empty_zero_page[102
- #ifndef __ASSEMBLY__
- #ifdef CONFIG_X86_PAE
- # include <asm/pgtable-3level.h>
--
--/*
-- * Need to initialise the X86 PAE caches
-- */
--extern void pgtable_cache_init(void);
--
- #else
- # include <asm/pgtable-2level.h>
--
--/*
-- * No page table caches to initialise
-- */
--#define pgtable_cache_init()	do { } while (0)
--
- #endif
- #endif
- 
---- linux-2.6.0-test1/include/asm-i386/posix_types.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned short	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-i386/rwlock.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/rwlock.h	2003-07-19 17:04:49.000000000 -0700
-@@ -20,28 +20,52 @@
- #define RW_LOCK_BIAS		 0x01000000
- #define RW_LOCK_BIAS_STR	"0x01000000"
- 
--#define __build_read_lock_ptr(rw, helper)   \
--	asm volatile(LOCK "subl $1,(%0)\n\t" \
--		     "js 2f\n" \
--		     "1:\n" \
--		     LOCK_SECTION_START("") \
--		     "2:\tcall " helper "\n\t" \
--		     "jmp 1b\n" \
--		     LOCK_SECTION_END \
--		     ::"a" (rw) : "memory")
--
--#define __build_read_lock_const(rw, helper)   \
--	asm volatile(LOCK "subl $1,%0\n\t" \
--		     "js 2f\n" \
--		     "1:\n" \
--		     LOCK_SECTION_START("") \
--		     "2:\tpushl %%eax\n\t" \
--		     "leal %0,%%eax\n\t" \
--		     "call " helper "\n\t" \
--		     "popl %%eax\n\t" \
--		     "jmp 1b\n" \
--		     LOCK_SECTION_END \
--		     :"=m" (*(volatile int *)rw) : : "memory")
-+#ifdef CONFIG_SPINLINE
-+
-+	#define __build_read_lock_ptr(rw, helper)   \
-+		asm volatile(LOCK "subl $1,(%0)\n\t" \
-+			     "jns 1f\n\t" \
-+			     "call " helper "\n\t" \
-+			     "1:\t" \
-+			     ::"a" (rw) : "memory")
-+
-+	#define __build_read_lock_const(rw, helper)   \
-+		asm volatile(LOCK "subl $1,%0\n\t" \
-+			     "jns 1f\n\t" \
-+			     "pushl %%eax\n\t" \
-+			     "leal %0,%%eax\n\t" \
-+			     "call " helper "\n\t" \
-+			     "popl %%eax\n\t" \
-+			     "1:\t" \
-+			     :"=m" (*(volatile int *)rw) : : "memory")
-+
-+#else /* !CONFIG_SPINLINE */
-+
-+	#define __build_read_lock_ptr(rw, helper)   \
-+		asm volatile(LOCK "subl $1,(%0)\n\t" \
-+			     "js 2f\n" \
-+			     "1:\n" \
-+			     LOCK_SECTION_START("") \
-+			     "2:\tcall " helper "\n\t" \
-+			     "jmp 1b\n" \
-+			     LOCK_SECTION_END \
-+			     ::"a" (rw) : "memory")
-+
-+	#define __build_read_lock_const(rw, helper)   \
-+		asm volatile(LOCK "subl $1,%0\n\t" \
-+			     "js 2f\n" \
-+			     "1:\n" \
-+			     LOCK_SECTION_START("") \
-+			     "2:\tpushl %%eax\n\t" \
-+			     "leal %0,%%eax\n\t" \
-+			     "call " helper "\n\t" \
-+			     "popl %%eax\n\t" \
-+			     "jmp 1b\n" \
-+			     LOCK_SECTION_END \
-+			     :"=m" (*(volatile int *)rw) : : "memory")
-+
-+#endif /* CONFIG_SPINLINE */
-+
- 
- #define __build_read_lock(rw, helper)	do { \
- 						if (__builtin_constant_p(rw)) \
-@@ -50,28 +74,51 @@
- 							__build_read_lock_ptr(rw, helper); \
- 					} while (0)
- 
--#define __build_write_lock_ptr(rw, helper) \
--	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
--		     "jnz 2f\n" \
--		     "1:\n" \
--		     LOCK_SECTION_START("") \
--		     "2:\tcall " helper "\n\t" \
--		     "jmp 1b\n" \
--		     LOCK_SECTION_END \
--		     ::"a" (rw) : "memory")
--
--#define __build_write_lock_const(rw, helper) \
--	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
--		     "jnz 2f\n" \
--		     "1:\n" \
--		     LOCK_SECTION_START("") \
--		     "2:\tpushl %%eax\n\t" \
--		     "leal %0,%%eax\n\t" \
--		     "call " helper "\n\t" \
--		     "popl %%eax\n\t" \
--		     "jmp 1b\n" \
--		     LOCK_SECTION_END \
--		     :"=m" (*(volatile int *)rw) : : "memory")
-+#ifdef CONFIG_SPINLINE
-+
-+	#define __build_write_lock_ptr(rw, helper) \
-+		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
-+			     "jz 1f\n\t" \
-+			     "call " helper "\n\t" \
-+			     "1:\n" \
-+			     ::"a" (rw) : "memory")
-+
-+	#define __build_write_lock_const(rw, helper) \
-+		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
-+			     "jz 1f\n\t" \
-+			     "pushl %%eax\n\t" \
-+			     "leal %0,%%eax\n\t" \
-+			     "call " helper "\n\t" \
-+			     "popl %%eax\n\t" \
-+			     "1:\n" \
-+			     :"=m" (*(volatile int *)rw) : : "memory")
-+
-+#else /* !CONFIG_SPINLINE */
-+
-+	#define __build_write_lock_ptr(rw, helper) \
-+		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
-+			     "jnz 2f\n" \
-+			     "1:\n" \
-+			     LOCK_SECTION_START("") \
-+			     "2:\tcall " helper "\n\t" \
-+			     "jmp 1b\n" \
-+			     LOCK_SECTION_END \
-+			     ::"a" (rw) : "memory")
-+
-+	#define __build_write_lock_const(rw, helper) \
-+		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
-+			     "jnz 2f\n" \
-+			     "1:\n" \
-+			     LOCK_SECTION_START("") \
-+			     "2:\tpushl %%eax\n\t" \
-+			     "leal %0,%%eax\n\t" \
-+			     "call " helper "\n\t" \
-+			     "popl %%eax\n\t" \
-+			     "jmp 1b\n" \
-+			     LOCK_SECTION_END \
-+			     :"=m" (*(volatile int *)rw) : : "memory")
-+
-+#endif /* CONFIG_SPINLINE */
- 
- #define __build_write_lock(rw, helper)	do { \
- 						if (__builtin_constant_p(rw)) \
---- linux-2.6.0-test1/include/asm-i386/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-i386/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -8,6 +8,7 @@
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #endif
- 
- #ifdef CONFIG_X86_LOCAL_APIC
-@@ -31,9 +32,7 @@
-  */
-  
- extern void smp_alloc_memory(void);
--extern unsigned long phys_cpu_present_map;
--extern unsigned long cpu_online_map;
--extern volatile unsigned long smp_invalidate_needed;
-+extern physid_mask_t phys_cpu_present_map;
- extern int pic_mode;
- extern int smp_num_siblings;
- extern int cpu_sibling_map[];
-@@ -54,37 +53,19 @@ extern void zap_low_mappings (void);
-  */
- #define smp_processor_id() (current_thread_info()->cpu)
- 
--extern volatile unsigned long cpu_callout_map;
-+extern cpumask_t cpu_callout_map;
- 
--#define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu)))
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--
--#define for_each_cpu(cpu, mask) \
--	for(mask = cpu_online_map; \
--	    cpu = __ffs(mask), mask != 0; \
--	    mask &= ~(1<<cpu))
--
--extern inline unsigned int num_online_cpus(void)
--{
--	return hweight32(cpu_online_map);
--}
-+#define cpu_possible(cpu) cpu_isset(cpu, cpu_callout_map)
- 
- /* We don't mark CPUs online until __cpu_up(), so we need another measure */
- static inline int num_booting_cpus(void)
- {
--	return hweight32(cpu_callout_map);
-+	return cpus_weight(cpu_callout_map);
- }
- 
- extern void map_cpu_to_logical_apicid(void);
- extern void unmap_cpu_to_logical_apicid(int cpu);
- 
--extern inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS;
--}
- #ifdef CONFIG_X86_LOCAL_APIC
- 
- #ifdef APIC_DEFINITION
---- linux-2.6.0-test1/include/asm-i386/spinlock.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-i386/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -43,18 +43,35 @@ typedef struct {
- #define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
- #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
- 
--#define spin_lock_string \
--	"\n1:\t" \
--	"lock ; decb %0\n\t" \
--	"js 2f\n" \
--	LOCK_SECTION_START("") \
--	"2:\t" \
--	"rep;nop\n\t" \
--	"cmpb $0,%0\n\t" \
--	"jle 2b\n\t" \
--	"jmp 1b\n" \
--	LOCK_SECTION_END
-+#ifdef CONFIG_SPINLINE
- 
-+	#define spin_lock_string \
-+		"\n1:\t" \
-+		"lock ; decb %0\n\t" \
-+		"js 2f\n" \
-+		"jmp 3f\n" \
-+		"2:\t" \
-+		"rep;nop\n\t" \
-+		"cmpb $0,%0\n\t" \
-+		"jle 2b\n\t" \
-+		"jmp 1b\n" \
-+		"3:\t"
-+
-+#else /* !CONFIG_SPINLINE */
-+
-+	#define spin_lock_string \
-+		"\n1:\t" \
-+		"lock ; decb %0\n\t" \
-+		"js 2f\n" \
-+		LOCK_SECTION_START("") \
-+		"2:\t" \
-+		"rep;nop\n\t" \
-+		"cmpb $0,%0\n\t" \
-+		"jle 2b\n\t" \
-+		"jmp 1b\n" \
-+		LOCK_SECTION_END
-+
-+#endif /* CONFIG_SPINLINE */
- /*
-  * This works. Despite all the confusion.
-  * (except on PPro SMP or if we are using OOSTORE)
-@@ -138,6 +155,11 @@ here:
-  */
- typedef struct {
- 	volatile unsigned int lock;
-+#ifdef CONFIG_LOCKMETER
-+	/* required for LOCKMETER since all bits in lock are used */
-+	/* and we need this storage for CPU and lock INDEX        */
-+	unsigned lockmeter_magic;
-+#endif
- #ifdef CONFIG_DEBUG_SPINLOCK
- 	unsigned magic;
- #endif
-@@ -145,11 +167,19 @@ typedef struct {
- 
- #define RWLOCK_MAGIC	0xdeaf1eed
- 
-+#ifdef CONFIG_LOCKMETER
-+#ifdef CONFIG_DEBUG_SPINLOCK
-+#define RWLOCK_MAGIC_INIT	, 0, RWLOCK_MAGIC
-+#else
-+#define RWLOCK_MAGIC_INIT	, 0
-+#endif
-+#else /* !CONFIG_LOCKMETER */
- #ifdef CONFIG_DEBUG_SPINLOCK
- #define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
- #else
- #define RWLOCK_MAGIC_INIT	/* */
- #endif
-+#endif /* !CONFIG_LOCKMETER */
- 
- #define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
- 
-@@ -196,4 +226,58 @@ static inline int _raw_write_trylock(rwl
- 	return 0;
- }
- 
-+#ifdef CONFIG_LOCKMETER
-+static inline int _raw_read_trylock(rwlock_t *lock)
-+{
-+/* FIXME -- replace with assembler */
-+	atomic_t *count = (atomic_t *)lock;
-+	atomic_dec(count);
-+	if (count->counter > 0)
-+		return 1;
-+	atomic_inc(count);
-+	return 0;
-+}
-+#endif
-+
-+#if defined(CONFIG_LOCKMETER) && defined(CONFIG_HAVE_DEC_LOCK)
-+extern void _metered_spin_lock  (spinlock_t *lock);
-+extern void _metered_spin_unlock(spinlock_t *lock);
-+
-+/*
-+ *  Matches what is in arch/i386/lib/dec_and_lock.c, except this one is
-+ *  "static inline" so that the spin_lock(), if actually invoked, is charged
-+ *  against the real caller, not against the catch-all atomic_dec_and_lock
-+ */
-+static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-+{
-+	int counter;
-+	int newcount;
-+
-+repeat:
-+	counter = atomic_read(atomic);
-+	newcount = counter-1;
-+
-+	if (!newcount)
-+		goto slow_path;
-+
-+	asm volatile("lock; cmpxchgl %1,%2"
-+		:"=a" (newcount)
-+		:"r" (newcount), "m" (atomic->counter), "0" (counter));
-+
-+	/* If the above failed, "eax" will have changed */
-+	if (newcount != counter)
-+		goto repeat;
-+	return 0;
-+
-+slow_path:
-+	_metered_spin_lock(lock);
-+	if (atomic_dec_and_test(atomic))
-+		return 1;
-+	_metered_spin_unlock(lock);
-+	return 0;
-+}
-+
-+#define ATOMIC_DEC_AND_LOCK
-+#endif
-+
- #endif /* __ASM_SPINLOCK_H */
---- linux-2.6.0-test1/include/asm-i386/stat.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/asm-i386/stat.h	2003-07-19 17:06:16.000000000 -0700
-@@ -9,6 +9,7 @@ struct __old_kernel_stat {
- 	unsigned short st_uid;
- 	unsigned short st_gid;
- 	unsigned short st_rdev;
-+	unsigned short __pad_16bit;
- 	unsigned long  st_size;
- 	unsigned long  st_atime;
- 	unsigned long  st_mtime;
---- linux-2.6.0-test1/include/asm-i386/thread_info.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/asm-i386/thread_info.h	2003-07-19 17:03:50.000000000 -0700
-@@ -87,8 +87,8 @@ static inline struct thread_info *curren
- 
- /* thread information allocation */
- #define THREAD_SIZE (2*PAGE_SIZE)
--#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
--#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-+#define alloc_thread_info(task) ((struct thread_info *)kmalloc(THREAD_SIZE, GFP_KERNEL))
-+#define free_thread_info(info)	kfree(info)
- #define get_thread_info(ti) get_task_struct((ti)->task)
- #define put_thread_info(ti) put_task_struct((ti)->task)
- 
---- linux-2.6.0-test1/include/asm-i386/topology.h	2003-06-14 12:17:59.000000000 -0700
-+++ 25/include/asm-i386/topology.h	2003-07-19 17:04:07.000000000 -0700
-@@ -31,9 +31,11 @@
- 
- #include <asm/mpspec.h>
- 
-+#include <linux/cpumask.h>
-+
- /* Mappings between logical cpu number and node number */
--extern volatile unsigned long node_2_cpu_mask[];
--extern volatile int cpu_2_node[];
-+extern cpumask_t node_2_cpu_mask[];
-+extern int cpu_2_node[];
- 
- /* Returns the number of the node containing CPU 'cpu' */
- static inline int cpu_to_node(int cpu)
-@@ -49,7 +51,7 @@ static inline int cpu_to_node(int cpu)
- #define parent_node(node) (node)
- 
- /* Returns a bitmask of CPUs on Node 'node'. */
--static inline unsigned long node_to_cpumask(int node)
-+static inline cpumask_t node_to_cpumask(int node)
- {
- 	return node_2_cpu_mask[node];
- }
-@@ -57,14 +59,15 @@ static inline unsigned long node_to_cpum
- /* Returns the number of the first CPU on Node 'node'. */
- static inline int node_to_first_cpu(int node)
- { 
--	return __ffs(node_to_cpumask(node));
-+	cpumask_t mask = node_to_cpumask(node);
-+	return first_cpu(mask);
- }
- 
- /* Returns the number of the first MemBlk on Node 'node' */
- #define node_to_memblk(node) (node)
- 
- /* Returns the number of the node containing PCI bus 'bus' */
--static inline unsigned long pcibus_to_cpumask(int bus)
-+static inline cpumask_t pcibus_to_cpumask(int bus)
- {
- 	return node_to_cpumask(mp_bus_id_to_node[bus]);
- }
---- linux-2.6.0-test1/include/asm-i386/unistd.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/asm-i386/unistd.h	2003-07-19 17:06:37.000000000 -0700
-@@ -277,8 +277,9 @@
- #define __NR_fstatfs64		269
- #define __NR_tgkill		270
- #define __NR_utimes		271
-+#define __NR_mknod64		272
- 
--#define NR_syscalls 272
-+#define NR_syscalls 273
- 
- /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
- 
---- linux-2.6.0-test1/include/asm-ia64/atomic.h	2003-06-14 12:17:59.000000000 -0700
-+++ 25/include/asm-ia64/atomic.h	2003-07-19 17:03:50.000000000 -0700
-@@ -9,7 +9,7 @@
-  * "int" types were carefully placed so as to ensure proper operation
-  * of the macros.
-  *
-- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
-+ * Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co
-  *	David Mosberger-Tang <davidm@hpl.hp.com>
-  */
- #include <linux/types.h>
-@@ -21,11 +21,16 @@
-  * memory accesses are ordered.
-  */
- typedef struct { volatile __s32 counter; } atomic_t;
-+typedef struct { volatile __s64 counter; } atomic64_t;
- 
- #define ATOMIC_INIT(i)		((atomic_t) { (i) })
-+#define ATOMIC64_INIT(i)	((atomic64_t) { (i) })
- 
- #define atomic_read(v)		((v)->counter)
-+#define atomic64_read(v)	((v)->counter)
-+
- #define atomic_set(v,i)		(((v)->counter) = (i))
-+#define atomic64_set(v,i)	(((v)->counter) = (i))
- 
- static __inline__ int
- ia64_atomic_add (int i, atomic_t *v)
-@@ -37,7 +42,21 @@ ia64_atomic_add (int i, atomic_t *v)
- 		CMPXCHG_BUGCHECK(v);
- 		old = atomic_read(v);
- 		new = old + i;
--	} while (ia64_cmpxchg("acq", v, old, old + i, sizeof(atomic_t)) != old);
-+	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
-+	return new;
-+}
-+
-+static __inline__ int
-+ia64_atomic64_add (int i, atomic64_t *v)
-+{
-+	__s64 old, new;
-+	CMPXCHG_BUGCHECK_DECL
-+
-+	do {
-+		CMPXCHG_BUGCHECK(v);
-+		old = atomic_read(v);
-+		new = old + i;
-+	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
- 	return new;
- }
- 
-@@ -55,6 +74,20 @@ ia64_atomic_sub (int i, atomic_t *v)
- 	return new;
- }
- 
-+static __inline__ int
-+ia64_atomic64_sub (int i, atomic64_t *v)
-+{
-+	__s64 old, new;
-+	CMPXCHG_BUGCHECK_DECL
-+
-+	do {
-+		CMPXCHG_BUGCHECK(v);
-+		old = atomic_read(v);
-+		new = old - i;
-+	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
-+	return new;
-+}
-+
- #define atomic_add_return(i,v)						\
- ({									\
- 	int __ia64_aar_i = (i);						\
-@@ -67,6 +100,18 @@ ia64_atomic_sub (int i, atomic_t *v)
- 		: ia64_atomic_add(__ia64_aar_i, v);			\
- })
- 
-+#define atomic64_add_return(i,v)					\
-+({									\
-+	long __ia64_aar_i = (i);					\
-+	(__builtin_constant_p(i)					\
-+	 && (   (__ia64_aar_i ==  1) || (__ia64_aar_i ==   4)		\
-+	     || (__ia64_aar_i ==  8) || (__ia64_aar_i ==  16)		\
-+	     || (__ia64_aar_i == -1) || (__ia64_aar_i ==  -4)		\
-+	     || (__ia64_aar_i == -8) || (__ia64_aar_i == -16)))		\
-+		? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter)	\
-+		: ia64_atomic64_add(__ia64_aar_i, v);			\
-+})
-+
- /*
-  * Atomically add I to V and return TRUE if the resulting value is
-  * negative.
-@@ -77,6 +122,12 @@ atomic_add_negative (int i, atomic_t *v)
- 	return atomic_add_return(i, v) < 0;
- }
- 
-+static __inline__ int
-+atomic64_add_negative (int i, atomic64_t *v)
-+{
-+	return atomic64_add_return(i, v) < 0;
-+}
-+
- #define atomic_sub_return(i,v)						\
- ({									\
- 	int __ia64_asr_i = (i);						\
-@@ -89,18 +140,40 @@ atomic_add_negative (int i, atomic_t *v)
- 		: ia64_atomic_sub(__ia64_asr_i, v);			\
- })
- 
-+#define atomic64_sub_return(i,v)					\
-+({									\
-+	long __ia64_asr_i = (i);					\
-+	(__builtin_constant_p(i)					\
-+	 && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)		\
-+	     || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)		\
-+	     || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)		\
-+	     || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))	\
-+		? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)	\
-+		: ia64_atomic64_sub(__ia64_asr_i, v);			\
-+})
-+
- #define atomic_dec_return(v)		atomic_sub_return(1, (v))
- #define atomic_inc_return(v)		atomic_add_return(1, (v))
-+#define atomic64_dec_return(v)		atomic64_sub_return(1, (v))
-+#define atomic64_inc_return(v)		atomic64_add_return(1, (v))
- 
- #define atomic_sub_and_test(i,v)	(atomic_sub_return((i), (v)) == 0)
- #define atomic_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
- #define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) != 0)
-+#define atomic64_sub_and_test(i,v)	(atomic64_sub_return((i), (v)) == 0)
-+#define atomic64_dec_and_test(v)	(atomic64_sub_return(1, (v)) == 0)
-+#define atomic64_inc_and_test(v)	(atomic64_add_return(1, (v)) != 0)
- 
- #define atomic_add(i,v)			atomic_add_return((i), (v))
- #define atomic_sub(i,v)			atomic_sub_return((i), (v))
- #define atomic_inc(v)			atomic_add(1, (v))
- #define atomic_dec(v)			atomic_sub(1, (v))
- 
-+#define atomic64_add(i,v)		atomic64_add_return((i), (v))
-+#define atomic64_sub(i,v)		atomic64_sub_return((i), (v))
-+#define atomic64_inc(v)			atomic64_add(1, (v))
-+#define atomic64_dec(v)			atomic64_sub(1, (v))
-+
- /* Atomic operations are already serializing */
- #define smp_mb__before_atomic_dec()	barrier()
- #define smp_mb__after_atomic_dec()	barrier()
---- linux-2.6.0-test1/include/asm-ia64/bitops.h	2003-06-14 12:18:33.000000000 -0700
-+++ 25/include/asm-ia64/bitops.h	2003-07-19 17:04:07.000000000 -0700
-@@ -409,7 +409,7 @@ found_middle:
-  * Find next bit in a bitmap reasonably efficiently..
-  */
- static inline int
--find_next_bit (void *addr, unsigned long size, unsigned long offset)
-+find_next_bit(const void *addr, unsigned long size, unsigned long offset)
- {
- 	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- 	unsigned long result = offset & ~63UL;
---- linux-2.6.0-test1/include/asm-ia64/elf.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ia64/elf.h	2003-07-19 17:03:50.000000000 -0700
-@@ -199,11 +199,11 @@ extern int dump_task_fpu (struct task_st
- 
- #define GATE_EHDR	((const struct elfhdr *) GATE_ADDR)
- 
--#define ARCH_DLINFO							\
--do {									\
--	extern char __kernel_syscall_via_epc[];				\
--	NEW_AUX_ENT(AT_SYSINFO, __kernel_syscall_via_epc);		\
--	NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);	\
-+#define ARCH_DLINFO								\
-+do {										\
-+	extern char __kernel_syscall_via_epc[];					\
-+	NEW_AUX_ENT(AT_SYSINFO, (unsigned long) __kernel_syscall_via_epc);	\
-+	NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);		\
- } while (0)
- 
- /*
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-ia64/local.h	2003-07-19 17:03:50.000000000 -0700
-@@ -0,0 +1,50 @@
-+#ifndef _ASM_IA64_LOCAL_H
-+#define _ASM_IA64_LOCAL_H
-+
-+/*
-+ * Copyright (C) 2003 Hewlett-Packard Co
-+ *	David Mosberger-Tang <davidm@hpl.hp.com>
-+ */
-+
-+#include <linux/percpu.h>
-+
-+typedef struct {
-+	atomic64_t val;
-+} local_t;
-+
-+#define LOCAL_INIT(i)	((local_t) { { (i) } })
-+#define local_read(l)	atomic64_read(&(l)->val)
-+#define local_set(l, i)	atomic64_set(&(l)->val, i)
-+#define local_inc(l)	atomic64_inc(&(l)->val)
-+#define local_dec(l)	atomic64_dec(&(l)->val)
-+#define local_add(l)	atomic64_add(&(l)->val)
-+#define local_sub(l)	atomic64_sub(&(l)->val)
-+
-+/* Non-atomic variants, i.e., preemption disabled and won't be touched in interrupt, etc.  */
-+
-+#define __local_inc(l)		(++(l)->val.counter)
-+#define __local_dec(l)		(--(l)->val.counter)
-+#define __local_add(i,l)	((l)->val.counter += (i))
-+#define __local_sub(i,l)	((l)->val.counter -= (i))
-+
-+/*
-+ * Use these for per-cpu local_t variables.  Note they take a variable (eg. mystruct.foo),
-+ * not an address.
-+ */
-+#define cpu_local_read(v)	local_read(&__ia64_per_cpu_var(v))
-+#define cpu_local_set(v, i)	local_set(&__ia64_per_cpu_var(v), (i))
-+#define cpu_local_inc(v)	local_inc(&__ia64_per_cpu_var(v))
-+#define cpu_local_dec(v)	local_dec(&__ia64_per_cpu_var(v))
-+#define cpu_local_add(i, v)	local_add((i), &__ia64_per_cpu_var(v))
-+#define cpu_local_sub(i, v)	local_sub((i), &__ia64_per_cpu_var(v))
-+
-+/*
-+ * Non-atomic increments, i.e., preemption disabled and won't be touched in interrupt,
-+ * etc.
-+ */
-+#define __cpu_local_inc(v)	__local_inc(&__ia64_per_cpu_var(v))
-+#define __cpu_local_dec(v)	__local_dec(&__ia64_per_cpu_var(v))
-+#define __cpu_local_add(i, v)	__local_add((i), &__ia64_per_cpu_var(v))
-+#define __cpu_local_sub(i, v)	__local_sub((i), &__ia64_per_cpu_var(v))
-+
-+#endif /* _ASM_IA64_LOCAL_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-ia64/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,72 @@
-+/*
-+ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ */
-+
-+#ifndef _IA64_LOCKMETER_H
-+#define _IA64_LOCKMETER_H
-+
-+#ifdef local_cpu_data
-+#define CPU_CYCLE_FREQUENCY	local_cpu_data->itc_freq
-+#else
-+#define CPU_CYCLE_FREQUENCY	my_cpu_data.itc_freq
-+#endif
-+#define get_cycles64()		get_cycles()
-+
-+#define THIS_CPU_NUMBER		smp_processor_id()
-+
-+/*
-+ * macros to cache and retrieve an index value inside of a lock
-+ * these macros assume that there are less than 65536 simultaneous
-+ * (read mode) holders of a rwlock.
-+ * we also assume that the hash table has less than 32767 entries.
-+ */
-+/*
-+ * instrumented spinlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a spinlock_t
-+ */
-+typedef struct inst_spinlock_s {
-+	/* remember, Intel is little endian */
-+	volatile unsigned short lock;
-+	volatile unsigned short index;
-+} inst_spinlock_t;
-+#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
-+#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
-+
-+/*
-+ * macros to cache and retrieve an index value in a read/write lock
-+ * as well as the cpu where a reader busy period started
-+ * we use the 2nd word (the debug word) for this, so require the
-+ * debug word to be present
-+ */
-+/*
-+ * instrumented rwlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a rwlock_t
-+ */
-+typedef struct inst_rwlock_s {
-+	volatile int read_counter:31;
-+	volatile int write_lock:1;
-+	volatile unsigned short index;
-+	volatile unsigned short cpu;
-+} inst_rwlock_t;
-+#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
-+#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
-+#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
-+
-+/*
-+ * return the number of readers for a rwlock_t
-+ */
-+#define RWLOCK_READERS(rwlock_ptr)	((rwlock_ptr)->read_counter)
-+
-+/*
-+ * return true if rwlock is write locked
-+ * (note that other lock attempts can cause the lock value to be negative)
-+ */
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->write_lock)
-+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->read_counter)
-+
-+#endif /* _IA64_LOCKMETER_H */
-+
---- linux-2.6.0-test1/include/asm-ia64/mmu_context.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-ia64/mmu_context.h	2003-07-19 17:03:50.000000000 -0700
-@@ -86,9 +86,9 @@ delayed_tlb_flush (void)
- {
- 	extern void local_flush_tlb_all (void);
- 
--	if (unlikely(__get_cpu_var(ia64_need_tlb_flush))) {
-+	if (unlikely(__ia64_per_cpu_var(ia64_need_tlb_flush))) {
- 		local_flush_tlb_all();
--		__get_cpu_var(ia64_need_tlb_flush) = 0;
-+		__ia64_per_cpu_var(ia64_need_tlb_flush) = 0;
- 	}
- }
- 
---- linux-2.6.0-test1/include/asm-ia64/percpu.h	2003-06-14 12:18:29.000000000 -0700
-+++ 25/include/asm-ia64/percpu.h	2003-07-19 17:03:50.000000000 -0700
-@@ -1,43 +1,73 @@
- #ifndef _ASM_IA64_PERCPU_H
- #define _ASM_IA64_PERCPU_H
- 
--#include <linux/config.h>
--#include <linux/compiler.h>
--
- /*
-  * Copyright (C) 2002-2003 Hewlett-Packard Co
-  *	David Mosberger-Tang <davidm@hpl.hp.com>
-  */
-+
- #define PERCPU_ENOUGH_ROOM PERCPU_PAGE_SIZE
- 
- #ifdef __ASSEMBLY__
--
--#define THIS_CPU(var)	(var##__per_cpu)  /* use this to mark accesses to per-CPU variables... */
--
-+# define THIS_CPU(var)	(per_cpu__##var)  /* use this to mark accesses to per-CPU variables... */
- #else /* !__ASSEMBLY__ */
- 
-+#include <linux/config.h>
-+
- #include <linux/threads.h>
- 
--extern unsigned long __per_cpu_offset[NR_CPUS];
-+#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
-+# define __SMALL_ADDR_AREA	__attribute__((__model__ (__small__)))
-+#else
-+# define __SMALL_ADDR_AREA
-+#endif
- 
--#define DEFINE_PER_CPU(type, name) \
--    __attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
--#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
-+#define DECLARE_PER_CPU(type, name)				\
-+	extern __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name
- 
--#define __get_cpu_var(var)	(var##__per_cpu)
-+/* Separate out the type, so (int[3], foo) works. */
-+#define DEFINE_PER_CPU(type, name)				\
-+	__attribute__((__section__(".data.percpu")))		\
-+	__SMALL_ADDR_AREA __typeof__(type) per_cpu__##name
-+
-+/*
-+ * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an
-+ * external routine, to avoid include-hell.
-+ */
- #ifdef CONFIG_SMP
--# define per_cpu(var, cpu)	(*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))
-+
-+extern unsigned long __per_cpu_offset[NR_CPUS];
-+
-+/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
-+DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
-+
-+#define per_cpu(var, cpu)  (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
-+#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
- 
- extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
--#else
--# define per_cpu(var, cpu)	((void)cpu, __get_cpu_var(var))
--#endif
- 
--#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
--#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
-+#else /* ! SMP */
-+
-+#define per_cpu(var, cpu)			((void)cpu, per_cpu__##var)
-+#define __get_cpu_var(var)			per_cpu__##var
-+
-+#endif	/* SMP */
-+
-+#define EXPORT_PER_CPU_SYMBOL(var)		EXPORT_SYMBOL(per_cpu__##var)
-+#define EXPORT_PER_CPU_SYMBOL_GPL(var)		EXPORT_SYMBOL_GPL(per_cpu__##var)
-+
-+/* ia64-specific part: */
- 
- extern void setup_per_cpu_areas (void);
- 
-+/*
-+ * Be extremely careful when taking the address of this variable!  Due to virtual
-+ * remapping, it is different from the canonical address returned by __get_cpu_var(var)!
-+ * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
-+ * more efficient.
-+ */
-+#define __ia64_per_cpu_var(var)	(per_cpu__##var)
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif /* _ASM_IA64_PERCPU_H */
---- linux-2.6.0-test1/include/asm-ia64/pgalloc.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ia64/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -71,9 +71,9 @@ pgd_free (pgd_t *pgd)
- }
- 
- static inline void
--pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, pmd_t *pmd)
-+pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, struct page *pmd)
- {
--	pgd_val(*pgd_entry) = __pa(pmd);
-+	pgd_val(*pgd_entry) = __pa(page_address(pmd));
- }
- 
- 
-@@ -90,8 +90,8 @@ pmd_alloc_one_fast (struct mm_struct *mm
- 	return (pmd_t *)ret;
- }
- 
--static inline pmd_t*
--pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
-+static inline pmd_t *
-+pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
- 	pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
- 
-@@ -100,9 +100,16 @@ pmd_alloc_one (struct mm_struct *mm, uns
- 	return pmd;
- }
- 
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	return pmd ? virt_to_page(pmd) : NULL;
-+}
-+
- static inline void
--pmd_free (pmd_t *pmd)
-+pmd_free(struct page *page)
- {
-+	pmd_t *pmd = page_address(page);
- 	*(unsigned long *)pmd = (unsigned long) pmd_quicklist;
- 	pmd_quicklist = (unsigned long *) pmd;
- 	++pgtable_cache_size;
---- linux-2.6.0-test1/include/asm-ia64/pgtable.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ia64/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -257,7 +257,8 @@ ia64_phys_addr_valid (unsigned long addr
- #define pgd_bad(pgd)			(!ia64_phys_addr_valid(pgd_val(pgd)))
- #define pgd_present(pgd)		(pgd_val(pgd) != 0UL)
- #define pgd_clear(pgdp)			(pgd_val(*(pgdp)) = 0UL)
--#define pgd_page(pgd)			((unsigned long) __va(pgd_val(pgd) & _PFN_MASK))
-+#define __pgd_page(pgd)			((unsigned long)__va(pgd_val(pgd) & _PFN_MASK))
-+#define pgd_page(pgd)			virt_to_page(__pgd_page(pgd))
- 
- /*
-  * The following have defined behavior only work if pte_present() is true.
-@@ -326,7 +327,13 @@ pgd_offset (struct mm_struct *mm, unsign
- 
- /* Find an entry in the second-level page table.. */
- #define pmd_offset(dir,addr) \
--	((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-+	((pmd_t *)__pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-+
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
- 
- /*
-  * Find an entry in the third-level page table.  This looks more complicated than it
---- linux-2.6.0-test1/include/asm-ia64/posix_types.h	2003-06-14 12:18:06.000000000 -0700
-+++ 25/include/asm-ia64/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -10,7 +10,9 @@
-  *	David Mosberger-Tang <davidm@hpl.hp.com>
-  */
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long	__kernel_dev_t;
-+#endif
- typedef unsigned int	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned int	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-ia64/processor.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-ia64/processor.h	2003-07-19 17:03:50.000000000 -0700
-@@ -191,10 +191,12 @@ struct cpuinfo_ia64 {
- DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info);
- 
- /*
-- * The "local" data pointer.  It points to the per-CPU data of the currently executing
-+ * The "local" data variable.  It refers to the per-CPU data of the currently executing
-  * CPU, much like "current" points to the per-task data of the currently executing task.
-+ * Do not use the address of local_cpu_data, since it will be different from
-+ * cpu_data(smp_processor_id())!
-  */
--#define local_cpu_data		(&__get_cpu_var(cpu_info))
-+#define local_cpu_data		(&__ia64_per_cpu_var(cpu_info))
- #define cpu_data(cpu)		(&per_cpu(cpu_info, cpu))
- 
- extern void identify_cpu (struct cpuinfo_ia64 *);
---- linux-2.6.0-test1/include/asm-ia64/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ia64/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -16,6 +16,7 @@
- #include <linux/init.h>
- #include <linux/threads.h>
- #include <linux/kernel.h>
-+#include <linux/cpumask.h>
- 
- #include <asm/bitops.h>
- #include <asm/io.h>
-@@ -37,8 +38,8 @@ extern struct smp_boot_data {
- 
- extern char no_int_routing __initdata;
- 
--extern unsigned long phys_cpu_present_map;
--extern volatile unsigned long cpu_online_map;
-+extern cpumask_t phys_cpu_present_map;
-+extern cpumask_t cpu_online_map;
- extern unsigned long ipi_base_addr;
- extern unsigned char smp_int_redirect;
- 
-@@ -47,22 +48,7 @@ extern volatile int ia64_cpu_to_sapicid[
- 
- extern unsigned long ap_wakeup_vector;
- 
--#define cpu_possible(cpu)	(phys_cpu_present_map & (1UL << (cpu)))
--#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
--
--static inline unsigned int
--num_online_cpus (void)
--{
--	return hweight64(cpu_online_map);
--}
--
--static inline unsigned int
--any_online_cpu (unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--	return NR_CPUS;
--}
-+#define cpu_possible(cpu)	cpu_isset(cpu, phys_cpu_present_map)
- 
- /*
-  * Function to map hard smp processor id to logical id.  Slow, so don't use this in
---- linux-2.6.0-test1/include/asm-ia64/spinlock.h	2003-06-26 22:07:25.000000000 -0700
-+++ 25/include/asm-ia64/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -120,8 +120,18 @@ _raw_spin_lock (spinlock_t *lock)
- typedef struct {
- 	volatile int read_counter	: 31;
- 	volatile int write_lock		:  1;
-+#ifdef CONFIG_LOCKMETER
-+	/* required for LOCKMETER since all bits in lock are used */
-+	/* and we need this storage for CPU and lock INDEX        */
-+	unsigned lockmeter_magic;
-+#endif
- } rwlock_t;
-+
-+#ifdef CONFIG_LOCKMETER
-+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
-+#else
- #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-+#endif
- 
- #define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while(0)
- #define rwlock_is_locked(x)	(*(volatile int *) (x) != 0)
-@@ -137,6 +147,48 @@ do {											\
- 	}										\
- } while (0)
- 
-+#ifdef CONFIG_LOCKMETER
-+/*
-+ * HACK: This works, but still have a timing window that affects performance:
-+ * we see that no one owns the Write lock, then someone * else grabs for Write
-+ * lock before we do a read_lock().
-+ * This means that on rare occasions our read_lock() will stall and spin-wait
-+ * until we acquire for Read, instead of simply returning a trylock failure.
-+ */
-+static inline int _raw_read_trylock(rwlock_t *rw)
-+{
-+	if (rw->write_lock) {
-+		return 0;
-+	} else {
-+		_raw_read_lock(rw);
-+		return 1;
-+	}
-+}
-+
-+static inline int _raw_write_trylock(rwlock_t *rw)
-+{
-+	if (!(rw->write_lock)) {
-+	    /* isn't currently write-locked... that looks promising... */
-+	    if (test_and_set_bit(31, rw) == 0) {
-+		/* now it is write-locked by me... */
-+		if (rw->read_counter) {
-+		    /* really read-locked, so release write-lock and fail */
-+		    clear_bit(31, rw);
-+		} else {
-+		    /* we've the the write-lock, no read-lockers... success! */
-+		    barrier();
-+		    return 1;
-+		}
-+
-+	    }
-+	}
-+
-+	/* falls through ... fails to write-lock */
-+	barrier();
-+	return 0;
-+}
-+#endif
-+
- #define _raw_read_unlock(rw)					\
- do {								\
- 	rwlock_t *__read_lock_ptr = (rw);			\
-@@ -181,4 +233,25 @@ do {										\
- 	clear_bit(31, (x));								\
- })
- 
-+#ifdef CONFIG_LOCKMETER
-+extern void _metered_spin_lock  (spinlock_t *lock);
-+extern void _metered_spin_unlock(spinlock_t *lock);
-+
-+/*
-+ *  Use a less efficient, and inline, atomic_dec_and_lock() if lockmetering
-+ *  so we can see the callerPC of who is actually doing the spin_lock().
-+ *  Otherwise, all we see is the generic rollup of all locks done by
-+ *  atomic_dec_and_lock().
-+ */
-+static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-+{
-+	_metered_spin_lock(lock);
-+	if (atomic_dec_and_test(atomic))
-+		return 1;
-+	_metered_spin_unlock(lock);
-+	return 0;
-+}
-+#define ATOMIC_DEC_AND_LOCK
-+#endif
-+
- #endif /*  _ASM_IA64_SPINLOCK_H */
---- linux-2.6.0-test1/include/asm-ia64/system.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ia64/system.h	2003-07-19 17:03:50.000000000 -0700
-@@ -20,9 +20,9 @@
- #include <asm/percpu.h>
- 
- /* 0xa000000000000000 - 0xa000000000000000+PERCPU_PAGE_SIZE remain unmapped */
--#define PERCPU_ADDR		(0xa000000000000000 + PERCPU_PAGE_SIZE)
--#define GATE_ADDR		(0xa000000000000000 + 2*PERCPU_PAGE_SIZE)
-+#define GATE_ADDR		(0xa000000000000000 + PERCPU_PAGE_SIZE)
- #define KERNEL_START		 0xa000000100000000
-+#define PERCPU_ADDR		(-PERCPU_PAGE_SIZE)
- 
- #ifndef __ASSEMBLY__
- 
---- linux-2.6.0-test1/include/asm-ia64/tlb.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-ia64/tlb.h	2003-07-19 17:03:50.000000000 -0700
-@@ -126,7 +126,7 @@ ia64_tlb_flush_mmu (struct mmu_gather *t
- static inline struct mmu_gather *
- tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
- {
--	struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
-+	struct mmu_gather *tlb = &__get_cpu_var(mmu_gathers);
- 
- 	tlb->mm = mm;
- 	/*
---- linux-2.6.0-test1/include/asm-m68k/motorola_pgalloc.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-m68k/motorola_pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -63,19 +63,28 @@ static inline void __pte_free_tlb(struct
- }
- 
- 
--static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-+static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
- {
- 	return get_pointer_table();
- }
- 
--static inline int pmd_free(pmd_t *pmd)
-+static inline struct page *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
--	return free_pointer_table(pmd);
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
- }
- 
--static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
-+static inline int pmd_free(struct page *pmd)
- {
--	return free_pointer_table(pmd);
-+	return free_pointer_table(page_address(pmd));
-+}
-+
-+static inline int __pmd_free_tlb(struct mmu_gather *tlb, struct page *pmd)
-+{
-+	return free_pointer_table(page_address(pmd));
- }
- 
- 
-@@ -100,9 +109,9 @@ static inline void pmd_populate(struct m
- 	pmd_set(pmd, page_address(page));
- }
- 
--static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd)
- {
--	pgd_set(pgd, pmd);
-+	pgd_set(pgd, page_address(pmd));
- }
- 
- #endif /* _MOTOROLA_PGALLOC_H */
---- linux-2.6.0-test1/include/asm-m68k/motorola_pgtable.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/include/asm-m68k/motorola_pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -115,6 +115,7 @@ extern inline void pgd_set(pgd_t * pgdp,
- #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
- #define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
- #define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
- 
- 
- #define pte_none(pte)		(!pte_val(pte))
-@@ -203,6 +204,12 @@ extern inline pmd_t * pmd_offset(pgd_t *
- 	return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- /* Find an entry in the third-level page table.. */ 
- extern inline pte_t * pte_offset_kernel(pmd_t * pmdp, unsigned long address)
- {
---- linux-2.6.0-test1/include/asm-m68knommu/pgtable.h	2003-06-14 12:18:23.000000000 -0700
-+++ 25/include/asm-m68knommu/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -21,7 +21,12 @@ typedef pte_t *pte_addr_t;
- #define pgd_bad(pgd)		(0)
- #define pgd_clear(pgdp)
- #define kern_addr_valid(addr)	(1)
--#define	pmd_offset(a, b)	((void *)0)
-+#define	pmd_offset(a, b)		((void *)0)
-+#define	pmd_offset_kernel(a, b)		pmd_offset(a, b)
-+#define	pmd_offset_map(a, b)		pmd_offset(a, b)
-+#define	pmd_offset_map_nested(a, b)	pmd_offset(a, b)
-+#define pmd_unmap(pmd)			do { } while (0)
-+#define pmd_unmap_nested(pmd)		do { } while (0)
- 
- #define PAGE_NONE	__pgprot(0)
- #define PAGE_SHARED	__pgprot(0)
---- linux-2.6.0-test1/include/asm-m68k/posix_types.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/asm-m68k/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned short	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-m68k/sun3_pgalloc.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-m68k/sun3_pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -18,7 +18,8 @@
- 
- extern const char bad_pmd_string[];
- 
--#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm,address)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm,address)	({ BUG(); ((pmd_t *)2); })
- 
- 
- static inline void pte_free_kernel(pte_t * pte)
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-mips64/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,120 @@
-+/*
-+ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ */
-+
-+#ifndef _ASM_LOCKMETER_H
-+#define _ASM_LOCKMETER_H
-+
-+#include <linux/time.h>
-+
-+#define SPINLOCK_MAGIC_INIT	/* */
-+
-+#define CPU_CYCLE_FREQUENCY	get_cpu_cycle_frequency()
-+
-+#define THIS_CPU_NUMBER		smp_processor_id()
-+
-+static uint32_t cpu_cycle_frequency = 0;
-+
-+static uint32_t get_cpu_cycle_frequency(void)
-+{
-+    /* a total hack, slow and invasive, but ... it works */
-+    int sec;
-+    uint32_t start_cycles;
-+    struct timeval tv;
-+
-+    if (cpu_cycle_frequency == 0) {	/* uninitialized */
-+	do_gettimeofday(&tv);
-+	sec = tv.tv_sec;	/* set up to catch the tv_sec rollover */
-+	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
-+	sec = tv.tv_sec;	/* rolled over to a new sec value */
-+	start_cycles = get_cycles();
-+	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
-+	cpu_cycle_frequency = get_cycles() - start_cycles;
-+    }
-+
-+    return cpu_cycle_frequency;
-+}
-+
-+extern struct timeval xtime;
-+extern long do_gettimeoffset(void);
-+
-+static uint64_t get_cycles64(void)
-+{
-+    static uint64_t last_get_cycles64 = 0;
-+    uint64_t ret;
-+    unsigned long sec;
-+    unsigned long usec, usec_offset;
-+
-+again:
-+    sec  = xtime.tv_sec;
-+    usec = xtime.tv_usec;
-+    usec_offset = do_gettimeoffset();
-+    if ((xtime.tv_sec != sec)  ||
-+	(xtime.tv_usec != usec)||
-+	(usec_offset >= 20000))
-+	goto again;
-+
-+    ret =  ((uint64_t)sec * cpu_cycle_frequency)
-+	+ ( ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency) / 1000000 );
-+
-+    /* XXX why does time go backwards?  do_gettimeoffset?  general time adj? */
-+    if (ret <= last_get_cycles64)
-+	ret  = last_get_cycles64+1;
-+    last_get_cycles64 = ret;
-+
-+    return ret;
-+}
-+
-+/*
-+ * macros to cache and retrieve an index value inside of a lock
-+ * these macros assume that there are less than 65536 simultaneous
-+ * (read mode) holders of a rwlock.
-+ * we also assume that the hash table has less than 32767 entries.
-+ * the high order bit is used for write locking a rw_lock
-+ */
-+#define INDEX_MASK   0x7FFF0000
-+#define READERS_MASK 0x0000FFFF
-+#define INDEX_SHIFT 16
-+#define PUT_INDEX(lockp,index)   \
-+        lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
-+#define GET_INDEX(lockp) \
-+        (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
-+
-+/*
-+ * macros to cache and retrieve an index value in a read/write lock
-+ * as well as the cpu where a reader busy period started
-+ * we use the 2nd word (the debug word) for this, so require the
-+ * debug word to be present
-+ */
-+/*
-+ * instrumented rwlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a rwlock_t
-+ */
-+typedef struct inst_rwlock_s {
-+	volatile int lock;
-+	unsigned short index;
-+	unsigned short cpu;
-+} inst_rwlock_t;
-+#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
-+#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
-+#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
-+
-+/*
-+ * return the number of readers for a rwlock_t
-+ */
-+#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
-+
-+extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
-+{
-+	int tmp = (int) rwlock_ptr->lock;
-+	return (tmp >= 0) ? tmp : 0;
-+}
-+
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
-+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->lock > 0)
-+
-+#endif /* _ASM_LOCKMETER_H */
---- linux-2.6.0-test1/include/asm-mips64/pgalloc.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips64/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -28,7 +28,7 @@ static inline void pmd_populate(struct m
- 	set_pmd(pmd, __pmd((PAGE_OFFSET + page_to_pfn(pte)) << PAGE_SHIFT));
- }
- 
--#define pgd_populate(mm, pgd, pmd)		set_pgd(pgd, __pgd(pmd))
-+#define pgd_populate(mm, pgd, pmd)		set_pgd(pgd, __pgd(page_address(pmd)))
- 
- static inline pgd_t *pgd_alloc(struct mm_struct *mm)
- {
-@@ -88,7 +88,7 @@ static inline void pte_free(struct page 
- #define __pte_free_tlb(tlb,pte)		tlb_remove_page((tlb),(pte))
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- 
--static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-+static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
- 	pmd_t *pmd;
- 
-@@ -98,9 +98,18 @@ static inline pmd_t *pmd_alloc_one(struc
- 	return pmd;
- }
- 
--static inline void pmd_free(pmd_t *pmd)
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
- {
--	free_pages((unsigned long)pmd, PMD_ORDER);
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
-+static inline void pmd_free(struct page *pmd)
-+{
-+	__free_pages(pmd, PMD_ORDER);
- }
- 
- extern pte_t kptbl[(PAGE_SIZE << PGD_ORDER)/sizeof(pte_t)];
---- linux-2.6.0-test1/include/asm-mips64/pgtable.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips64/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -155,11 +155,13 @@ extern pmd_t empty_bad_pmd_table[2*PAGE_
- #define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
- #define pmd_page_kernel(pmd)	pmd_val(pmd)
- 
--static inline unsigned long pgd_page(pgd_t pgd)
-+static inline unsigned long __pgd_page(pgd_t pgd)
- {
- 	return pgd_val(pgd);
- }
- 
-+#define pgd_page(pgd)		virt_to_page(__pgd_page(pgd))
-+
- static inline int pte_none(pte_t pte)
- {
- 	return !(pte_val(pte) & ~_PAGE_GLOBAL);
-@@ -397,10 +399,16 @@ static inline pte_t pte_modify(pte_t pte
- /* Find an entry in the second-level page table.. */
- static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
- {
--	return (pmd_t *) pgd_page(*dir) +
-+	return (pmd_t *)__pgd_page(*dir) +
- 	       ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while(0)
-+#define pmd_unmap_nested(pmd)				do { } while(0)
-+
- /* Find an entry in the third-level page table.. */
- #define __pte_offset(address)						\
- 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
---- linux-2.6.0-test1/include/asm-mips64/posix_types.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips64/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -15,7 +15,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned int	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-mips64/smp.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips64/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -17,6 +17,7 @@
- 
- #include <linux/bitops.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <asm/atomic.h>
- 
- #define smp_processor_id()	(current_thread_info()->cpu)
-@@ -45,56 +46,17 @@ extern struct call_data_struct *call_dat
- #define SMP_RESCHEDULE_YOURSELF	0x1	/* XXX braindead */
- #define SMP_CALL_FUNCTION	0x2
- 
--#if (NR_CPUS <= _MIPS_SZLONG)
--
--typedef unsigned long   cpumask_t;
--
--#define CPUMASK_CLRALL(p)	(p) = 0
--#define CPUMASK_SETB(p, bit)	(p) |= 1UL << (bit)
--#define CPUMASK_CLRB(p, bit)	(p) &= ~(1UL << (bit))
--#define CPUMASK_TSTB(p, bit)	((p) & (1UL << (bit)))
--
--#elif (NR_CPUS <= 128)
--
--/*
-- * The foll should work till 128 cpus.
-- */
--#define CPUMASK_SIZE		(NR_CPUS/_MIPS_SZLONG)
--#define CPUMASK_INDEX(bit)	((bit) >> 6)
--#define CPUMASK_SHFT(bit)	((bit) & 0x3f)
--
--typedef struct {
--	unsigned long	_bits[CPUMASK_SIZE];
--} cpumask_t;
--
--#define	CPUMASK_CLRALL(p)	(p)._bits[0] = 0, (p)._bits[1] = 0
--#define CPUMASK_SETB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] |= \
--					(1UL << CPUMASK_SHFT(bit))
--#define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
--					~(1UL << CPUMASK_SHFT(bit))
--#define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
--					(1UL << CPUMASK_SHFT(bit)))
--
--#else
--#error cpumask macros only defined for 128p kernels
--#endif
--
- extern cpumask_t phys_cpu_present_map;
- extern cpumask_t cpu_online_map;
- 
--#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu)))
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--
--extern inline unsigned int num_online_cpus(void)
--{
--	return hweight32(cpu_online_map);
--}
-+#define cpu_possible(cpu) cpu_isset(cpu, phys_cpu_present_map)
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- 
--extern volatile unsigned long cpu_callout_map;
-+extern cpumask_t cpu_callout_map;
- /* We don't mark CPUs online until __cpu_up(), so we need another measure */
- static inline int num_booting_cpus(void)
- {
--	return hweight32(cpu_callout_map);
-+	return cpus_weight(cpu_callout_map);
- }
- 
- #endif /* CONFIG_SMP */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-mips/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,126 @@
-+/*
-+ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ *  Ported to mips32 for Asita Technologies
-+ *   by D.J. Barrow ( dj.barrow@asitatechnologies.com )
-+ */
-+#ifndef _ASM_LOCKMETER_H
-+#define _ASM_LOCKMETER_H
-+
-+/* do_gettimeoffset is a function pointer on mips */
-+/* & it is not included by <linux/time.h> */
-+#include <asm/time.h>
-+#include <linux/time.h>
-+#include <asm/div64.h>
-+
-+#define SPINLOCK_MAGIC_INIT	/* */
-+
-+#define CPU_CYCLE_FREQUENCY	get_cpu_cycle_frequency()
-+
-+#define THIS_CPU_NUMBER		smp_processor_id()
-+
-+static uint32_t cpu_cycle_frequency = 0;
-+
-+static uint32_t get_cpu_cycle_frequency(void)
-+{
-+    /* a total hack, slow and invasive, but ... it works */
-+    int sec;
-+    uint32_t start_cycles;
-+    struct timeval tv;
-+
-+    if (cpu_cycle_frequency == 0) {	/* uninitialized */
-+	do_gettimeofday(&tv);
-+	sec = tv.tv_sec;	/* set up to catch the tv_sec rollover */
-+	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
-+	sec = tv.tv_sec;	/* rolled over to a new sec value */
-+	start_cycles = get_cycles();
-+	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
-+	cpu_cycle_frequency = get_cycles() - start_cycles;
-+    }
-+
-+    return cpu_cycle_frequency;
-+}
-+
-+extern struct timeval xtime;
-+
-+static uint64_t get_cycles64(void)
-+{
-+    static uint64_t last_get_cycles64 = 0;
-+    uint64_t ret;
-+    unsigned long sec;
-+    unsigned long usec, usec_offset;
-+
-+again:
-+    sec  = xtime.tv_sec;
-+    usec = xtime.tv_usec;
-+    usec_offset = do_gettimeoffset();
-+    if ((xtime.tv_sec != sec)  ||
-+	(xtime.tv_usec != usec)||
-+	(usec_offset >= 20000))
-+	goto again;
-+
-+    ret = ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency);
-+    /* We can't do a normal 64 bit division on mips without libgcc.a */
-+    do_div(ret,1000000);
-+    ret +=  ((uint64_t)sec * cpu_cycle_frequency);
-+
-+    /* XXX why does time go backwards?  do_gettimeoffset?  general time adj? */
-+    if (ret <= last_get_cycles64)
-+	ret  = last_get_cycles64+1;
-+    last_get_cycles64 = ret;
-+
-+    return ret;
-+}
-+
-+/*
-+ * macros to cache and retrieve an index value inside of a lock
-+ * these macros assume that there are less than 65536 simultaneous
-+ * (read mode) holders of a rwlock.
-+ * we also assume that the hash table has less than 32767 entries.
-+ * the high order bit is used for write locking a rw_lock
-+ */
-+#define INDEX_MASK   0x7FFF0000
-+#define READERS_MASK 0x0000FFFF
-+#define INDEX_SHIFT 16
-+#define PUT_INDEX(lockp,index)   \
-+        lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
-+#define GET_INDEX(lockp) \
-+        (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
-+
-+/*
-+ * macros to cache and retrieve an index value in a read/write lock
-+ * as well as the cpu where a reader busy period started
-+ * we use the 2nd word (the debug word) for this, so require the
-+ * debug word to be present
-+ */
-+/*
-+ * instrumented rwlock structure -- never used to allocate storage
-+ * only used in macros below to overlay a rwlock_t
-+ */
-+typedef struct inst_rwlock_s {
-+	volatile int lock;
-+	unsigned short index;
-+	unsigned short cpu;
-+} inst_rwlock_t;
-+#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
-+#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
-+#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
-+
-+/*
-+ * return the number of readers for a rwlock_t
-+ */
-+#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
-+
-+extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
-+{
-+	int tmp = (int) rwlock_ptr->lock;
-+	return (tmp >= 0) ? tmp : 0;
-+}
-+
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
-+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->lock > 0)
-+
-+#endif /* _ASM_LOCKMETER_H */
---- linux-2.6.0-test1/include/asm-mips/pgalloc.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -96,7 +96,8 @@ static inline void pte_free(struct page 
-  * allocating and freeing a pmd is trivial: the 1-entry pmd is
-  * inside the pgd, so has no extra memory associated with it.
-  */
--#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)	({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)			do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- 
---- linux-2.6.0-test1/include/asm-mips/pgtable.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -374,6 +374,12 @@ static inline pmd_t *pmd_offset(pgd_t *d
- 	return (pmd_t *) dir;
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- /* Find an entry in the third-level page table.. */
- #define __pte_offset(address)						\
- 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
---- linux-2.6.0-test1/include/asm-mips/posix_types.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -14,7 +14,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned long	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-mips/smp.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -17,6 +17,7 @@
- 
- #include <linux/bitops.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <asm/atomic.h>
- 
- #define smp_processor_id()	(current_thread_info()->cpu)
-@@ -45,56 +46,17 @@ extern struct call_data_struct *call_dat
- #define SMP_RESCHEDULE_YOURSELF	0x1	/* XXX braindead */
- #define SMP_CALL_FUNCTION	0x2
- 
--#if (NR_CPUS <= _MIPS_SZLONG)
--
--typedef unsigned long   cpumask_t;
--
--#define CPUMASK_CLRALL(p)	(p) = 0
--#define CPUMASK_SETB(p, bit)	(p) |= 1UL << (bit)
--#define CPUMASK_CLRB(p, bit)	(p) &= ~(1UL << (bit))
--#define CPUMASK_TSTB(p, bit)	((p) & (1UL << (bit)))
--
--#elif (NR_CPUS <= 128)
--
--/*
-- * The foll should work till 128 cpus.
-- */
--#define CPUMASK_SIZE		(NR_CPUS/_MIPS_SZLONG)
--#define CPUMASK_INDEX(bit)	((bit) >> 6)
--#define CPUMASK_SHFT(bit)	((bit) & 0x3f)
--
--typedef struct {
--	unsigned long	_bits[CPUMASK_SIZE];
--} cpumask_t;
--
--#define	CPUMASK_CLRALL(p)	(p)._bits[0] = 0, (p)._bits[1] = 0
--#define CPUMASK_SETB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] |= \
--					(1UL << CPUMASK_SHFT(bit))
--#define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
--					~(1UL << CPUMASK_SHFT(bit))
--#define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
--					(1UL << CPUMASK_SHFT(bit)))
--
--#else
--#error cpumask macros only defined for 128p kernels
--#endif
--
- extern cpumask_t phys_cpu_present_map;
- extern cpumask_t cpu_online_map;
- 
--#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu)))
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--
--extern inline unsigned int num_online_cpus(void)
--{
--	return hweight32(cpu_online_map);
--}
-+#define cpu_possible(cpu) cpu_isset(cpu, phys_cpu_present_map)
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- 
--extern volatile unsigned long cpu_callout_map;
-+extern cpumask_t cpu_callout_map;
- /* We don't mark CPUs online until __cpu_up(), so we need another measure */
- static inline int num_booting_cpus(void)
- {
--	return hweight32(cpu_callout_map);
-+	return cpus_weight(cpu_callout_map);
- }
- 
- #endif /* CONFIG_SMP */
---- linux-2.6.0-test1/include/asm-mips/spinlock.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-mips/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -91,9 +91,18 @@ static inline unsigned int _raw_spin_try
- 
- typedef struct {
- 	volatile unsigned int lock;
-+#ifdef CONFIG_LOCKMETER
-+	/* required for LOCKMETER since all bits in lock are used */
-+	/* and we need this storage for CPU and lock INDEX        */
-+	unsigned lockmeter_magic;
-+#endif
- } rwlock_t;
- 
-+#ifdef CONFIG_LOCKMETER
-+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
-+#else
- #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-+#endif
- 
- #define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
- 
---- linux-2.6.0-test1/include/asm-parisc/pgalloc.h	2003-06-14 12:18:35.000000000 -0700
-+++ 25/include/asm-parisc/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -28,12 +28,12 @@ static inline void pgd_free(pgd_t *pgd)
- 
- /* Three Level Page Table Support for pmd's */
- 
--static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd)
- {
--	pgd_val(*pgd) = _PAGE_TABLE + __pa((unsigned long)pmd);
-+	pgd_val(*pgd) = _PAGE_TABLE + __pa(page_address(pmd));
- }
- 
--static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-+static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
- 	pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
- 	if (pmd)
-@@ -41,9 +41,18 @@ static inline pmd_t *pmd_alloc_one(struc
- 	return pmd;
- }
- 
--static inline void pmd_free(pmd_t *pmd)
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
- {
--	free_page((unsigned long)pmd);
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
-+static inline void pmd_free(struct page *pmd)
-+{
-+	__free_page(pmd);
- }
- 
- #else
-@@ -55,7 +64,8 @@ static inline void pmd_free(pmd_t *pmd)
-  * inside the pgd, so has no extra memory associated with it.
-  */
- 
--#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)	pmd_alloc_one(mm, addr)
- #define pmd_free(x)			do { } while (0)
- #define pgd_populate(mm, pmd, pte)	BUG()
- 
---- linux-2.6.0-test1/include/asm-parisc/pgtable.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/asm-parisc/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -242,7 +242,8 @@ extern unsigned long *empty_zero_page;
- 
- 
- #ifdef __LP64__
--#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+#define __pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
- 
- /* For 64 bit we have three level tables */
- 
-@@ -339,11 +340,17 @@ extern inline pte_t pte_modify(pte_t pte
- 
- #ifdef __LP64__
- #define pmd_offset(dir,address) \
--((pmd_t *) pgd_page(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1)))
-+((pmd_t *)__pgd_page(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1)))
- #else
- #define pmd_offset(dir,addr) ((pmd_t *) dir)
- #endif
- 
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
-+
- /* Find an entry in the third-level page table.. */ 
- #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
- #define pte_offset_kernel(pmd, address) \
---- linux-2.6.0-test1/include/asm-parisc/posix_types.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-parisc/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -6,7 +6,9 @@
-  * be a little careful about namespace pollution etc.  Also, we cannot
-  * assume GCC is being used.
-  */
--typedef unsigned int		__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long		__kernel_ino_t;
- typedef unsigned short		__kernel_mode_t;
- typedef unsigned short		__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-parisc/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-parisc/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -14,9 +14,10 @@
- #ifndef ASSEMBLY
- #include <linux/bitops.h>
- #include <linux/threads.h>	/* for NR_CPUS */
-+#include <linux/cpumask.h>
- typedef unsigned long address_t;
- 
--extern volatile unsigned long cpu_online_map;
-+extern cpumask_t cpu_online_map;
- 
- 
- /*
-@@ -51,22 +52,10 @@ extern void smp_send_reschedule(int cpu)
- extern unsigned long cpu_present_mask;
- 
- #define smp_processor_id()	(current_thread_info()->cpu)
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- 
--#define cpu_possible(cpu)       (cpu_present_mask & (1<<(cpu)))
-+#define cpu_possible(cpu)       cpu_isset(cpu, cpu_present_mask)
- 
--extern inline unsigned int num_online_cpus(void)
--{
--	return hweight32(cpu_online_map);
--}
--
--extern inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS;
--}
- #endif /* CONFIG_SMP */
- 
- #define NO_PROC_ID		0xFF		/* No processor magic marker */
---- linux-2.6.0-test1/include/asm-ppc64/mmu_context.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-ppc64/mmu_context.h	2003-07-19 17:04:07.000000000 -0700
-@@ -143,7 +143,7 @@ switch_mm(struct mm_struct *prev, struct
- 	  struct task_struct *tsk)
- {
- 	flush_stab(tsk, next);
--	set_bit(smp_processor_id(), &next->cpu_vm_mask);
-+	cpu_set(smp_processor_id(), next->cpu_vm_mask);
- }
- 
- #define deactivate_mm(tsk,mm)	do { } while (0)
---- linux-2.6.0-test1/include/asm-ppc64/pgalloc.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-ppc64/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -26,10 +26,10 @@ pgd_free(pgd_t *pgd)
- 	free_page((unsigned long)pgd);
- }
- 
--#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
-+#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, page_address(PMD))
- 
- static inline pmd_t *
--pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
- 	pmd_t *pmd;
- 
-@@ -39,10 +39,19 @@ pmd_alloc_one(struct mm_struct *mm, unsi
- 	return pmd;
- }
- 
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
- static inline void
--pmd_free(pmd_t *pmd)
-+pmd_free(struct page *pmd)
- {
--	free_page((unsigned long)pmd);
-+	__free_page(pmd);
- }
- 
- #define __pmd_free_tlb(tlb, pmd)	pmd_free(pmd)
---- linux-2.6.0-test1/include/asm-ppc64/pgtable.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/asm-ppc64/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -190,7 +190,8 @@ extern unsigned long empty_zero_page[PAG
- #define pgd_bad(pgd)		((pgd_val(pgd)) == 0)
- #define pgd_present(pgd)	(pgd_val(pgd) != 0UL)
- #define pgd_clear(pgdp)		(pgd_val(*(pgdp)) = 0UL)
--#define pgd_page(pgd)		(__bpn_to_ba(pgd_val(pgd))) 
-+#define __pgd_page(pgd)		(__bpn_to_ba(pgd_val(pgd)))
-+#define pgd_page(pgd)		virt_to_page(__pgd_page(pgd))
- 
- /* 
-  * Find an entry in a page-table-directory.  We combine the address region 
-@@ -203,12 +204,18 @@ extern unsigned long empty_zero_page[PAG
- 
- /* Find an entry in the second-level page table.. */
- #define pmd_offset(dir,addr) \
--  ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-+  ((pmd_t *)__pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
- 
- /* Find an entry in the third-level page table.. */
- #define pte_offset_kernel(dir,addr) \
-   ((pte_t *) pmd_page_kernel(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
- 
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
-+
- #define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr))
- #define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir), (addr))
- #define pte_unmap(pte)			do { } while(0)
---- linux-2.6.0-test1/include/asm-ppc64/semaphore.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/asm-ppc64/semaphore.h	2003-07-19 17:04:51.000000000 -0700
-@@ -22,6 +22,7 @@ struct semaphore {
- 	 * sleeping on `wait'.
- 	 */
- 	atomic_t count;
-+	int sleepers;
- 	wait_queue_head_t wait;
- #ifdef WAITQUEUE_DEBUG
- 	long __magic;
-@@ -37,6 +38,7 @@ struct semaphore {
- 
- #define __SEMAPHORE_INITIALIZER(name, count) \
- 	{ ATOMIC_INIT(count), \
-+	  0, \
- 	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
- 	  __SEM_DEBUG_INIT(name) }
- 
-@@ -52,6 +54,7 @@ struct semaphore {
- static inline void sema_init (struct semaphore *sem, int val)
- {
- 	atomic_set(&sem->count, val);
-+	sem->sleepers = 0;
- 	init_waitqueue_head(&sem->wait);
- #ifdef WAITQUEUE_DEBUG
- 	sem->__magic = (long)&sem->__magic;
---- linux-2.6.0-test1/include/asm-ppc64/smp.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-ppc64/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -19,6 +19,7 @@
- 
- #include <linux/config.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <linux/kernel.h>
- 
- #ifdef CONFIG_SMP
-@@ -27,31 +28,13 @@
- 
- #include <asm/paca.h>
- 
--extern unsigned long cpu_online_map;
--
- extern void smp_message_pass(int target, int msg, unsigned long data, int wait);
- extern void smp_send_tlb_invalidate(int);
- extern void smp_send_xmon_break(int cpu);
- struct pt_regs;
- extern void smp_message_recv(int, struct pt_regs *);
- 
--#define cpu_online(cpu)	test_bit((cpu), &cpu_online_map)
--
- #define cpu_possible(cpu)	paca[cpu].active
--
--static inline unsigned int num_online_cpus(void)
--{
--	return hweight64(cpu_online_map);
--}
--
--static inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS;
--}
--
- #define smp_processor_id() (get_paca()->xPacaIndex)
- 
- /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
---- linux-2.6.0-test1/include/asm-ppc64/tlb.h	2003-06-14 12:18:07.000000000 -0700
-+++ 25/include/asm-ppc64/tlb.h	2003-07-19 17:04:07.000000000 -0700
-@@ -49,6 +49,7 @@ static inline void __tlb_remove_tlb_entr
- 	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu];
- 	unsigned long i = batch->index;
- 	pte_t pte;
-+	cpumask_t local_cpumask = cpumask_of_cpu(cpu);
- 
- 	if (pte_val(*ptep) & _PAGE_HASHPTE) {
- 		pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
-@@ -61,7 +62,7 @@ static inline void __tlb_remove_tlb_entr
- 			if (i == PPC64_TLB_BATCH_NR) {
- 				int local = 0;
- 
--				if (tlb->mm->cpu_vm_mask == (1UL << cpu))
-+				if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask))
- 					local = 1;
- 
- 				flush_hash_range(tlb->mm->context, i, local);
-@@ -78,8 +79,9 @@ static inline void tlb_flush(struct mmu_
- 	int cpu = smp_processor_id();
- 	struct ppc64_tlb_batch *batch = &ppc64_tlb_batch[cpu];
- 	int local = 0;
-+	cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
- 
--	if (tlb->mm->cpu_vm_mask == (1UL << smp_processor_id()))
-+	if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask))
- 		local = 1;
- 
- 	flush_hash_range(tlb->mm->context, batch->index, local);
---- linux-2.6.0-test1/include/asm-ppc/hardirq.h	2003-07-02 14:53:17.000000000 -0700
-+++ 25/include/asm-ppc/hardirq.h	2003-07-19 17:03:50.000000000 -0700
-@@ -14,8 +14,6 @@
-  */
- typedef struct {
- 	unsigned long __softirq_pending;	/* set_bit is used on this */
--	unsigned int __syscall_count;
--	struct task_struct * __ksoftirqd_task;
- 	unsigned int __last_jiffy_stamp;
- } ____cacheline_aligned irq_cpustat_t;
- 
---- linux-2.6.0-test1/include/asm-ppc/ipc.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-ppc/ipc.h	2003-07-19 17:03:50.000000000 -0700
-@@ -14,6 +14,7 @@ struct ipc_kludge {
- #define SEMOP		 1
- #define SEMGET		 2
- #define SEMCTL		 3
-+#define SEMTIMEDOP	 4
- #define MSGSND		11
- #define MSGRCV		12
- #define MSGGET		13
---- linux-2.6.0-test1/include/asm-ppc/pci.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ppc/pci.h	2003-07-19 17:03:50.000000000 -0700
-@@ -53,18 +53,12 @@ extern unsigned long phys_to_bus(unsigne
- extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr);
- extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
-     
--/* Dynamic DMA Mapping stuff, stolen from i386
-- * 	++ajoshi
-+/*
-+ * Dynamic DMA Mapping stuff
-+ * Originally stolen from i386 by ajoshi and updated by paulus
-+ * Non-consistent cache support by Dan Malek
-  */
- 
--#include <linux/types.h>
--#include <linux/slab.h>
--#include <linux/string.h>
--#include <asm/scatterlist.h>
--#include <asm/io.h>
--
--struct pci_dev;
--
- /* The PCI address space does equal the physical memory
-  * address space.  The networking and block device layers use
-  * this boolean for bounce buffer decisions.
-@@ -101,8 +95,7 @@ extern void pci_free_consistent(struct p
- static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
- 					size_t size, int direction)
- {
--	if (direction == PCI_DMA_NONE)
--		BUG();
-+	BUG_ON(direction == PCI_DMA_NONE);
- 
- 	consistent_sync(ptr, size, direction);
- 
-@@ -130,10 +123,11 @@ static inline void pci_unmap_single(stru
-  * to pci_map_single, but takes a struct page instead of a virtual address
-  */
- static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
--				      unsigned long offset, size_t size, int direction)
-+				      unsigned long offset, size_t size,
-+				      int direction)
- {
--	if (direction == PCI_DMA_NONE)
--		BUG();
-+	BUG_ON(direction == PCI_DMA_NONE);
-+	consistent_sync_page(page, offset, size, direction);
- 	return (page - mem_map) * PAGE_SIZE + PCI_DRAM_OFFSET + offset;
- }
- 
-@@ -171,10 +165,11 @@ static inline int pci_map_sg(struct pci_
- 	/*
- 	 * temporary 2.4 hack
- 	 */
--	for (i = 0; i < nents; i++) {
--		if (!sg[i].page)
--			BUG();
--		sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
-+	for (i = 0; i < nents; i++, sg++) {
-+		BUG_ON(!sg->page);
-+		consistent_sync_page(sg->page, sg->offset,
-+				     sg->length, direction);
-+		sg->dma_address = page_to_bus(sg->page) + sg->offset;
- 	}
- 
- 	return nents;
-@@ -187,8 +182,7 @@ static inline int pci_map_sg(struct pci_
- static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
- 				int nents, int direction)
- {
--	if (direction == PCI_DMA_NONE)
--		BUG();
-+	BUG_ON(direction == PCI_DMA_NONE);
- 	/* nothing to do */
- }
- 
-@@ -205,8 +199,7 @@ static inline void pci_dma_sync_single(s
- 				       dma_addr_t dma_handle,
- 				       size_t size, int direction)
- {
--	if (direction == PCI_DMA_NONE)
--		BUG();
-+	BUG_ON(direction == PCI_DMA_NONE);
- 
- 	consistent_sync(bus_to_virt(dma_handle), size, direction);
- }
-@@ -221,9 +214,13 @@ static inline void pci_dma_sync_sg(struc
- 				   struct scatterlist *sg,
- 				   int nelems, int direction)
- {
--	if (direction == PCI_DMA_NONE)
--		BUG();
--	/* nothing to do */
-+	int i;
-+
-+	BUG_ON(direction == PCI_DMA_NONE);
-+
-+	for (i = 0; i < nelems; i++, sg++)
-+		consistent_sync_page(sg->page, sg->offset,
-+				     sg->length, direction);
- }
- 
- /* Return whether the given PCI device DMA address mask can
---- linux-2.6.0-test1/include/asm-ppc/pgalloc.h	2003-06-14 12:17:55.000000000 -0700
-+++ 25/include/asm-ppc/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -15,7 +15,8 @@ extern void pgd_free(pgd_t *pgd);
-  * We don't have any real pmd's, and this code never triggers because
-  * the pgd will always be present..
-  */
--#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm,address)       ({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm,addr)   ({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)                     do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- #define pgd_populate(mm, pmd, pte)      BUG()
---- linux-2.6.0-test1/include/asm-ppc/pgtable.h	2003-06-14 12:18:01.000000000 -0700
-+++ 25/include/asm-ppc/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -370,8 +370,9 @@ static inline int pgd_bad(pgd_t pgd)		{ 
- static inline int pgd_present(pgd_t pgd)	{ return 1; }
- #define pgd_clear(xp)				do { } while (0)
- 
--#define pgd_page(pgd) \
-+#define __pgd_page(pgd) \
- 	((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
- 
- /*
-  * The following only work if pte_present() is true.
-@@ -503,6 +504,12 @@ static inline pmd_t * pmd_offset(pgd_t *
- 	return (pmd_t *) dir;
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- /* Find an entry in the third-level page table.. */
- #define pte_index(address)		\
- 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
---- linux-2.6.0-test1/include/asm-ppc/posix_types.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-ppc/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-ppc/processor.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-ppc/processor.h	2003-07-19 17:03:50.000000000 -0700
-@@ -705,6 +705,7 @@ struct thread_struct {
- 	.ksp = INIT_SP, \
- 	.fs = KERNEL_DS, \
- 	.pgdir = swapper_pg_dir, \
-+	.fpexc_mode = MSR_FE0 | MSR_FE1, \
- }
- 
- /*
---- linux-2.6.0-test1/include/asm-ppc/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-ppc/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -14,6 +14,7 @@
- #include <linux/kernel.h>
- #include <linux/bitops.h>
- #include <linux/errno.h>
-+#include <linux/cpumask.h>
- 
- #ifdef CONFIG_SMP
- 
-@@ -28,8 +29,8 @@ struct cpuinfo_PPC {
- };
- 
- extern struct cpuinfo_PPC cpu_data[];
--extern unsigned long cpu_online_map;
--extern unsigned long cpu_possible_map;
-+extern cpumask_t cpu_online_map;
-+extern cpumask_t cpu_possible_map;
- extern unsigned long smp_proc_in_lock[];
- extern volatile unsigned long cpu_callin_map[];
- extern int smp_tb_synchronized;
-@@ -45,21 +46,8 @@ extern void smp_local_timer_interrupt(st
- 
- #define smp_processor_id() (current_thread_info()->cpu)
- 
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--#define cpu_possible(cpu) (cpu_possible_map & (1<<(cpu)))
--
--extern inline unsigned int num_online_cpus(void)
--{
--	return hweight32(cpu_online_map);
--}
--
--extern inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS;
--}
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
-+#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map)
- 
- extern int __cpu_up(unsigned int cpu);
- 
---- linux-2.6.0-test1/include/asm-ppc/uaccess.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-ppc/uaccess.h	2003-07-19 17:03:51.000000000 -0700
-@@ -16,10 +16,13 @@
-  * get_fs() == KERNEL_DS, checking is bypassed.
-  *
-  * For historical reasons, these macros are grossly misnamed.
-+ *
-+ * The fs/ds values are now the highest legal address in the "segment".
-+ * This simplifies the checking in the routines below.
-  */
- 
--#define KERNEL_DS	((mm_segment_t) { 0 })
--#define USER_DS		((mm_segment_t) { 1 })
-+#define KERNEL_DS	((mm_segment_t) { ~0UL })
-+#define USER_DS		((mm_segment_t) { TASK_SIZE - 1 })
- 
- #define get_ds()	(KERNEL_DS)
- #define get_fs()	(current->thread.fs)
-@@ -27,14 +30,15 @@
- 
- #define segment_eq(a,b)	((a).seg == (b).seg)
- 
--#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
--#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
--#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
--#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
-+#define __access_ok(addr,size)						    \
-+	((addr) <= current->thread.fs.seg				    \
-+	 && ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr)))
-+
-+#define access_ok(type, addr, size) __access_ok((unsigned long)(addr),(size))
- 
- extern inline int verify_area(int type, const void __user * addr, unsigned long size)
- {
--	return access_ok(type,addr,size) ? 0 : -EFAULT;
-+	return access_ok(type, addr, size) ? 0 : -EFAULT;
- }
- 
- 
-@@ -303,7 +307,7 @@ extern int __strnlen_user(const char __u
-  */
- extern __inline__ int strnlen_user(const char __user *str, long len)
- {
--	unsigned long top = __kernel_ok? ~0UL: TASK_SIZE - 1;
-+	unsigned long top = current->thread.fs.seg;
- 
- 	if ((unsigned long)str > top)
- 		return 0;
---- linux-2.6.0-test1/include/asm-ppc/unistd.h	2003-06-16 22:32:21.000000000 -0700
-+++ 25/include/asm-ppc/unistd.h	2003-07-19 17:03:51.000000000 -0700
-@@ -253,177 +253,112 @@
- #define __NR_clock_gettime	246
- #define __NR_clock_getres	247
- #define __NR_clock_nanosleep	248
-+#define __NR_swapcontext	249
-+#define __NR_tgkill		250
-+#define __NR_utimes		251
-+#define __NR_statfs64		252
-+#define __NR_fstatfs64		253
- 
--#define __NR_syscalls		249
-+#define __NR_syscalls		254
- 
- #define __NR(n)	#n
- 
--#define __syscall_return(type) \
--	return (__sc_err & 0x10000000 ? errno = __sc_ret, __sc_ret = -1 : 0), \
--	       (type) __sc_ret
--
--#define __syscall_clobbers \
--	"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
-+/* On powerpc a system call basically clobbers the same registers like a
-+ * function call, with the exception of LR (which is needed for the
-+ * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
-+ * an error return status).
-+ */
- 
--#define _syscall0(type,name)						\
--type name(void)								\
--{									\
-+#define __syscall_nr(nr, type, name, args...)				\
- 	unsigned long __sc_ret, __sc_err;				\
- 	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--									\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0)		\
--			: __syscall_clobbers);				\
-+		register unsigned long __sc_0  __asm__ ("r0");		\
-+		register unsigned long __sc_3  __asm__ ("r3");		\
-+		register unsigned long __sc_4  __asm__ ("r4");		\
-+		register unsigned long __sc_5  __asm__ ("r5");		\
-+		register unsigned long __sc_6  __asm__ ("r6");		\
-+		register unsigned long __sc_7  __asm__ ("r7");		\
-+									\
-+		__sc_loadargs_##nr(name, args);				\
-+		__asm__ __volatile__					\
-+			("sc           \n\t"				\
-+			 "mfcr %0      "				\
-+			: "=&r" (__sc_0),				\
-+			  "=&r" (__sc_3),  "=&r" (__sc_4),		\
-+			  "=&r" (__sc_5),  "=&r" (__sc_6),		\
-+			  "=&r" (__sc_7)				\
-+			: __sc_asm_input_##nr				\
-+			: "cr0", "ctr", "memory",			\
-+			  "r8", "r9", "r10","r11", "r12");		\
- 		__sc_ret = __sc_3;					\
- 		__sc_err = __sc_0;					\
- 	}								\
--	__syscall_return (type);					\
-+	if (__sc_err & 0x10000000)					\
-+	{								\
-+		errno = __sc_ret;					\
-+		__sc_ret = -1;						\
-+	}								\
-+	return (type) __sc_ret
-+
-+#define __sc_loadargs_0(name, dummy...)					\
-+	__sc_0 = __NR_##name
-+#define __sc_loadargs_1(name, arg1)					\
-+	__sc_loadargs_0(name);						\
-+	__sc_3 = (unsigned long) (arg1)
-+#define __sc_loadargs_2(name, arg1, arg2)				\
-+	__sc_loadargs_1(name, arg1);					\
-+	__sc_4 = (unsigned long) (arg2)
-+#define __sc_loadargs_3(name, arg1, arg2, arg3)				\
-+	__sc_loadargs_2(name, arg1, arg2);				\
-+	__sc_5 = (unsigned long) (arg3)
-+#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)			\
-+	__sc_loadargs_3(name, arg1, arg2, arg3);			\
-+	__sc_6 = (unsigned long) (arg4)
-+#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)		\
-+	__sc_loadargs_4(name, arg1, arg2, arg3, arg4);			\
-+	__sc_7 = (unsigned long) (arg5)
-+
-+#define __sc_asm_input_0 "0" (__sc_0)
-+#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)
-+#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)
-+#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)
-+#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)
-+#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)
-+
-+#define _syscall0(type,name)						\
-+type name(void)								\
-+{									\
-+	__syscall_nr(0, type, name);					\
- }
- 
- #define _syscall1(type,name,type1,arg1)					\
- type name(type1 arg1)							\
- {									\
--	unsigned long __sc_ret, __sc_err;				\
--	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--									\
--		__sc_3 = (unsigned long) (arg1);			\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0)		\
--			: __syscall_clobbers);				\
--		__sc_ret = __sc_3;					\
--		__sc_err = __sc_0;					\
--	}								\
--	__syscall_return (type);					\
-+	__syscall_nr(1, type, name, arg1);				\
- }
- 
- #define _syscall2(type,name,type1,arg1,type2,arg2)			\
- type name(type1 arg1, type2 arg2)					\
- {									\
--	unsigned long __sc_ret, __sc_err;				\
--	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--		register unsigned long __sc_4 __asm__ ("r4");		\
--									\
--		__sc_3 = (unsigned long) (arg1);			\
--		__sc_4 = (unsigned long) (arg2);			\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0),		\
--			  "r"   (__sc_4)				\
--			: __syscall_clobbers);				\
--		__sc_ret = __sc_3;					\
--		__sc_err = __sc_0;					\
--	}								\
--	__syscall_return (type);					\
-+	__syscall_nr(2, type, name, arg1, arg2);			\
- }
- 
- #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
- type name(type1 arg1, type2 arg2, type3 arg3)				\
- {									\
--	unsigned long __sc_ret, __sc_err;				\
--	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--		register unsigned long __sc_4 __asm__ ("r4");		\
--		register unsigned long __sc_5 __asm__ ("r5");		\
--									\
--		__sc_3 = (unsigned long) (arg1);			\
--		__sc_4 = (unsigned long) (arg2);			\
--		__sc_5 = (unsigned long) (arg3);			\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0),		\
--			  "r"   (__sc_4),				\
--			  "r"   (__sc_5)				\
--			: __syscall_clobbers);				\
--		__sc_ret = __sc_3;					\
--		__sc_err = __sc_0;					\
--	}								\
--	__syscall_return (type);					\
-+	__syscall_nr(3, type, name, arg1, arg2, arg3);			\
- }
- 
- #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
- {									\
--	unsigned long __sc_ret, __sc_err;				\
--	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--		register unsigned long __sc_4 __asm__ ("r4");		\
--		register unsigned long __sc_5 __asm__ ("r5");		\
--		register unsigned long __sc_6 __asm__ ("r6");		\
--									\
--		__sc_3 = (unsigned long) (arg1);			\
--		__sc_4 = (unsigned long) (arg2);			\
--		__sc_5 = (unsigned long) (arg3);			\
--		__sc_6 = (unsigned long) (arg4);			\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0),		\
--			  "r"   (__sc_4),				\
--			  "r"   (__sc_5),				\
--			  "r"   (__sc_6)				\
--			: __syscall_clobbers);				\
--		__sc_ret = __sc_3;					\
--		__sc_err = __sc_0;					\
--	}								\
--	__syscall_return (type);					\
-+	__syscall_nr(4, type, name, arg1, arg2, arg3, arg4);		\
- }
- 
- #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
- {									\
--	unsigned long __sc_ret, __sc_err;				\
--	{								\
--		register unsigned long __sc_0 __asm__ ("r0");		\
--		register unsigned long __sc_3 __asm__ ("r3");		\
--		register unsigned long __sc_4 __asm__ ("r4");		\
--		register unsigned long __sc_5 __asm__ ("r5");		\
--		register unsigned long __sc_6 __asm__ ("r6");		\
--		register unsigned long __sc_7 __asm__ ("r7");		\
--									\
--		__sc_3 = (unsigned long) (arg1);			\
--		__sc_4 = (unsigned long) (arg2);			\
--		__sc_5 = (unsigned long) (arg3);			\
--		__sc_6 = (unsigned long) (arg4);			\
--		__sc_7 = (unsigned long) (arg5);			\
--		__sc_0 = __NR_##name;					\
--		__asm__ __volatile__					\
--			("sc           \n\t"				\
--			 "mfcr %1      "				\
--			: "=&r" (__sc_3), "=&r" (__sc_0)		\
--			: "0"   (__sc_3), "1"   (__sc_0),		\
--			  "r"   (__sc_4),				\
--			  "r"   (__sc_5),				\
--			  "r"   (__sc_6),				\
--			  "r"   (__sc_7)				\
--			: __syscall_clobbers);				\
--		__sc_ret = __sc_3;					\
--		__sc_err = __sc_0;					\
--	}								\
--	__syscall_return (type);					\
-+	__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);	\
- }
- 
- #ifdef __KERNEL__
---- linux-2.6.0-test1/include/asm-s390/bitops.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-s390/bitops.h	2003-07-19 17:04:07.000000000 -0700
-@@ -505,7 +505,7 @@ static inline int __test_bit(unsigned lo
- 	unsigned char ch;
- 
- 	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
--	ch = *(unsigned char *) addr;
-+	ch = *(volatile unsigned char *) addr;
- 	return (ch >> (nr & 7)) & 1;
- }
- 
---- linux-2.6.0-test1/include/asm-s390/dma.h	2003-06-14 12:18:33.000000000 -0700
-+++ 25/include/asm-s390/dma.h	2003-07-19 17:03:51.000000000 -0700
-@@ -2,8 +2,6 @@
-  *  include/asm-s390/dma.h
-  *
-  *  S390 version
-- *
-- *  This file exists so that an #include <dma.h> doesn't break anything.
-  */
- 
- #ifndef _ASM_DMA_H
---- linux-2.6.0-test1/include/asm-s390/dma-mapping.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-s390/dma-mapping.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1 +1,11 @@
--#include <asm-generic/dma-mapping.h>
-+/*
-+ *  include/asm-s390/dma-mapping.h
-+ *
-+ *  S390 version
-+ *
-+ *  This file exists so that #include <dma-mapping.h> doesn't break anything.
-+ */
-+
-+#ifndef _ASM_DMA_MAPPING_H
-+#define _ASM_DMA_MAPPING_H
-+#endif /* _ASM_DMA_MAPPING_H */
---- linux-2.6.0-test1/include/asm-s390/irq.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-s390/irq.h	2003-07-19 17:03:51.000000000 -0700
-@@ -8,16 +8,13 @@
-  * the definition of irqs has changed in 2.5.46:
-  * NR_IRQS is no longer the number of i/o
-  * interrupts (65536), but rather the number
-- * of interrupt classes (6).
-+ * of interrupt classes (2).
-+ * Only external and i/o interrupts make much sense here (CH).
-  */
- 
- enum interruption_class {
- 	EXTERNAL_INTERRUPT,
- 	IO_INTERRUPT,
--	MACHINE_CHECK_INTERRUPT,
--	PROGRAM_INTERRUPT,
--	RESTART_INTERRUPT,
--	SUPERVISOR_CALL,
- 
- 	NR_IRQS,
- };
---- linux-2.6.0-test1/include/asm-s390/mmu_context.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-s390/mmu_context.h	2003-07-19 17:04:07.000000000 -0700
-@@ -42,7 +42,7 @@ static inline void switch_mm(struct mm_s
-                              : : "m" (pgd) );
- #endif /* __s390x__ */
-         }
--	set_bit(smp_processor_id(), &next->cpu_vm_mask);
-+	cpu_set(smp_processor_id(), next->cpu_vm_mask);
- }
- 
- #define deactivate_mm(tsk,mm)	do { } while (0)
---- linux-2.6.0-test1/include/asm-s390/pgalloc.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/include/asm-s390/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -61,12 +61,13 @@ static inline void pgd_free(pgd_t *pgd)
-  * We use pmd cache only on s390x, so these are dummy routines. This
-  * code never triggers because the pgd will always be present.
-  */
--#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm,address)       ({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm,addr)   ({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)                     do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- #define pgd_populate(mm, pmd, pte)      BUG()
- #else /* __s390x__ */
--static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-+static inline pmd_t * pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
- {
- 	pmd_t *pmd;
-         int i;
-@@ -79,16 +80,25 @@ static inline pmd_t * pmd_alloc_one(stru
- 	return pmd;
- }
- 
--static inline void pmd_free (pmd_t *pmd)
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
- {
--	free_pages((unsigned long) pmd, 2);
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
-+static inline void pmd_free(struct page *pmd)
-+{
-+	__free_pages(pmd, 2);
- }
- 
- #define __pmd_free_tlb(tlb,pmd) pmd_free(pmd)
- 
--static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, struct page *pmd)
- {
--	pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
-+	pgd_val(*pgd) = _PGD_ENTRY | __pa(page_address(pmd));
- }
- 
- #endif /* __s390x__ */
---- linux-2.6.0-test1/include/asm-s390/pgtable.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-s390/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -613,6 +613,7 @@ static inline pte_t mk_pte_phys(unsigned
- /* to find an entry in a page-table-directory */
- #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
- #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
-+#define pgd_page(pgd)	virt_to_page(pgd_page_kernel(pgd))
- 
- /* to find an entry in a kernel page-table-directory */
- #define pgd_offset_k(address) pgd_offset(&init_mm, address)
-@@ -634,6 +635,12 @@ extern inline pmd_t * pmd_offset(pgd_t *
- 
- #endif /* __s390x__ */
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
-+
- /* Find an entry in the third-level page table.. */
- #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
- #define pte_offset_kernel(pmd, address) \
---- linux-2.6.0-test1/include/asm-s390/posix_types.h	2003-06-14 12:17:55.000000000 -0700
-+++ 25/include/asm-s390/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -34,7 +34,9 @@ typedef long long       __kernel_loff_t;
- 
- #ifndef __s390x__
- 
--typedef unsigned short  __kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long   __kernel_ino_t;
- typedef unsigned short  __kernel_mode_t;
- typedef unsigned short  __kernel_nlink_t;
-@@ -51,7 +53,9 @@ typedef unsigned short	__kernel_old_dev_
- 
- #else /* __s390x__ */
- 
--typedef unsigned int    __kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned int    __kernel_ino_t;
- typedef unsigned int    __kernel_mode_t;
- typedef unsigned int    __kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-s390/siginfo.h	2003-06-14 12:18:33.000000000 -0700
-+++ 25/include/asm-s390/siginfo.h	2003-07-19 17:03:51.000000000 -0700
-@@ -10,6 +10,9 @@
- #define _S390_SIGINFO_H
- 
- #define HAVE_ARCH_SI_CODES
-+#ifdef __s390x__
-+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-+#endif
- 
- #include <asm-generic/siginfo.h>
- 
---- linux-2.6.0-test1/include/asm-s390/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-s390/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -11,6 +11,7 @@
- 
- #include <linux/config.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <linux/bitops.h>
- 
- #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__)
-@@ -28,8 +29,8 @@ typedef struct
- 	__u16      cpu;
- } sigp_info;
- 
--extern volatile unsigned long cpu_online_map;
--extern volatile unsigned long cpu_possible_map;
-+extern cpumask_t cpu_online_map;
-+extern cpumask_t cpu_possible_map;
- 
- #define NO_PROC_ID		0xFF		/* No processor magic marker */
- 
-@@ -47,25 +48,8 @@ extern volatile unsigned long cpu_possib
- 
- #define smp_processor_id() (current_thread_info()->cpu)
- 
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--#define cpu_possible(cpu) (cpu_possible_map & (1<<(cpu)))
--
--extern inline unsigned int num_online_cpus(void)
--{
--#ifndef __s390x__
--	return hweight32(cpu_online_map);
--#else /* __s390x__ */
--	return hweight64(cpu_online_map);
--#endif /* __s390x__ */
--}
--
--extern inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS;
--}
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
-+#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map)
- 
- extern __inline__ __u16 hard_smp_processor_id(void)
- {
---- linux-2.6.0-test1/include/asm-s390/tlbflush.h	2003-06-14 12:18:49.000000000 -0700
-+++ 25/include/asm-s390/tlbflush.h	2003-07-19 17:04:07.000000000 -0700
-@@ -98,13 +98,15 @@ static inline void global_flush_tlb(void
- 
- static inline void __flush_tlb_mm(struct mm_struct * mm)
- {
-+	cpumask_t local_cpumask;
- 	preempt_disable();
--	if (mm->cpu_vm_mask != (1UL << smp_processor_id())) {
-+	local_cpumask = cpumask_of_cpu(smp_processor_id());
-+	if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) {
- 		/* mm was active on more than one cpu. */
- 		if (mm == current->active_mm &&
- 		    atomic_read(&mm->mm_users) == 1)
- 			/* this cpu is the only one using the mm. */
--			mm->cpu_vm_mask = 1UL << smp_processor_id();
-+			mm->cpu_vm_mask = local_cpumask;
- 		global_flush_tlb();
- 	} else
- 		local_flush_tlb();
---- linux-2.6.0-test1/include/asm-sh/pgalloc.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/asm-sh/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -94,7 +94,8 @@ static inline void pte_free(struct page 
-  * inside the pgd, so has no extra memory associated with it.
-  */
- 
--#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)	({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)		({ BUG(); ((struct page *)2); })
- #define pmd_free(x)			do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- #define pgd_populate(mm, pmd, pte)	BUG()
---- linux-2.6.0-test1/include/asm-sh/pgtable-2level.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/asm-sh/pgtable-2level.h	2003-07-19 17:07:16.000000000 -0700
-@@ -48,14 +48,21 @@ static inline void pgd_clear (pgd_t * pg
- #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
- #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
- 
--#define pgd_page(pgd) \
-+#define __pgd_page(pgd) \
- ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
- 
- static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
- {
- 	return (pmd_t *) dir;
- }
- 
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
-+
- #define pte_pfn(x)		((unsigned long)(((x).pte >> PAGE_SHIFT)))
- #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
- #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
---- linux-2.6.0-test1/include/asm-sh/posix_types.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/asm-sh/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
--typedef unsigned short	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned short	__kernel_mode_t;
- typedef unsigned short	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-sparc64/atomic.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/asm-sparc64/atomic.h	2003-07-19 17:03:51.000000000 -0700
-@@ -9,25 +9,46 @@
- #define __ARCH_SPARC64_ATOMIC__
- 
- typedef struct { volatile int counter; } atomic_t;
--#define ATOMIC_INIT(i)	{ (i) }
-+typedef struct { volatile long counter; } atomic64_t;
-+
-+#define ATOMIC_INIT(i)		{ (i) }
-+#define ATOMIC64_INIT(i)	{ (i) }
- 
- #define atomic_read(v)		((v)->counter)
-+#define atomic64_read(v)	((v)->counter)
-+
- #define atomic_set(v, i)	(((v)->counter) = i)
-+#define atomic64_set(v, i)	(((v)->counter) = i)
- 
- extern int __atomic_add(int, atomic_t *);
-+extern int __atomic64_add(int, atomic64_t *);
-+
- extern int __atomic_sub(int, atomic_t *);
-+extern int __atomic64_sub(int, atomic64_t *);
- 
- #define atomic_add(i, v) ((void)__atomic_add(i, v))
-+#define atomic64_add(i, v) ((void)__atomic64_add(i, v))
-+
- #define atomic_sub(i, v) ((void)__atomic_sub(i, v))
-+#define atomic64_sub(i, v) ((void)__atomic64_sub(i, v))
- 
- #define atomic_dec_return(v) __atomic_sub(1, v)
-+#define atomic64_dec_return(v) __atomic64_sub(1, v)
-+
- #define atomic_inc_return(v) __atomic_add(1, v)
-+#define atomic64_inc_return(v) __atomic64_add(1, v)
- 
- #define atomic_sub_and_test(i, v) (__atomic_sub(i, v) == 0)
-+#define atomic64_sub_and_test(i, v) (__atomic64_sub(i, v) == 0)
-+
- #define atomic_dec_and_test(v) (__atomic_sub(1, v) == 0)
-+#define atomic64_dec_and_test(v) (__atomic64_sub(1, v) == 0)
- 
- #define atomic_inc(v) ((void)__atomic_add(1, v))
-+#define atomic64_inc(v) ((void)__atomic64_add(1, v))
-+
- #define atomic_dec(v) ((void)__atomic_sub(1, v))
-+#define atomic64_dec(v) ((void)__atomic64_sub(1, v))
- 
- /* Atomic operations are already serializing */
- #define smp_mb__before_atomic_dec()	barrier()
---- linux-2.6.0-test1/include/asm-sparc64/bitops.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/asm-sparc64/bitops.h	2003-07-19 17:04:07.000000000 -0700
-@@ -156,6 +156,14 @@ static __inline__ int ffs(int x)
- 
- #ifdef ULTRA_HAS_POPULATION_COUNT
- 
-+static __inline__ unsigned int hweight64(unsigned long w)
-+{
-+	unsigned int res;
-+
-+	__asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
-+	return res;
-+}
-+
- static __inline__ unsigned int hweight32(unsigned int w)
- {
- 	unsigned int res;
-@@ -182,6 +190,7 @@ static __inline__ unsigned int hweight8(
- 
- #else
- 
-+#define hweight64(x) generic_hweight64(x)
- #define hweight32(x) generic_hweight32(x)
- #define hweight16(x) generic_hweight16(x)
- #define hweight8(x) generic_hweight8(x)
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-sparc64/local.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,40 @@
-+#ifndef _ARCH_SPARC64_LOCAL_H
-+#define _ARCH_SPARC64_LOCAL_H
-+
-+#include <linux/percpu.h>
-+#include <asm/atomic.h>
-+
-+typedef atomic64_t local_t;
-+
-+#define LOCAL_INIT(i)	ATOMIC64_INIT(i)
-+#define local_read(v)	atomic64_read(v)
-+#define local_set(v,i)	atomic64_set(v,i)
-+
-+#define local_inc(v)	atomic64_inc(v)
-+#define local_dec(v)	atomic64_inc(v)
-+#define local_add(i, v)	atomic64_add(i, v)
-+#define local_sub(i, v)	atomic64_sub(i, v)
-+
-+#define __local_inc(v)		((v)->counter++)
-+#define __local_dec(v)		((v)->counter++)
-+#define __local_add(i,v)	((v)->counter+=(i))
-+#define __local_sub(i,v)	((v)->counter-=(i))
-+
-+/* Use these for per-cpu local_t variables: on some archs they are
-+ * much more efficient than these naive implementations.  Note they take
-+ * a variable, not an address.
-+ */
-+#define cpu_local_read(v)	local_read(&__get_cpu_var(v))
-+#define cpu_local_set(v, i)	local_set(&__get_cpu_var(v), (i))
-+
-+#define cpu_local_inc(v)	local_inc(&__get_cpu_var(v))
-+#define cpu_local_dec(v)	local_dec(&__get_cpu_var(v))
-+#define cpu_local_add(i, v)	local_add((i), &__get_cpu_var(v))
-+#define cpu_local_sub(i, v)	local_sub((i), &__get_cpu_var(v))
-+
-+#define __cpu_local_inc(v)	__local_inc(&__get_cpu_var(v))
-+#define __cpu_local_dec(v)	__local_dec(&__get_cpu_var(v))
-+#define __cpu_local_add(i, v)	__local_add((i), &__get_cpu_var(v))
-+#define __cpu_local_sub(i, v)	__local_sub((i), &__get_cpu_var(v))
-+
-+#endif /* _ARCH_SPARC64_LOCAL_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-sparc64/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
-+ */
-+
-+#ifndef _SPARC64_LOCKMETER_H
-+#define _SPARC64_LOCKMETER_H
-+
-+#include <asm/spinlock.h>
-+
-+#include <linux/version.h>
-+
-+extern unsigned long cpu_hz;
-+#define CPU_CYCLE_FREQUENCY	cpu_hz
-+
-+#define THIS_CPU_NUMBER		__cpu_number_map[smp_processor_id()]
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-+#define local_irq_save(x)	__save_and_cli(x)
-+#define local_irq_restore(x)	__restore_flags(x)
-+#endif /* Linux version 2.2.x */
-+
-+#define PUT_INDEX(lock_ptr,indexv)	(lock_ptr)->index = (indexv)
-+#define GET_INDEX(lock_ptr)		(lock_ptr)->index
-+
-+#define PUT_RWINDEX(rwlock_ptr,indexv) (rwlock_ptr)->index = (indexv)
-+#define GET_RWINDEX(rwlock_ptr)        (rwlock_ptr)->index
-+#define PUT_RW_CPU(rwlock_ptr,cpuv)    (rwlock_ptr)->cpu = (cpuv)
-+#define GET_RW_CPU(rwlock_ptr)         (rwlock_ptr)->cpu
-+
-+#define RWLOCK_READERS(rwlock_ptr)	rwlock_readers(rwlock_ptr)
-+
-+extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
-+{
-+	signed int tmp = rwlock_ptr->lock;
-+
-+	if (tmp > 0)
-+		return tmp;
-+	else
-+		return 0;
-+}
-+
-+#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr)	((signed int)((rwlock_ptr)->lock) < 0)
-+#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)	((signed int)((rwlock_ptr)->lock) > 0)
-+
-+#define get_cycles64()	get_cycles()
-+
-+#endif /* _SPARC64_LOCKMETER_H */
---- linux-2.6.0-test1/include/asm-sparc64/mmu_context.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/asm-sparc64/mmu_context.h	2003-07-19 17:04:07.000000000 -0700
-@@ -125,7 +125,7 @@ static inline void switch_mm(struct mm_s
- 	}
- 
- 	{
--		unsigned long vm_mask = (1UL << smp_processor_id());
-+		int cpu = smp_processor_id();
- 
- 		/* Even if (mm == old_mm) we _must_ check
- 		 * the cpu_vm_mask.  If we do not we could
-@@ -133,8 +133,8 @@ static inline void switch_mm(struct mm_s
- 		 * smp_flush_tlb_{page,range,mm} on sparc64
- 		 * and lazy tlb switches work. -DaveM
- 		 */
--		if (!ctx_valid || !(mm->cpu_vm_mask & vm_mask)) {
--			mm->cpu_vm_mask |= vm_mask;
-+		if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
-+			cpu_set(cpu, mm->cpu_vm_mask);
- 			__flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
- 		}
- 	}
-@@ -148,14 +148,14 @@ extern void __flush_tlb_mm(unsigned long
- /* Activate a new MM instance for the current task. */
- static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
- {
--	unsigned long vm_mask;
-+	int cpu;
- 
- 	spin_lock(&mm->page_table_lock);
- 	if (!CTX_VALID(mm->context))
- 		get_new_mmu_context(mm);
--	vm_mask = (1UL << smp_processor_id());
--	if (!(mm->cpu_vm_mask & vm_mask))
--		mm->cpu_vm_mask |= vm_mask;
-+	cpu = smp_processor_id();
-+	if (!cpu_isset(cpu, mm->cpu_vm_mask))
-+		cpu_set(cpu, mm->cpu_vm_mask);
- 	spin_unlock(&mm->page_table_lock);
- 
- 	load_secondary_context(mm);
---- linux-2.6.0-test1/include/asm-sparc64/pgalloc.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/asm-sparc64/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -132,7 +132,7 @@ static __inline__ void free_pgd_slow(pgd
- #define DCACHE_COLOR(address)		0
- #endif
- 
--#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
-+#define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, page_address(PMD))
- 
- static __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
- {
-@@ -153,7 +153,7 @@ static __inline__ pmd_t *pmd_alloc_one_f
- 	return (pmd_t *)ret;
- }
- 
--static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-+static __inline__ pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
- {
- 	pmd_t *pmd;
- 
-@@ -166,6 +166,15 @@ static __inline__ pmd_t *pmd_alloc_one(s
- 	return pmd;
- }
- 
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
- static __inline__ void free_pmd_fast(pmd_t *pmd)
- {
- 	unsigned long color = DCACHE_COLOR((unsigned long)pmd);
-@@ -222,7 +231,7 @@ static __inline__ void free_pte_slow(pte
- 
- #define pte_free_kernel(pte)	free_pte_fast(pte)
- #define pte_free(pte)		free_pte_fast(page_address(pte))
--#define pmd_free(pmd)		free_pmd_fast(pmd)
-+#define pmd_free(pmd)		free_pmd_fast(page_address(pmd))
- #define pgd_free(pgd)		free_pgd_fast(pgd)
- #define pgd_alloc(mm)		get_pgd_fast()
- 
---- linux-2.6.0-test1/include/asm-sparc64/pgtable.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-sparc64/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -228,7 +228,8 @@ static inline pte_t pte_modify(pte_t ori
- 	(pgd_val(*(pgdp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
- #define __pmd_page(pmd)			((unsigned long) __va((pmd_val(pmd)<<11UL)))
- #define pmd_page(pmd) 			virt_to_page((void *)__pmd_page(pmd))
--#define pgd_page(pgd)			((unsigned long) __va((pgd_val(pgd)<<11UL)))
-+#define __pgd_page(pgd)			((unsigned long) __va((pgd_val(pgd)<<11UL)))
-+#define pgd_page(pgd)			virt_to_page(__pgd_page(pgd))
- #define pte_none(pte) 			(!pte_val(pte))
- #define pte_present(pte)		(pte_val(pte) & _PAGE_PRESENT)
- #define pte_clear(pte)			(pte_val(*(pte)) = 0UL)
-@@ -270,8 +271,13 @@ static inline pte_t pte_modify(pte_t ori
- #define pgd_offset_k(address) pgd_offset(&init_mm, address)
- 
- /* Find an entry in the second-level page table.. */
--#define pmd_offset(dir, address)	((pmd_t *) pgd_page(*(dir)) + \
-+#define pmd_offset(dir, address)	((pmd_t *)__pgd_page(*(dir)) + \
- 					((address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1)))
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
- 
- /* Find an entry in the third-level page table.. */
- #define pte_index(dir, address)	((pte_t *) __pmd_page(*(dir)) + \
---- linux-2.6.0-test1/include/asm-sparc64/posix_types.h	2003-06-14 12:18:32.000000000 -0700
-+++ 25/include/asm-sparc64/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -16,7 +16,9 @@ typedef int                    __kernel_
- typedef int                    __kernel_ipc_pid_t;
- typedef unsigned int           __kernel_uid_t;
- typedef unsigned int           __kernel_gid_t;
--typedef unsigned int           __kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long	__kernel_dev_t;
-+#endif
- typedef unsigned long          __kernel_ino_t;
- typedef unsigned int           __kernel_mode_t;
- typedef unsigned short         __kernel_umode_t;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-sparc64/sections.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,7 @@
-+#ifndef _SPARC64_SECTIONS_H
-+#define _SPARC64_SECTIONS_H
-+
-+/* nothing to see, move along */
-+#include <asm-generic/sections.h>
-+
-+#endif
---- linux-2.6.0-test1/include/asm-sparc64/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-sparc64/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -14,6 +14,7 @@
- 
- #ifndef __ASSEMBLY__
- 
-+#include <linux/cpumask.h>
- #include <linux/cache.h>
- 
- /* PROM provided per-processor information we need
-@@ -68,25 +69,14 @@ extern cpuinfo_sparc cpu_data[NR_CPUS];
- 
- extern unsigned char boot_cpu_id;
- 
--extern unsigned long phys_cpu_present_map;
--#define cpu_possible(cpu)	(phys_cpu_present_map & (1UL << (cpu)))
-+extern cpumask_t phys_cpu_present_map;
-+#define cpu_possible(cpu)	cpu_isset(cpu, phys_cpu_present_map)
- 
--extern unsigned long cpu_online_map;
--#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
--
--extern atomic_t sparc64_num_cpus_online;
--#define num_online_cpus()	(atomic_read(&sparc64_num_cpus_online))
-+#define cpu_online(cpu)		cpu_isset(cpu, cpu_online_map)
- 
- extern atomic_t sparc64_num_cpus_possible;
- #define num_possible_cpus()	(atomic_read(&sparc64_num_cpus_possible))
- 
--static inline unsigned int any_online_cpu(unsigned long mask)
--{
--	if ((mask &= cpu_online_map) != 0UL)
--		return __ffs(mask);
--	return NR_CPUS;
--}
--
- /*
-  *	General functions that each host system must provide.
-  */
---- linux-2.6.0-test1/include/asm-sparc64/spinlock.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/asm-sparc64/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -30,15 +30,23 @@
- 
- #ifndef CONFIG_DEBUG_SPINLOCK
- 
--typedef unsigned char spinlock_t;
--#define SPIN_LOCK_UNLOCKED	0
-+typedef struct {
-+	unsigned char lock;
-+	unsigned int  index;
-+} spinlock_t;
- 
--#define spin_lock_init(lock)	(*((unsigned char *)(lock)) = 0)
--#define spin_is_locked(lock)	(*((volatile unsigned char *)(lock)) != 0)
-+#ifdef CONFIG_LOCKMETER
-+#define SPIN_LOCK_UNLOCKED	(spinlock_t) {0, 0}
-+#else
-+#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
-+#endif
- 
--#define spin_unlock_wait(lock)	\
-+#define spin_lock_init(__lock)	do { *(__lock) = SPIN_LOCK_UNLOCKED; } while(0)
-+#define spin_is_locked(__lock)	(*((volatile unsigned char *)(&((__lock)->lock))) != 0)
-+
-+#define spin_unlock_wait(__lock)	\
- do {	membar("#LoadLoad");	\
--} while(*((volatile unsigned char *)lock))
-+} while(*((volatile unsigned char *)(&(((spinlock_t *)__lock)->lock))))
- 
- static __inline__ void _raw_spin_lock(spinlock_t *lock)
- {
-@@ -109,8 +117,20 @@ extern int _spin_trylock (spinlock_t *lo
- 
- #ifndef CONFIG_DEBUG_SPINLOCK
- 
--typedef unsigned int rwlock_t;
--#define RW_LOCK_UNLOCKED	0
-+#ifdef CONFIG_LOCKMETER
-+typedef struct {
-+	unsigned int lock;
-+	unsigned int index;
-+	unsigned int cpu;
-+} rwlock_t;
-+#define RW_LOCK_UNLOCKED       (rwlock_t) { 0, 0, 0xff }
-+#else
-+typedef struct {
-+	unsigned int lock;
-+} rwlock_t;
-+#define RW_LOCK_UNLOCKED        (rwlock_t) { 0 }
-+#endif
-+
- #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
- #define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
- 
---- linux-2.6.0-test1/include/asm-sparc/pgalloc.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/asm-sparc/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -38,15 +38,24 @@ BTFIXUPDEF_CALL(void, free_pgd_fast, pgd
- 
- BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
- #define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
--#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
-+#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, page_address(PMD))
- 
--BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long)
--#define pmd_alloc_one(mm, address)	BTFIXUP_CALL(pmd_alloc_one)(mm, address)
-+BTFIXUPDEF_CALL(pmd_t *, __pmd_alloc_one, struct mm_struct *, unsigned long)
-+#define pmd_alloc_one_kernel(mm, address) BTFIXUP_CALL(__pmd_alloc_one)(mm, address)
-+
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
- 
- BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
- #define free_pmd_fast(pmd)	BTFIXUP_CALL(free_pmd_fast)(pmd)
- 
--#define pmd_free(pmd)           free_pmd_fast(pmd)
-+#define pmd_free(pmd)           free_pmd_fast(page_address(pmd))
- #define __pmd_free_tlb(tlb, pmd) pmd_free(pmd)
- 
- BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
---- linux-2.6.0-test1/include/asm-sparc/pgtable.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/asm-sparc/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -202,10 +202,11 @@ extern unsigned long empty_zero_page;
- /*
-  */
- BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
--BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page, pgd_t)
-+BTFIXUPDEF_CALL_CONST(unsigned long, __pgd_page, pgd_t)
- 
- #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
--#define pgd_page(pgd) BTFIXUP_CALL(pgd_page)(pgd)
-+#define __pgd_page(pgd) BTFIXUP_CALL(__pgd_page)(pgd)
-+#define pgd_page(pgd)	virt_to_page(__pgd_page(pgd))
- 
- BTFIXUPDEF_SETHI(none_mask)
- BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
-@@ -352,6 +353,11 @@ extern __inline__ pte_t pte_modify(pte_t
- /* Find an entry in the second-level page table.. */
- BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
- #define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
- 
- /* Find an entry in the third-level page table.. */ 
- BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
---- linux-2.6.0-test1/include/asm-sparc/posix_types.h	2003-06-14 12:18:06.000000000 -0700
-+++ 25/include/asm-sparc/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -17,7 +17,9 @@ typedef int                    __kernel_
- typedef unsigned short         __kernel_ipc_pid_t;
- typedef unsigned short         __kernel_uid_t;
- typedef unsigned short         __kernel_gid_t;
--typedef unsigned short         __kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long          __kernel_ino_t;
- typedef unsigned short         __kernel_mode_t;
- typedef unsigned short         __kernel_umode_t;
---- linux-2.6.0-test1/include/asm-sparc/smp.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/include/asm-sparc/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -8,6 +8,7 @@
- 
- #include <linux/config.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <asm/head.h>
- #include <asm/btfixup.h>
- 
---- linux-2.6.0-test1/include/asm-um/pgalloc.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-um/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -42,7 +42,8 @@ static inline void pte_free(struct page 
-  * inside the pgd, so has no extra memory associated with it.
-  */
- 
--#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-+#define pmd_alloc_one(mm, addr)		({ BUG(); ((struct page *)2); })
-+#define pmd_alloc_one_kernel(mm, addr)	({ BUG(); ((pmd_t *)2); })
- #define pmd_free(x)			do { } while (0)
- #define __pmd_free_tlb(tlb,x)		do { } while (0)
- #define pgd_populate(mm, pmd, pte)	BUG()
---- linux-2.6.0-test1/include/asm-um/pgtable.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-um/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -374,6 +374,12 @@ static inline pmd_t * pmd_offset(pgd_t *
- 	return (pmd_t *) dir;
- }
- 
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pgd, addr)				do { } while (0)
-+#define pmd_unmap_nested(pgd, addr)			do { } while (0)
-+
- /* Find an entry in the third-level page table.. */ 
- #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
- #define pte_offset_kernel(dir, address) \
---- linux-2.6.0-test1/include/asm-um/smp.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-um/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -1,13 +1,14 @@
- #ifndef __UM_SMP_H
- #define __UM_SMP_H
- 
--extern unsigned long cpu_online_map;
--
- #ifdef CONFIG_SMP
- 
- #include "linux/config.h"
- #include "linux/bitops.h"
- #include "asm/current.h"
-+#include "linux/cpumask.h"
-+
-+extern cpumask_t cpu_online_map;
- 
- #define smp_processor_id() (current->thread_info->cpu)
- #define cpu_logical_map(n) (n)
-@@ -16,16 +17,11 @@ extern unsigned long cpu_online_map;
- extern int hard_smp_processor_id(void);
- #define NO_PROC_ID -1
- 
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- 
- extern int ncpus;
- #define cpu_possible(cpu) (cpu < ncpus)
- 
--extern inline unsigned int num_online_cpus(void)
--{
--	return(hweight32(cpu_online_map));
--}
--
- extern inline void smp_cpus_done(unsigned int maxcpus)
- {
- }
---- linux-2.6.0-test1/include/asm-v850/anna.h	2003-06-14 12:18:06.000000000 -0700
-+++ 25/include/asm-v850/anna.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/anna.h -- Anna V850E2 evaluation cpu chip/board
-  *
-- *  Copyright (C) 2001,2002  NEC Corporation
-- *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -14,8 +14,9 @@
- #ifndef __V850_ANNA_H__
- #define __V850_ANNA_H__
- 
-+#include <asm/v850e2.h>		/* Based on V850E2 core.  */
-+
- 
--#define CPU_ARCH 	"v850e2"
- #define CPU_MODEL	"v850e2/anna"
- #define CPU_MODEL_LONG	"NEC V850E2/Anna"
- #define PLATFORM	"anna"
-@@ -48,30 +49,6 @@
- 
- 
- /* Anna specific control registers.  */
--#define ANNA_CSC_ADDR(n)		(0xFFFFF060 + (n) * 2)
--#define ANNA_CSC(n)			(*(volatile u16 *)ANNA_CSC_ADDR(n))
--#define ANNA_BPC_ADDR			0xFFFFF064
--#define ANNA_BPC			(*(volatile u16 *)ANNA_BPC_ADDR)
--#define ANNA_BSC_ADDR			0xFFFFF066
--#define ANNA_BSC			(*(volatile u16 *)ANNA_BSC_ADDR)
--#define ANNA_BEC_ADDR			0xFFFFF068
--#define ANNA_BEC			(*(volatile u16 *)ANNA_BEC_ADDR)
--#define ANNA_BHC_ADDR			0xFFFFF06A
--#define ANNA_BHC			(*(volatile u16 *)ANNA_BHC_ADDR)
--#define ANNA_BCT_ADDR(n)		(0xFFFFF480 + (n) * 2)
--#define ANNA_BCT(n)			(*(volatile u16 *)ANNA_BCT_ADDR(n))
--#define ANNA_DWC_ADDR(n)		(0xFFFFF484 + (n) * 2)
--#define ANNA_DWC(n)			(*(volatile u16 *)ANNA_DWC_ADDR(n))
--#define ANNA_BCC_ADDR			0xFFFFF488
--#define ANNA_BCC			(*(volatile u16 *)ANNA_BCC_ADDR)
--#define ANNA_ASC_ADDR			0xFFFFF48A
--#define ANNA_ASC			(*(volatile u16 *)ANNA_ASC_ADDR)
--#define ANNA_LBS_ADDR			0xFFFFF48E
--#define ANNA_LBS			(*(volatile u16 *)ANNA_LBS_ADDR)
--#define ANNA_SCR3_ADDR			0xFFFFF4AC
--#define ANNA_SCR3			(*(volatile u16 *)ANNA_SCR3_ADDR)
--#define ANNA_RFS3_ADDR			0xFFFFF4AE
--#define ANNA_RFS3			(*(volatile u16 *)ANNA_RFS3_ADDR)
- #define ANNA_ILBEN_ADDR			0xFFFFF7F2
- #define ANNA_ILBEN			(*(volatile u16 *)ANNA_ILBEN_ADDR)
- 
-@@ -85,9 +62,6 @@
- #define ANNA_PORT_PM(n)			(*(volatile u8 *)ANNA_PORT_PM_ADDR(n))
- 
- 
--/* NB85E-style interrupt system.  */
--#include <asm/nb85e_intc.h>
--
- /* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
- #define IRQ_INTP(n)	(n)	/* Pnnn (pin) interrupts 0-15 */
- #define IRQ_INTP_NUM	16
-@@ -116,12 +90,15 @@ extern void anna_init_irqs (void);
- 
- 
- /* Anna UART details (basically the same as the V850E/MA1, but 2 channels).  */
--#define NB85E_UART_NUM_CHANNELS		2
--#define NB85E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 2)
--#define NB85E_UART_CHIP_NAME 		"V850E2/NA85E2A"
-+#define V850E_UART_NUM_CHANNELS		2
-+#define V850E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 2)
-+#define V850E_UART_CHIP_NAME 		"V850E2/NA85E2A"
-+
-+/* This is the UART channel that's actually connected on the board.  */
-+#define V850E_UART_CONSOLE_CHANNEL	1
- 
- /* This is a function that gets called before configuring the UART.  */
--#define NB85E_UART_PRE_CONFIGURE	anna_uart_pre_configure
-+#define V850E_UART_PRE_CONFIGURE	anna_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void anna_uart_pre_configure (unsigned chan,
- 				     unsigned cflags, unsigned baud);
-@@ -130,9 +107,9 @@ extern void anna_uart_pre_configure (uns
- /* This board supports RTS/CTS for the on-chip UART, but only for channel 1. */
- 
- /* CTS for UART channel 1 is pin P37 (bit 7 of port 3).  */
--#define NB85E_UART_CTS(chan)	((chan) == 1 ? !(ANNA_PORT_IO(3) & 0x80) : 1)
-+#define V850E_UART_CTS(chan)	((chan) == 1 ? !(ANNA_PORT_IO(3) & 0x80) : 1)
- /* RTS for UART channel 1 is pin P07 (bit 7 of port 0).  */
--#define NB85E_UART_SET_RTS(chan, val)					      \
-+#define V850E_UART_SET_RTS(chan, val)					      \
-    do {									      \
- 	   if (chan == 1) {						      \
- 		   unsigned old = ANNA_PORT_IO(0); 			      \
-@@ -145,16 +122,16 @@ extern void anna_uart_pre_configure (uns
- 
- 
- /* Timer C details.  */
--#define NB85E_TIMER_C_BASE_ADDR		0xFFFFF600
-+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
- 
- /* Timer D details (the Anna actually has 5 of these; should change later). */
--#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF540
--#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
--#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x2)
--#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
-+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
-+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
-+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
-+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
- 
--#define NB85E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
--#define NB85E_TIMER_D_TMCD_CS_MIN	1 /* min 2^1 divider */
-+#define V850E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
-+#define V850E_TIMER_D_TMCD_CS_MIN	1 /* min 2^1 divider */
- 
- 
- /* For <asm/param.h> */
---- linux-2.6.0-test1/include/asm-v850/as85ep1.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-v850/as85ep1.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/as85ep1.h -- AS85EP1 evaluation CPU chip/board
-  *
-- *  Copyright (C) 2001,2002  NEC Corporation
-- *  Copyright (C) 2001,2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -14,8 +14,9 @@
- #ifndef __V850_AS85EP1_H__
- #define __V850_AS85EP1_H__
- 
-+#include <asm/v850e.h>
-+
- 
--#define CPU_ARCH 	"v850e"
- #define CPU_MODEL	"as85ep1"
- #define CPU_MODEL_LONG	"NEC V850E/AS85EP1"
- #define PLATFORM	"AS85EP1"
-@@ -86,9 +87,6 @@
- #define AS85EP1_PORT_PMC(n)	(*(volatile u8 *)AS85EP1_PORT_PMC_ADDR(n))
- 
- 
--/* NB85E-style interrupt system.  */
--#include <asm/nb85e_intc.h>
--
- /* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
- #define IRQ_INTCCC(n)	(0x0C + (n))
- #define IRQ_INTCCC_NUM	8
-@@ -110,12 +108,12 @@ extern void as85ep1_init_irqs (void);
- 
- 
- /* AS85EP1 UART details (basically the same as the V850E/MA1, but 2 channels).  */
--#define NB85E_UART_NUM_CHANNELS		2
--#define NB85E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 4)
--#define NB85E_UART_CHIP_NAME 		"V850E/NA85E"
-+#define V850E_UART_NUM_CHANNELS		2
-+#define V850E_UART_BASE_FREQ		(SYS_CLOCK_FREQ / 4)
-+#define V850E_UART_CHIP_NAME 		"V850E/NA85E"
- 
- /* This is a function that gets called before configuring the UART.  */
--#define NB85E_UART_PRE_CONFIGURE	as85ep1_uart_pre_configure
-+#define V850E_UART_PRE_CONFIGURE	as85ep1_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void as85ep1_uart_pre_configure (unsigned chan,
- 					unsigned cflags, unsigned baud);
-@@ -124,9 +122,9 @@ extern void as85ep1_uart_pre_configure (
- /* This board supports RTS/CTS for the on-chip UART, but only for channel 1. */
- 
- /* CTS for UART channel 1 is pin P54 (bit 4 of port 5).  */
--#define NB85E_UART_CTS(chan)   ((chan) == 1 ? !(AS85EP1_PORT_IO(5) & 0x10) : 1)
-+#define V850E_UART_CTS(chan)   ((chan) == 1 ? !(AS85EP1_PORT_IO(5) & 0x10) : 1)
- /* RTS for UART channel 1 is pin P53 (bit 3 of port 5).  */
--#define NB85E_UART_SET_RTS(chan, val)					      \
-+#define V850E_UART_SET_RTS(chan, val)					      \
-    do {									      \
- 	   if (chan == 1) {						      \
- 		   unsigned old = AS85EP1_PORT_IO(5); 			      \
-@@ -139,16 +137,16 @@ extern void as85ep1_uart_pre_configure (
- 
- 
- /* Timer C details.  */
--#define NB85E_TIMER_C_BASE_ADDR		0xFFFFF600
-+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
- 
- /* Timer D details (the AS85EP1 actually has 5 of these; should change later). */
--#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF540
--#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
--#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x2)
--#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
-+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
-+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
-+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
-+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
- 
--#define NB85E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
--#define NB85E_TIMER_D_TMCD_CS_MIN	2 /* min 2^2 divider */
-+#define V850E_TIMER_D_BASE_FREQ		SYS_CLOCK_FREQ
-+#define V850E_TIMER_D_TMCD_CS_MIN	2 /* min 2^2 divider */
- 
- 
- /* For <asm/param.h> */
---- linux-2.6.0-test1/include/asm-v850/asm.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-v850/asm.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/asm.h -- Macros for writing assembly code
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
---- linux-2.6.0-test1/include/asm-v850/cacheflush.h	2003-06-14 12:18:07.000000000 -0700
-+++ 25/include/asm-v850/cacheflush.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/cacheflush.h
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -21,21 +21,40 @@
- #include <asm/machdep.h>
- 
- 
--#ifndef flush_cache_all
--/* If there's no flush_cache_all macro defined by <asm/machdep.h>, then
--   this processor has no cache, so just define these as nops.  */
--
-+/* The following are all used by the kernel in ways that only affect
-+   systems with MMUs, so we don't need them.  */
- #define flush_cache_all()			((void)0)
- #define flush_cache_mm(mm)			((void)0)
- #define flush_cache_range(vma, start, end)	((void)0)
- #define flush_cache_page(vma, vmaddr)		((void)0)
- #define flush_dcache_page(page)			((void)0)
-+
-+#ifdef CONFIG_NO_CACHE
-+
-+/* Some systems have no cache at all, in which case we don't need these
-+   either.  */
- #define flush_icache()				((void)0)
- #define flush_icache_range(start, end)		((void)0)
- #define flush_icache_page(vma,pg)		((void)0)
- #define flush_icache_user_range(vma,pg,adr,len)	((void)0)
- #define flush_cache_sigtramp(vaddr)		((void)0)
- 
--#endif /* !flush_cache_all */
-+#else /* !CONFIG_NO_CACHE */
-+
-+struct page;
-+struct mm_struct;
-+struct vm_area_struct;
-+
-+/* Otherwise, somebody had better define them.  */
-+extern void flush_icache (void);
-+extern void flush_icache_range (unsigned long start, unsigned long end);
-+extern void flush_icache_page (struct vm_area_struct *vma, struct page *page);
-+extern void flush_icache_user_range (struct vm_area_struct *vma,
-+				     struct page *page,
-+				     unsigned long adr, int len);
-+extern void flush_cache_sigtramp (unsigned long addr);
-+
-+#endif /* CONFIG_NO_CACHE */
-+
- 
- #endif /* __V850_CACHEFLUSH_H__ */
---- linux-2.6.0-test1/include/asm-v850/entry.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-v850/entry.h	2003-07-19 17:03:51.000000000 -0700
-@@ -65,10 +65,10 @@
- #define RESET_GUARD_ACTIVE	0xFAB4BEEF
- #endif /* CONFIG_RESET_GUARD */
- 
--#ifdef CONFIG_V850E_MA1_HIGHRES_TIMER
-+#ifdef CONFIG_V850E_HIGHRES_TIMER
- #define HIGHRES_TIMER_SLOW_TICKS_ADDR (KERNEL_VAR_SPACE_ADDR + 32)
- #define HIGHRES_TIMER_SLOW_TICKS     KERNEL_VAR (HIGHRES_TIMER_SLOW_TICKS_ADDR)
--#endif /* CONFIG_V850E_MA1_HIGHRES_TIMER */
-+#endif /* CONFIG_V850E_HIGHRES_TIMER */
- 
- #ifndef __ASSEMBLY__
- 
---- linux-2.6.0-test1/include/asm-v850/fpga85e2c.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/asm-v850/fpga85e2c.h	2003-07-19 17:03:51.000000000 -0700
-@@ -2,8 +2,8 @@
-  * include/asm-v850/fpga85e2c.h -- Machine-dependent defs for
-  *	FPGA implementation of V850E2/NA85E2C
-  *
-- *  Copyright (C) 2002  NEC Corporation
-- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -15,11 +15,10 @@
- #ifndef __V850_FPGA85E2C_H__
- #define __V850_FPGA85E2C_H__
- 
--
-+#include <asm/v850e2.h>
- #include <asm/clinkage.h>
- 
- 
--#define CPU_ARCH 	"v850e2"
- #define CPU_MODEL	"v850e2/fpga85e2c"
- #define CPU_MODEL_LONG	"NEC V850E2/NA85E2C"
- #define PLATFORM	"fpga85e2c"
-@@ -42,27 +41,6 @@
- #define CSDEV_ADDR(n)		(0xFFE80110 + 2*(n))
- #define CSDEV(n)		(*(volatile unsigned char *)CSDEV_ADDR (n))
- 
--/* The BSC register controls bus-sizing.  Each memory area CSn uses a pair
--   of bits N*2 and N*2+1, where 00 means an 8-bit bus size, 01 16-bit, and
--   10 32-bit.  */
--#define BSC_ADDR		0xFFFFF066
--#define BSC			(*(volatile unsigned short *)BSC_ADDR)
--
--#define DWC_ADDR(n)		(0xFFFFF484 + 2*(n))
--#define DWC(n)			(*(volatile unsigned short *)DWC_ADDR (n))
--
--#define ASC_ADDR		0xFFFFF48A
--#define ASC			(*(volatile unsigned short *)ASC_ADDR)
--
--#define BTSC_ADDR		0xFFFFF070
--#define BTSC			(*(volatile unsigned short *)BTSC_ADDR)
--
--#define BHC_ADDR		0xFFFFF06A
--#define BHC			(*(volatile unsigned short *)BHC_ADDR)
--
--
--/* NB85E-style interrupt system.  */
--#include <asm/nb85e_intc.h>
- 
- /* Timer interrupts 0-3, interrupt at intervals from CLK/4096 to CLK/16384.  */
- #define IRQ_RPU(n)		(60 + (n))
---- linux-2.6.0-test1/include/asm-v850/highres_timer.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/asm-v850/highres_timer.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/highres_timer.h -- High resolution timing routines
-  *
-- *  Copyright (C) 2001  NEC Corporation
-- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -25,7 +25,7 @@
-    counter overflows).  */
- #define HIGHRES_TIMER_SLOW_TICK_RATE	25
- 
--/* Which timer in the nb85e `Timer D' we use.  */
-+/* Which timer in the V850E `Timer D' we use.  */
- #define HIGHRES_TIMER_TIMER_D_UNIT	3
- 
- 
---- linux-2.6.0-test1/include/asm-v850/ma1.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/include/asm-v850/ma1.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/ma1.h -- V850E/MA1 cpu chip
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -40,12 +40,11 @@
- #define IRQ_INTST(n)	(0x27 + (n)*4) /* UART 0-2 transmission completion */
- #define IRQ_INTST_NUM	3
- 
--/* For <asm/irq.h> */
- #define NUM_CPU_IRQS	0x30
- 
- 
- /* The MA1 has a UART with 3 channels.  */
--#define NB85E_UART_NUM_CHANNELS	3
-+#define V850E_UART_NUM_CHANNELS	3
- 
- 
- #endif /* __V850_MA1_H__ */
---- linux-2.6.0-test1/include/asm-v850/machdep.h	2003-06-14 12:18:07.000000000 -0700
-+++ 25/include/asm-v850/machdep.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/machdep.h -- Machine-dependent definitions
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -20,6 +20,9 @@
- #ifdef CONFIG_V850E_MA1
- #include <asm/ma1.h>
- #endif
-+#ifdef CONFIG_V850E_ME2
-+#include <asm/me2.h>
-+#endif
- #ifdef CONFIG_V850E_TEG
- #include <asm/teg.h>
- #endif
-@@ -36,6 +39,9 @@
- #ifdef CONFIG_RTE_CB_MA1
- #include <asm/rte_ma1_cb.h>
- #endif
-+#ifdef CONFIG_RTE_CB_ME2
-+#include <asm/rte_me2_cb.h>
-+#endif
- #ifdef CONFIG_RTE_CB_NB85E
- #include <asm/rte_nb85e_cb.h>
- #endif
-@@ -45,6 +51,9 @@
- #ifdef CONFIG_V850E2_SIM85E2C
- #include <asm/sim85e2c.h>
- #endif
-+#ifdef CONFIG_V850E2_SIM85E2S
-+#include <asm/sim85e2s.h>
-+#endif
- #ifdef CONFIG_V850E2_FPGA85E2C
- #include <asm/fpga85e2c.h>
- #endif
---- linux-2.6.0-test1/include/asm-v850/ma.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/asm-v850/ma.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,8 +1,8 @@
- /*
-  * include/asm-v850/ma.h -- V850E/MA series of cpu chips
-  *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-  * Public License.  See the file COPYING in the main directory of this
-@@ -14,9 +14,8 @@
- #ifndef __V850_MA_H__
- #define __V850_MA_H__
- 
--
--/* The MA series uses the NB85E cpu core.  */
--#include <asm/nb85e.h>
-+/* The MA series uses the V850E cpu core.  */
-+#include <asm/v850e.h>
- 
- 
- /* For <asm/entry.h> */
-@@ -28,10 +27,10 @@
- 
- 
- /* MA series UART details.  */
--#define NB85E_UART_BASE_FREQ		CPU_CLOCK_FREQ
-+#define V850E_UART_BASE_FREQ		CPU_CLOCK_FREQ
- 
- /* This is a function that gets called before configuring the UART.  */
--#define NB85E_UART_PRE_CONFIGURE	ma_uart_pre_configure
-+#define V850E_UART_PRE_CONFIGURE	ma_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void ma_uart_pre_configure (unsigned chan,
- 				   unsigned cflags, unsigned baud);
-@@ -39,16 +38,16 @@ extern void ma_uart_pre_configure (unsig
- 
- 
- /* MA series timer C details.  */
--#define NB85E_TIMER_C_BASE_ADDR		0xFFFFF600
-+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
- 
- 
- /* MA series timer D details.  */
--#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF540
--#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
--#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x2)
--#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
-+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
-+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
-+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
-+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
- 
--#define NB85E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
-+#define V850E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
- 
- 
- /* Port 0 */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/me2.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,182 @@
-+/*
-+ * include/asm-v850/me2.h -- V850E/ME2 cpu chip
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_ME2_H__
-+#define __V850_ME2_H__
-+
-+#include <asm/v850e.h>
-+#include <asm/v850e_cache.h>
-+
-+
-+#define CPU_MODEL	"v850e/me2"
-+#define CPU_MODEL_LONG	"NEC V850E/ME2"
-+
-+
-+/* Hardware-specific interrupt numbers (in the kernel IRQ namespace).  */
-+#define IRQ_INTP(n)       (n) /* Pnnn (pin) interrupts */
-+#define IRQ_INTP_NUM      31
-+#define IRQ_INTCMD(n)     (0x31 + (n)) /* interval timer interrupts 0-3 */
-+#define IRQ_INTCMD_NUM    4
-+#define IRQ_INTDMA(n)     (0x41 + (n)) /* DMA interrupts 0-3 */
-+#define IRQ_INTDMA_NUM    4
-+#define IRQ_INTUBTIRE(n)  (0x49 + (n)*5)/* UARTB 0-1 reception error */
-+#define IRQ_INTUBTIRE_NUM 2
-+#define IRQ_INTUBTIR(n)   (0x4a + (n)*5) /* UARTB 0-1 reception complete */
-+#define IRQ_INTUBTIR_NUM  2
-+#define IRQ_INTUBTIT(n)   (0x4b + (n)*5) /* UARTB 0-1 transmission complete */
-+#define IRQ_INTUBTIT_NUM  2
-+#define IRQ_INTUBTIF(n)   (0x4c + (n)*5) /* UARTB 0-1 FIFO trans. complete */
-+#define IRQ_INTUBTIF_NUM  2
-+#define IRQ_INTUBTITO(n)  (0x4d + (n)*5) /* UARTB 0-1 reception timeout */
-+#define IRQ_INTUBTITO_NUM 2
-+
-+/* For <asm/irq.h> */
-+#define NUM_CPU_IRQS		0x59 /* V850E/ME2 */
-+
-+
-+/* For <asm/entry.h> */
-+/* We use on-chip RAM, for a few miscellaneous variables that must be
-+   accessible using a load instruction relative to R0.  */
-+#define R0_RAM_ADDR			0xFFFFB000 /* V850E/ME2 */
-+
-+
-+/* V850E/ME2 UARTB details.*/
-+#define V850E_UART_NUM_CHANNELS		2
-+#define V850E_UARTB_BASE_FREQ		(CPU_CLOCK_FREQ / 4)
-+
-+/* This is a function that gets called before configuring the UART.  */
-+#define V850E_UART_PRE_CONFIGURE	me2_uart_pre_configure
-+#ifndef __ASSEMBLY__
-+extern void me2_uart_pre_configure (unsigned chan,
-+				    unsigned cflags, unsigned baud);
-+#endif /* __ASSEMBLY__ */
-+
-+
-+/* V850E/ME2 timer C details.  */
-+#define V850E_TIMER_C_BASE_ADDR		0xFFFFF600
-+
-+
-+/* V850E/ME2 timer D details.  */
-+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF540
-+#define V850E_TIMER_D_TMD_BASE_ADDR	(V850E_TIMER_D_BASE_ADDR + 0x0)
-+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x2)
-+#define V850E_TIMER_D_TMCD_BASE_ADDR	(V850E_TIMER_D_BASE_ADDR + 0x4)
-+
-+#define V850E_TIMER_D_BASE_FREQ		(CPU_CLOCK_FREQ / 2)
-+
-+
-+/* Select iRAM mode.  */
-+#define ME2_IRAMM_ADDR			0xFFFFF80A
-+#define ME2_IRAMM			(*(volatile u8*)ME2_IRAMM_ADDR)
-+
-+
-+/* Interrupt edge-detection configuration.  INTF(n) and INTR(n) are only
-+   valid for n == 1, 2, or 5.  */
-+#define ME2_INTF_ADDR(n)		(0xFFFFFC00 + (n) * 0x2)
-+#define ME2_INTF(n)			(*(volatile u8*)ME2_INTF_ADDR(n))
-+#define ME2_INTR_ADDR(n)		(0xFFFFFC20 + (n) * 0x2)
-+#define ME2_INTR(n)			(*(volatile u8*)ME2_INTR_ADDR(n))
-+#define ME2_INTFAL_ADDR			0xFFFFFC10
-+#define ME2_INTFAL			(*(volatile u8*)ME2_INTFAL_ADDR)
-+#define ME2_INTRAL_ADDR			0xFFFFFC30
-+#define ME2_INTRAL			(*(volatile u8*)ME2_INTRAL_ADDR)
-+#define ME2_INTFDH_ADDR			0xFFFFFC16
-+#define ME2_INTFDH			(*(volatile u16*)ME2_INTFDH_ADDR)
-+#define ME2_INTRDH_ADDR			0xFFFFFC36
-+#define ME2_INTRDH			(*(volatile u16*)ME2_INTRDH_ADDR)
-+#define ME2_SESC_ADDR(n)		(0xFFFFF609 + (n) * 0x10)
-+#define ME2_SESC(n)			(*(volatile u8*)ME2_SESC_ADDR(n))
-+#define ME2_SESA10_ADDR			0xFFFFF5AD
-+#define ME2_SESA10			(*(volatile u8*)ME2_SESA10_ADDR)
-+#define ME2_SESA11_ADDR			0xFFFFF5DD
-+#define ME2_SESA11			(*(volatile u8*)ME2_SESA11_ADDR)
-+
-+
-+/* Port 1 */
-+/* Direct I/O.  Bits 0-3 are pins P10-P13.  */
-+#define ME2_PORT1_IO_ADDR		0xFFFFF402
-+#define ME2_PORT1_IO			(*(volatile u8 *)ME2_PORT1_IO_ADDR)
-+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
-+#define ME2_PORT1_PM_ADDR		0xFFFFF422
-+#define ME2_PORT1_PM			(*(volatile u8 *)ME2_PORT1_PM_ADDR)
-+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
-+#define ME2_PORT1_PMC_ADDR		0xFFFFF442
-+#define ME2_PORT1_PMC			(*(volatile u8 *)ME2_PORT1_PMC_ADDR)
-+/* Port function control (for serial interfaces, 0 = CSI30, 1 = UARTB0 ).  */
-+#define ME2_PORT1_PFC_ADDR		0xFFFFF462
-+#define ME2_PORT1_PFC			(*(volatile u8 *)ME2_PORT1_PFC_ADDR)
-+
-+/* Port 2 */
-+/* Direct I/O.  Bits 0-3 are pins P20-P25.  */
-+#define ME2_PORT2_IO_ADDR		0xFFFFF404
-+#define ME2_PORT2_IO			(*(volatile u8 *)ME2_PORT2_IO_ADDR)
-+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
-+#define ME2_PORT2_PM_ADDR		0xFFFFF424
-+#define ME2_PORT2_PM			(*(volatile u8 *)ME2_PORT2_PM_ADDR)
-+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
-+#define ME2_PORT2_PMC_ADDR		0xFFFFF444
-+#define ME2_PORT2_PMC			(*(volatile u8 *)ME2_PORT2_PMC_ADDR)
-+/* Port function control (for serial interfaces, 0 = INTP2x, 1 = UARTB1 ).  */
-+#define ME2_PORT2_PFC_ADDR		0xFFFFF464
-+#define ME2_PORT2_PFC			(*(volatile u8 *)ME2_PORT2_PFC_ADDR)
-+
-+/* Port 5 */
-+/* Direct I/O.  Bits 0-5 are pins P50-P55.  */
-+#define ME2_PORT5_IO_ADDR		0xFFFFF40A
-+#define ME2_PORT5_IO			(*(volatile u8 *)ME2_PORT5_IO_ADDR)
-+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
-+#define ME2_PORT5_PM_ADDR		0xFFFFF42A
-+#define ME2_PORT5_PM			(*(volatile u8 *)ME2_PORT5_PM_ADDR)
-+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
-+#define ME2_PORT5_PMC_ADDR		0xFFFFF44A
-+#define ME2_PORT5_PMC			(*(volatile u8 *)ME2_PORT5_PMC_ADDR)
-+/* Port function control ().  */
-+#define ME2_PORT5_PFC_ADDR		0xFFFFF46A
-+#define ME2_PORT5_PFC			(*(volatile u8 *)ME2_PORT5_PFC_ADDR)
-+
-+/* Port 6 */
-+/* Direct I/O.  Bits 5-7 are pins P65-P67.  */
-+#define ME2_PORT6_IO_ADDR		0xFFFFF40C
-+#define ME2_PORT6_IO			(*(volatile u8 *)ME2_PORT6_IO_ADDR)
-+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
-+#define ME2_PORT6_PM_ADDR		0xFFFFF42C
-+#define ME2_PORT6_PM			(*(volatile u8 *)ME2_PORT6_PM_ADDR)
-+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
-+#define ME2_PORT6_PMC_ADDR		0xFFFFF44C
-+#define ME2_PORT6_PMC			(*(volatile u8 *)ME2_PORT6_PMC_ADDR)
-+/* Port function control ().  */
-+#define ME2_PORT6_PFC_ADDR		0xFFFFF46C
-+#define ME2_PORT6_PFC			(*(volatile u8 *)ME2_PORT6_PFC_ADDR)
-+
-+/* Port 7 */
-+/* Direct I/O.  Bits 2-7 are pins P72-P77.  */
-+#define ME2_PORT7_IO_ADDR		0xFFFFF40E
-+#define ME2_PORT7_IO			(*(volatile u8 *)ME2_PORT7_IO_ADDR)
-+/* Port mode (for direct I/O, 0 = output, 1 = input).  */
-+#define ME2_PORT7_PM_ADDR		0xFFFFF42E
-+#define ME2_PORT7_PM			(*(volatile u8 *)ME2_PORT7_PM_ADDR)
-+/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode).  */
-+#define ME2_PORT7_PMC_ADDR		0xFFFFF44E
-+#define ME2_PORT7_PMC			(*(volatile u8 *)ME2_PORT7_PMC_ADDR)
-+/* Port function control ().  */
-+#define ME2_PORT7_PFC_ADDR		0xFFFFF46E
-+#define ME2_PORT7_PFC			(*(volatile u8 *)ME2_PORT7_PFC_ADDR)
-+
-+
-+#ifndef __ASSEMBLY__
-+/* Initialize V850E/ME2 chip interrupts.  */
-+extern void me2_init_irqs (void);
-+#endif /* !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_ME2_H__ */
---- linux-2.6.0-test1/include/asm-v850/nb85e_cache.h	2003-06-14 12:18:21.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,78 +0,0 @@
--/*
-- * include/asm-v850/nb85e_cache_cache.h -- Cache control for NB85E_CACHE212 and
-- * 	NB85E_CACHE213 cache memories
-- *
-- *  Copyright (C) 2001,03  NEC Electronics Corporation
-- *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#ifndef __V850_NB85E_CACHE_H__
--#define __V850_NB85E_CACHE_H__
--
--#include <asm/types.h>
--
--
--/* Cache control registers.  */
--#define NB85E_CACHE_BHC_ADDR	0xFFFFF06A
--#define NB85E_CACHE_BHC		(*(volatile u16 *)NB85E_CACHE_BHC_ADDR)
--#define NB85E_CACHE_ICC_ADDR	0xFFFFF070
--#define NB85E_CACHE_ICC		(*(volatile u16 *)NB85E_CACHE_ICC_ADDR)
--#define NB85E_CACHE_ISI_ADDR	0xFFFFF072
--#define NB85E_CACHE_ISI		(*(volatile u16 *)NB85E_CACHE_ISI_ADDR)
--#define NB85E_CACHE_DCC_ADDR	0xFFFFF078
--#define NB85E_CACHE_DCC		(*(volatile u16 *)NB85E_CACHE_DCC_ADDR)
--
--/* Size of a cache line in bytes.  */
--#define NB85E_CACHE_LINE_SIZE	16
--
--/* For <asm/cache.h> */
--#define L1_CACHE_BYTES				NB85E_CACHE_LINE_SIZE
--
--
--#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
--
--/* Set caching params via the BHC and DCC registers.  */
--void nb85e_cache_enable (u16 bhc, u16 dcc);
--
--struct page;
--struct mm_struct;
--struct vm_area_struct;
--
--extern void nb85e_cache_flush_all (void);
--extern void nb85e_cache_flush_mm (struct mm_struct *mm);
--extern void nb85e_cache_flush_range (struct mm_struct *mm,
--				     unsigned long start,
--				     unsigned long end);
--extern void nb85e_cache_flush_page (struct vm_area_struct *vma,
--				    unsigned long page_addr);
--extern void nb85e_cache_flush_dcache_page (struct page *page);
--extern void nb85e_cache_flush_icache (void);
--extern void nb85e_cache_flush_icache_range (unsigned long start,
--					    unsigned long end);
--extern void nb85e_cache_flush_icache_page (struct vm_area_struct *vma,
--					   struct page *page);
--extern void nb85e_cache_flush_icache_user_range (struct vm_area_struct *vma,
--						 struct page *page,
--						 unsigned long adr, int len);
--extern void nb85e_cache_flush_sigtramp (unsigned long addr);
--
--#define flush_cache_all		nb85e_cache_flush_all
--#define flush_cache_mm		nb85e_cache_flush_mm
--#define flush_cache_range	nb85e_cache_flush_range
--#define flush_cache_page	nb85e_cache_flush_page
--#define flush_dcache_page	nb85e_cache_flush_dcache_page
--#define flush_icache		nb85e_cache_flush_icache
--#define flush_icache_range	nb85e_cache_flush_icache_range
--#define flush_icache_page	nb85e_cache_flush_icache_page
--#define flush_icache_user_range	nb85e_cache_flush_icache_user_range
--#define flush_cache_sigtramp	nb85e_cache_flush_sigtramp
--
--#endif /* __KERNEL__ && !__ASSEMBLY__ */
--
--#endif /* __V850_NB85E_CACHE_H__ */
---- linux-2.6.0-test1/include/asm-v850/nb85e.h	2003-06-14 12:18:21.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,21 +0,0 @@
--/*
-- * include/asm-v850/nb85e.h -- NB85E cpu core
-- *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#ifndef __V850_NB85E_H__
--#define __V850_NB85E_H__
--
--#include <asm/nb85e_intc.h>
--
--#define CPU_ARCH "v850e"
--
--#endif /* __V850_NB85E_H__ */
---- linux-2.6.0-test1/include/asm-v850/nb85e_intc.h	2003-06-14 12:18:29.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,133 +0,0 @@
--/*
-- * include/asm-v850/nb85e_intc.h -- NB85E cpu core interrupt controller (INTC)
-- *
-- *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#ifndef __V850_NB85E_INTC_H__
--#define __V850_NB85E_INTC_H__
--
--
--/* There are 4 16-bit `Interrupt Mask Registers' located contiguously
--   starting from this base.  Each interrupt uses a single bit to
--   indicated enabled/disabled status.  */
--#define NB85E_INTC_IMR_BASE_ADDR  0xFFFFF100
--#define NB85E_INTC_IMR_ADDR(irq)  (NB85E_INTC_IMR_BASE_ADDR + ((irq) >> 3))
--#define NB85E_INTC_IMR_BIT(irq)	  ((irq) & 0x7)
--
--/* Each maskable interrupt has a single-byte control register at this
--   address.  */
--#define NB85E_INTC_IC_BASE_ADDR	  0xFFFFF110
--#define NB85E_INTC_IC_ADDR(irq)	  (NB85E_INTC_IC_BASE_ADDR + ((irq) << 1))
--#define NB85E_INTC_IC(irq)	  (*(volatile u8 *)NB85E_INTC_IC_ADDR(irq))
--/* Encode priority PR for storing in an interrupt control register.  */
--#define NB85E_INTC_IC_PR(pr)	  (pr)
--/* Interrupt disable bit in an interrupt control register.  */
--#define NB85E_INTC_IC_MK_BIT	  6
--#define NB85E_INTC_IC_MK	  (1 << NB85E_INTC_IC_MK_BIT)
--/* Interrupt pending flag in an interrupt control register.  */
--#define NB85E_INTC_IC_IF_BIT	  7
--#define NB85E_INTC_IC_IF	  (1 << NB85E_INTC_IC_IF_BIT)
--
--/* The ISPR (In-service priority register) contains one bit for each interrupt
--   priority level, which is set to one when that level is currently being
--   serviced (and thus blocking any interrupts of equal or lesser level).  */
--#define NB85E_INTC_ISPR_ADDR	  0xFFFFF1FA
--#define NB85E_INTC_ISPR		  (*(volatile u8 *)NB85E_INTC_ISPR_ADDR)
--
--
--#ifndef __ASSEMBLY__
--
--/* Enable interrupt handling for interrupt IRQ.  */
--static inline void nb85e_intc_enable_irq (unsigned irq)
--{
--	__asm__ __volatile__ ("clr1 %0, [%1]"
--			      :: "r" (NB85E_INTC_IMR_BIT (irq)),
--			         "r" (NB85E_INTC_IMR_ADDR (irq))
--			      : "memory");
--}
--
--/* Disable interrupt handling for interrupt IRQ.  Note that any
--   interrupts received while disabled will be delivered once the
--   interrupt is enabled again, unless they are explicitly cleared using
--   `nb85e_intc_clear_pending_irq'.  */
--static inline void nb85e_intc_disable_irq (unsigned irq)
--{
--	__asm__ __volatile__ ("set1 %0, [%1]"
--			      :: "r" (NB85E_INTC_IMR_BIT (irq)),
--			         "r" (NB85E_INTC_IMR_ADDR (irq))
--			      : "memory");
--}
--
--/* Return true if interrupt handling for interrupt IRQ is enabled.  */
--static inline int nb85e_intc_irq_enabled (unsigned irq)
--{
--	int rval;
--	__asm__ __volatile__ ("tst1 %1, [%2]; setf z, %0"
--			      : "=r" (rval)
--			      : "r" (NB85E_INTC_IMR_BIT (irq)),
--			        "r" (NB85E_INTC_IMR_ADDR (irq)));
--	return rval;
--}
--
--/* Disable irqs from 0 until LIMIT.  LIMIT must be a multiple of 8.  */
--static inline void _nb85e_intc_disable_irqs (unsigned limit)
--{
--	unsigned long addr;
--	for (addr = NB85E_INTC_IMR_BASE_ADDR; limit >= 8; addr++, limit -= 8)
--		*(char *)addr = 0xFF;
--}
--
--/* Disable all irqs.  This is purposely a macro, because NUM_MACH_IRQS
--   will be only be defined later.  */
--#define nb85e_intc_disable_irqs()   _nb85e_intc_disable_irqs (NUM_MACH_IRQS)
--
--/* Clear any pending interrupts for IRQ.  */
--static inline void nb85e_intc_clear_pending_irq (unsigned irq)
--{
--	__asm__ __volatile__ ("clr1 %0, 0[%1]"
--			      :: "i" (NB85E_INTC_IC_IF_BIT),
--			         "r" (NB85E_INTC_IC_ADDR (irq))
--			      : "memory");
--}
--
--/* Return true if interrupt IRQ is pending (but disabled).  */
--static inline int nb85e_intc_irq_pending (unsigned irq)
--{
--	int rval;
--	__asm__ __volatile__ ("tst1 %1, 0[%2]; setf nz, %0"
--			      : "=r" (rval)
--			      : "i" (NB85E_INTC_IC_IF_BIT),
--			        "r" (NB85E_INTC_IC_ADDR (irq)));
--	return rval;
--}
--
--
--struct nb85e_intc_irq_init {
--	const char *name;	/* name of interrupt type */
--
--	/* Range of kernel irq numbers for this type:
--	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
--	unsigned base, num, interval;
--
--	unsigned priority;	/* interrupt priority to assign */
--};
--struct hw_interrupt_type;	/* fwd decl */
--
--/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
--   INITS (which is terminated by an entry with the name field == 0).  */
--extern void nb85e_intc_init_irq_types (struct nb85e_intc_irq_init *inits,
--				       struct hw_interrupt_type *hw_irq_types);
--
--
--#endif /* !__ASSEMBLY__ */
--
--
--#endif /* __V850_NB85E_INTC_H__ */
---- linux-2.6.0-test1/include/asm-v850/nb85e_timer_c.h	2003-06-14 12:17:58.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,48 +0,0 @@
--/*
-- * include/asm-v850/nb85e_timer_c.h -- `Timer C' component often used
-- *	with the NB85E cpu core
-- *
-- *  Copyright (C) 2001  NEC Corporation
-- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--/* NOTE: this include file currently contains only enough to allow us to
--   use timer C as an interrupt pass-through.  */
--
--#ifndef __V850_NB85E_TIMER_C_H__
--#define __V850_NB85E_TIMER_C_H__
--
--#include <asm/types.h>
--#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
--
--
--/* Timer C (16-bit interval timers).  */
--
--/* Control register 0 for timer C.  */
--#define NB85E_TIMER_C_TMCC0_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x6 + 0x10 *(n))
--#define NB85E_TIMER_C_TMCC0(n)	  (*(volatile u8 *)NB85E_TIMER_C_TMCC0_ADDR(n))
--#define NB85E_TIMER_C_TMCC0_CAE	  0x01 /* clock action enable */
--#define NB85E_TIMER_C_TMCC0_CE	  0x02 /* count enable */
--/* ... */
--
--/* Control register 1 for timer C.  */
--#define NB85E_TIMER_C_TMCC1_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x8 + 0x10 *(n))
--#define NB85E_TIMER_C_TMCC1(n)	  (*(volatile u8 *)NB85E_TIMER_C_TMCC1_ADDR(n))
--#define NB85E_TIMER_C_TMCC1_CMS0  0x01 /* capture/compare mode select (ccc0) */
--#define NB85E_TIMER_C_TMCC1_CMS1  0x02 /* capture/compare mode select (ccc1) */
--/* ... */
--
--/* Interrupt edge-sensitivity control for timer C.  */
--#define NB85E_TIMER_C_SESC_ADDR(n) (NB85E_TIMER_C_BASE_ADDR + 0x9 + 0x10 *(n))
--#define NB85E_TIMER_C_SESC(n)	  (*(volatile u8 *)NB85E_TIMER_C_SESC_ADDR(n))
--
--/* ...etc... */
--
--
--#endif /* __V850_NB85E_TIMER_C_H__  */
---- linux-2.6.0-test1/include/asm-v850/nb85e_timer_d.h	2003-06-14 12:18:06.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,62 +0,0 @@
--/*
-- * include/asm-v850/nb85e_timer_d.h -- `Timer D' component often used
-- *	with the NB85E cpu core
-- *
-- *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#ifndef __V850_NB85E_TIMER_D_H__
--#define __V850_NB85E_TIMER_D_H__
--
--#include <asm/types.h>
--#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
--
--
--/* Timer D (16-bit interval timers).  */
--
--/* Count registers for timer D.  */
--#define NB85E_TIMER_D_TMD_ADDR(n) (NB85E_TIMER_D_TMD_BASE_ADDR + 0x10 * (n))
--#define NB85E_TIMER_D_TMD(n)	  (*(volatile u16 *)NB85E_TIMER_D_TMD_ADDR(n))
--
--/* Count compare registers for timer D.  */
--#define NB85E_TIMER_D_CMD_ADDR(n) (NB85E_TIMER_D_CMD_BASE_ADDR + 0x10 * (n))
--#define NB85E_TIMER_D_CMD(n)	  (*(volatile u16 *)NB85E_TIMER_D_CMD_ADDR(n))
--
--/* Control registers for timer D.  */
--#define NB85E_TIMER_D_TMCD_ADDR(n) (NB85E_TIMER_D_TMCD_BASE_ADDR + 0x10 * (n))
--#define NB85E_TIMER_D_TMCD(n)	   (*(volatile u8 *)NB85E_TIMER_D_TMCD_ADDR(n))
--/* Control bits for timer D.  */
--#define NB85E_TIMER_D_TMCD_CE  	   0x2 /* count enable */
--#define NB85E_TIMER_D_TMCD_CAE	   0x1 /* clock action enable */
--/* Clock divider setting (log2).  */
--#define NB85E_TIMER_D_TMCD_CS(divlog2) (((divlog2) - NB85E_TIMER_D_TMCD_CS_MIN) << 4)
--/* Minimum clock divider setting (log2).  */
--#ifndef NB85E_TIMER_D_TMCD_CS_MIN /* Can be overridden by mach-specific hdrs */
--#define NB85E_TIMER_D_TMCD_CS_MIN  2 /* Default is correct for the v850e/ma1 */
--#endif
--/* Maximum clock divider setting (log2).  */
--#define NB85E_TIMER_D_TMCD_CS_MAX  (NB85E_TIMER_D_TMCD_CS_MIN + 7)
--
--/* Return the clock-divider (log2) of timer D unit N.  */
--#define NB85E_TIMER_D_DIVLOG2(n) \
--  (((NB85E_TIMER_D_TMCD(n) >> 4) & 0x7) + NB85E_TIMER_D_TMCD_CS_MIN)
--
--
--#ifndef __ASSEMBLY__
--
--/* Start interval timer TIMER (0-3).  The timer will issue the
--   corresponding INTCMD interrupt RATE times per second.  This function
--   does not enable the interrupt.  */
--extern void nb85e_timer_d_configure (unsigned timer, unsigned rate);
--
--#endif /* !__ASSEMBLY__ */
--
--
--#endif /* __V850_NB85E_TIMER_D_H__  */
---- linux-2.6.0-test1/include/asm-v850/nb85e_uart.h	2003-06-14 12:18:50.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,144 +0,0 @@
--/*
-- * include/asm-v850/nb85e_uart.h -- On-chip UART often used with the
-- *	NB85E cpu core
-- *
-- *  Copyright (C) 2001,02  NEC Corporation
-- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--/* There's not actually a single UART implementation used by nb85e
--   derivatives, but rather a series of implementations that are all
--   `close' to one another.  This file attempts to capture some
--   commonality between them.  */
--
--#ifndef __V850_NB85E_UART_H__
--#define __V850_NB85E_UART_H__
--
--#include <asm/types.h>
--#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
--
--
--/* The base address of the UART control registers for channel N.
--   The default is the address used on the V850E/MA1.  */
--#ifndef NB85E_UART_BASE_ADDR
--#define NB85E_UART_BASE_ADDR(n)		(0xFFFFFA00 + 0x10 * (n))
--#endif 
--
--/* Addresses of specific UART control registers for channel N.
--   The defaults are the addresses used on the V850E/MA1; if a platform
--   wants to redefine any of these, it must redefine them all.  */
--#ifndef NB85E_UART_ASIM_ADDR
--#define NB85E_UART_ASIM_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x0)
--#define NB85E_UART_RXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x2)
--#define NB85E_UART_ASIS_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x3)
--#define NB85E_UART_TXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x4)
--#define NB85E_UART_ASIF_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x5)
--#define NB85E_UART_CKSR_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x6)
--#define NB85E_UART_BRGC_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x7)
--#endif
--
--#ifndef NB85E_UART_CKSR_MAX_FREQ
--#define NB85E_UART_CKSR_MAX_FREQ (25*1000*1000)
--#endif
--
--/* UART config registers.  */
--#define NB85E_UART_ASIM(n)	(*(volatile u8 *)NB85E_UART_ASIM_ADDR(n))
--/* Control bits for config registers.  */
--#define NB85E_UART_ASIM_CAE	0x80 /* clock enable */
--#define NB85E_UART_ASIM_TXE	0x40 /* transmit enable */
--#define NB85E_UART_ASIM_RXE	0x20 /* receive enable */
--#define NB85E_UART_ASIM_PS_MASK	0x18 /* mask covering parity-select bits */
--#define NB85E_UART_ASIM_PS_NONE	0x00 /* no parity */
--#define NB85E_UART_ASIM_PS_ZERO	0x08 /* zero parity */
--#define NB85E_UART_ASIM_PS_ODD	0x10 /* odd parity */
--#define NB85E_UART_ASIM_PS_EVEN	0x18 /* even parity */
--#define NB85E_UART_ASIM_CL_8	0x04 /* char len is 8 bits (otherwise, 7) */
--#define NB85E_UART_ASIM_SL_2	0x02 /* 2 stop bits (otherwise, 1) */
--#define NB85E_UART_ASIM_ISRM	0x01 /* generate INTSR interrupt on errors
--					(otherwise, generate INTSER) */
--
--/* UART serial interface status registers.  */
--#define NB85E_UART_ASIS(n)	(*(volatile u8 *)NB85E_UART_ASIS_ADDR(n))
--/* Control bits for status registers.  */
--#define NB85E_UART_ASIS_PE	0x04 /* parity error */
--#define NB85E_UART_ASIS_FE	0x02 /* framing error */
--#define NB85E_UART_ASIS_OVE	0x01 /* overrun error */
--
--/* UART serial interface transmission status registers.  */
--#define NB85E_UART_ASIF(n)	(*(volatile u8 *)NB85E_UART_ASIF_ADDR(n))
--#define NB85E_UART_ASIF_TXBF	0x02 /* transmit buffer flag (data in TXB) */
--#define NB85E_UART_ASIF_TXSF	0x01 /* transmit shift flag (sending data) */
--
--/* UART receive buffer register.  */
--#define NB85E_UART_RXB(n)	(*(volatile u8 *)NB85E_UART_RXB_ADDR(n))
--
--/* UART transmit buffer register.  */
--#define NB85E_UART_TXB(n)	(*(volatile u8 *)NB85E_UART_TXB_ADDR(n))
--
--/* UART baud-rate generator control registers.  */
--#define NB85E_UART_CKSR(n)	(*(volatile u8 *)NB85E_UART_CKSR_ADDR(n))
--#define NB85E_UART_CKSR_MAX	11
--#define NB85E_UART_BRGC(n)	(*(volatile u8 *)NB85E_UART_BRGC_ADDR(n))
--
--
--/* This UART doesn't implement RTS/CTS by default, but some platforms
--   implement them externally, so check to see if <asm/machdep.h> defined
--   anything.  */
--#ifdef NB85E_UART_CTS
--#define nb85e_uart_cts(n)	NB85E_UART_CTS(n)
--#else
--#define nb85e_uart_cts(n)	(1)
--#endif
--
--/* Do the same for RTS.  */
--#ifdef NB85E_UART_SET_RTS
--#define nb85e_uart_set_rts(n,v)	NB85E_UART_SET_RTS(n,v)
--#else
--#define nb85e_uart_set_rts(n,v)	((void)0)
--#endif
--
--/* Return true if all characters awaiting transmission on uart channel N
--   have been transmitted.  */
--#define nb85e_uart_xmit_done(n)						      \
--   (! (NB85E_UART_ASIF(n) & NB85E_UART_ASIF_TXBF))
--/* Wait for this to be true.  */
--#define nb85e_uart_wait_for_xmit_done(n)				      \
--   do { } while (! nb85e_uart_xmit_done (n))
--
--/* Return true if uart channel N is ready to transmit a character.  */
--#define nb85e_uart_xmit_ok(n)						      \
--   (nb85e_uart_xmit_done(n) && nb85e_uart_cts(n))
--/* Wait for this to be true.  */
--#define nb85e_uart_wait_for_xmit_ok(n)					      \
--   do { } while (! nb85e_uart_xmit_ok (n))
--
--/* Write character CH to uart channel N.  */
--#define nb85e_uart_putc(n, ch)	(NB85E_UART_TXB(n) = (ch))
--
--
--#define NB85E_UART_MINOR_BASE	64
--
--
--#ifndef __ASSEMBLY__
--
--/* Setup a console using channel 0 of the builtin uart.  */
--extern void nb85e_uart_cons_init (unsigned chan);
--
--/* Configure and turn on uart channel CHAN, using the termios `control
--   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
--void nb85e_uart_configure (unsigned chan, unsigned cflags, unsigned baud);
--
--/* If the macro NB85E_UART_PRE_CONFIGURE is defined (presumably by a
--   <asm/machdep.h>), it is called from nb85e_uart_pre_configure before
--   anything else is done, with interrupts disabled.  */
--
--#endif /* !__ASSEMBLY__ */
--
--
--#endif /* __V850_NB85E_UART_H__ */
---- linux-2.6.0-test1/include/asm-v850/nb85e_utils.h	2003-06-14 12:18:20.000000000 -0700
-+++ /dev/null	2002-08-30 16:31:37.000000000 -0700
-@@ -1,35 +0,0 @@
--/*
-- * include/asm-v850/nb85e_utils.h -- Utility functions associated with
-- *	the NB85E cpu core
-- *
-- *  Copyright (C) 2001  NEC Corporation
-- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
-- *
-- * This file is subject to the terms and conditions of the GNU General
-- * Public License.  See the file COPYING in the main directory of this
-- * archive for more details.
-- *
-- * Written by Miles Bader <miles@gnu.org>
-- */
--
--#ifndef __V850_NB85E_UTILS_H__
--#define __V850_NB85E_UTILS_H__
--
--/* Calculate counter clock-divider and count values to attain the
--   desired frequency RATE from the base frequency BASE_FREQ.  The
--   counter is expected to have a clock-divider, which can divide the
--   system cpu clock by a power of two value from MIN_DIVLOG2 to
--   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
--   counts up and resets whenever it's equal to the compare register,
--   generating an interrupt or whatever when it does so).  The returned
--   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
--   -- the counter compare value to use.  Returns true if it was possible
--   to find a reasonable value, otherwise false (and the other return
--   values will be set to be as good as possible).  */
--extern int calc_counter_params (unsigned long base_freq,
--				unsigned long rate,
--				unsigned min_divlog2, unsigned max_divlog2,
--				unsigned counter_size,
--				unsigned *divlog2, unsigned *count);
--
--#endif /* __V850_NB85E_UTILS_H__ */
---- linux-2.6.0-test1/include/asm-v850/pgtable.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/include/asm-v850/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -13,6 +13,11 @@ typedef pte_t *pte_addr_t;
- #define pgd_clear(pgdp)		((void)0)
- 
- #define	pmd_offset(a, b)	((void *)0)
-+#define pmd_offset_kernel(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)	pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)				do { } while (0)
-+#define pmd_unmap_nested(pmd)			do { } while (0)
- 
- #define kern_addr_valid(addr)	(1)
- 
---- linux-2.6.0-test1/include/asm-v850/posix_types.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/asm-v850/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -14,7 +14,9 @@
- #ifndef __V850_POSIX_TYPES_H__
- #define __V850_POSIX_TYPES_H__
- 
--typedef unsigned int	__kernel_dev_t;
-+#ifdef __GNUC__
-+typedef unsigned long long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned long long __kernel_ino64_t;
- typedef unsigned int	__kernel_mode_t;
---- linux-2.6.0-test1/include/asm-v850/processor.h	2003-06-14 12:18:04.000000000 -0700
-+++ 25/include/asm-v850/processor.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/processor.h
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
---- linux-2.6.0-test1/include/asm-v850/ptrace.h	2003-06-14 12:18:51.000000000 -0700
-+++ 25/include/asm-v850/ptrace.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/ptrace.h -- Access to CPU registers
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
---- linux-2.6.0-test1/include/asm-v850/rte_cb.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-v850/rte_cb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/rte_cb.h -- Midas labs RTE-CB series of evaluation boards
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
-@@ -20,42 +20,54 @@
- #define MB_A_SRAM_SIZE		0x00200000 /* 2MB */
- 
- 
-+#ifdef CONFIG_RTE_GBUS_INT
- /* GBUS interrupt support.  */
--#define GBUS_INT_BASE_IRQ	NUM_CPU_IRQS
--#define GBUS_INT_BASE_ADDR	(GCS2_ADDR + 0x00006000)
--#include <asm/gbus_int.h>
- 
--/* We define NUM_MACH_IRQS to include extra interrupts from the GBUS.  */
--#define NUM_MACH_IRQS		(NUM_CPU_IRQS + IRQ_GBUS_INT_NUM)
-+# include <asm/gbus_int.h>
-+
-+# define GBUS_INT_BASE_IRQ	NUM_RTE_CB_IRQS
-+# define GBUS_INT_BASE_ADDR	(GCS2_ADDR + 0x00006000)
- 
- /* Some specific interrupts.  */
--#define IRQ_MB_A_LAN		IRQ_GBUS_INT(10)
--#define IRQ_MB_A_PCI1(n)	(IRQ_GBUS_INT(16) + (n))
--#define IRQ_MB_A_PCI1_NUM	4
--#define IRQ_MB_A_PCI2(n)	(IRQ_GBUS_INT(20) + (n))
--#define IRQ_MB_A_PCI2_NUM	4
--#define IRQ_MB_A_EXT(n)		(IRQ_GBUS_INT(24) + (n))
--#define IRQ_MB_A_EXT_NUM	4
--#define IRQ_MB_A_USB_OC(n)	(IRQ_GBUS_INT(28) + (n))
--#define IRQ_MB_A_USB_OC_NUM	2
--#define IRQ_MB_A_PCMCIA_OC	IRQ_GBUS_INT(30)
-+# define IRQ_MB_A_LAN		IRQ_GBUS_INT(10)
-+# define IRQ_MB_A_PCI1(n)	(IRQ_GBUS_INT(16) + (n))
-+# define IRQ_MB_A_PCI1_NUM	4
-+# define IRQ_MB_A_PCI2(n)	(IRQ_GBUS_INT(20) + (n))
-+# define IRQ_MB_A_PCI2_NUM	4
-+# define IRQ_MB_A_EXT(n)	(IRQ_GBUS_INT(24) + (n))
-+# define IRQ_MB_A_EXT_NUM	4
-+# define IRQ_MB_A_USB_OC(n)	(IRQ_GBUS_INT(28) + (n))
-+# define IRQ_MB_A_USB_OC_NUM	2
-+# define IRQ_MB_A_PCMCIA_OC	IRQ_GBUS_INT(30)
-+
-+/* We define NUM_MACH_IRQS to include extra interrupts from the GBUS.  */
-+# define NUM_MACH_IRQS		(NUM_RTE_CB_IRQS + IRQ_GBUS_INT_NUM)
- 
-+#else /* !CONFIG_RTE_GBUS_INT */
- 
-+# define NUM_MACH_IRQS		NUM_RTE_CB_IRQS
-+
-+#endif /* CONFIG_RTE_GBUS_INT */
-+
-+
-+#ifdef CONFIG_RTE_MB_A_PCI
- /* Mother-A PCI bus support.  */
--#include <asm/rte_mb_a_pci.h>
-+
-+# include <asm/rte_mb_a_pci.h>
- 
- /* These are the base addresses used for allocating device address
-    space.  512K of the motherboard SRAM is in the same space, so we have
-    to be careful not to let it be allocated.  */
--#define PCIBIOS_MIN_MEM		(MB_A_PCI_MEM_ADDR + 0x80000)
--#define PCIBIOS_MIN_IO		MB_A_PCI_IO_ADDR
-+# define PCIBIOS_MIN_MEM	(MB_A_PCI_MEM_ADDR + 0x80000)
-+# define PCIBIOS_MIN_IO		MB_A_PCI_IO_ADDR
- 
- /* As we don't really support PCI DMA to cpu memory, and use bounce-buffers
-    instead, perversely enough, this becomes always true! */
--#define pci_dma_supported(dev, mask)		1
--#define pci_dac_dma_supported(dev, mask)	0
--#define pcibios_assign_all_busses()		1
-+# define pci_dma_supported(dev, mask)		1
-+# define pci_dac_dma_supported(dev, mask)	0
-+# define pcibios_assign_all_busses()		1
- 
-+#endif /* CONFIG_RTE_MB_A_PCI */
- 
- 
- /* For <asm/param.h> */
---- linux-2.6.0-test1/include/asm-v850/rte_ma1_cb.h	2003-06-14 12:17:59.000000000 -0700
-+++ 25/include/asm-v850/rte_ma1_cb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -17,25 +17,6 @@
- #include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
- 
- 
--/* CPU addresses of GBUS memory spaces.  */
--#define GCS0_ADDR		0x05000000 /* GCS0 - Common SRAM (2MB) */
--#define GCS0_SIZE		0x00200000 /*   2MB */
--#define GCS1_ADDR		0x06000000 /* GCS1 - Flash ROM (8MB) */
--#define GCS1_SIZE		0x00800000 /*   8MB */
--#define GCS2_ADDR		0x07900000 /* GCS2 - I/O registers */
--#define GCS2_SIZE		0x00400000 /*   4MB */
--#define GCS5_ADDR		0x04000000 /* GCS5 - PCI bus space */
--#define GCS5_SIZE		0x01000000 /*   16MB */
--#define GCS6_ADDR		0x07980000 /* GCS6 - PCI control registers */
--#define GCS6_SIZE		0x00000200 /*   512B */
--
--
--/* The GBUS GINT0 - GINT4 interrupts are connected to the INTP000 - INTP011
--   pins on the CPU.  These are shared among the GBUS interrupts.  */
--#define IRQ_GINT(n)		IRQ_INTP(n)
--#define IRQ_GINT_NUM		4
--
--
- #define PLATFORM		"rte-v850e/ma1-cb"
- #define PLATFORM_LONG		"Midas lab RTE-V850E/MA1-CB"
- 
-@@ -53,10 +34,32 @@
- #define SDRAM_SIZE		0x02000000 /* 32MB */
- 
- 
-+/* CPU addresses of GBUS memory spaces.  */
-+#define GCS0_ADDR		0x05000000 /* GCS0 - Common SRAM (2MB) */
-+#define GCS0_SIZE		0x00200000 /*   2MB */
-+#define GCS1_ADDR		0x06000000 /* GCS1 - Flash ROM (8MB) */
-+#define GCS1_SIZE		0x00800000 /*   8MB */
-+#define GCS2_ADDR		0x07900000 /* GCS2 - I/O registers */
-+#define GCS2_SIZE		0x00400000 /*   4MB */
-+#define GCS5_ADDR		0x04000000 /* GCS5 - PCI bus space */
-+#define GCS5_SIZE		0x01000000 /*   16MB */
-+#define GCS6_ADDR		0x07980000 /* GCS6 - PCI control registers */
-+#define GCS6_SIZE		0x00000200 /*   512B */
-+
-+
- /* For <asm/page.h> */
- #define PAGE_OFFSET 		SRAM_ADDR
- 
- 
-+/* The GBUS GINT0 - GINT3 interrupts are connected to the INTP000 - INTP011
-+   pins on the CPU.  These are shared among the GBUS interrupts.  */
-+#define IRQ_GINT(n)		IRQ_INTP(n)
-+#define IRQ_GINT_NUM		4
-+
-+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
-+#define NUM_RTE_CB_IRQS		NUM_CPU_IRQS
-+
-+
- #ifdef CONFIG_ROM_KERNEL
- /* Kernel is in ROM, starting at address 0.  */
- 
-@@ -98,8 +101,8 @@
- 
- /* Override the basic MA uart pre-initialization so that we can
-    initialize extra stuff.  */
--#undef NB85E_UART_PRE_CONFIGURE	/* should be defined by <asm/ma.h> */
--#define NB85E_UART_PRE_CONFIGURE	rte_ma1_cb_uart_pre_configure
-+#undef V850E_UART_PRE_CONFIGURE	/* should be defined by <asm/ma.h> */
-+#define V850E_UART_PRE_CONFIGURE	rte_ma1_cb_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void rte_ma1_cb_uart_pre_configure (unsigned chan,
- 					   unsigned cflags, unsigned baud);
-@@ -108,9 +111,9 @@ extern void rte_ma1_cb_uart_pre_configur
- /* This board supports RTS/CTS for the on-chip UART, but only for channel 0. */
- 
- /* CTS for UART channel 0 is pin P43 (bit 3 of port 4).  */
--#define NB85E_UART_CTS(chan)	((chan) == 0 ? !(MA_PORT4_IO & 0x8) : 1)
-+#define V850E_UART_CTS(chan)	((chan) == 0 ? !(MA_PORT4_IO & 0x8) : 1)
- /* RTS for UART channel 0 is pin P42 (bit 2 of port 4).  */
--#define NB85E_UART_SET_RTS(chan, val)					      \
-+#define V850E_UART_SET_RTS(chan, val)					      \
-    do {									      \
- 	   if (chan == 0) {						      \
- 		   unsigned old = MA_PORT4_IO; 				      \
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/rte_me2_cb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,202 @@
-+/*
-+ * include/asm-v850/rte_me2_cb.h -- Midas labs RTE-V850E/ME2-CB board
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_RTE_ME2_CB_H__
-+#define __V850_RTE_ME2_CB_H__
-+
-+#include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
-+
-+
-+#define PLATFORM		"rte-v850e/me2-cb"
-+#define PLATFORM_LONG		"Midas lab RTE-V850E/ME2-CB"
-+
-+#define CPU_CLOCK_FREQ		150000000 /* 150MHz */
-+#define FIXED_BOGOMIPS		50
-+
-+/* 32MB of onbard SDRAM.  */
-+#define SDRAM_ADDR		0x00800000
-+#define SDRAM_SIZE		0x02000000 /* 32MB */
-+
-+
-+/* CPU addresses of GBUS memory spaces.  */
-+#define GCS0_ADDR		0x04000000 /* GCS0 - Common SRAM (2MB) */
-+#define GCS0_SIZE		0x00800000 /*   8MB */
-+#define GCS1_ADDR		0x04800000 /* GCS1 - Flash ROM (8MB) */
-+#define GCS1_SIZE		0x00800000 /*   8MB */
-+#define GCS2_ADDR		0x07000000 /* GCS2 - I/O registers */
-+#define GCS2_SIZE		0x00800000 /*   8MB */
-+#define GCS5_ADDR		0x08000000 /* GCS5 - PCI bus space */
-+#define GCS5_SIZE		0x02000000 /*   32MB */
-+#define GCS6_ADDR		0x07800000 /* GCS6 - PCI control registers */
-+#define GCS6_SIZE		0x00800000 /*   8MB */
-+
-+
-+/* For <asm/page.h> */
-+#define PAGE_OFFSET 		SDRAM_ADDR
-+
-+
-+#ifdef CONFIG_ROM_KERNEL
-+/* Kernel is in ROM, starting at address 0.  */
-+
-+#define INTV_BASE		0
-+#define ROOT_FS_IMAGE_RW	0
-+
-+#else /* !CONFIG_ROM_KERNEL */
-+/* Using RAM-kernel.  Assume some sort of boot-loader got us loaded at
-+   address 0.  */
-+
-+#define INTV_BASE		0
-+#define ROOT_FS_IMAGE_RW	1
-+
-+#endif /* CONFIG_ROM_KERNEL */
-+
-+
-+/* Some misc. on-board devices.  */
-+
-+/* Seven-segment LED display (four digits).  */
-+#define LED_ADDR(n)		(0x0FE02000 + (n))
-+#define LED(n)			(*(volatile unsigned char *)LED_ADDR(n))
-+#define LED_NUM_DIGITS		4
-+
-+
-+/* On-board PIC.  */
-+
-+#define CB_PIC_BASE_ADDR 	0x0FE04000
-+
-+#define CB_PIC_INT0M_ADDR 	(CB_PIC_BASE_ADDR + 0x00)
-+#define CB_PIC_INT0M      	(*(volatile u16 *)CB_PIC_INT0M_ADDR)
-+#define CB_PIC_INT1M_ADDR 	(CB_PIC_BASE_ADDR + 0x10)
-+#define CB_PIC_INT1M      	(*(volatile u16 *)CB_PIC_INT1M_ADDR)
-+#define CB_PIC_INTR_ADDR  	(CB_PIC_BASE_ADDR + 0x20)
-+#define CB_PIC_INTR       	(*(volatile u16 *)CB_PIC_INTR_ADDR)
-+#define CB_PIC_INTEN_ADDR 	(CB_PIC_BASE_ADDR + 0x30)
-+#define CB_PIC_INTEN      	(*(volatile u16 *)CB_PIC_INTEN_ADDR)
-+
-+#define CB_PIC_INT0EN        	0x0001
-+#define CB_PIC_INT1EN        	0x0002
-+#define CB_PIC_INT0SEL       	0x0080
-+
-+/* The PIC interrupts themselves.  */
-+#define CB_PIC_BASE_IRQ		NUM_CPU_IRQS
-+#define IRQ_CB_PIC_NUM		10
-+
-+/* Some specific CB_PIC interrupts. */
-+#define IRQ_CB_EXTTM0		(CB_PIC_BASE_IRQ + 0)
-+#define IRQ_CB_EXTSIO		(CB_PIC_BASE_IRQ + 1)
-+#define IRQ_CB_TOVER		(CB_PIC_BASE_IRQ + 2)
-+#define IRQ_CB_GINT0		(CB_PIC_BASE_IRQ + 3)
-+#define IRQ_CB_USB		(CB_PIC_BASE_IRQ + 4)
-+#define IRQ_CB_LANC		(CB_PIC_BASE_IRQ + 5)
-+#define IRQ_CB_USB_VBUS_ON	(CB_PIC_BASE_IRQ + 6)
-+#define IRQ_CB_USB_VBUS_OFF	(CB_PIC_BASE_IRQ + 7)
-+#define IRQ_CB_EXTTM1		(CB_PIC_BASE_IRQ + 8)
-+#define IRQ_CB_EXTTM2		(CB_PIC_BASE_IRQ + 9)
-+
-+/* The GBUS GINT1 - GINT3 (note, not GINT0!) interrupts are connected to
-+   the INTP65 - INTP67 pins on the CPU.  These are shared among the GBUS
-+   interrupts.  */
-+#define IRQ_GINT(n)		IRQ_INTP((n) + 9)  /* 0 is unused! */
-+#define IRQ_GINT_NUM		4		   /* 0 is unused! */
-+
-+/* The shared interrupt line from the PIC is connected to CPU pin INTP23.  */
-+#define IRQ_CB_PIC		IRQ_INTP(4) /* P23 */
-+
-+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
-+#define NUM_RTE_CB_IRQS		(NUM_CPU_IRQS + IRQ_CB_PIC_NUM)
-+
-+
-+#ifndef __ASSEMBLY__
-+struct cb_pic_irq_init {
-+	const char *name;	/* name of interrupt type */
-+
-+	/* Range of kernel irq numbers for this type:
-+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
-+	unsigned base, num, interval;
-+
-+	unsigned priority;	/* interrupt priority to assign */
-+};
-+struct hw_interrupt_type;	/* fwd decl */
-+
-+/* Enable interrupt handling for interrupt IRQ.  */
-+extern void cb_pic_enable_irq (unsigned irq);
-+/* Disable interrupt handling for interrupt IRQ.  Note that any interrupts
-+   received while disabled will be delivered once the interrupt is enabled
-+   again, unless they are explicitly cleared using `cb_pic_clear_pending_irq'.  */
-+extern void cb_pic_disable_irq (unsigned irq);
-+/* Initialize HW_IRQ_TYPES for PIC irqs described in array INITS (which is
-+   terminated by an entry with the name field == 0).  */
-+extern void cb_pic_init_irq_types (struct cb_pic_irq_init *inits,
-+				   struct hw_interrupt_type *hw_irq_types);
-+/* Initialize PIC interrupts.  */
-+extern void cb_pic_init_irqs (void);
-+#endif /* __ASSEMBLY__ */
-+
-+
-+/* TL16C550C on board UART see also asm/serial.h */
-+#define CB_UART_BASE    	0x0FE08000
-+#define CB_UART_REG_GAP 	0x10
-+#define CB_UART_CLOCK   	0x16000000
-+
-+/* CompactFlash setting see also asm/ide.h, asm/hdreg.h.  */
-+#define CB_CF_BASE     		0x0FE0C000
-+#define CB_CF_CCR_ADDR 		(CB_CF_BASE+0x200)
-+#define CB_CF_CCR      		(*(volatile u8 *)CB_CF_CCR_ADDR)
-+#define CB_CF_REG0_ADDR		(CB_CF_BASE+0x1000)
-+#define CB_CF_REG0     		(*(volatile u16 *)CB_CF_REG0_ADDR)
-+#define CB_CF_STS0_ADDR		(CB_CF_BASE+0x1004)
-+#define CB_CF_STS0     		(*(volatile u16 *)CB_CF_STS0_ADDR)
-+#define CB_PCATA_BASE  		(CB_CF_BASE+0x800)
-+#define CB_IDE_BASE    		(CB_CF_BASE+0x9F0)
-+#define CB_IDE_CTRL    		(CB_CF_BASE+0xBF6)
-+#define CB_IDE_REG_OFFS		0x1
-+
-+
-+/* SMSC LAN91C111 setting */
-+#if defined(CONFIG_SMC91111)
-+#define CB_LANC_BASE 		0x0FE10300
-+#define CONFIG_SMC16BITONLY
-+#define ETH0_ADDR 		CB_LANC_BASE
-+#define ETH0_IRQ 		IRQ_CB_LANC
-+#endif /* CONFIG_SMC16BITONLY */
-+
-+
-+#undef V850E_UART_PRE_CONFIGURE
-+#define V850E_UART_PRE_CONFIGURE	rte_me2_cb_uart_pre_configure
-+#ifndef __ASSEMBLY__
-+extern void rte_me2_cb_uart_pre_configure (unsigned chan,
-+					   unsigned cflags, unsigned baud);
-+#endif /* __ASSEMBLY__ */
-+
-+/* This board supports RTS/CTS for the on-chip UART, but only for channel 0. */
-+
-+/* CTS for UART channel 0 is pin P22 (bit 2 of port 2).  */
-+#define V850E_UART_CTS(chan)	((chan) == 0 ? !(ME2_PORT2_IO & 0x4) : 1)
-+/* RTS for UART channel 0 is pin P21 (bit 1 of port 2).  */
-+#define V850E_UART_SET_RTS(chan, val)					      \
-+   do {									      \
-+	   if (chan == 0) {						      \
-+		   unsigned old = ME2_PORT2_IO; 			      \
-+		   if (val)						      \
-+			   ME2_PORT2_IO = old & ~0x2;			      \
-+		   else							      \
-+			   ME2_PORT2_IO = old | 0x2;			      \
-+	   }								      \
-+   } while (0)
-+
-+
-+#ifndef __ASSEMBLY__
-+extern void rte_me2_cb_init_irqs (void);
-+#endif /* !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_RTE_ME2_CB_H__ */
---- linux-2.6.0-test1/include/asm-v850/rte_nb85e_cb.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/asm-v850/rte_nb85e_cb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -17,6 +17,21 @@
- #include <asm/rte_cb.h>		/* Common defs for Midas RTE-CB boards.  */
- 
- 
-+#define PLATFORM		"rte-v850e/nb85e-cb"
-+#define PLATFORM_LONG		"Midas lab RTE-V850E/NB85E-CB"
-+
-+#define CPU_CLOCK_FREQ		50000000 /* 50MHz */
-+
-+/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
-+   for its own purposes, so care must be taken.  */
-+#define SRAM_ADDR		0x03C00000
-+#define SRAM_SIZE		0x00100000 /* 1MB */
-+
-+/* 16MB of onbard SDRAM.  */
-+#define SDRAM_ADDR		0x01000000
-+#define SDRAM_SIZE		0x01000000 /* 16MB */
-+
-+
- /* CPU addresses of GBUS memory spaces.  */
- #define GCS0_ADDR		0x00400000 /* GCS0 - Common SRAM (2MB) */
- #define GCS0_SIZE		0x00400000 /*   4MB */
-@@ -39,20 +54,8 @@
- #define IRQ_GINT(n)		(10 + (n))
- #define IRQ_GINT_NUM		3
- 
--
--#define PLATFORM	"rte-v850e/nb85e-cb"
--#define PLATFORM_LONG	"Midas lab RTE-V850E/NB85E-CB"
--
--#define CPU_CLOCK_FREQ	50000000 /* 50MHz */
--
--/* 1MB of onboard SRAM.  Note that the monitor ROM uses parts of this
--   for its own purposes, so care must be taken.  */
--#define SRAM_ADDR	0x03C00000
--#define SRAM_SIZE	0x00100000 /* 1MB */
--
--/* 16MB of onbard SDRAM.  */
--#define SDRAM_ADDR	0x01000000
--#define SDRAM_SIZE	0x01000000 /* 16MB */
-+/* Used by <asm/rte_cb.h> to derive NUM_MACH_IRQS.  */
-+#define NUM_RTE_CB_IRQS		NUM_CPU_IRQS
- 
- 
- #ifdef CONFIG_ROM_KERNEL
-@@ -86,8 +89,8 @@
- 
- /* Override the basic TEG UART pre-initialization so that we can
-    initialize extra stuff.  */
--#undef NB85E_UART_PRE_CONFIGURE	/* should be defined by <asm/teg.h> */
--#define NB85E_UART_PRE_CONFIGURE	rte_nb85e_cb_uart_pre_configure
-+#undef V850E_UART_PRE_CONFIGURE	/* should be defined by <asm/teg.h> */
-+#define V850E_UART_PRE_CONFIGURE	rte_nb85e_cb_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void rte_nb85e_cb_uart_pre_configure (unsigned chan,
- 					     unsigned cflags, unsigned baud);
-@@ -96,9 +99,9 @@ extern void rte_nb85e_cb_uart_pre_config
- /* This board supports RTS/CTS for the on-chip UART. */
- 
- /* CTS is pin P00.  */
--#define NB85E_UART_CTS(chan)	(! (TEG_PORT0_IO & 0x1))
-+#define V850E_UART_CTS(chan)	(! (TEG_PORT0_IO & 0x1))
- /* RTS is pin P02.  */
--#define NB85E_UART_SET_RTS(chan, val)					      \
-+#define V850E_UART_SET_RTS(chan, val)					      \
-    do {									      \
- 	   unsigned old = TEG_PORT0_IO;					      \
- 	   TEG_PORT0_IO = val ? (old & ~0x4) : (old | 0x4);		      \
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/serial.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,58 @@
-+/*
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1999 by Ralf Baechle
-+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
-+ */ 
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_RTE_CB_ME2
-+
-+#include <asm/rte_me2_cb.h>
-+
-+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-+
-+#define irq_cannonicalize(x) (x)
-+#define BASE_BAUD	250000	/* (16MHz / (16 * 38400)) * 9600 */
-+#define RS_TABLE_SIZE	1
-+#define SERIAL_PORT_DFNS \
-+   { 0, BASE_BAUD, CB_UART_BASE, IRQ_CB_EXTSIO, STD_COM_FLAGS },
-+
-+/* Redefine UART register offsets.  */
-+#undef UART_RX
-+#undef UART_TX
-+#undef UART_DLL
-+#undef UART_TRG
-+#undef UART_DLM
-+#undef UART_IER
-+#undef UART_FCTR
-+#undef UART_IIR
-+#undef UART_FCR
-+#undef UART_EFR
-+#undef UART_LCR
-+#undef UART_MCR
-+#undef UART_LSR
-+#undef UART_MSR
-+#undef UART_SCR
-+#undef UART_EMSR
-+
-+#define UART_RX		(0 * CB_UART_REG_GAP)
-+#define UART_TX		(0 * CB_UART_REG_GAP)
-+#define UART_DLL	(0 * CB_UART_REG_GAP)
-+#define UART_TRG	(0 * CB_UART_REG_GAP)
-+#define UART_DLM	(1 * CB_UART_REG_GAP)
-+#define UART_IER	(1 * CB_UART_REG_GAP)
-+#define UART_FCTR	(1 * CB_UART_REG_GAP)
-+#define UART_IIR	(2 * CB_UART_REG_GAP)
-+#define UART_FCR	(2 * CB_UART_REG_GAP)
-+#define UART_EFR	(2 * CB_UART_REG_GAP)
-+#define UART_LCR	(3 * CB_UART_REG_GAP)
-+#define UART_MCR	(4 * CB_UART_REG_GAP)
-+#define UART_LSR	(5 * CB_UART_REG_GAP)
-+#define UART_MSR	(6 * CB_UART_REG_GAP)
-+#define UART_SCR	(7 * CB_UART_REG_GAP)
-+#define UART_EMSR	(7 * CB_UART_REG_GAP)
-+
-+#endif /* CONFIG_RTE_CB_ME2 */
---- linux-2.6.0-test1/include/asm-v850/sim85e2c.h	2003-06-14 12:18:01.000000000 -0700
-+++ 25/include/asm-v850/sim85e2c.h	2003-07-19 17:03:51.000000000 -0700
-@@ -15,78 +15,12 @@
- #ifndef __V850_SIM85E2C_H__
- #define __V850_SIM85E2C_H__
- 
-+/* Use generic sim85e2 settings, other than the various names.  */
-+#include <asm/sim85e2.h>
- 
--#define CPU_ARCH 	"v850e2"
- #define CPU_MODEL	"v850e2"
- #define CPU_MODEL_LONG	"NEC V850E2"
- #define PLATFORM	"sim85e2c"
- #define PLATFORM_LONG	"SIM85E2C V850E2 simulator"
- 
--
--/* Various memory areas supported by the simulator.
--   These should match the corresponding definitions in the linker script.  */
--
--/* `instruction RAM'; instruction fetches are much faster from IRAM than
--   from DRAM.  */
--#define IRAM_ADDR		0
--#define IRAM_SIZE		0x00100000 /* 1MB */
--/* `data RAM', below and contiguous with the I/O space.
--   Data fetches are much faster from DRAM than from IRAM.  */
--#define DRAM_ADDR		0xfff00000
--#define DRAM_SIZE		0x000ff000 /* 1020KB */
--/* `external ram'.  Unlike the above RAM areas, this memory is cached,
--   so both instruction and data fetches should be (mostly) fast --
--   however, currently only write-through caching is supported, so writes
--   to ERAM will be slow.  */
--#define ERAM_ADDR		0x00100000
--#define ERAM_SIZE		0x07f00000 /* 127MB (max) */
--
--
--/* CPU core control registers; these should be expanded and moved into
--   separate header files when we support some other processors based on
--   the same E2 core.  */
--/* Bus Transaction Control Register */
--#define NA85E2C_CACHE_BTSC_ADDR	0xfffff070
--#define NA85E2C_CACHE_BTSC 	(*(volatile unsigned short *)NA85E2C_CACHE_BTSC_ADDR)
--#define NA85E2C_CACHE_BTSC_ICM	0x1 /* icache enable */
--#define NA85E2C_CACHE_BTSC_DCM0	0x4 /* dcache enable, bit 0 */
--#define NA85E2C_CACHE_BTSC_DCM1	0x8 /* dcache enable, bit 1 */
--/* Cache Configuration Register */
--#define NA85E2C_BUSM_BHC_ADDR	0xfffff06a
--#define NA85E2C_BUSM_BHC	(*(volatile unsigned short *)NA85E2C_BUSM_BHC_ADDR)
--
--/* Simulator specific control registers.  */
--/* NOTHAL controls whether the simulator will stop at a `halt' insn.  */
--#define NOTHAL_ADDR		0xffffff22
--#define NOTHAL			(*(volatile unsigned char *)NOTHAL_ADDR)
--/* The simulator will stop N cycles after N is written to SIMFIN.  */
--#define SIMFIN_ADDR		0xffffff24
--#define SIMFIN			(*(volatile unsigned short *)SIMFIN_ADDR)
--
--
--/* The simulator has an nb85e-style interrupt system.  */
--#include <asm/nb85e_intc.h>
--
--/* For <asm/irq.h> */
--#define NUM_CPU_IRQS		64
--
--
--/* For <asm/page.h> */
--#define PAGE_OFFSET		DRAM_ADDR
--
--
--/* For <asm/entry.h> */
--/* `R0 RAM', used for a few miscellaneous variables that must be accessible
--   using a load instruction relative to R0.  The sim85e2c simulator
--   actually puts 1020K of RAM from FFF00000 to FFFFF000, so we arbitarily
--   choose a small portion at the end of that.  */
--#define R0_RAM_ADDR		0xFFFFE000
--
--
--/* For <asm/param.h> */
--#ifndef HZ
--#define HZ			24	/* Minimum supported frequency.  */
--#endif
--
--
- #endif /* __V850_SIM85E2C_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/sim85e2.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,79 @@
-+/*
-+ * include/asm-v850/sim85e2.h -- Machine-dependent defs for
-+ *	V850E2 RTL simulator
-+ *
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_SIM85E2_H__
-+#define __V850_SIM85E2_H__
-+
-+
-+#include <asm/v850e2.h>		/* Based on V850E2 core.  */
-+
-+
-+/* Various memory areas supported by the simulator.
-+   These should match the corresponding definitions in the linker script.  */
-+
-+/* `instruction RAM'; instruction fetches are much faster from IRAM than
-+   from DRAM.  */
-+#define IRAM_ADDR		0
-+#define IRAM_SIZE		0x00100000 /* 1MB */
-+/* `data RAM', below and contiguous with the I/O space.
-+   Data fetches are much faster from DRAM than from IRAM.  */
-+#define DRAM_ADDR		0xfff00000
-+#define DRAM_SIZE		0x000ff000 /* 1020KB */
-+/* `external ram'.  Unlike the above RAM areas, this memory is cached,
-+   so both instruction and data fetches should be (mostly) fast --
-+   however, currently only write-through caching is supported, so writes
-+   to ERAM will be slow.  */
-+#define ERAM_ADDR		0x00100000
-+#define ERAM_SIZE		0x07f00000 /* 127MB (max) */
-+/* Dynamic RAM; uses memory controller.  */
-+#define SDRAM_ADDR		0x10000000
-+#if 0
-+#define SDRAM_SIZE		0x01000000 /* 16MB */
-+#else
-+#define SDRAM_SIZE		0x00200000 /* Only use 2MB for testing */
-+#endif
-+
-+
-+/* Simulator specific control registers.  */
-+/* NOTHAL controls whether the simulator will stop at a `halt' insn.  */
-+#define SIM85E2_NOTHAL_ADDR	0xffffff22
-+#define SIM85E2_NOTHAL		(*(volatile u8 *)SIM85E2_NOTHAL_ADDR)
-+/* The simulator will stop N cycles after N is written to SIMFIN.  */
-+#define SIM85E2_SIMFIN_ADDR	0xffffff24
-+#define SIM85E2_SIMFIN		(*(volatile u16 *)SIM85E2_SIMFIN_ADDR)
-+
-+
-+/* For <asm/irq.h> */
-+#define NUM_CPU_IRQS		64
-+
-+
-+/* For <asm/page.h> */
-+#define PAGE_OFFSET		SDRAM_ADDR
-+
-+
-+/* For <asm/entry.h> */
-+/* `R0 RAM', used for a few miscellaneous variables that must be accessible
-+   using a load instruction relative to R0.  The sim85e2 simulator
-+   actually puts 1020K of RAM from FFF00000 to FFFFF000, so we arbitarily
-+   choose a small portion at the end of that.  */
-+#define R0_RAM_ADDR		0xFFFFE000
-+
-+
-+/* For <asm/param.h> */
-+#ifndef HZ
-+#define HZ			24	/* Minimum supported frequency.  */
-+#endif
-+
-+
-+#endif /* __V850_SIM85E2_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/sim85e2s.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,28 @@
-+/*
-+ * include/asm-v850/sim85e2s.h -- Machine-dependent defs for
-+ *	V850E2 RTL simulator
-+ *
-+ *  Copyright (C) 2003  NEC Electronics Corporation
-+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_SIM85E2S_H__
-+#define __V850_SIM85E2S_H__
-+
-+#include <asm/sim85e2.h>	/* Use generic sim85e2 settings.  */
-+#if 0
-+#include <asm/v850e2_cache.h>	/* + cache */
-+#endif
-+
-+#define CPU_MODEL	"v850e2"
-+#define CPU_MODEL_LONG	"NEC V850E2"
-+#define PLATFORM	"sim85e2s"
-+#define PLATFORM_LONG	"SIM85E2S V850E2 simulator"
-+
-+#endif /* __V850_SIM85E2S_H__ */
---- linux-2.6.0-test1/include/asm-v850/stat.h	2003-06-14 12:18:26.000000000 -0700
-+++ 25/include/asm-v850/stat.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/stat.h -- v850 stat structure
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
---- linux-2.6.0-test1/include/asm-v850/system.h	2003-06-14 12:18:29.000000000 -0700
-+++ 25/include/asm-v850/system.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  * include/asm-v850/system.h -- Low-level interrupt/thread ops
-  *
-- *  Copyright (C) 2001,02,03  NEC Corporation
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-  *
-  * This file is subject to the terms and conditions of the GNU General
---- linux-2.6.0-test1/include/asm-v850/teg.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/asm-v850/teg.h	2003-07-19 17:03:51.000000000 -0700
-@@ -15,9 +15,9 @@
- #define __V850_TEG_H__
- 
- 
--/* The TEG uses the NB85E cpu core.  */
--#include <asm/nb85e.h>
--#include <asm/nb85e_cache.h>
-+/* The TEG uses the V850E cpu core.  */
-+#include <asm/v850e.h>
-+#include <asm/v850e_cache.h>
- 
- 
- #define CPU_MODEL	"v850e/nb85e-teg"
-@@ -51,18 +51,18 @@
- 
- 
- /* TEG UART details.  */
--#define NB85E_UART_BASE_ADDR(n)		(0xFFFFF600 + 0x10 * (n))
--#define NB85E_UART_ASIM_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x0)
--#define NB85E_UART_ASIS_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x2)
--#define NB85E_UART_ASIF_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x4)
--#define NB85E_UART_CKSR_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x6)
--#define NB85E_UART_BRGC_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0x8)
--#define NB85E_UART_TXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0xA)
--#define NB85E_UART_RXB_ADDR(n)		(NB85E_UART_BASE_ADDR(n) + 0xC)
--#define NB85E_UART_NUM_CHANNELS		1
--#define NB85E_UART_BASE_FREQ		CPU_CLOCK_FREQ
-+#define V850E_UART_BASE_ADDR(n)		(0xFFFFF600 + 0x10 * (n))
-+#define V850E_UART_ASIM_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x0)
-+#define V850E_UART_ASIS_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x2)
-+#define V850E_UART_ASIF_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x4)
-+#define V850E_UART_CKSR_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x6)
-+#define V850E_UART_BRGC_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x8)
-+#define V850E_UART_TXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0xA)
-+#define V850E_UART_RXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0xC)
-+#define V850E_UART_NUM_CHANNELS		1
-+#define V850E_UART_BASE_FREQ		CPU_CLOCK_FREQ
- /* This is a function that gets called before configuring the UART.  */
--#define NB85E_UART_PRE_CONFIGURE	teg_uart_pre_configure
-+#define V850E_UART_PRE_CONFIGURE	teg_uart_pre_configure
- #ifndef __ASSEMBLY__
- extern void teg_uart_pre_configure (unsigned chan,
- 				    unsigned cflags, unsigned baud);
-@@ -70,15 +70,15 @@ extern void teg_uart_pre_configure (unsi
- 
- 
- /* The TEG RTPU.  */
--#define NB85E_RTPU_BASE_ADDR		0xFFFFF210
-+#define V850E_RTPU_BASE_ADDR		0xFFFFF210
- 
- 
- /* TEG series timer D details.  */
--#define NB85E_TIMER_D_BASE_ADDR		0xFFFFF210
--#define NB85E_TIMER_D_TMCD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x0)
--#define NB85E_TIMER_D_TMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x4)
--#define NB85E_TIMER_D_CMD_BASE_ADDR 	(NB85E_TIMER_D_BASE_ADDR + 0x8)
--#define NB85E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
-+#define V850E_TIMER_D_BASE_ADDR		0xFFFFF210
-+#define V850E_TIMER_D_TMCD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x0)
-+#define V850E_TIMER_D_TMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x4)
-+#define V850E_TIMER_D_CMD_BASE_ADDR 	(V850E_TIMER_D_BASE_ADDR + 0x8)
-+#define V850E_TIMER_D_BASE_FREQ		CPU_CLOCK_FREQ
- 
- 
- /* `Interrupt Source Select' control register.  */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e2_cache.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,74 @@
-+/*
-+ * include/asm-v850/v850e2_cache_cache.h -- Cache control for V850E2
-+ * 	cache memories
-+ *
-+ *  Copyright (C) 2003  NEC Electronics Corporation
-+ *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E2_CACHE_H__
-+#define __V850_V850E2_CACHE_H__
-+
-+#include <asm/types.h>
-+
-+
-+/* Cache control registers.  */
-+
-+/* Bus Transaction Control */
-+#define V850E2_CACHE_BTSC_ADDR	0xFFFFF070
-+#define V850E2_CACHE_BTSC 	(*(volatile u16 *)V850E2_CACHE_BTSC_ADDR)
-+#define V850E2_CACHE_BTSC_ICM	0x0001 /* icache enable */
-+#define V850E2_CACHE_BTSC_DCM0	0x0004 /* dcache enable, bit 0 */
-+#define V850E2_CACHE_BTSC_DCM1	0x0008 /* dcache enable, bit 1 */
-+#define V850E2_CACHE_BTSC_DCM_WT		      /* write-through */ \
-+			V850E2_CACHE_BTSC_DCM0
-+#ifdef CONFIG_V850E2_V850E2S
-+# define V850E2_CACHE_BTSC_DCM_WB_NO_ALLOC    /* write-back, non-alloc */ \
-+			V850E2_CACHE_BTSC_DCM1	
-+# define V850E2_CACHE_BTSC_DCM_WB_ALLOC	      /* write-back, non-alloc */ \
-+			(V850E2_CACHE_BTSC_DCM1 | V850E2_CACHE_BTSC_DCM0)
-+# define V850E2_CACHE_BTSC_ISEQ	0x0010 /* icache `address sequence mode' */
-+# define V850E2_CACHE_BTSC_DSEQ	0x0020 /* dcache `address sequence mode' */
-+# define V850E2_CACHE_BTSC_IRFC	0x0030
-+# define V850E2_CACHE_BTSC_ILCD	0x4000
-+# define V850E2_CACHE_BTSC_VABE	0x8000
-+#endif /* CONFIG_V850E2_V850E2S */
-+
-+/* Cache operation start address register (low-bits).  */
-+#define V850E2_CACHE_CADL_ADDR	0xFFFFF074
-+#define V850E2_CACHE_CADL 	(*(volatile u16 *)V850E2_CACHE_CADL_ADDR)
-+/* Cache operation start address register (high-bits).  */
-+#define V850E2_CACHE_CADH_ADDR	0xFFFFF076
-+#define V850E2_CACHE_CADH 	(*(volatile u16 *)V850E2_CACHE_CADH_ADDR)
-+/* Cache operation count register.  */
-+#define V850E2_CACHE_CCNT_ADDR	0xFFFFF078
-+#define V850E2_CACHE_CCNT 	(*(volatile u16 *)V850E2_CACHE_CCNT_ADDR)
-+/* Cache operation specification register.  */
-+#define V850E2_CACHE_COPR_ADDR	0xFFFFF07A
-+#define V850E2_CACHE_COPR 	(*(volatile u16 *)V850E2_CACHE_COPR_ADDR)
-+#define V850E2_CACHE_COPR_STRT	0x0001 /* start cache operation */
-+#define V850E2_CACHE_COPR_LBSL	0x0100 /* 0 = icache, 1 = dcache */
-+#define V850E2_CACHE_COPR_WSLE	0x0200 /* operate on cache way */
-+#define V850E2_CACHE_COPR_WSL(way) ((way) * 0x0400) /* way select */
-+#define V850E2_CACHE_COPR_CFC(op)  ((op)  * 0x1000) /* cache function code */
-+
-+
-+/* Size of a cache line in bytes.  */
-+#define V850E2_CACHE_LINE_SIZE_BITS	4
-+#define V850E2_CACHE_LINE_SIZE		(1 << V850E2_CACHE_LINE_SIZE_BITS)
-+
-+/* The size of each cache `way' in lines.  */
-+#define V850E2_CACHE_WAY_SIZE		256
-+
-+
-+/* For <asm/cache.h> */
-+#define L1_CACHE_BYTES			V850E2_CACHE_LINE_SIZE
-+
-+
-+#endif /* __V850_V850E2_CACHE_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e2.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,69 @@
-+/*
-+ * include/asm-v850/v850e2.h -- Machine-dependent defs for V850E2 CPUs
-+ *
-+ *  Copyright (C) 2002,03  NEC Electronics Corporation
-+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E2_H__
-+#define __V850_V850E2_H__
-+
-+#include <asm/v850e_intc.h>	/* v850e-style interrupt system.  */
-+
-+
-+#define CPU_ARCH "v850e2"
-+
-+
-+/* Control registers.  */
-+
-+/* Chip area select control */ 
-+#define V850E2_CSC_ADDR(n)	(0xFFFFF060 + (n) * 2)
-+#define V850E2_CSC(n)		(*(volatile u16 *)V850E2_CSC_ADDR(n))
-+/* I/O area select control */
-+#define V850E2_BPC_ADDR		0xFFFFF064
-+#define V850E2_BPC		(*(volatile u16 *)V850E2_BPC_ADDR)
-+/* Bus size configuration */
-+#define V850E2_BSC_ADDR		0xFFFFF066
-+#define V850E2_BSC		(*(volatile u16 *)V850E2_BSC_ADDR)
-+/* Endian configuration */
-+#define V850E2_BEC_ADDR		0xFFFFF068
-+#define V850E2_BEC		(*(volatile u16 *)V850E2_BEC_ADDR)
-+/* Cache configuration */
-+#define V850E2_BHC_ADDR		0xFFFFF06A
-+#define V850E2_BHC		(*(volatile u16 *)V850E2_BHC_ADDR)
-+/* NPB strobe-wait configuration */
-+#define V850E2_VSWC_ADDR	0xFFFFF06E
-+#define V850E2_VSWC		(*(volatile u16 *)V850E2_VSWC_ADDR)
-+/* Bus cycle type */
-+#define V850E2_BCT_ADDR(n)	(0xFFFFF480 + (n) * 2)
-+#define V850E2_BCT(n)		(*(volatile u16 *)V850E2_BCT_ADDR(n))
-+/* Data wait control */
-+#define V850E2_DWC_ADDR(n)	(0xFFFFF484 + (n) * 2)
-+#define V850E2_DWC(n)		(*(volatile u16 *)V850E2_DWC_ADDR(n))
-+/* Bus cycle control */
-+#define V850E2_BCC_ADDR		0xFFFFF488
-+#define V850E2_BCC		(*(volatile u16 *)V850E2_BCC_ADDR)
-+/* Address wait control */
-+#define V850E2_ASC_ADDR		0xFFFFF48A
-+#define V850E2_ASC		(*(volatile u16 *)V850E2_ASC_ADDR)
-+/* Local bus sizing control */
-+#define V850E2_LBS_ADDR		0xFFFFF48E
-+#define V850E2_LBS		(*(volatile u16 *)V850E2_LBS_ADDR)
-+/* Line buffer control */
-+#define V850E2_LBC_ADDR(n)	(0xFFFFF490 + (n) * 2)
-+#define V850E2_LBC(n)		(*(volatile u16 *)V850E2_LBC_ADDR(n))
-+/* SDRAM configuration */
-+#define V850E2_SCR_ADDR(n)	(0xFFFFF4A0 + (n) * 4)
-+#define V850E2_SCR(n)		(*(volatile u16 *)V850E2_SCR_ADDR(n))
-+/* SDRAM refresh cycle control */
-+#define V850E2_RFS_ADDR(n)	(0xFFFFF4A2 + (n) * 4)
-+#define V850E2_RFS(n)		(*(volatile u16 *)V850E2_RFS_ADDR(n))
-+
-+
-+#endif /* __V850_V850E2_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_cache.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,48 @@
-+/*
-+ * include/asm-v850/v850e_cache.h -- Cache control for V850E cache memories
-+ *
-+ *  Copyright (C) 2001,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* This file implements cache control for the rather simple cache used on
-+   some V850E CPUs, specifically the NB85E/TEG CPU-core and the V850E/ME2
-+   CPU.  V850E2 processors have their own (better) cache
-+   implementation.  */
-+
-+#ifndef __V850_V850E_CACHE_H__
-+#define __V850_V850E_CACHE_H__
-+
-+#include <asm/types.h>
-+
-+
-+/* Cache control registers.  */
-+#define V850E_CACHE_BHC_ADDR	0xFFFFF06A
-+#define V850E_CACHE_BHC		(*(volatile u16 *)V850E_CACHE_BHC_ADDR)
-+#define V850E_CACHE_ICC_ADDR	0xFFFFF070
-+#define V850E_CACHE_ICC		(*(volatile u16 *)V850E_CACHE_ICC_ADDR)
-+#define V850E_CACHE_ISI_ADDR	0xFFFFF072
-+#define V850E_CACHE_ISI		(*(volatile u16 *)V850E_CACHE_ISI_ADDR)
-+#define V850E_CACHE_DCC_ADDR	0xFFFFF078
-+#define V850E_CACHE_DCC		(*(volatile u16 *)V850E_CACHE_DCC_ADDR)
-+
-+/* Size of a cache line in bytes.  */
-+#define V850E_CACHE_LINE_SIZE	16
-+
-+/* For <asm/cache.h> */
-+#define L1_CACHE_BYTES		V850E_CACHE_LINE_SIZE
-+
-+
-+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
-+/* Set caching params via the BHC, ICC, and DCC registers.  */
-+void v850e_cache_enable (u16 bhc, u16 icc, u16 dcc);
-+#endif /* __KERNEL__ && !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_V850E_CACHE_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,21 @@
-+/*
-+ * include/asm-v850/v850e.h -- V850E CPU
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E_H__
-+#define __V850_V850E_H__
-+
-+#include <asm/v850e_intc.h>
-+
-+#define CPU_ARCH "v850e"
-+
-+#endif /* __V850_V850E_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_intc.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,133 @@
-+/*
-+ * include/asm-v850/v850e_intc.h -- V850E CPU interrupt controller (INTC)
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E_INTC_H__
-+#define __V850_V850E_INTC_H__
-+
-+
-+/* There are 4 16-bit `Interrupt Mask Registers' located contiguously
-+   starting from this base.  Each interrupt uses a single bit to
-+   indicated enabled/disabled status.  */
-+#define V850E_INTC_IMR_BASE_ADDR  0xFFFFF100
-+#define V850E_INTC_IMR_ADDR(irq)  (V850E_INTC_IMR_BASE_ADDR + ((irq) >> 3))
-+#define V850E_INTC_IMR_BIT(irq)	  ((irq) & 0x7)
-+
-+/* Each maskable interrupt has a single-byte control register at this
-+   address.  */
-+#define V850E_INTC_IC_BASE_ADDR	  0xFFFFF110
-+#define V850E_INTC_IC_ADDR(irq)	  (V850E_INTC_IC_BASE_ADDR + ((irq) << 1))
-+#define V850E_INTC_IC(irq)	  (*(volatile u8 *)V850E_INTC_IC_ADDR(irq))
-+/* Encode priority PR for storing in an interrupt control register.  */
-+#define V850E_INTC_IC_PR(pr)	  (pr)
-+/* Interrupt disable bit in an interrupt control register.  */
-+#define V850E_INTC_IC_MK_BIT	  6
-+#define V850E_INTC_IC_MK	  (1 << V850E_INTC_IC_MK_BIT)
-+/* Interrupt pending flag in an interrupt control register.  */
-+#define V850E_INTC_IC_IF_BIT	  7
-+#define V850E_INTC_IC_IF	  (1 << V850E_INTC_IC_IF_BIT)
-+
-+/* The ISPR (In-service priority register) contains one bit for each interrupt
-+   priority level, which is set to one when that level is currently being
-+   serviced (and thus blocking any interrupts of equal or lesser level).  */
-+#define V850E_INTC_ISPR_ADDR	  0xFFFFF1FA
-+#define V850E_INTC_ISPR		  (*(volatile u8 *)V850E_INTC_ISPR_ADDR)
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+/* Enable interrupt handling for interrupt IRQ.  */
-+static inline void v850e_intc_enable_irq (unsigned irq)
-+{
-+	__asm__ __volatile__ ("clr1 %0, [%1]"
-+			      :: "r" (V850E_INTC_IMR_BIT (irq)),
-+			         "r" (V850E_INTC_IMR_ADDR (irq))
-+			      : "memory");
-+}
-+
-+/* Disable interrupt handling for interrupt IRQ.  Note that any
-+   interrupts received while disabled will be delivered once the
-+   interrupt is enabled again, unless they are explicitly cleared using
-+   `v850e_intc_clear_pending_irq'.  */
-+static inline void v850e_intc_disable_irq (unsigned irq)
-+{
-+	__asm__ __volatile__ ("set1 %0, [%1]"
-+			      :: "r" (V850E_INTC_IMR_BIT (irq)),
-+			         "r" (V850E_INTC_IMR_ADDR (irq))
-+			      : "memory");
-+}
-+
-+/* Return true if interrupt handling for interrupt IRQ is enabled.  */
-+static inline int v850e_intc_irq_enabled (unsigned irq)
-+{
-+	int rval;
-+	__asm__ __volatile__ ("tst1 %1, [%2]; setf z, %0"
-+			      : "=r" (rval)
-+			      : "r" (V850E_INTC_IMR_BIT (irq)),
-+			        "r" (V850E_INTC_IMR_ADDR (irq)));
-+	return rval;
-+}
-+
-+/* Disable irqs from 0 until LIMIT.  LIMIT must be a multiple of 8.  */
-+static inline void _v850e_intc_disable_irqs (unsigned limit)
-+{
-+	unsigned long addr;
-+	for (addr = V850E_INTC_IMR_BASE_ADDR; limit >= 8; addr++, limit -= 8)
-+		*(char *)addr = 0xFF;
-+}
-+
-+/* Disable all irqs.  This is purposely a macro, because NUM_MACH_IRQS
-+   will be only be defined later.  */
-+#define v850e_intc_disable_irqs()   _v850e_intc_disable_irqs (NUM_MACH_IRQS)
-+
-+/* Clear any pending interrupts for IRQ.  */
-+static inline void v850e_intc_clear_pending_irq (unsigned irq)
-+{
-+	__asm__ __volatile__ ("clr1 %0, 0[%1]"
-+			      :: "i" (V850E_INTC_IC_IF_BIT),
-+			         "r" (V850E_INTC_IC_ADDR (irq))
-+			      : "memory");
-+}
-+
-+/* Return true if interrupt IRQ is pending (but disabled).  */
-+static inline int v850e_intc_irq_pending (unsigned irq)
-+{
-+	int rval;
-+	__asm__ __volatile__ ("tst1 %1, 0[%2]; setf nz, %0"
-+			      : "=r" (rval)
-+			      : "i" (V850E_INTC_IC_IF_BIT),
-+			        "r" (V850E_INTC_IC_ADDR (irq)));
-+	return rval;
-+}
-+
-+
-+struct v850e_intc_irq_init {
-+	const char *name;	/* name of interrupt type */
-+
-+	/* Range of kernel irq numbers for this type:
-+	   BASE, BASE+INTERVAL, ..., BASE+INTERVAL*NUM  */
-+	unsigned base, num, interval;
-+
-+	unsigned priority;	/* interrupt priority to assign */
-+};
-+struct hw_interrupt_type;	/* fwd decl */
-+
-+/* Initialize HW_IRQ_TYPES for INTC-controlled irqs described in array
-+   INITS (which is terminated by an entry with the name field == 0).  */
-+extern void v850e_intc_init_irq_types (struct v850e_intc_irq_init *inits,
-+				       struct hw_interrupt_type *hw_irq_types);
-+
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_V850E_INTC_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_timer_c.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,48 @@
-+/*
-+ * include/asm-v850/v850e_timer_c.h -- `Timer C' component often used
-+ *	with the V850E cpu core
-+ *
-+ *  Copyright (C) 2001,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* NOTE: this include file currently contains only enough to allow us to
-+   use timer C as an interrupt pass-through.  */
-+
-+#ifndef __V850_V850E_TIMER_C_H__
-+#define __V850_V850E_TIMER_C_H__
-+
-+#include <asm/types.h>
-+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
-+
-+
-+/* Timer C (16-bit interval timers).  */
-+
-+/* Control register 0 for timer C.  */
-+#define V850E_TIMER_C_TMCC0_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x6 + 0x10 *(n))
-+#define V850E_TIMER_C_TMCC0(n)	  (*(volatile u8 *)V850E_TIMER_C_TMCC0_ADDR(n))
-+#define V850E_TIMER_C_TMCC0_CAE	  0x01 /* clock action enable */
-+#define V850E_TIMER_C_TMCC0_CE	  0x02 /* count enable */
-+/* ... */
-+
-+/* Control register 1 for timer C.  */
-+#define V850E_TIMER_C_TMCC1_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x8 + 0x10 *(n))
-+#define V850E_TIMER_C_TMCC1(n)	  (*(volatile u8 *)V850E_TIMER_C_TMCC1_ADDR(n))
-+#define V850E_TIMER_C_TMCC1_CMS0  0x01 /* capture/compare mode select (ccc0) */
-+#define V850E_TIMER_C_TMCC1_CMS1  0x02 /* capture/compare mode select (ccc1) */
-+/* ... */
-+
-+/* Interrupt edge-sensitivity control for timer C.  */
-+#define V850E_TIMER_C_SESC_ADDR(n) (V850E_TIMER_C_BASE_ADDR + 0x9 + 0x10 *(n))
-+#define V850E_TIMER_C_SESC(n)	  (*(volatile u8 *)V850E_TIMER_C_SESC_ADDR(n))
-+
-+/* ...etc... */
-+
-+
-+#endif /* __V850_V850E_TIMER_C_H__  */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_timer_d.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,62 @@
-+/*
-+ * include/asm-v850/v850e_timer_d.h -- `Timer D' component often used
-+ *	with the V850E cpu core
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E_TIMER_D_H__
-+#define __V850_V850E_TIMER_D_H__
-+
-+#include <asm/types.h>
-+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
-+
-+
-+/* Timer D (16-bit interval timers).  */
-+
-+/* Count registers for timer D.  */
-+#define V850E_TIMER_D_TMD_ADDR(n) (V850E_TIMER_D_TMD_BASE_ADDR + 0x10 * (n))
-+#define V850E_TIMER_D_TMD(n)	  (*(volatile u16 *)V850E_TIMER_D_TMD_ADDR(n))
-+
-+/* Count compare registers for timer D.  */
-+#define V850E_TIMER_D_CMD_ADDR(n) (V850E_TIMER_D_CMD_BASE_ADDR + 0x10 * (n))
-+#define V850E_TIMER_D_CMD(n)	  (*(volatile u16 *)V850E_TIMER_D_CMD_ADDR(n))
-+
-+/* Control registers for timer D.  */
-+#define V850E_TIMER_D_TMCD_ADDR(n) (V850E_TIMER_D_TMCD_BASE_ADDR + 0x10 * (n))
-+#define V850E_TIMER_D_TMCD(n)	   (*(volatile u8 *)V850E_TIMER_D_TMCD_ADDR(n))
-+/* Control bits for timer D.  */
-+#define V850E_TIMER_D_TMCD_CE  	   0x2 /* count enable */
-+#define V850E_TIMER_D_TMCD_CAE	   0x1 /* clock action enable */
-+/* Clock divider setting (log2).  */
-+#define V850E_TIMER_D_TMCD_CS(divlog2) (((divlog2) - V850E_TIMER_D_TMCD_CS_MIN) << 4)
-+/* Minimum clock divider setting (log2).  */
-+#ifndef V850E_TIMER_D_TMCD_CS_MIN /* Can be overridden by mach-specific hdrs */
-+#define V850E_TIMER_D_TMCD_CS_MIN  2 /* Default is correct for the v850e/ma1 */
-+#endif
-+/* Maximum clock divider setting (log2).  */
-+#define V850E_TIMER_D_TMCD_CS_MAX  (V850E_TIMER_D_TMCD_CS_MIN + 7)
-+
-+/* Return the clock-divider (log2) of timer D unit N.  */
-+#define V850E_TIMER_D_DIVLOG2(n) \
-+  (((V850E_TIMER_D_TMCD(n) >> 4) & 0x7) + V850E_TIMER_D_TMCD_CS_MIN)
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+/* Start interval timer TIMER (0-3).  The timer will issue the
-+   corresponding INTCMD interrupt RATE times per second.  This function
-+   does not enable the interrupt.  */
-+extern void v850e_timer_d_configure (unsigned timer, unsigned rate);
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_V850E_TIMER_D_H__  */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_uarta.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,278 @@
-+/*
-+ * include/asm-v850/v850e_uarta.h -- original V850E on-chip UART
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* This is the original V850E UART implementation is called just `UART' in
-+   the docs, but we name this header file <asm/v850e_uarta.h> because the
-+   name <asm/v850e_uart.h> is used for the common driver that handles both
-+   `UART' and `UARTB' implementations.  */
-+
-+#ifndef __V850_V850E_UARTA_H__
-+#define __V850_V850E_UARTA_H__
-+
-+
-+/* Raw hardware interface.  */
-+
-+/* The base address of the UART control registers for channel N.
-+   The default is the address used on the V850E/MA1.  */
-+#ifndef V850E_UART_BASE_ADDR
-+#define V850E_UART_BASE_ADDR(n)		(0xFFFFFA00 + 0x10 * (n))
-+#endif 
-+
-+/* Addresses of specific UART control registers for channel N.
-+   The defaults are the addresses used on the V850E/MA1; if a platform
-+   wants to redefine any of these, it must redefine them all.  */
-+#ifndef V850E_UART_ASIM_ADDR
-+#define V850E_UART_ASIM_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x0)
-+#define V850E_UART_RXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x2)
-+#define V850E_UART_ASIS_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x3)
-+#define V850E_UART_TXB_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x4)
-+#define V850E_UART_ASIF_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x5)
-+#define V850E_UART_CKSR_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x6)
-+#define V850E_UART_BRGC_ADDR(n)		(V850E_UART_BASE_ADDR(n) + 0x7)
-+#endif
-+
-+/* UART config registers.  */
-+#define V850E_UART_ASIM(n)	(*(volatile u8 *)V850E_UART_ASIM_ADDR(n))
-+/* Control bits for config registers.  */
-+#define V850E_UART_ASIM_CAE	0x80 /* clock enable */
-+#define V850E_UART_ASIM_TXE	0x40 /* transmit enable */
-+#define V850E_UART_ASIM_RXE	0x20 /* receive enable */
-+#define V850E_UART_ASIM_PS_MASK	0x18 /* mask covering parity-select bits */
-+#define V850E_UART_ASIM_PS_NONE	0x00 /* no parity */
-+#define V850E_UART_ASIM_PS_ZERO	0x08 /* zero parity */
-+#define V850E_UART_ASIM_PS_ODD	0x10 /* odd parity */
-+#define V850E_UART_ASIM_PS_EVEN	0x18 /* even parity */
-+#define V850E_UART_ASIM_CL_8	0x04 /* char len is 8 bits (otherwise, 7) */
-+#define V850E_UART_ASIM_SL_2	0x02 /* 2 stop bits (otherwise, 1) */
-+#define V850E_UART_ASIM_ISRM	0x01 /* generate INTSR interrupt on errors
-+					(otherwise, generate INTSER) */
-+
-+/* UART serial interface status registers.  */
-+#define V850E_UART_ASIS(n)	(*(volatile u8 *)V850E_UART_ASIS_ADDR(n))
-+/* Control bits for status registers.  */
-+#define V850E_UART_ASIS_PE	0x04 /* parity error */
-+#define V850E_UART_ASIS_FE	0x02 /* framing error */
-+#define V850E_UART_ASIS_OVE	0x01 /* overrun error */
-+
-+/* UART serial interface transmission status registers.  */
-+#define V850E_UART_ASIF(n)	(*(volatile u8 *)V850E_UART_ASIF_ADDR(n))
-+#define V850E_UART_ASIF_TXBF	0x02 /* transmit buffer flag (data in TXB) */
-+#define V850E_UART_ASIF_TXSF	0x01 /* transmit shift flag (sending data) */
-+
-+/* UART receive buffer register.  */
-+#define V850E_UART_RXB(n)	(*(volatile u8 *)V850E_UART_RXB_ADDR(n))
-+
-+/* UART transmit buffer register.  */
-+#define V850E_UART_TXB(n)	(*(volatile u8 *)V850E_UART_TXB_ADDR(n))
-+
-+/* UART baud-rate generator control registers.  */
-+#define V850E_UART_CKSR(n)	(*(volatile u8 *)V850E_UART_CKSR_ADDR(n))
-+#define V850E_UART_CKSR_MAX	11
-+#define V850E_UART_BRGC(n)	(*(volatile u8 *)V850E_UART_BRGC_ADDR(n))
-+#define V850E_UART_BRGC_MIN	8
-+
-+
-+#ifndef V850E_UART_CKSR_MAX_FREQ
-+#define V850E_UART_CKSR_MAX_FREQ (25*1000*1000)
-+#endif
-+
-+/* Calculate the minimum value for CKSR on this processor.  */
-+static inline unsigned v850e_uart_cksr_min (void)
-+{
-+	int min = 0;
-+	unsigned freq = V850E_UART_BASE_FREQ;
-+	while (freq > V850E_UART_CKSR_MAX_FREQ) {
-+		freq >>= 1;
-+		min++;
-+	}
-+	return min;
-+}
-+
-+
-+/* Slightly abstract interface used by driver.  */
-+
-+
-+/* Interrupts used by the UART.  */
-+
-+/* Received when the most recently transmitted character has been sent.  */
-+#define V850E_UART_TX_IRQ(chan)		IRQ_INTST (chan)
-+/* Received when a new character has been received.  */
-+#define V850E_UART_RX_IRQ(chan)		IRQ_INTSR (chan)
-+
-+
-+/* UART clock generator interface.  */
-+
-+/* This type encapsulates a particular uart frequency.  */
-+typedef struct {
-+	unsigned clk_divlog2;
-+	unsigned brgen_count;
-+} v850e_uart_speed_t;
-+
-+/* Calculate a uart speed from BAUD for this uart.  */
-+static inline v850e_uart_speed_t v850e_uart_calc_speed (unsigned baud)
-+{
-+	v850e_uart_speed_t speed;
-+
-+	/* Calculate the log2 clock divider and baud-rate counter values
-+	   (note that the UART divides the resulting clock by 2, so
-+	   multiply BAUD by 2 here to compensate).  */
-+	calc_counter_params (V850E_UART_BASE_FREQ, baud * 2,
-+			     v850e_uart_cksr_min(),
-+			     V850E_UART_CKSR_MAX, 8/*bits*/,
-+			     &speed.clk_divlog2, &speed.brgen_count);
-+
-+	return speed;
-+}
-+
-+/* Return the current speed of uart channel CHAN.  */
-+static inline v850e_uart_speed_t v850e_uart_speed (unsigned chan)
-+{
-+	v850e_uart_speed_t speed;
-+	speed.clk_divlog2 = V850E_UART_CKSR (chan);
-+	speed.brgen_count = V850E_UART_BRGC (chan);
-+	return speed;
-+}
-+
-+/* Set the current speed of uart channel CHAN.  */
-+static inline void v850e_uart_set_speed(unsigned chan,v850e_uart_speed_t speed)
-+{
-+	V850E_UART_CKSR (chan) = speed.clk_divlog2;
-+	V850E_UART_BRGC (chan) = speed.brgen_count;
-+}
-+
-+static inline int
-+v850e_uart_speed_eq (v850e_uart_speed_t speed1, v850e_uart_speed_t speed2)
-+{
-+	return speed1.clk_divlog2 == speed2.clk_divlog2
-+		&& speed1.brgen_count == speed2.brgen_count;
-+}
-+
-+/* Minimum baud rate possible.  */
-+#define v850e_uart_min_baud() \
-+   ((V850E_UART_BASE_FREQ >> V850E_UART_CKSR_MAX) / (2 * 255) + 1)
-+
-+/* Maximum baud rate possible.  The error is quite high at max, though.  */
-+#define v850e_uart_max_baud() \
-+   ((V850E_UART_BASE_FREQ >> v850e_uart_cksr_min()) / (2 *V850E_UART_BRGC_MIN))
-+
-+/* The `maximum' clock rate the uart can used, which is wanted (though not
-+   really used in any useful way) by the serial framework.  */
-+#define v850e_uart_max_clock() \
-+   ((V850E_UART_BASE_FREQ >> v850e_uart_cksr_min()) / 2)
-+
-+
-+/* UART configuration interface.  */
-+
-+/* Type of the uart config register; must be a scalar.  */
-+typedef u16 v850e_uart_config_t;
-+
-+/* The uart hardware config register for channel CHAN.  */
-+#define V850E_UART_CONFIG(chan)		V850E_UART_ASIM (chan)
-+
-+/* This config bit set if the uart is enabled.  */
-+#define V850E_UART_CONFIG_ENABLED	V850E_UART_ASIM_CAE
-+/* If the uart _isn't_ enabled, store this value to it to do so.  */
-+#define V850E_UART_CONFIG_INIT		V850E_UART_ASIM_CAE
-+/* Store this config value to disable the uart channel completely.  */
-+#define V850E_UART_CONFIG_FINI		0
-+
-+/* Setting/clearing these bits enable/disable TX/RX, respectively (but
-+   otherwise generally leave things running).  */
-+#define V850E_UART_CONFIG_RX_ENABLE	V850E_UART_ASIM_RXE
-+#define V850E_UART_CONFIG_TX_ENABLE	V850E_UART_ASIM_TXE
-+
-+/* These masks define which config bits affect TX/RX modes, respectively.  */
-+#define V850E_UART_CONFIG_RX_BITS \
-+  (V850E_UART_ASIM_PS_MASK | V850E_UART_ASIM_CL_8 | V850E_UART_ASIM_ISRM)
-+#define V850E_UART_CONFIG_TX_BITS \
-+  (V850E_UART_ASIM_PS_MASK | V850E_UART_ASIM_CL_8 | V850E_UART_ASIM_SL_2)
-+
-+static inline v850e_uart_config_t v850e_uart_calc_config (unsigned cflags)
-+{
-+	v850e_uart_config_t config = 0;
-+
-+	/* Figure out new configuration of control register.  */
-+	if (cflags & CSTOPB)
-+		/* Number of stop bits, 1 or 2.  */
-+		config |= V850E_UART_ASIM_SL_2;
-+	if ((cflags & CSIZE) == CS8)
-+		/* Number of data bits, 7 or 8.  */
-+		config |= V850E_UART_ASIM_CL_8;
-+	if (! (cflags & PARENB))
-+		/* No parity check/generation.  */
-+		config |= V850E_UART_ASIM_PS_NONE;
-+	else if (cflags & PARODD)
-+		/* Odd parity check/generation.  */
-+		config |= V850E_UART_ASIM_PS_ODD;
-+	else
-+		/* Even parity check/generation.  */
-+		config |= V850E_UART_ASIM_PS_EVEN;
-+	if (cflags & CREAD)
-+		/* Reading enabled.  */
-+		config |= V850E_UART_ASIM_RXE;
-+
-+	config |= V850E_UART_ASIM_CAE;
-+	config |= V850E_UART_ASIM_TXE; /* Writing is always enabled.  */
-+	config |= V850E_UART_ASIM_ISRM; /* Errors generate a read-irq.  */
-+
-+	return config;
-+}
-+
-+/* This should delay as long as necessary for a recently written config
-+   setting to settle, before we turn the uart back on.  */
-+static inline void
-+v850e_uart_config_delay (v850e_uart_config_t config, v850e_uart_speed_t speed)
-+{
-+	/* The UART may not be reset properly unless we wait at least 2
-+	   `basic-clocks' until turning on the TXE/RXE bits again.
-+	   A `basic clock' is the clock used by the baud-rate generator,
-+	   i.e., the cpu clock divided by the 2^new_clk_divlog2.
-+	   The loop takes 2 insns, so loop CYCLES / 2 times.  */
-+	register unsigned count = 1 << speed.clk_divlog2;
-+	while (--count != 0)
-+		/* nothing */;
-+}
-+
-+
-+/* RX/TX interface.  */
-+
-+/* Return true if all characters awaiting transmission on uart channel N
-+   have been transmitted.  */
-+#define v850e_uart_xmit_done(n)						      \
-+   (! (V850E_UART_ASIF(n) & V850E_UART_ASIF_TXBF))
-+/* Wait for this to be true.  */
-+#define v850e_uart_wait_for_xmit_done(n)				      \
-+   do { } while (! v850e_uart_xmit_done (n))
-+
-+/* Return true if uart channel N is ready to transmit a character.  */
-+#define v850e_uart_xmit_ok(n)						      \
-+   (v850e_uart_xmit_done(n) && v850e_uart_cts(n))
-+/* Wait for this to be true.  */
-+#define v850e_uart_wait_for_xmit_ok(n)					      \
-+   do { } while (! v850e_uart_xmit_ok (n))
-+
-+/* Write character CH to uart channel CHAN.  */
-+#define v850e_uart_putc(chan, ch)	(V850E_UART_TXB(chan) = (ch))
-+
-+/* Return latest character read on channel CHAN.  */
-+#define v850e_uart_getc(chan)		V850E_UART_RXB (chan)
-+
-+/* Return bit-mask of uart error status.  */
-+#define v850e_uart_err(chan)		V850E_UART_ASIS (chan)
-+/* Various error bits set in the error result.  */
-+#define V850E_UART_ERR_OVERRUN		V850E_UART_ASIS_OVE
-+#define V850E_UART_ERR_FRAME		V850E_UART_ASIS_FE
-+#define V850E_UART_ERR_PARITY		V850E_UART_ASIS_PE
-+
-+
-+#endif /* __V850_V850E_UARTA_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_uartb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,262 @@
-+/*
-+ * include/asm-v850/v850e_uartb.h -- V850E on-chip `UARTB' UART
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* The V850E UARTB is basically a superset of the original V850E UART, but
-+   even where it's the same, the names and details have changed a bit.
-+   It's similar enough to use the same driver (v850e_uart.c), but the
-+   details have been abstracted slightly to do so.  */
-+
-+#ifndef __V850_V850E_UARTB_H__
-+#define __V850_V850E_UARTB_H__
-+
-+
-+/* Raw hardware interface.  */
-+
-+#define V850E_UARTB_BASE_ADDR(n)	(0xFFFFFA00 + 0x10 * (n))
-+
-+/* Addresses of specific UART control registers for channel N.  */
-+#define V850E_UARTB_CTL0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x0)
-+#define V850E_UARTB_CTL2_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x2)
-+#define V850E_UARTB_STR_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x4)
-+#define V850E_UARTB_RX_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x6)
-+#define V850E_UARTB_RXAP_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0x6)
-+#define V850E_UARTB_TX_ADDR(n)		(V850E_UARTB_BASE_ADDR(n) + 0x8)
-+#define V850E_UARTB_FIC0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xA)
-+#define V850E_UARTB_FIC1_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xB)
-+#define V850E_UARTB_FIC2_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xC)
-+#define V850E_UARTB_FIS0_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xE)
-+#define V850E_UARTB_FIS1_ADDR(n)	(V850E_UARTB_BASE_ADDR(n) + 0xF)
-+
-+/* UARTB control register 0 (general config).  */
-+#define V850E_UARTB_CTL0(n)	(*(volatile u8 *)V850E_UARTB_CTL0_ADDR(n))
-+/* Control bits for config registers.  */
-+#define V850E_UARTB_CTL0_PWR		0x80	/* clock enable */
-+#define V850E_UARTB_CTL0_TXE		0x40	/* transmit enable */
-+#define V850E_UARTB_CTL0_RXE		0x20	/* receive enable */
-+#define V850E_UARTB_CTL0_DIR		0x10	/*  */
-+#define V850E_UARTB_CTL0_PS1		0x08	/* parity */
-+#define V850E_UARTB_CTL0_PS0		0x04	/* parity */
-+#define V850E_UARTB_CTL0_CL		0x02	/* char len 1:8bit, 0:7bit */
-+#define V850E_UARTB_CTL0_SL		0x01	/* stop bit 1:2bit, 0:1bit */
-+#define V850E_UARTB_CTL0_PS_MASK	0x0C	/* mask covering parity bits */
-+#define V850E_UARTB_CTL0_PS_NONE	0x00	/* no parity */
-+#define V850E_UARTB_CTL0_PS_ZERO	0x04	/* zero parity */
-+#define V850E_UARTB_CTL0_PS_ODD		0x08	/* odd parity */
-+#define V850E_UARTB_CTL0_PS_EVEN	0x0C	/* even parity */
-+#define V850E_UARTB_CTL0_CL_8		0x02	/* char len 1:8bit, 0:7bit */
-+#define V850E_UARTB_CTL0_SL_2		0x01	/* stop bit 1:2bit, 0:1bit */
-+
-+/* UARTB control register 2 (clock divider).  */
-+#define V850E_UARTB_CTL2(n)	(*(volatile u16 *)V850E_UARTB_CTL2_ADDR(n))
-+#define V850E_UARTB_CTL2_MIN	4
-+#define V850E_UARTB_CTL2_MAX	0xFFFF
-+
-+/* UARTB serial interface status register.  */
-+#define V850E_UARTB_STR(n)	(*(volatile u8 *)V850E_UARTB_STR_ADDR(n))
-+/* Control bits for status registers.  */
-+#define V850E_UARTB_STR_TSF	0x80	/* UBTX or FIFO exist data  */
-+#define V850E_UARTB_STR_OVF	0x08	/* overflow error */
-+#define V850E_UARTB_STR_PE	0x04	/* parity error */
-+#define V850E_UARTB_STR_FE	0x02	/* framing error */
-+#define V850E_UARTB_STR_OVE	0x01	/* overrun error */
-+
-+/* UARTB receive data register.  */
-+#define V850E_UARTB_RX(n)	(*(volatile u8 *)V850E_UARTB_RX_ADDR(n))
-+#define V850E_UARTB_RXAP(n)	(*(volatile u16 *)V850E_UARTB_RXAP_ADDR(n))
-+/* Control bits for status registers.  */
-+#define V850E_UARTB_RXAP_PEF	0x0200 /* parity error */
-+#define V850E_UARTB_RXAP_FEF	0x0100 /* framing error */
-+
-+/* UARTB transmit data register.  */
-+#define V850E_UARTB_TX(n)	(*(volatile u8 *)V850E_UARTB_TX_ADDR(n))
-+
-+/* UARTB FIFO control register 0.  */
-+#define V850E_UARTB_FIC0(n)	(*(volatile u8 *)V850E_UARTB_FIC0_ADDR(n))
-+
-+/* UARTB FIFO control register 1.  */
-+#define V850E_UARTB_FIC1(n)	(*(volatile u8 *)V850E_UARTB_FIC1_ADDR(n))
-+
-+/* UARTB FIFO control register 2.  */
-+#define V850E_UARTB_FIC2(n)	(*(volatile u16 *)V850E_UARTB_FIC2_ADDR(n))
-+
-+/* UARTB FIFO status register 0.  */
-+#define V850E_UARTB_FIS0(n)	(*(volatile u8 *)V850E_UARTB_FIS0_ADDR(n))
-+
-+/* UARTB FIFO status register 1.  */
-+#define V850E_UARTB_FIS1(n)	(*(volatile u8 *)V850E_UARTB_FIS1_ADDR(n))
-+
-+
-+/* Slightly abstract interface used by driver.  */
-+
-+
-+/* Interrupts used by the UART.  */
-+
-+/* Received when the most recently transmitted character has been sent.  */
-+#define V850E_UART_TX_IRQ(chan)		IRQ_INTUBTIT (chan)
-+/* Received when a new character has been received.  */
-+#define V850E_UART_RX_IRQ(chan)		IRQ_INTUBTIR (chan)
-+
-+/* Use by serial driver for information purposes.  */
-+#define V850E_UART_BASE_ADDR(chan)	V850E_UARTB_BASE_ADDR(chan)
-+
-+
-+/* UART clock generator interface.  */
-+
-+/* This type encapsulates a particular uart frequency.  */
-+typedef u16 v850e_uart_speed_t;
-+
-+/* Calculate a uart speed from BAUD for this uart.  */
-+static inline v850e_uart_speed_t v850e_uart_calc_speed (unsigned baud)
-+{
-+	v850e_uart_speed_t speed;
-+
-+	/*
-+	 * V850E/ME2 UARTB baud rate is determined by the value of UBCTL2
-+	 * fx = V850E_UARTB_BASE_FREQ = CPU_CLOCK_FREQ/4
-+	 * baud = fx / 2*speed   [ speed >= 4 ]
-+	 */
-+	speed = V850E_UARTB_CTL2_MIN;
-+	while (((V850E_UARTB_BASE_FREQ / 2) / speed ) > baud)
-+		speed++;
-+
-+	return speed;
-+}
-+
-+/* Return the current speed of uart channel CHAN.  */
-+#define v850e_uart_speed(chan)		    V850E_UARTB_CTL2 (chan)
-+
-+/* Set the current speed of uart channel CHAN.  */
-+#define v850e_uart_set_speed(chan, speed)   (V850E_UARTB_CTL2 (chan) = (speed))
-+
-+/* Return true if SPEED1 and SPEED2 are the same.  */
-+#define v850e_uart_speed_eq(speed1, speed2) ((speed1) == (speed2))
-+
-+/* Minimum baud rate possible.  */
-+#define v850e_uart_min_baud() \
-+   ((V850E_UARTB_BASE_FREQ / 2) / V850E_UARTB_CTL2_MAX)
-+
-+/* Maximum baud rate possible.  The error is quite high at max, though.  */
-+#define v850e_uart_max_baud() \
-+   ((V850E_UARTB_BASE_FREQ / 2) / V850E_UARTB_CTL2_MIN)
-+
-+/* The `maximum' clock rate the uart can used, which is wanted (though not
-+   really used in any useful way) by the serial framework.  */
-+#define v850e_uart_max_clock() \
-+   (V850E_UARTB_BASE_FREQ / 2)
-+
-+
-+/* UART configuration interface.  */
-+
-+/* Type of the uart config register; must be a scalar.  */
-+typedef u16 v850e_uart_config_t;
-+
-+/* The uart hardware config register for channel CHAN.  */
-+#define V850E_UART_CONFIG(chan)		V850E_UARTB_CTL0 (chan)
-+
-+/* This config bit set if the uart is enabled.  */
-+#define V850E_UART_CONFIG_ENABLED	V850E_UARTB_CTL0_PWR
-+/* If the uart _isn't_ enabled, store this value to it to do so.  */
-+#define V850E_UART_CONFIG_INIT		V850E_UARTB_CTL0_PWR
-+/* Store this config value to disable the uart channel completely.  */
-+#define V850E_UART_CONFIG_FINI		0
-+
-+/* Setting/clearing these bits enable/disable TX/RX, respectively (but
-+   otherwise generally leave things running).  */
-+#define V850E_UART_CONFIG_RX_ENABLE	V850E_UARTB_CTL0_RXE
-+#define V850E_UART_CONFIG_TX_ENABLE	V850E_UARTB_CTL0_TXE
-+
-+/* These masks define which config bits affect TX/RX modes, respectively.  */
-+#define V850E_UART_CONFIG_RX_BITS \
-+  (V850E_UARTB_CTL0_PS_MASK | V850E_UARTB_CTL0_CL_8)
-+#define V850E_UART_CONFIG_TX_BITS \
-+  (V850E_UARTB_CTL0_PS_MASK | V850E_UARTB_CTL0_CL_8 | V850E_UARTB_CTL0_SL_2)
-+
-+static inline v850e_uart_config_t v850e_uart_calc_config (unsigned cflags)
-+{
-+	v850e_uart_config_t config = 0;
-+
-+	/* Figure out new configuration of control register.  */
-+	if (cflags & CSTOPB)
-+		/* Number of stop bits, 1 or 2.  */
-+		config |= V850E_UARTB_CTL0_SL_2;
-+	if ((cflags & CSIZE) == CS8)
-+		/* Number of data bits, 7 or 8.  */
-+		config |= V850E_UARTB_CTL0_CL_8;
-+	if (! (cflags & PARENB))
-+		/* No parity check/generation.  */
-+		config |= V850E_UARTB_CTL0_PS_NONE;
-+	else if (cflags & PARODD)
-+		/* Odd parity check/generation.  */
-+		config |= V850E_UARTB_CTL0_PS_ODD;
-+	else
-+		/* Even parity check/generation.  */
-+		config |= V850E_UARTB_CTL0_PS_EVEN;
-+	if (cflags & CREAD)
-+		/* Reading enabled.  */
-+		config |= V850E_UARTB_CTL0_RXE;
-+
-+	config |= V850E_UARTB_CTL0_PWR;
-+	config |= V850E_UARTB_CTL0_TXE; /* Writing is always enabled.  */
-+	config |= V850E_UARTB_CTL0_DIR; /* LSB first.  */
-+
-+	return config;
-+}
-+
-+/* This should delay as long as necessary for a recently written config
-+   setting to settle, before we turn the uart back on.  */
-+static inline void
-+v850e_uart_config_delay (v850e_uart_config_t config, v850e_uart_speed_t speed)
-+{
-+	/* The UART may not be reset properly unless we wait at least 2
-+	   `basic-clocks' until turning on the TXE/RXE bits again.
-+	   A `basic clock' is the clock used by the baud-rate generator,
-+	   i.e., the cpu clock divided by the 2^new_clk_divlog2.
-+	   The loop takes 2 insns, so loop CYCLES / 2 times.  */
-+	register unsigned count = 1 << speed;
-+	while (--count != 0)
-+		/* nothing */;
-+}
-+
-+
-+/* RX/TX interface.  */
-+
-+/* Return true if all characters awaiting transmission on uart channel N
-+   have been transmitted.  */
-+#define v850e_uart_xmit_done(n)						      \
-+   (! (V850E_UARTB_STR(n) & V850E_UARTB_STR_TSF))
-+/* Wait for this to be true.  */
-+#define v850e_uart_wait_for_xmit_done(n)				      \
-+   do { } while (! v850e_uart_xmit_done (n))
-+
-+/* Return true if uart channel N is ready to transmit a character.  */
-+#define v850e_uart_xmit_ok(n)						      \
-+   (v850e_uart_xmit_done(n) && v850e_uart_cts(n))
-+/* Wait for this to be true.  */
-+#define v850e_uart_wait_for_xmit_ok(n)					      \
-+   do { } while (! v850e_uart_xmit_ok (n))
-+
-+/* Write character CH to uart channel CHAN.  */
-+#define v850e_uart_putc(chan, ch)	(V850E_UARTB_TX(chan) = (ch))
-+
-+/* Return latest character read on channel CHAN.  */
-+#define v850e_uart_getc(chan)		V850E_UARTB_RX (chan)
-+
-+/* Return bit-mask of uart error status.  */
-+#define v850e_uart_err(chan)		V850E_UARTB_STR (chan)
-+/* Various error bits set in the error result.  */
-+#define V850E_UART_ERR_OVERRUN		V850E_UARTB_STR_OVE
-+#define V850E_UART_ERR_FRAME		V850E_UARTB_STR_FE
-+#define V850E_UART_ERR_PARITY		V850E_UARTB_STR_PE
-+
-+
-+#endif /* __V850_V850E_UARTB_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_uart.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,77 @@
-+/*
-+ * include/asm-v850/v850e_uart.h -- common V850E on-chip UART driver
-+ *
-+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+/* There's not actually a single UART implementation used by V850E CPUs,
-+   but rather a series of implementations that are all `close' to one
-+   another.  This file corresponds to the single driver which handles all
-+   of them.  */
-+
-+#ifndef __V850_V850E_UART_H__
-+#define __V850_V850E_UART_H__
-+
-+#include <linux/config.h>
-+#include <linux/termios.h>
-+
-+#include <asm/v850e_utils.h>
-+#include <asm/types.h>
-+#include <asm/machdep.h>	/* Pick up chip-specific defs.  */
-+
-+
-+/* Include model-specific definitions.  */
-+#ifdef CONFIG_V850E_UART
-+# ifdef CONFIG_V850E_UARTB
-+#  include <asm-v850/v850e_uartb.h>
-+# else
-+#  include <asm-v850/v850e_uarta.h> /* original V850E UART */
-+# endif
-+#endif
-+
-+
-+/* Optional capabilities some hardware provides.  */
-+
-+/* This UART doesn't implement RTS/CTS by default, but some platforms
-+   implement them externally, so check to see if <asm/machdep.h> defined
-+   anything.  */
-+#ifdef V850E_UART_CTS
-+#define v850e_uart_cts(n)		V850E_UART_CTS(n)
-+#else
-+#define v850e_uart_cts(n)		(1)
-+#endif
-+
-+/* Do the same for RTS.  */
-+#ifdef V850E_UART_SET_RTS
-+#define v850e_uart_set_rts(n,v)		V850E_UART_SET_RTS(n,v)
-+#else
-+#define v850e_uart_set_rts(n,v)		((void)0)
-+#endif
-+
-+
-+/* This is the serial channel to use for the boot console (if desired).  */
-+#ifndef V850E_UART_CONSOLE_CHANNEL
-+# define V850E_UART_CONSOLE_CHANNEL 0
-+#endif
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+/* Setup a console using channel 0 of the builtin uart.  */
-+extern void v850e_uart_cons_init (unsigned chan);
-+
-+/* Configure and turn on uart channel CHAN, using the termios `control
-+   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
-+void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud);
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+
-+#endif /* __V850_V850E_UART_H__ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/asm-v850/v850e_utils.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,35 @@
-+/*
-+ * include/asm-v850/v850e_utils.h -- Utility functions associated with
-+ *	V850E CPUs
-+ *
-+ *  Copyright (C) 2001,03  NEC Electronics Corporation
-+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
-+ *
-+ * This file is subject to the terms and conditions of the GNU General
-+ * Public License.  See the file COPYING in the main directory of this
-+ * archive for more details.
-+ *
-+ * Written by Miles Bader <miles@gnu.org>
-+ */
-+
-+#ifndef __V850_V850E_UTILS_H__
-+#define __V850_V850E_UTILS_H__
-+
-+/* Calculate counter clock-divider and count values to attain the
-+   desired frequency RATE from the base frequency BASE_FREQ.  The
-+   counter is expected to have a clock-divider, which can divide the
-+   system cpu clock by a power of two value from MIN_DIVLOG2 to
-+   MAX_DIV_LOG2, and a word-size of COUNTER_SIZE bits (the counter
-+   counts up and resets whenever it's equal to the compare register,
-+   generating an interrupt or whatever when it does so).  The returned
-+   values are: *DIVLOG2 -- log2 of the desired clock divider and *COUNT
-+   -- the counter compare value to use.  Returns true if it was possible
-+   to find a reasonable value, otherwise false (and the other return
-+   values will be set to be as good as possible).  */
-+extern int calc_counter_params (unsigned long base_freq,
-+				unsigned long rate,
-+				unsigned min_divlog2, unsigned max_divlog2,
-+				unsigned counter_size,
-+				unsigned *divlog2, unsigned *count);
-+
-+#endif /* __V850_V850E_UTILS_H__ */
---- linux-2.6.0-test1/include/asm-x86_64/bitops.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/asm-x86_64/bitops.h	2003-07-19 17:04:07.000000000 -0700
-@@ -477,6 +477,7 @@ static __inline__ int ffs(int x)
-  * The Hamming Weight of a number is the total number of bits set in it.
-  */
- 
-+#define hweight64(x) generic_hweight64(x)
- #define hweight32(x) generic_hweight32(x)
- #define hweight16(x) generic_hweight16(x)
- #define hweight8(x) generic_hweight8(x)
---- linux-2.6.0-test1/include/asm-x86_64/mpspec.h	2003-06-14 12:18:09.000000000 -0700
-+++ 25/include/asm-x86_64/mpspec.h	2003-07-19 17:04:07.000000000 -0700
-@@ -171,7 +171,7 @@ extern int quad_local_to_mp_bus_id [NR_C
- extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
- 
- extern unsigned int boot_cpu_physical_apicid;
--extern unsigned long phys_cpu_present_map;
-+extern cpumask_t phys_cpu_present_map;
- extern int smp_found_config;
- extern void find_smp_config (void);
- extern void get_smp_config (void);
---- linux-2.6.0-test1/include/asm-x86_64/pgalloc.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/asm-x86_64/pgalloc.h	2003-07-19 17:07:16.000000000 -0700
-@@ -10,7 +10,7 @@
- #define pmd_populate_kernel(mm, pmd, pte) \
- 		set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
- #define pgd_populate(mm, pgd, pmd) \
--		set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
-+		set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(page_address(pmd))))
- 
- static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
- {
-@@ -22,18 +22,25 @@ extern __inline__ pmd_t *get_pmd(void)
- 	return (pmd_t *)get_zeroed_page(GFP_KERNEL);
- }
- 
--extern __inline__ void pmd_free(pmd_t *pmd)
-+extern __inline__ void pmd_free(struct page *pmd)
- {
--	if ((unsigned long)pmd & (PAGE_SIZE-1)) 
--		BUG(); 
--	free_page((unsigned long)pmd);
-+	__free_page(pmd);
- }
- 
--static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
-+static inline pmd_t *pmd_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
- {
- 	return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
- }
- 
-+static inline struct page *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+	pmd_t *pmd = pmd_alloc_one_kernel(mm, addr);
-+	if (pmd)
-+		return virt_to_page(pmd);
-+	else
-+		return NULL;
-+}
-+
- static inline pgd_t *pgd_alloc (struct mm_struct *mm)
- {
- 	return (pgd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
---- linux-2.6.0-test1/include/asm-x86_64/pgtable.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/asm-x86_64/pgtable.h	2003-07-19 17:07:16.000000000 -0700
-@@ -98,8 +98,9 @@ static inline void set_pml4(pml4_t *dst,
- 	pml4_val(*dst) = pml4_val(val); 
- }
- 
--#define pgd_page(pgd) \
-+#define __pgd_page(pgd) \
- ((unsigned long) __va(pgd_val(pgd) & PHYSICAL_PAGE_MASK))
-+#define pgd_page(pgd)		virt_to_page(__pgd_page(pgd))
- 
- #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte, 0))
- #define pte_same(a, b)		((a).pte == (b).pte)
-@@ -332,8 +333,13 @@ static inline pgd_t *current_pgd_offset_
- #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
- 
- #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
--#define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
-+#define pmd_offset(dir, address) ((pmd_t *)__pgd_page(*(dir)) + \
- 			pmd_index(address))
-+#define pmd_offset_kernel(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map(pgd, addr)			pmd_offset(pgd, addr)
-+#define pmd_offset_map_nested(pgd, addr)		pmd_offset(pgd, addr)
-+#define pmd_unmap(pmd)					do { } while (0)
-+#define pmd_unmap_nested(pmd)				do { } while (0)
- #define pmd_none(x)	(!pmd_val(x))
- #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
- #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
---- linux-2.6.0-test1/include/asm-x86_64/posix_types.h	2003-06-14 12:18:48.000000000 -0700
-+++ 25/include/asm-x86_64/posix_types.h	2003-07-19 17:06:39.000000000 -0700
-@@ -7,7 +7,9 @@
-  * assume GCC is being used.
-  */
- 
-+#ifdef __GNUC__
- typedef unsigned long	__kernel_dev_t;
-+#endif
- typedef unsigned long	__kernel_ino_t;
- typedef unsigned int	__kernel_mode_t;
- typedef unsigned long	__kernel_nlink_t;
---- linux-2.6.0-test1/include/asm-x86_64/smp.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/asm-x86_64/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -7,6 +7,7 @@
- #ifndef __ASSEMBLY__
- #include <linux/config.h>
- #include <linux/threads.h>
-+#include <linux/cpumask.h>
- #include <linux/bitops.h>
- extern int disable_apic;
- #endif
-@@ -35,8 +36,8 @@ struct pt_regs;
-  */
-  
- extern void smp_alloc_memory(void);
--extern unsigned long phys_cpu_present_map;
--extern unsigned long cpu_online_map;
-+extern cpumask_t phys_cpu_present_map;
-+extern cpumask_t cpu_online_map;
- extern volatile unsigned long smp_invalidate_needed;
- extern int pic_mode;
- extern void smp_flush_tlb(void);
-@@ -56,35 +57,17 @@ void smp_stop_cpu(void);
-  * compresses data structures.
-  */
- 
--extern volatile unsigned long cpu_callout_map;
-+extern cpumask_t cpu_callout_map;
- 
--#define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu)))
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
--
--#define for_each_cpu(cpu, mask) \
--	for(mask = cpu_online_map; \
--	    cpu = __ffs(mask), mask != 0; \
--	    mask &= ~(1UL<<cpu))
--
--extern inline unsigned int any_online_cpu(unsigned int mask)
--{
--	if (mask & cpu_online_map)
--		return __ffs(mask & cpu_online_map);
--
--	return NR_CPUS; 
--} 
--
--extern inline unsigned int num_online_cpus(void)
--{ 
--	return hweight32(cpu_online_map);
--} 
-+#define cpu_possible(cpu) cpu_isset(cpu, cpu_callout_map)
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- 
- static inline int num_booting_cpus(void)
- {
--	return hweight32(cpu_callout_map);
-+	return cpus_weight(cpu_callout_map);
- }
- 
--extern volatile unsigned long cpu_callout_map;
-+extern cpumask_t cpu_callout_map;
- 
- #define smp_processor_id() read_pda(cpunumber)
- 
-@@ -104,7 +87,7 @@ extern inline int safe_smp_processor_id(
- 		return hard_smp_processor_id();
- } 
- 
--#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
-+#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
- #endif /* !ASSEMBLY */
- 
- #define NO_PROC_ID		0xFF		/* No processor magic marker */
-@@ -117,7 +100,6 @@ extern inline int safe_smp_processor_id(
- #ifndef CONFIG_SMP
- #define stack_smp_processor_id() 0
- #define safe_smp_processor_id() 0
--#define for_each_cpu(x) (x)=0;
- #define cpu_logical_map(x) (x)
- #else
- #include <asm/thread_info.h>
---- linux-2.6.0-test1/include/asm-x86_64/topology.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/include/asm-x86_64/topology.h	2003-07-19 17:04:07.000000000 -0700
-@@ -8,13 +8,13 @@
- /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */
- 
- extern int fake_node;
--extern unsigned long cpu_online_map;
-+extern cpumask_t cpu_online_map;
- 
- #define cpu_to_node(cpu)		(fake_node ? 0 : (cpu))
- #define memblk_to_node(memblk) 	(fake_node ? 0 : (memblk))
- #define parent_node(node)		(node)
- #define node_to_first_cpu(node) 	(fake_node ? 0 : (node))
--#define node_to_cpu_mask(node)	(fake_node ? cpu_online_map : (1UL << (node)))
-+#define node_to_cpu_mask(node)	(fake_node ? cpu_online_map : cpumask_of_cpu(node))
- #define node_to_memblk(node)		(node)
- 
- #define NODE_BALANCE_RATE 30	/* CHECKME */ 
---- linux-2.6.0-test1/include/linux/aio.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/aio.h	2003-07-19 17:07:03.000000000 -0700
-@@ -54,7 +54,7 @@ struct kiocb {
- 	struct file		*ki_filp;
- 	struct kioctx		*ki_ctx;	/* may be NULL for sync ops */
- 	int			(*ki_cancel)(struct kiocb *, struct io_event *);
--	long			(*ki_retry)(struct kiocb *);
-+	ssize_t			(*ki_retry)(struct kiocb *);
- 
- 	struct list_head	ki_list;	/* the aio core uses this
- 						 * for cancellation */
-@@ -63,6 +63,16 @@ struct kiocb {
- 	__u64			ki_user_data;	/* user's data for completion */
- 	loff_t			ki_pos;
- 
-+	/* State that we remember to be able to restart/retry  */
-+	unsigned short		ki_opcode;
-+	size_t			ki_nbytes; 	/* copy of iocb->aio_nbytes */
-+	char 			*ki_buf;	/* remaining iocb->aio_buf */
-+	size_t			ki_left; 	/* remaining bytes */
-+	wait_queue_t		ki_wait;
-+	long			ki_retried; 	/* just for testing */
-+	long			ki_kicked; 	/* just for testing */
-+	long			ki_queued; 	/* just for testing */
-+
- 	char			private[KIOCB_PRIVATE_SIZE];
- };
- 
-@@ -77,6 +87,8 @@ struct kiocb {
- 		(x)->ki_ctx = &tsk->active_mm->default_kioctx;	\
- 		(x)->ki_cancel = NULL;			\
- 		(x)->ki_user_obj = tsk;			\
-+		(x)->ki_user_data = 0;			\
-+		init_wait((&(x)->ki_wait));		\
- 	} while (0)
- 
- #define AIO_RING_MAGIC			0xa10a10a1
-@@ -159,6 +171,17 @@ int FASTCALL(io_submit_one(struct kioctx
- #define get_ioctx(kioctx)	do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
- #define put_ioctx(kioctx)	do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
- 
-+#define in_aio() !is_sync_wait(current->io_wait)
-+/* may be used for debugging */
-+#define warn_if_async()	if (in_aio()) {\
-+	printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
-+	__FUNCTION__, __FILE__, __LINE__); \
-+	dump_stack(); \
-+	}
-+
-+#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
-+#define is_retried_kiocb(iocb) ((iocb)->ki_retried > 1)
-+
- #include <linux/aio_abi.h>
- 
- static inline struct kiocb *list_kiocb(struct list_head *h)
---- linux-2.6.0-test1/include/linux/atmdev.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/linux/atmdev.h	2003-07-19 17:03:51.000000000 -0700
-@@ -252,6 +252,7 @@ enum {
- 	ATM_VF_SESSION,		/* VCC is p2mp session control descriptor */
- 	ATM_VF_HASSAP,		/* SAP has been set */
- 	ATM_VF_CLOSE,		/* asynchronous close - treat like VF_RELEASED*/
-+	ATM_VF_WAITING,		/* waiting for reply from sigd */
- };
- 
- 
-@@ -291,14 +292,11 @@ struct atm_vcc {
- 	void		*dev_data;	/* per-device data */
- 	void		*proto_data;	/* per-protocol data */
- 	struct k_atm_aal_stats *stats;	/* pointer to AAL stats group */
--	wait_queue_head_t sleep;	/* if socket is busy */
- 	struct sock	*sk;		/* socket backpointer */
- 	/* SVC part --- may move later ------------------------------------- */
- 	short		itf;		/* interface number */
- 	struct sockaddr_atmsvc local;
- 	struct sockaddr_atmsvc remote;
--	void (*callback)(struct atm_vcc *vcc);
--	int		reply;		/* also used by ATMTCP */
- 	/* Multipoint part ------------------------------------------------- */
- 	struct atm_vcc	*session;	/* session VCC descriptor */
- 	/* Other stuff ----------------------------------------------------- */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/linux/bitmap.h	2003-07-19 17:04:13.000000000 -0700
-@@ -0,0 +1,159 @@
-+#ifndef __LINUX_BITMAP_H
-+#define __LINUX_BITMAP_H
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/string.h>
-+
-+static inline int bitmap_empty(const unsigned long *bitmap, int bits)
-+{
-+	int k, lim = bits/BITS_PER_LONG;
-+	for (k = 0; k < lim; ++k)
-+		if (bitmap[k])
-+			return 0;
-+
-+	if (bits % BITS_PER_LONG)
-+		if (bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1))
-+			return 0;
-+
-+	return 1;
-+}
-+
-+static inline int bitmap_full(const unsigned long *bitmap, int bits)
-+{
-+	int k, lim = bits/BITS_PER_LONG;
-+	for (k = 0; k < lim; ++k)
-+		if (~bitmap[k])
-+			return 0;
-+
-+	if (bits % BITS_PER_LONG)
-+		if (~bitmap[k] & ((1UL << (bits % BITS_PER_LONG)) - 1))
-+			return 0;
-+
-+	return 1;
-+}
-+
-+static inline int bitmap_equal(const unsigned long *bitmap1,
-+				unsigned long *bitmap2, int bits)
-+{
-+	int k, lim = bits/BITS_PER_LONG;;
-+	for (k = 0; k < lim; ++k)
-+		if (bitmap1[k] != bitmap2[k])
-+			return 0;
-+
-+	if (bits % BITS_PER_LONG)
-+		if ((bitmap1[k] ^ bitmap2[k]) &
-+				((1UL << (bits % BITS_PER_LONG)) - 1))
-+			return 0;
-+
-+	return 1;
-+}
-+
-+static inline void bitmap_complement(unsigned long *bitmap, int bits)
-+{
-+	int k;
-+
-+	for (k = 0; k < BITS_TO_LONGS(bits); ++k)
-+		bitmap[k] = ~bitmap[k];
-+}
-+
-+static inline void bitmap_clear(unsigned long *bitmap, int bits)
-+{
-+	CLEAR_BITMAP((unsigned long *)bitmap, bits);
-+}
-+
-+static inline void bitmap_fill(unsigned long *bitmap, int bits)
-+{
-+	memset(bitmap, 0xff, BITS_TO_LONGS(bits)*sizeof(unsigned long));
-+}
-+
-+static inline void bitmap_copy(unsigned long *dst,
-+			const unsigned long *src, int bits)
-+{
-+	memcpy(dst, src, BITS_TO_LONGS(bits)*sizeof(unsigned long));
-+}
-+
-+static inline void bitmap_shift_right(unsigned long *dst,
-+				const unsigned long *src, int shift, int bits)
-+{
-+	int k;
-+	DECLARE_BITMAP(__shr_tmp, bits);
-+
-+	bitmap_clear(__shr_tmp, bits);
-+	for (k = 0; k < bits - shift; ++k)
-+		if (test_bit(k + shift, src))
-+			set_bit(k, __shr_tmp);
-+	bitmap_copy(dst, __shr_tmp, bits);
-+}
-+
-+static inline void bitmap_shift_left(unsigned long *dst,
-+				const unsigned long *src, int shift, int bits)
-+{
-+	int k;
-+	DECLARE_BITMAP(__shl_tmp, bits);
-+
-+	bitmap_clear(__shl_tmp, bits);
-+	for (k = bits; k >= shift; --k)
-+		if (test_bit(k - shift, src))
-+			set_bit(k, __shl_tmp);
-+	bitmap_copy(dst, __shl_tmp, bits);
-+}
-+
-+static inline void bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
-+				const unsigned long *bitmap2, int bits)
-+{
-+	int k;
-+	int nr = BITS_TO_LONGS(bits);
-+
-+	for (k = 0; k < nr; k++)
-+		dst[k] = bitmap1[k] & bitmap2[k];
-+}
-+
-+static inline void bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
-+				const unsigned long *bitmap2, int bits)
-+{
-+	int k;
-+	int nr = BITS_TO_LONGS(bits);
-+
-+	for (k = 0; k < nr; k++)
-+		dst[k] = bitmap1[k] | bitmap2[k];
-+}
-+
-+#if BITS_PER_LONG == 32
-+static inline int bitmap_weight(const unsigned long *bitmap, int bits)
-+{
-+	int k, w = 0, lim = bits/BITS_PER_LONG;
-+
-+	for (k = 0; k < lim; k++)
-+		w += hweight32(bitmap[k]);
-+
-+	if (bits % BITS_PER_LONG)
-+		w += hweight32(bitmap[k] &
-+				((1UL << (bits % BITS_PER_LONG)) - 1));
-+
-+	return w;
-+}
-+#else
-+static inline int bitmap_weight(const unsigned long *bitmap, int bits)
-+{
-+	int k, w = 0, lim = bits/BITS_PER_LONG;
-+
-+	for (k = 0; k < lim; k++)
-+		w += hweight64(bitmap[k]);
-+
-+	if (bits % BITS_PER_LONG)
-+		w += hweight64(bitmap[k] &
-+				((1UL << (bits % BITS_PER_LONG)) - 1));
-+
-+	return w;
-+}
-+#endif
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif /* __LINUX_BITMAP_H */
---- linux-2.6.0-test1/include/linux/blkdev.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/blkdev.h	2003-07-19 17:06:49.000000000 -0700
-@@ -44,9 +44,9 @@ struct as_io_context {
- 	unsigned long ttime_samples;
- 	unsigned long ttime_mean;
- 	/* Layout pattern */
--	long seek_samples;
-+	unsigned int seek_samples;
- 	sector_t last_request_pos;
--	sector_t seek_total;
-+	u64 seek_total;
- 	sector_t seek_mean;
- };
- 
-@@ -491,6 +491,7 @@ extern void __blk_attempt_remerge(reques
- extern struct request *blk_get_request(request_queue_t *, int, int);
- extern void blk_put_request(struct request *);
- extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
-+extern void blk_requeue_request(request_queue_t *, struct request *);
- extern void blk_plug_device(request_queue_t *);
- extern int blk_remove_plug(request_queue_t *);
- extern void blk_recount_segments(request_queue_t *, struct bio *);
-@@ -549,6 +550,7 @@ extern void blk_queue_max_phys_segments(
- extern void blk_queue_max_hw_segments(request_queue_t *, unsigned short);
- extern void blk_queue_max_segment_size(request_queue_t *, unsigned int);
- extern void blk_queue_hardsect_size(request_queue_t *, unsigned short);
-+extern void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b);
- extern void blk_queue_segment_boundary(request_queue_t *, unsigned long);
- extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn);
- extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
-@@ -574,6 +576,7 @@ extern void blk_queue_free_tags(request_
- extern int blk_queue_resize_tags(request_queue_t *, int);
- extern void blk_queue_invalidate_tags(request_queue_t *);
- extern void blk_congestion_wait(int rw, long timeout);
-+extern int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait);
- 
- extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
- extern void blk_rq_prep_restart(struct request *);
---- linux-2.6.0-test1/include/linux/blk.h	2003-06-14 12:18:30.000000000 -0700
-+++ 25/include/linux/blk.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,2 +1,2 @@
--/* this file is obsolete, please use <linux/blkdev.h> instead */
-+#warning this file is obsolete, please use <linux/blkdev.h> instead
- #include <linux/blkdev.h>
---- linux-2.6.0-test1/include/linux/buffer_head.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/buffer_head.h	2003-07-19 17:07:00.000000000 -0700
-@@ -158,6 +158,7 @@ void mark_buffer_async_write(struct buff
- void invalidate_bdev(struct block_device *, int);
- int sync_blockdev(struct block_device *bdev);
- void __wait_on_buffer(struct buffer_head *);
-+int __wait_on_buffer_wq(struct buffer_head *, wait_queue_t *wait);
- wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
- void wake_up_buffer(struct buffer_head *bh);
- int fsync_bdev(struct block_device *);
-@@ -169,6 +170,8 @@ void __brelse(struct buffer_head *);
- void __bforget(struct buffer_head *);
- void __breadahead(struct block_device *, sector_t block, int size);
- struct buffer_head *__bread(struct block_device *, sector_t block, int size);
-+struct buffer_head *__bread_wq(struct block_device *, sector_t block,
-+	int size, wait_queue_t *wait);
- struct buffer_head *alloc_buffer_head(int gfp_flags);
- void free_buffer_head(struct buffer_head * bh);
- void FASTCALL(unlock_buffer(struct buffer_head *bh));
-@@ -203,11 +206,6 @@ int nobh_prepare_write(struct page*, uns
- int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
- int nobh_truncate_page(struct address_space *, loff_t);
- 
--#define OSYNC_METADATA	(1<<0)
--#define OSYNC_DATA	(1<<1)
--#define OSYNC_INODE	(1<<2)
--int generic_osync_inode(struct inode *, int);
--
- 
- /*
-  * inline definitions
-@@ -226,13 +224,13 @@ static inline void put_bh(struct buffer_
- 
- static inline void brelse(struct buffer_head *bh)
- {
--	if (bh)
-+	if (bh && !IS_ERR(bh))
- 		__brelse(bh);
- }
- 
- static inline void bforget(struct buffer_head *bh)
- {
--	if (bh)
-+	if (bh && !IS_ERR(bh))
- 		__bforget(bh);
- }
- 
-@@ -249,7 +247,12 @@ sb_breadahead(struct super_block *sb, se
- }
- 
- static inline struct buffer_head *
--sb_getblk(struct super_block *sb, sector_t block)
-+sb_bread_wq(struct super_block *sb, sector_t block, wait_queue_t *wait)
-+{
-+	return __bread_wq(sb->s_bdev, block, sb->s_blocksize, wait);
-+}
-+
-+static inline struct buffer_head *sb_getblk(struct super_block *sb, sector_t block)
- {
- 	return __getblk(sb->s_bdev, block, sb->s_blocksize);
- }
-@@ -273,16 +276,34 @@ map_bh(struct buffer_head *bh, struct su
-  * __wait_on_buffer() just to trip a debug check.  Because debug code in inline
-  * functions is bloaty.
-  */
--static inline void wait_on_buffer(struct buffer_head *bh)
-+
-+static inline int wait_on_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
- {
- 	if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0)
--		__wait_on_buffer(bh);
-+		return __wait_on_buffer_wq(bh, wait);
-+
-+	return 0;
-+}
-+
-+static inline void wait_on_buffer(struct buffer_head *bh)
-+{
-+	wait_on_buffer_wq(bh, NULL);
-+}
-+
-+static inline int lock_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
-+{
-+	while (test_set_buffer_locked(bh)) {
-+		int ret = __wait_on_buffer_wq(bh, wait);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return 0;
- }
- 
- static inline void lock_buffer(struct buffer_head *bh)
- {
--	while (test_set_buffer_locked(bh))
--		__wait_on_buffer(bh);
-+	lock_buffer_wq(bh, NULL);
- }
- 
- #endif /* _LINUX_BUFFER_HEAD_H */
---- linux-2.6.0-test1/include/linux/compiler.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/compiler.h	2003-07-19 17:04:50.000000000 -0700
-@@ -78,6 +78,6 @@
-    shouldn't recognize the original var, and make assumptions about it */
- #define RELOC_HIDE(ptr, off)					\
-   ({ unsigned long __ptr;					\
--    __asm__ ("" : "=g"(__ptr) : "0"(ptr));		\
-+    __asm__ ("" : "=r"(__ptr) : "0"(ptr));		\
-     (typeof(ptr)) (__ptr + (off)); })
- #endif /* __LINUX_COMPILER_H */
---- linux-2.6.0-test1/include/linux/config.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/config.h	2003-07-19 17:04:53.000000000 -0700
-@@ -2,5 +2,8 @@
- #define _LINUX_CONFIG_H
- 
- #include <linux/autoconf.h>
-+#if defined(__i386__) && !defined(IN_BOOTLOADER)
-+#include <asm/kgdb.h>
-+#endif
- 
- #endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/linux/cpumask.h	2003-07-19 17:04:07.000000000 -0700
-@@ -0,0 +1,62 @@
-+#ifndef __LINUX_CPUMASK_H
-+#define __LINUX_CPUMASK_H
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/threads.h>
-+#include <linux/types.h>
-+#include <linux/bitmap.h>
-+
-+#define CPU_ARRAY_SIZE		BITS_TO_LONGS(NR_CPUS)
-+
-+struct cpumask
-+{
-+	unsigned long mask[CPU_ARRAY_SIZE];
-+};
-+
-+typedef struct cpumask cpumask_t;
-+
-+#ifdef CONFIG_SMP
-+#include <asm-generic/cpumask_array.h>
-+#else
-+#include <asm-generic/cpumask_up.h>
-+#endif
-+
-+#if NR_CPUS <= 4*BITS_PER_LONG
-+#include <asm-generic/cpumask_const_value.h>
-+#else
-+#include <asm-generic/cpumask_const_reference.h>
-+#endif
-+
-+
-+#ifdef CONFIG_SMP
-+
-+extern cpumask_t cpu_online_map;
-+
-+#define num_online_cpus()		cpus_weight(cpu_online_map)
-+#define cpu_online(cpu)			cpu_isset(cpu, cpu_online_map)
-+#else
-+#define	cpu_online_map			cpumask_of_cpu(0)
-+#define num_online_cpus()		1
-+#define cpu_online(cpu)			({ BUG_ON((cpu) != 0); 1; })
-+#endif
-+
-+static inline int next_online_cpu(int cpu, cpumask_t map)
-+{
-+	do
-+		cpu = next_cpu_const(cpu, map);
-+	while (cpu < NR_CPUS && !cpu_online(cpu));
-+	return cpu;
-+}
-+
-+#define for_each_cpu(cpu, map)						\
-+	for (cpu = first_cpu_const(map);				\
-+		cpu < NR_CPUS;						\
-+		cpu = next_cpu_const(cpu,map))
-+
-+#define for_each_online_cpu(cpu, map)					\
-+	for (cpu = first_cpu_const(map);				\
-+		cpu < NR_CPUS;						\
-+		cpu = next_online_cpu(cpu,map))
-+
-+#endif /* __LINUX_CPUMASK_H */
---- linux-2.6.0-test1/include/linux/dm-ioctl.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/linux/dm-ioctl.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,5 +1,5 @@
- /*
-- * Copyright (C) 2001 Sistina Software (UK) Limited.
-+ * Copyright (C) 2003 Sistina Software (UK) Limited.
-  *
-  * This file is released under the LGPL.
-  */
-@@ -7,143 +7,12 @@
- #ifndef _LINUX_DM_IOCTL_H
- #define _LINUX_DM_IOCTL_H
- 
--#include <linux/types.h>
-+#include <linux/config.h>
- 
--#define DM_DIR "mapper"	/* Slashes not supported */
--#define DM_MAX_TYPE_NAME 16
--#define DM_NAME_LEN 128
--#define DM_UUID_LEN 129
-+#ifdef CONFIG_DM_IOCTL_V4
-+#include "dm-ioctl-v4.h"
-+#else
-+#include "dm-ioctl-v1.h"
-+#endif
- 
--/*
-- * Implements a traditional ioctl interface to the device mapper.
-- */
--
--/*
-- * All ioctl arguments consist of a single chunk of memory, with
-- * this structure at the start.  If a uuid is specified any
-- * lookup (eg. for a DM_INFO) will be done on that, *not* the
-- * name.
-- */
--struct dm_ioctl {
--	/*
--	 * The version number is made up of three parts:
--	 * major - no backward or forward compatibility,
--	 * minor - only backwards compatible,
--	 * patch - both backwards and forwards compatible.
--	 *
--	 * All clients of the ioctl interface should fill in the
--	 * version number of the interface that they were
--	 * compiled with.
--	 *
--	 * All recognised ioctl commands (ie. those that don't
--	 * return -ENOTTY) fill out this field, even if the
--	 * command failed.
--	 */
--	uint32_t version[3];	/* in/out */
--	uint32_t data_size;	/* total size of data passed in
--				 * including this struct */
--
--	uint32_t data_start;	/* offset to start of data
--				 * relative to start of this struct */
--
--	uint32_t target_count;	/* in/out */
--	uint32_t open_count;	/* out */
--	uint32_t flags;		/* in/out */
--
--	__kernel_dev_t dev;	/* in/out */
--
--	char name[DM_NAME_LEN];	/* device name */
--	char uuid[DM_UUID_LEN];	/* unique identifier for
--				 * the block device */
--};
--
--/*
-- * Used to specify tables.  These structures appear after the
-- * dm_ioctl.
-- */
--struct dm_target_spec {
--	int32_t status;		/* used when reading from kernel only */
--	uint64_t sector_start;
--	uint32_t length;
--
--	/*
--	 * Offset in bytes (from the start of this struct) to
--	 * next target_spec.
--	 */
--	uint32_t next;
--
--	char target_type[DM_MAX_TYPE_NAME];
--
--	/*
--	 * Parameter string starts immediately after this object.
--	 * Be careful to add padding after string to ensure correct
--	 * alignment of subsequent dm_target_spec.
--	 */
--};
--
--/*
-- * Used to retrieve the target dependencies.
-- */
--struct dm_target_deps {
--	uint32_t count;
--
--	__kernel_dev_t dev[0];	/* out */
--};
--
--/*
-- * If you change this make sure you make the corresponding change
-- * to dm-ioctl.c:lookup_ioctl()
-- */
--enum {
--	/* Top level cmds */
--	DM_VERSION_CMD = 0,
--	DM_REMOVE_ALL_CMD,
--
--	/* device level cmds */
--	DM_DEV_CREATE_CMD,
--	DM_DEV_REMOVE_CMD,
--	DM_DEV_RELOAD_CMD,
--	DM_DEV_RENAME_CMD,
--	DM_DEV_SUSPEND_CMD,
--	DM_DEV_DEPS_CMD,
--	DM_DEV_STATUS_CMD,
--
--	/* target level cmds */
--	DM_TARGET_STATUS_CMD,
--	DM_TARGET_WAIT_CMD
--};
--
--#define DM_IOCTL 0xfd
--
--#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
--#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
--
--#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
--#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
--#define DM_DEV_RELOAD    _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD, struct dm_ioctl)
--#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
--#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
--#define DM_DEV_DEPS      _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD, struct dm_ioctl)
--#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
--
--#define DM_TARGET_STATUS _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD, struct dm_ioctl)
--#define DM_TARGET_WAIT   _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD, struct dm_ioctl)
--
--#define DM_VERSION_MAJOR	1
--#define DM_VERSION_MINOR	0
--#define DM_VERSION_PATCHLEVEL	6
--#define DM_VERSION_EXTRA	"-ioctl (2002-10-15)"
--
--/* Status bits */
--#define DM_READONLY_FLAG	0x00000001
--#define DM_SUSPEND_FLAG		0x00000002
--#define DM_EXISTS_FLAG		0x00000004
--#define DM_PERSISTENT_DEV_FLAG	0x00000008
--
--/*
-- * Flag passed into ioctl STATUS command to get table information
-- * rather than current status.
-- */
--#define DM_STATUS_TABLE_FLAG	0x00000010
--
--#endif				/* _LINUX_DM_IOCTL_H */
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/linux/dm-ioctl-v1.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,149 @@
-+/*
-+ * Copyright (C) 2001 Sistina Software (UK) Limited.
-+ *
-+ * This file is released under the LGPL.
-+ */
-+
-+#ifndef _LINUX_DM_IOCTL_V1_H
-+#define _LINUX_DM_IOCTL_V1_H
-+
-+#include <linux/types.h>
-+
-+#define DM_DIR "mapper"	/* Slashes not supported */
-+#define DM_MAX_TYPE_NAME 16
-+#define DM_NAME_LEN 128
-+#define DM_UUID_LEN 129
-+
-+/*
-+ * Implements a traditional ioctl interface to the device mapper.
-+ */
-+
-+/*
-+ * All ioctl arguments consist of a single chunk of memory, with
-+ * this structure at the start.  If a uuid is specified any
-+ * lookup (eg. for a DM_INFO) will be done on that, *not* the
-+ * name.
-+ */
-+struct dm_ioctl {
-+	/*
-+	 * The version number is made up of three parts:
-+	 * major - no backward or forward compatibility,
-+	 * minor - only backwards compatible,
-+	 * patch - both backwards and forwards compatible.
-+	 *
-+	 * All clients of the ioctl interface should fill in the
-+	 * version number of the interface that they were
-+	 * compiled with.
-+	 *
-+	 * All recognised ioctl commands (ie. those that don't
-+	 * return -ENOTTY) fill out this field, even if the
-+	 * command failed.
-+	 */
-+	uint32_t version[3];	/* in/out */
-+	uint32_t data_size;	/* total size of data passed in
-+				 * including this struct */
-+
-+	uint32_t data_start;	/* offset to start of data
-+				 * relative to start of this struct */
-+
-+	uint32_t target_count;	/* in/out */
-+	uint32_t open_count;	/* out */
-+	uint32_t flags;		/* in/out */
-+
-+	__kernel_dev_t dev;	/* in/out */
-+
-+	char name[DM_NAME_LEN];	/* device name */
-+	char uuid[DM_UUID_LEN];	/* unique identifier for
-+				 * the block device */
-+};
-+
-+/*
-+ * Used to specify tables.  These structures appear after the
-+ * dm_ioctl.
-+ */
-+struct dm_target_spec {
-+	int32_t status;		/* used when reading from kernel only */
-+	uint64_t sector_start;
-+	uint32_t length;
-+
-+	/*
-+	 * Offset in bytes (from the start of this struct) to
-+	 * next target_spec.
-+	 */
-+	uint32_t next;
-+
-+	char target_type[DM_MAX_TYPE_NAME];
-+
-+	/*
-+	 * Parameter string starts immediately after this object.
-+	 * Be careful to add padding after string to ensure correct
-+	 * alignment of subsequent dm_target_spec.
-+	 */
-+};
-+
-+/*
-+ * Used to retrieve the target dependencies.
-+ */
-+struct dm_target_deps {
-+	uint32_t count;
-+
-+	__kernel_dev_t dev[0];	/* out */
-+};
-+
-+/*
-+ * If you change this make sure you make the corresponding change
-+ * to dm-ioctl.c:lookup_ioctl()
-+ */
-+enum {
-+	/* Top level cmds */
-+	DM_VERSION_CMD = 0,
-+	DM_REMOVE_ALL_CMD,
-+
-+	/* device level cmds */
-+	DM_DEV_CREATE_CMD,
-+	DM_DEV_REMOVE_CMD,
-+	DM_DEV_RELOAD_CMD,
-+	DM_DEV_RENAME_CMD,
-+	DM_DEV_SUSPEND_CMD,
-+	DM_DEV_DEPS_CMD,
-+	DM_DEV_STATUS_CMD,
-+
-+	/* target level cmds */
-+	DM_TARGET_STATUS_CMD,
-+	DM_TARGET_WAIT_CMD
-+};
-+
-+#define DM_IOCTL 0xfd
-+
-+#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
-+#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
-+
-+#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
-+#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
-+#define DM_DEV_RELOAD    _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD, struct dm_ioctl)
-+#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
-+#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
-+#define DM_DEV_DEPS      _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD, struct dm_ioctl)
-+#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
-+
-+#define DM_TARGET_STATUS _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD, struct dm_ioctl)
-+#define DM_TARGET_WAIT   _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD, struct dm_ioctl)
-+
-+#define DM_VERSION_MAJOR	1
-+#define DM_VERSION_MINOR	0
-+#define DM_VERSION_PATCHLEVEL	6
-+#define DM_VERSION_EXTRA	"-ioctl (2002-10-15)"
-+
-+/* Status bits */
-+#define DM_READONLY_FLAG	0x00000001
-+#define DM_SUSPEND_FLAG		0x00000002
-+#define DM_EXISTS_FLAG		0x00000004
-+#define DM_PERSISTENT_DEV_FLAG	0x00000008
-+
-+/*
-+ * Flag passed into ioctl STATUS command to get table information
-+ * rather than current status.
-+ */
-+#define DM_STATUS_TABLE_FLAG	0x00000010
-+
-+#endif				/* _LINUX_DM_IOCTL_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/linux/dm-ioctl-v4.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,237 @@
-+/*
-+ * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
-+ *
-+ * This file is released under the LGPL.
-+ */
-+
-+#ifndef _LINUX_DM_IOCTL_V4_H
-+#define _LINUX_DM_IOCTL_V4_H
-+
-+#include <linux/types.h>
-+
-+#define DM_DIR "mapper"		/* Slashes not supported */
-+#define DM_MAX_TYPE_NAME 16
-+#define DM_NAME_LEN 128
-+#define DM_UUID_LEN 129
-+
-+/*
-+ * A traditional ioctl interface for the device mapper.
-+ *
-+ * Each device can have two tables associated with it, an
-+ * 'active' table which is the one currently used by io passing
-+ * through the device, and an 'inactive' one which is a table
-+ * that is being prepared as a replacement for the 'active' one.
-+ *
-+ * DM_VERSION:
-+ * Just get the version information for the ioctl interface.
-+ *
-+ * DM_REMOVE_ALL:
-+ * Remove all dm devices, destroy all tables.  Only really used
-+ * for debug.
-+ *
-+ * DM_LIST_DEVICES:
-+ * Get a list of all the dm device names.
-+ *
-+ * DM_DEV_CREATE:
-+ * Create a new device, neither the 'active' or 'inactive' table
-+ * slots will be filled.  The device will be in suspended state
-+ * after creation, however any io to the device will get errored
-+ * since it will be out-of-bounds.
-+ *
-+ * DM_DEV_REMOVE:
-+ * Remove a device, destroy any tables.
-+ *
-+ * DM_DEV_RENAME:
-+ * Rename a device.
-+ *
-+ * DM_SUSPEND:
-+ * This performs both suspend and resume, depending which flag is
-+ * passed in.
-+ * Suspend: This command will not return until all pending io to
-+ * the device has completed.  Further io will be deferred until
-+ * the device is resumed.
-+ * Resume: It is no longer an error to issue this command on an
-+ * unsuspended device.  If a table is present in the 'inactive'
-+ * slot, it will be moved to the active slot, then the old table
-+ * from the active slot will be _destroyed_.  Finally the device
-+ * is resumed.
-+ *
-+ * DM_DEV_STATUS:
-+ * Retrieves the status for the table in the 'active' slot.
-+ *
-+ * DM_DEV_WAIT:
-+ * Wait for a significant event to occur to the device.  This
-+ * could either be caused by an event triggered by one of the
-+ * targets of the table in the 'active' slot, or a table change.
-+ *
-+ * DM_TABLE_LOAD:
-+ * Load a table into the 'inactive' slot for the device.  The
-+ * device does _not_ need to be suspended prior to this command.
-+ *
-+ * DM_TABLE_CLEAR:
-+ * Destroy any table in the 'inactive' slot (ie. abort).
-+ *
-+ * DM_TABLE_DEPS:
-+ * Return a set of device dependencies for the 'active' table.
-+ *
-+ * DM_TABLE_STATUS:
-+ * Return the targets status for the 'active' table.
-+ */
-+
-+/*
-+ * All ioctl arguments consist of a single chunk of memory, with
-+ * this structure at the start.  If a uuid is specified any
-+ * lookup (eg. for a DM_INFO) will be done on that, *not* the
-+ * name.
-+ */
-+struct dm_ioctl {
-+	/*
-+	 * The version number is made up of three parts:
-+	 * major - no backward or forward compatibility,
-+	 * minor - only backwards compatible,
-+	 * patch - both backwards and forwards compatible.
-+	 *
-+	 * All clients of the ioctl interface should fill in the
-+	 * version number of the interface that they were
-+	 * compiled with.
-+	 *
-+	 * All recognised ioctl commands (ie. those that don't
-+	 * return -ENOTTY) fill out this field, even if the
-+	 * command failed.
-+	 */
-+	uint32_t version[3];	/* in/out */
-+	uint32_t data_size;	/* total size of data passed in
-+				 * including this struct */
-+
-+	uint32_t data_start;	/* offset to start of data
-+				 * relative to start of this struct */
-+
-+	uint32_t target_count;	/* in/out */
-+	int32_t open_count;	/* out */
-+	uint32_t flags;		/* in/out */
-+	uint32_t event_nr;      	/* in/out */
-+	uint32_t padding;
-+
-+	uint64_t dev;		/* in/out */
-+
-+	char name[DM_NAME_LEN];	/* device name */
-+	char uuid[DM_UUID_LEN];	/* unique identifier for
-+				 * the block device */
-+};
-+
-+/*
-+ * Used to specify tables.  These structures appear after the
-+ * dm_ioctl.
-+ */
-+struct dm_target_spec {
-+	uint64_t sector_start;
-+	uint64_t length;
-+	int32_t status;		/* used when reading from kernel only */
-+
-+	/*
-+	 * Offset in bytes (from the start of this struct) to
-+	 * next target_spec.
-+	 */
-+	uint32_t next;
-+
-+	char target_type[DM_MAX_TYPE_NAME];
-+
-+	/*
-+	 * Parameter string starts immediately after this object.
-+	 * Be careful to add padding after string to ensure correct
-+	 * alignment of subsequent dm_target_spec.
-+	 */
-+};
-+
-+/*
-+ * Used to retrieve the target dependencies.
-+ */
-+struct dm_target_deps {
-+	uint32_t count;	/* Array size */
-+	uint32_t padding;	/* unused */
-+	uint64_t dev[0];	/* out */
-+};
-+
-+/*
-+ * Used to get a list of all dm devices.
-+ */
-+struct dm_name_list {
-+	uint64_t dev;
-+	uint32_t next;		/* offset to the next record from
-+				   the _start_ of this */
-+	char name[0];
-+};
-+
-+/*
-+ * If you change this make sure you make the corresponding change
-+ * to dm-ioctl.c:lookup_ioctl()
-+ */
-+enum {
-+	/* Top level cmds */
-+	DM_VERSION_CMD = 0,
-+	DM_REMOVE_ALL_CMD,
-+	DM_LIST_DEVICES_CMD,
-+
-+	/* device level cmds */
-+	DM_DEV_CREATE_CMD,
-+	DM_DEV_REMOVE_CMD,
-+	DM_DEV_RENAME_CMD,
-+	DM_DEV_SUSPEND_CMD,
-+	DM_DEV_STATUS_CMD,
-+	DM_DEV_WAIT_CMD,
-+
-+	/* Table level cmds */
-+	DM_TABLE_LOAD_CMD,
-+	DM_TABLE_CLEAR_CMD,
-+	DM_TABLE_DEPS_CMD,
-+	DM_TABLE_STATUS_CMD,
-+};
-+
-+#define DM_IOCTL 0xfd
-+
-+#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
-+#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
-+#define DM_LIST_DEVICES  _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
-+
-+#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
-+#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
-+#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
-+#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
-+#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
-+#define DM_DEV_WAIT      _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
-+
-+#define DM_TABLE_LOAD    _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
-+#define DM_TABLE_CLEAR   _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
-+#define DM_TABLE_DEPS    _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
-+#define DM_TABLE_STATUS  _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
-+
-+#define DM_VERSION_MAJOR	4
-+#define DM_VERSION_MINOR	0
-+#define DM_VERSION_PATCHLEVEL	0
-+#define DM_VERSION_EXTRA	"-ioctl (2003-06-04)"
-+
-+/* Status bits */
-+#define DM_READONLY_FLAG	(1 << 0) /* In/Out */
-+#define DM_SUSPEND_FLAG		(1 << 1) /* In/Out */
-+#define DM_PERSISTENT_DEV_FLAG	(1 << 3) /* In */
-+
-+/*
-+ * Flag passed into ioctl STATUS command to get table information
-+ * rather than current status.
-+ */
-+#define DM_STATUS_TABLE_FLAG	(1 << 4) /* In */
-+
-+/*
-+ * Flags that indicate whether a table is present in either of
-+ * the two table slots that a device has.
-+ */
-+#define DM_ACTIVE_PRESENT_FLAG   (1 << 5) /* Out */
-+#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
-+
-+/*
-+ * Indicates that the buffer passed in wasn't big enough for the
-+ * results.
-+ */
-+#define DM_BUFFER_FULL_FLAG	(1 << 8) /* Out */
-+
-+#endif				/* _LINUX_DM_IOCTL_H */
---- linux-2.6.0-test1/include/linux/elevator.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/elevator.h	2003-07-19 17:03:51.000000000 -0700
-@@ -13,6 +13,7 @@ typedef struct request *(elevator_next_r
- typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
- typedef int (elevator_queue_empty_fn) (request_queue_t *);
- typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
-+typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
- typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
- typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
- typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
-@@ -33,6 +34,7 @@ struct elevator_s
- 	elevator_next_req_fn *elevator_next_req_fn;
- 	elevator_add_req_fn *elevator_add_req_fn;
- 	elevator_remove_req_fn *elevator_remove_req_fn;
-+	elevator_requeue_req_fn *elevator_requeue_req_fn;
- 
- 	elevator_queue_empty_fn *elevator_queue_empty_fn;
- 	elevator_completed_req_fn *elevator_completed_req_fn;
-@@ -64,6 +66,7 @@ extern void elv_merge_requests(request_q
- 			       struct request *);
- extern void elv_merged_request(request_queue_t *, struct request *);
- extern void elv_remove_request(request_queue_t *, struct request *);
-+extern void elv_requeue_request(request_queue_t *, struct request *);
- extern int elv_queue_empty(request_queue_t *);
- extern struct request *elv_next_request(struct request_queue *q);
- extern struct request *elv_former_request(request_queue_t *, struct request *);
---- linux-2.6.0-test1/include/linux/elfcore.h	2003-06-14 12:18:51.000000000 -0700
-+++ 25/include/linux/elfcore.h	2003-07-19 17:03:51.000000000 -0700
-@@ -107,12 +107,12 @@ static inline int elf_core_copy_task_reg
- 
- extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
- 
--static inline int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
-+static inline int elf_core_copy_task_fpregs(struct task_struct *t, struct pt_regs *regs, elf_fpregset_t *fpu)
- {
- #ifdef ELF_CORE_COPY_FPREGS
- 	return ELF_CORE_COPY_FPREGS(t, fpu);
- #else
--	return dump_fpu(NULL, fpu);
-+	return dump_fpu(regs, fpu);
- #endif
- }
- 
---- linux-2.6.0-test1/include/linux/errno.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/errno.h	2003-07-19 17:06:43.000000000 -0700
-@@ -22,6 +22,7 @@
- #define EBADTYPE	527	/* Type not supported by server */
- #define EJUKEBOX	528	/* Request initiated, but will not complete before timeout */
- #define EIOCBQUEUED	529	/* iocb queued, will get completion event */
-+#define EIOCBRETRY	530	/* iocb queued, will trigger a retry */
- 
- #endif
- 
---- linux-2.6.0-test1/include/linux/ext3_fs.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/ext3_fs.h	2003-07-19 17:07:18.000000000 -0700
-@@ -721,7 +721,6 @@ extern int ext3_forget(handle_t *, int, 
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
- 
--extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
- extern int  ext3_setattr (struct dentry *, struct iattr *);
---- linux-2.6.0-test1/include/linux/ext3_jbd.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/linux/ext3_jbd.h	2003-07-19 17:03:51.000000000 -0700
-@@ -30,10 +30,11 @@
- 
- #define EXT3_SINGLEDATA_TRANS_BLOCKS	8U
- 
--/* Extended attributes may touch two data buffers, two bitmap buffers,
-- * and two group and summaries. */
-+/* Extended attribute operations touch at most two data buffers,
-+ * two bitmap buffers, and two group summaries, in addition to the inode
-+ * and the superblock, which are already accounted for. */
- 
--#define EXT3_XATTR_TRANS_BLOCKS		8
-+#define EXT3_XATTR_TRANS_BLOCKS		6U
- 
- /* Define the minimum size for a transaction which modifies data.  This
-  * needs to take into account the fact that we may end up modifying two
---- linux-2.6.0-test1/include/linux/fb.h	2003-06-14 12:18:06.000000000 -0700
-+++ 25/include/linux/fb.h	2003-07-19 17:04:55.000000000 -0700
-@@ -2,7 +2,6 @@
- #define _LINUX_FB_H
- 
- #include <linux/tty.h>
--#include <linux/workqueue.h>
- #include <asm/types.h>
- #include <asm/io.h>
- 
-@@ -326,28 +325,38 @@ struct fb_cursor {
- 	struct fb_image	image;	/* Cursor image */
- };
- 
-+#ifdef __KERNEL__
-+
-+#include <linux/fs.h>
-+#include <linux/init.h>
-+#include <linux/workqueue.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+/*
-+ * The purpose of this structure is to translate data
-+ * from the hardwre independent format of fbdev to what 
-+ * format the hardware needs.
-+ */ 
-+
- #define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
- #define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
- #define FB_PIXMAP_IO      4     /* memory is iomapped       */
- #define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
- 
- struct fb_pixmap {
--        __u8  *addr;                      /* pointer to memory             */  
--	__u32 size;                       /* size of buffer in bytes       */
--	__u32 offset;                     /* current offset to buffer      */
--	__u32 buf_align;                  /* byte alignment of each bitmap */
--	__u32 scan_align;                 /* alignment per scanline        */
--	__u32 flags;                      /* see FB_PIXMAP_*               */
--					  /* access methods                */
--	void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
--	u8   (*inbuf) (u8 *addr);
--	spinlock_t lock;                  /* spinlock                      */
-+	u8  *addr;		/* pointer to memory 			*/
-+	u32 size;		/* size of buffer in bytes 		*/
-+	u32 offset;		/* current offset to buffer 		*/
-+	u32 buf_align;		/* byte alignment of each bitmap 	*/
-+	u32 scan_align;		/* alignment per scanline 		*/
-+	u32 access_align;	/* alignment per read/write		*/
-+	u32 flags;		/* see FB_PIXMAP_* 			*/
-+	spinlock_t lock;	/* spinlock 				*/
- 	atomic_t count;
-+	/* access methods */
-+	void (*outbuf)(u8 *addr, u8 *dst, unsigned int size); 
-+	u8   (*inbuf) (u8 *addr);
- };
--#ifdef __KERNEL__
--
--#include <linux/fs.h>
--#include <linux/init.h>
- 
- struct fb_info;
- struct vm_area_struct;
-@@ -396,24 +405,24 @@ struct fb_ops {
- };
- 
- struct fb_info {
--   int node;
--   int flags;
--   int open;                            /* Has this been open already ? */
-+	int node;
-+	int flags;
- #define FBINFO_FLAG_MODULE	1	/* Low-level driver is a module */
--   struct fb_var_screeninfo var;        /* Current var */
--   struct fb_fix_screeninfo fix;        /* Current fix */
--   struct fb_monspecs monspecs;         /* Current Monitor specs */
--   struct fb_cursor cursor;		/* Current cursor */	
--   struct work_struct queue;		/* Framebuffer event queue */
--   struct fb_pixmap pixmap;	        /* Current pixmap */
--   struct fb_cmap cmap;                 /* Current cmap */
--   struct fb_ops *fbops;
--   char *screen_base;                   /* Virtual address */
--   struct vc_data *display_fg;		/* Console visible on this display */
--   int currcon;				/* Current VC. */	
--   void *pseudo_palette;                /* Fake palette of 16 colors */ 
--   /* From here on everything is device dependent */
--   void *par;	
-+	struct fb_var_screeninfo var;	/* Current var */
-+	struct fb_fix_screeninfo fix;	/* Current fix */
-+	struct fb_monspecs monspecs;	/* Current Monitor specs */
-+	struct fb_cursor cursor;	/* Current cursor */	
-+	struct work_struct queue;	/* Framebuffer event queue */
-+	struct fb_pixmap pixmap;	/* Image HW mapper */
-+	struct fb_pixmap sprite;	/* Cursor HW mapper */
-+	struct fb_cmap cmap;		/* Current cmap */
-+	struct fb_ops *fbops;
-+	char *screen_base;		/* Virtual address */
-+	struct vc_data *display_fg;	/* Console visible on this display */
-+	void *pseudo_palette;		/* Fake palette of 16 colors */ 
-+	int currcon;			/* Current VC. */	
-+	/* From here on everything is device dependent */
-+	void *par;	
- };
- 
- #ifdef MODULE
-@@ -481,12 +490,12 @@ extern int register_framebuffer(struct f
- extern int unregister_framebuffer(struct fb_info *fb_info);
- extern int fb_prepare_logo(struct fb_info *fb_info);
- extern int fb_show_logo(struct fb_info *fb_info);
--extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
--extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
--			     	u32 height, u32 mask, u32 shift_high, u32 shift_low,
-+extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
-+extern void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
-+				u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
- 				u32 mod, u32 idx);
--extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
--			     u32 s_pitch, u32 height);
-+extern void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src, 
-+			     u32 d_pitch, u32 s_pitch, u32 height);
- extern struct fb_info *registered_fb[FB_MAX];
- extern int num_registered_fb;
- 
---- linux-2.6.0-test1/include/linux/fs.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/linux/fs.h	2003-07-19 17:07:03.000000000 -0700
-@@ -323,6 +323,7 @@ struct address_space {
- 	struct list_head	i_mmap;		/* list of private mappings */
- 	struct list_head	i_mmap_shared;	/* list of shared mappings */
- 	struct semaphore	i_shared_sem;	/* protect both above lists */
-+	atomic_t		truncate_count;	/* Cover race condition with truncate */
- 	unsigned long		dirtied_when;	/* jiffies of first page dirtying */
- 	int			gfp_mask;	/* how to allocate the pages */
- 	struct backing_dev_info *backing_dev_info; /* device readahead, etc */
-@@ -729,6 +730,11 @@ extern int vfs_rename(struct inode *, st
- #define DT_SOCK		12
- #define DT_WHT		14
- 
-+#define OSYNC_METADATA	(1<<0)
-+#define OSYNC_DATA	(1<<1)
-+#define OSYNC_INODE	(1<<2)
-+int generic_osync_inode(struct inode *, int);
-+
- /*
-  * This is the "filldir" function type, used by readdir() to let
-  * the kernel specify what kind of dirent layout it wants to have.
---- linux-2.6.0-test1/include/linux/hfs_sysdep.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/linux/hfs_sysdep.h	2003-07-19 17:03:51.000000000 -0700
-@@ -28,9 +28,6 @@
- 
- extern struct timezone sys_tz;
- 
--#undef offsetof
--#define offsetof(TYPE, MEMB) ((size_t) &((TYPE *)0)->MEMB)
--
- /* Typedefs for integer types by size and signedness */
- typedef __u8            hfs_u8;
- typedef __u16           hfs_u16;
---- linux-2.6.0-test1/include/linux/ide.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/linux/ide.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1288,12 +1288,6 @@ extern ide_devices_t   *idescsi;
- #endif
- extern int noautodma;
- 
--/*
-- * We need blk.h, but we replace its end_request by our own version.
-- */
--#define IDE_DRIVER		/* Toggle some magic bits in blk.h */
--#include <linux/blk.h>
--
- extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
- 
- /*
---- linux-2.6.0-test1/include/linux/init_task.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/init_task.h	2003-07-19 17:06:43.000000000 -0700
-@@ -70,7 +70,7 @@
- 	.prio		= MAX_PRIO-20,					\
- 	.static_prio	= MAX_PRIO-20,					\
- 	.policy		= SCHED_NORMAL,					\
--	.cpus_allowed	= ~0UL,						\
-+	.cpus_allowed	= CPU_MASK_ALL,					\
- 	.mm		= NULL,						\
- 	.active_mm	= &init_mm,					\
- 	.run_list	= LIST_HEAD_INIT(tsk.run_list),			\
-@@ -108,6 +108,7 @@
- 	.proc_lock	= SPIN_LOCK_UNLOCKED,				\
- 	.switch_lock	= SPIN_LOCK_UNLOCKED,				\
- 	.journal_info	= NULL,						\
-+	.io_wait	= NULL,						\
- }
- 
- 
---- linux-2.6.0-test1/include/linux/irq.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/linux/irq.h	2003-07-19 17:04:07.000000000 -0700
-@@ -15,6 +15,7 @@
- 
- #include <linux/cache.h>
- #include <linux/spinlock.h>
-+#include <linux/cpumask.h>
- 
- #include <asm/irq.h>
- #include <asm/ptrace.h>
-@@ -44,7 +45,7 @@ struct hw_interrupt_type {
- 	void (*disable)(unsigned int irq);
- 	void (*ack)(unsigned int irq);
- 	void (*end)(unsigned int irq);
--	void (*set_affinity)(unsigned int irq, unsigned long mask);
-+	void (*set_affinity)(unsigned int irq, cpumask_t dest);
- };
- 
- typedef struct hw_interrupt_type  hw_irq_controller;
---- linux-2.6.0-test1/include/linux/kdev_t.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/kdev_t.h	2003-07-19 17:06:39.000000000 -0700
-@@ -1,82 +1,14 @@
- #ifndef _LINUX_KDEV_T_H
- #define _LINUX_KDEV_T_H
- #ifdef __KERNEL__
--/*
--As a preparation for the introduction of larger device numbers,
--we introduce a type kdev_t to hold them. No information about
--this type is known outside of this include file.
--
--Objects of type kdev_t designate a device. Outside of the kernel
--the corresponding things are objects of type dev_t - usually an
--integral type with the device major and minor in the high and low
--bits, respectively. Conversion is done by
--
--extern kdev_t to_kdev_t(int);
--
--It is up to the various file systems to decide how objects of type
--dev_t are stored on disk.
--The only other point of contact between kernel and outside world
--are the system calls stat and mknod, new versions of which will
--eventually have to be used in libc.
--
--[Unfortunately, the floppy control ioctls fail to hide the internal
--kernel structures, and the fd_device field of a struct floppy_drive_struct
--is user-visible. So, it remains a dev_t for the moment, with some ugly
--conversions in floppy.c.]
--
--Inside the kernel, we aim for a kdev_t type that is a pointer
--to a structure with information about the device (like major,
--minor, size, blocksize, sectorsize, name, read-only flag,
--struct file_operations etc.).
--
--However, for the time being we let kdev_t be almost the same as dev_t:
--
--typedef struct { unsigned short major, minor; } kdev_t;
--
--Admissible operations on an object of type kdev_t:
--- passing it along
--- comparing it for equality with another such object
--- storing it in inode->i_rdev or tty->device
--- using its bit pattern as argument in a hash function
--- finding its major and minor
--- complaining about it
--
--An object of type kdev_t is created only by the function MKDEV(),
--with the single exception of the constant 0 (no device).
--
--Right now the other information mentioned above is usually found
--in static arrays indexed by major or major,minor.
--
--An obstacle to immediately using
--    typedef struct { ... (* lots of information *) } *kdev_t
--is the case of mknod used to create a block device that the
--kernel doesn't know about at present (but first learns about
--when some module is inserted).
--
--aeb - 950811
--*/
- 
-+#include <linux/types.h>       /* for dev_t */
- 
--/*
-- * NOTE NOTE NOTE!
-- *
-- * The kernel-internal "kdev_t" will eventually have
-- * 20 bits for minor numbers, and 12 bits for majors.
-- *
-- * HOWEVER, the external representation is still 8+8
-- * bits, and there is no way to generate the extended
-- * "kdev_t" format yet. Which is just as well, since
-- * we still use "minor" as an index into various
-- * static arrays, and they are sized for a 8-bit index.
-- */
- typedef struct {
--	unsigned short value;
-+	unsigned long long value;
- } kdev_t;
- 
--#define KDEV_MINOR_BITS		8
--#define KDEV_MAJOR_BITS		8
--
--#define __mkdev(major,minor)	(((major) << KDEV_MINOR_BITS) + (minor))
-+#define __mkdev(major, minor)	(((unsigned long long)(major) << 32) + (minor))
- 
- #define mk_kdev(major, minor)	((kdev_t) { __mkdev(major,minor) } )
- 
-@@ -85,12 +17,12 @@ typedef struct {
-  * internal equality comparisons and for things
-  * like NFS filehandle conversion.
-  */
--static inline unsigned int kdev_val(kdev_t dev)
-+static inline unsigned long long kdev_val(kdev_t dev)
- {
- 	return dev.value;
- }
- 
--static inline kdev_t val_to_kdev(unsigned int val)
-+static inline kdev_t val_to_kdev(unsigned long long val)
- {
- 	kdev_t dev;
- 	dev.value = val;
-@@ -107,37 +39,85 @@ static inline int kdev_same(kdev_t dev1,
- 
- #define kdev_none(d1)	(!kdev_val(d1))
- 
--/* Mask off the high bits for now.. */
--#define minor(dev)	((dev).value & 0xff)
--#define major(dev)	(((dev).value >> KDEV_MINOR_BITS) & 0xff)
-+#define minor(dev)	(unsigned int)((dev).value & 0xffffffff)
-+#define major(dev)	(unsigned int)((dev).value >> 32)
- 
- /* These are for user-level "dev_t" */
--#define MINORBITS	8
--#define MINORMASK	((1U << MINORBITS) - 1)
-+/* Going back and forth between dev and (ma,mi) is one-to-one
-+   provided ma is nonzero or ma is zero and mi is 8-bit only.
-+   Never use major 0 together with a minor larger than 255. */
-+#if 0
-+/* readable versions */
-+static inline unsigned int
-+MAJOR(dev_t dev) {
-+        return (dev & ~0xffffffffULL) ? (dev >> 32) :
-+                (dev & ~0xffff) ? (dev >> 16) : (dev >> 8);
-+}
- 
--#define MAJOR(dev)	((unsigned int) ((dev) >> MINORBITS))
--#define MINOR(dev)	((unsigned int) ((dev) & MINORMASK))
--#define MKDEV(ma,mi)	(((ma) << MINORBITS) | (mi))
-+static inline unsigned int
-+MINOR(dev_t dev) {
-+        return (dev & ~0xffffffffULL) ? (dev & 0xffffffff) :
-+                (dev & ~0xffff) ? (dev & 0xffff) : (dev & 0xff);
-+}
-+
-+static inline dev_t
-+MKDEV(unsigned int major, unsigned int minor) {
-+        unsigned int both = (major | minor);
-+        return ((both & ~0xffff) ? (((dev_t) major) << 32) :
-+                (both & ~0xff) ? (((dev_t) major) << 16) :
-+                (((dev_t) major) << 8) ) | minor;
-+}
-+#else
-+/* ugly macro versions */
-+#define MAJOR(dev) ((unsigned int)({ dev_t __dev = dev; \
-+   (__dev & ~0xffffffffULL) ? (__dev >> 32) : \
-+   (__dev & ~0xffff) ? (__dev >> 16) : (__dev >> 8); }))
-+#define MINOR(dev) ((unsigned int)({ dev_t __dev = dev; \
-+   (__dev & ~0xffffffffULL) ? (__dev & 0xffffffff) : \
-+   (__dev & ~0xffff) ? (__dev & 0xffff) : (__dev & 0xff); }))
-+#define constant_MKDEV(ma, mi) \
-+   ((((ma)|(mi)) & ~0xffff) ? ((ma) << 32) | (mi) : \
-+    (((ma)|(mi)) & ~0xff) ? ((ma) << 16) | (mi) : ((ma) << 8) | (mi))
-+#define MKDEV(major, minor) ({ \
-+   unsigned int __ma = major, __mi = minor, __both = (__ma | __mi); \
-+   ((sizeof(dev_t) > 4 && (__both & ~0xffff)) ? (((dev_t) __ma) << 32) : \
-+    (__both & ~0xff) ? (((dev_t) __ma) << 16) : (((dev_t) __ma) << 8) \
-+   ) | __mi; })
-+#endif
- 
- /*
-  * Conversion functions
-  */
- 
--static inline int kdev_t_to_nr(kdev_t dev)
-+static inline dev_t kdev_t_to_nr(kdev_t dev)
- {
--	return MKDEV(major(dev), minor(dev));
-+	unsigned int ma = major(dev);
-+	unsigned int mi = minor(dev);
-+	return MKDEV(ma, mi);
- }
- 
--static inline kdev_t to_kdev_t(int dev)
-+static inline kdev_t to_kdev_t(dev_t dev)
- {
--	return mk_kdev(MAJOR(dev),MINOR(dev));
-+	unsigned int ma = MAJOR(dev);
-+	unsigned int mi = MINOR(dev);
-+	return mk_kdev(ma, mi);
- }
- 
-+#define print_dev_t(buffer, dev)					\
-+	sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev))
-+
-+#define format_dev_t(buffer, dev)					\
-+	({								\
-+		sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev));	\
-+		buffer;							\
-+	})
-+
- #else /* __KERNEL__ */
- 
- /*
- Some programs want their definitions of MAJOR and MINOR and MKDEV
- from the kernel sources. These must be the externally visible ones.
-+Of course such programs should be updated.
- */
- #define MAJOR(dev)	((dev)>>8)
- #define MINOR(dev)	((dev) & 0xff)
---- linux-2.6.0-test1/include/linux/kernel_stat.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/kernel_stat.h	2003-07-19 17:03:51.000000000 -0700
-@@ -23,9 +23,7 @@ struct cpu_usage_stat {
- 
- struct kernel_stat {
- 	struct cpu_usage_stat	cpustat;
--#if !defined(CONFIG_ARCH_S390)
- 	unsigned int irqs[NR_IRQS];
--#endif
- };
- 
- DECLARE_PER_CPU(struct kernel_stat, kstat);
-@@ -36,7 +34,6 @@ DECLARE_PER_CPU(struct kernel_stat, ksta
- 
- extern unsigned long nr_context_switches(void);
- 
--#if !defined(CONFIG_ARCH_S390)
- /*
-  * Number of interrupts per specific IRQ source, since bootup
-  */
-@@ -50,6 +47,5 @@ static inline int kstat_irqs(int irq)
- 
- 	return sum;
- }
--#endif
- 
- #endif /* _LINUX_KERNEL_STAT_H */
---- linux-2.6.0-test1/include/linux/linux_logo.h	2003-06-14 12:18:05.000000000 -0700
-+++ 25/include/linux/linux_logo.h	2003-07-19 17:04:55.000000000 -0700
-@@ -16,13 +16,11 @@
- 
- #include <linux/init.h>
- 
--
- #define LINUX_LOGO_MONO		1	/* monochrome black/white */
- #define LINUX_LOGO_VGA16	2	/* 16 colors VGA text palette */
- #define LINUX_LOGO_CLUT224	3	/* 224 colors */
- #define LINUX_LOGO_GRAY256	4	/* 256 levels grayscale */
- 
--
- struct linux_logo {
- 	int type;			/* one of LINUX_LOGO_* */
- 	unsigned int width;
-@@ -32,6 +30,6 @@ struct linux_logo {
- 	const unsigned char *data;
- };
- 
--extern const struct linux_logo *fb_find_logo(int depth);
-+extern const struct linux_logo *find_logo(int depth);
- 
- #endif /* _LINUX_LINUX_LOGO_H */
---- linux-2.6.0-test1/include/linux/list.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/list.h	2003-07-19 17:06:35.000000000 -0700
-@@ -142,8 +142,11 @@ static inline void __list_del(struct lis
-  * Note: list_empty on entry does not return true after this, the entry is
-  * in an undefined state.
-  */
-+#include <linux/kernel.h>	/* BUG_ON */
- static inline void list_del(struct list_head *entry)
- {
-+	BUG_ON(entry->prev->next != entry);
-+	BUG_ON(entry->next->prev != entry);
- 	__list_del(entry->prev, entry->next);
- 	entry->next = LIST_POISON1;
- 	entry->prev = LIST_POISON2;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/linux/lockmeter.h	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,320 @@
-+/*
-+ *  Copyright (C) 1999-2002 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
-+ *
-+ *  Modified by Ray Bryant (raybry@us.ibm.com) Feb-Apr 2000
-+ *  Changes Copyright (C) 2000 IBM, Inc.
-+ *  Added save of index in spinlock_t to improve efficiency
-+ *  of "hold" time reporting for spinlocks
-+ *  Added support for hold time statistics for read and write
-+ *  locks.
-+ *  Moved machine dependent code to include/asm/lockmeter.h.
-+ *
-+ */
-+
-+#ifndef _LINUX_LOCKMETER_H
-+#define _LINUX_LOCKMETER_H
-+
-+
-+/*---------------------------------------------------
-+ *	architecture-independent lockmeter.h
-+ *-------------------------------------------------*/
-+
-+/*
-+ * raybry -- version 2: added efficient hold time statistics
-+ *           requires lstat recompile, so flagged as new version
-+ * raybry -- version 3: added global reader lock data
-+ * hawkes -- version 4: removed some unnecessary fields to simplify mips64 port
-+ */
-+#define LSTAT_VERSION	5
-+
-+int	lstat_update(void*, void*, int);
-+int	lstat_update_time(void*, void*, int, uint32_t);
-+
-+/*
-+ * Currently, the mips64 and sparc64 kernels talk to a 32-bit lockstat, so we
-+ * need to force compatibility in the inter-communication data structure.
-+ */
-+
-+#if defined(CONFIG_MIPS32_COMPAT)
-+#define TIME_T		uint32_t
-+#elif defined(CONFIG_SPARC32_COMPAT)
-+#define TIME_T		uint64_t
-+#else
-+#define TIME_T		time_t
-+#endif
-+
-+#if defined(__KERNEL__) || (!defined(CONFIG_MIPS32_COMPAT) && !defined(CONFIG_SPARC32_COMPAT)) || (_MIPS_SZLONG==32)
-+#define POINTER		void *
-+#else
-+#define	POINTER		int64_t
-+#endif
-+
-+/*
-+ * Values for the "action" parameter passed to lstat_update.
-+ *	ZZZ - do we want a try-success status here???
-+ */
-+#define LSTAT_ACT_NO_WAIT	0
-+#define LSTAT_ACT_SPIN		1
-+#define LSTAT_ACT_REJECT	2
-+#define LSTAT_ACT_WW_SPIN       3
-+#define LSTAT_ACT_SLEPT		4 /* UNUSED */
-+
-+#define LSTAT_ACT_MAX_VALUES	4 /* NOTE: Increase to 5 if use ACT_SLEPT */
-+
-+/*
-+ * Special values for the low 2 bits of an RA passed to
-+ * lstat_update.
-+ */
-+/* we use these values to figure out what kind of lock data */
-+/* is stored in the statistics table entry at index ....... */
-+#define LSTAT_RA_SPIN           0  /* spin lock data */
-+#define LSTAT_RA_READ           1  /* read lock statistics */
-+#define LSTAT_RA_SEMA		2  /* RESERVED */
-+#define LSTAT_RA_WRITE          3  /* write lock statistics*/
-+
-+#define LSTAT_RA(n)	\
-+	((void*)( ((unsigned long)__builtin_return_address(0) & ~3) | n) )
-+
-+/*
-+ * Constants used for lock addresses in the lstat_directory
-+ * to indicate special values of the lock address.
-+ */
-+#define	LSTAT_MULTI_LOCK_ADDRESS	NULL
-+
-+/*
-+ * Maximum size of the lockstats tables. Increase this value
-+ * if its not big enough. (Nothing bad happens if its not
-+ * big enough although some locks will not be monitored.)
-+ * We record overflows of this quantity in lstat_control.dir_overflows
-+ *
-+ * Note:  The max value here must fit into the field set
-+ * and obtained by the macro's PUT_INDEX() and GET_INDEX().
-+ * This value depends on how many bits are available in the
-+ * lock word in the particular machine implementation we are on.
-+ */
-+#define LSTAT_MAX_STAT_INDEX		2000
-+
-+/*
-+ * Size and mask for the hash table into the directory.
-+ */
-+#define LSTAT_HASH_TABLE_SIZE		4096		/* must be 2**N */
-+#define LSTAT_HASH_TABLE_MASK		(LSTAT_HASH_TABLE_SIZE-1)
-+
-+#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
-+
-+/*
-+ *	This defines an entry in the lockstat directory. It contains
-+ *	information about a lock being monitored.
-+ *	A directory entry only contains the lock identification -
-+ *	counts on usage of the lock are kept elsewhere in a per-cpu
-+ *	data structure to minimize cache line pinging.
-+ */
-+typedef struct {
-+	POINTER	caller_ra;		  /* RA of code that set lock */
-+	POINTER	lock_ptr;		  /* lock address */
-+	ushort	next_stat_index;  /* Used to link multiple locks that have the same hash table value */
-+} lstat_directory_entry_t;
-+
-+/*
-+ *	A multi-dimensioned array used to contain counts for lock accesses.
-+ *	The array is 3-dimensional:
-+ *		- CPU number. Keep from thrashing cache lines between CPUs
-+ *		- Directory entry index. Identifies the lock
-+ *		- Action. Indicates what kind of contention occurred on an
-+ *		  access to the lock.
-+ *
-+ *	The index of an entry in the directory is the same as the 2nd index
-+ *	of the entry in the counts array.
-+ */
-+/*
-+ *  This table contains data for spin_locks, write locks, and read locks
-+ *  Not all data is used for all cases.  In particular, the hold time
-+ *  information is not stored here for read locks since that is a global
-+ *  (e. g. cannot be separated out by return address) quantity.
-+ *  See the lstat_read_lock_counts_t structure for the global read lock
-+ *  hold time.
-+ */
-+typedef struct {
-+	uint64_t    cum_wait_ticks;	/* sum of wait times               */
-+	                                /* for write locks, sum of time a  */
-+					/* writer is waiting for a reader  */
-+	int64_t	    cum_hold_ticks;	/* cumulative sum of holds         */
-+	                                /* not used for read mode locks    */
-+					/* must be signed. ............... */
-+	uint32_t    max_wait_ticks;	/* max waiting time                */
-+	uint32_t    max_hold_ticks;	/* max holding time                */
-+	uint64_t    cum_wait_ww_ticks;  /* sum times writer waits on writer*/
-+	uint32_t    max_wait_ww_ticks;  /* max wait time writer vs writer  */
-+	                                /* prev 2 only used for write locks*/
-+	uint32_t    acquire_time;       /* time lock acquired this CPU     */
-+	uint32_t    count[LSTAT_ACT_MAX_VALUES];
-+} lstat_lock_counts_t;
-+
-+typedef lstat_lock_counts_t	lstat_cpu_counts_t[LSTAT_MAX_STAT_INDEX];
-+
-+/*
-+ * User request to:
-+ *	- turn statistic collection on/off, or to reset
-+ */
-+#define LSTAT_OFF	 0
-+#define LSTAT_ON	 1
-+#define LSTAT_RESET      2
-+#define LSTAT_RELEASE    3
-+
-+#define LSTAT_MAX_READ_LOCK_INDEX 1000
-+typedef struct {
-+	POINTER	    lock_ptr;            /* address of lock for output stats */
-+	uint32_t    read_lock_count;
-+	int64_t     cum_hold_ticks;       /* sum of read lock hold times over */
-+	                                  /* all callers. ....................*/
-+	uint32_t    write_index;          /* last write lock hash table index */
-+	uint32_t    busy_periods;         /* count of busy periods ended this */
-+	uint64_t    start_busy;           /* time this busy period started. ..*/
-+	uint64_t    busy_ticks;           /* sum of busy periods this lock. ..*/
-+	uint64_t    max_busy;             /* longest busy period for this lock*/
-+	uint32_t    max_readers;          /* maximum number of readers ...... */
-+#ifdef USER_MODE_TESTING
-+	rwlock_t    entry_lock;           /* lock for this read lock entry... */
-+	                                  /* avoid having more than one rdr at*/
-+	                                  /* needed for user space testing... */
-+	                                  /* not needed for kernel 'cause it  */
-+					  /* is non-preemptive. ............. */
-+#endif
-+} lstat_read_lock_counts_t;
-+typedef lstat_read_lock_counts_t	lstat_read_lock_cpu_counts_t[LSTAT_MAX_READ_LOCK_INDEX];
-+
-+#if defined(__KERNEL__) || defined(USER_MODE_TESTING)
-+
-+#ifndef USER_MODE_TESTING
-+#include <asm/lockmeter.h>
-+#else
-+#include "asm_newlockmeter.h"
-+#endif
-+
-+/*
-+ * Size and mask for the hash table into the directory.
-+ */
-+#define LSTAT_HASH_TABLE_SIZE		4096		/* must be 2**N */
-+#define LSTAT_HASH_TABLE_MASK		(LSTAT_HASH_TABLE_SIZE-1)
-+
-+#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
-+
-+/*
-+ * This version eliminates the per processor lock stack.  What we do is to
-+ * store the index of the lock hash structure in unused bits in the lock
-+ * itself.  Then on unlock we can find the statistics record without doing
-+ * any additional hash or lock stack lookup.  This works for spin_locks.
-+ * Hold time reporting is now basically as cheap as wait time reporting
-+ * so we ignore the difference between LSTAT_ON_HOLD and LSTAT_ON_WAIT
-+ * as in version 1.1.* of lockmeter.
-+ *
-+ * For rw_locks, we store the index of a global reader stats structure in
-+ * the lock and the writer index is stored in the latter structure.
-+ * For read mode locks we hash at the time of the lock to find an entry
-+ * in the directory for reader wait time and the like.
-+ * At unlock time for read mode locks, we update just the global structure
-+ * so we don't need to know the reader directory index value at unlock time.
-+ *
-+ */
-+
-+/*
-+ * Protocol to change lstat_control.state
-+ *   This is complicated because we don't want the cum_hold_time for
-+ * a rw_lock to be decremented in _read_lock_ without making sure it
-+ * is incremented in _read_lock_ and vice versa.  So here is the
-+ * way we change the state of lstat_control.state:
-+ * I.  To Turn Statistics On
-+ *     After allocating storage, set lstat_control.state non-zero.
-+ * This works because we don't start updating statistics for in use
-+ * locks until the reader lock count goes to zero.
-+ * II. To Turn Statistics Off:
-+ * (0)  Disable interrupts on this CPU
-+ * (1)  Seize the lstat_control.directory_lock
-+ * (2)  Obtain the current value of lstat_control.next_free_read_lock_index
-+ * (3)  Store a zero in lstat_control.state.
-+ * (4)  Release the lstat_control.directory_lock
-+ * (5)  For each lock in the read lock list up to the saved value
-+ *      (well, -1) of the next_free_read_lock_index, do the following:
-+ *      (a)  Check validity of the stored lock address
-+ *           by making sure that the word at the saved addr
-+ *           has an index that matches this entry.  If not
-+ *           valid, then skip this entry.
-+ *      (b)  If there is a write lock already set on this lock,
-+ *           skip to (d) below.
-+ *      (c)  Set a non-metered write lock on the lock
-+ *      (d)  set the cached INDEX in the lock to zero
-+ *      (e)  Release the non-metered write lock.
-+ * (6)  Re-enable interrupts
-+ *
-+ * These rules ensure that a read lock will not have its statistics
-+ * partially updated even though the global lock recording state has
-+ * changed.  See put_lockmeter_info() for implementation.
-+ *
-+ * The reason for (b) is that there may be write locks set on the
-+ * syscall path to put_lockmeter_info() from user space.  If we do
-+ * not do this check, then we can deadlock.  A similar problem would
-+ * occur if the lock was read locked by the current CPU.  At the
-+ * moment this does not appear to happen.
-+ */
-+
-+/*
-+ * Main control structure for lockstat. Used to turn statistics on/off
-+ * and to maintain directory info.
-+ */
-+typedef struct {
-+	int				state;
-+	spinlock_t		control_lock;		/* used to serialize turning statistics on/off   */
-+	spinlock_t		directory_lock;		/* for serialize adding entries to directory     */
-+	volatile int	next_free_dir_index;/* next free entry in the directory */
-+	/* FIXME not all of these fields are used / needed .............. */
-+                /* the following fields represent data since     */
-+		/* first "lstat on" or most recent "lstat reset" */
-+	TIME_T      first_started_time;     /* time when measurement first enabled */
-+	TIME_T      started_time;           /* time when measurement last started  */
-+	TIME_T      ending_time;            /* time when measurement last disabled */
-+	uint64_t    started_cycles64;       /* cycles when measurement last started          */
-+	uint64_t    ending_cycles64;        /* cycles when measurement last disabled         */
-+	uint64_t    enabled_cycles64;       /* total cycles with measurement enabled         */
-+	int         intervals;              /* number of measurement intervals recorded      */
-+	                                    /* i. e. number of times did lstat on;lstat off  */
-+	lstat_directory_entry_t	*dir;		/* directory */
-+	int         dir_overflow;           /* count of times ran out of space in directory  */
-+	int         rwlock_overflow;        /* count of times we couldn't allocate a rw block*/
-+	ushort		*hashtab;		 	    /* hash table for quick dir scans */
-+	lstat_cpu_counts_t	*counts[NR_CPUS];	 /* Array of pointers to per-cpu stats */
-+    int         next_free_read_lock_index;   /* next rwlock reader (global) stats block  */
-+    lstat_read_lock_cpu_counts_t *read_lock_counts[NR_CPUS]; /* per cpu read lock stats  */
-+} lstat_control_t;
-+
-+#endif	/* defined(__KERNEL__) || defined(USER_MODE_TESTING) */
-+
-+typedef struct {
-+	short		lstat_version;		/* version of the data */
-+	short		state;			/* the current state is returned */
-+	int		maxcpus;		/* Number of cpus present */
-+	int		next_free_dir_index;	/* index of the next free directory entry */
-+	TIME_T          first_started_time;	/* when measurement enabled for first time */
-+	TIME_T          started_time;		/* time in secs since 1969 when stats last turned on  */
-+	TIME_T		ending_time;		/* time in secs since 1969 when stats last turned off */
-+	uint32_t	cycleval;		/* cycles per second */
-+#ifdef notyet
-+	void		*kernel_magic_addr;	/* address of kernel_magic */
-+	void		*kernel_end_addr;	/* contents of kernel magic (points to "end") */
-+#endif
-+	int              next_free_read_lock_index; /* index of next (global) read lock stats struct */
-+	uint64_t         started_cycles64;	/* cycles when measurement last started        */
-+	uint64_t         ending_cycles64;	/* cycles when stats last turned off           */
-+	uint64_t         enabled_cycles64;	/* total cycles with measurement enabled       */
-+	int              intervals;		/* number of measurement intervals recorded      */
-+						/* i.e. number of times we did lstat on;lstat off*/
-+	int              dir_overflow;		/* number of times we wanted more space in directory */
-+	int              rwlock_overflow;	/* # of times we wanted more space in read_locks_count */
-+	struct new_utsname   uts;		/* info about machine where stats are measured */
-+						/* -T option of lockstat allows data to be     */
-+						/* moved to another machine. ................. */
-+} lstat_user_request_t;
-+
-+#endif /* _LINUX_LOCKMETER_H */
---- linux-2.6.0-test1/include/linux/loop.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/linux/loop.h	2003-07-19 17:03:51.000000000 -0700
-@@ -15,7 +15,7 @@
- 
- #ifdef __KERNEL__
- #include <linux/bio.h>
--#include <linux/blk.h>
-+#include <linux/blkdev.h>
- #include <linux/spinlock.h>
- 
- /* Possible states of device */
---- linux-2.6.0-test1/include/linux/mm.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/mm.h	2003-07-19 17:07:16.000000000 -0700
-@@ -421,10 +421,14 @@ int copy_page_range(struct mm_struct *ds
- int zeromap_page_range(struct vm_area_struct *vma, unsigned long from,
- 			unsigned long size, pgprot_t prot);
- 
-+extern void invalidate_mmap_range(struct address_space *mapping,
-+				  loff_t const holebegin,
-+				  loff_t const holelen);
- extern int vmtruncate(struct inode * inode, loff_t offset);
- extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
-+pmd_t *FASTCALL(__pmd_alloc_kernel(struct mm_struct *mm, pgd_t *pmd, unsigned long address));
- extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
--extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
-+pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, unsigned long address));
- extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
- extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
- extern int make_pages_present(unsigned long addr, unsigned long end);
-@@ -485,12 +489,11 @@ static inline int set_page_dirty(struct 
-  * inlining and the symmetry break with pte_alloc_map() that does all
-  * of this out-of-line.
-  */
--static inline pmd_t *pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
--{
--	if (pgd_none(*pgd))
--		return __pmd_alloc(mm, pgd, address);
--	return pmd_offset(pgd, address);
--}
-+#define pmd_alloc_map(mm, pgd, addr)				\
-+	(pgd_none(*(pgd))? __pmd_alloc(mm,pgd,addr): pmd_offset_map(pgd,addr))
-+
-+#define pmd_alloc_kernel(mm, pgd, addr)				\
-+	(pgd_none(*(pgd))? __pmd_alloc_kernel(mm,pgd,addr): pmd_offset_kernel(pgd,addr))
- 
- extern void free_area_init(unsigned long * zones_size);
- extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
---- linux-2.6.0-test1/include/linux/module.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/linux/module.h	2003-07-19 17:03:51.000000000 -0700
-@@ -16,6 +16,7 @@
- #include <linux/kmod.h>
- #include <linux/elf.h>
- #include <linux/stringify.h>
-+#include <asm/local.h>
- 
- #include <asm/module.h>
- 
-@@ -171,7 +172,7 @@ void *__symbol_get_gpl(const char *symbo
- 
- struct module_ref
- {
--	atomic_t count;
-+	local_t count;
- } ____cacheline_aligned;
- 
- enum module_state
-@@ -276,19 +277,17 @@ struct module *module_get_kallsym(unsign
- 				  char *type,
- 				  char namebuf[128]);
- int is_exported(const char *name, const struct module *mod);
--#ifdef CONFIG_MODULE_UNLOAD
- 
-+extern void __module_put_and_exit(struct module *mod, long code)
-+	__attribute__((noreturn));
-+#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
-+
-+#ifdef CONFIG_MODULE_UNLOAD
- unsigned int module_refcount(struct module *mod);
- void __symbol_put(const char *symbol);
- #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
- void symbol_put_addr(void *addr);
- 
--/* We only need protection against local interrupts. */
--#ifndef __HAVE_ARCH_LOCAL_INC
--#define local_inc(x) atomic_inc(x)
--#define local_dec(x) atomic_dec(x)
--#endif
--
- /* Sometimes we know we already have a refcount, and it's easier not
-    to handle the error case (which only happens with rmmod --wait). */
- static inline void __module_get(struct module *module)
-@@ -445,6 +444,8 @@ static inline int unregister_module_noti
- 	return 0;
- }
- 
-+#define module_put_and_exit(code) do_exit(code)
-+
- #endif /* CONFIG_MODULES */
- 
- #ifdef MODULE
---- linux-2.6.0-test1/include/linux/namespace.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/linux/namespace.h	2003-07-19 17:03:51.000000000 -0700
-@@ -2,7 +2,7 @@
- #define _NAMESPACE_H_
- #ifdef __KERNEL__
- 
--#include <linux/dcache.h>
-+#include <linux/mount.h>
- #include <linux/sched.h>
- 
- struct namespace {
-@@ -14,17 +14,12 @@ struct namespace {
- 
- extern void umount_tree(struct vfsmount *);
- extern int copy_namespace(int, struct task_struct *);
-+void __put_namespace(struct namespace *namespace);
- 
- static inline void put_namespace(struct namespace *namespace)
- {
--	if (atomic_dec_and_test(&namespace->count)) {
--		down_write(&namespace->sem);
--		spin_lock(&dcache_lock);
--		umount_tree(namespace->root);
--		spin_unlock(&dcache_lock);
--		up_write(&namespace->sem);
--		kfree(namespace);
--	}
-+	if (atomic_dec_and_test(&namespace->count))
-+		__put_namespace(namespace);
- }
- 
- static inline void exit_namespace(struct task_struct *p)
---- linux-2.6.0-test1/include/linux/netdevice.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/netdevice.h	2003-07-19 17:03:51.000000000 -0700
-@@ -29,6 +29,7 @@
- #include <linux/if_ether.h>
- #include <linux/if_packet.h>
- #include <linux/device.h>
-+#include <linux/percpu.h>
- 
- #include <asm/atomic.h>
- #include <asm/cache.h>
-@@ -544,10 +545,9 @@ struct softnet_data
- 	struct sk_buff		*completion_queue;
- 
- 	struct net_device	backlog_dev;	/* Sorry. 8) */
--} ____cacheline_aligned;
--
-+};
- 
--extern struct softnet_data softnet_data[NR_CPUS];
-+DECLARE_PER_CPU(struct softnet_data,softnet_data);
- 
- #define HAVE_NETIF_QUEUE
- 
-@@ -555,12 +555,12 @@ static inline void __netif_schedule(stru
- {
- 	if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
- 		unsigned long flags;
--		int cpu;
-+		struct softnet_data *sd;
- 
- 		local_irq_save(flags);
--		cpu = smp_processor_id();
--		dev->next_sched = softnet_data[cpu].output_queue;
--		softnet_data[cpu].output_queue = dev;
-+		sd = &__get_cpu_var(softnet_data);
-+		dev->next_sched = sd->output_queue;
-+		sd->output_queue = dev;
- 		raise_softirq_irqoff(NET_TX_SOFTIRQ);
- 		local_irq_restore(flags);
- 	}
-@@ -605,13 +605,13 @@ static inline int netif_running(const st
- static inline void dev_kfree_skb_irq(struct sk_buff *skb)
- {
- 	if (atomic_dec_and_test(&skb->users)) {
--		int cpu;
-+		struct softnet_data *sd;
- 		unsigned long flags;
- 
- 		local_irq_save(flags);
--		cpu = smp_processor_id();
--		skb->next = softnet_data[cpu].completion_queue;
--		softnet_data[cpu].completion_queue = skb;
-+		sd = &__get_cpu_var(softnet_data);
-+		skb->next = sd->completion_queue;
-+		sd->completion_queue = skb;
- 		raise_softirq_irqoff(NET_TX_SOFTIRQ);
- 		local_irq_restore(flags);
- 	}
-@@ -769,12 +769,10 @@ static inline int netif_rx_schedule_prep
- static inline void __netif_rx_schedule(struct net_device *dev)
- {
- 	unsigned long flags;
--	int cpu;
- 
- 	local_irq_save(flags);
--	cpu = smp_processor_id();
- 	dev_hold(dev);
--	list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
-+	list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
- 	if (dev->quota < 0)
- 		dev->quota += dev->weight;
- 	else
-@@ -798,13 +796,11 @@ static inline int netif_rx_reschedule(st
- {
- 	if (netif_rx_schedule_prep(dev)) {
- 		unsigned long flags;
--		int cpu;
- 
- 		dev->quota += undo;
- 
- 		local_irq_save(flags);
--		cpu = smp_processor_id();
--		list_add_tail(&dev->poll_list, &softnet_data[cpu].poll_list);
-+		list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
- 		__raise_softirq_irqoff(NET_RX_SOFTIRQ);
- 		local_irq_restore(flags);
- 		return 1;
---- linux-2.6.0-test1/include/linux/nfs_fs.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/nfs_fs.h	2003-07-19 17:07:05.000000000 -0700
-@@ -172,6 +172,7 @@ struct nfs_inode {
- #define NFS_INO_ADVISE_RDPLUS   0x0002          /* advise readdirplus */
- #define NFS_INO_REVALIDATING	0x0004		/* revalidating attrs */
- #define NFS_INO_FLUSH		0x0008		/* inode is due for flushing */
-+#define NFS_INO_FAKE_ROOT	0x0080		/* root inode placeholder */
- 
- static inline struct nfs_inode *NFS_I(struct inode *inode)
- {
-@@ -207,6 +208,7 @@ do { \
- #define NFS_FLAGS(inode)		(NFS_I(inode)->flags)
- #define NFS_REVALIDATING(inode)		(NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
- #define NFS_STALE(inode)		(NFS_FLAGS(inode) & NFS_INO_STALE)
-+#define NFS_FAKE_ROOT(inode)		(NFS_FLAGS(inode) & NFS_INO_FAKE_ROOT)
- 
- #define NFS_FILEID(inode)		(NFS_I(inode)->fileid)
- 
-@@ -269,7 +271,7 @@ nfs_file_cred(struct file *file)
- /*
-  * linux/fs/nfs/direct.c
-  */
--extern int nfs_direct_IO(int, struct file *, const struct iovec *, loff_t,
-+extern int nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
- 			unsigned long);
- 
- /*
---- linux-2.6.0-test1/include/linux/nfs_fs_sb.h	2003-06-14 12:18:52.000000000 -0700
-+++ 25/include/linux/nfs_fs_sb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -9,6 +9,7 @@
-  */
- struct nfs_server {
- 	struct rpc_clnt *	client;		/* RPC client handle */
-+	struct rpc_clnt *	client_sys;	/* 2nd handle for FSINFO */
- 	struct nfs_rpc_ops *	rpc_ops;	/* NFS protocol vector */
- 	struct backing_dev_info	backing_dev_info;
- 	int			flags;		/* various flags */
---- linux-2.6.0-test1/include/linux/nfs_mount.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/include/linux/nfs_mount.h	2003-07-19 17:03:51.000000000 -0700
-@@ -20,7 +20,7 @@
-  * mount-to-kernel version compatibility.  Some of these aren't used yet
-  * but here they are anyway.
-  */
--#define NFS_MOUNT_VERSION	4
-+#define NFS_MOUNT_VERSION	5
- 
- struct nfs_mount_data {
- 	int		version;		/* 1 */
-@@ -40,7 +40,7 @@ struct nfs_mount_data {
- 	int		namlen;			/* 2 */
- 	unsigned int	bsize;			/* 3 */
- 	struct nfs3_fh	root;			/* 4 */
--	int		pseudoflavor;		/* 4 */
-+	int		pseudoflavor;		/* 5 */
- };
- 
- /* bits in the flags field */
-@@ -57,7 +57,7 @@ struct nfs_mount_data {
- #define NFS_MOUNT_NONLM		0x0200	/* 3 */
- #define NFS_MOUNT_BROKEN_SUID	0x0400	/* 4 */
- #define NFS_MOUNT_STRICTLOCK	0x1000	/* reserved for NFSv4 */
--#define NFS_MOUNT_SECFLAVOUR	0x2000	/* reserved */
-+#define NFS_MOUNT_SECFLAVOUR	0x2000	/* 5 */
- #define NFS_MOUNT_FLAGMASK	0xFFFF
- 
- #endif
---- linux-2.6.0-test1/include/linux/nfs_page.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/nfs_page.h	2003-07-19 17:07:05.000000000 -0700
-@@ -46,7 +46,6 @@ extern	struct nfs_page *nfs_create_reque
- 					    unsigned int, unsigned int);
- extern	void nfs_clear_request(struct nfs_page *req);
- extern	void nfs_release_request(struct nfs_page *req);
--extern	void nfs_release_list(struct list_head *list);
- 
- 
- extern	void nfs_list_add_request(struct nfs_page *, struct list_head *);
-@@ -56,7 +55,6 @@ extern	int nfs_scan_list(struct list_hea
- extern	int nfs_coalesce_requests(struct list_head *, struct list_head *,
- 				  unsigned int);
- extern  int nfs_wait_on_request(struct nfs_page *);
--extern	int nfs_wait_for_reads(struct list_head *);
- 
- extern	spinlock_t nfs_wreq_lock;
- 
---- linux-2.6.0-test1/include/linux/nfs_xdr.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/nfs_xdr.h	2003-07-19 17:07:07.000000000 -0700
-@@ -591,6 +591,7 @@ struct nfs4_compound {
- #endif /* CONFIG_NFS_V4 */
- 
- struct nfs_read_data {
-+	int			flags;
- 	struct rpc_task		task;
- 	struct inode		*inode;
- 	struct rpc_cred		*cred;
-@@ -605,6 +606,7 @@ struct nfs_read_data {
- };
- 
- struct nfs_write_data {
-+	int			flags;
- 	struct rpc_task		task;
- 	struct inode		*inode;
- 	struct rpc_cred		*cred;
-@@ -634,16 +636,9 @@ struct nfs_rpc_ops {
- 			    struct nfs_fh *, struct nfs_fattr *);
- 	int	(*access)  (struct inode *, struct rpc_cred *, int);
- 	int	(*readlink)(struct inode *, struct page *);
--	int	(*read)    (struct inode *, struct rpc_cred *,
--			    struct nfs_fattr *,
--			    int, unsigned int, unsigned int,
--			    struct page *, int *eofp);
--	int	(*write)   (struct inode *, struct rpc_cred *,
--			    struct nfs_fattr *,
--			    int, unsigned int, unsigned int,
--			    struct page *, struct nfs_writeverf *verfp);
--	int	(*commit)  (struct inode *, struct nfs_fattr *,
--			    unsigned long, unsigned int);
-+	int	(*read)    (struct nfs_read_data *);
-+	int	(*write)   (struct nfs_write_data *);
-+	int	(*commit)  (struct nfs_write_data *);
- 	int	(*create)  (struct inode *, struct qstr *, struct iattr *,
- 			    int, struct nfs_fh *, struct nfs_fattr *);
- 	int	(*remove)  (struct inode *, struct qstr *);
---- linux-2.6.0-test1/include/linux/node.h	2003-06-14 12:18:34.000000000 -0700
-+++ 25/include/linux/node.h	2003-07-19 17:04:07.000000000 -0700
-@@ -20,9 +20,10 @@
- #define _LINUX_NODE_H_
- 
- #include <linux/sysdev.h>
-+#include <linux/cpumask.h>
- 
- struct node {
--	unsigned long cpumap;	/* Bitmap of CPUs on the Node */
-+	cpumask_t cpumap;	/* Bitmap of CPUs on the Node */
- 	struct sys_device	sysdev;
- };
- 
---- linux-2.6.0-test1/include/linux/pagemap.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/pagemap.h	2003-07-19 17:07:00.000000000 -0700
-@@ -130,17 +130,27 @@ static inline void ___add_to_page_cache(
- extern void FASTCALL(__lock_page(struct page *page));
- extern void FASTCALL(unlock_page(struct page *page));
- 
--static inline void lock_page(struct page *page)
-+
-+extern int FASTCALL(__lock_page_wq(struct page *page, wait_queue_t *wait));
-+static inline int lock_page_wq(struct page *page, wait_queue_t *wait)
- {
- 	if (TestSetPageLocked(page))
--		__lock_page(page);
-+		return __lock_page_wq(page, wait);
-+	else
-+		return 0;
-+}
-+
-+static inline void lock_page(struct page *page)
-+{
-+	lock_page_wq(page, NULL);
- }
- 	
- /*
-  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
-  * Never use this directly!
-  */
--extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr));
-+extern int FASTCALL(wait_on_page_bit_wq(struct page *page, int bit_nr,
-+	wait_queue_t *wait));
- 
- /* 
-  * Wait for a page to be unlocked.
-@@ -149,19 +159,33 @@ extern void FASTCALL(wait_on_page_bit(st
-  * ie with increased "page->count" so that the page won't
-  * go away during the wait..
-  */
--static inline void wait_on_page_locked(struct page *page)
-+static inline int wait_on_page_locked_wq(struct page *page, wait_queue_t *wait)
- {
- 	if (PageLocked(page))
--		wait_on_page_bit(page, PG_locked);
-+		return wait_on_page_bit_wq(page, PG_locked, wait);
-+	return 0;
-+}
-+
-+static inline void wait_on_page_locked(struct page *page)
-+{
-+	wait_on_page_locked_wq(page, NULL);
- }
- 
- /* 
-  * Wait for a page to complete writeback
-  */
--static inline void wait_on_page_writeback(struct page *page)
-+
-+static inline int wait_on_page_writeback_wq(struct page *page,
-+						wait_queue_t *wait)
- {
- 	if (PageWriteback(page))
--		wait_on_page_bit(page, PG_writeback);
-+		return wait_on_page_bit_wq(page, PG_writeback, wait);
-+	return 0;
-+}
-+
-+static inline void wait_on_page_writeback(struct page *page)
-+{
-+	wait_on_page_writeback_wq(page, NULL);
- }
- 
- extern void end_page_writeback(struct page *page);
---- linux-2.6.0-test1/include/linux/pci.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/pci.h	2003-07-19 17:03:51.000000000 -0700
-@@ -715,7 +715,6 @@ static inline int pci_dac_set_dma_mask(s
- static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
- static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
- static inline void pci_unregister_driver(struct pci_driver *drv) { }
--static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
- static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
- static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
- 
---- linux-2.6.0-test1/include/linux/raid/md_k.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/raid/md_k.h	2003-07-19 17:06:39.000000000 -0700
-@@ -64,11 +64,7 @@ static inline int level_to_pers (int lev
- typedef struct mddev_s mddev_t;
- typedef struct mdk_rdev_s mdk_rdev_t;
- 
--#if (MINORBITS != 8)
--#error MD does not handle bigger kdev yet
--#endif
--
--#define MAX_MD_DEVS  (1<<MINORBITS)	/* Max number of md dev */
-+#define MAX_MD_DEVS  256	/* Max number of md dev */
- 
- /*
-  * options passed in raidrun:
---- linux-2.6.0-test1/include/linux/rcupdate.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/rcupdate.h	2003-07-19 17:04:56.000000000 -0700
-@@ -40,6 +40,7 @@
- #include <linux/spinlock.h>
- #include <linux/threads.h>
- #include <linux/percpu.h>
-+#include <linux/cpumask.h>
- 
- /**
-  * struct rcu_head - callback structure for use with RCU
-@@ -67,7 +68,7 @@ struct rcu_ctrlblk {
- 	spinlock_t	mutex;		/* Guard this struct                  */
- 	long		curbatch;	/* Current batch number.	      */
- 	long		maxbatch;	/* Max requested batch number.        */
--	unsigned long	rcu_cpu_mask; 	/* CPUs that need to switch in order  */
-+	cpumask_t	rcu_cpu_mask; 	/* CPUs that need to switch in order  */
- 					/* for current batch to proceed.      */
- };
- 
-@@ -95,6 +96,8 @@ struct rcu_data {
-         long  	       	batch;           /* Batch # for current RCU batch */
-         struct list_head  nxtlist;
-         struct list_head  curlist;
-+ 	long		nr_rcureqs;
-+ 	long		nr_rcupdates;
- };
- 
- DECLARE_PER_CPU(struct rcu_data, rcu_data);
-@@ -105,6 +108,8 @@ extern struct rcu_ctrlblk rcu_ctrlblk;
- #define RCU_batch(cpu) 		(per_cpu(rcu_data, (cpu)).batch)
- #define RCU_nxtlist(cpu) 	(per_cpu(rcu_data, (cpu)).nxtlist)
- #define RCU_curlist(cpu) 	(per_cpu(rcu_data, (cpu)).curlist)
-+#define RCU_nr_rcureqs(cpu) 	(per_cpu(rcu_data, (cpu)).nr_rcureqs)
-+#define RCU_nr_rcupdates(cpu) 	(per_cpu(rcu_data, (cpu)).nr_rcupdates)
- 
- #define RCU_QSCTR_INVALID	0
- 
-@@ -114,7 +119,7 @@ static inline int rcu_pending(int cpu) 
- 	     rcu_batch_before(RCU_batch(cpu), rcu_ctrlblk.curbatch)) ||
- 	    (list_empty(&RCU_curlist(cpu)) &&
- 			 !list_empty(&RCU_nxtlist(cpu))) ||
--	    test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask))
-+	    cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask))
- 		return 1;
- 	else
- 		return 0;
---- linux-2.6.0-test1/include/linux/root_dev.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/root_dev.h	2003-07-19 17:06:39.000000000 -0700
-@@ -1,18 +1,16 @@
- #ifndef _ROOT_DEV_H_
- #define _ROOT_DEV_H_
- 
--enum {
--	Root_NFS = MKDEV(UNNAMED_MAJOR, 255),
--	Root_RAM0 = MKDEV(RAMDISK_MAJOR, 0),
--	Root_RAM1 = MKDEV(RAMDISK_MAJOR, 1),
--	Root_FD0 = MKDEV(FLOPPY_MAJOR, 0),
--	Root_HDA1 = MKDEV(IDE0_MAJOR, 1),
--	Root_HDA2 = MKDEV(IDE0_MAJOR, 2),
--	Root_SDA1 = MKDEV(SCSI_DISK0_MAJOR, 1),
--	Root_SDA2 = MKDEV(SCSI_DISK0_MAJOR, 2),
--	Root_HDC1 = MKDEV(IDE1_MAJOR, 1),
--	Root_SR0 = MKDEV(SCSI_CDROM_MAJOR, 0),
--};
-+#define	Root_NFS	MKDEV(UNNAMED_MAJOR, 255)
-+#define	Root_RAM0	MKDEV(RAMDISK_MAJOR, 0)
-+#define	Root_RAM1	MKDEV(RAMDISK_MAJOR, 1)
-+#define	Root_FD0	MKDEV(FLOPPY_MAJOR, 0)
-+#define	Root_HDA1	MKDEV(IDE0_MAJOR, 1)
-+#define	Root_HDA2	MKDEV(IDE0_MAJOR, 2)
-+#define	Root_SDA1	MKDEV(SCSI_DISK0_MAJOR, 1)
-+#define	Root_SDA2	MKDEV(SCSI_DISK0_MAJOR, 2)
-+#define	Root_HDC1	MKDEV(IDE1_MAJOR, 1)
-+#define	Root_SR0	MKDEV(SCSI_CDROM_MAJOR, 0)
- 
- extern dev_t ROOT_DEV;
- 
---- linux-2.6.0-test1/include/linux/sched.h	2003-07-10 18:50:32.000000000 -0700
-+++ 25/include/linux/sched.h	2003-07-19 17:07:10.000000000 -0700
-@@ -12,6 +12,7 @@
- #include <linux/jiffies.h>
- #include <linux/rbtree.h>
- #include <linux/thread_info.h>
-+#include <linux/cpumask.h>
- 
- #include <asm/system.h>
- #include <asm/semaphore.h>
-@@ -52,6 +53,7 @@ struct exec_domain;
- #define CLONE_DETACHED		0x00400000	/* parent wants no child-exit signal */
- #define CLONE_UNTRACED		0x00800000	/* set if the tracing process can't force CLONE_PTRACE on this clone */
- #define CLONE_CHILD_SETTID	0x01000000	/* set the TID in the child */
-+#define CLONE_STOPPED		0x02000000	/* Start in stopped state */
- 
- /*
-  * List of flags we want to share for kernel threads,
-@@ -149,6 +151,7 @@ extern void init_idle(task_t *idle, int 
- 
- extern void show_state(void);
- extern void show_regs(struct pt_regs *);
-+extern void show_trace_task(task_t *tsk);
- 
- /*
-  * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
-@@ -202,7 +205,7 @@ struct mm_struct {
- 	unsigned long arg_start, arg_end, env_start, env_end;
- 	unsigned long rss, total_vm, locked_vm;
- 	unsigned long def_flags;
--	unsigned long cpu_vm_mask;
-+	cpumask_t cpu_vm_mask;
- 	unsigned long swap_address;
- 
- 	unsigned dumpable:1;
-@@ -338,10 +341,11 @@ struct task_struct {
- 	prio_array_t *array;
- 
- 	unsigned long sleep_avg;
-+	unsigned long avg_start;
- 	unsigned long last_run;
- 
- 	unsigned long policy;
--	unsigned long cpus_allowed;
-+	cpumask_t cpus_allowed;
- 	unsigned int time_slice, first_time_slice;
- 
- 	struct list_head tasks;
-@@ -456,12 +460,24 @@ struct task_struct {
- 
- 	unsigned long ptrace_message;
- 	siginfo_t *last_siginfo; /* For ptrace use.  */
-+	long debug;
-+/*
-+ * current io wait handle: wait queue entry to use for io waits
-+ * If this thread is processing aio, this points at the waitqueue
-+ * inside the currently handled kiocb. It may be NULL (i.e. default
-+ * to a stack based synchronous wait) if its doing sync IO.
-+ */
-+	wait_queue_t *io_wait;
- };
- 
- extern void __put_task_struct(struct task_struct *tsk);
- #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
--#define put_task_struct(tsk) \
--do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
-+#define put_task_struct(tsk)					\
-+	do {							\
-+		BUG_ON((tsk)->debug == 0x6b6b6b6b);		\
-+		if (atomic_dec_and_test(&(tsk)->usage))		\
-+			__put_task_struct(tsk);			\
-+	} while (0)
- 
- /*
-  * Per process flags
-@@ -488,9 +504,9 @@ do { if (atomic_dec_and_test(&(tsk)->usa
- #define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
- 
- #ifdef CONFIG_SMP
--extern int set_cpus_allowed(task_t *p, unsigned long new_mask);
-+extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
- #else
--static inline int set_cpus_allowed(task_t *p, unsigned long new_mask)
-+static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
- {
- 	return 0;
- }
-@@ -636,6 +652,8 @@ static inline void mmdrop(struct mm_stru
- 
- /* mmput gets rid of the mappings and all user-space */
- extern void mmput(struct mm_struct *);
-+/* Grab a reference to the mm if its not already going away */
-+extern struct mm_struct *mmgrab(struct mm_struct *);
- /* Remove the current tasks stale references to the old mm_struct */
- extern void mm_release(struct task_struct *, struct mm_struct *);
- 
-@@ -743,7 +761,7 @@ static inline struct mm_struct * get_tas
- 	task_lock(task);
- 	mm = task->mm;
- 	if (mm)
--		atomic_inc(&mm->mm_users);
-+		mm = mmgrab(mm);
- 	task_unlock(task);
- 
- 	return mm;
---- linux-2.6.0-test1/include/linux/serial_core.h	2003-06-14 12:17:58.000000000 -0700
-+++ 25/include/linux/serial_core.h	2003-07-19 17:03:51.000000000 -0700
-@@ -57,7 +57,7 @@
- #define PORT_SUNSAB	39
- 
- /* NEC v850.  */
--#define PORT_NB85E_UART	40
-+#define PORT_V850E_UART	40
- 
- /* NEC PC-9800 */
- #define PORT_8251_PC98	41
---- linux-2.6.0-test1/include/linux/smp.h	2003-06-14 12:18:22.000000000 -0700
-+++ 25/include/linux/smp.h	2003-07-19 17:04:07.000000000 -0700
-@@ -102,9 +102,6 @@ void smp_prepare_boot_cpu(void);
- #define smp_call_function(func,info,retry,wait)	({ 0; })
- #define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
- static inline void smp_send_reschedule(int cpu) { }
--#define cpu_online_map				1
--#define cpu_online(cpu)				({ BUG_ON((cpu) != 0); 1; })
--#define num_online_cpus()			1
- #define num_booting_cpus()			1
- #define cpu_possible(cpu)			({ BUG_ON((cpu) != 0); 1; })
- #define smp_prepare_boot_cpu()			do {} while (0)
---- linux-2.6.0-test1/include/linux/spinlock.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/linux/spinlock.h	2003-07-19 17:06:40.000000000 -0700
-@@ -184,6 +184,17 @@ typedef struct {
- 
- #endif /* !SMP */
- 
-+#ifdef CONFIG_LOCKMETER
-+extern void _metered_spin_lock   (spinlock_t *lock);
-+extern void _metered_spin_unlock (spinlock_t *lock);
-+extern int  _metered_spin_trylock(spinlock_t *lock);
-+extern void _metered_read_lock    (rwlock_t *lock);
-+extern void _metered_read_unlock  (rwlock_t *lock);
-+extern void _metered_write_lock   (rwlock_t *lock);
-+extern void _metered_write_unlock (rwlock_t *lock);
-+extern int  _metered_write_trylock(rwlock_t *lock);
-+#endif
-+
- /*
-  * Define the various spin_lock and rw_lock methods.  Note we define these
-  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
-@@ -389,6 +400,141 @@ do { \
- 				_raw_spin_trylock(lock) ? 1 : \
- 				({preempt_enable(); local_bh_enable(); 0;});})
- 
-+#ifdef CONFIG_LOCKMETER
-+#undef spin_lock
-+#undef spin_trylock
-+#undef spin_unlock
-+#undef spin_lock_irqsave
-+#undef spin_lock_irq
-+#undef spin_lock_bh
-+#undef read_lock
-+#undef read_unlock
-+#undef write_lock
-+#undef write_unlock
-+#undef write_trylock
-+#undef spin_unlock_bh
-+#undef read_lock_irqsave
-+#undef read_lock_irq
-+#undef read_lock_bh
-+#undef read_unlock_bh
-+#undef write_lock_irqsave
-+#undef write_lock_irq
-+#undef write_lock_bh
-+#undef write_unlock_bh
-+
-+#define spin_lock(lock) \
-+do { \
-+	preempt_disable(); \
-+	_metered_spin_lock(lock); \
-+} while(0)
-+
-+#define spin_trylock(lock)     ({preempt_disable(); _metered_spin_trylock(lock) ? \
-+				1 : ({preempt_enable(); 0;});})
-+#define spin_unlock(lock) \
-+do { \
-+	_metered_spin_unlock(lock); \
-+	preempt_enable(); \
-+} while (0)
-+
-+#define spin_lock_irqsave(lock, flags) \
-+do { \
-+	local_irq_save(flags); \
-+	preempt_disable(); \
-+	_metered_spin_lock(lock); \
-+} while (0)
-+
-+#define spin_lock_irq(lock) \
-+do { \
-+	local_irq_disable(); \
-+	preempt_disable(); \
-+	_metered_spin_lock(lock); \
-+} while (0)
-+
-+#define spin_lock_bh(lock) \
-+do { \
-+	local_bh_disable(); \
-+	preempt_disable(); \
-+	_metered_spin_lock(lock); \
-+} while (0)
-+
-+#define spin_unlock_bh(lock) \
-+do { \
-+	_metered_spin_unlock(lock); \
-+	preempt_enable(); \
-+	local_bh_enable(); \
-+} while (0)
-+
-+
-+#define read_lock(lock)                ({preempt_disable(); _metered_read_lock(lock);})
-+#define read_unlock(lock)      ({_metered_read_unlock(lock); preempt_enable();})
-+#define write_lock(lock)       ({preempt_disable(); _metered_write_lock(lock);})
-+#define write_unlock(lock)     ({_metered_write_unlock(lock); preempt_enable();})
-+#define write_trylock(lock)    ({preempt_disable();_metered_write_trylock(lock) ? \
-+				1 : ({preempt_enable(); 0;});})
-+#define spin_unlock_no_resched(lock) \
-+do { \
-+	_metered_spin_unlock(lock); \
-+	preempt_enable_no_resched(); \
-+} while (0)
-+
-+#define read_lock_irqsave(lock, flags) \
-+do { \
-+	local_irq_save(flags); \
-+	preempt_disable(); \
-+	_metered_read_lock(lock); \
-+} while (0)
-+
-+#define read_lock_irq(lock) \
-+do { \
-+	local_irq_disable(); \
-+	preempt_disable(); \
-+	_metered_read_lock(lock); \
-+} while (0)
-+
-+#define read_lock_bh(lock) \
-+do { \
-+	local_bh_disable(); \
-+	preempt_disable(); \
-+	_metered_read_lock(lock); \
-+} while (0)
-+
-+#define read_unlock_bh(lock) \
-+do { \
-+	_metered_read_unlock(lock); \
-+	preempt_enable(); \
-+	local_bh_enable(); \
-+} while (0)
-+
-+#define write_lock_irqsave(lock, flags) \
-+do { \
-+	local_irq_save(flags); \
-+	preempt_disable(); \
-+	_metered_write_lock(lock); \
-+} while (0)
-+
-+#define write_lock_irq(lock) \
-+do { \
-+	local_irq_disable(); \
-+	preempt_disable(); \
-+	_metered_write_lock(lock); \
-+} while (0)
-+
-+#define write_lock_bh(lock) \
-+do { \
-+	local_bh_disable(); \
-+	preempt_disable(); \
-+	_metered_write_lock(lock); \
-+} while (0)
-+
-+#define write_unlock_bh(lock) \
-+do { \
-+	_metered_write_unlock(lock); \
-+	preempt_enable(); \
-+	local_bh_enable(); \
-+} while (0)
-+
-+#endif /* !CONFIG_LOCKMETER */
-+
- /* "lock on reference count zero" */
- #ifndef ATOMIC_DEC_AND_LOCK
- #include <asm/atomic.h>
---- linux-2.6.0-test1/include/linux/times.h	2003-06-14 12:17:57.000000000 -0700
-+++ 25/include/linux/times.h	2003-07-19 17:03:51.000000000 -0700
-@@ -11,6 +11,26 @@
- # define jiffies_to_clock_t(x) ((clock_t) jiffies_64_to_clock_t((u64) x))
- #endif
- 
-+static inline unsigned long clock_t_to_jiffies(unsigned long x)
-+{
-+#if (HZ % USER_HZ)==0
-+	if (x >= ~0UL / (HZ / USER_HZ))
-+		return ~0UL;
-+	return x * (HZ / USER_HZ);
-+#else
-+	u64 jif;
-+
-+	/* Don't worry about loss of precision here .. */
-+	if (x >= ~0UL / HZ * USER_HZ)
-+		return ~0UL;
-+
-+	/* .. but do try to contain it here */
-+	jif = x * (u64) HZ;
-+	do_div(jif, USER_HZ);
-+	return jif;
-+#endif
-+}
-+
- static inline u64 jiffies_64_to_clock_t(u64 x)
- {
- #if (HZ % USER_HZ)==0
---- linux-2.6.0-test1/include/linux/topology.h	2003-06-14 12:18:25.000000000 -0700
-+++ 25/include/linux/topology.h	2003-07-19 17:04:07.000000000 -0700
-@@ -27,6 +27,7 @@
- #ifndef _LINUX_TOPOLOGY_H
- #define _LINUX_TOPOLOGY_H
- 
-+#include <linux/cpumask.h>
- #include <linux/bitops.h>
- #include <linux/mmzone.h>
- #include <linux/smp.h>
-@@ -34,7 +35,12 @@
- #include <asm/topology.h>
- 
- #ifndef nr_cpus_node
--#define nr_cpus_node(node)	(hweight_long(node_to_cpumask(node)))
-+#define nr_cpus_node(node)							\
-+	({									\
-+		cpumask_t __tmp__;						\
-+		__tmp__ = node_to_cpumask(node);				\
-+		cpus_weight(__tmp__);						\
-+	})
- #endif
- 
- static inline int __next_node_with_cpus(int node)
---- linux-2.6.0-test1/include/linux/tty.h	2003-06-14 12:18:21.000000000 -0700
-+++ 25/include/linux/tty.h	2003-07-19 17:03:51.000000000 -0700
-@@ -57,40 +57,40 @@
-  */
- 
- struct screen_info {
--	unsigned char  orig_x;			/* 0x00 */
--	unsigned char  orig_y;			/* 0x01 */
--	unsigned short dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
--	unsigned short orig_video_page;		/* 0x04 */
--	unsigned char  orig_video_mode;		/* 0x06 */
--	unsigned char  orig_video_cols;		/* 0x07 */
--	unsigned short unused2;			/* 0x08 */
--	unsigned short orig_video_ega_bx;	/* 0x0a */
--	unsigned short unused3;			/* 0x0c */
--	unsigned char  orig_video_lines;	/* 0x0e */
--	unsigned char  orig_video_isVGA;	/* 0x0f */
--	unsigned short orig_video_points;	/* 0x10 */
-+	u8  orig_x;		/* 0x00 */
-+	u8  orig_y;		/* 0x01 */
-+	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
-+	u16 orig_video_page;	/* 0x04 */
-+	u8  orig_video_mode;	/* 0x06 */
-+	u8  orig_video_cols;	/* 0x07 */
-+	u16 unused2;		/* 0x08 */
-+	u16 orig_video_ega_bx;	/* 0x0a */
-+	u16 unused3;		/* 0x0c */
-+	u8  orig_video_lines;	/* 0x0e */
-+	u8  orig_video_isVGA;	/* 0x0f */
-+	u16 orig_video_points;	/* 0x10 */
- 
- 	/* VESA graphic mode -- linear frame buffer */
--	unsigned short lfb_width;		/* 0x12 */
--	unsigned short lfb_height;		/* 0x14 */
--	unsigned short lfb_depth;		/* 0x16 */
--	unsigned long  lfb_base;		/* 0x18 */
--	unsigned long  lfb_size;		/* 0x1c */
--	unsigned short dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
--	unsigned short lfb_linelength;		/* 0x24 */
--	unsigned char  red_size;		/* 0x26 */
--	unsigned char  red_pos;			/* 0x27 */
--	unsigned char  green_size;		/* 0x28 */
--	unsigned char  green_pos;		/* 0x29 */
--	unsigned char  blue_size;		/* 0x2a */
--	unsigned char  blue_pos;		/* 0x2b */
--	unsigned char  rsvd_size;		/* 0x2c */
--	unsigned char  rsvd_pos;		/* 0x2d */
--	unsigned short vesapm_seg;		/* 0x2e */
--	unsigned short vesapm_off;		/* 0x30 */
--	unsigned short pages;			/* 0x32 */
--	unsigned short vesa_attributes;		/* 0x34 */
--						/* 0x36 -- 0x3f reserved for future expansion */
-+	u16 lfb_width;		/* 0x12 */
-+	u16 lfb_height;		/* 0x14 */
-+	u16 lfb_depth;		/* 0x16 */
-+	u32 lfb_base;		/* 0x18 */
-+	u32 lfb_size;		/* 0x1c */
-+	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
-+	u16 lfb_linelength;	/* 0x24 */
-+	u8  red_size;		/* 0x26 */
-+	u8  red_pos;		/* 0x27 */
-+	u8  green_size;		/* 0x28 */
-+	u8  green_pos;		/* 0x29 */
-+	u8  blue_size;		/* 0x2a */
-+	u8  blue_pos;		/* 0x2b */
-+	u8  rsvd_size;		/* 0x2c */
-+	u8  rsvd_pos;		/* 0x2d */
-+	u16 vesapm_seg;		/* 0x2e */
-+	u16 vesapm_off;		/* 0x30 */
-+	u16 pages;		/* 0x32 */
-+	u16 vesa_attributes;	/* 0x34 */
-+				/* 0x36 -- 0x3f reserved for future expansion */
- };
- 
- extern struct screen_info screen_info;
---- linux-2.6.0-test1/include/linux/usb.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/linux/usb.h	2003-07-19 17:03:51.000000000 -0700
-@@ -80,7 +80,8 @@ struct usb_host_interface {
-  * @act_altsetting: index of current altsetting.  this number is always
-  *	less than num_altsetting.  after the device is configured, each
-  *	interface uses its default setting of zero.
-- * @max_altsetting:
-+ * @max_altsetting: the max number of altsettings for this interface.
-+ * @driver: the USB driver that is bound to this interface.
-  * @minor: the minor number assigned to this interface, if this
-  *	interface is bound to a driver that uses the USB major number.
-  *	If this interface does not use the USB major, this field should
-@@ -409,7 +410,11 @@ static inline int usb_make_path (struct 
-  *	do (or don't) show up otherwise in the filesystem.
-  * @id_table: USB drivers use ID table to support hotplugging.
-  *	Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
-- *	or your driver's probe function will never get called. 
-+ *	or your driver's probe function will never get called.
-+ * @driver: the driver model core driver structure.
-+ * @serialize: a semaphore used to serialize access to this driver.  Used
-+ * 	in the probe and disconnect functions.  Only the USB core should use
-+ * 	this lock.
-  *
-  * USB drivers must provide a name, probe() and disconnect() methods,
-  * and an id_table.  Other driver fields are optional.
-@@ -575,6 +580,8 @@ typedef void (*usb_complete_t)(struct ur
-  *	it likes with the URB, including resubmitting or freeing it.
-  * @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to 
-  *	collect the transfer status for each buffer.
-+ * @timeout: If set to zero, the urb will never timeout.  Otherwise this is
-+ *	the time in jiffies that this urb will timeout in.
-  *
-  * This structure identifies USB transfer requests.  URBs must be allocated by
-  * calling usb_alloc_urb() and freed with a call to usb_free_urb().
-@@ -677,10 +684,14 @@ typedef void (*usb_complete_t)(struct ur
-  */
- struct urb
- {
-+	/* private, usb core and host controller only fields in the urb */
- 	spinlock_t lock;		/* lock for the URB */
- 	atomic_t count;			/* reference count of the URB */
- 	void *hcpriv;			/* private data for host controller */
- 	struct list_head urb_list;	/* list pointer to all active urbs */
-+	int bandwidth;			/* bandwidth for INT/ISO request */
-+
-+	/* public, documented fields in the urb that can be used by drivers */
- 	struct usb_device *dev; 	/* (in) pointer to associated device */
- 	unsigned int pipe;		/* (in) pipe information */
- 	int status;			/* (return) non-ISO status */
-@@ -689,7 +700,6 @@ struct urb
- 	dma_addr_t transfer_dma;	/* (in) dma addr for transfer_buffer */
- 	int transfer_buffer_length;	/* (in) data buffer length */
- 	int actual_length;		/* (return) actual transfer length */
--	int bandwidth;			/* bandwidth for INT/ISO request */
- 	unsigned char *setup_packet;	/* (in) setup packet (control only) */
- 	dma_addr_t setup_dma;		/* (in) dma addr for setup_packet */
- 	int start_frame;		/* (modify) start frame (INT/ISO) */
-@@ -891,8 +901,10 @@ struct usb_sg_request {
- 	int			status;
- 	size_t			bytes;
- 
--	// members not documented above are private to usbcore,
--	// and are not provided for driver access!
-+	/* 
-+	 * members below are private to usbcore,
-+	 * and are not provided for driver access!
-+	 */
- 	spinlock_t		lock;
- 
- 	struct usb_device	*dev;
---- linux-2.6.0-test1/include/linux/wait.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/wait.h	2003-07-19 17:06:43.000000000 -0700
-@@ -80,6 +80,15 @@ static inline int waitqueue_active(wait_
- 	return !list_empty(&q->task_list);
- }
- 
-+/*
-+ * Used to distinguish between sync and async io wait context:
-+ * sync i/o typically specifies a NULL wait queue entry or a wait
-+ * queue entry bound to a task (current task) to wake up.
-+ * aio specifies a wait queue entry with an async notification
-+ * callback routine, not associated with any task.
-+ */
-+#define is_sync_wait(wait)	(!(wait) || ((wait)->task))
-+
- extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
- extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
- extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
---- linux-2.6.0-test1/include/linux/writeback.h	2003-06-26 22:07:26.000000000 -0700
-+++ 25/include/linux/writeback.h	2003-07-19 17:06:57.000000000 -0700
-@@ -84,10 +84,12 @@ int dirty_writeback_centisecs_handler(st
- 					  void *, size_t *);
- 
- void page_writeback_init(void);
--void balance_dirty_pages(struct address_space *mapping);
--void balance_dirty_pages_ratelimited(struct address_space *mapping);
-+int balance_dirty_pages(struct address_space *mapping);
-+int balance_dirty_pages_ratelimited(struct address_space *mapping);
- int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
- int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
-+ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
-+			loff_t pos, size_t count);
- 
- /* pdflush.c */
- extern int nr_pdflush_threads;	/* Global so it can be exported to sysctl
---- linux-2.6.0-test1/include/media/saa7146.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/media/saa7146.h	2003-07-19 17:03:51.000000000 -0700
-@@ -89,8 +89,6 @@ struct saa7146_extension
- #define SAA7146_USE_I2C_IRQ	0x1
- 	int	flags;
- 	
--	struct saa7146_ext_vv	*ext_vv_data;
--	
- 	/* pairs of subvendor and subdevice ids for
- 	   supported devices, last entry 0xffff, 0xfff */
- 	struct module *module;
-@@ -134,6 +132,7 @@ struct saa7146_dev
- 	/* extension handling */
- 	struct saa7146_extension	*ext;		/* indicates if handled by extension */
- 	void				*ext_priv;	/* pointer for extension private use (most likely some private data) */
-+	struct saa7146_ext_vv		*ext_vv_data;
- 
- 	/* per device video/vbi informations (if available) */
- 	struct saa7146_vv	*vv_data;
---- linux-2.6.0-test1/include/media/saa7146_vv.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/media/saa7146_vv.h	2003-07-19 17:03:51.000000000 -0700
-@@ -10,12 +10,10 @@
- #define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
- 
- #define WRITE_RPS0(x) do { \
--	static int count = 0;	\
- 	dev->d_rps0.cpu_addr[ count++ ] = cpu_to_le32(x); \
- 	} while (0);
- 
- #define WRITE_RPS1(x) do { \
--	static int count = 0;	\
- 	dev->d_rps1.cpu_addr[ count++ ] = cpu_to_le32(x); \
- 	} while (0);
- 
-@@ -41,13 +39,13 @@ struct saa7146_standard
- 	char          *name;
- 	v4l2_std_id   id;
- 
--	int v_offset;
--	int v_field;
--	int v_calc;
-+	int v_offset;	/* number of lines of vertical offset before processing */
-+	int v_field;	/* number of lines in a field for HPS to process */
-+	int v_calc;	/* number of vertical active lines */
- 	
--	int h_offset;
--	int h_pixels;
--	int h_calc;
-+	int h_offset;	/* horizontal offset of processing window */
-+	int h_pixels;	/* number of horizontal pixels to process */
-+	int h_calc;	/* number of horizontal active pixels */
- 	
- 	int v_max_out;
- 	int h_max_out;
-@@ -122,6 +120,7 @@ struct saa7146_vv
- 	/* video capture */
- 	struct saa7146_dmaqueue		video_q;
- 	struct saa7146_fh		*streaming;
-+	enum v4l2_field			last_field;
- 
- 	/* common: fixme? shouldn't this be in saa7146_fh?
- 	   (this leads to a more complicated question: shall the driver
-@@ -166,7 +165,7 @@ struct saa7146_ext_vv
- 	int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
- 		
- 	struct saa7146_extension_ioctls *ioctls;
--	int (*ioctl)(struct saa7146_dev*, unsigned int cmd, void *arg);
-+	int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg);
- };
- 
- struct saa7146_use_ops  {
-@@ -188,7 +187,7 @@ int saa7146_buffer_queue(struct saa7146_
- void saa7146_buffer_timeout(unsigned long data);
- void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf);
- 
--int saa7146_vv_init(struct saa7146_dev* dev);
-+int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv);
- int saa7146_vv_release(struct saa7146_dev* dev);
- 
- 
-@@ -201,6 +200,8 @@ void saa7146_set_gpio(struct saa7146_dev
- 
- /* from saa7146_video.c */
- extern struct saa7146_use_ops saa7146_video_uops;
-+int saa7146_start_preview(struct saa7146_fh *fh);
-+int saa7146_stop_preview(struct saa7146_fh *fh);
- 
- /* from saa7146_vbi.c */
- extern struct saa7146_use_ops saa7146_vbi_uops;
-@@ -215,35 +216,6 @@ extern struct saa7146_use_ops saa7146_vb
- #define SAA7146_HPS_SYNC_PORT_A		0x00
- #define SAA7146_HPS_SYNC_PORT_B		0x01
- 
--/* number of vertical active lines */
--#define V_ACTIVE_LINES_PAL	576
--#define V_ACTIVE_LINES_NTSC	480
--#define V_ACTIVE_LINES_SECAM	576
--
--/* number of lines in a field for HPS to process */
--#define V_FIELD_PAL	288
--#define V_FIELD_NTSC	240
--#define V_FIELD_SECAM	288
--
--/* number of lines of vertical offset before processing */
--#define V_OFFSET_PAL	0x17
--#define V_OFFSET_NTSC	0x16
--#define V_OFFSET_SECAM	0x14
--
--/* number of horizontal pixels to process */
--#define H_PIXELS_PAL	680
--#define H_PIXELS_NTSC	708
--#define H_PIXELS_SECAM	720
--
--/* horizontal offset of processing window */
--#define H_OFFSET_PAL	0x14
--#define H_OFFSET_NTSC	0x06
--#define H_OFFSET_SECAM	0x14
--
--#define SAA7146_PAL_VALUES 	V_OFFSET_PAL, V_FIELD_PAL, V_ACTIVE_LINES_PAL, H_OFFSET_PAL, H_PIXELS_PAL, H_PIXELS_PAL+1, V_ACTIVE_LINES_PAL, 768
--#define SAA7146_NTSC_VALUES	V_OFFSET_NTSC, V_FIELD_NTSC, V_ACTIVE_LINES_NTSC, H_OFFSET_NTSC, H_PIXELS_NTSC, H_PIXELS_NTSC+1, V_ACTIVE_LINES_NTSC, 640
--#define SAA7146_SECAM_VALUES	V_OFFSET_SECAM, V_FIELD_SECAM, V_ACTIVE_LINES_SECAM, H_OFFSET_SECAM, H_PIXELS_SECAM, H_PIXELS_SECAM+1, V_ACTIVE_LINES_SECAM, 768
--
- /* some memory sizes */
- #define SAA7146_CLIPPING_MEM	(14*PAGE_SIZE)
- 
---- linux-2.6.0-test1/include/net/ip_vs.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/net/ip_vs.h	2003-07-19 17:03:51.000000000 -0700
-@@ -887,7 +887,6 @@ extern int sysctl_ip_vs_cache_bypass;
- extern int sysctl_ip_vs_expire_nodest_conn;
- extern int sysctl_ip_vs_sync_threshold[2];
- extern int sysctl_ip_vs_nat_icmp_send;
--extern atomic_t ip_vs_dropentry;
- extern struct ip_vs_stats ip_vs_stats;
- 
- extern struct ip_vs_service *
-@@ -902,7 +901,6 @@ extern struct ip_vs_dest *
- ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
- extern int ip_vs_use_count_inc(void);
- extern void ip_vs_use_count_dec(void);
--extern void update_defense_level(void);
- extern int ip_vs_control_init(void);
- extern void ip_vs_control_cleanup(void);
- 
---- linux-2.6.0-test1/include/pcmcia/ss.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/include/pcmcia/ss.h	2003-07-19 17:03:51.000000000 -0700
-@@ -51,6 +51,7 @@
- #define SS_3VCARD	0x1000
- #define SS_XVCARD	0x2000
- #define SS_PENDING	0x4000
-+#define SS_ZVCARD	0x8000
- 
- /* InquireSocket capabilities */
- #define SS_CAP_PAGE_REGS	0x0001
-@@ -209,6 +210,10 @@ struct pcmcia_socket {
- 	/* socket operations */
- 	struct pccard_operations *	ops;
- 
-+	/* Zoom video behaviour is so chip specific its not worth adding
-+	   this to _ops */
-+	void 				(*zoom_video)(struct pcmcia_socket *, int);
-+                           
- 	/* state thread */
- 	struct semaphore		skt_sem;	/* protects socket h/w state */
- 
---- linux-2.6.0-test1/include/scsi/scsi_device.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/scsi/scsi_device.h	2003-07-19 17:03:51.000000000 -0700
-@@ -11,8 +11,6 @@ struct scsi_mode_data;
- 
- 
- struct scsi_device {
--	struct class_device	sdev_classdev;
--
- 	struct list_head    siblings;   /* list of all devices on this host */
- 	struct list_head    same_target_siblings; /* just the devices sharing same target id */
- 	struct Scsi_Host *host;
-@@ -86,10 +84,11 @@ struct scsi_device {
- 	unsigned int max_device_blocked; /* what device_blocked counts down from  */
- #define SCSI_DEFAULT_DEVICE_BLOCKED	3
- 
--	struct device sdev_driverfs_dev;
-+	struct device		sdev_gendev;
-+	struct class_device	sdev_classdev;
- };
- #define	to_scsi_device(d)	\
--	container_of(d, struct scsi_device, sdev_driverfs_dev)
-+	container_of(d, struct scsi_device, sdev_gendev)
- 
- extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
- 		uint, uint, uint);
---- linux-2.6.0-test1/include/scsi/scsi_host.h	2003-06-22 12:04:45.000000000 -0700
-+++ 25/include/scsi/scsi_host.h	2003-07-19 17:03:51.000000000 -0700
-@@ -329,12 +329,12 @@ struct scsi_host_template {
- #define SCSI_DEFAULT_HOST_BLOCKED	7
- 
- 	/*
--	 * Pointer to the sysfs class properties for this host
-+	 * Pointer to the sysfs class properties for this host, NULL terminated.
- 	 */
- 	struct class_device_attribute **shost_attrs;
- 
- 	/*
--	 * Pointer to the SCSI device properties for this host
-+	 * Pointer to the SCSI device properties for this host, NULL terminated.
- 	 */
- 	struct device_attribute **sdev_attrs;
- 
-@@ -442,12 +442,6 @@ struct Scsi_Host {
- 	 */
- 	unsigned int max_host_blocked;
- 
--	/* 
--	 * Support for sysfs
--	 */
--	struct device host_gendev;
--	struct class_device class_dev;
--
- 	/* legacy crap */
- 	unsigned long base;
- 	unsigned long io_port;
-@@ -455,6 +449,9 @@ struct Scsi_Host {
- 	unsigned char dma_channel;
- 	unsigned int  irq;
- 
-+	/* ldm bits */
-+	struct device		shost_gendev;
-+	struct class_device	shost_classdev;
- 
- 	/*
- 	 * List of hosts per template.
-@@ -474,12 +471,13 @@ struct Scsi_Host {
- 		__attribute__ ((aligned (sizeof(unsigned long))));
- };
- #define		dev_to_shost(d)		\
--	container_of(d, struct Scsi_Host, host_gendev)
-+	container_of(d, struct Scsi_Host, shost_gendev)
- #define		class_to_shost(d)	\
--	container_of(d, struct Scsi_Host, class_dev)
-+	container_of(d, struct Scsi_Host, shost_classdev)
- 
- extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
- extern int scsi_add_host(struct Scsi_Host *, struct device *);
-+extern void scsi_scan_host(struct Scsi_Host *);
- extern int scsi_remove_host(struct Scsi_Host *);
- extern void scsi_host_get(struct Scsi_Host *);
- extern void scsi_host_put(struct Scsi_Host *t);
-@@ -495,16 +493,14 @@ static inline void scsi_assign_lock(stru
- static inline void scsi_set_device(struct Scsi_Host *shost,
-                                    struct device *dev)
- {
--        shost->host_gendev.parent = dev;
-+        shost->shost_gendev.parent = dev;
- }
- 
- static inline struct device *scsi_get_device(struct Scsi_Host *shost)
- {
--        return shost->host_gendev.parent;
-+        return shost->shost_gendev.parent;
- }
- 
--extern void scsi_sysfs_release_attributes(struct scsi_host_template *);
--
- extern void scsi_unblock_requests(struct Scsi_Host *);
- extern void scsi_block_requests(struct Scsi_Host *);
- 
---- linux-2.6.0-test1/include/scsi/scsi_request.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/include/scsi/scsi_request.h	2003-07-19 17:03:51.000000000 -0700
-@@ -56,7 +56,7 @@ extern void scsi_do_req(struct scsi_requ
- 			int timeout, int retries);
- 
- struct scsi_mode_data {
--	__u16	length;
-+	__u32	length;
- 	__u16	block_descriptor_length;
- 	__u8	medium_type;
- 	__u8	device_specific;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/include/video/epson1355.h	2003-07-19 17:04:55.000000000 -0700
-@@ -0,0 +1,64 @@
-+/*
-+ * include/video/epson13xx.h -- Epson 13xx frame buffer
-+ *
-+ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
-+ *
-+ * Written by Christopher Hoover <ch@hpl.hp.com>
-+ *
-+ */
-+
-+#ifndef _EPSON13XX_H_
-+#define _EPSON13XX_H_
-+
-+#define REG_REVISION_CODE              0x00
-+#define REG_MEMORY_CONFIG              0x01
-+#define REG_PANEL_TYPE                 0x02
-+#define REG_MOD_RATE                   0x03
-+#define REG_HORZ_DISP_WIDTH            0x04
-+#define REG_HORZ_NONDISP_PERIOD        0x05
-+#define REG_HRTC_START_POSITION        0x06
-+#define REG_HRTC_PULSE_WIDTH           0x07
-+#define REG_VERT_DISP_HEIGHT0          0x08
-+#define REG_VERT_DISP_HEIGHT1          0x09
-+#define REG_VERT_NONDISP_PERIOD        0x0A
-+#define REG_VRTC_START_POSITION        0x0B
-+#define REG_VRTC_PULSE_WIDTH           0x0C
-+#define REG_DISPLAY_MODE               0x0D
-+#define REG_SCRN1_LINE_COMPARE0        0x0E
-+#define REG_SCRN1_LINE_COMPARE1        0x0F
-+#define REG_SCRN1_DISP_START_ADDR0     0x10
-+#define REG_SCRN1_DISP_START_ADDR1     0x11
-+#define REG_SCRN1_DISP_START_ADDR2     0x12
-+#define REG_SCRN2_DISP_START_ADDR0     0x13
-+#define REG_SCRN2_DISP_START_ADDR1     0x14
-+#define REG_SCRN2_DISP_START_ADDR2     0x15
-+#define REG_MEM_ADDR_OFFSET0           0x16
-+#define REG_MEM_ADDR_OFFSET1           0x17
-+#define REG_PIXEL_PANNING              0x18
-+#define REG_CLOCK_CONFIG               0x19
-+#define REG_POWER_SAVE_CONFIG          0x1A
-+#define REG_MISC                       0x1B
-+#define REG_MD_CONFIG_READBACK0        0x1C
-+#define REG_MD_CONFIG_READBACK1        0x1D
-+#define REG_GPIO_CONFIG0               0x1E
-+#define REG_GPIO_CONFIG1               0x1F
-+#define REG_GPIO_CONTROL0              0x20
-+#define REG_GPIO_CONTROL1              0x21
-+#define REG_PERF_ENHANCEMENT0          0x22
-+#define REG_PERF_ENHANCEMENT1          0x23
-+#define REG_LUT_ADDR                   0x24
-+#define REG_RESERVED_1                 0x25
-+#define REG_LUT_DATA                   0x26
-+#define REG_INK_CURSOR_CONTROL         0x27
-+#define REG_CURSOR_X_POSITION0         0x28
-+#define REG_CURSOR_X_POSITION1         0x29
-+#define REG_CURSOR_Y_POSITION0         0x2A
-+#define REG_CURSOR_Y_POSITION1         0x2B
-+#define REG_INK_CURSOR_COLOR0_0        0x2C
-+#define REG_INK_CURSOR_COLOR0_1        0x2D
-+#define REG_INK_CURSOR_COLOR1_0        0x2E
-+#define REG_INK_CURSOR_COLOR1_1        0x2F
-+#define REG_INK_CURSOR_START_ADDR      0x30
-+#define REG_ALTERNATE_FRM              0x31
-+
-+#endif
---- linux-2.6.0-test1/include/video/neomagic.h	2003-06-14 12:18:07.000000000 -0700
-+++ 25/include/video/neomagic.h	2003-07-19 17:04:55.000000000 -0700
-@@ -75,45 +75,45 @@
- 
- 
- struct xtimings {
--  unsigned int pixclock;
--  unsigned int HDisplay;
--  unsigned int HSyncStart;
--  unsigned int HSyncEnd;
--  unsigned int HTotal;
--  unsigned int VDisplay;
--  unsigned int VSyncStart;
--  unsigned int VSyncEnd;
--  unsigned int VTotal;
--  unsigned int sync;
--  int	       dblscan;
--  int	       interlaced;
-+	unsigned int pixclock;
-+	unsigned int HDisplay;
-+	unsigned int HSyncStart;
-+	unsigned int HSyncEnd;
-+	unsigned int HTotal;
-+	unsigned int VDisplay;
-+	unsigned int VSyncStart;
-+	unsigned int VSyncEnd;
-+	unsigned int VTotal;
-+	unsigned int sync;
-+	int dblscan;
-+	int interlaced;
- };
- 
- 
- /* --------------------------------------------------------------------- */
- 
- typedef volatile struct {
--  __u32 bltStat;
--  __u32 bltCntl;
--  __u32 xpColor;
--  __u32 fgColor;
--  __u32 bgColor;
--  __u32 pitch;
--  __u32 clipLT;
--  __u32 clipRB;
--  __u32 srcBitOffset;
--  __u32 srcStart;
--  __u32 reserved0;
--  __u32 dstStart;
--  __u32 xyExt;
--
--  __u32 reserved1[19];
--
--  __u32 pageCntl;
--  __u32 pageBase;
--  __u32 postBase;
--  __u32 postPtr;
--  __u32 dataPtr;
-+	__u32 bltStat;
-+	__u32 bltCntl;
-+	__u32 xpColor;
-+	__u32 fgColor;
-+	__u32 bgColor;
-+	__u32 pitch;
-+	__u32 clipLT;
-+	__u32 clipRB;
-+	__u32 srcBitOffset;
-+	__u32 srcStart;
-+	__u32 reserved0;
-+	__u32 dstStart;
-+	__u32 xyExt;
-+
-+	__u32 reserved1[19];
-+
-+	__u32 pageCntl;
-+	__u32 pageBase;
-+	__u32 postBase;
-+	__u32 postPtr;
-+	__u32 dataPtr;
- } Neo2200;
- 
- #define NR_PALETTE	256
-@@ -124,142 +124,65 @@ typedef volatile struct {
- #define NEO_EXT_GR_MAX 0xC7
- 
- struct neofb_par {
--  
--  unsigned char MiscOutReg;     /* Misc */
--  unsigned char CRTC[25];       /* Crtc Controller */
--  unsigned char Sequencer[5];   /* Video Sequencer */
--  unsigned char Graphics[9];    /* Video Graphics */
--  unsigned char Attribute[21];  /* Video Atribute */
--
--  unsigned char GeneralLockReg;
--  unsigned char ExtCRTDispAddr;
--  unsigned char ExtCRTOffset;
--  unsigned char SysIfaceCntl1;
--  unsigned char SysIfaceCntl2;
--  unsigned char ExtColorModeSelect;
--  unsigned char biosMode;
--
--  unsigned char PanelDispCntlReg1;
--  unsigned char PanelDispCntlReg2;
--  unsigned char PanelDispCntlReg3;
--  unsigned char PanelVertCenterReg1;
--  unsigned char PanelVertCenterReg2;
--  unsigned char PanelVertCenterReg3;
--  unsigned char PanelVertCenterReg4;
--  unsigned char PanelVertCenterReg5;
--  unsigned char PanelHorizCenterReg1;
--  unsigned char PanelHorizCenterReg2;
--  unsigned char PanelHorizCenterReg3;
--  unsigned char PanelHorizCenterReg4;
--  unsigned char PanelHorizCenterReg5;
--
--  int           ProgramVCLK;
--  unsigned char VCLK3NumeratorLow;
--  unsigned char VCLK3NumeratorHigh;
--  unsigned char VCLK3Denominator;
--  unsigned char VerticalExt;
-+	struct vgastate state;
-+	unsigned char MiscOutReg;	/* Misc */
-+	unsigned char CRTC[25];		/* Crtc Controller */
-+	unsigned char Sequencer[5];	/* Video Sequencer */
-+	unsigned char Graphics[9];	/* Video Graphics */
-+	unsigned char Attribute[21];	/* Video Atribute */
-+
-+	unsigned char GeneralLockReg;
-+	unsigned char ExtCRTDispAddr;
-+	unsigned char ExtCRTOffset;
-+	unsigned char SysIfaceCntl1;
-+	unsigned char SysIfaceCntl2;
-+	unsigned char ExtColorModeSelect;
-+	unsigned char biosMode;
-+
-+	unsigned char PanelDispCntlReg1;
-+	unsigned char PanelDispCntlReg2;
-+	unsigned char PanelDispCntlReg3;
-+	unsigned char PanelVertCenterReg1;
-+	unsigned char PanelVertCenterReg2;
-+	unsigned char PanelVertCenterReg3;
-+	unsigned char PanelVertCenterReg4;
-+	unsigned char PanelVertCenterReg5;
-+	unsigned char PanelHorizCenterReg1;
-+	unsigned char PanelHorizCenterReg2;
-+	unsigned char PanelHorizCenterReg3;
-+	unsigned char PanelHorizCenterReg4;
-+	unsigned char PanelHorizCenterReg5;
-+
-+	int ProgramVCLK;
-+	unsigned char VCLK3NumeratorLow;
-+	unsigned char VCLK3NumeratorHigh;
-+	unsigned char VCLK3Denominator;
-+	unsigned char VerticalExt;
- 
- #ifdef CONFIG_MTRR
--  int    mtrr;
-+	int mtrr;
- #endif
--  u8    *mmio_vbase;
-+	u8 *mmio_vbase;
- 
--  Neo2200 *neo2200;
-+	Neo2200 *neo2200;
- 
--  /* Panels size */
--  int NeoPanelWidth;
--  int NeoPanelHeight;
-+	/* Panels size */
-+	int NeoPanelWidth;
-+	int NeoPanelHeight;
- 
--  int maxClock;
-+	int maxClock;
- 
--  int pci_burst;
--  int lcd_stretch;
--  int internal_display;
--  int external_display;
--  int libretto;
-+	int pci_burst;
-+	int lcd_stretch;
-+	int internal_display;
-+	int external_display;
-+	int libretto;
- };
- 
- typedef struct {
--    int x_res;
--    int y_res;
--    int mode;
-+	int x_res;
-+	int y_res;
-+	int mode;
- } biosMode;
- 
--/* vga IO functions */
--static inline u8 VGArCR (u8 index)
--{
--  outb (index, 0x3d4);
--  return inb (0x3d5);
--}
--
--static inline void VGAwCR (u8 index, u8 val)
--{
--  outb (index, 0x3d4);
--  outb (val, 0x3d5);
--}
--
--static inline u8 VGArGR (u8 index)
--{
--  outb (index, 0x3ce);
--  return inb (0x3cf);
--}
--
--static inline void VGAwGR (u8 index, u8 val)
--{
--  outb (index, 0x3ce);
--  outb (val, 0x3cf);
--}
--
--static inline u8 VGArSEQ (u8 index)
--{
--  outb (index, 0x3c4);
--  return inb (0x3c5);
--}
--
--static inline void VGAwSEQ (u8 index, u8 val)
--{
--  outb (index, 0x3c4);
--  outb (val, 0x3c5);
--}
--
--
--static int paletteEnabled = 0;
--
--static inline void VGAenablePalette (void)
--{
--  u8 tmp;
--
--  tmp = inb (0x3da);
--  outb (0x00, 0x3c0);
--  paletteEnabled = 1;
--}
--
--static inline void VGAdisablePalette (void)
--{
--  u8 tmp;
--
--  tmp = inb (0x3da);
--  outb (0x20, 0x3c0);
--  paletteEnabled = 0;
--}
--
--static inline void VGAwATTR (u8 index, u8 value)
--{
--  u8 tmp;
--
--  if (paletteEnabled)
--    index &= ~0x20;
--  else
--    index |= 0x20;
--
--  tmp = inb (0x3da);
--  outb (index, 0x3c0);
--  outb (value, 0x3c0);
--}
--
--static inline void VGAwMISC (u8 value)
--{
--  outb (value, 0x3c2);
--}
- #endif
--
---- linux-2.6.0-test1/include/video/sisfb.h	2003-06-14 12:18:08.000000000 -0700
-+++ 25/include/video/sisfb.h	2003-07-19 17:04:55.000000000 -0700
-@@ -6,6 +6,53 @@
- #include <asm/ioctl.h>
- #include <asm/types.h>
- 
-+/* TW: vbflags */
-+#define CRT2_DEFAULT            0x00000001
-+#define CRT2_LCD                0x00000002  /* TW: Never change the order of the CRT2_XXX entries */
-+#define CRT2_TV                 0x00000004  /*     (see SISCycleCRT2Type())                       */
-+#define CRT2_VGA                0x00000008
-+#define CRT2_ENABLE		(CRT2_LCD | CRT2_TV | CRT2_VGA)
-+#define VB_DISPTYPE_DISP2	CRT2_ENABLE
-+#define VB_DISPTYPE_CRT2	CRT2_ENABLE
-+#define TV_NTSC                 0x00000010
-+#define TV_PAL                  0x00000020
-+#define TV_HIVISION             0x00000040
-+#define TV_HIVISION_LV          0x00000080
-+#define TV_TYPE                 (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV)
-+#define TV_AVIDEO               0x00000100
-+#define TV_SVIDEO               0x00000200
-+#define TV_SCART                0x00000400
-+#define TV_INTERFACE            (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV)
-+#define VB_USELCDA		0x00000800
-+#define TV_PALM                 0x00001000
-+#define TV_PALN                 0x00002000
-+#define TV_CHSCART              0x00008000
-+#define TV_CHHDTV               0x00010000
-+#define VGA2_CONNECTED          0x00040000
-+#define VB_DISPTYPE_CRT1	0x00080000  	/* CRT1 connected and used */
-+#define VBDISPTYPE_DISP1	VB_DISPTYPE_CRT1
-+#define VB_301                  0x00100000	/* Video bridge type */
-+#define VB_301B                 0x00200000
-+#define VB_302B                 0x00400000
-+#define VB_30xBDH		0x00800000      /* 30xB DH version (w/o LCD support) */
-+#define VB_LVDS                 0x01000000
-+#define VB_CHRONTEL             0x02000000
-+#define VB_301LV                0x04000000  	
-+#define VB_302LV                0x08000000  	
-+#define VB_TRUMPION		0x10000000     
-+#define VB_VIDEOBRIDGE		(VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV| \
-+				 VB_LVDS|VB_CHRONTEL|VB_TRUMPION)
-+#define VB_SISBRIDGE            (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV)
-+#define VB_SINGLE_MODE          0x20000000   	 /* CRT1 or CRT2; determined by VB_DISPTYPE_CRTx */
-+#define VB_DISPMODE_SINGLE	VB_SINGLE_MODE 	 
-+#define VB_MIRROR_MODE		0x40000000   	 /* CRT1 + CRT2 identical (mirror mode) */
-+#define VB_DISPMODE_MIRROR	VB_MIRROR_MODE   
-+#define VB_DUALVIEW_MODE	0x80000000   	 /* CRT1 + CRT2 independent (dual head mode) */
-+#define VB_DISPMODE_DUAL	VB_DUALVIEW_MODE 
-+#define VB_DISPLAY_MODE         (VB_SINGLE_MODE | VB_MIRROR_MODE | VB_DUALVIEW_MODE) 
-+
-+
-+/* entries for disp_state - deprecated as of 1.6.02 */
- #define DISPTYPE_CRT1       0x00000008L
- #define DISPTYPE_CRT2       0x00000004L
- #define DISPTYPE_LCD        0x00000002L
-@@ -16,6 +63,7 @@
- #define DISPMODE_MIRROR	    0x00000010L
- #define DISPMODE_DUALVIEW   0x00000040L
- 
-+/* Deprecated as of 1.6.02 - use vbflags instead */
- #define HASVB_NONE      	0x00
- #define HASVB_301       	0x01
- #define HASVB_LVDS      	0x02
-@@ -39,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
- 	SIS_650,
- 	SIS_740,
- 	SIS_330,
-+	SIS_660,
- 	MAX_SIS_CHIP
- } SIS_CHIP_TYPE;
- 
-@@ -83,13 +132,15 @@ struct ap_data {
- 	struct mode_info minfo;
- 	unsigned long iobase;
- 	unsigned int  mem_size;
--	unsigned long disp_state;    	
-+	unsigned long disp_state;  /* deprecated */  	
- 	SIS_CHIP_TYPE chip;
- 	unsigned char hasVB;
--	SIS_TV_TYPE TV_type;
--	SIS_TV_PLUG TV_plug;
-+	SIS_TV_TYPE TV_type;	   /* deprecated */
-+	SIS_TV_PLUG TV_plug;	   /* deprecated */
- 	unsigned long version;
--	char reserved[256];
-+	unsigned long vbflags;	   /* replaces deprecated entries above */
-+	unsigned long currentvbflags;
-+	char reserved[248];
- };
- 
- struct video_info {
-@@ -114,10 +165,10 @@ struct video_info {
- 	int    video_linelength;
- 	unsigned int refresh_rate;
- 
--	unsigned long disp_state;
--	unsigned char hasVB;
--	unsigned char TV_type;
--	unsigned char TV_plug;
-+	unsigned long disp_state;		/* DEPRECATED */
-+	unsigned char hasVB;			/* DEPRECATED */
-+	unsigned char TV_type;			/* DEPRECATED */
-+	unsigned char TV_plug;			/* DEPRECATED */
- 
- 	SIS_CHIP_TYPE chip;
- 	unsigned char revision_id;
-@@ -136,8 +187,19 @@ struct video_info {
- 
- 	unsigned short subsysvendor;
- 	unsigned short subsysdevice;
-+	
-+	unsigned long  vbflags;			/* Replacing deprecated stuff from above */
-+	unsigned long  currentvbflags;
-+	
-+	int    current_bpp;
-+	int    current_width;
-+	int    current_height;
-+	int    current_htotal;
-+	int    current_vtotal;
-+	__u32  current_pixclock;
-+	int    current_refresh_rate;
- 
--	char reserved[236];
-+	char reserved[200];
- };
- 
- 
-@@ -177,8 +239,11 @@ struct _SISFB_INFO {
- 	unsigned char sisfb_lcdpdc;	/* PanelDelayCompensation */
- 	
- 	unsigned char sisfb_lcda;	/* Detected status of LCDA for low res/text modes */
-+	
-+	unsigned long sisfb_vbflags;
-+	unsigned long sisfb_currentvbflags;
- 
--	char reserved[235]; 		/* for future use */
-+	char reserved[227]; 		/* for future use */
- };
- 
- #ifdef __KERNEL__
---- linux-2.6.0-test1/init/do_mounts.h	2003-06-14 12:18:24.000000000 -0700
-+++ 25/init/do_mounts.h	2003-07-19 17:03:51.000000000 -0700
-@@ -6,7 +6,7 @@
- #include <linux/unistd.h>
- #include <linux/slab.h>
- #include <linux/mount.h>
--#include <linux/blk.h>
-+#include <linux/major.h>
- #include <linux/root_dev.h>
- 
- asmlinkage long sys_unlink(const char *name);
---- linux-2.6.0-test1/init/do_mounts_initrd.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/init/do_mounts_initrd.c	2003-07-19 17:03:51.000000000 -0700
-@@ -5,6 +5,7 @@
- #include <linux/ext2_fs.h>
- #include <linux/romfs_fs.h>
- #include <linux/initrd.h>
-+#include <linux/sched.h>
- 
- #include "do_mounts.h"
- 
---- linux-2.6.0-test1/init/do_mounts_rd.c	2003-06-14 12:18:28.000000000 -0700
-+++ 25/init/do_mounts_rd.c	2003-07-19 17:03:51.000000000 -0700
-@@ -5,6 +5,7 @@
- #include <linux/ext2_fs.h>
- #include <linux/romfs_fs.h>
- #include <linux/initrd.h>
-+#include <linux/string.h>
- 
- #include "do_mounts.h"
- 
---- linux-2.6.0-test1/init/main.c	2003-06-26 22:07:26.000000000 -0700
-+++ 25/init/main.c	2003-07-19 17:03:51.000000000 -0700
-@@ -23,7 +23,6 @@
- #include <linux/ioport.h>
- #include <linux/init.h>
- #include <linux/smp_lock.h>
--#include <linux/blk.h>
- #include <linux/initrd.h>
- #include <linux/hdreg.h>
- #include <linux/bootmem.h>
---- linux-2.6.0-test1/kernel/compat.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/kernel/compat.c	2003-07-19 17:03:51.000000000 -0700
-@@ -425,9 +425,11 @@ asmlinkage int compat_sys_sched_getaffin
- 				    &kernel_mask);
- 	set_fs(old_fs);
- 
--	if (ret > 0)
-+	if (ret > 0) {
-+		ret = sizeof(compat_ulong_t);
- 		if (put_user(kernel_mask, user_mask_ptr))
- 			return -EFAULT;
-+	}
- 
- 	return ret;
- }
---- linux-2.6.0-test1/kernel/extable.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/kernel/extable.c	2003-07-19 17:03:51.000000000 -0700
-@@ -17,10 +17,10 @@
- */
- #include <linux/module.h>
- #include <asm/uaccess.h>
-+#include <asm/sections.h>
- 
- extern const struct exception_table_entry __start___ex_table[];
- extern const struct exception_table_entry __stop___ex_table[];
--extern char _stext[], _etext[], _sinittext[], _einittext[];
- 
- /* Given an address, look for it in the exception tables. */
- const struct exception_table_entry *search_exception_tables(unsigned long addr)
---- linux-2.6.0-test1/kernel/fork.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/kernel/fork.c	2003-07-19 17:06:43.000000000 -0700
-@@ -53,13 +53,6 @@ DEFINE_PER_CPU(unsigned long, process_co
- 
- rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;  /* outer */
- 
--/*
-- * A per-CPU task cache - this relies on the fact that
-- * the very last portion of sys_exit() is executed with
-- * preemption turned off.
-- */
--static task_t *task_cache[NR_CPUS] __cacheline_aligned;
--
- int nr_processes(void)
- {
- 	int cpu;
-@@ -80,26 +73,8 @@ static kmem_cache_t *task_struct_cachep;
- 
- static void free_task(struct task_struct *tsk)
- {
--	/*
--	 * The task cache is effectively disabled right now.
--	 * Do we want it? The slab cache already has per-cpu
--	 * stuff, but the thread info (usually a order-1 page
--	 * allocation) doesn't.
--	 */
--	if (tsk != current) {
--		free_thread_info(tsk->thread_info);
--		free_task_struct(tsk);
--	} else {
--		int cpu = get_cpu();
--
--		tsk = task_cache[cpu];
--		if (tsk) {
--			free_thread_info(tsk->thread_info);
--			free_task_struct(tsk);
--		}
--		task_cache[cpu] = current;
--		put_cpu();
--	}
-+	free_thread_info(tsk->thread_info);
-+	free_task_struct(tsk);
- }
- 
- void __put_task_struct(struct task_struct *tsk)
-@@ -146,7 +121,12 @@ void prepare_to_wait(wait_queue_head_t *
- {
- 	unsigned long flags;
- 
--	__set_current_state(state);
-+	/*
-+	 * don't alter the task state if this is just going to
-+	 * queue an async wait queue callback
-+	 */
-+	if (is_sync_wait(wait))
-+		__set_current_state(state);
- 	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
- 	spin_lock_irqsave(&q->lock, flags);
- 	if (list_empty(&wait->task_list))
-@@ -159,7 +139,12 @@ prepare_to_wait_exclusive(wait_queue_hea
- {
- 	unsigned long flags;
- 
--	__set_current_state(state);
-+	/*
-+	 * don't alter the task state if this is just going to
-+	 * queue an async wait queue callback
-+	 */
-+	if (is_sync_wait(wait))
-+		__set_current_state(state);
- 	wait->flags |= WQ_FLAG_EXCLUSIVE;
- 	spin_lock_irqsave(&q->lock, flags);
- 	if (list_empty(&wait->task_list))
-@@ -220,25 +205,18 @@ static struct task_struct *dup_task_stru
- {
- 	struct task_struct *tsk;
- 	struct thread_info *ti;
--	int cpu = get_cpu();
- 
- 	prepare_to_copy(orig);
- 
--	tsk = task_cache[cpu];
--	task_cache[cpu] = NULL;
--	put_cpu();
--	if (!tsk) {
--		tsk = alloc_task_struct();
--		if (!tsk)
--			return NULL;
--
--		ti = alloc_thread_info(tsk);
--		if (!ti) {
--			free_task_struct(tsk);
--			return NULL;
--		}
--	} else
--		ti = tsk->thread_info;
-+	tsk = alloc_task_struct();
-+	if (!tsk)
-+		return NULL;
-+
-+	ti = alloc_thread_info(tsk);
-+	if (!ti) {
-+		free_task_struct(tsk);
-+		return NULL;
-+	}
- 
- 	*ti = *orig->thread_info;
- 	*tsk = *orig;
-@@ -265,7 +243,7 @@ static inline int dup_mmap(struct mm_str
- 	mm->free_area_cache = TASK_UNMAPPED_BASE;
- 	mm->map_count = 0;
- 	mm->rss = 0;
--	mm->cpu_vm_mask = 0;
-+	cpus_clear(mm->cpu_vm_mask);
- 	pprev = &mm->mmap;
- 
- 	/*
-@@ -430,6 +408,23 @@ void mmput(struct mm_struct *mm)
- 	}
- }
- 
-+/*
-+ * Checks if the use count of an mm is non-zero and if so
-+ * returns a reference to it after bumping up the use count.
-+ * If the use count is zero, it means this mm is going away,
-+ * so return NULL.
-+ */
-+struct mm_struct *mmgrab(struct mm_struct *mm)
-+{
-+	spin_lock(&mmlist_lock);
-+	if (!atomic_read(&mm->mm_users))
-+		mm = NULL;
-+	else
-+		atomic_inc(&mm->mm_users);
-+	spin_unlock(&mmlist_lock);
-+	return mm;
-+}
-+
- /* Please note the differences between mmput and mm_release.
-  * mmput is called whenever we stop holding onto a mm_struct,
-  * error success whatever.
-@@ -791,8 +786,10 @@ struct task_struct *copy_process(unsigne
- 		goto fork_out;
- 
- 	retval = -EAGAIN;
--	if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) {
--		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
-+	if (atomic_read(&p->user->processes) >=
-+			p->rlim[RLIMIT_NPROC].rlim_cur) {
-+		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-+				p->user != &root_user)
- 			goto bad_fork_free;
- 	}
- 
-@@ -866,6 +863,7 @@ struct task_struct *copy_process(unsigne
- 	p->start_time = get_jiffies_64();
- 	p->security = NULL;
- 	p->io_context = NULL;
-+	p->io_wait = NULL;
- 
- 	retval = -ENOMEM;
- 	if ((retval = security_task_alloc(p)))
-@@ -1106,7 +1104,7 @@ long do_fork(unsigned long clone_flags,
- 			init_completion(&vfork);
- 		}
- 
--		if (p->ptrace & PT_PTRACED) {
-+		if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {
- 			/*
- 			 * We'll start up with an immediate SIGSTOP.
- 			 */
-@@ -1114,7 +1112,9 @@ long do_fork(unsigned long clone_flags,
- 			set_tsk_thread_flag(p, TIF_SIGPENDING);
- 		}
- 
--		wake_up_forked_process(p);		/* do this last */
-+		p->state = TASK_STOPPED;
-+		if (!(clone_flags & CLONE_STOPPED))
-+			wake_up_forked_process(p);	/* do this last */
- 		++total_forks;
- 
- 		if (unlikely (trace)) {
---- linux-2.6.0-test1/kernel/ksyms.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/kernel/ksyms.c	2003-07-19 17:06:51.000000000 -0700
-@@ -120,12 +120,14 @@ EXPORT_SYMBOL(mem_map);
- EXPORT_SYMBOL(max_mapnr);
- #endif
- EXPORT_SYMBOL(high_memory);
-+EXPORT_SYMBOL_GPL(invalidate_mmap_range);
- EXPORT_SYMBOL(vmtruncate);
- EXPORT_SYMBOL(find_vma);
- EXPORT_SYMBOL(get_unmapped_area);
- EXPORT_SYMBOL(init_mm);
- EXPORT_SYMBOL(blk_queue_bounce);
- EXPORT_SYMBOL(blk_congestion_wait);
-+EXPORT_SYMBOL(blk_congestion_wait_wq);
- #ifdef CONFIG_HIGHMEM
- EXPORT_SYMBOL(kmap_high);
- EXPORT_SYMBOL(kunmap_high);
-@@ -219,6 +221,7 @@ EXPORT_SYMBOL(sync_dirty_buffer);
- EXPORT_SYMBOL(submit_bh);
- EXPORT_SYMBOL(unlock_buffer);
- EXPORT_SYMBOL(__wait_on_buffer);
-+EXPORT_SYMBOL(__wait_on_buffer_wq);
- EXPORT_SYMBOL(blockdev_direct_IO);
- EXPORT_SYMBOL(block_write_full_page);
- EXPORT_SYMBOL(block_read_full_page);
-@@ -605,6 +608,19 @@ EXPORT_SYMBOL(next_thread);
- EXPORT_SYMBOL(__per_cpu_offset);
- #endif
- 
-+EXPORT_SYMBOL(set_fs_pwd);
-+EXPORT_SYMBOL(set_fs_root);
-+
-+#if defined(CONFIG_LOCKMETER)
-+EXPORT_SYMBOL(_metered_spin_lock);
-+EXPORT_SYMBOL(_metered_spin_unlock);
-+EXPORT_SYMBOL(_metered_spin_trylock);
-+EXPORT_SYMBOL(_metered_read_lock);
-+EXPORT_SYMBOL(_metered_read_unlock);
-+EXPORT_SYMBOL(_metered_write_lock);
-+EXPORT_SYMBOL(_metered_write_unlock);
-+#endif
-+
- /* debug */
- EXPORT_SYMBOL(dump_stack);
- EXPORT_SYMBOL(ptrace_notify);
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/kernel/lockmeter.c	2003-07-19 17:06:40.000000000 -0700
-@@ -0,0 +1,1169 @@
-+/*
-+ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
-+ *
-+ *  Written by John Hawkes (hawkes@sgi.com)
-+ *  Based on klstat.c by Jack Steiner (steiner@sgi.com)
-+ *
-+ *  Modified by Ray Bryant (raybry@us.ibm.com)
-+ *  Changes Copyright (C) 2000 IBM, Inc.
-+ *  Added save of index in spinlock_t to improve efficiency
-+ *  of "hold" time reporting for spinlocks
-+ *  Added support for hold time statistics for read and write
-+ *  locks.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/smp.h>
-+#include <linux/threads.h>
-+#include <linux/version.h>
-+#include <linux/vmalloc.h>
-+#include <linux/spinlock.h>
-+#include <linux/utsname.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <linux/lockmeter.h>
-+
-+#define ASSERT(cond)
-+#define bzero(loc,size)		memset(loc,0,size)
-+
-+/*<---------------------------------------------------*/
-+/*              lockmeter.c                           */
-+/*>---------------------------------------------------*/
-+
-+static lstat_control_t lstat_control __cacheline_aligned =
-+	{ LSTAT_OFF, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED,
-+	  19 * 0, NR_CPUS * 0, 0, NR_CPUS * 0 };
-+
-+static ushort lstat_make_dir_entry(void *, void *);
-+
-+/*
-+ * lstat_lookup
-+ *
-+ * Given a RA, locate the directory entry for the lock.
-+ */
-+static ushort
-+lstat_lookup(void *lock_ptr, void *caller_ra)
-+{
-+	ushort index;
-+	lstat_directory_entry_t *dirp;
-+
-+	dirp = lstat_control.dir;
-+
-+	index = lstat_control.hashtab[DIRHASH(caller_ra)];
-+	while (dirp[index].caller_ra != caller_ra) {
-+		if (index == 0) {
-+			return lstat_make_dir_entry(lock_ptr, caller_ra);
-+		}
-+		index = dirp[index].next_stat_index;
-+	}
-+
-+	if (dirp[index].lock_ptr != NULL && dirp[index].lock_ptr != lock_ptr) {
-+		dirp[index].lock_ptr = NULL;
-+	}
-+
-+	return index;
-+}
-+
-+/*
-+ * lstat_make_dir_entry
-+ * Called to add a new lock to the lock directory.
-+ */
-+static ushort
-+lstat_make_dir_entry(void *lock_ptr, void *caller_ra)
-+{
-+	lstat_directory_entry_t *dirp;
-+	ushort index, hindex;
-+	unsigned long flags;
-+
-+	/* lock the table without recursively reentering this metering code */
-+	local_irq_save(flags);
-+	_raw_spin_lock(&lstat_control.directory_lock);
-+
-+	hindex = DIRHASH(caller_ra);
-+	index = lstat_control.hashtab[hindex];
-+	dirp = lstat_control.dir;
-+	while (index && dirp[index].caller_ra != caller_ra)
-+		index = dirp[index].next_stat_index;
-+
-+	if (index == 0) {
-+		if (lstat_control.next_free_dir_index < LSTAT_MAX_STAT_INDEX) {
-+			index = lstat_control.next_free_dir_index++;
-+			lstat_control.dir[index].caller_ra = caller_ra;
-+			lstat_control.dir[index].lock_ptr = lock_ptr;
-+			lstat_control.dir[index].next_stat_index =
-+				lstat_control.hashtab[hindex];
-+			lstat_control.hashtab[hindex] = index;
-+		} else {
-+			lstat_control.dir_overflow++;
-+		}
-+	}
-+	_raw_spin_unlock(&lstat_control.directory_lock);
-+	local_irq_restore(flags);
-+	return index;
-+}
-+
-+int
-+lstat_update(void *lock_ptr, void *caller_ra, int action)
-+{
-+	int index;
-+	int cpu;
-+
-+	ASSERT(action < LSTAT_ACT_MAX_VALUES);
-+
-+	if (lstat_control.state == LSTAT_OFF)
-+		return 0;
-+
-+	index = lstat_lookup(lock_ptr, caller_ra);
-+	cpu = THIS_CPU_NUMBER;
-+	(*lstat_control.counts[cpu])[index].count[action]++;
-+	(*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
-+
-+	return index;
-+}
-+
-+int
-+lstat_update_time(void *lock_ptr, void *caller_ra, int action, uint32_t ticks)
-+{
-+	ushort index;
-+	int cpu;
-+
-+	ASSERT(action < LSTAT_ACT_MAX_VALUES);
-+
-+	if (lstat_control.state == LSTAT_OFF)
-+		return 0;
-+
-+	index = lstat_lookup(lock_ptr, caller_ra);
-+	cpu = THIS_CPU_NUMBER;
-+	(*lstat_control.counts[cpu])[index].count[action]++;
-+	(*lstat_control.counts[cpu])[index].cum_wait_ticks += (uint64_t) ticks;
-+	if ((*lstat_control.counts[cpu])[index].max_wait_ticks < ticks)
-+		(*lstat_control.counts[cpu])[index].max_wait_ticks = ticks;
-+
-+	(*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
-+
-+	return index;
-+}
-+
-+void
-+_metered_spin_lock(spinlock_t * lock_ptr)
-+{
-+	if (lstat_control.state == LSTAT_OFF) {
-+		_raw_spin_lock(lock_ptr);	/* do the real lock */
-+		PUT_INDEX(lock_ptr, 0);	/* clean index in case lockmetering  */
-+		/* gets turned on before unlock */
-+	} else {
-+		void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
-+		int index;
-+
-+		if (_raw_spin_trylock(lock_ptr)) {
-+			index = lstat_update(lock_ptr, this_pc,
-+						LSTAT_ACT_NO_WAIT);
-+		} else {
-+			uint32_t start_cycles = get_cycles();
-+			_raw_spin_lock(lock_ptr);	/* do the real lock */
-+			index = lstat_update_time(lock_ptr, this_pc,
-+				LSTAT_ACT_SPIN, get_cycles() - start_cycles);
-+		}
-+		/* save the index in the lock itself for use in spin unlock */
-+		PUT_INDEX(lock_ptr, index);
-+	}
-+}
-+
-+int
-+_metered_spin_trylock(spinlock_t * lock_ptr)
-+{
-+	if (lstat_control.state == LSTAT_OFF) {
-+		return _raw_spin_trylock(lock_ptr);
-+	} else {
-+		int retval;
-+		void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
-+
-+		if ((retval = _raw_spin_trylock(lock_ptr))) {
-+			int index = lstat_update(lock_ptr, this_pc,
-+						LSTAT_ACT_NO_WAIT);
-+			/*
-+			 * save the index in the lock itself for use in spin
-+			 * unlock
-+			 */
-+			PUT_INDEX(lock_ptr, index);
-+		} else {
-+			lstat_update(lock_ptr, this_pc, LSTAT_ACT_REJECT);
-+		}
-+
-+		return retval;
-+	}
-+}
-+
-+void
-+_metered_spin_unlock(spinlock_t * lock_ptr)
-+{
-+	int index = -1;
-+
-+	if (lstat_control.state != LSTAT_OFF) {
-+		index = GET_INDEX(lock_ptr);
-+		/*
-+		 * If statistics were turned off when we set the lock,
-+		 * then the index can be zero.  If that is the case,
-+		 * then collect no stats on this call.
-+		 */
-+		if (index > 0) {
-+			uint32_t hold_time;
-+			int cpu = THIS_CPU_NUMBER;
-+			hold_time = get_cycles() -
-+			 (*lstat_control.counts[cpu])[index].acquire_time;
-+			(*lstat_control.counts[cpu])[index].cum_hold_ticks +=
-+				(uint64_t) hold_time;
-+			if ((*lstat_control.counts[cpu])[index].max_hold_ticks <
-+			    hold_time)
-+				(*lstat_control.counts[cpu])[index].
-+				    max_hold_ticks = hold_time;
-+		}
-+	}
-+
-+	/* make sure we don't have a stale index value saved */
-+	PUT_INDEX(lock_ptr, 0);
-+	_raw_spin_unlock(lock_ptr);	/* do the real unlock */
-+}
-+
-+/*
-+ * allocate the next global read lock structure and store its index
-+ * in the rwlock at "lock_ptr".
-+ */
-+uint32_t
-+alloc_rwlock_struct(rwlock_t * rwlock_ptr)
-+{
-+	int index;
-+	unsigned long flags;
-+	int cpu = THIS_CPU_NUMBER;
-+
-+	/* If we've already overflowed, then do a quick exit */
-+	if (lstat_control.next_free_read_lock_index >
-+			LSTAT_MAX_READ_LOCK_INDEX) {
-+		lstat_control.rwlock_overflow++;
-+		return 0;
-+	}
-+
-+	local_irq_save(flags);
-+	_raw_spin_lock(&lstat_control.directory_lock);
-+
-+	/* It is possible this changed while we were waiting for the directory_lock */
-+	if (lstat_control.state == LSTAT_OFF) {
-+		index = 0;
-+		goto unlock;
-+	}
-+
-+	/* It is possible someone else got here first and set the index */
-+	if ((index = GET_RWINDEX(rwlock_ptr)) == 0) {
-+		/*
-+		 * we can't turn on read stats for this lock while there are
-+		 * readers (this would mess up the running hold time sum at
-+		 * unlock time)
-+		 */
-+		if (RWLOCK_READERS(rwlock_ptr) != 0) {
-+			index = 0;
-+			goto unlock;
-+		}
-+
-+		/*
-+		 * if stats are turned on after being off, we may need to
-+		 * return an old index from when the statistics were on last
-+		 * time.
-+		 */
-+		for (index = 1; index < lstat_control.next_free_read_lock_index;
-+				index++)
-+			if ((*lstat_control.read_lock_counts[cpu])[index].
-+					lock_ptr == rwlock_ptr)
-+				goto put_index_and_unlock;
-+
-+		/* allocate the next global read lock structure */
-+		if (lstat_control.next_free_read_lock_index >=
-+		    LSTAT_MAX_READ_LOCK_INDEX) {
-+			lstat_control.rwlock_overflow++;
-+			index = 0;
-+			goto unlock;
-+		}
-+		index = lstat_control.next_free_read_lock_index++;
-+
-+		/*
-+		 * initialize the global read stats data structure for each
-+		 * cpu
-+		 */
-+		for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+			(*lstat_control.read_lock_counts[cpu])[index].lock_ptr =
-+				rwlock_ptr;
-+		}
-+put_index_and_unlock:
-+		/* store the index for the read lock structure into the lock */
-+		PUT_RWINDEX(rwlock_ptr, index);
-+	}
-+
-+unlock:
-+	_raw_spin_unlock(&lstat_control.directory_lock);
-+	local_irq_restore(flags);
-+	return index;
-+}
-+
-+void
-+_metered_read_lock(rwlock_t * rwlock_ptr)
-+{
-+	void *this_pc;
-+	uint32_t start_cycles;
-+	int index;
-+	int cpu;
-+	unsigned long flags;
-+	int readers_before, readers_after;
-+	uint64_t cycles64;
-+
-+	if (lstat_control.state == LSTAT_OFF) {
-+		_raw_read_lock(rwlock_ptr);
-+		/* clean index in case lockmetering turns on before an unlock */
-+		PUT_RWINDEX(rwlock_ptr, 0);
-+		return;
-+	}
-+
-+	this_pc = LSTAT_RA(LSTAT_RA_READ);
-+	cpu = THIS_CPU_NUMBER;
-+	index = GET_RWINDEX(rwlock_ptr);
-+
-+	/* allocate the global stats entry for this lock, if needed */
-+	if (index == 0)
-+		index = alloc_rwlock_struct(rwlock_ptr);
-+
-+	readers_before = RWLOCK_READERS(rwlock_ptr);
-+	if (_raw_read_trylock(rwlock_ptr)) {
-+		/*
-+		 * We have decremented the lock to count a new reader,
-+		 * and have confirmed that no writer has it locked.
-+		 */
-+		/* update statistics if enabled */
-+		if (index > 0) {
-+			local_irq_save(flags);
-+			lstat_update((void *) rwlock_ptr, this_pc,
-+					LSTAT_ACT_NO_WAIT);
-+			/* preserve value of TSC so cum_hold_ticks and start_busy use same value */
-+			cycles64 = get_cycles64();
-+			(*lstat_control.read_lock_counts[cpu])[index].
-+				cum_hold_ticks -= cycles64;
-+
-+			/* record time and cpu of start of busy period */
-+			/* this is not perfect (some race conditions are possible) */
-+			if (readers_before == 0) {
-+				(*lstat_control.read_lock_counts[cpu])[index].
-+					start_busy = cycles64;
-+				PUT_RW_CPU(rwlock_ptr, cpu);
-+			}
-+			readers_after = RWLOCK_READERS(rwlock_ptr);
-+			if (readers_after >
-+				(*lstat_control.read_lock_counts[cpu])[index].
-+					max_readers)
-+				(*lstat_control.read_lock_counts[cpu])[index].
-+					max_readers = readers_after;
-+			local_irq_restore(flags);
-+		}
-+
-+		return;
-+	}
-+	/* If we get here, then we could not quickly grab the read lock */
-+
-+	start_cycles = get_cycles();	/* start counting the wait time */
-+
-+	/* Now spin until read_lock is successful */
-+	_raw_read_lock(rwlock_ptr);
-+
-+	lstat_update_time((void *) rwlock_ptr, this_pc, LSTAT_ACT_SPIN,
-+			  get_cycles() - start_cycles);
-+
-+	/* update statistics if they are enabled for this lock */
-+	if (index > 0) {
-+		local_irq_save(flags);
-+		cycles64 = get_cycles64();
-+		(*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks -=
-+				cycles64;
-+
-+		/* this is not perfect (some race conditions are possible) */
-+		if (readers_before == 0) {
-+			(*lstat_control.read_lock_counts[cpu])[index].
-+				start_busy = cycles64;
-+			PUT_RW_CPU(rwlock_ptr, cpu);
-+		}
-+		readers_after = RWLOCK_READERS(rwlock_ptr);
-+		if (readers_after >
-+		    (*lstat_control.read_lock_counts[cpu])[index].max_readers)
-+			(*lstat_control.read_lock_counts[cpu])[index].
-+				max_readers = readers_after;
-+		local_irq_restore(flags);
-+	}
-+}
-+
-+void
-+_metered_read_unlock(rwlock_t * rwlock_ptr)
-+{
-+	int index;
-+	int cpu;
-+	unsigned long flags;
-+	uint64_t busy_length;
-+	uint64_t cycles64;
-+
-+	if (lstat_control.state == LSTAT_OFF) {
-+		_raw_read_unlock(rwlock_ptr);
-+		return;
-+	}
-+
-+	index = GET_RWINDEX(rwlock_ptr);
-+	cpu = THIS_CPU_NUMBER;
-+
-+	if (index > 0) {
-+		local_irq_save(flags);
-+		/*
-+		 * preserve value of TSC so cum_hold_ticks and busy_ticks are
-+		 * consistent.
-+		 */
-+		cycles64 = get_cycles64();
-+		(*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks +=
-+			cycles64;
-+		(*lstat_control.read_lock_counts[cpu])[index].read_lock_count++;
-+
-+		/*
-+		 * once again, this is not perfect (some race conditions are
-+		 * possible)
-+		 */
-+		if (RWLOCK_READERS(rwlock_ptr) == 1) {
-+			int cpu1 = GET_RW_CPU(rwlock_ptr);
-+			uint64_t last_start_busy =
-+				(*lstat_control.read_lock_counts[cpu1])[index].
-+					start_busy;
-+			(*lstat_control.read_lock_counts[cpu])[index].
-+				busy_periods++;
-+			if (cycles64 > last_start_busy) {
-+				busy_length = cycles64 - last_start_busy;
-+				(*lstat_control.read_lock_counts[cpu])[index].
-+					busy_ticks += busy_length;
-+				if (busy_length >
-+					(*lstat_control.
-+						read_lock_counts[cpu])[index].
-+							max_busy)
-+					(*lstat_control.
-+					 read_lock_counts[cpu])[index].
-+						max_busy = busy_length;
-+			}
-+		}
-+		local_irq_restore(flags);
-+	}
-+	_raw_read_unlock(rwlock_ptr);
-+}
-+
-+void
-+_metered_write_lock(rwlock_t * rwlock_ptr)
-+{
-+	uint32_t start_cycles;
-+	void *this_pc;
-+	uint32_t spin_ticks = 0; /* in anticipation of a potential wait */
-+	int index;
-+	int write_index = 0;
-+	int cpu;
-+	enum {
-+		writer_writer_conflict,
-+		writer_reader_conflict
-+	} why_wait = writer_writer_conflict;
-+
-+	if (lstat_control.state == LSTAT_OFF) {
-+		_raw_write_lock(rwlock_ptr);
-+		/* clean index in case lockmetering turns on before an unlock */
-+		PUT_RWINDEX(rwlock_ptr, 0);
-+		return;
-+	}
-+
-+	this_pc = LSTAT_RA(LSTAT_RA_WRITE);
-+	cpu = THIS_CPU_NUMBER;
-+	index = GET_RWINDEX(rwlock_ptr);
-+
-+	/* allocate the global stats entry for this lock, if needed */
-+	if (index == 0) {
-+		index = alloc_rwlock_struct(rwlock_ptr);
-+	}
-+
-+	if (_raw_write_trylock(rwlock_ptr)) {
-+		/* We acquired the lock on the first try */
-+		write_index = lstat_update((void *) rwlock_ptr, this_pc,
-+					LSTAT_ACT_NO_WAIT);
-+		/* save the write_index for use in unlock if stats enabled */
-+		if (index > 0)
-+			(*lstat_control.read_lock_counts[cpu])[index].
-+				write_index = write_index;
-+		return;
-+	}
-+
-+	/* If we get here, then we could not quickly grab the write lock */
-+	start_cycles = get_cycles();	/* start counting the wait time */
-+
-+	why_wait = RWLOCK_READERS(rwlock_ptr) ?
-+			writer_reader_conflict : writer_writer_conflict;
-+
-+	/* Now set the lock and wait for conflicts to disappear */
-+	_raw_write_lock(rwlock_ptr);
-+
-+	spin_ticks = get_cycles() - start_cycles;
-+
-+	/* update stats -- if enabled */
-+	if (index > 0 && spin_ticks) {
-+		if (why_wait == writer_reader_conflict) {
-+			/* waited due to a reader holding the lock */
-+			write_index = lstat_update_time((void *)rwlock_ptr,
-+					this_pc, LSTAT_ACT_SPIN, spin_ticks);
-+		} else {
-+			/*
-+			 * waited due to another writer holding the lock
-+			 */
-+			write_index = lstat_update_time((void *)rwlock_ptr,
-+				this_pc, LSTAT_ACT_WW_SPIN, spin_ticks);
-+			(*lstat_control.counts[cpu])[write_index].
-+				cum_wait_ww_ticks += spin_ticks;
-+			if (spin_ticks >
-+				(*lstat_control.counts[cpu])[write_index].
-+					max_wait_ww_ticks) {
-+				(*lstat_control.counts[cpu])[write_index].
-+					max_wait_ww_ticks = spin_ticks;
-+			}
-+		}
-+
-+		/* save the directory index for use on write_unlock */
-+		(*lstat_control.read_lock_counts[cpu])[index].
-+			write_index = write_index;
-+	}
-+}
-+
-+void
-+_metered_write_unlock(rwlock_t * rwlock_ptr)
-+{
-+	int index;
-+	int cpu;
-+	int write_index;
-+	uint32_t hold_time;
-+
-+	if (lstat_control.state == LSTAT_OFF) {
-+		_raw_write_unlock(rwlock_ptr);
-+		return;
-+	}
-+
-+	cpu = THIS_CPU_NUMBER;
-+	index = GET_RWINDEX(rwlock_ptr);
-+
-+	/* update statistics if stats enabled for this lock */
-+	if (index > 0) {
-+		write_index =
-+		    (*lstat_control.read_lock_counts[cpu])[index].write_index;
-+
-+		hold_time = get_cycles() -
-+			(*lstat_control.counts[cpu])[write_index].acquire_time;
-+		(*lstat_control.counts[cpu])[write_index].cum_hold_ticks +=
-+			(uint64_t) hold_time;
-+		if ((*lstat_control.counts[cpu])[write_index].max_hold_ticks <
-+				hold_time)
-+			(*lstat_control.counts[cpu])[write_index].
-+				max_hold_ticks = hold_time;
-+	}
-+	_raw_write_unlock(rwlock_ptr);
-+}
-+
-+int
-+_metered_write_trylock(rwlock_t * rwlock_ptr)
-+{
-+	int retval;
-+	void *this_pc = LSTAT_RA(LSTAT_RA_WRITE);
-+
-+	if ((retval = _raw_write_trylock(rwlock_ptr))) {
-+		lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_NO_WAIT);
-+	} else {
-+		lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_REJECT);
-+	}
-+
-+	return retval;
-+}
-+
-+static void
-+init_control_space(void)
-+{
-+	/* Set all control space pointers to null and indices to "empty" */
-+	int cpu;
-+
-+	/*
-+	 * Access CPU_CYCLE_FREQUENCY at the outset, which in some
-+	 * architectures may trigger a runtime calculation that uses a
-+	 * spinlock.  Let's do this before lockmetering is turned on.
-+	 */
-+	if (CPU_CYCLE_FREQUENCY == 0)
-+		BUG();
-+
-+	lstat_control.hashtab = NULL;
-+	lstat_control.dir = NULL;
-+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-+		lstat_control.counts[cpu] = NULL;
-+		lstat_control.read_lock_counts[cpu] = NULL;
-+	}
-+}
-+
-+static int
-+reset_lstat_data(void)
-+{
-+	int cpu, flags;
-+
-+	flags = 0;
-+	lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
-+	lstat_control.next_free_read_lock_index = 1;
-+	lstat_control.dir_overflow = 0;
-+	lstat_control.rwlock_overflow = 0;
-+
-+	lstat_control.started_cycles64 = 0;
-+	lstat_control.ending_cycles64 = 0;
-+	lstat_control.enabled_cycles64 = 0;
-+	lstat_control.first_started_time = 0;
-+	lstat_control.started_time = 0;
-+	lstat_control.ending_time = 0;
-+	lstat_control.intervals = 0;
-+
-+	/*
-+	 * paranoia -- in case someone does a "lockstat reset" before
-+	 * "lockstat on"
-+	 */
-+	if (lstat_control.hashtab) {
-+		bzero(lstat_control.hashtab,
-+			LSTAT_HASH_TABLE_SIZE * sizeof (short));
-+		bzero(lstat_control.dir, LSTAT_MAX_STAT_INDEX *
-+				sizeof (lstat_directory_entry_t));
-+
-+		for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+			bzero(lstat_control.counts[cpu],
-+				sizeof (lstat_cpu_counts_t));
-+			bzero(lstat_control.read_lock_counts[cpu],
-+				sizeof (lstat_read_lock_cpu_counts_t));
-+		}
-+	}
-+#ifdef NOTDEF
-+	_raw_spin_unlock(&lstat_control.directory_lock);
-+	local_irq_restore(flags);
-+#endif
-+	return 1;
-+}
-+
-+static void
-+release_control_space(void)
-+{
-+	/*
-+	 * Called when either (1) allocation of kmem
-+	 * or (2) when user writes LSTAT_RELEASE to /pro/lockmeter.
-+	 * Assume that all pointers have been initialized to zero,
-+	 * i.e., nonzero pointers are valid addresses.
-+	 */
-+	int cpu;
-+
-+	if (lstat_control.hashtab) {
-+		kfree(lstat_control.hashtab);
-+		lstat_control.hashtab = NULL;
-+	}
-+
-+	if (lstat_control.dir) {
-+		vfree(lstat_control.dir);
-+		lstat_control.dir = NULL;
-+	}
-+
-+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-+		if (lstat_control.counts[cpu]) {
-+			vfree(lstat_control.counts[cpu]);
-+			lstat_control.counts[cpu] = NULL;
-+		}
-+		if (lstat_control.read_lock_counts[cpu]) {
-+			kfree(lstat_control.read_lock_counts[cpu]);
-+			lstat_control.read_lock_counts[cpu] = NULL;
-+		}
-+	}
-+}
-+
-+int
-+get_lockmeter_info_size(void)
-+{
-+	return sizeof (lstat_user_request_t)
-+		+ num_online_cpus() * sizeof (lstat_cpu_counts_t)
-+		+ num_online_cpus() * sizeof (lstat_read_lock_cpu_counts_t)
-+		+ (LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t));
-+}
-+
-+ssize_t
-+get_lockmeter_info(char *buffer, size_t max_len, loff_t * last_index)
-+{
-+	lstat_user_request_t req;
-+	struct timeval tv;
-+	ssize_t next_ret_bcount;
-+	ssize_t actual_ret_bcount = 0;
-+	int cpu;
-+
-+	*last_index = 0;	/* a one-shot read */
-+
-+	req.lstat_version = LSTAT_VERSION;
-+	req.state = lstat_control.state;
-+	req.maxcpus = num_online_cpus();
-+	req.cycleval = CPU_CYCLE_FREQUENCY;
-+#ifdef notyet
-+	req.kernel_magic_addr = (void *) &_etext;
-+	req.kernel_end_addr = (void *) &_etext;
-+#endif
-+	req.uts = system_utsname;
-+	req.intervals = lstat_control.intervals;
-+
-+	req.first_started_time = lstat_control.first_started_time;
-+	req.started_time = lstat_control.started_time;
-+	req.started_cycles64 = lstat_control.started_cycles64;
-+
-+	req.next_free_dir_index = lstat_control.next_free_dir_index;
-+	req.next_free_read_lock_index = lstat_control.next_free_read_lock_index;
-+	req.dir_overflow = lstat_control.dir_overflow;
-+	req.rwlock_overflow = lstat_control.rwlock_overflow;
-+
-+	if (lstat_control.state == LSTAT_OFF) {
-+		if (req.intervals == 0) {
-+			/* mesasurement is off and no valid data present */
-+			next_ret_bcount = sizeof (lstat_user_request_t);
-+			req.enabled_cycles64 = 0;
-+
-+			if ((actual_ret_bcount + next_ret_bcount) > max_len)
-+				return actual_ret_bcount;
-+
-+			copy_to_user(buffer, (void *) &req, next_ret_bcount);
-+			actual_ret_bcount += next_ret_bcount;
-+			return actual_ret_bcount;
-+		} else {
-+			/*
-+			 * measurement is off but valid data present
-+			 * fetch time info from lstat_control
-+			 */
-+			req.ending_time = lstat_control.ending_time;
-+			req.ending_cycles64 = lstat_control.ending_cycles64;
-+			req.enabled_cycles64 = lstat_control.enabled_cycles64;
-+		}
-+	} else {
-+		/*
-+		 * this must be a read while data active--use current time,
-+		 * etc
-+		 */
-+		do_gettimeofday(&tv);
-+		req.ending_time = tv.tv_sec;
-+		req.ending_cycles64 = get_cycles64();
-+		req.enabled_cycles64 = req.ending_cycles64 -
-+			req.started_cycles64 + lstat_control.enabled_cycles64;
-+	}
-+
-+	next_ret_bcount = sizeof (lstat_user_request_t);
-+	if ((actual_ret_bcount + next_ret_bcount) > max_len)
-+		return actual_ret_bcount;
-+
-+	copy_to_user(buffer, (void *) &req, next_ret_bcount);
-+	actual_ret_bcount += next_ret_bcount;
-+
-+	if (!lstat_control.counts[0])	/* not initialized? */
-+		return actual_ret_bcount;
-+
-+	next_ret_bcount = sizeof (lstat_cpu_counts_t);
-+	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+		if ((actual_ret_bcount + next_ret_bcount) > max_len)
-+			return actual_ret_bcount;	/* leave early */
-+		copy_to_user(buffer + actual_ret_bcount,
-+				lstat_control.counts[cpu], next_ret_bcount);
-+		actual_ret_bcount += next_ret_bcount;
-+	}
-+
-+	next_ret_bcount = LSTAT_MAX_STAT_INDEX *
-+			sizeof (lstat_directory_entry_t);
-+	if (((actual_ret_bcount + next_ret_bcount) > max_len)
-+			|| !lstat_control.dir)
-+		return actual_ret_bcount;	/* leave early */
-+
-+	copy_to_user(buffer + actual_ret_bcount, lstat_control.dir,
-+			next_ret_bcount);
-+	actual_ret_bcount += next_ret_bcount;
-+
-+	next_ret_bcount = sizeof (lstat_read_lock_cpu_counts_t);
-+	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+		if (actual_ret_bcount + next_ret_bcount > max_len)
-+			return actual_ret_bcount;
-+		copy_to_user(buffer + actual_ret_bcount,
-+				lstat_control.read_lock_counts[cpu],
-+				next_ret_bcount);
-+		actual_ret_bcount += next_ret_bcount;
-+	}
-+
-+	return actual_ret_bcount;
-+}
-+
-+/*
-+ *  Writing to the /proc lockmeter node enables or disables metering.
-+ *  based upon the first byte of the "written" data.
-+ *  The following values are defined:
-+ *  LSTAT_ON: 1st call: allocates storage, intializes and turns on measurement
-+ *            subsequent calls just turn on measurement
-+ *  LSTAT_OFF: turns off measurement
-+ *  LSTAT_RESET: resets statistics
-+ *  LSTAT_RELEASE: releases statistics storage
-+ *
-+ *  This allows one to accumulate statistics over several lockstat runs:
-+ *
-+ *  lockstat on
-+ *  lockstat off
-+ *  ...repeat above as desired...
-+ *  lockstat get
-+ *  ...now start a new set of measurements...
-+ *  lockstat reset
-+ *  lockstat on
-+ *  ...
-+ *
-+ */
-+ssize_t
-+put_lockmeter_info(const char *buffer, size_t len)
-+{
-+	int error = 0;
-+	int dirsize, countsize, read_lock_countsize, hashsize;
-+	int cpu;
-+	char put_char;
-+	int i, read_lock_blocks;
-+	unsigned long flags;
-+	rwlock_t *lock_ptr;
-+	struct timeval tv;
-+
-+	if (len <= 0)
-+		return -EINVAL;
-+
-+	_raw_spin_lock(&lstat_control.control_lock);
-+
-+	get_user(put_char, buffer);
-+	switch (put_char) {
-+
-+	case LSTAT_OFF:
-+		if (lstat_control.state != LSTAT_OFF) {
-+			/*
-+			 * To avoid seeing read lock hold times in an
-+			 * inconsisent state, we have to follow this protocol
-+			 * to turn off statistics
-+			 */
-+			local_irq_save(flags);
-+			/*
-+			 * getting this lock will stop any read lock block
-+			 * allocations
-+			 */
-+			_raw_spin_lock(&lstat_control.directory_lock);
-+			/*
-+			 * keep any more read lock blocks from being
-+			 * allocated
-+			 */
-+			lstat_control.state = LSTAT_OFF;
-+			/* record how may read lock blocks there are */
-+			read_lock_blocks =
-+				lstat_control.next_free_read_lock_index;
-+			_raw_spin_unlock(&lstat_control.directory_lock);
-+			/* now go through the list of read locks */
-+			cpu = THIS_CPU_NUMBER;
-+			for (i = 1; i < read_lock_blocks; i++) {
-+				lock_ptr =
-+				    (*lstat_control.read_lock_counts[cpu])[i].
-+				    lock_ptr;
-+				/* is this saved lock address still valid? */
-+				if (GET_RWINDEX(lock_ptr) == i) {
-+					/*
-+					 * lock address appears to still be
-+					 * valid because we only hold one lock
-+					 * at a time, this can't cause a
-+					 * deadlock unless this is a lock held
-+					 * as part of the current system call
-+					 * path. At the moment there
-+					 * are no READ mode locks held to get
-+					 * here from user space, so we solve
-+					 * this by skipping locks held in
-+					 * write mode.
-+					 */
-+					if (RWLOCK_IS_WRITE_LOCKED(lock_ptr)) {
-+						PUT_RWINDEX(lock_ptr, 0);
-+						continue;
-+					}
-+					/*
-+					 * now we know there are no read
-+					 * holders of this lock! stop
-+					 * statistics collection for this
-+					 * lock
-+					 */
-+					_raw_write_lock(lock_ptr);
-+					PUT_RWINDEX(lock_ptr, 0);
-+					_raw_write_unlock(lock_ptr);
-+				}
-+				/*
-+				 * it may still be possible for the hold time
-+				 * sum to be negative e.g. if a lock is
-+				 * reallocated while "busy" we will have to fix
-+				 * this up in the data reduction program.
-+				 */
-+			}
-+			local_irq_restore(flags);
-+			lstat_control.intervals++;
-+			lstat_control.ending_cycles64 = get_cycles64();
-+			lstat_control.enabled_cycles64 +=
-+				lstat_control.ending_cycles64 -
-+				lstat_control.started_cycles64;
-+			do_gettimeofday(&tv);
-+			lstat_control.ending_time = tv.tv_sec;
-+			/*
-+			 * don't deallocate the structures -- we may do a
-+			 * lockstat on to add to the data that is already
-+			 * there. Use LSTAT_RELEASE to release storage
-+			 */
-+		} else {
-+			error = -EBUSY;	/* already OFF */
-+		}
-+		break;
-+
-+	case LSTAT_ON:
-+		if (lstat_control.state == LSTAT_OFF) {
-+#ifdef DEBUG_LOCKMETER
-+			printk("put_lockmeter_info(cpu=%d): LSTAT_ON\n",
-+				THIS_CPU_NUMBER);
-+#endif
-+			lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
-+
-+			dirsize = LSTAT_MAX_STAT_INDEX *
-+					sizeof (lstat_directory_entry_t);
-+			hashsize =
-+				(1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
-+			countsize = sizeof (lstat_cpu_counts_t);
-+			read_lock_countsize =
-+				sizeof (lstat_read_lock_cpu_counts_t);
-+#ifdef DEBUG_LOCKMETER
-+			printk(" dirsize:%d", dirsize);
-+			printk(" hashsize:%d", hashsize);
-+			printk(" countsize:%d", countsize);
-+			printk(" read_lock_countsize:%d\n",
-+				read_lock_countsize);
-+#endif
-+#ifdef DEBUG_LOCKMETER
-+			{
-+				int secs;
-+				unsigned long cycles;
-+				uint64_t cycles64;
-+
-+				do_gettimeofday(&tv);
-+				secs = tv.tv_sec;
-+				do {
-+					do_gettimeofday(&tv);
-+				} while (secs == tv.tv_sec);
-+				cycles = get_cycles();
-+				cycles64 = get_cycles64();
-+				secs = tv.tv_sec;
-+				do {
-+					do_gettimeofday(&tv);
-+				} while (secs == tv.tv_sec);
-+				cycles = get_cycles() - cycles;
-+				cycles64 = get_cycles64() - cycles;
-+				printk("lockmeter: cycleFrequency:%d "
-+					"cycles:%d cycles64:%d\n",
-+					CPU_CYCLE_FREQUENCY, cycles, cycles64);
-+			}
-+#endif
-+
-+			/*
-+			 * if this is the first call, allocate storage and
-+			 * initialize
-+			 */
-+			if (!lstat_control.hashtab) {
-+
-+				spin_lock_init(&lstat_control.directory_lock);
-+
-+				/* guarantee all pointers at zero */
-+				init_control_space();
-+
-+				lstat_control.hashtab =
-+				    kmalloc(hashsize, GFP_KERNEL);
-+				if (!lstat_control.hashtab) {
-+					error = -ENOSPC;
-+#ifdef DEBUG_LOCKMETER
-+					printk("!!error kmalloc of hashtab\n");
-+#endif
-+				}
-+				lstat_control.dir = vmalloc(dirsize);
-+				if (!lstat_control.dir) {
-+					error = -ENOSPC;
-+#ifdef DEBUG_LOCKMETER
-+					printk("!!error kmalloc of dir\n");
-+#endif
-+				}
-+
-+				for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+					lstat_control.counts[cpu] =
-+						vmalloc(countsize);
-+					if (!lstat_control.counts[cpu]) {
-+						error = -ENOSPC;
-+#ifdef DEBUG_LOCKMETER
-+						printk("!!error vmalloc of "
-+							"counts[%d]\n", cpu);
-+#endif
-+					}
-+					lstat_control.read_lock_counts[cpu] =
-+						(lstat_read_lock_cpu_counts_t *)
-+						kmalloc(read_lock_countsize,
-+							GFP_KERNEL);
-+					if (!lstat_control.
-+							read_lock_counts[cpu]) {
-+						error = -ENOSPC;
-+#ifdef DEBUG_LOCKMETER
-+						printk("!!error kmalloc of "
-+						  "read_lock_counts[%d]\n",
-+							cpu);
-+#endif
-+					}
-+				}
-+			}
-+
-+			if (error) {
-+				/*
-+				 * One or more kmalloc failures -- free
-+				 * everything
-+				 */
-+				release_control_space();
-+			} else {
-+
-+				if (!reset_lstat_data()) {
-+					error = -EINVAL;
-+					break;
-+				};
-+
-+				/*
-+				 * record starting and ending times and the
-+				 * like
-+				 */
-+				if (lstat_control.intervals == 0) {
-+					do_gettimeofday(&tv);
-+					lstat_control.first_started_time =
-+						tv.tv_sec;
-+				}
-+				lstat_control.started_cycles64 = get_cycles64();
-+				do_gettimeofday(&tv);
-+				lstat_control.started_time = tv.tv_sec;
-+
-+				lstat_control.state = LSTAT_ON;
-+			}
-+		} else {
-+			error = -EBUSY;	/* already ON */
-+		}
-+		break;
-+
-+	case LSTAT_RESET:
-+		if (lstat_control.state == LSTAT_OFF) {
-+			if (!reset_lstat_data())
-+				error = -EINVAL;
-+		} else {
-+			error = -EBUSY;	/* still on; can't reset */
-+		}
-+		break;
-+
-+	case LSTAT_RELEASE:
-+		if (lstat_control.state == LSTAT_OFF) {
-+			release_control_space();
-+			lstat_control.intervals = 0;
-+			lstat_control.enabled_cycles64 = 0;
-+		} else {
-+			error = -EBUSY;
-+		}
-+		break;
-+
-+	default:
-+		error = -EINVAL;
-+	}			/* switch */
-+
-+	_raw_spin_unlock(&lstat_control.control_lock);
-+	return error ? error : len;
-+}
-+
-+#ifdef USER_MODE_TESTING
-+/* following used for user mode testing */
-+void
-+lockmeter_init()
-+{
-+	int dirsize, hashsize, countsize, read_lock_countsize, cpu;
-+
-+	printf("lstat_control is at %x size=%d\n", &lstat_control,
-+		sizeof (lstat_control));
-+	printf("sizeof(spinlock_t)=%d\n", sizeof (spinlock_t));
-+	lstat_control.state = LSTAT_ON;
-+
-+	lstat_control.directory_lock = SPIN_LOCK_UNLOCKED;
-+	lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
-+	lstat_control.next_free_read_lock_index = 1;
-+
-+	dirsize = LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t);
-+	hashsize = (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
-+	countsize = sizeof (lstat_cpu_counts_t);
-+	read_lock_countsize = sizeof (lstat_read_lock_cpu_counts_t);
-+
-+	lstat_control.hashtab = (ushort *) malloc(hashsize);
-+
-+	if (lstat_control.hashtab == 0) {
-+		printf("malloc failure for at line %d in lockmeter.c\n",
-+			__LINE__);
-+		exit(0);
-+	}
-+
-+	lstat_control.dir = (lstat_directory_entry_t *) malloc(dirsize);
-+
-+	if (lstat_control.dir == 0) {
-+		printf("malloc failure for at line %d in lockmeter.c\n", cpu,
-+			__LINE__);
-+		exit(0);
-+	}
-+
-+	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+		int j, k;
-+		j = (int) (lstat_control.counts[cpu] =
-+			   (lstat_cpu_counts_t *) malloc(countsize));
-+		k = (int) (lstat_control.read_lock_counts[cpu] =
-+			   (lstat_read_lock_cpu_counts_t *)
-+			   malloc(read_lock_countsize));
-+		if (j * k == 0) {
-+			printf("malloc failure for cpu=%d at line %d in "
-+				"lockmeter.c\n", cpu, __LINE__);
-+			exit(0);
-+		}
-+	}
-+
-+	memset(lstat_control.hashtab, 0, hashsize);
-+	memset(lstat_control.dir, 0, dirsize);
-+
-+	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
-+		memset(lstat_control.counts[cpu], 0, countsize);
-+		memset(lstat_control.read_lock_counts[cpu], 0,
-+			read_lock_countsize);
-+	}
-+}
-+
-+asm("
-+.align	4
-+.globl	__write_lock_failed
-+__write_lock_failed:
-+	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)
-+1:	cmpl	$" RW_LOCK_BIAS_STR ",(%eax)
-+	jne	1b
-+
-+	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
-+	jnz	__write_lock_failed
-+	ret
-+
-+
-+.align	4
-+.globl	__read_lock_failed
-+__read_lock_failed:
-+	lock ; incl	(%eax)
-+1:	cmpl	$1,(%eax)
-+	js	1b
-+
-+	lock ; decl	(%eax)
-+	js	__read_lock_failed
-+	ret
-+");
-+#endif
---- linux-2.6.0-test1/kernel/Makefile	2003-06-26 22:07:26.000000000 -0700
-+++ 25/kernel/Makefile	2003-07-19 17:06:40.000000000 -0700
-@@ -11,6 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o
- obj-$(CONFIG_FUTEX) += futex.o
- obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
- obj-$(CONFIG_SMP) += cpu.o
-+obj-$(CONFIG_LOCKMETER) += lockmeter.o
- obj-$(CONFIG_UID16) += uid16.o
- obj-$(CONFIG_MODULES) += ksyms.o module.o
- obj-$(CONFIG_KALLSYMS) += kallsyms.o
---- linux-2.6.0-test1/kernel/module.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/kernel/module.c	2003-07-19 17:04:07.000000000 -0700
-@@ -98,6 +98,17 @@ int init_module(void)
- }
- EXPORT_SYMBOL(init_module);
- 
-+/* A thread that wants to hold a reference to a module only while it
-+ * is running can call ths to safely exit.
-+ * nfsd and lockd use this.
-+ */
-+void __module_put_and_exit(struct module *mod, long code)
-+{
-+	module_put(mod);
-+	do_exit(code);
-+}
-+EXPORT_SYMBOL(__module_put_and_exit);
-+	
- /* Find a module section: 0 means not found. */
- static unsigned int find_sec(Elf_Ehdr *hdr,
- 			     Elf_Shdr *sechdrs,
-@@ -374,9 +385,9 @@ static void module_unload_init(struct mo
- 
- 	INIT_LIST_HEAD(&mod->modules_which_use_me);
- 	for (i = 0; i < NR_CPUS; i++)
--		atomic_set(&mod->ref[i].count, 0);
-+		local_set(&mod->ref[i].count, 0);
- 	/* Hold reference count during initialization. */
--	atomic_set(&mod->ref[smp_processor_id()].count, 1);
-+	local_set(&mod->ref[smp_processor_id()].count, 1);
- 	/* Backwards compatibility macros put refcount during init. */
- 	mod->waiter = current;
- }
-@@ -471,7 +482,7 @@ static int stopref(void *cpu)
- 	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
- 	setscheduler(current->pid, SCHED_FIFO, &param);
- #endif
--	set_cpus_allowed(current, 1UL << (unsigned long)cpu);
-+	set_cpus_allowed(current, cpumask_of_cpu((int)(long)cpu));
- 
- 	/* Ack: we are alive */
- 	atomic_inc(&stopref_thread_ack);
-@@ -524,7 +535,7 @@ static void stopref_set_state(enum stopr
- static int stop_refcounts(void)
- {
- 	unsigned int i, cpu;
--	unsigned long old_allowed;
-+	cpumask_t old_allowed;
- 	int ret = 0;
- 
- 	/* One thread per cpu.  We'll do our own. */
-@@ -532,7 +543,7 @@ static int stop_refcounts(void)
- 
- 	/* FIXME: racy with set_cpus_allowed. */
- 	old_allowed = current->cpus_allowed;
--	set_cpus_allowed(current, 1UL << (unsigned long)cpu);
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 
- 	atomic_set(&stopref_thread_ack, 0);
- 	stopref_num_threads = 0;
-@@ -599,7 +610,7 @@ unsigned int module_refcount(struct modu
- 	unsigned int i, total = 0;
- 
- 	for (i = 0; i < NR_CPUS; i++)
--		total += atomic_read(&mod->ref[i].count);
-+		total += local_read(&mod->ref[i].count);
- 	return total;
- }
- EXPORT_SYMBOL(module_refcount);
-@@ -610,7 +621,10 @@ static void free_module(struct module *m
- #ifdef CONFIG_MODULE_FORCE_UNLOAD
- static inline int try_force(unsigned int flags)
- {
--	return (flags & O_TRUNC);
-+	int ret = (flags & O_TRUNC);
-+	if (ret)
-+		tainted |= TAINT_FORCED_MODULE;
-+	return ret;
- }
- #else
- static inline int try_force(unsigned int flags)
---- linux-2.6.0-test1/kernel/printk.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/kernel/printk.c	2003-07-19 17:07:04.000000000 -0700
-@@ -399,9 +399,13 @@ asmlinkage int printk(const char *fmt, .
- 	char *p;
- 	static char printk_buf[1024];
- 	static int log_level_unknown = 1;
-+	static int printk_cpu = -1;
- 
--	if (oops_in_progress) {
--		/* If a crash is occurring, make sure we can't deadlock */
-+	if (oops_in_progress && printk_cpu == smp_processor_id()) {
-+		/*
-+		 * If a crash is occurring during printk() on this CPU, make
-+		 * sure we can't deadlock
-+		 */
- 		spin_lock_init(&logbuf_lock);
- 		/* And make sure that we print immediately */
- 		init_MUTEX(&console_sem);
-@@ -409,6 +413,7 @@ asmlinkage int printk(const char *fmt, .
- 
- 	/* This stops the holder of console_sem just where we want him */
- 	spin_lock_irqsave(&logbuf_lock, flags);
-+	printk_cpu = smp_processor_id();
- 
- 	/* Emit the output into the temporary buffer */
- 	va_start(args, fmt);
---- linux-2.6.0-test1/kernel/profile.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/kernel/profile.c	2003-07-19 17:03:51.000000000 -0700
-@@ -8,8 +8,7 @@
- #include <linux/bootmem.h>
- #include <linux/notifier.h>
- #include <linux/mm.h>
--
--extern char _stext, _etext;
-+#include <asm/sections.h>
- 
- unsigned int * prof_buffer;
- unsigned long prof_len;
-@@ -36,7 +35,7 @@ void __init profile_init(void)
- 		return;
-  
- 	/* only text is profiled */
--	prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
-+	prof_len = _etext - _stext;
- 	prof_len >>= prof_shift;
- 		
- 	size = prof_len * sizeof(unsigned int) + PAGE_SIZE - 1;
---- linux-2.6.0-test1/kernel/rcupdate.c	2003-06-26 22:07:26.000000000 -0700
-+++ 25/kernel/rcupdate.c	2003-07-19 17:04:56.000000000 -0700
-@@ -41,6 +41,7 @@
- #include <linux/module.h>
- #include <linux/completion.h>
- #include <linux/percpu.h>
-+#include <linux/seq_file.h>
- #include <linux/notifier.h>
- #include <linux/rcupdate.h>
- #include <linux/cpu.h>
-@@ -48,7 +49,7 @@
- /* Definition for rcupdate control block. */
- struct rcu_ctrlblk rcu_ctrlblk = 
- 	{ .mutex = SPIN_LOCK_UNLOCKED, .curbatch = 1, 
--	  .maxbatch = 1, .rcu_cpu_mask = 0 };
-+	  .maxbatch = 1, .rcu_cpu_mask = CPU_MASK_NONE };
- DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
- 
- /* Fake initialization required by compiler */
-@@ -76,6 +77,7 @@ void call_rcu(struct rcu_head *head, voi
- 	local_irq_save(flags);
- 	cpu = smp_processor_id();
- 	list_add_tail(&head->list, &RCU_nxtlist(cpu));
-+	RCU_nr_rcureqs(cpu)++;
- 	local_irq_restore(flags);
- }
- 
-@@ -83,7 +85,7 @@ void call_rcu(struct rcu_head *head, voi
-  * Invoke the completed RCU callbacks. They are expected to be in
-  * a per-cpu list.
-  */
--static void rcu_do_batch(struct list_head *list)
-+static void rcu_do_batch(int cpu, struct list_head *list)
- {
- 	struct list_head *entry;
- 	struct rcu_head *head;
-@@ -93,6 +95,7 @@ static void rcu_do_batch(struct list_hea
- 		list_del(entry);
- 		head = list_entry(entry, struct rcu_head, list);
- 		head->func(head->arg);
-+		RCU_nr_rcupdates(cpu)++;
- 	}
- }
- 
-@@ -107,7 +110,7 @@ static void rcu_start_batch(long newbatc
- 		rcu_ctrlblk.maxbatch = newbatch;
- 	}
- 	if (rcu_batch_before(rcu_ctrlblk.maxbatch, rcu_ctrlblk.curbatch) ||
--	    (rcu_ctrlblk.rcu_cpu_mask != 0)) {
-+	    !cpus_empty(rcu_ctrlblk.rcu_cpu_mask)) {
- 		return;
- 	}
- 	rcu_ctrlblk.rcu_cpu_mask = cpu_online_map;
-@@ -122,7 +125,7 @@ static void rcu_check_quiescent_state(vo
- {
- 	int cpu = smp_processor_id();
- 
--	if (!test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask))
-+	if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask))
- 		return;
- 
- 	/* 
-@@ -138,12 +141,12 @@ static void rcu_check_quiescent_state(vo
- 		return;
- 
- 	spin_lock(&rcu_ctrlblk.mutex);
--	if (!test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask))
-+	if (!cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask))
- 		goto out_unlock;
- 
--	clear_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask);
-+	cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask);
- 	RCU_last_qsctr(cpu) = RCU_QSCTR_INVALID;
--	if (rcu_ctrlblk.rcu_cpu_mask != 0)
-+	if (!cpus_empty(rcu_ctrlblk.rcu_cpu_mask))
- 		goto out_unlock;
- 
- 	rcu_ctrlblk.curbatch++;
-@@ -186,7 +189,7 @@ static void rcu_process_callbacks(unsign
- 	}
- 	rcu_check_quiescent_state();
- 	if (!list_empty(&list))
--		rcu_do_batch(&list);
-+		rcu_do_batch(cpu, &list);
- }
- 
- void rcu_check_callbacks(int cpu, int user)
-@@ -265,3 +268,44 @@ void synchronize_kernel(void)
- 
- EXPORT_SYMBOL(call_rcu);
- EXPORT_SYMBOL(synchronize_kernel);
-+
-+#ifdef	CONFIG_PROC_FS
-+
-+static void *rcu_start(struct seq_file *m, loff_t *pos)
-+{
-+	static int cpu;
-+	cpu = *pos;
-+	return *pos < NR_CPUS ? &cpu : NULL;
-+}
-+
-+static void *rcu_next(struct seq_file *m, void *v, loff_t *pos)
-+{
-+	++*pos;
-+	return rcu_start(m, pos);
-+}
-+
-+static void rcu_stop(struct seq_file *m, void *v)
-+{
-+}
-+
-+static int show_rcu(struct seq_file *m, void *v)
-+{
-+	int cpu = *(int *)v;
-+
-+	if (!cpu_online(cpu))
-+		return 0;
-+	seq_printf(m, "CPU : %d\n", cpu);
-+	seq_printf(m, "RCU requests : %ld\n", RCU_nr_rcureqs(cpu));
-+	seq_printf(m, "RCU updates : %ld\n\n", RCU_nr_rcupdates(cpu));
-+	return 0;
-+}
-+
-+struct seq_operations rcu_op = {
-+	.start	= rcu_start,
-+	.next	= rcu_next,
-+	.stop	= rcu_stop,
-+	.show	= show_rcu,
-+};
-+
-+#endif
-+
---- linux-2.6.0-test1/kernel/sched.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/kernel/sched.c	2003-07-19 17:07:14.000000000 -0700
-@@ -68,14 +68,16 @@
-  */
- #define MIN_TIMESLICE		( 10 * HZ / 1000)
- #define MAX_TIMESLICE		(200 * HZ / 1000)
--#define CHILD_PENALTY		50
-+#define CHILD_PENALTY		95
- #define PARENT_PENALTY		100
- #define EXIT_WEIGHT		3
- #define PRIO_BONUS_RATIO	25
- #define INTERACTIVE_DELTA	2
-+#define MIN_SLEEP_AVG		(HZ)
- #define MAX_SLEEP_AVG		(10*HZ)
- #define STARVATION_LIMIT	(10*HZ)
- #define NODE_THRESHOLD		125
-+#define MAX_BONUS		(MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
- 
- /*
-  * If a task is 'interactive' then we reinsert it in the active
-@@ -176,7 +178,7 @@ struct runqueue {
- static DEFINE_PER_CPU(struct runqueue, runqueues);
- 
- #define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
--#define this_rq()		(&__get_cpu_var(runqueues))
-+#define this_rq()		(cpu_rq(smp_processor_id())) /* not __get_cpu_var(runqueues)! */
- #define task_rq(p)		cpu_rq(task_cpu(p))
- #define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
- #define rt_task(p)		((p)->prio < MAX_RT_PRIO)
-@@ -297,6 +299,26 @@ static inline void enqueue_task(struct t
- 	array->nr_active++;
- 	p->array = array;
- }
-+/*
-+ * normalise_sleep converts a task's sleep_avg to
-+ * an appropriate proportion of MIN_SLEEP_AVG.
-+ */
-+static inline void normalise_sleep(task_t *p)
-+{
-+	unsigned long old_avg_time = jiffies - p->avg_start;
-+
-+	if (unlikely(old_avg_time < MIN_SLEEP_AVG))
-+		return;
-+
-+	if (p->sleep_avg > MAX_SLEEP_AVG)
-+		p->sleep_avg = MAX_SLEEP_AVG;
-+
-+	if (old_avg_time > MAX_SLEEP_AVG)
-+		old_avg_time = MAX_SLEEP_AVG;
-+
-+	p->sleep_avg = p->sleep_avg * MIN_SLEEP_AVG / old_avg_time;
-+	p->avg_start = jiffies - MIN_SLEEP_AVG;
-+}
- 
- /*
-  * effective_prio - return the priority that is based on the static
-@@ -315,11 +337,28 @@ static inline void enqueue_task(struct t
- static int effective_prio(task_t *p)
- {
- 	int bonus, prio;
-+	unsigned long sleep_period;
- 
- 	if (rt_task(p))
- 		return p->prio;
- 
--	bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 -
-+	sleep_period = jiffies - p->avg_start;
-+
-+	if (unlikely(!sleep_period))
-+		return p->static_prio;
-+
-+	if (sleep_period > MAX_SLEEP_AVG)
-+		sleep_period = MAX_SLEEP_AVG;
-+
-+	if (p->sleep_avg > sleep_period)
-+		sleep_period = p->sleep_avg;
-+
-+	/*
-+	 * The bonus is determined according to the accumulated
-+	 * sleep avg over the duration the task has been running
-+	 * until it reaches MAX_SLEEP_AVG. -ck
-+	 */
-+	bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/sleep_period/100 -
- 			MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
- 
- 	prio = p->static_prio - bonus;
-@@ -350,31 +389,47 @@ static inline void activate_task(task_t 
- 	long sleep_time = jiffies - p->last_run - 1;
- 
- 	if (sleep_time > 0) {
--		int sleep_avg;
--
- 		/*
--		 * This code gives a bonus to interactive tasks.
--		 *
--		 * The boost works by updating the 'average sleep time'
--		 * value here, based on ->last_run. The more time a task
--		 * spends sleeping, the higher the average gets - and the
--		 * higher the priority boost gets as well.
-+		 * User tasks that sleep a long time are categorised as idle and
-+		 * will get just under interactive status with a small runtime
-+		 * to allow them to become interactive or non-interactive rapidly
- 		 */
--		sleep_avg = p->sleep_avg + sleep_time;
-+		if (sleep_time > MIN_SLEEP_AVG && p->mm){
-+			p->avg_start = jiffies - MIN_SLEEP_AVG;
-+			p->sleep_avg = MIN_SLEEP_AVG * (MAX_BONUS - INTERACTIVE_DELTA - 2) /
-+				MAX_BONUS;
-+		} else {
-+			unsigned long runtime = jiffies - p->avg_start;
- 
--		/*
--		 * 'Overflow' bonus ticks go to the waker as well, so the
--		 * ticks are not lost. This has the effect of further
--		 * boosting tasks that are related to maximum-interactive
--		 * tasks.
--		 */
--		if (sleep_avg > MAX_SLEEP_AVG)
--			sleep_avg = MAX_SLEEP_AVG;
--		if (p->sleep_avg != sleep_avg) {
--			p->sleep_avg = sleep_avg;
--			p->prio = effective_prio(p);
-+			if (runtime > MAX_SLEEP_AVG)
-+				runtime = MAX_SLEEP_AVG;
-+
-+			/*
-+			 * This code gives a bonus to interactive tasks.
-+			 *
-+			 * The boost works by updating the 'average sleep time'
-+			 * value here, based on ->last_run. The more time a task
-+			 * spends sleeping, the higher the average gets - and the
-+			 * higher the priority boost gets as well.
-+			 */
-+			p->sleep_avg += sleep_time;
-+
-+			/*
-+			 * Processes that sleep get pushed to a higher priority
-+			 * each time they sleep
-+			 */
-+			p->sleep_avg = (p->sleep_avg * MAX_BONUS / runtime + 1) * runtime / MAX_BONUS;
-+
-+			if (p->sleep_avg > MAX_SLEEP_AVG)
-+				p->sleep_avg = MAX_SLEEP_AVG;
-+		}
-+
-+		if (unlikely(p->avg_start > jiffies)){
-+			p->avg_start = jiffies;
-+			p->sleep_avg = 0;
- 		}
- 	}
-+	p->prio = effective_prio(p);
- 	__activate_task(p, rq);
- }
- 
-@@ -489,7 +544,7 @@ repeat_lock_task:
- 			 */
- 			if (unlikely(sync && !task_running(rq, p) &&
- 				(task_cpu(p) != smp_processor_id()) &&
--				(p->cpus_allowed & (1UL << smp_processor_id())))) {
-+				cpu_isset(smp_processor_id(), p->cpus_allowed))) {
- 
- 				set_task_cpu(p, smp_processor_id());
- 				task_rq_unlock(rq, &flags);
-@@ -551,6 +606,7 @@ void wake_up_forked_process(task_t * p)
- 	 * from forking tasks that are max-interactive.
- 	 */
- 	current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100;
-+	normalise_sleep(p);
- 	p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100;
- 	p->prio = effective_prio(p);
- 	set_task_cpu(p, smp_processor_id());
-@@ -591,6 +647,8 @@ void sched_exit(task_t * p)
- 	 * If the child was a (relative-) CPU hog then decrease
- 	 * the sleep_avg of the parent as well.
- 	 */
-+	normalise_sleep(p);
-+	normalise_sleep(p->parent);
- 	if (p->sleep_avg < p->parent->sleep_avg)
- 		p->parent->sleep_avg = (p->parent->sleep_avg * EXIT_WEIGHT +
- 			p->sleep_avg) / (EXIT_WEIGHT + 1);
-@@ -758,13 +816,13 @@ static inline void double_rq_unlock(runq
-  */
- static void sched_migrate_task(task_t *p, int dest_cpu)
- {
--	unsigned long old_mask;
-+	cpumask_t old_mask;
- 
- 	old_mask = p->cpus_allowed;
--	if (!(old_mask & (1UL << dest_cpu)))
-+	if (!cpu_isset(dest_cpu, old_mask))
- 		return;
- 	/* force the process onto the specified CPU */
--	set_cpus_allowed(p, 1UL << dest_cpu);
-+	set_cpus_allowed(p, cpumask_of_cpu(dest_cpu));
- 
- 	/* restore the cpus allowed mask */
- 	set_cpus_allowed(p, old_mask);
-@@ -777,7 +835,7 @@ static void sched_migrate_task(task_t *p
- static int sched_best_cpu(struct task_struct *p)
- {
- 	int i, minload, load, best_cpu, node = 0;
--	unsigned long cpumask;
-+	cpumask_t cpumask;
- 
- 	best_cpu = task_cpu(p);
- 	if (cpu_rq(best_cpu)->nr_running <= 2)
-@@ -801,7 +859,7 @@ static int sched_best_cpu(struct task_st
- 	minload = 10000000;
- 	cpumask = node_to_cpumask(node);
- 	for (i = 0; i < NR_CPUS; ++i) {
--		if (!(cpumask & (1UL << i)))
-+		if (!cpu_isset(i, cpumask))
- 			continue;
- 		if (cpu_rq(i)->nr_running < minload) {
- 			best_cpu = i;
-@@ -888,7 +946,7 @@ static inline unsigned int double_lock_b
- /*
-  * find_busiest_queue - find the busiest runqueue among the cpus in cpumask.
-  */
--static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, unsigned long cpumask)
-+static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, cpumask_t cpumask)
- {
- 	int nr_running, load, max_load, i;
- 	runqueue_t *busiest, *rq_src;
-@@ -923,7 +981,7 @@ static inline runqueue_t *find_busiest_q
- 	busiest = NULL;
- 	max_load = 1;
- 	for (i = 0; i < NR_CPUS; i++) {
--		if (!((1UL << i) & cpumask))
-+		if (!cpu_isset(i, cpumask))
- 			continue;
- 
- 		rq_src = cpu_rq(i);
-@@ -942,10 +1000,10 @@ static inline runqueue_t *find_busiest_q
- 	if (likely(!busiest))
- 		goto out;
- 
--	*imbalance = (max_load - nr_running) / 2;
-+	*imbalance = max_load - nr_running;
- 
- 	/* It needs an at least ~25% imbalance to trigger balancing. */
--	if (!idle && (*imbalance < (max_load + 3)/4)) {
-+	if (!idle && ((*imbalance)*4 < max_load)) {
- 		busiest = NULL;
- 		goto out;
- 	}
-@@ -955,7 +1013,7 @@ static inline runqueue_t *find_busiest_q
- 	 * Make sure nothing changed since we checked the
- 	 * runqueue length.
- 	 */
--	if (busiest->nr_running <= nr_running + 1) {
-+	if (busiest->nr_running <= nr_running) {
- 		spin_unlock(&busiest->lock);
- 		busiest = NULL;
- 	}
-@@ -995,7 +1053,7 @@ static inline void pull_task(runqueue_t 
-  * We call this with the current runqueue locked,
-  * irqs disabled.
-  */
--static void load_balance(runqueue_t *this_rq, int idle, unsigned long cpumask)
-+static void load_balance(runqueue_t *this_rq, int idle, cpumask_t cpumask)
- {
- 	int imbalance, idx, this_cpu = smp_processor_id();
- 	runqueue_t *busiest;
-@@ -1008,6 +1066,12 @@ static void load_balance(runqueue_t *thi
- 		goto out;
- 
- 	/*
-+	 * We only want to steal a number of tasks equal to 1/2 the imbalance,
-+	 * otherwise we'll just shift the imbalance to the new queue:
-+	 */
-+	imbalance /= 2;
-+
-+	/*
- 	 * We first consider expired tasks. Those will likely not be
- 	 * executed in the near future, and they are most likely to
- 	 * be cache-cold, thus switching CPUs has the least effect
-@@ -1049,7 +1113,7 @@ skip_queue:
- #define CAN_MIGRATE_TASK(p,rq,this_cpu)					\
- 	((!idle || (jiffies - (p)->last_run > cache_decay_ticks)) &&	\
- 		!task_running(rq, p) &&					\
--			((p)->cpus_allowed & (1UL << (this_cpu))))
-+			cpu_isset(this_cpu, (p)->cpus_allowed))
- 
- 	curr = curr->prev;
- 
-@@ -1092,10 +1156,10 @@ out:
- static void balance_node(runqueue_t *this_rq, int idle, int this_cpu)
- {
- 	int node = find_busiest_node(cpu_to_node(this_cpu));
--	unsigned long cpumask, this_cpumask = 1UL << this_cpu;
- 
- 	if (node >= 0) {
--		cpumask = node_to_cpumask(node) | this_cpumask;
-+		cpumask_t cpumask = node_to_cpumask(node);
-+		cpu_set(this_cpu, cpumask);
- 		spin_lock(&this_rq->lock);
- 		load_balance(this_rq, idle, cpumask);
- 		spin_unlock(&this_rq->lock);
-@@ -1207,11 +1271,7 @@ void scheduler_tick(int user_ticks, int 
- 	spin_lock(&rq->lock);
- 	/*
- 	 * The task was running during this tick - update the
--	 * time slice counter and the sleep average. Note: we
--	 * do not update a thread's priority until it either
--	 * goes to sleep or uses up its timeslice. This makes
--	 * it possible for interactive tasks to use up their
--	 * timeslices at their highest priority levels.
-+	 * time slice counter and the sleep average.
- 	 */
- 	if (p->sleep_avg)
- 		p->sleep_avg--;
-@@ -1244,6 +1304,17 @@ void scheduler_tick(int user_ticks, int 
- 			enqueue_task(p, rq->expired);
- 		} else
- 			enqueue_task(p, rq->active);
-+	} else if (p->mm && !((task_timeslice(p) - p->time_slice) %
-+		 (MIN_TIMESLICE * (MAX_BONUS + 1 - p->sleep_avg * MAX_BONUS / MAX_SLEEP_AVG)))){
-+		/*
-+		 * Running user tasks get requeued with their remaining timeslice
-+		 * after a period proportional to how cpu intensive they are to
-+		 * minimise the duration one interactive task can starve another
-+		 */
-+		dequeue_task(p, rq->active);
-+		set_tsk_need_resched(p);
-+		p->prio = effective_prio(p);
-+		enqueue_task(p, rq->active);
- 	}
- out_unlock:
- 	spin_unlock(&rq->lock);
-@@ -1606,6 +1677,13 @@ out_unlock:
- 	task_rq_unlock(rq, &flags);
- }
- 
-+#if defined( CONFIG_KGDB) 
-+struct task_struct * kgdb_get_idle(int this_cpu)
-+{
-+        return cpu_rq(this_cpu)->idle;
-+}
-+#endif
-+
- #ifndef __alpha__
- 
- /*
-@@ -1898,7 +1976,7 @@ out_unlock:
- asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
- 				      unsigned long __user *user_mask_ptr)
- {
--	unsigned long new_mask;
-+	cpumask_t new_mask;
- 	int retval;
- 	task_t *p;
- 
-@@ -1946,7 +2024,7 @@ asmlinkage long sys_sched_getaffinity(pi
- 				      unsigned long __user *user_mask_ptr)
- {
- 	unsigned int real_len;
--	unsigned long mask;
-+	cpumask_t mask;
- 	int retval;
- 	task_t *p;
- 
-@@ -1962,7 +2040,7 @@ asmlinkage long sys_sched_getaffinity(pi
- 		goto out_unlock;
- 
- 	retval = 0;
--	mask = p->cpus_allowed & cpu_online_map;
-+	cpus_and(mask, p->cpus_allowed, cpu_online_map);
- 
- out_unlock:
- 	read_unlock(&tasklist_lock);
-@@ -2080,7 +2158,7 @@ asmlinkage long sys_sched_get_priority_m
- }
- 
- /**
-- * sys_sched_get_priority_mix - return minimum RT priority.
-+ * sys_sched_get_priority_min - return minimum RT priority.
-  * @policy: scheduling class.
-  *
-  * this syscall returns the minimum rt_priority that can be used
-@@ -2159,17 +2237,16 @@ static inline struct task_struct *younge
- 
- static void show_task(task_t * p)
- {
--	unsigned long free = 0;
- 	task_t *relative;
--	int state;
--	static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
-+	unsigned state;
-+	static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
- 
- 	printk("%-13.13s ", p->comm);
- 	state = p->state ? __ffs(p->state) + 1 : 0;
--	if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
-+	if (state < ARRAY_SIZE(stat_nam))
- 		printk(stat_nam[state]);
- 	else
--		printk(" ");
-+		printk("?");
- #if (BITS_PER_LONG == 32)
- 	if (p == current)
- 		printk(" current  ");
-@@ -2181,13 +2258,7 @@ static void show_task(task_t * p)
- 	else
- 		printk(" %016lx ", thread_saved_pc(p));
- #endif
--	{
--		unsigned long * n = (unsigned long *) (p->thread_info+1);
--		while (!*n)
--			n++;
--		free = (unsigned long) n - (unsigned long)(p+1);
--	}
--	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
-+	printk("%5d %6d ", p->pid, p->parent->pid);
- 	if ((relative = eldest_child(p)))
- 		printk("%5d ", relative->pid);
- 	else
-@@ -2214,12 +2285,12 @@ void show_state(void)
- 
- #if (BITS_PER_LONG == 32)
- 	printk("\n"
--	       "                         free                        sibling\n");
--	printk("  task             PC    stack   pid father child younger older\n");
-+	       "                                               sibling\n");
-+	printk("  task             PC      pid father child younger older\n");
- #else
- 	printk("\n"
--	       "                                 free                        sibling\n");
--	printk("  task                 PC        stack   pid father child younger older\n");
-+	       "                                                       sibling\n");
-+	printk("  task                 PC          pid father child younger older\n");
- #endif
- 	read_lock(&tasklist_lock);
- 	do_each_thread(g, p) {
-@@ -2292,7 +2363,7 @@ typedef struct {
-  * task must not exit() & deallocate itself prematurely.  The
-  * call is not atomic; no spinlocks may be held.
-  */
--int set_cpus_allowed(task_t *p, unsigned long new_mask)
-+int set_cpus_allowed(task_t *p, cpumask_t new_mask)
- {
- 	unsigned long flags;
- 	migration_req_t req;
-@@ -2307,7 +2378,7 @@ int set_cpus_allowed(task_t *p, unsigned
- 	 * Can the task run on the task's current CPU? If not then
- 	 * migrate the thread off to a proper CPU.
- 	 */
--	if (new_mask & (1UL << task_cpu(p))) {
-+	if (cpu_isset(task_cpu(p), new_mask)) {
- 		task_rq_unlock(rq, &flags);
- 		return 0;
- 	}
-@@ -2377,7 +2448,7 @@ static int migration_thread(void * data)
- 	 * migration thread on this CPU, guaranteed (we're started
- 	 * serially).
- 	 */
--	set_cpus_allowed(current, 1UL << cpu);
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 
- 	ret = setscheduler(0, SCHED_FIFO, &param);
- 
-@@ -2541,7 +2612,7 @@ void __might_sleep(char *file, int line)
- 		if (time_before(jiffies, prev_jiffy + HZ))
- 			return;
- 		prev_jiffy = jiffies;
--		printk(KERN_ERR "Debug: sleeping function called from illegal"
-+		printk(KERN_ERR "Debug: sleeping function called from invalid"
- 				" context at %s:%d\n", file, line);
- 		dump_stack();
- 	}
---- linux-2.6.0-test1/kernel/softirq.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/kernel/softirq.c	2003-07-19 17:04:53.000000000 -0700
-@@ -59,11 +59,22 @@ static inline void wakeup_softirqd(void)
- 		wake_up_process(tsk);
- }
- 
-+/*
-+ * We restart softirq processing MAX_SOFTIRQ_RESTART times,
-+ * and we fall back to softirqd after that.
-+ *
-+ * This number has been established via experimentation.
-+ * The two things to balance is latency against fairness -
-+ * we want to handle softirqs as soon as possible, but they
-+ * should not be able to lock up the box.
-+ */
-+#define MAX_SOFTIRQ_RESTART 10
-+
- asmlinkage void do_softirq(void)
- {
-+	int max_restart = MAX_SOFTIRQ_RESTART;
- 	__u32 pending;
- 	unsigned long flags;
--	__u32 mask;
- 
- 	if (in_interrupt())
- 		return;
-@@ -75,7 +86,6 @@ asmlinkage void do_softirq(void)
- 	if (pending) {
- 		struct softirq_action *h;
- 
--		mask = ~pending;
- 		local_bh_disable();
- restart:
- 		/* Reset the pending bitmask before enabling irqs */
-@@ -95,10 +105,8 @@ restart:
- 		local_irq_disable();
- 
- 		pending = local_softirq_pending();
--		if (pending & mask) {
--			mask &= ~pending;
-+		if (pending && --max_restart)
- 			goto restart;
--		}
- 		if (pending)
- 			wakeup_softirqd();
- 		__local_bh_enable();
-@@ -322,9 +330,8 @@ static int ksoftirqd(void * __bind_cpu)
- 	current->flags |= PF_IOTHREAD;
- 
- 	/* Migrate to the right CPU */
--	set_cpus_allowed(current, 1UL << cpu);
--	if (smp_processor_id() != cpu)
--		BUG();
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
-+	BUG_ON(smp_processor_id() != cpu);
- 
- 	__set_current_state(TASK_INTERRUPTIBLE);
- 	mb();
---- linux-2.6.0-test1/kernel/suspend.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/kernel/suspend.c	2003-07-19 17:03:51.000000000 -0700
-@@ -52,7 +52,6 @@
- #include <linux/genhd.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
--#include <linux/blk.h>
- #include <linux/swap.h>
- #include <linux/pm.h>
- #include <linux/device.h>
---- linux-2.6.0-test1/kernel/sys.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/kernel/sys.c	2003-07-19 17:03:51.000000000 -0700
-@@ -601,6 +601,14 @@ static int set_user(uid_t new_ruid, int 
- 	new_user = alloc_uid(new_ruid);
- 	if (!new_user)
- 		return -EAGAIN;
-+
-+	if (atomic_read(&new_user->processes) >=
-+				current->rlim[RLIMIT_NPROC].rlim_cur &&
-+			new_user != &root_user) {
-+		free_uid(new_user);
-+		return -EAGAIN;
-+	}
-+
- 	switch_uid(new_user);
- 
- 	if(dumpclear)
-@@ -1159,6 +1167,7 @@ asmlinkage long sys_newuname(struct new_
- asmlinkage long sys_sethostname(char __user *name, int len)
- {
- 	int errno;
-+	char tmp[__NEW_UTS_LEN];
- 
- 	if (!capable(CAP_SYS_ADMIN))
- 		return -EPERM;
-@@ -1166,7 +1175,8 @@ asmlinkage long sys_sethostname(char __u
- 		return -EINVAL;
- 	down_write(&uts_sem);
- 	errno = -EFAULT;
--	if (!copy_from_user(system_utsname.nodename, name, len)) {
-+	if (!copy_from_user(tmp, name, len)) {
-+		memcpy(system_utsname.nodename, tmp, len);
- 		system_utsname.nodename[len] = 0;
- 		errno = 0;
- 	}
-@@ -1198,6 +1208,7 @@ asmlinkage long sys_gethostname(char __u
- asmlinkage long sys_setdomainname(char __user *name, int len)
- {
- 	int errno;
-+	char tmp[__NEW_UTS_LEN];
- 
- 	if (!capable(CAP_SYS_ADMIN))
- 		return -EPERM;
-@@ -1206,9 +1217,10 @@ asmlinkage long sys_setdomainname(char _
- 
- 	down_write(&uts_sem);
- 	errno = -EFAULT;
--	if (!copy_from_user(system_utsname.domainname, name, len)) {
--		errno = 0;
-+	if (!copy_from_user(tmp, name, len)) {
-+		memcpy(system_utsname.domainname, tmp, len);
- 		system_utsname.domainname[len] = 0;
-+		errno = 0;
- 	}
- 	up_write(&uts_sem);
- 	return errno;
---- linux-2.6.0-test1/kernel/time.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/kernel/time.c	2003-07-19 17:03:51.000000000 -0700
-@@ -66,7 +66,7 @@ asmlinkage long sys_time(int * tloc)
-  * architectures that need it).
-  */
-  
--asmlinkage long sys_stime(int * tptr)
-+asmlinkage long sys_stime(time_t *tptr)
- {
- 	struct timespec tv;
- 
-@@ -160,22 +160,25 @@ int do_sys_settimeofday(struct timespec 
- 	return 0;
- }
- 
--asmlinkage long sys_settimeofday(struct timeval __user *tv, struct timezone __user *tz)
-+asmlinkage long sys_settimeofday(struct timeval __user *tv,
-+				struct timezone __user *tz)
- {
--	struct timespec	new_tv;
-+	struct timeval user_tv;
-+	struct timespec	new_ts;
- 	struct timezone new_tz;
- 
- 	if (tv) {
--		if (copy_from_user(&new_tv, tv, sizeof(*tv)))
-+		if (copy_from_user(&user_tv, tv, sizeof(*tv)))
- 			return -EFAULT;
--		new_tv.tv_nsec *= NSEC_PER_USEC;
-+		new_ts.tv_sec = user_tv.tv_sec;
-+		new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
- 	}
- 	if (tz) {
- 		if (copy_from_user(&new_tz, tz, sizeof(*tz)))
- 			return -EFAULT;
- 	}
- 
--	return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
-+	return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
- }
- 
- long pps_offset;		/* pps time offset (us) */
---- linux-2.6.0-test1/kernel/timer.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/kernel/timer.c	2003-07-19 17:04:53.000000000 -0700
-@@ -160,7 +160,7 @@ static void internal_add_timer(tvec_base
-  */
- void add_timer(struct timer_list *timer)
- {
--	tvec_base_t *base = &get_cpu_var(tvec_bases);
-+	tvec_base_t *base = &per_cpu(tvec_bases, get_cpu());
-   	unsigned long flags;
-   
-   	BUG_ON(timer_pending(timer) || !timer->function);
-@@ -171,7 +171,7 @@ void add_timer(struct timer_list *timer)
- 	internal_add_timer(base, timer);
- 	timer->base = base;
- 	spin_unlock_irqrestore(&base->lock, flags);
--	put_cpu_var(tvec_bases);
-+	put_cpu();
- }
- 
- /***
-@@ -234,7 +234,7 @@ int mod_timer(struct timer_list *timer, 
- 		return 1;
- 
- 	spin_lock_irqsave(&timer->lock, flags);
--	new_base = &__get_cpu_var(tvec_bases);
-+	new_base = &per_cpu(tvec_bases, smp_processor_id());
- repeat:
- 	old_base = timer->base;
- 
-@@ -792,7 +792,7 @@ seqlock_t xtime_lock __cacheline_aligned
-  */
- static void run_timer_softirq(struct softirq_action *h)
- {
--	tvec_base_t *base = &__get_cpu_var(tvec_bases);
-+	tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id());
- 
- 	if (time_after_eq(jiffies, base->timer_jiffies))
- 		__run_timers(base);
---- linux-2.6.0-test1/kernel/workqueue.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/kernel/workqueue.c	2003-07-19 17:04:07.000000000 -0700
-@@ -176,7 +176,7 @@ static int worker_thread(void *__startup
- 	cwq->thread = current;
- 
- 	set_user_nice(current, -10);
--	set_cpus_allowed(current, 1UL << cpu);
-+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
- 
- 	complete(&startup->done);
- 
---- linux-2.6.0-test1/MAINTAINERS	2003-07-13 21:44:34.000000000 -0700
-+++ 25/MAINTAINERS	2003-07-19 17:04:55.000000000 -0700
-@@ -657,6 +657,11 @@ L:	emu10k1-devel@lists.sourceforge.net
- W:	http://sourceforge.net/projects/emu10k1/
- S:	Maintained
- 
-+EPSON 1355 FRAMEBUFFER DRIVER
-+P:	Christopher Hoover
-+M:	ch@murgatroid.com, ch@hpl.hp.com
-+S:	Maintained
-+
- ETHEREXPRESS-16 NETWORK DRIVER
- P:	Philip Blundell
- M:	Philip.Blundell@pobox.com
-@@ -973,7 +978,7 @@ M:	scott.feldman@intel.com
- S:	Supported
- 
- INTERMEZZO FILE SYSTEM
--P:	Chen Yang
-+P:	Cluster File Systems	
- M:	intermezzo-devel@lists.sf.net
- W:	http://www.inter-mezzo.org/
- L:	intermezzo-discuss@lists.sourceforge.net
-@@ -1076,6 +1081,12 @@ L:	kbuild-devel@lists.sourceforge.net
- W:	http://kbuild.sourceforge.net
- S:	Maintained 
- 
-+KGDB FOR I386 PLATFORM
-+P:	George Anzinger
-+M:	george@mvista.com
-+L:	linux-net@vger.kernel.org
-+S:	Supported
-+
- KERNEL NFSD
- P:	Neil Brown
- M:	neilb@cse.unsw.edu.au
---- linux-2.6.0-test1/Makefile	2003-07-13 21:44:34.000000000 -0700
-+++ 25/Makefile	2003-07-19 17:03:58.000000000 -0700
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 6
- SUBLEVEL = 0
--EXTRAVERSION = -test1
-+EXTRAVERSION = -test1-mm2
- 
- # *DOCUMENTATION*
- # To see a list of typical targets execute "make help"
-@@ -781,7 +781,8 @@ rpm:	clean spec
- 	tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
- 	rm $(KERNELPATH) ; \
- 	cd $(TOPDIR) ; \
--	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > .version ; \
-+	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > .tmp_version ; \
-+	mv -f .tmp_version .version; \
- 	$(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
- 	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
- 
---- linux-2.6.0-test1/mm/bootmem.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/mm/bootmem.c	2003-07-19 17:03:51.000000000 -0700
-@@ -183,7 +183,7 @@ restart_scan:
- 	for (i = preferred; i < eidx; i += incr) {
- 		unsigned long j;
- 		i = find_next_zero_bit(bdata->node_bootmem_map, eidx, i);
--		i = (i + incr - 1) & -incr;
-+		i = ALIGN(i, incr);
- 		if (test_bit(i, bdata->node_bootmem_map))
- 			continue;
- 		for (j = i + 1; j < i + areasize; ++j) {
-@@ -195,7 +195,7 @@ restart_scan:
- 		start = i;
- 		goto found;
- 	fail_block:
--		;
-+		i = ALIGN(j, incr);
- 	}
- 
- 	if (preferred > offset) {
---- linux-2.6.0-test1/mm/filemap.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/mm/filemap.c	2003-07-19 17:07:03.000000000 -0700
-@@ -265,21 +265,42 @@ static wait_queue_head_t *page_waitqueue
- 	return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
- }
- 
--void wait_on_page_bit(struct page *page, int bit_nr)
-+/*
-+ * wait for the specified page bit to be cleared
-+ * this could be a synchronous wait or could just queue an async
-+ * notification callback depending on the wait queue entry parameter
-+ *
-+ * A NULL wait queue parameter defaults to sync behaviour
-+ */
-+int wait_on_page_bit_wq(struct page *page, int bit_nr, wait_queue_t *wait)
- {
- 	wait_queue_head_t *waitqueue = page_waitqueue(page);
--	DEFINE_WAIT(wait);
-+	DEFINE_WAIT(local_wait);
-+
-+	if (!wait)
-+		wait = &local_wait; /* default to a sync wait entry */
- 
- 	do {
--		prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(waitqueue, wait, TASK_UNINTERRUPTIBLE);
- 		if (test_bit(bit_nr, &page->flags)) {
- 			sync_page(page);
-+			if (!is_sync_wait(wait)) {
-+				/*
-+				 * if we've queued an async wait queue
-+				 * callback do not block; just tell the
-+				 * caller to return and retry later when
-+				 * the callback is notified
-+				 */
-+				return -EIOCBRETRY;
-+			}
- 			io_schedule();
- 		}
- 	} while (test_bit(bit_nr, &page->flags));
--	finish_wait(waitqueue, &wait);
-+	finish_wait(waitqueue, wait);
-+
-+	return 0;
- }
--EXPORT_SYMBOL(wait_on_page_bit);
-+EXPORT_SYMBOL(wait_on_page_bit_wq);
- 
- /**
-  * unlock_page() - unlock a locked page
-@@ -289,7 +310,9 @@ EXPORT_SYMBOL(wait_on_page_bit);
-  * Unlocks the page and wakes up sleepers in ___wait_on_page_locked().
-  * Also wakes sleepers in wait_on_page_writeback() because the wakeup
-  * mechananism between PageLocked pages and PageWriteback pages is shared.
-- * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
-+ * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep,
-+ * or in case the wakeup notifies async wait queue entries, as in the case
-+ * of aio, retries would be triggered and may re-queue their callbacks.
-  *
-  * The first mb is necessary to safely close the critical section opened by the
-  * TestSetPageLocked(), the second mb is necessary to enforce ordering between
-@@ -326,26 +349,51 @@ void end_page_writeback(struct page *pag
- EXPORT_SYMBOL(end_page_writeback);
- 
- /*
-- * Get a lock on the page, assuming we need to sleep to get it.
-+ * Get a lock on the page, assuming we need to either sleep to get it
-+ * or to queue an async notification callback to try again when its
-+ * available.
-+ *
-+ * A NULL wait queue parameter defaults to sync behaviour. Otherwise
-+ * it specifies the wait queue entry to be used for async notification
-+ * or waiting.
-  *
-  * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary.  If some
-  * random driver's requestfn sets TASK_RUNNING, we could busywait.  However
-  * chances are that on the second loop, the block layer's plug list is empty,
-  * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
-  */
--void __lock_page(struct page *page)
-+int __lock_page_wq(struct page *page, wait_queue_t *wait)
- {
- 	wait_queue_head_t *wqh = page_waitqueue(page);
--	DEFINE_WAIT(wait);
-+	DEFINE_WAIT(local_wait);
-+
-+	if (!wait)
-+		wait = &local_wait;
- 
- 	while (TestSetPageLocked(page)) {
--		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
- 		if (PageLocked(page)) {
- 			sync_page(page);
-+			if (!is_sync_wait(wait)) {
-+				/*
-+				 * if we've queued an async wait queue
-+				 * callback do not block; just tell the
-+				 * caller to return and retry later when
-+				 * the callback is notified
-+				 */
-+				return -EIOCBRETRY;
-+			}
- 			io_schedule();
- 		}
- 	}
--	finish_wait(wqh, &wait);
-+	finish_wait(wqh, wait);
-+	return 0;
-+}
-+EXPORT_SYMBOL(__lock_page_wq);
-+
-+void __lock_page(struct page *page)
-+{
-+	__lock_page_wq(page, NULL);
- }
- EXPORT_SYMBOL(__lock_page);
- 
-@@ -395,8 +443,8 @@ struct page *find_trylock_page(struct ad
-  *
-  * Returns zero if the page was not present. find_lock_page() may sleep.
-  */
--struct page *find_lock_page(struct address_space *mapping,
--				unsigned long offset)
-+struct page *find_lock_page_wq(struct address_space *mapping,
-+				unsigned long offset, wait_queue_t *wait)
- {
- 	struct page *page;
- 
-@@ -407,7 +455,10 @@ repeat:
- 		page_cache_get(page);
- 		if (TestSetPageLocked(page)) {
- 			spin_unlock(&mapping->page_lock);
--			lock_page(page);
-+			if (-EIOCBRETRY == lock_page_wq(page, wait)) {
-+				page_cache_release(page);
-+				return ERR_PTR(-EIOCBRETRY);
-+			}
- 			spin_lock(&mapping->page_lock);
- 
- 			/* Has the page been truncated while we slept? */
-@@ -422,6 +473,12 @@ repeat:
- 	return page;
- }
- 
-+struct page *find_lock_page(struct address_space *mapping,
-+				unsigned long offset)
-+{
-+	return find_lock_page_wq(mapping, offset, NULL);
-+}
-+
- /**
-  * find_or_create_page - locate or add a pagecache page
-  *
-@@ -544,21 +601,39 @@ void do_generic_mapping_read(struct addr
- 			     read_actor_t actor)
- {
- 	struct inode *inode = mapping->host;
--	unsigned long index, offset;
-+	unsigned long index, offset, last, end_index;
- 	struct page *cached_page;
-+	loff_t isize = i_size_read(inode);
- 	int error;
- 
- 	cached_page = NULL;
- 	index = *ppos >> PAGE_CACHE_SHIFT;
- 	offset = *ppos & ~PAGE_CACHE_MASK;
- 
-+	last = (*ppos + desc->count) >> PAGE_CACHE_SHIFT;
-+	end_index = isize >> PAGE_CACHE_SHIFT;
-+	if (last > end_index)
-+		last = end_index;
-+
-+	/* Don't repeat the readahead if we are executing aio retries */
-+	if (in_aio()) {
-+		if (is_retried_kiocb(io_wait_to_kiocb(current->io_wait)))
-+			goto done_readahead;
-+	}
-+
-+	/*
-+	 * Let the readahead logic know upfront about all
-+	 * the pages we'll need to satisfy this request
-+	 */
-+	for (; index < last; index++)
-+		page_cache_readahead(mapping, ra, filp, index);
-+	index = *ppos >> PAGE_CACHE_SHIFT;
-+
-+done_readahead:
- 	for (;;) {
- 		struct page *page;
--		unsigned long end_index, nr, ret;
--		loff_t isize = i_size_read(inode);
-+		unsigned long nr, ret;
- 
--		end_index = isize >> PAGE_CACHE_SHIFT;
--			
- 		if (index > end_index)
- 			break;
- 		nr = PAGE_CACHE_SIZE;
-@@ -569,7 +644,6 @@ void do_generic_mapping_read(struct addr
- 		}
- 
- 		cond_resched();
--		page_cache_readahead(mapping, ra, filp, index);
- 
- 		nr = nr - offset;
- find_page:
-@@ -619,7 +693,12 @@ page_not_up_to_date:
- 			goto page_ok;
- 
- 		/* Get exclusive access to the page ... */
--		lock_page(page);
-+
-+		if (lock_page_wq(page, current->io_wait)) {
-+			pr_debug("queued lock page \n");
-+			error = -EIOCBRETRY;
-+			goto sync_error;
-+		}
- 
- 		/* Did it get unhashed before we got the lock? */
- 		if (!page->mapping) {
-@@ -641,13 +720,23 @@ readpage:
- 		if (!error) {
- 			if (PageUptodate(page))
- 				goto page_ok;
--			wait_on_page_locked(page);
-+			if (wait_on_page_locked_wq(page, current->io_wait)) {
-+				pr_debug("queued wait_on_page \n");
-+				error = -EIOCBRETRY;
-+				goto sync_error;
-+			}
-+
- 			if (PageUptodate(page))
- 				goto page_ok;
- 			error = -EIO;
- 		}
- 
--		/* UHHUH! A synchronous read error occurred. Report it */
-+sync_error:
-+		/* We don't have uptodate data in the page yet */
-+		/* Could be due to an error or because we need to
-+		 * retry when we get an async i/o notification.
-+		 * Report the reason.
-+		 */
- 		desc->error = error;
- 		page_cache_release(page);
- 		break;
-@@ -1385,7 +1474,9 @@ __grab_cache_page(struct address_space *
- 	int err;
- 	struct page *page;
- repeat:
--	page = find_lock_page(mapping, index);
-+	page = find_lock_page_wq(mapping, index, current->io_wait);
-+	if (IS_ERR(page))
-+		return page;
- 	if (!page) {
- 		if (!*cached_page) {
- 			*cached_page = page_cache_alloc(mapping);
-@@ -1672,7 +1763,6 @@ generic_file_aio_write_nolock(struct kio
- 	if (err)
- 		goto out;
- 
--
- 	if (count == 0)
- 		goto out;
- 
-@@ -1726,6 +1816,10 @@ generic_file_aio_write_nolock(struct kio
- 		fault_in_pages_readable(buf, bytes);
- 
- 		page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
-+		if (IS_ERR(page)) {
-+			status = PTR_ERR(page);
-+			break;
-+		}
- 		if (!page) {
- 			status = -ENOMEM;
- 			break;
-@@ -1776,7 +1870,11 @@ generic_file_aio_write_nolock(struct kio
- 		page_cache_release(page);
- 		if (status < 0)
- 			break;
--		balance_dirty_pages_ratelimited(mapping);
-+		status = balance_dirty_pages_ratelimited(mapping);
-+		if (status < 0) {
-+			pr_debug("async balance_dirty_pages\n");
-+			break;
-+		}
- 		cond_resched();
- 	} while (count);
- 	*ppos = pos;
-@@ -1787,12 +1885,14 @@ generic_file_aio_write_nolock(struct kio
- 	/*
- 	 * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
- 	 */
--	if (status >= 0) {
--		if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
--			status = generic_osync_inode(inode,
--					OSYNC_METADATA|OSYNC_DATA);
-+	if (likely(status >= 0)) {
-+		if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-+			if (!a_ops->writepage)
-+				status = generic_osync_inode(inode,
-+						OSYNC_METADATA|OSYNC_DATA);
-+		}
- 	}
--	
-+
- out_status:	
- 	err = written ? written : status;
- out:
-@@ -1819,18 +1919,43 @@ ssize_t generic_file_aio_write(struct ki
- 			       size_t count, loff_t pos)
- {
- 	struct file *file = iocb->ki_filp;
--	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
--	ssize_t err;
--	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
-+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-+	struct inode *inode = mapping->host;
-+	ssize_t ret;
-+	struct iovec local_iov = { .iov_base = (void __user *)buf,
-+					.iov_len = count };
- 
- 	BUG_ON(iocb->ki_pos != pos);
- 
-+	if (!buf && !is_sync_kiocb(iocb)) {
-+		/* nothing to transfer, may just need to sync data */
-+		ret = count;
-+		goto osync;
-+	}
-+
- 	down(&inode->i_sem);
--	err = generic_file_aio_write_nolock(iocb, &local_iov, 1, 
-+	ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
- 						&iocb->ki_pos);
- 	up(&inode->i_sem);
- 
--	return err;
-+	/*
-+	 * Avoid doing a sync in parts for aio - its more efficient to
-+	 * call in again after all the data has been copied
-+	 */
-+	if (!is_sync_kiocb(iocb))
-+		return ret;
-+
-+osync:
-+	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-+		ssize_t err;
-+
-+		err = sync_page_range(inode, mapping, pos, ret);
-+		if (err < 0)
-+			ret = err;
-+		else
-+			iocb->ki_pos = pos + err;
-+	}
-+	return ret;
- }
- EXPORT_SYMBOL(generic_file_aio_write);
- EXPORT_SYMBOL(generic_file_aio_write_nolock);
-@@ -1838,15 +1963,24 @@ EXPORT_SYMBOL(generic_file_aio_write_nol
- ssize_t generic_file_write(struct file *file, const char __user *buf,
- 			   size_t count, loff_t *ppos)
- {
--	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
--	ssize_t		err;
--	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
-+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-+	struct inode *inode = mapping->host;
-+	ssize_t	ret;
-+	struct iovec local_iov = { .iov_base = (void __user *)buf,
-+					.iov_len = count };
- 
- 	down(&inode->i_sem);
--	err = generic_file_write_nolock(file, &local_iov, 1, ppos);
-+	ret = generic_file_write_nolock(file, &local_iov, 1, ppos);
- 	up(&inode->i_sem);
- 
--	return err;
-+	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-+		ssize_t err;
-+
-+		err = sync_page_range(inode, mapping, *ppos - ret, ret);
-+		if (err < 0)
-+			ret = err;
-+	}
-+	return ret;
- }
- 
- ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
-@@ -1863,7 +1997,7 @@ ssize_t generic_file_readv(struct file *
- }
- 
- ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
--			unsigned long nr_segs, loff_t * ppos) 
-+			unsigned long nr_segs, loff_t *ppos)
- {
- 	struct inode *inode = file->f_dentry->d_inode;
- 	ssize_t ret;
-@@ -1871,6 +2005,15 @@ ssize_t generic_file_writev(struct file 
- 	down(&inode->i_sem);
- 	ret = generic_file_write_nolock(file, iov, nr_segs, ppos);
- 	up(&inode->i_sem);
-+
-+	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-+		ssize_t err;
-+
-+		err = sync_page_range(inode, inode->i_mapping,
-+					*ppos - ret, ret);
-+		if (err < 0)
-+			ret = err;
-+	}
- 	return ret;
- }
- 
---- linux-2.6.0-test1/mm/fremap.c	2003-06-14 12:17:56.000000000 -0700
-+++ 25/mm/fremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -67,11 +67,11 @@ int install_page(struct mm_struct *mm, s
- 	pgd = pgd_offset(mm, addr);
- 	spin_lock(&mm->page_table_lock);
- 
--	pmd = pmd_alloc(mm, pgd, addr);
-+	pmd = pmd_alloc_map(mm, pgd, addr);
- 	if (!pmd)
- 		goto err_unlock;
- 
--	pte = pte_alloc_map(mm, pmd, addr);
-+	pte = pte_alloc_map(mm, pgd, &pmd, addr);
- 	if (!pte)
- 		goto err_unlock;
- 
-@@ -82,6 +82,7 @@ int install_page(struct mm_struct *mm, s
- 	set_pte(pte, mk_pte(page, prot));
- 	pte_chain = page_add_rmap(page, pte, pte_chain);
- 	pte_unmap(pte);
-+	pmd_unmap(pmd);
- 	if (flush)
- 		flush_tlb_page(vma, addr);
- 	update_mmu_cache(vma, addr, *pte);
---- linux-2.6.0-test1/mm/memory.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/mm/memory.c	2003-07-19 17:07:16.000000000 -0700
-@@ -104,6 +104,7 @@ static inline void free_one_pgd(struct m
- {
- 	int j;
- 	pmd_t * pmd;
-+	struct page *page;
- 
- 	if (pgd_none(*dir))
- 		return;
-@@ -112,11 +113,13 @@ static inline void free_one_pgd(struct m
- 		pgd_clear(dir);
- 		return;
- 	}
--	pmd = pmd_offset(dir, 0);
-+	page = pgd_page(*dir);
-+	pmd = pmd_offset_map(dir, 0);
- 	pgd_clear(dir);
- 	for (j = 0; j < PTRS_PER_PMD ; j++)
- 		free_one_pmd(tlb, pmd+j);
--	pmd_free_tlb(tlb, pmd);
-+	pmd_unmap(pmd);
-+	pmd_free_tlb(tlb, page);
- }
- 
- /*
-@@ -136,30 +139,38 @@ void clear_page_tables(struct mmu_gather
- 	} while (--nr);
- }
- 
--pte_t * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
-+/*
-+ * error return happens with pmd unmapped
-+ */
-+pte_t *pte_alloc_map(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd, unsigned long addr)
- {
--	if (!pmd_present(*pmd)) {
-+	if (!pmd_present(**pmd)) {
- 		struct page *new;
- 
-+		pmd_unmap(*pmd);
- 		spin_unlock(&mm->page_table_lock);
--		new = pte_alloc_one(mm, address);
-+		new = pte_alloc_one(mm, addr);
- 		spin_lock(&mm->page_table_lock);
--		if (!new)
-+		if (!new) {
-+			*pmd = NULL;
- 			return NULL;
-+		}
-+
-+		*pmd = pmd_offset_map(pgd, addr);
- 
- 		/*
- 		 * Because we dropped the lock, we should re-check the
- 		 * entry, as somebody else could have populated it..
- 		 */
--		if (pmd_present(*pmd)) {
-+		if (pmd_present(**pmd)) {
- 			pte_free(new);
- 			goto out;
- 		}
--		pgtable_add_rmap(new, mm, address);
--		pmd_populate(mm, pmd, new);
-+		pgtable_add_rmap(new, mm, addr);
-+		pmd_populate(mm, *pmd, new);
- 	}
- out:
--	return pte_offset_map(pmd, address);
-+	return pte_offset_map(*pmd, addr);
- }
- 
- pte_t * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
-@@ -199,7 +210,7 @@ out:
-  *         variable count and make things faster. -jj
-  *
-  * dst->page_table_lock is held on entry and exit,
-- * but may be dropped within pmd_alloc() and pte_alloc_map().
-+ * but may be dropped within pmd_alloc_map() and pte_alloc_map().
-  */
- int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
- 			struct vm_area_struct *vma)
-@@ -244,11 +255,10 @@ skip_copy_pmd_range:	address = (address 
- 			continue;
- 		}
- 
--		src_pmd = pmd_offset(src_pgd, address);
--		dst_pmd = pmd_alloc(dst, dst_pgd, address);
-+		dst_pmd = pmd_alloc_map(dst, dst_pgd, address);
- 		if (!dst_pmd)
- 			goto nomem;
--
-+		src_pmd = pmd_offset_map_nested(src_pgd, address);
- 		do {
- 			pte_t * src_pte, * dst_pte;
- 		
-@@ -261,15 +271,20 @@ skip_copy_pmd_range:	address = (address 
- 				pmd_clear(src_pmd);
- skip_copy_pte_range:
- 				address = (address + PMD_SIZE) & PMD_MASK;
--				if (address >= end)
-+				if (address >= end) {
-+					pmd_unmap(dst_pmd);
-+					pmd_unmap_nested(src_pmd);
- 					goto out;
-+				}
- 				goto cont_copy_pmd_range;
- 			}
- 
--			dst_pte = pte_alloc_map(dst, dst_pmd, address);
-+			pmd_unmap_nested(src_pmd);
-+			dst_pte = pte_alloc_map(dst, dst_pgd, &dst_pmd, address);
- 			if (!dst_pte)
- 				goto nomem;
- 			spin_lock(&src->page_table_lock);	
-+			src_pmd = pmd_offset_map_nested(src_pgd, address);
- 			src_pte = pte_offset_map_nested(src_pmd, address);
- 			do {
- 				pte_t pte = *src_pte;
-@@ -336,6 +351,8 @@ skip_copy_pte_range:
- 				 */
- 				pte_unmap_nested(src_pte);
- 				pte_unmap(dst_pte);
-+				pmd_unmap_nested(src_pmd);
-+				pmd_unmap(dst_pmd);
- 				spin_unlock(&src->page_table_lock);	
- 				spin_unlock(&dst->page_table_lock);	
- 				pte_chain = pte_chain_alloc(GFP_KERNEL);
-@@ -343,12 +360,16 @@ skip_copy_pte_range:
- 				if (!pte_chain)
- 					goto nomem;
- 				spin_lock(&src->page_table_lock);
-+				dst_pmd = pmd_offset_map(dst_pgd, address);
-+				src_pmd = pmd_offset_map_nested(src_pgd, address);
- 				dst_pte = pte_offset_map(dst_pmd, address);
- 				src_pte = pte_offset_map_nested(src_pmd,
- 								address);
- cont_copy_pte_range_noset:
- 				address += PAGE_SIZE;
- 				if (address >= end) {
-+					pmd_unmap(dst_pmd);
-+					pmd_unmap_nested(src_pmd);
- 					pte_unmap_nested(src_pte);
- 					pte_unmap(dst_pte);
- 					goto out_unlock;
-@@ -364,6 +385,8 @@ cont_copy_pmd_range:
- 			src_pmd++;
- 			dst_pmd++;
- 		} while ((unsigned long)src_pmd & PMD_TABLE_MASK);
-+		pmd_unmap_nested(src_pmd-1);
-+		pmd_unmap(dst_pmd-1);
- 	}
- out_unlock:
- 	spin_unlock(&src->page_table_lock);
-@@ -439,7 +462,7 @@ zap_pmd_range(struct mmu_gather *tlb, pg
- 		pgd_clear(dir);
- 		return;
- 	}
--	pmd = pmd_offset(dir, address);
-+	pmd = pmd_offset_map(dir, address);
- 	end = address + size;
- 	if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
- 		end = ((address + PGDIR_SIZE) & PGDIR_MASK);
-@@ -448,6 +471,7 @@ zap_pmd_range(struct mmu_gather *tlb, pg
- 		address = (address + PMD_SIZE) & PMD_MASK; 
- 		pmd++;
- 	} while (address < end);
-+	pmd_unmap(pmd - 1);
- }
- 
- void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
-@@ -629,20 +653,27 @@ follow_page(struct mm_struct *mm, unsign
- 	if (pgd_none(*pgd) || pgd_bad(*pgd))
- 		goto out;
- 
--	pmd = pmd_offset(pgd, address);
-+	pmd = pmd_offset_map(pgd, address);
- 	if (pmd_none(*pmd))
--		goto out;
--	if (pmd_huge(*pmd))
--		return follow_huge_pmd(mm, address, pmd, write);
--	if (pmd_bad(*pmd))
--		goto out;
-+		goto out_unmap;
-+	if (pmd_bad(*pmd)) {
-+		pmd_ERROR(*pmd);
-+		pmd_clear(pmd);
-+		goto out_unmap;
-+	}
-+	if (pmd_huge(*pmd)) {
-+		struct page *page = follow_huge_pmd(mm, address, pmd, write);
-+		pmd_unmap(pmd);
-+		return page;
-+	}
- 
- 	ptep = pte_offset_map(pmd, address);
- 	if (!ptep)
--		goto out;
-+		goto out_unmap;
- 
- 	pte = *ptep;
- 	pte_unmap(ptep);
-+	pmd_unmap(pmd);
- 	if (pte_present(pte)) {
- 		if (!write || (pte_write(pte) && pte_dirty(pte))) {
- 			pfn = pte_pfn(pte);
-@@ -653,6 +684,9 @@ follow_page(struct mm_struct *mm, unsign
- 
- out:
- 	return NULL;
-+out_unmap:
-+	pmd_unmap(pmd);
-+	goto out;
- }
- 
- /* 
-@@ -711,7 +745,7 @@ int get_user_pages(struct task_struct *t
- 			pgd = pgd_offset_k(pg);
- 			if (!pgd)
- 				return i ? : -EFAULT;
--			pmd = pmd_offset(pgd, pg);
-+			pmd = pmd_offset_kernel(pgd, pg);
- 			if (!pmd)
- 				return i ? : -EFAULT;
- 			pte = pte_offset_kernel(pmd, pg);
-@@ -803,8 +837,8 @@ static void zeromap_pte_range(pte_t * pt
- 	} while (address && (address < end));
- }
- 
--static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address,
--                                    unsigned long size, pgprot_t prot)
-+static inline int zeromap_pmd_range(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd,
-+			unsigned long address, unsigned long size, pgprot_t prot)
- {
- 	unsigned long end;
- 
-@@ -813,13 +847,13 @@ static inline int zeromap_pmd_range(stru
- 	if (end > PGDIR_SIZE)
- 		end = PGDIR_SIZE;
- 	do {
--		pte_t * pte = pte_alloc_map(mm, pmd, address);
-+		pte_t *pte = pte_alloc_map(mm, pgd, pmd, address);
- 		if (!pte)
- 			return -ENOMEM;
- 		zeromap_pte_range(pte, address, end - address, prot);
- 		pte_unmap(pte);
- 		address = (address + PMD_SIZE) & PMD_MASK;
--		pmd++;
-+		(*pmd)++;
- 	} while (address && (address < end));
- 	return 0;
- }
-@@ -839,13 +873,14 @@ int zeromap_page_range(struct vm_area_st
- 
- 	spin_lock(&mm->page_table_lock);
- 	do {
--		pmd_t *pmd = pmd_alloc(mm, dir, address);
-+		pmd_t *pmd = pmd_alloc_map(mm, dir, address);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
--		error = zeromap_pmd_range(mm, pmd, address, end - address, prot);
-+		error = zeromap_pmd_range(mm, dir, &pmd, address, end - address, prot);
- 		if (error)
- 			break;
-+		pmd_unmap(pmd - 1);
- 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (address && (address < end));
-@@ -880,8 +915,9 @@ static inline void remap_pte_range(pte_t
- 	} while (address && (address < end));
- }
- 
--static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
--	unsigned long phys_addr, pgprot_t prot)
-+static inline int remap_pmd_range(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmd,
-+				unsigned long address, unsigned long size,
-+				unsigned long phys_addr, pgprot_t prot)
- {
- 	unsigned long base, end;
- 
-@@ -892,13 +928,13 @@ static inline int remap_pmd_range(struct
- 		end = PGDIR_SIZE;
- 	phys_addr -= address;
- 	do {
--		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
-+		pte_t *pte = pte_alloc_map(mm, pgd, pmd, base + address);
- 		if (!pte)
- 			return -ENOMEM;
- 		remap_pte_range(pte, base + address, end - address, address + phys_addr, prot);
- 		pte_unmap(pte);
- 		address = (address + PMD_SIZE) & PMD_MASK;
--		pmd++;
-+		(*pmd)++;
- 	} while (address && (address < end));
- 	return 0;
- }
-@@ -920,13 +956,14 @@ int remap_page_range(struct vm_area_stru
- 
- 	spin_lock(&mm->page_table_lock);
- 	do {
--		pmd_t *pmd = pmd_alloc(mm, dir, from);
-+		pmd_t *pmd = pmd_alloc_map(mm, dir, from);
- 		error = -ENOMEM;
- 		if (!pmd)
- 			break;
--		error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
-+		error = remap_pmd_range(mm, dir, &pmd, from, end - from, phys_addr + from, prot);
- 		if (error)
- 			break;
-+		pmd_unmap(pmd - 1);
- 		from = (from + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (from && (from < end));
-@@ -996,6 +1033,7 @@ static int do_wp_page(struct mm_struct *
- 		 * data, but for the moment just pretend this is OOM.
- 		 */
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 		printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
- 				address);
- 		goto oom;
-@@ -1010,11 +1048,13 @@ static int do_wp_page(struct mm_struct *
- 			establish_pte(vma, address, page_table,
- 				pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
- 			pte_unmap(page_table);
-+			pmd_unmap(pmd);
- 			ret = VM_FAULT_MINOR;
- 			goto out;
- 		}
- 	}
- 	pte_unmap(page_table);
-+	pmd_unmap(pmd);
- 
- 	/*
- 	 * Ok, we need to copy. Oh, well..
-@@ -1034,6 +1074,7 @@ static int do_wp_page(struct mm_struct *
- 	 * Re-check the pte - we dropped the lock
- 	 */
- 	spin_lock(&mm->page_table_lock);
-+	pmd = pmd_offset_map(pgd_offset(mm, address), address);
- 	page_table = pte_offset_map(pmd, address);
- 	if (pte_same(*page_table, pte)) {
- 		if (PageReserved(old_page))
-@@ -1047,6 +1088,7 @@ static int do_wp_page(struct mm_struct *
- 		new_page = old_page;
- 	}
- 	pte_unmap(page_table);
-+	pmd_unmap(pmd);
- 	page_cache_release(new_page);
- 	page_cache_release(old_page);
- 	ret = VM_FAULT_MINOR;
-@@ -1062,35 +1104,77 @@ out:
- 	return ret;
- }
- 
--static void vmtruncate_list(struct list_head *head, unsigned long pgoff)
-+/*
-+ * Helper function for invalidate_mmap_range().
-+ * Both hba and hlen are page numbers in PAGE_SIZE units.
-+ * An hlen of zero blows away the entire portion file after hba.
-+ */
-+static void
-+invalidate_mmap_range_list(struct list_head *head,
-+			   unsigned long const hba,
-+			   unsigned long const hlen)
- {
--	unsigned long start, end, len, diff;
--	struct vm_area_struct *vma;
- 	struct list_head *curr;
--
-+	unsigned long hea;	/* last page of hole. */
-+	unsigned long vba;
-+	unsigned long vea;	/* last page of corresponding uva hole. */
-+	struct vm_area_struct *vp;
-+	unsigned long zba;
-+	unsigned long zea;
-+
-+	hea = hba + hlen - 1;	/* avoid overflow. */
-+	if (hea < hba)
-+		hea = ULONG_MAX;
- 	list_for_each(curr, head) {
--		vma = list_entry(curr, struct vm_area_struct, shared);
--		start = vma->vm_start;
--		end = vma->vm_end;
--		len = end - start;
--
--		/* mapping wholly truncated? */
--		if (vma->vm_pgoff >= pgoff) {
--			zap_page_range(vma, start, len);
--			continue;
--		}
-+		vp = list_entry(curr, struct vm_area_struct, shared);
-+		vba = vp->vm_pgoff;
-+		vea = vba + ((vp->vm_end - vp->vm_start) >> PAGE_SHIFT) - 1;
-+		if (hea < vba || vea < hba)
-+		    	continue;	/* Mapping disjoint from hole. */
-+		zba = (hba <= vba) ? vba : hba;
-+		zea = (vea <= hea) ? vea : hea;
-+		zap_page_range(vp,
-+			       ((zba - vba) << PAGE_SHIFT) + vp->vm_start,
-+			       (zea - zba + 1) << PAGE_SHIFT);
-+	}
-+}
- 
--		/* mapping wholly unaffected? */
--		len = len >> PAGE_SHIFT;
--		diff = pgoff - vma->vm_pgoff;
--		if (diff >= len)
--			continue;
-+/**
-+ * invalidate_mmap_range - invalidate the portion of all mmaps
-+ * in the specified address_space corresponding to the specified
-+ * page range in the underlying file.
-+ * @address_space: the address space containing mmaps to be invalidated.
-+ * @holebegin: byte in first page to invalidate, relative to the start of
-+ * the underlying file.  This will be rounded down to a PAGE_SIZE
-+ * boundary.  Note that this is different from vmtruncate(), which
-+ * must keep the partial page.  In contrast, we must get rid of
-+ * partial pages.
-+ * @holelen: size of prospective hole in bytes.  This will be rounded
-+ * up to a PAGE_SIZE boundary.  A holelen of zero truncates to the
-+ * end of the file.
-+ */
-+void invalidate_mmap_range(struct address_space *mapping,
-+		      loff_t const holebegin, loff_t const holelen)
-+{
-+	unsigned long hba = holebegin >> PAGE_SHIFT;
-+	unsigned long hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+
-+	/* Check for overflow. */
-+	if (sizeof(holelen) > sizeof(hlen)) {
-+		long long holeend =
-+			(holebegin + holelen + PAGE_SIZE - 1) >> PAGE_SHIFT;
- 
--		/* Ok, partially affected.. */
--		start += diff << PAGE_SHIFT;
--		len = (len - diff) << PAGE_SHIFT;
--		zap_page_range(vma, start, len);
-+		if (holeend & ~(long long)ULONG_MAX)
-+			hlen = ULONG_MAX - hba + 1;
- 	}
-+	down(&mapping->i_shared_sem);
-+	/* Protect against page fault */
-+	atomic_inc(&mapping->truncate_count);
-+	if (unlikely(!list_empty(&mapping->i_mmap)))
-+		invalidate_mmap_range_list(&mapping->i_mmap, hba, hlen);
-+	if (unlikely(!list_empty(&mapping->i_mmap_shared)))
-+		invalidate_mmap_range_list(&mapping->i_mmap_shared, hba, hlen);
-+	up(&mapping->i_shared_sem);
- }
- 
- /*
-@@ -1103,20 +1187,13 @@ static void vmtruncate_list(struct list_
-  */
- int vmtruncate(struct inode * inode, loff_t offset)
- {
--	unsigned long pgoff;
- 	struct address_space *mapping = inode->i_mapping;
- 	unsigned long limit;
- 
- 	if (inode->i_size < offset)
- 		goto do_expand;
- 	i_size_write(inode, offset);
--	pgoff = (offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
--	down(&mapping->i_shared_sem);
--	if (unlikely(!list_empty(&mapping->i_mmap)))
--		vmtruncate_list(&mapping->i_mmap, pgoff);
--	if (unlikely(!list_empty(&mapping->i_mmap_shared)))
--		vmtruncate_list(&mapping->i_mmap_shared, pgoff);
--	up(&mapping->i_shared_sem);
-+	invalidate_mmap_range(mapping, offset + PAGE_SIZE - 1, 0);
- 	truncate_inode_pages(mapping, offset);
- 	goto out_truncate;
- 
-@@ -1180,6 +1257,7 @@ static int do_swap_page(struct mm_struct
- 	struct pte_chain *pte_chain = NULL;
- 
- 	pte_unmap(page_table);
-+	pmd_unmap(pmd);
- 	spin_unlock(&mm->page_table_lock);
- 	page = lookup_swap_cache(entry);
- 	if (!page) {
-@@ -1191,12 +1269,14 @@ static int do_swap_page(struct mm_struct
- 			 * we released the page table lock.
- 			 */
- 			spin_lock(&mm->page_table_lock);
-+			pmd = pmd_offset_map(pgd_offset(mm, address), address);
- 			page_table = pte_offset_map(pmd, address);
- 			if (pte_same(*page_table, orig_pte))
- 				ret = VM_FAULT_OOM;
- 			else
- 				ret = VM_FAULT_MINOR;
- 			pte_unmap(page_table);
-+			pmd_unmap(pmd);
- 			spin_unlock(&mm->page_table_lock);
- 			goto out;
- 		}
-@@ -1219,9 +1299,11 @@ static int do_swap_page(struct mm_struct
- 	 * released the page table lock.
- 	 */
- 	spin_lock(&mm->page_table_lock);
-+	pmd = pmd_offset_map(pgd_offset(mm, address), address);
- 	page_table = pte_offset_map(pmd, address);
- 	if (!pte_same(*page_table, orig_pte)) {
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 		spin_unlock(&mm->page_table_lock);
- 		unlock_page(page);
- 		page_cache_release(page);
-@@ -1247,6 +1329,7 @@ static int do_swap_page(struct mm_struct
- 
- 	/* No need to invalidate - it was non-present before */
- 	update_mmu_cache(vma, address, pte);
-+	pmd_unmap(pmd);
- 	pte_unmap(page_table);
- 	spin_unlock(&mm->page_table_lock);
- out:
-@@ -1272,11 +1355,13 @@ do_anonymous_page(struct mm_struct *mm, 
- 	pte_chain = pte_chain_alloc(GFP_ATOMIC);
- 	if (!pte_chain) {
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 		spin_unlock(&mm->page_table_lock);
- 		pte_chain = pte_chain_alloc(GFP_KERNEL);
- 		if (!pte_chain)
- 			goto no_mem;
- 		spin_lock(&mm->page_table_lock);
-+		pmd = pmd_offset_map(pgd_offset(mm, addr), addr);
- 		page_table = pte_offset_map(pmd, addr);
- 	}
- 		
-@@ -1287,6 +1372,7 @@ do_anonymous_page(struct mm_struct *mm, 
- 	if (write_access) {
- 		/* Allocate our own private page. */
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 		spin_unlock(&mm->page_table_lock);
- 
- 		page = alloc_page(GFP_HIGHUSER);
-@@ -1295,9 +1381,11 @@ do_anonymous_page(struct mm_struct *mm, 
- 		clear_user_highpage(page, addr);
- 
- 		spin_lock(&mm->page_table_lock);
-+		pmd = pmd_offset_map(pgd_offset(mm, addr), addr);
- 		page_table = pte_offset_map(pmd, addr);
- 
- 		if (!pte_none(*page_table)) {
-+			pmd_unmap(pmd);
- 			pte_unmap(page_table);
- 			page_cache_release(page);
- 			spin_unlock(&mm->page_table_lock);
-@@ -1313,6 +1401,7 @@ do_anonymous_page(struct mm_struct *mm, 
- 	set_pte(page_table, entry);
- 	/* ignores ZERO_PAGE */
- 	pte_chain = page_add_rmap(page, page_table, pte_chain);
-+	pmd_unmap(pmd);
- 	pte_unmap(page_table);
- 
- 	/* No need to invalidate - it was non-present before */
-@@ -1345,16 +1434,22 @@ do_no_page(struct mm_struct *mm, struct 
- 	unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd)
- {
- 	struct page * new_page;
-+	struct address_space *mapping;
- 	pte_t entry;
- 	struct pte_chain *pte_chain;
-+	int sequence;
- 	int ret;
- 
- 	if (!vma->vm_ops || !vma->vm_ops->nopage)
- 		return do_anonymous_page(mm, vma, page_table,
- 					pmd, write_access, address);
- 	pte_unmap(page_table);
--	spin_unlock(&mm->page_table_lock);
-+	pmd_unmap(pmd);
- 
-+	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
-+	sequence = atomic_read(&mapping->truncate_count);
-+	spin_unlock(&mm->page_table_lock);
-+retry:
- 	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
- 
- 	/* no page was available -- either SIGBUS or OOM */
-@@ -1383,6 +1478,18 @@ do_no_page(struct mm_struct *mm, struct 
- 	}
- 
- 	spin_lock(&mm->page_table_lock);
-+	/*
-+	 * For a file-backed vma, someone could have truncated or otherwise
-+	 * invalidated this page.  If invalidate_mmap_range got called,
-+	 * retry getting the page.
-+	 */
-+	if (unlikely(sequence != atomic_read(&mapping->truncate_count))) {
-+		sequence = atomic_read(&mapping->truncate_count);
-+		spin_unlock(&mm->page_table_lock);
-+		page_cache_release(new_page);
-+		goto retry;
-+	}
-+	pmd = pmd_offset_map(pgd_offset(mm, address), address);
- 	page_table = pte_offset_map(pmd, address);
- 
- 	/*
-@@ -1405,9 +1512,11 @@ do_no_page(struct mm_struct *mm, struct 
- 		set_pte(page_table, entry);
- 		pte_chain = page_add_rmap(new_page, page_table, pte_chain);
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 	} else {
- 		/* One of our sibling threads was faster, back out. */
- 		pte_unmap(page_table);
-+		pmd_unmap(pmd);
- 		page_cache_release(new_page);
- 		spin_unlock(&mm->page_table_lock);
- 		ret = VM_FAULT_MINOR;
-@@ -1451,6 +1560,7 @@ static int do_file_page(struct mm_struct
- 	pgoff = pte_to_pgoff(*pte);
- 
- 	pte_unmap(pte);
-+	pmd_unmap(pmd);
- 	spin_unlock(&mm->page_table_lock);
- 
- 	err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0);
-@@ -1511,6 +1621,7 @@ static inline int handle_pte_fault(struc
- 	entry = pte_mkyoung(entry);
- 	establish_pte(vma, address, pte, entry);
- 	pte_unmap(pte);
-+	pmd_unmap(pmd);
- 	spin_unlock(&mm->page_table_lock);
- 	return VM_FAULT_MINOR;
- }
-@@ -1537,10 +1648,10 @@ int handle_mm_fault(struct mm_struct *mm
- 	 * and the SMP-safe atomic PTE updates.
- 	 */
- 	spin_lock(&mm->page_table_lock);
--	pmd = pmd_alloc(mm, pgd, address);
-+	pmd = pmd_alloc_map(mm, pgd, address);
- 
- 	if (pmd) {
--		pte_t * pte = pte_alloc_map(mm, pmd, address);
-+		pte_t *pte = pte_alloc_map(mm, pgd, &pmd, address);
- 		if (pte)
- 			return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
- 	}
-@@ -1559,10 +1670,33 @@ int handle_mm_fault(struct mm_struct *mm
-  */
- pmd_t *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
- {
-+	struct page *page;
-+
-+	spin_unlock(&mm->page_table_lock);
-+	page = pmd_alloc_one(mm, address);
-+	spin_lock(&mm->page_table_lock);
-+	if (!page)
-+		return NULL;
-+
-+	/*
-+	 * Because we dropped the lock, we should re-check the
-+	 * entry, as somebody else could have populated it..
-+	 */
-+	if (pgd_present(*pgd)) {
-+		pmd_free(page);
-+		goto out;
-+	}
-+	pgd_populate(mm, pgd, page);
-+out:
-+	return pmd_offset_map(pgd, address);
-+}
-+
-+pmd_t *__pmd_alloc_kernel(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
-+{
- 	pmd_t *new;
- 
- 	spin_unlock(&mm->page_table_lock);
--	new = pmd_alloc_one(mm, address);
-+	new = pmd_alloc_one_kernel(mm, address);
- 	spin_lock(&mm->page_table_lock);
- 	if (!new)
- 		return NULL;
-@@ -1572,12 +1706,12 @@ pmd_t *__pmd_alloc(struct mm_struct *mm,
- 	 * entry, as somebody else could have populated it..
- 	 */
- 	if (pgd_present(*pgd)) {
--		pmd_free(new);
-+		pmd_free(virt_to_page(new));
- 		goto out;
- 	}
--	pgd_populate(mm, pgd, new);
-+	pgd_populate(mm, pgd, virt_to_page(new));
- out:
--	return pmd_offset(pgd, address);
-+	return pmd_offset_kernel(pgd, address);
- }
- 
- int make_pages_present(unsigned long addr, unsigned long end)
-@@ -1609,7 +1743,7 @@ struct page * vmalloc_to_page(void * vma
- 	pte_t *ptep, pte;
-   
- 	if (!pgd_none(*pgd)) {
--		pmd = pmd_offset(pgd, addr);
-+		pmd = pmd_offset_map(pgd, addr);
- 		if (!pmd_none(*pmd)) {
- 			preempt_disable();
- 			ptep = pte_offset_map(pmd, addr);
-@@ -1619,6 +1753,7 @@ struct page * vmalloc_to_page(void * vma
- 			pte_unmap(ptep);
- 			preempt_enable();
- 		}
-+		pmd_unmap(pmd);
- 	}
- 	return page;
- }
---- linux-2.6.0-test1/mm/mprotect.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/mm/mprotect.c	2003-07-19 17:07:16.000000000 -0700
-@@ -73,7 +73,7 @@ change_pmd_range(pgd_t *pgd, unsigned lo
- 		pgd_clear(pgd);
- 		return;
- 	}
--	pmd = pmd_offset(pgd, address);
-+	pmd = pmd_offset_map(pgd, address);
- 	address &= ~PGDIR_MASK;
- 	end = address + size;
- 	if (end > PGDIR_SIZE)
-@@ -83,6 +83,7 @@ change_pmd_range(pgd_t *pgd, unsigned lo
- 		address = (address + PMD_SIZE) & PMD_MASK;
- 		pmd++;
- 	} while (address && (address < end));
-+	pmd_unmap(pmd - 1);
- }
- 
- static void
---- linux-2.6.0-test1/mm/mremap.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/mm/mremap.c	2003-07-19 17:07:16.000000000 -0700
-@@ -38,7 +38,7 @@ static pte_t *get_one_pte_map_nested(str
- 		goto end;
- 	}
- 
--	pmd = pmd_offset(pgd, addr);
-+	pmd = pmd_offset_map_nested(pgd, addr);
- 	if (pmd_none(*pmd))
- 		goto end;
- 	if (pmd_bad(*pmd)) {
-@@ -53,6 +53,7 @@ static pte_t *get_one_pte_map_nested(str
- 		pte = NULL;
- 	}
- end:
-+	pmd_unmap_nested(pmd);
- 	return pte;
- }
- 
-@@ -61,12 +62,15 @@ static inline int page_table_present(str
- {
- 	pgd_t *pgd;
- 	pmd_t *pmd;
-+	int ret;
- 
- 	pgd = pgd_offset(mm, addr);
- 	if (pgd_none(*pgd))
- 		return 0;
--	pmd = pmd_offset(pgd, addr);
--	return pmd_present(*pmd);
-+	pmd = pmd_offset_map(pgd, addr);
-+	ret = pmd_present(*pmd);
-+	pmd_unmap(pmd);
-+	return ret != 0;
- }
- #else
- #define page_table_present(mm, addr)	(1)
-@@ -74,12 +78,15 @@ static inline int page_table_present(str
- 
- static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
- {
-+	pgd_t *pgd;
- 	pmd_t *pmd;
- 	pte_t *pte = NULL;
- 
--	pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr);
-+	pgd = pgd_offset(mm, addr);
-+	pmd = pmd_alloc_map(mm, pgd, addr);
- 	if (pmd)
--		pte = pte_alloc_map(mm, pmd, addr);
-+		pte = pte_alloc_map(mm, pgd, &pmd, addr);
-+	pmd_unmap(pmd);
- 	return pte;
- }
- 
---- linux-2.6.0-test1/mm/msync.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/mm/msync.c	2003-07-19 17:07:16.000000000 -0700
-@@ -82,7 +82,7 @@ static inline int filemap_sync_pmd_range
- 		pgd_clear(pgd);
- 		return 0;
- 	}
--	pmd = pmd_offset(pgd, address);
-+	pmd = pmd_offset_map(pgd, address);
- 	if ((address & PGDIR_MASK) != (end & PGDIR_MASK))
- 		end = (address & PGDIR_MASK) + PGDIR_SIZE;
- 	error = 0;
-@@ -91,6 +91,7 @@ static inline int filemap_sync_pmd_range
- 		address = (address + PMD_SIZE) & PMD_MASK;
- 		pmd++;
- 	} while (address && (address < end));
-+	pmd_unmap(pmd - 1);
- 	return error;
- }
- 
---- linux-2.6.0-test1/mm/page-writeback.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/mm/page-writeback.c	2003-07-19 17:06:58.000000000 -0700
-@@ -28,6 +28,7 @@
- #include <linux/smp.h>
- #include <linux/sysctl.h>
- #include <linux/cpu.h>
-+#include <linux/pagevec.h>
- 
- /*
-  * The maximum number of pages to writeout in a single bdflush/kupdate
-@@ -144,7 +145,7 @@ get_dirty_limits(struct page_state *ps, 
-  * If we're over `background_thresh' then pdflush is woken to perform some
-  * writeout.
-  */
--void balance_dirty_pages(struct address_space *mapping)
-+int balance_dirty_pages(struct address_space *mapping)
- {
- 	struct page_state ps;
- 	long nr_reclaimable;
-@@ -161,6 +162,7 @@ void balance_dirty_pages(struct address_
- 			.sync_mode	= WB_SYNC_NONE,
- 			.older_than_this = NULL,
- 			.nr_to_write	= write_chunk,
-+			.nonblocking	= !is_sync_wait(current->io_wait)
- 		};
- 
- 		get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
-@@ -187,7 +189,11 @@ void balance_dirty_pages(struct address_
- 			if (pages_written >= write_chunk)
- 				break;		/* We've done our duty */
- 		}
--		blk_congestion_wait(WRITE, HZ/10);
-+		if (-EIOCBRETRY == blk_congestion_wait_wq(WRITE, HZ/10,
-+			current->io_wait)) {
-+			pr_debug("async blk congestion wait\n");
-+			return -EIOCBRETRY;
-+		}
- 	}
- 
- 	if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
-@@ -195,6 +201,8 @@ void balance_dirty_pages(struct address_
- 
- 	if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
- 		pdflush_operation(background_writeout, 0);
-+
-+	return 0;
- }
- 
- /**
-@@ -210,7 +218,7 @@ void balance_dirty_pages(struct address_
-  * decrease the ratelimiting by a lot, to prevent individual processes from
-  * overshooting the limit by (ratelimit_pages) each.
-  */
--void balance_dirty_pages_ratelimited(struct address_space *mapping)
-+int balance_dirty_pages_ratelimited(struct address_space *mapping)
- {
- 	static DEFINE_PER_CPU(int, ratelimits) = 0;
- 	long ratelimit;
-@@ -222,10 +230,10 @@ void balance_dirty_pages_ratelimited(str
- 	if (get_cpu_var(ratelimits)++ >= ratelimit) {
- 		__get_cpu_var(ratelimits) = 0;
- 		put_cpu_var(ratelimits);
--		balance_dirty_pages(mapping);
--		return;
-+		return balance_dirty_pages(mapping);
- 	}
- 	put_cpu_var(ratelimits);
-+	return 0;
- }
- 
- /*
-@@ -560,3 +568,107 @@ int test_clear_page_dirty(struct page *p
- 	return 0;
- }
- EXPORT_SYMBOL(test_clear_page_dirty);
-+
-+
-+static ssize_t operate_on_page_range(struct address_space *mapping,
-+		loff_t pos, size_t count, int (*operator)(struct page *))
-+{
-+	pgoff_t first = pos >> PAGE_CACHE_SHIFT;
-+	pgoff_t last = (pos + count - 1) >> PAGE_CACHE_SHIFT;	/* inclusive */
-+	pgoff_t next = first;
-+	struct pagevec pvec;
-+	ssize_t ret = 0, bytes = 0;
-+	int i;
-+
-+	if (count == 0)
-+		return 0;
-+
-+	pagevec_init(&pvec, 0);
-+	while (pagevec_lookup(&pvec, mapping, next,
-+				min((pgoff_t)PAGEVEC_SIZE, last - next + 1))) {
-+		for (i = 0; i < pagevec_count(&pvec); i++) {
-+			struct page *page = pvec.pages[i];
-+
-+			lock_page(page);	/* stabilise ->index */
-+			if (!page->mapping) {	/* truncated */
-+				unlock_page(page);
-+				next++;
-+				continue;
-+			}
-+			next = page->index + 1;
-+			ret = (*operator)(page);
-+			if (ret == -EIOCBRETRY)
-+				break;
-+			if (PageError(page)) {
-+				if (!ret)
-+					ret = -EIO;
-+			}
-+			if (next > last)
-+				break;
-+		}
-+		pagevec_release(&pvec);
-+		if ((next > last) || (ret == -EIOCBRETRY))
-+			break;
-+	}
-+	bytes = (next << PAGE_CACHE_SHIFT) - pos;
-+	if (bytes > count)
-+		bytes = count;
-+	return (bytes && (!ret || (ret == -EIOCBRETRY))) ? bytes : ret;
-+}
-+
-+static int page_waiter(struct page *page)
-+{
-+	unlock_page(page);
-+	return wait_on_page_writeback_wq(page, current->io_wait);
-+}
-+
-+static size_t
-+wait_on_page_range(struct address_space *mapping, loff_t pos, size_t count)
-+{
-+	return operate_on_page_range(mapping, pos, count, page_waiter);
-+}
-+
-+static int page_writer(struct page *page)
-+{
-+	struct writeback_control wbc = {
-+		.sync_mode	= WB_SYNC_ALL,
-+		.nr_to_write	= 1,
-+	};
-+
-+	wait_on_page_writeback(page);
-+	return page->mapping->a_ops->writepage(page, &wbc);
-+}
-+
-+static ssize_t
-+write_out_page_range(struct address_space *mapping, loff_t pos, size_t count)
-+{
-+	return operate_on_page_range(mapping, pos, count, page_writer);
-+}
-+
-+/*
-+ * Write and wait upon all the pages in the passed range.  This is a "data
-+ * integrity" operation.  It waits upon in-flight writeout before starting and
-+ * waiting upon new writeout.  If there was an IO error, return it.
-+ *
-+ * We need to re-take i_sem during the generic_osync_inode list walk because
-+ * it is otherwise livelockable.
-+ */
-+ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
-+			loff_t pos, size_t count)
-+{
-+	int ret;
-+
-+	if (!mapping->a_ops->writepage)
-+		return 0;
-+	if (mapping->backing_dev_info->memory_backed)
-+		return 0;
-+	ret = write_out_page_range(mapping, pos, count);
-+	if (ret >= 0) {
-+		down(&inode->i_sem);
-+		ret = generic_osync_inode(inode, OSYNC_METADATA);
-+		up(&inode->i_sem);
-+	}
-+	if (ret >= 0)
-+		ret = wait_on_page_range(mapping, pos, count);
-+	return ret;
-+}
---- linux-2.6.0-test1/mm/slab.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/mm/slab.c	2003-07-19 17:07:16.000000000 -0700
-@@ -1628,7 +1628,13 @@ static inline void *cache_free_debugchec
- 	kfree_debugcheck(objp);
- 	page = virt_to_page(objp);
- 
--	BUG_ON(GET_PAGE_CACHE(page) != cachep);
-+	if (GET_PAGE_CACHE(page) != cachep) {
-+		printk(KERN_ERR "mismatch in kmem_cache_free: expected cache %p, got %p\n",
-+				GET_PAGE_CACHE(page),cachep);
-+		printk(KERN_ERR "%p is %s.\n", cachep, cachep->name);
-+		printk(KERN_ERR "%p is %s.\n", GET_PAGE_CACHE(page), GET_PAGE_CACHE(page)->name);
-+		WARN_ON(1);
-+	}
- 	slabp = GET_PAGE_SLAB(page);
- 
- 	if (cachep->flags & SLAB_STORE_USER) {
-@@ -2482,11 +2488,11 @@ static void *s_start(struct seq_file *m,
- 		seq_puts(m, "slabinfo - version: 2.0\n");
- #endif
- 		seq_puts(m, "# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>");
--		seq_puts(m, " : tunables <batchcount> <limit <sharedfactor>");
-+		seq_puts(m, " : tunables <batchcount> <limit> <sharedfactor>");
- 		seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
- #if STATS
- 		seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <freelimit>");
--		seq_puts(m, " : cpustat <allochit <allocmiss <freehit <freemiss>");
-+		seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit <freemiss>");
- #endif
- 		seq_putc(m, '\n');
- 	}
-@@ -2717,7 +2723,7 @@ void ptrinfo(unsigned long addr)
- 			printk("No pgd.\n");
- 			break;
- 		}
--		pmd = pmd_offset(pgd, addr);
-+		pmd = pmd_offset_kernel(pgd, addr);
- 		if (pmd_none(*pmd)) {
- 			printk("No pmd.\n");
- 			break;
---- linux-2.6.0-test1/mm/swapfile.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/mm/swapfile.c	2003-07-19 17:07:16.000000000 -0700
-@@ -448,7 +448,7 @@ static int unuse_pgd(struct vm_area_stru
- 		pgd_clear(dir);
- 		return 0;
- 	}
--	pmd = pmd_offset(dir, address);
-+	pmd = pmd_offset_map(dir, address);
- 	offset = address & PGDIR_MASK;
- 	address &= ~PGDIR_MASK;
- 	end = address + size;
-@@ -463,6 +463,7 @@ static int unuse_pgd(struct vm_area_stru
- 		address = (address + PMD_SIZE) & PMD_MASK;
- 		pmd++;
- 	} while (address && (address < end));
-+	pmd_unmap(pmd - 1);
- 	return 0;
- }
- 
---- linux-2.6.0-test1/mm/swap_state.c	2003-06-26 22:07:26.000000000 -0700
-+++ 25/mm/swap_state.c	2003-07-19 17:07:03.000000000 -0700
-@@ -35,6 +35,7 @@ struct address_space swapper_space = {
- 	.i_mmap		= LIST_HEAD_INIT(swapper_space.i_mmap),
- 	.i_mmap_shared	= LIST_HEAD_INIT(swapper_space.i_mmap_shared),
- 	.i_shared_sem	= __MUTEX_INITIALIZER(swapper_space.i_shared_sem),
-+	.truncate_count  = ATOMIC_INIT(0),
- 	.private_lock	= SPIN_LOCK_UNLOCKED,
- 	.private_list	= LIST_HEAD_INIT(swapper_space.private_list),
- };
---- linux-2.6.0-test1/mm/vmalloc.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/mm/vmalloc.c	2003-07-19 17:07:16.000000000 -0700
-@@ -70,7 +70,7 @@ static void unmap_area_pmd(pgd_t *dir, u
- 		return;
- 	}
- 
--	pmd = pmd_offset(dir, address);
-+	pmd = pmd_offset_kernel(dir, address);
- 	address &= ~PGDIR_MASK;
- 	end = address + size;
- 	if (end > PGDIR_SIZE)
-@@ -159,7 +159,7 @@ int map_vm_area(struct vm_struct *area, 
- 	dir = pgd_offset_k(address);
- 	spin_lock(&init_mm.page_table_lock);
- 	do {
--		pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
-+		pmd_t *pmd = pmd_alloc_kernel(&init_mm, dir, address);
- 		if (!pmd) {
- 			err = -ENOMEM;
- 			break;
---- linux-2.6.0-test1/mm/vmscan.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/mm/vmscan.c	2003-07-19 17:06:15.000000000 -0700
-@@ -921,7 +921,7 @@ static int balance_pgdat(pg_data_t *pgda
- 			if (i < ZONE_HIGHMEM) {
- 				reclaim_state->reclaimed_slab = 0;
- 				shrink_slab(max_scan + nr_mapped, GFP_KERNEL);
--				to_free += reclaim_state->reclaimed_slab;
-+				to_free -= reclaim_state->reclaimed_slab;
- 			}
- 			if (zone->all_unreclaimable)
- 				continue;
-@@ -930,7 +930,8 @@ static int balance_pgdat(pg_data_t *pgda
- 		}
- 		if (all_zones_ok)
- 			break;
--		blk_congestion_wait(WRITE, HZ/10);
-+		if (to_free)
-+			blk_congestion_wait(WRITE, HZ/10);
- 	}
- 	return nr_pages - to_free;
- }
-@@ -956,11 +957,11 @@ int kswapd(void *p)
- 	struct reclaim_state reclaim_state = {
- 		.reclaimed_slab = 0,
- 	};
--	unsigned long cpumask;
-+	cpumask_t cpumask;
- 
- 	daemonize("kswapd%d", pgdat->node_id);
- 	cpumask = node_to_cpumask(pgdat->node_id);
--	if (cpumask)
-+	if (!cpus_empty(cpumask))
- 		set_cpus_allowed(tsk, cpumask);
- 	current->reclaim_state = &reclaim_state;
- 
---- linux-2.6.0-test1/net/atm/br2684.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/net/atm/br2684.c	2003-07-19 17:03:51.000000000 -0700
-@@ -16,9 +16,12 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hun
- #include <linux/ip.h>
- #include <asm/uaccess.h>
- #include <net/arp.h>
-+#include <linux/atm.h>
-+#include <linux/atmdev.h>
- 
- #include <linux/atmbr2684.h>
- 
-+#include "common.h"
- #include "ipcommon.h"
- 
- /*
-@@ -768,8 +771,6 @@ static struct file_operations br2684_pro
- 
- extern struct proc_dir_entry *atm_proc_root;	/* from proc.c */
- 
--extern int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
--
- /* the following avoids some spurious warnings from the compiler */
- #define UNUSED __attribute__((unused))
- 
-@@ -779,14 +780,14 @@ static int __init UNUSED br2684_init(voi
- 	if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
- 		return -ENOMEM;
- 	p->proc_fops = &br2684_proc_operations;
--	br2684_ioctl_hook = br2684_ioctl;
-+	br2684_ioctl_set(br2684_ioctl);
- 	return 0;
- }
- 
- static void __exit UNUSED br2684_exit(void)
- {
- 	struct br2684_dev *brdev;
--	br2684_ioctl_hook = NULL;
-+	br2684_ioctl_set(NULL);
- 	remove_proc_entry("br2684", atm_proc_root);
- 	while (!list_empty(&br2684_devs)) {
- 		brdev = list_entry_brdev(br2684_devs.next);
---- linux-2.6.0-test1/net/atm/clip.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/atm/clip.c	2003-07-19 17:03:51.000000000 -0700
-@@ -67,7 +67,7 @@ static int to_atmarpd(enum atmarp_ctrl_t
- 	ctrl->ip = ip;
- 	atm_force_charge(atmarpd,skb->truesize);
- 	skb_queue_tail(&atmarpd->sk->sk_receive_queue, skb);
--	wake_up(&atmarpd->sleep);
-+	atmarpd->sk->sk_data_ready(atmarpd->sk, skb->len);
- 	return 0;
- }
- 
---- linux-2.6.0-test1/net/atm/common.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/common.c	2003-07-19 17:03:51.000000000 -0700
-@@ -129,14 +129,34 @@ EXPORT_SYMBOL(atm_clip_ops_set);
- #endif
- 
- #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
--int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
--EXPORT_SYMBOL(pppoatm_ioctl_hook);
-+static DECLARE_MUTEX(pppoatm_ioctl_mutex);
-+
-+static int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
-+
-+void pppoatm_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long))
-+{
-+	down(&pppoatm_ioctl_mutex);
-+	pppoatm_ioctl_hook = hook;
-+	up(&pppoatm_ioctl_mutex);
-+}
-+#ifdef CONFIG_PPPOATM_MODULE
-+EXPORT_SYMBOL(pppoatm_ioctl_set);
-+#endif
- #endif
- 
- #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
--int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
-+static DECLARE_MUTEX(br2684_ioctl_mutex);
-+
-+static int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
-+
-+void br2684_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long))
-+{
-+	down(&br2684_ioctl_mutex);
-+	br2684_ioctl_hook = hook;
-+	up(&br2684_ioctl_mutex);
-+}
- #ifdef CONFIG_ATM_BR2684_MODULE
--EXPORT_SYMBOL(br2684_ioctl_hook);
-+EXPORT_SYMBOL(br2684_ioctl_set);
- #endif
- #endif
- 
-@@ -215,6 +235,37 @@ static void vcc_sock_destruct(struct soc
- 
- 	kfree(sk->sk_protinfo);
- }
-+
-+static void vcc_def_wakeup(struct sock *sk)
-+{
-+	read_lock(&sk->sk_callback_lock);
-+	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-+		wake_up(sk->sk_sleep);
-+	read_unlock(&sk->sk_callback_lock);
-+}
-+
-+static inline int vcc_writable(struct sock *sk)
-+{
-+	struct atm_vcc *vcc = atm_sk(sk);
-+
-+	return (vcc->qos.txtp.max_sdu +
-+	        atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
-+}
-+
-+static void vcc_write_space(struct sock *sk)
-+{       
-+	read_lock(&sk->sk_callback_lock);
-+
-+	if (vcc_writable(sk)) {
-+		if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-+			wake_up_interruptible(sk->sk_sleep);
-+
-+		sk_wake_async(sk, 2, POLL_OUT);
-+	}
-+
-+	read_unlock(&sk->sk_callback_lock);
-+}
-+
-  
- int vcc_create(struct socket *sock, int protocol, int family)
- {
-@@ -227,7 +278,9 @@ int vcc_create(struct socket *sock, int 
- 	sk = sk_alloc(family, GFP_KERNEL, 1, NULL);
- 	if (!sk)
- 		return -ENOMEM;
--	sock_init_data(NULL, sk);
-+	sock_init_data(sock, sk);
-+	sk->sk_state_change = vcc_def_wakeup;
-+	sk->sk_write_space = vcc_write_space;
- 
- 	vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL);
- 	if (!vcc) {
-@@ -238,7 +291,6 @@ int vcc_create(struct socket *sock, int 
- 	memset(vcc, 0, sizeof(*vcc));
- 	vcc->sk = sk;
- 	vcc->dev = NULL;
--	vcc->callback = NULL;
- 	memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
- 	memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
- 	vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
-@@ -249,8 +301,6 @@ int vcc_create(struct socket *sock, int 
- 	vcc->push_oam = NULL;
- 	vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
- 	vcc->atm_options = vcc->aal_options = 0;
--	init_waitqueue_head(&vcc->sleep);
--	sk->sk_sleep = &vcc->sleep;
- 	sk->sk_destruct = vcc_sock_destruct;
- 	sock->sk = sk;
- 	return 0;
-@@ -300,9 +350,9 @@ int vcc_release(struct socket *sock)
- void vcc_release_async(struct atm_vcc *vcc, int reply)
- {
- 	set_bit(ATM_VF_CLOSE, &vcc->flags);
--	vcc->reply = reply;
- 	vcc->sk->sk_err = -reply;
--	wake_up(&vcc->sleep);
-+	clear_bit(ATM_VF_WAITING, &vcc->flags);
-+	vcc->sk->sk_state_change(vcc->sk);
- }
- 
- 
-@@ -475,7 +525,7 @@ int vcc_recvmsg(struct kiocb *iocb, stru
- 	vcc = ATM_SD(sock);
- 	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
- 	    test_bit(ATM_VF_CLOSE,&vcc->flags))
--		return vcc->reply;
-+		return -sk->sk_err;
- 	if (!test_bit(ATM_VF_READY, &vcc->flags))
- 		return 0;
- 
-@@ -532,7 +582,7 @@ int vcc_sendmsg(struct kiocb *iocb, stru
- 	vcc = ATM_SD(sock);
- 	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
- 	    test_bit(ATM_VF_CLOSE, &vcc->flags)) {
--		error = vcc->reply;
-+		error = -sk->sk_err;
- 		goto out;
- 	}
- 	if (!test_bit(ATM_VF_READY, &vcc->flags)) {
-@@ -549,7 +599,7 @@ int vcc_sendmsg(struct kiocb *iocb, stru
- 	}
- 	/* verify_area is done by net/socket.c */
- 	eff = (size+3) & ~3; /* align to word boundary */
--	prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+	prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 	error = 0;
- 	while (!(skb = alloc_tx(vcc,eff))) {
- 		if (m->msg_flags & MSG_DONTWAIT) {
-@@ -563,16 +613,16 @@ int vcc_sendmsg(struct kiocb *iocb, stru
- 		}
- 		if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
- 		    test_bit(ATM_VF_CLOSE,&vcc->flags)) {
--			error = vcc->reply;
-+			error = -sk->sk_err;
- 			break;
- 		}
- 		if (!test_bit(ATM_VF_READY,&vcc->flags)) {
- 			error = -EPIPE;
- 			break;
- 		}
--		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 	}
--	finish_wait(&vcc->sleep, &wait);
-+	finish_wait(sk->sk_sleep, &wait);
- 	if (error)
- 		goto out;
- 	skb->dev = NULL; /* for paths shared with net_device interfaces */
-@@ -591,29 +641,38 @@ out:
- }
- 
- 
--unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait)
-+unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
- {
-+	struct sock *sk = sock->sk;
- 	struct atm_vcc *vcc;
- 	unsigned int mask;
- 
--	vcc = ATM_SD(sock);
--	poll_wait(file,&vcc->sleep,wait);
-+	poll_wait(file, sk->sk_sleep, wait);
- 	mask = 0;
--	if (skb_peek(&vcc->sk->sk_receive_queue))
--		mask |= POLLIN | POLLRDNORM;
--	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
--	    test_bit(ATM_VF_CLOSE,&vcc->flags))
-+
-+	vcc = ATM_SD(sock);
-+
-+	/* exceptional events */
-+	if (sk->sk_err)
-+		mask = POLLERR;
-+
-+	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
-+	    test_bit(ATM_VF_CLOSE, &vcc->flags))
- 		mask |= POLLHUP;
--	if (sock->state != SS_CONNECTING) {
--		if (vcc->qos.txtp.traffic_class != ATM_NONE &&
--		    vcc->qos.txtp.max_sdu +
--		    atomic_read(&vcc->sk->sk_wmem_alloc) <= vcc->sk->sk_sndbuf)
--			mask |= POLLOUT | POLLWRNORM;
--	}
--	else if (vcc->reply != WAITING) {
--			mask |= POLLOUT | POLLWRNORM;
--			if (vcc->reply) mask |= POLLERR;
--		}
-+
-+	/* readable? */
-+	if (!skb_queue_empty(&sk->sk_receive_queue))
-+		mask |= POLLIN | POLLRDNORM;
-+
-+	/* writable? */
-+	if (sock->state == SS_CONNECTING &&
-+	    test_bit(ATM_VF_WAITING, &vcc->flags))
-+		return mask;
-+
-+	if (vcc->qos.txtp.traffic_class != ATM_NONE &&
-+	    vcc_writable(vcc->sk))
-+		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-+
- 	return mask;
- }
- 
-@@ -859,19 +918,22 @@ int vcc_ioctl(struct socket *sock, unsig
- 		default:
- 			break;
- 	}
-+	error = -ENOIOCTLCMD;
- #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
--	if (pppoatm_ioctl_hook) {
-+	down(&pppoatm_ioctl_mutex);
-+	if (pppoatm_ioctl_hook)
- 		error = pppoatm_ioctl_hook(vcc, cmd, arg);
--		if (error != -ENOIOCTLCMD)
--			goto done;
--	}
-+	up(&pppoatm_ioctl_mutex);
-+	if (error != -ENOIOCTLCMD)
-+		goto done;
- #endif
- #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
--	if (br2684_ioctl_hook) {
-+	down(&br2684_ioctl_mutex);
-+	if (br2684_ioctl_hook)
- 		error = br2684_ioctl_hook(vcc, cmd, arg);
--		if (error != -ENOIOCTLCMD)
--			goto done;
--	}
-+	up(&br2684_ioctl_mutex);
-+	if (error != -ENOIOCTLCMD)
-+		goto done;
- #endif
- 
- 	error = atm_dev_ioctl(cmd, arg);
---- linux-2.6.0-test1/net/atm/common.h	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/common.h	2003-07-19 17:03:51.000000000 -0700
-@@ -17,7 +17,7 @@ int vcc_recvmsg(struct kiocb *iocb, stru
- 		int size, int flags);
- int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
- 		int total_len);
--unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait);
-+unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
- int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
- int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
- 		   int optlen);
-@@ -26,6 +26,9 @@ int vcc_getsockopt(struct socket *sock, 
- 
- void atm_shutdown_dev(struct atm_dev *dev);
- 
-+void pppoatm_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long));
-+void br2684_ioctl_set(int (*hook)(struct atm_vcc *, unsigned int, unsigned long));
-+
- int atmpvc_init(void);
- void atmpvc_exit(void);
- int atmsvc_init(void);
---- linux-2.6.0-test1/net/atm/lec.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/lec.c	2003-07-19 17:03:51.000000000 -0700
-@@ -134,7 +134,7 @@ static void lec_handle_bridge(struct sk_
-                 priv = (struct lec_priv *)dev->priv;
-                 atm_force_charge(priv->lecd, skb2->truesize);
-                 skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb2);
--                wake_up(&priv->lecd->sleep);
-+                priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb2->len);
-         }
- 
-         return;
-@@ -513,7 +513,7 @@ lec_atm_send(struct atm_vcc *vcc, struct
-                         memcpy(skb2->data, mesg, sizeof(struct atmlec_msg));
-                         atm_force_charge(priv->lecd, skb2->truesize);
-                         skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb2);
--                        wake_up(&priv->lecd->sleep);
-+                        priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb2->len);
-                 }
-                 if (f != NULL) br_fdb_put_hook(f);
- #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
-@@ -598,13 +598,13 @@ send_to_lecd(struct lec_priv *priv, atml
- 
-         atm_force_charge(priv->lecd, skb->truesize);
- 	skb_queue_tail(&priv->lecd->sk->sk_receive_queue, skb);
--        wake_up(&priv->lecd->sleep);
-+        priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb->len);
- 
-         if (data != NULL) {
-                 DPRINTK("lec: about to send %d bytes of data\n", data->len);
-                 atm_force_charge(priv->lecd, data->truesize);
-                 skb_queue_tail(&priv->lecd->sk->sk_receive_queue, data);
--                wake_up(&priv->lecd->sleep);
-+                priv->lecd->sk->sk_data_ready(priv->lecd->sk, skb->len);
-         }
- 
-         return 0;
-@@ -686,7 +686,7 @@ lec_push(struct atm_vcc *vcc, struct sk_
-         if (memcmp(skb->data, lec_ctrl_magic, 4) ==0) { /* Control frame, to daemon*/
-                 DPRINTK("%s: To daemon\n",dev->name);
-                 skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
--                wake_up(&vcc->sleep);
-+                vcc->sk->sk_data_ready(vcc->sk, skb->len);
-         } else { /* Data frame, queue to protocol handlers */
-                 unsigned char *dst;
- 
---- linux-2.6.0-test1/net/atm/mpc.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/mpc.c	2003-07-19 17:03:51.000000000 -0700
-@@ -669,7 +669,7 @@ static void mpc_push(struct atm_vcc *vcc
- 		dprintk("mpoa: (%s) mpc_push: control packet arrived\n", dev->name);
- 		/* Pass control packets to daemon */
- 		skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
--		wake_up(&vcc->sleep);
-+		vcc->sk->sk_data_ready(vcc->sk, skb->len);
- 		return;
- 	}
- 
-@@ -947,7 +947,7 @@ int msg_to_mpoad(struct k_message *mesg,
- 	memcpy(skb->data, mesg, sizeof(struct k_message));
- 	atm_force_charge(mpc->mpoad_vcc, skb->truesize);
- 	skb_queue_tail(&mpc->mpoad_vcc->sk->sk_receive_queue, skb);
--	wake_up(&mpc->mpoad_vcc->sleep);
-+	mpc->mpoad_vcc->sk->sk_data_ready(mpc->mpoad_vcc->sk, skb->len);
- 
- 	return 0;
- }
-@@ -1226,7 +1226,7 @@ static void purge_egress_shortcut(struct
- 
- 	atm_force_charge(vcc, skb->truesize);
- 	skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
--	wake_up(&vcc->sleep);
-+	vcc->sk->sk_data_ready(vcc->sk, skb->len);
- 	dprintk("mpoa: purge_egress_shortcut: exiting:\n");
- 
- 	return;
---- linux-2.6.0-test1/net/atm/pppoatm.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/net/atm/pppoatm.c	2003-07-19 17:03:51.000000000 -0700
-@@ -44,6 +44,8 @@
- #include <linux/ppp_channel.h>
- #include <linux/atmppp.h>
- 
-+#include "common.h"
-+
- #if 0
- #define DPRINTK(format, args...) \
- 	printk(KERN_DEBUG "pppoatm: " format, ##args)
-@@ -344,17 +346,15 @@ static int pppoatm_ioctl(struct atm_vcc 
- /* the following avoids some spurious warnings from the compiler */
- #define UNUSED __attribute__((unused))
- 
--extern int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
--
- static int __init UNUSED pppoatm_init(void)
- {
--	pppoatm_ioctl_hook = pppoatm_ioctl;
-+	pppoatm_ioctl_set(pppoatm_ioctl);
- 	return 0;
- }
- 
- static void __exit UNUSED pppoatm_exit(void)
- {
--	pppoatm_ioctl_hook = NULL;
-+	pppoatm_ioctl_set(NULL);
- }
- 
- module_init(pppoatm_init);
---- linux-2.6.0-test1/net/atm/proc.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/proc.c	2003-07-19 17:03:51.000000000 -0700
-@@ -224,7 +224,7 @@ static void vc_info(struct atm_vcc *vcc,
- 			here += sprintf(here, "%3d", vcc->sk->sk_family);
- 	}
- 	here += sprintf(here," %04lx  %5d %7d/%7d %7d/%7d\n",vcc->flags,
--	    vcc->reply,
-+	    vcc->sk->sk_err,
- 	    atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf,
- 	    atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf);
- }
---- linux-2.6.0-test1/net/atm/pvc.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/pvc.c	2003-07-19 17:03:51.000000000 -0700
-@@ -111,7 +111,7 @@ static struct proto_ops pvc_proto_ops = 
- 	.socketpair =	sock_no_socketpair,
- 	.accept =	sock_no_accept,
- 	.getname =	pvc_getname,
--	.poll =		atm_poll,
-+	.poll =		vcc_poll,
- 	.ioctl =	vcc_ioctl,
- 	.listen =	sock_no_listen,
- 	.shutdown =	pvc_shutdown,
---- linux-2.6.0-test1/net/atm/raw.c	2003-06-14 12:18:34.000000000 -0700
-+++ 25/net/atm/raw.c	2003-07-19 17:03:51.000000000 -0700
-@@ -29,7 +29,7 @@ void atm_push_raw(struct atm_vcc *vcc,st
- {
- 	if (skb) {
- 		skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
--		wake_up(&vcc->sleep);
-+		vcc->sk->sk_data_ready(vcc->sk, skb->len);
- 	}
- }
- 
-@@ -40,7 +40,7 @@ static void atm_pop_raw(struct atm_vcc *
- 		skb->truesize);
- 	atomic_sub(skb->truesize, &vcc->sk->sk_wmem_alloc);
- 	dev_kfree_skb_any(skb);
--	wake_up(&vcc->sleep);
-+	vcc->sk->sk_write_space(vcc->sk);
- }
- 
- 
---- linux-2.6.0-test1/net/atm/signaling.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/signaling.c	2003-07-19 17:03:51.000000000 -0700
-@@ -61,7 +61,7 @@ static void sigd_put_skb(struct sk_buff 
- #endif
- 	atm_force_charge(sigd,skb->truesize);
- 	skb_queue_tail(&sigd->sk->sk_receive_queue,skb);
--	wake_up(&sigd->sleep);
-+	sigd->sk->sk_data_ready(sigd->sk, skb->len);
- }
- 
- 
-@@ -103,7 +103,8 @@ static int sigd_send(struct atm_vcc *vcc
- 	vcc = *(struct atm_vcc **) &msg->vcc;
- 	switch (msg->type) {
- 		case as_okay:
--			vcc->reply = msg->reply;
-+			vcc->sk->sk_err = -msg->reply;
-+			clear_bit(ATM_VF_WAITING, &vcc->flags);
- 			if (!*vcc->local.sas_addr.prv &&
- 			    !*vcc->local.sas_addr.pub) {
- 				vcc->local.sas_family = AF_ATMSVC;
-@@ -123,8 +124,8 @@ static int sigd_send(struct atm_vcc *vcc
- 		case as_error:
- 			clear_bit(ATM_VF_REGIS,&vcc->flags);
- 			clear_bit(ATM_VF_READY,&vcc->flags);
--			vcc->reply = msg->reply;
- 			vcc->sk->sk_err = -msg->reply;
-+			clear_bit(ATM_VF_WAITING, &vcc->flags);
- 			break;
- 		case as_indicate:
- 			vcc = *(struct atm_vcc **) &msg->listen_vcc;
-@@ -137,19 +138,16 @@ static int sigd_send(struct atm_vcc *vcc
- 			}
- 			vcc->sk->sk_ack_backlog++;
- 			skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
--			if (vcc->callback) {
--				DPRINTK("waking vcc->sleep 0x%p\n",
--				    &vcc->sleep);
--				vcc->callback(vcc);
--			}
-+			DPRINTK("waking vcc->sk->sk_sleep 0x%p\n", vcc->sk->sk_sleep);
-+			vcc->sk->sk_state_change(vcc->sk);
- as_indicate_complete:
- 			release_sock(vcc->sk);
- 			return 0;
- 		case as_close:
- 			set_bit(ATM_VF_RELEASED,&vcc->flags);
- 			clear_bit(ATM_VF_READY,&vcc->flags);
--			vcc->reply = msg->reply;
- 			vcc->sk->sk_err = -msg->reply;
-+			clear_bit(ATM_VF_WAITING, &vcc->flags);
- 			break;
- 		case as_modify:
- 			modify_qos(vcc,msg);
-@@ -159,7 +157,7 @@ as_indicate_complete:
- 			    (int) msg->type);
- 			return -EINVAL;
- 	}
--	if (vcc->callback) vcc->callback(vcc);
-+	vcc->sk->sk_state_change(vcc->sk);
- 	dev_kfree_skb(skb);
- 	return 0;
- }
-@@ -205,9 +203,9 @@ static void purge_vcc(struct atm_vcc *vc
- 	if (vcc->sk->sk_family == PF_ATMSVC &&
- 	    !test_bit(ATM_VF_META,&vcc->flags)) {
- 		set_bit(ATM_VF_RELEASED,&vcc->flags);
--		vcc->reply = -EUNATCH;
- 		vcc->sk->sk_err = EUNATCH;
--		wake_up(&vcc->sleep);
-+		clear_bit(ATM_VF_WAITING, &vcc->flags);
-+		vcc->sk->sk_state_change(vcc->sk);
- 	}
- }
- 
---- linux-2.6.0-test1/net/atm/signaling.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/net/atm/signaling.h	2003-07-19 17:03:51.000000000 -0700
-@@ -11,9 +11,6 @@
- #include <linux/atmsvc.h>
- 
- 
--#define WAITING 1 /* for reply: 0: no error, < 0: error, ... */
--
--
- extern struct atm_vcc *sigd; /* needed in svc_release */
- 
- 
---- linux-2.6.0-test1/net/atm/svc.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/atm/svc.c	2003-07-19 17:03:51.000000000 -0700
-@@ -43,14 +43,6 @@ static int svc_create(struct socket *soc
-  */
- 
- 
--void svc_callback(struct atm_vcc *vcc)
--{
--	wake_up(&vcc->sleep);
--}
--
--
--
--
- static int svc_shutdown(struct socket *sock,int how)
- {
- 	return 0;
-@@ -64,13 +56,13 @@ static void svc_disconnect(struct atm_vc
- 
- 	DPRINTK("svc_disconnect %p\n",vcc);
- 	if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
--		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 		sigd_enq(vcc,as_close,NULL,NULL,NULL);
- 		while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
- 			schedule();
--			prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+			prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 		}
--		finish_wait(&vcc->sleep, &wait);
-+		finish_wait(vcc->sk->sk_sleep, &wait);
- 	}
- 	/* beware - socket is still in use by atmsigd until the last
- 	   as_indicate has been answered */
-@@ -145,22 +137,22 @@ static int svc_bind(struct socket *sock,
- 		goto out;
- 	}
- 	vcc->local = *addr;
--	vcc->reply = WAITING;
--	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+	set_bit(ATM_VF_WAITING, &vcc->flags);
-+	prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
--	while (vcc->reply == WAITING && sigd) {
-+	while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
- 		schedule();
--		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	}
--	finish_wait(&vcc->sleep, &wait);
-+	finish_wait(sk->sk_sleep, &wait);
- 	clear_bit(ATM_VF_REGIS,&vcc->flags); /* doesn't count */
- 	if (!sigd) {
- 		error = -EUNATCH;
- 		goto out;
- 	}
--        if (!vcc->reply)
-+        if (!sk->sk_err)
- 		set_bit(ATM_VF_BOUND,&vcc->flags);
--	error = vcc->reply;
-+	error = -sk->sk_err;
- out:
- 	release_sock(sk);
- 	return error;
-@@ -191,13 +183,13 @@ static int svc_connect(struct socket *so
- 		error = -EISCONN;
- 		goto out;
- 	case SS_CONNECTING:
--		if (vcc->reply == WAITING) {
-+		if (test_bit(ATM_VF_WAITING, &vcc->flags)) {
- 			error = -EALREADY;
- 			goto out;
- 		}
- 		sock->state = SS_UNCONNECTED;
--		if (vcc->reply) {
--			error = vcc->reply;
-+		if (sk->sk_err) {
-+			error = -sk->sk_err;
- 			goto out;
- 		}
- 		break;
-@@ -226,20 +218,20 @@ static int svc_connect(struct socket *so
- 			goto out;
- 		}
- 		vcc->remote = *addr;
--		vcc->reply = WAITING;
--		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+		set_bit(ATM_VF_WAITING, &vcc->flags);
-+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 		sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
- 		if (flags & O_NONBLOCK) {
--			finish_wait(&vcc->sleep, &wait);
-+			finish_wait(sk->sk_sleep, &wait);
- 			sock->state = SS_CONNECTING;
- 			error = -EINPROGRESS;
- 			goto out;
- 		}
- 		error = 0;
--		while (vcc->reply == WAITING && sigd) {
-+		while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
- 			schedule();
- 			if (!signal_pending(current)) {
--				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+				prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 				continue;
- 			}
- 			DPRINTK("*ABORT*\n");
-@@ -256,14 +248,14 @@ static int svc_connect(struct socket *so
- 			 *   Kernel <--close--- Demon
- 			 */
- 			sigd_enq(vcc,as_close,NULL,NULL,NULL);
--			while (vcc->reply == WAITING && sigd) {
--				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+			while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
-+				prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 				schedule();
- 			}
--			if (!vcc->reply)
-+			if (!sk->sk_err)
- 				while (!test_bit(ATM_VF_RELEASED,&vcc->flags)
- 				    && sigd) {
--					prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+					prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 					schedule();
- 				}
- 			clear_bit(ATM_VF_REGIS,&vcc->flags);
-@@ -273,15 +265,15 @@ static int svc_connect(struct socket *so
- 			error = -EINTR;
- 			break;
- 		}
--		finish_wait(&vcc->sleep, &wait);
-+		finish_wait(sk->sk_sleep, &wait);
- 		if (error)
- 			goto out;
- 		if (!sigd) {
- 			error = -EUNATCH;
- 			goto out;
- 		}
--		if (vcc->reply) {
--			error = vcc->reply;
-+		if (sk->sk_err) {
-+			error = -sk->sk_err;
- 			goto out;
- 		}
- 	}
-@@ -319,14 +311,14 @@ static int svc_listen(struct socket *soc
- 		error = -EINVAL;
- 		goto out;
- 	}
--	vcc->reply = WAITING;
--	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+	set_bit(ATM_VF_WAITING, &vcc->flags);
-+	prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
--	while (vcc->reply == WAITING && sigd) {
-+	while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
- 		schedule();
--		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	}
--	finish_wait(&vcc->sleep, &wait);
-+	finish_wait(sk->sk_sleep, &wait);
- 	if (!sigd) {
- 		error = -EUNATCH;
- 		goto out;
-@@ -334,7 +326,7 @@ static int svc_listen(struct socket *soc
- 	set_bit(ATM_VF_LISTEN,&vcc->flags);
- 	vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog :
- 						    ATM_BACKLOG_DEFAULT;
--	error = vcc->reply;
-+	error = -sk->sk_err;
- out:
- 	release_sock(sk);
- 	return error;
-@@ -362,12 +354,12 @@ static int svc_accept(struct socket *soc
- 	while (1) {
- 		DEFINE_WAIT(wait);
- 
--		prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+		prepare_to_wait(old_vcc->sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 		while (!(skb = skb_dequeue(&old_vcc->sk->sk_receive_queue)) &&
- 		       sigd) {
- 			if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break;
- 			if (test_bit(ATM_VF_CLOSE,&old_vcc->flags)) {
--				error = old_vcc->reply;
-+				error = -sk->sk_err;
- 				break;
- 			}
- 			if (flags & O_NONBLOCK) {
-@@ -381,9 +373,9 @@ static int svc_accept(struct socket *soc
- 				error = -ERESTARTSYS;
- 				break;
- 			}
--			prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
-+			prepare_to_wait(old_vcc->sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- 		}
--		finish_wait(&old_vcc->sleep, &wait);
-+		finish_wait(old_vcc->sk->sk_sleep, &wait);
- 		if (error)
- 			goto out;
- 		if (!skb) {
-@@ -407,23 +399,24 @@ static int svc_accept(struct socket *soc
- 			goto out;
- 		}
- 		/* wait should be short, so we ignore the non-blocking flag */
--		new_vcc->reply = WAITING;
--		prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+		set_bit(ATM_VF_WAITING, &new_vcc->flags);
-+		prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 		sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
--		while (new_vcc->reply == WAITING && sigd) {
-+		while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) {
- 			release_sock(sk);
- 			schedule();
- 			lock_sock(sk);
--			prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+			prepare_to_wait(new_vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 		}
--		finish_wait(&new_vcc->sleep, &wait);
-+		finish_wait(new_vcc->sk->sk_sleep, &wait);
- 		if (!sigd) {
- 			error = -EUNATCH;
- 			goto out;
- 		}
--		if (!new_vcc->reply) break;
--		if (new_vcc->reply != -ERESTARTSYS) {
--			error = new_vcc->reply;
-+		if (!new_vcc->sk->sk_err)
-+			break;
-+		if (new_vcc->sk->sk_err != ERESTARTSYS) {
-+			error = -new_vcc->sk->sk_err;
- 			goto out;
- 		}
- 	}
-@@ -451,17 +444,17 @@ int svc_change_qos(struct atm_vcc *vcc,s
- {
- 	DEFINE_WAIT(wait);
- 
--	vcc->reply = WAITING;
--	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+	set_bit(ATM_VF_WAITING, &vcc->flags);
-+	prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
--	while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
--	    && sigd) {
-+	while (test_bit(ATM_VF_WAITING, &vcc->flags) &&
-+	       !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) {
- 		schedule();
--		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
-+		prepare_to_wait(vcc->sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
- 	}
--	finish_wait(&vcc->sleep, &wait);
-+	finish_wait(vcc->sk->sk_sleep, &wait);
- 	if (!sigd) return -EUNATCH;
--	return vcc->reply;
-+	return -vcc->sk->sk_err;
- }
- 
- 
-@@ -527,7 +520,7 @@ static struct proto_ops svc_proto_ops = 
- 	.socketpair =	sock_no_socketpair,
- 	.accept =	svc_accept,
- 	.getname =	svc_getname,
--	.poll =		atm_poll,
-+	.poll =		vcc_poll,
- 	.ioctl =	vcc_ioctl,
- 	.listen =	svc_listen,
- 	.shutdown =	svc_shutdown,
-@@ -547,7 +540,6 @@ static int svc_create(struct socket *soc
- 	sock->ops = &svc_proto_ops;
- 	error = vcc_create(sock, protocol, AF_ATMSVC);
- 	if (error) return error;
--	ATM_SD(sock)->callback = svc_callback;
- 	ATM_SD(sock)->local.sas_family = AF_ATMSVC;
- 	ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
- 	return 0;
---- linux-2.6.0-test1/net/core/dev.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/core/dev.c	2003-07-19 17:03:51.000000000 -0700
-@@ -178,7 +178,7 @@ static struct notifier_block *netdev_cha
-  *	Device drivers call our routines to queue packets here. We empty the
-  *	queue in the local softnet handler.
-  */
--struct softnet_data softnet_data[NR_CPUS] __cacheline_aligned;
-+DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, };
- 
- #ifdef CONFIG_NET_FASTROUTE
- int netdev_fastroute;
-@@ -1280,34 +1280,35 @@ static void get_sample_stats(int cpu)
- 	unsigned long rd;
- 	int rq;
- #endif
--	int blog = softnet_data[cpu].input_pkt_queue.qlen;
--	int avg_blog = softnet_data[cpu].avg_blog;
-+	struct softnet_data *sd = &per_cpu(softnet_data, cpu);
-+	int blog = sd->input_pkt_queue.qlen;
-+	int avg_blog = sd->avg_blog;
- 
- 	avg_blog = (avg_blog >> 1) + (blog >> 1);
- 
- 	if (avg_blog > mod_cong) {
- 		/* Above moderate congestion levels. */
--		softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
-+		sd->cng_level = NET_RX_CN_HIGH;
- #ifdef RAND_LIE
- 		rd = net_random();
- 		rq = rd % netdev_max_backlog;
- 		if (rq < avg_blog) /* unlucky bastard */
--			softnet_data[cpu].cng_level = NET_RX_DROP;
-+			sd->cng_level = NET_RX_DROP;
- #endif
- 	} else if (avg_blog > lo_cong) {
--		softnet_data[cpu].cng_level = NET_RX_CN_MOD;
-+		sd->cng_level = NET_RX_CN_MOD;
- #ifdef RAND_LIE
- 		rd = net_random();
- 		rq = rd % netdev_max_backlog;
- 			if (rq < avg_blog) /* unlucky bastard */
--				softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
-+				sd->cng_level = NET_RX_CN_HIGH;
- #endif
- 	} else if (avg_blog > no_cong)
--		softnet_data[cpu].cng_level = NET_RX_CN_LOW;
-+		sd->cng_level = NET_RX_CN_LOW;
- 	else  /* no congestion */
--		softnet_data[cpu].cng_level = NET_RX_SUCCESS;
-+		sd->cng_level = NET_RX_SUCCESS;
- 
--	softnet_data[cpu].avg_blog = avg_blog;
-+	sd->avg_blog = avg_blog;
- }
- 
- #ifdef OFFLINE_SAMPLE
-@@ -1357,7 +1358,7 @@ int netif_rx(struct sk_buff *skb)
- 	 */
- 	local_irq_save(flags);
- 	this_cpu = smp_processor_id();
--	queue = &softnet_data[this_cpu];
-+	queue = &__get_cpu_var(softnet_data);
- 
- 	netdev_rx_stat[this_cpu].total++;
- 	if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
-@@ -1445,14 +1446,14 @@ static __inline__ void skb_bond(struct s
- 
- static void net_tx_action(struct softirq_action *h)
- {
--	int cpu = smp_processor_id();
-+	struct softnet_data *sd = &__get_cpu_var(softnet_data);
- 
--	if (softnet_data[cpu].completion_queue) {
-+	if (sd->completion_queue) {
- 		struct sk_buff *clist;
- 
- 		local_irq_disable();
--		clist = softnet_data[cpu].completion_queue;
--		softnet_data[cpu].completion_queue = NULL;
-+		clist = sd->completion_queue;
-+		sd->completion_queue = NULL;
- 		local_irq_enable();
- 
- 		while (clist) {
-@@ -1464,12 +1465,12 @@ static void net_tx_action(struct softirq
- 		}
- 	}
- 
--	if (softnet_data[cpu].output_queue) {
-+	if (sd->output_queue) {
- 		struct net_device *head;
- 
- 		local_irq_disable();
--		head = softnet_data[cpu].output_queue;
--		softnet_data[cpu].output_queue = NULL;
-+		head = sd->output_queue;
-+		sd->output_queue = NULL;
- 		local_irq_enable();
- 
- 		while (head) {
-@@ -1611,8 +1612,7 @@ static int process_backlog(struct net_de
- {
- 	int work = 0;
- 	int quota = min(backlog_dev->quota, *budget);
--	int this_cpu = smp_processor_id();
--	struct softnet_data *queue = &softnet_data[this_cpu];
-+	struct softnet_data *queue = &__get_cpu_var(softnet_data);
- 	unsigned long start_time = jiffies;
- 
- 	for (;;) {
-@@ -1673,7 +1673,7 @@ job_done:
- static void net_rx_action(struct softirq_action *h)
- {
- 	int this_cpu = smp_processor_id();
--	struct softnet_data *queue = &softnet_data[this_cpu];
-+	struct softnet_data *queue = &__get_cpu_var(softnet_data);
- 	unsigned long start_time = jiffies;
- 	int budget = netdev_max_backlog;
- 
-@@ -2979,7 +2979,7 @@ static int __init net_dev_init(void)
- 	for (i = 0; i < NR_CPUS; i++) {
- 		struct softnet_data *queue;
- 
--		queue = &softnet_data[i];
-+		queue = &per_cpu(softnet_data, i);
- 		skb_queue_head_init(&queue->input_pkt_queue);
- 		queue->throttle = 0;
- 		queue->cng_level = 0;
---- linux-2.6.0-test1/net/ipv4/ip_gre.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/ipv4/ip_gre.c	2003-07-19 17:03:51.000000000 -0700
-@@ -816,6 +816,7 @@ static int ipgre_tunnel_xmit(struct sk_b
- 			skb_set_owner_w(new_skb, skb->sk);
- 		dev_kfree_skb(skb);
- 		skb = new_skb;
-+		old_iph = skb->nh.iph;
- 	}
- 
- 	skb->nh.raw = skb_push(skb, gre_hlen);
---- linux-2.6.0-test1/net/ipv4/ipip.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/ipv4/ipip.c	2003-07-19 17:03:51.000000000 -0700
-@@ -616,6 +616,7 @@ static int ipip_tunnel_xmit(struct sk_bu
- 			skb_set_owner_w(new_skb, skb->sk);
- 		dev_kfree_skb(skb);
- 		skb = new_skb;
-+		old_iph = skb->nh.iph;
- 	}
- 
- 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
---- linux-2.6.0-test1/net/ipv4/ipvs/ip_vs_conn.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv4/ipvs/ip_vs_conn.c	2003-07-19 17:03:51.000000000 -0700
-@@ -507,9 +507,6 @@ static void ip_vs_conn_expire(unsigned l
- 	 *	refcnt==1 implies I'm the only one referrer
- 	 */
- 	if (likely(atomic_read(&cp->refcnt) == 1)) {
--		/* make sure that there is no timer on it now */
--		del_timer_sync(&cp->timer);
--
- 		/* does anybody control me? */
- 		if (cp->control)
- 			ip_vs_control_del(cp);
-@@ -517,7 +514,6 @@ static void ip_vs_conn_expire(unsigned l
- 		if (unlikely(cp->app != NULL))
- 			ip_vs_unbind_app(cp);
- 		ip_vs_unbind_dest(cp);
--		//ip_vs_timeout_detach(cp);
- 		if (cp->flags & IP_VS_CONN_F_NO_CPORT)
- 			atomic_dec(&ip_vs_conn_no_cport_cnt);
- 		atomic_dec(&ip_vs_conn_count);
---- linux-2.6.0-test1/net/ipv4/ipvs/ip_vs_ctl.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv4/ipvs/ip_vs_ctl.c	2003-07-19 17:03:51.000000000 -0700
-@@ -93,7 +93,7 @@ int ip_vs_get_debug_level(void)
- /*
-  *	update_defense_level is called from timer bh and from sysctl.
-  */
--void update_defense_level(void)
-+static void update_defense_level(void)
- {
- 	struct sysinfo i;
- 	static int old_secure_tcp = 0;
-@@ -210,6 +210,22 @@ void update_defense_level(void)
- }
- 
- 
-+/*
-+ *	Timer for checking the defense
-+ */
-+static struct timer_list defense_timer;
-+#define DEFENSE_TIMER_PERIOD	1*HZ
-+
-+static void defense_timer_handler(unsigned long data)
-+{
-+	update_defense_level();
-+	if (atomic_read(&ip_vs_dropentry))
-+		ip_vs_random_dropentry();
-+
-+	mod_timer(&defense_timer, jiffies + DEFENSE_TIMER_PERIOD);
-+}
-+
-+
- int
- ip_vs_use_count_inc(void)
- {
-@@ -2187,6 +2203,12 @@ int ip_vs_control_init(void)
- 	ip_vs_stats.lock = SPIN_LOCK_UNLOCKED;
- 	ip_vs_new_estimator(&ip_vs_stats);
- 
-+	/* Hook the defense timer */
-+	init_timer(&defense_timer);
-+	defense_timer.function = defense_timer_handler;
-+	defense_timer.expires = jiffies + DEFENSE_TIMER_PERIOD;
-+	add_timer(&defense_timer);
-+
- 	LeaveFunction(2);
- 	return 0;
- }
-@@ -2196,6 +2218,7 @@ void ip_vs_control_cleanup(void)
- {
- 	EnterFunction(2);
- 	ip_vs_trash_cleanup();
-+	del_timer_sync(&defense_timer);
- 	ip_vs_kill_estimator(&ip_vs_stats);
- 	unregister_sysctl_table(ipv4_vs_table.sysctl_header);
- 	proc_net_remove("ip_vs_stats");
---- linux-2.6.0-test1/net/ipv4/ipvs/ip_vs_xmit.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv4/ipvs/ip_vs_xmit.c	2003-07-19 17:03:51.000000000 -0700
-@@ -78,7 +78,6 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp
- 						.daddr = dest->addr,
- 						.saddr = 0,
- 						.tos = rtos, } },
--				.proto = cp->protocol,
- 			};
- 
- 			if (ip_route_output_key(&rt, &fl)) {
-@@ -102,7 +101,6 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp
- 					.daddr = dest->addr,
- 					.saddr = 0,
- 					.tos = rtos, } },
--			.proto = cp->protocol,
- 		};
- 
- 		if (ip_route_output_key(&rt, &fl)) {
---- linux-2.6.0-test1/net/ipv4/ipvs/Kconfig	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv4/ipvs/Kconfig	2003-07-19 17:03:51.000000000 -0700
-@@ -147,7 +147,7 @@ config	IP_VS_WLC
- 	  unsure, say N.
- 
- config	IP_VS_LBLC
--	tristate "locality-based least-connection with replication scheduling"
-+	tristate "locality-based least-connection scheduling"
-         depends on IP_VS
- 	---help---
- 	  The locality-based least-connection scheduling algorithm is for
-@@ -163,7 +163,7 @@ config	IP_VS_LBLC
- 	  unsure, say N.
- 
- config  IP_VS_LBLCR
--	tristate "locality-based least-connection with replication schedulin"
-+	tristate "locality-based least-connection with replication scheduling"
-         depends on IP_VS
- 	---help---
- 	  The locality-based least-connection with replication scheduling
---- linux-2.6.0-test1/net/ipv4/tcp_input.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv4/tcp_input.c	2003-07-19 17:03:51.000000000 -0700
-@@ -2373,7 +2373,7 @@ static void tcp_fin(struct sk_buff *skb,
- 	tcp_schedule_ack(tp);
- 
- 	sk->sk_shutdown |= RCV_SHUTDOWN;
--	sock_reset_flag(sk, SOCK_DONE);
-+	sock_set_flag(sk, SOCK_DONE);
- 
- 	switch (sk->sk_state) {
- 		case TCP_SYN_RECV:
---- linux-2.6.0-test1/net/ipv6/addrconf.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/ipv6/addrconf.c	2003-07-19 17:03:51.000000000 -0700
-@@ -368,7 +368,8 @@ static struct inet6_dev * ipv6_add_dev(s
- 				dev, dev->name);
- 			ndev->cnf.use_tempaddr = -1;
- 		} else {
--			__ipv6_regen_rndid(ndev);
-+			in6_dev_hold(ndev);
-+			ipv6_regen_rndid((unsigned long) ndev);
- 		}
- #endif
- 
-@@ -1122,9 +1123,6 @@ static int __ipv6_regen_rndid(struct ine
- 	sg[1].offset = ((long) eui64 & ~PAGE_MASK);
- 	sg[1].length = 8;
- 
--	if (!del_timer(&idev->regen_timer))
--		in6_dev_hold(idev);
--
- 	dev = idev->dev;
- 
- 	if (ipv6_generate_eui64(eui64, dev)) {
-@@ -1137,7 +1135,6 @@ regen:
- 	spin_lock(&md5_tfm_lock);
- 	if (unlikely(md5_tfm == NULL)) {
- 		spin_unlock(&md5_tfm_lock);
--		in6_dev_put(idev);
- 		return -1;
- 	}
- 	crypto_digest_init(md5_tfm);
-@@ -1170,33 +1167,41 @@ regen:
- 		if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
- 			goto regen;
- 	}
--	
--	idev->regen_timer.expires = jiffies +
--					idev->cnf.temp_prefered_lft * HZ - 
--					idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
--	if (time_before(idev->regen_timer.expires, jiffies)) {
--		idev->regen_timer.expires = 0;
--		printk(KERN_WARNING
--			"__ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n",
--			idev->dev->name);
--		in6_dev_put(idev);
--		return -1;
--	}
- 
--	add_timer(&idev->regen_timer);
- 	return 0;
- }
- 
- static void ipv6_regen_rndid(unsigned long data)
- {
- 	struct inet6_dev *idev = (struct inet6_dev *) data;
-+	unsigned long expires;
- 
- 	read_lock_bh(&addrconf_lock);
- 	write_lock_bh(&idev->lock);
--	if (!idev->dead)
--		__ipv6_regen_rndid(idev);
-+
-+	if (idev->dead)
-+		goto out;
-+
-+	if (__ipv6_regen_rndid(idev) < 0)
-+		goto out;
-+	
-+	expires = jiffies +
-+		idev->cnf.temp_prefered_lft * HZ - 
-+		idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
-+	if (time_before(expires, jiffies)) {
-+		printk(KERN_WARNING
-+			"ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n",
-+			idev->dev->name);
-+		goto out;
-+	}
-+
-+	if (!mod_timer(&idev->regen_timer, expires))
-+		in6_dev_hold(idev);
-+
-+out:
- 	write_unlock_bh(&idev->lock);
- 	read_unlock_bh(&addrconf_lock);
-+	in6_dev_put(idev);
- }
- 
- static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) {
-@@ -1928,6 +1933,27 @@ static int addrconf_ifdown(struct net_de
- 	/* Step 3: clear address list */
- 
- 	write_lock_bh(&idev->lock);
-+#ifdef CONFIG_IPV6_PRIVACY
-+	if (how == 1 && del_timer(&idev->regen_timer))
-+		in6_dev_put(idev);
-+
-+	/* clear tempaddr list */
-+	while ((ifa = idev->tempaddr_list) != NULL) {
-+		idev->tempaddr_list = ifa->tmp_next;
-+		ifa->tmp_next = NULL;
-+		ifa->dead = 1;
-+		write_unlock_bh(&idev->lock);
-+		spin_lock_bh(&ifa->lock);
-+
-+		if (ifa->ifpub) {
-+			in6_ifa_put(ifa->ifpub);
-+			ifa->ifpub = NULL;
-+		}
-+		spin_unlock_bh(&ifa->lock);
-+		in6_ifa_put(ifa);
-+		write_lock_bh(&idev->lock);
-+	}
-+#endif
- 	while ((ifa = idev->addr_list) != NULL) {
- 		idev->addr_list = ifa->if_next;
- 		ifa->if_next = NULL;
---- linux-2.6.0-test1/net/ipv6/ah6.c	2003-06-16 22:32:21.000000000 -0700
-+++ 25/net/ipv6/ah6.c	2003-07-19 17:03:51.000000000 -0700
-@@ -19,7 +19,7 @@
-  *
-  *	Mitsuru KANDA @USAGI       : IPv6 Support 
-  * 	Kazunori MIYAZAWA @USAGI   :
-- * 	Kunihiro Ishiguro          :
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 	
-  * 	This file is derived from net/ipv4/ah.c.
-  */
---- linux-2.6.0-test1/net/ipv6/esp6.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/net/ipv6/esp6.c	2003-07-19 17:03:51.000000000 -0700
-@@ -19,7 +19,7 @@
-  *
-  *	Mitsuru KANDA @USAGI       : IPv6 Support 
-  * 	Kazunori MIYAZAWA @USAGI   :
-- * 	Kunihiro Ishiguro          :
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 	
-  * 	This file is derived from net/ipv4/esp.c
-  */
---- linux-2.6.0-test1/net/ipv6/route.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/ipv6/route.c	2003-07-19 17:03:51.000000000 -0700
-@@ -567,6 +567,11 @@ struct dst_entry *ndisc_dst_alloc(struct
- 	if (unlikely(rt == NULL))
- 		goto out;
- 
-+	if (dev)
-+		dev_hold(dev);
-+	if (neigh)
-+		neigh_hold(neigh);
-+
- 	rt->rt6i_dev	  = dev;
- 	rt->rt6i_nexthop  = neigh;
- 	rt->rt6i_expires  = 0;
---- linux-2.6.0-test1/net/ipv6/sit.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/ipv6/sit.c	2003-07-19 17:03:51.000000000 -0700
-@@ -550,6 +550,7 @@ static int ipip6_tunnel_xmit(struct sk_b
- 			skb_set_owner_w(new_skb, skb->sk);
- 		dev_kfree_skb(skb);
- 		skb = new_skb;
-+		iph6 = skb->nh.ipv6h;
- 	}
- 
- 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
---- linux-2.6.0-test1/net/ipv6/tcp_ipv6.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/ipv6/tcp_ipv6.c	2003-07-19 17:03:51.000000000 -0700
-@@ -579,7 +579,7 @@ static int tcp_v6_connect(struct sock *s
- 
- 	addr_type = ipv6_addr_type(&usin->sin6_addr);
- 
--	if(addr_type & IPV6_ADDR_MULTICAST)
-+	if (addr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
- 		return -ENETUNREACH;
- 
- 	if (addr_type&IPV6_ADDR_LINKLOCAL) {
-@@ -967,12 +967,14 @@ static void tcp_v6_send_reset(struct sk_
- 	struct tcphdr *th = skb->h.th, *t1; 
- 	struct sk_buff *buff;
- 	struct flowi fl;
-+	int daddr_type;
- 
- 	if (th->rst)
- 		return;
- 
--	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
--		return; 
-+	daddr_type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
-+	if (daddr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
-+		return;
- 
- 	/*
- 	 * We need to grab some memory, and put together an RST,
-@@ -1171,13 +1173,14 @@ static int tcp_v6_conn_request(struct so
- 	struct tcp_opt tmptp, *tp = tcp_sk(sk);
- 	struct open_request *req = NULL;
- 	__u32 isn = TCP_SKB_CB(skb)->when;
-+	int daddr_type;
- 
- 	if (skb->protocol == htons(ETH_P_IP))
- 		return tcp_v4_conn_request(sk, skb);
- 
--	/* FIXME: do the same check for anycast */
--	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
--		goto drop; 
-+	daddr_type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
-+	if (daddr_type & (IPV6_ADDR_ANYCAST | IPV6_ADDR_MULTICAST))
-+		goto drop;
- 
- 	/*
- 	 *	There are no SYN attacks on IPv6, yet...	
---- linux-2.6.0-test1/net/ipv6/xfrm6_input.c	2003-07-02 14:53:18.000000000 -0700
-+++ 25/net/ipv6/xfrm6_input.c	2003-07-19 17:03:51.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Authors:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  *	YOSHIFUJI Hideaki @USAGI
-  *		IPv6 support
-  */
---- linux-2.6.0-test1/net/ipv6/xfrm6_policy.c	2003-06-22 12:04:45.000000000 -0700
-+++ 25/net/ipv6/xfrm6_policy.c	2003-07-19 17:03:51.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Authors:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 		IPv6 support
-  * 	YOSHIFUJI Hideaki
-  * 		Split up af-specific portion
---- linux-2.6.0-test1/net/ipv6/xfrm6_state.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/net/ipv6/xfrm6_state.c	2003-07-19 17:03:51.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Authors:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 		IPv6 support
-  * 	YOSHIFUJI Hideaki @USAGI
-  * 		Split up af-specific portion
---- linux-2.6.0-test1/net/netsyms.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/netsyms.c	2003-07-19 17:03:51.000000000 -0700
-@@ -685,7 +685,7 @@ EXPORT_SYMBOL(ip_route_me_harder);
- 
- EXPORT_SYMBOL(register_gifconf);
- 
--EXPORT_SYMBOL(softnet_data);
-+EXPORT_PER_CPU_SYMBOL(softnet_data);
- 
- #ifdef CONFIG_NET_RADIO
- #include <net/iw_handler.h>		/* Wireless Extensions driver API */
---- linux-2.6.0-test1/net/sunrpc/auth_gss/auth_gss.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/net/sunrpc/auth_gss/auth_gss.c	2003-07-19 17:03:51.000000000 -0700
-@@ -235,7 +235,7 @@ gss_parse_init_downcall(struct gss_api_m
- 		goto err;
- 	}
- 	ctx->gc_proc = RPC_GSS_PROC_DATA;
--	ctx->gc_seq = 0;
-+	ctx->gc_seq = 1;	/* NetApp 6.4R1 doesn't accept seq. no. 0 */
- 	spin_lock_init(&ctx->gc_seq_lock);
- 	atomic_set(&ctx->count,1);
- 
---- linux-2.6.0-test1/net/sunrpc/clnt.c	2003-06-14 12:18:07.000000000 -0700
-+++ 25/net/sunrpc/clnt.c	2003-07-19 17:07:18.000000000 -0700
-@@ -385,7 +385,8 @@ rpc_setbufsize(struct rpc_clnt *clnt, un
- 	xprt->rcvsize = 0;
- 	if (rcvsize)
- 		xprt->rcvsize = rcvsize + RPC_SLACK_SPACE;
--	xprt_sock_setbufsize(xprt);
-+	if (xprt_connected(xprt))
-+		xprt_sock_setbufsize(xprt);
- }
- 
- /*
-@@ -743,14 +744,14 @@ call_timeout(struct rpc_task *task)
- 
- 	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
- 	if (clnt->cl_softrtry) {
--		if (clnt->cl_chatty && !task->tk_exit)
-+		if (clnt->cl_chatty)
- 			printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
- 				clnt->cl_protname, clnt->cl_server);
- 		rpc_exit(task, -EIO);
- 		return;
- 	}
- 
--	if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN) && rpc_ntimeo(&clnt->cl_rtt) > 7) {
-+	if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) {
- 		task->tk_flags |= RPC_CALL_MAJORSEEN;
- 		printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
- 			clnt->cl_protname, clnt->cl_server);
---- linux-2.6.0-test1/net/sunrpc/xprt.c	2003-06-14 12:18:25.000000000 -0700
-+++ 25/net/sunrpc/xprt.c	2003-07-19 17:07:18.000000000 -0700
-@@ -436,6 +436,7 @@ xprt_connect(struct rpc_task *task)
- 		goto out_write;
- 	}
- 	xprt_bind_socket(xprt, sock);
-+	xprt_sock_setbufsize(xprt);
- 
- 	if (!xprt->stream)
- 		goto out_write;
-@@ -1041,21 +1042,6 @@ out:
- }
- 
- /*
-- * Exponential backoff for UDP retries
-- */
--static inline int
--xprt_expbackoff(struct rpc_task *task, struct rpc_rqst *req)
--{
--	int backoff;
--
--	req->rq_ntimeo++;
--	backoff = min(rpc_ntimeo(&task->tk_client->cl_rtt), XPRT_MAX_BACKOFF);
--	if (req->rq_ntimeo < (1 << backoff))
--		return 1;
--	return 0;
--}
--
--/*
-  * RPC receive timeout handler.
-  */
- static void
-@@ -1068,14 +1054,7 @@ xprt_timer(struct rpc_task *task)
- 	if (req->rq_received)
- 		goto out;
- 
--	if (!xprt->nocong) {
--		if (xprt_expbackoff(task, req)) {
--			rpc_add_timer(task, xprt_timer);
--			goto out_unlock;
--		}
--		rpc_inc_timeo(&task->tk_client->cl_rtt);
--		xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT);
--	}
-+	xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT);
- 	req->rq_nresend++;
- 
- 	dprintk("RPC: %4d xprt_timer (%s request)\n",
-@@ -1085,7 +1064,6 @@ xprt_timer(struct rpc_task *task)
- out:
- 	task->tk_timeout = 0;
- 	rpc_wake_up_task(task);
--out_unlock:
- 	spin_unlock(&xprt->sock_lock);
- }
- 
-@@ -1221,16 +1199,17 @@ xprt_transmit(struct rpc_task *task)
- 	return;
-  out_receive:
- 	dprintk("RPC: %4d xmit complete\n", task->tk_pid);
-+	spin_lock_bh(&xprt->sock_lock);
- 	/* Set the task's receive timeout value */
- 	if (!xprt->nocong) {
- 		task->tk_timeout = rpc_calc_rto(&clnt->cl_rtt,
- 				task->tk_msg.rpc_proc->p_timer);
--		req->rq_ntimeo = 0;
-+		task->tk_timeout <<= clnt->cl_timeout.to_retries
-+			- req->rq_timeout.to_retries;
- 		if (task->tk_timeout > req->rq_timeout.to_maxval)
- 			task->tk_timeout = req->rq_timeout.to_maxval;
- 	} else
- 		task->tk_timeout = req->rq_timeout.to_current;
--	spin_lock_bh(&xprt->sock_lock);
- 	/* Don't race with disconnect */
- 	if (!xprt_connected(xprt))
- 		task->tk_status = -ENOTCONN;
---- linux-2.6.0-test1/net/wanrouter/wanmain.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/wanrouter/wanmain.c	2003-07-19 17:03:51.000000000 -0700
-@@ -668,7 +668,7 @@ static int wanrouter_device_stat(struct 
- static int wanrouter_device_new_if(struct wan_device *wandev,
- 				   wanif_conf_t *u_conf)
- {
--	wanif_conf_t conf;
-+	wanif_conf_t *cnf;
- 	struct net_device *dev = NULL;
- #ifdef CONFIG_WANPIPE_MULTPPP
- 	struct ppp_device *pppdev=NULL;
-@@ -678,38 +678,47 @@ static int wanrouter_device_new_if(struc
- 	if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
- 		return -ENODEV;
- 
--	if (copy_from_user(&conf, u_conf, sizeof(wanif_conf_t)))
--		return -EFAULT;
--
--	if (conf.magic != ROUTER_MAGIC)
--		return -EINVAL;
-+	cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL);
-+	if (!cnf)
-+		return -ENOBUFS;
-+
-+	err = -EFAULT;
-+	if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t)))
-+		goto out;
-+
-+	err = -EINVAL;
-+	if (cnf->magic != ROUTER_MAGIC)
-+		goto out;
- 
--	if (conf.config_id == WANCONFIG_MPPP) {
-+	if (cnf->config_id == WANCONFIG_MPPP) {
- #ifdef CONFIG_WANPIPE_MULTPPP
- 		pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
-+		err = -ENOBUFS;
- 		if (pppdev == NULL)
--			return -ENOBUFS;
-+			goto out;
- 		memset(pppdev, 0, sizeof(struct ppp_device));
- 		pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
- 		if (pppdev->dev == NULL) {
- 			kfree(pppdev);
--			return -ENOBUFS;
-+			err = -ENOBUFS;
-+			goto out;
- 		}
- 		memset(pppdev->dev, 0, sizeof(struct net_device));
--		err = wandev->new_if(wandev,
--				     (struct net_device *)pppdev, &conf);
-+		err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);
- 		dev = pppdev->dev;
- #else
- 		printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
- 				wandev->name);
--		return -EPROTONOSUPPORT;
-+		err = -EPROTONOSUPPORT;
-+		goto out;
- #endif
- 	} else {
- 		dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-+		err = -ENOBUFS;
- 		if (dev == NULL)
--			return -ENOBUFS;
-+			goto out;
- 		memset(dev, 0, sizeof(struct net_device));
--		err = wandev->new_if(wandev, dev, &conf);
-+		err = wandev->new_if(wandev, dev, cnf);
- 	}
- 
- 	if (!err) {
-@@ -748,7 +757,8 @@ static int wanrouter_device_new_if(struc
- 				++wandev->ndev;
- 
- 				unlock_adapter_irq(&wandev->lock, &smp_flags);
--				return 0;	/* done !!! */
-+				err = 0;	/* done !!! */
-+				goto out;
- 			}
- 		}
- 		if (wandev->del_if)
-@@ -761,18 +771,19 @@ static int wanrouter_device_new_if(struc
- 		dev->priv = NULL;
- 	}
- 
--
- #ifdef CONFIG_WANPIPE_MULTPPP
--	if (conf.config_id == WANCONFIG_MPPP)
-+	if (cnf->config_id == WANCONFIG_MPPP)
- 		kfree(pppdev);
- 	else
- 		kfree(dev);
- #else
- 	/* Sync PPP is disabled */
--	if (conf.config_id != WANCONFIG_MPPP)
-+	if (cnf->config_id != WANCONFIG_MPPP)
- 		kfree(dev);
- #endif
- 
-+out:
-+	kfree(cnf);
- 	return err;
- }
- 
---- linux-2.6.0-test1/net/xfrm/xfrm_policy.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/net/xfrm/xfrm_policy.c	2003-07-19 17:03:51.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Changes:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 		IPv6 support
-  * 	Kazunori MIYAZAWA @USAGI
-  * 	YOSHIFUJI Hideaki
---- linux-2.6.0-test1/net/xfrm/xfrm_state.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/xfrm/xfrm_state.c	2003-07-19 17:03:51.000000000 -0700
-@@ -4,7 +4,7 @@
-  * Changes:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 		IPv6 support
-  * 	YOSHIFUJI Hideaki @USAGI
-  * 		Split up af-specific functions
---- linux-2.6.0-test1/net/xfrm/xfrm_user.c	2003-07-10 18:50:32.000000000 -0700
-+++ 25/net/xfrm/xfrm_user.c	2003-07-19 17:03:51.000000000 -0700
-@@ -5,7 +5,7 @@
-  * Changes:
-  *	Mitsuru KANDA @USAGI
-  * 	Kazunori MIYAZAWA @USAGI
-- * 	Kunihiro Ishiguro
-+ * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
-  * 		IPv6 support
-  * 	
-  */
---- linux-2.6.0-test1/scripts/ver_linux	2003-07-10 18:50:32.000000000 -0700
-+++ 25/scripts/ver_linux	2003-07-19 17:03:51.000000000 -0700
-@@ -54,11 +54,14 @@ pppd --version 2>&1| grep version | awk 
- isdnctrl 2>&1 | grep version | awk \
- 'NR==1{print "isdn4k-utils          ", $NF}'
- 
-+showmount --version 2>&1 | grep nfs-utils | awk \
-+'NR==1{print "nfs-utils             ", $NF}'
-+
- ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \
- -e 's/\.so$//' | awk -F'[.-]'   '{print "Linux C Library        " \
- $(NF-2)"."$(NF-1)"."$NF}'
- 
--ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -1 | awk \
-+ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -n 1 | awk \
- 'NR==1{print "Dynamic linker (ldd)  ", $NF}'
- 
- ls -l /usr/lib/lib{g,stdc}++.so  2>/dev/null | awk -F. \
---- linux-2.6.0-test1/security/Kconfig	2003-06-14 12:18:25.000000000 -0700
-+++ 25/security/Kconfig	2003-07-19 17:04:47.000000000 -0700
-@@ -44,5 +44,7 @@ config SECURITY_ROOTPLUG
- 	  
- 	  If you are unsure how to answer this question, answer N.
- 
-+source security/selinux/Kconfig
-+
- endmenu
- 
---- linux-2.6.0-test1/security/Makefile	2003-06-14 12:18:28.000000000 -0700
-+++ 25/security/Makefile	2003-07-19 17:04:47.000000000 -0700
-@@ -2,6 +2,8 @@
- # Makefile for the kernel security code
- #
- 
-+subdir-$(CONFIG_SECURITY_SELINUX)	+= selinux
-+
- # if we don't select a security model, use the default capabilities
- ifneq ($(CONFIG_SECURITY),y)
- obj-y		+= capability.o
-@@ -9,5 +11,9 @@ endif
- 
- # Object file lists
- obj-$(CONFIG_SECURITY)			+= security.o dummy.o
-+# Must precede capability.o in order to stack properly.
-+ifeq ($(CONFIG_SECURITY_SELINUX),y)
-+	obj-$(CONFIG_SECURITY_SELINUX)	+= selinux/built-in.o
-+endif
- obj-$(CONFIG_SECURITY_CAPABILITIES)	+= capability.o
- obj-$(CONFIG_SECURITY_ROOTPLUG)		+= root_plug.o
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/avc.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,1115 @@
-+/*
-+ * Implementation of the kernel access vector cache (AVC).
-+ *
-+ * Authors:  Stephen Smalley, <sds@epoch.ncsc.mil>
-+ *           James Morris <jmorris@redhat.com>
-+ *
-+ * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
-+ *
-+ *	This program is free software; you can redistribute it and/or modify
-+ *	it under the terms of the GNU General Public License version 2,
-+ *      as published by the Free Software Foundation.
-+ */
-+#include <linux/types.h>
-+#include <linux/stddef.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/fs.h>
-+#include <linux/dcache.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <linux/un.h>
-+#include <net/af_unix.h>
-+#include <linux/ip.h>
-+#include <linux/udp.h>
-+#include <linux/tcp.h>
-+#include "avc.h"
-+#include "avc_ss.h"
-+#include "class_to_string.h"
-+#include "common_perm_to_string.h"
-+#include "av_inherit.h"
-+#include "av_perm_to_string.h"
-+#include "objsec.h"
-+
-+#define AVC_CACHE_SLOTS		512
-+#define AVC_CACHE_MAXNODES	410
-+
-+struct avc_entry {
-+	u32			ssid;
-+	u32			tsid;
-+	u16			tclass;
-+	struct av_decision	avd;
-+	int			used;	/* used recently */
-+};
-+
-+struct avc_node {
-+	struct avc_entry	ae;
-+	struct avc_node		*next;
-+};
-+
-+struct avc_cache {
-+	struct avc_node	*slots[AVC_CACHE_SLOTS];
-+	u32		lru_hint;	/* LRU hint for reclaim scan */
-+	u32		active_nodes;
-+	u32		latest_notif;	/* latest revocation notification */
-+};
-+
-+struct avc_callback_node {
-+	int (*callback) (u32 event, u32 ssid, u32 tsid,
-+	                 u16 tclass, u32 perms,
-+	                 u32 *out_retained);
-+	u32 events;
-+	u32 ssid;
-+	u32 tsid;
-+	u16 tclass;
-+	u32 perms;
-+	struct avc_callback_node *next;
-+};
-+
-+static spinlock_t avc_lock = SPIN_LOCK_UNLOCKED;
-+static spinlock_t avc_log_lock = SPIN_LOCK_UNLOCKED;
-+static struct avc_node *avc_node_freelist = NULL;
-+static struct avc_cache avc_cache;
-+static char *avc_audit_buffer = NULL;
-+static unsigned avc_cache_stats[AVC_NSTATS];
-+static struct avc_callback_node *avc_callbacks = NULL;
-+static unsigned int avc_log_level = 4; /* default:  KERN_WARNING */
-+static char avc_level_string[4] = "< >";
-+
-+static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
-+{
-+	return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
-+}
-+
-+/**
-+ * avc_dump_av - Display an access vector in human-readable form.
-+ * @tclass: target security class
-+ * @av: access vector
-+ */
-+void avc_dump_av(u16 tclass, u32 av)
-+{
-+	char **common_pts = 0;
-+	u32 common_base = 0;
-+	int i, i2, perm;
-+
-+	if (av == 0) {
-+		printk(" null");
-+		return;
-+	}
-+
-+	for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
-+		if (av_inherit[i].tclass == tclass) {
-+			common_pts = av_inherit[i].common_pts;
-+			common_base = av_inherit[i].common_base;
-+			break;
-+		}
-+	}
-+
-+	printk(" {");
-+	i = 0;
-+	perm = 1;
-+	while (perm < common_base) {
-+		if (perm & av)
-+			printk(" %s", common_pts[i]);
-+		i++;
-+		perm <<= 1;
-+	}
-+
-+	while (i < sizeof(av) * 8) {
-+		if (perm & av) {
-+			for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) {
-+				if ((av_perm_to_string[i2].tclass == tclass) &&
-+				    (av_perm_to_string[i2].value == perm))
-+					break;
-+			}
-+			if (i2 < ARRAY_SIZE(av_perm_to_string))
-+				printk(" %s", av_perm_to_string[i2].name);
-+		}
-+		i++;
-+		perm <<= 1;
-+	}
-+
-+	printk(" }");
-+}
-+
-+/**
-+ * avc_dump_query - Display a SID pair and a class in human-readable form.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ */
-+void avc_dump_query(u32 ssid, u32 tsid, u16 tclass)
-+{
-+	int rc;
-+	char *scontext;
-+	u32 scontext_len;
-+
-+ 	rc = security_sid_to_context(ssid, &scontext, &scontext_len);
-+	if (rc)
-+		printk("ssid=%d", ssid);
-+	else {
-+		printk("scontext=%s", scontext);
-+		kfree(scontext);
-+	}
-+
-+	rc = security_sid_to_context(tsid, &scontext, &scontext_len);
-+	if (rc)
-+		printk(" tsid=%d", tsid);
-+	else {
-+		printk(" tcontext=%s", scontext);
-+		kfree(scontext);
-+	}
-+	printk(" tclass=%s", class_to_string[tclass]);
-+}
-+
-+/**
-+ * avc_init - Initialize the AVC.
-+ *
-+ * Initialize the access vector cache.
-+ */
-+void avc_init(void)
-+{
-+	struct avc_node	*new;
-+	int i;
-+
-+	for (i = 0; i < AVC_NSTATS; i++)
-+		avc_cache_stats[i] = 0;
-+
-+	for (i = 0; i < AVC_CACHE_SLOTS; i++)
-+		avc_cache.slots[i] = 0;
-+	avc_cache.lru_hint = 0;
-+	avc_cache.active_nodes = 0;
-+	avc_cache.latest_notif = 0;
-+
-+	for (i = 0; i < AVC_CACHE_MAXNODES; i++) {
-+		new = kmalloc(sizeof(*new), GFP_ATOMIC);
-+		if (!new) {
-+			printk(KERN_WARNING "avc:  only able to allocate "
-+			       "%d entries\n", i);
-+			break;
-+		}
-+		memset(new, 0, sizeof(*new));
-+		new->next = avc_node_freelist;
-+		avc_node_freelist = new;
-+	}
-+
-+	avc_audit_buffer = (char *)__get_free_page(GFP_ATOMIC);
-+	if (!avc_audit_buffer)
-+		panic("AVC:  unable to allocate audit buffer\n");
-+
-+	avc_level_string[1] = '0' + avc_log_level;
-+}
-+
-+#if 0
-+static void avc_hash_eval(char *tag)
-+{
-+	int i, chain_len, max_chain_len, slots_used;
-+	struct avc_node *node;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&avc_lock,flags);
-+
-+	slots_used = 0;
-+	max_chain_len = 0;
-+	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-+		node = avc_cache.slots[i];
-+		if (node) {
-+			slots_used++;
-+			chain_len = 0;
-+			while (node) {
-+				chain_len++;
-+				node = node->next;
-+			}
-+			if (chain_len > max_chain_len)
-+				max_chain_len = chain_len;
-+		}
-+	}
-+
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+
-+	printk(KERN_INFO "\n");
-+	printk(KERN_INFO "%s avc:  %d entries and %d/%d buckets used, longest "
-+	       "chain length %d\n", tag, avc_cache.active_nodes, slots_used,
-+	       AVC_CACHE_SLOTS, max_chain_len);
-+}
-+#else
-+static inline void avc_hash_eval(char *tag)
-+{ }
-+#endif
-+
-+static inline struct avc_node *avc_reclaim_node(void)
-+{
-+	struct avc_node *prev, *cur;
-+	int hvalue, try;
-+
-+	hvalue = avc_cache.lru_hint;
-+	for (try = 0; try < 2; try++) {
-+		do {
-+			prev = NULL;
-+			cur = avc_cache.slots[hvalue];
-+			while (cur) {
-+				if (!cur->ae.used)
-+					goto found;
-+
-+				cur->ae.used = 0;
-+
-+				prev = cur;
-+				cur = cur->next;
-+			}
-+			hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
-+		} while (hvalue != avc_cache.lru_hint);
-+	}
-+
-+	panic("avc_reclaim_node");
-+
-+found:
-+	avc_cache.lru_hint = hvalue;
-+
-+	if (prev == NULL)
-+		avc_cache.slots[hvalue] = cur->next;
-+	else
-+		prev->next = cur->next;
-+
-+	return cur;
-+}
-+
-+static inline struct avc_node *avc_claim_node(u32 ssid,
-+                                              u32 tsid, u16 tclass)
-+{
-+	struct avc_node *new;
-+	int hvalue;
-+
-+	hvalue = avc_hash(ssid, tsid, tclass);
-+	if (avc_node_freelist) {
-+		new = avc_node_freelist;
-+		avc_node_freelist = avc_node_freelist->next;
-+		avc_cache.active_nodes++;
-+	} else {
-+		new = avc_reclaim_node();
-+		if (!new)
-+			goto out;
-+	}
-+
-+	new->ae.used = 1;
-+	new->ae.ssid = ssid;
-+	new->ae.tsid = tsid;
-+	new->ae.tclass = tclass;
-+	new->next = avc_cache.slots[hvalue];
-+	avc_cache.slots[hvalue] = new;
-+
-+out:
-+	return new;
-+}
-+
-+static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid,
-+                                               u16 tclass, int *probes)
-+{
-+	struct avc_node *cur;
-+	int hvalue;
-+	int tprobes = 1;
-+
-+	hvalue = avc_hash(ssid, tsid, tclass);
-+	cur = avc_cache.slots[hvalue];
-+	while (cur != NULL &&
-+	       (ssid != cur->ae.ssid ||
-+		tclass != cur->ae.tclass ||
-+		tsid != cur->ae.tsid)) {
-+		tprobes++;
-+		cur = cur->next;
-+	}
-+
-+	if (cur == NULL) {
-+		/* cache miss */
-+		goto out;
-+	}
-+
-+	/* cache hit */
-+	if (probes)
-+		*probes = tprobes;
-+
-+	cur->ae.used = 1;
-+
-+out:
-+	return cur;
-+}
-+
-+/**
-+ * avc_lookup - Look up an AVC entry.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @requested: requested permissions, interpreted based on @tclass
-+ * @aeref:  AVC entry reference
-+ *
-+ * Look up an AVC entry that is valid for the
-+ * @requested permissions between the SID pair
-+ * (@ssid, @tsid), interpreting the permissions
-+ * based on @tclass.  If a valid AVC entry exists,
-+ * then this function updates @aeref to refer to the
-+ * entry and returns %0. Otherwise, this function
-+ * returns -%ENOENT.
-+ */
-+int avc_lookup(u32 ssid, u32 tsid, u16 tclass,
-+               u32 requested, struct avc_entry_ref *aeref)
-+{
-+	struct avc_node *node;
-+	int probes, rc = 0;
-+
-+	avc_cache_stats_incr(AVC_CAV_LOOKUPS);
-+	node = avc_search_node(ssid, tsid, tclass,&probes);
-+
-+	if (node && ((node->ae.avd.decided & requested) == requested)) {
-+		avc_cache_stats_incr(AVC_CAV_HITS);
-+		avc_cache_stats_add(AVC_CAV_PROBES,probes);
-+		aeref->ae = &node->ae;
-+		goto out;
-+	}
-+
-+	avc_cache_stats_incr(AVC_CAV_MISSES);
-+	rc = -ENOENT;
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * avc_insert - Insert an AVC entry.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @ae: AVC entry
-+ * @aeref:  AVC entry reference
-+ *
-+ * Insert an AVC entry for the SID pair
-+ * (@ssid, @tsid) and class @tclass.
-+ * The access vectors and the sequence number are
-+ * normally provided by the security server in
-+ * response to a security_compute_av() call.  If the
-+ * sequence number @ae->avd.seqno is not less than the latest
-+ * revocation notification, then the function copies
-+ * the access vectors into a cache entry, updates
-+ * @aeref to refer to the entry, and returns %0.
-+ * Otherwise, this function returns -%EAGAIN.
-+ */
-+int avc_insert(u32 ssid, u32 tsid, u16 tclass,
-+               struct avc_entry *ae, struct avc_entry_ref *aeref)
-+{
-+	struct avc_node *node;
-+	int rc = 0;
-+
-+	if (ae->avd.seqno < avc_cache.latest_notif) {
-+		printk(KERN_WARNING "avc:  seqno %d < latest_notif %d\n",
-+		       ae->avd.seqno, avc_cache.latest_notif);
-+		rc = -EAGAIN;
-+		goto out;
-+	}
-+
-+	node = avc_claim_node(ssid, tsid, tclass);
-+	if (!node) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	node->ae.avd.allowed = ae->avd.allowed;
-+	node->ae.avd.decided = ae->avd.decided;
-+	node->ae.avd.auditallow = ae->avd.auditallow;
-+	node->ae.avd.auditdeny = ae->avd.auditdeny;
-+	node->ae.avd.seqno = ae->avd.seqno;
-+	aeref->ae = &node->ae;
-+out:
-+	return rc;
-+}
-+
-+static inline void avc_print_ipv4_addr(u32 addr, u16 port, char *name1, char *name2)
-+{
-+	if (addr)
-+		printk(" %s=%d.%d.%d.%d", name1, NIPQUAD(addr));
-+	if (port)
-+		printk(" %s=%d", name2, ntohs(port));
-+}
-+
-+/*
-+ * Copied from net/core/utils.c:net_ratelimit and modified for
-+ * use by the AVC audit facility.
-+ */
-+#define AVC_MSG_COST	5*HZ
-+#define AVC_MSG_BURST	10*5*HZ
-+
-+/*
-+ * This enforces a rate limit: not more than one kernel message
-+ * every 5secs to make a denial-of-service attack impossible.
-+ */
-+static int avc_ratelimit(void)
-+{
-+	static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
-+	static unsigned long toks = 10*5*HZ;
-+	static unsigned long last_msg;
-+	static int missed, rc = 0;
-+	unsigned long flags;
-+	unsigned long now = jiffies;
-+
-+	spin_lock_irqsave(&ratelimit_lock, flags);
-+	toks += now - last_msg;
-+	last_msg = now;
-+	if (toks > AVC_MSG_BURST)
-+		toks = AVC_MSG_BURST;
-+	if (toks >= AVC_MSG_COST) {
-+		int lost = missed;
-+		missed = 0;
-+		toks -= AVC_MSG_COST;
-+		spin_unlock_irqrestore(&ratelimit_lock, flags);
-+		if (lost)
-+			printk(KERN_WARNING "AVC: %d messages suppressed.\n",
-+			       lost);
-+		rc = 1;
-+		goto out;
-+	}
-+	missed++;
-+	spin_unlock_irqrestore(&ratelimit_lock, flags);
-+out:
-+	return rc;
-+}
-+
-+static inline int check_avc_ratelimit(void)
-+{
-+	if (selinux_enforcing)
-+		return avc_ratelimit();
-+	else {
-+		/* If permissive, then never suppress messages. */
-+		return 1;
-+	}
-+}
-+
-+/**
-+ * avc_audit - Audit the granting or denial of permissions.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @requested: requested permissions
-+ * @avd: access vector decisions
-+ * @result: result from avc_has_perm_noaudit
-+ * @a:  auxiliary audit data
-+ *
-+ * Audit the granting or denial of permissions in accordance
-+ * with the policy.  This function is typically called by
-+ * avc_has_perm() after a permission check, but can also be
-+ * called directly by callers who use avc_has_perm_noaudit()
-+ * in order to separate the permission check from the auditing.
-+ * For example, this separation is useful when the permission check must
-+ * be performed under a lock, to allow the lock to be released
-+ * before calling the auditing code.
-+ */
-+void avc_audit(u32 ssid, u32 tsid,
-+               u16 tclass, u32 requested,
-+               struct av_decision *avd, int result, struct avc_audit_data *a)
-+{
-+	struct task_struct *tsk = current;
-+	struct inode *inode = NULL;
-+	char *p;
-+	u32 denied, audited;
-+
-+	denied = requested & ~avd->allowed;
-+	if (denied) {
-+		audited = denied;
-+		if (!(audited & avd->auditdeny))
-+			return;
-+	} else if (result) {
-+		audited = denied = requested;
-+        } else {
-+		audited = requested;
-+		if (!(audited & avd->auditallow))
-+			return;
-+	}
-+
-+	if (!check_avc_ratelimit())
-+		return;
-+
-+	/* prevent overlapping printks */
-+	spin_lock_irq(&avc_log_lock);
-+
-+	printk("%s\n", avc_level_string);
-+	printk("%savc:  %s ", avc_level_string, denied ? "denied" : "granted");
-+	avc_dump_av(tclass,audited);
-+	printk(" for ");
-+	if (a && a->tsk)
-+		tsk = a->tsk;
-+	if (tsk && tsk->pid) {
-+		struct mm_struct *mm;
-+		struct vm_area_struct *vma;
-+		printk(" pid=%d", tsk->pid);
-+		if (tsk == current)
-+			mm = current->mm;
-+		else
-+			mm = get_task_mm(tsk);
-+		if (mm) {
-+			if (down_read_trylock(&mm->mmap_sem)) {
-+				vma = mm->mmap;
-+				while (vma) {
-+					if ((vma->vm_flags & VM_EXECUTABLE) &&
-+					    vma->vm_file) {
-+						p = d_path(vma->vm_file->f_dentry,
-+							   vma->vm_file->f_vfsmnt,
-+							   avc_audit_buffer,
-+							   PAGE_SIZE);
-+						printk(" exe=%s", p);
-+						break;
-+					}
-+					vma = vma->vm_next;
-+				}
-+				up_read(&mm->mmap_sem);
-+			}
-+			if (tsk != current)
-+				mmput(mm);
-+		} else {
-+			printk(" comm=%s", tsk->comm);
-+		}
-+	}
-+	if (a) {
-+		switch (a->type) {
-+		case AVC_AUDIT_DATA_IPC:
-+			printk(" key=%d", a->u.ipc_id);
-+			break;
-+		case AVC_AUDIT_DATA_CAP:
-+			printk(" capability=%d", a->u.cap);
-+			break;
-+		case AVC_AUDIT_DATA_FS:
-+			if (a->u.fs.dentry) {
-+				if (a->u.fs.mnt) {
-+					p = d_path(a->u.fs.dentry,
-+						   a->u.fs.mnt,
-+						   avc_audit_buffer,
-+						   PAGE_SIZE);
-+					if (p)
-+						printk(" path=%s", p);
-+				}
-+				inode = a->u.fs.dentry->d_inode;
-+			} else if (a->u.fs.inode) {
-+				inode = a->u.fs.inode;
-+			}
-+			if (inode)
-+				printk(" dev=%s ino=%ld",
-+				       inode->i_sb->s_id, inode->i_ino);
-+			break;
-+		case AVC_AUDIT_DATA_NET:
-+			if (a->u.net.sk) {
-+				struct sock *sk = a->u.net.sk;
-+				struct unix_sock *u;
-+				struct inet_opt *inet;
-+
-+				switch (sk->sk_family) {
-+				case AF_INET:
-+					inet = inet_sk(sk);
-+					avc_print_ipv4_addr(inet->rcv_saddr,
-+					                    inet->sport,
-+					                    "laddr", "lport");
-+					avc_print_ipv4_addr(inet->daddr,
-+					                    inet->dport,
-+					                    "faddr", "fport");
-+					break;
-+				case AF_UNIX:
-+					u = unix_sk(sk);
-+					if (u->dentry) {
-+						p = d_path(u->dentry,
-+							   u->mnt,
-+							   avc_audit_buffer,
-+							   PAGE_SIZE);
-+						printk(" path=%s", p);
-+					} else if (u->addr) {
-+						p = avc_audit_buffer;
-+						memcpy(p,
-+						       u->addr->name->sun_path,
-+						       u->addr->len-sizeof(short));
-+						if (*p == 0) {
-+							*p = '@';
-+							p += u->addr->len-sizeof(short);
-+							*p = 0;
-+						}
-+						printk(" path=%s",
-+						       avc_audit_buffer);
-+					}
-+					break;
-+				}
-+			}
-+			if (a->u.net.daddr) {
-+				printk(" daddr=%d.%d.%d.%d",
-+				       NIPQUAD(a->u.net.daddr));
-+				if (a->u.net.port)
-+					printk(" dest=%d", a->u.net.port);
-+			} else if (a->u.net.port)
-+				printk(" port=%d", a->u.net.port);
-+			if (a->u.net.skb) {
-+				struct sk_buff *skb = a->u.net.skb;
-+
-+				if ((skb->protocol == htons(ETH_P_IP)) &&
-+				     skb->nh.iph) {
-+					u16 source = 0, dest = 0;
-+					u8  protocol = skb->nh.iph->protocol;
-+
-+
-+					if (protocol == IPPROTO_TCP &&
-+					    skb->h.th) {
-+						source = skb->h.th->source;
-+						dest = skb->h.th->dest;
-+					}
-+					if (protocol == IPPROTO_UDP &&
-+					    skb->h.uh) {
-+						source = skb->h.uh->source;
-+						dest = skb->h.uh->dest;
-+					}
-+
-+					avc_print_ipv4_addr(skb->nh.iph->saddr,
-+					                    source,
-+					                    "saddr", "source");
-+					avc_print_ipv4_addr(skb->nh.iph->daddr,
-+					                    dest,
-+					                    "daddr", "dest");
-+				}
-+			}
-+			if (a->u.net.netif)
-+				printk(" netif=%s", a->u.net.netif);
-+			break;
-+		}
-+	}
-+	printk(" ");
-+	avc_dump_query(ssid, tsid, tclass);
-+	printk("\n");
-+
-+	spin_unlock_irq(&avc_log_lock);
-+}
-+
-+/**
-+ * avc_add_callback - Register a callback for security events.
-+ * @callback: callback function
-+ * @events: security events
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions
-+ *
-+ * Register a callback function for events in the set @events
-+ * related to the SID pair (@ssid, @tsid) and
-+ * and the permissions @perms, interpreting
-+ * @perms based on @tclass.  Returns %0 on success or
-+ * -%ENOMEM if insufficient memory exists to add the callback.
-+ */
-+int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
-+                                     u16 tclass, u32 perms,
-+                                     u32 *out_retained),
-+                     u32 events, u32 ssid, u32 tsid,
-+                     u16 tclass, u32 perms)
-+{
-+	struct avc_callback_node *c;
-+	int rc = 0;
-+
-+	c = kmalloc(sizeof(*c), GFP_ATOMIC);
-+	if (!c) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	c->callback = callback;
-+	c->events = events;
-+	c->ssid = ssid;
-+	c->tsid = tsid;
-+	c->perms = perms;
-+	c->next = avc_callbacks;
-+	avc_callbacks = c;
-+out:
-+	return rc;
-+}
-+
-+static inline int avc_sidcmp(u32 x, u32 y)
-+{
-+	return (x == y || x == SECSID_WILD || y == SECSID_WILD);
-+}
-+
-+static inline void avc_update_node(u32 event, struct avc_node *node, u32 perms)
-+{
-+	switch (event) {
-+	case AVC_CALLBACK_GRANT:
-+		node->ae.avd.allowed |= perms;
-+		break;
-+	case AVC_CALLBACK_TRY_REVOKE:
-+	case AVC_CALLBACK_REVOKE:
-+		node->ae.avd.allowed &= ~perms;
-+		break;
-+	case AVC_CALLBACK_AUDITALLOW_ENABLE:
-+		node->ae.avd.auditallow |= perms;
-+		break;
-+	case AVC_CALLBACK_AUDITALLOW_DISABLE:
-+		node->ae.avd.auditallow &= ~perms;
-+		break;
-+	case AVC_CALLBACK_AUDITDENY_ENABLE:
-+		node->ae.avd.auditdeny |= perms;
-+		break;
-+	case AVC_CALLBACK_AUDITDENY_DISABLE:
-+		node->ae.avd.auditdeny &= ~perms;
-+		break;
-+	}
-+}
-+
-+static int avc_update_cache(u32 event, u32 ssid, u32 tsid,
-+                            u16 tclass, u32 perms)
-+{
-+	struct avc_node *node;
-+	int i;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&avc_lock,flags);
-+
-+	if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
-+		/* apply to all matching nodes */
-+		for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-+			for (node = avc_cache.slots[i]; node;
-+			     node = node->next) {
-+				if (avc_sidcmp(ssid, node->ae.ssid) &&
-+				    avc_sidcmp(tsid, node->ae.tsid) &&
-+				    tclass == node->ae.tclass) {
-+					avc_update_node(event,node,perms);
-+				}
-+			}
-+		}
-+	} else {
-+		/* apply to one node */
-+		node = avc_search_node(ssid, tsid, tclass, 0);
-+		if (node) {
-+			avc_update_node(event,node,perms);
-+		}
-+	}
-+
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+
-+	return 0;
-+}
-+
-+static int avc_control(u32 event, u32 ssid, u32 tsid,
-+                       u16 tclass, u32 perms,
-+                       u32 seqno, u32 *out_retained)
-+{
-+	struct avc_callback_node *c;
-+	u32 tretained = 0, cretained = 0;
-+	int rc = 0;
-+	unsigned long flags;
-+
-+	/*
-+	 * try_revoke only removes permissions from the cache
-+	 * state if they are not retained by the object manager.
-+	 * Hence, try_revoke must wait until after the callbacks have
-+	 * been invoked to update the cache state.
-+	 */
-+	if (event != AVC_CALLBACK_TRY_REVOKE)
-+		avc_update_cache(event,ssid,tsid,tclass,perms);
-+
-+	for (c = avc_callbacks; c; c = c->next)
-+	{
-+		if ((c->events & event) &&
-+		    avc_sidcmp(c->ssid, ssid) &&
-+		    avc_sidcmp(c->tsid, tsid) &&
-+		    c->tclass == tclass &&
-+		    (c->perms & perms)) {
-+			cretained = 0;
-+			rc = c->callback(event, ssid, tsid, tclass,
-+					 (c->perms & perms),
-+					 &cretained);
-+			if (rc)
-+				goto out;
-+			tretained |= cretained;
-+		}
-+	}
-+
-+	if (event == AVC_CALLBACK_TRY_REVOKE) {
-+		/* revoke any unretained permissions */
-+		perms &= ~tretained;
-+		avc_update_cache(event,ssid,tsid,tclass,perms);
-+		*out_retained = tretained;
-+	}
-+
-+	spin_lock_irqsave(&avc_lock,flags);
-+	if (seqno > avc_cache.latest_notif)
-+		avc_cache.latest_notif = seqno;
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * avc_ss_grant - Grant previously denied permissions.
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions to grant
-+ * @seqno: policy sequence number
-+ */
-+int avc_ss_grant(u32 ssid, u32 tsid, u16 tclass,
-+                 u32 perms, u32 seqno)
-+{
-+	return avc_control(AVC_CALLBACK_GRANT,
-+			   ssid, tsid, tclass, perms, seqno, 0);
-+}
-+
-+/**
-+ * avc_ss_try_revoke - Try to revoke previously granted permissions.
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions to grant
-+ * @seqno: policy sequence number
-+ * @out_retained: subset of @perms that are retained
-+ *
-+ * Try to revoke previously granted permissions, but
-+ * only if they are not retained as migrated permissions.
-+ * Return the subset of permissions that are retained via @out_retained.
-+ */
-+int avc_ss_try_revoke(u32 ssid, u32 tsid, u16 tclass,
-+                      u32 perms, u32 seqno, u32 *out_retained)
-+{
-+	return avc_control(AVC_CALLBACK_TRY_REVOKE,
-+			   ssid, tsid, tclass, perms, seqno, out_retained);
-+}
-+
-+/**
-+ * avc_ss_revoke - Revoke previously granted permissions.
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions to grant
-+ * @seqno: policy sequence number
-+ *
-+ * Revoke previously granted permissions, even if
-+ * they are retained as migrated permissions.
-+ */
-+int avc_ss_revoke(u32 ssid, u32 tsid, u16 tclass,
-+                  u32 perms, u32 seqno)
-+{
-+	return avc_control(AVC_CALLBACK_REVOKE,
-+			   ssid, tsid, tclass, perms, seqno, 0);
-+}
-+
-+/**
-+ * avc_ss_reset - Flush the cache and revalidate migrated permissions.
-+ * @seqno: policy sequence number
-+ */
-+int avc_ss_reset(u32 seqno)
-+{
-+	struct avc_callback_node *c;
-+	int i, rc = 0;
-+	struct avc_node *node, *tmp;
-+	unsigned long flags;
-+
-+	avc_hash_eval("reset");
-+
-+	spin_lock_irqsave(&avc_lock,flags);
-+
-+	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-+		node = avc_cache.slots[i];
-+		while (node) {
-+			tmp = node;
-+			node = node->next;
-+			tmp->ae.ssid = tmp->ae.tsid = SECSID_NULL;
-+			tmp->ae.tclass = SECCLASS_NULL;
-+			tmp->ae.avd.allowed = tmp->ae.avd.decided = 0;
-+			tmp->ae.avd.auditallow = tmp->ae.avd.auditdeny = 0;
-+			tmp->ae.used = 0;
-+			tmp->next = avc_node_freelist;
-+			avc_node_freelist = tmp;
-+			avc_cache.active_nodes--;
-+		}
-+		avc_cache.slots[i] = 0;
-+	}
-+	avc_cache.lru_hint = 0;
-+
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+
-+	for (i = 0; i < AVC_NSTATS; i++)
-+		avc_cache_stats[i] = 0;
-+
-+	for (c = avc_callbacks; c; c = c->next) {
-+		if (c->events & AVC_CALLBACK_RESET) {
-+			rc = c->callback(AVC_CALLBACK_RESET,
-+					 0, 0, 0, 0, 0);
-+			if (rc)
-+				goto out;
-+		}
-+	}
-+
-+	spin_lock_irqsave(&avc_lock,flags);
-+	if (seqno > avc_cache.latest_notif)
-+		avc_cache.latest_notif = seqno;
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * avc_ss_set_auditallow - Enable or disable auditing of granted permissions.
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions to grant
-+ * @seqno: policy sequence number
-+ * @enable: enable flag.
-+ */
-+int avc_ss_set_auditallow(u32 ssid, u32 tsid, u16 tclass,
-+                          u32 perms, u32 seqno, u32 enable)
-+{
-+	if (enable)
-+		return avc_control(AVC_CALLBACK_AUDITALLOW_ENABLE,
-+				   ssid, tsid, tclass, perms, seqno, 0);
-+	else
-+		return avc_control(AVC_CALLBACK_AUDITALLOW_DISABLE,
-+				   ssid, tsid, tclass, perms, seqno, 0);
-+}
-+
-+/**
-+ * avc_ss_set_auditdeny - Enable or disable auditing of denied permissions.
-+ * @ssid: source security identifier or %SECSID_WILD
-+ * @tsid: target security identifier or %SECSID_WILD
-+ * @tclass: target security class
-+ * @perms: permissions to grant
-+ * @seqno: policy sequence number
-+ * @enable: enable flag.
-+ */
-+int avc_ss_set_auditdeny(u32 ssid, u32 tsid, u16 tclass,
-+                         u32 perms, u32 seqno, u32 enable)
-+{
-+	if (enable)
-+		return avc_control(AVC_CALLBACK_AUDITDENY_ENABLE,
-+				   ssid, tsid, tclass, perms, seqno, 0);
-+	else
-+		return avc_control(AVC_CALLBACK_AUDITDENY_DISABLE,
-+				   ssid, tsid, tclass, perms, seqno, 0);
-+}
-+
-+/**
-+ * avc_has_perm_noaudit - Check permissions but perform no auditing.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @requested: requested permissions, interpreted based on @tclass
-+ * @aeref:  AVC entry reference
-+ * @avd: access vector decisions
-+ *
-+ * Check the AVC to determine whether the @requested permissions are granted
-+ * for the SID pair (@ssid, @tsid), interpreting the permissions
-+ * based on @tclass, and call the security server on a cache miss to obtain
-+ * a new decision and add it to the cache.  Update @aeref to refer to an AVC
-+ * entry with the resulting decisions, and return a copy of the decisions
-+ * in @avd.  Return %0 if all @requested permissions are granted,
-+ * -%EACCES if any permissions are denied, or another -errno upon
-+ * other errors.  This function is typically called by avc_has_perm(),
-+ * but may also be called directly to separate permission checking from
-+ * auditing, e.g. in cases where a lock must be held for the check but
-+ * should be released for the auditing.
-+ */
-+int avc_has_perm_noaudit(u32 ssid, u32 tsid,
-+                         u16 tclass, u32 requested,
-+                         struct avc_entry_ref *aeref, struct av_decision *avd)
-+{
-+	struct avc_entry *ae;
-+	int rc = 0;
-+	unsigned long flags;
-+	struct avc_entry entry;
-+	u32 denied;
-+	struct avc_entry_ref ref;
-+
-+	if (!aeref) {
-+		avc_entry_ref_init(&ref);
-+		aeref = &ref;
-+	}
-+
-+	spin_lock_irqsave(&avc_lock, flags);
-+	avc_cache_stats_incr(AVC_ENTRY_LOOKUPS);
-+	ae = aeref->ae;
-+	if (ae) {
-+		if (ae->ssid == ssid &&
-+		    ae->tsid == tsid &&
-+		    ae->tclass == tclass &&
-+		    ((ae->avd.decided & requested) == requested)) {
-+			avc_cache_stats_incr(AVC_ENTRY_HITS);
-+			ae->used = 1;
-+		} else {
-+			avc_cache_stats_incr(AVC_ENTRY_DISCARDS);
-+			ae = 0;
-+		}
-+	}
-+
-+	if (!ae) {
-+		avc_cache_stats_incr(AVC_ENTRY_MISSES);
-+		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
-+		if (rc) {
-+			spin_unlock_irqrestore(&avc_lock,flags);
-+			rc = security_compute_av(ssid,tsid,tclass,requested,&entry.avd);
-+			if (rc)
-+				goto out;
-+			spin_lock_irqsave(&avc_lock, flags);
-+			rc = avc_insert(ssid,tsid,tclass,&entry,aeref);
-+			if (rc) {
-+				spin_unlock_irqrestore(&avc_lock,flags);
-+				goto out;
-+			}
-+		}
-+		ae = aeref->ae;
-+	}
-+
-+	if (avd)
-+		memcpy(avd, &ae->avd, sizeof(*avd));
-+
-+	denied = requested & ~(ae->avd.allowed);
-+
-+	if (!requested || denied) {
-+		if (selinux_enforcing) {
-+			spin_unlock_irqrestore(&avc_lock,flags);
-+			rc = -EACCES;
-+			goto out;
-+		} else {
-+			ae->avd.allowed |= requested;
-+			spin_unlock_irqrestore(&avc_lock,flags);
-+			goto out;
-+		}
-+	}
-+
-+	spin_unlock_irqrestore(&avc_lock,flags);
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * avc_has_perm - Check permissions and perform any appropriate auditing.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @requested: requested permissions, interpreted based on @tclass
-+ * @aeref:  AVC entry reference
-+ * @auditdata: auxiliary audit data
-+ *
-+ * Check the AVC to determine whether the @requested permissions are granted
-+ * for the SID pair (@ssid, @tsid), interpreting the permissions
-+ * based on @tclass, and call the security server on a cache miss to obtain
-+ * a new decision and add it to the cache.  Update @aeref to refer to an AVC
-+ * entry with the resulting decisions.  Audit the granting or denial of
-+ * permissions in accordance with the policy.  Return %0 if all @requested
-+ * permissions are granted, -%EACCES if any permissions are denied, or
-+ * another -errno upon other errors.
-+ */
-+int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
-+                 u32 requested, struct avc_entry_ref *aeref,
-+                 struct avc_audit_data *auditdata)
-+{
-+	struct av_decision avd;
-+	int rc;
-+
-+	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
-+	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
-+	return rc;
-+}
-+
-+static int __init avc_log_level_setup(char *str)
-+{
-+	avc_log_level = simple_strtol(str, NULL, 0);
-+	if (avc_log_level > 7)
-+		avc_log_level = 7;
-+	return 1;
-+}
-+
-+__setup("avc_log_level=", avc_log_level_setup);
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/hooks.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,3405 @@
-+/*
-+ *  NSA Security-Enhanced Linux (SELinux) security module
-+ *
-+ *  This file contains the SELinux hook function implementations.
-+ *
-+ *  Authors:  Stephen Smalley, <sds@epoch.ncsc.mil>
-+ *            Chris Vance, <cvance@nai.com>
-+ *            Wayne Salamon, <wsalamon@nai.com>
-+ *            James Morris <jmorris@redhat.com>
-+ *
-+ *  Copyright (C) 2001,2002 Networks Associates Technology, Inc.
-+ *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
-+ *
-+ *	This program is free software; you can redistribute it and/or modify
-+ *	it under the terms of the GNU General Public License version 2,
-+ *      as published by the Free Software Foundation.
-+ */
-+
-+#define XATTR_SECURITY_PREFIX "security."
-+#define XATTR_SELINUX_SUFFIX "selinux"
-+#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/ptrace.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/security.h>
-+#include <linux/xattr.h>
-+#include <linux/capability.h>
-+#include <linux/unistd.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/swap.h>
-+#include <linux/smp_lock.h>
-+#include <linux/spinlock.h>
-+#include <linux/file.h>
-+#include <linux/namei.h>
-+#include <linux/mount.h>
-+#include <linux/ext2_fs.h>
-+#include <linux/proc_fs.h>
-+#include <linux/kd.h>
-+#include <net/icmp.h>
-+#include <net/ip.h>		/* for sysctl_local_port_range[] */
-+#include <net/tcp.h>		/* struct or_callable used in sock_rcv_skb */
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+#include <asm/ioctls.h>
-+#include <linux/bitops.h>
-+#include <linux/interrupt.h>
-+#include <linux/netdevice.h>	/* for network interface checks */
-+#include <linux/netlink.h>
-+#include <linux/tcp.h>
-+#include <linux/quota.h>
-+#include <linux/un.h>		/* for Unix socket types */
-+#include <net/af_unix.h>	/* for Unix socket types */
-+
-+#include "avc.h"
-+#include "objsec.h"
-+
-+#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-+int selinux_enforcing = 0;
-+
-+static int __init enforcing_setup(char *str)
-+{
-+	selinux_enforcing = simple_strtol(str,NULL,0);
-+	return 1;
-+}
-+__setup("enforcing=", enforcing_setup);
-+#endif
-+
-+/* Original (dummy) security module. */
-+static struct security_operations *original_ops = NULL;
-+
-+/* Minimal support for a secondary security module,
-+   just to allow the use of the dummy or capability modules.
-+   The owlsm module can alternatively be used as a secondary
-+   module as long as CONFIG_OWLSM_FD is not enabled. */
-+static struct security_operations *secondary_ops = NULL;
-+
-+/* Lists of inode and superblock security structures initialized
-+   before the policy was loaded. */
-+static LIST_HEAD(inode_security_head);
-+static spinlock_t inode_security_lock = SPIN_LOCK_UNLOCKED;
-+
-+static LIST_HEAD(superblock_security_head);
-+static spinlock_t sb_security_lock = SPIN_LOCK_UNLOCKED;
-+
-+/* Allocate and free functions for each kind of security blob. */
-+
-+static int task_alloc_security(struct task_struct *task)
-+{
-+	struct task_security_struct *tsec;
-+
-+	tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
-+	if (!tsec)
-+		return -ENOMEM;
-+
-+	memset(tsec, 0, sizeof(struct task_security_struct));
-+	tsec->magic = SELINUX_MAGIC;
-+	tsec->task = task;
-+	tsec->osid = tsec->sid = SECINITSID_UNLABELED;
-+	task->security = tsec;
-+
-+	return 0;
-+}
-+
-+static void task_free_security(struct task_struct *task)
-+{
-+	struct task_security_struct *tsec = task->security;
-+
-+	if (!tsec || tsec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	task->security = NULL;
-+	kfree(tsec);
-+}
-+
-+static int inode_alloc_security(struct inode *inode)
-+{
-+	struct task_security_struct *tsec = current->security;
-+	struct inode_security_struct *isec;
-+
-+	isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
-+	if (!isec)
-+		return -ENOMEM;
-+
-+	memset(isec, 0, sizeof(struct inode_security_struct));
-+	init_MUTEX(&isec->sem);
-+	INIT_LIST_HEAD(&isec->list);
-+	isec->magic = SELINUX_MAGIC;
-+	isec->inode = inode;
-+	isec->sid = SECINITSID_UNLABELED;
-+	isec->sclass = SECCLASS_FILE;
-+	if (tsec && tsec->magic == SELINUX_MAGIC)
-+		isec->task_sid = tsec->sid;
-+	else
-+		isec->task_sid = SECINITSID_UNLABELED;
-+	inode->i_security = isec;
-+
-+	return 0;
-+}
-+
-+static void inode_free_security(struct inode *inode)
-+{
-+	struct inode_security_struct *isec = inode->i_security;
-+
-+	if (!isec || isec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	spin_lock(&inode_security_lock);
-+	if (!list_empty(&isec->list))
-+		list_del_init(&isec->list);
-+	spin_unlock(&inode_security_lock);
-+
-+	inode->i_security = NULL;
-+	kfree(isec);
-+}
-+
-+static int file_alloc_security(struct file *file)
-+{
-+	struct task_security_struct *tsec = current->security;
-+	struct file_security_struct *fsec;
-+
-+	fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
-+	if (!fsec)
-+		return -ENOMEM;
-+
-+	memset(fsec, 0, sizeof(struct file_security_struct));
-+	fsec->magic = SELINUX_MAGIC;
-+	fsec->file = file;
-+	if (tsec && tsec->magic == SELINUX_MAGIC) {
-+		fsec->sid = tsec->sid;
-+		fsec->fown_sid = tsec->sid;
-+	} else {
-+		fsec->sid = SECINITSID_UNLABELED;
-+		fsec->fown_sid = SECINITSID_UNLABELED;
-+	}
-+	file->f_security = fsec;
-+
-+	return 0;
-+}
-+
-+static void file_free_security(struct file *file)
-+{
-+	struct file_security_struct *fsec = file->f_security;
-+
-+	if (!fsec || fsec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	file->f_security = NULL;
-+	kfree(fsec);
-+}
-+
-+static int superblock_alloc_security(struct super_block *sb)
-+{
-+	struct superblock_security_struct *sbsec;
-+
-+	sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
-+	if (!sbsec)
-+		return -ENOMEM;
-+
-+	memset(sbsec, 0, sizeof(struct superblock_security_struct));
-+	init_MUTEX(&sbsec->sem);
-+	INIT_LIST_HEAD(&sbsec->list);
-+	sbsec->magic = SELINUX_MAGIC;
-+	sbsec->sb = sb;
-+	sbsec->sid = SECINITSID_UNLABELED;
-+	sb->s_security = sbsec;
-+
-+	return 0;
-+}
-+
-+static void superblock_free_security(struct super_block *sb)
-+{
-+	struct superblock_security_struct *sbsec = sb->s_security;
-+
-+	if (!sbsec || sbsec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	spin_lock(&sb_security_lock);
-+	if (!list_empty(&sbsec->list))
-+		list_del_init(&sbsec->list);
-+	spin_unlock(&sb_security_lock);
-+
-+	sb->s_security = NULL;
-+	kfree(sbsec);
-+}
-+
-+/* The security server must be initialized before
-+   any labeling or access decisions can be provided. */
-+extern int ss_initialized;
-+
-+/* The file system's label must be initialized prior to use. */
-+
-+static char *labeling_behaviors[5] = {
-+	"uses xattr",
-+	"uses transition SIDs",
-+	"uses task SIDs",
-+	"uses genfs_contexts",
-+	"not configured for labeling"
-+};
-+
-+static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
-+
-+static inline int inode_doinit(struct inode *inode)
-+{
-+	return inode_doinit_with_dentry(inode, NULL);
-+}
-+
-+static int superblock_doinit(struct super_block *sb)
-+{
-+	struct superblock_security_struct *sbsec = sb->s_security;
-+	struct dentry *root = sb->s_root;
-+	struct inode *inode = root->d_inode;
-+	int rc = 0;
-+
-+	down(&sbsec->sem);
-+	if (sbsec->initialized)
-+		goto out;
-+
-+	if (!ss_initialized) {
-+		/* Defer initialization until selinux_complete_init,
-+		   after the initial policy is loaded and the security
-+		   server is ready to handle calls. */
-+		spin_lock(&sb_security_lock);
-+		if (list_empty(&sbsec->list))
-+			list_add(&sbsec->list, &superblock_security_head);
-+		spin_unlock(&sb_security_lock);
-+		goto out;
-+	}
-+
-+	/* Determine the labeling behavior to use for this filesystem type. */
-+	rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid);
-+	if (rc) {
-+		printk(KERN_WARNING "%s:  security_fs_use(%s) returned %d\n",
-+		       __FUNCTION__, sb->s_type->name, rc);
-+		goto out;
-+	}
-+
-+	if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
-+		/* Make sure that the xattr handler exists and that no
-+		   error other than -ENODATA is returned by getxattr on
-+		   the root directory.  -ENODATA is ok, as this may be
-+		   the first boot of the SELinux kernel before we have
-+		   assigned xattr values to the filesystem. */
-+		if (!inode->i_op->getxattr) {
-+			printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
-+			       "xattr support\n", sb->s_id, sb->s_type->name);
-+			rc = -EOPNOTSUPP;
-+			goto out;
-+		}
-+		rc = inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0);
-+		if (rc < 0 && rc != -ENODATA) {
-+			if (rc == -EOPNOTSUPP)
-+				printk(KERN_WARNING "SELinux: (dev %s, type "
-+				       "%s) has no security xattr handler\n",
-+				       sb->s_id, sb->s_type->name);
-+			else
-+				printk(KERN_WARNING "SELinux: (dev %s, type "
-+				       "%s) getxattr errno %d\n", sb->s_id,
-+				       sb->s_type->name, -rc);
-+			goto out;
-+		}
-+	}
-+
-+	if (strcmp(sb->s_type->name, "proc") == 0)
-+		sbsec->proc = 1;
-+
-+	sbsec->initialized = 1;
-+
-+	printk(KERN_INFO "SELinux: initialized (dev %s, type %s), %s\n",
-+	       sb->s_id, sb->s_type->name,
-+	       labeling_behaviors[sbsec->behavior-1]);
-+
-+	/* Initialize the root inode. */
-+	rc = inode_doinit_with_dentry(sb->s_root->d_inode, sb->s_root);
-+out:
-+	up(&sbsec->sem);
-+	return rc;
-+}
-+
-+static inline u16 inode_mode_to_security_class(umode_t mode)
-+{
-+	switch (mode & S_IFMT) {
-+	case S_IFSOCK:
-+		return SECCLASS_SOCK_FILE;
-+	case S_IFLNK:
-+		return SECCLASS_LNK_FILE;
-+	case S_IFREG:
-+		return SECCLASS_FILE;
-+	case S_IFBLK:
-+		return SECCLASS_BLK_FILE;
-+	case S_IFDIR:
-+		return SECCLASS_DIR;
-+	case S_IFCHR:
-+		return SECCLASS_CHR_FILE;
-+	case S_IFIFO:
-+		return SECCLASS_FIFO_FILE;
-+
-+	}
-+
-+	return SECCLASS_FILE;
-+}
-+
-+static inline u16 socket_type_to_security_class(int family, int type)
-+{
-+	switch (family) {
-+	case PF_UNIX:
-+		switch (type) {
-+		case SOCK_STREAM:
-+			return SECCLASS_UNIX_STREAM_SOCKET;
-+		case SOCK_DGRAM:
-+			return SECCLASS_UNIX_DGRAM_SOCKET;
-+		}
-+	case PF_INET:
-+	case PF_INET6:
-+		switch (type) {
-+		case SOCK_STREAM:
-+			return SECCLASS_TCP_SOCKET;
-+		case SOCK_DGRAM:
-+			return SECCLASS_UDP_SOCKET;
-+		case SOCK_RAW:
-+			return SECCLASS_RAWIP_SOCKET;
-+		}
-+	case PF_NETLINK:
-+		return SECCLASS_NETLINK_SOCKET;
-+	case PF_PACKET:
-+		return SECCLASS_PACKET_SOCKET;
-+	case PF_KEY:
-+		return SECCLASS_KEY_SOCKET;
-+	}
-+
-+	return SECCLASS_SOCKET;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+static int selinux_proc_get_sid(struct proc_dir_entry *de,
-+				u16 tclass,
-+				u32 *sid)
-+{
-+	int buflen, rc;
-+	char *buffer, *path, *end;
-+
-+	buffer = (char*)__get_free_page(GFP_KERNEL);
-+	if (!buffer)
-+		return -ENOMEM;
-+
-+	buflen = PAGE_SIZE;
-+	end = buffer+buflen;
-+	*--end = '\0';
-+	buflen--;
-+	path = end-1;
-+	*path = '/';
-+	while (de && de != de->parent) {
-+		buflen -= de->namelen + 1;
-+		if (buflen < 0)
-+			break;
-+		end -= de->namelen;
-+		memcpy(end, de->name, de->namelen);
-+		*--end = '/';
-+		path = end;
-+		de = de->parent;
-+	}
-+	rc = security_genfs_sid("proc", path, tclass, sid);
-+	free_page((unsigned long)buffer);
-+	return rc;
-+}
-+#else
-+static int selinux_proc_get_sid(struct proc_dir_entry *de,
-+				u16 tclass,
-+				u32 *sid)
-+{
-+	return -EINVAL;
-+}
-+#endif
-+
-+/* The inode's security attributes must be initialized before first use. */
-+static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
-+{
-+	struct superblock_security_struct *sbsec = NULL;
-+	struct inode_security_struct *isec = inode->i_security;
-+	u32 sid;
-+	struct dentry *dentry;
-+#define INITCONTEXTLEN 255
-+	char *context = NULL;
-+	unsigned len = 0;
-+	int rc = 0;
-+	int hold_sem = 0;
-+
-+	if (isec->initialized)
-+		goto out;
-+
-+	down(&isec->sem);
-+	hold_sem = 1;
-+	if (isec->initialized)
-+		goto out;
-+
-+	sbsec = inode->i_sb->s_security;
-+	if (!sbsec || !sbsec->initialized) {
-+		/* Defer initialization until selinux_complete_init,
-+		   after the initial policy is loaded and the security
-+		   server is ready to handle calls. */
-+		spin_lock(&inode_security_lock);
-+		if (list_empty(&isec->list))
-+			list_add(&isec->list, &inode_security_head);
-+		spin_unlock(&inode_security_lock);
-+		goto out;
-+	}
-+
-+	switch (sbsec->behavior) {
-+	case SECURITY_FS_USE_XATTR:
-+		if (!inode->i_op->getxattr) {
-+			isec->sid = SECINITSID_FILE;
-+			break;
-+		}
-+
-+		/* Need a dentry, since the xattr API requires one.
-+		   Life would be simpler if we could just pass the inode. */
-+		if (opt_dentry) {
-+			/* Called from d_instantiate or d_splice_alias. */
-+			dentry = dget(opt_dentry);
-+		} else {
-+			/* Called from selinux_complete_init, try to find a dentry. */
-+			dentry = d_find_alias(inode);
-+		}
-+		if (!dentry) {
-+			printk(KERN_WARNING "%s:  no dentry for dev=%s "
-+			       "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id,
-+			       inode->i_ino);
-+			goto out;
-+		}
-+
-+		len = INITCONTEXTLEN;
-+		context = kmalloc(len, GFP_KERNEL);
-+		if (!context) {
-+			rc = -ENOMEM;
-+			dput(dentry);
-+			goto out;
-+		}
-+		rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
-+					   context, len);
-+		if (rc == -ERANGE) {
-+			/* Need a larger buffer.  Query for the right size. */
-+			rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
-+						   NULL, 0);
-+			if (rc < 0) {
-+				dput(dentry);
-+				goto out;
-+			}
-+			kfree(context);
-+			len = rc;
-+			context = kmalloc(len, GFP_KERNEL);
-+			if (!context) {
-+				rc = -ENOMEM;
-+				dput(dentry);
-+				goto out;
-+			}
-+			rc = inode->i_op->getxattr(dentry,
-+						   XATTR_NAME_SELINUX,
-+						   context, len);
-+		}
-+		dput(dentry);
-+		if (rc < 0) {
-+			if (rc != -ENODATA) {
-+				printk(KERN_WARNING "%s:  getxattr returned "
-+				       "%d for dev=%s ino=%ld\n", __FUNCTION__,
-+				       -rc, inode->i_sb->s_id, inode->i_ino);
-+				kfree(context);
-+				goto out;
-+			}
-+			/* Map ENODATA to the default file SID */
-+			sid = SECINITSID_FILE;
-+			rc = 0;
-+		} else {
-+			rc = security_context_to_sid(context, rc, &sid);
-+			if (rc) {
-+				printk(KERN_WARNING "%s:  context_to_sid(%s) "
-+				       "returned %d for dev=%s ino=%ld\n",
-+				       __FUNCTION__, context, -rc,
-+				       inode->i_sb->s_id, inode->i_ino);
-+				kfree(context);
-+				goto out;
-+			}
-+		}
-+		kfree(context);
-+		isec->sid = sid;
-+		break;
-+	case SECURITY_FS_USE_TASK:
-+		isec->sid = isec->task_sid;
-+		break;
-+	case SECURITY_FS_USE_TRANS:
-+		/* Default to the fs SID. */
-+		isec->sid = sbsec->sid;
-+
-+		/* Try to obtain a transition SID. */
-+		isec->sclass = inode_mode_to_security_class(inode->i_mode);
-+		rc = security_transition_sid(isec->task_sid,
-+					     sbsec->sid,
-+					     isec->sclass,
-+					     &sid);
-+		if (rc)
-+			goto out;
-+		isec->sid = sid;
-+		break;
-+	default:
-+		/* Default to the fs SID. */
-+		isec->sid = sbsec->sid;
-+
-+		if (sbsec->proc) {
-+			struct proc_inode *proci = PROC_I(inode);
-+			if (proci->pde) {
-+				isec->sclass = inode_mode_to_security_class(inode->i_mode);
-+				rc = selinux_proc_get_sid(proci->pde,
-+							  isec->sclass,
-+							  &sid);
-+				if (rc)
-+					goto out;
-+				isec->sid = sid;
-+			}
-+		}
-+		break;
-+	}
-+
-+	isec->initialized = 1;
-+
-+out:
-+	if (inode->i_sock) {
-+		struct socket *sock = SOCKET_I(inode);
-+		if (sock->sk) {
-+			isec->sclass = socket_type_to_security_class(sock->sk->sk_family,
-+			                                             sock->sk->sk_type);
-+		} else {
-+			isec->sclass = SECCLASS_SOCKET;
-+		}
-+	} else {
-+		isec->sclass = inode_mode_to_security_class(inode->i_mode);
-+	}
-+
-+	if (hold_sem)
-+		up(&isec->sem);
-+	return rc;
-+}
-+
-+/* Convert a Linux signal to an access vector. */
-+static inline u32 signal_to_av(int sig)
-+{
-+	u32 perm = 0;
-+
-+	switch (sig) {
-+	case SIGCHLD:
-+		/* Commonly granted from child to parent. */
-+		perm = PROCESS__SIGCHLD;
-+		break;
-+	case SIGKILL:
-+		/* Cannot be caught or ignored */
-+		perm = PROCESS__SIGKILL;
-+		break;
-+	case SIGSTOP:
-+		/* Cannot be caught or ignored */
-+		perm = PROCESS__SIGSTOP;
-+		break;
-+	default:
-+		/* All other signals. */
-+		perm = PROCESS__SIGNAL;
-+		break;
-+	}
-+
-+	return perm;
-+}
-+
-+/* Check permission betweeen a pair of tasks, e.g. signal checks,
-+   fork check, ptrace check, etc. */
-+int task_has_perm(struct task_struct *tsk1,
-+		  struct task_struct *tsk2,
-+		  u32 perms)
-+{
-+	struct task_security_struct *tsec1, *tsec2;
-+
-+	tsec1 = tsk1->security;
-+	tsec2 = tsk2->security;
-+	return avc_has_perm(tsec1->sid, tsec2->sid,
-+			    SECCLASS_PROCESS, perms, &tsec2->avcr, NULL);
-+}
-+
-+/* Check whether a task is allowed to use a capability. */
-+int task_has_capability(struct task_struct *tsk,
-+			int cap)
-+{
-+	struct task_security_struct *tsec;
-+	struct avc_audit_data ad;
-+
-+	tsec = tsk->security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,CAP);
-+	ad.tsk = tsk;
-+	ad.u.cap = cap;
-+
-+	return avc_has_perm(tsec->sid, tsec->sid,
-+			    SECCLASS_CAPABILITY, CAP_TO_MASK(cap), NULL, &ad);
-+}
-+
-+/* Check whether a task is allowed to use a system operation. */
-+int task_has_system(struct task_struct *tsk,
-+		    u32 perms)
-+{
-+	struct task_security_struct *tsec;
-+
-+	tsec = tsk->security;
-+
-+	return avc_has_perm(tsec->sid, SECINITSID_KERNEL,
-+			    SECCLASS_SYSTEM, perms, NULL, NULL);
-+}
-+
-+/* Check whether a task has a particular permission to an inode.
-+   The 'aeref' parameter is optional and allows other AVC
-+   entry references to be passed (e.g. the one in the struct file).
-+   The 'adp' parameter is optional and allows other audit
-+   data to be passed (e.g. the dentry). */
-+int inode_has_perm(struct task_struct *tsk,
-+		   struct inode *inode,
-+		   u32 perms,
-+		   struct avc_entry_ref *aeref,
-+		   struct avc_audit_data *adp)
-+{
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = tsk->security;
-+	isec = inode->i_security;
-+
-+	if (!adp) {
-+		adp = &ad;
-+		AVC_AUDIT_DATA_INIT(&ad, FS);
-+		ad.u.fs.inode = inode;
-+	}
-+
-+	return avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			    perms, aeref ? aeref : &isec->avcr, adp);
-+}
-+
-+/* Same as inode_has_perm, but pass explicit audit data containing
-+   the dentry to help the auditing code to more easily generate the
-+   pathname if needed. */
-+static inline int dentry_has_perm(struct task_struct *tsk,
-+				  struct vfsmount *mnt,
-+				  struct dentry *dentry,
-+				  u32 av)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct avc_audit_data ad;
-+	AVC_AUDIT_DATA_INIT(&ad,FS);
-+	ad.u.fs.mnt = mnt;
-+	ad.u.fs.dentry = dentry;
-+	return inode_has_perm(tsk, inode, av, NULL, &ad);
-+}
-+
-+/* Check whether a task can use an open file descriptor to
-+   access an inode in a given way.  Check access to the
-+   descriptor itself, and then use dentry_has_perm to
-+   check a particular permission to the file.
-+   Access to the descriptor is implicitly granted if it
-+   has the same SID as the process.  If av is zero, then
-+   access to the file is not checked, e.g. for cases
-+   where only the descriptor is affected like seek. */
-+static inline int file_has_perm(struct task_struct *tsk,
-+				struct file *file,
-+				u32 av)
-+{
-+	struct task_security_struct *tsec = tsk->security;
-+	struct file_security_struct *fsec = file->f_security;
-+	struct vfsmount *mnt = file->f_vfsmnt;
-+	struct dentry *dentry = file->f_dentry;
-+	struct inode *inode = dentry->d_inode;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, FS);
-+	ad.u.fs.mnt = mnt;
-+	ad.u.fs.dentry = dentry;
-+
-+	if (tsec->sid != fsec->sid) {
-+		rc = avc_has_perm(tsec->sid, fsec->sid,
-+				  SECCLASS_FD,
-+				  FD__USE,
-+				  &fsec->avcr, &ad);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	/* av is zero if only checking access to the descriptor. */
-+	if (av)
-+		return inode_has_perm(tsk, inode, av, &fsec->inode_avcr, &ad);
-+
-+	return 0;
-+}
-+
-+/* Check whether a task can create a file. */
-+static int may_create(struct inode *dir,
-+		      struct dentry *dentry,
-+		      u16 tclass)
-+{
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *dsec;
-+	struct superblock_security_struct *sbsec;
-+	u32 newsid;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	tsec = current->security;
-+	dsec = dir->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, FS);
-+	ad.u.fs.dentry = dentry;
-+
-+	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,
-+			  DIR__ADD_NAME | DIR__SEARCH,
-+			  &dsec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+
-+	if (tsec->create_sid) {
-+		newsid = tsec->create_sid;
-+	} else {
-+		rc = security_transition_sid(tsec->sid, dsec->sid, tclass,
-+					     &newsid);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	rc = avc_has_perm(tsec->sid, newsid, tclass, FILE__CREATE, NULL, &ad);
-+	if (rc)
-+		return rc;
-+
-+	sbsec = dir->i_sb->s_security;
-+
-+	return avc_has_perm(newsid, sbsec->sid,
-+			    SECCLASS_FILESYSTEM,
-+			    FILESYSTEM__ASSOCIATE, NULL, &ad);
-+}
-+
-+#define MAY_LINK   0
-+#define MAY_UNLINK 1
-+#define MAY_RMDIR  2
-+
-+/* Check whether a task can link, unlink, or rmdir a file/directory. */
-+static int may_link(struct inode *dir,
-+		    struct dentry *dentry,
-+		    int kind)
-+
-+{
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *dsec, *isec;
-+	struct avc_audit_data ad;
-+	u32 av;
-+	int rc;
-+
-+	tsec = current->security;
-+	dsec = dir->i_security;
-+	isec = dentry->d_inode->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, FS);
-+	ad.u.fs.dentry = dentry;
-+
-+	av = DIR__SEARCH;
-+	av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
-+	rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR,
-+			  av, &dsec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+
-+	switch (kind) {
-+	case MAY_LINK:
-+		av = FILE__LINK;
-+		break;
-+	case MAY_UNLINK:
-+		av = FILE__UNLINK;
-+		break;
-+	case MAY_RMDIR:
-+		av = DIR__RMDIR;
-+		break;
-+	default:
-+		printk(KERN_WARNING "may_link:  unrecognized kind %d\n", kind);
-+		return 0;
-+	}
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			  av, &isec->avcr, &ad);
-+	return rc;
-+}
-+
-+static inline int may_rename(struct inode *old_dir,
-+			     struct dentry *old_dentry,
-+			     struct inode *new_dir,
-+			     struct dentry *new_dentry)
-+{
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
-+	struct avc_audit_data ad;
-+	u32 av;
-+	int old_is_dir, new_is_dir;
-+	int rc;
-+
-+	tsec = current->security;
-+	old_dsec = old_dir->i_security;
-+	old_isec = old_dentry->d_inode->i_security;
-+	old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-+	new_dsec = new_dir->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, FS);
-+
-+	ad.u.fs.dentry = old_dentry;
-+	rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR,
-+			  DIR__REMOVE_NAME | DIR__SEARCH,
-+			  &old_dsec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+	rc = avc_has_perm(tsec->sid, old_isec->sid,
-+			  old_isec->sclass,
-+			  FILE__RENAME,
-+			  &old_isec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+	if (old_is_dir && new_dir != old_dir) {
-+		rc = avc_has_perm(tsec->sid, old_isec->sid,
-+				  old_isec->sclass,
-+				  DIR__REPARENT,
-+				  &old_isec->avcr, &ad);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	ad.u.fs.dentry = new_dentry;
-+	av = DIR__ADD_NAME | DIR__SEARCH;
-+	if (new_dentry->d_inode)
-+		av |= DIR__REMOVE_NAME;
-+	rc = avc_has_perm(tsec->sid, new_dsec->sid, SECCLASS_DIR,
-+			  av,&new_dsec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+	if (new_dentry->d_inode) {
-+		new_isec = new_dentry->d_inode->i_security;
-+		new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
-+		rc = avc_has_perm(tsec->sid, new_isec->sid,
-+				  new_isec->sclass,
-+				  (new_is_dir ? DIR__RMDIR : FILE__UNLINK),
-+				  &new_isec->avcr, &ad);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	return 0;
-+}
-+
-+/* Check whether a task can perform a filesystem operation. */
-+int superblock_has_perm(struct task_struct *tsk,
-+			struct super_block *sb,
-+			u32 perms,
-+			struct avc_audit_data *ad)
-+{
-+	struct task_security_struct *tsec;
-+	struct superblock_security_struct *sbsec;
-+
-+	tsec = tsk->security;
-+	sbsec = sb->s_security;
-+	return avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
-+			    perms, NULL, ad);
-+}
-+
-+/* Convert a Linux mode and permission mask to an access vector. */
-+static inline u32 file_mask_to_av(int mode, int mask)
-+{
-+	u32 av = 0;
-+
-+	if ((mode & S_IFMT) != S_IFDIR) {
-+		if (mask & MAY_EXEC)
-+			av |= FILE__EXECUTE;
-+		if (mask & MAY_READ)
-+			av |= FILE__READ;
-+
-+		if (mask & MAY_APPEND)
-+			av |= FILE__APPEND;
-+		else if (mask & MAY_WRITE)
-+			av |= FILE__WRITE;
-+
-+	} else {
-+		if (mask & MAY_EXEC)
-+			av |= DIR__SEARCH;
-+		if (mask & MAY_WRITE)
-+			av |= DIR__WRITE;
-+		if (mask & MAY_READ)
-+			av |= DIR__READ;
-+	}
-+
-+	return av;
-+}
-+
-+/* Convert a Linux file to an access vector. */
-+static inline u32 file_to_av(struct file *file)
-+{
-+	u32 av = 0;
-+
-+	if (file->f_mode & FMODE_READ)
-+		av |= FILE__READ;
-+	if (file->f_mode & FMODE_WRITE) {
-+		if (file->f_flags & O_APPEND)
-+			av |= FILE__APPEND;
-+		else
-+			av |= FILE__WRITE;
-+	}
-+
-+	return av;
-+}
-+
-+/* Set an inode's SID to a specified value. */
-+int inode_security_set_sid(struct inode *inode, u32 sid)
-+{
-+	struct inode_security_struct *isec = inode->i_security;
-+
-+	down(&isec->sem);
-+	isec->sclass = inode_mode_to_security_class(inode->i_mode);
-+	isec->sid = sid;
-+	isec->initialized = 1;
-+	up(&isec->sem);
-+	return 0;
-+}
-+
-+/* Set the security attributes on a newly created file. */
-+static int post_create(struct inode *dir,
-+		       struct dentry *dentry)
-+{
-+
-+	struct task_security_struct *tsec;
-+	struct inode *inode;
-+	struct inode_security_struct *dsec;
-+	struct superblock_security_struct *sbsec;
-+	u32 newsid;
-+	char *context;
-+	unsigned int len;
-+	int rc;
-+
-+	tsec = current->security;
-+	dsec = dir->i_security;
-+
-+	inode = dentry->d_inode;
-+	if (!inode) {
-+		/* Some file system types (e.g. NFS) may not instantiate
-+		   a dentry for all create operations (e.g. symlink),
-+		   so we have to check to see if the inode is non-NULL. */
-+		printk(KERN_WARNING "post_create:  no inode, dir (dev=%s, "
-+		       "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);
-+		return 0;
-+	}
-+
-+	if (tsec->create_sid) {
-+		newsid = tsec->create_sid;
-+	} else {
-+		rc = security_transition_sid(tsec->sid, dsec->sid,
-+					     inode_mode_to_security_class(inode->i_mode),
-+					     &newsid);
-+		if (rc) {
-+			printk(KERN_WARNING "post_create:  "
-+			       "security_transition_sid failed, rc=%d (dev=%s "
-+			       "ino=%ld)\n",
-+			       -rc, inode->i_sb->s_id, inode->i_ino);
-+			return rc;
-+		}
-+	}
-+
-+	rc = inode_security_set_sid(inode, newsid);
-+	if (rc) {
-+		printk(KERN_WARNING "post_create:  inode_security_set_sid "
-+		       "failed, rc=%d (dev=%s ino=%ld)\n",
-+		       -rc, inode->i_sb->s_id, inode->i_ino);
-+		return rc;
-+	}
-+
-+	sbsec = dir->i_sb->s_security;
-+	if (!sbsec)
-+		return 0;
-+
-+	if (sbsec->behavior == SECURITY_FS_USE_XATTR &&
-+	    inode->i_op->setxattr) {
-+		/* Use extended attributes. */
-+		rc = security_sid_to_context(newsid, &context, &len);
-+		if (rc) {
-+			printk(KERN_WARNING "post_create:  sid_to_context "
-+			       "failed, rc=%d (dev=%s ino=%ld)\n",
-+			       -rc, inode->i_sb->s_id, inode->i_ino);
-+			return rc;
-+		}
-+		down(&inode->i_sem);
-+		rc = inode->i_op->setxattr(dentry,
-+					   XATTR_NAME_SELINUX,
-+					   context, len, 0);
-+		up(&inode->i_sem);
-+		kfree(context);
-+		if (rc < 0) {
-+			printk(KERN_WARNING "post_create:  setxattr failed, "
-+			       "rc=%d (dev=%s ino=%ld)\n",
-+			       -rc, inode->i_sb->s_id, inode->i_ino);
-+			return rc;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+
-+/* Hook functions begin here. */
-+
-+static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
-+{
-+	int rc;
-+
-+	rc = secondary_ops->ptrace(parent,child);
-+	if (rc)
-+		return rc;
-+
-+	return task_has_perm(parent, child, PROCESS__PTRACE);
-+}
-+
-+static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
-+                          kernel_cap_t *inheritable, kernel_cap_t *permitted)
-+{
-+	int error;
-+
-+	error = task_has_perm(current, target, PROCESS__GETCAP);
-+	if (error)
-+		return error;
-+
-+	return secondary_ops->capget(target, effective, inheritable, permitted);
-+}
-+
-+static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective,
-+                                kernel_cap_t *inheritable, kernel_cap_t *permitted)
-+{
-+	int error;
-+
-+	error = task_has_perm(current, target, PROCESS__SETCAP);
-+	if (error)
-+		return error;
-+
-+	return secondary_ops->capset_check(target, effective, inheritable, permitted);
-+}
-+
-+static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,
-+                               kernel_cap_t *inheritable, kernel_cap_t *permitted)
-+{
-+	int error;
-+
-+	error = task_has_perm(current, target, PROCESS__SETCAP);
-+	if (error)
-+		return;
-+
-+	return secondary_ops->capset_set(target, effective, inheritable, permitted);
-+}
-+
-+static int selinux_capable(struct task_struct *tsk, int cap)
-+{
-+	int rc;
-+
-+	rc = secondary_ops->capable(tsk, cap);
-+	if (rc)
-+		return rc;
-+
-+	return task_has_capability(tsk,cap);
-+}
-+
-+static int selinux_sysctl(ctl_table *table, int op)
-+{
-+	int error = 0;
-+	u32 av;
-+	struct task_security_struct *tsec;
-+	u32 tsid;
-+	int rc;
-+
-+	tsec = current->security;
-+
-+	rc = selinux_proc_get_sid(table->de, (op == 001) ?
-+	                          SECCLASS_DIR : SECCLASS_FILE, &tsid);
-+	if (rc) {
-+		/* Default to the well-defined sysctl SID. */
-+		tsid = SECINITSID_SYSCTL;
-+	}
-+
-+	/* The op values are "defined" in sysctl.c, thereby creating
-+	 * a bad coupling between this module and sysctl.c */
-+	if(op == 001) {
-+		error = avc_has_perm(tsec->sid, tsid,
-+				     SECCLASS_DIR, DIR__SEARCH, NULL, NULL);
-+	} else {
-+		av = 0;
-+		if (op & 004)
-+			av |= FILE__READ;
-+		if (op & 002)
-+			av |= FILE__WRITE;
-+		if (av)
-+			error = avc_has_perm(tsec->sid, tsid,
-+					     SECCLASS_FILE, av, NULL, NULL);
-+        }
-+
-+	return error;
-+}
-+
-+static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
-+{
-+	int rc = 0;
-+
-+	if (!sb)
-+		return 0;
-+
-+	switch (cmds) {
-+		case Q_SYNC:
-+		case Q_QUOTAON:
-+		case Q_QUOTAOFF:
-+	        case Q_SETINFO:
-+		case Q_SETQUOTA:
-+			rc = superblock_has_perm(current,
-+						 sb,
-+						 FILESYSTEM__QUOTAMOD, NULL);
-+			break;
-+	        case Q_GETFMT:
-+	        case Q_GETINFO:
-+		case Q_GETQUOTA:
-+			rc = superblock_has_perm(current,
-+						 sb,
-+						 FILESYSTEM__QUOTAGET, NULL);
-+			break;
-+		default:
-+			rc = 0;  /* let the kernel handle invalid cmds */
-+			break;
-+	}
-+	return rc;
-+}
-+
-+static int selinux_quota_on(struct file *f)
-+{
-+	return file_has_perm(current, f, FILE__QUOTAON);;
-+}
-+
-+static int selinux_syslog(int type)
-+{
-+	int rc;
-+
-+	rc = secondary_ops->syslog(type);
-+	if (rc)
-+		return rc;
-+
-+	switch (type) {
-+		case 3:         /* Read last kernel messages */
-+			rc = task_has_system(current, SYSTEM__SYSLOG_READ);
-+			break;
-+		case 6:         /* Disable logging to console */
-+		case 7:         /* Enable logging to console */
-+		case 8:		/* Set level of messages printed to console */
-+			rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
-+			break;
-+		case 0:         /* Close log */
-+		case 1:         /* Open log */
-+		case 2:         /* Read from log */
-+		case 4:         /* Read/clear last kernel messages */
-+		case 5:         /* Clear ring buffer */
-+		default:
-+			rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
-+			break;
-+	}
-+	return rc;
-+}
-+
-+/*
-+ * Check that a process has enough memory to allocate a new virtual
-+ * mapping. 0 means there is enough memory for the allocation to
-+ * succeed and -ENOMEM implies there is not.
-+ *
-+ * We currently support three overcommit policies, which are set via the
-+ * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-acounting
-+ *
-+ * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
-+ * Additional code 2002 Jul 20 by Robert Love.
-+ */
-+static int selinux_vm_enough_memory(long pages)
-+{
-+	unsigned long free, allowed;
-+	int rc;
-+	struct task_security_struct *tsec = current->security;
-+
-+	vm_acct_memory(pages);
-+
-+        /*
-+	 * Sometimes we want to use more memory than we have
-+	 */
-+	if (sysctl_overcommit_memory == 1)
-+		return 0;
-+
-+	if (sysctl_overcommit_memory == 0) {
-+		free = get_page_cache_size();
-+		free += nr_free_pages();
-+		free += nr_swap_pages;
-+
-+		/*
-+		 * Any slabs which are created with the
-+		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
-+		 * which are reclaimable, under pressure.  The dentry
-+		 * cache and most inode caches should fall into this
-+		 */
-+		free += atomic_read(&slab_reclaim_pages);
-+
-+		/*
-+		 * Leave the last 3% for privileged processes.
-+		 * Don't audit the check, as it is applied to all processes
-+		 * that allocate mappings.
-+		 */
-+		rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
-+		if (!rc) {
-+			rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
-+						  SECCLASS_CAPABILITY,
-+						  CAP_TO_MASK(CAP_SYS_ADMIN),
-+						  NULL, NULL);
-+		}
-+		if (rc)
-+			free -= free / 32;
-+
-+		if (free > pages)
-+			return 0;
-+		vm_unacct_memory(pages);
-+		return -ENOMEM;
-+	}
-+
-+	allowed = totalram_pages * sysctl_overcommit_ratio / 100;
-+	allowed += total_swap_pages;
-+
-+	if (atomic_read(&vm_committed_space) < allowed)
-+		return 0;
-+
-+	vm_unacct_memory(pages);
-+
-+	return -ENOMEM;
-+}
-+
-+static int selinux_netlink_send(struct sk_buff *skb)
-+{
-+	if (capable(CAP_NET_ADMIN))
-+		cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
-+	else
-+		NETLINK_CB(skb).eff_cap = 0;
-+	return 0;
-+}
-+
-+static int selinux_netlink_recv(struct sk_buff *skb)
-+{
-+	if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
-+		return -EPERM;
-+	return 0;
-+}
-+
-+/* binprm security operations */
-+
-+static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
-+{
-+	int rc;
-+
-+	/* Make sure that the secondary module doesn't use the
-+	   bprm->security field, since we do not yet support chaining
-+	   of multiple security structures on the field.  Neither
-+	   the dummy nor the capability module use the field.  The owlsm
-+	   module uses the field if CONFIG_OWLSM_FD is enabled. */
-+	rc = secondary_ops->bprm_alloc_security(bprm);
-+	if (rc)
-+		return rc;
-+	if (bprm->security) {
-+		printk(KERN_WARNING "%s: no support yet for chaining on the "
-+		       "security field by secondary modules.\n", __FUNCTION__);
-+		/* Release the secondary module's security object. */
-+		secondary_ops->bprm_free_security(bprm);
-+		/* Unregister the secondary module to prevent problems
-+		   with subsequent binprm hooks. This will revert to the
-+		   original (dummy) module for the secondary operations. */
-+		rc = security_ops->unregister_security("unknown", secondary_ops);
-+		if (rc)
-+			return rc;
-+		printk(KERN_WARNING "%s: Unregistered the secondary security "
-+		       "module.\n", __FUNCTION__);
-+	}
-+	bprm->security = NULL;
-+	return 0;
-+}
-+
-+static int selinux_bprm_set_security(struct linux_binprm *bprm)
-+{
-+	struct task_security_struct *tsec;
-+	struct inode *inode = bprm->file->f_dentry->d_inode;
-+	struct inode_security_struct *isec;
-+	u32 newsid;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	rc = secondary_ops->bprm_set_security(bprm);
-+	if (rc)
-+		return rc;
-+
-+	if (bprm->sh_bang || bprm->security)
-+		/* The security field should already be set properly. */
-+		return 0;
-+
-+	tsec = current->security;
-+	isec = inode->i_security;
-+
-+	/* Default to the current task SID. */
-+	bprm->security = (void *)tsec->sid;
-+
-+	/* Reset create SID on execve. */
-+	tsec->create_sid = 0;
-+
-+	if (tsec->exec_sid) {
-+		newsid = tsec->exec_sid;
-+		/* Reset exec SID on execve. */
-+		tsec->exec_sid = 0;
-+	} else {
-+		/* Check for a default transition on this program. */
-+		rc = security_transition_sid(tsec->sid, isec->sid,
-+		                             SECCLASS_PROCESS, &newsid);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	AVC_AUDIT_DATA_INIT(&ad, FS);
-+	ad.u.fs.mnt = bprm->file->f_vfsmnt;
-+	ad.u.fs.dentry = bprm->file->f_dentry;
-+
-+	if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
-+		newsid = tsec->sid;
-+
-+        if (tsec->sid == newsid) {
-+		rc = avc_has_perm(tsec->sid, isec->sid,
-+				  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS,
-+				  &isec->avcr, &ad);
-+		if (rc)
-+			return rc;
-+	} else {
-+		/* Check permissions for the transition. */
-+		rc = avc_has_perm(tsec->sid, newsid,
-+				  SECCLASS_PROCESS, PROCESS__TRANSITION,
-+				  NULL,
-+				  &ad);
-+		if (rc)
-+			return rc;
-+
-+		rc = avc_has_perm(newsid, isec->sid,
-+				  SECCLASS_FILE, FILE__ENTRYPOINT,
-+				  &isec->avcr, &ad);
-+		if (rc)
-+			return rc;
-+
-+		/* Set the security field to the new SID. */
-+		bprm->security = (void*) newsid;
-+	}
-+
-+	return 0;
-+}
-+
-+static int selinux_bprm_check_security (struct linux_binprm *bprm)
-+{
-+	return 0;
-+}
-+
-+
-+static int selinux_bprm_secureexec (struct linux_binprm *bprm)
-+{
-+	struct task_security_struct *tsec = current->security;
-+	int atsecure = 0;
-+
-+	if (tsec->osid != tsec->sid) {
-+		/* Enable secure mode for SIDs transitions unless
-+		   the noatsecure permission is granted between
-+		   the two SIDs, i.e. ahp returns 0. */
-+		atsecure = avc_has_perm(tsec->osid, tsec->sid,
-+					 SECCLASS_PROCESS,
-+					 PROCESS__NOATSECURE, NULL, NULL);
-+	}
-+
-+	/* Note that we must include the legacy uid/gid test below
-+	   to retain it, as the new userland will simply use the
-+	   value passed by AT_SECURE to decide whether to enable
-+	   secure mode. */
-+	return ( atsecure || current->euid != current->uid ||
-+		current->egid != current->gid);
-+}
-+
-+static void selinux_bprm_free_security(struct linux_binprm *bprm)
-+{
-+	/* Nothing to do - not dynamically allocated. */
-+	return;
-+}
-+
-+/* Derived from fs/exec.c:flush_old_files. */
-+static inline void flush_unauthorized_files(struct files_struct * files)
-+{
-+	struct avc_audit_data ad;
-+	struct file *file;
-+	long j = -1;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,FS);
-+
-+	spin_lock(&files->file_lock);
-+	for (;;) {
-+		unsigned long set, i;
-+
-+		j++;
-+		i = j * __NFDBITS;
-+		if (i >= files->max_fds || i >= files->max_fdset)
-+			break;
-+		set = files->open_fds->fds_bits[j];
-+		if (!set)
-+			continue;
-+		spin_unlock(&files->file_lock);
-+		for ( ; set ; i++,set >>= 1) {
-+			if (set & 1) {
-+				file = fget(i);
-+				if (!file)
-+					continue;
-+				if (file_has_perm(current,
-+						  file,
-+						  file_to_av(file)))
-+					sys_close(i);
-+				fput(file);
-+			}
-+		}
-+		spin_lock(&files->file_lock);
-+
-+	}
-+	spin_unlock(&files->file_lock);
-+}
-+
-+static void selinux_bprm_compute_creds(struct linux_binprm *bprm)
-+{
-+	struct task_security_struct *tsec, *psec;
-+	u32 sid;
-+	struct av_decision avd;
-+	int rc;
-+
-+	secondary_ops->bprm_compute_creds(bprm);
-+
-+	tsec = current->security;
-+
-+	sid = (u32)bprm->security;
-+	if (!sid)
-+		sid = tsec->sid;
-+
-+	tsec->osid = tsec->sid;
-+	if (tsec->sid != sid) {
-+		/* Check for shared state.  If not ok, leave SID
-+		   unchanged and kill. */
-+		if ((atomic_read(&current->fs->count) > 1 ||
-+		     atomic_read(&current->files->count) > 1 ||
-+		     atomic_read(&current->sighand->count) > 1)) {
-+			rc = avc_has_perm(tsec->sid, sid,
-+					  SECCLASS_PROCESS, PROCESS__SHARE,
-+					  NULL, NULL);
-+			if (rc) {
-+				force_sig_specific(SIGKILL, current);
-+				return;
-+			}
-+		}
-+
-+		/* Check for ptracing, and update the task SID if ok.
-+		   Otherwise, leave SID unchanged and kill. */
-+		task_lock(current);
-+		if (current->ptrace & PT_PTRACED) {
-+			psec = current->parent->security;
-+			rc = avc_has_perm_noaudit(psec->sid, sid,
-+					  SECCLASS_PROCESS, PROCESS__PTRACE,
-+					  NULL, &avd);
-+			if (!rc)
-+				tsec->sid = sid;
-+			task_unlock(current);
-+			avc_audit(psec->sid, sid, SECCLASS_PROCESS,
-+				  PROCESS__PTRACE, &avd, rc, NULL);
-+			if (rc) {
-+				force_sig_specific(SIGKILL, current);
-+				return;
-+			}
-+		} else {
-+			tsec->sid = sid;
-+			task_unlock(current);
-+		}
-+
-+		/* Close files for which the new task SID is not authorized. */
-+		flush_unauthorized_files(current->files);
-+
-+		/* Wake up the parent if it is waiting so that it can
-+		   recheck wait permission to the new task SID. */
-+		wake_up_interruptible(&current->parent->wait_chldexit);
-+	}
-+}
-+
-+/* superblock security operations */
-+
-+static int selinux_sb_alloc_security(struct super_block *sb)
-+{
-+	return superblock_alloc_security(sb);
-+}
-+
-+static void selinux_sb_free_security(struct super_block *sb)
-+{
-+	superblock_free_security(sb);
-+}
-+
-+static int selinux_sb_kern_mount(struct super_block *sb)
-+{
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	rc = superblock_doinit(sb);
-+	if (rc)
-+		return rc;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,FS);
-+	ad.u.fs.dentry = sb->s_root;
-+	return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);
-+}
-+
-+static int selinux_sb_statfs(struct super_block *sb)
-+{
-+	struct avc_audit_data ad;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,FS);
-+	ad.u.fs.dentry = sb->s_root;
-+	return superblock_has_perm(current, sb, FILESYSTEM__GETATTR, &ad);
-+}
-+
-+static int selinux_mount(char * dev_name,
-+                         struct nameidata *nd,
-+                         char * type,
-+                         unsigned long flags,
-+                         void * data)
-+{
-+	if (flags & MS_REMOUNT)
-+		return superblock_has_perm(current, nd->mnt->mnt_sb,
-+		                           FILESYSTEM__REMOUNT, NULL);
-+	else
-+		return dentry_has_perm(current, nd->mnt, nd->dentry,
-+		                       FILE__MOUNTON);
-+}
-+
-+static int selinux_umount(struct vfsmount *mnt, int flags)
-+{
-+	return superblock_has_perm(current,mnt->mnt_sb,
-+	                           FILESYSTEM__UNMOUNT,NULL);
-+}
-+
-+/* inode security operations */
-+
-+static int selinux_inode_alloc_security(struct inode *inode)
-+{
-+	return inode_alloc_security(inode);
-+}
-+
-+static void selinux_inode_free_security(struct inode *inode)
-+{
-+	inode_free_security(inode);
-+}
-+
-+static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
-+{
-+	return may_create(dir, dentry, SECCLASS_FILE);
-+}
-+
-+static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask)
-+{
-+	post_create(dir, dentry);
-+}
-+
-+static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
-+{
-+	int rc;
-+
-+	rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);
-+	if (rc)
-+		return rc;
-+	return may_link(dir, old_dentry, MAY_LINK);
-+}
-+
-+static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
-+{
-+	return;
-+}
-+
-+static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
-+{
-+	return may_link(dir, dentry, MAY_UNLINK);
-+}
-+
-+static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
-+{
-+	return may_create(dir, dentry, SECCLASS_LNK_FILE);
-+}
-+
-+static void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name)
-+{
-+	post_create(dir, dentry);
-+}
-+
-+static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
-+{
-+	return may_create(dir, dentry, SECCLASS_DIR);
-+}
-+
-+static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask)
-+{
-+	post_create(dir, dentry);
-+}
-+
-+static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
-+{
-+	return may_link(dir, dentry, MAY_RMDIR);
-+}
-+
-+static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-+{
-+	return may_create(dir, dentry, inode_mode_to_security_class(mode));
-+}
-+
-+static void selinux_inode_post_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-+{
-+	post_create(dir, dentry);
-+}
-+
-+static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
-+                                struct inode *new_inode, struct dentry *new_dentry)
-+{
-+	return may_rename(old_inode, old_dentry, new_inode, new_dentry);
-+}
-+
-+static void selinux_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry,
-+                                      struct inode *new_inode, struct dentry *new_dentry)
-+{
-+	return;
-+}
-+
-+static int selinux_inode_readlink(struct dentry *dentry)
-+{
-+	return dentry_has_perm(current, NULL, dentry, FILE__READ);
-+}
-+
-+static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
-+{
-+	int rc;
-+
-+	rc = secondary_ops->inode_follow_link(dentry,nameidata);
-+	if (rc)
-+		return rc;
-+	return dentry_has_perm(current, NULL, dentry, FILE__READ);
-+}
-+
-+static int selinux_inode_permission(struct inode *inode, int mask)
-+{
-+	if (!mask) {
-+		/* No permission to check.  Existence test. */
-+		return 0;
-+	}
-+
-+	return inode_has_perm(current, inode,
-+			       file_mask_to_av(inode->i_mode, mask), NULL, NULL);
-+}
-+
-+static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
-+{
-+	if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
-+			       ATTR_ATIME_SET | ATTR_MTIME_SET))
-+		return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
-+
-+	return dentry_has_perm(current, NULL, dentry, FILE__WRITE);
-+}
-+
-+static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
-+{
-+	return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
-+}
-+
-+static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
-+{
-+	struct task_security_struct *tsec = current->security;
-+	struct inode *inode = dentry->d_inode;
-+	struct inode_security_struct *isec = inode->i_security;
-+	struct superblock_security_struct *sbsec;
-+	struct avc_audit_data ad;
-+	u32 newsid;
-+	int rc = 0;
-+
-+	if (strcmp(name, XATTR_NAME_SELINUX)) {
-+		if (!strncmp(name, XATTR_SECURITY_PREFIX,
-+			     sizeof XATTR_SECURITY_PREFIX - 1) &&
-+		    !capable(CAP_SYS_ADMIN)) {
-+			/* A different attribute in the security namespace.
-+			   Restrict to administrator. */
-+			return -EPERM;
-+		}
-+
-+		/* Not an attribute we recognize, so just check the
-+		   ordinary setattr permission. */
-+		return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
-+	}
-+
-+	AVC_AUDIT_DATA_INIT(&ad,FS);
-+	ad.u.fs.dentry = dentry;
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			  FILE__RELABELFROM,
-+			  &isec->avcr, &ad);
-+	if (rc)
-+		return rc;
-+
-+	rc = security_context_to_sid(value, size, &newsid);
-+	if (rc)
-+		return rc;
-+
-+	rc = avc_has_perm(tsec->sid, newsid, isec->sclass,
-+			  FILE__RELABELTO, NULL, &ad);
-+	if (rc)
-+		return rc;
-+
-+	sbsec = inode->i_sb->s_security;
-+	if (!sbsec)
-+		return 0;
-+
-+	return avc_has_perm(newsid,
-+			    sbsec->sid,
-+			    SECCLASS_FILESYSTEM,
-+			    FILESYSTEM__ASSOCIATE,
-+			    NULL,
-+			    &ad);
-+}
-+
-+static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
-+                                        void *value, size_t size, int flags)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct inode_security_struct *isec = inode->i_security;
-+	u32 newsid;
-+	int rc;
-+
-+	if (strcmp(name, XATTR_NAME_SELINUX)) {
-+		/* Not an attribute we recognize, so nothing to do. */
-+		return;
-+	}
-+
-+	rc = security_context_to_sid(value, size, &newsid);
-+	if (rc) {
-+		printk(KERN_WARNING "%s:  unable to obtain SID for context "
-+		       "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc);
-+		return;
-+	}
-+
-+	isec->sid = newsid;
-+	return;
-+}
-+
-+static int selinux_inode_getxattr (struct dentry *dentry, char *name)
-+{
-+	return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
-+}
-+
-+static int selinux_inode_listxattr (struct dentry *dentry)
-+{
-+	return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
-+}
-+
-+static int selinux_inode_removexattr (struct dentry *dentry, char *name)
-+{
-+	if (strcmp(name, XATTR_NAME_SELINUX)) {
-+		if (!strncmp(name, XATTR_SECURITY_PREFIX,
-+			     sizeof XATTR_SECURITY_PREFIX - 1) &&
-+		    !capable(CAP_SYS_ADMIN)) {
-+			/* A different attribute in the security namespace.
-+			   Restrict to administrator. */
-+			return -EPERM;
-+		}
-+
-+		/* Not an attribute we recognize, so just check the
-+		   ordinary setattr permission. Might want a separate
-+		   permission for removexattr. */
-+		return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
-+	}
-+
-+	/* No one is allowed to remove a SELinux security label.
-+	   You can change the label, but all data must be labeled. */
-+	return -EACCES;
-+}
-+
-+static int selinux_inode_getsecurity(struct dentry *dentry, const char *name, void *buffer, size_t size)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct inode_security_struct *isec = inode->i_security;
-+	char *context;
-+	unsigned len;
-+	int rc;
-+
-+	/* Permission check handled by selinux_inode_getxattr hook.*/
-+
-+	if (strcmp(name, XATTR_SELINUX_SUFFIX))
-+		return -EOPNOTSUPP;
-+
-+	rc = security_sid_to_context(isec->sid, &context, &len);
-+	if (rc)
-+		return rc;
-+
-+	if (!buffer || !size) {
-+		kfree(context);
-+		return len;
-+	}
-+	if (size < len) {
-+		kfree(context);
-+		return -ERANGE;
-+	}
-+	memcpy(buffer, context, len);
-+	kfree(context);
-+	return len;
-+}
-+
-+static int selinux_inode_setsecurity(struct dentry *dentry, const char *name,
-+                                     const void *value, size_t size, int flags)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct inode_security_struct *isec = inode->i_security;
-+	u32 newsid;
-+	int rc;
-+
-+	if (strcmp(name, XATTR_SELINUX_SUFFIX))
-+		return -EOPNOTSUPP;
-+
-+	if (!value || !size)
-+		return -EACCES;
-+
-+	rc = security_context_to_sid((void*)value, size, &newsid);
-+	if (rc)
-+		return rc;
-+
-+	isec->sid = newsid;
-+	return 0;
-+}
-+
-+static int selinux_inode_listsecurity(struct dentry *dentry, char *buffer)
-+{
-+	const int len = sizeof(XATTR_NAME_SELINUX);
-+	if (buffer)
-+		memcpy(buffer, XATTR_NAME_SELINUX, len);
-+	return len;
-+}
-+
-+/* file security operations */
-+
-+static int selinux_file_permission(struct file *file, int mask)
-+{
-+	struct inode *inode = file->f_dentry->d_inode;
-+
-+	if (!mask) {
-+		/* No permission to check.  Existence test. */
-+		return 0;
-+	}
-+
-+	/* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
-+	if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
-+		mask |= MAY_APPEND;
-+
-+	return file_has_perm(current, file,
-+			     file_mask_to_av(inode->i_mode, mask));
-+}
-+
-+static int selinux_file_alloc_security(struct file *file)
-+{
-+	return file_alloc_security(file);
-+}
-+
-+static void selinux_file_free_security(struct file *file)
-+{
-+	file_free_security(file);
-+}
-+
-+static int selinux_file_ioctl(struct file *file, unsigned int cmd,
-+			      unsigned long arg)
-+{
-+	int error = 0;
-+
-+	switch (cmd) {
-+		case FIONREAD:
-+		/* fall through */
-+		case FIBMAP:
-+		/* fall through */
-+		case FIGETBSZ:
-+		/* fall through */
-+		case EXT2_IOC_GETFLAGS:
-+		/* fall through */
-+		case EXT2_IOC_GETVERSION:
-+			error = file_has_perm(current, file, FILE__GETATTR);
-+			break;
-+
-+		case EXT2_IOC_SETFLAGS:
-+		/* fall through */
-+		case EXT2_IOC_SETVERSION:
-+			error = file_has_perm(current, file, FILE__SETATTR);
-+			break;
-+
-+		/* sys_ioctl() checks */
-+		case FIONBIO:
-+		/* fall through */
-+		case FIOASYNC:
-+			error = file_has_perm(current, file, 0);
-+			break;
-+
-+	        case KDSKBENT:
-+	        case KDSKBSENT:
-+		  	if (!capable(CAP_SYS_TTY_CONFIG))
-+				error = -EPERM;
-+			break;
-+
-+		/* default case assumes that the command will go
-+		 * to the file's ioctl() function.
-+		 */
-+		default:
-+			error = file_has_perm(current, file, FILE__IOCTL);
-+
-+	}
-+	return error;
-+}
-+
-+static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags)
-+{
-+	u32 av;
-+
-+	if (file) {
-+		/* read access is always possible with a mapping */
-+		av = FILE__READ;
-+
-+		/* write access only matters if the mapping is shared */
-+		if ((flags & MAP_TYPE) == MAP_SHARED && (prot & PROT_WRITE))
-+			av |= FILE__WRITE;
-+
-+		if (prot & PROT_EXEC)
-+			av |= FILE__EXECUTE;
-+
-+		return file_has_perm(current, file, av);
-+	}
-+	return 0;
-+}
-+
-+static int selinux_file_mprotect(struct vm_area_struct *vma,
-+				 unsigned long prot)
-+{
-+	return selinux_file_mmap(vma->vm_file, prot, vma->vm_flags);
-+}
-+
-+static int selinux_file_lock(struct file *file, unsigned int cmd)
-+{
-+	return file_has_perm(current, file, FILE__LOCK);
-+}
-+
-+static int selinux_file_fcntl(struct file *file, unsigned int cmd,
-+			      unsigned long arg)
-+{
-+	int err = 0;
-+
-+	switch (cmd) {
-+	        case F_SETFL:
-+			if (!file->f_dentry || !file->f_dentry->d_inode) {
-+				err = -EINVAL;
-+				break;
-+			}
-+
-+			if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
-+				err = file_has_perm(current, file,FILE__WRITE);
-+				break;
-+			}
-+			/* fall through */
-+	        case F_SETOWN:
-+	        case F_SETSIG:
-+	        case F_GETFL:
-+	        case F_GETOWN:
-+	        case F_GETSIG:
-+			/* Just check FD__USE permission */
-+			err = file_has_perm(current, file, 0);
-+			break;
-+		case F_GETLK:
-+		case F_SETLK:
-+	        case F_SETLKW:
-+	        case F_GETLK64:
-+		case F_SETLK64:
-+	        case F_SETLKW64:
-+			if (!file->f_dentry || !file->f_dentry->d_inode) {
-+				err = -EINVAL;
-+				break;
-+			}
-+			err = file_has_perm(current, file, FILE__LOCK);
-+			break;
-+	}
-+
-+	return err;
-+}
-+
-+static int selinux_file_set_fowner(struct file *file)
-+{
-+	struct task_security_struct *tsec;
-+	struct file_security_struct *fsec;
-+
-+	tsec = current->security;
-+	fsec = file->f_security;
-+	fsec->fown_sid = tsec->sid;
-+
-+	return 0;
-+}
-+
-+static int selinux_file_send_sigiotask(struct task_struct *tsk,
-+				       struct fown_struct *fown,
-+				       int fd, int reason)
-+{
-+        struct file *file;
-+	u32 perm;
-+	struct task_security_struct *tsec;
-+	struct file_security_struct *fsec;
-+
-+	/* struct fown_struct is never outside the context of a struct file */
-+        file = (struct file *)((long)fown - offsetof(struct file,f_owner));
-+
-+	tsec = tsk->security;
-+	fsec = file->f_security;
-+
-+	if (!fown->signum)
-+		perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
-+	else
-+		perm = signal_to_av(fown->signum);
-+
-+	return avc_has_perm(fsec->fown_sid, tsec->sid,
-+			    SECCLASS_PROCESS, perm, NULL, NULL);
-+}
-+
-+static int selinux_file_receive(struct file *file)
-+{
-+	return file_has_perm(current, file, file_to_av(file));
-+}
-+
-+/* task security operations */
-+
-+static int selinux_task_create(unsigned long clone_flags)
-+{
-+	return task_has_perm(current, current, PROCESS__FORK);
-+}
-+
-+static int selinux_task_alloc_security(struct task_struct *tsk)
-+{
-+	struct task_security_struct *tsec1, *tsec2;
-+	int rc;
-+
-+	tsec1 = current->security;
-+
-+	rc = task_alloc_security(tsk);
-+	if (rc)
-+		return rc;
-+	tsec2 = tsk->security;
-+
-+	tsec2->osid = tsec1->osid;
-+	tsec2->sid = tsec1->sid;
-+
-+	/* Retain the exec and create SIDs across fork */
-+	tsec2->exec_sid = tsec1->exec_sid;
-+	tsec2->create_sid = tsec1->create_sid;
-+
-+	return 0;
-+}
-+
-+static void selinux_task_free_security(struct task_struct *tsk)
-+{
-+	task_free_security(tsk);
-+}
-+
-+static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
-+{
-+	/* Since setuid only affects the current process, and
-+	   since the SELinux controls are not based on the Linux
-+	   identity attributes, SELinux does not need to control
-+	   this operation.  However, SELinux does control the use
-+	   of the CAP_SETUID and CAP_SETGID capabilities using the
-+	   capable hook. */
-+	return 0;
-+}
-+
-+static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
-+{
-+	return secondary_ops->task_post_setuid(id0,id1,id2,flags);
-+}
-+
-+static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
-+{
-+	/* See the comment for setuid above. */
-+	return 0;
-+}
-+
-+static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
-+{
-+	return task_has_perm(current, p, PROCESS__SETPGID);
-+}
-+
-+static int selinux_task_getpgid(struct task_struct *p)
-+{
-+	return task_has_perm(current, p, PROCESS__GETPGID);
-+}
-+
-+static int selinux_task_getsid(struct task_struct *p)
-+{
-+	return task_has_perm(current, p, PROCESS__GETSESSION);
-+}
-+
-+static int selinux_task_setgroups(int gidsetsize, gid_t *grouplist)
-+{
-+	/* See the comment for setuid above. */
-+	return 0;
-+}
-+
-+static int selinux_task_setnice(struct task_struct *p, int nice)
-+{
-+	return task_has_perm(current,p, PROCESS__SETSCHED);
-+}
-+
-+static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
-+{
-+	/* SELinux does not currently provide a process
-+	   resource limit policy based on security contexts.
-+	   It does control the use of the CAP_SYS_RESOURCE capability
-+	   using the capable hook. */
-+	return 0;
-+}
-+
-+static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
-+{
-+	struct task_security_struct *tsec1, *tsec2;
-+
-+	tsec1 = current->security;
-+	tsec2 = p->security;
-+
-+	/* No auditing from the setscheduler hook, since the runqueue lock
-+	   is held and the system will deadlock if we try to log an audit
-+	   message. */
-+	return avc_has_perm_noaudit(tsec1->sid, tsec2->sid,
-+				    SECCLASS_PROCESS, PROCESS__SETSCHED,
-+				    &tsec2->avcr, NULL);
-+}
-+
-+static int selinux_task_getscheduler(struct task_struct *p)
-+{
-+	return task_has_perm(current, p, PROCESS__GETSCHED);
-+}
-+
-+static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig)
-+{
-+	u32 perm;
-+
-+	if (info && ((unsigned long)info == 1 ||
-+	             (unsigned long)info == 2 || SI_FROMKERNEL(info)))
-+		return 0;
-+
-+	if (!sig)
-+		perm = PROCESS__SIGNULL; /* null signal; existence test */
-+	else
-+		perm = signal_to_av(sig);
-+
-+	return task_has_perm(current, p, perm);
-+}
-+
-+static int selinux_task_prctl(int option,
-+			      unsigned long arg2,
-+			      unsigned long arg3,
-+			      unsigned long arg4,
-+			      unsigned long arg5)
-+{
-+	/* The current prctl operations do not appear to require
-+	   any SELinux controls since they merely observe or modify
-+	   the state of the current process. */
-+	return 0;
-+}
-+
-+static int selinux_task_wait(struct task_struct *p)
-+{
-+	u32 perm;
-+
-+	perm = signal_to_av(p->exit_signal);
-+
-+	return task_has_perm(p, current, perm);
-+}
-+
-+static void selinux_task_reparent_to_init(struct task_struct *p)
-+{
-+  	struct task_security_struct *tsec;
-+
-+	secondary_ops->task_reparent_to_init(p);
-+
-+	tsec = p->security;
-+	tsec->osid = tsec->sid;
-+	tsec->sid = SECINITSID_KERNEL;
-+	return;
-+}
-+
-+static void selinux_task_to_inode(struct task_struct *p,
-+				  struct inode *inode)
-+{
-+	struct task_security_struct *tsec = p->security;
-+	struct inode_security_struct *isec = inode->i_security;
-+
-+	isec->sid = tsec->sid;
-+	isec->initialized = 1;
-+	return;
-+}
-+
-+#ifdef CONFIG_SECURITY_NETWORK
-+
-+/* socket security operations */
-+static int socket_has_perm(struct task_struct *task, struct socket *sock,
-+			   u32 perms)
-+{
-+	struct inode_security_struct *isec;
-+	struct task_security_struct *tsec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	tsec = task->security;
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = sock->sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   perms, &isec->avcr, &ad);
-+
-+	return err;
-+}
-+
-+static int selinux_socket_create(int family, int type, int protocol)
-+{
-+	int err;
-+	struct task_security_struct *tsec;
-+
-+	tsec = current->security;
-+
-+	err = avc_has_perm(tsec->sid, tsec->sid,
-+			   socket_type_to_security_class(family, type),
-+			   SOCKET__CREATE, NULL, NULL);
-+
-+	return err;
-+}
-+
-+static void selinux_socket_post_create(struct socket *sock, int family, int type, int protocol)
-+{
-+	int err;
-+	struct inode_security_struct *isec;
-+	struct task_security_struct *tsec;
-+
-+	err = inode_doinit(SOCK_INODE(sock));
-+	if (err < 0)
-+		return;
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	tsec = current->security;
-+	isec->sclass = socket_type_to_security_class(family, type);
-+	isec->sid = tsec->sid;
-+
-+	return;
-+}
-+
-+/* Range of port numbers used to automatically bind.
-+   Need to determine whether we should perform a name_bind
-+   permission check between the socket and the port number. */
-+#define ip_local_port_range_0 sysctl_local_port_range[0]
-+#define ip_local_port_range_1 sysctl_local_port_range[1]
-+
-+static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
-+{
-+	int err;
-+
-+	err = socket_has_perm(current, sock, SOCKET__BIND);
-+	if (err)
-+		return err;
-+
-+	/*
-+	 * If PF_INET, check name_bind permission for the port.
-+	 */
-+	if (sock->sk->sk_family == PF_INET) {
-+		struct inode_security_struct *isec;
-+		struct task_security_struct *tsec;
-+		struct avc_audit_data ad;
-+		struct sockaddr_in *addr = (struct sockaddr_in *)address;
-+		unsigned short snum = ntohs(addr->sin_port);
-+		struct sock *sk = sock->sk;
-+		u32 sid;
-+
-+		tsec = current->security;
-+		isec = SOCK_INODE(sock)->i_security;
-+
-+		if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) ||
-+			   snum > ip_local_port_range_1)) {
-+			err = security_port_sid(sk->sk_family, sk->sk_type,
-+						sk->sk_protocol, snum, &sid);
-+			if (err)
-+				return err;
-+			AVC_AUDIT_DATA_INIT(&ad,NET);
-+			ad.u.net.port = snum;
-+			err = avc_has_perm(isec->sid, sid,
-+					   isec->sclass,
-+					   SOCKET__NAME_BIND, NULL, &ad);
-+			if (err)
-+				return err;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
-+{
-+	int err;
-+	struct sock *sk = sock->sk;
-+	struct avc_audit_data ad;
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *isec;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	tsec = current->security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, NET);
-+	ad.u.net.sk = sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__CONNECT, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_listen(struct socket *sock, int backlog)
-+{
-+	int err;
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, NET);
-+	ad.u.net.sk = sock->sk;
-+
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__LISTEN, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
-+{
-+	int err;
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *isec;
-+	struct inode_security_struct *newisec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, NET);
-+	ad.u.net.sk = sock->sk;
-+
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__ACCEPT, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	err = inode_doinit(SOCK_INODE(newsock));
-+	if (err < 0)
-+		return err;
-+	newisec = SOCK_INODE(newsock)->i_security;
-+
-+	newisec->sclass = isec->sclass;
-+	newisec->sid = isec->sid;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
-+ 				  int size)
-+{
-+	struct task_security_struct *tsec;
-+	struct inode_security_struct *isec;
-+	struct avc_audit_data ad;
-+	struct sock *sk;
-+	int err;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	tsec = current->security;
-+
-+	sk = sock->sk;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, NET);
-+	ad.u.net.sk = sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__WRITE, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
-+				  int size, int flags)
-+{
-+	struct inode_security_struct *isec;
-+	struct task_security_struct *tsec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+	tsec = current->security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = sock->sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__READ, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_getsockname(struct socket *sock)
-+{
-+	struct inode_security_struct *isec;
-+	struct task_security_struct *tsec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	tsec = current->security;
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = sock->sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__GETATTR, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_getpeername(struct socket *sock)
-+{
-+	struct inode_security_struct *isec;
-+	struct task_security_struct *tsec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	tsec = current->security;
-+	isec = SOCK_INODE(sock)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = sock->sk;
-+	err = avc_has_perm(tsec->sid, isec->sid, isec->sclass,
-+			   SOCKET__GETATTR, &isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_setsockopt(struct socket *sock,int level,int optname)
-+{
-+	return socket_has_perm(current, sock, SOCKET__SETOPT);
-+}
-+
-+static int selinux_socket_getsockopt(struct socket *sock, int level,
-+				     int optname)
-+{
-+	return socket_has_perm(current, sock, SOCKET__GETOPT);
-+}
-+
-+static int selinux_socket_shutdown(struct socket *sock, int how)
-+{
-+	return socket_has_perm(current, sock, SOCKET__SHUTDOWN);
-+}
-+
-+static int selinux_socket_unix_stream_connect(struct socket *sock,
-+					      struct socket *other,
-+					      struct sock *newsk)
-+{
-+	struct inode_security_struct *isec;
-+	struct inode_security_struct *other_isec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+	other_isec = SOCK_INODE(other)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = other->sk;
-+
-+	err = avc_has_perm(isec->sid, other_isec->sid,
-+			   isec->sclass,
-+			   UNIX_STREAM_SOCKET__CONNECTTO,
-+			   &other_isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static int selinux_socket_unix_may_send(struct socket *sock,
-+					struct socket *other)
-+{
-+	struct inode_security_struct *isec;
-+	struct inode_security_struct *other_isec;
-+	struct avc_audit_data ad;
-+	int err;
-+
-+	isec = SOCK_INODE(sock)->i_security;
-+	other_isec = SOCK_INODE(other)->i_security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad,NET);
-+	ad.u.net.sk = other->sk;
-+
-+	err = avc_has_perm(isec->sid, other_isec->sid,
-+			   isec->sclass,
-+			   SOCKET__SENDTO,
-+			   &other_isec->avcr, &ad);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+#endif
-+
-+static int ipc_alloc_security(struct task_struct *task,
-+			      struct kern_ipc_perm *perm,
-+			      u16 sclass)
-+{
-+	struct task_security_struct *tsec = task->security;
-+	struct ipc_security_struct *isec;
-+
-+	isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
-+	if (!isec)
-+		return -ENOMEM;
-+
-+	memset(isec, 0, sizeof(struct ipc_security_struct));
-+	isec->magic = SELINUX_MAGIC;
-+	isec->sclass = sclass;
-+	isec->ipc_perm = perm;
-+	if (tsec) {
-+		isec->sid = tsec->sid;
-+	} else {
-+		isec->sid = SECINITSID_UNLABELED;
-+	}
-+	perm->security = isec;
-+
-+	return 0;
-+}
-+
-+static void ipc_free_security(struct kern_ipc_perm *perm)
-+{
-+	struct ipc_security_struct *isec = perm->security;
-+	if (!isec || isec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	perm->security = NULL;
-+	kfree(isec);
-+}
-+
-+static int msg_msg_alloc_security(struct msg_msg *msg)
-+{
-+	struct msg_security_struct *msec;
-+
-+	msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
-+	if (!msec)
-+		return -ENOMEM;
-+
-+	memset(msec, 0, sizeof(struct msg_security_struct));
-+	msec->magic = SELINUX_MAGIC;
-+	msec->msg = msg;
-+	msec->sid = SECINITSID_UNLABELED;
-+	msg->security = msec;
-+
-+	return 0;
-+}
-+
-+static void msg_msg_free_security(struct msg_msg *msg)
-+{
-+	struct msg_security_struct *msec = msg->security;
-+	if (!msec || msec->magic != SELINUX_MAGIC)
-+		return;
-+
-+	msg->security = NULL;
-+	kfree(msec);
-+}
-+
-+static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
-+			u16 sclass, u32 perms)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+	isec = ipc_perms->security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+	ad.u.ipc_id = ipc_perms->key;
-+
-+	return avc_has_perm(tsec->sid, isec->sid, sclass,
-+			    perms, &isec->avcr, &ad);
-+}
-+
-+static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
-+{
-+	return msg_msg_alloc_security(msg);
-+}
-+
-+static void selinux_msg_msg_free_security(struct msg_msg *msg)
-+{
-+	return msg_msg_free_security(msg);
-+}
-+
-+/* message queue security operations */
-+static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ);
-+	if (rc)
-+		return rc;
-+
-+	tsec = current->security;
-+	isec = msq->q_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+ 	ad.u.ipc_id = msq->q_perm.key;
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-+			  MSGQ__CREATE, &isec->avcr, &ad);
-+	if (rc) {
-+		ipc_free_security(&msq->q_perm);
-+		return rc;
-+	}
-+	return 0;
-+}
-+
-+static void selinux_msg_queue_free_security(struct msg_queue *msq)
-+{
-+	ipc_free_security(&msq->q_perm);
-+}
-+
-+static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+	isec = msq->q_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+	ad.u.ipc_id = msq->q_perm.key;
-+
-+	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-+			    MSGQ__ASSOCIATE, &isec->avcr, &ad);
-+}
-+
-+static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
-+{
-+	int err;
-+	int perms;
-+
-+	switch(cmd) {
-+	case IPC_INFO:
-+	case MSG_INFO:
-+		/* No specific object, just general system-wide information. */
-+		return task_has_system(current, SYSTEM__IPC_INFO);
-+	case IPC_STAT:
-+	case MSG_STAT:
-+		perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
-+		break;
-+	case IPC_SET:
-+		perms = MSGQ__SETATTR;
-+		break;
-+	case IPC_RMID:
-+		perms = MSGQ__DESTROY;
-+		break;
-+	default:
-+		return 0;
-+	}
-+
-+	err = ipc_has_perm(&msq->q_perm, SECCLASS_MSGQ, perms);
-+	return err;
-+}
-+
-+static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct msg_security_struct *msec;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	tsec = current->security;
-+	isec = msq->q_perm.security;
-+	msec = msg->security;
-+
-+	/*
-+	 * First time through, need to assign label to the message
-+	 */
-+	if (msec->sid == SECINITSID_UNLABELED) {
-+		/*
-+		 * Compute new sid based on current process and
-+		 * message queue this message will be stored in
-+		 */
-+		rc = security_transition_sid(tsec->sid,
-+					     isec->sid,
-+					     SECCLASS_MSG,
-+					     &msec->sid);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+	ad.u.ipc_id = msq->q_perm.key;
-+
-+	/* Can this process write to the queue? */
-+	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_MSGQ,
-+			  MSGQ__WRITE, &isec->avcr, &ad);
-+	if (!rc)
-+		/* Can this process send the message */
-+		rc = avc_has_perm(tsec->sid, msec->sid,
-+				  SECCLASS_MSG, MSG__SEND,
-+				  &msec->avcr, &ad);
-+	if (!rc)
-+		/* Can the message be put in the queue? */
-+		rc = avc_has_perm(msec->sid, isec->sid,
-+				  SECCLASS_MSGQ, MSGQ__ENQUEUE,
-+				  &isec->avcr, &ad);
-+
-+	return rc;
-+}
-+
-+static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
-+				    struct task_struct *target,
-+				    long type, int mode)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct msg_security_struct *msec;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	tsec = target->security;
-+	isec = msq->q_perm.security;
-+	msec = msg->security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+ 	ad.u.ipc_id = msq->q_perm.key;
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid,
-+			  SECCLASS_MSGQ, MSGQ__READ,
-+			  &isec->avcr, &ad);
-+	if (!rc)
-+		rc = avc_has_perm(tsec->sid, msec->sid,
-+				  SECCLASS_MSG, MSG__RECEIVE,
-+				  &msec->avcr, &ad);
-+	return rc;
-+}
-+
-+/* Shared Memory security operations */
-+static int selinux_shm_alloc_security(struct shmid_kernel *shp)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM);
-+	if (rc)
-+		return rc;
-+
-+	tsec = current->security;
-+	isec = shp->shm_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+ 	ad.u.ipc_id = shp->shm_perm.key;
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
-+			  SHM__CREATE, &isec->avcr, &ad);
-+	if (rc) {
-+		ipc_free_security(&shp->shm_perm);
-+		return rc;
-+	}
-+	return 0;
-+}
-+
-+static void selinux_shm_free_security(struct shmid_kernel *shp)
-+{
-+	ipc_free_security(&shp->shm_perm);
-+}
-+
-+static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+	isec = shp->shm_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+	ad.u.ipc_id = shp->shm_perm.key;
-+
-+	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SHM,
-+			    SHM__ASSOCIATE, &isec->avcr, &ad);
-+}
-+
-+/* Note, at this point, shp is locked down */
-+static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
-+{
-+	int perms;
-+	int err;
-+
-+	switch(cmd) {
-+	case IPC_INFO:
-+	case SHM_INFO:
-+		/* No specific object, just general system-wide information. */
-+		return task_has_system(current, SYSTEM__IPC_INFO);
-+	case IPC_STAT:
-+	case SHM_STAT:
-+		perms = SHM__GETATTR | SHM__ASSOCIATE;
-+		break;
-+	case IPC_SET:
-+		perms = SHM__SETATTR;
-+		break;
-+	case SHM_LOCK:
-+	case SHM_UNLOCK:
-+		perms = SHM__LOCK;
-+		break;
-+	case IPC_RMID:
-+		perms = SHM__DESTROY;
-+		break;
-+	default:
-+		return 0;
-+	}
-+
-+	err = ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms);
-+	return err;
-+}
-+
-+static int selinux_shm_shmat(struct shmid_kernel *shp,
-+			     char *shmaddr, int shmflg)
-+{
-+	u32 perms;
-+
-+	if (shmflg & SHM_RDONLY)
-+		perms = SHM__READ;
-+	else
-+		perms = SHM__READ | SHM__WRITE;
-+
-+	return ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms);
-+}
-+
-+/* Semaphore security operations */
-+static int selinux_sem_alloc_security(struct sem_array *sma)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+	int rc;
-+
-+	rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM);
-+	if (rc)
-+		return rc;
-+
-+	tsec = current->security;
-+	isec = sma->sem_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+ 	ad.u.ipc_id = sma->sem_perm.key;
-+
-+	rc = avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
-+			  SEM__CREATE, &isec->avcr, &ad);
-+	if (rc) {
-+		ipc_free_security(&sma->sem_perm);
-+		return rc;
-+	}
-+	return 0;
-+}
-+
-+static void selinux_sem_free_security(struct sem_array *sma)
-+{
-+	ipc_free_security(&sma->sem_perm);
-+}
-+
-+static int selinux_sem_associate(struct sem_array *sma, int semflg)
-+{
-+	struct task_security_struct *tsec;
-+	struct ipc_security_struct *isec;
-+	struct avc_audit_data ad;
-+
-+	tsec = current->security;
-+	isec = sma->sem_perm.security;
-+
-+	AVC_AUDIT_DATA_INIT(&ad, IPC);
-+	ad.u.ipc_id = sma->sem_perm.key;
-+
-+	return avc_has_perm(tsec->sid, isec->sid, SECCLASS_SEM,
-+			    SEM__ASSOCIATE, &isec->avcr, &ad);
-+}
-+
-+/* Note, at this point, sma is locked down */
-+static int selinux_sem_semctl(struct sem_array *sma, int cmd)
-+{
-+	int err;
-+	u32 perms;
-+
-+	switch(cmd) {
-+	case IPC_INFO:
-+	case SEM_INFO:
-+		/* No specific object, just general system-wide information. */
-+		return task_has_system(current, SYSTEM__IPC_INFO);
-+	case GETPID:
-+	case GETNCNT:
-+	case GETZCNT:
-+		perms = SEM__GETATTR;
-+		break;
-+	case GETVAL:
-+	case GETALL:
-+		perms = SEM__READ;
-+		break;
-+	case SETVAL:
-+	case SETALL:
-+		perms = SEM__WRITE;
-+		break;
-+	case IPC_RMID:
-+		perms = SEM__DESTROY;
-+		break;
-+	case IPC_SET:
-+		perms = SEM__SETATTR;
-+		break;
-+	case IPC_STAT:
-+	case SEM_STAT:
-+		perms = SEM__GETATTR | SEM__ASSOCIATE;
-+		break;
-+	default:
-+		return 0;
-+	}
-+
-+	err = ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms);
-+	return err;
-+}
-+
-+static int selinux_sem_semop(struct sem_array *sma,
-+			     struct sembuf *sops, unsigned nsops, int alter)
-+{
-+	u32 perms;
-+
-+	if (alter)
-+		perms = SEM__READ | SEM__WRITE;
-+	else
-+		perms = SEM__READ;
-+
-+	return ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms);
-+}
-+
-+static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
-+{
-+	struct ipc_security_struct *isec = ipcp->security;
-+	u16 sclass = SECCLASS_IPC;
-+	u32 av = 0;
-+
-+	if (isec && isec->magic == SELINUX_MAGIC)
-+		sclass = isec->sclass;
-+
-+	av = 0;
-+	if (flag & S_IRUGO)
-+		av |= IPC__UNIX_READ;
-+	if (flag & S_IWUGO)
-+		av |= IPC__UNIX_WRITE;
-+
-+	if (av == 0)
-+		return 0;
-+
-+	return ipc_has_perm(ipcp, sclass, av);
-+}
-+
-+/* module stacking operations */
-+int selinux_register_security (const char *name, struct security_operations *ops)
-+{
-+	if (secondary_ops != original_ops) {
-+		printk(KERN_INFO "%s:  There is already a secondary security "
-+		       "module registered.\n", __FUNCTION__);
-+		return -EINVAL;
-+ 	}
-+
-+	secondary_ops = ops;
-+
-+	printk(KERN_INFO "%s:  Registering secondary module %s\n",
-+	       __FUNCTION__,
-+	       name);
-+
-+	return 0;
-+}
-+
-+int selinux_unregister_security (const char *name, struct security_operations *ops)
-+{
-+	if (ops != secondary_ops) {
-+		printk (KERN_INFO "%s:  trying to unregister a security module "
-+		        "that is not registered.\n", __FUNCTION__);
-+		return -EINVAL;
-+	}
-+
-+	secondary_ops = original_ops;
-+
-+	return 0;
-+}
-+
-+static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode)
-+{
-+	if (inode)
-+		inode_doinit_with_dentry(inode, dentry);
-+}
-+
-+static int selinux_getprocattr(struct task_struct *p,
-+			       char *name, void *value, size_t size)
-+{
-+	struct task_security_struct *tsec;
-+	u32 sid;
-+	char *context;
-+	size_t len;
-+	int error;
-+
-+	if (current != p) {
-+		error = task_has_perm(current, p, PROCESS__GETATTR);
-+		if (error)
-+			return error;
-+	}
-+
-+	if (!size)
-+		return -ERANGE;
-+
-+	tsec = p->security;
-+
-+	if (!strcmp(name, "current"))
-+		sid = tsec->sid;
-+	else if (!strcmp(name, "prev"))
-+		sid = tsec->osid;
-+	else if (!strcmp(name, "exec"))
-+		sid = tsec->exec_sid;
-+	else if (!strcmp(name, "fscreate"))
-+		sid = tsec->create_sid;
-+	else
-+		return -EINVAL;
-+
-+	if (!sid)
-+		return 0;
-+
-+	error = security_sid_to_context(sid, &context, &len);
-+	if (error)
-+		return error;
-+	if (len > size) {
-+		kfree(context);
-+		return -ERANGE;
-+	}
-+	memcpy(value, context, len);
-+	kfree(context);
-+	return len;
-+}
-+
-+static int selinux_setprocattr(struct task_struct *p,
-+			       char *name, void *value, size_t size)
-+{
-+	struct task_security_struct *tsec;
-+	u32 sid = 0;
-+	int error;
-+
-+	if (current != p || !strcmp(name, "current")) {
-+		/* SELinux only allows a process to change its own
-+		   security attributes, and it only allows the process
-+		   current SID to change via exec. */
-+		return -EACCES;
-+	}
-+
-+	/*
-+	 * Basic control over ability to set these attributes at all.
-+	 * current == p, but we'll pass them separately in case the
-+	 * above restriction is ever removed.
-+	 */
-+	if (!strcmp(name, "exec"))
-+		error = task_has_perm(current, p, PROCESS__SETEXEC);
-+	else if (!strcmp(name, "fscreate"))
-+		error = task_has_perm(current, p, PROCESS__SETFSCREATE);
-+	else
-+		error = -EINVAL;
-+	if (error)
-+		return error;
-+
-+	/* Obtain a SID for the context, if one was specified. */
-+	if (size) {
-+		int error;
-+		error = security_context_to_sid(value, size, &sid);
-+		if (error)
-+			return error;
-+	}
-+
-+	/* Permission checking based on the specified context is
-+	   performed during the actual operation (execve,
-+	   open/mkdir/...), when we know the full context of the
-+	   operation.  See selinux_bprm_set_security for the execve
-+	   checks and may_create for the file creation checks. The
-+	   operation will then fail if the context is not permitted. */
-+	tsec = p->security;
-+	if (!strcmp(name, "exec"))
-+		tsec->exec_sid = sid;
-+	else if (!strcmp(name, "fscreate"))
-+		tsec->create_sid = sid;
-+	else
-+		return -EINVAL;
-+
-+	return size;
-+}
-+
-+struct security_operations selinux_ops = {
-+	.ptrace =			selinux_ptrace,
-+	.capget =			selinux_capget,
-+	.capset_check =			selinux_capset_check,
-+	.capset_set =			selinux_capset_set,
-+	.sysctl =			selinux_sysctl,
-+	.capable =			selinux_capable,
-+	.quotactl =			selinux_quotactl,
-+	.quota_on =			selinux_quota_on,
-+	.syslog =			selinux_syslog,
-+	.vm_enough_memory =		selinux_vm_enough_memory,
-+
-+	.netlink_send =			selinux_netlink_send,
-+        .netlink_recv =			selinux_netlink_recv,
-+
-+	.bprm_alloc_security =		selinux_bprm_alloc_security,
-+	.bprm_free_security =		selinux_bprm_free_security,
-+	.bprm_compute_creds =		selinux_bprm_compute_creds,
-+	.bprm_set_security =		selinux_bprm_set_security,
-+	.bprm_check_security =		selinux_bprm_check_security,
-+	.bprm_secureexec =		selinux_bprm_secureexec,
-+
-+	.sb_alloc_security =		selinux_sb_alloc_security,
-+	.sb_free_security =		selinux_sb_free_security,
-+	.sb_kern_mount =	        selinux_sb_kern_mount,
-+	.sb_statfs =			selinux_sb_statfs,
-+	.sb_mount =			selinux_mount,
-+	.sb_umount =			selinux_umount,
-+
-+	.inode_alloc_security =		selinux_inode_alloc_security,
-+	.inode_free_security =		selinux_inode_free_security,
-+	.inode_create =			selinux_inode_create,
-+	.inode_post_create =		selinux_inode_post_create,
-+	.inode_link =			selinux_inode_link,
-+	.inode_post_link =		selinux_inode_post_link,
-+	.inode_unlink =			selinux_inode_unlink,
-+	.inode_symlink =		selinux_inode_symlink,
-+	.inode_post_symlink =		selinux_inode_post_symlink,
-+	.inode_mkdir =			selinux_inode_mkdir,
-+	.inode_post_mkdir =		selinux_inode_post_mkdir,
-+	.inode_rmdir =			selinux_inode_rmdir,
-+	.inode_mknod =			selinux_inode_mknod,
-+	.inode_post_mknod =		selinux_inode_post_mknod,
-+	.inode_rename =			selinux_inode_rename,
-+	.inode_post_rename =		selinux_inode_post_rename,
-+	.inode_readlink =		selinux_inode_readlink,
-+	.inode_follow_link =		selinux_inode_follow_link,
-+	.inode_permission =		selinux_inode_permission,
-+	.inode_setattr =		selinux_inode_setattr,
-+	.inode_getattr =		selinux_inode_getattr,
-+	.inode_setxattr =		selinux_inode_setxattr,
-+	.inode_post_setxattr =		selinux_inode_post_setxattr,
-+	.inode_getxattr =		selinux_inode_getxattr,
-+	.inode_listxattr =		selinux_inode_listxattr,
-+	.inode_removexattr =		selinux_inode_removexattr,
-+	.inode_getsecurity =            selinux_inode_getsecurity,
-+	.inode_setsecurity =            selinux_inode_setsecurity,
-+	.inode_listsecurity =           selinux_inode_listsecurity,
-+
-+	.file_permission =		selinux_file_permission,
-+	.file_alloc_security =		selinux_file_alloc_security,
-+	.file_free_security =		selinux_file_free_security,
-+	.file_ioctl =			selinux_file_ioctl,
-+	.file_mmap =			selinux_file_mmap,
-+	.file_mprotect =		selinux_file_mprotect,
-+	.file_lock =			selinux_file_lock,
-+	.file_fcntl =			selinux_file_fcntl,
-+	.file_set_fowner =		selinux_file_set_fowner,
-+	.file_send_sigiotask =		selinux_file_send_sigiotask,
-+	.file_receive =			selinux_file_receive,
-+
-+	.task_create =			selinux_task_create,
-+	.task_alloc_security =		selinux_task_alloc_security,
-+	.task_free_security =		selinux_task_free_security,
-+	.task_setuid =			selinux_task_setuid,
-+	.task_post_setuid =		selinux_task_post_setuid,
-+	.task_setgid =			selinux_task_setgid,
-+	.task_setpgid =			selinux_task_setpgid,
-+	.task_getpgid =			selinux_task_getpgid,
-+	.task_getsid =		        selinux_task_getsid,
-+	.task_setgroups =		selinux_task_setgroups,
-+	.task_setnice =			selinux_task_setnice,
-+	.task_setrlimit =		selinux_task_setrlimit,
-+	.task_setscheduler =		selinux_task_setscheduler,
-+	.task_getscheduler =		selinux_task_getscheduler,
-+	.task_kill =			selinux_task_kill,
-+	.task_wait =			selinux_task_wait,
-+	.task_prctl =			selinux_task_prctl,
-+	.task_reparent_to_init =	selinux_task_reparent_to_init,
-+	.task_to_inode =                selinux_task_to_inode,
-+
-+	.ipc_permission =		selinux_ipc_permission,
-+
-+	.msg_msg_alloc_security =	selinux_msg_msg_alloc_security,
-+	.msg_msg_free_security =	selinux_msg_msg_free_security,
-+
-+	.msg_queue_alloc_security =	selinux_msg_queue_alloc_security,
-+	.msg_queue_free_security =	selinux_msg_queue_free_security,
-+	.msg_queue_associate =		selinux_msg_queue_associate,
-+	.msg_queue_msgctl =		selinux_msg_queue_msgctl,
-+	.msg_queue_msgsnd =		selinux_msg_queue_msgsnd,
-+	.msg_queue_msgrcv =		selinux_msg_queue_msgrcv,
-+
-+	.shm_alloc_security =		selinux_shm_alloc_security,
-+	.shm_free_security =		selinux_shm_free_security,
-+	.shm_associate =		selinux_shm_associate,
-+	.shm_shmctl =			selinux_shm_shmctl,
-+	.shm_shmat =			selinux_shm_shmat,
-+
-+	.sem_alloc_security = 		selinux_sem_alloc_security,
-+	.sem_free_security =  		selinux_sem_free_security,
-+	.sem_associate =		selinux_sem_associate,
-+	.sem_semctl =			selinux_sem_semctl,
-+	.sem_semop =			selinux_sem_semop,
-+
-+	.register_security =		selinux_register_security,
-+	.unregister_security =		selinux_unregister_security,
-+
-+	.d_instantiate =                selinux_d_instantiate,
-+
-+	.getprocattr =                  selinux_getprocattr,
-+	.setprocattr =                  selinux_setprocattr,
-+
-+#ifdef CONFIG_SECURITY_NETWORK
-+        .unix_stream_connect =		selinux_socket_unix_stream_connect,
-+	.unix_may_send =		selinux_socket_unix_may_send,
-+
-+	.socket_create =		selinux_socket_create,
-+	.socket_post_create =		selinux_socket_post_create,
-+	.socket_bind =			selinux_socket_bind,
-+	.socket_connect =		selinux_socket_connect,
-+	.socket_listen =		selinux_socket_listen,
-+	.socket_accept =		selinux_socket_accept,
-+	.socket_sendmsg =		selinux_socket_sendmsg,
-+	.socket_recvmsg =		selinux_socket_recvmsg,
-+	.socket_getsockname =		selinux_socket_getsockname,
-+	.socket_getpeername =		selinux_socket_getpeername,
-+	.socket_getsockopt =		selinux_socket_getsockopt,
-+	.socket_setsockopt =		selinux_socket_setsockopt,
-+	.socket_shutdown =		selinux_socket_shutdown,
-+#endif
-+};
-+
-+__init int selinux_init(void)
-+{
-+	struct task_security_struct *tsec;
-+
-+	printk(KERN_INFO "SELinux:  Initializing.\n");
-+
-+	/* Set the security state for the initial task. */
-+	if (task_alloc_security(current))
-+		panic("SELinux:  Failed to initialize initial task.\n");
-+	tsec = current->security;
-+	tsec->osid = tsec->sid = SECINITSID_KERNEL;
-+
-+	avc_init();
-+
-+	original_ops = secondary_ops = security_ops;
-+	if (!secondary_ops)
-+		panic ("SELinux: No initial security operations\n");
-+	if (register_security (&selinux_ops))
-+		panic("SELinux: Unable to register with kernel.\n");
-+
-+	if (selinux_enforcing) {
-+		printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
-+	} else {
-+		printk(KERN_INFO "SELinux:  Starting in permissive mode\n");
-+	}
-+	return 0;
-+}
-+
-+void selinux_complete_init(void)
-+{
-+	printk(KERN_INFO "SELinux:  Completing initialization.\n");
-+
-+	/* Set up any superblocks initialized prior to the policy load. */
-+	printk(KERN_INFO "SELinux:  Setting up existing superblocks.\n");
-+	spin_lock(&sb_security_lock);
-+next_sb:
-+	if (!list_empty(&superblock_security_head)) {
-+		struct superblock_security_struct *sbsec =
-+				list_entry(superblock_security_head.next,
-+				           struct superblock_security_struct,
-+				           list);
-+		struct super_block *sb = sbsec->sb;
-+		spin_lock(&sb_lock);
-+		sb->s_count++;
-+		spin_unlock(&sb_lock);
-+		spin_unlock(&sb_security_lock);
-+		down_read(&sb->s_umount);
-+		if (sb->s_root)
-+			superblock_doinit(sb);
-+		drop_super(sb);
-+		spin_lock(&sb_security_lock);
-+		list_del_init(&sbsec->list);
-+		goto next_sb;
-+	}
-+	spin_unlock(&sb_security_lock);
-+
-+	/* Set up any inodes initialized prior to the policy load. */
-+	printk(KERN_INFO "SELinux:  Setting up existing inodes.\n");
-+	spin_lock(&inode_security_lock);
-+next_inode:
-+	if (!list_empty(&inode_security_head)) {
-+		struct inode_security_struct *isec =
-+				list_entry(inode_security_head.next,
-+				           struct inode_security_struct, list);
-+		struct inode *inode = isec->inode;
-+		spin_unlock(&inode_security_lock);
-+		inode = igrab(inode);
-+		if (inode) {
-+			inode_doinit(inode);
-+			iput(inode);
-+		}
-+		spin_lock(&inode_security_lock);
-+		list_del_init(&isec->list);
-+		goto next_inode;
-+	}
-+	spin_unlock(&inode_security_lock);
-+}
-+
-+/* SELinux requires early initialization in order to label
-+   all processes and objects when they are created. */
-+security_initcall(selinux_init);
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/avc.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,159 @@
-+/*
-+ * Access vector cache interface for object managers.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SELINUX_AVC_H_
-+#define _SELINUX_AVC_H_
-+
-+#include <linux/stddef.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/kdev_t.h>
-+#include <linux/spinlock.h>
-+#include <asm/system.h>
-+#include "flask.h"
-+#include "av_permissions.h"
-+#include "security.h"
-+
-+#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-+extern int selinux_enforcing;
-+#else
-+#define selinux_enforcing 1
-+#endif
-+
-+/*
-+ * An entry in the AVC.
-+ */
-+struct avc_entry;
-+
-+/*
-+ * A reference to an AVC entry.
-+ */
-+struct avc_entry_ref {
-+	struct avc_entry *ae;
-+};
-+
-+/* Initialize an AVC entry reference before first use. */
-+static inline void avc_entry_ref_init(struct avc_entry_ref *h)
-+{
-+	h->ae = NULL;
-+}
-+
-+struct task_struct;
-+struct vfsmount;
-+struct dentry;
-+struct inode;
-+struct sock;
-+struct sk_buff;
-+
-+/* Auxiliary data to use in generating the audit record. */
-+struct avc_audit_data {
-+	char    type;
-+#define AVC_AUDIT_DATA_FS   1
-+#define AVC_AUDIT_DATA_NET  2
-+#define AVC_AUDIT_DATA_CAP  3
-+#define AVC_AUDIT_DATA_IPC  4
-+	struct task_struct *tsk;
-+	union 	{
-+		struct {
-+			struct vfsmount *mnt;
-+			struct dentry *dentry;
-+			struct inode *inode;
-+		} fs;
-+		struct {
-+			char *netif;
-+			struct sk_buff *skb;
-+			struct sock *sk;
-+			u16 port;
-+			u32 daddr;
-+		} net;
-+		int cap;
-+		int ipc_id;
-+	} u;
-+};
-+
-+/* Initialize an AVC audit data structure. */
-+#define AVC_AUDIT_DATA_INIT(_d,_t) \
-+        { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; }
-+
-+/*
-+ * AVC statistics
-+ */
-+#define AVC_ENTRY_LOOKUPS        0
-+#define AVC_ENTRY_HITS	         1
-+#define AVC_ENTRY_MISSES         2
-+#define AVC_ENTRY_DISCARDS       3
-+#define AVC_CAV_LOOKUPS          4
-+#define AVC_CAV_HITS             5
-+#define AVC_CAV_PROBES           6
-+#define AVC_CAV_MISSES           7
-+#define AVC_NSTATS               8
-+extern unsigned avc_cache_stats[AVC_NSTATS];
-+
-+#ifdef AVC_CACHE_STATS
-+static inline void avc_cache_stats_incr(int type)
-+{
-+	avc_cache_stats[type]++;
-+}
-+
-+static inline void avc_cache_stats_add(int type, unsigned val)
-+{
-+	avc_cache_stats[type] += val;
-+}
-+#else
-+static inline void avc_cache_stats_incr(int type)
-+{ }
-+
-+static inline void avc_cache_stats_add(int type, unsigned val)
-+{ }
-+#endif
-+
-+/*
-+ * AVC display support
-+ */
-+void avc_dump_av(u16 tclass, u32 av);
-+void avc_dump_query(u32 ssid, u32 tsid, u16 tclass);
-+void avc_dump_cache(char *tag);
-+
-+/*
-+ * AVC operations
-+ */
-+
-+void avc_init(void);
-+
-+int avc_lookup(u32 ssid, u32 tsid, u16 tclass,
-+               u32 requested, struct avc_entry_ref *aeref);
-+
-+int avc_insert(u32 ssid, u32 tsid, u16 tclass,
-+               struct avc_entry *ae, struct avc_entry_ref *out_aeref);
-+
-+void avc_audit(u32 ssid, u32 tsid,
-+               u16 tclass, u32 requested,
-+               struct av_decision *avd, int result, struct avc_audit_data *auditdata);
-+
-+int avc_has_perm_noaudit(u32 ssid, u32 tsid,
-+                         u16 tclass, u32 requested,
-+                         struct avc_entry_ref *aeref, struct av_decision *avd);
-+
-+int avc_has_perm(u32 ssid, u32 tsid,
-+                 u16 tclass, u32 requested,
-+                 struct avc_entry_ref *aeref, struct avc_audit_data *auditdata);
-+
-+#define AVC_CALLBACK_GRANT		1
-+#define AVC_CALLBACK_TRY_REVOKE		2
-+#define AVC_CALLBACK_REVOKE		4
-+#define AVC_CALLBACK_RESET		8
-+#define AVC_CALLBACK_AUDITALLOW_ENABLE	16
-+#define AVC_CALLBACK_AUDITALLOW_DISABLE	32
-+#define AVC_CALLBACK_AUDITDENY_ENABLE	64
-+#define AVC_CALLBACK_AUDITDENY_DISABLE	128
-+
-+int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
-+                                     u16 tclass, u32 perms,
-+				     u32 *out_retained),
-+		     u32 events, u32 ssid, u32 tsid,
-+		     u16 tclass, u32 perms);
-+
-+#endif /* _SELINUX_AVC_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/avc_ss.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,27 @@
-+/*
-+ * Access vector cache interface for the security server.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SELINUX_AVC_SS_H_
-+#define _SELINUX_AVC_SS_H_
-+
-+#include "flask.h"
-+
-+int avc_ss_grant(u32 ssid, u32 tsid, u16 tclass, u32 perms, u32 seqno);
-+
-+int avc_ss_try_revoke(u32 ssid, u32 tsid, u16 tclass, u32 perms, u32 seqno,
-+		      u32 *out_retained);
-+
-+int avc_ss_revoke(u32 ssid, u32 tsid, u16 tclass, u32 perms, u32 seqno);
-+
-+int avc_ss_reset(u32 seqno);
-+
-+int avc_ss_set_auditallow(u32 ssid, u32 tsid, u16 tclass, u32 perms,
-+			  u32 seqno, u32 enable);
-+
-+int avc_ss_set_auditdeny(u32 ssid, u32 tsid, u16 tclass, u32 perms,
-+			 u32 seqno, u32 enable);
-+
-+#endif /* _SELINUX_AVC_SS_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/av_inherit.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,35 @@
-+/* This file is automatically generated.  Do not edit. */
-+/* FLASK */
-+
-+struct av_inherit
-+{
-+    u16 tclass;
-+    char **common_pts;
-+    u32 common_base;
-+};
-+
-+static struct av_inherit av_inherit[] = {
-+   { SECCLASS_DIR, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_LNK_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_CHR_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_BLK_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_SOCK_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_FIFO_FILE, common_file_perm_to_string, 0x00020000UL },
-+   { SECCLASS_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_TCP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_UDP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_RAWIP_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_NETLINK_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_PACKET_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_KEY_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_UNIX_STREAM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_UNIX_DGRAM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
-+   { SECCLASS_IPC, common_ipc_perm_to_string, 0x00000200UL },
-+   { SECCLASS_SEM, common_ipc_perm_to_string, 0x00000200UL },
-+   { SECCLASS_MSGQ, common_ipc_perm_to_string, 0x00000200UL },
-+   { SECCLASS_SHM, common_ipc_perm_to_string, 0x00000200UL },
-+};
-+
-+
-+/* FLASK */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/av_permissions.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,550 @@
-+/* This file is automatically generated.  Do not edit. */
-+/* FLASK */
-+
-+#define COMMON_FILE__IOCTL                               0x00000001UL
-+#define COMMON_FILE__READ                                0x00000002UL
-+#define COMMON_FILE__WRITE                               0x00000004UL
-+#define COMMON_FILE__CREATE                              0x00000008UL
-+#define COMMON_FILE__GETATTR                             0x00000010UL
-+#define COMMON_FILE__SETATTR                             0x00000020UL
-+#define COMMON_FILE__LOCK                                0x00000040UL
-+#define COMMON_FILE__RELABELFROM                         0x00000080UL
-+#define COMMON_FILE__RELABELTO                           0x00000100UL
-+#define COMMON_FILE__APPEND                              0x00000200UL
-+#define COMMON_FILE__UNLINK                              0x00000400UL
-+#define COMMON_FILE__LINK                                0x00000800UL
-+#define COMMON_FILE__RENAME                              0x00001000UL
-+#define COMMON_FILE__EXECUTE                             0x00002000UL
-+#define COMMON_FILE__SWAPON                              0x00004000UL
-+#define COMMON_FILE__QUOTAON                             0x00008000UL
-+#define COMMON_FILE__MOUNTON                             0x00010000UL
-+
-+#define COMMON_SOCKET__IOCTL                             0x00000001UL
-+#define COMMON_SOCKET__READ                              0x00000002UL
-+#define COMMON_SOCKET__WRITE                             0x00000004UL
-+#define COMMON_SOCKET__CREATE                            0x00000008UL
-+#define COMMON_SOCKET__GETATTR                           0x00000010UL
-+#define COMMON_SOCKET__SETATTR                           0x00000020UL
-+#define COMMON_SOCKET__LOCK                              0x00000040UL
-+#define COMMON_SOCKET__RELABELFROM                       0x00000080UL
-+#define COMMON_SOCKET__RELABELTO                         0x00000100UL
-+#define COMMON_SOCKET__APPEND                            0x00000200UL
-+#define COMMON_SOCKET__BIND                              0x00000400UL
-+#define COMMON_SOCKET__CONNECT                           0x00000800UL
-+#define COMMON_SOCKET__LISTEN                            0x00001000UL
-+#define COMMON_SOCKET__ACCEPT                            0x00002000UL
-+#define COMMON_SOCKET__GETOPT                            0x00004000UL
-+#define COMMON_SOCKET__SETOPT                            0x00008000UL
-+#define COMMON_SOCKET__SHUTDOWN                          0x00010000UL
-+#define COMMON_SOCKET__RECVFROM                          0x00020000UL
-+#define COMMON_SOCKET__SENDTO                            0x00040000UL
-+#define COMMON_SOCKET__RECV_MSG                          0x00080000UL
-+#define COMMON_SOCKET__SEND_MSG                          0x00100000UL
-+#define COMMON_SOCKET__NAME_BIND                         0x00200000UL
-+
-+#define COMMON_IPC__CREATE                               0x00000001UL
-+#define COMMON_IPC__DESTROY                              0x00000002UL
-+#define COMMON_IPC__GETATTR                              0x00000004UL
-+#define COMMON_IPC__SETATTR                              0x00000008UL
-+#define COMMON_IPC__READ                                 0x00000010UL
-+#define COMMON_IPC__WRITE                                0x00000020UL
-+#define COMMON_IPC__ASSOCIATE                            0x00000040UL
-+#define COMMON_IPC__UNIX_READ                            0x00000080UL
-+#define COMMON_IPC__UNIX_WRITE                           0x00000100UL
-+
-+#define FILESYSTEM__MOUNT                         0x00000001UL
-+#define FILESYSTEM__REMOUNT                       0x00000002UL
-+#define FILESYSTEM__UNMOUNT                       0x00000004UL
-+#define FILESYSTEM__GETATTR                       0x00000008UL
-+#define FILESYSTEM__RELABELFROM                   0x00000010UL
-+#define FILESYSTEM__RELABELTO                     0x00000020UL
-+#define FILESYSTEM__TRANSITION                    0x00000040UL
-+#define FILESYSTEM__ASSOCIATE                     0x00000080UL
-+#define FILESYSTEM__QUOTAMOD                      0x00000100UL
-+#define FILESYSTEM__QUOTAGET                      0x00000200UL
-+
-+#define DIR__EXECUTE                              0x00002000UL
-+#define DIR__UNLINK                               0x00000400UL
-+#define DIR__SETATTR                              0x00000020UL
-+#define DIR__QUOTAON                              0x00008000UL
-+#define DIR__RELABELFROM                          0x00000080UL
-+#define DIR__LINK                                 0x00000800UL
-+#define DIR__WRITE                                0x00000004UL
-+#define DIR__IOCTL                                0x00000001UL
-+#define DIR__RELABELTO                            0x00000100UL
-+#define DIR__READ                                 0x00000002UL
-+#define DIR__RENAME                               0x00001000UL
-+#define DIR__APPEND                               0x00000200UL
-+#define DIR__LOCK                                 0x00000040UL
-+#define DIR__SWAPON                               0x00004000UL
-+#define DIR__GETATTR                              0x00000010UL
-+#define DIR__MOUNTON                              0x00010000UL
-+#define DIR__CREATE                               0x00000008UL
-+
-+#define DIR__ADD_NAME                             0x00020000UL
-+#define DIR__REMOVE_NAME                          0x00040000UL
-+#define DIR__REPARENT                             0x00080000UL
-+#define DIR__SEARCH                               0x00100000UL
-+#define DIR__RMDIR                                0x00200000UL
-+
-+#define FILE__EXECUTE                             0x00002000UL
-+#define FILE__UNLINK                              0x00000400UL
-+#define FILE__SETATTR                             0x00000020UL
-+#define FILE__QUOTAON                             0x00008000UL
-+#define FILE__RELABELFROM                         0x00000080UL
-+#define FILE__LINK                                0x00000800UL
-+#define FILE__WRITE                               0x00000004UL
-+#define FILE__IOCTL                               0x00000001UL
-+#define FILE__RELABELTO                           0x00000100UL
-+#define FILE__READ                                0x00000002UL
-+#define FILE__RENAME                              0x00001000UL
-+#define FILE__APPEND                              0x00000200UL
-+#define FILE__LOCK                                0x00000040UL
-+#define FILE__SWAPON                              0x00004000UL
-+#define FILE__GETATTR                             0x00000010UL
-+#define FILE__MOUNTON                             0x00010000UL
-+#define FILE__CREATE                              0x00000008UL
-+
-+#define FILE__EXECUTE_NO_TRANS                    0x00020000UL
-+#define FILE__ENTRYPOINT                          0x00040000UL
-+
-+#define LNK_FILE__EXECUTE                         0x00002000UL
-+#define LNK_FILE__UNLINK                          0x00000400UL
-+#define LNK_FILE__SETATTR                         0x00000020UL
-+#define LNK_FILE__QUOTAON                         0x00008000UL
-+#define LNK_FILE__RELABELFROM                     0x00000080UL
-+#define LNK_FILE__LINK                            0x00000800UL
-+#define LNK_FILE__WRITE                           0x00000004UL
-+#define LNK_FILE__IOCTL                           0x00000001UL
-+#define LNK_FILE__RELABELTO                       0x00000100UL
-+#define LNK_FILE__READ                            0x00000002UL
-+#define LNK_FILE__RENAME                          0x00001000UL
-+#define LNK_FILE__APPEND                          0x00000200UL
-+#define LNK_FILE__LOCK                            0x00000040UL
-+#define LNK_FILE__SWAPON                          0x00004000UL
-+#define LNK_FILE__GETATTR                         0x00000010UL
-+#define LNK_FILE__MOUNTON                         0x00010000UL
-+#define LNK_FILE__CREATE                          0x00000008UL
-+
-+#define CHR_FILE__EXECUTE                         0x00002000UL
-+#define CHR_FILE__UNLINK                          0x00000400UL
-+#define CHR_FILE__SETATTR                         0x00000020UL
-+#define CHR_FILE__QUOTAON                         0x00008000UL
-+#define CHR_FILE__RELABELFROM                     0x00000080UL
-+#define CHR_FILE__LINK                            0x00000800UL
-+#define CHR_FILE__WRITE                           0x00000004UL
-+#define CHR_FILE__IOCTL                           0x00000001UL
-+#define CHR_FILE__RELABELTO                       0x00000100UL
-+#define CHR_FILE__READ                            0x00000002UL
-+#define CHR_FILE__RENAME                          0x00001000UL
-+#define CHR_FILE__APPEND                          0x00000200UL
-+#define CHR_FILE__LOCK                            0x00000040UL
-+#define CHR_FILE__SWAPON                          0x00004000UL
-+#define CHR_FILE__GETATTR                         0x00000010UL
-+#define CHR_FILE__MOUNTON                         0x00010000UL
-+#define CHR_FILE__CREATE                          0x00000008UL
-+
-+#define BLK_FILE__EXECUTE                         0x00002000UL
-+#define BLK_FILE__UNLINK                          0x00000400UL
-+#define BLK_FILE__SETATTR                         0x00000020UL
-+#define BLK_FILE__QUOTAON                         0x00008000UL
-+#define BLK_FILE__RELABELFROM                     0x00000080UL
-+#define BLK_FILE__LINK                            0x00000800UL
-+#define BLK_FILE__WRITE                           0x00000004UL
-+#define BLK_FILE__IOCTL                           0x00000001UL
-+#define BLK_FILE__RELABELTO                       0x00000100UL
-+#define BLK_FILE__READ                            0x00000002UL
-+#define BLK_FILE__RENAME                          0x00001000UL
-+#define BLK_FILE__APPEND                          0x00000200UL
-+#define BLK_FILE__LOCK                            0x00000040UL
-+#define BLK_FILE__SWAPON                          0x00004000UL
-+#define BLK_FILE__GETATTR                         0x00000010UL
-+#define BLK_FILE__MOUNTON                         0x00010000UL
-+#define BLK_FILE__CREATE                          0x00000008UL
-+
-+#define SOCK_FILE__EXECUTE                        0x00002000UL
-+#define SOCK_FILE__UNLINK                         0x00000400UL
-+#define SOCK_FILE__SETATTR                        0x00000020UL
-+#define SOCK_FILE__QUOTAON                        0x00008000UL
-+#define SOCK_FILE__RELABELFROM                    0x00000080UL
-+#define SOCK_FILE__LINK                           0x00000800UL
-+#define SOCK_FILE__WRITE                          0x00000004UL
-+#define SOCK_FILE__IOCTL                          0x00000001UL
-+#define SOCK_FILE__RELABELTO                      0x00000100UL
-+#define SOCK_FILE__READ                           0x00000002UL
-+#define SOCK_FILE__RENAME                         0x00001000UL
-+#define SOCK_FILE__APPEND                         0x00000200UL
-+#define SOCK_FILE__LOCK                           0x00000040UL
-+#define SOCK_FILE__SWAPON                         0x00004000UL
-+#define SOCK_FILE__GETATTR                        0x00000010UL
-+#define SOCK_FILE__MOUNTON                        0x00010000UL
-+#define SOCK_FILE__CREATE                         0x00000008UL
-+
-+#define FIFO_FILE__EXECUTE                        0x00002000UL
-+#define FIFO_FILE__UNLINK                         0x00000400UL
-+#define FIFO_FILE__SETATTR                        0x00000020UL
-+#define FIFO_FILE__QUOTAON                        0x00008000UL
-+#define FIFO_FILE__RELABELFROM                    0x00000080UL
-+#define FIFO_FILE__LINK                           0x00000800UL
-+#define FIFO_FILE__WRITE                          0x00000004UL
-+#define FIFO_FILE__IOCTL                          0x00000001UL
-+#define FIFO_FILE__RELABELTO                      0x00000100UL
-+#define FIFO_FILE__READ                           0x00000002UL
-+#define FIFO_FILE__RENAME                         0x00001000UL
-+#define FIFO_FILE__APPEND                         0x00000200UL
-+#define FIFO_FILE__LOCK                           0x00000040UL
-+#define FIFO_FILE__SWAPON                         0x00004000UL
-+#define FIFO_FILE__GETATTR                        0x00000010UL
-+#define FIFO_FILE__MOUNTON                        0x00010000UL
-+#define FIFO_FILE__CREATE                         0x00000008UL
-+
-+#define FD__USE                                   0x00000001UL
-+
-+#define SOCKET__RELABELTO                         0x00000100UL
-+#define SOCKET__RECV_MSG                          0x00080000UL
-+#define SOCKET__RELABELFROM                       0x00000080UL
-+#define SOCKET__SETOPT                            0x00008000UL
-+#define SOCKET__APPEND                            0x00000200UL
-+#define SOCKET__SETATTR                           0x00000020UL
-+#define SOCKET__SENDTO                            0x00040000UL
-+#define SOCKET__GETOPT                            0x00004000UL
-+#define SOCKET__READ                              0x00000002UL
-+#define SOCKET__SHUTDOWN                          0x00010000UL
-+#define SOCKET__LISTEN                            0x00001000UL
-+#define SOCKET__BIND                              0x00000400UL
-+#define SOCKET__WRITE                             0x00000004UL
-+#define SOCKET__ACCEPT                            0x00002000UL
-+#define SOCKET__CONNECT                           0x00000800UL
-+#define SOCKET__LOCK                              0x00000040UL
-+#define SOCKET__IOCTL                             0x00000001UL
-+#define SOCKET__CREATE                            0x00000008UL
-+#define SOCKET__NAME_BIND                         0x00200000UL
-+#define SOCKET__SEND_MSG                          0x00100000UL
-+#define SOCKET__RECVFROM                          0x00020000UL
-+#define SOCKET__GETATTR                           0x00000010UL
-+
-+#define TCP_SOCKET__RELABELTO                     0x00000100UL
-+#define TCP_SOCKET__RECV_MSG                      0x00080000UL
-+#define TCP_SOCKET__RELABELFROM                   0x00000080UL
-+#define TCP_SOCKET__SETOPT                        0x00008000UL
-+#define TCP_SOCKET__APPEND                        0x00000200UL
-+#define TCP_SOCKET__SETATTR                       0x00000020UL
-+#define TCP_SOCKET__SENDTO                        0x00040000UL
-+#define TCP_SOCKET__GETOPT                        0x00004000UL
-+#define TCP_SOCKET__READ                          0x00000002UL
-+#define TCP_SOCKET__SHUTDOWN                      0x00010000UL
-+#define TCP_SOCKET__LISTEN                        0x00001000UL
-+#define TCP_SOCKET__BIND                          0x00000400UL
-+#define TCP_SOCKET__WRITE                         0x00000004UL
-+#define TCP_SOCKET__ACCEPT                        0x00002000UL
-+#define TCP_SOCKET__CONNECT                       0x00000800UL
-+#define TCP_SOCKET__LOCK                          0x00000040UL
-+#define TCP_SOCKET__IOCTL                         0x00000001UL
-+#define TCP_SOCKET__CREATE                        0x00000008UL
-+#define TCP_SOCKET__NAME_BIND                     0x00200000UL
-+#define TCP_SOCKET__SEND_MSG                      0x00100000UL
-+#define TCP_SOCKET__RECVFROM                      0x00020000UL
-+#define TCP_SOCKET__GETATTR                       0x00000010UL
-+
-+#define TCP_SOCKET__CONNECTTO                     0x00400000UL
-+#define TCP_SOCKET__NEWCONN                       0x00800000UL
-+#define TCP_SOCKET__ACCEPTFROM                    0x01000000UL
-+
-+#define UDP_SOCKET__RELABELTO                     0x00000100UL
-+#define UDP_SOCKET__RECV_MSG                      0x00080000UL
-+#define UDP_SOCKET__RELABELFROM                   0x00000080UL
-+#define UDP_SOCKET__SETOPT                        0x00008000UL
-+#define UDP_SOCKET__APPEND                        0x00000200UL
-+#define UDP_SOCKET__SETATTR                       0x00000020UL
-+#define UDP_SOCKET__SENDTO                        0x00040000UL
-+#define UDP_SOCKET__GETOPT                        0x00004000UL
-+#define UDP_SOCKET__READ                          0x00000002UL
-+#define UDP_SOCKET__SHUTDOWN                      0x00010000UL
-+#define UDP_SOCKET__LISTEN                        0x00001000UL
-+#define UDP_SOCKET__BIND                          0x00000400UL
-+#define UDP_SOCKET__WRITE                         0x00000004UL
-+#define UDP_SOCKET__ACCEPT                        0x00002000UL
-+#define UDP_SOCKET__CONNECT                       0x00000800UL
-+#define UDP_SOCKET__LOCK                          0x00000040UL
-+#define UDP_SOCKET__IOCTL                         0x00000001UL
-+#define UDP_SOCKET__CREATE                        0x00000008UL
-+#define UDP_SOCKET__NAME_BIND                     0x00200000UL
-+#define UDP_SOCKET__SEND_MSG                      0x00100000UL
-+#define UDP_SOCKET__RECVFROM                      0x00020000UL
-+#define UDP_SOCKET__GETATTR                       0x00000010UL
-+
-+#define RAWIP_SOCKET__RELABELTO                   0x00000100UL
-+#define RAWIP_SOCKET__RECV_MSG                    0x00080000UL
-+#define RAWIP_SOCKET__RELABELFROM                 0x00000080UL
-+#define RAWIP_SOCKET__SETOPT                      0x00008000UL
-+#define RAWIP_SOCKET__APPEND                      0x00000200UL
-+#define RAWIP_SOCKET__SETATTR                     0x00000020UL
-+#define RAWIP_SOCKET__SENDTO                      0x00040000UL
-+#define RAWIP_SOCKET__GETOPT                      0x00004000UL
-+#define RAWIP_SOCKET__READ                        0x00000002UL
-+#define RAWIP_SOCKET__SHUTDOWN                    0x00010000UL
-+#define RAWIP_SOCKET__LISTEN                      0x00001000UL
-+#define RAWIP_SOCKET__BIND                        0x00000400UL
-+#define RAWIP_SOCKET__WRITE                       0x00000004UL
-+#define RAWIP_SOCKET__ACCEPT                      0x00002000UL
-+#define RAWIP_SOCKET__CONNECT                     0x00000800UL
-+#define RAWIP_SOCKET__LOCK                        0x00000040UL
-+#define RAWIP_SOCKET__IOCTL                       0x00000001UL
-+#define RAWIP_SOCKET__CREATE                      0x00000008UL
-+#define RAWIP_SOCKET__NAME_BIND                   0x00200000UL
-+#define RAWIP_SOCKET__SEND_MSG                    0x00100000UL
-+#define RAWIP_SOCKET__RECVFROM                    0x00020000UL
-+#define RAWIP_SOCKET__GETATTR                     0x00000010UL
-+
-+#define NODE__TCP_RECV                            0x00000001UL
-+#define NODE__TCP_SEND                            0x00000002UL
-+#define NODE__UDP_RECV                            0x00000004UL
-+#define NODE__UDP_SEND                            0x00000008UL
-+#define NODE__RAWIP_RECV                          0x00000010UL
-+#define NODE__RAWIP_SEND                          0x00000020UL
-+#define NODE__ENFORCE_DEST                        0x00000040UL
-+
-+#define NETIF__TCP_RECV                           0x00000001UL
-+#define NETIF__TCP_SEND                           0x00000002UL
-+#define NETIF__UDP_RECV                           0x00000004UL
-+#define NETIF__UDP_SEND                           0x00000008UL
-+#define NETIF__RAWIP_RECV                         0x00000010UL
-+#define NETIF__RAWIP_SEND                         0x00000020UL
-+
-+#define NETLINK_SOCKET__RELABELTO                 0x00000100UL
-+#define NETLINK_SOCKET__RECV_MSG                  0x00080000UL
-+#define NETLINK_SOCKET__RELABELFROM               0x00000080UL
-+#define NETLINK_SOCKET__SETOPT                    0x00008000UL
-+#define NETLINK_SOCKET__APPEND                    0x00000200UL
-+#define NETLINK_SOCKET__SETATTR                   0x00000020UL
-+#define NETLINK_SOCKET__SENDTO                    0x00040000UL
-+#define NETLINK_SOCKET__GETOPT                    0x00004000UL
-+#define NETLINK_SOCKET__READ                      0x00000002UL
-+#define NETLINK_SOCKET__SHUTDOWN                  0x00010000UL
-+#define NETLINK_SOCKET__LISTEN                    0x00001000UL
-+#define NETLINK_SOCKET__BIND                      0x00000400UL
-+#define NETLINK_SOCKET__WRITE                     0x00000004UL
-+#define NETLINK_SOCKET__ACCEPT                    0x00002000UL
-+#define NETLINK_SOCKET__CONNECT                   0x00000800UL
-+#define NETLINK_SOCKET__LOCK                      0x00000040UL
-+#define NETLINK_SOCKET__IOCTL                     0x00000001UL
-+#define NETLINK_SOCKET__CREATE                    0x00000008UL
-+#define NETLINK_SOCKET__NAME_BIND                 0x00200000UL
-+#define NETLINK_SOCKET__SEND_MSG                  0x00100000UL
-+#define NETLINK_SOCKET__RECVFROM                  0x00020000UL
-+#define NETLINK_SOCKET__GETATTR                   0x00000010UL
-+
-+#define PACKET_SOCKET__RELABELTO                  0x00000100UL
-+#define PACKET_SOCKET__RECV_MSG                   0x00080000UL
-+#define PACKET_SOCKET__RELABELFROM                0x00000080UL
-+#define PACKET_SOCKET__SETOPT                     0x00008000UL
-+#define PACKET_SOCKET__APPEND                     0x00000200UL
-+#define PACKET_SOCKET__SETATTR                    0x00000020UL
-+#define PACKET_SOCKET__SENDTO                     0x00040000UL
-+#define PACKET_SOCKET__GETOPT                     0x00004000UL
-+#define PACKET_SOCKET__READ                       0x00000002UL
-+#define PACKET_SOCKET__SHUTDOWN                   0x00010000UL
-+#define PACKET_SOCKET__LISTEN                     0x00001000UL
-+#define PACKET_SOCKET__BIND                       0x00000400UL
-+#define PACKET_SOCKET__WRITE                      0x00000004UL
-+#define PACKET_SOCKET__ACCEPT                     0x00002000UL
-+#define PACKET_SOCKET__CONNECT                    0x00000800UL
-+#define PACKET_SOCKET__LOCK                       0x00000040UL
-+#define PACKET_SOCKET__IOCTL                      0x00000001UL
-+#define PACKET_SOCKET__CREATE                     0x00000008UL
-+#define PACKET_SOCKET__NAME_BIND                  0x00200000UL
-+#define PACKET_SOCKET__SEND_MSG                   0x00100000UL
-+#define PACKET_SOCKET__RECVFROM                   0x00020000UL
-+#define PACKET_SOCKET__GETATTR                    0x00000010UL
-+
-+#define KEY_SOCKET__RELABELTO                     0x00000100UL
-+#define KEY_SOCKET__RECV_MSG                      0x00080000UL
-+#define KEY_SOCKET__RELABELFROM                   0x00000080UL
-+#define KEY_SOCKET__SETOPT                        0x00008000UL
-+#define KEY_SOCKET__APPEND                        0x00000200UL
-+#define KEY_SOCKET__SETATTR                       0x00000020UL
-+#define KEY_SOCKET__SENDTO                        0x00040000UL
-+#define KEY_SOCKET__GETOPT                        0x00004000UL
-+#define KEY_SOCKET__READ                          0x00000002UL
-+#define KEY_SOCKET__SHUTDOWN                      0x00010000UL
-+#define KEY_SOCKET__LISTEN                        0x00001000UL
-+#define KEY_SOCKET__BIND                          0x00000400UL
-+#define KEY_SOCKET__WRITE                         0x00000004UL
-+#define KEY_SOCKET__ACCEPT                        0x00002000UL
-+#define KEY_SOCKET__CONNECT                       0x00000800UL
-+#define KEY_SOCKET__LOCK                          0x00000040UL
-+#define KEY_SOCKET__IOCTL                         0x00000001UL
-+#define KEY_SOCKET__CREATE                        0x00000008UL
-+#define KEY_SOCKET__NAME_BIND                     0x00200000UL
-+#define KEY_SOCKET__SEND_MSG                      0x00100000UL
-+#define KEY_SOCKET__RECVFROM                      0x00020000UL
-+#define KEY_SOCKET__GETATTR                       0x00000010UL
-+
-+#define UNIX_STREAM_SOCKET__RELABELTO             0x00000100UL
-+#define UNIX_STREAM_SOCKET__RECV_MSG              0x00080000UL
-+#define UNIX_STREAM_SOCKET__RELABELFROM           0x00000080UL
-+#define UNIX_STREAM_SOCKET__SETOPT                0x00008000UL
-+#define UNIX_STREAM_SOCKET__APPEND                0x00000200UL
-+#define UNIX_STREAM_SOCKET__SETATTR               0x00000020UL
-+#define UNIX_STREAM_SOCKET__SENDTO                0x00040000UL
-+#define UNIX_STREAM_SOCKET__GETOPT                0x00004000UL
-+#define UNIX_STREAM_SOCKET__READ                  0x00000002UL
-+#define UNIX_STREAM_SOCKET__SHUTDOWN              0x00010000UL
-+#define UNIX_STREAM_SOCKET__LISTEN                0x00001000UL
-+#define UNIX_STREAM_SOCKET__BIND                  0x00000400UL
-+#define UNIX_STREAM_SOCKET__WRITE                 0x00000004UL
-+#define UNIX_STREAM_SOCKET__ACCEPT                0x00002000UL
-+#define UNIX_STREAM_SOCKET__CONNECT               0x00000800UL
-+#define UNIX_STREAM_SOCKET__LOCK                  0x00000040UL
-+#define UNIX_STREAM_SOCKET__IOCTL                 0x00000001UL
-+#define UNIX_STREAM_SOCKET__CREATE                0x00000008UL
-+#define UNIX_STREAM_SOCKET__NAME_BIND             0x00200000UL
-+#define UNIX_STREAM_SOCKET__SEND_MSG              0x00100000UL
-+#define UNIX_STREAM_SOCKET__RECVFROM              0x00020000UL
-+#define UNIX_STREAM_SOCKET__GETATTR               0x00000010UL
-+
-+#define UNIX_STREAM_SOCKET__CONNECTTO             0x00400000UL
-+#define UNIX_STREAM_SOCKET__NEWCONN               0x00800000UL
-+#define UNIX_STREAM_SOCKET__ACCEPTFROM            0x01000000UL
-+
-+#define UNIX_DGRAM_SOCKET__RELABELTO              0x00000100UL
-+#define UNIX_DGRAM_SOCKET__RECV_MSG               0x00080000UL
-+#define UNIX_DGRAM_SOCKET__RELABELFROM            0x00000080UL
-+#define UNIX_DGRAM_SOCKET__SETOPT                 0x00008000UL
-+#define UNIX_DGRAM_SOCKET__APPEND                 0x00000200UL
-+#define UNIX_DGRAM_SOCKET__SETATTR                0x00000020UL
-+#define UNIX_DGRAM_SOCKET__SENDTO                 0x00040000UL
-+#define UNIX_DGRAM_SOCKET__GETOPT                 0x00004000UL
-+#define UNIX_DGRAM_SOCKET__READ                   0x00000002UL
-+#define UNIX_DGRAM_SOCKET__SHUTDOWN               0x00010000UL
-+#define UNIX_DGRAM_SOCKET__LISTEN                 0x00001000UL
-+#define UNIX_DGRAM_SOCKET__BIND                   0x00000400UL
-+#define UNIX_DGRAM_SOCKET__WRITE                  0x00000004UL
-+#define UNIX_DGRAM_SOCKET__ACCEPT                 0x00002000UL
-+#define UNIX_DGRAM_SOCKET__CONNECT                0x00000800UL
-+#define UNIX_DGRAM_SOCKET__LOCK                   0x00000040UL
-+#define UNIX_DGRAM_SOCKET__IOCTL                  0x00000001UL
-+#define UNIX_DGRAM_SOCKET__CREATE                 0x00000008UL
-+#define UNIX_DGRAM_SOCKET__NAME_BIND              0x00200000UL
-+#define UNIX_DGRAM_SOCKET__SEND_MSG               0x00100000UL
-+#define UNIX_DGRAM_SOCKET__RECVFROM               0x00020000UL
-+#define UNIX_DGRAM_SOCKET__GETATTR                0x00000010UL
-+
-+#define PROCESS__FORK                             0x00000001UL
-+#define PROCESS__TRANSITION                       0x00000002UL
-+#define PROCESS__SIGCHLD                          0x00000004UL
-+#define PROCESS__SIGKILL                          0x00000008UL
-+#define PROCESS__SIGSTOP                          0x00000010UL
-+#define PROCESS__SIGNULL                          0x00000020UL
-+#define PROCESS__SIGNAL                           0x00000040UL
-+#define PROCESS__PTRACE                           0x00000080UL
-+#define PROCESS__GETSCHED                         0x00000100UL
-+#define PROCESS__SETSCHED                         0x00000200UL
-+#define PROCESS__GETSESSION                       0x00000400UL
-+#define PROCESS__GETPGID                          0x00000800UL
-+#define PROCESS__SETPGID                          0x00001000UL
-+#define PROCESS__GETCAP                           0x00002000UL
-+#define PROCESS__SETCAP                           0x00004000UL
-+#define PROCESS__SHARE                            0x00008000UL
-+#define PROCESS__GETATTR                          0x00010000UL
-+#define PROCESS__SETEXEC                          0x00020000UL
-+#define PROCESS__SETFSCREATE                      0x00040000UL
-+#define PROCESS__NOATSECURE                       0x00080000UL
-+
-+#define IPC__SETATTR                              0x00000008UL
-+#define IPC__READ                                 0x00000010UL
-+#define IPC__ASSOCIATE                            0x00000040UL
-+#define IPC__DESTROY                              0x00000002UL
-+#define IPC__UNIX_WRITE                           0x00000100UL
-+#define IPC__CREATE                               0x00000001UL
-+#define IPC__UNIX_READ                            0x00000080UL
-+#define IPC__GETATTR                              0x00000004UL
-+#define IPC__WRITE                                0x00000020UL
-+
-+#define SEM__SETATTR                              0x00000008UL
-+#define SEM__READ                                 0x00000010UL
-+#define SEM__ASSOCIATE                            0x00000040UL
-+#define SEM__DESTROY                              0x00000002UL
-+#define SEM__UNIX_WRITE                           0x00000100UL
-+#define SEM__CREATE                               0x00000001UL
-+#define SEM__UNIX_READ                            0x00000080UL
-+#define SEM__GETATTR                              0x00000004UL
-+#define SEM__WRITE                                0x00000020UL
-+
-+#define MSGQ__SETATTR                             0x00000008UL
-+#define MSGQ__READ                                0x00000010UL
-+#define MSGQ__ASSOCIATE                           0x00000040UL
-+#define MSGQ__DESTROY                             0x00000002UL
-+#define MSGQ__UNIX_WRITE                          0x00000100UL
-+#define MSGQ__CREATE                              0x00000001UL
-+#define MSGQ__UNIX_READ                           0x00000080UL
-+#define MSGQ__GETATTR                             0x00000004UL
-+#define MSGQ__WRITE                               0x00000020UL
-+
-+#define MSGQ__ENQUEUE                             0x00000200UL
-+
-+#define MSG__SEND                                 0x00000001UL
-+#define MSG__RECEIVE                              0x00000002UL
-+
-+#define SHM__SETATTR                              0x00000008UL
-+#define SHM__READ                                 0x00000010UL
-+#define SHM__ASSOCIATE                            0x00000040UL
-+#define SHM__DESTROY                              0x00000002UL
-+#define SHM__UNIX_WRITE                           0x00000100UL
-+#define SHM__CREATE                               0x00000001UL
-+#define SHM__UNIX_READ                            0x00000080UL
-+#define SHM__GETATTR                              0x00000004UL
-+#define SHM__WRITE                                0x00000020UL
-+
-+#define SHM__LOCK                                 0x00000200UL
-+
-+#define SECURITY__COMPUTE_AV                      0x00000001UL
-+#define SECURITY__COMPUTE_CREATE                  0x00000002UL
-+#define SECURITY__COMPUTE_MEMBER                  0x00000004UL
-+#define SECURITY__CHECK_CONTEXT                   0x00000008UL
-+#define SECURITY__LOAD_POLICY                     0x00000010UL
-+#define SECURITY__COMPUTE_RELABEL                 0x00000020UL
-+#define SECURITY__COMPUTE_USER                    0x00000040UL
-+#define SECURITY__SETENFORCE                      0x00000080UL
-+
-+#define SYSTEM__IPC_INFO                          0x00000001UL
-+#define SYSTEM__SYSLOG_READ                       0x00000002UL
-+#define SYSTEM__SYSLOG_MOD                        0x00000004UL
-+#define SYSTEM__SYSLOG_CONSOLE                    0x00000008UL
-+
-+#define CAPABILITY__CHOWN                         0x00000001UL
-+#define CAPABILITY__DAC_OVERRIDE                  0x00000002UL
-+#define CAPABILITY__DAC_READ_SEARCH               0x00000004UL
-+#define CAPABILITY__FOWNER                        0x00000008UL
-+#define CAPABILITY__FSETID                        0x00000010UL
-+#define CAPABILITY__KILL                          0x00000020UL
-+#define CAPABILITY__SETGID                        0x00000040UL
-+#define CAPABILITY__SETUID                        0x00000080UL
-+#define CAPABILITY__SETPCAP                       0x00000100UL
-+#define CAPABILITY__LINUX_IMMUTABLE               0x00000200UL
-+#define CAPABILITY__NET_BIND_SERVICE              0x00000400UL
-+#define CAPABILITY__NET_BROADCAST                 0x00000800UL
-+#define CAPABILITY__NET_ADMIN                     0x00001000UL
-+#define CAPABILITY__NET_RAW                       0x00002000UL
-+#define CAPABILITY__IPC_LOCK                      0x00004000UL
-+#define CAPABILITY__IPC_OWNER                     0x00008000UL
-+#define CAPABILITY__SYS_MODULE                    0x00010000UL
-+#define CAPABILITY__SYS_RAWIO                     0x00020000UL
-+#define CAPABILITY__SYS_CHROOT                    0x00040000UL
-+#define CAPABILITY__SYS_PTRACE                    0x00080000UL
-+#define CAPABILITY__SYS_PACCT                     0x00100000UL
-+#define CAPABILITY__SYS_ADMIN                     0x00200000UL
-+#define CAPABILITY__SYS_BOOT                      0x00400000UL
-+#define CAPABILITY__SYS_NICE                      0x00800000UL
-+#define CAPABILITY__SYS_RESOURCE                  0x01000000UL
-+#define CAPABILITY__SYS_TIME                      0x02000000UL
-+#define CAPABILITY__SYS_TTY_CONFIG                0x04000000UL
-+#define CAPABILITY__MKNOD                         0x08000000UL
-+#define CAPABILITY__LEASE                         0x10000000UL
-+
-+#define PASSWD__PASSWD                            0x00000001UL
-+#define PASSWD__CHFN                              0x00000002UL
-+#define PASSWD__CHSH                              0x00000004UL
-+
-+
-+/* FLASK */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/av_perm_to_string.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,120 @@
-+/* This file is automatically generated.  Do not edit. */
-+/* FLASK */
-+
-+struct av_perm_to_string
-+{
-+    u16 tclass;
-+    u32 value;
-+    char *name;
-+};
-+
-+static struct av_perm_to_string av_perm_to_string[] = {
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod" },
-+   { SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget" },
-+   { SECCLASS_DIR, DIR__ADD_NAME, "add_name" },
-+   { SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name" },
-+   { SECCLASS_DIR, DIR__REPARENT, "reparent" },
-+   { SECCLASS_DIR, DIR__SEARCH, "search" },
-+   { SECCLASS_DIR, DIR__RMDIR, "rmdir" },
-+   { SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans" },
-+   { SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint" },
-+   { SECCLASS_FD, FD__USE, "use" },
-+   { SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto" },
-+   { SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn" },
-+   { SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom" },
-+   { SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv" },
-+   { SECCLASS_NODE, NODE__TCP_SEND, "tcp_send" },
-+   { SECCLASS_NODE, NODE__UDP_RECV, "udp_recv" },
-+   { SECCLASS_NODE, NODE__UDP_SEND, "udp_send" },
-+   { SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv" },
-+   { SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send" },
-+   { SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest" },
-+   { SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv" },
-+   { SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send" },
-+   { SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv" },
-+   { SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send" },
-+   { SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv" },
-+   { SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send" },
-+   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto" },
-+   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" },
-+   { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" },
-+   { SECCLASS_PROCESS, PROCESS__FORK, "fork" },
-+   { SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" },
-+   { SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" },
-+   { SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill" },
-+   { SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop" },
-+   { SECCLASS_PROCESS, PROCESS__SIGNULL, "signull" },
-+   { SECCLASS_PROCESS, PROCESS__SIGNAL, "signal" },
-+   { SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace" },
-+   { SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched" },
-+   { SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched" },
-+   { SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession" },
-+   { SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid" },
-+   { SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid" },
-+   { SECCLASS_PROCESS, PROCESS__GETCAP, "getcap" },
-+   { SECCLASS_PROCESS, PROCESS__SETCAP, "setcap" },
-+   { SECCLASS_PROCESS, PROCESS__SHARE, "share" },
-+   { SECCLASS_PROCESS, PROCESS__GETATTR, "getattr" },
-+   { SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec" },
-+   { SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" },
-+   { SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" },
-+   { SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" },
-+   { SECCLASS_MSG, MSG__SEND, "send" },
-+   { SECCLASS_MSG, MSG__RECEIVE, "receive" },
-+   { SECCLASS_SHM, SHM__LOCK, "lock" },
-+   { SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av" },
-+   { SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create" },
-+   { SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member" },
-+   { SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context" },
-+   { SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy" },
-+   { SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel" },
-+   { SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user" },
-+   { SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce" },
-+   { SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info" },
-+   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read" },
-+   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod" },
-+   { SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod" },
-+   { SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease" },
-+   { SECCLASS_PASSWD, PASSWD__PASSWD, "passwd" },
-+   { SECCLASS_PASSWD, PASSWD__CHFN, "chfn" },
-+   { SECCLASS_PASSWD, PASSWD__CHSH, "chsh" },
-+};
-+
-+
-+/* FLASK */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/class_to_string.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,39 @@
-+/* This file is automatically generated.  Do not edit. */
-+/*
-+ * Security object class definitions
-+ */
-+static char *class_to_string[] =
-+{
-+    "null",
-+    "security",
-+    "process",
-+    "system",
-+    "capability",
-+    "filesystem",
-+    "file",
-+    "dir",
-+    "fd",
-+    "lnk_file",
-+    "chr_file",
-+    "blk_file",
-+    "sock_file",
-+    "fifo_file",
-+    "socket",
-+    "tcp_socket",
-+    "udp_socket",
-+    "rawip_socket",
-+    "node",
-+    "netif",
-+    "netlink_socket",
-+    "packet_socket",
-+    "key_socket",
-+    "unix_stream_socket",
-+    "unix_dgram_socket",
-+    "sem",
-+    "msg",
-+    "msgq",
-+    "shm",
-+    "ipc",
-+    "passwd",
-+};
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/common_perm_to_string.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,65 @@
-+/* This file is automatically generated.  Do not edit. */
-+/* FLASK */
-+
-+static char *common_file_perm_to_string[] =
-+{
-+    "ioctl",
-+    "read",
-+    "write",
-+    "create",
-+    "getattr",
-+    "setattr",
-+    "lock",
-+    "relabelfrom",
-+    "relabelto",
-+    "append",
-+    "unlink",
-+    "link",
-+    "rename",
-+    "execute",
-+    "swapon",
-+    "quotaon",
-+    "mounton",
-+};
-+
-+static char *common_socket_perm_to_string[] =
-+{
-+    "ioctl",
-+    "read",
-+    "write",
-+    "create",
-+    "getattr",
-+    "setattr",
-+    "lock",
-+    "relabelfrom",
-+    "relabelto",
-+    "append",
-+    "bind",
-+    "connect",
-+    "listen",
-+    "accept",
-+    "getopt",
-+    "setopt",
-+    "shutdown",
-+    "recvfrom",
-+    "sendto",
-+    "recv_msg",
-+    "send_msg",
-+    "name_bind",
-+};
-+
-+static char *common_ipc_perm_to_string[] =
-+{
-+    "create",
-+    "destroy",
-+    "getattr",
-+    "setattr",
-+    "read",
-+    "write",
-+    "associate",
-+    "unix_read",
-+    "unix_write",
-+};
-+
-+
-+/* FLASK */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/flask.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,71 @@
-+/* This file is automatically generated.  Do not edit. */
-+#ifndef _SELINUX_FLASK_H_
-+#define _SELINUX_FLASK_H_
-+
-+/*
-+ * Security object class definitions
-+ */
-+#define SECCLASS_SECURITY                                1
-+#define SECCLASS_PROCESS                                 2
-+#define SECCLASS_SYSTEM                                  3
-+#define SECCLASS_CAPABILITY                              4
-+#define SECCLASS_FILESYSTEM                              5
-+#define SECCLASS_FILE                                    6
-+#define SECCLASS_DIR                                     7
-+#define SECCLASS_FD                                      8
-+#define SECCLASS_LNK_FILE                                9
-+#define SECCLASS_CHR_FILE                                10
-+#define SECCLASS_BLK_FILE                                11
-+#define SECCLASS_SOCK_FILE                               12
-+#define SECCLASS_FIFO_FILE                               13
-+#define SECCLASS_SOCKET                                  14
-+#define SECCLASS_TCP_SOCKET                              15
-+#define SECCLASS_UDP_SOCKET                              16
-+#define SECCLASS_RAWIP_SOCKET                            17
-+#define SECCLASS_NODE                                    18
-+#define SECCLASS_NETIF                                   19
-+#define SECCLASS_NETLINK_SOCKET                          20
-+#define SECCLASS_PACKET_SOCKET                           21
-+#define SECCLASS_KEY_SOCKET                              22
-+#define SECCLASS_UNIX_STREAM_SOCKET                      23
-+#define SECCLASS_UNIX_DGRAM_SOCKET                       24
-+#define SECCLASS_SEM                                     25
-+#define SECCLASS_MSG                                     26
-+#define SECCLASS_MSGQ                                    27
-+#define SECCLASS_SHM                                     28
-+#define SECCLASS_IPC                                     29
-+#define SECCLASS_PASSWD                                  30
-+
-+/*
-+ * Security identifier indices for initial entities
-+ */
-+#define SECINITSID_KERNEL                               1
-+#define SECINITSID_SECURITY                             2
-+#define SECINITSID_UNLABELED                            3
-+#define SECINITSID_FS                                   4
-+#define SECINITSID_FILE                                 5
-+#define SECINITSID_FILE_LABELS                          6
-+#define SECINITSID_INIT                                 7
-+#define SECINITSID_ANY_SOCKET                           8
-+#define SECINITSID_PORT                                 9
-+#define SECINITSID_NETIF                                10
-+#define SECINITSID_NETMSG                               11
-+#define SECINITSID_NODE                                 12
-+#define SECINITSID_IGMP_PACKET                          13
-+#define SECINITSID_ICMP_SOCKET                          14
-+#define SECINITSID_TCP_SOCKET                           15
-+#define SECINITSID_SYSCTL_MODPROBE                      16
-+#define SECINITSID_SYSCTL                               17
-+#define SECINITSID_SYSCTL_FS                            18
-+#define SECINITSID_SYSCTL_KERNEL                        19
-+#define SECINITSID_SYSCTL_NET                           20
-+#define SECINITSID_SYSCTL_NET_UNIX                      21
-+#define SECINITSID_SYSCTL_VM                            22
-+#define SECINITSID_SYSCTL_DEV                           23
-+#define SECINITSID_KMOD                                 24
-+#define SECINITSID_POLICY                               25
-+#define SECINITSID_SCMP_PACKET                          26
-+
-+#define SECINITSID_NUM                                  26
-+
-+#endif
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/initial_sid_to_string.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,32 @@
-+/* This file is automatically generated.  Do not edit. */
-+static char *initial_sid_to_string[] =
-+{
-+    "null",
-+    "kernel",
-+    "security",
-+    "unlabeled",
-+    "fs",
-+    "file",
-+    "file_labels",
-+    "init",
-+    "any_socket",
-+    "port",
-+    "netif",
-+    "netmsg",
-+    "node",
-+    "igmp_packet",
-+    "icmp_socket",
-+    "tcp_socket",
-+    "sysctl_modprobe",
-+    "sysctl",
-+    "sysctl_fs",
-+    "sysctl_kernel",
-+    "sysctl_net",
-+    "sysctl_net_unix",
-+    "sysctl_vm",
-+    "sysctl_dev",
-+    "kmod",
-+    "policy",
-+    "scmp_packet",
-+};
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/objsec.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,88 @@
-+/*
-+ *  NSA Security-Enhanced Linux (SELinux) security module
-+ *
-+ *  This file contains the SELinux security data structures for kernel objects.
-+ *
-+ *  Author(s):  Stephen Smalley, <sds@epoch.ncsc.mil>
-+ *              Chris Vance, <cvance@nai.com>
-+ *              Wayne Salamon, <wsalamon@nai.com>
-+ *              James Morris <jmorris@redhat.com>
-+ *
-+ *  Copyright (C) 2001,2002 Networks Associates Technology, Inc.
-+ *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
-+ *
-+ *	This program is free software; you can redistribute it and/or modify
-+ *	it under the terms of the GNU General Public License version 2,
-+ *      as published by the Free Software Foundation.
-+ */
-+#ifndef _SELINUX_OBJSEC_H_
-+#define _SELINUX_OBJSEC_H_
-+
-+#include <linux/list.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/in.h>
-+#include "flask.h"
-+#include "avc.h"
-+
-+struct task_security_struct {
-+        unsigned long magic;           /* magic number for this module */
-+	struct task_struct *task;      /* back pointer to task object */
-+	u32 osid;            /* SID prior to last execve */
-+	u32 sid;             /* current SID */
-+	u32 exec_sid;        /* exec SID */
-+	u32 create_sid;      /* fscreate SID */
-+        struct avc_entry_ref avcr;     /* reference to process permissions */
-+};
-+
-+struct inode_security_struct {
-+	unsigned long magic;           /* magic number for this module */
-+        struct inode *inode;           /* back pointer to inode object */
-+	struct list_head list;         /* list of inode_security_struct */
-+	u32 task_sid;        /* SID of creating task */
-+	u32 sid;             /* SID of this object */
-+	u16 sclass;       /* security class of this object */
-+	struct avc_entry_ref avcr;     /* reference to object permissions */
-+	unsigned char initialized;     /* initialization flag */
-+	struct semaphore sem;
-+	unsigned char inherit;         /* inherit SID from parent entry */
-+};
-+
-+struct file_security_struct {
-+	unsigned long magic;            /* magic number for this module */
-+	struct file *file;              /* back pointer to file object */
-+	u32 sid;              /* SID of open file description */
-+	u32 fown_sid;         /* SID of file owner (for SIGIO) */
-+	struct avc_entry_ref avcr;	/* reference to fd permissions */
-+	struct avc_entry_ref inode_avcr;     /* reference to object permissions */
-+};
-+
-+struct superblock_security_struct {
-+	unsigned long magic;            /* magic number for this module */
-+	struct super_block *sb;         /* back pointer to sb object */
-+	struct list_head list;          /* list of superblock_security_struct */
-+	u32 sid;              /* SID of file system */
-+	unsigned int behavior;          /* labeling behavior */
-+	unsigned char initialized;      /* initialization flag */
-+	unsigned char proc;             /* proc fs */
-+	struct semaphore sem;
-+};
-+
-+struct msg_security_struct {
-+        unsigned long magic;		/* magic number for this module */
-+	struct msg_msg *msg;		/* back pointer */
-+	u32 sid;              /* SID of message */
-+        struct avc_entry_ref avcr;	/* reference to permissions */
-+};
-+
-+struct ipc_security_struct {
-+        unsigned long magic;		/* magic number for this module */
-+	struct kern_ipc_perm *ipc_perm; /* back pointer */
-+	u16 sclass;	/* security class of this object */
-+	u32 sid;              /* SID of IPC resource */
-+        struct avc_entry_ref avcr;	/* reference to permissions */
-+};
-+
-+extern int inode_security_set_sid(struct inode *inode, u32 sid);
-+
-+#endif /* _SELINUX_OBJSEC_H_ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/include/security.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,70 @@
-+/*
-+ * Security server interface.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SELINUX_SECURITY_H_
-+#define _SELINUX_SECURITY_H_
-+
-+#include "flask.h"
-+
-+#define SECSID_NULL			0x00000000 /* unspecified SID */
-+#define SECSID_WILD			0xffffffff /* wildcard SID */
-+#define SECCLASS_NULL			0x0000 /* no class */
-+
-+#define SELINUX_MAGIC 0xf97cff8c
-+
-+int security_load_policy(void * data, size_t len);
-+
-+struct av_decision {
-+	u32 allowed;
-+	u32 decided;
-+	u32 auditallow;
-+	u32 auditdeny;
-+	u32 seqno;
-+};
-+
-+int security_compute_av(u32 ssid, u32 tsid,
-+	u16 tclass, u32 requested,
-+	struct av_decision *avd);
-+
-+int security_transition_sid(u32 ssid, u32 tsid,
-+	u16 tclass, u32 *out_sid);
-+
-+int security_member_sid(u32 ssid, u32 tsid,
-+	u16 tclass, u32 *out_sid);
-+
-+int security_change_sid(u32 ssid, u32 tsid,
-+	u16 tclass, u32 *out_sid);
-+
-+int security_sid_to_context(u32 sid, char **scontext,
-+	u32 *scontext_len);
-+
-+int security_context_to_sid(char *scontext, u32 scontext_len,
-+	u32 *out_sid);
-+
-+int security_get_user_sids(u32 callsid, char *username,
-+			   u32 **sids, u32 *nel);
-+
-+int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
-+	u32 *out_sid);
-+
-+int security_netif_sid(char *name, u32 *if_sid,
-+	u32 *msg_sid);
-+
-+int security_node_sid(u16 domain, void *addr, u32 addrlen,
-+	u32 *out_sid);
-+
-+#define SECURITY_FS_USE_XATTR 1 /* use xattr */
-+#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
-+#define SECURITY_FS_USE_TASK  3 /* use task SIDs, e.g. pipefs/sockfs */
-+#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */
-+#define SECURITY_FS_USE_NONE  5 /* no labeling support */
-+int security_fs_use(const char *fstype, unsigned int *behavior,
-+	u32 *sid);
-+
-+int security_genfs_sid(const char *fstype, char *name, u16 sclass,
-+	u32 *sid);
-+
-+#endif /* _SELINUX_SECURITY_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/Kconfig	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,34 @@
-+config SECURITY_SELINUX
-+	bool "NSA SELinux Support"
-+	depends on SECURITY
-+	default n
-+	help
-+	  This enables NSA Security-Enhanced Linux (SELinux).
-+	  You will also need a policy configuration and a labeled filesystem.
-+	  You can obtain the policy compiler (checkpolicy), the utility for
-+	  labeling filesystems (setfiles), and an example policy configuration
-+	  from http://www.nsa.gov/selinux.
-+	  If you are unsure how to answer this question, answer N.
-+
-+config SECURITY_SELINUX_DEVELOP
-+	bool "NSA SELinux Development Support"
-+	depends on SECURITY_SELINUX
-+	default y
-+	help
-+	  This enables the development support option of NSA SELinux,
-+	  which is useful for experimenting with SELinux and developing
-+	  policies.  If unsure, say Y.  With this option enabled, the
-+	  kernel will start in permissive mode (log everything, deny nothing)
-+	  unless you specify enforcing=1 on the kernel command line.  You
-+	  can interactively toggle the kernel between enforcing mode and
-+	  permissive mode (if permitted by the policy) via /selinux/enforce.
-+
-+config SECURITY_SELINUX_MLS
-+	bool "NSA SELinux MLS policy (EXPERIMENTAL)"
-+	depends on SECURITY_SELINUX && EXPERIMENTAL
-+	default n
-+	help
-+	  This enables the NSA SELinux Multi-Level Security (MLS) policy in
-+	  addition to the default RBAC/TE policy.  This policy is
-+	  experimental and has not been configured for use.  Unless you
-+	  specifically want to experiment with MLS, say N.
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/Makefile	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for building the SELinux module as part of the kernel tree.
-+#
-+
-+obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
-+
-+selinux-objs := avc.o hooks.o selinuxfs.o
-+
-+EXTRA_CFLAGS += -Isecurity/selinux/include
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/selinuxfs.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,593 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/fs.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+#include <linux/security.h>
-+#include <asm/uaccess.h>
-+
-+/* selinuxfs pseudo filesystem for exporting the security policy API.
-+   Based on the proc code and the fs/nfsd/nfsctl.c code. */
-+
-+#include "flask.h"
-+#include "avc.h"
-+#include "avc_ss.h"
-+#include "security.h"
-+#include "objsec.h"
-+
-+/* Check whether a task is allowed to use a security operation. */
-+int task_has_security(struct task_struct *tsk,
-+		      u32 perms)
-+{
-+	struct task_security_struct *tsec;
-+
-+	tsec = tsk->security;
-+
-+	return avc_has_perm(tsec->sid, SECINITSID_SECURITY,
-+			    SECCLASS_SECURITY, perms, NULL, NULL);
-+}
-+
-+enum sel_inos {
-+	SEL_ROOT_INO = 2,
-+	SEL_LOAD,	/* load policy */
-+	SEL_ENFORCE,	/* get or set enforcing status */
-+	SEL_CONTEXT,	/* validate context */
-+	SEL_ACCESS,	/* compute access decision */
-+	SEL_CREATE,	/* compute create labeling decision */
-+	SEL_RELABEL,	/* compute relabeling decision */
-+	SEL_USER	/* compute reachable user contexts */
-+};
-+
-+static ssize_t sel_read_enforce(struct file *filp, char *buf,
-+				size_t count, loff_t *ppos)
-+{
-+	char *page;
-+	ssize_t length;
-+	ssize_t end;
-+
-+	if (count < 0 || count > PAGE_SIZE)
-+		return -EINVAL;
-+	if (!(page = (char*)__get_free_page(GFP_KERNEL)))
-+		return -ENOMEM;
-+	memset(page, 0, PAGE_SIZE);
-+
-+	length = snprintf(page, PAGE_SIZE, "%d", selinux_enforcing);
-+	if (length < 0) {
-+		free_page((unsigned long)page);
-+		return length;
-+	}
-+
-+	if (*ppos >= length) {
-+		free_page((unsigned long)page);
-+		return 0;
-+	}
-+	if (count + *ppos > length)
-+		count = length - *ppos;
-+	end = count + *ppos;
-+	if (copy_to_user(buf, (char *) page + *ppos, count)) {
-+		count = -EFAULT;
-+		goto out;
-+	}
-+	*ppos = end;
-+out:
-+	free_page((unsigned long)page);
-+	return count;
-+}
-+
-+#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-+static ssize_t sel_write_enforce(struct file * file, const char * buf,
-+				 size_t count, loff_t *ppos)
-+
-+{
-+	char *page;
-+	ssize_t length;
-+	int new_value;
-+
-+	if (count < 0 || count >= PAGE_SIZE)
-+		return -ENOMEM;
-+	if (*ppos != 0) {
-+		/* No partial writes. */
-+		return -EINVAL;
-+	}
-+	page = (char*)__get_free_page(GFP_KERNEL);
-+	if (!page)
-+		return -ENOMEM;
-+	memset(page, 0, PAGE_SIZE);
-+	length = -EFAULT;
-+	if (copy_from_user(page, buf, count))
-+		goto out;
-+
-+	length = -EINVAL;
-+	if (sscanf(page, "%d", &new_value) != 1)
-+		goto out;
-+
-+	if (new_value != selinux_enforcing) {
-+		length = task_has_security(current, SECURITY__SETENFORCE);
-+		if (length)
-+			goto out;
-+		selinux_enforcing = new_value;
-+		if (selinux_enforcing)
-+			avc_ss_reset(0);
-+	}
-+	length = count;
-+out:
-+	free_page((unsigned long) page);
-+	return length;
-+}
-+#else
-+#define sel_write_enforce NULL
-+#endif
-+
-+static struct file_operations sel_enforce_ops = {
-+	.read		= sel_read_enforce,
-+	.write		= sel_write_enforce,
-+};
-+
-+static ssize_t sel_write_load(struct file * file, const char * buf,
-+			      size_t count, loff_t *ppos)
-+
-+{
-+	ssize_t length;
-+	void *data;
-+
-+	length = task_has_security(current, SECURITY__LOAD_POLICY);
-+	if (length)
-+		return length;
-+
-+	if (*ppos != 0) {
-+		/* No partial writes. */
-+		return -EINVAL;
-+	}
-+
-+	if ((count < 0) || (count > 64 * 1024 * 1024) || (data = vmalloc(count)) == NULL)
-+		return -ENOMEM;
-+
-+	length = -EFAULT;
-+	if (copy_from_user(data, buf, count) != 0)
-+		goto out;
-+
-+	length = security_load_policy(data, count);
-+	if (length)
-+		goto out;
-+
-+	length = count;
-+out:
-+	vfree(data);
-+	return length;
-+}
-+
-+static struct file_operations sel_load_ops = {
-+	.write		= sel_write_load,
-+};
-+
-+
-+static ssize_t sel_write_context(struct file * file, const char * buf,
-+				 size_t count, loff_t *ppos)
-+
-+{
-+	char *page;
-+	u32 sid;
-+	ssize_t length;
-+
-+	length = task_has_security(current, SECURITY__CHECK_CONTEXT);
-+	if (length)
-+		return length;
-+
-+	if (count < 0 || count >= PAGE_SIZE)
-+		return -ENOMEM;
-+	if (*ppos != 0) {
-+		/* No partial writes. */
-+		return -EINVAL;
-+	}
-+	page = (char*)__get_free_page(GFP_KERNEL);
-+	if (!page)
-+		return -ENOMEM;
-+	memset(page, 0, PAGE_SIZE);
-+	length = -EFAULT;
-+	if (copy_from_user(page, buf, count))
-+		goto out;
-+
-+	length = security_context_to_sid(page, count, &sid);
-+	if (length < 0)
-+		goto out;
-+
-+	length = count;
-+out:
-+	free_page((unsigned long) page);
-+	return length;
-+}
-+
-+static struct file_operations sel_context_ops = {
-+	.write		= sel_write_context,
-+};
-+
-+
-+/*
-+ * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
-+ */
-+static ssize_t sel_write_access(struct file * file, char *buf, size_t size);
-+static ssize_t sel_write_create(struct file * file, char *buf, size_t size);
-+static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size);
-+static ssize_t sel_write_user(struct file * file, char *buf, size_t size);
-+
-+static ssize_t (*write_op[])(struct file *, char *, size_t) = {
-+	[SEL_ACCESS] = sel_write_access,
-+	[SEL_CREATE] = sel_write_create,
-+	[SEL_RELABEL] = sel_write_relabel,
-+	[SEL_USER] = sel_write_user,
-+};
-+
-+/* an argresp is stored in an allocated page and holds the
-+ * size of the argument or response, along with its content
-+ */
-+struct argresp {
-+	ssize_t size;
-+	char data[0];
-+};
-+
-+#define PAYLOAD_SIZE (PAGE_SIZE - sizeof(struct argresp))
-+
-+/*
-+ * transaction based IO methods.
-+ * The file expects a single write which triggers the transaction, and then
-+ * possibly a read which collects the result - which is stored in a
-+ * file-local buffer.
-+ */
-+static ssize_t TA_write(struct file *file, const char *buf, size_t size, loff_t *pos)
-+{
-+	ino_t ino =  file->f_dentry->d_inode->i_ino;
-+	struct argresp *ar;
-+	ssize_t rv = 0;
-+
-+	if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
-+		return -EINVAL;
-+	if (file->private_data)
-+		return -EINVAL; /* only one write allowed per open */
-+	if (size > PAYLOAD_SIZE - 1) /* allow one byte for null terminator */
-+		return -EFBIG;
-+
-+	ar = kmalloc(PAGE_SIZE, GFP_KERNEL);
-+	if (!ar)
-+		return -ENOMEM;
-+	memset(ar, 0, PAGE_SIZE); /* clear buffer, particularly last byte */
-+	ar->size = 0;
-+	down(&file->f_dentry->d_inode->i_sem);
-+	if (file->private_data)
-+		rv = -EINVAL;
-+	else
-+		file->private_data = ar;
-+	up(&file->f_dentry->d_inode->i_sem);
-+	if (rv) {
-+		kfree(ar);
-+		return rv;
-+	}
-+	if (copy_from_user(ar->data, buf, size))
-+		return -EFAULT;
-+
-+	rv =  write_op[ino](file, ar->data, size);
-+	if (rv>0) {
-+		ar->size = rv;
-+		rv = size;
-+	}
-+	return rv;
-+}
-+
-+static ssize_t TA_read(struct file *file, char *buf, size_t size, loff_t *pos)
-+{
-+	struct argresp *ar;
-+	ssize_t rv = 0;
-+
-+	if (file->private_data == NULL)
-+		rv = TA_write(file, buf, 0, pos);
-+	if (rv < 0)
-+		return rv;
-+
-+	ar = file->private_data;
-+	if (!ar)
-+		return 0;
-+	if (*pos >= ar->size)
-+		return 0;
-+	if (*pos + size > ar->size)
-+		size = ar->size - *pos;
-+	if (copy_to_user(buf, ar->data + *pos, size))
-+		return -EFAULT;
-+	*pos += size;
-+	return size;
-+}
-+
-+static int TA_open(struct inode *inode, struct file *file)
-+{
-+	file->private_data = NULL;
-+	return 0;
-+}
-+
-+static int TA_release(struct inode *inode, struct file *file)
-+{
-+	void *p = file->private_data;
-+	file->private_data = NULL;
-+	kfree(p);
-+	return 0;
-+}
-+
-+static struct file_operations transaction_ops = {
-+	.write		= TA_write,
-+	.read		= TA_read,
-+	.open		= TA_open,
-+	.release	= TA_release,
-+};
-+
-+/*
-+ * payload - write methods
-+ * If the method has a response, the response should be put in buf,
-+ * and the length returned.  Otherwise return 0 or and -error.
-+ */
-+
-+static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
-+{
-+	char *scon, *tcon;
-+	u32 ssid, tsid;
-+	u16 tclass;
-+	u32 req;
-+	struct av_decision avd;
-+	ssize_t length;
-+
-+	length = task_has_security(current, SECURITY__COMPUTE_AV);
-+	if (length)
-+		return length;
-+
-+	length = -ENOMEM;
-+	scon = kmalloc(size+1, GFP_KERNEL);
-+	if (!scon)
-+		return length;
-+	memset(scon, 0, size+1);
-+
-+	tcon = kmalloc(size+1, GFP_KERNEL);
-+	if (!tcon)
-+		goto out;
-+	memset(tcon, 0, size+1);
-+
-+	length = -EINVAL;
-+	if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
-+		goto out2;
-+
-+	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-+	if (length < 0)
-+		goto out2;
-+	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_compute_av(ssid, tsid, tclass, req, &avd);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = snprintf(buf, PAYLOAD_SIZE, "%x %x %x %x %u",
-+			  avd.allowed, avd.decided,
-+			  avd.auditallow, avd.auditdeny,
-+			  avd.seqno);
-+out2:
-+	kfree(tcon);
-+out:
-+	kfree(scon);
-+	return length;
-+}
-+
-+static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
-+{
-+	char *scon, *tcon;
-+	u32 ssid, tsid, newsid;
-+	u16 tclass;
-+	ssize_t length;
-+	char *newcon;
-+	u32 len;
-+
-+	length = task_has_security(current, SECURITY__COMPUTE_CREATE);
-+	if (length)
-+		return length;
-+
-+	length = -ENOMEM;
-+	scon = kmalloc(size+1, GFP_KERNEL);
-+	if (!scon)
-+		return length;
-+	memset(scon, 0, size+1);
-+
-+	tcon = kmalloc(size+1, GFP_KERNEL);
-+	if (!tcon)
-+		goto out;
-+	memset(tcon, 0, size+1);
-+
-+	length = -EINVAL;
-+	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
-+		goto out2;
-+
-+	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-+	if (length < 0)
-+		goto out2;
-+	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_transition_sid(ssid, tsid, tclass, &newsid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_sid_to_context(newsid, &newcon, &len);
-+	if (length < 0)
-+		goto out2;
-+
-+	if (len > PAYLOAD_SIZE) {
-+		printk(KERN_ERR "%s:  context size (%u) exceeds payload "
-+		       "max\n", __FUNCTION__, len);
-+		length = -ERANGE;
-+		goto out3;
-+	}
-+
-+	memcpy(buf, newcon, len);
-+	length = len;
-+out3:
-+	kfree(newcon);
-+out2:
-+	kfree(tcon);
-+out:
-+	kfree(scon);
-+	return length;
-+}
-+
-+static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
-+{
-+	char *scon, *tcon;
-+	u32 ssid, tsid, newsid;
-+	u16 tclass;
-+	ssize_t length;
-+	char *newcon;
-+	u32 len;
-+
-+	length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
-+	if (length)
-+		return length;
-+
-+	length = -ENOMEM;
-+	scon = kmalloc(size+1, GFP_KERNEL);
-+	if (!scon)
-+		return length;
-+	memset(scon, 0, size+1);
-+
-+	tcon = kmalloc(size+1, GFP_KERNEL);
-+	if (!tcon)
-+		goto out;
-+	memset(tcon, 0, size+1);
-+
-+	length = -EINVAL;
-+	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
-+		goto out2;
-+
-+	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-+	if (length < 0)
-+		goto out2;
-+	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_change_sid(ssid, tsid, tclass, &newsid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_sid_to_context(newsid, &newcon, &len);
-+	if (length < 0)
-+		goto out2;
-+
-+	if (len > PAYLOAD_SIZE) {
-+		length = -ERANGE;
-+		goto out3;
-+	}
-+
-+	memcpy(buf, newcon, len);
-+	length = len;
-+out3:
-+	kfree(newcon);
-+out2:
-+	kfree(tcon);
-+out:
-+	kfree(scon);
-+	return length;
-+}
-+
-+static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
-+{
-+	char *con, *user, *ptr;
-+	u32 sid, *sids;
-+	ssize_t length;
-+	char *newcon;
-+	int i, rc;
-+	u32 len, nsids;
-+
-+	length = task_has_security(current, SECURITY__COMPUTE_USER);
-+	if (length)
-+		return length;
-+
-+	length = -ENOMEM;
-+	con = kmalloc(size+1, GFP_KERNEL);
-+	if (!con)
-+		return length;
-+	memset(con, 0, size+1);
-+
-+	user = kmalloc(size+1, GFP_KERNEL);
-+	if (!user)
-+		goto out;
-+	memset(user, 0, size+1);
-+
-+	length = -EINVAL;
-+	if (sscanf(buf, "%s %s", con, user) != 2)
-+		goto out2;
-+
-+	length = security_context_to_sid(con, strlen(con)+1, &sid);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = security_get_user_sids(sid, user, &sids, &nsids);
-+	if (length < 0)
-+		goto out2;
-+
-+	length = sprintf(buf, "%u", nsids) + 1;
-+	ptr = buf + length;
-+	for (i = 0; i < nsids; i++) {
-+		rc = security_sid_to_context(sids[i], &newcon, &len);
-+		if (rc) {
-+			length = rc;
-+			goto out3;
-+		}
-+		if ((length + len) >= PAYLOAD_SIZE) {
-+			kfree(newcon);
-+			length = -ERANGE;
-+			goto out3;
-+		}
-+		memcpy(ptr, newcon, len);
-+		kfree(newcon);
-+		ptr += len;
-+		length += len;
-+	}
-+out3:
-+	kfree(sids);
-+out2:
-+	kfree(user);
-+out:
-+	kfree(con);
-+	return length;
-+}
-+
-+
-+static int sel_fill_super(struct super_block * sb, void * data, int silent)
-+{
-+	static struct tree_descr selinux_files[] = {
-+		[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
-+		[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUSR|S_IWUSR},
-+		[SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO},
-+		[SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
-+		[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
-+		[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
-+		[SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
-+		/* last one */ {""}
-+	};
-+	return simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
-+}
-+
-+static struct super_block *sel_get_sb(struct file_system_type *fs_type,
-+				      int flags, const char *dev_name, void *data)
-+{
-+	return get_sb_single(fs_type, flags, data, sel_fill_super);
-+}
-+
-+static struct file_system_type sel_fs_type = {
-+	.name		= "selinuxfs",
-+	.get_sb		= sel_get_sb,
-+	.kill_sb	= kill_litter_super,
-+};
-+
-+static int __init init_sel_fs(void)
-+{
-+	return register_filesystem(&sel_fs_type);
-+}
-+
-+__initcall(init_sel_fs);
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/avtab.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,264 @@
-+/*
-+ * Implementation of the access vector table type.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "avtab.h"
-+#include "policydb.h"
-+
-+#define AVTAB_HASH(keyp) \
-+((keyp->target_class + \
-+ (keyp->target_type << 2) + \
-+ (keyp->source_type << 9)) & \
-+ AVTAB_HASH_MASK)
-+
-+int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum)
-+{
-+	int hvalue;
-+	struct avtab_node *prev, *cur, *newnode;
-+
-+	if (!h)
-+		return -EINVAL;
-+
-+	hvalue = AVTAB_HASH(key);
-+	for (prev = NULL, cur = h->htable[hvalue];
-+	     cur;
-+	     prev = cur, cur = cur->next) {
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type == cur->key.target_type &&
-+		    key->target_class == cur->key.target_class &&
-+		    (datum->specified & cur->datum.specified))
-+			return -EEXIST;
-+		if (key->source_type < cur->key.source_type)
-+			break;
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type < cur->key.target_type)
-+			break;
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type == cur->key.target_type &&
-+		    key->target_class < cur->key.target_class)
-+			break;
-+	}
-+
-+	newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
-+	if (newnode == NULL)
-+		return -ENOMEM;
-+	memset(newnode, 0, sizeof(*newnode));
-+	newnode->key = *key;
-+	newnode->datum = *datum;
-+	if (prev) {
-+		newnode->next = prev->next;
-+		prev->next = newnode;
-+	} else {
-+		newnode->next = h->htable[hvalue];
-+		h->htable[hvalue] = newnode;
-+	}
-+
-+	h->nel++;
-+	return 0;
-+}
-+
-+
-+struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified)
-+{
-+	int hvalue;
-+	struct avtab_node *cur;
-+
-+	if (!h)
-+		return NULL;
-+
-+	hvalue = AVTAB_HASH(key);
-+	for (cur = h->htable[hvalue]; cur; cur = cur->next) {
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type == cur->key.target_type &&
-+		    key->target_class == cur->key.target_class &&
-+		    (specified & cur->datum.specified))
-+			return &cur->datum;
-+
-+		if (key->source_type < cur->key.source_type)
-+			break;
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type < cur->key.target_type)
-+			break;
-+		if (key->source_type == cur->key.source_type &&
-+		    key->target_type == cur->key.target_type &&
-+		    key->target_class < cur->key.target_class)
-+			break;
-+	}
-+
-+	return NULL;
-+}
-+
-+void avtab_destroy(struct avtab *h)
-+{
-+	int i;
-+	struct avtab_node *cur, *temp;
-+
-+	if (!h)
-+		return;
-+
-+	for (i = 0; i < AVTAB_SIZE; i++) {
-+		cur = h->htable[i];
-+		while (cur != NULL) {
-+			temp = cur;
-+			cur = cur->next;
-+			kfree(temp);
-+		}
-+		h->htable[i] = NULL;
-+	}
-+	kfree(h->htable);
-+}
-+
-+
-+int avtab_map(struct avtab *h,
-+	      int (*apply) (struct avtab_key *k,
-+			    struct avtab_datum *d,
-+			    void *args),
-+	      void *args)
-+{
-+	int i, ret;
-+	struct avtab_node *cur;
-+
-+	if (!h)
-+		return 0;
-+
-+	for (i = 0; i < AVTAB_SIZE; i++) {
-+		cur = h->htable[i];
-+		while (cur != NULL) {
-+			ret = apply(&cur->key, &cur->datum, args);
-+			if (ret)
-+				return ret;
-+			cur = cur->next;
-+		}
-+	}
-+	return 0;
-+}
-+
-+int avtab_init(struct avtab *h)
-+{
-+	int i;
-+
-+	h->htable = kmalloc(sizeof(*(h->htable)) * AVTAB_SIZE, GFP_KERNEL);
-+	if (!h->htable)
-+		return -ENOMEM;
-+	for (i = 0; i < AVTAB_SIZE; i++)
-+		h->htable[i] = NULL;
-+	h->nel = 0;
-+	return 0;
-+}
-+
-+void avtab_hash_eval(struct avtab *h, char *tag)
-+{
-+	int i, chain_len, slots_used, max_chain_len;
-+	struct avtab_node *cur;
-+
-+	slots_used = 0;
-+	max_chain_len = 0;
-+	for (i = 0; i < AVTAB_SIZE; i++) {
-+		cur = h->htable[i];
-+		if (cur) {
-+			slots_used++;
-+			chain_len = 0;
-+			while (cur) {
-+				chain_len++;
-+				cur = cur->next;
-+			}
-+
-+			if (chain_len > max_chain_len)
-+				max_chain_len = chain_len;
-+		}
-+	}
-+
-+	printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
-+	       "chain length %d\n", tag, h->nel, slots_used, AVTAB_SIZE,
-+	       max_chain_len);
-+}
-+
-+int avtab_read(struct avtab *a, void *fp, u32 config)
-+{
-+	int i, rc = -EINVAL;
-+	struct avtab_key avkey;
-+	struct avtab_datum avdatum;
-+	u32 *buf;
-+	u32 nel, items, items2;
-+
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		printk(KERN_ERR "security: avtab: truncated table\n");
-+		goto bad;
-+	}
-+	nel = le32_to_cpu(buf[0]);
-+	if (!nel) {
-+		printk(KERN_ERR "security: avtab: table is empty\n");
-+		goto bad;
-+	}
-+	for (i = 0; i < nel; i++) {
-+		memset(&avkey, 0, sizeof(avkey));
-+		memset(&avdatum, 0, sizeof(avdatum));
-+
-+		buf = next_entry(fp, sizeof(u32));
-+		if (!buf) {
-+			printk(KERN_ERR "security: avtab: truncated entry\n");
-+			goto bad;
-+		}
-+		items2 = le32_to_cpu(buf[0]);
-+		buf = next_entry(fp, sizeof(u32)*items2);
-+		if (!buf) {
-+			printk(KERN_ERR "security: avtab: truncated entry\n");
-+			goto bad;
-+		}
-+		items = 0;
-+		avkey.source_type = le32_to_cpu(buf[items++]);
-+		avkey.target_type = le32_to_cpu(buf[items++]);
-+		avkey.target_class = le32_to_cpu(buf[items++]);
-+		avdatum.specified = le32_to_cpu(buf[items++]);
-+		if (!(avdatum.specified & (AVTAB_AV | AVTAB_TYPE))) {
-+			printk(KERN_ERR "security: avtab: null entry\n");
-+			goto bad;
-+		}
-+		if ((avdatum.specified & AVTAB_AV) &&
-+		    (avdatum.specified & AVTAB_TYPE)) {
-+			printk(KERN_ERR "security: avtab: entry has both "
-+			       "access vectors and types\n");
-+			goto bad;
-+		}
-+		if (avdatum.specified & AVTAB_AV) {
-+			if (avdatum.specified & AVTAB_ALLOWED)
-+				avtab_allowed(&avdatum) = le32_to_cpu(buf[items++]);
-+			if (avdatum.specified & AVTAB_AUDITDENY)
-+				avtab_auditdeny(&avdatum) = le32_to_cpu(buf[items++]);
-+			if (avdatum.specified & AVTAB_AUDITALLOW)
-+				avtab_auditallow(&avdatum) = le32_to_cpu(buf[items++]);
-+		} else {
-+			if (avdatum.specified & AVTAB_TRANSITION)
-+				avtab_transition(&avdatum) = le32_to_cpu(buf[items++]);
-+			if (avdatum.specified & AVTAB_CHANGE)
-+				avtab_change(&avdatum) = le32_to_cpu(buf[items++]);
-+			if (avdatum.specified & AVTAB_MEMBER)
-+				avtab_member(&avdatum) = le32_to_cpu(buf[items++]);
-+		}
-+		if (items != items2) {
-+			printk(KERN_ERR "security: avtab: entry only had %d "
-+			       "items, expected %d\n", items2, items);
-+			goto bad;
-+		}
-+		rc = avtab_insert(a, &avkey, &avdatum);
-+		if (rc) {
-+			if (rc == -ENOMEM)
-+				printk(KERN_ERR "security: avtab: out of memory\n");
-+			if (rc == -EEXIST)
-+				printk(KERN_ERR "security: avtab: duplicate entry\n");
-+			goto bad;
-+		}
-+	}
-+
-+	rc = 0;
-+out:
-+	return rc;
-+
-+bad:
-+	avtab_destroy(a);
-+	goto out;
-+}
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/avtab.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,68 @@
-+/*
-+ * An access vector table (avtab) is a hash table
-+ * of access vectors and transition types indexed
-+ * by a type pair and a class.  An access vector
-+ * table is used to represent the type enforcement
-+ * tables.
-+ *
-+ *  Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_AVTAB_H_
-+#define _SS_AVTAB_H_
-+
-+struct avtab_key {
-+	u32 source_type;	/* source type */
-+	u32 target_type;	/* target type */
-+	u32 target_class;	/* target object class */
-+};
-+
-+struct avtab_datum {
-+#define AVTAB_ALLOWED     1
-+#define AVTAB_AUDITALLOW  2
-+#define AVTAB_AUDITDENY   4
-+#define AVTAB_AV         (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)
-+#define AVTAB_TRANSITION 16
-+#define AVTAB_MEMBER     32
-+#define AVTAB_CHANGE     64
-+#define AVTAB_TYPE       (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
-+	u32 specified;	/* what fields are specified */
-+	u32 data[3];	/* access vectors or types */
-+#define avtab_allowed(x) (x)->data[0]
-+#define avtab_auditdeny(x) (x)->data[1]
-+#define avtab_auditallow(x) (x)->data[2]
-+#define avtab_transition(x) (x)->data[0]
-+#define avtab_change(x) (x)->data[1]
-+#define avtab_member(x) (x)->data[2]
-+};
-+
-+struct avtab_node {
-+	struct avtab_key key;
-+	struct avtab_datum datum;
-+	struct avtab_node *next;
-+};
-+
-+struct avtab {
-+	struct avtab_node **htable;
-+	u32 nel;	/* number of elements */
-+};
-+
-+int avtab_init(struct avtab *);
-+int avtab_insert(struct avtab *h, struct avtab_key *k, struct avtab_datum *d);
-+struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k, int specified);
-+void avtab_destroy(struct avtab *h);
-+int avtab_map(struct avtab *h,
-+	      int (*apply) (struct avtab_key *k,
-+			    struct avtab_datum *d,
-+			    void *args),
-+	      void *args);
-+void avtab_hash_eval(struct avtab *h, char *tag);
-+int avtab_read(struct avtab *a, void *fp, u32 config);
-+
-+#define AVTAB_HASH_BITS 15
-+#define AVTAB_HASH_BUCKETS (1 << AVTAB_HASH_BITS)
-+#define AVTAB_HASH_MASK (AVTAB_HASH_BUCKETS-1)
-+
-+#define AVTAB_SIZE AVTAB_HASH_BUCKETS
-+
-+#endif	/* _SS_AVTAB_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/constraint.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,54 @@
-+/*
-+ * A constraint is a condition that must be satisfied in
-+ * order for one or more permissions to be granted.
-+ * Constraints are used to impose additional restrictions
-+ * beyond the type-based rules in `te' or the role-based
-+ * transition rules in `rbac'.  Constraints are typically
-+ * used to prevent a process from transitioning to a new user
-+ * identity or role unless it is in a privileged type.
-+ * Constraints are likewise typically used to prevent a
-+ * process from labeling an object with a different user
-+ * identity.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_CONSTRAINT_H_
-+#define _SS_CONSTRAINT_H_
-+
-+#include "ebitmap.h"
-+
-+#define CEXPR_MAXDEPTH 5
-+
-+struct constraint_expr {
-+#define CEXPR_NOT		1 /* not expr */
-+#define CEXPR_AND		2 /* expr and expr */
-+#define CEXPR_OR		3 /* expr or expr */
-+#define CEXPR_ATTR		4 /* attr op attr */
-+#define CEXPR_NAMES		5 /* attr op names */
-+	u32 expr_type;		/* expression type */
-+
-+#define CEXPR_USER 1		/* user */
-+#define CEXPR_ROLE 2		/* role */
-+#define CEXPR_TYPE 4		/* type */
-+#define CEXPR_TARGET 8		/* target if set, source otherwise */
-+	u32 attr;		/* attribute */
-+
-+#define CEXPR_EQ     1		/* == or eq */
-+#define CEXPR_NEQ    2		/* != */
-+#define CEXPR_DOM    3		/* dom */
-+#define CEXPR_DOMBY  4		/* domby  */
-+#define CEXPR_INCOMP 5		/* incomp */
-+	u32 op;			/* operator */
-+
-+	struct ebitmap names;	/* names */
-+
-+	struct constraint_expr *next;   /* next expression */
-+};
-+
-+struct constraint_node {
-+	u32 permissions;	/* constrained permissions */
-+	struct constraint_expr *expr;	/* constraint on permissions */
-+	struct constraint_node *next;	/* next constraint */
-+};
-+
-+#endif	/* _SS_CONSTRAINT_H_ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/context.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,117 @@
-+/*
-+ * A security context is a set of security attributes
-+ * associated with each subject and object controlled
-+ * by the security policy.  Security contexts are
-+  * externally represented as variable-length strings
-+ * that can be interpreted by a user or application
-+ * with an understanding of the security policy.
-+ * Internally, the security server uses a simple
-+ * structure.  This structure is private to the
-+ * security server and can be changed without affecting
-+ * clients of the security server.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_CONTEXT_H_
-+#define _SS_CONTEXT_H_
-+
-+#include "ebitmap.h"
-+#include "mls_types.h"
-+
-+/*
-+ * A security context consists of an authenticated user
-+ * identity, a role, a type and a MLS range.
-+ */
-+struct context {
-+	u32 user;
-+	u32 role;
-+	u32 type;
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+	struct mls_range range;
-+#endif
-+};
-+
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+
-+static inline void mls_context_init(struct context *c)
-+{
-+	memset(&c->range, 0, sizeof(c->range));
-+}
-+
-+static inline int mls_context_cpy(struct context *dst, struct context *src)
-+{
-+	int rc;
-+
-+	dst->range.level[0].sens = src->range.level[0].sens;
-+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
-+	if (rc)
-+		goto out;
-+
-+	dst->range.level[1].sens = src->range.level[1].sens;
-+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
-+	if (rc)
-+		ebitmap_destroy(&dst->range.level[0].cat);
-+out:
-+	return rc;
-+}
-+
-+static inline int mls_context_cmp(struct context *c1, struct context *c2)
-+{
-+	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
-+		ebitmap_cmp(&c1->range.level[0].cat,&c2->range.level[0].cat) &&
-+		(c1->range.level[1].sens == c2->range.level[1].sens) &&
-+		ebitmap_cmp(&c1->range.level[1].cat,&c2->range.level[1].cat));
-+}
-+
-+static inline void mls_context_destroy(struct context *c)
-+{
-+	ebitmap_destroy(&c->range.level[0].cat);
-+	ebitmap_destroy(&c->range.level[1].cat);
-+	mls_context_init(c);
-+}
-+
-+#else
-+
-+static inline void mls_context_init(struct context *c)
-+{ }
-+
-+static inline int mls_context_cpy(struct context *dst, struct context *src)
-+{ return 0; }
-+
-+static inline int mls_context_cmp(struct context *c1, struct context *c2)
-+{ return 1; }
-+
-+static inline void mls_context_destroy(struct context *c)
-+{ }
-+
-+#endif
-+
-+static inline void context_init(struct context *c)
-+{
-+	memset(c, 0, sizeof(*c));
-+}
-+
-+static inline int context_cpy(struct context *dst, struct context *src)
-+{
-+	dst->user = src->user;
-+	dst->role = src->role;
-+	dst->type = src->type;
-+	return mls_context_cpy(dst, src);
-+}
-+
-+static inline void context_destroy(struct context *c)
-+{
-+	c->user = c->role = c->type = 0;
-+	mls_context_destroy(c);
-+}
-+
-+static inline int context_cmp(struct context *c1, struct context *c2)
-+{
-+	return ((c1->user == c2->user) &&
-+		(c1->role == c2->role) &&
-+		(c1->type == c2->type) &&
-+		mls_context_cmp(c1, c2));
-+}
-+
-+#endif	/* _SS_CONTEXT_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/ebitmap.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,332 @@
-+/*
-+ * Implementation of the extensible bitmap type.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "ebitmap.h"
-+#include "policydb.h"
-+
-+int ebitmap_or(struct ebitmap *dst, struct ebitmap *e1, struct ebitmap *e2)
-+{
-+	struct ebitmap_node *n1, *n2, *new, *prev;
-+
-+	ebitmap_init(dst);
-+
-+	n1 = e1->node;
-+	n2 = e2->node;
-+	prev = 0;
-+	while (n1 || n2) {
-+		new = kmalloc(sizeof(*new), GFP_ATOMIC);
-+		if (!new) {
-+			ebitmap_destroy(dst);
-+			return -ENOMEM;
-+		}
-+		memset(new, 0, sizeof(*new));
-+		if (n1 && n2 && n1->startbit == n2->startbit) {
-+			new->startbit = n1->startbit;
-+			new->map = n1->map | n2->map;
-+			n1 = n1->next;
-+			n2 = n2->next;
-+		} else if (!n2 || (n1 && n1->startbit < n2->startbit)) {
-+			new->startbit = n1->startbit;
-+			new->map = n1->map;
-+			n1 = n1->next;
-+		} else {
-+			new->startbit = n2->startbit;
-+			new->map = n2->map;
-+			n2 = n2->next;
-+		}
-+
-+		new->next = 0;
-+		if (prev)
-+			prev->next = new;
-+		else
-+			dst->node = new;
-+		prev = new;
-+	}
-+
-+	dst->highbit = (e1->highbit > e2->highbit) ? e1->highbit : e2->highbit;
-+	return 0;
-+}
-+
-+int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
-+{
-+	struct ebitmap_node *n1, *n2;
-+
-+	if (e1->highbit != e2->highbit)
-+		return 0;
-+
-+	n1 = e1->node;
-+	n2 = e2->node;
-+	while (n1 && n2 &&
-+	       (n1->startbit == n2->startbit) &&
-+	       (n1->map == n2->map)) {
-+		n1 = n1->next;
-+		n2 = n2->next;
-+	}
-+
-+	if (n1 || n2)
-+		return 0;
-+
-+	return 1;
-+}
-+
-+int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
-+{
-+	struct ebitmap_node *n, *new, *prev;
-+
-+	ebitmap_init(dst);
-+	n = src->node;
-+	prev = 0;
-+	while (n) {
-+		new = kmalloc(sizeof(*new), GFP_ATOMIC);
-+		if (!new) {
-+			ebitmap_destroy(dst);
-+			return -ENOMEM;
-+		}
-+		memset(new, 0, sizeof(*new));
-+		new->startbit = n->startbit;
-+		new->map = n->map;
-+		new->next = 0;
-+		if (prev)
-+			prev->next = new;
-+		else
-+			dst->node = new;
-+		prev = new;
-+		n = n->next;
-+	}
-+
-+	dst->highbit = src->highbit;
-+	return 0;
-+}
-+
-+int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
-+{
-+	struct ebitmap_node *n1, *n2;
-+
-+	if (e1->highbit < e2->highbit)
-+		return 0;
-+
-+	n1 = e1->node;
-+	n2 = e2->node;
-+	while (n1 && n2 && (n1->startbit <= n2->startbit)) {
-+		if (n1->startbit < n2->startbit) {
-+			n1 = n1->next;
-+			continue;
-+		}
-+		if ((n1->map & n2->map) != n2->map)
-+			return 0;
-+
-+		n1 = n1->next;
-+		n2 = n2->next;
-+	}
-+
-+	if (n2)
-+		return 0;
-+
-+	return 1;
-+}
-+
-+int ebitmap_get_bit(struct ebitmap *e, unsigned long bit)
-+{
-+	struct ebitmap_node *n;
-+
-+	if (e->highbit < bit)
-+		return 0;
-+
-+	n = e->node;
-+	while (n && (n->startbit <= bit)) {
-+		if ((n->startbit + MAPSIZE) > bit) {
-+			if (n->map & (MAPBIT << (bit - n->startbit)))
-+				return 1;
-+			else
-+				return 0;
-+		}
-+		n = n->next;
-+	}
-+
-+	return 0;
-+}
-+
-+int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
-+{
-+	struct ebitmap_node *n, *prev, *new;
-+
-+	prev = 0;
-+	n = e->node;
-+	while (n && n->startbit <= bit) {
-+		if ((n->startbit + MAPSIZE) > bit) {
-+			if (value) {
-+				n->map |= (MAPBIT << (bit - n->startbit));
-+			} else {
-+				n->map &= ~(MAPBIT << (bit - n->startbit));
-+				if (!n->map) {
-+					/* drop this node from the bitmap */
-+
-+					if (!n->next) {
-+						/*
-+						 * this was the highest map
-+						 * within the bitmap
-+						 */
-+						if (prev)
-+							e->highbit = prev->startbit + MAPSIZE;
-+						else
-+							e->highbit = 0;
-+					}
-+					if (prev)
-+						prev->next = n->next;
-+					else
-+						e->node = n->next;
-+
-+					kfree(n);
-+				}
-+			}
-+			return 0;
-+		}
-+		prev = n;
-+		n = n->next;
-+	}
-+
-+	if (!value)
-+		return 0;
-+
-+	new = kmalloc(sizeof(*new), GFP_ATOMIC);
-+	if (!new)
-+		return -ENOMEM;
-+	memset(new, 0, sizeof(*new));
-+
-+	new->startbit = bit & ~(MAPSIZE - 1);
-+	new->map = (MAPBIT << (bit - new->startbit));
-+
-+	if (!n)
-+		/* this node will be the highest map within the bitmap */
-+		e->highbit = new->startbit + MAPSIZE;
-+
-+	if (prev) {
-+		new->next = prev->next;
-+		prev->next = new;
-+	} else {
-+		new->next = e->node;
-+		e->node = new;
-+	}
-+
-+	return 0;
-+}
-+
-+void ebitmap_destroy(struct ebitmap *e)
-+{
-+	struct ebitmap_node *n, *temp;
-+
-+	if (!e)
-+		return;
-+
-+	n = e->node;
-+	while (n) {
-+		temp = n;
-+		n = n->next;
-+		kfree(temp);
-+	}
-+
-+	e->highbit = 0;
-+	e->node = 0;
-+	return;
-+}
-+
-+int ebitmap_read(struct ebitmap *e, void *fp)
-+{
-+	int rc = -EINVAL;
-+	struct ebitmap_node *n, *l;
-+	u32 *buf, mapsize, count, i;
-+	u64 map;
-+
-+	ebitmap_init(e);
-+
-+	buf = next_entry(fp, sizeof(u32)*3);
-+	if (!buf)
-+		goto out;
-+
-+	mapsize = le32_to_cpu(buf[0]);
-+	e->highbit = le32_to_cpu(buf[1]);
-+	count = le32_to_cpu(buf[2]);
-+
-+	if (mapsize != MAPSIZE) {
-+		printk(KERN_ERR "security: ebitmap: map size %d does not "
-+		       "match my size %d (high bit was %d)\n", mapsize,
-+		       MAPSIZE, e->highbit);
-+		goto out;
-+	}
-+	if (!e->highbit) {
-+		e->node = NULL;
-+		goto ok;
-+	}
-+	if (e->highbit & (MAPSIZE - 1)) {
-+		printk(KERN_ERR "security: ebitmap: high bit (%d) is not a "
-+		       "multiple of the map size (%d)\n", e->highbit, MAPSIZE);
-+		goto bad;
-+	}
-+	l = NULL;
-+	for (i = 0; i < count; i++) {
-+		buf = next_entry(fp, sizeof(u32));
-+		if (!buf) {
-+			printk(KERN_ERR "security: ebitmap: truncated map\n");
-+			goto bad;
-+		}
-+		n = kmalloc(sizeof(*n), GFP_KERNEL);
-+		if (!n) {
-+			printk(KERN_ERR "security: ebitmap: out of memory\n");
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memset(n, 0, sizeof(*n));
-+
-+		n->startbit = le32_to_cpu(buf[0]);
-+
-+		if (n->startbit & (MAPSIZE - 1)) {
-+			printk(KERN_ERR "security: ebitmap start bit (%d) is "
-+			       "not a multiple of the map size (%d)\n",
-+			       n->startbit, MAPSIZE);
-+			goto bad_free;
-+		}
-+		if (n->startbit > (e->highbit - MAPSIZE)) {
-+			printk(KERN_ERR "security: ebitmap start bit (%d) is "
-+			       "beyond the end of the bitmap (%d)\n",
-+			       n->startbit, (e->highbit - MAPSIZE));
-+			goto bad_free;
-+		}
-+		buf = next_entry(fp, sizeof(u64));
-+		if (!buf) {
-+			printk(KERN_ERR "security: ebitmap: truncated map\n");
-+			goto bad_free;
-+		}
-+		memcpy(&map, buf, sizeof(u64));
-+		n->map = le64_to_cpu(map);
-+
-+		if (!n->map) {
-+			printk(KERN_ERR "security: ebitmap: null map in "
-+			       "ebitmap (startbit %d)\n", n->startbit);
-+			goto bad_free;
-+		}
-+		if (l) {
-+			if (n->startbit <= l->startbit) {
-+				printk(KERN_ERR "security: ebitmap: start "
-+				       "bit %d comes after start bit %d\n",
-+				       n->startbit, l->startbit);
-+				goto bad_free;
-+			}
-+			l->next = n;
-+		} else
-+			e->node = n;
-+
-+		l = n;
-+	}
-+
-+ok:
-+	rc = 0;
-+out:
-+	return rc;
-+bad_free:
-+	kfree(n);
-+bad:
-+	ebitmap_destroy(e);
-+	goto out;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/ebitmap.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,49 @@
-+/*
-+ * An extensible bitmap is a bitmap that supports an
-+ * arbitrary number of bits.  Extensible bitmaps are
-+ * used to represent sets of values, such as types,
-+ * roles, categories, and classes.
-+ *
-+ * Each extensible bitmap is implemented as a linked
-+ * list of bitmap nodes, where each bitmap node has
-+ * an explicitly specified starting bit position within
-+ * the total bitmap.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_EBITMAP_H_
-+#define _SS_EBITMAP_H_
-+
-+#define MAPTYPE u64			/* portion of bitmap in each node */
-+#define MAPSIZE (sizeof(MAPTYPE) * 8)	/* number of bits in node bitmap */
-+#define MAPBIT  1ULL			/* a bit in the node bitmap */
-+
-+struct ebitmap_node {
-+	u32 startbit;		/* starting position in the total bitmap */
-+	MAPTYPE map;		/* this node's portion of the bitmap */
-+	struct ebitmap_node *next;
-+};
-+
-+struct ebitmap {
-+	struct ebitmap_node *node;	/* first node in the bitmap */
-+	u32 highbit;	/* highest position in the total bitmap */
-+};
-+
-+#define ebitmap_length(e) ((e)->highbit)
-+#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
-+
-+static inline void ebitmap_init(struct ebitmap *e)
-+{
-+	memset(e, 0, sizeof(*e));
-+}
-+
-+int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
-+int ebitmap_or(struct ebitmap *dst, struct ebitmap *e1, struct ebitmap *e2);
-+int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
-+int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2);
-+int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
-+int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
-+void ebitmap_destroy(struct ebitmap *e);
-+int ebitmap_read(struct ebitmap *e, void *fp);
-+
-+#endif	/* _SS_EBITMAP_H_ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/global.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,17 @@
-+#ifndef _SS_GLOBAL_H_
-+#define _SS_GLOBAL_H_
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/in.h>
-+#include <linux/spinlock.h>
-+#include <asm/semaphore.h>
-+
-+#include "flask.h"
-+#include "avc.h"
-+#include "avc_ss.h"
-+#include "security.h"
-+
-+#endif /* _SS_GLOBAL_H_ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/hashtab.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,277 @@
-+/*
-+ * Implementation of the hash table type.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "hashtab.h"
-+
-+struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
-+                               int (*keycmp)(struct hashtab *h, void *key1, void *key2),
-+                               u32 size)
-+{
-+	struct hashtab *p;
-+	u32 i;
-+
-+	p = kmalloc(sizeof(*p), GFP_KERNEL);
-+	if (p == NULL)
-+		return p;
-+
-+	memset(p, 0, sizeof(*p));
-+	p->size = size;
-+	p->nel = 0;
-+	p->hash_value = hash_value;
-+	p->keycmp = keycmp;
-+	p->htable = kmalloc(sizeof(*(p->htable)) * size, GFP_KERNEL);
-+	if (p->htable == NULL) {
-+		kfree(p);
-+		return NULL;
-+	}
-+
-+	for (i = 0; i < size; i++)
-+		p->htable[i] = NULL;
-+
-+	return p;
-+}
-+
-+int hashtab_insert(struct hashtab *h, void *key, void *datum)
-+{
-+	u32 hvalue;
-+	struct hashtab_node *prev, *cur, *newnode;
-+
-+	if (!h || h->nel == HASHTAB_MAX_NODES)
-+		return -EINVAL;
-+
-+	hvalue = h->hash_value(h, key);
-+	prev = NULL;
-+	cur = h->htable[hvalue];
-+	while (cur && h->keycmp(h, key, cur->key) > 0) {
-+		prev = cur;
-+		cur = cur->next;
-+	}
-+
-+	if (cur && (h->keycmp(h, key, cur->key) == 0))
-+		return -EEXIST;
-+
-+	newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
-+	if (newnode == NULL)
-+		return -ENOMEM;
-+	memset(newnode, 0, sizeof(*newnode));
-+	newnode->key = key;
-+	newnode->datum = datum;
-+	if (prev) {
-+		newnode->next = prev->next;
-+		prev->next = newnode;
-+	} else {
-+		newnode->next = h->htable[hvalue];
-+		h->htable[hvalue] = newnode;
-+	}
-+
-+	h->nel++;
-+	return 0;
-+}
-+
-+int hashtab_remove(struct hashtab *h, void *key,
-+		   void (*destroy)(void *k, void *d, void *args),
-+		   void *args)
-+{
-+	u32 hvalue;
-+	struct hashtab_node *cur, *last;
-+
-+	if (!h)
-+		return -EINVAL;
-+
-+	hvalue = h->hash_value(h, key);
-+	last = NULL;
-+	cur = h->htable[hvalue];
-+	while (cur != NULL && h->keycmp(h, key, cur->key) > 0) {
-+		last = cur;
-+		cur = cur->next;
-+	}
-+
-+	if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
-+		return -ENOENT;
-+
-+	if (last == NULL)
-+		h->htable[hvalue] = cur->next;
-+	else
-+		last->next = cur->next;
-+
-+	if (destroy)
-+		destroy(cur->key, cur->datum, args);
-+	kfree(cur);
-+	h->nel--;
-+	return 0;
-+}
-+
-+int hashtab_replace(struct hashtab *h, void *key, void *datum,
-+		    void (*destroy)(void *k, void *d, void *args),
-+		    void *args)
-+{
-+	u32 hvalue;
-+	struct hashtab_node *prev, *cur, *newnode;
-+
-+	if (!h)
-+		return -EINVAL;
-+
-+	hvalue = h->hash_value(h, key);
-+	prev = NULL;
-+	cur = h->htable[hvalue];
-+	while (cur != NULL && h->keycmp(h, key, cur->key) > 0) {
-+		prev = cur;
-+		cur = cur->next;
-+	}
-+
-+	if (cur && (h->keycmp(h, key, cur->key) == 0)) {
-+		if (destroy)
-+			destroy(cur->key, cur->datum, args);
-+		cur->key = key;
-+		cur->datum = datum;
-+	} else {
-+		newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
-+		if (newnode == NULL)
-+			return -ENOMEM;
-+		memset(newnode, 0, sizeof(*newnode));
-+		newnode->key = key;
-+		newnode->datum = datum;
-+		if (prev) {
-+			newnode->next = prev->next;
-+			prev->next = newnode;
-+		} else {
-+			newnode->next = h->htable[hvalue];
-+			h->htable[hvalue] = newnode;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+void *hashtab_search(struct hashtab *h, void *key)
-+{
-+	u32 hvalue;
-+	struct hashtab_node *cur;
-+
-+	if (!h)
-+		return NULL;
-+
-+	hvalue = h->hash_value(h, key);
-+	cur = h->htable[hvalue];
-+	while (cur != NULL && h->keycmp(h, key, cur->key) > 0)
-+		cur = cur->next;
-+
-+	if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
-+		return NULL;
-+
-+	return cur->datum;
-+}
-+
-+void hashtab_destroy(struct hashtab *h)
-+{
-+	u32 i;
-+	struct hashtab_node *cur, *temp;
-+
-+	if (!h)
-+		return;
-+
-+	for (i = 0; i < h->size; i++) {
-+		cur = h->htable[i];
-+		while (cur != NULL) {
-+			temp = cur;
-+			cur = cur->next;
-+			kfree(temp);
-+		}
-+		h->htable[i] = NULL;
-+	}
-+
-+	kfree(h->htable);
-+	h->htable = NULL;
-+
-+	kfree(h);
-+}
-+
-+int hashtab_map(struct hashtab *h,
-+		int (*apply)(void *k, void *d, void *args),
-+		void *args)
-+{
-+	u32 i;
-+	int ret;
-+	struct hashtab_node *cur;
-+
-+	if (!h)
-+		return 0;
-+
-+	for (i = 0; i < h->size; i++) {
-+		cur = h->htable[i];
-+		while (cur != NULL) {
-+			ret = apply(cur->key, cur->datum, args);
-+			if (ret)
-+				return ret;
-+			cur = cur->next;
-+		}
-+	}
-+	return 0;
-+}
-+
-+
-+void hashtab_map_remove_on_error(struct hashtab *h,
-+                                 int (*apply)(void *k, void *d, void *args),
-+                                 void (*destroy)(void *k, void *d, void *args),
-+                                 void *args)
-+{
-+	u32 i;
-+	int ret;
-+	struct hashtab_node *last, *cur, *temp;
-+
-+	if (!h)
-+		return;
-+
-+	for (i = 0; i < h->size; i++) {
-+		last = NULL;
-+		cur = h->htable[i];
-+		while (cur != NULL) {
-+			ret = apply(cur->key, cur->datum, args);
-+			if (ret) {
-+				if (last)
-+					last->next = cur->next;
-+				else
-+					h->htable[i] = cur->next;
-+
-+				temp = cur;
-+				cur = cur->next;
-+				if (destroy)
-+					destroy(temp->key, temp->datum, args);
-+				kfree(temp);
-+				h->nel--;
-+			} else {
-+				last = cur;
-+				cur = cur->next;
-+			}
-+		}
-+	}
-+	return;
-+}
-+
-+void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
-+{
-+	u32 i, chain_len, slots_used, max_chain_len;
-+	struct hashtab_node *cur;
-+
-+	slots_used = 0;
-+	max_chain_len = 0;
-+	for (slots_used = max_chain_len = i = 0; i < h->size; i++) {
-+		cur = h->htable[i];
-+		if (cur) {
-+			slots_used++;
-+			chain_len = 0;
-+			while (cur) {
-+				chain_len++;
-+				cur = cur->next;
-+			}
-+
-+			if (chain_len > max_chain_len)
-+				max_chain_len = chain_len;
-+		}
-+	}
-+
-+	info->slots_used = slots_used;
-+	info->max_chain_len = max_chain_len;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/hashtab.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,125 @@
-+/*
-+ * A hash table (hashtab) maintains associations between
-+ * key values and datum values.  The type of the key values
-+ * and the type of the datum values is arbitrary.  The
-+ * functions for hash computation and key comparison are
-+ * provided by the creator of the table.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_HASHTAB_H_
-+#define _SS_HASHTAB_H_
-+
-+#define HASHTAB_MAX_NODES	0xffffffff
-+
-+struct hashtab_node {
-+	void *key;
-+	void *datum;
-+	struct hashtab_node *next;
-+};
-+
-+struct hashtab {
-+	struct hashtab_node **htable;	/* hash table */
-+	u32 size;			/* number of slots in hash table */
-+	u32 nel;			/* number of elements in hash table */
-+	u32 (*hash_value)(struct hashtab *h, void *key);
-+					/* hash function */
-+	int (*keycmp)(struct hashtab *h, void *key1, void *key2);
-+					/* key comparison function */
-+};
-+
-+struct hashtab_info {
-+	u32 slots_used;
-+	u32 max_chain_len;
-+};
-+
-+/*
-+ * Creates a new hash table with the specified characteristics.
-+ *
-+ * Returns NULL if insufficent space is available or
-+ * the new hash table otherwise.
-+ */
-+struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
-+                               int (*keycmp)(struct hashtab *h, void *key1, void *key2),
-+                               u32 size);
-+
-+/*
-+ * Inserts the specified (key, datum) pair into the specified hash table.
-+ *
-+ * Returns -ENOMEM on memory allocation error,
-+ * -EEXIST if there is already an entry with the same key,
-+ * -EINVAL for general errors or
-+ * 0 otherwise.
-+ */
-+int hashtab_insert(struct hashtab *h, void *k, void *d);
-+
-+/*
-+ * Removes the entry with the specified key from the hash table.
-+ * Applies the specified destroy function to (key,datum,args) for
-+ * the entry.
-+ *
-+ * Returns -ENOENT if no entry has the specified key,
-+ * -EINVAL for general errors or
-+ *0 otherwise.
-+ */
-+int hashtab_remove(struct hashtab *h, void *k,
-+		   void (*destroy)(void *k, void *d, void *args),
-+		   void *args);
-+
-+/*
-+ * Insert or replace the specified (key, datum) pair in the specified
-+ * hash table.  If an entry for the specified key already exists,
-+ * then the specified destroy function is applied to (key,datum,args)
-+ * for the entry prior to replacing the entry's contents.
-+ *
-+ * Returns -ENOMEM if insufficient space is available,
-+ * -EINVAL for general errors or
-+ * 0 otherwise.
-+ */
-+int hashtab_replace(struct hashtab *h, void *k, void *d,
-+		    void (*destroy)(void *k, void *d, void *args),
-+		    void *args);
-+
-+/*
-+ * Searches for the entry with the specified key in the hash table.
-+ *
-+ * Returns NULL if no entry has the specified key or
-+ * the datum of the entry otherwise.
-+ */
-+void *hashtab_search(struct hashtab *h, void *k);
-+
-+/*
-+ * Destroys the specified hash table.
-+ */
-+void hashtab_destroy(struct hashtab *h);
-+
-+/*
-+ * Applies the specified apply function to (key,datum,args)
-+ * for each entry in the specified hash table.
-+ *
-+ * The order in which the function is applied to the entries
-+ * is dependent upon the internal structure of the hash table.
-+ *
-+ * If apply returns a non-zero status, then hashtab_map will cease
-+ * iterating through the hash table and will propagate the error
-+ * return to its caller.
-+ */
-+int hashtab_map(struct hashtab *h,
-+		int (*apply)(void *k, void *d, void *args),
-+		void *args);
-+
-+/*
-+ * Same as hashtab_map, except that if apply returns a non-zero status,
-+ * then the (key,datum) pair will be removed from the hashtab and the
-+ * destroy function will be applied to (key,datum,args).
-+ */
-+void hashtab_map_remove_on_error(struct hashtab *h,
-+                                 int (*apply)(void *k, void *d, void *args),
-+                                 void (*destroy)(void *k, void *d, void *args),
-+                                 void *args);
-+
-+
-+/* Fill info with some hash table statistics */
-+void hashtab_stat(struct hashtab *h, struct hashtab_info *info);
-+
-+#endif	/* _SS_HASHTAB_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/Makefile	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,14 @@
-+#
-+# Makefile for building the SELinux security server as part of the kernel tree.
-+#
-+
-+EXTRA_CFLAGS += -Isecurity/selinux/include -include security/selinux/ss/global.h
-+
-+obj-y := ss.o
-+
-+ss-objs := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o
-+
-+ifeq ($(CONFIG_SECURITY_SELINUX_MLS),y)
-+ss-objs += mls.o
-+endif
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/mls.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,741 @@
-+/*
-+ * Implementation of the multi-level security (MLS) policy.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "mls.h"
-+#include "policydb.h"
-+#include "services.h"
-+
-+/*
-+ * Remove any permissions from `allowed' that are
-+ * denied by the MLS policy.
-+ */
-+void mls_compute_av(struct context *scontext,
-+		    struct context *tcontext,
-+		    struct class_datum *tclass,
-+		    u32 *allowed)
-+{
-+	unsigned int rel[2];
-+	int l;
-+
-+	for (l = 0; l < 2; l++)
-+		rel[l] = mls_level_relation(scontext->range.level[l],
-+					    tcontext->range.level[l]);
-+
-+	if (rel[1] != MLS_RELATION_EQ) {
-+		if (rel[1] != MLS_RELATION_DOM &&
-+		    !ebitmap_get_bit(&policydb.trustedreaders, scontext->type - 1) &&
-+		    !ebitmap_get_bit(&policydb.trustedobjects, tcontext->type - 1)) {
-+			/* read(s,t) = (s.high >= t.high) = False */
-+			*allowed = (*allowed) & ~(tclass->mlsperms.read);
-+		}
-+		if (rel[1] != MLS_RELATION_DOMBY &&
-+		    !ebitmap_get_bit(&policydb.trustedreaders, tcontext->type - 1) &&
-+		    !ebitmap_get_bit(&policydb.trustedobjects, scontext->type - 1)) {
-+			/* readby(s,t) = read(t,s) = False */
-+			*allowed = (*allowed) & ~(tclass->mlsperms.readby);
-+		}
-+	}
-+	if (((rel[0] != MLS_RELATION_DOMBY && rel[0] != MLS_RELATION_EQ) ||
-+	    ((!mls_level_eq(tcontext->range.level[0],
-+			    tcontext->range.level[1])) &&
-+	     (rel[1] != MLS_RELATION_DOM && rel[1] != MLS_RELATION_EQ))) &&
-+	    !ebitmap_get_bit(&policydb.trustedwriters, scontext->type - 1) &&
-+	    !ebitmap_get_bit(&policydb.trustedobjects, tcontext->type - 1)) {
-+		/*
-+		 * write(s,t) = ((s.low <= t.low = t.high) or (s.low
-+		 * <= t.low <= t.high <= s.high)) = False
-+		 */
-+		*allowed = (*allowed) & ~(tclass->mlsperms.write);
-+	}
-+
-+	if (((rel[0] != MLS_RELATION_DOM && rel[0] != MLS_RELATION_EQ) ||
-+	    ((!mls_level_eq(scontext->range.level[0],
-+			    scontext->range.level[1])) &&
-+	     (rel[1] != MLS_RELATION_DOMBY && rel[1] != MLS_RELATION_EQ))) &&
-+	    !ebitmap_get_bit(&policydb.trustedwriters, tcontext->type - 1) &&
-+	    !ebitmap_get_bit(&policydb.trustedobjects, scontext->type - 1)) {
-+		/* writeby(s,t) = write(t,s) = False */
-+		*allowed = (*allowed) & ~(tclass->mlsperms.writeby);
-+	}
-+}
-+
-+/*
-+ * Return the length in bytes for the MLS fields of the
-+ * security context string representation of `context'.
-+ */
-+int mls_compute_context_len(struct context * context)
-+{
-+	int i, l, len;
-+
-+
-+	len = 0;
-+	for (l = 0; l < 2; l++) {
-+		len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]) + 1;
-+
-+		for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++)
-+			if (ebitmap_get_bit(&context->range.level[l].cat, i - 1))
-+				len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
-+
-+		if (mls_level_relation(context->range.level[0], context->range.level[1])
-+				== MLS_RELATION_EQ)
-+			break;
-+	}
-+
-+	return len;
-+}
-+
-+/*
-+ * Write the security context string representation of
-+ * the MLS fields of `context' into the string `*scontext'.
-+ * Update `*scontext' to point to the end of the MLS fields.
-+ */
-+int mls_sid_to_context(struct context *context,
-+		       char **scontext)
-+{
-+	char *scontextp;
-+	int i, l;
-+
-+	scontextp = *scontext;
-+
-+	for (l = 0; l < 2; l++) {
-+		strcpy(scontextp,
-+		       policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
-+		scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
-+		*scontextp = ':';
-+		scontextp++;
-+		for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++)
-+			if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) {
-+				strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
-+				scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
-+				*scontextp = ',';
-+				scontextp++;
-+			}
-+		if (mls_level_relation(context->range.level[0], context->range.level[1])
-+				!= MLS_RELATION_EQ) {
-+			scontextp--;
-+			sprintf(scontextp, "-");
-+			scontextp++;
-+
-+		} else {
-+			break;
-+		}
-+	}
-+
-+	*scontext = scontextp;
-+	return 0;
-+}
-+
-+/*
-+ * Return 1 if the MLS fields in the security context
-+ * structure `c' are valid.  Return 0 otherwise.
-+ */
-+int mls_context_isvalid(struct policydb *p, struct context *c)
-+{
-+	unsigned int relation;
-+	struct level_datum *levdatum;
-+	struct user_datum *usrdatum;
-+	struct mls_range_list *rnode;
-+	int i, l;
-+
-+	/*
-+	 * MLS range validity checks: high must dominate low, low level must
-+	 * be valid (category set <-> sensitivity check), and high level must
-+	 * be valid (category set <-> sensitivity check)
-+	 */
-+	relation = mls_level_relation(c->range.level[1],
-+				      c->range.level[0]);
-+	if (!(relation & (MLS_RELATION_DOM | MLS_RELATION_EQ)))
-+		/* High does not dominate low. */
-+		return 0;
-+
-+	for (l = 0; l < 2; l++) {
-+		if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim)
-+			return 0;
-+		levdatum = hashtab_search(p->p_levels.table,
-+			p->p_sens_val_to_name[c->range.level[l].sens - 1]);
-+		if (!levdatum)
-+			return 0;
-+
-+		for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) {
-+			if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) {
-+				if (i > p->p_cats.nprim)
-+					return 0;
-+				if (!ebitmap_get_bit(&levdatum->level->cat, i - 1))
-+					/*
-+					 * Category may not be associated with
-+					 * sensitivity in low level.
-+					 */
-+					return 0;
-+			}
-+		}
-+	}
-+
-+	if (c->role == OBJECT_R_VAL)
-+		return 1;
-+
-+	/*
-+	 * User must be authorized for the MLS range.
-+	 */
-+	if (!c->user || c->user > p->p_users.nprim)
-+		return 0;
-+	usrdatum = p->user_val_to_struct[c->user - 1];
-+	for (rnode = usrdatum->ranges; rnode; rnode = rnode->next) {
-+		if (mls_range_contains(rnode->range, c->range))
-+			break;
-+	}
-+	if (!rnode)
-+		/* user may not be associated with range */
-+		return 0;
-+
-+	return 1;
-+}
-+
-+
-+/*
-+ * Set the MLS fields in the security context structure
-+ * `context' based on the string representation in
-+ * the string `*scontext'.  Update `*scontext' to
-+ * point to the end of the string representation of
-+ * the MLS fields.
-+ *
-+ * This function modifies the string in place, inserting
-+ * NULL characters to terminate the MLS fields.
-+ */
-+int mls_context_to_sid(char oldc,
-+		       char **scontext,
-+		       struct context *context)
-+{
-+
-+	char delim;
-+	char *scontextp, *p;
-+	struct level_datum *levdatum;
-+	struct cat_datum *catdatum;
-+	int l, rc = -EINVAL;
-+
-+	if (!oldc) {
-+		/* No MLS component to the security context.  Try
-+		   to use a default 'unclassified' value. */
-+		levdatum = hashtab_search(policydb.p_levels.table,
-+		                          "unclassified");
-+		if (!levdatum)
-+			goto out;
-+		context->range.level[0].sens = levdatum->level->sens;
-+		context->range.level[1].sens = context->range.level[0].sens;
-+		rc = 0;
-+		goto out;
-+	}
-+
-+	/* Extract low sensitivity. */
-+	scontextp = p = *scontext;
-+	while (*p && *p != ':' && *p != '-')
-+		p++;
-+
-+	delim = *p;
-+	if (delim != 0)
-+		*p++ = 0;
-+
-+	for (l = 0; l < 2; l++) {
-+		levdatum = hashtab_search(policydb.p_levels.table, scontextp);
-+		if (!levdatum)
-+			goto out;
-+
-+		context->range.level[l].sens = levdatum->level->sens;
-+
-+		if (delim == ':') {
-+			/* Extract low category set. */
-+			while (1) {
-+				scontextp = p;
-+				while (*p && *p != ',' && *p != '-')
-+					p++;
-+				delim = *p;
-+				if (delim != 0)
-+					*p++ = 0;
-+
-+				catdatum = hashtab_search(policydb.p_cats.table,
-+				                          scontextp);
-+				if (!catdatum)
-+					goto out;
-+
-+				rc = ebitmap_set_bit(&context->range.level[l].cat,
-+				                     catdatum->value - 1, 1);
-+				if (rc)
-+					goto out;
-+				if (delim != ',')
-+					break;
-+			}
-+		}
-+		if (delim == '-') {
-+			/* Extract high sensitivity. */
-+			scontextp = p;
-+			while (*p && *p != ':')
-+				p++;
-+
-+			delim = *p;
-+			if (delim != 0)
-+				*p++ = 0;
-+		} else
-+			break;
-+	}
-+
-+	if (l == 0) {
-+		context->range.level[1].sens = context->range.level[0].sens;
-+		rc = ebitmap_cpy(&context->range.level[1].cat,
-+				 &context->range.level[0].cat);
-+		if (rc)
-+			goto out;
-+	}
-+	*scontext = p;
-+	rc = 0;
-+out:
-+	return rc;
-+}
-+
-+/*
-+ * Copies the MLS range from `src' into `dst'.
-+ */
-+static inline int mls_copy_context(struct context *dst,
-+				   struct context *src)
-+{
-+	int l, rc = 0;
-+
-+	/* Copy the MLS range from the source context */
-+	for (l = 0; l < 2; l++) {
-+
-+		dst->range.level[l].sens = src->range.level[l].sens;
-+		rc = ebitmap_cpy(&dst->range.level[l].cat,
-+				 &src->range.level[l].cat);
-+		if (rc)
-+			break;
-+	}
-+
-+	return rc;
-+}
-+
-+/*
-+ * Convert the MLS fields in the security context
-+ * structure `c' from the values specified in the
-+ * policy `oldp' to the values specified in the policy `newp'.
-+ */
-+int mls_convert_context(struct policydb *oldp,
-+			struct policydb *newp,
-+			struct context *c)
-+{
-+	struct level_datum *levdatum;
-+	struct cat_datum *catdatum;
-+	struct ebitmap bitmap;
-+	int l, i;
-+
-+	for (l = 0; l < 2; l++) {
-+		levdatum = hashtab_search(newp->p_levels.table,
-+			oldp->p_sens_val_to_name[c->range.level[l].sens - 1]);
-+
-+		if (!levdatum)
-+			return -EINVAL;
-+		c->range.level[l].sens = levdatum->level->sens;
-+
-+		ebitmap_init(&bitmap);
-+		for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) {
-+			if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) {
-+				int rc;
-+
-+				catdatum = hashtab_search(newp->p_cats.table,
-+				         	oldp->p_cat_val_to_name[i - 1]);
-+				if (!catdatum)
-+					return -EINVAL;
-+				rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
-+				if (rc)
-+					return rc;
-+			}
-+		}
-+		ebitmap_destroy(&c->range.level[l].cat);
-+		c->range.level[l].cat = bitmap;
-+	}
-+
-+	return 0;
-+}
-+
-+int mls_compute_sid(struct context *scontext,
-+		    struct context *tcontext,
-+		    u16 tclass,
-+		    u32 specified,
-+		    struct context *newcontext)
-+{
-+	switch (specified) {
-+	case AVTAB_TRANSITION:
-+	case AVTAB_CHANGE:
-+		/* Use the process MLS attributes. */
-+		return mls_copy_context(newcontext, scontext);
-+	case AVTAB_MEMBER:
-+		/* Only polyinstantiate the MLS attributes if
-+		   the type is being polyinstantiated */
-+		if (newcontext->type != tcontext->type) {
-+			/* Use the process MLS attributes. */
-+			return mls_copy_context(newcontext, scontext);
-+		} else {
-+			/* Use the related object MLS attributes. */
-+			return mls_copy_context(newcontext, tcontext);
-+		}
-+	default:
-+		return -EINVAL;
-+	}
-+	return -EINVAL;
-+}
-+
-+void mls_user_destroy(struct user_datum *usrdatum)
-+{
-+	struct mls_range_list *rnode, *rtmp;
-+	rnode = usrdatum->ranges;
-+	while (rnode) {
-+		rtmp = rnode;
-+		rnode = rnode->next;
-+		ebitmap_destroy(&rtmp->range.level[0].cat);
-+		ebitmap_destroy(&rtmp->range.level[1].cat);
-+		kfree(rtmp);
-+	}
-+}
-+
-+int mls_read_perm(struct perm_datum *perdatum, void *fp)
-+{
-+	u32 *buf;
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf)
-+		return -EINVAL;
-+	perdatum->base_perms = le32_to_cpu(buf[0]);
-+	return 0;
-+}
-+
-+/*
-+ * Read a MLS level structure from a policydb binary
-+ * representation file.
-+ */
-+struct mls_level *mls_read_level(void *fp)
-+{
-+	struct mls_level *l;
-+	u32 *buf;
-+
-+	l = kmalloc(sizeof(*l), GFP_ATOMIC);
-+	if (!l) {
-+		printk(KERN_ERR "security: mls: out of memory\n");
-+		return NULL;
-+	}
-+	memset(l, 0, sizeof(*l));
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		printk(KERN_ERR "security: mls: truncated level\n");
-+		goto bad;
-+	}
-+	l->sens = cpu_to_le32(buf[0]);
-+
-+	if (ebitmap_read(&l->cat, fp)) {
-+		printk(KERN_ERR "security: mls:  error reading level "
-+		       "categories\n");
-+		goto bad;
-+	}
-+	return l;
-+
-+bad:
-+	kfree(l);
-+	return NULL;
-+}
-+
-+
-+/*
-+ * Read a MLS range structure from a policydb binary
-+ * representation file.
-+ */
-+static int mls_read_range_helper(struct mls_range *r, void *fp)
-+{
-+	u32 *buf;
-+	int items, rc = -EINVAL;
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf)
-+		goto out;
-+
-+	items = le32_to_cpu(buf[0]);
-+	buf = next_entry(fp, sizeof(u32) * items);
-+	if (!buf) {
-+		printk(KERN_ERR "security: mls:  truncated range\n");
-+		goto out;
-+	}
-+	r->level[0].sens = le32_to_cpu(buf[0]);
-+	if (items > 1) {
-+		r->level[1].sens = le32_to_cpu(buf[1]);
-+	} else {
-+		r->level[1].sens = r->level[0].sens;
-+	}
-+
-+	rc = ebitmap_read(&r->level[0].cat, fp);
-+	if (rc) {
-+		printk(KERN_ERR "security: mls:  error reading low "
-+		       "categories\n");
-+		goto out;
-+	}
-+	if (items > 1) {
-+		rc = ebitmap_read(&r->level[1].cat, fp);
-+		if (rc) {
-+			printk(KERN_ERR "security: mls:  error reading high "
-+			       "categories\n");
-+			goto bad_high;
-+		}
-+	} else {
-+		rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
-+		if (rc) {
-+			printk(KERN_ERR "security: mls:  out of memory\n");
-+			goto bad_high;
-+		}
-+	}
-+
-+	rc = 0;
-+out:
-+	return rc;
-+bad_high:
-+	ebitmap_destroy(&r->level[0].cat);
-+	goto out;
-+}
-+
-+int mls_read_range(struct context *c, void *fp)
-+{
-+	return mls_read_range_helper(&c->range, fp);
-+}
-+
-+
-+/*
-+ * Read a MLS perms structure from a policydb binary
-+ * representation file.
-+ */
-+int mls_read_class(struct class_datum *cladatum, void *fp)
-+{
-+	struct mls_perms *p = &cladatum->mlsperms;
-+	u32 *buf;
-+
-+	buf = next_entry(fp, sizeof(u32)*4);
-+	if (!buf) {
-+		printk(KERN_ERR "security: mls:  truncated mls permissions\n");
-+		return -EINVAL;
-+	}
-+	p->read = le32_to_cpu(buf[0]);
-+	p->readby = le32_to_cpu(buf[1]);
-+	p->write = le32_to_cpu(buf[2]);
-+	p->writeby = le32_to_cpu(buf[3]);
-+	return 0;
-+}
-+
-+int mls_read_user(struct user_datum *usrdatum, void *fp)
-+{
-+	struct mls_range_list *r, *l;
-+	int rc = 0;
-+	u32 nel, i;
-+	u32 *buf;
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	nel = le32_to_cpu(buf[0]);
-+	l = NULL;
-+	for (i = 0; i < nel; i++) {
-+		r = kmalloc(sizeof(*r), GFP_ATOMIC);
-+		if (!r) {
-+			rc = -ENOMEM;
-+			goto out;
-+		}
-+		memset(r, 0, sizeof(*r));
-+
-+		rc = mls_read_range_helper(&r->range, fp);
-+		if (rc)
-+			goto out;
-+
-+		if (l)
-+			l->next = r;
-+		else
-+			usrdatum->ranges = r;
-+		l = r;
-+	}
-+out:
-+	return rc;
-+}
-+
-+int mls_read_nlevels(struct policydb *p, void *fp)
-+{
-+	u32 *buf;
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf)
-+		return -EINVAL;
-+	p->nlevels = le32_to_cpu(buf[0]);
-+	return 0;
-+}
-+
-+int mls_read_trusted(struct policydb *p, void *fp)
-+{
-+	int rc = 0;
-+
-+	rc = ebitmap_read(&p->trustedreaders, fp);
-+	if (rc)
-+		goto out;
-+	rc = ebitmap_read(&p->trustedwriters, fp);
-+	if (rc)
-+		goto out;
-+	rc = ebitmap_read(&p->trustedobjects, fp);
-+out:
-+	return rc;
-+}
-+
-+int sens_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct level_datum *levdatum;
-+
-+
-+	levdatum = datum;
-+	p = datap;
-+
-+	if (!levdatum->isalias)
-+		p->p_sens_val_to_name[levdatum->level->sens - 1] = key;
-+
-+	return 0;
-+}
-+
-+int cat_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct cat_datum *catdatum;
-+
-+
-+	catdatum = datum;
-+	p = datap;
-+
-+
-+	if (!catdatum->isalias)
-+		p->p_cat_val_to_name[catdatum->value - 1] = key;
-+
-+	return 0;
-+}
-+
-+int sens_destroy(void *key, void *datum, void *p)
-+{
-+	struct level_datum *levdatum;
-+
-+	kfree(key);
-+	levdatum = datum;
-+	if (!levdatum->isalias) {
-+		ebitmap_destroy(&levdatum->level->cat);
-+		kfree(levdatum->level);
-+	}
-+	kfree(datum);
-+	return 0;
-+}
-+
-+int cat_destroy(void *key, void *datum, void *p)
-+{
-+	kfree(key);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+int sens_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct level_datum *levdatum;
-+	int rc;
-+	u32 *buf, len;
-+
-+	levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
-+	if (!levdatum) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(levdatum, 0, sizeof(*levdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*2);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	levdatum->isalias = le32_to_cpu(buf[1]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_ATOMIC);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	levdatum->level = mls_read_level(fp);
-+	if (!levdatum->level) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	rc = hashtab_insert(h, key, levdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	sens_destroy(key, levdatum, NULL);
-+	goto out;
-+}
-+
-+
-+int cat_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct cat_datum *catdatum;
-+	int rc;
-+	u32 *buf, len;
-+
-+	catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
-+	if (!catdatum) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(catdatum, 0, sizeof(*catdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*3);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	catdatum->value = le32_to_cpu(buf[1]);
-+	catdatum->isalias = le32_to_cpu(buf[2]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_ATOMIC);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	rc = hashtab_insert(h, key, catdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+
-+bad:
-+	cat_destroy(key, catdatum, NULL);
-+	goto out;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/mls.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,99 @@
-+/*
-+ * Multi-level security (MLS) policy operations.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_MLS_H_
-+#define _SS_MLS_H_
-+
-+#include "context.h"
-+#include "policydb.h"
-+
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+
-+void mls_compute_av(struct context *scontext,
-+		    struct context *tcontext,
-+		    struct class_datum *tclass,
-+		    u32 *allowed);
-+
-+int mls_compute_context_len(struct context *context);
-+int mls_sid_to_context(struct context *context, char **scontext);
-+int mls_context_isvalid(struct policydb *p, struct context *c);
-+
-+int mls_context_to_sid(char oldc,
-+	               char **scontext,
-+		       struct context *context);
-+
-+int mls_convert_context(struct policydb *oldp,
-+			struct policydb *newp,
-+			struct context *context);
-+
-+int mls_compute_sid(struct context *scontext,
-+		    struct context *tcontext,
-+		    u16 tclass,
-+		    u32 specified,
-+		    struct context *newcontext);
-+
-+int sens_index(void *key, void *datum, void *datap);
-+int cat_index(void *key, void *datum, void *datap);
-+int sens_destroy(void *key, void *datum, void *p);
-+int cat_destroy(void *key, void *datum, void *p);
-+int sens_read(struct policydb *p, struct hashtab *h, void *fp);
-+int cat_read(struct policydb *p, struct hashtab *h, void *fp);
-+
-+#define mls_for_user_ranges(user, usercon) { \
-+struct mls_range_list *__ranges; \
-+for (__ranges = user->ranges; __ranges; __ranges = __ranges->next) { \
-+usercon.range = __ranges->range;
-+
-+#define mls_end_user_ranges } }
-+
-+#define mls_symtab_names , "levels", "categories"
-+#define mls_symtab_sizes , 16, 16
-+#define mls_index_f ,sens_index, cat_index
-+#define mls_destroy_f ,sens_destroy, cat_destroy
-+#define mls_read_f ,sens_read, cat_read
-+#define mls_write_f ,sens_write, cat_write
-+#define mls_policydb_index_others(p) printk(", %d levels", p->nlevels);
-+
-+#define mls_set_config(config) config |= POLICYDB_CONFIG_MLS
-+
-+void mls_user_destroy(struct user_datum *usrdatum);
-+int mls_read_range(struct context *c, void *fp);
-+int mls_read_perm(struct perm_datum *perdatum, void *fp);
-+int mls_read_class(struct class_datum *cladatum,  void *fp);
-+int mls_read_user(struct user_datum *usrdatum, void *fp);
-+int mls_read_nlevels(struct policydb *p, void *fp);
-+int mls_read_trusted(struct policydb *p, void *fp);
-+
-+#else
-+
-+#define	mls_compute_av(scontext, tcontext, tclass_datum, allowed)
-+#define mls_compute_context_len(context) 0
-+#define	mls_sid_to_context(context, scontextpp)
-+#define mls_context_isvalid(p, c) 1
-+#define	mls_context_to_sid(oldc, context_str, context) 0
-+#define mls_convert_context(oldp, newp, c) 0
-+#define mls_compute_sid(scontext, tcontext, tclass, specified, newcontextp) 0
-+#define mls_for_user_ranges(user, usercon)
-+#define mls_end_user_ranges
-+#define mls_symtab_names
-+#define mls_symtab_sizes
-+#define mls_index_f
-+#define mls_destroy_f
-+#define mls_read_f
-+#define mls_write_f
-+#define mls_policydb_index_others(p)
-+#define mls_set_config(config)
-+#define mls_user_destroy(usrdatum)
-+#define mls_read_range(c, fp) 0
-+#define mls_read_perm(p, fp) 0
-+#define mls_read_class(c, fp) 0
-+#define mls_read_user(u, fp) 0
-+#define mls_read_nlevels(p, fp) 0
-+#define mls_read_trusted(p, fp) 0
-+
-+#endif
-+
-+#endif	/* _SS_MLS_H */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/mls_types.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,58 @@
-+/*
-+ * Type definitions for the multi-level security (MLS) policy.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_MLS_TYPES_H_
-+#define _SS_MLS_TYPES_H_
-+
-+struct mls_level {
-+	u32 sens;		/* sensitivity */
-+	struct ebitmap cat;	/* category set */
-+};
-+
-+struct mls_range {
-+	struct mls_level level[2]; /* low == level[0], high == level[1] */
-+};
-+
-+struct mls_range_list {
-+	struct mls_range range;
-+	struct mls_range_list *next;
-+};
-+
-+#define MLS_RELATION_DOM	1 /* source dominates */
-+#define MLS_RELATION_DOMBY	2 /* target dominates */
-+#define MLS_RELATION_EQ		4 /* source and target are equivalent */
-+#define MLS_RELATION_INCOMP	8 /* source and target are incomparable */
-+
-+#define mls_level_eq(l1,l2) \
-+(((l1).sens == (l2).sens) && ebitmap_cmp(&(l1).cat,&(l2).cat))
-+
-+#define mls_level_relation(l1,l2) ( \
-+(((l1).sens == (l2).sens) && ebitmap_cmp(&(l1).cat,&(l2).cat)) ? \
-+				    MLS_RELATION_EQ : \
-+(((l1).sens >= (l2).sens) && ebitmap_contains(&(l1).cat, &(l2).cat)) ? \
-+				    MLS_RELATION_DOM : \
-+(((l2).sens >= (l1).sens) && ebitmap_contains(&(l2).cat, &(l1).cat)) ? \
-+				    MLS_RELATION_DOMBY : \
-+				    MLS_RELATION_INCOMP )
-+
-+#define mls_range_contains(r1,r2) \
-+((mls_level_relation((r1).level[0], (r2).level[0]) & \
-+	  (MLS_RELATION_EQ | MLS_RELATION_DOMBY)) && \
-+	 (mls_level_relation((r1).level[1], (r2).level[1]) & \
-+	  (MLS_RELATION_EQ | MLS_RELATION_DOM)))
-+
-+/*
-+ * Every access vector permission is mapped to a set of MLS base
-+ * permissions, based on the flow properties of the corresponding
-+ * operation.
-+ */
-+struct mls_perms {
-+	u32 read;     /* permissions that map to `read' */
-+	u32 readby;   /* permissions that map to `readby' */
-+	u32 write;    /* permissions that map to `write' */
-+	u32 writeby;  /* permissions that map to `writeby' */
-+};
-+
-+#endif	/* _SS_MLS_TYPES_H_ */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/policydb.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,1429 @@
-+/*
-+ * Implementation of the policy database.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "policydb.h"
-+#include "mls.h"
-+
-+#define _DEBUG_HASHES
-+
-+#ifdef DEBUG_HASHES
-+static char *symtab_name[SYM_NUM] = {
-+	"common prefixes",
-+	"classes",
-+	"roles",
-+	"types",
-+	"users"
-+	mls_symtab_names
-+};
-+#endif
-+
-+static unsigned int symtab_sizes[SYM_NUM] = {
-+	2,
-+	32,
-+	16,
-+	512,
-+	128
-+	mls_symtab_sizes
-+};
-+
-+/*
-+ * Initialize the role table.
-+ */
-+int roles_init(struct policydb *p)
-+{
-+	char *key = 0;
-+	int rc;
-+	struct role_datum *role;
-+
-+	role = kmalloc(sizeof(*role), GFP_KERNEL);
-+	if (!role) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(role, 0, sizeof(*role));
-+	role->value = ++p->p_roles.nprim;
-+	if (role->value != OBJECT_R_VAL) {
-+		rc = -EINVAL;
-+		goto out_free_role;
-+	}
-+	key = kmalloc(strlen(OBJECT_R)+1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto out_free_role;
-+	}
-+	strcpy(key, OBJECT_R);
-+	rc = hashtab_insert(p->p_roles.table, key, role);
-+	if (rc)
-+		goto out_free_key;
-+out:
-+	return rc;
-+
-+out_free_key:
-+	kfree(key);
-+out_free_role:
-+	kfree(role);
-+	goto out;
-+}
-+
-+/*
-+ * Initialize a policy database structure.
-+ */
-+int policydb_init(struct policydb *p)
-+{
-+	int i, rc;
-+
-+	memset(p, 0, sizeof(*p));
-+
-+	for (i = 0; i < SYM_NUM; i++) {
-+		rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
-+		if (rc)
-+			goto out_free_symtab;
-+	}
-+
-+	rc = avtab_init(&p->te_avtab);
-+	if (rc)
-+		goto out_free_symtab;
-+
-+	rc = roles_init(p);
-+	if (rc)
-+		goto out_free_avtab;
-+
-+out:
-+	return rc;
-+
-+out_free_avtab:
-+	avtab_destroy(&p->te_avtab);
-+
-+out_free_symtab:
-+	for (i = 0; i < SYM_NUM; i++)
-+		hashtab_destroy(p->symtab[i].table);
-+	goto out;
-+}
-+
-+/*
-+ * The following *_index functions are used to
-+ * define the val_to_name and val_to_struct arrays
-+ * in a policy database structure.  The val_to_name
-+ * arrays are used when converting security context
-+ * structures into string representations.  The
-+ * val_to_struct arrays are used when the attributes
-+ * of a class, role, or user are needed.
-+ */
-+
-+static int common_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct common_datum *comdatum;
-+
-+	comdatum = datum;
-+	p = datap;
-+	p->p_common_val_to_name[comdatum->value - 1] = key;
-+	return 0;
-+}
-+
-+static int class_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct class_datum *cladatum;
-+
-+	cladatum = datum;
-+	p = datap;
-+	p->p_class_val_to_name[cladatum->value - 1] = key;
-+	p->class_val_to_struct[cladatum->value - 1] = cladatum;
-+	return 0;
-+}
-+
-+static int role_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct role_datum *role;
-+
-+	role = datum;
-+	p = datap;
-+	p->p_role_val_to_name[role->value - 1] = key;
-+	p->role_val_to_struct[role->value - 1] = role;
-+	return 0;
-+}
-+
-+static int type_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct type_datum *typdatum;
-+
-+	typdatum = datum;
-+	p = datap;
-+
-+	if (typdatum->primary)
-+		p->p_type_val_to_name[typdatum->value - 1] = key;
-+
-+	return 0;
-+}
-+
-+static int user_index(void *key, void *datum, void *datap)
-+{
-+	struct policydb *p;
-+	struct user_datum *usrdatum;
-+
-+	usrdatum = datum;
-+	p = datap;
-+	p->p_user_val_to_name[usrdatum->value - 1] = key;
-+	p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
-+	return 0;
-+}
-+
-+static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
-+{
-+	common_index,
-+	class_index,
-+	role_index,
-+	type_index,
-+	user_index
-+	mls_index_f
-+};
-+
-+/*
-+ * Define the common val_to_name array and the class
-+ * val_to_name and val_to_struct arrays in a policy
-+ * database structure.
-+ *
-+ * Caller must clean up upon failure.
-+ */
-+int policydb_index_classes(struct policydb *p)
-+{
-+	int rc;
-+
-+	p->p_common_val_to_name =
-+		kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
-+	if (!p->p_common_val_to_name) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	rc = hashtab_map(p->p_commons.table, common_index, p);
-+	if (rc)
-+		goto out;
-+
-+	p->class_val_to_struct =
-+		kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
-+	if (!p->class_val_to_struct) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	p->p_class_val_to_name =
-+		kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
-+	if (!p->p_class_val_to_name) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	rc = hashtab_map(p->p_classes.table, class_index, p);
-+out:
-+	return rc;
-+}
-+
-+#ifdef DEBUG_HASHES
-+static void symtab_hash_eval(struct symtab *s)
-+{
-+	int i;
-+
-+	for (i = 0; i < SYM_NUM; i++) {
-+		struct hashtab *h = s[i].table;
-+		struct hashtab_info info;
-+
-+		hashtab_stat(h, &info);
-+		printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, "
-+		       "longest chain length %d\n", symtab_name[i], h->nel,
-+		       info.slots_used, h->size, info.max_chain_len);
-+	}
-+}
-+#endif
-+
-+/*
-+ * Define the other val_to_name and val_to_struct arrays
-+ * in a policy database structure.
-+ *
-+ * Caller must clean up on failure.
-+ */
-+int policydb_index_others(struct policydb *p)
-+{
-+	int i, rc = 0;
-+
-+	printk(KERN_INFO "security:  %d users, %d roles, %d types",
-+	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim);
-+	mls_policydb_index_others(p);
-+	printk("\n");
-+
-+	printk(KERN_INFO "security:  %d classes, %d rules\n",
-+	       p->p_classes.nprim, p->te_avtab.nel);
-+
-+#ifdef DEBUG_HASHES
-+	avtab_hash_eval(&p->te_avtab, "rules");
-+	symtab_hash_eval(p->symtab);
-+#endif
-+
-+	p->role_val_to_struct =
-+		kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
-+		        GFP_KERNEL);
-+	if (!p->role_val_to_struct) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	p->user_val_to_struct =
-+		kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
-+		        GFP_KERNEL);
-+	if (!p->user_val_to_struct) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	for (i = SYM_ROLES; i < SYM_NUM; i++) {
-+		p->sym_val_to_name[i] =
-+			kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL);
-+		if (!p->sym_val_to_name[i]) {
-+			rc = -ENOMEM;
-+			goto out;
-+		}
-+		rc = hashtab_map(p->symtab[i].table, index_f[i], p);
-+		if (rc)
-+			goto out;
-+	}
-+
-+out:
-+	return rc;
-+}
-+
-+/*
-+ * The following *_destroy functions are used to
-+ * free any memory allocated for each kind of
-+ * symbol data in the policy database.
-+ */
-+
-+static int perm_destroy(void *key, void *datum, void *p)
-+{
-+	kfree(key);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int common_destroy(void *key, void *datum, void *p)
-+{
-+	struct common_datum *comdatum;
-+
-+	kfree(key);
-+	comdatum = datum;
-+	hashtab_map(comdatum->permissions.table, perm_destroy, 0);
-+	hashtab_destroy(comdatum->permissions.table);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int class_destroy(void *key, void *datum, void *p)
-+{
-+	struct class_datum *cladatum;
-+	struct constraint_node *constraint, *ctemp;
-+	struct constraint_expr *e, *etmp;
-+
-+	kfree(key);
-+	cladatum = datum;
-+	hashtab_map(cladatum->permissions.table, perm_destroy, 0);
-+	hashtab_destroy(cladatum->permissions.table);
-+	constraint = cladatum->constraints;
-+	while (constraint) {
-+		e = constraint->expr;
-+		while (e) {
-+			ebitmap_destroy(&e->names);
-+			etmp = e;
-+			e = e->next;
-+			kfree(etmp);
-+		}
-+		ctemp = constraint;
-+		constraint = constraint->next;
-+		kfree(ctemp);
-+	}
-+	kfree(cladatum->comkey);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int role_destroy(void *key, void *datum, void *p)
-+{
-+	struct role_datum *role;
-+
-+	kfree(key);
-+	role = datum;
-+	ebitmap_destroy(&role->dominates);
-+	ebitmap_destroy(&role->types);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int type_destroy(void *key, void *datum, void *p)
-+{
-+	kfree(key);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int user_destroy(void *key, void *datum, void *p)
-+{
-+	struct user_datum *usrdatum;
-+
-+	kfree(key);
-+	usrdatum = datum;
-+	ebitmap_destroy(&usrdatum->roles);
-+	mls_user_destroy(usrdatum);
-+	kfree(datum);
-+	return 0;
-+}
-+
-+static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
-+{
-+	common_destroy,
-+	class_destroy,
-+	role_destroy,
-+	type_destroy,
-+	user_destroy
-+	mls_destroy_f
-+};
-+
-+/*
-+ * Free any memory allocated by a policy database structure.
-+ */
-+void policydb_destroy(struct policydb *p)
-+{
-+	struct ocontext *c, *ctmp;
-+	struct genfs *g, *gtmp;
-+	int i;
-+
-+	for (i = 0; i < SYM_NUM; i++) {
-+		hashtab_map(p->symtab[i].table, destroy_f[i], 0);
-+		hashtab_destroy(p->symtab[i].table);
-+	}
-+
-+	for (i = 0; i < SYM_NUM; i++) {
-+		if (p->sym_val_to_name[i])
-+			kfree(p->sym_val_to_name[i]);
-+	}
-+
-+	if (p->class_val_to_struct)
-+		kfree(p->class_val_to_struct);
-+	if (p->role_val_to_struct)
-+		kfree(p->role_val_to_struct);
-+	if (p->user_val_to_struct)
-+		kfree(p->user_val_to_struct);
-+
-+	avtab_destroy(&p->te_avtab);
-+
-+	for (i = 0; i < OCON_NUM; i++) {
-+		c = p->ocontexts[i];
-+		while (c) {
-+			ctmp = c;
-+			c = c->next;
-+			context_destroy(&ctmp->context[0]);
-+			context_destroy(&ctmp->context[1]);
-+			if (i == OCON_ISID || i == OCON_FS ||
-+			    i == OCON_NETIF || i == OCON_FSUSE)
-+				kfree(ctmp->u.name);
-+			kfree(ctmp);
-+		}
-+	}
-+
-+	g = p->genfs;
-+	while (g) {
-+		kfree(g->fstype);
-+		c = g->head;
-+		while (c) {
-+			ctmp = c;
-+			c = c->next;
-+			context_destroy(&ctmp->context[0]);
-+			kfree(ctmp->u.name);
-+			kfree(ctmp);
-+		}
-+		gtmp = g;
-+		g = g->next;
-+		kfree(gtmp);
-+	}
-+
-+	return;
-+}
-+
-+/*
-+ * Load the initial SIDs specified in a policy database
-+ * structure into a SID table.
-+ */
-+int policydb_load_isids(struct policydb *p, struct sidtab *s)
-+{
-+	struct ocontext *head, *c;
-+	int rc;
-+
-+	rc = sidtab_init(s);
-+	if (rc) {
-+		printk(KERN_ERR "security:  out of memory on SID table init\n");
-+		goto out;
-+	}
-+
-+	head = p->ocontexts[OCON_ISID];
-+	for (c = head; c; c = c->next) {
-+		if (!c->context[0].user) {
-+			printk(KERN_ERR "security:  SID %s was never "
-+			       "defined.\n", c->u.name);
-+			rc = -EINVAL;
-+			goto out;
-+		}
-+		if (sidtab_insert(s, c->sid[0], &c->context[0])) {
-+			printk(KERN_ERR "security:  unable to load initial "
-+			       "SID %s.\n", c->u.name);
-+			rc = -EINVAL;
-+			goto out;
-+		}
-+	}
-+out:
-+	return rc;
-+}
-+
-+/*
-+ * Return 1 if the fields in the security context
-+ * structure `c' are valid.  Return 0 otherwise.
-+ */
-+int policydb_context_isvalid(struct policydb *p, struct context *c)
-+{
-+	struct role_datum *role;
-+	struct user_datum *usrdatum;
-+
-+	/*
-+	 * Role must be authorized for the type.
-+	 */
-+	if (!c->role || c->role > p->p_roles.nprim)
-+		return 0;
-+
-+	if (c->role != OBJECT_R_VAL) {
-+		role = p->role_val_to_struct[c->role - 1];
-+		if (!ebitmap_get_bit(&role->types,
-+				     c->type - 1))
-+			/* role may not be associated with type */
-+			return 0;
-+
-+		/*
-+		 * User must be authorized for the role.
-+		 */
-+		if (!c->user || c->user > p->p_users.nprim)
-+			return 0;
-+		usrdatum = p->user_val_to_struct[c->user - 1];
-+		if (!usrdatum)
-+			return 0;
-+
-+		if (!ebitmap_get_bit(&usrdatum->roles,
-+				     c->role - 1))
-+			/* user may not be associated with role */
-+			return 0;
-+	}
-+
-+	if (!mls_context_isvalid(p, c))
-+		return 0;
-+
-+	return 1;
-+}
-+
-+/*
-+ * Read and validate a security context structure
-+ * from a policydb binary representation file.
-+ */
-+static int context_read_and_validate(struct context *c,
-+				     struct policydb *p,
-+				     void *fp)
-+{
-+	u32 *buf;
-+	int rc = 0;
-+
-+	buf = next_entry(fp, sizeof(u32)*3);
-+	if (!buf) {
-+		printk(KERN_ERR "security: context truncated\n");
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	c->user = le32_to_cpu(buf[0]);
-+	c->role = le32_to_cpu(buf[1]);
-+	c->type = le32_to_cpu(buf[2]);
-+	if (mls_read_range(c, fp)) {
-+		printk(KERN_ERR "security: error reading MLS range of "
-+		       "context\n");
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+
-+	if (!policydb_context_isvalid(p, c)) {
-+		printk(KERN_ERR "security:  invalid security context\n");
-+		context_destroy(c);
-+		rc = -EINVAL;
-+	}
-+out:
-+	return rc;
-+}
-+
-+/*
-+ * The following *_read functions are used to
-+ * read the symbol data from a policy database
-+ * binary representation file.
-+ */
-+
-+static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct perm_datum *perdatum;
-+	int rc;
-+	u32 *buf, len;
-+
-+	perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
-+	if (!perdatum) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(perdatum, 0, sizeof(*perdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*2);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	perdatum->value = le32_to_cpu(buf[1]);
-+	rc = mls_read_perm(perdatum, fp);
-+	if (rc)
-+		goto bad;
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	rc = hashtab_insert(h, key, perdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	perm_destroy(key, perdatum, NULL);
-+	goto out;
-+}
-+
-+static int common_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct common_datum *comdatum;
-+	u32 *buf, len, nel;
-+	int i, rc;
-+
-+	comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
-+	if (!comdatum) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(comdatum, 0, sizeof(*comdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*4);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	comdatum->value = le32_to_cpu(buf[1]);
-+
-+	rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE);
-+	if (rc)
-+		goto bad;
-+	comdatum->permissions.nprim = le32_to_cpu(buf[2]);
-+	nel = le32_to_cpu(buf[3]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	for (i = 0; i < nel; i++) {
-+		rc = perm_read(p, comdatum->permissions.table, fp);
-+		if (rc)
-+			goto bad;
-+	}
-+
-+	rc = hashtab_insert(h, key, comdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	common_destroy(key, comdatum, NULL);
-+	goto out;
-+}
-+
-+static int class_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct class_datum *cladatum;
-+	struct constraint_node *c, *lc;
-+	struct constraint_expr *e, *le;
-+	u32 *buf, len, len2, ncons, nexpr, nel;
-+	int i, j, depth, rc;
-+
-+	cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
-+	if (!cladatum) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memset(cladatum, 0, sizeof(*cladatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*6);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	len2 = le32_to_cpu(buf[1]);
-+	cladatum->value = le32_to_cpu(buf[2]);
-+
-+	rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE);
-+	if (rc)
-+		goto bad;
-+	cladatum->permissions.nprim = le32_to_cpu(buf[3]);
-+	nel = le32_to_cpu(buf[4]);
-+
-+	ncons = le32_to_cpu(buf[5]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	if (len2) {
-+		cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL);
-+		if (!cladatum->comkey) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		buf = next_entry(fp, len2);
-+		if (!buf) {
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		memcpy(cladatum->comkey, buf, len2);
-+		cladatum->comkey[len2] = 0;
-+
-+		cladatum->comdatum = hashtab_search(p->p_commons.table,
-+						    cladatum->comkey);
-+		if (!cladatum->comdatum) {
-+			printk(KERN_ERR "security:  unknown common %s\n",
-+			       cladatum->comkey);
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+	}
-+	for (i = 0; i < nel; i++) {
-+		rc = perm_read(p, cladatum->permissions.table, fp);
-+		if (rc)
-+			goto bad;
-+	}
-+
-+	lc = NULL;
-+	rc = -EINVAL;
-+	for (i = 0; i < ncons; i++) {
-+		c = kmalloc(sizeof(*c), GFP_KERNEL);
-+		if (!c) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memset(c, 0, sizeof(*c));
-+		buf = next_entry(fp, sizeof(u32)*2);
-+		if (!buf)
-+			goto bad;
-+		c->permissions = le32_to_cpu(buf[0]);
-+		nexpr = le32_to_cpu(buf[1]);
-+		le = NULL;
-+		depth = -1;
-+		for (j = 0; j < nexpr; j++) {
-+			e = kmalloc(sizeof(*e), GFP_KERNEL);
-+			if (!e) {
-+				rc = -ENOMEM;
-+				goto bad;
-+			}
-+			memset(e, 0, sizeof(*e));
-+			buf = next_entry(fp, sizeof(u32)*3);
-+			if (!buf) {
-+				kfree(e);
-+				goto bad;
-+			}
-+			e->expr_type = le32_to_cpu(buf[0]);
-+			e->attr = le32_to_cpu(buf[1]);
-+			e->op = le32_to_cpu(buf[2]);
-+
-+			switch (e->expr_type) {
-+			case CEXPR_NOT:
-+				if (depth < 0) {
-+					kfree(e);
-+					goto bad;
-+				}
-+				break;
-+			case CEXPR_AND:
-+			case CEXPR_OR:
-+				if (depth < 1) {
-+					kfree(e);
-+					goto bad;
-+				}
-+				depth--;
-+				break;
-+			case CEXPR_ATTR:
-+				if (depth == (CEXPR_MAXDEPTH-1)) {
-+					kfree(e);
-+					goto bad;
-+				}
-+				depth++;
-+				break;
-+			case CEXPR_NAMES:
-+				if (depth == (CEXPR_MAXDEPTH-1)) {
-+					kfree(e);
-+					goto bad;
-+				}
-+				depth++;
-+				if (ebitmap_read(&e->names, fp)) {
-+					kfree(e);
-+					goto bad;
-+				}
-+				break;
-+			default:
-+				kfree(e);
-+				goto bad;
-+				break;
-+			}
-+			if (le) {
-+				le->next = e;
-+			} else {
-+				c->expr = e;
-+			}
-+			le = e;
-+		}
-+		if (depth != 0)
-+			goto bad;
-+		if (lc) {
-+			lc->next = c;
-+		} else {
-+			cladatum->constraints = c;
-+		}
-+		lc = c;
-+	}
-+
-+	rc = mls_read_class(cladatum, fp);
-+	if (rc)
-+		goto bad;
-+
-+	rc = hashtab_insert(h, key, cladatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	class_destroy(key, cladatum, NULL);
-+	goto out;
-+}
-+
-+static int role_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct role_datum *role;
-+	int rc;
-+	u32 *buf, len;
-+
-+	role = kmalloc(sizeof(*role), GFP_KERNEL);
-+	if (!role) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(role, 0, sizeof(*role));
-+
-+	buf = next_entry(fp, sizeof(u32)*2);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	role->value = le32_to_cpu(buf[1]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	rc = ebitmap_read(&role->dominates, fp);
-+	if (rc)
-+		goto bad;
-+
-+	rc = ebitmap_read(&role->types, fp);
-+	if (rc)
-+		goto bad;
-+
-+	if (strcmp(key, OBJECT_R) == 0) {
-+		if (role->value != OBJECT_R_VAL) {
-+			printk(KERN_ERR "Role %s has wrong value %d\n",
-+			       OBJECT_R, role->value);
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		rc = 0;
-+		goto bad;
-+	}
-+
-+	rc = hashtab_insert(h, key, role);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	role_destroy(key, role, NULL);
-+	goto out;
-+}
-+
-+static int type_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct type_datum *typdatum;
-+	int rc;
-+	u32 *buf, len;
-+
-+	typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
-+	if (!typdatum) {
-+		rc = -ENOMEM;
-+		return rc;
-+	}
-+	memset(typdatum, 0, sizeof(*typdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*3);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	typdatum->value = le32_to_cpu(buf[1]);
-+	typdatum->primary = le32_to_cpu(buf[2]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	rc = hashtab_insert(h, key, typdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	type_destroy(key, typdatum, NULL);
-+	goto out;
-+}
-+
-+static int user_read(struct policydb *p, struct hashtab *h, void *fp)
-+{
-+	char *key = 0;
-+	struct user_datum *usrdatum;
-+	int rc;
-+	u32 *buf, len;
-+
-+
-+	usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
-+	if (!usrdatum) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memset(usrdatum, 0, sizeof(*usrdatum));
-+
-+	buf = next_entry(fp, sizeof(u32)*2);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+
-+	len = le32_to_cpu(buf[0]);
-+	usrdatum->value = le32_to_cpu(buf[1]);
-+
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	key = kmalloc(len + 1,GFP_KERNEL);
-+	if (!key) {
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(key, buf, len);
-+	key[len] = 0;
-+
-+	rc = ebitmap_read(&usrdatum->roles, fp);
-+	if (rc)
-+		goto bad;
-+
-+	rc = mls_read_user(usrdatum, fp);
-+	if (rc)
-+		goto bad;
-+
-+	rc = hashtab_insert(h, key, usrdatum);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	user_destroy(key, usrdatum, NULL);
-+	goto out;
-+}
-+
-+static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
-+{
-+	common_read,
-+	class_read,
-+	role_read,
-+	type_read,
-+	user_read
-+	mls_read_f
-+};
-+
-+#define mls_config(x) \
-+       ((x) & POLICYDB_CONFIG_MLS) ? "mls" : "no_mls"
-+
-+/*
-+ * Read the configuration data from a policy database binary
-+ * representation file into a policy database structure.
-+ */
-+int policydb_read(struct policydb *p, void *fp)
-+{
-+	struct role_allow *ra, *lra;
-+	struct role_trans *tr, *ltr;
-+	struct ocontext *l, *c, *newc;
-+	struct genfs *genfs_p, *genfs, *newgenfs;
-+	int i, j, rc;
-+	u32 *buf, len, len2, config, nprim, nel, nel2;
-+	char *policydb_str;
-+
-+	config = 0;
-+	mls_set_config(config);
-+
-+	rc = policydb_init(p);
-+	if (rc)
-+		goto out;
-+
-+	rc = -EINVAL;
-+	/* Read the magic number and string length. */
-+	buf = next_entry(fp, sizeof(u32)* 2);
-+	if (!buf)
-+		goto bad;
-+
-+	for (i = 0; i < 2; i++)
-+		buf[i] = le32_to_cpu(buf[i]);
-+
-+	if (buf[0] != POLICYDB_MAGIC) {
-+		printk(KERN_ERR "security:  policydb magic number 0x%x does "
-+		       "not match expected magic number 0x%x\n",
-+		       buf[0], POLICYDB_MAGIC);
-+		goto bad;
-+	}
-+
-+	len = buf[1];
-+	if (len != strlen(POLICYDB_STRING)) {
-+		printk(KERN_ERR "security:  policydb string length %d does not "
-+		       "match expected length %d\n",
-+		       len, strlen(POLICYDB_STRING));
-+		goto bad;
-+	}
-+	buf = next_entry(fp, len);
-+	if (!buf) {
-+		printk(KERN_ERR "security:  truncated policydb string identifier\n");
-+		goto bad;
-+	}
-+	policydb_str = kmalloc(len + 1,GFP_KERNEL);
-+	if (!policydb_str) {
-+		printk(KERN_ERR "security:  unable to allocate memory for policydb "
-+		       "string of length %d\n", len);
-+		rc = -ENOMEM;
-+		goto bad;
-+	}
-+	memcpy(policydb_str, buf, len);
-+	policydb_str[len] = 0;
-+	if (strcmp(policydb_str, POLICYDB_STRING)) {
-+		printk(KERN_ERR "security:  policydb string %s does not match "
-+		       "my string %s\n", policydb_str, POLICYDB_STRING);
-+		kfree(policydb_str);
-+		goto bad;
-+	}
-+	/* Done with policydb_str. */
-+	kfree(policydb_str);
-+	policydb_str = NULL;
-+
-+	/* Read the version, config, and table sizes. */
-+	buf = next_entry(fp, sizeof(u32)*4);
-+	if (!buf)
-+		goto bad;
-+	for (i = 0; i < 4; i++)
-+		buf[i] = le32_to_cpu(buf[i]);
-+
-+	if (buf[0] != POLICYDB_VERSION) {
-+		printk(KERN_ERR "security:  policydb version %d does not match "
-+		       "my version %d\n", buf[0], POLICYDB_VERSION);
-+		goto bad;
-+	}
-+	if (buf[1] != config) {
-+		printk(KERN_ERR "security:  policydb configuration (%s) does "
-+		       "not match my configuration (%s)\n",
-+		       mls_config(buf[1]),
-+		       mls_config(config));
-+		goto bad;
-+	}
-+	if (buf[2] != SYM_NUM || buf[3] != OCON_NUM) {
-+		printk(KERN_ERR "security:  policydb table sizes (%d,%d) do "
-+		       "not match mine (%d,%d)\n",
-+		       buf[2], buf[3], SYM_NUM, OCON_NUM);
-+		goto bad;
-+	}
-+
-+	rc = mls_read_nlevels(p, fp);
-+	if (rc)
-+		goto bad;
-+
-+	for (i = 0; i < SYM_NUM; i++) {
-+		buf = next_entry(fp, sizeof(u32)*2);
-+		if (!buf) {
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		nprim = le32_to_cpu(buf[0]);
-+		nel = le32_to_cpu(buf[1]);
-+		for (j = 0; j < nel; j++) {
-+			rc = read_f[i](p, p->symtab[i].table, fp);
-+			if (rc)
-+				goto bad;
-+		}
-+
-+		p->symtab[i].nprim = nprim;
-+	}
-+
-+	rc = avtab_read(&p->te_avtab, fp, config);
-+	if (rc)
-+		goto bad;
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	nel = le32_to_cpu(buf[0]);
-+	ltr = NULL;
-+	for (i = 0; i < nel; i++) {
-+		tr = kmalloc(sizeof(*tr), GFP_KERNEL);
-+		if (!tr) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memset(tr, 0, sizeof(*tr));
-+		if (ltr) {
-+			ltr->next = tr;
-+		} else {
-+			p->role_tr = tr;
-+		}
-+		buf = next_entry(fp, sizeof(u32)*3);
-+		if (!buf) {
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		tr->role = le32_to_cpu(buf[0]);
-+		tr->type = le32_to_cpu(buf[1]);
-+		tr->new_role = le32_to_cpu(buf[2]);
-+		ltr = tr;
-+	}
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	nel = le32_to_cpu(buf[0]);
-+	lra = NULL;
-+	for (i = 0; i < nel; i++) {
-+		ra = kmalloc(sizeof(*ra), GFP_KERNEL);
-+		if (!ra) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memset(ra, 0, sizeof(*ra));
-+		if (lra) {
-+			lra->next = ra;
-+		} else {
-+			p->role_allow = ra;
-+		}
-+		buf = next_entry(fp, sizeof(u32)*2);
-+		if (!buf) {
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		ra->role = le32_to_cpu(buf[0]);
-+		ra->new_role = le32_to_cpu(buf[1]);
-+		lra = ra;
-+	}
-+
-+	rc = policydb_index_classes(p);
-+	if (rc)
-+		goto bad;
-+
-+	rc = policydb_index_others(p);
-+	if (rc)
-+		goto bad;
-+
-+	for (i = 0; i < OCON_NUM; i++) {
-+		buf = next_entry(fp, sizeof(u32));
-+		if (!buf) {
-+			rc = -EINVAL;
-+			goto bad;
-+		}
-+		nel = le32_to_cpu(buf[0]);
-+		l = NULL;
-+		for (j = 0; j < nel; j++) {
-+			c = kmalloc(sizeof(*c), GFP_KERNEL);
-+			if (!c) {
-+				rc = -ENOMEM;
-+				goto bad;
-+			}
-+			memset(c, 0, sizeof(*c));
-+			if (l) {
-+				l->next = c;
-+			} else {
-+				p->ocontexts[i] = c;
-+			}
-+			l = c;
-+			rc = -EINVAL;
-+			switch (i) {
-+			case OCON_ISID:
-+				buf = next_entry(fp, sizeof(u32));
-+				if (!buf)
-+					goto bad;
-+				c->sid[0] = le32_to_cpu(buf[0]);
-+				rc = context_read_and_validate(&c->context[0], p, fp);
-+				if (rc)
-+					goto bad;
-+				break;
-+			case OCON_FS:
-+			case OCON_NETIF:
-+				buf = next_entry(fp, sizeof(u32));
-+				if (!buf)
-+					goto bad;
-+				len = le32_to_cpu(buf[0]);
-+				buf = next_entry(fp, len);
-+				if (!buf)
-+					goto bad;
-+				c->u.name = kmalloc(len + 1,GFP_KERNEL);
-+				if (!c->u.name) {
-+					rc = -ENOMEM;
-+					goto bad;
-+				}
-+				memcpy(c->u.name, buf, len);
-+				c->u.name[len] = 0;
-+				rc = context_read_and_validate(&c->context[0], p, fp);
-+				if (rc)
-+					goto bad;
-+				rc = context_read_and_validate(&c->context[1], p, fp);
-+				if (rc)
-+					goto bad;
-+				break;
-+			case OCON_PORT:
-+				buf = next_entry(fp, sizeof(u32)*3);
-+				if (!buf)
-+					goto bad;
-+				c->u.port.protocol = le32_to_cpu(buf[0]);
-+				c->u.port.low_port = le32_to_cpu(buf[1]);
-+				c->u.port.high_port = le32_to_cpu(buf[2]);
-+				rc = context_read_and_validate(&c->context[0], p, fp);
-+				if (rc)
-+					goto bad;
-+				break;
-+			case OCON_NODE:
-+				buf = next_entry(fp, sizeof(u32)* 2);
-+				if (!buf)
-+					goto bad;
-+				c->u.node.addr = le32_to_cpu(buf[0]);
-+				c->u.node.mask = le32_to_cpu(buf[1]);
-+				rc = context_read_and_validate(&c->context[0], p, fp);
-+				if (rc)
-+					goto bad;
-+				break;
-+			case OCON_FSUSE:
-+				buf = next_entry(fp, sizeof(u32)*2);
-+				if (!buf)
-+					goto bad;
-+				c->v.behavior = le32_to_cpu(buf[0]);
-+				len = le32_to_cpu(buf[1]);
-+				buf = next_entry(fp, len);
-+				if (!buf)
-+					goto bad;
-+				c->u.name = kmalloc(len + 1,GFP_KERNEL);
-+				if (!c->u.name) {
-+					rc = -ENOMEM;
-+					goto bad;
-+				}
-+				memcpy(c->u.name, buf, len);
-+				c->u.name[len] = 0;
-+				rc = context_read_and_validate(&c->context[0], p, fp);
-+				if (rc)
-+					goto bad;
-+				break;
-+			}
-+		}
-+	}
-+
-+	buf = next_entry(fp, sizeof(u32));
-+	if (!buf) {
-+		rc = -EINVAL;
-+		goto bad;
-+	}
-+	nel = le32_to_cpu(buf[0]);
-+	genfs_p = NULL;
-+	rc = -EINVAL;
-+	for (i = 0; i < nel; i++) {
-+		newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
-+		if (!newgenfs) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memset(newgenfs, 0, sizeof(*newgenfs));
-+		buf = next_entry(fp, sizeof(u32));
-+		if (!buf)
-+			goto bad;
-+		len = le32_to_cpu(buf[0]);
-+		buf = next_entry(fp, len);
-+		if (!buf)
-+			goto bad;
-+		newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
-+		if (!newgenfs->fstype) {
-+			rc = -ENOMEM;
-+			goto bad;
-+		}
-+		memcpy(newgenfs->fstype, buf, len);
-+		newgenfs->fstype[len] = 0;
-+		for (genfs_p = NULL, genfs = p->genfs; genfs;
-+		     genfs_p = genfs, genfs = genfs->next) {
-+			if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
-+				printk(KERN_ERR "security:  dup genfs "
-+				       "fstype %s\n", newgenfs->fstype);
-+				goto bad;
-+			}
-+			if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
-+				break;
-+		}
-+		newgenfs->next = genfs;
-+		if (genfs_p)
-+			genfs_p->next = newgenfs;
-+		else
-+			p->genfs = newgenfs;
-+		buf = next_entry(fp, sizeof(u32));
-+		if (!buf)
-+			goto bad;
-+		nel2 = le32_to_cpu(buf[0]);
-+		for (j = 0; j < nel2; j++) {
-+			newc = kmalloc(sizeof(*newc), GFP_KERNEL);
-+			if (!newc) {
-+				rc = -ENOMEM;
-+				goto bad;
-+			}
-+			memset(newc, 0, sizeof(*newc));
-+			buf = next_entry(fp, sizeof(u32));
-+			if (!buf)
-+				goto bad;
-+			len = le32_to_cpu(buf[0]);
-+			buf = next_entry(fp, len);
-+			if (!buf)
-+				goto bad;
-+			newc->u.name = kmalloc(len + 1,GFP_KERNEL);
-+			if (!newc->u.name) {
-+				rc = -ENOMEM;
-+				goto bad;
-+			}
-+			memcpy(newc->u.name, buf, len);
-+			newc->u.name[len] = 0;
-+			buf = next_entry(fp, sizeof(u32));
-+			if (!buf)
-+				goto bad;
-+			newc->v.sclass = le32_to_cpu(buf[0]);
-+			if (context_read_and_validate(&newc->context[0], p, fp))
-+				goto bad;
-+			for (l = NULL, c = newgenfs->head; c;
-+			     l = c, c = c->next) {
-+				if (!strcmp(newc->u.name, c->u.name) &&
-+				    (!c->v.sclass || !newc->v.sclass ||
-+				     newc->v.sclass == c->v.sclass)) {
-+					printk(KERN_ERR "security:  dup genfs "
-+					       "entry (%s,%s)\n",
-+					       newgenfs->fstype, c->u.name);
-+					goto bad;
-+				}
-+				len = strlen(newc->u.name);
-+				len2 = strlen(c->u.name);
-+				if (len > len2)
-+					break;
-+			}
-+			newc->next = c;
-+			if (l)
-+				l->next = newc;
-+			else
-+				newgenfs->head = newc;
-+		}
-+	}
-+
-+	rc = mls_read_trusted(p, fp);
-+	if (rc)
-+		goto bad;
-+out:
-+	return rc;
-+bad:
-+	policydb_destroy(p);
-+	goto out;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/policydb.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,256 @@
-+/*
-+ * A policy database (policydb) specifies the
-+ * configuration data for the security policy.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_POLICYDB_H_
-+#define _SS_POLICYDB_H_
-+
-+#include "symtab.h"
-+#include "avtab.h"
-+#include "sidtab.h"
-+#include "context.h"
-+#include "constraint.h"
-+
-+/*
-+ * A datum type is defined for each kind of symbol
-+ * in the configuration data:  individual permissions,
-+ * common prefixes for access vectors, classes,
-+ * users, roles, types, sensitivities, categories, etc.
-+ */
-+
-+/* Permission attributes */
-+struct perm_datum {
-+	u32 value;		/* permission bit + 1 */
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+#define MLS_BASE_READ    1	/* MLS base permission `read' */
-+#define MLS_BASE_WRITE   2	/* MLS base permission `write' */
-+#define MLS_BASE_READBY  4	/* MLS base permission `readby' */
-+#define MLS_BASE_WRITEBY 8	/* MLS base permission `writeby' */
-+	u32 base_perms;		/* MLS base permission mask */
-+#endif
-+};
-+
-+/* Attributes of a common prefix for access vectors */
-+struct common_datum {
-+	u32 value;			/* internal common value */
-+	struct symtab permissions;	/* common permissions */
-+};
-+
-+/* Class attributes */
-+struct class_datum {
-+	u32 value;			/* class value */
-+	char *comkey;			/* common name */
-+	struct common_datum *comdatum;	/* common datum */
-+	struct symtab permissions;	/* class-specific permission symbol table */
-+	struct constraint_node *constraints;	/* constraints on class permissions */
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+	struct mls_perms mlsperms;	/* MLS base permission masks */
-+#endif
-+};
-+
-+/* Role attributes */
-+struct role_datum {
-+	u32 value;			/* internal role value */
-+	struct ebitmap dominates;	/* set of roles dominated by this role */
-+	struct ebitmap types;		/* set of authorized types for role */
-+};
-+
-+struct role_trans {
-+	u32 role;		/* current role */
-+	u32 type;		/* program executable type */
-+	u32 new_role;		/* new role */
-+	struct role_trans *next;
-+};
-+
-+struct role_allow {
-+	u32 role;		/* current role */
-+	u32 new_role;		/* new role */
-+	struct role_allow *next;
-+};
-+
-+/* Type attributes */
-+struct type_datum {
-+	u32 value;		/* internal type value */
-+	unsigned char primary;	/* primary name? */
-+};
-+
-+/* User attributes */
-+struct user_datum {
-+	u32 value;			/* internal user value */
-+	struct ebitmap roles;		/* set of authorized roles for user */
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+	struct mls_range_list *ranges;	/* list of authorized MLS ranges for user */
-+#endif
-+};
-+
-+
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+/* Sensitivity attributes */
-+struct level_datum {
-+	struct mls_level *level;	/* sensitivity and associated categories */
-+	unsigned char isalias;	/* is this sensitivity an alias for another? */
-+};
-+
-+/* Category attributes */
-+struct cat_datum {
-+	u32 value;		/* internal category bit + 1 */
-+	unsigned char isalias;  /* is this category an alias for another? */
-+};
-+#endif
-+
-+
-+/*
-+ * The configuration data includes security contexts for
-+ * initial SIDs, unlabeled file systems, TCP and UDP port numbers,
-+ * network interfaces, and nodes.  This structure stores the
-+ * relevant data for one such entry.  Entries of the same kind
-+ * (e.g. all initial SIDs) are linked together into a list.
-+ */
-+struct ocontext {
-+	union {
-+		char *name;	/* name of initial SID, fs, netif, fstype, path */
-+		struct {
-+			u8 protocol;
-+			u16 low_port;
-+			u16 high_port;
-+		} port;		/* TCP or UDP port information */
-+		struct {
-+			u32 addr;
-+			u32 mask;
-+		} node;		/* node information */
-+	} u;
-+	union {
-+		u32 sclass;  /* security class for genfs */
-+		u32 behavior;  /* labeling behavior for fs_use */
-+	} v;
-+	struct context context[2];	/* security context(s) */
-+	u32 sid[2];	/* SID(s) */
-+	struct ocontext *next;
-+};
-+
-+struct genfs {
-+	char *fstype;
-+	struct ocontext *head;
-+	struct genfs *next;
-+};
-+
-+/* symbol table array indices */
-+#define SYM_COMMONS 0
-+#define SYM_CLASSES 1
-+#define SYM_ROLES   2
-+#define SYM_TYPES   3
-+#define SYM_USERS   4
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+#define SYM_LEVELS  5
-+#define SYM_CATS    6
-+#define SYM_NUM     7
-+#else
-+#define SYM_NUM     5
-+#endif
-+
-+/* object context array indices */
-+#define OCON_ISID  0	/* initial SIDs */
-+#define OCON_FS    1	/* unlabeled file systems */
-+#define OCON_PORT  2	/* TCP and UDP port numbers */
-+#define OCON_NETIF 3	/* network interfaces */
-+#define OCON_NODE  4	/* nodes */
-+#define OCON_FSUSE 5	/* fs_use */
-+#define OCON_NUM   6
-+
-+/* The policy database */
-+struct policydb {
-+	/* symbol tables */
-+	struct symtab symtab[SYM_NUM];
-+#define p_commons symtab[SYM_COMMONS]
-+#define p_classes symtab[SYM_CLASSES]
-+#define p_roles symtab[SYM_ROLES]
-+#define p_types symtab[SYM_TYPES]
-+#define p_users symtab[SYM_USERS]
-+#define p_levels symtab[SYM_LEVELS]
-+#define p_cats symtab[SYM_CATS]
-+
-+	/* symbol names indexed by (value - 1) */
-+	char **sym_val_to_name[SYM_NUM];
-+#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
-+#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
-+#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
-+#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
-+#define p_user_val_to_name sym_val_to_name[SYM_USERS]
-+#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
-+#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
-+
-+	/* class, role, and user attributes indexed by (value - 1) */
-+	struct class_datum **class_val_to_struct;
-+	struct role_datum **role_val_to_struct;
-+	struct user_datum **user_val_to_struct;
-+
-+	/* type enforcement access vectors and transitions */
-+	struct avtab te_avtab;
-+
-+	/* role transitions */
-+	struct role_trans *role_tr;
-+
-+	/* role allows */
-+	struct role_allow *role_allow;
-+
-+	/* security contexts of initial SIDs, unlabeled file systems,
-+	   TCP or UDP port numbers, network interfaces and nodes */
-+	struct ocontext *ocontexts[OCON_NUM];
-+
-+        /* security contexts for files in filesystems that cannot support
-+	   a persistent label mapping or use another
-+	   fixed labeling behavior. */
-+  	struct genfs *genfs;
-+
-+#ifdef CONFIG_SECURITY_SELINUX_MLS
-+	/* number of legitimate MLS levels */
-+	u32 nlevels;
-+
-+	struct ebitmap trustedreaders;
-+	struct ebitmap trustedwriters;
-+	struct ebitmap trustedobjects;
-+#endif
-+};
-+
-+extern int policydb_init(struct policydb *p);
-+extern int policydb_index_classes(struct policydb *p);
-+extern int policydb_index_others(struct policydb *p);
-+extern int constraint_expr_destroy(struct constraint_expr *expr);
-+extern void policydb_destroy(struct policydb *p);
-+extern int policydb_load_isids(struct policydb *p, struct sidtab *s);
-+extern int policydb_context_isvalid(struct policydb *p, struct context *c);
-+extern int policydb_read(struct policydb *p, void *fp);
-+
-+#define PERM_SYMTAB_SIZE 32
-+
-+#define POLICYDB_VERSION 15
-+#define POLICYDB_CONFIG_MLS    1
-+
-+#define OBJECT_R "object_r"
-+#define OBJECT_R_VAL 1
-+
-+#define POLICYDB_MAGIC SELINUX_MAGIC
-+#define POLICYDB_STRING "SE Linux"
-+
-+struct policy_file {
-+	char *data;
-+	size_t len;
-+};
-+
-+static inline void *next_entry(struct policy_file *fp, size_t bytes)
-+{
-+	void *buf;
-+
-+	if (bytes > fp->len)
-+		return NULL;
-+
-+	buf = fp->data;
-+	fp->data += bytes;
-+	fp->len -= bytes;
-+	return buf;
-+}
-+
-+#endif	/* _SS_POLICYDB_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/services.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,1413 @@
-+/*
-+ * Implementation of the security services.
-+ *
-+ * Authors : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ *           James Morris <jmorris@redhat.com>
-+ *
-+ *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
-+ *
-+ *	This program is free software; you can redistribute it and/or modify
-+ *	it under the terms of the GNU General Public License version 2,
-+ *      as published by the Free Software Foundation.
-+ */
-+#include "context.h"
-+#include "policydb.h"
-+#include "sidtab.h"
-+#include "services.h"
-+#include "mls.h"
-+
-+static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
-+#define POLICY_RDLOCK read_lock(&policy_rwlock)
-+#define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
-+#define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
-+#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
-+
-+static DECLARE_MUTEX(load_sem);
-+#define LOAD_LOCK down(&load_sem)
-+#define LOAD_UNLOCK up(&load_sem)
-+
-+struct sidtab sidtab;
-+struct policydb policydb;
-+int ss_initialized = 0;
-+
-+/*
-+ * The largest sequence number that has been used when
-+ * providing an access decision to the access vector cache.
-+ * The sequence number only changes when a policy change
-+ * occurs.
-+ */
-+static u32 latest_granting = 0;
-+
-+/*
-+ * Return the boolean value of a constraint expression
-+ * when it is applied to the specified source and target
-+ * security contexts.
-+ */
-+static int constraint_expr_eval(struct context *scontext,
-+				struct context *tcontext,
-+				struct constraint_expr *cexpr)
-+{
-+	u32 val1, val2;
-+	struct context *c;
-+	struct role_datum *r1, *r2;
-+	struct constraint_expr *e;
-+	int s[CEXPR_MAXDEPTH];
-+	int sp = -1;
-+
-+	for (e = cexpr; e; e = e->next) {
-+		switch (e->expr_type) {
-+		case CEXPR_NOT:
-+			BUG_ON(sp < 0);
-+			s[sp] = !s[sp];
-+			break;
-+		case CEXPR_AND:
-+			BUG_ON(sp < 1);
-+			sp--;
-+			s[sp] &= s[sp+1];
-+			break;
-+		case CEXPR_OR:
-+			BUG_ON(sp < 1);
-+			sp--;
-+			s[sp] |= s[sp+1];
-+			break;
-+		case CEXPR_ATTR:
-+			if (sp == (CEXPR_MAXDEPTH-1))
-+				return 0;
-+			switch (e->attr) {
-+			case CEXPR_USER:
-+				val1 = scontext->user;
-+				val2 = tcontext->user;
-+				break;
-+			case CEXPR_TYPE:
-+				val1 = scontext->type;
-+				val2 = tcontext->type;
-+				break;
-+			case CEXPR_ROLE:
-+				val1 = scontext->role;
-+				val2 = tcontext->role;
-+				r1 = policydb.role_val_to_struct[val1 - 1];
-+				r2 = policydb.role_val_to_struct[val2 - 1];
-+				switch (e->op) {
-+				case CEXPR_DOM:
-+					s[++sp] = ebitmap_get_bit(&r1->dominates,
-+								  val2 - 1);
-+					continue;
-+				case CEXPR_DOMBY:
-+					s[++sp] = ebitmap_get_bit(&r2->dominates,
-+								  val1 - 1);
-+					continue;
-+				case CEXPR_INCOMP:
-+					s[++sp] = ( !ebitmap_get_bit(&r1->dominates,
-+								     val2 - 1) &&
-+						    !ebitmap_get_bit(&r2->dominates,
-+								     val1 - 1) );
-+					continue;
-+				default:
-+					break;
-+				}
-+				break;
-+			default:
-+				BUG();
-+				return 0;
-+			}
-+
-+			switch (e->op) {
-+			case CEXPR_EQ:
-+				s[++sp] = (val1 == val2);
-+				break;
-+			case CEXPR_NEQ:
-+				s[++sp] = (val1 != val2);
-+				break;
-+			default:
-+				BUG();
-+				return 0;
-+			}
-+			break;
-+		case CEXPR_NAMES:
-+			if (sp == (CEXPR_MAXDEPTH-1))
-+				return 0;
-+			c = scontext;
-+			if (e->attr & CEXPR_TARGET)
-+				c = tcontext;
-+			if (e->attr & CEXPR_USER)
-+				val1 = c->user;
-+			else if (e->attr & CEXPR_ROLE)
-+				val1 = c->role;
-+			else if (e->attr & CEXPR_TYPE)
-+				val1 = c->type;
-+			else {
-+				BUG();
-+				return 0;
-+			}
-+
-+			switch (e->op) {
-+			case CEXPR_EQ:
-+				s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
-+				break;
-+			case CEXPR_NEQ:
-+				s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
-+				break;
-+			default:
-+				BUG();
-+				return 0;
-+			}
-+			break;
-+		default:
-+			BUG();
-+			return 0;
-+		}
-+	}
-+
-+	BUG_ON(sp != 0);
-+	return s[0];
-+}
-+
-+/*
-+ * Compute access vectors based on a context structure pair for
-+ * the permissions in a particular class.
-+ */
-+static int context_struct_compute_av(struct context *scontext,
-+				     struct context *tcontext,
-+				     u16 tclass,
-+				     u32 requested,
-+				     struct av_decision *avd)
-+{
-+	struct constraint_node *constraint;
-+	struct role_allow *ra;
-+	struct avtab_key avkey;
-+	struct avtab_datum *avdatum;
-+	struct class_datum *tclass_datum;
-+
-+	if (!tclass || tclass > policydb.p_classes.nprim) {
-+		printk(KERN_ERR "security_compute_av:  unrecognized class %d\n",
-+		       tclass);
-+		return -EINVAL;
-+	}
-+	tclass_datum = policydb.class_val_to_struct[tclass - 1];
-+
-+	/*
-+	 * Initialize the access vectors to the default values.
-+	 */
-+	avd->allowed = 0;
-+	avd->decided = 0xffffffff;
-+	avd->auditallow = 0;
-+	avd->auditdeny = 0xffffffff;
-+	avd->seqno = latest_granting;
-+
-+	/*
-+	 * If a specific type enforcement rule was defined for
-+	 * this permission check, then use it.
-+	 */
-+	avkey.source_type = scontext->type;
-+	avkey.target_type = tcontext->type;
-+	avkey.target_class = tclass;
-+	avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV);
-+	if (avdatum) {
-+		if (avdatum->specified & AVTAB_ALLOWED)
-+			avd->allowed = avtab_allowed(avdatum);
-+		if (avdatum->specified & AVTAB_AUDITDENY)
-+			avd->auditdeny = avtab_auditdeny(avdatum);
-+		if (avdatum->specified & AVTAB_AUDITALLOW)
-+			avd->auditallow = avtab_auditallow(avdatum);
-+	}
-+
-+	/*
-+	 * Remove any permissions prohibited by the MLS policy.
-+	 */
-+	mls_compute_av(scontext, tcontext, tclass_datum, &avd->allowed);
-+
-+	/*
-+	 * Remove any permissions prohibited by a constraint.
-+	 */
-+	constraint = tclass_datum->constraints;
-+	while (constraint) {
-+		if ((constraint->permissions & (avd->allowed)) &&
-+		    !constraint_expr_eval(scontext, tcontext,
-+					  constraint->expr)) {
-+			avd->allowed = (avd->allowed) & ~(constraint->permissions);
-+		}
-+		constraint = constraint->next;
-+	}
-+
-+	/*
-+	 * If checking process transition permission and the
-+	 * role is changing, then check the (current_role, new_role)
-+	 * pair.
-+	 */
-+	if (tclass == SECCLASS_PROCESS &&
-+	    avd->allowed && PROCESS__TRANSITION &&
-+	    scontext->role != tcontext->role) {
-+		for (ra = policydb.role_allow; ra; ra = ra->next) {
-+			if (scontext->role == ra->role &&
-+			    tcontext->role == ra->new_role)
-+				break;
-+		}
-+		if (!ra)
-+			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION);
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * security_compute_av - Compute access vector decisions.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @requested: requested permissions
-+ * @avd: access vector decisions
-+ *
-+ * Compute a set of access vector decisions based on the
-+ * SID pair (@ssid, @tsid) for the permissions in @tclass.
-+ * Return -%EINVAL if any of the parameters are invalid or %0
-+ * if the access vector decisions were computed successfully.
-+ */
-+int security_compute_av(u32 ssid,
-+			u32 tsid,
-+			u16 tclass,
-+			u32 requested,
-+			struct av_decision *avd)
-+{
-+	struct context *scontext = 0, *tcontext = 0;
-+	int rc = 0;
-+
-+	if (!ss_initialized) {
-+		avd->allowed = requested;
-+		avd->decided = requested;
-+		avd->auditallow = 0;
-+		avd->auditdeny = 0xffffffff;
-+		avd->seqno = latest_granting;
-+		return 0;
-+	}
-+
-+	POLICY_RDLOCK;
-+
-+	scontext = sidtab_search(&sidtab, ssid);
-+	if (!scontext) {
-+		printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
-+		       ssid);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	tcontext = sidtab_search(&sidtab, tsid);
-+	if (!tcontext) {
-+		printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
-+		       tsid);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+
-+	rc = context_struct_compute_av(scontext, tcontext, tclass,
-+				       requested, avd);
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
-+
-+/*
-+ * Write the security context string representation of
-+ * the context structure `context' into a dynamically
-+ * allocated string of the correct size.  Set `*scontext'
-+ * to point to this string and set `*scontext_len' to
-+ * the length of the string.
-+ */
-+int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len)
-+{
-+	char *scontextp;
-+
-+	*scontext = 0;
-+	*scontext_len = 0;
-+
-+	/* Compute the size of the context. */
-+	*scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
-+	*scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
-+	*scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
-+	*scontext_len += mls_compute_context_len(context);
-+
-+	/* Allocate space for the context; caller must free this space. */
-+	scontextp = kmalloc(*scontext_len+1,GFP_ATOMIC);
-+	if (!scontextp) {
-+		return -ENOMEM;
-+	}
-+	*scontext = scontextp;
-+
-+	/*
-+	 * Copy the user name, role name and type name into the context.
-+	 */
-+	sprintf(scontextp, "%s:%s:%s:",
-+		policydb.p_user_val_to_name[context->user - 1],
-+		policydb.p_role_val_to_name[context->role - 1],
-+		policydb.p_type_val_to_name[context->type - 1]);
-+	scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
-+	             1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
-+	             1 + strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
-+
-+	mls_sid_to_context(context, &scontextp);
-+
-+	scontextp--;
-+	*scontextp = 0;
-+
-+	return 0;
-+}
-+
-+#include "initial_sid_to_string.h"
-+
-+/**
-+ * security_sid_to_context - Obtain a context for a given SID.
-+ * @sid: security identifier, SID
-+ * @scontext: security context
-+ * @scontext_len: length in bytes
-+ *
-+ * Write the string representation of the context associated with @sid
-+ * into a dynamically allocated string of the correct size.  Set @scontext
-+ * to point to this string and set @scontext_len to the length of the string.
-+ */
-+int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
-+{
-+	struct context *context;
-+	int rc = 0;
-+
-+	if (!ss_initialized) {
-+		if (sid <= SECINITSID_NUM) {
-+			char *scontextp;
-+
-+			*scontext_len = strlen(initial_sid_to_string[sid]) + 1;
-+			scontextp = kmalloc(*scontext_len,GFP_KERNEL);
-+			strcpy(scontextp, initial_sid_to_string[sid]);
-+			*scontext = scontextp;
-+			goto out;
-+		}
-+		printk(KERN_ERR "security_sid_to_context:  called before initial "
-+		       "load_policy on unknown SID %d\n", sid);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	POLICY_RDLOCK;
-+	context = sidtab_search(&sidtab, sid);
-+	if (!context) {
-+		printk(KERN_ERR "security_sid_to_context:  unrecognized SID "
-+		       "%d\n", sid);
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+	rc = context_struct_to_string(context, scontext, scontext_len);
-+out_unlock:
-+	POLICY_RDUNLOCK;
-+out:
-+	return rc;
-+
-+}
-+
-+/**
-+ * security_context_to_sid - Obtain a SID for a given security context.
-+ * @scontext: security context
-+ * @scontext_len: length in bytes
-+ * @sid: security identifier, SID
-+ *
-+ * Obtains a SID associated with the security context that
-+ * has the string representation specified by @scontext.
-+ * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
-+ * memory is available, or 0 on success.
-+ */
-+int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
-+{
-+	char *scontext2;
-+	struct context context;
-+	struct role_datum *role;
-+	struct type_datum *typdatum;
-+	struct user_datum *usrdatum;
-+	char *scontextp, *p, oldc;
-+	int rc = 0;
-+
-+	if (!ss_initialized) {
-+		int i;
-+
-+		for (i = 1; i < SECINITSID_NUM; i++) {
-+			if (!strcmp(initial_sid_to_string[i], scontext)) {
-+				*sid = i;
-+				goto out;
-+			}
-+		}
-+		printk(KERN_ERR "security_context_to_sid: called before "
-+		       "initial load_policy on unknown context %s\n", scontext);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	*sid = SECSID_NULL;
-+
-+	/* Copy the string so that we can modify the copy as we parse it.
-+	   The string should already by null terminated, but we append a
-+	   null suffix to the copy to avoid problems with the existing
-+	   attr package, which doesn't view the null terminator as part
-+	   of the attribute value. */
-+	scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);
-+	if (!scontext2) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	memcpy(scontext2, scontext, scontext_len);
-+	scontext2[scontext_len] = 0;
-+
-+	context_init(&context);
-+	*sid = SECSID_NULL;
-+
-+	POLICY_RDLOCK;
-+
-+	/* Parse the security context. */
-+
-+	rc = -EINVAL;
-+	scontextp = (char *) scontext2;
-+
-+	/* Extract the user. */
-+	p = scontextp;
-+	while (*p && *p != ':')
-+		p++;
-+
-+	if (*p == 0)
-+		goto out_unlock;
-+
-+	*p++ = 0;
-+
-+	usrdatum = hashtab_search(policydb.p_users.table, scontextp);
-+	if (!usrdatum)
-+		goto out_unlock;
-+
-+	context.user = usrdatum->value;
-+
-+	/* Extract role. */
-+	scontextp = p;
-+	while (*p && *p != ':')
-+		p++;
-+
-+	if (*p == 0)
-+		goto out_unlock;
-+
-+	*p++ = 0;
-+
-+	role = hashtab_search(policydb.p_roles.table, scontextp);
-+	if (!role)
-+		goto out_unlock;
-+	context.role = role->value;
-+
-+	/* Extract type. */
-+	scontextp = p;
-+	while (*p && *p != ':')
-+		p++;
-+	oldc = *p;
-+	*p++ = 0;
-+
-+	typdatum = hashtab_search(policydb.p_types.table, scontextp);
-+	if (!typdatum)
-+		goto out_unlock;
-+
-+	context.type = typdatum->value;
-+
-+	rc = mls_context_to_sid(oldc, &p, &context);
-+	if (rc)
-+		goto out_unlock;
-+
-+	/* Check the validity of the new context. */
-+	if (!policydb_context_isvalid(&policydb, &context)) {
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+	/* Obtain the new sid. */
-+	rc = sidtab_context_to_sid(&sidtab, &context, sid);
-+out_unlock:
-+	POLICY_RDUNLOCK;
-+	context_destroy(&context);
-+	kfree(scontext2);
-+out:
-+	return rc;
-+}
-+
-+static inline int compute_sid_handle_invalid_context(
-+	struct context *scontext,
-+	struct context *tcontext,
-+	u16 tclass,
-+	struct context *newcontext)
-+{
-+	int rc = 0;
-+
-+	if (selinux_enforcing) {
-+		rc = -EACCES;
-+	} else {
-+		char *s, *t, *n;
-+		u32 slen, tlen, nlen;
-+
-+		context_struct_to_string(scontext, &s, &slen);
-+		context_struct_to_string(tcontext, &t, &tlen);
-+		context_struct_to_string(newcontext, &n, &nlen);
-+		printk(KERN_ERR "security_compute_sid:  invalid context %s", n);
-+		printk(" for scontext=%s", s);
-+		printk(" tcontext=%s", t);
-+		printk(" tclass=%s\n", policydb.p_class_val_to_name[tclass-1]);
-+		kfree(s);
-+		kfree(t);
-+		kfree(n);
-+	}
-+	return rc;
-+}
-+
-+static int security_compute_sid(u32 ssid,
-+				u32 tsid,
-+				u16 tclass,
-+				u32 specified,
-+				u32 *out_sid)
-+{
-+	struct context *scontext = 0, *tcontext = 0, newcontext;
-+	struct role_trans *roletr = 0;
-+	struct avtab_key avkey;
-+	struct avtab_datum *avdatum;
-+	unsigned int type_change = 0;
-+	int rc = 0;
-+
-+	if (!ss_initialized) {
-+		switch (tclass) {
-+		case SECCLASS_PROCESS:
-+			*out_sid = ssid;
-+			break;
-+		default:
-+			*out_sid = tsid;
-+			break;
-+		}
-+		goto out;
-+	}
-+
-+	POLICY_RDLOCK;
-+
-+	scontext = sidtab_search(&sidtab, ssid);
-+	if (!scontext) {
-+		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
-+		       ssid);
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+	tcontext = sidtab_search(&sidtab, tsid);
-+	if (!tcontext) {
-+		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
-+		       tsid);
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+
-+	context_init(&newcontext);
-+
-+	/* Set the user identity. */
-+	switch (specified) {
-+	case AVTAB_TRANSITION:
-+	case AVTAB_CHANGE:
-+		/* Use the process user identity. */
-+		newcontext.user = scontext->user;
-+		break;
-+	case AVTAB_MEMBER:
-+		/* Use the related object owner. */
-+		newcontext.user = tcontext->user;
-+		break;
-+	}
-+
-+	/* Set the role and type to default values. */
-+	switch (tclass) {
-+	case SECCLASS_PROCESS:
-+		/* Use the current role and type of process. */
-+		newcontext.role = scontext->role;
-+		newcontext.type = scontext->type;
-+		break;
-+	default:
-+		/* Use the well-defined object role. */
-+		newcontext.role = OBJECT_R_VAL;
-+		/* Use the type of the related object. */
-+		newcontext.type = tcontext->type;
-+	}
-+
-+	/* Look for a type transition/member/change rule. */
-+	avkey.source_type = scontext->type;
-+	avkey.target_type = tcontext->type;
-+	avkey.target_class = tclass;
-+	avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE);
-+	type_change = (avdatum && (avdatum->specified & specified));
-+	if (type_change) {
-+		/* Use the type from the type transition/member/change rule. */
-+		switch (specified) {
-+		case AVTAB_TRANSITION:
-+			newcontext.type = avtab_transition(avdatum);
-+			break;
-+		case AVTAB_MEMBER:
-+			newcontext.type = avtab_member(avdatum);
-+			break;
-+		case AVTAB_CHANGE:
-+			newcontext.type = avtab_change(avdatum);
-+			break;
-+		}
-+	}
-+
-+	/* Check for class-specific changes. */
-+	switch (tclass) {
-+	case SECCLASS_PROCESS:
-+		if (specified & AVTAB_TRANSITION) {
-+			/* Look for a role transition rule. */
-+			for (roletr = policydb.role_tr; roletr;
-+			     roletr = roletr->next) {
-+				if (roletr->role == scontext->role &&
-+				    roletr->type == tcontext->type) {
-+					/* Use the role transition rule. */
-+					newcontext.role = roletr->new_role;
-+					break;
-+				}
-+			}
-+		}
-+
-+		if (!type_change && !roletr) {
-+			/* No change in process role or type. */
-+			*out_sid = ssid;
-+			goto out_unlock;
-+
-+		}
-+		break;
-+	default:
-+		if (!type_change &&
-+		    (newcontext.user == tcontext->user) &&
-+		    mls_context_cmp(scontext, tcontext)) {
-+                        /* No change in object type, owner,
-+			   or MLS attributes. */
-+			*out_sid = tsid;
-+			goto out_unlock;
-+		}
-+		break;
-+	}
-+
-+	/* Set the MLS attributes.
-+	   This is done last because it may allocate memory. */
-+	rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
-+	if (rc)
-+		goto out_unlock;
-+
-+	/* Check the validity of the context. */
-+	if (!policydb_context_isvalid(&policydb, &newcontext)) {
-+		rc = compute_sid_handle_invalid_context(scontext,
-+							tcontext,
-+							tclass,
-+							&newcontext);
-+		if (rc)
-+			goto out_unlock;
-+	}
-+	/* Obtain the sid for the context. */
-+	rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
-+out_unlock:
-+	POLICY_RDUNLOCK;
-+	context_destroy(&newcontext);
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * security_transition_sid - Compute the SID for a new subject/object.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @out_sid: security identifier for new subject/object
-+ *
-+ * Compute a SID to use for labeling a new subject or object in the
-+ * class @tclass based on a SID pair (@ssid, @tsid).
-+ * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
-+ * if insufficient memory is available, or %0 if the new SID was
-+ * computed successfully.
-+ */
-+int security_transition_sid(u32 ssid,
-+			    u32 tsid,
-+			    u16 tclass,
-+			    u32 *out_sid)
-+{
-+	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
-+}
-+
-+/**
-+ * security_member_sid - Compute the SID for member selection.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @out_sid: security identifier for selected member
-+ *
-+ * Compute a SID to use when selecting a member of a polyinstantiated
-+ * object of class @tclass based on a SID pair (@ssid, @tsid).
-+ * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
-+ * if insufficient memory is available, or %0 if the SID was
-+ * computed successfully.
-+ */
-+int security_member_sid(u32 ssid,
-+			u32 tsid,
-+			u16 tclass,
-+			u32 *out_sid)
-+{
-+	return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
-+}
-+
-+/**
-+ * security_change_sid - Compute the SID for object relabeling.
-+ * @ssid: source security identifier
-+ * @tsid: target security identifier
-+ * @tclass: target security class
-+ * @out_sid: security identifier for selected member
-+ *
-+ * Compute a SID to use for relabeling an object of class @tclass
-+ * based on a SID pair (@ssid, @tsid).
-+ * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
-+ * if insufficient memory is available, or %0 if the SID was
-+ * computed successfully.
-+ */
-+int security_change_sid(u32 ssid,
-+			u32 tsid,
-+			u16 tclass,
-+			u32 *out_sid)
-+{
-+	return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
-+}
-+
-+/*
-+ * Verify that each permission that is defined under the
-+ * existing policy is still defined with the same value
-+ * in the new policy.
-+ */
-+static int validate_perm(void *key, void *datum, void *p)
-+{
-+	struct hashtab *h;
-+	struct perm_datum *perdatum, *perdatum2;
-+	int rc = 0;
-+
-+
-+	h = p;
-+	perdatum = datum;
-+
-+	perdatum2 = hashtab_search(h, key);
-+	if (!perdatum2) {
-+		printk(KERN_ERR "security:  permission %s disappeared",
-+		       (char *)key);
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+	if (perdatum->value != perdatum2->value) {
-+		printk(KERN_ERR "security:  the value of permission %s changed",
-+		       (char *)key);
-+		rc = -EINVAL;
-+	}
-+out:
-+	return rc;
-+}
-+
-+/*
-+ * Verify that each class that is defined under the
-+ * existing policy is still defined with the same
-+ * attributes in the new policy.
-+ */
-+static int validate_class(void *key, void *datum, void *p)
-+{
-+	struct policydb *newp;
-+	struct class_datum *cladatum, *cladatum2;
-+	int rc;
-+
-+	newp = p;
-+	cladatum = datum;
-+
-+	cladatum2 = hashtab_search(newp->p_classes.table, key);
-+	if (!cladatum2) {
-+		printk(KERN_ERR "security:  class %s disappeared\n",
-+		       (char *)key);
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+	if (cladatum->value != cladatum2->value) {
-+		printk(KERN_ERR "security:  the value of class %s changed\n",
-+		       (char *)key);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	if ((cladatum->comdatum && !cladatum2->comdatum) ||
-+	    (!cladatum->comdatum && cladatum2->comdatum)) {
-+		printk(KERN_ERR "security:  the inherits clause for the access "
-+		       "vector definition for class %s changed\n", (char *)key);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+	if (cladatum->comdatum) {
-+		rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
-+		                 cladatum2->comdatum->permissions.table);
-+		if (rc) {
-+			printk(" in the access vector definition for class "
-+			       "%s\n", (char *)key);
-+			goto out;
-+		}
-+	}
-+	rc = hashtab_map(cladatum->permissions.table, validate_perm,
-+	                 cladatum2->permissions.table);
-+	if (rc)
-+		printk(" in access vector definition for class %s\n",
-+		       (char *)key);
-+out:
-+	return rc;
-+}
-+
-+/* Clone the SID into the new SID table. */
-+static int clone_sid(u32 sid,
-+		     struct context *context,
-+		     void *arg)
-+{
-+	struct sidtab *s = arg;
-+
-+	return sidtab_insert(s, sid, context);
-+}
-+
-+static inline int convert_context_handle_invalid_context(struct context *context)
-+{
-+	int rc = 0;
-+
-+	if (selinux_enforcing) {
-+		rc = -EINVAL;
-+	} else {
-+		char *s;
-+		u32 len;
-+
-+		context_struct_to_string(context, &s, &len);
-+		printk(KERN_ERR "security:  context %s is invalid\n", s);
-+		kfree(s);
-+	}
-+	return rc;
-+}
-+
-+struct convert_context_args {
-+	struct policydb *oldp;
-+	struct policydb *newp;
-+};
-+
-+/*
-+ * Convert the values in the security context
-+ * structure `c' from the values specified
-+ * in the policy `p->oldp' to the values specified
-+ * in the policy `p->newp'.  Verify that the
-+ * context is valid under the new policy.
-+ */
-+static int convert_context(u32 key,
-+			   struct context *c,
-+			   void *p)
-+{
-+	struct convert_context_args *args;
-+	struct context oldc;
-+	struct role_datum *role;
-+	struct type_datum *typdatum;
-+	struct user_datum *usrdatum;
-+	char *s;
-+	u32 len;
-+	int rc = -EINVAL;
-+
-+	args = p;
-+
-+	rc = context_cpy(&oldc, c);
-+	if (rc)
-+		goto out;
-+
-+	/* Convert the user. */
-+	usrdatum = hashtab_search(args->newp->p_users.table,
-+	                          args->oldp->p_user_val_to_name[c->user - 1]);
-+	if (!usrdatum) {
-+		goto bad;
-+	}
-+	c->user = usrdatum->value;
-+
-+	/* Convert the role. */
-+	role = hashtab_search(args->newp->p_roles.table,
-+	                      args->oldp->p_role_val_to_name[c->role - 1]);
-+	if (!role) {
-+		goto bad;
-+	}
-+	c->role = role->value;
-+
-+	/* Convert the type. */
-+	typdatum = hashtab_search(args->newp->p_types.table,
-+	                          args->oldp->p_type_val_to_name[c->type - 1]);
-+	if (!typdatum) {
-+		goto bad;
-+	}
-+	c->type = typdatum->value;
-+
-+	rc = mls_convert_context(args->oldp, args->newp, c);
-+	if (rc)
-+		goto bad;
-+
-+	/* Check the validity of the new context. */
-+	if (!policydb_context_isvalid(args->newp, c)) {
-+		rc = convert_context_handle_invalid_context(&oldc);
-+		if (rc)
-+			goto bad;
-+	}
-+
-+	context_destroy(&oldc);
-+out:
-+	return rc;
-+bad:
-+	context_struct_to_string(&oldc, &s, &len);
-+	context_destroy(&oldc);
-+	printk(KERN_ERR "security:  invalidating context %s\n", s);
-+	kfree(s);
-+	goto out;
-+}
-+
-+extern void selinux_complete_init(void);
-+
-+/**
-+ * security_load_policy - Load a security policy configuration.
-+ * @data: binary policy data
-+ * @len: length of data in bytes
-+ *
-+ * Load a new set of security policy configuration data,
-+ * validate it and convert the SID table as necessary.
-+ * This function will flush the access vector cache after
-+ * loading the new policy.
-+ */
-+int security_load_policy(void *data, size_t len)
-+{
-+	struct policydb oldpolicydb, newpolicydb;
-+	struct sidtab oldsidtab, newsidtab;
-+	struct convert_context_args args;
-+	u32 seqno;
-+	int rc = 0;
-+	struct policy_file file = { data, len }, *fp = &file;
-+
-+	LOAD_LOCK;
-+
-+	if (!ss_initialized) {
-+		if (policydb_read(&policydb, fp)) {
-+			LOAD_UNLOCK;
-+			return -EINVAL;
-+		}
-+		if (policydb_load_isids(&policydb, &sidtab)) {
-+			LOAD_UNLOCK;
-+			policydb_destroy(&policydb);
-+			return -EINVAL;
-+		}
-+		ss_initialized = 1;
-+		LOAD_UNLOCK;
-+		selinux_complete_init();
-+		return 0;
-+	}
-+
-+#if 0
-+	sidtab_hash_eval(&sidtab, "sids");
-+#endif
-+
-+	if (policydb_read(&newpolicydb, fp)) {
-+		LOAD_UNLOCK;
-+		return -EINVAL;
-+	}
-+
-+	sidtab_init(&newsidtab);
-+
-+	/* Verify that the existing classes did not change. */
-+	if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
-+		printk(KERN_ERR "security:  the definition of an existing "
-+		       "class changed\n");
-+		rc = -EINVAL;
-+		goto err;
-+	}
-+
-+	/* Clone the SID table. */
-+	sidtab_shutdown(&sidtab);
-+	if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
-+		rc = -ENOMEM;
-+		goto err;
-+	}
-+
-+	/* Convert the internal representations of contexts
-+	   in the new SID table and remove invalid SIDs. */
-+	args.oldp = &policydb;
-+	args.newp = &newpolicydb;
-+	sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
-+
-+	/* Save the old policydb and SID table to free later. */
-+	memcpy(&oldpolicydb, &policydb, sizeof policydb);
-+	sidtab_set(&oldsidtab, &sidtab);
-+
-+	/* Install the new policydb and SID table. */
-+	POLICY_WRLOCK;
-+	memcpy(&policydb, &newpolicydb, sizeof policydb);
-+	sidtab_set(&sidtab, &newsidtab);
-+	seqno = ++latest_granting;
-+	POLICY_WRUNLOCK;
-+	LOAD_UNLOCK;
-+
-+	/* Free the old policydb and SID table. */
-+	policydb_destroy(&oldpolicydb);
-+	sidtab_destroy(&oldsidtab);
-+
-+	avc_ss_reset(seqno);
-+
-+	return 0;
-+
-+err:
-+	LOAD_UNLOCK;
-+	sidtab_destroy(&newsidtab);
-+	policydb_destroy(&newpolicydb);
-+	return rc;
-+
-+}
-+
-+/**
-+ * security_port_sid - Obtain the SID for a port.
-+ * @domain: communication domain aka address family
-+ * @type: socket type
-+ * @protocol: protocol number
-+ * @port: port number
-+ * @out_sid: security identifier
-+ */
-+int security_port_sid(u16 domain,
-+		      u16 type,
-+		      u8 protocol,
-+		      u16 port,
-+		      u32 *out_sid)
-+{
-+	struct ocontext *c;
-+	int rc = 0;
-+
-+	POLICY_RDLOCK;
-+
-+	c = policydb.ocontexts[OCON_PORT];
-+	while (c) {
-+		if (c->u.port.protocol == protocol &&
-+		    c->u.port.low_port <= port &&
-+		    c->u.port.high_port >= port)
-+			break;
-+		c = c->next;
-+	}
-+
-+	if (c) {
-+		if (!c->sid[0]) {
-+			rc = sidtab_context_to_sid(&sidtab,
-+						   &c->context[0],
-+						   &c->sid[0]);
-+			if (rc)
-+				goto out;
-+		}
-+		*out_sid = c->sid[0];
-+	} else {
-+		*out_sid = SECINITSID_PORT;
-+	}
-+
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
-+
-+/**
-+ * security_netif_sid - Obtain the SID for a network interface.
-+ * @name: interface name
-+ * @if_sid: interface SID
-+ * @msg_sid: default SID for received packets
-+ */
-+int security_netif_sid(char *name,
-+		       u32 *if_sid,
-+		       u32 *msg_sid)
-+{
-+	int rc = 0;
-+	struct ocontext *c;
-+
-+	POLICY_RDLOCK;
-+
-+	c = policydb.ocontexts[OCON_NETIF];
-+	while (c) {
-+		if (strcmp(name, c->u.name) == 0)
-+			break;
-+		c = c->next;
-+	}
-+
-+	if (c) {
-+		if (!c->sid[0] || !c->sid[1]) {
-+			rc = sidtab_context_to_sid(&sidtab,
-+						  &c->context[0],
-+						  &c->sid[0]);
-+			if (rc)
-+				goto out;
-+			rc = sidtab_context_to_sid(&sidtab,
-+						   &c->context[1],
-+						   &c->sid[1]);
-+			if (rc)
-+				goto out;
-+		}
-+		*if_sid = c->sid[0];
-+		*msg_sid = c->sid[1];
-+	} else {
-+		*if_sid = SECINITSID_NETIF;
-+		*msg_sid = SECINITSID_NETMSG;
-+	}
-+
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
-+
-+
-+/**
-+ * security_node_sid - Obtain the SID for a node (host).
-+ * @domain: communication domain aka address family
-+ * @addrp: address
-+ * @addrlen: address length in bytes
-+ * @out_sid: security identifier
-+ */
-+int security_node_sid(u16 domain,
-+		      void *addrp,
-+		      u32 addrlen,
-+		      u32 *out_sid)
-+{
-+	int rc = 0;
-+	u32 addr;
-+	struct ocontext *c;
-+
-+	POLICY_RDLOCK;
-+
-+	if (domain != AF_INET || addrlen != sizeof(u32)) {
-+		*out_sid = SECINITSID_NODE;
-+		goto out;
-+	}
-+	addr = *((u32 *)addrp);
-+
-+	c = policydb.ocontexts[OCON_NODE];
-+	while (c) {
-+		if (c->u.node.addr == (addr & c->u.node.mask))
-+			break;
-+		c = c->next;
-+	}
-+
-+	if (c) {
-+		if (!c->sid[0]) {
-+			rc = sidtab_context_to_sid(&sidtab,
-+						   &c->context[0],
-+						   &c->sid[0]);
-+			if (rc)
-+				goto out;
-+		}
-+		*out_sid = c->sid[0];
-+	} else {
-+		*out_sid = SECINITSID_NODE;
-+	}
-+
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
-+
-+#define SIDS_NEL 25
-+
-+/**
-+ * security_get_user_sids - Obtain reachable SIDs for a user.
-+ * @fromsid: starting SID
-+ * @username: username
-+ * @sids: array of reachable SIDs for user
-+ * @nel: number of elements in @sids
-+ *
-+ * Generate the set of SIDs for legal security contexts
-+ * for a given user that can be reached by @fromsid.
-+ * Set *@sids to point to a dynamically allocated
-+ * array containing the set of SIDs.  Set *@nel to the
-+ * number of elements in the array.
-+ */
-+
-+int security_get_user_sids(u32 fromsid,
-+	                   char *username,
-+			   u32 **sids,
-+			   u32 *nel)
-+{
-+	struct context *fromcon, usercon;
-+	u32 *mysids, *mysids2, sid;
-+	u32 mynel = 0, maxnel = SIDS_NEL;
-+	struct user_datum *user;
-+	struct role_datum *role;
-+	struct av_decision avd;
-+	int rc = 0, i, j;
-+
-+	if (!ss_initialized) {
-+		*sids = NULL;
-+		*nel = 0;
-+		goto out;
-+	}
-+
-+	POLICY_RDLOCK;
-+
-+	fromcon = sidtab_search(&sidtab, fromsid);
-+	if (!fromcon) {
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+
-+	user = hashtab_search(policydb.p_users.table, username);
-+	if (!user) {
-+		rc = -EINVAL;
-+		goto out_unlock;
-+	}
-+	usercon.user = user->value;
-+
-+	mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
-+	if (!mysids) {
-+		rc = -ENOMEM;
-+		goto out_unlock;
-+	}
-+	memset(mysids, 0, maxnel*sizeof(*mysids));
-+
-+	for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) {
-+		if (!ebitmap_get_bit(&user->roles, i))
-+			continue;
-+		role = policydb.role_val_to_struct[i];
-+		usercon.role = i+1;
-+		for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) {
-+			if (!ebitmap_get_bit(&role->types, j))
-+				continue;
-+			usercon.type = j+1;
-+			if (usercon.type == fromcon->type)
-+				continue;
-+			mls_for_user_ranges(user,usercon) {
-+				rc = context_struct_compute_av(fromcon, &usercon,
-+							       SECCLASS_PROCESS,
-+							       PROCESS__TRANSITION,
-+							       &avd);
-+				if (rc ||  !(avd.allowed & PROCESS__TRANSITION))
-+					continue;
-+				rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
-+				if (rc) {
-+					kfree(mysids);
-+					goto out_unlock;
-+				}
-+				if (mynel < maxnel) {
-+					mysids[mynel++] = sid;
-+				} else {
-+					maxnel += SIDS_NEL;
-+					mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
-+					if (!mysids2) {
-+						rc = -ENOMEM;
-+						kfree(mysids);
-+						goto out_unlock;
-+					}
-+					memset(mysids2, 0, maxnel*sizeof(*mysids2));
-+					memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
-+					kfree(mysids);
-+					mysids = mysids2;
-+					mysids[mynel++] = sid;
-+				}
-+			}
-+			mls_end_user_ranges;
-+		}
-+	}
-+
-+	*sids = mysids;
-+	*nel = mynel;
-+
-+out_unlock:
-+	POLICY_RDUNLOCK;
-+out:
-+	return rc;
-+}
-+
-+/**
-+ * security_genfs_sid - Obtain a SID for a file in a filesystem
-+ * @fstype: filesystem type
-+ * @path: path from root of mount
-+ * @sclass: file security class
-+ * @sid: SID for path
-+ *
-+ * Obtain a SID to use for a file in a filesystem that
-+ * cannot support xattr or use a fixed labeling behavior like
-+ * transition SIDs or task SIDs.
-+ */
-+int security_genfs_sid(const char *fstype,
-+	               char *path,
-+		       u16 sclass,
-+		       u32 *sid)
-+{
-+	int len;
-+	struct genfs *genfs;
-+	struct ocontext *c;
-+	int rc = 0, cmp = 0;
-+
-+	POLICY_RDLOCK;
-+
-+	for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
-+		cmp = strcmp(fstype, genfs->fstype);
-+		if (cmp <= 0)
-+			break;
-+	}
-+
-+	if (!genfs || cmp) {
-+		*sid = SECINITSID_UNLABELED;
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+
-+	for (c = genfs->head; c; c = c->next) {
-+		len = strlen(c->u.name);
-+		if ((!c->v.sclass || sclass == c->v.sclass) &&
-+		    (strncmp(c->u.name, path, len) == 0))
-+			break;
-+	}
-+
-+	if (!c) {
-+		*sid = SECINITSID_UNLABELED;
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+
-+	if (!c->sid[0]) {
-+		rc = sidtab_context_to_sid(&sidtab,
-+					   &c->context[0],
-+					   &c->sid[0]);
-+		if (rc)
-+			goto out;
-+	}
-+
-+	*sid = c->sid[0];
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
-+
-+/**
-+ * security_fs_use - Determine how to handle labeling for a filesystem.
-+ * @fstype: filesystem type
-+ * @behavior: labeling behavior
-+ * @sid: SID for filesystem (superblock)
-+ */
-+int security_fs_use(
-+	const char *fstype,
-+	unsigned int *behavior,
-+	u32 *sid)
-+{
-+	int rc = 0;
-+	struct ocontext *c;
-+
-+	POLICY_RDLOCK;
-+
-+	c = policydb.ocontexts[OCON_FSUSE];
-+	while (c) {
-+		if (strcmp(fstype, c->u.name) == 0)
-+			break;
-+		c = c->next;
-+	}
-+
-+	if (c) {
-+		*behavior = c->v.behavior;
-+		if (!c->sid[0]) {
-+			rc = sidtab_context_to_sid(&sidtab,
-+						   &c->context[0],
-+						   &c->sid[0]);
-+			if (rc)
-+				goto out;
-+		}
-+		*sid = c->sid[0];
-+	} else {
-+		rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
-+		if (rc) {
-+			*behavior = SECURITY_FS_USE_NONE;
-+			rc = 0;
-+		} else {
-+			*behavior = SECURITY_FS_USE_GENFS;
-+		}
-+	}
-+
-+out:
-+	POLICY_RDUNLOCK;
-+	return rc;
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/services.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,21 @@
-+/*
-+ * Implementation of the security services.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_SERVICES_H_
-+#define _SS_SERVICES_H_
-+
-+#include "policydb.h"
-+#include "sidtab.h"
-+
-+/*
-+ * The security server uses two global data structures
-+ * when providing its services:  the SID table (sidtab)
-+ * and the policy database (policydb).
-+ */
-+extern struct sidtab sidtab;
-+extern struct policydb policydb;
-+
-+#endif	/* _SS_SERVICES_H_ */
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/sidtab.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,329 @@
-+/*
-+ * Implementation of the SID table type.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "sidtab.h"
-+
-+#define SIDTAB_HASH(sid) \
-+(sid & SIDTAB_HASH_MASK)
-+
-+#define INIT_SIDTAB_LOCK(s) spin_lock_init(&s->lock)
-+#define SIDTAB_LOCK(s) spin_lock_irq(&s->lock)
-+#define SIDTAB_UNLOCK(s) spin_unlock_irq(&s->lock)
-+
-+int sidtab_init(struct sidtab *s)
-+{
-+	int i;
-+
-+	s->htable = kmalloc(sizeof(*(s->htable)) * SIDTAB_SIZE, GFP_ATOMIC);
-+	if (!s->htable)
-+		return -ENOMEM;
-+	for (i = 0; i < SIDTAB_SIZE; i++)
-+		s->htable[i] = NULL;
-+	s->nel = 0;
-+	s->next_sid = 1;
-+	s->shutdown = 0;
-+	INIT_SIDTAB_LOCK(s);
-+	return 0;
-+}
-+
-+int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
-+{
-+	int hvalue, rc = 0;
-+	struct sidtab_node *prev, *cur, *newnode;
-+
-+	if (!s) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	hvalue = SIDTAB_HASH(sid);
-+	prev = NULL;
-+	cur = s->htable[hvalue];
-+	while (cur != NULL && sid > cur->sid) {
-+		prev = cur;
-+		cur = cur->next;
-+	}
-+
-+	if (cur && sid == cur->sid) {
-+		rc = -EEXIST;
-+		goto out;
-+	}
-+
-+	newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC);
-+	if (newnode == NULL) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	newnode->sid = sid;
-+	if (context_cpy(&newnode->context, context)) {
-+		kfree(newnode);
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+
-+	if (prev) {
-+		newnode->next = prev->next;
-+		wmb();
-+		prev->next = newnode;
-+	} else {
-+		newnode->next = s->htable[hvalue];
-+		wmb();
-+		s->htable[hvalue] = newnode;
-+	}
-+
-+	s->nel++;
-+	if (sid >= s->next_sid)
-+		s->next_sid = sid + 1;
-+out:
-+	return rc;
-+}
-+
-+int sidtab_remove(struct sidtab *s, u32 sid)
-+{
-+	int hvalue, rc = 0;
-+	struct sidtab_node *cur, *last;
-+
-+	if (!s) {
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+
-+	hvalue = SIDTAB_HASH(sid);
-+	last = NULL;
-+	cur = s->htable[hvalue];
-+	while (cur != NULL && sid > cur->sid) {
-+		last = cur;
-+		cur = cur->next;
-+	}
-+
-+	if (cur == NULL || sid != cur->sid) {
-+		rc = -ENOENT;
-+		goto out;
-+	}
-+
-+	if (last == NULL)
-+		s->htable[hvalue] = cur->next;
-+	else
-+		last->next = cur->next;
-+
-+	context_destroy(&cur->context);
-+
-+	kfree(cur);
-+	s->nel--;
-+out:
-+	return rc;
-+}
-+
-+struct context *sidtab_search(struct sidtab *s, u32 sid)
-+{
-+	int hvalue;
-+	struct sidtab_node *cur;
-+
-+	if (!s)
-+		return NULL;
-+
-+	hvalue = SIDTAB_HASH(sid);
-+	cur = s->htable[hvalue];
-+	while (cur != NULL && sid > cur->sid)
-+		cur = cur->next;
-+
-+	if (cur == NULL || sid != cur->sid) {
-+		/* Remap invalid SIDs to the unlabeled SID. */
-+		sid = SECINITSID_UNLABELED;
-+		hvalue = SIDTAB_HASH(sid);
-+		cur = s->htable[hvalue];
-+		while (cur != NULL && sid > cur->sid)
-+			cur = cur->next;
-+		if (!cur || sid != cur->sid)
-+			return NULL;
-+	}
-+
-+	return &cur->context;
-+}
-+
-+int sidtab_map(struct sidtab *s,
-+	       int (*apply) (u32 sid,
-+			     struct context *context,
-+			     void *args),
-+	       void *args)
-+{
-+	int i, rc = 0;
-+	struct sidtab_node *cur;
-+
-+	if (!s)
-+		goto out;
-+
-+	for (i = 0; i < SIDTAB_SIZE; i++) {
-+		cur = s->htable[i];
-+		while (cur != NULL) {
-+			rc = apply(cur->sid, &cur->context, args);
-+			if (rc)
-+				goto out;
-+			cur = cur->next;
-+		}
-+	}
-+out:
-+	return rc;
-+}
-+
-+void sidtab_map_remove_on_error(struct sidtab *s,
-+				int (*apply) (u32 sid,
-+					      struct context *context,
-+					      void *args),
-+				void *args)
-+{
-+	int i, ret;
-+	struct sidtab_node *last, *cur, *temp;
-+
-+	if (!s)
-+		return;
-+
-+	for (i = 0; i < SIDTAB_SIZE; i++) {
-+		last = NULL;
-+		cur = s->htable[i];
-+		while (cur != NULL) {
-+			ret = apply(cur->sid, &cur->context, args);
-+			if (ret) {
-+				if (last) {
-+					last->next = cur->next;
-+				} else {
-+					s->htable[i] = cur->next;
-+				}
-+
-+				temp = cur;
-+				cur = cur->next;
-+				context_destroy(&temp->context);
-+				kfree(temp);
-+				s->nel--;
-+			} else {
-+				last = cur;
-+				cur = cur->next;
-+			}
-+		}
-+	}
-+
-+	return;
-+}
-+
-+static inline u32 sidtab_search_context(struct sidtab *s,
-+						  struct context *context)
-+{
-+	int i;
-+	struct sidtab_node *cur;
-+
-+	for (i = 0; i < SIDTAB_SIZE; i++) {
-+		cur = s->htable[i];
-+		while (cur != NULL) {
-+			if (context_cmp(&cur->context, context))
-+				return cur->sid;
-+			cur = cur->next;
-+		}
-+	}
-+	return 0;
-+}
-+
-+int sidtab_context_to_sid(struct sidtab *s,
-+			  struct context *context,
-+			  u32 *out_sid)
-+{
-+	u32 sid;
-+	int ret = 0;
-+
-+	*out_sid = SECSID_NULL;
-+
-+	sid = sidtab_search_context(s, context);
-+	if (!sid) {
-+		SIDTAB_LOCK(s);
-+		/* Rescan now that we hold the lock. */
-+		sid = sidtab_search_context(s, context);
-+		if (sid)
-+			goto unlock_out;
-+		/* No SID exists for the context.  Allocate a new one. */
-+		if (s->next_sid == UINT_MAX || s->shutdown) {
-+			ret = -ENOMEM;
-+			goto unlock_out;
-+		}
-+		sid = s->next_sid++;
-+		ret = sidtab_insert(s, sid, context);
-+		if (ret)
-+			s->next_sid--;
-+unlock_out:
-+		SIDTAB_UNLOCK(s);
-+	}
-+
-+	if (ret)
-+		return ret;
-+
-+	*out_sid = sid;
-+	return 0;
-+}
-+
-+void sidtab_hash_eval(struct sidtab *h, char *tag)
-+{
-+	int i, chain_len, slots_used, max_chain_len;
-+	struct sidtab_node *cur;
-+
-+	slots_used = 0;
-+	max_chain_len = 0;
-+	for (i = 0; i < SIDTAB_SIZE; i++) {
-+		cur = h->htable[i];
-+		if (cur) {
-+			slots_used++;
-+			chain_len = 0;
-+			while (cur) {
-+				chain_len++;
-+				cur = cur->next;
-+			}
-+
-+			if (chain_len > max_chain_len)
-+				max_chain_len = chain_len;
-+		}
-+	}
-+
-+	printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
-+	       "chain length %d\n", tag, h->nel, slots_used, SIDTAB_SIZE,
-+	       max_chain_len);
-+}
-+
-+void sidtab_destroy(struct sidtab *s)
-+{
-+	int i;
-+	struct sidtab_node *cur, *temp;
-+
-+	if (!s)
-+		return;
-+
-+	for (i = 0; i < SIDTAB_SIZE; i++) {
-+		cur = s->htable[i];
-+		while (cur != NULL) {
-+			temp = cur;
-+			cur = cur->next;
-+			context_destroy(&temp->context);
-+			kfree(temp);
-+		}
-+		s->htable[i] = NULL;
-+	}
-+	kfree(s->htable);
-+	s->htable = NULL;
-+	s->nel = 0;
-+	s->next_sid = 1;
-+}
-+
-+void sidtab_set(struct sidtab *dst, struct sidtab *src)
-+{
-+	SIDTAB_LOCK(src);
-+	dst->htable = src->htable;
-+	dst->nel = src->nel;
-+	dst->next_sid = src->next_sid;
-+	dst->shutdown = 0;
-+	SIDTAB_UNLOCK(src);
-+}
-+
-+void sidtab_shutdown(struct sidtab *s)
-+{
-+	SIDTAB_LOCK(s);
-+	s->shutdown = 1;
-+	SIDTAB_UNLOCK(s);
-+}
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/sidtab.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,59 @@
-+/*
-+ * A security identifier table (sidtab) is a hash table
-+ * of security context structures indexed by SID value.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_SIDTAB_H_
-+#define _SS_SIDTAB_H_
-+
-+#include "context.h"
-+
-+struct sidtab_node {
-+	u32 sid;		/* security identifier */
-+	struct context context;	/* security context structure */
-+	struct sidtab_node *next;
-+};
-+
-+#define SIDTAB_HASH_BITS 7
-+#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS)
-+#define SIDTAB_HASH_MASK (SIDTAB_HASH_BUCKETS-1)
-+
-+#define SIDTAB_SIZE SIDTAB_HASH_BUCKETS
-+
-+struct sidtab {
-+	struct sidtab_node **htable;
-+	unsigned int nel;	/* number of elements */
-+	unsigned int next_sid;	/* next SID to allocate */
-+	unsigned char shutdown;
-+	spinlock_t lock;
-+};
-+
-+int sidtab_init(struct sidtab *s);
-+int sidtab_insert(struct sidtab *s, u32 sid, struct context *context);
-+struct context *sidtab_search(struct sidtab *s, u32 sid);
-+
-+int sidtab_map(struct sidtab *s,
-+	       int (*apply) (u32 sid,
-+			     struct context *context,
-+			     void *args),
-+	       void *args);
-+
-+void sidtab_map_remove_on_error(struct sidtab *s,
-+				int (*apply) (u32 sid,
-+					      struct context *context,
-+					      void *args),
-+				void *args);
-+
-+int sidtab_context_to_sid(struct sidtab *s,
-+			  struct context *context,
-+			  u32 *sid);
-+
-+void sidtab_hash_eval(struct sidtab *h, char *tag);
-+void sidtab_destroy(struct sidtab *s);
-+void sidtab_set(struct sidtab *dst, struct sidtab *src);
-+void sidtab_shutdown(struct sidtab *s);
-+
-+#endif	/* _SS_SIDTAB_H_ */
-+
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/symtab.c	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,40 @@
-+/*
-+ * Implementation of the symbol table type.
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#include "symtab.h"
-+
-+static unsigned int symhash(struct hashtab *h, void *key)
-+{
-+	char *p, *keyp;
-+	unsigned int size;
-+	unsigned int val;
-+
-+	val = 0;
-+	keyp = key;
-+	size = strlen(keyp);
-+	for (p = keyp; (p - keyp) < size; p++)
-+		val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p);
-+	return val & (h->size - 1);
-+}
-+
-+static int symcmp(struct hashtab *h, void *key1, void *key2)
-+{
-+	char *keyp1, *keyp2;
-+
-+	keyp1 = key1;
-+	keyp2 = key2;
-+	return strcmp(keyp1, keyp2);
-+}
-+
-+
-+int symtab_init(struct symtab *s, unsigned int size)
-+{
-+	s->table = hashtab_create(symhash, symcmp, size);
-+	if (!s->table)
-+		return -1;
-+	s->nprim = 0;
-+	return 0;
-+}
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/security/selinux/ss/symtab.h	2003-07-19 17:04:47.000000000 -0700
-@@ -0,0 +1,23 @@
-+/*
-+ * A symbol table (symtab) maintains associations between symbol
-+ * strings and datum values.  The type of the datum values
-+ * is arbitrary.  The symbol table type is implemented
-+ * using the hash table type (hashtab).
-+ *
-+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
-+ */
-+#ifndef _SS_SYMTAB_H_
-+#define _SS_SYMTAB_H_
-+
-+#include "hashtab.h"
-+
-+struct symtab {
-+	struct hashtab *table;	/* hash table (keyed on a string) */
-+	u32 nprim;		/* number of primary names in table */
-+};
-+
-+int symtab_init(struct symtab *s, unsigned int size);
-+
-+#endif	/* _SS_SYMTAB_H_ */
-+
-+
---- linux-2.6.0-test1/sound/core/timer.c	2003-06-14 12:18:24.000000000 -0700
-+++ 25/sound/core/timer.c	2003-07-19 17:06:14.000000000 -0700
-@@ -1688,10 +1688,11 @@ static ssize_t snd_timer_user_read(struc
- 				break;
- 			}
- 		}
--		spin_unlock_irq(&tu->qlock);
- 		if (err < 0)
- 			break;
- 
-+		spin_unlock_irq(&tu->qlock);
-+
- 		if (tu->tread) {
- 			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
- 				err = -EFAULT;
-@@ -1712,6 +1713,7 @@ static ssize_t snd_timer_user_read(struc
- 		spin_lock_irq(&tu->qlock);
- 		tu->qused--;
- 	}
-+	spin_unlock_irq(&tu->qlock);
- 	return result > 0 ? result : err;
- }
- 
---- linux-2.6.0-test1/sound/isa/cmi8330.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/sound/isa/cmi8330.c	2003-07-19 17:03:51.000000000 -0700
-@@ -293,7 +293,7 @@ static int __devinit snd_cmi8330_pnp(int
- 				     const struct pnp_card_device_id *id)
- {
- 	struct pnp_dev *pdev;
--	struct pnp_resource_table * cfg = kmalloc(GFP_ATOMIC, sizeof(struct pnp_resource_table));
-+	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_ATOMIC);
- 	int err;
- 
- 	acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
---- linux-2.6.0-test1/sound/isa/es18xx.c	2003-06-14 12:18:08.000000000 -0700
-+++ 25/sound/isa/es18xx.c	2003-07-19 17:03:51.000000000 -0700
-@@ -1966,7 +1966,7 @@ static int __devinit snd_audiodrive_pnp(
- 					const struct pnp_card_device_id *id)
- {
- 	struct pnp_dev *pdev;
--	struct pnp_resource_table * cfg = kmalloc(GFP_ATOMIC, sizeof(struct pnp_resource_table));
-+	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_ATOMIC);
- 	int err;
- 
- 	if (!cfg)
---- linux-2.6.0-test1/sound/oss/ac97_plugin_ad1980.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/ac97_plugin_ad1980.c	2003-07-19 17:03:51.000000000 -0700
-@@ -17,7 +17,7 @@
-    the provisions above, a recipient may use your version of this
-    file under either the OSL or the GPL.
-    
--   Authors: 	Arjan van de Ven <arjanv@redhat.com>
-+   Authors: 	Alan Cox <alan@redhat.com>
- 
-    This is an example codec plugin. This one switches the connections
-    around to match the setups some vendors use with audio switched to
---- linux-2.6.0-test1/sound/oss/ad1816.c	2003-06-14 12:18:33.000000000 -0700
-+++ 25/sound/oss/ad1816.c	2003-07-19 17:03:51.000000000 -0700
-@@ -1,15 +1,15 @@
- /*
-  *
-- * AD1816 lowlevel sound driver for Linux 2.2.0 and above
-+ * AD1816 lowlevel sound driver for Linux 2.6.0 and above
-  *
-- * Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
-+ * Copyright (C) 1998-2003 by Thorsten Knabe <linux@thorsten-knabe.de>
-  *
-  * Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
-  *
-  *
-- * version: 1.3.1
-- * status: experimental
-- * date: 1999/4/18
-+ * version: 1.5
-+ * status: beta
-+ * date: 2003/07/15
-  *
-  * Changes:
-  *	Oleg Drokin: Some cleanup of load/unload functions.	1998/11/24
-@@ -30,8 +30,17 @@
-  *	Christoph Hellwig: Added isapnp support			2000/03/15
-  *
-  *	Arnaldo Carvalho de Melo: get rid of check_region	2001/10/07
-+ *      
-+ *      Thorsten Knabe: Compiling with CONFIG_PNP enabled
-+ *	works again. It is now possible to use more than one 
-+ *	AD1816 sound card. Sample rate now may be changed during
-+ *	playback/capture. printk() uses log levels everywhere.
-+ *	SMP fixes. DMA handling fixes.
-+ *	Other minor code cleanup.				2003/07/15
-+ *
-  */
- 
-+
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/init.h>
-@@ -42,9 +51,6 @@
- #include "sound_config.h"
- 
- #define DEBUGNOISE(x)
--#define DEBUGINFO(x)
--#define DEBUGLOG(x)
--#define DEBUGWARN(x)
- 
- #define CHECK_FOR_POWER { int timeout=100; \
-   while (timeout > 0 && (inb(devc->base)&0x80)!= 0x80) {\
-@@ -63,21 +69,21 @@ typedef struct
- 	int            dma_playback;
-         int            dma_capture;
-   
--        int            speed;         /* open */
-+	int            opened;         /* open */
-+        int            speed;	
- 	int            channels;
- 	int            audio_format;
--	unsigned char  format_bits;
-         int            audio_mode; 
--	int            opened;
-   
-         int            recmask;        /* setup */
-+	unsigned char  format_bits;
- 	int            supported_devices;
- 	int            supported_rec_devices;
- 	unsigned short levels[SOUND_MIXER_NRDEVICES];
-+					/* misc */
-+	struct pnp_dev *pnpdev;	 /* configured via pnp */
-         int            dev_no;   /* this is the # in audio_devs and NOT 
- 				    in ad1816_info */
--	int            irq_ok;
--	int            *osp;
- 	spinlock_t	lock;  
- } ad1816_info;
- 
-@@ -85,12 +91,6 @@ static int nr_ad1816_devs;
- static int ad1816_clockfreq = 33000;
- static int options;
- 
--/* for backward mapping of irq to sound device */
--
--static volatile char irq2dev[17] = {-1, -1, -1, -1, -1, -1, -1, -1,
--				    -1, -1, -1, -1, -1, -1, -1, -1, -1};
--
--
- /* supported audio formats */
- static int  ad_format_mask =
- AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW;
-@@ -105,33 +105,22 @@ static ad1816_info dev_info[MAX_AUDIO_DE
- 
- static int ad_read (ad1816_info * devc, int reg)
- {
--	unsigned long   flags;
- 	int result;
- 	
- 	CHECK_FOR_POWER;
--
--	spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
- 	outb ((unsigned char) (reg & 0x3f), devc->base+0);
- 	result = inb(devc->base+2);
- 	result+= inb(devc->base+3)<<8;
--	spin_unlock_irqrestore(&devc->lock,flags);
--	
- 	return (result);
- }
- 
- 
- static void ad_write (ad1816_info * devc, int reg, int data)
- {
--	unsigned long flags;
--	
- 	CHECK_FOR_POWER;
--	
--	spin_lock_irqsave(&devc->lock,flags); /* make register access atomic */
- 	outb ((unsigned char) (reg & 0xff), devc->base+0);
- 	outb ((unsigned char) (data & 0xff),devc->base+2);
- 	outb ((unsigned char) ((data>>8)&0xff),devc->base+3);
--	spin_unlock_irqrestore(&devc->lock,flags);
--
- }
- 
- /* ------------------------------------------------------------------- */
-@@ -144,7 +133,7 @@ static void ad1816_halt_input (int dev)
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	unsigned char buffer;
- 	
--	DEBUGINFO (printk("ad1816: halt_input called\n"));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: halt_input called\n"));
- 	
- 	spin_lock_irqsave(&devc->lock,flags); 
- 	
-@@ -176,7 +165,7 @@ static void ad1816_halt_output (int dev)
- 	
- 	unsigned char buffer;
- 
--	DEBUGINFO (printk("ad1816: halt_output called!\n"));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: halt_output called!\n"));
- 
- 	spin_lock_irqsave(&devc->lock,flags); 
- 	/* Mute pcm output */
-@@ -210,7 +199,7 @@ static void ad1816_output_block (int dev
- 	unsigned long cnt;
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	
--	DEBUGINFO(printk("ad1816: output_block called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: output_block called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
-   
- 	cnt = count/4 - 1;
-   
-@@ -231,7 +220,7 @@ static void ad1816_start_input (int dev,
- 	unsigned long  cnt;
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	
--	DEBUGINFO(printk("ad1816: start_input called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: start_input called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
- 
- 	cnt = count/4 - 1;
- 
-@@ -239,7 +228,6 @@ static void ad1816_start_input (int dev,
- 
- 	/* set transfer count */
- 	ad_write (devc, 10, cnt & 0xffff); 
--
- 	devc->audio_mode |= PCM_ENABLE_INPUT;
- 	spin_unlock_irqrestore(&devc->lock,flags);
- }
-@@ -251,33 +239,19 @@ static int ad1816_prepare_for_input (int
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	unsigned char fmt_bits;
- 	
--	DEBUGINFO (printk ("ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
- 
- 	spin_lock_irqsave(&devc->lock,flags);
--	
- 	fmt_bits= (devc->format_bits&0x7)<<3;
- 	
- 	/* set mono/stereo mode */
- 	if (devc->channels > 1) {
- 		fmt_bits |=0x4;
- 	}
--
- 	/* set Mono/Stereo in playback/capture register */
- 	outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8); 
- 	outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
--  
--	/* If compiled into kernel, AD1816_CLOCK is defined, so use it */
--#ifdef AD1816_CLOCK 
--	ad1816_clockfreq=AD1816_CLOCK;
--#endif
--
--	/* capture/playback frequency correction for soundcards 
--	   with clock chips != 33MHz (allowed range 5 - 100 kHz) */
- 
--	if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
--		ad1816_clockfreq=33000;
--	}
--	
- 	freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq; 
- 
- 	/* write playback/capture speeds */
-@@ -297,7 +271,7 @@ static int ad1816_prepare_for_output (in
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	unsigned char fmt_bits;
- 
--	DEBUGINFO (printk ("ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
- 
- 	spin_lock_irqsave(&devc->lock,flags);
- 
-@@ -311,17 +285,6 @@ static int ad1816_prepare_for_output (in
- 	outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8); 
- 	outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
-   
--#ifdef AD1816_CLOCK 
--	ad1816_clockfreq=AD1816_CLOCK;
--#endif
--
--	/* capture/playback frequency correction for soundcards 
--	   with clock chips != 33MHz (allowed range 5 - 100 kHz)*/
--
--	if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
--		ad1816_clockfreq=33000;
--	}
--  
- 	freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq; 
- 	
- 	/* write playback/capture speeds */
-@@ -340,7 +303,7 @@ static void ad1816_trigger (int dev, int
- 	unsigned long flags;
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 
--	DEBUGINFO (printk("ad1816: trigger called! (devc=%d,devc->base=%d\n", devc, devc->base));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: trigger called! (devc=%d,devc->base=%d\n", devc, devc->base));
- 
- 	/* mode may have changed */
- 
-@@ -388,10 +351,17 @@ static void ad1816_reset (int dev)
- /* set playback speed */
- static int ad1816_set_speed (int dev, int arg)
- {
-+	unsigned long flags;
-+	unsigned int freq;
-+	int ret;
-+
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	
-+	spin_lock_irqsave(&devc->lock, flags);
- 	if (arg == 0) {
--		return devc->speed;
-+		ret = devc->speed;
-+		spin_unlock_irqrestore(&devc->lock, flags);
-+		return ret;
- 	}
- 	/* range checking */
- 	if (arg < 4000) {
-@@ -400,14 +370,23 @@ static int ad1816_set_speed (int dev, in
- 	if (arg > 55000) {
- 		arg = 55000;
- 	}
--
- 	devc->speed = arg;
--	return devc->speed;
-+
-+	/* change speed during playback */
-+	freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq; 
-+	/* write playback/capture speeds */
-+	ad_write (devc, 2, freq & 0xffff);	
-+	ad_write (devc, 3, freq & 0xffff);	
-+
-+	ret = devc->speed;
-+	spin_unlock_irqrestore(&devc->lock, flags);
-+	return ret;
- 
- }
- 
- static unsigned int ad1816_set_bits (int dev, unsigned int arg)
- {
-+	unsigned long flags;
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 	
- 	static struct format_tbl {
-@@ -428,10 +407,13 @@ static unsigned int ad1816_set_bits (int
- 
- 	int  i, n = sizeof (format2bits) / sizeof (struct format_tbl);
- 
-+	spin_lock_irqsave(&devc->lock, flags);
- 	/* return current format */
--	if (arg == 0)
--		return devc->audio_format;
--	
-+	if (arg == 0) {
-+	  	arg = devc->audio_format;
-+		spin_unlock_irqrestore(&devc->lock, flags);
-+		return arg;
-+	}
- 	devc->audio_format = arg;
- 
- 	/* search matching format bits */
-@@ -439,12 +421,15 @@ static unsigned int ad1816_set_bits (int
- 		if (format2bits[i].format == arg) {
- 			devc->format_bits = format2bits[i].bits;
- 			devc->audio_format = arg;
-+			spin_unlock_irqrestore(&devc->lock, flags);
- 			return arg;
- 		}
- 
- 	/* Still hanging here. Something must be terribly wrong */
- 	devc->format_bits = 0;
--	return devc->audio_format = AFMT_U8;
-+	devc->audio_format = AFMT_U8;
-+	spin_unlock_irqrestore(&devc->lock, flags);
-+	return(AFMT_U8); 
- }
- 
- static short ad1816_set_channels (int dev, short arg)
-@@ -486,9 +471,8 @@ static int ad1816_open (int dev, int mod
- 	devc->speed = 8000;
- 	devc->audio_format=AFMT_U8;
- 	devc->channels=1;
--
--	ad1816_reset(devc->dev_no); /* halt all pending output */
- 	spin_unlock_irqrestore(&devc->lock,flags);
-+	ad1816_reset(devc->dev_no); /* halt all pending output */
- 	return 0;
- }
- 
-@@ -497,17 +481,15 @@ static void ad1816_close (int dev) /* cl
- 	unsigned long flags;
- 	ad1816_info    *devc = (ad1816_info *) audio_devs[dev]->devc;
- 
--	spin_lock_irqsave(&devc->lock,flags);
--
- 	/* halt all pending output */
- 	ad1816_reset(devc->dev_no); 
--	
-+
-+	spin_lock_irqsave(&devc->lock,flags);
- 	devc->opened = 0;
- 	devc->audio_mode = 0;
- 	devc->speed = 8000;
- 	devc->audio_format=AFMT_U8;
- 	devc->format_bits = 0;
--
- 	spin_unlock_irqrestore(&devc->lock,flags);
- }
- 
-@@ -543,25 +525,13 @@ static struct audio_driver ad1816_audio_
- static irqreturn_t ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
- {
- 	unsigned char	status;
--	ad1816_info	*devc;
--	int		dev;
--
-+	ad1816_info	*devc = (ad1816_info *)dev_id;
- 	
- 	if (irq < 0 || irq > 15) {
- 	        printk(KERN_WARNING "ad1816: Got bogus interrupt %d\n", irq);
- 		return IRQ_NONE;
- 	}
- 
--	dev = irq2dev[irq];
--	
--	if (dev < 0 || dev >= num_audiodevs) {
--	        printk(KERN_WARNING "ad1816: IRQ2AD1816-mapping failed for "
--				    "irq %d device %d\n", irq,dev);
--		return IRQ_NONE;
--	}
--
--	devc = (ad1816_info *) audio_devs[dev]->devc;
--	
- 	spin_lock(&devc->lock);
- 
- 	/* read interrupt register */
-@@ -569,18 +539,19 @@ static irqreturn_t ad1816_interrupt (int
- 	/* Clear all interrupt  */
- 	outb (~status, devc->base+1);	
- 
--	DEBUGNOISE (printk("ad1816: Got interrupt subclass %d\n",status));
--	
--	devc->irq_ok=1;
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: Got interrupt subclass %d\n",status));
- 
--	if (status == 0)
--		DEBUGWARN(printk ("ad1816: interrupt: Got interrupt, but no reason?\n"));
-+	if (status == 0) {
-+		DEBUGNOISE(printk(KERN_DEBUG "ad1816: interrupt: Got interrupt, but no source.\n"));
-+		spin_unlock(&devc->lock);
-+		return IRQ_NONE;
-+	}
- 
- 	if (devc->opened && (devc->audio_mode & PCM_ENABLE_INPUT) && (status&64))
--		DMAbuf_inputintr (dev);
-+		DMAbuf_inputintr (devc->dev_no);
- 
- 	if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128))
--		DMAbuf_outputintr (dev, 1);
-+		DMAbuf_outputintr (devc->dev_no, 1);
- 
- 	spin_unlock(&devc->lock);
- 	return IRQ_HANDLED;
-@@ -671,9 +642,11 @@ static unsigned short default_mixer_leve
- static int
- ad1816_set_recmask (ad1816_info * devc, int mask)
- {
-+  	unsigned long 	flags;
- 	unsigned char   recdev;
- 	int             i, n;
- 	
-+	spin_lock_irqsave(&devc->lock, flags);
- 	mask &= devc->supported_rec_devices;
- 	
- 	n = 0;
-@@ -733,6 +706,7 @@ ad1816_set_recmask (ad1816_info * devc, 
- 		  (ad_read (devc, 20) & 0x8f8f) | recdev | (recdev<<8));
- 
- 	devc->recmask = mask;
-+	spin_unlock_irqrestore(&devc->lock, flags);
- 	return mask;
- }
- 
-@@ -760,7 +734,7 @@ change_bits (int *regval, int dev, int c
- static int
- ad1816_mixer_get (ad1816_info * devc, int dev)
- {
--	DEBUGINFO(printk("ad1816: mixer_get called!\n"));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_get called!\n"));
- 	
- 	/* range check + supported mixer check */
- 	if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES )
-@@ -781,8 +755,9 @@ ad1816_mixer_set (ad1816_info * devc, in
- 	int   regoffs;
- 	int   val;
- 	int   valmute;
-+	unsigned long flags;
- 
--	DEBUGINFO(printk("ad1816: mixer_set called!\n"));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_set called!\n"));
- 	
- 	if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES )
- 		return -(EINVAL);
-@@ -813,6 +788,7 @@ ad1816_mixer_set (ad1816_info * devc, in
- 	/* sanity check */
- 	if (mix_devices[dev][LEFT_CHN].nbits == 0)
- 		return -(EINVAL);
-+	spin_lock_irqsave(&devc->lock, flags);
- 
- 	/* keep precise volume internal */
- 	devc->levels[dev] = retvol;
-@@ -840,8 +816,10 @@ ad1816_mixer_set (ad1816_info * devc, in
- 	 */
-  
- 	/* Was just a mono channel */
--	if (mix_devices[dev][RIGHT_CHN].nbits == 0)
-+	if (mix_devices[dev][RIGHT_CHN].nbits == 0) {
-+		spin_unlock_irqrestore(&devc->lock, flags);
- 		return retvol;		
-+	}
- 
- 	regoffs = mix_devices[dev][RIGHT_CHN].regno;
- 	val = ad_read (devc, regoffs);
-@@ -857,7 +835,7 @@ ad1816_mixer_set (ad1816_info * devc, in
- 			valmute &= ~0x80;
- 	}
- 	ad_write (devc, regoffs, valmute); /* mute */
--	
-+	spin_unlock_irqrestore(&devc->lock, flags);
-        	return retvol;
- }
- 
-@@ -901,7 +879,7 @@ ad1816_mixer_ioctl (int dev, unsigned in
- 	ad1816_info    *devc = mixer_devs[dev]->devc;
- 	int val;
-   
--	DEBUGINFO(printk("ad1816: mixer_ioctl called!\n"));
-+	DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_ioctl called!\n"));
-   
- 	/* Mixer ioctl */
- 	if (((cmd >> 8) & 0xff) == 'M') { 
-@@ -980,83 +958,91 @@ static struct mixer_operations ad1816_mi
- 
- /* ------------------------------------------------------------------- */
- 
--/* stuff for card recognition, init and unloading */
-+/* stuff for card recognition, init and unloading PNP ...*/
- 
- 
--/* replace with probe routine */
--static int __init probe_ad1816 ( struct address_info *hw_config )
-+/* check if AD1816 present at specified hw_config and register device with OS 
-+ * return 1 if initialization was successful, 0 otherwise
-+ */
-+static int __init ad1816_init_card (struct address_info *hw_config, 
-+	struct pnp_dev *pnp)
- {
--	ad1816_info    *devc = &dev_info[nr_ad1816_devs];
--	int io_base=hw_config->io_base;
--	int *osp=hw_config->osp;
-+	ad1816_info    *devc = NULL;
- 	int tmp;
-+	int oss_devno = -1;
- 
--	printk(KERN_INFO "ad1816: AD1816 sounddriver "
--			 "Copyright (C) 1998 by Thorsten Knabe\n");
--	printk(KERN_INFO "ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, "
--			 "clockfreq=%d, options=%d isadmabug=%d\n",
-+	printk(KERN_INFO "ad1816: initializing card: io=0x%x, irq=%d, dma=%d, "
-+			 "dma2=%d, clockfreq=%d, options=%d isadmabug=%d "
-+			 "%s\n",
- 	       hw_config->io_base,
- 	       hw_config->irq,
- 	       hw_config->dma,
- 	       hw_config->dma2,
- 	       ad1816_clockfreq,
- 	       options,
--	       isa_dma_bridge_buggy);
-+	       isa_dma_bridge_buggy,
-+	       pnp?"(PNP)":"");
- 
--	if (!request_region(io_base, 16, "AD1816 Sound")) {
--		printk(KERN_WARNING "ad1816: I/O port 0x%03x not free\n",
--				    io_base);
--		goto err;
--	}
--
--	DEBUGLOG(printk ("ad1816: detect(%x)\n", io_base));
--	
-+	/* ad1816_info structure remaining ? */
- 	if (nr_ad1816_devs >= MAX_AUDIO_DEV) {
--		printk(KERN_WARNING "ad1816: detect error - step 0\n");
--		goto out_release_region;
-+		printk(KERN_WARNING "ad1816: no more ad1816_info structures "
-+			"left\n");
-+		goto out;
- 	}
- 
--	devc->base = io_base;
--	devc->irq_ok = 0;
--	devc->irq = 0;
-+	devc = &dev_info[nr_ad1816_devs];
-+	devc->base = hw_config->io_base;
-+	devc->irq = hw_config->irq;
-+	devc->dma_playback=hw_config->dma;
-+	devc->dma_capture=hw_config->dma2;
- 	devc->opened = 0;
--	devc->osp = osp;
-+	devc->pnpdev = pnp;
- 	spin_lock_init(&devc->lock);
- 
-+	if (!request_region(devc->base, 16, "AD1816 Sound")) {
-+		printk(KERN_WARNING "ad1816: I/O port 0x%03x not free\n",
-+				    devc->base);
-+		goto out;
-+	}
-+
-+	printk(KERN_INFO "ad1816: Examining AD1816 at address 0x%03x.\n", 
-+		devc->base);
-+	
-+
-+	/* tests for ad1816 */
- 	/* base+0: bit 1 must be set but not 255 */
- 	tmp=inb(devc->base);
- 	if ( (tmp&0x80)==0 || tmp==255 ) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 or chip is not active (Test 0)\n"));
-+		printk (KERN_INFO "ad1816: Chip is not an AD1816 or chip "
-+			"is not active (Test 0)\n");
- 		goto out_release_region;
- 	}
- 
--
- 	/* writes to ireg 8 are copied to ireg 9 */
- 	ad_write(devc,8,12345); 
- 	if (ad_read(devc,9)!=12345) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 1)\n"));
-+		printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 1)\n");
- 		goto out_release_region;
- 	}
-   
- 	/* writes to ireg 8 are copied to ireg 9 */
- 	ad_write(devc,8,54321); 
- 	if (ad_read(devc,9)!=54321) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 2)\n"));
-+		printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 2)\n");
- 		goto out_release_region;
- 	}
- 
--
- 	/* writes to ireg 10 are copied to ireg 11 */
- 	ad_write(devc,10,54321); 
- 	if (ad_read(devc,11)!=54321) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 3)\n"));
-+		printk (KERN_INFO "ad1816: Chip is not an AD1816 (Test 3)\n");
- 		goto out_release_region;
- 	}
- 
- 	/* writes to ireg 10 are copied to ireg 11 */
- 	ad_write(devc,10,12345); 
- 	if (ad_read(devc,11)!=12345) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 4)\n"));
-+		printk (KERN_INFO "ad1816: Chip is not an AD1816 (Test 4)\n");
- 		goto out_release_region;
- 	}
- 
-@@ -1064,35 +1050,12 @@ static int __init probe_ad1816 ( struct 
- 	tmp=inb(devc->base+1);
- 	outb(0xff,devc->base+1); 
- 	if (inb(devc->base+1)!=tmp) {
--		DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 5)\n"));
-+		printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 5)\n");
- 		goto out_release_region;
- 	}
--
-   
--	DEBUGLOG (printk ("ad1816: detect() - Detected OK\n"));
--	DEBUGLOG (printk ("ad1816: AD1816 Version: %d\n",ad_read(devc,45)));
--
--	/* detection was successful */
--	return 1; 
--out_release_region:
--	release_region(io_base, 16);
--	/* detection was NOT successful */
--err:	return 0;
--}
--
--
--/* allocate resources from the kernel. If any allocation fails, free
--   all allocated resources and exit attach.
--  
-- */
--
--static void __init attach_ad1816 (struct address_info *hw_config)
--{
--	int             my_dev;
--	char            dev_name[100];
--	ad1816_info    *devc = &dev_info[nr_ad1816_devs];
--
--	devc->base = hw_config->io_base;	
-+	printk(KERN_INFO "ad1816: AD1816 (version %d) successfully detected!\n",
-+		ad_read(devc,45));
- 
- 	/* disable all interrupts */
- 	ad_write(devc,1,0);     
-@@ -1101,62 +1064,54 @@ static void __init attach_ad1816 (struct
- 	outb (0, devc->base+1);	
- 
- 	/* allocate irq */
--	if (hw_config->irq < 0 || hw_config->irq > 15)
-+	if (devc->irq < 0 || devc->irq > 15)
- 		goto out_release_region;
--	if (request_irq(hw_config->irq, ad1816_interrupt,0,
--			"SoundPort", hw_config->osp) < 0)	{
-+	if (request_irq(devc->irq, ad1816_interrupt,0,
-+			"SoundPort", devc) < 0)	{
- 	        printk(KERN_WARNING "ad1816: IRQ in use\n");
- 		goto out_release_region;
- 	}
--	devc->irq=hw_config->irq;
- 
- 	/* DMA stuff */
--	if (sound_alloc_dma (hw_config->dma, "Sound System")) {
-+	if (sound_alloc_dma (devc->dma_playback, "Sound System")) {
- 		printk(KERN_WARNING "ad1816: Can't allocate DMA%d\n",
--				    hw_config->dma);
-+				    devc->dma_playback);
- 		goto out_free_irq;
- 	}
--	devc->dma_playback=hw_config->dma;
- 	
--	if ( hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma) {
--		if (sound_alloc_dma(hw_config->dma2,
-+	if ( devc->dma_capture >= 0 && 
-+	  	devc->dma_capture != devc->dma_playback) {
-+		if (sound_alloc_dma(devc->dma_capture,
- 				    "Sound System (capture)")) {
- 			printk(KERN_WARNING "ad1816: Can't allocate DMA%d\n",
--					    hw_config->dma2);
-+					    devc->dma_capture);
- 			goto out_free_dma;
- 		}
--		devc->dma_capture=hw_config->dma2;
- 		devc->audio_mode=DMA_AUTOMODE|DMA_DUPLEX;
- 	} else {
--	        devc->dma_capture=-1;
-+	  	printk(KERN_WARNING "ad1816: Only one DMA channel "
-+			"available/configured. No duplex operation possible\n");
- 		devc->audio_mode=DMA_AUTOMODE;
- 	}
- 
--	sprintf (dev_name,"AD1816 audio driver");
--  
--	conf_printf2 (dev_name,
--		      devc->base, devc->irq, hw_config->dma, hw_config->dma2);
-+	conf_printf2 ("AD1816 audio driver",
-+		      devc->base, devc->irq, devc->dma_playback, 
-+		      devc->dma_capture);
- 
- 	/* register device */
--	if ((my_dev = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
--					      dev_name,
-+	if ((oss_devno = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
-+					      "AD1816 audio driver",
- 					      &ad1816_audio_driver,
- 					      sizeof (struct audio_driver),
- 					      devc->audio_mode,
- 					      ad_format_mask,
- 					      devc,
--					      hw_config->dma, 
--					      hw_config->dma2)) < 0) {
-+					      devc->dma_playback, 
-+					      devc->dma_capture)) < 0) {
- 		printk(KERN_WARNING "ad1816: Can't install sound driver\n");
- 		goto out_free_dma_2;
- 	}
- 
--	/* fill rest of structure with reasonable default values */
--	irq2dev[hw_config->irq] = devc->dev_no = my_dev;
--	devc->opened = 0;
--	devc->irq_ok = 0;
--	devc->osp = hw_config->osp;  
--	nr_ad1816_devs++;
- 
- 	ad_write(devc,32,0x80f0); /* sound system mode */
- 	if (options&1) {
-@@ -1186,25 +1141,30 @@ static void __init attach_ad1816 (struct
- 	ad1816_mixer_reset (devc); 
-   
- 	/* register mixer */
--	if ((audio_devs[my_dev]->mixer_dev=sound_install_mixer(
-+	if ((audio_devs[oss_devno]->mixer_dev=sound_install_mixer(
- 				       MIXER_DRIVER_VERSION,
--				       dev_name,
-+				       "AD1816 audio driver",
- 				       &ad1816_mixer_operations,
- 				       sizeof (struct mixer_operations),
--				       devc)) >= 0) {
--		audio_devs[my_dev]->min_fragment = 0;
-+				       devc)) < 0) {
-+	  	printk(KERN_WARNING "Can't install mixer\n");
- 	}
--out:	return;
-+	/* make ad1816_info active */
-+	nr_ad1816_devs++;
-+	printk(KERN_INFO "ad1816: card successfully installed!\n");
-+	return 1;
-+	/* error handling */
- out_free_dma_2:
--	if (devc->dma_capture >= 0)
--	        sound_free_dma(hw_config->dma2);
-+	if (devc->dma_capture >= 0 && devc->dma_capture != devc->dma_playback)
-+	        sound_free_dma(devc->dma_capture);
- out_free_dma:
--	sound_free_dma(hw_config->dma);
-+	sound_free_dma(devc->dma_playback);
- out_free_irq:
--	free_irq(hw_config->irq,hw_config->osp);
-+	free_irq(devc->irq, devc);
- out_release_region:
--	release_region(hw_config->io_base, 16);
--	goto out;
-+	release_region(devc->base, 16);
-+out:
-+	return 0;
- }
- 
- static void __exit unload_card(ad1816_info *devc)
-@@ -1212,7 +1172,7 @@ static void __exit unload_card(ad1816_in
- 	int  mixer, dev = 0;
- 	
- 	if (devc != NULL) {
--		DEBUGLOG (printk("ad1816: Unloading card at base=%x\n",devc->base));
-+		printk("ad1816: Unloading card at address 0x%03x\n",devc->base);
- 		
- 		dev = devc->dev_no;
- 		mixer = audio_devs[dev]->mixer_dev;
-@@ -1221,45 +1181,41 @@ static void __exit unload_card(ad1816_in
- 		if(mixer>=0) {
- 			sound_unload_mixerdev(mixer);
- 		}
-+		/* unreg audiodev */
- 		sound_unload_audiodev(dev);
- 		
- 		/* free dma channels */
--		if (devc->dma_capture>=0) {
-+		if (devc->dma_capture>=0 && 
-+		  	devc->dma_capture != devc->dma_playback) {
- 			sound_free_dma(devc->dma_capture);
- 		}
--
--		/* card won't get added if resources could not be allocated
--		   thus we need not ckeck if allocation was successful */
- 		sound_free_dma (devc->dma_playback);
--		free_irq(devc->irq, devc->osp);
-+		/* free irq */
-+		free_irq(devc->irq, devc);
-+		/* free io */
- 		release_region (devc->base, 16);
--		
--		DEBUGLOG (printk("ad1816: Unloading card at base=%x was successful\n",devc->base));
-+#ifdef __ISAPNP__
-+		if (devc->pnpdev) {
-+		  	pnp_disable_dev(devc->pnpdev);
-+			pnp_device_detach(devc->pnpdev);
-+		}
-+#endif
- 		
- 	} else
- 		printk(KERN_WARNING "ad1816: no device/card specified\n");
- }
- 
--static struct address_info cfg;
--
- static int __initdata io = -1;
- static int __initdata irq = -1;
- static int __initdata dma = -1;
- static int __initdata dma2 = -1;
- 
- #ifdef __ISAPNP__
--struct pci_dev	*ad1816_dev  = NULL;
--
--static int activated	= 1;
--
-+/* use isapnp for configuration */
- static int isapnp	= 1;
- static int isapnpjump	= 0;
--
- MODULE_PARM(isapnp, "i");
- MODULE_PARM(isapnpjump, "i");
--
--#else
--static int isapnp = 0;
- #endif
- 
- MODULE_PARM(io,"i");
-@@ -1270,51 +1226,6 @@ MODULE_PARM(ad1816_clockfreq,"i");
- MODULE_PARM(options,"i");
- 
- #ifdef __ISAPNP__
--
--static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
--{
--	int err;
--	
--	if(dev->active) {
--		activated = 0;
--		return(dev);
--	}
--
--	if((err = dev->activate(dev)) < 0) {
--		printk(KERN_ERR "ad1816: %s %s config failed (out of resources?)[%d]\n",
--			devname, resname, err);
--		dev->deactivate(dev);
--		return(NULL);
--	}
--		
--	return(dev);
--}
--
--static struct pci_dev *ad1816_init_generic(struct pci_bus *bus, struct pci_dev *card,
--	struct address_info *hw_config)
--{
--	if((ad1816_dev = isapnp_find_dev(bus, card->vendor, card->device, NULL))) {
--		ad1816_dev->prepare(ad1816_dev);
--		
--		if((ad1816_dev = activate_dev("Analog Devices 1816(A)", "ad1816", ad1816_dev))) {
--			hw_config->io_base	= ad1816_dev->resource[2].start;
--			hw_config->irq		= ad1816_dev->irq_resource[0].start;
--			hw_config->dma		= ad1816_dev->dma_resource[0].start;
--			hw_config->dma2		= ad1816_dev->dma_resource[1].start;
--		}
--	}
--	
--	return(ad1816_dev);
--}
--
--static struct ad1816_data {
--	struct pci_dev * (*initfunc)(struct pci_bus*, struct pci_dev *, struct address_info *);
--	char *name;
--} ad1816_pnp_data[] __initdata = {
--	{ &ad1816_init_generic, "Analog Devices 1815" },
--	{ &ad1816_init_generic, "Analog Devices 1816A" }
--};
--
- static struct {
- 	unsigned short card_vendor, card_device;
- 	unsigned short vendor;
-@@ -1323,107 +1234,101 @@ static struct {
- } isapnp_ad1816_list[] __initdata = {
- 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- 		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150), 
--		&ad1816_pnp_data[0] },
-+		0 },
- 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- 		ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180),
--		&ad1816_pnp_data[1] },
-+		0 },
- 	{0}
- };
- 
- MODULE_DEVICE_TABLE(isapnp, isapnp_ad1816_list);
- 
--static int __init ad1816_init_isapnp(struct address_info *hw_config,
--	struct pci_bus *bus, struct pci_dev *card, int slot)
-+
-+void __init ad1816_config_pnp_card(struct pnp_card *card, unsigned short vendor,
-+	unsigned short function)
- {
--	struct pci_dev *idev = NULL;
--	
--	/* You missed the init func? That's bad. */
--	if(isapnp_ad1816_list[slot].data->initfunc) {
--		char *busname = bus->name[0] ? bus->name : isapnp_ad1816_list[slot].data->name;
--		
--		printk(KERN_INFO "ad1816: %s detected\n", busname);
--		
--		/* Initialize this baby. */
--		if((idev = isapnp_ad1816_list[slot].data->initfunc(bus, card, hw_config))) {
--			/* We got it. */
--
--			printk(KERN_NOTICE "ad1816: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
--				busname,
--				hw_config->io_base, hw_config->irq, hw_config->dma,
--				hw_config->dma2);
--			return 1;
--		} else
--			printk(KERN_INFO "ad1816: Failed to initialize %s\n", busname);
--	} else
--		printk(KERN_ERR "ad1816: Bad entry in ad1816.c PnP table\n");
--	
--	return 0;
-+	struct address_info cfg;
-+  	struct pnp_dev *card_dev = pnp_find_dev(card, vendor, function, NULL);
-+	if (!card_dev) return;
-+	if (pnp_device_attach(card_dev) < 0) {
-+	  	printk(KERN_WARNING "ad1816: Failed to attach PnP device\n");
-+		return;
-+	}
-+	if (pnp_activate_dev(card_dev) < 0) {
-+		printk(KERN_WARNING "ad1816: Failed to activate PnP device\n");
-+		pnp_device_detach(card_dev);
-+		return;
-+	}
-+	cfg.io_base = pnp_port_start(card_dev, 2);
-+	cfg.irq = pnp_irq(card_dev, 0);
-+	cfg.dma = pnp_irq(card_dev, 0);
-+	cfg.dma2 = pnp_irq(card_dev, 1);
-+	if (!ad1816_init_card(&cfg, card_dev)) {
-+	  	pnp_disable_dev(card_dev);
-+		pnp_device_detach(card_dev);
-+	}
- }
- 
--/*
-- * Actually this routine will detect and configure only the first card with successful
-- * initialization. isapnpjump could be used to jump to a specific entry.
-- * Please always add entries at the end of the array.
-- * Should this be fixed? - azummo
-- */
--
--int __init ad1816_probe_isapnp(struct address_info *hw_config)
-+void __init ad1816_config_pnp_cards(void)
- {
-+	int nr_pnp_cfg;
- 	int i;
- 	
- 	/* Count entries in isapnp_ad1816_list */
--	for (i = 0; isapnp_ad1816_list[i].vendor != 0; i++)
--		;
-+	for (nr_pnp_cfg = 0; isapnp_ad1816_list[nr_pnp_cfg].card_vendor != 0; 
-+		nr_pnp_cfg++);
- 	/* Check and adjust isapnpjump */
--	if( isapnpjump < 0 || isapnpjump > ( i - 1 ) ) {
--		printk(KERN_ERR "ad1816: Valid range for isapnpjump is 0-%d. Adjusted to 0.\n", i-1);
-+	if( isapnpjump < 0 || isapnpjump >= nr_pnp_cfg) {
-+		printk(KERN_WARNING 
-+			"ad1816: Valid range for isapnpjump is 0-%d. "
-+			"Adjusted to 0.\n", nr_pnp_cfg-1);
- 		isapnpjump = 0;
- 	}
--
--	 for (i = isapnpjump; isapnp_ad1816_list[i].vendor != 0; i++) {
--	 	struct pci_dev *card = NULL;
--		
--		while ((card = isapnp_find_dev(NULL, isapnp_ad1816_list[i].vendor,
--		  isapnp_ad1816_list[i].function, card)))
--			if(ad1816_init_isapnp(hw_config, card->bus, card, i))
--				return 0;
-+	for (i = isapnpjump; isapnp_ad1816_list[i].card_vendor != 0; i++) {
-+	 	struct pnp_card *card = NULL;
-+		/* iterate over all pnp cards */		
-+		while ((card = pnp_find_card(isapnp_ad1816_list[i].card_vendor,
-+		              	isapnp_ad1816_list[i].card_device, card))) 
-+			ad1816_config_pnp_card(card, 
-+				isapnp_ad1816_list[i].vendor,
-+				isapnp_ad1816_list[i].function);
- 	}
--
--	return -ENODEV;
- }
- #endif
- 
-+/* module initialization */
- static int __init init_ad1816(void)
- {
--
--#ifdef __ISAPNP__
--	if(isapnp && (ad1816_probe_isapnp(&cfg) < 0) ) {
--		printk(KERN_NOTICE "ad1816: No ISAPnP cards found, trying standard ones...\n");
--		isapnp = 0;
--	}
-+	printk(KERN_INFO "ad1816: AD1816 sounddriver "
-+			 "Copyright (C) 1998-2003 by Thorsten Knabe and "
-+			 "others\n");
-+#ifdef AD1816_CLOCK 
-+	/* set ad1816_clockfreq if set during compilation */
-+	ad1816_clockfreq=AD1816_CLOCK;
- #endif
--
--	if( isapnp == 0) {
--		cfg.io_base	= io;
--		cfg.irq		= irq;
--		cfg.dma		= dma;
--		cfg.dma2	= dma2;
--	}
--
--	if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1) {
--		printk(KERN_INFO "ad1816: dma, dma2, irq and io must be set.\n");
--		return -EINVAL;
-+	if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
-+		ad1816_clockfreq=33000;
- 	}
- 
--	if (probe_ad1816(&cfg) == 0) {
--		return -ENODEV;
-+#ifdef __ISAPNP__
-+	/* configure PnP cards */
-+	if(isapnp) ad1816_config_pnp_cards();
-+#endif
-+	/* configure card by module params */
-+	if (io != -1 && irq != -1 && dma != -1) {
-+		struct address_info cfg;
-+		cfg.io_base = io;
-+		cfg.irq = irq;
-+		cfg.dma = dma;
-+		cfg.dma2 = dma2;
-+		ad1816_init_card(&cfg, NULL);
- 	}
--
--	attach_ad1816(&cfg);
--
-+	if (nr_ad1816_devs <= 0)
-+	  	return -ENODEV;
- 	return 0;
- }
- 
-+/* module cleanup */
- static void __exit cleanup_ad1816 (void)
- {
- 	int          i;
-@@ -1435,18 +1340,14 @@ static void __exit cleanup_ad1816 (void)
- 		unload_card(devc);
- 	}     
- 	nr_ad1816_devs=0;
--
--#ifdef __ISAPNP__
--	if(activated)
--		if(ad1816_dev)
--			ad1816_dev->deactivate(ad1816_dev);
--#endif
-+	printk(KERN_INFO "ad1816: driver unloaded!\n");
- }
- 
- module_init(init_ad1816);
- module_exit(cleanup_ad1816);
- 
- #ifndef MODULE
-+/* kernel command line parameter evaluation */
- static int __init setup_ad1816(char *str)
- {
- 	/* io, irq, dma, dma2 */
-@@ -1458,7 +1359,6 @@ static int __init setup_ad1816(char *str
- 	irq	= ints[2];
- 	dma	= ints[3];
- 	dma2	= ints[4];
--
- 	return 1;
- }
- 
---- linux-2.6.0-test1/sound/oss/ad1889.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/ad1889.c	2003-07-19 17:03:51.000000000 -0700
-@@ -245,7 +245,6 @@ static ad1889_dev_t *ad1889_alloc_dev(st
- 		dmabuf->ready = 0;
- 		dmabuf->rate = 44100;
- 	}
--out:
- 	return dev;
- 
- err_free_dmabuf:
---- linux-2.6.0-test1/sound/oss/btaudio.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/btaudio.c	2003-07-19 17:03:51.000000000 -0700
-@@ -328,8 +328,8 @@ static int btaudio_mixer_ioctl(struct in
- 	if (cmd == SOUND_MIXER_INFO) {
- 		mixer_info info;
- 		memset(&info,0,sizeof(info));
--                strncpy(info.id,"bt878",sizeof(info.id));
--                strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-+                strlcpy(info.id,"bt878",sizeof(info.id));
-+                strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-                 info.modify_counter = bta->mixcount;
-                 if (copy_to_user((void *)arg, &info, sizeof(info)))
-                         return -EFAULT;
-@@ -338,8 +338,8 @@ static int btaudio_mixer_ioctl(struct in
- 	if (cmd == SOUND_OLD_MIXER_INFO) {
- 		_old_mixer_info info;
- 		memset(&info,0,sizeof(info));
--                strncpy(info.id,"bt878",sizeof(info.id)-1);
--                strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-+                strlcpy(info.id,"bt878",sizeof(info.id)-1);
-+                strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
-                 if (copy_to_user((void *)arg, &info, sizeof(info)))
-                         return -EFAULT;
- 		return 0;
---- linux-2.6.0-test1/sound/oss/dmasound/dmasound_core.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/dmasound/dmasound_core.c	2003-07-19 17:03:51.000000000 -0700
-@@ -1660,13 +1660,13 @@ static int __init dmasound_setup(char *s
- #ifdef HAS_RECORD
-         case 5:
-                 if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
--                        printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
-+                        printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
-                 else
-                         catchRadius = ints[5];
-                 /* fall through */
-         case 4:
-                 if (ints[4] < MIN_BUFFERS)
--                        printk("dmasound_setup: illegal number of read buffers, using default = %d\n",
-+                        printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
-                                  numReadBufs);
-                 else
-                         numReadBufs = ints[4];
-@@ -1675,21 +1675,21 @@ static int __init dmasound_setup(char *s
- 		if ((size = ints[3]) < 256)  /* check for small buffer specs */
- 			size <<= 10 ;
-                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
--                        printk("dmasound_setup: illegal read buffer size, using default = %d\n", readBufSize);
-+                        printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
-                 else
-                         readBufSize = size;
-                 /* fall through */
- #else
- 	case 3:
- 		if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
--			printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
-+			printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
- 		else
- 			catchRadius = ints[3];
- 		/* fall through */
- #endif
- 	case 2:
- 		if (ints[1] < MIN_BUFFERS)
--			printk("dmasound_setup: illegal number of buffers, using default = %d\n", numWriteBufs);
-+			printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
- 		else
- 			numWriteBufs = ints[1];
- 		/* fall through */
-@@ -1697,13 +1697,13 @@ static int __init dmasound_setup(char *s
- 		if ((size = ints[2]) < 256) /* check for small buffer specs */
- 			size <<= 10 ;
-                 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
--                        printk("dmasound_setup: illegal write buffer size, using default = %d\n", writeBufSize);
-+                        printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);
-                 else
-                         writeBufSize = size;
- 	case 0:
- 		break;
- 	default:
--		printk("dmasound_setup: illegal number of arguments\n");
-+		printk("dmasound_setup: invalid number of arguments\n");
- 		return 0;
- 	}
- 	return 1;
---- linux-2.6.0-test1/sound/oss/emu10k1/8010.h	2003-06-14 12:17:56.000000000 -0700
-+++ 25/sound/oss/emu10k1/8010.h	2003-07-19 17:03:51.000000000 -0700
-@@ -1,7 +1,7 @@
- /*
-  **********************************************************************
-  *     8010.h
-- *     Copyright 1999, 2000 Creative Labs, Inc.
-+ *     Copyright 1999-2001 Creative Labs, Inc.
-  *
-  **********************************************************************
-  *
-@@ -11,6 +11,8 @@
-  *     November 2, 1999     Alan Cox	    Cleaned of 8bit chars, DOS
-  *					    line endings
-  *     December 8, 1999     Jon Taylor	    Added lots of new register info
-+ *     May 16, 2001         Daniel Bertrand Added unofficial DBG register info
-+ *     Oct-Nov 2001         D.B.            Added unofficial Audigy registers 
-  *
-  **********************************************************************
-  *
-@@ -39,6 +41,14 @@
- 
- #include <linux/types.h>
- 
-+// Driver version:
-+#define MAJOR_VER 0
-+#define MINOR_VER 20
-+#define DRIVER_VERSION "0.20a"
-+
-+
-+// Audigy specify registers are prefixed with 'A_'
-+
- /************************************************************************************************/
- /* PCI function 0 registers, address = <val> + PCIBASE0						*/
- /************************************************************************************************/
-@@ -57,6 +67,11 @@
- #define IPR			0x08		/* Global interrupt pending register		*/
- 						/* Clear pending interrupts by writing a 1 to	*/
- 						/* the relevant bits and zero to the other bits	*/
-+
-+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-+#define A_IPR_MIDITRANSBUFEMPTY2	0x10000000	/* MIDI UART transmit buffer empty		*/
-+#define A_IPR_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
-+
- #define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
- #define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
- #define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
-@@ -81,6 +96,10 @@
- 						/* IP is written with CL set, the bit in CLIPL	*/
- 						/* or CLIPH corresponding to the CIN value 	*/
- 						/* written will be cleared.			*/
-+#define A_IPR_MIDITRANSBUFEMPTY1	IPR_MIDITRANSBUFEMPTY	/* MIDI UART transmit buffer empty		*/
-+#define A_IPR_MIDIRECVBUFEMPTY1	IPR_MIDIRECVBUFEMPTY	/* MIDI UART receive buffer empty		*/
-+
-+
- 
- #define INTE			0x0c		/* Interrupt enable register			*/
- #define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
-@@ -108,6 +127,11 @@
- 						/* behavior and possibly random segfaults and	*/
- 						/* lockups if enabled.				*/
- 
-+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-+#define A_INTE_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
-+#define A_INTE_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
-+
-+
- #define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
- 						/* NOTE: This bit must always be enabled       	*/
- #define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
-@@ -124,6 +148,10 @@
- #define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
- #define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
- 
-+/* The next two interrupts are for the midi port on the Audigy (A_MPU2)	*/
-+#define A_INTE_MIDITXENABLE1  	INTE_MIDITXENABLE
-+#define A_INTE_MIDIRXENABLE1	INTE_MIDIRXENABLE
-+
- #define WC			0x10		/* Wall Clock register				*/
- #define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
- #define WC_SAMPLECOUNTER	0x14060010
-@@ -186,6 +214,8 @@
- 						/* Should be set to 1 when the EMU10K1 is	*/
- 						/* completely initialized.			*/
- 
-+//For Audigy, MPU port move to 0x70-0x74 ptr register
-+
- #define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
- 
- #define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
-@@ -197,13 +227,16 @@
- #define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
- #define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
- 
--#define TIMER			0x1a		/* Timer terminal count register		*/
-+#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
-+#define A_GPINPUT_MASK		0xff00
-+#define A_GPOUTPUT_MASK		0x00ff
-+
-+#define TIMER			0x1a		/* Timer terminal count register (16-bit)	*/
- 						/* NOTE: After the rate is changed, a maximum	*/
- 						/* of 1024 sample periods should be allowed	*/
- 						/* before the new rate is guaranteed accurate.	*/
--#define TIMER_RATE_MASK		0x000003ff	/* Timer interrupt rate in sample periods	*/
-+#define TIMER_RATE_MASK		0x03ff		/* Timer interrupt rate in sample periods	*/
- 						/* 0 == 1024 periods, [1..4] are not useful	*/
--#define TIMER_RATE		0x0a00001a
- 
- #define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
- 
-@@ -386,6 +419,8 @@
- #define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
- #define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
- 						/* Signed 2's complement, with +/- 12dB extremes	*/
-+#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
-+						/* ??Hz steps, maximum of ?? Hz.			*/
- 
- #define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
- #define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
-@@ -426,7 +461,12 @@
- #define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
- 						/* NOTE: To guarantee phase coherency, both channels	*/
- 						/* must be disabled prior to enabling both channels.	*/
-+#define A_ADCCR_RCHANENABLE	0x00000020
-+#define A_ADCCR_LCHANENABLE	0x00000010
-+
-+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
- #define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
-+
- #define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
- #define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
- #define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
-@@ -436,10 +476,16 @@
- #define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
- #define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
- 
-+#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
-+#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
-+#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
-+
- #define FXWC			0x43		/* FX output write channels register			*/
- 						/* When set, each bit enables the writing of the	*/
--						/* corresponding FX output channel into host memory	*/
--
-+						/* corresponding FX output channel (internal registers  */
-+						/* 0x20-0x3f) into host memory. This mode of recording	*/
-+						/* is 16bit, 48KHz only. All 32	channels can be enabled */
-+						/* simultaneously.					*/
- #define TCBS			0x44		/* Tank cache buffer size register			*/
- #define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
- #define TCBS_BUFFSIZE_16K	0x00000000
-@@ -519,6 +565,13 @@
- 
- #define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
- 
-+#define A_DBG			 0x53
-+#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
-+#define A_DBG_ZC		 0x40000000	/* zero tram counter */
-+#define A_DBG_STEP_ADDR		 0x000003ff
-+#define A_DBG_SATURATION_OCCURED 0x20000000
-+#define A_DBG_SATURATION_ADDR	 0x0ffc0000
-+
- #define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
- 
- #define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
-@@ -582,10 +635,19 @@
- #define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
- #define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
- 
-+
-+/* Note that these values can vary +/- by a small amount                                        */
-+#define SRCS_SPDIFRATE_44	0x0003acd9
-+#define SRCS_SPDIFRATE_48	0x00040000
-+#define SRCS_SPDIFRATE_96	0x00080000
-+
- #define MICIDX                  0x63            /* Microphone recording buffer index register   */
- #define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
- #define MICIDX_IDX		0x10000063
- 
-+#define A_ADCIDX		0x63
-+#define A_ADCIDX_IDX		0x10000063
-+
- #define ADCIDX			0x64		/* ADC recording buffer index register		*/
- #define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
- #define ADCIDX_IDX		0x10000064
-@@ -594,9 +656,50 @@
- #define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
- #define FXIDX_IDX		0x10000065
- 
-+/* This is the MPU port on the card (via the game port)						*/
-+#define A_MUDATA1		0x70
-+#define A_MUCMD1		0x71
-+#define A_MUSTAT1		A_MUCMD1
-+
-+/* This is the MPU port on the Audigy Drive 							*/
-+#define A_MUDATA2		0x72
-+#define A_MUCMD2		0x73
-+#define A_MUSTAT2		A_MUCMD2	
-+
-+/* The next two are the Audigy equivalent of FXWC						*/
-+/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
-+/* Each bit selects a channel for recording */
-+#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
-+#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
-+
-+#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
-+#define A_SPDIF_48000		0x00000080
-+#define A_SPDIF_44100		0x00000000
-+#define A_SPDIF_96000		0x00000040
-+
-+#define A_FXRT2			0x7c
-+#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
-+#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
-+#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
-+#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
-+
-+#define A_SENDAMOUNTS		0x7d
-+#define A_FXSENDAMOUNT_E_MASK	0xff000000
-+#define A_FXSENDAMOUNT_F_MASK	0x00ff0000
-+#define A_FXSENDAMOUNT_G_MASK	0x0000ff00
-+#define A_FXSENDAMOUNT_H_MASK	0x000000ff
-+
-+/* The send amounts for this one are the same as used with the emu10k1 */
-+#define A_FXRT1			0x7e
-+#define A_FXRT_CHANNELA		0x0000003f
-+#define A_FXRT_CHANNELB		0x00003f00
-+#define A_FXRT_CHANNELC		0x003f0000
-+#define A_FXRT_CHANNELD		0x3f000000
-+
-+
- /* Each FX general purpose register is 32 bits in length, all bits are used			*/
- #define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
--
-+#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
- /* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
- /* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
- /* locations are for external TRAM. 								*/
-@@ -621,4 +724,14 @@
- #define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
- #define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
- 
-+
-+/* Audigy Soundcard have a different instruction format */
-+#define AUDIGY_CODEBASE		0x600
-+#define A_LOWORD_OPY_MASK	0x000007ff		
-+#define A_LOWORD_OPX_MASK	0x007ff000
-+#define A_HIWORD_OPCODE_MASK	0x0f000000
-+#define A_HIWORD_RESULT_MASK	0x007ff000
-+#define A_HIWORD_OPA_MASK	0x000007ff
-+
-+
- #endif /* _8010_H */
---- linux-2.6.0-test1/sound/oss/emu10k1/audio.c	2003-06-14 12:17:57.000000000 -0700
-+++ 25/sound/oss/emu10k1/audio.c	2003-07-19 17:03:51.000000000 -0700
-@@ -158,8 +158,8 @@ static ssize_t emu10k1_audio_write(struc
- 		spin_unlock_irqrestore(&woinst->lock, flags);
- 		return -ENXIO;
- 	}
--
--	if (woinst->format.passthrough) {
-+	// This is for emu10k1 revs less than 7, we need to go through tram
-+	if (woinst->format.passthrough == 1) {
- 		int r;
- 		
- 		woinst->buffer.ossfragshift = PT_BLOCKSIZE_LOG2;
-@@ -350,8 +350,9 @@ static int emu10k1_audio_ioctl(struct in
- 
- 	case SNDCTL_DSP_GETCAPS:
- 		DPF(2, "SNDCTL_DSP_GETCAPS:\n");
--		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_COPROC, (int *) arg);
--
-+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-+				DSP_CAP_TRIGGER | DSP_CAP_MMAP |
-+				DSP_CAP_COPROC| DSP_CAP_MULTI, (int *) arg);
- 	case SNDCTL_DSP_SPEED:
- 		DPF(2, "SNDCTL_DSP_SPEED:\n");
- 
-@@ -528,8 +529,8 @@ static int emu10k1_audio_ioctl(struct in
- 		else if (file->f_mode & FMODE_WRITE) {
- 			val = AFMT_S16_LE | AFMT_U8;
- 			if (emu10k1_find_control_gpr(&wave_dev->card->mgr,
--			    			     wave_dev->card->pt.patch_name, 
--			    			     wave_dev->card->pt.enable_gpr_name) >= 0)
-+						     wave_dev->card->pt.patch_name, 
-+						     wave_dev->card->pt.enable_gpr_name) >= 0)
- 				val |= AFMT_AC3;
- 		}
- 		return put_user(val, (int *) arg);
-@@ -789,7 +790,7 @@ static int emu10k1_audio_ioctl(struct in
- 				cinfo.blocks = 0;
- 			}
- 
--			if(wiinst->mmapped)
-+			if (wiinst->mmapped)
- 				wiinst->buffer.bytestocopy %= wiinst->buffer.fragment_size;
- 
- 			spin_unlock_irqrestore(&wiinst->lock, flags);
-@@ -811,15 +812,17 @@ static int emu10k1_audio_ioctl(struct in
- 			spin_lock_irqsave(&woinst->lock, flags);
- 
- 			if (woinst->state & WAVE_STATE_OPEN || 
--			    (woinst->format.passthrough && wave_dev->card->pt.state)) {
-+			    ((woinst->format.passthrough == 1) && wave_dev->card->pt.state)) {
- 				int num_fragments;
--				if (woinst->format.passthrough) {
-+
-+				if (woinst->format.passthrough == 1) {
- 					emu10k1_pt_waveout_update(wave_dev);
- 					cinfo.bytes = woinst->total_played;
- 				} else {
- 					emu10k1_waveout_update(woinst);
- 					cinfo.bytes = woinst->total_played;
- 				}
-+
- 				cinfo.ptr = woinst->buffer.hw_pos;
- 				num_fragments = cinfo.bytes / woinst->buffer.fragment_size;
- 				cinfo.blocks = num_fragments - woinst->blocks;
-@@ -899,7 +902,7 @@ static int emu10k1_audio_ioctl(struct in
- 
- 		if (file->f_mode & FMODE_WRITE) {
- 			/* digital pass-through fragment count and size are fixed values */
--			if (woinst->state & WAVE_STATE_OPEN || woinst->format.passthrough)
-+			if (woinst->state & WAVE_STATE_OPEN || (woinst->format.passthrough == 1))
- 				return -EINVAL;	/* too late to change */
- 
- 			woinst->buffer.ossfragshift = val & 0xffff;
-@@ -936,19 +939,35 @@ static int emu10k1_audio_ioctl(struct in
- 				kfree (buf);
- 				return -EINVAL;
- 			}
-+
-+			if (buf->command == CMD_WRITE) {
-+				
- #ifdef DBGEMU
--			if ( (buf->offs < 0) || (buf->offs + buf->len > 0x800) || (buf->len > 1000)) {
-+				if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
- #else
--			if ( ((buf->offs < 0x100 ) || (buf->offs + buf->len > 0x800) || (buf->len > 1000))
--			     && !( ( buf->offs == DBG) && (buf->len ==1) )){
--#endif	
--				kfree(buf);
--				return -EINVAL;
--			}
-+				if (((buf->offs < 0x100) || (buf->offs + buf->len > (wave_dev->card->is_audigy ? 0xe00 : 0x800)) || (buf->len > 1000)
-+				) && !(
-+					//any register allowed raw access to users goes here:
-+					(buf->offs == DBG ||
-+					  buf->offs == A_DBG)
-+					&& (buf->len == 1))) {
-+#endif		
-+					kfree(buf);
-+					return -EINVAL;
-+				}
-+			} else {
-+				if ((buf->offs < 0) || (buf->offs + buf->len > 0xe00) || (buf->len > 1000)) {
-+					kfree(buf);
-+					return -EINVAL;
-+				}
-+			}			
-+				
-+			if (((unsigned)buf->flags) > 0x3f)
-+				buf->flags = 0;
- 
- 			if (buf->command == CMD_READ) {
- 				for (i = 0; i < buf->len; i++)
--					((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, 0);
-+					((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags);
- 
- 				if (copy_to_user((copr_buffer *) arg, buf, sizeof(copr_buffer))) {
- 					kfree(buf);
-@@ -956,7 +975,7 @@ static int emu10k1_audio_ioctl(struct in
- 				}
- 			} else {
- 				for (i = 0; i < buf->len; i++)
--					sblive_writeptr(wave_dev->card, buf->offs + i, 0, ((u32 *) buf->data)[i]);
-+					sblive_writeptr(wave_dev->card, buf->offs + i, buf->flags, ((u32 *) buf->data)[i]);
- 			}
- 
- 			kfree (buf);
-@@ -1244,8 +1263,9 @@ static int emu10k1_audio_release(struct 
- 		struct woinst *woinst = wave_dev->woinst;
- 
- 		spin_lock_irqsave(&woinst->lock, flags);
--
--		if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE) {
-+		if(woinst->format.passthrough==2)
-+			card->pt.state=PT_STATE_PLAYING;
-+		if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE){
- 			spin_lock(&card->pt.lock);
-                         emu10k1_pt_stop(card);
- 			spin_unlock(&card->pt.lock);
---- linux-2.6.0-test1/sound/oss/emu10k1/cardmi.c	2003-06-14 12:18:22.000000000 -0700
-+++ 25/sound/oss/emu10k1/cardmi.c	2003-07-19 17:03:51.000000000 -0700
-@@ -113,7 +113,7 @@ int emu10k1_mpuin_close(struct emu10k1_c
- 	}
- 
- 	/* Disable RX interrupt */
--	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
-+	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
- 
- 	emu10k1_mpu_release(card);
- 
-@@ -189,7 +189,7 @@ int emu10k1_mpuin_start(struct emu10k1_c
- 		card_mpuin->qhead = 0;
- 		card_mpuin->qtail = 0;
- 
--		emu10k1_irq_enable(card, INTE_MIDIRXENABLE);
-+		emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
- 	}
- 
- 	return 0;
-@@ -207,7 +207,7 @@ int emu10k1_mpuin_stop(struct emu10k1_ca
- 
- 	DPF(2, "emu10k1_mpuin_stop()\n");
- 
--	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
-+	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
- 
- 	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */
- 
-@@ -246,7 +246,7 @@ int emu10k1_mpuin_reset(struct emu10k1_c
- 
- 	DPF(2, "emu10k1_mpuin_reset()\n");
- 
--	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
-+	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);
- 
- 	while (card_mpuin->firstmidiq) {
- 		midiq = card_mpuin->firstmidiq;
---- linux-2.6.0-test1/sound/oss/emu10k1/cardmo.c	2003-06-14 12:17:58.000000000 -0700
-+++ 25/sound/oss/emu10k1/cardmo.c	2003-07-19 17:03:51.000000000 -0700
-@@ -72,7 +72,7 @@ int emu10k1_mpuout_close(struct emu10k1_
- 
- 	DPF(2, "emu10k1_mpuout_close()\n");
- 
--	emu10k1_irq_disable(card, INTE_MIDITXENABLE);
-+	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
- 
- 	spin_lock_irqsave(&card_mpuout->lock, flags);
- 
-@@ -142,7 +142,7 @@ int emu10k1_mpuout_add_buffer(struct emu
- 
- 	card_mpuout->intr = 0;
- 
--	emu10k1_irq_enable(card, INTE_MIDITXENABLE);
-+	emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
- 
- 	spin_unlock_irqrestore(&card_mpuout->lock, flags);
- 
-@@ -206,7 +206,7 @@ void emu10k1_mpuout_bh(unsigned long ref
- 
- 	if ((card_mpuout->firstmidiq != NULL) || cByteSent) {
- 		card_mpuout->intr = 0;
--		emu10k1_irq_enable(card, INTE_MIDITXENABLE);
-+		emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
- 	}
- 
- 	spin_unlock_irqrestore(&card_mpuout->lock, flags);
-@@ -221,7 +221,7 @@ int emu10k1_mpuout_irqhandler(struct emu
- 	DPF(4, "emu10k1_mpuout_irqhandler\n");
- 
- 	card_mpuout->intr = 1;
--	emu10k1_irq_disable(card, INTE_MIDITXENABLE);
-+	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);
- 
- 	tasklet_hi_schedule(&card_mpuout->tasklet);
- 
---- linux-2.6.0-test1/sound/oss/emu10k1/cardwo.c	2003-06-14 12:18:30.000000000 -0700
-+++ 25/sound/oss/emu10k1/cardwo.c	2003-07-19 17:03:51.000000000 -0700
-@@ -85,25 +85,36 @@ static void query_format(struct emu10k1_
- 		break;
- 	}	
- 	if (do_passthrough) {
--		i = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.intr_gpr_name);
--		j = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.enable_gpr_name);
- 		/* currently only one waveout instance may use pass-through */
--		if (i < 0 || j < 0 || woinst->state != WAVE_STATE_CLOSED || 
-+		if (woinst->state != WAVE_STATE_CLOSED || 
- 		    card->pt.state != PT_STATE_INACTIVE ||
--		    (wave_fmt->samplingrate != 48000 && !is_ac3) ||
- 		    (wave_fmt->samplingrate != 48000 && !is_ac3)) {
- 			DPF(2, "unable to set pass-through mode\n");
--		} else {
--			wave_fmt->samplingrate = 48000;
--			wave_fmt->channels = 2;
--			wave_fmt->passthrough = 1;
--			card->pt.intr_gpr = i;
--			card->pt.enable_gpr = j;
--			card->pt.state = PT_STATE_INACTIVE;
--			card->pt.pos_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.pos_gpr_name);
--			DPD(2, "is_ac3 is %d\n", is_ac3);
--			card->pt.ac3data = is_ac3;
--	                wave_fmt->bitsperchannel = 16;
-+		} else if (USE_PT_METHOD1) {
-+			i = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.intr_gpr_name);
-+			j = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.enable_gpr_name);
-+			if (i < 0 || j < 0)
-+				DPF(2, "unable to set pass-through mode\n");
-+			else {
-+				wave_fmt->samplingrate = 48000;
-+				wave_fmt->channels = 2;
-+				card->pt.pos_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
-+									    card->pt.pos_gpr_name);
-+				wave_fmt->passthrough = 1;
-+				card->pt.intr_gpr = i;
-+				card->pt.enable_gpr = j;
-+				card->pt.state = PT_STATE_INACTIVE;
-+			
-+				DPD(2, "is_ac3 is %d\n", is_ac3);
-+				card->pt.ac3data = is_ac3;
-+				wave_fmt->bitsperchannel = 16;
-+			}
-+		}else{
-+			DPF(2, "Using Passthrough Method 2\n");
-+			card->pt.enable_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
-+								       card->pt.enable_gpr_name);
-+			wave_fmt->passthrough = 2;
-+			wave_fmt->bitsperchannel = 16;
- 		}
- 	}
- 
-@@ -149,33 +160,37 @@ static int get_voice(struct emu10k1_card
- 	voice->endloop = voice->startloop + woinst->buffer.size / woinst->format.bytespervoicesample;
- 	voice->start = voice->startloop;
- 
--	if (voice->flags & VOICE_FLAGS_STEREO) {
--		voice->params[0].send_a = card->waveout.send_a[1];
--		voice->params[0].send_b = card->waveout.send_b[1];
--		voice->params[0].send_c = card->waveout.send_c[1];
--		voice->params[0].send_d = card->waveout.send_d[1];
--
--		if (woinst->device)
--			voice->params[0].send_routing = 0x7654;
--		else
--			voice->params[0].send_routing = card->waveout.send_routing[1];
--
--		voice->params[0].volume_target = 0xffff;
--		voice->params[0].initial_fc = 0xff;
--		voice->params[0].initial_attn = 0x00;
--		voice->params[0].byampl_env_sustain = 0x7f;
--		voice->params[0].byampl_env_decay = 0x7f;
--
--		voice->params[1].send_a = card->waveout.send_a[2];
--		voice->params[1].send_b = card->waveout.send_b[2];
--		voice->params[1].send_c = card->waveout.send_c[2];
--		voice->params[1].send_d = card->waveout.send_d[2];
--
--		if (woinst->device)
--			voice->params[1].send_routing = 0x7654;
--		else
--			voice->params[1].send_routing = card->waveout.send_routing[2];
-+	
-+	voice->params[0].volume_target = 0xffff;
-+	voice->params[0].initial_fc = 0xff;
-+	voice->params[0].initial_attn = 0x00;
-+	voice->params[0].byampl_env_sustain = 0x7f;
-+	voice->params[0].byampl_env_decay = 0x7f;
- 
-+	
-+	if (voice->flags & VOICE_FLAGS_STEREO) {
-+		if (woinst->format.passthrough == 2) {
-+			voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PT];
-+			voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PT];
-+			voice->params[0].send_dcba = 0xff;
-+			voice->params[1].send_dcba = 0xff00;
-+			voice->params[0].send_hgfe = voice->params[1].send_hgfe=0;
-+		} else {
-+			voice->params[0].send_dcba = card->waveout.send_dcba[SEND_LEFT];
-+			voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_LEFT];
-+			voice->params[1].send_dcba = card->waveout.send_dcba[SEND_RIGHT];
-+			voice->params[1].send_hgfe = card->waveout.send_hgfe[SEND_RIGHT];
-+
-+			if (woinst->device) {
-+				// /dev/dps1
-+				voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PCM1];
-+				voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
-+			} else {
-+				voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PCM];
-+				voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
-+			}
-+		}
-+		
- 		voice->params[1].volume_target = 0xffff;
- 		voice->params[1].initial_fc = 0xff;
- 		voice->params[1].initial_attn = 0x00;
-@@ -183,30 +198,28 @@ static int get_voice(struct emu10k1_card
- 		voice->params[1].byampl_env_decay = 0x7f;
- 	} else {
- 		if (woinst->num_voices > 1) {
--			voice->params[0].send_a = 0xff;
--			voice->params[0].send_b = 0;
--			voice->params[0].send_c = 0;
--			voice->params[0].send_d = 0;
--
--			voice->params[0].send_routing =
--			 0xfff0 + card->mchannel_fx + voicenum;
-+			// Multichannel pcm
-+			voice->params[0].send_dcba=0xff;
-+			voice->params[0].send_hgfe=0;
-+			if (card->is_audigy) {
-+				voice->params[0].send_routing = 0x3f3f3f00 + card->mchannel_fx + voicenum;
-+				voice->params[0].send_routing2 = 0x3f3f3f3f;
-+			} else {
-+				voice->params[0].send_routing = 0xfff0 + card->mchannel_fx + voicenum;
-+			}
-+			
- 		} else {
--			voice->params[0].send_a = card->waveout.send_a[0];
--			voice->params[0].send_b = card->waveout.send_b[0];
--			voice->params[0].send_c = card->waveout.send_c[0];
--			voice->params[0].send_d = card->waveout.send_d[0];
--
--			if (woinst->device)
--				voice->params[0].send_routing = 0x7654;
--			else
--				voice->params[0].send_routing = card->waveout.send_routing[0];
--		}	
--
--		voice->params[0].volume_target = 0xffff;
--		voice->params[0].initial_fc = 0xff;
--		voice->params[0].initial_attn = 0x00;
--		voice->params[0].byampl_env_sustain = 0x7f;
--		voice->params[0].byampl_env_decay = 0x7f;
-+			voice->params[0].send_dcba = card->waveout.send_dcba[SEND_MONO];
-+			voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_MONO];
-+
-+			if (woinst->device) {
-+				voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM1];
-+				voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
-+			} else {
-+				voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM];
-+				voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
-+			}
-+		}
- 	}
- 
- 	DPD(2, "voice: startloop=%#x, endloop=%#x\n", voice->startloop, voice->endloop);
-@@ -280,9 +293,16 @@ void emu10k1_waveout_start(struct emu10k
- {
- 	struct emu10k1_card *card = wave_dev->card;
- 	struct woinst *woinst = wave_dev->woinst;
-+	struct pt_data *pt = &card->pt;
- 
- 	DPF(2, "emu10k1_waveout_start()\n");
- 
-+	if (woinst->format.passthrough == 2) {
-+		emu10k1_pt_setup(wave_dev);
-+		sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + pt->enable_gpr, 0, 1);
-+		pt->state = PT_STATE_PLAYING;
-+	}
-+
- 	/* Actual start */
- 	emu10k1_voices_start(woinst->voice, woinst->num_voices, woinst->total_played);
- 
---- linux-2.6.0-test1/sound/oss/emu10k1/efxmgr.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/emu10k1/efxmgr.c	2003-07-19 17:03:51.000000000 -0700
-@@ -80,15 +80,20 @@ void emu10k1_set_control_gpr(struct emu1
- 	if (addr < 0 || addr >= NUM_GPRS)
- 		return;
- 
--	if (flag)
--		val += sblive_readptr(card, GPR_BASE + addr, 0);
--
--	if (val > mgr->gpr[addr].max)
--		val = mgr->gpr[addr].max;
--	else if (val < mgr->gpr[addr].min)
--		val = mgr->gpr[addr].min;
--
--	sblive_writeptr(card, GPR_BASE + addr, 0, val);
-+	//fixme: once patch manager is up, remember to fix this for the audigy
-+	if (card->is_audigy) {
-+		sblive_writeptr(card, A_GPR_BASE + addr, 0, val);
-+	} else {
-+		if (flag)
-+			val += sblive_readptr(card, GPR_BASE + addr, 0);
-+		if (val > mgr->gpr[addr].max)
-+			val = mgr->gpr[addr].max;
-+		else if (val < mgr->gpr[addr].min)
-+			val = mgr->gpr[addr].min;
-+		sblive_writeptr(card, GPR_BASE + addr, 0, val);
-+	}
-+	
-+	
- }
- 
- //TODO: make this configurable:
---- linux-2.6.0-test1/sound/oss/emu10k1/efxmgr.h	2003-06-14 12:18:35.000000000 -0700
-+++ 25/sound/oss/emu10k1/efxmgr.h	2003-07-19 17:03:51.000000000 -0700
-@@ -32,16 +32,30 @@
- #ifndef _EFXMGR_H
- #define _EFXMGR_H
- 
--#define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (b), 0, (c))
-+struct emu_efx_info_t{
-+	int opcode_shift;
-+	int high_operand_shift;
-+	int instruction_start;
-+	int gpr_base;
-+	int output_base;
-+};
-+
-+
-+#define WRITE_EFX(a, b, c) sblive_writeptr((a), emu_efx_info[card->is_audigy].instruction_start + (b), 0, (c))
- 
- #define OP(op, z, w, x, y) \
--	do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
--	WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
-+	do { WRITE_EFX(card, (pc) * 2, ((x) << emu_efx_info[card->is_audigy].high_operand_shift) | (y)); \
-+	WRITE_EFX(card, (pc) * 2 + 1, ((op) << emu_efx_info[card->is_audigy].opcode_shift ) | ((z) << emu_efx_info[card->is_audigy].high_operand_shift) | (w)); \
- 	++pc; } while (0)
- 
- #define NUM_INPUTS 0x20
- #define NUM_OUTPUTS 0x20
- #define NUM_GPRS 0x100
-+
-+#define A_NUM_INPUTS 0x60
-+#define A_NUM_OUTPUTS 0x60  //fixme: this may or may not be true
-+#define A_NUM_GPRS 0x200
-+
- #define GPR_NAME_SIZE   32
- #define PATCH_NAME_SIZE 32
- 
-@@ -98,6 +112,9 @@ enum {
- #define GPR_BASE 0x100
- #define OUTPUT_BASE 0x20
- 
-+#define A_GPR_BASE 0x400
-+#define A_OUTPUT_BASE 0x60
-+
- #define MAX_PATCHES_PAGES 32
- 
- struct patch_manager {
---- linux-2.6.0-test1/sound/oss/emu10k1/hwaccess.c	2003-06-14 12:18:06.000000000 -0700
-+++ 25/sound/oss/emu10k1/hwaccess.c	2003-07-19 17:03:51.000000000 -0700
-@@ -160,6 +160,24 @@ void emu10k1_writefn0(struct emu10k1_car
- 	return;
- }
- 
-+void emu10k1_writefn0_2(struct emu10k1_card *card, u32 reg, u32 data, int size)
-+{
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&card->lock, flags);
-+
-+	if (size == 32)
-+		outl(data, card->iobase + (reg & 0x1F));
-+	else if (size == 16)
-+		outw(data, card->iobase + (reg & 0x1F));
-+	else
-+		outb(data, card->iobase + (reg & 0x1F));
-+
-+	spin_unlock_irqrestore(&card->lock, flags);
-+
-+	return;
-+}
-+
- u32 emu10k1_readfn0(struct emu10k1_card * card, u32 reg)
- {
- 	u32 val;
-@@ -200,12 +218,13 @@ void emu10k1_timer_set(struct emu10k1_ca
- * write/read Emu10k1 pointer-offset register set, accessed through      *
- *  the PTR and DATA registers                                           *
- *************************************************************************/
-+#define A_PTR_ADDRESS_MASK 0x0fff0000
- void sblive_writeptr(struct emu10k1_card *card, u32 reg, u32 channel, u32 data)
- {
- 	u32 regptr;
- 	unsigned long flags;
- 
--	regptr = ((reg << 16) & PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
-+	regptr = ((reg << 16) & A_PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
- 
- 	if (reg & 0xff000000) {
- 		u32 mask;
-@@ -242,7 +261,7 @@ void sblive_writeptr_tag(struct emu10k1_
- 	spin_lock_irqsave(&card->lock, flags);
- 	while ((reg = va_arg(args, u32)) != TAGLIST_END) {
- 		u32 data = va_arg(args, u32);
--		u32 regptr = (((reg << 16) & PTR_ADDRESS_MASK)
-+		u32 regptr = (((reg << 16) & A_PTR_ADDRESS_MASK)
- 			      | (channel & PTR_CHANNELNUM_MASK));
- 		outl(regptr, card->iobase + PTR);
- 		if (reg & 0xff000000) {
-@@ -267,7 +286,7 @@ u32 sblive_readptr(struct emu10k1_card *
- 	u32 regptr, val;
- 	unsigned long flags;
- 
--	regptr = ((reg << 16) & PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
-+	regptr = ((reg << 16) & A_PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
- 
- 	if (reg & 0xff000000) {
- 		u32 mask;
-@@ -389,7 +408,7 @@ void emu10k1_ac97_write(struct ac97_code
- 
- 	outb(reg, card->iobase + AC97ADDRESS);
- 	outw(value, card->iobase + AC97DATA);
--
-+	outb( AC97_EXTENDED_ID, card->iobase + AC97ADDRESS); 
- 	spin_unlock_irqrestore(&card->lock, flags);
- }
- 
-@@ -402,15 +421,23 @@ int emu10k1_mpu_write_data(struct emu10k
- 	unsigned long flags;
- 	int ret;
- 
--	spin_lock_irqsave(&card->lock, flags);
-+	if (card->is_audigy) {
-+		if ((sblive_readptr(card, A_MUSTAT,0) & MUSTAT_ORDYN) == 0) {
-+			sblive_writeptr(card, A_MUDATA, 0, data);
-+			ret = 0;
-+		} else
-+			ret = -1;
-+	} else {
-+		spin_lock_irqsave(&card->lock, flags);
- 
--	if ((inb(card->iobase + MUSTAT) & MUSTAT_ORDYN) == 0) {
--		outb(data, card->iobase + MUDATA);
--		ret = 0;
--	} else
--		ret = -1;
-+		if ((inb(card->iobase + MUSTAT) & MUSTAT_ORDYN) == 0) {
-+			outb(data, card->iobase + MUDATA);
-+			ret = 0;
-+		} else
-+			ret = -1;
- 
--	spin_unlock_irqrestore(&card->lock, flags);
-+		spin_unlock_irqrestore(&card->lock, flags);
-+	}
- 
- 	return ret;
- }
-@@ -420,15 +447,23 @@ int emu10k1_mpu_read_data(struct emu10k1
- 	unsigned long flags;
- 	int ret;
- 
--	spin_lock_irqsave(&card->lock, flags);
-+	if (card->is_audigy) {
-+		if ((sblive_readptr(card, A_MUSTAT,0) & MUSTAT_IRDYN) == 0) {
-+			*data = sblive_readptr(card, A_MUDATA,0);
-+			ret = 0;
-+		} else
-+			ret = -1;
-+	} else {
-+		spin_lock_irqsave(&card->lock, flags);
- 
--	if ((inb(card->iobase + MUSTAT) & MUSTAT_IRDYN) == 0) {
--		*data = inb(card->iobase + MUDATA);
--		ret = 0;
--	} else
--		ret = -1;
-+		if ((inb(card->iobase + MUSTAT) & MUSTAT_IRDYN) == 0) {
-+			*data = inb(card->iobase + MUDATA);
-+			ret = 0;
-+		} else
-+			ret = -1;
- 
--	spin_unlock_irqrestore(&card->lock, flags);
-+		spin_unlock_irqrestore(&card->lock, flags);
-+	}
- 
- 	return ret;
- }
-@@ -439,37 +474,54 @@ int emu10k1_mpu_reset(struct emu10k1_car
- 	unsigned long flags;
- 
- 	DPF(2, "emu10k1_mpu_reset()\n");
-+	if (card->is_audigy) {
-+		if (card->mpuacqcount == 0) {
-+			sblive_writeptr(card, A_MUCMD, 0, MUCMD_RESET);
-+			sblive_wcwait(card, 8);
-+			sblive_writeptr(card, A_MUCMD, 0, MUCMD_RESET);
-+			sblive_wcwait(card, 8);
-+			sblive_writeptr(card, A_MUCMD, 0, MUCMD_ENTERUARTMODE);
-+			sblive_wcwait(card, 8);
-+			status = sblive_readptr(card, A_MUDATA, 0);
-+			if (status == 0xfe)
-+				return 0;
-+			else
-+				return -1;
-+		}
- 
--	if (card->mpuacqcount == 0) {
--		spin_lock_irqsave(&card->lock, flags);
--		outb(MUCMD_RESET, card->iobase + MUCMD);
--		spin_unlock_irqrestore(&card->lock, flags);
-+		return 0;
-+	} else {
-+		if (card->mpuacqcount == 0) {
-+			spin_lock_irqsave(&card->lock, flags);
-+			outb(MUCMD_RESET, card->iobase + MUCMD);
-+			spin_unlock_irqrestore(&card->lock, flags);
- 
--		sblive_wcwait(card, 8);
-+			sblive_wcwait(card, 8);
- 
--		spin_lock_irqsave(&card->lock, flags);
--		outb(MUCMD_RESET, card->iobase + MUCMD);
--		spin_unlock_irqrestore(&card->lock, flags);
-+			spin_lock_irqsave(&card->lock, flags);
-+			outb(MUCMD_RESET, card->iobase + MUCMD);
-+			spin_unlock_irqrestore(&card->lock, flags);
- 
--		sblive_wcwait(card, 8);
-+			sblive_wcwait(card, 8);
- 
--		spin_lock_irqsave(&card->lock, flags);
--		outb(MUCMD_ENTERUARTMODE, card->iobase + MUCMD);
--		spin_unlock_irqrestore(&card->lock, flags);
-+			spin_lock_irqsave(&card->lock, flags);
-+			outb(MUCMD_ENTERUARTMODE, card->iobase + MUCMD);
-+			spin_unlock_irqrestore(&card->lock, flags);
- 
--		sblive_wcwait(card, 8);
-+			sblive_wcwait(card, 8);
- 
--		spin_lock_irqsave(&card->lock, flags);
--		status = inb(card->iobase + MUDATA);
--		spin_unlock_irqrestore(&card->lock, flags);
-+			spin_lock_irqsave(&card->lock, flags);
-+			status = inb(card->iobase + MUDATA);
-+			spin_unlock_irqrestore(&card->lock, flags);
- 
--		if (status == 0xfe)
--			return 0;
--		else
--			return -1;
--	}
-+			if (status == 0xfe)
-+				return 0;
-+			else
-+				return -1;
-+		}
- 
--	return 0;
-+		return 0;
-+	}
- }
- 
- int emu10k1_mpu_acquire(struct emu10k1_card *card)
---- linux-2.6.0-test1/sound/oss/emu10k1/hwaccess.h	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/emu10k1/hwaccess.h	2003-07-19 17:03:51.000000000 -0700
-@@ -79,13 +79,21 @@ struct memhandle
- 
- struct emu10k1_waveout
- {
--	u16 send_routing[3];
--
--	u8 send_a[3];
--	u8 send_b[3];
--	u8 send_c[3];
--	u8 send_d[3];
-+	u32 send_routing[3];
-+	// audigy only:
-+	u32 send_routing2[3];
-+
-+	u32 send_dcba[3];
-+	// audigy only:
-+	u32 send_hgfe[3];
- };
-+#define ROUTE_PCM 0
-+#define ROUTE_PT 1
-+#define ROUTE_PCM1 2
-+
-+#define SEND_MONO 0
-+#define SEND_LEFT 1
-+#define SEND_RIGHT 2
- 
- struct emu10k1_wavein
- {
-@@ -129,7 +137,7 @@ struct mixer_private_ioctl {
- #define CMD_AC97_BOOST		_IOW('D', 20, struct mixer_private_ioctl)
- 
- //up this number when breaking compatibility
--#define PRIVATE3_VERSION 1
-+#define PRIVATE3_VERSION 2
- 
- struct emu10k1_card 
- {
-@@ -181,7 +189,7 @@ struct emu10k1_card 
- 	u32	    has_toslink;	       // TOSLink detection
- 
- 	u8 chiprev;                    /* Chip revision                */
--
-+	u8 is_audigy;
- 	u8 is_aps;
- 
- 	struct patch_manager mgr;
-@@ -211,6 +219,7 @@ extern struct list_head emu10k1_devs;
- /* Hardware Abstraction Layer access functions */
- 
- void emu10k1_writefn0(struct emu10k1_card *, u32, u32);
-+void emu10k1_writefn0_2(struct emu10k1_card *, u32, u32, int);
- u32 emu10k1_readfn0(struct emu10k1_card *, u32);
- 
- void emu10k1_timer_set(struct emu10k1_card *, u16);
---- linux-2.6.0-test1/sound/oss/emu10k1/irqmgr.h	2003-06-14 12:18:03.000000000 -0700
-+++ 25/sound/oss/emu10k1/irqmgr.h	2003-07-19 17:03:51.000000000 -0700
-@@ -33,15 +33,15 @@
- #define _IRQ_H
- 
- /* EMU Irq Types */
--#define IRQTYPE_PCIBUSERROR         IPR_PCIERROR
--#define IRQTYPE_MIXERBUTTON         (IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
--#define IRQTYPE_VOICE               (IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
--#define IRQTYPE_RECORD              (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
--#define IRQTYPE_MPUOUT              IPR_MIDITRANSBUFEMPTY
--#define IRQTYPE_MPUIN               IPR_MIDIRECVBUFEMPTY
--#define IRQTYPE_TIMER               IPR_INTERVALTIMER
--#define IRQTYPE_SPDIF               (IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
--#define IRQTYPE_DSP                 IPR_FXDSP
-+#define IRQTYPE_PCIBUSERROR	IPR_PCIERROR
-+#define IRQTYPE_MIXERBUTTON	(IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
-+#define IRQTYPE_VOICE		(IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
-+#define IRQTYPE_RECORD		(IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
-+#define IRQTYPE_MPUOUT		(IPR_MIDITRANSBUFEMPTY | A_IPR_MIDITRANSBUFEMPTY2) 
-+#define IRQTYPE_MPUIN		(IPR_MIDIRECVBUFEMPTY | A_IPR_MIDIRECVBUFEMPTY2)
-+#define IRQTYPE_TIMER		IPR_INTERVALTIMER
-+#define IRQTYPE_SPDIF		(IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
-+#define IRQTYPE_DSP		IPR_FXDSP
- 
- void emu10k1_timer_irqhandler(struct emu10k1_card *);
- void emu10k1_dsp_irqhandler(struct emu10k1_card *);
---- linux-2.6.0-test1/sound/oss/emu10k1/main.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/emu10k1/main.c	2003-07-19 17:03:51.000000000 -0700
-@@ -78,10 +78,11 @@
-  *          Cleaned up poll() functions (audio and midi). Don't start input.
-  *	    Restrict DMA pages used to 512Mib range.
-  *	    New AC97_BOOST mixer ioctl.
-- *     0.19 Real fix for kernel with highmem support (cast dma_handle to u32).
-+ *    0.19a Added Support for Audigy Cards
-+ *	    Real fix for kernel with highmem support (cast dma_handle to u32).
-  *	    Fix recording buffering parameters calculation.
-  *	    Use unsigned long for variables in bit ops.
-- *     0.20 Fixed recording startup
-+ *    0.20a Fixed recording startup
-  *	    Fixed timer rate setting (it's a 16-bit register)
-  *********************************************************************/
- 
-@@ -114,7 +115,6 @@
- #define SNDCARD_EMU10K1 46
- #endif
-  
--#define DRIVER_VERSION "0.20"
- 
- /* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */
- #define EMU10K1_DMA_MASK                0x1fffffff	/* DMA buffer mask for pci_alloc_consist */
-@@ -126,20 +126,27 @@
- #ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
- #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
- #endif
-+#ifndef PCI_DEVICE_ID_CREATIVE_AUDIGY
-+#define PCI_DEVICE_ID_CREATIVE_AUDIGY 0x0004
-+#endif
- 
- #define EMU_APS_SUBID	0x40011102
-  
- enum {
- 	EMU10K1 = 0,
-+	AUDIGY,
- };
- 
- static char *card_names[] __devinitdata = {
- 	"EMU10K1",
-+	"Audigy",
- };
- 
- static struct pci_device_id emu10k1_pci_tbl[] = {
- 	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_EMU10K1,
- 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, EMU10K1},
-+	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_AUDIGY,
-+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AUDIGY},
- 	{0,}
- };
- 
-@@ -161,6 +168,67 @@ extern irqreturn_t emu10k1_interrupt(int
- 
- static int __devinit emu10k1_audio_init(struct emu10k1_card *card)
- {
-+	/* Assign default playback voice parameters */
-+	if (card->is_audigy)
-+		card->mchannel_fx = 0;
-+	else
-+		card->mchannel_fx = 8;
-+
-+
-+	if (card->is_audigy) {
-+		/* mono voice */
-+		card->waveout.send_dcba[SEND_MONO] = 0xffffffff;
-+		card->waveout.send_hgfe[SEND_MONO] = 0x0000ffff;
-+	
-+		/* stereo voice */
-+		/* left */
-+		card->waveout.send_dcba[SEND_LEFT] = 0x00ff00ff;
-+		card->waveout.send_hgfe[SEND_LEFT] = 0x00007f7f;	
-+		/* right */
-+		card->waveout.send_dcba[SEND_RIGHT] = 0xff00ff00;
-+		card->waveout.send_hgfe[SEND_RIGHT] = 0x00007f7f;
-+
-+		card->waveout.send_routing[ROUTE_PCM] = 0x03020100; // Regular pcm
-+		card->waveout.send_routing2[ROUTE_PCM] = 0x07060504;
-+
-+		card->waveout.send_routing[ROUTE_PT] = 0x3f3f3d3c; // Passthrough
-+		card->waveout.send_routing2[ROUTE_PT] = 0x3f3f3f3f;
-+		
-+		card->waveout.send_routing[ROUTE_PCM1] = 0x03020100; // Spare
-+		card->waveout.send_routing2[ROUTE_PCM1] = 0x07060404;
-+		
-+	} else {
-+		/* mono voice */
-+		card->waveout.send_dcba[SEND_MONO] = 0x0000ffff;
-+	
-+		/* stereo voice */
-+		/* left */
-+		card->waveout.send_dcba[SEND_LEFT] = 0x000000ff;
-+		/* right */
-+		card->waveout.send_dcba[SEND_RIGHT] = 0x0000ff00;
-+
-+		card->waveout.send_routing[ROUTE_PCM] = 0x3210; // pcm
-+		card->waveout.send_routing[ROUTE_PT] = 0x3210; // passthrough
-+		card->waveout.send_routing[ROUTE_PCM1] = 0x7654; // /dev/dsp1
-+	}
-+
-+	/* Assign default recording parameters */
-+	/* FIXME */
-+	if (card->is_aps)
-+		card->wavein.recsrc = WAVERECORD_FX;
-+	else
-+		card->wavein.recsrc = WAVERECORD_AC97;
-+
-+	card->wavein.fxwc = 0x0003;
-+	return 0;
-+}
-+
-+static void emu10k1_audio_cleanup(struct emu10k1_card *card)
-+{
-+}
-+
-+static int __devinit emu10k1_register_devices(struct emu10k1_card *card)
-+{
- 	card->audio_dev = register_sound_dsp(&emu10k1_audio_fops, -1);
- 	if (card->audio_dev < 0) {
- 		printk(KERN_ERR "emu10k1: cannot register first audio device!\n");
-@@ -173,56 +241,167 @@ static int __devinit emu10k1_audio_init(
- 		goto err_dev1;
- 	}
- 
--	/* Assign default playback voice parameters */
--	card->mchannel_fx = 8;
--	/* mono voice */
--	card->waveout.send_a[0] = 0xff;
--	card->waveout.send_b[0] = 0xff;
--	card->waveout.send_c[0] = 0x00;
--	card->waveout.send_d[0] = 0x00;
--	card->waveout.send_routing[0] = 0x3210;
--
--	/* stereo voice */
--	/* left */
--	card->waveout.send_a[1] = 0xff;
--	card->waveout.send_b[1] = 0x00;
--	card->waveout.send_c[1] = 0x00;
--	card->waveout.send_d[1] = 0x00;
--	card->waveout.send_routing[1] = 0x3210;
--
--	/* right */
--	card->waveout.send_a[2] = 0x00;
--	card->waveout.send_b[2] = 0xff;
--	card->waveout.send_c[2] = 0x00;
--	card->waveout.send_d[2] = 0x00;
--	card->waveout.send_routing[2] = 0x3210;
-+	card->ac97->dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
-+	if (card->ac97->dev_mixer < 0) {
-+		printk(KERN_ERR "emu10k1: cannot register mixer device\n");
-+		goto err_mixer;
-+        }
- 
--	/* Assign default recording parameters */
--	/* FIXME */
--	if (card->is_aps)
--		card->wavein.recsrc = WAVERECORD_FX;
--	else
--		card->wavein.recsrc = WAVERECORD_AC97;
-+	card->midi_dev = register_sound_midi(&emu10k1_midi_fops, -1);
-+	if (card->midi_dev < 0) {
-+                printk(KERN_ERR "emu10k1: cannot register midi device!\n");
-+		goto err_midi;
-+        }
- 
--	card->wavein.fxwc = 0x0003;
-+#ifdef EMU10K1_SEQUENCER
-+	card->seq_dev = sound_alloc_mididev();
-+	if (card->seq_dev == -1)
-+		printk(KERN_WARNING "emu10k1: unable to register sequencer device!");
-+	else {
-+		std_midi_synth.midi_dev = card->seq_dev;
-+		midi_devs[card->seq_dev] = 
-+			(struct midi_operations *)
-+			kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
-+
-+		if (midi_devs[card->seq_dev] == NULL) {
-+			printk(KERN_ERR "emu10k1: unable to allocate memory!");
-+			sound_unload_mididev(card->seq_dev);
-+			card->seq_dev = -1;
-+			/* return without error */
-+		} else {
-+			memcpy((char *)midi_devs[card->seq_dev], 
-+				(char *)&emu10k1_midi_operations, 
-+				sizeof(struct midi_operations));
-+			midi_devs[card->seq_dev]->devc = card;
-+			sequencer_init();
-+			card->seq_mididev = NULL;
-+		}
-+	}
-+#endif
- 	return 0;
- 
-+err_midi:
-+	unregister_sound_mixer(card->ac97->dev_mixer);
-+err_mixer:
-+	unregister_sound_dsp(card->audio_dev);
- err_dev1:
- 	unregister_sound_dsp(card->audio_dev);
- err_dev:
- 	return -ENODEV;
- }
- 
--static void __devinit emu10k1_audio_cleanup(struct emu10k1_card *card)
-+static void emu10k1_unregister_devices(struct emu10k1_card *card)
- {
-+#ifdef EMU10K1_SEQUENCER
-+	if (card->seq_dev > -1) {
-+		kfree(midi_devs[card->seq_dev]);
-+		midi_devs[card->seq_dev] = NULL;
-+		sound_unload_mididev(card->seq_dev);
-+		card->seq_dev = -1;
-+	}
-+#endif
-+
-+	unregister_sound_midi(card->midi_dev);
-+	unregister_sound_mixer(card->ac97->dev_mixer);
- 	unregister_sound_dsp(card->audio_dev1);
- 	unregister_sound_dsp(card->audio_dev);
- }
- 
--static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
-+int emu10k1_info_proc (char *page, char **start, off_t off,
-+		    int count, int *eof, void *data)
-+{
-+	struct emu10k1_card *card = data;
-+	int len = 0;
-+	
-+	if (card == NULL)
-+		return -ENODEV;
-+
-+	len += sprintf (page + len, "Driver Version : %s\n", DRIVER_VERSION);
-+	len += sprintf (page + len, "Card type      : %s\n", card->is_aps ? "Aps" : (card->is_audigy ? "Audigy" : "Emu10k1"));
-+	len += sprintf (page + len, "Revision       : %d\n", card->chiprev);
-+	len += sprintf (page + len, "Model          : %#06x\n", card->model);
-+	len += sprintf (page + len, "IO             : %#06lx-%#06lx\n", card->iobase, card->iobase + card->length - 1);
-+	len += sprintf (page + len, "IRQ            : %d\n\n", card->irq);
-+	
-+	len += sprintf (page + len, "Registered /dev Entries:\n");
-+	len += sprintf (page + len, "/dev/dsp%d\n", card->audio_dev / 16);
-+	len += sprintf (page + len, "/dev/dsp%d\n", card->audio_dev1 / 16);
-+	len += sprintf (page + len, "/dev/mixer%d\n", card->ac97->dev_mixer / 16);
-+	len += sprintf (page + len, "/dev/midi%d\n", card->midi_dev / 16);
-+
-+#ifdef EMU10K1_SEQUENCER
-+	len += sprintf (page + len, "/dev/sequencer\n");
-+#endif
-+
-+	return len;
-+}
-+
-+static int __devinit emu10k1_proc_init(struct emu10k1_card *card)
-+{
-+	char s[48];
-+
-+	if (!proc_mkdir ("driver/emu10k1", 0)) {
-+		printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");
-+		goto err_out;
-+	}
-+
-+	sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
-+	if (!proc_mkdir (s, 0)) {
-+		printk(KERN_ERR "emu10k1: unable to create proc directory %s\n", s);
-+		goto err_emu10k1_proc;
-+	}
-+
-+	sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name);
-+	if (!create_proc_read_entry (s, 0, 0, emu10k1_info_proc, card)) {
-+		printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
-+		goto err_dev_proc;
-+	}
-+
-+	if (!card->is_aps) {
-+		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
-+		if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
-+			printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
-+			goto err_proc_ac97;
-+		}
-+	}
-+
-+	return 0;
-+
-+err_proc_ac97:
-+	sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name);
-+	remove_proc_entry(s, NULL);
-+
-+err_dev_proc:
-+	sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
-+	remove_proc_entry(s, NULL);
-+
-+err_emu10k1_proc:
-+	remove_proc_entry("driver/emu10k1", NULL);
-+
-+err_out:
-+	return -EIO;
-+}
-+
-+static void emu10k1_proc_cleanup(struct emu10k1_card *card)
- {
--	char s[32];
-+	char s[48];
- 
-+	if (!card->is_aps) {
-+		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
-+		remove_proc_entry(s, NULL);
-+	}
-+
-+	sprintf(s, "driver/emu10k1/%s/info", card->pci_dev->slot_name);
-+	remove_proc_entry(s, NULL);
-+
-+	sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
-+	remove_proc_entry(s, NULL);
-+		
-+	remove_proc_entry("driver/emu10k1", NULL);
-+}
-+
-+static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
-+{
- 	struct ac97_codec *codec  = ac97_alloc_codec();
- 	
- 	if(codec == NULL)
-@@ -231,15 +410,6 @@ static int __devinit emu10k1_mixer_init(
- 		return -EIO;
- 	}
- 	card->ac97 = codec;
--	
--#warning "Initialisation order race. Must register after usable"
--
--	card->ac97->dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
--	if (card->ac97->dev_mixer < 0) {
--		printk(KERN_ERR "emu10k1: cannot register mixer device\n");
--		goto err_codec;
--        }
--
- 	card->ac97->private_data = card;
- 
- 	if (!card->is_aps) {
-@@ -261,23 +431,6 @@ static int __devinit emu10k1_mixer_init(
- 		// Force 5bit:		    
- 		//card->ac97->bit_resolution=5;
- 
--		if (!proc_mkdir ("driver/emu10k1", 0)) {
--			printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");
--			goto err_out;
--		}
--
--		sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
--		if (!proc_mkdir (s, 0)) {
--			printk(KERN_ERR "emu10k1: unable to create proc directory %s\n", s);
--			goto err_emu10k1_proc;
--		}
--	
--		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
--		if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
--			printk(KERN_ERR "emu10k1: unable to create proc entry %s\n", s);
--			goto err_ac97_proc;
--		}
--
- 		/* these will store the original values and never be modified */
- 		card->ac97_supported_mixers = card->ac97->supported_mixers;
- 		card->ac97_stereo_mixers = card->ac97->stereo_mixers;
-@@ -285,34 +438,13 @@ static int __devinit emu10k1_mixer_init(
- 
- 	return 0;
- 
-- err_ac97_proc:
--	sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
--	remove_proc_entry(s, NULL);
--
-- err_emu10k1_proc:
--	remove_proc_entry("driver/emu10k1", NULL);
-  err_out:
--	unregister_sound_mixer (card->ac97->dev_mixer);
-- err_codec:
-  	ac97_release_codec(card->ac97);
- 	return -EIO;
- }
- 
--static void __devinit emu10k1_mixer_cleanup(struct emu10k1_card *card)
-+static void emu10k1_mixer_cleanup(struct emu10k1_card *card)
- {
--	char s[32];
--
--	if (!card->is_aps) {
--		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
--		remove_proc_entry(s, NULL);
--
--		sprintf(s, "driver/emu10k1/%s", card->pci_dev->slot_name);
--		remove_proc_entry(s, NULL);
--
--		remove_proc_entry("driver/emu10k1", NULL);
--	}
--
--	unregister_sound_mixer (card->ac97->dev_mixer);
- 	ac97_release_codec(card->ac97);
- }
- 
-@@ -320,13 +452,6 @@ static int __devinit emu10k1_midi_init(s
- {
- 	int ret;
- 
--	card->midi_dev = register_sound_midi(&emu10k1_midi_fops, -1);
--	if (card->midi_dev < 0) {
--                printk(KERN_ERR "emu10k1: cannot register midi device!\n");
--		return -ENODEV;
--        }
--
--
- 	card->mpuout = kmalloc(sizeof(struct emu10k1_mpuout), GFP_KERNEL);
- 	if (card->mpuout == NULL) {
- 		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuout: out of memory\n");
-@@ -366,31 +491,6 @@ static int __devinit emu10k1_midi_init(s
- 		goto err_out3;
- 	}
- 
--#ifdef EMU10K1_SEQUENCER
--	card->seq_dev = sound_alloc_mididev();
--	if (card->seq_dev == -1)
--			printk(KERN_WARNING "emu10k1: unable to register sequencer device!");
--	else {
--			std_midi_synth.midi_dev = card->seq_dev;
--			midi_devs[card->seq_dev] = 
--					(struct midi_operations *)
--					kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
--			
--			if (midi_devs[card->seq_dev] == NULL) {
--				printk(KERN_ERR "emu10k1: unable to allocate memory!");
--				sound_unload_mididev(card->seq_dev);
--				card->seq_dev = -1;
--				return 0;
--			} else {
--				memcpy((char *)midi_devs[card->seq_dev], 
--					(char *)&emu10k1_midi_operations, 
--					sizeof(struct midi_operations));
--				midi_devs[card->seq_dev]->devc = card;
--				sequencer_init();
--			}
--	}
--	card->seq_mididev = 0;
--#endif
- 	return 0;
- 
- err_out3:
-@@ -398,28 +498,16 @@ err_out3:
- err_out2:
- 	kfree(card->mpuout);
- err_out1:
--	unregister_sound_midi(card->midi_dev);
- 	return ret;
- }
- 
--static void __devinit emu10k1_midi_cleanup(struct emu10k1_card *card)
-+static void emu10k1_midi_cleanup(struct emu10k1_card *card)
- {
- 	tasklet_kill(&card->mpuout->tasklet);
- 	kfree(card->mpuout);
- 
- 	tasklet_kill(&card->mpuin->tasklet);
- 	kfree(card->mpuin);
--
--#ifdef EMU10K1_SEQUENCER
--	if (card->seq_dev > -1) {
--		kfree(midi_devs[card->seq_dev]);
--		midi_devs[card->seq_dev] = NULL;
--		sound_unload_mididev(card->seq_dev);
--		card->seq_dev = -1;
--	}
--#endif
--
--	unregister_sound_midi(card->midi_dev);
- }
- 
- static void __devinit voice_init(struct emu10k1_card *card)
-@@ -450,7 +538,7 @@ static void __devinit addxmgr_init(struc
- 	card->emupagetable[1] = MAXPAGES - 1;
- }
- 
--static void __devinit fx_cleanup(struct patch_manager *mgr)
-+static void fx_cleanup(struct patch_manager *mgr)
- {
- 	int i;
- 	for(i = 0; i < mgr->current_pages; i++)
-@@ -465,24 +553,25 @@ static int __devinit fx_init(struct emu1
- 	s32 left, right;
- 	int i;
- 	u32 pc = 0;
--	u32 patch_n;
-+	u32 patch_n=0;
-+	struct emu_efx_info_t emu_efx_info[2]=
-+		{{ 20, 10, 0x400, 0x100, 0x20 },
-+		 { 24, 12, 0x600, 0x400, 0x60 },
-+		}; 
-+			
- 
- 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
- 		mgr->ctrl_gpr[i][0] = -1;
- 		mgr->ctrl_gpr[i][1] = -1;
- 	}
- 
--	for (i = 0; i < 512; i++)
--		OP(6, 0x40, 0x40, 0x40, 0x40);
--
--	for (i = 0; i < 256; i++)
--		sblive_writeptr_tag(card, 0,
--				    FXGPREGBASE + i, 0,
--				    TANKMEMADDRREGBASE + i, 0,
--				    TAGLIST_END);
- 
--	/* !! The number bellow must equal the number of patches, currently 11 !! */
--	mgr->current_pages = (11 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
-+	if (card->is_audigy)
-+		mgr->current_pages = (2 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
-+	else
-+		/* !! The number below must equal the number of patches, currently 11 !! */
-+		mgr->current_pages = (11 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
-+	
- 	for (i = 0; i < mgr->current_pages; i++) {
- 		mgr->patch[i] = (void *)__get_free_page(GFP_KERNEL);
- 		if (mgr->patch[i] == NULL) {
-@@ -493,215 +582,298 @@ static int __devinit fx_init(struct emu1
- 		memset(mgr->patch[i], 0, PAGE_SIZE);
- 	}
- 
--	pc = 0;
--	patch_n = 0;
--	//first free GPR = 0x11b
--
--	/* FX volume correction and Volume control*/
--	INPUT_PATCH_START(patch, "Pcm L vol", 0x0, 0);
--	GET_OUTPUT_GPR(patch, 0x100, 0x0);
--	GET_CONTROL_GPR(patch, 0x106, "Vol", 0, 0x7fffffff);
--	GET_DYNAMIC_GPR(patch, 0x112);
--
--	OP(4, 0x112, 0x40, PCM_IN_L, 0x44); //*4
--	OP(0, 0x100, 0x040, 0x112, 0x106);  //*vol
--	INPUT_PATCH_END(patch);
--
--
--	INPUT_PATCH_START(patch, "Pcm R vol", 0x1, 0);
--	GET_OUTPUT_GPR(patch, 0x101, 0x1);
--	GET_CONTROL_GPR(patch, 0x107, "Vol", 0, 0x7fffffff);
--	GET_DYNAMIC_GPR(patch, 0x112);
--
--	OP(4, 0x112, 0x40, PCM_IN_R, 0x44); 
--	OP(0, 0x101, 0x040, 0x112, 0x107);
--
--	INPUT_PATCH_END(patch);
--
--
--	// CD-Digital In Volume control
--	INPUT_PATCH_START(patch, "CD-Digital Vol L", 0x12, 0);
--	GET_OUTPUT_GPR(patch, 0x10c, 0x12);
--	GET_CONTROL_GPR(patch, 0x10d, "Vol", 0, 0x7fffffff);
--
--	OP(0, 0x10c, 0x040, SPDIF_CD_L, 0x10d);
--	INPUT_PATCH_END(patch);
--
--	INPUT_PATCH_START(patch, "CD-Digital Vol R", 0x13, 0);
--	GET_OUTPUT_GPR(patch, 0x10e, 0x13);
--	GET_CONTROL_GPR(patch, 0x10f, "Vol", 0, 0x7fffffff);
--
--	OP(0, 0x10e, 0x040, SPDIF_CD_R, 0x10f);
--	INPUT_PATCH_END(patch);
--
--	//Volume Correction for Multi-channel Inputs
--	INPUT_PATCH_START(patch, "Multi-Channel Gain", 0x08, 0);
--	patch->input=patch->output=0x3F00;
--
--	GET_OUTPUT_GPR(patch, 0x113, MULTI_FRONT_L);
--	GET_OUTPUT_GPR(patch, 0x114, MULTI_FRONT_R);
--	GET_OUTPUT_GPR(patch, 0x115, MULTI_REAR_L);
--	GET_OUTPUT_GPR(patch, 0x116, MULTI_REAR_R);
--	GET_OUTPUT_GPR(patch, 0x117, MULTI_CENTER);
--	GET_OUTPUT_GPR(patch, 0x118, MULTI_LFE);
--
--	OP(4, 0x113, 0x40, MULTI_FRONT_L, 0x44);
--	OP(4, 0x114, 0x40, MULTI_FRONT_R, 0x44);
--	OP(4, 0x115, 0x40, MULTI_REAR_L, 0x44);
--	OP(4, 0x116, 0x40, MULTI_REAR_R, 0x44);
--	OP(4, 0x117, 0x40, MULTI_CENTER, 0x44);
--	OP(4, 0x118, 0x40, MULTI_LFE, 0x44);
--	
--	INPUT_PATCH_END(patch);
--
--
--	//Routing patch start
--	ROUTING_PATCH_START(rpatch, "Routing");
--	GET_INPUT_GPR(rpatch, 0x100, 0x0);
--	GET_INPUT_GPR(rpatch, 0x101, 0x1);
--	GET_INPUT_GPR(rpatch, 0x10c, 0x12);
--	GET_INPUT_GPR(rpatch, 0x10e, 0x13);
--	GET_INPUT_GPR(rpatch, 0x113, MULTI_FRONT_L);
--	GET_INPUT_GPR(rpatch, 0x114, MULTI_FRONT_R);
--	GET_INPUT_GPR(rpatch, 0x115, MULTI_REAR_L);
--	GET_INPUT_GPR(rpatch, 0x116, MULTI_REAR_R);
--	GET_INPUT_GPR(rpatch, 0x117, MULTI_CENTER);
--	GET_INPUT_GPR(rpatch, 0x118, MULTI_LFE);
--
--	GET_DYNAMIC_GPR(rpatch, 0x102);
--	GET_DYNAMIC_GPR(rpatch, 0x103);
--
--	GET_OUTPUT_GPR(rpatch, 0x104, 0x8);
--	GET_OUTPUT_GPR(rpatch, 0x105, 0x9);
--	GET_OUTPUT_GPR(rpatch, 0x10a, 0x2);
--	GET_OUTPUT_GPR(rpatch, 0x10b, 0x3);
--
--
--	/* input buffer */
--	OP(6, 0x102, AC97_IN_L, 0x40, 0x40);
--	OP(6, 0x103, AC97_IN_R, 0x40, 0x40);
--
--
--	/* Digital In + PCM + MULTI_FRONT-> AC97 out (front speakers)*/
--	OP(6, AC97_FRONT_L, 0x100, 0x10c, 0x113);
--
--	CONNECT(MULTI_FRONT_L, AC97_FRONT_L);
--	CONNECT(PCM_IN_L, AC97_FRONT_L);
--	CONNECT(SPDIF_CD_L, AC97_FRONT_L);
--
--	OP(6, AC97_FRONT_R, 0x101, 0x10e, 0x114);
--
--	CONNECT(MULTI_FRONT_R, AC97_FRONT_R);
--	CONNECT(PCM_IN_R, AC97_FRONT_R);
--	CONNECT(SPDIF_CD_R, AC97_FRONT_R);
--
--	/* Digital In + PCM + AC97 In + PCM1 + MULTI_REAR --> Rear Channel */ 
--	OP(6, 0x104, PCM1_IN_L, 0x100, 0x115);
--	OP(6, 0x104, 0x104, 0x10c, 0x102);
--
--	CONNECT(MULTI_REAR_L, ANALOG_REAR_L);
--	CONNECT(AC97_IN_L, ANALOG_REAR_L);
--	CONNECT(PCM_IN_L, ANALOG_REAR_L);
--	CONNECT(SPDIF_CD_L, ANALOG_REAR_L);
--	CONNECT(PCM1_IN_L, ANALOG_REAR_L);
--
--	OP(6, 0x105, PCM1_IN_R, 0x101, 0x116);
--	OP(6, 0x105, 0x105, 0x10e, 0x103);
--
--	CONNECT(MULTI_REAR_R, ANALOG_REAR_R);
--	CONNECT(AC97_IN_R, ANALOG_REAR_R);
--	CONNECT(PCM_IN_R, ANALOG_REAR_R);
--	CONNECT(SPDIF_CD_R, ANALOG_REAR_R);
--	CONNECT(PCM1_IN_R, ANALOG_REAR_R);
--
--	/* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
--	OP(6, 0x10a, 0x100, 0x102, 0x10c);
--	OP(6, 0x10a, 0x10a, 0x113, 0x40);
--
--	CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L);
--	CONNECT(PCM_IN_L, DIGITAL_OUT_L);
--	CONNECT(AC97_IN_L, DIGITAL_OUT_L);
--	CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
--
--	OP(6, 0x10b, 0x101, 0x103, 0x10e);
--	OP(6, 0x10b, 0x10b, 0x114, 0x40);
--
--	CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R);
--	CONNECT(PCM_IN_R, DIGITAL_OUT_R);
--	CONNECT(AC97_IN_R, DIGITAL_OUT_R);
--	CONNECT(SPDIF_CD_R, DIGITAL_OUT_R);
--
--	/* AC97 In --> ADC Recording Buffer */
--	OP(6, ADC_REC_L, 0x102, 0x40, 0x40);
--
--	CONNECT(AC97_IN_L, ADC_REC_L);
--
--	OP(6, ADC_REC_R, 0x103, 0x40, 0x40);
--
--	CONNECT(AC97_IN_R, ADC_REC_R);
-+	if (card->is_audigy) {
-+		for (i = 0; i < 1024; i++)
-+			OP(0xf, 0x0c0, 0x0c0, 0x0cf, 0x0c0);
-+
-+		for (i = 0; i < 512 ; i++)
-+			sblive_writeptr(card, A_GPR_BASE+i,0,0);
-+
-+		pc=0;
-+
-+		//Pcm input volume
-+		OP(0, 0x402, 0x0c0, 0x406, 0x000);
-+		OP(0, 0x403, 0x0c0, 0x407, 0x001);
-+
-+		//CD-Digital input Volume
-+		OP(0, 0x404, 0x0c0, 0x40d, 0x42);
-+		OP(0, 0x405, 0x0c0, 0x40f, 0x43);
-+
-+		// CD + PCM 
-+		OP(6, 0x400, 0x0c0, 0x402, 0x404);
-+		OP(6, 0x401, 0x0c0, 0x403, 0x405);
-+		
-+		// Front Output + Master Volume
-+		OP(0, 0x68, 0x0c0, 0x408, 0x400);
-+		OP(0, 0x69, 0x0c0, 0x409, 0x401);
-+
-+		// Add-in analog inputs for other speakers
-+		OP(6, 0x400, 0x40, 0x400, 0xc0);
-+		OP(6, 0x401, 0x41, 0x401, 0xc0);
-+
-+		// Digital Front + Master Volume
-+		OP(0, 0x60, 0x0c0, 0x408, 0x400);
-+		OP(0, 0x61, 0x0c0, 0x409, 0x401);
-+
-+		// Rear Output + Rear Volume
-+		OP(0, 0x06e, 0x0c0, 0x419, 0x400);
-+		OP(0, 0x06f, 0x0c0, 0x41a, 0x401);		
-+
-+		// Digital Rear Output + Rear Volume
-+		OP(0, 0x066, 0x0c0, 0x419, 0x400);
-+		OP(0, 0x067, 0x0c0, 0x41a, 0x401);		
-+
-+		// Audigy Drive, Headphone out
-+		OP(6, 0x64, 0x0c0, 0x0c0, 0x400);
-+		OP(6, 0x65, 0x0c0, 0x0c0, 0x401);
-+
-+		// ac97 Recording
-+		OP(6, 0x76, 0x0c0, 0x0c0, 0x40);
-+		OP(6, 0x77, 0x0c0, 0x0c0, 0x41);
-+		
-+		// Center = sub = Left/2 + Right/2
-+		OP(0xe, 0x400, 0x401, 0xcd, 0x400);
-+
-+		// center/sub  Volume (master)
-+		OP(0, 0x06a, 0x0c0, 0x408, 0x400);
-+		OP(0, 0x06b, 0x0c0, 0x409, 0x400);
-+
-+		// Digital center/sub  Volume (master)
-+		OP(0, 0x062, 0x0c0, 0x408, 0x400);
-+		OP(0, 0x063, 0x0c0, 0x409, 0x400);
-+
-+		ROUTING_PATCH_START(rpatch, "Routing");
-+		ROUTING_PATCH_END(rpatch);
-+
-+		/* delimiter patch */
-+		patch = PATCH(mgr, patch_n);
-+		patch->code_size = 0;
- 
-+	
-+		sblive_writeptr(card, 0x53, 0, 0);
-+	} else {
-+		for (i = 0; i < 512 ; i++)
-+			OP(6, 0x40, 0x40, 0x40, 0x40);
-+
-+		for (i = 0; i < 256; i++)
-+			sblive_writeptr_tag(card, 0,
-+					    FXGPREGBASE + i, 0,
-+					    TANKMEMADDRREGBASE + i, 0,
-+					    TAGLIST_END);
- 
--	/* fx12:Analog-Center */
--	OP(6, ANALOG_CENTER, 0x117, 0x40, 0x40);
--	CONNECT(MULTI_CENTER, ANALOG_CENTER);
-+		
-+		pc = 0;
- 
--	/* fx11:Analog-LFE */
--	OP(6, ANALOG_LFE, 0x118, 0x40, 0x40);
--	CONNECT(MULTI_LFE, ANALOG_LFE);
-+		//first free GPR = 0x11b
-+	
-+		
-+		/* FX volume correction and Volume control*/
-+		INPUT_PATCH_START(patch, "Pcm L vol", 0x0, 0);
-+		GET_OUTPUT_GPR(patch, 0x100, 0x0);
-+		GET_CONTROL_GPR(patch, 0x106, "Vol", 0, 0x7fffffff);
-+		GET_DYNAMIC_GPR(patch, 0x112);
-+
-+		OP(4, 0x112, 0x40, PCM_IN_L, 0x44); //*4	
-+		OP(0, 0x100, 0x040, 0x112, 0x106);  //*vol	
-+		INPUT_PATCH_END(patch);
-+
-+
-+		INPUT_PATCH_START(patch, "Pcm R vol", 0x1, 0);
-+		GET_OUTPUT_GPR(patch, 0x101, 0x1);
-+		GET_CONTROL_GPR(patch, 0x107, "Vol", 0, 0x7fffffff);
-+		GET_DYNAMIC_GPR(patch, 0x112);
-+
-+		OP(4, 0x112, 0x40, PCM_IN_R, 0x44); 
-+		OP(0, 0x101, 0x040, 0x112, 0x107);
-+
-+		INPUT_PATCH_END(patch);
-+
-+
-+		// CD-Digital In Volume control	
-+		INPUT_PATCH_START(patch, "CD-Digital Vol L", 0x12, 0);
-+		GET_OUTPUT_GPR(patch, 0x10c, 0x12);
-+		GET_CONTROL_GPR(patch, 0x10d, "Vol", 0, 0x7fffffff);
-+
-+		OP(0, 0x10c, 0x040, SPDIF_CD_L, 0x10d);
-+		INPUT_PATCH_END(patch);
-+
-+		INPUT_PATCH_START(patch, "CD-Digital Vol R", 0x13, 0);
-+		GET_OUTPUT_GPR(patch, 0x10e, 0x13);
-+		GET_CONTROL_GPR(patch, 0x10f, "Vol", 0, 0x7fffffff);
-+
-+		OP(0, 0x10e, 0x040, SPDIF_CD_R, 0x10f);
-+		INPUT_PATCH_END(patch);
-+
-+		//Volume Correction for Multi-channel Inputs	
-+		INPUT_PATCH_START(patch, "Multi-Channel Gain", 0x08, 0);
-+		patch->input=patch->output=0x3F00;
-+
-+		GET_OUTPUT_GPR(patch, 0x113, MULTI_FRONT_L);
-+		GET_OUTPUT_GPR(patch, 0x114, MULTI_FRONT_R);
-+		GET_OUTPUT_GPR(patch, 0x115, MULTI_REAR_L);
-+		GET_OUTPUT_GPR(patch, 0x116, MULTI_REAR_R);
-+		GET_OUTPUT_GPR(patch, 0x117, MULTI_CENTER);
-+		GET_OUTPUT_GPR(patch, 0x118, MULTI_LFE);
-+
-+		OP(4, 0x113, 0x40, MULTI_FRONT_L, 0x44);
-+		OP(4, 0x114, 0x40, MULTI_FRONT_R, 0x44);
-+		OP(4, 0x115, 0x40, MULTI_REAR_L, 0x44);
-+		OP(4, 0x116, 0x40, MULTI_REAR_R, 0x44);
-+		OP(4, 0x117, 0x40, MULTI_CENTER, 0x44);
-+		OP(4, 0x118, 0x40, MULTI_LFE, 0x44);
-+	
-+		INPUT_PATCH_END(patch);
- 
--	/* fx12:Digital-Center */
--	OP(6, DIGITAL_CENTER, 0x117, 0x40, 0x40);
--	CONNECT(MULTI_CENTER, DIGITAL_CENTER);
- 
--	/* fx11:Analog-LFE */
--	OP(6, DIGITAL_LFE, 0x118, 0x40, 0x40);
--	CONNECT(MULTI_LFE, DIGITAL_LFE);
-+		//Routing patch start	
-+		ROUTING_PATCH_START(rpatch, "Routing");
-+		GET_INPUT_GPR(rpatch, 0x100, 0x0);
-+		GET_INPUT_GPR(rpatch, 0x101, 0x1);
-+		GET_INPUT_GPR(rpatch, 0x10c, 0x12);
-+		GET_INPUT_GPR(rpatch, 0x10e, 0x13);
-+		GET_INPUT_GPR(rpatch, 0x113, MULTI_FRONT_L);
-+		GET_INPUT_GPR(rpatch, 0x114, MULTI_FRONT_R);
-+		GET_INPUT_GPR(rpatch, 0x115, MULTI_REAR_L);
-+		GET_INPUT_GPR(rpatch, 0x116, MULTI_REAR_R);
-+		GET_INPUT_GPR(rpatch, 0x117, MULTI_CENTER);
-+		GET_INPUT_GPR(rpatch, 0x118, MULTI_LFE);
-+
-+		GET_DYNAMIC_GPR(rpatch, 0x102);
-+		GET_DYNAMIC_GPR(rpatch, 0x103);
-+
-+		GET_OUTPUT_GPR(rpatch, 0x104, 0x8);
-+		GET_OUTPUT_GPR(rpatch, 0x105, 0x9);
-+		GET_OUTPUT_GPR(rpatch, 0x10a, 0x2);
-+		GET_OUTPUT_GPR(rpatch, 0x10b, 0x3);
-+		
-+		
-+		/* input buffer */
-+		OP(6, 0x102, AC97_IN_L, 0x40, 0x40);
-+		OP(6, 0x103, AC97_IN_R, 0x40, 0x40);
-+
-+
-+		/* Digital In + PCM + MULTI_FRONT-> AC97 out (front speakers)*/
-+		OP(6, AC97_FRONT_L, 0x100, 0x10c, 0x113);
-+
-+		CONNECT(MULTI_FRONT_L, AC97_FRONT_L);
-+		CONNECT(PCM_IN_L, AC97_FRONT_L);
-+		CONNECT(SPDIF_CD_L, AC97_FRONT_L);
-+
-+		OP(6, AC97_FRONT_R, 0x101, 0x10e, 0x114);
-+
-+		CONNECT(MULTI_FRONT_R, AC97_FRONT_R);
-+		CONNECT(PCM_IN_R, AC97_FRONT_R);
-+		CONNECT(SPDIF_CD_R, AC97_FRONT_R);
-+
-+		/* Digital In + PCM + AC97 In + PCM1 + MULTI_REAR --> Rear Channel */ 
-+		OP(6, 0x104, PCM1_IN_L, 0x100, 0x115);
-+		OP(6, 0x104, 0x104, 0x10c, 0x102);
-+
-+		CONNECT(MULTI_REAR_L, ANALOG_REAR_L);
-+		CONNECT(AC97_IN_L, ANALOG_REAR_L);
-+		CONNECT(PCM_IN_L, ANALOG_REAR_L);
-+		CONNECT(SPDIF_CD_L, ANALOG_REAR_L);
-+		CONNECT(PCM1_IN_L, ANALOG_REAR_L);
-+
-+		OP(6, 0x105, PCM1_IN_R, 0x101, 0x116);
-+		OP(6, 0x105, 0x105, 0x10e, 0x103);
-+
-+		CONNECT(MULTI_REAR_R, ANALOG_REAR_R);
-+		CONNECT(AC97_IN_R, ANALOG_REAR_R);
-+		CONNECT(PCM_IN_R, ANALOG_REAR_R);
-+		CONNECT(SPDIF_CD_R, ANALOG_REAR_R);
-+		CONNECT(PCM1_IN_R, ANALOG_REAR_R);
-+
-+		/* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
-+		OP(6, 0x10b, 0x100, 0x102, 0x10c);
-+		OP(6, 0x10b, 0x10b, 0x113, 0x40);
-+
-+		CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L);
-+		CONNECT(PCM_IN_L, DIGITAL_OUT_L);
-+		CONNECT(AC97_IN_L, DIGITAL_OUT_L);
-+		CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
-+
-+		OP(6, 0x10a, 0x101, 0x103, 0x10e);
-+		OP(6, 0x10b, 0x10b, 0x114, 0x40);
-+
-+		CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R);
-+		CONNECT(PCM_IN_R, DIGITAL_OUT_R);
-+		CONNECT(AC97_IN_R, DIGITAL_OUT_R);
-+		CONNECT(SPDIF_CD_R, DIGITAL_OUT_R);
-+
-+		/* AC97 In --> ADC Recording Buffer */
-+		OP(6, ADC_REC_L, 0x102, 0x40, 0x40);
-+
-+		CONNECT(AC97_IN_L, ADC_REC_L);
-+
-+		OP(6, ADC_REC_R, 0x103, 0x40, 0x40);
-+
-+		CONNECT(AC97_IN_R, ADC_REC_R);
-+
-+
-+		/* fx12:Analog-Center */
-+		OP(6, ANALOG_CENTER, 0x117, 0x40, 0x40);
-+		CONNECT(MULTI_CENTER, ANALOG_CENTER);
-+
-+		/* fx11:Analog-LFE */
-+		OP(6, ANALOG_LFE, 0x118, 0x40, 0x40);
-+		CONNECT(MULTI_LFE, ANALOG_LFE);
-+
-+		/* fx12:Digital-Center */
-+		OP(6, DIGITAL_CENTER, 0x117, 0x40, 0x40);
-+		CONNECT(MULTI_CENTER, DIGITAL_CENTER);
-+		
-+		/* fx11:Analog-LFE */
-+		OP(6, DIGITAL_LFE, 0x118, 0x40, 0x40);
-+		CONNECT(MULTI_LFE, DIGITAL_LFE);
- 	
--	ROUTING_PATCH_END(rpatch);
-+		ROUTING_PATCH_END(rpatch);
- 
- 
--	// Rear volume control
--	OUTPUT_PATCH_START(patch, "Vol Rear L", 0x8, 0);
--	GET_INPUT_GPR(patch, 0x104, 0x8);
--	GET_CONTROL_GPR(patch, 0x119, "Vol", 0, 0x7fffffff);
-+		// Rear volume control	
-+		OUTPUT_PATCH_START(patch, "Vol Rear L", 0x8, 0);
-+		GET_INPUT_GPR(patch, 0x104, 0x8);
-+		GET_CONTROL_GPR(patch, 0x119, "Vol", 0, 0x7fffffff);
- 
--	OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x119);
--	OUTPUT_PATCH_END(patch);
-+		OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x119);
-+		OUTPUT_PATCH_END(patch);
- 
-+		OUTPUT_PATCH_START(patch, "Vol Rear R", 0x9, 0);
-+		GET_INPUT_GPR(patch, 0x105, 0x9);
-+		GET_CONTROL_GPR(patch, 0x11a, "Vol", 0, 0x7fffffff);
- 
--	OUTPUT_PATCH_START(patch, "Vol Rear R", 0x9, 0);
--	GET_INPUT_GPR(patch, 0x105, 0x9);
--	GET_CONTROL_GPR(patch, 0x11a, "Vol", 0, 0x7fffffff);
-+		OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x11a);
-+		OUTPUT_PATCH_END(patch);
- 
--	OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x11a);
--	OUTPUT_PATCH_END(patch);
- 
-+		//Master volume control on front-digital	
-+		OUTPUT_PATCH_START(patch, "Vol Master L", 0x2, 1);
-+		GET_INPUT_GPR(patch, 0x10a, 0x2);
-+		GET_CONTROL_GPR(patch, 0x108, "Vol", 0, 0x7fffffff);
- 
--	//Master volume control on front-digital
--	OUTPUT_PATCH_START(patch, "Vol Master L", 0x2, 1);
--	GET_INPUT_GPR(patch, 0x10a, 0x2);
--	GET_CONTROL_GPR(patch, 0x108, "Vol", 0, 0x7fffffff);
-+		OP(0, DIGITAL_OUT_L, 0x040, 0x10a, 0x108);
-+		OUTPUT_PATCH_END(patch);
- 
--	OP(0, DIGITAL_OUT_L, 0x040, 0x10a, 0x108);
--	OUTPUT_PATCH_END(patch);
- 
-+		OUTPUT_PATCH_START(patch, "Vol Master R", 0x3, 1);
-+		GET_INPUT_GPR(patch, 0x10b, 0x3);
-+		GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff);
- 
--	OUTPUT_PATCH_START(patch, "Vol Master R", 0x3, 1);
--	GET_INPUT_GPR(patch, 0x10b, 0x3);
--	GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff);
-+		OP(0, DIGITAL_OUT_R, 0x040, 0x10b, 0x109);
-+		OUTPUT_PATCH_END(patch);
- 
--	OP(0, DIGITAL_OUT_R, 0x040, 0x10b, 0x109);
--	OUTPUT_PATCH_END(patch);
- 
-+		/* delimiter patch */
-+		patch = PATCH(mgr, patch_n);
-+		patch->code_size = 0;
- 
--	/* delimiter patch */
--	patch = PATCH(mgr, patch_n);
--	patch->code_size = 0;
--
--	sblive_writeptr(card, DBG, 0, 0);
-+	
-+		sblive_writeptr(card, DBG, 0, 0);
-+	}
- 
- 	mgr->lock = SPIN_LOCK_UNLOCKED;
- 
-+	// Set up Volume controls, try to keep this the same for both Audigy and Live
- 
- 	//Master volume
- 	mgr->ctrl_gpr[SOUND_MIXER_VOLUME][0] = 8;
-@@ -749,8 +921,16 @@ static int __devinit fx_init(struct emu1
- 	emu10k1_set_volume_gpr(card, 0xd, left, VOL_5BIT);
- 	emu10k1_set_volume_gpr(card, 0xf, right, VOL_5BIT);
- 
--	//hard wire the ac97's pcm, we'll do that in dsp code instead.
--	emu10k1_ac97_write(card->ac97, 0x18, 0x0);
-+
-+	//hard wire the ac97's pcm, pcm volume is done above using dsp code.
-+	if (card->is_audigy)
-+		//for Audigy, we mute it and use the philips 6 channel DAC instead
-+		emu10k1_ac97_write(card->ac97, 0x18, 0x8000);
-+	else
-+		//For the Live we hardwire it to full volume
-+		emu10k1_ac97_write(card->ac97, 0x18, 0x0);
-+
-+	//remove it from the ac97_codec's control
- 	card->ac97_supported_mixers &= ~SOUND_MASK_PCM;
- 	card->ac97_stereo_mixers &= ~SOUND_MASK_PCM;
- 
-@@ -789,6 +969,13 @@ static int __devinit hw_init(struct emu1
- 			    SOLEH, 0,
- 			    TAGLIST_END);
- 
-+	if (card->is_audigy) {
-+		sblive_writeptr_tag(card,0,
-+				    0x5e,0xf00,
-+				    0x5f,0x3,
-+				    TAGLIST_END);
-+	}
-+
- 	/* Init envelope engine */
- 	for (nCh = 0; nCh < NUM_G; nCh++) {
- 		sblive_writeptr_tag(card, nCh,
-@@ -824,6 +1011,21 @@ static int __devinit hw_init(struct emu1
- 				    ENVVAL, 0,
-                                     TAGLIST_END);
- 		sblive_writeptr(card, CPF, nCh, 0);
-+		/*
-+		  Audigy FXRT initialization
-+		  reversed eng'd, may not be accurate.
-+		 */
-+		if (card->is_audigy) {
-+			sblive_writeptr_tag(card,nCh,
-+					    0x4c,0x0,
-+					    0x4d,0x0,
-+					    0x4e,0x0,
-+					    0x4f,0x0,
-+					    A_FXRT1, 0x3f3f3f3f,
-+					    A_FXRT2, 0x3f3f3f3f,
-+					    A_SENDAMOUNTS, 0,
-+					    TAGLIST_END);
-+		}
- 	}
- 	
- 
-@@ -858,6 +1060,25 @@ static int __devinit hw_init(struct emu1
- 
- 			    TAGLIST_END);
- 
-+	if (card->is_audigy && (card->chiprev == 4)) {
-+		/* Hacks for Alice3 to work independent of haP16V driver */
-+		u32 tmp;
-+
-+		//Setup SRCMulti_I2S SamplingRate
-+		tmp = sblive_readptr(card, A_SPDIF_SAMPLERATE, 0);
-+		tmp &= 0xfffff1ff;
-+		tmp |= (0x2<<9);
-+		sblive_writeptr(card, A_SPDIF_SAMPLERATE, 0, tmp);
-+
-+		/* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
-+		emu10k1_writefn0(card, 0x20, 0x600000);
-+		emu10k1_writefn0(card, 0x24, 0x14);
-+
-+		/* Setup SRCMulti Input Audio Enable */
-+		emu10k1_writefn0(card, 0x20, 0x6E0000);
-+		emu10k1_writefn0(card, 0x24, 0xFF00FF00);
-+	}
-+
- 	ret = fx_init(card);		/* initialize effects engine */
- 	if (ret < 0)
- 		return ret;
-@@ -905,16 +1126,30 @@ static int __devinit hw_init(struct emu1
- 	/* Lock Tank Memory = 1 */
- 	/* Lock Sound Memory = 0 */
- 	/* Auto Mute = 1 */
--
--	if (card->model == 0x20 || card->model == 0xc400 ||
--	  (card->model == 0x21 && card->chiprev < 6))
--	        emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE);
--	else
--		emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE);
--
-+	if (card->is_audigy) {
-+		if (card->chiprev == 4)
-+			emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_AC3ENABLE_CDSPDIF | HCFG_AC3ENABLE_GPSPDIF | HCFG_AUTOMUTE | HCFG_JOYENABLE);
-+		else
-+			emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_AUTOMUTE | HCFG_JOYENABLE);
-+	} else {
-+		if (card->model == 0x20 || card->model == 0xc400 ||
-+		 (card->model == 0x21 && card->chiprev < 6))
-+	        	emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE);
-+		else
-+			emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE);
-+	}
- 	/* Enable Vol_Ctrl irqs */
- 	emu10k1_irq_enable(card, INTE_VOLINCRENABLE | INTE_VOLDECRENABLE | INTE_MUTEENABLE | INTE_FXDSPENABLE);
- 
-+	if (card->is_audigy && (card->chiprev == 4)) {
-+		/* Unmute Analog now.  Set GPO6 to 1 for Apollo.
-+		 * This has to be done after init ALice3 I2SOut beyond 48KHz.
-+		 * So, sequence is important. */
-+		u32 tmp = emu10k1_readfn0(card, A_IOCFG);
-+		tmp |= 0x0040;
-+		emu10k1_writefn0(card, A_IOCFG, tmp);
-+	}
-+	
- 	/* FIXME: TOSLink detection */
- 	card->has_toslink = 0;
- 
-@@ -967,7 +1202,7 @@ static int __devinit emu10k1_init(struct
- 	return 0;
- }
- 
--static void __devinit emu10k1_cleanup(struct emu10k1_card *card)
-+static void emu10k1_cleanup(struct emu10k1_card *card)
- {
- 	int ch;
- 
-@@ -1012,6 +1247,8 @@ static void __devinit emu10k1_cleanup(st
- 			    SOLEH, 0,
- 			    TAGLIST_END);
- 
-+	if (card->is_audigy)
-+		sblive_writeptr(card, 0, A_DBG,  A_DBG_SINGLE_STEP);
- 
- 	pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
- 	pci_free_consistent(card->pci_dev, card->silentpage.size, card->silentpage.addr, card->silentpage.dma_handle);
-@@ -1074,6 +1311,9 @@ static int __devinit emu10k1_probe(struc
- 		card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
- 		card->iobase + card->length - 1, card->irq);
- 
-+	if (pci_id->device == PCI_DEVICE_ID_CREATIVE_AUDIGY)
-+		card->is_audigy = 1;
-+
- 	pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
- 	card->is_aps = (subsysvid == EMU_APS_SUBID);
- 
-@@ -1083,13 +1323,13 @@ static int __devinit emu10k1_probe(struc
- 	init_waitqueue_head(&card->open_wait);
- 
- 	ret = emu10k1_audio_init(card);
--	if(ret < 0) {
-+	if (ret < 0) {
-                 printk(KERN_ERR "emu10k1: cannot initialize audio devices\n");
-                 goto err_audio;
-         }
- 
- 	ret = emu10k1_mixer_init(card);
--	if(ret < 0) {
-+	if (ret < 0) {
- 		printk(KERN_ERR "emu10k1: cannot initialize AC97 codec\n");
-                 goto err_mixer;
- 	}
-@@ -1109,10 +1349,28 @@ static int __devinit emu10k1_probe(struc
- 	if (card->is_aps)
- 		emu10k1_ecard_init(card);
- 
-+	ret = emu10k1_register_devices(card);
-+	if (ret < 0)
-+		goto err_register;
-+
-+	/* proc entries must be created after registering devices, as
-+	 * emu10k1_info_proc prints card->audio_dev &co. */
-+	ret = emu10k1_proc_init(card);
-+	if (ret < 0) {
-+		printk(KERN_ERR "emu10k1: cannot initialize proc directory\n");
-+                goto err_proc;
-+	}
-+	
- 	list_add(&card->list, &emu10k1_devs);
- 
- 	return 0;
- 
-+err_proc:
-+	emu10k1_unregister_devices(card);
-+
-+err_register:
-+	emu10k1_cleanup(card);
-+	
- err_emu10k1_init:
- 	emu10k1_midi_cleanup(card);
- 
-@@ -1141,9 +1399,11 @@ static void __devexit emu10k1_remove(str
- 
- 	list_del(&card->list);
- 
-+	emu10k1_unregister_devices(card);
- 	emu10k1_cleanup(card);
- 	emu10k1_midi_cleanup(card);
- 	emu10k1_mixer_cleanup(card);
-+	emu10k1_proc_cleanup(card);
- 	emu10k1_audio_cleanup(card);	
- 	free_irq(card->irq, card);
- 	release_region(card->iobase, card->length);
---- linux-2.6.0-test1/sound/oss/emu10k1/midi.h	2003-06-14 12:18:00.000000000 -0700
-+++ 25/sound/oss/emu10k1/midi.h	2003-07-19 17:03:51.000000000 -0700
-@@ -52,4 +52,27 @@ struct emu10k1_mididevice
- 	struct list_head mid_hdrs;
- };
- 
-+/* uncomment next line to use midi port on Audigy drive */
-+//#define USE_AUDIGY_DRIVE_MIDI
-+
-+#ifdef USE_AUDIGY_DRIVE_MIDI
-+#define A_MUDATA	A_MUDATA2
-+#define A_MUCMD		A_MUCMD2
-+#define A_MUSTAT	A_MUCMD2
-+#define A_IPR_MIDITRANSBUFEMPTY	A_IPR_MIDITRANSBUFEMPTY2
-+#define A_IPR_MIDIRECVBUFEMPTY	A_IPR_MIDIRECVBUFEMPTY2
-+#define A_INTE_MIDITXENABLE	A_INTE_MIDITXENABLE2
-+#define A_INTE_MIDIRXENABLE	A_INTE_MIDIRXENABLE2
-+#else
-+#define A_MUDATA	A_MUDATA1
-+#define A_MUCMD		A_MUCMD1
-+#define A_MUSTAT	A_MUCMD1
-+#define A_IPR_MIDITRANSBUFEMPTY	A_IPR_MIDITRANSBUFEMPTY1
-+#define A_IPR_MIDIRECVBUFEMPTY	A_IPR_MIDIRECVBUFEMPTY1
-+#define A_INTE_MIDITXENABLE	A_INTE_MIDITXENABLE1
-+#define A_INTE_MIDIRXENABLE	A_INTE_MIDIRXENABLE1
-+#endif
-+
-+
- #endif /* _MIDI_H */
-+
---- linux-2.6.0-test1/sound/oss/emu10k1/mixer.c	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/emu10k1/mixer.c	2003-07-19 17:03:51.000000000 -0700
-@@ -136,7 +136,7 @@ static void set_bass(struct emu10k1_card
- 	r = (r * 40 + 50) / 100;
- 
- 	for (i = 0; i < 5; i++)
--		sblive_writeptr(card, GPR_BASE + card->mgr.ctrl_gpr[SOUND_MIXER_BASS][0] + i, 0, bass_table[l][i]);
-+		sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + card->mgr.ctrl_gpr[SOUND_MIXER_BASS][0] + i, 0, bass_table[l][i]);
- }
- 
- static void set_treble(struct emu10k1_card *card, int l, int r)
-@@ -147,7 +147,7 @@ static void set_treble(struct emu10k1_ca
- 	r = (r * 40 + 50) / 100;
- 
- 	for (i = 0; i < 5; i++)
--		sblive_writeptr(card, GPR_BASE + card->mgr.ctrl_gpr[SOUND_MIXER_TREBLE][0] + i , 0, treble_table[l][i]);
-+		sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + card->mgr.ctrl_gpr[SOUND_MIXER_TREBLE][0] + i , 0, treble_table[l][i]);
- }
- 
- const char volume_params[SOUND_MIXER_NRDEVICES]= {
-@@ -206,22 +206,25 @@ static int emu10k1_private_mixer(struct 
- 		switch (ctl->cmd) {
- #ifdef DBGEMU
- 		case CMD_WRITEFN0:
--			emu10k1_writefn0(card, ctl->val[0], ctl->val[1]);
-+			emu10k1_writefn0_2(card, ctl->val[0], ctl->val[1], ctl->val[2]);
- 			break;
--
-+#endif
- 		case CMD_WRITEPTR:
--			if (ctl->val[1] >= 0x40 || ctl->val[0] > 0xff) {
-+#ifdef DBGEMU
-+			if (ctl->val[1] >= 0x40 || ctl->val[0] >= 0x1000) {
-+#else
-+			if (ctl->val[1] >= 0x40 || ctl->val[0] >= 0x1000 || ((ctl->val[0] < 0x100 ) &&
-+		    //Any register allowed raw access goes here:
-+				     (ctl->val[0] != A_SPDIF_SAMPLERATE) && (ctl->val[0] != A_DBG)
-+			)
-+				) {
-+#endif
- 				ret = -EINVAL;
- 				break;
- 			}
--
--			if ((ctl->val[0] & 0x7ff) > 0x3f)
--				ctl->val[1] = 0x00;
--
- 			sblive_writeptr(card, ctl->val[0], ctl->val[1], ctl->val[2]);
--
- 			break;
--#endif
-+
- 		case CMD_READFN0:
- 			ctl->val[2] = emu10k1_readfn0(card, ctl->val[0]);
- 
-@@ -286,16 +289,13 @@ static int emu10k1_private_mixer(struct 
- 
- 		case CMD_GETVOICEPARAM:
- 			ctl->val[0] = card->waveout.send_routing[0];
--			ctl->val[1] = card->waveout.send_a[0] | card->waveout.send_b[0] << 8 |
--			    	      card->waveout.send_c[0] << 16 | card->waveout.send_d[0] << 24;
-+			ctl->val[1] = card->waveout.send_dcba[0];
- 
- 			ctl->val[2] = card->waveout.send_routing[1];
--			ctl->val[3] = card->waveout.send_a[1] | card->waveout.send_b[1] << 8 |
--				      card->waveout.send_c[1] << 16 | card->waveout.send_d[1] << 24;
-+			ctl->val[3] = card->waveout.send_dcba[1];
- 
- 			ctl->val[4] = card->waveout.send_routing[2];
--			ctl->val[5] = card->waveout.send_a[2] | card->waveout.send_b[2] << 8 |
--				     card->waveout.send_c[2] << 16 | card->waveout.send_d[2] << 24;
-+			ctl->val[5] = card->waveout.send_dcba[2];
- 
- 			if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
- 				ret = -EFAULT;
-@@ -303,23 +303,14 @@ static int emu10k1_private_mixer(struct 
- 			break;
- 
- 		case CMD_SETVOICEPARAM:
--			card->waveout.send_routing[0] = ctl->val[0] & 0xffff;
--			card->waveout.send_a[0] = ctl->val[1] & 0xff;
--			card->waveout.send_b[0] = (ctl->val[1] >> 8) & 0xff;
--			card->waveout.send_c[0] = (ctl->val[1] >> 16) & 0xff;
--			card->waveout.send_d[0] = (ctl->val[1] >> 24) & 0xff;
--
--			card->waveout.send_routing[1] = ctl->val[2] & 0xffff;
--			card->waveout.send_a[1] = ctl->val[3] & 0xff;
--			card->waveout.send_b[1] = (ctl->val[3] >> 8) & 0xff;
--			card->waveout.send_c[1] = (ctl->val[3] >> 16) & 0xff;
--			card->waveout.send_d[1] = (ctl->val[3] >> 24) & 0xff;
--
--			card->waveout.send_routing[2] = ctl->val[4] & 0xffff;
--			card->waveout.send_a[2] = ctl->val[5] & 0xff;
--			card->waveout.send_b[2] = (ctl->val[5] >> 8) & 0xff;
--			card->waveout.send_c[2] = (ctl->val[5] >> 16) & 0xff;
--			card->waveout.send_d[2] = (ctl->val[5] >> 24) & 0xff;
-+			card->waveout.send_routing[0] = ctl->val[0];
-+			card->waveout.send_dcba[0] = ctl->val[1];
-+
-+			card->waveout.send_routing[1] = ctl->val[2];
-+			card->waveout.send_dcba[1] = ctl->val[3];
-+
-+			card->waveout.send_routing[2] = ctl->val[4];
-+			card->waveout.send_dcba[2] = ctl->val[5];
- 
- 			break;
- 		
-@@ -416,12 +407,16 @@ static int emu10k1_private_mixer(struct 
- 			break;
- 
- 		case CMD_SETGPOUT:
--			if (ctl->val[0] > 2 || ctl->val[1] > 1) {
-+			if ( ((ctl->val[0] > 2) && (!card->is_audigy))
-+			     || (ctl->val[0] > 15) || ctl->val[1] > 1) {
- 				ret= -EINVAL;
- 				break;
- 			}
- 
--			emu10k1_writefn0(card, (1 << 24) | (((ctl->val[0]) + 10) << 16) | HCFG, ctl->val[1]);
-+			if (card->is_audigy)
-+				emu10k1_writefn0(card, (1 << 24) | ((ctl->val[0]) << 16) | A_IOCFG, ctl->val[1]);
-+			else
-+				emu10k1_writefn0(card, (1 << 24) | (((ctl->val[0]) + 10) << 16) | HCFG, ctl->val[1]);
- 			break;
- 
- 		case CMD_GETGPR2OSS:
-@@ -493,13 +488,20 @@ static int emu10k1_private_mixer(struct 
- 			break;
- 
- 		case CMD_PRIVATE3_VERSION:
--			ctl->val[0]=PRIVATE3_VERSION;
-+			ctl->val[0] = PRIVATE3_VERSION;	//private3 version
-+			ctl->val[1] = MAJOR_VER;	//major driver version
-+			ctl->val[2] = MINOR_VER;	//minor driver version
-+			ctl->val[3] = card->is_audigy;	//1=card is audigy
-+
-+			if (card->is_audigy)
-+				ctl->val[4]=emu10k1_readfn0(card, 0x18);
-+
- 			if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
- 				ret = -EFAULT;
- 			break;
- 
- 		case CMD_AC97_BOOST:
--			if(ctl->val[0])
-+			if (ctl->val[0])
- 				emu10k1_ac97_write(card->ac97, 0x18, 0x0);	
- 			else
- 				emu10k1_ac97_write(card->ac97, 0x18, 0x0808);
-@@ -556,7 +558,7 @@ static int emu10k1_private_mixer(struct 
- 
- 				card->tankmem.size = size;
- 
--				sblive_writeptr_tag(card, 0, TCB, (u32) card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
-+				sblive_writeptr_tag(card, 0, TCB, (u32) card->tankmem.dma_handle, TCBS,(u32) size_reg, TAGLIST_END);
- 
- 				emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
- 			}
-@@ -623,8 +625,13 @@ static int emu10k1_mixer_ioctl(struct in
- 		if (cmd == SOUND_MIXER_INFO) {
- 			mixer_info info;
- 
--			strncpy(info.id, card->ac97->name, sizeof(info.id));
--			strncpy(info.name, "Creative SBLive - Emu10k1", sizeof(info.name));
-+			strlcpy(info.id, card->ac97->name, sizeof(info.id));
-+
-+			if (card->is_audigy)
-+				strlcpy(info.name, "Audigy - Emu10k1", sizeof(info.name));
-+			else
-+				strlcpy(info.name, "Creative SBLive - Emu10k1", sizeof(info.name));
-+				
- 			info.modify_counter = card->ac97->modcnt;
- 
- 			if (copy_to_user((void *)arg, &info, sizeof(info)))
---- linux-2.6.0-test1/sound/oss/emu10k1/passthrough.c	2003-06-14 12:18:09.000000000 -0700
-+++ 25/sound/oss/emu10k1/passthrough.c	2003-07-19 17:03:51.000000000 -0700
-@@ -109,7 +109,7 @@ static int pt_putblock(struct emu10k1_wa
- 	return 0;
- }
- 
--static int pt_setup(struct emu10k1_wavedevice *wave_dev)
-+int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev)
- {
- 	u32 bits;
- 	struct emu10k1_card *card = wave_dev->card;
-@@ -155,7 +155,7 @@ ssize_t emu10k1_pt_write(struct file *fi
- 		pt->prepend_size = 0;
- 		if (pt->buf == NULL)
- 			return -ENOMEM;
--		pt_setup(wave_dev);
-+		emu10k1_pt_setup(wave_dev);
- 	}
- 	if (pt->prepend_size) {
- 		int needed = PT_BLOCKSIZE - pt->prepend_size;
-@@ -208,13 +208,14 @@ void emu10k1_pt_stop(struct emu10k1_card
- 
- 	if (pt->state != PT_STATE_INACTIVE) {
- 		DPF(2, "digital pass-through stopped\n");
--		sblive_writeptr(card, GPR_BASE + pt->enable_gpr, 0, 0);
-+		sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + pt->enable_gpr, 0, 0);
- 		for (i = 0; i < 3; i++) {
-                         if (pt->spcs_to_use & (1 << i))
- 				sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]);
- 		}
- 		pt->state = PT_STATE_INACTIVE;
--		kfree(pt->buf);
-+		if(pt->buf)
-+			kfree(pt->buf);
- 	}
- }
- 
---- linux-2.6.0-test1/sound/oss/emu10k1/passthrough.h	2003-06-14 12:18:21.000000000 -0700
-+++ 25/sound/oss/emu10k1/passthrough.h	2003-07-19 17:03:51.000000000 -0700
-@@ -63,7 +63,36 @@ struct pt_data
- 	spinlock_t lock;
- };
- 
-+/*
-+  Passthrough can be done in two methods:
-+
-+  Method 1 : tram
-+     In original emu10k1, we couldn't bypass the sample rate converters. Even at 48kHz
-+     (the internal sample rate of the emu10k1) the samples would get messed up.
-+     To over come this, samples are copied into the tram and a special dsp patch copies
-+     the samples out and generates interrupts when a block has finnished playing.
-+
-+  Method 2 : Interpolator bypass
-+
-+     Creative fixed the sample rate convert problem in emu10k1 rev 7 and higher
-+     (including the emu10k2 (audigy)). This allows us to use the regular, and much simpler
-+     playback method. 
-+
-+
-+  In both methods, dsp code is used to mux audio and passthrough. This ensures that the spdif
-+  doesn't receive audio and pasthrough data at the same time. The spdif flag SPCS_NOTAUDIODATA
-+  is set to tell 
-+
-+ */
-+
-+// emu10k1 revs greater than or equal to 7 can use method2
-+
-+#define USE_PT_METHOD2  (card->is_audigy)
-+#define USE_PT_METHOD1	!USE_PT_METHOD2
-+
- ssize_t emu10k1_pt_write(struct file *file, const char *buf, size_t count);
-+
-+int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev);
- void emu10k1_pt_stop(struct emu10k1_card *card);
- void emu10k1_pt_waveout_update(struct emu10k1_wavedevice *wave_dev);
- 
---- linux-2.6.0-test1/sound/oss/emu10k1/recmgr.c	2003-06-14 12:18:52.000000000 -0700
-+++ 25/sound/oss/emu10k1/recmgr.c	2003-07-19 17:03:51.000000000 -0700
-@@ -74,7 +74,7 @@ void emu10k1_set_record_src(struct emu10
- 		DPF(2, "recording source: AC97\n");
- 		buffer->sizereg = ADCBS;
- 		buffer->addrreg = ADCBA;
--		buffer->idxreg = ADCIDX_IDX;
-+		buffer->idxreg = card->is_audigy ? A_ADCIDX_IDX : ADCIDX_IDX;
- 
- 		switch (wiinst->format.samplingrate) {
- 		case 0xBB80:
-@@ -95,21 +95,27 @@ void emu10k1_set_record_src(struct emu10
- 		case 0x3E80:
- 			buffer->adcctl = ADCCR_SAMPLERATE_16;
- 			break;
-+		// FIXME: audigy supports 12kHz recording
-+		/*
-+		case ????:
-+			buffer->adcctl = A_ADCCR_SAMPLERATE_12;
-+			break;
-+		*/
- 		case 0x2B11:
--			buffer->adcctl = ADCCR_SAMPLERATE_11;
-+			buffer->adcctl = card->is_audigy ? A_ADCCR_SAMPLERATE_11 : ADCCR_SAMPLERATE_11;
- 			break;
- 		case 0x1F40:
--			buffer->adcctl = ADCCR_SAMPLERATE_8;
-+			buffer->adcctl = card->is_audigy ? A_ADCCR_SAMPLERATE_8 : ADCCR_SAMPLERATE_8;
- 			break;
- 		default:
- 			BUG();
- 			break;
- 		}
- 
--		buffer->adcctl |= ADCCR_LCHANENABLE;
-+		buffer->adcctl |= card->is_audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE;
- 
- 		if (wiinst->format.channels == 2)
--			buffer->adcctl |= ADCCR_RCHANENABLE;
-+			buffer->adcctl |= card->is_audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE;
- 
- 		break;
- 
---- linux-2.6.0-test1/sound/oss/emu10k1/voicemgr.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/sound/oss/emu10k1/voicemgr.c	2003-07-19 17:03:51.000000000 -0700
-@@ -32,6 +32,34 @@
- #include "voicemgr.h"
- #include "8010.h"
- 
-+#define PITCH_48000 0x00004000
-+#define PITCH_96000 0x00008000
-+#define PITCH_85000 0x00007155
-+#define PITCH_80726 0x00006ba2
-+#define PITCH_67882 0x00005a82
-+#define PITCH_57081 0x00004c1c
-+
-+u32 emu10k1_select_interprom(struct emu10k1_card *card, struct emu_voice *voice)
-+{
-+	if(voice->pitch_target==PITCH_48000)
-+		return CCCA_INTERPROM_0;
-+	else if(voice->pitch_target<PITCH_48000)
-+		return CCCA_INTERPROM_1;
-+	else  if(voice->pitch_target>=PITCH_96000)
-+		return CCCA_INTERPROM_0;
-+	else  if(voice->pitch_target>=PITCH_85000)
-+		return CCCA_INTERPROM_6;
-+	else  if(voice->pitch_target>=PITCH_80726)
-+		return CCCA_INTERPROM_5;
-+	else  if(voice->pitch_target>=PITCH_67882)
-+		return CCCA_INTERPROM_4;
-+	else  if(voice->pitch_target>=PITCH_57081)
-+		return CCCA_INTERPROM_3;
-+	else  
-+		return CCCA_INTERPROM_2;
-+}
-+
-+
- /**
-  * emu10k1_voice_alloc_buffer -
-  *
-@@ -216,17 +244,25 @@ void emu10k1_voice_playback_setup(struct
- 	voice->start += start;
- 
- 	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
--		sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].send_routing << 16);
-+		if (card->is_audigy) {
-+			sblive_writeptr(card, A_FXRT1, voice->num + i, voice->params[i].send_routing);
-+			sblive_writeptr(card, A_FXRT2, voice->num + i, voice->params[i].send_routing2);
-+			sblive_writeptr(card,  A_SENDAMOUNTS, voice->num + i, voice->params[i].send_hgfe);
-+		} else {
-+			sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].send_routing << 16);
-+		}
- 
- 		/* Stop CA */
- 		/* Assumption that PT is already 0 so no harm overwriting */
--		sblive_writeptr(card, PTRX, voice->num + i, (voice->params[i].send_a << 8) | voice->params[i].send_b);
-+		sblive_writeptr(card, PTRX, voice->num + i, ((voice->params[i].send_dcba & 0xff) << 8)
-+				| ((voice->params[i].send_dcba & 0xff00) >> 8));
- 
- 		sblive_writeptr_tag(card, voice->num + i,
- 				/* CSL, ST, CA */
--				    DSL, voice->endloop | (voice->params[i].send_d << 24),
--				    PSST, voice->startloop | (voice->params[i].send_c << 24),
--				    CCCA, (voice->start) | CCCA_INTERPROM_0 | ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
-+				    DSL, voice->endloop | (voice->params[i].send_dcba & 0xff000000),
-+				    PSST, voice->startloop | ((voice->params[i].send_dcba & 0x00ff0000) << 8),
-+				    CCCA, (voice->start) |  emu10k1_select_interprom(card,voice) |
-+				        ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
- 				    /* Clear filter delay memory */
- 				    Z1, 0,
- 				    Z2, 0,
---- linux-2.6.0-test1/sound/oss/emu10k1/voicemgr.h	2003-06-14 12:18:23.000000000 -0700
-+++ 25/sound/oss/emu10k1/voicemgr.h	2003-07-19 17:03:51.000000000 -0700
-@@ -48,11 +48,13 @@ struct voice_param
- 	/* FX bus amount send */
- 
- 	u32 send_routing;
-+	// audigy only:
-+	u32 send_routing2;
-+
-+	u32 send_dcba;
-+	// audigy only:
-+	u32 send_hgfe;
- 
--	u32 send_a;
--	u32 send_b;
--	u32 send_c;
--	u32 send_d;
- 
- 	u32 initial_fc;
- 	u32 fc_target;
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/sound/oss/hal2.c	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,1498 @@
-+/*
-+ *  Driver for HAL2 sound processors
-+ *  Copyright (c) 2001, 2002 Ladislav Michl <ladis@psi.cz>
-+ *  
-+ *  Based on Ulf Carlsson's code.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as 
-+ *  published by the Free Software Foundation.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ *  Supported devices:
-+ *  /dev/dsp    standard dsp device, (mostly) OSS compatible
-+ *  /dev/mixer	standard mixer device, (mostly) OSS compatible
-+ *
-+ *  BUGS:
-+ *  + Driver currently supports indigo mode only.
-+ *  + Recording doesn't work. I guess that it is caused by PBUS channel
-+ *    misconfiguration, but until I get relevant info I'm unable to fix it.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/sgi/sgint23.h>
-+
-+#include "hal2.h"
-+
-+#if 0
-+#define DEBUG(args...)		printk(args)
-+#else
-+#define DEBUG(args...)
-+#endif
-+
-+#if 0 
-+#define DEBUG_MIX(args...)	printk(args)
-+#else
-+#define DEBUG_MIX(args...)
-+#endif
-+
-+#define H2_INDIRECT_WAIT(regs)	while (regs->isr & H2_ISR_TSTATUS);
-+
-+#define H2_READ_ADDR(addr)	(addr | (1<<7))
-+#define H2_WRITE_ADDR(addr)	(addr)
-+
-+static char *hal2str = "HAL2 audio";
-+static int ibuffers = 32;
-+static int obuffers = 32;
-+
-+/* I doubt anyone has a machine with two HAL2 cards. It's possible to
-+ * have two HPC's, so it is probably possible to have two HAL2 cards.
-+ * Try to deal with it, but note that it is not tested.
-+ */
-+#define MAXCARDS	2
-+static hal2_card_t* hal2_card[MAXCARDS];
-+
-+static const struct {
-+	unsigned char idx:4, avail:1;
-+} mixtable[SOUND_MIXER_NRDEVICES] = {
-+	[SOUND_MIXER_PCM] = { H2_MIX_OUTPUT_ATT, 1 },	/* voice */
-+	[SOUND_MIXER_MIC] = { H2_MIX_INPUT_GAIN, 1 },	/* mic */
-+};
-+
-+#define H2_SUPPORTED_FORMATS	(AFMT_S16_LE | AFMT_S16_BE)
-+
-+static inline void hal2_isr_write(hal2_card_t *hal2, u32 val)
-+{
-+	hal2->ctl_regs->isr = val;
-+}
-+
-+static inline u32 hal2_isr_look(hal2_card_t *hal2)
-+{
-+	return hal2->ctl_regs->isr;
-+}
-+
-+static inline u32 hal2_rev_look(hal2_card_t *hal2)
-+{
-+	return hal2->ctl_regs->rev;
-+}
-+
-+#if 0
-+static u16 hal2_i_look16(hal2_card_t *hal2, u32 addr)
-+{
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	return (regs->idr0 & 0xffff);
-+}
-+#endif
-+
-+static u32 hal2_i_look32(hal2_card_t *hal2, u32 addr)
-+{
-+	u32 ret;
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	ret = regs->idr0 & 0xffff;
-+	regs->iar = H2_READ_ADDR(addr | 0x1);
-+	H2_INDIRECT_WAIT(regs);
-+	ret |= (regs->idr0 & 0xffff) << 16;
-+	return ret;
-+}
-+
-+static void hal2_i_write16(hal2_card_t *hal2, u32 addr, u16 val)
-+{
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->idr0 = val;
-+	regs->idr1 = 0;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+
-+static void hal2_i_write32(hal2_card_t *hal2, u32 addr, u32 val)
-+{
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->idr0 = val & 0xffff;
-+	regs->idr1 = val >> 16;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+
-+static void hal2_i_setbit16(hal2_card_t *hal2, u32 addr, u16 bit)
-+{
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	regs->idr0 = regs->idr0 | bit;
-+	regs->idr1 = 0;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+
-+static void hal2_i_setbit32(hal2_card_t *hal2, u32 addr, u32 bit)
-+{
-+	u32 tmp;
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	tmp = regs->idr0 | (regs->idr1 << 16) | bit;
-+	regs->idr0 = tmp & 0xffff;
-+	regs->idr1 = tmp >> 16;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+
-+static void hal2_i_clearbit16(hal2_card_t *hal2, u32 addr, u16 bit)
-+{
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	regs->idr0 = regs->idr0 & ~bit;
-+	regs->idr1 = 0;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+
-+#if 0
-+static void hal2_i_clearbit32(hal2_card_t *hal2, u32 addr, u32 bit)
-+{
-+	u32 tmp;
-+	hal2_ctl_regs_t *regs = hal2->ctl_regs;
-+
-+	regs->iar = H2_READ_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+	tmp = (regs->idr0 | (regs->idr1 << 16)) & ~bit;
-+	regs->idr0 = tmp & 0xffff;
-+	regs->idr1 = tmp >> 16;
-+	regs->idr2 = 0;
-+	regs->idr3 = 0;
-+	regs->iar = H2_WRITE_ADDR(addr);
-+	H2_INDIRECT_WAIT(regs);
-+}
-+#endif
-+
-+#ifdef HAL2_DEBUG
-+static void hal2_dump_regs(hal2_card_t *hal2)
-+{
-+	printk("isr: %08hx ", hal2_isr_look(hal2));
-+	printk("rev: %08hx\n", hal2_rev_look(hal2));
-+	printk("relay: %04hx\n", hal2_i_look16(hal2, H2I_RELAY_C));
-+	printk("port en: %04hx ", hal2_i_look16(hal2, H2I_DMA_PORT_EN));
-+	printk("dma end: %04hx ", hal2_i_look16(hal2, H2I_DMA_END));
-+	printk("dma drv: %04hx\n", hal2_i_look16(hal2, H2I_DMA_DRV));
-+	printk("syn ctl: %04hx ", hal2_i_look16(hal2, H2I_SYNTH_C));
-+	printk("aesrx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESRX_C));
-+	printk("aestx ctl: %04hx ", hal2_i_look16(hal2, H2I_AESTX_C));
-+	printk("dac ctl1: %04hx ", hal2_i_look16(hal2, H2I_ADC_C1));
-+	printk("dac ctl2: %08lx ", hal2_i_look32(hal2, H2I_ADC_C2));
-+	printk("adc ctl1: %04hx ", hal2_i_look16(hal2, H2I_DAC_C1));
-+	printk("adc ctl2: %08lx ", hal2_i_look32(hal2, H2I_DAC_C2));
-+	printk("syn map: %04hx\n", hal2_i_look16(hal2, H2I_SYNTH_MAP_C));
-+	printk("bres1 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES1_C1));
-+	printk("bres1 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES1_C2));
-+	printk("bres2 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES2_C1));
-+	printk("bres2 ctl2: %04lx ", hal2_i_look32(hal2, H2I_BRES2_C2));
-+	printk("bres3 ctl1: %04hx ", hal2_i_look16(hal2, H2I_BRES3_C1));
-+	printk("bres3 ctl2: %04lx\n", hal2_i_look32(hal2, H2I_BRES3_C2));
-+}
-+#endif
-+
-+static hal2_card_t* hal2_dsp_find_card(int minor)
-+{
-+	int i;
-+
-+	for (i = 0; i < MAXCARDS; i++)
-+		if (hal2_card[i] != NULL && hal2_card[i]->dev_dsp == minor)
-+			return hal2_card[i];
-+	return NULL;
-+}
-+
-+static hal2_card_t* hal2_mixer_find_card(int minor)
-+{
-+	int i;
-+
-+	for (i = 0; i < MAXCARDS; i++)
-+		if (hal2_card[i] != NULL && hal2_card[i]->dev_mixer == minor)
-+			return hal2_card[i];
-+	return NULL;
-+}
-+
-+
-+static void hal2_dac_interrupt(hal2_codec_t *dac)
-+{
-+	int running;
-+
-+	spin_lock(&dac->lock);
-+	
-+	/* if tail buffer contains zero samples DMA stream was already
-+	 * stopped */
-+	running = dac->tail->info.cnt;
-+	dac->tail->info.cnt = 0;
-+	dac->tail->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX;
-+	dma_cache_wback_inv((unsigned long) dac->tail,
-+			    sizeof(struct hpc_dma_desc));
-+	/* we just proccessed empty buffer, don't update tail pointer */
-+	if (running)
-+		dac->tail = dac->tail->info.next;
-+
-+	spin_unlock(&dac->lock);
-+
-+	wake_up(&dac->dma_wait);
-+}
-+
-+static void hal2_adc_interrupt(hal2_codec_t *adc)
-+{
-+	int running;
-+	
-+	spin_lock(&adc->lock);
-+
-+	/* if head buffer contains nonzero samples DMA stream was already
-+	 * stopped */
-+	running = !adc->head->info.cnt;
-+	adc->head->info.cnt = H2_BUFFER_SIZE;
-+	adc->head->info.desc.cntinfo = HPCDMA_XIE | HPCDMA_EOX;
-+	dma_cache_wback_inv((unsigned long) adc->head,
-+			    sizeof(struct hpc_dma_desc));
-+	/* we just proccessed empty buffer, don't update head pointer */
-+	if (running) {
-+		dma_cache_inv((unsigned long) adc->head->data, H2_BUFFER_SIZE);
-+		adc->head = adc->head->info.next;
-+	}
-+
-+	spin_unlock(&adc->lock);
-+
-+	wake_up(&adc->dma_wait);
-+}
-+
-+static irqreturn_t hal2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+	hal2_card_t *hal2 = (hal2_card_t*)dev_id;
-+
-+	/* decide what caused this interrupt */
-+	if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT)
-+		hal2_dac_interrupt(&hal2->dac);
-+	if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT)
-+		hal2_adc_interrupt(&hal2->adc);
-+	return IRQ_HANDLED;
-+}
-+
-+static int hal2_compute_rate(hal2_codec_t *codec, unsigned int rate)
-+{
-+	unsigned short inc;
-+	
-+	/* We default to 44.1 kHz and if it isn't possible to fall back to
-+	 * 48.0 kHz with the needed adjustments of real_rate.
-+	 */
-+
-+	DEBUG("rate: %d\n", rate);
-+	
-+	/* Refer to CS4216 data sheet */
-+	if (rate < 4000)
-+		rate = 4000;
-+	if (rate > 50000)
-+		rate = 50000;
-+
-+	/* Note: This is NOT the way they set up the bresenham clock generators
-+	 * in the specification. I've tried to implement that method but it
-+	 * doesn't work. It's probably another silly bug in the spec.
-+	 *
-+	 * I accidently discovered this method while I was testing and it seems
-+	 * to work very well with all frequencies, and thee shall follow rule #1
-+	 * of programming :-)
-+	 */
-+	
-+	if (44100 % rate == 0) {
-+		inc = 44100 / rate;
-+		if (inc < 1) inc = 1;
-+		codec->master = 44100;
-+	} else {
-+		inc = 48000 / rate;
-+		if (inc < 1) inc = 1;
-+		rate = 48000 / inc;
-+		codec->master = 48000;
-+	}
-+	codec->inc = inc;
-+	codec->mod = 1;
-+	
-+	DEBUG("real_rate: %d\n", rate);
-+
-+	return rate;
-+}
-+
-+static void hal2_set_dac_rate(hal2_card_t *hal2)
-+{
-+	unsigned int master = hal2->dac.master;
-+	int inc = hal2->dac.inc;
-+	int mod = hal2->dac.mod;
-+
-+	DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
-+	
-+	hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
-+	hal2_i_write32(hal2, H2I_BRES1_C2, ((0xffff & (mod - inc - 1)) << 16) | 1);
-+}
-+
-+static void hal2_set_adc_rate(hal2_card_t *hal2)
-+{
-+	unsigned int master = hal2->adc.master;
-+	int inc = hal2->adc.inc;
-+	int mod = hal2->adc.mod;
-+
-+	DEBUG("master: %d inc: %d mod: %d\n", master, inc, mod);
-+	
-+	hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
-+	hal2_i_write32(hal2, H2I_BRES2_C2, ((0xffff & (mod - inc - 1)) << 16) | 1);
-+}
-+
-+static void hal2_setup_dac(hal2_card_t *hal2)
-+{
-+	unsigned int fifobeg, fifoend, highwater, sample_size;
-+	hal2_pbus_t *pbus = &hal2->dac.pbus;
-+
-+	DEBUG("hal2_setup_dac\n");
-+	
-+	/* Now we set up some PBUS information. The PBUS needs information about
-+	 * what portion of the fifo it will use. If it's receiving or
-+	 * transmitting, and finally whether the stream is little endian or big
-+	 * endian. The information is written later, on the start call.
-+	 */
-+	sample_size = 2 * hal2->dac.voices;
-+
-+	/* Fifo should be set to hold exactly four samples. Highwater mark
-+	 * should be set to two samples. */
-+	highwater = (sample_size * 2) >> 1;	/* halfwords */
-+	fifobeg = 0;				/* playback is first */
-+	fifoend = (sample_size * 4) >> 3;	/* doublewords */
-+	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
-+		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
-+	/* We disable everything before we do anything at all */
-+	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
-+	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
-+	hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
-+	/* Setup the HAL2 for playback */
-+	hal2_set_dac_rate(hal2);
-+	/* We are using 1st Bresenham clock generator for playback */
-+	hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
-+			| (1 << H2I_C1_CLKID_SHIFT)
-+			| (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
-+}
-+
-+static void hal2_setup_adc(hal2_card_t *hal2)
-+{
-+	unsigned int fifobeg, fifoend, highwater, sample_size;
-+	hal2_pbus_t *pbus = &hal2->adc.pbus;
-+
-+	DEBUG("hal2_setup_adc\n");
-+	
-+	sample_size = 2 * hal2->adc.voices;
-+
-+	highwater = (sample_size * 2) >> 1;		/* halfwords */
-+	fifobeg = (4 * 4) >> 3;				/* record is second */
-+	fifoend = (4 * 4 + sample_size * 4) >> 3;	/* doublewords */
-+	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | 
-+		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
-+	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
-+	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
-+	hal2_i_clearbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
-+	/* Setup the HAL2 for record */
-+	hal2_set_adc_rate(hal2);
-+	/* We are using 2nd Bresenham clock generator for record */
-+	hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
-+			| (2 << H2I_C1_CLKID_SHIFT)
-+			| (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
-+}
-+
-+static void hal2_start_dac(hal2_card_t *hal2)
-+{
-+	hal2_pbus_t *pbus = &hal2->dac.pbus;
-+
-+	DEBUG("hal2_start_dac\n");
-+	
-+	pbus->pbus->pbdma_dptr = PHYSADDR(hal2->dac.tail);
-+	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
-+
-+	/* set endianess */
-+	if (hal2->dac.format & AFMT_S16_LE)
-+		hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
-+	else
-+		hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
-+	/* set DMA bus */
-+	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
-+	/* enable DAC */
-+	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
-+}
-+
-+static void hal2_start_adc(hal2_card_t *hal2)
-+{
-+	hal2_pbus_t *pbus = &hal2->adc.pbus;
-+
-+	DEBUG("hal2_start_adc\n");
-+	
-+	pbus->pbus->pbdma_dptr = PHYSADDR(hal2->adc.head);
-+	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
-+	
-+	/* set endianess */
-+	if (hal2->adc.format & AFMT_S16_LE)
-+		hal2_i_setbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
-+	else
-+		hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
-+	/* set DMA bus */
-+	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
-+	/* enable ADC */
-+	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
-+}
-+
-+static inline void hal2_stop_dac(hal2_card_t *hal2)
-+{
-+	DEBUG("hal2_stop_dac\n");
-+	
-+	hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
-+	/* The HAL2 itself may remain enabled safely */
-+}
-+
-+static inline void hal2_stop_adc(hal2_card_t *hal2)
-+{
-+	DEBUG("hal2_stop_adc\n");
-+	
-+	hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
-+}
-+
-+#define hal2_alloc_dac_dmabuf(hal2)	hal2_alloc_dmabuf(hal2, 1)
-+#define hal2_alloc_adc_dmabuf(hal2)	hal2_alloc_dmabuf(hal2, 0)
-+static int hal2_alloc_dmabuf(hal2_card_t *hal2, int is_dac)
-+{
-+	int buffers, cntinfo;
-+	hal2_buf_t *buf, *prev;
-+	hal2_codec_t *codec;
-+
-+	if (is_dac) {
-+		codec = &hal2->dac;
-+		buffers = obuffers;
-+		cntinfo = HPCDMA_XIE | HPCDMA_EOX;
-+	} else {
-+		codec = &hal2->adc;
-+		buffers = ibuffers;
-+		cntinfo = HPCDMA_XIE | H2_BUFFER_SIZE;
-+	}
-+	
-+	DEBUG("allocating %d DMA buffers.\n", buffers);
-+	
-+	buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
-+	codec->head = buf;
-+	codec->tail = buf;
-+	
-+	while (--buffers) {
-+		buf->info.desc.pbuf = PHYSADDR(&buf->data);
-+		buf->info.desc.cntinfo = cntinfo;
-+		buf->info.cnt = 0;
-+		prev = buf;
-+		buf = (hal2_buf_t*) get_zeroed_page(GFP_KERNEL);
-+		if (!buf) {
-+			printk("HAL2: Not enough memory for DMA buffer.\n");
-+			buf = codec->head;
-+			while (buf) {
-+				prev = buf;
-+				free_page((unsigned long) buf);
-+				buf = prev->info.next;
-+			}
-+			return -ENOMEM;
-+		}
-+		prev->info.next = buf;
-+		prev->info.desc.pnext = PHYSADDR(buf);
-+		/* The PBUS can prolly not read this stuff when it's in
-+		 * the cache so we have to flush it back to main memory
-+		 */
-+		dma_cache_wback_inv((unsigned long) prev, PAGE_SIZE);
-+	}
-+	buf->info.desc.pbuf = PHYSADDR(&buf->data);
-+	buf->info.desc.cntinfo = cntinfo;
-+	buf->info.cnt = 0;
-+	buf->info.next = codec->head;
-+	buf->info.desc.pnext = PHYSADDR(codec->head);
-+	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
-+	
-+	return 0;
-+}
-+
-+#define hal2_free_dac_dmabuf(hal2)	hal2_free_dmabuf(hal2, 1)
-+#define hal2_free_adc_dmabuf(hal2)	hal2_free_dmabuf(hal2, 0)
-+static void hal2_free_dmabuf(hal2_card_t *hal2, int is_dac)
-+{
-+	hal2_buf_t *buf, *next;
-+	hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc;
-+
-+	if (!codec->head)
-+		return;
-+	
-+	buf = codec->head->info.next;
-+	codec->head->info.next = NULL;
-+	while (buf) {
-+		next = buf->info.next;
-+		free_page((unsigned long) buf);
-+		buf = next;
-+	}
-+	codec->head = codec->tail = NULL;
-+}
-+
-+/* 
-+ * Add 'count' bytes to 'buffer' from DMA ring buffers. Return number of
-+ * bytes added or -EFAULT if copy_from_user failed.
-+ */
-+static int hal2_get_buffer(hal2_card_t *hal2, char *buffer, int count)
-+{
-+	unsigned long flags;
-+	int size, ret = 0;
-+	hal2_codec_t *adc = &hal2->adc;
-+	
-+	spin_lock_irqsave(&adc->lock, flags);
-+	
-+	DEBUG("getting %d bytes ", count);
-+
-+	/* enable DMA stream if there are no data */
-+	if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) &&
-+	    adc->tail->info.cnt == 0)
-+		hal2_start_adc(hal2);
-+
-+	DEBUG("... ");
-+
-+	while (adc->tail->info.cnt > 0 && count > 0) {
-+		size = min(adc->tail->info.cnt, count);
-+		spin_unlock_irqrestore(&adc->lock, flags);
-+
-+		if (copy_to_user(buffer, &adc->tail->data[H2_BUFFER_SIZE-size],
-+				 size)) {
-+			ret = -EFAULT;
-+			goto out;
-+		}
-+
-+		spin_lock_irqsave(&adc->lock, flags);
-+		
-+		adc->tail->info.cnt -= size;
-+		/* buffer is empty, update tail pointer */
-+		if (adc->tail->info.cnt == 0) {
-+			adc->tail->info.desc.cntinfo = HPCDMA_XIE |
-+						       H2_BUFFER_SIZE;
-+			dma_cache_wback_inv((unsigned long) adc->tail,
-+					    sizeof(struct hpc_dma_desc));
-+			adc->tail = adc->tail->info.next;
-+			/* enable DMA stream again if needed */
-+			if (!(adc->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT))
-+				hal2_start_adc(hal2);
-+
-+		}
-+		buffer += size;
-+		ret += size;
-+		count -= size;
-+
-+		DEBUG("(%d) ", size);
-+	}
-+	spin_unlock_irqrestore(&adc->lock, flags);
-+out:	
-+	DEBUG("\n");
-+	
-+	return ret;
-+} 
-+
-+/* 
-+ * Add 'count' bytes from 'buffer' to DMA ring buffers. Return number of
-+ * bytes added or -EFAULT if copy_from_user failed.
-+ */
-+static int hal2_add_buffer(hal2_card_t *hal2, char *buffer, int count)
-+{
-+	unsigned long flags;
-+	int size, ret = 0;
-+	hal2_codec_t *dac = &hal2->dac;
-+	
-+	spin_lock_irqsave(&dac->lock, flags);
-+	
-+	DEBUG("adding %d bytes ", count);
-+
-+	while (dac->head->info.cnt == 0 && count > 0) {
-+		size = min((int)H2_BUFFER_SIZE, count);
-+		spin_unlock_irqrestore(&dac->lock, flags);
-+		
-+		if (copy_from_user(dac->head->data, buffer, size)) {
-+			ret = -EFAULT;
-+			goto out;
-+		}
-+		spin_lock_irqsave(&dac->lock, flags);
-+
-+		dac->head->info.desc.cntinfo = size | HPCDMA_XIE;
-+		dac->head->info.cnt = size;
-+		dma_cache_wback_inv((unsigned long) dac->head, 
-+				    size + PAGE_SIZE - H2_BUFFER_SIZE);
-+		buffer += size;
-+		ret += size;
-+		count -= size;
-+		dac->head = dac->head->info.next;
-+
-+		DEBUG("(%d) ", size);
-+	}
-+	if (!(dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) && ret > 0)
-+		hal2_start_dac(hal2);
-+	
-+	spin_unlock_irqrestore(&dac->lock, flags);
-+out:	
-+	DEBUG("\n");
-+	
-+	return ret;
-+}
-+
-+#define hal2_reset_dac_pointer(hal2)	hal2_reset_pointer(hal2, 1)
-+#define hal2_reset_adc_pointer(hal2)	hal2_reset_pointer(hal2, 0)
-+static void hal2_reset_pointer(hal2_card_t *hal2, int is_dac)
-+{
-+	hal2_codec_t *codec = (is_dac) ? &hal2->dac : &hal2->adc;
-+	
-+	DEBUG("hal2_reset_pointer\n");
-+
-+	codec->tail = codec->head;
-+	do {
-+		codec->tail->info.desc.cntinfo = HPCDMA_XIE | (is_dac) ? 
-+						 HPCDMA_EOX : H2_BUFFER_SIZE;
-+		codec->tail->info.cnt = 0;
-+		dma_cache_wback_inv((unsigned long) codec->tail, 
-+				    sizeof(struct hpc_dma_desc));
-+		codec->tail = codec->tail->info.next;
-+	} while (codec->tail != codec->head);
-+}
-+
-+static int hal2_sync_dac(hal2_card_t *hal2)
-+{
-+	DECLARE_WAITQUEUE(wait, current);
-+	hal2_codec_t *dac = &hal2->dac;
-+	int ret = 0;
-+	signed long timeout = 1000 * H2_BUFFER_SIZE * 2 * dac->voices *
-+			      HZ / dac->sample_rate / 900;
-+
-+	down(&dac->sem);
-+	
-+	while (dac->pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_ISACT) {
-+		add_wait_queue(&dac->dma_wait, &wait);
-+		set_current_state(TASK_INTERRUPTIBLE);
-+		if (!schedule_timeout(timeout))
-+			/* We may get bogus timeout when system is 
-+			 * heavily loaded */
-+			if (dac->tail->info.cnt) {
-+				printk("HAL2: timeout...\n");
-+				ret = -ETIME;
-+			}
-+		if (signal_pending(current))
-+			ret = -ERESTARTSYS;
-+		if (ret) {
-+			hal2_stop_dac(hal2);
-+			hal2_reset_dac_pointer(hal2);
-+		}
-+		remove_wait_queue(&dac->dma_wait, &wait);
-+	}
-+
-+	up(&dac->sem);
-+	
-+	return ret;
-+}
-+
-+static int hal2_write_mixer(hal2_card_t *hal2, int index, int vol)
-+{
-+	unsigned int l, r;
-+
-+	DEBUG_MIX("mixer %d write\n", index);
-+	
-+	if (index >= SOUND_MIXER_NRDEVICES || !mixtable[index].avail)
-+		return -EINVAL;
-+
-+	r = (vol >> 8) & 0xff;
-+	if (r > 100)
-+		r = 100;
-+	l = vol & 0xff;
-+	if (l > 100)
-+		l = 100;
-+	
-+	hal2->mixer.volume[mixtable[index].idx] = l | (r << 8);
-+
-+	switch (mixtable[index].idx) {
-+	case H2_MIX_OUTPUT_ATT: {
-+
-+		DEBUG_MIX("output attenuator %d,%d\n", l, r);
-+
-+		if (r | l) {
-+			unsigned int tmp = hal2_i_look32(hal2, H2I_DAC_C2); 
-+		
-+			tmp &= ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
-+
-+			/* Attenuator has five bits */
-+			l = (31 * (100 - l) / 99);
-+			r = (31 * (100 - r) / 99);
-+			
-+			DEBUG_MIX("left: %d, right %d\n", l, r);
-+
-+			tmp |= (l << H2I_C2_L_ATT_SHIFT) & H2I_C2_L_ATT_M;
-+			tmp |= (r << H2I_C2_R_ATT_SHIFT) & H2I_C2_R_ATT_M;
-+			hal2_i_write32(hal2, H2I_DAC_C2, tmp);
-+		} else 
-+			hal2_i_setbit32(hal2, H2I_DAC_C2, H2I_C2_MUTE);
-+	}
-+	case H2_MIX_INPUT_GAIN: {
-+		/* TODO */
-+	}
-+	}
-+	return 0;
-+}
-+
-+static void hal2_init_mixer(hal2_card_t *hal2)
-+{
-+	int i;
-+
-+	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-+		hal2_write_mixer(hal2, i, 100 | (100 << 8));
-+		
-+}
-+
-+static int hal2_mixer_ioctl(hal2_card_t *hal2, unsigned int cmd, 
-+			    unsigned long arg)
-+{
-+	int val;
-+
-+        if (cmd == SOUND_MIXER_INFO) {
-+		mixer_info info;
-+		
-+		strncpy(info.id, hal2str, sizeof(info.id));
-+		strncpy(info.name, hal2str, sizeof(info.name));
-+		info.modify_counter = hal2->mixer.modcnt;
-+		if (copy_to_user((void *)arg, &info, sizeof(info)))
-+			return -EFAULT;
-+		return 0;
-+	}
-+	if (cmd == SOUND_OLD_MIXER_INFO) {
-+		_old_mixer_info info;
-+		
-+		strncpy(info.id, hal2str, sizeof(info.id));
-+		strncpy(info.name, hal2str, sizeof(info.name));
-+		if (copy_to_user((void *)arg, &info, sizeof(info)))
-+			return -EFAULT;
-+		return 0;
-+	}
-+	if (cmd == OSS_GETVERSION)
-+		return put_user(SOUND_VERSION, (int *)arg);
-+
-+	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
-+                return -EINVAL;
-+
-+        if (_IOC_DIR(cmd) == _IOC_READ) {
-+                switch (_IOC_NR(cmd)) {
-+		/* Give the current record source */
-+		case SOUND_MIXER_RECSRC:
-+			val = 0;	/* FIXME */
-+			break;
-+		/* Give the supported mixers, all of them support stereo */
-+                case SOUND_MIXER_DEVMASK:
-+                case SOUND_MIXER_STEREODEVS: {
-+			int i;
-+			
-+			for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-+				if (mixtable[i].avail)
-+					val |= 1 << i;
-+			break;
-+			}
-+		/* Arg contains a bit for each supported recording source */
-+                case SOUND_MIXER_RECMASK:
-+			val = 0;
-+			break;
-+                case SOUND_MIXER_CAPS:
-+			val = 0;
-+			break;
-+		/* Read a specific mixer */
-+		default: {
-+			int i = _IOC_NR(cmd);
-+			
-+			if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-+				return -EINVAL;
-+			val = hal2->mixer.volume[mixtable[i].idx];
-+			break;
-+			}
-+		}
-+		return put_user(val, (int *)arg);
-+	}
-+	
-+        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
-+		return -EINVAL;
-+	
-+	hal2->mixer.modcnt++;
-+
-+	if (get_user(val, (int *)arg))
-+		return -EFAULT;
-+
-+	switch (_IOC_NR(cmd)) {
-+	/* Arg contains a bit for each recording source */
-+	case SOUND_MIXER_RECSRC:
-+		return 0;	/* FIXME */
-+	default:
-+		return hal2_write_mixer(hal2, _IOC_NR(cmd), val);
-+	}
-+
-+	return 0;
-+}
-+
-+static int hal2_open_mixdev(struct inode *inode, struct file *file)
-+{
-+	hal2_card_t *hal2 = hal2_mixer_find_card(MINOR(inode->i_rdev));
-+
-+	if (hal2) {
-+		file->private_data = hal2;
-+		return 0;
-+	}
-+	return -ENODEV;
-+}
-+
-+static int hal2_release_mixdev(struct inode *inode, struct file *file)
-+{
-+	return 0;
-+}
-+
-+static int hal2_ioctl_mixdev(struct inode *inode, struct file *file,
-+			     unsigned int cmd, unsigned long arg)
-+{
-+	return hal2_mixer_ioctl((hal2_card_t *)file->private_data, cmd, arg);
-+}
-+
-+
-+static int hal2_ioctl(struct inode *inode, struct file *file, 
-+		      unsigned int cmd, unsigned long arg)
-+{
-+	int val;
-+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
-+
-+	switch (cmd) {
-+	case OSS_GETVERSION:
-+		return put_user(SOUND_VERSION, (int *)arg);
-+		
-+	case SNDCTL_DSP_SYNC:
-+		if (file->f_mode & FMODE_WRITE)
-+			return hal2_sync_dac(hal2);
-+		return 0;
-+		
-+	case SNDCTL_DSP_SETDUPLEX:
-+		return 0;
-+
-+	case SNDCTL_DSP_GETCAPS:
-+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_MULTI, (int *)arg);
-+		
-+	case SNDCTL_DSP_RESET:
-+		if (file->f_mode & FMODE_READ) {
-+			hal2_stop_adc(hal2);
-+			hal2_reset_adc_pointer(hal2);
-+		}
-+		if (file->f_mode & FMODE_WRITE) {
-+			hal2_stop_dac(hal2);
-+			hal2_reset_dac_pointer(hal2);
-+		}
-+		return 0;
-+
-+ 	case SNDCTL_DSP_SPEED:
-+		if (get_user(val, (int *)arg))
-+			return -EFAULT;
-+		if (file->f_mode & FMODE_READ) {
-+			hal2_stop_adc(hal2);
-+			val = hal2_compute_rate(&hal2->adc, val);
-+			hal2->adc.sample_rate = val;
-+			hal2_set_adc_rate(hal2);
-+		}
-+		if (file->f_mode & FMODE_WRITE) {
-+			hal2_stop_dac(hal2);
-+			val = hal2_compute_rate(&hal2->dac, val);
-+			hal2->dac.sample_rate = val;
-+			hal2_set_dac_rate(hal2);
-+		}
-+		return put_user(val, (int *)arg);
-+		
-+	case SNDCTL_DSP_STEREO:
-+		if (get_user(val, (int *)arg))
-+			return -EFAULT;
-+		if (file->f_mode & FMODE_READ) {
-+			hal2_stop_adc(hal2);
-+			hal2->adc.voices = (val) ? 2 : 1;
-+			hal2_setup_adc(hal2);
-+		}
-+		if (file->f_mode & FMODE_WRITE) {
-+			hal2_stop_dac(hal2);
-+			hal2->dac.voices = (val) ? 2 : 1;
-+			hal2_setup_dac(hal2);
-+                }
-+		return 0;
-+
-+	case SNDCTL_DSP_CHANNELS:
-+		if (get_user(val, (int *)arg))
-+			return -EFAULT;
-+		if (val != 0) {
-+			if (file->f_mode & FMODE_READ) {
-+				hal2_stop_adc(hal2);
-+				hal2->adc.voices = (val == 1) ? 1 : 2;
-+				hal2_setup_adc(hal2);
-+			}
-+			if (file->f_mode & FMODE_WRITE) {
-+				hal2_stop_dac(hal2);
-+				hal2->dac.voices = (val == 1) ? 1 : 2;
-+				hal2_setup_dac(hal2);
-+			}
-+		}
-+		val = -EINVAL;
-+		if (file->f_mode & FMODE_READ)
-+			val = hal2->adc.voices;
-+		if (file->f_mode & FMODE_WRITE)
-+			val = hal2->dac.voices;
-+		return put_user(val, (int *)arg);
-+		
-+	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-+                return put_user(H2_SUPPORTED_FORMATS, (int *)arg);
-+		
-+	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-+		if (get_user(val, (int *)arg))
-+			return -EFAULT;
-+		if (val != AFMT_QUERY) {
-+			if (!(val & H2_SUPPORTED_FORMATS))
-+				return -EINVAL;
-+			if (file->f_mode & FMODE_READ) {
-+				hal2_stop_adc(hal2);
-+				hal2->adc.format = val;
-+				hal2_setup_adc(hal2);
-+			}
-+			if (file->f_mode & FMODE_WRITE) {
-+				hal2_stop_dac(hal2);
-+				hal2->dac.format = val;
-+				hal2_setup_dac(hal2);
-+			}
-+		} else {
-+			val = -EINVAL;
-+			if (file->f_mode & FMODE_READ)
-+				val = hal2->adc.format;
-+			if (file->f_mode & FMODE_WRITE)
-+				val = hal2->dac.format;
-+		}
-+		return put_user(val, (int *)arg);
-+		
-+	case SNDCTL_DSP_POST:
-+		return 0;
-+
-+	case SNDCTL_DSP_GETOSPACE: {
-+		unsigned long flags;
-+		audio_buf_info info;
-+		hal2_buf_t *buf;
-+		hal2_codec_t *dac = &hal2->dac;
-+		
-+		if (!(file->f_mode & FMODE_WRITE))
-+			return -EINVAL;
-+		
-+		spin_lock_irqsave(&dac->lock, flags);
-+		info.fragments = 0;
-+		buf = dac->head;
-+		while (buf->info.cnt == 0 && buf != dac->tail) {
-+			info.fragments++;
-+			buf = buf->info.next;
-+		}
-+		spin_unlock_irqrestore(&dac->lock, flags);
-+		
-+		info.fragstotal = obuffers;
-+		info.fragsize = H2_BUFFER_SIZE;
-+                info.bytes = info.fragsize * info.fragments;
-+
-+		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-+	}
-+			   
-+	case SNDCTL_DSP_GETISPACE: {
-+		unsigned long flags;
-+		audio_buf_info info;
-+		hal2_buf_t *buf;
-+		hal2_codec_t *adc = &hal2->adc;
-+			
-+		if (!(file->f_mode & FMODE_READ))
-+			return -EINVAL;
-+		
-+		spin_lock_irqsave(&adc->lock, flags);
-+		info.fragments = 0;
-+		info.bytes = 0;
-+		buf = adc->tail;
-+		while (buf->info.cnt > 0 && buf != adc->head) {
-+			info.fragments++;
-+			info.bytes += buf->info.cnt;
-+			buf = buf->info.next;
-+		}
-+		spin_unlock_irqrestore(&adc->lock, flags);
-+
-+		info.fragstotal = ibuffers;
-+		info.fragsize = H2_BUFFER_SIZE;
-+		
-+		return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-+	}
-+
-+	case SNDCTL_DSP_NONBLOCK:
-+		file->f_flags |= O_NONBLOCK;
-+		return 0;
-+		
-+	case SNDCTL_DSP_GETBLKSIZE:
-+		return put_user(H2_BUFFER_SIZE, (int *)arg);
-+	
-+	case SNDCTL_DSP_SETFRAGMENT:
-+		return 0;
-+
-+	case SOUND_PCM_READ_RATE:
-+		val = -EINVAL;
-+		if (file->f_mode & FMODE_READ)
-+			val = hal2->adc.sample_rate;
-+		if (file->f_mode & FMODE_WRITE)
-+			val = hal2->dac.sample_rate;
-+		return put_user(val, (int *)arg);
-+
-+	case SOUND_PCM_READ_CHANNELS:
-+		val = -EINVAL;
-+		if (file->f_mode & FMODE_READ)
-+			val = hal2->adc.voices;
-+		if (file->f_mode & FMODE_WRITE)
-+			val = hal2->dac.voices;
-+		return put_user(val, (int *)arg);
-+
-+	case SOUND_PCM_READ_BITS:
-+		val = 16;
-+		return put_user(val, (int *)arg);
-+	}
-+	
-+	return hal2_mixer_ioctl(hal2, cmd, arg);
-+}
-+
-+static ssize_t hal2_read(struct file *file, char *buffer,
-+			 size_t count, loff_t *ppos)
-+{
-+	ssize_t err;
-+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
-+	hal2_codec_t *adc = &hal2->adc;
-+
-+	if (count == 0)
-+		return 0;
-+	if (ppos != &file->f_pos)
-+		return -ESPIPE;
-+	
-+	down(&adc->sem);
-+	
-+	if (file->f_flags & O_NONBLOCK) {
-+		err = hal2_get_buffer(hal2, buffer, count);
-+		err = err == 0 ? -EAGAIN : err;
-+	} else {
-+		do {
-+			/* ~10% longer */
-+			signed long timeout = 1000 * H2_BUFFER_SIZE *
-+				2 * adc->voices * HZ / adc->sample_rate / 900;
-+			DECLARE_WAITQUEUE(wait, current);
-+			ssize_t cnt = 0;
-+			
-+			err = hal2_get_buffer(hal2, buffer, count);
-+			if (err > 0) {
-+				count -= err;
-+				cnt += err;
-+				buffer += err;
-+				err = cnt;
-+			}
-+			if (count > 0 && err >= 0) {
-+				add_wait_queue(&adc->dma_wait, &wait);
-+				set_current_state(TASK_INTERRUPTIBLE);
-+				/* Well, it is possible, that interrupt already
-+				 * arrived. Hmm, shit happens, we have one more
-+				 * buffer filled ;) */
-+				if (!schedule_timeout(timeout))
-+					/* We may get bogus timeout when system
-+					 * is heavily loaded */
-+					if (!adc->tail->info.cnt) {
-+						printk("HAL2: timeout...\n");
-+						hal2_stop_adc(hal2);
-+						hal2_reset_adc_pointer(hal2);
-+						err = -EAGAIN;
-+					}
-+				if (signal_pending(current))
-+					err = -ERESTARTSYS;
-+				remove_wait_queue(&adc->dma_wait, &wait);
-+			}
-+		} while (count > 0 && err >= 0);
-+	
-+	}
-+	
-+	up(&adc->sem);
-+	
-+	return err;
-+}
-+
-+static ssize_t hal2_write(struct file *file, const char *buffer,
-+			  size_t count, loff_t *ppos)
-+{
-+	ssize_t err;
-+	char *buf = (char*) buffer;
-+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
-+	hal2_codec_t *dac = &hal2->dac;
-+
-+	if (count == 0)
-+		return 0;
-+	if (ppos != &file->f_pos)
-+		return -ESPIPE;
-+
-+	down(&dac->sem);
-+
-+	if (file->f_flags & O_NONBLOCK) {
-+		err = hal2_add_buffer(hal2, buf, count);
-+		err = err == 0 ? -EAGAIN : err;
-+	} else {
-+		do {
-+			/* ~10% longer */
-+			signed long timeout = 1000 * H2_BUFFER_SIZE *
-+				2 * dac->voices * HZ / dac->sample_rate / 900;
-+			DECLARE_WAITQUEUE(wait, current);
-+			ssize_t cnt = 0;
-+			
-+			err = hal2_add_buffer(hal2, buf, count);
-+			if (err > 0) {
-+				count -= err;
-+				cnt += err;
-+				buf += err;
-+				err = cnt;
-+			}
-+			if (count > 0 && err >= 0) {
-+				add_wait_queue(&dac->dma_wait, &wait);
-+				set_current_state(TASK_INTERRUPTIBLE);
-+				/* Well, it is possible, that interrupt already
-+				 * arrived. Hmm, shit happens, we have one more
-+				 * buffer free ;) */
-+				if (!schedule_timeout(timeout))
-+					/* We may get bogus timeout when system
-+					 * is heavily loaded */
-+					if (dac->head->info.cnt) {
-+						printk("HAL2: timeout...\n");
-+						hal2_stop_dac(hal2);
-+						hal2_reset_dac_pointer(hal2);
-+						err = -EAGAIN;
-+					}
-+				if (signal_pending(current))
-+					err = -ERESTARTSYS;
-+				remove_wait_queue(&dac->dma_wait, &wait);
-+			}
-+		} while (count > 0 && err >= 0);
-+	}
-+	
-+	up(&dac->sem);
-+
-+	return err;
-+}
-+
-+static unsigned int hal2_poll(struct file *file, struct poll_table_struct *wait)
-+{
-+	unsigned long flags;
-+	unsigned int mask = 0;
-+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
-+
-+	if (file->f_mode & FMODE_READ) {
-+		hal2_codec_t *adc = &hal2->adc;
-+		
-+		poll_wait(file, &hal2->adc.dma_wait, wait);
-+		spin_lock_irqsave(&adc->lock, flags);
-+		if (adc->tail->info.cnt > 0)
-+			mask |= POLLIN;
-+		spin_unlock_irqrestore(&adc->lock, flags);
-+	}
-+	
-+	if (file->f_mode & FMODE_WRITE) {
-+		hal2_codec_t *dac = &hal2->dac;
-+		
-+		poll_wait(file, &dac->dma_wait, wait);
-+		spin_lock_irqsave(&dac->lock, flags);
-+		if (dac->head->info.cnt == 0)
-+			mask |= POLLOUT;
-+		spin_unlock_irqrestore(&dac->lock, flags);
-+	}
-+	
-+	return mask;
-+}
-+
-+static int hal2_open(struct inode *inode, struct file *file)
-+{
-+	int err;
-+	hal2_card_t *hal2 = hal2_dsp_find_card(MINOR(inode->i_rdev));
-+
-+	DEBUG("opening audio device.\n");
-+
-+	if (!hal2) {
-+		printk("HAL2: Whee?! Open door and go away!\n");
-+		return -ENODEV;
-+	}
-+	file->private_data = hal2;
-+
-+	if (file->f_mode & FMODE_READ) {
-+		if (hal2->adc.usecount)
-+			return -EBUSY;
-+		
-+		/* OSS spec wanted us to use 8 bit, 8 kHz mono by default,
-+		 * but HAL2 can't do 8bit audio */
-+		hal2->adc.format = AFMT_S16_BE;
-+		hal2->adc.voices = 1;
-+		hal2->adc.sample_rate = hal2_compute_rate(&hal2->adc, 8000);
-+		hal2_set_adc_rate(hal2);
-+
-+		/* alloc DMA buffers */
-+		err = hal2_alloc_adc_dmabuf(hal2);
-+		if (err)
-+			return err;
-+		hal2_setup_adc(hal2);
-+
-+		hal2->adc.usecount++;
-+	}
-+
-+	if (file->f_mode & FMODE_WRITE) {
-+		if (hal2->dac.usecount)
-+			return -EBUSY;
-+
-+		hal2->dac.format = AFMT_S16_BE;
-+		hal2->dac.voices = 1;
-+		hal2->dac.sample_rate = hal2_compute_rate(&hal2->dac, 8000);
-+		hal2_set_dac_rate(hal2);
-+
-+		/* alloc DMA buffers */
-+		err = hal2_alloc_dac_dmabuf(hal2);
-+		if (err)
-+			return err;
-+		hal2_setup_dac(hal2);
-+		
-+		hal2->dac.usecount++;
-+	}
-+	
-+	return 0;
-+}
-+
-+static int hal2_release(struct inode *inode, struct file *file)
-+{
-+	hal2_card_t *hal2 = (hal2_card_t *) file->private_data;
-+
-+	if (file->f_mode & FMODE_READ) {
-+		hal2_stop_adc(hal2);
-+		hal2_free_adc_dmabuf(hal2);
-+		hal2->adc.usecount--;
-+	}
-+
-+	if (file->f_mode & FMODE_WRITE) {
-+		hal2_sync_dac(hal2);
-+		hal2_free_dac_dmabuf(hal2);
-+		hal2->dac.usecount--;
-+	}
-+
-+	return 0;
-+}
-+
-+static struct file_operations hal2_audio_fops = {
-+	owner:		THIS_MODULE,
-+	llseek:		no_llseek,
-+	read:		hal2_read,
-+	write:		hal2_write,
-+	poll:		hal2_poll,
-+	ioctl:		hal2_ioctl,
-+	open:		hal2_open,
-+	release:	hal2_release,
-+};
-+
-+static struct file_operations hal2_mixer_fops = {
-+	owner:		THIS_MODULE,
-+	llseek:		no_llseek,
-+	ioctl:		hal2_ioctl_mixdev,
-+	open:		hal2_open_mixdev,
-+	release:	hal2_release_mixdev,
-+};
-+
-+static int hal2_request_irq(hal2_card_t *hal2, int irq)
-+{
-+	unsigned long flags;
-+	int ret = 0;
-+
-+	save_and_cli(flags);
-+	if (request_irq(irq, hal2_interrupt, SA_SHIRQ, hal2str, hal2)) {
-+		printk(KERN_ERR "HAL2: Can't get irq %d\n", irq);
-+		ret = -EAGAIN;
-+	}
-+	restore_flags(flags);
-+	return ret;
-+}
-+
-+static int hal2_alloc_resources(hal2_card_t *hal2, struct hpc3_regs *hpc3)
-+{
-+	hal2_pbus_t *pbus;
-+
-+	pbus = &hal2->dac.pbus;
-+	pbus->pbusnr = 0;
-+	pbus->pbus = &hpc3->pbdma[pbus->pbusnr];
-+	/* The spec says that we should write 0x08248844 but that's WRONG. HAL2
-+	 * does 8 bit DMA, not 16 bit even if it generates 16 bit audio. */
-+	hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844;	/* Magic :-) */
-+
-+	pbus = &hal2->adc.pbus;
-+	pbus->pbusnr = 1;
-+	pbus->pbus = &hpc3->pbdma[pbus->pbusnr];
-+	hpc3->pbus_dmacfgs[pbus->pbusnr][0] = 0x08208844;	/* Magic :-) */
-+
-+	return hal2_request_irq(hal2, SGI_HPCDMA_IRQ);
-+}
-+
-+static void hal2_init_codec(hal2_codec_t *codec)
-+{
-+	init_waitqueue_head(&codec->dma_wait);
-+	init_MUTEX(&codec->sem);
-+	spin_lock_init(&codec->lock);
-+}
-+
-+static void hal2_free_resources(hal2_card_t *hal2)
-+{
-+	free_irq(SGI_HPCDMA_IRQ, hal2);
-+}
-+
-+static int hal2_detect(hal2_card_t *hal2)
-+{
-+	unsigned short board, major, minor;
-+	unsigned short rev;
-+
-+	/* reset HAL2 */
-+	hal2_isr_write(hal2, 0);
-+
-+	/* release reset */
-+	hal2_isr_write(hal2, H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N);
-+
-+	hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); 
-+
-+	if ((rev = hal2_rev_look(hal2)) & H2_REV_AUDIO_PRESENT) {
-+		DEBUG("HAL2: no device detected, rev: 0x%04hx\n", rev);
-+		return -ENODEV;
-+	}
-+
-+	board = (rev & H2_REV_BOARD_M) >> 12;
-+	major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
-+	minor = (rev & H2_REV_MINOR_CHIP_M);
-+
-+	printk("SGI HAL2 Processor revision %i.%i.%i detected\n",
-+	       board, major, minor);
-+
-+	if (board != 4 || major != 1 || minor != 0) 
-+		printk( "Other revision than 4.1.0 detected. "
-+			"Your card is probably unsupported\n");
-+
-+	return 0;
-+}
-+
-+static int hal2_init_card(hal2_card_t **phal2, struct hpc3_regs *hpc3,
-+			  unsigned long hpc3_base)
-+{
-+	int ret = 0;
-+	hal2_card_t *hal2;
-+	
-+	hal2 = (hal2_card_t *) kmalloc(sizeof(hal2_card_t), GFP_KERNEL);
-+	if (!hal2)
-+		return -ENOMEM;
-+	memset(hal2, 0, sizeof(hal2_card_t));
-+
-+	hal2->ctl_regs = (hal2_ctl_regs_t *) KSEG1ADDR(hpc3_base + H2_CTL_PIO);
-+	hal2->aes_regs = (hal2_aes_regs_t *) KSEG1ADDR(hpc3_base + H2_AES_PIO);
-+	hal2->vol_regs = (hal2_vol_regs_t *) KSEG1ADDR(hpc3_base + H2_VOL_PIO);
-+	hal2->syn_regs = (hal2_syn_regs_t *) KSEG1ADDR(hpc3_base + H2_SYN_PIO);
-+
-+	if (hal2_detect(hal2) < 0) {
-+		printk("HAL2 audio processor not found\n");
-+		ret = -ENODEV;
-+		goto fail1;
-+	}
-+
-+	hal2_init_codec(&hal2->dac);
-+	hal2_init_codec(&hal2->adc);
-+
-+	ret = hal2_alloc_resources(hal2, hpc3);
-+	if (ret)
-+		goto fail1;
-+	
-+	hal2_init_mixer(hal2);
-+
-+	hal2->dev_dsp = register_sound_dsp(&hal2_audio_fops, -1);
-+	if (hal2->dev_dsp < 0) {
-+		ret = hal2->dev_dsp;
-+		goto fail2;
-+	}
-+
-+	hal2->dev_mixer = register_sound_mixer(&hal2_mixer_fops, -1);
-+	if (hal2->dev_mixer < 0) {
-+		ret = hal2->dev_mixer;
-+		goto fail3;
-+	}
-+	
-+	*phal2 = hal2;
-+	return 0;
-+fail3:
-+	unregister_sound_dsp(hal2->dev_dsp);
-+fail2:
-+	hal2_free_resources(hal2);
-+fail1:
-+	kfree(hal2);
-+	
-+	return ret;
-+}
-+
-+/* 
-+ * We are assuming only one HAL2 card. If you ever meet machine with more than
-+ * one, tell immediately about it to someone. Preferably to me. --ladis
-+ */
-+static int __init init_hal2(void)
-+{
-+	int i;
-+
-+	for (i = 0; i < MAXCARDS; i++)
-+		hal2_card[i] = NULL;
-+
-+	return hal2_init_card(&hal2_card[0], hpc3c0, HPC3_CHIP0_PBASE);
-+}
-+
-+static void __exit exit_hal2(void)
-+{
-+	int i;
-+	
-+	for (i = 0; i < MAXCARDS; i++)
-+		if (hal2_card[i]) {
-+			hal2_free_resources(hal2_card[i]);
-+			unregister_sound_dsp(hal2_card[i]->dev_dsp);
-+			unregister_sound_mixer(hal2_card[i]->dev_mixer);
-+			kfree(hal2_card[i]);
-+	}
-+}
-+
-+module_init(init_hal2);
-+module_exit(exit_hal2);
-+
-+MODULE_DESCRIPTION("OSS compatible driver for SGI HAL2 audio");
-+MODULE_AUTHOR("Ladislav Michl");
-+MODULE_LICENSE("GPL");
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/sound/oss/hal2.h	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,328 @@
-+#ifndef __HAL2_H
-+#define __HAL2_H
-+
-+/*
-+ *  Driver for HAL2 sound processors
-+ *  Copyright (c) 1999 Ulf Carlsson <ulfc@bun.falkenberg.se>
-+ *  Copyright (c) 2001 Ladislav Michl <ladis@psi.cz>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as 
-+ *  published by the Free Software Foundation.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#include <asm/addrspace.h>
-+#include <asm/sgi/sgihpc.h>
-+#include <linux/spinlock.h>
-+#include <linux/types.h>
-+
-+#define H2_HAL2_BASE		0x58000
-+#define H2_CTL_PIO		(H2_HAL2_BASE + 0 * 0x400)
-+#define H2_AES_PIO		(H2_HAL2_BASE + 1 * 0x400)
-+#define H2_VOL_PIO		(H2_HAL2_BASE + 2 * 0x400)
-+#define H2_SYN_PIO		(H2_HAL2_BASE + 3 * 0x400)
-+
-+/* Indirect status register */
-+
-+#define H2_ISR_TSTATUS		0x01	/* RO: transaction status 1=busy */
-+#define H2_ISR_USTATUS		0x02	/* RO: utime status bit 1=armed */
-+#define H2_ISR_QUAD_MODE	0x04	/* codec mode 0=indigo 1=quad */
-+#define H2_ISR_GLOBAL_RESET_N	0x08	/* chip global reset 0=reset */
-+#define H2_ISR_CODEC_RESET_N	0x10	/* codec/synth reset 0=reset  */
-+
-+/* Revision register */
-+
-+#define H2_REV_AUDIO_PRESENT	0x8000	/* RO: audio present 0=present */
-+#define H2_REV_BOARD_M		0x7000	/* RO: bits 14:12, board revision */
-+#define H2_REV_MAJOR_CHIP_M	0x00F0	/* RO: bits 7:4, major chip revision */
-+#define H2_REV_MINOR_CHIP_M	0x000F	/* RO: bits 3:0, minor chip revision */
-+
-+/* Indirect address register */
-+
-+/*
-+ * Address of indirect internal register to be accessed. A write to this
-+ * register initiates read or write access to the indirect registers in the
-+ * HAL2. Note that there af four indirect data registers for write access to
-+ * registers larger than 16 byte.
-+ */
-+
-+#define H2_IAR_TYPE_M		0xF000	/* bits 15:12, type of functional */
-+					/* block the register resides in */
-+					/* 1=DMA Port */
-+					/* 9=Global DMA Control */
-+					/* 2=Bresenham */
-+					/* 3=Unix Timer */
-+#define H2_IAR_NUM_M		0x0F00	/* bits 11:8 instance of the */
-+					/* blockin which the indirect */
-+					/* register resides */
-+					/* If IAR_TYPE_M=DMA Port: */
-+					/* 1=Synth In */
-+					/* 2=AES In */
-+					/* 3=AES Out */
-+					/* 4=DAC Out */
-+					/* 5=ADC Out */
-+					/* 6=Synth Control */
-+					/* If IAR_TYPE_M=Global DMA Control: */
-+					/* 1=Control */
-+					/* If IAR_TYPE_M=Bresenham: */
-+					/* 1=Bresenham Clock Gen 1 */
-+					/* 2=Bresenham Clock Gen 2 */
-+					/* 3=Bresenham Clock Gen 3 */
-+					/* If IAR_TYPE_M=Unix Timer: */
-+					/* 1=Unix Timer */
-+#define H2_IAR_ACCESS_SELECT	0x0080	/* 1=read 0=write */
-+#define H2_IAR_PARAM		0x000C	/* Parameter Select */
-+#define H2_IAR_RB_INDEX_M	0x0003	/* Read Back Index */
-+					/* 00:word0 */
-+					/* 01:word1 */
-+					/* 10:word2 */
-+					/* 11:word3 */
-+/*
-+ * HAL2 internal addressing
-+ *
-+ * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
-+ * Indirect Data registers. Write the address to the Indirect Address register
-+ * to transfer the data.
-+ *
-+ * We define the H2IR_* to the read address and H2IW_* to the write address and
-+ * H2I_* to be fields in whatever register is referred to.
-+ *
-+ * When we write to indirect registers which are larger than one word (16 bit)
-+ * we have to fill more than one indirect register before writing. When we read
-+ * back however we have to read several times, each time with different Read
-+ * Back Indexes (there are defs for doing this easily).
-+ */
-+
-+/*
-+ * Relay Control
-+ */
-+#define H2I_RELAY_C		0x9100
-+#define H2I_RELAY_C_STATE	0x01		/* state of RELAY pin signal */
-+
-+/* DMA port enable */
-+
-+#define H2I_DMA_PORT_EN		0x9104
-+#define H2I_DMA_PORT_EN_SY_IN	0x01		/* Synth_in DMA port */
-+#define H2I_DMA_PORT_EN_AESRX	0x02		/* AES receiver DMA port */
-+#define H2I_DMA_PORT_EN_AESTX	0x04		/* AES transmitter DMA port */
-+#define H2I_DMA_PORT_EN_CODECTX	0x08		/* CODEC transmit DMA port */
-+#define H2I_DMA_PORT_EN_CODECR	0x10		/* CODEC receive DMA port */
-+
-+#define H2I_DMA_END		0x9108 		/* global dma endian select */
-+#define H2I_DMA_END_SY_IN	0x01		/* Synth_in DMA port */
-+#define H2I_DMA_END_AESRX	0x02		/* AES receiver DMA port */
-+#define H2I_DMA_END_AESTX	0x04		/* AES transmitter DMA port */
-+#define H2I_DMA_END_CODECTX	0x08		/* CODEC transmit DMA port */
-+#define H2I_DMA_END_CODECR	0x10		/* CODEC receive DMA port */
-+						/* 0=b_end 1=l_end */
-+
-+#define H2I_DMA_DRV		0x910C  	/* global PBUS DMA enable */
-+
-+#define H2I_SYNTH_C		0x1104		/* Synth DMA control */
-+
-+#define H2I_AESRX_C		0x1204	 	/* AES RX dma control */
-+
-+#define H2I_C_TS_EN		0x20		/* Timestamp enable */
-+#define H2I_C_TS_FRMT		0x40		/* Timestamp format */
-+#define H2I_C_NAUDIO		0x80		/* Sign extend */
-+
-+/* AESRX CTL, 16 bit */
-+
-+#define H2I_AESTX_C		0x1304		/* AES TX DMA control */
-+#define H2I_AESTX_C_CLKID_SHIFT	3		/* Bresenham Clock Gen 1-3 */
-+#define H2I_AESTX_C_CLKID_M	0x18
-+#define H2I_AESTX_C_DATAT_SHIFT	8		/* 1=mono 2=stereo (3=quad) */
-+#define H2I_AESTX_C_DATAT_M	0x300
-+
-+/* CODEC registers */
-+
-+#define H2I_DAC_C1		0x1404 		/* DAC DMA control, 16 bit */
-+#define H2I_DAC_C2		0x1408		/* DAC DMA control, 32 bit */
-+#define H2I_ADC_C1		0x1504 		/* ADC DMA control, 16 bit */
-+#define H2I_ADC_C2		0x1508		/* ADC DMA control, 32 bit */
-+
-+/* Bits in CTL1 register */
-+
-+#define H2I_C1_DMA_SHIFT	0		/* DMA channel */
-+#define H2I_C1_DMA_M		0x7
-+#define H2I_C1_CLKID_SHIFT	3		/* Bresenham Clock Gen 1-3 */
-+#define H2I_C1_CLKID_M		0x18
-+#define H2I_C1_DATAT_SHIFT	8		/* 1=mono 2=stereo (3=quad) */
-+#define H2I_C1_DATAT_M		0x300
-+
-+/* Bits in CTL2 register */
-+
-+#define H2I_C2_R_GAIN_SHIFT	0		/* right a/d input gain */	
-+#define H2I_C2_R_GAIN_M		0xf	
-+#define H2I_C2_L_GAIN_SHIFT	4		/* left a/d input gain */
-+#define H2I_C2_L_GAIN_M		0xf0
-+#define H2I_C2_R_SEL		0x100		/* right input select */
-+#define H2I_C2_L_SEL		0x200		/* left input select */
-+#define H2I_C2_MUTE		0x400		/* mute */
-+#define H2I_C2_DO1		0x00010000	/* digital output port bit 0 */
-+#define H2I_C2_DO2		0x00020000	/* digital output port bit 1 */
-+#define H2I_C2_R_ATT_SHIFT	18		/* right d/a output - */
-+#define H2I_C2_R_ATT_M		0x007c0000	/* attenuation */
-+#define H2I_C2_L_ATT_SHIFT	23		/* left d/a output - */
-+#define H2I_C2_L_ATT_M		0x0f800000	/* attenuation */
-+
-+#define H2I_SYNTH_MAP_C		0x1104		/* synth dma handshake ctrl */
-+
-+/* Clock generator CTL 1, 16 bit */
-+
-+#define H2I_BRES1_C1		0x2104
-+#define H2I_BRES2_C1		0x2204
-+#define H2I_BRES3_C1		0x2304
-+
-+#define H2I_BRES_C1_SHIFT	0		/* 0=48.0 1=44.1 2=aes_rx */
-+#define H2I_BRES_C1_M		0x03
-+				
-+/* Clock generator CTL 2, 32 bit */
-+
-+#define H2I_BRES1_C2		0x2108
-+#define H2I_BRES2_C2		0x2208
-+#define H2I_BRES3_C2		0x2308
-+
-+#define H2I_BRES_C2_INC_SHIFT	0		/* increment value */
-+#define H2I_BRES_C2_INC_M	0xffff
-+#define H2I_BRES_C2_MOD_SHIFT	16		/* modcontrol value */
-+#define H2I_BRES_C2_MOD_M	0xffff0000	/* modctrl=0xffff&(modinc-1) */
-+
-+/* Unix timer, 64 bit */
-+
-+#define H2I_UTIME		0x3104
-+#define H2I_UTIME_0_LD		0xffff		/* microseconds, LSB's */
-+#define H2I_UTIME_1_LD0		0x0f		/* microseconds, MSB's */
-+#define H2I_UTIME_1_LD1		0xf0		/* tenths of microseconds */
-+#define H2I_UTIME_2_LD		0xffff		/* seconds, LSB's */
-+#define H2I_UTIME_3_LD		0xffff		/* seconds, MSB's */
-+
-+typedef volatile u32 hal2_reg_t;
-+
-+typedef struct stru_hal2_ctl_regs hal2_ctl_regs_t;
-+struct stru_hal2_ctl_regs {
-+	hal2_reg_t _unused0[4];
-+	hal2_reg_t isr;			/* 0x10 Status Register */
-+	hal2_reg_t _unused1[3];
-+	hal2_reg_t rev;			/* 0x20 Revision Register */
-+	hal2_reg_t _unused2[3];
-+	hal2_reg_t iar;			/* 0x30 Indirect Address Register */
-+	hal2_reg_t _unused3[3];
-+	hal2_reg_t idr0;		/* 0x40 Indirect Data Register 0 */
-+	hal2_reg_t _unused4[3];
-+	hal2_reg_t idr1;		/* 0x50 Indirect Data Register 1 */
-+	hal2_reg_t _unused5[3];
-+	hal2_reg_t idr2;		/* 0x60 Indirect Data Register 2 */
-+	hal2_reg_t _unused6[3];
-+	hal2_reg_t idr3;		/* 0x70 Indirect Data Register 3 */
-+};
-+
-+typedef struct stru_hal2_aes_regs hal2_aes_regs_t;
-+struct stru_hal2_aes_regs {
-+	hal2_reg_t rx_stat[2];		/* Status registers */
-+	hal2_reg_t rx_cr[2];		/* Control registers */
-+	hal2_reg_t rx_ud[4];		/* User data window */
-+	hal2_reg_t rx_st[24];		/* Channel status data */
-+	
-+	hal2_reg_t tx_stat[1];		/* Status register */
-+	hal2_reg_t tx_cr[3];		/* Control registers */
-+	hal2_reg_t tx_ud[4];		/* User data window */
-+	hal2_reg_t tx_st[24];		/* Channel status data */
-+};
-+
-+typedef struct stru_hal2_vol_regs hal2_vol_regs_t;
-+struct stru_hal2_vol_regs {
-+	hal2_reg_t right;		/* 0x00 Right volume */
-+	hal2_reg_t left;		/* 0x04 Left volume */
-+};
-+
-+typedef struct stru_hal2_syn_regs hal2_syn_regs_t;
-+struct stru_hal2_syn_regs {
-+	hal2_reg_t _unused0[2];
-+	hal2_reg_t page;		/* DOC Page register */
-+	hal2_reg_t regsel;		/* DOC Register selection */
-+	hal2_reg_t dlow;		/* DOC Data low */
-+	hal2_reg_t dhigh;		/* DOC Data high */
-+	hal2_reg_t irq;			/* IRQ Status */
-+	hal2_reg_t dram;		/* DRAM Access */
-+};
-+
-+/* HAL2 specific structures */
-+
-+typedef struct stru_hal2_pbus hal2_pbus_t;
-+struct stru_hal2_pbus {
-+	struct hpc3_pbus_dmacregs *pbus;
-+	int pbusnr;
-+	unsigned int ctrl;		/* Current state of pbus->pbdma_ctrl */
-+};
-+
-+typedef struct stru_hal2_binfo hal2_binfo_t;
-+typedef struct stru_hal2_buffer hal2_buf_t;
-+struct stru_hal2_binfo {
-+	volatile struct hpc_dma_desc desc;
-+	hal2_buf_t *next;		/* pointer to next buffer */
-+	int cnt;			/* bytes in buffer */
-+};
-+#define H2_BUFFER_SIZE	(PAGE_SIZE - \
-+		((sizeof(hal2_binfo_t) - 1) / 8 + 1) * 8)
-+struct stru_hal2_buffer {
-+	hal2_binfo_t info;
-+	char data[H2_BUFFER_SIZE] __attribute__((aligned(8)));
-+};
-+
-+typedef struct stru_hal2_codec hal2_codec_t;
-+struct stru_hal2_codec {
-+	hal2_buf_t *head;
-+	hal2_buf_t *tail; 
-+	hal2_pbus_t pbus;
-+	unsigned int format;		/* Audio data format */
-+	int voices;			/* mono/stereo */
-+	unsigned int sample_rate;
-+	unsigned int master;		/* Master frequency */
-+	unsigned short mod;		/* MOD value */
-+	unsigned short inc;		/* INC value */
-+
-+	wait_queue_head_t dma_wait;
-+	spinlock_t lock;
-+	struct semaphore sem;
-+
-+	int usecount;			/* recording and playback are 
-+					 * independent */
-+};
-+
-+#define H2_MIX_OUTPUT_ATT	0
-+#define H2_MIX_INPUT_GAIN	1
-+#define H2_MIXERS		2
-+typedef struct stru_hal2_mixer hal2_mixer_t;
-+struct stru_hal2_mixer {
-+	int modcnt;
-+	unsigned int volume[H2_MIXERS];
-+};
-+
-+typedef struct stru_hal2_card hal2_card_t;
-+struct stru_hal2_card {
-+	int dev_dsp;			/* audio device */
-+	int dev_mixer;			/* mixer device */
-+	int dev_midi;			/* midi device */
-+	
-+	hal2_ctl_regs_t *ctl_regs;	/* HAL2 ctl registers */
-+	hal2_aes_regs_t *aes_regs;	/* HAL2 vol registers */
-+	hal2_vol_regs_t *vol_regs;	/* HAL2 aes registers */
-+	hal2_syn_regs_t *syn_regs;	/* HAL2 syn registers */
-+
-+	hal2_codec_t dac;
-+	hal2_codec_t adc;
-+	hal2_mixer_t mixer;
-+};
-+
-+#endif				/* __HAL2_H */
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/sound/oss/harmony.c	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,1307 @@
-+/*
-+ 	drivers/sound/harmony.c 
-+
-+	This is a sound driver for ASP's and Lasi's Harmony sound chip
-+	and is unlikely to be used for anything other than on a HP PA-RISC.
-+
-+	Harmony is found in HP 712s, 715/new and many other GSC based machines.
-+	On older 715 machines you'll find the technically identical chip 
-+	called 'Vivace'. Both Harmony and Vicace are supported by this driver.
-+
-+	Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@linuxcare.com>
-+	Copyright 2000-2002 (c) Helge Deller <deller@gmx.de>
-+	Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
-+	Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
-+
-+				
-+TODO:
-+	- fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to
-+		return the real values
-+	- add private ioctl for selecting line- or microphone input
-+		(only one of them is available at the same time)
-+	- add module parameters
-+	- implement mmap functionality
-+	- implement gain meter ?
-+	- ...
-+*/
-+
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <linux/types.h>
-+#include <linux/mm.h>
-+#include <linux/pci.h>
-+
-+#include <asm/gsc.h>
-+#include <asm/io.h>
-+#include <asm/pgalloc.h>
-+
-+#include "sound_config.h"
-+
-+
-+#define PFX "harmony: "
-+#define HARMONY_VERSION "V0.9a"
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+# define DPRINTK printk 
-+#else
-+# define DPRINTK(x,...)
-+#endif
-+
-+
-+#define MAX_BUFS 10		/* maximum number of rotating buffers */
-+#define HARMONY_BUF_SIZE 4096	/* needs to be a multiple of PAGE_SIZE (4096)! */
-+
-+#define CNTL_C		0x80000000
-+#define	CNTL_ST		0x00000020
-+#define CNTL_44100	0x00000015	/* HARMONY_SR_44KHZ */
-+#define CNTL_8000	0x00000008	/* HARMONY_SR_8KHZ */
-+
-+#define GAINCTL_HE	0x08000000
-+#define GAINCTL_LE	0x04000000
-+#define GAINCTL_SE	0x02000000
-+
-+#define DSTATUS_PN	0x00000200
-+#define DSTATUS_RN	0x00000002
-+
-+#define DSTATUS_IE	0x80000000
-+
-+#define HARMONY_DF_16BIT_LINEAR	0
-+#define HARMONY_DF_8BIT_ULAW	1
-+#define HARMONY_DF_8BIT_ALAW	2
-+
-+#define HARMONY_SS_MONO		0
-+#define HARMONY_SS_STEREO	1
-+
-+#define HARMONY_SR_8KHZ		0x08
-+#define HARMONY_SR_16KHZ	0x09
-+#define HARMONY_SR_27KHZ	0x0A
-+#define HARMONY_SR_32KHZ	0x0B
-+#define HARMONY_SR_48KHZ	0x0E
-+#define HARMONY_SR_9KHZ		0x0F
-+#define HARMONY_SR_5KHZ		0x10
-+#define HARMONY_SR_11KHZ	0x11
-+#define HARMONY_SR_18KHZ	0x12
-+#define HARMONY_SR_22KHZ	0x13
-+#define HARMONY_SR_37KHZ	0x14
-+#define HARMONY_SR_44KHZ	0x15
-+#define HARMONY_SR_33KHZ	0x16
-+#define HARMONY_SR_6KHZ		0x17
-+
-+/*
-+ * Some magics numbers used to auto-detect file formats
-+ */
-+
-+#define HARMONY_MAGIC_8B_ULAW	1
-+#define HARMONY_MAGIC_8B_ALAW	27
-+#define HARMONY_MAGIC_16B_LINEAR 3
-+#define HARMONY_MAGIC_MONO	1
-+#define HARMONY_MAGIC_STEREO	2
-+
-+/*
-+ * Channels Positions in mixer register
-+ */
-+
-+#define GAIN_HE_SHIFT   27
-+#define GAIN_HE_MASK    ( 1 << GAIN_HE_SHIFT) 
-+#define GAIN_LE_SHIFT   26
-+#define GAIN_LE_MASK    ( 1 << GAIN_LE_SHIFT) 
-+#define GAIN_SE_SHIFT   25
-+#define GAIN_SE_MASK    ( 1 << GAIN_SE_SHIFT) 
-+#define GAIN_IS_SHIFT   24
-+#define GAIN_IS_MASK    ( 1 << GAIN_IS_SHIFT) 
-+#define GAIN_MA_SHIFT   20
-+#define GAIN_MA_MASK    ( 0x0f << GAIN_MA_SHIFT) 
-+#define GAIN_LI_SHIFT   16
-+#define GAIN_LI_MASK    ( 0x0f << GAIN_LI_SHIFT) 
-+#define GAIN_RI_SHIFT   12
-+#define GAIN_RI_MASK    ( 0x0f << GAIN_RI_SHIFT) 
-+#define GAIN_LO_SHIFT   6
-+#define GAIN_LO_MASK    ( 0x3f << GAIN_LO_SHIFT) 
-+#define GAIN_RO_SHIFT   0
-+#define GAIN_RO_MASK    ( 0x3f << GAIN_RO_SHIFT) 
-+
-+
-+#define MAX_OUTPUT_LEVEL (GAIN_RO_MASK >> GAIN_RO_SHIFT)
-+#define MAX_INPUT_LEVEL  (GAIN_RI_MASK >> GAIN_RI_SHIFT)
-+#define MAX_VOLUME_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT)
-+
-+/*
-+ * Channels Mask in mixer register
-+ */
-+
-+#define GAIN_TOTAL_SILENCE 0x00F00FFF
-+#define GAIN_DEFAULT       0x0FF00000
-+
-+
-+struct harmony_hpa {
-+	u8	unused000;
-+	u8	id;
-+	u8	teleshare_id;
-+	u8	unused003;
-+	u32	reset;
-+	u32	cntl;
-+	u32	gainctl;
-+	u32	pnxtadd;
-+	u32	pcuradd;
-+	u32	rnxtadd;
-+	u32	rcuradd;
-+	u32	dstatus;
-+	u32	ov;
-+	u32	pio;
-+	u32	unused02c;
-+	u32	unused030[3];
-+	u32	diag;
-+};
-+
-+struct harmony_dev {
-+	int irq;
-+	struct harmony_hpa *hpa;
-+	u32 current_gain;
-+	u8 data_format;		/* HARMONY_DF_xx_BIT_xxx */
-+	u8 sample_rate;		/* HARMONY_SR_xx_KHZ */
-+	u8 stereo_select;	/* HARMONY_SS_MONO or HARMONY_SS_STEREO */
-+	int format_initialized;
-+	u32 dac_rate;		/* 8000 ... 48000 (Hz) */
-+	int suspended_playing;
-+	int suspended_recording;
-+	
-+	int blocked_playing;
-+	int blocked_recording;
-+	
-+	wait_queue_head_t wq_play, wq_record;
-+	int first_filled_play;	/* first buffer containing data (next to play) */
-+	int nb_filled_play; 
-+	int play_offset;
-+	int first_filled_record;
-+	int nb_filled_record;
-+		
-+	int audio_open, mixer_open;
-+	int dsp_unit, mixer_unit;
-+
-+	struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for 
-+					pci_* functions under ccio. */
-+};
-+
-+
-+static struct harmony_dev harmony;
-+
-+
-+/*
-+ * Dynamic sound buffer allocation and DMA memory
-+ */
-+
-+struct harmony_buffer {
-+	unsigned char *addr;
-+	dma_addr_t dma_handle;
-+	int dma_consistent;	/* Zero if pci_alloc_consistent() fails */
-+	int len;
-+};
-+
-+/*
-+ * Harmony memory buffers
-+ */
-+
-+static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
-+
-+
-+#define CHECK_WBACK_INV_OFFSET(b,offset,len) \
-+        do { if (!b.dma_consistent) \
-+		dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
-+	} while (0) 
-+
-+	
-+static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
-+		int buffer_count)
-+{
-+	b->len = buffer_count * HARMONY_BUF_SIZE;
-+	b->addr = pci_alloc_consistent(harmony.fake_pci_dev, 
-+			  b->len, &b->dma_handle);
-+	if (b->addr && b->dma_handle) {
-+		b->dma_consistent = 1;
-+		DPRINTK(KERN_INFO PFX "consistent memory: 0x%lx, played_buf: 0x%lx\n",
-+				(unsigned long)b->dma_handle, (unsigned long)b->addr);
-+	} else {
-+		b->dma_consistent = 0;
-+		/* kmalloc()ed memory will HPMC on ccio machines ! */
-+		b->addr = kmalloc(b->len, GFP_KERNEL);
-+		if (!b->addr) {
-+			printk(KERN_ERR PFX "couldn't allocate memory\n");
-+			return -EBUSY;
-+		}
-+		b->dma_handle = __pa(b->addr);
-+	}
-+	return 0;
-+}
-+
-+static void __exit harmony_free_buffer(struct harmony_buffer *b)
-+{
-+	if (!b->addr)
-+		return;
-+
-+	if (b->dma_consistent)
-+		pci_free_consistent(harmony.fake_pci_dev,
-+				b->len, b->addr, b->dma_handle);
-+	else
-+		kfree(b->addr);
-+
-+	memset(b, 0, sizeof(*b));
-+}
-+
-+
-+
-+/*
-+ * Low-Level sound-chip programming
-+ */
-+
-+static void __inline__ harmony_wait_CNTL(void)
-+{
-+	/* Wait until we're out of control mode */
-+	while (gsc_readl(&harmony.hpa->cntl) & CNTL_C)
-+		/* wait */ ;
-+}
-+
-+
-+static void harmony_update_control(void) 
-+{
-+	u32 default_cntl;
-+	
-+	/* Set CNTL */
-+	default_cntl = (CNTL_C |  		/* The C bit */
-+		(harmony.data_format << 6) |	/* Set the data format */
-+		(harmony.stereo_select << 5) |	/* Stereo select */
-+		(harmony.sample_rate));		/* Set sample rate */
-+	harmony.format_initialized = 1;
-+	
-+	/* initialize CNTL */
-+	gsc_writel(default_cntl, &harmony.hpa->cntl);
-+}
-+
-+static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) 
-+{
-+	harmony.sample_rate = sample_rate;
-+	harmony.data_format = data_format;
-+	harmony.stereo_select = stereo_select;
-+	harmony_update_control();
-+}
-+
-+static void harmony_set_rate(u8 data_rate) 
-+{
-+	harmony.sample_rate = data_rate;
-+	harmony_update_control();
-+}
-+
-+static int harmony_detect_rate(int *freq)
-+{
-+	int newrate;
-+	switch (*freq) {
-+	case 8000:	newrate = HARMONY_SR_8KHZ;	break;
-+	case 16000:	newrate = HARMONY_SR_16KHZ;	break; 
-+	case 27428:	newrate = HARMONY_SR_27KHZ;	break; 
-+	case 32000:	newrate = HARMONY_SR_32KHZ;	break; 
-+	case 48000:	newrate = HARMONY_SR_48KHZ;	break; 
-+	case 9600:	newrate = HARMONY_SR_9KHZ;	break; 
-+	case 5125:	newrate = HARMONY_SR_5KHZ;	break; 
-+	case 11025:	newrate = HARMONY_SR_11KHZ;	break; 
-+	case 18900:	newrate = HARMONY_SR_18KHZ;	break; 
-+	case 22050:	newrate = HARMONY_SR_22KHZ;	break; 
-+	case 37800:	newrate = HARMONY_SR_37KHZ;	break; 
-+	case 44100:	newrate = HARMONY_SR_44KHZ;	break; 
-+	case 33075:	newrate = HARMONY_SR_33KHZ;	break; 
-+	case 6615:	newrate = HARMONY_SR_6KHZ;	break; 
-+	default:	newrate = HARMONY_SR_8KHZ; 
-+			*freq = 8000;			break;
-+	}
-+	return newrate;
-+}
-+
-+static void harmony_set_format(u8 data_format) 
-+{
-+	harmony.data_format = data_format;
-+	harmony_update_control();
-+}
-+
-+static void harmony_set_stereo(u8 stereo_select) 
-+{
-+	harmony.stereo_select = stereo_select;
-+	harmony_update_control();
-+}
-+
-+static void harmony_disable_interrupts(void) 
-+{
-+	harmony_wait_CNTL();
-+	gsc_writel(0, &harmony.hpa->dstatus); 
-+}
-+
-+static void harmony_enable_interrupts(void) 
-+{
-+	harmony_wait_CNTL();
-+	gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); 
-+}
-+
-+/*
-+ * harmony_silence()
-+ *
-+ * This subroutine fills in a buffer starting at location start and
-+ * silences for length bytes.  This references the current
-+ * configuration of the audio format.
-+ *
-+ */
-+
-+static void harmony_silence(struct harmony_buffer *buffer, int start, int length) 
-+{
-+	u8 silence_char;
-+
-+	/* Despite what you hear, silence is different in
-+	   different audio formats.  */
-+	switch (harmony.data_format) {
-+		case HARMONY_DF_8BIT_ULAW:	silence_char = 0x55; break;
-+		case HARMONY_DF_8BIT_ALAW:	silence_char = 0xff; break;
-+		case HARMONY_DF_16BIT_LINEAR:	/* fall through */
-+		default:			silence_char = 0;
-+	}
-+
-+	memset(buffer->addr+start, silence_char, length);
-+}
-+
-+
-+static int harmony_audio_open(struct inode *inode, struct file *file)
-+{
-+	if (harmony.audio_open) 
-+		return -EBUSY;
-+	
-+	harmony.audio_open++;
-+	harmony.suspended_playing = harmony.suspended_recording = 1;
-+	harmony.blocked_playing   = harmony.blocked_recording   = 0;
-+	harmony.first_filled_play = harmony.first_filled_record = 0;
-+	harmony.nb_filled_play    = harmony.nb_filled_record    = 0;
-+	harmony.play_offset = 0;
-+	init_waitqueue_head(&harmony.wq_play);
-+	init_waitqueue_head(&harmony.wq_record);
-+	
-+	/* Start off in a balanced mode. */
-+	harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-+	harmony_update_control();
-+	harmony.format_initialized = 0;
-+
-+	/* Clear out all the buffers and flush to cache */
-+	harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-+	CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-+	
-+	return 0;
-+}
-+
-+/*
-+ * Release (close) the audio device.
-+ */
-+
-+static int harmony_audio_release(struct inode *inode, struct file *file)
-+{
-+	if (!harmony.audio_open) 
-+		return -EBUSY;
-+	
-+	harmony.audio_open--;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Read recorded data off the audio device.
-+ */
-+
-+static ssize_t harmony_audio_read(struct file *file,
-+                                char *buffer,
-+                                size_t size_count,
-+                                loff_t *ppos)
-+{
-+	int total_count = (int) size_count;
-+	int count = 0;
-+	int buf_to_read;
-+
-+	while (count<total_count) {
-+		/* Wait until we're out of control mode */
-+		harmony_wait_CNTL();
-+		
-+		/* Figure out which buffer to fill in */
-+		if (harmony.nb_filled_record <= 2) {
-+			harmony.blocked_recording = 1;
-+		        if (harmony.suspended_recording) {
-+				harmony.suspended_recording = 0;
-+				harmony_enable_interrupts();
-+			}
-+							
-+			interruptible_sleep_on(&harmony.wq_record);
-+			harmony.blocked_recording = 0;
-+		}
-+		
-+		if (harmony.nb_filled_record < 2)
-+			return -EBUSY;
-+		
-+		buf_to_read = harmony.first_filled_record;
-+
-+		/* Copy the page to an aligned buffer */
-+		if (copy_to_user(buffer+count, recorded_buf.addr +
-+				 (HARMONY_BUF_SIZE*buf_to_read),
-+				 HARMONY_BUF_SIZE)) {
-+			count = -EFAULT;
-+			break;
-+		}
-+		
-+		harmony.nb_filled_record--;
-+		harmony.first_filled_record++;
-+		harmony.first_filled_record %= MAX_BUFS;
-+				
-+		count += HARMONY_BUF_SIZE;
-+	}
-+	return count;
-+}
-+
-+
-+
-+
-+/*
-+ * Here is the place where we try to recognize file format.
-+ * Sun/NeXT .au files begin with the string .snd
-+ * At offset 12 is specified the encoding.
-+ * At offset 16 is specified speed rate
-+ * At Offset 20 is specified the numbers of voices
-+ */
-+
-+#define four_bytes_to_u32(start) (file_header[start] << 24)|\
-+                                  (file_header[start+1] << 16)|\
-+                                  (file_header[start+2] << 8)|\
-+                                  (file_header[start+3]);
-+
-+#define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\
-+                                                    
-+
-+static int harmony_format_auto_detect(const char *buffer, int block_size)
-+{
-+	u8 file_header[24];
-+	u32 start_string;
-+	int ret = 0;
-+	
-+	if (block_size>24) {
-+		if (copy_from_user(file_header, buffer, sizeof(file_header)))
-+			ret = -EFAULT;
-+			
-+		start_string = four_bytes_to_u32(0);
-+		
-+		if ((file_header[4]==0) && (start_string==0x2E736E64)) {
-+			u32 format;
-+			u32 nb_voices;
-+			u32 speed;
-+			
-+			format = four_bytes_to_u32(12);
-+			nb_voices = four_bytes_to_u32(20);
-+			speed = four_bytes_to_u32(16);
-+			
-+			switch (format) {
-+			case HARMONY_MAGIC_8B_ULAW:
-+				harmony.data_format = HARMONY_DF_8BIT_ULAW;
-+				break;
-+			case HARMONY_MAGIC_8B_ALAW:
-+				harmony.data_format = HARMONY_DF_8BIT_ALAW;
-+				break;
-+			case HARMONY_MAGIC_16B_LINEAR:
-+				harmony.data_format = HARMONY_DF_16BIT_LINEAR;
-+				break;
-+			default:
-+				harmony_set_control(HARMONY_DF_16BIT_LINEAR,
-+						HARMONY_SR_44KHZ, HARMONY_SS_STEREO);
-+				goto out;
-+			}
-+			switch (nb_voices) {
-+			case HARMONY_MAGIC_MONO:
-+				harmony.stereo_select = HARMONY_SS_MONO;
-+				break;
-+			case HARMONY_MAGIC_STEREO:
-+				harmony.stereo_select = HARMONY_SS_STEREO;
-+				break;
-+			default:
-+				harmony.stereo_select = HARMONY_SS_MONO;
-+				break;
-+			}
-+			harmony_set_rate(harmony_detect_rate(&speed));
-+			harmony.dac_rate = speed;
-+			goto out;
-+		}
-+	}
-+	harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-+out:
-+	return ret;
-+}
-+#undef four_bytes_to_u32
-+
-+
-+static ssize_t harmony_audio_write(struct file *file,
-+                                 const char *buffer,
-+                                 size_t size_count,
-+                                 loff_t *ppos)
-+{
-+	int total_count = (int) size_count;
-+	int count = 0;
-+	int frame_size;
-+	int buf_to_fill;
-+
-+	if (!harmony.format_initialized) {
-+		if (harmony_format_auto_detect(buffer, total_count))
-+			return -EFAULT;
-+	}
-+	
-+	while (count<total_count) {
-+		/* Wait until we're out of control mode */
-+		harmony_wait_CNTL();
-+
-+		/* Figure out which buffer to fill in */
-+		if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) {
-+			harmony.blocked_playing = 1;
-+			interruptible_sleep_on(&harmony.wq_play);
-+			harmony.blocked_playing = 0;
-+		}
-+		if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset)
-+			return -EBUSY;
-+		
-+		
-+		buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); 
-+		if (harmony.play_offset)
-+			buf_to_fill--;
-+		buf_to_fill %= MAX_BUFS;
-+
-+		/* Figure out the size of the frame */
-+		if ((total_count-count) > HARMONY_BUF_SIZE - harmony.play_offset) {
-+			frame_size = HARMONY_BUF_SIZE - harmony.play_offset;
-+		} else {
-+			frame_size = total_count - count;
-+			/* Clear out the buffer, since there we'll only be 
-+			   overlaying part of the old buffer with the new one */
-+			harmony_silence(&played_buf, 
-+				HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset,
-+				HARMONY_BUF_SIZE-frame_size-harmony.play_offset);
-+		}
-+
-+		/* Copy the page to an aligned buffer */
-+		if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, 
-+				   buffer+count, frame_size))
-+			return -EFAULT;
-+		CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), 
-+				frame_size);
-+	
-+		if (!harmony.play_offset)
-+			harmony.nb_filled_play++;
-+		
-+		count += frame_size;
-+		harmony.play_offset += frame_size;
-+		harmony.play_offset %= HARMONY_BUF_SIZE;
-+		if (harmony.suspended_playing && (harmony.nb_filled_play>=4))
-+			harmony_enable_interrupts();
-+	}
-+	
-+	return count;
-+}
-+
-+static unsigned int harmony_audio_poll(struct file *file,
-+                                     struct poll_table_struct *wait)
-+{
-+	unsigned int mask = 0;
-+	
-+	if (file->f_mode & FMODE_READ) {
-+		if (!harmony.suspended_recording)
-+			poll_wait(file, &harmony.wq_record, wait);
-+		if (harmony.nb_filled_record)
-+			mask |= POLLIN | POLLRDNORM;
-+	}
-+
-+	if (file->f_mode & FMODE_WRITE) {
-+		if (!harmony.suspended_playing)
-+			poll_wait(file, &harmony.wq_play, wait);
-+		if (harmony.nb_filled_play)
-+			mask |= POLLOUT | POLLWRNORM;
-+	}
-+
-+	return mask;
-+}
-+
-+static int harmony_audio_ioctl(struct inode *inode,
-+                                struct file *file,
-+				unsigned int cmd,
-+                                unsigned long arg)
-+{
-+	int ival, new_format;
-+	int frag_size, frag_buf;
-+	struct audio_buf_info info;
-+	
-+	switch (cmd) {
-+	case OSS_GETVERSION:
-+		return put_user(SOUND_VERSION, (int *) arg);
-+
-+	case SNDCTL_DSP_GETCAPS:
-+		ival = DSP_CAP_DUPLEX;
-+		return put_user(ival, (int *) arg);
-+
-+	case SNDCTL_DSP_GETFMTS:
-+		ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); 
-+		return put_user(ival, (int *) arg);
-+	
-+	case SNDCTL_DSP_SETFMT:
-+		if (get_user(ival, (int *) arg)) 
-+			return -EFAULT;
-+		if (ival != AFMT_QUERY) {
-+			switch (ival) {
-+			case AFMT_MU_LAW:	new_format = HARMONY_DF_8BIT_ULAW; break;
-+			case AFMT_A_LAW:	new_format = HARMONY_DF_8BIT_ALAW; break;
-+			case AFMT_S16_LE:	/* fall through, but not really supported */
-+			case AFMT_S16_BE:	new_format = HARMONY_DF_16BIT_LINEAR;
-+						ival = AFMT_S16_BE;
-+						break; 
-+			default: {
-+				DPRINTK(KERN_WARNING PFX 
-+					"unsupported sound format 0x%04x requested.\n",
-+					ival);
-+				return -EINVAL;
-+			}
-+			}
-+			harmony_set_format(new_format);
-+		} else {
-+			switch (harmony.data_format) {
-+			case HARMONY_DF_8BIT_ULAW:	ival = AFMT_MU_LAW; break;
-+			case HARMONY_DF_8BIT_ALAW:	ival = AFMT_A_LAW;  break;
-+			case HARMONY_DF_16BIT_LINEAR:	ival = AFMT_U16_BE; break;
-+			default: ival = 0;
-+			}
-+		}
-+		return put_user(ival, (int *) arg);
-+
-+	case SOUND_PCM_READ_RATE:
-+		ival = harmony.dac_rate;
-+		return put_user(ival, (int *) arg);
-+
-+	case SNDCTL_DSP_SPEED:
-+		if (get_user(ival, (int *) arg))
-+			return -EFAULT;
-+		harmony_set_rate(harmony_detect_rate(&ival));
-+		harmony.dac_rate = ival;
-+		return put_user(ival, (int*) arg);
-+
-+	case SNDCTL_DSP_STEREO:
-+		if (get_user(ival, (int *) arg))
-+			return -EFAULT;
-+		if (ival != 0 && ival != 1)
-+			return -EINVAL;
-+		harmony_set_stereo(ival);
-+		return put_user(ival, (int *) arg);
-+
-+	case SNDCTL_DSP_GETBLKSIZE:
-+		ival = HARMONY_BUF_SIZE;
-+		return put_user(ival, (int *) arg);
-+		
-+        case SNDCTL_DSP_NONBLOCK:
-+                file->f_flags |= O_NONBLOCK;
-+                return 0;
-+
-+        case SNDCTL_DSP_RESET:
-+		if (!harmony.suspended_recording) {
-+			/* TODO: stop_recording() */
-+		}
-+		return 0;
-+
-+	case SNDCTL_DSP_SETFRAGMENT:
-+		if (get_user(ival, (int *)arg))
-+			return -EFAULT;
-+		frag_size = ival & 0xffff;
-+		frag_buf = (ival>>16) & 0xffff;
-+		/* TODO: We use hardcoded fragment sizes and numbers for now */
-+		frag_size = 12;  /* 4096 == 2^12 */
-+		frag_buf  = MAX_BUFS;
-+		ival = (frag_buf << 16) + frag_size;
-+		return put_user(ival, (int *) arg);
-+		
-+	case SNDCTL_DSP_GETOSPACE:
-+		if (!(file->f_mode & FMODE_WRITE))
-+			return -EINVAL;
-+		info.fragstotal = MAX_BUFS;
-+                info.fragments = MAX_BUFS - harmony.nb_filled_play;
-+		info.fragsize = HARMONY_BUF_SIZE;
-+                info.bytes = info.fragments * info.fragsize;
-+		return copy_to_user((void *)arg, &info, sizeof(info));
-+
-+	case SNDCTL_DSP_GETISPACE:
-+		if (!(file->f_mode & FMODE_READ))
-+			return -EINVAL;
-+		info.fragstotal = MAX_BUFS;
-+                info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record;
-+		info.fragsize = HARMONY_BUF_SIZE;
-+                info.bytes = info.fragments * info.fragsize;
-+		return copy_to_user((void *)arg, &info, sizeof(info));
-+	
-+	case SNDCTL_DSP_SYNC:
-+		return 0;
-+	}
-+	
-+	return -EINVAL;
-+}
-+
-+
-+/*
-+ * harmony_interrupt()
-+ *
-+ * harmony interruption service routine
-+ * 
-+ */
-+
-+static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
-+{
-+	u32 dstatus;
-+	struct harmony_hpa *hpa;
-+
-+	/* Setup the hpa */
-+	hpa = ((struct harmony_dev *)dev)->hpa;
-+	harmony_wait_CNTL();
-+
-+	/* Read dstatus and pcuradd (the current address) */
-+	dstatus = gsc_readl(&hpa->dstatus);
-+	
-+	/* Turn off interrupts */
-+	harmony_disable_interrupts();
-+	
-+	/* Check if this is a request to get the next play buffer */
-+	if (dstatus & DSTATUS_PN) {
-+		if (!harmony.nb_filled_play) {
-+			harmony.suspended_playing = 1;
-+			gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd);
-+						
-+			if (!harmony.suspended_recording)
-+				harmony_enable_interrupts();
-+		} else {
-+			harmony.suspended_playing = 0;
-+			gsc_writel((unsigned long)played_buf.dma_handle + 
-+					(HARMONY_BUF_SIZE*harmony.first_filled_play),
-+					&hpa->pnxtadd);
-+			harmony.first_filled_play++;
-+			harmony.first_filled_play %= MAX_BUFS;
-+			harmony.nb_filled_play--;
-+			
-+		       	harmony_enable_interrupts();
-+		}
-+		
-+		if (harmony.blocked_playing)
-+			wake_up_interruptible(&harmony.wq_play);
-+	}
-+	
-+	/* Check if we're being asked to fill in a recording buffer */
-+	if (dstatus & DSTATUS_RN) {
-+		if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording)
-+		{
-+			harmony.nb_filled_record = 0;
-+			harmony.first_filled_record = 0;
-+			harmony.suspended_recording = 1;
-+			gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd);
-+			if (!harmony.suspended_playing)
-+				harmony_enable_interrupts();
-+		} else {
-+			int buf_to_fill;
-+			buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS;
-+			CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE);
-+			gsc_writel((unsigned long)recorded_buf.dma_handle +
-+					HARMONY_BUF_SIZE*buf_to_fill,
-+					&hpa->rnxtadd);
-+			harmony.nb_filled_record++;
-+			harmony_enable_interrupts();
-+		}
-+
-+		if (harmony.blocked_recording && harmony.nb_filled_record>3)
-+			wake_up_interruptible(&harmony.wq_record);
-+	}
-+	return IRQ_HANDLED;
-+}
-+
-+/*
-+ * Sound playing functions
-+ */
-+
-+static struct file_operations harmony_audio_fops = {
-+	owner:	THIS_MODULE,
-+	llseek:	no_llseek,
-+	read: 	harmony_audio_read,
-+	write:	harmony_audio_write,
-+	poll: 	harmony_audio_poll,
-+	ioctl: 	harmony_audio_ioctl,
-+	open: 	harmony_audio_open,
-+	release:harmony_audio_release,
-+};
-+
-+static int harmony_audio_init(void)
-+{
-+	/* Request that IRQ */
-+	if (request_irq(harmony.irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
-+		printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.irq);
-+		return -EFAULT;
-+	}
-+
-+   	harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
-+	if (harmony.dsp_unit < 0) {
-+		printk(KERN_ERR PFX "Error registering dsp\n");
-+		free_irq(harmony.irq, &harmony);
-+		return -EFAULT;
-+	}
-+	
-+	/* Clear the buffers so you don't end up with crap in the buffers. */ 
-+	harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-+
-+	/* Make sure this makes it to cache */
-+	CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-+
-+	/* Clear out the silent buffer and flush to cache */
-+	harmony_silence(&silent, 0, HARMONY_BUF_SIZE);
-+	CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE);
-+	
-+	harmony.audio_open = 0;
-+	
-+	return 0;
-+}
-+
-+
-+/*
-+ * mixer functions 
-+ */
-+
-+static void harmony_mixer_set_gain(void)
-+{
-+	harmony_wait_CNTL();
-+	gsc_writel(harmony.current_gain, &harmony.hpa->gainctl);
-+}
-+
-+/* 
-+ *  Read gain of selected channel.
-+ *  The OSS rate is from 0 (silent) to 100 -> need some conversions
-+ *
-+ *  The harmony gain are attenuation for output and monitor gain.
-+ *                   is amplifaction for input gain
-+ */
-+#define to_harmony_level(level,max) ((level)*max/100)
-+#define to_oss_level(level,max) ((level)*100/max)
-+
-+static int harmony_mixer_get_level(int channel)
-+{
-+	int left_level;
-+	int right_level;
-+
-+	switch (channel) {
-+		case SOUND_MIXER_OGAIN:
-+			left_level  = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT;
-+			right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT;
-+			left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-+			right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-+			return (right_level << 8)+left_level;
-+			
-+		case SOUND_MIXER_IGAIN:
-+			left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT;
-+			right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT;
-+			left_level = to_oss_level(left_level, MAX_INPUT_LEVEL);
-+			right_level= to_oss_level(right_level, MAX_INPUT_LEVEL);
-+			return (right_level << 8)+left_level;
-+			
-+		case SOUND_MIXER_VOLUME:
-+			left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT;
-+			left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL);
-+			return left_level;
-+	}
-+	return -EINVAL;
-+}
-+
-+
-+
-+/*
-+ * Some conversions for the same reasons.
-+ * We give back the new real value(s) due to
-+ * the rescale.
-+ */
-+
-+static int harmony_mixer_set_level(int channel, int value)
-+{
-+	int left_level;
-+	int right_level;
-+	int new_left_level;
-+	int new_right_level;
-+
-+	right_level = (value & 0x0000ff00) >> 8;
-+	left_level = value & 0x000000ff;
-+  
-+	switch (channel) {
-+		case SOUND_MIXER_OGAIN:
-+			right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL);
-+			left_level  = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL);
-+			new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-+			new_left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-+			harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) 
-+					| (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT);
-+			harmony_mixer_set_gain();
-+			return (new_right_level << 8) + new_left_level;
-+			
-+		case SOUND_MIXER_IGAIN:
-+			right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL);
-+			left_level  = to_harmony_level(left_level, MAX_INPUT_LEVEL);
-+			new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL);
-+			new_left_level  = to_oss_level(left_level, MAX_INPUT_LEVEL);
-+			harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK))
-+					| (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT);
-+			harmony_mixer_set_gain();
-+			return (new_right_level << 8) + new_left_level;
-+	
-+		case SOUND_MIXER_VOLUME:
-+			left_level = to_harmony_level(100-left_level, MAX_VOLUME_LEVEL);
-+			new_left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL);
-+			harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK)| (left_level << GAIN_MA_SHIFT);
-+			harmony_mixer_set_gain();
-+			return new_left_level;
-+	}
-+
-+	return -EINVAL;
-+}
-+
-+#undef to_harmony_level
-+#undef to_oss_level
-+
-+/* 
-+ * Return the selected input device (mic or line)
-+ */
-+
-+static int harmony_mixer_get_recmask(void) 
-+{
-+	int current_input_line;
-+	
-+	current_input_line = (harmony.current_gain & GAIN_IS_MASK) 
-+				    >> GAIN_IS_SHIFT;
-+	if (current_input_line) 
-+		return SOUND_MASK_MIC;
-+
-+	return SOUND_MASK_LINE;
-+}
-+
-+/*
-+ * Set the input (only one at time, arbitrary priority to line in)
-+ */
-+
-+static int harmony_mixer_set_recmask(int recmask)
-+{
-+	int new_input_line;
-+	int new_input_mask;
-+
-+	if ((recmask & SOUND_MASK_LINE)) {
-+		new_input_line = 0;
-+		new_input_mask = SOUND_MASK_LINE;
-+	} else  {
-+		new_input_line = 1;
-+		new_input_mask = SOUND_MASK_MIC;
-+	}
-+	harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | 
-+				(new_input_line << GAIN_IS_SHIFT ));
-+	harmony_mixer_set_gain();
-+	return new_input_mask;
-+}
-+
-+
-+/* 
-+ * give the active outlines
-+ */
-+
-+static int harmony_mixer_get_outmask(void)
-+{
-+	int outmask = 0;
-+	
-+	if (harmony.current_gain & GAIN_HE_MASK) outmask |=SOUND_MASK_PHONEOUT;
-+	if (harmony.current_gain & GAIN_LE_MASK) outmask |=SOUND_MASK_LINE;
-+	if (harmony.current_gain & GAIN_SE_MASK) outmask |=SOUND_MASK_SPEAKER;
-+	
-+	return outmask;
-+}
-+
-+
-+static int harmony_mixer_set_outmask(int outmask)
-+{
-+	if (outmask & SOUND_MASK_PHONEOUT) 
-+		harmony.current_gain |= GAIN_HE_MASK; 
-+	else 
-+		harmony.current_gain &= ~GAIN_HE_MASK;
-+	
-+	if (outmask & SOUND_MASK_LINE) 
-+		harmony.current_gain |= GAIN_LE_MASK;
-+	else 
-+		harmony.current_gain &= ~GAIN_LE_MASK;
-+	
-+	if (outmask & SOUND_MASK_SPEAKER) 
-+		harmony.current_gain |= GAIN_SE_MASK;
-+	else 
-+		harmony.current_gain &= ~GAIN_SE_MASK;
-+	
-+	harmony_mixer_set_gain();
-+
-+	return (outmask & (SOUND_MASK_PHONEOUT | SOUND_MASK_LINE | SOUND_MASK_SPEAKER));
-+}
-+
-+/*
-+ * This code is inspired from sb_mixer.c
-+ */
-+
-+static int harmony_mixer_ioctl(struct inode * inode, struct file * file,
-+		unsigned int cmd, unsigned long arg)
-+{
-+	int val;
-+	int ret;
-+
-+	if (cmd == SOUND_MIXER_INFO) {
-+		mixer_info info;
-+		memset(&info, 0, sizeof(info));
-+                strncpy(info.id, "harmony", sizeof(info.id)-1);
-+                strncpy(info.name, "Harmony audio", sizeof(info.name)-1);
-+                info.modify_counter = 1; /* ? */
-+                if (copy_to_user((void *)arg, &info, sizeof(info)))
-+                        return -EFAULT;
-+		return 0;
-+	}
-+	
-+	if (cmd == OSS_GETVERSION)
-+		return put_user(SOUND_VERSION, (int *)arg);
-+
-+	/* read */
-+	val = 0;
-+	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-+		if (get_user(val, (int *)arg))
-+			return -EFAULT;
-+
-+	switch (cmd) {
-+	case MIXER_READ(SOUND_MIXER_CAPS):
-+		ret = SOUND_CAP_EXCL_INPUT;
-+		break;
-+	case MIXER_READ(SOUND_MIXER_STEREODEVS):
-+		ret = SOUND_MASK_IGAIN | SOUND_MASK_OGAIN;
-+		break;
-+		
-+	case MIXER_READ(SOUND_MIXER_RECMASK):
-+		ret = SOUND_MASK_MIC | SOUND_MASK_LINE;
-+		break;
-+	case MIXER_READ(SOUND_MIXER_DEVMASK):
-+		ret = SOUND_MASK_OGAIN | SOUND_MASK_IGAIN |
-+			SOUND_MASK_VOLUME;
-+		break;
-+	case MIXER_READ(SOUND_MIXER_OUTMASK):
-+		ret = SOUND_MASK_SPEAKER | SOUND_MASK_LINE |
-+			SOUND_MASK_PHONEOUT;
-+		break;
-+		
-+	case MIXER_WRITE(SOUND_MIXER_RECSRC):
-+		ret = harmony_mixer_set_recmask(val);
-+		break;
-+	case MIXER_READ(SOUND_MIXER_RECSRC):
-+		ret = harmony_mixer_get_recmask();
-+		break;
-+	      
-+	case MIXER_WRITE(SOUND_MIXER_OUTSRC):
-+		ret = harmony_mixer_set_outmask(val);
-+		break;
-+	case MIXER_READ(SOUND_MIXER_OUTSRC):
-+		ret = harmony_mixer_get_outmask();
-+		break;
-+	
-+	case MIXER_WRITE(SOUND_MIXER_OGAIN):
-+	case MIXER_WRITE(SOUND_MIXER_IGAIN):
-+	case MIXER_WRITE(SOUND_MIXER_VOLUME):
-+		ret = harmony_mixer_set_level(cmd & 0xff, val);
-+		break;
-+
-+	case MIXER_READ(SOUND_MIXER_OGAIN):
-+	case MIXER_READ(SOUND_MIXER_IGAIN):
-+	case MIXER_READ(SOUND_MIXER_VOLUME):
-+		ret = harmony_mixer_get_level(cmd & 0xff);
-+		break;
-+
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	if (put_user(ret, (int *)arg))
-+		return -EFAULT;
-+	return 0;
-+}
-+
-+
-+static int harmony_mixer_open(struct inode *inode, struct file *file)
-+{
-+	if (harmony.mixer_open) 
-+		return -EBUSY;
-+	harmony.mixer_open++;
-+	return 0;
-+}
-+
-+static int harmony_mixer_release(struct inode *inode, struct file *file)
-+{
-+	if (!harmony.mixer_open) 
-+		return -EBUSY;
-+	harmony.mixer_open--;
-+	return 0;
-+}
-+
-+static struct file_operations harmony_mixer_fops = {
-+	owner:		THIS_MODULE,
-+	llseek:		no_llseek,
-+	open:		harmony_mixer_open,
-+	release:	harmony_mixer_release,
-+	ioctl:		harmony_mixer_ioctl,
-+};
-+
-+
-+/*
-+ * Mute all the output and reset Harmony.
-+ */
-+
-+static void __init harmony_mixer_reset(void)
-+{
-+	harmony.current_gain = GAIN_TOTAL_SILENCE;
-+	harmony_mixer_set_gain();
-+	harmony_wait_CNTL();
-+	gsc_writel(1, &harmony.hpa->reset);
-+	mdelay(50);		/* wait 50 ms */
-+	gsc_writel(0, &harmony.hpa->reset);
-+	harmony.current_gain = GAIN_DEFAULT;
-+	harmony_mixer_set_gain();
-+}
-+
-+static int __init harmony_mixer_init(void)
-+{
-+	/* Register the device file operations */
-+	harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1);
-+	if (harmony.mixer_unit < 0) {
-+		printk(KERN_WARNING PFX "Error Registering Mixer Driver\n");
-+		return -EFAULT;
-+	}
-+  
-+	harmony_mixer_reset();
-+	harmony.mixer_open = 0;
-+	
-+	return 0;
-+}
-+
-+
-+
-+/* 
-+ * This is the callback that's called by the inventory hardware code 
-+ * if it finds a match to the registered driver. 
-+ */
-+static int __init
-+harmony_driver_callback(struct parisc_device *dev)
-+{
-+	u8	id;
-+	u8	rev;
-+	u32	cntl;
-+	int	ret;
-+
-+	if (harmony.hpa) {
-+		/* We only support one Harmony at this time */
-+		printk(KERN_ERR PFX "driver already registered\n");
-+		return -EBUSY;
-+	}
-+
-+	/* Set the HPA of harmony */
-+	harmony.hpa = (struct harmony_hpa *)dev->hpa;
-+
-+	harmony.irq = dev->irq;
-+	if (!harmony.irq) {
-+		printk(KERN_ERR PFX "no irq found\n");
-+		return -ENODEV;
-+	}
-+
-+	/* Grab the ID and revision from the device */
-+	id = gsc_readb(&harmony.hpa->id);
-+	if ((id | 1) != 0x15) {
-+		printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id);
-+		return -EBUSY;
-+	}
-+	cntl = gsc_readl(&harmony.hpa->cntl);
-+	rev = (cntl>>20) & 0xff;
-+
-+	printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
-+			"h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
-+			id, rev, dev->hpa, harmony.irq);
-+	
-+	/* Make sure the control bit isn't set, although I don't think it 
-+	   ever is. */
-+	if (cntl & CNTL_C) {
-+		printk(KERN_WARNING PFX "CNTL busy\n");
-+		harmony.hpa = 0;
-+		return -EBUSY;
-+	}
-+
-+	/* a fake pci_dev is needed for pci_* functions under ccio */
-+	harmony.fake_pci_dev = ccio_get_fake(dev);
-+	
-+	/* Initialize the memory buffers */
-+	if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
-+	    harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
-+	    harmony_alloc_buffer(&graveyard, 1) ||
-+	    harmony_alloc_buffer(&silent, 1)) {
-+		ret = -EBUSY;
-+		goto out_err;
-+	}
-+
-+	/* Initialize /dev/mixer and /dev/audio  */
-+	if ((ret=harmony_mixer_init())) 
-+		goto out_err;
-+	if ((ret=harmony_audio_init())) 
-+		goto out_err;
-+
-+	return 0;
-+
-+out_err:
-+	harmony.hpa = 0;
-+	harmony_free_buffer(&played_buf);
-+	harmony_free_buffer(&recorded_buf);
-+	harmony_free_buffer(&graveyard);
-+	harmony_free_buffer(&silent);
-+	return ret;
-+}
-+
-+
-+static struct parisc_device_id harmony_tbl[] = {
-+ /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */
-+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
-+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
-+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
-+ { 0, }
-+};
-+
-+MODULE_DEVICE_TABLE(parisc, harmony_tbl);
-+
-+static struct parisc_driver harmony_driver = {
-+	name:		"Lasi Harmony",
-+	id_table:	harmony_tbl,
-+	probe:		harmony_driver_callback,
-+};
-+
-+static int __init init_harmony(void)
-+{
-+	return register_parisc_driver(&harmony_driver);
-+}
-+
-+static void __exit cleanup_harmony(void)
-+{
-+	free_irq(harmony.irq, &harmony);
-+	unregister_sound_mixer(harmony.mixer_unit);
-+	unregister_sound_dsp(harmony.dsp_unit);
-+	harmony_free_buffer(&played_buf);
-+	harmony_free_buffer(&recorded_buf);
-+	harmony_free_buffer(&graveyard);
-+	harmony_free_buffer(&silent);
-+	unregister_parisc_driver(&harmony_driver);
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("Alex DeVries <alex@linuxcare.com>");
-+MODULE_DESCRIPTION("Harmony sound driver");
-+MODULE_LICENSE("GPL");
-+
-+module_init(init_harmony);
-+module_exit(cleanup_harmony);
-+
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25/sound/oss/kahlua.c	2003-07-19 17:03:51.000000000 -0700
-@@ -0,0 +1,227 @@
-+/*
-+ *	Initialisation code for Cyrix/NatSemi VSA1 softaudio
-+ *
-+ *	(C) Copyright 2003 Red Hat Inc <alan@redhat.com>
-+ *
-+ * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
-+ * The older version (VSA1) provides fairly good soundblaster emulation
-+ * although there are a couple of bugs: large DMA buffers break record,
-+ * and the MPU event handling seems suspect. VSA2 allows the native driver
-+ * to control the AC97 audio engine directly and requires a different driver.
-+ *
-+ * Thanks to National Semiconductor for providing the needed information
-+ * on the XpressAudio(tm) internals.
-+ *
-+ * This program 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, or (at your option) any
-+ * later version.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * TO DO:
-+ *	Investigate whether we can portably support Cognac (5520) in the
-+ *	same manner.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+
-+#include "sound_config.h"
-+
-+#include "sb.h"
-+
-+/*
-+ *	Read a soundblaster compatible mixer register.
-+ *	In this case we are actually reading an SMI trap
-+ *	not real hardware.
-+ */
-+
-+static u8 __devinit mixer_read(unsigned long io, u8 reg)
-+{
-+	outb(reg, io + 4);
-+	udelay(20);
-+	reg = inb(io + 5);
-+	udelay(20);
-+	return reg;
-+}
-+
-+static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-+{
-+	struct address_info *hw_config;
-+	unsigned long base;
-+	void *mem;
-+	unsigned long io;
-+	u16 map;
-+	u8 irq, dma8, dma16;
-+	int oldquiet;
-+	extern int sb_be_quiet;
-+		
-+	base = pci_resource_start(pdev, 0);
-+	if(base == 0UL)
-+		return 1;
-+	
-+	mem = ioremap(base, 128);
-+	if(mem == 0UL)
-+		return 1;
-+	map = readw(mem + 0x18);	/* Read the SMI enables */
-+	iounmap(mem);
-+	
-+	/* Map bits
-+		0:1	* 0x20 + 0x200 = sb base
-+		2	sb enable
-+		3	adlib enable
-+		5	MPU enable 0x330
-+		6	MPU enable 0x300
-+		
-+	   The other bits may be used internally so must be masked */
-+
-+	io = 0x220 + 0x20 * (map & 3);	   
-+	
-+	if(map & (1<<2))
-+		printk(KERN_INFO "kahlua: XpressAudio at 0x%lx\n", io);
-+	else
-+		return 1;
-+		
-+	if(map & (1<<5))
-+		printk(KERN_INFO "kahlua: MPU at 0x300\n");
-+	else if(map & (1<<6))
-+		printk(KERN_INFO "kahlua: MPU at 0x330\n");
-+	
-+	irq = mixer_read(io, 0x80) & 0x0F;
-+	dma8 = mixer_read(io, 0x81);
-+
-+	// printk("IRQ=%x MAP=%x DMA=%x\n", irq, map, dma8);
-+	
-+	if(dma8 & 0x20)
-+		dma16 = 5;
-+	else if(dma8 & 0x40)
-+		dma16 = 6;
-+	else if(dma8 & 0x80)
-+		dma16 = 7;
-+	else
-+	{
-+		printk(KERN_ERR "kahlua: No 16bit DMA enabled.\n");
-+		return 1;
-+	}
-+		
-+	if(dma8 & 0x01)
-+		dma8 = 0;
-+	else if(dma8 & 0x02)
-+		dma8 = 1;
-+	else if(dma8 & 0x08)
-+		dma8 = 3;
-+	else
-+	{
-+		printk(KERN_ERR "kahlua: No 8bit DMA enabled.\n");
-+		return 1;
-+	}
-+	
-+	if(irq & 1)
-+		irq = 9;
-+	else if(irq & 2)
-+		irq = 5;
-+	else if(irq & 4)
-+		irq = 7;
-+	else if(irq & 8)
-+		irq = 10;
-+	else
-+	{
-+		printk(KERN_ERR "kahlua: SB IRQ not set.\n");
-+		return 1;
-+	}
-+	
-+	printk(KERN_INFO "kahlua: XpressAudio on IRQ %d, DMA %d, %d\n",
-+		irq, dma8, dma16);
-+	
-+	hw_config = kmalloc(sizeof(struct address_info), GFP_KERNEL);
-+	if(hw_config == NULL)
-+	{
-+		printk(KERN_ERR "kahlua: out of memory.\n");
-+		return 1;
-+	}
-+	memset(hw_config, 0, sizeof(*hw_config));
-+	
-+	pci_set_drvdata(pdev, hw_config);
-+	
-+	hw_config->io_base = io;
-+	hw_config->irq = irq;
-+	hw_config->dma = dma8;
-+	hw_config->dma2 = dma16;
-+	hw_config->name = "Cyrix XpressAudio";
-+	hw_config->driver_use_1 = SB_NO_MIDI | SB_PCI_IRQ;
-+	
-+	if(sb_dsp_detect(hw_config, 0, 0, NULL)==0)
-+	{
-+		printk(KERN_ERR "kahlua: audio not responding.\n");
-+		goto err_out_free;
-+	}
-+
-+	oldquiet = sb_be_quiet;	
-+	sb_be_quiet = 1;
-+	if(sb_dsp_init(hw_config, THIS_MODULE))
-+	{
-+		sb_be_quiet = oldquiet;
-+		goto err_out_free;
-+	}
-+	sb_be_quiet = oldquiet;
-+	
-+	return 0;
-+
-+err_out_free:
-+	pci_set_drvdata(pdev, NULL);
-+	kfree(hw_config);
-+	return 1;
-+}
-+
-+static void __devexit remove_one(struct pci_dev *pdev)
-+{
-+	struct address_info *hw_config = pci_get_drvdata(pdev);
-+	sb_dsp_unload(hw_config, 0);
-+	pci_set_drvdata(pdev, NULL);
-+	kfree(hw_config);
-+}
-+
-+MODULE_AUTHOR("Alan Cox");
-+MODULE_DESCRIPTION("Kahlua VSA1 PCI Audio");
-+MODULE_LICENSE("GPL");
-+
-+/*
-+ *	5530 only. The 5510/5520 decode is different.
-+ */
-+
-+static struct pci_device_id id_tbl[] __devinitdata = {
-+	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-+	{ }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, id_tbl);
-+
-+static struct pci_driver kahlua_driver = {
-+	name:		"kahlua",
-+	id_table:	id_tbl,
-+	probe:		probe_one,
-+	remove:         __devexit_p(remove_one),
-+};
-+
-+
-+static int __init kahlua_init_module(void)
-+{
-+	printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n");
-+	return pci_module_init(&kahlua_driver);
-+}
-+
-+static void __devexit kahlua_cleanup_module(void)
-+{
-+	return pci_unregister_driver(&kahlua_driver);
-+}
-+
-+
-+module_init(kahlua_init_module);
-+module_exit(kahlua_cleanup_module);
-+
---- linux-2.6.0-test1/sound/oss/Kconfig	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/Kconfig	2003-07-19 17:03:51.000000000 -0700
-@@ -233,6 +233,10 @@ config SOUND_ICH
- 	  Support for integral audio in Intel's I/O Controller Hub (ICH)
- 	  chipset, as used on the 810/820/840 motherboards.
- 
-+config SOUND_HARMONY
-+	tristate "PA Harmony audio driver"
-+	depends on GSC_LASI && SOUND
-+
- config SOUND_RME96XX
- 	tristate "RME Hammerfall (RME96XX) support (EXPERIMENTAL)"
- 	depends on SOUND_PRIME!=n && SOUND && PCI && EXPERIMENTAL
-@@ -260,6 +264,10 @@ config SOUND_VWSND
- 	  <file:Documentation/sound/oss/vwsnd> for more info on this driver's
- 	  capabilities.
- 
-+config SOUND_HAL2
-+	tristate "SGI HAL2 sound (EXPERIMENTAL)"
-+	depends on SGI_IP22 && SOUND && EXPERIMENTAL
-+
- config SOUND_VRC5477
- 	tristate "NEC Vrc5477 AC97 sound"
- 	depends on SOUND_PRIME!=n && DDB5477 && SOUND
-@@ -1126,3 +1134,23 @@ config SOUND_TVMIXER
- 	  Support for audio mixer facilities on the BT848 TV frame-grabber
- 	  card.
- 
-+config SOUND_KAHLUA
-+	tristate "XpressAudio Sound Blaster emulation"
-+	depends on SOUND_SB
-+
-+config SOUND_ALI5455
-+	tristate "ALi5455 audio support"
-+	depends on SOUND_PRIME!=n && PCI
-+
-+config SOUND_FORTE
-+	tristate "ForteMedia FM801 driver"
-+	depends on SOUND_PRIME!=n && PCI
-+
-+config SOUND_RME96XX
-+	tristate "RME Hammerfall (RME96XX) support"
-+	depends on SOUND_PRIME!=n && PCI
-+
-+config SOUND_AD1980
-+	tristate "AD1980 front/back switch plugin"
-+	depends on SOUND_PRIME!=n
-+
---- linux-2.6.0-test1/sound/oss/Makefile	2003-07-13 21:44:35.000000000 -0700
-+++ 25/sound/oss/Makefile	2003-07-19 17:03:51.000000000 -0700
-@@ -10,6 +10,7 @@ obj-$(CONFIG_SOUND_CS4232)	+= cs4232.o a
- 
- # Please leave it as is, cause the link order is significant !
- 
-+obj-$(CONFIG_SOUND_HAL2)	+= hal2.o
- obj-$(CONFIG_SOUND_AEDSP16)	+= aedsp16.o
- obj-$(CONFIG_SOUND_PSS)		+= pss.o ad1848.o mpu401.o
- obj-$(CONFIG_SOUND_TRIX)	+= trix.o ad1848.o sb_lib.o uart401.o
-@@ -21,6 +22,7 @@ obj-$(CONFIG_SOUND_MSS)		+= ad1848.o
- obj-$(CONFIG_SOUND_OPL3SA2)	+= opl3sa2.o ad1848.o mpu401.o
- obj-$(CONFIG_SOUND_PAS)		+= pas2.o sb.o sb_lib.o uart401.o
- obj-$(CONFIG_SOUND_SB)		+= sb.o sb_lib.o uart401.o
-+obj-$(CONFIG_SOUND_KAHLUA)	+= kahlua.o
- obj-$(CONFIG_SOUND_WAVEFRONT)	+= wavefront.o
- obj-$(CONFIG_SOUND_MAUI)	+= maui.o mpu401.o
- obj-$(CONFIG_SOUND_MPU401)	+= mpu401.o
-@@ -60,10 +62,16 @@ obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o a
- obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
- obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3.o ac97_codec.o
- obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
-+obj-$(CONFIG_SOUND_HARMONY)	+= harmony.o
- obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
- obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
- obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
-+obj-$(CONFIG_SOUND_ALI5455)	+= ali5455.o ac97_codec.o
- obj-$(CONFIG_SOUND_IT8172)	+= ite8172.o ac97_codec.o
-+obj-$(CONFIG_SOUND_FORTE)	+= forte.o
-+
-+obj-$(CONFIG_SOUND_AD1980)	+= ac97_plugin_ad1980.o
-+obj-$(CONFIG_SOUND_WM97XX)	+= ac97_plugin_wm97xx.o
- 
- ifeq ($(CONFIG_MIDI_EMU10K1),y)
-   obj-$(CONFIG_SOUND_EMU10K1)	+= sound.o
---- linux-2.6.0-test1/sound/pci/ice1712/ak4xxx.c	2003-06-14 12:17:55.000000000 -0700
-+++ 25/sound/pci/ice1712/ak4xxx.c	2003-07-19 17:06:15.000000000 -0700
-@@ -116,8 +116,8 @@ static void snd_ice1712_akm4xxx_write(ak
- /*
-  * initialize the akm4xxx_t record with the template
-  */
--int __devinit snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp,
--				       const struct snd_ak4xxx_private *_priv, ice1712_t *ice)
-+int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp,
-+			     const struct snd_ak4xxx_private *_priv, ice1712_t *ice)
- {
- 	struct snd_ak4xxx_private *priv;
- 
-@@ -139,7 +139,7 @@ int __devinit snd_ice1712_akm4xxx_init(a
- 	return 0;
- }
- 
--void __devexit snd_ice1712_akm4xxx_free(ice1712_t *ice)
-+void snd_ice1712_akm4xxx_free(ice1712_t *ice)
- {
- 	unsigned int akidx;
- 	if (ice->akm == NULL)
-@@ -155,7 +155,7 @@ void __devexit snd_ice1712_akm4xxx_free(
- /*
-  * build AK4xxx controls
-  */
--int __devinit snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
-+int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
- {
- 	unsigned int akidx;
- 	int err;
---- linux-2.6.0-test1/sound/pci/intel8x0.c	2003-06-14 12:18:23.000000000 -0700
-+++ 25/sound/pci/intel8x0.c	2003-07-19 17:04:58.000000000 -0700
-@@ -2062,10 +2062,8 @@ static void __devinit intel8x0_measure_a
- 
- 	t = stop_time.tv_sec - start_time.tv_sec;
- 	t *= 1000000;
--	if (stop_time.tv_usec < start_time.tv_usec)
--		t -= start_time.tv_usec - stop_time.tv_usec;
--	else
--		t += stop_time.tv_usec - start_time.tv_usec;
-+	t += stop_time.tv_usec - start_time.tv_usec;
-+	printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
- 	if (t == 0) {
- 		snd_printk(KERN_ERR "?? calculation error..\n");
- 		return;
---- linux-2.6.0-test1/usr/Makefile	2003-07-10 18:50:32.000000000 -0700
-+++ 25/usr/Makefile	2003-07-19 17:03:51.000000000 -0700
-@@ -3,7 +3,7 @@ obj-y := initramfs_data.o
- 
- host-progs  := gen_init_cpio
- 
--clean-files := initramfs_data.cpio.gz
-+clean-files := initramfs_data.cpio.gz initramfs_data.S
- 
- $(src)/initramfs_data.S: $(obj)/initramfs_data.cpio.gz
- 	echo "	.section .init.ramfs,\"a\"" > $(src)/initramfs_data.S
diff --git a/lustre/kernel_patches/patches/2.6.0-test6-mm4.patch b/lustre/kernel_patches/patches/2.6.0-test6-mm4.patch
new file mode 100644
index 0000000000000000000000000000000000000000..320311e267c2cfe90c4a4054bc25c7f18c92a673
--- /dev/null
+++ b/lustre/kernel_patches/patches/2.6.0-test6-mm4.patch
@@ -0,0 +1,113290 @@
+--- linux-2.6.0-test6/arch/alpha/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/alpha/Kconfig	2003-10-05 00:36:11.000000000 -0700
+@@ -471,21 +471,6 @@ config EISA
+ 	bool
+ 	depends on ALPHA_GENERIC || ALPHA_JENSEN || ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_RAWHIDE
+ 	default y
+-	---help---
+-	  The Extended Industry Standard Architecture (EISA) bus was
+-	  developed as an open alternative to the IBM MicroChannel bus.
+-
+-	  The EISA bus provided some of the features of the IBM MicroChannel
+-	  bus while maintaining backward compatibility with cards made for
+-	  the older ISA bus.  The EISA bus saw limited use between 1988 and
+-	  1995 when it was made obsolete by the PCI bus.
+-
+-	  Say Y here if you are building a kernel for an EISA-based machine.
+-
+-	  Otherwise, say N.
+-
+-config EISA_ALWAYS
+-	def_bool EISA
+ 
+ config SMP
+ 	bool "Symmetric multi-processing support"
+--- linux-2.6.0-test6/arch/alpha/kernel/core_irongate.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/alpha/kernel/core_irongate.c	2003-10-05 00:33:23.000000000 -0700
+@@ -391,7 +391,7 @@ irongate_ioremap(unsigned long addr, uns
+ 		cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
+ 		pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
+ 
+-		if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
++		if (__alpha_remap_area_pages(vaddr,
+ 					     pte, PAGE_SIZE, 0)) {
+ 			printk("AGP ioremap: FAILED to map...\n");
+ 			vfree(area->addr);
+--- linux-2.6.0-test6/arch/alpha/kernel/core_marvel.c	2003-08-22 19:23:39.000000000 -0700
++++ 25/arch/alpha/kernel/core_marvel.c	2003-10-05 00:33:23.000000000 -0700
+@@ -696,7 +696,7 @@ marvel_ioremap(unsigned long addr, unsig
+ 			}
+ 			pfn >>= 1;	/* make it a true pfn */
+ 			
+-			if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
++			if (__alpha_remap_area_pages(vaddr,
+ 						     pfn << PAGE_SHIFT, 
+ 						     PAGE_SIZE, 0)) {
+ 				printk("FAILED to map...\n");
+--- linux-2.6.0-test6/arch/alpha/kernel/core_titan.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/alpha/kernel/core_titan.c	2003-10-05 00:33:23.000000000 -0700
+@@ -534,7 +534,7 @@ titan_ioremap(unsigned long addr, unsign
+ 			}
+ 			pfn >>= 1;	/* make it a true pfn */
+ 			
+-			if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
++			if (__alpha_remap_area_pages(vaddr,
+ 						     pfn << PAGE_SHIFT, 
+ 						     PAGE_SIZE, 0)) {
+ 				printk("FAILED to map...\n");
+--- linux-2.6.0-test6/arch/alpha/kernel/setup.c	2003-08-22 19:23:39.000000000 -0700
++++ 25/arch/alpha/kernel/setup.c	2003-10-05 00:36:11.000000000 -0700
+@@ -33,6 +33,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/root_dev.h>
+ #include <linux/initrd.h>
++#include <linux/eisa.h>
+ #ifdef CONFIG_MAGIC_SYSRQ
+ #include <linux/sysrq.h>
+ #include <linux/reboot.h>
+@@ -680,6 +681,11 @@ setup_arch(char **cmdline_p)
+ 	/* Default root filesystem to sda2.  */
+ 	ROOT_DEV = Root_SDA2;
+ 
++#ifdef CONFIG_EISA
++	/* FIXME:  only set this when we actually have EISA in this box? */
++	EISA_bus = 1;
++#endif
++
+  	/*
+ 	 * Check ASN in HWRPB for validity, report if bad.
+ 	 * FIXME: how was this failing?  Should we trust it instead,
+@@ -1203,7 +1209,7 @@ show_cpuinfo(struct seq_file *f, void *s
+ 		       platform_string(), nr_processors);
+ 
+ #ifdef CONFIG_SMP
+-	seq_printf(f, "cpus active\t\t: %d\n"
++	seq_printf(f, "cpus active\t\t: %ld\n"
+ 		      "cpu active mask\t\t: %016lx\n",
+ 		       num_online_cpus(), cpu_present_mask);
+ #endif
+--- linux-2.6.0-test6/arch/alpha/kernel/smp.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/alpha/kernel/smp.c	2003-10-05 00:33:23.000000000 -0700
+@@ -597,7 +597,7 @@ smp_cpus_done(unsigned int max_cpus)
+ 		if (cpu_online(cpu))
+ 			bogosum += cpu_data[cpu].loops_per_jiffy;
+ 	
+-	printk(KERN_INFO "SMP: Total of %d processors activated "
++	printk(KERN_INFO "SMP: Total of %ld processors activated "
+ 	       "(%lu.%02lu BogoMIPS).\n",
+ 	       num_online_cpus(), 
+ 	       (bogosum + 2500) / (500000/HZ),
+--- linux-2.6.0-test6/arch/alpha/kernel/time.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/alpha/kernel/time.c	2003-10-05 00:33:23.000000000 -0700
+@@ -89,6 +89,16 @@ static inline __u32 rpcc(void)
+     return result;
+ }
+ 
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ *
++ * Copied from ARM code for expediency... ;-}
++ */
++unsigned long long sched_clock(void)
++{
++        return (unsigned long long)jiffies * (1000000000 / HZ);
++}
++
+ 
+ /*
+  * timer_interrupt() needs to keep up the real-time clock,
+@@ -239,8 +249,9 @@ validate_cc_value(unsigned long cc)
+  * arch/i386/time.c.
+  */
+ 
+-#define CALIBRATE_LATCH	(52 * LATCH)
+-#define CALIBRATE_TIME	(52 * 1000020 / HZ)
++#define PIC_TICK_RATE	1193180UL
++#define CALIBRATE_LATCH	0xffff
++#define TIMEOUT_COUNT	0x100000
+ 
+ static unsigned long __init
+ calibrate_cc_with_pic(void)
+@@ -263,19 +274,15 @@ calibrate_cc_with_pic(void)
+ 
+ 	cc = rpcc();
+ 	do {
+-	  count+=100; /* by 1 takes too long to timeout from 0 */
+-	} while ((inb(0x61) & 0x20) == 0 && count > 0);
++		count++;
++	} while ((inb(0x61) & 0x20) == 0 && count < TIMEOUT_COUNT);
+ 	cc = rpcc() - cc;
+ 
+ 	/* Error: ECTCNEVERSET or ECPUTOOFAST.  */
+-	if (count <= 100)
+-		return 0;
+-
+-	/* Error: ECPUTOOSLOW.  */
+-	if (cc <= CALIBRATE_TIME)
++	if (count <= 1 || count == TIMEOUT_COUNT)
+ 		return 0;
+ 
+-	return (cc * 1000000UL) / CALIBRATE_TIME;
++	return ((long)cc * PIC_TICK_RATE) / (CALIBRATE_LATCH + 1);
+ }
+ 
+ /* The Linux interpretation of the CMOS clock register contents:
+--- linux-2.6.0-test6/arch/alpha/mm/init.c	2003-07-27 12:14:38.000000000 -0700
++++ 25/arch/alpha/mm/init.c	2003-10-05 00:33:23.000000000 -0700
+@@ -210,7 +210,8 @@ callback_init(void * kernel_end)
+ 	/* Allocate one PGD and one PMD.  In the case of SRM, we'll need
+ 	   these to actually remap the console.  There is an assumption
+ 	   here that only one of each is needed, and this allows for 8MB.
+-	   Currently (late 1999), big consoles are still under 4MB.
++	   On systems with larger consoles, additional pages will be
++	   allocated as needed during the mapping process.
+ 
+ 	   In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC,
+ 	   we need to allocate the PGD we use for vmalloc before we start
+@@ -237,6 +238,15 @@ callback_init(void * kernel_end)
+ 			unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT;
+ 			crb->map[i].va = vaddr;
+ 			for (j = 0; j < crb->map[i].count; ++j) {
++				/* Newer console's (especially on larger
++				   systems) may require more pages of
++				   PTEs. Grab additional pages as needed. */
++				if (pmd != pmd_offset(pgd, vaddr)) {
++					memset(kernel_end, 0, PAGE_SIZE);
++					pmd = pmd_offset(pgd, vaddr);
++					pmd_set(pmd, (pte_t *)kernel_end);
++					kernel_end += PAGE_SIZE;
++				}
+ 				set_pte(pte_offset_kernel(pmd, vaddr),
+ 					pfn_pte(pfn, PAGE_KERNEL));
+ 				pfn++;
+--- linux-2.6.0-test6/arch/arm/boot/compressed/head.S	2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/arm/boot/compressed/head.S	2003-10-05 00:33:23.000000000 -0700
+@@ -477,6 +477,12 @@ proc_types:
+ @		b	__arm6_cache_off
+ @		b	__armv3_cache_flush
+ 
++		.word	0x00000000		@ old ARM ID
++		.word	0x0000f000
++		mov	pc, lr
++		mov	pc, lr
++		mov	pc, lr
++
+ 		.word	0x41007000		@ ARM7/710
+ 		.word	0xfff8fe00
+ 		b	__arm7_cache_off
+@@ -489,6 +495,14 @@ proc_types:
+ 		b	__armv4_cache_off
+ 		mov	pc, lr
+ 
++		.word	0x00007000		@ ARM7 IDs
++		.word	0x0000f000
++		mov	pc, lr
++		mov	pc, lr
++		mov	pc, lr
++
++		@ Everything from here on will be the new ID system.
++
+ 		.word	0x41129200		@ ARM920T
+ 		.word	0xff00fff0
+ 		b	__armv4_cache_on
+@@ -507,8 +521,16 @@ proc_types:
+ 		b	__armv4_cache_off
+ 		b	__armv4_cache_flush
+ 
+-		.word	0x69050000		@ xscale
+-		.word	0xffff0000
++		@ These match on the architecture ID
++
++		.word	0x00050000		@ ARMv5TE
++		.word	0x000f0000
++		b	__armv4_cache_on
++		b	__armv4_cache_off
++		b	__armv4_cache_flush
++
++		.word	0x00060000		@ ARMv5TEJ
++		.word	0x000f0000
+ 		b	__armv4_cache_on
+ 		b	__armv4_cache_off
+ 		b	__armv4_cache_flush
+--- linux-2.6.0-test6/arch/arm/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/Kconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -239,7 +239,7 @@ config DISCONTIGMEM
+ 
+ # Now handle the bus types
+ config PCI
+-	bool "PCI support" if ARCH_INTEGRATOR
++	bool "PCI support" if ARCH_INTEGRATOR_AP
+ 	default y if ARCH_FTVPCI || ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX
+ 	help
+ 	  Find out whether you have a PCI motherboard. PCI is the name of a
+@@ -645,8 +645,6 @@ source "drivers/misc/Kconfig"
+ 
+ source "drivers/usb/Kconfig"
+ 
+-source "net/bluetooth/Kconfig"
+-
+ 
+ menu "Kernel hacking"
+ 
+--- linux-2.6.0-test6/arch/arm/kernel/apm.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/arm/kernel/apm.c	2003-10-05 00:33:23.000000000 -0700
+@@ -179,13 +179,10 @@ static void queue_event(apm_event_t even
+ 	wake_up_interruptible(&apm_waitqueue);
+ }
+ 
+-/* defined in pm.c */
+-extern int suspend(void);
+-
+ static int apm_suspend(void)
+ {
+ 	struct list_head *l;
+-	int err = suspend();
++	int err = pm_suspend(PM_SUSPEND_MEM);
+ 
+ 	/*
+ 	 * Anyone on the APM queues will think we're still suspended.
+--- linux-2.6.0-test6/arch/arm/kernel/entry-armv.S	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/kernel/entry-armv.S	2003-10-05 00:33:23.000000000 -0700
+@@ -439,20 +439,25 @@ ENTRY(soft_irq_mask)
+ 
+ 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+ /* FIXME: should not be using soo many LDRs here */
+-		ldr	\irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+-		ldr	\irqstat, [\irqnr, #IRQ_STATUS]		@ get masked status
+-		ldr	\irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+-		ldr	\irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+-		orr	\irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0
++		ldr	\base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
++		mov	\irqnr, #IRQ_PIC_START
++		ldr	\irqstat, [\base, #IRQ_STATUS]		@ get masked status
++		ldr	\base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
++		teq	\irqstat, #0
++		ldreq	\irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
++		moveq	\irqnr, #IRQ_CIC_START
+ 
+-		mov	\irqnr, #0
+-1001:		tst	\irqstat, #1
++1001:		tst	\irqstat, #15
+ 		bne	1002f
++		add	\irqnr, \irqnr, #4
++		movs	\irqstat, \irqstat, lsr #4
++		bne	1001b
++1002:		tst	\irqstat, #1
++		bne	1003f
+ 		add	\irqnr, \irqnr, #1
+-		mov	\irqstat, \irqstat, lsr #1
+-		cmp	\irqnr, #22
+-		bcc	1001b
+-1002:		/* EQ will be set if we reach 22 */
++		movs	\irqstat, \irqstat, lsr #1
++		bne	1002b
++1003:		/* EQ will be set if no irqs pending */
+ 		.endm
+ 
+ 		.macro	irq_prio_table
+--- linux-2.6.0-test6/arch/arm/kernel/pm.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/arm/kernel/pm.c	2003-10-05 00:33:23.000000000 -0700
+@@ -9,68 +9,18 @@
+  *  sleep.
+  */
+ #include <linux/config.h>
++#include <linux/init.h>
++#include <linux/sysctl.h>
+ #include <linux/pm.h>
+-#include <linux/device.h>
+-#include <linux/sysdev.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ 
+-#include <asm/leds.h>
+-#include <asm/system.h>
+-
+-/*
+- * Tell the linker that pm_do_suspend may not be present.
+- */
+-extern int pm_do_suspend(void) __attribute__((weak));
+-
+-int suspend(void)
+-{
+-	int ret;
+-
+-	if (!pm_do_suspend)
+-		return -ENOSYS;
+-
+-	/*
+-	 * Suspend "legacy" devices.
+-	 */
+-	ret = pm_send_all(PM_SUSPEND, (void *)3);
+-	if (ret != 0)
+-		goto out;
+-
+-	ret = device_suspend(3);
+-	if (ret)
+-		goto resume_legacy;
+-
+-	local_irq_disable();
+-	leds_event(led_stop);
+-
+-	sysdev_suspend(3);
+-
+-	ret = pm_do_suspend();
+-
+-	sysdev_resume();
+-
+-	leds_event(led_start);
+-	local_irq_enable();
+-
+-	device_resume();
+-
+- resume_legacy:
+-	pm_send_all(PM_RESUME, (void *)0);
+-
+- out:
+-	return ret;
+-}
+-
+ #ifdef CONFIG_SYSCTL
+ /*
+  * We really want this to die.  It's a disgusting hack using unallocated
+  * sysctl numbers.  We should be using a real interface.
+  */
+ 
+-#include <linux/init.h>
+-#include <linux/sysctl.h>
+-
+ static int
+ pm_sysctl_proc_handler(ctl_table *ctl, int write, struct file *filp,
+ 		       void *buffer, size_t *lenp)
+@@ -79,7 +29,7 @@ pm_sysctl_proc_handler(ctl_table *ctl, i
+ 	printk("PM: task %s (pid %d) uses deprecated sysctl PM interface\n",
+ 		current->comm, current->pid);
+ 	if (write)
+-		ret = suspend();
++		ret = pm_suspend(PM_SUSPEND_MEM);
+ 	return ret;
+ }
+ 
+--- linux-2.6.0-test6/arch/arm/kernel/process.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/kernel/process.c	2003-10-05 00:33:23.000000000 -0700
+@@ -117,12 +117,10 @@ __setup("reboot=", reboot_setup);
+ 
+ void machine_halt(void)
+ {
+-	leds_event(led_halted);
+ }
+ 
+ void machine_power_off(void)
+ {
+-	leds_event(led_halted);
+ 	if (pm_power_off)
+ 		pm_power_off();
+ }
+--- linux-2.6.0-test6/arch/arm/kernel/setup.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/kernel/setup.c	2003-10-05 00:33:23.000000000 -0700
+@@ -182,7 +182,7 @@ static const char *proc_arch[] = {
+ 	"5",
+ 	"5T",
+ 	"5TE",
+-	"?(8)",
++	"5TEJ",
+ 	"?(9)",
+ 	"?(10)",
+ 	"?(11)",
+--- linux-2.6.0-test6/arch/arm/kernel/signal.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/arm/kernel/signal.c	2003-10-05 00:33:23.000000000 -0700
+@@ -21,6 +21,7 @@
+ #include <linux/tty.h>
+ #include <linux/binfmts.h>
+ #include <linux/elf.h>
++#include <linux/suspend.h>
+ 
+ #include <asm/pgalloc.h>
+ #include <asm/ucontext.h>
+@@ -539,6 +540,11 @@ static int do_signal(sigset_t *oldset, s
+ 	if (!user_mode(regs))
+ 		return 0;
+ 
++	if (current->flags & PF_FREEZE) {
++		refrigerator(0);
++		goto no_signal;
++	}
++
+ 	if (current->ptrace & PT_SINGLESTEP)
+ 		ptrace_cancel_bpt(current);
+ 
+@@ -550,6 +556,7 @@ static int do_signal(sigset_t *oldset, s
+ 		return 1;
+ 	}
+ 
++ no_signal:
+ 	/*
+ 	 * No signal to deliver to the process - restart the syscall.
+ 	 */
+--- linux-2.6.0-test6/arch/arm/kernel/time.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/kernel/time.c	2003-10-05 00:33:23.000000000 -0700
+@@ -26,6 +26,7 @@
+ #include <linux/timex.h>
+ #include <linux/errno.h>
+ #include <linux/profile.h>
++#include <linux/sysdev.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+@@ -72,8 +73,6 @@ unsigned long (*gettimeoffset)(void) = d
+  */
+ unsigned long long sched_clock(void)
+ {
+-	unsigned long long this_offset;
+-
+ 	return (unsigned long long)jiffies * (1000000000 / HZ);
+ }
+ 
+@@ -137,6 +136,47 @@ static void dummy_leds_event(led_event_t
+ 
+ void (*leds_event)(led_event_t) = dummy_leds_event;
+ 
++static int leds_suspend(struct sys_device *dev, u32 state)
++{
++	leds_event(led_stop);
++	return 0;
++}
++
++static int leds_resume(struct sys_device *dev)
++{
++	leds_event(led_start);
++	return 0;
++}
++
++static int leds_shutdown(struct sys_device *dev)
++{
++	leds_event(led_halted);
++	return 0;
++}
++
++static struct sysdev_class leds_sysclass = {
++	set_kset_name("leds"),
++	.shutdown	= leds_shutdown,
++	.suspend	= leds_suspend,
++	.resume		= leds_resume,
++};
++
++static struct sys_device leds_device = {
++	.id		= 0,
++	.cls		= &leds_sysclass,
++};
++
++static int __init leds_init(void)
++{
++	int ret;
++	ret = sysdev_class_register(&leds_sysclass);
++	if (ret == 0)
++		ret = sys_device_register(&leds_device);
++	return ret;
++}
++
++device_initcall(leds_init);
++
+ EXPORT_SYMBOL(leds_event);
+ #endif
+ 
+--- linux-2.6.0-test6/arch/arm/kernel/traps.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/arm/kernel/traps.c	2003-10-05 00:33:23.000000000 -0700
+@@ -212,10 +212,10 @@ NORET_TYPE void die(const char *str, str
+ 	printk("CPU: %d\n", smp_processor_id());
+ 	show_regs(regs);
+ 	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
+-		current->comm, current->pid, tsk->thread_info + 1);
++		tsk->comm, tsk->pid, tsk->thread_info + 1);
+ 
+ 	if (!user_mode(regs) || in_interrupt()) {
+-		dump_mem("Stack: ", (unsigned long)(regs + 1), 8192+(unsigned long)tsk->thread_info);
++		dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
+ 		dump_backtrace(regs, tsk);
+ 		dump_instr(regs);
+ 	}
+--- linux-2.6.0-test6/arch/arm/lib/io-readsl-armv4.S	2003-06-14 12:18:30.000000000 -0700
++++ 25/arch/arm/lib/io-readsl-armv4.S	2003-10-05 00:33:23.000000000 -0700
+@@ -9,7 +9,6 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
+ 
+ /*
+  * Note that some reads can be aligned on half-word boundaries.
+@@ -31,6 +30,10 @@ ENTRY(__raw_readsl)
+ 		blt	4f
+ 		bgt	6f
+ 
++#ifndef	__ARMEB__
++
++		/* little endian code */
++
+ 		strh	ip, [r1], #2
+ 		mov	ip, ip, lsr #16
+ 3:		subs	r2, r2, #1
+@@ -68,3 +71,48 @@ ENTRY(__raw_readsl)
+ 		strb	ip, [r1]
+ 		mov	pc, lr
+ 
++#else
++
++		/* big endian code */
++
++
++		mov	r3, ip, lsr #16
++		strh	r3, [r1], #2
++3:		mov	r3, ip, lsl #16
++		subs	r2, r2, #1
++		ldrne	ip, [r0]
++		orrne	r3, r3, ip, lsr #16
++		strne	r3, [r1], #4
++		bne	3b
++ 		strh	ip, [r1], #2
++ 		mov	pc, lr
++
++4:		mov	r3, ip, lsr #24
++		strb	r3, [r1], #1
++		mov	r3, ip, lsr #8
++		strh	r3, [r1], #2
++5:		mov	r3, ip, lsl #24
++		subs	r2, r2, #1
++		ldrne	ip, [r0]
++		orrne	r3, r3, ip, lsr #8
++		strne	r3, [r1], #4
++		bne	5b
++		strb	ip, [r1], #1
++		mov	pc, lr
++
++6:		mov	r3, ip, lsr #24
++		strb	r3, [r1], #1
++7:		mov	r3, ip, lsl #8
++		subs	r2, r2, #1
++		ldrne	ip, [r0]
++		orrne	r3, r3, ip, lsr #24
++		strne	r3, [r1], #4
++		bne	7b
++		mov	r3, ip, lsr #8
++		strh	r3, [r1], #2
++		strb	ip, [r1], #1
++		mov	pc, lr
++
++#endif
++
++
+--- linux-2.6.0-test6/arch/arm/lib/io-readsw-armv4.S	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/arm/lib/io-readsw-armv4.S	2003-10-05 00:33:23.000000000 -0700
+@@ -9,7 +9,14 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
++
++		.macro	pack, rd, hw1, hw2
++#ifndef __ARMEB__
++		orr	\rd, \hw1, \hw2, lsl #16
++#else
++		orr	\rd, \hw2, \hw1, lsl #16
++#endif
++		.endm
+ 
+ .insw_bad_alignment:
+ 		adr	r0, .insw_bad_align_msg
+@@ -41,19 +48,19 @@ ENTRY(__raw_readsw)
+ 
+ .insw_8_lp:	ldrh	r3, [r0]
+ 		ldrh	r4, [r0]
+-		orr	r3, r3, r4, lsl #16
++		pack	r3, r3, r4
+ 
+ 		ldrh	r4, [r0]
+ 		ldrh	r5, [r0]
+-		orr	r4, r4, r5, lsl #16
++		pack	r4, r4, r5
+ 
+ 		ldrh	r5, [r0]
+ 		ldrh	ip, [r0]
+-		orr	r5, r5, ip, lsl #16
++		pack	r5, r5, ip
+ 
+ 		ldrh	ip, [r0]
+ 		ldrh	lr, [r0]
+-		orr	ip, ip, lr, lsl #16
++		pack	ip, ip, lr
+ 
+ 		stmia	r1!, {r3 - r5, ip}
+ 
+@@ -68,11 +75,11 @@ ENTRY(__raw_readsw)
+ 
+ 		ldrh	r3, [r0]
+ 		ldrh	r4, [r0]
+-		orr	r3, r3, r4, lsl #16
++		pack	r3, r3, r4
+ 
+ 		ldrh	r4, [r0]
+ 		ldrh	ip, [r0]
+-		orr	r4, r4, ip, lsl #16
++		pack	r4, r4, ip
+ 
+ 		stmia	r1!, {r3, r4}
+ 
+@@ -81,7 +88,7 @@ ENTRY(__raw_readsw)
+ 
+ 		ldrh	r3, [r0]
+ 		ldrh	ip, [r0]
+-		orr	r3, r3, ip, lsl #16
++		pack	r3, r3, ip
+ 
+ 		str	r3, [r1], #4
+ 
+--- linux-2.6.0-test6/arch/arm/lib/io-writesw-armv4.S	2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/arm/lib/io-writesw-armv4.S	2003-10-05 00:33:23.000000000 -0700
+@@ -9,7 +9,18 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
++
++		.macro	outword, rd
++#ifndef __ARMEB__
++		strh	\rd, [r0]
++		mov	\rd, \rd, lsr #16
++		strh	\rd, [r0]
++#else
++		mov	lr, \rd, lsr #16
++		strh	lr, [r0]
++		strh	\rd, [r0]
++#endif
++		.endm
+ 
+ .outsw_bad_alignment:
+ 		adr	r0, .outsw_bad_align_msg
+@@ -40,20 +51,10 @@ ENTRY(__raw_writesw)
+ 		bmi	.no_outsw_8
+ 
+ .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
+-
+-		strh	r3, [r0]
+-		mov	r3, r3, lsr #16
+-		strh	r3, [r0]
+-		strh	r4, [r0]
+-		mov	r4, r4, lsr #16
+-		strh	r4, [r0]
+-		strh	r5, [r0]
+-		mov	r5, r5, lsr #16
+-		strh	r5, [r0]
+-		strh	ip, [r0]
+-		mov	ip, ip, lsr #16
+-		strh	ip, [r0]
+-
++		outword	r3
++		outword	r4
++		outword	r5
++		outword	ip
+ 		subs	r2, r2, #8
+ 		bpl	.outsw_8_lp
+ 
+@@ -64,20 +65,14 @@ ENTRY(__raw_writesw)
+ 		beq	.no_outsw_4
+ 
+ 		ldmia	r1!, {r3, ip}
+-		strh	r3, [r0]
+-		mov	r3, r3, lsr #16
+-		strh	r3, [r0]
+-		strh	ip, [r0]
+-		mov	ip, ip, lsr #16
+-		strh	ip, [r0]
++		outword	r3
++		outword	ip
+ 
+ .no_outsw_4:	tst	r2, #2
+ 		beq	.no_outsw_2
+ 
+ 		ldr	r3, [r1], #4
+-		strh	r3, [r0]
+-		mov	r3, r3, lsr #16
+-		strh	r3, [r0]
++		outword	r3
+ 
+ .no_outsw_2:	tst	r2, #1
+ 		ldrneh	r3, [r1]
+--- linux-2.6.0-test6/arch/arm/lib/lib1funcs.S	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/lib/lib1funcs.S	2003-10-05 00:33:23.000000000 -0700
+@@ -1,7 +1,12 @@
+-@ libgcc1 routines for ARM cpu.
+-@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
++/*
++ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
++ *
++ * Author: Nicolas Pitre <nico@cam.org>
++ *   - contributed to gcc-3.4 on Sep 30, 2003
++ *   - adapted for the Linux kernel on Oct 2, 2003
++ */
+ 
+-/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ 
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+@@ -10,11 +15,12 @@ later version.
+ 
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+-compiled version of this file with other programs, and to distribute
+-those programs without any restriction coming from the use of this
+-file.  (The General Public License restrictions do apply in other
+-respects; for example, they cover modification of the file, and
+-distribution when not linked into another program.)
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file.  (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
+ 
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+@@ -26,286 +32,283 @@ along with this program; see the file CO
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+ 
+-/* As a special exception, if you link this library with other files,
+-   some of which are compiled with GCC, to produce an executable,
+-   this library does not by itself cause the resulting executable
+-   to be covered by the GNU General Public License.
+-   This exception does not however invalidate any other reasons why
+-   the executable file might be covered by the GNU General Public License.
+- */
+-/* This code is derived from gcc 2.95.3
+- * 29/07/01 Adapted for linux
+- * 27/03/03 Ian Molton Clean up CONFIG_CPU
+- */
+ 
+ #include <linux/linkage.h>
+ #include <asm/assembler.h>
+-#include <asm/hardware.h>
+ 
+-#define RET	mov
+-#define RETc(x)	mov##x
+-#define RETCOND
+-
+-dividend	.req	r0
+-divisor		.req	r1
+-result		.req	r2
+-overdone        .req    r2
+-curbit		.req	r3
++
++.macro ARM_DIV_BODY dividend, divisor, result, curbit
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\curbit, \divisor
++	clz	\result, \dividend
++	sub	\result, \curbit, \result
++	mov	\curbit, #1
++	mov	\divisor, \divisor, lsl \result
++	mov	\curbit, \curbit, lsl \result
++	mov	\result, #0
+ 	
+-ENTRY(__udivsi3)
+-	cmp	divisor, #0
+-	beq	Ldiv0
+-	mov	curbit, #1
+-	mov	result, #0
+-	cmp	dividend, divisor
+-	bcc	Lgot_result_udivsi3
+-1:
++#else
++
++	@ Initially shift the divisor left 3 bits if possible,
++	@ set curbit accordingly.  This allows for curbit to be located
++	@ at the left end of each 4 bit nibbles in the division loop
++	@ to save one loop in most cases.
++	tst	\divisor, #0xe0000000
++	moveq	\divisor, \divisor, lsl #3
++	moveq	\curbit, #8
++	movne	\curbit, #1
++
+ 	@ Unless the divisor is very big, shift it up in multiples of
+ 	@ four bits, since this is the amount of unwinding in the main
+ 	@ division loop.  Continue shifting until the divisor is 
+ 	@ larger than the dividend.
+-	cmp	divisor, #0x10000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #4
+-	movcc	curbit, curbit, lsl #4
+-	bcc	1b
++1:	cmp	\divisor, #0x10000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #4
++	movlo	\curbit, \curbit, lsl #4
++	blo	1b
+ 
+-2:
+ 	@ For very big divisors, we must shift it a bit at a time, or
+ 	@ we will be in danger of overflowing.
+-	cmp	divisor, #0x80000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #1
+-	movcc	curbit, curbit, lsl #1
+-	bcc	2b
+-
+-3:
+-	@ Test for possible subtractions, and note which bits
+-	@ are done in the result.  On the final pass, this may subtract
+-	@ too much from the dividend, but the result will be ok, since the
+-	@ "bit" will have been shifted out at the bottom.
+-	cmp	dividend, divisor
+-	subcs	dividend, dividend, divisor
+-	orrcs	result, result, curbit
+-	cmp	dividend, divisor, lsr #1
+-	subcs	dividend, dividend, divisor, lsr #1
+-	orrcs	result, result, curbit, lsr #1
+-	cmp	dividend, divisor, lsr #2
+-	subcs	dividend, dividend, divisor, lsr #2
+-	orrcs	result, result, curbit, lsr #2
+-	cmp	dividend, divisor, lsr #3
+-	subcs	dividend, dividend, divisor, lsr #3
+-	orrcs	result, result, curbit, lsr #3
+-	cmp	dividend, #0			@ Early termination?
+-	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+-	movne	divisor, divisor, lsr #4
+-	bne	3b
+-Lgot_result_udivsi3:
+-	mov	r0, result
+-	RET	pc, lr
++1:	cmp	\divisor, #0x80000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #1
++	movlo	\curbit, \curbit, lsl #1
++	blo	1b
+ 
+-Ldiv0:
+-	str	lr, [sp, #-4]!
+-	bl	__div0
+-	mov	r0, #0			@ about as wrong as it could be
+-	ldmia	sp!, {pc}RETCOND
++	mov	\result, #0
+ 
+-/* __umodsi3 ----------------------- */
++#endif
++
++	@ Division loop
++1:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	orrhs	\result,   \result,   \curbit
++	cmp	\dividend, \divisor,  lsr #1
++	subhs	\dividend, \dividend, \divisor, lsr #1
++	orrhs	\result,   \result,   \curbit,  lsr #1
++	cmp	\dividend, \divisor,  lsr #2
++	subhs	\dividend, \dividend, \divisor, lsr #2
++	orrhs	\result,   \result,   \curbit,  lsr #2
++	cmp	\dividend, \divisor,  lsr #3
++	subhs	\dividend, \dividend, \divisor, lsr #3
++	orrhs	\result,   \result,   \curbit,  lsr #3
++	cmp	\dividend, #0			@ Early termination?
++	movnes	\curbit,   \curbit,  lsr #4	@ No, any more bits to do?
++	movne	\divisor,  \divisor, lsr #4
++	bne	1b
++
++.endm
++
++
++.macro ARM_DIV2_ORDER divisor, order
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\order, \divisor
++	rsb	\order, \order, #31
++
++#else
++
++	cmp	\divisor, #(1 << 16)
++	movhs	\divisor, \divisor, lsr #16
++	movhs	\order, #16
++	movlo	\order, #0
++
++	cmp	\divisor, #(1 << 8)
++	movhs	\divisor, \divisor, lsr #8
++	addhs	\order, \order, #8
++
++	cmp	\divisor, #(1 << 4)
++	movhs	\divisor, \divisor, lsr #4
++	addhs	\order, \order, #4
++
++	cmp	\divisor, #(1 << 2)
++	addhi	\order, \order, #3
++	addls	\order, \order, \divisor, lsr #1
++
++#endif
++
++.endm
++
++
++.macro ARM_MOD_BODY dividend, divisor, order, spare
++
++#if __LINUX_ARM_ARCH__ >= 5
++
++	clz	\order, \divisor
++	clz	\spare, \dividend
++	sub	\order, \order, \spare
++	mov	\divisor, \divisor, lsl \order
++
++#else
++
++	mov	\order, #0
+ 
+-ENTRY(__umodsi3)
+-	cmp	divisor, #0
+-	beq	Ldiv0
+-	mov	curbit, #1
+-	cmp	dividend, divisor
+-	RETc(cc)	pc, lr
+-1:
+ 	@ Unless the divisor is very big, shift it up in multiples of
+ 	@ four bits, since this is the amount of unwinding in the main
+ 	@ division loop.  Continue shifting until the divisor is 
+ 	@ larger than the dividend.
+-	cmp	divisor, #0x10000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #4
+-	movcc	curbit, curbit, lsl #4
+-	bcc	1b
++1:	cmp	\divisor, #0x10000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #4
++	addlo	\order, \order, #4
++	blo	1b
+ 
+-2:
+ 	@ For very big divisors, we must shift it a bit at a time, or
+ 	@ we will be in danger of overflowing.
+-	cmp	divisor, #0x80000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #1
+-	movcc	curbit, curbit, lsl #1
+-	bcc	2b
+-
+-3:
+-	@ Test for possible subtractions.  On the final pass, this may 
+-	@ subtract too much from the dividend, so keep track of which
+-	@ subtractions are done, we can fix them up afterwards...
+-	mov	overdone, #0
+-	cmp	dividend, divisor
+-	subcs	dividend, dividend, divisor
+-	cmp	dividend, divisor, lsr #1
+-	subcs	dividend, dividend, divisor, lsr #1
+-	orrcs	overdone, overdone, curbit, ror #1
+-	cmp	dividend, divisor, lsr #2
+-	subcs	dividend, dividend, divisor, lsr #2
+-	orrcs	overdone, overdone, curbit, ror #2
+-	cmp	dividend, divisor, lsr #3
+-	subcs	dividend, dividend, divisor, lsr #3
+-	orrcs	overdone, overdone, curbit, ror #3
+-	mov	ip, curbit
+-	cmp	dividend, #0			@ Early termination?
+-	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+-	movne	divisor, divisor, lsr #4
+-	bne	3b
+-
+-	@ Any subtractions that we should not have done will be recorded in
+-	@ the top three bits of "overdone".  Exactly which were not needed
+-	@ are governed by the position of the bit, stored in ip.
+-	@ If we terminated early, because dividend became zero,
+-	@ then none of the below will match, since the bit in ip will not be
+-	@ in the bottom nibble.
+-	ands	overdone, overdone, #0xe0000000
+-	RETc(eq)	pc, lr				@ No fixups needed
+-	tst	overdone, ip, ror #3
+-	addne	dividend, dividend, divisor, lsr #3
+-	tst	overdone, ip, ror #2
+-	addne	dividend, dividend, divisor, lsr #2
+-	tst	overdone, ip, ror #1
+-	addne	dividend, dividend, divisor, lsr #1
+-	RET	pc, lr
++1:	cmp	\divisor, #0x80000000
++	cmplo	\divisor, \dividend
++	movlo	\divisor, \divisor, lsl #1
++	addlo	\order, \order, #1
++	blo	1b
++
++#endif
++
++	@ Perform all needed substractions to keep only the reminder.
++	@ Do comparisons in batch of 4 first.
++	subs	\order, \order, #3		@ yes, 3 is intended here
++	blt	2f
++
++1:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	cmp	\dividend, \divisor,  lsr #1
++	subhs	\dividend, \dividend, \divisor, lsr #1
++	cmp	\dividend, \divisor,  lsr #2
++	subhs	\dividend, \dividend, \divisor, lsr #2
++	cmp	\dividend, \divisor,  lsr #3
++	subhs	\dividend, \dividend, \divisor, lsr #3
++	cmp	\dividend, #1
++	mov	\divisor, \divisor, lsr #4
++	subges	\order, \order, #4
++	bge	1b
++
++	tst	\order, #3
++	teqne	\dividend, #0
++	beq	5f
++
++	@ Either 1, 2 or 3 comparison/substractions are left.
++2:	cmn	\order, #2
++	blt	4f
++	beq	3f
++	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	mov	\divisor,  \divisor,  lsr #1
++3:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++	mov	\divisor,  \divisor,  lsr #1
++4:	cmp	\dividend, \divisor
++	subhs	\dividend, \dividend, \divisor
++5:
++.endm
++
++
++ENTRY(__udivsi3)
++
++	subs	r2, r1, #1
++	moveq	pc, lr
++	bcc	Ldiv0
++	cmp	r0, r1
++	bls	11f
++	tst	r1, r2
++	beq	12f
++
++	ARM_DIV_BODY r0, r1, r2, r3
++
++	mov	r0, r2
++	mov	pc, lr
++
++11:	moveq	r0, #1
++	movne	r0, #0
++	mov	pc, lr
++
++12:	ARM_DIV2_ORDER r1, r2
++
++	mov	r0, r0, lsr r2
++	mov	pc, lr
++
++
++ENTRY(__umodsi3)
++
++	subs	r2, r1, #1			@ compare divisor with 1
++	bcc	Ldiv0
++	cmpne	r0, r1				@ compare dividend with divisor
++	moveq   r0, #0
++	tsthi	r1, r2				@ see if divisor is power of 2
++	andeq	r0, r0, r2
++	movls	pc, lr
++
++	ARM_MOD_BODY r0, r1, r2, r3
++
++	mov	pc, lr
++
+ 
+ ENTRY(__divsi3)
+-	eor	ip, dividend, divisor		@ Save the sign of the result.
+-	mov	curbit, #1
+-	mov	result, #0
+-	cmp	divisor, #0
+-	rsbmi	divisor, divisor, #0		@ Loops below use unsigned.
++
++	cmp	r1, #0
++	eor	ip, r0, r1			@ save the sign of the result.
+ 	beq	Ldiv0
+-	cmp	dividend, #0
+-	rsbmi	dividend, dividend, #0
+-	cmp	dividend, divisor
+-	bcc	Lgot_result_divsi3
++	rsbmi	r1, r1, #0			@ loops below use unsigned.
++	subs	r2, r1, #1			@ division by 1 or -1 ?
++	beq	10f
++	movs	r3, r0
++	rsbmi	r3, r0, #0			@ positive dividend value
++	cmp	r3, r1
++	bls	11f
++	tst	r1, r2				@ divisor is power of 2 ?
++	beq	12f
+ 
+-1:
+-	@ Unless the divisor is very big, shift it up in multiples of
+-	@ four bits, since this is the amount of unwinding in the main
+-	@ division loop.  Continue shifting until the divisor is 
+-	@ larger than the dividend.
+-	cmp	divisor, #0x10000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #4
+-	movcc	curbit, curbit, lsl #4
+-	bcc	1b
++	ARM_DIV_BODY r3, r1, r0, r2
+ 
+-2:
+-	@ For very big divisors, we must shift it a bit at a time, or
+-	@ we will be in danger of overflowing.
+-	cmp	divisor, #0x80000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #1
+-	movcc	curbit, curbit, lsl #1
+-	bcc	2b
+-
+-3:
+-	@ Test for possible subtractions, and note which bits
+-	@ are done in the result.  On the final pass, this may subtract
+-	@ too much from the dividend, but the result will be ok, since the
+-	@ "bit" will have been shifted out at the bottom.
+-	cmp	dividend, divisor
+-	subcs	dividend, dividend, divisor
+-	orrcs	result, result, curbit
+-	cmp	dividend, divisor, lsr #1
+-	subcs	dividend, dividend, divisor, lsr #1
+-	orrcs	result, result, curbit, lsr #1
+-	cmp	dividend, divisor, lsr #2
+-	subcs	dividend, dividend, divisor, lsr #2
+-	orrcs	result, result, curbit, lsr #2
+-	cmp	dividend, divisor, lsr #3
+-	subcs	dividend, dividend, divisor, lsr #3
+-	orrcs	result, result, curbit, lsr #3
+-	cmp	dividend, #0			@ Early termination?
+-	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+-	movne	divisor, divisor, lsr #4
+-	bne	3b
+-Lgot_result_divsi3:
+-	mov	r0, result
+ 	cmp	ip, #0
+ 	rsbmi	r0, r0, #0
+-	RET	pc, lr
++	mov	pc, lr
++
++10:	teq	ip, r0				@ same sign ?
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++11:	movlo	r0, #0
++	moveq	r0, ip, asr #31
++	orreq	r0, r0, #1
++	mov	pc, lr
++
++12:	ARM_DIV2_ORDER r1, r2
++
++	cmp	ip, #0
++	mov	r0, r3, lsr r2
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
+ 
+ ENTRY(__modsi3)
+-	mov	curbit, #1
+-	cmp	divisor, #0
+-	rsbmi	divisor, divisor, #0		@ Loops below use unsigned.
++
++	cmp	r1, #0
+ 	beq	Ldiv0
+-	@ Need to save the sign of the dividend, unfortunately, we need
+-	@ ip later on; this is faster than pushing lr and using that.
+-	str	dividend, [sp, #-4]!
+-	cmp	dividend, #0
+-	rsbmi	dividend, dividend, #0
+-	cmp	dividend, divisor
+-	bcc	Lgot_result_modsi3
++	rsbmi	r1, r1, #0			@ loops below use unsigned.
++	movs	ip, r0				@ preserve sign of dividend
++	rsbmi	r0, r0, #0			@ if negative make positive
++	subs	r2, r1, #1			@ compare divisor with 1
++	cmpne	r0, r1				@ compare dividend with divisor
++	moveq	r0, #0
++	tsthi	r1, r2				@ see if divisor is power of 2
++	andeq	r0, r0, r2
++	bls	10f
++
++	ARM_MOD_BODY r0, r1, r2, r3
++
++10:	cmp	ip, #0
++	rsbmi	r0, r0, #0
++	mov	pc, lr
++
++
++Ldiv0:
++
++	str	lr, [sp, #-4]!
++	bl	__div0
++	mov	r0, #0			@ About as wrong as it could be.
++	ldr	pc, [sp], #4
+ 
+-1:
+-	@ Unless the divisor is very big, shift it up in multiples of
+-	@ four bits, since this is the amount of unwinding in the main
+-	@ division loop.  Continue shifting until the divisor is 
+-	@ larger than the dividend.
+-	cmp	divisor, #0x10000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #4
+-	movcc	curbit, curbit, lsl #4
+-	bcc	1b
+ 
+-2:
+-	@ For very big divisors, we must shift it a bit at a time, or
+-	@ we will be in danger of overflowing.
+-	cmp	divisor, #0x80000000
+-	cmpcc	divisor, dividend
+-	movcc	divisor, divisor, lsl #1
+-	movcc	curbit, curbit, lsl #1
+-	bcc	2b
+-
+-3:
+-	@ Test for possible subtractions.  On the final pass, this may 
+-	@ subtract too much from the dividend, so keep track of which
+-	@ subtractions are done, we can fix them up afterwards...
+-	mov	overdone, #0
+-	cmp	dividend, divisor
+-	subcs	dividend, dividend, divisor
+-	cmp	dividend, divisor, lsr #1
+-	subcs	dividend, dividend, divisor, lsr #1
+-	orrcs	overdone, overdone, curbit, ror #1
+-	cmp	dividend, divisor, lsr #2
+-	subcs	dividend, dividend, divisor, lsr #2
+-	orrcs	overdone, overdone, curbit, ror #2
+-	cmp	dividend, divisor, lsr #3
+-	subcs	dividend, dividend, divisor, lsr #3
+-	orrcs	overdone, overdone, curbit, ror #3
+-	mov	ip, curbit
+-	cmp	dividend, #0			@ Early termination?
+-	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+-	movne	divisor, divisor, lsr #4
+-	bne	3b
+-
+-	@ Any subtractions that we should not have done will be recorded in
+-	@ the top three bits of "overdone".  Exactly which were not needed
+-	@ are governed by the position of the bit, stored in ip.
+-	@ If we terminated early, because dividend became zero,
+-	@ then none of the below will match, since the bit in ip will not be
+-	@ in the bottom nibble.
+-	ands	overdone, overdone, #0xe0000000
+-	beq	Lgot_result_modsi3
+-	tst	overdone, ip, ror #3
+-	addne	dividend, dividend, divisor, lsr #3
+-	tst	overdone, ip, ror #2
+-	addne	dividend, dividend, divisor, lsr #2
+-	tst	overdone, ip, ror #1
+-	addne	dividend, dividend, divisor, lsr #1
+-Lgot_result_modsi3:
+-	ldr	ip, [sp], #4
+-	cmp	ip, #0
+-	rsbmi	dividend, dividend, #0
+-	RET	pc, lr
+--- linux-2.6.0-test6/arch/arm/mach-integrator/core.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/mach-integrator/core.c	2003-10-05 00:33:23.000000000 -0700
+@@ -1,134 +1,59 @@
+ /*
+- *  linux/arch/arm/mach-integrator/arch.c
++ *  linux/arch/arm/mach-integrator/core.c
+  *
+- *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
+  *
+  * This program 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.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ * it under the terms of the GNU General Public License version 2, as
++ * published by the Free Software Foundation.
+  */
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/list.h>
+ #include <linux/device.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+ 
+ #include <asm/hardware.h>
+-#include <asm/io.h>
+ #include <asm/irq.h>
+-#include <asm/setup.h>
+-#include <asm/mach-types.h>
+ #include <asm/hardware/amba.h>
+-#include <asm/hardware/amba_kmi.h>
+-
+-#include <asm/arch/lm.h>
+-
+-#include <asm/mach/arch.h>
+-#include <asm/mach/irq.h>
+-#include <asm/mach/map.h>
+-
+-/* 
+- * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+- * is the (PA >> 12).
+- *
+- * Setup a VA for the Integrator interrupt controller (for header #0,
+- * just for now).
+- */
+-#define VA_IC_BASE	IO_ADDRESS(INTEGRATOR_IC_BASE) 
+-#define VA_SC_BASE	IO_ADDRESS(INTEGRATOR_SC_BASE)
+-#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+-
+-/*
+- * Logical      Physical
+- * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
+- * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
+- * ed000000	62000000	PCI V3 regs		PHYS_PCI_V3_BASE	(max 64k)
+- * ee000000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
+- * ef000000			Cache flush
+- * f1000000	10000000	Core module registers
+- * f1100000	11000000	System controller registers
+- * f1200000	12000000	EBI registers
+- * f1300000	13000000	Counter/Timer
+- * f1400000	14000000	Interrupt controller
+- * f1500000	15000000	RTC
+- * f1600000	16000000	UART 0
+- * f1700000	17000000	UART 1
+- * f1a00000	1a000000	Debug LEDs
+- * f1b00000	1b000000	GPIO
+- */
+ 
+-static struct map_desc integrator_io_desc[] __initdata = {
+- { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
+- { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
+- { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
+- { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
+- { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
+- { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
++static struct amba_device rtc_device = {
++	.dev		= {
++		.bus_id	= "mb:15",
++	},
++	.res		= {
++		.start	= INTEGRATOR_RTC_BASE,
++		.end	= INTEGRATOR_RTC_BASE + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	.irq		= IRQ_RTCINT,
++	.periphid	= 0x00041030,
+ };
+ 
+-static void __init integrator_map_io(void)
+-{
+-	iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
+-}
+-
+-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
+-
+-static void sc_mask_irq(unsigned int irq)
+-{
+-	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+-}
+-
+-static void sc_unmask_irq(unsigned int irq)
+-{
+-	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+-}
+-
+-static struct irqchip sc_chip = {
+-	.ack	= sc_mask_irq,
+-	.mask	= sc_mask_irq,
+-	.unmask = sc_unmask_irq,
++static struct amba_device uart0_device = {
++	.dev		= {
++		.bus_id	= "mb:16",
++	},
++	.res		= {
++		.start	= INTEGRATOR_UART0_BASE,
++		.end	= INTEGRATOR_UART0_BASE + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	.irq		= IRQ_UARTINT0,
++	.periphid	= 0x0041010,
+ };
+ 
+-static void __init integrator_init_irq(void)
+-{
+-	unsigned int i;
+-
+-	/* Disable all interrupts initially. */
+-	/* Do the core module ones */
+-	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+-
+-	/* do the header card stuff next */
+-	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+-	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+-
+-	for (i = 0; i < NR_IRQS; i++) {
+-		if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+-			set_irq_chip(i, &sc_chip);
+-			set_irq_handler(i, do_level_IRQ);
+-			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+-		}
+-	}
+-}
++static struct amba_device uart1_device = {
++	.dev		= {
++		.bus_id	= "mb:17",
++	},
++	.res		= {
++		.start	= INTEGRATOR_UART1_BASE,
++		.end	= INTEGRATOR_UART1_BASE + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	.irq		= IRQ_UARTINT1,
++	.periphid	= 0x0041010,
++};
+ 
+ static struct amba_device kmi0_device = {
+ 	.dev		= {
+@@ -136,7 +61,7 @@ static struct amba_device kmi0_device = 
+ 	},
+ 	.res		= {
+ 		.start	= KMI0_BASE,
+-		.end	= KMI0_BASE + KMI_SIZE - 1,
++		.end	= KMI0_BASE + SZ_4K - 1,
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ 	.irq		= IRQ_KMIINT0,
+@@ -149,7 +74,7 @@ static struct amba_device kmi1_device = 
+ 	},
+ 	.res		= {
+ 		.start	= KMI1_BASE,
+-		.end	= KMI1_BASE + KMI_SIZE - 1,
++		.end	= KMI1_BASE + SZ_4K - 1,
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ 	.irq		= IRQ_KMIINT1,
+@@ -157,52 +82,23 @@ static struct amba_device kmi1_device = 
+ };
+ 
+ static struct amba_device *amba_devs[] __initdata = {
++	&rtc_device,
++	&uart0_device,
++	&uart1_device,
+ 	&kmi0_device,
+ 	&kmi1_device,
+ };
+ 
+-static int __init register_devices(void)
++static int __init integrator_init(void)
+ {
+-	unsigned long sc_dec;
+ 	int i;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ 		struct amba_device *d = amba_devs[i];
+-
+ 		amba_device_register(d, &iomem_resource);
+ 	}
+ 
+-	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+-	for (i = 0; i < 4; i++) {
+-		struct lm_device *lmdev;
+-
+-		if ((sc_dec & (16 << i)) == 0)
+-			continue;
+-
+-		lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
+-		if (!lmdev)
+-			continue;
+-
+-		memset(lmdev, 0, sizeof(struct lm_device));
+-
+-		lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+-		lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+-		lmdev->resource.flags = IORESOURCE_MEM;
+-		lmdev->irq = IRQ_EXPINT0 + i;
+-		lmdev->id = i;
+-
+-		lm_device_register(lmdev);
+-	}
+-
+ 	return 0;
+ }
+ 
+-arch_initcall(register_devices);
+-
+-MACHINE_START(INTEGRATOR, "ARM-Integrator")
+-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+-	BOOT_PARAMS(0x00000100)
+-	MAPIO(integrator_map_io)
+-	INITIRQ(integrator_init_irq)
+-MACHINE_END
++arch_initcall(integrator_init);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/arm/mach-integrator/integrator_ap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -0,0 +1,294 @@
++/*
++ *  linux/arch/arm/mach-integrator/integrator_ap.c
++ *
++ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
++ *
++ * This program 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/hardware/amba.h>
++#include <asm/hardware/amba_kmi.h>
++
++#include <asm/arch/lm.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/map.h>
++
++
++/* 
++ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
++ * is the (PA >> 12).
++ *
++ * Setup a VA for the Integrator interrupt controller (for header #0,
++ * just for now).
++ */
++#define VA_IC_BASE	IO_ADDRESS(INTEGRATOR_IC_BASE) 
++#define VA_SC_BASE	IO_ADDRESS(INTEGRATOR_SC_BASE)
++#define VA_EBI_BASE	IO_ADDRESS(INTEGRATOR_EBI_BASE)
++#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
++
++/*
++ * Logical      Physical
++ * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
++ * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
++ * ed000000	62000000	PCI V3 regs		PHYS_PCI_V3_BASE	(max 64k)
++ * ee000000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
++ * ef000000			Cache flush
++ * f1000000	10000000	Core module registers
++ * f1100000	11000000	System controller registers
++ * f1200000	12000000	EBI registers
++ * f1300000	13000000	Counter/Timer
++ * f1400000	14000000	Interrupt controller
++ * f1500000	15000000	RTC
++ * f1600000	16000000	UART 0
++ * f1700000	17000000	UART 1
++ * f1a00000	1a000000	Debug LEDs
++ * f1b00000	1b000000	GPIO
++ */
++
++static struct map_desc ap_io_desc[] __initdata = {
++ { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
++ { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
++ { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
++ { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
++ { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
++ { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
++};
++
++static void __init ap_map_io(void)
++{
++	iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
++}
++
++#define INTEGRATOR_SC_VALID_INT	0x003fffff
++
++static void sc_mask_irq(unsigned int irq)
++{
++	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
++}
++
++static void sc_unmask_irq(unsigned int irq)
++{
++	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
++}
++
++static struct irqchip sc_chip = {
++	.ack	= sc_mask_irq,
++	.mask	= sc_mask_irq,
++	.unmask = sc_unmask_irq,
++};
++
++static void __init ap_init_irq(void)
++{
++	unsigned int i;
++
++	/* Disable all interrupts initially. */
++	/* Do the core module ones */
++	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
++
++	/* do the header card stuff next */
++	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
++	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
++
++	for (i = 0; i < NR_IRQS; i++) {
++		if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
++			set_irq_chip(i, &sc_chip);
++			set_irq_handler(i, do_level_IRQ);
++			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++		}
++	}
++}
++
++#ifdef CONFIG_PM
++static unsigned long ic_irq_enable;
++
++static int irq_suspend(struct sys_device *dev, u32 state)
++{
++	ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
++	return 0;
++}
++
++static int irq_resume(struct sys_device *dev)
++{
++	/* disable all irq sources */
++	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
++	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
++	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
++
++	writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
++	return 0;
++}
++#else
++#define irq_suspend NULL
++#define irq_resume NULL
++#endif
++
++static struct sysdev_class irq_class = {
++	set_kset_name("irq"),
++	.suspend	= irq_suspend,
++	.resume		= irq_resume,
++};
++
++static struct sys_device irq_device = {
++	.id	= 0,
++	.cls	= &irq_class,
++};
++
++static int __init irq_init_sysfs(void)
++{
++	int ret = sysdev_class_register(&irq_class);
++	if (ret == 0)
++		ret = sys_device_register(&irq_device);
++	return ret;
++}
++
++device_initcall(irq_init_sysfs);
++
++/*
++ * Flash handling.
++ */
++#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
++#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
++#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
++#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
++
++static int ap_flash_init(void)
++{
++	u32 tmp;
++
++	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
++
++	tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
++	writel(tmp, EBI_CSR1);
++
++	if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
++		writel(0xa05f, EBI_LOCK);
++		writel(tmp, EBI_CSR1);
++		writel(0, EBI_LOCK);
++	}
++	return 0;
++}
++
++static void ap_flash_exit(void)
++{
++	u32 tmp;
++
++	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
++
++	tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
++	writel(tmp, EBI_CSR1);
++
++	if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
++		writel(0xa05f, EBI_LOCK);
++		writel(tmp, EBI_CSR1);
++		writel(0, EBI_LOCK);
++	}
++}
++
++static void ap_flash_set_vpp(int on)
++{
++	unsigned long reg = on ? SC_CTRLS : SC_CTRLC;
++
++	writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
++}
++
++static struct flash_platform_data ap_flash_data = {
++	.map_name	= "cfi_probe",
++	.width		= 4,
++	.init		= ap_flash_init,
++	.exit		= ap_flash_exit,
++	.set_vpp	= ap_flash_set_vpp,
++};
++
++static struct resource cfi_flash_resource = {
++	.start		= INTEGRATOR_FLASH_BASE,
++	.end		= INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
++	.flags		= IORESOURCE_MEM,
++};
++
++static struct platform_device cfi_flash_device = {
++	.name		= "armflash",
++	.id		= 0,
++	.dev		= {
++		.platform_data	= &ap_flash_data,
++	},
++	.num_resources	= 1,
++	.resource	= &cfi_flash_resource,
++};
++
++static int __init ap_init(void)
++{
++	unsigned long sc_dec;
++	int i;
++
++	platform_add_device(&cfi_flash_device);
++
++	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
++	for (i = 0; i < 4; i++) {
++		struct lm_device *lmdev;
++
++		if ((sc_dec & (16 << i)) == 0)
++			continue;
++
++		lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL);
++		if (!lmdev)
++			continue;
++
++		memset(lmdev, 0, sizeof(struct lm_device));
++
++		lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
++		lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
++		lmdev->resource.flags = IORESOURCE_MEM;
++		lmdev->irq = IRQ_AP_EXPINT0 + i;
++		lmdev->id = i;
++
++		lm_device_register(lmdev);
++	}
++
++	return 0;
++}
++
++arch_initcall(ap_init);
++
++MACHINE_START(INTEGRATOR, "ARM-Integrator")
++	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
++	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
++	BOOT_PARAMS(0x00000100)
++	MAPIO(ap_map_io)
++	INITIRQ(ap_init_irq)
++MACHINE_END
+--- linux-2.6.0-test6/arch/arm/mach-integrator/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/mach-integrator/Kconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -1,8 +1,15 @@
+ menu "Integrator Options"
+ 	depends on ARCH_INTEGRATOR
+ 
++config ARCH_INTEGRATOR_AP
++	bool "Support Integrator/AP and Integrator/PP2 platforms"
++	help
++	  Include support for the ARM(R) Integrator/AP and
++	  Integrator/PP2 platforms.
++
+ config INTEGRATOR_IMPD1
+ 	tristate "Include support for Integrator/IM-PD1"
++	depends on ARCH_INTEGRATOR_AP
+ 	help
+ 	  The IM-PD1 is an add-on logic module for the Integrator which
+ 	  allows ARM(R) Ltd PrimeCells to be developed and evaluated.
+--- linux-2.6.0-test6/arch/arm/mach-integrator/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/mach-integrator/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -4,9 +4,10 @@
+ 
+ # Object file lists.
+ 
+-obj-y			:= core.o lm.o time.o
++obj-y					:= core.o lm.o time.o
++obj-$(CONFIG_ARCH_INTEGRATOR_AP)	+= integrator_ap.o
+ 
+-obj-$(CONFIG_LEDS)	+= leds.o
+-obj-$(CONFIG_PCI)	+= pci_v3.o pci.o
++obj-$(CONFIG_LEDS)			+= leds.o
++obj-$(CONFIG_PCI)			+= pci_v3.o pci.o
+ obj-$(CONFIG_CPU_FREQ_INTEGRATOR)	+= cpu.o
+ obj-$(CONFIG_INTEGRATOR_IMPD1)		+= impd1.o
+--- linux-2.6.0-test6/arch/arm/mach-integrator/pci.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/arm/mach-integrator/pci.c	2003-10-05 00:33:23.000000000 -0700
+@@ -96,7 +96,7 @@ static u8 __init integrator_swizzle(stru
+ }
+ 
+ static int irq_tab[4] __initdata = {
+-	IRQ_PCIINT0,	IRQ_PCIINT1,	IRQ_PCIINT2,	IRQ_PCIINT3
++	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
+ };
+ 
+ /*
+--- linux-2.6.0-test6/arch/arm/mach-integrator/pci_v3.c	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/arm/mach-integrator/pci_v3.c	2003-10-05 00:33:23.000000000 -0700
+@@ -575,7 +575,7 @@ void __init pci_v3_preinit(void)
+ 	/*
+ 	 * Grab the PCI error interrupt.
+ 	 */
+-	ret = request_irq(IRQ_V3INT, v3_irq, 0, "V3", NULL);
++	ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
+ 	if (ret)
+ 		printk(KERN_ERR "PCI: unable to grab PCI error "
+ 		       "interrupt: %d\n", ret);
+@@ -596,7 +596,7 @@ void __init pci_v3_postinit(void)
+ 	v3_writeb(V3_LB_IMASK, 0x68);
+ 
+ #if 0
+-	ret = request_irq(IRQ_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
++	ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
+ 	if (ret)
+ 		printk(KERN_ERR "PCI: unable to grab local bus timeout "
+ 		       "interrupt: %d\n", ret);
+--- linux-2.6.0-test6/arch/arm/mach-pxa/irq.c	2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/arm/mach-pxa/irq.c	2003-10-05 00:33:23.000000000 -0700
+@@ -58,7 +58,19 @@ static int pxa_gpio_irq_type(unsigned in
+ {
+ 	int gpio, idx;
+ 
+-	gpio = irq - ((irq >= IRQ_GPIO(2)) ? IRQ_GPIO(2) + 2 : IRQ_GPIO(0));
++	gpio = IRQ_TO_GPIO(irq);
++	idx = gpio >> 5;
++
++	if (type == IRQT_PROBE) {
++	    /* Don't mess with enabled GPIOs using preconfigured edges or
++	       GPIOs set to alternate function during probe */
++		if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
++		    GPIO_bit(gpio))
++			return 0;
++		if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
++			return 0;
++		type = __IRQT_RISEDGE | __IRQT_FALEDGE;
++	}
+ 
+ 	printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio);
+ 
+@@ -78,10 +90,8 @@ static int pxa_gpio_irq_type(unsigned in
+ 
+ 	printk("edges\n");
+ 
+-	idx = gpio >> 5;
+ 	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
+ 	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
+-
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/arch/arm/mach-pxa/leds.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/mach-pxa/leds.c	2003-10-05 00:33:23.000000000 -0700
+@@ -7,6 +7,7 @@
+  *
+  * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+  */
++#include <linux/compiler.h>
+ #include <linux/init.h>
+ 
+ #include <asm/leds.h>
+--- linux-2.6.0-test6/arch/arm/mach-pxa/lubbock.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/arm/mach-pxa/lubbock.c	2003-10-05 00:33:23.000000000 -0700
+@@ -78,7 +78,7 @@ static void __init lubbock_init_irq(void
+ 	pxa_init_irq();
+ 
+ 	/* setup extra lubbock irqs */
+-	for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_IRQ(5); irq++) {
++	for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
+ 		set_irq_chip(irq, &lubbock_irq_chip);
+ 		set_irq_handler(irq, do_level_IRQ);
+ 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+@@ -124,6 +124,7 @@ static struct map_desc lubbock_io_desc[]
+   { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE }, /* CPLD */
+   { 0xf1000000, 0x0c000000, 0x00100000, MT_DEVICE }, /* LAN91C96 IO */
+   { 0xf1100000, 0x0e000000, 0x00100000, MT_DEVICE }, /* LAN91C96 Attr */
++  { 0xf4000000, 0x10000000, 0x00800000, MT_DEVICE }, /* SA1111 */
+ };
+ 
+ static void __init lubbock_map_io(void)
+--- linux-2.6.0-test6/arch/arm/mach-pxa/pm.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/mach-pxa/pm.c	2003-10-05 00:33:23.000000000 -0700
+@@ -11,13 +11,14 @@
+  * modify it under the terms of the GNU General Public License.
+  */
+ #include <linux/config.h>
++#include <linux/init.h>
++#include <linux/suspend.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/memory.h>
+ #include <asm/system.h>
+-#include <asm/leds.h>
+ 
+ 
+ /*
+@@ -60,13 +61,16 @@ enum {	SLEEP_SAVE_START = 0,
+ };
+ 
+ 
+-int pm_do_suspend(void)
++static int pxa_pm_enter(u32 state)
+ {
+ 	unsigned long sleep_save[SLEEP_SAVE_SIZE];
+ 	unsigned long checksum = 0;
+ 	unsigned long delta;
+ 	int i;
+ 
++	if (state != PM_SUSPEND_MEM)
++		return -EINVAL;
++
+ 	/* preserve current time */
+ 	delta = xtime.tv_sec - RCNR;
+ 
+@@ -194,3 +198,37 @@ unsigned long sleep_phys_sp(void *sp)
+ {
+ 	return virt_to_phys(sp);
+ }
++
++/*
++ * Called after processes are frozen, but before we shut down devices.
++ */
++static int pxa_pm_prepare(u32 state)
++{
++	return 0;
++}
++
++/*
++ * Called after devices are re-setup, but before processes are thawed.
++ */
++static int pxa_pm_finish(u32 state)
++{
++	return 0;
++}
++
++/*
++ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
++ */
++static struct pm_ops pxa_pm_ops = {
++	.pm_disk_mode	= PM_DISK_FIRMWARE,
++	.prepare	= pxa_pm_prepare,
++	.enter		= pxa_pm_enter,
++	.finish		= pxa_pm_finish,
++};
++
++static int __init pxa_pm_init(void)
++{
++	pm_set_ops(&pxa_pm_ops);
++	return 0;
++}
++
++late_initcall(pxa_pm_init);
+--- linux-2.6.0-test6/arch/arm/mach-sa1100/leds.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/arm/mach-sa1100/leds.c	2003-10-05 00:33:23.000000000 -0700
+@@ -5,6 +5,7 @@
+  * 
+  * Copyright (C) 2001 Nicolas Pitre
+  */
++#include <linux/compiler.h>
+ #include <linux/init.h>
+ 
+ #include <asm/leds.h>
+--- linux-2.6.0-test6/arch/arm/mach-sa1100/pm.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/arm/mach-sa1100/pm.c	2003-10-05 00:33:23.000000000 -0700
+@@ -22,6 +22,8 @@
+  * 2002-05-27:	Nicolas Pitre	Killed sleep.h and the kmalloced save array.
+  * 				Storage is local on the stack now.
+  */
++#include <linux/init.h>
++#include <linux/suspend.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+ 
+@@ -54,11 +56,14 @@ enum {	SLEEP_SAVE_SP = 0,
+ };
+ 
+ 
+-int pm_do_suspend(void)
++static int sa11x0_pm_enter(u32 state)
+ {
+ 	unsigned long sleep_save[SLEEP_SAVE_SIZE];
+ 	unsigned long delta, gpio;
+ 
++	if (state != PM_SUSPEND_MEM)
++		return -EINVAL;
++
+ 	/* preserve current time */
+ 	delta = xtime.tv_sec - RCNR;
+ 	gpio = GPLR;
+@@ -139,3 +144,37 @@ unsigned long sleep_phys_sp(void *sp)
+ {
+ 	return virt_to_phys(sp);
+ }
++
++/*
++ * Called after processes are frozen, but before we shut down devices.
++ */
++static int sa11x0_pm_prepare(u32 state)
++{
++	return 0;
++}
++
++/*
++ * Called after devices are re-setup, but before processes are thawed.
++ */
++static int sa11x0_pm_finish(u32 state)
++{
++	return 0;
++}
++
++/*
++ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
++ */
++static struct pm_ops sa11x0_pm_ops = {
++	.pm_disk_mode	= PM_DISK_FIRMWARE,
++	.prepare	= sa11x0_pm_prepare,
++	.enter		= sa11x0_pm_enter,
++	.finish		= sa11x0_pm_finish,
++};
++
++static int __init sa11x0_pm_init(void)
++{
++	pm_set_ops(&sa11x0_pm_ops);
++	return 0;
++}
++
++late_initcall(sa11x0_pm_init);
+--- linux-2.6.0-test6/arch/arm/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/arm/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -182,7 +182,6 @@ define archhelp
+   echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+   echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+   echo  '  bootpImage    - Combined zImage and initial RAM disk' 
+-  echo  '  initrd        - Create an initial image'
+   echo  '  install       - Install uncompressed kernel'
+   echo  '  zinstall      - Install compressed kernel'
+   echo  '                  Install using (your) ~/bin/installkernel or'
+--- linux-2.6.0-test6/arch/arm/mm/discontig.c	2003-06-14 12:18:31.000000000 -0700
++++ 25/arch/arm/mm/discontig.c	2003-10-05 00:34:40.000000000 -0700
+@@ -15,7 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+ 
+-#if NR_NODES != 4
++#if MAX_NUMNODES != 4
+ #error Fix Me Please
+ #endif
+ 
+@@ -23,9 +23,9 @@
+  * Our node_data structure for discontiguous memory.
+  */
+ 
+-static bootmem_data_t node_bootmem_data[NR_NODES];
++static bootmem_data_t node_bootmem_data[MAX_NUMNODES];
+ 
+-pg_data_t discontig_node_data[NR_NODES] = {
++pg_data_t discontig_node_data[MAX_NUMNODES] = {
+   { .bdata = &node_bootmem_data[0] },
+   { .bdata = &node_bootmem_data[1] },
+   { .bdata = &node_bootmem_data[2] },
+--- linux-2.6.0-test6/arch/arm/mm/init.c	2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/arm/mm/init.c	2003-10-05 00:34:40.000000000 -0700
+@@ -33,12 +33,6 @@
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ 
+-#ifndef CONFIG_DISCONTIGMEM
+-#define NR_NODES	1
+-#else
+-#define NR_NODES	4
+-#endif
+-
+ #ifdef CONFIG_CPU_32
+ #define TABLE_OFFSET	(PTRS_PER_PTE)
+ #else
+@@ -178,7 +172,7 @@ find_memend_and_nodes(struct meminfo *mi
+ {
+ 	unsigned int i, bootmem_pages = 0, memend_pfn = 0;
+ 
+-	for (i = 0; i < NR_NODES; i++) {
++	for (i = 0; i < MAX_NUMNODES; i++) {
+ 		np[i].start = -1U;
+ 		np[i].end = 0;
+ 		np[i].bootmap_pages = 0;
+@@ -207,7 +201,7 @@ find_memend_and_nodes(struct meminfo *mi
+ 			 * we have, we're in trouble.  (maybe we ought to
+ 			 * limit, instead of bugging?)
+ 			 */
+-			if (numnodes > NR_NODES)
++			if (numnodes > MAX_NUMNODES)
+ 				BUG();
+ 		}
+ 
+@@ -365,7 +359,7 @@ static inline void free_bootmem_node_ban
+  */
+ void __init bootmem_init(struct meminfo *mi)
+ {
+-	struct node_info node_info[NR_NODES], *np = node_info;
++	struct node_info node_info[MAX_NUMNODES], *np = node_info;
+ 	unsigned int bootmap_pages, bootmap_pfn, map_pg;
+ 	int node, initrd_node;
+ 
+--- linux-2.6.0-test6/arch/arm/mm/ioremap.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/arm/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -150,7 +150,7 @@ __ioremap(unsigned long phys_addr, size_
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/cris/mm/ioremap.c	2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/cris/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -157,7 +157,7 @@ void * __ioremap(unsigned long phys_addr
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/h8300/README	2003-06-14 12:18:26.000000000 -0700
++++ 25/arch/h8300/README	2003-10-05 00:33:23.000000000 -0700
+@@ -16,7 +16,7 @@ H8S is planning.
+ 
+ 3.H8MAX 
+   Under development
+-  see http://www.strawbelly-linux.com (Japanese Only)
++  see http://www.strawberry-linux.com (Japanese Only)
+ 
+ * Toolchain Version
+ gcc-3.1 or higher and patch
+--- linux-2.6.0-test6/arch/i386/boot/setup.S	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/boot/setup.S	2003-10-05 00:36:48.000000000 -0700
+@@ -162,7 +162,7 @@ cmd_line_ptr:	.long 0			# (Header versio
+ 					# can be located anywhere in
+ 					# low memory 0x10000 or higher.
+ 
+-ramdisk_max:	.long MAXMEM-1		# (Header version 0x0203 or later)
++ramdisk_max:	.long __MAXMEM-1	# (Header version 0x0203 or later)
+ 					# The highest safe address for
+ 					# the contents of an initrd
+ 
+--- linux-2.6.0-test6/arch/i386/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/Kconfig	2003-10-05 00:36:48.000000000 -0700
+@@ -397,6 +397,54 @@ config X86_OOSTORE
+ 	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6
+ 	default y
+ 
++config X86_4G
++	bool "4 GB kernel-space and 4 GB user-space virtual memory support"
++	help
++          This option is only useful for systems that have more than 1 GB
++          of RAM.
++
++          The default kernel VM layout leaves 1 GB of virtual memory for
++          kernel-space mappings, and 3 GB of VM for user-space applications.
++          This option ups both the kernel-space VM and the user-space VM to
++          4 GB.
++
++          The cost of this option is additional TLB flushes done at
++          system-entry points that transition from user-mode into kernel-mode.
++          I.e. system calls and page faults, and IRQs that interrupt user-mode
++          code. There's also additional overhead to kernel operations that copy
++          memory to/from user-space. The overhead from this is hard to tell and
++          depends on the workload - it can be anything from no visible overhead
++          to 20-30% overhead. A good rule of thumb is to count with a runtime
++          overhead of 20%.
++
++          The upside is the much increased kernel-space VM, which more than
++          quadruples the maximum amount of RAM supported. Kernels compiled with
++          this option boot on 64GB of RAM and still have more than 3.1 GB of
++          'lowmem' left. Another bonus is that highmem IO bouncing decreases,
++          if used with drivers that still use bounce-buffers.
++
++          There's also a 33% increase in user-space VM size - database
++          applications might see a boost from this.
++
++          But the cost of the TLB flushes and the runtime overhead has to be
++          weighed against the bonuses offered by the larger VM spaces. The
++          dividing line depends on the actual workload - there might be 4 GB
++          systems that benefit from this option. Systems with less than 4 GB
++          of RAM will rarely see a benefit from this option - but it's not
++          out of question, the exact circumstances have to be considered.
++
++config X86_SWITCH_PAGETABLES
++	def_bool X86_4G
++
++config X86_4G_VM_LAYOUT
++	def_bool X86_4G
++
++config X86_UACCESS_INDIRECT
++	def_bool X86_4G
++
++config X86_HIGH_ENTRY
++	def_bool X86_4G
++
+ config HPET_TIMER
+ 	bool "HPET Timer Support"
+ 	help
+@@ -793,7 +841,8 @@ config HAVE_DEC_LOCK
+ # Summit needs it only when NUMA is on
+ config BOOT_IOREMAP
+ 	bool
+-	depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA)
++	depends on X86_PC
++# depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA)) || X86_GENERICARCH
+ 	default y
+ 
+ endmenu
+@@ -1030,6 +1079,25 @@ config PCI_DIRECT
+  	depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
+ 	default y
+ 
++config PCI_USE_VECTOR
++	bool "Vector-based interrupt indexing"
++	depends on X86_LOCAL_APIC
++	default n
++	help
++	   This replaces the current existing IRQ-based index interrupt scheme
++	   with the vector-base index scheme. The advantages of vector base
++	   over IRQ base are listed below:
++	   1) Support MSI implementation.
++	   2) Support future IOxAPIC hotplug
++
++	   Note that this enables MSI, Message Signaled Interrupt, on all
++	   MSI capable device functions detected if users also install the
++	   MSI patch. Message Signal Interrupt enables an MSI-capable
++	   hardware device to send an inbound Memory Write on its PCI bus
++	   instead of asserting IRQ signal on device IRQ pin.
++
++	   If you don't know what to do here, say N.
++
+ source "drivers/pci/Kconfig"
+ 
+ config ISA
+@@ -1231,6 +1299,15 @@ config DEBUG_PAGEALLOC
+ 	  This results in a large slowdown, but helps to find certain types
+ 	  of memory corruptions.
+ 
++config SPINLINE
++	bool "Spinlock inlining"
++	depends on DEBUG_KERNEL
++	help
++	  This will change spinlocks from out of line to inline, making them
++	  account cost to the callers in readprofile, rather than the lock
++	  itself (as ".text.lock.filename"). This can be helpful for finding
++	  the callers of locks.
++
+ config DEBUG_HIGHMEM
+ 	bool "Highmem debugging"
+ 	depends on DEBUG_KERNEL && HIGHMEM
+@@ -1247,20 +1324,208 @@ config DEBUG_INFO
+ 	  Say Y here only if you plan to use gdb to debug the kernel.
+ 	  If you don't debug the kernel, you can say N.
+ 	  
++config LOCKMETER
++	bool "Kernel lock metering"
++	depends on SMP && !PREEMPT
++	help
++	  Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++	  but allows you to see various statistics using the lockstat command.
++
+ config DEBUG_SPINLOCK_SLEEP
+ 	bool "Sleep-inside-spinlock checking"
+ 	help
+ 	  If you say Y here, various routines which may sleep will become very
+ 	  noisy if they are called with a spinlock held.	
+ 
++config KGDB
++	bool "Include kgdb kernel debugger"
++	depends on DEBUG_KERNEL
++	help
++	  If you say Y here, the system will be compiled with the debug
++	  option (-g) and a debugging stub will be included in the
++	  kernel.  This stub communicates with gdb on another (host)
++	  computer via a serial port.  The host computer should have
++	  access to the kernel binary file (vmlinux) and a serial port
++	  that is connected to the target machine.  Gdb can be made to
++	  configure the serial port or you can use stty and setserial to
++	  do this. See the 'target' command in gdb. This option also
++	  configures in the ability to request a breakpoint early in the
++	  boot process.  To request the breakpoint just include 'kgdb'
++	  as a boot option when booting the target machine.  The system
++	  will then break as soon as it looks at the boot options.  This
++	  option also installs a breakpoint in panic and sends any
++	  kernel faults to the debugger. For more information see the
++	  Documentation/i386/kgdb.txt file.
++
++choice
++	depends on KGDB
++    	prompt "Debug serial port BAUD"
++	default KGDB_115200BAUD
++	help
++	  Gdb and the kernel stub need to agree on the baud rate to be
++	  used.  Some systems (x86 family at this writing) allow this to
++	  be configured.
++
++config KGDB_9600BAUD
++	bool "9600"
++
++config KGDB_19200BAUD
++	bool "19200"
++
++config KGDB_38400BAUD
++	bool "38400"
++
++config KGDB_57600BAUD
++	bool "57600"
++
++config KGDB_115200BAUD
++	bool "115200"
++endchoice
++
++config KGDB_PORT
++	hex "hex I/O port address of the debug serial port"
++	depends on KGDB
++	default  3f8
++	help
++	  Some systems (x86 family at this writing) allow the port
++	  address to be configured.  The number entered is assumed to be
++	  hex, don't put 0x in front of it.  The standard address are:
++	  COM1 3f8 , irq 4 and COM2 2f8 irq 3.  Setserial /dev/ttySx
++	  will tell you what you have.  It is good to test the serial
++	  connection with a live system before trying to debug.
++
++config KGDB_IRQ
++	int "IRQ of the debug serial port"
++	depends on KGDB
++	default 4
++	help
++	  This is the irq for the debug port.  If everything is working
++	  correctly and the kernel has interrupts on a control C to the
++	  port should cause a break into the kernel debug stub.
++
++config DEBUG_INFO
++	bool
++	depends on KGDB
++	default y
++
++config KGDB_MORE
++	bool "Add any additional compile options"
++	depends on KGDB
++	default n
++	help
++	  Saying yes here turns on the ability to enter additional
++	  compile options.
++
++
++config KGDB_OPTIONS
++	depends on KGDB_MORE
++	string "Additional compile arguments"
++	default "-O1"
++	help
++	  This option allows you enter additional compile options for
++	  the whole kernel compile.  Each platform will have a default
++	  that seems right for it.  For example on PPC "-ggdb -O1", and
++	  for i386 "-O1".  Note that by configuring KGDB "-g" is already
++	  turned on.  In addition, on i386 platforms
++	  "-fomit-frame-pointer" is deleted from the standard compile
++	  options.
++
++config NO_KGDB_CPUS
++	int "Number of CPUs"
++	depends on KGDB && SMP
++	default NR_CPUS
++	help
++
++	  This option sets the number of cpus for kgdb ONLY.  It is used
++	  to prune some internal structures so they look "nice" when
++	  displayed with gdb.  This is to overcome possibly larger
++	  numbers that may have been entered above.  Enter the real
++	  number to get nice clean kgdb_info displays.
++
++config KGDB_TS
++	bool "Enable kgdb time stamp macros?"
++	depends on KGDB
++	default n
++	help
++	  Kgdb event macros allow you to instrument your code with calls
++	  to the kgdb event recording function.  The event log may be
++	  examined with gdb at a break point.  Turning on this
++	  capability also allows you to choose how many events to
++	  keep. Kgdb always keeps the lastest events.
++
++choice
++	depends on KGDB_TS
++	prompt "Max number of time stamps to save?"
++	default KGDB_TS_128
++
++config KGDB_TS_64
++	bool "64"
++
++config KGDB_TS_128
++	bool "128"
++
++config KGDB_TS_256
++	bool "256"
++
++config KGDB_TS_512
++	bool "512"
++
++config KGDB_TS_1024
++	bool "1024"
++
++endchoice
++
++config STACK_OVERFLOW_TEST
++	bool "Turn on kernel stack overflow testing?"
++	depends on KGDB
++	default n
++	help
++	  This option enables code in the front line interrupt handlers
++	  to check for kernel stack overflow on interrupts and system
++	  calls.  This is part of the kgdb code on x86 systems.
++
++config KGDB_CONSOLE
++	bool "Enable serial console thru kgdb port"
++	depends on KGDB
++	default n
++	help
++	  This option enables the command line "console=kgdb" option.
++	  When the system is booted with this option in the command line
++	  all kernel printk output is sent to gdb (as well as to other
++	  consoles).  For this to work gdb must be connected.  For this
++	  reason, this command line option will generate a breakpoint if
++	  gdb has not yet connected.  After the gdb continue command is
++	  given all pent up console output will be printed by gdb on the
++	  host machine.  Neither this option, nor KGDB require the
++	  serial driver to be configured.
++
++config KGDB_SYSRQ
++	bool "Turn on SysRq 'G' command to do a break?"
++	depends on KGDB
++	default y
++	help
++	  This option includes an option in the SysRq code that allows
++	  you to enter SysRq G which generates a breakpoint to the KGDB
++	  stub.  This will work if the keyboard is alive and can
++	  interrupt the system.  Because of constraints on when the
++	  serial port interrupt can be enabled, this code may allow you
++	  to interrupt the system before the serial port control C is
++	  available.  Just say yes here.
++
+ config FRAME_POINTER
+ 	bool "Compile the kernel with frame pointers"
++	default KGDB
+ 	help
+ 	  If you say Y here the resulting kernel image will be slightly larger
+ 	  and slower, but it will give very useful debugging information.
+ 	  If you don't debug the kernel, you can say N, but we may not be able
+ 	  to solve problems without frame pointers.
+ 
++config MAGIC_SYSRQ
++	bool
++	depends on KGDB_SYSRQ
++	default y
++
+ config X86_EXTRA_IRQS
+ 	bool
+ 	depends on X86_LOCAL_APIC || X86_VOYAGER
+@@ -1303,3 +1568,8 @@ config X86_TRAMPOLINE
+ 	bool
+ 	depends on SMP || X86_VISWS
+ 	default y
++
++config PC
++	bool
++	depends on X86 && !EMBEDDED
++	default y
+--- linux-2.6.0-test6/arch/i386/kernel/acpi/boot.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/kernel/acpi/boot.c	2003-10-05 00:36:22.000000000 -0700
+@@ -26,6 +26,7 @@
+ #include <linux/init.h>
+ #include <linux/config.h>
+ #include <linux/acpi.h>
++#include <linux/efi.h>
+ #include <asm/pgalloc.h>
+ #include <asm/io_apic.h>
+ #include <asm/apic.h>
+@@ -183,8 +184,7 @@ acpi_parse_lapic_nmi (
+ 
+ #endif /*CONFIG_X86_LOCAL_APIC*/
+ 
+-#ifdef CONFIG_X86_IO_APIC
+-
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+ 
+ static int __init
+ acpi_parse_ioapic (
+@@ -297,6 +297,10 @@ acpi_find_rsdp (void)
+ {
+ 	unsigned long		rsdp_phys = 0;
+ 
++	if (efi.acpi20)
++		return __pa(efi.acpi20);
++	else if (efi.acpi)
++		return __pa(efi.acpi);
+ 	/*
+ 	 * Scan memory looking for the RSDP signature. First search EBDA (low
+ 	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
+@@ -368,7 +372,6 @@ acpi_boot_init (void)
+ 
+ 	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
+ 	if (!result) {
+-		printk(KERN_WARNING PREFIX "MADT not present\n");
+ 		return 0;
+ 	}
+ 	else if (result < 0) {
+@@ -416,7 +419,7 @@ acpi_boot_init (void)
+ 
+ #endif /*CONFIG_X86_LOCAL_APIC*/
+ 
+-#ifdef CONFIG_X86_IO_APIC
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+ 
+ 	/* 
+ 	 * I/O APIC 
+@@ -472,7 +475,8 @@ acpi_boot_init (void)
+ 	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+ 
+ 	acpi_ioapic = 1;
+-#endif /*CONFIG_X86_IO_APIC*/
++
++#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */
+ 
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 	if (acpi_lapic && acpi_ioapic) {
+@@ -480,6 +484,7 @@ acpi_boot_init (void)
+ 		clustered_apic_check();
+ 	}
+ #endif
++
+ #ifdef CONFIG_HPET_TIMER
+ 	acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ #endif
+--- linux-2.6.0-test6/arch/i386/kernel/asm-offsets.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/i386/kernel/asm-offsets.c	2003-10-05 00:36:48.000000000 -0700
+@@ -4,9 +4,11 @@
+  * to extract and format the required data.
+  */
+ 
++#include <linux/sched.h>
+ #include <linux/signal.h>
+ #include <asm/ucontext.h>
+ #include "sigframe.h"
++#include <asm/fixmap.h>
+ 
+ #define DEFINE(sym, val) \
+         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+@@ -28,4 +30,17 @@ void foo(void)
+ 
+ 	DEFINE(RT_SIGFRAME_sigcontext,
+ 	       offsetof (struct rt_sigframe, uc.uc_mcontext));
++	DEFINE(TI_task, offsetof (struct thread_info, task));
++	DEFINE(TI_exec_domain, offsetof (struct thread_info, exec_domain));
++	DEFINE(TI_flags, offsetof (struct thread_info, flags));
++	DEFINE(TI_preempt_count, offsetof (struct thread_info, preempt_count));
++	DEFINE(TI_addr_limit, offsetof (struct thread_info, addr_limit));
++	DEFINE(TI_real_stack, offsetof (struct thread_info, real_stack));
++	DEFINE(TI_virtual_stack, offsetof (struct thread_info, virtual_stack));
++	DEFINE(TI_user_pgd, offsetof (struct thread_info, user_pgd));
++
++	DEFINE(FIX_ENTRY_TRAMPOLINE_0_addr, __fix_to_virt(FIX_ENTRY_TRAMPOLINE_0));
++	DEFINE(FIX_VSYSCALL_addr, __fix_to_virt(FIX_VSYSCALL));
++	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
++	DEFINE(task_thread_db7, offsetof (struct task_struct, thread.debugreg[7]));
+ }
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/common.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/cpu/common.c	2003-10-05 00:36:48.000000000 -0700
+@@ -510,16 +510,20 @@ void __init cpu_init (void)
+ 		BUG();
+ 	enter_lazy_tlb(&init_mm, current);
+ 
+-	load_esp0(t, thread->esp0);
+-	set_tss_desc(cpu,t);
++	t->esp0 = thread->esp0;
++	set_tss_desc(cpu, t);
+ 	cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
+ 	load_TR_desc();
+-	load_LDT(&init_mm.context);
++	if (cpu)
++		load_LDT(&init_mm.context);
+ 
+ 	/* Set up doublefault TSS pointer in the GDT */
+ 	__set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
+ 	cpu_gdt_table[cpu][GDT_ENTRY_DOUBLEFAULT_TSS].b &= 0xfffffdff;
+ 
++	if (cpu)
++		trap_init_virtual_GDT();
++
+ 	/* Clear %fs and %gs. */
+ 	asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
+ 
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/cpufreq/acpi.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/acpi.c	2003-10-05 00:33:23.000000000 -0700
+@@ -231,7 +231,7 @@ acpi_processor_set_performance (
+ 	int			state)
+ {
+ 	u16			port = 0;
+-	u8			value = 0;
++	u16			value = 0;
+ 	int			i = 0;
+ 	struct cpufreq_freqs    cpufreq_freqs;
+ 
+@@ -282,9 +282,9 @@ acpi_processor_set_performance (
+ 	value = (u16) perf->states[state].control;
+ 
+ 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+-		"Writing 0x%02x to port 0x%04x\n", value, port));
++		"Writing 0x%04x to port 0x%04x\n", value, port));
+ 
+-	outb(value, port); 
++	outw(value, port); 
+ 
+ 	/*
+ 	 * Then we read the 'status_register' and compare the value with the
+@@ -296,12 +296,12 @@ acpi_processor_set_performance (
+ 	port = perf->status_register;
+ 
+ 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+-		"Looking for 0x%02x from port 0x%04x\n",
+-		(u8) perf->states[state].status, port));
++		"Looking for 0x%04x from port 0x%04x\n",
++		(u16) perf->states[state].status, port));
+ 
+ 	for (i=0; i<100; i++) {
+-		value = inb(port);
+-		if (value == (u8) perf->states[state].status)
++		value = inw(port);
++		if (value == (u16) perf->states[state].status)
+ 			break;
+ 		udelay(10);
+ 	}
+@@ -309,7 +309,7 @@ acpi_processor_set_performance (
+ 	/* notify cpufreq */
+ 	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
+ 
+-	if (value != perf->states[state].status) {
++	if (value != (u16) perf->states[state].status) {
+ 		unsigned int tmp = cpufreq_freqs.new;
+ 		cpufreq_freqs.new = cpufreq_freqs.old;
+ 		cpufreq_freqs.old = tmp;
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -88,6 +88,16 @@ config X86_POWERNOW_K7
+ 
+ 	  If in doubt, say N.
+ 
++config X86_POWERNOW_K8
++	tristate "AMD Opteron/Athlon64 PowerNow!"
++	depends on CPU_FREQ_TABLE
++	help
++	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
++
++	  For details, take a look at linux/Documentation/cpu-freq. 
++
++	  If in doubt, say N.
++
+ config X86_GX_SUSPMOD
+ 	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
+ 	depends on CPU_FREQ
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/cpufreq/longhaul.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/longhaul.c	2003-10-05 00:33:23.000000000 -0700
+@@ -70,21 +70,6 @@ static unsigned int calc_speed (int mult
+ }
+ 
+ 
+-static unsigned int longhaul_get_cpu_fsb (void)
+-{
+-	unsigned long lo, hi;
+-	unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
+-	unsigned int invalue=0;
+-
+-	if (fsb == 0) {
+-		rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
+-		invalue = (lo & (1<<18|1<<19)) >>18;
+-		fsb = eblcr_fsb_table[invalue];
+-	}
+-	return fsb;
+-}
+-
+-
+ static int longhaul_get_cpu_mult (void)
+ {
+ 	unsigned long invalue=0,lo, hi;
+@@ -168,7 +153,7 @@ static void longhaul_setstate (unsigned 
+ 		break;
+ 
+ 	/*
+-	 * Longhaul v3. (Ezra-T [C5M], Nehemiag [C5N])
++	 * Longhaul v3. (Ezra-T [C5M], Nehemiah [C5N])
+ 	 * This can also do voltage scaling, but see above.
+ 	 * Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
+ 	 */
+@@ -193,6 +178,39 @@ static void longhaul_setstate (unsigned 
+ 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ 
++/*
++ * Centaur decided to make life a little more tricky.
++ * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
++ * Samuel2 and above have to try and guess what the FSB is.
++ * We do this by assuming we booted at maximum multiplier, and interpolate
++ * between that value multiplied by possible FSBs and cpu_mhz which
++ * was calculated at boot time. Really ugly, but no other way to do this.
++ */
++static int _guess (int guess, int maxmult)
++{
++	int target;
++
++	target = ((maxmult/10)*guess);
++	if (maxmult%10 != 0)
++		target += (guess/2);
++	target &= ~0xf;
++	return target;
++}
++
++static int guess_fsb(int maxmult)
++{
++	int speed = (cpu_khz/1000) & ~0xf;
++	int i;
++	int speeds[3] = { 66, 100, 133 };
++
++	for (i=0; i<3; i++) {
++		if (_guess(speeds[i],maxmult) == speed)
++			return speeds[i];
++	}
++	return 0;
++}
++
++
+ 
+ static int __init longhaul_get_ranges (void)
+ {
+@@ -203,8 +221,8 @@ static int __init longhaul_get_ranges (v
+ 		-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
+ 	unsigned int j, k = 0;
+ 	union msr_longhaul longhaul;
+-
+-	fsb = longhaul_get_cpu_fsb();
++	unsigned long lo, hi;
++	unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
+ 
+ 	switch (longhaul_version) {
+ 	case 1:
+@@ -212,6 +230,9 @@ static int __init longhaul_get_ranges (v
+ 		   Assume min=3.0x & max = whatever we booted at. */
+ 		minmult = 30;
+ 		maxmult = longhaul_get_cpu_mult();
++		rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
++		invalue = (lo & (1<<18|1<<19)) >>18;
++		fsb = eblcr_fsb_table[invalue];
+ 		break;
+ 
+ 	case 2 ... 3:
+@@ -222,14 +243,13 @@ static int __init longhaul_get_ranges (v
+ 			invalue += 16;
+ 		maxmult=multipliers[invalue];
+ 
+-#if 0
+ 		invalue = longhaul.bits.MinMHzBR;
+-		if (longhaul.bits.MinMHzBR4);
+-			invalue += 16;
+-		minmult = multipliers[invalue];
+-#else
+-		minmult = 30; /* as per spec */
+-#endif
++		if (longhaul.bits.MinMHzBR4 == 1)
++			minmult = 30;
++		else
++			minmult = multipliers[invalue];
++
++		fsb = guess_fsb(maxmult);
+ 		break;
+ 	}
+ 
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/cpufreq/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -1,5 +1,6 @@
+ obj-$(CONFIG_X86_POWERNOW_K6)	+= powernow-k6.o
+ obj-$(CONFIG_X86_POWERNOW_K7)	+= powernow-k7.o
++obj-$(CONFIG_X86_POWERNOW_K8)	+= powernow-k8.o
+ obj-$(CONFIG_X86_LONGHAUL)	+= longhaul.o
+ obj-$(CONFIG_X86_P4_CLOCKMOD)	+= p4-clockmod.o
+ obj-$(CONFIG_ELAN_CPUFREQ)	+= elanfreq.o
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2003-10-05 00:33:23.000000000 -0700
+@@ -0,0 +1,1020 @@
++/*
++ *   (c) 2003 Advanced Micro Devices, Inc.
++ *  Your use of this code is subject to the terms and conditions of the
++ *  GNU general public license version 2. See "../../../COPYING" or
++ *  http://www.gnu.org/licenses/gpl.html
++ *
++ *  Support : paul.devriendt@amd.com
++ *
++ *  Based on the powernow-k7.c module written by Dave Jones.
++ *  (C) 2003 Dave Jones <davej@codemonkey.ork.uk> on behalf of SuSE Labs
++ *  Licensed under the terms of the GNU GPL License version 2.
++ *  Based upon datasheets & sample CPUs kindly provided by AMD.
++ *
++ *  Processor information obtained from Chapter 9 (Power and Thermal Management)
++ *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
++ *  Opteron Processors", revision 3.03, available for download from www.amd.com
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/smp.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/cpufreq.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++
++#include <asm/msr.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++
++#define PFX "powernow-k8: "
++#define BFX PFX "BIOS error: "
++#define VERSION "version 1.00.08 - September 26, 2003"
++#include "powernow-k8.h"
++
++#ifdef CONFIG_PREEMPT
++#warning this driver has not been tested on a preempt system
++#endif
++
++static u32 vstable;	/* voltage stabalization time, from PSB, units 20 us */
++static u32 plllock;	/* pll lock time, from PSB, units 1 us */
++static u32 numps;	/* number of p-states, from PSB */
++static u32 rvo;		/* ramp voltage offset, from PSB */
++static u32 irt;		/* isochronous relief time, from PSB */
++static u32 vidmvs;	/* usable value calculated from mvs, from PSB */
++struct pst_s *ppst;	/* array of p states, valid for this part */
++static u32 currvid;	/* keep track of the current fid / vid */
++static u32 currfid;
++
++/*
++The PSB table supplied by BIOS allows for the definition of the number of
++p-states that can be used when running on a/c, and the number of p-states
++that can be used when running on battery. This allows laptop manufacturers
++to force the system to save power when running from battery. The relationship 
++is :
++   1 <= number_of_battery_p_states <= maximum_number_of_p_states
++
++This driver does NOT have the support in it to detect transitions from
++a/c power to battery power, and thus trigger the transition to a lower
++p-state if required. This is because I need ACPI and the 2.6 kernel to do 
++this, and this is a 2.4 kernel driver. Check back for a new improved driver
++for the 2.6 kernel soon.
++
++This code therefore assumes it is on battery at all times, and thus
++restricts performance to number_of_battery_p_states. For desktops, 
++  number_of_battery_p_states == maximum_number_of_pstates, 
++so this is not actually a restriction.
++*/
++
++static u32 batps;	/* limit on the number of p states when on battery */
++			/* - set by BIOS in the PSB/PST                    */
++
++static struct cpufreq_driver cpufreq_amd64_driver = {
++	.verify = drv_verify,
++	.target = drv_target,
++	.init = drv_cpu_init,
++	.name = "cpufreq-amd64",
++	.owner = THIS_MODULE,
++};
++
++#define SEARCH_UP     1
++#define SEARCH_DOWN   0
++
++/* Return a frequency in MHz, given an input fid */
++u32
++find_freq_from_fid(u32 fid)
++{
++	return 800 + (fid * 100);
++}
++
++/* Return a fid matching an input frequency in MHz */
++u32
++find_fid_from_freq(u32 freq)
++{
++	return (freq - 800) / 100;
++}
++
++/* Return the vco fid for an input fid */
++static u32
++convert_fid_to_vco_fid(u32 fid)
++{
++	if (fid < HI_FID_TABLE_BOTTOM) {
++		return 8 + (2 * fid);
++	} else {
++		return fid;
++	}
++}
++
++/* Sort the fid/vid frequency table into ascending order by fid. The spec */
++/* implies that it will be sorted by BIOS, but, it only implies it, and I */
++/* prefer not to trust when I can check.                                  */
++/* Yes, it is a simple bubble sort, but the PST is really small, so the   */
++/* choice of algorithm is pretty irrelevant.                              */
++static inline void
++sort_pst(struct pst_s *ppst, u32 numpstates)
++{
++	u32 i;
++	u8 tempfid;
++	u8 tempvid;
++	int swaps = 1;
++
++	while (swaps) {
++		swaps = 0;
++		for (i = 0; i < (numpstates - 1); i++) {
++			if (ppst[i].fid > ppst[i + 1].fid) {
++				swaps = 1;
++				tempfid = ppst[i].fid;
++				tempvid = ppst[i].vid;
++				ppst[i].fid = ppst[i + 1].fid;
++				ppst[i].vid = ppst[i + 1].vid;
++				ppst[i + 1].fid = tempfid;
++				ppst[i + 1].vid = tempvid;
++			}
++		}
++	}
++
++	return;
++}
++
++/* Return 1 if the pending bit is set. Unless we are actually just told the */
++/* processor to transition a state, seeing this bit set is really bad news. */
++static inline int
++pending_bit_stuck(void)
++{
++	u32 lo;
++	u32 hi;
++
++	rdmsr(MSR_FIDVID_STATUS, lo, hi);
++	return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
++}
++
++/* Update the global current fid / vid values from the status msr. Returns 1 */
++/* on error.                                                                 */
++static int
++query_current_values_with_pending_wait(void)
++{
++	u32 lo;
++	u32 hi;
++	u32 i = 0;
++
++	lo = MSR_S_LO_CHANGE_PENDING;
++	while (lo & MSR_S_LO_CHANGE_PENDING) {
++		if (i++ > 0x1000000) {
++			printk(KERN_ERR PFX "detected change pending stuck\n");
++			return 1;
++		}
++		rdmsr(MSR_FIDVID_STATUS, lo, hi);
++	}
++
++	currvid = hi & MSR_S_HI_CURRENT_VID;
++	currfid = lo & MSR_S_LO_CURRENT_FID;
++
++	return 0;
++}
++
++/* the isochronous relief time */
++static inline void
++count_off_irt(void)
++{
++	udelay((1 << irt) * 10);
++	return;
++}
++
++/* the voltage stabalization time */
++static inline void
++count_off_vst(void)
++{
++	udelay(vstable * VST_UNITS_20US);
++	return;
++}
++
++/* write the new fid value along with the other control fields to the msr */
++static int
++write_new_fid(u32 fid)
++{
++	u32 lo;
++	u32 savevid = currvid;
++
++	if ((fid & INVALID_FID_MASK) || (currvid & INVALID_VID_MASK)) {
++		printk(KERN_ERR PFX "internal error - overflow on fid write\n");
++		return 1;
++	}
++
++	lo = fid | (currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
++
++	dprintk(KERN_DEBUG PFX "writing fid %x, lo %x, hi %x\n",
++		fid, lo, plllock * PLL_LOCK_CONVERSION);
++
++	wrmsr(MSR_FIDVID_CTL, lo, plllock * PLL_LOCK_CONVERSION);
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	count_off_irt();
++
++	if (savevid != currvid) {
++		printk(KERN_ERR PFX
++		       "vid changed on fid transition, save %x, currvid %x\n",
++		       savevid, currvid);
++		return 1;
++	}
++
++	if (fid != currfid) {
++		printk(KERN_ERR PFX
++		       "fid transition failed, fid %x, currfid %x\n",
++		        fid, currfid);
++		return 1;
++	}
++
++	return 0;
++}
++
++/* Write a new vid to the hardware */
++static int
++write_new_vid(u32 vid)
++{
++	u32 lo;
++	u32 savefid = currfid;
++
++	if ((currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
++		printk(KERN_ERR PFX "internal error - overflow on vid write\n");
++		return 1;
++	}
++
++	lo = currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
++
++	dprintk(KERN_DEBUG PFX "writing vid %x, lo %x, hi %x\n",
++		vid, lo, STOP_GRANT_5NS);
++
++	wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
++
++	if (query_current_values_with_pending_wait()) {
++		return 1;
++	}
++
++	if (savefid != currfid) {
++		printk(KERN_ERR PFX
++		       "fid changed on vid transition, save %x currfid %x\n",
++		       savefid, currfid);
++		return 1;
++	}
++
++	if (vid != currvid) {
++		printk(KERN_ERR PFX
++		       "vid transition failed, vid %x, currvid %x\n",
++		       vid, currvid);
++		return 1;
++	}
++
++	return 0;
++}
++
++/* Reduce the vid by the max of step or reqvid.                   */
++/* Decreasing vid codes represent increasing voltages :           */
++/* vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off. */
++static int
++decrease_vid_code_by_step(u32 reqvid, u32 step)
++{
++	if ((currvid - reqvid) > step)
++		reqvid = currvid - step;
++
++	if (write_new_vid(reqvid))
++		return 1;
++
++	count_off_vst();
++
++	return 0;
++}
++
++/* Change the fid and vid, by the 3 phases. */
++static inline int
++transition_fid_vid(u32 reqfid, u32 reqvid)
++{
++	if (core_voltage_pre_transition(reqvid))
++		return 1;
++
++	if (core_frequency_transition(reqfid))
++		return 1;
++
++	if (core_voltage_post_transition(reqvid))
++		return 1;
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	if ((reqfid != currfid) || (reqvid != currvid)) {
++		printk(KERN_ERR PFX "failed: req 0x%x 0x%x, curr 0x%x 0x%x\n",
++		       reqfid, reqvid, currfid, currvid);
++		return 1;
++	}
++
++	dprintk(KERN_INFO PFX
++		"transitioned: new fid 0x%x, vid 0x%x\n", currfid, currvid);
++
++	return 0;
++}
++
++/* Phase 1 - core voltage transition ... setup appropriate voltage for the */
++/* fid transition.                                                         */
++static inline int
++core_voltage_pre_transition(u32 reqvid)
++{
++	u32 rvosteps = rvo;
++	u32 savefid = currfid;
++
++	dprintk(KERN_DEBUG PFX
++		"ph1: start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo %x\n",
++		currfid, currvid, reqvid, rvo);
++
++	while (currvid > reqvid) {
++		dprintk(KERN_DEBUG PFX "ph1: curr 0x%x, requesting vid 0x%x\n",
++			currvid, reqvid);
++		if (decrease_vid_code_by_step(reqvid, vidmvs))
++			return 1;
++	}
++
++	while (rvosteps > 0) {
++		if (currvid == 0) {
++			rvosteps = 0;
++		} else {
++			dprintk(KERN_DEBUG PFX
++				"ph1: changing vid for rvo, requesting 0x%x\n",
++				currvid - 1);
++			if (decrease_vid_code_by_step(currvid - 1, 1))
++				return 1;
++			rvosteps--;
++		}
++	}
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	if (savefid != currfid) {
++		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", currfid);
++		return 1;
++	}
++
++	dprintk(KERN_DEBUG PFX "ph1 complete, currfid 0x%x, currvid 0x%x\n",
++		currfid, currvid);
++
++	return 0;
++}
++
++/* Phase 2 - core frequency transition */
++static inline int
++core_frequency_transition(u32 reqfid)
++{
++	u32 vcoreqfid;
++	u32 vcocurrfid;
++	u32 vcofiddiff;
++	u32 savevid = currvid;
++
++	if ((reqfid < HI_FID_TABLE_BOTTOM) && (currfid < HI_FID_TABLE_BOTTOM)) {
++		printk(KERN_ERR PFX "ph2 illegal lo-lo transition 0x%x 0x%x\n",
++		       reqfid, currfid);
++		return 1;
++	}
++
++	if (currfid == reqfid) {
++		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", currfid);
++		return 0;
++	}
++
++	dprintk(KERN_DEBUG PFX
++		"ph2 starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
++		currfid, currvid, reqfid);
++
++	vcoreqfid = convert_fid_to_vco_fid(reqfid);
++	vcocurrfid = convert_fid_to_vco_fid(currfid);
++	vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
++	    : vcoreqfid - vcocurrfid;
++
++	while (vcofiddiff > 2) {
++		if (reqfid > currfid) {
++			if (currfid > LO_FID_TABLE_TOP) {
++				if (write_new_fid(currfid + 2)) {
++					return 1;
++				}
++			} else {
++				if (write_new_fid
++				    (2 + convert_fid_to_vco_fid(currfid))) {
++					return 1;
++				}
++			}
++		} else {
++			if (write_new_fid(currfid - 2))
++				return 1;
++		}
++
++		vcocurrfid = convert_fid_to_vco_fid(currfid);
++		vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
++		    : vcoreqfid - vcocurrfid;
++	}
++
++	if (write_new_fid(reqfid))
++		return 1;
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	if (currfid != reqfid) {
++		printk(KERN_ERR PFX
++		       "ph2 mismatch, failed fid transition, curr %x, req %x\n",
++		       currfid, reqfid);
++		return 1;
++	}
++
++	if (savevid != currvid) {
++		printk(KERN_ERR PFX
++		       "ph2 vid changed, save %x, curr %x\n", savevid,
++		       currvid);
++		return 1;
++	}
++
++	dprintk(KERN_DEBUG PFX "ph2 complete, currfid 0x%x, currvid 0x%x\n",
++		currfid, currvid);
++
++	return 0;
++}
++
++/* Phase 3 - core voltage transition flow ... jump to the final vid. */
++static inline int
++core_voltage_post_transition(u32 reqvid)
++{
++	u32 savefid = currfid;
++	u32 savereqvid = reqvid;
++
++	dprintk(KERN_DEBUG PFX "ph3 starting, currfid 0x%x, currvid 0x%x\n",
++		currfid, currvid);
++
++	if (reqvid != currvid) {
++		if (write_new_vid(reqvid))
++			return 1;
++
++		if (savefid != currfid) {
++			printk(KERN_ERR PFX
++			       "ph3: bad fid change, save %x, curr %x\n",
++			       savefid, currfid);
++			return 1;
++		}
++
++		if (currvid != reqvid) {
++			printk(KERN_ERR PFX
++			       "ph3: failed vid transition\n, req %x, curr %x",
++			       reqvid, currvid);
++			return 1;
++		}
++	}
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	if (savereqvid != currvid) {
++		dprintk(KERN_ERR PFX "ph3 failed, currvid 0x%x\n", currvid);
++		return 1;
++	}
++
++	if (savefid != currfid) {
++		dprintk(KERN_ERR PFX "ph3 failed, currfid changed 0x%x\n",
++			currfid);
++		return 1;
++	}
++
++	dprintk(KERN_DEBUG PFX "ph3 complete, currfid 0x%x, currvid 0x%x\n",
++		currfid, currvid);
++
++	return 0;
++}
++
++static inline int
++check_supported_cpu(void)
++{
++	struct cpuinfo_x86 *c = cpu_data;
++	u32 eax, ebx, ecx, edx;
++
++	if (num_online_cpus() != 1) {
++		printk(KERN_INFO PFX "multiprocessor systems not supported\n");
++		return 0;
++	}
++
++	if (c->x86_vendor != X86_VENDOR_AMD) {
++		printk(KERN_INFO PFX "Not an AMD processor\n");
++		return 0;
++	}
++
++	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
++	if ((eax & CPUID_XFAM_MOD) == ATHLON64_XFAM_MOD) {
++		dprintk(KERN_DEBUG PFX "AMD Althon 64 Processor found\n");
++		if ((eax & CPUID_F1_STEP) < ATHLON64_REV_C0) {
++			printk(KERN_INFO PFX "Revision C0 or better "
++			       "AMD Athlon 64 processor required\n");
++			return 0;
++		}
++	} else if ((eax & CPUID_XFAM_MOD) == OPTERON_XFAM_MOD) {
++		dprintk(KERN_DEBUG PFX "AMD Opteron Processor found\n");
++	} else {
++		printk(KERN_INFO PFX
++		       "AMD Athlon 64 or AMD Opteron processor required\n");
++		return 0;
++	}
++
++	eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
++	if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
++		printk(KERN_INFO PFX
++		       "No frequency change capabilities detected\n");
++		return 0;
++	}
++
++	cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
++	if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) {
++		printk(KERN_INFO PFX "Power state transitions not supported\n");
++		return 0;
++	}
++
++	printk(KERN_INFO PFX "Found AMD Athlon 64 / Opteron processor "
++	       "supporting p-state transitions\n");
++
++	return 1;
++}
++
++/* Find and validate the PSB/PST table in BIOS. */
++static inline int
++find_psb_table(void)
++{
++	struct psb_s *psb;
++	struct pst_s *pst;
++	unsigned i, j;
++	u32 lastfid;
++	u32 mvs;
++	u8 maxvid;
++
++	for (i = 0xc0000; i < 0xffff0; i += 0x10) {
++		/* Scan BIOS looking for the signature. */
++		/* It can not be at ffff0 - it is too big. */
++
++		psb = phys_to_virt(i);
++		if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
++			continue;
++
++		dprintk(KERN_DEBUG PFX "found PSB header at 0x%p\n", psb);
++
++		dprintk(KERN_DEBUG PFX "table vers: 0x%x\n", psb->tableversion);
++		if (psb->tableversion != PSB_VERSION_1_4) {
++			printk(KERN_INFO BFX "PSB table is not v1.4\n");
++			return -ENODEV;
++		}
++
++		dprintk(KERN_DEBUG PFX "flags: 0x%x\n", psb->flags1);
++		if (psb->flags1) {
++			printk(KERN_ERR BFX "unknown flags\n");
++			return -ENODEV;
++		}
++
++		vstable = psb->voltagestabilizationtime;
++		printk(KERN_INFO PFX "voltage stable time: %d (units 20us)\n",
++		       vstable);
++
++		dprintk(KERN_DEBUG PFX "flags2: 0x%x\n", psb->flags2);
++		rvo = psb->flags2 & 3;
++		irt = ((psb->flags2) >> 2) & 3;
++		mvs = ((psb->flags2) >> 4) & 3;
++		vidmvs = 1 << mvs;
++		batps = ((psb->flags2) >> 6) & 3;
++		printk(KERN_INFO PFX "p states on battery: %d ", batps);
++		switch (batps) {
++		case 0:
++			printk("- all available\n");
++			break;
++		case 1:
++			printk("- only the minimum\n");
++			break;
++		case 2:
++			printk("- only the 2 lowest\n");
++			break;
++		case 3:
++			printk("- only the 3 lowest\n");
++			break;
++		}
++		printk(KERN_INFO PFX "ramp voltage offset: %d\n", rvo);
++		printk(KERN_INFO PFX "isochronous relief time: %d\n", irt);
++		printk(KERN_INFO PFX "maximum voltage step: %d\n", mvs);
++
++		dprintk(KERN_DEBUG PFX "numpst: 0x%x\n", psb->numpst);
++		if (psb->numpst != 1) {
++			printk(KERN_ERR BFX "numpst must be 1\n");
++			return -ENODEV;
++		}
++
++		dprintk(KERN_DEBUG PFX "cpuid: 0x%x\n", psb->cpuid);
++
++		plllock = psb->plllocktime;
++		printk(KERN_INFO PFX "pll lock time: 0x%x\n", plllock);
++
++		maxvid = psb->maxvid;
++		printk(KERN_INFO PFX "maxfid: 0x%x\n", psb->maxfid);
++		printk(KERN_INFO PFX "maxvid: 0x%x\n", maxvid);
++
++		numps = psb->numpstates;
++		printk(KERN_INFO PFX "numpstates: 0x%x\n", numps);
++		if (numps < 2) {
++			printk(KERN_ERR BFX "no p states to transition\n");
++			return -ENODEV;
++		}
++
++		if (batps == 0) {
++			batps = numps;
++		} else if (batps > numps) {
++			printk(KERN_ERR BFX "batterypstates > numpstates\n");
++			batps = numps;
++		} else {
++			printk(KERN_ERR PFX
++			       "Restricting operation to %d p-states\n", batps);
++			printk(KERN_ERR PFX
++			       "Check for an updated driver to access all "
++			       "%d p-states\n", numps);
++		}
++
++		if ((numps <= 1) || (batps <= 1)) {
++			printk(KERN_ERR PFX "only 1 p-state to transition\n");
++			return -ENODEV;
++		}
++
++		ppst = kmalloc(sizeof (struct pst_s) * numps, GFP_KERNEL);
++		if (!ppst) {
++			printk(KERN_ERR PFX "ppst memory alloc failure\n");
++			return -ENOMEM;
++		}
++
++		pst = (struct pst_s *) (psb + 1);
++		for (j = 0; j < numps; j++) {
++			ppst[j].fid = pst[j].fid;
++			ppst[j].vid = pst[j].vid;
++			printk(KERN_INFO PFX
++			       "   %d : fid 0x%x, vid 0x%x\n", j,
++			       ppst[j].fid, ppst[j].vid);
++		}
++		sort_pst(ppst, numps);
++
++		lastfid = ppst[0].fid;
++		if (lastfid > LO_FID_TABLE_TOP)
++			printk(KERN_INFO BFX "first fid not in lo freq tbl\n");
++
++		if ((lastfid > MAX_FID) || (lastfid & 1) || (ppst[0].vid > LEAST_VID)) {
++			printk(KERN_ERR BFX "first fid/vid bad (0x%x - 0x%x)\n",
++			       lastfid, ppst[0].vid);
++			kfree(ppst);
++			return -ENODEV;
++		}
++
++		for (j = 1; j < numps; j++) {
++			if ((lastfid >= ppst[j].fid)
++			    || (ppst[j].fid & 1)
++			    || (ppst[j].fid < HI_FID_TABLE_BOTTOM)
++			    || (ppst[j].fid > MAX_FID)
++			    || (ppst[j].vid > LEAST_VID)) {
++				printk(KERN_ERR BFX
++				       "invalid fid/vid in pst(%x %x)\n",
++				       ppst[j].fid, ppst[j].vid);
++				kfree(ppst);
++				return -ENODEV;
++			}
++			lastfid = ppst[j].fid;
++		}
++
++		for (j = 0; j < numps; j++) {
++			if (ppst[j].vid < rvo) {	/* vid+rvo >= 0 */
++				printk(KERN_ERR BFX
++				       "0 vid exceeded with pstate %d\n", j);
++				return -ENODEV;
++			}
++			if (ppst[j].vid < maxvid+rvo) { /* vid+rvo >= maxvid */
++				printk(KERN_ERR BFX
++				       "maxvid exceeded with pstate %d\n", j);
++				return -ENODEV;
++			}
++		}
++
++		if (query_current_values_with_pending_wait()) {
++			kfree(ppst);
++			return -EIO;
++		}
++
++		printk(KERN_INFO PFX "currfid 0x%x, currvid 0x%x\n",
++		       currfid, currvid);
++
++		for (j = 0; j < numps; j++)
++			if ((ppst[j].fid==currfid) && (ppst[j].vid==currvid))
++				return (0);
++
++		printk(KERN_ERR BFX "currfid/vid do not match PST, ignoring\n");
++		return 0;
++	}
++
++	printk(KERN_ERR BFX "no PSB\n");
++	return -ENODEV;
++}
++
++/* Converts a frequency (that might not necessarily be a multiple of 200) */
++/* to a fid.                                                              */
++u32
++find_closest_fid(u32 freq, int searchup)
++{
++	if (searchup == SEARCH_UP)
++		freq += MIN_FREQ_RESOLUTION - 1;
++
++	freq = (freq / MIN_FREQ_RESOLUTION) * MIN_FREQ_RESOLUTION;
++
++	if (freq < MIN_FREQ)
++		freq = MIN_FREQ;
++	else if (freq > MAX_FREQ)
++		freq = MAX_FREQ;
++
++	return find_fid_from_freq(freq);
++}
++
++static int
++find_match(u32 * ptargfreq, u32 * pmin, u32 * pmax, int searchup, u32 * pfid,
++	   u32 * pvid)
++{
++	u32 availpstates = batps;
++	u32 targfid = find_closest_fid(*ptargfreq, searchup);
++	u32 minfid = find_closest_fid(*pmin, SEARCH_DOWN);
++	u32 maxfid = find_closest_fid(*pmax, SEARCH_UP);
++	u32 minidx = 0;
++	u32 maxidx = availpstates - 1;
++	u32 targidx = 0xffffffff;
++	int i;
++
++	dprintk(KERN_DEBUG PFX "find match: freq %d MHz, min %d, max %d\n",
++		*ptargfreq, *pmin, *pmax);
++
++	/* Restrict values to the frequency choices in the PST */
++	if (minfid < ppst[0].fid)
++		minfid = ppst[0].fid;
++	if (maxfid > ppst[maxidx].fid)
++		maxfid = ppst[maxidx].fid;
++
++	/* Find appropriate PST index for the minimim fid */
++	for (i = 0; i < (int) availpstates; i++) {
++		if (minfid >= ppst[i].fid)
++			minidx = i;
++	}
++
++	/* Find appropriate PST index for the maximum fid */
++	for (i = availpstates - 1; i >= 0; i--) {
++		if (maxfid <= ppst[i].fid)
++			maxidx = i;
++	}
++
++	if (minidx > maxidx)
++		maxidx = minidx;
++
++	/* Frequency ids are now constrained by limits matching PST entries */
++	minfid = ppst[minidx].fid;
++	maxfid = ppst[maxidx].fid;
++
++	/* Limit the target frequency to these limits */
++	if (targfid < minfid)
++		targfid = minfid;
++	else if (targfid > maxfid)
++		targfid = maxfid;
++
++	/* Find the best target index into the PST, contrained by the range */
++	if (searchup == SEARCH_UP) {
++		for (i = maxidx; i >= (int) minidx; i--) {
++			if (targfid <= ppst[i].fid)
++				targidx = i;
++		}
++	} else {
++		for (i = minidx; i <= (int) maxidx; i++) {
++			if (targfid >= ppst[i].fid)
++				targidx = i;
++		}
++	}
++
++	if (targidx == 0xffffffff) {
++		printk(KERN_ERR PFX "could not find target\n");
++		return 1;
++	}
++
++	*pmin = find_freq_from_fid(minfid);
++	*pmax = find_freq_from_fid(maxfid);
++	*ptargfreq = find_freq_from_fid(ppst[targidx].fid);
++
++	if (pfid)
++		*pfid = ppst[targidx].fid;
++	if (pvid)
++		*pvid = ppst[targidx].vid;
++
++	return 0;
++}
++
++/* Take a frequency, and issue the fid/vid transition command */
++static inline int
++transition_frequency(u32 * preq, u32 * pmin, u32 * pmax, u32 searchup)
++{
++	u32 fid;
++	u32 vid;
++	int res;
++	struct cpufreq_freqs freqs;
++
++	if (find_match(preq, pmin, pmax, searchup, &fid, &vid))
++		return 1;
++
++	dprintk(KERN_DEBUG PFX "table matched fid 0x%x, giving vid 0x%x\n",
++		fid, vid);
++
++	if (query_current_values_with_pending_wait())
++		return 1;
++
++	if ((currvid == vid) && (currfid == fid)) {
++		dprintk(KERN_DEBUG PFX
++			"target matches current values (fid 0x%x, vid 0x%x)\n",
++			fid, vid);
++		return 0;
++	}
++
++	if ((fid < HI_FID_TABLE_BOTTOM) && (currfid < HI_FID_TABLE_BOTTOM)) {
++		printk(KERN_ERR PFX
++		       "ignoring illegal change in lo freq table-%x to %x\n",
++		       currfid, fid);
++		return 1;
++	}
++
++	dprintk(KERN_DEBUG PFX "changing to fid 0x%x, vid 0x%x\n", fid, vid);
++
++	freqs.cpu = 0;	/* only true because SMP not supported */
++
++	freqs.old = find_freq_from_fid(currfid);
++	freqs.new = find_freq_from_fid(fid);
++	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++	res = transition_fid_vid(fid, vid);
++
++	freqs.new = find_freq_from_fid(currfid);
++	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++	return res;
++}
++
++/* Driver entry point to switch to the target frequency */
++static int
++drv_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation)
++{
++	u32 checkfid = currfid;
++	u32 checkvid = currvid;
++	u32 reqfreq = targfreq / 1000;
++	u32 minfreq = pol->min / 1000;
++	u32 maxfreq = pol->max / 1000;
++
++	if (ppst == 0) {
++		printk(KERN_ERR PFX "targ: ppst 0\n");
++		return -ENODEV;
++	}
++
++	if (pending_bit_stuck()) {
++		printk(KERN_ERR PFX "drv targ fail: change pending bit set\n");
++		return -EIO;
++	}
++
++	dprintk(KERN_DEBUG PFX "targ: %d kHz, min %d, max %d, relation %d\n",
++		targfreq, pol->min, pol->max, relation);
++
++	if (query_current_values_with_pending_wait())
++		return -EIO;
++
++	dprintk(KERN_DEBUG PFX "targ: curr fid 0x%x, vid 0x%x\n",
++		currfid, currvid);
++
++	if ((checkvid != currvid) || (checkfid != currfid)) {
++		printk(KERN_ERR PFX
++		       "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n",
++		       checkfid, currfid, checkvid, currvid);
++	}
++
++	if (transition_frequency(&reqfreq, &minfreq, &maxfreq,
++				 relation ==
++				 CPUFREQ_RELATION_H ? SEARCH_UP : SEARCH_DOWN))
++	{
++		printk(KERN_ERR PFX "transition frequency failed\n");
++		return 1;
++	}
++
++	pol->cur = 1000 * find_freq_from_fid(currfid);
++
++	return 0;
++}
++
++/* Driver entry point to verify the policy and range of frequencies */
++static int
++drv_verify(struct cpufreq_policy *pol)
++{
++	u32 min = pol->min / 1000;
++	u32 max = pol->max / 1000;
++	u32 targ = min;
++	int res;
++
++	if (ppst == 0) {
++		printk(KERN_ERR PFX "verify - ppst 0\n");
++		return -ENODEV;
++	}
++
++	if (pending_bit_stuck()) {
++		printk(KERN_ERR PFX "failing verify, change pending bit set\n");
++		return -EIO;
++	}
++
++	dprintk(KERN_DEBUG PFX
++		"ver: cpu%d, min %d, max %d, cur %d, pol %d\n", pol->cpu,
++		pol->min, pol->max, pol->cur, pol->policy);
++
++	if (pol->cpu != 0) {
++		printk(KERN_ERR PFX "verify - cpu not 0\n");
++		return -ENODEV;
++	}
++
++	res = find_match(&targ, &min, &max,
++			 pol->policy == CPUFREQ_POLICY_POWERSAVE ?
++			 SEARCH_DOWN : SEARCH_UP, 0, 0);
++	if (!res) {
++		pol->min = min * 1000;
++		pol->max = max * 1000;
++	}
++	return res;
++}
++
++/* per CPU init entry point to the driver */
++static int __init
++drv_cpu_init(struct cpufreq_policy *pol)
++{
++	if (pol->cpu != 0) {
++		printk(KERN_ERR PFX "init not cpu 0\n");
++		return -ENODEV;
++	}
++
++	pol->policy = CPUFREQ_POLICY_PERFORMANCE; /* boot as fast as we can */
++
++	/* Take a crude guess here. */
++	pol->cpuinfo.transition_latency = ((rvo + 8) * vstable * VST_UNITS_20US)
++	    + (3 * (1 << irt) * 10);
++
++	if (query_current_values_with_pending_wait())
++		return -EIO;
++
++	pol->cur = 1000 * find_freq_from_fid(currfid);
++	dprintk(KERN_DEBUG PFX "policy current frequency %d kHz\n", pol->cur);
++
++	/* min/max the cpu is capable of */
++	pol->cpuinfo.min_freq = 1000 * find_freq_from_fid(ppst[0].fid);
++	pol->cpuinfo.max_freq = 1000 * find_freq_from_fid(ppst[numps-1].fid);
++	pol->min = 1000 * find_freq_from_fid(ppst[0].fid);
++	pol->max = 1000 * find_freq_from_fid(ppst[batps - 1].fid);
++
++	printk(KERN_INFO PFX "cpu_init done, current fid 0x%x, vid 0x%x\n",
++	       currfid, currvid);
++
++	return 0;
++}
++
++/* driver entry point for init */
++static int __init
++drv_init(void)
++{
++	int rc;
++
++	printk(KERN_INFO PFX VERSION "\n");
++
++	if (check_supported_cpu() == 0)
++		return -ENODEV;
++
++	rc = find_psb_table();
++	if (rc)
++		return rc;
++
++	if (pending_bit_stuck()) {
++		printk(KERN_ERR PFX "drv_init fail, change pending bit set\n");
++		kfree(ppst);
++		return -EIO;
++	}
++
++	return cpufreq_register_driver(&cpufreq_amd64_driver);
++}
++
++/* driver entry point for term */
++static void __exit
++drv_exit(void)
++{
++	dprintk(KERN_INFO PFX "drv_exit\n");
++
++	cpufreq_unregister_driver(&cpufreq_amd64_driver);
++	kfree(ppst);
++}
++
++MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>");
++MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
++MODULE_LICENSE("GPL");
++
++module_init(drv_init);
++module_exit(drv_exit);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2003-10-05 00:33:23.000000000 -0700
+@@ -0,0 +1,126 @@
++/*
++ *   (c) 2003 Advanced Micro Devices, Inc.
++ *  Your use of this code is subject to the terms and conditions of the
++ *  GNU general public license version 2. See "../../../COPYING" or
++ *  http://www.gnu.org/licenses/gpl.html
++ */
++
++/* processor's cpuid instruction support */
++#define CPUID_PROCESSOR_SIGNATURE             1	/* function 1               */
++#define CPUID_F1_FAM                 0x00000f00	/* family mask              */
++#define CPUID_F1_XFAM                0x0ff00000	/* extended family mask     */
++#define CPUID_F1_MOD                 0x000000f0	/* model mask               */
++#define CPUID_F1_STEP                0x0000000f	/* stepping level mask      */
++#define CPUID_XFAM_MOD               0x0ff00ff0	/* xtended fam, fam + model */
++#define ATHLON64_XFAM_MOD            0x00000f40	/* xtended fam, fam + model */
++#define OPTERON_XFAM_MOD             0x00000f50	/* xtended fam, fam + model */
++#define ATHLON64_REV_C0                       8
++#define CPUID_GET_MAX_CAPABILITIES   0x80000000
++#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
++#define P_STATE_TRANSITION_CAPABLE            6
++
++/* Model Specific Registers for p-state transitions. MSRs are 64-bit. For     */
++/* writes (wrmsr - opcode 0f 30), the register number is placed in ecx, and   */
++/* the value to write is placed in edx:eax. For reads (rdmsr - opcode 0f 32), */
++/* the register number is placed in ecx, and the data is returned in edx:eax. */
++
++#define MSR_FIDVID_CTL      0xc0010041
++#define MSR_FIDVID_STATUS   0xc0010042
++
++/* Field definitions within the FID VID Low Control MSR : */
++#define MSR_C_LO_INIT_FID_VID     0x00010000
++#define MSR_C_LO_NEW_VID          0x00001f00
++#define MSR_C_LO_NEW_FID          0x0000002f
++#define MSR_C_LO_VID_SHIFT        8
++
++/* Field definitions within the FID VID High Control MSR : */
++#define MSR_C_HI_STP_GNT_TO       0x000fffff
++
++/* Field definitions within the FID VID Low Status MSR : */
++#define MSR_S_LO_CHANGE_PENDING   0x80000000	/* cleared when completed */
++#define MSR_S_LO_MAX_RAMP_VID     0x1f000000
++#define MSR_S_LO_MAX_FID          0x003f0000
++#define MSR_S_LO_START_FID        0x00003f00
++#define MSR_S_LO_CURRENT_FID      0x0000003f
++
++/* Field definitions within the FID VID High Status MSR : */
++#define MSR_S_HI_MAX_WORKING_VID  0x001f0000
++#define MSR_S_HI_START_VID        0x00001f00
++#define MSR_S_HI_CURRENT_VID      0x0000001f
++
++/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
++#define LO_FID_TABLE_TOP     6
++#define HI_FID_TABLE_BOTTOM  8
++
++#define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
++#define HI_VCOFREQ_TABLE_BOTTOM 1600
++
++#define MIN_FREQ_RESOLUTION  200 /* fids jump by 2 matching freq jumps by 200 */
++
++#define MAX_FID 0x2a	/* Spec only gives FID values as far as 5 GHz */
++
++#define LEAST_VID 0x1e	/* Lowest (numerically highest) useful vid value */
++
++#define MIN_FREQ 800	/* Min and max freqs, per spec */
++#define MAX_FREQ 5000
++
++#define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
++
++#define INVALID_VID_MASK 0xffffffe0  /* not a valid vid if these bits are set */
++
++#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
++
++#define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
++
++#define MAXIMUM_VID_STEPS 1  /* Current cpus only allow a single step of 25mV */
++
++#define VST_UNITS_20US 20   /* Voltage Stabalization Time is in units of 20us */
++
++/*
++Version 1.4 of the PSB table. This table is constructed by BIOS and is
++to tell the OS's power management driver which VIDs and FIDs are
++supported by this particular processor. This information is obtained from
++the data sheets for each processor model by the system vendor and
++incorporated into the BIOS.
++If the data in the PSB / PST is wrong, then this driver will program the
++wrong values into hardware, which is very likely to lead to a crash.
++*/
++
++#define PSB_ID_STRING      "AMDK7PNOW!"
++#define PSB_ID_STRING_LEN  10
++
++#define PSB_VERSION_1_4  0x14
++
++struct psb_s {
++	u8 signature[10];
++	u8 tableversion;
++	u8 flags1;
++	u16 voltagestabilizationtime;
++	u8 flags2;
++	u8 numpst;
++	u32 cpuid;
++	u8 plllocktime;
++	u8 maxfid;
++	u8 maxvid;
++	u8 numpstates;
++};
++
++/* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
++struct pst_s {
++	u8 fid;
++	u8 vid;
++};
++
++#ifdef DEBUG
++#define dprintk(msg...) printk(msg)
++#else
++#define dprintk(msg...) do { } while(0)
++#endif
++
++static inline int core_voltage_pre_transition(u32 reqvid);
++static inline int core_voltage_post_transition(u32 reqvid);
++static inline int core_frequency_transition(u32 reqfid);
++static int drv_verify(struct cpufreq_policy *pol);
++static int drv_target(struct cpufreq_policy *pol, unsigned targfreq,
++		      unsigned relation);
++static int __init drv_cpu_init(struct cpufreq_policy *pol);
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/intel.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/cpu/intel.c	2003-10-05 00:36:48.000000000 -0700
+@@ -8,11 +8,10 @@
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+ #include <asm/uaccess.h>
++#include <asm/desc.h>
+ 
+ #include "cpu.h"
+ 
+-extern int trap_init_f00f_bug(void);
+-
+ #ifdef CONFIG_X86_INTEL_USERCOPY
+ /*
+  * Alignment at which movsl is preferred for bulk memory copies.
+@@ -157,7 +156,7 @@ static void __init init_intel(struct cpu
+ 
+ 		c->f00f_bug = 1;
+ 		if ( !f00f_workaround_enabled ) {
+-			trap_init_f00f_bug();
++			trap_init_virtual_IDT();
+ 			printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
+ 			f00f_workaround_enabled = 1;
+ 		}
+@@ -238,12 +237,9 @@ static void __init init_intel(struct cpu
+ 	}
+ 
+ 	/* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */
+-	if ( c->x86 == 6) {
+-		unsigned model_mask = (c->x86_model << 8) + c->x86_mask;
+-		if (model_mask < 0x0303)
+-			clear_bit(X86_FEATURE_SEP, c->x86_capability);
+-	}
+-	
++	if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
++		clear_bit(X86_FEATURE_SEP, c->x86_capability);
++
+ 	/* Names for the Pentium II/Celeron processors 
+ 	   detectable only by also checking the cache size.
+ 	   Dixon is NOT a Celeron. */
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/k7.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/k7.c	2003-10-05 00:33:23.000000000 -0700
+@@ -17,7 +17,7 @@
+ #include "mce.h"
+ 
+ /* Machine Check Handler For AMD Athlon/Duron */
+-static void k7_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void k7_machine_check(struct pt_regs * regs, long error_code)
+ {
+ 	int recover=1;
+ 	u32 alow, ahigh, high, low;
+@@ -31,7 +31,7 @@ static void k7_machine_check(struct pt_r
+ 	printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
+ 		smp_processor_id(), mcgsth, mcgstl);
+ 
+-	for (i=0; i<nr_mce_banks; i++) {
++	for (i=1; i<nr_mce_banks; i++) {
+ 		rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high);
+ 		if (high&(1<<31)) {
+ 			if (high & (1<<29))
+@@ -81,6 +81,9 @@ void __init amd_mcheck_init(struct cpuin
+ 		wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
+ 	nr_mce_banks = l & 0xff;
+ 
++	/* Clear status for MC index 0 separately, we don't touch CTL,
++	 * as some Athlons cause spurious MCEs when its enabled. */
++	wrmsr (MSR_IA32_MC0_STATUS, 0x0, 0x0);
+ 	for (i=1; i<nr_mce_banks; i++) {
+ 		wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
+ 		wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/mce.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/mce.c	2003-10-05 00:33:23.000000000 -0700
+@@ -18,18 +18,13 @@ int mce_disabled __initdata = 0;
+ int nr_mce_banks;
+ 
+ /* Handle unconfigured int18 (should never happen) */
+-static void unexpected_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void unexpected_machine_check(struct pt_regs * regs, long error_code)
+ {	
+ 	printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
+ }
+ 
+ /* Call the installed machine check handler for this CPU setup. */
+-void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
+-
+-asmlinkage void do_machine_check(struct pt_regs * regs, long error_code)
+-{
+-	machine_check_vector(regs, error_code);
+-}
++void asmlinkage (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
+ 
+ /* This has to be run for each processor */
+ void __init mcheck_init(struct cpuinfo_x86 *c)
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/mce.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/mce.h	2003-10-05 00:33:23.000000000 -0700
+@@ -7,7 +7,7 @@ void intel_p6_mcheck_init(struct cpuinfo
+ void winchip_mcheck_init(struct cpuinfo_x86 *c);
+ 
+ /* Call the installed machine check handler for this CPU setup. */
+-extern void (*machine_check_vector)(struct pt_regs *, long error_code);
++extern asmlinkage void (*machine_check_vector)(struct pt_regs *, long error_code);
+ 
+ extern int mce_disabled __initdata;
+ extern int nr_mce_banks;
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/p4.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/p4.c	2003-10-05 00:33:23.000000000 -0700
+@@ -148,7 +148,7 @@ done:
+ 	return mce_num_extended_msrs;
+ }
+ 
+-static void intel_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_code)
+ {
+ 	int recover=1;
+ 	u32 alow, ahigh, high, low;
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/p5.c	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/p5.c	2003-10-05 00:33:23.000000000 -0700
+@@ -16,7 +16,7 @@
+ #include "mce.h"
+ 
+ /* Machine check handler for Pentium class Intel */
+-static void pentium_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void pentium_machine_check(struct pt_regs * regs, long error_code)
+ {
+ 	u32 loaddr, hi, lotype;
+ 	rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/p6.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/p6.c	2003-10-05 00:33:23.000000000 -0700
+@@ -16,7 +16,7 @@
+ #include "mce.h"
+ 
+ /* Machine Check Handler For PII/PIII */
+-static void intel_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_code)
+ {
+ 	int recover=1;
+ 	u32 alow, ahigh, high, low;
+--- linux-2.6.0-test6/arch/i386/kernel/cpu/mcheck/winchip.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/i386/kernel/cpu/mcheck/winchip.c	2003-10-05 00:33:23.000000000 -0700
+@@ -15,7 +15,7 @@
+ #include "mce.h"
+ 
+ /* Machine check handler for WinChip C6 */
+-static void winchip_machine_check(struct pt_regs * regs, long error_code)
++static asmlinkage void winchip_machine_check(struct pt_regs * regs, long error_code)
+ {
+ 	printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
+ }
+--- linux-2.6.0-test6/arch/i386/kernel/dmi_scan.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/dmi_scan.c	2003-10-05 00:33:23.000000000 -0700
+@@ -939,11 +939,6 @@ static __initdata struct dmi_blacklist d
+ 			MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+ 			NO_MATCH, NO_MATCH }},
+ 
+-	{ force_acpi_ht, "ASUS A7V", {
+-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+-			MATCH(DMI_BOARD_NAME, "<A7V>"),
+-			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }},
+-
+ 	{ force_acpi_ht, "ABIT i440BX-W83977", {
+ 			MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+ 			MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+@@ -978,7 +973,10 @@ static __initdata struct dmi_blacklist d
+ 	{ disable_acpi_pci, "ASUS A7V", {
+ 			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+ 			MATCH(DMI_BOARD_NAME, "<A7V>"),
+-			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }},
++			/* newer BIOS, Revision 1011, does work */
++			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
++			NO_MATCH }},
++
+ #endif
+ 
+ 	{ NULL, }
+--- linux-2.6.0-test6/arch/i386/kernel/doublefault.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/doublefault.c	2003-10-05 00:36:48.000000000 -0700
+@@ -7,12 +7,13 @@
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
++#include <asm/fixmap.h>
+ 
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+ #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
+ 
+-#define ptr_ok(x) ((x) > 0xc0000000 && (x) < 0xc1000000)
++#define ptr_ok(x) (((x) > __PAGE_OFFSET && (x) < (__PAGE_OFFSET + 0x01000000)) || ((x) >= FIXADDR_START))
+ 
+ static void doublefault_fn(void)
+ {
+@@ -38,8 +39,8 @@ static void doublefault_fn(void)
+ 
+ 			printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+ 				t->eax, t->ebx, t->ecx, t->edx);
+-			printk("esi = %08lx, edi = %08lx\n",
+-				t->esi, t->edi);
++			printk("esi = %08lx, edi = %08lx, ebp = %08lx\n",
++				t->esi, t->edi, t->ebp);
+ 		}
+ 	}
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/efi.c	2003-10-05 00:36:25.000000000 -0700
+@@ -0,0 +1,611 @@
++/*
++ * Extensible Firmware Interface
++ *
++ * Based on Extensible Firmware Interface Specification version 1.0
++ *
++ * Copyright (C) 1999 VA Linux Systems
++ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
++ * Copyright (C) 1999-2002 Hewlett-Packard Co.
++ *	David Mosberger-Tang <davidm@hpl.hp.com>
++ *	Stephane Eranian <eranian@hpl.hp.com>
++ *
++ * All EFI Runtime Services are not implemented yet as EFI only
++ * supports physical mode addressing on SoftSDV. This is to be fixed
++ * in a future version.  --drummond 1999-07-20
++ *
++ * Implemented EFI runtime services and virtual mode calls.  --davidm
++ *
++ * Goutham Rao: <goutham.rao@intel.com>
++ *	Skip non-WB memory and ignore empty memory ranges.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/types.h>
++#include <linux/time.h>
++#include <linux/spinlock.h>
++#include <linux/bootmem.h>
++#include <linux/ioport.h>
++#include <linux/proc_fs.h>
++#include <linux/efi.h>
++
++#include <asm/setup.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/processor.h>
++#include <asm/desc.h>
++#include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++
++#define EFI_DEBUG	0
++#define PFX 		"EFI: "
++
++extern efi_status_t asmlinkage efi_call_phys(void *, ...);
++
++struct efi efi;
++struct efi efi_phys __initdata;
++struct efi_memory_map memmap __initdata;
++
++/*
++ * We require an early boot_ioremap mapping mechanism initially
++ */
++extern void * boot_ioremap(unsigned long, unsigned long);
++
++/*
++ * efi_dir is allocated here, but the directory isn't created
++ * here, as proc_mkdir() doesn't work this early in the bootup
++ * process.  Therefore, each module, like efivars, must test for
++ *    if (!efi_dir) efi_dir = proc_mkdir("efi", NULL);
++ * prior to creating their own entries under /proc/efi.
++ */
++#ifdef CONFIG_PROC_FS
++struct proc_dir_entry *efi_dir;
++#endif
++
++
++/*
++ * To make EFI call EFI runtime service in physical addressing mode we need
++ * prelog/epilog before/after the invocation to disable interrupt, to
++ * claim EFI runtime service handler exclusively and to duplicate a memory in
++ * low memory space say 0 - 3G.
++ */
++
++static unsigned long efi_rt_eflags;
++static spinlock_t efi_rt_lock = SPIN_LOCK_UNLOCKED;
++static pgd_t efi_bak_pg_dir_pointer[2];
++
++static void efi_call_phys_prelog(void)
++{
++	unsigned long cr4;
++	unsigned long temp;
++
++	spin_lock(&efi_rt_lock);
++	local_irq_save(efi_rt_eflags);
++
++	/*
++	 * If I don't have PSE, I should just duplicate two entries in page
++	 * directory. If I have PSE, I just need to duplicate one entry in
++	 * page directory.
++	 */
++	__asm__ __volatile__("movl %%cr4, %0":"=r"(cr4));
++
++	if (cr4 & X86_CR4_PSE) {
++		efi_bak_pg_dir_pointer[0].pgd =
++		    swapper_pg_dir[pgd_index(0)].pgd;
++		swapper_pg_dir[0].pgd =
++		    swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
++	} else {
++		efi_bak_pg_dir_pointer[0].pgd =
++		    swapper_pg_dir[pgd_index(0)].pgd;
++		efi_bak_pg_dir_pointer[1].pgd =
++		    swapper_pg_dir[pgd_index(0x400000)].pgd;
++		swapper_pg_dir[pgd_index(0)].pgd =
++		    swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
++		temp = PAGE_OFFSET + 0x400000;
++		swapper_pg_dir[pgd_index(0x400000)].pgd =
++		    swapper_pg_dir[pgd_index(temp)].pgd;
++	}
++
++	/*
++	 * After the lock is released, the original page table is restored.
++	 */
++	local_flush_tlb();
++
++	cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
++	__asm__ __volatile__("lgdt %0":"=m"
++			    (*(struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0])));
++}
++
++static void efi_call_phys_epilog(void)
++{
++	unsigned long cr4;
++
++	cpu_gdt_descr[0].address =
++		(unsigned long) __va(cpu_gdt_descr[0].address);
++	__asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr));
++	__asm__ __volatile__("movl %%cr4, %0":"=r"(cr4));
++
++	if (cr4 & X86_CR4_PSE) {
++		swapper_pg_dir[pgd_index(0)].pgd =
++		    efi_bak_pg_dir_pointer[0].pgd;
++	} else {
++		swapper_pg_dir[pgd_index(0)].pgd =
++		    efi_bak_pg_dir_pointer[0].pgd;
++		swapper_pg_dir[pgd_index(0x400000)].pgd =
++		    efi_bak_pg_dir_pointer[1].pgd;
++	}
++
++	/*
++	 * After the lock is released, the original page table is restored.
++	 */
++	local_flush_tlb();
++
++	local_irq_restore(efi_rt_eflags);
++	spin_unlock(&efi_rt_lock);
++}
++
++static efi_status_t
++phys_efi_set_virtual_address_map(unsigned long memory_map_size,
++				 unsigned long descriptor_size,
++				 u32 descriptor_version,
++				 efi_memory_desc_t *virtual_map)
++{
++	efi_status_t status;
++
++	efi_call_phys_prelog();
++	status = efi_call_phys(efi_phys.set_virtual_address_map,
++				     memory_map_size, descriptor_size,
++				     descriptor_version, virtual_map);
++	efi_call_phys_epilog();
++	return status;
++}
++
++efi_status_t
++phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
++{
++	efi_status_t status;
++
++	efi_call_phys_prelog();
++	status = efi_call_phys(efi_phys.get_time, tm, tc);
++	efi_call_phys_epilog();
++	return status;
++}
++
++void efi_gettimeofday(struct timespec *tv)
++{
++	efi_time_t tm;
++
++	memset(tv, 0, sizeof(*tv));
++	if ((*efi.get_time) (&tm, 0) != EFI_SUCCESS)
++		return;
++
++	tv->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute,
++		            tm.second);
++	tv->tv_nsec = tm.nanosecond;
++}
++
++int is_available_memory(efi_memory_desc_t * md)
++{
++	if (!(md->attribute & EFI_MEMORY_WB))
++		return 0;
++
++	switch (md->type) {
++		case EFI_LOADER_CODE:
++		case EFI_LOADER_DATA:
++		case EFI_BOOT_SERVICES_CODE:
++		case EFI_BOOT_SERVICES_DATA:
++		case EFI_CONVENTIONAL_MEMORY:
++			return 1;
++	}
++	return 0;
++}
++
++/*
++ * We need to map the EFI memory map again after paging_init().
++ */
++void __init efi_map_memmap(void)
++{
++	memmap.map = NULL;
++
++	memmap.map = (efi_memory_desc_t *)
++		bt_ioremap((unsigned long) memmap.phys_map,
++			(memmap.nr_map * sizeof(efi_memory_desc_t)));
++
++	if (memmap.map == NULL)
++		printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
++}
++
++void __init print_efi_memmap(void)
++{
++	efi_memory_desc_t *md;
++	int i;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++		printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
++			"range=[0x%016llx-0x%016llx) (%lluMB)\n",
++			i, md->type, md->attribute, md->phys_addr,
++			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
++			(md->num_pages >> (20 - EFI_PAGE_SHIFT)));
++	}
++}
++
++/*
++ * Walks the EFI memory map and calls CALLBACK once for each EFI
++ * memory descriptor that has memory that is available for kernel use.
++ */
++void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
++{
++	int prev_valid = 0;
++	struct range {
++		unsigned long start;
++		unsigned long end;
++	} prev, curr;
++	efi_memory_desc_t *md;
++	unsigned long start, end;
++	int i;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++
++		if ((md->num_pages == 0) || (!is_available_memory(md)))
++			continue;
++
++		curr.start = md->phys_addr;
++		curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
++
++		if (!prev_valid) {
++			prev = curr;
++			prev_valid = 1;
++		} else {
++			if (curr.start < prev.start)
++				printk(KERN_INFO PFX "Unordered memory map\n");
++			if (prev.end == curr.start)
++				prev.end = curr.end;
++			else {
++				start =
++				    (unsigned long) (PAGE_ALIGN(prev.start));
++				end = (unsigned long) (prev.end & PAGE_MASK);
++				if ((end > start)
++				    && (*callback) (start, end, arg) < 0)
++					return;
++				prev = curr;
++			}
++		}
++	}
++	if (prev_valid) {
++		start = (unsigned long) PAGE_ALIGN(prev.start);
++		end = (unsigned long) (prev.end & PAGE_MASK);
++		if (end > start)
++			(*callback) (start, end, arg);
++	}
++}
++
++void __init efi_init(void)
++{
++	efi_config_table_t *config_tables;
++	efi_runtime_services_t *runtime;
++	efi_char16_t *c16;
++	char vendor[100] = "unknown";
++	unsigned long num_config_tables;
++	int i = 0;
++
++	memset(&efi, 0, sizeof(efi) );
++	memset(&efi_phys, 0, sizeof(efi_phys));
++
++	efi_phys.systab = EFI_SYSTAB;
++	memmap.phys_map = EFI_MEMMAP;
++	memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
++	memmap.desc_version = EFI_MEMDESC_VERSION;
++
++	efi.systab = (efi_system_table_t *)
++		boot_ioremap((unsigned long) efi_phys.systab,
++			sizeof(efi_system_table_t));
++	/*
++	 * Verify the EFI Table
++	 */
++	if (efi.systab == NULL)
++		printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
++	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
++		printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
++	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
++		printk(KERN_ERR PFX
++		       "Warning: EFI system table major version mismatch: "
++		       "got %d.%02d, expected %d.%02d\n",
++		       efi.systab->hdr.revision >> 16,
++		       efi.systab->hdr.revision & 0xffff,
++		       EFI_SYSTEM_TABLE_REVISION >> 16,
++		       EFI_SYSTEM_TABLE_REVISION & 0xffff);
++	/*
++	 * Grab some details from the system table
++	 */
++	num_config_tables = efi.systab->nr_tables;
++	config_tables = (efi_config_table_t *)efi.systab->tables;
++	runtime = efi.systab->runtime;
++
++	/*
++	 * Show what we know for posterity
++	 */
++	c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2);
++	if (c16) {
++		for (i = 0; i < sizeof(vendor) && *c16; ++i)
++			vendor[i] = *c16++;
++		vendor[i] = '\0';
++	} else
++		printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
++
++	printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n",
++	       efi.systab->hdr.revision >> 16,
++	       efi.systab->hdr.revision & 0xffff, vendor);
++
++	/*
++	 * Let's see what config tables the firmware passed to us.
++	 */
++	config_tables = (efi_config_table_t *)
++				boot_ioremap((unsigned long) config_tables,
++			        num_config_tables * sizeof(efi_config_table_t));
++
++	if (config_tables == NULL)
++		printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n");
++
++	for (i = 0; i < num_config_tables; i++) {
++		if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
++			efi.mps = (void *)config_tables[i].table;
++			printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table);
++		} else
++		    if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
++			efi.acpi20 = __va(config_tables[i].table);
++			printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table);
++		} else
++		    if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
++			efi.acpi = __va(config_tables[i].table);
++			printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table);
++		} else
++		    if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
++			efi.smbios = (void *) config_tables[i].table;
++			printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table);
++		} else
++		    if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
++			efi.hcdp = (void *)config_tables[i].table;
++			printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table);
++		} else
++		    if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) {
++			efi.uga = (void *)config_tables[i].table;
++			printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table);
++		}
++	}
++	printk("\n");
++
++	/*
++	 * Check out the runtime services table. We need to map
++	 * the runtime services table so that we can grab the physical
++	 * address of several of the EFI runtime functions, needed to
++	 * set the firmware into virtual mode.
++	 */
++
++	runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long)
++						runtime,
++				      		sizeof(efi_runtime_services_t));
++	if (runtime != NULL) {
++		/*
++	 	 * We will only need *early* access to the following
++		 * two EFI runtime services before set_virtual_address_map
++		 * is invoked.
++ 	 	 */
++		efi_phys.get_time = (efi_get_time_t *) runtime->get_time;
++		efi_phys.set_virtual_address_map =
++			(efi_set_virtual_address_map_t *)
++				runtime->set_virtual_address_map;
++	} else
++		printk(KERN_ERR PFX "Could not map the runtime service table!\n");
++
++	/* Map the EFI memory map for use until paging_init() */
++
++	memmap.map = (efi_memory_desc_t *)
++		boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
++
++	if (memmap.map == NULL)
++		printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
++
++	if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) {
++		printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't "
++			   "match the one from EFI!\n");
++	}
++#if EFI_DEBUG
++	print_efi_memmap();
++#endif
++}
++
++/*
++ * This function will switch the EFI runtime services to virtual mode.
++ * Essentially, look through the EFI memmap and map every region that
++ * has the runtime attribute bit set in its memory descriptor and update
++ * that memory descriptor with the virtual address obtained from ioremap().
++ * This enables the runtime services to be called without having to
++ * thunk back into physical mode for every invocation.
++ */
++
++void __init efi_enter_virtual_mode(void)
++{
++	efi_memory_desc_t *md;
++	efi_status_t status;
++	int i;
++
++	efi.systab = NULL;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++
++		if (md->attribute & EFI_MEMORY_RUNTIME) {
++			md->virt_addr =
++				(unsigned long)ioremap(md->phys_addr,
++					md->num_pages << EFI_PAGE_SHIFT);
++			if (!(unsigned long)md->virt_addr) {
++				printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
++					(unsigned long)md->phys_addr);
++			}
++
++			if (((unsigned long)md->phys_addr <=
++					(unsigned long)efi_phys.systab) &&
++				((unsigned long)efi_phys.systab <
++					md->phys_addr +
++					((unsigned long)md->num_pages <<
++						EFI_PAGE_SHIFT))) {
++				unsigned long addr;
++
++				addr = md->virt_addr - md->phys_addr +
++						(unsigned long)efi_phys.systab;
++				efi.systab = (efi_system_table_t *)addr;
++			}
++		}
++	}
++
++	if (!efi.systab)
++		BUG();
++
++	status = phys_efi_set_virtual_address_map(
++			sizeof(efi_memory_desc_t) * memmap.nr_map,
++			sizeof(efi_memory_desc_t),
++			memmap.desc_version,
++		       	memmap.phys_map);
++
++	if (status != EFI_SUCCESS) {
++		printk (KERN_ALERT "You are screwed! "
++			"Unable to switch EFI into virtual mode "
++			"(status=%lx)\n", status);
++		panic("EFI call to SetVirtualAddressMap() failed!");
++	}
++
++	/*
++	 * Now that EFI is in virtual mode, update the function
++	 * pointers in the runtime service table to the new virtual addresses.
++	 */
++
++	efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time;
++	efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time;
++	efi.get_wakeup_time = (efi_get_wakeup_time_t *)
++					efi.systab->runtime->get_wakeup_time;
++	efi.set_wakeup_time = (efi_set_wakeup_time_t *)
++					efi.systab->runtime->set_wakeup_time;
++	efi.get_variable = (efi_get_variable_t *)
++					efi.systab->runtime->get_variable;
++	efi.get_next_variable = (efi_get_next_variable_t *)
++					efi.systab->runtime->get_next_variable;
++	efi.set_variable = (efi_set_variable_t *)
++					efi.systab->runtime->set_variable;
++	efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *)
++					efi.systab->runtime->get_next_high_mono_count;
++	efi.reset_system = (efi_reset_system_t *)
++					efi.systab->runtime->reset_system;
++}
++
++void __init
++efi_initialize_iomem_resources(struct resource *code_resource,
++			       struct resource *data_resource)
++{
++	struct resource *res;
++	efi_memory_desc_t *md;
++	int i;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++
++		if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
++		    0x100000000ULL)
++			continue;
++		res = alloc_bootmem_low(sizeof(struct resource));
++		switch (md->type) {
++		case EFI_RESERVED_TYPE:
++			res->name = "Reserved Memory";
++			break;
++		case EFI_LOADER_CODE:
++			res->name = "Loader Code";
++			break;
++		case EFI_LOADER_DATA:
++			res->name = "Loader Data";
++			break;
++		case EFI_BOOT_SERVICES_DATA:
++			res->name = "BootServices Data";
++			break;
++		case EFI_BOOT_SERVICES_CODE:
++			res->name = "BootServices Code";
++			break;
++		case EFI_RUNTIME_SERVICES_CODE:
++			res->name = "Runtime Service Code";
++			break;
++		case EFI_RUNTIME_SERVICES_DATA:
++			res->name = "Runtime Service Data";
++			break;
++		case EFI_CONVENTIONAL_MEMORY:
++			res->name = "Conventional Memory";
++			break;
++		case EFI_UNUSABLE_MEMORY:
++			res->name = "Unusable Memory";
++			break;
++		case EFI_ACPI_RECLAIM_MEMORY:
++			res->name = "ACPI Reclaim";
++			break;
++		case EFI_ACPI_MEMORY_NVS:
++			res->name = "ACPI NVS";
++			break;
++		case EFI_MEMORY_MAPPED_IO:
++			res->name = "Memory Mapped IO";
++			break;
++		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
++			res->name = "Memory Mapped IO Port Space";
++			break;
++		default:
++			res->name = "Reserved";
++			break;
++		}
++		res->start = md->phys_addr;
++		res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1);
++		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++		if (request_resource(&iomem_resource, res) < 0)
++			printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n",
++				res->name, res->start, res->end);
++		/*
++		 * We don't know which region contains kernel data so we try
++		 * it repeatedly and let the resource manager test it.
++		 */
++		if (md->type == EFI_CONVENTIONAL_MEMORY) {
++			request_resource(res, code_resource);
++			request_resource(res, data_resource);
++		}
++	}
++}
++
++/*
++ * Convenience functions to obtain memory types and attributes
++ */
++
++u32 efi_mem_type(unsigned long phys_addr)
++{
++	efi_memory_desc_t *md;
++	int i;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++		if ((md->phys_addr <= phys_addr) && (phys_addr <
++			(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
++			return md->type;
++	}
++	return 0;
++}
++
++u64 efi_mem_attributes(unsigned long phys_addr)
++{
++	efi_memory_desc_t *md;
++	int i;
++
++	for (i = 0; i < memmap.nr_map; i++) {
++		md = &memmap.map[i];
++		if ((md->phys_addr <= phys_addr) && (phys_addr <
++			(md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
++			return md->attribute;
++	}
++	return 0;
++}
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/efi_stub.S	2003-10-05 00:36:22.000000000 -0700
+@@ -0,0 +1,125 @@
++/*
++ * EFI call stub for IA32.
++ *
++ * This stub allows us to make EFI calls in physical mode with interrupts
++ * turned off.
++ */
++
++#include <linux/config.h>
++#include <linux/linkage.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++
++/*
++ * efi_call_phys(void *, ...) is a function with variable parameters.
++ * All the callers of this function assure that all the parameters are 4-bytes.
++ */
++
++/*
++ * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save.
++ * So we'd better save all of them at the beginning of this function and restore
++ * at the end no matter how many we use, because we can not assure EFI runtime
++ * service functions will comply with gcc calling convention, too.
++ */
++
++.text
++.section .text, "a"
++ENTRY(efi_call_phys)
++	/*
++	 * 0. The function can only be called in Linux kernel. So CS has been
++	 * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found
++	 * the values of these registers are the same. And, the corresponding
++	 * GDT entries are identical. So I will do nothing about segment reg
++	 * and GDT, but change GDT base register in prelog and epilog.
++	 */
++
++	/*
++	 * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET.
++	 * But to make it smoothly switch from virtual mode to flat mode.
++	 * The mapping of lower virtual memory has been created in prelog and
++	 * epilog.
++	 */
++	movl	$1f, %edx
++	subl	$__PAGE_OFFSET, %edx
++	jmp	*%edx
++1:
++
++	/*
++	 * 2. Now on the top of stack is the return
++	 * address in the caller of efi_call_phys(), then parameter 1,
++	 * parameter 2, ..., param n. To make things easy, we save the return
++	 * address of efi_call_phys in a global variable.
++	 */
++	popl	%edx
++	movl	%edx, saved_return_addr
++	/* get the function pointer into ECX*/
++	popl	%ecx
++	movl	%ecx, efi_rt_function_ptr
++	movl	$2f, %edx
++	subl	$__PAGE_OFFSET, %edx
++	pushl	%edx
++
++	/*
++	 * 3. Clear PG bit in %CR0.
++	 */
++	movl	%cr0, %edx
++	andl	$0x7fffffff, %edx
++	movl	%edx, %cr0
++	jmp	1f
++1:
++
++	/*
++	 * 4. Adjust stack pointer.
++	 */
++	subl	$__PAGE_OFFSET, %esp
++
++	/*
++	 * 5. Call the physical function.
++	 */
++	jmp	*%ecx
++
++2:
++	/*
++	 * 6. After EFI runtime service returns, control will return to
++	 * following instruction. We'd better readjust stack pointer first.
++	 */
++	addl	$__PAGE_OFFSET, %esp
++
++	/*
++	 * 7. Restore PG bit
++	 */
++	movl	%cr0, %edx
++	orl	$0x80000000, %edx
++	movl	%edx, %cr0
++	jmp	1f
++1:
++	/*
++	 * 8. Now restore the virtual mode from flat mode by
++	 * adding EIP with PAGE_OFFSET.
++	 */
++	movl	$1f, %edx
++	jmp	*%edx
++1:
++
++	/*
++	 * 9. Balance the stack. And because EAX contain the return value,
++	 * we'd better not clobber it.
++	 */
++	leal	efi_rt_function_ptr, %edx
++	movl	(%edx), %ecx
++	pushl	%ecx
++
++	/*
++	 * 10. Push the saved return address onto the stack and return.
++	 */
++	leal	saved_return_addr, %edx
++	movl	(%edx), %ecx
++	pushl	%ecx
++	ret
++.previous
++
++.data
++saved_return_addr:
++	.long 0
++efi_rt_function_ptr:
++	.long 0
+--- linux-2.6.0-test6/arch/i386/kernel/entry.S	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/entry.S	2003-10-05 00:36:48.000000000 -0700
+@@ -43,11 +43,25 @@
+ #include <linux/config.h>
+ #include <linux/linkage.h>
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+ #include <asm/errno.h>
+ #include <asm/segment.h>
++#include <asm/page.h>
+ #include <asm/smp.h>
+ #include <asm/page.h>
+ #include "irq_vectors.h"
++        /* We do not recover from a stack overflow, but at least
++         * we know it happened and should be able to track it down.
++         */
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#define STACK_OVERFLOW_TEST \
++        testl $7680,%esp;    \
++        jnz   10f;            \
++        call  stack_overflow; \
++10:
++#else
++#define STACK_OVERFLOW_TEST
++#endif
+ 
+ EBX		= 0x00
+ ECX		= 0x04
+@@ -85,7 +99,102 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ #define resume_kernel		restore_all
+ #endif
+ 
+-#define SAVE_ALL \
++#ifdef CONFIG_X86_HIGH_ENTRY
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++/*
++ * If task is preempted in __SWITCH_KERNELSPACE, and moved to another cpu,
++ * __switch_to repoints %esp to the appropriate virtual stack; but %ebp is
++ * left stale, so we must check whether to repeat the real stack calculation.
++ */
++#define repeat_if_esp_changed				\
++	xorl %esp, %ebp;				\
++	testl $0xffffe000, %ebp;			\
++	jnz 0b
++#else
++#define repeat_if_esp_changed
++#endif
++
++/* clobbers ebx, edx and ebp */
++
++#define __SWITCH_KERNELSPACE				\
++	cmpl $0xff000000, %esp;				\
++	jb 1f;						\
++							\
++	/*						\
++	 * switch pagetables and load the real stack,	\
++	 * keep the stack offset:			\
++	 */						\
++							\
++	movl $swapper_pg_dir-__PAGE_OFFSET, %edx;	\
++							\
++	/* GET_THREAD_INFO(%ebp) intermixed */		\
++0:							\
++	movl %esp, %ebp;				\
++	movl %esp, %ebx;				\
++	andl $0xffffe000, %ebp;				\
++	andl $0x00001fff, %ebx;				\
++	orl TI_real_stack(%ebp), %ebx;			\
++	repeat_if_esp_changed;				\
++							\
++	movl %edx, %cr3;				\
++	movl %ebx, %esp;				\
++1:
++
++#endif
++
++
++#define __SWITCH_USERSPACE \
++	/* interrupted any of the user return paths? */	\
++							\
++	movl EIP(%esp), %eax;				\
++							\
++	cmpl $int80_ret_start_marker, %eax;		\
++	jb 33f; /* nope - continue with sysexit check */\
++	cmpl $int80_ret_end_marker, %eax;		\
++	jb 22f; /* yes - switch to virtual stack */	\
++33:							\
++	cmpl $sysexit_ret_start_marker, %eax;		\
++	jb 44f; /* nope - continue with user check */	\
++	cmpl $sysexit_ret_end_marker, %eax;		\
++	jb 22f; /* yes - switch to virtual stack */	\
++	/* return to userspace? */			\
++44:							\
++	movl EFLAGS(%esp),%ecx;				\
++	movb CS(%esp),%cl;				\
++	testl $(VM_MASK | 3),%ecx;			\
++	jz 2f;						\
++22:							\
++	/*						\
++	 * switch to the virtual stack, then switch to	\
++	 * the userspace pagetables.			\
++	 */						\
++							\
++	GET_THREAD_INFO(%ebp);				\
++	movl TI_virtual_stack(%ebp), %edx;		\
++	movl TI_user_pgd(%ebp), %ecx;			\
++							\
++	movl %esp, %ebx;				\
++	andl $0x1fff, %ebx;				\
++	orl %ebx, %edx;					\
++int80_ret_start_marker:					\
++	movl %edx, %esp; 				\
++	movl %ecx, %cr3;				\
++							\
++	__RESTORE_ALL;					\
++int80_ret_end_marker:					\
++2:
++
++#else /* !CONFIG_X86_HIGH_ENTRY */
++
++#define __SWITCH_KERNELSPACE
++#define __SWITCH_USERSPACE
++
++#endif
++
++#define __SAVE_ALL \
+ 	cld; \
+ 	pushl %es; \
+ 	pushl %ds; \
+@@ -100,7 +209,7 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ 	movl %edx, %ds; \
+ 	movl %edx, %es;
+ 
+-#define RESTORE_INT_REGS \
++#define __RESTORE_INT_REGS \
+ 	popl %ebx;	\
+ 	popl %ecx;	\
+ 	popl %edx;	\
+@@ -109,29 +218,28 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ 	popl %ebp;	\
+ 	popl %eax
+ 
+-#define RESTORE_REGS	\
+-	RESTORE_INT_REGS; \
+-1:	popl %ds;	\
+-2:	popl %es;	\
++#define __RESTORE_REGS	\
++	__RESTORE_INT_REGS; \
++111:	popl %ds;	\
++222:	popl %es;	\
+ .section .fixup,"ax";	\
+-3:	movl $0,(%esp);	\
+-	jmp 1b;		\
+-4:	movl $0,(%esp);	\
+-	jmp 2b;		\
++444:	movl $0,(%esp);	\
++	jmp 111b;	\
++555:	movl $0,(%esp);	\
++	jmp 222b;	\
+ .previous;		\
+ .section __ex_table,"a";\
+ 	.align 4;	\
+-	.long 1b,3b;	\
+-	.long 2b,4b;	\
++	.long 111b,444b;\
++	.long 222b,555b;\
+ .previous
+ 
+-
+-#define RESTORE_ALL	\
+-	RESTORE_REGS	\
++#define __RESTORE_ALL	\
++	__RESTORE_REGS	\
+ 	addl $4, %esp;	\
+-1:	iret;		\
++333:	iret;		\
+ .section .fixup,"ax";   \
+-2:	sti;		\
++666:	sti;		\
+ 	movl $(__USER_DS), %edx; \
+ 	movl %edx, %ds; \
+ 	movl %edx, %es; \
+@@ -140,10 +248,19 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ .previous;		\
+ .section __ex_table,"a";\
+ 	.align 4;	\
+-	.long 1b,2b;	\
++	.long 333b,666b;\
+ .previous
+ 
++#define SAVE_ALL \
++	__SAVE_ALL;					\
++	__SWITCH_KERNELSPACE;				\
++        STACK_OVERFLOW_TEST;
++
++#define RESTORE_ALL					\
++	__SWITCH_USERSPACE;				\
++	__RESTORE_ALL;
+ 
++.section .entry.text,"ax"
+ 
+ ENTRY(lcall7)
+ 	pushfl			# We get a different stack layout with call
+@@ -161,7 +278,7 @@ do_lcall:
+ 	movl %edx,EIP(%ebp)	# Now we move them to their "normal" places
+ 	movl %ecx,CS(%ebp)	#
+ 	andl $-8192, %ebp	# GET_THREAD_INFO
+-	movl TI_EXEC_DOMAIN(%ebp), %edx	# Get the execution domain
++	movl TI_exec_domain(%ebp), %edx	# Get the execution domain
+ 	call *4(%edx)		# Call the lcall7 handler for the domain
+ 	addl $4, %esp
+ 	popl %eax
+@@ -206,7 +323,7 @@ ENTRY(resume_userspace)
+  	cli				# make sure we don't miss an interrupt
+ 					# setting need_resched or sigpending
+ 					# between sampling and the iret
+-	movl TI_FLAGS(%ebp), %ecx
++	movl TI_flags(%ebp), %ecx
+ 	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on
+ 					# int/exception return?
+ 	jne work_pending
+@@ -214,18 +331,18 @@ ENTRY(resume_userspace)
+ 
+ #ifdef CONFIG_PREEMPT
+ ENTRY(resume_kernel)
+-	cmpl $0,TI_PRE_COUNT(%ebp)	# non-zero preempt_count ?
++	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
+ 	jnz restore_all
+ need_resched:
+-	movl TI_FLAGS(%ebp), %ecx	# need_resched set ?
++	movl TI_flags(%ebp), %ecx	# need_resched set ?
+ 	testb $_TIF_NEED_RESCHED, %cl
+ 	jz restore_all
+ 	testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
+ 	jz restore_all
+-	movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebp)
++	movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
+ 	sti
+ 	call schedule
+-	movl $0,TI_PRE_COUNT(%ebp)
++	movl $0,TI_preempt_count(%ebp)
+ 	cli
+ 	jmp need_resched
+ #endif
+@@ -244,37 +361,50 @@ sysenter_past_esp:
+ 	pushl $(__USER_CS)
+ 	pushl $SYSENTER_RETURN
+ 
+-/*
+- * Load the potential sixth argument from user stack.
+- * Careful about security.
+- */
+-	cmpl $__PAGE_OFFSET-3,%ebp
+-	jae syscall_fault
+-1:	movl (%ebp),%ebp
+-.section __ex_table,"a"
+-	.align 4
+-	.long 1b,syscall_fault
+-.previous
+-
+ 	pushl %eax
+ 	SAVE_ALL
+ 	GET_THREAD_INFO(%ebp)
+ 	cmpl $(nr_syscalls), %eax
+ 	jae syscall_badsys
+ 
+-	testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++	testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+ 	jnz syscall_trace_entry
+ 	call *sys_call_table(,%eax,4)
+ 	movl %eax,EAX(%esp)
+ 	cli
+-	movl TI_FLAGS(%ebp), %ecx
++	movl TI_flags(%ebp), %ecx
+ 	testw $_TIF_ALLWORK_MASK, %cx
+ 	jne syscall_exit_work
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++	GET_THREAD_INFO(%ebp)
++	movl TI_virtual_stack(%ebp), %edx
++	movl TI_user_pgd(%ebp), %ecx
++	movl %esp, %ebx
++	andl $0x1fff, %ebx
++	orl %ebx, %edx
++sysexit_ret_start_marker:
++	movl %edx, %esp
++	movl %ecx, %cr3
++#endif
++	/*
++	 * only ebx is not restored by the userspace sysenter vsyscall
++	 * code, it assumes it to be callee-saved.
++	 */
++	movl EBX(%esp), %ebx
++
+ /* if something modifies registers it must also disable sysexit */
++
+ 	movl EIP(%esp), %edx
+ 	movl OLDESP(%esp), %ecx
++
+ 	sti
+ 	sysexit
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++sysexit_ret_end_marker:
++	nop
++#endif
+ 
+ 
+ 	# system call handler stub
+@@ -285,7 +415,7 @@ ENTRY(system_call)
+ 	cmpl $(nr_syscalls), %eax
+ 	jae syscall_badsys
+ 					# system call tracing in operation
+-	testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++	testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+ 	jnz syscall_trace_entry
+ syscall_call:
+ 	call *sys_call_table(,%eax,4)
+@@ -294,10 +424,23 @@ syscall_exit:
+ 	cli				# make sure we don't miss an interrupt
+ 					# setting need_resched or sigpending
+ 					# between sampling and the iret
+-	movl TI_FLAGS(%ebp), %ecx
++	movl TI_flags(%ebp), %ecx
+ 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
+ 	jne syscall_exit_work
+ restore_all:
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
++	movb CS(%esp), %al
++	testl $(VM_MASK | 3), %eax
++	jz resume_kernelX		# returning to kernel or vm86-space
++
++	cmpl $0,TI_preempt_count(%ebp)	# non-zero preempt_count ?
++	jz resume_kernelX
++
++        int $3
++
++resume_kernelX:
++#endif
+ 	RESTORE_ALL
+ 
+ 	# perform work that needs to be done immediately before resumption
+@@ -310,7 +453,7 @@ work_resched:
+ 	cli				# make sure we don't miss an interrupt
+ 					# setting need_resched or sigpending
+ 					# between sampling and the iret
+-	movl TI_FLAGS(%ebp), %ecx
++	movl TI_flags(%ebp), %ecx
+ 	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other
+ 					# than syscall tracing?
+ 	jz restore_all
+@@ -325,6 +468,22 @@ work_notifysig:				# deal with pending s
+ 					# vm86-space
+ 	xorl %edx, %edx
+ 	call do_notify_resume
++
++#if CONFIG_X86_HIGH_ENTRY
++	/*
++	 * Reload db7 if necessary:
++	 */
++	movl TI_flags(%ebp), %ecx
++	testb $_TIF_DB7, %cl
++	jnz work_db7
++
++	jmp restore_all
++
++work_db7:
++	movl TI_task(%ebp), %edx;
++	movl task_thread_db7(%edx), %edx;
++	movl %edx, %db7;
++#endif
+ 	jmp restore_all
+ 
+ 	ALIGN
+@@ -380,7 +539,7 @@ syscall_badsys:
+  */
+ .data
+ ENTRY(interrupt)
+-.text
++.previous
+ 
+ vector=0
+ ENTRY(irq_entries_start)
+@@ -390,7 +549,7 @@ ENTRY(irq_entries_start)
+ 	jmp common_interrupt
+ .data
+ 	.long 1b
+-.text
++.previous
+ vector=vector+1
+ .endr
+ 
+@@ -431,12 +590,17 @@ error_code:
+ 	movl ES(%esp), %edi		# get the function address
+ 	movl %eax, ORIG_EAX(%esp)
+ 	movl %ecx, ES(%esp)
+-	movl %esp, %edx
+ 	pushl %esi			# push the error code
+-	pushl %edx			# push the pt_regs pointer
+ 	movl $(__USER_DS), %edx
+ 	movl %edx, %ds
+ 	movl %edx, %es
++
++/* clobbers edx, ebx and ebp */
++	__SWITCH_KERNELSPACE
++
++	leal 4(%esp), %edx		# prepare pt_regs
++	pushl %edx			# push pt_regs
++
+ 	call *%edi
+ 	addl $8, %esp
+ 	jmp ret_from_exception
+@@ -527,7 +691,7 @@ nmi_stack_correct:
+ 	pushl %edx
+ 	call do_nmi
+ 	addl $8, %esp
+-	RESTORE_ALL
++	jmp restore_all
+ 
+ nmi_stack_fixup:
+ 	FIX_STACK(12,nmi_stack_correct, 1)
+@@ -595,7 +759,7 @@ ENTRY(page_fault)
+ #ifdef CONFIG_X86_MCE
+ ENTRY(machine_check)
+ 	pushl $0
+-	pushl $do_machine_check
++	pushl machine_check_vector
+ 	jmp error_code
+ #endif
+ 
+@@ -604,6 +768,8 @@ ENTRY(spurious_interrupt_bug)
+ 	pushl $do_spurious_interrupt_bug
+ 	jmp error_code
+ 
++.previous
++
+ .data
+ ENTRY(sys_call_table)
+ 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
+@@ -879,5 +1045,60 @@ ENTRY(sys_call_table)
+ 	.long sys_tgkill	/* 270 */
+ 	.long sys_utimes
+  	.long sys_fadvise64_64
++	.long sys_ni_syscall	/* sys_vserver */
+ 
+ nr_syscalls=(.-sys_call_table)/4
++
++
++#	Here we do call frames.  We cheat a bit as we only really need
++#	correct frames at locations we can actually look at from a
++#	debugger.  Since the break instruction trap actually goes thru
++#	some of this code, we don't really need info on those areas, but
++#	only after the fact.  I.e. if we can not step or break in a
++#	location or end up with a return address pointing at the
++#	location, we don't need a correct call frame for it.
++
++#if 0
++
++#include <linux/dwarf2-lang.h>
++/*
++ * The register numbers as known by gdb
++ */
++#define _EAX 0
++#define _ECX 1
++#define _EDX 2
++#define _EBX 3
++#define _ESP 4
++#define _EBP 5
++#define _ESI 6
++#define _EDI 7
++#define _PC  8
++#define _EIP 8
++#define _PS  9
++#define _EFLAGS  9
++#define _CS 10
++#define _SS 11
++#define _DS 12
++#define _ES 13
++#define _FS 14
++#define _GS 15
++
++	CFI_preamble(c1,_PC,1,1)
++	CFA_define_reference(_ESP,OLDESP)
++	CFA_define_offset(_EIP,EIP)
++	CFA_define_offset(_EBX,EBX)
++	CFA_define_offset(_ECX,ECX)
++	CFA_define_offset(_EDX,EDX)
++	CFA_define_offset(_ESI,ESI)
++	CFA_define_offset(_EDI,EDI)
++	CFA_define_offset(_EBP,EBP)
++	CFA_define_offset(_EAX,EAX)
++	CFA_define_offset(_EFLAGS,EFLAGS)
++	CFA_define_offset(_CS,CS)
++	CFA_define_offset(_DS,DS)
++	CFA_define_offset(_ES,ES)
++	CFI_postamble(c1)
++
++	FDE_preamble(c1,f1,ret_from_intr,(divide_error - ret_from_intr))
++	FDE_postamble(f1)
++#endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/entry_trampoline.c	2003-10-05 00:36:48.000000000 -0700
+@@ -0,0 +1,75 @@
++/*
++ * linux/arch/i386/kernel/entry_trampoline.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * This file contains the needed support code for 4GB userspace
++ */
++
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/highmem.h>
++#include <asm/desc.h>
++#include <asm/atomic_kmap.h>
++
++extern char __entry_tramp_start, __entry_tramp_end, __start___entry_text;
++
++void __init init_entry_mappings(void)
++{
++#ifdef CONFIG_X86_HIGH_ENTRY
++	void *tramp;
++
++	/*
++	 * We need a high IDT and GDT for the 4G/4G split:
++	 */
++	trap_init_virtual_IDT();
++
++	__set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL);
++	__set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL);
++	tramp = (void *)fix_to_virt(FIX_ENTRY_TRAMPOLINE_0);
++
++	printk("mapped 4G/4G trampoline to %p.\n", tramp);
++	BUG_ON((void *)&__start___entry_text != tramp);
++	/*
++	 * Virtual kernel stack:
++	 */
++	BUG_ON(__kmap_atomic_vaddr(KM_VSTACK0) & 8191);
++	BUG_ON(sizeof(struct desc_struct)*NR_CPUS*GDT_ENTRIES > 2*PAGE_SIZE);
++	BUG_ON((unsigned int)&__entry_tramp_end - (unsigned int)&__entry_tramp_start > 2*PAGE_SIZE);
++
++	/*
++	 * set up the initial thread's virtual stack related
++	 * fields:
++	 */
++	current->thread.stack_page0 = virt_to_page((char *)current->thread_info);
++	current->thread.stack_page1 = virt_to_page((char *)current->thread_info + PAGE_SIZE);
++	current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++	__kunmap_atomic_type(KM_VSTACK0);
++	__kunmap_atomic_type(KM_VSTACK1);
++        __kmap_atomic(current->thread.stack_page0, KM_VSTACK0);
++        __kmap_atomic(current->thread.stack_page1, KM_VSTACK1);
++
++#endif
++	printk("current: %p\n", current);
++	printk("current->thread_info: %p\n", current->thread_info);
++	current->thread_info->real_stack = (void *)current->thread_info;
++	current->thread_info->user_pgd = NULL;
++	current->thread.esp0 = (unsigned long)current->thread_info->real_stack + THREAD_SIZE;
++}
++
++
++
++void __init entry_trampoline_setup(void)
++{
++	/*
++	 * old IRQ entries set up by the boot code will still hang
++	 * around - they are a sign of hw trouble anyway, now they'll
++	 * produce a double fault message.
++	 */
++	trap_init_virtual_GDT();
++}
+--- linux-2.6.0-test6/arch/i386/kernel/head.S	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/head.S	2003-10-05 00:36:48.000000000 -0700
+@@ -16,6 +16,7 @@
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
+ #include <asm/cache.h>
++#include <asm/asm_offsets.h>
+ 
+ #define OLD_CL_MAGIC_ADDR	0x90020
+ #define OLD_CL_MAGIC		0xA33F
+@@ -330,7 +331,7 @@ ENTRY(stack_start)
+ 
+ /* This is the default interrupt "handler" :-) */
+ int_msg:
+-	.asciz "Unknown interrupt\n"
++	.asciz "Unknown interrupt or fault at EIP %p %p %p\n"
+ 	ALIGN
+ ignore_int:
+ 	cld
+@@ -342,9 +343,17 @@ ignore_int:
+ 	movl $(__KERNEL_DS),%eax
+ 	movl %eax,%ds
+ 	movl %eax,%es
++	pushl 16(%esp)
++	pushl 24(%esp)
++	pushl 32(%esp)
++	pushl 40(%esp)
+ 	pushl $int_msg
+ 	call printk
+ 	popl %eax
++	popl %eax
++	popl %eax
++	popl %eax
++	popl %eax
+ 	popl %ds
+ 	popl %es
+ 	popl %edx
+@@ -377,23 +386,27 @@ cpu_gdt_descr:
+ 	.fill NR_CPUS-1,8,0		# space for the other GDT descriptors
+ 
+ /*
+- * This is initialized to create an identity-mapping at 0-8M (for bootup
+- * purposes) and another mapping of the 0-8M area at virtual address
++ * This is initialized to create an identity-mapping at 0-16M (for bootup
++ * purposes) and another mapping of the 0-16M area at virtual address
+  * PAGE_OFFSET.
+  */
+ .org 0x1000
+ ENTRY(swapper_pg_dir)
+ 	.long 0x00102007
+ 	.long 0x00103007
+-	.fill BOOT_USER_PGD_PTRS-2,4,0
+-	/* default: 766 entries */
++	.long 0x00104007
++	.long 0x00105007
++	.fill BOOT_USER_PGD_PTRS-4,4,0
++	/* default: 764 entries */
+ 	.long 0x00102007
+ 	.long 0x00103007
+-	/* default: 254 entries */
+-	.fill BOOT_KERNEL_PGD_PTRS-2,4,0
++	.long 0x00104007
++	.long 0x00105007
++	/* default: 252 entries */
++	.fill BOOT_KERNEL_PGD_PTRS-4,4,0
+ 
+ /*
+- * The page tables are initialized to only 8MB here - the final page
++ * The page tables are initialized to only 16MB here - the final page
+  * tables are set up later depending on memory size.
+  */
+ .org 0x2000
+@@ -402,15 +415,21 @@ ENTRY(pg0)
+ .org 0x3000
+ ENTRY(pg1)
+ 
++.org 0x4000
++ENTRY(pg2)
++
++.org 0x5000
++ENTRY(pg3)
++
+ /*
+  * empty_zero_page must immediately follow the page tables ! (The
+  * initialization loop counts until empty_zero_page)
+  */
+ 
+-.org 0x4000
++.org 0x6000
+ ENTRY(empty_zero_page)
+ 
+-.org 0x5000
++.org 0x7000
+ 
+ /*
+  * Real beginning of normal "text" segment
+@@ -419,12 +438,12 @@ ENTRY(stext)
+ ENTRY(_stext)
+ 
+ /*
+- * This starts the data section. Note that the above is all
+- * in the text section because it has alignment requirements
+- * that we cannot fulfill any other way.
++ * This starts the data section.
+  */
+ .data
+ 
++.align PAGE_SIZE_asm
++
+ /*
+  * The Global Descriptor Table contains 28 quadwords, per-CPU.
+  */
+@@ -439,7 +458,9 @@ ENTRY(boot_gdt_table)
+ 	.quad 0x00cf9a000000ffff	/* kernel 4GB code at 0x00000000 */
+ 	.quad 0x00cf92000000ffff	/* kernel 4GB data at 0x00000000 */
+ #endif
+-	.align L1_CACHE_BYTES
++
++.align PAGE_SIZE_asm
++
+ ENTRY(cpu_gdt_table)
+ 	.quad 0x0000000000000000	/* NULL descriptor */
+ 	.quad 0x0000000000000000	/* 0x0b reserved */
+--- linux-2.6.0-test6/arch/i386/kernel/i386_ksyms.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/i386_ksyms.c	2003-10-05 00:36:48.000000000 -0700
+@@ -98,7 +98,6 @@ EXPORT_SYMBOL_NOVERS(__down_failed_inter
+ EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+ EXPORT_SYMBOL_NOVERS(__up_wakeup);
+ /* Networking helper routines. */
+-EXPORT_SYMBOL(csum_partial_copy_generic);
+ /* Delay loops */
+ EXPORT_SYMBOL(__ndelay);
+ EXPORT_SYMBOL(__udelay);
+@@ -112,13 +111,17 @@ EXPORT_SYMBOL_NOVERS(__get_user_4);
+ EXPORT_SYMBOL(strpbrk);
+ EXPORT_SYMBOL(strstr);
+ 
++#if !defined(CONFIG_X86_UACCESS_INDIRECT)
+ EXPORT_SYMBOL(strncpy_from_user);
+-EXPORT_SYMBOL(__strncpy_from_user);
++EXPORT_SYMBOL(__direct_strncpy_from_user);
+ EXPORT_SYMBOL(clear_user);
+ EXPORT_SYMBOL(__clear_user);
+ EXPORT_SYMBOL(__copy_from_user_ll);
+ EXPORT_SYMBOL(__copy_to_user_ll);
+ EXPORT_SYMBOL(strnlen_user);
++#else /* CONFIG_X86_UACCESS_INDIRECT */
++EXPORT_SYMBOL(direct_csum_partial_copy_generic);
++#endif
+ 
+ EXPORT_SYMBOL(dma_alloc_coherent);
+ EXPORT_SYMBOL(dma_free_coherent);
+--- linux-2.6.0-test6/arch/i386/kernel/i387.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/i386/kernel/i387.c	2003-10-05 00:36:48.000000000 -0700
+@@ -219,6 +219,7 @@ void set_fpu_mxcsr( struct task_struct *
+ static int convert_fxsr_to_user( struct _fpstate __user *buf,
+ 					struct i387_fxsave_struct *fxsave )
+ {
++	struct _fpreg tmp[8]; /* 80 bytes scratch area */
+ 	unsigned long env[7];
+ 	struct _fpreg __user *to;
+ 	struct _fpxreg *from;
+@@ -235,23 +236,25 @@ static int convert_fxsr_to_user( struct 
+ 	if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
+ 		return 1;
+ 
+-	to = &buf->_st[0];
++	to = tmp;
+ 	from = (struct _fpxreg *) &fxsave->st_space[0];
+ 	for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ 		unsigned long *t = (unsigned long *)to;
+ 		unsigned long *f = (unsigned long *)from;
+ 
+-		if (__put_user(*f, t) ||
+-				__put_user(*(f + 1), t + 1) ||
+-				__put_user(from->exponent, &to->exponent))
+-			return 1;
++		*t = *f;
++		*(t + 1) = *(f+1);
++		to->exponent = from->exponent;
+ 	}
++	if (copy_to_user(buf->_st, tmp, sizeof(struct _fpreg [8])))
++		return 1;
+ 	return 0;
+ }
+ 
+ static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
+ 					  struct _fpstate __user *buf )
+ {
++	struct _fpreg tmp[8]; /* 80 bytes scratch area */
+ 	unsigned long env[7];
+ 	struct _fpxreg *to;
+ 	struct _fpreg __user *from;
+@@ -259,6 +262,8 @@ static int convert_fxsr_from_user( struc
+ 
+ 	if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
+ 		return 1;
++	if (copy_from_user(tmp, buf->_st, sizeof(struct _fpreg [8])))
++		return 1;
+ 
+ 	fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+ 	fxsave->swd = (unsigned short)(env[1] & 0xffff);
+@@ -270,15 +275,14 @@ static int convert_fxsr_from_user( struc
+ 	fxsave->fos = env[6];
+ 
+ 	to = (struct _fpxreg *) &fxsave->st_space[0];
+-	from = &buf->_st[0];
++	from = tmp;
+ 	for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ 		unsigned long *t = (unsigned long *)to;
+ 		unsigned long *f = (unsigned long *)from;
+ 
+-		if (__get_user(*t, f) ||
+-				__get_user(*(t + 1), f + 1) ||
+-				__get_user(to->exponent, &from->exponent))
+-			return 1;
++		*t = *f;
++		*(t + 1) = *(f + 1);
++		to->exponent = from->exponent;
+ 	}
+ 	return 0;
+ }
+@@ -549,13 +553,3 @@ int dump_task_extended_fpu(struct task_s
+ 	}
+ 	return fpvalid;
+ }
+-
+-
+-#ifdef CONFIG_SMP
+-void dump_smp_unlazy_fpu(void)
+-{
+-	unlazy_fpu(current);
+-	return;
+-}
+-#endif
+-
+--- linux-2.6.0-test6/arch/i386/kernel/i8259.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/i386/kernel/i8259.c	2003-10-05 00:36:20.000000000 -0700
+@@ -419,8 +419,10 @@ void __init init_IRQ(void)
+ 	 * us. (some of these will be overridden and become
+ 	 * 'special' SMP interrupts)
+ 	 */
+-	for (i = 0; i < NR_IRQS; i++) {
++	for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
+ 		int vector = FIRST_EXTERNAL_VECTOR + i;
++		if (i >= NR_IRQS)
++			break;
+ 		if (vector != SYSCALL_VECTOR) 
+ 			set_intr_gate(vector, interrupt[i]);
+ 	}
+--- linux-2.6.0-test6/arch/i386/kernel/init_task.c	2003-06-14 12:18:35.000000000 -0700
++++ 25/arch/i386/kernel/init_task.c	2003-10-05 00:36:48.000000000 -0700
+@@ -23,7 +23,7 @@ struct mm_struct init_mm = INIT_MM(init_
+  */
+ union thread_union init_thread_union 
+ 	__attribute__((__section__(".data.init_task"))) =
+-		{ INIT_THREAD_INFO(init_task) };
++		{ INIT_THREAD_INFO(init_task, init_thread_union) };
+ 
+ /*
+  * Initial task structure.
+@@ -39,5 +39,5 @@ struct task_struct init_task = INIT_TASK
+  * section. Since TSS's are completely CPU-local, we want them
+  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+  */ 
+-struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS };
++struct tss_struct init_tss[NR_CPUS] __attribute__((__section__(".data.tss"))) = { [0 ... NR_CPUS-1] = INIT_TSS };
+ 
+--- linux-2.6.0-test6/arch/i386/kernel/io_apic.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/io_apic.c	2003-10-05 00:36:27.000000000 -0700
+@@ -76,6 +76,14 @@ static struct irq_pin_list {
+ 	int apic, pin, next;
+ } irq_2_pin[PIN_MAP_SIZE];
+ 
++#ifdef CONFIG_PCI_USE_VECTOR
++int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
++#define vector_to_irq(vector) 	\
++	(platform_legacy_irq(vector) ? vector : vector_irq[vector])
++#else
++#define vector_to_irq(vector)	(vector)
++#endif
++
+ /*
+  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
+  * shared ISA-space IRQs, so we have to support them. We are super
+@@ -249,7 +257,7 @@ static void clear_IO_APIC (void)
+ 			clear_IO_APIC_pin(apic, pin);
+ }
+ 
+-static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask)
++static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
+ {
+ 	unsigned long flags;
+ 	int pin;
+@@ -288,7 +296,7 @@ static void set_ioapic_affinity(unsigned
+ 
+ extern cpumask_t irq_affinity[NR_IRQS];
+ 
+-static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
++cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
+ 
+ #define IRQBALANCE_CHECK_ARCH -999
+ static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
+@@ -670,13 +678,11 @@ static int __init irqbalance_disable(cha
+ 
+ __setup("noirqbalance", irqbalance_disable);
+ 
+-static void set_ioapic_affinity(unsigned int irq, cpumask_t mask);
+-
+ static inline void move_irq(int irq)
+ {
+ 	/* note - we hold the desc->lock */
+ 	if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) {
+-		set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]);
++		set_ioapic_affinity_irq(irq, pending_irq_balance_cpumask[irq]);
+ 		cpus_clear(pending_irq_balance_cpumask[irq]);
+ 	}
+ }
+@@ -853,7 +859,7 @@ void __init setup_ioapic_dest(cpumask_t 
+ 			if (irq_entry == -1)
+ 				continue;
+ 			irq = pin_2_irq(irq_entry, ioapic, pin);
+-			set_ioapic_affinity(irq, mask);
++			set_ioapic_affinity_irq(irq, mask);
+ 		}
+ 
+ 	}
+@@ -1138,12 +1144,14 @@ static inline int IO_APIC_irq_trigger(in
+ 	return 0;
+ }
+ 
+-int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
++u8 *irq_vector;
++int nr_irqs;
+ 
+-static int __init assign_irq_vector(int irq)
++#ifndef CONFIG_PCI_USE_VECTOR
++int __init assign_irq_vector(int irq)
+ {
+ 	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
+-	BUG_ON(irq >= NR_IRQS);
++	BUG_ON(irq >= nr_irqs);
+ 	if (IO_APIC_VECTOR(irq) > 0)
+ 		return IO_APIC_VECTOR(irq);
+ next:
+@@ -1157,11 +1165,36 @@ next:
+ 	}
+ 
+ 	IO_APIC_VECTOR(irq) = current_vector;
++
+ 	return current_vector;
+ }
++#endif
+ 
+-static struct hw_interrupt_type ioapic_level_irq_type;
+-static struct hw_interrupt_type ioapic_edge_irq_type;
++static struct hw_interrupt_type ioapic_level_type;
++static struct hw_interrupt_type ioapic_edge_type;
++
++#define IOAPIC_AUTO	-1
++#define IOAPIC_EDGE	0
++#define IOAPIC_LEVEL	1
++
++static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
++{
++	if (use_pci_vector() && !platform_legacy_irq(irq)) {
++		if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++				trigger == IOAPIC_LEVEL)
++			irq_desc[vector].handler = &ioapic_level_type;
++		else
++			irq_desc[vector].handler = &ioapic_edge_type;
++		set_intr_gate(vector, interrupt[vector]);
++	} else	{
++		if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++				trigger == IOAPIC_LEVEL)
++			irq_desc[irq].handler = &ioapic_level_type;
++		else
++			irq_desc[irq].handler = &ioapic_edge_type;
++		set_intr_gate(vector, interrupt[irq]);
++	}
++}
+ 
+ void __init setup_IO_APIC_irqs(void)
+ {
+@@ -1219,13 +1252,7 @@ void __init setup_IO_APIC_irqs(void)
+ 		if (IO_APIC_IRQ(irq)) {
+ 			vector = assign_irq_vector(irq);
+ 			entry.vector = vector;
+-
+-			if (IO_APIC_irq_trigger(irq))
+-				irq_desc[irq].handler = &ioapic_level_irq_type;
+-			else
+-				irq_desc[irq].handler = &ioapic_edge_irq_type;
+-
+-			set_intr_gate(vector, interrupt[irq]);
++			ioapic_register_intr(irq, vector, IOAPIC_AUTO);
+ 		
+ 			if (!apic && (irq < 16))
+ 				disable_8259A_irq(irq);
+@@ -1272,7 +1299,7 @@ void __init setup_ExtINT_IRQ0_pin(unsign
+ 	 * The timer IRQ doesn't have to know that behind the
+ 	 * scene we have a 8259A-master in AEOI mode ...
+ 	 */
+-	irq_desc[0].handler = &ioapic_edge_irq_type;
++	irq_desc[0].handler = &ioapic_edge_type;
+ 
+ 	/*
+ 	 * Add it to the IO-APIC irq-routing table:
+@@ -1762,9 +1789,6 @@ static int __init timer_irq_works(void)
+  * that was delayed but this is now handled in the device
+  * independent code.
+  */
+-#define enable_edge_ioapic_irq unmask_IO_APIC_irq
+-
+-static void disable_edge_ioapic_irq (unsigned int irq) { /* nothing */ }
+ 
+ /*
+  * Starting up a edge-triggered IO-APIC interrupt is
+@@ -1775,7 +1799,6 @@ static void disable_edge_ioapic_irq (uns
+  * This is not complete - we should be able to fake
+  * an edge even if it isn't on the 8259A...
+  */
+-
+ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+ {
+ 	int was_pending = 0;
+@@ -1793,8 +1816,6 @@ static unsigned int startup_edge_ioapic_
+ 	return was_pending;
+ }
+ 
+-#define shutdown_edge_ioapic_irq	disable_edge_ioapic_irq
+-
+ /*
+  * Once we have recorded IRQ_PENDING already, we can mask the
+  * interrupt for real. This prevents IRQ storms from unhandled
+@@ -1809,9 +1830,6 @@ static void ack_edge_ioapic_irq(unsigned
+ 	ack_APIC_irq();
+ }
+ 
+-static void end_edge_ioapic_irq (unsigned int i) { /* nothing */ }
+-
+-
+ /*
+  * Level triggered interrupts can just be masked,
+  * and shutting down and starting up the interrupt
+@@ -1833,10 +1851,6 @@ static unsigned int startup_level_ioapic
+ 	return 0; /* don't check for pending */
+ }
+ 
+-#define shutdown_level_ioapic_irq	mask_IO_APIC_irq
+-#define enable_level_ioapic_irq		unmask_IO_APIC_irq
+-#define disable_level_ioapic_irq	mask_IO_APIC_irq
+-
+ static void end_level_ioapic_irq (unsigned int irq)
+ {
+ 	unsigned long v;
+@@ -1863,6 +1877,7 @@ static void end_level_ioapic_irq (unsign
+  * The idea is from Manfred Spraul.  --macro
+  */
+ 	i = IO_APIC_VECTOR(irq);
++
+ 	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+ 
+ 	ack_APIC_irq();
+@@ -1897,7 +1912,57 @@ static void end_level_ioapic_irq (unsign
+ 	}
+ }
+ 
+-static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
++#ifdef CONFIG_PCI_USE_VECTOR
++static unsigned int startup_edge_ioapic_vector(unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	return startup_edge_ioapic_irq(irq);
++}
++
++static void ack_edge_ioapic_vector(unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	ack_edge_ioapic_irq(irq);
++}
++
++static unsigned int startup_level_ioapic_vector (unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	return startup_level_ioapic_irq (irq);
++}
++
++static void end_level_ioapic_vector (unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	end_level_ioapic_irq(irq);
++}
++
++static void mask_IO_APIC_vector (unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	mask_IO_APIC_irq(irq);
++}
++
++static void unmask_IO_APIC_vector (unsigned int vector)
++{
++	int irq = vector_to_irq(vector);
++
++	unmask_IO_APIC_irq(irq);
++}
++
++static void set_ioapic_affinity_vector (unsigned int vector,
++					unsigned long cpu_mask)
++{
++	int irq = vector_to_irq(vector);
++
++	set_ioapic_affinity_irq(irq, cpu_mask);
++}
++#endif
+ 
+ /*
+  * Level and edge triggered IO-APIC interrupts need different handling,
+@@ -1907,26 +1972,25 @@ static void mask_and_ack_level_ioapic_ir
+  * edge-triggered handler, without risking IRQ storms and other ugly
+  * races.
+  */
+-
+-static struct hw_interrupt_type ioapic_edge_irq_type = {
++static struct hw_interrupt_type ioapic_edge_type = {
+ 	.typename 	= "IO-APIC-edge",
+-	.startup 	= startup_edge_ioapic_irq,
+-	.shutdown 	= shutdown_edge_ioapic_irq,
+-	.enable 	= enable_edge_ioapic_irq,
+-	.disable 	= disable_edge_ioapic_irq,
+-	.ack 		= ack_edge_ioapic_irq,
+-	.end 		= end_edge_ioapic_irq,
++	.startup 	= startup_edge_ioapic,
++	.shutdown 	= shutdown_edge_ioapic,
++	.enable 	= enable_edge_ioapic,
++	.disable 	= disable_edge_ioapic,
++	.ack 		= ack_edge_ioapic,
++	.end 		= end_edge_ioapic,
+ 	.set_affinity 	= set_ioapic_affinity,
+ };
+ 
+-static struct hw_interrupt_type ioapic_level_irq_type = {
++static struct hw_interrupt_type ioapic_level_type = {
+ 	.typename 	= "IO-APIC-level",
+-	.startup 	= startup_level_ioapic_irq,
+-	.shutdown 	= shutdown_level_ioapic_irq,
+-	.enable 	= enable_level_ioapic_irq,
+-	.disable 	= disable_level_ioapic_irq,
+-	.ack 		= mask_and_ack_level_ioapic_irq,
+-	.end 		= end_level_ioapic_irq,
++	.startup 	= startup_level_ioapic,
++	.shutdown 	= shutdown_level_ioapic,
++	.enable 	= enable_level_ioapic,
++	.disable 	= disable_level_ioapic,
++	.ack 		= mask_and_ack_level_ioapic,
++	.end 		= end_level_ioapic,
+ 	.set_affinity 	= set_ioapic_affinity,
+ };
+ 
+@@ -1946,7 +2010,13 @@ static inline void init_IO_APIC_traps(vo
+ 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
+ 	 */
+ 	for (irq = 0; irq < NR_IRQS ; irq++) {
+-		if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) {
++		int tmp = irq;
++		if (use_pci_vector()) {
++			if (!platform_legacy_irq(tmp))
++				if ((tmp = vector_to_irq(tmp)) == -1)
++					continue;
++		}
++		if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
+ 			/*
+ 			 * Hmm.. We don't have an entry for this,
+ 			 * so default to an old-fashioned 8259
+@@ -2378,10 +2448,12 @@ int io_apic_set_pci_routing (int ioapic,
+ 		"IRQ %d Mode:%i Active:%i)\n", ioapic, 
+ 		mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low);
+ 
++ 	if (use_pci_vector() && !platform_legacy_irq(irq))
++		irq = IO_APIC_VECTOR(irq);
+ 	if (edge_level) {
+-	irq_desc[irq].handler = &ioapic_level_irq_type;
++		irq_desc[irq].handler = &ioapic_level_type;
+ 	} else {
+-		irq_desc[irq].handler = &ioapic_edge_irq_type;
++		irq_desc[irq].handler = &ioapic_edge_type;
+ 	}
+ 
+ 	set_intr_gate(entry.vector, interrupt[irq]);
+--- linux-2.6.0-test6/arch/i386/kernel/irq.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/irq.c	2003-10-05 00:33:50.000000000 -0700
+@@ -44,6 +44,7 @@
+ #include <asm/delay.h>
+ #include <asm/desc.h>
+ #include <asm/irq.h>
++#include <asm/kgdb.h>
+ 
+ /*
+  * Linux has a controller-independent x86 interrupt architecture.
+@@ -499,6 +500,17 @@ out:
+ 
+ 	irq_exit();
+ 
++#ifdef CONFIG_KGDB
++	/*
++	 * We need to do this after clearing out of all the interrupt
++	 * machinery because kgdb will reenter the NIC driver and the IRQ
++	 * system.  synchronize_irq() (at least) will deadlock.
++	 */
++	if (kgdb_eth_need_breakpoint[smp_processor_id()]) {
++		kgdb_eth_need_breakpoint[smp_processor_id()] = 0;
++		BREAKPOINT;
++	}
++#endif
+ 	return 1;
+ }
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/kgdb_stub.c	2003-10-05 00:33:51.000000000 -0700
+@@ -0,0 +1,2492 @@
++/*
++ *
++ * This program 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, or (at your option) any
++ * later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
++ * General Public License for more details.
++ *
++ */
++
++/*
++ * Copyright (c) 2000 VERITAS Software Corporation.
++ *
++ */
++/****************************************************************************
++ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
++ *
++ *  Module name: remcom.c $
++ *  Revision: 1.34 $
++ *  Date: 91/03/09 12:29:49 $
++ *  Contributor:     Lake Stevens Instrument Division$
++ *
++ *  Description:     low level support for gdb debugger. $
++ *
++ *  Considerations:  only works on target hardware $
++ *
++ *  Written by:	     Glenn Engel $
++ *  Updated by:	     David Grothe <dave@gcom.com>
++ *  Updated by:	     Robert Walsh <rjwalsh@durables.org>
++ *  Updated by:	     wangdi <wangdi@clusterfs.com>
++ *  ModuleState:     Experimental $
++ *
++ *  NOTES:	     See Below $
++ *
++ *  Modified for 386 by Jim Kingdon, Cygnus Support.
++ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
++ *
++ *  Changes to allow auto initilization.  All that is needed is that it
++ *  be linked with the kernel and a break point (int 3) be executed.
++ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
++ *  this. It should also be possible, once the interrupt system is up, to
++ *  call putDebugChar("+").  Once this is done, the remote debugger should
++ *  get our attention by sending a ^C in a packet. George Anzinger
++ *  <george@mvista.com>
++ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
++ *  Added thread support, support for multiple processors,
++ *	support for ia-32(x86) hardware debugging.
++ *	Amit S. Kale ( akale@veritas.com )
++ *
++ *  Modified to support debugging over ethernet by Robert Walsh
++ *  <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ *  code by San Mehat.
++ *
++ *
++ *  To enable debugger support, two things need to happen.  One, a
++ *  call to set_debug_traps() is necessary in order to allow any breakpoints
++ *  or error conditions to be properly intercepted and reported to gdb.
++ *  Two, a breakpoint needs to be generated to begin communication.  This
++ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
++ *  simulates a breakpoint by executing an int 3.
++ *
++ *************
++ *
++ *    The following gdb commands are supported:
++ *
++ * command	    function				   Return value
++ *
++ *    g		    return the value of the CPU registers  hex data or ENN
++ *    G		    set the value of the CPU registers	   OK or ENN
++ *
++ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA	   hex data or ENN
++ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA	   OK or ENN
++ *
++ *    c		    Resume at current address		   SNN	 ( signal NN)
++ *    cAA..AA	    Continue at address AA..AA		   SNN
++ *
++ *    s		    Step one instruction		   SNN
++ *    sAA..AA	    Step one instruction from AA..AA	   SNN
++ *
++ *    k		    kill
++ *
++ *    ?		    What was the last sigval ?		   SNN	 (signal NN)
++ *
++ * All commands and responses are sent with a packet which includes a
++ * checksum.  A packet consists of
++ *
++ * $<packet info>#<checksum>.
++ *
++ * where
++ * <packet info> :: <characters representing the command or response>
++ * <checksum>	 :: < two hex digits computed as modulo 256 sum of <packetinfo>>
++ *
++ * When a packet is received, it is first acknowledged with either '+' or '-'.
++ * '+' indicates a successful transfer.	 '-' indicates a failed transfer.
++ *
++ * Example:
++ *
++ * Host:		  Reply:
++ * $m0,10#2a		   +$00010203040506070809101112131415#42
++ *
++ ****************************************************************************/
++#define KGDB_VERSION "<20030915.1651.33>"
++#include <linux/config.h>
++#include <linux/types.h>
++#include <asm/string.h>		/* for strcpy */
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <asm/vm86.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>		/* for linux pt_regs struct */
++#include <asm/kgdb_local.h>
++#include <linux/list.h>
++#include <asm/atomic.h>
++#include <asm/processor.h>
++#include <linux/irq.h>
++#include <asm/desc.h>
++#include <linux/inet.h>
++#include <linux/kallsyms.h>
++
++/************************************************************************
++ *
++ * external low-level support routines
++ */
++typedef void (*Function) (void);	/* pointer to a function */
++
++/* Thread reference */
++typedef unsigned char threadref[8];
++
++extern int tty_putDebugChar(int);     /* write a single character      */
++extern int tty_getDebugChar(void);    /* read and return a single char */
++extern void tty_flushDebugChar(void); /* flush pending characters      */
++extern int eth_putDebugChar(int);     /* write a single character      */
++extern int eth_getDebugChar(void);    /* read and return a single char */
++extern void eth_flushDebugChar(void); /* flush pending characters      */
++extern void kgdb_eth_set_trapmode(int);
++extern void kgdb_eth_reply_arp(void);   /*send arp request */
++extern volatile int kgdb_eth_is_initializing;
++
++
++/************************************************************************/
++/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
++/* at least NUMREGBYTES*2 are needed for register packets */
++/* Longer buffer is needed to list all threads */
++#define BUFMAX 400
++
++char *kgdb_version = KGDB_VERSION;
++
++/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
++int debug_regs = 0;		/* set to non-zero to print registers */
++
++/* filled in by an external module */
++char *gdb_module_offsets;
++
++static const char hexchars[] = "0123456789abcdef";
++
++/* Number of bytes of registers.  */
++#define NUMREGBYTES 64
++/*
++ * Note that this register image is in a different order than
++ * the register image that Linux produces at interrupt time.
++ *
++ * Linux's register image is defined by struct pt_regs in ptrace.h.
++ * Just why GDB uses a different order is a historical mystery.
++ */
++enum regnames { _EAX,		/* 0 */
++	_ECX,			/* 1 */
++	_EDX,			/* 2 */
++	_EBX,			/* 3 */
++	_ESP,			/* 4 */
++	_EBP,			/* 5 */
++	_ESI,			/* 6 */
++	_EDI,			/* 7 */
++	_PC /* 8 also known as eip */ ,
++	_PS /* 9 also known as eflags */ ,
++	_CS,			/* 10 */
++	_SS,			/* 11 */
++	_DS,			/* 12 */
++	_ES,			/* 13 */
++	_FS,			/* 14 */
++	_GS			/* 15 */
++};
++
++/***************************  ASSEMBLY CODE MACROS *************************/
++/*
++ * Put the error code here just in case the user cares.
++ * Likewise, the vector number here (since GDB only gets the signal
++ * number through the usual means, and that's not very specific).
++ * The called_from is the return address so he can tell how we entered kgdb.
++ * This will allow him to seperate out the various possible entries.
++ */
++#define REMOTE_DEBUG 0		/* set != to turn on printing (also available in info) */
++
++#define PID_MAX PID_MAX_DEFAULT
++
++#ifdef CONFIG_SMP
++void smp_send_nmi_allbutself(void);
++#define IF_SMP(x) x
++#undef MAX_NO_CPUS
++#ifndef CONFIG_NO_KGDB_CPUS
++#define CONFIG_NO_KGDB_CPUS 2
++#endif
++#if CONFIG_NO_KGDB_CPUS > NR_CPUS
++#define MAX_NO_CPUS NR_CPUS
++#else
++#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
++#endif
++#define hold_init hold_on_sstep: 1,
++#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
++#define NUM_CPUS num_online_cpus()
++#else
++#define IF_SMP(x)
++#define hold_init
++#undef MAX_NO_CPUS
++#define MAX_NO_CPUS 1
++#define NUM_CPUS 1
++#endif
++#define NOCPU (struct task_struct *)0xbad1fbad
++/* *INDENT-OFF*	 */
++struct kgdb_info {
++	int used_malloc;
++	void *called_from;
++	long long entry_tsc;
++	int errcode;
++	int vector;
++	int print_debug_info;
++#ifdef CONFIG_SMP
++	int hold_on_sstep;
++	struct {
++		volatile struct task_struct *task;
++		int pid;
++		int hold;
++		struct pt_regs *regs;
++	} cpus_waiting[MAX_NO_CPUS];
++#endif
++} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
++
++/* *INDENT-ON*	*/
++
++#define used_m kgdb_info.used_malloc
++/*
++ * This is little area we set aside to contain the stack we
++ * need to build to allow gdb to call functions.  We use one
++ * per cpu to avoid locking issues.  We will do all this work
++ * with interrupts off so that should take care of the protection
++ * issues.
++ */
++#define LOOKASIDE_SIZE 200	/* should be more than enough */
++#define MALLOC_MAX   200	/* Max malloc size */
++struct {
++	unsigned int esp;
++	int array[LOOKASIDE_SIZE];
++} fn_call_lookaside[MAX_NO_CPUS];
++
++static int trap_cpu;
++static unsigned int OLD_esp;
++
++#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
++#define IF_BIT 0x200
++#define TF_BIT 0x100
++
++#define MALLOC_ROUND 8-1
++
++static char malloc_array[MALLOC_MAX];
++IF_SMP(static void to_gdb(const char *mess));
++void *
++malloc(int size)
++{
++
++	if (size <= (MALLOC_MAX - used_m)) {
++		int old_used = used_m;
++		used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
++		return &malloc_array[old_used];
++	} else {
++		return NULL;
++	}
++}
++
++/*
++ * I/O dispatch functions...
++ * Based upon kgdb_eth, either call the ethernet
++ * handler or the serial one..
++ */
++void
++putDebugChar(int c)
++{
++	if (kgdb_eth == -1) {
++		tty_putDebugChar(c);
++	} else {
++		eth_putDebugChar(c);
++	}
++}
++
++int
++getDebugChar(void)
++{
++	if (kgdb_eth == -1) {
++		return tty_getDebugChar();
++	} else {
++		return eth_getDebugChar();
++	}
++}
++
++void
++flushDebugChar(void)
++{
++	if (kgdb_eth == -1) {
++		tty_flushDebugChar();
++	} else {
++		eth_flushDebugChar();
++	}
++}
++
++/*
++ * Gdb calls functions by pushing agruments, including a return address
++ * on the stack and the adjusting EIP to point to the function.	 The
++ * whole assumption in GDB is that we are on a different stack than the
++ * one the "user" i.e. code that hit the break point, is on.  This, of
++ * course is not true in the kernel.  Thus various dodges are needed to
++ * do the call without directly messing with EIP (which we can not change
++ * as it is just a location and not a register.	 To adjust it would then
++ * require that we move every thing below EIP up or down as needed.  This
++ * will not work as we may well have stack relative pointer on the stack
++ * (such as the pointer to regs, for example).
++
++ * So here is what we do:
++ * We detect gdb attempting to store into the stack area and instead, store
++ * into the fn_call_lookaside.array at the same relative location as if it
++ * were the area ESP pointed at.  We also trap ESP modifications
++ * and uses these to adjust fn_call_lookaside.esp.  On entry
++ * fn_call_lookaside.esp will be set to point at the last entry in
++ * fn_call_lookaside.array.  This allows us to check if it has changed, and
++ * if so, on exit, we add the registers we will use to do the move and a
++ * trap/ interrupt return exit sequence.  We then adjust the eflags in the
++ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
++ * kill the interrupt bit, AND we change EIP to point at our set up stub.
++ * As part of the register set up we preset the registers to point at the
++ * begining and end of the fn_call_lookaside.array, so all the stub needs to
++ * do is move words from the array to the stack until ESP= the desired value
++ * then do the rti.  This will then transfer to the desired function with
++ * all the correct registers.  Nifty huh?
++ */
++extern asmlinkage void fn_call_stub(void);
++extern asmlinkage void fn_rtn_stub(void);
++/*					   *INDENT-OFF*	 */
++__asm__("fn_rtn_stub:\n\t"
++	"movl %eax,%esp\n\t"
++	"fn_call_stub:\n\t"
++	"1:\n\t"
++	"addl $-4,%ebx\n\t"
++	"movl (%ebx), %eax\n\t"
++	"pushl %eax\n\t"
++	"cmpl %esp,%ecx\n\t"
++	"jne  1b\n\t"
++	"popl %eax\n\t"
++	"popl %ebx\n\t"
++	"popl %ecx\n\t"
++	"iret \n\t");
++/*					     *INDENT-ON*  */
++#define gdb_i386vector	kgdb_info.vector
++#define gdb_i386errcode kgdb_info.errcode
++#define waiting_cpus	kgdb_info.cpus_waiting
++#define remote_debug	kgdb_info.print_debug_info
++#define hold_cpu(cpu)	kgdb_info.cpus_waiting[cpu].hold
++/* gdb locks */
++
++#ifdef CONFIG_SMP
++static int in_kgdb_called;
++static spinlock_t waitlocks[MAX_NO_CPUS] =
++    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
++/*
++ * The following array has the thread pointer of each of the "other"
++ * cpus.  We make it global so it can be seen by gdb.
++ */
++volatile int in_kgdb_entry_log[MAX_NO_CPUS];
++volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
++/*
++static spinlock_t continuelocks[MAX_NO_CPUS];
++*/
++spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
++/* waiters on our spinlock plus us */
++static atomic_t spinlock_waiters = ATOMIC_INIT(1);
++static int spinlock_count = 0;
++static int spinlock_cpu = 0;
++/*
++ * Note we use nested spin locks to account for the case where a break
++ * point is encountered when calling a function by user direction from
++ * kgdb. Also there is the memory exception recursion to account for.
++ * Well, yes, but this lets other cpus thru too.  Lets add a
++ * cpu id to the lock.
++ */
++#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
++			      spinlock_cpu != smp_processor_id()){\
++				      atomic_inc(&spinlock_waiters); \
++				      while (! spin_trylock(x)) {\
++					    in_kgdb(&regs);\
++				      }\
++				      atomic_dec(&spinlock_waiters); \
++				      spinlock_count = 1; \
++				      spinlock_cpu = smp_processor_id(); \
++			  }else{  \
++				      spinlock_count++; \
++			  }
++#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
++#else
++unsigned kgdb_spinlock = 0;
++#define KGDB_SPIN_LOCK(x) --*x
++#define KGDB_SPIN_UNLOCK(x) ++*x
++#endif
++
++int
++hex(char ch)
++{
++	if ((ch >= 'a') && (ch <= 'f'))
++		return (ch - 'a' + 10);
++	if ((ch >= '0') && (ch <= '9'))
++		return (ch - '0');
++	if ((ch >= 'A') && (ch <= 'F'))
++		return (ch - 'A' + 10);
++	return (-1);
++}
++
++/* scan for the sequence $<data>#<checksum>	*/
++void
++getpacket(char *buffer)
++{
++	unsigned char checksum;
++	unsigned char xmitcsum;
++	int i;
++	int count;
++	char ch;
++
++	do {
++		/* wait around for the start character, ignore all other characters */
++		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
++		checksum = 0;
++		xmitcsum = -1;
++
++		count = 0;
++
++		/* now, read until a # or end of buffer is found */
++		while (count < BUFMAX) {
++			ch = getDebugChar() & 0x7f;
++			if (ch == '#')
++				break;
++			checksum = checksum + ch;
++			buffer[count] = ch;
++			count = count + 1;
++		}
++		buffer[count] = 0;
++
++		if (ch == '#') {
++			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
++			xmitcsum += hex(getDebugChar() & 0x7f);
++			if ((remote_debug) && (checksum != xmitcsum)) {
++				printk
++				    ("bad checksum.	My count = 0x%x, sent=0x%x. buf=%s\n",
++				     checksum, xmitcsum, buffer);
++			}
++
++			if (checksum != xmitcsum)
++				putDebugChar('-');	/* failed checksum */
++			else {
++				putDebugChar('+');	/* successful transfer */
++				/* if a sequence char is present, reply the sequence ID */
++				if (buffer[2] == ':') {
++					putDebugChar(buffer[0]);
++					putDebugChar(buffer[1]);
++					/* remove sequence chars from buffer */
++					count = strlen(buffer);
++					for (i = 3; i <= count; i++)
++						buffer[i - 3] = buffer[i];
++				}
++			}
++		}
++	} while (checksum != xmitcsum);
++
++	if (remote_debug)
++		printk("R:%s\n", buffer);
++	flushDebugChar();
++}
++
++/* send the packet in buffer.  */
++
++void
++putpacket(char *buffer)
++{
++	unsigned char checksum;
++	int count;
++	char ch;
++
++	/*  $<packet info>#<checksum>. */
++
++	if (kgdb_eth == -1) {
++		do {
++			if (remote_debug)
++				printk("T:%s\n", buffer);
++			putDebugChar('$');
++			checksum = 0;
++			count = 0;
++
++			while ((ch = buffer[count])) {
++				putDebugChar(ch);
++				checksum += ch;
++				count += 1;
++			}
++
++			putDebugChar('#');
++			putDebugChar(hexchars[checksum >> 4]);
++			putDebugChar(hexchars[checksum % 16]);
++			flushDebugChar();
++
++		} while ((getDebugChar() & 0x7f) != '+');
++	} else {
++		/*
++		 * For udp, we can not transfer too much bytes once.
++		 * We only transfer MAX_SEND_COUNT size bytes each time
++		 */
++
++#define MAX_SEND_COUNT 30
++
++		int send_count = 0, i = 0;
++		char send_buf[MAX_SEND_COUNT];
++
++		do {
++			if (remote_debug)
++				printk("T:%s\n", buffer);
++			putDebugChar('$');
++			checksum = 0;
++			count = 0;
++			send_count = 0;
++			while ((ch = buffer[count])) {
++				if (send_count >= MAX_SEND_COUNT) {
++					for(i = 0; i < MAX_SEND_COUNT; i++) {
++						putDebugChar(send_buf[i]);
++					}
++					flushDebugChar();
++					send_count = 0;
++				} else {
++					send_buf[send_count] = ch;
++					checksum += ch;
++					count ++;
++					send_count++;
++				}
++			}
++			for(i = 0; i < send_count; i++)
++				putDebugChar(send_buf[i]);
++			putDebugChar('#');
++			putDebugChar(hexchars[checksum >> 4]);
++			putDebugChar(hexchars[checksum % 16]);
++			flushDebugChar();
++		} while ((getDebugChar() & 0x7f) != '+');
++	}
++}
++
++static char remcomInBuffer[BUFMAX];
++static char remcomOutBuffer[BUFMAX];
++static short error;
++
++void
++debug_error(char *format, char *parm)
++{
++	if (remote_debug)
++		printk(format, parm);
++}
++
++static void
++print_regs(struct pt_regs *regs)
++{
++	printk("EAX=%08lx ", regs->eax);
++	printk("EBX=%08lx ", regs->ebx);
++	printk("ECX=%08lx ", regs->ecx);
++	printk("EDX=%08lx ", regs->edx);
++	printk("\n");
++	printk("ESI=%08lx ", regs->esi);
++	printk("EDI=%08lx ", regs->edi);
++	printk("EBP=%08lx ", regs->ebp);
++	printk("ESP=%08lx ", (long) &regs->esp);
++	printk("\n");
++	printk(" DS=%08x ", regs->xds);
++	printk(" ES=%08x ", regs->xes);
++	printk(" SS=%08x ", __KERNEL_DS);
++	printk(" FL=%08lx ", regs->eflags);
++	printk("\n");
++	printk(" CS=%08x ", regs->xcs);
++	printk(" IP=%08lx ", regs->eip);
++#if 0
++	printk(" FS=%08x ", regs->fs);
++	printk(" GS=%08x ", regs->gs);
++#endif
++	printk("\n");
++
++}				/* print_regs */
++
++#define NEW_esp fn_call_lookaside[trap_cpu].esp
++
++static void
++regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
++{
++	gdb_regs[_EAX] = regs->eax;
++	gdb_regs[_EBX] = regs->ebx;
++	gdb_regs[_ECX] = regs->ecx;
++	gdb_regs[_EDX] = regs->edx;
++	gdb_regs[_ESI] = regs->esi;
++	gdb_regs[_EDI] = regs->edi;
++	gdb_regs[_EBP] = regs->ebp;
++	gdb_regs[_DS] = regs->xds;
++	gdb_regs[_ES] = regs->xes;
++	gdb_regs[_PS] = regs->eflags;
++	gdb_regs[_CS] = regs->xcs;
++	gdb_regs[_PC] = regs->eip;
++	/* Note, as we are a debugging the kernel, we will always
++	 * trap in kernel code, this means no priviledge change,
++	 * and so the pt_regs structure is not completely valid.  In a non
++	 * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
++	 * SS and ESP are not stacked, this means that the last 2 elements of
++	 * pt_regs is not valid (they would normally refer to the user stack)
++	 * also, using regs+1 is no good because you end up will a value that is
++	 * 2 longs (8) too high.  This used to cause stepping over functions
++	 * to fail, so my fix is to use the address of regs->esp, which
++	 * should point at the end of the stack frame.	Note I have ignored
++	 * completely exceptions that cause an error code to be stacked, such
++	 * as double fault.  Stuart Hughes, Zentropix.
++	 * original code: gdb_regs[_ESP] =  (int) (regs + 1) ;
++
++	 * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
++	 */
++	gdb_regs[_ESP] = NEW_esp;
++	gdb_regs[_SS] = __KERNEL_DS;
++	gdb_regs[_FS] = 0xFFFF;
++	gdb_regs[_GS] = 0xFFFF;
++}				/* regs_to_gdb_regs */
++
++static void
++gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
++{
++	regs->eax = gdb_regs[_EAX];
++	regs->ebx = gdb_regs[_EBX];
++	regs->ecx = gdb_regs[_ECX];
++	regs->edx = gdb_regs[_EDX];
++	regs->esi = gdb_regs[_ESI];
++	regs->edi = gdb_regs[_EDI];
++	regs->ebp = gdb_regs[_EBP];
++	regs->xds = gdb_regs[_DS];
++	regs->xes = gdb_regs[_ES];
++	regs->eflags = gdb_regs[_PS];
++	regs->xcs = gdb_regs[_CS];
++	regs->eip = gdb_regs[_PC];
++	NEW_esp = gdb_regs[_ESP];	/* keep the value */
++#if 0				/* can't change these */
++	regs->esp = gdb_regs[_ESP];
++	regs->xss = gdb_regs[_SS];
++	regs->fs = gdb_regs[_FS];
++	regs->gs = gdb_regs[_GS];
++#endif
++
++}				/* gdb_regs_to_regs */
++extern void scheduling_functions_start_here(void);
++extern void scheduling_functions_end_here(void);
++#define first_sched	((unsigned long) scheduling_functions_start_here)
++#define last_sched	((unsigned long) scheduling_functions_end_here)
++
++int thread_list = 0;
++
++void
++get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
++{
++	unsigned long stack_page;
++	int count = 0;
++	IF_SMP(int i);
++	if (!p || p == current) {
++		regs_to_gdb_regs(gdb_regs, regs);
++		return;
++	}
++#ifdef CONFIG_SMP
++	for (i = 0; i < MAX_NO_CPUS; i++) {
++		if (p == kgdb_info.cpus_waiting[i].task) {
++			regs_to_gdb_regs(gdb_regs,
++					 kgdb_info.cpus_waiting[i].regs);
++			gdb_regs[_ESP] =
++			    (int) &kgdb_info.cpus_waiting[i].regs->esp;
++
++			return;
++		}
++	}
++#endif
++	memset(gdb_regs, 0, NUMREGBYTES);
++	gdb_regs[_ESP] = p->thread.esp;
++	gdb_regs[_PC] = p->thread.eip;
++	gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
++	gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
++	gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
++
++/*
++ * This code is to give a more informative notion of where a process
++ * is waiting.	It is used only when the user asks for a thread info
++ * list.  If he then switches to the thread, s/he will find the task
++ * is in schedule, but a back trace should show the same info we come
++ * up with.  This code was shamelessly purloined from process.c.  It was
++ * then enhanced to provide more registers than simply the program
++ * counter.
++ */
++
++	if (!thread_list) {
++		return;
++	}
++
++	if (p->state == TASK_RUNNING)
++		return;
++	stack_page = (unsigned long) p->thread_info;
++	if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
++		return;
++	/* include/asm-i386/system.h:switch_to() pushes ebp last. */
++	do {
++		if (gdb_regs[_EBP] < stack_page ||
++		    gdb_regs[_EBP] > 8184 + stack_page)
++			return;
++		gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
++		gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
++		gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
++		if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
++			return;
++	} while (count++ < 16);
++	return;
++}
++
++/* Indicate to caller of mem2hex or hex2mem that there has been an
++   error.  */
++static volatile int mem_err = 0;
++static volatile int mem_err_expected = 0;
++static volatile int mem_err_cnt = 0;
++static int garbage_loc = -1;
++
++int
++get_char(char *addr)
++{
++	return *addr;
++}
++
++void
++set_char(char *addr, int val, int may_fault)
++{
++	/*
++	 * This code traps references to the area mapped to the kernel
++	 * stack as given by the regs and, instead, stores to the
++	 * fn_call_lookaside[cpu].array
++	 */
++	if (may_fault &&
++	    (unsigned int) addr < OLD_esp &&
++	    ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
++		addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
++	}
++	*addr = val;
++}
++
++/* convert the memory pointed to by mem into hex, placing result in buf */
++/* return a pointer to the last char put in buf (null) */
++/* If MAY_FAULT is non-zero, then we should set mem_err in response to
++   a fault; if zero treat a fault like any other fault in the stub.  */
++char *
++mem2hex(char *mem, char *buf, int count, int may_fault)
++{
++	int i;
++	unsigned char ch;
++
++	if (may_fault) {
++		mem_err_expected = 1;
++		mem_err = 0;
++	}
++	for (i = 0; i < count; i++) {
++		/* printk("%lx = ", mem) ; */
++
++		ch = get_char(mem++);
++
++		/* printk("%02x\n", ch & 0xFF) ; */
++		if (may_fault && mem_err) {
++			if (remote_debug)
++				printk("Mem fault fetching from addr %lx\n",
++				       (long) (mem - 1));
++			*buf = 0;	/* truncate buffer */
++			return (buf);
++		}
++		*buf++ = hexchars[ch >> 4];
++		*buf++ = hexchars[ch % 16];
++	}
++	*buf = 0;
++	if (may_fault)
++		mem_err_expected = 0;
++	return (buf);
++}
++
++/* convert the hex array pointed to by buf into binary to be placed in mem */
++/* return a pointer to the character AFTER the last byte written */
++/* NOTE: We use the may fault flag to also indicate if the write is to
++ * the registers (0) or "other" memory (!=0)
++ */
++char *
++hex2mem(char *buf, char *mem, int count, int may_fault)
++{
++	int i;
++	unsigned char ch;
++
++	if (may_fault) {
++		mem_err_expected = 1;
++		mem_err = 0;
++	}
++	for (i = 0; i < count; i++) {
++		ch = hex(*buf++) << 4;
++		ch = ch + hex(*buf++);
++		set_char(mem++, ch, may_fault);
++
++		if (may_fault && mem_err) {
++			if (remote_debug)
++				printk("Mem fault storing to addr %lx\n",
++				       (long) (mem - 1));
++			return (mem);
++		}
++	}
++	if (may_fault)
++		mem_err_expected = 0;
++	return (mem);
++}
++
++/**********************************************/
++/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
++/* RETURN NUMBER OF CHARS PROCESSED	      */
++/**********************************************/
++int
++hexToInt(char **ptr, int *intValue)
++{
++	int numChars = 0;
++	int hexValue;
++
++	*intValue = 0;
++
++	while (**ptr) {
++		hexValue = hex(**ptr);
++		if (hexValue >= 0) {
++			*intValue = (*intValue << 4) | hexValue;
++			numChars++;
++		} else
++			break;
++
++		(*ptr)++;
++	}
++
++	return (numChars);
++}
++
++#define stubhex(h) hex(h)
++#ifdef old_thread_list
++
++static int
++stub_unpack_int(char *buff, int fieldlength)
++{
++	int nibble;
++	int retval = 0;
++
++	while (fieldlength) {
++		nibble = stubhex(*buff++);
++		retval |= nibble;
++		fieldlength--;
++		if (fieldlength)
++			retval = retval << 4;
++	}
++	return retval;
++}
++#endif
++static char *
++pack_hex_byte(char *pkt, int byte)
++{
++	*pkt++ = hexchars[(byte >> 4) & 0xf];
++	*pkt++ = hexchars[(byte & 0xf)];
++	return pkt;
++}
++
++#define BUF_THREAD_ID_SIZE 16
++
++static char *
++pack_threadid(char *pkt, threadref * id)
++{
++	char *limit;
++	unsigned char *altid;
++
++	altid = (unsigned char *) id;
++	limit = pkt + BUF_THREAD_ID_SIZE;
++	while (pkt < limit)
++		pkt = pack_hex_byte(pkt, *altid++);
++	return pkt;
++}
++
++#ifdef old_thread_list
++static char *
++unpack_byte(char *buf, int *value)
++{
++	*value = stub_unpack_int(buf, 2);
++	return buf + 2;
++}
++
++static char *
++unpack_threadid(char *inbuf, threadref * id)
++{
++	char *altref;
++	char *limit = inbuf + BUF_THREAD_ID_SIZE;
++	int x, y;
++
++	altref = (char *) id;
++
++	while (inbuf < limit) {
++		x = stubhex(*inbuf++);
++		y = stubhex(*inbuf++);
++		*altref++ = (x << 4) | y;
++	}
++	return inbuf;
++}
++#endif
++void
++int_to_threadref(threadref * id, int value)
++{
++	unsigned char *scan;
++
++	scan = (unsigned char *) id;
++	{
++		int i = 4;
++		while (i--)
++			*scan++ = 0;
++	}
++	*scan++ = (value >> 24) & 0xff;
++	*scan++ = (value >> 16) & 0xff;
++	*scan++ = (value >> 8) & 0xff;
++	*scan++ = (value & 0xff);
++}
++int
++int_to_hex_v(unsigned char * id, int value)
++{
++	unsigned char *start = id;
++	int shift;
++	int ch;
++
++	for (shift = 28; shift >= 0; shift -= 4) {
++		if ((ch = (value >> shift) & 0xf) || (id != start)) {
++			*id = hexchars[ch];
++			id++;
++		}
++	}
++	if (id == start)
++		*id++ = '0';
++	return id - start;
++}
++#ifdef old_thread_list
++
++static int
++threadref_to_int(threadref * ref)
++{
++	int i, value = 0;
++	unsigned char *scan;
++
++	scan = (char *) ref;
++	scan += 4;
++	i = 4;
++	while (i-- > 0)
++		value = (value << 8) | ((*scan++) & 0xff);
++	return value;
++}
++#endif
++static int
++cmp_str(char *s1, char *s2, int count)
++{
++	while (count--) {
++		if (*s1++ != *s2++)
++			return 0;
++	}
++	return 1;
++}
++
++#if 1				/* this is a hold over from 2.4 where O(1) was "sometimes" */
++extern struct task_struct *kgdb_get_idle(int cpu);
++#define idle_task(cpu) kgdb_get_idle(cpu)
++#else
++#define idle_task(cpu) init_tasks[cpu]
++#endif
++
++extern int kgdb_pid_init_done;
++
++struct task_struct *
++getthread(int pid)
++{
++	struct task_struct *thread;
++	if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
++
++		return idle_task(pid - PID_MAX);
++	} else {
++		/*
++		 * find_task_by_pid is relatively safe all the time
++		 * Other pid functions require lock downs which imply
++		 * that we may be interrupting them (as we get here
++		 * in the middle of most any lock down).
++		 * Still we don't want to call until the table exists!
++		 */
++		if (kgdb_pid_init_done){
++			thread = find_task_by_pid(pid);
++			if (thread) {
++				return thread;
++			}
++		}
++	}
++	return NULL;
++}
++/* *INDENT-OFF*	 */
++struct hw_breakpoint {
++	unsigned enabled;
++	unsigned type;
++	unsigned len;
++	unsigned addr;
++} breakinfo[4] = { {enabled:0},
++		   {enabled:0},
++		   {enabled:0},
++		   {enabled:0}};
++/* *INDENT-ON*	*/
++unsigned hw_breakpoint_status;
++void
++correct_hw_break(void)
++{
++	int breakno;
++	int correctit;
++	int breakbit;
++	unsigned dr7;
++
++	asm volatile ("movl %%db7, %0\n":"=r" (dr7)
++		      :);
++	/* *INDENT-OFF*	 */
++	do {
++		unsigned addr0, addr1, addr2, addr3;
++		asm volatile ("movl %%db0, %0\n"
++			      "movl %%db1, %1\n"
++			      "movl %%db2, %2\n"
++			      "movl %%db3, %3\n"
++			      :"=r" (addr0), "=r"(addr1),
++			      "=r"(addr2), "=r"(addr3)
++			      :);
++	} while (0);
++	/* *INDENT-ON*	*/
++	correctit = 0;
++	for (breakno = 0; breakno < 3; breakno++) {
++		breakbit = 2 << (breakno << 1);
++		if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
++			correctit = 1;
++			dr7 |= breakbit;
++			dr7 &= ~(0xf0000 << (breakno << 2));
++			dr7 |= (((breakinfo[breakno].len << 2) |
++				 breakinfo[breakno].type) << 16) <<
++			    (breakno << 2);
++			switch (breakno) {
++			case 0:
++				asm volatile ("movl %0, %%dr0\n"::"r"
++					      (breakinfo[breakno].addr));
++				break;
++
++			case 1:
++				asm volatile ("movl %0, %%dr1\n"::"r"
++					      (breakinfo[breakno].addr));
++				break;
++
++			case 2:
++				asm volatile ("movl %0, %%dr2\n"::"r"
++					      (breakinfo[breakno].addr));
++				break;
++
++			case 3:
++				asm volatile ("movl %0, %%dr3\n"::"r"
++					      (breakinfo[breakno].addr));
++				break;
++			}
++		} else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
++			correctit = 1;
++			dr7 &= ~breakbit;
++			dr7 &= ~(0xf0000 << (breakno << 2));
++		}
++	}
++	if (correctit) {
++		asm volatile ("movl %0, %%db7\n"::"r" (dr7));
++	}
++}
++
++int
++remove_hw_break(unsigned breakno)
++{
++	if (!breakinfo[breakno].enabled) {
++		return -1;
++	}
++	breakinfo[breakno].enabled = 0;
++	return 0;
++}
++
++int
++set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
++{
++	if (breakinfo[breakno].enabled) {
++		return -1;
++	}
++	breakinfo[breakno].enabled = 1;
++	breakinfo[breakno].type = type;
++	breakinfo[breakno].len = len;
++	breakinfo[breakno].addr = addr;
++	return 0;
++}
++
++#ifdef CONFIG_SMP
++static int in_kgdb_console = 0;
++
++int
++in_kgdb(struct pt_regs *regs)
++{
++	unsigned flags;
++	int cpu = smp_processor_id();
++	in_kgdb_called = 1;
++	if (!spin_is_locked(&kgdb_spinlock)) {
++		if (in_kgdb_here_log[cpu] ||	/* we are holding this cpu */
++		    in_kgdb_console) {	/* or we are doing slow i/o */
++			return 1;
++		}
++		return 0;
++	}
++
++	/* As I see it the only reason not to let all cpus spin on
++	 * the same spin_lock is to allow selected ones to proceed.
++	 * This would be a good thing, so we leave it this way.
++	 * Maybe someday....  Done !
++
++	 * in_kgdb() is called from an NMI so we don't pretend
++	 * to have any resources, like printk() for example.
++	 */
++
++	kgdb_local_irq_save(flags);	/* only local here, to avoid hanging */
++	/*
++	 * log arival of this cpu
++	 * The NMI keeps on ticking.  Protect against recurring more
++	 * than once, and ignor the cpu that has the kgdb lock
++	 */
++	in_kgdb_entry_log[cpu]++;
++	in_kgdb_here_log[cpu] = regs;
++	if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
++		goto exit_in_kgdb;
++	}
++	/*
++	 * For protection of the initilization of the spin locks by kgdb
++	 * it locks the kgdb spinlock before it gets the wait locks set
++	 * up.	We wait here for the wait lock to be taken.  If the
++	 * kgdb lock goes away first??	Well, it could be a slow exit
++	 * sequence where the wait lock is removed prior to the kgdb lock
++	 * so if kgdb gets unlocked, we just exit.
++	 */
++	while (spin_is_locked(&kgdb_spinlock) &&
++	       !spin_is_locked(waitlocks + cpu)) ;
++	if (!spin_is_locked(&kgdb_spinlock)) {
++		goto exit_in_kgdb;
++	}
++	waiting_cpus[cpu].task = current;
++	waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
++	waiting_cpus[cpu].regs = regs;
++
++	spin_unlock_wait(waitlocks + cpu);
++	/*
++	 * log departure of this cpu
++	 */
++	waiting_cpus[cpu].task = 0;
++	waiting_cpus[cpu].pid = 0;
++	waiting_cpus[cpu].regs = 0;
++	correct_hw_break();
++      exit_in_kgdb:
++	in_kgdb_here_log[cpu] = 0;
++	kgdb_local_irq_restore(flags);
++	return 1;
++	/*
++	   spin_unlock(continuelocks + smp_processor_id());
++	 */
++}
++
++void
++smp__in_kgdb(struct pt_regs regs)
++{
++	ack_APIC_irq();
++	in_kgdb(&regs);
++}
++#else
++int
++in_kgdb(struct pt_regs *regs)
++{
++	return (kgdb_spinlock);
++}
++#endif
++
++void
++printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
++{
++	unsigned dr6;
++	int i;
++	switch (exceptionNo) {
++	case 1:		/* debug exception */
++		break;
++	case 3:		/* breakpoint */
++		sprintf(buffer, "Software breakpoint");
++		return;
++	default:
++		sprintf(buffer, "Details not available");
++		return;
++	}
++	asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++		      :);
++	if (dr6 & 0x4000) {
++		sprintf(buffer, "Single step");
++		return;
++	}
++	for (i = 0; i < 4; ++i) {
++		if (dr6 & (1 << i)) {
++			sprintf(buffer, "Hardware breakpoint %d", i);
++			return;
++		}
++	}
++	sprintf(buffer, "Unknown trap");
++	return;
++}
++
++/*
++ * This function does all command procesing for interfacing to gdb.
++ *
++ * NOTE:  The INT nn instruction leaves the state of the interrupt
++ *	  enable flag UNCHANGED.  That means that when this routine
++ *	  is entered via a breakpoint (INT 3) instruction from code
++ *	  that has interrupts enabled, then interrupts will STILL BE
++ *	  enabled when this routine is entered.	 The first thing that
++ *	  we do here is disable interrupts so as to prevent recursive
++ *	  entries and bothersome serial interrupts while we are
++ *	  trying to run the serial port in polled mode.
++ *
++ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
++ * it is always necessary to do a restore_flags before returning
++ * so as to let go of that lock.
++ */
++int
++kgdb_handle_exception(int exceptionVector,
++		      int signo, int err_code, struct pt_regs *linux_regs)
++{
++	struct task_struct *usethread = NULL;
++	struct task_struct *thread_list_start = 0, *thread = NULL;
++	int addr, length;
++	unsigned long address;
++	int breakno, breaktype;
++	char *ptr;
++	int newPC;
++	threadref thref;
++	int threadid;
++	int thread_min = PID_MAX + MAX_NO_CPUS;
++#ifdef old_thread_list
++	int maxthreads;
++#endif
++	int nothreads;
++	unsigned long flags;
++	int gdb_regs[NUMREGBYTES / 4];
++	int dr6;
++	IF_SMP(int entry_state = 0);	/* 0, ok, 1, no nmi, 2 sync failed */
++#define NO_NMI 1
++#define NO_SYNC 2
++#define	regs	(*linux_regs)
++#define NUMREGS NUMREGBYTES/4
++	/*
++	 * If the entry is not from the kernel then return to the Linux
++	 * trap handler and let it process the interrupt normally.
++	 */
++	if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
++		printk("ignoring non-kernel exception\n");
++		print_regs(&regs);
++		return (0);
++	}
++	/*
++	 * If we're using eth mode, set the 'mode' in the netdevice.
++	 */
++
++	__asm__("movl %%cr2,%0":"=r" (address));
++
++	if (kgdb_eth != -1) {
++		kgdb_eth_set_trapmode(1);
++	}
++
++	kgdb_local_irq_save(flags);
++
++	/* Get kgdb spinlock */
++
++	KGDB_SPIN_LOCK(&kgdb_spinlock);
++	rdtscll(kgdb_info.entry_tsc);
++	/*
++	 * We depend on this spinlock and the NMI watch dog to control the
++	 * other cpus.	They will arrive at "in_kgdb()" as a result of the
++	 * NMI and will wait there for the following spin locks to be
++	 * released.
++	 */
++#ifdef CONFIG_SMP
++
++#if 0
++	if (cpu_callout_map & ~MAX_CPU_MASK) {
++		printk("kgdb : too many cpus, possibly not mapped"
++		       " in contiguous space, change MAX_NO_CPUS"
++		       " in kgdb_stub and make new kernel.\n"
++		       " cpu_callout_map is %lx\n", cpu_callout_map);
++		goto exit_just_unlock;
++	}
++#endif
++	if (spinlock_count == 1) {
++		int time, end_time, dum;
++		int i;
++		int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
++		};
++		if (remote_debug) {
++			printk("kgdb : cpu %d entry, syncing others\n",
++			       smp_processor_id());
++		}
++		for (i = 0; i < MAX_NO_CPUS; i++) {
++			/*
++			 * Use trylock as we may already hold the lock if
++			 * we are holding the cpu.  Net result is all
++			 * locked.
++			 */
++			spin_trylock(&waitlocks[i]);
++		}
++		for (i = 0; i < MAX_NO_CPUS; i++)
++			cpu_logged_in[i] = 0;
++		/*
++		 * Wait for their arrival.  We know the watch dog is active if
++		 * in_kgdb() has ever been called, as it is always called on a
++		 * watchdog tick.
++		 */
++		rdtsc(dum, time);
++		end_time = time + 2;	/* Note: we use the High order bits! */
++		i = 1;
++		if (num_online_cpus() > 1) {
++			int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
++			smp_send_nmi_allbutself();
++			while (i < num_online_cpus() && time != end_time) {
++				int j;
++				for (j = 0; j < MAX_NO_CPUS; j++) {
++					if (waiting_cpus[j].task &&
++					    !cpu_logged_in[j]) {
++						i++;
++						cpu_logged_in[j] = 1;
++						if (remote_debug) {
++							printk
++							    ("kgdb : cpu %d arrived at kgdb\n",
++							     j);
++						}
++						break;
++					} else if (!waiting_cpus[j].task &&
++						   !cpu_online(j)) {
++						waiting_cpus[j].task = NOCPU;
++						cpu_logged_in[j] = 1;
++						waiting_cpus[j].hold = 1;
++						break;
++					}
++					if (!waiting_cpus[j].task &&
++					    in_kgdb_here_log[j]) {
++
++						int wait = 100000;
++						while (wait--) ;
++						if (!waiting_cpus[j].task &&
++						    in_kgdb_here_log[j]) {
++							printk
++							    ("kgdb : cpu %d stall"
++							     " in in_kgdb\n",
++							     j);
++							i++;
++							cpu_logged_in[j] = 1;
++							waiting_cpus[j].task =
++							    (struct task_struct
++							     *) 1;
++						}
++					}
++				}
++
++				if (in_kgdb_entry_log[smp_processor_id()] >
++				    (me_in_kgdb + 10)) {
++					break;
++				}
++
++				rdtsc(dum, time);
++			}
++			if (i < num_online_cpus()) {
++				printk
++				    ("kgdb : time out, proceeding without sync\n");
++#if 0
++				printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
++				       waiting_cpus[0].task != 0,
++				       waiting_cpus[1].task != 0);
++				printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
++				       cpu_logged_in[0], cpu_logged_in[1]);
++				printk
++				    ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
++				     in_kgdb_here_log[0] != 0,
++				     in_kgdb_here_log[1] != 0);
++#endif
++				entry_state = NO_SYNC;
++			} else {
++#if 0
++				int ent =
++				    in_kgdb_entry_log[smp_processor_id()] -
++				    me_in_kgdb;
++				printk("kgdb : sync after %d entries\n", ent);
++#endif
++			}
++		} else {
++			if (remote_debug) {
++				printk
++				    ("kgdb : %d cpus, but watchdog not active\n"
++				     "proceeding without locking down other cpus\n",
++				     num_online_cpus());
++				entry_state = NO_NMI;
++			}
++		}
++	}
++#endif
++
++	if (remote_debug) {
++		printk("handle_exception(exceptionVector=%d, "
++		       "signo=%d, err_code=%d, linux_regs=%p)\n",
++		       exceptionVector, signo, err_code, linux_regs);
++		printk(" address: %lx\n", address);
++
++		if (debug_regs) {
++			print_regs(&regs);
++			show_trace(current, (unsigned long *)&regs);
++		}
++	}
++
++	/* Disable hardware debugging while we are in kgdb */
++	/* Get the debug register status register */
++/*				       *INDENT-OFF*  */
++      __asm__("movl %0,%%db7"
++	      :	/* no output */
++	      :"r"(0));
++
++	asm volatile ("movl %%db6, %0\n"
++		      :"=r" (hw_breakpoint_status)
++		      :);
++
++/*				       *INDENT-ON*  */
++	switch (exceptionVector) {
++	case 0:		/* divide error */
++	case 1:		/* debug exception */
++	case 2:		/* NMI */
++	case 3:		/* breakpoint */
++	case 4:		/* overflow */
++	case 5:		/* bounds check */
++	case 6:		/* invalid opcode */
++	case 7:		/* device not available */
++	case 8:		/* double fault (errcode) */
++	case 10:		/* invalid TSS (errcode) */
++	case 12:		/* stack fault (errcode) */
++	case 16:		/* floating point error */
++	case 17:		/* alignment check (errcode) */
++	default:		/* any undocumented */
++		break;
++	case 11:		/* segment not present (errcode) */
++	case 13:		/* general protection (errcode) */
++	case 14:		/* page fault (special errcode) */
++	case 19:		/* cache flush denied */
++		if (mem_err_expected) {
++			/*
++			 * This fault occured because of the
++			 * get_char or set_char routines.  These
++			 * two routines use either eax of edx to
++			 * indirectly reference the location in
++			 * memory that they are working with.
++			 * For a page fault, when we return the
++			 * instruction will be retried, so we
++			 * have to make sure that these
++			 * registers point to valid memory.
++			 */
++			mem_err = 1;	/* set mem error flag */
++			mem_err_expected = 0;
++			mem_err_cnt++;	/* helps in debugging */
++			/* make valid address */
++			regs.eax = (long) &garbage_loc;
++			/* make valid address */
++			regs.edx = (long) &garbage_loc;
++			if (remote_debug)
++				printk("Return after memory error: "
++				       "mem_err_cnt=%d\n", mem_err_cnt);
++			if (debug_regs)
++				print_regs(&regs);
++			goto exit_kgdb;
++		}
++		break;
++	}
++	if (remote_debug)
++		printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
++
++	gdb_i386vector = exceptionVector;
++	gdb_i386errcode = err_code;
++	kgdb_info.called_from = __builtin_return_address(0);
++#ifdef CONFIG_SMP
++	/*
++	 * OK, we can now communicate, lets tell gdb about the sync.
++	 * but only if we had a problem.
++	 */
++	switch (entry_state) {
++	case NO_NMI:
++		to_gdb("NMI not active, other cpus not stopped\n");
++		break;
++	case NO_SYNC:
++		to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
++	default:;
++	}
++
++#endif
++/*
++ * Set up the gdb function call area.
++ */
++	trap_cpu = smp_processor_id();
++	OLD_esp = NEW_esp = (int) (&linux_regs->esp);
++
++      IF_SMP(once_again:)
++	    /* reply to host that an exception has occurred */
++	    remcomOutBuffer[0] = 'S';
++	remcomOutBuffer[1] = hexchars[signo >> 4];
++	remcomOutBuffer[2] = hexchars[signo % 16];
++	remcomOutBuffer[3] = 0;
++
++	if (kgdb_eth_is_initializing) {
++		kgdb_eth_is_initializing = 0;
++	} else {
++		putpacket(remcomOutBuffer);
++	}
++
++	kgdb_eth_reply_arp();
++	while (1 == 1) {
++		error = 0;
++		remcomOutBuffer[0] = 0;
++		getpacket(remcomInBuffer);
++		switch (remcomInBuffer[0]) {
++		case '?':
++			remcomOutBuffer[0] = 'S';
++			remcomOutBuffer[1] = hexchars[signo >> 4];
++			remcomOutBuffer[2] = hexchars[signo % 16];
++			remcomOutBuffer[3] = 0;
++			break;
++		case 'd':
++			remote_debug = !(remote_debug);	/* toggle debug flag */
++			printk("Remote debug %s\n",
++			       remote_debug ? "on" : "off");
++			break;
++		case 'g':	/* return the value of the CPU registers */
++			get_gdb_regs(usethread, &regs, gdb_regs);
++			mem2hex((char *) gdb_regs,
++				remcomOutBuffer, NUMREGBYTES, 0);
++			break;
++		case 'G':	/* set the value of the CPU registers - return OK */
++			hex2mem(&remcomInBuffer[1],
++				(char *) gdb_regs, NUMREGBYTES, 0);
++			if (!usethread || usethread == current) {
++				gdb_regs_to_regs(gdb_regs, &regs);
++				strcpy(remcomOutBuffer, "OK");
++			} else {
++				strcpy(remcomOutBuffer, "E00");
++			}
++			break;
++
++		case 'P':{	/* set the value of a single CPU register -
++				   return OK */
++				/*
++				 * For some reason, gdb wants to talk about psudo
++				 * registers (greater than 15).	 These may have
++				 * meaning for ptrace, but for us it is safe to
++				 * ignor them.	We do this by dumping them into
++				 * _GS which we also ignor, but do have memory for.
++				 */
++				int regno;
++
++				ptr = &remcomInBuffer[1];
++				regs_to_gdb_regs(gdb_regs, &regs);
++				if ((!usethread || usethread == current) &&
++				    hexToInt(&ptr, &regno) &&
++				    *ptr++ == '=' && (regno >= 0)) {
++					regno =
++					    (regno >= NUMREGS ? _GS : regno);
++					hex2mem(ptr, (char *) &gdb_regs[regno],
++						4, 0);
++					gdb_regs_to_regs(gdb_regs, &regs);
++					strcpy(remcomOutBuffer, "OK");
++					break;
++				}
++				strcpy(remcomOutBuffer, "E01");
++				break;
++			}
++
++			/* mAA..AA,LLLL	 Read LLLL bytes at address AA..AA */
++		case 'm':
++			/* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
++			ptr = &remcomInBuffer[1];
++			if (hexToInt(&ptr, &addr) &&
++			    (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
++				ptr = 0;
++				/*
++				 * hex doubles the byte count
++				 */
++				if (length > (BUFMAX / 2))
++					length = BUFMAX / 2;
++				mem2hex((char *) addr,
++					remcomOutBuffer, length, 1);
++				if (mem_err) {
++					strcpy(remcomOutBuffer, "E03");
++					debug_error("memory fault\n", NULL);
++				}
++			}
++
++			if (ptr) {
++				strcpy(remcomOutBuffer, "E01");
++				debug_error
++				    ("malformed read memory command: %s\n",
++				     remcomInBuffer);
++			}
++			break;
++
++			/* MAA..AA,LLLL:
++			   Write LLLL bytes at address AA.AA return OK */
++		case 'M':
++			/* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
++			ptr = &remcomInBuffer[1];
++			if (hexToInt(&ptr, &addr) &&
++			    (*(ptr++) == ',') &&
++			    (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
++				hex2mem(ptr, (char *) addr, length, 1);
++
++				if (mem_err) {
++					strcpy(remcomOutBuffer, "E03");
++					debug_error("memory fault\n", NULL);
++				} else {
++					strcpy(remcomOutBuffer, "OK");
++				}
++
++				ptr = 0;
++			}
++			if (ptr) {
++				strcpy(remcomOutBuffer, "E02");
++				debug_error
++				    ("malformed write memory command: %s\n",
++				     remcomInBuffer);
++			}
++			break;
++		case 'S':
++			remcomInBuffer[0] = 's';
++		case 'C':
++			/* Csig;AA..AA where ;AA..AA is optional
++			 * continue with signal
++			 * Since signals are meaning less to us, delete that
++			 * part and then fall into the 'c' code.
++			 */
++			ptr = &remcomInBuffer[1];
++			length = 2;
++			while (*ptr && *ptr != ';') {
++				length++;
++				ptr++;
++			}
++			if (*ptr) {
++				do {
++					ptr++;
++					*(ptr - length++) = *ptr;
++				} while (*ptr);
++			} else {
++				remcomInBuffer[1] = 0;
++			}
++
++			/* cAA..AA  Continue at address AA..AA(optional) */
++			/* sAA..AA  Step one instruction from AA..AA(optional) */
++			/* D	    detach, reply OK and then continue */
++		case 'c':
++		case 's':
++		case 'D':
++
++			/* try to read optional parameter,
++			   pc unchanged if no parm */
++			ptr = &remcomInBuffer[1];
++			if (hexToInt(&ptr, &addr)) {
++				if (remote_debug)
++					printk("Changing EIP to 0x%x\n", addr);
++
++				regs.eip = addr;
++			}
++
++			newPC = regs.eip;
++
++			if (kgdb_eth != -1) {
++				kgdb_eth_set_trapmode(0);
++			}
++
++			/* clear the trace bit */
++			regs.eflags &= 0xfffffeff;
++
++			/* set the trace bit if we're stepping */
++			if (remcomInBuffer[0] == 's')
++				regs.eflags |= 0x100;
++
++			/* detach is a friendly version of continue. Note that
++			   debugging is still enabled (e.g hit control C)
++			 */
++			if (remcomInBuffer[0] == 'D') {
++				strcpy(remcomOutBuffer, "OK");
++				putpacket(remcomOutBuffer);
++			}
++
++			if (remote_debug) {
++				printk("Resuming execution\n");
++				print_regs(&regs);
++			}
++			asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++				      :);
++			if (!(dr6 & 0x4000)) {
++				for (breakno = 0; breakno < 4; ++breakno) {
++					if (dr6 & (1 << breakno) &&
++					    (breakinfo[breakno].type == 0)) {
++						/* Set restore flag */
++						regs.eflags |= 0x10000;
++						break;
++					}
++				}
++			}
++			correct_hw_break();
++			asm volatile ("movl %0, %%db6\n"::"r" (0));
++			goto exit_kgdb;
++
++			/* kill the program */
++		case 'k':	/* do nothing */
++			break;
++
++			/* query */
++		case 'q':
++			nothreads = 0;
++			switch (remcomInBuffer[1]) {
++			case 'f':
++				threadid = 1;
++				thread_list = 2;
++				thread_list_start = (usethread ? : current);
++			case 's':
++				if (!cmp_str(&remcomInBuffer[2],
++					     "ThreadInfo", 10))
++					break;
++
++				remcomOutBuffer[nothreads++] = 'm';
++				for (; threadid < PID_MAX + MAX_NO_CPUS;
++				     threadid++) {
++					thread = getthread(threadid);
++					if (thread) {
++						nothreads += int_to_hex_v(
++							&remcomOutBuffer[
++								nothreads],
++							threadid);
++						if (thread_min > threadid)
++							thread_min = threadid;
++						remcomOutBuffer[
++							nothreads] = ',';
++						nothreads++;
++						if (nothreads > BUFMAX - 10)
++							break;
++					}
++				}
++				if (remcomOutBuffer[nothreads - 1] == 'm') {
++					remcomOutBuffer[nothreads - 1] = 'l';
++				} else {
++					nothreads--;
++				}
++				remcomOutBuffer[nothreads] = 0;
++				break;
++
++#ifdef old_thread_list /* Old thread info request */
++			case 'L':
++				/* List threads */
++				thread_list = 2;
++				thread_list_start = (usethread ? : current);
++				unpack_byte(remcomInBuffer + 3, &maxthreads);
++				unpack_threadid(remcomInBuffer + 5, &thref);
++				do {
++					int buf_thread_limit =
++					    (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
++					if (maxthreads > buf_thread_limit) {
++						maxthreads = buf_thread_limit;
++					}
++				} while (0);
++				remcomOutBuffer[0] = 'q';
++				remcomOutBuffer[1] = 'M';
++				remcomOutBuffer[4] = '0';
++				pack_threadid(remcomOutBuffer + 5, &thref);
++
++				threadid = threadref_to_int(&thref);
++				for (nothreads = 0;
++				     nothreads < maxthreads &&
++				     threadid < PID_MAX + MAX_NO_CPUS;
++				     threadid++) {
++					thread = getthread(threadid);
++					if (thread) {
++						int_to_threadref(&thref,
++								 threadid);
++						pack_threadid(remcomOutBuffer +
++							      21 +
++							      nothreads * 16,
++							      &thref);
++						nothreads++;
++						if (thread_min > threadid)
++							thread_min = threadid;
++					}
++				}
++
++				if (threadid == PID_MAX + MAX_NO_CPUS) {
++					remcomOutBuffer[4] = '1';
++				}
++				pack_hex_byte(remcomOutBuffer + 2, nothreads);
++				remcomOutBuffer[21 + nothreads * 16] = '\0';
++				break;
++#endif
++			case 'C':
++				/* Current thread id */
++				remcomOutBuffer[0] = 'Q';
++				remcomOutBuffer[1] = 'C';
++				threadid = current->pid;
++				if (!threadid) {
++					/*
++					 * idle thread
++					 */
++					for (threadid = PID_MAX;
++					     threadid < PID_MAX + MAX_NO_CPUS;
++					     threadid++) {
++						if (current ==
++						    idle_task(threadid -
++							      PID_MAX))
++							break;
++					}
++				}
++				int_to_threadref(&thref, threadid);
++				pack_threadid(remcomOutBuffer + 2, &thref);
++				remcomOutBuffer[18] = '\0';
++				break;
++
++			case 'E':
++				/* Print exception info */
++				printexceptioninfo(exceptionVector,
++						   err_code, remcomOutBuffer);
++				break;
++			case 'T':{
++				char * nptr;
++				/* Thread extra info */
++				if (!cmp_str(&remcomInBuffer[2],
++					    "hreadExtraInfo,", 15)) {
++					break;
++				}
++				ptr = &remcomInBuffer[17];
++				hexToInt(&ptr, &threadid);
++				thread = getthread(threadid);
++				nptr = &thread->comm[0];
++				length = 0;
++				ptr = &remcomOutBuffer[0];
++				do {
++					length++;
++					ptr = pack_hex_byte(ptr, *nptr++);
++				 } while (*nptr && length < 16);
++				/*
++				 * would like that 16 to be the size of
++				 * task_struct.comm but don't know the
++				 * syntax..
++				 */
++				*ptr = 0;
++			}
++			}
++			break;
++
++			/* task related */
++		case 'H':
++			switch (remcomInBuffer[1]) {
++			case 'g':
++				ptr = &remcomInBuffer[2];
++				hexToInt(&ptr, &threadid);
++				thread = getthread(threadid);
++				if (!thread) {
++					remcomOutBuffer[0] = 'E';
++					remcomOutBuffer[1] = '\0';
++					break;
++				}
++				/*
++				 * Just in case I forget what this is all about,
++				 * the "thread info" command to gdb causes it
++				 * to ask for a thread list.  It then switches
++				 * to each thread and asks for the registers.
++				 * For this (and only this) usage, we want to
++				 * fudge the registers of tasks not on the run
++				 * list (i.e. waiting) to show the routine that
++				 * called schedule. Also, gdb, is a minimalist
++				 * in that if the current thread is the last
++				 * it will not re-read the info when done.
++				 * This means that in this case we must show
++				 * the real registers. So here is how we do it:
++				 * Each entry we keep track of the min
++				 * thread in the list (the last that gdb will)
++				 * get info for.  We also keep track of the
++				 * starting thread.
++				 * "thread_list" is cleared when switching back
++				 * to the min thread if it is was current, or
++				 * if it was not current, thread_list is set
++				 * to 1.  When the switch to current comes,
++				 * if thread_list is 1, clear it, else do
++				 * nothing.
++				 */
++				usethread = thread;
++				if ((thread_list == 1) &&
++				    (thread == thread_list_start)) {
++					thread_list = 0;
++				}
++				if (thread_list && (threadid == thread_min)) {
++					if (thread == thread_list_start) {
++						thread_list = 0;
++					} else {
++						thread_list = 1;
++					}
++				}
++				/* follow through */
++			case 'c':
++				remcomOutBuffer[0] = 'O';
++				remcomOutBuffer[1] = 'K';
++				remcomOutBuffer[2] = '\0';
++				break;
++			}
++			break;
++
++			/* Query thread status */
++		case 'T':
++			ptr = &remcomInBuffer[1];
++			hexToInt(&ptr, &threadid);
++			thread = getthread(threadid);
++			if (thread) {
++				remcomOutBuffer[0] = 'O';
++				remcomOutBuffer[1] = 'K';
++				remcomOutBuffer[2] = '\0';
++				if (thread_min > threadid)
++					thread_min = threadid;
++			} else {
++				remcomOutBuffer[0] = 'E';
++				remcomOutBuffer[1] = '\0';
++			}
++			break;
++
++		case 'Y': /* set up a hardware breakpoint */
++			ptr = &remcomInBuffer[1];
++			hexToInt(&ptr, &breakno);
++			ptr++;
++			hexToInt(&ptr, &breaktype);
++			ptr++;
++			hexToInt(&ptr, &length);
++			ptr++;
++			hexToInt(&ptr, &addr);
++			if (set_hw_break(breakno & 0x3,
++					 breaktype & 0x3,
++					 length & 0x3, addr) == 0) {
++				strcpy(remcomOutBuffer, "OK");
++			} else {
++				strcpy(remcomOutBuffer, "ERROR");
++			}
++			break;
++
++			/* Remove hardware breakpoint */
++		case 'y':
++			ptr = &remcomInBuffer[1];
++			hexToInt(&ptr, &breakno);
++			if (remove_hw_break(breakno & 0x3) == 0) {
++				strcpy(remcomOutBuffer, "OK");
++			} else {
++				strcpy(remcomOutBuffer, "ERROR");
++			}
++			break;
++
++		case 'r':	/* reboot */
++			strcpy(remcomOutBuffer, "OK");
++			putpacket(remcomOutBuffer);
++			/*to_gdb("Rebooting\n"); */
++			/* triplefault	 no return from here */
++			{
++				static long no_idt[2];
++				__asm__ __volatile__("lidt %0"::"m"(no_idt[0]));
++				BREAKPOINT;
++			}
++
++		}		/* switch */
++
++		/* reply to the request */
++		putpacket(remcomOutBuffer);
++	}			/* while(1==1) */
++	/*
++	 *  reached by goto only.
++	 */
++      exit_kgdb:
++	/*
++	 * Here is where we set up to trap a gdb function call.	 NEW_esp
++	 * will be changed if we are trying to do this.	 We handle both
++	 * adding and subtracting, thus allowing gdb to put grung on
++	 * the stack which it removes later.
++	 */
++	if (NEW_esp != OLD_esp) {
++		int *ptr = END_OF_LOOKASIDE;
++		if (NEW_esp < OLD_esp)
++			ptr -= (OLD_esp - NEW_esp) / sizeof (int);
++		*--ptr = linux_regs->eflags;
++		*--ptr = linux_regs->xcs;
++		*--ptr = linux_regs->eip;
++		*--ptr = linux_regs->ecx;
++		*--ptr = linux_regs->ebx;
++		*--ptr = linux_regs->eax;
++		linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
++		linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
++		if (NEW_esp < OLD_esp) {
++			linux_regs->eip = (unsigned int) fn_call_stub;
++		} else {
++			linux_regs->eip = (unsigned int) fn_rtn_stub;
++			linux_regs->eax = NEW_esp;
++		}
++		linux_regs->eflags &= ~(IF_BIT | TF_BIT);
++	}
++#ifdef CONFIG_SMP
++	/*
++	 * Release gdb wait locks
++	 * Sanity check time.  Must have at least one cpu to run.  Also single
++	 * step must not be done if the current cpu is on hold.
++	 */
++	if (spinlock_count == 1) {
++		int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
++		int cpu_avail = 0;
++		int i;
++
++		for (i = 0; i < MAX_NO_CPUS; i++) {
++			if (!cpu_online(i))
++				break;
++			if (!hold_cpu(i)) {
++				cpu_avail = 1;
++			}
++		}
++		/*
++		 * Early in the bring up there will be NO cpus on line...
++		 */
++		if (!cpu_avail && !cpus_empty(cpu_online_map)) {
++			to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
++			goto once_again;
++		}
++		if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
++			to_gdb
++			    ("Current cpu must be unblocked to single step\n");
++			goto once_again;
++		}
++		if (!(ss_hold)) {
++			int i;
++			for (i = 0; i < MAX_NO_CPUS; i++) {
++				if (!hold_cpu(i)) {
++					spin_unlock(&waitlocks[i]);
++				}
++			}
++		} else {
++			spin_unlock(&waitlocks[smp_processor_id()]);
++		}
++		/* Release kgdb spinlock */
++		KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++		/*
++		 * If this cpu is on hold, this is where we
++		 * do it.  Note, the NMI will pull us out of here,
++		 * but will return as the above lock is not held.
++		 * We will stay here till another cpu releases the lock for us.
++		 */
++		spin_unlock_wait(waitlocks + smp_processor_id());
++		kgdb_local_irq_restore(flags);
++		return (0);
++	}
++#if 0
++exit_just_unlock:
++#endif
++#endif
++	/* Release kgdb spinlock */
++	KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++	kgdb_local_irq_restore(flags);
++	return (0);
++}
++
++/* this function is used to set up exception handlers for tracing and
++ * breakpoints.
++ * This function is not needed as the above line does all that is needed.
++ * We leave it for backward compatitability...
++ */
++void
++set_debug_traps(void)
++{
++	/*
++	 * linux_debug_hook is defined in traps.c.  We store a pointer
++	 * to our own exception handler into it.
++
++	 * But really folks, every hear of labeled common, an old Fortran
++	 * concept.  Lots of folks can reference it and it is define if
++	 * anyone does.	 Only one can initialize it at link time.  We do
++	 * this with the hook.	See the statement above.  No need for any
++	 * executable code and it is ready as soon as the kernel is
++	 * loaded.  Very desirable in kernel debugging.
++
++	 linux_debug_hook = handle_exception ;
++	 */
++
++	/* In case GDB is started before us, ack any packets (presumably
++	   "$?#xx") sitting there.
++	   putDebugChar ('+');
++
++	   initialized = 1;
++	 */
++}
++
++/* This function will generate a breakpoint exception.	It is used at the
++   beginning of a program to sync up with a debugger and can be used
++   otherwise as a quick means to stop program execution and "break" into
++   the debugger. */
++/* But really, just use the BREAKPOINT macro.  We will handle the int stuff
++ */
++
++#ifdef later
++/*
++ * possibly we should not go thru the traps.c code at all?  Someday.
++ */
++void
++do_kgdb_int3(struct pt_regs *regs, long error_code)
++{
++	kgdb_handle_exception(3, 5, error_code, regs);
++	return;
++}
++#endif
++#undef regs
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++asmlinkage void
++bad_sys_call_exit(int stuff)
++{
++	struct pt_regs *regs = (struct pt_regs *) &stuff;
++	printk("Sys call %d return with %x preempt_count\n",
++	       (int) regs->orig_eax, preempt_count());
++}
++#endif
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#include <asm/kgdb.h>
++asmlinkage void
++stack_overflow(void)
++{
++#ifdef BREAKPOINT
++	BREAKPOINT;
++#else
++	printk("Kernel stack overflow, looping forever\n");
++#endif
++	while (1) {
++	}
++}
++#endif
++
++#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
++char gdbconbuf[BUFMAX];
++
++static void
++kgdb_gdb_message(const char *s, unsigned count)
++{
++	int i;
++	int wcount;
++	char *bufptr;
++	/*
++	 * This takes care of NMI while spining out chars to gdb
++	 */
++	IF_SMP(in_kgdb_console = 1);
++	gdbconbuf[0] = 'O';
++	bufptr = gdbconbuf + 1;
++	while (count > 0) {
++		if ((count << 1) > (BUFMAX - 2)) {
++			wcount = (BUFMAX - 2) >> 1;
++		} else {
++			wcount = count;
++		}
++		count -= wcount;
++		for (i = 0; i < wcount; i++) {
++			bufptr = pack_hex_byte(bufptr, s[i]);
++		}
++		*bufptr = '\0';
++		s += wcount;
++
++		putpacket(gdbconbuf);
++
++	}
++	IF_SMP(in_kgdb_console = 0);
++}
++#endif
++#ifdef CONFIG_SMP
++static void
++to_gdb(const char *s)
++{
++	int count = 0;
++	while (s[count] && (count++ < BUFMAX)) ;
++	kgdb_gdb_message(s, count);
++}
++#endif
++#ifdef CONFIG_KGDB_CONSOLE
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++void
++kgdb_console_write(struct console *co, const char *s, unsigned count)
++{
++
++	if (gdb_i386vector == -1) {
++		/*
++		 * We have not yet talked to gdb.  What to do...
++		 * lets break, on continue we can do the write.
++		 * But first tell him whats up. Uh, well no can do,
++		 * as this IS the console.  Oh well...
++		 * We do need to wait or the messages will be lost.
++		 * Other option would be to tell the above code to
++		 * ignore this breakpoint and do an auto return,
++		 * but that might confuse gdb.	Also this happens
++		 * early enough in boot up that we don't have the traps
++		 * set up yet, so...
++		 */
++		breakpoint();
++	}
++	kgdb_gdb_message(s, count);
++}
++
++/*
++ * ------------------------------------------------------------
++ * Serial KGDB driver
++ * ------------------------------------------------------------
++ */
++
++static struct console kgdbcons = {
++	name:"kgdb",
++	write:kgdb_console_write,
++#ifdef CONFIG_KGDB_USER_CONSOLE
++	device:kgdb_console_device,
++#endif
++	flags:CON_PRINTBUFFER | CON_ENABLED,
++	index:-1,
++};
++
++/*
++ * The trick here is that this file gets linked before printk.o
++ * That means we get to peer at the console info in the command
++ * line before it does.	 If we are up, we register, otherwise,
++ * do nothing.	By returning 0, we allow printk to look also.
++ */
++static int kgdb_console_enabled;
++
++int __init
++kgdb_console_init(char *str)
++{
++	if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
++		register_console(&kgdbcons);
++		kgdb_console_enabled = 1;
++	}
++	return 0;		/* let others look at the string */
++}
++
++__setup("console=", kgdb_console_init);
++
++#ifdef CONFIG_KGDB_USER_CONSOLE
++static kdev_t kgdb_console_device(struct console *c);
++/* This stuff sort of works, but it knocks out telnet devices
++ * we are leaving it here in case we (or you) find time to figure it out
++ * better..
++ */
++
++/*
++ * We need a real char device as well for when the console is opened for user
++ * space activities.
++ */
++
++static int
++kgdb_consdev_open(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++static ssize_t
++kgdb_consdev_write(struct file *file, const char *buf,
++		   size_t count, loff_t * ppos)
++{
++	int size, ret = 0;
++	static char kbuf[128];
++	static DECLARE_MUTEX(sem);
++
++	/* We are not reentrant... */
++	if (down_interruptible(&sem))
++		return -ERESTARTSYS;
++
++	while (count > 0) {
++		/* need to copy the data from user space */
++		size = count;
++		if (size > sizeof (kbuf))
++			size = sizeof (kbuf);
++		if (copy_from_user(kbuf, buf, size)) {
++			ret = -EFAULT;
++			break;;
++		}
++		kgdb_console_write(&kgdbcons, kbuf, size);
++		count -= size;
++		ret += size;
++		buf += size;
++	}
++
++	up(&sem);
++
++	return ret;
++}
++
++struct file_operations kgdb_consdev_fops = {
++	open:kgdb_consdev_open,
++	write:kgdb_consdev_write
++};
++static kdev_t
++kgdb_console_device(struct console *c)
++{
++	return MKDEV(TTYAUX_MAJOR, 1);
++}
++
++/*
++ * This routine gets called from the serial stub in the i386/lib
++ * This is so it is done late in bring up (just before the console open).
++ */
++void
++kgdb_console_finit(void)
++{
++	if (kgdb_console_enabled) {
++		char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
++		char *cp = cptr;
++		while (*cptr && *cptr != '(')
++			cptr++;
++		*cptr = 0;
++		unregister_chrdev(TTYAUX_MAJOR, cp);
++		register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
++	}
++}
++#endif
++#endif
++#ifdef CONFIG_KGDB_TS
++#include <asm/msr.h>		/* time stamp code */
++#include <asm/hardirq.h>	/* in_interrupt */
++#ifdef CONFIG_KGDB_TS_64
++#define DATA_POINTS 64
++#endif
++#ifdef CONFIG_KGDB_TS_128
++#define DATA_POINTS 128
++#endif
++#ifdef CONFIG_KGDB_TS_256
++#define DATA_POINTS 256
++#endif
++#ifdef CONFIG_KGDB_TS_512
++#define DATA_POINTS 512
++#endif
++#ifdef CONFIG_KGDB_TS_1024
++#define DATA_POINTS 1024
++#endif
++#ifndef DATA_POINTS
++#define DATA_POINTS 128		/* must be a power of two */
++#endif
++#define INDEX_MASK (DATA_POINTS - 1)
++#if (INDEX_MASK & DATA_POINTS)
++#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
++#endif
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++	int on_cpu;
++#endif
++	struct task_struct *task;
++	long long at_time;
++	int from_ln;
++	char *in_src;
++	void *from;
++	int *with_shpf;
++	int data0;
++	int data1;
++};
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++	int on_cpu;
++#endif
++	struct task_struct *task;
++	long long at_time;
++	int from_ln;
++	char *in_src;
++	void *from;
++	int *with_shpf;
++	struct task_struct *t1;
++	struct task_struct *t2;
++};
++struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
++
++struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
++int kgdb_and_then_count;
++
++void
++kgdb_tstamp(int line, char *source, int data0, int data1)
++{
++	static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
++	int flags;
++	kgdb_local_irq_save(flags);
++	spin_lock(&ts_spin);
++	rdtscll(kgdb_and_then->at_time);
++#ifdef CONFIG_SMP
++	kgdb_and_then->on_cpu = smp_processor_id();
++#endif
++	kgdb_and_then->task = current;
++	kgdb_and_then->from_ln = line;
++	kgdb_and_then->in_src = source;
++	kgdb_and_then->from = __builtin_return_address(0);
++	kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
++					    (preempt_count() << 8));
++	kgdb_and_then->data0 = data0;
++	kgdb_and_then->data1 = data1;
++	kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
++	spin_unlock(&ts_spin);
++	kgdb_local_irq_restore(flags);
++#ifdef CONFIG_PREEMPT
++
++#endif
++	return;
++}
++#endif
++typedef int gdb_debug_hook(int exceptionVector,
++			   int signo, int err_code, struct pt_regs *linux_regs);
++gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;	/* histerical reasons... */
++
++static int __init kgdb_opt_kgdbeth(char *str)
++{
++	kgdb_eth = simple_strtoul(str, NULL, 10);
++	return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_remoteip(char *str)
++{
++	kgdb_remoteip = in_aton(str);
++	return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_listenport(char *str)
++{
++	kgdb_listenport = simple_strtoul(str, NULL, 10);
++	kgdb_sendport = kgdb_listenport - 1;
++	return 1;
++}
++
++static int __init parse_hw_addr(char *str, unsigned char *addr)
++{
++	int  i;
++	char *p;
++
++	p = str;
++	i = 0;
++	while(1)
++	{
++		unsigned int c;
++
++		sscanf(p, "%x:", &c);
++		addr[i++] = c;
++		while((*p != 0) && (*p != ':')) {
++			p++;
++		}
++		if (*p == 0) {
++			break;
++		}
++		p++;
++	}
++
++	return 1;
++}
++
++static int __init kgdb_opt_kgdbeth_remotemac(char *str)
++{
++	return parse_hw_addr(str, kgdb_remotemac);
++}
++static int __init kgdb_opt_kgdbeth_localmac(char *str)
++{
++	return parse_hw_addr(str, kgdb_localmac);
++}
++
++
++__setup("gdbeth=", kgdb_opt_kgdbeth);
++__setup("gdbeth_remoteip=", kgdb_opt_kgdbeth_remoteip);
++__setup("gdbeth_listenport=", kgdb_opt_kgdbeth_listenport);
++__setup("gdbeth_remotemac=", kgdb_opt_kgdbeth_remotemac);
++__setup("gdbeth_localmac=", kgdb_opt_kgdbeth_localmac);
++
+--- linux-2.6.0-test6/arch/i386/kernel/ldt.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/ldt.c	2003-10-05 00:36:48.000000000 -0700
+@@ -2,7 +2,7 @@
+  * linux/kernel/ldt.c
+  *
+  * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
++ * Copyright (C) 1999, 2003 Ingo Molnar <mingo@redhat.com>
+  */
+ 
+ #include <linux/errno.h>
+@@ -18,6 +18,8 @@
+ #include <asm/system.h>
+ #include <asm/ldt.h>
+ #include <asm/desc.h>
++#include <linux/highmem.h>
++#include <asm/atomic_kmap.h>
+ 
+ #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+ static void flush_ldt(void *null)
+@@ -29,34 +31,31 @@ static void flush_ldt(void *null)
+ 
+ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+ {
+-	void *oldldt;
+-	void *newldt;
+-	int oldsize;
++	int oldsize, newsize, i;
+ 
+ 	if (mincount <= pc->size)
+ 		return 0;
++	/*
++	 * LDT got larger - reallocate if necessary.
++	 */
+ 	oldsize = pc->size;
+ 	mincount = (mincount+511)&(~511);
+-	if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+-		newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+-	else
+-		newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+-
+-	if (!newldt)
+-		return -ENOMEM;
+-
+-	if (oldsize)
+-		memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+-	oldldt = pc->ldt;
+-	memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+-	pc->ldt = newldt;
+-	wmb();
++	newsize = mincount*LDT_ENTRY_SIZE;
++	for (i = 0; i < newsize; i += PAGE_SIZE) {
++		int nr = i/PAGE_SIZE;
++		BUG_ON(i >= 64*1024);
++		if (!pc->ldt_pages[nr]) {
++			pc->ldt_pages[nr] = alloc_page(GFP_HIGHUSER);
++			if (!pc->ldt_pages[nr])
++				return -ENOMEM;
++			clear_highpage(pc->ldt_pages[nr]);
++		}
++	}
+ 	pc->size = mincount;
+-	wmb();
+-
+ 	if (reload) {
+ #ifdef CONFIG_SMP
+ 		cpumask_t mask;
++
+ 		preempt_disable();
+ 		load_LDT(pc);
+ 		mask = cpumask_of_cpu(smp_processor_id());
+@@ -67,21 +66,20 @@ static int alloc_ldt(mm_context_t *pc, i
+ 		load_LDT(pc);
+ #endif
+ 	}
+-	if (oldsize) {
+-		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+-			vfree(oldldt);
+-		else
+-			kfree(oldldt);
+-	}
+ 	return 0;
+ }
+ 
+ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+ {
+-	int err = alloc_ldt(new, old->size, 0);
+-	if (err < 0)
++	int i, err, size = old->size, nr_pages = (size*LDT_ENTRY_SIZE + PAGE_SIZE-1)/PAGE_SIZE;
++
++	err = alloc_ldt(new, size, 0);
++	if (err < 0) {
++		new->size = 0;
+ 		return err;
+-	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
++	}
++	for (i = 0; i < nr_pages; i++)
++		copy_user_highpage(new->ldt_pages[i], old->ldt_pages[i], 0);
+ 	return 0;
+ }
+ 
+@@ -96,6 +94,7 @@ int init_new_context(struct task_struct 
+ 
+ 	init_MUTEX(&mm->context.sem);
+ 	mm->context.size = 0;
++	memset(mm->context.ldt_pages, 0, sizeof(struct page *) * MAX_LDT_PAGES);
+ 	old_mm = current->mm;
+ 	if (old_mm && old_mm->context.size > 0) {
+ 		down(&old_mm->context.sem);
+@@ -107,23 +106,21 @@ int init_new_context(struct task_struct 
+ 
+ /*
+  * No need to lock the MM as we are the last user
++ * Do not touch the ldt register, we are already
++ * in the next thread.
+  */
+ void destroy_context(struct mm_struct *mm)
+ {
+-	if (mm->context.size) {
+-		if (mm == current->active_mm)
+-			clear_LDT();
+-		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+-			vfree(mm->context.ldt);
+-		else
+-			kfree(mm->context.ldt);
+-		mm->context.size = 0;
+-	}
++	int i, nr_pages = (mm->context.size*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++	for (i = 0; i < nr_pages; i++)
++		__free_page(mm->context.ldt_pages[i]);
++	mm->context.size = 0;
+ }
+ 
+ static int read_ldt(void __user * ptr, unsigned long bytecount)
+ {
+-	int err;
++	int err, i;
+ 	unsigned long size;
+ 	struct mm_struct * mm = current->mm;
+ 
+@@ -138,8 +135,25 @@ static int read_ldt(void __user * ptr, u
+ 		size = bytecount;
+ 
+ 	err = 0;
+-	if (copy_to_user(ptr, mm->context.ldt, size))
+-		err = -EFAULT;
++	/*
++	 * This is necessary just in case we got here straight from a
++	 * context-switch where the ptes were set but no tlb flush
++	 * was done yet. We rather avoid doing a TLB flush in the
++	 * context-switch path and do it here instead.
++	 */
++	__flush_tlb_global();
++
++	for (i = 0; i < size; i += PAGE_SIZE) {
++		int nr = i / PAGE_SIZE, bytes;
++		char *kaddr = kmap(mm->context.ldt_pages[nr]);
++
++		bytes = size - i;
++		if (bytes > PAGE_SIZE)
++			bytes = PAGE_SIZE;
++		if (copy_to_user(ptr + i, kaddr, size - i))
++			err = -EFAULT;
++		kunmap(mm->context.ldt_pages[nr]);
++	}
+ 	up(&mm->context.sem);
+ 	if (err < 0)
+ 		return err;
+@@ -158,7 +172,7 @@ static int read_default_ldt(void __user 
+ 
+ 	err = 0;
+ 	address = &default_ldt[0];
+-	size = 5*sizeof(struct desc_struct);
++	size = 5*LDT_ENTRY_SIZE;
+ 	if (size > bytecount)
+ 		size = bytecount;
+ 
+@@ -200,7 +214,15 @@ static int write_ldt(void __user * ptr, 
+ 			goto out_unlock;
+ 	}
+ 
+-	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
++	/*
++	 * No rescheduling allowed from this point to the install.
++	 *
++	 * We do a TLB flush for the same reason as in the read_ldt() path.
++	 */
++	preempt_disable();
++	__flush_tlb_global();
++	lp = (__u32 *) ((ldt_info.entry_number << 3) +
++			(char *) __kmap_atomic_vaddr(KM_LDT_PAGE0));
+ 
+    	/* Allow LDTs to be cleared by the user. */
+    	if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+@@ -221,6 +243,7 @@ install:
+ 	*lp	= entry_1;
+ 	*(lp+1)	= entry_2;
+ 	error = 0;
++	preempt_enable();
+ 
+ out_unlock:
+ 	up(&mm->context.sem);
+@@ -248,3 +271,26 @@ asmlinkage int sys_modify_ldt(int func, 
+ 	}
+ 	return ret;
+ }
++
++/*
++ * load one particular LDT into the current CPU
++ */
++void load_LDT_nolock(mm_context_t *pc, int cpu)
++{
++	struct page **pages = pc->ldt_pages;
++	int count = pc->size;
++	int nr_pages, i;
++
++	if (likely(!count)) {
++		pages = &default_ldt_page;
++		count = 5;
++	}
++       	nr_pages = (count*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++	for (i = 0; i < nr_pages; i++) {
++		__kunmap_atomic_type(KM_LDT_PAGE0 - i);
++		__kmap_atomic(pages[i], KM_LDT_PAGE0 - i);
++	}
++	set_ldt_desc(cpu, (void *)__kmap_atomic_vaddr(KM_LDT_PAGE0), count);
++	load_LDT_desc();
++}
+--- linux-2.6.0-test6/arch/i386/kernel/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/Makefile	2003-10-05 00:36:48.000000000 -0700
+@@ -7,13 +7,14 @@ extra-y := head.o init_task.o vmlinux.ld
+ obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+ 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
+ 		pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
+-		doublefault.o
++		doublefault.o efi.o efi_stub.o entry_trampoline.o
+ 
+ obj-y				+= cpu/
+ obj-y				+= timers/
+ obj-$(CONFIG_ACPI_BOOT)		+= acpi/
+ obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
+ obj-$(CONFIG_MCA)		+= mca.o
++obj-$(CONFIG_KGDB)		+= kgdb_stub.o
+ obj-$(CONFIG_X86_MSR)		+= msr.o
+ obj-$(CONFIG_X86_CPUID)		+= cpuid.o
+ obj-$(CONFIG_MICROCODE)		+= microcode.o
+--- linux-2.6.0-test6/arch/i386/kernel/mca.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/mca.c	2003-10-05 00:36:10.000000000 -0700
+@@ -132,7 +132,9 @@ struct resource mca_standard_resources[]
+ #define MCA_STANDARD_RESOURCES	(sizeof(mca_standard_resources)/sizeof(struct resource))
+ 
+ /**
+- *	mca_read_pos - read the POS registers into a memory buffer
++ *	mca_read_and_store_pos - read the POS registers into a memory buffer
++ *      @pos: a char pointer to 8 bytes, contains the POS register value on
++ *            successful return
+  *
+  *	Returns 1 if a card actually exists (i.e. the pos isn't
+  *	all 0xff) or 0 otherwise
+--- linux-2.6.0-test6/arch/i386/kernel/mpparse.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/mpparse.c	2003-10-05 00:36:48.000000000 -0700
+@@ -169,7 +169,7 @@ void __init MP_processor_info (struct mp
+ 
+ 	if (num_processors >= NR_CPUS) {
+ 		printk(KERN_WARNING "NR_CPUS limit of %i reached.  Cannot "
+-			"boot CPU(apicid 0x%d).\n", NR_CPUS, m->mpc_apicid);
++			"boot CPU(apicid 0x%x).\n", NR_CPUS, m->mpc_apicid);
+ 		return;
+ 	}
+ 	num_processors++;
+@@ -616,6 +616,31 @@ static inline void __init construct_defa
+ 	}
+ }
+ 
++#ifdef CONFIG_X86_IO_APIC
++/* irq_vector must be have an entry for all RTEs of all I/O APICs. */
++void __init alloc_irq_vector_array(void)
++{
++	int	total = 0;
++	int	idx;
++	union IO_APIC_reg_01	reg_01;
++
++	/* The I/O APIC fixmaps aren't inited yet, so use the first one. */
++	for (idx = 0; idx < nr_ioapics; idx++) {
++		set_fixmap_nocache(FIX_IO_APIC_BASE_0, mp_ioapics[idx].mpc_apicaddr);
++		reg_01.raw = io_apic_read(0, 1);
++		total += reg_01.bits.entries + 1;
++	}
++
++	/* Always alloc at least NR_IRQS vectors. */
++	nr_irqs = max(total, NR_IRQS);
++	irq_vector = (u8 *) alloc_bootmem(nr_irqs);
++	memset(irq_vector, 0, nr_irqs);
++	irq_vector[0] = FIRST_DEVICE_VECTOR;
++}
++#else
++void __init alloc_irq_vector_array(void) { }
++#endif /* CONFIG_X86_IO_APIC */
++
+ static struct intel_mp_floating *mpf_found;
+ 
+ /*
+@@ -633,6 +658,7 @@ void __init get_smp_config (void)
+ 	 */
+ 	if (acpi_lapic && acpi_ioapic) {
+ 		printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
++		alloc_irq_vector_array();
+ 		return;
+ 	}
+ 	else if (acpi_lapic)
+@@ -661,10 +687,11 @@ void __init get_smp_config (void)
+ 		 * Read the physical hardware table.  Anything here will
+ 		 * override the defaults.
+ 		 */
+-		if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
++		if (!smp_read_mpc((void *)phys_to_virt(mpf->mpf_physptr))) {
+ 			smp_found_config = 0;
+ 			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
+ 			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
++			alloc_irq_vector_array();
+ 			return;
+ 		}
+ 		/*
+@@ -688,6 +715,7 @@ void __init get_smp_config (void)
+ 	} else
+ 		BUG();
+ 
++	alloc_irq_vector_array();
+ 	printk(KERN_INFO "Processors: %d\n", num_processors);
+ 	/*
+ 	 * Only use the first configuration found.
+@@ -830,7 +858,7 @@ void __init mp_register_lapic (
+ 	MP_processor_info(&processor);
+ }
+ 
+-#ifdef CONFIG_X86_IO_APIC
++#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+ 
+ #define MP_ISA_BUS		0
+ #define MP_MAX_IOAPIC_PIN	127
+@@ -1019,10 +1047,6 @@ void __init mp_config_acpi_legacy_irqs (
+ 	}
+ }
+ 
+-#ifdef	CONFIG_ACPI
+-
+-/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+-
+ extern FADT_DESCRIPTOR acpi_fadt;
+ 
+ void __init mp_config_ioapic_for_sci(int irq)
+@@ -1031,6 +1055,7 @@ void __init mp_config_ioapic_for_sci(int
+ 	int ioapic_pin;
+ 	struct acpi_table_madt *madt;
+ 	struct acpi_table_int_src_ovr *entry = NULL;
++	acpi_interrupt_flags flags;
+ 	void *madt_end;
+ 	acpi_status status;
+ 
+@@ -1049,32 +1074,37 @@ void __init mp_config_ioapic_for_sci(int
+ 
+ 		while ((void *) entry < madt_end) {
+                 	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
+-			    acpi_fadt.sci_int == entry->bus_irq) {
+-				/*
+-				 * See the note at the end of ACPI 2.0b section
+-				 * 5.2.10.8 for what this is about.
+-				 */
+-				if (entry->bus_irq != entry->global_irq) {
+-					acpi_fadt.sci_int = entry->global_irq;
+-					irq = entry->global_irq;
+-					break;
+-				}
+-				else
+-                			return;
+-			}
+-
++			    acpi_fadt.sci_int == entry->bus_irq)
++				goto found;
++			
+                 	entry = (struct acpi_table_int_src_ovr *)
+                 	        ((unsigned long) entry + entry->header.length);
+         	}
+ 	}
++	/*
++	 * Although the ACPI spec says that the SCI should be level/low
++	 * don't reprogram it unless there is an explicit MADT OVR entry
++	 * instructing us to do so -- otherwise we break Tyan boards which
++	 * have the SCI wired edge/high but no MADT OVR.
++	 */
++	return;
++
++found:
++	/*
++	 * See the note at the end of ACPI 2.0b section
++	 * 5.2.10.8 for what this is about.
++	 */
++	flags = entry->flags;
++	acpi_fadt.sci_int = entry->global_irq;
++	irq = entry->global_irq;
+ 
+ 	ioapic = mp_find_ioapic(irq);
+ 
+ 	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+ 
+-	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
++	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
++				(flags.trigger >> 1) , (flags.polarity >> 1));
+ }
+-#endif	/* CONFIG_ACPI */
+ 
+ #ifdef CONFIG_ACPI_PCI
+ 
+@@ -1110,8 +1140,10 @@ void __init mp_parse_prt (void)
+ 		}
+ 
+ 		/* Don't set up the ACPI SCI because it's already set up */
+-		if (acpi_fadt.sci_int == irq)
++                if (acpi_fadt.sci_int == irq) {
++                        entry->irq = irq; /*we still need to set entry's irq*/
+ 			continue;
++                }
+ 	
+ 		ioapic = mp_find_ioapic(irq);
+ 		if (ioapic < 0)
+@@ -1136,15 +1168,19 @@ void __init mp_parse_prt (void)
+ 		if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+ 			printk(KERN_DEBUG "Pin %d-%d already programmed\n",
+ 				mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+-			entry->irq = irq;
++ 			if (use_pci_vector() && !platform_legacy_irq(irq))
++ 				irq = IO_APIC_VECTOR(irq);
++ 			entry->irq = irq;
+ 			continue;
+ 		}
+ 
+ 		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+ 
+-		if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low))
+-			entry->irq = irq;
+-
++		if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) {
++ 			if (use_pci_vector() && !platform_legacy_irq(irq))
++ 				irq = IO_APIC_VECTOR(irq);
++ 			entry->irq = irq;
++ 		}
+ 		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
+ 			entry->id.segment, entry->id.bus, 
+ 			entry->id.device, ('A' + entry->pin), 
+@@ -1154,5 +1190,5 @@ void __init mp_parse_prt (void)
+ }
+ 
+ #endif /*CONFIG_ACPI_PCI*/
+-#endif	/* CONFIG_X86_IO_APIC */
++#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
+ #endif /*CONFIG_ACPI_BOOT*/
+--- linux-2.6.0-test6/arch/i386/kernel/nmi.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/kernel/nmi.c	2003-10-05 00:33:38.000000000 -0700
+@@ -31,7 +31,16 @@
+ #include <asm/mpspec.h>
+ #include <asm/nmi.h>
+ 
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#ifdef CONFIG_SMP
++unsigned int nmi_watchdog = NMI_IO_APIC;
++#else
++unsigned int nmi_watchdog = NMI_LOCAL_APIC;
++#endif
++#else
+ unsigned int nmi_watchdog = NMI_NONE;
++#endif
+ static unsigned int nmi_hz = HZ;
+ unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
+ extern void show_registers(struct pt_regs *regs);
+@@ -408,6 +417,9 @@ void touch_nmi_watchdog (void)
+ 	for (i = 0; i < NR_CPUS; i++)
+ 		alert_counter[i] = 0;
+ }
++#ifdef CONFIG_KGDB
++int tune_watchdog = 5*HZ;
++#endif
+ 
+ void nmi_watchdog_tick (struct pt_regs * regs)
+ {
+@@ -421,12 +433,24 @@ void nmi_watchdog_tick (struct pt_regs *
+ 
+ 	sum = irq_stat[cpu].apic_timer_irqs;
+ 
++#ifdef CONFIG_KGDB
++ 	if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
++
++#else
+ 	if (last_irq_sums[cpu] == sum) {
++#endif
+ 		/*
+ 		 * Ayiee, looks like this CPU is stuck ...
+ 		 * wait a few IRQs (5 seconds) before doing the oops ...
+ 		 */
+ 		alert_counter[cpu]++;
++#ifdef CONFIG_KGDB
++                if (alert_counter[cpu] == tune_watchdog) {
++                        kgdb_handle_exception(2, SIGPWR, 0, regs);
++                        last_irq_sums[cpu] = sum;
++                        alert_counter[cpu] = 0;
++                }
++#endif
+ 		if (alert_counter[cpu] == 5*nmi_hz) {
+ 			spin_lock(&nmi_print_lock);
+ 			/*
+--- linux-2.6.0-test6/arch/i386/kernel/process.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/process.c	2003-10-05 00:36:48.000000000 -0700
+@@ -47,6 +47,7 @@
+ #include <asm/i387.h>
+ #include <asm/irq.h>
+ #include <asm/desc.h>
++#include <asm/atomic_kmap.h>
+ #ifdef CONFIG_MATH_EMULATION
+ #include <asm/math_emu.h>
+ #endif
+@@ -298,6 +299,9 @@ void flush_thread(void)
+ 	struct task_struct *tsk = current;
+ 
+ 	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
++#ifdef CONFIG_X86_HIGH_ENTRY
++	clear_thread_flag(TIF_DB7);
++#endif
+ 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
+ 	/*
+ 	 * Forget coprocessor state..
+@@ -311,9 +315,8 @@ void release_thread(struct task_struct *
+ 	if (dead_task->mm) {
+ 		// temporary debugging check
+ 		if (dead_task->mm->context.size) {
+-			printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
++			printk("WARNING: dead process %8s still has LDT? <%d>\n",
+ 					dead_task->comm,
+-					dead_task->mm->context.ldt,
+ 					dead_task->mm->context.size);
+ 			BUG();
+ 		}
+@@ -348,7 +351,17 @@ int copy_thread(int nr, unsigned long cl
+ 	p->thread.esp = (unsigned long) childregs;
+ 	p->thread.esp0 = (unsigned long) (childregs+1);
+ 
++	/*
++	 * get the two stack pages, for the virtual stack.
++	 *
++	 * IMPORTANT: this code relies on the fact that the task
++	 * structure is an 8K aligned piece of physical memory.
++	 */
++	p->thread.stack_page0 = virt_to_page((unsigned long)p->thread_info);
++	p->thread.stack_page1 = virt_to_page((unsigned long)p->thread_info + PAGE_SIZE);
++
+ 	p->thread.eip = (unsigned long) ret_from_fork;
++	p->thread_info->real_stack = p->thread_info;
+ 
+ 	savesegment(fs,p->thread.fs);
+ 	savesegment(gs,p->thread.gs);
+@@ -500,10 +513,40 @@ struct task_struct * __switch_to(struct 
+ 
+ 	__unlazy_fpu(prev_p);
+ 
++#ifdef CONFIG_X86_HIGH_ENTRY
++	/*
++	 * Set the ptes of the virtual stack. (NOTE: a one-page TLB flush is
++	 * needed because otherwise NMIs could interrupt the
++	 * user-return code with a virtual stack and stale TLBs.)
++	 */
++	__kunmap_atomic_type(KM_VSTACK0);
++	__kunmap_atomic_type(KM_VSTACK1);
++	__kmap_atomic(next->stack_page0, KM_VSTACK0);
++	__kmap_atomic(next->stack_page1, KM_VSTACK1);
++
++	/*
++	 * NOTE: here we rely on the task being the stack as well
++	 */
++	next_p->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++	/*
++	 * If next was preempted on entry from userspace to kernel,
++	 * and now it's on a different cpu, we need to adjust %esp.
++	 * This assumes that entry.S does not copy %esp while on the
++	 * virtual stack (with interrupts enabled): which is so,
++	 * except within __SWITCH_KERNELSPACE itself.
++	 */
++	if (unlikely(next->esp >= TASK_SIZE)) {
++		next->esp &= THREAD_SIZE - 1;
++		next->esp |= (unsigned long) next_p->thread_info->virtual_stack;
++	}
++#endif
++#endif
+ 	/*
+-	 * Reload esp0, LDT and the page table pointer:
++	 * Reload esp0:
+ 	 */
+-	load_esp0(tss, next->esp0);
++	load_esp0(tss, virtual_esp0(next_p));
+ 
+ 	/*
+ 	 * Load the per-thread Thread-Local Storage descriptor.
+--- linux-2.6.0-test6/arch/i386/kernel/reboot.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/reboot.c	2003-10-05 00:36:48.000000000 -0700
+@@ -7,6 +7,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/mc146818rtc.h>
++#include <linux/efi.h>
+ #include <asm/uaccess.h>
+ #include <asm/apic.h>
+ #include "mach_reboot.h"
+@@ -153,12 +154,11 @@ void machine_real_restart(unsigned char 
+ 	CMOS_WRITE(0x00, 0x8f);
+ 	spin_unlock_irqrestore(&rtc_lock, flags);
+ 
+-	/* Remap the kernel at virtual address zero, as well as offset zero
+-	   from the kernel segment.  This assumes the kernel segment starts at
+-	   virtual address PAGE_OFFSET. */
+-
+-	memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
+-		sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
++	/*
++	 * Remap the first 16 MB of RAM (which includes the kernel image)
++	 * at virtual address zero:
++	 */
++	setup_identity_mappings(swapper_pg_dir, 0, 16*1024*1024);
+ 
+ 	/*
+ 	 * Use `swapper_pg_dir' as our page directory.
+@@ -262,7 +262,12 @@ void machine_restart(char * __unused)
+ 	disable_IO_APIC();
+ #endif
+ 
+-	if(!reboot_thru_bios) {
++	if (!reboot_thru_bios) {
++		if (efi_enabled) {
++			efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, 0);
++			__asm__ __volatile__("lidt %0": :"m" (no_idt));
++			__asm__ __volatile__("int3");
++		}
+ 		/* rebooting needs to touch the page at absolute addr 0 */
+ 		*((unsigned short *)__va(0x472)) = reboot_mode;
+ 		for (;;) {
+@@ -272,6 +277,8 @@ void machine_restart(char * __unused)
+ 			__asm__ __volatile__("int3");
+ 		}
+ 	}
++	if (efi_enabled)
++		efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, 0);
+ 
+ 	machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
+ }
+@@ -282,6 +289,8 @@ void machine_halt(void)
+ 
+ void machine_power_off(void)
+ {
++	if (efi_enabled)
++		efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, 0);
+ 	if (pm_power_off)
+ 		pm_power_off();
+ }
+--- linux-2.6.0-test6/arch/i386/kernel/setup.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/setup.c	2003-10-05 00:36:22.000000000 -0700
+@@ -36,6 +36,8 @@
+ #include <linux/root_dev.h>
+ #include <linux/highmem.h>
+ #include <linux/module.h>
++#include <linux/efi.h>
++#include <linux/init.h>
+ #include <video/edid.h>
+ #include <asm/e820.h>
+ #include <asm/mpspec.h>
+@@ -56,6 +58,8 @@ static inline char * __init machine_spec
+  * Machine setup..
+  */
+ 
++int efi_enabled = 0;
++
+ /* cpu data as detected by the assembly code in head.S */
+ struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+ /* common cpu data for all cpus */
+@@ -64,10 +68,10 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 
+ unsigned long mmu_cr4_features;
+ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+ 
+-#ifdef	CONFIG_ACPI
+-	int acpi_disabled __initdata = 0;
++#ifdef	CONFIG_ACPI_INTERPRETER
++	int acpi_disabled = 0;
+ #else
+-	int acpi_disabled __initdata = 1;
++	int acpi_disabled = 1;
+ #endif
+ EXPORT_SYMBOL(acpi_disabled);
+ 
+@@ -144,6 +148,20 @@ static void __init limit_regions (unsign
+ 	int i;
+ 	unsigned long long current_size = 0;
+ 
++	if (efi_enabled) {
++		for (i = 0; i < memmap.nr_map; i++) {
++			current_size = memmap.map[i].phys_addr +
++				       (memmap.map[i].num_pages << 12);
++			if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) {
++				if (current_size > size) {
++					memmap.map[i].num_pages -=
++						(((current_size-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
++					memmap.nr_map = i + 1;
++					return;
++				}
++			}
++		}
++	}
+ 	for (i = 0; i < e820.nr_map; i++) {
+ 		if (e820.map[i].type == E820_RAM) {
+ 			current_size += e820.map[i].size;
+@@ -158,17 +176,21 @@ static void __init limit_regions (unsign
+ static void __init add_memory_region(unsigned long long start,
+                                   unsigned long long size, int type)
+ {
+-	int x = e820.nr_map;
++	int x;
+ 
+-	if (x == E820MAX) {
+-	    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+-	    return;
+-	}
++	if (!efi_enabled) {
++       		x = e820.nr_map;
+ 
+-	e820.map[x].addr = start;
+-	e820.map[x].size = size;
+-	e820.map[x].type = type;
+-	e820.nr_map++;
++		if (x == E820MAX) {
++		    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
++		    return;
++		}
++
++		e820.map[x].addr = start;
++		e820.map[x].size = size;
++		e820.map[x].type = type;
++		e820.nr_map++;
++	}
+ } /* add_memory_region */
+ 
+ #define E820_DEBUG	1
+@@ -445,7 +467,6 @@ static inline void copy_edd(void)
+ static void __init setup_memory_region(void)
+ {
+ 	char *who = machine_specific_memory_setup();
+-
+ 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
+ 	print_memory_map(who);
+ } /* setup_memory_region */
+@@ -583,6 +604,23 @@ static void __init parse_cmdline_early (
+ }
+ 
+ /*
++ * Callback for efi_memory_walk.
++ */
++static int __init
++efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
++{
++	unsigned long *max_pfn = arg, pfn;
++
++	if (start < end) {
++		pfn = PFN_UP(end -1);
++		if (pfn > *max_pfn)
++			*max_pfn = pfn;
++	}
++	return 0;
++}
++
++
++/*
+  * Find the highest page frame number we have available
+  */
+ void __init find_max_pfn(void)
+@@ -590,6 +628,11 @@ void __init find_max_pfn(void)
+ 	int i;
+ 
+ 	max_pfn = 0;
++	if (efi_enabled) {
++		efi_memmap_walk(efi_find_max_pfn, &max_pfn);
++		return;
++	}
++
+ 	for (i = 0; i < e820.nr_map; i++) {
+ 		unsigned long start, end;
+ 		/* RAM? */
+@@ -664,6 +707,25 @@ unsigned long __init find_max_low_pfn(vo
+ }
+ 
+ #ifndef CONFIG_DISCONTIGMEM
++
++/*
++ * Free all available memory for boot time allocation.  Used
++ * as a callback function by efi_memory_walk()
++ */
++
++static int __init
++free_available_memory(unsigned long start, unsigned long end, void *arg)
++{
++	/* check max_low_pfn */
++	if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
++		return 0;
++	if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
++		end = (max_low_pfn + 1) << PAGE_SHIFT;
++	if (start < end)
++		free_bootmem(start, end - start);
++
++	return 0;
++}
+ /*
+  * Register fully available low RAM pages with the bootmem allocator.
+  */
+@@ -671,6 +733,10 @@ static void __init register_bootmem_low_
+ {
+ 	int i;
+ 
++	if (efi_enabled) {
++		efi_memmap_walk(free_available_memory, NULL);
++		return;
++	}
+ 	for (i = 0; i < e820.nr_map; i++) {
+ 		unsigned long curr_pfn, last_pfn, size;
+ 		/*
+@@ -798,9 +864,9 @@ extern unsigned long setup_memory(void);
+  * Request address space for all standard RAM and ROM resources
+  * and also for regions reported as reserved by the e820.
+  */
+-static void __init register_memory(unsigned long max_low_pfn)
++static void __init
++legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+ {
+-	unsigned long low_mem_size;
+ 	int i;
+ 
+ 	probe_roms();
+@@ -825,11 +891,26 @@ static void __init register_memory(unsig
+ 			 *  so we try it repeatedly and let the resource manager
+ 			 *  test it.
+ 			 */
+-			request_resource(res, &code_resource);
+-			request_resource(res, &data_resource);
++			request_resource(res, code_resource);
++			request_resource(res, data_resource);
+ 		}
+ 	}
++}
++
++/*
++ * Request address space for all standard resources
++ */
++static void __init register_memory(unsigned long max_low_pfn)
++{
++	unsigned long low_mem_size;
++	int i;
+ 
++	if (efi_enabled)
++		efi_initialize_iomem_resources(&code_resource, &data_resource);
++	else
++		legacy_init_iomem_resources(&code_resource, &data_resource);
++
++ 	 /* EFI systems may still have VGA */
+ 	request_graphics_resource();
+ 
+ 	/* request I/O space for devices used on all i[345]86 PCs */
+@@ -949,6 +1030,13 @@ static int __init noreplacement_setup(ch
+ 
+ __setup("noreplacement", noreplacement_setup); 
+ 
++/*
++ * Determine if we were loaded by an EFI loader.  If so, then we have also been
++ * passed the efi memmap, systab, etc., so we should use these data structures
++ * for initialization.  Note, the efi init code path is determined by the
++ * global efi_enabled. This allows the same kernel image to be used on existing
++ * systems (with a traditional BIOS) as well as on EFI systems.
++ */
+ void __init setup_arch(char **cmdline_p)
+ {
+ 	unsigned long max_low_pfn;
+@@ -957,6 +1045,12 @@ void __init setup_arch(char **cmdline_p)
+ 	pre_setup_arch_hook();
+ 	early_cpu_init();
+ 
++	/* FIXME: This isn't an official loader_type right
++	 * now but does currently work with elilo.
++	 */
++	if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
++		efi_enabled = 1;
++
+  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+  	drive_info = DRIVE_INFO;
+  	screen_info = SCREEN_INFO;
+@@ -979,7 +1073,11 @@ void __init setup_arch(char **cmdline_p)
+ 	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+ #endif
+ 	ARCH_SETUP
+-	setup_memory_region();
++	if (efi_enabled)
++		efi_init();
++	else
++		setup_memory_region();
++
+ 	copy_edd();
+ 
+ 	if (!MOUNT_ROOT_RDONLY)
+@@ -1013,6 +1111,8 @@ void __init setup_arch(char **cmdline_p)
+ #ifdef CONFIG_X86_GENERICARCH
+ 	generic_apic_probe(*cmdline_p);
+ #endif	
++	if (efi_enabled)
++		efi_map_memmap();
+ 
+ 	/*
+ 	 * Parse the ACPI tables for possible boot-time SMP configuration.
+@@ -1028,7 +1128,8 @@ void __init setup_arch(char **cmdline_p)
+ 
+ #ifdef CONFIG_VT
+ #if defined(CONFIG_VGA_CONSOLE)
+-	conswitchp = &vga_con;
++	if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
++		conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+ 	conswitchp = &dummy_con;
+ #endif
+--- linux-2.6.0-test6/arch/i386/kernel/signal.c	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/i386/kernel/signal.c	2003-10-05 00:36:48.000000000 -0700
+@@ -128,25 +128,25 @@ sys_sigaltstack(const stack_t __user *us
+  */
+ 
+ static int
+-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax)
++restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *__sc, int *peax)
+ {
+-	unsigned int err = 0;
++	struct sigcontext scratch; /* 88 bytes of scratch area */
+ 
+-#define COPY(x)		err |= __get_user(regs->x, &sc->x)
++	if (copy_from_user(&scratch, __sc, sizeof(scratch)))
++		return -EFAULT;
++
++#define COPY(x)		regs->x = scratch.x
+ 
+ #define COPY_SEG(seg)							\
+-	{ unsigned short tmp;						\
+-	  err |= __get_user(tmp, &sc->seg);				\
++	{ unsigned short tmp = scratch.seg;				\
+ 	  regs->x##seg = tmp; }
+ 
+ #define COPY_SEG_STRICT(seg)						\
+-	{ unsigned short tmp;						\
+-	  err |= __get_user(tmp, &sc->seg);				\
++	{ unsigned short tmp = scratch.seg;				\
+ 	  regs->x##seg = tmp|3; }
+ 
+ #define GET_SEG(seg)							\
+-	{ unsigned short tmp;						\
+-	  err |= __get_user(tmp, &sc->seg);				\
++	{ unsigned short tmp = scratch.seg;				\
+ 	  loadsegment(seg,tmp); }
+ 
+ 	GET_SEG(gs);
+@@ -165,27 +165,23 @@ restore_sigcontext(struct pt_regs *regs,
+ 	COPY_SEG_STRICT(ss);
+ 	
+ 	{
+-		unsigned int tmpflags;
+-		err |= __get_user(tmpflags, &sc->eflags);
++		unsigned int tmpflags = scratch.eflags;
+ 		regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
+ 		regs->orig_eax = -1;		/* disable syscall checks */
+ 	}
+ 
+ 	{
+-		struct _fpstate __user * buf;
+-		err |= __get_user(buf, &sc->fpstate);
++		struct _fpstate * buf = scratch.fpstate;
+ 		if (buf) {
+ 			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
+-				goto badframe;
+-			err |= restore_i387(buf);
++				return -EFAULT;
++			if (restore_i387(buf))
++				return -EFAULT;
+ 		}
+ 	}
+ 
+-	err |= __get_user(*peax, &sc->eax);
+-	return err;
+-
+-badframe:
+-	return 1;
++	*peax = scratch.eax;
++	return 0;
+ }
+ 
+ asmlinkage int sys_sigreturn(unsigned long __unused)
+@@ -263,46 +259,47 @@ badframe:
+  */
+ 
+ static int
+-setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
++setup_sigcontext(struct sigcontext __user *__sc, struct _fpstate __user *fpstate,
+ 		 struct pt_regs *regs, unsigned long mask)
+ {
+-	int tmp, err = 0;
++	struct sigcontext sc; /* 88 bytes of scratch area */
++	int tmp;
+ 
+ 	tmp = 0;
+ 	__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
+-	err |= __put_user(tmp, (unsigned int *)&sc->gs);
++	*(unsigned int *)&sc.gs = tmp;
+ 	__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
+-	err |= __put_user(tmp, (unsigned int *)&sc->fs);
+-
+-	err |= __put_user(regs->xes, (unsigned int *)&sc->es);
+-	err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
+-	err |= __put_user(regs->edi, &sc->edi);
+-	err |= __put_user(regs->esi, &sc->esi);
+-	err |= __put_user(regs->ebp, &sc->ebp);
+-	err |= __put_user(regs->esp, &sc->esp);
+-	err |= __put_user(regs->ebx, &sc->ebx);
+-	err |= __put_user(regs->edx, &sc->edx);
+-	err |= __put_user(regs->ecx, &sc->ecx);
+-	err |= __put_user(regs->eax, &sc->eax);
+-	err |= __put_user(current->thread.trap_no, &sc->trapno);
+-	err |= __put_user(current->thread.error_code, &sc->err);
+-	err |= __put_user(regs->eip, &sc->eip);
+-	err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
+-	err |= __put_user(regs->eflags, &sc->eflags);
+-	err |= __put_user(regs->esp, &sc->esp_at_signal);
+-	err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
++	*(unsigned int *)&sc.fs = tmp;
++	*(unsigned int *)&sc.es = regs->xes;
++	*(unsigned int *)&sc.ds = regs->xds;
++	sc.edi = regs->edi;
++	sc.esi = regs->esi;
++	sc.ebp = regs->ebp;
++	sc.esp = regs->esp;
++	sc.ebx = regs->ebx;
++	sc.edx = regs->edx;
++	sc.ecx = regs->ecx;
++	sc.eax = regs->eax;
++	sc.trapno = current->thread.trap_no;
++	sc.err = current->thread.error_code;
++	sc.eip = regs->eip;
++	*(unsigned int *)&sc.cs = regs->xcs;
++	sc.eflags = regs->eflags;
++	sc.esp_at_signal = regs->esp;
++	*(unsigned int *)&sc.ss = regs->xss;
+ 
+ 	tmp = save_i387(fpstate);
+ 	if (tmp < 0)
+-	  err = 1;
+-	else
+-	  err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
++		return 1;
++	sc.fpstate = tmp ? fpstate : NULL;
+ 
+ 	/* non-iBCS2 extensions.. */
+-	err |= __put_user(mask, &sc->oldmask);
+-	err |= __put_user(current->thread.cr2, &sc->cr2);
++	sc.oldmask = mask;
++	sc.cr2 = current->thread.cr2;
+ 
+-	return err;
++	if (copy_to_user(__sc, &sc, sizeof(sc)))
++		return 1;
++	return 0;
+ }
+ 
+ /*
+@@ -440,7 +437,7 @@ static void setup_rt_frame(int sig, stru
+ 	/* Create the ucontext.  */
+ 	err |= __put_user(0, &frame->uc.uc_flags);
+ 	err |= __put_user(0, &frame->uc.uc_link);
+-	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
++	err |= __put_user(current->sas_ss_sp, (unsigned long *)&frame->uc.uc_stack.ss_sp);
+ 	err |= __put_user(sas_ss_flags(regs->esp),
+ 			  &frame->uc.uc_stack.ss_flags);
+ 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+--- linux-2.6.0-test6/arch/i386/kernel/smpboot.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/smpboot.c	2003-10-05 00:34:39.000000000 -0700
+@@ -499,8 +499,8 @@ static struct task_struct * __init fork_
+ #ifdef CONFIG_NUMA
+ 
+ /* which logical CPUs are on which nodes */
+-cpumask_t node_2_cpu_mask[MAX_NR_NODES] =
+-				{ [0 ... MAX_NR_NODES-1] = CPU_MASK_NONE };
++cpumask_t node_2_cpu_mask[MAX_NUMNODES] =
++				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
+ /* which node each logical CPU is on */
+ int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
+ 
+@@ -518,7 +518,7 @@ static inline void unmap_cpu_to_node(int
+ 	int node;
+ 
+ 	printk("Unmapping cpu %d from all nodes\n", cpu);
+-	for (node = 0; node < MAX_NR_NODES; node ++)
++	for (node = 0; node < MAX_NUMNODES; node ++)
+ 		cpu_clear(cpu, node_2_cpu_mask[node]);
+ 	cpu_2_node[cpu] = -1;
+ }
+@@ -937,6 +937,7 @@ int cpu_sibling_map[NR_CPUS] __cacheline
+ static void __init smp_boot_cpus(unsigned int max_cpus)
+ {
+ 	int apicid, cpu, bit, kicked;
++	unsigned long bogosum = 0;
+ 
+ 	/*
+ 	 * Setup boot CPU information
+@@ -1048,26 +1049,25 @@ static void __init smp_boot_cpus(unsigne
+ 	/*
+ 	 * Allow the user to impress friends.
+ 	 */
+-
+ 	Dprintk("Before bogomips.\n");
+-	if (!cpucount) {
+-		printk(KERN_ERR "Error: only one processor found.\n");
+-	} else {
+-		unsigned long bogosum = 0;
+-		for (cpu = 0; cpu < NR_CPUS; cpu++)
+-			if (cpu_isset(cpu, cpu_callout_map))
+-				bogosum += cpu_data[cpu].loops_per_jiffy;
+-		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+-			cpucount+1,
+-			bogosum/(500000/HZ),
+-			(bogosum/(5000/HZ))%100);
+-		Dprintk("Before bogocount - setting activated=1.\n");
+-	}
++	for (cpu = 0; cpu < NR_CPUS; cpu++)
++		if (cpu_isset(cpu, cpu_callout_map))
++			bogosum += cpu_data[cpu].loops_per_jiffy;
++	printk(KERN_INFO
++		"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
++		cpucount+1,
++		bogosum/(500000/HZ),
++		(bogosum/(5000/HZ))%100);
++	
++	Dprintk("Before bogocount - setting activated=1.\n");
+ 
+ 	if (smp_b_stepping)
+ 		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
+ 
+-	/* Don't taint if we are running SMP kernel on a single non-MP approved Athlon  */
++	/*
++	 * Don't taint if we are running SMP kernel on a single non-MP
++	 * approved Athlon
++	 */
+ 	if (tainted & TAINT_UNSAFE_SMP) {
+ 		if (cpucount)
+ 			printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n");
+--- linux-2.6.0-test6/arch/i386/kernel/smp.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/smp.c	2003-10-05 00:36:48.000000000 -0700
+@@ -327,10 +327,12 @@ asmlinkage void smp_invalidate_interrupt
+ 		 
+ 	if (flush_mm == cpu_tlbstate[cpu].active_mm) {
+ 		if (cpu_tlbstate[cpu].state == TLBSTATE_OK) {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ 			if (flush_va == FLUSH_ALL)
+ 				local_flush_tlb();
+ 			else
+ 				__flush_tlb_one(flush_va);
++#endif
+ 		} else
+ 			leave_mm(cpu);
+ 	}
+@@ -396,21 +398,6 @@ static void flush_tlb_others(cpumask_t c
+ 	spin_unlock(&tlbstate_lock);
+ }
+ 	
+-void flush_tlb_current_task(void)
+-{
+-	struct mm_struct *mm = current->mm;
+-	cpumask_t cpu_mask;
+-
+-	preempt_disable();
+-	cpu_mask = mm->cpu_vm_mask;
+-	cpu_clear(smp_processor_id(), cpu_mask);
+-
+-	local_flush_tlb();
+-	if (!cpus_empty(cpu_mask))
+-		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+-	preempt_enable();
+-}
+-
+ void flush_tlb_mm (struct mm_struct * mm)
+ {
+ 	cpumask_t cpu_mask;
+@@ -442,7 +429,10 @@ void flush_tlb_page(struct vm_area_struc
+ 
+ 	if (current->active_mm == mm) {
+ 		if(current->mm)
+-			__flush_tlb_one(va);
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
++			__flush_tlb_one(va)
++#endif
++				;
+ 		 else
+ 		 	leave_mm(smp_processor_id());
+ 	}
+@@ -466,7 +456,17 @@ void flush_tlb_all(void)
+ {
+ 	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+ }
+-
++#ifdef CONFIG_KGDB
++/*
++ * By using the NMI code instead of a vector we just sneak thru the
++ * word generator coming out with just what we want.  AND it does
++ * not matter if clustered_apic_mode is set or not.
++ */
++void smp_send_nmi_allbutself(void)
++{
++	send_IPI_allbutself(APIC_DM_NMI);
++}
++#endif
+ /*
+  * this function sends a 'reschedule' IPI to another CPU.
+  * it goes straight through and wastes no time serializing
+--- linux-2.6.0-test6/arch/i386/kernel/sysenter.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/kernel/sysenter.c	2003-10-05 00:36:48.000000000 -0700
+@@ -18,13 +18,18 @@
+ #include <asm/msr.h>
+ #include <asm/pgtable.h>
+ #include <asm/unistd.h>
++#include <linux/highmem.h>
+ 
+ extern asmlinkage void sysenter_entry(void);
+ 
+ void enable_sep_cpu(void *info)
+ {
+ 	int cpu = get_cpu();
++#ifdef CONFIG_X86_HIGH_ENTRY
++	struct tss_struct *tss = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
+ 	struct tss_struct *tss = init_tss + cpu;
++#endif
+ 
+ 	tss->ss1 = __KERNEL_CS;
+ 	tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
+--- linux-2.6.0-test6/arch/i386/kernel/time.c	2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/kernel/time.c	2003-10-05 00:36:22.000000000 -0700
+@@ -44,6 +44,7 @@
+ #include <linux/module.h>
+ #include <linux/sysdev.h>
+ #include <linux/bcd.h>
++#include <linux/efi.h>
+ 
+ #include <asm/io.h>
+ #include <asm/smp.h>
+@@ -160,6 +161,37 @@ static int set_rtc_mmss(unsigned long no
+ 	return retval;
+ }
+ 
++static int efi_set_rtc_mmss(unsigned long nowtime)
++{
++	int real_seconds, real_minutes;
++	unsigned long 	flags;
++	efi_status_t 	status;
++	efi_time_t 	eft;
++	efi_time_cap_t 	cap;
++
++	spin_lock_irqsave(&rtc_lock, flags);
++
++	status = efi.get_time(&eft, &cap);
++	if (status != EFI_SUCCESS)
++		panic("Ooops, efitime: can't read time!\n");
++	real_seconds = nowtime % 60;
++	real_minutes = nowtime / 60;
++
++	if (((abs(real_minutes - eft.minute) + 15)/30) & 1)
++		real_minutes += 30;
++	real_minutes %= 60;
++
++	eft.minute = real_minutes;
++	eft.second = real_seconds;
++
++	status = efi.set_time(&eft);
++	if (status != EFI_SUCCESS)
++		panic("Ooops: efitime: can't read time!\n");
++
++	spin_unlock_irqrestore(&rtc_lock, flags);
++	return 0;
++}
++
+ /* last time the cmos clock got updated */
+ static long last_rtc_update;
+ 
+@@ -212,7 +244,7 @@ static inline void do_timer_interrupt(in
+ 			>= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
+ 	    (xtime.tv_nsec / 1000)
+ 			<= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) {
+-		if (set_rtc_mmss(xtime.tv_sec) == 0)
++		if ((efi_enabled && (!efi_set_rtc_mmss(xtime.tv_sec) )) || (set_rtc_mmss(xtime.tv_sec) == 0))
+ 			last_rtc_update = xtime.tv_sec;
+ 		else
+ 			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+@@ -277,6 +309,27 @@ static struct sysdev_class pit_sysclass 
+ 	set_kset_name("pit"),
+ };
+ 
++/*
++ * This is called before the RT mappings are in place, so we
++ * need to be able to get the time in physical mode.
++ */
++unsigned long efi_get_time(void)
++{
++	efi_status_t status;
++	unsigned long flags;
++	efi_time_t eft;
++	efi_time_cap_t cap;
++
++	spin_lock_irqsave(&rtc_lock, flags);
++	status = phys_efi_get_time(&eft, &cap);
++	if (status != EFI_SUCCESS)
++		printk("Oops: efitime: can't read time status: 0x%lx\n", status);
++
++	spin_unlock_irqrestore(&rtc_lock, flags);
++
++	return mktime(eft.year, eft.month, eft.day, eft.hour, eft.minute, eft.second);
++}
++
+ /* XXX this driverfs stuff should probably go elsewhere later -john */
+ static struct sys_device device_i8253 = {
+ 	.id	= 0,
+@@ -298,7 +351,10 @@ extern void (*late_time_init)(void);
+ /* Duplicate of time_init() below, with hpet_enable part added */
+ void __init hpet_time_init(void)
+ {
+-	xtime.tv_sec = get_cmos_time();
++	if (efi_enabled)
++		xtime.tv_sec = efi_get_time();
++	else
++		xtime.tv_sec = get_cmos_time();
+ 	wall_to_monotonic.tv_sec = -xtime.tv_sec;
+ 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+ 	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
+@@ -324,8 +380,10 @@ void __init time_init(void)
+ 		return;
+ 	}
+ #endif
+-
+-	xtime.tv_sec = get_cmos_time();
++	if (efi_enabled)
++		xtime.tv_sec = efi_get_time();
++	else
++		xtime.tv_sec = get_cmos_time();
+ 	wall_to_monotonic.tv_sec = -xtime.tv_sec;
+ 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+ 	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
+--- linux-2.6.0-test6/arch/i386/kernel/traps.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/traps.c	2003-10-05 00:36:48.000000000 -0700
+@@ -54,12 +54,8 @@
+ 
+ #include "mach_traps.h"
+ 
+-asmlinkage int system_call(void);
+-asmlinkage void lcall7(void);
+-asmlinkage void lcall27(void);
+-
+-struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
+-		{ 0, 0 }, { 0, 0 } };
++struct desc_struct default_ldt[] __attribute__((__section__(".data.default_ldt"))) = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
++struct page *default_ldt_page;
+ 
+ /* Do we ignore FPU interrupts ? */
+ char ignore_fpu_irq = 0;
+@@ -91,6 +87,43 @@ asmlinkage void alignment_check(void);
+ asmlinkage void spurious_interrupt_bug(void);
+ asmlinkage void machine_check(void);
+ 
++#ifdef CONFIG_KGDB
++extern void sysenter_entry(void);
++#include <asm/kgdb.h>
++#include <linux/init.h>
++extern void int3(void);
++extern void debug(void);
++void set_intr_gate(unsigned int n, void *addr);
++static void set_intr_usr_gate(unsigned int n, void *addr);
++/*
++ * Should be able to call this breakpoint() very early in
++ * bring up.  Just hard code the call where needed.
++ * The breakpoint() code is here because set_?_gate() functions
++ * are local (static) to trap.c.  They need be done only once,
++ * but it does not hurt to do them over.
++ */
++void breakpoint(void)
++{
++	init_entry_mappings();
++        set_intr_usr_gate(3,&int3); /* disable ints on trap */
++	set_intr_gate(1,&debug);
++	set_intr_gate(14,&page_fault);
++
++        BREAKPOINT;
++}
++#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)		\
++    {									\
++	if (!user_mode(regs)  ) \
++	{								\
++		kgdb_handle_exception(trapnr, signr, error_code, regs);	\
++		after;							\
++	} else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
++    }
++#else
++#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)
++#endif
++
++
+ static int kstack_depth_to_print = 24;
+ 
+ void show_trace(struct task_struct *task, unsigned long * stack)
+@@ -173,8 +206,9 @@ void show_registers(struct pt_regs *regs
+ 		ss = regs->xss & 0xffff;
+ 	}
+ 	print_modules();
+-	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
+-		smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
++	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\nEFLAGS: %08lx\n",
++		smp_processor_id(), 0xffff & regs->xcs,
++		regs->eip, print_tainted(), regs->eflags);
+ 
+ 	print_symbol("EIP is at %s\n", regs->eip);
+ 	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+@@ -190,23 +224,27 @@ void show_registers(struct pt_regs *regs
+ 	 * time of the fault..
+ 	 */
+ 	if (in_kernel) {
++		u8 *eip;
+ 
+ 		printk("\nStack: ");
+ 		show_stack(NULL, (unsigned long*)esp);
+ 
+ 		printk("Code: ");
+-		if(regs->eip < PAGE_OFFSET)
+-			goto bad;
+ 
+-		for(i=0;i<20;i++)
+-		{
+-			unsigned char c;
+-			if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+-bad:
++		eip = (u8 *)regs->eip - 43;
++		for (i = 0; i < 64; i++, eip++) {
++			unsigned char c = 0xff;
++
++			if ((user_mode(regs) && get_user(c, eip)) ||
++			    (!user_mode(regs) && __direct_get_user(c, eip))) {
++
+ 				printk(" Bad EIP value.");
+ 				break;
+ 			}
+-			printk("%02x ", c);
++			if (eip == (u8 *)regs->eip)
++				printk("<%02x> ", c);
++			else
++				printk("%02x ", c);
+ 		}
+ 	}
+ 	printk("\n");
+@@ -253,12 +291,36 @@ spinlock_t die_lock = SPIN_LOCK_UNLOCKED
+ void die(const char * str, struct pt_regs * regs, long err)
+ {
+ 	static int die_counter;
++	int nl = 0;
+ 
+ 	console_verbose();
+ 	spin_lock_irq(&die_lock);
+ 	bust_spinlocks(1);
+ 	handle_BUG(regs);
+ 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++	printk("PREEMPT ");
++	nl = 1;
++#endif
++#ifdef CONFIG_SMP
++	printk("SMP ");
++	nl = 1;
++#endif
++#ifdef CONFIG_DEBUG_PAGEALLOC
++	printk("DEBUG_PAGEALLOC");
++	nl = 1;
++#endif
++	if (nl)
++		printk("\n");
++#ifdef CONFIG_KGDB
++	/* This is about the only place we want to go to kgdb even if in
++	 * user mode.  But we must go in via a trap so within kgdb we will
++	 * always be in kernel mode.
++	 */
++	if (user_mode(regs))
++		BREAKPOINT;
++#endif
++ 	CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
+ 	show_registers(regs);
+ 	bust_spinlocks(0);
+ 	spin_unlock_irq(&die_lock);
+@@ -328,6 +390,7 @@ static inline void do_trap(int trapnr, i
+ #define DO_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
+ 	do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
+ }
+ 
+@@ -345,7 +408,9 @@ asmlinkage void do_##name(struct pt_regs
+ #define DO_VM86_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++	CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
+ 	do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
++	return; \
+ }
+ 
+ #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+@@ -388,8 +453,10 @@ gp_in_vm86:
+ 	return;
+ 
+ gp_in_kernel:
+-	if (!fixup_exception(regs))
++	if (!fixup_exception(regs)){
++ 		CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
+ 		die("general protection fault", regs, error_code);
++	}
+ }
+ 
+ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+@@ -528,10 +595,18 @@ asmlinkage void do_debug(struct pt_regs 
+ 	if (regs->eflags & X86_EFLAGS_IF)
+ 		local_irq_enable();
+ 
+-	/* Mask out spurious debug traps due to lazy DR7 setting */
++	/*
++	 * Mask out spurious debug traps due to lazy DR7 setting or
++	 * due to 4G/4G kernel mode:
++	 */
+ 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
+ 		if (!tsk->thread.debugreg[7])
+ 			goto clear_dr7;
++		if (!user_mode(regs)) {
++			// restore upon return-to-userspace:
++			set_thread_flag(TIF_DB7);
++			goto clear_dr7;
++		}
+ 	}
+ 
+ 	if (regs->eflags & VM_MASK)
+@@ -551,8 +626,18 @@ asmlinkage void do_debug(struct pt_regs 
+ 		 * allowing programs to debug themselves without the ptrace()
+ 		 * interface.
+ 		 */
++#ifdef CONFIG_KGDB
++		/*
++		 * I think this is the only "real" case of a TF in the kernel
++		 * that really belongs to user space.  Others are
++		 * "Ours all ours!"
++		 */
++		if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
++			goto clear_TF_reenable;
++#else
+ 		if ((regs->xcs & 3) == 0)
+ 			goto clear_TF_reenable;
++#endif
+ 		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
+ 			goto clear_TF;
+ 	}
+@@ -564,6 +649,17 @@ asmlinkage void do_debug(struct pt_regs 
+ 	info.si_errno = 0;
+ 	info.si_code = TRAP_BRKPT;
+ 	
++#ifdef CONFIG_KGDB
++        /*
++	 * If this is a kernel mode trap, we need to reset db7 to allow us
++	 * to continue sanely ALSO skip the signal delivery
++         */
++	if ((regs->xcs & 3) == 0)
++		goto clear_dr7;
++
++        /* if not kernel, allow ints but only if they were on */
++       if ( regs->eflags & 0x200) local_irq_enable();
++#endif
+ 	/* If this is a kernel mode trap, save the user PC on entry to 
+ 	 * the kernel, that's what the debugger can make sense of.
+ 	 */
+@@ -578,6 +674,7 @@ clear_dr7:
+ 	__asm__("movl %0,%%db7"
+ 		: /* no output */
+ 		: "r" (0));
++	CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
+ 	return;
+ 
+ debug_vm86:
+@@ -773,19 +870,53 @@ asmlinkage void math_emulate(long arg)
+ 
+ #endif /* CONFIG_MATH_EMULATION */
+ 
+-#ifdef CONFIG_X86_F00F_BUG
+-void __init trap_init_f00f_bug(void)
++void __init trap_init_virtual_IDT(void)
+ {
+-	__set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
+-
+ 	/*
+-	 * Update the IDT descriptor and reload the IDT so that
+-	 * it uses the read-only mapped virtual address.
++	 * "idt" is magic - it overlaps the idt_descr
++	 * variable so that updating idt will automatically
++	 * update the idt descriptor..
+ 	 */
+-	idt_descr.address = fix_to_virt(FIX_F00F_IDT);
++	__set_fixmap(FIX_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
++	idt_descr.address = __fix_to_virt(FIX_IDT);
++
+ 	__asm__ __volatile__("lidt %0" : : "m" (idt_descr));
+ }
++
++void __init trap_init_virtual_GDT(void)
++{
++	int cpu = smp_processor_id();
++	struct Xgt_desc_struct *gdt_desc = cpu_gdt_descr + cpu;
++	struct Xgt_desc_struct tmp_desc = {0, 0};
++	struct tss_struct * t;
++
++	__asm__ __volatile__("sgdt %0": "=m" (tmp_desc): :"memory");
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++	if (!cpu) {
++		__set_fixmap(FIX_GDT_0, __pa(cpu_gdt_table), PAGE_KERNEL);
++		__set_fixmap(FIX_GDT_1, __pa(cpu_gdt_table) + PAGE_SIZE, PAGE_KERNEL);
++		__set_fixmap(FIX_TSS_0, __pa(init_tss), PAGE_KERNEL);
++		__set_fixmap(FIX_TSS_1, __pa(init_tss) + 1*PAGE_SIZE, PAGE_KERNEL);
++		__set_fixmap(FIX_TSS_2, __pa(init_tss) + 2*PAGE_SIZE, PAGE_KERNEL);
++		__set_fixmap(FIX_TSS_3, __pa(init_tss) + 3*PAGE_SIZE, PAGE_KERNEL);
++	}
++
++	gdt_desc->address = __fix_to_virt(FIX_GDT_0) + sizeof(cpu_gdt_table[0]) * cpu;
++#else
++	gdt_desc->address = (unsigned long)cpu_gdt_table[cpu];
++#endif
++	__asm__ __volatile__("lgdt %0": "=m" (*gdt_desc));
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++	t = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
++	t = init_tss + cpu;
+ #endif
++	set_tss_desc(cpu, t);
++	cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
++	load_TR_desc();
++}
+ 
+ #define _set_gate(gate_addr,type,dpl,addr,seg) \
+ do { \
+@@ -812,20 +943,26 @@ void set_intr_gate(unsigned int n, void 
+ 	_set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+ }
+ 
+-static void __init set_trap_gate(unsigned int n, void *addr)
++void __init set_trap_gate(unsigned int n, void *addr)
+ {
+ 	_set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+ }
+ 
+-static void __init set_system_gate(unsigned int n, void *addr)
++void __init set_system_gate(unsigned int n, void *addr)
+ {
+ 	_set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
+ }
+ 
+-static void __init set_call_gate(void *a, void *addr)
++void __init set_call_gate(void *a, void *addr)
+ {
+ 	_set_gate(a,12,3,addr,__KERNEL_CS);
+ }
++#ifdef CONFIG_KGDB
++void set_intr_usr_gate(unsigned int n, void *addr)
++{
++	_set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
++}
++#endif
+ 
+ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+ {
+@@ -844,11 +981,16 @@ void __init trap_init(void)
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 	init_apic_mappings();
+ #endif
++	init_entry_mappings();
+ 
+ 	set_trap_gate(0,&divide_error);
+ 	set_intr_gate(1,&debug);
+ 	set_intr_gate(2,&nmi);
++#ifndef CONFIG_KGDB
+ 	set_system_gate(3,&int3);	/* int3-5 can be called from all */
++#else
++	set_intr_usr_gate(3,&int3);	/* int3-5 can be called from all */
++#endif
+ 	set_system_gate(4,&overflow);
+ 	set_system_gate(5,&bounds);
+ 	set_trap_gate(6,&invalid_op);
+--- linux-2.6.0-test6/arch/i386/kernel/vm86.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/i386/kernel/vm86.c	2003-10-05 00:36:48.000000000 -0700
+@@ -117,7 +117,7 @@ struct pt_regs * save_v86_state(struct k
+ 
+ 	tss = init_tss + get_cpu();
+ 	current->thread.esp0 = current->thread.saved_esp0;
+-	load_esp0(tss, current->thread.esp0);
++	load_esp0(tss, virtual_esp0(current));
+ 	current->thread.saved_esp0 = 0;
+ 	put_cpu();
+ 
+@@ -294,7 +294,8 @@ static void do_sys_vm86(struct kernel_vm
+ 	asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs));
+ 
+ 	tss = init_tss + get_cpu();
+-	tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
++	tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
++	tss->esp0 = virtual_esp0(tsk);
+ 	disable_sysenter(tss);
+ 	put_cpu();
+ 
+--- linux-2.6.0-test6/arch/i386/kernel/vmlinux.lds.S	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/vmlinux.lds.S	2003-10-05 00:36:48.000000000 -0700
+@@ -3,6 +3,9 @@
+  */
+ 
+ #include <asm-generic/vmlinux.lds.h>
++#include <linux/config.h>
++#include <asm/page.h>
++#include <asm/asm_offsets.h>
+ 	
+ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+ OUTPUT_ARCH(i386)
+@@ -10,7 +13,7 @@ ENTRY(startup_32)
+ jiffies = jiffies_64;
+ SECTIONS
+ {
+-  . = 0xC0000000 + 0x100000;
++  . = __PAGE_OFFSET + 0x100000;
+   /* read-only */
+   _text = .;			/* Text and read-only data */
+   .text : {
+@@ -19,6 +22,19 @@ SECTIONS
+ 	*(.gnu.warning)
+ 	} = 0x9090
+ 
++#ifdef CONFIG_X86_4G
++  . = ALIGN(PAGE_SIZE_asm);
++  __entry_tramp_start = .;
++  . = FIX_ENTRY_TRAMPOLINE_0_addr;
++  __start___entry_text = .;
++  .entry.text : AT (__entry_tramp_start) { *(.entry.text) }
++  __entry_tramp_end = __entry_tramp_start + SIZEOF(.entry.text);
++  . = __entry_tramp_end;
++  . = ALIGN(PAGE_SIZE_asm);
++#else
++  .entry.text : { *(.entry.text) }
++#endif
++
+   _etext = .;			/* End of text section */
+ 
+   . = ALIGN(16);		/* Exception table */
+@@ -34,15 +50,12 @@ SECTIONS
+ 	CONSTRUCTORS
+ 	}
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __nosave_begin = .;
+   .data_nosave : { *(.data.nosave) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __nosave_end = .;
+ 
+-  . = ALIGN(4096);
+-  .data.page_aligned : { *(.data.idt) }
+-
+   . = ALIGN(32);
+   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ 
+@@ -52,7 +65,7 @@ SECTIONS
+   .data.init_task : { *(.data.init_task) }
+ 
+   /* will be freed after init */
+-  . = ALIGN(4096);		/* Init code and data */
++  . = ALIGN(PAGE_SIZE_asm);		/* Init code and data */
+   __init_begin = .;
+   .init.text : { 
+ 	_sinittext = .;
+@@ -91,7 +104,7 @@ SECTIONS
+      from .altinstructions and .eh_frame */
+   .exit.text : { *(.exit.text) }
+   .exit.data : { *(.exit.data) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __initramfs_start = .;
+   .init.ramfs : { *(.init.ramfs) }
+   __initramfs_end = .;
+@@ -99,10 +112,22 @@ SECTIONS
+   __per_cpu_start = .;
+   .data.percpu  : { *(.data.percpu) }
+   __per_cpu_end = .;
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __init_end = .;
+   /* freed after init ends here */
+-	
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_tss : { *(.data.tss) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_default_ldt : { *(.data.default_ldt) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_idt : { *(.data.idt) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_gdt : { *(.data.gdt) }
++
+   __bss_start = .;		/* BSS */
+   .bss : { *(.bss) }
+   __bss_stop = .; 
+@@ -122,4 +147,6 @@ SECTIONS
+   .stab.index 0 : { *(.stab.index) }
+   .stab.indexstr 0 : { *(.stab.indexstr) }
+   .comment 0 : { *(.comment) }
++
++
+ }
+--- linux-2.6.0-test6/arch/i386/kernel/vsyscall.lds	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/i386/kernel/vsyscall.lds	2003-10-05 00:36:48.000000000 -0700
+@@ -5,7 +5,7 @@
+  */
+ 
+ /* This must match <asm/fixmap.h>.  */
+-VSYSCALL_BASE = 0xffffe000;
++VSYSCALL_BASE = 0xffffd000;
+ 
+ SECTIONS
+ {
+--- linux-2.6.0-test6/arch/i386/kernel/vsyscall-sysenter.S	2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/i386/kernel/vsyscall-sysenter.S	2003-10-05 00:36:48.000000000 -0700
+@@ -7,6 +7,11 @@
+ 	.type __kernel_vsyscall,@function
+ __kernel_vsyscall:
+ .LSTART_vsyscall:
++	cmpl $192, %eax
++	jne 1f
++	int $0x80
++	ret
++1:
+ 	push %ecx
+ .Lpush_ecx:
+ 	push %edx
+--- linux-2.6.0-test6/arch/i386/lib/checksum.S	2003-06-14 12:18:30.000000000 -0700
++++ 25/arch/i386/lib/checksum.S	2003-10-05 00:36:48.000000000 -0700
+@@ -280,14 +280,14 @@ unsigned int csum_partial_copy_generic (
+ 	.previous
+ 
+ .align 4
+-.globl csum_partial_copy_generic
++.globl direct_csum_partial_copy_generic
+ 				
+ #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
+ 
+ #define ARGBASE 16		
+ #define FP		12
+ 		
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+ 	subl  $4,%esp	
+ 	pushl %edi
+ 	pushl %esi
+@@ -422,7 +422,7 @@ DST(	movb %cl, (%edi)	)
+ 
+ #define ARGBASE 12
+ 		
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+ 	pushl %ebx
+ 	pushl %edi
+ 	pushl %esi
+--- linux-2.6.0-test6/arch/i386/lib/dec_and_lock.c	2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/lib/dec_and_lock.c	2003-10-05 00:36:40.000000000 -0700
+@@ -10,6 +10,7 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
+ 
++#ifndef ATOMIC_DEC_AND_LOCK
+ int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+ {
+ 	int counter;
+@@ -38,3 +39,5 @@ slow_path:
+ 	spin_unlock(lock);
+ 	return 0;
+ }
++#endif
++
+--- linux-2.6.0-test6/arch/i386/lib/getuser.S	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/i386/lib/getuser.S	2003-10-05 00:36:48.000000000 -0700
+@@ -9,6 +9,7 @@
+  * return value.
+  */
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+ 
+ 
+ /*
+@@ -28,7 +29,7 @@
+ .globl __get_user_1
+ __get_user_1:
+ 	GET_THREAD_INFO(%edx)
+-	cmpl TI_ADDR_LIMIT(%edx),%eax
++	cmpl TI_addr_limit(%edx),%eax
+ 	jae bad_get_user
+ 1:	movzbl (%eax),%edx
+ 	xorl %eax,%eax
+@@ -40,7 +41,7 @@ __get_user_2:
+ 	addl $1,%eax
+ 	jc bad_get_user
+ 	GET_THREAD_INFO(%edx)
+-	cmpl TI_ADDR_LIMIT(%edx),%eax
++	cmpl TI_addr_limit(%edx),%eax
+ 	jae bad_get_user
+ 2:	movzwl -1(%eax),%edx
+ 	xorl %eax,%eax
+@@ -52,7 +53,7 @@ __get_user_4:
+ 	addl $3,%eax
+ 	jc bad_get_user
+ 	GET_THREAD_INFO(%edx)
+-	cmpl TI_ADDR_LIMIT(%edx),%eax
++	cmpl TI_addr_limit(%edx),%eax
+ 	jae bad_get_user
+ 3:	movl -3(%eax),%edx
+ 	xorl %eax,%eax
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/lib/kgdb_serial.c	2003-10-05 00:33:44.000000000 -0700
+@@ -0,0 +1,499 @@
++/*
++ * Serial interface GDB stub
++ *
++ * Written (hacked together) by David Grothe (dave@gcom.com)
++ * Modified to allow invokation early in boot see also
++ * kgdb.h for instructions by George Anzinger(george@mvista.com)
++ * Modified to handle debugging over ethernet by Robert Walsh
++ * <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ * code by San Mehat.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/kgdb_local.h>
++#ifdef CONFIG_KGDB_USER_CONSOLE
++extern void kgdb_console_finit(void);
++#endif
++#define PRNT_off
++#define TEST_EXISTANCE
++#ifdef PRNT
++#define dbprintk(s) printk s
++#else
++#define dbprintk(s)
++#endif
++#define TEST_INTERRUPT_off
++#ifdef TEST_INTERRUPT
++#define intprintk(s) printk s
++#else
++#define intprintk(s)
++#endif
++
++#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
++
++#define	GDB_BUF_SIZE	512	/* power of 2, please */
++
++static char gdb_buf[GDB_BUF_SIZE];
++static int gdb_buf_in_inx;
++static atomic_t gdb_buf_in_cnt;
++static int gdb_buf_out_inx;
++
++struct async_struct *gdb_async_info;
++static int gdb_async_irq;
++
++#define outb_px(a,b) outb_p(b,a)
++
++static void program_uart(struct async_struct *info);
++static void write_char(struct async_struct *info, int chr);
++/*
++ * Get a byte from the hardware data buffer and return it
++ */
++static int
++read_data_bfr(struct async_struct *info)
++{
++	char it = inb_p(info->port + UART_LSR);
++
++	if (it & UART_LSR_DR)
++		return (inb_p(info->port + UART_RX));
++	/*
++	 * If we have a framing error assume somebody messed with
++	 * our uart.  Reprogram it and send '-' both ways...
++	 */
++	if (it & 0xc) {
++		program_uart(info);
++		write_char(info, '-');
++		return ('-');
++	}
++	return (-1);
++
++}				/* read_data_bfr */
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++
++ * Locking here is a bit of a problem.	We MUST not lock out communication
++ * if we are trying to talk to gdb about a kgdb entry.	ON the other hand
++ * we can loose chars in the console pass thru if we don't lock.  It is also
++ * possible that we could hold the lock or be waiting for it when kgdb
++ * NEEDS to talk.  Since kgdb locks down the world, it does not need locks.
++ * We do, of course have possible issues with interrupting a uart operation,
++ * but we will just depend on the uart status to help keep that straight.
++
++ */
++static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
++#ifdef CONFIG_SMP
++extern spinlock_t kgdb_spinlock;
++#endif
++
++static int
++read_char(struct async_struct *info)
++{
++	int chr;
++	unsigned long flags;
++	local_irq_save(flags);
++#ifdef CONFIG_SMP
++	if (!spin_is_locked(&kgdb_spinlock)) {
++		spin_lock(&uart_interrupt_lock);
++	}
++#endif
++	if (atomic_read(&gdb_buf_in_cnt) != 0) {	/* intr routine has q'd chars */
++		chr = gdb_buf[gdb_buf_out_inx++];
++		gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
++		atomic_dec(&gdb_buf_in_cnt);
++	} else {
++		chr = read_data_bfr(info);
++	}
++#ifdef CONFIG_SMP
++	if (!spin_is_locked(&kgdb_spinlock)) {
++		spin_unlock(&uart_interrupt_lock);
++	}
++#endif
++	local_irq_restore(flags);
++	return (chr);
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_char(struct async_struct *info, int chr)
++{
++	while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
++
++	outb_p(chr, info->port + UART_TX);
++
++}				/* write_char */
++
++/*
++ * Mostly we don't need a spinlock, but since the console goes
++ * thru here with interrutps on, well, we need to catch those
++ * chars.
++ */
++/*
++ * This is the receiver interrupt routine for the GDB stub.
++ * It will receive a limited number of characters of input
++ * from the gdb  host machine and save them up in a buffer.
++ *
++ * When the gdb stub routine tty_getDebugChar() is called it
++ * draws characters out of the buffer until it is empty and
++ * then reads directly from the serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine
++ * since the stubs do all of that via tty_putDebugChar() which
++ * writes one byte after waiting for the interface to become
++ * ready.
++ *
++ * The debug stubs like to run with interrupts disabled since,
++ * after all, they run as a consequence of a breakpoint in
++ * the kernel.
++ *
++ * Perhaps someone who knows more about the tty driver than I
++ * care to learn can make this work for any low level serial
++ * driver.
++ */
++static irqreturn_t
++gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct async_struct *info;
++	unsigned long flags;
++
++	info = gdb_async_info;
++	if (!info || !info->tty || irq != gdb_async_irq)
++		return IRQ_NONE;
++
++	local_irq_save(flags);
++	spin_lock(&uart_interrupt_lock);
++	do {
++		int chr = read_data_bfr(info);
++		intprintk(("Debug char on int: %x hex\n", chr));
++		if (chr < 0)
++			continue;
++
++		if (chr == 3) {	/* Ctrl-C means remote interrupt */
++			BREAKPOINT;
++			continue;
++		}
++
++		if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++			/* buffer overflow tosses early char */
++			read_char(info);
++		}
++		gdb_buf[gdb_buf_in_inx++] = chr;
++		gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++	} while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
++	spin_unlock(&uart_interrupt_lock);
++	local_irq_restore(flags);
++	return IRQ_HANDLED;
++}				/* gdb_interrupt */
++
++/*
++ * Just a NULL routine for testing.
++ */
++void
++gdb_null(void)
++{
++}				/* gdb_null */
++
++/* These structure are filled in with values defined in asm/kgdb_local.h
++ */
++static struct serial_state state = SB_STATE;
++static struct async_struct local_info = SB_INFO;
++static int ok_to_enable_ints = 0;
++static void kgdb_enable_ints_now(void);
++
++extern char *kgdb_version;
++/*
++ * Hook an IRQ for KGDB.
++ *
++ * This routine is called from tty_putDebugChar, below.
++ */
++static int ints_disabled = 1;
++int
++gdb_hook_interrupt(struct async_struct *info, int verb)
++{
++	struct serial_state *state = info->state;
++	unsigned long flags;
++	int port;
++#ifdef TEST_EXISTANCE
++	int scratch, scratch2;
++#endif
++
++	/* The above fails if memory managment is not set up yet.
++	 * Rather than fail the set up, just keep track of the fact
++	 * and pick up the interrupt thing later.
++	 */
++	gdb_async_info = info;
++	port = gdb_async_info->port;
++	gdb_async_irq = state->irq;
++	if (verb) {
++		printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
++		       kgdb_version,
++		       port,
++		       gdb_async_irq, gdb_async_info->state->custom_divisor);
++	}
++	local_irq_save(flags);
++#ifdef TEST_EXISTANCE
++	/* Existance test */
++	/* Should not need all this, but just in case.... */
++
++	scratch = inb_p(port + UART_IER);
++	outb_px(port + UART_IER, 0);
++	outb_px(0xff, 0x080);
++	scratch2 = inb_p(port + UART_IER);
++	outb_px(port + UART_IER, scratch);
++	if (scratch2) {
++		printk
++		    ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
++		local_irq_restore(flags);
++		return 1;	/* We failed; there's nothing here */
++	}
++	scratch2 = inb_p(port + UART_LCR);
++	outb_px(port + UART_LCR, 0xBF);	/* set up for StarTech test */
++	outb_px(port + UART_EFR, 0);	/* EFR is the same as FCR */
++	outb_px(port + UART_LCR, 0);
++	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
++	scratch = inb_p(port + UART_IIR) >> 6;
++	if (scratch == 1) {
++		printk("gdb_hook_interrupt: Undefined UART type!"
++		       "  Not a UART! \n");
++		local_irq_restore(flags);
++		return 1;
++	} else {
++		dbprintk(("gdb_hook_interrupt: UART type "
++			  "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
++	}
++	scratch = inb_p(port + UART_MCR);
++	outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
++	outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
++	scratch2 = inb_p(port + UART_MSR) & 0xF0;
++	outb_px(port + UART_MCR, scratch);
++	if (scratch2 != 0x90) {
++		printk("gdb_hook_interrupt: "
++		       "Loop back test failed! Not a UART!\n");
++		local_irq_restore(flags);
++		return scratch2 + 1000;	/* force 0 to fail */
++	}
++#endif				/* test existance */
++	program_uart(info);
++	local_irq_restore(flags);
++
++	return (0);
++
++}				/* gdb_hook_interrupt */
++
++static void
++program_uart(struct async_struct *info)
++{
++	int port = info->port;
++
++	(void) inb_p(port + UART_RX);
++	outb_px(port + UART_IER, 0);
++
++	(void) inb_p(port + UART_RX);	/* serial driver comments say */
++	(void) inb_p(port + UART_IIR);	/* this clears the interrupt regs */
++	(void) inb_p(port + UART_MSR);
++	outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
++	outb_px(port + UART_DLL, info->state->custom_divisor & 0xff);	/* LS */
++	outb_px(port + UART_DLM, info->state->custom_divisor >> 8);	/* MS  */
++	outb_px(port + UART_MCR, info->MCR);
++
++	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);	/* set fcr */
++	outb_px(port + UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
++	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1);	/* set fcr */
++	if (!ints_disabled) {
++		intprintk(("KGDB: Sending %d to port %x offset %d\n",
++			   gdb_async_info->IER,
++			   (int) gdb_async_info->port, UART_IER));
++		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++	}
++	return;
++}
++
++/*
++ * tty_getDebugChar
++ *
++ * This is a GDB stub routine.	It waits for a character from the
++ * serial interface and then returns it.  If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.  In the
++ */
++int kgdb_in_isr = 0;
++int kgdb_in_lsr = 0;
++extern spinlock_t kgdb_spinlock;
++
++/* Caller takes needed protections */
++
++int
++tty_getDebugChar(void)
++{
++	volatile int chr, dum, time, end_time;
++
++	dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
++
++	if (gdb_async_info == NULL) {
++		gdb_hook_interrupt(&local_info, 0);
++	}
++	/*
++	 * This trick says if we wait a very long time and get
++	 * no char, return the -1 and let the upper level deal
++	 * with it.
++	 */
++	rdtsc(dum, time);
++	end_time = time + 2;
++	while (((chr = read_char(gdb_async_info)) == -1) &&
++	       (end_time - time) > 0) {
++		rdtsc(dum, time);
++	};
++	/*
++	 * This covers our butts if some other code messes with
++	 * our uart, hay, it happens :o)
++	 */
++	if (chr == -1)
++		program_uart(gdb_async_info);
++
++	dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
++	return (chr);
++
++}				/* tty_getDebugChar */
++
++static int count = 3;
++static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
++
++static int __init
++kgdb_enable_ints(void)
++{
++	if (kgdb_eth != -1) {
++		return 0;
++	}
++	if (gdb_async_info == NULL) {
++		gdb_hook_interrupt(&local_info, 1);
++	}
++	ok_to_enable_ints = 1;
++	kgdb_enable_ints_now();
++#ifdef CONFIG_KGDB_USER_CONSOLE
++	kgdb_console_finit();
++#endif
++	return 0;
++}
++
++#ifdef CONFIG_SERIAL_8250
++void shutdown_for_kgdb(struct async_struct *gdb_async_info);
++#endif
++
++#ifdef CONFIG_DISCONTIGMEM
++static inline int kgdb_mem_init_done(void)
++{
++	return highmem_start_page != NULL;
++}
++#else
++static inline int kgdb_mem_init_done(void)
++{
++	return max_mapnr != 0;
++}
++#endif
++
++static void
++kgdb_enable_ints_now(void)
++{
++	if (!spin_trylock(&one_at_atime))
++		return;
++	if (!ints_disabled)
++		goto exit;
++	if (kgdb_mem_init_done() &&
++			ints_disabled) {	/* don't try till mem init */
++#ifdef CONFIG_SERIAL_8250
++		/*
++		 * The ifdef here allows the system to be configured
++		 * without the serial driver.
++		 * Don't make it a module, however, it will steal the port
++		 */
++		shutdown_for_kgdb(gdb_async_info);
++#endif
++		ints_disabled = request_irq(gdb_async_info->state->irq,
++					    gdb_interrupt,
++					    IRQ_T(gdb_async_info),
++					    "KGDB-stub", NULL);
++		intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
++	}
++	if (!ints_disabled) {
++		intprintk(("KGDB: Sending %d to port %x offset %d\n",
++			   gdb_async_info->IER,
++			   (int) gdb_async_info->port, UART_IER));
++		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++	}
++      exit:
++	spin_unlock(&one_at_atime);
++}
++
++/*
++ * tty_putDebugChar
++ *
++ * This is a GDB stub routine.	It waits until the interface is ready
++ * to transmit a char and then sends it.  If there is no serial
++ * interface connection then it simply returns to its caller, having
++ * pretended to send the char.	Caller takes needed protections.
++ */
++void
++tty_putDebugChar(int chr)
++{
++	dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
++		  gdb_async_info->port,
++		  chr,
++		  chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
++
++	if (gdb_async_info == NULL) {
++		gdb_hook_interrupt(&local_info, 0);
++	}
++
++	write_char(gdb_async_info, chr);	/* this routine will wait */
++	count = (chr == '#') ? 0 : count + 1;
++	if ((count == 2)) {	/* try to enable after */
++		if (ints_disabled & ok_to_enable_ints)
++			kgdb_enable_ints_now();	/* try to enable after */
++
++		/* We do this a lot because, well we really want to get these
++		 * interrupts.	The serial driver will clear these bits when it
++		 * initializes the chip.  Every thing else it does is ok,
++		 * but this.
++		 */
++		if (!ints_disabled) {
++			outb_px(gdb_async_info->port + UART_IER,
++				gdb_async_info->IER);
++		}
++	}
++
++}				/* tty_putDebugChar */
++
++/*
++ * This does nothing for the serial port, since it doesn't buffer.
++ */
++
++void tty_flushDebugChar(void)
++{
++}
++
++module_init(kgdb_enable_ints);
+--- linux-2.6.0-test6/arch/i386/lib/Makefile	2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/lib/Makefile	2003-10-05 00:33:38.000000000 -0700
+@@ -9,4 +9,5 @@ lib-y = checksum.o delay.o \
+ 
+ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
+ lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
++lib-$(CONFIG_KGDB) += kgdb_serial.o
+ lib-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
+--- linux-2.6.0-test6/arch/i386/lib/usercopy.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/lib/usercopy.c	2003-10-05 00:36:48.000000000 -0700
+@@ -76,7 +76,7 @@ do {									   \
+  * and returns @count.
+  */
+ long
+-__strncpy_from_user(char *dst, const char __user *src, long count)
++__direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+ 	long res;
+ 	__do_strncpy_from_user(dst, src, count, res);
+@@ -102,7 +102,7 @@ __strncpy_from_user(char *dst, const cha
+  * and returns @count.
+  */
+ long
+-strncpy_from_user(char *dst, const char __user *src, long count)
++direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+ 	long res = -EFAULT;
+ 	if (access_ok(VERIFY_READ, src, 1))
+@@ -147,7 +147,7 @@ do {									\
+  * On success, this will be zero.
+  */
+ unsigned long
+-clear_user(void __user *to, unsigned long n)
++direct_clear_user(void __user *to, unsigned long n)
+ {
+ 	might_sleep();
+ 	if (access_ok(VERIFY_WRITE, to, n))
+@@ -167,7 +167,7 @@ clear_user(void __user *to, unsigned lon
+  * On success, this will be zero.
+  */
+ unsigned long
+-__clear_user(void __user *to, unsigned long n)
++__direct_clear_user(void __user *to, unsigned long n)
+ {
+ 	__do_clear_user(to, n);
+ 	return n;
+@@ -184,7 +184,7 @@ __clear_user(void __user *to, unsigned l
+  * On exception, returns 0.
+  * If the string is too long, returns a value greater than @n.
+  */
+-long strnlen_user(const char __user *s, long n)
++long direct_strnlen_user(const char __user *s, long n)
+ {
+ 	unsigned long mask = -__addr_ok(s);
+ 	unsigned long res, tmp;
+@@ -573,3 +573,4 @@ unsigned long __copy_from_user_ll(void *
+ 		n = __copy_user_zeroing_intel(to, (const void *) from, n);
+ 	return n;
+ }
++
+--- linux-2.6.0-test6/arch/i386/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/Makefile	2003-10-05 00:33:38.000000000 -0700
+@@ -84,6 +84,9 @@ mcore-$(CONFIG_X86_ES7000)	:= mach-es700
+ # default subarch .h files
+ mflags-y += -Iinclude/asm-i386/mach-default
+ 
++mflags-$(CONFIG_KGDB) += -gdwarf-2
++mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
++
+ head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+ 
+ libs-y 					+= arch/i386/lib/
+--- linux-2.6.0-test6/arch/i386/math-emu/fpu_system.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/arch/i386/math-emu/fpu_system.h	2003-10-05 00:36:48.000000000 -0700
+@@ -15,6 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
++#include <asm/atomic_kmap.h>
+ 
+ /* This sets the pointer FPU_info to point to the argument part
+    of the stack frame of math_emulate() */
+@@ -22,7 +23,7 @@
+ 
+ /* s is always from a cpu register, and the cpu does bounds checking
+  * during register load --> no further bounds checks needed */
+-#define LDT_DESCRIPTOR(s)	(((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
++#define LDT_DESCRIPTOR(s)	(((struct desc_struct *)__kmap_atomic_vaddr(KM_LDT_PAGE0))[(s) >> 3])
+ #define SEG_D_SIZE(x)		((x).b & (3 << 21))
+ #define SEG_G_BIT(x)		((x).b & (1 << 23))
+ #define SEG_GRANULARITY(x)	(((x).b & (1 << 23)) ? 4096 : 1)
+--- linux-2.6.0-test6/arch/i386/mm/extable.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/i386/mm/extable.c	2003-10-05 00:36:48.000000000 -0700
+@@ -6,6 +6,52 @@
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
+ #include <asm/uaccess.h>
++#include <asm/pgtable.h>
++
++extern struct exception_table_entry __start___ex_table[];
++extern struct exception_table_entry __stop___ex_table[];
++
++/*
++ * The exception table needs to be sorted because we use the macros
++ * which put things into the exception table in a variety of sections
++ * as well as the init section and the main kernel text section.
++ */
++static inline void
++sort_ex_table(struct exception_table_entry *start,
++	      struct exception_table_entry *finish)
++{
++	struct exception_table_entry el, *p, *q;
++
++	/* insertion sort */
++	for (p = start + 1; p < finish; ++p) {
++		/* start .. p-1 is sorted */
++		if (p[0].insn < p[-1].insn) {
++			/* move element p down to its right place */
++			el = *p;
++			q = p;
++			do {
++				/* el comes before q[-1], move q[-1] up one */
++				q[0] = q[-1];
++				--q;
++			} while (q > start && el.insn < q[-1].insn);
++			*q = el;
++		}
++	}
++}
++
++void fixup_sort_exception_table(void)
++{
++	struct exception_table_entry *p;
++
++	/*
++	 * Fix up the trampoline exception addresses:
++	 */
++	for (p = __start___ex_table; p < __stop___ex_table; p++) {
++		p->insn = (unsigned long)(void *)p->insn;
++		p->fixup = (unsigned long)(void *)p->fixup;
++	}
++	sort_ex_table(__start___ex_table, __stop___ex_table);
++}
+ 
+ /* Simple binary search */
+ const struct exception_table_entry *
+@@ -15,13 +61,15 @@ search_extable(const struct exception_ta
+ {
+         while (first <= last) {
+ 		const struct exception_table_entry *mid;
+-		long diff;
+ 
+ 		mid = (last - first) / 2 + first;
+-		diff = mid->insn - value;
+-                if (diff == 0)
++		/*
++		 * careful, the distance between entries can be
++		 * larger than 2GB:
++		 */
++                if (mid->insn == value)
+                         return mid;
+-                else if (diff < 0)
++                else if (mid->insn < value)
+                         first = mid+1;
+                 else
+                         last = mid-1;
+--- linux-2.6.0-test6/arch/i386/mm/fault.c	2003-06-26 22:07:23.000000000 -0700
++++ 25/arch/i386/mm/fault.c	2003-10-05 00:36:50.000000000 -0700
+@@ -19,6 +19,7 @@
+ #include <linux/init.h>
+ #include <linux/tty.h>
+ #include <linux/vt_kern.h>		/* For unblank_screen() */
++#include <linux/highmem.h>
+ #include <linux/module.h>
+ 
+ #include <asm/system.h>
+@@ -26,6 +27,7 @@
+ #include <asm/pgalloc.h>
+ #include <asm/hardirq.h>
+ #include <asm/desc.h>
++#include <asm/tlbflush.h>
+ 
+ extern void die(const char *,struct pt_regs *,long);
+ 
+@@ -55,6 +57,161 @@ void bust_spinlocks(int yes)
+ 	console_loglevel = loglevel_save;
+ }
+ 
++/*
++ * Return EIP plus the CS segment base.  The segment limit is also
++ * adjusted, clamped to the kernel/user address space (whichever is
++ * appropriate), and returned in *eip_limit.
++ *
++ * The segment is checked, because it might have been changed by another
++ * task between the original faulting instruction and here.
++ *
++ * If CS is no longer a valid code segment, or if EIP is beyond the
++ * limit, or if it is a kernel address when CS is not a kernel segment,
++ * then the returned value will be greater than *eip_limit.
++ */
++static inline unsigned long get_segment_eip(struct pt_regs *regs,
++					    unsigned long *eip_limit)
++{
++	unsigned long eip = regs->eip;
++	unsigned seg = regs->xcs & 0xffff;
++	u32 seg_ar, seg_limit, base, *desc;
++
++	/* The standard kernel/user address space limit. */
++	*eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg;
++
++	/* Unlikely, but must come before segment checks. */
++	if (unlikely((regs->eflags & VM_MASK) != 0))
++		return eip + (seg << 4);
++
++	/* By far the commonest cases. */
++	if (likely(seg == __USER_CS || seg == __KERNEL_CS))
++		return eip;
++
++	/* Check the segment exists, is within the current LDT/GDT size,
++	   that kernel/user (ring 0..3) has the appropriate privilege,
++	   that it's a code segment, and get the limit. */
++	__asm__ ("larl %3,%0; lsll %3,%1"
++		 : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
++	if ((~seg_ar & 0x9800) || eip > seg_limit) {
++		*eip_limit = 0;
++		return 1;	 /* So that returned eip > *eip_limit. */
++	}
++
++	/* Get the GDT/LDT descriptor base.
++	   When you look for races in this code remember that
++	   LDT and other horrors are only used in user space. */
++	if (seg & (1<<2)) {
++		/* Must lock the LDT while reading it. */
++		down(&current->mm->context.sem);
++#if 1
++		/* horrible hack for 4/4 disabled kernels.
++		   I'm not quite sure what the TLB flush is good for,
++		   it's mindlessly copied from the read_ldt code */
++		__flush_tlb_global();
++		desc = kmap(current->mm->context.ldt_pages[(seg & ~7)/PAGE_SIZE]);
++		desc = (void *)desc + ((seg & ~7) % PAGE_SIZE);
++#else
++		desc = current->mm->context.ldt;
++		desc = (void *)desc + (seg & ~7);
++#endif
++	} else {
++		/* Must disable preemption while reading the GDT. */
++		desc = (u32 *)&cpu_gdt_table[get_cpu()];
++		desc = (void *)desc + (seg & ~7);
++	}
++	base = (desc[0] >> 16) |
++		((desc[1] & 0xff) << 16) |
++		(desc[1] & 0xff000000);
++	if (seg & (1<<2)) {
++#if 1
++		kunmap((void *)((unsigned long)desc & PAGE_MASK));
++#endif
++		up(&current->mm->context.sem);
++	} else
++		put_cpu();
++
++	/* Adjust EIP and segment limit, and clamp at the kernel limit.
++	   It's legitimate for segments to wrap at 0xffffffff. */
++	seg_limit += base;
++	if (seg_limit < *eip_limit && seg_limit >= base)
++		*eip_limit = seg_limit;
++	return eip + base;
++}
++
++/*
++ * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
++ * Check that here and ignore it.
++ */
++static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++	unsigned long limit;
++	unsigned long instr = get_segment_eip (regs, &limit);
++	int scan_more = 1;
++	int prefetch = 0;
++	int i;
++
++	for (i = 0; scan_more && i < 15; i++) {
++		unsigned char opcode;
++		unsigned char instr_hi;
++		unsigned char instr_lo;
++
++		if (instr > limit)
++			break;
++		if (__get_user(opcode, (unsigned char *) instr))
++			break;
++
++		instr_hi = opcode & 0xf0;
++		instr_lo = opcode & 0x0f;
++		instr++;
++
++		switch (instr_hi) {
++		case 0x20:
++		case 0x30:
++			/* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */
++			scan_more = ((instr_lo & 7) == 0x6);
++			break;
++
++		case 0x60:
++			/* 0x64 thru 0x67 are valid prefixes in all modes. */
++			scan_more = (instr_lo & 0xC) == 0x4;
++			break;
++		case 0xF0:
++			/* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
++			scan_more = !instr_lo || (instr_lo>>1) == 1;
++			break;
++		case 0x00:
++			/* Prefetch instruction is 0x0F0D or 0x0F18 */
++			scan_more = 0;
++			if (instr > limit)
++				break;
++			if (__get_user(opcode, (unsigned char *) instr))
++				break;
++			prefetch = (instr_lo == 0xF) &&
++				(opcode == 0x0D || opcode == 0x18);
++			break;
++		default:
++			scan_more = 0;
++			break;
++		}
++	}
++
++#if 1
++	if (prefetch)
++		printk("prefetch handled at %lx eip %lx instr %lx cs %x\n",
++		       addr, regs->eip, instr, regs->xcs);
++#endif
++
++	return prefetch;
++}
++
++static inline int is_prefetch(struct pt_regs *regs, unsigned long addr)
++{
++	if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
++		     boot_cpu_data.x86 >= 6))
++		return __is_prefetch(regs, addr);
++	return 0;
++}
++
+ asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
+ 
+ /*
+@@ -86,6 +243,8 @@ asmlinkage void do_page_fault(struct pt_
+ 
+ 	tsk = current;
+ 
++	info.si_code = SEGV_MAPERR;
++
+ 	/*
+ 	 * We fault-in kernel-space virtual memory on-demand. The
+ 	 * 'reference' page table is init_mm.pgd.
+@@ -99,18 +258,26 @@ asmlinkage void do_page_fault(struct pt_
+ 	 * (error_code & 4) == 0, and that the fault was not a
+ 	 * protection error (error_code & 1) == 0.
+ 	 */
+-	if (address >= TASK_SIZE && !(error_code & 5))
++#ifdef CONFIG_X86_4G
++	/* On 4/4 all kernels faults are either bugs, vmalloc or prefetch */
++	if (unlikely((regs->xcs & 3) == 0))
+ 		goto vmalloc_fault;
++#else
++	if (unlikely(address >= TASK_SIZE)) {
++		if (!(error_code & 5))
++			goto vmalloc_fault;
++		goto bad_area_nosemaphore;
++	}
++#endif
+ 
+ 	mm = tsk->mm;
+-	info.si_code = SEGV_MAPERR;
+ 
+ 	/*
+ 	 * If we're in an interrupt, have no user context or are running in an
+ 	 * atomic region then we must not take the fault..
+ 	 */
+ 	if (in_atomic() || !mm)
+-		goto no_context;
++		goto bad_area_nosemaphore;
+ 
+ 	down_read(&mm->mmap_sem);
+ 
+@@ -198,8 +365,16 @@ good_area:
+ bad_area:
+ 	up_read(&mm->mmap_sem);
+ 
++bad_area_nosemaphore:
+ 	/* User mode accesses just cause a SIGSEGV */
+ 	if (error_code & 4) {
++		/*
++		 * Valid to do another page fault here because this one came
++		 * from user space.
++		 */
++		if (is_prefetch(regs, address))
++			return;
++
+ 		tsk->thread.cr2 = address;
+ 		tsk->thread.error_code = error_code;
+ 		tsk->thread.trap_no = 14;
+@@ -232,10 +407,24 @@ no_context:
+ 	if (fixup_exception(regs))
+ 		return;
+ 
++	/*
++	 * Valid to do another page fault here, because if this fault
++	 * had been triggered by is_prefetch fixup_exception would have
++	 * handled it.
++	 */
++ 	if (is_prefetch(regs, address))
++ 		return;
++
+ /*
+  * Oops. The kernel tried to access some bad page. We'll have to
+  * terminate things with extreme prejudice.
+  */
++#ifdef CONFIG_KGDB
++        if (!user_mode(regs)){
++                kgdb_handle_exception(14,SIGBUS, error_code, regs);
++                return;
++        }
++#endif
+ 
+ 	bust_spinlocks(1);
+ 
+@@ -286,10 +475,14 @@ out_of_memory:
+ do_sigbus:
+ 	up_read(&mm->mmap_sem);
+ 
+-	/*
+-	 * Send a sigbus, regardless of whether we were in kernel
+-	 * or user mode.
+-	 */
++	/* Kernel mode? Handle exceptions or die */
++	if (!(error_code & 4))
++		goto no_context;
++
++	/* User space => ok to do another page fault */
++	if (is_prefetch(regs, address))
++		return;
++
+ 	tsk->thread.cr2 = address;
+ 	tsk->thread.error_code = error_code;
+ 	tsk->thread.trap_no = 14;
+@@ -298,10 +491,6 @@ do_sigbus:
+ 	info.si_code = BUS_ADRERR;
+ 	info.si_addr = (void *)address;
+ 	force_sig_info(SIGBUS, &info, tsk);
+-
+-	/* Kernel mode? Handle exceptions or die */
+-	if (!(error_code & 4))
+-		goto no_context;
+ 	return;
+ 
+ vmalloc_fault:
+--- linux-2.6.0-test6/arch/i386/mm/init.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/mm/init.c	2003-10-05 00:36:48.000000000 -0700
+@@ -25,6 +25,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
++#include <linux/efi.h>
+ 
+ #include <asm/processor.h>
+ #include <asm/system.h>
+@@ -38,125 +39,13 @@
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
+ #include <asm/sections.h>
++#include <asm/desc.h>
+ 
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+ unsigned long highstart_pfn, highend_pfn;
+ 
+ static int do_test_wp_bit(void);
+ 
+-/*
+- * Creates a middle page table and puts a pointer to it in the
+- * given global directory entry. This only returns the gd entry
+- * in non-PAE compilation mode, since the middle layer is folded.
+- */
+-static pmd_t * __init one_md_table_init(pgd_t *pgd)
+-{
+-	pmd_t *pmd_table;
+-		
+-#ifdef CONFIG_X86_PAE
+-	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-	set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+-	if (pmd_table != pmd_offset(pgd, 0)) 
+-		BUG();
+-#else
+-	pmd_table = pmd_offset(pgd, 0);
+-#endif
+-
+-	return pmd_table;
+-}
+-
+-/*
+- * Create a page table and place a pointer to it in a middle page
+- * directory entry.
+- */
+-static pte_t * __init one_page_table_init(pmd_t *pmd)
+-{
+-	if (pmd_none(*pmd)) {
+-		pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-		set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
+-		if (page_table != pte_offset_kernel(pmd, 0))
+-			BUG();	
+-
+-		return page_table;
+-	}
+-	
+-	return pte_offset_kernel(pmd, 0);
+-}
+-
+-/*
+- * This function initializes a certain range of kernel virtual memory 
+- * with new bootmem page tables, everywhere page tables are missing in
+- * the given range.
+- */
+-
+-/*
+- * NOTE: The pagetables are allocated contiguous on the physical space 
+- * so we can cache the place of the first one and move around without 
+- * checking the pgd every time.
+- */
+-static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+-{
+-	pgd_t *pgd;
+-	pmd_t *pmd;
+-	int pgd_idx, pmd_idx;
+-	unsigned long vaddr;
+-
+-	vaddr = start;
+-	pgd_idx = pgd_index(vaddr);
+-	pmd_idx = pmd_index(vaddr);
+-	pgd = pgd_base + pgd_idx;
+-
+-	for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+-		if (pgd_none(*pgd)) 
+-			one_md_table_init(pgd);
+-
+-		pmd = pmd_offset(pgd, vaddr);
+-		for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
+-			if (pmd_none(*pmd)) 
+-				one_page_table_init(pmd);
+-
+-			vaddr += PMD_SIZE;
+-		}
+-		pmd_idx = 0;
+-	}
+-}
+-
+-/*
+- * This maps the physical memory to kernel virtual address space, a total 
+- * of max_low_pfn pages, by creating page tables starting from address 
+- * PAGE_OFFSET.
+- */
+-static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+-{
+-	unsigned long pfn;
+-	pgd_t *pgd;
+-	pmd_t *pmd;
+-	pte_t *pte;
+-	int pgd_idx, pmd_idx, pte_ofs;
+-
+-	pgd_idx = pgd_index(PAGE_OFFSET);
+-	pgd = pgd_base + pgd_idx;
+-	pfn = 0;
+-
+-	for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
+-		pmd = one_md_table_init(pgd);
+-		if (pfn >= max_low_pfn)
+-			continue;
+-		for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
+-			/* Map with big pages if possible, otherwise create normal page tables. */
+-			if (cpu_has_pse) {
+-				set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
+-				pfn += PTRS_PER_PTE;
+-			} else {
+-				pte = one_page_table_init(pmd);
+-
+-				for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++)
+-					set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
+-			}
+-		}
+-	}	
+-}
+-
+ static inline int page_kills_ppro(unsigned long pagenr)
+ {
+ 	if (pagenr >= 0x70000 && pagenr <= 0x7003F)
+@@ -164,12 +53,30 @@ static inline int page_kills_ppro(unsign
+ 	return 0;
+ }
+ 
++extern int is_available_memory(efi_memory_desc_t *);
++
+ static inline int page_is_ram(unsigned long pagenr)
+ {
+ 	int i;
++	unsigned long addr, end;
++
++	if (efi_enabled) {
++		efi_memory_desc_t *md;
++
++		for (i = 0; i < memmap.nr_map; i++) {
++			md = &memmap.map[i];
++			if (!is_available_memory(md))
++				continue;
++			addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
++			end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
++
++			if ((pagenr >= addr) && (pagenr < end))
++				return 1;
++		}
++		return 0;
++	}
+ 
+ 	for (i = 0; i < e820.nr_map; i++) {
+-		unsigned long addr, end;
+ 
+ 		if (e820.map[i].type != E820_RAM)	/* not usable memory */
+ 			continue;
+@@ -186,38 +93,14 @@ static inline int page_is_ram(unsigned l
+ 	return 0;
+ }
+ 
+-#ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+-pgprot_t kmap_prot;
+ 
+ #define kmap_get_fixmap_pte(vaddr)					\
+ 	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ 
+ void __init kmap_init(void)
+ {
+-	unsigned long kmap_vstart;
+-
+-	/* cache the first kmap pte */
+-	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+-	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+-
+-	kmap_prot = PAGE_KERNEL;
+-}
+-
+-void __init permanent_kmaps_init(pgd_t *pgd_base)
+-{
+-	pgd_t *pgd;
+-	pmd_t *pmd;
+-	pte_t *pte;
+-	unsigned long vaddr;
+-
+-	vaddr = PKMAP_BASE;
+-	page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+-
+-	pgd = swapper_pg_dir + pgd_index(vaddr);
+-	pmd = pmd_offset(pgd, vaddr);
+-	pte = pte_offset_kernel(pmd, vaddr);
+-	pkmap_page_table = pte;	
++	kmap_pte = kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
+ }
+ 
+ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+@@ -232,6 +115,8 @@ void __init one_highpage_init(struct pag
+ 		SetPageReserved(page);
+ }
+ 
++#ifdef CONFIG_HIGHMEM
++
+ #ifndef CONFIG_DISCONTIGMEM
+ void __init set_highmem_pages_init(int bad_ppro) 
+ {
+@@ -243,12 +128,9 @@ void __init set_highmem_pages_init(int b
+ #else
+ extern void set_highmem_pages_init(int);
+ #endif /* !CONFIG_DISCONTIGMEM */
+-
+ #else
+-#define kmap_init() do { } while (0)
+-#define permanent_kmaps_init(pgd_base) do { } while (0)
+-#define set_highmem_pages_init(bad_ppro) do { } while (0)
+-#endif /* CONFIG_HIGHMEM */
++# define set_highmem_pages_init(bad_ppro) do { } while (0)
++#endif
+ 
+ unsigned long __PAGE_KERNEL = _PAGE_KERNEL;
+ 
+@@ -258,30 +140,125 @@ unsigned long __PAGE_KERNEL = _PAGE_KERN
+ extern void __init remap_numa_kva(void);
+ #endif
+ 
+-static void __init pagetable_init (void)
++static __init void prepare_pagetables(pgd_t *pgd_base, unsigned long address)
++{
++	pgd_t *pgd;
++	pmd_t *pmd;
++	pte_t *pte;
++
++	pgd = pgd_base + pgd_index(address);
++	pmd = pmd_offset(pgd, address);
++	if (!pmd_present(*pmd)) {
++		pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
++	}
++}
++
++static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
++{
++	unsigned long vaddr;
++
++	for (vaddr = start; vaddr != end; vaddr += PAGE_SIZE)
++		prepare_pagetables(pgd_base, vaddr);
++}
++
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
+ {
+ 	unsigned long vaddr;
+-	pgd_t *pgd_base = swapper_pg_dir;
++	pgd_t *pgd;
++	int i, j, k;
++	pmd_t *pmd;
++	pte_t *pte, *pte_base;
++
++	pgd = pgd_base;
++
++	for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++		vaddr = i*PGDIR_SIZE;
++		if (end && (vaddr >= end))
++			break;
++		pmd = pmd_offset(pgd, 0);
++		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++			vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++			if (end && (vaddr >= end))
++				break;
++			if (vaddr < start)
++				continue;
++			if (cpu_has_pse) {
++				unsigned long __pe;
++
++				set_in_cr4(X86_CR4_PSE);
++				boot_cpu_data.wp_works_ok = 1;
++				__pe = _KERNPG_TABLE + _PAGE_PSE + vaddr - start;
++				/* Make it "global" too if supported */
++				if (cpu_has_pge) {
++					set_in_cr4(X86_CR4_PGE);
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
++					__pe += _PAGE_GLOBAL;
++					__PAGE_KERNEL |= _PAGE_GLOBAL;
++#endif
++				}
++				set_pmd(pmd, __pmd(__pe));
++				continue;
++			}
++			if (!pmd_present(*pmd))
++				pte_base = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++			else
++				pte_base = (pte_t *) page_address(pmd_page(*pmd));
++			pte = pte_base;
++			for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
++				vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
++				if (end && (vaddr >= end))
++					break;
++				if (vaddr < start)
++					continue;
++				*pte = mk_pte_phys(vaddr-start, PAGE_KERNEL);
++			}
++			set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
++		}
++	}
++}
+ 
++static void __init pagetable_init (void)
++{
++	unsigned long vaddr, end;
++	pgd_t *pgd_base;
+ #ifdef CONFIG_X86_PAE
+ 	int i;
+-	/* Init entries of the first-level page table to the zero page */
+-	for (i = 0; i < PTRS_PER_PGD; i++)
+-		set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
+ #endif
+ 
+-	/* Enable PSE if available */
+-	if (cpu_has_pse) {
+-		set_in_cr4(X86_CR4_PSE);
+-	}
++	/*
++	 * This can be zero as well - no problem, in that case we exit
++	 * the loops anyway due to the PTRS_PER_* conditions.
++	 */
++	end = (unsigned long)__va(max_low_pfn*PAGE_SIZE);
+ 
+-	/* Enable PGE if available */
+-	if (cpu_has_pge) {
+-		set_in_cr4(X86_CR4_PGE);
+-		__PAGE_KERNEL |= _PAGE_GLOBAL;
++	pgd_base = swapper_pg_dir;
++#ifdef CONFIG_X86_PAE
++	/*
++	 * It causes too many problems if there's no proper pmd set up
++	 * for all 4 entries of the PGD - so we allocate all of them.
++	 * PAE systems will not miss this extra 4-8K anyway ...
++	 */
++	for (i = 0; i < PTRS_PER_PGD; i++) {
++		pmd_t *pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++		set_pgd(pgd_base + i, __pgd(__pa(pmd) + 0x1));
+ 	}
++#endif
++	/*
++	 * Set up lowmem-sized identity mappings at PAGE_OFFSET:
++	 */
++	setup_identity_mappings(pgd_base, PAGE_OFFSET, end);
+ 
+-	kernel_physical_mapping_init(pgd_base);
++	/*
++	 * Add flat-mode identity-mappings - SMP needs it when
++	 * starting up on an AP from real-mode. (In the non-PAE
++	 * case we already have these mappings through head.S.)
++	 * All user-space mappings are explicitly cleared after
++	 * SMP startup.
++	 */
++#if CONFIG_SMP && CONFIG_X86_PAE
++	setup_identity_mappings(pgd_base, 0, 16*1024*1024);
++#endif
+ 	remap_numa_kva();
+ 
+ 	/*
+@@ -289,38 +266,64 @@ static void __init pagetable_init (void)
+ 	 * created - mappings will be set by set_fixmap():
+ 	 */
+ 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+-	page_table_range_init(vaddr, 0, pgd_base);
++	fixrange_init(vaddr, 0, pgd_base);
+ 
+-	permanent_kmaps_init(pgd_base);
++#if CONFIG_HIGHMEM
++	{
++		pgd_t *pgd;
++		pmd_t *pmd;
++		pte_t *pte;
+ 
+-#ifdef CONFIG_X86_PAE
+-	/*
+-	 * Add low memory identity-mappings - SMP needs it when
+-	 * starting up on an AP from real-mode. In the non-PAE
+-	 * case we already have these mappings through head.S.
+-	 * All user-space mappings are explicitly cleared after
+-	 * SMP startup.
+-	 */
+-	pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
++		/*
++		 * Permanent kmaps:
++		 */
++		vaddr = PKMAP_BASE;
++		fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
++
++		pgd = swapper_pg_dir + pgd_index(vaddr);
++		pmd = pmd_offset(pgd, vaddr);
++		pte = pte_offset_kernel(pmd, vaddr);
++		pkmap_page_table = pte;
++	}
+ #endif
+ }
+ 
+-void zap_low_mappings (void)
++/*
++ * Clear kernel pagetables in a PMD_SIZE-aligned range.
++ */
++static void clear_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
+ {
+-	int i;
++	unsigned long vaddr;
++	pgd_t *pgd;
++	pmd_t *pmd;
++	int i, j;
++
++	pgd = pgd_base;
++
++	for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++		vaddr = i*PGDIR_SIZE;
++		if (end && (vaddr >= end))
++			break;
++		pmd = pmd_offset(pgd, 0);
++		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++			vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++			if (end && (vaddr >= end))
++				break;
++			if (vaddr < start)
++				continue;
++			pmd_clear(pmd);
++		}
++	}
++	flush_tlb_all();
++}
++
++void __init zap_low_mappings(void)
++{
++	printk("zapping low mappings.\n");
+ 	/*
+ 	 * Zap initial low-memory mappings.
+-	 *
+-	 * Note that "pgd_clear()" doesn't do it for
+-	 * us, because pgd_clear() is a no-op on i386.
+ 	 */
+-	for (i = 0; i < USER_PTRS_PER_PGD; i++)
+-#ifdef CONFIG_X86_PAE
+-		set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
+-#else
+-		set_pgd(swapper_pg_dir+i, __pgd(0));
+-#endif
+-	flush_tlb_all();
++	clear_mappings(swapper_pg_dir, 0, 16*1024*1024);
+ }
+ 
+ #ifndef CONFIG_DISCONTIGMEM
+@@ -424,6 +427,7 @@ extern void set_max_mapnr_init(void);
+ #endif /* !CONFIG_DISCONTIGMEM */
+ 
+ static struct kcore_list kcore_mem, kcore_vmalloc; 
++extern void fixup_sort_exception_table(void);
+ 
+ void __init mem_init(void)
+ {
+@@ -432,6 +436,8 @@ void __init mem_init(void)
+ 	int tmp;
+ 	int bad_ppro;
+ 
++	fixup_sort_exception_table();
++
+ #ifndef CONFIG_DISCONTIGMEM
+ 	if (!mem_map)
+ 		BUG();
+@@ -507,13 +513,18 @@ void __init mem_init(void)
+ #ifndef CONFIG_SMP
+ 	zap_low_mappings();
+ #endif
++	entry_trampoline_setup();
++	default_ldt_page = virt_to_page(default_ldt);
++	load_LDT(&init_mm.context);
+ }
+ 
+-kmem_cache_t *pgd_cache;
+-kmem_cache_t *pmd_cache;
++kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+ 
+ void __init pgtable_cache_init(void)
+ {
++	void (*ctor)(void *, kmem_cache_t *, unsigned long);
++	void (*dtor)(void *, kmem_cache_t *, unsigned long);
++
+ 	if (PTRS_PER_PMD > 1) {
+ 		pmd_cache = kmem_cache_create("pmd",
+ 					PTRS_PER_PMD*sizeof(pmd_t),
+@@ -523,13 +534,36 @@ void __init pgtable_cache_init(void)
+ 					NULL);
+ 		if (!pmd_cache)
+ 			panic("pgtable_cache_init(): cannot create pmd cache");
++
++		if (TASK_SIZE > PAGE_OFFSET) {
++			kpmd_cache = kmem_cache_create("kpmd",
++					PTRS_PER_PMD*sizeof(pmd_t),
++					0,
++					SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
++					kpmd_ctor,
++					NULL);
++			if (!kpmd_cache)
++				panic("pgtable_cache_init(): "
++						"cannot create kpmd cache");
++		}
+ 	}
++
++	if (PTRS_PER_PMD == 1 || TASK_SIZE <= PAGE_OFFSET)
++		ctor = pgd_ctor;
++	else
++		ctor = NULL;
++
++	if (PTRS_PER_PMD == 1 && TASK_SIZE <= PAGE_OFFSET)
++		dtor = pgd_dtor;
++	else
++		dtor = NULL;
++
+ 	pgd_cache = kmem_cache_create("pgd",
+ 				PTRS_PER_PGD*sizeof(pgd_t),
+ 				0,
+ 				SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
+-				pgd_ctor,
+-				PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
++				ctor,
++				dtor);
+ 	if (!pgd_cache)
+ 		panic("pgtable_cache_init(): Cannot create pgd cache");
+ }
+--- linux-2.6.0-test6/arch/i386/mm/ioremap.c	2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/i386/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -158,7 +158,7 @@ void * __ioremap(unsigned long phys_addr
+ 		return NULL;
+ 	area->phys_addr = phys_addr;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vunmap(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/i386/mm/pgtable.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/mm/pgtable.c	2003-10-05 00:36:48.000000000 -0700
+@@ -21,6 +21,7 @@
+ #include <asm/e820.h>
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+ 
+ void show_mem(void)
+ {
+@@ -157,11 +158,20 @@ void pmd_ctor(void *pmd, kmem_cache_t *c
+ 	memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+ }
+ 
++void kpmd_ctor(void *__pmd, kmem_cache_t *cache, unsigned long flags)
++{
++	pmd_t *kpmd, *pmd;
++	kpmd = pmd_offset(&swapper_pg_dir[PTRS_PER_PGD-1],
++				(PTRS_PER_PMD - NR_SHARED_PMDS)*PMD_SIZE);
++	pmd = (pmd_t *)__pmd + (PTRS_PER_PMD - NR_SHARED_PMDS);
++
++	memset(__pmd, 0, (PTRS_PER_PMD - NR_SHARED_PMDS)*sizeof(pmd_t));
++	memcpy(pmd, kpmd, NR_SHARED_PMDS*sizeof(pmd_t));
++}
++
+ /*
+- * List of all pgd's needed for non-PAE so it can invalidate entries
+- * in both cached and uncached pgd's; not needed for PAE since the
+- * kernel pmd is shared. If PAE were not to share the pmd a similar
+- * tactic would be needed. This is essentially codepath-based locking
++ * List of all pgd's needed so it can invalidate entries in both cached
++ * and uncached pgd's. This is essentially codepath-based locking
+  * against pageattr.c; it is the unique case in which a valid change
+  * of kernel pagetables can't be lazily synchronized by vmalloc faults.
+  * vmalloc faults work because attached pagetables are never freed.
+@@ -170,30 +180,60 @@ void pmd_ctor(void *pmd, kmem_cache_t *c
+  * could be used. The locking scheme was chosen on the basis of
+  * manfred's recommendations and having no core impact whatsoever.
+  * -- wli
++ *
++ * The entire issue goes away when XKVA is configured.
+  */
+ spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(pgd_list);
+ 
+-void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
++/*
++ * This is not that hard to figure out.
++ * (a) PTRS_PER_PMD == 1 means non-PAE.
++ * (b) PTRS_PER_PMD > 1 means PAE.
++ * (c) TASK_SIZE > PAGE_OFFSET means XKVA.
++ * (d) TASK_SIZE <= PAGE_OFFSET means non-XKVA.
++ *
++ * Do *NOT* back out the preconstruction like the patch I'm cleaning
++ * up after this very instant did, or at all, for that matter.
++ * This is never called when PTRS_PER_PMD > 1 && TASK_SIZE > PAGE_OFFSET.
++ * -- wli
++ */
++void pgd_ctor(void *__pgd, kmem_cache_t *cache, unsigned long unused)
+ {
++	pgd_t *pgd = (pgd_t *)__pgd;
+ 	unsigned long flags;
+ 
+-	if (PTRS_PER_PMD == 1)
+-		spin_lock_irqsave(&pgd_lock, flags);
++	if (PTRS_PER_PMD == 1) {
++		if (TASK_SIZE <= PAGE_OFFSET)
++			spin_lock_irqsave(&pgd_lock, flags);
++		else
++ 			memcpy(&pgd[PTRS_PER_PGD - NR_SHARED_PMDS],
++ 				&swapper_pg_dir[PTRS_PER_PGD - NR_SHARED_PMDS],
++ 				NR_SHARED_PMDS * sizeof(pgd_t));
++	}
+ 
+-	memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+-			swapper_pg_dir + USER_PTRS_PER_PGD,
+-			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++	if (TASK_SIZE <= PAGE_OFFSET)
++ 		memcpy(pgd + USER_PTRS_PER_PGD,
++ 			swapper_pg_dir + USER_PTRS_PER_PGD,
++ 			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+ 
+ 	if (PTRS_PER_PMD > 1)
+ 		return;
+ 
+-	list_add(&virt_to_page(pgd)->lru, &pgd_list);
+-	spin_unlock_irqrestore(&pgd_lock, flags);
+-	memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++	if (TASK_SIZE > PAGE_OFFSET)
++		memset(pgd, 0, (PTRS_PER_PGD - NR_SHARED_PMDS)*sizeof(pgd_t));
++	else {
++		list_add(&virt_to_page(pgd)->lru, &pgd_list);
++		spin_unlock_irqrestore(&pgd_lock, flags);
++		memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++	}
+ }
+ 
+-/* never called when PTRS_PER_PMD > 1 */
++/*
++ * Never called when PTRS_PER_PMD > 1 || TASK_SIZE > PAGE_OFFSET
++ * for with PAE we would list_del() multiple times, and for non-PAE
++ * with XKVA all the AGP pgd shootdown code is unnecessary.
++ */
+ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+ {
+ 	unsigned long flags; /* can be called from interrupt context */
+@@ -203,6 +243,12 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
+ 	spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+ 
++/*
++ * See the comments above pgd_ctor() wrt. preconstruction.
++ * Do *NOT* memcpy() here. If you do, you back out important
++ * anti- cache pollution code.
++ *
++ */
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+ 	int i;
+@@ -211,15 +257,33 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+ 	if (PTRS_PER_PMD == 1 || !pgd)
+ 		return pgd;
+ 
++	/*
++	 * In the 4G userspace case alias the top 16 MB virtual
++	 * memory range into the user mappings as well (these
++	 * include the trampoline and CPU data structures).
++	 */
+ 	for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+-		pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++		kmem_cache_t *cache;
++		pmd_t *pmd;
++
++		if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++			cache = kpmd_cache;
++		else
++			cache = pmd_cache;
++
++		pmd = kmem_cache_alloc(cache, GFP_KERNEL);
+ 		if (!pmd)
+ 			goto out_oom;
+ 		set_pgd(&pgd[i], __pgd(1 + __pa((u64)((u32)pmd))));
+ 	}
+-	return pgd;
+ 
++	return pgd;
+ out_oom:
++	/*
++	 * we don't have to handle the kpmd_cache here, since it's the
++	 * last allocation, and has either nothing to free or when it
++	 * succeeds the whole operation succeeds.
++	 */
+ 	for (i--; i >= 0; i--)
+ 		kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+ 	kmem_cache_free(pgd_cache, pgd);
+@@ -230,10 +294,29 @@ void pgd_free(pgd_t *pgd)
+ {
+ 	int i;
+ 
+-	/* in the PAE case user pgd entries are overwritten before usage */
+-	if (PTRS_PER_PMD > 1)
+-		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
+-			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+ 	/* in the non-PAE case, clear_page_tables() clears user pgd entries */
++	if (PTRS_PER_PMD == 1)
++		goto out_free;
++
++	/* in the PAE case user pgd entries are overwritten before usage */
++	for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
++		kmem_cache_t *cache;
++		pmd_t *pmd = __va(pgd_val(pgd[i]) - 1);
++
++		/*
++		 * only userspace pmd's are cleared for us
++		 * by mm/memory.c; it's a slab cache invariant
++		 * that we must separate the kernel pmd slab
++		 * all times, else we'll have bad pmd's.
++		 */
++		if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++			cache = kpmd_cache;
++		else
++			cache = pmd_cache;
++
++		kmem_cache_free(cache, pmd);
++	}
++out_free:
+ 	kmem_cache_free(pgd_cache, pgd);
+ }
++
+--- linux-2.6.0-test6/arch/i386/pci/acpi.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/pci/acpi.c	2003-10-05 00:34:16.000000000 -0700
+@@ -15,10 +15,11 @@ struct pci_bus * __devinit pci_acpi_scan
+ 
+ static int __init pci_acpi_init(void)
+ {
++	extern int acpi_disabled;
+ 	if (pcibios_scanned)
+ 		return 0;
+ 
+-	if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
++	if (!(pci_probe & PCI_NO_ACPI_ROUTING) && !acpi_disabled) {
+ 		if (!acpi_pci_irq_init()) {
+ 			printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+ 			printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n");
+--- linux-2.6.0-test6/arch/i386/pci/irq.c	2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/pci/irq.c	2003-10-05 00:36:20.000000000 -0700
+@@ -680,8 +680,10 @@ static int pcibios_lookup_irq(struct pci
+ 		    	if ( dev2->irq && dev2->irq != irq && \
+ 			(!(pci_probe & PCI_USE_PIRQ_MASK) || \
+ 			((1 << dev2->irq) & mask)) ) {
++#ifndef CONFIG_PCI_USE_VECTOR
+ 		    		printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
+ 				       pci_name(dev2), dev2->irq, irq);
++#endif
+ 		    		continue;
+ 		    	}
+ 			dev2->irq = irq;
+@@ -745,6 +747,10 @@ static void __init pcibios_fixup_irqs(vo
+ 							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+ 				}
+ 				if (irq >= 0) {
++					if (use_pci_vector() &&
++						!platform_legacy_irq(irq))
++						irq = IO_APIC_VECTOR(irq);
++
+ 					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+ 						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+ 					dev->irq = irq;
+--- linux-2.6.0-test6/arch/ia64/ia32/ia32_ioctl.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/ia64/ia32/ia32_ioctl.c	2003-10-05 00:34:44.000000000 -0700
+@@ -26,43 +26,11 @@
+ 	_ret;						\
+ })
+ 
+-#define P(i)	((void *)(unsigned long)(i))
+-
+ asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+ 
+ #define CODE
+ #include "compat_ioctl.c"
+ 
+-#define	VFAT_IOCTL_READDIR_BOTH32	_IOR('r', 1, struct linux32_dirent[2])
+-#define	VFAT_IOCTL_READDIR_SHORT32	_IOR('r', 2, struct linux32_dirent[2])
+-
+-static long
+-put_dirent32 (struct dirent *d, struct linux32_dirent *d32)
+-{
+-	size_t namelen = strlen(d->d_name);
+-
+-	return (put_user(d->d_ino, &d32->d_ino)
+-		|| put_user(d->d_off, &d32->d_off)
+-		|| put_user(d->d_reclen, &d32->d_reclen)
+-		|| copy_to_user(d32->d_name, d->d_name, namelen + 1));
+-}
+-
+-static int vfat_ioctl32(unsigned fd, unsigned cmd,  void *ptr) 
+-{
+-	int ret;
+-	mm_segment_t oldfs = get_fs();
+-	struct dirent d[2]; 
+-
+-	set_fs(KERNEL_DS);
+-	ret = sys_ioctl(fd,cmd,(unsigned long)&d); 
+-	set_fs(oldfs); 
+-	if (!ret) { 
+-		ret |= put_dirent32(&d[0], (struct linux32_dirent *)ptr); 
+-		ret |= put_dirent32(&d[1], ((struct linux32_dirent *)ptr) + 1); 
+-	}
+-	return ret; 
+-} 
+-
+ typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
+ 
+ #define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
+@@ -73,8 +41,6 @@ typedef int (* ioctl32_handler_t)(unsign
+ 	};
+ 
+ IOCTL_TABLE_START
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
+ #define DECLARES
+ #include "compat_ioctl.c"
+ #include <linux/compat_ioctl.h>
+--- linux-2.6.0-test6/arch/ia64/ia32/ia32priv.h	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/ia32/ia32priv.h	2003-10-05 00:34:44.000000000 -0700
+@@ -249,13 +249,6 @@ typedef struct siginfo32 {
+ 	} _sifields;
+ } siginfo_t32;
+ 
+-struct linux32_dirent {
+-	u32	d_ino;
+-	u32	d_off;
+-	u16	d_reclen;
+-	char	d_name[256];
+-};
+-
+ struct old_linux32_dirent {
+ 	u32	d_ino;
+ 	u32	d_offset;
+--- linux-2.6.0-test6/arch/ia64/ia32/sys_ia32.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/ia32/sys_ia32.c	2003-10-05 00:34:44.000000000 -0700
+@@ -707,8 +707,8 @@ sys32_settimeofday (struct compat_timeva
+ }
+ 
+ struct getdents32_callback {
+-	struct linux32_dirent * current_dir;
+-	struct linux32_dirent * previous;
++	struct compat_dirent * current_dir;
++	struct compat_dirent * previous;
+ 	int count;
+ 	int error;
+ };
+@@ -722,7 +722,7 @@ static int
+ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
+ 	   unsigned int d_type)
+ {
+-	struct linux32_dirent * dirent;
++	struct compat_dirent * dirent;
+ 	struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
+ 	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+ 
+@@ -748,10 +748,10 @@ filldir32 (void *__buf, const char *name
+ }
+ 
+ asmlinkage long
+-sys32_getdents (unsigned int fd, struct linux32_dirent *dirent, unsigned int count)
++sys32_getdents (unsigned int fd, struct compat_dirent *dirent, unsigned int count)
+ {
+ 	struct file * file;
+-	struct linux32_dirent * lastdirent;
++	struct compat_dirent * lastdirent;
+ 	struct getdents32_callback buf;
+ 	int error;
+ 
+--- linux-2.6.0-test6/arch/ia64/kernel/acpi.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/kernel/acpi.c	2003-10-05 00:34:41.000000000 -0700
+@@ -41,6 +41,7 @@
+ #include <linux/irq.h>
+ #include <linux/acpi.h>
+ #include <linux/efi.h>
++#include <linux/mmzone.h>
+ #include <asm/io.h>
+ #include <asm/iosapic.h>
+ #include <asm/machvec.h>
+@@ -56,7 +57,7 @@ void (*pm_power_off) (void);
+ 
+ unsigned char acpi_kbd_controller_present = 1;
+ 
+-int acpi_disabled __initdata;	/* XXX this shouldn't be needed---we can't boot without ACPI! */
++int acpi_disabled;	/* XXX this shouldn't be needed---we can't boot without ACPI! */
+ 
+ const char *
+ acpi_get_sysname (void)
+@@ -341,7 +342,7 @@ static u32 __initdata pxm_flag[PXM_FLAG_
+ #define pxm_bit_test(bit)	(test_bit(bit,(void *)pxm_flag))
+ /* maps to convert between proximity domain and logical node ID */
+ int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+-int __initdata nid_to_pxm_map[NR_NODES];
++int __initdata nid_to_pxm_map[MAX_NUMNODES];
+ static struct acpi_table_slit __initdata *slit_table;
+ 
+ /*
+--- linux-2.6.0-test6/arch/ia64/kernel/perfmon.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/kernel/perfmon.c	2003-10-05 00:34:03.000000000 -0700
+@@ -2165,6 +2165,7 @@ pfm_alloc_fd(struct file **cfile)
+ 
+ 	d_add(file->f_dentry, inode);
+ 	file->f_vfsmnt = mntget(pfmfs_mnt);
++	file->f_mapping = inode->i_mapping;
+ 
+ 	file->f_op    = &pfm_file_ops;
+ 	file->f_mode  = FMODE_READ;
+--- linux-2.6.0-test6/arch/ia64/kernel/unaligned.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/ia64/kernel/unaligned.c	2003-10-05 00:36:18.000000000 -0700
+@@ -1347,7 +1347,7 @@ ia64_handle_unaligned (unsigned long ifa
+ 			 * be holding locks...
+ 			 */
+ 			if (user_mode(regs))
+-				tty_write_message(current->tty, buf);
++				tty_write_message(process_tty(current), buf);
+ 			buf[len-1] = '\0';	/* drop '\r' */
+ 			printk(KERN_WARNING "%s", buf);	/* watch for command names containing %s */
+ 		}
+--- linux-2.6.0-test6/arch/ia64/mm/discontig.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/mm/discontig.c	2003-10-05 00:34:41.000000000 -0700
+@@ -14,7 +14,6 @@
+ #include <linux/mm.h>
+ #include <linux/swap.h>
+ #include <linux/bootmem.h>
+-#include <linux/mmzone.h>
+ #include <linux/acpi.h>
+ #include <linux/efi.h>
+ #include <asm/pgalloc.h>
+@@ -26,10 +25,10 @@
+  */
+ #define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+ 
+-static struct ia64_node_data	*node_data[NR_NODES];
+-static long			boot_pg_data[8*NR_NODES+sizeof(pg_data_t)]  __initdata;
+-static pg_data_t		*pg_data_ptr[NR_NODES] __initdata;
+-static bootmem_data_t		bdata[NR_NODES][NR_BANKS_PER_NODE+1] __initdata;
++static struct ia64_node_data	*node_data[MAX_NUMNODES];
++static long			boot_pg_data[8*MAX_NUMNODES+sizeof(pg_data_t)]  __initdata;
++static pg_data_t		*pg_data_ptr[MAX_NUMNODES] __initdata;
++static bootmem_data_t		bdata[MAX_NUMNODES][NR_BANKS_PER_NODE+1] __initdata;
+ /*
+  * Return the compact node number of this cpu. Used prior to
+  * setting up the cpu_data area.
+--- linux-2.6.0-test6/arch/ia64/mm/numa.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/ia64/mm/numa.c	2003-10-05 00:34:41.000000000 -0700
+@@ -15,7 +15,6 @@
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <linux/bootmem.h>
+-#include <linux/mmzone.h>
+ #include <asm/numa.h>
+ 
+ /*
+@@ -29,7 +28,7 @@ struct node_cpuid_s node_cpuid[NR_CPUS];
+  * This is a matrix with "distances" between nodes, they should be
+  * proportional to the memory access latency ratios.
+  */
+-u8 numa_slit[NR_NODES * NR_NODES];
++u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
+ 
+ /* Identify which cnode a physical address resides on */
+ int
+--- linux-2.6.0-test6/arch/ia64/sn/io/sn2/module.c	2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/ia64/sn/io/sn2/module.c	2003-10-05 00:33:23.000000000 -0700
+@@ -166,7 +166,6 @@ int module_probe_snum(module_t *m, nasid
+ {
+     lboard_t	       *board;
+     klmod_serial_num_t *comp;
+-    char * bcopy(const char * src, char * dest, int count);
+     char serial_number[16];
+ 
+     /*
+@@ -215,9 +214,9 @@ int module_probe_snum(module_t *m, nasid
+ #endif
+ 
+ 	    if (comp->snum.snum_str[0] != '\0') {
+-		bcopy(comp->snum.snum_str,
+-		      m->sys_snum,
+-		      MAX_SERIAL_NUM_SIZE);
++		memcpy(m->sys_snum,
++		       comp->snum.snum_str,
++		       MAX_SERIAL_NUM_SIZE);
+ 		m->sys_snum_valid = 1;
+ 	    }
+     }
+--- linux-2.6.0-test6/arch/ia64/sn/io/sn2/pic.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ia64/sn/io/sn2/pic.c	2003-10-05 00:33:23.000000000 -0700
+@@ -29,8 +29,6 @@
+ #include <asm/sn/io.h>
+ #include <asm/sn/sn_private.h>
+ 
+-extern char *bcopy(const char * src, char * dest, int count);
+-
+ 
+ #define PCI_BUS_NO_1 1
+ 
+@@ -51,7 +49,7 @@ pic_bus1_inventory_dup(vertex_hdl_t conn
+ 				(arbitrary_info_t *)&pinv) == GRAPH_SUCCESS)
+  {
+ 		NEW(peer_pinv);
+-		bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t));
++		memcpy(peer_pinv, pinv, sizeof(inventory_t));
+ 		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT,
+ 			    (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) {
+ 			DEL(peer_pinv);
+--- linux-2.6.0-test6/arch/m68k/atari/stram.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/m68k/atari/stram.c	2003-10-05 00:33:23.000000000 -0700
+@@ -22,6 +22,7 @@
+ #include <linux/shm.h>
+ #include <linux/bootmem.h>
+ #include <linux/mount.h>
++#include <linux/blkdev.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/machdep.h>
+--- linux-2.6.0-test6/arch/m68k/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/m68k/Kconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -87,7 +87,7 @@ config ATARI
+ 
+ config HADES
+ 	bool "Hades support"
+-	depends on ATARI
++	depends on ATARI && BROKEN
+ 	help
+ 	  This option enables support for the Hades Atari clone. If you plan
+ 	  to use this kernel on a Hades, say Y here; otherwise say N.
+@@ -361,7 +361,7 @@ config AMIGA_PCMCIA
+ 
+ config STRAM_SWAP
+ 	bool "Support for ST-RAM as swap space"
+-	depends on ATARI
++	depends on ATARI && BROKEN
+ 	---help---
+ 	  Some Atari 68k macines (including the 520STF and 1020STE) divide
+ 	  their addressible memory into ST and TT sections.  The TT section
+@@ -961,7 +961,7 @@ config MVME147_SCC
+ 
+ config SERIAL167
+ 	bool "CD2401 support for MVME166/7 serial ports"
+-	depends on MVME16x
++	depends on MVME16x && BROKEN
+ 	help
+ 	  This is the driver for the serial ports on the Motorola MVME166,
+ 	  167, and 172 boards.  Everyone using one of these boards should say
+--- linux-2.6.0-test6/arch/m68k/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/m68k/kernel/time.c	2003-10-05 00:33:23.000000000 -0700
+@@ -171,3 +171,12 @@ int do_settimeofday(struct timespec *tv)
+ 	write_sequnlock_irq(&xtime_lock);
+ 	return 0;
+ }
++
++/*
++ * Scheduler clock - returns current time in ns units.
++ */
++unsigned long long sched_clock(void)
++{
++       return (unsigned long long)jiffies*(1000000000/HZ);
++}
++
+--- linux-2.6.0-test6/arch/m68k/Makefile	2003-07-27 12:14:38.000000000 -0700
++++ 25/arch/m68k/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -76,6 +76,8 @@ core-$(CONFIG_M68040)		+= arch/m68k/fpsp
+ core-$(CONFIG_M68060)		+= arch/m68k/ifpsp060/
+ core-$(CONFIG_M68KFPU_EMU)	+= arch/m68k/math-emu/
+ 
++all:	zImage
++
+ lilo:	vmlinux
+ 	if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
+ 	if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
+--- linux-2.6.0-test6/arch/m68k/q40/q40ints.c	2003-07-27 12:14:38.000000000 -0700
++++ 25/arch/m68k/q40/q40ints.c	2003-10-05 00:33:23.000000000 -0700
+@@ -200,7 +200,9 @@ void q40_free_irq(unsigned int irq, void
+ 
+ irqreturn_t q40_process_int (int level, struct pt_regs *fp)
+ {
+-  printk("unexpected interrupt %x\n",level);
++  printk("unexpected interrupt vec=%x, pc=%lx, d0=%lx, d0_orig=%lx, d1=%lx, d2=%lx\n",
++          level, fp->pc, fp->d0, fp->orig_d0, fp->d1, fp->d2);
++  printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG));
+   return IRQ_HANDLED;
+ }
+ 
+@@ -378,7 +380,7 @@ irqreturn_t q40_irq2_handler (int vec, v
+ 				  /*printk("reenabling irq %d\n",irq); */
+ #endif
+ 			  }
+-// used to do 'goto repeat;' her, this delayed bh processing too long
++// used to do 'goto repeat;' here, this delayed bh processing too long
+ 			  return IRQ_HANDLED;
+ 		  }
+ 	  }
+@@ -387,6 +389,7 @@ irqreturn_t q40_irq2_handler (int vec, v
+   } 
+  iirq:
+   mir=master_inb(IIRQ_REG);
++  /* should test whether keyboard irq is really enabled, doing it in defhand */
+   if (mir&Q40_IRQ_KEYB_MASK) {
+ 	  irq_tab[Q40_IRQ_KEYBOARD].count++;
+ 	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
+@@ -413,7 +416,9 @@ int show_q40_interrupts (struct seq_file
+ 
+ static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
+ {
+-	printk ("Unknown q40 interrupt 0x%02x\n", irq);
++        if (irq!=Q40_IRQ_KEYBOARD)
++	     printk ("Unknown q40 interrupt %d\n", irq);
++	else master_outb(-1,KEYBOARD_UNLOCK_REG);
+ 	return IRQ_NONE;
+ }
+ static irqreturn_t sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
+--- linux-2.6.0-test6/arch/m68k/sun3/config.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/m68k/sun3/config.c	2003-10-05 00:33:23.000000000 -0700
+@@ -129,7 +129,7 @@ void __init sun3_bootmem_alloc(unsigned 
+ 	high_memory = (void *)memory_end;
+ 	availmem = memory_start;
+ 
+-	availmem += init_bootmem(start_page, num_pages);
++	availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
+ 	availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
+ 
+ 	free_bootmem(__pa(availmem), memory_end - (availmem));
+--- linux-2.6.0-test6/arch/mips/mm/ioremap.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/arch/mips/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -162,7 +162,7 @@ void * __ioremap(phys_t phys_addr, phys_
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vunmap(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/parisc/Kconfig	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/Kconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -150,6 +150,7 @@ config COMPAT
+ 
+ config HPUX
+ 	bool "Support for HP-UX binaries"
++	depends on !PARISC64
+ 
+ config NR_CPUS
+ 	int "Maximum number of CPUs (2-32)"
+@@ -190,6 +191,8 @@ source drivers/message/fusion/Kconfig
+ 
+ #source drivers/message/i2o/Kconfig
+ 
++source "net/Kconfig"
++
+ #source "drivers/isdn/Kconfig"
+ 
+ #source "drivers/telephony/Kconfig"
+--- linux-2.6.0-test6/arch/parisc/kernel/asm-offsets.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/parisc/kernel/asm-offsets.c	2003-10-05 00:33:23.000000000 -0700
+@@ -8,6 +8,7 @@
+ #include <linux/sched.h>
+ #include <linux/thread_info.h>
+ #include <linux/version.h>
++#include <linux/ptrace.h>
+ 
+ #include <asm/ptrace.h>
+ #include <asm/processor.h>
+@@ -249,5 +250,8 @@ int main(void)
+ 	DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
+ 	DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
+ 	BLANK();
++	DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT);
++	DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT);
++	BLANK();
+ 	return 0;
+ }
+--- linux-2.6.0-test6/arch/parisc/kernel/binfmt_elf32.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/parisc/kernel/binfmt_elf32.c	2003-10-05 00:33:23.000000000 -0700
+@@ -88,7 +88,9 @@ struct elf_prpsinfo32
+  */
+ 
+ #define SET_PERSONALITY(ex, ibcs2) \
+-	current->personality = PER_LINUX_32BIT
++	current->personality = PER_LINUX32; \
++	current->thread.map_base = DEFAULT_MAP_BASE32; \
++	current->thread.task_size = DEFAULT_TASK_SIZE32 \
+ 
+ #define jiffies_to_timeval jiffies_to_compat_timeval 
+ static __inline__ void
+@@ -99,3 +101,25 @@ jiffies_to_compat_timeval(unsigned long 
+ }
+ 
+ #include "../../../fs/binfmt_elf.c"
++
++/* Set up a separate execution domain for ELF32 binaries running
++ * on an ELF64 kernel */
++
++static struct exec_domain parisc32_exec_domain = { 
++	.name = "Linux/ELF32",
++	.pers_low = PER_LINUX32,
++	.pers_high = PER_LINUX32,
++};      
++
++static int __init parisc32_exec_init(void)
++{
++	/* steal the identity signal mappings from the default domain */
++	parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
++	parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
++
++	register_exec_domain(&parisc32_exec_domain);
++
++	return 0;
++}
++
++__initcall(parisc32_exec_init);
+--- linux-2.6.0-test6/arch/parisc/kernel/drivers.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/drivers.c	2003-10-05 00:33:23.000000000 -0700
+@@ -28,6 +28,7 @@
+ 
+ /* See comments in include/asm-parisc/pci.h */
+ struct hppa_dma_ops *hppa_dma_ops;
++EXPORT_SYMBOL(hppa_dma_ops);
+ 
+ static struct parisc_device root;
+ 
+@@ -155,6 +156,7 @@ int register_parisc_driver(struct parisc
+ 
+ 	return driver_register(&driver->drv);
+ }
++EXPORT_SYMBOL(register_parisc_driver);
+ 
+ /**
+  * count_parisc_driver - count # of devices this driver would match
+@@ -187,6 +189,7 @@ int unregister_parisc_driver(struct pari
+ 	driver_unregister(&driver->drv);
+ 	return 0;
+ }
++EXPORT_SYMBOL(unregister_parisc_driver);
+ 
+ static struct parisc_device *find_device_by_addr(unsigned long hpa)
+ {
+@@ -257,7 +260,7 @@ char *print_pa_hwpath(struct parisc_devi
+ 	path.mod = dev->hw_path;
+ 	return print_hwpath(&path, output);
+ }
+-
++EXPORT_SYMBOL(print_pa_hwpath);
+ 
+ #if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+ /**
+@@ -289,6 +292,7 @@ void get_pci_node_path(struct pci_dev *d
+ 		padev = padev->parent;
+ 	}
+ }
++EXPORT_SYMBOL(get_pci_node_path);
+ 
+ /**
+  * print_pci_hwpath - Returns hardware path for PCI devices
+@@ -306,6 +310,8 @@ char *print_pci_hwpath(struct pci_dev *d
+ 	get_pci_node_path(dev, &path);
+ 	return print_hwpath(&path, output);
+ }
++EXPORT_SYMBOL(print_pci_hwpath);
++
+ #endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
+ 
+ 
+--- linux-2.6.0-test6/arch/parisc/kernel/entry.S	2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/parisc/kernel/entry.S	2003-10-05 00:33:23.000000000 -0700
+@@ -2225,18 +2225,23 @@ syscall_exit:
+ 	LDREG     TI_TASK(%r1),%r1
+ 	STREG     %r28,TASK_PT_GR28(%r1)
+ 
+-	/* Save other hpux returns if personality is PER_HPUX */
++#ifdef CONFIG_HPUX
+ 
+ /* <linux/personality.h> cannot be easily included */
+ #define PER_HPUX 0x10
+ 	LDREG     TASK_PERSONALITY(%r1),%r19
+-#warning the ldo+CMPIB could probably be done better but 0x10 i soutside of range of CMPIB
++
++	/* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
+ 	ldo	  -PER_HPUX(%r19), %r19
+ 	CMPIB<>,n 0,%r19,1f
++
++	/* Save other hpux returns if personality is PER_HPUX */
+ 	STREG     %r22,TASK_PT_GR22(%r1)
+ 	STREG     %r29,TASK_PT_GR29(%r1)
+ 1:
+ 
++#endif /* CONFIG_HPUX */
++
+ 	/* Seems to me that dp could be wrong here, if the syscall involved
+ 	 * calling a module, and nothing got round to restoring dp on return.
+ 	 */
+@@ -2315,18 +2320,16 @@ syscall_restore:
+ 	depi	3,31,2,%r31			   /* ensure return to user mode. */
+ 
+ #ifdef __LP64__
+-	/* Since we are returning to a 32 bit user process, we always
+-	 * clear the W bit. This means that the be (and mtsp) gets
+-	 * executed in narrow mode, but that is OK, since we are
+-	 * returning to a 32 bit process. When we support 64 bit processes
+-	 * we won't clear the W bit, so the be will run in wide mode.
+-	 */
+-
+-	be	0(%sr3,%r31)			   /* return to user space */
++	/* decide whether to reset the wide mode bit
++	 *
++	 * For a syscall, the W bit is stored in the lowest bit
++	 * of sp.  Extract it and reset W if it is zero */
++	extrd,u,*<>	%r30,63,1,%r1
+ 	rsm	PSW_SM_W, %r0
+-#else
+-	be,n    0(%sr3,%r31)                       /* return to user space */
++	/* now reset the lowest bit of sp if it was set */
++	xor	%r30,%r1,%r30
+ #endif
++	be,n    0(%sr3,%r31)                       /* return to user space */
+ 
+ 	/* We have to return via an RFI, so that PSW T and R bits can be set
+ 	 * appropriately.
+@@ -2340,12 +2343,19 @@ syscall_restore_rfi:
+ 	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */
+ 	ldi	0x0b,%r20			   /* Create new PSW */
+ 	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */
+-	bb,>=,n	%r19,15,try_tbit		   /* PT_SINGLESTEP */
++
++	/* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
++	 * set in include/linux/ptrace.h and converted to PA bitmap
++	 * numbers in asm-offsets.c */
++
++	/* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
++	extru,=	%r19,PA_SINGLESTEP_BIT,1,%r0
+ 	depi	-1,27,1,%r20			   /* R bit */
+-try_tbit:
+-	bb,>=,n	%r19,14,psw_setup		   /* PT_BLOCKSTEP, see ptrace.c */
++
++	/* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
++	extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
+ 	depi	-1,7,1,%r20			   /* T bit */
+-psw_setup:
++
+ 	STREG	%r20,TASK_PT_PSW(%r1)
+ 
+ 	/* Always store space registers, since sr3 can be changed (e.g. fork) */
+--- linux-2.6.0-test6/arch/parisc/kernel/firmware.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/parisc/kernel/firmware.c	2003-10-05 00:33:23.000000000 -0700
+@@ -41,19 +41,20 @@
+  *					prumpf	991016	
+  */
+ 
++#include <stdarg.h>
++
++#include <linux/delay.h>
++#include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/spinlock.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+ 
+ #include <asm/page.h>
+ #include <asm/pdc.h>
+ #include <asm/system.h>
+ #include <asm/processor.h>	/* for boot_cpu_data */
+ 
+-#include <stdarg.h>
+-
+ static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
+ static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
+ static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
+@@ -151,6 +152,7 @@ int pdc_add_valid(unsigned long address)
+ 
+         return retval;
+ }
++EXPORT_SYMBOL(pdc_add_valid);
+ 
+ /**
+  * pdc_chassis_info - Return chassis information.
+@@ -264,6 +266,7 @@ int pdc_iodc_read(unsigned long *actcnt,
+ 
+ 	return retval;
+ }
++EXPORT_SYMBOL(pdc_iodc_read);
+ 
+ /**
+  * pdc_system_map_find_mods - Locate unarchitected modules.
+@@ -518,6 +521,7 @@ int pdc_lan_station_id(char *lan_addr, u
+ 
+ 	return retval;
+ }
++EXPORT_SYMBOL(pdc_lan_station_id);
+ 
+ 
+ /**
+@@ -594,6 +598,7 @@ int pdc_get_initiator( struct hardware_p
+ 	spin_unlock_irq(&pdc_lock);
+ 	return retval >= PDC_OK;
+ }
++EXPORT_SYMBOL(pdc_get_initiator);
+ 
+ 
+ /**
+@@ -660,6 +665,7 @@ int pdc_tod_read(struct pdc_tod *tod)
+ 
+         return retval;
+ }
++EXPORT_SYMBOL(pdc_tod_read);
+ 
+ /**
+  * pdc_tod_set - Set the Time-Of-Day clock.
+@@ -678,6 +684,7 @@ int pdc_tod_set(unsigned long sec, unsig
+ 
+         return retval;
+ }
++EXPORT_SYMBOL(pdc_tod_set);
+ 
+ #ifdef __LP64__
+ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+@@ -772,20 +779,34 @@ int pdc_soft_power_button(int sw_control
+ }
+ 
+ /*
+- * pdc_suspend_usb - Stop USB controller
++ * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
++ * Primarily a problem on T600 (which parisc-linux doesn't support) but
++ * who knows what other platform firmware might do with this OS "hook".
++ */
++void pdc_io_reset(void)
++{
++	spin_lock_irq(&pdc_lock);  
++	mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
++	spin_unlock_irq(&pdc_lock);
++}
++
++/*
++ * pdc_io_reset_devices - Hack to Stop USB controller
+  *
+  * If PDC used the usb controller, the usb controller
+  * is still running and will crash the machines during iommu 
+  * setup, because of still running DMA. This PDC call
+- * stops the USB controller
++ * stops the USB controller.
++ * Normally called after calling pdc_io_reset().
+  */
+-void pdc_suspend_usb(void)
++void pdc_io_reset_devices(void)
+ {
+ 	spin_lock_irq(&pdc_lock);  
+-	mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
++	mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
+ 	spin_unlock_irq(&pdc_lock);
+ }
+ 
++
+ /**
+  * pdc_iodc_putc - Console character print using IODC.
+  * @c: the character to output.
+@@ -905,6 +926,7 @@ int pdc_sti_call(unsigned long func, uns
+ 
+         return retval;
+ }
++EXPORT_SYMBOL(pdc_sti_call);
+ 
+ #ifdef __LP64__
+ /**
+--- linux-2.6.0-test6/arch/parisc/kernel/inventory.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/parisc/kernel/inventory.c	2003-10-05 00:33:23.000000000 -0700
+@@ -526,12 +526,14 @@ static void __init system_map_inventory(
+ 	int i;
+ 	long status = PDC_OK;
+     
++#if defined(CONFIG_IOMMU_SBA) && defined(CONFIG_SUPERIO)
+ 	/*
+-	 * first stop the usb controller, otherwise the machine
+-	 * might crash during iommu setup
++	 * Stop the suckyio usb controller on Astro based systems.
++	 * Otherwise the machine might crash during iommu setup.
+ 	 */
+-#warning We still probably need to worry about USB here, but how?
+-        /* pdc_suspend_usb(); */
++	pdc_io_reset();
++	pdc_io_reset_devices();
++#endif
+ 
+ 	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
+ 		struct parisc_device *dev;
+--- linux-2.6.0-test6/arch/parisc/kernel/irq.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/irq.c	2003-10-05 00:33:23.000000000 -0700
+@@ -193,6 +193,7 @@ void disable_irq(int irq)
+ 	else
+ 		BUG();
+ }
++EXPORT_SYMBOL(disable_irq);
+ 
+ void enable_irq(int irq)
+ {
+@@ -208,6 +209,7 @@ void enable_irq(int irq)
+ 	else
+ 		BUG();
+ }
++EXPORT_SYMBOL(enable_irq);
+ 
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+@@ -698,6 +700,7 @@ void synchronize_irq(unsigned int irqnum
+ {
+ 	while (in_irq()) ;
+ }
++EXPORT_SYMBOL(synchronize_irq);
+ #endif
+ 
+ 
+@@ -847,6 +850,7 @@ unsigned int probe_irq_mask(unsigned lon
+ {
+ 	return 0;
+ }
++EXPORT_SYMBOL(probe_irq_mask);
+ 
+ void __init init_IRQ(void)
+ {
+--- linux-2.6.0-test6/arch/parisc/kernel/module.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/module.c	2003-10-05 00:33:23.000000000 -0700
+@@ -73,10 +73,7 @@ struct got_entry {
+ 	Elf32_Addr addr;
+ };
+ 
+-struct fdesc_entry {
+-	Elf32_Addr addr;
+-	Elf32_Addr gp;
+-};
++#define Elf_Fdesc	Elf32_Fdesc
+ 
+ struct stub_entry {
+ 	Elf32_Word insns[2]; /* each stub entry has two insns */
+@@ -86,11 +83,7 @@ struct got_entry {
+ 	Elf64_Addr addr;
+ };
+ 
+-struct fdesc_entry {
+-	Elf64_Addr dummy[2];
+-	Elf64_Addr addr;
+-	Elf64_Addr gp;
+-};
++#define Elf_Fdesc	Elf64_Fdesc
+ 
+ struct stub_entry {
+ 	Elf64_Word insns[4]; /* each stub entry has four insns */
+@@ -276,7 +269,7 @@ int module_frob_arch_sections(CONST Elf_
+ 
+ 	me->core_size = ALIGN(me->core_size, 16);
+ 	me->arch.fdesc_offset = me->core_size;
+-	me->core_size += fdescs * sizeof(struct fdesc_entry);
++	me->core_size += fdescs * sizeof(Elf_Fdesc);
+ 
+ 	me->core_size = ALIGN(me->core_size, 16);
+ 	me->arch.stub_offset = me->core_size;
+@@ -322,7 +315,7 @@ static Elf64_Word get_got(struct module 
+ #ifdef __LP64__
+ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+ {
+-	struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset;
++	Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
+ 
+ 	if (!value) {
+ 		printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+@@ -664,7 +657,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs
+ 				*loc64 = get_fdesc(me, val+addend);
+ 				DEBUGP("FDESC for %s at %p points to %lx\n",
+ 				       strtab + sym->st_name, *loc64,
+-				       ((struct fdesc_entry *)*loc64)->addr);
++				       ((Elf_Fdesc *)*loc64)->addr);
+ 			} else {
+ 				/* if the symbol is not local to this
+ 				 * module then val+addend is a pointer
+@@ -696,10 +689,10 @@ int module_finalize(const Elf_Ehdr *hdr,
+ 	Elf_Sym *newptr, *oldptr;
+ 	Elf_Shdr *symhdr = NULL;
+ #ifdef DEBUG
+-	struct fdesc_entry *entry;
++	Elf_Fdesc *entry;
+ 	u32 *addr;
+ 
+-	entry = (struct fdesc_entry *)me->init;
++	entry = (Elf_Fdesc *)me->init;
+ 	printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry,
+ 	       entry->gp, entry->addr);
+ 	addr = (u32 *)entry->addr;
+--- linux-2.6.0-test6/arch/parisc/kernel/parisc_ksyms.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/parisc_ksyms.c	2003-10-05 00:33:23.000000000 -0700
+@@ -26,19 +26,6 @@ EXPORT_SYMBOL(strrchr);
+ EXPORT_SYMBOL(strstr);
+ EXPORT_SYMBOL(strpbrk);
+ 
+-#include <asm/hardware.h>	/* struct parisc_device for asm/pci.h */
+-#include <linux/pci.h>
+-EXPORT_SYMBOL(hppa_dma_ops);
+-#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+-EXPORT_SYMBOL(get_pci_node_path);
+-#endif
+-
+-#include <linux/sched.h>
+-#include <asm/irq.h>
+-EXPORT_SYMBOL(enable_irq);
+-EXPORT_SYMBOL(disable_irq);
+-EXPORT_SYMBOL(probe_irq_mask);
+-
+ #include <asm/processor.h>
+ EXPORT_SYMBOL(kernel_thread);
+ EXPORT_SYMBOL(boot_cpu_data);
+@@ -46,10 +33,6 @@ EXPORT_SYMBOL(boot_cpu_data);
+ #include <linux/pm.h>
+ EXPORT_SYMBOL(pm_power_off);
+ 
+-#ifdef CONFIG_SMP
+-EXPORT_SYMBOL(synchronize_irq);
+-#endif /* CONFIG_SMP */
+-
+ #include <asm/atomic.h>
+ EXPORT_SYMBOL(__xchg8);
+ EXPORT_SYMBOL(__xchg32);
+@@ -74,14 +57,6 @@ extern int $global$;
+ EXPORT_SYMBOL($global$);
+ #endif
+ 
+-EXPORT_SYMBOL(register_parisc_driver);
+-EXPORT_SYMBOL(unregister_parisc_driver);
+-EXPORT_SYMBOL(print_pci_hwpath);
+-EXPORT_SYMBOL(print_pa_hwpath);
+-EXPORT_SYMBOL(pdc_iodc_read);
+-EXPORT_SYMBOL(pdc_tod_read);
+-EXPORT_SYMBOL(pdc_tod_set);
+-
+ #include <asm/io.h>
+ EXPORT_SYMBOL(__ioremap);
+ EXPORT_SYMBOL(iounmap);
+@@ -89,22 +64,6 @@ EXPORT_SYMBOL(__memcpy_toio);
+ EXPORT_SYMBOL(__memcpy_fromio);
+ EXPORT_SYMBOL(__memset_io);
+ 
+-#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+-EXPORT_SYMBOL(inb);
+-EXPORT_SYMBOL(inw);
+-EXPORT_SYMBOL(inl);
+-EXPORT_SYMBOL(outb);
+-EXPORT_SYMBOL(outw);
+-EXPORT_SYMBOL(outl);
+-
+-EXPORT_SYMBOL(insb);
+-EXPORT_SYMBOL(insw);
+-EXPORT_SYMBOL(insl);
+-EXPORT_SYMBOL(outsb);
+-EXPORT_SYMBOL(outsw);
+-EXPORT_SYMBOL(outsl);
+-#endif
+-
+ #include <asm/cache.h>
+ EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
+ EXPORT_SYMBOL(flush_kernel_dcache_page);
+@@ -130,17 +89,6 @@ EXPORT_SYMBOL(__up);
+ EXPORT_SYMBOL(__down_interruptible);
+ EXPORT_SYMBOL(__down);
+ 
+-#include <linux/in6.h>
+-#include <asm/checksum.h>
+-EXPORT_SYMBOL(csum_partial_copy_nocheck);
+-EXPORT_SYMBOL(csum_partial_copy_from_user);
+-
+-#include <asm/pdc.h>
+-EXPORT_SYMBOL(pdc_add_valid);
+-EXPORT_SYMBOL(pdc_lan_station_id);
+-EXPORT_SYMBOL(pdc_get_initiator);
+-EXPORT_SYMBOL(pdc_sti_call);
+-
+ extern void $$divI(void);
+ extern void $$divU(void);
+ extern void $$remI(void);
+@@ -218,6 +166,3 @@ EXPORT_SYMBOL(__moddi3);
+ extern void $$dyncall(void);
+ EXPORT_SYMBOL($$dyncall);
+ #endif
+-
+-#include <asm/pgtable.h>
+-EXPORT_SYMBOL(vmalloc_start);
+--- linux-2.6.0-test6/arch/parisc/kernel/pci.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/pci.c	2003-10-05 00:33:23.000000000 -0700
+@@ -88,7 +88,8 @@ u##size in##type (int addr) \
+ 	EISA_IN(size); \
+ 	if (!parisc_pci_hba[b]) return (u##size) -1; \
+ 	return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
+-}
++} \
++EXPORT_SYMBOL(in##type);
+ 
+ PCI_PORT_IN(b,  8)
+ PCI_PORT_IN(w, 16)
+@@ -102,7 +103,8 @@ void out##type (u##size d, int addr) \
+ 	EISA_OUT(size); \
+ 	if (!parisc_pci_hba[b]) return; \
+ 	pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
+-}
++} \
++EXPORT_SYMBOL(out##type);
+ 
+ PCI_PORT_OUT(b,  8)
+ PCI_PORT_OUT(w, 16)
+--- linux-2.6.0-test6/arch/parisc/kernel/ptrace.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/parisc/kernel/ptrace.c	2003-10-05 00:33:23.000000000 -0700
+@@ -23,16 +23,6 @@
+ #include <asm/processor.h>
+ #include <asm/offsets.h>
+ 
+-/* These are used in entry.S, syscall_restore_rfi.  We need to record the
+- * current stepping mode somewhere other than in PSW, because there is no
+- * concept of saving and restoring the users PSW over a syscall.  We choose
+- * to use these two bits in task->ptrace.  These bits must not clash with
+- * any PT_* defined in include/linux/sched.h, and must match with the bit
+- * tests in entry.S
+- */
+-#define PT_SINGLESTEP	0x10000
+-#define PT_BLOCKSTEP	0x20000
+-
+ /* PSW bits we allow the debugger to modify */
+ #define USER_PSW_BITS	(PSW_N | PSW_V | PSW_CB)
+ 
+--- linux-2.6.0-test6/arch/parisc/kernel/setup.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/setup.c	2003-10-05 00:33:23.000000000 -0700
+@@ -43,6 +43,7 @@
+ #include <asm/led.h>
+ #include <asm/machdep.h>	/* for pa7300lc_init() proto */
+ #include <asm/pdc_chassis.h>
++#include <asm/io.h>
+ 
+ #define COMMAND_LINE_SIZE 1024
+ char	saved_command_line[COMMAND_LINE_SIZE];
+@@ -208,27 +209,32 @@ static void __init parisc_proc_mkdir(voi
+                         proc_runway_root = proc_mkdir("bus/runway", 0);
+                 }
+                 break;
++	default:
++		/* FIXME: this was added to prevent the compiler 
++		 * complaining about missing pcx, pcxs and pcxt
++		 * I'm assuming they have neither gsc nor runway */
++		break;
+ 	}
+ }
+ 
+ static struct resource central_bus = {
+ 	.name	= "Central Bus",
+-	.start	= (unsigned long)0xfffffffffff80000,
+-	.end    = (unsigned long)0xfffffffffffaffff,
++	.start	= F_EXTEND(0xfff80000),
++	.end    = F_EXTEND(0xfffaffff),
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource local_broadcast = {
+ 	.name	= "Local Broadcast",
+-	.start	= (unsigned long)0xfffffffffffb0000,
+-	.end	= (unsigned long)0xfffffffffffdffff,
++	.start	= F_EXTEND(0xfffb0000),
++	.end	= F_EXTEND(0xfffdffff),
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+ static struct resource global_broadcast = {
+ 	.name	= "Global Broadcast",
+-	.start	= (unsigned long)0xfffffffffffe0000,
+-	.end	= (unsigned long)0xffffffffffffffff,
++	.start	= F_EXTEND(0xfffe0000),
++	.end	= F_EXTEND(0xffffffff),
+ 	.flags	= IORESOURCE_MEM,
+ };
+ 
+--- linux-2.6.0-test6/arch/parisc/kernel/signal.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/signal.c	2003-10-05 00:33:23.000000000 -0700
+@@ -25,6 +25,8 @@
+ #include <linux/unistd.h>
+ #include <linux/stddef.h>
+ #include <linux/compat.h>
++#include <linux/elf.h>
++#include <linux/personality.h>
+ #include <asm/ucontext.h>
+ #include <asm/rt_sigframe.h>
+ #include <asm/uaccess.h>
+@@ -41,8 +43,11 @@
+ 
+ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+ 
+-/* Use this to get at 32-bit user passed pointers. 
+- *    See sys_sparc32.c for description about these. */
++/* gcc will complain if a pointer is cast to an integer of different
++ * size.  If you really need to do this (and we do for an ELF32 user
++ * application in an ELF64 kernel) then you have to do a cast to an
++ * integer of the same size first.  The A() macro accomplishes
++ * this. */
+ #define A(__x)	((unsigned long)(__x))
+ 
+ int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
+@@ -166,11 +171,17 @@ sys_rt_sigreturn(struct pt_regs *regs, i
+ 	struct rt_sigframe *frame;
+ 	struct siginfo si;
+ 	sigset_t set;
+-	unsigned long usp = regs->gr[30];
++	unsigned long usp = (regs->gr[30] & ~(0x01UL));
++	unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
++#ifdef __LP64__
++	if(personality(current->personality) == PER_LINUX32)
++		sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
++#endif
++
+ 
+ 	/* Unwind the user stack to get the rt_sigframe structure. */
+ 	frame = (struct rt_sigframe *)
+-		(usp - PARISC_RT_SIGFRAME_SIZE);
++		(usp - sigframe_size);
+ 	DBG(("in sys_rt_sigreturn, frame is %p\n", frame));
+ 
+ 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+@@ -271,11 +282,12 @@ setup_rt_frame(int sig, struct k_sigacti
+ 	       sigset_t *set, struct pt_regs *regs, int in_syscall)
+ {
+ 	struct rt_sigframe *frame;
+-	unsigned long rp, usp, haddr;
++	unsigned long rp, usp;
++	unsigned long haddr, sigframe_size;
+ 	struct siginfo si;
+ 	int err = 0;
+ 
+-	usp = regs->gr[30];
++	usp = (regs->gr[30] & ~(0x01UL));
+ 	frame = get_sigframe(ka, usp, sizeof(*frame));
+ 
+ 	DBG(("setup_rt_frame 1: frame %p info %p\n", frame, info));
+@@ -308,64 +320,86 @@ setup_rt_frame(int sig, struct k_sigacti
+ 	}
+ #endif
+ 
+-#undef CACHE_FLUSHING_IS_NOT_BROKEN
+-#ifdef CACHE_FLUSHING_IS_NOT_BROKEN
++	flush_user_dcache_range((unsigned long) &frame->tramp[0],
++			   (unsigned long) &frame->tramp[4]);
+ 	flush_user_icache_range((unsigned long) &frame->tramp[0],
+ 			   (unsigned long) &frame->tramp[4]);
+-#else
+-	/* It should *always* be cache line-aligned, but the compiler
+-	sometimes screws up. */
+-	asm volatile("fdc 0(%%sr3,%0)\n\t"
+-		     "fdc %1(%%sr3,%0)\n\t"
+-		     "sync\n\t"
+-		     "fic 0(%%sr3,%0)\n\t"
+-		     "fic %1(%%sr3,%0)\n\t"
+-		     "sync\n\t"
+-		      : : "r" (frame->tramp), "r" (L1_CACHE_BYTES));
+-#endif
+ 
+ 	rp = (unsigned long) frame->tramp;
+ 
+ 	if (err)
+ 		goto give_sigsegv;
+ 
+-/* Much more has to happen with signals than this -- but it'll at least */
+-/* provide a pointer to some places which definitely need a look. */
+-#define HACK u32
+-
+-	haddr = (HACK)A(ka->sa.sa_handler);
+-	/* ARGH!  Fucking brain damage.  You don't want to know. */
+-	if (haddr & 2) {
+-		HACK *plabel;
+-		HACK ltp;
+-
+-		plabel = (HACK *) (haddr & ~3);
+-		err |= __get_user(haddr, plabel);
+-		err |= __get_user(ltp, plabel + 1);
++	haddr = A(ka->sa.sa_handler);
++	/* The sa_handler may be a pointer to a function descriptor */
++#ifdef __LP64__
++	if(personality(current->personality) == PER_LINUX32) {
++#endif
++		if (haddr & PA_PLABEL_FDESC) {
++			Elf32_Fdesc fdesc;
++			Elf32_Fdesc *ufdesc = (Elf32_Fdesc *)A(haddr & ~3);
++
++			err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
++
++			if (err)
++				goto give_sigsegv;
++
++			haddr = fdesc.addr;
++			regs->gr[19] = fdesc.gp;
++		}
++#ifdef __LP64__
++	} else {
++		Elf64_Fdesc fdesc;
++		Elf64_Fdesc *ufdesc = (Elf64_Fdesc *)A(haddr & ~3);
++		
++		err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
++		
+ 		if (err)
+ 			goto give_sigsegv;
+-		regs->gr[19] = ltp;
++		
++		haddr = fdesc.addr;
++		regs->gr[19] = fdesc.gp;
++		DBG(("64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
++		     haddr, regs->gr[19], in_syscall));
+ 	}
++#endif
+ 
+ 	/* The syscall return path will create IAOQ values from r31.
+ 	 */
+-	if (in_syscall)
+-		regs->gr[31] = (HACK) haddr;
+-	else {
+-		regs->gr[0] = USER_PSW;
+-		regs->iaoq[0] = (HACK) haddr | 3;
++	sigframe_size = PARISC_RT_SIGFRAME_SIZE;
++#ifdef __LP64__
++	if(personality(current->personality) == PER_LINUX32)
++		sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
++#endif
++	if (in_syscall) {
++		regs->gr[31] = haddr;
++#ifdef __LP64__
++		if(personality(current->personality) == PER_LINUX)
++			sigframe_size |= 1;
++#endif
++	} else {
++		unsigned long psw = USER_PSW;
++#ifdef __LP64__
++		if(personality(current->personality) == PER_LINUX)
++			psw |= PSW_W;
++#endif
++
++		regs->gr[0] = psw;
++		regs->iaoq[0] = haddr | 3;
+ 		regs->iaoq[1] = regs->iaoq[0] + 4;
+ 	}
+ 
+ 	regs->gr[2]  = rp;                /* userland return pointer */
+ 	regs->gr[26] = sig;               /* signal number */
+-	regs->gr[25] = (HACK)A(&frame->info); /* siginfo pointer */
+-	regs->gr[24] = (HACK)A(&frame->uc);   /* ucontext pointer */
++	regs->gr[25] = A(&frame->info); /* siginfo pointer */
++	regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
++	
+ 	DBG(("making sigreturn frame: %#lx + %#x = %#lx\n",
+-	       regs->gr[30], PARISC_RT_SIGFRAME_SIZE,
+-	       regs->gr[30] + PARISC_RT_SIGFRAME_SIZE));
++	       regs->gr[30], sigframe_size,
++	       regs->gr[30] + sigframe_size));
+ 	/* Raise the user stack pointer to make a proper call frame. */
+-	regs->gr[30] = ((HACK)A(frame) + PARISC_RT_SIGFRAME_SIZE);
++	regs->gr[30] = (A(frame) + sigframe_size);
++
+ 
+ 	DBG(("SIG deliver (%s:%d): frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
+ 	       current->comm, current->pid, frame, regs->gr[30],
+--- linux-2.6.0-test6/arch/parisc/kernel/syscall.S	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/syscall.S	2003-10-05 00:33:23.000000000 -0700
+@@ -69,9 +69,14 @@ linux_gateway_entry:
+ 	 * exit from the syscall, and also use that value to know
+ 	 * whether to do narrow or wide syscalls. -PB
+ 	 */
+-	ssm	PSW_SM_W, %r0
++	ssm	PSW_SM_W, %r1
++	extrd,u	%r1,PSW_W_BIT,1,%r1
++	/* sp must be aligned on 4, so deposit the W bit setting into
++	 * the bottom of sp temporarily */
++	or,ev	%r1,%r30,%r30
++	b,n	1f
+ 	/* The top halves of argument registers must be cleared on syscall
+-	 * entry.
++	 * entry from narrow executable.
+ 	 */
+ 	depdi	0, 31, 32, %r26
+ 	depdi	0, 31, 32, %r25
+@@ -79,11 +84,13 @@ linux_gateway_entry:
+ 	depdi	0, 31, 32, %r23
+ 	depdi	0, 31, 32, %r22
+ 	depdi	0, 31, 32, %r21
++1:	
+ #endif
+ 	mfctl   %cr30,%r1
+ 	xor     %r1,%r30,%r30                   /* ye olde xor trick */
+ 	xor     %r1,%r30,%r1
+ 	xor     %r1,%r30,%r30
++	
+ 	ldo     THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */
+ 
+ 	/* N.B.: It is critical that we don't set sr7 to 0 until r30
+@@ -104,9 +111,19 @@ linux_gateway_entry:
+ 	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
+ 	STREG	%r0,  TASK_PT_PSW(%r1)
+ 	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
++	STREG	%r19, TASK_PT_GR19(%r1)
++
+ 	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
++#ifdef __LP64__
++	extrd,u	%r2,63,1,%r19			/* W hidden in bottom bit */
++#if 0
++	xor	%r19,%r2,%r2			/* clear bottom bit */
++	depd,z	%r19,1,1,%r19
++	std	%r19,TASK_PT_PSW(%r1)
++#endif
++#endif
+ 	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
+-	STREG	%r19, TASK_PT_GR19(%r1)
++	
+ 	STREG	%r20, TASK_PT_GR20(%r1)
+ 	STREG	%r21, TASK_PT_GR21(%r1)
+ 	STREG	%r22, TASK_PT_GR22(%r1)
+@@ -130,6 +147,7 @@ linux_gateway_entry:
+ 
+ #ifdef __LP64__
+ 	ldo	-16(%r30),%r29			/* Reference param save area */
++	copy	%r19,%r2			/* W bit back to r2 */
+ #else
+ 	/* no need to save these on stack in wide mode because the first 8
+ 	 * args are passed in registers */
+@@ -144,9 +162,17 @@ linux_gateway_entry:
+ 	/* Note!  We cannot use the syscall table that is mapped
+ 	nearby since the gateway page is mapped execute-only. */
+ 
++#ifdef __LP64__
++	ldil	L%sys_call_table, %r1
++	or,=	%r2,%r2,%r2
++	addil	L%(sys_call_table64-sys_call_table), %r1
++	ldo	R%sys_call_table(%r1), %r19
++	or,=	%r2,%r2,%r2
++	ldo	R%sys_call_table64(%r1), %r19
++#else
+ 	ldil	L%sys_call_table, %r1
+ 	ldo     R%sys_call_table(%r1), %r19
+-	
++#endif	
+ 	comiclr,>>=	__NR_Linux_syscalls, %r20, %r0
+ 	b,n	.Lsyscall_nosys
+ 	
+@@ -317,304 +343,21 @@ tracesys_sigexit:
+ 	ldil	L%syscall_exit_rfi,%r1
+ 	be,n	R%syscall_exit_rfi(%sr7,%r1)
+ 
+-#ifdef __LP64__
+-/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
+- * narrow palinux.  Use ENTRY_DIFF for those where a 32-bit specific
+- * implementation is required on wide palinux.  Use ENTRY_COMP where
+- * the compatability layer has a useful 32-bit implementation.
+- */
+-#define ENTRY_SAME(_name_) .dword sys_##_name_
+-#define ENTRY_DIFF(_name_) .dword sys32_##_name_
+-#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
+-#define ENTRY_OURS(_name_) .dword parisc_##_name_
+-#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
+-#else
+-#define ENTRY_SAME(_name_) .word sys_##_name_
+-#define ENTRY_DIFF(_name_) .word sys_##_name_
+-#define ENTRY_UHOH(_name_) .word sys_##_name_
+-#define ENTRY_OURS(_name_) .word parisc_##_name_
+-#define ENTRY_COMP(_name_) .word sys_##_name_
+-#endif
+-
+-	.align 8
++	.align 4096
+ 	.export sys_call_table
+ .Lsys_call_table:
+ sys_call_table:
+-	ENTRY_SAME(ni_syscall)	/* 0  -  old "setup()" system call*/
+-	ENTRY_SAME(exit)
+-	ENTRY_SAME(fork_wrapper)
+-	ENTRY_SAME(read)
+-	ENTRY_SAME(write)
+-	ENTRY_SAME(open)		/* 5 */
+-	ENTRY_SAME(close)
+-	ENTRY_SAME(waitpid)
+-	ENTRY_SAME(creat)
+-	ENTRY_SAME(link)
+-	ENTRY_SAME(unlink)		/* 10 */
+-	ENTRY_DIFF(execve_wrapper)
+-	ENTRY_SAME(chdir)
+-	/* See comments in kernel/time.c!!! Maybe we don't need this? */
+-	ENTRY_DIFF(time)
+-	ENTRY_SAME(mknod)
+-	ENTRY_SAME(chmod)		/* 15 */
+-	ENTRY_SAME(lchown)
+-	ENTRY_SAME(socket)
+-	/* struct stat is MAYBE identical wide and narrow ?? */
+-	ENTRY_COMP(newstat)
+-	ENTRY_DIFF(lseek)
+-	ENTRY_SAME(getpid)		/* 20 */
+-	/* the 'void * data' parameter may need re-packing in wide */
+-	ENTRY_DIFF(mount)
+-	/* concerned about struct sockaddr in wide/narrow */
+-	/* ---> I think sockaddr is OK unless the compiler packs the struct */
+-	/*      differently to align the char array */
+-	ENTRY_SAME(bind)
+-	ENTRY_SAME(setuid)
+-	ENTRY_SAME(getuid)
+-	ENTRY_SAME(stime)		/* 25 */
+-	ENTRY_SAME(ptrace)
+-	ENTRY_SAME(alarm)
+-	/* see stat comment */
+-	ENTRY_COMP(newfstat)
+-	ENTRY_SAME(pause)
+-	/* struct utimbuf uses time_t which might vary */
+-	ENTRY_COMP(utime)		/* 30 */
+-	/* struct sockaddr... */
+-	ENTRY_SAME(connect)
+-	ENTRY_SAME(listen)
+-	ENTRY_SAME(access)
+-	ENTRY_SAME(nice)
+-	/* struct sockaddr... */
+-	ENTRY_SAME(accept)		/* 35 */
+-	ENTRY_SAME(sync)
+-	ENTRY_SAME(kill)
+-	ENTRY_SAME(rename)
+-	ENTRY_SAME(mkdir)
+-	ENTRY_SAME(rmdir)		/* 40 */
+-	ENTRY_SAME(dup)
+-	ENTRY_SAME(pipe)
+-	ENTRY_COMP(times)
+-	/* struct sockaddr... */
+-	ENTRY_SAME(getsockname)
+-	/* it seems possible brk() could return a >4G pointer... */
+-	ENTRY_SAME(brk)			/* 45 */
+-	ENTRY_SAME(setgid)
+-	ENTRY_SAME(getgid)
+-	ENTRY_SAME(signal)
+-	ENTRY_SAME(geteuid)
+-	ENTRY_SAME(getegid)		/* 50 */
+-	ENTRY_SAME(acct)
+-	ENTRY_SAME(umount)
+-	/* struct sockaddr... */
+-	ENTRY_SAME(getpeername)
+-	ENTRY_COMP(ioctl)
+-	ENTRY_COMP(fcntl)		/* 55 */
+-	ENTRY_SAME(socketpair)
+-	ENTRY_SAME(setpgid)
+-	ENTRY_SAME(send)
+-	ENTRY_SAME(newuname)
+-	ENTRY_SAME(umask)		/* 60 */
+-	ENTRY_SAME(chroot)
+-	ENTRY_SAME(ustat)
+-	ENTRY_SAME(dup2)
+-	ENTRY_SAME(getppid)
+-	ENTRY_SAME(getpgrp)		/* 65 */
+-	ENTRY_SAME(setsid)
+-	ENTRY_SAME(pivot_root)
+-	/* I don't like this */
+-	ENTRY_UHOH(sgetmask)
+-	ENTRY_UHOH(ssetmask)
+-	ENTRY_SAME(setreuid)		/* 70 */
+-	ENTRY_SAME(setregid)
+-	ENTRY_SAME(mincore)
+-	ENTRY_COMP(sigpending)
+-	ENTRY_SAME(sethostname)
+-	/* Following 3 have linux-common-code structs containing longs -( */
+-	ENTRY_COMP(setrlimit)		/* 75 */
+-	ENTRY_COMP(getrlimit)
+-	ENTRY_COMP(getrusage)
+-	/* struct timeval and timezone are maybe?? consistent wide and narrow */
+-	ENTRY_DIFF(gettimeofday)
+-	ENTRY_DIFF(settimeofday)
+-	ENTRY_SAME(getgroups)		/* 80 */
+-	ENTRY_SAME(setgroups)
+-	/* struct socketaddr... */
+-	ENTRY_SAME(sendto)
+-	ENTRY_SAME(symlink)
+-	/* see stat comment */
+-	ENTRY_COMP(newlstat)
+-	ENTRY_SAME(readlink)		/* 85 */
+-	ENTRY_SAME(ni_syscall)	/* was uselib */
+-	ENTRY_SAME(swapon)
+-	ENTRY_SAME(reboot)
+-	ENTRY_SAME(mmap2)
+-	ENTRY_SAME(mmap)		/* 90 */
+-	ENTRY_SAME(munmap)
+-	ENTRY_SAME(truncate)
+-	ENTRY_SAME(ftruncate)
+-	ENTRY_SAME(fchmod)
+-	ENTRY_SAME(fchown)		/* 95 */
+-	ENTRY_SAME(getpriority)
+-	ENTRY_SAME(setpriority)
+-	ENTRY_SAME(recv)
+-	ENTRY_COMP(statfs)
+-	ENTRY_COMP(fstatfs)		/* 100 */
+-	ENTRY_SAME(stat64)
+-	ENTRY_SAME(ni_syscall)	/* was socketcall */
+-	ENTRY_SAME(syslog)
+-	/* even though manpage says struct timeval contains longs, ours has
+-	 * time_t and suseconds_t -- both of which are safe wide/narrow */
+-	ENTRY_COMP(setitimer)
+-	ENTRY_COMP(getitimer)		/* 105 */
+-	ENTRY_SAME(capget)
+-	ENTRY_SAME(capset)
+-	ENTRY_OURS(pread64)
+-	ENTRY_OURS(pwrite64)
+-	ENTRY_SAME(getcwd)		/* 110 */
+-	ENTRY_SAME(vhangup)
+-	ENTRY_SAME(fstat64)
+-	ENTRY_SAME(vfork_wrapper)
+-	/* struct rusage contains longs... */
+-	ENTRY_COMP(wait4)
+-	ENTRY_SAME(swapoff)		/* 115 */
+-	ENTRY_DIFF(sysinfo)
+-	ENTRY_SAME(shutdown)
+-	ENTRY_SAME(fsync)
+-	ENTRY_SAME(madvise)
+-	ENTRY_SAME(clone_wrapper)	/* 120 */
+-	ENTRY_SAME(setdomainname)
+-	ENTRY_DIFF(sendfile)
+-	/* struct sockaddr... */
+-	ENTRY_SAME(recvfrom)
+-	/* struct timex contains longs */
+-	ENTRY_DIFF(adjtimex)
+-	ENTRY_SAME(mprotect)		/* 125 */
+-	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
+-	ENTRY_COMP(sigprocmask)
+-	ENTRY_SAME(ni_syscall)	/* create_module */
+-	ENTRY_SAME(init_module)
+-	ENTRY_SAME(delete_module)
+-	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
+-	/* time_t inside struct dqblk */
+-	ENTRY_SAME(quotactl)
+-	ENTRY_SAME(getpgid)
+-	ENTRY_SAME(fchdir)
+-	ENTRY_SAME(bdflush)
+-	ENTRY_SAME(sysfs)		/* 135 */
+-	ENTRY_SAME(personality)
+-	ENTRY_SAME(ni_syscall)	/* for afs_syscall */
+-	ENTRY_SAME(setfsuid)
+-	ENTRY_SAME(setfsgid)
+-	/* I think this might work */
+-	ENTRY_SAME(llseek)		/* 140 */
+-	/* struct linux_dirent has longs, like 'unsigned long d_ino' which
+-	 * almost definitely should be 'ino_t d_ino' but it's too late now */
+-	ENTRY_DIFF(getdents)
+-	/* it is POSSIBLE that select will be OK because even though fd_set
+-	 * contains longs, the macros and sizes are clever. */
+-	ENTRY_DIFF(select)
+-	ENTRY_SAME(flock)
+-	ENTRY_SAME(msync)
+-	/* struct iovec contains pointers */
+-	ENTRY_DIFF(readv)		/* 145 */
+-	ENTRY_DIFF(writev)
+-	ENTRY_SAME(getsid)
+-	ENTRY_SAME(fdatasync)
+-	/* struct __sysctl_args is a mess */
+-	ENTRY_DIFF(sysctl)
+-	ENTRY_SAME(mlock)		/* 150 */
+-	ENTRY_SAME(munlock)
+-	ENTRY_SAME(mlockall)
+-	ENTRY_SAME(munlockall)
+-	/* struct sched_param is ok for now */
+-	ENTRY_SAME(sched_setparam)
+-	ENTRY_SAME(sched_getparam)	/* 155 */
+-	ENTRY_SAME(sched_setscheduler)
+-	ENTRY_SAME(sched_getscheduler)
+-	ENTRY_SAME(sched_yield)
+-	ENTRY_SAME(sched_get_priority_max)
+-	ENTRY_SAME(sched_get_priority_min)	/* 160 */
+-	/* These 2 would've worked if someone had defined struct timespec
+-	 * carefully, like timeval for example (which is about the same).
+-	 * Unfortunately it contains a long :-( */
+-	ENTRY_DIFF(sched_rr_get_interval)
+-	ENTRY_COMP(nanosleep)
+-	ENTRY_SAME(mremap)
+-	ENTRY_SAME(setresuid)
+-	ENTRY_SAME(getresuid)		/* 165 */
+-	ENTRY_DIFF(sigaltstack_wrapper)
+-	ENTRY_SAME(ni_syscall)		/* query_module */
+-	ENTRY_SAME(poll)
+-	/* structs contain pointers and an in_addr... */
+-	ENTRY_DIFF(nfsservctl)
+-	ENTRY_SAME(setresgid)		/* 170 */
+-	ENTRY_SAME(getresgid)
+-	ENTRY_SAME(prctl)
+-	/* signals need a careful review */
+-	ENTRY_SAME(rt_sigreturn_wrapper)
+-	ENTRY_DIFF(rt_sigaction)
+-	ENTRY_DIFF(rt_sigprocmask)	/* 175 */
+-	ENTRY_DIFF(rt_sigpending)
+-	ENTRY_UHOH(rt_sigtimedwait)
+-	/* even though the struct siginfo_t is different, it appears like
+-	 * all the paths use values which should be same wide and narrow.
+-	 * Also the struct is padded to 128 bytes which means we don't have
+-	 * to worry about faulting trying to copy in a larger 64-bit
+-	 * struct from a 32-bit user-space app.
+-	 */
+-	ENTRY_SAME(rt_sigqueueinfo)
+-	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
+-	ENTRY_SAME(chown)		/* 180 */
+-	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
+-	ENTRY_COMP(setsockopt)
+-	ENTRY_SAME(getsockopt)
+-	ENTRY_COMP(sendmsg)
+-	ENTRY_COMP(recvmsg)
+-	ENTRY_SAME(semop)		/* 185 */
+-	ENTRY_SAME(semget)
+-	ENTRY_DIFF(semctl_broken)
+-	ENTRY_DIFF(msgsnd)
+-	ENTRY_DIFF(msgrcv)
+-	ENTRY_SAME(msgget)		/* 190 */
+-	ENTRY_SAME(msgctl_broken)
+-	ENTRY_SAME(shmat_wrapper)
+-	ENTRY_SAME(shmdt)
+-	ENTRY_SAME(shmget)
+-	ENTRY_SAME(shmctl_broken)	/* 195 */
+-	ENTRY_SAME(ni_syscall)		/* streams1 */
+-	ENTRY_SAME(ni_syscall)		/* streams2 */
+-	ENTRY_SAME(lstat64)
+-	ENTRY_OURS(truncate64)
+-	ENTRY_OURS(ftruncate64)		/* 200 */
+-	ENTRY_SAME(getdents64)
+-	ENTRY_COMP(fcntl64)
+-	ENTRY_SAME(ni_syscall)
+-	ENTRY_SAME(ni_syscall)
+-	ENTRY_SAME(ni_syscall)		/* 205 */
+-	ENTRY_SAME(gettid)             
+-	ENTRY_OURS(readahead)          
+-	ENTRY_SAME(ni_syscall)		/* tkill */
+-
+-	ENTRY_SAME(sendfile64)
+-	ENTRY_COMP(futex)		/* 210 */
+-	ENTRY_COMP(sched_setaffinity)
+-	ENTRY_COMP(sched_getaffinity)
+-	ENTRY_SAME(ni_syscall)
+-	ENTRY_SAME(ni_syscall)
+-	ENTRY_SAME(io_setup)		/* 215 */
+-	ENTRY_SAME(io_destroy)
+-	ENTRY_SAME(io_getevents)
+-	ENTRY_SAME(io_submit)
+-	ENTRY_SAME(io_cancel)
+-	ENTRY_SAME(alloc_hugepages)	/* 220 */
+-	ENTRY_SAME(free_hugepages)
+-	ENTRY_SAME(exit_group)
+-	ENTRY_DIFF(lookup_dcookie)
+-	ENTRY_SAME(epoll_create)
+-	ENTRY_SAME(epoll_ctl)		/* 225 */
+-	ENTRY_SAME(epoll_wait)
+- 	ENTRY_SAME(remap_file_pages)
++#include "syscall_table.S"
+ .end
++#ifdef __LP64__
++	.align 4096
++	.export sys_call_table64
++.Lsys_call_table64:
++sys_call_table64:
++#define SYSCALL_TABLE_64BIT
++#include "syscall_table.S"
++#endif
++
+ 
+ 	/* Make sure nothing else is placed on this page */
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/parisc/kernel/syscall_table.S	2003-10-05 00:33:23.000000000 -0700
+@@ -0,0 +1,304 @@
++#undef ENTRY_SAME
++#undef ENTRY_DIFF
++#undef ENTRY_UHOH
++#undef ENTRY_COMP
++#undef ENTRY_OURS
++#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT)
++/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
++ * narrow palinux.  Use ENTRY_DIFF for those where a 32-bit specific
++ * implementation is required on wide palinux.  Use ENTRY_COMP where
++ * the compatability layer has a useful 32-bit implementation.
++ */
++#define ENTRY_SAME(_name_) .dword sys_##_name_
++#define ENTRY_DIFF(_name_) .dword sys32_##_name_
++#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
++#define ENTRY_OURS(_name_) .dword parisc_##_name_
++#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
++#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT)
++#define ENTRY_SAME(_name_) .dword sys_##_name_
++#define ENTRY_DIFF(_name_) .dword sys_##_name_
++#define ENTRY_UHOH(_name_) .dword sys_##_name_
++#define ENTRY_OURS(_name_) .dword sys_##_name_
++#define ENTRY_COMP(_name_) .dword sys_##_name_
++#else
++#define ENTRY_SAME(_name_) .word sys_##_name_
++#define ENTRY_DIFF(_name_) .word sys_##_name_
++#define ENTRY_UHOH(_name_) .word sys_##_name_
++#define ENTRY_OURS(_name_) .word parisc_##_name_
++#define ENTRY_COMP(_name_) .word sys_##_name_
++#endif
++
++	ENTRY_SAME(ni_syscall)	/* 0  -  old "setup()" system call*/
++	ENTRY_SAME(exit)
++	ENTRY_SAME(fork_wrapper)
++	ENTRY_SAME(read)
++	ENTRY_SAME(write)
++	ENTRY_SAME(open)		/* 5 */
++	ENTRY_SAME(close)
++	ENTRY_SAME(waitpid)
++	ENTRY_SAME(creat)
++	ENTRY_SAME(link)
++	ENTRY_SAME(unlink)		/* 10 */
++	ENTRY_DIFF(execve_wrapper)
++	ENTRY_SAME(chdir)
++	/* See comments in kernel/time.c!!! Maybe we don't need this? */
++	ENTRY_DIFF(time)
++	ENTRY_SAME(mknod)
++	ENTRY_SAME(chmod)		/* 15 */
++	ENTRY_SAME(lchown)
++	ENTRY_SAME(socket)
++	/* struct stat is MAYBE identical wide and narrow ?? */
++	ENTRY_COMP(newstat)
++	ENTRY_DIFF(lseek)
++	ENTRY_SAME(getpid)		/* 20 */
++	/* the 'void * data' parameter may need re-packing in wide */
++	ENTRY_DIFF(mount)
++	/* concerned about struct sockaddr in wide/narrow */
++	/* ---> I think sockaddr is OK unless the compiler packs the struct */
++	/*      differently to align the char array */
++	ENTRY_SAME(bind)
++	ENTRY_SAME(setuid)
++	ENTRY_SAME(getuid)
++	ENTRY_SAME(stime)		/* 25 */
++	ENTRY_SAME(ptrace)
++	ENTRY_SAME(alarm)
++	/* see stat comment */
++	ENTRY_COMP(newfstat)
++	ENTRY_SAME(pause)
++	/* struct utimbuf uses time_t which might vary */
++	ENTRY_COMP(utime)		/* 30 */
++	/* struct sockaddr... */
++	ENTRY_SAME(connect)
++	ENTRY_SAME(listen)
++	ENTRY_SAME(access)
++	ENTRY_SAME(nice)
++	/* struct sockaddr... */
++	ENTRY_SAME(accept)		/* 35 */
++	ENTRY_SAME(sync)
++	ENTRY_SAME(kill)
++	ENTRY_SAME(rename)
++	ENTRY_SAME(mkdir)
++	ENTRY_SAME(rmdir)		/* 40 */
++	ENTRY_SAME(dup)
++	ENTRY_SAME(pipe)
++	ENTRY_COMP(times)
++	/* struct sockaddr... */
++	ENTRY_SAME(getsockname)
++	/* it seems possible brk() could return a >4G pointer... */
++	ENTRY_SAME(brk)			/* 45 */
++	ENTRY_SAME(setgid)
++	ENTRY_SAME(getgid)
++	ENTRY_SAME(signal)
++	ENTRY_SAME(geteuid)
++	ENTRY_SAME(getegid)		/* 50 */
++	ENTRY_SAME(acct)
++	ENTRY_SAME(umount)
++	/* struct sockaddr... */
++	ENTRY_SAME(getpeername)
++	ENTRY_COMP(ioctl)
++	ENTRY_COMP(fcntl)		/* 55 */
++	ENTRY_SAME(socketpair)
++	ENTRY_SAME(setpgid)
++	ENTRY_SAME(send)
++	ENTRY_SAME(newuname)
++	ENTRY_SAME(umask)		/* 60 */
++	ENTRY_SAME(chroot)
++	ENTRY_SAME(ustat)
++	ENTRY_SAME(dup2)
++	ENTRY_SAME(getppid)
++	ENTRY_SAME(getpgrp)		/* 65 */
++	ENTRY_SAME(setsid)
++	ENTRY_SAME(pivot_root)
++	/* I don't like this */
++	ENTRY_UHOH(sgetmask)
++	ENTRY_UHOH(ssetmask)
++	ENTRY_SAME(setreuid)		/* 70 */
++	ENTRY_SAME(setregid)
++	ENTRY_SAME(mincore)
++	ENTRY_COMP(sigpending)
++	ENTRY_SAME(sethostname)
++	/* Following 3 have linux-common-code structs containing longs -( */
++	ENTRY_COMP(setrlimit)		/* 75 */
++	ENTRY_COMP(getrlimit)
++	ENTRY_COMP(getrusage)
++	/* struct timeval and timezone are maybe?? consistent wide and narrow */
++	ENTRY_DIFF(gettimeofday)
++	ENTRY_DIFF(settimeofday)
++	ENTRY_SAME(getgroups)		/* 80 */
++	ENTRY_SAME(setgroups)
++	/* struct socketaddr... */
++	ENTRY_SAME(sendto)
++	ENTRY_SAME(symlink)
++	/* see stat comment */
++	ENTRY_COMP(newlstat)
++	ENTRY_SAME(readlink)		/* 85 */
++	ENTRY_SAME(ni_syscall)	/* was uselib */
++	ENTRY_SAME(swapon)
++	ENTRY_SAME(reboot)
++	ENTRY_SAME(mmap2)
++	ENTRY_SAME(mmap)		/* 90 */
++	ENTRY_SAME(munmap)
++	ENTRY_SAME(truncate)
++	ENTRY_SAME(ftruncate)
++	ENTRY_SAME(fchmod)
++	ENTRY_SAME(fchown)		/* 95 */
++	ENTRY_SAME(getpriority)
++	ENTRY_SAME(setpriority)
++	ENTRY_SAME(recv)
++	ENTRY_COMP(statfs)
++	ENTRY_COMP(fstatfs)		/* 100 */
++	ENTRY_SAME(stat64)
++	ENTRY_SAME(ni_syscall)	/* was socketcall */
++	ENTRY_SAME(syslog)
++	/* even though manpage says struct timeval contains longs, ours has
++	 * time_t and suseconds_t -- both of which are safe wide/narrow */
++	ENTRY_COMP(setitimer)
++	ENTRY_COMP(getitimer)		/* 105 */
++	ENTRY_SAME(capget)
++	ENTRY_SAME(capset)
++	ENTRY_OURS(pread64)
++	ENTRY_OURS(pwrite64)
++	ENTRY_SAME(getcwd)		/* 110 */
++	ENTRY_SAME(vhangup)
++	ENTRY_SAME(fstat64)
++	ENTRY_SAME(vfork_wrapper)
++	/* struct rusage contains longs... */
++	ENTRY_COMP(wait4)
++	ENTRY_SAME(swapoff)		/* 115 */
++	ENTRY_DIFF(sysinfo)
++	ENTRY_SAME(shutdown)
++	ENTRY_SAME(fsync)
++	ENTRY_SAME(madvise)
++	ENTRY_SAME(clone_wrapper)	/* 120 */
++	ENTRY_SAME(setdomainname)
++	ENTRY_DIFF(sendfile)
++	/* struct sockaddr... */
++	ENTRY_SAME(recvfrom)
++	/* struct timex contains longs */
++	ENTRY_DIFF(adjtimex)
++	ENTRY_SAME(mprotect)		/* 125 */
++	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
++	ENTRY_COMP(sigprocmask)
++	ENTRY_SAME(ni_syscall)	/* create_module */
++	ENTRY_SAME(init_module)
++	ENTRY_SAME(delete_module)
++	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
++	/* time_t inside struct dqblk */
++	ENTRY_SAME(quotactl)
++	ENTRY_SAME(getpgid)
++	ENTRY_SAME(fchdir)
++	ENTRY_SAME(bdflush)
++	ENTRY_SAME(sysfs)		/* 135 */
++	ENTRY_SAME(personality)
++	ENTRY_SAME(ni_syscall)	/* for afs_syscall */
++	ENTRY_SAME(setfsuid)
++	ENTRY_SAME(setfsgid)
++	/* I think this might work */
++	ENTRY_SAME(llseek)		/* 140 */
++	/* struct linux_dirent has longs, like 'unsigned long d_ino' which
++	 * almost definitely should be 'ino_t d_ino' but it's too late now */
++	ENTRY_DIFF(getdents)
++	/* it is POSSIBLE that select will be OK because even though fd_set
++	 * contains longs, the macros and sizes are clever. */
++	ENTRY_DIFF(select)
++	ENTRY_SAME(flock)
++	ENTRY_SAME(msync)
++	/* struct iovec contains pointers */
++	ENTRY_DIFF(readv)		/* 145 */
++	ENTRY_DIFF(writev)
++	ENTRY_SAME(getsid)
++	ENTRY_SAME(fdatasync)
++	/* struct __sysctl_args is a mess */
++	ENTRY_DIFF(sysctl)
++	ENTRY_SAME(mlock)		/* 150 */
++	ENTRY_SAME(munlock)
++	ENTRY_SAME(mlockall)
++	ENTRY_SAME(munlockall)
++	/* struct sched_param is ok for now */
++	ENTRY_SAME(sched_setparam)
++	ENTRY_SAME(sched_getparam)	/* 155 */
++	ENTRY_SAME(sched_setscheduler)
++	ENTRY_SAME(sched_getscheduler)
++	ENTRY_SAME(sched_yield)
++	ENTRY_SAME(sched_get_priority_max)
++	ENTRY_SAME(sched_get_priority_min)	/* 160 */
++	/* These 2 would've worked if someone had defined struct timespec
++	 * carefully, like timeval for example (which is about the same).
++	 * Unfortunately it contains a long :-( */
++	ENTRY_DIFF(sched_rr_get_interval)
++	ENTRY_COMP(nanosleep)
++	ENTRY_SAME(mremap)
++	ENTRY_SAME(setresuid)
++	ENTRY_SAME(getresuid)		/* 165 */
++	ENTRY_DIFF(sigaltstack_wrapper)
++	ENTRY_SAME(ni_syscall)		/* query_module */
++	ENTRY_SAME(poll)
++	/* structs contain pointers and an in_addr... */
++	ENTRY_DIFF(nfsservctl)
++	ENTRY_SAME(setresgid)		/* 170 */
++	ENTRY_SAME(getresgid)
++	ENTRY_SAME(prctl)
++	/* signals need a careful review */
++	ENTRY_SAME(rt_sigreturn_wrapper)
++	ENTRY_DIFF(rt_sigaction)
++	ENTRY_DIFF(rt_sigprocmask)	/* 175 */
++	ENTRY_DIFF(rt_sigpending)
++	ENTRY_UHOH(rt_sigtimedwait)
++	/* even though the struct siginfo_t is different, it appears like
++	 * all the paths use values which should be same wide and narrow.
++	 * Also the struct is padded to 128 bytes which means we don't have
++	 * to worry about faulting trying to copy in a larger 64-bit
++	 * struct from a 32-bit user-space app.
++	 */
++	ENTRY_SAME(rt_sigqueueinfo)
++	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
++	ENTRY_SAME(chown)		/* 180 */
++	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
++	ENTRY_COMP(setsockopt)
++	ENTRY_SAME(getsockopt)
++	ENTRY_COMP(sendmsg)
++	ENTRY_COMP(recvmsg)
++	ENTRY_SAME(semop)		/* 185 */
++	ENTRY_SAME(semget)
++	ENTRY_DIFF(semctl_broken)
++	ENTRY_DIFF(msgsnd)
++	ENTRY_DIFF(msgrcv)
++	ENTRY_SAME(msgget)		/* 190 */
++	ENTRY_SAME(msgctl_broken)
++	ENTRY_SAME(shmat_wrapper)
++	ENTRY_SAME(shmdt)
++	ENTRY_SAME(shmget)
++	ENTRY_SAME(shmctl_broken)	/* 195 */
++	ENTRY_SAME(ni_syscall)		/* streams1 */
++	ENTRY_SAME(ni_syscall)		/* streams2 */
++	ENTRY_SAME(lstat64)
++	ENTRY_OURS(truncate64)
++	ENTRY_OURS(ftruncate64)		/* 200 */
++	ENTRY_SAME(getdents64)
++	ENTRY_COMP(fcntl64)
++	ENTRY_SAME(ni_syscall)
++	ENTRY_SAME(ni_syscall)
++	ENTRY_SAME(ni_syscall)		/* 205 */
++	ENTRY_SAME(gettid)             
++	ENTRY_OURS(readahead)          
++	ENTRY_SAME(ni_syscall)		/* tkill */
++
++	ENTRY_SAME(sendfile64)
++	ENTRY_COMP(futex)		/* 210 */
++	ENTRY_COMP(sched_setaffinity)
++	ENTRY_COMP(sched_getaffinity)
++	ENTRY_SAME(ni_syscall)
++	ENTRY_SAME(ni_syscall)
++	ENTRY_SAME(io_setup)		/* 215 */
++	ENTRY_SAME(io_destroy)
++	ENTRY_SAME(io_getevents)
++	ENTRY_SAME(io_submit)
++	ENTRY_SAME(io_cancel)
++	ENTRY_SAME(alloc_hugepages)	/* 220 */
++	ENTRY_SAME(free_hugepages)
++	ENTRY_SAME(exit_group)
++	ENTRY_DIFF(lookup_dcookie)
++	ENTRY_SAME(epoll_create)
++	ENTRY_SAME(epoll_ctl)		/* 225 */
++	ENTRY_SAME(epoll_wait)
++ 	ENTRY_SAME(remap_file_pages)
+--- linux-2.6.0-test6/arch/parisc/kernel/sys_parisc.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/sys_parisc.c	2003-10-05 00:34:08.000000000 -0700
+@@ -65,7 +65,7 @@ static int get_offset(struct address_spa
+  */
+ static int get_offset(struct address_space *mapping)
+ {
+-	int offset = (int) mapping << (PAGE_SHIFT - 8);
++	int offset = (unsigned long) mapping << (PAGE_SHIFT - 8);
+ 	return offset & 0x3FF000;
+ }
+ #endif
+@@ -93,17 +93,13 @@ static unsigned long get_shared_area(str
+ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 		unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+-	struct inode *inode;
+-
+ 	if (len > TASK_SIZE)
+ 		return -ENOMEM;
+ 	if (!addr)
+ 		addr = TASK_UNMAPPED_BASE;
+ 
+-	inode = filp ? filp->f_dentry->d_inode : NULL;
+-
+-	if (inode && (flags & MAP_SHARED)) {
+-		addr = get_shared_area(inode->i_mapping, addr, len, pgoff);
++	if (filp && (flags & MAP_SHARED)) {
++		addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
+ 	} else {
+ 		addr = get_unshared_area(addr, len);
+ 	}
+@@ -165,12 +161,13 @@ long sys_shmat_wrapper(int shmid, char *
+ 	return raddr;
+ }
+ 
+-
+ /* Fucking broken ABI */
+ 
+ #ifdef CONFIG_PARISC64
+ extern asmlinkage long sys_truncate(const char *, unsigned long);
+ extern asmlinkage long sys_ftruncate(unsigned int, unsigned long);
++extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long);
++
+ asmlinkage long parisc_truncate64(const char * path,
+ 					unsigned int high, unsigned int low)
+ {
+@@ -182,6 +179,21 @@ asmlinkage long parisc_ftruncate64(unsig
+ {
+ 	return sys_ftruncate(fd, (long)high << 32 | low);
+ }
++
++/* stubs for the benefit of the syscall_table since truncate64 and truncate 
++ * are identical on LP64 */
++asmlinkage long sys_truncate64(const char * path, unsigned long length)
++{
++	return sys_truncate(path, length);
++}
++asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
++{
++	return sys_ftruncate(fd, length);
++}
++asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++	return sys_fcntl(fd, cmd, arg);
++}
+ #else
+ 
+ extern asmlinkage long sys_truncate64(const char *, loff_t);
+--- linux-2.6.0-test6/arch/parisc/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/parisc/kernel/time.c	2003-10-05 00:33:23.000000000 -0700
+@@ -48,7 +48,9 @@ static inline void
+ parisc_do_profile(struct pt_regs *regs)
+ {
+ 	unsigned long pc = regs->iaoq[0];
++#if 0
+ 	extern unsigned long prof_cpu_mask;
++#endif
+ 	extern char _stext;
+ 
+ 	profile_hook(regs);
+@@ -60,6 +62,10 @@ parisc_do_profile(struct pt_regs *regs)
+ 		return;
+ 
+ #if 0
++	/* FIXME: when we have irq affinity to cpu, we need to
++	 * only look at the cpus specified in this mask 
++	 */
++
+ 	if (!((1 << smp_processor_id()) & prof_cpu_mask))
+ 		return;
+ #endif
+@@ -206,7 +212,6 @@ do_settimeofday (struct timespec *tv)
+ 		 * done, and then undo it!
+ 		 */
+ 		nsec -= gettimeoffset() * 1000;
+-		nsec -= (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ);
+ 
+ 		wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ 		wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+@@ -223,6 +228,16 @@ do_settimeofday (struct timespec *tv)
+ 	return 0;
+ }
+ 
++/*
++ * XXX: We can do better than this.
++ * Returns nanoseconds
++ */
++
++unsigned long long sched_clock(void)
++{
++	return (unsigned long long)jiffies * (1000000000 / HZ);
++}
++
+ 
+ void __init time_init(void)
+ {
+--- linux-2.6.0-test6/arch/parisc/kernel/traps.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/parisc/kernel/traps.c	2003-10-05 00:33:23.000000000 -0700
+@@ -678,12 +678,13 @@ void handle_interruption(int code, struc
+ 	}
+ 
+ 	if (user_mode(regs)) {
+-	    if (fault_space != regs->sr[7]) {
++	    if ((fault_space>>SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
+ #ifdef PRINT_USER_FAULTS
+ 		if (fault_space == 0)
+ 			printk(KERN_DEBUG "User Fault on Kernel Space ");
+ 		else
+-			printk(KERN_DEBUG "User Fault (long pointer) ");
++			printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
++			       code);
+ 		printk("pid=%d command='%s'\n", current->pid, current->comm);
+ 		show_regs(regs);
+ #endif
+--- linux-2.6.0-test6/arch/parisc/kernel/unaligned.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/parisc/kernel/unaligned.c	2003-10-05 00:33:23.000000000 -0700
+@@ -369,8 +369,8 @@ static int emulate_std(struct pt_regs *r
+ 
+ void handle_unaligned(struct pt_regs *regs)
+ {
+-	unsigned long unaligned_count = 0;
+-	unsigned long last_time = 0;
++	static unsigned long unaligned_count = 0;
++	static unsigned long last_time = 0;
+ 	unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
+ 	int modify = 0;
+ 	int ret = -1;
+@@ -380,7 +380,6 @@ void handle_unaligned(struct pt_regs *re
+ 	/* if the unaligned access is inside the kernel:
+ 	 *   if the access is caused by a syscall, then we fault the calling
+ 	 *     user process
+-	 *   otherwise we halt the kernel
+ 	 */
+ 	if (!user_mode(regs))
+ 	{
+@@ -427,10 +426,10 @@ void handle_unaligned(struct pt_regs *re
+ 			show_regs(regs);
+ #endif		
+ 		}
+-	}
+ 
+-	if (!unaligned_enabled)
+-		goto force_sigbus;
++		if (!unaligned_enabled)
++			goto force_sigbus;
++	}
+ 
+ 	/* handle modification - OK, it's ugly, see the instruction manual */
+ 	switch (MAJOR_OP(regs->iir))
+--- linux-2.6.0-test6/arch/parisc/lib/checksum.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/parisc/lib/checksum.c	2003-10-05 00:33:23.000000000 -0700
+@@ -16,8 +16,10 @@
+  *
+  * $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  */
+-#include <net/checksum.h>
++#include <linux/module.h>
+ #include <linux/types.h>
++
++#include <net/checksum.h>
+ #include <asm/byteorder.h>
+ #include <asm/string.h>
+ #include <asm/uaccess.h>
+@@ -109,6 +111,7 @@ unsigned int csum_partial_copy_nocheck(c
+ 
+ 	return sum;
+ }
++EXPORT_SYMBOL(csum_partial_copy_nocheck);
+ 
+ /*
+  * Copy from userspace and compute checksum.  If we catch an exception
+@@ -128,3 +131,4 @@ unsigned int csum_partial_copy_from_user
+ 		
+ 	return csum_partial(dst, len, sum);
+ }
++EXPORT_SYMBOL(csum_partial_copy_from_user);
+--- linux-2.6.0-test6/arch/parisc/lib/io.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/parisc/lib/io.c	2003-10-05 00:33:23.000000000 -0700
+@@ -8,6 +8,7 @@
+  */
+ 
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <asm/io.h>
+ 
+ /* Copies a block of memory to a device in an efficient manner.
+@@ -457,3 +458,10 @@ void outsl (unsigned long port, const vo
+ 		break;
+ 	}
+ }
++
++EXPORT_SYMBOL(insb);
++EXPORT_SYMBOL(insw);
++EXPORT_SYMBOL(insl);
++EXPORT_SYMBOL(outsb);
++EXPORT_SYMBOL(outsw);
++EXPORT_SYMBOL(outsl);
+--- linux-2.6.0-test6/arch/parisc/math-emu/denormal.c	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/parisc/math-emu/denormal.c	2003-10-05 00:33:23.000000000 -0700
+@@ -47,7 +47,7 @@
+ #include "sgl_float.h"
+ #include "dbl_float.h"
+ #include "hppa.h"
+-#include "types.h"
++#include <linux/kernel.h>
+ /* #include <machine/sys/mdep_private.h> */
+ 
+ #undef Fpustatus_register
+--- linux-2.6.0-test6/arch/parisc/math-emu/fpudispatch.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/parisc/math-emu/fpudispatch.c	2003-10-05 00:33:23.000000000 -0700
+@@ -50,7 +50,7 @@
+ #define FPUDEBUG 0
+ 
+ #include "float.h"
+-#include "types.h"
++#include <linux/kernel.h>
+ #include <asm/processor.h>
+ /* #include <sys/debug.h> */
+ /* #include <machine/sys/mdep_private.h> */
+--- linux-2.6.0-test6/arch/parisc/math-emu/Makefile	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/parisc/math-emu/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -2,6 +2,11 @@
+ # Makefile for the linux/parisc floating point code
+ #
+ 
++# See arch/parisc/math-emu/README
++CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \
++	-Wno-uninitialized -Wno-strict-prototypes -Wno-return-type \
++	-Wno-implicit-int
++
+ obj-y	 := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \
+ 		dfmpy.o sfmpy.o sfsqrt.o dfsqrt.o dfadd.o fmpyfadd.o \
+ 		sfadd.o dfsub.o sfsub.o fcnvfxt.o fcnvff.o fcnvxf.o \
+--- linux-2.6.0-test6/arch/parisc/math-emu/types.h	2003-06-14 12:18:00.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,25 +0,0 @@
+-/*
+- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+- *
+- * Floating-point emulation code
+- *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
+- *
+- *    This program 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, or (at your option)
+- *    any later version.
+- *
+- *    This program is distributed in the hope that it will be useful,
+- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- *    GNU General Public License for more details.
+- *
+- *    You should have received a copy of the GNU General Public License
+- *    along with this program; if not, write to the Free Software
+- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+- */
+-
+-#include <linux/kernel.h>
+-#define BUG() do { \
+-        printk(KERN_ERR "floating-pt emulation BUG at %s:%d!\n", __FILE__, __LINE__); \
+-} while (0)
+--- linux-2.6.0-test6/arch/parisc/mm/init.c	2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/parisc/mm/init.c	2003-10-05 00:33:23.000000000 -0700
+@@ -430,6 +430,8 @@ void free_initmem(void)
+ 				     & ~(VM_MAP_OFFSET-1)))
+ 
+ void *vmalloc_start;
++EXPORT_SYMBOL(vmalloc_start);
++
+ #ifdef CONFIG_PA11
+ unsigned long pcxl_dma_start;
+ #endif
+@@ -618,8 +620,6 @@ static void __init pagetable_init(void)
+ {
+ 	int range;
+ 
+-	printk("pagetable_init\n");
+-
+ 	/* Map each physical memory range to its kernel vaddr */
+ 
+ 	for (range = 0; range < npmem_ranges; range++) {
+--- linux-2.6.0-test6/arch/parisc/mm/ioremap.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/parisc/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -159,7 +159,7 @@ void * __ioremap(unsigned long phys_addr
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/ppc64/kernel/ioctl32.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/ppc64/kernel/ioctl32.c	2003-10-05 00:34:44.000000000 -0700
+@@ -328,396 +328,6 @@ static int do_ncp_setprivatedata(unsigne
+ 	return err;
+ }
+ 
+-struct usbdevfs_ctrltransfer32 {
+-	__u8 bRequestType;
+-	__u8 bRequest;
+-	__u16 wValue;
+-	__u16 wIndex;
+-	__u16 wLength;
+-	__u32 timeout;  /* in milliseconds */
+-	__u32 data;
+-};
+-
+-#define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+-
+-static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_ctrltransfer kctrl;
+-	struct usbdevfs_ctrltransfer32 *uctrl;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	int err;
+-
+-	uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+-
+-	if (copy_from_user(&kctrl, uctrl,
+-			   (sizeof(struct usbdevfs_ctrltransfer) -
+-			    sizeof(void *))))
+-		return -EFAULT;
+-
+-	if (get_user(udata, &uctrl->data))
+-		return -EFAULT;
+-	uptr = (void *) A(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kctrl.wLength > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *)__get_free_page(GFP_KERNEL);
+-
+-	if ((kctrl.bRequestType & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kctrl.wLength))
+-			goto out;
+-	}
+-
+-	kctrl.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kctrl.bRequestType & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kctrl.wLength))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-struct usbdevfs_bulktransfer32 {
+-	unsigned int ep;
+-	unsigned int len;
+-	unsigned int timeout; /* in milliseconds */
+-	__u32 data;
+-};
+-
+-#define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+-
+-static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_bulktransfer kbulk;
+-	struct usbdevfs_bulktransfer32 *ubulk;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	int err;
+-
+-	ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+-
+-	if (get_user(kbulk.ep, &ubulk->ep) ||
+-	    get_user(kbulk.len, &ubulk->len) ||
+-	    get_user(kbulk.timeout, &ubulk->timeout) ||
+-	    get_user(udata, &ubulk->data))
+-		return -EFAULT;
+-
+-	uptr = (void *) A(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kbulk.len > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *) __get_free_page(GFP_KERNEL);
+-
+-	if ((kbulk.ep & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kbulk.len))
+-			goto out;
+-	}
+-
+-	kbulk.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kbulk.ep & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kbulk.len))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-/* This needs more work before we can enable it.  Unfortunately
+- * because of the fancy asynchronous way URB status/error is written
+- * back to userspace, we'll need to fiddle with USB devio internals
+- * and/or reimplement entirely the frontend of it ourselves. -DaveM
+- *
+- * The issue is:
+- *
+- *	When an URB is submitted via usbdevicefs it is put onto an
+- *	asynchronous queue.  When the URB completes, it may be reaped
+- *	via another ioctl.  During this reaping the status is written
+- *	back to userspace along with the length of the transfer.
+- *
+- *	We must translate into 64-bit kernel types so we pass in a kernel
+- *	space copy of the usbdevfs_urb structure.  This would mean that we
+- *	must do something to deal with the async entry reaping.  First we
+- *	have to deal somehow with this transitory memory we've allocated.
+- *	This is problematic since there are many call sites from which the
+- *	async entries can be destroyed (and thus when we'd need to free up
+- *	this kernel memory).  One of which is the close() op of usbdevicefs.
+- *	To handle that we'd need to make our own file_operations struct which
+- *	overrides usbdevicefs's release op with our own which runs usbdevicefs's
+- *	real release op then frees up the kernel memory.
+- *
+- *	But how to keep track of these kernel buffers?  We'd need to either
+- *	keep track of them in some table _or_ know about usbdevicefs internals
+- *	(ie. the exact layout of its file private, which is actually defined
+- *	in linux/usbdevice_fs.h, the layout of the async queues are private to
+- *	devio.c)
+- *
+- * There is one possible other solution I considered, also involving knowledge
+- * of usbdevicefs internals:
+- *
+- *	After an URB is submitted, we "fix up" the address back to the user
+- *	space one.  This would work if the status/length fields written back
+- *	by the async URB completion lines up perfectly in the 32-bit type with
+- *	the 64-bit kernel type.  Unfortunately, it does not because the iso
+- *	frame descriptors, at the end of the struct, can be written back.
+- *
+- * I think we'll just need to simply duplicate the devio URB engine here.
+- */
+-#if 0
+-struct usbdevfs_urb32 {
+-	__u8 type;
+-	__u8 endpoint;
+-	__s32 status;
+-	__u32 flags;
+-	__u32 buffer;
+-	__s32 buffer_length;
+-	__s32 actual_length;
+-	__s32 start_frame;
+-	__s32 number_of_packets;
+-	__s32 error_count;
+-	__u32 signr;
+-	__u32 usercontext; /* unused */
+-	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+-};
+-
+-#define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
+-
+-static int get_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (get_user(kurb->type, &uurb->type) ||
+-	    __get_user(kurb->endpoint, &uurb->endpoint) ||
+-	    __get_user(kurb->status, &uurb->status) ||
+-	    __get_user(kurb->flags, &uurb->flags) ||
+-	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+-	    __get_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __get_user(kurb->start_frame, &uurb->start_frame) ||
+-	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+-	    __get_user(kurb->error_count, &uurb->error_count) ||
+-	    __get_user(kurb->signr, &uurb->signr))
+-		return -EFAULT;
+-
+-	kurb->usercontext = 0; /* unused currently */
+-
+-	return 0;
+-}
+-
+-/* Just put back the values which usbdevfs actually changes. */
+-static int put_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (put_user(kurb->status, &uurb->status) ||
+-	    __put_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __put_user(kurb->error_count, &uurb->error_count))
+-		return -EFAULT;
+-
+-	if (kurb->number_of_packets != 0) {
+-		int i;
+-
+-		for (i = 0; i < kurb->number_of_packets; i++) {
+-			if (__put_user(kurb->iso_frame_desc[i].actual_length,
+-				       &uurb->iso_frame_desc[i].actual_length) ||
+-			    __put_user(kurb->iso_frame_desc[i].status,
+-				       &uurb->iso_frame_desc[i].status))
+-				return -EFAULT;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+-			       struct usbdevfs_urb32 *uurb)
+-{
+-	unsigned int totlen;
+-	int i;
+-
+-	if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+-		kurb->number_of_packets = 0;
+-		return 0;
+-	}
+-
+-	if (kurb->number_of_packets < 1 ||
+-	    kurb->number_of_packets > 128)
+-		return -EINVAL;
+-
+-	if (copy_from_user(&kurb->iso_frame_desc[0],
+-			   &uurb->iso_frame_desc[0],
+-			   sizeof(struct usbdevfs_iso_packet_desc) *
+-			   kurb->number_of_packets))
+-		return -EFAULT;
+-
+-	totlen = 0;
+-	for (i = 0; i < kurb->number_of_packets; i++) {
+-		unsigned int this_len;
+-
+-		this_len = kurb->iso_frame_desc[i].length;
+-		if (this_len > 1023)
+-			return -EINVAL;
+-
+-		totlen += this_len;
+-	}
+-
+-	if (totlen > 32768)
+-		return -EINVAL;
+-
+-	kurb->buffer_length = totlen;
+-
+-	return 0;
+-}
+-
+-static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_urb *kurb;
+-	struct usbdevfs_urb32 *uurb;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	unsigned int buflen;
+-	int err;
+-
+-	uurb = (struct usbdevfs_urb32 *) arg;
+-
+-	err = -ENOMEM;
+-	kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+-		       (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+-		       GFP_KERNEL);
+-	if (!kurb)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (get_urb32(kurb, uurb))
+-		goto out;
+-
+-	err = get_urb32_isoframes(kurb, uurb);
+-	if (err)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (__get_user(udata, &uurb->buffer))
+-		goto out;
+-	uptr = (void *) A(udata);
+-
+-	err = -ENOMEM;
+-	buflen = kurb->buffer_length;
+-	kptr = kmalloc(buflen, GFP_KERNEL);
+-	if (!kptr)
+-		goto out;
+-
+-	kurb->buffer = kptr;
+-
+-	err = -EFAULT;
+-	if (copy_from_user(kptr, uptr, buflen))
+-		goto out_kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+-	set_fs(old_fs);
+-
+-	if (err >= 0) {
+-		/* XXX Shit, this doesn't work for async URBs :-( XXX */
+-		if (put_urb32(kurb, uurb)) {
+-			err = -EFAULT;
+-		} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
+-			if (copy_to_user(uptr, kptr, buflen))
+-				err = -EFAULT;
+-		}
+-	}
+-
+-out_kptr:
+-	kfree(kptr);
+-
+-out:
+-	kfree(kurb);
+-	return err;
+-}
+-#endif
+-
+-#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+-#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+-
+-static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	mm_segment_t old_fs;
+-	void *kptr;
+-	int err;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd,
+-			(cmd == USBDEVFS_REAPURB32 ?
+-			 USBDEVFS_REAPURB :
+-			 USBDEVFS_REAPURBNDELAY),
+-			(unsigned long) &kptr);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    put_user(((u32)(long)kptr), (u32 *) A(arg)))
+-		err = -EFAULT;
+-
+-	return err;
+-}
+-
+-struct usbdevfs_disconnectsignal32 {
+-	unsigned int signr;
+-	u32 context;
+-};
+-
+-#define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+-
+-static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_disconnectsignal kdis;
+-	struct usbdevfs_disconnectsignal32 *udis;
+-	mm_segment_t old_fs;
+-	u32 uctx;
+-	int err;
+-
+-	udis = (struct usbdevfs_disconnectsignal32 *) arg;
+-
+-	if (get_user(kdis.signr, &udis->signr) ||
+-	    __get_user(uctx, &udis->context))
+-		return -EFAULT;
+-
+-	kdis.context = (void *) (long)uctx;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+-	set_fs(old_fs);
+-
+-	return err;
+-}
+ 
+ #define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
+ #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
+@@ -734,8 +344,6 @@ IOCTL_TABLE_START
+ COMPATIBLE_IOCTL(TCSBRKP)
+ COMPATIBLE_IOCTL(TIOCSTART)
+ COMPATIBLE_IOCTL(TIOCSTOP)
+-COMPATIBLE_IOCTL(TIOCGSERIAL)
+-COMPATIBLE_IOCTL(TIOCSSERIAL)
+ COMPATIBLE_IOCTL(TIOCSLTC)
+ #if 0
+ COMPATIBLE_IOCTL(FBIOBLANK)
+@@ -755,13 +363,6 @@ HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, d
+ HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
+ HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
+ 
+-/* USB devfs */
+-HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
+-HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
+-/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+-HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+ IOCTL_TABLE_END
+ 
+ int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+--- linux-2.6.0-test6/arch/ppc64/kernel/process.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/ppc64/kernel/process.c	2003-10-05 00:33:23.000000000 -0700
+@@ -70,23 +70,6 @@ enable_kernel_fp(void)
+ #endif /* CONFIG_SMP */
+ }
+ 
+-#ifdef CONFIG_SMP
+-static void smp_unlazy_onefpu(void *arg)
+-{
+-	struct pt_regs *regs = current->thread.regs;
+-
+-	if (!regs)
+-		return;
+-	if (regs->msr & MSR_FP)
+-		giveup_fpu(current);
+-}
+-
+-void dump_smp_unlazy_fpu(void)
+-{
+-	smp_call_function(smp_unlazy_onefpu, NULL, 1, 1);
+-}
+-#endif
+-
+ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
+ {
+ 	struct pt_regs *regs = tsk->thread.regs;
+--- linux-2.6.0-test6/arch/ppc64/kernel/semaphore.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/ppc64/kernel/semaphore.c	2003-10-05 00:34:19.000000000 -0700
+@@ -21,6 +21,7 @@
+ #include <asm/semaphore.h>
+ #include <asm/errno.h>
+ 
++#if 0
+ /*
+  * Atomically update sem->count.
+  * This does the equivalent of the following:
+@@ -128,3 +129,140 @@ int __down_interruptible(struct semaphor
+ 	wake_up(&sem->wait);
+ 	return retval;
+ }
++#else
++
++static __inline__ int atomic_add_negative(int i, atomic_t *v)
++{
++	if (atomic_add_return(i, v) < 0)
++		return 1;
++	else
++		return 0;
++}
++
++void __up(struct semaphore *sem)
++{
++	wake_up(&sem->wait);
++}
++
++void __down(struct semaphore * sem)
++{
++	struct task_struct *tsk = current;
++	DECLARE_WAITQUEUE(wait, tsk);
++	unsigned long flags;
++
++	tsk->state = TASK_UNINTERRUPTIBLE;
++	spin_lock_irqsave(&sem->wait.lock, flags);
++	add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++	sem->sleepers++;
++	for (;;) {
++		int sleepers = sem->sleepers;
++
++		/*
++		 * Add "everybody else" into it. They aren't
++		 * playing, because we own the spinlock in
++		 * the wait_queue_head.
++		 */
++		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
++			sem->sleepers = 0;
++			break;
++		}
++		sem->sleepers = 1;	/* us - see -1 above */
++		spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++		schedule();
++
++		spin_lock_irqsave(&sem->wait.lock, flags);
++		tsk->state = TASK_UNINTERRUPTIBLE;
++	}
++	remove_wait_queue_locked(&sem->wait, &wait);
++	wake_up_locked(&sem->wait);
++	spin_unlock_irqrestore(&sem->wait.lock, flags);
++	tsk->state = TASK_RUNNING;
++}
++
++int __down_interruptible(struct semaphore * sem)
++{
++	int retval = 0;
++	struct task_struct *tsk = current;
++	DECLARE_WAITQUEUE(wait, tsk);
++	unsigned long flags;
++
++	tsk->state = TASK_INTERRUPTIBLE;
++	spin_lock_irqsave(&sem->wait.lock, flags);
++	add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++	sem->sleepers++;
++	for (;;) {
++		int sleepers = sem->sleepers;
++
++		/*
++		 * With signals pending, this turns into
++		 * the trylock failure case - we won't be
++		 * sleeping, and we* can't get the lock as
++		 * it has contention. Just correct the count
++		 * and exit.
++		 */
++		if (signal_pending(current)) {
++			retval = -EINTR;
++			sem->sleepers = 0;
++			atomic_add(sleepers, &sem->count);
++			break;
++		}
++
++		/*
++		 * Add "everybody else" into it. They aren't
++		 * playing, because we own the spinlock in
++		 * wait_queue_head. The "-1" is because we're
++		 * still hoping to get the semaphore.
++		 */
++		if (!atomic_add_negative(sleepers - 1, &sem->count)) {
++			sem->sleepers = 0;
++			break;
++		}
++		sem->sleepers = 1;	/* us - see -1 above */
++		spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++		schedule();
++
++		spin_lock_irqsave(&sem->wait.lock, flags);
++		tsk->state = TASK_INTERRUPTIBLE;
++	}
++	remove_wait_queue_locked(&sem->wait, &wait);
++	wake_up_locked(&sem->wait);
++	spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++	tsk->state = TASK_RUNNING;
++	return retval;
++}
++
++/*
++ * Trylock failed - make sure we correct for
++ * having decremented the count.
++ *
++ * We could have done the trylock with a
++ * single "cmpxchg" without failure cases,
++ * but then it wouldn't work on a 386.
++ */
++int __down_trylock(struct semaphore * sem)
++{
++	int sleepers;
++	unsigned long flags;
++
++	spin_lock_irqsave(&sem->wait.lock, flags);
++	sleepers = sem->sleepers + 1;
++	sem->sleepers = 0;
++
++	/*
++	 * Add "everybody else" and us into it. They aren't
++	 * playing, because we own the spinlock in the
++	 * wait_queue_head.
++	 */
++	if (!atomic_add_negative(sleepers, &sem->count)) {
++		wake_up_locked(&sem->wait);
++	}
++
++	spin_unlock_irqrestore(&sem->wait.lock, flags);
++	return 1;
++}
++#endif
+--- linux-2.6.0-test6/arch/ppc/boot/ld.script	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/ppc/boot/ld.script	2003-10-05 00:36:51.000000000 -0700
+@@ -82,6 +82,7 @@ SECTIONS
+     *(__ksymtab)
+     *(__ksymtab_strings)
+     *(__bug_table)
++    *(__kcrctab)
+   }
+ 
+ }
+--- linux-2.6.0-test6/arch/ppc/mm/cachemap.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/ppc/mm/cachemap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -101,7 +101,7 @@ void *consistent_alloc(int gfp, size_t s
+ 	if (! area)
+ 		goto out;
+ 
+-	va = VMALLOC_VMADDR(area->addr);
++	va = (unsigned long) area->addr;
+ 
+ 	flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+ 	
+--- linux-2.6.0-test6/arch/ppc/mm/pgtable.c	2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ppc/mm/pgtable.c	2003-10-05 00:33:23.000000000 -0700
+@@ -195,7 +195,7 @@ __ioremap(phys_addr_t addr, unsigned lon
+ 		area = get_vm_area(size, VM_IOREMAP);
+ 		if (area == 0)
+ 			return NULL;
+-		v = VMALLOC_VMADDR(area->addr);
++		v = (unsigned long) area->addr;
+ 	} else {
+ 		v = (ioremap_bot -= size);
+ 	}
+--- linux-2.6.0-test6/arch/s390/mm/ioremap.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/s390/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -124,7 +124,7 @@ void * __ioremap(unsigned long phys_addr
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/sh/mm/init.c	2003-07-27 12:14:38.000000000 -0700
++++ 25/arch/sh/mm/init.c	2003-10-05 00:34:40.000000000 -0700
+@@ -51,8 +51,8 @@ unsigned long mmu_context_cache = NO_CON
+ #endif
+ 
+ #ifdef CONFIG_DISCONTIGMEM
+-pg_data_t discontig_page_data[NR_NODES];
+-bootmem_data_t discontig_node_bdata[NR_NODES];
++pg_data_t discontig_page_data[MAX_NUMNODES];
++bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
+ #endif
+ 
+ void show_mem(void)
+--- linux-2.6.0-test6/arch/sh/mm/ioremap.c	2003-07-02 14:53:14.000000000 -0700
++++ 25/arch/sh/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -149,7 +149,7 @@ void * p3_ioremap(unsigned long phys_add
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/arch/sparc64/defconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/sparc64/defconfig	2003-10-05 00:33:23.000000000 -0700
+@@ -571,6 +571,7 @@ CONFIG_BRIDGE_EBT_T_NAT=m
+ CONFIG_BRIDGE_EBT_802_3=m
+ CONFIG_BRIDGE_EBT_ARP=m
+ CONFIG_BRIDGE_EBT_IP=m
++CONFIG_BRIDGE_EBT_LIMIT=m
+ CONFIG_BRIDGE_EBT_MARK=m
+ CONFIG_BRIDGE_EBT_PKTTYPE=m
+ CONFIG_BRIDGE_EBT_STP=m
+@@ -665,7 +666,7 @@ CONFIG_TUN=m
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
++CONFIG_MII=m
+ CONFIG_SUNLANCE=y
+ CONFIG_HAPPYMEAL=y
+ CONFIG_SUNBMAC=m
+@@ -729,15 +730,6 @@ CONFIG_YELLOWFIN=m
+ CONFIG_R8169=m
+ # CONFIG_SIS190 is not set
+ CONFIG_SK98LIN=m
+-CONFIG_CONFIG_SK98LIN_T1=y
+-CONFIG_CONFIG_SK98LIN_T2=y
+-CONFIG_CONFIG_SK98LIN_T3=y
+-CONFIG_CONFIG_SK98LIN_T4=y
+-CONFIG_CONFIG_SK98LIN_T5=y
+-CONFIG_CONFIG_SK98LIN_T6=y
+-CONFIG_CONFIG_SK98LIN_T7=y
+-CONFIG_CONFIG_SK98LIN_T8=y
+-CONFIG_CONFIG_SK98LIN_T9=y
+ CONFIG_TIGON3=m
+ 
+ #
+@@ -895,6 +887,30 @@ CONFIG_IRDA_FAST_RR=y
+ # CONFIG_VLSI_FIR is not set
+ 
+ #
++# Bluetooth support
++#
++CONFIG_BT=m
++CONFIG_BT_L2CAP=m
++CONFIG_BT_SCO=m
++CONFIG_BT_RFCOMM=m
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=m
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++
++#
++# Bluetooth device drivers
++#
++CONFIG_BT_HCIUSB=m
++CONFIG_BT_USB_SCO=y
++# CONFIG_BT_USB_ZERO_PACKET is not set
++CONFIG_BT_HCIUART=m
++CONFIG_BT_HCIUART_H4=y
++CONFIG_BT_HCIUART_BCSP=y
++CONFIG_BT_HCIUART_BCSP_TXCRC=y
++CONFIG_BT_HCIVHCI=m
++
++#
+ # ISDN subsystem
+ #
+ CONFIG_ISDN_BOOL=y
+@@ -1517,30 +1533,6 @@ CONFIG_USB_TEST=m
+ # CONFIG_USB_GADGET is not set
+ 
+ #
+-# Bluetooth support
+-#
+-CONFIG_BT=m
+-CONFIG_BT_L2CAP=m
+-CONFIG_BT_SCO=m
+-CONFIG_BT_RFCOMM=m
+-CONFIG_BT_RFCOMM_TTY=y
+-CONFIG_BT_BNEP=m
+-CONFIG_BT_BNEP_MC_FILTER=y
+-CONFIG_BT_BNEP_PROTO_FILTER=y
+-
+-#
+-# Bluetooth device drivers
+-#
+-CONFIG_BT_HCIUSB=m
+-CONFIG_BT_USB_SCO=y
+-# CONFIG_BT_USB_ZERO_PACKET is not set
+-CONFIG_BT_HCIUART=m
+-CONFIG_BT_HCIUART_H4=y
+-CONFIG_BT_HCIUART_BCSP=y
+-CONFIG_BT_HCIUART_BCSP_TXCRC=y
+-CONFIG_BT_HCIVHCI=m
+-
+-#
+ # Watchdog
+ #
+ # CONFIG_SOFT_WATCHDOG is not set
+--- linux-2.6.0-test6/arch/sparc64/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/sparc64/Kconfig	2003-10-05 00:36:40.000000000 -0700
+@@ -787,12 +787,19 @@ config DEBUG_SPINLOCK
+ 	  best used in conjunction with the NMI watchdog so that spinlock
+ 	  deadlocks are also debuggable.
+ 
++config LOCKMETER
++	bool "Kernel lock metering"
++	depends on SMP && !PREEMPT
++	help
++	  Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++	  but allows you to see various statistics using the lockstat command.
++
+ # We have a custom atomic_dec_and_lock() implementation but it's not
+ # compatible with spinlock debugging so we need to fall back on
+ # the generic version in that case.
+ config HAVE_DEC_LOCK
+ 	bool
+-	depends on !DEBUG_SPINLOCK
++	depends on !DEBUG_SPINLOCK && !LOCKMETER
+ 	default y
+ 
+ config DEBUG_SPINLOCK_SLEEP
+--- linux-2.6.0-test6/arch/sparc64/kernel/entry.S	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/sparc64/kernel/entry.S	2003-10-05 00:33:23.000000000 -0700
+@@ -26,7 +26,7 @@
+ 
+ #define curptr      g6
+ 
+-#define NR_SYSCALLS 267      /* Each OS is different... */
++#define NR_SYSCALLS 268      /* Each OS is different... */
+ 
+ 	.text
+ 	.align		32
+--- linux-2.6.0-test6/arch/sparc64/kernel/ioctl32.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/sparc64/kernel/ioctl32.c	2003-10-05 00:34:44.000000000 -0700
+@@ -985,402 +985,6 @@ static int drm32_res_ctx(unsigned int fd
+ 
+ #endif
+ 
+-/* HERE! */
+-
+-struct usbdevfs_ctrltransfer32 {
+-	__u8 bRequestType;
+-	__u8 bRequest;
+-	__u16 wValue;
+-	__u16 wIndex;
+-	__u16 wLength;
+-	__u32 timeout;  /* in milliseconds */
+-	__u32 data;
+-};
+-
+-#define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+-
+-static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_ctrltransfer kctrl;
+-	struct usbdevfs_ctrltransfer32 *uctrl;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void __user *uptr;
+-	void *kptr;
+-	int err;
+-
+-	uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+-
+-	if (copy_from_user(&kctrl, uctrl,
+-			   (sizeof(struct usbdevfs_ctrltransfer) -
+-			    sizeof(void *))))
+-		return -EFAULT;
+-
+-	if (get_user(udata, &uctrl->data))
+-		return -EFAULT;
+-	uptr = A(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kctrl.wLength > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *)__get_free_page(GFP_KERNEL);
+-
+-	if ((kctrl.bRequestType & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kctrl.wLength))
+-			goto out;
+-	}
+-
+-	kctrl.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kctrl.bRequestType & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kctrl.wLength))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-struct usbdevfs_bulktransfer32 {
+-	unsigned int ep;
+-	unsigned int len;
+-	unsigned int timeout; /* in milliseconds */
+-	__u32 data;
+-};
+-
+-#define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+-
+-static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_bulktransfer kbulk;
+-	struct usbdevfs_bulktransfer32 *ubulk;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void __user *uptr;
+-	void *kptr;
+-	int err;
+-
+-	ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+-
+-	if (get_user(kbulk.ep, &ubulk->ep) ||
+-	    get_user(kbulk.len, &ubulk->len) ||
+-	    get_user(kbulk.timeout, &ubulk->timeout) ||
+-	    get_user(udata, &ubulk->data))
+-		return -EFAULT;
+-
+-	uptr = A(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kbulk.len > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *) __get_free_page(GFP_KERNEL);
+-
+-	if ((kbulk.ep & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kbulk.len))
+-			goto out;
+-	}
+-
+-	kbulk.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kbulk.ep & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kbulk.len))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-/* This needs more work before we can enable it.  Unfortunately
+- * because of the fancy asynchronous way URB status/error is written
+- * back to userspace, we'll need to fiddle with USB devio internals
+- * and/or reimplement entirely the frontend of it ourselves. -DaveM
+- *
+- * The issue is:
+- *
+- *	When an URB is submitted via usbdevicefs it is put onto an
+- *	asynchronous queue.  When the URB completes, it may be reaped
+- *	via another ioctl.  During this reaping the status is written
+- *	back to userspace along with the length of the transfer.
+- *
+- *	We must translate into 64-bit kernel types so we pass in a kernel
+- *	space copy of the usbdevfs_urb structure.  This would mean that we
+- *	must do something to deal with the async entry reaping.  First we
+- *	have to deal somehow with this transitory memory we've allocated.
+- *	This is problematic since there are many call sites from which the
+- *	async entries can be destroyed (and thus when we'd need to free up
+- *	this kernel memory).  One of which is the close() op of usbdevicefs.
+- *	To handle that we'd need to make our own file_operations struct which
+- *	overrides usbdevicefs's release op with our own which runs usbdevicefs's
+- *	real release op then frees up the kernel memory.
+- *
+- *	But how to keep track of these kernel buffers?  We'd need to either
+- *	keep track of them in some table _or_ know about usbdevicefs internals
+- *	(ie. the exact layout of its file private, which is actually defined
+- *	in linux/usbdevice_fs.h, the layout of the async queues are private to
+- *	devio.c)
+- *
+- * There is one possible other solution I considered, also involving knowledge
+- * of usbdevicefs internals:
+- *
+- *	After an URB is submitted, we "fix up" the address back to the user
+- *	space one.  This would work if the status/length fields written back
+- *	by the async URB completion lines up perfectly in the 32-bit type with
+- *	the 64-bit kernel type.  Unfortunately, it does not because the iso
+- *	frame descriptors, at the end of the struct, can be written back.
+- *
+- * I think we'll just need to simply duplicate the devio URB engine here.
+- */
+-#if 0
+-struct usbdevfs_urb32 {
+-	__u8 type;
+-	__u8 endpoint;
+-	__s32 status;
+-	__u32 flags;
+-	__u32 buffer;
+-	__s32 buffer_length;
+-	__s32 actual_length;
+-	__s32 start_frame;
+-	__s32 number_of_packets;
+-	__s32 error_count;
+-	__u32 signr;
+-	__u32 usercontext; /* unused */
+-	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+-};
+-
+-#define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
+-
+-static int get_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (get_user(kurb->type, &uurb->type) ||
+-	    __get_user(kurb->endpoint, &uurb->endpoint) ||
+-	    __get_user(kurb->status, &uurb->status) ||
+-	    __get_user(kurb->flags, &uurb->flags) ||
+-	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+-	    __get_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __get_user(kurb->start_frame, &uurb->start_frame) ||
+-	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+-	    __get_user(kurb->error_count, &uurb->error_count) ||
+-	    __get_user(kurb->signr, &uurb->signr))
+-		return -EFAULT;
+-
+-	kurb->usercontext = 0; /* unused currently */
+-
+-	return 0;
+-}
+-
+-/* Just put back the values which usbdevfs actually changes. */
+-static int put_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (put_user(kurb->status, &uurb->status) ||
+-	    __put_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __put_user(kurb->error_count, &uurb->error_count))
+-		return -EFAULT;
+-
+-	if (kurb->number_of_packets != 0) {
+-		int i;
+-
+-		for (i = 0; i < kurb->number_of_packets; i++) {
+-			if (__put_user(kurb->iso_frame_desc[i].actual_length,
+-				       &uurb->iso_frame_desc[i].actual_length) ||
+-			    __put_user(kurb->iso_frame_desc[i].status,
+-				       &uurb->iso_frame_desc[i].status))
+-				return -EFAULT;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+-			       struct usbdevfs_urb32 *uurb)
+-{
+-	unsigned int totlen;
+-	int i;
+-
+-	if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+-		kurb->number_of_packets = 0;
+-		return 0;
+-	}
+-
+-	if (kurb->number_of_packets < 1 ||
+-	    kurb->number_of_packets > 128)
+-		return -EINVAL;
+-
+-	if (copy_from_user(&kurb->iso_frame_desc[0],
+-			   &uurb->iso_frame_desc[0],
+-			   sizeof(struct usbdevfs_iso_packet_desc) *
+-			   kurb->number_of_packets))
+-		return -EFAULT;
+-
+-	totlen = 0;
+-	for (i = 0; i < kurb->number_of_packets; i++) {
+-		unsigned int this_len;
+-
+-		this_len = kurb->iso_frame_desc[i].length;
+-		if (this_len > 1023)
+-			return -EINVAL;
+-
+-		totlen += this_len;
+-	}
+-
+-	if (totlen > 32768)
+-		return -EINVAL;
+-
+-	kurb->buffer_length = totlen;
+-
+-	return 0;
+-}
+-
+-static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_urb *kurb;
+-	struct usbdevfs_urb32 *uurb;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void __user *uptr;
+-	void *kptr;
+-	unsigned int buflen;
+-	int err;
+-
+-	uurb = (struct usbdevfs_urb32 *) arg;
+-
+-	err = -ENOMEM;
+-	kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+-		       (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+-		       GFP_KERNEL);
+-	if (!kurb)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (get_urb32(kurb, uurb))
+-		goto out;
+-
+-	err = get_urb32_isoframes(kurb, uurb);
+-	if (err)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (__get_user(udata, &uurb->buffer))
+-		goto out;
+-	uptr = A(udata);
+-
+-	err = -ENOMEM;
+-	buflen = kurb->buffer_length;
+-	kptr = kmalloc(buflen, GFP_KERNEL);
+-	if (!kptr)
+-		goto out;
+-
+-	kurb->buffer = kptr;
+-
+-	err = -EFAULT;
+-	if (copy_from_user(kptr, uptr, buflen))
+-		goto out_kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+-	set_fs(old_fs);
+-
+-	if (err >= 0) {
+-		/* XXX Shit, this doesn't work for async URBs :-( XXX */
+-		if (put_urb32(kurb, uurb)) {
+-			err = -EFAULT;
+-		} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
+-			if (copy_to_user(uptr, kptr, buflen))
+-				err = -EFAULT;
+-		}
+-	}
+-
+-out_kptr:
+-	kfree(kptr);
+-
+-out:
+-	kfree(kurb);
+-	return err;
+-}
+-#endif
+-
+-#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+-#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+-
+-static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	mm_segment_t old_fs;
+-	void *kptr;
+-	int err;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd,
+-			(cmd == USBDEVFS_REAPURB32 ?
+-			 USBDEVFS_REAPURB :
+-			 USBDEVFS_REAPURBNDELAY),
+-			(unsigned long) &kptr);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    put_user(((u32)(long)kptr), (u32 __user *) A(arg)))
+-		err = -EFAULT;
+-
+-	return err;
+-}
+-
+-struct usbdevfs_disconnectsignal32 {
+-	unsigned int signr;
+-	u32 context;
+-};
+-
+-#define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+-
+-static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_disconnectsignal kdis;
+-	struct usbdevfs_disconnectsignal32 *udis;
+-	mm_segment_t old_fs;
+-	u32 uctx;
+-	int err;
+-
+-	udis = (struct usbdevfs_disconnectsignal32 *) arg;
+-
+-	if (get_user(kdis.signr, &udis->signr) ||
+-	    __get_user(uctx, &udis->context))
+-		return -EFAULT;
+-
+-	kdis.context = (void *) (long)uctx;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+-	set_fs(old_fs);
+-
+-	return err;
+-}
+-
+ typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
+ 
+ #define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
+@@ -1397,8 +1001,6 @@ IOCTL_TABLE_START
+ COMPATIBLE_IOCTL(TCSBRKP)
+ COMPATIBLE_IOCTL(TIOCSTART)
+ COMPATIBLE_IOCTL(TIOCSTOP)
+-COMPATIBLE_IOCTL(TIOCGSERIAL)
+-COMPATIBLE_IOCTL(TIOCSSERIAL)
+ COMPATIBLE_IOCTL(TIOCSLTC)
+ COMPATIBLE_IOCTL(FBIOGTYPE)
+ COMPATIBLE_IOCTL(FBIOSATTR)
+@@ -1467,9 +1069,6 @@ COMPATIBLE_IOCTL(AUDIO_GETDEV)
+ COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS)
+ COMPATIBLE_IOCTL(AUDIO_FLUSH)
+ COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
+-/* Raw devices */
+-COMPATIBLE_IOCTL(RAW_SETBIND)
+-COMPATIBLE_IOCTL(RAW_GETBIND)
+ /* NCP ioctls which do not need any translations */
+ COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
+ COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
+@@ -1575,12 +1174,6 @@ HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioct
+ HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)
+ HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)
+ #endif
+-HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
+-HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
+-/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+-HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+ /* take care of sizeof(sizeof()) breakage */
+ IOCTL_TABLE_END
+ 
+--- linux-2.6.0-test6/arch/sparc64/kernel/module.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/sparc64/kernel/module.c	2003-10-05 00:33:23.000000000 -0700
+@@ -14,6 +14,9 @@
+ #include <linux/vmalloc.h>
+ #include <linux/mm.h>
+ 
++#include <asm/processor.h>
++#include <asm/spitfire.h>
++
+ static struct vm_struct * modvmlist = NULL;
+ 
+ static void module_unmap(void * addr)
+@@ -279,6 +282,16 @@ int module_finalize(const Elf_Ehdr *hdr,
+ 		    const Elf_Shdr *sechdrs,
+ 		    struct module *me)
+ {
++	/* Cheetah's I-cache is fully coherent.  */
++	if (tlb_type == spitfire) {
++		unsigned long va;
++
++		flushw_all();
++		for (va =  0; va < (PAGE_SIZE << 1); va += 32)
++			spitfire_put_icache_tag(va, 0x0);
++		__asm__ __volatile__("flush %g6");
++	}
++
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/arch/sparc64/kernel/smp.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/sparc64/kernel/smp.c	2003-10-05 00:33:23.000000000 -0700
+@@ -118,7 +118,6 @@ void __init smp_callin(void)
+ 
+ 	inherit_locked_prom_mappings(0);
+ 
+-	__flush_cache_all();
+ 	__flush_tlb_all();
+ 
+ 	smp_setup_percpu_timer();
+@@ -661,7 +660,6 @@ extern unsigned long xcall_flush_tlb_ran
+ extern unsigned long xcall_flush_tlb_kernel_range;
+ extern unsigned long xcall_flush_tlb_all_spitfire;
+ extern unsigned long xcall_flush_tlb_all_cheetah;
+-extern unsigned long xcall_flush_cache_all_spitfire;
+ extern unsigned long xcall_report_regs;
+ extern unsigned long xcall_receive_signal;
+ extern unsigned long xcall_flush_dcache_page_cheetah;
+@@ -776,15 +774,6 @@ void smp_report_regs(void)
+ 	smp_cross_call(&xcall_report_regs, 0, 0, 0);
+ }
+ 
+-void smp_flush_cache_all(void)
+-{
+-	/* Cheetah need do nothing. */
+-	if (tlb_type == spitfire) {
+-		smp_cross_call(&xcall_flush_cache_all_spitfire, 0, 0, 0);
+-		__flush_cache_all();
+-	}
+-}
+-
+ void smp_flush_tlb_all(void)
+ {
+ 	if (tlb_type == spitfire)
+--- linux-2.6.0-test6/arch/sparc64/kernel/systbls.S	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/sparc64/kernel/systbls.S	2003-10-05 00:33:23.000000000 -0700
+@@ -72,7 +72,7 @@ sys_call_table32:
+ /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
+ 	.word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep
+ /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun
+-	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall
++	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall
+ 
+ 	/* Now the 64-bit native Linux syscall table. */
+ 
+@@ -133,7 +133,7 @@ sys_call_table:
+ /*250*/	.word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+ 	.word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
+ /*260*/	.word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
+-	.word sys_timer_delete, sys_timer_create, sys_ni_syscall
++	.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_ni_syscall
+ 
+ #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
+     defined(CONFIG_SOLARIS_EMUL_MODULE)
+@@ -233,5 +233,6 @@ sunos_sys_table:
+ 	.word sunos_nosys, sunos_nosys, sunos_nosys
+ 	.word sunos_nosys, sunos_nosys, sunos_nosys
+ 	.word sunos_nosys, sunos_nosys, sunos_nosys
++	.word sunos_nosys
+ 
+ #endif
+--- linux-2.6.0-test6/arch/sparc64/lib/rwlock.S	2003-06-26 22:07:24.000000000 -0700
++++ 25/arch/sparc64/lib/rwlock.S	2003-10-05 00:36:40.000000000 -0700
+@@ -63,5 +63,33 @@ __write_lock: /* %o0 = lock_ptr */
+ 	be,pt		%icc, 99b
+ 	 membar		#StoreLoad | #StoreStore
+ 	ba,a,pt		%xcc, 1b
++
++	.globl	__read_trylock
++__read_trylock: /* %o0 = lock_ptr */
++	ldsw		[%o0], %g5
++	brlz,pn		%g5, 100f
++	 add		%g5, 1, %g7
++	cas		[%o0], %g5, %g7
++	cmp		%g5, %g7
++	bne,pn		%icc, __read_trylock
++	 membar		#StoreLoad | #StoreStore
++	retl
++	 mov		1, %o0
++
++	.globl		__write_trylock
++__write_trylock: /* %o0 = lock_ptr */
++	sethi		%hi(0x80000000), %g2
++1:	lduw		[%o0], %g5
++4:	brnz,pn		%g5, 100f
++	 or		%g5, %g2, %g7
++	cas		[%o0], %g5, %g7
++	cmp		%g5, %g7
++	bne,pn		%icc, 1b
++	 membar		#StoreLoad | #StoreStore
++	retl
++	 mov		1, %o0
++100:	retl
++	 mov		0, %o0
++
+ rwlock_impl_end:
+ 
+--- linux-2.6.0-test6/arch/sparc64/mm/init.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/sparc64/mm/init.c	2003-10-05 00:33:23.000000000 -0700
+@@ -1025,19 +1025,6 @@ void __flush_dcache_range(unsigned long 
+ 	}
+ }
+ 
+-void __flush_cache_all(void)
+-{
+-	/* Cheetah should be fine here too. */
+-	if (tlb_type == spitfire) {
+-		unsigned long va;
+-
+-		flushw_all();
+-		for (va =  0; va < (PAGE_SIZE << 1); va += 32)
+-			spitfire_put_icache_tag(va, 0x0);
+-		__asm__ __volatile__("flush %g6");
+-	}
+-}
+-
+ /* If not locked, zap it. */
+ void __flush_tlb_all(void)
+ {
+--- linux-2.6.0-test6/arch/sparc64/mm/ultra.S	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/sparc64/mm/ultra.S	2003-10-05 00:33:23.000000000 -0700
+@@ -721,20 +721,6 @@ xcall_flush_tlb_all_cheetah:
+ 	stxa		%g0, [%g2] ASI_IMMU_DEMAP
+ 	retry
+ 
+-	.globl		xcall_flush_cache_all_spitfire
+-xcall_flush_cache_all_spitfire:
+-	sethi		%hi(16383), %g2
+-	or		%g2, %lo(16383), %g2
+-	clr		%g3
+-1:	stxa		%g0, [%g3] ASI_IC_TAG
+-	membar		#Sync
+-	add		%g3, 32, %g3
+-	cmp		%g3, %g2
+-	bleu,pt		%xcc, 1b
+-	 nop
+-	flush		%g6
+-	retry
+-
+ 	/* These just get rescheduled to PIL vectors. */
+ 	.globl		xcall_call_function
+ xcall_call_function:
+--- linux-2.6.0-test6/arch/sparc/kernel/entry.S	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/sparc/kernel/entry.S	2003-10-05 00:33:23.000000000 -0700
+@@ -38,7 +38,7 @@
+ 
+ #define curptr      g6
+ 
+-#define NR_SYSCALLS 267      /* Each OS is different... */
++#define NR_SYSCALLS 268      /* Each OS is different... */
+ 
+ /* These are just handy. */
+ #define _SV	save	%sp, -STACKFRAME_SZ, %sp
+--- linux-2.6.0-test6/arch/sparc/kernel/systbls.S	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/sparc/kernel/systbls.S	2003-10-05 00:33:23.000000000 -0700
+@@ -72,7 +72,7 @@ sys_call_table:
+ /*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
+ /*255*/	.long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
+ /*260*/	.long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
+-/*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall
++/*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_nis_syscall
+ 
+ #ifdef CONFIG_SUNOS_EMUL
+ 	/* Now the SunOS syscall table. */
+@@ -171,6 +171,6 @@ sunos_sys_table:
+ 	.long sunos_nosys
+ /*260*/	.long sunos_nosys, sunos_nosys, sunos_nosys
+ 	.long sunos_nosys, sunos_nosys, sunos_nosys
+-	.long sunos_nosys, sunos_nosys
++	.long sunos_nosys, sunos_nosys, sunos_nosys
+ 
+ #endif
+--- linux-2.6.0-test6/arch/sparc/kernel/time.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/arch/sparc/kernel/time.c	2003-10-05 00:36:33.000000000 -0700
+@@ -617,3 +617,12 @@ static int set_rtc_mmss(unsigned long no
+ 		return -1;
+ 	}
+ }
++
++/*
++ * Returns nanoseconds
++  */
++
++unsigned long long sched_clock(void)
++{
++	return (unsigned long long)jiffies * (1000000000 / HZ);
++}
+--- linux-2.6.0-test6/arch/um/config.release	2003-08-08 22:55:11.000000000 -0700
++++ 25/arch/um/config.release	2003-10-05 00:34:32.000000000 -0700
+@@ -228,7 +228,6 @@ CONFIG_ROMFS_FS=m
+ CONFIG_EXT2_FS=y
+ CONFIG_SYSV_FS=m
+ CONFIG_UDF_FS=m
+-# CONFIG_UDF_RW is not set
+ CONFIG_UFS_FS=m
+ # CONFIG_UFS_FS_WRITE is not set
+ 
+--- linux-2.6.0-test6/arch/um/defconfig	2003-08-08 22:55:11.000000000 -0700
++++ 25/arch/um/defconfig	2003-10-05 00:34:32.000000000 -0700
+@@ -3,29 +3,19 @@
+ #
+ CONFIG_USERMODE=y
+ CONFIG_MMU=y
+-CONFIG_SWAP=y
+ CONFIG_UID16=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+-CONFIG_CONFIG_LOG_BUF_SHIFT=14
+-
+-#
+-# Code maturity level options
+-#
+-CONFIG_EXPERIMENTAL=y
+ 
+ #
+-# General Setup
++# UML-specific options
+ #
+ CONFIG_MODE_TT=y
+ CONFIG_MODE_SKAS=y
+ CONFIG_NET=y
+-CONFIG_SYSVIPC=y
+-CONFIG_BSD_PROCESS_ACCT=y
+-CONFIG_SYSCTL=y
+-CONFIG_BINFMT_AOUT=y
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=y
+ CONFIG_HOSTFS=y
++CONFIG_HPPFS=y
+ CONFIG_MCONSOLE=y
+ CONFIG_MAGIC_SYSRQ=y
+ # CONFIG_HOST_2G_2G is not set
+@@ -38,10 +28,38 @@ CONFIG_PROC_MM=y
+ CONFIG_KERNEL_STACK_ORDER=2
+ 
+ #
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_STANDALONE=y
++CONFIG_BROKEN_ON_SMP=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_IKCONFIG is not set
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++
++#
+ # Loadable module support
+ #
+-CONFIG_MODULES=y
+-# CONFIG_KMOD is not set
++# CONFIG_MODULES is not set
++
++#
++# Generic Driver Options
++#
+ 
+ #
+ # Character Devices
+@@ -69,6 +87,7 @@ CONFIG_HOSTAUDIO=y
+ #
+ CONFIG_BLK_DEV_UBD=y
+ # CONFIG_BLK_DEV_UBD_SYNC is not set
++CONFIG_BLK_DEV_COW_COMMON=y
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_NBD=y
+ CONFIG_BLK_DEV_RAM=y
+@@ -78,7 +97,7 @@ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_NETDEVICES=y
+ 
+ #
+-# Network Devices
++# UML Network Devices
+ #
+ CONFIG_UML_NET=y
+ CONFIG_UML_NET_ETHERTAP=y
+@@ -88,22 +107,6 @@ CONFIG_UML_NET_DAEMON=y
+ CONFIG_UML_NET_MCAST=y
+ # CONFIG_UML_NET_PCAP is not set
+ CONFIG_UML_NET_SLIRP=y
+-CONFIG_DUMMY=y
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-CONFIG_TUN=y
+-# CONFIG_ETHERTAP is not set
+-CONFIG_PPP=y
+-# CONFIG_PPP_MULTILINK is not set
+-# CONFIG_PPP_ASYNC is not set
+-# CONFIG_PPP_SYNC_TTY is not set
+-# CONFIG_PPP_DEFLATE is not set
+-# CONFIG_PPP_BSDCOMP is not set
+-# CONFIG_PPPOE is not set
+-CONFIG_SLIP=y
+-# CONFIG_SLIP_COMPRESSED is not set
+-# CONFIG_SLIP_SMART is not set
+-# CONFIG_SLIP_MODE_SLIP6 is not set
+ 
+ #
+ # Networking support
+@@ -115,8 +118,6 @@ CONFIG_SLIP=y
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+ # CONFIG_NETLINK_DEV is not set
+-# CONFIG_NETFILTER is not set
+-# CONFIG_FILTER is not set
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+@@ -130,8 +131,11 @@ CONFIG_INET=y
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+ # CONFIG_INET_ESP is not set
+-# CONFIG_XFRM_USER is not set
++# CONFIG_INET_IPCOMP is not set
+ # CONFIG_IPV6 is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NETFILTER is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -141,8 +145,6 @@ CONFIG_IPV6_SCTP__=y
+ # CONFIG_ATM is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_LLC is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_NET_DIVERT is not set
+@@ -160,6 +162,10 @@ CONFIG_IPV6_SCTP__=y
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=y
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -171,6 +177,22 @@ CONFIG_IPV6_SCTP__=y
+ #
+ 
+ #
++# Ethernet (10000 Mbit)
++#
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++# CONFIG_PPP_ASYNC is not set
++# CONFIG_PPP_SYNC_TTY is not set
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=y
++# CONFIG_SLIP_COMPRESSED is not set
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++
++#
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
+@@ -188,66 +210,82 @@ CONFIG_IPV6_SCTP__=y
+ #
+ # File systems
+ #
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_REISERFS_FS=y
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_ROMFS_FS is not set
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ # CONFIG_QFMT_V2 is not set
+ CONFIG_QUOTACTL=y
+-CONFIG_AUTOFS_FS=m
+-CONFIG_AUTOFS4_FS=m
+-CONFIG_REISERFS_FS=m
+-# CONFIG_REISERFS_CHECK is not set
+-# CONFIG_REISERFS_PROC_INFO is not set
++CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS4_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# CONFIG_DEVFS_DEBUG is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+-# CONFIG_EXT3_FS is not set
+-# CONFIG_JBD is not set
+-CONFIG_FAT_FS=m
+-CONFIG_MSDOS_FS=m
+-CONFIG_VFAT_FS=m
+ # CONFIG_EFS_FS is not set
+ CONFIG_JFFS_FS=y
+ CONFIG_JFFS_FS_VERBOSE=0
+-CONFIG_JFFS_PROC_FS=y
+ # CONFIG_JFFS2_FS is not set
+ # CONFIG_CRAMFS is not set
+-# CONFIG_TMPFS is not set
+-CONFIG_RAMFS=y
+-CONFIG_ISO9660_FS=m
+-# CONFIG_JOLIET is not set
+-# CONFIG_ZISOFS is not set
+-# CONFIG_JFS_FS is not set
+-CONFIG_MINIX_FS=m
+ # CONFIG_VXFS_FS is not set
+-# CONFIG_NTFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+-CONFIG_PROC_FS=y
+-CONFIG_DEVFS_FS=y
+-CONFIG_DEVFS_MOUNT=y
+-# CONFIG_DEVFS_DEBUG is not set
+-CONFIG_DEVPTS_FS=y
+ # CONFIG_QNX4FS_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_SYSV_FS is not set
+-# CONFIG_UDF_FS is not set
+ # CONFIG_UFS_FS is not set
+-# CONFIG_XFS_FS is not set
+ 
+ #
+ # Network File Systems
+ #
+-# CONFIG_CODA_FS is not set
+-# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_NFS_FS is not set
+ # CONFIG_NFSD is not set
+ # CONFIG_EXPORTFS is not set
+-# CONFIG_CIFS is not set
+ # CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_AFS_FS is not set
+ 
+ #
+@@ -317,28 +355,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # SCSI support
+ #
+-CONFIG_SCSI=y
+-CONFIG_GENERIC_ISA_DMA=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-CONFIG_SD_EXTRA_DEVS=40
+-CONFIG_CHR_DEV_ST=y
+-CONFIG_BLK_DEV_SR=y
+-CONFIG_BLK_DEV_SR_VENDOR=y
+-CONFIG_SR_EXTRA_DEVS=2
+-CONFIG_CHR_DEV_SG=y
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-CONFIG_SCSI_DEBUG_QUEUES=y
+-CONFIG_SCSI_MULTI_LUN=y
+-CONFIG_SCSI_CONSTANTS=y
+-CONFIG_SCSI_LOGGING=y
+-CONFIG_SCSI_DEBUG=y
++# CONFIG_SCSI is not set
+ 
+ #
+ # Multi-device support (RAID and LVM)
+@@ -360,6 +377,7 @@ CONFIG_MTD_CHAR=y
+ CONFIG_MTD_BLOCK=y
+ # CONFIG_FTL is not set
+ # CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
+ 
+ #
+ # RAM/ROM/Flash chip drivers
+@@ -374,20 +392,21 @@ CONFIG_MTD_BLOCK=y
+ #
+ # Mapping drivers for chip access
+ #
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ 
+ #
+ # Self-contained MTD device drivers
+ #
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+-CONFIG_MTD_BLKMTD=m
++CONFIG_MTD_BLKMTD=y
+ 
+ #
+ # Disk-On-Chip Device Drivers
+ #
+-# CONFIG_MTD_DOC1000 is not set
+ # CONFIG_MTD_DOC2000 is not set
+ # CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
+ 
+ #
+ # NAND Flash Device Drivers
+--- linux-2.6.0-test6/arch/um/drivers/chan_kern.c	2003-06-14 12:18:35.000000000 -0700
++++ 25/arch/um/drivers/chan_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -8,6 +8,7 @@
+ #include <linux/list.h>
+ #include <linux/slab.h>
+ #include <linux/tty.h>
++#include <linux/string.h>
+ #include <linux/tty_flip.h>
+ #include <asm/irq.h>
+ #include "chan_kern.h"
+--- linux-2.6.0-test6/arch/um/drivers/chan_user.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/um/drivers/chan_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -188,8 +188,8 @@ void register_winch(int fd, void *device
+ 	if(!isatty(fd)) return;
+ 
+ 	pid = tcgetpgrp(fd);
+-	if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
+-	   (pid == -1)){
++	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
++			     device_data) && (pid == -1)){
+ 		thread = winch_tramp(fd, device_data, &thread_fd);
+ 		if(fd != -1){
+ 			register_winch_irq(thread_fd, fd, thread, device_data);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/um/drivers/cow.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,40 @@
++#ifndef __COW_H__
++#define __COW_H__
++
++#include <asm/types.h>
++
++#if __BYTE_ORDER == __BIG_ENDIAN
++# define ntohll(x) (x)
++# define htonll(x) (x)
++#elif __BYTE_ORDER == __LITTLE_ENDIAN
++# define ntohll(x)  bswap_64(x)
++# define htonll(x)  bswap_64(x)
++#else
++#error "__BYTE_ORDER not defined"
++#endif
++
++extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
++			 int sectorsize, int *bitmap_offset_out, 
++			 unsigned long *bitmap_len_out, int *data_offset_out);
++
++extern int file_reader(__u64 offset, char *buf, int len, void *arg);
++extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
++			   void *arg, __u32 *magic_out, 
++			   char **backing_file_out, time_t *mtime_out, 
++			   __u64 *size_out, int *sectorsize_out, 
++			   int *bitmap_offset_out);
++
++extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
++			    int sectorsize, long long *size);
++
++extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
++		      unsigned long *bitmap_len_out, int *data_offset_out);
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/um/drivers/cow_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,628 @@
++#define COW_MAJOR 60
++#define MAJOR_NR COW_MAJOR
++
++#include <linux/stddef.h>
++#include <linux/kernel.h>
++#include <linux/ctype.h>
++#include <linux/stat.h>
++#include <linux/vmalloc.h>
++#include <linux/blkdev.h>
++#include <linux/blk.h>
++#include <linux/fs.h>
++#include <linux/genhd.h>
++#include <linux/devfs_fs.h>
++#include <asm/uaccess.h>
++#include "2_5compat.h"
++#include "cow.h"
++#include "ubd_user.h"
++
++#define COW_SHIFT 4
++
++struct cow {
++	int count;
++	char *cow_path;
++	dev_t cow_dev;
++	struct block_device *cow_bdev;
++	char *backing_path;
++	dev_t backing_dev;
++	struct block_device *backing_bdev;
++	int sectorsize;
++	unsigned long *bitmap;
++	unsigned long bitmap_len;
++	int bitmap_offset;
++	int data_offset;
++	devfs_handle_t devfs;
++	struct semaphore sem;
++	struct semaphore io_sem;
++	atomic_t working;
++	spinlock_t io_lock;
++	struct buffer_head *bh;
++	struct buffer_head *bhtail;
++	void *end_io;
++};
++
++#define DEFAULT_COW { \
++	.count			= 0, \
++	.cow_path		= NULL, \
++	.cow_dev		= 0, \
++	.backing_path		= NULL, \
++	.backing_dev		= 0, \
++        .bitmap			= NULL, \
++	.bitmap_len		= 0, \
++	.bitmap_offset		= 0, \
++        .data_offset		= 0, \
++	.devfs			= NULL, \
++	.working		= ATOMIC_INIT(0), \
++	.io_lock		= SPIN_LOCK_UNLOCKED, \
++}
++
++#define MAX_DEV (8)
++#define MAX_MINOR (MAX_DEV << COW_SHIFT)
++
++struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
++
++/* Not modified by this driver */
++static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
++static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
++
++/* Protected by cow_lock */
++static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
++
++static struct hd_struct	cow_part[MAX_MINOR] =
++	{ [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
++
++/* Protected by io_request_lock */
++static request_queue_t *cow_queue;
++
++static int cow_open(struct inode *inode, struct file *filp);
++static int cow_release(struct inode * inode, struct file * file);
++static int cow_ioctl(struct inode * inode, struct file * file,
++		     unsigned int cmd, unsigned long arg);
++static int cow_revalidate(kdev_t rdev);
++
++static struct block_device_operations cow_blops = {
++       .open		= cow_open,
++       .release	= cow_release,
++       .ioctl		= cow_ioctl,
++       .revalidate	= cow_revalidate,
++};
++
++/* Initialized in an initcall, and unchanged thereafter */
++devfs_handle_t cow_dir_handle;
++
++#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
++{ \
++	.major 		= maj, \
++	.major_name  	= name, \
++	.minor_shift 	= shift, \
++	.max_p  	= 1 << shift, \
++	.part  		= parts, \
++	.sizes  	= bsizes, \
++	.nr_real  	= max, \
++	.real_devices  	= NULL, \
++	.next  		= NULL, \
++	.fops  		= blops, \
++	.de_arr  	= NULL, \
++	.flags  	= 0 \
++}
++
++static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
++
++static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
++						 COW_SHIFT, sizes, MAX_DEV, 
++						 &cow_blops);
++
++static int cow_add(int n)
++{
++	struct cow *dev = &cow_dev[n];
++	char name[sizeof("nnnnnn\0")];
++	int err = -ENODEV;
++
++	if(dev->cow_path == NULL)
++		goto out;
++
++	sprintf(name, "%d", n);
++	dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
++				    MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
++				    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
++				    &cow_blops, NULL);
++
++	init_MUTEX_LOCKED(&dev->sem);
++	init_MUTEX(&dev->io_sem);
++
++	return(0);
++
++out:
++	return(err);
++}
++
++/*
++* Add buffer_head to back of pending list
++*/
++static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&cow->io_lock, flags);
++	if(cow->bhtail != NULL){
++		cow->bhtail->b_reqnext = bh;
++		cow->bhtail = bh;
++	}
++	else {
++		cow->bh = bh;
++		cow->bhtail = bh;
++	}
++	spin_unlock_irqrestore(&cow->io_lock, flags);
++}
++
++/*
++* Grab first pending buffer
++*/
++static struct buffer_head *cow_get_bh(struct cow *cow)
++{
++	struct buffer_head *bh;
++
++	spin_lock_irq(&cow->io_lock);
++	bh = cow->bh;
++	if(bh != NULL){
++		if(bh == cow->bhtail)
++			cow->bhtail = NULL;
++		cow->bh = bh->b_reqnext;
++		bh->b_reqnext = NULL;
++	}
++	spin_unlock_irq(&cow->io_lock);
++
++	return(bh);
++}
++
++static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
++			  struct buffer_head **cow_bh, int ncow_bh)
++{
++	int i;
++
++	if(ncow_bh > 0)
++		ll_rw_block(WRITE, ncow_bh, cow_bh);
++
++	for(i = 0; i < ncow_bh ; i++){
++		wait_on_buffer(cow_bh[i]);
++		brelse(cow_bh[i]);
++	}
++
++	ll_rw_block(WRITE, 1, &bh);
++	brelse(bh);
++}
++
++static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
++{
++	struct buffer_head *bh;
++
++	sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
++	bh = getblk(dev->cow_dev, sector, dev->sectorsize);
++	memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
++	       dev->sectorsize);
++	return(bh);
++}
++
++/* Copied from loop.c, needed to avoid deadlocking in make_request. */
++
++static int cow_thread(void *data)
++{
++	struct cow *dev = data;
++	struct buffer_head *bh;
++
++	daemonize();
++	exit_files(current);
++
++	sprintf(current->comm, "cow%d", dev - cow_dev);
++
++	spin_lock_irq(&current->sigmask_lock);
++	sigfillset(&current->blocked);
++	flush_signals(current);
++	spin_unlock_irq(&current->sigmask_lock);
++
++	atomic_inc(&dev->working);
++
++	current->policy = SCHED_OTHER;
++	current->nice = -20;
++
++	current->flags |= PF_NOIO;
++
++	/*
++	 * up sem, we are running
++	 */
++	up(&dev->sem);
++
++	for(;;){
++		int start, len, nbh, i, update_bitmap = 0;
++		struct buffer_head *cow_bh[2];
++
++		down_interruptible(&dev->io_sem);
++		/*
++		 * could be upped because of tear-down, not because of
++		 * pending work
++		 */
++		if(!atomic_read(&dev->working))
++			break;
++
++		bh = cow_get_bh(dev);
++		if(bh == NULL){
++			printk(KERN_ERR "cow: missing bh\n");
++			continue;
++		}
++
++		start = bh->b_blocknr * bh->b_size / dev->sectorsize;
++		len = bh->b_size / dev->sectorsize;
++		for(i = 0; i < len ; i++){
++			if(ubd_test_bit(start +ni, 
++					(unsigned char *) dev->bitmap))
++				continue;
++
++			update_bitmap = 1;
++			ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
++		}
++
++		cow_bh[0] = NULL;
++		cow_bh[1] = NULL;
++		nbh = 0;
++		if(update_bitmap){
++			cow_bh[0] = cow_new_bh(dev, start);
++			nbh++;
++			if(start / dev->sectorsize != 
++			   (start + len) / dev->sectorsize){
++				cow_bh[1] = cow_new_bh(dev, start + len);
++				nbh++;
++			}
++		}
++		
++		bh->b_dev = dev->cow_dev;
++		bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++		cow_handle_bh(dev, bh, cow_bh, nbh);
++
++		/*
++		 * upped both for pending work and tear-down, lo_pending
++		 * will hit zero then
++		 */
++		if(atomic_dec_and_test(&dev->working))
++			break;
++	}
++
++	up(&dev->sem);
++	return(0);
++}
++
++static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
++{
++	struct cow *dev;
++	int n, minor;
++
++	minor = MINOR(bh->b_rdev);
++	n = minor >> COW_SHIFT;
++	dev = &cow_dev[n];
++
++	dev->end_io = NULL;
++	if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
++		bh->b_rdev = dev->cow_dev;
++		bh->b_rsector += dev->data_offset / dev->sectorsize;
++	}
++	else if(rw == WRITE){
++		bh->b_dev = dev->cow_dev;
++		bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++		cow_add_bh(dev, bh);
++		up(&dev->io_sem);
++		return(0);
++	}
++	else {
++		bh->b_rdev = dev->backing_dev;
++	}
++
++	return(1);
++}
++
++int cow_init(void)
++{
++	int i;
++
++	cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
++	if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
++		printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
++		return -1;
++	}
++	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
++	blksize_size[MAJOR_NR] = blk_sizes;
++	blk_size[MAJOR_NR] = sizes;
++	INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
++
++	cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
++	blk_init_queue(cow_queue, NULL);
++	INIT_ELV(cow_queue, &cow_queue->elevator);
++	blk_queue_make_request(cow_queue, cow_make_request);
++
++       add_gendisk(&cow_gendisk);
++
++	for(i=0;i<MAX_DEV;i++) 
++		cow_add(i);
++
++	return(0);
++}
++
++__initcall(cow_init);
++
++static int reader(__u64 start, char *buf, int count, void *arg)
++{
++	dev_t dev = *((dev_t *) arg);
++	struct buffer_head *bh;
++	__u64 block;
++	int cur, offset, left, n, blocksize = get_hardsect_size(dev);
++
++	if(blocksize == 0)
++		panic("Zero blocksize");
++
++	block = start / blocksize;
++	offset = start % blocksize;
++	left = count;
++	cur = 0;
++	while(left > 0){
++		n = (left > blocksize) ? blocksize : left;
++
++		bh = bread(dev, block, (n < 512) ? 512 : n);
++		if(bh == NULL)
++			return(-EIO);
++
++		n -= offset;
++		memcpy(&buf[cur], bh->b_data + offset, n);
++		block++;
++		left -= n;
++		cur += n;
++		offset = 0;
++		brelse(bh);
++	}
++
++	return(count);
++}
++
++static int cow_open(struct inode *inode, struct file *filp)
++{
++	int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
++			 unsigned long);
++	mm_segment_t fs;
++	struct cow *dev;
++	__u64 size;
++	__u32 magic;
++	time_t mtime;
++	char *backing_file;
++	int n, offset, err = 0;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++	offset = n << COW_SHIFT;
++
++	spin_lock(&cow_lock);
++
++	if(dev->count == 0){
++		dev->cow_dev = name_to_kdev_t(dev->cow_path);
++		if(dev->cow_dev == 0){
++			printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++			       "failed\n", dev->cow_path);
++			err = -ENODEV;
++		}
++
++		dev->backing_dev = name_to_kdev_t(dev->backing_path);
++		if(dev->backing_dev == 0){
++			printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++			       "failed\n", dev->backing_path);
++			err = -ENODEV;
++		}
++
++		if(err) 
++			goto out;
++
++		dev->cow_bdev = bdget(dev->cow_dev);
++		if(dev->cow_bdev == NULL){
++			printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
++			       dev->cow_path);
++			err = -ENOMEM;
++		}
++		dev->backing_bdev = bdget(dev->backing_dev);
++		if(dev->backing_bdev == NULL){
++			printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
++			       dev->backing_path);
++			err = -ENOMEM;
++		}
++
++		if(err) 
++			goto out;
++
++		err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
++				 BDEV_RAW);
++		if(err){
++			printk("cow_open - blkdev_get of COW device failed, "
++			       "error = %d\n", err);
++			goto out;
++		}
++		
++		err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
++		if(err){
++			printk("cow_open - blkdev_get of backing device "
++			       "failed, error = %d\n", err);
++			goto out;
++		}
++		
++		err = read_cow_header(reader, &dev->cow_dev, &magic, 
++				      &backing_file, &mtime, &size,
++				      &dev->sectorsize, &dev->bitmap_offset);
++		if(err){
++			printk(KERN_ERR "cow_open - read_cow_header failed, "
++			       "err = %d\n", err);
++			goto out;
++		}
++
++		cow_sizes(size, dev->sectorsize, dev->bitmap_offset, 
++			  &dev->bitmap_len, &dev->data_offset);
++		dev->bitmap = (void *) vmalloc(dev->bitmap_len);
++		if(dev->bitmap == NULL){
++			err = -ENOMEM;
++			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++			goto out;
++		}
++		flush_tlb_kernel_vm();
++		
++		err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
++			     dev->bitmap_len, &dev->cow_dev);
++		if(err < 0){
++			printk(KERN_ERR "Failed to read COW bitmap\n");
++			vfree(dev->bitmap);
++			goto out;
++		}
++
++		dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++		fs = get_fs();
++		set_fs(KERNEL_DS);
++		err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
++				   (unsigned long) &sizes[offset]);
++		set_fs(fs);
++		if(err){
++			printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
++			       "error = %d\n", err);
++			goto out;
++		}
++
++		kernel_thread(cow_thread, dev, 
++			      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++		down(&dev->sem);
++	}
++	dev->count++;
++out:
++	spin_unlock(&cow_lock);
++	return(err);
++}
++
++static int cow_release(struct inode * inode, struct file * file)
++{
++	struct cow *dev;
++	int n, err;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++
++	spin_lock(&cow_lock);
++
++	if(--dev->count > 0)
++		goto out;
++
++	err = blkdev_put(dev->cow_bdev, BDEV_RAW);
++	if(err)
++		printk("cow_release - blkdev_put of cow device failed, "
++		       "error = %d\n", err);
++	bdput(dev->cow_bdev);
++	dev->cow_bdev = 0;
++
++	err = blkdev_put(dev->backing_bdev, BDEV_RAW);
++	if(err)
++		printk("cow_release - blkdev_put of backing device failed, "
++		       "error = %d\n", err);
++	bdput(dev->backing_bdev);
++	dev->backing_bdev = 0;
++
++out:
++	spin_unlock(&cow_lock);
++	return(0);
++}
++
++static int cow_ioctl(struct inode * inode, struct file * file,
++		     unsigned int cmd, unsigned long arg)
++{
++	struct cow *dev;
++	int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
++			 unsigned long);
++	int n;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++
++	dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++	return((*dev_ioctl)(inode, file, cmd, arg));
++}
++
++static int cow_revalidate(kdev_t rdev)
++{
++	printk(KERN_ERR "Need to implement cow_revalidate\n");
++	return(0);
++}
++
++static int parse_unit(char **ptr)
++{
++	char *str = *ptr, *end;
++	int n = -1;
++
++	if(isdigit(*str)) {
++		n = simple_strtoul(str, &end, 0);
++		if(end == str)
++			return(-1);
++		*ptr = end;
++	}
++	else if (('a' <= *str) && (*str <= 'h')) {
++		n = *str - 'a';
++		str++;
++		*ptr = str;
++	}
++	return(n);
++}
++
++static int cow_setup(char *str)
++{
++	struct cow *dev;
++	char *cow_name, *backing_name;
++	int unit;
++
++	unit = parse_unit(&str);
++	if(unit < 0){
++		printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
++		return(1);
++	}
++
++	if(*str != '='){
++		printk(KERN_ERR "cow_setup - Missing '=' after unit "
++		       "number\n");
++		return(1);
++	}
++	str++;
++
++	cow_name = str;
++	backing_name = strchr(str, ',');
++	if(backing_name == NULL){
++		printk(KERN_ERR "cow_setup - missing backing device name\n");
++		return(0);
++	}
++	*backing_name = '\0';
++	backing_name++;
++
++	spin_lock(&cow_lock);
++
++	dev = &cow_dev[unit];
++	dev->cow_path = cow_name;
++	dev->backing_path = backing_name;
++	
++	spin_unlock(&cow_lock);
++	return(0);
++}
++
++__setup("cow", cow_setup);
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/um/drivers/cow_sys.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,48 @@
++#ifndef __COW_SYS_H__
++#define __COW_SYS_H__
++
++#include "kern_util.h"
++#include "user_util.h"
++#include "os.h"
++#include "user.h"
++
++static inline void *cow_malloc(int size)
++{
++	return(um_kmalloc(size));
++}
++
++static inline void cow_free(void *ptr)
++{
++	kfree(ptr);
++}
++
++#define cow_printf printk
++
++static inline char *cow_strdup(char *str)
++{
++	return(uml_strdup(str));
++}
++
++static inline int cow_seek_file(int fd, __u64 offset)
++{
++	return(os_seek_file(fd, offset));
++}
++
++static inline int cow_file_size(char *file, __u64 *size_out)
++{
++	return(os_file_size(file, size_out));
++}
++
++static inline int cow_write_file(int fd, char *buf, int size)
++{
++	return(os_write_file(fd, buf, size));
++}
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/um/drivers/cow_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,296 @@
++#include <stddef.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <byteswap.h>
++#include <sys/stat.h>
++#include <sys/time.h>
++#include <sys/param.h>
++#include <netinet/in.h>
++
++#include "cow.h"
++#include "cow_sys.h"
++
++#define PATH_LEN_V1 256
++
++struct cow_header_v1 {
++	int magic;
++	int version;
++	char backing_file[PATH_LEN_V1];
++	time_t mtime;
++	__u64 size;
++	int sectorsize;
++};
++
++#define PATH_LEN_V2 MAXPATHLEN
++
++struct cow_header_v2 {
++	unsigned long magic;
++	unsigned long version;
++	char backing_file[PATH_LEN_V2];
++	time_t mtime;
++	__u64 size;
++	int sectorsize;
++};
++
++union cow_header {
++	struct cow_header_v1 v1;
++	struct cow_header_v2 v2;
++};
++
++#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
++#define COW_VERSION 2
++
++void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
++	       unsigned long *bitmap_len_out, int *data_offset_out)
++{
++	*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
++
++	*data_offset_out = bitmap_offset + *bitmap_len_out;
++	*data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
++	*data_offset_out *= sectorsize;
++}
++
++static int absolutize(char *to, int size, char *from)
++{
++	char save_cwd[256], *slash;
++	int remaining;
++
++	if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
++		cow_printf("absolutize : unable to get cwd - errno = %d\n", 
++			   errno);
++		return(-1);
++	}
++	slash = strrchr(from, '/');
++	if(slash != NULL){
++		*slash = '\0';
++		if(chdir(from)){
++			*slash = '/';
++			cow_printf("absolutize : Can't cd to '%s' - " 
++				   "errno = %d\n", from, errno);
++			return(-1);
++		}
++		*slash = '/';
++		if(getcwd(to, size) == NULL){
++			cow_printf("absolutize : unable to get cwd of '%s' - "
++			       "errno = %d\n", from, errno);
++			return(-1);
++		}
++		remaining = size - strlen(to);
++		if(strlen(slash) + 1 > remaining){
++			cow_printf("absolutize : unable to fit '%s' into %d "
++			       "chars\n", from, size);
++			return(-1);
++		}
++		strcat(to, slash);
++	}
++	else {
++		if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
++			cow_printf("absolutize : unable to fit '%s' into %d "
++			       "chars\n", from, size);
++			return(-1);
++		}
++		strcpy(to, save_cwd);
++		strcat(to, "/");
++		strcat(to, from);
++	}
++	chdir(save_cwd);
++	return(0);
++}
++
++int write_cow_header(char *cow_file, int fd, char *backing_file, 
++		     int sectorsize, long long *size)
++{
++	struct cow_header_v2 *header;
++	struct stat64 buf;
++	int err;
++
++	err = cow_seek_file(fd, 0);
++	if(err != 0){
++		cow_printf("write_cow_header - lseek failed, errno = %d\n", 
++			   errno);
++		return(-errno);
++	}
++
++	err = -ENOMEM;
++	header = cow_malloc(sizeof(*header));
++	if(header == NULL){
++		cow_printf("Failed to allocate COW V2 header\n");
++		goto out;
++	}
++	header->magic = htonl(COW_MAGIC);
++	header->version = htonl(COW_VERSION);
++
++	err = -EINVAL;
++	if(strlen(backing_file) > sizeof(header->backing_file) - 1){
++		cow_printf("Backing file name \"%s\" is too long - names are "
++			   "limited to %d characters\n", backing_file, 
++			   sizeof(header->backing_file) - 1);
++		goto out_free;
++	}
++
++	if(absolutize(header->backing_file, sizeof(header->backing_file), 
++		      backing_file))
++		goto out_free;
++
++	err = stat64(header->backing_file, &buf);
++	if(err < 0){
++		cow_printf("Stat of backing file '%s' failed, errno = %d\n",
++			   header->backing_file, errno);
++		err = -errno;
++		goto out_free;
++	}
++
++	err = cow_file_size(header->backing_file, size);
++	if(err){
++		cow_printf("Couldn't get size of backing file '%s', "
++			   "errno = %d\n", header->backing_file, -*size);
++		goto out_free;
++	}
++
++	header->mtime = htonl(buf.st_mtime);
++	header->size = htonll(*size);
++	header->sectorsize = htonl(sectorsize);
++
++	err = write(fd, header, sizeof(*header));
++	if(err != sizeof(*header)){
++		cow_printf("Write of header to new COW file '%s' failed, "
++			   "errno = %d\n", cow_file, errno);
++		goto out_free;
++	}
++	err = 0;
++ out_free:
++	cow_free(header);
++ out:
++	return(err);
++}
++
++int file_reader(__u64 offset, char *buf, int len, void *arg)
++{
++	int fd = *((int *) arg);
++
++	return(pread(fd, buf, len, offset));
++}
++
++int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
++		    __u32 *magic_out, char **backing_file_out, 
++		    time_t *mtime_out, __u64 *size_out, 
++		    int *sectorsize_out, int *bitmap_offset_out)
++{
++	union cow_header *header;
++	char *file;
++	int err, n;
++	unsigned long version, magic;
++
++	header = cow_malloc(sizeof(*header));
++	if(header == NULL){
++	        cow_printf("read_cow_header - Failed to allocate header\n");
++		return(-ENOMEM);
++	}
++	err = -EINVAL;
++	n = (*reader)(0, (char *) header, sizeof(*header), arg);
++	if(n < offsetof(typeof(header->v1), backing_file)){
++		cow_printf("read_cow_header - short header\n");
++		goto out;
++	}
++
++	magic = header->v1.magic;
++	if(magic == COW_MAGIC) {
++		version = header->v1.version;
++	}
++	else if(magic == ntohl(COW_MAGIC)){
++		version = ntohl(header->v1.version);
++	}
++	/* No error printed because the non-COW case comes through here */
++	else goto out;
++
++	*magic_out = COW_MAGIC;
++
++	if(version == 1){
++		if(n < sizeof(header->v1)){
++			cow_printf("read_cow_header - failed to read V1 "
++				   "header\n");
++			goto out;
++		}
++		*mtime_out = header->v1.mtime;
++		*size_out = header->v1.size;
++		*sectorsize_out = header->v1.sectorsize;
++		*bitmap_offset_out = sizeof(header->v1);
++		file = header->v1.backing_file;
++	}
++	else if(version == 2){
++		if(n < sizeof(header->v2)){
++			cow_printf("read_cow_header - failed to read V2 "
++				   "header\n");
++			goto out;
++		}
++		*mtime_out = ntohl(header->v2.mtime);
++		*size_out = ntohll(header->v2.size);
++		*sectorsize_out = ntohl(header->v2.sectorsize);
++		*bitmap_offset_out = sizeof(header->v2);
++		file = header->v2.backing_file;
++	}
++	else {
++		cow_printf("read_cow_header - invalid COW version\n");
++		goto out;
++	}
++	err = -ENOMEM;
++	*backing_file_out = cow_strdup(file);
++	if(*backing_file_out == NULL){
++		cow_printf("read_cow_header - failed to allocate backing "
++			   "file\n");
++		goto out;
++	}
++	err = 0;
++ out:
++	cow_free(header);
++	return(err);
++}
++
++int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
++		  int *bitmap_offset_out, unsigned long *bitmap_len_out, 
++		  int *data_offset_out)
++{
++	__u64 size, offset;
++	char zero = 0;
++	int err;
++
++	err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
++	if(err) 
++		goto out;
++	
++	cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
++		  bitmap_len_out, data_offset_out);
++	*bitmap_offset_out = sizeof(struct cow_header_v2);
++
++	offset = *data_offset_out + size - sizeof(zero);
++	err = cow_seek_file(fd, offset);
++	if(err != 0){
++		cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
++		goto out;
++	}
++
++	/* does not really matter how much we write it is just to set EOF 
++	 * this also sets the entire COW bitmap
++	 * to zero without having to allocate it 
++	 */
++	err = cow_write_file(fd, &zero, sizeof(zero));
++	if(err != sizeof(zero)){
++		err = -EINVAL;
++		cow_printf("Write of bitmap to new COW file '%s' failed, "
++			   "errno = %d\n", cow_file, errno);
++		goto out;
++	}
++
++	return(0);
++
++ out:
++	return(err);
++}
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+--- linux-2.6.0-test6/arch/um/drivers/hostaudio_kern.c	2003-06-14 12:18:35.000000000 -0700
++++ 25/arch/um/drivers/hostaudio_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -11,6 +11,7 @@
+ #include "linux/fs.h"
+ #include "linux/sound.h"
+ #include "linux/soundcard.h"
++#include "asm/uaccess.h"
+ #include "kern_util.h"
+ #include "init.h"
+ #include "hostaudio.h"
+@@ -22,7 +23,7 @@ char *mixer = HOSTAUDIO_DEV_MIXER;
+ #ifndef MODULE
+ static int set_dsp(char *name, int *add)
+ {
+-	dsp = uml_strdup(name);
++	dsp = name;
+ 	return(0);
+ }
+ 
+@@ -34,7 +35,7 @@ __uml_setup("dsp=", set_dsp,
+ 
+ static int set_mixer(char *name, int *add)
+ {
+-	mixer = uml_strdup(name);
++	mixer = name;
+ 	return(0);
+ }
+ 
+@@ -51,23 +52,55 @@ static ssize_t hostaudio_read(struct fil
+ 			      loff_t *ppos)
+ {
+         struct hostaudio_state *state = file->private_data;
++	void *kbuf;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: read called, count = %d\n", count);
+ #endif
+ 
+-        return(hostaudio_read_user(state, buffer, count, ppos));
++	kbuf = kmalloc(count, GFP_KERNEL);
++	if(kbuf == NULL)
++		return(-ENOMEM);
++
++        err = hostaudio_read_user(state, kbuf, count, ppos);
++	if(err < 0)
++		goto out;
++
++	if(copy_to_user(buffer, kbuf, err))
++		err = -EFAULT;
++
++ out:
++	kfree(kbuf);
++	return(err);
+ }
+ 
+ static ssize_t hostaudio_write(struct file *file, const char *buffer, 
+ 			       size_t count, loff_t *ppos)
+ {
+         struct hostaudio_state *state = file->private_data;
++	void *kbuf;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: write called, count = %d\n", count);
+ #endif
+-        return(hostaudio_write_user(state, buffer, count, ppos));
++
++	kbuf = kmalloc(count, GFP_KERNEL);
++	if(kbuf == NULL)
++		return(-ENOMEM);
++
++	err = -EFAULT;
++	if(copy_from_user(kbuf, buffer, count))
++		goto out;
++
++        err = hostaudio_write_user(state, kbuf, count, ppos);
++	if(err < 0)
++		goto out;
++
++ out:
++	kfree(kbuf);
++	return(err);
+ }
+ 
+ static unsigned int hostaudio_poll(struct file *file, 
+@@ -86,12 +119,43 @@ static int hostaudio_ioctl(struct inode 
+ 			   unsigned int cmd, unsigned long arg)
+ {
+         struct hostaudio_state *state = file->private_data;
++	unsigned long data = 0;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: ioctl called, cmd = %u\n", cmd);
+ #endif
++	switch(cmd){
++	case SNDCTL_DSP_SPEED:
++	case SNDCTL_DSP_STEREO:
++	case SNDCTL_DSP_GETBLKSIZE:
++	case SNDCTL_DSP_CHANNELS:
++	case SNDCTL_DSP_SUBDIVIDE:
++	case SNDCTL_DSP_SETFRAGMENT:
++		if(get_user(data, (int *) arg))
++			return(-EFAULT);
++		break;
++	default:
++		break;
++	}
++
++        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
++
++	switch(cmd){
++	case SNDCTL_DSP_SPEED:
++	case SNDCTL_DSP_STEREO:
++	case SNDCTL_DSP_GETBLKSIZE:
++	case SNDCTL_DSP_CHANNELS:
++	case SNDCTL_DSP_SUBDIVIDE:
++	case SNDCTL_DSP_SETFRAGMENT:
++		if(put_user(data, (int *) arg))
++			return(-EFAULT);
++		break;
++	default:
++		break;
++	}
+ 
+-        return(hostaudio_ioctl_user(state, cmd, arg));
++	return(err);
+ }
+ 
+ static int hostaudio_open(struct inode *inode, struct file *file)
+@@ -225,7 +289,8 @@ MODULE_LICENSE("GPL");
+ 
+ static int __init hostaudio_init_module(void)
+ {
+-        printk(KERN_INFO "UML Audio Relay\n");
++        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
++	       dsp, mixer);
+ 
+ 	module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
+         if(module_data.dev_audio < 0){
+--- linux-2.6.0-test6/arch/um/drivers/line.c	2003-06-14 12:18:33.000000000 -0700
++++ 25/arch/um/drivers/line.c	2003-10-05 00:34:32.000000000 -0700
+@@ -6,8 +6,8 @@
+ #include "linux/sched.h"
+ #include "linux/slab.h"
+ #include "linux/list.h"
++#include "linux/interrupt.h"
+ #include "linux/devfs_fs_kernel.h"
+-#include "asm/irq.h"
+ #include "asm/uaccess.h"
+ #include "chan_kern.h"
+ #include "irq_user.h"
+@@ -16,16 +16,18 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "os.h"
++#include "irq_kern.h"
+ 
+ #define LINE_BUFSIZE 4096
+ 
+-void line_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct line *dev = data;
+ 
+ 	if(dev->count > 0) 
+ 		chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
+ 			       dev);
++	return IRQ_HANDLED;
+ }
+ 
+ void line_timer_cb(void *arg)
+@@ -136,20 +138,22 @@ int line_write(struct line *lines, struc
+ 	return(len);
+ }
+ 
+-void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct line *dev = data;
+ 	struct tty_struct *tty = dev->tty;
+ 	int err;
+ 
+ 	err = flush_buffer(dev);
+-	if(err == 0) return;
++	if(err == 0) 
++		return(IRQ_NONE);
+ 	else if(err < 0){
+ 		dev->head = dev->buffer;
+ 		dev->tail = dev->buffer;
+ 	}
+ 
+-	if(tty == NULL) return;
++	if(tty == NULL) 
++		return(IRQ_NONE);
+ 
+ 	if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
+ 	   (tty->ldisc.write_wakeup != NULL))
+@@ -161,9 +165,9 @@ void line_write_interrupt(int irq, void 
+ 	 * writes.
+ 	 */
+ 
+-	if (waitqueue_active(&tty->write_wait))
++	if(waitqueue_active(&tty->write_wait))
+ 		wake_up_interruptible(&tty->write_wait);
+-
++	return(IRQ_HANDLED);
+ }
+ 
+ int line_write_room(struct tty_struct *tty)
+@@ -369,7 +373,7 @@ int line_get_config(char *name, struct l
+ 
+ 	dev = simple_strtoul(name, &end, 0);
+ 	if((*end != '\0') || (end == name)){
+-		*error_out = "line_setup failed to parse device number";
++		*error_out = "line_get_config failed to parse device number";
+ 		return(0);
+ 	}
+ 
+@@ -379,15 +383,15 @@ int line_get_config(char *name, struct l
+ 	}
+ 
+ 	line = &lines[dev];
++
+ 	down(&line->sem);
+-	
+ 	if(!line->valid)
+ 		CONFIG_CHUNK(str, size, n, "none", 1);
+ 	else if(line->count == 0)
+ 		CONFIG_CHUNK(str, size, n, line->init_str, 1);
+ 	else n = chan_config_string(&line->chan_list, str, size, error_out);
+-
+ 	up(&line->sem);
++
+ 	return(n);
+ }
+ 
+@@ -412,7 +416,8 @@ struct tty_driver *line_register_devfs(s
+ 		return NULL;
+ 
+ 	driver->driver_name = line_driver->name;
+-	driver->name = line_driver->devfs_name;
++	driver->name = line_driver->device_name;
++	driver->devfs_name = line_driver->devfs_name;
+ 	driver->major = line_driver->major;
+ 	driver->minor_start = line_driver->minor_start;
+ 	driver->type = line_driver->type;
+@@ -432,7 +437,7 @@ struct tty_driver *line_register_devfs(s
+ 
+ 	for(i = 0; i < nlines; i++){
+ 		if(!lines[i].valid) 
+-			tty_unregister_devfs(driver, i);
++			tty_unregister_device(driver, i);
+ 	}
+ 
+ 	mconsole_register_dev(&line_driver->mc);
+@@ -465,24 +470,25 @@ struct winch {
+ 	struct line *line;
+ };
+ 
+-void winch_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct winch *winch = data;
+ 	struct tty_struct *tty;
+ 	int err;
+ 	char c;
+ 
+-	err = generic_read(winch->fd, &c, NULL);
+-	if(err < 0){
+-		if(err != -EAGAIN){
+-			printk("winch_interrupt : read failed, errno = %d\n", 
+-			       -err);
+-			printk("fd %d is losing SIGWINCH support\n", 
+-			       winch->tty_fd);
+-			free_irq(irq, data);
+-			return;
++	if(winch->fd != -1){
++		err = generic_read(winch->fd, &c, NULL);
++		if(err < 0){
++			if(err != -EAGAIN){
++				printk("winch_interrupt : read failed, "
++				       "errno = %d\n", -err);
++				printk("fd %d is losing SIGWINCH support\n", 
++				       winch->tty_fd);
++				return(IRQ_HANDLED);
++			}
++			goto out;
+ 		}
+-		goto out;
+ 	}
+ 	tty = winch->line->tty;
+ 	if(tty != NULL){
+@@ -492,7 +498,9 @@ void winch_interrupt(int irq, void *data
+ 		kill_pg(tty->pgrp, SIGWINCH, 1);
+ 	}
+  out:
+-	reactivate_fd(winch->fd, WINCH_IRQ);
++	if(winch->fd != -1)
++		reactivate_fd(winch->fd, WINCH_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ DECLARE_MUTEX(winch_handler_sem);
+@@ -529,7 +537,10 @@ static void winch_cleanup(void)
+ 
+ 	list_for_each(ele, &winch_handlers){
+ 		winch = list_entry(ele, struct winch, list);
+-		close(winch->fd);
++		if(winch->fd != -1){
++			deactivate_fd(winch->fd, WINCH_IRQ);
++			close(winch->fd);
++		}
+ 		if(winch->pid != -1) 
+ 			os_kill_process(winch->pid, 1);
+ 	}
+--- linux-2.6.0-test6/arch/um/drivers/Makefile	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/um/drivers/Makefile	2003-10-05 00:34:32.000000000 -0700
+@@ -1,5 +1,5 @@
+ # 
+-# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
++# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
+ # Licensed under the GPL
+ #
+ 
+@@ -39,6 +39,8 @@ obj-$(CONFIG_PTY_CHAN) += pty.o
+ obj-$(CONFIG_TTY_CHAN) += tty.o 
+ obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
+ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
++obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
++obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
+ 
+ obj-y += stdio_console.o $(CHAN_OBJS)
+ 
+@@ -46,7 +48,7 @@ USER_SINGLE_OBJS = $(foreach f,$(patsubs
+ 
+ USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
+ 	null.o pty.o tty.o xterm.o
+-USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
++USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+ 
+ $(USER_OBJS) : %.o: %.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+--- linux-2.6.0-test6/arch/um/drivers/mconsole_kern.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/um/drivers/mconsole_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -27,6 +27,7 @@
+ #include "init.h"
+ #include "os.h"
+ #include "umid.h"
++#include "irq_kern.h"
+ 
+ static int do_unlink_socket(struct notifier_block *notifier, 
+ 			    unsigned long what, void *data)
+@@ -67,7 +68,7 @@ void mc_work_proc(void *unused)
+ 
+ DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
+ 
+-void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	int fd;
+ 	struct mconsole_entry *new;
+@@ -88,6 +89,7 @@ void mconsole_interrupt(int irq, void *d
+ 	}
+ 	if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
+ 	reactivate_fd(fd, MCONSOLE_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ void mconsole_version(struct mc_request *req)
+@@ -100,20 +102,34 @@ void mconsole_version(struct mc_request 
+ 	mconsole_reply(req, version, 0, 0);
+ }
+ 
++void mconsole_log(struct mc_request *req)
++{
++	int len;
++	char *ptr = req->request.data;
++	
++	ptr += strlen("log");
++	while(isspace(*ptr)) ptr++;
++
++	len = ptr - req->request.data;
++	printk("%.*s", len, ptr);
++	mconsole_reply(req, "", 0, 0);
++}
++
+ #define UML_MCONSOLE_HELPTEXT \
+-"Commands:
+-    version - Get kernel version
+-    help - Print this message
+-    halt - Halt UML
+-    reboot - Reboot UML
+-    config <dev>=<config> - Add a new device to UML; 
+-	same syntax as command line
+-    config <dev> - Query the configuration of a device
+-    remove <dev> - Remove a device from UML
+-    sysrq <letter> - Performs the SysRq action controlled by the letter
+-    cad - invoke the Ctl-Alt-Del handler
+-    stop - pause the UML; it will do nothing until it receives a 'go'
+-    go - continue the UML after a 'stop'
++"Commands: \n\
++    version - Get kernel version \n\
++    help - Print this message \n\
++    halt - Halt UML \n\
++    reboot - Reboot UML \n\
++    config <dev>=<config> - Add a new device to UML;  \n\
++	same syntax as command line \n\
++    config <dev> - Query the configuration of a device \n\
++    remove <dev> - Remove a device from UML \n\
++    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
++    cad - invoke the Ctl-Alt-Del handler \n\
++    stop - pause the UML; it will do nothing until it receives a 'go' \n\
++    go - continue the UML after a 'stop' \n\
++    log <string> - make UML enter <string> into the kernel log\n\
+ "
+ 
+ void mconsole_help(struct mc_request *req)
+@@ -302,7 +318,7 @@ int mconsole_init(void)
+ 	if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
+ 	snprintf(mconsole_socket_name, sizeof(file), "%s", file);
+ 
+-	sock = create_unix_socket(file, sizeof(file));
++	sock = create_unix_socket(file, sizeof(file), 1);
+ 	if (sock < 0){
+ 		printk("Failed to initialize management console\n");
+ 		return(1);
+--- linux-2.6.0-test6/arch/um/drivers/mconsole_user.c	2003-06-14 12:17:59.000000000 -0700
++++ 25/arch/um/drivers/mconsole_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -28,6 +28,7 @@ static struct mconsole_command commands[
+ 	{ "cad", mconsole_cad, 1 },
+ 	{ "stop", mconsole_stop, 0 },
+ 	{ "go", mconsole_go, 1 },
++	{ "log", mconsole_log, 1 },
+ };
+ 
+ /* Initialized in mconsole_init, which is an initcall */
+@@ -139,6 +140,7 @@ int mconsole_reply(struct mc_request *re
+ 		memcpy(reply.data, str, len);
+ 		reply.data[len] = '\0';
+ 		total -= len;
++ 		str += len;
+ 		reply.len = len + 1;
+ 
+ 		len = sizeof(reply) + reply.len - sizeof(reply.data);
+--- linux-2.6.0-test6/arch/um/drivers/mmapper_kern.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/um/drivers/mmapper_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -120,7 +120,10 @@ static int __init mmapper_init(void)
+ 	printk(KERN_INFO "Mapper v0.1\n");
+ 
+ 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
+-	if(mmapper_size == 0) return(0);
++	if(mmapper_size == 0){
++		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
++		return(0);
++	}
+ 
+ 	p_buf = __pa(v_buf);
+ 
+--- linux-2.6.0-test6/arch/um/drivers/net_kern.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/drivers/net_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -26,6 +26,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(opened);
+@@ -61,14 +62,14 @@ static int uml_net_rx(struct net_device 
+ 	return pkt_len;
+ }
+ 
+-void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct net_device *dev = dev_id;
+ 	struct uml_net_private *lp = dev->priv;
+ 	int err;
+ 
+ 	if(!netif_running(dev))
+-		return;
++		return(IRQ_NONE);
+ 
+ 	spin_lock(&lp->lock);
+ 	while((err = uml_net_rx(dev)) > 0) ;
+@@ -83,6 +84,7 @@ void uml_net_interrupt(int irq, void *de
+ 
+  out:
+ 	spin_unlock(&lp->lock);
++	return(IRQ_HANDLED);
+ }
+ 
+ static int uml_net_open(struct net_device *dev)
+@@ -252,37 +254,6 @@ void uml_net_user_timer_expire(unsigned 
+ #endif
+ }
+ 
+-/*
+- * default do nothing hard header packet routines for struct net_device init.
+- * real ethernet transports will overwrite with real routines.
+- */
+-static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
+-                 unsigned short type, void *daddr, void *saddr, unsigned len)
+-{
+-	return(0); /* no change */
+-}
+-
+-static int uml_net_rebuild_header(struct sk_buff *skb)
+-{
+-	return(0); /* ignore */ 
+-}
+-
+-static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+-{
+-	return(-1); /* fail */
+-}
+-
+-static void uml_net_header_cache_update(struct hh_cache *hh,
+-                 struct net_device *dev, unsigned char * haddr)
+-{
+-	/* ignore */
+-}
+-
+-static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
+-{
+-	return(0); /* nothing */
+-}
+-
+ static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
+ static struct list_head devices = LIST_HEAD_INIT(devices);
+ 
+@@ -292,7 +263,7 @@ static int eth_configure(int n, void *in
+ 	struct uml_net *device;
+ 	struct net_device *dev;
+ 	struct uml_net_private *lp;
+-	int err, size;
++	int save, err, size;
+ 
+ 	size = transport->private_size + sizeof(struct uml_net_private) + 
+ 		sizeof(((struct uml_net_private *) 0)->user);
+@@ -334,12 +305,6 @@ static int eth_configure(int n, void *in
+ 	snprintf(dev->name, sizeof(dev->name), "eth%d", n);
+ 	device->dev = dev;
+ 
+-        dev->hard_header = uml_net_hard_header;
+-        dev->rebuild_header = uml_net_rebuild_header;
+-        dev->hard_header_cache = uml_net_header_cache;
+-        dev->header_cache_update= uml_net_header_cache_update;
+-        dev->hard_header_parse = uml_net_header_parse;
+-
+ 	(*transport->kern->init)(dev, init);
+ 
+ 	dev->mtu = transport->user->max_packet;
+@@ -362,21 +327,29 @@ static int eth_configure(int n, void *in
+ 		return 1;
+ 	lp = dev->priv;
+ 
+-	INIT_LIST_HEAD(&lp->list);
+-	spin_lock_init(&lp->lock);
+-	lp->dev = dev;
+-	lp->fd = -1;
+-	lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
+-	lp->have_mac = device->have_mac;
+-	lp->protocol = transport->kern->protocol;
+-	lp->open = transport->user->open;
+-	lp->close = transport->user->close;
+-	lp->remove = transport->user->remove;
+-	lp->read = transport->kern->read;
+-	lp->write = transport->kern->write;
+-	lp->add_address = transport->user->add_address;
+-	lp->delete_address = transport->user->delete_address;
+-	lp->set_mtu = transport->user->set_mtu;
++	/* lp.user is the first four bytes of the transport data, which
++	 * has already been initialized.  This structure assignment will
++	 * overwrite that, so we make sure that .user gets overwritten with
++	 * what it already has.
++	 */
++	save = lp->user[0];
++	*lp = ((struct uml_net_private) 
++		{ .list  		= LIST_HEAD_INIT(lp->list),
++		  .lock 		= SPIN_LOCK_UNLOCKED,
++		  .dev 			= dev,
++		  .fd 			= -1,
++		  .mac 			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
++		  .have_mac 		= device->have_mac,
++		  .protocol 		= transport->kern->protocol,
++		  .open 		= transport->user->open,
++		  .close 		= transport->user->close,
++		  .remove 		= transport->user->remove,
++		  .read 		= transport->kern->read,
++		  .write 		= transport->kern->write,
++		  .add_address 		= transport->user->add_address,
++		  .delete_address  	= transport->user->delete_address,
++		  .set_mtu 		= transport->user->set_mtu,
++		  .user  		= { save } });
+ 
+ 	init_timer(&lp->tl);
+ 	lp->tl.function = uml_net_user_timer_expire;
+@@ -609,7 +582,8 @@ static int net_remove(char *str)
+ 	unregister_netdev(dev);
+ 
+ 	list_del(&device->list);
+-	free_netdev(device);
++	kfree(device);
++	free_netdev(dev);
+ 	return(0);
+ }
+ 
+--- linux-2.6.0-test6/arch/um/drivers/port_kern.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/um/drivers/port_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -6,6 +6,7 @@
+ #include "linux/list.h"
+ #include "linux/sched.h"
+ #include "linux/slab.h"
++#include "linux/interrupt.h"
+ #include "linux/irq.h"
+ #include "linux/spinlock.h"
+ #include "linux/errno.h"
+@@ -14,6 +15,7 @@
+ #include "kern_util.h"
+ #include "kern.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "port.h"
+ #include "init.h"
+ #include "os.h"
+@@ -44,7 +46,7 @@ struct connection {
+ 	struct port_list *port;
+ };
+ 
+-static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct connection *conn = data;
+ 	int fd;
+@@ -52,7 +54,7 @@ static void pipe_interrupt(int irq, void
+  	fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
+ 	if(fd < 0){
+ 		if(fd == -EAGAIN)
+-			return;
++			return(IRQ_NONE);
+ 
+ 		printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
+ 		       -fd);
+@@ -65,6 +67,7 @@ static void pipe_interrupt(int irq, void
+ 	list_add(&conn->list, &conn->port->connections);
+ 
+ 	up(&conn->port->sem);
++	return(IRQ_HANDLED);
+ }
+ 
+ static int port_accept(struct port_list *port)
+@@ -138,12 +141,13 @@ void port_work_proc(void *unused)
+ 
+ DECLARE_WORK(port_work, port_work_proc, NULL);
+ 
+-static void port_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct port_list *port = data;
+ 
+ 	port->has_connection = 1;
+ 	schedule_work(&port_work);
++	return(IRQ_HANDLED);
+ } 
+ 
+ void *port_data(int port_num)
+--- linux-2.6.0-test6/arch/um/drivers/ssl.c	2003-06-14 12:18:21.000000000 -0700
++++ 25/arch/um/drivers/ssl.c	2003-10-05 00:34:32.000000000 -0700
+@@ -53,8 +53,9 @@ static int ssl_remove(char *str);
+ 
+ static struct line_driver driver = {
+ 	.name 			= "UML serial line",
+-	.devfs_name 		= "tts/%d",
+-	.major 			= TTYAUX_MAJOR,
++	.device_name 		= "ttS",
++	.devfs_name 		= "tts/",
++	.major 			= TTY_MAJOR,
+ 	.minor_start 		= 64,
+ 	.type 		 	= TTY_DRIVER_TYPE_SERIAL,
+ 	.subtype 	 	= 0,
+--- linux-2.6.0-test6/arch/um/drivers/stdio_console.c	2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/um/drivers/stdio_console.c	2003-10-05 00:34:32.000000000 -0700
+@@ -83,7 +83,8 @@ static int con_remove(char *str);
+ 
+ static struct line_driver driver = {
+ 	.name 			= "UML console",
+-	.devfs_name 		= "vc/%d",
++	.device_name 		= "tty",
++	.devfs_name 		= "vc/",
+ 	.major 			= TTY_MAJOR,
+ 	.minor_start 		= 0,
+ 	.type 		 	= TTY_DRIVER_TYPE_CONSOLE,
+@@ -159,6 +160,15 @@ static int chars_in_buffer(struct tty_st
+ 
+ static int con_init_done = 0;
+ 
++static struct tty_operations console_ops = {
++	.open 	 		= con_open,
++	.close 	 		= con_close,
++	.write 	 		= con_write,
++	.chars_in_buffer 	= chars_in_buffer,
++	.set_termios 		= set_termios,
++	.write_room		= line_write_room,
++};
++
+ int stdio_init(void)
+ {
+ 	char *new_title;
+@@ -166,7 +176,8 @@ int stdio_init(void)
+ 	printk(KERN_INFO "Initializing stdio console driver\n");
+ 
+ 	console_driver = line_register_devfs(&console_lines, &driver,
+-				&console_ops, vts, sizeof(vts)/sizeof(vts[0]));
++					     &console_ops, vts,
++					     sizeof(vts)/sizeof(vts[0]));
+ 
+ 	lines_init(vts, sizeof(vts)/sizeof(vts[0]));
+ 
+@@ -188,15 +199,6 @@ static void console_write(struct console
+ 	if(con_init_done) up(&vts[console->index].sem);
+ }
+ 
+-static struct tty_operations console_ops = {
+-	.open 	 		= con_open,
+-	.close 	 		= con_close,
+-	.write 	 		= con_write,
+-	.chars_in_buffer 	= chars_in_buffer,
+-	.set_termios 		= set_termios,
+-	.write_room		= line_write_room,
+-};
+-
+ static struct tty_driver *console_device(struct console *c, int *index)
+ {
+ 	*index = c->index;
+@@ -212,12 +214,14 @@ static struct console stdiocons = INIT_C
+ 					       console_device, console_setup,
+ 					       CON_PRINTBUFFER);
+ 
+-static void __init stdio_console_init(void)
++static int __init stdio_console_init(void)
+ {
+ 	INIT_LIST_HEAD(&vts[0].chan_list);
+ 	list_add(&init_console_chan.list, &vts[0].chan_list);
+ 	register_console(&stdiocons);
++	return(0);
+ }
++
+ console_initcall(stdio_console_init);
+ 
+ static int console_chan_setup(char *str)
+--- linux-2.6.0-test6/arch/um/drivers/ubd_kern.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/um/drivers/ubd_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -8,6 +8,13 @@
+  * old style ubd by setting UBD_SHIFT to 0
+  * 2002-09-27...2002-10-18 massive tinkering for 2.5
+  * partitions have changed in 2.5
++ * 2003-01-29 more tinkering for 2.5.59-1
++ * This should now address the sysfs problems and has
++ * the symlink for devfs to allow for booting with
++ * the common /dev/ubd/discX/... names rather than
++ * only /dev/ubdN/discN this version also has lots of
++ * clean ups preparing for ubd-many.
++ * James McMechan
+  */
+ 
+ #define MAJOR_NR UBD_MAJOR
+@@ -40,6 +47,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "ubd_user.h"
+ #include "2_5compat.h"
+ #include "os.h"
+@@ -49,9 +57,9 @@ static spinlock_t ubd_lock = SPIN_LOCK_U
+ 
+ static void (*do_ubd)(void);
+ 
+-static int ubd_open(struct inode * inode, struct file * filp);
+-static int ubd_release(struct inode * inode, struct file * file);
+-static int ubd_ioctl(struct inode * inode, struct file * file,
++static int ubd_open(struct block_device *bdev, struct file * filp);
++static int ubd_release(struct gendisk *disk);
++static int ubd_ioctl(struct block_device *bdev, struct file * file,
+ 		     unsigned int cmd, unsigned long arg);
+ 
+ #define MAX_DEV (8)
+@@ -67,7 +75,7 @@ static struct block_device_operations ub
+ static request_queue_t *ubd_queue;
+ 
+ /* Protected by ubd_lock */
+-static int fake_major = 0;
++static int fake_major = MAJOR_NR;
+ 
+ static struct gendisk *ubd_gendisk[MAX_DEV];
+ static struct gendisk *fake_gendisk[MAX_DEV];
+@@ -96,12 +104,12 @@ struct cow {
+ 
+ struct ubd {
+ 	char *file;
+-	int is_dir;
+ 	int count;
+ 	int fd;
+ 	__u64 size;
+ 	struct openflags boot_openflags;
+ 	struct openflags openflags;
++	int no_cow;
+ 	struct cow cow;
+ };
+ 
+@@ -115,12 +123,12 @@ struct ubd {
+ 
+ #define DEFAULT_UBD { \
+ 	.file = 		NULL, \
+-	.is_dir =		0, \
+ 	.count =		0, \
+ 	.fd =			-1, \
+ 	.size =			-1, \
+ 	.boot_openflags =	OPEN_FLAGS, \
+ 	.openflags =		OPEN_FLAGS, \
++        .no_cow =               0, \
+         .cow =			DEFAULT_COW, \
+ }
+ 
+@@ -128,8 +136,10 @@ struct ubd ubd_dev[MAX_DEV] = { [ 0 ... 
+ 
+ static int ubd0_init(void)
+ {
+-	if(ubd_dev[0].file == NULL)
+-		ubd_dev[0].file = "root_fs";
++	struct ubd *dev = &ubd_dev[0];
++
++	if(dev->file == NULL)
++		dev->file = "root_fs";
+ 	return(0);
+ }
+ 
+@@ -196,19 +206,39 @@ __uml_help(fake_ide_setup,
+ "    Create ide0 entries that map onto ubd devices.\n\n"
+ );
+ 
++static int parse_unit(char **ptr)
++{
++	char *str = *ptr, *end;
++	int n = -1;
++
++	if(isdigit(*str)) {
++		n = simple_strtoul(str, &end, 0);
++		if(end == str)
++			return(-1);
++		*ptr = end;
++	}
++	else if (('a' <= *str) && (*str <= 'h')) {
++		n = *str - 'a';
++		str++;
++		*ptr = str;
++	}
++	return(n);
++}
++
+ static int ubd_setup_common(char *str, int *index_out)
+ {
++	struct ubd *dev;
+ 	struct openflags flags = global_openflags;
+ 	char *backing_file;
+ 	int n, err;
+ 
+ 	if(index_out) *index_out = -1;
+-	n = *str++;
++	n = *str;
+ 	if(n == '='){
+-		static int fake_major_allowed = 1;
+ 		char *end;
+ 		int major;
+ 
++		str++;
+ 		if(!strcmp(str, "sync")){
+ 			global_openflags.s = 1;
+ 			return(0);
+@@ -220,20 +250,14 @@ static int ubd_setup_common(char *str, i
+ 			return(1);
+ 		}
+ 
+-		if(!fake_major_allowed){
+-			printk(KERN_ERR "Can't assign a fake major twice\n");
+-			return(1);
+-		}
+-
+ 		err = 1;
+  		spin_lock(&ubd_lock);
+- 		if(!fake_major_allowed){
++ 		if(fake_major != MAJOR_NR){
+  			printk(KERN_ERR "Can't assign a fake major twice\n");
+  			goto out1;
+  		}
+  
+  		fake_major = major;
+-		fake_major_allowed = 0;
+ 
+ 		printk(KERN_INFO "Setting extra ubd major number to %d\n",
+ 		       major);
+@@ -243,25 +267,23 @@ static int ubd_setup_common(char *str, i
+ 		return(err);
+ 	}
+ 
+-	if(n < '0'){
+-		printk(KERN_ERR "ubd_setup : index out of range\n"); }
+-
+-	if((n >= '0') && (n <= '9')) n -= '0';
+-	else if((n >= 'a') && (n <= 'z')) n -= 'a';
+-	else {
+-		printk(KERN_ERR "ubd_setup : device syntax invalid\n");
++	n = parse_unit(&str);
++	if(n < 0){
++		printk(KERN_ERR "ubd_setup : couldn't parse unit number "
++		       "'%s'\n", str);
+ 		return(1);
+ 	}
+ 	if(n >= MAX_DEV){
+-		printk(KERN_ERR "ubd_setup : index out of range "
+-		       "(%d devices)\n", MAX_DEV);	
++		printk(KERN_ERR "ubd_setup : index %d out of range "
++		       "(%d devices)\n", n, MAX_DEV);
+ 		return(1);
+ 	}
+ 
+ 	err = 1;
+ 	spin_lock(&ubd_lock);
+ 
+-	if(ubd_dev[n].file != NULL){
++	dev = &ubd_dev[n];
++	if(dev->file != NULL){
+ 		printk(KERN_ERR "ubd_setup : device already configured\n");
+ 		goto out2;
+ 	}
+@@ -276,6 +298,11 @@ static int ubd_setup_common(char *str, i
+ 		flags.s = 1;
+ 		str++;
+ 	}
++	if (*str == 'd'){
++		dev->no_cow = 1;
++		str++;
++	}
++
+ 	if(*str++ != '='){
+ 		printk(KERN_ERR "ubd_setup : Expected '='\n");
+ 		goto out2;
+@@ -284,14 +311,17 @@ static int ubd_setup_common(char *str, i
+ 	err = 0;
+ 	backing_file = strchr(str, ',');
+ 	if(backing_file){
+-		*backing_file = '\0';
+-		backing_file++;
++		if(dev->no_cow)
++			printk(KERN_ERR "Can't specify both 'd' and a "
++			       "cow file\n");
++		else {
++			*backing_file = '\0';
++			backing_file++;
++		}
+ 	}
+-	ubd_dev[n].file = str;
+-	if(ubd_is_dir(ubd_dev[n].file))
+-		ubd_dev[n].is_dir = 1;
+-	ubd_dev[n].cow.file = backing_file;
+-	ubd_dev[n].boot_openflags = flags;
++	dev->file = str;
++	dev->cow.file = backing_file;
++	dev->boot_openflags = flags;
+  out2:
+ 	spin_unlock(&ubd_lock);
+ 	return(err);
+@@ -321,8 +351,7 @@ __uml_help(ubd_setup,
+ static int fakehd_set = 0;
+ static int fakehd(char *str)
+ {
+-	printk(KERN_INFO 
+-	       "fakehd : Changing ubd name to \"hd\".\n");
++	printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
+ 	fakehd_set = 1;
+ 	return 1;
+ }
+@@ -391,9 +420,10 @@ static void ubd_handler(void)
+ 	do_ubd_request(ubd_queue);
+ }
+ 
+-static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
++static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
+ {
+ 	ubd_handler();
++	return(IRQ_HANDLED);
+ }
+ 
+ /* Only changed by ubd_init, which is an initcall. */
+@@ -429,16 +459,18 @@ static void ubd_close(struct ubd *dev)
+ static int ubd_open_dev(struct ubd *dev)
+ {
+ 	struct openflags flags;
+-	int err, n, create_cow, *create_ptr;
++	char **back_ptr;
++	int err, create_cow, *create_ptr;
+ 
++	dev->openflags = dev->boot_openflags;
+ 	create_cow = 0;
+ 	create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
+-	dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
++	back_ptr = dev->no_cow ? NULL : &dev->cow.file;
++	dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
+ 				&dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
+ 				&dev->cow.data_offset, create_ptr);
+ 
+ 	if((dev->fd == -ENOENT) && create_cow){
+-		n = dev - ubd_dev;
+ 		dev->fd = create_cow_file(dev->file, dev->cow.file, 
+ 					  dev->openflags, 1 << 9,
+ 					  &dev->cow.bitmap_offset, 
+@@ -455,7 +487,10 @@ static int ubd_open_dev(struct ubd *dev)
+ 	if(dev->cow.file != NULL){
+ 		err = -ENOMEM;
+ 		dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
+-		if(dev->cow.bitmap == NULL) goto error;
++		if(dev->cow.bitmap == NULL){
++			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++			goto error;
++		}
+ 		flush_tlb_kernel_vm();
+ 
+ 		err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
+@@ -481,17 +516,31 @@ static int ubd_new_disk(int major, u64 s
+ 			
+ {
+ 	struct gendisk *disk;
++	char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
++	int err;
+ 
+ 	disk = alloc_disk(1 << UBD_SHIFT);
+-	if (!disk)
+-		return -ENOMEM;
++	if(disk == NULL)
++		return(-ENOMEM);
+ 
+ 	disk->major = major;
+ 	disk->first_minor = unit << UBD_SHIFT;
+ 	disk->fops = &ubd_blops;
+ 	set_capacity(disk, size / 512);
+-	sprintf(disk->disk_name, "ubd");
+-	sprintf(disk->devfs_name, "ubd/disc%d", unit);
++	if(major == MAJOR_NR){
++		sprintf(disk->disk_name, "ubd%d", unit);
++		sprintf(disk->devfs_name, "ubd/disc%d", unit);
++		sprintf(from, "ubd/%d", unit);
++		sprintf(to, "disc%d/disc", unit);
++		err = devfs_mk_symlink(from, to);
++		if(err)
++			printk("ubd_new_disk failed to make link from %s to "
++			       "%s, error = %d\n", from, to, err);
++	}
++	else {
++		sprintf(disk->disk_name, "ubd_fake%d", unit);
++		sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
++	}
+ 
+ 	disk->private_data = &ubd_dev[unit];
+ 	disk->queue = ubd_queue;
+@@ -506,10 +555,7 @@ static int ubd_add(int n)
+ 	struct ubd *dev = &ubd_dev[n];
+ 	int err;
+ 
+-	if(dev->is_dir)
+-		return(-EISDIR);
+-
+-	if (!dev->file)
++	if(dev->file == NULL)
+ 		return(-ENODEV);
+ 
+ 	if (ubd_open_dev(dev))
+@@ -523,7 +569,7 @@ static int ubd_add(int n)
+ 	if(err) 
+ 		return(err);
+  
+-	if(fake_major)
++	if(fake_major != MAJOR_NR)
+ 		ubd_new_disk(fake_major, dev->size, n, 
+ 			     &fake_gendisk[n]);
+ 
+@@ -561,42 +607,42 @@ static int ubd_config(char *str)
+ 	return(err);
+ }
+ 
+-static int ubd_get_config(char *dev, char *str, int size, char **error_out)
++static int ubd_get_config(char *name, char *str, int size, char **error_out)
+ {
+-	struct ubd *ubd;
++	struct ubd *dev;
+ 	char *end;
+-	int major, n = 0;
++	int n, len = 0;
+ 
+-	major = simple_strtoul(dev, &end, 0);
+-	if((*end != '\0') || (end == dev)){
+-		*error_out = "ubd_get_config : didn't parse major number";
++	n = simple_strtoul(name, &end, 0);
++	if((*end != '\0') || (end == name)){
++		*error_out = "ubd_get_config : didn't parse device number";
+ 		return(-1);
+ 	}
+ 
+-	if((major >= MAX_DEV) || (major < 0)){
+-		*error_out = "ubd_get_config : major number out of range";
++	if((n >= MAX_DEV) || (n < 0)){
++		*error_out = "ubd_get_config : device number out of range";
+ 		return(-1);
+ 	}
+ 
+-	ubd = &ubd_dev[major];
++	dev = &ubd_dev[n];
+ 	spin_lock(&ubd_lock);
+ 
+-	if(ubd->file == NULL){
+-		CONFIG_CHUNK(str, size, n, "", 1);
++	if(dev->file == NULL){
++		CONFIG_CHUNK(str, size, len, "", 1);
+ 		goto out;
+ 	}
+ 
+-	CONFIG_CHUNK(str, size, n, ubd->file, 0);
++	CONFIG_CHUNK(str, size, len, dev->file, 0);
+ 
+-	if(ubd->cow.file != NULL){
+-		CONFIG_CHUNK(str, size, n, ",", 0);
+-		CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
++	if(dev->cow.file != NULL){
++		CONFIG_CHUNK(str, size, len, ",", 0);
++		CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+ 	}
+-	else CONFIG_CHUNK(str, size, n, "", 1);
++	else CONFIG_CHUNK(str, size, len, "", 1);
+ 
+  out:
+ 	spin_unlock(&ubd_lock);
+-	return(n);
++	return(len);
+ }
+ 
+ static int ubd_remove(char *str)
+@@ -604,11 +650,9 @@ static int ubd_remove(char *str)
+ 	struct ubd *dev;
+ 	int n, err = -ENODEV;
+ 
+-	if(!isdigit(*str))
+-		return(err);	/* it should be a number 0-7/a-h */
++	n = parse_unit(&str);
+ 
+-	n = *str - '0';
+-	if(n >= MAX_DEV) 
++	if((n < 0) || (n >= MAX_DEV))
+ 		return(err);
+ 
+ 	dev = &ubd_dev[n];
+@@ -669,7 +713,7 @@ int ubd_init(void)
+ 		
+ 	elevator_init(ubd_queue, &elevator_noop);
+ 
+-	if (fake_major != 0) {
++	if (fake_major != MAJOR_NR) {
+ 		char name[sizeof("ubd_nnn\0")];
+ 
+ 		snprintf(name, sizeof(name), "ubd_%d", fake_major);
+@@ -710,19 +754,13 @@ int ubd_driver_init(void){
+ 
+ device_initcall(ubd_driver_init);
+ 
+-static int ubd_open(struct inode *inode, struct file *filp)
++static int ubd_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct ubd *dev = disk->private_data;
+-	int err = -EISDIR;
+-
+-	if(dev->is_dir == 1)
+-		goto out;
++	int err = 0;
+ 
+-	err = 0;
+ 	if(dev->count == 0){
+-		dev->openflags = dev->boot_openflags;
+-
+ 		err = ubd_open_dev(dev);
+ 		if(err){
+ 			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
+@@ -739,9 +777,8 @@ static int ubd_open(struct inode *inode,
+ 	return(err);
+ }
+ 
+-static int ubd_release(struct inode * inode, struct file * file)
++static int ubd_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct ubd *dev = disk->private_data;
+ 
+ 	if(--dev->count == 0)
+@@ -796,15 +833,6 @@ static int prepare_request(struct reques
+ 
+ 	if(req->rq_status == RQ_INACTIVE) return(1);
+ 
+-	if(dev->is_dir){
+-		strcpy(req->buffer, "HOSTFS:");
+-		strcat(req->buffer, dev->file);
+- 		spin_lock(&ubd_io_lock);
+-		end_request(req, 1);
+- 		spin_unlock(&ubd_io_lock);
+-		return(1);
+-	}
+-
+ 	if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+ 		printk("Write attempted on readonly ubd device %s\n", 
+ 		       disk->disk_name);
+@@ -865,11 +893,11 @@ static void do_ubd_request(request_queue
+ 	}
+ }
+ 
+-static int ubd_ioctl(struct inode * inode, struct file * file,
++static int ubd_ioctl(struct block_device *bdev, struct file * file,
+ 		     unsigned int cmd, unsigned long arg)
+ {
+ 	struct hd_geometry *loc = (struct hd_geometry *) arg;
+-	struct ubd *dev = inode->i_bdev->bd_disk->private_data;
++	struct ubd *dev = bdev->bd_disk->private_data;
+ 	int err;
+ 	struct hd_driveid ubd_id = {
+ 		.cyls		= 0,
+@@ -890,7 +918,7 @@ static int ubd_ioctl(struct inode * inod
+ 
+ 	case HDIO_SET_UNMASKINTR:
+ 		if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
+-		if((arg > 1) || (inode->i_bdev->bd_contains != inode->i_bdev))
++		if((arg > 1) || (bdev->bd_contains != bdev))
+ 			return(-EINVAL);
+ 		return(0);
+ 
+@@ -910,7 +938,7 @@ static int ubd_ioctl(struct inode * inod
+ 
+ 	case HDIO_SET_MULTCOUNT:
+ 		if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
+-		if(inode->i_bdev->bd_contains != inode->i_bdev)
++		if(bdev->bd_contains != bdev)
+ 			return(-EINVAL);
+ 		return(0);
+ 
+--- linux-2.6.0-test6/arch/um/drivers/ubd_user.c	2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/um/drivers/ubd_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -24,142 +24,24 @@
+ #include "user.h"
+ #include "ubd_user.h"
+ #include "os.h"
++#include "cow.h"
+ 
+ #include <endian.h>
+ #include <byteswap.h>
+-#if __BYTE_ORDER == __BIG_ENDIAN
+-# define ntohll(x) (x)
+-# define htonll(x) (x)
+-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+-# define ntohll(x)  bswap_64(x)
+-# define htonll(x)  bswap_64(x)
+-#else
+-#error "__BYTE_ORDER not defined"
+-#endif
+-
+-#define PATH_LEN_V1 256
+-
+-struct cow_header_v1 {
+-	int magic;
+-	int version;
+-	char backing_file[PATH_LEN_V1];
+-	time_t mtime;
+-	__u64 size;
+-	int sectorsize;
+-};
+-
+-#define PATH_LEN_V2 MAXPATHLEN
+-
+-struct cow_header_v2 {
+-	unsigned long magic;
+-	unsigned long version;
+-	char backing_file[PATH_LEN_V2];
+-	time_t mtime;
+-	__u64 size;
+-	int sectorsize;
+-};
+-
+-union cow_header {
+-	struct cow_header_v1 v1;
+-	struct cow_header_v2 v2;
+-};
+-
+-#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
+-#define COW_VERSION 2
+-
+-static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
+-		  unsigned long *bitmap_len_out, int *data_offset_out)
+-{
+-	*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
+-
+-	*data_offset_out = bitmap_offset + *bitmap_len_out;
+-	*data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
+-	*data_offset_out *= sectorsize;
+-}
+-
+-static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
+-			   time_t *mtime_out, __u64 *size_out, 
+-			   int *sectorsize_out, int *bitmap_offset_out)
+-{
+-	union cow_header *header;
+-	char *file;
+-	int err, n;
+-	unsigned long version, magic;
+-
+-	header = um_kmalloc(sizeof(*header));
+-	if(header == NULL){
+-		printk("read_cow_header - Failed to allocate header\n");
+-		return(-ENOMEM);
+-	}
+-	err = -EINVAL;
+-	n = read(fd, header, sizeof(*header));
+-	if(n < offsetof(typeof(header->v1), backing_file)){
+-		printk("read_cow_header - short header\n");
+-		goto out;
+-	}
+-
+-	magic = header->v1.magic;
+-	if(magic == COW_MAGIC) {
+-		version = header->v1.version;
+-	}
+-	else if(magic == ntohl(COW_MAGIC)){
+-		version = ntohl(header->v1.version);
+-	}
+-	else goto out;
+-
+-	*magic_out = COW_MAGIC;
+-
+-	if(version == 1){
+-		if(n < sizeof(header->v1)){
+-			printk("read_cow_header - failed to read V1 header\n");
+-			goto out;
+-		}
+-		*mtime_out = header->v1.mtime;
+-		*size_out = header->v1.size;
+-		*sectorsize_out = header->v1.sectorsize;
+-		*bitmap_offset_out = sizeof(header->v1);
+-		file = header->v1.backing_file;
+-	}
+-	else if(version == 2){
+-		if(n < sizeof(header->v2)){
+-			printk("read_cow_header - failed to read V2 header\n");
+-			goto out;
+-		}
+-		*mtime_out = ntohl(header->v2.mtime);
+-		*size_out = ntohll(header->v2.size);
+-		*sectorsize_out = ntohl(header->v2.sectorsize);
+-		*bitmap_offset_out = sizeof(header->v2);
+-		file = header->v2.backing_file;
+-	}
+-	else {
+-		printk("read_cow_header - invalid COW version\n");
+-		goto out;
+-	}
+-	err = -ENOMEM;
+-	*backing_file_out = uml_strdup(file);
+-	if(*backing_file_out == NULL){
+-		printk("read_cow_header - failed to allocate backing file\n");
+-		goto out;
+-	}
+-	err = 0;
+- out:
+-	kfree(header);
+-	return(err);
+-}
+ 
+ static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+ {
+-	struct stat buf1, buf2;
++	struct stat64 buf1, buf2;
+ 
+ 	if(from_cmdline == NULL) return(1);
+ 	if(!strcmp(from_cmdline, from_cow)) return(1);
+ 
+-	if(stat(from_cmdline, &buf1) < 0){
++	if(stat64(from_cmdline, &buf1) < 0){
+ 		printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
+ 		       errno);
+ 		return(1);
+ 	}
+-	if(stat(from_cow, &buf2) < 0){
++	if(stat64(from_cow, &buf2) < 0){
+ 		printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
+ 		return(1);
+ 	}
+@@ -215,118 +97,6 @@ int read_cow_bitmap(int fd, void *buf, i
+ 	return(0);
+ }
+ 
+-static int absolutize(char *to, int size, char *from)
+-{
+-	char save_cwd[256], *slash;
+-	int remaining;
+-
+-	if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+-		printk("absolutize : unable to get cwd - errno = %d\n", errno);
+-		return(-1);
+-	}
+-	slash = strrchr(from, '/');
+-	if(slash != NULL){
+-		*slash = '\0';
+-		if(chdir(from)){
+-			*slash = '/';
+-			printk("absolutize : Can't cd to '%s' - errno = %d\n",
+-			       from, errno);
+-			return(-1);
+-		}
+-		*slash = '/';
+-		if(getcwd(to, size) == NULL){
+-			printk("absolutize : unable to get cwd of '%s' - "
+-			       "errno = %d\n", from, errno);
+-			return(-1);
+-		}
+-		remaining = size - strlen(to);
+-		if(strlen(slash) + 1 > remaining){
+-			printk("absolutize : unable to fit '%s' into %d "
+-			       "chars\n", from, size);
+-			return(-1);
+-		}
+-		strcat(to, slash);
+-	}
+-	else {
+-		if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+-			printk("absolutize : unable to fit '%s' into %d "
+-			       "chars\n", from, size);
+-			return(-1);
+-		}
+-		strcpy(to, save_cwd);
+-		strcat(to, "/");
+-		strcat(to, from);
+-	}
+-	chdir(save_cwd);
+-	return(0);
+-}
+-
+-static int write_cow_header(char *cow_file, int fd, char *backing_file, 
+-			    int sectorsize, long long *size)
+-{
+-        struct cow_header_v2 *header;
+-	struct stat64 buf;
+-	int err;
+-
+-	err = os_seek_file(fd, 0);
+-	if(err != 0){
+-		printk("write_cow_header - lseek failed, errno = %d\n", errno);
+-		return(-errno);
+-	}
+-
+-	err = -ENOMEM;
+-	header = um_kmalloc(sizeof(*header));
+-	if(header == NULL){
+-		printk("Failed to allocate COW V2 header\n");
+-		goto out;
+-	}
+-	header->magic = htonl(COW_MAGIC);
+-	header->version = htonl(COW_VERSION);
+-
+-	err = -EINVAL;
+-	if(strlen(backing_file) > sizeof(header->backing_file) - 1){
+-		printk("Backing file name \"%s\" is too long - names are "
+-		       "limited to %d characters\n", backing_file, 
+-		       sizeof(header->backing_file) - 1);
+-		goto out_free;
+-	}
+-
+-	if(absolutize(header->backing_file, sizeof(header->backing_file), 
+-		      backing_file))
+-		goto out_free;
+-
+-	err = stat64(header->backing_file, &buf);
+-	if(err < 0){
+-		printk("Stat of backing file '%s' failed, errno = %d\n",
+-		       header->backing_file, errno);
+-		err = -errno;
+-		goto out_free;
+-	}
+-
+-	err = os_file_size(header->backing_file, size);
+-	if(err){
+-		printk("Couldn't get size of backing file '%s', errno = %d\n",
+-		       header->backing_file, -*size);
+-		goto out_free;
+-	}
+-
+-	header->mtime = htonl(buf.st_mtime);
+-	header->size = htonll(*size);
+-	header->sectorsize = htonl(sectorsize);
+-
+-	err = write(fd, header, sizeof(*header));
+-	if(err != sizeof(*header)){
+-		printk("Write of header to new COW file '%s' failed, "
+-		       "errno = %d\n", cow_file, errno);
+-		goto out_free;
+-	}
+-	err = 0;
+- out_free:
+-	kfree(header);
+- out:
+-	return(err);
+-}
+-
+ int open_ubd_file(char *file, struct openflags *openflags, 
+ 		  char **backing_file_out, int *bitmap_offset_out, 
+ 		  unsigned long *bitmap_len_out, int *data_offset_out, 
+@@ -346,10 +116,17 @@ int open_ubd_file(char *file, struct ope
+                 if((fd = os_open_file(file, *openflags, mode)) < 0) 
+ 			return(fd);
+         }
++
++	err = os_lock_file(fd, openflags->w);
++	if(err){
++		printk("Failed to lock '%s', errno = %d\n", file, -err);
++		goto error;
++	}
++	
+ 	if(backing_file_out == NULL) return(fd);
+ 
+-	err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
+-			      &sectorsize, bitmap_offset_out);
++	err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime, 
++			      &size, &sectorsize, bitmap_offset_out);
+ 	if(err && (*backing_file_out != NULL)){
+ 		printk("Failed to read COW header from COW file \"%s\", "
+ 		       "errno = %d\n", file, err);
+@@ -376,12 +153,12 @@ int open_ubd_file(char *file, struct ope
+ 		if(err) goto error;
+ 	}
+ 
+-	sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
+-	      data_offset_out);
++	cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
++		  data_offset_out);
+ 
+         return(fd);
+  error:
+-	close(fd);
++	os_close_file(fd);
+ 	return(err);
+ }
+ 
+@@ -389,10 +166,7 @@ int create_cow_file(char *cow_file, char
+ 		    int sectorsize, int *bitmap_offset_out, 
+ 		    unsigned long *bitmap_len_out, int *data_offset_out)
+ {
+-	__u64 blocks;
+-	long zero;
+-	int err, fd, i;
+-	long long size;
++	int err, fd;
+ 
+ 	flags.c = 1;
+ 	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+@@ -403,29 +177,12 @@ int create_cow_file(char *cow_file, char
+ 		goto out;
+ 	}
+ 
+-	err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
+-	if(err) goto out_close;
+-
+-	blocks = (size + sectorsize - 1) / sectorsize;
+-	blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
+-	zero = 0;
+-	for(i = 0; i < blocks; i++){
+-		err = write(fd, &zero, sizeof(zero));
+-		if(err != sizeof(zero)){
+-			printk("Write of bitmap to new COW file '%s' failed, "
+-			       "errno = %d\n", cow_file, errno);
+-			goto out_close;
+-		}
+-	}
+-
+-	sizes(size, sectorsize, sizeof(struct cow_header_v2), 
+-	      bitmap_len_out, data_offset_out);
+-	*bitmap_offset_out = sizeof(struct cow_header_v2);
+-
+-	return(fd);
+-
+- out_close:
+-	close(fd);
++	err = init_cow_file(fd, cow_file, backing_file, sectorsize, 
++			    bitmap_offset_out, bitmap_len_out, 
++			    data_offset_out);
++	if(!err)
++		return(fd);
++	os_close_file(fd);
+  out:
+ 	return(err);
+ }
+@@ -448,14 +205,6 @@ int write_ubd_fs(int fd, char *buffer, i
+ 	else return(n);
+ }
+ 
+-int ubd_is_dir(char *file)
+-{
+-	struct stat64 buf;
+-
+-	if(stat64(file, &buf) < 0) return(0);
+-	return(S_ISDIR(buf.st_mode));
+-}
+-
+ void do_io(struct io_thread_req *req)
+ {
+ 	char *buf;
+--- linux-2.6.0-test6/arch/um/drivers/xterm.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/um/drivers/xterm.c	2003-10-05 00:34:32.000000000 -0700
+@@ -108,7 +108,7 @@ int xterm_open(int input, int output, in
+ 	}
+ 	close(fd);
+ 
+-	fd = create_unix_socket(file, sizeof(file));
++	fd = create_unix_socket(file, sizeof(file), 1);
+ 	if(fd < 0){
+ 		printk("xterm_open : create_unix_socket failed, errno = %d\n", 
+ 		       -fd);
+--- linux-2.6.0-test6/arch/um/drivers/xterm_kern.c	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/um/drivers/xterm_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -5,9 +5,12 @@
+ 
+ #include "linux/errno.h"
+ #include "linux/slab.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "asm/irq.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "kern_util.h"
+ #include "os.h"
+ #include "xterm.h"
+@@ -19,17 +22,18 @@ struct xterm_wait {
+ 	int new_fd;
+ };
+ 
+-static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct xterm_wait *xterm = data;
+ 	int fd;
+ 
+ 	fd = os_rcv_fd(xterm->fd, &xterm->pid);
+ 	if(fd == -EAGAIN)
+-		return;
++		return(IRQ_NONE);
+ 
+ 	xterm->new_fd = fd;
+ 	up(&xterm->sem);
++	return(IRQ_HANDLED);
+ }
+ 
+ int xterm_fd(int socket, int *pid_out)
+--- linux-2.6.0-test6/arch/um/dyn.lds.S	2003-06-14 12:18:21.000000000 -0700
++++ 25/arch/um/dyn.lds.S	2003-10-05 00:34:32.000000000 -0700
+@@ -15,7 +15,11 @@ SECTIONS
+   . = ALIGN(4096);		/* Init code and data */
+   _stext = .;
+   __init_begin = .;
+-  .text.init : { *(.text.init) }
++  .init.text : { 
++	_sinittext = .;
++	*(.init.text)
++	_einittext = .;
++  }
+ 
+   . = ALIGN(4096);
+ 
+@@ -67,7 +71,7 @@ SECTIONS
+ 
+   #include "asm/common.lds.S"
+ 
+-  .data.init : { *(.data.init) }
++  init.data : { *(.init.data) }
+ 
+   /* Ensure the __preinit_array_start label is properly aligned.  We
+      could instead move the label definition inside the section, but
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/um/include/irq_kern.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,28 @@
++/* 
++ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#ifndef __IRQ_KERN_H__
++#define __IRQ_KERN_H__
++
++#include "linux/interrupt.h"
++
++extern int um_request_irq(unsigned int irq, int fd, int type,
++			  irqreturn_t (*handler)(int, void *, 
++						 struct pt_regs *),
++			  unsigned long irqflags,  const char * devname,
++			  void *dev_id);
++
++#endif
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+--- linux-2.6.0-test6/arch/um/include/kern_util.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/um/include/kern_util.h	2003-10-05 00:34:32.000000000 -0700
+@@ -63,10 +63,9 @@ extern void init_flush_vm(void);
+ extern void *syscall_sp(void *t);
+ extern void syscall_trace(void);
+ extern int hz(void);
+-extern void idle_timer(void);
++extern void uml_idle_timer(void);
+ extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
+ extern int external_pid(void *t);
+-extern int pid_to_processor_id(int pid);
+ extern void boot_timer_handler(int sig);
+ extern void interrupt_end(void);
+ extern void initial_thread_cb(void (*proc)(void *), void *arg);
+@@ -90,9 +89,7 @@ extern int remove_gdb(void);
+ extern char *uml_strdup(char *string);
+ extern void unprotect_kernel_mem(void);
+ extern void protect_kernel_mem(void);
+-extern void set_kmem_end(unsigned long);
+ extern void uml_cleanup(void);
+-extern int pid_to_processor_id(int pid);
+ extern void set_current(void *t);
+ extern void lock_signalled_task(void *t);
+ extern void IPI_handler(int cpu);
+@@ -101,7 +98,9 @@ extern void *get_init_task(void);
+ extern int clear_user_proc(void *buf, int size);
+ extern int copy_to_user_proc(void *to, void *from, int size);
+ extern int copy_from_user_proc(void *to, void *from, int size);
++extern int strlen_user_proc(char *str);
+ extern void bus_handler(int sig, union uml_pt_regs *regs);
++extern void winch(int sig, union uml_pt_regs *regs);
+ extern long execute_syscall(void *r);
+ extern int smp_sigio_handler(void);
+ extern void *get_current(void);
+--- linux-2.6.0-test6/arch/um/include/line.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/um/include/line.h	2003-10-05 00:34:32.000000000 -0700
+@@ -9,12 +9,14 @@
+ #include "linux/list.h"
+ #include "linux/workqueue.h"
+ #include "linux/tty.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "chan_user.h"
+ #include "mconsole_kern.h"
+ 
+ struct line_driver {
+ 	char *name;
++	char *device_name;
+ 	char *devfs_name;
+ 	short major;
+ 	short minor_start;
+@@ -67,8 +69,9 @@ struct lines {
+ 
+ #define LINES_INIT(n) {  num :		n }
+ 
+-extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
+-extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_write_interrupt(int irq, void *data, 
++					struct pt_regs *unused);
+ extern void line_close(struct line *lines, struct tty_struct *tty);
+ extern int line_open(struct line *lines, struct tty_struct *tty, 
+ 		     struct chan_opts *opts);
+--- linux-2.6.0-test6/arch/um/include/mconsole.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/um/include/mconsole.h	2003-10-05 00:34:32.000000000 -0700
+@@ -77,6 +77,7 @@ extern void mconsole_sysrq(struct mc_req
+ extern void mconsole_cad(struct mc_request *req);
+ extern void mconsole_stop(struct mc_request *req);
+ extern void mconsole_go(struct mc_request *req);
++extern void mconsole_log(struct mc_request *req);
+ 
+ extern int mconsole_get_request(int fd, struct mc_request *req);
+ extern int mconsole_notify(char *sock_name, int type, const void *data, 
+--- linux-2.6.0-test6/arch/um/include/mem.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/um/include/mem.h	2003-10-05 00:34:32.000000000 -0700
+@@ -13,7 +13,6 @@ struct vm_reserved {
+ };
+ 
+ extern void set_usable_vm(unsigned long start, unsigned long end);
+-extern void set_kmem_end(unsigned long new);
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/arch/um/include/mem_user.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/um/include/mem_user.h	2003-10-05 00:34:32.000000000 -0700
+@@ -51,9 +51,6 @@ extern unsigned long task_size;
+ 
+ extern int init_mem_user(void);
+ extern int create_mem_file(unsigned long len);
+-extern void setup_range(int fd, char *driver, unsigned long start,
+-			unsigned long pfn, unsigned long total, int need_vm, 
+-			struct mem_region *region, void *reserved);
+ extern void setup_memory(void *entry);
+ extern unsigned long find_iomem(char *driver, unsigned long *len_out);
+ extern int init_maps(struct mem_region *region);
+--- linux-2.6.0-test6/arch/um/include/os.h	2003-06-14 12:18:02.000000000 -0700
++++ 25/arch/um/include/os.h	2003-10-05 00:34:32.000000000 -0700
+@@ -103,10 +103,11 @@ extern int os_accept_connection(int fd);
+ extern int os_shutdown_socket(int fd, int r, int w);
+ extern void os_close_file(int fd);
+ extern int os_rcv_fd(int fd, int *helper_pid_out);
+-extern int create_unix_socket(char *file, int len);
++extern int create_unix_socket(char *file, int len, int close_on_exec);
+ extern int os_connect_socket(char *name);
+ extern int os_file_type(char *file);
+ extern int os_file_mode(char *file, struct openflags *mode_out);
++extern int os_lock_file(int fd, int excl);
+ 
+ extern unsigned long os_process_pc(int pid);
+ extern int os_process_parent(int pid);
+@@ -120,6 +121,7 @@ extern int os_map_memory(void *virt, int
+ extern int os_protect_memory(void *addr, unsigned long len, 
+ 			     int r, int w, int x);
+ extern int os_unmap_memory(void *addr, int len);
++extern void os_flush_stdout(void);
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/arch/um/include/sysdep-i386/sigcontext.h	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/um/include/sysdep-i386/sigcontext.h	2003-10-05 00:34:32.000000000 -0700
+@@ -28,8 +28,8 @@
+  */
+ #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
+ 
+-/* These are General Protection and Page Fault */
+-#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
++/* This is Page Fault */
++#define SEGV_IS_FIXABLE(trap) (trap == 14)
+ 
+ #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
+ 
+--- linux-2.6.0-test6/arch/um/include/ubd_user.h	2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/um/include/ubd_user.h	2003-10-05 00:34:32.000000000 -0700
+@@ -39,7 +39,6 @@ extern int read_ubd_fs(int fd, void *buf
+ extern int write_ubd_fs(int fd, char *buffer, int len);
+ extern int start_io_thread(unsigned long sp, int *fds_out);
+ extern void do_io(struct io_thread_req *req);
+-extern int ubd_is_dir(char *file);
+ 
+ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
+ {
+--- linux-2.6.0-test6/arch/um/include/user.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/um/include/user.h	2003-10-05 00:34:32.000000000 -0700
+@@ -14,7 +14,7 @@ extern void *um_kmalloc_atomic(int size)
+ extern void kfree(void *ptr);
+ extern int in_aton(char *str);
+ extern int open_gdb_chan(void);
+-
++extern int strlcpy(char *, const char *, int);
+ #endif
+ 
+ /*
+--- linux-2.6.0-test6/arch/um/include/user_util.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/um/include/user_util.h	2003-10-05 00:34:32.000000000 -0700
+@@ -59,7 +59,6 @@ extern int wait_for_stop(int pid, int si
+ extern void *add_signal_handler(int sig, void (*handler)(int));
+ extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
+ 			    int clone_flags, int (*tramp)(void *));
+-extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
+ extern int linux_main(int argc, char **argv);
+ extern void set_cmdline(char *cmd);
+ extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
+@@ -90,7 +89,8 @@ extern int arch_handle_signal(int sig, u
+ extern int arch_fixup(unsigned long address, void *sc_ptr);
+ extern void forward_pending_sigio(int target);
+ extern int can_do_skas(void);
+- 
++extern void arch_init_thread(void);
++
+ #endif
+ 
+ /*
+--- linux-2.6.0-test6/arch/um/Kconfig	2003-08-08 22:55:11.000000000 -0700
++++ 25/arch/um/Kconfig	2003-10-05 00:34:32.000000000 -0700
+@@ -61,6 +61,20 @@ config MODE_SKAS
+ 
+ config NET
+ 	bool "Networking support"
++	help
++	Unless you really know what you are doing, you should say Y here.
++	The reason is that some programs need kernel networking support even
++	when running on a stand-alone machine that isn't connected to any
++	other computer. If you are upgrading from an older kernel, you
++	should consider updating your networking tools too because changes
++	in the kernel and the tools often go hand in hand. The tools are
++	contained in the package net-tools, the location and version number
++	of which are given in Documentation/Changes.
++
++	For a general introduction to Linux networking, it is highly
++	recommended to read the NET-HOWTO, available from
++	<http://www.tldp.org/docs.html#howto>.
++
+ 
+ source "fs/Kconfig.binfmt"
+ 
+@@ -105,6 +119,16 @@ config MCONSOLE
+ config MAGIC_SYSRQ
+ 	bool "Magic SysRq key"
+ 	depends on MCONSOLE
++	help
++	If you say Y here, you will have some control over the system even
++	if the system crashes for example during kernel debugging (e.g., you
++	will be able to flush the buffer cache to disk, reboot the system
++	immediately or dump some status information). This is accomplished
++	by pressing various keys while holding SysRq (Alt+PrintScreen). It
++	also works on a serial console (on PC hardware at least), if you
++	send a BREAK and then within 5 seconds a command keypress. The
++	keys are documented in Documentation/sysrq.txt. Don't say Y
++	unless you really know what this hack does.
+ 
+ config HOST_2G_2G
+ 	bool "2G/2G host address space split"
+@@ -239,6 +263,10 @@ config FRAME_POINTER
+ config PT_PROXY
+ 	bool "Enable ptrace proxy"
+ 	depends on XTERM_CHAN && DEBUG_INFO
++	help
++	This option enables a debugging interface which allows gdb to debug
++	the kernel without needing to actually attach to kernel threads.
++	If you want to do kernel debugging, say Y here; otherwise say N.
+ 
+ config GPROF
+ 	bool "Enable gprof support"
+--- linux-2.6.0-test6/arch/um/Kconfig_block	2003-06-14 12:18:25.000000000 -0700
++++ 25/arch/um/Kconfig_block	2003-10-05 00:34:32.000000000 -0700
+@@ -29,6 +29,20 @@ config BLK_DEV_UBD_SYNC
+         wise choice too.  In all other cases (for example, if you're just
+         playing around with User-Mode Linux) you can choose N.
+ 
++# Turn this back on when the driver actually works
++#
++#config BLK_DEV_COW
++#	tristate "COW block device"
++#	help
++#	This is a layered driver which sits above two other block devices.
++#	One is read-only, and the other is a read-write layer which stores
++#	all changes.  This provides the illusion that the read-only layer
++#	can be mounted read-write and changed.
++
++config BLK_DEV_COW_COMMON
++	bool
++	default BLK_DEV_COW || BLK_DEV_UBD
++
+ config BLK_DEV_LOOP
+ 	tristate "Loopback device support"
+ 
+--- linux-2.6.0-test6/arch/um/Kconfig_net	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/um/Kconfig_net	2003-10-05 00:34:32.000000000 -0700
+@@ -1,5 +1,5 @@
+ 
+-menu "Network Devices"
++menu "UML Network Devices"
+ 	depends on NET
+ 
+ # UML virtual driver
+@@ -176,73 +176,5 @@ config UML_NET_SLIRP
+ 	
+         Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
+ 
+-
+-# Below are hardware-independent drivers mirrored from
+-# drivers/net/Config.in. It would be nice if Linux
+-# had HW independent drivers separated from the other
+-# but it does not. Until then each non-ISA/PCI arch
+-# needs to provide it's own menu of network drivers
+-config DUMMY
+-	tristate "Dummy net driver support"
+-
+-config BONDING
+-	tristate "Bonding driver support"
+-
+-config EQUALIZER
+-	tristate "EQL (serial line load balancing) support"
+-
+-config TUN
+-	tristate "Universal TUN/TAP device driver support"
+-
+-config ETHERTAP
+-	tristate "Ethertap network tap (OBSOLETE)"
+-	depends on EXPERIMENTAL && NETLINK
+-
+-config PPP
+-	tristate "PPP (point-to-point protocol) support"
+-
+-config PPP_MULTILINK
+-	bool "PPP multilink support (EXPERIMENTAL)"
+-	depends on PPP && EXPERIMENTAL
+-
+-config PPP_FILTER
+-	bool "PPP filtering"
+-	depends on PPP && FILTER
+-
+-config PPP_ASYNC
+-	tristate "PPP support for async serial ports"
+-	depends on PPP
+-
+-config PPP_SYNC_TTY
+-	tristate "PPP support for sync tty ports"
+-	depends on PPP
+-
+-config PPP_DEFLATE
+-	tristate "PPP Deflate compression"
+-	depends on PPP
+-
+-config PPP_BSDCOMP
+-	tristate "PPP BSD-Compress compression"
+-	depends on PPP
+-
+-config PPPOE
+-	tristate "PPP over Ethernet (EXPERIMENTAL)"
+-	depends on PPP && EXPERIMENTAL
+-
+-config SLIP
+-	tristate "SLIP (serial line) support"
+-
+-config SLIP_COMPRESSED
+-	bool "CSLIP compressed headers"
+-	depends on SLIP=y
+-
+-config SLIP_SMART
+-	bool "Keepalive and linefill"
+-	depends on SLIP=y
+-
+-config SLIP_MODE_SLIP6
+-	bool "Six bit SLIP encapsulation"
+-	depends on SLIP=y
+-
+ endmenu
+ 
+--- linux-2.6.0-test6/arch/um/kernel/config.c.in	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/um/kernel/config.c.in	2003-10-05 00:34:32.000000000 -0700
+@@ -7,9 +7,7 @@
+ #include <stdlib.h>
+ #include "init.h"
+ 
+-static __initdata char *config = "
+-CONFIG
+-";
++static __initdata char *config = "CONFIG";
+ 
+ static int __init print_config(char *line, int *add)
+ {
+--- linux-2.6.0-test6/arch/um/kernel/init_task.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/um/kernel/init_task.c	2003-10-05 00:34:32.000000000 -0700
+@@ -17,6 +17,7 @@ static struct fs_struct init_fs = INIT_F
+ struct mm_struct init_mm = INIT_MM(init_mm);
+ static struct files_struct init_files = INIT_FILES;
+ static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+ 
+ /*
+  * Initial task structure.
+@@ -38,26 +39,12 @@ union thread_union init_thread_union 
+ __attribute__((__section__(".data.init_task"))) = 
+ { INIT_THREAD_INFO(init_task) };
+ 
+-struct task_struct *alloc_task_struct(void)
+-{
+-	return((struct task_struct *) 
+-	       __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
+-}
+-
+ void unprotect_stack(unsigned long stack)
+ {
+ 	protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
+ 		       1, 1, 0, 1);
+ }
+ 
+-void free_task_struct(struct task_struct *task)
+-{
+-	/* free_pages decrements the page counter and only actually frees
+-	 * the pages if they are now not accessed by anything.
+-	 */
+-	free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
+-}
+-
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+--- linux-2.6.0-test6/arch/um/kernel/irq.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/irq.c	2003-10-05 00:34:32.000000000 -0700
+@@ -28,6 +28,7 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ static void register_irq_proc (unsigned int irq);
+ 
+@@ -82,65 +83,52 @@ struct hw_interrupt_type no_irq_type = {
+ 	end_none
+ };
+ 
+-/* Not changed */
+-volatile unsigned long irq_err_count;
+-
+ /*
+  * Generic, controller-independent functions:
+  */
+ 
+-int get_irq_list(char *buf)
++int show_interrupts(struct seq_file *p, void *v)
+ {
+ 	int i, j;
+-	unsigned long flags;
+ 	struct irqaction * action;
+-	char *p = buf;
++	unsigned long flags;
+ 
+-	p += sprintf(p, "           ");
+-	for (j=0; j<num_online_cpus(); j++)
+-		p += sprintf(p, "CPU%d       ",j);
+-	*p++ = '\n';
++	seq_printf(p, "           ");
++	for (j=0; j<NR_CPUS; j++)
++		if (cpu_online(j))
++			seq_printf(p, "CPU%d       ",j);
++	seq_putc(p, '\n');
+ 
+ 	for (i = 0 ; i < NR_IRQS ; i++) {
+ 		spin_lock_irqsave(&irq_desc[i].lock, flags);
+ 		action = irq_desc[i].action;
+ 		if (!action) 
+-			goto end;
+-		p += sprintf(p, "%3d: ",i);
++			goto skip;
++		seq_printf(p, "%3d: ",i);
+ #ifndef CONFIG_SMP
+-		p += sprintf(p, "%10u ", kstat_irqs(i));
++		seq_printf(p, "%10u ", kstat_irqs(i));
+ #else
+-		for (j = 0; j < num_online_cpus(); j++)
+-			p += sprintf(p, "%10u ",
+-				kstat_cpu(cpu_logical_map(j)).irqs[i]);
++		for (j = 0; j < NR_CPUS; j++)
++			if (cpu_online(j))
++				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ #endif
+-		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+-		p += sprintf(p, "  %s", action->name);
++		seq_printf(p, " %14s", irq_desc[i].handler->typename);
++		seq_printf(p, "  %s", action->name);
+ 
+ 		for (action=action->next; action; action = action->next)
+-			p += sprintf(p, ", %s", action->name);
+-		*p++ = '\n';
+-	end:
++			seq_printf(p, ", %s", action->name);
++
++		seq_putc(p, '\n');
++skip:
+ 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ 	}
+-	p += sprintf(p, "\n");
+-#ifdef notdef
+-#ifdef CONFIG_SMP
+-	p += sprintf(p, "LOC: ");
+-	for (j = 0; j < num_online_cpus(); j++)
+-		p += sprintf(p, "%10u ",
+-			apic_timer_irqs[cpu_logical_map(j)]);
+-	p += sprintf(p, "\n");
+-#endif
+-#endif
+-	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+-	return p - buf;
+-}
+-
++	seq_printf(p, "NMI: ");
++	for (j = 0; j < NR_CPUS; j++)
++		if (cpu_online(j))
++			seq_printf(p, "%10u ", nmi_count(j));
++	seq_putc(p, '\n');
+ 
+-int show_interrupts(struct seq_file *p, void *v)
+-{
+-	return(0);
++	return 0;
+ }
+ 
+ /*
+@@ -281,13 +269,12 @@ unsigned int do_IRQ(int irq, union uml_p
+ 	 * 0 return value means that this irq is already being
+ 	 * handled by some other CPU. (or is disabled)
+ 	 */
+-	int cpu = smp_processor_id();
+ 	irq_desc_t *desc = irq_desc + irq;
+ 	struct irqaction * action;
+ 	unsigned int status;
+ 
+ 	irq_enter();
+-	kstat_cpu(cpu).irqs[irq]++;
++	kstat_this_cpu.irqs[irq]++;
+ 	spin_lock(&desc->lock);
+ 	desc->handler->ack(irq);
+ 	/*
+@@ -384,7 +371,7 @@ out:
+  */
+  
+ int request_irq(unsigned int irq,
+-		void (*handler)(int, void *, struct pt_regs *),
++		irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ 		unsigned long irqflags, 
+ 		const char * devname,
+ 		void *dev_id)
+@@ -430,15 +417,19 @@ int request_irq(unsigned int irq,
+ }
+ 
+ int um_request_irq(unsigned int irq, int fd, int type,
+-		   void (*handler)(int, void *, struct pt_regs *),
++		   irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ 		   unsigned long irqflags, const char * devname,
+ 		   void *dev_id)
+ {
+-	int retval;
++	int err;
+ 
+-	retval = request_irq(irq, handler, irqflags, devname, dev_id);
+-	if(retval) return(retval);
+-	return(activate_fd(irq, fd, type, dev_id));
++	err = request_irq(irq, handler, irqflags, devname, dev_id);
++	if(err) 
++		return(err);
++
++	if(fd != -1)
++		err = activate_fd(irq, fd, type, dev_id);
++	return(err);
+ }
+ 
+ /* this was setup_x86_irq but it seems pretty generic */
+@@ -654,7 +645,7 @@ static int prof_cpu_mask_read_proc (char
+ 		return -EINVAL;
+ 	tmp = *mask;
+ 	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
++		int j = sprintf(page, "%04hx", (short) cpus_coerce(tmp));
+ 		len += j;
+ 		page += j;
+ 		cpus_shift_right(tmp, tmp, 16);
+--- linux-2.6.0-test6/arch/um/kernel/Makefile	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/Makefile	2003-10-05 00:34:32.000000000 -0700
+@@ -21,6 +21,8 @@ obj-$(CONFIG_TTY_LOG)	+= tty_log.o
+ obj-$(CONFIG_MODE_TT) += tt/
+ obj-$(CONFIG_MODE_SKAS) += skas/
+ 
++clean-files	:= config.c
++
+ user-objs-$(CONFIG_TTY_LOG) += tty_log.o
+ 
+ USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
+@@ -45,17 +47,13 @@ $(USER_OBJS) : %.o: %.c
+ $(obj)/frame.o: $(src)/frame.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
+ 
+-QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
++QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
+ 
+ $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
+ 	$(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
+ 
+ $(obj)/config.o : $(obj)/config.c
+ 
+-clean:
+-	rm -f config.c
+-	for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
+-
+ modules:
+ 
+ fastdep:
+--- linux-2.6.0-test6/arch/um/kernel/mem.c	2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/um/kernel/mem.c	2003-10-05 00:34:32.000000000 -0700
+@@ -119,11 +119,6 @@ unsigned long get_kmem_end(void)
+ 	return(kmem_top);
+ }
+ 
+-void set_kmem_end(unsigned long new)
+-{
+-	kmem_top = new;
+-}
+-
+ #ifdef CONFIG_HIGHMEM
+ /* Changed during early boot */
+ pte_t *kmap_pte;
+@@ -218,7 +213,7 @@ static int setup_one_range(int fd, char 
+ 		if(regions[i] == NULL) break;		
+ 	}
+ 	if(i == NREGIONS){
+-		printk("setup_range : no free regions\n");
++		printk("setup_one_range : no free regions\n");
+ 		i = -1;
+ 		goto out;
+ 	}
+@@ -227,7 +222,9 @@ static int setup_one_range(int fd, char 
+ 		fd = create_mem_file(len);
+ 
+ 	if(region == NULL){
+-		region = alloc_bootmem_low_pages(sizeof(*region));
++		if(kmalloc_ok)
++			region = kmalloc(sizeof(*region), GFP_KERNEL);
++		else region = alloc_bootmem_low_pages(sizeof(*region));
+ 		if(region == NULL)
+ 			panic("Failed to allocating mem_region");
+ 	}
+@@ -528,9 +525,9 @@ int nregions(void)
+ 	return(NREGIONS);
+ }
+ 
+-void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
+-		 unsigned long len, int need_vm, struct mem_region *region, 
+-		 void *reserved)
++static void setup_range(int fd, char *driver, unsigned long start, 
++			unsigned long pfn, unsigned long len, int need_vm, 
++			struct mem_region *region, void *reserved)
+ {
+ 	int i, cur;
+ 
+--- linux-2.6.0-test6/arch/um/kernel/mem_user.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/um/kernel/mem_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -111,6 +111,11 @@ int setup_region(struct mem_region *regi
+ 		offset = 0;
+ 	}
+ 
++	if(offset >= region->len){
++		printf("%ld bytes of physical memory is insufficient\n",
++		       region->len);
++		exit(1);
++	}
+ 	loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
+ 		   MAP_SHARED | MAP_FIXED, region->fd, offset);
+ 	if(loc != start){
+@@ -122,26 +127,26 @@ int setup_region(struct mem_region *regi
+ 
+ static int __init parse_iomem(char *str, int *add)
+ {
+-	struct stat buf;
++	struct stat64 buf;
+ 	char *file, *driver;
+ 	int fd;
+ 
+ 	driver = str;
+ 	file = strchr(str,',');
+ 	if(file == NULL){
+-		printk("parse_iomem : failed to parse iomem\n");
++		printf("parse_iomem : failed to parse iomem\n");
+ 		return(1);
+ 	}
+ 	*file = '\0';
+ 	file++;
+ 	fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
+ 	if(fd < 0){
+-		printk("parse_iomem - Couldn't open io file, errno = %d\n", 
++		printf("parse_iomem - Couldn't open io file, errno = %d\n", 
+ 		       errno);
+ 		return(1);
+ 	}
+-	if(fstat(fd, &buf) < 0) {
+-		printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
++	if(fstat64(fd, &buf) < 0) {
++		printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
+ 		return(1);
+ 	}
+ 	add_iomem(driver, fd, buf.st_size);
+--- linux-2.6.0-test6/arch/um/kernel/process.c	2003-06-14 12:18:32.000000000 -0700
++++ 25/arch/um/kernel/process.c	2003-10-05 00:34:32.000000000 -0700
+@@ -72,7 +72,6 @@ void init_new_thread_signals(int altstac
+ 		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ 	set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
+ 		    SA_NOMASK | flags, -1);
+-	(void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
+ 	signal(SIGHUP, SIG_IGN);
+ 
+ 	init_irq_signals(altstack);
+@@ -127,7 +126,8 @@ int start_fork_tramp(void *thread_arg, u
+ 	if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
+ 			  errno);
+ 	if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
+-		panic("outer trampoline didn't exit with SIGKILL");
++		panic("outer trampoline didn't exit with SIGKILL, "
++		      "status = %d", status);
+ 
+ 	return(arg.pid);
+ }
+--- linux-2.6.0-test6/arch/um/kernel/process_kern.c	2003-07-10 18:50:30.000000000 -0700
++++ 25/arch/um/kernel/process_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -52,17 +52,12 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [
+ 
+ struct task_struct *get_task(int pid, int require)
+ {
+-        struct task_struct *task, *ret;
++        struct task_struct *ret;
+ 
+-        ret = NULL;
+         read_lock(&tasklist_lock);
+-        for_each_process(task){
+-                if(task->pid == pid){
+-                        ret = task;
+-                        break;
+-                }
+-        }
++	ret = find_task_by_pid(pid);
+         read_unlock(&tasklist_lock);
++
+         if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
+         return(ret);
+ }
+@@ -103,13 +98,14 @@ unsigned long alloc_stack(int order, int
+ 
+ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ {
+-	struct task_struct *p;
++	int pid;
+ 
+ 	current->thread.request.u.thread.proc = fn;
+ 	current->thread.request.u.thread.arg = arg;
+-	p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
+-	if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
+-	return(p->pid);
++	pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
++	if(pid < 0)
++		panic("do_fork failed in kernel_thread, errno = %d", pid);
++	return(pid);
+ }
+ 
+ void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
+@@ -129,7 +125,7 @@ void set_current(void *t)
+ 		{ external_pid(task), task });
+ }
+ 
+-void *switch_to(void *prev, void *next, void *last)
++void *_switch_to(void *prev, void *next, void *last)
+ {
+ 	return(CHOOSE_MODE(switch_to_tt(prev, next), 
+ 			   switch_to_skas(prev, next)));
+@@ -149,7 +145,7 @@ void release_thread(struct task_struct *
+ void exit_thread(void)
+ {
+ 	CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
+-	unprotect_stack((unsigned long) current->thread_info);
++	unprotect_stack((unsigned long) current_thread);
+ }
+  
+ void *get_current(void)
+@@ -157,6 +153,10 @@ void *get_current(void)
+ 	return(current);
+ }
+ 
++void prepare_to_copy(struct task_struct *tsk)
++{
++}
++
+ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ 		unsigned long stack_top, struct task_struct * p, 
+ 		struct pt_regs *regs)
+@@ -190,7 +190,7 @@ int current_pid(void)
+ 
+ void default_idle(void)
+ {
+-	idle_timer();
++	uml_idle_timer();
+ 
+ 	atomic_inc(&init_mm.mm_count);
+ 	current->mm = &init_mm;
+@@ -363,10 +363,15 @@ int clear_user_proc(void *buf, int size)
+ 	return(clear_user(buf, size));
+ }
+ 
++int strlen_user_proc(char *str)
++{
++	return(strlen_user(str));
++}
++
+ int smp_sigio_handler(void)
+ {
+ #ifdef CONFIG_SMP
+-	int cpu = current->thread_info->cpu;
++	int cpu = current_thread->cpu;
+ 	IPI_handler(cpu);
+ 	if(cpu != 0)
+ 		return(1);
+@@ -381,7 +386,7 @@ int um_in_interrupt(void)
+ 
+ int cpu(void)
+ {
+-	return(current->thread_info->cpu);
++	return(current_thread->cpu);
+ }
+ 
+ /*
+--- linux-2.6.0-test6/arch/um/kernel/ptrace.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/arch/um/kernel/ptrace.c	2003-10-05 00:34:32.000000000 -0700
+@@ -311,11 +311,8 @@ void syscall_trace(void)
+ 
+ 	/* the 0x80 provides a way for the tracing parent to distinguish
+ 	   between a syscall stop and SIGTRAP delivery */
+- 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+- 					? 0x80 : 0);
+-	current->state = TASK_STOPPED;
+-	notify_parent(current, SIGCHLD);
+-	schedule();
++	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
++				 ? 0x80 : 0));
+ 
+ 	/*
+ 	 * this isn't the same as continuing with a signal, but it will do
+--- linux-2.6.0-test6/arch/um/kernel/sigio_kern.c	2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/um/kernel/sigio_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -6,18 +6,21 @@
+ #include "linux/kernel.h"
+ #include "linux/list.h"
+ #include "linux/slab.h"
+-#include "asm/irq.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "init.h"
+ #include "sigio.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ /* Protected by sigio_lock() called from write_sigio_workaround */
+ static int sigio_irq_fd = -1;
+ 
+-void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	read_sigio_fd(sigio_irq_fd);
+ 	reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ int write_sigio_irq(int fd)
+--- linux-2.6.0-test6/arch/um/kernel/signal_kern.c	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/um/kernel/signal_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -36,7 +36,7 @@ static void force_segv(int sig)
+ 	if(sig == SIGSEGV){
+ 		struct k_sigaction *ka;
+ 
+-		ka = &current->sig->action[SIGSEGV - 1];
++		ka = &current->sighand->action[SIGSEGV - 1];
+ 		ka->sa.sa_handler = SIG_DFL;
+ 	}
+ 	force_sig(SIGSEGV, current);
+@@ -142,7 +142,7 @@ static int kern_do_signal(struct pt_regs
+ 		return(0);
+ 
+ 	/* Whee!  Actually deliver the signal.  */
+-	ka = &current->sig->action[sig -1 ];
++	ka = &current->sighand->action[sig -1 ];
+ 	err = handle_signal(regs, sig, ka, &info, oldset, error);
+ 	if(!err) return(1);
+ 
+@@ -201,7 +201,7 @@ int sys_sigsuspend(int history0, int his
+ 	}
+ }
+ 
+-int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
++int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+ {
+ 	sigset_t saveset, newset;
+ 
+@@ -227,6 +227,42 @@ int sys_rt_sigsuspend(sigset_t *unewset,
+ 	}
+ }
+ 
++int sys_sigaction(int sig, const struct old_sigaction __user *act,
++			 struct old_sigaction __user *oact)
++{
++	struct k_sigaction new_ka, old_ka;
++	int ret;
++
++	if (act) {
++		old_sigset_t mask;
++		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
++		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
++		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
++			return -EFAULT;
++		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
++		__get_user(mask, &act->sa_mask);
++		siginitset(&new_ka.sa.sa_mask, mask);
++	}
++
++	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++
++	if (!ret && oact) {
++		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
++		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
++		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
++			return -EFAULT;
++		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
++	}
++
++	return ret;
++}
++
++int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
++{
++	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
++}
++
+ static int copy_sc_from_user(struct pt_regs *to, void *from, 
+ 			     struct arch_frame_data *arch)
+ {
+@@ -239,8 +275,8 @@ static int copy_sc_from_user(struct pt_r
+ 
+ int sys_sigreturn(struct pt_regs regs)
+ {
+-	void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
+-	void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
++	void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
++	void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
+ 	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
+ 
+ 	spin_lock_irq(&current->sighand->siglock);
+@@ -257,7 +293,8 @@ int sys_sigreturn(struct pt_regs regs)
+ 
+ int sys_rt_sigreturn(struct pt_regs regs)
+ {
+-	struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
++	unsigned long sp = PT_REGS_SP(&current->thread.regs);
++	struct ucontext __user *uc = sp_to_uc(sp);
+ 	void *fp;
+ 	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
+ 
+--- linux-2.6.0-test6/arch/um/kernel/skas/include/mode.h	2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/um/kernel/skas/include/mode.h	2003-10-05 00:34:32.000000000 -0700
+@@ -20,6 +20,7 @@ extern void sig_handler_common_skas(int 
+ extern void halt_skas(void);
+ extern void reboot_skas(void);
+ extern void kill_off_processes_skas(void);
++extern int is_skas_winch(int pid, int fd, void *data);
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/arch/um/kernel/skas/include/uaccess.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/um/kernel/skas/include/uaccess.h	2003-10-05 00:34:32.000000000 -0700
+@@ -19,7 +19,7 @@
+ #define access_ok_skas(type, addr, size) \
+ 	((segment_eq(get_fs(), KERNEL_DS)) || \
+ 	 (((unsigned long) (addr) < TASK_SIZE) && \
+-	  ((unsigned long) (addr) + (size) < TASK_SIZE)))
++	  ((unsigned long) (addr) + (size) <= TASK_SIZE)))
+ 
+ static inline int verify_area_skas(int type, const void * addr, 
+ 				   unsigned long size)
+--- linux-2.6.0-test6/arch/um/kernel/skas/Makefile	2003-06-14 12:18:06.000000000 -0700
++++ 25/arch/um/kernel/skas/Makefile	2003-10-05 00:34:32.000000000 -0700
+@@ -7,18 +7,22 @@ obj-y = exec_kern.o exec_user.o mem.o me
+ 	process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
+ 	sys-$(SUBARCH)/
+ 
++host-progs	:= util/mk_ptregs
++clean-files	:= include/skas_ptregs.h
++
+ USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+ 
+-include/skas_ptregs.h : util/mk_ptregs
+-	util/mk_ptregs > $@
+-
+-util/mk_ptregs :
+-	$(MAKE) -C util
++$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
++	@echo -n '  Generating $@'
++	@$< > $@.tmp
++	@if [ -r $@ ] && cmp -s $@ $@.tmp; then \
++		echo ' (unchanged)'; \
++		rm -f $@.tmp; \
++	else \
++		echo ' (updated)'; \
++		mv -f $@.tmp $@; \
++	fi
+ 
+ $(USER_OBJS) : %.o: %.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+-
+-clean :
+-	$(MAKE) -C util clean
+-	$(RM) -f include/skas_ptregs.h
+--- linux-2.6.0-test6/arch/um/kernel/skas/process.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/um/kernel/skas/process.c	2003-10-05 00:34:32.000000000 -0700
+@@ -4,6 +4,7 @@
+  */
+ 
+ #include <stdlib.h>
++#include <unistd.h>
+ #include <errno.h>
+ #include <signal.h>
+ #include <setjmp.h>
+@@ -24,6 +25,16 @@
+ #include "os.h"
+ #include "proc_mm.h"
+ #include "skas_ptrace.h"
++#include "chan_user.h"
++
++int is_skas_winch(int pid, int fd, void *data)
++{
++	if(pid != getpid())
++		return(0);
++
++	register_winch_irq(-1, fd, -1, data);
++	return(1);
++}
+ 
+ unsigned long exec_regs[FRAME_SIZE];
+ unsigned long exec_fp_regs[HOST_FP_SIZE];
+@@ -48,11 +59,11 @@ static void handle_trap(int pid, union u
+ 	int err, syscall_nr, status;
+ 
+ 	syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
++	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 	if(syscall_nr < 1){
+ 		relay_signal(SIGTRAP, regs);
+ 		return;
+ 	}
+-	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 
+ 	err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
+ 	if(err < 0)
+@@ -72,8 +83,6 @@ static void handle_trap(int pid, union u
+ 	handle_syscall(regs);
+ }
+ 
+-int userspace_pid;
+-
+ static int userspace_tramp(void *arg)
+ {
+ 	init_new_thread_signals(0);
+@@ -83,6 +92,8 @@ static int userspace_tramp(void *arg)
+ 	return(0);
+ }
+ 
++int userspace_pid;
++
+ void start_userspace(void)
+ {
+ 	void *stack;
+@@ -149,6 +160,7 @@ void userspace(union uml_pt_regs *regs)
+ 			case SIGILL:
+ 			case SIGBUS:
+ 			case SIGFPE:
++			case SIGWINCH:
+ 				user_signal(WSTOPSIG(status), regs);
+ 				break;
+ 			default:
+@@ -328,7 +340,8 @@ void reboot_skas(void)
+ int new_mm(int from)
+ {
+ 	struct proc_mm_op copy;
+-	int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
++	int n, fd = os_open_file("/proc/mm", 
++				 of_cloexec(of_write(OPENFLAGS())), 0);
+ 
+ 	if(fd < 0)
+ 		return(-errno);
+@@ -342,6 +355,7 @@ int new_mm(int from)
+ 			printk("new_mm : /proc/mm copy_segments failed, "
+ 			       "errno = %d\n", errno);
+ 	}
++
+ 	return(fd);
+ }
+ 
+--- linux-2.6.0-test6/arch/um/kernel/skas/process_kern.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/skas/process_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -61,9 +61,8 @@ void new_thread_handler(int sig)
+ 	thread_wait(&current->thread.mode.skas.switch_buf, 
+ 		    current->thread.mode.skas.fork_buf);
+ 
+-#ifdef CONFIG_SMP
+-	schedule_tail(NULL);
+-#endif
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
+ 	current->thread.prev_sched = NULL;
+ 
+ 	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
+@@ -93,9 +92,8 @@ void fork_handler(int sig)
+ 		    current->thread.mode.skas.fork_buf);
+   	
+ 	force_flush_all();
+-#ifdef CONFIG_SMP
+-	schedule_tail(current->thread.prev_sched);
+-#endif
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
+ 	current->thread.prev_sched = NULL;
+ 	unblock_signals();
+ 
+@@ -136,7 +134,7 @@ int copy_thread_skas(int nr, unsigned lo
+ 
+ void init_idle_skas(void)
+ {
+-	cpu_tasks[current->thread_info->cpu].pid = os_getpid();
++	cpu_tasks[current_thread->cpu].pid = os_getpid();
+ 	default_idle();
+ }
+ 
+@@ -164,7 +162,7 @@ int start_uml_skas(void)
+ 	capture_signal_stack();
+ 
+ 	init_new_thread_signals(1);
+-	idle_timer();
++	uml_idle_timer();
+ 
+ 	init_task.thread.request.u.thread.proc = start_kernel_proc;
+ 	init_task.thread.request.u.thread.arg = NULL;
+--- linux-2.6.0-test6/arch/um/kernel/skas/util/mk_ptregs.c	2003-06-14 12:18:08.000000000 -0700
++++ 25/arch/um/kernel/skas/util/mk_ptregs.c	2003-10-05 00:34:32.000000000 -0700
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+ 
+--- linux-2.6.0-test6/arch/um/kernel/smp.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/smp.c	2003-10-05 00:34:32.000000000 -0700
+@@ -22,7 +22,7 @@
+ #include "os.h"
+ 
+ /* CPU online map, set by smp_boot_cpus */
+-unsigned long cpu_online_map = cpumask_of_cpu(0);
++unsigned long cpu_online_map = CPU_MASK_NONE;
+ 
+ /* Per CPU bogomips and other parameters
+  * The only piece used here is the ipi pipe, which is set before SMP is
+@@ -97,15 +97,15 @@ void smp_send_stop(void)
+ 
+ 	printk(KERN_INFO "Stopping all CPUs...");
+ 	for(i = 0; i < num_online_cpus(); i++){
+-		if(i == current->thread_info->cpu)
++		if(i == current_thread->cpu)
+ 			continue;
+ 		write(cpu_data[i].ipi_pipe[1], "S", 1);
+ 	}
+ 	printk("done\n");
+ }
+ 
+-static cpumask_t smp_commenced_mask;
+-static cpumask_t smp_callin_map = CPU_MASK_NONE;
++static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
++static cpumask_t cpu_callin_map = CPU_MASK_NONE;
+ 
+ static int idle_proc(void *cpup)
+ {
+@@ -120,12 +120,12 @@ static int idle_proc(void *cpup)
+ 		     current->thread.mode.tt.extern_pid);
+  
+ 	wmb();
+-	if (cpu_test_and_set(cpu, &smp_callin_map)) {
++	if (cpu_test_and_set(cpu, cpu_callin_map)) {
+ 		printk("huh, CPU#%d already present??\n", cpu);
+ 		BUG();
+ 	}
+ 
+-	while (!cpu_isset(cpu, &smp_commenced_mask))
++	while (!cpu_isset(cpu, smp_commenced_mask))
+ 		cpu_relax();
+ 
+ 	cpu_set(cpu, cpu_online_map);
+@@ -140,8 +140,11 @@ static struct task_struct *idle_thread(i
+ 
+         current->thread.request.u.thread.proc = idle_proc;
+         current->thread.request.u.thread.arg = (void *) cpu;
+-	new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
+-	if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
++	new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
++				NULL);
++	if(IS_ERR(new_task)) 
++		panic("copy_process failed in idle_thread, error = %ld",
++		      PTR_ERR(new_task));
+ 
+ 	cpu_tasks[cpu] = ((struct cpu_task) 
+ 		          { .pid = 	new_task->thread.mode.tt.extern_pid,
+@@ -150,6 +153,7 @@ static struct task_struct *idle_thread(i
+ 	CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
+ 			  sizeof(c)),
+ 		    ({ panic("skas mode doesn't support SMP"); }));
++	wake_up_forked_process(new_task);
+ 	return(new_task);
+ }
+ 
+@@ -157,15 +161,16 @@ void smp_prepare_cpus(unsigned int maxcp
+ {
+ 	struct task_struct *idle;
+ 	unsigned long waittime;
+-	int err, cpu;
++	int err, cpu, me = smp_processor_id();
+ 
+-	cpu_set(0, cpu_online_map);
+-	cpu_set(0, smp_callin_map);
++	cpu_clear(me, cpu_online_map);
++	cpu_set(me, cpu_online_map);
++	cpu_set(me, cpu_callin_map);
+ 
+-	err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
++	err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
+ 	if(err)	panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
+ 
+-	activate_ipi(cpu_data[0].ipi_pipe[0], 
++	activate_ipi(cpu_data[me].ipi_pipe[0], 
+ 		     current->thread.mode.tt.extern_pid);
+ 
+ 	for(cpu = 1; cpu < ncpus; cpu++){
+@@ -177,10 +182,10 @@ void smp_prepare_cpus(unsigned int maxcp
+ 		unhash_process(idle);
+ 
+ 		waittime = 200000000;
+-		while (waittime-- && !cpu_isset(cpu, smp_callin_map))
++		while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
+ 			cpu_relax();
+ 
+-		if (cpu_isset(cpu, smp_callin_map))
++		if (cpu_isset(cpu, cpu_callin_map))
+ 			printk("done\n");
+ 		else printk("failed\n");
+ 	}
+@@ -270,7 +275,7 @@ int smp_call_function(void (*_func)(void
+ 	info = _info;
+ 
+ 	for (i=0;i<NR_CPUS;i++)
+-		if((i != current->thread_info->cpu) && 
++		if((i != current_thread->cpu) && 
+ 		   cpu_isset(i, cpu_online_map))
+ 			write(cpu_data[i].ipi_pipe[1], "C", 1);
+ 
+--- linux-2.6.0-test6/arch/um/kernel/syscall_kern.c	2003-06-14 12:18:28.000000000 -0700
++++ 25/arch/um/kernel/syscall_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -35,39 +35,40 @@ long um_mount(char * dev_name, char * di
+ 
+ long sys_fork(void)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
++        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+-long sys_clone(unsigned long clone_flags, unsigned long newsp)
++long sys_clone(unsigned long clone_flags, unsigned long newsp, 
++	       int *parent_tid, int *child_tid)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-	p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
++	ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+ long sys_vfork(void)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
++	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
++		      NULL);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+ /* common code for old and new mmaps */
+-static inline long do_mmap2(
+-	unsigned long addr, unsigned long len,
+-	unsigned long prot, unsigned long flags,
+-	unsigned long fd, unsigned long pgoff)
++long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
++	      unsigned long prot, unsigned long flags, unsigned long fd,
++	      unsigned long pgoff)
+ {
+ 	int error = -EBADF;
+ 	struct file * file = NULL;
+@@ -93,7 +94,7 @@ long sys_mmap2(unsigned long addr, unsig
+ 	       unsigned long prot, unsigned long flags,
+ 	       unsigned long fd, unsigned long pgoff)
+ {
+-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
++	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
+ }
+ 
+ /*
+@@ -120,7 +121,8 @@ int old_mmap(unsigned long addr, unsigne
+ 	if (offset & ~PAGE_MASK)
+ 		goto out;
+ 
+-	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++	err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
++		       offset >> PAGE_SHIFT);
+  out:
+ 	return err;
+ }
+@@ -141,37 +143,6 @@ int sys_pipe(unsigned long * fildes)
+         return error;
+ }
+ 
+-int sys_sigaction(int sig, const struct old_sigaction *act,
+-			 struct old_sigaction *oact)
+-{
+-	struct k_sigaction new_ka, old_ka;
+-	int ret;
+-
+-	if (act) {
+-		old_sigset_t mask;
+-		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+-			return -EFAULT;
+-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+-		__get_user(mask, &act->sa_mask);
+-		siginitset(&new_ka.sa.sa_mask, mask);
+-	}
+-
+-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+-
+-	if (!ret && oact) {
+-		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+-			return -EFAULT;
+-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+-	}
+-
+-	return ret;
+-}
+-
+ /*
+  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+  *
+@@ -253,7 +224,7 @@ int sys_ipc (uint call, int first, int s
+ 		return sys_shmctl (first, second,
+ 				   (struct shmid_ds *) ptr);
+ 	default:
+-		return -EINVAL;
++		return -ENOSYS;
+ 	}
+ }
+ 
+@@ -302,11 +273,6 @@ int sys_olduname(struct oldold_utsname *
+ 	return error;
+ }
+ 
+-int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+-{
+-	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
+-}
+-
+ long execute_syscall(void *r)
+ {
+ 	return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
+--- linux-2.6.0-test6/arch/um/kernel/sys_call_table.c	2003-06-14 12:18:30.000000000 -0700
++++ 25/arch/um/kernel/sys_call_table.c	2003-10-05 00:34:32.000000000 -0700
+@@ -219,15 +219,30 @@ extern syscall_handler_t sys_getdents64;
+ extern syscall_handler_t sys_gettid;
+ extern syscall_handler_t sys_readahead;
+ extern syscall_handler_t sys_tkill;
++extern syscall_handler_t sys_setxattr;
++extern syscall_handler_t sys_lsetxattr;
++extern syscall_handler_t sys_fsetxattr;
++extern syscall_handler_t sys_getxattr;
++extern syscall_handler_t sys_lgetxattr;
++extern syscall_handler_t sys_fgetxattr;
++extern syscall_handler_t sys_listxattr;
++extern syscall_handler_t sys_llistxattr;
++extern syscall_handler_t sys_flistxattr;
++extern syscall_handler_t sys_removexattr;
++extern syscall_handler_t sys_lremovexattr;
++extern syscall_handler_t sys_fremovexattr;
+ extern syscall_handler_t sys_sendfile64;
+ extern syscall_handler_t sys_futex;
+ extern syscall_handler_t sys_sched_setaffinity;
+ extern syscall_handler_t sys_sched_getaffinity;
++extern syscall_handler_t sys_set_thread_area;
++extern syscall_handler_t sys_get_thread_area;
+ extern syscall_handler_t sys_io_setup;
+ extern syscall_handler_t sys_io_destroy;
+ extern syscall_handler_t sys_io_getevents;
+ extern syscall_handler_t sys_io_submit;
+ extern syscall_handler_t sys_io_cancel;
++extern syscall_handler_t sys_fadvise64;
+ extern syscall_handler_t sys_exit_group;
+ extern syscall_handler_t sys_lookup_dcookie;
+ extern syscall_handler_t sys_epoll_create;
+@@ -235,6 +250,20 @@ extern syscall_handler_t sys_epoll_ctl;
+ extern syscall_handler_t sys_epoll_wait;
+ extern syscall_handler_t sys_remap_file_pages;
+ extern syscall_handler_t sys_set_tid_address;
++extern syscall_handler_t sys_timer_create;
++extern syscall_handler_t sys_timer_settime;
++extern syscall_handler_t sys_timer_gettime;
++extern syscall_handler_t sys_timer_getoverrun;
++extern syscall_handler_t sys_timer_delete;
++extern syscall_handler_t sys_clock_settime;
++extern syscall_handler_t sys_clock_gettime;
++extern syscall_handler_t sys_clock_getres;
++extern syscall_handler_t sys_clock_nanosleep;
++extern syscall_handler_t sys_statfs64;
++extern syscall_handler_t sys_fstatfs64;
++extern syscall_handler_t sys_tgkill;
++extern syscall_handler_t sys_utimes;
++extern syscall_handler_t sys_fadvise64_64;
+ 
+ #ifdef CONFIG_NFSD
+ #define NFSSERVCTL sys_nfsservctl
+@@ -246,7 +275,7 @@ extern syscall_handler_t um_mount;
+ extern syscall_handler_t um_time;
+ extern syscall_handler_t um_stime;
+ 
+-#define LAST_GENERIC_SYSCALL __NR_set_tid_address
++#define LAST_GENERIC_SYSCALL __NR_fadvise64_64
+ 
+ #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
+ #define LAST_SYSCALL LAST_GENERIC_SYSCALL
+@@ -455,32 +484,37 @@ syscall_handler_t *sys_call_table[] = {
+ 	[ __NR_stat64 ] = sys_stat64,
+ 	[ __NR_lstat64 ] = sys_lstat64,
+ 	[ __NR_fstat64 ] = sys_fstat64,
+-	[ __NR_fcntl64 ] = sys_fcntl64,
+ 	[ __NR_getdents64 ] = sys_getdents64,
++	[ __NR_fcntl64 ] = sys_fcntl64,
++	[ 223 ] = sys_ni_syscall,
+ 	[ __NR_gettid ] = sys_gettid,
+ 	[ __NR_readahead ] = sys_readahead,
+-	[ __NR_setxattr ] = sys_ni_syscall,
+-	[ __NR_lsetxattr ] = sys_ni_syscall,
+-	[ __NR_fsetxattr ] = sys_ni_syscall,
+-	[ __NR_getxattr ] = sys_ni_syscall,
+-	[ __NR_lgetxattr ] = sys_ni_syscall,
+-	[ __NR_fgetxattr ] = sys_ni_syscall,
+-	[ __NR_listxattr ] = sys_ni_syscall,
+-	[ __NR_llistxattr ] = sys_ni_syscall,
+-	[ __NR_flistxattr ] = sys_ni_syscall,
+-	[ __NR_removexattr ] = sys_ni_syscall,
+-	[ __NR_lremovexattr ] = sys_ni_syscall,
+-	[ __NR_fremovexattr ] = sys_ni_syscall,
++	[ __NR_setxattr ] = sys_setxattr,
++	[ __NR_lsetxattr ] = sys_lsetxattr,
++	[ __NR_fsetxattr ] = sys_fsetxattr,
++	[ __NR_getxattr ] = sys_getxattr,
++	[ __NR_lgetxattr ] = sys_lgetxattr,
++	[ __NR_fgetxattr ] = sys_fgetxattr,
++	[ __NR_listxattr ] = sys_listxattr,
++	[ __NR_llistxattr ] = sys_llistxattr,
++	[ __NR_flistxattr ] = sys_flistxattr,
++	[ __NR_removexattr ] = sys_removexattr,
++	[ __NR_lremovexattr ] = sys_lremovexattr,
++	[ __NR_fremovexattr ] = sys_fremovexattr,
+ 	[ __NR_tkill ] = sys_tkill,
+ 	[ __NR_sendfile64 ] = sys_sendfile64,
+ 	[ __NR_futex ] = sys_futex,
+ 	[ __NR_sched_setaffinity ] = sys_sched_setaffinity,
+ 	[ __NR_sched_getaffinity ] = sys_sched_getaffinity,
++	[ __NR_set_thread_area ] = sys_ni_syscall,
++	[ __NR_get_thread_area ] = sys_ni_syscall,
+ 	[ __NR_io_setup ] = sys_io_setup,
+ 	[ __NR_io_destroy ] = sys_io_destroy,
+ 	[ __NR_io_getevents ] = sys_io_getevents,
+ 	[ __NR_io_submit ] = sys_io_submit,
+ 	[ __NR_io_cancel ] = sys_io_cancel,
++	[ __NR_fadvise64 ] = sys_fadvise64,
++	[ 251 ] = sys_ni_syscall,
+ 	[ __NR_exit_group ] = sys_exit_group,
+ 	[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
+ 	[ __NR_epoll_create ] = sys_epoll_create,
+@@ -488,6 +522,20 @@ syscall_handler_t *sys_call_table[] = {
+ 	[ __NR_epoll_wait ] = sys_epoll_wait,
+         [ __NR_remap_file_pages ] = sys_remap_file_pages,
+         [ __NR_set_tid_address ] = sys_set_tid_address,
++	[ __NR_timer_create ] = sys_timer_create,
++	[ __NR_timer_settime ] = sys_timer_settime,
++	[ __NR_timer_gettime ] = sys_timer_gettime,
++	[ __NR_timer_getoverrun ] = sys_timer_getoverrun,
++	[ __NR_timer_delete ] = sys_timer_delete,
++	[ __NR_clock_settime ] = sys_clock_settime,
++	[ __NR_clock_gettime ] = sys_clock_gettime,
++	[ __NR_clock_getres ] = sys_clock_getres,
++	[ __NR_clock_nanosleep ] = sys_clock_nanosleep,
++	[ __NR_statfs64 ] = sys_statfs64,
++	[ __NR_fstatfs64 ] = sys_fstatfs64,
++	[ __NR_tgkill ] = sys_tgkill,
++	[ __NR_utimes ] = sys_utimes,
++	[ __NR_fadvise64_64 ] = sys_fadvise64_64,
+ 
+ 	ARCH_SYSCALLS
+ 	[ LAST_SYSCALL + 1 ... NR_syscalls ] = 
+--- linux-2.6.0-test6/arch/um/kernel/sysrq.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/arch/um/kernel/sysrq.c	2003-10-05 00:34:32.000000000 -0700
+@@ -53,6 +53,14 @@ void show_trace_task(struct task_struct 
+ 	show_trace((unsigned long *)esp);
+ }
+ 
++void show_stack(struct task_struct *task, unsigned long *sp)
++{
++	if(task)
++		show_trace_task(task);
++	else
++		show_trace(sp);
++}
++
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+--- linux-2.6.0-test6/arch/um/kernel/time.c	2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/um/kernel/time.c	2003-10-05 00:34:32.000000000 -0700
+@@ -15,12 +15,16 @@
+ #include "process.h"
+ #include "signal_user.h"
+ #include "time_user.h"
++#include "kern_constants.h"
+ 
+ extern struct timeval xtime;
+ 
++struct timeval local_offset = { 0, 0 };
++
+ void timer(void)
+ {
+ 	gettimeofday(&xtime, NULL);
++	timeradd(&xtime, &local_offset, &xtime);
+ }
+ 
+ void set_interval(int timer_type)
+@@ -65,7 +69,7 @@ void switch_timers(int to_real)
+ 		       errno);
+ }
+ 
+-void idle_timer(void)
++void uml_idle_timer(void)
+ {
+ 	if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
+ 		panic("Couldn't unset SIGVTALRM handler");
+@@ -82,8 +86,6 @@ void time_init(void)
+ 	set_interval(ITIMER_VIRTUAL);
+ }
+ 
+-struct timeval local_offset = { 0, 0 };
+-
+ void do_gettimeofday(struct timeval *tv)
+ {
+ 	unsigned long flags;
+@@ -100,7 +102,7 @@ int do_settimeofday(struct timespec *tv)
+ 	unsigned long flags;
+ 	struct timeval tv_in;
+ 
+-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++	if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
+ 		return -EINVAL;
+ 
+ 	tv_in.tv_sec = tv->tv_sec;
+@@ -110,6 +112,8 @@ int do_settimeofday(struct timespec *tv)
+ 	gettimeofday(&now, NULL);
+ 	timersub(&tv_in, &now, &local_offset);
+ 	time_unlock(flags);
++
++	return(0);
+ }
+ 
+ void idle_sleep(int secs)
+--- linux-2.6.0-test6/arch/um/kernel/time_kern.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/um/kernel/time_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -38,7 +38,7 @@ int __attribute__ ((__section__ (".unpro
+ 
+ void timer_irq(union uml_pt_regs *regs)
+ {
+-	int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
++	int cpu = current_thread->cpu, ticks = missed_ticks[cpu];
+ 
+         if(!timer_irq_inited) return;
+ 	missed_ticks[cpu] = 0;
+@@ -55,12 +55,13 @@ void boot_timer_handler(int sig)
+ 	do_timer(&regs);
+ }
+ 
+-void um_timer(int irq, void *dev, struct pt_regs *regs)
++irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
+ {
+ 	do_timer(regs);
+-	write_seqlock(&xtime_lock);
++	write_seqlock_irq(&xtime_lock);
+ 	timer();
+-	write_sequnlock(&xtime_lock);
++	write_sequnlock_irq(&xtime_lock);
++	return(IRQ_HANDLED);
+ }
+ 
+ long um_time(int * tloc)
+@@ -78,12 +79,12 @@ long um_time(int * tloc)
+ long um_stime(int * tptr)
+ {
+ 	int value;
+-	struct timeval new;
++	struct timespec new;
+ 
+ 	if (get_user(value, tptr))
+                 return -EFAULT;
+ 	new.tv_sec = value;
+-	new.tv_usec = 0;
++	new.tv_nsec = 0;
+ 	do_settimeofday(&new);
+ 	return 0;
+ }
+@@ -122,9 +123,11 @@ void __const_udelay(um_udelay_t usecs)
+ void timer_handler(int sig, union uml_pt_regs *regs)
+ {
+ #ifdef CONFIG_SMP
++	local_irq_disable();
+ 	update_process_times(user_context(UPT_SP(regs)));
++	local_irq_enable();
+ #endif
+-	if(current->thread_info->cpu == 0)
++	if(current_thread->cpu == 0)
+ 		timer_irq(regs);
+ }
+ 
+--- linux-2.6.0-test6/arch/um/kernel/trap_kern.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/um/kernel/trap_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -16,6 +16,7 @@
+ #include "asm/tlbflush.h"
+ #include "asm/a.out.h"
+ #include "asm/current.h"
++#include "asm/irq.h"
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "kern.h"
+@@ -51,7 +52,7 @@ int handle_page_fault(unsigned long addr
+ 	if(is_write && !(vma->vm_flags & VM_WRITE)) 
+ 		goto out;
+ 	page = address & PAGE_MASK;
+-	if(page == (unsigned long) current->thread_info + PAGE_SIZE)
++	if(page == (unsigned long) current_thread + PAGE_SIZE)
+ 		panic("Kernel stack overflow");
+ 	pgd = pgd_offset(mm, page);
+ 	pmd = pmd_offset(pgd, page);
+@@ -180,6 +181,11 @@ void bus_handler(int sig, union uml_pt_r
+ 	else relay_signal(sig, regs);
+ }
+ 
++void winch(int sig, union uml_pt_regs *regs)
++{
++	do_IRQ(WINCH_IRQ, regs);
++}
++
+ void trap_init(void)
+ {
+ }
+--- linux-2.6.0-test6/arch/um/kernel/trap_user.c	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/um/kernel/trap_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -82,6 +82,8 @@ struct signal_info sig_info[] = {
+ 		     .is_irq 		= 0 },
+ 	[ SIGILL ] { .handler 		= relay_signal,
+ 		     .is_irq 		= 0 },
++	[ SIGWINCH ] { .handler		= winch,
++		       .is_irq		= 1 },
+ 	[ SIGBUS ] { .handler 		= bus_handler,
+ 		     .is_irq 		= 0 },
+ 	[ SIGSEGV] { .handler 		= segv_handler,
+--- linux-2.6.0-test6/arch/um/kernel/tt/exec_kern.c	2003-06-14 12:17:59.000000000 -0700
++++ 25/arch/um/kernel/tt/exec_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -47,17 +47,17 @@ void flush_thread_tt(void)
+ 		do_exit(SIGKILL);
+ 	}
+ 
+-	if(current->thread_info->cpu == 0)
++	if(current_thread->cpu == 0)
+ 		forward_interrupts(new_pid);
+ 	current->thread.request.op = OP_EXEC;
+ 	current->thread.request.u.exec.pid = new_pid;
+-	unprotect_stack((unsigned long) current->thread_info);
++	unprotect_stack((unsigned long) current_thread);
+ 	os_usr1_process(os_getpid());
+ 
+ 	enable_timer();
+ 	free_page(stack);
+ 	protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
+-	task_protections((unsigned long) current->thread_info);
++	task_protections((unsigned long) current_thread);
+ 	force_flush_all();
+ 	unblock_signals();
+ }
+--- linux-2.6.0-test6/arch/um/kernel/tt/include/uaccess.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/arch/um/kernel/tt/include/uaccess.h	2003-10-05 00:34:32.000000000 -0700
+@@ -46,18 +46,20 @@ extern int __do_copy_from_user(void *to,
+ 
+ static inline int copy_from_user_tt(void *to, const void *from, int n)
+ {
+-	return(access_ok_tt(VERIFY_READ, from, n) ?
+-	       __do_copy_from_user(to, from, n, 
+-				   &current->thread.fault_addr,
+-				   &current->thread.fault_catcher) : n);
++	if(!access_ok_tt(VERIFY_READ, from, n)) 
++		return(n);
++
++	return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
++				   &current->thread.fault_catcher));
+ }
+ 
+ static inline int copy_to_user_tt(void *to, const void *from, int n)
+ {
+-	return(access_ok_tt(VERIFY_WRITE, to, n) ?
+-	       __do_copy_to_user(to, from, n, 
+-				   &current->thread.fault_addr,
+-				   &current->thread.fault_catcher) : n);
++	if(!access_ok_tt(VERIFY_WRITE, to, n))
++		return(n);
++		
++	return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
++				 &current->thread.fault_catcher));
+ }
+ 
+ extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
+@@ -67,7 +69,9 @@ static inline int strncpy_from_user_tt(c
+ {
+ 	int n;
+ 
+-	if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
++	if(!access_ok_tt(VERIFY_READ, src, 1)) 
++		return(-EFAULT);
++
+ 	n = __do_strncpy_from_user(dst, src, count, 
+ 				   &current->thread.fault_addr,
+ 				   &current->thread.fault_catcher);
+@@ -87,10 +91,11 @@ static inline int __clear_user_tt(void *
+ 
+ static inline int clear_user_tt(void *mem, int len)
+ {
+-	return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
+-	       __do_clear_user(mem, len, 
+-			       &current->thread.fault_addr,
+-			       &current->thread.fault_catcher) : len);
++	if(!access_ok_tt(VERIFY_WRITE, mem, len))
++		return(len);
++
++	return(__do_clear_user(mem, len, &current->thread.fault_addr,
++			       &current->thread.fault_catcher));
+ }
+ 
+ extern int __do_strnlen_user(const char *str, unsigned long n,
+--- linux-2.6.0-test6/arch/um/kernel/tt/process_kern.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/tt/process_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -104,7 +104,10 @@ void *switch_to_tt(void *prev, void *nex
+ 
+ void release_thread_tt(struct task_struct *task)
+ {
+-	os_kill_process(task->thread.mode.tt.extern_pid, 0);
++	int pid = task->thread.mode.tt.extern_pid;
++
++	if(os_getpid() != pid)
++		os_kill_process(pid, 0);
+ }
+ 
+ void exit_thread_tt(void)
+@@ -125,27 +128,27 @@ static void new_thread_handler(int sig)
+ 	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
+ 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+ 
+-	block_signals();
++	force_flush_all();
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
++	current->thread.prev_sched = NULL;
++
+ 	init_new_thread_signals(1);
+-#ifdef CONFIG_SMP
+-	schedule_tail(current->thread.prev_sched);
+-#endif
+ 	enable_timer();
+ 	free_page(current->thread.temp_stack);
+ 	set_cmdline("(kernel thread)");
+-	force_flush_all();
+ 
+-	current->thread.prev_sched = NULL;
+ 	change_sig(SIGUSR1, 1);
+ 	change_sig(SIGVTALRM, 1);
+ 	change_sig(SIGPROF, 1);
+-	unblock_signals();
++	local_irq_enable();
+ 	if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
+ 		do_exit(0);
+ }
+ 
+ static int new_thread_proc(void *stack)
+ {
++	local_irq_disable();
+ 	init_new_thread_stack(stack, new_thread_handler);
+ 	os_usr1_process(os_getpid());
+ 	return(0);
+@@ -165,35 +168,32 @@ void finish_fork_handler(int sig)
+  	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
+ 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+ 
+-#ifdef CONFIG_SMP	
+-	schedule_tail(NULL);
+-#endif
++	force_flush_all();
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
++	current->thread.prev_sched = NULL;
++
+ 	enable_timer();
+ 	change_sig(SIGVTALRM, 1);
+ 	local_irq_enable();
+-	force_flush_all();
+ 	if(current->mm != current->parent->mm)
+ 		protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
+ 			       1, 0, 1);
+-	task_protections((unsigned long) current->thread_info);
+-
+-	current->thread.prev_sched = NULL;
++	task_protections((unsigned long) current_thread);
+ 
+ 	free_page(current->thread.temp_stack);
++	local_irq_disable();
+ 	change_sig(SIGUSR1, 0);
+ 	set_user_mode(current);
+ }
+ 
+-static int sigusr1 = SIGUSR1;
+-
+ int fork_tramp(void *stack)
+ {
+-	int sig = sigusr1;
+-
+ 	local_irq_disable();
++	arch_init_thread();
+ 	init_new_thread_stack(stack, finish_fork_handler);
+ 
+-	kill(os_getpid(), sig);
++	os_usr1_process(os_getpid());
+ 	return(0);
+ }
+ 
+@@ -377,8 +377,8 @@ static void mprotect_kernel_mem(int w)
+ 
+ 	pages = (1 << CONFIG_KERNEL_STACK_ORDER);
+ 
+-	start = (unsigned long) current->thread_info + PAGE_SIZE;
+-	end = (unsigned long) current + PAGE_SIZE * pages;
++	start = (unsigned long) current_thread + PAGE_SIZE;
++	end = (unsigned long) current_thread + PAGE_SIZE * pages;
+ 	protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
+ 	protect_memory(end, high_physmem - end, 1, w, 1, 1);
+ 
+--- linux-2.6.0-test6/arch/um/kernel/tt/ptproxy/proxy.c	2003-06-14 12:18:23.000000000 -0700
++++ 25/arch/um/kernel/tt/ptproxy/proxy.c	2003-10-05 00:34:32.000000000 -0700
+@@ -293,10 +293,10 @@ void fake_child_exit(void)
+ }
+ 
+ char gdb_init_string[] = 
+-"att 1
+-b panic
+-b stop
+-handle SIGWINCH nostop noprint pass
++"att 1 \n\
++b panic \n\
++b stop \n\
++handle SIGWINCH nostop noprint pass \n\
+ ";
+ 
+ int start_debugger(char *prog, int startup, int stop, int *fd_out)
+--- linux-2.6.0-test6/arch/um/kernel/tt/tracer.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/arch/um/kernel/tt/tracer.c	2003-10-05 00:34:32.000000000 -0700
+@@ -39,7 +39,7 @@ int is_tracer_winch(int pid, int fd, voi
+ 		return(0);
+ 
+ 	register_winch_irq(tracer_winch[0], fd, -1, data);
+-	return(0);
++	return(1);
+ }
+ 
+ static void tracer_winch_handler(int sig)
+@@ -401,7 +401,7 @@ static int __init uml_debug_setup(char *
+ 		
+ 		if(!strcmp(line, "go"))	debug_stop = 0;
+ 		else if(!strcmp(line, "parent")) debug_parent = 1;
+-		else printk("Unknown debug option : '%s'\n", line);
++		else printf("Unknown debug option : '%s'\n", line);
+ 
+ 		line = next;
+ 	}
+--- linux-2.6.0-test6/arch/um/kernel/tt/uaccess_user.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/arch/um/kernel/tt/uaccess_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -8,15 +8,20 @@
+ #include <string.h>
+ #include "user_util.h"
+ #include "uml_uaccess.h"
++#include "task.h"
++#include "kern_util.h"
+ 
+ int __do_copy_from_user(void *to, const void *from, int n,
+ 			void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+ 			       __do_copy, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(0);
+ 	else return(n - (fault - (unsigned long) from));
+ }
+@@ -29,11 +34,14 @@ static void __do_strncpy(void *dst, cons
+ int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
+ 			   void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
+ 			       __do_strncpy, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(strlen(dst));
+ 	else return(-1);
+ }
+@@ -46,11 +54,14 @@ static void __do_clear(void *to, const v
+ int __do_clear_user(void *mem, unsigned long len,
+ 		    void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
+ 			       __do_clear, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(0);
+ 	else return(len - (fault - (unsigned long) mem));
+ }
+@@ -58,6 +69,7 @@ int __do_clear_user(void *mem, unsigned 
+ int __do_strnlen_user(const char *str, unsigned long n,
+ 		      void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	int ret;
+ 	unsigned long *faddrp = (unsigned long *)fault_addr;
+ 	jmp_buf jbuf;
+@@ -71,6 +83,8 @@ int __do_strnlen_user(const char *str, u
+ 	}
+ 	*fault_addr = NULL;
+ 	*fault_catcher = NULL;
++
++	TASK_REGS(get_current())->tt = save;
+ 	return ret;
+ }
+ 
+--- linux-2.6.0-test6/arch/um/kernel/um_arch.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/um/kernel/um_arch.c	2003-10-05 00:34:32.000000000 -0700
+@@ -38,13 +38,18 @@
+ #include "mode_kern.h"
+ #include "mode.h"
+ 
+-#define DEFAULT_COMMAND_LINE "root=6200"
++#define DEFAULT_COMMAND_LINE "root=ubd0"
+ 
+ struct cpuinfo_um boot_cpu_data = { 
+ 	.loops_per_jiffy	= 0,
+ 	.ipi_pipe		= { -1, -1 }
+ };
+ 
++/* Placeholder to make UML link until the vsyscall stuff is actually 
++ * implemented
++ */
++void *__kernel_vsyscall;
++
+ unsigned long thread_saved_pc(struct task_struct *task)
+ {
+ 	return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
+@@ -61,10 +66,14 @@ static int show_cpuinfo(struct seq_file 
+ 		return 0;
+ #endif
+ 
+-	seq_printf(m, "bogomips\t: %lu.%02lu\n",
++	seq_printf(m, "processor\t: %d\n", index);
++	seq_printf(m, "vendor_id\t: User Mode Linux\n");
++	seq_printf(m, "model name\t: UML\n");
++	seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
++	seq_printf(m, "host\t\t: %s\n", host_info);
++	seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+ 		   loops_per_jiffy/(500000/HZ),
+ 		   (loops_per_jiffy/(5000/HZ)) % 100);
+-	seq_printf(m, "host\t\t: %s\n", host_info);
+ 
+ 	return(0);
+ }
+@@ -134,12 +143,12 @@ void set_cmdline(char *cmd)
+ 	if(umid != NULL){
+ 		snprintf(argv1_begin, 
+ 			 (argv1_end - argv1_begin) * sizeof(*ptr), 
+-			 "(%s)", umid);
++			 "(%s) ", umid);
+ 		ptr = &argv1_begin[strlen(argv1_begin)];
+ 	}
+ 	else ptr = argv1_begin;
+ 
+-	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
++	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
+ 	memset(argv1_begin + strlen(argv1_begin), '\0', 
+ 	       argv1_end - argv1_begin - strlen(argv1_begin));
+ #endif
+@@ -179,7 +188,7 @@ __uml_setup("root=", uml_root_setup,
+ static int __init uml_ncpus_setup(char *line, int *add)
+ {
+        if (!sscanf(line, "%d", &ncpus)) {
+-               printk("Couldn't parse [%s]\n", line);
++               printf("Couldn't parse [%s]\n", line);
+                return -1;
+        }
+ 
+@@ -210,7 +219,7 @@ static int __init mode_tt_setup(char *li
+ 
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+-	printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
++	printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
+ 	return(0);
+ }
+ 
+@@ -221,7 +230,7 @@ static int __init mode_tt_setup(char *li
+ 
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+-	printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
++	printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
+ 	return(0);
+ }
+ 
+@@ -369,6 +378,7 @@ int linux_main(int argc, char **argv)
+ 		2 * PAGE_SIZE;
+ 
+ 	task_protections((unsigned long) &init_thread_info);
++	os_flush_stdout();
+ 
+ 	return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
+ }
+--- linux-2.6.0-test6/arch/um/kernel/umid.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/um/kernel/umid.c	2003-10-05 00:34:32.000000000 -0700
+@@ -33,18 +33,19 @@ static char *uml_dir = UML_DIR;
+ static int umid_is_random = 1;
+ static int umid_inited = 0;
+ 
+-static int make_umid(void);
++static int make_umid(int (*printer)(const char *fmt, ...));
+ 
+-static int __init set_umid(char *name, int is_random)
++static int __init set_umid(char *name, int is_random, 
++			   int (*printer)(const char *fmt, ...))
+ {
+ 	if(umid_inited){
+-		printk("Unique machine name can't be set twice\n");
++		(*printer)("Unique machine name can't be set twice\n");
+ 		return(-1);
+ 	}
+ 
+ 	if(strlen(name) > UMID_LEN - 1)
+-		printk("Unique machine name is being truncated to %s "
+-		       "characters\n", UMID_LEN);
++		(*printer)("Unique machine name is being truncated to %s "
++			   "characters\n", UMID_LEN);
+ 	strlcpy(umid, name, sizeof(umid));
+ 
+ 	umid_is_random = is_random;
+@@ -54,7 +55,7 @@ static int __init set_umid(char *name, i
+ 
+ static int __init set_umid_arg(char *name, int *add)
+ {
+-	return(set_umid(name, 0));
++	return(set_umid(name, 0, printf));
+ }
+ 
+ __uml_setup("umid=", set_umid_arg,
+@@ -67,7 +68,7 @@ int __init umid_file_name(char *name, ch
+ {
+ 	int n;
+ 
+-	if(!umid_inited && make_umid()) return(-1);
++	if(!umid_inited && make_umid(printk)) return(-1);
+ 
+ 	n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
+ 	if(n > len){
+@@ -92,14 +93,14 @@ static int __init create_pid_file(void)
+ 	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
+ 			  0644);
+ 	if(fd < 0){
+-		printk("Open of machine pid file \"%s\" failed - "
++		printf("Open of machine pid file \"%s\" failed - "
+ 		       "errno = %d\n", file, -fd);
+ 		return 0;
+ 	}
+ 
+ 	sprintf(pid, "%d\n", os_getpid());
+ 	if(write(fd, pid, strlen(pid)) != strlen(pid))
+-		printk("Write of pid file failed - errno = %d\n", errno);
++		printf("Write of pid file failed - errno = %d\n", errno);
+ 	close(fd);
+ 	return 0;
+ }
+@@ -197,7 +198,7 @@ static int __init set_uml_dir(char *name
+ 	if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
+ 		uml_dir = malloc(strlen(name) + 1);
+ 		if(uml_dir == NULL){
+-			printk("Failed to malloc uml_dir - error = %d\n",
++			printf("Failed to malloc uml_dir - error = %d\n",
+ 			       errno);
+ 			uml_dir = name;
+ 			return(0);
+@@ -217,7 +218,7 @@ static int __init make_uml_dir(void)
+ 		char *home = getenv("HOME");
+ 
+ 		if(home == NULL){
+-			printk("make_uml_dir : no value in environment for "
++			printf("make_uml_dir : no value in environment for "
+ 			       "$HOME\n");
+ 			exit(1);
+ 		}
+@@ -239,25 +240,25 @@ static int __init make_uml_dir(void)
+ 	strcpy(uml_dir, dir);
+ 	
+ 	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
+-	        printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
++	        printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
+ 		return(-1);
+ 	}
+ 	return 0;
+ }
+ 
+-static int __init make_umid(void)
++static int __init make_umid(int (*printer)(const char *fmt, ...))
+ {
+ 	int fd, err;
+ 	char tmp[strlen(uml_dir) + UMID_LEN + 1];
+ 
+ 	strlcpy(tmp, uml_dir, sizeof(tmp));
+ 
+-	if(*umid == 0){
++	if(!umid_inited){
+ 		strcat(tmp, "XXXXXX");
+ 		fd = mkstemp(tmp);
+ 		if(fd < 0){
+-			printk("make_umid - mkstemp failed, errno = %d\n",
+-			       errno);
++			(*printer)("make_umid - mkstemp failed, errno = %d\n",
++				   errno);
+ 			return(1);
+ 		}
+ 
+@@ -267,7 +268,7 @@ static int __init make_umid(void)
+ 		 * for directories.
+ 		 */
+ 		unlink(tmp);
+-		set_umid(&tmp[strlen(uml_dir)], 1);
++		set_umid(&tmp[strlen(uml_dir)], 1, printer);
+ 	}
+ 	
+ 	sprintf(tmp, "%s%s", uml_dir, umid);
+@@ -275,14 +276,14 @@ static int __init make_umid(void)
+ 	if((err = mkdir(tmp, 0777)) < 0){
+ 		if(errno == EEXIST){
+ 			if(not_dead_yet(tmp)){
+-				printk("umid '%s' is in use\n", umid);
++				(*printer)("umid '%s' is in use\n", umid);
+ 				return(-1);
+ 			}
+ 			err = mkdir(tmp, 0777);
+ 		}
+ 	}
+ 	if(err < 0){
+-		printk("Failed to create %s - errno = %d\n", umid, errno);
++		(*printer)("Failed to create %s - errno = %d\n", umid, errno);
+ 		return(-1);
+ 	}
+ 
+@@ -295,7 +296,13 @@ __uml_setup("uml_dir=", set_uml_dir,
+ );
+ 
+ __uml_postsetup(make_uml_dir);
+-__uml_postsetup(make_umid);
++
++static int __init make_umid_setup(void)
++{
++	return(make_umid(printf));
++}
++
++__uml_postsetup(make_umid_setup);
+ __uml_postsetup(create_pid_file);
+ 
+ /*
+--- linux-2.6.0-test6/arch/um/kernel/user_util.c	2003-06-14 12:17:59.000000000 -0700
++++ 25/arch/um/kernel/user_util.c	2003-10-05 00:34:32.000000000 -0700
+@@ -119,17 +119,6 @@ int wait_for_stop(int pid, int sig, int 
+ 	}
+ }
+ 
+-int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
+-{
+-	int pid;
+-
+-	pid = clone(fn, sp, flags, arg);
+- 	if(pid < 0) return(-1);
+-	wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
+-	ptrace(PTRACE_CONT, pid, 0, 0);
+-	return(pid);
+-}
+-
+ int raw(int fd, int complain)
+ {
+ 	struct termios tt;
+--- linux-2.6.0-test6/arch/um/Makefile	2003-08-08 22:55:11.000000000 -0700
++++ 25/arch/um/Makefile	2003-10-05 00:34:32.000000000 -0700
+@@ -24,15 +24,17 @@ core-y			+= $(ARCH_DIR)/kernel/		 \
+ # Have to precede the include because the included Makefiles reference them.
+ SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
+ 	include/asm-um/sigcontext.h include/asm-um/processor.h \
+-	include/asm-um/ptrace.h include/asm-um/arch-signal.h
++	include/asm-um/ptrace.h include/asm-um/arch-signal.h \
++	include/asm-um/module.h
+ 
+ ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
+ 	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
+ 
+ GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
+ 
+-include $(ARCH_DIR)/Makefile-$(SUBARCH)
+-include $(ARCH_DIR)/Makefile-os-$(OS)
++.PHONY: sys_prepare
++sys_prepare:
++	@:
+ 
+ MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
+ MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+@@ -41,6 +43,9 @@ ifneq ($(MAKEFILE-y),)
+   include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
+ endif
+ 
++include $(ARCH_DIR)/Makefile-$(SUBARCH)
++include $(ARCH_DIR)/Makefile-os-$(OS)
++
+ EXTRAVERSION := $(EXTRAVERSION)-1um
+ 
+ ARCH_INCLUDE = -I$(ARCH_DIR)/include
+@@ -52,14 +57,14 @@ ARCH_INCLUDE = -I$(ARCH_DIR)/include
+ 
+ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+ 	-D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
+-	$(MODE_INCLUDE)
++	-Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
+ 
+ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+ 
+ SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
+ 
+ ifeq ($(CONFIG_MODE_SKAS), y)
+-$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+ endif
+ 
+ include/linux/version.h: arch/$(ARCH)/Makefile
+@@ -98,17 +103,17 @@ CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_
+ CONFIG_KERNEL_STACK_ORDER ?= 2
+ STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
+ 
+-AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
++AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
+ 	-DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
+ 	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+-	-DKERNEL_STACK_SIZE=$(STACK_SIZE)
++	-DKERNEL_STACK_SIZE=$(STACK_SIZE))
+ 
+-AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
++export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
+ 
+ LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
+ 
+-$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
+-	$(call if_changed_dep,as_s_S)
++#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
++#	$(call if_changed_dep,as_s_S)
+ 
+ linux: vmlinux $(LD_SCRIPT-y)
+ 	$(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
+@@ -116,6 +121,7 @@ linux: vmlinux $(LD_SCRIPT-y)
+ 
+ USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+ USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
++USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
+ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+ 	$(MODE_INCLUDE)
+ 
+@@ -123,9 +129,10 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,
+ USER_CFLAGS += -D_GNU_SOURCE
+ 
+ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
+-	$(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
++	$(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
++	$(GEN_HEADERS)
+ 
+-$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
++$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
+ 	$(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+ 
+ archmrproper:
+@@ -161,19 +168,23 @@ $(ARCH_DIR)/include/sysdep:
+ $(ARCH_DIR)/os:
+ 	cd $(ARCH_DIR) && ln -sf os-$(OS) os
+ 
+-$(ARCH_DIR)/include/uml-config.h :
++$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
+ 	sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
+ 
++filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
++
+ $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
+-	$< > $@
++	$(call filechk,$@)
++
++filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
+ 
+ $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
+-	$< > $@
++	$(call filechk,$@)
+ 
+-$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
+-	$(ARCH_DIR)/util FORCE ;
++$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
++	sys_prepare FORCE ;
+ 
+ $(ARCH_DIR)/util: FORCE
+-	@$(call descend,$@,)
++	$(MAKE) -f scripts/Makefile.build obj=$@
+ 
+-export SUBARCH USER_CFLAGS OS
++export SUBARCH USER_CFLAGS OS 
+--- linux-2.6.0-test6/arch/um/Makefile-i386	2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/um/Makefile-i386	2003-10-05 00:34:32.000000000 -0700
+@@ -16,22 +16,28 @@ SYS_UTIL_DIR	:= $(ARCH_DIR)/sys-i386/uti
+ 
+ SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+ 
++sys_prepare: $(SYS_DIR)/sc.h
++
+ prepare: $(SYS_HEADERS)
+ 
++filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
++
+ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
+-	$< > $@
++	$(call filechk,$@)
++
++filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
+ 
+ $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
+-	$< > $@
++	$(call filechk,$@)
+ 
+-$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
+-	@$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
++	+@$(call descend,$(SYS_UTIL_DIR),$@)
+ 
+-$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
+-	@$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
++	+@$(call descend,$(SYS_UTIL_DIR),$@)
+ 
+ $(SYS_UTIL_DIR): include/asm FORCE
+-	@$(call descend,$@,)
++	+@$(call descend,$@,)
+ 
+ sysclean :
+ 	rm -f $(SYS_HEADERS)
+--- linux-2.6.0-test6/arch/um/Makefile-skas	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/um/Makefile-skas	2003-10-05 00:34:32.000000000 -0700
+@@ -14,7 +14,7 @@ MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/
+ LINK_SKAS = -Wl,-rpath,/lib 
+ LD_SCRIPT_SKAS = dyn.lds.s
+ 
+-GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+ 
+-$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
+-	$(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
++$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
++	$(call descend,$(ARCH_DIR)/kernel/skas,$@)
+--- linux-2.6.0-test6/arch/um/os-Linux/drivers/tuntap_user.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/um/os-Linux/drivers/tuntap_user.c	2003-10-05 00:34:32.000000000 -0700
+@@ -142,7 +142,7 @@ static int tuntap_open(void *data)
+ 			return(-errno);
+ 		}
+ 		memset(&ifr, 0, sizeof(ifr));
+-		ifr.ifr_flags = IFF_TAP;
++		ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 		strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
+ 		if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ 			printk("TUNSETIFF failed, errno = %d", errno);
+--- linux-2.6.0-test6/arch/um/os-Linux/file.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/um/os-Linux/file.c	2003-10-05 00:34:32.000000000 -0700
+@@ -315,7 +315,7 @@ int os_rcv_fd(int fd, int *helper_pid_ou
+ 	return(new);
+ }
+ 
+-int create_unix_socket(char *file, int len)
++int create_unix_socket(char *file, int len, int close_on_exec)
+ {
+ 	struct sockaddr_un addr;
+ 	int sock, err;
+@@ -327,6 +327,10 @@ int create_unix_socket(char *file, int l
+ 		return(-errno);
+ 	}
+ 
++	if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
++		printk("create_unix_socket : Setting FD_CLOEXEC failed, "
++		       "errno = %d", errno);
++
+ 	addr.sun_family = AF_UNIX;
+ 
+ 	/* XXX Be more careful about overflow */
+@@ -342,6 +346,37 @@ int create_unix_socket(char *file, int l
+ 	return(sock);
+ }
+ 
++void os_flush_stdout(void)
++{
++	fflush(stdout);
++}
++
++int os_lock_file(int fd, int excl)
++{
++	int type = excl ? F_WRLCK : F_RDLCK;
++	struct flock lock = ((struct flock) { .l_type	= type,
++					      .l_whence	= SEEK_SET,
++					      .l_start	= 0,
++					      .l_len	= 0 } );
++	int err, save;
++
++	err = fcntl(fd, F_SETLK, &lock);
++	if(!err)
++		goto out;
++
++	save = -errno;
++	err = fcntl(fd, F_GETLK, &lock);
++	if(err){
++		err = -errno;
++		goto out;
++	}
++	
++	printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
++	err = save;
++ out:
++	return(err);
++}
++
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+--- linux-2.6.0-test6/arch/um/sys-i386/bugs.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/arch/um/sys-i386/bugs.c	2003-10-05 00:34:32.000000000 -0700
+@@ -8,6 +8,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <sys/signal.h>
++#include <asm/ldt.h>
+ #include "kern_util.h"
+ #include "user.h"
+ #include "sysdep/ptrace.h"
+@@ -16,8 +17,8 @@
+ #define MAXTOKEN 64
+ 
+ /* Set during early boot */
+-int cpu_has_cmov = 1;
+-int cpu_has_xmm = 0;
++int host_has_cmov = 1;
++int host_has_xmm = 0;
+ 
+ static char token(int fd, char *buf, int len, char stop)
+ {
+@@ -104,6 +105,25 @@ static int check_cpu_feature(char *featu
+ 	return(1);
+ }
+ 
++static void disable_lcall(void)
++{
++	struct modify_ldt_ldt_s ldt;
++	int err;
++
++	bzero(&ldt, sizeof(ldt));
++	ldt.entry_number = 7;
++	ldt.base_addr = 0;
++	ldt.limit = 0;
++	err = modify_ldt(1, &ldt, sizeof(ldt));
++	if(err)
++		printk("Failed to disable lcall7 - errno = %d\n", errno);
++}
++
++void arch_init_thread(void)
++{
++	disable_lcall();
++}
++
+ void arch_check_bugs(void)
+ {
+ 	int have_it;
+@@ -113,8 +133,8 @@ void arch_check_bugs(void)
+ 		       "checks\n");
+ 		return;
+ 	}
+-	if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
+-	if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
++	if(check_cpu_feature("cmov", &have_it)) host_has_cmov = have_it;
++	if(check_cpu_feature("xmm", &have_it)) host_has_xmm = have_it;
+ }
+ 
+ int arch_handle_signal(int sig, union uml_pt_regs *regs)
+@@ -130,18 +150,18 @@ int arch_handle_signal(int sig, union um
+ 	if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
+ 		return(0);
+ 
+-	if(cpu_has_cmov == 0)
++	if(host_has_cmov == 0)
+ 		panic("SIGILL caused by cmov, which this processor doesn't "
+ 		      "implement, boot a filesystem compiled for older "
+ 		      "processors");
+-	else if(cpu_has_cmov == 1)
++	else if(host_has_cmov == 1)
+ 		panic("SIGILL caused by cmov, which this processor claims to "
+ 		      "implement");
+-	else if(cpu_has_cmov == -1)
++	else if(host_has_cmov == -1)
+ 		panic("SIGILL caused by cmov, couldn't tell if this processor "
+ 		      "implements it, boot a filesystem compiled for older "
+ 		      "processors");
+-	else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
++	else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
+ 	return(0);
+ }
+ 
+--- linux-2.6.0-test6/arch/um/sys-i386/Makefile	2003-06-14 12:17:59.000000000 -0700
++++ 25/arch/um/sys-i386/Makefile	2003-10-05 00:34:32.000000000 -0700
+@@ -1,7 +1,8 @@
+-obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
+-	ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
++obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
++	ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
+ 
+ obj-$(CONFIG_HIGHMEM) += highmem.o
++obj-$(CONFIG_MODULES) += module.o
+ 
+ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+@@ -9,6 +10,8 @@ USER_OBJS := $(foreach file,$(USER_OBJS)
+ SYMLINKS = semaphore.c highmem.c module.c
+ SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
+ 
++clean-files := $(SYMLINKS)
++
+ semaphore.c-dir = kernel
+ highmem.c-dir = mm
+ module.c-dir = kernel
+@@ -24,8 +27,7 @@ $(USER_OBJS) : %.o: %.c
+ $(SYMLINKS): 
+ 	$(call make_link,$@)
+ 
+-clean:
+-	$(MAKE) -C util clean
++subdir- := util
+ 
+ fastdep:
+ 
+--- linux-2.6.0-test6/arch/um/uml.lds.S	2003-06-14 12:18:09.000000000 -0700
++++ 25/arch/um/uml.lds.S	2003-10-05 00:34:32.000000000 -0700
+@@ -26,7 +26,11 @@ SECTIONS
+   . = ALIGN(4096);		/* Init code and data */
+   _stext = .;
+   __init_begin = .;
+-  .text.init : { *(.text.init) }
++  .init.text : { 
++	_sinittext = .;
++	*(.init.text)
++	_einittext = .;
++  }
+   . = ALIGN(4096);
+   .text      :
+   {
+@@ -38,7 +42,7 @@ SECTIONS
+ 
+   #include "asm/common.lds.S"
+ 
+-  .data.init : { *(.data.init) }
++  init.data : { *(init.data) }
+   .data    :
+   {
+     . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
+--- linux-2.6.0-test6/arch/um/util/mk_constants_kern.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/arch/um/util/mk_constants_kern.c	2003-10-05 00:34:32.000000000 -0700
+@@ -1,5 +1,6 @@
+ #include "linux/kernel.h"
+ #include "linux/stringify.h"
++#include "linux/time.h"
+ #include "asm/page.h"
+ 
+ extern void print_head(void);
+@@ -11,6 +12,7 @@ int main(int argc, char **argv)
+ {
+   print_head();
+   print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
++
+   print_constant_str("UM_KERN_EMERG", KERN_EMERG);
+   print_constant_str("UM_KERN_ALERT", KERN_ALERT);
+   print_constant_str("UM_KERN_CRIT", KERN_CRIT);
+@@ -19,6 +21,8 @@ int main(int argc, char **argv)
+   print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
+   print_constant_str("UM_KERN_INFO", KERN_INFO);
+   print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
++
++  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
+   print_tail();
+   return(0);
+ }
+--- linux-2.6.0-test6/arch/x86_64/boot/compressed/head.S	2003-06-26 22:07:24.000000000 -0700
++++ 25/arch/x86_64/boot/compressed/head.S	2003-10-05 00:33:43.000000000 -0700
+@@ -26,6 +26,7 @@
+ .code32
+ .text
+ 
++#define IN_BOOTLOADER
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+ 
+--- linux-2.6.0-test6/arch/x86_64/boot/compressed/misc.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/x86_64/boot/compressed/misc.c	2003-10-05 00:33:43.000000000 -0700
+@@ -9,6 +9,7 @@
+  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+  */
+ 
++#define IN_BOOTLOADER
+ #include "miscsetup.h"
+ #include <asm/io.h>
+ 
+--- linux-2.6.0-test6/arch/x86_64/ia32/ia32_binfmt.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/x86_64/ia32/ia32_binfmt.c	2003-10-05 00:33:23.000000000 -0700
+@@ -82,9 +82,12 @@ do {									      \
+ 	int i;								      \
+ 	Elf32_Off ofs = 0;						      \
+ 	for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {		      \
+-		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
++		struct elf32_phdr phdr = vsyscall_phdrs[i];		      \
+ 		if (phdr.p_type == PT_LOAD) {				      \
++			BUG_ON(ofs != 0);				      \
+ 			ofs = phdr.p_offset = offset;			      \
++			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);	      \
++			phdr.p_filesz = phdr.p_memsz;			      \
+ 			offset += phdr.p_filesz;			      \
+ 		}							      \
+ 		else							      \
+@@ -99,10 +102,10 @@ do {									      \
+ 		(const struct elf32_phdr *) (VSYSCALL32_BASE		      \
+ 					   + VSYSCALL32_EHDR->e_phoff);	      \
+ 	int i;								      \
+-	for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {		      \
++	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+ 		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
+ 			DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,	      \
+-				   vsyscall_phdrs[i].p_filesz);		      \
++				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
+ 	}								      \
+ } while (0)
+ 
+--- linux-2.6.0-test6/arch/x86_64/ia32/ia32_ioctl.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/x86_64/ia32/ia32_ioctl.c	2003-10-05 00:34:44.000000000 -0700
+@@ -38,87 +38,6 @@ static int tiocgdev(unsigned fd, unsigne
+ 	return put_user(new_encode_dev(tty_devnum(real_tty)), ptr); 
+ } 
+ 
+-
+-struct raw32_config_request 
+-{
+-	compat_int_t	raw_minor;
+-	__u64	block_major;
+-	__u64	block_minor;
+-} __attribute__((packed));
+-
+-static int raw_ioctl(unsigned fd, unsigned cmd,  void *ptr) 
+-{ 
+-	int ret;
+-	switch (cmd) { 
+-	case RAW_SETBIND:
+-	case RAW_GETBIND: {
+-		struct raw_config_request req; 
+-		struct raw32_config_request *user_req = ptr;
+-		mm_segment_t oldfs = get_fs(); 
+-
+-		if (get_user(req.raw_minor, &user_req->raw_minor) ||
+-		    get_user(req.block_major, &user_req->block_major) ||
+-		    get_user(req.block_minor, &user_req->block_minor))
+-			return -EFAULT;
+-		set_fs(KERNEL_DS); 
+-		ret = sys_ioctl(fd,cmd,(unsigned long)&req); 
+-		set_fs(oldfs); 
+-		break;
+-	}
+-	default:
+-		ret = sys_ioctl(fd,cmd,(unsigned long)ptr);
+-		break;
+-	} 
+-	return ret; 		
+-} 
+-
+-
+-#define REISERFS_IOC_UNPACK32               _IOW(0xCD,1,int)
+-
+-static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr) 
+-{ 
+-	if (cmd == REISERFS_IOC_UNPACK32) 
+-		cmd = REISERFS_IOC_UNPACK; 
+-	return sys_ioctl(fd,cmd,ptr); 
+-} 
+-
+-struct dirent32 {
+-	compat_int_t	d_ino;
+-	compat_off_t	d_off;
+-	unsigned short	d_reclen;
+-	char		d_name[256]; /* We must not include limits.h! */
+-};
+-
+-#define	VFAT_IOCTL_READDIR_BOTH32	_IOR('r', 1, struct dirent32 [2])
+-#define	VFAT_IOCTL_READDIR_SHORT32	_IOR('r', 2, struct dirent32 [2])
+-
+-static int put_dirent32(struct dirent *src, struct dirent32 *dst)
+-{
+-	int ret; 
+-	ret = put_user(src->d_ino, &dst->d_ino); 
+-	ret |= __put_user(src->d_off, &dst->d_off); 
+-	ret |= __put_user(src->d_reclen, &dst->d_reclen); 
+-	if (__copy_to_user(&dst->d_name, src->d_name, src->d_reclen))
+-		ret |= -EFAULT;
+-	return ret;
+-} 
+-
+-static int vfat_ioctl32(unsigned fd, unsigned cmd,  void *ptr) 
+-{
+-	int ret;
+-	mm_segment_t oldfs = get_fs();
+-	struct dirent d[2]; 
+-
+-	set_fs(KERNEL_DS);
+-	ret = sys_ioctl(fd,cmd,(unsigned long)&d); 
+-	set_fs(oldfs); 
+-	if (!ret) { 
+-		ret |= put_dirent32(&d[0], (struct dirent32 *)ptr); 
+-		ret |= put_dirent32(&d[1], ((struct dirent32 *)ptr) + 1); 
+-	}
+-	return ret; 
+-} 
+-
+ #define RTC_IRQP_READ32	_IOR('p', 0x0b, unsigned int)	 /* Read IRQ rate   */
+ #define RTC_IRQP_SET32	_IOW('p', 0x0c, unsigned int)	 /* Set IRQ rate    */
+ #define RTC_EPOCH_READ32	_IOR('p', 0x0d, unsigned)	 /* Read epoch      */
+@@ -158,436 +77,6 @@ static int rtc32_ioctl(unsigned fd, unsi
+ 	return sys_ioctl(fd,cmd,arg); 
+ } 
+ 
+-struct serial_struct32 {
+-	compat_int_t	type;
+-	compat_int_t	line;
+-	compat_uint_t	port;
+-	compat_int_t	irq;
+-	compat_int_t	flags;
+-	compat_int_t	xmit_fifo_size;
+-	compat_int_t	custom_divisor;
+-	compat_int_t	baud_base;
+-	unsigned short	close_delay;
+-	char	io_type;
+-	char	reserved_char[1];
+-	compat_int_t	hub6;
+-	unsigned short	closing_wait; /* time to wait before closing */
+-	unsigned short	closing_wait2; /* no longer used... */
+-	compat_uint_t	iomem_base;
+-	unsigned short	iomem_reg_shift;
+-	unsigned int	port_high;
+-	compat_int_t	reserved[1];
+-};
+-
+-static int serial_struct_ioctl(unsigned fd, unsigned cmd,  void *ptr) 
+-{
+-	typedef struct serial_struct SS;
+-	struct serial_struct32 *ss32 = ptr; 
+-	int err;
+-	struct serial_struct ss; 
+-	mm_segment_t oldseg = get_fs(); 
+-	if (cmd == TIOCSSERIAL) { 
+-		if (copy_from_user(&ss, ss32, sizeof(struct serial_struct32)))
+-			return -EFAULT;
+-		memmove(&ss.iomem_reg_shift, ((char*)&ss.iomem_base)+4, 
+-			sizeof(SS)-offsetof(SS,iomem_reg_shift)); 
+-		ss.iomem_base = (void *)((unsigned long)ss.iomem_base & 0xffffffff);
+-	}
+-	set_fs(KERNEL_DS);
+-		err = sys_ioctl(fd,cmd,(unsigned long)(&ss)); 
+-	set_fs(oldseg);
+-	if (cmd == TIOCGSERIAL && err >= 0) { 
+-		if (__copy_to_user(ss32,&ss,offsetof(SS,iomem_base)) ||
+-		    __put_user((unsigned long)ss.iomem_base  >> 32 ? 
+-			       0xffffffff : (unsigned)(unsigned long)ss.iomem_base,
+-			       &ss32->iomem_base) ||
+-		    __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
+-		    __put_user(ss.port_high, &ss32->port_high))
+-			return -EFAULT;
+-	} 
+-	return err;	
+-}
+-
+-
+-
+-struct usbdevfs_ctrltransfer32 {
+-	u8 bRequestType;
+-	u8 bRequest;
+-	u16 wValue;
+-	u16 wIndex;
+-	u16 wLength;
+-	u32 timeout;  /* in milliseconds */
+-	compat_caddr_t data;
+-};
+-
+-#define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+-
+-static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_ctrltransfer kctrl;
+-	struct usbdevfs_ctrltransfer32 *uctrl;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	int err;
+-
+-	uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+-
+-	if (copy_from_user(&kctrl, uctrl,
+-			   (sizeof(struct usbdevfs_ctrltransfer) -
+-			    sizeof(void *))))
+-		return -EFAULT;
+-
+-	if (get_user(udata, &uctrl->data))
+-		return -EFAULT;
+-	uptr = compat_ptr(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kctrl.wLength > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *)__get_free_page(GFP_KERNEL);
+-
+-	if ((kctrl.bRequestType & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kctrl.wLength))
+-			goto out;
+-	}
+-
+-	kctrl.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kctrl.bRequestType & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kctrl.wLength))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-struct usbdevfs_bulktransfer32 {
+-	compat_uint_t ep;
+-	compat_uint_t len;
+-	compat_uint_t timeout; /* in milliseconds */
+-	compat_caddr_t data;
+-};
+-
+-#define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+-
+-static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_bulktransfer kbulk;
+-	struct usbdevfs_bulktransfer32 *ubulk;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	int err;
+-
+-	ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+-
+-	if (get_user(kbulk.ep, &ubulk->ep) ||
+-	    get_user(kbulk.len, &ubulk->len) ||
+-	    get_user(kbulk.timeout, &ubulk->timeout) ||
+-	    get_user(udata, &ubulk->data))
+-		return -EFAULT;
+-
+-	uptr = compat_ptr(udata);
+-
+-	/* In usbdevice_fs, it limits the control buffer to a page,
+-	 * for simplicity so do we.
+-	 */
+-	if (!uptr || kbulk.len > PAGE_SIZE)
+-		return -EINVAL;
+-
+-	kptr = (void *) __get_free_page(GFP_KERNEL);
+-
+-	if ((kbulk.ep & 0x80) == 0) {
+-		err = -EFAULT;
+-		if (copy_from_user(kptr, uptr, kbulk.len))
+-			goto out;
+-	}
+-
+-	kbulk.data = kptr;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    ((kbulk.ep & 0x80) != 0)) {
+-		if (copy_to_user(uptr, kptr, kbulk.len))
+-			err = -EFAULT;
+-	}
+-
+-out:
+-	free_page((unsigned long) kptr);
+-	return err;
+-}
+-
+-/* This needs more work before we can enable it.  Unfortunately
+- * because of the fancy asynchronous way URB status/error is written
+- * back to userspace, we'll need to fiddle with USB devio internals
+- * and/or reimplement entirely the frontend of it ourselves. -DaveM
+- *
+- * The issue is:
+- *
+- *	When an URB is submitted via usbdevicefs it is put onto an
+- *	asynchronous queue.  When the URB completes, it may be reaped
+- *	via another ioctl.  During this reaping the status is written
+- *	back to userspace along with the length of the transfer.
+- *
+- *	We must translate into 64-bit kernel types so we pass in a kernel
+- *	space copy of the usbdevfs_urb structure.  This would mean that we
+- *	must do something to deal with the async entry reaping.  First we
+- *	have to deal somehow with this transitory memory we've allocated.
+- *	This is problematic since there are many call sites from which the
+- *	async entries can be destroyed (and thus when we'd need to free up
+- *	this kernel memory).  One of which is the close() op of usbdevicefs.
+- *	To handle that we'd need to make our own file_operations struct which
+- *	overrides usbdevicefs's release op with our own which runs usbdevicefs's
+- *	real release op then frees up the kernel memory.
+- *
+- *	But how to keep track of these kernel buffers?  We'd need to either
+- *	keep track of them in some table _or_ know about usbdevicefs internals
+- *	(ie. the exact layout of its file private, which is actually defined
+- *	in linux/usbdevice_fs.h, the layout of the async queues are private to
+- *	devio.c)
+- *
+- * There is one possible other solution I considered, also involving knowledge
+- * of usbdevicefs internals:
+- *
+- *	After an URB is submitted, we "fix up" the address back to the user
+- *	space one.  This would work if the status/length fields written back
+- *	by the async URB completion lines up perfectly in the 32-bit type with
+- *	the 64-bit kernel type.  Unfortunately, it does not because the iso
+- *	frame descriptors, at the end of the struct, can be written back.
+- *
+- * I think we'll just need to simply duplicate the devio URB engine here.
+- */
+-#if 0
+-struct usbdevfs_urb32 {
+-	unsigned char type;
+-	unsigned char endpoint;
+-	compat_int_t status;
+-	compat_uint_t flags;
+-	compat_caddr_t buffer;
+-	compat_int_t buffer_length;
+-	compat_int_t actual_length;
+-	compat_int_t start_frame;
+-	compat_int_t number_of_packets;
+-	compat_int_t error_count;
+-	compat_uint_t signr;
+-	compat_caddr_t usercontext; /* unused */
+-	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+-};
+-
+-#define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
+-
+-static int get_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (get_user(kurb->type, &uurb->type) ||
+-	    __get_user(kurb->endpoint, &uurb->endpoint) ||
+-	    __get_user(kurb->status, &uurb->status) ||
+-	    __get_user(kurb->flags, &uurb->flags) ||
+-	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+-	    __get_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __get_user(kurb->start_frame, &uurb->start_frame) ||
+-	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+-	    __get_user(kurb->error_count, &uurb->error_count) ||
+-	    __get_user(kurb->signr, &uurb->signr))
+-		return -EFAULT;
+-
+-	kurb->usercontext = 0; /* unused currently */
+-
+-	return 0;
+-}
+-
+-/* Just put back the values which usbdevfs actually changes. */
+-static int put_urb32(struct usbdevfs_urb *kurb,
+-		     struct usbdevfs_urb32 *uurb)
+-{
+-	if (put_user(kurb->status, &uurb->status) ||
+-	    __put_user(kurb->actual_length, &uurb->actual_length) ||
+-	    __put_user(kurb->error_count, &uurb->error_count))
+-		return -EFAULT;
+-
+-	if (kurb->number_of_packets != 0) {
+-		int i;
+-
+-		for (i = 0; i < kurb->number_of_packets; i++) {
+-			if (__put_user(kurb->iso_frame_desc[i].actual_length,
+-				       &uurb->iso_frame_desc[i].actual_length) ||
+-			    __put_user(kurb->iso_frame_desc[i].status,
+-				       &uurb->iso_frame_desc[i].status))
+-				return -EFAULT;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+-			       struct usbdevfs_urb32 *uurb)
+-{
+-	unsigned int totlen;
+-	int i;
+-
+-	if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+-		kurb->number_of_packets = 0;
+-		return 0;
+-	}
+-
+-	if (kurb->number_of_packets < 1 ||
+-	    kurb->number_of_packets > 128)
+-		return -EINVAL;
+-
+-	if (copy_from_user(&kurb->iso_frame_desc[0],
+-			   &uurb->iso_frame_desc[0],
+-			   sizeof(struct usbdevfs_iso_packet_desc) *
+-			   kurb->number_of_packets))
+-		return -EFAULT;
+-
+-	totlen = 0;
+-	for (i = 0; i < kurb->number_of_packets; i++) {
+-		unsigned int this_len;
+-
+-		this_len = kurb->iso_frame_desc[i].length;
+-		if (this_len > 1023)
+-			return -EINVAL;
+-
+-		totlen += this_len;
+-	}
+-
+-	if (totlen > 32768)
+-		return -EINVAL;
+-
+-	kurb->buffer_length = totlen;
+-
+-	return 0;
+-}
+-
+-static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_urb *kurb;
+-	struct usbdevfs_urb32 *uurb;
+-	mm_segment_t old_fs;
+-	__u32 udata;
+-	void *uptr, *kptr;
+-	unsigned int buflen;
+-	int err;
+-
+-	uurb = (struct usbdevfs_urb32 *) arg;
+-
+-	err = -ENOMEM;
+-	kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+-		       (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+-		       GFP_KERNEL);
+-	if (!kurb)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (get_urb32(kurb, uurb))
+-		goto out;
+-
+-	err = get_urb32_isoframes(kurb, uurb);
+-	if (err)
+-		goto out;
+-
+-	err = -EFAULT;
+-	if (__get_user(udata, &uurb->buffer))
+-		goto out;
+-	uptr = compat_ptr(udata);
+-
+-	buflen = kurb->buffer_length;
+-	err = verify_area(VERIFY_WRITE, uptr, buflen);
+-	if (err) 
+-		goto out;
+-
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+-	set_fs(old_fs);
+-
+-	if (err >= 0) {
+-		/* RED-PEN Shit, this doesn't work for async URBs :-( XXX */
+-		if (put_urb32(kurb, uurb)) {
+-			err = -EFAULT;
+-		}
+-	}
+-
+-out:
+-	kfree(kurb);
+-	return err;
+-}
+-#endif
+-
+-#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
+-#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
+-
+-static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	mm_segment_t old_fs;
+-	void *kptr;
+-	int err;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd,
+-			(cmd == USBDEVFS_REAPURB32 ?
+-			 USBDEVFS_REAPURB :
+-			 USBDEVFS_REAPURBNDELAY),
+-			(unsigned long) &kptr);
+-	set_fs(old_fs);
+-
+-	if (err >= 0 &&
+-	    put_user((u32)(u64)kptr, (u32 *)arg))
+-		err = -EFAULT;
+-
+-	return err;
+-}
+-
+-struct usbdevfs_disconnectsignal32 {
+-	compat_int_t signr;
+-	compat_caddr_t context;
+-};
+-
+-#define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+-
+-static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+-{
+-	struct usbdevfs_disconnectsignal kdis;
+-	struct usbdevfs_disconnectsignal32 *udis;
+-	mm_segment_t old_fs;
+-	u32 uctx;
+-	int err;
+-
+-	udis = (struct usbdevfs_disconnectsignal32 *) arg;
+-
+-	if (get_user(kdis.signr, &udis->signr) ||
+-	    __get_user(uctx, &udis->context))
+-		return -EFAULT;
+-
+-	kdis.context = (void *) (long)uctx;
+-
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+-	set_fs(old_fs);
+-
+-	return err;
+-}
+ /* /proc/mtrr ioctls */
+ 
+ 
+@@ -726,27 +215,12 @@ COMPATIBLE_IOCTL(FIOQSIZE)
+ 
+ /* And these ioctls need translation */
+ HANDLE_IOCTL(TIOCGDEV, tiocgdev)
+-HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
+-HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
+-/* Raw devices */
+-HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
+ /* realtime device */
+ HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
+ HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
+ HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
+ HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
+ HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
+-HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
+-/* VFAT */
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
+-
+-HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
+-HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
+-/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+-HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
+-HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+ /* take care of sizeof(sizeof()) breakage */
+ /* mtrr */
+ HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
+--- linux-2.6.0-test6/arch/x86_64/kernel/i387.c	2003-06-14 12:18:05.000000000 -0700
++++ 25/arch/x86_64/kernel/i387.c	2003-10-05 00:33:23.000000000 -0700
+@@ -138,12 +138,3 @@ int dump_task_fpu(struct task_struct *ts
+ }
+ 	return fpvalid;
+ }
+-
+-#ifdef CONFIG_SMP
+-void dump_smp_unlazy_fpu(void)
+-{
+-	unlazy_fpu(current);
+-	return;
+-}
+-#endif
+-
+--- linux-2.6.0-test6/arch/x86_64/mm/ioremap.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/arch/x86_64/mm/ioremap.c	2003-10-05 00:33:23.000000000 -0700
+@@ -159,7 +159,7 @@ void * __ioremap(unsigned long phys_addr
+ 	if (!area)
+ 		return NULL;
+ 	addr = area->addr;
+-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
++	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vunmap(addr);
+ 		return NULL;
+ 	}
+--- linux-2.6.0-test6/CREDITS	2003-09-27 18:57:43.000000000 -0700
++++ 25/CREDITS	2003-10-05 00:33:23.000000000 -0700
+@@ -1459,6 +1459,13 @@ S: Ballinagard
+ S: Roscommon
+ S: Ireland
+ 
++N: Michael Hunold
++E: michael@mihu.de
++W: http://www.mihu.de/linux/
++D: Generic saa7146 video4linux-2 driver core,
++D: Driver for the "Multimedia eXtension Board", "dpc7146",
++D: "Hexium Orion", "Hexium Gemini"
++
+ N: Miguel de Icaza Amozurrutia
+ E: miguel@nuclecu.unam.mx
+ D: Linux/SPARC team, Midnight Commander maintainer
+--- linux-2.6.0-test6/Documentation/cachetlb.txt	2003-06-14 12:18:07.000000000 -0700
++++ 25/Documentation/cachetlb.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -59,9 +59,9 @@ changes occur:
+ 	address translations from the TLB.  After running, this
+ 	interface must make sure that any previous page table
+ 	modifications for the address space 'vma->vm_mm' in the range
+-	'start' to 'end' will be visible to the cpu.  That is, after
++	'start' to 'end-1' will be visible to the cpu.  That is, after
+ 	running, here will be no entries in the TLB for 'mm' for
+-	virtual addresses in the range 'start' to 'end'.
++	virtual addresses in the range 'start' to 'end-1'.
+ 
+ 	The "vma" is the backing store being used for the region.
+ 	Primarily, this is used for munmap() type operations.
+@@ -100,7 +100,7 @@ changes occur:
+ 			   unsigned long start, unsigned long end)
+ 
+    The software page tables for address space 'mm' for virtual
+-   addresses in the range 'start' to 'end' are being torn down.
++   addresses in the range 'start' to 'end-1' are being torn down.
+ 
+    Some platforms cache the lowest level of the software page tables
+    in a linear virtually mapped array, to make TLB miss processing
+@@ -165,15 +165,7 @@ and have no dependency on translation in
+ 
+ Here are the routines, one by one:
+ 
+-1) void flush_cache_all(void)
+-
+-	The most severe flush of all.  After this interface runs,
+-	the entire cpu cache is flushed.
+-
+-	This is usually invoked when the kernel page tables are
+-	changed, since such translations are "global" in nature.
+-
+-2) void flush_cache_mm(struct mm_struct *mm)
++1) void flush_cache_mm(struct mm_struct *mm)
+ 
+ 	This interface flushes an entire user address space from
+ 	the caches.  That is, after running, there will be no cache
+@@ -183,13 +175,13 @@ Here are the routines, one by one:
+ 	page table operations such as what happens during
+ 	fork, exit, and exec.
+ 
+-3) void flush_cache_range(struct vm_area_struct *vma,
++2) void flush_cache_range(struct vm_area_struct *vma,
+ 			  unsigned long start, unsigned long end)
+ 
+ 	Here we are flushing a specific range of (user) virtual
+ 	addresses from the cache.  After running, there will be no
+ 	entries in the cache for 'vma->vm_mm' for virtual addresses in
+-	the range 'start' to 'end'.
++	the range 'start' to 'end-1'.
+ 
+ 	The "vma" is the backing store being used for the region.
+ 	Primarily, this is used for munmap() type operations.
+@@ -200,7 +192,7 @@ Here are the routines, one by one:
+ 	call flush_cache_page (see below) for each entry which may be
+ 	modified.
+ 
+-4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
++3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
+ 
+ 	This time we need to remove a PAGE_SIZE sized range
+ 	from the cache.  The 'vma' is the backing structure used by
+@@ -215,6 +207,30 @@ Here are the routines, one by one:
+ 
+ 	This is used primarily during fault processing.
+ 
++4) void flush_cache_kmaps(void)
++
++	This routine need only be implemented if the platform utilizes
++	highmem.  It will be called right before all of the kmaps
++	are invalidated.
++
++	After running, there will be no entries in the cache for
++	the kernel virtual address range PKMAP_ADDR(0) to
++	PKMAP_ADDR(LAST_PKMAP).
++
++	This routing should be implemented in asm/highmem.h
++
++5) void flush_cache_vmap(unsigned long start, unsigned long end)
++   void flush_cache_vunmap(unsigned long start, unsigned long end)
++
++	Here in these two interfaces we are flushing a specific range
++	of (kernel) virtual addresses from the cache.  After running,
++	there will be no entries in the cache for the kernel address
++	space for virtual addresses in the range 'start' to 'end-1'.
++
++	The first of these two routines is invoked after map_vm_area()
++	has installed the page table entries.  The second is invoked
++	before unmap_vm_area() deletes the page table entries.
++
+ There exists another whole class of cpu cache issues which currently
+ require a whole different set of interfaces to handle properly.
+ The biggest problem is that of virtual aliasing in the data cache
+@@ -317,6 +333,26 @@ maps this page at its virtual address.
+ 			dirty.  Again, see sparc64 for examples of how
+ 			to deal with this.
+ 
++  void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
++                         unsigned long user_vaddr,
++                         void *dst, void *src, int len)
++  void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
++                           unsigned long user_vaddr,
++                           void *dst, void *src, int len)
++	When the kernel needs to copy arbitrary data in and out
++	of arbitrary user pages (f.e. for ptrace()) it will use
++	these two routines.
++
++	The page has been kmap()'d, and flush_cache_page() has
++	just been called for the user mapping of this page (if
++	necessary).
++
++	Any necessary cache flushing or other coherency operations
++	that need to occur should happen here.  If the processor's
++	instruction cache does not snoop cpu stores, it is very
++	likely that you will need to flush the instruction cache
++	for copy_to_user_page().
++
+   void flush_icache_range(unsigned long start, unsigned long end)
+   	When the kernel stores into addresses that it will execute
+ 	out of (eg when loading modules), this function is called.
+@@ -324,17 +360,6 @@ maps this page at its virtual address.
+ 	If the icache does not snoop stores then this routine will need
+ 	to flush it.
+ 
+-  void flush_icache_user_range(struct vm_area_struct *vma,
+-			struct page *page, unsigned long addr, int len)
+-	This is called when the kernel stores into addresses that are
+-	part of the address space of a user process (which may be some
+-	other process than the current process).  The addr argument
+-	gives the virtual address in that process's address space,
+-	page is the page which is being modified, and len indicates
+-	how many bytes have been modified.  The modified region must
+-	not cross a page boundary.  Currently this is only called from
+-	kernel/ptrace.c.
+-
+   void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+ 	All the functionality of flush_icache_page can be implemented in
+ 	flush_dcache_page and update_mmu_cache. In 2.7 the hope is to
+--- linux-2.6.0-test6/Documentation/cpu-freq/user-guide.txt	2003-08-08 22:55:10.000000000 -0700
++++ 25/Documentation/cpu-freq/user-guide.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -57,6 +57,8 @@ AMD mobile K6-2+
+ AMD mobile K6-3+
+ AMD mobile Duron
+ AMD mobile Athlon
++AMD Opteron
++AMD Athlon 64
+ Cyrix Media GXm
+ Intel mobile PIII and Intel mobile PIII-M on certain chipsets
+ Intel Pentium 4, Intel Xeon
+--- linux-2.6.0-test6/Documentation/crypto/api-intro.txt	2003-08-22 19:23:39.000000000 -0700
++++ 25/Documentation/crypto/api-intro.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -126,7 +126,7 @@ might already be working on.
+ BUGS
+ 
+ Send bug reports to:
+-James Morris <jmorris@intercode.com.au>
++James Morris <jmorris@redhat.com>
+ Cc: David S. Miller <davem@redhat.com>
+ 
+ 
+@@ -220,5 +220,5 @@ CAST5 algorithm contributors:
+ Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
+ 
+ Please send any credits updates or corrections to:
+-James Morris <jmorris@intercode.com.au>
++James Morris <jmorris@redhat.com>
+ 
+--- linux-2.6.0-test6/Documentation/DocBook/kernel-api.tmpl	2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/DocBook/kernel-api.tmpl	2003-10-05 00:33:23.000000000 -0700
+@@ -318,6 +318,5 @@ X!Idrivers/video/console/fonts.c
+ <!-- Needs ksyms to list additional exported symbols, but no specific doc.
+      docproc do not care about sgml commants.
+ !Dkernel/ksyms.c
+-!Dnet/netsyms.c
+ -->
+ </book>
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/fb/neofb.txt	2003-10-05 00:34:22.000000000 -0700
+@@ -0,0 +1,27 @@
++the neofb framebuffer driver supports the following Neomagic chipsets:
++
++NM2070 MagicGraph 128
++NM2090 MagicGraph 128V
++NM2093 MagicGraph 128ZV
++NM2097 MagicGraph 128ZV+
++NM2160 MagicGraph 128XD
++NM2200 MagicGraph 256AV
++NM2230 MagicGraph 256AV+
++NM2360 MagicGraph 256ZX
++NM2380 MagicGraph 256XL+
++
++with the following options:
++
++disabled	Disable this driver's initialization.
++internal	Enable output on internal LCD Display.
++external	Enable output on external CRT.
++nostretch	Disable stretching of modes smaller than LCD.
++nopciburst	Disable PCI burst mode.
++libretto	Force Libretto 100/110 800x480 LCD.
++picturebook	Force Picturebook 1024x480 LCD.
++
++at the boot prompt:
++	video=neofb:picturebook
++
++as a module:
++	modprobe neofb picturebook=1
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/andthen	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,100 @@
++
++define	set_andthen
++	set var $thp=0
++	set var $thp=(struct kgdb_and_then_struct *)&kgdb_data[0]
++	set var $at_size = (sizeof kgdb_data)/(sizeof *$thp)
++	set var $at_oc=kgdb_and_then_count
++	set var $at_cc=$at_oc
++end
++
++define andthen_next
++	set var $at_cc=$arg0
++end
++
++define andthen
++	andthen_set_edge
++	if ($at_cc >= $at_oc)
++		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
++	else
++		printf "%d: ",$at_cc
++		output *($thp+($at_cc++ % $at_size ))
++		printf "\n"
++	end
++end
++define andthen_set_edge
++	set var $at_oc=kgdb_and_then_count
++	set var $at_low = $at_oc - $at_size
++	if ($at_low < 0 )
++		set var $at_low = 0
++	end
++	if (( $at_cc > $at_oc) || ($at_cc < $at_low))
++		printf "Count outside of window, setting count to "
++		if ($at_cc >= $at_oc)
++			set var $at_cc = $at_oc
++		else
++			set var $at_cc = $at_low
++		end
++		printf "%d\n",$at_cc
++	end
++end
++
++define beforethat
++	andthen_set_edge
++	if ($at_cc <= $at_low)
++		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
++	else
++		printf "%d: ",$at_cc-1
++		output *($thp+(--$at_cc % $at_size ))
++		printf "\n"
++	end
++end
++
++document andthen_next
++	andthen_next <count>
++	.	sets the number of the event to display next. If this event
++	.	is not in the event pool, either andthen or beforethat will
++	.	correct it to the nearest event pool edge.  The event pool
++	.	ends at the last event recorded and begins <number of events>
++	.	prior to that.  If beforethat is used next, it will display
++	.	event <count> -1.
++.
++	andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++
++document andthen
++	andthen
++.	displays the next event in the list.  <set_andthen> sets up to display
++.	the oldest saved event first.
++.	<count> (optional) count of the event to display.
++.	note the number of events saved is specified at configure time.
++.	if events are saved between calls to andthen the index will change
++.	but the displayed event will be the next one (unless the event buffer
++.	is overrun).
++.
++.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document set_andthen
++	set_andthen
++.	sets up to use the <andthen> and <beforethat> commands.
++.		if you have defined your own struct, use the above and
++.		then enter the following:
++.		p $thp=(struct kgdb_and_then_structX *)&kgdb_data[0]
++.		where <kgdb_and_then_structX> is the name of your structure.
++.
++.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document beforethat
++	beforethat
++.	displays the next prior event in the list. <set_andthen> sets up to
++.	display the last occuring event first.
++.
++.	note the number of events saved is specified at configure time.
++.	if events are saved between calls to beforethat the index will change
++.	but the displayed event will be the next one (unless the event buffer
++.	is overrun).
++.
++.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/debug-nmi.txt	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,37 @@
++Subject: Debugging with NMI
++Date: Mon, 12 Jul 1999 11:28:31 -0500
++From: David Grothe <dave@gcom.com>
++Organization: Gcom, Inc
++To: David Grothe <dave@gcom.com>
++
++Kernel hackers:
++
++Maybe this is old hat, but it is new to me --
++
++On an ISA bus machine, if you short out the A1 and B1 pins of an ISA
++slot you will generate an NMI to the CPU.  This interrupts even a
++machine that is hung in a loop with interrupts disabled.  Used in
++conjunction with kgdb <
++ftp://ftp.gcom.com/pub/linux/src/kgdb-2.3.35/kgdb-2.3.35.tgz > you can
++gain debugger control of a machine that is hung in the kernel!  Even
++without kgdb the kernel will print a stack trace so you can find out
++where it was hung.
++
++The A1/B1 pins are directly opposite one another and the farthest pins
++towards the bracket end of the ISA bus socket.  You can stick a paper
++clip or multi-meter probe between them to short them out.
++
++I had a spare ISA bus to PC104 bus adapter around.  The PC104 end of the
++board consists of two rows of wire wrap pins.  So I wired a push button
++between the A1/B1 pins and now have an ISA board that I can stick into
++any ISA bus slot for debugger entry.
++
++Microsoft has a circuit diagram of a PCI card at
++http://www.microsoft.com/hwdev/DEBUGGING/DMPSW.HTM.  If you want to
++build one you will have to mail them and ask for the PAL equations.
++Nobody makes one comercially.
++
++[THIS TIP COMES WITH NO WARRANTY WHATSOEVER.  It works for me, but if
++your machine catches fire, it is your problem, not mine.]
++
++-- Dave (the kgdb guy)
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdb-globals.txt	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,71 @@
++Sender: akale@veritas.com
++Date: Fri, 23 Jun 2000 19:26:35 +0530
++From: "Amit S. Kale" <akale@veritas.com>
++Organization: Veritas Software (India)
++To: Dave Grothe <dave@gcom.com>, linux-kernel@vger.rutgers.edu
++CC: David Milburn <dmilburn@wirespeed.com>,
++        "Edouard G. Parmelan" <Edouard.Parmelan@quadratec.fr>,
++        ezannoni@cygnus.com, Keith Owens <kaos@ocs.com.au>
++Subject: Re: Module debugging using kgdb
++
++Dave Grothe wrote:
++>
++> Amit:
++>
++> There is a 2.4.0 version of kgdb on our ftp site:
++> ftp://ftp.gcom.com/pub/linux/src/kgdb.  I mirrored your version of gdb
++> and loadmodule.sh there.
++>
++> Have a look at the README file and see if I go it right.  If not, send
++> me some corrections and I will update it.
++>
++> Does your version of gdb solve the global variable problem?
++
++Yes.
++Thanks to Elena Zanoni, gdb (developement version) can now calculate
++correctly addresses  of dynamically loaded object files. I have not been
++following gdb developement for sometime and am not sure when symbol
++address calculation fix is going to appear in a gdb stable version.
++
++Elena, any idea when the fix will make it to a prebuilt gdb from a
++redhat release?
++
++For the time being I have built a gdb developement version. It can be
++used for module debugging with loadmodule.sh script.
++
++The problem with calculating of module addresses with previous versions
++of gdb was as follows:
++gdb did not use base address of a section while calculating address of
++a symbol in the section in an object file loaded via 'add-symbol-file'.
++It used address of .text segment instead. Due to this addresses of
++symbols in .data, .bss etc. (e.g. global variables) were calculated incorrectly.
++
++Above mentioned fix allow gdb to use base address of a segment while
++calculating address of a symbol in it. It adds a parameter '-s' to
++'add-symbol-file' command for specifying base address of a segment.
++
++loadmodule.sh script works as follows.
++
++1. Copy a module file to target machine.
++2. Load the module on the target machine using insmod with -m parameter.
++insmod produces a module load map which contains base addresses of all
++sections in the module and addresses of symbols in the module file.
++3. Find all sections and their base addresses in the module from
++the module map.
++4. Generate a script that loads the module file. The script uses
++'add-symbol-file' and specifies address of text segment followed by
++addresses of all segments in the module.
++
++Here is an example gdb script produced by loadmodule.sh script.
++
++add-symbol-file foo 0xd082c060 -s .text.lock 0xd08cbfb5
++-s .fixup 0xd08cfbdf -s .rodata 0xd08cfde0 -s __ex_table 0xd08e3b38
++-s .data 0xd08e3d00 -s .bss 0xd08ec8c0 -s __ksymtab 0xd08ee838
++
++With this command gdb can calculate addresses of symbols in ANY segment
++in a module file.
++
++Regards.
++--
++Amit Kale
++Veritas Software ( http://www.veritas.com )
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,14 @@
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400
++target remote /dev/ttyS0
++define si
++stepi
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
++end
++define ni
++nexti
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit.hw	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,117 @@
++
++#Using ia-32 hardware breakpoints.
++#
++#4 hardware breakpoints are available in ia-32 processors. These breakpoints
++#do not need code modification. They are set using debug registers.
++#
++#Each hardware breakpoint can be of one of the
++#three types: execution, write, access.
++#1. An Execution breakpoint is triggered when code at the breakpoint address is
++#executed.
++#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
++#at the breakpoint address is written.
++#3. An access breakpoint is triggered when memory location at the breakpoint
++#address is either read or written.
++#
++#As hardware breakpoints are available in limited number, use software
++#breakpoints ( br command in gdb ) instead of execution hardware breakpoints.
++#
++#Length of an access or a write breakpoint defines length of the datatype to
++#be watched. Length is 1 for char, 2 short , 3 int.
++#
++#For placing execution, write and access breakpoints, use commands
++#hwebrk, hwwbrk, hwabrk
++#To remove a breakpoint use hwrmbrk command.
++#
++#These commands take following types of arguments. For arguments associated
++#with each command, use help command.
++#1. breakpointno: 0 to 3
++#2. length: 1 to 3
++#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
++#
++#Use the command exinfo to find which hardware breakpoint occured.
++
++#hwebrk breakpointno address
++define hwebrk
++	maintenance packet Y$arg0,0,0,$arg1
++end
++document hwebrk
++	hwebrk <breakpointno> <address>
++	Places a hardware execution breakpoint
++	<breakpointno> = 0 - 3
++	<address> = Hex digits without leading "0x".
++end
++
++#hwwbrk breakpointno length address
++define hwwbrk
++	maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwwbrk
++	hwwbrk <breakpointno> <length> <address>
++	Places a hardware write breakpoint
++	<breakpointno> = 0 - 3
++	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++	<address> = Hex digits without leading "0x".
++end
++
++#hwabrk breakpointno length address
++define hwabrk
++	maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwabrk
++	hwabrk <breakpointno> <length> <address>
++	Places a hardware access breakpoint
++	<breakpointno> = 0 - 3
++	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++	<address> = Hex digits without leading "0x".
++end
++
++#hwrmbrk breakpointno
++define hwrmbrk
++	maintenance packet y$arg0
++end
++document hwrmbrk
++	hwrmbrk <breakpointno>
++	<breakpointno> = 0 - 3
++	Removes a hardware breakpoint
++end
++
++define reboot
++        maintenance packet r
++end
++#exinfo
++define exinfo
++	maintenance packet qE
++end
++document exinfo
++	exinfo
++	Gives information about a breakpoint.
++end
++define get_th
++	p $th=(struct thread_info *)((int)$esp & ~8191)
++end
++document get_th
++	get_tu
++	Gets and prints the current thread_info pointer, Defines th to be it.
++end
++define get_cu
++	p $cu=((struct thread_info *)((int)$esp & ~8191))->task
++end
++document get_cu
++	get_cu
++	Gets and print the "current" value.  Defines $cu to be it.
++end
++define int_off
++	set var $flags=$eflags
++	set $eflags=$eflags&~0x200
++	end
++define int_on
++	set var $eflags|=$flags&0x200
++	end
++document int_off
++	saves the current interrupt state and clears the processor interrupt
++	flag.  Use int_on to restore the saved flag.
++end
++document int_on
++	Restores the interrupt flag saved by int_off.
++end
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit-modules	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,146 @@
++#
++# Usefull GDB user-command to debug Linux Kernel Modules with gdbstub.
++#
++# This don't work for Linux-2.0 or older.
++#
++# Author Edouard G. Parmelan <Edouard.Parmelan@quadratec.fr>
++#
++#
++# Fri Apr 30 20:33:29 CEST 1999
++#   First public release.
++#
++#   Major cleanup after experiment Linux-2.0 kernel without success.
++#   Symbols of a module are not in the correct order, I can't explain
++#   why :(
++#
++# Fri Mar 19 15:41:40 CET 1999
++#   Initial version.
++#
++# Thu Jan  6 16:29:03 CST 2000
++#   A little fixing by Dave Grothe <dave@gcom.com>
++#
++# Mon Jun 19 09:33:13 CDT 2000
++#   Alignment changes from Edouard Parmelan
++#
++# The basic idea is to find where insmod load the module and inform
++# GDB to load the symbol table of the module with the GDB command
++# ``add-symbol-file <object> <address>''.
++#
++# The Linux kernel holds the list of all loaded modules in module_list,
++# this list end with &kernel_module (exactly with module->next == NULL,
++# but the last module is not a real module).
++#
++# Insmod allocates the struct module before the object file.  Since
++# Linux-2.1, this structure contain his size.  The real address of
++# the object file is then (char*)module + module->size_of_struct.
++#
++# You can use three user functions ``mod-list'', ``mod-print-symbols''
++# and ``add-module-symbols''.
++#
++# mod-list list all loaded modules with the format:
++#    <module-address> <module-name>
++#
++# As soon as you have found the address of your module, you can
++# print its exported symbols (mod-print-symbols) or inform GDB to add
++# symbols from your module file (mod-add-symbols).
++#
++# The argument that you give to mod-print-symbols or mod-add-symbols
++# is the <module-address> from the mod-list command.
++#
++# When using the mod-add-symbols command you must also give the full
++# pathname of the modules object code file.
++#
++# The command mod-add-lis is an example of how to make this easier.
++# You can edit this macro to contain the path name of your own
++# favorite module and then use it as a shorthand to load it.  You
++# still need the module-address, however.
++#
++# The internal function ``mod-validate'' set the GDB variable $mod
++# as a ``struct module*'' if the kernel known the module otherwise
++# $mod is set to NULL.  This ensure to not add symbols for a wrong
++# address.
++#
++# Have a nice hacking day !
++#
++#
++define mod-list
++    set $mod = (struct module*)module_list
++    # the last module is the kernel, ignore it
++    while $mod != &kernel_module
++    	printf "%p\t%s\n", (long)$mod, ($mod)->name
++	set $mod = $mod->next
++    end
++end
++document mod-list
++List all modules in the form: <module-address> <module-name>
++Use the <module-address> as the argument for the other
++mod-commands: mod-print-symbols, mod-add-symbols.
++end
++
++define mod-validate
++    set $mod = (struct module*)module_list
++    while ($mod != $arg0) && ($mod != &kernel_module)
++    	set $mod = $mod->next
++    end
++    if $mod == &kernel_module
++	set $mod = 0
++    	printf "%p is not a module\n", $arg0
++    end
++end
++document mod-validate
++mod-validate <module-address>
++Internal user-command used to validate the module parameter.
++If <module> is a real loaded module, set $mod to it otherwise set $mod to 0.
++end
++
++
++define mod-print-symbols
++    mod-validate $arg0
++    if $mod != 0
++	set $i = 0
++	while $i < $mod->nsyms
++	    set $sym = $mod->syms[$i]
++	    printf "%p\t%s\n", $sym->value, $sym->name
++	    set $i = $i + 1
++	end
++    end
++end
++document mod-print-symbols
++mod-print-symbols <module-address>
++Print all exported symbols of the module.  see mod-list
++end
++
++
++define mod-add-symbols-align
++    mod-validate $arg0
++    if $mod != 0
++	set $mod_base = ($mod->size_of_struct + (long)$mod)
++	if ($arg2 != 0) && (($mod_base & ($arg2 - 1)) != 0)
++	    set $mod_base = ($mod_base | ($arg2 - 1)) + 1
++	end
++	add-symbol-file $arg1 $mod_base
++    end
++end
++document mod-add-symbols-align
++mod-add-symbols-align <module-address> <object file path name> <align>
++Load the symbols table of the module from the object file where
++first section aligment is <align>.
++To retreive alignment, use `objdump -h <object file path name>'.
++end
++
++define mod-add-symbols
++    mod-add-symbols-align $arg0 $arg1 sizeof(long)
++end
++document mod-add-symbols
++mod-add-symbols <module-address> <object file path name>
++Load the symbols table of the module from the object file.
++Default alignment is 4.  See mod-add-symbols-align.
++end
++
++define mod-add-lis
++    mod-add-symbols-align $arg0 /usr/src/LiS/streams.o 16
++end
++document mod-add-lis
++mod-add-lis <module-address>
++Does mod-add-symbols <module-address> /usr/src/LiS/streams.o
++end
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/kgdbeth.txt	2003-10-05 00:33:46.000000000 -0700
+@@ -0,0 +1,118 @@
++KGDB over ethernet
++==================
++
++Authors
++-------
++
++Robert Walsh <rjwalsh@durables.org>  (2.6 port)
++wangdi <wangdi@clusterfs.com>        (2.6 port)
++San Mehat                            (original 2.4 code)
++
++
++Introduction
++------------
++
++KGDB supports debugging over ethernet.  Only a limited set of ethernet
++devices are supported right now, but adding support for new devices
++should not be too complicated.  See "New Devices" below for details.
++
++
++Terminology
++-----------
++
++This document uses the following terms:
++
++  TARGET: the machine being debugged.
++  HOST:   the machine running gdb.
++
++
++Usage
++-----
++
++You need to use the following command-line options on the TARGET kernel:
++
++  gdbeth=DEVICENUM
++  gdbeth_remoteip=HOSTIPADDR
++  gdbeth_remotemac=REMOTEMAC
++  gdbeth_localmac=LOCALMAC
++
++kgdbeth=DEVICENUM sets the ethernet device number to listen on for
++debugging packets.  e.g. kgdbeth=0 listens on eth0.
++
++kgdbeth_remoteip=HOSTIPADDR sets the IP address of the HOST machine.
++Only packets originating from this IP address will be accepted by the
++debugger.  e.g. kgdbeth_remoteip=192.168.2.2
++
++kgdbeth_remotemac=REMOTEMAC sets the ethernet address of the HOST machine.
++e.g. kgdbeth_remotemac=00:07:70:12:4E:F5
++
++kgdbeth_localmac=LOCALMAC sets the ethernet address of the TARGET machine.
++e.g. kgdbeth_localmac=00:10:9F:18:21:3C
++
++You can also set the following command-line option on the TARGET kernel:
++
++  kgdbeth_listenport=PORT
++
++kgdbeth_listenport sets the UDP port to listen on for gdb debugging
++packets.  The default value is "6443".  e.g. kgdbeth_listenport=7654
++causes the kernel to listen on UDP port 7654 for debugging packets.
++
++On the HOST side, run gdb as normal and use a remote UDP host as the
++target:
++
++   % gdb ./vmlinux
++   GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
++   Copyright 2003 Free Software Foundation, Inc.
++   GDB is free software, covered by the GNU General Public License, and you are
++   welcome to change it and/or distribute copies of it under certain conditions.
++   Type "show copying" to see the conditions.
++   There is absolutely no warranty for GDB.  Type "show warranty" for details.
++   This GDB was configured as "i386-redhat-linux-gnu"...
++   (gdb) target remote udp:HOSTNAME:6443
++
++You can now continue as if you were debugging over a serial line.
++
++Observations
++------------
++
++I've used this with NFS and various other network applications (ssh,
++etc.) and it's doesn't appear to interfere with their operation in
++any way.  It doesn't seem to effect the NIC it uses - i.e. you don't
++need a dedicated NIC for this.
++
++Limitations
++-----------
++
++In the inital release of this code you _must_ break into the system with the
++debugger by hand, early after boot, as described above.
++
++Otherwise, the first time the kernel tries to enter the debugger (say, via an
++oops or a BUG), the kgdb stub will doublefault and die because things aren't
++fully set up yet.
++
++Supported devices
++-----------------
++
++Right now, the following drivers are supported:
++
++  e100 driver (drivers/net/e100/*)
++  3c59x driver (drivers/net/3c59x.c)
++
++
++New devices
++-----------
++
++Supporting a new device is straightforward.  Just add a "poll" routine to
++the driver and hook it into the poll_controller field in the netdevice
++structure.  For an example, look in drivers/net/3c59x.c and search
++for CONFIG_KGDB (two places.)
++
++The poll routine is usually quite simple - it's usually enough to just
++disable interrupts, call the device's interrupt routine and re-enable
++interrupts again.
++
++
++Bug reports
++-----------
++
++Send bug reports to Robert Walsh <rjwalsh@durables.org>.
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/kgdb.txt	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,775 @@
++Last edit: <20030806.1637.12>
++This file has information specific to the i386 kgdb option.  Other
++platforms with the kgdb option may behave in a similar fashion.
++
++New features:
++============
++20030806.1557.37
++This version was made against the 2.6.0-test2 kernel. We have made the
++following changes:
++
++- The getthread() code in the stub calls find_task_by_pid().  It fails
++  if we are early in the bring up such that the pid arrays have yet to
++  be allocated.  We have added a line to kernel/pid.c to make
++  "kgdb_pid_init_done" true once the arrays are allocated.  This way the
++  getthread() code knows not to call.  This is only used by the thread
++  debugging stuff and threads will not yet exist at this point in the
++  boot.
++
++- For some reason, gdb was not asking for a new thread list when the
++  "info thread" command was given.  We changed to the newer version of
++  the thread info command and gdb now seems to ask when needed.  Result,
++  we now get all threads in the thread list.
++
++- We now respond to the ThreadExtraInfo request from gdb with the thread
++  name from task_struct .comm.  This then appears in the thread list.
++  Thoughts on additional options for this are welcome.  Things such as
++  "has BKL" and "Preempted" come to mind.  I think we could have a flag
++  word that could enable different bits of info here.
++
++- We now honor, sort of, the C and S commands.  These are continue and
++  single set after delivering a signal.  We ignore the signal and do the
++  requested action.  This only happens when we told gdb that a signal
++  was the reason for entry, which is only done on memory faults.  The
++  result is that you can now continue into the Oops.
++
++- We changed the -g to -gdwarf-2.  This seems to be the same as -ggdb,
++  but it is more exact on what language to use.
++
++- We added two dwarf2 include files and a bit of code at the end of
++  entry.S.  This does not yet work, so it is disabled.  Still we want to
++  keep track of the code and "maybe" someone out there can fix it.
++
++- Randy Dunlap sent some fix ups for this file which are now merged.
++
++- Hugh Dickins sent a fix to a bit of code in traps.c that prevents a
++  compiler warning if CONFIG_KGDB is off (now who would do that :).
++
++- Andrew Morton sent a fix for the serial driver which is now merged.
++
++- Andrew also sent a change to the stub around the cpu managment code
++  which is also merged.
++
++- Andrew also sent a patch to make "f" as well as "g" work as SysRq
++  commands to enter kgdb, merged.
++
++- If CONFIG_KGDB and CONFIG_DEBUG_SPINLOCKS are both set we added a
++  "who" field to the spinlock data struct.  This is filled with
++  "current" when ever the spinlock suceeds.  Useful if you want to know
++  who has the lock.
++
++_ And last, but not least, we fixed the "get_cu" macro to properly get
++  the current value of "current".
++
++New features:
++============
++20030505.1827.27
++We are starting to align with the sourceforge version, at least in
++commands.  To this end, the boot command string to start kgdb at
++boot time has been changed from "kgdb" to "gdb".
++
++Andrew Morton sent a couple of patches which are now included as follows:
++1.) We now return a flag to the interrupt handler.
++2.) We no longer use smp_num_cpus (a conflict with the lock meter).
++3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
++    sure high-mem is set up before we attempt to register our interrupt
++    handler.
++We now include asm/kgdb.h from config.h so you will most likely never
++have to include it.  It also 'NULLS' the kgdb macros you might have in
++your code when CONFIG_KGDB is not defined.  This allows you to just
++turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
++This include is conditioned on the machine being an x86 so as to not
++mess with other archs.
++
++20020801.1129.03
++This is currently the version for the 2.4.18 (and beyond?) kernel.
++
++We have several new "features" beginning with this version:
++
++1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI.  No more
++    waiting and it will pull that guy out of an IRQ off spin lock :)
++
++2.) We doctored up the code that tells where a task is waiting and
++    included it so that the "info thread" command will show a bit more
++    than "schedule()".  Try it...
++
++3.) Added the ability to call a function from gdb.  All the standard gdb
++    issues apply, i.e. if you hit a breakpoint in the function, you are
++    not allowed to call another (gdb limitation, not kgdb).  To help
++    this capability we added a memory allocation function.  Gdb does not
++    return this memory (it is used for strings that you pass to that function
++    you are calling from gdb) so we fixed up a way to allow you to
++    manually return the memory (see below).
++
++4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
++    interrupt flag to now also include the preemption count and the
++    "in_interrupt" info.  The flag is now called "with_pif" to indicate
++    the order, preempt_count, in_interrupt, flag.  The preempt_count is
++    shifted left by 4 bits so you can read the count in hex by dropping
++    the low order digit.  In_interrupt is in bit 1, and the flag is in
++    bit 0.
++
++5.) The command: "p kgdb_info" is now expanded and prints something
++    like:
++(gdb) p kgdb_info
++$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259,
++  errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1,
++  cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0,
++      regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
++
++    Things to note here: a.) used_malloc is the amount of memory that
++    has been malloc'ed to do calls from gdb.  You can reclaim this
++    memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
++    cpus_waiting is now "sized" by the number of CPUs you enter at
++    configure time in the kgdb configure section.  This is NOT used
++    anywhere else in the system, but it is "nice" here.  c.)  The task's
++    "pid" is now in the structure.  This is the pid you will need to use
++    to decode to the thread id to get gdb to look at that thread.
++    Remember that the "info thread" command prints a list of threads
++    wherein it numbers each thread with its reference number followed
++    by the thread's pid.  Note that the per-CPU idle threads actually
++    have pids of 0 (yes, there is more than one pid 0 in an SMP system).
++    To avoid confusion, kgdb numbers these threads with numbers beyond
++    the MAX_PID.  That is why you see 32768 and above.
++
++6.) A subtle change, we now provide the complete register set for tasks
++    that are active on the other CPUs.  This allows better trace back on
++    those tasks.
++
++    And, let's mention what we could not fix.  Back-trace from all but the
++    thread that we trapped will, most likely, have a bogus entry in it.
++    The problem is that gdb does not recognize the entry code for
++    functions that use "current" near (at all?) the entry.  The compiler
++    is putting the "current" decode as the first two instructions of the
++    function where gdb expects to find %ebp changing code.  Back trace
++    also has trouble with interrupt frames.  I am talking with Daniel
++    Jacobowitz about some way to fix this, but don't hold your breath.
++
++20011220.0050.35
++Major enhancement with this version is the ability to hold one or more
++CPUs in an SMP system while allowing the others to continue.  Also, by
++default only the current CPU is enabled on single-step commands (please
++note that gdb issues single-step commands at times other than when you
++use the si command).
++
++Another change is to collect some useful information in
++a global structure called "kgdb_info".  You should be able to just:
++
++p kgdb_info
++
++although I have seen cases where the first time this is done gdb just
++prints the first member but prints the whole structure if you then enter
++CR (carriage return or enter).  This also works:
++
++p *&kgdb_info
++
++Here is a sample:
++(gdb) p kgdb_info
++$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0,
++  vector = 3, print_debug_info = 0}
++
++"Called_from" is the return address from the current entry into kgdb.
++Sometimes it is useful to know why you are in kgdb, for example, was
++it an NMI or a real breakpoint?  The simple way to interrogate this
++return address is:
++
++l *0xc010732c
++
++which will print the surrounding few lines of source code.
++
++"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
++kgdb_ts entries).
++
++"errcode" and "vector" are other entry parameters which may be helpful on
++some traps.
++
++"print_debug_info" is the internal debugging kgdb print enable flag.  Yes,
++you can modify it.
++
++In SMP systems kgdb_info also includes the "cpus_waiting" structure and
++"hold_on_step":
++
++(gdb) p kgdb_info
++$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0,
++  vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
++      task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0,
++      regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}}}
++
++"Cpus_waiting" has an entry for each CPU other than the current one that
++has been stopped.  Each entry contains the task_struct address for that
++CPU, the address of the regs for that task and a hold flag.  All these
++have the proper typing so that, for example:
++
++p *kgdb_info.cpus_waiting[1].regs
++
++will print the registers for CPU 1.
++
++"Hold_on_sstep" is a new feature with this version and comes up set or
++true.  What this means is that whenever kgdb is asked to single-step all
++other CPUs are held (i.e. not allowed to execute).  The flag applies to
++all but the current CPU and, again, can be changed:
++
++p kgdb_info.hold_on_sstep=0
++
++restores the old behavior of letting all CPUs run during single-stepping.
++
++Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
++of execution.  Note that this has some risk in cases where the CPUs need
++to communicate with each other.  If kgdb finds no CPU available on exit,
++it will push a message thru gdb and stay in kgdb.  Note that it is legal
++to hold the current CPU as long as at least one CPU can execute.
++
++20010621.1117.09
++This version implements an event queue.  Events are signaled by calling
++a function in the kgdb stub and may be examined from gdb.  See EVENTS
++below for details.  This version also tightens up the interrupt and SMP
++handling to not allow interrupts on the way to kgdb from a breakpoint
++trap.  It is fine to allow these interrupts for user code, but not
++system debugging.
++
++Version
++=======
++
++This version of the kgdb package was developed and tested on
++kernel version 2.4.16.  It will not install on any earlier kernels.
++It is possible that it will continue to work on later versions
++of 2.4 and then versions of 2.5 (I hope).
++
++
++Debugging Setup
++===============
++
++Designate one machine as the "development" machine.  This is the
++machine on which you run your compiles and which has your source
++code for the kernel.  Designate a second machine as the "target"
++machine.  This is the machine that will run your experimental
++kernel.
++
++The two machines will be connected together via a serial line out
++one or the other of the COM ports of the PC.  You will need the
++appropriate modem eliminator (null modem) cable(s) for this.
++
++Decide on which tty port you want the machines to communicate, then
++connect them up back-to-back using the null modem cable.  COM1 is
++/dev/ttyS0 and COM2 is /dev/ttyS1. You should test this connection
++with the two machines prior to trying to debug a kernel.  Once you
++have it working, on the TARGET machine, enter:
++
++setserial /dev/ttyS0 (or what ever tty you are using)
++
++and record the port address and the IRQ number.
++
++On the DEVELOPMENT machine you need to apply the patch for the kgdb
++hooks.  You have probably already done that if you are reading this
++file.
++
++On your DEVELOPMENT machine, go to your kernel source directory and do
++"make Xconfig" where X is one of "x", "menu", or "".  If you are
++configuring in the standard serial driver, it must not be a module.
++Either yes or no is ok, but making the serial driver a module means it
++will initialize after kgdb has set up the UART interrupt code and may
++cause a failure of the control-C option discussed below.  The configure
++question for the serial driver is under the "Character devices" heading
++and is:
++
++"Standard/generic (8250/16550 and compatible UARTs) serial support"
++
++Go down to the kernel debugging menu item and open it up.  Enable the
++kernel kgdb stub code by selecting that item.  You can also choose to
++turn on the "-ggdb -O1" compile options.  The -ggdb causes the compiler
++to put more debug info (like local symbols) in the object file.  On the
++i386 -g and -ggdb are the same so this option just reduces to "O1".  The
++-O1 reduces the optimization level.  This may be helpful in some cases,
++be aware, however, that this may also mask the problem you are looking
++for.
++
++The baud rate.  Default is 115200.  What ever you choose be sure that
++the host machine is set to the same speed.  I recommend the default.
++
++The port.  This is the I/O address of the serial UART that you should
++have gotten using setserial as described above.  The standard COM1 port
++(3f8) using IRQ 4 is default.  COM2 is 2f8 which by convention uses IRQ
++3.
++
++The port IRQ (see above).
++
++Stack overflow test.  This option makes a minor change in the trap,
++system call and interrupt code to detect stack overflow and transfer
++control to kgdb if it happens.  (Some platforms have this in the
++baseline code, but the i386 does not.)
++
++You can also configure the system to recognize the boot option
++"console=kgdb" which if given will cause all console output during
++booting to be put thru gdb as well as other consoles.  This option
++requires that gdb and kgdb be connected prior to sending console output
++so, if they are not, a breakpoint is executed to force the connection.
++This will happen before any kernel output (it is going thru gdb, right),
++and will stall the boot until the connection is made.
++
++You can also configure in a patch to SysRq to enable the kGdb SysRq.
++This request generates a breakpoint.  Since the serial port IRQ line is
++set up after any serial drivers, it is possible that this command will
++work when the control-C will not.
++
++Save and exit the Xconfig program.  Then do "make clean" , "make dep"
++and "make bzImage" (or whatever target you want to make).  This gets the
++kernel compiled with the "-g" option set -- necessary for debugging.
++
++You have just built the kernel on your DEVELOPMENT machine that you
++intend to run on your TARGET machine.
++
++To install this new kernel, use the following installation procedure.
++Remember, you are on the DEVELOPMENT machine patching the kernel source
++for the kernel that you intend to run on the TARGET machine.
++
++Copy this kernel to your target machine using your usual procedures.  I
++usually arrange to copy development:
++/usr/src/linux/arch/i386/boot/bzImage to /vmlinuz on the TARGET machine
++via a LAN based NFS access.  That is, I run the cp command on the target
++and copy from the development machine via the LAN.  Run Lilo (see "man
++lilo" for details on how to set this up) on the new kernel on the target
++machine so that it will boot!  Then boot the kernel on the target
++machine.
++
++On the DEVELOPMENT machine, create a file called .gdbinit in the
++directory /usr/src/linux.  An example .gdbinit file looks like this:
++
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400 (or what ever speed you have chosen)
++target remote /dev/ttyS0
++
++
++Change the "echo" and "target" definition so that it specifies the tty
++port that you intend to use.  Change the "remotebaud" definition to
++match the data rate that you are going to use for the com line.
++
++You are now ready to try it out.
++
++Boot your target machine with "kgdb" in the boot command i.e. something
++like:
++
++lilo> test kgdb
++
++or if you also want console output thru gdb:
++
++lilo> test kgdb console=kgdb
++
++You should see the lilo message saying it has loaded the kernel and then
++all output stops.  The kgdb stub is trying to connect with gdb.  Start
++gdb something like this:
++
++
++On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux".
++When gdb gets the symbols loaded it will read your .gdbinit file and, if
++everything is working correctly, you should see gdb print out a few
++lines indicating that a breakpoint has been taken.  It will actually
++show a line of code in the target kernel inside the kgdb activation
++code.
++
++The gdb interaction should look something like this:
++
++    linux-dev:/usr/src/linux# gdb vmlinux
++    GDB is free software and you are welcome to distribute copies of it
++     under certain conditions; type "show copying" to see the conditions.
++    There is absolutely no warranty for GDB; type "show warranty" for details.
++    GDB 4.15.1 (i486-slackware-linux),
++    Copyright 1995 Free Software Foundation, Inc...
++    breakpoint () at i386-stub.c:750
++    750     }
++    (gdb)
++
++You can now use whatever gdb commands you like to set breakpoints.
++Enter "continue" to start your target machine executing again.  At this
++point the target system will run at full speed until it encounters
++your breakpoint or gets a segment violation in the kernel, or whatever.
++
++If you have the kgdb console enabled when you continue, gdb will print
++out all the console messages.
++
++The above example caused a breakpoint relatively early in the boot
++process.  For the i386 kgdb it is possible to code a break instruction
++as the first C-language point in init/main.c, i.e. as the first instruction
++in start_kernel().  This could be done as follows:
++
++#include <asm/kgdb.h>
++	 breakpoint();
++
++This breakpoint() is really a function that sets up the breakpoint and
++single-step hardware trap cells and then executes a breakpoint.  Any
++early hard coded breakpoint will need to use this function.  Once the
++trap cells are set up they need not be set again, but doing it again
++does not hurt anything, so you don't need to be concerned about which
++breakpoint is hit first.  Once the trap cells are set up (and the kernel
++sets them up in due course even if breakpoint() is never called) the
++macro:
++
++BREAKPOINT;
++
++will generate an inline breakpoint.  This may be more useful as it stops
++the processor at the instruction instead of in a function a step removed
++from the location of interest.  In either case <asm/kgdb.h> must be
++included to define both breakpoint() and BREAKPOINT.
++
++Triggering kgdbstub at other times
++==================================
++
++Often you don't need to enter the debugger until much later in the boot
++or even after the machine has been running for some time.  Once the
++kernel is booted and interrupts are on, you can force the system to
++enter the debugger by sending a control-C to the debug port. This is
++what the first line of the recommended .gdbinit file does.  This allows
++you to start gdb any time after the system is up as well as when the
++system is already at a breakpoint.  (In the case where the system is
++already at a breakpoint the control-C is not needed, however, it will
++be ignored by the target so no harm is done.  Also note the the echo
++command assumes that the port speed is already set.  This will be true
++once gdb has connected, but it is best to set the port speed before you
++run gdb.)
++
++Another simple way to do this is to put the following file in you ~/bin
++directory:
++
++#!/bin/bash
++echo  -e "\003"  > /dev/ttyS0
++
++Here, the ttyS0 should be replaced with what ever port you are using.
++The "\003" is control-C.  Once you are connected with gdb, you can enter
++control-C at the command prompt.
++
++An alternative way to get control to the debugger is to enable the kGdb
++SysRq command.  Then you would enter Alt-SysRq-g (all three keys at the
++same time, but push them down in the order given).  To refresh your
++memory of the available SysRq commands try Alt-SysRq-=.  Actually any
++undefined command could replace the "=", but I like to KNOW that what I
++am pushing will never be defined.
++
++Debugging hints
++===============
++
++You can break into the target machine at any time from the development
++machine by typing ^C (see above paragraph).  If the target machine has
++interrupts enabled this will stop it in the kernel and enter the
++debugger.
++
++There is unfortunately no way of breaking into the kernel if it is
++in a loop with interrupts disabled, so if this happens to you then
++you need to place exploratory breakpoints or printk's into the kernel
++to find out where it is looping.  The exploratory breakpoints can be
++entered either thru gdb or hard coded into the source.  This is very
++handy if you do something like:
++
++if (<it hurts>) BREAKPOINT;
++
++
++There is a copy of an e-mail in the Documentation/i386/kgdb/ directory
++(debug-nmi.txt) which describes how to create an NMI on an ISA bus
++machine using a paper clip.  I have a sophisticated version of this made
++by wiring a push button switch into a PC104/ISA bus adapter card.  The
++adapter card nicely furnishes wire wrap pins for all the ISA bus
++signals.
++
++When you are done debugging the kernel on the target machine it is a
++good idea to leave it in a running state.  This makes reboots faster,
++bypassing the fsck.  So do a gdb "continue" as the last gdb command if
++this is possible.  To terminate gdb itself on the development machine
++and leave the target machine running, first clear all breakpoints and
++continue, then type ^Z to suspend gdb and then kill it with "kill %1" or
++something similar.
++
++If gdbstub Does Not Work
++========================
++
++If it doesn't work, you will have to troubleshoot it.  Do the easy
++things first like double checking your cabling and data rates.  You
++might try some non-kernel based programs to see if the back-to-back
++connection works properly.  Just something simple like cat /etc/hosts
++>/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
++if you can send data from one machine to the other.  Make sure it works
++in both directions.  There is no point in tearing out your hair in the
++kernel if the line doesn't work.
++
++All of the real action takes place in the file
++/usr/src/linux/arch/i386/kernel/kgdb_stub.c.  That is the code on the target
++machine that interacts with gdb on the development machine.  In gdb you can
++turn on a debug switch with the following command:
++
++	set remotedebug
++
++This will print out the protocol messages that gdb is exchanging with
++the target machine.
++
++Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c. This is
++the code that talks to the serial port on the target side.  There might
++be a problem there.  In particular there is a section of this code that
++tests the UART which will tell you what UART you have if you define
++"PRNT" (just remove "_off" from the #define PRNT_off).  To view this
++report you will need to boot the system without any beakpoints.  This
++allows the kernel to run to the point where it calls kgdb to set up
++interrupts.  At this time kgdb will test the UART and print out the type
++it finds.  (You need to wait so that the printks are actually being
++printed.  Early in the boot they are cached, waiting for the console to
++be enabled.  Also, if kgdb is entered thru a breakpoint it is possible
++to cause a dead lock by calling printk when the console is locked.  The
++stub thus avoids doing printks from breakpoints, especially in the
++serial code.)  At this time, if the UART fails to do the expected thing,
++kgdb will print out (using printk) information on what failed.  (These
++messages will be buried in all the other boot up messages.  Look for
++lines that start with "gdb_hook_interrupt:".  You may want to use dmesg
++once the system is up to view the log.  If this fails or if you still
++don't connect, review your answers for the port address.  Use:
++
++setserial /dev/ttyS0
++
++to get the current port and IRQ information.  This command will also
++tell you what the system found for the UART type. The stub recognizes
++the following UART types:
++
++16450, 16550, and 16550A
++
++If you are really desperate you can use printk debugging in the
++kgdbstub code in the target kernel until you get it working.  In particular,
++there is a global variable in /usr/src/linux/arch/i386/kernel/kgdb_stub.c
++named "remote_debug".  Compile your kernel with this set to 1, rather
++than 0 and the debug stub will print out lots of stuff as it does
++what it does.  Likewise there are debug printks in the kgdb_serial.c
++code that can be turned on with simple changes in the macro defines.
++
++
++Debugging Loadable Modules
++==========================
++
++This technique comes courtesy of Edouard Parmelan
++<Edouard.Parmelan@quadratec.fr>
++
++When you run gdb, enter the command
++
++source gdbinit-modules
++
++This will read in a file of gdb macros that was installed in your
++kernel source directory when kgdb was installed.  This file implements
++the following commands:
++
++mod-list
++    Lists the loaded modules in the form <module-address> <module-name>
++
++mod-print-symbols <module-address>
++    Prints all the symbols in the indicated module.
++
++mod-add-symbols <module-address> <object-file-path-name>
++    Loads the symbols from the object file and associates them
++    with the indicated module.
++
++After you have loaded the module that you want to debug, use the command
++mod-list to find the <module-address> of your module.  Then use that
++address in the mod-add-symbols command to load your module's symbols.
++From that point onward you can debug your module as if it were a part
++of the kernel.
++
++The file gdbinit-modules also contains a command named mod-add-lis as
++an example of how to construct a command of your own to load your
++favorite module.  The idea is to "can" the pathname of the module
++in the command so you don't have to type so much.
++
++Threads
++=======
++
++Each process in a target machine is seen as a gdb thread. gdb thread
++related commands (info threads, thread n) can be used.
++
++ia-32 hardware breakpoints
++==========================
++
++kgdb stub contains support for hardware breakpoints using debugging features
++of ia-32(x86) processors. These breakpoints do not need code modification.
++They use debugging registers. 4 hardware breakpoints are available in ia-32
++processors.
++
++Each hardware breakpoint can be of one of the following three types.
++
++1. Execution breakpoint - An Execution breakpoint is triggered when code
++	at the breakpoint address is executed.
++
++	As limited number of hardware breakpoints are available, it is
++	advisable to use software breakpoints ( break command ) instead
++	of execution hardware breakpoints, unless modification of code
++	is to be avoided.
++
++2. Write breakpoint - A write breakpoint is triggered when memory
++	location at the breakpoint address is written.
++
++	A write or can be placed for data of variable length. Length of
++	a write breakpoint indicates length of the datatype to be
++	watched. Length is 1 for 1 byte data , 2 for 2 byte data, 3 for
++	4 byte data.
++
++3. Access breakpoint - An access breakpoint is triggered when memory
++	location at the breakpoint address is either read or written.
++
++	Access breakpoints also have lengths similar to write breakpoints.
++
++IO breakpoints in ia-32 are not supported.
++
++Since gdb stub at present does not use the protocol used by gdb for hardware
++breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros
++for hardware breakpoints are described below.
++
++hwebrk	- Places an execution breakpoint
++	hwebrk breakpointno address
++hwwbrk	- Places a write breakpoint
++	hwwbrk breakpointno length address
++hwabrk	- Places an access breakpoint
++	hwabrk breakpointno length address
++hwrmbrk	- Removes a breakpoint
++	hwrmbrk breakpointno
++exinfo	- Tells whether a software or hardware breakpoint has occurred.
++	Prints number of the hardware breakpoint if a hardware breakpoint has
++	occurred.
++
++Arguments required by these commands are as follows
++breakpointno	- 0 to 3
++length		- 1 to 3
++address		- Memory location in hex digits ( without 0x ) e.g c015e9bc
++
++SMP support
++==========
++
++When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb
++client, all the processors are forced to enter the debugger. Current
++thread corresponds to the thread running on the processor where
++breakpoint occurred.  Threads running on other processor(s) appear
++similar to other non-running threads in the 'info threads' output.
++Within the kgdb stub there is a structure "waiting_cpus" in which kgdb
++records the values of "current" and "regs" for each CPU other than the
++one that hit the breakpoint.  "current" is a pointer to the task
++structure for the task that CPU is running, while "regs" points to the
++saved registers for the task.  This structure can be examined with the
++gdb "p" command.
++
++ia-32 hardware debugging registers on all processors are set to same
++values.  Hence any hardware breakpoints may occur on any processor.
++
++gdb troubleshooting
++===================
++
++1. gdb hangs
++Kill it. restart gdb. Connect to target machine.
++
++2. gdb cannot connect to target machine (after killing a gdb and
++restarting another) If the target machine was not inside debugger when
++you killed gdb, gdb cannot connect because the target machine won't
++respond.  In this case echo "Ctrl+C"(ASCII 3) to the serial line.
++e.g. echo -e "\003" > /dev/ttyS1
++This forces that target machine into the debugger, after which you
++can connect.
++
++3. gdb cannot connect even after echoing Ctrl+C into serial line
++Try changing serial line settings min to 1 and time to 0
++e.g. stty min 1 time 0 < /dev/ttyS1
++Try echoing again
++
++Check serial line speed and set it to correct value if required
++e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
++
++EVENTS
++======
++
++Ever want to know the order of things happening?  Which CPU did what and
++when?  How did the spinlock get the way it is?  Then events are for
++you.  Events are defined by calls to an event collection interface and
++saved for later examination.  In this case, kgdb events are saved by a
++very fast bit of code in kgdb which is fully SMP and interrupt protected
++and they are examined by using gdb to display them.  Kgdb keeps only
++the last N events, where N must be a power of two and is defined at
++configure time.
++
++
++Events are signaled to kgdb by calling:
++
++kgdb_ts(data0,data1)
++
++For each call kgdb records each call in an array along with other info.
++Here is the array definition:
++
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++	int	on_cpu;
++#endif
++	long long at_time;
++	int  	from_ln;
++	char	* in_src;
++	void	*from;
++        int     with_if;
++	int	data0;
++	int	data1;
++};
++
++For SMP machines the CPU is recorded, for all machines the TSC is
++recorded (gets a time stamp) as well as the line number and source file
++the call was made from.  The address of the (from), the "if" (interrupt
++flag) and the two data items are also recorded.  The macro kgdb_ts casts
++the types to int, so you can put any 32-bit values here.  There is a
++configure option to select the number of events you want to keep.  A
++nice number might be 128, but you can keep up to 1024 if you want.  The
++number must be a power of two.  An "andthen" macro library is provided
++for gdb to help you look at these events.  It is also possible to define
++a different structure for the event storage and cast the data to this
++structure.  For example the following structure is defined in kgdb:
++
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++	int	on_cpu;
++#endif
++	long long at_time;
++	int  	from_ln;
++	char	* in_src;
++	void	*from;
++        int     with_if;
++	struct task_struct *t1;
++	struct task_struct *t2;
++};
++
++If you use this for display, the data elements will be displayed as
++pointers to task_struct entries.  You may want to define your own
++structure to use in casting.  You should only change the last two items
++and you must keep the structure size the same.  Kgdb will handle these
++as 32-bit ints, but within that constraint you can define a structure to
++cast to any 32-bit quantity.  This need only be available to gdb and is
++only used for casting in the display code.
++
++Final Items
++===========
++
++I picked up this code from Amit S. Kale and enhanced it.
++
++If you make some really cool modification to this stuff, or if you
++fix a bug, please let me know.
++
++George Anzinger
++<george@mvista.com>
++
++Amit S. Kale
++<akale@veritas.com>
++
++(First kgdb by David Grothe <dave@gcom.com>)
++
++(modified by Tigran Aivazian <tigran@sco.com>)
++    Putting gdbstub into the kernel config menu.
++
++(modified by Scott Foehner <sfoehner@engr.sgi.com>)
++    Hooks for entering gdbstub at boot time.
++
++(modified by Amit S. Kale <akale@veritas.com>)
++    Threads, ia-32 hw debugging, mp support, console support,
++    nmi watchdog handling.
++
++(modified by George Anzinger <george@mvista.com>)
++    Extended threads to include the idle threads.
++    Enhancements to allow breakpoint() at first C code.
++    Use of module_init() and __setup() to automate the configure.
++    Enhanced the cpu "collection" code to work in early bring-up.
++    Added ability to call functions from gdb
++    Print info thread stuff without going back to schedule()
++    Now collect the "other" cpus with an IPI/ NMI.
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/loadmodule.sh	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,78 @@
++#/bin/sh
++# This script loads a module on a target machine and generates a gdb script.
++# source generated gdb script to load the module file at appropriate addresses
++# in gdb.
++#
++# Usage:
++# Loading the module on target machine and generating gdb script)
++#	[foo]$ loadmodule.sh <modulename>
++#
++# Loading the module file into gdb
++#	(gdb) source <gdbscriptpath>
++#
++# Modify following variables according to your setup.
++#	TESTMACHINE - Name of the target machine
++#	GDBSCRIPTS - The directory where a gdb script will be generated
++#
++# Author: Amit S. Kale (akale@veritas.com).
++#
++# If you run into problems, please check files pointed to by following
++# variables.
++#	ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
++#	MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
++#	GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
++
++TESTMACHINE=foo
++GDBSCRIPTS=/home/bar
++
++if [ $# -lt 1 ] ; then {
++	echo Usage: $0 modulefile
++	exit
++} ; fi
++
++MODULEFILE=$1
++MODULEFILEBASENAME=`basename $1`
++
++if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
++	MODULEFILE=`pwd`/$MODULEFILE
++} fi
++
++ERRFILE=/tmp/$MODULEFILEBASENAME.errs
++MAPFILE=/tmp/$MODULEFILEBASENAME.map
++GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
++
++function findaddr() {
++	local ADDR=0x$(echo "$SEGMENTS" | \
++		grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
++		sed 's/[ ]*[^ ]*$//')
++	echo $ADDR
++}
++
++function checkerrs() {
++	if [ "`cat $ERRFILE`" != "" ] ; then {
++		cat $ERRFILE
++		exit
++	} fi
++}
++
++#load the module
++echo Copying $MODULEFILE to $TESTMACHINE
++rcp $MODULEFILE root@${TESTMACHINE}:
++
++echo Loading module $MODULEFILE
++rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
++	> $MAPFILE 2> $ERRFILE
++checkerrs
++
++SEGMENTS=`head -n 11 $MAPFILE | tail -n 10`
++TEXTADDR=$(findaddr "\\.text[^.]")
++LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
++SEGADDRS=`echo "$SEGMENTS" | awk '//{
++	if ($1 != ".text" && $1 != ".this" &&
++	    $1 != ".kstrtab" && $1 != ".kmodtab") {
++		print " -s " $1 " 0x" $3 " "
++	}
++}'`
++LOADSTRING="$LOADSTRING $SEGADDRS"
++echo Generating script $GDBSCRIPT
++echo $LOADSTRING > $GDBSCRIPT
+--- linux-2.6.0-test6/Documentation/ioctl-number.txt	2003-09-08 13:58:55.000000000 -0700
++++ 25/Documentation/ioctl-number.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -175,10 +175,6 @@ Code	Seq#	Include File		Comments
+ 					<mailto:buk@buks.ipn.de>
+ 0xA0	all	linux/sdp/sdp.h		Industrial Device Project
+ 					<mailto:kenji@bitgate.com>
+-0xA2    00-0F   DVD decoder driver      in development:
+-                                        <http://linuxtv.org/developer/dvdapi.html>
+-0xA3	00-1F	Philips SAA7146 dirver	in development:
+-					<mailto:Andreas.Beckmann@hamburg.sc.philips.com>
+ 0xA3	80-8F	Port ACL		in development:
+ 					<mailto:tlewis@mindspring.com>
+ 0xA3	90-9F	linux/dtlk.h
+--- linux-2.6.0-test6/Documentation/iostats.txt	2003-06-14 12:18:06.000000000 -0700
++++ 25/Documentation/iostats.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -1,22 +1,22 @@
+ I/O statistics fields
+ ---------------
+ 
+-Last modified 5/15/03
++Last modified Sep 30, 2003
+ 
+-In 2.4.20 (and some versions before, with patches), and 2.5.45,
+-more extensive disk statistics were introduced to help measure disk
++Since 2.4.20 (and some versions before, with patches), and 2.5.45,
++more extensive disk statistics have been introduced to help measure disk
+ activity. Tools such as sar and iostat typically interpret these and do
+ the work for you, but in case you are interested in creating your own
+ tools, the fields are explained here.
+ 
+-In most versions of the 2.4 patch, the information is found as additional
+-fields in /proc/partitions.  In 2.5, the same information is found in
+-two places: one is in the file /proc/diskstats (appears in 2.5.69 and
+-beyond), and the other is within the sysfs file system, which must be
+-mounted in order to obtain the information. Throughout this document
+-we'll assume that sysfs is mounted on /sys, although of course it may
+-be mounted anywhere.  In 2.5, both /proc/diskstats and sysfs use the
+-same source for the information and so should not differ.
++In 2.4 now, the information is found as additional fields in
++/proc/partitions.  In 2.6, the same information is found in two
++places: one is in the file /proc/diskstats, and the other is within
++the sysfs file system, which must be mounted in order to obtain
++the information. Throughout this document we'll assume that sysfs
++is mounted on /sys, although of course it may be mounted anywhere.
++Both /proc/diskstats and sysfs use the same source for the information
++and so should not differ.
+ 
+ Here are examples of these different formats:
+ 
+@@ -25,15 +25,15 @@ Here are examples of these different for
+    3     1    9221278 hda1 35486 0 35496 38030 0 0 0 0 0 38030 38030
+ 
+ 
+-2.5 sysfs:
++2.6 sysfs:
+    446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
+    35486    38030    38030    38030
+ 
+-2.5 diskstats:
++2.6 diskstats:
+    3    0   hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
+    3    1   hda1 35486 38030 38030 38030
+ 
+-On 2.4 you might execute "grep 'hda ' /proc/partitions". On 2.5, you have
++On 2.4 you might execute "grep 'hda ' /proc/partitions". On 2.6, you have
+ a choice of "cat /sys/block/hda/stat" or "grep 'hda ' /proc/diskstats".
+ The advantage of one over the other is that the sysfs choice works well
+ if you are watching a known, small set of disks.  /proc/diskstats may
+@@ -43,7 +43,7 @@ each snapshot of your disk statistics.
+ 
+ In 2.4, the statistics fields are those after the device name. In
+ the above example, the first field of statistics would be 446216.
+-By contrast, in 2.5 if you look at /sys/block/hda/stat, you'll
++By contrast, in 2.6 if you look at /sys/block/hda/stat, you'll
+ find just the eleven fields, beginning with 446216.  If you look at
+ /proc/diskstats, the eleven fields will be preceded by the major and
+ minor device numbers, and device name.  Each of these formats provide
+@@ -93,35 +93,35 @@ Field 11 -- weighted # of milliseconds s
+ To avoid introducing performance bottlenecks, no locks are held while
+ modifying these counters.  This implies that minor inaccuracies may be
+ introduced when changes collide, so (for instance) adding up all the
+-read I/Os issued per partition should equal those made to the disks
+-... but due to the lack of locking it may only be very close.
++read I/Os issued per partition should equal those made to the disks ...
++but due to the lack of locking it may only be very close.
+ 
+-In release 2.5.65 the 2.5 counters were made per-cpu, which made the lack
+-of locking almost a non-issue.  When the statistics are read, the per-cpu
+-counters are summed (possibly overflowing the unsigned 32-bit variable
+-they are summed to) and the result given to the user.  There is no
+-convenient user interface for accessing the per-cpu counters themselves.
++In 2.6, there are counters for each cpu, which made the lack of locking
++almost a non-issue.  When the statistics are read, the per-cpu counters
++are summed (possibly overflowing the unsigned 32-bit variable they are
++summed to) and the result given to the user.  There is no convenient
++user interface for accessing the per-cpu counters themselves.
+ 
+ Disks vs Partitions
+ -------------------
+ 
+-There were significant changes between 2.4 and 2.5 in the I/O subsystem.
++There were significant changes between 2.4 and 2.6 in the I/O subsystem.
+ As a result, some statistic information disappeared. The translation from
+ a disk address relative to a partition to the disk address relative to
+ the host disk happens much earlier.  All merges and timings now happen
+ at the disk level rather than at both the disk and partition level as
+-in 2.4.  Consequently, you'll see a different statistics output on 2.5 for
++in 2.4.  Consequently, you'll see a different statistics output on 2.6 for
+ partitions from that for disks.  There are only *four* fields available
+-for partitions on 2.5 machines.  This is reflected in the examples above.
++for partitions on 2.6 machines.  This is reflected in the examples above.
+ 
+ Field  1 -- # of reads issued
+     This is the total number of reads issued to this partition.
+ Field  2 -- # of sectors read
+     This is the total number of sectors requested to be read from this
+     partition.
+-Field  3 -- # of reads issued
++Field  3 -- # of writes issued
+     This is the total number of writes issued to this partition.
+-Field  4 -- # of sectors read
++Field  4 -- # of sectors written
+     This is the total number of sectors requested to be written to
+     this partition.
+ 
+@@ -135,14 +135,16 @@ a subtle distinction that is probably un
+ Additional notes
+ ----------------
+ 
+-In 2.5, sysfs is not mounted by default.  Here's the line you'll want
+-to add to your /etc/fstab:
++In 2.6, sysfs is not mounted by default.  If your distribution of
++Linux hasn't added it already, here's the line you'll want to add to
++your /etc/fstab:
+ 
+ none /sys sysfs defaults 0 0
+ 
+ 
+-In 2.5, at the same time that disk statistics appeared in sysfs, they were
+-removed from /proc/stat.  In 2.4, they appear in both /proc/partitions
+-and /proc/stat.
++In 2.6, all disk statistics were removed from /proc/stat.  In 2.4, they
++appear in both /proc/partitions and /proc/stat, although the ones in
++/proc/stat take a very different format from those in /proc/partitions
++(see proc(5), if your system has it.)
+ 
+ -- ricklind@us.ibm.com
+--- linux-2.6.0-test6/Documentation/kernel-parameters.txt	2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/kernel-parameters.txt	2003-10-05 00:34:33.000000000 -0700
+@@ -460,6 +460,10 @@ running once the system is up.
+ 	logibm_irq=	[HW,MOUSE] Logitech Bus Mouse Driver
+ 			Format: <irq>
+ 
++	log_buf_len=n	Sets the size of the printk ring buffer, in bytes.
++			Format is n, nk, nM.  n must be a power of two.  The
++			default is set in kernel config.
++
+ 	lp=0		[LP]	Specify parallel ports to use, e.g,
+ 	lp=port[,port...]	lp=none,parport0 (lp0 not configured, lp1 uses
+ 	lp=reset		first parallel port). 'lp=0' disables the
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/MSI-HOWTO.txt	2003-10-05 00:36:20.000000000 -0700
+@@ -0,0 +1,321 @@
++		The MSI Driver Guide HOWTO
++	Tom L Nguyen tom.l.nguyen@intel.com
++			10/03/2003
++
++1. About this guide
++
++This guide describes the basics of Message Signaled Interrupts(MSI), the
++advantages of using MSI over traditional interrupt mechanisms, and how
++to enable your driver to use MSI or MSI-X. Also included is a Frequently
++Asked Questions.
++
++2. Copyright 2003 Intel Corporation
++
++3. What is MSI/MSI-X?
++
++Message Signaled Interrupt (MSI), as described in the PCI Local Bus
++Specification Revision 2.3 or latest, is an optional feature, and a
++required feature for PCI Express devices. MSI enables a device function
++to request service by sending an Inbound Memory Write on its PCI bus to
++the FSB as a Message Signal Interrupt transaction. Because MSI is
++generated in the form of a Memory Write, all transaction conditions,
++such as a Retry, Master-Abort, Target-Abort or normal completion, are
++supported.
++
++A PCI device that supports MSI must also support pin IRQ assertion
++interrupt mechanism to provide backward compatibility for systems that
++do not support MSI. In Systems, which support MSI, the bus driver is
++responsible for initializing the message address and message data of
++the device function's MSI/MSI-X capability structure during device
++initial configuration.
++
++An MSI capable device function indicates MSI support by implementing
++the MSI/MSI-X capability structure in its PCI capability list. The
++device function may implement both the MSI capability structure and
++the MSI-X capability structure; however, the bus driver should not
++enable both, but instead enable only the MSI-X capability structure.
++
++The MSI capability structure contains Message Control register,
++Message Address register and Message Data register. These registers
++provide the bus driver control over MSI. The Message Control register
++indicates the MSI capability supported by the device. The Message
++Address register specifies the target address and the Message Data
++register specifies the characteristics of the message. To request
++service, the device function writes the content of the Message Data
++register to the target address. The device and its software driver
++are prohibited from writing to these registers.
++
++The MSI-X capability structure is an optional extension to MSI. It
++uses an independent and separate capability structure. There are
++some key advantages to implementing the MSI-X capability structure
++over the MSI capability structure as described below.
++
++	- Support a larger maximum number of vectors per function.
++
++	- Provide the ability for system software to configure
++	each vector with an independent message address and message
++	data, specified by a table that resides in Memory Space.
++
++        - MSI and MSI-X both support per-vector masking. Per-vector
++	masking is an optional extension of MSI but a required
++	feature for MSI-X. Per-vector masking provides the kernel
++	the ability to mask/unmask MSI when servicing its software
++	interrupt service routing handler. If per-vector masking is
++	not supported, then the device driver should provide the
++	hardware/software synchronization to ensure that the device
++	generates MSI when the driver wants it to do so.
++
++4. Why use MSI?
++
++As a benefit the simplification of board design, MSI allows board
++designers to remove out of band interrupt routing. MSI is another
++step towards a legacy-free environment.
++
++Due to increasing pressure on chipset and processor packages to
++reduce pin count, the need for interrupt pins is expected to
++diminish over time. Devices, due to pin constraints, may implement
++messages to increase performance.
++
++PCI Express endpoints uses INTx emulation (in-band messages) instead
++of IRQ pin assertion. Using INTx emulation requires interrupt
++sharing among devices connected to the same node (PCI bridge) while
++MSI is unique (non-shared) and does not require BIOS configuration
++support. As a result, the PCI Express technology requires MSI
++support for better interrupt performance.
++
++Using MSI enables the device functions to support two or more
++vectors, which can be configure to target different CPU's to
++increase scalability.
++
++5. Configuring a driver to use MSI/MSI-X
++
++By default, the kernel will not enable MSI/MSI-X on all devices that
++support this capability once the patch is installed. A kernel
++configuration option must be selected to enable MSI/MSI-X support.
++
++5.1 Including MSI support into the kernel
++
++To include MSI support into the kernel requires users to patch the
++VECTOR-base patch first and then the MSI patch because the MSI
++support needs VECTOR based scheme. Once these patches are installed,
++setting CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and
++the option for MSI-capable device drivers to selectively enable MSI
++(using pci_enable_msi as desribed below).
++
++Since the target of the inbound message is the local APIC, providing
++CONFIG_PCI_USE_VECTOR is dependent on whether CONFIG_X86_LOCAL_APIC
++is enabled or not.
++
++int pci_enable_msi(struct pci_dev *)
++
++With this new API, any existing device driver, which like to have
++MSI enabled on its device function, must call this explicitly. A
++successful call will initialize the MSI/MSI-X capability structure
++with ONE vector, regardless of whether the device function is
++capable of supporting multiple messages. This vector replaces the
++pre-assigned dev->irq with a new MSI vector. To avoid the conflict
++of new assigned vector with existing pre-assigned vector requires
++the device driver to call this API before calling request_irq(...).
++
++The below diagram shows the events, which switches the interrupt
++mode on the MSI-capable device function between MSI mode and
++PIN-IRQ assertion mode.
++
++	 ------------   pci_enable_msi 	 ------------------------
++	|	     | <===============	| 			 |
++	| MSI MODE   |	  	     	| PIN-IRQ ASSERTION MODE |
++	| 	     | ===============>	|			 |
++ 	 ------------	free_irq      	 ------------------------
++
++5.2 Configuring for MSI support
++
++Due to the non-contiguous fashion in vector assignment of the
++existing Linux kernel, this patch does not support multiple
++messages regardless of the device function is capable of supporting
++more than one vector. The bus driver initializes only entry 0 of
++this capability if pci_enable_msi(...) is called successfully by
++the device driver.
++
++5.3 Configuring for MSI-X support
++
++Both the MSI capability structure and the MSI-X capability structure
++share the same above semantics; however, due to the ability of the
++system software to configure each vector of the MSI-X capability
++structure with an independent message address and message data, the
++non-contiguous fashion in vector assignment of the existing Linux
++kernel has no impact on supporting multiple messages on an MSI-X
++capable device functions. By default, as mentioned above, ONE vector
++should be always allocated to the MSI-X capability structure at
++entry 0. The bus driver does not initialize other entries of the
++MSI-X table.
++
++Note that the PCI subsystem should have full control of a MSI-X
++table that resides in Memory Space. The software device driver
++should not access this table.
++
++To request for additional vectors, the device software driver should
++call function msi_alloc_vectors(). It is recommended that the
++software driver should call this function once during the
++initialization phase of the device driver.
++
++The function msi_alloc_vectors(), once invoked, enables either
++all or nothing, depending on the current availability of vector
++resources. If no vector resources are available, the device function
++still works with ONE vector. If the vector resources are available
++for the number of vectors requested by the driver, this function
++will reconfigure the MSI-X capability structure of the device with
++additional messages, starting from entry 1. To emphasize this
++reason, for example, the device may be capable for supporting the
++maximum of 32 vectors while its software driver usually may request
++4 vectors.
++
++For each vector, after this successful call, the device driver is
++responsible to call other functions like request_irq(), enable_irq(),
++etc. to enable this vector with its corresponding interrupt service
++handler. It is the device driver's choice to have all vectors shared
++the same interrupt service handler or each vector with a unique
++interrupt service handler.
++
++In addition to the function msi_alloc_vectors(), another function
++msi_free_vectors() is provided to allow the software driver to
++release a number of vectors back to the vector resources. Once
++invoked, the PCI subsystem disables (masks) each vector released.
++These vectors are no longer valid for the hardware device and its
++software driver to use. Like free_irq, it recommends that the
++device driver should also call msi_free_vectors to release all
++additional vectors previously requested.
++
++int msi_alloc_vectors(struct pci_dev *dev, int *vector, int nvec)
++
++This API enables the software driver to request the PCI subsystem
++for additional messages. Depending on the number of vectors
++available, the PCI subsystem enables either all or nothing.
++
++Argument dev points to the device (pci_dev) structure.
++Argument vector is a pointer of integer type. The number of
++elements is indicated in argument nvec.
++Argument nvec is an integer indicating the number of messages
++requested.
++A return of zero indicates that the number of allocated vector is
++successfully allocated. Otherwise, indicate resources not
++available.
++
++int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec)
++
++This API enables the software driver to inform the PCI subsystem
++that it is willing to release a number of vectors back to the
++MSI resource pool. Once invoked, the PCI subsystem disables each
++MSI-X entry associated with each vector stored in the argument 2.
++These vectors are no longer valid for the hardware device and
++its software driver to use.
++
++Argument dev points to the device (pci_dev) structure.
++Argument vector is a pointer of integer type. The number of
++elements is indicated in argument nvec.
++Argument nvec is an integer indicating the number of messages
++released.
++A return of zero indicates that the number of allocated vectors
++is successfully released. Otherwise, indicates a failure.
++
++5.4 Hardware requirements for MSI support
++MSI support requires support from both system hardware and
++individual hardware device functions.
++
++5.4.1 System hardware support
++Since the target of MSI address is the local APIC CPU, enabling
++MSI support in Linux kernel is dependent on whether existing
++system hardware supports local APIC. Users should verify their
++system whether it runs when CONFIG_X86_LOCAL_APIC=y.
++
++In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
++however, in UP environment, users must manually set
++CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
++CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and
++the option for MSI-capable device drivers to selectively enable
++MSI (using pci_enable_msi as desribed below).
++
++Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI
++vector is allocated new during runtime and MSI support does not
++depend on BIOS support. This key independency enables MSI support
++on future IOxAPIC free platform.
++
++5.4.2 Device hardware support
++The hardware device function supports MSI by indicating the
++MSI/MSI-X capability structure on its PCI capability list. By
++default, this capability structure will not be initialized by
++the kernel to enable MSI during the system boot. In other words,
++the device function is running on its default pin assertion mode.
++Note that in many cases the hardware supporting MSI have bugs,
++which may result in system hang. The software driver of specific
++MSI-capable hardware is responsible for whether calling
++pci_enable_msi or not. A return of zero indicates the kernel
++successfully initializes the MSI/MSI-X capability structure of the
++device funtion. The device function is now running on MSI mode.
++
++5.5 How to tell whether MSI is enabled on device function
++
++At the driver level, a return of zero from pci_enable_msi(...)
++indicates to the device driver that its device function is
++initialized successfully and ready to run in MSI mode.
++
++At the user level, users can use command 'cat /proc/interrupts'
++to display the vector allocated for the device and its interrupt
++mode, as shown below.
++
++           CPU0       CPU1
++  0:     324639          0    IO-APIC-edge  timer
++  1:       1186          0    IO-APIC-edge  i8042
++  2:          0          0          XT-PIC  cascade
++ 12:       2797          0    IO-APIC-edge  i8042
++ 14:       6543          0    IO-APIC-edge  ide0
++ 15:          1          0    IO-APIC-edge  ide1
++169:          0          0   IO-APIC-level  uhci-hcd
++185:          0          0   IO-APIC-level  uhci-hcd
++193:        138         10         PCI MSI  aic79xx
++201:         30          0         PCI MSI  aic79xx
++225:         30          0   IO-APIC-level  aic7xxx
++233:         30          0   IO-APIC-level  aic7xxx
++NMI:          0          0
++LOC:     324553     325068
++ERR:          0
++MIS:          0
++
++6. FAQ
++
++Q1. Are there any limitations on using the MSI?
++
++A1. If the PCI device supports MSI and conforms to the
++specification and the platform supports the APIC local bus,
++then using MSI should work.
++
++Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
++AMD processors)? In P3 IPI's are transmitted on the APIC local
++bus and in P4 and Xeon they are transmitted on the system
++bus. Are there any implications with this?
++
++A2. MSI support enables a PCI device sending an inbound
++memory write (0xfeexxxxx as target address) on its PCI bus
++directly to the FSB. Since the message address has a
++redirection hint bit cleared, it should work.
++
++Q3. The target address 0xfeexxxxx will be translated by the
++Host Bridge into an interrupt message. Are there any
++limitations on the chipsets such as Intel 8xx, Intel e7xxx,
++or VIA?
++
++A3. If these chipsets support an inbound memory write with
++target address set as 0xfeexxxxx, as conformed to PCI
++specification 2.3 or latest, then it should work.
++
++Q4. From the driver point of view, if the MSI is lost because
++of the errors occur during inbound memory write, then it may
++wait for ever. Is there a mechanism for it to recover?
++
++A4. Since the target of the transaction is an inbound memory
++write, all transaction termination conditions (Retry,
++Master-Abort, Target-Abort, or normal completion) are
++supported. A device sending an MSI must abide by all the PCI
++rules and conditions regarding that inbound memory write. So,
++if a retry is signaled it must retry, etc... We believe that
++the recommendation for Abort is also a retry (refer to PCI
++specification 2.3 or latest).
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/must-fix.txt	2003-10-05 00:33:51.000000000 -0700
+@@ -0,0 +1,354 @@
++
++Must-fix bugs
++=============
++
++drivers/char/
++~~~~~~~~~~~~~
++
++o TTY locking is broken.
++
++  o see FIXME in do_tty_hangup().  This causes ppp BUGs in local_bh_enable()
++
++  o Other problems: aviro, dipankar, Alan have details.
++
++  o somebody will have to document the tty driver and ldisc API
++
++o Lack of test cases and/or stress tests is a problem.  Contributions and
++  suggestions are sought.
++
++o Lots of drivers are using cli/sti and are broken.
++
++drivers/tty
++~~~~~~~~~~~
++
++o viro: we need to fix refcounting for tty_driver (oopsable race, must fix
++  anyway, hopefully about a week until it's merged) then we can do
++  tty/misc/upper levels of sound.
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o ideraid hasn't been ported to 2.5 at all yet.
++
++  We need to understand whether the proposed BIO split code will suffice
++  for this.
++
++o CD burning.  There are still a few quirks to solve wrt SG_IO and ide-cd.
++
++  Jens: The basic hang has been solved (double fault in ide-cd), there still
++  seems to be some cases that don't work too well.  Don't really have a
++  handle on those :/
++
++o lmb: Last time I looked at the multipath code (2.5.50 or so) it also
++  looked pretty broken; I plan to port forward the changes we did on 2.4
++  before KS.
++
++drivers/input/
++~~~~~~~~~~~~~~
++
++o rmk: unconverted keyboard/mouse drivers (there's a deadline of 2.6.0
++  currently on these remaining in my/Linus' tree.)
++
++o viro: large absence of locking.
++
++o viro: parport is nearly as bad as that and there the code is more hairy. 
++  IMO parport is more of "figure out what API changes are needed for its
++  users, get them done ASAP, then fix generic layer at leisure"
++
++o (Albert Cahalan) Lots of people (check Google) get this message from the
++  kernel:
++
++  psmouse.c: Lost synchronization, throwing 2 bytes away.
++
++  (the number of bytes will be 1, 2, or 3)
++
++  At work, I get it when there is heavy NFS traffic.  The mouse goes crazy,
++  jumping around and doing random cut-and-paste all over everything.  This
++  is with a decently fast and modern PC.
++
++o There seem to be too many reports of keyboards and mice failing or acting
++  strangely.
++
++
++drivers/misc/
++~~~~~~~~~~~~~
++
++o rmk: UCB1[23]00 drivers, currently sitting in drivers/misc in the ARM
++  tree.  (touchscreen, audio, gpio, type device.)
++
++  These need to be moved out of drivers/misc/ and into real places
++
++o viro: actually, misc.c has a good chance to die.  With cdev-cidr that's
++  trivial.
++
++drivers/net/
++~~~~~~~~~~~~
++
++o rmk: network drivers.  ARM people like to add tonnes of #ifdefs into
++  these to customise them to their hardware platform (eg, chip access
++  methods, addresses, etc.) I cope with this by not integrating them into my
++  tree.  The result is that many ARM platforms can't be built from even my
++  tree without extra patches.  This isn't sane, and has bred a culture of
++  network drivers not being submitted.  I don't see this changing for 2.6
++  though.
++
++drivers/net/irda/
++~~~~~~~~~~~~~~~~~
++
++o dongle drivers need to be converted to sir-dev
++
++o irport need to be converted to sir-kthread
++
++o new drivers (irtty-sir/smsc-ircc2/donauboe) need more testing
++
++o rmk: Refuse IrDA initialisation if sizeof(structures) is incorrect (I'm
++  not sure if we still need this; I think gcc 2.95.3 on ARM shows this
++  problem though.)
++
++drivers/pci/
++~~~~~~~~~~~~
++
++o alan: Some cardbus crashes the system
++
++  (bugzilla, please?)
++
++drivers/pcmcia/
++~~~~~~~~~~~~~~~
++
++o alan: This is a locking disaster.
++
++  (rmk, brodo: in progress)
++
++drivers/pld/
++~~~~~~~~~~~~
++
++o rmk: EPXA (ARM platform) PLD hotswap drivers (drivers/pld)
++
++  (rmk: will work out what to do here.  maybe drivers/arm/)
++
++drivers/video/
++~~~~~~~~~~~~~~
++
++o Lots of drivers don't compile, others do but don't work.
++
++drivers/scsi/
++~~~~~~~~~~~~~
++
++o hch: large parts of the locking are hosed or not existant
++
++  (Mike Anderson, Patrick Mansfield, Badari Pulavarty)
++
++  o shost->my_devices isn't locked down at all
++
++  o there are lots of members of struct Scsi_Host/scsi_device/scsi_cmnd
++    with very unclear locking, many of them probably want to become
++    atomic_t's or bitmaps (for the 1bit bitfields).
++
++  o there's lots of volatile abuse in the scsi code that needs to be
++    thought about.
++
++  o there's some global variables incremented without any locks
++
++o Convert am53c974, dpt_i2o, initio and pci2220i to DMA-mapping
++
++o Make inia100, cpqfc, pci2000 and dc390t compile
++
++o Convert
++
++   wd33c99 based: a2091 a3000 gpv11 mvme174 sgiwd93
++
++   53c7xx based: amiga7xxx bvme6000 mvme16x initio am53c974 pci2000
++   pci2220i dc390t
++
++  To new error handling
++
++  It also might be possible to shift the 53c7xx based drivers over to
++  53c700 which does the new EH stuff, but I don't have the hardware to check
++  such a shift.
++
++  For the non-compiling stuff, I've probably missed a few that just aren't
++  compilable on my platforms, so any updates would be welcome.  Also, are
++  some of our non-compiling or unconverted drivers obsolete?
++
++o rmk: I have a pending todo: I need to put the scsi error handling through
++  a workout on my scsi bus from hell to make sure it does the right thing
++  and doesn't get wedged.
++
++o James B: USB hot-removal crash: "It's a known scsi refcounting issue."
++
++fs/
++~~~
++
++o AIO/direct-IO writes can race with truncate and wreck filesystems.
++  (Badari has a patch)
++
++o hch: devfs: there's a fundamental lookup vs devfsd race that's only
++  fixable by introducing a lookup vs devfs deadlock.  I can't see how this is
++  fixable without getting rid of the current devfsd design.  Mandrake seems
++  to have a workaround for this so this is at least not triggered so easily,
++  but that's not what I'd consider a fix..
++
++o viro: fs/char_dev.c needs removal of aeb stuff and merge of cdev-cidr. 
++  In progress.
++
++o forward-port sct's O_DIRECT fixes (Badari has a patch)
++
++o viro: there is some generic stuff for namei/namespace/super, but that's a
++  slow-merge and can go in 2.6 just fine
++
++o andi: also soft needs to be fixed - there are quite a lot of
++  uninterruptible waits in sunrpc/nfs
++
++o trond: NFS has a mmap-versus-truncate problem
++
++kernel/sched.c
++~~~~~~~~~~~~~~
++
++o Starvation, general interactivity need close monitoring.
++
++kernel/
++~~~~~~~
++
++o Alan: 32bit uid support is *still* broken for process accounting.
++
++  Create a 32bit uid, turn accounting on.  Shock horror it doesn't work
++  because the field is 16bit.  We need an acct structure flag day for 2.6
++  IMHO
++
++  (alan has patch)
++
++o viro: core sysctl code is racy.  And its interaction wiuth sysfs
++
++o (ingo) rwsems (on x86) are limited to 32766 waiting processes.  This
++  means that setting pid_max to above 32K is unsafe :-(
++
++  An option is to use CONFIG_RWSEM_GENERIC_SPINLOCK variant all the time,
++  for all archs, and not inline any part of the ops.
++
++lib/kobject.c
++~~~~~~~~~~~~~
++
++o kobject refcounting (comments from Al Viro):
++
++  _anything_ can grab a temporary reference to kobject.  IOW, if kobject is
++  embedded into something that could be freed - it _MUST_ have a destructor
++  and that destructor _MUST_ be the destructor for containing object.
++
++  Any violation of the above (and we already have a bunch of those) is a
++  user-triggerable memory corruption.
++
++  We can tolerate it for a while in 2.5 (e.g.  during work on susbsystem we
++  can decide to switch to that way of handling objects and have subsystem
++  vulnerable for a while), but all such windows must be closed before 2.6
++  and during 2.6 we can't open them at all.
++
++o All block drivers which control multiple gendisks with a single
++  request_queue are broken, due to one-to-one assumptions in the request
++  queue sysfs hookup.
++
++mm/
++~~~
++
++o GFP_DMA32 (or something like that).  Lots of ideas.  jejb, zaitcev,
++  willy, arjan, wli.
++
++  Specifically, 64-bit systems need to be able to enforce 32-bit addressing
++  limits for device metadata like network cards' ring buffers and SCSI
++  command descriptors.
++
++o access_process_vm() doesn't flush right.  We probably need new flushing
++  primitives to do this (davem?)
++
++
++modules
++~~~~~~~
++
++  (Rusty)
++
++net/
++~~~~
++
++  (davem)
++
++o UDP apps can in theory deadlock, because the ip_append_data path can end
++  up sleeping while the socket lock is held.
++
++  It is OK to sleep with the socket held held, normally.  But in this case
++  the sleep happens while waiting for socket memory/space to become
++  available, if another context needs to take the socket lock to free up the
++  space we could hang.
++
++  I sent a rough patch on how to fix this to Alexey, and he is analyzing
++  the situation.  I expect a final fix from him next week or so.
++
++o Semantics for IPSEC during operations such as TCP connect suck currently.
++
++  When we first try to connect to a destination, we may need to ask the
++  IPSEC key management daemon to resolve the IPSEC routes for us.  For the
++  purposes of what the kernel needs to do, you can think of it like ARP.  We
++  can't send the packet out properly until we resolve the path.
++
++  What happens now for IPSEC is basically this:
++
++  O_NONBLOCK: returns -EAGAIN over and over until route is resolved
++
++  !O_NONBLOCK: Sleeps until route is resolved
++
++  These semantics are total crap.  The solution, which Alexey is working
++  on, is to allow incomplete routes to exist.  These "incomplete" routes
++  merely put the packet onto a "resolution queue", and once the key manager
++  does it's thing we finish the output of the packet.  This is precisely how
++  ARP works.
++
++  I don't know when Alexey will be done with this.
++
++net/*/netfilter/
++~~~~~~~~~~~~~~~~
++
++  (Rusty)
++
++o Rework conntrack hashing.
++
++o Module relationship bogosity fix (trivial, have patch).
++
++sound/
++~~~~~~
++
++o rmk: several OSS drivers for SA11xx-based hardware in need of
++  ALSA-ification and L3 bus support code for these.
++
++o rmk: linux/sound/drivers/mpu401/mpu401.c and
++  linux/sound/drivers/virmidi.c complained about 'errno' at some time in the
++  past, need to confirm whether this is still a problem.
++
++o rmk: need to complete ALSA-ification of the WaveArtist driver for both
++  NetWinder and other stuff (there's some fairly fundamental differences in
++  the way the mixer needs to be handled for the NetWinder.)
++
++
++  (Issues with forward-porting 2.4 bugfixes.)
++  (Killing off OSS is 2.7 material)
++
++
++global
++~~~~~~
++
++o 64-bit dev_t.  Seems almost ready, but it's not really known how much
++  work is still to do.  Patches exist in -mm but with the recent rise of the
++  neo-viro I'm not sure where things are at.
++
++o Lots of 2.4 fixes including some security are not in 2.5
++
++o There are about 60 or 70 security related checks that need doing
++  (copy_user etc) from Stanford tools.  (badari is looking into this, and
++  hollisb)
++
++o A couple of hundred real looking bugzilla bugs
++
++o viro: cdev rework.  Main group is pretty stable and I hope to feed it to
++  Linus RSN.  That's cdev-cidr and ->i_cdev/->i_cindex stuff
++
++o Athlon prefetch oopses sometimes.  It is currently disabled, and needs to
++  be fixed.
++
++
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/should-fix.txt	2003-10-05 00:33:52.000000000 -0700
+@@ -0,0 +1,611 @@
++Not-ready features and speedups
++===============================
++
++Legend:
++
++PRI1:	We're totally lame if this doesn't get in
++PRI2:	Would be nice
++PRI3:	Not very important
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o Framework for selecting IO schedulers.  This is the main one really. 
++  Once this is in place we can drop in new schedulers any old time, no risk.
++  Nick Piggin has code for this.
++
++  PRI1
++
++o viro: paride drivers need a big cleanup
++
++  PRI2
++
++drivers/char/rtc/
++~~~~~~~~~~~~~~~~~
++
++o rmk, trini: add support for alarms to the existing generic rtc driver.
++
++  PRI2
++
++console drivers
++~~~~~~~~~~~~~~~
++  (Pavel Machek <pavel@ucw.cz>)
++
++o There are few must-fix bugs in cursor handling.
++
++o Play with gpm selection for a while and your cursor gets corrupted with
++  random dots. Ouch.
++
++device mapper
++~~~~~~~~~~~~~
++
++o ioctl interface cleanup patch is ready (redo the structure layouts)
++
++  PRI1
++
++o A port of the 2.4 snapshot and mirror targets is in progress
++
++  PRI1
++
++o the fs interface to dm needs to be redone.  gregkh was going to work on
++  this.  viro is interested in seeing work thus-far.
++
++  PRI2
++
++drivers/net/wireless/
++~~~~~~~~~~~~~~~~~~~~~
++
++  (Jean Tourrilhes <jt@bougret.hpl.hp.com>)
++
++o get latest orinoco changes from David.
++
++  PRI1
++
++o get the latest airo.c fixes from CVS.  This will hopefully fix problems
++  people have reported on the LKML.
++
++  PRI1
++
++o get HostAP driver in the kernel.  No consolidation of the 802.11
++  management across driver can happen until this one is in (which is probably
++  2.7.X material).  I think Jouni is mostly ready but didn't find time for
++  it.
++
++  PRI2
++
++o get more wireless drivers into the kernel.  The most "integrable" drivers
++  at this point seem the NWN driver, Pavel's Spectrum driver and the Atmel
++  driver.
++
++  PRI1
++
++o The last two drivers mentioned above are held up by firmware issues (see
++  flamewar on LKML a few days ago).  So maybe fixing those firmware issues
++  should be a requirement for 2.6.X, because we can expect more wireless
++  devices to need firmware upload at startup coming to market.
++
++  (in progress?)
++
++  PRI1
++
++drivers/usb/gadget/
++~~~~~~~~~~~~~~~~~~~
++
++o rmk: SA11xx USB client/gadget code (David B has been doing some work on
++  this, and keeps trying to prod me, but unfortunately I haven't had the time
++  to look at his work, sorry David.)
++
++  PRI3
++
++fs/
++~~~
++
++o ext3 and ext2 block allocators have serious failure modes - interleaved
++  allocations.
++
++  PRI3
++
++o Integrate Chris Mason's 2.4 reiserfs ordered data and data journaling
++  patches.  They make reiserfs a lot safer.
++
++  Ordered: PRI2
++  data journalled: PRI3
++
++o (Trond:) Yes: I'm still working on an atomic "open()", i.e.  one
++           where we short-circuit the usual VFS path_walk() + lookup() +
++           permission() + create() + ....  bullsh*t...
++
++           I have several reasons for wanting to do this (all of
++           them related to NFS of course, but much of the reasoning applies
++           to *all* networked file systems).
++
++   1) The above sequence is simply not atomic on *any* networked
++      filesystem.
++
++   2) It introduces a sh*tload of completely unnecessary RPC calls (why
++      do a 'permission' RPC call when the server is in *any* case going to
++      tell you whether or not this operations is allowed.  Why do a
++      'lookup()' when the 'create()' call can be made to tell you whether or
++      not a file already exists).
++
++   3) It is incompatible with some operations: the current create()
++      doesn't pass an 'EXCLUSIVE' flag down to the filesystems.
++
++   4) (NFS specific?) open() has very different cache consistency
++      requirements when compared to most other VFS operations.
++
++   I'd very much like for something like Peter Braam's 'lookup with
++   intent' or (better yet) for a proper dentry->open() to be integrated with
++   path_walk()/open_namei().  I'm still working on the latter (Peter has
++   already completed the lookup with intent stuff).
++
++   (All this is in progress, see http://www.fys.uio.no/~trondmy/src)
++
++   (Is awaiting Pater Braam's intent patches.  Applicable to CIFS)
++
++   PRI2 (?)
++
++o (Chuck Lever <cel@citi.umich.edu>): NFS O_DIRECT support must be
++  completed.  The best approach is to fall back to something like the 2.4 NFS
++  O_DIRECT support, which issues RPCs synchronously and uses the RPC
++  completion mechanism to wait for I/O completion.
++
++  PRI2
++
++o viro: cleaning up options-parsers in filesystems.  (patch exists, needs
++  porting).
++
++  PRI2
++
++o aio: fs IO isn't async at present.  suparna has restart patches, they're
++  in -mm.  Need to get Ben to review/comment.
++
++  PRI1.
++
++o drepper: various filesystems use ->pid wrongly
++
++kernel/
++~~~~~~~
++
++o rusty: Zippel's Reference count simplification.  Tricky code, but cuts
++  about 120 lines from module.c.  Patch exists, needs stressing.
++
++  PRI3
++
++o rusty: Fix module-failed-init races by starting module "disabled".  Patch
++  exists, requires some subsystems (ie.  add_partition) to explicitly say
++  "make module live now".  Without patch we are no worse off than 2.4 etc.  
++
++  PRI1
++
++o Integrate userspace irq balancing daemon.
++
++  PRI2
++
++o kexec.  Seems to work, was in -mm.
++
++  PRI3
++
++o rmk: lib/inflate.c must not use static variables (causes these to be
++  referenced via GOTOFF relocations in PIC decompressor.  We have a PIC
++  decompressor to avoid having to hard code a per platform zImage link
++  address into the makefiles.)
++
++  PRI2
++
++o klibc merge?
++
++  PRI2
++
++mm/
++~~~
++
++o objrmap: concerns over page reclaim performance at high sharing levels,
++  and interoperation with nonlinear mappings is hairy.
++
++o oxymoron's async write-error-handling patch
++
++  PRI1
++
++o dropbehind for large files
++
++  PRI2
++
++net/
++~~~~
++
++  (davem)
++
++o Real serious use of IPSEC is hampered by lack of MPLS support.  MPLS is a
++  switching technology that works by switching based upon fixed length labels
++  prepended to packets.  Many people use this and IPSEC to implement VPNs
++  over public networks, it is also used for things like traffic engineering.
++
++  A good reference site is:
++
++	http://www.mplsrc.com/
++
++  Anyways, an existing (crappy) implementation exists.  I've almost
++  completed a rewrite, I should have something in the tree next week.
++
++  PRI1
++
++o Sometimes we generate IP fragments when it truly isn't necessary.
++
++  The way IP fragmentation is specified, each fragment must be modulo 8
++  bytes in length.  So suppose the device has an MTU that is not 0 modulo 8,
++  ethernet even classifies in this way.  1500 == (8 * 187) + 4
++
++  Our IP fragmenting engine can fragment on packets that are sized within
++  the last modulo 8 bytes of the MTU.  This happens in obscure cases, but it
++  does happen.
++
++  I've proposed a fix to Alexey, whereby very late in the output path we
++  check the packet, if we fragmented but the data length would fit into the
++  MTU we unfragment the packet.
++
++  This is low priority, because technically it creates suboptimal behavior
++  rather than mis-operation.
++
++  PRI1
++
++net/*/netfilter/
++~~~~~~~~~~~~~~~~
++
++o Lots of misc. cleanups, which are happening slowly.
++
++  PRI2
++
++power management
++~~~~~~~~~~~~~~~~
++
++o PM code in mainline is currently b0rked. Fixes in -mm
++
++  PRI1
++
++o Pat and Pavel disagree over swsusp. Need to sort that out.
++
++  PRI2
++
++o Frame buffer restore codepaths (that requires some deep PCI magic)
++
++  PRI2
++
++o XFree86 hooks
++
++  PRI2
++
++o AGP restoration
++
++  PRI2
++
++o DRI restoration
++
++  (davej/Alan: not super-critical, can crash laptop on restore.  davej
++  looking into it.)
++
++  PRI2
++
++o IDE suspend/resume without races (Ben is looking at this a little)
++
++  PRI2
++
++o Pat: There are already CPU device structures; MTRRs should be a
++  dynamically registered interface of CPUs, which implies there needs
++  to be some other glue to know that there are MTRRs that need to be
++  saved/restored.
++
++  PRI1
++
++global
++~~~~~~
++
++o We need a kernel side API for reporting error events to userspace (could
++  be async to 2.6 itself)
++
++  (Prototype core based on netlink exists)
++
++  PRI2
++
++o Kai: Introduce a sane, easy and standard way to build external modules
++  - make clean and make modules_install are both broken
++
++  PRI2
++
++drivers
++~~~~~~~
++
++o Alan: Cardbus/PCMCIA requires all Russell's stuff is merged to do
++  multiheader right and so on
++
++  PRI1
++
++drivers/acpi/
++~~~~~~~~~~~~~
++
++o Fix acpi for all newer IBM Thinkpads see
++  http://bugme.osdl.org/show_bug.cgi?id=1038 for more information
++
++o alan: VIA APIC stuff is one bit of this, there are also some other
++  reports that were caused by ACPI not setting level v edge trigger some
++  times
++
++  PRI1
++
++o mochel: it seems the acpi irq routing code could use a serious rewrite.
++
++  grover: The problem is the ACPI irq routing code is trying to piggyback
++  on the existing MPS-specific data structures, and it's generally a hack. 
++  So yes mochel is right, but it is also purging MPS-ities from common code
++  as well.  I've done some preliminary work in this area and it doesn't seem
++  to break anything (yet) but a rewrite in this area imho should not be
++  rushed out the door.  And, I think the above bugs can be fixed w/o the
++  rewrite.
++
++  PRI2
++
++o mochel: ACPI suspend doesn't work.  Important, not cricital.  Pat is
++  working it.
++
++  PRI2
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o Floppy is almost unusably buggy still
++
++  akpm: we need more people to test & report.
++
++  alan: "Floppy has worked for me since the patches that went in 2.5.69-ac
++  and I think -bk somewhere"
++
++  PRI1
++
++drivers/char/
++~~~~~~~~~~~~~
++
++
++drivers/ide/
++~~~~~~~~~~~~
++
++  (Alan)
++
++o IDE PIO has occasional unexplained PIO disk eating reports
++
++  PRI1
++
++o IDE has multiple zillions of races/hangs in 2.5 still
++
++  PRI1
++
++o IDE scsi needs rewriting
++
++  PRI2
++
++o IDE needs significant reworking to handle Simplex right
++
++  PRI2
++
++o IDE hotplug handling for 2.5 is completely broken still
++
++  PRI2
++
++o There are lots of other IDE bugs that wont go away until the taskfile
++  stuff is included, the locking bugs that allow any user to hang the IDE
++  layer in 2.5, and some other updates are forward ported.  (esp.  HPT372N).
++
++  PRI1
++
++drivers/isdn/
++~~~~~~~~~~~~~
++
++  (Kai, rmk)
++
++o isdn_tty locking is completely broken (cli() and friends)
++
++  PRI2
++
++o fix other drivers
++
++  PRI2
++
++o lots more cleanups, adaption to recent APIs etc
++
++  PRI3
++
++o fixup tty-based ISDN drivers which provide TIOCM* ioctls (see my recent
++  3-set patch for serial stuff)
++
++  Alternatively, we could re-introduce the fallback to driver ioctl parsing
++  for these if not enough drivers get updated.
++
++  PRI3
++
++drivers/net/
++~~~~~~~~~~~~
++
++o davej: Either Wireless network drivers or PCMCIA broke somewhen.  A
++  configuration that worked fine under 2.4 doesn't receive any packets.  Need
++  to look into this more to make sure I don't have any misconfiguration that
++  just 'happened to work' under 2.4
++
++  PRI1
++
++drivers/scsi/
++~~~~~~~~~~~~~
++
++o jejb: qlogic -
++
++  o Merge the feral driver.  It covers all qlogic chips: 1020 all the way
++    up to 23xxx. http://linux-scsi.bkbits.net/scsi-isp-2.5
++
++  o qla2xxx: only for FC chips.  Has significant build issues.  hch
++    promises to send me a "must fix" list for this.
++    http://linux-scsi.bkbits.net/scsi-qla2xxx-2.5
++
++  PRI2
++
++arch/i386/
++~~~~~~~~~~
++
++o Also PC9800 merge needs finishing to the point we want for 2.6 (not all).
++
++  PRI3
++
++o davej: PAT support (for mtrr exhaustion w/ AGP)
++
++  PRI2
++
++o 2.5.x won't boot on some 440GX
++
++  alan: Problem understood now, feasible fix in 2.4/2.4-ac.  (440GX has two
++  IRQ routers, we use the $PIR table with the PIIX, but the 440GX doesnt use
++  the PIIX for its IRQ routing).  Fall back to BIOS for 440GX works and Intel
++  concurs.
++
++  PRI1
++
++o 2.5.x doesn't handle VIA APIC right yet.
++
++  1. We must write the PCI_INTERRUPT_LINE
++
++  2. We have quirk handlers that seem to trash it.
++
++  PRI1
++
++o ACPI needs the relax patches merging to work on lots of laptops
++
++  alan: ACPI relax stuff is in 2.4-ac, compaq workaround is in next -ac
++  coming.  These seem to deliver the goods - toshibas now work a treat.  Some
++  other relax bits are being discussed (assume local0 starts 0 etc) and
++  progress looks great.  This can occur before 2.6 or during.
++
++  PRI1
++
++o ECC driver questions are not yet sorted (DaveJ is working on this) (Dan
++  Hollis)
++
++  alan: ECC - I have some test bits from Dan's stuff - they need no kernel
++  core changes for most platforms.  That means we can treat it as a random
++  driver merge.
++
++  PRI3
++
++o alan: 2.4 has some fixes for tsc handling bugs.  One where some bioses in
++  SMM mode mess up our toggle on the time high/low or mangle the counter and
++  one where a few chips need religious use of _p for timer access and we
++  don't do that.  This is forward porting little bits of fixup.
++
++  ACPI HZ stuff we can't trap - a lot of ACPI is implemented as outb's
++  triggering SMM traps
++
++  PRI1
++
++arch/x86_64/
++~~~~~~~~~~~~
++
++  (Andi)
++
++o time handling is broken. Need to move up 2.4 time.c code.
++
++  PRI1
++
++o NMI watchdog seems to tick too fast
++
++  PRI2
++
++o not very well tested. probably more bugs lurking.
++
++  PRI1
++
++o need to coredump 64bit vsyscall code with dwarf2
++
++  PRI2
++
++o Consider merging of Erich Focht's very clean and simple homenode NUMA
++  scheduler (I have my own in 2.4, but Erich's 2.5 version is much cleaner)
++
++  PRI2
++  
++o Consider port of the Simple NUMA API from 2.4/homenode.
++
++  PRI3
++
++o move 64bit signal trampolines into vsyscall code and add dwarf2 for it.
++  (in progress)
++
++  PRI1
++
++o describe kernel assembly with dwarf2 annotations for kgdb
++
++  PRI3
++
++arch/alpha/
++~~~~~~~~~~~
++
++o rth: Ptrace writes are broken.  This means we can't (reliably) set
++  breakpoints or modify variables from gdb.
++
++  PRI1
++
++arch/arm/
++~~~~~~~~~
++
++o rmk: missing raw keyboard translation tables for all ARM machines. 
++  Haven't even looked into this at all.  This could be messy since there
++  isn't an ARM architecture standard.  I'm presently hoping that it won't be
++  an issue.  If it does, I guess we'll see drivers/char/keyboard.c explode.
++
++  PRI2
++
++arch/others/
++~~~~~~~~~~~~
++
++o SH needs resyncing, as do some other ports. SH64 needs merging.
++  No impact on mainstream platforms hopefully.
++
++  PRI2
++
++arch/s390/
++~~~~~~~~~
++
++o A nastly memory management problem causes random crashes.  These appear
++  to be fixed/hidden by the objrmap patch, more investigation is needed.
++
++  PRI1
++
++drivers/s390/
++~~~~~~~~~~~~~
++
++o Early userspace and 64 bit dev_t will allow the removal of most of
++  dasd_devmap.c and dasd_genhd.c.
++
++  PRI2
++
++o The 3270 console driver needs to be replaced with a working one
++  (prototype is there, needs to be finished).
++
++  PRI2
++
++o Minor interface changes are pending in cio/ when the z990 machines are
++  out.
++
++  PRI2
++
++o Jan Glauber is working on a fix for the timer issues related to running
++  on virtualized CPUs (wall-clock vs.  cpu time).
++
++  PRI1
++
++o a block device driver for ramdisks shared among virtual machines
++
++  PRI3
++
++o driver for crypto hardware
++
++  PRI3
++
++o 'claw' network device driver
++
++  PRI3
++
+--- linux-2.6.0-test6/Documentation/zorro.txt	2003-07-27 12:14:38.000000000 -0700
++++ 25/Documentation/zorro.txt	2003-10-05 00:33:23.000000000 -0700
+@@ -2,7 +2,7 @@
+ 		----------------------------------------
+ 
+ Written by Geert Uytterhoeven <geert@linux-m68k.org>
+-Last revised: February 27, 2000
++Last revised: September 5, 2003
+ 
+ 
+ 1. Introduction
+@@ -75,7 +75,7 @@ they are CPU physical addresses as well.
+ The treatment of these regions depends on the type of Zorro space:
+ 
+   - Zorro II address space is always mapped and does not have to be mapped
+-    explicitly using ioremap().
++    explicitly using z_ioremap().
+     
+     Conversion from bus/physical Zorro II addresses to kernel virtual addresses
+     and vice versa is done using:
+@@ -83,22 +83,20 @@ The treatment of these regions depends o
+ 	virt_addr = ZTWO_VADDR(bus_addr);
+ 	bus_addr = ZTWO_PADDR(virt_addr);
+ 
+-  - Zorro III address space must be mapped explicitly using ioremap() first
++  - Zorro III address space must be mapped explicitly using z_ioremap() first
+     before it can be accessed:
+  
+-	virt_addr = ioremap(bus_addr, size);
++	virt_addr = z_ioremap(bus_addr, size);
+ 	...
+-	iounmap(virt_addr);
++	z_iounmap(virt_addr);
+ 
+ 
+ 5. References
+ -------------
+ 
+ linux/include/linux/zorro.h
+-linux/include/linux/ioport.h
+-linux/include/asm-m68k/io.h
+-linux/include/asm-m68k/amigahw.h
+-linux/include/asm-ppc/io.h
++linux/include/asm-{m68k,ppc}/zorro.h
++linux/include/linux/zorro_ids.h
+ linux/drivers/zorro
+ /proc/bus/zorro
+ 
+--- linux-2.6.0-test6/drivers/acorn/block/fd1772.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/acorn/block/fd1772.c	2003-10-05 00:34:00.000000000 -0700
+@@ -365,13 +365,12 @@ static void finish_fdc_done(int dummy);
+ static void floppy_off(unsigned int nr);
+ static void setup_req_params(int drive);
+ static void redo_fd_request(void);
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int
+ 		    cmd, unsigned long param);
+ static void fd_probe(int drive);
+ static int fd_test_drive_present(int drive);
+ static void config_types(void);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
+ static void do_fd_request(request_queue_t *);
+ 
+ /************************* End of Prototypes **************************/
+@@ -1309,11 +1308,9 @@ static int invalidate_drive(struct block
+ 	return 0;
+ }
+ 
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+ 		    unsigned int cmd, unsigned long param)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+-
+ 	switch (cmd) {
+ 	case FDFMTEND:
+ 	case FDFLUSH:
+@@ -1453,10 +1450,11 @@ static void config_types(void)
+  * drive with different device numbers.
+  */
+ 
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	int drive = iminor(inode) & 3;
+-	int type =  iminor(inode) >> 2;
++	struct archy_floppy_struct *p = bdev->bd_disk->private_data;
++	int drive = p - unit;
++	int type =  MINOR(bdev->bd_dev) >> 2;
+ 	int old_dev = fd_device[drive];
+ 
+ 	if (fd_ref[drive] && old_dev != type)
+@@ -1476,10 +1474,13 @@ static int floppy_open(struct inode *ino
+ 		return 0;
+ 
+ 	if (filp->f_mode & 3) {
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		if (filp->f_mode & 2) {
+-			if (unit[drive].wpstat) {
+-				floppy_release(inode, filp);
++			if (p->wpstat) {
++				if (fd_ref[drive] < 0)
++					fd_ref[drive] = 0;
++				else
++					fd_ref[drive]--;
+ 				return -EROFS;
+ 			}
+ 		}
+@@ -1487,10 +1488,10 @@ static int floppy_open(struct inode *ino
+ 	return 0;
+ }
+ 
+-
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	int drive = iminor(inode) & 3;
++	struct archy_floppy_struct *p = disk->private_data;
++	int drive = p - unit;
+ 
+ 	if (fd_ref[drive] < 0)
+ 		fd_ref[drive] = 0;
+--- linux-2.6.0-test6/drivers/acorn/block/mfmhd.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/acorn/block/mfmhd.c	2003-10-05 00:33:54.000000000 -0700
+@@ -1153,9 +1153,9 @@ static int mfm_initdrives(void)
+  * The 'front' end of the mfm driver follows...
+  */
+ 
+-static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
++static int mfm_ioctl(struct block_device *bdev, struct file *file, u_int cmd, u_long arg)
+ {
+-	struct mfm_info *p = inode->i_bdev->bd_disk->private_data;
++	struct mfm_info *p = bdev->bd_disk->private_data;
+ 	struct hd_geometry *geo = (struct hd_geometry *) arg;
+ 	if (cmd != HDIO_GETGEO)
+ 		return -EINVAL;
+@@ -1167,7 +1167,7 @@ static int mfm_ioctl(struct inode *inode
+ 		return -EFAULT;
+ 	if (put_user (p->cylinders, &geo->cylinders))
+ 		return -EFAULT;
+-	if (put_user (get_start_sect(inode->i_bdev), &geo->start))
++	if (put_user (get_start_sect(bdev), &geo->start))
+ 		return -EFAULT;
+ 	return 0;
+ }
+--- linux-2.6.0-test6/drivers/acpi/asus_acpi.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/acpi/asus_acpi.c	2003-10-05 00:33:23.000000000 -0700
+@@ -26,13 +26,17 @@
+  *  Johann Wiesner - Small compile fixes
+  *  John Belmonte  - ACPI code for Toshiba laptop was a good starting point.
+  *
+- *  TODO
++ *  TODO:
+  *  add Fn key status
+- *  Add mode selection on module loading (parameter) -> still necessary ?
++ *  Add mode selection on module loading (parameter) -> still necessary?
+  *  Complete display switching -- may require dirty hacks?
+- *
+  */
+ 
++#include <linux/config.h>
++#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) && defined (MODULE)
++#include <linux/modversions.h>
++#endif
++
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+@@ -41,7 +45,7 @@
+ #include <acpi/acpi_drivers.h>
+ #include <acpi/acpi_bus.h>
+ 
+-#define ASUS_ACPI_VERSION "0.24a"
++#define ASUS_ACPI_VERSION "0.26"
+ 
+ #define PROC_ASUS       "asus"	//the directory
+ #define PROC_MLED       "mled"
+@@ -110,20 +114,24 @@ struct asus_hotk {
+ 	struct model_data *methods;	//methods available on the laptop
+ 	u8 brightness;			//brighness level
+ 	enum {
+-		L2X = 0,	//L200D -> TODO check Q11 (Fn+F8)
+-				//	   Calling this method simply hang the
++		A1X=0,  	//A1340D, A1300F
++		A2X,		//A2500H
++		D1X,		//D1
++		L1X,		//L1400B
++		L2X,		//L2000D -> TODO check Q11 (Fn+F8)
++				//	   Calling this method simply hangs the
+ 				//	   computer, ISMI method hangs the laptop.
+-		L3X,		//L3C
+ 		L3D,		//L3400D
++		L3X,		//L3C
++		L5X,		//L5C TODO this model seems to have one more
++		                //         LED, add support
+ 		M2X,		//M2400E
++		M3N,		//M3700N, but also S1300N -> TODO WLED
+ 		S1X,		//S1300A -> TODO special keys do not work ?
+-		D1X,		//D1
+-		L1X,		//L1400B
+-		A1X, 		//A1340D, A1300F
+-		J1X,		//S200 (J1)
+-				//TODO  A1370D does not seems to have a ATK device 
++		S2X,		//S200 (J1 reported), Victor MP-XP7210
++				//TODO  A1370D does not seem to have an ATK device 
+ 				//	L8400 model doesn't have ATK
+-		END_MODEL,
++		END_MODEL
+ 	} model;		//Models currently supported
+ 	u16 event_count[128];	//count for each event TODO make this better
+ };
+@@ -133,7 +141,8 @@ struct asus_hotk {
+ #define S1X_PREFIX "\\_SB.PCI0.PX40."
+ #define L1X_PREFIX S1X_PREFIX
+ #define A1X_PREFIX "\\_SB.PCI0.ISA.EC0."
+-#define J1X_PREFIX A1X_PREFIX
++#define S2X_PREFIX A1X_PREFIX
++#define M3N_PREFIX "\\_SB.PCI0.SBRG.EC0."
+ 
+ static struct model_data model_conf[END_MODEL] = {
+         /*
+@@ -147,33 +156,43 @@ static struct model_data model_conf[END_
+ 	 * it seems to be a kind of switch, but what for ?
+ 	 *
+ 	 */
++	{"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI",
++	 A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL},
++
++	{"A2X", "MLED", NULL, "WLED", "\\SG66", "\\Q10", "\\BAOF",
++	 "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\CMOD", "SDSP", "\\INFB"},
++
++	{"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", 
++	 "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"},
++
++	{"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", 
++	 L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
++	 
+ 	{"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0", 
+ 	 "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"},
+ 
++	{"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG",
++	 "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"},
++
+ 	{"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32", 
+ 	 L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP", 
+ 	 "\\_SB.PCI0.PCI1.VGAC.NMAP"},
+ 
+-	{"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG",
+-	 "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"},
+-
++	{"L5X", "MLED", NULL, "WLED", "WRED", "\\Q0D", "\\BAOF", 
++	 "\\Q0C","\\Q0B", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"},
++	 
+ 	{"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06", 
+ 	 "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"},
++
++	{"M3N", "MLED", NULL, "WLED", "\\PO33", M3N_PREFIX "_Q10", "\\BKLT", 
++	 M3N_PREFIX "_Q0F", M3N_PREFIX "_Q0E", "SPLV", "GPLV", "\\LBTN", "SDSP", 
++	 "\\ADVG"},
+ 	
+ 	{"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF", 
+ 	 S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
+ 	
+-	{"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", 
+-	 "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"},
+-
+-	{"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", 
+-	 L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
+-
+-	{"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI",
+-	 A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL},
+-
+-	{"J1X", "MLED", "\\MAIL", NULL, NULL, J1X_PREFIX "_Q10", "\\BKLI",
+-	 J1X_PREFIX "_Q0B", J1X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL}
++	{"S2X", "MLED", "\\MAIL", NULL, NULL, S2X_PREFIX "_Q10", "\\BKLI",
++	 S2X_PREFIX "_Q0B", S2X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL}
+ };
+ 
+ /* procdir we use */
+@@ -234,7 +253,7 @@ static int read_acpi_int(acpi_handle han
+ 	output.length = sizeof(out_obj);
+ 	output.pointer = &out_obj;
+ 
+-	status = acpi_evaluate_object(handle, (char*) method, NULL, &output);
++	status = acpi_evaluate_object(handle, (char *) method, NULL, &output);
+ 	*val = out_obj.integer.value;
+ 	return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
+ }
+@@ -249,6 +268,7 @@ proc_read_info(char *page, char **start,
+ 		void *data)
+ {
+ 	int len = 0;
++	int sfun;
+ 	struct asus_hotk *hotk = (struct asus_hotk *) data;
+ 	char buf[16];		//enough for all info
+ 	/*
+@@ -257,28 +277,27 @@ proc_read_info(char *page, char **start,
+ 	 */
+ 
+ 	len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
+-	len +=
+-	    sprintf(page + len, "Model reference    : %s\n",
+-		    hotk->methods->name);
++	len += sprintf(page + len, "Model reference    : %s\n", 
++		       hotk->methods->name);
++	if(read_acpi_int(hotk->handle, "SFUN", &sfun))
++		len += sprintf(page + len, "SFUN value         : 0x%04x\n", sfun);
+ 	if (asus_info) {
+-		snprintf(buf, 5, "%s", asus_info->signature);
+-		len += sprintf(page + len, "ACPI signature     : %s\n", buf);
+ 		snprintf(buf, 16, "%d", asus_info->length);
+-		len += sprintf(page + len, "Table length       : %s\n", buf);
+-		snprintf(buf, 16, "%d", asus_info->revision);
+-		len += sprintf(page + len, "ACPI minor version : %s\n", buf);
++		len += sprintf(page + len, "DSDT length        : %s\n", buf);
+ 		snprintf(buf, 16, "%d", asus_info->checksum);
+-		len += sprintf(page + len, "Checksum           : %s\n", buf);
++		len += sprintf(page + len, "DSDT checksum      : %s\n", buf);
++		snprintf(buf, 16, "%d", asus_info->revision);
++		len += sprintf(page + len, "DSDT revision      : %s\n", buf);
+ 		snprintf(buf, 7, "%s", asus_info->oem_id);
+-		len += sprintf(page + len, "OEM identification : %s\n", buf);
++		len += sprintf(page + len, "OEM id             : %s\n", buf);
+ 		snprintf(buf, 9, "%s", asus_info->oem_table_id);
+ 		len += sprintf(page + len, "OEM table id       : %s\n", buf);
+ 		snprintf(buf, 16, "%x", asus_info->oem_revision);
+-		len += sprintf(page + len, "OEM rev number     : 0x%s\n", buf);
++		len += sprintf(page + len, "OEM revision       : 0x%s\n", buf);
+ 		snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
+-		len += sprintf(page + len, "ASL comp vendor ID : %s\n", buf);
++		len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
+ 		snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
+-		len += sprintf(page + len, "ASL comp rev number: 0x%s\n", buf);
++		len += sprintf(page + len, "ASL comp revision  : 0x%s\n", buf);
+ 	}
+ 
+ 	return len;
+@@ -304,7 +323,7 @@ proc_read_mled(char *page, char **start,
+ 				  &led_status))
+ 			len =  sprintf(page, "%d\n", led_status);
+ 		else
+-			printk(KERN_NOTICE "Asus ACPI: Error reading MLED "
++			printk(KERN_WARNING "Asus ACPI: Error reading MLED "
+ 			       "status\n");
+ 	} else {
+ 		len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0);
+@@ -334,7 +353,7 @@ proc_write_mled(struct file *file, const
+ 	/* We don't have to check mt_mled exists if we are here :) */
+ 	if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out,
+ 			    NULL))
+-		printk(KERN_NOTICE "Asus ACPI: MLED write failed\n");
++		printk(KERN_WARNING "Asus ACPI: MLED write failed\n");
+ 
+ 
+ 
+@@ -355,11 +374,11 @@ proc_read_wled(char *page, char **start,
+ 	int led_status;
+ 
+ 	if (hotk->methods->wled_status) {
+-		if (read_acpi_int(NULL, hotk->methods->mled_status, 
++		if (read_acpi_int(NULL, hotk->methods->wled_status, 
+ 				  &led_status))
+ 			len = sprintf(page, "%d\n", led_status);
+ 		else
+-			printk(KERN_NOTICE "Asus ACPI: Error reading WLED "
++			printk(KERN_WARNING "Asus ACPI: Error reading WLED "
+ 			       "status\n");
+ 	} else {
+ 		len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0);
+@@ -386,7 +405,7 @@ proc_write_wled(struct file *file, const
+ 	/* We don't have to check if mt_wled exists if we are here :) */
+ 	if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out,
+ 			    NULL))
+-		printk(KERN_NOTICE "Asus ACPI: WLED write failed\n");
++		printk(KERN_WARNING "Asus ACPI: WLED write failed\n");
+ 
+ 
+ 	return count;
+@@ -399,7 +418,7 @@ static int get_lcd_state(struct asus_hot
+ 
+ 	/* We don't have to check anything, if we are here */
+ 	if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
+-		printk(KERN_NOTICE "Asus ACPI: Error reading LCD status\n");
++		printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n");
+ 	
+ 	if (hotk->model == L2X)
+ 		lcd = ~lcd;
+@@ -438,7 +457,7 @@ proc_write_lcd(struct file *file, const 
+ 		    acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
+ 					 NULL, NULL);
+ 		if (ACPI_FAILURE(status))
+-			printk(KERN_NOTICE "Asus ACPI: Error switching LCD\n");
++			printk(KERN_WARNING "Asus ACPI: Error switching LCD\n");
+ 	}
+ 
+ 	return count;
+@@ -452,15 +471,15 @@ static void set_brightness(int value, st
+ {
+ 	acpi_status status = 0;
+ 
+-	/* ATKD laptop */
++	/* SPLV laptop */
+ 	if(hotk->methods->brightness_set) {
+ 		if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, 
+ 				    value, NULL))
+-			printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n");
++			printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+ 		return;
+ 	}
+ 
+-	/* HOTK laptop if we are here, act as appropriate */
++	/* No SPLV method if we are here, act as appropriate */
+ 	value -= hotk->brightness;
+ 	while (value != 0) {
+ 		status = acpi_evaluate_object(NULL, (value > 0) ? 
+@@ -469,7 +488,7 @@ static void set_brightness(int value, st
+ 					      NULL, NULL);
+ 		(value > 0) ? value-- : value++;
+ 		if (ACPI_FAILURE(status))
+-			printk(KERN_NOTICE "Asus ACPI: Error changing brightness\n");
++			printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+ 	}
+ 	return;
+ }
+@@ -478,15 +497,15 @@ static int read_brightness(struct asus_h
+ {
+ 	int value;
+ 	
+-	if(hotk->methods->brightness_get) { /* ATKD laptop */
++	if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
+ 		if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, 
+ 				   &value))
+-			printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n");
++			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
+ 	} else if (hotk->methods->brightness_status) { /* For D1 for example */
+ 		if (!read_acpi_int(NULL, hotk->methods->brightness_status, 
+ 				   &value))
+-			printk(KERN_NOTICE "Asus ACPI: Error reading brightness\n");
+-	} else /* HOTK laptop */
++			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
++	} else /* No GPLV method */
+ 		value = hotk->brightness;
+ 	return value;
+ }
+@@ -512,7 +531,7 @@ proc_write_brn(struct file *file, const 
+ 			/* 0 <= value <= 15 */
+ 		set_brightness(value, hotk);
+ 	} else {
+-		printk(KERN_NOTICE "Asus ACPI: Error reading user input\n");
++		printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
+ 	}
+ 
+ 	return count;
+@@ -523,7 +542,7 @@ static void set_display(int value, struc
+ 	/* no sanity check needed for now */
+ 	if (!write_acpi_int(hotk->handle, hotk->methods->display_set, 
+ 			    value, NULL))
+-		printk(KERN_NOTICE "Asus ACPI: Error setting display\n");
++		printk(KERN_WARNING "Asus ACPI: Error setting display\n");
+ 	return;
+ }
+ 
+@@ -540,12 +559,12 @@ proc_read_disp(char *page, char **start,
+ 	struct asus_hotk *hotk = (struct asus_hotk *) data;
+ 	
+ 	if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
+-		printk(KERN_NOTICE "Asus ACPI: Error reading display status\n");
++		printk(KERN_WARNING "Asus ACPI: Error reading display status\n");
+ 	return sprintf(page, "%d\n", value);
+ }
+ 
+ /*
+- * Preliminary support for display switching. As of now: 0x01 should activate 
++ * Experimental support for display switching. As of now: 0x01 should activate 
+  * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination 
+  * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
+  * simultaneously, so be warned.
+@@ -562,13 +581,13 @@ proc_write_disp(struct file *file, const
+ 	if (sscanf(buffer, "%d", &value) == 1)
+ 		set_display(value, hotk);
+ 	else {
+-		printk(KERN_NOTICE "Asus ACPI: Error reading user input\n");
++		printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
+ 	}
+ 
+ 	return count;
+ }
+ 
+-static int asus_hotk_add_fs(struct acpi_device *device)
++static int __init asus_hotk_add_fs(struct acpi_device *device)
+ {
+ 	struct proc_dir_entry *proc;
+ 	struct asus_hotk *hotk = acpi_driver_data(device);
+@@ -582,7 +601,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 
+ 	if ((asus_uid == 0) && (asus_gid == 0)){
+ 		mode = S_IFREG | S_IRUGO | S_IWUGO;
+-	}else{
++	} else {
+ 		mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
+ 	}
+ 
+@@ -598,7 +617,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 		proc->uid = asus_uid;
+ 		proc->gid = asus_gid;;
+ 	} else {
+-		printk(KERN_NOTICE "  Unable to create " PROC_INFOS
++		printk(KERN_WARNING "  Unable to create " PROC_INFOS
+ 		       " fs entry\n");
+ 	}
+ 
+@@ -612,7 +631,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 			proc->uid = asus_uid;
+ 			proc->gid = asus_gid;;
+ 		} else {
+-			printk(KERN_NOTICE "  Unable to create " PROC_WLED
++			printk(KERN_WARNING "  Unable to create " PROC_WLED
+ 			       " fs entry\n");
+ 		}
+ 	}
+@@ -627,7 +646,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 			proc->uid = asus_uid;
+ 			proc->gid = asus_gid;;
+ 		} else {
+-			printk(KERN_NOTICE "  Unable to create " PROC_MLED
++			printk(KERN_WARNING "  Unable to create " PROC_MLED
+ 			       " fs entry\n");
+ 		}
+ 	}
+@@ -646,7 +665,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 			proc->uid = asus_uid;
+ 			proc->gid = asus_gid;;
+ 		} else {
+-			printk(KERN_NOTICE "  Unable to create " PROC_LCD
++			printk(KERN_WARNING "  Unable to create " PROC_LCD
+ 			       " fs entry\n");
+ 		}
+ 	}
+@@ -662,7 +681,7 @@ static int asus_hotk_add_fs(struct acpi_
+ 			proc->uid = asus_uid;
+ 			proc->gid = asus_gid;;
+ 		} else {
+-			printk(KERN_NOTICE "  Unable to create " PROC_BRN
++			printk(KERN_WARNING "  Unable to create " PROC_BRN
+ 			       " fs entry\n");
+ 		}
+ 	}
+@@ -677,19 +696,19 @@ static int asus_hotk_add_fs(struct acpi_
+ 			proc->uid = asus_uid;
+ 			proc->gid = asus_gid;;
+ 		} else {
+-			printk(KERN_NOTICE "  Unable to create " PROC_DISP
++			printk(KERN_WARNING "  Unable to create " PROC_DISP
+ 			       " fs entry\n");
+ 		}
+ 	}
+ 
+-	return (AE_OK);
++	return 0;
+ }
+ 
+ 
+ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
+ {
+ 	/* TODO Find a better way to handle events count. Here, in data, we receive
+-	 * the hotk, so we can make anything !!
++	 * the hotk, so we can do anything!
+ 	 */
+ 	struct asus_hotk *hotk = (struct asus_hotk *) data;
+ 
+@@ -712,19 +731,40 @@ static void asus_hotk_notify(acpi_handle
+  * This function is used to initialize the hotk with right values. In this
+  * method, we can make all the detection we want, and modify the hotk struct
+  */
+-static int asus_hotk_get_info(struct asus_hotk *hotk)
++static int __init asus_hotk_get_info(struct asus_hotk *hotk)
+ {
+ 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
++	struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
+ 	union acpi_object *model = NULL;
++	int bsts_result;
++	acpi_status status;
+ 
+-	/* 
+-	 * We have to write 0 on init this far for all ASUS models
++	/*
++	 * Get DSDT headers early enough to allow for differentiating between 
++	 * models, but late enough to allow acpi_bus_register_driver() to fail 
++	 * before doing anything ACPI-specific. Should we encounter a machine,
++	 * which needs special handling (i.e. its hotkey device has a different
++	 * HID), this bit will be moved. A global variable asus_info contains
++	 * the DSDT header.
+ 	 */
++	status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
++	if (ACPI_FAILURE(status))
++		printk(KERN_WARNING "  Couldn't get the DSDT table header\n");
++	else
++		asus_info = (struct acpi_table_header *) dsdt.pointer;
++
++	/* We have to write 0 on init this far for all ASUS models */
+ 	if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
+-		printk(KERN_NOTICE "  Hotkey initialization failed\n");
++		printk(KERN_ERR "  Hotkey initialization failed\n");
+ 		return -ENODEV;
+ 	}
+ 
++	/* For testing purposes */
++	if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result))
++		printk(KERN_WARNING "  Error calling BSTS\n");
++	else if (bsts_result)
++		printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n", bsts_result);
++
+ 	/*
+ 	 * Here, we also use asus_info to make decision. For example, on INIT
+ 	 * method, S1X and L1X models both reports to be L84F, but they don't
+@@ -749,26 +789,34 @@ static int asus_hotk_get_info(struct asu
+ 		hotk->model = L3X;
+ 	else if (strncmp(model->string.pointer, "M2", 2) == 0)
+ 		hotk->model = M2X;
++	else if (strncmp(model->string.pointer, "M3N", 3) == 0 ||
++		 strncmp(model->string.pointer, "S1N", 3) == 0)
++		hotk->model = M3N; /* S1300N is similar enough */
+ 	else if (strncmp(model->string.pointer, "L2", 2) == 0)
+ 		hotk->model = L2X;
+-	else if (strncmp(model->string.pointer, "L8", 2) == 0)
++	else if (strncmp(model->string.pointer, "L8", 2) == 0) {
+ 		/* S1300A reports L84F, but L1400B too */
+-		if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
+-			hotk->model = L1X;
+-		else
++		if (asus_info) {
++			if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
++				hotk->model = L1X;
++		} else
+ 			hotk->model = S1X;
++	}
+ 	else if (strncmp(model->string.pointer, "D1", 2) == 0)
+ 		hotk->model = D1X;
+ 	else if (strncmp(model->string.pointer, "A1", 2) == 0)
+ 		hotk->model = A1X;
++	else if (strncmp(model->string.pointer, "A2", 2) == 0)
++		hotk->model = A2X;
+ 	else if (strncmp(model->string.pointer, "J1", 2) == 0)
+-		hotk->model = J1X;
+-
++		hotk->model = S2X;
++	else if (strncmp(model->string.pointer, "L5", 2) == 0)
++		hotk->model = L5X;
+ 
+ 	if (hotk->model == END_MODEL) {
+ 		/* By default use the same values, as I don't know others */
+-		printk("unsupported, trying default values, contact the "
+-		       "developers\n");
++		printk("unsupported, trying default values, supply the "
++		       "developers with your DSDT\n");
+ 		hotk->model = L2X;
+ 	} else {
+ 		printk("supported\n");
+@@ -783,7 +831,7 @@ static int asus_hotk_get_info(struct asu
+ 
+ 
+ 
+-static int asus_hotk_check(struct asus_hotk *hotk)
++static int __init asus_hotk_check(struct asus_hotk *hotk)
+ {
+ 	int result = 0;
+ 
+@@ -797,7 +845,7 @@ static int asus_hotk_check(struct asus_h
+ 	if (hotk->device->status.present) {
+ 		result = asus_hotk_get_info(hotk);
+ 	} else {
+-		printk(KERN_NOTICE "  Hotkey device not present, aborting\n");
++		printk(KERN_ERR "  Hotkey device not present, aborting\n");
+ 		return(-EINVAL);
+ 	}
+ 
+@@ -806,7 +854,7 @@ static int asus_hotk_check(struct asus_h
+ 
+ 
+ 
+-static int asus_hotk_add(struct acpi_device *device)
++static int __init asus_hotk_add(struct acpi_device *device)
+ {
+ 	struct asus_hotk *hotk = NULL;
+ 	acpi_status status = AE_OK;
+@@ -815,6 +863,9 @@ static int asus_hotk_add(struct acpi_dev
+ 	if (!device)
+ 		return(-EINVAL);
+ 
++	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
++	       ASUS_ACPI_VERSION);
++
+ 	hotk =
+ 	    (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+ 	if (!hotk)
+@@ -842,25 +893,23 @@ static int asus_hotk_add(struct acpi_dev
+ 	 */
+ 	status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+ 					     asus_hotk_notify, hotk);
+-	if (ACPI_FAILURE(status)) {
+-		printk(KERN_NOTICE
+-		       "  Error installing notify handler\n");
+-	} else {
+-		printk(KERN_DEBUG
+-		       "  Notify Handler installed successfully\n");
+-	}
++	if (ACPI_FAILURE(status))
++		printk(KERN_ERR "  Error installing notify handler\n");
+ 
+-	/* For HOTK laptops: init the hotk->brightness value */
++	/* For laptops without GPLV: init the hotk->brightness value */
+ 	if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) &&
+ 	    (hotk->methods->brightness_up && hotk->methods->brightness_down)) {
+ 		status = acpi_evaluate_object(NULL, hotk->methods->brightness_down,
+ 					      NULL, NULL);
+ 		if (ACPI_FAILURE(status))
+-			printk(KERN_NOTICE "  Error changing brightness\n");
+-		status = acpi_evaluate_object(NULL, hotk->methods->brightness_up,
+-					      NULL, NULL);
+-		if (ACPI_FAILURE(status))
+-			printk(KERN_NOTICE "  Error changing brightness\n");
++			printk(KERN_WARNING "  Error changing brightness\n");
++		else {
++			status = acpi_evaluate_object(NULL, hotk->methods->brightness_up,
++						      NULL, NULL);
++			if (ACPI_FAILURE(status))
++				printk(KERN_WARNING "  Strange, error changing" 
++				       " brightness\n");
++		}
+ 	}
+ 
+       end:
+@@ -887,7 +936,7 @@ static int asus_hotk_remove(struct acpi_
+ 	status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+ 					    asus_hotk_notify);
+ 	if (ACPI_FAILURE(status))
+-		printk(KERN_NOTICE "Error removing notify handler\n");
++		printk(KERN_ERR "Asus ACPI: Error removing notify handler\n");
+ 
+ 	kfree(hotk);
+ 
+@@ -899,35 +948,17 @@ static int asus_hotk_remove(struct acpi_
+ 
+ static int __init asus_acpi_init(void)
+ {
+-	int result = 0;
+-	acpi_status status = 0;
+-	struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
+-
+-	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
+-	       ASUS_ACPI_VERSION);
+-	/*
+-	 * Here is the code to know the model we are running on. We need to
+-	 * know this before calling the acpi_bus_register_driver function, in
+-	 * case the HID for the laptop we are running on is different from
+-	 * ACPI_HOTK_HID, which I have never seen yet :)
+-	 * 
+-	 * This information is then available in the global var asus_info
+-	 */
+-	status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
+-	if (ACPI_FAILURE(status)) {
+-		printk(KERN_NOTICE "  Couldn't get the DSDT table header\n");
+-	} else {
+-		asus_info = (struct acpi_table_header *) dsdt.pointer;
+-	}
++	int result;
+ 
+ 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
+-	if (!asus_proc_dir)
++	if (!asus_proc_dir) {
++		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry");
+ 		return(-ENODEV);
++	}
+ 	asus_proc_dir->owner = THIS_MODULE;
+ 
+ 	result = acpi_bus_register_driver(&asus_hotk_driver);
+ 	if (result < 0) {
+-		printk(KERN_NOTICE "  Error registering " ACPI_HOTK_NAME " \n");
+ 		remove_proc_entry(PROC_ASUS, acpi_root_dir);
+ 		return(-ENODEV);
+ 	}
+--- linux-2.6.0-test6/drivers/acpi/bus.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/bus.c	2003-10-05 00:33:23.000000000 -0700
+@@ -634,8 +634,7 @@ acpi_bus_init (void)
+ 	 * the EC parameters out of that.
+ 	 */
+ 	status = acpi_ec_ecdt_probe();
+-	if (ACPI_FAILURE(status))
+-		goto error1;
++	/* Ignore result. Not having an ECDT is not fatal. */
+ #endif
+ 
+ 	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dsfield.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsfield.c	2003-10-05 00:33:23.000000000 -0700
+@@ -105,27 +105,33 @@ acpi_ds_create_buffer_field (
+ 		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ 	}
+ 
+-	/*
+-	 * During the load phase, we want to enter the name of the field into
+-	 * the namespace.  During the execute phase (when we evaluate the size
+-	 * operand), we want to lookup the name
+-	 */
+-	if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
+-		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
++	if (walk_state->deferred_node) {
++		node = walk_state->deferred_node;
++		status = AE_OK;
+ 	}
+ 	else {
+-		flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
+-	}
++		/*
++		 * During the load phase, we want to enter the name of the field into
++		 * the namespace.  During the execute phase (when we evaluate the size
++		 * operand), we want to lookup the name
++		 */
++		if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
++			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
++		}
++		else {
++			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
++		}
+ 
+-	/*
+-	 * Enter the name_string into the namespace
+-	 */
+-	status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+-			 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
+-			 flags, walk_state, &(node));
+-	if (ACPI_FAILURE (status)) {
+-		ACPI_REPORT_NSERROR (arg->common.value.string, status);
+-		return_ACPI_STATUS (status);
++		/*
++		 * Enter the name_string into the namespace
++		 */
++		status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
++				 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
++				 flags, walk_state, &(node));
++		if (ACPI_FAILURE (status)) {
++			ACPI_REPORT_NSERROR (arg->common.value.string, status);
++			return_ACPI_STATUS (status);
++		}
+ 	}
+ 
+ 	/* We could put the returned object (Node) on the object stack for later, but
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dsinit.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsinit.c	2003-10-05 00:33:23.000000000 -0700
+@@ -135,7 +135,7 @@ acpi_ds_init_one_object (
+ 		}
+ 
+ 		/*
+-		 * Always parse methods to detect errors, we may delete
++		 * Always parse methods to detect errors, we will delete
+ 		 * the parse tree below
+ 		 */
+ 		status = acpi_ds_parse_method (obj_handle);
+@@ -150,7 +150,7 @@ acpi_ds_init_one_object (
+ 		}
+ 
+ 		/*
+-		 * Delete the parse tree.  We simple re-parse the method
++		 * Delete the parse tree.  We simply re-parse the method
+ 		 * for every execution since there isn't much overhead
+ 		 */
+ 		acpi_ns_delete_namespace_subtree (obj_handle);
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dsopcode.c	2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsopcode.c	2003-10-05 00:33:23.000000000 -0700
+@@ -65,7 +65,7 @@
+  *
+  * RETURN:      Status.
+  *
+- * DESCRIPTION: Late execution of region or field arguments
++ * DESCRIPTION: Late (deferred) execution of region or field arguments
+  *
+  ****************************************************************************/
+ 
+@@ -111,7 +111,10 @@ acpi_ds_execute_arguments (
+ 		return_ACPI_STATUS (status);
+ 	}
+ 
++	/* Mark this parse as a deferred opcode */
++
+ 	walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
++	walk_state->deferred_node = node;
+ 
+ 	/* Pass1: Parse the entire declaration */
+ 
+@@ -128,7 +131,7 @@ acpi_ds_execute_arguments (
+ 	arg->common.node = node;
+ 	acpi_ps_delete_parse_tree (op);
+ 
+-	/* Evaluate the address and length arguments for the Buffer Field */
++	/* Evaluate the deferred arguments */
+ 
+ 	op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
+ 	if (!op) {
+@@ -144,6 +147,8 @@ acpi_ds_execute_arguments (
+ 		return_ACPI_STATUS (AE_NO_MEMORY);
+ 	}
+ 
++	/* Execute the opcode and arguments */
++
+ 	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
+ 			  aml_length, NULL, NULL, 3);
+ 	if (ACPI_FAILURE (status)) {
+@@ -151,6 +156,9 @@ acpi_ds_execute_arguments (
+ 		return_ACPI_STATUS (status);
+ 	}
+ 
++	/* Mark this execution as a deferred opcode */
++
++	walk_state->deferred_node = node;
+ 	status = acpi_ps_parse_aml (walk_state);
+ 	acpi_ps_delete_parse_tree (op);
+ 	return_ACPI_STATUS (status);
+@@ -192,7 +200,7 @@ acpi_ds_get_buffer_field_arguments (
+ 	node = obj_desc->buffer_field.node;
+ 
+ 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
+-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field JIT Init\n",
++	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
+ 		node->name.ascii));
+ 
+ 	/* Execute the AML code for the term_arg arguments */
+@@ -207,7 +215,7 @@ acpi_ds_get_buffer_field_arguments (
+  *
+  * FUNCTION:    acpi_ds_get_buffer_arguments
+  *
+- * PARAMETERS:  obj_desc        - A valid Bufferobject
++ * PARAMETERS:  obj_desc        - A valid Buffer object
+  *
+  * RETURN:      Status.
+  *
+@@ -240,7 +248,7 @@ acpi_ds_get_buffer_arguments (
+ 		return_ACPI_STATUS (AE_AML_INTERNAL);
+ 	}
+ 
+-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer JIT Init\n"));
++	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+ 
+ 	/* Execute the AML code for the term_arg arguments */
+ 
+@@ -254,7 +262,7 @@ acpi_ds_get_buffer_arguments (
+  *
+  * FUNCTION:    acpi_ds_get_package_arguments
+  *
+- * PARAMETERS:  obj_desc        - A valid Packageobject
++ * PARAMETERS:  obj_desc        - A valid Package object
+  *
+  * RETURN:      Status.
+  *
+@@ -287,7 +295,7 @@ acpi_ds_get_package_arguments (
+ 		return_ACPI_STATUS (AE_AML_INTERNAL);
+ 	}
+ 
+-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package JIT Init\n"));
++	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+ 
+ 	/* Execute the AML code for the term_arg arguments */
+ 
+@@ -335,11 +343,12 @@ acpi_ds_get_region_arguments (
+ 
+ 	node = obj_desc->region.node;
+ 
+-	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
++	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
+ 
+-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Init at AML %p\n",
++	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
+ 		node->name.ascii, extra_desc->extra.aml_start));
+ 
++	/* Execute the argument AML */
+ 
+ 	status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
+ 			 extra_desc->extra.aml_length, extra_desc->extra.aml_start);
+@@ -505,14 +514,16 @@ acpi_ds_init_buffer_field (
+ 		goto cleanup;
+ 	}
+ 
+-
+ 	/* Entire field must fit within the current length of the buffer */
+ 
+ 	if ((bit_offset + bit_count) >
+ 		(8 * (u32) buffer_desc->buffer.length)) {
+ 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-			"Field size %d exceeds Buffer size %d (bits)\n",
+-			 bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length));
++			"Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
++			((struct acpi_namespace_node *) result_desc)->name.ascii,
++			 bit_offset + bit_count,
++			 buffer_desc->buffer.node->name.ascii,
++			 8 * (u32) buffer_desc->buffer.length));
+ 		status = AE_AML_BUFFER_LIMIT;
+ 		goto cleanup;
+ 	}
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dsutils.c	2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsutils.c	2003-10-05 00:33:23.000000000 -0700
+@@ -53,6 +53,7 @@
+ #define _COMPONENT          ACPI_DISPATCHER
+ 	 ACPI_MODULE_NAME    ("dsutils")
+ 
++
+ #ifndef ACPI_NO_METHOD_EXECUTION
+ 
+ /*******************************************************************************
+@@ -196,7 +197,6 @@ result_not_used:
+ 			acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+ 
+ 	return_VALUE (FALSE);
+-
+ }
+ 
+ 
+@@ -239,7 +239,6 @@ acpi_ds_delete_result_if_not_used (
+ 		return_VOID;
+ 	}
+ 
+-
+ 	if (!acpi_ds_is_result_used (op, walk_state)) {
+ 		/*
+ 		 * Must pop the result stack (obj_desc should be equal to result_obj)
+@@ -389,61 +388,77 @@ acpi_ds_create_operand (
+ 		 * in name_string
+ 		 */
+ 
++
+ 		/*
+-		 * Differentiate between a namespace "create" operation
+-		 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
+-		 * IMODE_EXECUTE) in order to support the creation of
+-		 * namespace objects during the execution of control methods.
++		 * Special handling for buffer_field declarations. This is a deferred
++		 * opcode that unfortunately defines the field name as the last
++		 * parameter instead of the first.  We get here when we are performing
++		 * the deferred execution, so the actual name of the field is already
++		 * in the namespace.  We don't want to attempt to look it up again
++		 * because we may be executing in a different scope than where the
++		 * actual opcode exists.
+ 		 */
+-		parent_op = arg->common.parent;
+-		op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
+-		if ((op_info->flags & AML_NSNODE) &&
+-			(parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
+-			(parent_op->common.aml_opcode != AML_REGION_OP) &&
+-			(parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
+-			/* Enter name into namespace if not found */
+-
+-			interpreter_mode = ACPI_IMODE_LOAD_PASS2;
++		if ((walk_state->deferred_node) &&
++			(walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
++			(arg_index != 0)) {
++			obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
++			status = AE_OK;
+ 		}
++		else    /* All other opcodes */ {
++			/*
++			 * Differentiate between a namespace "create" operation
++			 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
++			 * IMODE_EXECUTE) in order to support the creation of
++			 * namespace objects during the execution of control methods.
++			 */
++			parent_op = arg->common.parent;
++			op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
++			if ((op_info->flags & AML_NSNODE) &&
++				(parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
++				(parent_op->common.aml_opcode != AML_REGION_OP) &&
++				(parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
++				/* Enter name into namespace if not found */
+ 
+-		else {
+-			/* Return a failure if name not found */
+-
+-			interpreter_mode = ACPI_IMODE_EXECUTE;
+-		}
++				interpreter_mode = ACPI_IMODE_LOAD_PASS2;
++			}
++			else {
++				/* Return a failure if name not found */
+ 
+-		status = acpi_ns_lookup (walk_state->scope_info, name_string,
+-				 ACPI_TYPE_ANY, interpreter_mode,
+-				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+-				 walk_state,
+-				 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
+-		/*
+-		 * The only case where we pass through (ignore) a NOT_FOUND
+-		 * error is for the cond_ref_of opcode.
+-		 */
+-		if (status == AE_NOT_FOUND) {
+-			if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
+-				/*
+-				 * For the Conditional Reference op, it's OK if
+-				 * the name is not found;  We just need a way to
+-				 * indicate this to the interpreter, set the
+-				 * object to the root
+-				 */
+-				obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
+-				status = AE_OK;
++				interpreter_mode = ACPI_IMODE_EXECUTE;
+ 			}
+ 
+-			else {
+-				/*
+-				 * We just plain didn't find it -- which is a
+-				 * very serious error at this point
+-				 */
+-				status = AE_AML_NAME_NOT_FOUND;
++			status = acpi_ns_lookup (walk_state->scope_info, name_string,
++					 ACPI_TYPE_ANY, interpreter_mode,
++					 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
++					 walk_state,
++					 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
++			/*
++			 * The only case where we pass through (ignore) a NOT_FOUND
++			 * error is for the cond_ref_of opcode.
++			 */
++			if (status == AE_NOT_FOUND) {
++				if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
++					/*
++					 * For the Conditional Reference op, it's OK if
++					 * the name is not found;  We just need a way to
++					 * indicate this to the interpreter, set the
++					 * object to the root
++					 */
++					obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
++					status = AE_OK;
++				}
++				else {
++					/*
++					 * We just plain didn't find it -- which is a
++					 * very serious error at this point
++					 */
++					status = AE_AML_NAME_NOT_FOUND;
++				}
+ 			}
+-		}
+ 
+-		if (ACPI_FAILURE (status)) {
+-			ACPI_REPORT_NSERROR (name_string, status);
++			if (ACPI_FAILURE (status)) {
++				ACPI_REPORT_NSERROR (name_string, status);
++			}
+ 		}
+ 
+ 		/* Free the namestring created above */
+@@ -464,8 +479,6 @@ acpi_ds_create_operand (
+ 		}
+ 		ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
+ 	}
+-
+-
+ 	else {
+ 		/* Check for null name case */
+ 
+@@ -480,7 +493,6 @@ acpi_ds_create_operand (
+ 
+ 			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
+ 		}
+-
+ 		else {
+ 			opcode = arg->common.aml_opcode;
+ 		}
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dswload.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswload.c	2003-10-05 00:33:23.000000000 -0700
+@@ -248,6 +248,14 @@ acpi_ds_load1_begin_op (
+ 		 *       buffer_field, or Package), the name of the object is already
+ 		 *       in the namespace.
+ 		 */
++		if (walk_state->deferred_node) {
++			/* This name is already in the namespace, get the node */
++
++			node = walk_state->deferred_node;
++			status = AE_OK;
++			break;
++		}
++
+ 		flags = ACPI_NS_NO_UPSEARCH;
+ 		if ((walk_state->opcode != AML_SCOPE_OP) &&
+ 			(!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
+@@ -589,7 +597,17 @@ acpi_ds_load2_begin_op (
+ 		 * Enter the named type into the internal namespace.  We enter the name
+ 		 * as we go downward in the parse tree.  Any necessary subobjects that involve
+ 		 * arguments to the opcode must be created as we go back up the parse tree later.
++		 *
++		 * Note: Name may already exist if we are executing a deferred opcode.
+ 		 */
++		if (walk_state->deferred_node) {
++			/* This name is already in the namespace, get the node */
++
++			node = walk_state->deferred_node;
++			status = AE_OK;
++			break;
++		}
++
+ 		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
+ 				  ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node));
+ 		break;
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dswscope.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswscope.c	2003-10-05 00:33:23.000000000 -0700
+@@ -121,10 +121,9 @@ acpi_ds_scope_stack_push (
+ 	/* Make sure object type is valid */
+ 
+ 	if (!acpi_ut_valid_object_type (type)) {
+-		ACPI_REPORT_WARNING (("ds_scope_stack_push: type code out of range\n"));
++		ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+ 	}
+ 
+-
+ 	/* Allocate a new scope object */
+ 
+ 	scope_info = acpi_ut_create_generic_state ();
+@@ -146,13 +145,13 @@ acpi_ds_scope_stack_push (
+ 	old_scope_info = walk_state->scope_info;
+ 	if (old_scope_info) {
+ 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+-			"[%4.4s] (%10s)",
++			"[%4.4s] (%s)",
+ 			old_scope_info->scope.node->name.ascii,
+ 			acpi_ut_get_type_name (old_scope_info->common.value)));
+ 	}
+ 	else {
+ 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+-			"[\\___] (%10s)", "ROOT"));
++			"[\\___] (%s)", "ROOT"));
+ 	}
+ 
+ 	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+@@ -163,7 +162,6 @@ acpi_ds_scope_stack_push (
+ 	/* Push new scope object onto stack */
+ 
+ 	acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
+-
+ 	return_ACPI_STATUS (AE_OK);
+ }
+ 
+@@ -207,7 +205,7 @@ acpi_ds_scope_stack_pop (
+ 	walk_state->scope_depth--;
+ 
+ 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+-		"[%.2d] Popped scope [%4.4s] (%10s), New scope -> ",
++		"[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
+ 		(u32) walk_state->scope_depth,
+ 		scope_info->scope.node->name.ascii,
+ 		acpi_ut_get_type_name (scope_info->common.value)));
+@@ -225,7 +223,6 @@ acpi_ds_scope_stack_pop (
+ 	}
+ 
+ 	acpi_ut_delete_generic_state (scope_info);
+-
+ 	return_ACPI_STATUS (AE_OK);
+ }
+ 
+--- linux-2.6.0-test6/drivers/acpi/dispatcher/dswstate.c	2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswstate.c	2003-10-05 00:33:23.000000000 -0700
+@@ -56,11 +56,12 @@
+  * FUNCTION:    acpi_ds_result_insert
+  *
+  * PARAMETERS:  Object              - Object to push
++ *              Index               - Where to insert the object
+  *              walk_state          - Current Walk state
+  *
+  * RETURN:      Status
+  *
+- * DESCRIPTION: Push an object onto this walk's result stack
++ * DESCRIPTION: Insert an object onto this walk's result stack
+  *
+  ******************************************************************************/
+ 
+@@ -114,6 +115,7 @@ acpi_ds_result_insert (
+  * FUNCTION:    acpi_ds_result_remove
+  *
+  * PARAMETERS:  Object              - Where to return the popped object
++ *              Index               - Where to extract the object
+  *              walk_state          - Current Walk state
+  *
+  * RETURN:      Status
+@@ -233,6 +235,7 @@ acpi_ds_result_pop (
+ 	return (AE_AML_NO_RETURN_VALUE);
+ }
+ 
++
+ /*******************************************************************************
+  *
+  * FUNCTION:    acpi_ds_result_pop_from_bottom
+@@ -295,7 +298,6 @@ acpi_ds_result_pop_from_bottom (
+ 		*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+ 		state, walk_state));
+ 
+-
+ 	return (AE_OK);
+ }
+ 
+@@ -358,8 +360,7 @@ acpi_ds_result_push (
+  *
+  * FUNCTION:    acpi_ds_result_stack_push
+  *
+- * PARAMETERS:  Object              - Object to push
+- *              walk_state          - Current Walk state
++ * PARAMETERS:  walk_state          - Current Walk state
+  *
+  * RETURN:      Status
+  *
+@@ -420,7 +421,6 @@ acpi_ds_result_stack_pop (
+ 		return (AE_AML_NO_OPERAND);
+ 	}
+ 
+-
+ 	state = acpi_ut_pop_generic_state (&walk_state->results);
+ 
+ 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+@@ -572,6 +572,7 @@ acpi_ds_obj_stack_pop_object (
+ }
+ #endif
+ 
++
+ /*******************************************************************************
+  *
+  * FUNCTION:    acpi_ds_obj_stack_pop
+@@ -641,6 +642,7 @@ acpi_ds_obj_stack_pop_and_delete (
+ 	u32                             i;
+ 	union acpi_operand_object       *obj_desc;
+ 
++
+ 	ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
+ 
+ 
+@@ -883,8 +885,15 @@ acpi_ds_create_walk_state (
+  * FUNCTION:    acpi_ds_init_aml_walk
+  *
+  * PARAMETERS:  walk_state      - New state to be initialized
++ *              Op              - Current parse op
++ *              method_node     - Control method NS node, if any
++ *              aml_start       - Start of AML
++ *              aml_length      - Length of AML
++ *              Params          - Method args, if any
++ *              return_obj_desc - Where to store a return object, if any
++ *              pass_number     - 1, 2, or 3
+  *
+- * RETURN:      None
++ * RETURN:      Status
+  *
+  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
+  *
+@@ -927,9 +936,9 @@ acpi_ds_init_aml_walk (
+ 
+ 	if (method_node) {
+ 		walk_state->parser_state.start_node = method_node;
+-		walk_state->walk_type               = ACPI_WALK_METHOD;
+-		walk_state->method_node             = method_node;
+-		walk_state->method_desc             = acpi_ns_get_attached_object (method_node);
++		walk_state->walk_type            = ACPI_WALK_METHOD;
++		walk_state->method_node          = method_node;
++		walk_state->method_desc          = acpi_ns_get_attached_object (method_node);
+ 
+ 		/* Push start scope on scope stack and make it current  */
+ 
+@@ -956,6 +965,7 @@ acpi_ds_init_aml_walk (
+ 		while (extra_op && !extra_op->common.node) {
+ 			extra_op = extra_op->common.parent;
+ 		}
++
+ 		if (!extra_op) {
+ 			parser_state->start_node = NULL;
+ 		}
+@@ -1014,7 +1024,7 @@ acpi_ds_delete_walk_state (
+ 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
+ 	}
+ 
+-   /* Always must free any linked control states */
++	/* Always must free any linked control states */
+ 
+ 	while (walk_state->control_state) {
+ 		state = walk_state->control_state;
+--- linux-2.6.0-test6/drivers/acpi/ec.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/acpi/ec.c	2003-10-05 00:33:24.000000000 -0700
+@@ -32,7 +32,7 @@
+ #include <asm/io.h>
+ #include <acpi/acpi_bus.h>
+ #include <acpi/acpi_drivers.h>
+-
++#include <acpi/actypes.h>
+ 
+ #define _COMPONENT		ACPI_EC_COMPONENT
+ ACPI_MODULE_NAME		("acpi_ec")
+@@ -412,7 +412,10 @@ acpi_ec_space_setup (
+ 	 * The EC object is in the handler context and is needed
+ 	 * when calling the acpi_ec_space_handler.
+ 	 */
+-	*return_context = handler_context;
++	if(function == ACPI_REGION_DEACTIVATE) 
++		*return_context = NULL;
++	else 
++		*return_context = handler_context;
+ 
+ 	return AE_OK;
+ }
+--- linux-2.6.0-test6/drivers/acpi/events/evregion.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/acpi/events/evregion.c	2003-10-05 00:33:24.000000000 -0700
+@@ -382,7 +382,7 @@ acpi_ev_detach_region(
+ 	union acpi_operand_object       *obj_desc;
+ 	union acpi_operand_object       **last_obj_ptr;
+ 	acpi_adr_space_setup            region_setup;
+-	void                            *region_context;
++	void                            **region_context;
+ 	union acpi_operand_object       *region_obj2;
+ 	acpi_status                     status;
+ 
+@@ -394,7 +394,7 @@ acpi_ev_detach_region(
+ 	if (!region_obj2) {
+ 		return_VOID;
+ 	}
+-	region_context = region_obj2->extra.region_context;
++	region_context = &region_obj2->extra.region_context;
+ 
+ 	/* Get the address handler from the region object */
+ 
+@@ -450,7 +450,7 @@ acpi_ev_detach_region(
+ 
+ 			region_setup = handler_obj->address_space.setup;
+ 			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
+-					  handler_obj->address_space.context, &region_context);
++					  handler_obj->address_space.context, region_context);
+ 
+ 			/* Init routine may fail, Just ignore errors */
+ 
+--- linux-2.6.0-test6/drivers/acpi/executer/excreate.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/acpi/executer/excreate.c	2003-10-05 00:33:24.000000000 -0700
+@@ -286,7 +286,7 @@ acpi_ex_create_region (
+ 	ACPI_FUNCTION_TRACE ("ex_create_region");
+ 
+ 
+-	/* Get the Node from the object stack  */
++	/* Get the Namespace Node */
+ 
+ 	node = walk_state->op->common.node;
+ 
+@@ -311,7 +311,6 @@ acpi_ex_create_region (
+ 	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
+ 			  acpi_ut_get_region_name (region_space), region_space));
+ 
+-
+ 	/* Create the region descriptor */
+ 
+ 	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+@@ -375,6 +374,7 @@ acpi_ex_create_table_region (
+ 
+ 	ACPI_FUNCTION_TRACE ("ex_create_table_region");
+ 
++
+ 	/* Get the Node from the object stack  */
+ 
+ 	node = walk_state->op->common.node;
+@@ -392,7 +392,6 @@ acpi_ex_create_table_region (
+ 	status = acpi_tb_find_table (operand[1]->string.pointer,
+ 			   operand[2]->string.pointer,
+ 			   operand[3]->string.pointer, &table);
+-
+ 	if (ACPI_FAILURE (status)) {
+ 		return_ACPI_STATUS (status);
+ 	}
+@@ -489,7 +488,6 @@ acpi_ex_create_processor (
+ 	status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
+ 			  obj_desc, ACPI_TYPE_PROCESSOR);
+ 
+-
+ 	/* Remove local reference to the object */
+ 
+ 	acpi_ut_remove_reference (obj_desc);
+@@ -540,7 +538,6 @@ acpi_ex_create_power_resource (
+ 	status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
+ 			  obj_desc, ACPI_TYPE_POWER);
+ 
+-
+ 	/* Remove local reference to the object */
+ 
+ 	acpi_ut_remove_reference (obj_desc);
+@@ -609,7 +606,6 @@ acpi_ex_create_method (
+ 		obj_desc->method.concurrency = (u8)
+ 				  (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1);
+ 	}
+-
+ 	else {
+ 		obj_desc->method.concurrency = INFINITE_CONCURRENCY;
+ 	}
+--- linux-2.6.0-test6/drivers/acpi/executer/exfldio.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/acpi/executer/exfldio.c	2003-10-05 00:33:24.000000000 -0700
+@@ -139,7 +139,41 @@ acpi_ex_setup_region (
+ 			field_datum_byte_offset, obj_desc->common_field.access_byte_width,
+ 			rgn_desc->region.node->name.ascii, rgn_desc->region.length));
+ 
+-		return_ACPI_STATUS (AE_AML_REGION_LIMIT);
++		#ifdef CONFIG_ACPI_RELAXED_AML
++		{
++			/*
++			 * Allow access to the field if it is within the region size
++			 * rounded up to a multiple of the access byte width.  This
++			 * overcomes "off-by-one" programming errors in the AML often
++			 * found in Toshiba laptops.  These errors were allowed by
++			 * the Microsoft ASL compiler.
++			 */
++			u32 rounded_length = ACPI_ROUND_UP(rgn_desc->region.length,
++									obj_desc->common_field.access_byte_width);
++
++			if (rounded_length < (obj_desc->common_field.base_byte_offset
++						+ field_datum_byte_offset
++						+ obj_desc->common_field.access_byte_width)) {
++				return_ACPI_STATUS (AE_AML_REGION_LIMIT);
++			} else {
++				static int	warn_once = 1;
++				if (warn_once) {
++					// Could also associate a flag with each field, and
++					// warn once for each field.
++					ACPI_REPORT_WARNING((
++						"The ACPI AML in your computer contains errors, "
++						"please nag the manufacturer to correct it.\n"));
++					ACPI_REPORT_WARNING((
++						"Allowing relaxed access to fields; "
++						"turn on CONFIG_ACPI_DEBUG for details.\n"));
++					warn_once = 0;
++				}
++				return_ACPI_STATUS (AE_OK);
++			}
++		}
++		#else
++			return_ACPI_STATUS (AE_AML_REGION_LIMIT);
++		#endif
+ 	}
+ 
+ 	return_ACPI_STATUS (AE_OK);
+--- linux-2.6.0-test6/drivers/acpi/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/acpi/Kconfig	2003-10-05 00:36:23.000000000 -0700
+@@ -3,34 +3,14 @@
+ #
+ 
+ menu "ACPI (Advanced Configuration and Power Interface) Support"
+-
+-config ACPI_HT
+-	bool "ACPI Processor Enumeration for HT"
+-	depends on X86
+-	default y
+-	---help---
+-	  ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
+-	  and physical processors.  It is designed to obsolete several older
+-	  specifications, including the MultiProcessor Specification (MPS),
+-	  which supported only physical processors.
+-
+-	  CONFIG_ACPI_HT includes the minimal ACPI boot-time code
+-	  necessary to enumerate logical processors and enable HT.
+-
+-	  CONFIG_ACPI includes CONFIG_ACPI_HT, plus IO APIC enumeration,
+-	  and the hooks to run the ACPI AML interpreter for run-time events.
+-
+-	  When CONFIG_ACPI is selected, the command-line option "acpi=ht"
+-	  is available to run just the ACPI boot-time code -- just as if
+-	  only CONFIG_ACPI_HT were selected.
+-
+-	  Note that "acpi=off" can be used to disable all ACPI code in the kernel.
+-
+-config ACPI
+-	bool "Full ACPI Support"
+ 	depends on !X86_VISWS
+ 	depends on !IA64_HP_SIM
+-	depends on IA64 || (X86 || ACPI_HT)
++	depends on IA64 || X86
++
++config ACPI
++	bool "ACPI Support"
++	depends on IA64 || X86
++
+ 	default y
+ 	---help---
+ 	  Advanced Configuration and Power Interface (ACPI) support for 
+@@ -62,12 +42,19 @@ config ACPI
+ 
+ config ACPI_BOOT
+ 	bool
+-	depends on ACPI || ACPI_HT
++	depends on ACPI || X86_HT
++	default y
++
++config ACPI_INTERPRETER
++	bool
++	depends on ACPI
++	depends on !IA64_SGI_SN
+ 	default y
+ 
+ config ACPI_SLEEP
+ 	bool "Sleep States (EXPERIMENTAL)"
+ 	depends on X86 && ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on EXPERIMENTAL && PM
+ 	default y
+ 	---help---
+@@ -93,7 +80,8 @@ config ACPI_SLEEP_PROC_FS
+ 
+ config ACPI_AC
+ 	tristate "AC Adapter"
+-	depends on X86 && ACPI
++	depends on X86
++	depends on ACPI_INTERPRETER
+ 	default m
+ 	help
+ 	  This driver adds support for the AC Adapter object, which indicates
+@@ -102,7 +90,8 @@ config ACPI_AC
+ 
+ config ACPI_BATTERY
+ 	tristate "Battery"
+-	depends on X86 && ACPI
++	depends on X86
++	depends on ACPI_INTERPRETER
+ 	default m
+ 	help
+ 	  This driver adds support for battery information through
+@@ -111,7 +100,7 @@ config ACPI_BATTERY
+ 
+ config ACPI_BUTTON
+ 	tristate "Button"
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default m
+ 	help
+@@ -123,7 +112,7 @@ config ACPI_BUTTON
+ 
+ config ACPI_FAN
+ 	tristate "Fan"
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default m
+ 	help
+@@ -132,7 +121,7 @@ config ACPI_FAN
+ 
+ config ACPI_PROCESSOR
+ 	tristate "Processor"
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default m
+ 	help
+@@ -152,14 +141,15 @@ config ACPI_THERMAL
+ 
+ config ACPI_NUMA
+ 	bool "NUMA support"
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on NUMA
+ 	depends on !X86_64
+ 	default y if IA64_GENERIC || IA64_SGI_SN2
+ 
+ config ACPI_ASUS
+         tristate "ASUS/Medion Laptop Extras"
+-        depends on X86 && ACPI
++	depends on X86
++	depends on ACPI_INTERPRETER
+ 	default m
+         ---help---
+           This driver provides support for extra features of ACPI-compatible
+@@ -170,6 +160,9 @@ config ACPI_ASUS
+           display brightness and output, switching the LCD backlight on and off,
+           and most importantly, allows you to blink those fancy LEDs intended
+           for reporting mail and wireless status.
++
++	  Note: display switching code is currently considered EXPERIMENTAL,
++	  toying with these values may even lock your machine.
+           
+           All settings are changed via /proc/acpi/asus directory entries. Owner
+           and group for these entries can be set with asus_uid and asus_gid
+@@ -185,7 +178,8 @@ config ACPI_ASUS
+           
+ config ACPI_TOSHIBA
+ 	tristate "Toshiba Laptop Extras"
+-	depends on X86 && ACPI
++	depends on X86
++	depends on ACPI_INTERPRETER
+ 	default m
+ 	---help---
+ 	  This driver adds support for access to certain system settings
+@@ -212,7 +206,7 @@ config ACPI_TOSHIBA
+ 
+ config ACPI_DEBUG
+ 	bool "Debug Statements"
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default n
+ 	help
+@@ -222,19 +216,14 @@ config ACPI_DEBUG
+ 
+ config ACPI_BUS
+ 	bool
+-	depends on ACPI
+-	depends on !IA64_SGI_SN
+-	default y
+-
+-config ACPI_INTERPRETER
+-	bool
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default y
+ 
+ config ACPI_EC
+ 	bool
+-	depends on X86 && ACPI
++	depends on X86
++	depends on ACPI_INTERPRETER
+ 	default y
+ 	help
+ 	  This driver is required on some systems for the proper operation of
+@@ -243,19 +232,19 @@ config ACPI_EC
+ 
+ config ACPI_POWER
+ 	bool
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default y
+ 
+ config ACPI_PCI
+ 	bool
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default PCI
+ 
+ config ACPI_SYSTEM
+ 	bool
+-	depends on ACPI
++	depends on ACPI_INTERPRETER
+ 	depends on !IA64_SGI_SN
+ 	default y
+ 	help
+@@ -263,10 +252,28 @@ config ACPI_SYSTEM
+ 	  dump your ACPI DSDT table using /proc/acpi/dsdt.
+ 
+ config ACPI_EFI
+-	bool
+-	depends on ACPI
+-	depends on IA64
+-	default y
++ 	bool "Obtain RSDP from EFI Configuration Table"
++	depends on ACPI_INTERPRETER
++	depends on IA64 || X86
++  	default n
++ 	help
++ 	   On EFI Systems the RSDP pointer is passed to the kernel via
++ 	   the EFI Configuration Table.  On Itanium systems this is
++ 	   standard and required.  For IA-32, systems that have
++ 	   EFI firmware should leave this enabled.  Platforms with
++ 	   traditional legacy BIOS should disable this option.
++
++config ACPI_RELAXED_AML
++	bool "Relaxed AML"
++	depends on ACPI_INTERPRETER
++	depends on !IA64_SGI_SN
++	default n
++	help
++	  If you say `Y' here, the ACPI interpreter will relax its checking
++	  for valid AML and will ignore some AML mistakes, such as off-by-one
++	  errors in region sizes.  Some laptops may require this option.  In
++	  particular, many Toshiba laptops require this for correct operation
++	  of the AC module.
+ 
+ endmenu
+ 
+--- linux-2.6.0-test6/drivers/acpi/Makefile	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/Makefile	2003-10-05 00:33:23.000000000 -0700
+@@ -18,7 +18,7 @@ obj-$(CONFIG_ACPI)		:= acpi_ksyms.o 
+ # ACPI Boot-Time Table Parsing
+ #
+ obj-$(CONFIG_ACPI_BOOT)		+= tables.o
+-obj-$(CONFIG_ACPI)		+= blacklist.o
++obj-$(CONFIG_ACPI_INTERPRETER)	+= blacklist.o
+ 
+ #
+ # ACPI Core Subsystem (Interpreter)
+--- linux-2.6.0-test6/drivers/acpi/namespace/nsdump.c	2003-06-14 12:18:33.000000000 -0700
++++ 25/drivers/acpi/namespace/nsdump.c	2003-10-05 00:33:24.000000000 -0700
+@@ -234,7 +234,7 @@ acpi_ns_dump_one_object (
+ 
+ 		case ACPI_TYPE_DEVICE:
+ 
+-			acpi_os_printf ("Notify object: %p", obj_desc);
++			acpi_os_printf ("Notify Object: %p\n", obj_desc);
+ 			break;
+ 
+ 
+@@ -371,7 +371,7 @@ acpi_ns_dump_one_object (
+ 		case ACPI_TYPE_LOCAL_BANK_FIELD:
+ 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+ 
+-			acpi_os_printf (" Off %.2X Len %.2X Acc %.2hd\n",
++			acpi_os_printf ("Off %.2X Len %.2X Acc %.2hd\n",
+ 					(obj_desc->common_field.base_byte_offset * 8)
+ 						+ obj_desc->common_field.start_field_bit_offset,
+ 					obj_desc->common_field.bit_length,
+--- linux-2.6.0-test6/drivers/acpi/namespace/nssearch.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/acpi/namespace/nssearch.c	2003-10-05 00:33:24.000000000 -0700
+@@ -96,7 +96,7 @@ acpi_ns_search_node (
+ 
+ 		scope_name = acpi_ns_get_external_pathname (node);
+ 		if (scope_name) {
+-			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (%s)\n",
++			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n",
+ 				scope_name, node, (char *) &target_name, acpi_ut_get_type_name (type)));
+ 
+ 			ACPI_MEM_FREE (scope_name);
+@@ -117,9 +117,9 @@ acpi_ns_search_node (
+ 			 * Found matching entry.
+ 			 */
+ 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+-				"Name %4.4s Type [%s] found in scope [%4.4s] %p\n",
++				"Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
+ 				(char *) &target_name, acpi_ut_get_type_name (next_node->type),
+-				next_node->name.ascii, next_node));
++				next_node, node->name.ascii, node));
+ 
+ 			*return_node = next_node;
+ 			return_ACPI_STATUS (AE_OK);
+@@ -143,7 +143,7 @@ acpi_ns_search_node (
+ 	/* Searched entire namespace level, not found */
+ 
+ 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+-		"Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n",
++		"Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+ 		(char *) &target_name, acpi_ut_get_type_name (type),
+ 		node->name.ascii, node, node->child));
+ 
+--- linux-2.6.0-test6/drivers/acpi/namespace/nsutils.c	2003-06-14 12:18:21.000000000 -0700
++++ 25/drivers/acpi/namespace/nsutils.c	2003-10-05 00:33:24.000000000 -0700
+@@ -175,6 +175,11 @@ acpi_ns_print_node_pathname (
+ 	acpi_status                     status;
+ 
+ 
++	if (!node) {
++		acpi_os_printf ("[NULL NAME]");
++		return;
++	}
++
+ 	/* Convert handle to a full pathname and print it (with supplied message) */
+ 
+ 	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+@@ -470,11 +475,11 @@ acpi_ns_build_internal_name (
+ 	*result = 0;
+ 
+ 	if (info->fully_qualified) {
+-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (abs) \"\\%s\"\n",
++		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
+ 			internal_name, internal_name));
+ 	}
+ 	else {
+-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) \"%s\"\n",
++		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
+ 			internal_name, internal_name));
+ 	}
+ 
+--- linux-2.6.0-test6/drivers/acpi/osl.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/osl.c	2003-10-05 00:36:22.000000000 -0700
+@@ -43,7 +43,6 @@
+ 
+ #ifdef CONFIG_ACPI_EFI
+ #include <linux/efi.h>
+-u64 efi_mem_attributes (u64 phys_addr);
+ #endif
+ 
+ 
+--- linux-2.6.0-test6/drivers/acpi/parser/psparse.c	2003-06-14 12:17:59.000000000 -0700
++++ 25/drivers/acpi/parser/psparse.c	2003-10-05 00:33:24.000000000 -0700
+@@ -437,7 +437,6 @@ acpi_ps_parse_loop (
+ 		return_ACPI_STATUS (AE_BAD_PARAMETER);
+ 	}
+ 
+-
+ 	parser_state = &walk_state->parser_state;
+ 	walk_state->arg_types = 0;
+ 
+@@ -705,10 +704,9 @@ acpi_ps_parse_loop (
+ 				walk_state->arg_types = 0;
+ 				break;
+ 
+-
+ 			default:
+ 
+-				/* Op is not a constant or string, append each argument */
++				/* Op is not a constant or string, append each argument to the Op */
+ 
+ 				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
+ 						!walk_state->arg_count) {
+@@ -727,23 +725,23 @@ acpi_ps_parse_loop (
+ 					INCREMENT_ARG_LIST (walk_state->arg_types);
+ 				}
+ 
++				/* Special processing for certain opcodes */
++
+ 				switch (op->common.aml_opcode) {
+ 				case AML_METHOD_OP:
+ 
+-					/* For a method, save the length and address of the body */
+-
+ 					/*
+-					 * Skip parsing of control method or opregion body,
++					 * Skip parsing of control method
+ 					 * because we don't have enough info in the first pass
+-					 * to parse them correctly.
++					 * to parse it correctly.
++					 *
++					 * Save the length and address of the body
+ 					 */
+ 					op->named.data   = parser_state->aml;
+ 					op->named.length = (u32) (parser_state->pkg_end - parser_state->aml);
+-					/*
+-					 * Skip body of method.  For op_regions, we must continue
+-					 * parsing because the opregion is not a standalone
+-					 * package (We don't know where the end is).
+-					 */
++
++					/* Skip body of method */
++
+ 					parser_state->aml   = parser_state->pkg_end;
+ 					walk_state->arg_count = 0;
+ 					break;
+@@ -756,15 +754,15 @@ acpi_ps_parse_loop (
+ 						(op->common.parent->common.aml_opcode == AML_NAME_OP) &&
+ 						(walk_state->descending_callback != acpi_ds_exec_begin_op)) {
+ 						/*
+-						 * Skip parsing of
++						 * Skip parsing of Buffers and Packages
+ 						 * because we don't have enough info in the first pass
+ 						 * to parse them correctly.
+ 						 */
+ 						op->named.data   = aml_op_start;
+ 						op->named.length = (u32) (parser_state->pkg_end - aml_op_start);
+-						/*
+-						 * Skip body
+-						 */
++
++						/* Skip body */
++
+ 						parser_state->aml   = parser_state->pkg_end;
+ 						walk_state->arg_count = 0;
+ 					}
+@@ -778,6 +776,7 @@ acpi_ps_parse_loop (
+ 					break;
+ 
+ 				default:
++
+ 					/* No action for all other opcodes */
+ 					break;
+ 				}
+--- linux-2.6.0-test6/drivers/acpi/pci_irq.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/pci_irq.c	2003-10-05 00:36:20.000000000 -0700
+@@ -71,6 +71,9 @@ acpi_pci_irq_find_prt_entry (
+ 
+ 	ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry");
+ 
++	if (!acpi_prt.count)
++		return_PTR(NULL);
++
+ 	/*
+ 	 * Parse through all PRT entries looking for a match on the specified
+ 	 * PCI device's segment, bus, device, and pin (don't care about func).
+@@ -234,7 +237,7 @@ acpi_pci_irq_add_prt (
+                           PCI Interrupt Routing Support
+    -------------------------------------------------------------------------- */
+ 
+-static int
++int
+ acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
+ {
+ 	struct acpi_prt_entry	*entry = NULL;
+--- linux-2.6.0-test6/drivers/acpi/pci_link.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/acpi/pci_link.c	2003-10-05 00:33:24.000000000 -0700
+@@ -220,7 +220,6 @@ acpi_pci_link_check_current (
+ 	return AE_CTRL_TERMINATE;
+ }
+ 
+-
+ static int
+ acpi_pci_link_get_current (
+ 	struct acpi_pci_link	*link)
+@@ -279,6 +278,28 @@ end:
+ 	return_VALUE(result);
+ }
+ 
++static int
++acpi_pci_link_try_get_current (
++	struct acpi_pci_link *link,
++	int irq)
++{
++	int result;
++
++	ACPI_FUNCTION_TRACE("acpi_pci_link_try_get_current");
++
++	result = acpi_pci_link_get_current(link);
++	if (result && link->irq.active) {
++ 		return_VALUE(result);
++ 	}
++
++	if (!link->irq.active) {
++		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No active IRQ resource found\n"));
++		printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for device (%s [%s]).\n", irq, acpi_device_name(link->device), acpi_device_bid(link->device));
++		link->irq.active = irq;
++	}
++	
++	return 0;
++}
+ 
+ static int
+ acpi_pci_link_set (
+@@ -294,6 +315,7 @@ acpi_pci_link_set (
+ 	struct acpi_buffer	buffer = {sizeof(resource)+1, &resource};
+ 	int			i = 0;
+ 	int			valid = 0;
++	int			resource_type = 0;
+ 
+ 	ACPI_FUNCTION_TRACE("acpi_pci_link_set");
+ 
+@@ -317,20 +339,32 @@ acpi_pci_link_set (
+ 		}
+ 	}
+ 
++	/* If IRQ<=15, first try with a "normal" IRQ descriptor. If that fails, try with
++	 * an extended one */
++	if (irq <= 15) {
++		resource_type = ACPI_RSTYPE_IRQ;
++	} else {
++		resource_type = ACPI_RSTYPE_EXT_IRQ;
++	}
++
++retry_programming:
++   
+ 	memset(&resource, 0, sizeof(resource));
+ 
+ 	/* NOTE: PCI interrupts are always level / active_low / shared. But not all
+ 	   interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for 
+ 	   parameters */
+-	if (irq <= 15) {
++	switch(resource_type) {
++	case ACPI_RSTYPE_IRQ:
+ 		resource.res.id = ACPI_RSTYPE_IRQ;
+ 		resource.res.length = sizeof(struct acpi_resource);
+ 		resource.res.data.irq.edge_level = link->irq.edge_level;
+ 		resource.res.data.irq.active_high_low = link->irq.active_high_low;
+ 		resource.res.data.irq.number_of_interrupts = 1;
+ 		resource.res.data.irq.interrupts[0] = irq;
+-	}
+-	else {
++		break;
++	   
++	case ACPI_RSTYPE_EXT_IRQ:
+ 		resource.res.id = ACPI_RSTYPE_EXT_IRQ;
+ 		resource.res.length = sizeof(struct acpi_resource);
+ 		resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
+@@ -339,11 +373,21 @@ acpi_pci_link_set (
+ 		resource.res.data.extended_irq.number_of_interrupts = 1;
+ 		resource.res.data.extended_irq.interrupts[0] = irq;
+ 		/* ignore resource_source, it's optional */
++		break;
+ 	}
+ 	resource.end.id = ACPI_RSTYPE_END_TAG;
+ 
+ 	/* Attempt to set the resource */
+ 	status = acpi_set_current_resources(link->handle, &buffer);
++
++	/* if we failed and IRQ <= 15, try again with an extended descriptor */
++	if (ACPI_FAILURE(status) && (resource_type == ACPI_RSTYPE_IRQ)) {
++                resource_type = ACPI_RSTYPE_EXT_IRQ;
++                printk(PREFIX "Retrying with extended IRQ descriptor\n");
++                goto retry_programming;
++	}
++  
++	/* check for total failure */
+ 	if (ACPI_FAILURE(status)) {
+ 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
+ 		return_VALUE(-ENODEV);
+@@ -361,7 +405,7 @@ acpi_pci_link_set (
+ 	}
+ 
+ 	/* Make sure the active IRQ is the one we requested. */
+-	result = acpi_pci_link_get_current(link);
++	result = acpi_pci_link_try_get_current(link, irq);
+ 	if (result) {
+ 		return_VALUE(result);
+ 	}
+@@ -456,16 +500,16 @@ static int acpi_pci_link_allocate(struct
+ 		irq = link->irq.active;
+ 	} else {
+ 		irq = link->irq.possible[0];
+-	}
+ 
+-		/* 
+-		 * Select the best IRQ.  This is done in reverse to promote 
++		/*
++		 * Select the best IRQ.  This is done in reverse to promote
+ 		 * the use of IRQs 9, 10, 11, and >15.
+ 		 */
+ 		for (i=(link->irq.possible_count-1); i>0; i--) {
+ 			if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
+ 				irq = link->irq.possible[i];
+ 		}
++	}
+ 
+ 	/* Attempt to enable the link device at this IRQ. */
+ 	if (acpi_pci_link_set(link, irq)) {
+@@ -574,10 +618,6 @@ acpi_pci_link_add (
+ 		else
+ 			printk(" %d", link->irq.possible[i]);
+ 	}
+-	if (!link->irq.active)
+-		printk(", disabled");
+-	else if (!found)
+-		printk(", enabled at IRQ %d", link->irq.active);
+ 	printk(")\n");
+ 
+ 	/* TBD: Acquire/release lock */
+--- linux-2.6.0-test6/drivers/acpi/tables.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/tables.c	2003-10-05 00:33:24.000000000 -0700
+@@ -69,7 +69,8 @@ struct acpi_table_sdt {
+ 
+ static unsigned long		sdt_pa;		/* Physical Address */
+ static unsigned long		sdt_count;	/* Table count */
+-static struct acpi_table_sdt	*sdt_entry;
++
++static struct acpi_table_sdt	sdt_entry[ACPI_MAX_TABLES];
+ 
+ void
+ acpi_table_print (
+@@ -418,12 +419,6 @@ acpi_table_get_sdt (
+ 			sdt_count = ACPI_MAX_TABLES;
+ 		}
+ 
+-		sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
+-		if (!sdt_entry) {
+-			printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
+-			return -ENOMEM;
+-		}
+-
+ 		for (i = 0; i < sdt_count; i++)
+ 			sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
+ 	}
+@@ -470,12 +465,6 @@ acpi_table_get_sdt (
+ 			sdt_count = ACPI_MAX_TABLES;
+ 		}
+ 
+-		sdt_entry = alloc_bootmem(sdt_count * sizeof(struct acpi_table_sdt));
+-		if (!sdt_entry) {
+-			printk(KERN_ERR "ACPI: Could not allocate mem for SDT entries!\n");
+-			return -ENOMEM;
+-		}
+-
+ 		for (i = 0; i < sdt_count; i++)
+ 			sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
+ 	}
+--- linux-2.6.0-test6/drivers/acpi/toshiba_acpi.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/acpi/toshiba_acpi.c	2003-10-05 00:33:24.000000000 -0700
+@@ -41,7 +41,6 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/proc_fs.h>
+-#include <linux/version.h>
+ 
+ #include <acpi/acpi_drivers.h>
+ 
+--- linux-2.6.0-test6/drivers/acpi/utilities/utdelete.c	2003-06-14 12:18:20.000000000 -0700
++++ 25/drivers/acpi/utilities/utdelete.c	2003-10-05 00:34:43.000000000 -0700
+@@ -417,6 +417,8 @@ acpi_ut_update_object_reference (
+ 	union acpi_generic_state         *state_list = NULL;
+ 	union acpi_generic_state         *state;
+ 
++	union acpi_operand_object        *tmp;
++
+ 
+ 	ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
+ 
+@@ -448,8 +450,15 @@ acpi_ut_update_object_reference (
+ 		switch (ACPI_GET_OBJECT_TYPE (object)) {
+ 		case ACPI_TYPE_DEVICE:
+ 
+-			acpi_ut_update_ref_count (object->device.system_notify, action);
+-			acpi_ut_update_ref_count (object->device.device_notify, action);
++			tmp = object->device.system_notify;
++			if(tmp && tmp->common.reference_count<=1 && action == REF_DECREMENT)
++				object->device.system_notify = NULL;
++			acpi_ut_update_ref_count (tmp, action);
++
++			tmp = object->device.device_notify;
++			if(tmp && tmp->common.reference_count <=1 && action == REF_DECREMENT)
++				object->device.device_notify = NULL;
++			acpi_ut_update_ref_count (tmp, action);
+ 			break;
+ 
+ 
+@@ -467,6 +476,9 @@ acpi_ut_update_object_reference (
+ 				 */
+ 				status = acpi_ut_create_update_state_and_push (
+ 						 object->package.elements[i], action, &state_list);
++				tmp = object->package.elements[i];
++				if(tmp && tmp->common.reference_count<=1  && action == REF_DECREMENT) /*reference count didn't refresh now*/
++					object->package.elements[i] = NULL;
+ 				if (ACPI_FAILURE (status)) {
+ 					goto error_exit;
+ 				}
+@@ -478,6 +490,9 @@ acpi_ut_update_object_reference (
+ 
+ 			status = acpi_ut_create_update_state_and_push (
+ 					 object->buffer_field.buffer_obj, action, &state_list);
++			tmp = object->buffer_field.buffer_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->buffer_field.buffer_obj = NULL;
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
+@@ -491,6 +506,9 @@ acpi_ut_update_object_reference (
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
++			tmp = object->field.region_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->field.region_obj = NULL;
+ 		   break;
+ 
+ 
+@@ -501,12 +519,18 @@ acpi_ut_update_object_reference (
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
++			tmp = object->bank_field.bank_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->bank_field.bank_obj = NULL;
+ 
+ 			status = acpi_ut_create_update_state_and_push (
+ 					 object->bank_field.region_obj, action, &state_list);
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
++			tmp = object->bank_field.region_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->bank_field.region_obj = NULL;
+ 			break;
+ 
+ 
+@@ -517,12 +541,18 @@ acpi_ut_update_object_reference (
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
++			tmp = object->index_field.index_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->index_field.index_obj = NULL;
+ 
+ 			status = acpi_ut_create_update_state_and_push (
+ 					 object->index_field.data_obj, action, &state_list);
+ 			if (ACPI_FAILURE (status)) {
+ 				goto error_exit;
+ 			}
++			tmp = object->index_field.data_obj;
++			if( tmp && tmp->common.reference_count <=1  && action == REF_DECREMENT)/*reference count didn't refresh now*/
++				object->index_field.data_obj = NULL;
+ 			break;
+ 
+ 
+--- linux-2.6.0-test6/drivers/block/acsi.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/acsi.c	2003-10-05 00:34:00.000000000 -0700
+@@ -63,6 +63,7 @@ typedef void Scsi_Device; /* hack to avo
+ #include <linux/hdreg.h> /* for HDIO_GETGEO */
+ #include <linux/blkpg.h>
+ #include <linux/buffer_head.h>
++#include <linux/blkdev.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/pgtable.h>
+@@ -346,7 +347,7 @@ struct acsi_error {
+ static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
+                         rwflag, int enable);
+ static int acsi_reqsense( char *buffer, int targ, int lun);
+-static void acsi_print_error(const unsigned char *errblk, int struct acsi_info_struct *aip);
++static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip);
+ static irqreturn_t acsi_interrupt (int irq, void *data, struct pt_regs *fp);
+ static void unexpected_acsi_interrupt( void );
+ static void bad_rw_intr( void );
+@@ -358,10 +359,9 @@ static void copy_from_acsibuffer( void )
+ static void do_end_requests( void );
+ static void do_acsi_request( request_queue_t * );
+ static void redo_acsi_request( void );
+-static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
++static int acsi_ioctl(struct block_device *bdev, struct file *file, unsigned int
+                        cmd, unsigned long arg );
+-static int acsi_open( struct inode * inode, struct file * filp );
+-static int acsi_release( struct inode * inode, struct file * file );
++static int acsi_open(struct block_device *bdev, struct file *filp);
+ static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag );
+ static int acsi_change_blk_size( int target, int lun);
+ static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
+@@ -1080,10 +1080,10 @@ static void redo_acsi_request( void )
+  ***********************************************************************/
+ 
+ 
+-static int acsi_ioctl( struct inode *inode, struct file *file,
+-					   unsigned int cmd, unsigned long arg )
++static int acsi_ioctl(struct block_device *bdev, struct file *file,
++		      unsigned int cmd, unsigned long arg )
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct acsi_info_struct *aip = disk->private_data;
+ 	switch (cmd) {
+ 	  case HDIO_GETGEO:
+@@ -1095,7 +1095,7 @@ static int acsi_ioctl( struct inode *ino
+ 	    put_user( 64, &geo->heads );
+ 	    put_user( 32, &geo->sectors );
+ 	    put_user( aip->size >> 11, &geo->cylinders );
+-		put_user(get_start_sect(inode->i_bdev), &geo->start);
++		put_user(get_start_sect(bdev), &geo->start);
+ 		return 0;
+ 	  }
+ 	  case SCSI_IOCTL_GET_IDLUN:
+@@ -1125,16 +1125,16 @@ static int acsi_ioctl( struct inode *ino
+  *
+  */
+ 
+-static int acsi_open( struct inode * inode, struct file * filp )
++static int acsi_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct acsi_info_struct *aip = disk->private_data;
+ 
+ 	if (aip->access_count == 0 && aip->removable) {
+ #if 0
+ 		aip->changed = 1;	/* safety first */
+ #endif
+-		check_disk_change( inode->i_bdev );
++		check_disk_change(bdev);
+ 		if (aip->changed)	/* revalidate was not successful (no medium) */
+ 			return -ENXIO;
+ 		acsi_prevent_removal(aip, 1);
+@@ -1142,10 +1142,11 @@ static int acsi_open( struct inode * ino
+ 	aip->access_count++;
+ 
+ 	if (filp && filp->f_mode) {
+-		check_disk_change( inode->i_bdev );
++		check_disk_change(bdev);
+ 		if (filp->f_mode & 2) {
+ 			if (aip->read_only) {
+-				acsi_release( inode, filp );
++				if (--aip->access_count == 0 && aip->removable)
++					acsi_prevent_removal(aip, 0);
+ 				return -EROFS;
+ 			}
+ 		}
+@@ -1159,9 +1160,8 @@ static int acsi_open( struct inode * ino
+  * be forgotten about...
+  */
+ 
+-static int acsi_release( struct inode * inode, struct file * file )
++static int acsi_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct acsi_info_struct *aip = disk->private_data;
+ 	if (--aip->access_count == 0 && aip->removable)
+ 		acsi_prevent_removal(aip, 0);
+@@ -1327,8 +1327,6 @@ static int acsi_mode_sense( int target, 
+  ********************************************************************/
+ 
+ 
+-extern struct block_device_operations acsi_fops;
+-
+ static struct gendisk *acsi_gendisk[MAX_DEV];
+ 
+ #define MAX_SCSI_DEVICE_CODE 10
+--- linux-2.6.0-test6/drivers/block/amiflop.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/amiflop.c	2003-10-05 00:34:00.000000000 -0700
+@@ -1434,10 +1434,11 @@ static void do_fd_request(request_queue_
+ 	redo_fd_request();
+ }
+ 
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+ 		    unsigned int cmd, unsigned long param)
+ {
+-	int drive = iminor(inode) & 3;
++	struct amiga_floppy_struct *floppy = bdev->bd_disk->private_data;
++	int drive = floppy - unit;
+ 	static struct floppy_struct getprm;
+ 
+ 	switch(cmd){
+@@ -1459,7 +1460,7 @@ static int fd_ioctl(struct inode *inode,
+ 			rel_fdc();
+ 			return -EBUSY;
+ 		}
+-		fsync_bdev(inode->i_bdev);
++		fsync_bdev(bdev);
+ 		if (fd_motor_on(drive) == 0) {
+ 			rel_fdc();
+ 			return -ENODEV;
+@@ -1488,7 +1489,7 @@ static int fd_ioctl(struct inode *inode,
+ 		break;
+ 	case FDFMTEND:
+ 		floppy_off(drive);
+-		invalidate_bdev(inode->i_bdev, 0);
++		invalidate_bdev(bdev, 0);
+ 		break;
+ 	case FDGETPRM:
+ 		memset((void *)&getprm, 0, sizeof (getprm));
+@@ -1559,10 +1560,11 @@ static void fd_probe(int dev)
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	int drive = iminor(inode) & 3;
+-	int system =  (iminor(inode) & 4) >> 2;
++	struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
++	int drive = p - unit;
++	int system =  (MINOR(bdev->bd_dev) & 4) >> 2;
+ 	int old_dev;
+ 	unsigned long flags;
+ 
+@@ -1572,7 +1574,7 @@ static int floppy_open(struct inode *ino
+ 		return -EBUSY;
+ 
+ 	if (filp && filp->f_mode & 3) {
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		if (filp->f_mode & 2 ) {
+ 			int wrprot;
+ 
+@@ -1607,9 +1609,10 @@ static int floppy_open(struct inode *ino
+ 	return 0;
+ }
+ 
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	int drive = iminor(inode) & 3;
++	struct amiga_floppy_struct *p = disk->private_data;
++	int drive = p - unit;
+ 
+ 	if (unit[drive].dirty == 1) {
+ 		del_timer (flush_track_timer + drive);
+--- linux-2.6.0-test6/drivers/block/as-iosched.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/as-iosched.c	2003-10-05 00:36:08.000000000 -0700
+@@ -174,12 +174,14 @@ static kmem_cache_t *arq_pool;
+  * IO Context helper functions
+  */
+ /* Debug */
+-static atomic_t nr_as_io_requests = ATOMIC_INIT(0);
++extern atomic_t global_nr_requests;
++static atomic_t nr_as_io_contexts = ATOMIC_INIT(0);
+ 
+ /* Called to deallocate the as_io_context */
+ static void free_as_io_context(struct as_io_context *aic)
+ {
+-	atomic_dec(&nr_as_io_requests);
++	WARN_ON(atomic_read(&nr_as_io_contexts) == 0);
++	atomic_dec(&nr_as_io_contexts);
+ 	kfree(aic);
+ }
+ 
+@@ -195,7 +197,9 @@ static struct as_io_context *alloc_as_io
+ 
+ 	ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
+ 	if (ret) {
+-		atomic_inc(&nr_as_io_requests);
++		atomic_inc(&nr_as_io_contexts);
++		WARN_ON(atomic_read(&nr_as_io_contexts) ==
++			1 + nr_threads + atomic_read(&global_nr_requests));
+ 		ret->dtor = free_as_io_context;
+ 		ret->exit = exit_as_io_context;
+ 		ret->state = 1 << AS_TASK_RUNNING;
+@@ -914,6 +918,8 @@ static void as_completed_request(request
+ 	struct as_rq *arq = RQ_DATA(rq);
+ 	struct as_io_context *aic;
+ 
++	WARN_ON(!list_empty(&rq->queuelist));
++
+ 	if (unlikely(arq->state != AS_RQ_DISPATCHED))
+ 		return;
+ 
+@@ -926,6 +932,7 @@ static void as_completed_request(request
+ 		if (ad->batch_data_dir == REQ_SYNC)
+ 			ad->new_batch = 1;
+ 	}
++	WARN_ON(ad->nr_dispatched == 0);
+ 	ad->nr_dispatched--;
+ 
+ 	/*
+@@ -1140,8 +1147,6 @@ static void as_move_to_dispatch(struct a
+ 	/*
+ 	 * take it off the sort and fifo list, add to dispatch queue
+ 	 */
+-	as_remove_queued_request(ad->q, rq);
+-
+ 	insert = ad->dispatch->prev;
+ 
+ 	while (!list_empty(&rq->queuelist)) {
+@@ -1159,6 +1164,7 @@ static void as_move_to_dispatch(struct a
+ 		ad->nr_dispatched++;
+ 	}
+ 
++	as_remove_queued_request(ad->q, rq);
+ 	list_add(&rq->queuelist, insert);
+ 	if (arq->io_context && arq->io_context->aic)
+ 		atomic_inc(&arq->io_context->aic->nr_dispatched);
+@@ -1325,12 +1331,27 @@ static struct request *as_next_request(r
+ static inline void
+ as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
+ {
++	struct request  *req = arq->request;
++	struct list_head *insert = alias->request->queuelist.prev;
++
++	/*
++	 * Transfer list of aliases
++	 */
++	while (!list_empty(&req->queuelist)) {
++		struct request *__rq = list_entry_rq(req->queuelist.next);
++		struct as_rq *__arq = RQ_DATA(__rq);
++
++		list_move_tail(&__rq->queuelist, &alias->request->queuelist);
++
++		WARN_ON(__arq->state != AS_RQ_QUEUED);
++	}
++
+ 	/*
+ 	 * Another request with the same start sector on the rbtree.
+ 	 * Link this request to that sector. They are untangled in
+ 	 * as_move_to_dispatch
+ 	 */
+-	list_add_tail(&arq->request->queuelist, &alias->request->queuelist);
++	list_add(&arq->request->queuelist, insert);
+ 
+ 	/*
+ 	 * Don't want to have to handle merges.
+@@ -1390,9 +1411,6 @@ static void as_add_request(struct as_dat
+ 		}
+ 	}
+ 
+-
+-
+-
+ 	arq->state = AS_RQ_QUEUED;
+ }
+ 
+@@ -1596,7 +1614,8 @@ static void as_merged_request(request_qu
+ 		 */
+ 	}
+ 
+-	q->last_merge = req;
++	if (arq->on_hash)
++		q->last_merge = req;
+ }
+ 
+ static void
+--- linux-2.6.0-test6/drivers/block/ataflop.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/ataflop.c	2003-10-05 00:34:00.000000000 -0700
+@@ -364,13 +364,12 @@ static void finish_fdc_done( int dummy )
+ static __inline__ void copy_buffer( void *from, void *to);
+ static void setup_req_params( int drive );
+ static void redo_fd_request( void);
+-static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int
+                      cmd, unsigned long param);
+ static void fd_probe( int drive );
+ static int fd_test_drive_present( int drive );
+ static void config_types( void );
+-static int floppy_open( struct inode *inode, struct file *filp );
+-static int floppy_release( struct inode * inode, struct file * filp );
++static int floppy_open(struct block_device *bdev, struct file *filp );
+ 
+ /************************* End of Prototypes **************************/
+ 
+@@ -1496,10 +1495,10 @@ void do_fd_request(request_queue_t * q)
+ 	atari_enable_irq( IRQ_MFP_FDC );
+ }
+ 
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+ 		    unsigned int cmd, unsigned long param)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct atari_floppy_struct *floppy = disk->private_data;
+ 	int drive = floppy - unit;
+ 	int type = floppy->type;
+@@ -1673,7 +1672,7 @@ static int fd_ioctl(struct inode *inode,
+ 		/* invalidate the buffer track to force a reread */
+ 		BufferDrive = -1;
+ 		set_bit(drive, &fake_change);
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		return 0;
+ 	default:
+ 		return -EINVAL;
+@@ -1816,10 +1815,10 @@ static void __init config_types( void )
+  * drive with different device numbers.
+  */
+ 
+-static int floppy_open( struct inode *inode, struct file *filp )
++static int floppy_open(struct block_device *bdev, struct file *filp )
+ {
+-	struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
+-	int type  = iminor(inode) >> 2;
++	struct atari_floppy_struct *p = bdev->bd_disk->private_data;
++	int type  = MINOR(bdev->bd_dev) >> 2;
+ 
+ 	DPRINT(("fd_open: type=%d\n",type));
+ 	if (p->ref && p->type != type)
+@@ -1839,14 +1838,13 @@ static int floppy_open( struct inode *in
+ 		return 0;
+ 
+ 	if (filp->f_mode & 3) {
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		if (filp->f_mode & 2) {
+ 			if (p->wpstat) {
+ 				if (p->ref < 0)
+ 					p->ref = 0;
+ 				else
+ 					p->ref--;
+-				floppy_release(inode, filp);
+ 				return -EROFS;
+ 			}
+ 		}
+@@ -1855,9 +1853,9 @@ static int floppy_open( struct inode *in
+ }
+ 
+ 
+-static int floppy_release( struct inode * inode, struct file * filp )
++static int floppy_release(struct gendisk *disk)
+ {
+-	struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
++	struct atari_floppy_struct *p = disk->private_data;
+ 	if (p->ref < 0)
+ 		p->ref = 0;
+ 	else if (!p->ref--) {
+--- linux-2.6.0-test6/drivers/block/cciss.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/cciss.c	2003-10-05 00:34:00.000000000 -0700
+@@ -111,12 +111,10 @@ static struct board_type products[] = {
+ 
+ static ctlr_info_t *hba[MAX_CTLR];
+ 
+-static struct proc_dir_entry *proc_cciss;
+-
+ static void do_cciss_request(request_queue_t *q);
+-static int cciss_open(struct inode *inode, struct file *filep);
+-static int cciss_release(struct inode *inode, struct file *filep);
+-static int cciss_ioctl(struct inode *inode, struct file *filep, 
++static int cciss_open(struct block_device *bdev, struct file *filep);
++static int cciss_release(struct gendisk *disk);
++static int cciss_ioctl(struct block_device *bdev, struct file *filep, 
+ 		unsigned int cmd, unsigned long arg);
+ 
+ static int revalidate_allvol(ctlr_info_t *host);
+@@ -137,8 +135,6 @@ static int cciss_proc_get_info(char *buf
+ 		int length, int *eof, void *data);
+ static void cciss_procinit(int i);
+ #else
+-static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
+-		int length, int *eof, void *data) { return 0;}
+ static void cciss_procinit(int i) {}
+ #endif /* CONFIG_PROC_FS */
+ 
+@@ -156,6 +152,9 @@ static struct block_device_operations cc
+  * Report information about this controller.
+  */
+ #ifdef CONFIG_PROC_FS
++
++static struct proc_dir_entry *proc_cciss;
++
+ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
+ 		int length, int *eof, void *data)
+ {
+@@ -363,13 +362,13 @@ static inline drive_info_struct *get_drv
+ /*
+  * Open.  Make sure the device is really there.
+  */
+-static int cciss_open(struct inode *inode, struct file *filep)
++static int cciss_open(struct block_device *bdev, struct file *filep)
+ {
+-	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+-	drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
++	ctlr_info_t *host = get_host(bdev->bd_disk);
++	drive_info_struct *drv = get_drv(bdev->bd_disk);
+ 
+ #ifdef CCISS_DEBUG
+-	printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
++	printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
+ #endif /* CCISS_DEBUG */ 
+ 
+ 	/*
+@@ -379,7 +378,7 @@ static int cciss_open(struct inode *inod
+ 	 * for "raw controller".
+ 	 */
+ 	if (drv->nr_blocks == 0) {
+-		if (iminor(inode) != 0)
++		if (bdev != bdev->bd_contains || drv != host->drv)
+ 			return -ENXIO;
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+@@ -391,13 +390,13 @@ static int cciss_open(struct inode *inod
+ /*
+  * Close.  Sync first.
+  */
+-static int cciss_release(struct inode *inode, struct file *filep)
++static int cciss_release(struct gendisk *disk)
+ {
+-	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+-	drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
++	ctlr_info_t *host = get_host(disk);
++	drive_info_struct *drv = get_drv(disk);
+ 
+ #ifdef CCISS_DEBUG
+-	printk(KERN_DEBUG "cciss_release %s\n", inode->i_bdev->bd_disk->disk_name);
++	printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name);
+ #endif /* CCISS_DEBUG */
+ 
+ 	drv->usage_count--;
+@@ -408,10 +407,9 @@ static int cciss_release(struct inode *i
+ /*
+  * ioctl 
+  */
+-static int cciss_ioctl(struct inode *inode, struct file *filep, 
++static int cciss_ioctl(struct block_device *bdev, struct file *filep, 
+ 		unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	struct gendisk *disk = bdev->bd_disk;
+ 	ctlr_info_t *host = get_host(disk);
+ 	drive_info_struct *drv = get_drv(disk);
+@@ -434,7 +432,7 @@ static int cciss_ioctl(struct inode *ino
+                         driver_geo.sectors = 0x3f;
+                         driver_geo.cylinders = (int)drv->nr_blocks / (0xff*0x3f);
+                 }
+-                driver_geo.start= get_start_sect(inode->i_bdev);
++                driver_geo.start= get_start_sect(bdev);
+                 if (copy_to_user((void *) arg, &driver_geo,
+                                 sizeof( struct hd_geometry)))
+                         return  -EFAULT;
+@@ -636,9 +634,11 @@ static int cciss_ioctl(struct inode *ino
+ 		{	
+ 			return -EINVAL;
+ 		} 
++#if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
+ 		/* Check kmalloc limits */
+ 		if(iocommand.buf_size > 128000)
+ 			return -EINVAL;
++#endif
+ 		if(iocommand.buf_size > 0)
+ 		{
+ 			buff =  kmalloc(iocommand.buf_size, GFP_KERNEL);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/block/cfq-iosched.c	2003-10-05 00:34:17.000000000 -0700
+@@ -0,0 +1,707 @@
++/*
++ *  linux/drivers/block/cfq-iosched.c
++ *
++ *  CFQ, or complete fairness queueing, disk scheduler.
++ *
++ *  Based on ideas from a previously unfinished io
++ *  scheduler (round robin per-process disk scheduling) and Andrea Arcangeli.
++ *
++ *  Copyright (C) 2003 Jens Axboe <axboe@suse.de>
++ */
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/blkdev.h>
++#include <linux/elevator.h>
++#include <linux/bio.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/compiler.h>
++#include <linux/hash.h>
++#include <linux/rbtree.h>
++#include <linux/mempool.h>
++
++/*
++ * tunables
++ */
++static int cfq_quantum = 4;
++static int cfq_queued = 8;
++
++#define CFQ_QHASH_SHIFT		6
++#define CFQ_QHASH_ENTRIES	(1 << CFQ_QHASH_SHIFT)
++#define list_entry_qhash(entry)	list_entry((entry), struct cfq_queue, cfq_hash)
++
++#define CFQ_MHASH_SHIFT		8
++#define CFQ_MHASH_BLOCK(sec)	((sec) >> 3)
++#define CFQ_MHASH_ENTRIES	(1 << CFQ_MHASH_SHIFT)
++#define CFQ_MHASH_FN(sec)	(hash_long(CFQ_MHASH_BLOCK((sec)),CFQ_MHASH_SHIFT))
++#define ON_MHASH(crq)		!list_empty(&(crq)->hash)
++#define rq_hash_key(rq)		((rq)->sector + (rq)->nr_sectors)
++#define list_entry_hash(ptr)	list_entry((ptr), struct cfq_rq, hash)
++
++#define list_entry_cfqq(ptr)	list_entry((ptr), struct cfq_queue, cfq_list)
++
++#define RQ_DATA(rq)		((struct cfq_rq *) (rq)->elevator_private)
++
++static kmem_cache_t *crq_pool;
++static kmem_cache_t *cfq_pool;
++static mempool_t *cfq_mpool;
++
++struct cfq_data {
++	struct list_head rr_list;
++	struct list_head *dispatch;
++	struct list_head *cfq_hash;
++
++	struct list_head *crq_hash;
++
++	unsigned int busy_queues;
++	unsigned int max_queued;
++
++	mempool_t *crq_pool;
++};
++
++struct cfq_queue {
++	struct list_head cfq_hash;
++	struct list_head cfq_list;
++	struct rb_root sort_list;
++	int pid;
++	int queued[2];
++#if 0
++	/*
++	 * with a simple addition like this, we can do io priorities. almost.
++	 * does need a split request free list, too.
++	 */
++	int io_prio
++#endif
++};
++
++struct cfq_rq {
++	struct rb_node rb_node;
++	sector_t rb_key;
++
++	struct request *request;
++
++	struct cfq_queue *cfq_queue;
++
++	struct list_head hash;
++};
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq);
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid);
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq);
++
++/*
++ * lots of deadline iosched dupes, can be abstracted later...
++ */
++static inline void __cfq_del_crq_hash(struct cfq_rq *crq)
++{
++	list_del_init(&crq->hash);
++}
++
++static inline void cfq_del_crq_hash(struct cfq_rq *crq)
++{
++	if (ON_MHASH(crq))
++		__cfq_del_crq_hash(crq);
++}
++
++static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
++{
++	cfq_del_crq_hash(crq);
++
++	if (q->last_merge == crq->request)
++		q->last_merge = NULL;
++}
++
++static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++	struct request *rq = crq->request;
++
++	BUG_ON(ON_MHASH(crq));
++
++	list_add(&crq->hash, &cfqd->crq_hash[CFQ_MHASH_FN(rq_hash_key(rq))]);
++}
++
++static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
++{
++	struct list_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
++	struct list_head *entry, *next = hash_list->next;
++
++	while ((entry = next) != hash_list) {
++		struct cfq_rq *crq = list_entry_hash(entry);
++		struct request *__rq = crq->request;
++
++		next = entry->next;
++
++		BUG_ON(!ON_MHASH(crq));
++
++		if (!rq_mergeable(__rq)) {
++			__cfq_del_crq_hash(crq);
++			continue;
++		}
++
++		if (rq_hash_key(__rq) == offset)
++			return __rq;
++	}
++
++	return NULL;
++}
++
++/*
++ * rb tree support functions
++ */
++#define RB_NONE		(2)
++#define RB_EMPTY(node)	((node)->rb_node == NULL)
++#define RB_CLEAR(node)	((node)->rb_color = RB_NONE)
++#define RB_CLEAR_ROOT(root)	((root)->rb_node = NULL)
++#define ON_RB(node)	((node)->rb_color != RB_NONE)
++#define rb_entry_crq(node)	rb_entry((node), struct cfq_rq, rb_node)
++#define rq_rb_key(rq)		(rq)->sector
++
++static inline void cfq_del_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++	if (ON_RB(&crq->rb_node)) {
++		cfqq->queued[rq_data_dir(crq->request)]--;
++		rb_erase(&crq->rb_node, &cfqq->sort_list);
++		crq->cfq_queue = NULL;
++	}
++}
++
++static struct cfq_rq *
++__cfq_add_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++	struct rb_node **p = &cfqq->sort_list.rb_node;
++	struct rb_node *parent = NULL;
++	struct cfq_rq *__crq;
++
++	while (*p) {
++		parent = *p;
++		__crq = rb_entry_crq(parent);
++
++		if (crq->rb_key < __crq->rb_key)
++			p = &(*p)->rb_left;
++		else if (crq->rb_key > __crq->rb_key)
++			p = &(*p)->rb_right;
++		else
++			return __crq;
++	}
++
++	rb_link_node(&crq->rb_node, parent, p);
++	return 0;
++}
++
++static void
++cfq_add_crq_rb(struct cfq_data *cfqd, struct cfq_queue *cfqq,struct cfq_rq *crq)
++{
++	struct request *rq = crq->request;
++	struct cfq_rq *__alias;
++
++	crq->rb_key = rq_rb_key(rq);
++	cfqq->queued[rq_data_dir(rq)]++;
++retry:
++	__alias = __cfq_add_crq_rb(cfqq, crq);
++	if (!__alias) {
++		rb_insert_color(&crq->rb_node, &cfqq->sort_list);
++		crq->cfq_queue = cfqq;
++		return;
++	}
++
++	cfq_del_crq_rb(cfqq, __alias);
++	cfq_dispatch_sort(cfqd->dispatch, __alias);
++	goto retry;
++}
++
++static struct request *
++cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
++{
++	struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++	struct rb_node *n;
++
++	if (!cfqq)
++		goto out;
++
++	n = cfqq->sort_list.rb_node;
++	while (n) {
++		struct cfq_rq *crq = rb_entry_crq(n);
++
++		if (sector < crq->rb_key)
++			n = n->rb_left;
++		else if (sector > crq->rb_key)
++			n = n->rb_right;
++		else
++			return crq->request;
++	}
++
++out:
++	return NULL;
++}
++
++static void cfq_remove_request(request_queue_t *q, struct request *rq)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_rq *crq = RQ_DATA(rq);
++
++	if (crq) {
++		struct cfq_queue *cfqq = crq->cfq_queue;
++
++		cfq_remove_merge_hints(q, crq);
++		list_del_init(&rq->queuelist);
++
++		if (cfqq) {
++			cfq_del_crq_rb(cfqq, crq);
++
++			if (RB_EMPTY(&cfqq->sort_list))
++				cfq_put_queue(cfqd, cfqq);
++		}
++	}
++}
++
++static int
++cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct request *__rq;
++	int ret;
++
++	ret = elv_try_last_merge(q, bio);
++	if (ret != ELEVATOR_NO_MERGE) {
++		__rq = q->last_merge;
++		goto out_insert;
++	}
++
++	__rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
++	if (__rq) {
++		BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
++
++		if (elv_rq_merge_ok(__rq, bio)) {
++			ret = ELEVATOR_BACK_MERGE;
++			goto out;
++		}
++	}
++
++	__rq = cfq_find_rq_rb(cfqd, bio->bi_sector + bio_sectors(bio));
++	if (__rq) {
++		if (elv_rq_merge_ok(__rq, bio)) {
++			ret = ELEVATOR_FRONT_MERGE;
++			goto out;
++		}
++	}
++
++	return ELEVATOR_NO_MERGE;
++out:
++	q->last_merge = __rq;
++out_insert:
++	*req = __rq;
++	return ret;
++}
++
++static void cfq_merged_request(request_queue_t *q, struct request *req)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_rq *crq = RQ_DATA(req);
++
++	cfq_del_crq_hash(crq);
++	cfq_add_crq_hash(cfqd, crq);
++
++	if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
++		struct cfq_queue *cfqq = crq->cfq_queue;
++
++		cfq_del_crq_rb(cfqq, crq);
++		cfq_add_crq_rb(cfqd, cfqq, crq);
++	}
++
++	q->last_merge = req;
++}
++
++static void
++cfq_merged_requests(request_queue_t *q, struct request *req,
++		    struct request *next)
++{
++	cfq_merged_request(q, req);
++	cfq_remove_request(q, next);
++}
++
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq)
++{
++	struct list_head *entry = head;
++	struct request *__rq;
++
++	if (!list_empty(head)) {
++		__rq = list_entry_rq(head->next);
++
++		if (crq->request->sector < __rq->sector) {
++			entry = head->prev;
++			goto link;
++		}
++	}
++
++	while ((entry = entry->prev) != head) {
++		__rq = list_entry_rq(entry);
++
++		if (crq->request->sector <= __rq->sector)
++			break;
++	}
++
++link:
++	list_add_tail(&crq->request->queuelist, entry);
++}
++
++static inline void
++__cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd,
++			struct cfq_queue *cfqq)
++{
++	struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
++
++	cfq_del_crq_rb(cfqq, crq);
++	cfq_remove_merge_hints(q, crq);
++	cfq_dispatch_sort(cfqd->dispatch, crq);
++}
++
++static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
++{
++	struct cfq_queue *cfqq;
++	struct list_head *entry, *tmp;
++	int ret, queued, good_queues;
++
++	if (list_empty(&cfqd->rr_list))
++		return 0;
++
++	queued = ret = 0;
++restart:
++	good_queues = 0;
++	list_for_each_safe(entry, tmp, &cfqd->rr_list) {
++		cfqq = list_entry_cfqq(cfqd->rr_list.next);
++
++		BUG_ON(RB_EMPTY(&cfqq->sort_list));
++
++		__cfq_dispatch_requests(q, cfqd, cfqq);
++
++		if (RB_EMPTY(&cfqq->sort_list))
++			cfq_put_queue(cfqd, cfqq);
++		else
++			good_queues++;
++
++		queued++;
++		ret = 1;
++	}
++
++	if ((queued < cfq_quantum) && good_queues)
++		goto restart;
++
++	return ret;
++}
++
++static struct request *cfq_next_request(request_queue_t *q)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct request *rq;
++
++	if (!list_empty(cfqd->dispatch)) {
++		struct cfq_rq *crq;
++dispatch:
++		rq = list_entry_rq(cfqd->dispatch->next);
++
++		BUG_ON(q->last_merge == rq);
++		crq = RQ_DATA(rq);
++		if (crq)
++			BUG_ON(ON_MHASH(crq));
++
++		return rq;
++	}
++
++	if (cfq_dispatch_requests(q, cfqd))
++		goto dispatch;
++
++	return NULL;
++}
++
++static inline struct cfq_queue *
++__cfq_find_cfq_hash(struct cfq_data *cfqd, int pid, const int hashval)
++{
++	struct list_head *hash_list = &cfqd->cfq_hash[hashval];
++	struct list_head *entry;
++
++	list_for_each(entry, hash_list) {
++		struct cfq_queue *__cfqq = list_entry_qhash(entry);
++
++		if (__cfqq->pid == pid)
++			return __cfqq;
++	}
++
++	return NULL;
++}
++
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid)
++{
++	const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++
++	return __cfq_find_cfq_hash(cfqd, pid, hashval);
++}
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
++{
++	cfqd->busy_queues--;
++	list_del(&cfqq->cfq_list);
++	list_del(&cfqq->cfq_hash);
++	mempool_free(cfqq, cfq_mpool);
++}
++
++static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, int pid)
++{
++	const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++	struct cfq_queue *cfqq = __cfq_find_cfq_hash(cfqd, pid, hashval);
++
++	if (!cfqq) {
++		cfqq = mempool_alloc(cfq_mpool, GFP_NOIO);
++
++		INIT_LIST_HEAD(&cfqq->cfq_hash);
++		INIT_LIST_HEAD(&cfqq->cfq_list);
++		RB_CLEAR_ROOT(&cfqq->sort_list);
++
++		cfqq->pid = pid;
++		cfqq->queued[0] = cfqq->queued[1] = 0;
++		list_add(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
++	}
++
++	return cfqq;
++}
++
++static void cfq_enqueue(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++	struct cfq_queue *cfqq;
++
++	cfqq = cfq_get_queue(cfqd, current->tgid);
++
++	cfq_add_crq_rb(cfqd, cfqq, crq);
++
++	if (list_empty(&cfqq->cfq_list)) {
++		list_add(&cfqq->cfq_list, &cfqd->rr_list);
++		cfqd->busy_queues++;
++	}
++}
++
++static void
++cfq_insert_request(request_queue_t *q, struct request *rq, int where)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_rq *crq = RQ_DATA(rq);
++
++	switch (where) {
++		case ELEVATOR_INSERT_BACK:
++			while (cfq_dispatch_requests(q, cfqd))
++				;
++			list_add_tail(&rq->queuelist, cfqd->dispatch);
++			break;
++		case ELEVATOR_INSERT_FRONT:
++			list_add(&rq->queuelist, cfqd->dispatch);
++			break;
++		case ELEVATOR_INSERT_SORT:
++			BUG_ON(!blk_fs_request(rq));
++			cfq_enqueue(cfqd, crq);
++			break;
++		default:
++			printk("%s: bad insert point %d\n", __FUNCTION__,where);
++			return;
++	}
++
++	if (rq_mergeable(rq)) {
++		cfq_add_crq_hash(cfqd, crq);
++
++		if (!q->last_merge)
++			q->last_merge = rq;
++	}
++}
++
++static int cfq_queue_empty(request_queue_t *q)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++
++	if (list_empty(cfqd->dispatch) && list_empty(&cfqd->rr_list))
++		return 1;
++
++	return 0;
++}
++
++static struct request *
++cfq_former_request(request_queue_t *q, struct request *rq)
++{
++	struct cfq_rq *crq = RQ_DATA(rq);
++	struct rb_node *rbprev = rb_prev(&crq->rb_node);
++
++	if (rbprev)
++		return rb_entry_crq(rbprev)->request;
++
++	return NULL;
++}
++
++static struct request *
++cfq_latter_request(request_queue_t *q, struct request *rq)
++{
++	struct cfq_rq *crq = RQ_DATA(rq);
++	struct rb_node *rbnext = rb_next(&crq->rb_node);
++
++	if (rbnext)
++		return rb_entry_crq(rbnext)->request;
++
++	return NULL;
++}
++
++static int cfq_may_queue(request_queue_t *q, int rw)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_queue *cfqq;
++	int ret = 1;
++
++	if (!cfqd->busy_queues)
++		goto out;
++
++	cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++	if (cfqq) {
++		int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
++
++		if (limit < 3)
++			limit = 3;
++		else if (limit > cfqd->max_queued)
++			limit = cfqd->max_queued;
++
++		if (cfqq->queued[rw] > limit)
++			ret = 0;
++	}
++out:
++	return ret;
++}
++
++static void cfq_put_request(request_queue_t *q, struct request *rq)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_rq *crq = RQ_DATA(rq);
++
++	if (crq) {
++		BUG_ON(q->last_merge == rq);
++		BUG_ON(ON_MHASH(crq));
++
++		mempool_free(crq, cfqd->crq_pool);
++		rq->elevator_private = NULL;
++	}
++}
++
++static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
++{
++	struct cfq_data *cfqd = q->elevator.elevator_data;
++	struct cfq_rq *crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
++
++	if (crq) {
++		RB_CLEAR(&crq->rb_node);
++		crq->request = rq;
++		crq->cfq_queue = NULL;
++		INIT_LIST_HEAD(&crq->hash);
++		rq->elevator_private = crq;
++		return 0;
++	}
++
++	return 1;
++}
++
++static void cfq_exit(request_queue_t *q, elevator_t *e)
++{
++	struct cfq_data *cfqd = e->elevator_data;
++
++	e->elevator_data = NULL;
++	mempool_destroy(cfqd->crq_pool);
++	kfree(cfqd->crq_hash);
++	kfree(cfqd->cfq_hash);
++	kfree(cfqd);
++}
++
++static int cfq_init(request_queue_t *q, elevator_t *e)
++{
++	struct cfq_data *cfqd;
++	int i;
++
++	cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
++	if (!cfqd)
++		return -ENOMEM;
++
++	memset(cfqd, 0, sizeof(*cfqd));
++	INIT_LIST_HEAD(&cfqd->rr_list);
++
++	cfqd->crq_hash = kmalloc(sizeof(struct list_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
++	if (!cfqd->crq_hash)
++		goto out_crqhash;
++
++	cfqd->cfq_hash = kmalloc(sizeof(struct list_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
++	if (!cfqd->cfq_hash)
++		goto out_cfqhash;
++
++	cfqd->crq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, crq_pool);
++	if (!cfqd->crq_pool)
++		goto out_crqpool;
++
++	for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
++		INIT_LIST_HEAD(&cfqd->crq_hash[i]);
++	for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
++		INIT_LIST_HEAD(&cfqd->cfq_hash[i]);
++
++	cfqd->dispatch = &q->queue_head;
++	e->elevator_data = cfqd;
++
++	/*
++	 * just set it to some high value, we want anyone to be able to queue
++	 * some requests. fairness is handled differently
++	 */
++	cfqd->max_queued = q->nr_requests;
++	q->nr_requests = 8192;
++
++	return 0;
++out_crqpool:
++	kfree(cfqd->cfq_hash);
++out_cfqhash:
++	kfree(cfqd->crq_hash);
++out_crqhash:
++	kfree(cfqd);
++	return -ENOMEM;
++}
++
++static int __init cfq_slab_setup(void)
++{
++	crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0,
++					NULL, NULL);
++
++	if (!crq_pool)
++		panic("cfq_iosched: can't init crq pool\n");
++
++	cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
++					NULL, NULL);
++
++	if (!cfq_pool)
++		panic("cfq_iosched: can't init cfq pool\n");
++
++	cfq_mpool = mempool_create(64, mempool_alloc_slab, mempool_free_slab, cfq_pool);
++
++	if (!cfq_mpool)
++		panic("cfq_iosched: can't init cfq mpool\n");
++
++	return 0;
++}
++
++subsys_initcall(cfq_slab_setup);
++
++elevator_t iosched_cfq = {
++	.elevator_name =		"cfq",
++	.elevator_merge_fn = 		cfq_merge,
++	.elevator_merged_fn =		cfq_merged_request,
++	.elevator_merge_req_fn =	cfq_merged_requests,
++	.elevator_next_req_fn =		cfq_next_request,
++	.elevator_add_req_fn =		cfq_insert_request,
++	.elevator_remove_req_fn =	cfq_remove_request,
++	.elevator_queue_empty_fn =	cfq_queue_empty,
++	.elevator_former_req_fn =	cfq_former_request,
++	.elevator_latter_req_fn =	cfq_latter_request,
++	.elevator_set_req_fn =		cfq_set_request,
++	.elevator_put_req_fn =		cfq_put_request,
++	.elevator_may_queue_fn =	cfq_may_queue,
++	.elevator_init_fn =		cfq_init,
++	.elevator_exit_fn =		cfq_exit,
++};
++
++EXPORT_SYMBOL(iosched_cfq);
+--- linux-2.6.0-test6/drivers/block/cpqarray.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/cpqarray.c	2003-10-05 00:34:00.000000000 -0700
+@@ -99,8 +99,6 @@ static struct board_type products[] = {
+ 
+ static struct gendisk *ida_gendisk[MAX_CTLR][NWD];
+ 
+-static struct proc_dir_entry *proc_array;
+-
+ /* Debug... */
+ #define DBG(s)	do { s } while(0)
+ /* Debug (general info)... */
+@@ -130,9 +128,9 @@ static int sendcmd(
+ 	unsigned int blkcnt,
+ 	unsigned int log_unit );
+ 
+-static int ida_open(struct inode *inode, struct file *filep);
+-static int ida_release(struct inode *inode, struct file *filep);
+-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
++static int ida_open(struct block_device *bdev, struct file *filep);
++static int ida_release(struct gendisk *disk);
++static int ida_ioctl(struct block_device *bdev, struct file *filep, unsigned int cmd, unsigned long arg);
+ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
+ 
+ static void do_ida_request(request_queue_t *q);
+@@ -153,8 +151,6 @@ static void ida_procinit(int i);
+ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
+ #else
+ static void ida_procinit(int i) {}
+-static int ida_proc_get_info(char *buffer, char **start, off_t offset,
+-			     int length, int *eof, void *data) { return 0;}
+ #endif
+ 
+ static inline drv_info_t *get_drv(struct gendisk *disk)
+@@ -179,6 +175,8 @@ static struct block_device_operations id
+ 
+ #ifdef CONFIG_PROC_FS
+ 
++static struct proc_dir_entry *proc_array;
++
+ /*
+  * Get us a file in /proc/array that says something about each controller.
+  * Create /proc/array if it doesn't exist yet.
+@@ -717,12 +715,12 @@ DBGINFO(
+ /*
+  * Open.  Make sure the device is really there.
+  */
+-static int ida_open(struct inode *inode, struct file *filep)
++static int ida_open(struct block_device *bdev, struct file *filep)
+ {
+-	drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+-	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++	drv_info_t *drv = get_drv(bdev->bd_disk);
++	ctlr_info_t *host = get_host(bdev->bd_disk);
+ 
+-	DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name));
++	DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name));
+ 	/*
+ 	 * Root is allowed to open raw volume zero even if it's not configured
+ 	 * so array config can still work.  I don't think I really like this,
+@@ -742,9 +740,9 @@ static int ida_open(struct inode *inode,
+ /*
+  * Close.  Sync first.
+  */
+-static int ida_release(struct inode *inode, struct file *filep)
++static int ida_release(struct gendisk *disk)
+ {
+-	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++	ctlr_info_t *host = get_host(disk);
+ 	host->usage_count--;
+ 	return 0;
+ }
+@@ -1024,10 +1022,10 @@ static void ida_timer(unsigned long tdat
+  *  ida_ioctl does some miscellaneous stuff like reporting drive geometry,
+  *  setting readahead and submitting commands from userspace to the controller.
+  */
+-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
++static int ida_ioctl(struct block_device *bdev, struct file *filep, unsigned int cmd, unsigned long arg)
+ {
+-	drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+-	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++	drv_info_t *drv = get_drv(bdev->bd_disk);
++	ctlr_info_t *host = get_host(bdev->bd_disk);
+ 	int error;
+ 	int diskinfo[4];
+ 	struct hd_geometry *geo = (struct hd_geometry *)arg;
+@@ -1048,7 +1046,7 @@ static int ida_ioctl(struct inode *inode
+ 		put_user(diskinfo[0], &geo->heads);
+ 		put_user(diskinfo[1], &geo->sectors);
+ 		put_user(diskinfo[2], &geo->cylinders);
+-		put_user(get_start_sect(inode->i_bdev), &geo->start);
++		put_user(get_start_sect(bdev), &geo->start);
+ 		return 0;
+ 	case IDAGETDRVINFO:
+ 		if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
+@@ -1078,7 +1076,7 @@ out_passthru:
+ 		put_user(host->ctlr_sig, (int*)arg);
+ 		return 0;
+ 	case IDAREVALIDATEVOLS:
+-		if (iminor(inode) != 0)
++		if (bdev != bdev->bd_contains || drv != host->drv)
+ 			return -ENXIO;
+ 		return revalidate_allvol(host);
+ 	case IDADRIVERVERSION:
+--- linux-2.6.0-test6/drivers/block/DAC960.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/DAC960.c	2003-10-05 00:33:58.000000000 -0700
+@@ -67,9 +67,9 @@ static long disk_size(DAC960_Controller_
+ 	}
+ }
+ 
+-static int DAC960_open(struct inode *inode, struct file *file)
++static int DAC960_open(struct block_device *bdev, struct file *file)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	DAC960_Controller_T *p = disk->queue->queuedata;
+ 	int drive_nr = (long)disk->private_data;
+ 
+@@ -84,17 +84,17 @@ static int DAC960_open(struct inode *ino
+ 			return -ENXIO;
+ 	}
+ 
+-	check_disk_change(inode->i_bdev);
++	check_disk_change(bdev);
+ 
+ 	if (!get_capacity(p->disks[drive_nr]))
+ 		return -ENXIO;
+ 	return 0;
+ }
+ 
+-static int DAC960_ioctl(struct inode *inode, struct file *file,
++static int DAC960_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	DAC960_Controller_T *p = disk->queue->queuedata;
+ 	int drive_nr = (long)disk->private_data;
+ 	struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+@@ -128,7 +128,7 @@ static int DAC960_ioctl(struct inode *in
+ 		g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);
+ 	}
+ 	
+-	g.start = get_start_sect(inode->i_bdev);
++	g.start = get_start_sect(bdev);
+ 
+ 	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+--- linux-2.6.0-test6/drivers/block/floppy98.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/floppy98.c	2003-10-05 00:34:01.000000000 -0700
+@@ -3484,14 +3484,14 @@ static int get_floppy_geometry(int drive
+ 	return 0;
+ }
+ 
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int cmd,
+ 		    unsigned long param)
+ {
+ #define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+ #define OUT(c,x) case c: outparam = (const char *) (x); break
+ #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
+ 
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)bdev->bd_disk->private_data;
+ 	int i, type = ITYPE(UDRS->fd_device);
+ 	int ret;
+ 	int size;
+@@ -3566,11 +3566,11 @@ static int fd_ioctl(struct inode *inode,
+ 			current_type[drive] = NULL;
+ 			floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+ 			UDRS->keep_data = 0;
+-			return invalidate_drive(inode->i_bdev);
++			return invalidate_drive(bdev);
+ 		case FDSETPRM:
+ 		case FDDEFPRM:
+ 			return set_geometry(cmd, & inparam.g,
+-					    drive, type, inode->i_bdev);
++					    drive, type, bdev);
+ 		case FDGETPRM:
+ 			ECALL(get_floppy_geometry(drive, type, 
+ 						  (struct floppy_struct**)
+@@ -3625,7 +3625,7 @@ static int fd_ioctl(struct inode *inode,
+ 		case FDFMTEND:
+ 		case FDFLUSH:
+ 			LOCK_FDC(drive,1);
+-			return invalidate_drive(inode->i_bdev);
++			return invalidate_drive(bdev);
+ 
+ 		case FDSETEMSGTRESH:
+ 			UDP->max_errors.reporting =
+@@ -3735,9 +3735,9 @@ static void __init config_types(void)
+ 		printk("\n");
+ }
+ 
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)disk->private_data;
+ 
+ 	down(&open_lock);
+ 	if (UDRS->fd_ref < 0)
+@@ -3758,11 +3758,10 @@ static int floppy_release(struct inode *
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-#define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0)
+ 
+-static int floppy_open(struct inode * inode, struct file * filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)bdev->bd_disk->private_data;
+ 	int old_dev;
+ 	int try;
+ 	int res = -EBUSY;
+@@ -3789,7 +3788,7 @@ static int floppy_open(struct inode * in
+ 
+ 	down(&open_lock);
+ 	old_dev = UDRS->fd_device;
+-	if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
++	if (opened_bdev[drive] && opened_bdev[drive] != bdev)
+ 		goto out2;
+ 
+ 	if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
+@@ -3809,7 +3808,7 @@ static int floppy_open(struct inode * in
+ 	else
+ 		UDRS->fd_ref++;
+ 
+-	opened_bdev[drive] = inode->i_bdev;
++	opened_bdev[drive] = bdev;
+ 
+ 	res = -ENXIO;
+ 
+@@ -3844,9 +3843,9 @@ static int floppy_open(struct inode * in
+ 		}
+ 	}
+ 
+-	UDRS->fd_device = iminor(inode);
+-	set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
+-	if (old_dev != -1 && old_dev != iminor(inode)) {
++	UDRS->fd_device = MINOR(bdev->bd_dev);
++	set_capacity(disks[drive], floppy_sizes[MINOR(bdev->bd_dev)]);
++	if (old_dev != -1 && old_dev != MINOR(bdev->bd_dev)) {
+ 		if (buffer_drive == drive)
+ 			buffer_track = -1;
+ 	}
+@@ -3859,8 +3858,7 @@ static int floppy_open(struct inode * in
+ 	/* Allow ioctls if we have write-permissions even if read-only open.
+ 	 * Needed so that programs such as fdrawcmd still can work on write
+ 	 * protected disks */
+-	if ((filp->f_mode & 2) || 
+-	    (inode->i_sb && (permission(inode,2) == 0)))
++	if ((filp->f_mode & 2) || permission(filp->f_dentry->d_inode,2) == 0)
+ 	    filp->private_data = (void*) 8;
+ 
+ 	if (UFDCS->rawcmd == 1)
+@@ -3873,7 +3871,7 @@ static int floppy_open(struct inode * in
+ 	if (!(filp->f_flags & O_NDELAY)) {
+ 		if (filp->f_mode & 3) {
+ 			UDRS->last_checked = 0;
+-			check_disk_change(inode->i_bdev);
++			check_disk_change(bdev);
+ 			if (UTESTF(FD_DISK_CHANGED))
+ 				goto out;
+ 		}
+--- linux-2.6.0-test6/drivers/block/floppy.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/floppy.c	2003-10-05 00:34:01.000000000 -0700
+@@ -3456,14 +3456,14 @@ static int get_floppy_geometry(int drive
+ 	return 0;
+ }
+ 
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int cmd,
+ 		    unsigned long param)
+ {
+ #define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+ #define OUT(c,x) case c: outparam = (const char *) (x); break
+ #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
+ 
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)bdev->bd_disk->private_data;
+ 	int i, type = ITYPE(UDRS->fd_device);
+ 	int ret;
+ 	int size;
+@@ -3539,11 +3539,11 @@ static int fd_ioctl(struct inode *inode,
+ 			current_type[drive] = NULL;
+ 			floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+ 			UDRS->keep_data = 0;
+-			return invalidate_drive(inode->i_bdev);
++			return invalidate_drive(bdev);
+ 		case FDSETPRM:
+ 		case FDDEFPRM:
+ 			return set_geometry(cmd, & inparam.g,
+-					    drive, type, inode->i_bdev);
++					    drive, type, bdev);
+ 		case FDGETPRM:
+ 			ECALL(get_floppy_geometry(drive, type, 
+ 						  (struct floppy_struct**)
+@@ -3574,7 +3574,7 @@ static int fd_ioctl(struct inode *inode,
+ 		case FDFMTEND:
+ 		case FDFLUSH:
+ 			LOCK_FDC(drive,1);
+-			return invalidate_drive(inode->i_bdev);
++			return invalidate_drive(bdev);
+ 
+ 		case FDSETEMSGTRESH:
+ 			UDP->max_errors.reporting =
+@@ -3685,9 +3685,9 @@ static void __init config_types(void)
+ 		printk("\n");
+ }
+ 
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)disk->private_data;
+ 
+ 	down(&open_lock);
+ 	if (UDRS->fd_ref < 0)
+@@ -3708,9 +3708,9 @@ static int floppy_release(struct inode *
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-static int floppy_open(struct inode * inode, struct file * filp)
++static int floppy_open(struct block_device *bdev, struct file * filp)
+ {
+-	int drive = (long)inode->i_bdev->bd_disk->private_data;
++	int drive = (long)bdev->bd_disk->private_data;
+ 	int old_dev;
+ 	int try;
+ 	int res = -EBUSY;
+@@ -3719,7 +3719,7 @@ static int floppy_open(struct inode * in
+ 	filp->private_data = (void*) 0;
+ 	down(&open_lock);
+ 	old_dev = UDRS->fd_device;
+-	if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
++	if (opened_bdev[drive] && opened_bdev[drive] != bdev)
+ 		goto out2;
+ 
+ 	if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
+@@ -3739,7 +3739,7 @@ static int floppy_open(struct inode * in
+ 	else
+ 		UDRS->fd_ref++;
+ 
+-	opened_bdev[drive] = inode->i_bdev;
++	opened_bdev[drive] = bdev;
+ 
+ 	res = -ENXIO;
+ 
+@@ -3774,9 +3774,9 @@ static int floppy_open(struct inode * in
+ 		}
+ 	}
+ 
+-	UDRS->fd_device = iminor(inode);
+-	set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
+-	if (old_dev != -1 && old_dev != iminor(inode)) {
++	UDRS->fd_device = MINOR(bdev->bd_dev);
++	set_capacity(disks[drive], floppy_sizes[MINOR(bdev->bd_dev)]);
++	if (old_dev != -1 && old_dev != MINOR(bdev->bd_dev)) {
+ 		if (buffer_drive == drive)
+ 			buffer_track = -1;
+ 	}
+@@ -3784,8 +3784,7 @@ static int floppy_open(struct inode * in
+ 	/* Allow ioctls if we have write-permissions even if read-only open.
+ 	 * Needed so that programs such as fdrawcmd still can work on write
+ 	 * protected disks */
+-	if ((filp->f_mode & 2) || 
+-	    (inode->i_sb && (permission(inode,2, NULL) == 0)))
++	if ((filp->f_mode & 2) || permission(filp->f_dentry->d_inode,2,NULL) == 0)
+ 	    filp->private_data = (void*) 8;
+ 
+ 	if (UFDCS->rawcmd == 1)
+@@ -3794,7 +3793,7 @@ static int floppy_open(struct inode * in
+ 	if (!(filp->f_flags & O_NDELAY)) {
+ 		if (filp->f_mode & 3) {
+ 			UDRS->last_checked = 0;
+-			check_disk_change(inode->i_bdev);
++			check_disk_change(bdev);
+ 			if (UTESTF(FD_DISK_CHANGED))
+ 				goto out;
+ 		}
+--- linux-2.6.0-test6/drivers/block/initrd.c	2003-06-14 12:18:51.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,100 +0,0 @@
+-
+-#include <linux/blkdev.h>
+-#include <linux/genhd.h>
+-#include <linux/initrd.h>
+-#include <linux/init.h>
+-#include <linux/major.h>
+-#include <linux/module.h>
+-#include <linux/spinlock.h>
+-#include <asm/uaccess.h>
+-
+-
+-unsigned long initrd_start, initrd_end;
+-int initrd_below_start_ok;
+-
+-static int initrd_users;
+-static spinlock_t initrd_users_lock = SPIN_LOCK_UNLOCKED;
+-
+-static struct gendisk *initrd_disk;
+-
+-static ssize_t initrd_read(struct file *file, char *buf,
+-			   size_t count, loff_t *ppos)
+-{
+-	int left = initrd_end - initrd_start - *ppos;
+-
+-	if (count > left)
+-		count = left;
+-	if (count == 0)
+-		return 0;
+-	if (copy_to_user(buf, (char *)initrd_start + *ppos, count))
+-		return -EFAULT;
+-
+-	*ppos += count;
+-	return count;
+-}
+-
+-static int initrd_release(struct inode *inode,struct file *file)
+-{
+-
+-	blkdev_put(inode->i_bdev, BDEV_FILE);
+-
+-	spin_lock(&initrd_users_lock);
+-	if (!--initrd_users) {
+-		spin_unlock(&initrd_users_lock);
+-		del_gendisk(initrd_disk);
+-		free_initrd_mem(initrd_start, initrd_end);
+-		initrd_start = 0;
+-	} else
+-		spin_unlock(&initrd_users_lock);
+-
+-	return 0;
+-}
+-
+-static struct file_operations initrd_fops = {
+-	.read =		initrd_read,
+-	.release =	initrd_release,
+-};
+-
+-static int initrd_open(struct inode *inode, struct file *filp)
+-{
+-	if (!initrd_start) 
+-		return -ENODEV;
+-
+-	spin_lock(&initrd_users_lock);
+-	initrd_users++;
+-	spin_unlock(&initrd_users_lock);
+-
+-	filp->f_op = &initrd_fops;
+-	return 0;
+-}
+-
+-static struct block_device_operations initrd_bdops = {
+-	.owner =	THIS_MODULE,
+-	.open =		initrd_open,
+-};
+-
+-static int __init initrd_init(void)
+-{
+-	initrd_disk = alloc_disk(1);
+-	if (!initrd_disk)
+-		return -ENOMEM;
+-
+-	initrd_disk->major = RAMDISK_MAJOR;
+-	initrd_disk->first_minor = INITRD_MINOR;
+-	initrd_disk->fops = &initrd_bdops;	
+-
+-	sprintf(initrd_disk->disk_name, "initrd");
+-	sprintf(initrd_disk->devfs_name, "rd/initrd");
+-
+-	set_capacity(initrd_disk, (initrd_end-initrd_start+511) >> 9);
+-	add_disk(initrd_disk);
+-	return 0;
+-}
+-
+-static void __exit initrd_exit(void)
+-{
+-	put_disk(initrd_disk);
+-}
+-
+-module_init(initrd_init);
+-module_exit(initrd_exit);
+--- linux-2.6.0-test6/drivers/block/ioctl.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/ioctl.c	2003-10-05 00:34:11.000000000 -0700
+@@ -132,10 +132,9 @@ static int put_u64(unsigned long arg, u6
+ 	return put_user(val, (u64 *)arg);
+ }
+ 
+-int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
++int blkdev_ioctl(struct block_device *bdev, struct file *file, unsigned cmd,
+ 			unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	struct gendisk *disk = bdev->bd_disk;
+ 	struct backing_dev_info *bdi;
+ 	int holder;
+@@ -194,7 +193,7 @@ int blkdev_ioctl(struct inode *inode, st
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EACCES;
+ 		if (disk->fops->ioctl) {
+-			ret = disk->fops->ioctl(inode, file, cmd, arg);
++			ret = disk->fops->ioctl(bdev, file, cmd, arg);
+ 			if (ret != -EINVAL)
+ 				return ret;
+ 		}
+@@ -203,7 +202,7 @@ int blkdev_ioctl(struct inode *inode, st
+ 		return 0;
+ 	case BLKROSET:
+ 		if (disk->fops->ioctl) {
+-			ret = disk->fops->ioctl(inode, file, cmd, arg);
++			ret = disk->fops->ioctl(bdev, file, cmd, arg);
+ 			if (ret != -EINVAL)
+ 				return ret;
+ 		}
+@@ -215,7 +214,7 @@ int blkdev_ioctl(struct inode *inode, st
+ 		return 0;
+ 	default:
+ 		if (disk->fops->ioctl)
+-			return disk->fops->ioctl(inode, file, cmd, arg);
++			return disk->fops->ioctl(bdev, file, cmd, arg);
+ 	}
+ 	return -ENOTTY;
+ }
+--- linux-2.6.0-test6/drivers/block/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -6,7 +6,7 @@ menu "Block devices"
+ 
+ config BLK_DEV_FD
+ 	tristate "Normal floppy disk support"
+-	depends on !X86_PC9800 && !ARCH_S390
++	depends on ISA || M68 || SPARC64
+ 	---help---
+ 	  If you want to use the floppy disk drive(s) of your PC under Linux,
+ 	  say Y. Information about this driver, especially important for IBM
+@@ -35,7 +35,7 @@ config BLK_DEV_FD98
+ 
+ config BLK_DEV_SWIM_IOP
+ 	bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)"
+-	depends on MAC && EXPERIMENTAL
++	depends on MAC && EXPERIMENTAL && BROKEN
+ 	help
+ 	  Say Y here to support the SWIM (Super Woz Integrated Machine) IOP
+ 	  floppy controller on the Macintosh IIfx and Quadra 900/950.
+@@ -63,7 +63,7 @@ config AMIGA_Z2RAM
+ 
+ config ATARI_ACSI
+ 	tristate "Atari ACSI support"
+-	depends on ATARI
++	depends on ATARI && BROKEN
+ 	---help---
+ 	  This enables support for the Atari ACSI interface. The driver
+ 	  supports hard disks and CD-ROMs, which have 512-byte sectors, or can
+--- linux-2.6.0-test6/drivers/block/Kconfig.iosched	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/block/Kconfig.iosched	2003-10-05 00:34:17.000000000 -0700
+@@ -27,3 +27,10 @@ config IOSCHED_DEADLINE
+ 	  a disk at any one time, its behaviour is almost identical to the
+ 	  anticipatory I/O scheduler and so is a good choice.
+ 
++config IOSCHED_CFQ
++	bool "CFQ I/O scheduler" if EMBEDDED
++	default y
++	---help---
++	  The CFQ I/O scheduler tries to distribute bandwidth equally
++	  among all processes in the system. It should provide a fair
++	  working environment, suitable for desktop systems.
+--- linux-2.6.0-test6/drivers/block/ll_rw_blk.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/ll_rw_blk.c	2003-10-05 00:36:58.000000000 -0700
+@@ -119,7 +119,7 @@ static void set_queue_congested(request_
+ 
+ /**
+  * blk_get_backing_dev_info - get the address of a queue's backing_dev_info
+- * @dev:	device
++ * @bdev:	device
+  *
+  * Locates the passed device's request queue and returns the address of its
+  * backing_dev_info
+@@ -414,8 +414,8 @@ void blk_queue_segment_boundary(request_
+ 
+ /**
+  * blk_queue_dma_alignment - set dma length and memory alignment
+- * @q:  the request queue for the device
+- * @dma_mask:  alignment mask
++ * @q:     the request queue for the device
++ * @mask:  alignment mask
+  *
+  * description:
+  *    set required memory and length aligment for direct dma transactions.
+@@ -1152,7 +1152,7 @@ void blk_stop_queue(request_queue_t *q)
+ 
+ /**
+  * blk_run_queue - run a single device queue
+- * @q	The queue to run
++ * @q:	The queue to run
+  */
+ void blk_run_queue(struct request_queue *q)
+ {
+@@ -1257,6 +1257,8 @@ static elevator_t *chosen_elevator =
+ 	&iosched_as;
+ #elif defined(CONFIG_IOSCHED_DEADLINE)
+ 	&iosched_deadline;
++#elif defined(CONFIG_IOSCHED_CFQ)
++	&iosched_cfq;
+ #elif defined(CONFIG_IOSCHED_NOOP)
+ 	&elevator_noop;
+ #else
+@@ -1275,6 +1277,10 @@ static int __init elevator_setup(char *s
+ 	if (!strcmp(str, "as"))
+ 		chosen_elevator = &iosched_as;
+ #endif
++#ifdef CONFIG_IOSCHED_CFQ
++	if (!strcmp(str, "cfq"))
++		chosen_elevator = &iosched_cfq;
++#endif
+ #ifdef CONFIG_IOSCHED_NOOP
+ 	if (!strcmp(str, "noop"))
+ 		chosen_elevator = &elevator_noop;
+@@ -1459,6 +1465,8 @@ static void freed_request(request_queue_
+ 	}
+ }
+ 
++atomic_t global_nr_requests = ATOMIC_INIT(0);
++
+ #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
+ /*
+  * Get a free request, queue_lock must not be held
+@@ -1536,6 +1544,8 @@ static struct request *get_request(reque
+ 	rq->data = NULL;
+ 	rq->sense = NULL;
+ 
++	atomic_inc(&global_nr_requests);
++
+ out:
+ 	put_io_context(ioc);
+ 	return rq;
+@@ -1766,6 +1776,9 @@ void __blk_put_request(request_queue_t *
+ 
+ 		blk_free_request(q, req);
+ 		freed_request(q, rw);
++
++		WARN_ON(atomic_read(&global_nr_requests) == 0);
++		atomic_dec(&global_nr_requests);
+ 	}
+ }
+ 
+@@ -1787,25 +1800,50 @@ void blk_put_request(struct request *req
+ }
+ 
+ /**
+- * blk_congestion_wait - wait for a queue to become uncongested
++ * blk_congestion_wait_wq - wait for a queue to become uncongested,
+  * @rw: READ or WRITE
+  * @timeout: timeout in jiffies
++ * @wait : wait queue entry to use for waiting or async notification
++ * (NULL defaults to synchronous behaviour)
+  *
+  * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
+  * If no queues are congested then just wait for the next request to be
+  * returned.
++ *
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, just register the callback on the wait
++ * queue for async notification when the queue gets uncongested.
+  */
+-void blk_congestion_wait(int rw, long timeout)
++int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait)
+ {
+-	DEFINE_WAIT(wait);
+ 	wait_queue_head_t *wqh = &congestion_wqh[rw];
++	DEFINE_WAIT(local_wait);
++
++	if (!wait)
++		wait = &local_wait;
+ 
+ 	blk_run_queues();
+-	prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++	prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
++	if (!is_sync_wait(wait)) {
++		/*
++		 * if we've queued an async wait queue
++		 * callback do not block; just tell the
++		 * caller to return and retry later when
++		 * the callback is notified
++		 */
++		return -EIOCBRETRY;
++	}
+ 	io_schedule_timeout(timeout);
+-	finish_wait(wqh, &wait);
++	finish_wait(wqh, wait);
++	return 0;
+ }
+ 
++void blk_congestion_wait(int rw, long timeout)
++{
++	blk_congestion_wait_wq(rw, timeout, NULL);
++}
++
++
+ /*
+  * Has to be called with the request spinlock acquired
+  */
+@@ -2592,6 +2630,7 @@ void put_io_context(struct io_context *i
+ 		if (ioc->aic && ioc->aic->dtor)
+ 			ioc->aic->dtor(ioc->aic);
+ 		kfree(ioc);
++		WARN_ON(atomic_read(&nr_io_contexts) == 0);
+ 		atomic_dec(&nr_io_contexts);
+ 	}
+ }
+@@ -2634,6 +2673,9 @@ struct io_context *get_io_context(int gf
+ 		ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
+ 		if (ret) {
+ 			atomic_inc(&nr_io_contexts);
++			WARN_ON(atomic_read(&nr_io_contexts) ==
++				1 + nr_threads + atomic_read(&global_nr_requests));
++
+ 			atomic_set(&ret->refcount, 1);
+ 			ret->pid = tsk->pid;
+ 			ret->last_waited = jiffies; /* doesn't matter... */
+--- linux-2.6.0-test6/drivers/block/loop.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/loop.c	2003-10-05 00:34:11.000000000 -0700
+@@ -140,8 +140,7 @@ figure_loop_size(struct loop_device *lo)
+ 	sector_t x;
+ 
+ 	/* Compute loopsize in bytes */
+-	size = i_size_read(lo->lo_backing_file->f_dentry->
+-				d_inode->i_mapping->host);
++	size = i_size_read(lo->lo_backing_file->f_mapping->host);
+ 	offset = lo->lo_offset;
+ 	loopsize = size - offset;
+ 	if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
+@@ -175,7 +174,7 @@ static int
+ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
+ {
+ 	struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct address_space_operations *aops = mapping->a_ops;
+ 	struct page *page;
+ 	char *kaddr, *data;
+@@ -660,6 +659,7 @@ static int loop_set_fd(struct loop_devic
+ 	struct file	*file;
+ 	struct inode	*inode;
+ 	struct block_device *lo_device = NULL;
++	struct address_space *mapping;
+ 	unsigned lo_blocksize;
+ 	int		lo_flags = 0;
+ 	int		error;
+@@ -676,14 +676,16 @@ static int loop_set_fd(struct loop_devic
+ 	if (!file)
+ 		goto out;
+ 
+-	error = -EINVAL;
+-	inode = file->f_dentry->d_inode;
++	mapping = file->f_mapping;
++	inode = mapping->host;
+ 
+ 	if (!(file->f_mode & FMODE_WRITE))
+ 		lo_flags |= LO_FLAGS_READ_ONLY;
+ 
++	error = -EINVAL;
++
+ 	if (S_ISBLK(inode->i_mode)) {
+-		lo_device = inode->i_bdev;
++		lo_device = I_BDEV(inode);
+ 		if (lo_device == bdev) {
+ 			error = -EBUSY;
+ 			goto out;
+@@ -692,7 +694,7 @@ static int loop_set_fd(struct loop_devic
+ 		if (bdev_read_only(lo_device))
+ 			lo_flags |= LO_FLAGS_READ_ONLY;
+ 	} else if (S_ISREG(inode->i_mode)) {
+-		struct address_space_operations *aops = inode->i_mapping->a_ops;
++		struct address_space_operations *aops = mapping->a_ops;
+ 		/*
+ 		 * If we can't read - sorry. If we only can't write - well,
+ 		 * it's going to be read-only.
+@@ -728,9 +730,8 @@ static int loop_set_fd(struct loop_devic
+ 		fput(file);
+ 		goto out_putf;
+ 	}
+-	lo->old_gfp_mask = mapping_gfp_mask(inode->i_mapping);
+-	mapping_set_gfp_mask(inode->i_mapping,
+-			     lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
++	lo->old_gfp_mask = mapping_gfp_mask(mapping);
++	mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
+ 
+ 	set_blocksize(bdev, lo_blocksize);
+ 
+@@ -846,7 +847,7 @@ static int loop_clr_fd(struct loop_devic
+ 	memset(lo->lo_file_name, 0, LO_NAME_SIZE);
+ 	invalidate_bdev(bdev, 0);
+ 	set_capacity(disks[lo->lo_number], 0);
+-	mapping_set_gfp_mask(filp->f_dentry->d_inode->i_mapping, gfp);
++	mapping_set_gfp_mask(filp->f_mapping, gfp);
+ 	lo->lo_state = Lo_unbound;
+ 	fput(filp);
+ 	/* This is safe: open() is still holding a reference. */
+@@ -1056,19 +1057,19 @@ loop_get_status64(struct loop_device *lo
+ 	return err;
+ }
+ 
+-static int lo_ioctl(struct inode * inode, struct file * file,
++static int lo_ioctl(struct block_device *bdev, struct file *file,
+ 	unsigned int cmd, unsigned long arg)
+ {
+-	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++	struct loop_device *lo = bdev->bd_disk->private_data;
+ 	int err;
+ 
+ 	down(&lo->lo_ctl_mutex);
+ 	switch (cmd) {
+ 	case LOOP_SET_FD:
+-		err = loop_set_fd(lo, file, inode->i_bdev, arg);
++		err = loop_set_fd(lo, file, bdev, arg);
+ 		break;
+ 	case LOOP_CLR_FD:
+-		err = loop_clr_fd(lo, inode->i_bdev);
++		err = loop_clr_fd(lo, bdev);
+ 		break;
+ 	case LOOP_SET_STATUS:
+ 		err = loop_set_status_old(lo, (struct loop_info *) arg);
+@@ -1089,9 +1090,9 @@ static int lo_ioctl(struct inode * inode
+ 	return err;
+ }
+ 
+-static int lo_open(struct inode *inode, struct file *file)
++static int lo_open(struct block_device *bdev, struct file *file)
+ {
+-	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++	struct loop_device *lo = bdev->bd_disk->private_data;
+ 
+ 	down(&lo->lo_ctl_mutex);
+ 	lo->lo_refcnt++;
+@@ -1100,9 +1101,9 @@ static int lo_open(struct inode *inode, 
+ 	return 0;
+ }
+ 
+-static int lo_release(struct inode *inode, struct file *file)
++static int lo_release(struct gendisk *disk)
+ {
+-	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++	struct loop_device *lo = disk->private_data;
+ 
+ 	down(&lo->lo_ctl_mutex);
+ 	--lo->lo_refcnt;
+--- linux-2.6.0-test6/drivers/block/Makefile	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/block/Makefile	2003-10-05 00:34:17.000000000 -0700
+@@ -18,6 +18,7 @@ obj-y	:= elevator.o ll_rw_blk.o ioctl.o 
+ obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
+ obj-$(CONFIG_IOSCHED_AS)	+= as-iosched.o
+ obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
++obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
+ obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
+ obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
+ obj-$(CONFIG_BLK_DEV_FD98)	+= floppy98.o
+@@ -28,7 +29,6 @@ obj-$(CONFIG_ATARI_ACSI)	+= acsi.o
+ obj-$(CONFIG_ATARI_SLM)		+= acsi_slm.o
+ obj-$(CONFIG_AMIGA_Z2RAM)	+= z2ram.o
+ obj-$(CONFIG_BLK_DEV_RAM)	+= rd.o
+-obj-$(CONFIG_BLK_DEV_INITRD)	+= initrd.o
+ obj-$(CONFIG_BLK_DEV_LOOP)	+= loop.o
+ obj-$(CONFIG_BLK_DEV_PS2)	+= ps2esdi.o
+ obj-$(CONFIG_BLK_DEV_XD)	+= xd.o
+--- linux-2.6.0-test6/drivers/block/nbd.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/block/nbd.c	2003-10-05 00:33:54.000000000 -0700
+@@ -535,10 +535,10 @@ static void do_nbd_request(request_queue
+ 	return;
+ }
+ 
+-static int nbd_ioctl(struct inode *inode, struct file *file,
++static int nbd_ioctl(struct block_device *bdev, struct file *file,
+ 		     unsigned int cmd, unsigned long arg)
+ {
+-	struct nbd_device *lo = inode->i_bdev->bd_disk->private_data;
++	struct nbd_device *lo = bdev->bd_disk->private_data;
+ 	int error;
+ 	struct request sreq ;
+ 
+@@ -593,7 +593,7 @@ static int nbd_ioctl(struct inode *inode
+ 		error = -EINVAL;
+ 		file = fget(arg);
+ 		if (file) {
+-			inode = file->f_dentry->d_inode;
++			struct inode *inode = file->f_dentry->d_inode;
+ 			if (inode->i_sock) {
+ 				lo->file = file;
+ 				lo->sock = SOCKET_I(inode);
+@@ -606,20 +606,20 @@ static int nbd_ioctl(struct inode *inode
+ 	case NBD_SET_BLKSIZE:
+ 		lo->blksize = arg;
+ 		lo->bytesize &= ~(lo->blksize-1);
+-		inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-		set_blocksize(inode->i_bdev, lo->blksize);
++		bdev->bd_inode->i_size = lo->bytesize;
++		set_blocksize(bdev, lo->blksize);
+ 		set_capacity(lo->disk, lo->bytesize >> 9);
+ 		return 0;
+ 	case NBD_SET_SIZE:
+ 		lo->bytesize = arg & ~(lo->blksize-1);
+-		inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-		set_blocksize(inode->i_bdev, lo->blksize);
++		bdev->bd_inode->i_size = lo->bytesize;
++		set_blocksize(bdev, lo->blksize);
+ 		set_capacity(lo->disk, lo->bytesize >> 9);
+ 		return 0;
+ 	case NBD_SET_SIZE_BLOCKS:
+ 		lo->bytesize = ((u64) arg) * lo->blksize;
+-		inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-		set_blocksize(inode->i_bdev, lo->blksize);
++		bdev->bd_inode->i_size = lo->bytesize;
++		set_blocksize(bdev, lo->blksize);
+ 		set_capacity(lo->disk, lo->bytesize >> 9);
+ 		return 0;
+ 	case NBD_DO_IT:
+@@ -664,11 +664,11 @@ static int nbd_ioctl(struct inode *inode
+ 	case NBD_PRINT_DEBUG:
+ #ifdef PARANOIA
+ 		printk(KERN_INFO "%s: next = %p, prev = %p. Global: in %d, out %d\n",
+-			inode->i_bdev->bd_disk->disk_name, lo->queue_head.next,
++			bdev->bd_disk->disk_name, lo->queue_head.next,
+ 			lo->queue_head.prev, requests_in, requests_out);
+ #else
+ 		printk(KERN_INFO "%s: next = %p, prev = %p\n",
+-			inode->i_bdev->bd_disk->disk_name,
++			bdev->bd_disk->disk_name,
+ 			lo->queue_head.next, lo->queue_head.prev);
+ #endif
+ 		return 0;
+--- linux-2.6.0-test6/drivers/block/paride/pcd.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/block/paride/pcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -243,23 +243,23 @@ static int pcd_warned;		/* Have we logge
+ 
+ /* kernel glue structures */
+ 
+-static int pcd_block_open(struct inode *inode, struct file *file)
++static int pcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-	struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_open(&cd->info, inode, file);
++	struct pcd_unit *cd = bdev->bd_disk->private_data;
++	return cdrom_open(&cd->info, bdev, file);
+ }
+ 
+-static int pcd_block_release(struct inode *inode, struct file *file)
++static int pcd_block_release(struct gendisk *disk)
+ {
+-	struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_release(&cd->info, file);
++	struct pcd_unit *cd = disk->private_data;
++	return cdrom_release(&cd->info);
+ }
+ 
+-static int pcd_block_ioctl(struct inode *inode, struct file *file,
++static int pcd_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_ioctl(&cd->info, inode, cmd, arg);
++	struct pcd_unit *cd = bdev->bd_disk->private_data;
++	return cdrom_ioctl(&cd->info, bdev, cmd, arg);
+ }
+ 
+ static int pcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/block/paride/pd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/paride/pd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -236,11 +236,11 @@ MODULE_PARM(drive3, "1-8i");
+ #define IDE_EJECT		0xed
+ 
+ void pd_setup(char *str, int *ints);
+-static int pd_open(struct inode *inode, struct file *file);
++static int pd_open(struct block_device *bdev, struct file *file);
+ static void do_pd_request(request_queue_t * q);
+-static int pd_ioctl(struct inode *inode, struct file *file,
++static int pd_ioctl(struct block_device *bdev, struct file *file,
+ 		    unsigned int cmd, unsigned long arg);
+-static int pd_release(struct inode *inode, struct file *file);
++static int pd_release(struct gendisk *disk);
+ static int pd_revalidate(struct gendisk *p);
+ static int pd_detect(void);
+ static void do_pd_read(void);
+@@ -304,8 +304,6 @@ static char *pd_errs[17] = { "ERR", "IND
+ 
+ /* kernel glue structures */
+ 
+-extern struct block_device_operations pd_fops;
+-
+ static struct block_device_operations pd_fops = {
+ 	.owner		= THIS_MODULE,
+ 	.open		= pd_open,
+@@ -337,9 +335,9 @@ static void pd_init_units(void)
+ 	}
+ }
+ 
+-static int pd_open(struct inode *inode, struct file *file)
++static int pd_open(struct block_device *bdev, struct file *file)
+ {
+-	struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++	struct pd_unit *disk = bdev->bd_disk->private_data;
+ 
+ 	disk->access++;
+ 
+@@ -350,10 +348,10 @@ static int pd_open(struct inode *inode, 
+ 	return 0;
+ }
+ 
+-static int pd_ioctl(struct inode *inode, struct file *file,
++static int pd_ioctl(struct block_device *bdev, struct file *file,
+ 	 unsigned int cmd, unsigned long arg)
+ {
+-	struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++	struct pd_unit *disk = bdev->bd_disk->private_data;
+ 	struct hd_geometry *geo = (struct hd_geometry *) arg;
+ 	struct hd_geometry g;
+ 
+@@ -372,7 +370,7 @@ static int pd_ioctl(struct inode *inode,
+ 			g.sectors = disk->sectors;
+ 			g.cylinders = disk->cylinders;
+ 		}
+-		g.start = get_start_sect(inode->i_bdev);
++		g.start = get_start_sect(bdev);
+ 		if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
+ 			return -EFAULT;
+ 		return 0;
+@@ -381,9 +379,9 @@ static int pd_ioctl(struct inode *inode,
+ 	}
+ }
+ 
+-static int pd_release(struct inode *inode, struct file *file)
++static int pd_release(struct gendisk *p)
+ {
+-	struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++	struct pd_unit *disk = p->private_data;
+ 
+ 	if (!--disk->access && disk->removable)
+ 		pd_doorlock(disk, IDE_DOORUNLOCK);
+--- linux-2.6.0-test6/drivers/block/paride/pf.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/block/paride/pf.c	2003-10-05 00:34:01.000000000 -0700
+@@ -222,12 +222,12 @@ MODULE_PARM(drive3, "1-7i");
+ #define ATAPI_READ_10		0x28
+ #define ATAPI_WRITE_10		0x2a
+ 
+-static int pf_open(struct inode *inode, struct file *file);
++static int pf_open(struct block_device *bdev, struct file *file);
+ static void do_pf_request(request_queue_t * q);
+-static int pf_ioctl(struct inode *inode, struct file *file,
++static int pf_ioctl(struct block_device *bdev, struct file *file,
+ 		    unsigned int cmd, unsigned long arg);
+ 
+-static int pf_release(struct inode *inode, struct file *file);
++static int pf_release(struct gendisk *disk);
+ 
+ static int pf_detect(void);
+ static void do_pf_read(void);
+@@ -315,9 +315,9 @@ void pf_init_units(void)
+ 	}
+ }
+ 
+-static int pf_open(struct inode *inode, struct file *file)
++static int pf_open(struct block_device *bdev, struct file *file)
+ {
+-	struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++	struct pf_unit *pf = bdev->bd_disk->private_data;
+ 
+ 	pf_identify(pf);
+ 
+@@ -334,9 +334,9 @@ static int pf_open(struct inode *inode, 
+ 	return 0;
+ }
+ 
+-static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int pf_ioctl(struct block_device *bdev, struct file *file, unsigned int cmd, unsigned long arg)
+ {
+-	struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++	struct pf_unit *pf = bdev->bd_disk->private_data;
+ 	struct hd_geometry *geo = (struct hd_geometry *) arg;
+ 	struct hd_geometry g;
+ 	sector_t capacity;
+@@ -365,9 +365,9 @@ static int pf_ioctl(struct inode *inode,
+ 	return 0;
+ }
+ 
+-static int pf_release(struct inode *inode, struct file *file)
++static int pf_release(struct gendisk *disk)
+ {
+-	struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++	struct pf_unit *pf = disk->private_data;
+ 
+ 	if (pf->access <= 0)
+ 		return -EINVAL;
+--- linux-2.6.0-test6/drivers/block/ps2esdi.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/ps2esdi.c	2003-10-05 00:33:54.000000000 -0700
+@@ -39,7 +39,7 @@
+ #include <linux/genhd.h>
+ #include <linux/ps2esdi.h>
+ #include <linux/blkdev.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/module.h>
+@@ -81,7 +81,7 @@ static void (*current_int_handler) (u_in
+ static void ps2esdi_normal_interrupt_handler(u_int);
+ static void ps2esdi_initial_reset_int_handler(u_int);
+ static void ps2esdi_geometry_int_handler(u_int);
+-static int ps2esdi_ioctl(struct inode *inode, struct file *file,
++static int ps2esdi_ioctl(struct block_device *bdev, struct file *file,
+ 			 u_int cmd, u_long arg);
+ 
+ static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
+@@ -1059,10 +1059,10 @@ static void dump_cmd_complete_status(u_i
+ 
+ }
+ 
+-static int ps2esdi_ioctl(struct inode *inode,
++static int ps2esdi_ioctl(struct block_device *bdev,
+ 			 struct file *file, u_int cmd, u_long arg)
+ {
+-	struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;
++	struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
+ 	struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
+ 	int err;
+ 
+@@ -1073,7 +1073,7 @@ static int ps2esdi_ioctl(struct inode *i
+ 	put_user(p->head, (char *) &geometry->heads);
+ 	put_user(p->sect, (char *) &geometry->sectors);
+ 	put_user(p->cyl, (short *) &geometry->cylinders);
+-	put_user(get_start_sect(inode->i_bdev), (long *) &geometry->start);
++	put_user(get_start_sect(bdev), (long *) &geometry->start);
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/drivers/block/rd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/rd.c	2003-10-05 00:34:30.000000000 -0700
+@@ -1,15 +1,15 @@
+ /*
+  * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta.
+- * 
+- * (C) Chad Page, Theodore Ts'o, et. al, 1995. 
++ *
++ * (C) Chad Page, Theodore Ts'o, et. al, 1995.
+  *
+  * This RAM disk is designed to have filesystems created on it and mounted
+- * just like a regular floppy disk.  
+- *  
++ * just like a regular floppy disk.
++ *
+  * It also does something suggested by Linus: use the buffer cache as the
+  * RAM disk data.  This makes it possible to dynamically allocate the RAM disk
+- * buffer - with some consequences I have to deal with as I write this. 
+- * 
++ * buffer - with some consequences I have to deal with as I write this.
++ *
+  * This code is based on the original ramdisk.c, written mostly by
+  * Theodore Ts'o (TYT) in 1991.  The code was largely rewritten by
+  * Chad Page to use the buffer cache to store the RAM disk data in
+@@ -33,7 +33,7 @@
+  *
+  *  Added initrd: Werner Almesberger & Hans Lermen, Feb '96
+  *
+- * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB) 
++ * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
+  *		- Chad Page
+  *
+  * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
+@@ -60,7 +60,7 @@
+ #include <asm/uaccess.h>
+ 
+ /* The RAM disk size is now a parameter */
+-#define NUM_RAMDISKS 16		/* This cannot be overridden (yet) */ 
++#define NUM_RAMDISKS 16		/* This cannot be overridden (yet) */
+ 
+ /* Various static variables go here.  Most are used only in the RAM disk code.
+  */
+@@ -73,7 +73,7 @@ static struct request_queue *rd_queue[NU
+  * Parameters for the boot-loading of the RAM disk.  These are set by
+  * init/main.c (from arguments to the kernel command line) or from the
+  * architecture-specific setup routine (from the stored boot sector
+- * information). 
++ * information).
+  */
+ int rd_size = CONFIG_BLK_DEV_RAM_SIZE;		/* Size of the RAM disks */
+ /*
+@@ -94,7 +94,7 @@ int rd_blocksize = BLOCK_SIZE;			/* bloc
+  *               2000 Transmeta Corp.
+  * aops copied from ramfs.
+  */
+-static int ramdisk_readpage(struct file *file, struct page * page)
++static int ramdisk_readpage(struct file *file, struct page *page)
+ {
+ 	if (!PageUptodate(page)) {
+ 		void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -108,7 +108,8 @@ static int ramdisk_readpage(struct file 
+ 	return 0;
+ }
+ 
+-static int ramdisk_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_prepare_write(struct file *file, struct page *page,
++				unsigned offset, unsigned to)
+ {
+ 	if (!PageUptodate(page)) {
+ 		void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -122,7 +123,8 @@ static int ramdisk_prepare_write(struct 
+ 	return 0;
+ }
+ 
+-static int ramdisk_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_commit_write(struct file *file, struct page *page,
++				unsigned offset, unsigned to)
+ {
+ 	return 0;
+ }
+@@ -212,7 +214,7 @@ static int rd_blkdev_pagecache_IO(int rw
+  * 19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Added devfs support
+  *
+  */
+-static int rd_make_request(request_queue_t * q, struct bio *bio)
++static int rd_make_request(request_queue_t *q, struct bio *bio)
+ {
+ 	struct block_device *bdev = bio->bi_bdev;
+ 	struct address_space * mapping = bdev->bd_inode->i_mapping;
+@@ -242,17 +244,19 @@ fail:
+ 	return 0;
+ } 
+ 
+-static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int rd_ioctl(struct block_device *bdev, struct file *file,
++			unsigned int cmd, unsigned long arg)
+ {
+ 	int error;
+-	struct block_device *bdev = inode->i_bdev;
+ 
+ 	if (cmd != BLKFLSBUF)
+ 		return -EINVAL;
+ 
+-	/* special: we want to release the ramdisk memory,
+-	   it's not like with the other blockdevices where
+-	   this ioctl only flushes away the buffer cache. */
++	/*
++	 * special: we want to release the ramdisk memory, it's not like with
++	 * the other blockdevices where this ioctl only flushes away the buffer
++	 * cache
++	 */
+ 	error = -EBUSY;
+ 	down(&bdev->bd_sem);
+ 	if (bdev->bd_openers <= 2) {
+@@ -268,16 +272,15 @@ static struct backing_dev_info rd_backin
+ 	.memory_backed	= 1,	/* Does not contribute to dirty memory */
+ };
+ 
+-static int rd_open(struct inode * inode, struct file * filp)
++static int rd_open(struct block_device *bdev, struct file *filp)
+ {
+-	unsigned unit = iminor(inode);
++	unsigned unit = MINOR(bdev->bd_dev);
+ 
+ 	/*
+ 	 * Immunize device against invalidate_buffers() and prune_icache().
+ 	 */
+ 	if (rd_bdev[unit] == NULL) {
+-		struct block_device *bdev = inode->i_bdev;
+-		inode = igrab(bdev->bd_inode);
++		struct inode *inode = igrab(bdev->bd_inode);
+ 		rd_bdev[unit] = bdev;
+ 		bdev->bd_openers++;
+ 		bdev->bd_block_size = rd_blocksize;
+@@ -295,12 +298,14 @@ static struct block_device_operations rd
+ 	.ioctl =	rd_ioctl,
+ };
+ 
+-/* Before freeing the module, invalidate all of the protected buffers! */
+-static void __exit rd_cleanup (void)
++/*
++ * Before freeing the module, invalidate all of the protected buffers!
++ */
++static void __exit rd_cleanup(void)
+ {
+ 	int i;
+ 
+-	for (i = 0 ; i < NUM_RAMDISKS; i++) {
++	for (i = 0; i < NUM_RAMDISKS; i++) {
+ 		struct block_device *bdev = rd_bdev[i];
+ 		rd_bdev[i] = NULL;
+ 		if (bdev) {
+@@ -311,17 +316,19 @@ static void __exit rd_cleanup (void)
+ 		put_disk(rd_disks[i]);
+ 	}
+ 	devfs_remove("rd");
+-	unregister_blkdev(RAMDISK_MAJOR, "ramdisk" );
++	unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
+ }
+ 
+-/* This is the registration and initialization section of the RAM disk driver */
+-static int __init rd_init (void)
++/*
++ * This is the registration and initialization section of the RAM disk driver
++ */
++static int __init rd_init(void)
+ {
+ 	int i;
+ 	int err = -ENOMEM;
+ 
+ 	if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
+-	    (rd_blocksize & (rd_blocksize-1))) {
++			(rd_blocksize & (rd_blocksize-1))) {
+ 		printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",
+ 		       rd_blocksize);
+ 		rd_blocksize = BLOCK_SIZE;
+@@ -362,8 +369,8 @@ static int __init rd_init (void)
+ 
+ 	/* rd_size is given in kB */
+ 	printk("RAMDISK driver initialized: "
+-	       "%d RAM disks of %dK size %d blocksize\n",
+-	       NUM_RAMDISKS, rd_size, rd_blocksize);
++		"%d RAM disks of %dK size %d blocksize\n",
++		NUM_RAMDISKS, rd_size, rd_blocksize);
+ 
+ 	return 0;
+ out_queue:
+--- linux-2.6.0-test6/drivers/block/scsi_ioctl.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/block/scsi_ioctl.c	2003-10-05 00:36:48.000000000 -0700
+@@ -25,6 +25,7 @@
+ #include <linux/cdrom.h>
+ #include <linux/slab.h>
+ #include <linux/bio.h>
++#include <linux/times.h>
+ #include <asm/uaccess.h>
+ 
+ #include <scsi/scsi.h>
+@@ -140,40 +141,36 @@ static int sg_emulated_host(request_queu
+ }
+ 
+ static int sg_io(request_queue_t *q, struct block_device *bdev,
+-		 struct sg_io_hdr *uptr)
++		 struct sg_io_hdr *hdr)
+ {
+ 	unsigned long start_time;
+ 	int reading, writing;
+-	struct sg_io_hdr hdr;
+ 	struct request *rq;
+ 	struct bio *bio;
+ 	char sense[SCSI_SENSE_BUFFERSIZE];
+ 	void *buffer;
+ 
+-	if (copy_from_user(&hdr, uptr, sizeof(*uptr)))
+-		return -EFAULT;
+-
+-	if (hdr.interface_id != 'S')
++	if (hdr->interface_id != 'S')
+ 		return -EINVAL;
+-	if (hdr.cmd_len > sizeof(rq->cmd))
++	if (hdr->cmd_len > sizeof(rq->cmd))
+ 		return -EINVAL;
+ 
+ 	/*
+ 	 * we'll do that later
+ 	 */
+-	if (hdr.iovec_count)
++	if (hdr->iovec_count)
+ 		return -EOPNOTSUPP;
+ 
+-	if (hdr.dxfer_len > (q->max_sectors << 9))
++	if (hdr->dxfer_len > (q->max_sectors << 9))
+ 		return -EIO;
+ 
+ 	reading = writing = 0;
+ 	buffer = NULL;
+ 	bio = NULL;
+-	if (hdr.dxfer_len) {
+-		unsigned int bytes = (hdr.dxfer_len + 511) & ~511;
++	if (hdr->dxfer_len) {
++		unsigned int bytes = (hdr->dxfer_len + 511) & ~511;
+ 
+-		switch (hdr.dxfer_direction) {
++		switch (hdr->dxfer_direction) {
+ 		default:
+ 			return -EINVAL;
+ 		case SG_DXFER_TO_FROM_DEV:
+@@ -191,8 +188,8 @@ static int sg_io(request_queue_t *q, str
+ 		 * first try to map it into a bio. reading from device will
+ 		 * be a write to vm.
+ 		 */
+-		bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
+-				   hdr.dxfer_len, reading);
++		bio = bio_map_user(bdev, (unsigned long) hdr->dxferp,
++				   hdr->dxfer_len, reading);
+ 
+ 		/*
+ 		 * if bio setup failed, fall back to slow approach
+@@ -203,11 +200,11 @@ static int sg_io(request_queue_t *q, str
+ 				return -ENOMEM;
+ 
+ 			if (writing) {
+-				if (copy_from_user(buffer, hdr.dxferp,
+-						   hdr.dxfer_len))
++				if (copy_from_user(buffer, hdr->dxferp,
++						   hdr->dxfer_len))
+ 					goto out_buffer;
+ 			} else
+-				memset(buffer, 0, hdr.dxfer_len);
++				memset(buffer, 0, hdr->dxfer_len);
+ 		}
+ 	}
+ 
+@@ -216,11 +213,10 @@ static int sg_io(request_queue_t *q, str
+ 	/*
+ 	 * fill in request structure
+ 	 */
+-	rq->cmd_len = hdr.cmd_len;
+-	if (copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len))
+-		goto out_request;
+-	if (sizeof(rq->cmd) != hdr.cmd_len)
+-		memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);
++	rq->cmd_len = hdr->cmd_len;
++	memcpy(rq->cmd, hdr->cmdp, hdr->cmd_len);
++	if (sizeof(rq->cmd) != hdr->cmd_len)
++		memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
+ 
+ 	memset(sense, 0, sizeof(sense));
+ 	rq->sense = sense;
+@@ -234,9 +230,9 @@ static int sg_io(request_queue_t *q, str
+ 		blk_rq_bio_prep(q, rq, bio);
+ 
+ 	rq->data = buffer;
+-	rq->data_len = hdr.dxfer_len;
++	rq->data_len = hdr->dxfer_len;
+ 
+-	rq->timeout = (hdr.timeout * HZ) / 1000;
++	rq->timeout = (hdr->timeout * HZ) / 1000;
+ 	if (!rq->timeout)
+ 		rq->timeout = q->sg_timeout;
+ 	if (!rq->timeout)
+@@ -254,33 +250,30 @@ static int sg_io(request_queue_t *q, str
+ 		bio_unmap_user(bio, reading);
+ 
+ 	/* write to all output members */
+-	hdr.status = rq->errors;	
+-	hdr.masked_status = (hdr.status >> 1) & 0x1f;
+-	hdr.msg_status = 0;
+-	hdr.host_status = 0;
+-	hdr.driver_status = 0;
+-	hdr.info = 0;
+-	if (hdr.masked_status || hdr.host_status || hdr.driver_status)
+-		hdr.info |= SG_INFO_CHECK;
+-	hdr.resid = rq->data_len;
+-	hdr.duration = ((jiffies - start_time) * 1000) / HZ;
+-	hdr.sb_len_wr = 0;
++	hdr->status = rq->errors;	
++	hdr->masked_status = (hdr->status >> 1) & 0x1f;
++	hdr->msg_status = 0;
++	hdr->host_status = 0;
++	hdr->driver_status = 0;
++	hdr->info = 0;
++	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
++		hdr->info |= SG_INFO_CHECK;
++	hdr->resid = rq->data_len;
++	hdr->duration = ((jiffies - start_time) * 1000) / HZ;
++	hdr->sb_len_wr = 0;
+ 
+-	if (rq->sense_len && hdr.sbp) {
+-		int len = min((unsigned int) hdr.mx_sb_len, rq->sense_len);
++	if (rq->sense_len && hdr->sbp) {
++		int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
+ 
+-		if (!copy_to_user(hdr.sbp, rq->sense, len))
+-			hdr.sb_len_wr = len;
++		if (!copy_to_user(hdr->sbp, rq->sense, len))
++			hdr->sb_len_wr = len;
+ 	}
+ 
+ 	blk_put_request(rq);
+ 
+-	if (copy_to_user(uptr, &hdr, sizeof(*uptr)))
+-		goto out_buffer;
+-
+ 	if (buffer) {
+ 		if (reading)
+-			if (copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len))
++			if (copy_to_user(hdr->dxferp, buffer, hdr->dxfer_len))
+ 				goto out_buffer;
+ 
+ 		kfree(buffer);
+@@ -289,8 +282,6 @@ static int sg_io(request_queue_t *q, str
+ 	/* may not have succeeded, but output values written to control
+ 	 * structure (struct sg_io_hdr).  */
+ 	return 0;
+-out_request:
+-	blk_put_request(rq);
+ out_buffer:
+ 	kfree(buffer);
+ 	return -EFAULT;
+@@ -319,7 +310,7 @@ static int sg_scsi_ioctl(request_queue_t
+ 		return -EFAULT;
+ 	if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
+ 		return -EINVAL;
+-	if (get_user(opcode, sic->data))
++	if (get_user(opcode, (int *)sic->data))
+ 		return -EFAULT;
+ 
+ 	bytes = max(in_len, out_len);
+@@ -437,9 +428,71 @@ int scsi_cmd_ioctl(struct block_device *
+ 		case SG_EMULATED_HOST:
+ 			err = sg_emulated_host(q, (int *) arg);
+ 			break;
+-		case SG_IO:
+-			err = sg_io(q, bdev, (struct sg_io_hdr *) arg);
++		case SG_IO: {
++			struct sg_io_hdr hdr;
++
++			if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) {
++				err = -EFAULT;
++				break;
++			}
++			err = sg_io(q, bdev, &hdr);
++			if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr)))
++				err = -EFAULT;
+ 			break;
++		}
++		case CDROM_SEND_PACKET: {
++			struct cdrom_generic_command cgc;
++			struct sg_io_hdr hdr;
++
++			if (copy_from_user(&cgc, (struct cdrom_generic_command *) arg, sizeof(cgc))) {
++				err = -EFAULT;
++				break;
++			}
++			cgc.timeout = clock_t_to_jiffies(cgc.timeout);
++			memset(&hdr, 0, sizeof(hdr));
++			hdr.interface_id = 'S';
++			hdr.cmd_len = sizeof(cgc.cmd);
++			hdr.dxfer_len = cgc.buflen;
++			err = 0;
++			switch (cgc.data_direction) {
++				case CGC_DATA_UNKNOWN:
++					hdr.dxfer_direction = SG_DXFER_UNKNOWN;
++					break;
++				case CGC_DATA_WRITE:
++					hdr.dxfer_direction = SG_DXFER_TO_DEV;
++					break;
++				case CGC_DATA_READ:
++					hdr.dxfer_direction = SG_DXFER_FROM_DEV;
++					break;
++				case CGC_DATA_NONE:
++					hdr.dxfer_direction = SG_DXFER_NONE;
++					break;
++				default:
++					err = -EINVAL;
++			}
++			if (err)
++				break;
++
++			hdr.dxferp = cgc.buffer;
++			hdr.sbp = (char *) cgc.sense;
++			if (hdr.sbp)
++				hdr.mx_sb_len = sizeof(struct request_sense);
++			hdr.timeout = cgc.timeout;
++			hdr.cmdp = cgc.cmd;
++			hdr.cmd_len = sizeof(cgc.cmd);
++			err = sg_io(q, bdev, &hdr);
++
++			if (hdr.status)
++				err = -EIO;
++
++			cgc.stat = err;
++			cgc.buflen = hdr.resid;
++			if (copy_to_user((struct cdrom_generic_command *) arg, &cgc, sizeof(cgc)))
++				err = -EFAULT;
++
++			break;
++		}
++
+ 		/*
+ 		 * old junk scsi send command ioctl
+ 		 */
+--- linux-2.6.0-test6/drivers/block/swim3.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/block/swim3.c	2003-10-05 00:34:01.000000000 -0700
+@@ -239,10 +239,9 @@ static int grab_drive(struct floppy_stat
+ 		      int interruptible);
+ static void release_drive(struct floppy_state *fs);
+ static int fd_eject(struct floppy_state *fs);
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+ 			unsigned int cmd, unsigned long param);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
+ static int floppy_check_change(struct gendisk *disk);
+ static int floppy_revalidate(struct gendisk *disk);
+ static int swim3_add_device(struct device_node *swims);
+@@ -811,10 +810,10 @@ static int fd_eject(struct floppy_state 
+ static struct floppy_struct floppy_type =
+ 	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };	/*  7 1.44MB 3.5"   */
+ 
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+ 			unsigned int cmd, unsigned long param)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = bdev->bd_disk->private_data;
+ 	int err;
+ 		
+ 	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+@@ -838,9 +837,9 @@ static int floppy_ioctl(struct inode *in
+ 	return -ENOTTY;
+ }
+ 
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = bdev->bd_disk->private_data;
+ 	volatile struct swim3 *sw = fs->swim3;
+ 	int n, err = 0;
+ 
+@@ -876,7 +875,7 @@ static int floppy_open(struct inode *ino
+ 
+ 	if (err == 0 && (filp->f_flags & O_NDELAY) == 0
+ 	    && (filp->f_mode & 3)) {
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		if (fs->ejected)
+ 			err = -ENXIO;
+ 	}
+@@ -904,9 +903,9 @@ static int floppy_open(struct inode *ino
+ 	return 0;
+ }
+ 
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = disk->private_data;
+ 	volatile struct swim3 *sw = fs->swim3;
+ 	if (fs->ref_count > 0 && --fs->ref_count == 0) {
+ 		swim3_action(fs, MOTOR_OFF);
+--- linux-2.6.0-test6/drivers/block/swim_iop.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/block/swim_iop.c	2003-10-05 00:34:01.000000000 -0700
+@@ -31,6 +31,7 @@
+ #include <linux/delay.h>
+ #include <linux/fd.h>
+ #include <linux/ioctl.h>
++#include <linux/blkdev.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/mac_iop.h>
+@@ -97,10 +98,10 @@ static void swimiop_receive(struct iop_m
+ static void swimiop_status_update(int, struct swim_drvstatus *);
+ static int swimiop_eject(struct floppy_state *fs);
+ 
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+ 			unsigned int cmd, unsigned long param);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
++static int floppy_release(struct gendisk *disk);
+ static int floppy_check_change(struct gendisk *disk);
+ static int floppy_revalidate(struct gendisk *disk);
+ static int grab_drive(struct floppy_state *fs, enum swim_state state,
+@@ -347,10 +348,10 @@ static int swimiop_eject(struct floppy_s
+ static struct floppy_struct floppy_type =
+ 	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };	/*  7 1.44MB 3.5"   */
+ 
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+ 			unsigned int cmd, unsigned long param)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = bdev->bd_disk->private_data;
+ 	int err;
+ 
+ 	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+@@ -371,15 +372,15 @@ static int floppy_ioctl(struct inode *in
+ 	return -ENOTTY;
+ }
+ 
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = bdev->bd_disk->private_data;
+ 
+ 	if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
+ 		return -EBUSY;
+ 
+ 	if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		if (fs->ejected)
+ 			return -ENXIO;
+ 	}
+@@ -395,9 +396,9 @@ static int floppy_open(struct inode *ino
+ 	return 0;
+ }
+ 
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++	struct floppy_state *fs = disk->private_data;
+ 	if (fs->ref_count > 0)
+ 		fs->ref_count--;
+ 	return 0;
+--- linux-2.6.0-test6/drivers/block/umem.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/umem.c	2003-10-05 00:33:58.000000000 -0700
+@@ -153,7 +153,6 @@ struct cardinfo {
+ };
+ 
+ static struct cardinfo cards[MM_MAXCARDS];
+-static struct block_device_operations mm_fops;
+ static struct timer_list battery_timer;
+ 
+ static int num_cards = 0;
+@@ -818,10 +817,10 @@ static int mm_revalidate(struct gendisk 
+ --                            mm_ioctl
+ -----------------------------------------------------------------------------------
+ */
+-static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
++static int mm_ioctl(struct block_device *bdev, struct file *f, unsigned int cmd, unsigned long arg)
+ {
+ 	if (cmd == HDIO_GETGEO) {
+-		struct cardinfo *card = i->i_bdev->bd_disk->private_data;
++		struct cardinfo *card = bdev->bd_disk->private_data;
+ 		int size = card->mm_size * (1024 / MM_HARDSECT);
+ 		struct hd_geometry geo;
+ 		/*
+@@ -831,7 +830,7 @@ static int mm_ioctl(struct inode *i, str
+ 		 */
+ 		geo.heads     = 64;
+ 		geo.sectors   = 32;
+-		geo.start     = get_start_sect(i->i_bdev);
++		geo.start     = get_start_sect(bdev);
+ 		geo.cylinders = size / (geo.heads * geo.sectors);
+ 
+ 		if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+--- linux-2.6.0-test6/drivers/block/xd.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/xd.c	2003-10-05 00:33:54.000000000 -0700
+@@ -322,9 +322,9 @@ static void do_xd_request (request_queue
+ }
+ 
+ /* xd_ioctl: handle device ioctl's */
+-static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
++static int xd_ioctl (struct block_device *bdev,struct file *file,u_int cmd,u_long arg)
+ {
+-	XD_INFO *p = inode->i_bdev->bd_disk->private_data;
++	XD_INFO *p = bdev->bd_disk->private_data;
+ 
+ 	switch (cmd) {
+ 		case HDIO_GETGEO:
+@@ -334,7 +334,7 @@ static int xd_ioctl (struct inode *inode
+ 			g.heads = p->heads;
+ 			g.sectors = p->sectors;
+ 			g.cylinders = p->cylinders;
+-			g.start = get_start_sect(inode->i_bdev);
++			g.start = get_start_sect(bdev);
+ 			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
+ 		}
+ 		case HDIO_SET_DMA:
+--- linux-2.6.0-test6/drivers/block/xd.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/block/xd.h	2003-10-05 00:33:54.000000000 -0700
+@@ -105,7 +105,7 @@ static u_char xd_detect (u_char *control
+ static u_char xd_initdrives (void (*init_drive)(u_char drive));
+ 
+ static void do_xd_request (request_queue_t * q);
+-static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
++static int xd_ioctl (struct block_device *bdev,struct file *file,unsigned int cmd,unsigned long arg);
+ static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);
+ static void xd_recalibrate (u_char drive);
+ 
+--- linux-2.6.0-test6/drivers/block/z2ram.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/z2ram.c	2003-10-05 00:34:01.000000000 -0700
+@@ -67,7 +67,6 @@ static int current_device   = -1;
+ 
+ static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED;
+ 
+-static struct block_device_operations z2_fops;
+ static struct gendisk *z2ram_gendisk;
+ 
+ static void do_z2_request(request_queue_t *q)
+@@ -141,7 +140,7 @@ get_chipram( void )
+ }
+ 
+ static int
+-z2_open( struct inode *inode, struct file *filp )
++z2_open( struct block_device *bdev, struct file *filp )
+ {
+     int device;
+     int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
+@@ -150,7 +149,7 @@ z2_open( struct inode *inode, struct fil
+ 	sizeof( z2ram_map[0] );
+     int rc = -ENOMEM;
+ 
+-    device = iminor(inode);
++    device = MINOR(bdev->bd_dev);
+ 
+     if ( current_device != -1 && current_device != device )
+     {
+@@ -301,8 +300,7 @@ err_out:
+     return rc;
+ }
+ 
+-static int
+-z2_release( struct inode *inode, struct file *filp )
++static int z2_release(struct gendisk *disk)
+ {
+     if ( current_device == -1 )
+ 	return 0;     
+--- linux-2.6.0-test6/drivers/cdrom/aztcd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/aztcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -330,10 +330,10 @@ static int aztGetToc(int multi);
+ 
+ /* Kernel Interface Functions */
+ static int check_aztcd_media_change(struct gendisk *disk);
+-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
++static int aztcd_ioctl(struct block_device *bdev, struct file *fp, unsigned int cmd,
+ 		       unsigned long arg);
+-static int aztcd_open(struct inode *ip, struct file *fp);
+-static int aztcd_release(struct inode *inode, struct file *file);
++static int aztcd_open(struct block_device *bdev, struct file *fp);
++static int aztcd_release(struct gendisk *disk);
+ 
+ static struct block_device_operations azt_fops = {
+ 	.owner		= THIS_MODULE,
+@@ -1153,7 +1153,7 @@ static int check_aztcd_media_change(stru
+ /*
+  * Kernel IO-controls
+ */
+-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
++static int aztcd_ioctl(struct block_device *bdev, struct file *fp, unsigned int cmd,
+ 		       unsigned long arg)
+ {
+ 	int i;
+@@ -1171,8 +1171,6 @@ static int aztcd_ioctl(struct inode *ip,
+ 	       cmd, jiffies);
+ 	printk("aztcd Status %x\n", getAztStatus());
+ #endif
+-	if (!ip)
+-		RETURNM("aztcd_ioctl 1", -EINVAL);
+ 	if (getAztStatus() < 0)
+ 		RETURNM("aztcd_ioctl 2", -EIO);
+ 	if ((!aztTocUpToDate) || (aztDiskChanged)) {
+@@ -1624,7 +1622,7 @@ static void azt_invalidate_buffers(void)
+ /*
+  * Open the device special file.  Check that a disk is in.
+  */
+-static int aztcd_open(struct inode *ip, struct file *fp)
++static int aztcd_open(struct block_device *bdev, struct file *fp)
+ {
+ 	int st;
+ 
+@@ -1673,12 +1671,11 @@ static int aztcd_open(struct inode *ip, 
+ /*
+  * On close, we flush all azt blocks from the buffer cache.
+  */
+-static int aztcd_release(struct inode *inode, struct file *file)
++static int aztcd_release(struct gendisk *disk)
+ {
+ #ifdef AZT_DEBUG
+ 	printk("aztcd: executing aztcd_release\n");
+-	printk("inode: %p, device: %s    file: %p\n", inode,
+-	       inode->i_bdev->bd_disk->disk_name, file);
++	printk("disk: %p, device: %s\n", disk, disk->disk_name);
+ #endif
+ 	if (!--azt_open_count) {
+ 		azt_invalidate_buffers();
+--- linux-2.6.0-test6/drivers/cdrom/cdrom.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/cdrom/cdrom.c	2003-10-05 00:33:59.000000000 -0700
+@@ -367,6 +367,7 @@ int register_cdrom(struct cdrom_device_i
+ 	ENSURE(generic_packet, CDC_GENERIC_PACKET);
+ 	cdi->mc_flags = 0;
+ 	cdo->n_minors = 0;
++	cdi->for_data = 0;
+         cdi->options = CDO_USE_FFLAGS;
+ 	
+ 	if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
+@@ -416,7 +417,7 @@ int unregister_cdrom(struct cdrom_device
+  * is in their own interest: device control becomes a lot easier
+  * this way.
+  */
+-int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
++int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, struct file *fp)
+ {
+ 	int ret;
+ 
+@@ -437,7 +438,7 @@ int cdrom_open(struct cdrom_device_info 
+ 	cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count);
+ 	/* Do this on open.  Don't wait for mount, because they might
+ 	    not be mounting, but opening with O_NONBLOCK */
+-	check_disk_change(ip->i_bdev);
++	check_disk_change(bdev);
+ 	return ret;
+ }
+ 
+@@ -530,6 +531,7 @@ int open_for_data(struct cdrom_device_in
+ 			cdinfo(CD_OPEN, "door locked.\n");
+ 	}
+ 	cdinfo(CD_OPEN, "device opened successfully.\n"); 
++	cdi->for_data = 1;
+ 	return ret;
+ 
+ 	/* Something failed.  Try to unlock the drive, because some drivers
+@@ -605,30 +607,29 @@ int check_for_audio_disc(struct cdrom_de
+ 
+ 
+ /* Admittedly, the logic below could be performed in a nicer way. */
+-int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
++int cdrom_release(struct cdrom_device_info *cdi)
+ {
+ 	struct cdrom_device_ops *cdo = cdi->ops;
+-	int opened_for_data;
+ 
+ 	cdinfo(CD_CLOSE, "entering cdrom_release\n"); 
+ 
+ 	if (cdi->use_count > 0)
+ 		cdi->use_count--;
+-	if (cdi->use_count == 0)
+-		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
+-	if (cdi->use_count == 0 &&
+-	    cdo->capability & CDC_LOCK && !keeplocked) {
++	if (cdi->use_count) {
++		cdo->release(cdi);
++		return 0;
++	}
++		
++	cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
++	if (cdo->capability & CDC_LOCK && !keeplocked) {
+ 		cdinfo(CD_CLOSE, "Unlocking door!\n");
+ 		cdo->lock_door(cdi, 0);
+ 	}
+-	opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
+-		!(fp && fp->f_flags & O_NONBLOCK);
+ 	cdo->release(cdi);
+-	if (cdi->use_count == 0) {      /* last process that closes dev*/
+-		if (opened_for_data &&
+-		    cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
+-			cdo->tray_move(cdi, 1);
+-	}
++	if (cdi->for_data &&
++	    cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
++		cdo->tray_move(cdi, 1);
++	cdi->for_data = 0;
+ 	return 0;
+ }
+ 
+@@ -1433,14 +1434,14 @@ static int cdrom_read_block(struct cdrom
+  * these days. ATAPI / SCSI specific code now mainly resides in
+  * mmc_ioct().
+  */
+-int cdrom_ioctl(struct cdrom_device_info *cdi, struct inode *ip,
++int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
+ 		unsigned int cmd, unsigned long arg)
+ {
+ 	struct cdrom_device_ops *cdo = cdi->ops;
+ 	int ret;
+ 
+ 	/* Try the generic SCSI command ioctl's first.. */
+-	ret = scsi_cmd_ioctl(ip->i_bdev, cmd, arg);
++	ret = scsi_cmd_ioctl(bdev, cmd, arg);
+ 	if (ret != -ENOTTY)
+ 		return ret;
+ 
+@@ -1593,7 +1594,7 @@ int cdrom_ioctl(struct cdrom_device_info
+ 		cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
+ 		if (!CDROM_CAN(CDC_RESET))
+ 			return -ENOSYS;
+-		invalidate_bdev(ip->i_bdev, 0);
++		invalidate_bdev(bdev, 0);
+ 		return cdo->reset(cdi);
+ 		}
+ 
+@@ -1856,57 +1857,6 @@ static int cdrom_switch_blocksize(struct
+ 	return cdo->generic_packet(cdi, &cgc);
+ }
+ 
+-static int cdrom_do_cmd(struct cdrom_device_info *cdi,
+-			struct cdrom_generic_command *cgc)
+-{
+-	struct request_sense *usense, sense;
+-	unsigned char *ubuf;
+-	int ret;
+-
+-	if (cgc->data_direction == CGC_DATA_UNKNOWN)
+-		return -EINVAL;
+-
+-	if (cgc->buflen < 0 || cgc->buflen >= 131072)
+-		return -EINVAL;
+-
+-	usense = cgc->sense;
+-	cgc->sense = &sense;
+-	if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense))) {
+-		return -EFAULT;
+-	}
+-
+-	ubuf = cgc->buffer;
+-	if (cgc->data_direction == CGC_DATA_READ ||
+-	    cgc->data_direction == CGC_DATA_WRITE) {
+-		cgc->buffer = kmalloc(cgc->buflen, GFP_KERNEL);
+-		if (cgc->buffer == NULL)
+-			return -ENOMEM;
+-	}
+-
+-
+-	if (cgc->data_direction == CGC_DATA_READ) {
+-		if (!access_ok(VERIFY_READ, ubuf, cgc->buflen)) {
+-			kfree(cgc->buffer);
+-			return -EFAULT;
+-		}
+-	} else if (cgc->data_direction == CGC_DATA_WRITE) {
+-		if (copy_from_user(cgc->buffer, ubuf, cgc->buflen)) {
+-			kfree(cgc->buffer);
+-			return -EFAULT;
+-		}
+-	}
+-
+-	ret = cdi->ops->generic_packet(cdi, cgc);
+-	__copy_to_user(usense, cgc->sense, sizeof(*usense));
+-	if (!ret && cgc->data_direction == CGC_DATA_READ)
+-		__copy_to_user(ubuf, cgc->buffer, cgc->buflen);
+-	if (cgc->data_direction == CGC_DATA_READ ||
+-	    cgc->data_direction == CGC_DATA_WRITE) {
+-		kfree(cgc->buffer);
+-	}
+-	return ret;
+-}
+-
+ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+ 		     unsigned long arg)
+ {		
+@@ -2176,14 +2126,6 @@ static int mmc_ioctl(struct cdrom_device
+ 		return 0;
+ 		}
+ 
+-	case CDROM_SEND_PACKET: {
+-		if (!CDROM_CAN(CDC_GENERIC_PACKET))
+-			return -ENOSYS;
+-		cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKET\n"); 
+-		IOCTL_IN(arg, struct cdrom_generic_command, cgc);
+-		cgc.timeout = clock_t_to_jiffies(cgc.timeout);
+-		return cdrom_do_cmd(cdi, &cgc);
+-		}
+ 	case CDROM_NEXT_WRITABLE: {
+ 		long next = 0;
+ 		cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n"); 
+--- linux-2.6.0-test6/drivers/cdrom/cdu31a.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/cdu31a.c	2003-10-05 00:34:01.000000000 -0700
+@@ -3167,20 +3167,20 @@ static struct cdrom_device_info scd_info
+ 	.name		= "cdu31a"
+ };
+ 
+-static int scd_block_open(struct inode *inode, struct file *file)
++static int scd_block_open(struct block_device *bdev, struct file *file)
+ {
+-	return cdrom_open(&scd_info, inode, file);
++	return cdrom_open(&scd_info, bdev, file);
+ }
+ 
+-static int scd_block_release(struct inode *inode, struct file *file)
++static int scd_block_release(struct gendisk *disk)
+ {
+-	return cdrom_release(&scd_info, file);
++	return cdrom_release(&scd_info);
+ }
+ 
+-static int scd_block_ioctl(struct inode *inode, struct file *file,
++static int scd_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	return cdrom_ioctl(&scd_info, inode, cmd, arg);
++	return cdrom_ioctl(&scd_info, bdev, cmd, arg);
+ }
+ 
+ static int scd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/cdrom/cm206.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/cm206.c	2003-10-05 00:34:01.000000000 -0700
+@@ -1350,20 +1350,20 @@ static struct cdrom_device_info cm206_in
+ 	.name		= "cm206",
+ };
+ 
+-static int cm206_block_open(struct inode *inode, struct file *file)
++static int cm206_block_open(struct block_device *bdev, struct file *file)
+ {
+-	return cdrom_open(&cm206_info, inode, file);
++	return cdrom_open(&cm206_info, bdev, file);
+ }
+ 
+-static int cm206_block_release(struct inode *inode, struct file *file)
++static int cm206_block_release(struct gendisk *disk)
+ {
+-	return cdrom_release(&cm206_info, file);
++	return cdrom_release(&cm206_info);
+ }
+ 
+-static int cm206_block_ioctl(struct inode *inode, struct file *file,
++static int cm206_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	return cdrom_ioctl(&cm206_info, inode, cmd, arg);
++	return cdrom_ioctl(&cm206_info, bdev, cmd, arg);
+ }
+ 
+ static int cm206_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/cdrom/gscd.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/cdrom/gscd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -91,10 +91,10 @@ static void gscd_bin2bcd(unsigned char *
+ /* Schnittstellen zum Kern/FS */
+ 
+ static void __do_gscd_request(unsigned long dummy);
+-static int gscd_ioctl(struct inode *, struct file *, unsigned int,
++static int gscd_ioctl(struct block_device *, struct file *, unsigned int,
+ 		      unsigned long);
+-static int gscd_open(struct inode *, struct file *);
+-static int gscd_release(struct inode *, struct file *);
++static int gscd_open(struct block_device *, struct file *);
++static int gscd_release(struct gendisk *disk);
+ static int check_gscd_med_chg(struct gendisk *disk);
+ 
+ /*      GoldStar Funktionen    */
+@@ -190,8 +190,8 @@ __setup("gscd=", gscd_setup);
+ 
+ #endif
+ 
+-static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+-		      unsigned long arg)
++static int gscd_ioctl(struct block_device *bdev, struct file *fp,
++			unsigned int cmd, unsigned long arg)
+ {
+ 	unsigned char to_do[10];
+ 	unsigned char dummy;
+@@ -338,7 +338,7 @@ static void gscd_read_cmd(struct request
+  * Open the device special file.  Check that a disk is in.
+  */
+ 
+-static int gscd_open(struct inode *ip, struct file *fp)
++static int gscd_open(struct block_device *bdev, struct file *fp)
+ {
+ 	int st;
+ 
+@@ -368,7 +368,7 @@ static int gscd_open(struct inode *ip, s
+  * On close, we flush all gscd blocks from the buffer cache.
+  */
+ 
+-static int gscd_release(struct inode *inode, struct file *file)
++static int gscd_release(struct gendisk *disk)
+ {
+ 
+ #ifdef GSCD_DEBUG
+--- linux-2.6.0-test6/drivers/cdrom/mcd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/mcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -214,20 +214,20 @@ static struct cdrom_device_info mcd_info
+ 	.name		= "mcd",
+ };
+ 
+-static int mcd_block_open(struct inode *inode, struct file *file)
++static int mcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-	return cdrom_open(&mcd_info, inode, file);
++	return cdrom_open(&mcd_info, bdev, file);
+ }
+ 
+-static int mcd_block_release(struct inode *inode, struct file *file)
++static int mcd_block_release(struct gendisk *disk)
+ {
+-	return cdrom_release(&mcd_info, file);
++	return cdrom_release(&mcd_info);
+ }
+ 
+-static int mcd_block_ioctl(struct inode *inode, struct file *file,
++static int mcd_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	return cdrom_ioctl(&mcd_info, inode, cmd, arg);
++	return cdrom_ioctl(&mcd_info, bdev, cmd, arg);
+ }
+ 
+ static int mcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/cdrom/mcdx.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/mcdx.c	2003-10-05 00:34:01.000000000 -0700
+@@ -221,23 +221,23 @@ struct s_drive_stuff {
+ int mcdx_init(void);
+ void do_mcdx_request(request_queue_t * q);
+ 
+-static int mcdx_block_open(struct inode *inode, struct file *file)
++static int mcdx_block_open(struct block_device *bdev, struct file *file)
+ {
+-	struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_open(&p->info, inode, file);
++	struct s_drive_stuff *p = bdev->bd_disk->private_data;
++	return cdrom_open(&p->info, bdev, file);
+ }
+ 
+-static int mcdx_block_release(struct inode *inode, struct file *file)
++static int mcdx_block_release(struct gendisk *disk)
+ {
+-	struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_release(&p->info, file);
++	struct s_drive_stuff *p = disk->private_data;
++	return cdrom_release(&p->info);
+ }
+ 
+-static int mcdx_block_ioctl(struct inode *inode, struct file *file,
++static int mcdx_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_ioctl(&p->info, inode, cmd, arg);
++	struct s_drive_stuff *p = bdev->bd_disk->private_data;
++	return cdrom_ioctl(&p->info, bdev, cmd, arg);
+ }
+ 
+ static int mcdx_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/cdrom/optcd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/optcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -1713,16 +1713,13 @@ static int cdromreset(void)
+ /* VFS calls */
+ 
+ 
+-static int opt_ioctl(struct inode *ip, struct file *fp,
++static int opt_ioctl(struct block_device *bdev, struct file *fp,
+                      unsigned int cmd, unsigned long arg)
+ {
+ 	int status, err, retval = 0;
+ 
+ 	DEBUG((DEBUG_VFS, "starting opt_ioctl"));
+ 
+-	if (!ip)
+-		return -EINVAL;
+-
+ 	if (cmd == CDROMRESET)
+ 		return cdromreset();
+ 
+@@ -1844,7 +1841,7 @@ static int opt_ioctl(struct inode *ip, s
+ static int open_count = 0;
+ 
+ /* Open device special file; check that a disk is in. */
+-static int opt_open(struct inode *ip, struct file *fp)
++static int opt_open(struct block_device *bdev, struct file *fp)
+ {
+ 	DEBUG((DEBUG_VFS, "starting opt_open"));
+ 
+@@ -1904,13 +1901,12 @@ err_out:
+ 
+ 
+ /* Release device special file; flush all blocks from the buffer cache */
+-static int opt_release(struct inode *ip, struct file *fp)
++static int opt_release(struct gendisk *disk)
+ {
+ 	int status;
+ 
+ 	DEBUG((DEBUG_VFS, "executing opt_release"));
+-	DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
+-		ip, ip->i_bdev->bd_disk->disk_name, fp));
++	DEBUG((DEBUG_VFS, "disk: %p, device: %s\n", disk, disk->disk_name));
+ 
+ 	if (!--open_count) {
+ 		toc_uptodate = 0;
+--- linux-2.6.0-test6/drivers/cdrom/sbpcd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/sbpcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -363,7 +363,6 @@
+ 
+ #include <linux/module.h>
+ 
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
+@@ -5357,23 +5356,23 @@ static int sbp_data(struct request *req)
+ }
+ /*==========================================================================*/
+ 
+-static int sbpcd_block_open(struct inode *inode, struct file *file)
++static int sbpcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_open(p->sbpcd_infop, inode, file);
++	struct sbpcd_drive *p = bdev->bd_disk->private_data;
++	return cdrom_open(p->sbpcd_infop, bdev, file);
+ }
+ 
+-static int sbpcd_block_release(struct inode *inode, struct file *file)
++static int sbpcd_block_release(struct gendisk *disk)
+ {
+-	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_release(p->sbpcd_infop, file);
++	struct sbpcd_drive *p = disk->private_data;
++	return cdrom_release(p->sbpcd_infop);
+ }
+ 
+-static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
++static int sbpcd_block_ioctl(struct block_device *bdev, struct file *file,
+ 				unsigned cmd, unsigned long arg)
+ {
+-	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-	return cdrom_ioctl(p->sbpcd_infop, inode, cmd, arg);
++	struct sbpcd_drive *p = bdev->bd_disk->private_data;
++	return cdrom_ioctl(p->sbpcd_infop, bdev, cmd, arg);
+ }
+ 
+ static int sbpcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/cdrom/sjcd.c	2003-09-08 13:58:56.000000000 -0700
++++ 25/drivers/cdrom/sjcd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -713,16 +713,13 @@ static int sjcd_tray_open(void)
+ /*
+  * Do some user commands.
+  */
+-static int sjcd_ioctl(struct inode *ip, struct file *fp,
++static int sjcd_ioctl(struct block_device *bdev, struct file *fp,
+ 		      unsigned int cmd, unsigned long arg)
+ {
+ #if defined( SJCD_TRACE )
+ 	printk("SJCD:ioctl\n");
+ #endif
+ 
+-	if (ip == NULL)
+-		return (-EINVAL);
+-
+ 	sjcd_get_status();
+ 	if (!sjcd_status_valid)
+ 		return (-EIO);
+@@ -1522,7 +1519,7 @@ static void do_sjcd_request(request_queu
+ /*
+  * Open the device special file. Check disk is in.
+  */
+-static int sjcd_open(struct inode *ip, struct file *fp)
++static int sjcd_open(struct block_device *bdev, struct file *fp)
+ {
+ 	/*
+ 	 * Check the presence of device.
+@@ -1607,7 +1604,7 @@ static int sjcd_open(struct inode *ip, s
+ /*
+  * On close, we flush all sjcd blocks from the buffer cache.
+  */
+-static int sjcd_release(struct inode *inode, struct file *file)
++static int sjcd_release(struct gendisk *disk)
+ {
+ 	int s;
+ 
+--- linux-2.6.0-test6/drivers/cdrom/sonycd535.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/cdrom/sonycd535.c	2003-10-05 00:34:01.000000000 -0700
+@@ -201,7 +201,7 @@
+ 
+ static int read_subcode(void);
+ static void sony_get_toc(void);
+-static int cdu_open(struct inode *inode, struct file *filp);
++static int cdu_open(struct block_device *bdev, struct file *filp);
+ static inline unsigned int int_to_bcd(unsigned int val);
+ static unsigned int bcd_to_int(unsigned int bcd);
+ static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
+@@ -1061,7 +1061,7 @@ sony_get_subchnl_info(long arg)
+  * The big ugly ioctl handler.
+  */
+ static int
+-cdu_ioctl(struct inode *inode,
++cdu_ioctl(struct block_device *bdev,
+ 		  struct file *file,
+ 		  unsigned int cmd,
+ 		  unsigned long arg)
+@@ -1363,9 +1363,7 @@ cdu_ioctl(struct inode *inode,
+  * Open the drive for operations.  Spin the drive up and read the table of
+  * contents if these have not already been done.
+  */
+-static int
+-cdu_open(struct inode *inode,
+-		 struct file *filp)
++static int cdu_open(struct block_device *bdev, struct file *filp)
+ {
+ 	Byte status[2], cmd_buff[2];
+ 
+@@ -1388,7 +1386,7 @@ cdu_open(struct inode *inode,
+ 		sony_inuse = 0;
+ 		return -EIO;
+ 	}
+-	check_disk_change(inode->i_bdev);
++	check_disk_change(bdev);
+ 	sony_usage++;
+ 
+ #ifdef LOCK_DOORS
+@@ -1405,9 +1403,7 @@ cdu_open(struct inode *inode,
+  * Close the drive.  Spin it down if no task is using it.  The spin
+  * down will fail if playing audio, so audio play is OK.
+  */
+-static int
+-cdu_release(struct inode *inode,
+-			struct file *filp)
++static int cdu_release(struct gendisk *disk)
+ {
+ 	Byte status[2], cmd_no;
+ 
+--- linux-2.6.0-test6/drivers/char/agp/amd64-agp.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/agp/amd64-agp.c	2003-10-05 00:33:24.000000000 -0700
+@@ -91,9 +91,9 @@ static int amd64_insert_memory(struct ag
+ 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+ 		tmp = agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
+ 
+-		BUG_ON(tmp & 0xffffff0000000ffc);
+-		pte = (tmp & 0x000000ff00000000) >> 28;
+-		pte |=(tmp & 0x00000000fffff000);
++		BUG_ON(tmp & 0xffffff0000000ffcULL);
++		pte = (tmp & 0x000000ff00000000ULL) >> 28;
++		pte |=(tmp & 0x00000000fffff000ULL);
+ 		pte |= GPTE_VALID | GPTE_COHERENT;
+ 
+ 		agp_bridge->gatt_table[j] = pte;
+--- linux-2.6.0-test6/drivers/char/agp/via-agp.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/agp/via-agp.c	2003-10-05 00:33:24.000000000 -0700
+@@ -251,6 +251,11 @@ static struct agp_device_ids via_agp_dev
+ 		.chipset_name	= "Pro 266",
+ 	},
+ 
++	{
++		.device_id	= PCI_DEVICE_ID_VIA_XN266,
++		.chipset_name	= "Apollo Pro266",
++	},
++
+ 	/* VT8361 */
+ 	{
+ 		.device_id	= PCI_DEVICE_ID_VIA_8361,
+--- linux-2.6.0-test6/drivers/char/amiserial.c	2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/char/amiserial.c	2003-10-05 00:33:24.000000000 -0700
+@@ -32,7 +32,6 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ 
+ #undef SERIAL_PARANOIA_CHECK
+ #define SERIAL_DO_RESTART
+--- linux-2.6.0-test6/drivers/char/cyclades.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/cyclades.c	2003-10-05 00:33:24.000000000 -0700
+@@ -670,7 +670,6 @@ static char rcsid[] =
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+-#include <linux/version.h>
+ 
+ #include <linux/stat.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/drivers/char/dsp56k.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/dsp56k.c	2003-10-05 00:33:24.000000000 -0700
+@@ -24,7 +24,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/slab.h>	/* for kmalloc() and kfree() */
+ #include <linux/sched.h>	/* for struct wait_queue etc */
+ #include <linux/major.h>
+--- linux-2.6.0-test6/drivers/char/dtlk.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/dtlk.c	2003-10-05 00:33:24.000000000 -0700
+@@ -48,7 +48,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ 
+ #define KERNEL
+ #include <linux/types.h>
+--- linux-2.6.0-test6/drivers/char/dz.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/char/dz.c	2003-10-05 00:33:24.000000000 -0700
+@@ -23,7 +23,6 @@ Qua Jun 27 15:02:26 BRT 2001
+ 
+ /* #define DEBUG_DZ 1 */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ 
+ #include <linux/config.h>
+--- linux-2.6.0-test6/drivers/char/ftape/compressor/zftape-compress.c	2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/char/ftape/compressor/zftape-compress.c	2003-10-05 00:33:24.000000000 -0700
+@@ -31,6 +31,7 @@
+  char zftc_rev[] = "$Revision: 1.2 $";
+  char zftc_dat[] = "$Date: 2003/12/03 03:13:28 $";
+ 
++#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/char/ftape/lowlevel/fdc-io.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/ftape/lowlevel/fdc-io.c	2003-10-05 00:33:24.000000000 -0700
+@@ -30,7 +30,6 @@
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/ioport.h>
+-#include <linux/version.h>
+ #include <linux/interrupt.h>
+ #include <asm/system.h>
+ #include <asm/io.h>
+--- linux-2.6.0-test6/drivers/char/generic_serial.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/generic_serial.c	2003-10-05 00:33:24.000000000 -0700
+@@ -348,7 +348,7 @@ int gs_real_chars_in_buffer(struct tty_s
+ static int gs_wait_tx_flushed (void * ptr, int timeout) 
+ {
+ 	struct gs_port *port = ptr;
+-	long end_jiffies;
++	unsigned long end_jiffies;
+ 	int jiffies_to_transmit, charsleft = 0, rv = 0;
+ 	int rcib;
+ 
+--- linux-2.6.0-test6/drivers/char/i8k.c	2003-06-14 12:18:01.000000000 -0700
++++ 25/drivers/char/i8k.c	2003-10-05 00:33:24.000000000 -0700
+@@ -17,7 +17,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/drivers/char/ip2/i2os.h	2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/char/ip2/i2os.h	2003-10-05 00:33:24.000000000 -0700
+@@ -25,7 +25,6 @@
+ 
+ #include "ip2types.h"
+ #include <asm/io.h>  /* For inb, etc */
+-#include <linux/version.h>
+ 
+ //------------------------------------
+ // Defines for I/O instructions:
+--- linux-2.6.0-test6/drivers/char/ip2main.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/ip2main.c	2003-10-05 00:33:24.000000000 -0700
+@@ -84,8 +84,6 @@
+ /************/
+ #include <linux/config.h>
+ 
+-#include <linux/version.h>
+-
+ #include <linux/ctype.h>
+ #include <linux/string.h>
+ #include <linux/fcntl.h>
+--- linux-2.6.0-test6/drivers/char/isicom.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/char/isicom.c	2003-10-05 00:33:24.000000000 -0700
+@@ -38,7 +38,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/tty.h>
+ #include <linux/termios.h>
+--- linux-2.6.0-test6/drivers/char/istallion.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/istallion.c	2003-10-05 00:33:24.000000000 -0700
+@@ -35,7 +35,6 @@
+ #include <linux/serial.h>
+ #include <linux/cdk.h>
+ #include <linux/comstats.h>
+-#include <linux/version.h>
+ #include <linux/istallion.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+--- linux-2.6.0-test6/drivers/char/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -954,6 +954,15 @@ config RAW_DRIVER
+ 	  Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 
+ 	  See the raw(8) manpage for more details.
+ 
++config MAX_RAW_DEVS
++	int "Maximum number of RAW devices to support (1-8192)"
++	depends on RAW_DRIVER
++	default "256"
++	help
++	  The maximum number of RAW devices that are supported.
++	  Default is 256. Increase this number in case you need lots of
++	  raw devices.
++
+ config HANGCHECK_TIMER
+ 	tristate "Hangcheck timer"
+ 	depends on X86_64 || X86
+--- linux-2.6.0-test6/drivers/char/keyboard.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/keyboard.c	2003-10-05 00:33:38.000000000 -0700
+@@ -1052,6 +1052,9 @@ void kbd_keycode(unsigned int keycode, i
+ 	}
+ 	if (sysrq_down && down && !rep) {
+ 		handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
++#ifdef CONFIG_KGDB_SYSRQ
++                sysrq_down = 0;        /* in case we miss the "up" event */
++#endif
+ 		return;
+ 	}
+ #endif
+--- linux-2.6.0-test6/drivers/char/lp_old98.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/lp_old98.c	2003-10-05 00:33:24.000000000 -0700
+@@ -23,7 +23,6 @@
+ #include <linux/fcntl.h>
+ #include <linux/delay.h>
+ #include <linux/console.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ 
+ #include <asm/io.h>
+--- linux-2.6.0-test6/drivers/char/mem.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/mem.c	2003-10-05 00:36:19.000000000 -0700
+@@ -40,6 +40,7 @@ extern void fbmem_init(void);
+ extern void tapechar_init(void);
+ #endif
+ 
++#ifdef pgprot_noncached
+ /*
+  * Architectures vary in how they handle caching for addresses
+  * outside of main memory.
+@@ -65,19 +66,21 @@ static inline int uncached_access(struct
+ 	  && addr >= __pa(high_memory);
+ #elif defined(CONFIG_IA64)
+ 	/*
+-	 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
++	 * On ia64, we ignore O_SYNC because we cannot tolerate memory
++	 * attribute aliases.
+ 	 */
+ 	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+ #else
+ 	/*
+-	 * Accessing memory above the top the kernel knows about or through a file pointer
+-	 * that was marked O_SYNC will be done non-cached.
++	 * Accessing memory above the top the kernel knows about or through a
++	 * file pointer that was marked O_SYNC will be done non-cached.
+ 	 */
+ 	if (file->f_flags & O_SYNC)
+ 		return 1;
+ 	return addr >= __pa(high_memory);
+ #endif
+ }
++#endif		/* pgprot_noncached */
+ 
+ static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
+ 			    const char * buf, size_t count, loff_t *ppos)
+@@ -159,28 +162,24 @@ static ssize_t write_mem(struct file * f
+ 	return do_write_mem(file, __va(p), p, buf, count, ppos);
+ }
+ 
+-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
++static int mmap_mem(struct file *file, struct vm_area_struct *vma)
+ {
+ 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+-	int uncached;
+ 
+-	uncached = uncached_access(file, offset);
+ #ifdef pgprot_noncached
+-	if (uncached)
++	if (uncached_access(file, offset))
+ 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ #endif
+ 
+-	/* Don't try to swap out physical pages.. */
+-	vma->vm_flags |= VM_RESERVED;
+-
+ 	/*
+-	 * Don't dump addresses that are not real memory to a core file.
++	 * Don't try to swap out physical pages..
++	 * And treat /dev/mem mappings as "IO" regions: they may not
++	 * describe valid pageframes.
+ 	 */
+-	if (uncached)
+-		vma->vm_flags |= VM_IO;
++	vma->vm_flags |= VM_RESERVED|VM_IO;
+ 
+-	if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
+-			     vma->vm_page_prot))
++	if (remap_page_range(vma, vma->vm_start, offset,
++			vma->vm_end-vma->vm_start, vma->vm_page_prot))
+ 		return -EAGAIN;
+ 	return 0;
+ }
+--- linux-2.6.0-test6/drivers/char/misc.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/misc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -157,12 +157,11 @@ static int misc_open(struct inode * inod
+ 		list_for_each_entry(c, &misc_list, list) {
+ 			if (c->minor == minor) {
+ 				new_fops = fops_get(c->fops);
+-				if (!new_fops)
+-					goto fail;
+ 				break;
+ 			}
+ 		}
+-		goto fail;
++		if (!new_fops)
++			goto fail;
+ 	}
+ 
+ 	err = 0;
+--- linux-2.6.0-test6/drivers/char/moxa.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/moxa.c	2003-10-05 00:33:24.000000000 -0700
+@@ -32,7 +32,6 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+-#include <linux/version.h>
+ #include <linux/mm.h>
+ #include <linux/ioport.h>
+ #include <linux/errno.h>
+--- linux-2.6.0-test6/drivers/char/mxser.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/char/mxser.c	2003-10-05 00:33:24.000000000 -0700
+@@ -39,7 +39,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+--- linux-2.6.0-test6/drivers/char/n_tty.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/n_tty.c	2003-10-05 00:36:15.000000000 -0700
+@@ -974,7 +974,8 @@ do_it_again:
+ 	/* NOTE: not yet done after every sleep pending a thorough
+ 	   check of the logic of this change. -- jlc */
+ 	/* don't stop on /dev/console */
+-	if (file->f_op->write != redirected_tty_write && current->tty == tty) {
++	if (file->f_op->write != redirected_tty_write &&
++			process_tty(current) == tty) {
+ 		if (tty->pgrp <= 0)
+ 			printk("read_chan: tty->pgrp <= 0!\n");
+ 		else if (process_group(current) != tty->pgrp) {
+--- linux-2.6.0-test6/drivers/char/pcmcia/synclink_cs.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/pcmcia/synclink_cs.c	2003-10-05 00:33:24.000000000 -0700
+@@ -37,7 +37,6 @@
+ 
+ #include <linux/config.h>	
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+--- linux-2.6.0-test6/drivers/char/pcxx.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/pcxx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -65,7 +65,6 @@
+ #include <linux/tty_driver.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+-#include <linux/version.h>
+ 
+ #ifndef MODULE
+ #include <linux/ctype.h> /* We only need it for parsing the "digi="-line */
+--- linux-2.6.0-test6/drivers/char/random.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/random.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1735,7 +1735,7 @@ random_ioctl(struct inode * inode, struc
+ 		tmp = kmalloc(size * sizeof(__u32), GFP_KERNEL);
+ 
+ 		if (!tmp)
+-			return -EFAULT;
++			return -ENOMEM;
+ 
+ 		spin_lock_irqsave(&random_state->lock, flags);
+ 		ent_count = random_state->entropy_count;
+--- linux-2.6.0-test6/drivers/char/raw.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/raw.c	2003-10-05 00:34:12.000000000 -0700
+@@ -20,8 +20,6 @@
+ 
+ #include <asm/uaccess.h>
+ 
+-#define MAX_RAW_MINORS	256
+-
+ struct raw_device_data {
+ 	struct block_device *binding;
+ 	int inuse;
+@@ -76,9 +74,8 @@ static int raw_open(struct inode *inode,
+ 			goto out;
+ 		}
+ 		filp->f_flags |= O_DIRECT;
+-		if (++raw_devices[minor].inuse == 1)
+-			filp->f_dentry->d_inode->i_mapping =
+-				bdev->bd_inode->i_mapping;
++		filp->f_mapping = bdev->bd_inode->i_mapping;
++		raw_devices[minor].inuse++;
+ 	}
+ 	filp->private_data = bdev;
+ out:
+@@ -97,11 +94,7 @@ static int raw_release(struct inode *ino
+ 
+ 	down(&raw_mutex);
+ 	bdev = raw_devices[minor].binding;
+-	if (--raw_devices[minor].inuse == 0) {
+-		/* Here  inode->i_mapping == bdev->bd_inode->i_mapping  */
+-		inode->i_mapping = &inode->i_data;
+-		inode->i_mapping->backing_dev_info = &default_backing_dev_info;
+-	}
++	--raw_devices[minor].inuse;
+ 	up(&raw_mutex);
+ 
+ 	bd_release(bdev);
+--- linux-2.6.0-test6/drivers/char/rio/rio_linux.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/rio/rio_linux.c	2003-10-05 00:33:24.000000000 -0700
+@@ -53,7 +53,6 @@
+ #include <linux/fcntl.h>
+ #include <linux/major.h>
+ #include <linux/delay.h>
+-#include <linux/version.h>
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+ #include <linux/miscdevice.h>
+--- linux-2.6.0-test6/drivers/char/rocket.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/rocket.c	2003-10-05 00:36:15.000000000 -0700
+@@ -85,11 +85,9 @@
+ #include <linux/string.h>
+ #include <linux/fcntl.h>
+ #include <linux/ptrace.h>
+-#include <linux/major.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/wait.h>
+-#include <linux/delay.h>
+ #include <linux/pci.h>
+ #include <asm/uaccess.h>
+ #include <asm/atomic.h>
+@@ -955,7 +953,7 @@ static int rp_open(struct tty_struct *tt
+ 	/*
+ 	 * Info->count is now 1; so it's safe to sleep now.
+ 	 */
+-	info->session = current->session;
++	info->session = process_session(current);
+ 	info->pgrp = process_group(current);
+ 
+ 	if ((info->flags & ROCKET_INITIALIZED) == 0) {
+--- linux-2.6.0-test6/drivers/char/ser_a2232.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/ser_a2232.c	2003-10-05 00:33:24.000000000 -0700
+@@ -703,7 +703,7 @@ static int a2232_init_drivers(void)
+ 	a2232_driver->name = "ttyY";
+ 	a2232_driver->major = A2232_NORMAL_MAJOR;
+ 	a2232_driver->type = TTY_DRIVER_TYPE_SERIAL;
+-	a2232_driver->subtype = SERIAL_TTY_NORMAL;
++	a2232_driver->subtype = SERIAL_TYPE_NORMAL;
+ 	a2232_driver->init_termios = tty_std_termios;
+ 	a2232_driver->init_termios.c_cflag =
+ 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+--- linux-2.6.0-test6/drivers/char/serial167.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/serial167.c	2003-10-05 00:33:24.000000000 -0700
+@@ -70,7 +70,6 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ 
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ #include <linux/init.h>
+ 
+--- linux-2.6.0-test6/drivers/char/stallion.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/stallion.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h> /* for linux/stallion.h */
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/tty.h>
+--- linux-2.6.0-test6/drivers/char/sx.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/sx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -240,7 +240,6 @@
+ #include "sxwindow.h"
+ 
+ #include <linux/generic_serial.h>
+-#include <asm/uaccess.h>
+ #include "sx.h"
+ 
+ 
+--- linux-2.6.0-test6/drivers/char/sysrq.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/sysrq.c	2003-10-05 00:33:38.000000000 -0700
+@@ -35,6 +35,25 @@
+ #include <linux/spinlock.h>
+ 
+ #include <asm/ptrace.h>
++#ifdef CONFIG_KGDB_SYSRQ
++
++#define  GDB_OP &kgdb_op
++static void kgdb_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
++{
++	printk("kgdb sysrq\n");
++	breakpoint();
++}
++
++static struct sysrq_key_op kgdb_op = {
++	.handler	= kgdb_sysrq,
++	.help_msg	= "kGdb|Fgdb",
++	.action_msg	= "Debug breakpoint\n",
++};
++
++#else
++#define  GDB_OP NULL
++#endif
++
+ 
+ extern void reset_vc(unsigned int);
+ 
+@@ -238,8 +257,8 @@ static struct sysrq_key_op *sysrq_key_ta
+ /* c */ NULL,
+ /* d */	NULL,
+ /* e */	&sysrq_term_op,
+-/* f */	NULL,
+-/* g */	NULL,
++/* f */	GDB_OP,
++/* g */	GDB_OP,
+ /* h */	NULL,
+ /* i */	&sysrq_kill_op,
+ /* j */	NULL,
+--- linux-2.6.0-test6/drivers/char/toshiba.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/char/toshiba.c	2003-10-05 00:33:24.000000000 -0700
+@@ -57,7 +57,6 @@
+ #define TOSH_DEBUG 0
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/types.h>
+@@ -85,7 +84,6 @@ static int tosh_fn = 0;
+ MODULE_PARM(tosh_fn, "i");
+ 
+ 
+-static int tosh_get_info(char *, char **, off_t, int);
+ static int tosh_ioctl(struct inode *, struct file *, unsigned int,
+ 	unsigned long);
+ 
+@@ -104,6 +102,7 @@ static struct miscdevice tosh_device = {
+ /*
+  * Read the Fn key status
+  */
++#ifdef CONFIG_PROC_FS
+ static int tosh_fn_status(void)
+ {
+         unsigned char scan;
+@@ -120,6 +119,7 @@ static int tosh_fn_status(void)
+ 
+         return (int) scan;
+ }
++#endif
+ 
+ 
+ /*
+@@ -291,6 +291,7 @@ static int tosh_ioctl(struct inode *ip, 
+ /*
+  * Print the information for /proc/toshiba
+  */
++#ifdef CONFIG_PROC_FS
+ int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
+ {
+ 	char *temp;
+@@ -319,6 +320,7 @@ int tosh_get_info(char *buffer, char **s
+ 
+ 	return temp-buffer;
+ }
++#endif
+ 
+ 
+ /*
+--- linux-2.6.0-test6/drivers/char/tty_io.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/tty_io.c	2003-10-05 00:36:15.000000000 -0700
+@@ -314,7 +314,7 @@ struct tty_driver *get_tty_driver(dev_t 
+  */
+ int tty_check_change(struct tty_struct * tty)
+ {
+-	if (current->tty != tty)
++	if (process_tty(current) != tty)
+ 		return 0;
+ 	if (tty->pgrp <= 0) {
+ 		printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
+@@ -481,14 +481,14 @@ void do_tty_hangup(void *data)
+ 	if (tty->session > 0) {
+ 		struct list_head *l;
+ 		for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) {
+-			if (p->tty == tty)
+-				p->tty = NULL;
+-			if (!p->leader)
++			if (process_tty(p) == tty)
++				p->signal->tty = NULL;
++			if (!process_session_leader(p))
+ 				continue;
+ 			send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p);
+ 			send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p);
+ 			if (tty->pgrp > 0)
+-				p->tty_old_pgrp = tty->pgrp;
++				p->signal->tty_old_pgrp = tty->pgrp;
+ 		}
+ 	}
+ 	read_unlock(&tasklist_lock);
+@@ -565,15 +565,15 @@ void disassociate_ctty(int on_exit)
+ 
+ 	lock_kernel();
+ 
+-	tty = current->tty;
++	tty = process_tty(current);
+ 	if (tty) {
+ 		tty_pgrp = tty->pgrp;
+ 		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
+ 			tty_vhangup(tty);
+ 	} else {
+-		if (current->tty_old_pgrp) {
+-			kill_pg(current->tty_old_pgrp, SIGHUP, on_exit);
+-			kill_pg(current->tty_old_pgrp, SIGCONT, on_exit);
++		if (current->signal->tty_old_pgrp) {
++			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
++			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
+ 		}
+ 		unlock_kernel();	
+ 		return;
+@@ -584,13 +584,13 @@ void disassociate_ctty(int on_exit)
+ 			kill_pg(tty_pgrp, SIGCONT, on_exit);
+ 	}
+ 
+-	current->tty_old_pgrp = 0;
++	current->signal->tty_old_pgrp = 0;
+ 	tty->session = 0;
+ 	tty->pgrp = -1;
+ 
+ 	read_lock(&tasklist_lock);
+-	for_each_task_pid(current->session, PIDTYPE_SID, p, l, pid)
+-		p->tty = NULL;
++	for_each_task_pid(process_session(current), PIDTYPE_SID, p, l, pid)
++		p->signal->tty = NULL;
+ 	read_unlock(&tasklist_lock);
+ 	unlock_kernel();
+ }
+@@ -1218,10 +1218,10 @@ static void release_dev(struct file * fi
+ 
+ 		read_lock(&tasklist_lock);
+ 		for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid)
+-			p->tty = NULL;
++			p->signal->tty = NULL;
+ 		if (o_tty)
+ 			for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
+-				p->tty = NULL;
++				p->signal->tty = NULL;
+ 		read_unlock(&tasklist_lock);
+ 	}
+ 
+@@ -1292,10 +1292,10 @@ static int tty_open(struct inode * inode
+ retry_open:
+ 	noctty = filp->f_flags & O_NOCTTY;
+ 	if (device == MKDEV(TTYAUX_MAJOR,0)) {
+-		if (!current->tty)
++		if (!process_tty(current))
+ 			return -ENXIO;
+-		driver = current->tty->driver;
+-		index = current->tty->index;
++		driver = process_tty(current)->driver;
++		index = process_tty(current)->index;
+ 		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
+ 		/* noctty = 1; */
+ 		goto got_driver;
+@@ -1389,15 +1389,13 @@ got_driver:
+ 			filp->f_op = &tty_fops;
+ 		goto retry_open;
+ 	}
+-	if (!noctty &&
+-	    current->leader &&
+-	    !current->tty &&
+-	    tty->session == 0) {
++	if (!noctty && process_session_leader(current) &&
++			!process_tty(current) && tty->session == 0) {
+ 	    	task_lock(current);
+-		current->tty = tty;
++		current->signal->tty = tty;
+ 		task_unlock(current);
+-		current->tty_old_pgrp = 0;
+-		tty->session = current->session;
++		current->signal->tty_old_pgrp = 0;
++		tty->session = process_session(current);
+ 		tty->pgrp = process_group(current);
+ 	}
+ 	return 0;
+@@ -1455,7 +1453,7 @@ static int tiocsti(struct tty_struct *tt
+ {
+ 	char ch, mbz = 0;
+ 
+-	if ((current->tty != tty) && !capable(CAP_SYS_ADMIN))
++	if ((process_tty(current) != tty) && !capable(CAP_SYS_ADMIN))
+ 		return -EPERM;
+ 	if (get_user(ch, arg))
+ 		return -EFAULT;
+@@ -1541,14 +1539,14 @@ static int tiocsctty(struct tty_struct *
+ 	struct pid *pid;
+ 	task_t *p;
+ 
+-	if (current->leader &&
+-	    (current->session == tty->session))
++	if (process_session_leader(current) &&
++			(process_session(current) == tty->session))
+ 		return 0;
+ 	/*
+ 	 * The process must be a session leader and
+ 	 * not have a controlling tty already.
+ 	 */
+-	if (!current->leader || current->tty)
++	if (!process_session_leader(current) || process_tty(current))
+ 		return -EPERM;
+ 	if (tty->session > 0) {
+ 		/*
+@@ -1562,16 +1560,16 @@ static int tiocsctty(struct tty_struct *
+ 
+ 			read_lock(&tasklist_lock);
+ 			for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid)
+-				p->tty = NULL;
++				p->signal->tty = NULL;
+ 			read_unlock(&tasklist_lock);
+ 		} else
+ 			return -EPERM;
+ 	}
+ 	task_lock(current);
+-	current->tty = tty;
++	current->signal->tty = tty;
+ 	task_unlock(current);
+-	current->tty_old_pgrp = 0;
+-	tty->session = current->session;
++	current->signal->tty_old_pgrp = 0;
++	tty->session = process_session(current);
+ 	tty->pgrp = process_group(current);
+ 	return 0;
+ }
+@@ -1582,12 +1580,13 @@ static int tiocgpgrp(struct tty_struct *
+ 	 * (tty == real_tty) is a cheap way of
+ 	 * testing if the tty is NOT a master pty.
+ 	 */
+-	if (tty == real_tty && current->tty != real_tty)
++	if (tty == real_tty && process_tty(current) != real_tty)
+ 		return -ENOTTY;
+ 	return put_user(real_tty->pgrp, arg);
+ }
+ 
+-static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t *arg)
++static int tiocspgrp(struct tty_struct *tty,
++			struct tty_struct *real_tty, pid_t *arg)
+ {
+ 	pid_t pgrp;
+ 	int retval = tty_check_change(real_tty);
+@@ -1596,15 +1595,14 @@ static int tiocspgrp(struct tty_struct *
+ 		return -ENOTTY;
+ 	if (retval)
+ 		return retval;
+-	if (!current->tty ||
+-	    (current->tty != real_tty) ||
+-	    (real_tty->session != current->session))
++	if (!process_tty(current) || (process_tty(current) != real_tty) ||
++			(real_tty->session != process_session(current)))
+ 		return -ENOTTY;
+ 	if (get_user(pgrp, (pid_t *) arg))
+ 		return -EFAULT;
+ 	if (pgrp < 0)
+ 		return -EINVAL;
+-	if (session_of_pgrp(pgrp) != current->session)
++	if (session_of_pgrp(pgrp) != process_session(current))
+ 		return -EPERM;
+ 	real_tty->pgrp = pgrp;
+ 	return 0;
+@@ -1616,7 +1614,7 @@ static int tiocgsid(struct tty_struct *t
+ 	 * (tty == real_tty) is a cheap way of
+ 	 * testing if the tty is NOT a master pty.
+ 	*/
+-	if (tty == real_tty && current->tty != real_tty)
++	if (tty == real_tty && process_tty(current) != real_tty)
+ 		return -ENOTTY;
+ 	if (real_tty->session <= 0)
+ 		return -ENOTTY;
+@@ -1774,12 +1772,12 @@ int tty_ioctl(struct inode * inode, stru
+ 			clear_bit(TTY_EXCLUSIVE, &tty->flags);
+ 			return 0;
+ 		case TIOCNOTTY:
+-			if (current->tty != tty)
++			if (process_tty(current) != tty)
+ 				return -ENOTTY;
+-			if (current->leader)
++			if (process_session_leader(current))
+ 				disassociate_ctty(0);
+ 			task_lock(current);
+-			current->tty = NULL;
++			current->signal->tty = NULL;
+ 			task_unlock(current);
+ 			return 0;
+ 		case TIOCSCTTY:
+@@ -1883,10 +1881,10 @@ static void __do_SAK(void *arg)
+ 		tty->driver->flush_buffer(tty);
+ 	read_lock(&tasklist_lock);
+ 	for_each_task_pid(session, PIDTYPE_SID, p, l, pid) {
+-		if (p->tty == tty || session > 0) {
++		if (process_tty(p) == tty || session > 0) {
+ 			printk(KERN_NOTICE "SAK: killed process %d"
+-			    " (%s): p->session==tty->session\n",
+-			    p->pid, p->comm);
++				" (%s): process_session(p)==tty->session\n",
++				p->pid, p->comm);
+ 			send_sig(SIGKILL, p, 1);
+ 			continue;
+ 		}
+--- linux-2.6.0-test6/drivers/char/vme_scc.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/vme_scc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -29,7 +29,6 @@
+ #include <linux/fcntl.h>
+ #include <linux/major.h>
+ #include <linux/delay.h>
+-#include <linux/version.h>
+ #include <linux/slab.h>
+ #include <linux/miscdevice.h>
+ #include <linux/console.h>
+--- linux-2.6.0-test6/drivers/char/vt.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/vt.c	2003-10-05 00:36:15.000000000 -0700
+@@ -2226,7 +2226,7 @@ int tioclinux(struct tty_struct *tty, un
+ 
+ 	if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE)
+ 		return -EINVAL;
+-	if (current->tty != tty && !capable(CAP_SYS_ADMIN))
++	if (process_tty(current) != tty && !capable(CAP_SYS_ADMIN))
+ 		return -EPERM;
+ 	if (get_user(type, (char *)arg))
+ 		return -EFAULT;
+--- linux-2.6.0-test6/drivers/char/vt_ioctl.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/char/vt_ioctl.c	2003-10-05 00:36:15.000000000 -0700
+@@ -380,7 +380,7 @@ int vt_ioctl(struct tty_struct *tty, str
+ 	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+ 	 */
+ 	perm = 0;
+-	if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
++	if (process_tty(current) == tty || capable(CAP_SYS_TTY_CONFIG))
+ 		perm = 1;
+  
+ 	kbd = kbd_table + console;
+@@ -1188,4 +1188,3 @@ void change_console(unsigned int new_con
+ 
+ 	complete_change_console(new_console);
+ }
+-
+--- linux-2.6.0-test6/drivers/char/watchdog/amd7xx_tco.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/watchdog/amd7xx_tco.c	2003-10-05 00:33:24.000000000 -0700
+@@ -19,13 +19,11 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/miscdevice.h>
+ #include <linux/watchdog.h>
+ #include <linux/ioport.h>
+ #include <linux/spinlock.h>
+-#include <linux/ioport.h>
+ #include <asm/semaphore.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+--- linux-2.6.0-test6/drivers/cpufreq/cpufreq.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/cpufreq/cpufreq.c	2003-10-05 00:36:14.000000000 -0700
+@@ -449,6 +449,9 @@ static int cpufreq_remove_dev (struct sy
+ 	if (!kobject_get(&data->kobj))
+ 		return -EFAULT;
+ 
++	if (cpufreq_driver->target)
++		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
++
+ 	kobject_unregister(&data->kobj);
+ 
+ 	kobject_put(&data->kobj);
+@@ -459,9 +462,6 @@ static int cpufreq_remove_dev (struct sy
+ 	 */
+ 	wait_for_completion(&data->kobj_unregister);
+ 
+-	if (cpufreq_driver->target)
+-		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+-
+ 	if (cpufreq_driver->exit)
+ 		cpufreq_driver->exit(data);
+ 
+--- linux-2.6.0-test6/drivers/eisa/eisa-bus.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/eisa/eisa-bus.c	2003-10-05 00:36:11.000000000 -0700
+@@ -33,23 +33,22 @@ static struct eisa_device_info __initdat
+ #endif
+ 
+ #define EISA_MAX_FORCED_DEV 16
+-#define EISA_FORCED_OFFSET  2
+ 
+-static int enable_dev[EISA_MAX_FORCED_DEV + EISA_FORCED_OFFSET]  = { 1, EISA_MAX_FORCED_DEV, };
+-static int disable_dev[EISA_MAX_FORCED_DEV + EISA_FORCED_OFFSET] = { 1, EISA_MAX_FORCED_DEV, };
++static int enable_dev[EISA_MAX_FORCED_DEV];
++static int enable_dev_count;
++static int disable_dev[EISA_MAX_FORCED_DEV];
++static int disable_dev_count;
+ 
+ static int is_forced_dev (int *forced_tab,
++			  int forced_count,
+ 			  struct eisa_root_device *root,
+ 			  struct eisa_device *edev)
+ {
+ 	int i, x;
+ 
+-	for (i = 0; i < EISA_MAX_FORCED_DEV; i++) {
+-		if (!forced_tab[EISA_FORCED_OFFSET + i])
+-			return 0;
+-
++	for (i = 0; i < forced_count; i++) {
+ 		x = (root->bus_nr << 8) | edev->slot;
+-		if (forced_tab[EISA_FORCED_OFFSET + i] == x)
++		if (forced_tab[i] == x)
+ 			return 1;
+ 	}
+ 
+@@ -198,10 +197,10 @@ static int __init eisa_init_device (stru
+ #endif
+ 	}
+ 
+-	if (is_forced_dev (enable_dev, root, edev))
++	if (is_forced_dev (enable_dev, enable_dev_count, root, edev))
+ 		edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED;
+ 	
+-	if (is_forced_dev (disable_dev, root, edev))
++	if (is_forced_dev (disable_dev, disable_dev_count, root, edev))
+ 		edev->state = EISA_CONFIG_FORCED;
+ 
+ 	return 0;
+@@ -418,20 +417,13 @@ static int __init eisa_init (void)
+ 	return 0;
+ }
+ 
+-/* Couldn't use intarray with checking on... :-( */
+-#undef  param_check_intarray
+-#define param_check_intarray(name, p)
+-
+-module_param(enable_dev,  intarray, 0444);
+-module_param(disable_dev, intarray, 0444);
++module_param_array(enable_dev, int, enable_dev_count, 0444);
++module_param_array(disable_dev, int, disable_dev_count, 0444);
+ 
+ postcore_initcall (eisa_init);
+ 
+-#ifndef CONFIG_EISA_ALWAYS
+-int EISA_bus;
+-EXPORT_SYMBOL(EISA_bus);
+-#endif
+-
++int EISA_bus;		/* for legacy drivers */
++EXPORT_SYMBOL (EISA_bus);
+ EXPORT_SYMBOL (eisa_bus_type);
+ EXPORT_SYMBOL (eisa_driver_register);
+ EXPORT_SYMBOL (eisa_driver_unregister);
+--- linux-2.6.0-test6/drivers/i2c/busses/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/i2c/busses/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -285,7 +285,7 @@ config I2C_VELLEMAN
+ 	  will be called i2c-velleman.
+ 
+ config I2C_VIA
+-	tristate "VIA 82C58B"
++	tristate "VIA 82C586B"
+ 	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
+ 	help
+ 
+--- linux-2.6.0-test6/drivers/i2c/i2c-sensor.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/i2c/i2c-sensor.c	2003-10-05 00:33:24.000000000 -0700
+@@ -133,7 +133,7 @@ int i2c_detect(struct i2c_adapter *adapt
+ 		     i += 2) {
+ 			if (((adapter_id == address_data->probe[i]) ||
+ 			     ((address_data->
+-			       probe[i] == ANY_I2C_BUS) & !is_isa))
++			       probe[i] == ANY_I2C_BUS) && !is_isa))
+ 			    && (addr == address_data->probe[i + 1])) {
+ 				dev_dbg(&adapter->dev, "found probe parameter for adapter %d, addr %04x\n", adapter_id, addr);
+ 				found = 1;
+@@ -141,7 +141,7 @@ int i2c_detect(struct i2c_adapter *adapt
+ 		}
+ 		for (i = 0; !found && (address_data->probe_range[i] != I2C_CLIENT_END); i += 3) {
+ 			if ( ((adapter_id == address_data->probe_range[i]) ||
+-			      ((address_data->probe_range[i] == ANY_I2C_BUS) & !is_isa)) &&
++			      ((address_data->probe_range[i] == ANY_I2C_BUS) && !is_isa)) &&
+ 			     (addr >= address_data->probe_range[i + 1]) &&
+ 			     (addr <= address_data->probe_range[i + 2])) {
+ 				found = 1;
+--- linux-2.6.0-test6/drivers/ide/ide.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/ide.c	2003-10-05 00:33:58.000000000 -0700
+@@ -457,7 +457,7 @@ void ide_probe_module (void)
+ 
+ EXPORT_SYMBOL(ide_probe_module);
+ 
+-static int ide_open (struct inode * inode, struct file * filp)
++static int ide_open (struct block_device *bdev, struct file * filp)
+ {
+ 	return -ENXIO;
+ }
+@@ -1800,27 +1800,26 @@ static int __init match_parm (char *s, c
+ 
+ #ifdef CONFIG_BLK_DEV_PDC4030
+ static int __initdata probe_pdc4030;
+-extern void init_pdc4030(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_ALI14XX
+ static int __initdata probe_ali14xx;
+-extern void init_ali14xx(void);
++extern int ali14xx_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_UMC8672
+ static int __initdata probe_umc8672;
+-extern void init_umc8672(void);
++extern int umc8672_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_DTC2278
+ static int __initdata probe_dtc2278;
+-extern void init_dtc2278(void);
++extern int dtc2278_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_HT6560B
+ static int __initdata probe_ht6560b;
+-extern void init_ht6560b(void);
++extern int ht6560b_init(void);
+ #endif
+ #ifdef CONFIG_BLK_DEV_QD65XX
+ static int __initdata probe_qd65xx;
+-extern void init_qd65xx(void);
++extern int qd65xx_init(void);
+ #endif
+ 
+ static int __initdata is_chipset_set[MAX_HWIFS];
+@@ -2238,8 +2237,9 @@ static void __init probe_for_hwifs (void
+ #endif /* CONFIG_BLK_DEV_CMD640 */
+ #ifdef CONFIG_BLK_DEV_PDC4030
+ 	{
+-		extern int ide_probe_for_pdc4030(void);
+-		(void) ide_probe_for_pdc4030();
++		extern int pdc4030_init(void);
++		if (probe_pdc4030)
++			(void)pdc4030_init();
+ 	}
+ #endif /* CONFIG_BLK_DEV_PDC4030 */
+ #ifdef CONFIG_BLK_DEV_IDE_PMAC
+@@ -2595,29 +2595,25 @@ int __init ide_init (void)
+ 
+ 	init_ide_data();
+ 
+-#ifdef CONFIG_BLK_DEV_PDC4030
+-	if (probe_pdc4030)
+-		init_pdc4030();
+-#endif
+ #ifdef CONFIG_BLK_DEV_ALI14XX
+ 	if (probe_ali14xx)
+-		init_ali14xx();
++		(void)ali14xx_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_UMC8672
+ 	if (probe_umc8672)
+-		init_umc8672();
++		(void)umc8672_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_DTC2278
+ 	if (probe_dtc2278)
+-		init_dtc2278();
++		(void)dtc2278_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_HT6560B
+ 	if (probe_ht6560b)
+-		init_ht6560b();
++		(void)ht6560b_init();
+ #endif
+ #ifdef CONFIG_BLK_DEV_QD65XX
+ 	if (probe_qd65xx)
+-		init_qd65xx();
++		(void)qd65xx_init();
+ #endif
+ 
+ 	initializing = 1;
+--- linux-2.6.0-test6/drivers/ide/ide-cd.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/ide/ide-cd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -3331,39 +3331,38 @@ static ide_driver_t ide_cdrom_driver = {
+ 	.complete_power_step	= ide_cdrom_complete_power_step,
+ };
+ 
+-static int idecd_open(struct inode * inode, struct file * file)
++static int idecd_open(struct block_device *bdev, struct file * file)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	struct cdrom_info *info = drive->driver_data;
+ 	int rc = -ENOMEM;
+ 	drive->usage++;
+ 
+ 	if (!info->buffer)
+ 		info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
+-        if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file)))
++        if (!info->buffer || (rc = cdrom_open(&info->devinfo, bdev, file)))
+ 		drive->usage--;
+ 	return rc;
+ }
+ 
+-static int idecd_release(struct inode * inode, struct file * file)
++static int idecd_release(struct gendisk *disk)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = disk->private_data;
+ 	struct cdrom_info *info = drive->driver_data;
+ 
+-	cdrom_release (&info->devinfo, file);
++	cdrom_release(&info->devinfo);
+ 	drive->usage--;
+ 	return 0;
+ }
+ 
+-static int idecd_ioctl (struct inode *inode, struct file *file,
++static int idecd_ioctl (struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	int err = generic_ide_ioctl(bdev, cmd, arg);
+ 	if (err == -EINVAL) {
+ 		struct cdrom_info *info = drive->driver_data;
+-		err = cdrom_ioctl(&info->devinfo, inode, cmd, arg);
++		err = cdrom_ioctl(&info->devinfo, bdev, cmd, arg);
+ 	}
+ 	return err;
+ }
+--- linux-2.6.0-test6/drivers/ide/ide-disk.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/ide-disk.c	2003-10-05 00:34:01.000000000 -0700
+@@ -1734,9 +1734,9 @@ static ide_driver_t idedisk_driver = {
+ 	.complete_power_step	= idedisk_complete_power_step,
+ };
+ 
+-static int idedisk_open(struct inode *inode, struct file *filp)
++static int idedisk_open(struct block_device *bdev, struct file *filp)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	drive->usage++;
+ 	if (drive->removable && drive->usage == 1) {
+ 		ide_task_t args;
+@@ -1744,7 +1744,7 @@ static int idedisk_open(struct inode *in
+ 		memset(&args, 0, sizeof(ide_task_t));
+ 		args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
+ 		args.command_type = ide_cmd_type_parser(&args);
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 		/*
+ 		 * Ignore the return code from door_lock,
+ 		 * since the open() has already succeeded,
+@@ -1782,9 +1782,9 @@ static int ide_cacheflush_p(ide_drive_t 
+ 	return 0;
+ }
+ 
+-static int idedisk_release(struct inode *inode, struct file *filp)
++static int idedisk_release(struct gendisk *disk)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = disk->private_data;
+ 	if (drive->removable && drive->usage == 1) {
+ 		ide_task_t args;
+ 		memset(&args, 0, sizeof(ide_task_t));
+@@ -1798,10 +1798,9 @@ static int idedisk_release(struct inode 
+ 	return 0;
+ }
+ 
+-static int idedisk_ioctl(struct inode *inode, struct file *file,
++static int idedisk_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	return generic_ide_ioctl(bdev, cmd, arg);
+ }
+ 
+--- linux-2.6.0-test6/drivers/ide/ide-floppy.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/ide-floppy.c	2003-10-05 00:34:01.000000000 -0700
+@@ -156,7 +156,6 @@ typedef struct idefloppy_packet_command_
+ 	int request_transfer;			/* Bytes to transfer */
+ 	int actually_transferred;		/* Bytes actually transferred */
+ 	int buffer_size;			/* Size of our data buffer */
+-	char *b_data;				/* Pointer which runs on the buffers */
+ 	int b_count;				/* Missing/Available data on the current buffer */
+ 	struct request *rq;			/* The corresponding request */
+ 	u8 *buffer;				/* Data buffer */
+@@ -515,9 +514,6 @@ typedef struct {
+ 	u8		reserved[4];
+ } idefloppy_mode_parameter_header_t;
+ 
+-#define IDEFLOPPY_MIN(a,b)	((a)<(b) ? (a):(b))
+-#define	IDEFLOPPY_MAX(a,b)	((a)>(b) ? (a):(b))
+-
+ /*
+  *	Too bad. The drive wants to send us data which we are not ready to accept.
+  *	Just throw it away.
+@@ -575,59 +571,68 @@ static int idefloppy_do_end_request(ide_
+ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
+ {
+ 	struct request *rq = pc->rq;
+-	struct bio *bio = rq->bio;
+-	int count;
++	struct bio_vec *bvec;
++	struct bio *bio;
++	unsigned long flags;
++	char *data;
++	int count, i, done = 0;
++
++	rq_for_each_bio(bio, rq) {
++		bio_for_each_segment(bvec, bio, i) {
++			if (!bcount)
++				break;
++
++			count = min(bvec->bv_len, bcount);
++
++			data = bvec_kmap_irq(bvec, &flags);
++			atapi_input_bytes(drive, data, count);
++			bvec_kunmap_irq(data, &flags);
+ 
+-	while (bcount) {
+-		if (pc->b_count == bio->bi_size) {
+-			rq->sector += rq->current_nr_sectors;
+-			rq->nr_sectors -= rq->current_nr_sectors;
+-			idefloppy_do_end_request(drive, 1, 0);
+-			if ((bio = rq->bio) != NULL)
+-				pc->b_count = 0;
+-		}
+-		if (bio == NULL) {
+-			printk(KERN_ERR "%s: bio == NULL in "
+-				"idefloppy_input_buffers, bcount == %d\n",
+-				drive->name, bcount);
+-			idefloppy_discard_data(drive, bcount);
+-			return;
+-		}
+-		count = IDEFLOPPY_MIN(bio->bi_size - pc->b_count, bcount);
+-		atapi_input_bytes(drive, bio_data(bio) + pc->b_count, count);
+-		bcount -= count;
+-		pc->b_count += count;
++			bcount -= count;
++			pc->b_count += count;
++			done += count;
++		}
++	}
++
++	idefloppy_do_end_request(drive, 1, done >> 9);
++
++	if (bcount) {
++		printk(KERN_ERR "%s: leftover data in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
++		idefloppy_discard_data(drive, bcount);
+ 	}
+ }
+ 
+ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
+ {
+ 	struct request *rq = pc->rq;
+-	struct bio *bio = rq->bio;
+-	int count;
+-	
+-	while (bcount) {
+-		if (!pc->b_count) {
+-			rq->sector += rq->current_nr_sectors;
+-			rq->nr_sectors -= rq->current_nr_sectors;
+-			idefloppy_do_end_request(drive, 1, 0);
+-			if ((bio = rq->bio) != NULL) {
+-				pc->b_data = bio_data(bio);
+-				pc->b_count = bio->bi_size;
+-			}
++	struct bio *bio;
++	struct bio_vec *bvec;
++	unsigned long flags;
++	int count, i, done = 0;
++	char *data;
++
++	rq_for_each_bio(bio, rq) {
++		bio_for_each_segment(bvec, bio, i) {
++			if (!bcount)
++				break;
++
++			count = min(bvec->bv_len, bcount);
++
++			data = bvec_kmap_irq(bvec, &flags);
++			atapi_output_bytes(drive, data, count);
++			bvec_kunmap_irq(data, &flags);
++
++			bcount -= count;
++			pc->b_count += count;
++			done += count;
+ 		}
+-		if (bio == NULL) {
+-			printk(KERN_ERR "%s: bio == NULL in "
+-				"idefloppy_output_buffers, bcount == %d\n",
+-				drive->name, bcount);
+-			idefloppy_write_zeros(drive, bcount);
+-			return;
+-		}
+-		count = IDEFLOPPY_MIN(pc->b_count, bcount);
+-		atapi_output_bytes(drive, pc->b_data, count);
+-		bcount -= count;
+-		pc->b_data += count;
+-		pc->b_count -= count;
++	}
++
++	idefloppy_do_end_request(drive, 1, done >> 9);
++
++	if (bcount) {
++		printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
++		idefloppy_write_zeros(drive, bcount);
+ 	}
+ }
+ 
+@@ -732,8 +737,6 @@ static void idefloppy_init_pc (idefloppy
+ 	pc->request_transfer = 0;
+ 	pc->buffer = pc->pc_buffer;
+ 	pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
+-	pc->b_data = NULL;
+-//	pc->bio = NULL;
+ 	pc->callback = &idefloppy_pc_callback;
+ }
+ 
+@@ -1199,7 +1202,6 @@ static void idefloppy_create_rw_cmd (ide
+ 	put_unaligned(htonl(block), (unsigned int *) &pc->c[2]);
+ 	pc->callback = &idefloppy_rw_callback;
+ 	pc->rq = rq;
+-	pc->b_data = rq->buffer;
+ 	pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
+ 	if (rq->flags & REQ_RW)
+ 		set_bit(PC_WRITING, &pc->flags);
+@@ -1864,9 +1866,9 @@ static ide_driver_t idefloppy_driver = {
+ 	.drives			= LIST_HEAD_INIT(idefloppy_driver.drives),
+ };
+ 
+-static int idefloppy_open(struct inode *inode, struct file *filp)
++static int idefloppy_open(struct block_device *bdev, struct file *filp)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	idefloppy_pc_t pc;
+ 
+@@ -1906,7 +1908,7 @@ static int idefloppy_open(struct inode *
+ 			idefloppy_create_prevent_cmd(&pc, 1);
+ 			(void) idefloppy_queue_pc_tail(drive, &pc);
+ 		}
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 	} else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
+ 		drive->usage--;
+ 		return -EBUSY;
+@@ -1914,9 +1916,9 @@ static int idefloppy_open(struct inode *
+ 	return 0;
+ }
+ 
+-static int idefloppy_release(struct inode *inode, struct file *filp)
++static int idefloppy_release(struct gendisk *disk)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = disk->private_data;
+ 	idefloppy_pc_t pc;
+ 	
+ 	debug_log(KERN_INFO "Reached idefloppy_release\n");
+@@ -1936,10 +1938,9 @@ static int idefloppy_release(struct inod
+ 	return 0;
+ }
+ 
+-static int idefloppy_ioctl(struct inode *inode, struct file *file,
++static int idefloppy_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	int err = generic_ide_ioctl(bdev, cmd, arg);
+--- linux-2.6.0-test6/drivers/ide/ide-proc.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/ide/ide-proc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -522,7 +522,8 @@ int proc_ide_write_settings
+ 			if (*p != ':')
+ 				goto parse_error;
+ 			len = IDE_MIN(p - start, MAX_LEN);
+-			strlcpy(name, start, IDE_MIN(len, MAX_LEN));
++			strncpy(name, start, IDE_MIN(len, MAX_LEN));
++			name[len] = 0;
+ 
+ 			if (n > 0) {
+ 				--n;
+--- linux-2.6.0-test6/drivers/ide/ide-tape.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/ide-tape.c	2003-10-05 00:34:01.000000000 -0700
+@@ -6338,24 +6338,23 @@ static struct file_operations idetape_fo
+ 	.release	= idetape_chrdev_release,
+ };
+ 
+-static int idetape_open(struct inode *inode, struct file *filp)
++static int idetape_open(struct block_device *bdev, struct file *filp)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	drive->usage++;
+ 	return 0;
+ }
+ 
+-static int idetape_release(struct inode *inode, struct file *filp)
++static int idetape_release(struct gendisk *disk)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = disk->private_data;
+ 	drive->usage--;
+ 	return 0;
+ }
+ 
+-static int idetape_ioctl(struct inode *inode, struct file *file,
++static int idetape_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	int err = generic_ide_ioctl(bdev, cmd, arg);
+ 	if (err == -EINVAL)
+--- linux-2.6.0-test6/drivers/ide/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/ide/Kconfig	2003-10-05 00:36:28.000000000 -0700
+@@ -740,6 +740,13 @@ config BLK_DEV_SVWKS
+ 	  This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5
+ 	  chipsets.
+ 
++config BLK_DEV_SGIIOC4
++	tristate "Silicon Graphics IOC4 chipset support"
++	help
++	  This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
++	  chipset.  Please say Y here, if you have an Altix System from
++	  Silicon Graphics Inc.
++
+ config BLK_DEV_SIIMAGE
+ 	tristate "Silicon Image chipset support"
+ 	help
+--- linux-2.6.0-test6/drivers/ide/legacy/ali14xx.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/ali14xx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -198,22 +198,12 @@ static int __init initRegisters (void) {
+ 	return t;
+ }
+ 
+-int __init probe_ali14xx (void)
++static int __init ali14xx_probe(void)
+ {
+-	/* auto-detect IDE controller port */
+-	if (!findPort()) {
+-		printk(KERN_ERR "ali14xx: not found.\n");
+-		return 1;
+-	}
++	ide_hwif_t *hwif, *mate;
+ 
+-	printk(KERN_DEBUG "ali14xx: base= 0x%03x, regOn = 0x%02x.\n", basePort, regOn);
+-	ide_hwifs[0].chipset = ide_ali14xx;
+-	ide_hwifs[1].chipset = ide_ali14xx;
+-	ide_hwifs[0].tuneproc = &ali14xx_tune_drive;
+-	ide_hwifs[1].tuneproc = &ali14xx_tune_drive;
+-	ide_hwifs[0].mate = &ide_hwifs[1];
+-	ide_hwifs[1].mate = &ide_hwifs[0];
+-	ide_hwifs[1].channel = 1;
++	printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
++			  basePort, regOn);
+ 
+ 	/* initialize controller registers */
+ 	if (!initRegisters()) {
+@@ -221,74 +211,59 @@ int __init probe_ali14xx (void)
+ 		return 1;
+ 	}
+ 
+-	probe_hwif_init(&ide_hwifs[0]);
+-	probe_hwif_init(&ide_hwifs[1]);
++	hwif = &ide_hwifs[0];
++	mate = &ide_hwifs[1];
+ 
+-	return 0;
+-}
++	hwif->chipset = ide_ali14xx;
++	hwif->tuneproc = &ali14xx_tune_drive;
++	hwif->mate = mate;
++
++	mate->chipset = ide_ali14xx;
++	mate->tuneproc = &ali14xx_tune_drive;
++	mate->mate = hwif;
++	mate->channel = 1;
+ 
+-static void ali14xx_release (void)
+-{
+-	if (ide_hwifs[0].chipset != ide_ali14xx &&
+-	    ide_hwifs[1].chipset != ide_ali14xx)
+-		return;
++	probe_hwif_init(hwif);
++	probe_hwif_init(mate);
+ 
+-	ide_hwifs[0].chipset = ide_unknown;
+-	ide_hwifs[1].chipset = ide_unknown;
+-	ide_hwifs[0].tuneproc = NULL;
+-	ide_hwifs[1].tuneproc = NULL;
+-	ide_hwifs[0].mate = NULL;
+-	ide_hwifs[1].mate = NULL;
++	return 0;
+ }
+ 
+-#ifndef MODULE
+-/*
+- * init_ali14xx:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_ali14xx (void)
++/* Can be called directly from ide.c. */
++int __init ali14xx_init(void)
+ {
+ 	/* auto-detect IDE controller port */
+-        if (findPort())
+-		if (probe_ali14xx())
+-			goto no_detect;
+-	return;
+-
+-no_detect:
++	if (findPort()) {
++		if (ali14xx_probe())
++			return -ENODEV;
++		return 0;
++	}
+ 	printk(KERN_ERR "ali14xx: not found.\n");
+-	ali14xx_release();
++	return -ENODEV;
+ }
+ 
+-#else
+-
+-MODULE_AUTHOR("see local file");
+-MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
+-MODULE_LICENSE("GPL");
+-
+-static int __init ali14xx_mod_init(void)
++#ifdef MODULE
++static void __exit ali14xx_release_hwif(ide_hwif_t *hwif)
+ {
+-	/* auto-detect IDE controller port */
+-	if (findPort())
+-		if (probe_ali14xx()) {
+-			ali14xx_release();
+-			return -ENODEV;
+-		}
++	if (hwif->chipset != ide_ali14xx)
++		return;
+ 
+-	if (ide_hwifs[0].chipset != ide_ali14xx &&
+-	    ide_hwifs[1].chipset != ide_ali14xx) {
+-		ali14xx_release();
+-		return -ENODEV;
+-	}
+-	return 0;
++	hwif->chipset = ide_unknown;
++	hwif->tuneproc = NULL;
++	hwif->mate = NULL;
++	hwif->channel = 0;
+ }
+-module_init(ali14xx_mod_init);
+ 
+-static void __exit ali14xx_mod_exit(void)
++static void __exit ali14xx_exit(void)
+ {
+-	ali14xx_release();
++	ali14xx_release_hwif(&ide_hwifs[0]);
++	ali14xx_release_hwif(&ide_hwifs[1]);
+ }
+-module_exit(ali14xx_mod_exit);
++
++module_init(ali14xx_init);
++module_exit(ali14xx_exit);
+ #endif
+ 
++MODULE_AUTHOR("see local file");
++MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/legacy/dtc2278.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/dtc2278.c	2003-10-05 00:33:24.000000000 -0700
+@@ -95,9 +95,16 @@ static void tune_dtc2278 (ide_drive_t *d
+ 	HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
+ }
+ 
+-void __init probe_dtc2278 (void)
++static int __init probe_dtc2278(void)
+ {
+ 	unsigned long flags;
++	ide_hwif_t *hwif, *mate;
++
++	hwif = &ide_hwifs[0];
++	mate = &ide_hwifs[1];
++
++	if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown)
++		return 1;
+ 
+ 	local_irq_save(flags);
+ 	/*
+@@ -117,76 +124,60 @@ void __init probe_dtc2278 (void)
+ #endif
+ 	local_irq_restore(flags);
+ 
+-	ide_hwifs[0].serialized = 1;
+-	ide_hwifs[1].serialized = 1;
+-	ide_hwifs[0].chipset = ide_dtc2278;
+-	ide_hwifs[1].chipset = ide_dtc2278;
+-	ide_hwifs[0].tuneproc = &tune_dtc2278;
+-	ide_hwifs[0].drives[0].no_unmask = 1;
+-	ide_hwifs[0].drives[1].no_unmask = 1;
+-	ide_hwifs[1].drives[0].no_unmask = 1;
+-	ide_hwifs[1].drives[1].no_unmask = 1;
+-	ide_hwifs[0].mate = &ide_hwifs[1];
+-	ide_hwifs[1].mate = &ide_hwifs[0];
+-	ide_hwifs[1].channel = 1;
++	hwif->serialized = 1;
++	hwif->chipset = ide_dtc2278;
++	hwif->tuneproc = &tune_dtc2278;
++	hwif->drives[0].no_unmask = 1;
++	hwif->drives[1].no_unmask = 1;
++	hwif->mate = mate;
++
++	mate->serialized = 1;
++	mate->chipset = ide_dtc2278;
++	mate->drives[0].no_unmask = 1;
++	mate->drives[1].no_unmask = 1;
++	mate->mate = hwif;
++	mate->channel = 1;
++
++	probe_hwif_init(hwif);
++	probe_hwif_init(mate);
+ 
+-	probe_hwif_init(&ide_hwifs[0]);
+-	probe_hwif_init(&ide_hwifs[1]);
++	return 0;
+ }
+ 
+-static void dtc2278_release (void)
++/* Can be called directly from ide.c. */
++int __init dtc2278_init(void)
+ {
+-	if (ide_hwifs[0].chipset != ide_dtc2278 &&
+-	    ide_hwifs[1].chipset != ide_dtc2278)
++	if (probe_dtc2278()) {
++		printk(KERN_ERR "dtc2278: ide interfaces already in use!\n");
++		return -EBUSY;
++	}
++	return 0;
++}
++
++#ifdef MODULE
++static void __exit dtc2278_release_hwif(ide_hwif_t *hwif)
++{
++	if (hwif->chipset != ide_dtc2278)
+ 		return;
+ 
+-	ide_hwifs[0].serialized = 0;
+-	ide_hwifs[1].serialized = 0;
+-	ide_hwifs[0].chipset = ide_unknown;
+-	ide_hwifs[1].chipset = ide_unknown;
+-	ide_hwifs[0].tuneproc = NULL;
+-	ide_hwifs[0].drives[0].no_unmask = 0;
+-	ide_hwifs[0].drives[1].no_unmask = 0;
+-	ide_hwifs[1].drives[0].no_unmask = 0;
+-	ide_hwifs[1].drives[1].no_unmask = 0;
+-	ide_hwifs[0].mate = NULL;
+-	ide_hwifs[1].mate = NULL;
++	hwif->serialized = 0;
++	hwif->chipset = ide_unknown;
++	hwif->tuneproc = NULL;
++	hwif->drives[0].no_unmask = 0;
++	hwif->drives[1].no_unmask = 0;
++	hwif->mate = NULL;
+ }
+ 
+-#ifndef MODULE
+-/*
+- * init_dtc2278:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_dtc2278 (void)
++static void __exit dtc2278_exit(void)
+ {
+-	probe_dtc2278();
++	dtc2278_release_hwif(&ide_hwifs[0]);
++	dtc2278_release_hwif(&ide_hwifs[1]);
+ }
+ 
+-#else
++module_init(dtc2278_init);
++module_exit(dtc2278_exit);
++#endif
+ 
+ MODULE_AUTHOR("See Local File");
+ MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
+ MODULE_LICENSE("GPL");
+-
+-static int __init dtc2278_mod_init(void)
+-{
+-	probe_dtc2278();
+-	if (ide_hwifs[0].chipset != ide_dtc2278 &&
+-	    ide_hwifs[1].chipset != ide_dtc2278) {
+-		dtc2278_release();
+-		return -ENODEV;
+-	}
+-	return 0;
+-}
+-module_init(dtc2278_mod_init);
+-
+-static void __exit dtc2278_mod_exit(void)
+-{
+-	dtc2278_release();
+-}
+-module_exit(dtc2278_mod_exit);
+-#endif
+-
+--- linux-2.6.0-test6/drivers/ide/legacy/hd98.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/ide/legacy/hd98.c	2003-10-05 00:33:54.000000000 -0700
+@@ -652,10 +652,10 @@ static void do_hd_request (request_queue
+ 	enable_irq(HD_IRQ);
+ }
+ 
+-static int hd_ioctl(struct inode * inode, struct file * file,
++static int hd_ioctl(struct block_device *bdev, struct file *file,
+ 	unsigned int cmd, unsigned long arg)
+ {
+-	struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
++	struct hd_i_struct *disk = bdev->bd_disk->private_data;
+ 	struct hd_geometry *loc = (struct hd_geometry *) arg;
+ 	struct hd_geometry g; 
+ 
+@@ -666,7 +666,7 @@ static int hd_ioctl(struct inode * inode
+ 	g.heads = disk->head;
+ 	g.sectors = disk->sect;
+ 	g.cylinders = disk->cyl;
+-	g.start = get_start_sect(inode->i_bdev);
++	g.start = get_start_sect(bdev);
+ 	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+ 
+--- linux-2.6.0-test6/drivers/ide/legacy/hd.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/ide/legacy/hd.c	2003-10-05 00:33:54.000000000 -0700
+@@ -656,10 +656,10 @@ static void do_hd_request (request_queue
+ 	enable_irq(HD_IRQ);
+ }
+ 
+-static int hd_ioctl(struct inode * inode, struct file * file,
++static int hd_ioctl(struct block_device *bdev, struct file *file,
+ 	unsigned int cmd, unsigned long arg)
+ {
+-	struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
++	struct hd_i_struct *disk = bdev->bd_disk->private_data;
+ 	struct hd_geometry *loc = (struct hd_geometry *) arg;
+ 	struct hd_geometry g; 
+ 
+@@ -670,7 +670,7 @@ static int hd_ioctl(struct inode * inode
+ 	g.heads = disk->head;
+ 	g.sectors = disk->sect;
+ 	g.cylinders = disk->cyl;
+-	g.start = get_start_sect(inode->i_bdev);
++	g.start = get_start_sect(bdev);
+ 	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+ 
+--- linux-2.6.0-test6/drivers/ide/legacy/ht6560b.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/ht6560b.c	2003-10-05 00:33:24.000000000 -0700
+@@ -304,35 +304,16 @@ static void tune_ht6560b (ide_drive_t *d
+ #endif
+ }
+ 
+-void ht6560b_release (void)
+-{
+-	if (ide_hwifs[0].chipset != ide_ht6560b &&
+-	    ide_hwifs[1].chipset != ide_ht6560b)
+-                return;
+-
+-	ide_hwifs[0].chipset = ide_unknown;
+-	ide_hwifs[1].chipset = ide_unknown;
+-	ide_hwifs[0].tuneproc = NULL;
+-	ide_hwifs[1].tuneproc = NULL;
+-	ide_hwifs[0].selectproc = NULL;
+-	ide_hwifs[1].selectproc = NULL;
+-	ide_hwifs[0].serialized = 0;
+-	ide_hwifs[1].serialized = 0;
+-	ide_hwifs[0].mate = NULL;
+-	ide_hwifs[1].mate = NULL;
+-
+-	ide_hwifs[0].drives[0].drive_data = 0;
+-	ide_hwifs[0].drives[1].drive_data = 0;
+-	ide_hwifs[1].drives[0].drive_data = 0;
+-	ide_hwifs[1].drives[1].drive_data = 0;
+-	release_region(HT_CONFIG_PORT, 1);
+-}
+-
+-static int __init ht6560b_mod_init(void)
++/* Can be called directly from ide.c. */
++int __init ht6560b_init(void)
+ {
++	ide_hwif_t *hwif, *mate;
+ 	int t;
+ 
+-	if (!request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name)) {
++	hwif = &ide_hwifs[0];
++	mate = &ide_hwifs[1];
++
++	if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) {
+ 		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
+ 			__FUNCTION__);
+ 		return -ENODEV;
+@@ -343,39 +324,33 @@ static int __init ht6560b_mod_init(void)
+ 		goto release_region;
+ 	}
+ 
+-	ide_hwifs[0].chipset = ide_ht6560b;
+-	ide_hwifs[1].chipset = ide_ht6560b;
+-	ide_hwifs[0].selectproc = &ht6560b_selectproc;
+-	ide_hwifs[1].selectproc = &ht6560b_selectproc;
+-	ide_hwifs[0].tuneproc = &tune_ht6560b;
+-	ide_hwifs[1].tuneproc = &tune_ht6560b;
+-	ide_hwifs[0].serialized = 1;  /* is this needed? */
+-	ide_hwifs[1].serialized = 1;  /* is this needed? */
+-	ide_hwifs[0].mate = &ide_hwifs[1];
+-	ide_hwifs[1].mate = &ide_hwifs[0];
+-	ide_hwifs[1].channel = 1;
++	hwif->chipset = ide_ht6560b;
++	hwif->selectproc = &ht6560b_selectproc;
++	hwif->tuneproc = &tune_ht6560b;
++	hwif->serialized = 1;	/* is this needed? */
++	hwif->mate = mate;
++
++	mate->chipset = ide_ht6560b;
++	mate->selectproc = &ht6560b_selectproc;
++	mate->tuneproc = &tune_ht6560b;
++	mate->serialized = 1;	/* is this needed? */
++	mate->mate = hwif;
++	mate->channel = 1;
+ 
+ 	/*
+ 	 * Setting default configurations for drives
+ 	 */
+ 	t = (HT_CONFIG_DEFAULT << 8);
+ 	t |= HT_TIMING_DEFAULT;
+-	ide_hwifs[0].drives[0].drive_data = t;
+-	ide_hwifs[0].drives[1].drive_data = t;
+-	t |= (HT_SECONDARY_IF << 8);
+-	ide_hwifs[1].drives[0].drive_data = t;
+-	ide_hwifs[1].drives[1].drive_data = t;
++	hwif->drives[0].drive_data = t;
++	hwif->drives[1].drive_data = t;
+ 
+-	probe_hwif_init(&ide_hwifs[0]);
+-	probe_hwif_init(&ide_hwifs[1]);
++	t |= (HT_SECONDARY_IF << 8);
++	mate->drives[0].drive_data = t;
++	mate->drives[1].drive_data = t;
+ 
+-#ifdef MODULE
+-	if (ide_hwifs[0].chipset != ide_ht6560b &&
+-	    ide_hwifs[1].chipset != ide_ht6560b) {
+-		ht6560b_release();
+-		return -ENODEV;
+-	}
+-#endif
++	probe_hwif_init(hwif);
++	probe_hwif_init(mate);
+ 
+ 	return 0;
+ 
+@@ -384,24 +359,34 @@ release_region:
+ 	return -ENODEV;
+ }
+ 
+-MODULE_AUTHOR("See Local File");
+-MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
+-MODULE_LICENSE("GPL");
+-
+ #ifdef MODULE
+-static void __exit ht6560b_mod_exit(void)
++static void __exit ht6560b_release_hwif(ide_hwif_t *hwif)
+ {
+-        ht6560b_release();
++	if (hwif->chipset != ide_ht6560b)
++		return;
++
++	hwif->chipset = ide_unknown;
++	hwif->tuneproc = NULL;
++	hwif->selectproc = NULL;
++	hwif->serialized = 0;
++	hwif->mate = NULL;
++	hwif->channel = 0;
++
++	hwif->drives[0].drive_data = 0;
++	hwif->drives[1].drive_data = 0;
+ }
+ 
+-module_init(ht6560b_mod_init);
+-module_exit(ht6560b_mod_exit);
+-#else
+-/*
+- * called by ide.c when parsing command line
+- */
+-void __init init_ht6560b (void)
++static void __exit ht6560b_exit(void)
+ {
+-	ht6560b_mod_init();	/* ignore return value */
++	ht6560b_release_hwif(&ide_hwifs[0]);
++	ht6560b_release_hwif(&ide_hwifs[1]);
++	release_region(HT_CONFIG_PORT, 1);
+ }
++
++module_init(ht6560b_init);
++module_exit(ht6560b_exit);
+ #endif
++
++MODULE_AUTHOR("See Local File");
++MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/legacy/pdc4030.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/pdc4030.c	2003-10-05 00:33:24.000000000 -0700
+@@ -147,8 +147,6 @@ int pdc4030_identify(ide_drive_t *drive)
+ 	return pdc4030_cmd(drive, PROMISE_IDENTIFY);
+ }
+ 
+-int enable_promise_support;
+-
+ /*
+  * setup_pdc4030()
+  * Completes the setup of a Promise DC4030 controller card, once found.
+@@ -296,33 +294,24 @@ int __init detect_pdc4030(ide_hwif_t *hw
+ 	}
+ }
+ 
+-
+-int __init ide_probe_for_pdc4030(void)
++int __init pdc4030_init(void)
+ {
+ 	unsigned int	index;
+ 	ide_hwif_t	*hwif;
+ 
+-#ifndef MODULE
+-	if (enable_promise_support == 0)
+-		return;
+-#endif
+-
+ 	for (index = 0; index < MAX_HWIFS; index++) {
+ 		hwif = &ide_hwifs[index];
+ 		if (hwif->chipset == ide_unknown && detect_pdc4030(hwif)) {
+-#ifndef MODULE
+-			setup_pdc4030(hwif);
+-#else
+-			return setup_pdc4030(hwif);
+-#endif
++			if (!setup_pdc4030(hwif))
++				return -ENODEV;
++			return 0;
+ 		}
+ 	}
+-#ifdef MODULE
+-	return 0;
+-#endif
++	return -ENODEV;
+ }
+ 
+-static void __exit release_pdc4030(ide_hwif_t *hwif, ide_hwif_t *mate)
++#ifdef MODULE
++static void __exit pdc4030_release_hwif(ide_hwif_t *hwif)
+ {
+ 	hwif->chipset = ide_unknown;
+ 	hwif->selectproc = NULL;
+@@ -333,72 +322,24 @@ static void __exit release_pdc4030(ide_h
+ 	hwif->drives[1].keep_settings = 0;
+ 	hwif->drives[0].noprobe = 0;
+ 	hwif->drives[1].noprobe = 0;
+-
+-	if (mate != NULL) {
+-		mate->chipset = ide_unknown;
+-		mate->selectproc = NULL;
+-		mate->serialized = 0;
+-		mate->drives[0].io_32bit = 0;
+-		mate->drives[1].io_32bit = 0;
+-		mate->drives[0].keep_settings = 0;
+-		mate->drives[1].keep_settings = 0;
+-		mate->drives[0].noprobe = 0;
+-		mate->drives[1].noprobe = 0;
+-	}
+ }
+ 
+-#ifndef MODULE
+-/*
+- * init_pdc4030:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_pdc4030(void)
++static void __exit pdc4030_exit(void)
+ {
+-	enable_promise_support = 1;
++	unsigned int index;
++
++	for (index = 0; index < MAX_HWIFS; index++)
++		pdc4030_release_hwif(&ide_hwifs[index]);
+ }
+ 
+-#else
++module_init(pdc4030_init);
++module_exit(pdc4030_exit);
++#endif
+ 
+ MODULE_AUTHOR("Peter Denison");
+ MODULE_DESCRIPTION("Support of Promise 4030 VLB series IDE chipsets");
+ MODULE_LICENSE("GPL");
+ 
+-static int __init pdc4030_mod_init(void)
+-{
+-	if (enable_promise_support == 0)
+-		enable_promise_support = 1;
+-
+-	if (!ide_probe_for_pdc4030())
+-		return -ENODEV;
+-        return 0;
+-}
+-module_init(pdc4030_mod_init);
+-
+-static void __exit pdc4030_mod_exit(void)
+-{
+-	unsigned int    index;
+-	ide_hwif_t      *hwif;
+-
+-	if (enable_promise_support == 0)
+-		return;
+- 
+-	for (index = 0; index < MAX_HWIFS; index++) {
+-		hwif = &ide_hwifs[index];
+-		if (hwif->chipset == ide_pdc4030) {
+-			ide_hwif_t *mate = &ide_hwifs[hwif->index+1];
+-			if (mate->chipset == ide_pdc4030)
+-				release_pdc4030(hwif, mate);
+-			else
+-				release_pdc4030(hwif, NULL);
+-                }
+-        }
+-	enable_promise_support = 0;
+-}
+-module_exit(pdc4030_mod_exit);
+-#endif
+-
+ /*
+  * promise_read_intr() is the handler for disk read/multread interrupts
+  */
+--- linux-2.6.0-test6/drivers/ide/legacy/qd65xx.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/qd65xx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -338,12 +338,12 @@ static int __init qd_testreg(int port)
+  * called to setup an ata channel : adjusts attributes & links for tuning
+  */
+ 
+-void __init qd_setup (int unit, int base, int config, unsigned int data0, unsigned int data1, void (*tuneproc) (ide_drive_t *, u8 pio))
++static void __init qd_setup(ide_hwif_t *hwif, int base, int config,
++			    unsigned int data0, unsigned int data1,
++			    void (*tuneproc) (ide_drive_t *, u8 pio))
+ {
+-	ide_hwif_t *hwif = &ide_hwifs[unit];
+-
+ 	hwif->chipset = ide_qd65xx;
+-	hwif->channel = unit;
++	hwif->channel = hwif->index;
+ 	hwif->select_data = base;
+ 	hwif->config_data = config;
+ 	hwif->drives[0].drive_data = data0;
+@@ -354,19 +354,20 @@ void __init qd_setup (int unit, int base
+ 	probe_hwif_init(hwif);
+ }
+ 
++#ifdef MODULE
+ /*
+  * qd_unsetup:
+  *
+  * called to unsetup an ata channel : back to default values, unlinks tuning
+  */
+-static void __exit qd_unsetup (int unit)
++static void __exit qd_unsetup(ide_hwif_t *hwif)
+ {
+-	ide_hwif_t *hwif = &ide_hwifs[unit];
+ 	u8 config = hwif->config_data;
+ 	int base = hwif->select_data;
+ 	void *tuneproc = (void *) hwif->tuneproc;
+ 
+-	if (!(hwif->chipset == ide_qd65xx)) return;
++	if (hwif->chipset != ide_qd65xx)
++		return;
+ 
+ 	printk(KERN_NOTICE "%s: back to defaults\n", hwif->name);
+ 
+@@ -381,13 +382,14 @@ static void __exit qd_unsetup (int unit)
+ 			qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ 			qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
+ 		} else {
+-			qd_write_reg(unit?QD6580_DEF_DATA2:QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
++			qd_write_reg(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ 		}
+ 	} else {
+ 		printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
+ 		printk(KERN_WARNING "keeping settings !\n");
+ 	}
+ }
++#endif
+ 
+ /*
+  * qd_probe:
+@@ -396,8 +398,9 @@ static void __exit qd_unsetup (int unit)
+  * return 1 if another qd may be probed
+  */
+ 
+-int __init qd_probe (int base)
++static int __init qd_probe(int base)
+ {
++	ide_hwif_t *hwif;
+ 	u8 config;
+ 	u8 unit;
+ 
+@@ -414,9 +417,8 @@ int __init qd_probe (int base)
+ 
+ 		/* qd6500 found */
+ 
+-		printk(KERN_NOTICE "%s: qd6500 at %#x\n",
+-			ide_hwifs[unit].name, base);
+-		
++		hwif = &ide_hwifs[unit];
++		printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base);
+ 		printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+ 			config, QD_ID3);
+ 		
+@@ -425,8 +427,8 @@ int __init qd_probe (int base)
+ 			return 1;
+ 		}
+ 
+-		qd_setup(unit, base, config, QD6500_DEF_DATA,
+-			QD6500_DEF_DATA, &qd6500_tune_drive);
++		qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA,
++			 &qd6500_tune_drive);
+ 		return 1;
+ 	}
+ 
+@@ -448,25 +450,31 @@ int __init qd_probe (int base)
+ 
+ 		if (control & QD_CONTR_SEC_DISABLED) {
+ 			/* secondary disabled */
++
++			hwif = &ide_hwifs[unit];
+ 			printk(KERN_INFO "%s: qd6580: single IDE board\n",
+-					ide_hwifs[unit].name);
+-			qd_setup(unit, base, config | (control << 8),
+-				QD6580_DEF_DATA, QD6580_DEF_DATA2,
+-				&qd6580_tune_drive);
++					 hwif->name);
++			qd_setup(hwif, base, config | (control << 8),
++				 QD6580_DEF_DATA, QD6580_DEF_DATA2,
++				 &qd6580_tune_drive);
+ 			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+ 
+ 			return 1;
+ 		} else {
++			ide_hwif_t *mate;
++
++			hwif = &ide_hwifs[0];
++			mate = &ide_hwifs[1];
+ 			/* secondary enabled */
+ 			printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+-					ide_hwifs[0].name,ide_hwifs[1].name);
++					hwif->name, mate->name);
+ 
+-			qd_setup(0, base, config | (control << 8),
+-				QD6580_DEF_DATA, QD6580_DEF_DATA,
+-				&qd6580_tune_drive);
+-			qd_setup(1, base, config | (control << 8),
+-				QD6580_DEF_DATA2, QD6580_DEF_DATA2,
+-				&qd6580_tune_drive);
++			qd_setup(hwif, base, config | (control << 8),
++				 QD6580_DEF_DATA, QD6580_DEF_DATA,
++				 &qd6580_tune_drive);
++			qd_setup(mate, base, config | (control << 8),
++				 QD6580_DEF_DATA2, QD6580_DEF_DATA2,
++				 &qd6580_tune_drive);
+ 			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+ 
+ 			return 0; /* no other qd65xx possible */
+@@ -476,38 +484,28 @@ int __init qd_probe (int base)
+ 	return 1;
+ }
+ 
+-#ifndef MODULE
+-/*
+- * init_qd65xx:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_qd65xx (void)
+-{
+-	if (qd_probe(0x30)) qd_probe(0xb0);
+-}
+-
+-#else
+-
+-MODULE_AUTHOR("Samuel Thibault");
+-MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
+-MODULE_LICENSE("GPL");
+-
+-static int __init qd65xx_mod_init(void)
++/* Can be called directly from ide.c. */
++int __init qd65xx_init(void)
+ {
+-	if (qd_probe(0x30)) qd_probe(0xb0);
++	if (qd_probe(0x30))
++		qd_probe(0xb0);
+ 	if (ide_hwifs[0].chipset != ide_qd65xx &&
+ 	    ide_hwifs[1].chipset != ide_qd65xx)
+ 		return -ENODEV;
+ 	return 0;
+ }
+-module_init(qd65xx_mod_init);
+ 
+-static void __exit qd65xx_mod_exit(void)
++#ifdef MODULE
++static void __exit qd65xx_exit(void)
+ {
+-	qd_unsetup(0);
+-	qd_unsetup(1);
++	qd_unsetup(&ide_hwifs[0]);
++	qd_unsetup(&ide_hwifs[1]);
+ }
+-module_exit(qd65xx_mod_exit);
++
++module_init(qd65xx_init);
++module_exit(qd65xx_exit);
+ #endif
++
++MODULE_AUTHOR("Samuel Thibault");
++MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/legacy/umc8672.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/legacy/umc8672.c	2003-10-05 00:33:24.000000000 -0700
+@@ -124,16 +124,16 @@ static void tune_umc (ide_drive_t *drive
+ 	spin_unlock_irqrestore(&ide_lock, flags);
+ }
+ 
+-int __init probe_umc8672 (void)
++static int __init umc8672_probe(void)
+ {
+ 	unsigned long flags;
++	ide_hwif_t *hwif, *mate;
+ 
+-	local_irq_save(flags);
+ 	if (!request_region(0x108, 2, "umc8672")) {
+-		local_irq_restore(flags);
+ 		printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
+ 		return 1;
+ 	}
++	local_irq_save(flags);
+ 	outb_p(0x5A,0x108); /* enable umc */
+ 	if (in_umc (0xd5) != 0xa0) {
+ 		local_irq_restore(flags);
+@@ -146,82 +146,62 @@ int __init probe_umc8672 (void)
+ 	umc_set_speeds (current_speeds);
+ 	local_irq_restore(flags);
+ 
+-	ide_hwifs[0].chipset = ide_umc8672;
+-	ide_hwifs[1].chipset = ide_umc8672;
+-	ide_hwifs[0].tuneproc = &tune_umc;
+-	ide_hwifs[1].tuneproc = &tune_umc;
+-	ide_hwifs[0].mate = &ide_hwifs[1];
+-	ide_hwifs[1].mate = &ide_hwifs[0];
+-	ide_hwifs[1].channel = 1;
++	hwif = &ide_hwifs[0];
++	mate = &ide_hwifs[1];
+ 
+-	probe_hwif_init(&ide_hwifs[0]);
+-	probe_hwif_init(&ide_hwifs[1]);
++	hwif->chipset = ide_umc8672;
++	hwif->tuneproc = &tune_umc;
++	hwif->mate = mate;
++
++	mate->chipset = ide_umc8672;
++	mate->tuneproc = &tune_umc;
++	mate->mate = hwif;
++	mate->channel = 1;
++
++	probe_hwif_init(hwif);
++	probe_hwif_init(mate);
+ 
+ 	return 0;
+ }
+ 
+-static void umc8672_release (void)
++/* Can be called directly from ide.c. */
++int __init umc8672_init(void)
+ {
+-	unsigned long flags;
++	if (umc8672_probe())
++		return -ENODEV;
++	return 0;
++}
+ 
+-	local_irq_save(flags);
+-	if (ide_hwifs[0].chipset != ide_umc8672 &&
+-	    ide_hwifs[1].chipset != ide_umc8672) {
+-		local_irq_restore(flags);
++#ifdef MODULE
++static void __exit umc8672_release_hwif(ide_hwif_t *hwif)
++{
++	if (hwif->chipset != ide_umc8672)
+ 		return;
+-	}
+ 
+-	ide_hwifs[0].chipset = ide_unknown;
+-	ide_hwifs[1].chipset = ide_unknown;	
+-	ide_hwifs[0].tuneproc = NULL;
+-	ide_hwifs[1].tuneproc = NULL;
+-	ide_hwifs[0].mate = NULL;
+-	ide_hwifs[1].mate = NULL;
+-	ide_hwifs[0].channel = 0;
+-	ide_hwifs[1].channel = 0;
+-
+-	outb_p(0xa5,0x108); /* disable umc */
+-
+-	release_region(0x108, 2);
+-	local_irq_restore(flags);
++	hwif->chipset = ide_unknown;
++	hwif->tuneproc = NULL;
++	hwif->mate = NULL;
++	hwif->channel = 0;
+ }
+ 
+-#ifndef MODULE
+-/*
+- * init_umc8672:
+- *
+- * called by ide.c when parsing command line
+- */
+-
+-void __init init_umc8672 (void)
++static void __exit umc8672_exit(void)
+ {
+-	if (probe_umc8672())
+-		printk(KERN_ERR "init_umc8672: umc8672 controller not found.\n");
+-}
++	unsigned long flags;
+ 
+-#else
++	umc8672_release_hwif(&ide_hwifs[0]);
++	umc8672_release_hwif(&ide_hwifs[1]);
+ 
+-MODULE_AUTHOR("Wolfram Podien");
+-MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
+-MODULE_LICENSE("GPL");
++	local_irq_save(flags);
++	outb_p(0xa5, 0x108);	/* disable umc */
++	local_irq_restore(flags);
+ 
+-static int __init umc8672_mod_init(void)
+-{
+-	if (probe_umc8672())
+-		return -ENODEV;
+-	if (ide_hwifs[0].chipset != ide_umc8672 &&
+-	    ide_hwifs[1].chipset != ide_umc8672) {
+-		umc8672_release();
+-		return -ENODEV;
+-	}
+-	return 0;
++	release_region(0x108, 2);
+ }
+-module_init(umc8672_mod_init);
+ 
+-static void __exit umc8672_mod_exit(void)
+-{
+-        umc8672_release();
+-}
+-module_exit(umc8672_mod_exit);
++module_init(umc8672_init);
++module_exit(umc8672_exit);
+ #endif
+ 
++MODULE_AUTHOR("Wolfram Podien");
++MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/pci/amd74xx.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/ide/pci/amd74xx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Version 2.9
++ * Version 2.11
+  *
+  * AMD 755/756/766/8111 and nVidia nForce IDE driver for Linux.
+  *
+@@ -65,7 +65,6 @@ static struct amd_ide_chip {
+ };
+ 
+ static struct amd_ide_chip *amd_config;
+-static unsigned char amd_enabled;
+ static unsigned int amd_80w;
+ static unsigned int amd_clock;
+ 
+@@ -103,7 +102,7 @@ static int amd74xx_get_info(char *buffer
+ 
+ 	amd_print("----------AMD BusMastering IDE Configuration----------------");
+ 
+-	amd_print("Driver Version:                     2.9");
++	amd_print("Driver Version:                     2.11");
+ 	amd_print("South Bridge:                       %s", pci_name(bmide_dev));
+ 
+ 	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+@@ -250,9 +249,6 @@ static int amd_set_drive(ide_drive_t *dr
+ 
+ static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
+ {
+-	if (!((amd_enabled >> HWIF(drive)->channel) & 1))
+-		return;
+-
+ 	if (pio == 255) {
+ 		amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+ 		return;
+@@ -330,9 +326,6 @@ static unsigned int __init init_chipset_
+ 			break;
+ 	}
+ 
+-	pci_read_config_dword(dev, AMD_IDE_ENABLE, &u);
+-	amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0);
+-
+ /*
+  * Take care of prefetch & postwrite.
+  */
+@@ -408,8 +401,8 @@ static void __init init_hwif_amd74xx(ide
+         hwif->mwdma_mask = 0x07;
+         hwif->swdma_mask = 0x07;
+ 
+-        if (!(hwif->udma_four))
+-                hwif->udma_four = ((amd_enabled & amd_80w) >> hwif->channel) & 1;
++	if (!hwif->udma_four)
++		hwif->udma_four = (amd_80w >> hwif->channel) & 1;
+         hwif->ide_dma_check = &amd74xx_ide_dma_check;
+         if (!noautodma)
+                 hwif->autodma = 1;
+@@ -417,16 +410,6 @@ static void __init init_hwif_amd74xx(ide
+         hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-/*
+- * We allow the BM-DMA driver only work on enabled interfaces.
+- */
+-
+-static void __init init_dma_amd74xx(ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	if ((amd_enabled >> hwif->channel) & 1)
+-		ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/amd74xx.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/ide/pci/amd74xx.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@ static ide_pci_host_proc_t amd74xx_procs
+ 
+ static unsigned int init_chipset_amd74xx(struct pci_dev *, const char *);
+ static void init_hwif_amd74xx(ide_hwif_t *);
+-static void init_dma_amd74xx(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -35,9 +34,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_AMD_COBRA_7401,
+ 		.name		= "AMD7401",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -48,9 +45,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_AMD_VIPER_7409,
+ 		.name		= "AMD7409",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -61,9 +56,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_AMD_VIPER_7411,
+ 		.name		= "AMD7411",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -74,9 +67,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_AMD_OPUS_7441,
+ 		.name		= "AMD7441",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -87,9 +78,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_AMD_8111_IDE,
+ 		.name		= "AMD8111",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.autodma	= AUTODMA,
+ 		.channels	= 2,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -101,9 +90,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,
+ 		.name		= "NFORCE",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+@@ -115,9 +102,7 @@ static ide_pci_device_t amd74xx_chipsets
+ 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,
+ 		.name		= "NFORCE2",
+ 		.init_chipset	= init_chipset_amd74xx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_amd74xx,
+-		.init_dma	= init_dma_amd74xx,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+--- linux-2.6.0-test6/drivers/ide/pci/cmd64x.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/cmd64x.c	2003-10-05 00:33:24.000000000 -0700
+@@ -742,11 +742,6 @@ static void __init init_hwif_cmd64x (ide
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_cmd64x (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/cmd64x.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/ide/pci/cmd64x.h	2003-10-05 00:33:24.000000000 -0700
+@@ -81,7 +81,6 @@ static ide_pci_host_proc_t cmd64x_procs[
+ 
+ static unsigned int init_chipset_cmd64x(struct pci_dev *, const char *);
+ static void init_hwif_cmd64x(ide_hwif_t *);
+-static void init_dma_cmd64x(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -91,7 +90,6 @@ static ide_pci_device_t cmd64x_chipsets[
+ 		.init_chipset	= init_chipset_cmd64x,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_cmd64x,
+-		.init_dma	= init_dma_cmd64x,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -104,7 +102,6 @@ static ide_pci_device_t cmd64x_chipsets[
+ 		.init_chipset	= init_chipset_cmd64x,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_cmd64x,
+-		.init_dma	= init_dma_cmd64x,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
+@@ -117,7 +114,6 @@ static ide_pci_device_t cmd64x_chipsets[
+ 		.init_chipset	= init_chipset_cmd64x,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_cmd64x,
+-		.init_dma	= init_dma_cmd64x,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -130,7 +126,6 @@ static ide_pci_device_t cmd64x_chipsets[
+ 		.init_chipset	= init_chipset_cmd64x,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_cmd64x,
+-		.init_dma	= init_dma_cmd64x,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/cs5530.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/cs5530.c	2003-10-05 00:33:24.000000000 -0700
+@@ -404,19 +404,6 @@ static void __init init_hwif_cs5530 (ide
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-/**
+- *	init_dma_cs5530		-	set up for DMA
+- *	@hwif: interface
+- *	@dmabase: DMA base address
+- *
+- *	FIXME: this can go away
+- */
+- 
+-static void __init init_dma_cs5530 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ 
+--- linux-2.6.0-test6/drivers/ide/pci/cs5530.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/ide/pci/cs5530.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@ static ide_pci_host_proc_t cs5530_procs[
+ 
+ static unsigned int init_chipset_cs5530(struct pci_dev *, const char *);
+ static void init_hwif_cs5530(ide_hwif_t *);
+-static void init_dma_cs5530(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t cs5530_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -37,7 +36,6 @@ static ide_pci_device_t cs5530_chipsets[
+ 		.init_chipset	= init_chipset_cs5530,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_cs5530,
+-		.init_dma	= init_dma_cs5530,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/generic.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/generic.c	2003-10-05 00:33:24.000000000 -0700
+@@ -72,11 +72,6 @@ static void __init init_hwif_generic (id
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void init_dma_generic (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ #if 0
+--- linux-2.6.0-test6/drivers/ide/pci/generic.h	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/generic.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,7 +7,6 @@
+ 
+ static unsigned int init_chipset_generic(struct pci_dev *, const char *);
+ static void init_hwif_generic(ide_hwif_t *);
+-static void init_dma_generic(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t generic_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -17,7 +16,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
+@@ -30,7 +28,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -43,7 +40,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -56,7 +52,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= NODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -69,7 +64,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= NODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -82,7 +76,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= NODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -95,7 +88,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -108,7 +100,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -121,7 +112,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -134,7 +124,6 @@ static ide_pci_device_t generic_chipsets
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -157,7 +146,6 @@ static ide_pci_device_t unknown_chipset[
+ 		.init_chipset	= init_chipset_generic,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_generic,
+-		.init_dma	= init_dma_generic,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/hpt34x.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/hpt34x.c	2003-10-05 00:33:24.000000000 -0700
+@@ -315,11 +315,6 @@ static void __init init_hwif_hpt34x (ide
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_hpt34x (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/hpt34x.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/ide/pci/hpt34x.h	2003-10-05 00:33:24.000000000 -0700
+@@ -33,7 +33,6 @@ static ide_pci_host_proc_t hpt34x_procs[
+ 
+ static unsigned int init_chipset_hpt34x(struct pci_dev *, const char *);
+ static void init_hwif_hpt34x(ide_hwif_t *);
+-static void init_dma_hpt34x(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t hpt34x_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -43,7 +42,6 @@ static ide_pci_device_t hpt34x_chipsets[
+ 		.init_chipset	= init_chipset_hpt34x,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_hpt34x,
+-		.init_dma	= init_dma_hpt34x,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/it8172.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/it8172.c	2003-10-05 00:33:24.000000000 -0700
+@@ -284,11 +284,6 @@ static void __init init_hwif_it8172 (ide
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_it8172 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/it8172.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/ide/pci/it8172.h	2003-10-05 00:33:24.000000000 -0700
+@@ -17,7 +17,6 @@ static int it8172_config_chipset_for_dma
+ static void init_setup_it8172(struct pci_dev *, ide_pci_device_t *);
+ static unsigned int init_chipset_it8172(struct pci_dev *, const char *);
+ static void init_hwif_it8172(ide_hwif_t *);
+-static void init_dma_it8172(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t it8172_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -28,7 +27,6 @@ static ide_pci_device_t it8172_chipsets[
+ 		.init_chipset	= init_chipset_it8172,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_it8172,
+-                .init_dma	= init_dma_it8172,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
+--- linux-2.6.0-test6/drivers/ide/pci/Makefile	2003-06-14 12:17:59.000000000 -0700
++++ 25/drivers/ide/pci/Makefile	2003-10-05 00:36:28.000000000 -0700
+@@ -18,10 +18,10 @@ obj-$(CONFIG_BLK_DEV_NS87415)		+= ns8741
+ obj-$(CONFIG_BLK_DEV_OPTI621)		+= opti621.o
+ obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)	+= pdc202xx_old.o
+ obj-$(CONFIG_BLK_DEV_PDC202XX_NEW)	+= pdc202xx_new.o
+-obj-$(CONFIG_BLK_DEV_PDC_ADMA)		+= pdcadma.o ide-adma.o
+ obj-$(CONFIG_BLK_DEV_PIIX)		+= piix.o
+ obj-$(CONFIG_BLK_DEV_RZ1000)		+= rz1000.o
+ obj-$(CONFIG_BLK_DEV_SVWKS)		+= serverworks.o
++obj-$(CONFIG_BLK_DEV_SGIIOC4)		+= sgiioc4.o
+ obj-$(CONFIG_BLK_DEV_SIIMAGE)		+= siimage.o
+ obj-$(CONFIG_BLK_DEV_SIS5513)		+= sis5513.o
+ obj-$(CONFIG_BLK_DEV_SL82C105)		+= sl82c105.o
+--- linux-2.6.0-test6/drivers/ide/pci/ns87415.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/ns87415.c	2003-10-05 00:33:24.000000000 -0700
+@@ -217,11 +217,6 @@ static void __init init_hwif_ns87415 (id
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_ns87415 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/ns87415.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/ide/pci/ns87415.h	2003-10-05 00:33:24.000000000 -0700
+@@ -6,7 +6,6 @@
+ #include <linux/ide.h>
+ 
+ static void init_hwif_ns87415(ide_hwif_t *);
+-static void init_dma_ns87415(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t ns87415_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -16,7 +15,6 @@ static ide_pci_device_t ns87415_chipsets
+ 		.init_chipset	= NULL,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_ns87415,
+-                .init_dma	= init_dma_ns87415,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/opti621.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/opti621.c	2003-10-05 00:33:24.000000000 -0700
+@@ -348,11 +348,6 @@ static void __init init_hwif_opti621 (id
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_opti621 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static void __init init_setup_opti621 (struct pci_dev *dev, ide_pci_device_t *d)
+--- linux-2.6.0-test6/drivers/ide/pci/opti621.h	2003-06-14 12:18:33.000000000 -0700
++++ 25/drivers/ide/pci/opti621.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,7 +7,6 @@
+ 
+ static void init_setup_opti621(struct pci_dev *, ide_pci_device_t *);
+ static void init_hwif_opti621(ide_hwif_t *);
+-static void init_dma_opti621(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -18,7 +17,6 @@ static ide_pci_device_t opti621_chipsets
+ 		.init_chipset	= NULL,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_opti621,
+-		.init_dma	= init_dma_opti621,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+@@ -32,7 +30,6 @@ static ide_pci_device_t opti621_chipsets
+ 		.init_chipset	= NULL,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_opti621,
+-                .init_dma	= init_dma_opti621,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/pdc202xx_new.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/pdc202xx_new.c	2003-10-05 00:33:24.000000000 -0700
+@@ -563,11 +563,6 @@ static void __init init_hwif_pdc202new (
+ #endif /* PDC202_DEBUG_CABLE */
+ }
+ 
+-static void __init init_dma_pdc202new (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
+ 
+--- linux-2.6.0-test6/drivers/ide/pci/pdc202xx_new.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/ide/pci/pdc202xx_new.h	2003-10-05 00:33:24.000000000 -0700
+@@ -188,7 +188,6 @@ static void init_setup_pdc20270(struct p
+ static void init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d);
+ static unsigned int init_chipset_pdcnew(struct pci_dev *, const char *);
+ static void init_hwif_pdc202new(ide_hwif_t *);
+-static void init_dma_pdc202new(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -199,7 +198,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -213,7 +211,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -227,7 +224,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ #ifdef CONFIG_PDC202XX_FORCE
+@@ -245,7 +241,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -259,7 +254,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -273,7 +267,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ #ifdef CONFIG_PDC202XX_FORCE
+@@ -291,7 +284,6 @@ static ide_pci_device_t pdcnew_chipsets[
+ 		.init_chipset	= init_chipset_pdcnew,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_pdc202new,
+-		.init_dma	= init_dma_pdc202new,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/pdcadma.c	2003-09-08 13:58:57.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,162 +0,0 @@
+-/*
+- * linux/drivers/ide/pci/pdcadma.c		Version 0.05	Sept 10, 2002
+- *
+- * Copyright (C) 1999-2000		Andre Hedrick <andre@linux-ide.org>
+- * May be copied or modified under the terms of the GNU General Public License
+- *
+- */
+-
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+-#include <linux/hdreg.h>
+-
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/pci.h>
+-#include <linux/ide.h>
+-
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-
+-#include "pdcadma.h"
+-
+-#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS)
+-#include <linux/stat.h>
+-#include <linux/proc_fs.h>
+-
+-static u8 pdcadma_proc = 0;
+-#define PDC_MAX_DEVS		5
+-static struct pci_dev *pdc_devs[PDC_MAX_DEVS];
+-static int n_pdc_devs;
+-
+-static int pdcadma_get_info (char *buffer, char **addr, off_t offset, int count)
+-{
+-	char *p = buffer;
+-	int i;
+-
+-	for (i = 0; i < n_pdc_devs; i++) {
+-		struct pci_dev *dev	= pdc_devs[i];
+-		unsigned long bibma = pci_resource_start(dev, 4);
+-
+-		p += sprintf(p, "\n                                "
+-			"PDC ADMA %04X Chipset.\n", dev->device);
+-		p += sprintf(p, "UDMA\n");
+-		p += sprintf(p, "PIO\n");
+-
+-	}
+-	return p-buffer;	/* => must be less than 4k! */
+-}
+-#endif  /* defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) */
+-
+-/*
+- * pdcadma_dma functions() initiates/aborts (U)DMA read/write
+- * operations on a drive.
+- */
+-#if 0
+-        int (*ide_dma_read)(ide_drive_t *drive);
+-        int (*ide_dma_write)(ide_drive_t *drive);
+-        int (*ide_dma_begin)(ide_drive_t *drive);
+-        int (*ide_dma_end)(ide_drive_t *drive);
+-        int (*ide_dma_check)(ide_drive_t *drive);
+-        int (*ide_dma_on)(ide_drive_t *drive);
+-        int (*ide_dma_off)(ide_drive_t *drive);
+-        int (*ide_dma_off_quietly)(ide_drive_t *drive);
+-        int (*ide_dma_test_irq)(ide_drive_t *drive);
+-        int (*ide_dma_host_on)(ide_drive_t *drive);
+-        int (*ide_dma_host_off)(ide_drive_t *drive);
+-        int (*ide_dma_bad_drive)(ide_drive_t *drive);
+-        int (*ide_dma_good_drive)(ide_drive_t *drive);
+-        int (*ide_dma_count)(ide_drive_t *drive);
+-        int (*ide_dma_verbose)(ide_drive_t *drive);
+-        int (*ide_dma_retune)(ide_drive_t *drive);
+-        int (*ide_dma_lostirq)(ide_drive_t *drive);
+-        int (*ide_dma_timeout)(ide_drive_t *drive);
+-
+-#endif
+-
+-static unsigned int __init init_chipset_pdcadma (struct pci_dev *dev, const char *name)
+-{
+-#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS)
+-	pdc_devs[n_pdc_devs++] = dev;
+-
+-	if (!pdcadma_proc) {
+-		pdcadma_proc = 1;
+-		ide_pci_register_host_proc(&pdcadma_procs[0]);
+-	}
+-#endif /* DISPLAY_PDCADMA_TIMINGS && CONFIG_PROC_FS */
+-	return 0;
+-}
+-
+-static void __init init_hwif_pdcadma (ide_hwif_t *hwif)
+-{
+-	hwif->autodma = 0;
+-	hwif->dma_base = 0;
+-
+-//	hwif->tuneproc = &pdcadma_tune_drive;
+-//	hwif->speedproc = &pdcadma_tune_chipset;
+-
+-//	if (hwif->dma_base) {
+-//		hwif->autodma = 1;
+-//	}
+-
+-	hwif->udma_four = 1;
+-
+-//	hwif->atapi_dma = 1;
+-//	hwif->ultra_mask = 0x7f;
+-//	hwif->mwdma_mask = 0x07;
+-//	hwif->swdma_mask = 0x07;
+-
+-}
+-
+-static void __init init_dma_pdcadma (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-#if 0
+-	ide_setup_dma(hwif, dmabase, 8);
+-#endif
+-}
+-
+-extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+-
+-static int __devinit pdcadma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+-{
+-	ide_pci_device_t *d = &pdcadma_chipsets[id->driver_data];
+-	if (dev->device != d->device)
+-		BUG();
+-	ide_setup_pci_device(dev, d);
+-	MOD_INC_USE_COUNT;
+-	return 1;
+-}
+-
+-static struct pci_device_id pdcadma_pci_tbl[] = {
+-	{ PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-	{ 0, },
+-};
+-
+-static struct pci_driver driver = {
+-	.name		= "PDCADMA-IDE",
+-	.id_table	= pdcadma_pci_tbl,
+-	.probe		= pdcadma_init_one,
+-};
+-
+-static int pdcadma_ide_init(void)
+-{
+-	return ide_pci_register_driver(&driver);
+-}
+-
+-static void pdcadma_ide_exit(void)
+-{
+-	ide_pci_unregister_driver(&driver);
+-}
+-
+-module_init(pdcadma_ide_init);
+-module_exit(pdcadma_ide_exit);
+-
+-MODULE_AUTHOR("Andre Hedrick");
+-MODULE_DESCRIPTION("PCI driver module for PDCADMA IDE");
+-MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/pci/pdcadma.h	2003-06-14 12:17:56.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,56 +0,0 @@
+-#ifndef PDC_ADMA_H
+-#define PDC_ADMA_H
+-
+-#include <linux/config.h>
+-#include <linux/pci.h>
+-#include <linux/ide.h>
+-
+-#undef DISPLAY_PDCADMA_TIMINGS
+-
+-#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS)
+-#include <linux/stat.h>
+-#include <linux/proc_fs.h>
+-
+-static u8 pdcadma_proc;
+-
+-static int pdcadma_get_info(char *, char **, off_t, int);
+-
+-static ide_pci_host_proc_t pdcadma_procs[] __initdata = {
+-	{
+-		.name		= "pdcadma",
+-		.set		= 1,
+-		.get_info	= pdcadma_get_info,
+-		.parent		= NULL,
+-	},
+-};
+-#endif  /* defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) */
+-
+-static void init_setup_pdcadma(struct pci_dev *, ide_pci_device_t *);
+-static unsigned int init_chipset_pdcadma(struct pci_dev *, const char *);
+-static void init_hwif_pdcadma(ide_hwif_t *);
+-static void init_dma_pdcadma(ide_hwif_t *, unsigned long);
+-
+-static ide_pci_device_t pdcadma_chipsets[] __devinitdata = {
+-	{	/* 0 */
+-		.vendor		= PCI_VENDOR_ID_PDC,
+-		.device		= PCI_DEVICE_ID_PDC_1841,
+-		.name		= "PDCADMA",
+-		.init_setup	= init_setup_pdcadma,
+-		.init_chipset	= init_chipset_pdcadma,
+-		.init_iops	= NULL,
+-		.init_hwif	= init_hwif_pdcadma,
+-		.init_dma	= init_dma_pdcadma,
+-		.channels	= 2,
+-		.autodma	= NODMA,
+-		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+-		.bootable	= OFF_BOARD,
+-		.extra		= 0,
+-	},{
+-		.vendor		= 0,
+-		.device		= 0,
+-		.channels	= 0,
+-		.bootable	= EOL,
+-	}
+-};
+-
+-#endif /* PDC_ADMA_H */
+--- linux-2.6.0-test6/drivers/ide/pci/piix.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/piix.c	2003-10-05 00:33:24.000000000 -0700
+@@ -709,21 +709,6 @@ static void __init init_hwif_piix (ide_h
+ 	hwif->drives[0].autodma = hwif->autodma;
+ }
+ 
+-/**
+- *	init_dma_piix		-	set up the PIIX DMA
+- *	@hwif: IDE interface
+- *	@dmabase: DMA PCI base
+- *
+- *	Set up the DMA on the PIIX controller, providing a DMA base is
+- *	available. The PIIX follows the normal specs so we do nothing
+- *	magical here.
+- */
+-
+-static void __init init_dma_piix (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ /**
+--- linux-2.6.0-test6/drivers/ide/pci/piix.h	2003-06-14 12:18:00.000000000 -0700
++++ 25/drivers/ide/pci/piix.h	2003-10-05 00:33:24.000000000 -0700
+@@ -30,8 +30,6 @@ static ide_pci_host_proc_t piix_procs[] 
+ static void init_setup_piix(struct pci_dev *, ide_pci_device_t *);
+ static unsigned int __devinit init_chipset_piix(struct pci_dev *, const char *);
+ static void init_hwif_piix(ide_hwif_t *);
+-static void init_dma_piix(ide_hwif_t *, unsigned long);
+-
+ 
+ /*
+  *	Table of the various PIIX capability blocks
+@@ -47,7 +45,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -61,7 +58,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -75,7 +71,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= NULL,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= NULL,
+ 		.channels	= 2,
+ 		.autodma	= NODMA,
+ 		.enablebits	= {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
+@@ -89,7 +84,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -103,7 +97,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -117,7 +110,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -131,7 +123,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -145,7 +136,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -159,7 +149,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -173,7 +162,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -187,7 +175,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -201,7 +188,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -215,7 +201,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -229,7 +214,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -243,7 +227,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -257,7 +240,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -271,7 +253,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -285,7 +266,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+@@ -299,7 +279,6 @@ static ide_pci_device_t piix_pci_info[] 
+ 		.init_chipset	= init_chipset_piix,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_piix,
+-		.init_dma	= init_dma_piix,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+--- linux-2.6.0-test6/drivers/ide/pci/sc1200.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/sc1200.c	2003-10-05 00:33:24.000000000 -0700
+@@ -396,44 +396,44 @@ typedef struct sc1200_saved_state_s {
+ 	__u32		regs[4];
+ } sc1200_saved_state_t;
+ 
+-static int sc1200_save_state (struct pci_dev *dev, u32 state)
++
++static int sc1200_suspend (struct pci_dev *dev, u32 state)
+ {
+ 	ide_hwif_t		*hwif = NULL;
+ 
+-printk("SC1200: save_state(%u)\n", state);
+-	if (state != 0)
+-		return 0;	// we only save state when going from full power to less
+-	//
+-	// Loop over all interfaces that are part of this PCI device:
+-	//
+-	while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
+-		sc1200_saved_state_t	*ss;
+-		unsigned int		basereg, r;
+-		//
+-		// allocate a permanent save area, if not already allocated
+-		//
+-		ss = (sc1200_saved_state_t *)hwif->config_data;
+-		if (ss == NULL) {
+-			ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
+-			if (ss == NULL)
+-				return -ENOMEM;
+-			(sc1200_saved_state_t *)hwif->config_data = ss;
+-		}
+-		ss = (sc1200_saved_state_t *)hwif->config_data;
++	printk("SC1200: suspend(%u)\n", state);
++
++	if (state == 0) {
++		// we only save state when going from full power to less
++
+ 		//
+-		// Save timing registers:  this may be unnecessary if BIOS also does it
++		// Loop over all interfaces that are part of this PCI device:
+ 		//
+-		basereg = hwif->channel ? 0x50 : 0x40;
+-		for (r = 0; r < 4; ++r) {
+-			pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
++		while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
++			sc1200_saved_state_t	*ss;
++			unsigned int		basereg, r;
++			//
++			// allocate a permanent save area, if not already allocated
++			//
++			ss = (sc1200_saved_state_t *)hwif->config_data;
++			if (ss == NULL) {
++				ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
++				if (ss == NULL)
++					return -ENOMEM;
++				(sc1200_saved_state_t *)hwif->config_data = ss;
++			}
++			ss = (sc1200_saved_state_t *)hwif->config_data;
++			//
++			// Save timing registers:  this may be unnecessary if 
++			// BIOS also does it
++			//
++			basereg = hwif->channel ? 0x50 : 0x40;
++			for (r = 0; r < 4; ++r) {
++				pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
++			}
+ 		}
+ 	}
+-	return 0;
+-}
+ 
+-static int sc1200_suspend (struct pci_dev *dev, u32 state)
+-{
+-	printk("SC1200: suspend(%u)\n", state);
+ 	/* You don't need to iterate over disks -- sysfs should have done that for you already */ 
+ 
+ 	pci_disable_device(dev);
+@@ -545,11 +545,6 @@ static void __init init_hwif_sc1200 (ide
+         hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-static void __init init_dma_sc1200 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ 
+@@ -572,7 +567,6 @@ static struct pci_driver driver = {
+ 	.name		= "SC1200 IDE",
+ 	.id_table	= sc1200_pci_tbl,
+ 	.probe		= sc1200_init_one,
+-	.save_state	= sc1200_save_state,
+ 	.suspend	= sc1200_suspend,
+ 	.resume		= sc1200_resume,
+ };
+--- linux-2.6.0-test6/drivers/ide/pci/sc1200.h	2003-06-14 12:18:05.000000000 -0700
++++ 25/drivers/ide/pci/sc1200.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@ static ide_pci_host_proc_t sc1200_procs[
+ 
+ static unsigned int init_chipset_sc1200(struct pci_dev *, const char *);
+ static void init_hwif_sc1200(ide_hwif_t *);
+-static void init_dma_sc1200(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t sc1200_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -37,7 +36,6 @@ static ide_pci_device_t sc1200_chipsets[
+ 		.init_chipset	= init_chipset_sc1200,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_sc1200,
+-		.init_dma	= init_dma_sc1200,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/ide/pci/sgiioc4.c	2003-10-05 00:36:28.000000000 -0700
+@@ -0,0 +1,1053 @@
++/*
++ * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License
++ * as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it would be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ *
++ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
++ * Mountain View, CA  94043, or:
++ *
++ * http://www.sgi.com
++ *
++ * For further information regarding this notice, see:
++ *
++ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/hdreg.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/timer.h>
++#include <linux/mm.h>
++#include <linux/ioport.h>
++#include <linux/blkdev.h>
++#include <asm/io.h>
++
++#define IDE_ARCH_ACK_INTR	1
++#include <linux/ide.h>
++
++/* IOC4 Specific Definitions */
++#define IOC4_CMD_OFFSET		0x100
++#define IOC4_CTRL_OFFSET	0x120
++#define IOC4_DMA_OFFSET		0x140
++#define IOC4_INTR_OFFSET	0x0
++
++#define IOC4_TIMING		0x00
++#define IOC4_DMA_PTR_L		0x01
++#define IOC4_DMA_PTR_H		0x02
++#define IOC4_DMA_ADDR_L		0x03
++#define IOC4_DMA_ADDR_H		0x04
++#define IOC4_BC_DEV		0x05
++#define IOC4_BC_MEM		0x06
++#define	IOC4_DMA_CTRL		0x07
++#define	IOC4_DMA_END_ADDR	0x08
++
++/* Bits in the IOC4 Control/Status Register */
++#define	IOC4_S_DMA_START	0x01
++#define	IOC4_S_DMA_STOP		0x02
++#define	IOC4_S_DMA_DIR		0x04
++#define	IOC4_S_DMA_ACTIVE	0x08
++#define	IOC4_S_DMA_ERROR	0x10
++#define	IOC4_ATA_MEMERR		0x02
++
++/* Read/Write Directions */
++#define	IOC4_DMA_WRITE		0x04
++#define	IOC4_DMA_READ		0x00
++
++/* Interrupt Register Offsets */
++#define IOC4_INTR_REG		0x03
++#define	IOC4_INTR_SET		0x05
++#define	IOC4_INTR_CLEAR		0x07
++
++#define IOC4_IDE_CACHELINE_SIZE	128
++#define IOC4_CMD_CTL_BLK_SIZE	0x20
++#define IOC4_SUPPORTED_FIRMWARE_REV 46
++
++/* Weeds out non-IDE interrupts to the IOC4 */
++#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
++
++#define SGIIOC4_MAX_DEVS	32
++
++#if  defined(CONFIG_PROC_FS)
++#include <linux/stat.h>
++#include <linux/proc_fs.h>
++
++static u8 sgiioc4_proc;
++
++static struct pci_dev *sgiioc4_devs[SGIIOC4_MAX_DEVS];
++static int sgiioc4_get_info(char *, char **, off_t, int);
++
++static ide_pci_host_proc_t sgiioc4_procs[] __initdata = {
++	{
++	 .name = "sgiioc4",
++	 .set = 1,
++	 .get_info = sgiioc4_get_info,
++	 .parent = NULL,
++	 }
++};
++#endif
++
++typedef struct {
++	u32 timing_reg0;
++	u32 timing_reg1;
++	u32 low_mem_ptr;
++	u32 high_mem_ptr;
++	u32 low_mem_addr;
++	u32 high_mem_addr;
++	u32 dev_byte_count;
++	u32 mem_byte_count;
++	u32 status;
++} ioc4_dma_regs_t;
++
++/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
++/* IOC4 has only 1 IDE channel */
++#define IOC4_PRD_BYTES       16
++#define IOC4_PRD_ENTRIES     (PAGE_SIZE /(4*IOC4_PRD_BYTES))
++
++typedef enum pciio_endian_e {
++	PCIDMA_ENDIAN_BIG,
++	PCIDMA_ENDIAN_LITTLE
++} pciio_endian_t;
++
++static void sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
++				    unsigned long ctrl_port,
++				    unsigned long irq_port);
++static void sgiioc4_ide_setup_pci_device(struct pci_dev *dev,
++					 ide_pci_device_t * d);
++static void sgiioc4_resetproc(ide_drive_t * drive);
++static void sgiioc4_maskproc(ide_drive_t * drive, int mask);
++static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive);
++static void __init ide_init_sgiioc4(ide_hwif_t * hwif);
++static void __init ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base);
++static int sgiioc4_checkirq(ide_hwif_t * hwif);
++static int sgiioc4_clearirq(ide_drive_t * drive);
++static int sgiioc4_get_info(char *buffer, char **addr, off_t offset, int count);
++static int sgiioc4_ide_dma_read(ide_drive_t * drive);
++static int sgiioc4_ide_dma_write(ide_drive_t * drive);
++static int sgiioc4_ide_dma_begin(ide_drive_t * drive);
++static int sgiioc4_ide_dma_end(ide_drive_t * drive);
++static int sgiioc4_ide_dma_check(ide_drive_t * drive);
++static int sgiioc4_ide_dma_on(ide_drive_t * drive);
++static int sgiioc4_ide_dma_off(ide_drive_t * drive);
++static int sgiioc4_ide_dma_off_quietly(ide_drive_t * drive);
++static int sgiioc4_ide_dma_test_irq(ide_drive_t * drive);
++static int sgiioc4_ide_dma_host_on(ide_drive_t * drive);
++static int sgiioc4_ide_dma_host_off(ide_drive_t * drive);
++static int sgiioc4_ide_dma_count(ide_drive_t * drive);
++static int sgiioc4_ide_dma_verbose(ide_drive_t * drive);
++static int sgiioc4_ide_dma_lostirq(ide_drive_t * drive);
++static int sgiioc4_ide_dma_timeout(ide_drive_t * drive);
++static int sgiioc4_ide_build_sglist(ide_drive_t * drive, struct request *rq);
++static int sgiioc4_ide_raw_build_sglist(ide_drive_t * drive,
++					struct request *rq);
++static u8 sgiioc4_INB(unsigned long port);
++static inline void xide_delay(long ticks);
++static unsigned int sgiioc4_build_dma_table(ide_drive_t * drive,
++					    struct request *rq, int ddir);
++static unsigned int __init pci_init_sgiioc4(struct pci_dev *dev,
++					    ide_pci_device_t * d);
++
++static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
++	{
++	 /* Channel 0 */
++	 .vendor = PCI_VENDOR_ID_SGI,
++	 .device = PCI_DEVICE_ID_SGI_IOC4,
++	 .name = "SGIIOC4",
++	 .init_chipset = NULL,
++	 .init_iops = NULL,
++	 .init_hwif = ide_init_sgiioc4,
++	 .init_dma = ide_dma_sgiioc4,
++	 .channels = 1,
++	 .autodma = AUTODMA,
++	 .enablebits = {{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}},
++	 .bootable = ON_BOARD,
++	 .extra = 0,
++	 }
++};
++
++#ifdef CONFIG_PROC_FS
++static u8 sgiioc4_proc;
++#endif				/* CONFIG_PROC_FS */
++
++static int n_sgiioc4_devs;
++
++static inline void
++xide_delay(long ticks)
++{
++	if (!ticks)
++		return;
++
++	current->state = TASK_UNINTERRUPTIBLE;
++	schedule_timeout(ticks);
++}
++static void __init
++sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
++{
++	unsigned long base = 0, ctl = 0, dma_base = 0, irqport = 0;
++	ide_hwif_t *hwif = NULL;
++	int h = 0;
++
++	/*  Get the CmdBlk and CtrlBlk Base Registers */
++	base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
++	ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET;
++	irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET;
++	dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
++
++	if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) {
++		printk(KERN_ERR
++			"%s : %s -- Warning, Port Addresses "
++			"0x%p to 0x%p ALREADY in use\n",
++		       __FUNCTION__, hwif->name, (void *) base,
++		       (void *) base + IOC4_CMD_CTL_BLK_SIZE);
++	}
++
++	for (h = 0; h < MAX_HWIFS; ++h) {
++		hwif = &ide_hwifs[h];
++		/* Find an empty HWIF */
++		if (hwif->chipset == ide_unknown)
++			break;
++	}
++
++	if (hwif->io_ports[IDE_DATA_OFFSET] != base) {
++		/* Initialize the IO registers */
++		sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport);
++		memcpy(hwif->io_ports, hwif->hw.io_ports,
++		       sizeof (hwif->io_ports));
++		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
++	}
++
++	hwif->irq = dev->irq;
++	hwif->chipset = ide_pci;
++	hwif->pci_dev = dev;
++	hwif->channel = 0;	/* Single Channel chip */
++	hwif->cds = (struct ide_pci_device_s *) d;
++	hwif->hw.ack_intr = &sgiioc4_checkirq;	/* MultiFunction Chip */
++	hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
++
++	/* Initializing chipset IRQ Registers */
++	hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
++
++	(void) ide_init_sgiioc4(hwif);
++
++	if (dma_base)
++		ide_dma_sgiioc4(hwif, dma_base);
++	else
++		printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
++		       hwif->name, d->name);
++
++	probe_hwif_init(hwif);
++}
++
++/* This ensures that we can build this for generic kernels without
++ * having all the SN2 code sync'd and merged.
++ */
++
++pciio_endian_t __attribute__ ((weak)) snia_pciio_endian_set(struct pci_dev
++					    *pci_dev, pciio_endian_t device_end,
++					    pciio_endian_t desired_end);
++
++static unsigned int __init
++pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
++{
++	if (pci_enable_device(dev)) {
++		printk(KERN_INFO
++		       "Failed to enable device %s at slot %s\n",
++		       d->name, dev->slot_name);
++		return 1;
++	}
++	pci_set_master(dev);
++
++	/* Enable Byte Swapping in the PIC... */
++	if (snia_pciio_endian_set) {
++		snia_pciio_endian_set(dev, PCIDMA_ENDIAN_LITTLE,
++				      PCIDMA_ENDIAN_BIG);
++	} else {
++		printk(KERN_INFO
++		       "Failed to set endianness for device %s at slot %s\n",
++		       d->name, dev->slot_name);
++		return 1;
++	}
++
++#ifdef CONFIG_PROC_FS
++	sgiioc4_devs[n_sgiioc4_devs++] = dev;
++	if (!sgiioc4_proc) {
++		sgiioc4_proc = 1;
++		ide_pci_register_host_proc(&sgiioc4_procs[0]);
++	}
++#endif
++	sgiioc4_ide_setup_pci_device(dev, d);
++
++	return 0;
++}
++
++static void
++sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
++			unsigned long ctrl_port, unsigned long irq_port)
++{
++	unsigned long reg = data_port;
++	int i;
++
++	/* Registers are word (32 bit) aligned */
++	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
++		hw->io_ports[i] = reg + i * 4;
++
++	if (ctrl_port)
++		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
++
++	if (irq_port)
++		hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
++}
++
++static void
++sgiioc4_resetproc(ide_drive_t * drive)
++{
++	sgiioc4_ide_dma_end(drive);
++	sgiioc4_clearirq(drive);
++}
++
++static void
++sgiioc4_maskproc(ide_drive_t * drive, int mask)
++{
++	ide_hwif_t *hwif = HWIF(drive);
++	hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
++		   IDE_CONTROL_REG);
++}
++
++static void __init
++ide_init_sgiioc4(ide_hwif_t * hwif)
++{
++	hwif->mmio = 2;
++	hwif->autodma = 1;
++	hwif->atapi_dma = 1;
++	hwif->ultra_mask = 0x0;	/* Disable Ultra DMA */
++	hwif->mwdma_mask = 0x2;	/* Multimode-2 DMA  */
++	hwif->swdma_mask = 0x2;
++	hwif->identify = NULL;
++	hwif->tuneproc = NULL;	/* Sets timing for PIO mode */
++	hwif->speedproc = NULL;	/* Sets timing for DMA &/or PIO modes */
++	hwif->selectproc = NULL;/* Use the default routine to select drive */
++	hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
++	hwif->pre_reset = NULL;	/* No HBA specific pre_set needed */
++	hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
++						clear interrupts */
++	hwif->intrproc = NULL;	/* Enable or Disable interrupt from drive */
++	hwif->maskproc = &sgiioc4_maskproc;	/* Mask on/off NIEN register */
++	hwif->quirkproc = NULL;
++	hwif->busproc = NULL;
++
++	hwif->ide_dma_read = &sgiioc4_ide_dma_read;
++	hwif->ide_dma_write = &sgiioc4_ide_dma_write;
++	hwif->ide_dma_begin = &sgiioc4_ide_dma_begin;
++	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
++	hwif->ide_dma_check = &sgiioc4_ide_dma_check;
++	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
++	hwif->ide_dma_off = &sgiioc4_ide_dma_off;
++	hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
++	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
++	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
++	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
++	hwif->ide_dma_bad_drive = &__ide_dma_bad_drive;
++	hwif->ide_dma_good_drive = &__ide_dma_good_drive;
++	hwif->ide_dma_count = &sgiioc4_ide_dma_count;
++	hwif->ide_dma_verbose = &sgiioc4_ide_dma_verbose;
++	hwif->ide_dma_retune = &__ide_dma_retune;
++	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
++	hwif->ide_dma_timeout = &sgiioc4_ide_dma_timeout;
++	hwif->INB = &sgiioc4_INB;
++}
++
++static int
++sgiioc4_ide_dma_read(ide_drive_t * drive)
++{
++	struct request *rq = HWGROUP(drive)->rq;
++	unsigned int count = 0;
++
++	if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_FROMDEVICE))) {
++		/* try PIO instead of DMA */
++		return 1;
++	}
++	/* Writes FROM the IOC4 TO Main Memory */
++	sgiioc4_configure_for_dma(IOC4_DMA_WRITE, drive);
++
++	return 0;
++}
++
++static int
++sgiioc4_ide_dma_write(ide_drive_t * drive)
++{
++	struct request *rq = HWGROUP(drive)->rq;
++	unsigned int count = 0;
++
++	if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_TODEVICE))) {
++		/* try PIO instead of DMA */
++		return 1;
++	}
++
++	sgiioc4_configure_for_dma(IOC4_DMA_READ, drive);
++	/* Writes TO the IOC4 FROM Main Memory */
++
++	return 0;
++}
++
++static int
++sgiioc4_ide_dma_begin(ide_drive_t * drive)
++{
++	ide_hwif_t *hwif = HWIF(drive);
++	unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
++	unsigned int temp_reg = reg | IOC4_S_DMA_START;
++
++	hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
++
++	return 0;
++}
++
++/* Stops the IOC4 DMA Engine */
++static int
++sgiioc4_ide_dma_end(ide_drive_t * drive)
++{
++	u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
++	ide_hwif_t *hwif = HWIF(drive);
++	uint64_t dma_base = hwif->dma_base;
++	int dma_stat = 0, count;
++	unsigned long *ending_dma = (unsigned long *) hwif->dma_base2;
++
++	hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++
++	count = 0;
++	do {
++		xide_delay(count);
++		ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++		count += 10;
++	} while ((ioc4_dma & IOC4_S_DMA_STOP) && (count < 100));
++
++	if (ioc4_dma & IOC4_S_DMA_STOP) {
++		printk(KERN_ERR
++		       "%s(%s): IOC4 DMA STOP bit is still 1 :"
++		       "ioc4_dma_reg 0x%x\n",
++		       __FUNCTION__, drive->name, ioc4_dma);
++		dma_stat = 1;
++	}
++
++	if (ending_dma) {
++		do {
++			for (num = 0; num < 16; num++) {
++				if (ending_dma[num] & (~0ul)) {
++					valid = 1;
++					break;
++				}
++			}
++			xide_delay(cnt);
++		} while ((cnt++ < 100) && (!valid));
++	}
++
++	if (!valid)
++		printk(KERN_INFO "%s(%s) : Stale DMA Data in Memory\n",
++		       __FUNCTION__, drive->name);
++
++	bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4);
++	bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4);
++
++	if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
++		if (bc_dev > bc_mem + 8) {
++			printk(KERN_ERR
++			       "%s(%s): WARNING!! byte_count_dev %d "
++			       "!= byte_count_mem %d\n",
++			       __FUNCTION__, drive->name, bc_dev, bc_mem);
++		}
++	}
++
++	drive->waiting_for_dma = 0;
++	ide_destroy_dmatable(drive);
++
++	return dma_stat;
++}
++
++static int
++sgiioc4_ide_dma_check(ide_drive_t * drive)
++{
++	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
++		printk(KERN_INFO
++		       "Couldnot set %s in Multimode-2 DMA mode | "
++			   "Drive %s using PIO instead\n",
++		       drive->name, drive->name);
++		drive->using_dma = 0;
++	} else
++		drive->using_dma = 1;
++
++	return 0;
++}
++
++static int
++sgiioc4_ide_dma_on(ide_drive_t * drive)
++{
++	drive->using_dma = 1;
++
++	return HWIF(drive)->ide_dma_host_on(drive);
++}
++
++static int
++sgiioc4_ide_dma_off(ide_drive_t * drive)
++{
++	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
++
++	return HWIF(drive)->ide_dma_off_quietly(drive);
++}
++
++static int
++sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
++{
++	drive->using_dma = 0;
++
++	return HWIF(drive)->ide_dma_host_off(drive);
++}
++
++/* returns 1 if dma irq issued, 0 otherwise */
++static int
++sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
++{
++	return sgiioc4_checkirq(HWIF(drive));
++}
++
++static int
++sgiioc4_ide_dma_host_on(ide_drive_t * drive)
++{
++	if (drive->using_dma)
++		return 0;
++
++	return 1;
++}
++
++static int
++sgiioc4_ide_dma_host_off(ide_drive_t * drive)
++{
++	sgiioc4_clearirq(drive);
++
++	return 0;
++}
++
++static int
++sgiioc4_ide_dma_count(ide_drive_t * drive)
++{
++	return HWIF(drive)->ide_dma_begin(drive);
++}
++
++static int
++sgiioc4_ide_dma_verbose(ide_drive_t * drive)
++{
++	if (drive->using_dma == 1)
++		printk(", UDMA(16)");
++	else
++		printk(", PIO");
++
++	return 1;
++}
++
++static int
++sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
++{
++	HWIF(drive)->resetproc(drive);
++
++	return __ide_dma_lostirq(drive);
++}
++
++static int
++sgiioc4_ide_dma_timeout(ide_drive_t * drive)
++{
++	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
++	if (HWIF(drive)->ide_dma_test_irq(drive))
++		return 0;
++
++	return HWIF(drive)->ide_dma_end(drive);
++}
++
++static u8
++sgiioc4_INB(unsigned long port)
++{
++	u8 reg = (u8) inb(port);
++
++	if ((port & 0xFFF) == 0x11C) {	/* Status register of IOC4 */
++		if (reg & 0x51) {	/* Not busy...check for interrupt */
++			unsigned long other_ir = port - 0x110;
++			unsigned int intr_reg = (u32) inl(other_ir);
++
++			/* Clear the Interrupt, Error bits on the IOC4 */
++			if (intr_reg & 0x03) {
++				outl(0x03, other_ir);
++				intr_reg = (u32) inl(other_ir);
++			}
++		}
++	}
++
++	return reg;
++}
++
++/* Creates a dma map for the scatter-gather list entries */
++static void __init
++ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
++{
++	int num_ports = sizeof (ioc4_dma_regs_t);
++
++	printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
++	       dma_base, dma_base + num_ports - 1);
++
++	if (!request_region(dma_base, num_ports, hwif->name)) {
++		printk(KERN_ERR
++		       "%s(%s) -- WARNING, Addresses 0x%p to 0x%p "
++		       "ALREADY in use\n",
++		       __FUNCTION__, hwif->name, (void *) dma_base,
++		       (void *) dma_base + num_ports - 1);
++	}
++
++	hwif->dma_base = dma_base;
++	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
++					  IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
++					  &hwif->dmatable_dma);
++
++	if (!hwif->dmatable_cpu)
++		goto dma_alloc_failure;
++
++	hwif->sg_table =
++	    kmalloc(sizeof (struct scatterlist) * IOC4_PRD_ENTRIES, GFP_KERNEL);
++
++	if (!hwif->sg_table) {
++		pci_free_consistent(hwif->pci_dev,
++				    IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
++				    hwif->dmatable_cpu, hwif->dmatable_dma);
++		goto dma_alloc_failure;
++	}
++
++	hwif->dma_base2 = (unsigned long)
++		pci_alloc_consistent(hwif->pci_dev,
++				     IOC4_IDE_CACHELINE_SIZE,
++				     (dma_addr_t *) &(hwif->dma_status));
++
++	if (!hwif->dma_base2) {
++		pci_free_consistent(hwif->pci_dev,
++				    IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
++				    hwif->dmatable_cpu, hwif->dmatable_dma);
++		kfree(hwif->sg_table);
++		goto dma_alloc_failure;
++	}
++
++	return;
++
++      dma_alloc_failure:
++	printk(KERN_INFO
++	       "%s() -- Error! Unable to allocate DMA Maps for drive %s\n",
++	       __FUNCTION__, hwif->name);
++	printk(KERN_INFO
++	       "Changing from DMA to PIO mode for Drive %s\n", hwif->name);
++
++	/* Disable DMA because we couldnot allocate any DMA maps */
++	hwif->autodma = 0;
++	hwif->atapi_dma = 0;
++}
++
++/* Initializes the IOC4 DMA Engine */
++static void
++sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
++{
++	u32 ioc4_dma;
++	int count;
++	ide_hwif_t *hwif = HWIF(drive);
++	uint64_t dma_base = hwif->dma_base;
++	uint32_t dma_addr, ending_dma_addr;
++
++	ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++
++	if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
++		printk(KERN_WARNING
++			"%s(%s):Warning!! DMA from previous transfer was still active\n",
++		       __FUNCTION__, drive->name);
++		hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++		count = 0;
++		do {
++			xide_delay(count);
++			ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++			count += 10;
++		} while ((ioc4_dma & IOC4_S_DMA_STOP) && (count < 100));
++
++		if (ioc4_dma & IOC4_S_DMA_STOP)
++			printk(KERN_ERR
++			       "%s(%s) : IOC4 Dma STOP bit is still 1\n",
++			       __FUNCTION__, drive->name);
++	}
++
++	ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++	if (ioc4_dma & IOC4_S_DMA_ERROR) {
++		printk(KERN_WARNING
++		       "%s(%s) : Warning!! - DMA Error during Previous"
++		       " transfer | status 0x%x\n",
++		       __FUNCTION__, drive->name, ioc4_dma);
++		hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++		count = 0;
++		do {
++			ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++			xide_delay(count);
++			count += 10;
++		} while ((ioc4_dma & IOC4_S_DMA_STOP) && (count < 100));
++
++		if (ioc4_dma & IOC4_S_DMA_STOP)
++			printk(KERN_ERR
++			       "%s(%s) : IOC4 DMA STOP bit is still 1\n",
++			       __FUNCTION__, drive->name);
++	}
++
++	/* Address of the Scatter Gather List */
++	dma_addr = cpu_to_le32(hwif->dmatable_dma);
++	hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
++
++	/* Address of the Ending DMA */
++	memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE);
++	ending_dma_addr = cpu_to_le32(hwif->dma_status);
++	hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
++
++	hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4);
++	drive->waiting_for_dma = 1;
++}
++
++/* IOC4 Scatter Gather list Format 					 */
++/* 128 Bit entries to support 64 bit addresses in the future		 */
++/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format	 */
++/* --------------------------------------------------------------------- */
++/* | Upper 32 bits - Zero           |	 	Lower 32 bits- address | */
++/* --------------------------------------------------------------------- */
++/* | Upper 32 bits - Zero	    |EOL| 15 unused     | 16 Bit Length| */
++/* --------------------------------------------------------------------- */
++/* Creates the scatter gather list, DMA Table */
++static unsigned int
++sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
++{
++	ide_hwif_t *hwif = HWIF(drive);
++	unsigned int *table = hwif->dmatable_cpu;
++	unsigned int count = 0, i = 1;
++	struct scatterlist *sg;
++
++	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
++		hwif->sg_nents = i = sgiioc4_ide_raw_build_sglist(drive, rq);
++	else
++		hwif->sg_nents = i = sgiioc4_ide_build_sglist(drive, rq);
++
++	if (!i)
++		return 0;	/* sglist of length Zero */
++
++	sg = hwif->sg_table;
++	while (i && sg_dma_len(sg)) {
++		dma_addr_t cur_addr;
++		int cur_len;
++		cur_addr = sg_dma_address(sg);
++		cur_len = sg_dma_len(sg);
++
++		while (cur_len) {
++			if (count++ >= IOC4_PRD_ENTRIES) {
++				printk(KERN_WARNING
++				       "%s: DMA table too small\n",
++				       drive->name);
++				goto use_pio_instead;
++			} else {
++				uint32_t xcount, bcount =
++				    0x10000 - (cur_addr & 0xffff);
++
++				if (bcount > cur_len)
++					bcount = cur_len;
++
++				/* put the addr, length in
++				 * the IOC4 dma-table format */
++				*table = 0x0;
++				table++;
++				*table = cpu_to_be32(cur_addr);
++				table++;
++				*table = 0x0;
++				table++;
++
++				xcount = bcount & 0xffff;
++				*table = cpu_to_be32(xcount);
++				table++;
++
++				cur_addr += bcount;
++				cur_len -= bcount;
++			}
++		}
++
++		sg++;
++		i--;
++	}
++
++	if (count) {
++		table--;
++		*table |= cpu_to_be32(0x80000000);
++		return count;
++	}
++
++      use_pio_instead:
++	pci_unmap_sg(hwif->pci_dev, hwif->sg_table, hwif->sg_nents,
++		     hwif->sg_dma_direction);
++	hwif->sg_dma_active = 0;
++
++	return 0;		/* revert to PIO for this request */
++}
++
++static int
++sgiioc4_checkirq(ide_hwif_t * hwif)
++{
++	uint8_t intr_reg =
++	    hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4);
++
++	if (intr_reg & 0x03)
++		return 1;
++
++	return 0;
++}
++
++static int
++sgiioc4_clearirq(ide_drive_t * drive)
++{
++	u32 intr_reg;
++	ide_hwif_t *hwif = HWIF(drive);
++	unsigned long other_ir =
++	    hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
++
++	/* Code to check for PCI error conditions */
++	intr_reg = hwif->INL(other_ir);
++	if (intr_reg & 0x03) {
++		/* Valid IOC4-IDE interrupt */
++		u8 stat = hwif->INB(IDE_STATUS_REG);
++		int count = 0;
++		do {
++			xide_delay(count);
++			stat = hwif->INB(IDE_STATUS_REG);
++			/* Removes Interrupt from IDE Device */
++		} while ((stat & 0x80) && (count++ < 1024));
++
++		if (intr_reg & 0x02) {
++			/* Error when transferring DMA data on PCI bus */
++			uint32_t pci_err_addr_low, pci_err_addr_high,
++			    pci_stat_cmd_reg;
++
++			pci_err_addr_low =
++				hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]);
++			pci_err_addr_high =
++				hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4);
++			pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
++					      &pci_stat_cmd_reg);
++			printk(KERN_ERR
++			       "%s(%s) : PCI Bus Error when doing DMA:"
++				   " status-cmd reg is 0x%x\n",
++			       __FUNCTION__, drive->name, pci_stat_cmd_reg);
++			printk(KERN_ERR
++			       "%s(%s) : PCI Error Address is 0x%x%x\n",
++			       __FUNCTION__, drive->name,
++			       pci_err_addr_high, pci_err_addr_low);
++			/* Clear the PCI Error indicator */
++			pci_write_config_dword(hwif->pci_dev, PCI_COMMAND,
++					       0x00000146);
++		}
++
++		/* Clear the Interrupt, Error bits on the IOC4 */
++		hwif->OUTL(0x03, other_ir);
++
++		intr_reg = hwif->INL(other_ir);
++	}
++
++	return intr_reg;
++}
++
++/**
++ * 	"Copied from drivers/ide/ide-dma.c"
++ *	sgiioc4_ide_build_sglist - map IDE scatter gather for DMA I/O
++ *	@hwif: the interface to build the DMA table for
++ *	@rq: the request holding the sg list
++ *	@ddir: data direction
++ *
++ *	Perform the PCI mapping magic neccessary to access the source
++ *	or target buffers of a request via PCI DMA. The lower layers
++ *	of the kernel provide the neccessary cache management so that
++ *	we can operate in a portable fashion.
++ *
++ *	This code is identical to ide_build_sglist in ide-dma.c
++ *	however that is not exported.
++ */
++
++static int
++sgiioc4_ide_build_sglist(ide_drive_t * drive, struct request *rq)
++{
++	ide_hwif_t *hwif = HWIF(drive);
++	struct scatterlist *sg = hwif->sg_table;
++	int nents;
++
++	if (hwif->sg_dma_active)
++		BUG();
++
++	nents = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
++
++	if (rq_data_dir(rq) == READ)
++		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
++	else
++		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
++
++	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
++}
++
++/**
++ * 	Copied from drivers/ide/ide-dma.c
++ *	sgiioc4_ide_raw_build_sglist	-	map IDE scatter gather for DMA
++ *	@hwif: the interface to build the DMA table for
++ *	@rq: the request holding the sg list
++ *
++ *	Perform the PCI mapping magic neccessary to access the source or
++ *	target buffers of a taskfile request via PCI DMA. The lower layers
++ *	of the  kernel provide the neccessary cache management so that we can
++ *	operate in a portable fashion
++ *
++ *	This code is identical to ide_raw_build_sglist in ide-dma.c
++ *	however that is not exported
++ */
++
++static int
++sgiioc4_ide_raw_build_sglist(ide_drive_t * drive, struct request *rq)
++{
++	ide_hwif_t *hwif = HWIF(drive);
++	struct scatterlist *sg = hwif->sg_table;
++	int nents = 0;
++	ide_task_t *args = rq->special;
++	u8 *virt_addr = rq->buffer;
++	int sector_count = rq->nr_sectors;
++
++	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
++		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
++	else
++		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
++
++#if 1
++	if (sector_count > 256)
++		BUG();
++
++	if (sector_count > 128) {
++#else
++	while (sector_count > 128) {
++#endif
++		memset(&sg[nents], 0, sizeof (*sg));
++		sg[nents].page = virt_to_page(virt_addr);
++		sg[nents].offset = offset_in_page(virt_addr);
++		sg[nents].length = 128 * SECTOR_SIZE;
++		nents++;
++		virt_addr = virt_addr + (128 * SECTOR_SIZE);
++		sector_count -= 128;
++	}
++	memset(&sg[nents], 0, sizeof (*sg));
++	sg[nents].page = virt_to_page(virt_addr);
++	sg[nents].offset = offset_in_page(virt_addr);
++	sg[nents].length = sector_count * SECTOR_SIZE;
++	nents++;
++
++	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
++}
++
++#ifdef CONFIG_PROC_FS
++
++static int
++sgiioc4_get_info(char *buffer, char **addr, off_t offset, int count)
++{
++	char *p = buffer;
++	unsigned int class_rev;
++	int i = 0;
++
++	while (i < n_sgiioc4_devs) {
++		pci_read_config_dword(sgiioc4_devs[i], PCI_CLASS_REVISION, &class_rev);
++		class_rev &= 0xff;
++
++		if (sgiioc4_devs[i]->device == PCI_DEVICE_ID_SGI_IOC4) {
++			p += sprintf(p,
++	"\n\tSGI IOC4 Chipset rev %d.\n\t"
++	"Chipset has 1 IDE channel and supports 2 devices on that channel.\n\t"
++	"Chipset supports DMA in MultiMode-2 data transfer protocol.\n",
++				class_rev);
++			/* Do we need more info. here? */
++		}
++		i++;
++	}
++
++	return p - buffer;
++}
++
++#endif				/* CONFIG_PROC_FS */
++
++static int __devinit
++sgiioc4_init_one(struct pci_dev *dev, const struct pci_device_id *id)
++{
++	unsigned int class_rev;
++	ide_pci_device_t *d = &sgiioc4_chipsets[id->driver_data];
++	if (dev->device != d->device) {
++		printk(KERN_ERR "Error in %s(dev 0x%p | id 0x%p )\n",
++		       __FUNCTION__, (void *) dev, (void *) id);
++		BUG();
++	}
++
++	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
++	class_rev &= 0xff;
++
++	if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
++		printk(KERN_INFO
++		       "Disabling IOC4 IDE Part due to "
++		       "unsupported Firmware Rev (%d)",
++		       class_rev);
++		printk(KERN_INFO
++		       "\nPlease upgrade to Firmware Rev 46 or higher\n");
++		return 0;
++	}
++
++	printk(KERN_INFO "%s: IDE controller at PCI slot %s\n", d->name,
++	       dev->slot_name);
++
++	if (pci_init_sgiioc4(dev, d))
++		return 0;
++
++	MOD_INC_USE_COUNT;
++
++	return 0;
++}
++
++static struct pci_device_id sgiioc4_pci_tbl[] = {
++	{PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
++	 PCI_ANY_ID, 0x0b4000, 0xFFFFFF, 0},
++	{0}
++};
++
++static struct pci_driver driver = {
++	.name = "SGI-IOC4 IDE",
++	.id_table = sgiioc4_pci_tbl,
++	.probe = sgiioc4_init_one,
++};
++
++static int
++sgiioc4_ide_init(void)
++{
++	return ide_pci_register_driver(&driver);
++}
++
++static void
++sgiioc4_ide_exit(void)
++{
++	ide_pci_unregister_driver(&driver);
++}
++
++module_init(sgiioc4_ide_init);
++module_exit(sgiioc4_ide_exit);
++
++MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
++MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/ide/pci/siimage.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/siimage.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1150,20 +1150,6 @@ static void __init init_hwif_siimage (id
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-/**
+- *	init_dma_siimage	-	set up IDE DMA
+- *	@hwif: interface
+- *	@dmabase: DMA base address to use
+- *	
+- *	For the SI chips this requires no special set up so we can just
+- *	let the IDE DMA core do the usual work.
+- */
+- 
+-static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ 
+--- linux-2.6.0-test6/drivers/ide/pci/siimage.h	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/siimage.h	2003-10-05 00:33:24.000000000 -0700
+@@ -44,7 +44,6 @@ static ide_pci_host_proc_t siimage_procs
+ static unsigned int init_chipset_siimage(struct pci_dev *, const char *);
+ static void init_iops_siimage(ide_hwif_t *);
+ static void init_hwif_siimage(ide_hwif_t *);
+-static void init_dma_siimage(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -54,7 +53,6 @@ static ide_pci_device_t siimage_chipsets
+ 		.init_chipset	= init_chipset_siimage,
+ 		.init_iops	= init_iops_siimage,
+ 		.init_hwif	= init_hwif_siimage,
+-		.init_dma	= init_dma_siimage,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -67,7 +65,6 @@ static ide_pci_device_t siimage_chipsets
+ 		.init_chipset	= init_chipset_siimage,
+ 		.init_iops	= init_iops_siimage,
+ 		.init_hwif	= init_hwif_siimage,
+-		.init_dma	= init_dma_siimage,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+@@ -80,7 +77,6 @@ static ide_pci_device_t siimage_chipsets
+ 		.init_chipset	= init_chipset_siimage,
+ 		.init_iops	= init_iops_siimage,
+ 		.init_hwif	= init_hwif_siimage,
+-		.init_dma	= init_dma_siimage,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+--- linux-2.6.0-test6/drivers/ide/pci/sis5513.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/sis5513.c	2003-10-05 00:33:24.000000000 -0700
+@@ -942,11 +942,6 @@ static void __init init_hwif_sis5513 (id
+ 	return;
+ }
+ 
+-static void __init init_dma_sis5513 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ 
+--- linux-2.6.0-test6/drivers/ide/pci/sis5513.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/ide/pci/sis5513.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@ static ide_pci_host_proc_t sis_procs[] _
+ 
+ static unsigned int init_chipset_sis5513(struct pci_dev *, const char *);
+ static void init_hwif_sis5513(ide_hwif_t *);
+-static void init_dma_sis5513(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t sis5513_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -37,7 +36,6 @@ static ide_pci_device_t sis5513_chipsets
+ 		.init_chipset	= init_chipset_sis5513,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_sis5513,
+-		.init_dma	= init_dma_sis5513,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+--- linux-2.6.0-test6/drivers/ide/pci/slc90e66.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/slc90e66.c	2003-10-05 00:33:24.000000000 -0700
+@@ -362,11 +362,6 @@ static void __init init_hwif_slc90e66 (i
+ #endif /* !CONFIG_BLK_DEV_IDEDMA */
+ }
+ 
+-static void __init init_dma_slc90e66 (ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ 
+--- linux-2.6.0-test6/drivers/ide/pci/slc90e66.h	2003-06-14 12:18:05.000000000 -0700
++++ 25/drivers/ide/pci/slc90e66.h	2003-10-05 00:33:24.000000000 -0700
+@@ -29,7 +29,6 @@ static ide_pci_host_proc_t slc90e66_proc
+ 
+ static unsigned int init_chipset_slc90e66(struct pci_dev *, const char *);
+ static void init_hwif_slc90e66(ide_hwif_t *);
+-static void init_dma_slc90e66(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t slc90e66_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -39,7 +38,6 @@ static ide_pci_device_t slc90e66_chipset
+ 		.init_chipset	= init_chipset_slc90e66,
+ 		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_slc90e66,
+-		.init_dma	= init_dma_slc90e66,
+ 		.channels	= 2,
+ 		.autodma	= AUTODMA,
+ 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+--- linux-2.6.0-test6/drivers/ide/pci/via82cxxx.c	2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/ide/pci/via82cxxx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,6 +1,6 @@
+ /*
+  *
+- * Version 3.37
++ * Version 3.38
+  *
+  * VIA IDE driver for Linux. Supported southbridges:
+  *
+@@ -96,7 +96,6 @@ static struct via_isa_bridge {
+ };
+ 
+ static struct via_isa_bridge *via_config;
+-static unsigned char via_enabled;
+ static unsigned int via_80w;
+ static unsigned int via_clock;
+ static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
+@@ -146,7 +145,7 @@ static int via_get_info(char *buffer, ch
+ 	via_print("----------VIA BusMastering IDE Configuration"
+ 		"----------------");
+ 
+-	via_print("Driver Version:                     3.37");
++	via_print("Driver Version:                     3.38");
+ 	via_print("South Bridge:                       VIA %s",
+ 		via_config->name);
+ 
+@@ -370,9 +369,6 @@ static int via_set_drive(ide_drive_t *dr
+ 
+ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
+ {
+-	if (!((via_enabled >> HWIF(drive)->channel) & 1))
+-		return;
+-
+ 	if (pio == 255) {
+ 		via_set_drive(drive,
+ 			ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
+@@ -506,7 +502,6 @@ static unsigned int __init init_chipset_
+ 	 */
+ 
+ 	pci_read_config_byte(dev, VIA_IDE_ENABLE, &v);
+-	via_enabled = ((v & 1) ? 2 : 0) | ((v & 2) ? 1 : 0);
+ 
+ 	/*
+ 	 * Set up FIFO sizes and thresholds.
+@@ -523,9 +518,9 @@ static unsigned int __init init_chipset_
+ 	/* Fix FIFO split between channels */
+ 	if (via_config->flags & VIA_SET_FIFO) {
+ 		t &= (t & 0x9f);
+-		switch (via_enabled) {
+-			case 1: t |= 0x00; break;	/* 16 on primary */
+-			case 2: t |= 0x60; break;	/* 16 on secondary */
++		switch (v & 3) {
++			case 2: t |= 0x00; break;	/* 16 on primary */
++			case 1: t |= 0x60; break;	/* 16 on secondary */
+ 			case 3: t |= 0x20; break;	/* 8 pri 8 sec */
+ 		}
+ 	}
+@@ -603,8 +598,8 @@ static void __init init_hwif_via82cxxx(i
+ 	hwif->mwdma_mask = 0x07;
+ 	hwif->swdma_mask = 0x07;
+ 
+-	if (!(hwif->udma_four))
+-		hwif->udma_four = ((via_enabled & via_80w) >> hwif->channel) & 1;
++	if (!hwif->udma_four)
++		hwif->udma_four = (via_80w >> hwif->channel) & 1;
+ 	hwif->ide_dma_check = &via82cxxx_ide_dma_check;
+ 	if (!noautodma)
+ 		hwif->autodma = 1;
+@@ -612,20 +607,6 @@ static void __init init_hwif_via82cxxx(i
+ 	hwif->drives[1].autodma = hwif->autodma;
+ }
+ 
+-/**
+- *	init_dma_via82cxxx	-	set up for IDE DMA
+- *	@hwif: IDE interface
+- *	@dmabase: DMA base address
+- *
+- *	We allow the BM-DMA driver to only work on enabled interfaces.
+- */
+-
+-static void __init init_dma_via82cxxx(ide_hwif_t *hwif, unsigned long dmabase)
+-{
+-	if ((via_enabled >> hwif->channel) & 1)
+-		ide_setup_dma(hwif, dmabase, 8);
+-}
+-
+ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+ 
+ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+--- linux-2.6.0-test6/drivers/ide/pci/via82cxxx.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/ide/pci/via82cxxx.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@ static ide_pci_host_proc_t via_procs[] _
+ 
+ static unsigned int init_chipset_via82cxxx(struct pci_dev *, const char *);
+ static void init_hwif_via82cxxx(ide_hwif_t *);
+-static void init_dma_via82cxxx(ide_hwif_t *, unsigned long);
+ 
+ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+ 	{	/* 0 */
+@@ -35,9 +34,7 @@ static ide_pci_device_t via82cxxx_chipse
+ 		.device		= PCI_DEVICE_ID_VIA_82C576_1,
+ 		.name		= "VP_IDE",
+ 		.init_chipset	= init_chipset_via82cxxx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_via82cxxx,
+-		.init_dma	= init_dma_via82cxxx,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+@@ -48,9 +45,7 @@ static ide_pci_device_t via82cxxx_chipse
+ 		.device		= PCI_DEVICE_ID_VIA_82C586_1,
+ 		.name		= "VP_IDE",
+ 		.init_chipset	= init_chipset_via82cxxx,
+-		.init_iops	= NULL,
+ 		.init_hwif	= init_hwif_via82cxxx,
+-		.init_dma	= init_dma_via82cxxx,
+ 		.channels	= 2,
+ 		.autodma	= NOAUTODMA,
+ 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+--- linux-2.6.0-test6/drivers/input/input.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/input.c	2003-10-05 00:34:14.000000000 -0700
+@@ -447,9 +447,10 @@ void input_register_device(struct input_
+ 	list_add_tail(&dev->node, &input_dev_list);
+ 
+ 	list_for_each_entry(handler, &input_handler_list, node)
+-		if ((id = input_match_device(handler->id_table, dev)))
+-			if ((handle = handler->connect(handler, dev, id)))
+-				input_link_handle(handle);
++		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
++			if ((id = input_match_device(handler->id_table, dev)))
++				if ((handle = handler->connect(handler, dev, id)))
++					input_link_handle(handle);
+ 
+ #ifdef CONFIG_HOTPLUG
+ 	input_call_hotplug("add", dev);
+@@ -507,9 +508,10 @@ void input_register_handler(struct input
+ 	list_add_tail(&handler->node, &input_handler_list);
+ 	
+ 	list_for_each_entry(dev, &input_dev_list, node)
+-		if ((id = input_match_device(handler->id_table, dev)))
+-			if ((handle = handler->connect(handler, dev, id)))
+-				input_link_handle(handle);
++		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
++			if ((id = input_match_device(handler->id_table, dev)))
++				if ((handle = handler->connect(handler, dev, id)))
++					input_link_handle(handle);
+ 
+ #ifdef CONFIG_PROC_FS
+ 	input_devices_state++;
+--- linux-2.6.0-test6/drivers/input/joydev.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/input/joydev.c	2003-10-05 00:34:14.000000000 -0700
+@@ -380,10 +380,6 @@ static struct input_handle *joydev_conne
+ 	struct joydev *joydev;
+ 	int i, j, t, minor;
+ 
+-	/* Avoid tablets */
+-        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
+-		return NULL;
+-
+ 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
+ 	if (minor == JOYDEV_MINORS) {
+ 		printk(KERN_ERR "joydev: no more free joydev devices\n");
+@@ -464,6 +460,15 @@ static void joydev_disconnect(struct inp
+ 		joydev_free(joydev);
+ }
+ 
++static struct input_device_id joydev_blacklist[] = {
++	{
++		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
++		.evbit = { BIT(EV_KEY) },
++		.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
++	}, 	/* Avoid itouchpads, touchscreens and tablets */
++	{ }, 	/* Terminating entry */
++};
++
+ static struct input_device_id joydev_ids[] = {
+ 	{
+ 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+@@ -493,6 +498,7 @@ static struct input_handler joydev_handl
+ 	.minor =	JOYDEV_MINOR_BASE,
+ 	.name =		"joydev",
+ 	.id_table =	joydev_ids,
++	.blacklist = 	joydev_blacklist,
+ };
+ 
+ static int __init joydev_init(void)
+--- linux-2.6.0-test6/drivers/input/joystick/analog.c	2003-06-16 22:32:21.000000000 -0700
++++ 25/drivers/input/joystick/analog.c	2003-10-05 00:33:24.000000000 -0700
+@@ -159,7 +159,7 @@ static unsigned int get_time_pit(void)
+ #define DELTA(x,y)	((y)-(x))
+ #define TIME_NAME	"TSC"
+ #elif __alpha__
+-#define GET_TIME(x)	do { x = get_cycles(x); } while (0)
++#define GET_TIME(x)	do { x = get_cycles(); } while (0)
+ #define DELTA(x,y)	((y)-(x))
+ #define TIME_NAME	"PCC"
+ #else
+--- linux-2.6.0-test6/drivers/input/keyboard/atkbd.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/keyboard/atkbd.c	2003-10-05 00:36:37.000000000 -0700
+@@ -369,10 +369,11 @@ static int atkbd_command(struct atkbd *a
+ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+ {
+ 	struct atkbd *atkbd = dev->private;
+-	struct { int p; u8 v; } period[] =	
+-		{ {30, 0x00}, {25, 0x02}, {20, 0x04}, {15, 0x08}, {10, 0x0c}, {7, 0x10}, {5, 0x14}, {0, 0x14} };
+-	struct { int d; u8 v; } delay[] =
+-        	{ {1000, 0x60}, {750, 0x40}, {500, 0x20}, {250, 0x00}, {0, 0x00} };
++	const short period[32] =
++		{ 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125,
++		 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
++	const short delay[4] =
++		{ 250, 500, 750, 1000 };
+ 	char param[2];
+ 	int i, j;
+ 
+@@ -406,11 +407,11 @@ static int atkbd_event(struct input_dev 
+ 			if (atkbd_softrepeat) return 0;
+ 
+ 			i = j = 0;
+-			while (period[i].p > dev->rep[REP_PERIOD]) i++;
+-			while (delay[j].d > dev->rep[REP_DELAY]) j++;
+-			dev->rep[REP_PERIOD] = period[i].p;
+-			dev->rep[REP_DELAY] = delay[j].d;
+-			param[0] = period[i].v | delay[j].v;
++			while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++;
++			while (j < 4 && delay[j] < dev->rep[REP_DELAY]) j++;
++			dev->rep[REP_PERIOD] = period[i];
++			dev->rep[REP_DELAY] = delay[j];
++			param[0] = i | (j << 5);
+ 			atkbd_command(atkbd, param, ATKBD_CMD_SETREP);
+ 
+ 			return 0;
+@@ -576,6 +577,7 @@ static void atkbd_disconnect(struct seri
+ 	struct atkbd *atkbd = serio->private;
+ 	input_unregister_device(&atkbd->dev);
+ 	serio_close(serio);
++	serio->private = NULL;
+ 	kfree(atkbd);
+ }
+ 
+@@ -634,6 +636,7 @@ static void atkbd_connect(struct serio *
+ 	serio->private = atkbd;
+ 
+ 	if (serio_open(serio, dev)) {
++		serio->private = NULL;
+ 		kfree(atkbd);
+ 		return;
+ 	}
+@@ -642,6 +645,7 @@ static void atkbd_connect(struct serio *
+ 
+ 		if (atkbd_probe(atkbd)) {
+ 			serio_close(serio);
++			serio->private = NULL;
+ 			kfree(atkbd);
+ 			return;
+ 		}
+--- linux-2.6.0-test6/drivers/input/keyboard/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/keyboard/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -12,10 +12,11 @@ config INPUT_KEYBOARD
+ 	  If unsure, say Y.
+ 
+ config KEYBOARD_ATKBD
+-	tristate "AT keyboard support" if EMBEDDED || !X86 
++	tristate "AT keyboard support" if !PC
+ 	default y
+ 	depends on INPUT && INPUT_KEYBOARD
+-	select SERIO_I8042
++	select SERIO
++	select SERIO_I8042 if PC
+ 	help
+ 	  Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
+ 	  you'll need this, unless you have a different type keyboard (USB, ADB
+--- linux-2.6.0-test6/drivers/input/mouse/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mouse/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -15,7 +15,8 @@ config MOUSE_PS2
+ 	tristate "PS/2 mouse"
+ 	default y
+ 	depends on INPUT && INPUT_MOUSE
+-	select SERIO_I8042
++	select SERIO
++	select SERIO_I8042 if PC
+ 	---help---
+ 	  Say Y here if you have a PS/2 mouse connected to your system. This
+ 	  includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
+--- linux-2.6.0-test6/drivers/input/mouse/logips2pp.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/input/mouse/logips2pp.c	2003-10-05 00:34:15.000000000 -0700
+@@ -10,6 +10,7 @@
+  */
+ 
+ #include <linux/input.h>
++#include <linux/serio.h>
+ #include "psmouse.h"
+ #include "logips2pp.h"
+ 
+--- linux-2.6.0-test6/drivers/input/mouse/psmouse-base.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mouse/psmouse-base.c	2003-10-05 00:34:15.000000000 -0700
+@@ -141,7 +141,8 @@ static irqreturn_t psmouse_interrupt(str
+ 		goto out;
+ 	}
+ 
+-	if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
++	if (psmouse->state == PSMOUSE_ACTIVATED && 
++	    psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
+ 		printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
+ 		       psmouse->name, psmouse->phys, psmouse->pktcnt);
+ 		psmouse->pktcnt = 0;
+@@ -276,24 +277,18 @@ static int psmouse_extensions(struct psm
+ 		return PSMOUSE_PS2;
+ 
+ /*
+- * Try Synaptics TouchPad magic ID
++ * Try Synaptics TouchPad
+  */
+-
+-       param[0] = 0;
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+-
+-       if (param[1] == 0x47) {
++	if (synaptics_detect(psmouse) == 0) {
+ 		psmouse->vendor = "Synaptics";
+ 		psmouse->name = "TouchPad";
+-		if (!synaptics_init(psmouse))
++
++#if CONFIG_MOUSE_PS2_SYNAPTICS
++		if (synaptics_init(psmouse) == 0)
+ 			return PSMOUSE_SYNAPTICS;
+-		else
+-			return PSMOUSE_PS2;
+-       }
++#endif
++		return PSMOUSE_PS2;
++	}
+ 
+ /*
+  * Try Genius NetMouse magic init.
+@@ -519,7 +514,18 @@ static void psmouse_disconnect(struct se
+ 	struct psmouse *psmouse = serio->private;
+ 
+ 	psmouse->state = PSMOUSE_IGNORE;
+-	synaptics_disconnect(psmouse);
++	
++	if (psmouse->ptport) {
++		if (psmouse->ptport->deactivate)
++			psmouse->ptport->deactivate(psmouse);
++		__serio_unregister_port(&psmouse->ptport->serio); /* we have serio_sem */
++		kfree(psmouse->ptport);
++		psmouse->ptport = NULL;
++	}
++		
++	if (psmouse->disconnect)
++		psmouse->disconnect(psmouse);
++	
+ 	input_unregister_device(&psmouse->dev);
+ 	serio_close(serio);
+ 	kfree(psmouse);
+@@ -532,20 +538,10 @@ static void psmouse_disconnect(struct se
+ static int psmouse_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
+ {
+ 	struct psmouse *psmouse = dev->data;
+-	struct serio_dev *ser_dev = psmouse->serio->dev;
+-
+-	synaptics_disconnect(psmouse);
+-
+-	/* We need to reopen the serio port to reinitialize the i8042 controller */
+-	serio_close(psmouse->serio);
+-	serio_open(psmouse->serio, ser_dev);
+-
+-	/* Probe and re-initialize the mouse */
+-	psmouse_probe(psmouse);
+-	psmouse_initialize(psmouse);
+-	synaptics_pt_init(psmouse);
+-	psmouse_activate(psmouse);
+ 
++	psmouse->state = PSMOUSE_IGNORE;
++	serio_reconnect(psmouse->serio);
++	
+ 	return 0;
+ }
+ 
+@@ -553,7 +549,6 @@ static int psmouse_pm_callback(struct pm
+  * psmouse_connect() is a callback from the serio module when
+  * an unhandled serio port is found.
+  */
+-
+ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
+ {
+ 	struct psmouse *psmouse;
+@@ -578,7 +573,6 @@ static void psmouse_connect(struct serio
+ 	psmouse->dev.private = psmouse;
+ 
+ 	serio->private = psmouse;
+-
+ 	if (serio_open(serio, dev)) {
+ 		kfree(psmouse);
+ 		return;
+@@ -590,10 +584,12 @@ static void psmouse_connect(struct serio
+ 		return;
+ 	}
+ 	
+-	pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, psmouse_pm_callback);
+-	if (pmdev) {
+-		psmouse->dev.pm_dev = pmdev;
+-		pmdev->data = psmouse;
++	if (serio->type != SERIO_PS_PSTHRU) {
++		pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, psmouse_pm_callback);
++		if (pmdev) {
++			psmouse->dev.pm_dev = pmdev;
++			pmdev->data = psmouse;
++		}
+ 	}
+ 
+ 	sprintf(psmouse->devname, "%s %s %s",
+@@ -614,14 +610,70 @@ static void psmouse_connect(struct serio
+ 
+ 	psmouse_initialize(psmouse);
+ 
+-	synaptics_pt_init(psmouse);
++	if (psmouse->ptport) {
++		printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio.name, psmouse->phys);
++		__serio_register_port(&psmouse->ptport->serio); /* we have serio_sem */
++		if (psmouse->ptport->activate)
++			psmouse->ptport->activate(psmouse);
++	}
++	
++	psmouse_activate(psmouse);
++}
+ 
++
++static int psmouse_reconnect(struct serio *serio)
++{
++	struct psmouse *psmouse = serio->private;
++	struct serio_dev *dev = serio->dev;
++	int old_type = psmouse->type;
++	
++	if (!dev) {
++		printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
++		return -1;
++	}
++	
++	/* We need to reopen the serio port to reinitialize the i8042 controller */
++	serio_close(serio);
++	if (serio_open(serio, dev)) {
++		/* do a disconnect here as serio_open leaves dev as NULL so disconnect 
++		 * will not be called automatically later
++		 */
++		psmouse_disconnect(serio);
++		return -1;
++	}
++	
++	psmouse->state = PSMOUSE_NEW_DEVICE;
++	psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
++	if (psmouse->reconnect) {
++	       if (psmouse->reconnect(psmouse))
++			return -1;
++	} else if (psmouse_probe(psmouse) != old_type)
++		return -1;
++	
++	/* ok, the device type (and capabilities) match the old one,
++	 * we can continue using it, complete intialization
++	 */ 
++	psmouse->type = old_type;
++	psmouse_initialize(psmouse);
++
++	if (psmouse->ptport) {
++       		if (psmouse_reconnect(&psmouse->ptport->serio)) {
++			__serio_unregister_port(&psmouse->ptport->serio);
++			__serio_register_port(&psmouse->ptport->serio);
++			if (psmouse->ptport->activate)
++				psmouse->ptport->activate(psmouse);
++		}
++	}
++	
+ 	psmouse_activate(psmouse);
++	return 0;
+ }
+ 
++
+ static struct serio_dev psmouse_dev = {
+ 	.interrupt =	psmouse_interrupt,
+ 	.connect =	psmouse_connect,
++	.reconnect =	psmouse_reconnect,
+ 	.disconnect =	psmouse_disconnect,
+ 	.cleanup =	psmouse_cleanup,
+ };
+--- linux-2.6.0-test6/drivers/input/mouse/psmouse.h	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mouse/psmouse.h	2003-10-05 00:34:15.000000000 -0700
+@@ -22,10 +22,20 @@
+ #define PSMOUSE_ACTIVATED	1
+ #define PSMOUSE_IGNORE		2
+ 
++struct psmouse;
++
++struct psmouse_ptport {
++	struct serio serio;
++
++	void (*activate)(struct psmouse *parent);
++	void (*deactivate)(struct psmouse *parent);
++};
++
+ struct psmouse {
+ 	void *private;
+ 	struct input_dev dev;
+ 	struct serio *serio;
++	struct psmouse_ptport *ptport;
+ 	char *vendor;
+ 	char *name;
+ 	unsigned char cmdbuf[8];
+@@ -41,6 +51,9 @@ struct psmouse {
+ 	char error;
+ 	char devname[64];
+ 	char phys[32];
++	
++	int (*reconnect)(struct psmouse *psmouse);
++	void (*disconnect)(struct psmouse *psmouse);
+ };
+ 
+ #define PSMOUSE_PS2		1
+--- linux-2.6.0-test6/drivers/input/mouse/synaptics.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mouse/synaptics.c	2003-10-05 00:34:15.000000000 -0700
+@@ -2,7 +2,8 @@
+  * Synaptics TouchPad PS/2 mouse driver
+  *
+  *   2003 Dmitry Torokhov <dtor@mail.ru>
+- *     Added support for pass-through port
++ *     Added support for pass-through port. Special thanks to Peter Berg Larsen
++ *     for explaining various Synaptics quirks.
+  *
+  *   2003 Peter Osterlund <petero2@telia.com>
+  *     Ported to 2.5 input device infrastructure.
+@@ -194,9 +195,7 @@ static void print_ident(struct synaptics
+ 
+ static int synaptics_query_hardware(struct psmouse *psmouse)
+ {
+-	struct synaptics_data *priv = psmouse->private;
+ 	int retries = 0;
+-	int mode;
+ 
+ 	while ((retries++ < 3) && synaptics_reset(psmouse))
+ 		printk(KERN_ERR "synaptics reset failed\n");
+@@ -207,8 +206,15 @@ static int synaptics_query_hardware(stru
+ 		return -1;
+ 	if (synaptics_capability(psmouse))
+ 		return -1;
++	
++	return 0;
++}
+ 
+-	mode = SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
++static int synaptics_set_mode(struct psmouse *psmouse, int mode)
++{
++	struct synaptics_data *priv = psmouse->private;
++
++	mode |= SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
+ 	if (SYN_ID_MAJOR(priv->identity) >= 4)
+ 		mode |= SYN_BIT_DISABLE_GESTURE;
+ 	if (SYN_CAP_EXTENDED(priv->capabilities))
+@@ -265,49 +271,38 @@ static void synaptics_pass_pt_packet(str
+ 	}
+ }
+ 
+-int synaptics_pt_init(struct psmouse *psmouse)
++static void synaptics_pt_activate(struct psmouse *psmouse)
+ {
+-	struct synaptics_data *priv = psmouse->private;
+-	struct serio *port;
+-	struct psmouse *child;
++	struct psmouse *child = psmouse->ptport->serio.private;
++	
++	/* adjust the touchpad to child's choice of protocol */
++	if (child && child->type >= PSMOUSE_GENPS) {
++		if (synaptics_set_mode(psmouse, SYN_BIT_FOUR_BYTE_CLIENT))
++			printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
++	}
++}
+ 
+-	if (psmouse->type != PSMOUSE_SYNAPTICS)
+-		return -1;
+-	if (!SYN_CAP_EXTENDED(priv->capabilities))
+-		return -1;
+-	if (!SYN_CAP_PASS_THROUGH(priv->capabilities))
+-		return -1;
++static void synaptics_pt_create(struct psmouse *psmouse)
++{
++	struct psmouse_ptport *port;
+ 
+-	priv->ptport = port = kmalloc(sizeof(struct serio), GFP_KERNEL);
++	psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
+ 	if (!port) {
+-		printk(KERN_ERR "synaptics: not enough memory to allocate serio port\n");
+-		return -1;
++		printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
++		return;
+ 	}
+ 
+-	memset(port, 0, sizeof(struct serio));
+-	port->type = SERIO_PS_PSTHRU;
+-	port->name = "Synaptics pass-through";
+-	port->phys = "synaptics-pt/serio0";
+-	port->write = synaptics_pt_write;
+-	port->open = synaptics_pt_open;
+-	port->close = synaptics_pt_close;
+-	port->driver = psmouse;
++	memset(port, 0, sizeof(struct psmouse_ptport));
+ 
+-	printk(KERN_INFO "serio: %s port at %s\n", port->name, psmouse->phys);
+-	serio_register_slave_port(port);
++	port->serio.type = SERIO_PS_PSTHRU;
++	port->serio.name = "Synaptics pass-through";
++	port->serio.phys = "synaptics-pt/serio0";
++	port->serio.write = synaptics_pt_write;
++	port->serio.open = synaptics_pt_open;
++	port->serio.close = synaptics_pt_close;
++	port->serio.driver = psmouse;
+ 
+-	/* adjust the touchpad to child's choice of protocol */
+-	child = port->private;
+-	if (child && child->type >= PSMOUSE_GENPS) {
+-		if (synaptics_mode_cmd(psmouse, (SYN_BIT_ABSOLUTE_MODE |
+-					 	 SYN_BIT_HIGH_RATE |
+-					 	 SYN_BIT_DISABLE_GESTURE |
+-						 SYN_BIT_FOUR_BYTE_CLIENT |
+-					 	 SYN_BIT_W_MODE)))
+-			printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
+-	}
+-
+-	return 0;
++	port->activate = synaptics_pt_activate;
+ }
+ 
+ /*****************************************************************************
+@@ -371,27 +366,82 @@ static void set_input_params(struct inpu
+ 	clear_bit(REL_Y, dev->relbit);
+ }
+ 
++static void synaptics_disconnect(struct psmouse *psmouse)
++{
++	synaptics_mode_cmd(psmouse, 0);
++	kfree(psmouse->private);
++}
++
++static int synaptics_reconnect(struct psmouse *psmouse)
++{
++	struct synaptics_data *priv = psmouse->private;
++	struct synaptics_data old_priv = *priv;
++
++	if (synaptics_detect(psmouse))
++		return -1;
++
++	if (synaptics_query_hardware(psmouse)) {
++		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
++		return -1;
++	}
++	
++	if (old_priv.identity != priv->identity ||
++	    old_priv.model_id != priv->model_id ||
++	    old_priv.capabilities != priv->capabilities ||
++    	    old_priv.ext_cap != priv->ext_cap)
++    		return -1;
++	
++	if (synaptics_set_mode(psmouse, 0)) {
++		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++int synaptics_detect(struct psmouse *psmouse)
++{
++	unsigned char param[4];
++	
++	param[0] = 0;
++	
++	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++	
++	return param[1] == 0x47 ? 0 : -1;
++}
++
+ int synaptics_init(struct psmouse *psmouse)
+ {
+ 	struct synaptics_data *priv;
+ 
+-#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
+-	return -1;
+-#endif
+-
+ 	psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+ 	if (!priv)
+ 		return -1;
+ 	memset(priv, 0, sizeof(struct synaptics_data));
+ 
+ 	if (synaptics_query_hardware(psmouse)) {
+-		printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n");
++		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
++		goto init_fail;
++	}
++	
++	if (synaptics_set_mode(psmouse, 0)) {
++		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+ 		goto init_fail;
+ 	}
+ 
++	if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
++       		synaptics_pt_create(psmouse);
++	
+ 	print_ident(priv);
+ 	set_input_params(&psmouse->dev, priv);
+ 
++	psmouse->disconnect = synaptics_disconnect;
++	psmouse->reconnect = synaptics_reconnect;
++	
+ 	return 0;
+ 
+  init_fail:
+@@ -399,36 +449,13 @@ int synaptics_init(struct psmouse *psmou
+ 	return -1;
+ }
+ 
+-void synaptics_disconnect(struct psmouse *psmouse)
+-{
+-	struct synaptics_data *priv = psmouse->private;
+-
+-	if (psmouse->type == PSMOUSE_SYNAPTICS && priv) {
+-		synaptics_mode_cmd(psmouse, 0);
+-		if (priv->ptport) {
+-			serio_unregister_slave_port(priv->ptport);
+-			kfree(priv->ptport);
+-		}
+-		kfree(priv);
+-	}
+-}
+-
+ /*****************************************************************************
+  *	Functions to interpret the absolute mode packets
+  ****************************************************************************/
+ 
+ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
+ {
+-	hw->up    = 0;
+-	hw->down  = 0;
+-	hw->b0    = 0;
+-	hw->b1    = 0;
+-	hw->b2    = 0;
+-	hw->b3    = 0;
+-	hw->b4    = 0;
+-	hw->b5    = 0;
+-	hw->b6    = 0;
+-	hw->b7    = 0;
++	memset(hw, 0, sizeof(struct synaptics_hw_state));
+ 
+ 	if (SYN_MODEL_NEWABS(priv->model_id)) {
+ 		hw->x = (((buf[3] & 0x10) << 8) |
+@@ -570,64 +597,47 @@ static void synaptics_process_packet(str
+ 	input_sync(dev);
+ }
+ 
++static int synaptics_validate_byte(struct psmouse *psmouse)
++{
++	static unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
++	static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
++	static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
++	static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
++	struct synaptics_data *priv = psmouse->private;
++	int idx = psmouse->pktcnt - 1;
++
++	if (SYN_MODEL_NEWABS(priv->model_id))
++		return (psmouse->packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
++	else
++		return (psmouse->packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
++}
++
+ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+ 	struct input_dev *dev = &psmouse->dev;
+ 	struct synaptics_data *priv = psmouse->private;
+-	unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
+-	int newabs = SYN_MODEL_NEWABS(priv->model_id);
+ 
+ 	input_regs(dev, regs);
+ 
+-	switch (psmouse->pktcnt) {
+-	case 1:
+-		if (newabs ? ((data & 0xC8) != 0x80) : ((data & 0xC0) != 0xC0)) {
+-			printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
+-			goto bad_sync;
+-		}
+-		break;
+-	case 2:
+-		if (!newabs && ((data & 0x60) != 0x00)) {
+-			printk(KERN_WARNING "Synaptics driver lost sync at 2nd byte\n");
+-			goto bad_sync;
+-		}
+-		break;
+-	case 4:
+-		if (newabs ? ((data & 0xC8) != 0xC0) : ((data & 0xC0) != 0x80)) {
+-			printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
+-			goto bad_sync;
+-		}
+-		break;
+-	case 5:
+-		if (!newabs && ((data & 0x60) != 0x00)) {
+-			printk(KERN_WARNING "Synaptics driver lost sync at 5th byte\n");
+-			goto bad_sync;
+-		}
+-		break;
+-	default:
+-		if (psmouse->pktcnt < 6)
+-			break;		    /* Wait for full packet */
+-
++	if (psmouse->pktcnt >= 6) { /* Full packet received */
+ 		if (priv->out_of_sync) {
+ 			priv->out_of_sync = 0;
+ 			printk(KERN_NOTICE "Synaptics driver resynced.\n");
+ 		}
+ 
+-		if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
+-			synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
++		if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
++			synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
+ 		else
+ 			synaptics_process_packet(psmouse);
+-
+ 		psmouse->pktcnt = 0;
+-		break;
+-	}
+-	return;
+ 
+- bad_sync:
+-	priv->out_of_sync++;
+-	psmouse->pktcnt = 0;
+-	if (psmouse_resetafter > 0 && priv->out_of_sync	== psmouse_resetafter) {
+-		psmouse->state = PSMOUSE_IGNORE;
+-		serio_rescan(psmouse->serio);
++	} else if (psmouse->pktcnt && !synaptics_validate_byte(psmouse)) {
++		printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
++		psmouse->pktcnt = 0;
++		if (++priv->out_of_sync == psmouse_resetafter) {
++			psmouse->state = PSMOUSE_IGNORE;
++			printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
++			serio_reconnect(psmouse->serio);
++		}
+ 	}
+ }
+--- linux-2.6.0-test6/drivers/input/mouse/synaptics.h	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mouse/synaptics.h	2003-10-05 00:34:15.000000000 -0700
+@@ -9,11 +9,9 @@
+ #ifndef _SYNAPTICS_H
+ #define _SYNAPTICS_H
+ 
+-
+ extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
++extern int synaptics_detect(struct psmouse *psmouse);
+ extern int synaptics_init(struct psmouse *psmouse);
+-extern int synaptics_pt_init(struct psmouse *psmouse);
+-extern void synaptics_disconnect(struct psmouse *psmouse);
+ 
+ /* synaptics queries */
+ #define SYN_QUE_IDENTIFY		0x00
+@@ -105,8 +103,6 @@ struct synaptics_data {
+ 	/* Data for normal processing */
+ 	unsigned int out_of_sync;		/* # of packets out of sync */
+ 	int old_w;				/* Previous w value */
+-	
+-	struct serio *ptport;			/* pass-through port */
+ };
+ 
+ #endif /* _SYNAPTICS_H */
+--- linux-2.6.0-test6/drivers/input/serio/serio.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/serio/serio.c	2003-10-05 00:34:15.000000000 -0700
+@@ -49,14 +49,15 @@ MODULE_LICENSE("GPL");
+ 
+ EXPORT_SYMBOL(serio_interrupt);
+ EXPORT_SYMBOL(serio_register_port);
+-EXPORT_SYMBOL(serio_register_slave_port);
++EXPORT_SYMBOL(__serio_register_port);
+ EXPORT_SYMBOL(serio_unregister_port);
+-EXPORT_SYMBOL(serio_unregister_slave_port);
++EXPORT_SYMBOL(__serio_unregister_port);
+ EXPORT_SYMBOL(serio_register_device);
+ EXPORT_SYMBOL(serio_unregister_device);
+ EXPORT_SYMBOL(serio_open);
+ EXPORT_SYMBOL(serio_close);
+ EXPORT_SYMBOL(serio_rescan);
++EXPORT_SYMBOL(serio_reconnect);
+ 
+ struct serio_event {
+ 	int type;
+@@ -83,10 +84,20 @@ static void serio_find_dev(struct serio 
+ }
+ 
+ #define SERIO_RESCAN	1
++#define SERIO_RECONNECT	2
+ 
+ static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
+ static DECLARE_COMPLETION(serio_exited);
+ 
++static void serio_invalidate_pending_events(struct serio *serio)
++{
++	struct serio_event *event;
++	
++	list_for_each_entry(event, &serio_event_list, node)
++		if (event->serio == serio)
++			event->serio = NULL;
++}
++
+ void serio_handle_events(void)
+ {
+ 	struct list_head *node, *next;
+@@ -95,17 +106,27 @@ void serio_handle_events(void)
+ 	list_for_each_safe(node, next, &serio_event_list) {
+ 		event = container_of(node, struct serio_event, node);	
+ 
++		down(&serio_sem);
++		if (event->serio == NULL)
++			goto event_done;
++		
+ 		switch (event->type) {
++			case SERIO_RECONNECT :
++				if (event->serio->dev && event->serio->dev->reconnect)
++					if (event->serio->dev->reconnect(event->serio) == 0)
++						break;
++				/* reconnect failed - fall through to rescan */
++				
+ 			case SERIO_RESCAN :
+-				down(&serio_sem);
+ 				if (event->serio->dev && event->serio->dev->disconnect)
+ 					event->serio->dev->disconnect(event->serio);
+ 				serio_find_dev(event->serio);
+-				up(&serio_sem);
+ 				break;
+ 			default:
+ 				break;
+ 		}
++event_done:
++		up(&serio_sem);
+ 		list_del_init(node);
+ 		kfree(event);
+ 	}
+@@ -130,18 +151,27 @@ static int serio_thread(void *nothing)
+ 	complete_and_exit(&serio_exited, 0);
+ }
+ 
+-void serio_rescan(struct serio *serio)
++static void serio_queue_event(struct serio *serio, int event_type)
+ {
+ 	struct serio_event *event;
+ 
+-	if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC)))
+-		return;
++	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
++		event->type = event_type;
++		event->serio = serio;
+ 
+-	event->type = SERIO_RESCAN;
+-	event->serio = serio;
++		list_add_tail(&event->node, &serio_event_list);
++		wake_up(&serio_wait);
++	}
++}
+ 
+-	list_add_tail(&event->node, &serio_event_list);
+-	wake_up(&serio_wait);
++void serio_rescan(struct serio *serio)
++{
++	serio_queue_event(serio, SERIO_RESCAN);
++}
++
++void serio_reconnect(struct serio *serio)
++{
++	serio_queue_event(serio, SERIO_RECONNECT);
+ }
+ 
+ irqreturn_t serio_interrupt(struct serio *serio,
+@@ -163,17 +193,16 @@ irqreturn_t serio_interrupt(struct serio
+ void serio_register_port(struct serio *serio)
+ {
+ 	down(&serio_sem);
+-	list_add_tail(&serio->node, &serio_list);
+-	serio_find_dev(serio);
++	__serio_register_port(serio);
+ 	up(&serio_sem);
+ }
+ 
+ /*
+- * Same as serio_register_port but does not try to acquire serio_sem.
+- * Should be used when registering a serio from other input device's
++ * Should only be called directly if serio_sem has already been taken,
++ * for example when unregistering a serio from other input device's 
+  * connect() function.
+  */
+-void serio_register_slave_port(struct serio *serio)
++void __serio_register_port(struct serio *serio)
+ {
+ 	list_add_tail(&serio->node, &serio_list);
+ 	serio_find_dev(serio);
+@@ -182,19 +211,18 @@ void serio_register_slave_port(struct se
+ void serio_unregister_port(struct serio *serio)
+ {
+ 	down(&serio_sem);
+-	list_del_init(&serio->node);
+-	if (serio->dev && serio->dev->disconnect)
+-		serio->dev->disconnect(serio);
++	__serio_unregister_port(serio);
+ 	up(&serio_sem);
+ }
+ 
+ /*
+- * Same as serio_unregister_port but does not try to acquire serio_sem.
+- * Should be used when unregistering a serio from other input device's
++ * Should only be called directly if serio_sem has already been taken,
++ * for example when unregistering a serio from other input device's 
+  * disconnect() function.
+  */
+-void serio_unregister_slave_port(struct serio *serio)
++void __serio_unregister_port(struct serio *serio)
+ {
++	serio_invalidate_pending_events(serio);
+ 	list_del_init(&serio->node);
+ 	if (serio->dev && serio->dev->disconnect)
+ 		serio->dev->disconnect(serio);
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/debuglib.h	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/debuglib.h	2003-10-05 00:33:24.000000000 -0700
+@@ -103,28 +103,28 @@
+ #define DL_TO_KERNEL    0x40000000
+ 
+ #ifdef DIVA_NO_DEBUGLIB
+-#define myDbgPrint_LOG(x,...) do { } while(0);
+-#define myDbgPrint_FTL(x,...) do { } while(0);
+-#define myDbgPrint_ERR(x,...) do { } while(0);
+-#define myDbgPrint_TRC(x,...) do { } while(0);
+-#define myDbgPrint_MXLOG(x,...) do { } while(0);
+-#define myDbgPrint_EVL(x,...) do { } while(0);
+-#define myDbgPrint_REG(x,...) do { } while(0);
+-#define myDbgPrint_MEM(x,...) do { } while(0);
+-#define myDbgPrint_SPL(x,...) do { } while(0);
+-#define myDbgPrint_IRP(x,...) do { } while(0);
+-#define myDbgPrint_TIM(x,...) do { } while(0);
+-#define myDbgPrint_BLK(x,...) do { } while(0);
+-#define myDbgPrint_TAPI(x,...) do { } while(0);
+-#define myDbgPrint_NDIS(x,...) do { } while(0);
+-#define myDbgPrint_CONN(x,...) do { } while(0);
+-#define myDbgPrint_STAT(x,...) do { } while(0);
+-#define myDbgPrint_SEND(x,...) do { } while(0);
+-#define myDbgPrint_RECV(x,...) do { } while(0);
+-#define myDbgPrint_PRV0(x,...) do { } while(0);
+-#define myDbgPrint_PRV1(x,...) do { } while(0);
+-#define myDbgPrint_PRV2(x,...) do { } while(0);
+-#define myDbgPrint_PRV3(x,...) do { } while(0);
++#define myDbgPrint_LOG(x...) do { } while(0);
++#define myDbgPrint_FTL(x...) do { } while(0);
++#define myDbgPrint_ERR(x...) do { } while(0);
++#define myDbgPrint_TRC(x...) do { } while(0);
++#define myDbgPrint_MXLOG(x...) do { } while(0);
++#define myDbgPrint_EVL(x...) do { } while(0);
++#define myDbgPrint_REG(x...) do { } while(0);
++#define myDbgPrint_MEM(x...) do { } while(0);
++#define myDbgPrint_SPL(x...) do { } while(0);
++#define myDbgPrint_IRP(x...) do { } while(0);
++#define myDbgPrint_TIM(x...) do { } while(0);
++#define myDbgPrint_BLK(x...) do { } while(0);
++#define myDbgPrint_TAPI(x...) do { } while(0);
++#define myDbgPrint_NDIS(x...) do { } while(0);
++#define myDbgPrint_CONN(x...) do { } while(0);
++#define myDbgPrint_STAT(x...) do { } while(0);
++#define myDbgPrint_SEND(x...) do { } while(0);
++#define myDbgPrint_RECV(x...) do { } while(0);
++#define myDbgPrint_PRV0(x...) do { } while(0);
++#define myDbgPrint_PRV1(x...) do { } while(0);
++#define myDbgPrint_PRV2(x...) do { } while(0);
++#define myDbgPrint_PRV3(x...) do { } while(0);
+ #define DBG_TEST(func,args) do { } while(0);
+ #define DBG_EVL_ID(args) do { } while(0);
+ 
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/divamnt.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/divamnt.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * Maint module
+@@ -24,10 +24,9 @@
+ #include "platform.h"
+ #include "di_defs.h"
+ #include "divasync.h"
+-#include "di_defs.h"
+ #include "debug_if.h"
+ 
+-static char *main_revision = "$Revision: 1.2 $";
++static char *main_revision = "$Revision: 1.2 $";
+ 
+ static int major;
+ 
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/divasmain.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/divasmain.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * Low level driver for Eicon DIVA Server ISDN cards.
+  *
+@@ -9,13 +9,11 @@
+  * of the GNU General Public License, incorporated herein by reference.
+  */
+ 
+-#define __KERNEL_SYSCALLS__
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+-#include <linux/unistd.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -43,7 +41,7 @@
+ #include "diva_dma.h"
+ #include "diva_pci.h"
+ 
+-static char *main_revision = "$Revision: 1.2 $";
++static char *main_revision = "$Revision: 1.2 $";
+ 
+ static int major;
+ 
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/dqueue.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/dqueue.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * User Mode IDI Interface
+  *
+- * Copyright 2000,2001 by Armin Schindler (mac@melware.de)
+- * Copyright 2000,2001 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+  *
+  * This software may be used and distributed according to the terms
+  * of the GNU General Public License, incorporated herein by reference.
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/mntfunc.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/mntfunc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * Driver for Eicon DIVA Server ISDN cards.
+  * Maint module
+@@ -14,7 +14,6 @@
+ #include "platform.h"
+ #include "di_defs.h"
+ #include "divasync.h"
+-#include "di_defs.h"
+ #include "debug_if.h"
+ 
+ extern char *DRIVERRELEASE_MNT;
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/os_capi.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/os_capi.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,10 +1,10 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * ISDN interface module for Eicon active cards DIVA.
+  * CAPI Interface OS include files 
+  * 
+- * Copyright 2000-2002 by Armin Schindler (mac@melware.de) 
+- * Copyright 2000-2002 Cytronics & Melware (info@melware.de)
++ * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 
++ * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
+  * 
+  * This software may be used and distributed according to the terms
+  * of the GNU General Public License, incorporated herein by reference.
+--- linux-2.6.0-test6/drivers/isdn/hardware/eicon/platform.h	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/eicon/platform.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,4 +1,4 @@
+-/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
++/* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  *
+  * platform.h
+  * 
+@@ -19,7 +19,6 @@
+ #endif
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/drivers/isdn/i4l/isdn_common.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/i4l/isdn_common.c	2003-10-05 00:33:24.000000000 -0700
+@@ -2229,8 +2229,10 @@ static int __init isdn_init(void)
+ 	isdn_info_update();
+ 	return 0;
+ 
+-/* err_tty_modem:*/
++#ifdef CONFIG_ISDN_PPP
++ err_tty_modem:
+ 	isdn_tty_exit();
++#endif
+  err_cleanup_devfs:
+ 	isdn_cleanup_devfs();
+ 	unregister_chrdev(ISDN_MAJOR, "isdn");
+--- linux-2.6.0-test6/drivers/mca/mca-legacy.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/mca/mca-legacy.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/device.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <asm/io.h>
+ 
+ /* NOTE: This structure is stack allocated */
+--- linux-2.6.0-test6/drivers/mca/mca-proc.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/mca/mca-proc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -120,12 +120,13 @@ static int mca_default_procfn(char* buf,
+ 	len += sprintf(buf+len, "Id: %02x%02x\n",
+ 		mca_dev->pos[1], mca_dev->pos[0]);
+ 	len += sprintf(buf+len, "Enabled: %s\nPOS: ",
+-		mca_isenabled(slot) ? "Yes" : "No");
++		mca_device_status(mca_dev) == MCA_ADAPTER_NORMAL ?
++			"Yes" : "No");
+ 	for(i=0; i<8; i++) {
+ 		len += sprintf(buf+len, "%02x ", mca_dev->pos[i]);
+ 	}
+ 	len += sprintf(buf+len, "\nDriver Installed: %s",
+-		mca_is_adapter_used(slot) ? "Yes" : "No");
++		mca_device_claimed(mca_dev) ? "Yes" : "No");
+ 	buf[len++] = '\n';
+ 	buf[len] = 0;
+ 
+@@ -189,6 +190,7 @@ void __init mca_do_proc_init(void)
+ 	/* Initialize /proc/mca entries for existing adapters */
+ 
+ 	for(i = 0; i < MCA_NUMADAPTERS; i++) {
++		enum MCA_AdapterStatus status;
+ 		mca_dev = mca_find_device_by_slot(i);
+ 		if(!mca_dev)
+ 			continue;
+@@ -200,7 +202,10 @@ void __init mca_do_proc_init(void)
+ 		else if(i == MCA_INTEGSCSI) sprintf(mca_dev->procname,"scsi");
+ 		else if(i == MCA_MOTHERBOARD) sprintf(mca_dev->procname,"planar");
+ 
+-		if(!mca_isadapter(i)) continue;
++		status = mca_device_status(mca_dev);
++		if (status != MCA_ADAPTER_NORMAL &&
++		    status != MCA_ADAPTER_DISABLED)
++			continue;
+ 
+ 		node = create_proc_read_entry(mca_dev->procname, 0, proc_mca,
+ 					      mca_read_proc, (void *)mca_dev);
+--- linux-2.6.0-test6/drivers/md/dm.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/dm.c	2003-10-05 00:34:01.000000000 -0700
+@@ -160,20 +160,16 @@ static void __exit dm_exit(void)
+ /*
+  * Block device functions
+  */
+-static int dm_blk_open(struct inode *inode, struct file *file)
++static int dm_blk_open(struct block_device *bdev, struct file *file)
+ {
+-	struct mapped_device *md;
+-
+-	md = inode->i_bdev->bd_disk->private_data;
++	struct mapped_device *md = bdev->bd_disk->private_data;
+ 	dm_get(md);
+ 	return 0;
+ }
+ 
+-static int dm_blk_close(struct inode *inode, struct file *file)
++static int dm_blk_close(struct gendisk *disk)
+ {
+-	struct mapped_device *md;
+-
+-	md = inode->i_bdev->bd_disk->private_data;
++	struct mapped_device *md = disk->private_data;
+ 	dm_put(md);
+ 	return 0;
+ }
+--- linux-2.6.0-test6/drivers/md/md.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/md.c	2003-10-05 00:34:01.000000000 -0700
+@@ -2360,11 +2360,10 @@ static int set_disk_faulty(mddev_t *mdde
+ 	return 1;
+ }
+ 
+-static int md_ioctl(struct inode *inode, struct file *file,
++static int md_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+ 	char b[BDEVNAME_SIZE];
+-	unsigned int minor = iminor(inode);
+ 	int err = 0;
+ 	struct hd_geometry *loc = (struct hd_geometry *) arg;
+ 	mddev_t *mddev = NULL;
+@@ -2372,11 +2371,6 @@ static int md_ioctl(struct inode *inode,
+ 	if (!capable(CAP_SYS_ADMIN))
+ 		return -EACCES;
+ 
+-	if (minor >= MAX_MD_DEVS) {
+-		MD_BUG();
+-		return -EINVAL;
+-	}
+-
+ 	/*
+ 	 * Commands dealing with the RAID driver but not any
+ 	 * particular array:
+@@ -2405,7 +2399,7 @@ static int md_ioctl(struct inode *inode,
+ 	 * Commands creating/starting a new array:
+ 	 */
+ 
+-	mddev = inode->i_bdev->bd_inode->u.generic_ip;
++	mddev = bdev->bd_inode->u.generic_ip;
+ 
+ 	if (!mddev) {
+ 		BUG();
+@@ -2527,7 +2521,7 @@ static int md_ioctl(struct inode *inode,
+ 						(short *) &loc->cylinders);
+ 			if (err)
+ 				goto abort_unlock;
+-			err = put_user (get_start_sect(inode->i_bdev),
++			err = put_user (get_start_sect(bdev),
+ 						(long *) &loc->start);
+ 			goto done_unlock;
+ 	}
+@@ -2605,12 +2599,12 @@ abort:
+ 	return err;
+ }
+ 
+-static int md_open(struct inode *inode, struct file *file)
++static int md_open(struct block_device *bdev, struct file *file)
+ {
+ 	/*
+ 	 * Succeed if we can find or allocate a mddev structure.
+ 	 */
+-	mddev_t *mddev = mddev_find(iminor(inode));
++	mddev_t *mddev = mddev_find(MINOR(bdev->bd_dev));
+ 	int err = -ENOMEM;
+ 
+ 	if (!mddev)
+@@ -2621,16 +2615,16 @@ static int md_open(struct inode *inode, 
+ 
+ 	err = 0;
+ 	mddev_unlock(mddev);
+-	inode->i_bdev->bd_inode->u.generic_ip = mddev_get(mddev);
++	bdev->bd_inode->u.generic_ip = mddev_get(mddev);
+  put:
+ 	mddev_put(mddev);
+  out:
+ 	return err;
+ }
+ 
+-static int md_release(struct inode *inode, struct file * file)
++static int md_release(struct gendisk *disk)
+ {
+- 	mddev_t *mddev = inode->i_bdev->bd_inode->u.generic_ip;
++ 	mddev_t *mddev = disk->private_data;
+ 
+ 	if (!mddev)
+ 		BUG();
+--- linux-2.6.0-test6/drivers/media/common/saa7146_i2c.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/common/saa7146_i2c.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,3 +1,4 @@
++#include <linux/version.h>
+ #include <media/saa7146_vv.h>
+ 
+ /* helper function */
+--- linux-2.6.0-test6/drivers/media/dvb/dvb-core/dvbdev.h	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvbdev.h	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+ #include <linux/poll.h>
+ #include <linux/fs.h>
+ #include <linux/list.h>
+-#include <linux/version.h>
+ #include <linux/devfs_fs_kernel.h>
+ 
+ #define DVB_MAJOR 250
+--- linux-2.6.0-test6/drivers/media/dvb/dvb-core/dvb_functions.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_functions.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1,4 +1,3 @@
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
+ #include <linux/string.h>
+--- linux-2.6.0-test6/drivers/media/dvb/dvb-core/dvb_functions.h	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_functions.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,8 +1,6 @@
+ #ifndef __DVB_FUNCTIONS_H__
+ #define __DVB_FUNCTIONS_H__
+ 
+-#include <linux/version.h>
+-
+ /**
+  *  a sleeping delay function, waits i ms
+  *
+--- linux-2.6.0-test6/drivers/media/dvb/ttpci/av7110.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/av7110.c	2003-10-05 00:33:24.000000000 -0700
+@@ -55,10 +55,8 @@
+ #include <linux/ptrace.h>
+ #include <linux/ioport.h>
+ #include <linux/in.h>
+-#include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+ #include <linux/vmalloc.h>
+ #include <linux/netdevice.h>
+ #include <linux/inetdevice.h>
+@@ -4745,12 +4743,19 @@ static struct saa7146_extension av7110_e
+ 
+ static int __init av7110_init(void) 
+ {
+-	if (saa7146_register_extension(&av7110_extension))
+-		return -ENODEV;
++	int retval;
++	retval = saa7146_register_extension(&av7110_extension);
++	if (retval)
++		goto failed_saa7146_register;
+ 	
+-	av7110_ir_init();
+-
++	retval = av7110_ir_init();
++	if (retval)
++		goto failed_av7110_ir_init;
+ 	return 0;
++failed_av7110_ir_init:
++	saa7146_unregister_extension(&av7110_extension);
++failed_saa7146_register:
++	return retval;
+ }
+ 
+ 
+--- linux-2.6.0-test6/drivers/media/dvb/ttpci/budget.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/budget.c	2003-10-05 00:33:24.000000000 -0700
+@@ -228,10 +228,7 @@ static struct saa7146_extension budget_e
+ 
+ static int __init budget_init(void) 
+ {
+-	if (saa7146_register_extension(&budget_extension))
+-		return -ENODEV;
+-	
+-	return 0;
++	return saa7146_register_extension(&budget_extension);
+ }
+ 
+ 
+--- linux-2.6.0-test6/drivers/media/dvb/ttpci/budget-ci.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/budget-ci.c	2003-10-05 00:33:24.000000000 -0700
+@@ -384,10 +384,7 @@ static struct saa7146_extension budget_e
+ 
+ static int __init budget_ci_init(void) 
+ {
+-	if (saa7146_register_extension(&budget_extension))
+-		return -ENODEV;
+-	
+-	return 0;
++	return saa7146_register_extension(&budget_extension);
+ }
+ 
+ 
+--- linux-2.6.0-test6/drivers/media/dvb/ttpci/budget-patch.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/budget-patch.c	2003-10-05 00:33:24.000000000 -0700
+@@ -247,10 +247,7 @@ static int budget_patch_detach (struct s
+ 
+ static int __init budget_patch_init(void) 
+ {
+-        if (saa7146_register_extension(&budget_extension))
+-                return -ENODEV;
+-        
+-        return 0;
++	return saa7146_register_extension(&budget_extension);
+ }
+ 
+ 
+--- linux-2.6.0-test6/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-10-05 00:33:24.000000000 -0700
+@@ -9,6 +9,7 @@
+  *	published by the Free Software Foundation; either version 2 of
+  *	the License, or (at your option) any later version.
+  */
++#include <linux/version.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/wait.h>
+@@ -27,7 +28,6 @@
+ #include <linux/dvb/frontend.h>
+ #include <linux/dvb/dmx.h>
+ #include <linux/pci.h>
+-#include <linux/usb.h>
+ 
+ #include "dvb_functions.h"
+ 
+@@ -1055,7 +1055,8 @@ static ssize_t stc_read(struct file *fil
+ 	if (tc < 0)
+ 		return 0;
+ 
+-	copy_to_user(buf, stc_firmware + *offset, tc);
++	if (copy_to_user(buf, stc_firmware + *offset, tc))
++		return -EFAULT;
+ 
+ 	*offset += tc;
+ 
+--- linux-2.6.0-test6/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-10-05 00:33:24.000000000 -0700
+@@ -19,6 +19,7 @@
+  *
+  */
+ 
++#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+--- linux-2.6.0-test6/drivers/media/radio/radio-gemtek-pci.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/media/radio/radio-gemtek-pci.c	2003-10-05 00:33:24.000000000 -0700
+@@ -37,7 +37,6 @@
+  ***************************************************************************
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/list.h>
+--- linux-2.6.0-test6/drivers/media/video/adv7170.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/adv7170.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,8 +28,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -49,7 +47,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
+--- linux-2.6.0-test6/drivers/media/video/adv7175.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/adv7175.c	2003-10-05 00:33:24.000000000 -0700
+@@ -24,8 +24,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -45,7 +43,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
+--- linux-2.6.0-test6/drivers/media/video/bt819.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/bt819.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,8 +28,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -49,7 +47,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
+--- linux-2.6.0-test6/drivers/media/video/bt856.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/bt856.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,8 +28,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -49,7 +47,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
+--- linux-2.6.0-test6/drivers/media/video/bttvp.h	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/media/video/bttvp.h	2003-10-05 00:33:24.000000000 -0700
+@@ -25,6 +25,7 @@
+ #define _BTTVP_H_
+ 
+ 
++#include <linux/version.h>
+ #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,11)
+ 
+ #include <linux/types.h>
+--- linux-2.6.0-test6/drivers/media/video/bw-qcam.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/bw-qcam.c	2003-10-05 00:33:24.000000000 -0700
+@@ -72,7 +72,6 @@ OTHER DEALINGS IN THE SOFTWARE.
+ #include <linux/mm.h>
+ #include <linux/parport.h>
+ #include <linux/sched.h>
+-#include <linux/version.h>
+ #include <linux/videodev.h>
+ #include <asm/semaphore.h>
+ #include <asm/uaccess.h>
+--- linux-2.6.0-test6/drivers/media/video/cpia.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/cpia.c	2003-10-05 00:33:24.000000000 -0700
+@@ -29,7 +29,6 @@
+ #include <linux/config.h>
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <linux/fs.h>
+ #include <linux/vmalloc.h>
+--- linux-2.6.0-test6/drivers/media/video/cpia_pp.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/media/video/cpia_pp.c	2003-10-05 00:33:24.000000000 -0700
+@@ -26,7 +26,6 @@
+ /* #define _CPIA_DEBUG_  1 */  
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ 
+ #include <linux/module.h>
+ #include <linux/init.h>
+--- linux-2.6.0-test6/drivers/media/video/c-qcam.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/c-qcam.c	2003-10-05 00:33:24.000000000 -0700
+@@ -33,7 +33,6 @@
+ #include <linux/mm.h>
+ #include <linux/parport.h>
+ #include <linux/sched.h>
+-#include <linux/version.h>
+ #include <linux/videodev.h>
+ #include <asm/semaphore.h>
+ #include <asm/uaccess.h>
+--- linux-2.6.0-test6/drivers/media/video/meye.h	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/meye.h	2003-10-05 00:33:24.000000000 -0700
+@@ -36,8 +36,6 @@
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/sonypi.h>
+-#include <linux/meye.h>
+ 
+ /****************************************************************************/
+ /* Motion JPEG chip registers                                               */
+--- linux-2.6.0-test6/drivers/media/video/planb.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/planb.c	2003-10-05 00:33:24.000000000 -0700
+@@ -27,7 +27,6 @@
+ 
+ /* $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $ */
+ 
+-#include <linux/version.h>
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/media/video/pms.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/pms.c	2003-10-05 00:33:24.000000000 -0700
+@@ -30,7 +30,6 @@
+ #include <asm/io.h>
+ #include <linux/sched.h>
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ 
+--- linux-2.6.0-test6/drivers/media/video/saa7110.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/saa7110.c	2003-10-05 00:33:24.000000000 -0700
+@@ -25,8 +25,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+--- linux-2.6.0-test6/drivers/media/video/saa7111.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/saa7111.c	2003-10-05 00:33:24.000000000 -0700
+@@ -24,8 +24,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -45,7 +43,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
+--- linux-2.6.0-test6/drivers/media/video/saa7114.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/saa7114.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,8 +28,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -51,7 +49,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
+--- linux-2.6.0-test6/drivers/media/video/saa7134/saa7134.h	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/saa7134/saa7134.h	2003-10-05 00:33:24.000000000 -0700
+@@ -18,6 +18,7 @@
+  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
++#include <linux/version.h>
+ #include <linux/pci.h>
+ #include <linux/i2c.h>
+ #include <linux/videodev.h>
+--- linux-2.6.0-test6/drivers/media/video/saa7185.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/saa7185.c	2003-10-05 00:33:24.000000000 -0700
+@@ -24,8 +24,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+-
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+@@ -45,7 +43,6 @@
+ #include <linux/types.h>
+ 
+ #include <linux/videodev.h>
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
+--- linux-2.6.0-test6/drivers/media/video/stradis.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/stradis.c	2003-10-05 00:33:24.000000000 -0700
+@@ -20,7 +20,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/fs.h>
+--- linux-2.6.0-test6/drivers/media/video/tuner-3036.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/tuner-3036.c	2003-10-05 00:33:24.000000000 -0700
+@@ -21,7 +21,6 @@
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/slab.h>
+-#include <linux/version.h>
+ #include <linux/init.h>
+ 
+ #include <linux/i2c.h>
+--- linux-2.6.0-test6/drivers/media/video/v4l2-common.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/media/video/v4l2-common.c	2003-10-05 00:33:24.000000000 -0700
+@@ -45,7 +45,6 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/drivers/media/video/videocodec.c	2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/media/video/videocodec.c	2003-10-05 00:33:24.000000000 -0700
+@@ -29,7 +29,6 @@
+ 
+ #define VIDEOCODEC_VERSION "v0.2"
+ 
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+--- linux-2.6.0-test6/drivers/media/video/videodev.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/videodev.c	2003-10-05 00:33:24.000000000 -0700
+@@ -15,7 +15,6 @@
+  *		- Added procfs support
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+@@ -27,7 +26,6 @@
+ #include <linux/init.h>
+ #include <linux/kmod.h>
+ #include <linux/slab.h>
+-#include <linux/types.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -52,7 +50,7 @@ static ssize_t show_dev(struct class_dev
+ {
+ 	struct video_device *vfd = container_of(cd, struct video_device, class_dev);
+ 	dev_t dev = MKDEV(VIDEO_MAJOR, vfd->minor);
+-	return sprintf(buf,"%04x\n",old_encode_dev(dev));
++	return print_dev_t(buf,dev);
+ }
+ 
+ static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+--- linux-2.6.0-test6/drivers/media/video/vpx3220.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/vpx3220.c	2003-10-05 00:33:24.000000000 -0700
+@@ -18,7 +18,6 @@
+  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+--- linux-2.6.0-test6/drivers/media/video/zoran_card.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/zoran_card.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/media/video/zoran_device.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/zoran_device.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/media/video/zoran_procfs.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/video/zoran_procfs.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ 
+ #include <linux/config.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/media/video/zr36120.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/video/zr36120.c	2003-10-05 00:33:24.000000000 -0700
+@@ -36,7 +36,6 @@
+ #include <linux/sched.h>
+ #include <linux/video_decoder.h>
+ 
+-#include <linux/version.h>
+ #include <asm/uaccess.h>
+ 
+ #include "tuner.h"
+--- linux-2.6.0-test6/drivers/media/video/zr36120_i2c.c	2003-06-14 12:18:52.000000000 -0700
++++ 25/drivers/media/video/zr36120_i2c.c	2003-10-05 00:33:24.000000000 -0700
+@@ -22,7 +22,6 @@
+ #include <linux/delay.h>
+ #include <asm/io.h>
+ 
+-#include <linux/version.h>
+ #include <linux/video_decoder.h>
+ #include <asm/uaccess.h>
+ 
+--- linux-2.6.0-test6/drivers/message/i2o/i2o_block.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/message/i2o/i2o_block.c	2003-10-05 00:34:01.000000000 -0700
+@@ -885,10 +885,10 @@ static void i2o_block_biosparam(
+  *	Issue device specific ioctl calls.
+  */
+ 
+-static int i2ob_ioctl(struct inode *inode, struct file *file,
++static int i2ob_ioctl(struct block_device *bdev, struct file *file,
+ 		     unsigned int cmd, unsigned long arg)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct i2ob_device *dev = disk->private_data;
+ 
+ 	/* Anyone capable of this syscall can do *real bad* things */
+@@ -901,7 +901,7 @@ static int i2ob_ioctl(struct inode *inod
+ 			struct hd_geometry g;
+ 			i2o_block_biosparam(get_capacity(disk), 
+ 					&g.cylinders, &g.heads, &g.sectors);
+-			g.start = get_start_sect(inode->i_bdev);
++			g.start = get_start_sect(bdev);
+ 			return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
+ 		}
+ 		
+@@ -927,9 +927,8 @@ static int i2ob_ioctl(struct inode *inod
+  *	Close the block device down
+  */
+  
+-static int i2ob_release(struct inode *inode, struct file *file)
++static int i2ob_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct i2ob_device *dev = disk->private_data;
+ 
+ 	/*
+@@ -999,9 +998,9 @@ static int i2ob_release(struct inode *in
+  *	Open the block device.
+  */
+  
+-static int i2ob_open(struct inode *inode, struct file *file)
++static int i2ob_open(struct block_device *bdev, struct file *file)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct i2ob_device *dev = disk->private_data;
+ 
+ 	if(!dev->i2odev)	
+--- linux-2.6.0-test6/drivers/mtd/chips/cfi_cmdset_0020.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/mtd/chips/cfi_cmdset_0020.c	2003-10-05 00:33:24.000000000 -0700
+@@ -17,6 +17,7 @@
+  *	- added a writev function
+  */
+ 
++#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+@@ -26,7 +27,6 @@
+ #include <asm/byteorder.h>
+ 
+ #include <linux/errno.h>
+-#include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+@@ -208,6 +208,7 @@ static struct mtd_info *cfi_staa_setup(s
+ 	if (!mtd->eraseregions) { 
+ 		printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
+ 		kfree(cfi->cmdset_priv);
++		kfree(mtd);
+ 		return NULL;
+ 	}
+ 	
+@@ -232,6 +233,7 @@ static struct mtd_info *cfi_staa_setup(s
+ 			printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
+ 			kfree(mtd->eraseregions);
+ 			kfree(cfi->cmdset_priv);
++			kfree(mtd);
+ 			return NULL;
+ 		}
+ 
+--- linux-2.6.0-test6/drivers/mtd/chips/gen_probe.c	2003-07-02 14:53:14.000000000 -0700
++++ 25/drivers/mtd/chips/gen_probe.c	2003-10-05 00:33:24.000000000 -0700
+@@ -11,7 +11,6 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/cfi.h>
+-#include <linux/mtd/mtd.h>
+ #include <linux/mtd/gen_probe.h>
+ 
+ static struct mtd_info *check_cmd_set(struct map_info *, int);
+--- linux-2.6.0-test6/drivers/mtd/chips/map_rom.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/mtd/chips/map_rom.c	2003-10-05 00:33:24.000000000 -0700
+@@ -4,7 +4,6 @@
+  * $Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/drivers/mtd/chips/sharp.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/mtd/chips/sharp.c	2003-10-05 00:33:24.000000000 -0700
+@@ -22,7 +22,6 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+--- linux-2.6.0-test6/drivers/mtd/devices/lart.c	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/mtd/devices/lart.c	2003-10-05 00:33:24.000000000 -0700
+@@ -42,7 +42,6 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+-#include <linux/version.h>
+ #include <linux/errno.h>
+ #include <linux/mtd/mtd.h>
+ #ifdef HAVE_PARTITIONS
+--- linux-2.6.0-test6/drivers/mtd/devices/pmc551.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/drivers/mtd/devices/pmc551.c	2003-10-05 00:33:24.000000000 -0700
+@@ -82,6 +82,7 @@
+  *       * Comb the init routine.  It's still a bit cludgy on a few things.
+  */
+ 
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/mtd/maps/integrator-flash.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/drivers/mtd/maps/integrator-flash.c	2003-10-05 00:33:24.000000000 -0700
+@@ -31,223 +31,181 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/ioport.h>
++#include <linux/device.h>
+ #include <linux/init.h>
+ 
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ 
++#include <asm/mach/flash.h>
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/system.h>
+ 
+-// board specific stuff - sorry, it should be in arch/arm/mach-*.
+-#ifdef CONFIG_ARCH_INTEGRATOR
+-
+-#define FLASH_BASE	INTEGRATOR_FLASH_BASE
+-#define FLASH_SIZE	INTEGRATOR_FLASH_SIZE
+-
+-#define FLASH_PART_SIZE 0x400000
+-
+-#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+-#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+-#define EBI_CSR1	(IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
+-#define EBI_LOCK	(IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
+-
+-/*
+- * Initialise the flash access systems:
+- *  - Disable VPP
+- *  - Assert WP
+- *  - Set write enable bit in EBI reg
+- */
+-static void armflash_flash_init(void)
+-{
+-	unsigned int tmp;
+-
+-	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+-
+-	tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
+-	__raw_writel(tmp, EBI_CSR1);
+-
+-	if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
+-		__raw_writel(0xa05f, EBI_LOCK);
+-		__raw_writel(tmp, EBI_CSR1);
+-		__raw_writel(0, EBI_LOCK);
+-	}
+-}
+-
+-/*
+- * Shutdown the flash access systems:
+- *  - Disable VPP
+- *  - Assert WP
+- *  - Clear write enable bit in EBI reg
+- */
+-static void armflash_flash_exit(void)
+-{
+-	unsigned int tmp;
+-
+-	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+-
+-	/*
+-	 * Clear the write enable bit in system controller EBI register.
+-	 */
+-	tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
+-	__raw_writel(tmp, EBI_CSR1);
+-
+-	if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
+-		__raw_writel(0xa05f, EBI_LOCK);
+-		__raw_writel(tmp, EBI_CSR1);
+-		__raw_writel(0, EBI_LOCK);
+-	}
+-}
+-
+-static void armflash_flash_wp(int on)
+-{
+-	unsigned int reg;
+-
+-	if (on)
+-		reg = SC_CTRLC;
+-	else
+-		reg = SC_CTRLS;
+-
+-	__raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
+-}
+-
+-static void armflash_set_vpp(struct map_info *map, int on)
+-{
+-	unsigned int reg;
+-
+-	if (on)
+-		reg = SC_CTRLS;
+-	else
+-		reg = SC_CTRLC;
+-
+-	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
+-}
+-#endif
+-
+ #ifdef CONFIG_ARCH_P720T
+-
+ #define FLASH_BASE		(0x04000000)
+ #define FLASH_SIZE		(64*1024*1024)
++#endif
+ 
+-#define FLASH_PART_SIZE 	(4*1024*1024)
+-#define FLASH_BLOCK_SIZE	(128*1024)
++struct armflash_info {
++	struct flash_platform_data *plat;
++	struct resource		*res;
++	struct mtd_partition	*parts;
++	struct mtd_info		*mtd;
++	struct map_info		map;
++};
+ 
+-static void armflash_flash_init(void)
++static void armflash_set_vpp(struct map_info *map, int on)
+ {
+-}
++	struct armflash_info *info = container_of(map, struct armflash_info, map);
+ 
+-static void armflash_flash_exit(void)
+-{
++	if (info->plat && info->plat->set_vpp)
++		info->plat->set_vpp(on);
+ }
+ 
+-static void armflash_flash_wp(int on)
+-{
+-}
++static const char *probes[] = { "RedBoot", "afs", NULL };
+ 
+-static void armflash_set_vpp(struct map_info *map, int on)
++static int armflash_probe(struct device *_dev)
+ {
+-}
+-#endif
++	struct platform_device *dev = to_platform_device(_dev);
++	struct flash_platform_data *plat = dev->dev.platform_data;
++	struct resource *res = dev->resource;
++	unsigned int size = res->end - res->start + 1;
++	struct armflash_info *info;
++	int err;
++	void *base;
+ 
++	info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL);
++	if (!info) {
++		err = -ENOMEM;
++		goto out;
++	}
+ 
+-static struct map_info armflash_map =
+-{
+-	.name =		"AFS",
+-	.set_vpp =	armflash_set_vpp,
+-	.phys =		FLASH_BASE,
+-};
++	memset(info, 0, sizeof(struct armflash_info));
+ 
+-static struct mtd_info *mtd;
+-static struct mtd_partition *parts;
+-static const char *probes[] = { "RedBoot", "afs", NULL };
++	info->plat = plat;
++	if (plat && plat->init) {
++		err = plat->init();
++		if (err)
++			goto no_resource;
++	}
+ 
+-static int __init armflash_cfi_init(void *base, u_int size)
+-{
+-	int ret;
++	info->res = request_mem_region(res->start, size, "armflash");
++	if (!info->res) {
++		err = -EBUSY;
++		goto no_resource;
++	}
+ 
+-	armflash_flash_init();
+-	armflash_flash_wp(1);
++	base = ioremap(res->start, size);
++	if (!base) {
++		err = -ENOMEM;
++		goto no_mem;
++	}
+ 
+ 	/*
+ 	 * look for CFI based flash parts fitted to this board
+ 	 */
+-	armflash_map.size       = size;
+-	armflash_map.buswidth   = 4;
+-	armflash_map.virt = (unsigned long) base;
++	info->map.size		= size;
++	info->map.buswidth	= plat->width;
++	info->map.phys		= res->start;
++	info->map.virt		= (unsigned long) base;
++	info->map.name		= dev->dev.bus_id;
++	info->map.set_vpp	= armflash_set_vpp;
+ 
+-	simple_map_init(&armflash_map);
++	simple_map_init(&info->map);
+ 
+ 	/*
+ 	 * Also, the CFI layer automatically works out what size
+ 	 * of chips we have, and does the necessary identification
+ 	 * for us automatically.
+ 	 */
+-	mtd = do_map_probe("cfi_probe", &armflash_map);
+-	if (!mtd)
+-		return -ENXIO;
+-
+-	mtd->owner = THIS_MODULE;
+-
+-	ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0);
+-	if (ret > 0) {
+-		ret = add_mtd_partitions(mtd, parts, ret);
+-		if (ret)
+-			printk(KERN_ERR "mtd partition registration "
+-				"failed: %d\n", ret);
++	info->mtd = do_map_probe(plat->map_name, &info->map);
++	if (!info->mtd) {
++		err = -ENXIO;
++		goto no_device;
+ 	}
+ 
++	info->mtd->owner = THIS_MODULE;
++
++	err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
++	if (err > 0) {
++		err = add_mtd_partitions(info->mtd, info->parts, err);
++		if (err)
++			printk(KERN_ERR
++			       "mtd partition registration failed: %d\n", err);
++	}
++
++	if (err == 0)
++		dev_set_drvdata(&dev->dev, info);
++
+ 	/*
+ 	 * If we got an error, free all resources.
+ 	 */
+-	if (ret < 0) {
+-		del_mtd_partitions(mtd);
+-		map_destroy(mtd);
+-	}
++	if (err < 0) {
++		if (info->mtd) {
++			del_mtd_partitions(info->mtd);
++			map_destroy(info->mtd);
++		}
++		if (info->parts)
++			kfree(info->parts);
+ 
+-	return ret;
+-}
+-
+-static void armflash_cfi_exit(void)
+-{
+-	if (mtd) {
+-		del_mtd_partitions(mtd);
+-		map_destroy(mtd);
++ no_device:
++		iounmap(base);
++ no_mem:
++		release_mem_region(res->start, size);
++ no_resource:
++		if (plat && plat->exit)
++			plat->exit();
++		kfree(info);
+ 	}
+-	if (parts)
+-		kfree(parts);
++ out:
++	return err;
+ }
+ 
+-static int __init armflash_init(void)
++static int armflash_remove(struct device *_dev)
+ {
+-	int err = -EBUSY;
+-	void *base;
++	struct platform_device *dev = to_platform_device(_dev);
++	struct armflash_info *info = dev_get_drvdata(&dev->dev);
+ 
+-	if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
+-		goto out;
++	dev_set_drvdata(&dev->dev, NULL);
+ 
+-	base = ioremap(FLASH_BASE, FLASH_SIZE);
+-	err = -ENOMEM;
+-	if (base == NULL)
+-		goto release;
++	if (info) {
++		if (info->mtd) {
++			del_mtd_partitions(info->mtd);
++			map_destroy(info->mtd);
++		}
++		if (info->parts)
++			kfree(info->parts);
+ 
+-	err = armflash_cfi_init(base, FLASH_SIZE);
+-	if (err) {
+-		iounmap(base);
+-release:
+-		release_mem_region(FLASH_BASE, FLASH_SIZE);
++		iounmap((void *)info->map.virt);
++		release_resource(info->res);
++		kfree(info->res);
++
++		if (info->plat && info->plat->exit)
++			info->plat->exit();
++
++		kfree(info);
+ 	}
+-out:
+-	return err;
++
++	return 0;
++}
++
++static struct device_driver armflash_driver = {
++	.name		= "armflash",
++	.bus		= &platform_bus_type,
++	.probe		= armflash_probe,
++	.remove		= armflash_remove,
++};
++
++static int __init armflash_init(void)
++{
++	return driver_register(&armflash_driver);
+ }
+ 
+ static void __exit armflash_exit(void)
+ {
+-	armflash_cfi_exit();
+-	iounmap((void *)armflash_map.virt);
+-	release_mem_region(FLASH_BASE, FLASH_SIZE);
+-	armflash_flash_exit();
++	driver_unregister(&armflash_driver);
+ }
+ 
+ module_init(armflash_init);
+--- linux-2.6.0-test6/drivers/mtd/maps/sun_uflash.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/mtd/maps/sun_uflash.c	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/fs.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+--- linux-2.6.0-test6/drivers/mtd/mtd_blkdevs.c	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/mtd/mtd_blkdevs.c	2003-10-05 00:34:01.000000000 -0700
+@@ -141,14 +141,12 @@ static void mtd_blktrans_request(struct 
+ }
+ 
+ 
+-int blktrans_open(struct inode *i, struct file *f)
++static int blktrans_open(struct block_device *bdev, struct file *f)
+ {
+-	struct mtd_blktrans_dev *dev;
+-	struct mtd_blktrans_ops *tr;
++	struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
++	struct mtd_blktrans_ops *tr = dev->tr;
+ 	int ret = -ENODEV;
+ 
+-	dev = i->i_bdev->bd_disk->private_data;
+-	tr = dev->tr;
+ 
+ 	if (!try_module_get(dev->mtd->owner))
+ 		goto out;
+@@ -172,15 +170,12 @@ int blktrans_open(struct inode *i, struc
+ 	return ret;
+ }
+ 
+-int blktrans_release(struct inode *i, struct file *f)
++static int blktrans_release(struct gendisk *disk)
+ {
+-	struct mtd_blktrans_dev *dev;
+-	struct mtd_blktrans_ops *tr;
++	struct mtd_blktrans_dev *dev = disk->private_data;
++	struct mtd_blktrans_ops *tr = dev->tr;
+ 	int ret = 0;
+ 
+-	dev = i->i_bdev->bd_disk->private_data;
+-	tr = dev->tr;
+-
+ 	if (tr->release)
+ 		ret = tr->release(dev);
+ 
+@@ -194,10 +189,10 @@ int blktrans_release(struct inode *i, st
+ }
+ 
+ 
+-static int blktrans_ioctl(struct inode *inode, struct file *file, 
++static int blktrans_ioctl(struct block_device *bdev, struct file *file, 
+ 			      unsigned int cmd, unsigned long arg)
+ {
+-	struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
++	struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+ 	struct mtd_blktrans_ops *tr = dev->tr;
+ 
+ 	switch (cmd) {
+@@ -217,7 +212,7 @@ static int blktrans_ioctl(struct inode *
+ 			if (ret)
+ 				return ret;
+ 
+-			g.start = get_start_sect(inode->i_bdev);
++			g.start = get_start_sect(bdev);
+ 			if (copy_to_user((void *)arg, &g, sizeof(g)))
+ 				return -EFAULT;
+ 			return 0;
+--- linux-2.6.0-test6/drivers/mtd/mtdcore.c	2003-06-14 12:18:20.000000000 -0700
++++ 25/drivers/mtd/mtdcore.c	2003-10-05 00:33:24.000000000 -0700
+@@ -6,6 +6,7 @@
+  *
+  */
+ 
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/drivers/mtd/nand/autcpu12.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/mtd/nand/autcpu12.c	2003-10-05 00:33:24.000000000 -0700
+@@ -27,6 +27,7 @@
+  *	10-06-2002 TG	128K card support added
+  */
+ 
++#include <linux/version.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+--- linux-2.6.0-test6/drivers/net/3c523.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/3c523.c	2003-10-05 00:33:24.000000000 -0700
+@@ -102,7 +102,7 @@
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/ethtool.h>
+ 
+ #include <asm/uaccess.h>
+--- linux-2.6.0-test6/drivers/net/3c527.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/3c527.c	2003-10-05 00:33:24.000000000 -0700
+@@ -92,7 +92,7 @@ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELD
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+ #include <linux/interrupt.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/ioport.h>
+ #include <linux/in.h>
+ #include <linux/skbuff.h>
+--- linux-2.6.0-test6/drivers/net/3c59x.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/3c59x.c	2003-10-05 00:33:46.000000000 -0700
+@@ -1063,6 +1063,22 @@ static int __devinit vortex_init_one (st
+ 	return rc;
+ }
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void vortex_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	vortex_interrupt(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++
++static void boomerang_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	boomerang_interrupt(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++#endif
++
+ /*
+  * Start up the PCI/EISA device which is described by *gendev.
+  * Return 0 on success.
+@@ -1450,6 +1466,13 @@ static int __devinit vortex_probe1(struc
+ 	dev->set_multicast_list = set_rx_mode;
+ 	dev->tx_timeout = vortex_tx_timeout;
+ 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	if (vp->full_bus_master_tx)
++		dev->poll_controller = boomerang_rx_poll;
++	else
++		dev->poll_controller = vortex_rx_poll;
++#endif
++
+ 	if (pdev) {
+ 		vp->pm_state_valid = 1;
+  		pci_save_state(VORTEX_PCI(vp), vp->power_state);
+--- linux-2.6.0-test6/drivers/net/8139too.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/8139too.c	2003-10-05 00:34:34.000000000 -0700
+@@ -248,6 +248,7 @@ static struct pci_device_id rtl8139_pci_
+ 	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+ 	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+ 	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
++	{0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+ 
+ #ifdef CONFIG_SH_SECUREEDGE5410
+ 	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
+--- linux-2.6.0-test6/drivers/net/arcnet/com20020.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/arcnet/com20020.c	2003-10-05 00:33:24.000000000 -0700
+@@ -180,10 +180,6 @@ int com20020_found(struct net_device *de
+ 	if (!dev->dev_addr[0])
+ 		dev->dev_addr[0] = inb(ioaddr + 8);	/* FIXME: do this some other way! */
+ 
+-	/* reserve the I/O region */
+-	if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)"))
+-		return -EBUSY;
+-
+ 	SET_SUBADR(SUB_SETUP1);
+ 	outb(lp->setup, _XREG);
+ 
+@@ -207,7 +203,6 @@ int com20020_found(struct net_device *de
+ 	if (request_irq(dev->irq, &arcnet_interrupt, shared,
+ 			"arcnet (COM20020)", dev)) {
+ 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+-		release_region(ioaddr, ARCNET_TOTAL_SIZE);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -227,7 +222,6 @@ int com20020_found(struct net_device *de
+ 	       clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
+ 
+ 	if (!dev->init && register_netdev(dev)) {
+-		release_region(ioaddr, ARCNET_TOTAL_SIZE);
+ 		free_irq(dev->irq, dev);
+ 		return -EIO;
+ 	}
+@@ -342,7 +336,6 @@ void com20020_remove(struct net_device *
+ {
+ 	unregister_netdev(dev);
+ 	free_irq(dev->irq, dev);
+-	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ 	kfree(dev->priv);
+ 	free_netdev(dev);
+ }
+--- linux-2.6.0-test6/drivers/net/arcnet/com20020-isa.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/arcnet/com20020-isa.c	2003-10-05 00:33:24.000000000 -0700
+@@ -53,6 +53,7 @@ static int __init com20020isa_probe(stru
+ 	int ioaddr;
+ 	unsigned long airqmask;
+ 	struct arcnet_local *lp = dev->priv;
++	int err;
+ 
+ 	BUGLVL(D_NORMAL) printk(VERSION);
+ 
+@@ -62,17 +63,20 @@ static int __init com20020isa_probe(stru
+ 		       "must specify the base address!\n");
+ 		return -ENODEV;
+ 	}
+-	if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
++	if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
+ 		BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
+ 		       ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+ 		return -ENXIO;
+ 	}
+ 	if (ASTATUS() == 0xFF) {
+ 		BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
+-		return -ENODEV;
++		err = -ENODEV;
++		goto out;
++	}
++	if (com20020_check(dev)) {
++		err = -ENODEV;
++		goto out;
+ 	}
+-	if (com20020_check(dev))
+-		return -ENODEV;
+ 
+ 	if (!dev->irq) {
+ 		/* if we do this, we're sure to get an IRQ since the
+@@ -96,13 +100,21 @@ static int __init com20020isa_probe(stru
+ 			dev->irq = probe_irq_off(airqmask);
+ 			if (dev->irq <= 0) {
+ 				BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
+-				return -ENODEV;
++				err = -ENODEV;
++				goto out;
+ 			}
+ 		}
+ 	}
+ 
+ 	lp->card_name = "ISA COM20020";
+-	return com20020_found(dev, 0);
++	if ((err = com20020_found(dev, 0)) != 0)
++		goto out;
++
++	return 0;
++
++out:
++	release_region(ioaddr, ARCNET_TOTAL_SIZE);
++	return err;
+ }
+ 
+ 
+@@ -170,6 +182,7 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+ 	com20020_remove(my_dev);
++	release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
+ }
+ 
+ #else
+--- linux-2.6.0-test6/drivers/net/arcnet/com20020-pci.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/arcnet/com20020-pci.c	2003-10-05 00:33:24.000000000 -0700
+@@ -115,20 +115,20 @@ static int __devinit com20020pci_probe(s
+ 		BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
+ 		       "but seems empty!\n", ioaddr);
+ 		err = -EIO;
+-		goto out_priv;
++		goto out_port;
+ 	}
+ 	if (com20020_check(dev)) {
+ 		err = -EIO;
+-		goto out_priv;
++		goto out_port;
+ 	}
+ 
+-	release_region(ioaddr, ARCNET_TOTAL_SIZE);
+-
+ 	if ((err = com20020_found(dev, SA_SHIRQ)) != 0)
+-	        goto out_priv;
++	        goto out_port;
+ 
+ 	return 0;
+ 
++out_port:
++	release_region(ioaddr, ARCNET_TOTAL_SIZE);
+ out_priv:
+ 	kfree(dev->priv);
+ out_dev:
+@@ -138,7 +138,9 @@ out_dev:
+ 
+ static void __devexit com20020pci_remove(struct pci_dev *pdev)
+ {
+-	com20020_remove(pci_get_drvdata(pdev));
++	struct net_device *dev = pci_get_drvdata(pdev);
++	com20020_remove(dev);
++	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ }
+ 
+ static struct pci_device_id com20020pci_id_table[] = {
+--- linux-2.6.0-test6/drivers/net/at1700.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/drivers/net/at1700.c	2003-10-05 00:33:24.000000000 -0700
+@@ -43,7 +43,7 @@
+ #include <linux/errno.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+--- linux-2.6.0-test6/drivers/net/e100/e100_main.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e100/e100_main.c	2003-10-05 00:33:46.000000000 -0700
+@@ -539,6 +539,15 @@ e100_trigger_SWI(struct e100_private *bd
+ 	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */
+ }
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void e100_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	e100intr(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++#endif
++
+ static int __devinit
+ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+ {
+@@ -631,7 +640,9 @@ e100_found1(struct pci_dev *pcid, const 
+ 	dev->set_multicast_list = &e100_set_multi;
+ 	dev->set_mac_address = &e100_set_mac;
+ 	dev->do_ioctl = &e100_ioctl;
+-
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = e100_rx_poll;
++#endif
+ 	if (bdp->flags & USE_IPCB)
+ 	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ 			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+--- linux-2.6.0-test6/drivers/net/eepro100.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/eepro100.c	2003-10-05 00:33:47.000000000 -0700
+@@ -543,6 +543,7 @@ static void speedo_refill_rx_buffers(str
+ static int speedo_rx(struct net_device *dev);
+ static void speedo_tx_buffer_gc(struct net_device *dev);
+ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
++static void poll_speedo (struct net_device *dev);
+ static int speedo_close(struct net_device *dev);
+ static struct net_device_stats *speedo_get_stats(struct net_device *dev);
+ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -885,6 +886,9 @@ static int __devinit speedo_found1(struc
+ 	dev->get_stats = &speedo_get_stats;
+ 	dev->set_multicast_list = &set_rx_mode;
+ 	dev->do_ioctl = &speedo_ioctl;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = &poll_speedo;
++#endif
+ 
+ 	if (register_netdevice(dev))
+ 		goto err_free_unlock;
+@@ -1675,6 +1679,22 @@ static irqreturn_t speedo_interrupt(int 
+ 	return IRQ_RETVAL(handled);
+ }
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_speedo (struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	speedo_interrupt (dev->irq, dev, NULL);
++	enable_irq(dev->irq);
++}
++#endif
++
+ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
+ {
+ 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
+--- linux-2.6.0-test6/drivers/net/eexpress.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/eexpress.c	2003-10-05 00:33:24.000000000 -0700
+@@ -113,7 +113,6 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+-#include <linux/mca.h>
+ #include <linux/mca-legacy.h>
+ #include <linux/spinlock.h>
+ 
+--- linux-2.6.0-test6/drivers/net/ibmlana.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ibmlana.c	2003-10-05 00:33:24.000000000 -0700
+@@ -82,7 +82,7 @@ History:
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/time.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+--- linux-2.6.0-test6/drivers/net/irda/act200l.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/act200l.c	2003-10-05 00:33:24.000000000 -0700
+@@ -84,12 +84,12 @@ static int  act200l_change_speed(struct 
+ #define ACT200L_OSCL    0x04 /* oscillator in low power, medium accuracy mode */
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_ACT200L_DONGLE,
+-	act200l_open,
+-	act200l_close,
+-	act200l_reset,
+-	act200l_change_speed,
++	.type = IRDA_ACT200L_DONGLE,
++	.open = act200l_open,
++	.close = act200l_close,
++	.reset = act200l_reset,
++	.change_speed = act200l_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init act200l_init(void)
+@@ -112,8 +112,6 @@ static void act200l_open(dongle_t *self,
+ 	/* Set the speeds we can accept */
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ 	qos->min_turn_time.bits = 0x03;
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void act200l_close(dongle_t *self)
+@@ -122,8 +120,6 @@ static void act200l_close(dongle_t *self
+ 
+ 	/* Power off the dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/actisys.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/actisys.c	2003-10-05 00:33:24.000000000 -0700
+@@ -64,21 +64,21 @@ static __u32 baud_rates[] = { 9600, 1920
+ #define MAX_SPEEDS 5
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_ACTISYS_DONGLE,
+-	actisys_open,
+-	actisys_close,
+-	actisys_reset,
+-	actisys_change_speed,
++	.type = IRDA_ACTISYS_DONGLE,
++	.open = actisys_open,
++	.close = actisys_close,
++	.reset = actisys_reset,
++	.change_speed = actisys_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ static struct dongle_reg dongle_plus = {
+-	Q_NULL,
+-	IRDA_ACTISYS_PLUS_DONGLE,
+-	actisys_open,
+-	actisys_close,
+-	actisys_reset,
+-	actisys_change_speed,
++	.type = IRDA_ACTISYS_PLUS_DONGLE,
++	.open = actisys_open,
++	.close = actisys_close,
++	.reset = actisys_reset,
++	.change_speed = actisys_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ /*
+@@ -128,16 +128,12 @@ static void actisys_open(dongle_t *self,
+ 		qos->baud_rate.bits &= ~IR_38400;
+ 	
+ 	qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void actisys_close(dongle_t *self)
+ {
+ 	/* Power off the dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/ali-ircc.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/ali-ircc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -254,7 +254,7 @@ static int ali_ircc_open(int i, chipio_t
+ 	if ((ali_ircc_setup(info)) == -1)
+ 		return -1;
+ 		
+-	dev = alloc_netdev(sizeof(*self), "irda%d", irda_device_setup);
++	dev = alloc_irdadev(sizeof(*self));
+ 	if (dev == NULL) {
+ 		ERROR("%s(), can't allocate memory for control block!\n", __FUNCTION__);
+ 		return -ENOMEM;
+--- linux-2.6.0-test6/drivers/net/irda/donauboe.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/donauboe.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1598,8 +1598,7 @@ toshoboe_open (struct pci_dev *pci_dev, 
+   if ((err=pci_enable_device(pci_dev)))
+     return err;
+ 
+-  dev = alloc_netdev(sizeof (struct toshoboe_cb), "irda%d",
+-		     irda_device_setup);
++  dev = alloc_irdadev(sizeof (struct toshoboe_cb));
+   if (dev == NULL)
+     {
+       printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
+--- linux-2.6.0-test6/drivers/net/irda/ep7211_ir.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/ep7211_ir.c	2003-10-05 00:33:24.000000000 -0700
+@@ -24,12 +24,12 @@ static int  ep7211_ir_change_speed(struc
+ static int  ep7211_ir_reset(struct irda_task *task);
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_EP7211_IR,
+-	ep7211_ir_open,
+-	ep7211_ir_close,
+-	ep7211_ir_reset,
+-	ep7211_ir_change_speed,
++	.type = IRDA_EP7211_IR,
++	.open = ep7211_ir_open,
++	.close = ep7211_ir_close,
++	.reset = ep7211_ir_reset,
++	.change_speed = ep7211_ir_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
+@@ -47,8 +47,6 @@ static void ep7211_ir_open(dongle_t *sel
+ 		UART (interrupt #14). */
+ 
+ 	restore_flags(flags);
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void ep7211_ir_close(dongle_t *self)
+@@ -66,8 +64,6 @@ static void ep7211_ir_close(dongle_t *se
+ 		reset them back to their original state. */
+ 
+ 	restore_flags(flags);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/esi.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/esi.c	2003-10-05 00:33:24.000000000 -0700
+@@ -44,12 +44,12 @@ static int  esi_change_speed(struct irda
+ static int  esi_reset(struct irda_task *task);
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_ESI_DONGLE,
+-	esi_open,
+-	esi_close,
+-	esi_reset,
+-	esi_change_speed,
++	.type = IRDA_ESI_DONGLE,
++	.open = esi_open,
++	.close = esi_close,
++	.reset = esi_reset,
++	.change_speed = esi_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init esi_init(void)
+@@ -66,16 +66,12 @@ static void esi_open(dongle_t *self, str
+ {
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
+ 	qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void esi_close(dongle_t *dongle)
+ {		
+ 	/* Power off dongle */
+ 	dongle->set_dtr_rts(dongle->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/girbil.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/girbil.c	2003-10-05 00:33:24.000000000 -0700
+@@ -63,12 +63,12 @@ static int  girbil_change_speed(struct i
+ #define GIRBIL_LOAD    0x51 /* Load the new baud rate value */
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_GIRBIL_DONGLE,
+-	girbil_open,
+-	girbil_close,
+-	girbil_reset,
+-	girbil_change_speed,
++	.type = IRDA_GIRBIL_DONGLE,
++	.open = girbil_open,
++	.close = girbil_close,
++	.reset = girbil_reset,
++	.change_speed = girbil_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init girbil_init(void)
+@@ -85,16 +85,12 @@ static void girbil_open(dongle_t *self, 
+ {
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ 	qos->min_turn_time.bits = 0x03;
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void girbil_close(dongle_t *self)
+ {
+ 	/* Power off dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/irda-usb.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/irda-usb.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1176,7 +1176,7 @@ static inline int irda_usb_open(struct i
+ 	memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
+ 
+ 	/* Create a network device for us */
+-	netdev = alloc_netdev(0, "irda%d",  irda_device_setup);
++	netdev = alloc_irdadev(0);
+ 	if (!netdev) {
+ 		ERROR("%s(), alloc_net_dev() failed!\n", __FUNCTION__);
+ 		return -ENOMEM;
+--- linux-2.6.0-test6/drivers/net/irda/irport.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/net/irda/irport.c	2003-10-05 00:33:24.000000000 -0700
+@@ -78,7 +78,6 @@ static inline void irport_write_wakeup(s
+ static inline int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
+ static inline void irport_receive(struct irport_cb *self);
+ 
+-static int  irport_net_init(struct net_device *dev);
+ static int  irport_net_ioctl(struct net_device *dev, struct ifreq *rq, 
+ 			     int cmd);
+ static inline int  irport_is_receiving(struct irport_cb *self);
+@@ -136,30 +135,27 @@ irport_open(int i, unsigned int iobase, 
+ {
+ 	struct net_device *dev;
+ 	struct irport_cb *self;
+-	void *ret;
+-	int err;
+ 
+ 	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
+ 
+ 	/* Lock the port that we need */
+-	ret = request_region(iobase, IO_EXTENT, driver_name);
+-	if (!ret) {
++	if (!request_region(iobase, IO_EXTENT, driver_name)) {
+ 		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
+ 			   __FUNCTION__, iobase);
+-		return NULL;
++		goto err_out1;
+ 	}
+ 
+ 	/*
+ 	 *  Allocate new instance of the driver
+ 	 */
+-	self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL);
+-	if (!self) {
++	dev = alloc_irdadev(sizeof(struct irport_cb));
++	if (!dev) {
+ 		ERROR("%s(), can't allocate memory for "
+-		      "control block!\n", __FUNCTION__);
+-		release_region(iobase, IO_EXTENT);
+-		return NULL;
++		      "irda device!\n", __FUNCTION__);
++		goto err_out2;
+ 	}
+-	memset(self, 0, sizeof(struct irport_cb));
++
++	self = dev->priv;
+ 	spin_lock_init(&self->lock);
+ 
+ 	/* Need to store self somewhere */
+@@ -189,8 +185,11 @@ irport_open(int i, unsigned int iobase, 
+ 	self->rx_buff.truesize = IRDA_SKB_MAX_MTU;
+ 	self->rx_buff.skb = __dev_alloc_skb(self->rx_buff.truesize,
+ 					    GFP_KERNEL);
+-	if (self->rx_buff.skb == NULL)
+-		return NULL;
++	if (self->rx_buff.skb == NULL) {
++		ERROR("%s(), can't allocate memory for "
++		      "receive buffer!\n", __FUNCTION__);
++		goto err_out3;
++	}
+ 	skb_reserve(self->rx_buff.skb, 1);
+ 	self->rx_buff.head = self->rx_buff.skb->data;
+ 	/* No need to memset the buffer, unless you are really pedantic */
+@@ -208,30 +207,23 @@ irport_open(int i, unsigned int iobase, 
+ 		self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+ 						      GFP_KERNEL);
+ 		if (self->tx_buff.head == NULL) {
+-			kfree_skb(self->rx_buff.skb);
+-			self->rx_buff.skb = NULL;
+-			self->rx_buff.head = NULL;
+-			return NULL;
++			ERROR("%s(), can't allocate memory for "
++			      "transmit buffer!\n", __FUNCTION__);
++			goto err_out4;
+ 		}
+ 		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+ 	}	
+ 	self->tx_buff.data = self->tx_buff.head;
+ 
+-	if (!(dev = dev_alloc("irda%d", &err))) {
+-		ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-		return NULL;
+-	}
+ 	self->netdev = dev;
+ 	/* Keep track of module usage */
+ 	SET_MODULE_OWNER(dev);
+ 
+ 	/* May be overridden by piggyback drivers */
+- 	dev->priv = (void *) self;
+ 	self->interrupt    = irport_interrupt;
+ 	self->change_speed = irport_change_speed;
+ 
+ 	/* Override the network functions we need to use */
+-	dev->init            = irport_net_init;
+ 	dev->hard_start_xmit = irport_hard_xmit;
+ 	dev->tx_timeout	     = irport_timeout;
+ 	dev->watchdog_timeo  = HZ;  /* Allow time enough for speed change */
+@@ -244,17 +236,25 @@ irport_open(int i, unsigned int iobase, 
+ 	dev->base_addr = iobase;
+ 	dev->irq = irq;
+ 
+-	rtnl_lock();
+-	err = register_netdevice(dev);
+-	rtnl_unlock();
+-	if (err) {
++	if (register_netdev(dev)) {
+ 		ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+-		return NULL;
++		goto err_out5;
+ 	}
+ 	MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n",
+ 		dev->name, iobase, irq);
+ 
+ 	return self;
++ err_out5:
++	kfree(self->tx_buff.head);
++ err_out4:
++	kfree_skb(self->rx_buff.skb);
++ err_out3:
++	free_netdev(dev);
++	dev_self[i] = NULL;
++ err_out2:
++	release_region(iobase, IO_EXTENT);
++ err_out1:
++	return NULL;
+ }
+ 
+ int irport_close(struct irport_cb *self)
+@@ -267,8 +267,7 @@ int irport_close(struct irport_cb *self)
+ 	self->dongle = NULL;
+ 	
+ 	/* Remove netdevice */
+-	if (self->netdev)
+-		unregister_netdev(self->netdev);
++	unregister_netdev(self->netdev);
+ 
+ 	/* Release the IO-port that this driver is using */
+ 	IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", 
+@@ -284,7 +283,7 @@ int irport_close(struct irport_cb *self)
+ 	
+ 	/* Remove ourselves */
+ 	dev_self[self->index] = NULL;
+-	kfree(self);
++	free_netdev(self->netdev);
+ 	
+ 	return 0;
+ }
+@@ -886,16 +885,6 @@ irqreturn_t irport_interrupt(int irq, vo
+ 	return IRQ_RETVAL(handled);
+ }
+ 
+-static int irport_net_init(struct net_device *dev)
+-{
+-	/* Set up to be a normal IrDA network device driver */
+-	irda_device_setup(dev);
+-
+-	/* Insert overrides below this line! */
+-
+-	return 0;
+-}
+-
+ /*
+  * Function irport_net_open (dev)
+  *
+--- linux-2.6.0-test6/drivers/net/irda/litelink.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/litelink.c	2003-10-05 00:33:24.000000000 -0700
+@@ -48,12 +48,12 @@ static int  litelink_reset(struct irda_t
+ static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 };
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_LITELINK_DONGLE,
+-	litelink_open,
+-	litelink_close,
+-	litelink_reset,
+-	litelink_change_speed,
++	.type = IRDA_LITELINK_DONGLE,
++	.open = litelink_open,
++	.close = litelink_close,
++	.reset = litelink_reset,
++	.change_speed = litelink_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init litelink_init(void)
+@@ -70,16 +70,12 @@ static void litelink_open(dongle_t *self
+ {
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ 	qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void litelink_close(dongle_t *self)
+ {
+ 	/* Power off dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/ma600.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/ma600.c	2003-10-05 00:33:24.000000000 -0700
+@@ -74,12 +74,12 @@ static int  ma600_reset(struct irda_task
+ #define MA600_2400	0x08
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_MA600_DONGLE,
+-	ma600_open,
+-	ma600_close,
+-	ma600_reset,
+-	ma600_change_speed,
++	.type = IRDA_MA600_DONGLE,
++	.open = ma600_open,
++	.close = ma600_close,
++	.reset = ma600_reset,
++	.change_speed = ma600_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init ma600_init(void)
+@@ -115,8 +115,6 @@ static void ma600_open(dongle_t *self, s
+ 
+ 	self->set_dtr_rts(self->dev, TRUE, TRUE);
+ 	// should wait 1 second
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void ma600_close(dongle_t *self)
+@@ -125,8 +123,6 @@ static void ma600_close(dongle_t *self)
+ 
+ 	/* Power off dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ static __u8 get_control_byte(__u32 speed)
+--- linux-2.6.0-test6/drivers/net/irda/mcp2120.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/mcp2120.c	2003-10-05 00:33:24.000000000 -0700
+@@ -40,12 +40,12 @@ static int  mcp2120_change_speed(struct 
+ #define MCP2120_COMMIT  0x11
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_MCP2120_DONGLE,
+-	mcp2120_open,
+-	mcp2120_close,
+-	mcp2120_reset,
+-	mcp2120_change_speed,
++	.type = IRDA_MCP2120_DONGLE,
++	.open = mcp2120_open,
++	.close = mcp2120_close,
++	.reset = mcp2120_reset,
++	.change_speed = mcp2120_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init mcp2120_init(void)
+@@ -62,8 +62,6 @@ static void mcp2120_open(dongle_t *self,
+ {
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ 	qos->min_turn_time.bits = 0x01;
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void mcp2120_close(dongle_t *self)
+@@ -72,8 +70,6 @@ static void mcp2120_close(dongle_t *self
+         /* reset and inhibit mcp2120 */
+ 	self->set_dtr_rts(self->dev, TRUE, TRUE);
+ 	//self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/nsc-ircc.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/nsc-ircc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -260,8 +260,7 @@ static int __init nsc_ircc_open(int i, c
+ 
+ 	MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
+ 
+-	dev = alloc_netdev(sizeof(struct nsc_ircc_cb), "irda%d",
+-			   irda_device_setup);
++	dev = alloc_irdadev(sizeof(struct nsc_ircc_cb));
+ 	if (dev == NULL) {
+ 		ERROR("%s(), can't allocate memory for "
+ 		       "control block!\n", __FUNCTION__);
+--- linux-2.6.0-test6/drivers/net/irda/old_belkin.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/old_belkin.c	2003-10-05 00:33:24.000000000 -0700
+@@ -74,12 +74,12 @@ static int  old_belkin_reset(struct irda
+ /* static __u32 baud_rates[] = { 9600 }; */
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_OLD_BELKIN_DONGLE,
+-	old_belkin_open,
+-	old_belkin_close,
+-	old_belkin_reset,
+-	old_belkin_change_speed,
++	.type = IRDA_OLD_BELKIN_DONGLE,
++	.open = old_belkin_open,
++	.close = old_belkin_close,
++	.reset = old_belkin_reset,
++	.change_speed = old_belkin_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init old_belkin_init(void)
+@@ -98,16 +98,12 @@ static void old_belkin_open(dongle_t *se
+ 	qos->baud_rate.bits &= IR_9600;
+ 	/* Needs at least 10 ms (totally wild guess, can do probably better) */
+ 	qos->min_turn_time.bits = 0x01;
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void old_belkin_close(dongle_t *self)
+ {
+ 	/* Power off dongle */
+ 	self->set_dtr_rts(self->dev, FALSE, FALSE);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/sir_dev.c	2003-07-10 18:50:31.000000000 -0700
++++ 25/drivers/net/irda/sir_dev.c	2003-10-05 00:33:24.000000000 -0700
+@@ -538,28 +538,6 @@ out:
+ 
+ /* ----------------------------------------------------------------------------- */
+ 
+-static int sirdev_init(struct net_device *ndev)
+-{
+-	struct sir_dev *dev = ndev->priv;
+-
+-	SET_MODULE_OWNER(ndev);
+-
+-	/* Set up to be a normal IrDA network device driver */
+-	irda_device_setup(ndev);
+-
+-	dev->flags = IFF_SIR | IFF_PIO;
+-
+-	/* Override the network functions we need to use */
+-	ndev->hard_start_xmit = sirdev_hard_xmit;
+-	ndev->open = sirdev_open;
+-	ndev->stop = sirdev_close;
+-	ndev->get_stats = sirdev_get_stats;
+-	ndev->do_ioctl = sirdev_ioctl;
+-
+-	return 0;
+-}
+-
+-
+ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name)
+ {
+ 	struct net_device *ndev;
+@@ -577,12 +555,12 @@ struct sir_dev * sirdev_get_instance(con
+ 	/*
+ 	 *  Allocate new instance of the device
+ 	 */
+-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+-	if (dev == NULL) {
++	ndev = alloc_irdadev(sizeof(*dev));
++	if (ndev == NULL) {
+ 		ERROR("%s - Can't allocate memory for IrDA control block!\n", __FUNCTION__);
+ 		goto out;
+ 	}
+-	memset(dev, 0, sizeof(*dev));
++	dev = ndev->priv;
+ 
+ 	irda_init_max_qos_capabilies(&dev->qos);
+ 	dev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+@@ -591,11 +569,6 @@ struct sir_dev * sirdev_get_instance(con
+ 
+ 	strncpy(dev->hwname, name, sizeof(dev->hwname)-1);
+ 
+-	ndev = kmalloc(sizeof(*ndev), GFP_KERNEL);
+-	if (ndev == NULL)
+-		goto out_freedev;
+-	memset(ndev, 0, sizeof(*ndev));
+-
+ 	atomic_set(&dev->enable_rx, 0);
+ 	dev->tx_skb = NULL;
+ 
+@@ -609,10 +582,17 @@ struct sir_dev * sirdev_get_instance(con
+ 	dev->drv = drv;
+ 	dev->netdev = ndev;
+ 
+-	ndev->priv = (void *) dev;
+-	ndev->init = sirdev_init;
++	SET_MODULE_OWNER(ndev);
++
++	dev->flags = IFF_SIR | IFF_PIO;
++
++	/* Override the network functions we need to use */
++	ndev->hard_start_xmit = sirdev_hard_xmit;
++	ndev->open = sirdev_open;
++	ndev->stop = sirdev_close;
++	ndev->get_stats = sirdev_get_stats;
++	ndev->do_ioctl = sirdev_ioctl;
+ 
+-	strcpy(ndev->name, "irda%d");
+ 	if (register_netdev(ndev)) {
+ 		ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+ 		goto out_freenetdev;
+@@ -621,9 +601,7 @@ struct sir_dev * sirdev_get_instance(con
+ 	return dev;
+ 
+ out_freenetdev:
+-	kfree(ndev);
+-out_freedev:
+-	kfree(dev);
++	free_netdev(ndev);
+ out:
+ 	return NULL;
+ }
+@@ -653,10 +631,9 @@ int sirdev_put_instance(struct sir_dev *
+ 	up(&dev->fsm.sem);
+ 
+ 	/* Remove netdevice */
+-	if (dev->netdev)
+-		unregister_netdev(dev->netdev);
++	unregister_netdev(dev->netdev);
+ 
+-	kfree(dev);
++	free_netdev(dev->netdev);
+ 
+ 	return 0;
+ }
+--- linux-2.6.0-test6/drivers/net/irda/smsc-ircc2.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/net/irda/smsc-ircc2.c	2003-10-05 00:33:24.000000000 -0700
+@@ -140,10 +140,8 @@ static const char *driver_name = "smsc-i
+ 
+ static int smsc_ircc_open(unsigned int firbase, unsigned int sirbase, u8 dma, u8 irq);
+ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base);
+-static int smsc_ircc_setup_io(struct smsc_ircc_cb *self, unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq);
+-static int smsc_ircc_setup_buffers(struct smsc_ircc_cb *self);
++static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq);
+ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self);
+-static int smsc_ircc_setup_netdev(struct smsc_ircc_cb *self);
+ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self);
+ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self);
+ static int  smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase); 
+@@ -163,7 +161,6 @@ static void smsc_ircc_sir_stop(struct sm
+ #endif
+ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self);
+ static int  smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len);
+-static int  smsc_ircc_net_init(struct net_device *dev);
+ static int  smsc_ircc_net_open(struct net_device *dev);
+ static int  smsc_ircc_net_close(struct net_device *dev);
+ static int  smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -366,38 +363,81 @@ int __init smsc_ircc_init(void)
+ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
+ {
+ 	struct smsc_ircc_cb *self;
++	struct net_device *dev;
+ 	int err;
+ 	
+ 	IRDA_DEBUG(1, "%s\n", __FUNCTION__);
+ 
+-	err= smsc_ircc_present(fir_base, sir_base);
+-	if(err) return -ENODEV;
++	err = smsc_ircc_present(fir_base, sir_base);
++	if(err) 
++		goto err_out;
+ 		
+-	if (dev_count>DIM(dev_self)) {
++	err = -ENOMEM;
++	if (dev_count > DIM(dev_self)) {
+ 	        WARNING("%s(), too many devices!\n", __FUNCTION__);
+-		return -ENOMEM;
++		goto err_out1;
+ 	}
+ 
+ 	/*
+ 	 *  Allocate new instance of the driver
+ 	 */
+-	self = kmalloc(sizeof(struct smsc_ircc_cb), GFP_KERNEL);
+-	if (self == NULL) {
+-		ERROR("%s, Can't allocate memory for control block!\n",
+-                      driver_name);
+-		return -ENOMEM;
++	dev = alloc_irdadev(sizeof(struct smsc_ircc_cb));
++	if (!dev) {
++		WARNING("%s() can't allocate net device\n", __FUNCTION__);
++		goto err_out1;
+ 	}
+-	memset(self, 0, sizeof(struct smsc_ircc_cb));
++
++	SET_MODULE_OWNER(dev);
++
++	dev->hard_start_xmit = smsc_ircc_hard_xmit_sir;
++#if SMSC_IRCC2_C_NET_TIMEOUT
++	dev->tx_timeout	     = smsc_ircc_timeout;
++	dev->watchdog_timeo  = HZ*2;  /* Allow enough time for speed change */
++#endif
++	dev->open            = smsc_ircc_net_open;
++	dev->stop            = smsc_ircc_net_close;
++	dev->do_ioctl        = smsc_ircc_net_ioctl;
++	dev->get_stats	     = smsc_ircc_net_get_stats;
++	
++	self = dev->priv;
++	self->netdev = dev;
++
++	/* Make ifconfig display some details */
++	dev->base_addr = self->io.fir_base = fir_base;
++	dev->irq = self->io.irq = irq;
+ 
+ 	/* Need to store self somewhere */
+ 	dev_self[dev_count++] = self;
+ 	spin_lock_init(&self->lock);
+ 
+-	err = smsc_ircc_setup_buffers(self);
+-	if(err) return err;
++	self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; 
++	self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE;
++
++	self->rx_buff.head = (u8 *) kmalloc(self->rx_buff.truesize,
++					      GFP_KERNEL|GFP_DMA);
++	if (self->rx_buff.head == NULL) {
++		ERROR("%s, Can't allocate memory for receive buffer!\n",
++                      driver_name);
++		goto err_out2;
++	}
++
++	self->tx_buff.head = (u8 *) kmalloc(self->tx_buff.truesize, 
++					      GFP_KERNEL|GFP_DMA);
++	if (self->tx_buff.head == NULL) {
++		ERROR("%s, Can't allocate memory for transmit buffer!\n",
++                      driver_name);
++		goto err_out3;
++	}
++
++	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
++	memset(self->tx_buff.head, 0, self->tx_buff.truesize);
++
++	self->rx_buff.in_frame = FALSE;
++	self->rx_buff.state = OUTSIDE_FRAME;
++	self->tx_buff.data = self->tx_buff.head;
++	self->rx_buff.data = self->rx_buff.head;
+ 	   
+-	err= smsc_ircc_setup_io(self, fir_base, sir_base, dma, irq);
+-	if(err) return err;
++	smsc_ircc_setup_io(self, fir_base, sir_base, dma, irq);
+ 
+ 	smsc_ircc_setup_qos(self);
+ 
+@@ -405,17 +445,38 @@ static int __init smsc_ircc_open(unsigne
+ 		
+ 	smsc_ircc_init_chip(self);
+ 	
+-	if(ircc_transceiver > 0 && ircc_transceiver < SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS) self->transceiver = ircc_transceiver;
+-	else smsc_ircc_probe_transceiver(self);
++	if(ircc_transceiver > 0  && 
++	   ircc_transceiver < SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS)
++		self->transceiver = ircc_transceiver;
++	else
++		smsc_ircc_probe_transceiver(self);
+ 
+-	err = smsc_ircc_setup_netdev(self);
+-	if(err) return err;
++	err = register_netdev(self->netdev);
++	if(err) {
++		ERROR("%s, Network device registration failed!\n",
++		      driver_name);
++		goto err_out4;
++	}
+ 
+ 	self->pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, smsc_ircc_pmproc);
+ 	if (self->pmdev)
+ 		self->pmdev->data = self;
+ 
++	MESSAGE("IrDA: Registered device %s\n", dev->name);
++
+ 	return 0;
++ err_out4:
++	kfree(self->tx_buff.head);
++ err_out3:
++	kfree(self->rx_buff.head);
++ err_out2:
++	free_netdev(self->netdev);
++	dev_self[--dev_count] = NULL;
++ err_out1:
++	release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
++	release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT);
++ err_out:
++	return err;
+ }
+ 
+ /*
+@@ -428,18 +489,19 @@ static int smsc_ircc_present(unsigned in
+ {
+ 	unsigned char low, high, chip, config, dma, irq, version;
+ 
+-	if (check_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT) < 0) {
++	if (!request_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT,
++			    driver_name)) {
+ 		WARNING("%s: can't get fir_base of 0x%03x\n",
+ 			__FUNCTION__, fir_base);
+-		return -ENODEV;
++		goto out1;
+ 	}
+-#if POSSIBLE_USED_BY_SERIAL_DRIVER
+-	if (check_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT) < 0) {
++
++	if (!request_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT,
++			    driver_name)) {
+ 		WARNING("%s: can't get sir_base of 0x%03x\n",
+ 			__FUNCTION__, sir_base);
+-		return -ENODEV;
++		goto out2;
+ 	}
+-#endif
+ 
+ 	register_bank(fir_base, 3);
+ 
+@@ -454,54 +516,19 @@ static int smsc_ircc_present(unsigned in
+ 	if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { 
+ 	        WARNING("%s(), addr 0x%04x - no device found!\n",
+ 			__FUNCTION__, fir_base);
+-		return -ENODEV;
++		goto out3;
+ 	}
+ 	MESSAGE("SMsC IrDA Controller found\n IrCC version %d.%d, "
+ 		"firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n",
+ 		chip & 0x0f, version, fir_base, sir_base, dma, irq);
+ 
+ 	return 0;
+-}
+-
+-/*
+- * Function smsc_ircc_setup_buffers(self)
+- *
+- *    Setup RX/TX buffers
+- *
+- */
+-static int smsc_ircc_setup_buffers(struct smsc_ircc_cb *self)
+-{
+-	self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; 
+-	self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE;
+-
+-	self->rx_buff.head = (u8 *) kmalloc(self->rx_buff.truesize,
+-					      GFP_KERNEL|GFP_DMA);
+-	if (self->rx_buff.head == NULL) {
+-		ERROR("%s, Can't allocate memory for receive buffer!\n",
+-                      driver_name);
+-		kfree(self);
+-		return -ENOMEM;
+-	}
+-
+-	self->tx_buff.head = (u8 *) kmalloc(self->tx_buff.truesize, 
+-					      GFP_KERNEL|GFP_DMA);
+-	if (self->tx_buff.head == NULL) {
+-		ERROR("%s, Can't allocate memory for transmit buffer!\n",
+-                      driver_name);
+-		kfree(self->rx_buff.head);
+-		kfree(self);
+-		return -ENOMEM;
+-	}
+-
+-	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+-	memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+-
+-	self->rx_buff.in_frame = FALSE;
+-	self->rx_buff.state = OUTSIDE_FRAME;
+-	self->tx_buff.data = self->tx_buff.head;
+-	self->rx_buff.data = self->rx_buff.head;
+-
+-	return 0;
++ out3:
++	release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
++ out2:
++	release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
++ out1:
++	return -ENODEV;
+ }
+ 
+ /*
+@@ -510,10 +537,11 @@ static int smsc_ircc_setup_buffers(struc
+  *    Setup I/O
+  *
+  */
+-static int smsc_ircc_setup_io(struct smsc_ircc_cb *self, unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
++static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, 
++			       unsigned int fir_base, unsigned int sir_base, 
++			       u8 dma, u8 irq)
+ {
+ 	unsigned char config, chip_dma, chip_irq;
+-	void *ret;
+ 
+ 	register_bank(fir_base, 3);
+ 	config  = inb(fir_base+IRCC_INTERFACE);
+@@ -545,27 +573,6 @@ static int smsc_ircc_setup_io(struct sms
+ 	else
+ 		self->io.dma = chip_dma;
+ 
+-	ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name);
+-	if (!ret) { 
+-		WARNING("%s(), can't get iobase of 0x%03x\n",
+-			__FUNCTION__, self->io.fir_base);
+-		kfree(self->tx_buff.head);
+-		kfree(self->rx_buff.head);
+-		kfree(self);
+-		return -ENODEV;
+-	}
+-	ret = request_region(self->io.sir_base, self->io.sir_ext, driver_name);
+-	if (!ret) { 
+-		WARNING("%s(), can't get iobase of 0x%03x\n",
+-			__FUNCTION__, self->io.sir_base);
+-		release_region(self->io.fir_base, self->io.fir_ext);
+-		kfree(self->tx_buff.head);
+-		kfree(self->rx_buff.head);
+-		kfree(self);
+-		return -ENODEV;
+-	}
+-
+-	return 0;
+ }
+ 
+ /*
+@@ -635,59 +642,6 @@ static void smsc_ircc_init_chip(struct s
+ }
+ 
+ /*
+- * Function smsc_ircc_setup_netdev(self)
+- *
+- *    Alloc and setup network device
+- *
+- */
+-static int smsc_ircc_setup_netdev(struct smsc_ircc_cb *self)
+-{
+-	struct net_device *dev;
+-	int err;
+-	/* Alloc netdev */
+-
+-	if (!(dev = dev_alloc("irda%d", &err))) {
+-		ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
+-		kfree(self->tx_buff.head);
+-		kfree(self->rx_buff.head);
+-		kfree(self);
+-		return -ENOMEM;
+-	}
+-
+-	dev->priv = (void *) self;
+-	self->netdev = dev;
+-
+-	dev->init            = smsc_ircc_net_init;
+-	dev->hard_start_xmit = smsc_ircc_hard_xmit_sir;
+-	#if SMSC_IRCC2_C_NET_TIMEOUT
+-	dev->tx_timeout	     = smsc_ircc_timeout;
+-	dev->watchdog_timeo  = HZ*2;  /* Allow enough time for speed change */
+-	#endif
+-	dev->open            = smsc_ircc_net_open;
+-	dev->stop            = smsc_ircc_net_close;
+-	dev->do_ioctl        = smsc_ircc_net_ioctl;
+-	dev->get_stats	     = smsc_ircc_net_get_stats;
+-	
+-	/* Make ifconfig display some details */
+-	dev->base_addr = self->io.fir_base;
+-	dev->irq = self->io.irq;
+-
+-	rtnl_lock();
+-	err = register_netdevice(dev);
+-	rtnl_unlock();
+-	if (err) {
+-		ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
+-		kfree(self->tx_buff.head);
+-		kfree(self->rx_buff.head);
+-		kfree(self);
+-		return -ENODEV;
+-	}
+-	MESSAGE("IrDA: Registered device %s\n", dev->name);
+-
+-	return 0;
+-}
+-
+-/*
+  * Function smsc_ircc_net_ioctl (dev, rq, cmd)
+  *
+  *    Process IOCTL commands for this device
+@@ -1571,18 +1525,6 @@ static int ircc_is_receiving(struct smsc
+ }
+ #endif /* unused */
+ 
+-static int smsc_ircc_net_init(struct net_device *dev)
+-{
+-	/* Keep track of module usage */
+-	SET_MODULE_OWNER(dev);
+-
+-	/* Set up to be a normal IrDA network device driver */
+-	irda_device_setup(dev);
+-
+-	/* Insert overrides below this line! */
+-
+-	return 0;
+-}
+ 
+ /*
+  * Function smsc_ircc_net_open (dev)
+@@ -1745,11 +1687,7 @@ static int __exit smsc_ircc_close(struct
+ 		pm_unregister(self->pmdev);
+ 
+ 	/* Remove netdevice */
+-	if (self->netdev) {
+-		rtnl_lock();
+-		unregister_netdevice(self->netdev);
+-		rtnl_unlock();
+-	}
++	unregister_netdev(self->netdev);
+ 
+ 	/* Make sure the irq handler is not exectuting */
+ 	spin_lock_irqsave(&self->lock, flags);
+@@ -1784,7 +1722,7 @@ static int __exit smsc_ircc_close(struct
+ 	if (self->rx_buff.head)
+ 		kfree(self->rx_buff.head);
+ 
+-	kfree(self);
++	free_netdev(self->netdev);
+ 
+ 	return 0;
+ }
+@@ -2269,32 +2207,36 @@ static const smsc_chip_t * __init smsc_i
+ 
+ static int __init smsc_superio_fdc(unsigned short cfg_base)
+ {
+-	if (check_region(cfg_base, 2) < 0) {
++	int ret = -1;
++
++	if (!request_region(cfg_base, 2, driver_name)) {
+ 		WARNING("%s: can't get cfg_base of 0x%03x\n",
+ 			__FUNCTION__, cfg_base);
+-		return -1;
+-	}
++	} else {
++		if (!smsc_superio_flat(fdc_chips_flat,cfg_base,"FDC")
++		    ||!smsc_superio_paged(fdc_chips_paged,cfg_base,"FDC"))
++			ret =  0;
+ 
+-	if (!smsc_superio_flat(fdc_chips_flat,cfg_base,"FDC")||!smsc_superio_paged(fdc_chips_paged,cfg_base,"FDC"))
+-		return 0;
++		release_region(cfg_base, 2);
++	}
+ 
+-	return -1;
++	return ret;
+ }
+ 
+ static int __init smsc_superio_lpc(unsigned short cfg_base)
+ {
+-#if 0
+-	if (check_region(cfg_base, 2) < 0) {
+-		IRDA_DEBUG(0, __FUNCTION__ ": can't get cfg_base of 0x%03x\n",
+-			   cfg_base);
+-		return -1;
+-	}
+-#endif
+-
+-	if (!smsc_superio_flat(lpc_chips_flat,cfg_base,"LPC")||!smsc_superio_paged(lpc_chips_paged,cfg_base,"LPC"))
+-		return 0;
++	int ret = -1;
+ 
+-	return -1;
++	if (!request_region(cfg_base, 2, driver_name)) {
++		WARNING("%s: can't get cfg_base of 0x%03x\n",
++			__FUNCTION__, cfg_base);
++	} else {
++		if (!smsc_superio_flat(lpc_chips_flat,cfg_base,"LPC")
++		    ||!smsc_superio_paged(lpc_chips_paged,cfg_base,"LPC"))
++			ret = 0;
++		release_region(cfg_base, 2);
++	}
++	return ret;
+ }
+ 
+ /************************************************
+--- linux-2.6.0-test6/drivers/net/irda/tekram.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/tekram.c	2003-10-05 00:33:24.000000000 -0700
+@@ -44,12 +44,12 @@ static int  tekram_reset(struct irda_tas
+ #define TEKRAM_PW     0x10 /* Pulse select bit */
+ 
+ static struct dongle_reg dongle = {
+-	Q_NULL,
+-	IRDA_TEKRAM_DONGLE,
+-	tekram_open,
+-	tekram_close,
+-	tekram_reset,
+-	tekram_change_speed,
++	.type = IRDA_TEKRAM_DONGLE,
++	.open  = tekram_open,
++	.close = tekram_close,
++	.reset = tekram_reset,
++	.change_speed = tekram_change_speed,
++	.owner = THIS_MODULE,
+ };
+ 
+ int __init tekram_init(void)
+@@ -69,8 +69,6 @@ static void tekram_open(dongle_t *self, 
+ 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ 	qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */	
+ 	irda_qos_bits_to_value(qos);
+-
+-	MOD_INC_USE_COUNT;
+ }
+ 
+ static void tekram_close(dongle_t *self)
+@@ -84,8 +82,6 @@ static void tekram_close(dongle_t *self)
+ 		irda_task_delete(self->reset_task);
+ 	if (self->speed_task)
+ 		irda_task_delete(self->speed_task);
+-
+-	MOD_DEC_USE_COUNT;
+ }
+ 
+ /*
+--- linux-2.6.0-test6/drivers/net/irda/via-ircc.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/via-ircc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -335,8 +335,7 @@ static __devinit int via_ircc_open(int i
+ 		return -1;
+ 
+ 	/* Allocate new instance of the driver */
+-	dev = alloc_netdev(sizeof(struct via_ircc_cb), "irda%d",
+-			   irda_device_setup);
++	dev = alloc_irdadev(sizeof(struct via_ircc_cb));
+ 	if (dev == NULL) 
+ 		return -ENOMEM;
+ 
+--- linux-2.6.0-test6/drivers/net/irda/vlsi_ir.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/irda/vlsi_ir.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1859,15 +1859,6 @@ static void __devexit vlsi_irda_remove(s
+  * otherwise we might get cheated by pci-pm.
+  */
+ 
+-static int vlsi_irda_save_state(struct pci_dev *pdev, u32 state)
+-{
+-	if (state < 1 || state > 3 ) {
+-		ERROR("%s - %s: invalid pm state request: %u\n",
+-			__FUNCTION__, PCIDEV_NAME(pdev), state);
+-		return -1;
+-	}
+-	return 0;
+-}
+ 
+ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
+ {
+@@ -1970,7 +1961,6 @@ static struct pci_driver vlsi_irda_drive
+ 	.probe		= vlsi_irda_probe,
+ 	.remove		= __devexit_p(vlsi_irda_remove),
+ #ifdef CONFIG_PM
+-	.save_state	= vlsi_irda_save_state,
+ 	.suspend	= vlsi_irda_suspend,
+ 	.resume		= vlsi_irda_resume,
+ #endif
+--- linux-2.6.0-test6/drivers/net/irda/w83977af_ir.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/irda/w83977af_ir.c	2003-10-05 00:33:24.000000000 -0700
+@@ -170,8 +170,7 @@ int w83977af_open(int i, unsigned int io
+ 	/*
+ 	 *  Allocate new instance of the driver
+ 	 */
+-	dev = alloc_netdev(sizeof(struct w83977af_ir), "irda%d",
+-			   irda_device_setup);
++	dev = alloc_irdadev(sizeof(struct w83977af_ir));
+ 	if (dev == NULL) {
+ 		printk( KERN_ERR "IrDA: Can't allocate memory for "
+ 			"IrDA control block!\n");
+--- linux-2.6.0-test6/drivers/net/Kconfig	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/Kconfig	2003-10-05 00:33:46.000000000 -0700
+@@ -8,32 +8,18 @@ config NETDEVICES
+ 	bool "Network device support"
+ 	---help---
+ 	  You can say N here if you don't intend to connect your Linux box to
+-	  any other computer at all or if all your connections will be over a
+-	  telephone line with a modem either via UUCP (UUCP is a protocol to
+-	  forward mail and news between unix hosts over telephone lines; read
+-	  the UUCP-HOWTO, available from
+-	  <http://www.tldp.org/docs.html#howto>) or dialing up a shell
+-	  account or a BBS, even using term (term is a program which gives you
+-	  almost full Internet connectivity if you have a regular dial up
+-	  shell account on some Internet connected Unix computer. Read
+-	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
++	  any other computer at all.
+ 
+ 	  You'll have to say Y if your computer contains a network card that
+-	  you want to use under Linux (make sure you know its name because you
+-	  will be asked for it and read the Ethernet-HOWTO (especially if you
+-	  plan to use more than one network card under Linux)) or if you want
+-	  to use SLIP (Serial Line Internet Protocol is the protocol used to
+-	  send Internet traffic over telephone lines or null modem cables) or
+-	  CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
+-	  and newer replacement for SLIP) or PLIP (Parallel Line Internet
+-	  Protocol is mainly used to create a mini network by connecting the
+-	  parallel ports of two local machines) or AX.25/KISS (protocol for
+-	  sending Internet traffic over amateur radio links).
+-
+-	  Make sure to read the NET-3-HOWTO. Eventually, you will have to read
+-	  Olaf Kirch's excellent and free book "Network Administrator's
+-	  Guide", to be found in <http://www.tldp.org/docs.html#guide>. If
+-	  unsure, say Y.
++	  you want to use under Linux. If you are going to run SLIP or PPP over
++	  telephone line or null modem cable you need say Y here. Connecting
++	  two machines with parallel ports using PLIP needs this, as well as
++	  AX.25/KISS for sending Internet traffic over amateur radio links.
++
++	  See also "The Linux Network Administrator's Guide" by Olaf Kirch and
++	  Terry Dawson. Available at <http://www.tldp.org/guides.html>.
++
++	  If unsure, say Y.
+ 
+ if NETDEVICES
+ 	source "drivers/net/arcnet/Kconfig"
+@@ -332,7 +318,7 @@ config MAC8390
+ 
+ config MAC89x0
+ 	tristate "Macintosh CS89x0 based ethernet cards"
+-	depends on NETDEVICES && MAC
++	depends on NETDEVICES && MAC && BROKEN
+ 	---help---
+ 	  Support for CS89x0 chipset based Ethernet cards.  If you have a
+ 	  Nubus or LC-PDS network (Ethernet) card of this type, say Y and
+@@ -405,7 +391,7 @@ config ATARILANCE
+ 
+ config ATARI_BIONET
+ 	tristate "BioNet-100 support"
+-	depends on NETDEVICES && ATARI && ATARI_ACSI!=n
++	depends on NETDEVICES && ATARI && ATARI_ACSI!=n && BROKEN
+ 	help
+ 	  Say Y to include support for BioData's BioNet-100 Ethernet adapter
+ 	  for the ACSI port. The driver works (has to work...) with a polled
+@@ -413,7 +399,7 @@ config ATARI_BIONET
+ 
+ config ATARI_PAMSNET
+ 	tristate "PAMsNet support"
+-	depends on NETDEVICES && ATARI && ATARI_ACSI!=n
++	depends on NETDEVICES && ATARI && ATARI_ACSI!=n && BROKEN
+ 	help
+ 	  Say Y to include support for the PAMsNet Ethernet adapter for the
+ 	  ACSI port ("ACSI node"). The driver works (has to work...) with a
+@@ -808,7 +794,7 @@ config ULTRA32
+ 
+ config SMC9194
+ 	tristate "SMC 9194 support"
+-	depends on NET_VENDOR_SMC && (ISA || MAC)
++	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
+ 	select CRC32
+ 	---help---
+ 	  This is support for the SMC9xxx based Ethernet cards. Choose this
+@@ -2455,6 +2441,9 @@ config SHAPER
+ 	  To compile this driver as a module, choose M here: the module
+ 	  will be called shaper.  If unsure, say N.
+ 
++config NET_POLL_CONTROLLER
++	def_bool KGDB
++
+ source "drivers/net/wan/Kconfig"
+ 
+ source "drivers/net/pcmcia/Kconfig"
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/kgdb_eth.c	2003-10-05 00:33:51.000000000 -0700
+@@ -0,0 +1,517 @@
++/*
++ * Network interface GDB stub
++ *
++ * Written by San Mehat (nettwerk@biodome.org)
++ * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
++ * and Scott Foehner (sfoehner@engr.sgi.com)
++ *
++ * Twiddled for 2.6 by Robert Walsh <rjwalsh@durables.org>
++ * and wangdi <wangdi@clusterfs.com>.
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/termios.h>
++#include <asm/kgdb.h>
++#include <linux/if_ether.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/delay.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/atomic.h>
++
++#define	GDB_BUF_SIZE	512		/* power of 2, please */
++
++static char	kgdb_buf[GDB_BUF_SIZE] ;
++static int	kgdb_buf_in_inx ;
++static atomic_t	kgdb_buf_in_cnt ;
++static int	kgdb_buf_out_inx ;
++
++extern void	set_debug_traps(void) ;		/* GDB routine */
++extern void	breakpoint(void);
++
++unsigned int	kgdb_remoteip = 0;
++unsigned short	kgdb_listenport = 6443;
++unsigned short	kgdb_sendport= 6442;
++int		kgdb_eth = -1; /* Default tty mode */
++unsigned char	kgdb_remotemac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++unsigned char	kgdb_localmac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++volatile int	kgdb_eth_is_initializing = 0;
++int		kgdb_eth_need_breakpoint[NR_CPUS];
++
++struct net_device *kgdb_netdevice = NULL;
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++ */
++static int
++read_char(void)
++{
++	/* intr routine has queued chars */
++	if (atomic_read(&kgdb_buf_in_cnt) != 0)
++	{
++		int chr;
++
++		chr = kgdb_buf[kgdb_buf_out_inx++] ;
++		kgdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
++		atomic_dec(&kgdb_buf_in_cnt) ;
++		return chr;
++	}
++
++	return -1; /* no data */
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_buffer(char *buf, int len)
++{
++	int			total_len, eth_len, ip_len, udp_len;
++	struct in_device	*in_dev;
++	struct sk_buff		*skb;
++	struct udphdr		*udph;
++	struct iphdr		*iph;
++	struct ethhdr		*eth;
++
++	if (!(in_dev = (struct in_device *) kgdb_netdevice->ip_ptr)) {
++		panic("No in_device available for interface!\n");
++	}
++
++	if (!(in_dev->ifa_list)) {
++		panic("No interface address set for interface!\n");
++	}
++
++	udp_len = len + sizeof(struct udphdr);
++	ip_len = eth_len = udp_len + sizeof(struct iphdr);
++	total_len = eth_len + ETH_HLEN;
++
++	if (!(skb = alloc_skb(total_len, GFP_ATOMIC))) {
++		return;
++	}
++
++	atomic_set(&skb->users, 1);
++	skb_reserve(skb, total_len - len);
++
++	memcpy(skb->data, (unsigned char *) buf, len);
++	skb->len += len;
++
++	udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
++	udph->source = htons(kgdb_listenport);
++	udph->dest   = htons(kgdb_sendport);
++	udph->len    = htons(udp_len);
++	udph->check  = 0;
++
++	iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
++	iph->version  = 4;
++	iph->ihl      = 5;
++	iph->tos      = 0;
++	iph->tot_len  = htons(ip_len);
++	iph->id       = 0;
++	iph->frag_off = 0;
++	iph->ttl      = 64;
++	iph->protocol = IPPROTO_UDP;
++	iph->check    = 0;
++	iph->saddr    = in_dev->ifa_list->ifa_address;
++	iph->daddr    = kgdb_remoteip;
++	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
++	eth->h_proto = htons(ETH_P_IP);
++	memcpy(eth->h_source, kgdb_localmac, kgdb_netdevice->addr_len);
++	memcpy(eth->h_dest, kgdb_remotemac, kgdb_netdevice->addr_len);
++
++repeat:
++	spin_lock(&kgdb_netdevice->xmit_lock);
++	kgdb_netdevice->xmit_lock_owner = smp_processor_id();
++
++	if (netif_queue_stopped(kgdb_netdevice)) {
++		kgdb_netdevice->xmit_lock_owner = -1;
++		spin_unlock(&kgdb_netdevice->xmit_lock);
++
++		kgdb_netdevice->poll_controller(kgdb_netdevice);
++		goto repeat;
++	}
++
++	kgdb_netdevice->hard_start_xmit(skb, kgdb_netdevice);
++	kgdb_netdevice->xmit_lock_owner = -1;
++	spin_unlock(&kgdb_netdevice->xmit_lock);
++}
++
++/*
++ * In the interrupt state the target machine will not respond to any
++ * arp requests, so handle them here.
++ */
++
++static struct sk_buff *send_skb = NULL;
++
++void
++kgdb_eth_reply_arp(void)
++{
++	if (send_skb) {
++		spin_lock(&kgdb_netdevice->xmit_lock);
++		kgdb_netdevice->xmit_lock_owner = smp_processor_id();
++	    	kgdb_netdevice->hard_start_xmit(send_skb, kgdb_netdevice);
++	    	kgdb_netdevice->xmit_lock_owner = -1;
++	    	spin_unlock(&kgdb_netdevice->xmit_lock);
++		send_skb = NULL;
++	}
++}
++
++static int
++make_arp_request(struct sk_buff *skb)
++{
++	struct arphdr *arp;
++	unsigned char *arp_ptr;
++	int type = ARPOP_REPLY;
++	int ptype = ETH_P_ARP;
++	u32 sip, tip;
++	unsigned char *sha, *tha;
++	struct in_device *in_dev = (struct in_device *) kgdb_netdevice->ip_ptr;
++
++	/* No arp on this interface */
++
++	if (kgdb_netdevice->flags & IFF_NOARP) {
++		return 0;
++	}
++
++	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++				 (2 * kgdb_netdevice->addr_len) +
++				 (2 * sizeof(u32))))) {
++		return 0;
++	}
++
++	skb->h.raw = skb->nh.raw = skb->data;
++	arp = skb->nh.arph;
++
++	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
++	     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
++	    arp->ar_pro != htons(ETH_P_IP)) {
++		return 0;
++	}
++
++	/* Understand only these message types */
++
++	if (arp->ar_op != htons(ARPOP_REQUEST)) {
++		return 0;
++	}
++
++	/* Extract fields */
++
++	arp_ptr= (unsigned char *)(arp+1);
++	sha = arp_ptr;
++	arp_ptr += kgdb_netdevice->addr_len;
++	memcpy(&sip, arp_ptr, 4);
++	arp_ptr += 4;
++	tha = arp_ptr;
++	arp_ptr += kgdb_netdevice->addr_len;
++	memcpy(&tip, arp_ptr, 4);
++
++	if (tip != in_dev->ifa_list->ifa_address) {
++		return 0;
++	}
++
++	if (kgdb_remoteip != sip) {
++		return 0;
++	}
++
++	/*
++	 * Check for bad requests for 127.x.x.x and requests for multicast
++	 * addresses.  If this is one such, delete it.
++	 */
++
++	if (LOOPBACK(tip) || MULTICAST(tip)) {
++		return 0;
++	}
++
++	/* reply to the ARP request */
++
++	send_skb = alloc_skb(sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4) + LL_RESERVED_SPACE(kgdb_netdevice), GFP_ATOMIC);
++
++	if (send_skb == NULL) {
++		return 0;
++	}
++
++	skb_reserve(send_skb, LL_RESERVED_SPACE(kgdb_netdevice));
++	send_skb->nh.raw = send_skb->data;
++	arp = (struct arphdr *) skb_put(send_skb, sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4));
++	send_skb->dev = kgdb_netdevice;
++	send_skb->protocol = htons(ETH_P_ARP);
++
++	/* Fill the device header for the ARP frame */
++
++	if (kgdb_netdevice->hard_header &&
++	    kgdb_netdevice->hard_header(send_skb, kgdb_netdevice, ptype,
++				       kgdb_remotemac, kgdb_localmac,
++				       send_skb->len) < 0) {
++		kfree_skb(send_skb);
++		return 0;
++	}
++
++	/*
++	 * Fill out the arp protocol part.
++	 *
++	 * we only support ethernet device type,
++	 * which (according to RFC 1390) should always equal 1 (Ethernet).
++	 */
++
++	arp->ar_hrd = htons(kgdb_netdevice->type);
++	arp->ar_pro = htons(ETH_P_IP);
++
++	arp->ar_hln = kgdb_netdevice->addr_len;
++	arp->ar_pln = 4;
++	arp->ar_op = htons(type);
++
++	arp_ptr=(unsigned char *)(arp + 1);
++
++	memcpy(arp_ptr, kgdb_netdevice->dev_addr, kgdb_netdevice->addr_len);
++	arp_ptr += kgdb_netdevice->addr_len;
++	memcpy(arp_ptr, &tip, 4);
++	arp_ptr += 4;
++	memcpy(arp_ptr, kgdb_localmac, kgdb_netdevice->addr_len);
++	arp_ptr += kgdb_netdevice->addr_len;
++	memcpy(arp_ptr, &sip, 4);
++	return 0;
++}
++
++
++/*
++ * Accept an skbuff from net_device layer and add the payload onto
++ * kgdb buffer
++ *
++ * When the kgdb stub routine getDebugChar() is called it draws characters
++ * out of the buffer until it is empty and then reads directly from the
++ * serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine since
++ * the stubs do all of that via putDebugChar() which writes one byte
++ * after waiting for the interface to become ready.
++ *
++ * The debug stubs like to run with interrupts disabled since, after all,
++ * they run as a consequence of a breakpoint in the kernel.
++ *
++ * NOTE: Return value of 1 means it was for us and is an indication to
++ * the calling driver to destroy the sk_buff and not send it up the stack.
++ */
++int
++kgdb_net_interrupt(struct sk_buff *skb)
++{
++	unsigned char	chr;
++	struct iphdr	*iph = (struct iphdr*)skb->data;
++	struct udphdr	*udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
++	unsigned char	*data = (unsigned char *) udph + sizeof(struct udphdr);
++	int		len;
++	int		i;
++
++	if ((kgdb_eth != -1) && (!kgdb_netdevice) &&
++	    (iph->protocol == IPPROTO_UDP) &&
++	    (be16_to_cpu(udph->dest) == kgdb_listenport)) {
++		kgdb_sendport = be16_to_cpu(udph->source);
++
++		while (kgdb_eth_is_initializing)
++			;
++		if (!kgdb_netdevice)
++			kgdb_eth_hook();
++		if (!kgdb_netdevice) {
++			/* Lets not even try again. */
++			kgdb_eth = -1;
++			return 0;
++		}
++	}
++	if (!kgdb_netdevice) {
++		return 0;
++	}
++	if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb) {
++		make_arp_request(skb);
++		return 0;
++	}
++	if (iph->protocol != IPPROTO_UDP) {
++		return 0;
++	}
++
++	if (be16_to_cpu(udph->dest) != kgdb_listenport) {
++		return 0;
++	}
++
++	len = (be16_to_cpu(iph->tot_len) -
++	       (sizeof(struct udphdr) + sizeof(struct iphdr)));
++
++	for (i = 0; i < len; i++) {
++		chr = data[i];
++		if (chr == 3) {
++			kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++			continue;
++		}
++		if (atomic_read(&kgdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++			/* buffer overflow, clear it */
++			kgdb_buf_in_inx = 0;
++			atomic_set(&kgdb_buf_in_cnt, 0);
++			kgdb_buf_out_inx = 0;
++			break;
++		}
++		kgdb_buf[kgdb_buf_in_inx++] = chr;
++		kgdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++		atomic_inc(&kgdb_buf_in_cnt);
++	}
++
++	if (!kgdb_netdevice->kgdb_is_trapped) {
++		/*
++		 * If a new gdb instance is trying to attach, we need to
++		 * break here.
++		 */
++		if (!strncmp(data, "$Hc-1#09", 8))
++			kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++	}
++	return 1;
++}
++EXPORT_SYMBOL(kgdb_net_interrupt);
++
++int
++kgdb_eth_hook(void)
++{
++	char kgdb_netdev[16];
++	extern void kgdb_respond_ok(void);
++
++	if (kgdb_remotemac[0] == 0xff) {
++		panic("ERROR! 'gdbeth_remotemac' option not set!\n");
++	}
++	if (kgdb_localmac[0] == 0xff) {
++		panic("ERROR! 'gdbeth_localmac' option not set!\n");
++	}
++	if (kgdb_remoteip == 0) {
++		panic("ERROR! 'gdbeth_remoteip' option not set!\n");
++	}
++
++	sprintf(kgdb_netdev,"eth%d",kgdb_eth);
++
++#ifdef CONFIG_SMP
++	if (num_online_cpus() > CONFIG_NO_KGDB_CPUS) {
++		printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
++		return -1;
++	}
++#endif
++	for (kgdb_netdevice = dev_base;
++		kgdb_netdevice != NULL;
++		kgdb_netdevice = kgdb_netdevice->next) {
++		if (strncmp(kgdb_netdevice->name, kgdb_netdev, IFNAMSIZ) == 0) {
++			break;
++		}
++	}
++	if (!kgdb_netdevice) {
++		printk("KGDB NET : Unable to find interface %s\n",kgdb_netdev);
++		return -ENODEV;
++	}
++
++	/*
++	 * Call GDB routine to setup the exception vectors for the debugger
++	 */
++	set_debug_traps();
++
++	/*
++	 * Call the breakpoint() routine in GDB to start the debugging
++	 * session.
++	 */
++	kgdb_eth_is_initializing = 1;
++	kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++	return 0;
++}
++
++/*
++ * getDebugChar
++ *
++ * This is a GDB stub routine.  It waits for a character from the
++ * serial interface and then returns it.  If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.
++ */
++int
++eth_getDebugChar(void)
++{
++	volatile int	chr;
++
++	while ((chr = read_char()) < 0) {
++		if (send_skb) {
++			kgdb_eth_reply_arp();
++		}
++		if (kgdb_netdevice->poll_controller) {
++			kgdb_netdevice->poll_controller(kgdb_netdevice);
++		} else {
++			printk("KGDB NET: Error - Device %s is not supported!\n", kgdb_netdevice->name);
++			panic("Please add support for kgdb net to this driver");
++		}
++	}
++	return chr;
++}
++
++#define ETH_QUEUE_SIZE 256
++static char eth_queue[ETH_QUEUE_SIZE];
++static int outgoing_queue;
++
++void
++eth_flushDebugChar(void)
++{
++	if(outgoing_queue) {
++		write_buffer(eth_queue, outgoing_queue);
++
++		outgoing_queue = 0;
++	}
++}
++
++static void
++put_char_on_queue(int chr)
++{
++	eth_queue[outgoing_queue++] = chr;
++	if(outgoing_queue == ETH_QUEUE_SIZE)
++	{
++		eth_flushDebugChar();
++	}
++}
++
++/*
++ * eth_putDebugChar
++ *
++ * This is a GDB stub routine.  It waits until the interface is ready
++ * to transmit a char and then sends it.
++ */
++void
++eth_putDebugChar(int chr)
++{
++	put_char_on_queue(chr); /* this routine will wait */
++}
++
++void
++kgdb_eth_set_trapmode(int mode)
++{
++	if (!kgdb_netdevice) {
++		return;
++	}
++	kgdb_netdevice->kgdb_is_trapped = mode;
++}
++
++int
++kgdb_eth_is_trapped()
++{
++	if (!kgdb_netdevice) {
++		return 0;
++	}
++	return kgdb_netdevice->kgdb_is_trapped;
++}
++EXPORT_SYMBOL(kgdb_eth_is_trapped);
+--- linux-2.6.0-test6/drivers/net/loopback.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/loopback.c	2003-10-05 00:33:24.000000000 -0700
+@@ -30,6 +30,7 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/jiffies.h>
++#include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/fs.h>
+ #include <linux/types.h>
+@@ -202,3 +203,5 @@ int __init loopback_init(void)
+ 	
+ 	return register_netdev(&loopback_dev);
+ };
++
++EXPORT_SYMBOL(loopback_dev);
+--- linux-2.6.0-test6/drivers/net/mac8390.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/net/mac8390.c	2003-10-05 00:33:24.000000000 -0700
+@@ -442,14 +442,14 @@ int __init mac8390_initdev(struct net_de
+                ei_status.tx_start_page = CABLETRON_TX_START_PG;
+                ei_status.rx_start_page = CABLETRON_RX_START_PG;
+                ei_status.stop_page = CABLETRON_RX_STOP_PG;
+-               dev->rmem_start = dev->mem_start;
+-               dev->rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
++               ei_status.rmem_start = dev->mem_start;
++               ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
+ 	} else {
+                ei_status.tx_start_page = WD_START_PG;
+                ei_status.rx_start_page = WD_START_PG + TX_PAGES;
+                ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
+-               dev->rmem_start = dev->mem_start + TX_PAGES*256;
+-               dev->rmem_end = dev->mem_end;
++               ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
++               ei_status.rmem_end = dev->mem_end;
+ 	}
+ 	
+ 	/* Fill in model-specific information and functions */
+@@ -621,12 +621,12 @@ static void sane_block_input(struct net_
+ 	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ 	unsigned long xfer_start = xfer_base + dev->mem_start;
+ 
+-	if (xfer_start + count > dev->rmem_end) {
++	if (xfer_start + count > ei_status.rmem_end) {
+ 		/* We must wrap the input move. */
+-		int semi_count = dev->rmem_end - xfer_start;
++		int semi_count = ei_status.rmem_end - xfer_start;
+ 		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, semi_count);
+ 		count -= semi_count;
+-		memcpy_toio(skb->data + semi_count, (char *)dev->rmem_start, count);
++		memcpy_toio(skb->data + semi_count, (char *)ei_status.rmem_start, count);
+ 	} else {
+ 		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, count);
+ 	}
+@@ -657,15 +657,16 @@ static void dayna_block_input(struct net
+ 
+ 	/* Note the offset math is done in card memory space which is word
+ 	   per long onto our space. */
+-	 
+-	if (xfer_start + count > dev->rmem_end) 
++
++	if (xfer_start + count > ei_status.rmem_end)
+ 	{
+ 		/* We must wrap the input move. */
+-		int semi_count = dev->rmem_end - xfer_start;
++		int semi_count = ei_status.rmem_end - xfer_start;
+ 		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
+ 		count -= semi_count;
+-		dayna_memcpy_fromcard(dev, skb->data + semi_count, 
+-			dev->rmem_start - dev->mem_start, count);
++		dayna_memcpy_fromcard(dev, skb->data + semi_count,
++				      ei_status.rmem_start - dev->mem_start,
++				      count);
+ 	}
+ 	else
+ 	{
+@@ -697,15 +698,15 @@ static void slow_sane_block_input(struct
+ 	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ 	unsigned long xfer_start = xfer_base+dev->mem_start;
+ 
+-	if (xfer_start + count > dev->rmem_end)
++	if (xfer_start + count > ei_status.rmem_end)
+ 	{
+ 		/* We must wrap the input move. */
+-		int semi_count = dev->rmem_end - xfer_start;
++		int semi_count = ei_status.rmem_end - xfer_start;
+ 		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +
+ 			xfer_base, semi_count);
+ 		count -= semi_count;
+ 		word_memcpy_fromcard(skb->data + semi_count,
+-			(char *)dev->rmem_start, count);
++				     (char *)ei_status.rmem_start, count);
+ 	}
+ 	else
+ 	{
+--- linux-2.6.0-test6/drivers/net/Makefile	2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/Makefile	2003-10-05 00:33:44.000000000 -0700
+@@ -32,6 +32,8 @@ obj-$(CONFIG_BMAC) += bmac.o
+ 
+ obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
+ 
++obj-$(CONFIG_KGDB) += kgdb_eth.o
++
+ obj-$(CONFIG_DGRS) += dgrs.o
+ obj-$(CONFIG_RCPCI) += rcpci.o
+ obj-$(CONFIG_VORTEX) += 3c59x.o
+--- linux-2.6.0-test6/drivers/net/ne2.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ne2.c	2003-10-05 00:33:24.000000000 -0700
+@@ -70,7 +70,7 @@ static const char *version = "ne2.c:v0.9
+ #include <linux/string.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+--- linux-2.6.0-test6/drivers/net/ne3210.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ne3210.c	2003-10-05 00:33:24.000000000 -0700
+@@ -23,6 +23,7 @@
+ 	This driver WILL NOT WORK FOR THE NE3200 - it is completely different
+ 	and does not use an 8390 at all.
+ 
++	Updated to EISA probing API 5/2003 by Marc Zyngier.
+ */
+ 
+ static const char *version =
+@@ -44,9 +45,6 @@ static const char *version =
+ 
+ #include "8390.h"
+ 
+-int ne3210_probe(struct net_device *dev);
+-static int ne3210_probe1(struct net_device *dev, int ioaddr);
+-
+ static int ne3210_open(struct net_device *dev);
+ static int ne3210_close(struct net_device *dev);
+ 
+@@ -59,7 +57,6 @@ static void ne3210_block_output(struct n
+ #define NE3210_START_PG		0x00    /* First page of TX buffer	*/
+ #define NE3210_STOP_PG		0x80    /* Last page +1 of RX ring	*/
+ 
+-#define NE3210_ID_PORT		0xc80	/* Same for all EISA cards 	*/
+ #define NE3210_IO_EXTENT	0x20
+ #define NE3210_SA_PROM		0x16	/* Start of e'net addr.		*/
+ #define NE3210_RESET_PORT	0xc84
+@@ -69,10 +66,9 @@ static void ne3210_block_output(struct n
+ #define NE3210_ADDR1		0x00
+ #define NE3210_ADDR2		0x1b
+ 
+-#define NE3210_ID	0x0118cc3a	/* 0x3acc = 1110 10110 01100 =  nvl */
+-
+ #define NE3210_CFG1		0xc84	/* NB: 0xc84 is also "reset" port. */
+ #define NE3210_CFG2		0xc90
++#define NE3210_CFG_EXTENT       (NE3210_CFG2 - NE3210_CFG1 + 1)
+ 
+ /*
+  *	You can OR any of the following bits together and assign it
+@@ -89,152 +85,108 @@ static void ne3210_block_output(struct n
+ 
+ static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
+ static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
++static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
++static int ifmap_val[] __initdata = {
++		IF_PORT_10BASET,
++		IF_PORT_UNKNOWN,
++		IF_PORT_10BASE2,
++		IF_PORT_AUI,
++};
+ 
+-/*
+- *	Probe for the card. The best way is to read the EISA ID if it
+- *	is known. Then we can check the prefix of the station address
+- *	PROM for a match against the value assigned to Novell.
+- */
+-
+-int __init ne3210_probe(struct net_device *dev)
++static int __init ne3210_eisa_probe (struct device *device)
+ {
+-	unsigned short ioaddr = dev->base_addr;
+-
+-	SET_MODULE_OWNER(dev);
++	unsigned long ioaddr, phys_mem;
++	int i, retval, port_index;
++	struct eisa_device *edev = to_eisa_device (device);
++	struct net_device *dev;
+ 
+-	if (ioaddr > 0x1ff)		/* Check a single specified location. */
+-		return ne3210_probe1(dev, ioaddr);
+-	else if (ioaddr > 0)		/* Don't probe at all. */
+-		return -ENXIO;
+-
+-	if (!EISA_bus) {
+-#if NE3210_DEBUG & NE3210_D_PROBE
+-		printk("ne3210-debug: Not an EISA bus. Not probing high ports.\n");
+-#endif
+-		return -ENXIO;
++	/* Allocate dev->priv and fill in 8390 specific dev fields. */
++	if (!(dev = alloc_ei_netdev ())) {
++		printk ("ne3210.c: unable to allocate memory for dev!\n");
++		return -ENOMEM;
+ 	}
+ 
+-	/* EISA spec allows for up to 16 slots, but 8 is typical. */
+-	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
+-		if (ne3210_probe1(dev, ioaddr) == 0)
+-			return 0;
+-
+-	return -ENODEV;
+-}
+-
+-static int __init ne3210_probe1(struct net_device *dev, int ioaddr)
+-{
+-	int i, retval;
+-	unsigned long eisa_id;
+-	const char *ifmap[] = {"UTP", "?", "BNC", "AUI"};
+-
+-	if (!request_region(dev->base_addr, NE3210_IO_EXTENT, dev->name))
+-		return -EBUSY;
++	SET_MODULE_OWNER(dev);
++	SET_NETDEV_DEV(dev, device);
++	device->driver_data = dev;
++	ioaddr = edev->base_addr;
+ 
+-	if (inb_p(ioaddr + NE3210_ID_PORT) == 0xff) {
+-		retval = -ENODEV;
++	if (ethdev_init (dev)) {
++		printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
++		retval = -ENOMEM;
+ 		goto out;
+ 	}
+ 
+-#if NE3210_DEBUG & NE3210_D_PROBE
+-	printk("ne3210-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + NE3210_ID_PORT));
+-	printk("ne3210-debug: config regs: %#x %#x\n",
+-		inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2));
+-#endif
+-
+-
+-/*	Check the EISA ID of the card. */
+-	eisa_id = inl(ioaddr + NE3210_ID_PORT);
+-	if (eisa_id != NE3210_ID) {
+-		retval = -ENODEV;
++	if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
++		retval = -EBUSY;
+ 		goto out;
+ 	}
+ 
+-	
+-#if 0
+-/*	Check the vendor ID as well. Not really required. */
+-	if (inb(ioaddr + NE3210_SA_PROM + 0) != NE3210_ADDR0
+-		|| inb(ioaddr + NE3210_SA_PROM + 1) != NE3210_ADDR1
+-		|| inb(ioaddr + NE3210_SA_PROM + 2) != NE3210_ADDR2 ) {
+-		printk("ne3210.c: card not found");
+-		for(i = 0; i < ETHER_ADDR_LEN; i++)
+-			printk(" %02x", inb(ioaddr + NE3210_SA_PROM + i));
+-		printk(" (invalid prefix).\n");
+-		retval = -ENODEV;
+-		goto out;
++	if (!request_region(ioaddr + NE3210_CFG1,
++			    NE3210_CFG_EXTENT, dev->name)) {
++		retval = -EBUSY;
++		goto out1;
+ 	}
++
++#if NE3210_DEBUG & NE3210_D_PROBE
++	printk("ne3210-debug: probe at %#x, ID %s\n", ioaddr, edev->id.sig);
++	printk("ne3210-debug: config regs: %#x %#x\n",
++		inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2));
+ #endif
+ 
+-	/* Allocate dev->priv and fill in 8390 specific dev fields. */
+-	if (ethdev_init(dev)) {
+-		printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
+-		retval = -ENOMEM;
+-		goto out;
+-	}
+ 
++	port_index = inb(ioaddr + NE3210_CFG2) >> 6;
+ 	printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:",
+-		ioaddr/0x1000, ifmap[inb(ioaddr + NE3210_CFG2) >> 6]);
++		edev->slot, ifmap[port_index]);
+ 	for(i = 0; i < ETHER_ADDR_LEN; i++)
+ 		printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i)));
+-	printk(".\nne3210.c: ");
++	
+ 
+ 	/* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */
+-	if (dev->irq == 0) {
+-		unsigned char irq_reg = inb(ioaddr + NE3210_CFG2) >> 3;
+-		dev->irq = irq_map[irq_reg & 0x07];
+-		printk("using");
+-	} else {
+-		/* This is useless unless we reprogram the card here too */
+-		if (dev->irq == 2) dev->irq = 9;	/* Doh! */
+-		printk("assigning");
+-	}
+-	printk(" IRQ %d,", dev->irq);
++	dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07];
++	printk(".\nne3210.c: using IRQ %d, ", dev->irq);
+ 
+ 	retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+ 	if (retval) {
+ 		printk (" unable to get IRQ %d.\n", dev->irq);
+-		goto out1;
+-	}
+-
+-	if (dev->mem_start == 0) {
+-		unsigned char mem_reg = inb(ioaddr + NE3210_CFG2) & 0x07;
+-		dev->mem_start = shmem_map[mem_reg] * 0x1000;
+-		printk(" using ");
+-	} else {
+-		/* Should check for value in shmem_map and reprogram the card to use it */
+-		dev->mem_start &= 0xfff8000;
+-		printk(" assigning ");
++		goto out2;
+ 	}
+ 
+-	printk("%dkB memory at physical address %#lx\n",
+-			NE3210_STOP_PG/4, dev->mem_start);
++	phys_mem = shmem_map[inb(ioaddr + NE3210_CFG2) & 0x07] * 0x1000;
+ 
+ 	/*
+ 	   BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
+ 	   the card mem within the region covered by `normal' RAM  !!!
+ 	*/
+-	if (dev->mem_start > 1024*1024) {	/* phys addr > 1MB */
+-		if (dev->mem_start < virt_to_phys(high_memory)) {
++	if (phys_mem > 1024*1024) {	/* phys addr > 1MB */
++		if (phys_mem < virt_to_phys(high_memory)) {
+ 			printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n");
+ 			printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n");
+ 			printk(KERN_CRIT "ne3210.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
+ 			printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n");
+ 			retval = -EINVAL;
+-			goto out2;
++			goto out3;
+ 		}
+-		dev->mem_start = (unsigned long)ioremap(dev->mem_start, NE3210_STOP_PG*0x100);
+-		if (dev->mem_start == 0) {
+-			printk(KERN_ERR "ne3210.c: Unable to remap card memory above 1MB !!\n");
+-			printk(KERN_ERR "ne3210.c: Try using EISA SCU to set memory below 1MB.\n");
+-			printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
+-			retval = -EAGAIN;
+-			goto out2;
+-		}
+-		ei_status.reg0 = 1;	/* Use as remap flag */
+-		printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
+-				NE3210_STOP_PG/4, dev->mem_start);
+ 	}
++	
++	if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, dev->name)) {
++		printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n",
++			phys_mem);
++		goto out3;
++	}
++	
++	printk("%dkB memory at physical address %#lx\n",
++	       NE3210_STOP_PG/4, phys_mem);
+ 
++	dev->mem_start = (unsigned long)ioremap(phys_mem, NE3210_STOP_PG*0x100);
++	if (dev->mem_start == 0) {
++		printk(KERN_ERR "ne3210.c: Unable to remap card memory !!\n");
++		printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
++		retval = -EAGAIN;
++		goto out4;
++	}
++	printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
++	       NE3210_STOP_PG/4, dev->mem_start);
+ 	dev->mem_end = ei_status.rmem_end = dev->mem_start
+ 		+ (NE3210_STOP_PG - NE3210_START_PG)*256;
+ 	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+@@ -247,6 +199,7 @@ static int __init ne3210_probe1(struct n
+ 	ei_status.rx_start_page = NE3210_START_PG + TX_PAGES;
+ 	ei_status.stop_page = NE3210_STOP_PG;
+ 	ei_status.word16 = 1;
++	ei_status.priv = phys_mem;
+ 
+ 	if (ei_debug > 0)
+ 		printk(version);
+@@ -258,18 +211,46 @@ static int __init ne3210_probe1(struct n
+ 
+ 	dev->open = &ne3210_open;
+ 	dev->stop = &ne3210_close;
++	dev->if_port = ifmap_val[port_index];
++
++	if ((retval = register_netdev (dev)))
++		goto out5;
++		
+ 	NS8390_init(dev, 0);
+ 	return 0;
+-out2:
+-	free_irq(dev->irq, dev);	
+-out1:
+-	kfree(dev->priv);
+-	dev->priv = NULL;
+-out:
+-	release_region(ioaddr, NE3210_IO_EXTENT);
++
++ out5:
++	iounmap((void *)dev->mem_start);
++ out4:
++	release_mem_region (phys_mem, NE3210_STOP_PG*0x100);
++ out3:
++	free_irq (dev->irq, dev);
++ out2:
++	release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT);
++ out1:
++	release_region (ioaddr, NE3210_IO_EXTENT);
++ out:
++	free_netdev (dev);
++	
+ 	return retval;
+ }
+ 
++static int __devexit ne3210_eisa_remove (struct device *device)
++{
++	struct net_device  *dev    = device->driver_data;
++	unsigned long       ioaddr = to_eisa_device (device)->base_addr;
++
++	unregister_netdev (dev);
++	iounmap((void *)dev->mem_start);
++	release_mem_region (ei_status.priv, NE3210_STOP_PG*0x100);
++	free_irq (dev->irq, dev);
++	release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT);
++	release_region (ioaddr, NE3210_IO_EXTENT);
++	free_netdev (dev);
++
++	return 0;
++}
++
+ /*
+  *	Reset by toggling the "Board Enable" bits (bit 2 and 0).
+  */
+@@ -309,7 +290,7 @@ static void
+ ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+ {
+ 	unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8);
+-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
++	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+ 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
+ }
+ 
+@@ -327,12 +308,12 @@ static void ne3210_block_input(struct ne
+ 	if (xfer_start + count > ei_status.rmem_end) {
+ 		/* Packet wraps over end of ring buffer. */
+ 		int semi_count = ei_status.rmem_end - xfer_start;
+-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
++		memcpy_fromio(skb->data, xfer_start, semi_count);
+ 		count -= semi_count;
+-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
++		memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+ 	} else {
+ 		/* Packet is in one chunk. */
+-		isa_memcpy_fromio(skb->data, xfer_start, count);
++		memcpy_fromio(skb->data, xfer_start, count);
+ 	}
+ }
+ 
+@@ -342,7 +323,7 @@ static void ne3210_block_output(struct n
+ 	unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8);
+ 
+ 	count = (count + 3) & ~3;     /* Round up to doubleword */
+-	isa_memcpy_toio(shmem, buf, count);
++	memcpy_toio(shmem, buf, count);
+ }
+ 
+ static int ne3210_open(struct net_device *dev)
+@@ -361,7 +342,23 @@ static int ne3210_close(struct net_devic
+ 	return 0;
+ }
+ 
++static struct eisa_device_id ne3210_ids[] = {
++	{ "EGL0101" },
++	{ "NVL1801" },
++	{ "" },
++};
++
++static struct eisa_driver ne3210_eisa_driver = {
++	.id_table = ne3210_ids,
++	.driver   = {
++		.name   = "ne3210",
++		.probe  = ne3210_eisa_probe,
++		.remove = __devexit_p (ne3210_eisa_remove),
++	},
++};
++
+ #ifdef MODULE
++#if 0
+ #define MAX_NE3210_CARDS	4	/* Max number of NE3210 cards per module */
+ static struct net_device dev_ne3210[MAX_NE3210_CARDS];
+ static int io[MAX_NE3210_CARDS];
+@@ -374,50 +371,22 @@ MODULE_PARM(mem, "1-" __MODULE_STRING(MA
+ MODULE_PARM_DESC(io, "I/O base address(es)");
+ MODULE_PARM_DESC(irq, "IRQ number(s)");
+ MODULE_PARM_DESC(mem, "memory base address(es)");
++#endif
++#endif /* MODULE */
++
++
+ MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
+ MODULE_LICENSE("GPL");
+ 
+-int init_module(void)
++int ne3210_init(void)
+ {
+-	int this_dev, found = 0;
+-
+-	for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
+-		struct net_device *dev = &dev_ne3210[this_dev];
+-		dev->irq = irq[this_dev];
+-		dev->base_addr = io[this_dev];
+-		dev->mem_start = mem[this_dev];
+-		dev->init = ne3210_probe;
+-		/* Default is to only install one card. */
+-		if (io[this_dev] == 0 && this_dev != 0) break;
+-		if (register_netdev(dev) != 0) {
+-			printk(KERN_WARNING "ne3210.c: No NE3210 card found (i/o = 0x%x).\n", io[this_dev]);
+-			if (found != 0) {	/* Got at least one. */
+-				return 0;
+-			}
+-			return -ENXIO;
+-		}
+-		found++;
+-	}
+-	return 0;
++	return eisa_driver_register (&ne3210_eisa_driver);
+ }
+ 
+-void cleanup_module(void)
++void ne3210_cleanup(void)
+ {
+-	int this_dev;
+-
+-	for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
+-		struct net_device *dev = &dev_ne3210[this_dev];
+-		if (dev->priv != NULL) {
+-			free_irq(dev->irq, dev);
+-			release_region(dev->base_addr, NE3210_IO_EXTENT);
+-			if (ei_status.reg0)
+-				iounmap((void *)dev->mem_start);
+-			unregister_netdev(dev);
+-			kfree(dev->priv);
+-			dev->priv = NULL;
+-		}
+-	}
++	eisa_driver_unregister (&ne3210_eisa_driver);
+ }
+ 
+-#endif /* MODULE */
+-
++module_init (ne3210_init);
++module_exit (ne3210_cleanup);
+--- linux-2.6.0-test6/drivers/net/sk_mca.c	2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/sk_mca.c	2003-10-05 00:33:24.000000000 -0700
+@@ -89,7 +89,7 @@ History:
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/time.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/version.h>
+--- linux-2.6.0-test6/drivers/net/slip.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/slip.c	2003-10-05 00:36:15.000000000 -0700
+@@ -1307,7 +1307,7 @@ static int sl_ioctl(struct net_device *d
+ 		/* Resolve race condition, when ioctl'ing hanged up 
+ 		   and opened by another process device.
+ 		 */
+-		if (sl->tty != current->tty && sl->pid != current->pid) {
++		if (sl->tty != process_tty(current) && sl->pid != current->pid) {
+ 			spin_unlock_bh(&sl->lock);
+ 			return -EPERM;
+ 		}
+--- linux-2.6.0-test6/drivers/net/Space.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/Space.c	2003-10-05 00:33:24.000000000 -0700
+@@ -67,7 +67,6 @@ extern int elplus_probe(struct net_devic
+ extern int ac3200_probe(struct net_device *);
+ extern int es_probe(struct net_device *);
+ extern int lne390_probe(struct net_device *);
+-extern int ne3210_probe(struct net_device *);
+ extern int e2100_probe(struct net_device *);
+ extern int ni5010_probe(struct net_device *);
+ extern int ni52_probe(struct net_device *);
+@@ -155,9 +154,6 @@ static struct devprobe eisa_probes[] __i
+ #ifdef CONFIG_LNE390
+ 	{lne390_probe, 0},
+ #endif
+-#ifdef CONFIG_NE3210
+-	{ne3210_probe, 0},
+-#endif
+ 	{NULL, 0},
+ };
+ 
+@@ -480,3 +476,5 @@ void __init probe_old_netdevs(void)
+ struct net_device *dev_base;
+ rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
+ 
++EXPORT_SYMBOL(dev_base);
++EXPORT_SYMBOL(dev_base_lock);
+--- linux-2.6.0-test6/drivers/net/tlan.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tlan.c	2003-10-05 00:33:48.000000000 -0700
+@@ -297,6 +297,7 @@ static int	TLan_ioctl( struct net_device
+ static int      TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
+ static void	TLan_tx_timeout( struct net_device *dev);
+ static int 	tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
++static void	TLan_Poll(struct net_device *dev);
+ 
+ static u32	TLan_HandleInvalid( struct net_device *, u16 );
+ static u32	TLan_HandleTxEOF( struct net_device *, u16 );
+@@ -453,6 +454,25 @@ static void __devexit tlan_remove_one( s
+ 	pci_set_drvdata( pdev, NULL );
+ } 
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void TLan_Poll (struct net_device *dev)
++{
++       disable_irq(dev->irq);
++       TLan_HandleInterrupt(dev->irq, dev, NULL);
++       enable_irq(dev->irq);
++}
++
++#endif
++
++
++
+ static struct pci_driver tlan_driver = {
+ 	.name		= "tlan",
+ 	.id_table	= tlan_pci_tbl,
+@@ -895,6 +915,9 @@ static int TLan_Init( struct net_device 
+ 	dev->do_ioctl = &TLan_ioctl;
+ 	dev->tx_timeout = &TLan_tx_timeout;
+ 	dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = &TLan_Poll;
++#endif
+ 
+ 	return 0;
+ 
+--- linux-2.6.0-test6/drivers/net/tokenring/madgemc.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/tokenring/madgemc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -20,7 +20,7 @@
+ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n";
+ 
+ #include <linux/module.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/pci.h>
+--- linux-2.6.0-test6/drivers/net/tokenring/smctr.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/smctr.c	2003-10-05 00:33:24.000000000 -0700
+@@ -43,7 +43,7 @@
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
+-#include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #include <linux/delay.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+--- linux-2.6.0-test6/drivers/net/tulip/interrupt.c	2003-06-14 12:18:04.000000000 -0700
++++ 25/drivers/net/tulip/interrupt.c	2003-10-05 00:36:07.000000000 -0700
+@@ -19,13 +19,13 @@
+ #include <linux/etherdevice.h>
+ #include <linux/pci.h>
+ 
+-
+ int tulip_rx_copybreak;
+ unsigned int tulip_max_interrupt_work;
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-
++#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ #define MIT_SIZE 15
++#define MIT_TABLE 15 /* We use 0 or max */
++
+ unsigned int mit_table[MIT_SIZE+1] =
+ {
+         /*  CRS11 21143 hardware Mitigation Control Interrupt
+@@ -99,16 +99,28 @@ int tulip_refill_rx(struct net_device *d
+ 	return refilled;
+ }
+ 
++#ifdef CONFIG_TULIP_NAPI
+ 
+-static int tulip_rx(struct net_device *dev)
++void oom_timer(unsigned long data)
++{
++        struct net_device *dev = (struct net_device *)data;
++	netif_rx_schedule(dev);
++}
++
++int tulip_poll(struct net_device *dev, int *budget)
+ {
+ 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+ 	int entry = tp->cur_rx % RX_RING_SIZE;
+-	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
++	int rx_work_limit = *budget;
+ 	int received = 0;
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        int drop = 0, mit_sel = 0;
++	if (!netif_running(dev))
++		goto done;
++
++	if (rx_work_limit > dev->quota)
++		rx_work_limit = dev->quota;
++
++#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ 
+ /* that one buffer is needed for mit activation; or might be a
+    bug in the ring buffer code; check later -- JHS*/
+@@ -119,6 +131,237 @@ static int tulip_rx(struct net_device *d
+ 	if (tulip_debug > 4)
+ 		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+ 			   tp->rx_ring[entry].status);
++
++       do {
++               /* Acknowledge current RX interrupt sources. */
++               outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
++
++
++               /* If we own the next entry, it is a new packet. Send it up. */
++               while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
++                       s32 status = le32_to_cpu(tp->rx_ring[entry].status);
++
++
++                       if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
++                               break;
++
++                       if (tulip_debug > 5)
++                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
++                                      dev->name, entry, status);
++                       if (--rx_work_limit < 0)
++                               goto not_done;
++
++                       if ((status & 0x38008300) != 0x0300) {
++                               if ((status & 0x38000300) != 0x0300) {
++                                /* Ingore earlier buffers. */
++                                       if ((status & 0xffff) != 0x7fff) {
++                                               if (tulip_debug > 1)
++                                                       printk(KERN_WARNING "%s: Oversized Ethernet frame "
++                                                              "spanned multiple buffers, status %8.8x!\n",
++                                                              dev->name, status);
++                                               tp->stats.rx_length_errors++;
++                                       }
++                               } else if (status & RxDescFatalErr) {
++                                /* There was a fatal error. */
++                                       if (tulip_debug > 2)
++                                               printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
++                                                      dev->name, status);
++                                       tp->stats.rx_errors++; /* end of a packet.*/
++                                       if (status & 0x0890) tp->stats.rx_length_errors++;
++                                       if (status & 0x0004) tp->stats.rx_frame_errors++;
++                                       if (status & 0x0002) tp->stats.rx_crc_errors++;
++                                       if (status & 0x0001) tp->stats.rx_fifo_errors++;
++                               }
++                       } else {
++                               /* Omit the four octet CRC from the length. */
++                               short pkt_len = ((status >> 16) & 0x7ff) - 4;
++                               struct sk_buff *skb;
++
++#ifndef final_version
++                               if (pkt_len > 1518) {
++                                       printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
++                                              dev->name, pkt_len, pkt_len);
++                                       pkt_len = 1518;
++                                       tp->stats.rx_length_errors++;
++                               }
++#endif
++                               /* Check if the packet is long enough to accept without copying
++                                  to a minimally-sized skbuff. */
++                               if (pkt_len < tulip_rx_copybreak
++                                   && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
++                                       skb->dev = dev;
++                                       skb_reserve(skb, 2);    /* 16 byte align the IP header */
++                                       pci_dma_sync_single(tp->pdev,
++                                                           tp->rx_buffers[entry].mapping,
++                                                           pkt_len, PCI_DMA_FROMDEVICE);
++#if ! defined(__alpha__)
++                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
++                                                        pkt_len, 0);
++                                       skb_put(skb, pkt_len);
++#else
++                                       memcpy(skb_put(skb, pkt_len),
++                                              tp->rx_buffers[entry].skb->tail,
++                                              pkt_len);
++#endif
++                               } else {        /* Pass up the skb already on the Rx ring. */
++                                       char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
++                                                            pkt_len);
++
++#ifndef final_version
++                                       if (tp->rx_buffers[entry].mapping !=
++                                           le32_to_cpu(tp->rx_ring[entry].buffer1)) {
++                                               printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
++                                                      "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
++                                                      dev->name,
++                                                      le32_to_cpu(tp->rx_ring[entry].buffer1),
++                                                      tp->rx_buffers[entry].mapping,
++                                                      skb->head, temp);
++                                       }
++#endif
++
++                                       pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
++                                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
++
++                                       tp->rx_buffers[entry].skb = NULL;
++                                       tp->rx_buffers[entry].mapping = 0;
++                               }
++                               skb->protocol = eth_type_trans(skb, dev);
++
++                               netif_receive_skb(skb);
++
++                               dev->last_rx = jiffies;
++                               tp->stats.rx_packets++;
++                               tp->stats.rx_bytes += pkt_len;
++                       }
++                       received++;
++
++                       entry = (++tp->cur_rx) % RX_RING_SIZE;
++                       if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
++                               tulip_refill_rx(dev);
++
++                }
++
++               /* New ack strategy... irq does not ack Rx any longer
++                  hopefully this helps */
++
++               /* Really bad things can happen here... If new packet arrives
++                * and an irq arrives (tx or just due to occasionally unset
++                * mask), it will be acked by irq handler, but new thread
++                * is not scheduled. It is major hole in design.
++                * No idea how to fix this if "playing with fire" will fail
++                * tomorrow (night 011029). If it will not fail, we won
++                * finally: amount of IO did not increase at all. */
++       } while ((inl(dev->base_addr + CSR5) & RxIntr));
++
++done:
++
++ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
++
++          /* We use this simplistic scheme for IM. It's proven by
++             real life installations. We can have IM enabled
++            continuesly but this would cause unnecessary latency.
++            Unfortunely we can't use all the NET_RX_* feedback here.
++            This would turn on IM for devices that is not contributing
++            to backlog congestion with unnecessary latency.
++
++             We monitor the the device RX-ring and have:
++
++             HW Interrupt Mitigation either ON or OFF.
++
++            ON:  More then 1 pkt received (per intr.) OR we are dropping
++             OFF: Only 1 pkt received
++
++             Note. We only use min and max (0, 15) settings from mit_table */
++
++
++          if( tp->flags &  HAS_INTR_MITIGATION) {
++                 if( received > 1 ) {
++                         if( ! tp->mit_on ) {
++                                 tp->mit_on = 1;
++                                 outl(mit_table[MIT_TABLE], dev->base_addr + CSR11);
++                         }
++                  }
++                 else {
++                         if( tp->mit_on ) {
++                                 tp->mit_on = 0;
++                                 outl(0, dev->base_addr + CSR11);
++                         }
++                  }
++          }
++
++#endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */
++
++         dev->quota -= received;
++         *budget -= received;
++
++         tulip_refill_rx(dev);
++
++         /* If RX ring is not full we are out of memory. */
++         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
++
++         /* Remove us from polling list and enable RX intr. */
++
++         netif_rx_complete(dev);
++         outl(tulip_tbl[tp->chip_id].valid_intrs, dev->base_addr+CSR7);
++
++         /* The last op happens after poll completion. Which means the following:
++          * 1. it can race with disabling irqs in irq handler
++          * 2. it can race with dise/enabling irqs in other poll threads
++          * 3. if an irq raised after beginning loop, it will be immediately
++          *    triggered here.
++          *
++          * Summarizing: the logic results in some redundant irqs both
++          * due to races in masking and due to too late acking of already
++          * processed irqs. But it must not result in losing events.
++          */
++
++         return 0;
++
++ not_done:
++         if (!received) {
++
++                 received = dev->quota; /* Not to happen */
++         }
++         dev->quota -= received;
++         *budget -= received;
++
++         if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
++             tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
++                 tulip_refill_rx(dev);
++
++         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
++
++         return 1;
++
++
++ oom:    /* Executed with RX ints disabled */
++
++
++         /* Start timer, stop polling, but do not enable rx interrupts. */
++         mod_timer(&tp->oom_timer, jiffies+1);
++
++         /* Think: timer_pending() was an explicit signature of bug.
++          * Timer can be pending now but fired and completed
++          * before we did netif_rx_complete(). See? We would lose it. */
++
++         /* remove ourselves from the polling list */
++         netif_rx_complete(dev);
++
++         return 0;
++}
++
++#else /* CONFIG_TULIP_NAPI */
++
++static int tulip_rx(struct net_device *dev)
++{
++	struct tulip_private *tp = (struct tulip_private *)dev->priv;
++	int entry = tp->cur_rx % RX_RING_SIZE;
++	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
++	int received = 0;
++
++	if (tulip_debug > 4)
++		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
++			   tp->rx_ring[entry].status);
+ 	/* If we own the next entry, it is a new packet. Send it up. */
+ 	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+ 		s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+@@ -163,11 +406,6 @@ static int tulip_rx(struct net_device *d
+ 			}
+ #endif
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        drop = atomic_read(&netdev_dropping);
+-                        if (drop)
+-                                goto throttle;
+-#endif
+ 			/* Check if the packet is long enough to accept without copying
+ 			   to a minimally-sized skbuff. */
+ 			if (pkt_len < tulip_rx_copybreak
+@@ -209,44 +447,9 @@ static int tulip_rx(struct net_device *d
+ 				tp->rx_buffers[entry].mapping = 0;
+ 			}
+ 			skb->protocol = eth_type_trans(skb, dev);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        mit_sel =
+-#endif
+-			netif_rx(skb);
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        switch (mit_sel) {
+-                        case NET_RX_SUCCESS:
+-                        case NET_RX_CN_LOW:
+-                        case NET_RX_CN_MOD:
+-                                break;
+-
+-                        case NET_RX_CN_HIGH:
+-                                rx_work_limit -= NET_RX_CN_HIGH; /* additional*/
+-                                break;
+-                        case NET_RX_DROP:
+-                                rx_work_limit = -1;
+-                                break;
+-                        default:
+-                                printk("unknown feedback return code %d\n", mit_sel);
+-                                break;
+-                        }
++			netif_rx(skb);
+ 
+-                        drop = atomic_read(&netdev_dropping);
+-                        if (drop) {
+-throttle:
+-                                rx_work_limit = -1;
+-                                mit_sel = NET_RX_DROP;
+-
+-                                if (tp->fc_bit) {
+-                                        long ioaddr = dev->base_addr;
+-
+-                                        /* disable Rx & RxNoBuf ints. */
+-                                        outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7);
+-                                        set_bit(tp->fc_bit, &netdev_fc_xoff);
+-                                }
+-                        }
+-#endif
+ 			dev->last_rx = jiffies;
+ 			tp->stats.rx_packets++;
+ 			tp->stats.rx_bytes += pkt_len;
+@@ -254,42 +457,9 @@ throttle:
+ 		received++;
+ 		entry = (++tp->cur_rx) % RX_RING_SIZE;
+ 	}
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-
+-        /* We use this simplistic scheme for IM. It's proven by
+-           real life installations. We can have IM enabled
+-           continuesly but this would cause unnecessary latency.
+-           Unfortunely we can't use all the NET_RX_* feedback here.
+-           This would turn on IM for devices that is not contributing
+-           to backlog congestion with unnecessary latency.
+-
+-           We monitor the device RX-ring and have:
+-
+-           HW Interrupt Mitigation either ON or OFF.
+-
+-           ON:  More then 1 pkt received (per intr.) OR we are dropping
+-           OFF: Only 1 pkt received
+-
+-           Note. We only use min and max (0, 15) settings from mit_table */
+-
+-
+-        if( tp->flags &  HAS_INTR_MITIGATION) {
+-                if((received > 1 || mit_sel == NET_RX_DROP)
+-                   && tp->mit_sel != 15 ) {
+-                        tp->mit_sel = 15;
+-                        tp->mit_change = 1; /* Force IM change */
+-                }
+-                if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) {
+-                        tp->mit_sel = 0;
+-                        tp->mit_change = 1; /* Force IM change */
+-                }
+-        }
+-
+-        return RX_RING_SIZE+1; /* maxrx+1 */
+-#else
+ 	return received;
+-#endif
+ }
++#endif  /* CONFIG_TULIP_NAPI */
+ 
+ static inline unsigned int phy_interrupt (struct net_device *dev)
+ {
+@@ -323,7 +493,6 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+ 	long ioaddr = dev->base_addr;
+ 	int csr5;
+-	int entry;
+ 	int missed;
+ 	int rx = 0;
+ 	int tx = 0;
+@@ -331,6 +500,11 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 	int maxrx = RX_RING_SIZE;
+ 	int maxtx = TX_RING_SIZE;
+ 	int maxoi = TX_RING_SIZE;
++#ifdef CONFIG_TULIP_NAPI
++	int rxd = 0;
++#else
++	int entry;
++#endif
+ 	unsigned int work_count = tulip_max_interrupt_work;
+ 	unsigned int handled = 0;
+ 
+@@ -346,22 +520,41 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 	tp->nir++;
+ 
+ 	do {
++
++#ifdef CONFIG_TULIP_NAPI
++
++		if (!rxd && (csr5 & (RxIntr | RxNoBuf))) {
++			rxd++;
++			/* Mask RX intrs and add the device to poll list. */
++			outl(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
++			netif_rx_schedule(dev);
++
++			if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
++                               break;
++		}
++
++               /* Acknowledge the interrupt sources we handle here ASAP
++                  the poll function does Rx and RxNoBuf acking */
++
++		outl(csr5 & 0x0001ff3f, ioaddr + CSR5);
++
++#else
+ 		/* Acknowledge all of the current interrupt sources ASAP. */
+ 		outl(csr5 & 0x0001ffff, ioaddr + CSR5);
+ 
+-		if (tulip_debug > 4)
+-			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
+-				   dev->name, csr5, inl(dev->base_addr + CSR5));
+ 
+ 		if (csr5 & (RxIntr | RxNoBuf)) {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        if ((!tp->fc_bit) ||
+-			    (!test_bit(tp->fc_bit, &netdev_fc_xoff)))
+-#endif
+ 				rx += tulip_rx(dev);
+ 			tulip_refill_rx(dev);
+ 		}
+ 
++#endif /*  CONFIG_TULIP_NAPI */
++
++		if (tulip_debug > 4)
++			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
++			       dev->name, csr5, inl(dev->base_addr + CSR5));
++
++
+ 		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
+ 			unsigned int dirty_tx;
+ 
+@@ -462,15 +655,8 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 			}
+ 			if (csr5 & RxDied) {		/* Missed a Rx frame. */
+                                 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-				if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
+-					tp->stats.rx_errors++;
+-					tulip_start_rxtx(tp);
+-				}
+-#else
+ 				tp->stats.rx_errors++;
+ 				tulip_start_rxtx(tp);
+-#endif
+ 			}
+ 			/*
+ 			 * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
+@@ -504,10 +690,6 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 			if (tulip_debug > 2)
+ 				printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
+ 					   dev->name, csr5);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        if (tp->fc_bit && (test_bit(tp->fc_bit, &netdev_fc_xoff)))
+-                          if (net_ratelimit()) printk("BUG!! enabling interrupt when FC off (timerintr.) \n");
+-#endif
+ 			outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+ 			tp->ttimer = 0;
+ 			oi++;
+@@ -520,16 +702,9 @@ irqreturn_t tulip_interrupt(int irq, voi
+                        /* Acknowledge all interrupt sources. */
+                         outl(0x8001ffff, ioaddr + CSR5);
+                         if (tp->flags & HAS_INTR_MITIGATION) {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                                if(tp->mit_change) {
+-                                        outl(mit_table[tp->mit_sel], ioaddr + CSR11);
+-                                        tp->mit_change = 0;
+-                                }
+-#else
+                      /* Josip Loncaric at ICASE did extensive experimentation
+ 			to develop a good interrupt mitigation setting.*/
+                                 outl(0x8b240000, ioaddr + CSR11);
+-#endif
+                         } else if (tp->chip_id == LC82C168) {
+ 				/* the LC82C168 doesn't have a hw timer.*/
+ 				outl(0x00, ioaddr + CSR7);
+@@ -537,10 +712,8 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 			} else {
+                           /* Mask all interrupting sources, set timer to
+ 				re-enable. */
+-#ifndef CONFIG_NET_HW_FLOWCONTROL
+                                 outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7);
+                                 outl(0x0012, ioaddr + CSR11);
+-#endif
+                         }
+ 			break;
+ 		}
+@@ -550,6 +723,21 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 			break;
+ 
+ 		csr5 = inl(ioaddr + CSR5);
++
++#ifdef CONFIG_TULIP_NAPI
++		if (rxd)
++			csr5 &= ~RxPollInt;
++	} while ((csr5 & (TxNoBuf |
++			  TxDied |
++			  TxIntr |
++			  TimerInt |
++			  /* Abnormal intr. */
++			  RxDied |
++			  TxFIFOUnderflow |
++			  TxJabber |
++			  TPLnkFail |
++			  SytemError )) != 0);
++#else
+ 	} while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
+ 
+ 	tulip_refill_rx(dev);
+@@ -574,6 +762,7 @@ irqreturn_t tulip_interrupt(int irq, voi
+ 			}
+ 		}
+ 	}
++#endif /* CONFIG_TULIP_NAPI */
+ 
+ 	if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
+ 		tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+--- linux-2.6.0-test6/drivers/net/tulip/Kconfig	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tulip/Kconfig	2003-10-05 00:34:49.000000000 -0700
+@@ -68,6 +68,26 @@ config TULIP_MMIO
+ 	  obscure bugs if your mainboard has memory controller timing issues.
+ 	  If in doubt, say N.
+ 
++config TULIP_NAPI
++	bool "Use NAPI RX polling "
++	depends on TULIP
++	---help---
++	  This is of useful for servers and routers dealing with high network loads.
++
++	  See <file:Documentation/networking/NAPI_HOWTO.txt>.
++
++	  If in doubt, say N.
++
++config TULIP_NAPI_HW_MITIGATION
++	bool "Use Interrupt Mitigation "
++	depends on TULIP_NAPI
++	---help---
++	  Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
++	  RX interrupts but itself. Although this reduces RX interrupts even at
++	  low levels traffic at the cost of a small latency.
++
++	  If in doubt, say Y.
++
+ config DE4X5
+ 	tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
+ 	depends on NET_TULIP && (PCI || EISA)
+--- linux-2.6.0-test6/drivers/net/tulip/tulip_core.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/tulip/tulip_core.c	2003-10-05 00:34:49.000000000 -0700
+@@ -14,11 +14,17 @@
+ 
+ */
+ 
++#include <linux/config.h>
++
+ #define DRV_NAME	"tulip"
++#ifdef CONFIG_TULIP_NAPI
++#define DRV_VERSION    "1.1.13-NAPI" /* Keep at least for test */
++#else
+ #define DRV_VERSION	"1.1.13"
++#endif
+ #define DRV_RELDATE	"May 11, 2002"
+ 
+-#include <linux/config.h>
++
+ #include <linux/module.h>
+ #include "tulip.h"
+ #include <linux/pci.h>
+@@ -246,6 +252,7 @@ static void tulip_down(struct net_device
+ static struct net_device_stats *tulip_get_stats(struct net_device *dev);
+ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static void set_rx_mode(struct net_device *dev);
++static void poll_tulip(struct net_device *dev);
+ 
+ 
+ 
+@@ -465,29 +472,16 @@ media_picked:
+ 	   to an alternate media type. */
+ 	tp->timer.expires = RUN_AT(next_tick);
+ 	add_timer(&tp->timer);
+-}
+-
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-/* Enable receiver */
+-void tulip_xon(struct net_device *dev)
+-{
+-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
+-
+-        clear_bit(tp->fc_bit, &netdev_fc_xoff);
+-        if (netif_running(dev)){
+-
+-                tulip_refill_rx(dev);
+-                outl(tulip_tbl[tp->chip_id].valid_intrs,  dev->base_addr+CSR7);
+-        }
+-}
++#ifdef CONFIG_TULIP_NAPI
++	init_timer(&tp->oom_timer);
++        tp->oom_timer.data = (unsigned long)dev;
++        tp->oom_timer.function = oom_timer;
+ #endif
++}
+ 
+ static int
+ tulip_open(struct net_device *dev)
+ {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
+-#endif
+ 	int retval;
+ 
+ 	if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)))
+@@ -497,10 +491,6 @@ tulip_open(struct net_device *dev)
+ 
+ 	tulip_up (dev);
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        tp->fc_bit = netdev_register_fc(dev, tulip_xon);
+-#endif
+-
+ 	netif_start_queue (dev);
+ 
+ 	return 0;
+@@ -581,10 +571,7 @@ static void tulip_tx_timeout(struct net_
+ #endif
+ 
+ 	/* Stop and restart the chip's Tx processes . */
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
+-                printk("BUG tx_timeout restarting rx when fc on\n");
+-#endif
++
+ 	tulip_restart_rxtx(tp);
+ 	/* Trigger an immediate transmit demand. */
+ 	outl(0, ioaddr + CSR1);
+@@ -741,7 +728,9 @@ static void tulip_down (struct net_devic
+ 	unsigned long flags;
+ 
+ 	del_timer_sync (&tp->timer);
+-
++#ifdef CONFIG_TULIP_NAPI
++	del_timer_sync (&tp->oom_timer);
++#endif
+ 	spin_lock_irqsave (&tp->lock, flags);
+ 
+ 	/* Disable interrupts by clearing the interrupt mask. */
+@@ -780,13 +769,6 @@ static int tulip_close (struct net_devic
+ 
+ 	netif_stop_queue (dev);
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        if (tp->fc_bit) {
+-                int bit = tp->fc_bit;
+-                tp->fc_bit = 0;
+-                netdev_unregister_fc(bit);
+-        }
+-#endif
+ 	tulip_down (dev);
+ 
+ 	if (tulip_debug > 1)
+@@ -1627,10 +1609,17 @@ static int __devinit tulip_init_one (str
+ 	dev->hard_start_xmit = tulip_start_xmit;
+ 	dev->tx_timeout = tulip_tx_timeout;
+ 	dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_TULIP_NAPI
++	dev->poll = tulip_poll;
++	dev->weight = 16;
++#endif
+ 	dev->stop = tulip_close;
+ 	dev->get_stats = tulip_get_stats;
+ 	dev->do_ioctl = private_ioctl;
+ 	dev->set_multicast_list = set_rx_mode;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = &poll_tulip;
++#endif
+ 
+ 	if (register_netdev(dev))
+ 		goto err_out_free_ring;
+@@ -1788,6 +1777,24 @@ static void __devexit tulip_remove_one (
+ }
+ 
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_tulip (struct net_device *dev)
++{
++       disable_irq(dev->irq);
++       tulip_interrupt (dev->irq, dev, NULL);
++       enable_irq(dev->irq);
++}
++
++#endif
++
++
+ static struct pci_driver tulip_driver = {
+ 	.name		= DRV_NAME,
+ 	.id_table	= tulip_pci_tbl,
+--- linux-2.6.0-test6/drivers/net/tulip/tulip.h	2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/net/tulip/tulip.h	2003-10-05 00:34:49.000000000 -0700
+@@ -126,6 +126,7 @@ enum pci_cfg_driver_reg {
+ 	CFDD_Snooze = (1 << 30),
+ };
+ 
++#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
+ 
+ /* The bits in the CSR5 status registers, mostly interrupt sources. */
+ enum status_bits {
+@@ -251,9 +252,9 @@ enum t21143_csr6_bits {
+    Making the Tx ring too large decreases the effectiveness of channel
+    bonding and packet priority.
+    There are no ill effects from too-large receive rings. */
+-#define TX_RING_SIZE	16
+-#define RX_RING_SIZE	32
+ 
++#define TX_RING_SIZE	32
++#define RX_RING_SIZE	128
+ #define MEDIA_MASK     31
+ 
+ #define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
+@@ -343,17 +344,15 @@ struct tulip_private {
+ 	int flags;
+ 	struct net_device_stats stats;
+ 	struct timer_list timer;	/* Media selection timer. */
++	struct timer_list oom_timer;    /* Out of memory timer. */
+ 	u32 mc_filter[2];
+ 	spinlock_t lock;
+ 	spinlock_t mii_lock;
+ 	unsigned int cur_rx, cur_tx;	/* The next free ring entry */
+ 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
+ 
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-#define RX_A_NBF_STOP 0xffffff3f /* To disable RX and RX-NOBUF ints. */
+-        int fc_bit;
+-        int mit_sel;
+-        int mit_change; /* Signal for Interrupt Mitigtion */
++#ifdef 	CONFIG_TULIP_NAPI_HW_MITIGATION
++        int mit_on;
+ #endif
+ 	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
+ 	unsigned int full_duplex_lock:1;
+@@ -415,6 +414,10 @@ extern unsigned int tulip_max_interrupt_
+ extern int tulip_rx_copybreak;
+ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+ int tulip_refill_rx(struct net_device *dev);
++#ifdef CONFIG_TULIP_NAPI
++int tulip_poll(struct net_device *dev, int *budget);
++#endif
++
+ 
+ /* media.c */
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
+@@ -438,6 +441,7 @@ extern int tulip_debug;
+ extern const char * const medianame[];
+ extern const char tulip_media_cap[];
+ extern struct tulip_chip_table tulip_tbl[];
++void oom_timer(unsigned long data);
+ extern u8 t21040_csr13[];
+ 
+ #ifndef USE_IO_OPS
+--- linux-2.6.0-test6/drivers/net/wan/comx-hw-munich.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/comx-hw-munich.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1849,7 +1849,7 @@ static int MUNICH_open(struct net_device
+     if (board->isx21)
+     {
+ 	init_timer(&board->modemline_timer);
+-	board->modemline_timer.data = (unsigned int)board;
++	board->modemline_timer.data = (unsigned long)board;
+ 	board->modemline_timer.function = pcicom_modemline;
+ 	board->modemline_timer.expires = jiffies + HZ;
+ 	add_timer((struct timer_list *)&board->modemline_timer);
+--- linux-2.6.0-test6/drivers/net/wan/dscc4.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/dscc4.c	2003-10-05 00:36:13.000000000 -0700
+@@ -107,7 +107,7 @@
+ #include <linux/hdlc.h>
+ 
+ /* Version */
+-static const char version[] = "$Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $ for Linux\n";
++static const char version[] = "$Id: 2.6.0-test6-mm4.patch,v 1.2 2003/12/03 03:13:28 phil Exp $ for Linux\n";
+ static int debug;
+ static int quartz;
+ 
+@@ -592,6 +592,7 @@ static inline int dscc4_xpr_ack(struct d
+ 	return (i >= 0 ) ? i : -EAGAIN;
+ }
+ 
++#if 0 /* dscc4_{rx/tx}_reset are both unreliable - more tweak needed */
+ static void dscc4_rx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+ {
+ 	unsigned long flags;
+@@ -606,6 +607,9 @@ static void dscc4_rx_reset(struct dscc4_
+ 	spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags);
+ }
+ 
++#endif
++
++#if 0
+ static void dscc4_tx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+ {
+ 	u16 i = 0;
+@@ -625,6 +629,7 @@ static void dscc4_tx_reset(struct dscc4_
+ 	if (dscc4_do_action(dev, "Rdt") < 0)
+ 		printk(KERN_ERR "%s: Tx reset failed\n", dev->name);
+ }
++#endif
+ 
+ /* TODO: (ab)use this function to refill a completely depleted RX ring. */
+ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
+@@ -859,7 +864,7 @@ static int dscc4_found1(struct pci_dev *
+ {
+ 	struct dscc4_pci_priv *ppriv;
+ 	struct dscc4_dev_priv *root;
+-	int i = 0;
++	int i, ret = -ENOMEM;
+ 
+ 	root = (struct dscc4_dev_priv *)
+ 		kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
+@@ -900,7 +905,8 @@ static int dscc4_found1(struct pci_dev *
+ 		hdlc->xmit = dscc4_start_xmit;
+ 		hdlc->attach = dscc4_hdlc_attach;
+ 
+-	        if (register_hdlc_device(hdlc)) {
++		ret = register_hdlc_device(hdlc);
++		if (ret < 0) {
+ 			printk(KERN_ERR "%s: unable to register\n", DRV_NAME);
+ 			goto err_unregister;
+ 	        }
+@@ -908,17 +914,20 @@ static int dscc4_found1(struct pci_dev *
+ 		dscc4_init_registers(dpriv, d);
+ 		dpriv->parity = PARITY_CRC16_PR0_CCITT;
+ 		dpriv->encoding = ENCODING_NRZ;
+-		if (dscc4_init_ring(d)) {
++
++		ret = dscc4_init_ring(d);
++		if (ret < 0) {
+ 			unregister_hdlc_device(hdlc);
+ 			goto err_unregister;
+ 		}
+ 	}
+-	if (dscc4_set_quartz(root, quartz) < 0)
++	ret = dscc4_set_quartz(root, quartz);
++	if (ret < 0)
+ 		goto err_unregister;
+ 	ppriv->root = root;
+ 	spin_lock_init(&ppriv->lock);
+ 	pci_set_drvdata(pdev, ppriv);
+-	return 0;
++	return ret;
+ 
+ err_unregister:
+ 	while (--i >= 0) {
+@@ -929,7 +938,7 @@ err_unregister:
+ err_free_dev:
+ 	kfree(root);
+ err_out:
+-	return -1;
++	return ret;
+ };
+ 
+ /* FIXME: get rid of the unneeded code */
+@@ -1092,9 +1101,7 @@ done:
+ 
+ err_disable_scc_events:
+ 	scc_writel(0xffffffff, dpriv, dev, IMR);
+-err_free_ring:
+ 	scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0);
+-	dscc4_release_ring(dpriv);
+ err_out:
+ 	hdlc_close(hdlc);
+ err:
+@@ -1160,7 +1167,6 @@ static int dscc4_close(struct net_device
+ 	dpriv->flags |= FakeReset;
+ 
+ 	hdlc_close(hdlc);
+-	dscc4_release_ring(dpriv);
+ 
+ 	return 0;
+ }
+@@ -2006,6 +2012,7 @@ static int dscc4_hdlc_attach(hdlc_device
+ 	return 0;
+ }
+ 
++#ifndef MODULE
+ static int __init dscc4_setup(char *str)
+ {
+ 	int *args[] = { &debug, &quartz, NULL }, **p = args;
+@@ -2016,6 +2023,7 @@ static int __init dscc4_setup(char *str)
+ }
+ 
+ __setup("dscc4.setup=", dscc4_setup);
++#endif
+ 
+ static struct pci_device_id dscc4_pci_tbl[] = {
+ 	{ PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_DSCC4,
+--- linux-2.6.0-test6/drivers/net/wan/sbni.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/sbni.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1300,12 +1300,9 @@ sbni_ioctl( struct net_device  *dev,  st
+   
+ 	switch( cmd ) {
+ 	case  SIOCDEVGETINSTATS :
+-		error = verify_area( VERIFY_WRITE, ifr->ifr_data,
+-				     sizeof(struct sbni_in_stats) );
+-		if( !error )
+-			if (copy_to_user( ifr->ifr_data, &nl->in_stats,
+-				      sizeof(struct sbni_in_stats) ))
+-				return -EFAULT;
++		if (copy_to_user( ifr->ifr_data, &nl->in_stats,
++					sizeof(struct sbni_in_stats) ))
++			error = -EFAULT;
+ 		break;
+ 
+ 	case  SIOCDEVRESINSTATS :
+@@ -1321,11 +1318,8 @@ sbni_ioctl( struct net_device  *dev,  st
+ 		flags.rxl	= nl->cur_rxl_index;
+ 		flags.fixed_rxl	= nl->delta_rxl == 0;
+ 
+-		error = verify_area( VERIFY_WRITE, ifr->ifr_data,
+-				     sizeof flags );
+-		if( !error )
+-			if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
+-				return -EFAULT;
++		if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
++			error = -EFAULT;
+ 		break;
+ 
+ 	case  SIOCDEVSHWSTATE :
+@@ -1353,10 +1347,6 @@ sbni_ioctl( struct net_device  *dev,  st
+ 		if( current->euid != 0 )	/* root only */
+ 			return  -EPERM;
+ 
+-		if( (error = verify_area( VERIFY_READ, ifr->ifr_data,
+-					  sizeof slave_name )) != 0 )
+-			return  error;
+-
+ 		if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
+ 			return -EFAULT;
+ 		slave_dev = dev_get_by_name( slave_name );
+--- linux-2.6.0-test6/drivers/net/wan/syncppp.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/syncppp.c	2003-10-05 00:33:24.000000000 -0700
+@@ -236,7 +236,7 @@ void sppp_input (struct net_device *dev,
+ 		sp->ipkts++;
+ 	}
+ 
+-	if (skb->len <= PPP_HEADER_LEN) {
++	if (!pskb_may_pull(skb, PPP_HEADER_LEN)) {
+ 		/* Too small packet, drop it. */
+ 		if (sp->pp_flags & PP_DEBUG)
+ 			printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",
+@@ -473,7 +473,7 @@ static void sppp_lcp_input (struct sppp 
+ 	u8 *p, opt[6];
+ 	u32 rmagic;
+ 
+-	if (len < 4) {
++	if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
+ 		if (sp->pp_flags & PP_DEBUG)
+ 			printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n",
+ 				dev->name, len);
+@@ -707,7 +707,9 @@ static void sppp_cisco_input (struct spp
+ 	struct cisco_packet *h;
+ 	struct net_device *dev = sp->pp_if;
+ 
+-	if (skb->len != CISCO_PACKET_LEN && skb->len != CISCO_BIG_PACKET_LEN) {
++	if (!pskb_may_pull(skb, sizeof(struct cisco_packet))
++	    || (skb->len != CISCO_PACKET_LEN
++		&& skb->len != CISCO_BIG_PACKET_LEN)) {
+ 		if (sp->pp_flags & PP_DEBUG)
+ 			printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n",
+ 				dev->name,  skb->len);
+@@ -1211,8 +1213,7 @@ static void sppp_ipcp_input (struct sppp
+ 	struct net_device *dev = sp->pp_if;
+ 	int len = skb->len;
+ 
+-	if (len < 4) 
+-	{
++	if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
+ 		if (sp->pp_flags & PP_DEBUG)
+ 			printk (KERN_WARNING "%s: invalid ipcp packet length: %d bytes\n",
+ 				dev->name,  len);
+--- linux-2.6.0-test6/drivers/net/wireless/arlan-main.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/arlan-main.c	2003-10-05 00:33:24.000000000 -0700
+@@ -5,7 +5,6 @@
+  * This module provides support for the Arlan 655 card made by Aironet
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include "arlan.h"
+ 
+@@ -721,9 +720,9 @@ static int arlan_hw_tx(struct net_device
+ 	else
+ 	{
+ 		netif_stop_queue (dev);
+-		return -1;
+ 		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
+ 			printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds);
++		return -1;
+ 	}
+ 	priv->out_bytes += length;
+ 	priv->out_bytes10 += length;
+@@ -1881,6 +1880,8 @@ int __init arlan_probe(struct net_device
+ 
+ #ifdef  MODULE
+ 
++static int probe = probeUNKNOWN;
++
+ static int __init arlan_find_devices(void)
+ {
+ 	int m;
+--- linux-2.6.0-test6/drivers/parisc/superio.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/parisc/superio.c	2003-10-05 00:33:24.000000000 -0700
+@@ -530,11 +530,6 @@ static struct pci_driver superio_driver 
+ 
+ static int __init superio_modinit(void)
+ {
+-#ifdef CONFIG_SERIAL_8250
+-	extern int serial8250_init(void);
+-	serial8250_init();
+-#endif
+-
+ 	return pci_module_init(&superio_driver);
+ }
+ 
+@@ -543,5 +538,10 @@ static void __exit superio_exit(void)
+ 	pci_unregister_driver(&superio_driver);
+ }
+ 
+-module_init(superio_modinit);
++/* Make late initcall to ensure the serial and tty layers are initialised
++ * before we start superio.
++ *
++ * FIXME: does this break the superio console?
++ */
++late_initcall(superio_modinit);
+ module_exit(superio_exit);
+--- linux-2.6.0-test6/drivers/pci/hotplug/cpqphp.h	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pci/hotplug/cpqphp.h	2003-10-05 00:33:24.000000000 -0700
+@@ -766,7 +766,6 @@ static inline int wait_for_ctrl_irq (str
+ 	set_current_state(TASK_INTERRUPTIBLE);
+ 	/* Sleep for up to 1 second to wait for the LED to change. */
+ 	schedule_timeout(1*HZ);
+-	set_current_state(TASK_RUNNING);
+ 	remove_wait_queue(&ctrl->queue, &wait);
+ 	if (signal_pending(current))
+ 		retval =  -EINTR;
+--- linux-2.6.0-test6/drivers/pci/hotplug/pci_hotplug_core.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pci/hotplug/pci_hotplug_core.c	2003-10-05 00:33:24.000000000 -0700
+@@ -69,7 +69,7 @@ static int debug;
+ 
+ static LIST_HEAD(pci_hotplug_slot_list);
+ 
+-static struct subsystem hotplug_slots_subsys;
++struct subsystem pci_hotplug_slots_subsys;
+ 
+ static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+ 		struct attribute *attr, char *buf)
+@@ -104,7 +104,7 @@ static struct kobj_type hotplug_slot_kty
+ 	.release = &hotplug_slot_release,
+ };
+ 
+-static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
++decl_subsys(pci_hotplug_slots, &hotplug_slot_ktype, NULL);
+ 
+ 
+ /* these strings match up with the values in pci_bus_speed */
+@@ -534,7 +534,7 @@ int pci_hp_register (struct hotplug_slot
+ 		return -EINVAL;
+ 
+ 	strlcpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+-	kobj_set_kset_s(slot, hotplug_slots_subsys);
++	kobj_set_kset_s(slot, pci_hotplug_slots_subsys);
+ 
+ 	/* this can fail if we have already registered a slot with the same name */
+ 	if (kobject_register(&slot->kobj)) {
+@@ -629,8 +629,8 @@ static int __init pci_hotplug_init (void
+ {
+ 	int result;
+ 
+-	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+-	result = subsystem_register(&hotplug_slots_subsys);
++	kset_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys);
++	result = subsystem_register(&pci_hotplug_slots_subsys);
+ 	if (result) {
+ 		err("Register subsys with error %d\n", result);
+ 		goto exit;
+@@ -645,7 +645,7 @@ static int __init pci_hotplug_init (void
+ 	goto exit;
+ 	
+ err_subsys:
+-	subsystem_unregister(&hotplug_slots_subsys);
++	subsystem_unregister(&pci_hotplug_slots_subsys);
+ exit:
+ 	return result;
+ }
+@@ -653,7 +653,7 @@ exit:
+ static void __exit pci_hotplug_exit (void)
+ {
+ 	cpci_hotplug_exit();
+-	subsystem_unregister(&hotplug_slots_subsys);
++	subsystem_unregister(&pci_hotplug_slots_subsys);
+ }
+ 
+ module_init(pci_hotplug_init);
+@@ -665,6 +665,7 @@ MODULE_LICENSE("GPL");
+ MODULE_PARM(debug, "i");
+ MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+ 
++EXPORT_SYMBOL_GPL(pci_hotplug_slots_subsys);
+ EXPORT_SYMBOL_GPL(pci_hp_register);
+ EXPORT_SYMBOL_GPL(pci_hp_deregister);
+ EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
+--- linux-2.6.0-test6/drivers/pci/hotplug/pci_hotplug.h	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pci/hotplug/pci_hotplug.h	2003-10-05 00:33:24.000000000 -0700
+@@ -145,6 +145,7 @@ extern int pci_hp_register		(struct hotp
+ extern int pci_hp_deregister		(struct hotplug_slot *slot);
+ extern int pci_hp_change_slot_info	(struct hotplug_slot *slot,
+ 					 struct hotplug_slot_info *info);
++extern struct subsystem pci_hotplug_slots_subsys;
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/drivers/pci/Makefile	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/pci/Makefile	2003-10-05 00:36:20.000000000 -0700
+@@ -4,7 +4,6 @@
+ 
+ obj-y		+= access.o bus.o probe.o remove.o pci.o pool.o quirks.o \
+ 			names.o pci-driver.o search.o pci-sysfs.o
+-obj-$(CONFIG_PM)  += power.o
+ obj-$(CONFIG_PROC_FS) += proc.o
+ 
+ ifndef CONFIG_SPARC64
+@@ -28,6 +27,7 @@ obj-$(CONFIG_PPC64) += setup-bus.o
+ obj-$(CONFIG_SGI_IP27) += setup-irq.o
+ obj-$(CONFIG_SGI_IP32) += setup-irq.o
+ obj-$(CONFIG_X86_VISWS) += setup-irq.o
++obj-$(CONFIG_PCI_USE_VECTOR) += msi.o
+ 
+ # Cardbus & CompactPCI use setup-bus
+ obj-$(CONFIG_HOTPLUG) += setup-bus.o
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/pci/msi.c	2003-10-05 00:36:21.000000000 -0700
+@@ -0,0 +1,1062 @@
++/*
++ * linux/drivers/pci/msi.c
++ */
++
++#include <linux/mm.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/ioport.h>
++#include <linux/smp_lock.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++#include <linux/acpi.h>
++
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/desc.h>
++#include <asm/io_apic.h>
++#include <mach_apic.h>
++
++#include <linux/pci_msi.h>
++
++_DEFINE_DBG_BUFFER
++
++static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
++static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
++static kmem_cache_t* msi_cachep;
++
++static int pci_msi_enable = 1;
++static int nr_alloc_vectors = 0;
++static int nr_released_vectors = 0;
++static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
++static int nr_msix_devices = 0;
++
++#ifndef CONFIG_X86_IO_APIC
++int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
++int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
++#endif
++
++static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
++{
++	memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
++}
++
++static int msi_cache_init(void)
++{
++	msi_cachep = kmem_cache_create("msi_cache",
++			NR_IRQS * sizeof(struct msi_desc),
++		       	0, SLAB_HWCACHE_ALIGN, msi_cache_ctor, NULL);
++	if (!msi_cachep)
++		return -ENOMEM;
++
++	return 0;
++}
++
++static void msi_set_mask_bit(unsigned int vector, int flag)
++{
++	struct msi_desc *entry;
++
++	entry = (struct msi_desc *)msi_desc[vector];
++	if (!entry || !entry->dev || !entry->mask_base)
++		return;
++	switch (entry->msi_attrib.type) {
++	case PCI_CAP_ID_MSI:
++	{
++		int		pos;
++		unsigned int	mask_bits;
++
++		pos = entry->mask_base;
++	        entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn,
++				pos, 4, &mask_bits);
++		mask_bits &= ~(1);
++		mask_bits |= flag;
++	        entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn,
++				pos, 4, mask_bits);
++		break;
++	}
++	case PCI_CAP_ID_MSIX:
++	{
++		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
++			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
++		writel(flag, entry->mask_base + offset);
++		break;
++	}
++	default:
++		break;
++	}
++}
++
++#ifdef CONFIG_SMP
++static void set_msi_affinity(unsigned int vector, unsigned long cpu_mask)
++{
++	struct msi_desc *entry;
++	struct msg_address address;
++	unsigned int dest_id;
++
++	entry = (struct msi_desc *)msi_desc[vector];
++	if (!entry || !entry->dev)
++		return;
++
++	switch (entry->msi_attrib.type) {
++	case PCI_CAP_ID_MSI:
++	{
++		int pos;
++
++   		if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI)))
++			return;
++
++	        entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn,
++			msi_lower_address_reg(pos), 4,
++			&address.lo_address.value);
++		dest_id = (address.lo_address.u.dest_id &
++			MSI_ADDRESS_HEADER_MASK) |
++			(cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT);
++		address.lo_address.u.dest_id = dest_id;
++		entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
++		entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn,
++			msi_lower_address_reg(pos), 4,
++			address.lo_address.value);
++		break;
++	}
++	case PCI_CAP_ID_MSIX:
++	{
++		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
++			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
++
++		address.lo_address.value = readl(entry->mask_base + offset);
++		dest_id = (address.lo_address.u.dest_id &
++			MSI_ADDRESS_HEADER_MASK) |
++			(cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT);
++		address.lo_address.u.dest_id = dest_id;
++		entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
++		writel(address.lo_address.value, entry->mask_base + offset);
++		break;
++	}
++	default:
++		break;
++	}
++}
++
++static inline void move_msi(int vector)
++{
++	if (unlikely(pending_irq_balance_cpumask[vector])) {
++		set_msi_affinity(vector, pending_irq_balance_cpumask[vector]);
++		pending_irq_balance_cpumask[vector] = 0;
++	}
++}
++#endif
++
++static void mask_MSI_irq(unsigned int vector)
++{
++	msi_set_mask_bit(vector, 1);
++}
++
++static void unmask_MSI_irq(unsigned int vector)
++{
++	msi_set_mask_bit(vector, 0);
++}
++
++static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
++{
++	return 0;	/* never anything pending */
++}
++
++static void pci_disable_msi(unsigned int vector);
++static void shutdown_msi_irq(unsigned int vector)
++{
++	pci_disable_msi(vector);
++}
++
++#define shutdown_msi_irq_wo_maskbit	shutdown_msi_irq
++static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
++static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
++static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
++static void end_msi_irq_wo_maskbit(unsigned int vector)
++{
++	move_msi(vector);
++	ack_APIC_irq();
++}
++
++static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
++{
++	unmask_MSI_irq(vector);
++	return 0;	/* never anything pending */
++}
++
++#define shutdown_msi_irq_w_maskbit	shutdown_msi_irq
++#define enable_msi_irq_w_maskbit	unmask_MSI_irq
++#define disable_msi_irq_w_maskbit	mask_MSI_irq
++#define ack_msi_irq_w_maskbit		mask_MSI_irq
++
++static void end_msi_irq_w_maskbit(unsigned int vector)
++{
++	move_msi(vector);
++	unmask_MSI_irq(vector);
++	ack_APIC_irq();
++}
++
++/*
++ * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI-X Capability Structure.
++ */
++static struct hw_interrupt_type msix_irq_type = {
++	.typename	= "PCI MSI-X",
++	.startup	= startup_msi_irq_w_maskbit,
++	.shutdown	= shutdown_msi_irq_w_maskbit,
++	.enable		= enable_msi_irq_w_maskbit,
++	.disable	= disable_msi_irq_w_maskbit,
++	.ack		= ack_msi_irq_w_maskbit,
++	.end		= end_msi_irq_w_maskbit,
++	.set_affinity	= set_msi_irq_affinity
++};
++
++/*
++ * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI Capability Structure with
++ * Mask-and-Pending Bits.
++ */
++static struct hw_interrupt_type msi_irq_w_maskbit_type = {
++	.typename	= "PCI MSI",
++	.startup	= startup_msi_irq_w_maskbit,
++	.shutdown	= shutdown_msi_irq_w_maskbit,
++	.enable		= enable_msi_irq_w_maskbit,
++	.disable	= disable_msi_irq_w_maskbit,
++	.ack		= ack_msi_irq_w_maskbit,
++	.end		= end_msi_irq_w_maskbit,
++	.set_affinity	= set_msi_irq_affinity
++};
++
++/*
++ * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI Capability Structure without
++ * Mask-and-Pending Bits.
++ */
++static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
++	.typename	= "PCI MSI",
++	.startup	= startup_msi_irq_wo_maskbit,
++	.shutdown	= shutdown_msi_irq_wo_maskbit,
++	.enable		= enable_msi_irq_wo_maskbit,
++	.disable	= disable_msi_irq_wo_maskbit,
++	.ack		= ack_msi_irq_wo_maskbit,
++	.end		= end_msi_irq_wo_maskbit,
++	.set_affinity	= set_msi_irq_affinity
++};
++
++static void msi_data_init(struct msg_data *msi_data,
++			  unsigned int vector)
++{
++	memset(msi_data, 0, sizeof(struct msg_data));
++	msi_data->vector = (u8)vector;
++	msi_data->delivery_mode = MSI_DELIVERY_MODE;
++	msi_data->level = MSI_LEVEL_MODE;
++	msi_data->trigger = MSI_TRIGGER_MODE;
++}
++
++static void msi_address_init(struct msg_address *msi_address)
++{
++	unsigned int	dest_id;
++
++	memset(msi_address, 0, sizeof(struct msg_address));
++	msi_address->hi_address = (u32)0;
++	dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT) |
++		 (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
++	msi_address->lo_address.u.dest_mode = MSI_LOGICAL_MODE;
++	msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
++	msi_address->lo_address.u.dest_id = dest_id;
++}
++
++static int pci_vector_resources(void)
++{
++	static int res = -EINVAL;
++	int nr_free_vectors;
++
++	if (res == -EINVAL) {
++		int i, repeat;
++		for (i = NR_REPEATS; i > 0; i--) {
++			if ((FIRST_DEVICE_VECTOR + i * 8) > FIRST_SYSTEM_VECTOR)
++				continue;
++			break;
++		}
++		i++;
++		repeat = (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)/i;
++		res = i * repeat - NR_RESERVED_VECTORS + 1;
++	}
++
++	nr_free_vectors = res + nr_released_vectors - nr_alloc_vectors;
++
++	return nr_free_vectors;
++}
++
++int assign_irq_vector(int irq)
++{
++	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
++
++	if (irq != MSI_AUTO && IO_APIC_VECTOR(irq) > 0)
++		return IO_APIC_VECTOR(irq);
++next:
++	current_vector += 8;
++	if (current_vector == SYSCALL_VECTOR)
++		goto next;
++
++	if (current_vector > FIRST_SYSTEM_VECTOR) {
++		offset++;
++		current_vector = FIRST_DEVICE_VECTOR + offset;
++	}
++
++	if (current_vector == FIRST_SYSTEM_VECTOR)
++		return -ENOSPC;
++
++	vector_irq[current_vector] = irq;
++	if (irq != MSI_AUTO)
++		IO_APIC_VECTOR(irq) = current_vector;
++
++	nr_alloc_vectors++;
++
++	return current_vector;
++}
++
++static int assign_msi_vector(void)
++{
++	static int new_vector_avail = 1;
++	int vector;
++	unsigned long flags;
++
++	/*
++	 * msi_lock is provided to ensure that successful allocation of MSI
++	 * vector is assigned unique among drivers.
++	 */
++	spin_lock_irqsave(&msi_lock, flags);
++	if (!(pci_vector_resources() > 0)) {
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EBUSY;
++	}
++
++	if (!new_vector_avail) {
++		/*
++	 	 * vector_irq[] = -1 indicates that this specific vector is:
++	 	 * - assigned for MSI (since MSI have no associated IRQ) or
++	 	 * - assigned for legacy if less than 16, or
++	 	 * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
++	 	 * vector_irq[] = 0 indicates that this vector, previously
++		 * assigned for MSI, is freed by hotplug removed operations.
++		 * This vector will be reused for any subsequent hotplug added
++		 * operations.
++	 	 * vector_irq[] > 0 indicates that this vector is assigned for
++		 * IOxAPIC IRQs. This vector and its value provides a 1-to-1
++		 * vector-to-IOxAPIC IRQ mapping.
++	 	 */
++		for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
++			if (vector_irq[vector] != 0)
++				continue;
++			vector_irq[vector] = -1;
++			nr_released_vectors--;
++			spin_unlock_irqrestore(&msi_lock, flags);
++			return vector;
++		}
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EBUSY;
++	}
++
++	vector = assign_irq_vector(MSI_AUTO);
++	if (vector  == (FIRST_SYSTEM_VECTOR - 8))
++		new_vector_avail = 0;
++
++	spin_unlock_irqrestore(&msi_lock, flags);
++	return vector;
++}
++
++static int get_new_vector(void)
++{
++	int vector;
++
++	if ((vector = assign_msi_vector()) > 0)
++		set_intr_gate(vector, interrupt[vector]);
++
++	return vector;
++}
++
++static int msi_init(void)
++{
++	static int status = -ENOMEM;
++
++	if (!status)
++		return status;
++
++	if ((status = msi_cache_init()) < 0) {
++		pci_msi_enable = 0;
++		printk(KERN_INFO "WARNING: MSI INIT FAILURE\n");
++		return status;
++	}
++	printk(KERN_INFO "MSI INIT SUCCESS\n");
++
++	return status;
++}
++
++static int get_msi_vector(struct pci_dev *dev)
++{
++	return get_new_vector();
++}
++
++static struct msi_desc* alloc_msi_entry(void)
++{
++	struct msi_desc *entry;
++
++	entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
++	if (!entry)
++		return NULL;
++
++	memset(entry, 0, sizeof(struct msi_desc));
++	entry->link.tail = entry->link.head = 0;	/* single message */
++	entry->dev = NULL;
++
++	return entry;
++}
++
++static void attach_msi_entry(struct msi_desc *entry, int vector)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	msi_desc[vector] = entry;
++	spin_unlock_irqrestore(&msi_lock, flags);
++}
++
++static void irq_handler_init(int cap_id, int pos, int mask)
++{
++	spin_lock(&irq_desc[pos].lock);
++	if (cap_id == PCI_CAP_ID_MSIX)
++		irq_desc[pos].handler = &msix_irq_type;
++	else {
++		if (!mask)
++			irq_desc[pos].handler = &msi_irq_wo_maskbit_type;
++		else
++			irq_desc[pos].handler = &msi_irq_w_maskbit_type;
++	}
++	spin_unlock(&irq_desc[pos].lock);
++}
++
++static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
++{
++	u32 control;
++
++	dev->bus->ops->read(dev->bus, dev->devfn,
++		msi_control_reg(pos), 2, &control);
++	if (type == PCI_CAP_ID_MSI) {
++		/* Set enabled bits to single MSI & enable MSI_enable bit */
++		msi_enable(control, 1);
++	        dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_control_reg(pos), 2, control);
++	} else {
++		msix_enable(control);
++	        dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_control_reg(pos), 2, control);
++	}
++    	if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
++		/* PCI Express Endpoint device detected */
++		u32 cmd;
++	        dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
++		cmd |= PCI_COMMAND_INTX_DISABLE;
++	        dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd);
++	}
++}
++
++static void disable_msi_mode(struct pci_dev *dev, int pos, int type)
++{
++	u32 control;
++
++	dev->bus->ops->read(dev->bus, dev->devfn,
++		msi_control_reg(pos), 2, &control);
++	if (type == PCI_CAP_ID_MSI) {
++		/* Set enabled bits to single MSI & enable MSI_enable bit */
++		msi_disable(control);
++	        dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_control_reg(pos), 2, control);
++	} else {
++		msix_disable(control);
++	        dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_control_reg(pos), 2, control);
++	}
++    	if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
++		/* PCI Express Endpoint device detected */
++		u32 cmd;
++	        dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
++		cmd &= ~PCI_COMMAND_INTX_DISABLE;
++	        dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd);
++	}
++}
++
++static int msi_lookup_vector(struct pci_dev *dev)
++{
++	int vector;
++	unsigned long flags;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
++		if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
++			msi_desc[vector]->msi_attrib.entry_nr ||
++			msi_desc[vector]->msi_attrib.default_vector != dev->irq)
++			continue;	/* not entry 0, skip */
++		spin_unlock_irqrestore(&msi_lock, flags);
++		/* This pre-assigned entry-0 MSI vector for this device
++		   already exits. Override dev->irq with this vector */
++		dev->irq = vector;
++		return 0;
++	}
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	return -EACCES;
++}
++
++void pci_scan_msi_device(struct pci_dev *dev)
++{
++	if (!dev)
++		return;
++
++   	if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0) {
++		nr_reserved_vectors++;
++		nr_msix_devices++;
++	} else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0)
++		nr_reserved_vectors++;
++}
++
++/**
++ * msi_capability_init - configure device's MSI capability structure
++ * @dev: pointer to the pci_dev data structure of MSI device function
++ *
++ * Setup the MSI capability structure of device funtion with a single
++ * MSI vector, regardless of device function is capable of handling
++ * multiple messages. A return of zero indicates the successful setup
++ * of an entry zero with the new MSI vector or non-zero for otherwise.
++ **/
++static int msi_capability_init(struct pci_dev *dev)
++{
++	struct msi_desc *entry;
++	struct msg_address address;
++	struct msg_data data;
++	int pos, vector;
++	u32 control;
++
++   	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
++	if (!pos)
++		return -EINVAL;
++
++	dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),
++		2, &control);
++	if (control & PCI_MSI_FLAGS_ENABLE)
++		return 0;
++
++	vector = dev->irq;
++	if (vector > 0 && !msi_lookup_vector(dev)) {
++		/* Lookup Sucess */
++		enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
++		return 0;
++	}
++	/* MSI Entry Initialization */
++	if (!(entry = alloc_msi_entry()))
++		return -ENOMEM;
++
++	if ((vector = get_msi_vector(dev)) < 0) {
++		kmem_cache_free(msi_cachep, entry);
++		return -EBUSY;
++	}
++	entry->msi_attrib.type = PCI_CAP_ID_MSI;
++	entry->msi_attrib.entry_nr = 0;
++	entry->msi_attrib.maskbit = is_mask_bit_support(control);
++	entry->msi_attrib.default_vector = dev->irq;
++	dev->irq = vector;	/* save default pre-assigned ioapic vector */
++	entry->dev = dev;
++	if (is_mask_bit_support(control)) {
++		entry->mask_base = msi_mask_bits_reg(pos,
++				is_64bit_address(control));
++	}
++	/* Replace with MSI handler */
++	irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
++	/* Configure MSI capability structure */
++	msi_address_init(&address);
++	msi_data_init(&data, vector);
++	entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++				MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++	dev->bus->ops->write(dev->bus, dev->devfn, msi_lower_address_reg(pos),
++				4, address.lo_address.value);
++	if (is_64bit_address(control)) {
++		dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_upper_address_reg(pos), 4, address.hi_address);
++		dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_data_reg(pos, 1), 2, *((u32*)&data));
++	} else
++		dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_data_reg(pos, 0), 2, *((u32*)&data));
++	if (entry->msi_attrib.maskbit) {
++		unsigned int maskbits, temp;
++		/* All MSIs are unmasked by default, Mask them all */
++	        dev->bus->ops->read(dev->bus, dev->devfn,
++			msi_mask_bits_reg(pos, is_64bit_address(control)), 4,
++			&maskbits);
++		temp = (1 << multi_msi_capable(control));
++		temp = ((temp - 1) & ~temp);
++		maskbits |= temp;
++		dev->bus->ops->write(dev->bus, dev->devfn,
++			msi_mask_bits_reg(pos, is_64bit_address(control)), 4,
++			maskbits);
++	}
++	attach_msi_entry(entry, vector);
++	/* Set MSI enabled bits	 */
++	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
++
++	return 0;
++}
++
++/**
++ * msix_capability_init - configure device's MSI-X capability
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ *
++ * Setup the MSI-X capability structure of device funtion with a
++ * single MSI-X vector. A return of zero indicates the successful setup
++ * of an entry zero with the new MSI-X vector or non-zero for otherwise.
++ * To request for additional MSI-X vectors, the device drivers are
++ * required to utilize the following supported APIs:
++ * 1) msi_alloc_vectors(...) for requesting one or more MSI-X vectors
++ * 2) msi_free_vectors(...) for releasing one or more MSI-X vectors
++ *    back to PCI subsystem before calling free_irq(...)
++ **/
++static int msix_capability_init(struct pci_dev	*dev)
++{
++	struct msi_desc *entry;
++	struct msg_address address;
++	struct msg_data data;
++	int vector, pos, dev_msi_cap;
++	u32 phys_addr, table_offset;
++	u32 control;
++	u8 bir;
++	void *base;
++
++   	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++	if (!pos)
++		return -EINVAL;
++
++	/* Request & Map MSI-X table region */
++	dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 2,
++		&control);
++	if (control & PCI_MSIX_FLAGS_ENABLE)
++		return 0;
++
++	vector = dev->irq;
++	if (vector > 0 && !msi_lookup_vector(dev)) {
++		/* Lookup Sucess */
++		enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
++		return 0;
++	}
++
++	dev_msi_cap = multi_msix_capable(control);
++	dev->bus->ops->read(dev->bus, dev->devfn,
++		msix_table_offset_reg(pos), 4, &table_offset);
++	bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
++	phys_addr = pci_resource_start (dev, bir);
++	phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
++	if (!request_mem_region(phys_addr,
++		dev_msi_cap * PCI_MSIX_ENTRY_SIZE,
++		"MSI-X iomap Failure"))
++		return -ENOMEM;
++	base = ioremap_nocache(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++	if (base == NULL)
++		goto free_region;
++	/* MSI Entry Initialization */
++	entry = alloc_msi_entry();
++	if (!entry)
++		goto free_iomap;
++	if ((vector = get_msi_vector(dev)) < 0)
++		goto free_entry;
++
++	entry->msi_attrib.type = PCI_CAP_ID_MSIX;
++	entry->msi_attrib.entry_nr = 0;
++	entry->msi_attrib.maskbit = 1;
++	entry->msi_attrib.default_vector = dev->irq;
++	dev->irq = vector;	/* save default pre-assigned ioapic vector */
++	entry->dev = dev;
++	entry->mask_base = (unsigned long)base;
++	/* Replace with MSI handler */
++	irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
++	/* Configure MSI-X capability structure */
++	msi_address_init(&address);
++	msi_data_init(&data, vector);
++	entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++				MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++	writel(address.lo_address.value, base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++	writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++	writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
++	/* Initialize all entries from 1 up to 0 */
++	for (pos = 1; pos < dev_msi_cap; pos++) {
++		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++			PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++			PCI_MSIX_ENTRY_DATA_OFFSET);
++	}
++	attach_msi_entry(entry, vector);
++	/* Set MSI enabled bits	 */
++	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
++
++	return 0;
++
++free_entry:
++	kmem_cache_free(msi_cachep, entry);
++free_iomap:
++	iounmap(base);
++free_region:
++	release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++
++	return ((vector < 0) ? -EBUSY : -ENOMEM);
++}
++
++/**
++ * pci_enable_msi - configure device's MSI(X) capability structure
++ * @dev: pointer to the pci_dev data structure of MSI(X) device function
++ *
++ * Setup the MSI/MSI-X capability structure of device function with
++ * a single MSI(X) vector upon its software driver call to request for
++ * MSI(X) mode enabled on its hardware device function. A return of zero
++ * indicates the successful setup of an entry zero with the new MSI(X)
++ * vector or non-zero for otherwise.
++ **/
++int pci_enable_msi(struct pci_dev* dev)
++{
++	int status = -EINVAL;
++
++	if (!pci_msi_enable || !dev)
++ 		return status;
++
++	if (msi_init() < 0)
++		return -ENOMEM;
++
++	if ((status = msix_capability_init(dev)) == -EINVAL)
++		status = msi_capability_init(dev);
++	if (!status)
++		nr_reserved_vectors--;
++
++	return status;
++}
++
++static int msi_free_vector(struct pci_dev* dev, int vector);
++static void pci_disable_msi(unsigned int vector)
++{
++	int head, tail, type, default_vector;
++	struct msi_desc *entry;
++	struct pci_dev *dev;
++	unsigned long flags;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[vector];
++	if (!entry || !entry->dev) {
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return;
++	}
++	dev = entry->dev;
++	type = entry->msi_attrib.type;
++	head = entry->link.head;
++	tail = entry->link.tail;
++	default_vector = entry->msi_attrib.default_vector;
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	disable_msi_mode(dev, pci_find_capability(dev, type), type);
++	/* Restore dev->irq to its default pin-assertion vector */
++	dev->irq = default_vector;
++	if (type == PCI_CAP_ID_MSIX && head != tail) {
++		/* Bad driver, which do not call msi_free_vectors before exit.
++		   We must do a cleanup here */
++		while (1) {
++			spin_lock_irqsave(&msi_lock, flags);
++			entry = msi_desc[vector];
++			head = entry->link.head;
++			tail = entry->link.tail;
++			spin_unlock_irqrestore(&msi_lock, flags);
++			if (tail == head)
++				break;
++			if (msi_free_vector(dev, entry->link.tail))
++				break;
++		}
++	}
++}
++
++static int msi_alloc_vector(struct pci_dev* dev, int head)
++{
++	struct msi_desc *entry;
++	struct msg_address address;
++	struct msg_data data;
++	int i, offset, pos, dev_msi_cap, vector;
++	u32 low_address, control;
++	unsigned long base = 0L;
++	unsigned long flags;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[dev->irq];
++	if (!entry) {
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EINVAL;
++	}
++	base = entry->mask_base;
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++   	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++	dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),
++		2, &control);
++	dev_msi_cap = multi_msix_capable(control);
++	for (i = 1; i < dev_msi_cap; i++) {
++		if (!(low_address = readl(base + i * PCI_MSIX_ENTRY_SIZE)))
++			 break;
++	}
++	if (i >= dev_msi_cap)
++		return -EINVAL;
++
++	/* MSI Entry Initialization */
++	if (!(entry = alloc_msi_entry()))
++		return -ENOMEM;
++
++	if ((vector = get_new_vector()) < 0) {
++		kmem_cache_free(msi_cachep, entry);
++		return vector;
++	}
++	entry->msi_attrib.type = PCI_CAP_ID_MSIX;
++	entry->msi_attrib.entry_nr = i;
++	entry->msi_attrib.maskbit = 1;
++	entry->dev = dev;
++	entry->link.head = head;
++	entry->mask_base = base;
++	irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
++	/* Configure MSI-X capability structure */
++	msi_address_init(&address);
++	msi_data_init(&data, vector);
++	entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++				MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++	offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
++	writel(address.lo_address.value, base + offset +
++		PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++	writel(address.hi_address, base + offset +
++		PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++	writel(*(u32*)&data, base + offset + PCI_MSIX_ENTRY_DATA_OFFSET);
++	writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++	attach_msi_entry(entry, vector);
++
++	return vector;
++}
++
++static int msi_free_vector(struct pci_dev* dev, int vector)
++{
++	struct msi_desc *entry;
++	int entry_nr, type;
++	unsigned long base = 0L;
++	unsigned long flags;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[vector];
++	if (!entry || entry->dev != dev) {
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EINVAL;
++	}
++	type = entry->msi_attrib.type;
++	entry_nr = entry->msi_attrib.entry_nr;
++	base = entry->mask_base;
++	if (entry->link.tail != entry->link.head) {
++		msi_desc[entry->link.head]->link.tail = entry->link.tail;
++		if (entry->link.tail)
++			msi_desc[entry->link.tail]->link.head = entry->link.head;
++	}
++	entry->dev = NULL;
++	vector_irq[vector] = 0;
++	nr_released_vectors++;
++	msi_desc[vector] = NULL;
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	kmem_cache_free(msi_cachep, entry);
++	if (type == PCI_CAP_ID_MSIX) {
++		int offset;
++
++		offset = entry_nr * PCI_MSIX_ENTRY_SIZE;
++		writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++		writel(0, base + offset + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++	}
++
++	return 0;
++}
++
++/**
++ * msi_alloc_vectors - allocate additional MSI-X vectors
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ * @vector: pointer to an array of new allocated MSI-X vectors
++ * @nvec: number of MSI-X vectors requested for allocation by device driver
++ *
++ * Allocate additional MSI-X vectors requested by device driver. A
++ * return of zero indicates the successful setup of MSI-X capability
++ * structure with new allocated MSI-X vectors or non-zero for otherwise.
++ **/
++int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec)
++{
++	struct msi_desc *entry;
++	int i, head, pos, vec, free_vectors, alloc_vectors;
++	int *vectors = (int *)vector;
++	u32 control;
++	unsigned long flags;
++
++	if (!pci_msi_enable || !dev)
++ 		return -EINVAL;
++
++   	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
++ 		return -EINVAL;
++
++	dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 			2, &control);
++	if (nvec > multi_msix_capable(control))
++		return -EINVAL;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[dev->irq];
++	if (!entry || entry->dev != dev ||		/* legal call */
++	   entry->msi_attrib.type != PCI_CAP_ID_MSIX || /* must be MSI-X */
++	   entry->link.head != entry->link.tail) {	/* already multi */
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EINVAL;
++	}
++	/*
++	 * msi_lock is provided to ensure that enough vectors resources are
++	 * available before granting.
++	 */
++	free_vectors = pci_vector_resources();
++	/* Ensure that each MSI/MSI-X device has one vector reserved by
++	   default to avoid any MSI-X driver to take all available
++ 	   resources */
++	free_vectors -= nr_reserved_vectors;
++	/* Find the average of free vectors among MSI-X devices */
++	if (nr_msix_devices > 0)
++		free_vectors /= nr_msix_devices;
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	if (nvec > free_vectors)
++		return -EBUSY;
++
++	alloc_vectors = 0;
++	head = dev->irq;
++	for (i = 0; i < nvec; i++) {
++		if ((vec = msi_alloc_vector(dev, head)) < 0)
++			break;
++		*(vectors + i) = vec;
++		head = vec;
++		alloc_vectors++;
++	}
++	if (alloc_vectors != nvec) {
++		for (i = 0; i < alloc_vectors; i++) {
++			vec = *(vectors + i);
++			msi_free_vector(dev, vec);
++		}
++		spin_lock_irqsave(&msi_lock, flags);
++		msi_desc[dev->irq]->link.tail = msi_desc[dev->irq]->link.head;
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EBUSY;
++	}
++	if (nr_msix_devices > 0)
++		nr_msix_devices--;
++
++	return 0;
++}
++
++/**
++ * msi_free_vectors - reclaim MSI-X vectors to unused state
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ * @vector: pointer to an array of released MSI-X vectors
++ * @nvec: number of MSI-X vectors requested for release by device driver
++ *
++ * Reclaim MSI-X vectors released by device driver to unused state,
++ * which may be used later on. A return of zero indicates the
++ * success or non-zero for otherwise. Device driver should call this
++ * before calling function free_irq.
++ **/
++int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec)
++{
++	struct msi_desc *entry;
++	int i;
++	unsigned long flags;
++
++	if (!pci_msi_enable)
++ 		return -EINVAL;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[dev->irq];
++	if (!entry || entry->dev != dev ||
++	   	entry->msi_attrib.type != PCI_CAP_ID_MSIX ||
++		entry->link.head == entry->link.tail) {	/* Nothing to free */
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return -EINVAL;
++	}
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	for (i = 0; i < nvec; i++) {
++		if (*(vector + i) == dev->irq)
++			continue;/* Don't free entry 0 if mistaken by driver */
++		msi_free_vector(dev, *(vector + i));
++	}
++
++	return 0;
++}
++
++/**
++ * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
++ * @dev: pointer to the pci_dev data structure of MSI(X) device function
++ *
++ * Being called during hotplug remove, from which the device funciton
++ * is hot-removed. All previous assigned MSI/MSI-X vectors, if
++ * allocated for this device function, are reclaimed to unused state,
++ * which may be used later on.
++ **/
++void msi_remove_pci_irq_vectors(struct pci_dev* dev)
++{
++	struct msi_desc *entry;
++	int type;
++	unsigned long flags;
++
++	if (!pci_msi_enable)
++ 		return;
++
++	spin_lock_irqsave(&msi_lock, flags);
++	entry = msi_desc[dev->irq];
++	if (!entry || entry->dev != dev) {
++		spin_unlock_irqrestore(&msi_lock, flags);
++		return;
++	}
++	type = entry->msi_attrib.type;
++	spin_unlock_irqrestore(&msi_lock, flags);
++
++	msi_free_vector(dev, dev->irq);
++	if (type == PCI_CAP_ID_MSIX) {
++		int i, pos, dev_msi_cap;
++		u32 phys_addr, table_offset;
++		u32 control;
++		u8 bir;
++
++   		pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++		dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 			2, &control);
++		dev_msi_cap = multi_msix_capable(control);
++		dev->bus->ops->read(dev->bus, dev->devfn,
++			msix_table_offset_reg(pos), 4, &table_offset);
++		bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
++		phys_addr = pci_resource_start (dev, bir);
++		phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
++		for (i = FIRST_DEVICE_VECTOR; i < NR_IRQS; i++) {
++			spin_lock_irqsave(&msi_lock, flags);
++			if (!msi_desc[i] || msi_desc[i]->dev != dev) {
++				spin_unlock_irqrestore(&msi_lock, flags);
++				continue;
++			}
++			spin_unlock_irqrestore(&msi_lock, flags);
++			msi_free_vector(dev, i);
++		}
++		writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++		iounmap((void*)entry->mask_base);
++		release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++	}
++	nr_reserved_vectors++;
++}
++
++EXPORT_SYMBOL(pci_enable_msi);
++EXPORT_SYMBOL(msi_alloc_vectors);
++EXPORT_SYMBOL(msi_free_vectors);
+--- linux-2.6.0-test6/drivers/pci/pci.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/pci/pci.c	2003-10-05 00:36:10.000000000 -0700
+@@ -126,11 +126,13 @@ pci_find_capability(struct pci_dev *dev,
+ 
+ /**
+  * pci_bus_find_capability - query for devices' capabilities 
+- * @dev: PCI device to query
+- * @cap: capability code
++ * @bus:   the PCI bus to query
++ * @devfn: PCI device to query
++ * @cap:   capability code
+  *
+  * Like pci_find_capability() but works for pci devices that do not have a
+  * pci_dev structure set up yet. 
++ *
+  * Returns the address of the requested capability structure within the
+  * device's PCI configuration space or 0 in case the device does not
+  * support it.
+--- linux-2.6.0-test6/drivers/pci/pool.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/pci/pool.c	2003-10-05 00:33:24.000000000 -0700
+@@ -296,7 +296,6 @@ restart:
+ 
+ 			schedule_timeout (POOL_TIMEOUT_JIFFIES);
+ 
+-			current->state = TASK_RUNNING;
+ 			remove_wait_queue (&pool->waitq, &wait);
+ 			goto restart;
+ 		}
+--- linux-2.6.0-test6/drivers/pci/power.c	2003-06-14 12:18:25.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,159 +0,0 @@
+-#include <linux/pci.h>
+-#include <linux/pm.h>
+-#include <linux/init.h>
+-
+-/*
+- * PCI Power management..
+- *
+- * This needs to be done centralized, so that we power manage PCI
+- * devices in the right order: we should not shut down PCI bridges
+- * before we've shut down the devices behind them, and we should
+- * not wake up devices before we've woken up the bridge to the
+- * device.. Eh?
+- *
+- * We do not touch devices that don't have a driver that exports
+- * a suspend/resume function. That is just too dangerous. If the default
+- * PCI suspend/resume functions work for a device, the driver can
+- * easily implement them (ie just have a suspend function that calls
+- * the pci_set_power_state() function).
+- */
+-
+-static int pci_pm_save_state_device(struct pci_dev *dev, u32 state)
+-{
+-	int error = 0;
+-	if (dev) {
+-		struct pci_driver *driver = dev->driver;
+-		if (driver && driver->save_state) 
+-			error = driver->save_state(dev,state);
+-	}
+-	return error;
+-}
+-
+-static int pci_pm_suspend_device(struct pci_dev *dev, u32 state)
+-{
+-	int error = 0;
+-	if (dev) {
+-		struct pci_driver *driver = dev->driver;
+-		if (driver && driver->suspend)
+-			error = driver->suspend(dev,state);
+-	}
+-	return error;
+-}
+-
+-static int pci_pm_resume_device(struct pci_dev *dev)
+-{
+-	int error = 0;
+-	if (dev) {
+-		struct pci_driver *driver = dev->driver;
+-		if (driver && driver->resume)
+-			error = driver->resume(dev);
+-	}
+-	return error;
+-}
+-
+-static int pci_pm_save_state_bus(struct pci_bus *bus, u32 state)
+-{
+-	struct list_head *list;
+-	int error = 0;
+-
+-	list_for_each(list, &bus->children) {
+-		error = pci_pm_save_state_bus(pci_bus_b(list),state);
+-		if (error) return error;
+-	}
+-	list_for_each(list, &bus->devices) {
+-		error = pci_pm_save_state_device(pci_dev_b(list),state);
+-		if (error) return error;
+-	}
+-	return 0;
+-}
+-
+-static int pci_pm_suspend_bus(struct pci_bus *bus, u32 state)
+-{
+-	struct list_head *list;
+-
+-	/* Walk the bus children list */
+-	list_for_each(list, &bus->children) 
+-		pci_pm_suspend_bus(pci_bus_b(list),state);
+-
+-	/* Walk the device children list */
+-	list_for_each(list, &bus->devices)
+-		pci_pm_suspend_device(pci_dev_b(list),state);
+-	return 0;
+-}
+-
+-static int pci_pm_resume_bus(struct pci_bus *bus)
+-{
+-	struct list_head *list;
+-
+-	/* Walk the device children list */
+-	list_for_each(list, &bus->devices)
+-		pci_pm_resume_device(pci_dev_b(list));
+-
+-	/* And then walk the bus children */
+-	list_for_each(list, &bus->children)
+-		pci_pm_resume_bus(pci_bus_b(list));
+-	return 0;
+-}
+-
+-static int pci_pm_save_state(u32 state)
+-{
+-	struct pci_bus *bus = NULL;
+-	int error = 0;
+-
+-	while ((bus = pci_find_next_bus(bus)) != NULL) {
+-		error = pci_pm_save_state_bus(bus,state);
+-		if (!error)
+-			error = pci_pm_save_state_device(bus->self,state);
+-	}
+-	return error;
+-}
+-
+-static int pci_pm_suspend(u32 state)
+-{
+-	struct pci_bus *bus = NULL;
+-
+-	while ((bus = pci_find_next_bus(bus)) != NULL) {
+-		pci_pm_suspend_bus(bus,state);
+-		pci_pm_suspend_device(bus->self,state);
+-	}
+-	return 0;
+-}
+-
+-static int pci_pm_resume(void)
+-{
+-	struct pci_bus *bus = NULL;
+-
+-	while ((bus = pci_find_next_bus(bus)) != NULL) {
+-		pci_pm_resume_device(bus->self);
+-		pci_pm_resume_bus(bus);
+-	}
+-	return 0;
+-}
+-
+-static int 
+-pci_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
+-{
+-	int error = 0;
+-
+-	switch (rqst) {
+-	case PM_SAVE_STATE:
+-		error = pci_pm_save_state((unsigned long)data);
+-		break;
+-	case PM_SUSPEND:
+-		error = pci_pm_suspend((unsigned long)data);
+-		break;
+-	case PM_RESUME:
+-		error = pci_pm_resume();
+-		break;
+-	default: break;
+-	}
+-	return error;
+-}
+-
+-static int __init pci_pm_init(void)
+-{
+-	pm_register(PM_PCI_DEV, 0, pci_pm_callback);
+-	return 0;
+-}
+-
+-subsys_initcall(pci_pm_init);
+--- linux-2.6.0-test6/drivers/pci/probe.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/pci/probe.c	2003-10-05 00:36:20.000000000 -0700
+@@ -176,7 +176,7 @@ void __devinit pci_read_bridge_bases(str
+ 		limit |= (io_limit_hi << 16);
+ 	}
+ 
+-	if (base && base <= limit) {
++	if (base <= limit) {
+ 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
+ 		res->start = base;
+ 		res->end = limit + 0xfff;
+@@ -187,7 +187,7 @@ void __devinit pci_read_bridge_bases(str
+ 	pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
+ 	base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
+ 	limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
+-	if (base && base <= limit) {
++	if (base <= limit) {
+ 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
+ 		res->start = base;
+ 		res->end = limit + 0xfffff;
+@@ -213,7 +213,7 @@ void __devinit pci_read_bridge_bases(str
+ 		}
+ #endif
+ 	}
+-	if (base && base <= limit) {
++	if (base <= limit) {
+ 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ 		res->start = base;
+ 		res->end = limit + 0xfffff;
+@@ -552,6 +552,7 @@ int __devinit pci_scan_slot(struct pci_b
+ 		struct pci_dev *dev;
+ 
+ 		dev = pci_scan_device(bus, devfn);
++		pci_scan_msi_device(dev);
+ 		if (func == 0) {
+ 			if (!dev)
+ 				break;
+--- linux-2.6.0-test6/drivers/pci/quirks.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/pci/quirks.c	2003-10-05 00:33:24.000000000 -0700
+@@ -750,6 +750,9 @@ static void __init quirk_sis_96x_compati
+ 
+ /*
+  *  The main table of quirks.
++ *
++ *  Note: any hooks for hotpluggable devices in this table must _NOT_
++ *        be declared __init.
+  */
+ 
+ static struct pci_fixup pci_fixups[] __devinitdata = {
+--- linux-2.6.0-test6/drivers/pci/remove.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/pci/remove.c	2003-10-05 00:36:20.000000000 -0700
+@@ -14,6 +14,8 @@ static void pci_free_resources(struct pc
+ {
+ 	int i;
+ 
++ 	msi_remove_pci_irq_vectors(dev);
++
+ 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ 		struct resource *res = dev->resource + i;
+ 		if (res->parent)
+--- linux-2.6.0-test6/drivers/s390/block/dasd.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/s390/block/dasd.c	2003-10-05 00:34:01.000000000 -0700
+@@ -1643,9 +1643,9 @@ dasd_flush_request_queue(struct dasd_dev
+ }
+ 
+ static int
+-dasd_open(struct inode *inp, struct file *filp)
++dasd_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct gendisk *disk = inp->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct dasd_device *device = disk->private_data;
+ 	int rc;
+ 
+@@ -1676,10 +1676,8 @@ out:
+ 	return rc;
+ }
+ 
+-static int
+-dasd_release(struct inode *inp, struct file *filp)
++static int dasd_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inp->i_bdev->bd_disk;
+ 	struct dasd_device *device = disk->private_data;
+ 
+ 	if (device->state < DASD_STATE_BASIC) {
+--- linux-2.6.0-test6/drivers/s390/block/dasd_int.h	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/s390/block/dasd_int.h	2003-10-05 00:33:54.000000000 -0700
+@@ -493,7 +493,7 @@ int  dasd_ioctl_init(void);
+ void dasd_ioctl_exit(void);
+ int  dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t);
+ int  dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t);
+-int  dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
++int  dasd_ioctl(struct block_device *, struct file *, unsigned int, unsigned long);
+ 
+ /* externals in dasd_proc.c */
+ int dasd_proc_init(void);
+--- linux-2.6.0-test6/drivers/s390/block/dasd_ioctl.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/s390/block/dasd_ioctl.c	2003-10-05 00:33:54.000000000 -0700
+@@ -78,10 +78,9 @@ dasd_ioctl_no_unregister(struct module *
+ }
+ 
+ int
+-dasd_ioctl(struct inode *inp, struct file *filp,
++dasd_ioctl(struct block_device *bdev, struct file *filp,
+ 	   unsigned int no, unsigned long data)
+ {
+-	struct block_device *bdev = inp->i_bdev;
+ 	struct dasd_device *device = bdev->bd_disk->private_data;
+ 	struct dasd_ioctl *ioctl;
+ 	const char *dir;
+--- linux-2.6.0-test6/drivers/s390/block/xpram.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/s390/block/xpram.c	2003-10-05 00:33:54.000000000 -0700
+@@ -328,7 +328,7 @@ fail:
+ 	return 0;
+ }
+ 
+-static int xpram_ioctl (struct inode *inode, struct file *filp,
++static int xpram_ioctl (struct block_device *bdev, struct file *filp,
+ 		 unsigned int cmd, unsigned long arg)
+ {
+ 	struct hd_geometry *geo;
+--- linux-2.6.0-test6/drivers/s390/char/tape_block.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/s390/char/tape_block.c	2003-10-05 00:34:01.000000000 -0700
+@@ -27,8 +27,8 @@
+ /*
+  * file operation structure for tape block frontend
+  */
+-static int tapeblock_open(struct inode *, struct file *);
+-static int tapeblock_release(struct inode *, struct file *);
++static int tapeblock_open(block_device *, struct file *);
++static int tapeblock_release(struct gendisk *);
+ 
+ static struct block_device_operations tapeblock_fops = {
+ 	.owner		= THIS_MODULE,
+@@ -299,9 +299,9 @@ static int tapeblock_mediumdetect(struct
+  * Block frontend tape device open function.
+  */
+ static int
+-tapeblock_open(struct inode *inode, struct file *filp)
++tapeblock_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct tape_device *device = disk->private_data;
+ 	int rc;
+ 
+@@ -336,9 +336,8 @@ tapeblock_open(struct inode *inode, stru
+  * Block frontend tape device release function.
+  */
+ static int
+-tapeblock_release(struct inode *inode, struct file *filp)
++tapeblock_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct tape_device *device = disk->private_data;
+ 
+ 	tape_release(device);
+--- linux-2.6.0-test6/drivers/sbus/char/bbc_envctrl.c	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/sbus/char/bbc_envctrl.c	2003-10-05 00:33:24.000000000 -0700
+@@ -59,7 +59,7 @@ static int errno;
+  * before the hardware based power-off event is triggered.
+  */
+ 
+-/* These settings are in celcius.  We use these defaults only
++/* These settings are in Celsius.  We use these defaults only
+  * if we cannot interrogate the cpu-fru SEEPROM.
+  */
+ struct temp_limits {
+--- linux-2.6.0-test6/drivers/sbus/char/cpwatchdog.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/sbus/char/cpwatchdog.c	2003-10-05 00:33:24.000000000 -0700
+@@ -539,7 +539,7 @@ static void wd_toggleintr(struct wd_time
+ static void wd_pingtimer(struct wd_timer* pTimer)
+ {
+ 	if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) {
+-		wd_readb(&pTimer->regs->dcntr);
++		wd_readw(&pTimer->regs->dcntr);
+ 	}
+ }
+ 
+--- linux-2.6.0-test6/drivers/sbus/char/jsflash.c	2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/sbus/char/jsflash.c	2003-10-05 00:33:24.000000000 -0700
+@@ -37,6 +37,7 @@
+ #include <linux/string.h>
+ #include <linux/smp_lock.h>
+ #include <linux/genhd.h>
++#include <linux/blkdev.h>
+ 
+ #define MAJOR_NR	JSFD_MAJOR
+ 
+@@ -187,7 +188,7 @@ static void jsfd_read(char *buf, unsigne
+ static void jsfd_do_request(request_queue_t *q)
+ {
+ 	struct request *req;
+-	
++
+ 	while ((req = elv_next_request(q)) != NULL) {
+ 		struct jsfd_part *jdp = req->rq_disk->private_data;
+ 		unsigned long offset = req->sector << 9;
+@@ -198,16 +199,11 @@ static void jsfd_do_request(request_queu
+ 			continue;
+ 		}
+ 
+-		if (req->cmd == WRITE) {
++		if (rq_data_dir(req) != READ) {
+ 			printk(KERN_ERR "jsfd: write\n");
+ 			end_request(req, 0);
+ 			continue;
+ 		}
+-		if (req->cmd != READ) {
+-			printk(KERN_ERR "jsfd: bad req->cmd %d\n", req->cmd);
+-			end_request(req, 0);
+-			continue;
+-		}
+ 
+ 		if ((jdp->dbase & 0xff000000) != 0x20000000) {
+ 			printk(KERN_ERR "jsfd: bad base %x\n", (int)jdp->dbase);
+@@ -215,7 +211,6 @@ static void jsfd_do_request(request_queu
+ 			continue;
+ 		}
+ 
+-/* printk("%s: read buf %p off %x len %x\n", req->rq_disk->disk_name, req->buffer, (int)offset, (int)len); */ /* P3 */
+ 		jsfd_read(req->buffer, jdp->dbase + offset, len);
+ 
+ 		end_request(req, 1);
+@@ -265,9 +260,6 @@ static ssize_t jsf_read(struct file * fi
+ 		unsigned int n;
+ 	} b;
+ 
+-	if (verify_area(VERIFY_WRITE, buf, togo))
+-		return -EFAULT; 
+-
+ 	if (p < JSF_BASE_ALL || p >= JSF_BASE_TOP) {
+ 		return 0;
+ 	}
+@@ -298,7 +290,8 @@ static ssize_t jsf_read(struct file * fi
+ 	while (togo >= 4) {
+ 		togo -= 4;
+ 		b.n = jsf_inl(p);
+-		copy_to_user(tmp, b.s, 4);
++		if (copy_to_user(tmp, b.s, 4))
++			return -EFAULT;
+ 		tmp += 4;
+ 		p += 4;
+ 	}
+@@ -374,19 +367,17 @@ static int jsf_ioctl_program(unsigned lo
+ 		char s[4];
+ 	} b;
+ 
+-	if (verify_area(VERIFY_READ, (void *)arg, JSFPRGSZ))
++	if (copy_from_user(&abuf, (char *)arg, JSFPRGSZ))
+ 		return -EFAULT; 
+-	copy_from_user(&abuf, (char *)arg, JSFPRGSZ);
+ 	p = abuf.off;
+ 	togo = abuf.size;
+ 	if ((togo & 3) || (p & 3)) return -EINVAL;
+ 
+ 	uptr = (char *) (unsigned long) abuf.data;
+-	if (verify_area(VERIFY_READ, uptr, togo))
+-		return -EFAULT;
+ 	while (togo != 0) {
+ 		togo -= 4;
+-		copy_from_user(&b.s[0], uptr, 4);
++		if (copy_from_user(&b.s[0], uptr, 4))
++			return -EFAULT;
+ 		jsf_write4(p, b.n);
+ 		p += 4;
+ 		uptr += 4;
+@@ -404,10 +395,8 @@ static int jsf_ioctl(struct inode *inode
+ 		return -EPERM;
+ 	switch (cmd) {
+ 	case JSFLASH_IDENT:
+-		if (verify_area(VERIFY_WRITE, (void *)arg, JSFIDSZ))
+-			return -EFAULT; 
+-		copy_to_user(arg, &jsf0.id, JSFIDSZ);
+-		error = 0;
++		if (copy_to_user((void *)arg, &jsf0.id, JSFIDSZ))
++			return -EFAULT;
+ 		break;
+ 	case JSFLASH_ERASE:
+ 		error = jsf_ioctl_erase(arg);
+--- linux-2.6.0-test6/drivers/scsi/a2091.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/scsi/a2091.c	2003-10-05 00:33:24.000000000 -0700
+@@ -25,31 +25,20 @@
+ #define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
+ #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+ 
+-static struct Scsi_Host *first_instance = NULL;
+-static Scsi_Host_Template *a2091_template;
+-
+-static irqreturn_t a2091_intr (int irq, void *dummy, struct pt_regs *fp)
++static irqreturn_t a2091_intr (int irq, void *_instance, struct pt_regs *fp)
+ {
+     unsigned long flags;
+     unsigned int status;
+-    struct Scsi_Host *instance;
+-    int handled = 0;
++    struct Scsi_Host *instance = (struct Scsi_Host *)_instance;
+ 
+-    for (instance = first_instance; instance &&
+-	 instance->hostt == a2091_template; instance = instance->next)
+-    {
+-	status = DMA(instance)->ISTR;
+-	if (!(status & (ISTR_INT_F|ISTR_INT_P)))
+-		continue;
+-
+-	if (status & ISTR_INTS) {
+-		spin_lock_irqsave(instance->host_lock, flags);
+-		wd33c93_intr (instance);
+-		spin_unlock_irqrestore(instance->host_lock, flags);
+-		handled = 1;
+-	}
+-    }
+-    return IRQ_RETVAL(handled);
++    status = DMA(instance)->ISTR;
++    if (!(status & (ISTR_INT_F|ISTR_INT_P)) || !(status & ISTR_INTS))
++	return IRQ_NONE;
++
++    spin_lock_irqsave(instance->host_lock, flags);
++    wd33c93_intr(instance);
++    spin_unlock_irqrestore(instance->host_lock, flags);
++    return IRQ_HANDLED;
+ }
+ 
+ static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
+@@ -184,8 +173,6 @@ static void dma_stop (struct Scsi_Host *
+     }
+ }
+ 
+-static int num_a2091 = 0;
+-
+ int __init a2091_detect(Scsi_Host_Template *tpnt)
+ {
+     static unsigned char called = 0;
+@@ -193,6 +180,7 @@ int __init a2091_detect(Scsi_Host_Templa
+     unsigned long address;
+     struct zorro_dev *z = NULL;
+     wd33c93_regs regs;
++    int num_a2091 = 0;
+ 
+     if (!MACH_IS_AMIGA || called)
+ 	return 0;
+@@ -221,13 +209,10 @@ int __init a2091_detect(Scsi_Host_Templa
+ 	regs.SASR = &(DMA(instance)->SASR);
+ 	regs.SCMD = &(DMA(instance)->SCMD);
+ 	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
+-	if (num_a2091++ == 0) {
+-	    first_instance = instance;
+-	    a2091_template = instance->hostt;
+-	    request_irq(IRQ_AMIGA_PORTS, a2091_intr, SA_SHIRQ, "A2091 SCSI",
+-			a2091_intr);
+-	}
++	request_irq(IRQ_AMIGA_PORTS, a2091_intr, SA_SHIRQ, "A2091 SCSI",
++		    instance);
+ 	DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN;
++	num_a2091++;
+     }
+ 
+     return num_a2091;
+@@ -266,8 +251,7 @@ int a2091_release(struct Scsi_Host *inst
+ #ifdef MODULE
+ 	DMA(instance)->CNTR = 0;
+ 	release_mem_region(ZTWO_PADDR(instance->base), 256);
+-	if (--num_a2091 == 0)
+-		free_irq(IRQ_AMIGA_PORTS, a2091_intr);
++	free_irq(IRQ_AMIGA_PORTS, instance);
+ 	wd33c93_release();
+ #endif
+ 	return 1;
+--- linux-2.6.0-test6/drivers/scsi/aic7xxx/aicasm/Makefile	2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aicasm/Makefile	2003-10-05 00:34:29.000000000 -0700
+@@ -49,14 +49,18 @@ aicdb.h:
+ clean:
+ 	rm -f $(clean-files)
+ 
+-aicasm_gram.c aicasm_gram.h: aicasm_gram.y
++aicasm_gram.c: aicasm_gram.h
++	mv $(<:.h=).tab.c $(<:.h=.c)
++
++aicasm_gram.h: aicasm_gram.y
+ 	$(YACC) $(YFLAGS) -b $(<:.y=) $<
+-	mv $(<:.y=).tab.c $(<:.y=.c)
+ 	mv $(<:.y=).tab.h $(<:.y=.h)
+ 
+-aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
++aicasm_macro_gram.c: aicasm_macro_gram.h
++	mv $(<:.h=).tab.c $(<:.h=.c)
++
++aicasm_macro_gram.h: aicasm_macro_gram.y
+ 	$(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
+-	mv $(<:.y=).tab.c $(<:.y=.c)
+ 	mv $(<:.y=).tab.h $(<:.y=.h)
+ 
+ aicasm_scan.c: aicasm_scan.l
+--- linux-2.6.0-test6/drivers/scsi/aic7xxx/Makefile	2003-06-14 12:18:48.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/Makefile	2003-10-05 00:34:29.000000000 -0700
+@@ -58,7 +58,9 @@ aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PR
+ 	-p $(obj)/aic7xxx_reg_print.c -i aic7xxx_osm.h
+ 
+ ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
+-$(aic7xxx-gen-y): $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
++$(aic7xxx-gen-y): $(src)/aic7xxx.seq
++
++$(src)/aic7xxx.seq: $(obj)/aicasm/aicasm $(src)/aic7xxx.reg
+ 	$(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
+ 			      $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \
+ 			      $(src)/aic7xxx.seq
+@@ -72,7 +74,9 @@ aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PR
+ 	-p $(obj)/aic79xx_reg_print.c -i aic79xx_osm.h
+ 
+ ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
+-$(aic79xx-gen-y): $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
++$(aic79xx-gen-y): $(src)/aic79xx.seq
++
++$(src)/aic79xx.seq: $(obj)/aicasm/aicasm $(src)/aic79xx.reg
+ 	$(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
+ 			      $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \
+ 			      $(src)/aic79xx.seq
+--- linux-2.6.0-test6/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2003-06-14 12:18:33.000000000 -0700
++++ 25/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2003-10-05 00:36:51.000000000 -0700
+@@ -92,7 +92,7 @@ aic7xxx_proc_info ( struct Scsi_Host *HB
+ 
+   HBAptr = NULL;
+ 
+-  for(p=first_aic7xxx; p->host != HBAptr; p=p->next)
++  for(p=first_aic7xxx; p && p->host != HBAptr; p=p->next)
+     ;
+ 
+   if (!p)
+--- linux-2.6.0-test6/drivers/scsi/g_NCR5380.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/g_NCR5380.c	2003-10-05 00:33:24.000000000 -0700
+@@ -527,8 +527,9 @@ int generic_NCR5380_release_resources(st
+  *	Locks: none
+  */
+ 
+-int generic_NCR5380_biosparam(struct scsi_device *sdev,
+-		struct block_device *bdev, sector_t capacity, int *ip)
++static int
++generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
++			  sector_t capacity, int *ip)
+ {
+ 	ip[0] = 64;
+ 	ip[1] = 32;
+--- linux-2.6.0-test6/drivers/scsi/g_NCR5380.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/scsi/g_NCR5380.h	2003-10-05 00:33:24.000000000 -0700
+@@ -52,7 +52,6 @@ static int generic_NCR5380_bus_reset(Scs
+ static int generic_NCR5380_host_reset(Scsi_Cmnd *);
+ static int generic_NCR5380_device_reset(Scsi_Cmnd *);
+ static const char* generic_NCR5380_info(struct Scsi_Host *);
+-static int generic_NCR5380_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
+ 
+ #ifndef CMD_PER_LUN
+ #define CMD_PER_LUN 2
+--- linux-2.6.0-test6/drivers/scsi/gvp11.c	2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/scsi/gvp11.c	2003-10-05 00:33:24.000000000 -0700
+@@ -25,29 +25,20 @@
+ #define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base))
+ #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+ 
+-static struct Scsi_Host *first_instance = NULL;
+-static Scsi_Host_Template *gvp11_template;
+-
+-static irqreturn_t gvp11_intr (int irq, void *dummy, struct pt_regs *fp)
++static irqreturn_t gvp11_intr (int irq, void *_instance, struct pt_regs *fp)
+ {
+     unsigned long flags;
+     unsigned int status;
+-    struct Scsi_Host *instance;
+-    int handled = 0;
+-
+-    for (instance = first_instance; instance &&
+-	 instance->hostt == gvp11_template; instance = instance->next)
+-    {
+-	status = DMA(instance)->CNTR;
+-	if (!(status & GVP11_DMAC_INT_PENDING))
+-	    continue;
++    struct Scsi_Host *instance = (struct Scsi_Host *)_instance;
+ 
+-	spin_lock_irqsave(instance->host_lock, flags);
+-	wd33c93_intr (instance);
+-	spin_unlock_irqrestore(instance->host_lock, flags);
+-	handled = 1;
+-    }
+-    return IRQ_RETVAL(handled);
++    status = DMA(instance)->CNTR;
++    if (!(status & GVP11_DMAC_INT_PENDING))
++	return IRQ_NONE;
++
++    spin_lock_irqsave(instance->host_lock, flags);
++    wd33c93_intr(instance);
++    spin_unlock_irqrestore(instance->host_lock, flags);
++    return IRQ_HANDLED;
+ }
+ 
+ static int gvp11_xfer_mask = 0;
+@@ -177,8 +168,6 @@ static void dma_stop (struct Scsi_Host *
+     }
+ }
+ 
+-static int num_gvp11 = 0;
+-
+ #define CHECK_WD33C93
+ 
+ int __init gvp11_detect(Scsi_Host_Template *tpnt)
+@@ -190,6 +179,7 @@ int __init gvp11_detect(Scsi_Host_Templa
+     struct zorro_dev *z = NULL;
+     unsigned int default_dma_xfer_mask;
+     wd33c93_regs regs;
++    int num_gvp11 = 0;
+ #ifdef CHECK_WD33C93
+     volatile unsigned char *sasr_3393, *scmd_3393;
+     unsigned char save_sasr;
+@@ -339,13 +329,10 @@ int __init gvp11_detect(Scsi_Host_Templa
+ 		     (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
+ 					     : WD33C93_FS_12_15);
+ 
+-	if (num_gvp11++ == 0) {
+-		first_instance = instance;
+-		gvp11_template = instance->hostt;
+-		request_irq(IRQ_AMIGA_PORTS, gvp11_intr, SA_SHIRQ,
+-			    "GVP11 SCSI", gvp11_intr);
+-	}
++	request_irq(IRQ_AMIGA_PORTS, gvp11_intr, SA_SHIRQ, "GVP11 SCSI",
++		    instance);
+ 	DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE;
++	num_gvp11++;
+ 	continue;
+ 
+ release:
+@@ -391,8 +378,7 @@ int gvp11_release(struct Scsi_Host *inst
+ #ifdef MODULE
+     DMA(instance)->CNTR = 0;
+     release_mem_region(ZTWO_PADDR(instance->base), 256);
+-    if (--num_gvp11 == 0)
+-	    free_irq(IRQ_AMIGA_PORTS, gvp11_intr);
++    free_irq(IRQ_AMIGA_PORTS, instance);
+     wd33c93_release();
+ #endif
+     return 1;
+--- linux-2.6.0-test6/drivers/scsi/ide-scsi.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/ide-scsi.c	2003-10-05 00:34:01.000000000 -0700
+@@ -635,24 +635,23 @@ static ide_driver_t idescsi_driver = {
+ 	.drives			= LIST_HEAD_INIT(idescsi_driver.drives),
+ };
+ 
+-static int idescsi_ide_open(struct inode *inode, struct file *filp)
++static int idescsi_ide_open(struct block_device *bdev, struct file *filp)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = bdev->bd_disk->private_data;
+ 	drive->usage++;
+ 	return 0;
+ }
+ 
+-static int idescsi_ide_release(struct inode *inode, struct file *filp)
++static int idescsi_ide_release(struct gendisk *disk)
+ {
+-	ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++	ide_drive_t *drive = disk->private_data;
+ 	drive->usage--;
+ 	return 0;
+ }
+ 
+-static int idescsi_ide_ioctl(struct inode *inode, struct file *file,
++static int idescsi_ide_ioctl(struct block_device *bdev, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	return generic_ide_ioctl(bdev, cmd, arg);
+ }
+ 
+--- linux-2.6.0-test6/drivers/scsi/Kconfig	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/Kconfig	2003-10-05 00:36:26.000000000 -0700
+@@ -55,6 +55,14 @@ config BLK_DEV_SD
+ 	  In this case, do not compile the driver for your SCSI host adapter
+ 	  (below) as a module either.
+ 
++config MAX_SD_DISKS
++	int "Maximum number of SCSI disks to support (256-8192)"
++	depends on BLK_DEV_SD
++	default "256"
++	help
++	The maximum number SCSI disks to support. Default is 256.
++	Change this value if you want kernel to support lots of SCSI devices.
++
+ config CHR_DEV_ST
+ 	tristate "SCSI tape support"
+ 	depends on SCSI
+@@ -1148,16 +1156,6 @@ config SCSI_QLOGIC_1280
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called qla1280.
+ 
+-config SCSI_QLOGIC_1280_PIO
+-	bool "Use PIO instead of MMIO" if !X86_VISWS
+-	depends on SCSI_QLOGIC_1280
+-	default y if X86_VISWS
+-	help
+-	  This instructs the driver to use programmed I/O ports (PIO) instead
+-	  of PCI shared memory (MMIO).  This can possibly solve some problems
+-	  in case your mainboard has memory consistency issues.  If unsure,
+-	  say N.
+-
+ config SCSI_QLOGICPTI
+ 	tristate "PTI Qlogic, ISP Driver"
+ 	depends on SBUS && SCSI
+@@ -1435,7 +1433,7 @@ config A3000_SCSI
+ 
+ config A4000T_SCSI
+ 	bool "A4000T SCSI support (EXPERIMENTAL)"
+-	depends on AMIGA && SCSI && EXPERIMENTAL
++	depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN
+ 	help
+ 	  Support for the NCR53C710 SCSI controller on the Amiga 4000T.
+ 
+@@ -1503,7 +1501,7 @@ config FASTLANE_SCSI
+ 
+ config A4091_SCSI
+ 	bool "A4091 SCSI support (EXPERIMENTAL)"
+-	depends on ZORRO && SCSI && EXPERIMENTAL
++	depends on ZORRO && SCSI && EXPERIMENTAL && BROKEN
+ 	help
+ 	  Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller
+ 	  (1993).  Very obscure -- the 4091 was part of an Amiga 4000 upgrade
+@@ -1511,7 +1509,7 @@ config A4091_SCSI
+ 
+ config WARPENGINE_SCSI
+ 	bool "WarpEngine SCSI support (EXPERIMENTAL)"
+-	depends on ZORRO && SCSI && EXPERIMENTAL
++	depends on ZORRO && SCSI && EXPERIMENTAL && BROKEN
+ 	help
+ 	  Support for MacroSystem Development's WarpEngine Amiga SCSI-2
+ 	  controller. Info at
+@@ -1519,7 +1517,7 @@ config WARPENGINE_SCSI
+ 
+ config BLZ603EPLUS_SCSI
+ 	bool "Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)"
+-	depends on ZORRO && SCSI && EXPERIMENTAL
++	depends on ZORRO && SCSI && EXPERIMENTAL && BROKEN
+ 	help
+ 	  If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+
+ 	  accelerator, say Y. Otherwise, say N.
+@@ -1535,7 +1533,7 @@ config OKTAGON_SCSI
+ 
+ config ATARI_SCSI
+ 	tristate "Atari native SCSI support"
+-	depends on ATARI && SCSI
++	depends on ATARI && SCSI && BROKEN
+ 	---help---
+ 	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
+ 	  Falcon, ...) say Y to get it supported. Of course also, if you have
+@@ -1604,7 +1602,7 @@ config MVME147_SCSI
+ 
+ config MVME16x_SCSI
+ 	bool "NCR53C710 SCSI driver for MVME16x"
+-	depends on MVME16x && SCSI
++	depends on MVME16x && SCSI && BROKEN
+ 	help
+ 	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
+ 	  SCSI controller chip.  Almost everyone using one of these boards
+@@ -1612,7 +1610,7 @@ config MVME16x_SCSI
+ 
+ config BVME6000_SCSI
+ 	bool "NCR53C710 SCSI driver for BVME6000"
+-	depends on BVME6000 && SCSI
++	depends on BVME6000 && SCSI && BROKEN
+ 	help
+ 	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
+ 	  SCSI controller chip.  Almost everyone using one of these boards
+--- linux-2.6.0-test6/drivers/scsi/megaraid.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/scsi/megaraid.c	2003-10-05 00:33:24.000000000 -0700
+@@ -586,7 +586,7 @@ mega_find_card(Scsi_Host_Template *host_
+ 
+ 		/* Set the Mode of addressing to 64 bit if we can */
+ 		if((adapter->flag & BOARD_64BIT)&&(sizeof(dma_addr_t) == 8)) {
+-			pci_set_dma_mask(pdev, 0xffffffffffffffff);
++			pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+ 			adapter->has_64bit_addr = 1;
+ 		}
+ 		else  {
+--- linux-2.6.0-test6/drivers/scsi/ncr53c8xx.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/ncr53c8xx.c	2003-10-05 00:33:24.000000000 -0700
+@@ -7757,7 +7757,7 @@ static void ncr_init_ccb(ncb_p np, ccb_p
+ 	cp->start.schedule.l_cmd = cpu_to_scr(SCR_JUMP);
+ 	cp->start.p_phys	 = cpu_to_scr(CCB_PHYS(cp, phys));
+ 
+-	bcopy(&cp->start, &cp->restart, sizeof(cp->restart));
++	memcpy(&cp->restart, &cp->start, sizeof(cp->restart));
+ 
+ 	cp->start.schedule.l_paddr   = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
+ 	cp->restart.schedule.l_paddr = cpu_to_scr(NCB_SCRIPTH_PHYS (np, abort));
+--- linux-2.6.0-test6/drivers/scsi/nsp32.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/scsi/nsp32.c	2003-10-05 00:33:24.000000000 -0700
+@@ -3435,15 +3435,6 @@ static inline int nsp32_prom_get(nsp32_h
+  * Power Management
+  */
+ #ifdef CONFIG_PM
+-/* Save Device Context */
+-static int nsp32_save_state(struct pci_dev *pdev, u32 state)
+-{
+-	struct Scsi_Host *host = pci_get_drvdata(pdev);
+-
+-	nsp32_msg(KERN_INFO, "pci-save_state: stub, pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host);
+-
+-	return 0;
+-}
+ 
+ /* Device suspended */
+ static int nsp32_suspend(struct pci_dev *pdev, u32 state)
+@@ -3573,7 +3564,6 @@ static struct pci_driver nsp32_driver = 
+ 	.probe		= nsp32_probe,
+ 	.remove		= __devexit_p(nsp32_remove),
+ #ifdef CONFIG_PM
+-	.save_state     = nsp32_save_state,
+ 	.suspend	= nsp32_suspend, 
+ 	.resume		= nsp32_resume, 
+ 	.enable_wake    = nsp32_enable_wake,
+--- linux-2.6.0-test6/drivers/scsi/qla1280.c	2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/qla1280.c	2003-10-05 00:33:24.000000000 -0700
+@@ -16,10 +16,15 @@
+ * General Public License for more details.
+ *
+ ******************************************************************************/
+-#define QLA1280_VERSION      "3.23.36"
++#define QLA1280_VERSION      "3.23.37"
+ /*****************************************************************************
+     Revision History:
+-    Rev  3.23.36 September 19, 2003, Christoph Hellwig
++    Rev  3.23.37 October 1, 2003, Jes Sorensen
++	- Make MMIO depend on CONFIG_X86_VISWS instead of yet another
++	  random CONFIG option
++	- Clean up locking in probe path
++    Rev  3.23.36 October 1, 2003, Christoph Hellwig
++	- queuecommand only ever receives new commands - clear flags
+ 	- Reintegrate lost fixes from Linux 2.5
+     Rev  3.23.35 August 14, 2003, Jes Sorensen
+ 	- Build against 2.6
+@@ -315,14 +320,14 @@
+ 
+ #if LINUX_VERSION_CODE >= 0x020545
+ #include <scsi/scsi_host.h>
++#include "scsi.h"
+ #else
+ #include <linux/blk.h>
++#include "scsi.h"
+ #include "hosts.h"
+ #include "sd.h"
+ #endif
+ 
+-#include "scsi.h"
+-
+ #if LINUX_VERSION_CODE < 0x020407
+ #error "Kernels older than 2.4.7 are no longer supported"
+ #endif
+@@ -339,7 +344,10 @@
+ #define  DEBUG_PRINT_NVRAM	0
+ #define  DEBUG_QLA1280		0
+ 
+-#ifdef	CONFIG_SCSI_QLOGIC_1280_PIO
++/*
++ * The SGI VISWS is broken and doesn't support MMIO ;-(
++ */
++#ifdef CONFIG_X86_VISWS
+ #define	MEMORY_MAPPED_IO	0
+ #else
+ #define	MEMORY_MAPPED_IO	1
+@@ -414,6 +422,11 @@ scsi_adjust_queue_depth(Scsi_Device *dev
+ #else
+ #define HOST_LOCK			ha->host->host_lock
+ #endif
++#if LINUX_VERSION_CODE < 0x020600
++#define DEV_SIMPLE_TAGS(device)		device->tagged_queue
++#else
++#define DEV_SIMPLE_TAGS(device)		device->simple_tags
++#endif
+ #if defined(__ia64__) && !defined(ia64_platform_is)
+ #define ia64_platform_is(foo)		(!strcmp(x, platform_name))
+ #endif
+@@ -647,11 +660,11 @@ static int ql_debug_level = 1;
+ #define	PROC_BUF	&qla1280_buffer[len]
+ 
+ #if LINUX_VERSION_CODE < 0x020600
+-static int qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
+-		      int hostno, int inout)
++static int qla1280_proc_info(char *buffer, char **start, off_t offset,
++			     int length, int hostno, int inout)
+ #else
+-static int qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start,
+-		      off_t offset, int length, int inout)
++static int qla1280_proc_info(struct Scsi_Host *host, char *buffer,
++			     char **start, off_t offset, int length, int inout)
+ #endif
+ {
+ 	struct scsi_qla_host *ha;
+@@ -955,8 +968,8 @@ qla1280_do_device_init(struct pci_dev *p
+ 		       host->io_port, host->io_port + 0xff);
+ 		goto error_free_irq;
+ 	}
+-
+ #endif
++
+ 	/* load the F/W, read paramaters, and init the H/W */
+ 	if (qla1280_initialize_adapter(ha)) {
+ 		printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
+@@ -1598,6 +1611,7 @@ qla1280_intr_handler(int irq, void *dev_
+ 	return IRQ_RETVAL(handled);
+ }
+ 
++
+ static int
+ qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+ {
+@@ -1666,9 +1680,7 @@ qla1280_slave_configure(Scsi_Device *dev
+ 	int target = device->id;
+ 	int status = 0;
+ 	struct nvram *nv;
+-#if LINUX_VERSION_CODE < 0x020500
+ 	unsigned long flags;
+-#endif
+ 
+ 	ha = (struct scsi_qla_host *)device->host->hostdata;
+ 	nv = &ha->nvram;
+@@ -1706,17 +1718,13 @@ qla1280_slave_configure(Scsi_Device *dev
+ 			nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
+ 	}
+ 
+-#if LINUX_VERSION_CODE < 0x020500
+ 	spin_lock_irqsave(HOST_LOCK, flags);
+-#endif
+ 	if (nv->bus[bus].target[target].parameter.f.enable_sync) {
+ 		status = qla12160_set_target_parameters(ha, bus, target);
+ 	}
+ 
+ 	qla12160_get_target_parameters(ha, device);
+-#if LINUX_VERSION_CODE < 0x020500
+ 	spin_unlock_irqrestore(HOST_LOCK, flags);
+-#endif
+ 	return status;
+ }
+ 
+@@ -1995,7 +2003,7 @@ qla1280_mem_alloc(struct scsi_qla_host *
+ 	if (ha->request_ring)
+ 		pci_free_consistent(ha->pdev,
+                                     ((REQUEST_ENTRY_CNT + 1) *
+-                                     (sizeof(request_t))),
++				     (sizeof(request_t))),
+                                     ha->request_ring, ha->request_dma);
+  finish:
+ 	LEAVE("qla1280_mem_alloc");
+@@ -2088,6 +2096,9 @@ qla1280_initialize_adapter(struct scsi_q
+ 	struct device_reg *reg;
+ 	int status;
+ 	int bus;
++#if LINUX_VERSION_CODE > 0x020500
++	unsigned long flags;
++#endif
+ 
+ 	ENTER("qla1280_initialize_adapter");
+ 
+@@ -2131,6 +2142,15 @@ qla1280_initialize_adapter(struct scsi_q
+ 			"NVRAM\n");
+ 	}
+ 
++#if LINUX_VERSION_CODE >= 0x020500
++	/*
++	 * It's necessary to grab the spin here as qla1280_mailbox_command
++	 * needs to be able to drop the lock unconditionally to wait
++	 * for completion.
++	 * In 2.4 ->detect is called with the io_request_lock held.
++	 */
++	spin_lock_irqsave(HOST_LOCK, flags);
++#endif
+ 	/* If firmware needs to be loaded */
+ 	if (qla1280_isp_firmware(ha)) {
+ 		if (!(status = qla1280_chip_diag (ha))) {
+@@ -2183,6 +2203,9 @@ qla1280_initialize_adapter(struct scsi_q
+ 		status = 1;
+ 
+  out:
++#if LINUX_VERSION_CODE >= 0x020500
++	spin_unlock_irqrestore(HOST_LOCK, flags);
++#endif
+ 	if (status)
+ 		dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");
+ 
+@@ -3208,18 +3231,14 @@ qla1280_mailbox_command(struct scsi_qla_
+ 	timer.function = qla1280_mailbox_timeout;
+ 	add_timer(&timer);
+ 
+-#if LINUX_VERSION_CODE < 0x020500
+ 	spin_unlock_irq(HOST_LOCK);
+-#endif
+ 	WRT_REG_WORD(&reg->host_cmd, HC_SET_HOST_INT);
+ 	data = qla1280_debounce_register(&reg->istatus);
+ 
+ 	wait_for_completion(&wait);
+ 	del_timer_sync(&timer);
+ 
+-#if LINUX_VERSION_CODE < 0x020500
+ 	spin_lock_irq(HOST_LOCK);
+-#endif
+ 
+ 	ha->mailbox_wait = NULL;
+ 
+@@ -3636,7 +3655,7 @@ qla1280_64bit_start_scsi(struct scsi_qla
+ 		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+ 
+ 	/* Enable simple tag queuing if device supports it. */
+-	if (cmd->device->simple_tags)
++	if (DEV_SIMPLE_TAGS(cmd->device))
+ 		pkt->control_flags |= cpu_to_le16(BIT_3);
+ 
+ 	/* Load SCSI command packet. */
+@@ -3936,7 +3955,7 @@ qla1280_32bit_start_scsi(struct scsi_qla
+ 		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+ 
+ 	/* Enable simple tag queuing if device supports it. */
+-	if (cmd->device->simple_tags)
++	if (DEV_SIMPLE_TAGS(cmd->device))
+ 		pkt->control_flags |= cpu_to_le16(BIT_3);
+ 
+ 	/* Load SCSI command packet. */
+@@ -4823,6 +4842,7 @@ qla1280_debounce_register(volatile u16 *
+ 	return ret;
+ }
+ 
++
+ /************************************************************************
+  * qla1280_check_for_dead_scsi_bus                                      *
+  *                                                                      *
+@@ -4891,7 +4911,7 @@ qla12160_get_target_parameters(struct sc
+ 	} else
+ 		printk(" Async");
+ 
+-	if (device->simple_tags)
++	if (DEV_SIMPLE_TAGS(device))
+ 		printk(", Tagged queuing: depth %d", device->queue_depth);
+ 	printk("\n");
+ }
+@@ -5105,6 +5125,7 @@ qla1280_get_token(char *str)
+ 	return ret;
+ }
+ 
++
+ static Scsi_Host_Template driver_template = {
+ 	.proc_info		= qla1280_proc_info,
+ 	.name			= "Qlogic ISP 1280/12160",
+@@ -5132,6 +5153,7 @@ static Scsi_Host_Template driver_templat
+ 
+ #include "scsi_module.c"
+ 
++
+ /*
+  * Overrides for Emacs so that we almost follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+--- linux-2.6.0-test6/drivers/scsi/qlogicfc.c	2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/qlogicfc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -718,8 +718,8 @@ int isp2x00_detect(Scsi_Host_Template * 
+ 				continue;
+ 
+ 			/* Try to configure DMA attributes. */
+-			if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
+-			    pci_set_dma_mask(pdev, (u64) 0xffffffff))
++			if (pci_set_dma_mask(pdev, 0xffffffffffffffffULL) &&
++			    pci_set_dma_mask(pdev, 0xffffffffULL))
+ 					continue;
+ 
+ 		        host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata));
+--- linux-2.6.0-test6/drivers/scsi/sd.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sd.c	2003-10-05 00:36:26.000000000 -0700
+@@ -62,6 +62,7 @@
+  */
+ #define SD_MAJORS	16
+ #define SD_DISKS	(SD_MAJORS << 4)
++#define TOTAL_SD_DISKS	CONFIG_MAX_SD_DISKS
+ 
+ /*
+  * Time out in seconds for disks and Magneto-opticals (which are slower).
+@@ -87,7 +88,7 @@ struct scsi_disk {
+ 	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
+ };
+ 
+-static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
++static unsigned long sd_index_bits[TOTAL_SD_DISKS / BITS_PER_LONG];
+ static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
+ 
+ static int sd_revalidate_disk(struct gendisk *disk);
+@@ -122,6 +123,9 @@ static int sd_major(int major_idx)
+ 		return SCSI_DISK1_MAJOR + major_idx - 1;
+ 	case 8 ... 15:
+ 		return SCSI_DISK8_MAJOR + major_idx - 8;
++#define MAX_IDX        (TOTAL_SD_DISKS >> 4)
++	case 16 ... MAX_IDX:
++		return SCSI_DISK15_MAJOR;
+ 	default:
+ 		BUG();
+ 		return 0;	/* shut up gcc */
+@@ -348,9 +352,9 @@ queue:
+  *	In the latter case @inode and @filp carry an abridged amount
+  *	of information as noted above.
+  **/
+-static int sd_open(struct inode *inode, struct file *filp)
++static int sd_open(struct block_device *bdev, struct file *filp)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
++	struct gendisk *disk = bdev->bd_disk;
+ 	struct scsi_disk *sdkp = scsi_disk(disk);
+ 	struct scsi_device *sdev = sdkp->device;
+ 	int retval;
+@@ -370,7 +374,7 @@ static int sd_open(struct inode *inode, 
+ 		goto error_out;
+ 
+ 	if (sdev->removable || sdkp->write_prot)
+-		check_disk_change(inode->i_bdev);
++		check_disk_change(bdev);
+ 
+ 	/*
+ 	 * If the drive is empty, just let the open fail.
+@@ -421,9 +425,8 @@ error_out:
+  *	Note: may block (uninterruptible) if error recovery is underway
+  *	on this disk.
+  **/
+-static int sd_release(struct inode *inode, struct file *filp)
++static int sd_release(struct gendisk *disk)
+ {
+-	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct scsi_disk *sdkp = scsi_disk(disk);
+ 	struct scsi_device *sdev = sdkp->device;
+ 
+@@ -486,10 +489,9 @@ static int sd_hdio_getgeo(struct block_d
+  *	Note: most ioctls are forward onto the block subsystem or further
+  *	down in the scsi subsytem.
+  **/
+-static int sd_ioctl(struct inode * inode, struct file * filp, 
++static int sd_ioctl(struct block_device *bdev, struct file *filp, 
+ 		    unsigned int cmd, unsigned long arg)
+ {
+-	struct block_device *bdev = inode->i_bdev;
+ 	struct gendisk *disk = bdev->bd_disk;
+ 	struct scsi_device *sdp = scsi_disk(disk)->device;
+ 	int error;
+@@ -1275,8 +1277,8 @@ static int sd_probe(struct device *dev)
+ 		goto out_free;
+ 
+ 	spin_lock(&sd_index_lock);
+-	index = find_first_zero_bit(sd_index_bits, SD_DISKS);
+-	if (index == SD_DISKS) {
++	index = find_first_zero_bit(sd_index_bits, TOTAL_SD_DISKS);
++	if (index == TOTAL_SD_DISKS) {
+ 		spin_unlock(&sd_index_lock);
+ 		error = -EBUSY;
+ 		goto out_put;
+@@ -1291,15 +1293,24 @@ static int sd_probe(struct device *dev)
+ 	sdkp->openers = 0;
+ 
+ 	gd->major = sd_major(index >> 4);
+-	gd->first_minor = (index & 15) << 4;
++	if (index > SD_DISKS)
++		gd->first_minor = ((index - SD_DISKS) & 15) << 4;
++	else
++		gd->first_minor = (index & 15) << 4;
+ 	gd->minors = 16;
+ 	gd->fops = &sd_fops;
+ 
+-	if (index >= 26) {
++	if (index < 26) {
++		sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
++	} else if (index < (26*27)) {
+ 		sprintf(gd->disk_name, "sd%c%c",
+ 			'a' + index/26-1,'a' + index % 26);
+ 	} else {
+-		sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
++		const unsigned int m1 = (index/ 26 - 1) / 26 - 1;
++		const unsigned int m2 = (index / 26 - 1) % 26;
++		const unsigned int m3 = index % 26;
++		sprintf(gd->disk_name, "sd%c%c%c",
++			'a' + m1, 'a' + m2, 'a' + m3);
+ 	}
+ 
+ 	strcpy(gd->devfs_name, sdp->devfs_name);
+--- linux-2.6.0-test6/drivers/scsi/sr.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sr.c	2003-10-05 00:34:45.000000000 -0700
+@@ -289,12 +289,12 @@ static int sr_init_command(struct scsi_c
+ 			return 0;
+ 
+ 		memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
+-		if (rq_data_dir(rq) == WRITE)
++		if (!rq->data_len)
++			SCpnt->sc_data_direction = SCSI_DATA_NONE;
++		else if (rq_data_dir(rq) == WRITE)
+ 			SCpnt->sc_data_direction = SCSI_DATA_WRITE;
+-		else if (rq->data_len)
+-			SCpnt->sc_data_direction = SCSI_DATA_READ;
+ 		else
+-			SCpnt->sc_data_direction = SCSI_DATA_NONE;
++			SCpnt->sc_data_direction = SCSI_DATA_READ;
+ 
+ 		this_count = rq->data_len;
+ 		if (rq->timeout)
+@@ -413,22 +413,22 @@ queue:
+ 	return 1;
+ }
+ 
+-static int sr_block_open(struct inode *inode, struct file *file)
++static int sr_block_open(struct block_device *bdev, struct file *file)
+ {
+-	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+-	return cdrom_open(&cd->cdi, inode, file);
++	struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
++	return cdrom_open(&cd->cdi, bdev, file);
+ }
+ 
+-static int sr_block_release(struct inode *inode, struct file *file)
++static int sr_block_release(struct gendisk *disk)
+ {
+-	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+-	return cdrom_release(&cd->cdi, file);
++	struct scsi_cd *cd = scsi_cd(disk);
++	return cdrom_release(&cd->cdi);
+ }
+ 
+-static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+-			  unsigned long arg)
++static int sr_block_ioctl(struct block_device *bdev, struct file *file,
++			  unsigned cmd, unsigned long arg)
+ {
+-	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
++	struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
+ 	struct scsi_device *sdev = cd->device;
+ 
+         /*
+@@ -440,7 +440,7 @@ static int sr_block_ioctl(struct inode *
+                 case SCSI_IOCTL_GET_BUS_NUMBER:
+                         return scsi_ioctl(sdev, cmd, (void *)arg);
+ 	}
+-	return cdrom_ioctl(&cd->cdi, inode, cmd, arg);
++	return cdrom_ioctl(&cd->cdi, bdev, cmd, arg);
+ }
+ 
+ static int sr_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0-test6/drivers/scsi/sun3_scsi.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/drivers/scsi/sun3_scsi.c	2003-10-05 00:33:24.000000000 -0700
+@@ -308,7 +308,6 @@ int sun3scsi_detect(Scsi_Host_Template *
+ 	return 1;
+ }
+ 
+-#ifdef MODULE
+ int sun3scsi_release (struct Scsi_Host *shpnt)
+ {
+ 	if (shpnt->irq != SCSI_IRQ_NONE)
+@@ -318,7 +317,6 @@ int sun3scsi_release (struct Scsi_Host *
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ #ifdef RESET_BOOT
+ /*
+--- linux-2.6.0-test6/drivers/scsi/sun3_scsi.h	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/scsi/sun3_scsi.h	2003-10-05 00:33:24.000000000 -0700
+@@ -52,11 +52,7 @@ static int sun3scsi_detect (Scsi_Host_Te
+ static const char *sun3scsi_info (struct Scsi_Host *);
+ static int sun3scsi_bus_reset(Scsi_Cmnd *);
+ static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+-#ifdef MODULE
+ static int sun3scsi_release (struct Scsi_Host *);
+-#else
+-#define sun3scsi_release NULL
+-#endif
+ 
+ #ifndef CMD_PER_LUN
+ #define CMD_PER_LUN 2
+--- linux-2.6.0-test6/drivers/scsi/sun3_scsi_vme.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/drivers/scsi/sun3_scsi_vme.c	2003-10-05 00:33:24.000000000 -0700
+@@ -140,7 +140,7 @@ static struct Scsi_Host *default_instanc
+  
+ static int sun3scsi_detect(Scsi_Host_Template * tpnt)
+ {
+-	unsigned long ioaddr, irq;
++	unsigned long ioaddr, irq = 0;
+ 	static int called = 0;
+ 	struct Scsi_Host *instance;
+ 	int i;
+@@ -277,17 +277,15 @@ static int sun3scsi_detect(Scsi_Host_Tem
+ 	return 1;
+ }
+ 
+-#ifdef MODULE
+ int sun3scsi_release (struct Scsi_Host *shpnt)
+ {
+ 	if (shpnt->irq != SCSI_IRQ_NONE)
+ 		free_irq (shpnt->irq, NULL);
+ 
+-	iounmap(sun3_scsi_regp);
++	iounmap((void *)sun3_scsi_regp);
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ #ifdef RESET_BOOT
+ /*
+--- linux-2.6.0-test6/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-10-05 00:34:19.000000000 -0700
+@@ -2159,8 +2159,7 @@ sym53c8xx_pci_init(struct pci_dev *pdev,
+ 
+ 	/* If the chip can do Memory Write Invalidate, enable it */
+ 	if (chip->features & FE_WRIE) {
+-		if (pci_set_mwi(pdev))
+-			return -1;
++		pci_set_mwi(pdev);
+ 	}
+ 
+ 	/*
+--- linux-2.6.0-test6/drivers/scsi/sym53c8xx_2/sym_glue.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_2/sym_glue.h	2003-10-05 00:33:24.000000000 -0700
+@@ -70,10 +70,6 @@
+ #include <scsi/scsi_host.h>
+ #include "../scsi.h"		/* XXX: DID_* */
+ 
+-#ifndef bcopy
+-#define bcopy(s, d, n)	memcpy((d), (s), (n))
+-#endif
+-
+ #ifndef bzero
+ #define bzero(d, n)	memset((d), 0, (n))
+ #endif
+--- linux-2.6.0-test6/drivers/scsi/sym53c8xx_2/sym_hipd.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_2/sym_hipd.c	2003-10-05 00:34:20.000000000 -0700
+@@ -838,7 +838,8 @@ static int sym_prepare_setting(hcb_p np,
+ 
+ 	period = parisc_setup_hcb(np, period);
+ 
+-	if	(period <= 250)		np->minsync = 10;
++	if	(period == 250)		np->minsync = 9;
++	else if	(period <= 250)		np->minsync = 10;
+ 	else if	(period <= 303)		np->minsync = 11;
+ 	else if	(period <= 500)		np->minsync = 12;
+ 	else				np->minsync = (period + 40 - 1) / 40;
+@@ -5889,9 +5890,9 @@ int sym_hcb_attach(hcb_p np, struct sym_
+ 	/*
+ 	 *  Copy scripts to controller instance.
+ 	 */
+-	bcopy(fw->a_base, np->scripta0, np->scripta_sz);
+-	bcopy(fw->b_base, np->scriptb0, np->scriptb_sz);
+-	bcopy(fw->z_base, np->scriptz0, np->scriptz_sz);
++	memcpy(np->scripta0, fw->a_base, np->scripta_sz);
++	memcpy(np->scriptb0, fw->b_base, np->scriptb_sz);
++	memcpy(np->scriptz0, fw->z_base, np->scriptz_sz);
+ 
+ 	/*
+ 	 *  Setup variable parts in scripts and compute
+--- linux-2.6.0-test6/drivers/scsi/sym53c8xx_2/sym_misc.c	2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_2/sym_misc.c	2003-10-05 00:33:24.000000000 -0700
+@@ -225,7 +225,7 @@ void sym_announce_transfer_rate(hcb_p np
+  */
+ void sym_update_trans_settings(hcb_p np, tcb_p tp)
+ {
+-	bcopy(&tp->tinfo.user, &tp->tinfo.goal, sizeof(tp->tinfo.goal));
++	memcpy(&tp->tinfo.goal, &tp->tinfo.user, sizeof(tp->tinfo.goal));
+ 
+ 	if (tp->inq_version >= 4) {
+ 		switch(tp->inq_byte56 & INQ56_CLOCKING) {
+--- linux-2.6.0-test6/drivers/scsi/sym53c8xx_comm.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_comm.h	2003-10-05 00:33:24.000000000 -0700
+@@ -88,10 +88,6 @@
+ #define u_int		unsigned int
+ #define u_long		unsigned long
+ 
+-#ifndef bcopy
+-#define bcopy(s, d, n)	memcpy((d), (s), (n))
+-#endif
+-
+ #ifndef bcmp
+ #define bcmp(s, d, n)	memcmp((d), (s), (n))
+ #endif
+--- linux-2.6.0-test6/drivers/serial/8250.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/serial/8250.c	2003-10-05 00:36:10.000000000 -0700
+@@ -469,8 +469,14 @@ static void autoconfig_16550a(struct uar
+ 	 */
+ 	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ 	if (serial_in(up, UART_EFR) == 0) {
+-		DEBUG_AUTOCONF("EFRv1 ");
+-		up->port.type = PORT_16650;
++		serial_outp(up, UART_EFR, 0xA8);
++		if (serial_in(up, UART_EFR) != 0) {
++			DEBUG_AUTOCONF("EFRv1 ");
++			up->port.type = PORT_16650;
++		} else {
++			DEBUG_AUTOCONF("Motorola 8xxx DUART ");
++		}
++		serial_outp(up, UART_EFR, 0);
+ 		return;
+ 	}
+ 
+@@ -490,7 +496,9 @@ static void autoconfig_16550a(struct uar
+ 	 * Attempt to switch to bank 2, read the value of the LOOP bit
+ 	 * from EXCR1. Switch back to bank 0, change it in MCR. Then
+ 	 * switch back to bank 2, read it from EXCR1 again and check
+-	 * it's changed. If so, set baud_base in EXCR2 to 921600.
++	 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
++	 * On PowerPC we don't want to change baud_base, as we have
++	 * a number of different divisors.  -- Tom Rini
+ 	 */
+ 	serial_outp(up, UART_LCR, 0);
+ 	status1 = serial_in(up, UART_MCR);
+@@ -506,12 +514,14 @@ static void autoconfig_16550a(struct uar
+ 		serial_outp(up, UART_MCR, status1);
+ 
+ 		if ((status2 ^ status1) & UART_MCR_LOOP) {
++#ifndef CONFIG_PPC
+ 			serial_outp(up, UART_LCR, 0xE0);
+ 			status1 = serial_in(up, 0x04); /* EXCR1 */
+ 			status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+ 			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+ 			serial_outp(up, 0x04, status1);
+ 			serial_outp(up, UART_LCR, 0);
++#endif
+ 
+ 			up->port.type = PORT_NS16550A;
+ 			up->port.uartclk = 921600*16;
+@@ -825,7 +835,7 @@ receive_chars(struct uart_8250_port *up,
+ 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+ 			tty->flip.work.func((void *)tty);
+ 			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+-				return; // if TTY_DONT_FLIP is set
++				return;	/* if TTY_DONT_FLIP is set */
+ 		}
+ 		ch = serial_inp(up, UART_RX);
+ 		*tty->flip.char_buf_ptr = ch;
+@@ -1186,12 +1196,21 @@ static void serial8250_break_ctl(struct 
+ 	spin_unlock_irqrestore(&up->port.lock, flags);
+ }
+ 
++#ifdef CONFIG_KGDB
++static int kgdb_irq = -1;
++#endif
++
+ static int serial8250_startup(struct uart_port *port)
+ {
+ 	struct uart_8250_port *up = (struct uart_8250_port *)port;
+ 	unsigned long flags;
+ 	int retval;
+ 
++#ifdef CONFIG_KGDB
++	if (up->port.irq == kgdb_irq)
++		return -EBUSY;
++#endif
++
+ 	up->capabilities = uart_config[up->port.type].flags;
+ 
+ 	if (up->port.type == PORT_16C950) {
+@@ -1857,6 +1876,10 @@ static void __init serial8250_register_p
+ 	for (i = 0; i < UART_NR; i++) {
+ 		struct uart_8250_port *up = &serial8250_ports[i];
+ 
++#ifdef CONFIG_KGDB
++		if (up->port.irq == kgdb_irq)
++			up->port.kgdb = 1;
++#endif
+ 		up->port.line = i;
+ 		up->port.ops = &serial8250_pops;
+ 		init_timer(&up->timer);
+@@ -2101,7 +2124,8 @@ void serial8250_get_irq_map(unsigned int
+ 
+ /**
+  *	serial8250_suspend_port - suspend one serial port
+- *	@line: serial line number
++ *	@line:  serial line number
++ *      @level: the level of port suspension, as per uart_suspend_port
+  *
+  *	Suspend one serial port.
+  */
+@@ -2112,7 +2136,8 @@ void serial8250_suspend_port(int line)
+ 
+ /**
+  *	serial8250_resume_port - resume one serial port
+- *	@line: serial line number
++ *	@line:  serial line number
++ *      @level: the level of port resumption, as per uart_resume_port
+  *
+  *	Resume one serial port.
+  */
+@@ -2121,6 +2146,31 @@ void serial8250_resume_port(int line)
+ 	uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
+ }
+ 
++#ifdef CONFIG_KGDB
++/*
++ * Find all the ports using the given irq and shut them down.
++ * Result should be that the irq will be released.
++ */
++void shutdown_for_kgdb(struct async_struct * info)
++{
++        int irq = info->state->irq;
++        struct uart_8250_port *up;
++	int ttyS;
++
++	kgdb_irq = irq;			/* save for later init */
++	for (ttyS = 0; ttyS < UART_NR; ttyS++){
++		up =  &serial8250_ports[ttyS];
++		if (up->port.irq == irq && (irq_lists + irq)->head) {
++#ifdef CONFIG_DEBUG_SPINLOCK   /* ugly business... */
++			if(up->port.lock.magic != SPINLOCK_MAGIC)
++				spin_lock_init(&up->port.lock);
++#endif
++			serial8250_shutdown(&up->port);
++		}
++        }
++}
++#endif	/* CONFIG_KGDB */
++
+ static int __init serial8250_init(void)
+ {
+ 	int ret, i;
+--- linux-2.6.0-test6/drivers/serial/serial_core.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/serial/serial_core.c	2003-10-05 00:36:10.000000000 -0700
+@@ -263,9 +263,9 @@ static void uart_shutdown(struct uart_st
+ 
+ /**
+  *	uart_update_timeout - update per-port FIFO timeout.
+- *	@port: uart_port structure describing the port.
++ *	@port:  uart_port structure describing the port
+  *	@cflag: termios cflag value
+- *	@quot: uart clock divisor quotient
++ *	@baud:  speed of the port
+  *
+  *	Set the port FIFO timeout value.  The @cflag value should
+  *	reflect the actual hardware settings.
+@@ -1973,6 +1973,11 @@ uart_configure_port(struct uart_driver *
+ {
+ 	unsigned int flags;
+ 
++#ifdef CONFIG_KGDB
++	if (port->kgdb)
++		return;
++#endif
++
+ 	/*
+ 	 * If there isn't a port here, don't do anything further.
+ 	 */
+--- linux-2.6.0-test6/drivers/telephony/ixj.h	2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/telephony/ixj.h	2003-10-05 00:33:24.000000000 -0700
+@@ -42,6 +42,7 @@ static char ixj_h_rcsid[] = "$Id: ixj.h,
+ 
+ #define IXJ_VERSION 3031
+ 
++#include <linux/version.h>
+ #include <linux/types.h>
+ 
+ #include <linux/ixjuser.h>
+--- linux-2.6.0-test6/drivers/telephony/phonedev.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/telephony/phonedev.c	2003-10-05 00:33:24.000000000 -0700
+@@ -14,7 +14,6 @@
+  *              phone_register_device now works with unit!=PHONE_UNIT_ANY
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/drivers/usb/core/inode.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/core/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -38,6 +38,7 @@
+ #include <linux/namei.h>
+ #include <linux/usbdevice_fs.h>
+ #include <linux/smp_lock.h>
++#include <linux/parser.h>
+ #include <asm/byteorder.h>
+ 
+ static struct super_operations usbfs_ops;
+@@ -62,86 +63,94 @@ static umode_t devmode = S_IWUSR | S_IRU
+ static umode_t busmode = S_IXUGO | S_IRUGO;
+ static umode_t listmode = S_IRUGO;
+ 
++enum {
++	Opt_devuid, Opt_devgid, Opt_devmode,
++	Opt_busuid, Opt_busgid, Opt_busmode,
++	Opt_listuid, Opt_listgid, Opt_listmode,
++	Opt_err,
++};
++
++static match_table_t tokens = {
++	{Opt_devuid, "devuid=%u"},
++	{Opt_devgid, "devgid=%u"},
++	{Opt_devmode, "devmode=%o"},
++	{Opt_busuid, "busuid=%u"},
++	{Opt_busgid, "busgid=%u"},
++	{Opt_busmode, "busmode=%o"},
++	{Opt_listuid, "listuid=%u"},
++	{Opt_listgid, "listgid=%u"},
++	{Opt_listmode, "listmode=%o"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(struct super_block *s, char *data)
+ {
+-	char *curopt = NULL, *value;
++	char *p;
++	int option;
+ 
+-	while ((curopt = strsep(&data, ",")) != NULL) {
+-		if (!*curopt)
++	while ((p = strsep(&data, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(curopt, '=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp(curopt, "devuid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			devuid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "devgid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			devgid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "devmode")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "busuid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			busuid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "busgid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			busgid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "busmode")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "listuid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			listuid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "listgid")) {
+-			if (!value || !value[0])
+-				return -EINVAL;
+-			listgid = simple_strtoul(value, &value, 0);
+-			if (*value)
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_devuid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			devuid = option;
++			break;
++		case Opt_devgid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			devgid = option;
++			break;
++		case Opt_devmode:
++			if (match_octal(&args[0], &option))
+ 				return -EINVAL;
+-		}
+-		if (!strcmp(curopt, "listmode")) {
+-			if (!value || !value[0])
++			devmode = option & S_IRWXUGO;
++			break;
++		case Opt_busuid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			busuid = option;
++			break;
++		case Opt_busgid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			busgid = option;
++			break;
++		case Opt_busmode:
++			if (match_octal(&args[0], &option))
+ 				return -EINVAL;
+-			listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+-			if (*value)
++			busmode = option & S_IRWXUGO;
++			break;
++		case Opt_listuid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			listuid = option;
++			break;
++		case Opt_listgid:
++			if (match_int(&args[0], &option))
++			       return -EINVAL;
++			listgid = option;
++			break;
++		case Opt_listmode:
++			if (match_octal(&args[0], &option))
+ 				return -EINVAL;
++			listmode = option & S_IRWXUGO;
++			break;
++		default:
++			err("usbfs: unrecognised mount option \"%s\" "
++			    "or missing value\n", p);
++			return -EINVAL;
+ 		}
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-
+-/* --------------------------------------------------------------------- */
+-
+ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev)
+ {
+ 	struct inode *inode = new_inode(sb);
+--- linux-2.6.0-test6/drivers/usb/host/uhci-debug.c	2003-07-02 14:53:16.000000000 -0700
++++ 25/drivers/usb/host/uhci-debug.c	2003-10-05 00:33:24.000000000 -0700
+@@ -99,82 +99,6 @@ static int uhci_show_td(struct uhci_td *
+ 	return out - buf;
+ }
+ 
+-static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
+-{
+-	char *out = buf;
+-
+-	/* Try to make sure there's enough memory */
+-	if (len < 80)
+-		return 0;
+-
+-	out += sprintf(out, "  stat%d     =     %04x   %s%s%s%s%s%s%s%s\n",
+-		port,
+-		status,
+-		(status & USBPORTSC_SUSP) ? "PortSuspend " : "",
+-		(status & USBPORTSC_PR) ?   "PortReset " : "",
+-		(status & USBPORTSC_LSDA) ? "LowSpeed " : "",
+-		(status & USBPORTSC_RD) ?   "ResumeDetect " : "",
+-		(status & USBPORTSC_PEC) ?  "EnableChange " : "",
+-		(status & USBPORTSC_PE) ?   "PortEnabled " : "",
+-		(status & USBPORTSC_CSC) ?  "ConnectChange " : "",
+-		(status & USBPORTSC_CCS) ?  "PortConnected " : "");
+-
+-	return out - buf;
+-}
+-
+-static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
+-{
+-	char *out = buf;
+-	unsigned int io_addr = uhci->io_addr;
+-	unsigned short usbcmd, usbstat, usbint, usbfrnum;
+-	unsigned int flbaseadd;
+-	unsigned char sof;
+-	unsigned short portsc1, portsc2;
+-
+-	/* Try to make sure there's enough memory */
+-	if (len < 80 * 6)
+-		return 0;
+-
+-	usbcmd    = inw(io_addr + 0);
+-	usbstat   = inw(io_addr + 2);
+-	usbint    = inw(io_addr + 4);
+-	usbfrnum  = inw(io_addr + 6);
+-	flbaseadd = inl(io_addr + 8);
+-	sof       = inb(io_addr + 12);
+-	portsc1   = inw(io_addr + 16);
+-	portsc2   = inw(io_addr + 18);
+-
+-	out += sprintf(out, "  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
+-		usbcmd,
+-		(usbcmd & USBCMD_MAXP) ?    "Maxp64 " : "Maxp32 ",
+-		(usbcmd & USBCMD_CF) ?      "CF " : "",
+-		(usbcmd & USBCMD_SWDBG) ?   "SWDBG " : "",
+-		(usbcmd & USBCMD_FGR) ?     "FGR " : "",
+-		(usbcmd & USBCMD_EGSM) ?    "EGSM " : "",
+-		(usbcmd & USBCMD_GRESET) ?  "GRESET " : "",
+-		(usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
+-		(usbcmd & USBCMD_RS) ?      "RS " : "");
+-
+-	out += sprintf(out, "  usbstat   =     %04x   %s%s%s%s%s%s\n",
+-		usbstat,
+-		(usbstat & USBSTS_HCH) ?    "HCHalted " : "",
+-		(usbstat & USBSTS_HCPE) ?   "HostControllerProcessError " : "",
+-		(usbstat & USBSTS_HSE) ?    "HostSystemError " : "",
+-		(usbstat & USBSTS_RD) ?     "ResumeDetect " : "",
+-		(usbstat & USBSTS_ERROR) ?  "USBError " : "",
+-		(usbstat & USBSTS_USBINT) ? "USBINT " : "");
+-
+-	out += sprintf(out, "  usbint    =     %04x\n", usbint);
+-	out += sprintf(out, "  usbfrnum  =   (%d)%03x\n", (usbfrnum >> 10) & 1,
+-		0xfff & (4*(unsigned int)usbfrnum));
+-	out += sprintf(out, "  flbaseadd = %08x\n", flbaseadd);
+-	out += sprintf(out, "  sof       =       %02x\n", sof);
+-	out += uhci_show_sc(1, portsc1, out, len - (out - buf));
+-	out += uhci_show_sc(2, portsc2, out, len - (out - buf));
+-
+-	return out - buf;
+-}
+-
+ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
+ {
+ 	char *out = buf;
+@@ -274,6 +198,13 @@ out:
+ 	return out - buf;
+ }
+ 
++#define show_frame_num()	\
++	if (!shown) {		\
++	  shown = 1;		\
++	  out += sprintf(out, "- Frame %d\n", i); \
++	}
++
++#ifdef CONFIG_PROC_FS
+ static const char *qh_names[] = {
+   "skel_int128_qh", "skel_int64_qh",
+   "skel_int32_qh", "skel_int16_qh",
+@@ -283,18 +214,88 @@ static const char *qh_names[] = {
+   "skel_bulk_qh", "skel_term_qh"
+ };
+ 
+-#define show_frame_num()	\
+-	if (!shown) {		\
+-	  shown = 1;		\
+-	  out += sprintf(out, "- Frame %d\n", i); \
+-	}
+-
+ #define show_qh_name()		\
+ 	if (!shown) {		\
+ 	  shown = 1;		\
+ 	  out += sprintf(out, "- %s\n", qh_names[i]); \
+ 	}
+ 
++static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
++{
++	char *out = buf;
++
++	/* Try to make sure there's enough memory */
++	if (len < 80)
++		return 0;
++
++	out += sprintf(out, "  stat%d     =     %04x   %s%s%s%s%s%s%s%s\n",
++		port,
++		status,
++		(status & USBPORTSC_SUSP) ? "PortSuspend " : "",
++		(status & USBPORTSC_PR) ?   "PortReset " : "",
++		(status & USBPORTSC_LSDA) ? "LowSpeed " : "",
++		(status & USBPORTSC_RD) ?   "ResumeDetect " : "",
++		(status & USBPORTSC_PEC) ?  "EnableChange " : "",
++		(status & USBPORTSC_PE) ?   "PortEnabled " : "",
++		(status & USBPORTSC_CSC) ?  "ConnectChange " : "",
++		(status & USBPORTSC_CCS) ?  "PortConnected " : "");
++
++	return out - buf;
++}
++
++static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
++{
++	char *out = buf;
++	unsigned int io_addr = uhci->io_addr;
++	unsigned short usbcmd, usbstat, usbint, usbfrnum;
++	unsigned int flbaseadd;
++	unsigned char sof;
++	unsigned short portsc1, portsc2;
++
++	/* Try to make sure there's enough memory */
++	if (len < 80 * 6)
++		return 0;
++
++	usbcmd    = inw(io_addr + 0);
++	usbstat   = inw(io_addr + 2);
++	usbint    = inw(io_addr + 4);
++	usbfrnum  = inw(io_addr + 6);
++	flbaseadd = inl(io_addr + 8);
++	sof       = inb(io_addr + 12);
++	portsc1   = inw(io_addr + 16);
++	portsc2   = inw(io_addr + 18);
++
++	out += sprintf(out, "  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
++		usbcmd,
++		(usbcmd & USBCMD_MAXP) ?    "Maxp64 " : "Maxp32 ",
++		(usbcmd & USBCMD_CF) ?      "CF " : "",
++		(usbcmd & USBCMD_SWDBG) ?   "SWDBG " : "",
++		(usbcmd & USBCMD_FGR) ?     "FGR " : "",
++		(usbcmd & USBCMD_EGSM) ?    "EGSM " : "",
++		(usbcmd & USBCMD_GRESET) ?  "GRESET " : "",
++		(usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
++		(usbcmd & USBCMD_RS) ?      "RS " : "");
++
++	out += sprintf(out, "  usbstat   =     %04x   %s%s%s%s%s%s\n",
++		usbstat,
++		(usbstat & USBSTS_HCH) ?    "HCHalted " : "",
++		(usbstat & USBSTS_HCPE) ?   "HostControllerProcessError " : "",
++		(usbstat & USBSTS_HSE) ?    "HostSystemError " : "",
++		(usbstat & USBSTS_RD) ?     "ResumeDetect " : "",
++		(usbstat & USBSTS_ERROR) ?  "USBError " : "",
++		(usbstat & USBSTS_USBINT) ? "USBINT " : "");
++
++	out += sprintf(out, "  usbint    =     %04x\n", usbint);
++	out += sprintf(out, "  usbfrnum  =   (%d)%03x\n", (usbfrnum >> 10) & 1,
++		0xfff & (4*(unsigned int)usbfrnum));
++	out += sprintf(out, "  flbaseadd = %08x\n", flbaseadd);
++	out += sprintf(out, "  sof       =       %02x\n", sof);
++	out += uhci_show_sc(1, portsc1, out, len - (out - buf));
++	out += uhci_show_sc(2, portsc2, out, len - (out - buf));
++
++	return out - buf;
++}
++
+ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *buf, int len)
+ {
+ 	struct list_head *tmp;
+@@ -512,7 +513,6 @@ static int uhci_sprint_schedule(struct u
+ 	return out - buf;
+ }
+ 
+-#ifdef CONFIG_PROC_FS
+ #define MAX_OUTPUT	(64 * 1024)
+ 
+ static struct proc_dir_entry *uhci_proc_root = NULL;
+--- linux-2.6.0-test6/drivers/usb/host/uhci-hcd.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/host/uhci-hcd.c	2003-10-05 00:33:24.000000000 -0700
+@@ -2185,8 +2185,8 @@ static int uhci_reset(struct usb_hcd *hc
+ 	/* Maybe kick BIOS off this hardware.  Then reset, so we won't get
+ 	 * interrupts from any previous setup.
+ 	 */
+-	pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
+ 	reset_hc(uhci);
++	pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/drivers/usb/input/Kconfig	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/input/Kconfig	2003-10-05 00:33:24.000000000 -0700
+@@ -186,8 +186,5 @@ config USB_XPAD
+ 	  For information about how to connect the X-Box pad to USB, see
+ 	  Documentation/input/xpad.txt.
+ 
+-	  This driver is also available as a module ( = code which can be
+-	  inserted in and removed from the running kernel whenever you want).
+-	  The module will be called xpad.  If you want to compile it as a
+-	  module, say M here and read <file:Documentation/modules.txt>.
+-
++	  To compile this driver as a module, choose M here: the
++	  module will be called xpad.
+--- linux-2.6.0-test6/drivers/usb/misc/brlvger.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/misc/brlvger.c	2003-10-05 00:33:24.000000000 -0700
+@@ -591,14 +591,14 @@ brlvger_write(struct file *file, const c
+ 			int firstpart = 6 - off;
+ 			
+ #ifdef WRITE_DEBUG
+-			dbg3("off: %d, rs: %d, count: %d, firstpart: %d",
++			dbg3("off: %lld, rs: %d, count: %d, firstpart: %d",
+ 			     off, rs, count, firstpart);
+ #endif
+ 
+ 			firstpart = (firstpart < count) ? firstpart : count;
+ 
+ #ifdef WRITE_DEBUG
+-			dbg3("off: %d", off);
++			dbg3("off: %lld", off);
+ 			dbg3("firstpart: %d", firstpart);
+ #endif
+ 
+@@ -618,7 +618,7 @@ brlvger_write(struct file *file, const c
+ 			off +=2;
+ 
+ #ifdef WRITE_DEBUG
+-			dbg3("off: %d, rs: %d, count: %d, firstpart: %d, "
++			dbg3("off: %lld, rs: %d, count: %d, firstpart: %d, "
+ 				"written: %d", 	off, rs, count, firstpart, written);
+ #endif
+ 		}
+--- linux-2.6.0-test6/drivers/usb/misc/speedtch.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/misc/speedtch.c	2003-10-05 00:33:24.000000000 -0700
+@@ -189,8 +189,7 @@ struct udsl_vcc_data {
+ 	struct atm_vcc *vcc;
+ 
+ 	/* raw cell reassembly */
+-	struct sk_buff *skb;
+-	unsigned int max_pdu;
++	struct sk_buff *sarb;
+ };
+ 
+ /* send */
+@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct u
+ {
+ 	struct udsl_vcc_data *cached_vcc = NULL;
+ 	struct atm_vcc *vcc;
+-	struct sk_buff *skb;
++	struct sk_buff *sarb;
+ 	struct udsl_vcc_data *vcc_data;
+ 	int cached_vci = 0;
+ 	unsigned int i;
+-	unsigned int length;
+-	unsigned int pdu_length;
+ 	int pti;
+ 	int vci;
+ 	short cached_vpi = 0;
+@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct u
+ 		}
+ 
+ 		vcc = vcc_data->vcc;
++		sarb = vcc_data->sarb;
+ 
+-		if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
+-			dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc);
+-			if (pti)
+-				atomic_inc (&vcc->stats->rx_err);
+-			continue;
+-		}
+-
+-		skb = vcc_data->skb;
+-
+-		if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
+-			dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
++		if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
++			dbg ("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
+ 			/* discard cells already received */
+-			skb_trim (skb, 0);
+-			DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
++			skb_trim (sarb, 0);
+ 		}
+ 
+-		memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+-		__skb_put (skb, ATM_CELL_PAYLOAD);
++		memcpy (sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
++		__skb_put (sarb, ATM_CELL_PAYLOAD);
+ 
+ 		if (pti) {
++			struct sk_buff *skb;
++			unsigned int length;
++			unsigned int pdu_length;
++
+ 			length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
+ 
+ 			/* guard against overflow */
+ 			if (length > ATM_MAX_AAL5_PDU) {
+-				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
+-				goto drop;
++				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
++				atomic_inc (&vcc->stats->rx_err);
++				goto out;
+ 			}
+ 
+ 			pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
+ 
+-			if (skb->len < pdu_length) {
+-				dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
+-				goto drop;
++			if (sarb->len < pdu_length) {
++				dbg ("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
++				atomic_inc (&vcc->stats->rx_err);
++				goto out;
+ 			}
+ 
+-			if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+-				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
+-				goto drop;
++			if (crc32_be (~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
++				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
++				atomic_inc (&vcc->stats->rx_err);
++				goto out;
+ 			}
+ 
+-			if (!atm_charge (vcc, skb->truesize)) {
+-				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
+-				goto drop_no_stats; /* atm_charge increments rx_drop */
+-			}
++			vdbg ("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
+ 
+-			/* now that we are sure to send the skb, it is ok to change skb->data */
+-			if (skb->len > pdu_length)
+-				skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
++			if (!(skb = dev_alloc_skb (length))) {
++				dbg ("udsl_extract_cells: no memory for skb (length: %u)!", length);
++				atomic_inc (&vcc->stats->rx_drop);
++				goto out;
++			}
+ 
+-			skb_trim (skb, length); /* drop zero padding and trailer */
++			vdbg ("udsl_extract_cells: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", skb, skb->truesize);
+ 
+-			atomic_inc (&vcc->stats->rx);
++			if (!atm_charge (vcc, skb->truesize)) {
++				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)!", skb->truesize);
++				dev_kfree_skb (skb);
++				goto out; /* atm_charge increments rx_drop */
++			}
+ 
+-			PACKETDEBUG (skb->data, skb->len);
++			memcpy (skb->data, sarb->tail - pdu_length, length);
++			__skb_put (skb, length);
+ 
+ 			vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
+ 
+-			vcc->push (vcc, skb);
+-
+-			vcc_data->skb = NULL;
++			PACKETDEBUG (skb->data, skb->len);
+ 
+-			continue;
++			vcc->push (vcc, skb);
+ 
+-drop:
+-			atomic_inc (&vcc->stats->rx_err);
+-drop_no_stats:
+-			skb_trim (skb, 0);
++			atomic_inc (&vcc->stats->rx);
++out:
++			skb_trim (sarb, 0);
+ 		}
+ 	}
+ }
+@@ -871,6 +867,7 @@ static int udsl_atm_open (struct atm_vcc
+ {
+ 	struct udsl_instance_data *instance = vcc->dev->dev_data;
+ 	struct udsl_vcc_data *new;
++	unsigned int max_pdu;
+ 
+ 	dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
+ 
+@@ -883,8 +880,10 @@ static int udsl_atm_open (struct atm_vcc
+ 		return -EINVAL;
+ 
+ 	/* only support AAL5 */
+-	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU))
++	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
++		dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
+ 		return -EINVAL;
++	}
+ 
+ 	if (!instance->firmware_loaded) {
+ 		dbg ("udsl_atm_open: firmware not loaded!");
+@@ -894,11 +893,13 @@ static int udsl_atm_open (struct atm_vcc
+ 	down (&instance->serialize); /* vs self, udsl_atm_close */
+ 
+ 	if (udsl_find_vcc (instance, vpi, vci)) {
++		dbg ("udsl_atm_open: %hd/%d already in use!", vpi, vci);
+ 		up (&instance->serialize);
+ 		return -EADDRINUSE;
+ 	}
+ 
+ 	if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
++		dbg ("udsl_atm_open: no memory for vcc_data!");
+ 		up (&instance->serialize);
+ 		return -ENOMEM;
+ 	}
+@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc
+ 	new->vcc = vcc;
+ 	new->vpi = vpi;
+ 	new->vci = vci;
+-	new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
++
++	/* udsl_extract_cells requires at least one cell */
++	max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
++	if (!(new->sarb = alloc_skb (max_pdu, GFP_KERNEL))) {
++		dbg ("udsl_atm_open: no memory for SAR buffer!");
++	        kfree (new);
++		up (&instance->serialize);
++		return -ENOMEM;
++	}
+ 
+ 	vcc->dev_data = new;
+ 	vcc->vpi = vpi;
+@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc
+ 
+ 	tasklet_schedule (&instance->receive_tasklet);
+ 
+-	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu);
++	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);
+ 
+ 	return 0;
+ }
+@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_v
+ 	list_del (&vcc_data->list);
+ 	tasklet_enable (&instance->receive_tasklet);
+ 
+-	if (vcc_data->skb)
+-		dev_kfree_skb (vcc_data->skb);
+-	vcc_data->skb = NULL;
++	kfree_skb (vcc_data->sarb);
++	vcc_data->sarb = NULL;
+ 
+ 	kfree (vcc_data);
+ 	vcc->dev_data = NULL;
+@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct 
+ 
+ 	for (i = 0; i < num_rcv_urbs; i++)
+ 		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
+-			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
++			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d!", i, result);
+ 
+ 	/* wait for completion handlers to finish */
+ 	do {
+@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct 
+ 
+ 	for (i = 0; i < num_snd_urbs; i++)
+ 		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
+-			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
++			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d!", i, result);
+ 
+ 	/* wait for completion handlers to finish */
+ 	do {
+@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct 
+ 
+ static int __init udsl_usb_init (void)
+ {
+-	struct sk_buff *skb; /* dummy for sizeof */
+-
+ 	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
+ 
+-	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
++	if (sizeof (struct udsl_control) > sizeof (((struct sk_buff *)0)->cb)) {
+ 		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
+ 		return -EIO;
+ 	}
+--- linux-2.6.0-test6/drivers/usb/serial/keyspan.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/serial/keyspan.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,6 +28,9 @@
+ 
+   Change History
+ 
++    2003sep04	LPM (Keyspan) add support for new single port product USA19HS.
++				Improve setup message handling for all devices.
++
+     Wed Feb 19 22:00:00 PST 2003 (Jeffrey S. Laing <keyspan@jsl.com>)
+       Merged the current (1/31/03) Keyspan code with the current (2.4.21-pre4)
+       Linux source tree.  The Linux tree lacked support for the 49WLC and
+@@ -172,6 +175,7 @@ struct keyspan_port_private {
+ 	int		baud;
+ 	int		old_baud;
+ 	unsigned int	cflag;
++	unsigned int	old_cflag;
+ 	enum		{flow_none, flow_cts, flow_xon} flow_control;
+ 	int		rts_state;	/* Handshaking pins (outputs) */
+ 	int		dtr_state;
+@@ -187,11 +191,12 @@ struct keyspan_port_private {
+ 
+ 	
+ /* Include Keyspan message headers.  All current Keyspan Adapters
+-   make use of one of three message formats which are referred
+-   to as USA-26, USA-28 and USA-49 by Keyspan and within this driver. */
++   make use of one of four message formats which are referred
++   to as USA-26, USA-28 and USA-49, USA-90 by Keyspan and within this driver. */
+ #include "keyspan_usa26msg.h"
+ #include "keyspan_usa28msg.h"
+ #include "keyspan_usa49msg.h"
++#include "keyspan_usa90msg.h"
+ 	
+ 
+ /* Functions used by new usb-serial code. */
+@@ -346,8 +351,8 @@ static int keyspan_ioctl(struct usb_seri
+ 	return -ENOIOCTLCMD;
+ }
+ 
+-	/* Write function is generic for the three protocols used
+-	   with only a minor change for usa49 required */
++	/* Write function is similar for the four protocols used
++	   with only a minor change for usa90 (usa19hs) required */
+ static int keyspan_write(struct usb_serial_port *port, int from_user, 
+ 			 const unsigned char *buf, int count)
+ {
+@@ -356,18 +361,26 @@ static int keyspan_write(struct usb_seri
+ 	int				flip;
+ 	int 				left, todo;
+ 	struct urb			*this_urb;
+-	int 				err;
++ 	int 				err, maxDataLen, dataOffset;
+ 
+ 	p_priv = usb_get_serial_port_data(port);
+ 	d_details = p_priv->device_details;
+ 
++	if (d_details->msg_format == msg_usa90) {
++   		maxDataLen = 64;
++		dataOffset = 0;
++	} else {
++		maxDataLen = 63;
++		dataOffset = 1;
++	}
++	
+ 	dbg("%s - for port %d (%d chars), flip=%d",
+ 	    __FUNCTION__, port->number, count, p_priv->out_flip);
+ 
+ 	for (left = count; left > 0; left -= todo) {
+ 		todo = left;
+-		if (todo > 63)
+-			todo = 63;
++		if (todo > maxDataLen)
++			todo = maxDataLen;
+ 
+ 		flip = p_priv->out_flip;
+ 	
+@@ -390,20 +403,20 @@ static int keyspan_write(struct usb_seri
+ 			break;
+ 		}
+ 
+-		/* First byte in buffer is "last flag" - unused so
++		/* First byte in buffer is "last flag" (except for usa19hx) - unused so
+ 		   for now so set to zero */
+ 		((char *)this_urb->transfer_buffer)[0] = 0;
+ 
+ 		if (from_user) {
+-			if (copy_from_user(this_urb->transfer_buffer + 1, buf, todo))
++			if (copy_from_user(this_urb->transfer_buffer + dataOffset, buf, todo))
+ 				return -EFAULT;
+ 		} else {
+-			memcpy (this_urb->transfer_buffer + 1, buf, todo);
++			memcpy (this_urb->transfer_buffer + dataOffset, buf, todo);
+ 		}
+ 		buf += todo;
+ 
+ 		/* send the data out the bulk port */
+-		this_urb->transfer_buffer_length = todo + 1;
++		this_urb->transfer_buffer_length = todo + dataOffset;
+ 
+ 		this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+ 		this_urb->dev = port->serial->dev;
+@@ -443,9 +456,12 @@ static void	usa26_indat_callback(struct 
+ 	if (urb->actual_length) {
+ 		/* 0x80 bit is error flag */
+ 		if ((data[0] & 0x80) == 0) {
+-			/* no error on any byte */
++			/* no errors on individual bytes, only possible overrun err*/
++			if (data[0] & RXERROR_OVERRUN)
++					err = TTY_OVERRUN;
++			else err = 0;
+ 			for (i = 1; i < urb->actual_length ; ++i) {
+-				tty_insert_flip_char(tty, data[i], 0);
++				tty_insert_flip_char(tty, data[i], err);
+ 			}
+ 		} else {
+ 			/* some bytes had errors, every byte has status */
+@@ -474,7 +490,7 @@ static void	usa26_indat_callback(struct 
+ 	return;
+ }
+ 
+-	/* Outdat handling is common for usa26, usa28 and usa49 messages */
++ 	/* Outdat handling is common for all devices */
+ static void	usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs)
+ {
+ 	struct usb_serial_port *port;
+@@ -577,7 +593,7 @@ static void	usa26_glocont_callback(struc
+ }
+ 
+ 
+-static void     usa28_indat_callback(struct urb *urb, struct pt_regs *regs)
++static void usa28_indat_callback(struct urb *urb, struct pt_regs *regs)
+ {
+ 	int                     i, err;
+ 	struct usb_serial_port  *port;
+@@ -861,29 +877,172 @@ static void	usa49_outcont_callback(struc
+ 	dbg ("%s", __FUNCTION__);
+ }
+ 
++static void	usa90_indat_callback(struct urb *urb, struct pt_regs *regs)
++{
++	int			i, err;
++	int			endpoint;
++	struct usb_serial_port	*port;
++	struct keyspan_port_private	 	*p_priv;
++	struct tty_struct	*tty;
++	unsigned char 		*data = urb->transfer_buffer;
++
++	dbg ("%s", __FUNCTION__); 
++
++	endpoint = usb_pipeendpoint(urb->pipe);
++
++
++	if (urb->status) {
++		dbg("%s - nonzero status: %x on endpoint %d.",
++		    __FUNCTION__, urb->status, endpoint);
++		return;
++	}
++
++	port = (struct usb_serial_port *) urb->context;
++	p_priv = usb_get_serial_port_data(port);
++
++	tty = port->tty;
++	if (urb->actual_length) {
++	
++		/* if current mode is DMA, looks like usa28 format
++	   		otherwise looks like usa26 data format */
++
++		if (p_priv->baud > 57600) {
++			for (i = 0; i < urb->actual_length ; ++i) 
++				tty_insert_flip_char(tty, data[i], 0);
++		}
++		else {
++			
++			/* 0x80 bit is error flag */
++			if ((data[0] & 0x80) == 0) {
++				/* no errors on individual bytes, only possible overrun err*/
++				if (data[0] & RXERROR_OVERRUN)
++						err = TTY_OVERRUN;
++				else err = 0;
++				for (i = 1; i < urb->actual_length ; ++i) 
++					tty_insert_flip_char(tty, data[i], err);
++			
++			} 
++			else {
++			/* some bytes had errors, every byte has status */
++				dbg("%s - RX error!!!!", __FUNCTION__);
++				for (i = 0; i + 1 < urb->actual_length; i += 2) {
++					int stat = data[i], flag = 0;
++					if (stat & RXERROR_OVERRUN)
++						flag |= TTY_OVERRUN;
++					if (stat & RXERROR_FRAMING)
++						flag |= TTY_FRAME;
++					if (stat & RXERROR_PARITY)
++						flag |= TTY_PARITY;
++					/* XXX should handle break (0x10) */
++					tty_insert_flip_char(tty, data[i+1], flag);
++				}
++			}
++		}
++		tty_flip_buffer_push(tty);
++	}
++				
++	/* Resubmit urb so we continue receiving */
++	urb->dev = port->serial->dev;
++	if (port->open_count)
++		if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
++			dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
++		}
++	return;
++}
++
++
++static void	usa90_instat_callback(struct urb *urb, struct pt_regs *regs)
++{
++	unsigned char 				*data = urb->transfer_buffer;
++	struct keyspan_usa90_portStatusMessage	*msg;
++	struct usb_serial			*serial;
++	struct usb_serial_port			*port;
++	struct keyspan_port_private	 	*p_priv;
++	int old_dcd_state, err;
++
++	serial = (struct usb_serial *) urb->context;
++
++	if (urb->status) {
++		dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
++		return;
++	}
++	if (urb->actual_length < 14) {
++		dbg("%s - %d byte report??", __FUNCTION__, urb->actual_length);
++		goto exit;
++	}
++
++	msg = (struct keyspan_usa90_portStatusMessage *)data;
++
++	/* Now do something useful with the data */
++
++	port = serial->port[0];
++	p_priv = usb_get_serial_port_data(port);
++	
++	/* Update handshaking pin state information */
++	old_dcd_state = p_priv->dcd_state;
++	p_priv->cts_state = ((msg->cts) ? 1 : 0);
++	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
++	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
++	p_priv->ri_state = ((msg->ri) ? 1 : 0);
++
++	if (port->tty && !C_CLOCAL(port->tty)
++	    && old_dcd_state != p_priv->dcd_state) {
++		if (old_dcd_state)
++			tty_hangup(port->tty);
++		/*  else */
++		/*	wake_up_interruptible(&p_priv->open_wait); */
++	}
++	
++	/* Resubmit urb so we continue receiving */
++	urb->dev = serial->dev;
++	if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
++		dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
++	}
++exit:
++	;
++}
++
++static void	usa90_outcont_callback(struct urb *urb, struct pt_regs *regs)
++{
++	struct usb_serial_port *port;
++	struct keyspan_port_private *p_priv;
++
++	port = (struct usb_serial_port *) urb->context;
++	p_priv = usb_get_serial_port_data(port);
+ 
++	if (p_priv->resend_cont) {
++		dbg ("%s - sending setup", __FUNCTION__); 
++		keyspan_usa90_send_setup(port->serial, port, p_priv->resend_cont - 1);
++	}
++}
+ 
+ static int keyspan_write_room (struct usb_serial_port *port)
+ {
+ 	struct keyspan_port_private	*p_priv;
+ 	const struct keyspan_device_details	*d_details;
+ 	int				flip;
++	int				data_len;
+ 	struct urb			*this_urb;
+ 
+ 	dbg("%s", __FUNCTION__);
+ 	p_priv = usb_get_serial_port_data(port);
+ 	d_details = p_priv->device_details;
+ 
++	if (d_details->msg_format == msg_usa90)
++   		data_len = 64;
++	else
++		data_len = 63;
++
+ 	flip = p_priv->out_flip;
+ 
+ 	/* Check both endpoints to see if any are available. */
+ 	if ((this_urb = p_priv->out_urbs[flip]) != 0) {
+ 		if (this_urb->status != -EINPROGRESS)
+-			return (63);
++			return (data_len);
+ 		flip = (flip + 1) & d_details->outdat_endp_flip;        
+ 		if ((this_urb = p_priv->out_urbs[flip]) != 0) 
+ 			if (this_urb->status != -EINPROGRESS)
+-				return (63);
++				return (data_len);
+ 	}
+ 	return (0);
+ }
+@@ -902,17 +1061,24 @@ static int keyspan_open (struct usb_seri
+ 	struct usb_serial 		*serial = port->serial;
+ 	const struct keyspan_device_details	*d_details;
+ 	int				i, err;
++	int				baud_rate, device_port;
+ 	struct urb			*urb;
++	unsigned int			cflag;
+ 
+ 	s_priv = usb_get_serial_data(serial);
+ 	p_priv = usb_get_serial_port_data(port);
+-	d_details = s_priv->device_details;
++	d_details = p_priv->device_details;
+ 	
+ 	dbg("%s - port%d.", __FUNCTION__, port->number); 
+ 
+ 	/* Set some sane defaults */
+ 	p_priv->rts_state = 1;
+ 	p_priv->dtr_state = 1;
++	p_priv->baud = 9600;
++
++	/* force baud and lcr to be set on open */
++	p_priv->old_baud = 0;
++	p_priv->old_cflag = 0;
+ 
+ 	p_priv->out_flip = 0;
+ 	p_priv->in_flip = 0;
+@@ -922,7 +1088,10 @@ static int keyspan_open (struct usb_seri
+ 		if ((urb = p_priv->in_urbs[i]) == NULL)
+ 			continue;
+ 		urb->dev = serial->dev;
+-		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0);
++
++		/* make sure endpoint data toggle is synchronized with the device */
++		
++		usb_clear_halt(urb->dev, urb->pipe);
+ 
+ 		if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
+ 			dbg("%s - submit urb %d failed (%d)", __FUNCTION__, i, err);
+@@ -937,12 +1106,29 @@ static int keyspan_open (struct usb_seri
+ 		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+ 	}
+ 
+-	// if the device is a USA49x, determine whether it is an W or WLC model
+-	// and set the baud clock accordingly
++	/* get the terminal config for the setup message now so we don't 
++	 * need to send 2 of them */
++
++	cflag = port->tty->termios->c_cflag;
++	device_port = port->number - port->serial->minor;
++
++	/* Baud rate calculation takes baud rate as an integer
++	   so other rates can be generated if desired. */
++	baud_rate = tty_get_baud_rate(port->tty);
++	/* If no match or invalid, leave as default */		
++	if (baud_rate >= 0
++	    && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
++				NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
++		p_priv->baud = baud_rate;
++	}
++
++	/* set CTS/RTS handshake etc. */
++	p_priv->cflag = cflag;
++	p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
+ 
+ 	keyspan_send_setup(port, 1);
+ 	//mdelay(100);
+-	keyspan_set_termios(port, NULL);
++	//keyspan_set_termios(port, NULL);
+ 
+ 	return (0);
+ }
+@@ -977,7 +1163,7 @@ static void keyspan_close(struct usb_ser
+ 		keyspan_send_setup(port, 2);
+ 		/* pilot-xfer seems to work best with this delay */
+ 		mdelay(100);
+-		keyspan_set_termios(port, NULL);
++		// keyspan_set_termios(port, NULL);
+ 	}
+ 
+ 	/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
+@@ -1172,6 +1358,14 @@ static struct callbacks {
+ 		.outdat_callback =	usa2x_outdat_callback,
+ 		.inack_callback =	usa49_inack_callback,
+ 		.outcont_callback =	usa49_outcont_callback,
++	}, {
++		/* msg_usa90 callbacks */
++		.instat_callback =	usa90_instat_callback,
++		.glocont_callback =	usa28_glocont_callback,		
++		.indat_callback =	usa90_indat_callback,
++		.outdat_callback =	usa2x_outdat_callback,
++		.inack_callback =	usa28_inack_callback,
++		.outcont_callback =	usa90_outcont_callback,
+ 	}
+ };
+ 
+@@ -1295,6 +1489,41 @@ static int keyspan_usa19_calc_baud(u32 b
+ 	return (KEYSPAN_BAUD_RATE_OK);
+ }
+ 
++/* usa19hs function doesn't require prescaler */
++static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
++				   u8 *rate_low, u8 *prescaler, int portnum)
++{
++	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
++			div;	/* divisor */	
++		
++	dbg ("%s - %d.", __FUNCTION__, baud_rate);
++
++		/* prevent divide by zero...  */
++	if( (b16 = (baud_rate * 16L)) == 0) 
++		return (KEYSPAN_INVALID_BAUD_RATE);
++	
++
++
++		/* calculate the divisor */
++	if( (div = (baudclk / b16)) == 0) 
++		return (KEYSPAN_INVALID_BAUD_RATE);
++
++	if(div > 0xffff) 
++		return (KEYSPAN_INVALID_BAUD_RATE);
++
++		/* return the counter values if non-null */
++	if (rate_low) 
++		*rate_low = (u8) (div & 0xff);
++	
++	if (rate_hi) 
++		*rate_hi = (u8) ((div >> 8) & 0xff);
++	
++	if (rate_low && rate_hi) 
++		dbg ("%s - %d %02x %02x.", __FUNCTION__, baud_rate, *rate_hi, *rate_low);
++	
++	return (KEYSPAN_BAUD_RATE_OK);
++}
++
+ static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
+ 				    u8 *rate_low, u8 *prescaler, int portnum)
+ {
+@@ -1447,6 +1676,7 @@ static int keyspan_usa26_send_setup(stru
+ 		p_priv->resend_cont = reset_port + 1;
+ 	if (this_urb->status == -EINPROGRESS) {
+ 		/*  dbg ("%s - already writing", __FUNCTION__); */
++		mdelay(5);
+ 		return(-1);
+ 	}
+ 
+@@ -1597,6 +1827,7 @@ static int keyspan_usa28_send_setup(stru
+ 		p_priv->resend_cont = reset_port + 1;
+ 	if (this_urb->status == -EINPROGRESS) {
+ 		dbg ("%s already writing", __FUNCTION__);
++		mdelay(5);
+ 		return(-1);
+ 	}
+ 
+@@ -1729,6 +1960,7 @@ static int keyspan_usa49_send_setup(stru
+ 		p_priv->resend_cont = reset_port + 1;
+ 	if (this_urb->status == -EINPROGRESS) {
+ 		/*  dbg ("%s - already writing", __FUNCTION__); */
++		mdelay(5);
+ 		return(-1);
+ 	}
+ 
+@@ -1857,6 +2089,144 @@ static int keyspan_usa49_send_setup(stru
+ 	return (0);
+ }
+ 
++static int keyspan_usa90_send_setup(struct usb_serial *serial,
++				    struct usb_serial_port *port,
++				    int reset_port)
++{
++	struct keyspan_usa90_portControlMessage	msg;		
++	struct keyspan_serial_private 		*s_priv;
++	struct keyspan_port_private 		*p_priv;
++	const struct keyspan_device_details	*d_details;
++	struct urb				*this_urb;
++	int 					err;
++	u8						prescaler;
++
++	dbg ("%s", __FUNCTION__);
++
++	s_priv = usb_get_serial_data(serial);
++	p_priv = usb_get_serial_port_data(port);
++	d_details = s_priv->device_details;
++
++	/* only do something if we have a bulk out endpoint */
++	if ((this_urb = p_priv->outcont_urb) == NULL) {
++		dbg("%s - oops no urb.", __FUNCTION__);
++		return -1;
++	}
++
++	/* Save reset port val for resend.
++	   Don't overwrite resend for open/close condition. */
++	if ((reset_port + 1) > p_priv->resend_cont)
++		p_priv->resend_cont = reset_port + 1;
++	if (this_urb->status == -EINPROGRESS) {
++		dbg ("%s already writing", __FUNCTION__);
++		mdelay(5);
++		return(-1);
++	}
++
++	memset(&msg, 0, sizeof (struct keyspan_usa90_portControlMessage));
++
++	/* Only set baud rate if it's changed */	
++	if (p_priv->old_baud != p_priv->baud) {
++		p_priv->old_baud = p_priv->baud;
++		msg.setClocking = 0x01;
++		if (d_details->calculate_baud_rate
++		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
++		     &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE ) {
++			dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__,
++			    p_priv->baud);
++			p_priv->baud = 9600;
++			d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, 
++				&msg.baudHi, &msg.baudLo, &prescaler, 0);
++		}
++		msg.setRxMode = 1;
++		msg.setTxMode = 1;
++	}
++
++	/* modes must always be correctly specified */
++	if (p_priv->baud > 57600)
++	{
++		msg.rxMode = RXMODE_DMA;
++		msg.txMode = TXMODE_DMA;
++	}
++	else
++	{
++		msg.rxMode = RXMODE_BYHAND;
++		msg.txMode = TXMODE_BYHAND;
++	}
++
++	msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1;
++	switch (p_priv->cflag & CSIZE) {
++	case CS5:
++		msg.lcr |= USA_DATABITS_5;
++		break;
++	case CS6:
++		msg.lcr |= USA_DATABITS_6;
++		break;
++	case CS7:
++		msg.lcr |= USA_DATABITS_7;
++		break;
++	case CS8:
++		msg.lcr |= USA_DATABITS_8;
++		break;
++	}
++	if (p_priv->cflag & PARENB) {
++		/* note USA_PARITY_NONE == 0 */
++		msg.lcr |= (p_priv->cflag & PARODD)?
++			USA_PARITY_ODD: USA_PARITY_EVEN;
++	}
++	if (p_priv->old_cflag != p_priv->cflag) {
++		p_priv->old_cflag = p_priv->cflag;
++		msg.setLcr = 0x01;
++	}
++
++	if (p_priv->flow_control == flow_cts)
++		msg.txFlowControl = TXFLOW_CTS;
++	msg.setTxFlowControl = 0x01;
++	msg.setRxFlowControl = 0x01;
++	
++	msg.rxForwardingLength = 16;
++	msg.rxForwardingTimeout = 16;	
++	msg.txAckSetting = 0;
++	msg.xonChar = 17;
++	msg.xoffChar = 19;
++
++	/* Opening port */ 
++	if (reset_port == 1) {
++		msg.portEnabled = 1;
++		msg.rxFlush = 1;
++		msg.txBreak = (p_priv->break_on);
++	}
++	/* Closing port */
++	else if (reset_port == 2) {
++		msg.portEnabled = 0;
++	}
++	/* Sending intermediate configs */
++	else {
++		if (port->open_count)
++			msg.portEnabled = 1;
++		msg.txBreak = (p_priv->break_on);
++	}
++
++	/* Do handshaking outputs */	
++	msg.setRts = 0x01;
++	msg.rts = p_priv->rts_state;
++
++	msg.setDtr = 0x01;
++	msg.dtr = p_priv->dtr_state;
++		
++	p_priv->resend_cont = 0;
++	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
++	
++	/* send the data out the device on control endpoint */
++	this_urb->transfer_buffer_length = sizeof(msg);
++
++	this_urb->dev = serial->dev;
++	if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
++		dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err);
++	}
++	return (0);
++}
++
+ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
+ {
+ 	struct usb_serial *serial = port->serial;
+@@ -1878,9 +2248,13 @@ static void keyspan_send_setup(struct us
+ 	case msg_usa49:
+ 		keyspan_usa49_send_setup(serial, port, reset_port);
+ 		break;
++	case msg_usa90:
++		keyspan_usa90_send_setup(serial, port, reset_port);
++		break;
+ 	}
+ }
+ 
++
+ /* Gets called by the "real" driver (ie once firmware is loaded
+    and renumeration has taken place. */
+ static int keyspan_startup (struct usb_serial *serial)
+--- linux-2.6.0-test6/drivers/usb/serial/keyspan.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/usb/serial/keyspan.h	2003-10-05 00:33:24.000000000 -0700
+@@ -82,6 +82,10 @@ static int  keyspan_usa28_calc_baud	(u32
+ 					 u8 *rate_hi, u8 *rate_low,
+ 					 u8 *prescaler, int portnum);
+ 
++static int  keyspan_usa19hs_calc_baud	(u32 baud_rate, u32 baudclk,
++					 u8 *rate_hi, u8 *rate_low,
++					 u8 *prescaler, int portnum);
++
+ static int  keyspan_usa28_send_setup	(struct usb_serial *serial,
+ 					 struct usb_serial_port *port,
+ 					 int reset_port);
+@@ -92,6 +96,9 @@ static int  keyspan_usa49_send_setup	(st
+ 					 struct usb_serial_port *port,
+ 					 int reset_port);
+ 
++static int  keyspan_usa90_send_setup	(struct usb_serial *serial,
++					 struct usb_serial_port *port,
++					 int reset_port);
+ 
+ /* Struct used for firmware - increased size of data section
+    to allow Keyspan's 'C' firmware struct to be used unmodified */
+@@ -183,6 +190,7 @@ struct ezusb_hex_record {
+ #define	KEYSPAN_USA18X_BAUDCLK			(12000000L)	/* a guess */
+ #define	KEYSPAN_USA19_BAUDCLK			(12000000L)
+ #define	KEYSPAN_USA19W_BAUDCLK			(24000000L)
++#define	KEYSPAN_USA19HS_BAUDCLK			(14769231L)
+ #define	KEYSPAN_USA28_BAUDCLK			(1843200L)
+ #define	KEYSPAN_USA28X_BAUDCLK			(12000000L)
+ #define	KEYSPAN_USA49W_BAUDCLK			(48000000L)
+@@ -215,6 +223,7 @@ struct ezusb_hex_record {
+ #define	keyspan_usa18x_product_id		0x0112
+ #define	keyspan_usa19_product_id		0x0107
+ #define	keyspan_usa19qi_product_id		0x010c
++#define	keyspan_usa19hs_product_id		0x0121
+ #define	keyspan_mpr_product_id			0x011c
+ #define	keyspan_usa19qw_product_id		0x0119
+ #define	keyspan_usa19w_product_id		0x0108
+@@ -230,7 +239,7 @@ struct keyspan_device_details {
+ 	/* product ID value */
+ 	int	product_id;
+ 
+-	enum	{msg_usa26, msg_usa28, msg_usa49} msg_format;
++	enum	{msg_usa26, msg_usa28, msg_usa49, msg_usa90} msg_format;
+ 
+ 		/* Number of physical ports */
+ 	int	num_ports;
+@@ -349,6 +358,22 @@ static const struct keyspan_device_detai
+ 	.baudclk		= KEYSPAN_USA19W_BAUDCLK,
+ };
+ 
++static const struct keyspan_device_details usa19hs_device_details = {
++	product_id:		keyspan_usa19hs_product_id,
++	msg_format:		msg_usa90,
++	num_ports:		1,
++	indat_endp_flip:	0,
++	outdat_endp_flip:	0,
++	indat_endpoints:	{0x81},
++	outdat_endpoints:	{0x01},
++	inack_endpoints:	{-1},
++	outcont_endpoints:	{0x02},
++	instat_endpoint:	0x82,
++	glocont_endpoint:	-1,
++	calculate_baud_rate:	keyspan_usa19hs_calc_baud,
++	baudclk:		KEYSPAN_USA19HS_BAUDCLK,
++};
++
+ static const struct keyspan_device_details usa28_device_details = {
+ 	.product_id		= keyspan_usa28_product_id,
+ 	.msg_format		= msg_usa28,
+@@ -437,6 +462,7 @@ static const struct keyspan_device_detai
+ 	&usa19qi_device_details,
+ 	&usa19qw_device_details,
+ 	&usa19w_device_details,
++	&usa19hs_device_details,
+ 	&usa28_device_details,
+ 	&usa28x_device_details,
+ 	&usa28xa_device_details,
+@@ -464,6 +490,7 @@ static struct usb_device_id keyspan_ids_
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
++	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) },
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) },
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
+ 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
+@@ -544,8 +571,8 @@ static struct usb_serial_device_type key
+ 	.short_name		= "keyspan_1",
+ 	.id_table		= keyspan_1port_ids,
+ 	.num_interrupt_in	= NUM_DONT_CARE,
+-	.num_bulk_in		= 3,
+-	.num_bulk_out		= 4,
++	.num_bulk_in		= NUM_DONT_CARE,
++	.num_bulk_out		= NUM_DONT_CARE,
+ 	.num_ports		= 1,
+ 	.open			= keyspan_open,
+ 	.close			= keyspan_close,
+--- linux-2.6.0-test6/drivers/usb/serial/keyspan_usa26msg.h	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/serial/keyspan_usa26msg.h	2003-10-05 00:33:24.000000000 -0700
+@@ -4,7 +4,7 @@
+ 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
+ 	This file is available under a BSD-style copyright
+ 
+-	Keyspan USB Async Firmware to run on Anchor EZ-USB
++	Keyspan USB Async Message Formats for the USA28X
+ 
+ 	Redistribution and use in source and binary forms, with or without
+ 	modification, are permitted provided that the following conditions are
+@@ -19,11 +19,7 @@
+ 
+         	This file is available under a BSD-style copyright
+ 
+-	2. Redistributions in binary form must reproduce the above copyright
+-   	notice, this list of conditions and the following disclaimer in the
+-   	documentation and/or other materials provided with the distribution.
+-
+-	3. The name of InnoSys Incorporated may not be used to endorse or promote
++	2. The name of InnoSys Incorporated may not be used to endorse or promote
+    	products derived from this software without specific prior written
+    	permission.
+ 
+--- linux-2.6.0-test6/drivers/usb/serial/keyspan_usa28msg.h	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/serial/keyspan_usa28msg.h	2003-10-05 00:33:24.000000000 -0700
+@@ -4,7 +4,7 @@
+ 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
+ 	This file is available under a BSD-style copyright
+ 
+-	Keyspan USB Async Firmware to run on Anchor EZ-USB
++	Keyspan USB Async Message Formats for the USA26X
+ 
+ 	Redistribution and use in source and binary forms, with or without
+ 	modification, are permitted provided that the following conditions are
+@@ -19,11 +19,7 @@
+ 
+         	This file is available under a BSD-style copyright
+ 
+-	2. Redistributions in binary form must reproduce the above copyright
+-   	notice, this list of conditions and the following disclaimer in the
+-   	documentation and/or other materials provided with the distribution.
+-
+-	3. The name of InnoSys Incorporated may not be used to endorse or promote
++	2. The name of InnoSys Incorporated may not be used to endorse or promote
+    	products derived from this software without specific prior written
+    	permission.
+ 
+--- linux-2.6.0-test6/drivers/usb/serial/keyspan_usa49msg.h	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/usb/serial/keyspan_usa49msg.h	2003-10-05 00:33:24.000000000 -0700
+@@ -4,7 +4,7 @@
+ 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
+ 	This file is available under a BSD-style copyright
+ 
+-	Keyspan USB Async Firmware to run on Anchor EZ-USB
++	Keyspan USB Async Message Formats for the USA49W
+ 
+ 	Redistribution and use in source and binary forms, with or without
+ 	modification, are permitted provided that the following conditions are
+@@ -19,11 +19,7 @@
+ 
+         	This file is available under a BSD-style copyright
+ 
+-	2. Redistributions in binary form must reproduce the above copyright
+-   	notice, this list of conditions and the following disclaimer in the
+-   	documentation and/or other materials provided with the distribution.
+-
+-	3. The name of InnoSys Incorporated may not be used to endorse or promote
++	2. The name of InnoSys Incorporated may not be used to endorse or promote
+    	products derived from this software without specific prior written
+    	permission.
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/usb/serial/keyspan_usa90msg.h	2003-10-05 00:33:24.000000000 -0700
+@@ -0,0 +1,198 @@
++/*
++	usa90msg.h
++
++	Copyright (c) 1998-2003 InnoSys Incorporated.  All Rights Reserved
++	This file is available under a BSD-style copyright
++
++	Keyspan USB Async Message Formats for the USA19HS
++
++	Redistribution and use in source and binary forms, with or without
++	modification, are permitted provided that the following conditions are
++	met:
++
++	1. Redistributions of source code must retain this licence text
++   	without modification, this list of conditions, and the following
++   	disclaimer.  The following copyright notice must appear immediately at
++   	the beginning of all source files:
++
++        	Copyright (c) 1998-2003 InnoSys Incorporated.  All Rights Reserved
++
++        	This file is available under a BSD-style copyright
++
++	2. The name of InnoSys Incorprated may not be used to endorse or promote
++   	products derived from this software without specific prior written
++   	permission.
++
++	THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
++	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++	NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++	INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
++	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++	OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++	SUCH DAMAGE.    
++
++	Revisions:
++
++	2003feb14		add setTxMode/txMode  and cancelRxXoff to portControl
++	2003mar21		change name of PARITY_0/1 to add MARK/SPACE
++*/
++
++#ifndef	__USA90MSG__
++#define	__USA90MSG__
++
++struct keyspan_usa90_portControlMessage
++{
++	/*
++		there are three types of "commands" sent in the control message:
++
++		1.	configuration changes which must be requested by setting
++			the corresponding "set" flag (and should only be requested
++			when necessary, to reduce overhead on the device):
++	*/
++
++	u8	setClocking,	// host requests baud rate be set
++		baudLo,			// host does baud divisor calculation
++		baudHi,			// host does baud divisor calculation 
++		
++		setLcr,			// host requests lcr be set
++		lcr,			// use PARITY, STOPBITS, DATABITS below
++		
++		setRxMode,		// set receive mode
++		rxMode,			// RXMODE_DMA or RXMODE_BYHAND
++
++		setTxMode,		// set transmit mode
++		txMode,			// TXMODE_DMA or TXMODE_BYHAND
++
++		setTxFlowControl,	// host requests tx flow control be set
++		txFlowControl	,	// use TX_FLOW... bits below
++		setRxFlowControl,	// host requests rx flow control be set
++		rxFlowControl,	// use RX_FLOW... bits below
++		sendXoff,		// host requests XOFF transmitted immediately
++		sendXon,		// host requests XON char transmitted
++		xonChar,		// specified in current character format
++		xoffChar,		// specified in current character format
++
++		sendChar,		// host requests char transmitted immediately
++		txChar,			// character to send
++
++		setRts,			// host requests RTS output be set
++		rts,			// 1=on, 0=off
++		setDtr, 		// host requests DTR output be set
++		dtr;			// 1=on, 0=off
++
++	
++	/*
++		2.	configuration data which is simply used as is 
++			and must be specified correctly in every host message.
++	*/
++
++	u8	rxForwardingLength,  // forward when this number of chars available
++		rxForwardingTimeout, // (1-31 in ms)
++		txAckSetting;	   // 0=don't ack, 1=normal, 2-255 TBD...
++	/*
++		3.	Firmware states which cause actions if they change					
++		and must be specified correctly in every host message.
++	*/
++
++	u8	portEnabled,	// 0=disabled, 1=enabled
++		txFlush,		// 0=normal, 1=toss outbound data
++		txBreak,		// 0=break off, 1=break on
++		loopbackMode;	// 0=no loopback, 1=loopback enabled
++
++	/*
++		4.	commands which are flags only; these are processed in order
++			(so that, e.g., if rxFlush and rxForward flags are set, the
++			port will have no data to forward); any non-zero value 
++			is respected
++	*/
++
++	u8	rxFlush,		// toss inbound data
++		rxForward,		// forward all inbound data, NOW (as if fwdLen==1)
++		cancelRxXoff,	// cancel any receive XOFF state (_txXoff)
++		returnStatus;	// return current status NOW
++};
++
++// defines for bits in lcr
++#define		USA_DATABITS_5		0x00
++#define		USA_DATABITS_6		0x01
++#define		USA_DATABITS_7		0x02
++#define		USA_DATABITS_8		0x03
++#define		STOPBITS_5678_1		0x00	// 1 stop bit for all byte sizes
++#define		STOPBITS_5_1p5		0x04	// 1.5 stop bits for 5-bit byte
++#define		STOPBITS_678_2		0x04	// 2 stop bits for 6-8 bit byte
++#define		USA_PARITY_NONE		0x00
++#define		USA_PARITY_ODD		0x08
++#define		USA_PARITY_EVEN		0x18
++#define		PARITY_MARK_1  		0x28   	// force parity MARK
++#define		PARITY_SPACE_0 		0x38	// force parity SPACE
++
++#define		TXFLOW_CTS			0x04	
++#define		TXFLOW_DSR			0x08
++#define		TXFLOW_XOFF			0x01	
++#define		TXFLOW_XOFF_ANY		0x02	
++#define		TXFLOW_XOFF_BITS	(TXFLOW_XOFF | TXFLOW_XOFF_ANY)
++
++#define		RXFLOW_XOFF			0x10	
++#define		RXFLOW_RTS			0x20	
++#define		RXFLOW_DTR			0x40
++#define		RXFLOW_DSR_SENSITIVITY	0x80
++
++#define		RXMODE_BYHAND		0x00	
++#define		RXMODE_DMA			0x02	
++
++#define		TXMODE_BYHAND		0x00	
++#define		TXMODE_DMA			0x02	
++
++
++// all things called "StatusMessage" are sent on the status endpoint
++
++struct keyspan_usa90_portStatusMessage	
++{
++	u8	msr,			// reports the actual MSR register
++		cts,			// reports CTS pin
++		dcd,			// reports DCD pin
++		dsr,			// reports DSR pin
++		ri,				// reports RI pin
++		_txXoff,		// port is in XOFF state (we received XOFF)
++		rxBreak,		// reports break state
++		rxOverrun,		// count of overrun errors (since last reported)
++		rxParity,		// count of parity errors (since last reported)
++		rxFrame,		// count of frame errors (since last reported)
++		portState,		// PORTSTATE_xxx bits (useful for debugging)
++		messageAck,		// message acknowledgement
++		charAck,		// character acknowledgement
++		controlResponse;	// (value = returnStatus) a control message has been processed 
++};
++
++// bits in RX data message when STAT byte is included
++
++#define	RXERROR_OVERRUN		0x02
++#define	RXERROR_PARITY		0x04
++#define	RXERROR_FRAMING		0x08
++#define	RXERROR_BREAK		0x10
++
++#define	PORTSTATE_ENABLED	0x80
++#define	PORTSTATE_TXFLUSH	0x01
++#define	PORTSTATE_TXBREAK	0x02
++#define	PORTSTATE_LOOPBACK 	0x04
++
++// MSR bits
++
++#define MSR_dCTS	  		0x01		// CTS has changed since last report	
++#define MSR_dDSR	  		0x02
++#define MSR_dRI				0x04
++#define MSR_dDCD	  		0x08
++
++#define MSR_CTS				0x10	  	// current state of CTS
++#define MSR_DSR				0x20
++#define MSR_RI				0x40
++#define MSR_DCD				0x80
++
++// ie: the maximum length of an endpoint buffer
++#define		MAX_DATA_LEN			64
++
++#endif
+--- linux-2.6.0-test6/drivers/usb/storage/freecom.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/drivers/usb/storage/freecom.c	2003-10-05 00:33:24.000000000 -0700
+@@ -101,7 +101,8 @@ struct freecom_status {
+ #define FCM_PACKET_IDE_READ	0xC0
+ 
+ /* All packets (except for status) are 64 bytes long. */
+-#define FCM_PACKET_LENGTH	64
++#define FCM_PACKET_LENGTH		64
++#define FCM_STATUS_PACKET_LENGTH	4
+ 
+ static int
+ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
+@@ -216,7 +217,7 @@ int freecom_transport(Scsi_Cmnd *srb, st
+ 	/* There are times we can optimize out this status read, but it
+ 	 * doesn't hurt us to always do it now. */
+ 	result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+-			FCM_PACKET_LENGTH, &partial);
++			FCM_STATUS_PACKET_LENGTH, &partial);
+ 	US_DEBUGP("foo Status result %d %u\n", result, partial);
+ 	if (result != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, st
+ 
+ 		/* get the data */
+ 		result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+-				FCM_PACKET_LENGTH, &partial);
++				FCM_STATUS_PACKET_LENGTH, &partial);
+ 
+ 		US_DEBUGP("bar Status result %d %u\n", result, partial);
+-		if (result > USB_STOR_XFER_SHORT)
++		if (result != USB_STOR_XFER_GOOD)
+ 			return USB_STOR_TRANSPORT_ERROR;
+ 
+ 		US_DEBUG(pdump ((void *) fst, partial));
+@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, st
+ 
+ 	switch (us->srb->sc_data_direction) {
+ 	case SCSI_DATA_READ:
++		/* catch bogus "read 0 length" case */
++		if (!length)
++			break;
+ 		/* Make sure that the status indicates that the device
+ 		 * wants data as well. */
+ 		if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
+@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, st
+ 		break;
+ 
+ 	case SCSI_DATA_WRITE:
++		/* catch bogus "write 0 length" case */
++		if (!length)
++			break;
+ 		/* Make sure the status indicates that the device wants to
+ 		 * send us data. */
+ 		/* !!IMPLEMENT!! */
+@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, st
+ 		break;
+ 
+ 	default:
++		/* should never hit here -- filtered in usb.c */
+ 		US_DEBUGP ("freecom unimplemented direction: %d\n",
+ 				us->srb->sc_data_direction);
+ 		// Return fail, SCSI seems to handle this better.
+--- linux-2.6.0-test6/drivers/usb/storage/unusual_devs.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/storage/unusual_devs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0
+ 		"Dimage F300",
+ 		US_SC_SCSI, US_PR_BULK, NULL, 0 ),
+ 
++/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
++UNUSUAL_DEV(  0x0686, 0x4017, 0x0001, 0x0001,
++                "Minolta",
++                "DIMAGE E223",
++                US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
++
+ UNUSUAL_DEV(  0x0693, 0x0002, 0x0100, 0x0100, 
+ 		"Hagiwara",
+ 		"FlashGate SmartMedia",
+@@ -542,7 +548,7 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0x
+  * - They don't like the INQUIRY command. So we must handle this command
+  *   of the SCSI layer ourselves.
+  */
+-UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
++UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x5009,
+ 		"Casio",
+ 		"QV DigitalCamera",
+ 		US_SC_8070, US_PR_CB, NULL,
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/video/asiliantfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -0,0 +1,619 @@
++/*
++ * drivers/video/asiliantfb.c
++ *  frame buffer driver for Asiliant 69000 chip
++ *  Copyright (C) 2001-2003 Saito.K & Jeanne
++ *
++ *  from driver/video/chipsfb.c and,
++ *
++ *  drivers/video/asiliantfb.c -- frame buffer device for
++ *  Asiliant 69030 chip (formerly Intel, formerly Chips & Technologies)
++ *  Author: apc@agelectronics.co.uk
++ *  Copyright (C) 2000 AG Electronics
++ *  Note: the data sheets don't seem to be available from Asiliant.
++ *  They are available by searching developer.intel.com, but are not otherwise
++ *  linked to.
++ *
++ *  This driver should be portable with minimal effort to the 69000 display
++ *  chip, and to the twin-display mode of the 69030.
++ *  Contains code from Thomas Hhenleitner <th@visuelle-maschinen.de> (thanks)
++ *
++ *  Derived from the CT65550 driver chipsfb.c:
++ *  Copyright (C) 1998 Paul Mackerras
++ *  ...which was derived from the Powermac "chips" driver:
++ *  Copyright (C) 1997 Fabio Riccardi.
++ *  And from the frame buffer device for Open Firmware-initialized devices:
++ *  Copyright (C) 1997 Geert Uytterhoeven.
++ *
++ *  This file is subject to the terms and conditions of the GNU General Public
++ *  License. See the file COPYING in the main directory of this archive for
++ *  more details.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++
++static struct fb_info asiliantfb_info;
++
++/* Built in clock of the 69030 */
++const unsigned Fref = 14318180;
++
++static u32 pseudo_palette[17];
++
++#define mmio_base (p->screen_base + 0x400000)
++
++#define mm_write_ind(num, val, ap, dp)	do { \
++	writeb((num), mmio_base + (ap)); writeb((val), mmio_base + (dp)); \
++} while (0)
++
++static void mm_write_xr(struct fb_info *p, u8 reg, u8 data)
++{
++	mm_write_ind(reg, data, 0x7ac, 0x7ad);
++}
++#define write_xr(num, val)	mm_write_xr(p, num, val)
++
++static void mm_write_fr(struct fb_info *p, u8 reg, u8 data)
++{
++	mm_write_ind(reg, data, 0x7a0, 0x7a1);
++}
++#define write_fr(num, val)	mm_write_fr(p, num, val)
++
++static void mm_write_cr(struct fb_info *p, u8 reg, u8 data)
++{
++	mm_write_ind(reg, data, 0x7a8, 0x7a9);
++}
++#define write_cr(num, val)	mm_write_cr(p, num, val)
++
++static void mm_write_gr(struct fb_info *p, u8 reg, u8 data)
++{
++	mm_write_ind(reg, data, 0x79c, 0x79d);
++}
++#define write_gr(num, val)	mm_write_gr(p, num, val)
++
++static void mm_write_sr(struct fb_info *p, u8 reg, u8 data)
++{
++	mm_write_ind(reg, data, 0x788, 0x789);
++}
++#define write_sr(num, val)	mm_write_sr(p, num, val)
++
++static void mm_write_ar(struct fb_info *p, u8 reg, u8 data)
++{
++	readb(mmio_base + 0x7b4);
++	mm_write_ind(reg, data, 0x780, 0x780);
++}
++#define write_ar(num, val)	mm_write_ar(p, num, val)
++
++/*
++ * Exported functions
++ */
++int asiliantfb_init(void);
++
++static int asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
++static int asiliantfb_check_var(struct fb_var_screeninfo *var,
++				struct fb_info *info);
++static int asiliantfb_set_par(struct fb_info *info);
++static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
++				u_int transp, struct fb_info *info);
++
++static struct fb_ops asiliantfb_ops = {
++	.owner		= THIS_MODULE,
++	.fb_check_var	= asiliantfb_check_var,
++	.fb_set_par	= asiliantfb_set_par,
++	.fb_setcolreg	= asiliantfb_setcolreg,
++	.fb_fillrect	= cfb_fillrect,
++	.fb_copyarea	= cfb_copyarea,
++	.fb_imageblit	= cfb_imageblit,
++	.fb_cursor	= soft_cursor,
++};
++
++/* Calculate the ratios for the dot clocks without using a single long long
++ * value */
++static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dclk2_div)
++{
++	unsigned pixclock = *ppixclock;
++	unsigned Ftarget = 1000000 * (1000000 / pixclock);
++	unsigned n;
++	unsigned best_error = 0xffffffff;
++	unsigned best_m = 0xffffffff,
++	         best_n = 0xffffffff;
++	unsigned ratio;
++	unsigned remainder;
++	unsigned char divisor = 0;
++
++	/* Calculate the frequency required. This is hard enough. */
++	ratio = 1000000 / pixclock;
++	remainder = 1000000 % pixclock;
++	Ftarget = 1000000 * ratio + (1000000 * remainder) / pixclock;
++
++	while (Ftarget < 100000000) {
++		divisor += 0x10;
++		Ftarget <<= 1;
++	}
++
++	ratio = Ftarget / Fref;
++	remainder = Ftarget % Fref;
++
++	/* This expresses the constraint that 150kHz <= Fref/n <= 5Mhz,
++	 * together with 3 <= n <= 257. */
++	for (n = 3; n <= 257; n++) {
++		unsigned m = n * ratio + (n * remainder) / Fref;
++
++		/* 3 <= m <= 257 */
++		if (m >= 3 && m <= 257) {
++			unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
++					       ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
++			if (new_error < best_error) {
++				best_n = n;
++				best_m = m;
++				best_error = new_error;
++			}
++		}
++		/* But if VLD = 4, then 4m <= 1028 */
++		else if (m <= 1028) {
++			/* remember there are still only 8-bits of precision in m, so
++			 * avoid over-optimistic error calculations */
++			unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
++					       ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
++			if (new_error < best_error) {
++				best_n = n;
++				best_m = m;
++				best_error = new_error;
++			}
++		}
++	}
++	if (best_m > 257)
++		best_m >>= 2;	/* divide m by 4, and leave VCO loop divide at 4 */
++	else
++		divisor |= 4;	/* or set VCO loop divide to 1 */
++	*dclk2_m = best_m - 2;
++	*dclk2_n = best_n - 2;
++	*dclk2_div = divisor;
++	*ppixclock = pixclock;
++	return;
++}
++
++static void asiliant_set_timing(struct fb_info *p)
++{
++	unsigned hd = p->var.xres / 8;
++	unsigned hs = (p->var.xres + p->var.right_margin) / 8;
++       	unsigned he = (p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
++	unsigned ht = (p->var.left_margin + p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
++	unsigned vd = p->var.yres;
++	unsigned vs = p->var.yres + p->var.lower_margin;
++	unsigned ve = p->var.yres + p->var.lower_margin + p->var.vsync_len;
++	unsigned vt = p->var.upper_margin + p->var.yres + p->var.lower_margin + p->var.vsync_len;
++	unsigned wd = (p->var.xres_virtual * ((p->var.bits_per_pixel+7)/8)) / 8;
++
++	if ((p->var.xres == 640) && (p->var.yres == 480) && (p->var.pixclock == 39722)) {
++	  write_fr(0x01, 0x02);  /* LCD */
++	} else {
++	  write_fr(0x01, 0x01);  /* CRT */
++	}
++
++	write_cr(0x11, (ve - 1) & 0x0f);
++	write_cr(0x00, (ht - 5) & 0xff);
++	write_cr(0x01, hd - 1);
++	write_cr(0x02, hd);
++	write_cr(0x03, ((ht - 1) & 0x1f) | 0x80);
++	write_cr(0x04, hs);
++	write_cr(0x05, (((ht - 1) & 0x20) <<2) | (he & 0x1f));
++	write_cr(0x3c, (ht - 1) & 0xc0);
++	write_cr(0x06, (vt - 2) & 0xff);
++	write_cr(0x30, (vt - 2) >> 8);
++	write_cr(0x07, 0x00);
++	write_cr(0x08, 0x00);
++	write_cr(0x09, 0x00);
++	write_cr(0x10, (vs - 1) & 0xff);
++	write_cr(0x32, ((vs - 1) >> 8) & 0xf);
++	write_cr(0x11, ((ve - 1) & 0x0f) | 0x80);
++	write_cr(0x12, (vd - 1) & 0xff);
++	write_cr(0x31, ((vd - 1) & 0xf00) >> 8);
++	write_cr(0x13, wd & 0xff);
++	write_cr(0x41, (wd & 0xf00) >> 8);
++	write_cr(0x15, (vs - 1) & 0xff);
++	write_cr(0x33, ((vs - 1) >> 8) & 0xf);
++	write_cr(0x38, ((ht - 5) & 0x100) >> 8);
++	write_cr(0x16, (vt - 1) & 0xff);
++	write_cr(0x18, 0x00);
++
++	if (p->var.xres == 640) {
++	  writeb(0xc7, mmio_base + 0x784);	/* set misc output reg */
++	} else {
++	  writeb(0x07, mmio_base + 0x784);	/* set misc output reg */
++	}
++}
++
++static int asiliantfb_check_var(struct fb_var_screeninfo *var,
++			     struct fb_info *p)
++{
++	unsigned long Ftarget, ratio, remainder;
++
++	ratio = 1000000 / var->pixclock;
++	remainder = 1000000 % var->pixclock;
++	Ftarget = 1000000 * ratio + (1000000 * remainder) / var->pixclock;
++
++	/* First check the constraint that the maximum post-VCO divisor is 32,
++	 * and the maximum Fvco is 220MHz */
++	if (Ftarget > 220000000 || Ftarget < 3125000) {
++		printk(KERN_ERR "asiliantfb dotclock must be between 3.125 and 220MHz\n");
++		return -ENXIO;
++	}
++	var->xres_virtual = var->xres;
++	var->yres_virtual = var->yres;
++
++	if (var->bits_per_pixel == 24) {
++		var->red.offset = 16;
++		var->green.offset = 8;
++		var->blue.offset = 0;
++		var->red.length = var->blue.length = var->green.length = 8;
++	} else if (var->bits_per_pixel == 16) {
++		switch (var->red.offset) {
++			case 11:
++				var->green.length = 6;
++				break;
++			case 10:
++				var->green.length = 5;
++				break;
++			default:
++				return -EINVAL;
++		}
++		var->green.offset = 5;
++		var->blue.offset = 0;
++		var->red.length = var->blue.length = 5;
++	} else if (var->bits_per_pixel == 8) {
++		var->red.offset = var->green.offset = var->blue.offset = 0;
++		var->red.length = var->green.length = var->blue.length = 8;
++	}
++	return 0;
++}
++
++static int asiliantfb_set_par(struct fb_info *p)
++{
++	u8 dclk2_m;		/* Holds m-2 value for register */
++	u8 dclk2_n;		/* Holds n-2 value for register */
++	u8 dclk2_div;		/* Holds divisor bitmask */
++
++	/* Set pixclock */
++	asiliant_calc_dclk2(&p->var.pixclock, &dclk2_m, &dclk2_n, &dclk2_div);
++
++	/* Set color depth */
++	if (p->var.bits_per_pixel == 24) {
++		write_xr(0x81, 0x16);	/* 24 bit packed color mode */
++		write_xr(0x82, 0x00);	/* Disable palettes */
++		write_xr(0x20, 0x20);	/* 24 bit blitter mode */
++	} else if (p->var.bits_per_pixel == 16) {
++		if (p->var.red.offset == 11)
++			write_xr(0x81, 0x15);	/* 16 bit color mode */
++		else
++			write_xr(0x81, 0x14);	/* 15 bit color mode */
++		write_xr(0x82, 0x00);	/* Disable palettes */
++		write_xr(0x20, 0x10);	/* 16 bit blitter mode */
++	} else if (p->var.bits_per_pixel == 8) {
++		write_xr(0x0a, 0x02);	/* Linear */
++		write_xr(0x81, 0x12);	/* 8 bit color mode */
++		write_xr(0x82, 0x00);	/* Graphics gamma enable */
++		write_xr(0x20, 0x00);	/* 8 bit blitter mode */
++	}
++	p->fix.line_length = p->var.xres * (p->var.bits_per_pixel >> 3);
++	p->fix.visual = (p->var.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
++	write_xr(0xc4, dclk2_m);
++	write_xr(0xc5, dclk2_n);
++	write_xr(0xc7, dclk2_div);
++	/* Set up the CR registers */
++	asiliant_set_timing(p);
++	return 0;
++}
++
++static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
++			     u_int transp, struct fb_info *p)
++{
++	if (regno > 255)
++		return 1;
++	red >>= 8;
++	green >>= 8;
++	blue >>= 8;
++
++        /* Set hardware palete */
++	writeb(regno, mmio_base + 0x790);
++	udelay(1);
++	writeb(red, mmio_base + 0x791);
++	writeb(green, mmio_base + 0x791);
++	writeb(blue, mmio_base + 0x791);
++
++	switch(p->var.bits_per_pixel) {
++	case 15:
++		if (regno < 16) {
++			((u32 *)(p->pseudo_palette))[regno] =
++				((red & 0xf8) << 7) |
++				((green & 0xf8) << 2) |
++				((blue & 0xf8) >> 3);
++		}
++		break;
++	case 16:
++		if (regno < 16) {
++			((u32 *)(p->pseudo_palette))[regno] =
++				((red & 0xf8) << 8) |
++				((green & 0xfc) << 3) |
++				((blue & 0xf8) >> 3);
++		}
++		break;
++	case 24:
++		if (regno < 24) {
++			((u32 *)(p->pseudo_palette))[regno] =
++				(red << 16)  |
++				(green << 8) |
++				(blue);
++		}
++		break;
++	}
++	return 0;
++}
++
++struct chips_init_reg {
++	unsigned char addr;
++	unsigned char data;
++};
++
++#define N_ELTS(x)	(sizeof(x) / sizeof(x[0]))
++
++static struct chips_init_reg chips_init_sr[] =
++{
++	{0x00, 0x03},		/* Reset register */
++	{0x01, 0x01},		/* Clocking mode */
++	{0x02, 0x0f},		/* Plane mask */
++	{0x04, 0x0e}		/* Memory mode */
++};
++
++static struct chips_init_reg chips_init_gr[] =
++{
++        {0x03, 0x00},		/* Data rotate */
++	{0x05, 0x00},		/* Graphics mode */
++	{0x06, 0x01},		/* Miscellaneous */
++	{0x08, 0x00}		/* Bit mask */
++};
++
++static struct chips_init_reg chips_init_ar[] =
++{
++	{0x10, 0x01},		/* Mode control */
++	{0x11, 0x00},		/* Overscan */
++	{0x12, 0x0f},		/* Memory plane enable */
++	{0x13, 0x00}		/* Horizontal pixel panning */
++};
++
++static struct chips_init_reg chips_init_cr[] =
++{
++	{0x0c, 0x00},		/* Start address high */
++	{0x0d, 0x00},		/* Start address low */
++	{0x40, 0x00},		/* Extended Start Address */
++	{0x41, 0x00},		/* Extended Start Address */
++	{0x14, 0x00},		/* Underline location */
++	{0x17, 0xe3},		/* CRT mode control */
++	{0x70, 0x00}		/* Interlace control */
++};
++
++
++static struct chips_init_reg chips_init_fr[] =
++{
++	{0x01, 0x02},
++	{0x03, 0x08},
++	{0x08, 0xcc},
++	{0x0a, 0x08},
++	{0x18, 0x00},
++	{0x1e, 0x80},
++	{0x40, 0x83},
++	{0x41, 0x00},
++	{0x48, 0x13},
++	{0x4d, 0x60},
++	{0x4e, 0x0f},
++
++	{0x0b, 0x01},
++
++	{0x21, 0x51},
++	{0x22, 0x1d},
++	{0x23, 0x5f},
++	{0x20, 0x4f},
++	{0x34, 0x00},
++	{0x24, 0x51},
++	{0x25, 0x00},
++	{0x27, 0x0b},
++	{0x26, 0x00},
++	{0x37, 0x80},
++	{0x33, 0x0b},
++	{0x35, 0x11},
++	{0x36, 0x02},
++	{0x31, 0xea},
++	{0x32, 0x0c},
++	{0x30, 0xdf},
++	{0x10, 0x0c},
++	{0x11, 0xe0},
++	{0x12, 0x50},
++	{0x13, 0x00},
++	{0x16, 0x03},
++	{0x17, 0xbd},
++	{0x1a, 0x00},
++};
++
++
++static struct chips_init_reg chips_init_xr[] =
++{
++	{0xce, 0x00},		/* set default memory clock */
++	{0xcc, 200 },	        /* MCLK ratio M */
++	{0xcd, 18  },	        /* MCLK ratio N */
++	{0xce, 0x90},		/* MCLK divisor = 2 */
++
++	{0xc4, 209 },
++	{0xc5, 118 },
++	{0xc7, 32  },
++	{0xcf, 0x06},
++	{0x09, 0x01},		/* IO Control - CRT controller extensions */
++	{0x0a, 0x02},		/* Frame buffer mapping */
++	{0x0b, 0x01},		/* PCI burst write */
++	{0x40, 0x03},		/* Memory access control */
++	{0x80, 0x82},		/* Pixel pipeline configuration 0 */
++	{0x81, 0x12},		/* Pixel pipeline configuration 1 */
++	{0x82, 0x08},		/* Pixel pipeline configuration 2 */
++
++	{0xd0, 0x0f},
++	{0xd1, 0x01},
++};
++
++static void __init chips_hw_init(struct fb_info *p)
++{
++	int i;
++
++	for (i = 0; i < N_ELTS(chips_init_xr); ++i)
++		write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
++	write_xr(0x81, 0x12);
++	write_xr(0x82, 0x08);
++	write_xr(0x20, 0x00);
++	for (i = 0; i < N_ELTS(chips_init_sr); ++i)
++		write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
++	for (i = 0; i < N_ELTS(chips_init_gr); ++i)
++		write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
++	for (i = 0; i < N_ELTS(chips_init_ar); ++i)
++		write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
++	/* Enable video output in attribute index register */
++	writeb(0x20, mmio_base + 0x780);
++	for (i = 0; i < N_ELTS(chips_init_cr); ++i)
++		write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
++	for (i = 0; i < N_ELTS(chips_init_fr); ++i)
++		write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
++}
++
++static struct fb_fix_screeninfo asiliantfb_fix __initdata = {
++	.id =		"Asiliant 69000",
++	.type =		FB_TYPE_PACKED_PIXELS,
++	.visual =	FB_VISUAL_PSEUDOCOLOR,
++	.accel =	FB_ACCEL_NONE,
++	.line_length =	640,
++	.smem_len =	0x200000,	/* 2MB */
++};
++
++static struct fb_var_screeninfo asiliantfb_var __initdata = {
++	.xres 		= 640,
++	.yres 		= 480,
++	.xres_virtual 	= 640,
++	.yres_virtual 	= 480,
++	.bits_per_pixel = 8,
++	.red 		= { .length = 8 },
++	.green 		= { .length = 8 },
++	.blue 		= { .length = 8 },
++	.height 	= -1,
++	.width 		= -1,
++	.vmode 		= FB_VMODE_NONINTERLACED,
++	.pixclock 	= 39722,
++	.left_margin 	= 48,
++	.right_margin 	= 16,
++	.upper_margin 	= 33,
++	.lower_margin 	= 10,
++	.hsync_len 	= 96,
++	.vsync_len 	= 2,
++};
++
++static void __init init_asiliant(struct fb_info *p, unsigned long addr)
++{
++	p->fix			= asiliantfb_fix;
++	p->fix.smem_start	= addr;
++	p->var			= asiliantfb_var;
++	p->fbops		= &asiliantfb_ops;
++	p->pseudo_palette	= pseudo_palette;
++	p->flags		= FBINFO_FLAG_DEFAULT;
++
++	fb_alloc_cmap(&p->cmap, 256, 0);
++
++	if (register_framebuffer(p) < 0) {
++		printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
++		return;
++	}
++
++	printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
++		p->node, p->fix.smem_len / 1024);
++
++	writeb(0xff, mmio_base + 0x78c);
++	chips_hw_init(p);
++}
++
++static int __devinit
++asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
++{
++	struct fb_info *p = &asiliantfb_info;
++	unsigned long addr, size;
++
++	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
++		return -ENODEV;
++	addr = pci_resource_start(dp, 0);
++	size = pci_resource_len(dp, 0);
++	if (addr == 0)
++		return -ENODEV;
++	if (p->screen_base != 0)
++		return -EBUSY;
++	if (!request_mem_region(addr, size, "asiliantfb"))
++		return -EBUSY;
++
++	p->screen_base = ioremap(addr, 0x800000);
++	if (p->screen_base == NULL) {
++		release_mem_region(addr, size);
++		return -ENOMEM;
++	}
++
++	pci_write_config_dword(dp, 4, 0x02800083);
++	writeb(3, addr + 0x400784);
++
++	init_asiliant(p, addr);
++
++	/* Clear the entire framebuffer */
++	memset(p->screen_base, 0, 0x200000);
++
++	pci_set_drvdata(dp, p);
++	return 0;
++}
++
++static void __devexit asiliantfb_remove(struct pci_dev *dp)
++{
++	struct fb_info *p = pci_get_drvdata(dp);
++
++	if (p != &asiliantfb_info || p->screen_base == NULL)
++		return;
++	unregister_framebuffer(p);
++	iounmap(p->screen_base);
++	p->screen_base = NULL;
++	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
++}
++
++static struct pci_device_id asiliantfb_pci_tbl[] __devinitdata = {
++	{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000, PCI_ANY_ID, PCI_ANY_ID },
++	{ 0 }
++};
++
++MODULE_DEVICE_TABLE(pci, asiliantfb_pci_tbl);
++
++static struct pci_driver asiliantfb_driver = {
++	.name =		"asiliantfb",
++	.id_table =	asiliantfb_pci_tbl,
++	.probe =	asiliantfb_pci_init,
++	.remove =	__devexit_p(asiliantfb_remove),
++};
++
++int __init asiliantfb_init(void)
++{
++	return pci_module_init(&asiliantfb_driver);
++}
++
++static void __exit asiliantfb_exit(void)
++{
++	pci_unregister_driver(&asiliantfb_driver);
++}
++
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/video/aty/aty128fb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/aty/aty128fb.c	2003-10-05 00:34:46.000000000 -0700
+@@ -2041,9 +2041,9 @@ aty128fb_setcolreg(u_int regno, u_int re
+ #define ATY_MIRROR_CRT_ON	0x00000002
+ 
+ /* out param: u32*	backlight value: 0 to 15 */
+-#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, sizeof(__u32*))
++#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, __u32*)
+ /* in param: u32*	backlight value: 0 to 15 */
+-#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, sizeof(__u32*))
++#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, __u32*)
+ 
+ static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ 			  u_long arg, struct fb_info *info)
+--- linux-2.6.0-test6/drivers/video/aty/Makefile	2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/video/aty/Makefile	2003-10-05 00:34:22.000000000 -0700
+@@ -4,4 +4,3 @@ obj-$(CONFIG_FB_ATY128) += aty128fb.o
+ atyfb-y				:= atyfb_base.o mach64_accel.o
+ atyfb-$(CONFIG_FB_ATY_GX)	+= mach64_gx.o
+ atyfb-$(CONFIG_FB_ATY_CT)	+= mach64_ct.o mach64_cursor.o
+-atyfb-objs			:= $(atyfb-y)
+--- linux-2.6.0-test6/drivers/video/chipsfb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/chipsfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -85,7 +85,7 @@ static struct pmu_sleep_notifier chips_s
+ /*
+  * Exported functions
+  */
+-int chips_init(void);
++int chipsfb_init(void);
+ 
+ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
+ static int chipsfb_check_var(struct fb_var_screeninfo *var,
+@@ -460,7 +460,7 @@ static struct pci_driver chipsfb_driver 
+ 	.remove =	__devexit_p(chipsfb_remove),
+ };
+ 
+-int __init chips_init(void)
++int __init chipsfb_init(void)
+ {
+ 	return pci_module_init(&chipsfb_driver);
+ }
+--- linux-2.6.0-test6/drivers/video/console/fbcon.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/video/console/fbcon.c	2003-10-05 00:34:22.000000000 -0700
+@@ -195,8 +195,7 @@ static void fb_flashcursor(void *private
+ {
+ 	struct fb_info *info = (struct fb_info *) private;
+ 
+-	/* Test to see if the cursor is erased but still on */
+-	if (!info || (info->cursor.rop == ROP_COPY))
++	if (!info)
+ 		return;
+ 	info->cursor.enable ^= 1;
+ 	info->fbops->fb_cursor(info, &info->cursor);
+@@ -226,8 +225,7 @@ static void cursor_timer_handler(unsigne
+ 	struct fb_info *info = (struct fb_info *) dev_addr;
+ 	
+ 	schedule_work(&info->queue);	
+-	cursor_timer.expires = jiffies + HZ / 5;
+-	add_timer(&cursor_timer);
++	mod_timer(&cursor_timer, jiffies + HZ/5);
+ }
+ 
+ int __init fb_console_setup(char *this_opt)
+@@ -308,97 +306,6 @@ int set_con2fb_map(int unit, int newidx)
+ }
+ 
+ /*
+- * drawing helpers
+- */
+-static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
+-			    struct fb_image *image, int count,
+-			    const unsigned short *s)
+-{
+-	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+-	unsigned int width = (vc->vc_font.width + 7) >> 3;
+-	unsigned int cellsize = vc->vc_font.height * width;
+-	unsigned int maxcnt = info->pixmap.size/cellsize;
+-	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
+-	unsigned int shift_high = 8, size, pitch, cnt, k;
+-	unsigned int buf_align = info->pixmap.buf_align - 1;
+-	unsigned int scan_align = info->pixmap.scan_align - 1;
+-	unsigned int idx = vc->vc_font.width >> 3;
+-	u8 mask, *src, *dst, *dst0;
+-
+-	while (count) {
+-		if (count > maxcnt)
+-			cnt = k = maxcnt;
+-		else
+-			cnt = k = count;
+-
+-		image->width = vc->vc_font.width * cnt;
+-		pitch = ((image->width + 7) >> 3) + scan_align;
+-		pitch &= ~scan_align;
+-		size = pitch * vc->vc_font.height + buf_align;
+-		size &= ~buf_align;
+-		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+-		image->data = dst0;
+-		while (k--) {
+-			src = vc->vc_font.data + (scr_readw(s++) & charmask)*
+-			cellsize;
+-			dst = dst0;
+-			mask = (u8) (0xfff << shift_high);
+-			move_buf_unaligned(info, dst, src, pitch, image->height,
+-					mask, shift_high, shift_low, mod, idx);
+-			shift_low += mod;
+-			dst0 += (shift_low >= 8) ? width : width - 1;
+-			shift_low &= 7;
+-			shift_high = 8 - shift_low;
+-		}
+-		info->fbops->fb_imageblit(info, image);
+-		image->dx += cnt * vc->vc_font.width;
+-		count -= cnt;
+-		atomic_dec(&info->pixmap.count);
+-		smp_mb__after_atomic_dec();
+-	}
+-}
+-
+-static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
+-			  struct fb_image *image, int count,
+-			  const unsigned short *s)
+-{
+-	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+-	unsigned int width = vc->vc_font.width >> 3;
+-	unsigned int cellsize = vc->vc_font.height * width;
+-	unsigned int maxcnt = info->pixmap.size/cellsize;
+-	unsigned int scan_align = info->pixmap.scan_align - 1;
+-	unsigned int buf_align = info->pixmap.buf_align - 1;
+-	unsigned int pitch, cnt, size, k;
+-	u8 *src, *dst, *dst0;
+-
+-	while (count) {
+-		if (count > maxcnt)
+-			cnt = k = maxcnt;
+-		else
+-			cnt = k = count;
+-		
+-		pitch = width * cnt + scan_align;
+-		pitch &= ~scan_align;
+-		size = pitch * vc->vc_font.height + buf_align;
+-		size &= ~buf_align;
+-		image->width = vc->vc_font.width * cnt;
+-		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+-		image->data = dst0;
+-		while (k--) {
+-			src = vc->vc_font.data + (scr_readw(s++)&charmask)*cellsize;
+-			dst = dst0;
+-			move_buf_aligned(info, dst, src, pitch, width, image->height);
+-			dst0 += width;
+-		}
+-		info->fbops->fb_imageblit(info, image);
+-		image->dx += cnt * vc->vc_font.width;
+-		count -= cnt;
+-		atomic_dec(&info->pixmap.count);
+-		smp_mb__after_atomic_dec();
+-	}
+-}
+-
+-/*
+  * Accelerated handlers.
+  */
+ void accel_bmove(struct vc_data *vc, struct fb_info *info, int sy, 
+@@ -432,48 +339,21 @@ void accel_clear(struct vc_data *vc, str
+ 	info->fbops->fb_fillrect(info, &region);
+ }	
+ 
+-static void accel_putc(struct vc_data *vc, struct fb_info *info,
+-                      int c, int ypos, int xpos)
++void accel_putcs(struct vc_data *vc, struct fb_info *info,
++			const unsigned short *s, int count, int yy, int xx)
+ {
+ 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ 	unsigned int width = (vc->vc_font.width + 7) >> 3;
++	unsigned int cellsize = vc->vc_font.height * width;
++	unsigned int maxcnt = info->pixmap.size/cellsize;
+ 	unsigned int scan_align = info->pixmap.scan_align - 1;
+ 	unsigned int buf_align = info->pixmap.buf_align - 1;
++	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
++	unsigned int shift_high = 8, pitch, cnt, size, k;
+ 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ 	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+-	unsigned int size, pitch;
+-	struct fb_image image;
+-	u8 *src, *dst;
+-
+-	image.dx = xpos * vc->vc_font.width;
+-	image.dy = ypos * vc->vc_font.height;
+-	image.width = vc->vc_font.width;
+-	image.height = vc->vc_font.height;
+-	image.fg_color = attr_fgcol(fgshift, c);
+-	image.bg_color = attr_bgcol(bgshift, c);
+-	image.depth = 1;
+-
+-	pitch = width + scan_align;
+-	pitch &= ~scan_align;
+-	size = pitch * vc->vc_font.height;
+-	size += buf_align;
+-	size &= ~buf_align;
+-	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+-	image.data = dst;
+-	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
+-
+-	move_buf_aligned(info, dst, src, pitch, width, image.height);
+-
+-	info->fbops->fb_imageblit(info, &image);
+-	atomic_dec(&info->pixmap.count);
+-	smp_mb__after_atomic_dec();
+-}
+-
+-void accel_putcs(struct vc_data *vc, struct fb_info *info,
+-			const unsigned short *s, int count, int yy, int xx)
+-{
+-	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
++	unsigned int idx = vc->vc_font.width >> 3;
++	u8 *src, *dst, *dst0, mask;
+ 	struct fb_image image;
+ 	u16 c = scr_readw(s);
+ 
+@@ -484,10 +364,44 @@ void accel_putcs(struct vc_data *vc, str
+ 	image.height = vc->vc_font.height;
+ 	image.depth = 1;
+ 
+-	if (!(vc->vc_font.width & 7))
+-               putcs_aligned(vc, info, &image, count, s);
+-        else
+-               putcs_unaligned(vc, info, &image, count, s);
++	while (count) {
++		if (count > maxcnt)
++			cnt = k = maxcnt;
++		else
++			cnt = k = count;
++
++		image.width = vc->vc_font.width * cnt;
++		pitch = ((image.width + 7) >> 3) + scan_align;
++		pitch &= ~scan_align;
++		size = pitch * vc->vc_font.height + buf_align;
++		size &= ~buf_align;
++		dst0 = fb_get_buffer_offset(info, &info->pixmap, size);
++		image.data = dst0;
++		while (k--) {
++			src = vc->vc_font.data + (scr_readw(s++) & charmask)*cellsize;
++			dst = dst0;
++
++			if (mod) {
++				mask = (u8) (0xfff << shift_high);
++				move_buf_unaligned(info, &info->pixmap, dst, src, pitch,
++						   image.height, mask, shift_high,
++						   shift_low, mod, idx);
++				shift_low += mod;
++				dst0 += (shift_low >= 8) ? width : width - 1;
++				shift_low &= 7;
++				shift_high = 8 - shift_low;
++			} else {
++				move_buf_aligned(info, &info->pixmap, dst, src, pitch, idx,
++						 image.height);
++				dst0 += width;
++			}
++		}
++		info->fbops->fb_imageblit(info, &image);
++		image.dx += cnt * vc->vc_font.width;
++		count -= cnt;
++		atomic_dec(&info->pixmap.count);
++		smp_mb__after_atomic_dec();
++	}
+ }
+ 
+ void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
+@@ -676,7 +590,7 @@ static const char *fbcon_startup(void)
+ 	if (!info->queue.func) {
+ 		INIT_WORK(&info->queue, fb_flashcursor, info);
+ 		
+-		cursor_timer.expires = jiffies + HZ / 50;
++		cursor_timer.expires = jiffies + HZ / 5;
+ 		cursor_timer.data = (unsigned long ) info;
+ 		add_timer(&cursor_timer);
+ 	}
+@@ -728,15 +642,13 @@ static __inline__ void updatescrollmode(
+ static void fbcon_set_display(struct vc_data *vc, int init, int logo)
+ {
+ 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
++	int nr_rows, nr_cols, old_rows, old_cols, i, charcnt = 256;
+ 	struct display *p = &fb_display[vc->vc_num];
+-	int nr_rows, nr_cols;
+-	int old_rows, old_cols;
+ 	unsigned short *save = NULL, *r, *q;
+-	int i, charcnt = 256;
+ 	struct font_desc *font;
+ 
+ 	if (vc->vc_num != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
+-	    info->fix.type == FB_TYPE_TEXT)
++	    (info->fix.type == FB_TYPE_TEXT))
+ 		logo = 0;
+ 
+ 	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
+@@ -960,11 +872,19 @@ static void fbcon_clear(struct vc_data *
+ 		accel_clear(vc, info, real_y(p, sy), sx, height, width);
+ }
+ 
+-
+ static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+ {
+ 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
++	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
++	unsigned int scan_align = info->pixmap.scan_align - 1;
++	unsigned int buf_align = info->pixmap.buf_align - 1;
++	unsigned int width = (vc->vc_font.width + 7) >> 3;
++	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
++	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ 	struct display *p = &fb_display[vc->vc_num];
++	unsigned int size, pitch;
++	struct fb_image image;
++	u8 *src, *dst;
+ 
+ 	if (!info->fbops->fb_blank && console_blanked)
+ 		return;
+@@ -972,7 +892,31 @@ static void fbcon_putc(struct vc_data *v
+ 	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
+ 		return;
+ 
+-	accel_putc(vc, info, c, real_y(p, ypos), xpos);
++	image.dx = xpos * vc->vc_font.width;
++	image.dy = real_y(p, ypos) * vc->vc_font.height;
++	image.width = vc->vc_font.width;
++	image.height = vc->vc_font.height;
++	image.fg_color = attr_fgcol(fgshift, c);
++	image.bg_color = attr_bgcol(bgshift, c);
++	image.depth = 1;
++
++	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
++
++	pitch = width + scan_align;
++	pitch &= ~scan_align;
++	size = pitch * vc->vc_font.height;
++	size += buf_align;
++	size &= ~buf_align;
++
++	dst = fb_get_buffer_offset(info, &info->pixmap, size);
++	image.data = dst;
++
++	move_buf_aligned(info, &info->pixmap, dst, src, pitch, width,
++			image.height);
++
++	info->fbops->fb_imageblit(info, &image);
++	atomic_dec(&info->pixmap.count);
++	smp_mb__after_atomic_dec();
+ }
+ 
+ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+@@ -994,12 +938,16 @@ static void fbcon_cursor(struct vc_data 
+ {
+ 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+ 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
++	unsigned int scan_align = info->sprite.scan_align - 1;
++	unsigned int buf_align = info->sprite.buf_align - 1;
+ 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ 	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ 	struct display *p = &fb_display[vc->vc_num];
+-	int w = (vc->vc_font.width + 7) >> 3, c;
+-	int y = real_y(p, vc->vc_y);
++	int y = real_y(p, vc->vc_y), d_pitch, dsize;
++	int s_pitch = (vc->vc_font.width + 7) >> 3;
++	int size = s_pitch * vc->vc_font.height, c;
+ 	struct fb_cursor cursor;
++	u8 *src, *dst;
+ 	
+ 	if (mode & CM_SOFTBACK) {
+ 		mode &= ~CM_SOFTBACK;
+@@ -1012,28 +960,24 @@ static void fbcon_cursor(struct vc_data 
+ 	} else if (softback_lines)
+ 		fbcon_set_origin(vc);
+ 
+- 	c = scr_readw((u16 *) vc->vc_pos);
++	del_timer(&cursor_timer);
++	if (info->cursor.enable) {
++		info->cursor.enable = 0;
++		info->fbops->fb_cursor(info, &info->cursor);
++	}
+ 
+-	cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
+-	cursor.set = FB_CUR_SETCUR;
+-	cursor.image.depth = 1;
+-	
+-	switch (mode) {
+-	case CM_ERASE:
+-		if (info->cursor.rop == ROP_XOR) {
+-			info->cursor.enable = 0;
+-			info->cursor.rop = ROP_COPY;
+-			info->fbops->fb_cursor(info, &cursor);
+-		}	
+-		break;
+-	case CM_MOVE:
+-	case CM_DRAW:
++	if (mode != CM_ERASE) {
++		memset(&cursor, 0, sizeof(struct fb_cursor));
+ 		info->cursor.enable = 1;
+-		
++
++ 		c = scr_readw((u16 *) vc->vc_pos);
++
++		src = vc->vc_font.data + ((c & charmask) * size);
+ 		if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
+ 	    	    info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
+ 			cursor.image.fg_color = attr_fgcol(fgshift, c);
+ 			cursor.image.bg_color = attr_bgcol(bgshift, c);
++			cursor.image.depth = 1;
+ 			cursor.set |= FB_CUR_SETCMAP;
+ 		}
+ 		
+@@ -1056,18 +1000,29 @@ static void fbcon_cursor(struct vc_data 
+ 			cursor.set |= FB_CUR_SETHOT;
+ 		}
+ 
++		src = vc->vc_font.data + ((c & charmask) * size);
++
++		d_pitch = (s_pitch + scan_align) & ~scan_align;
++		dsize = d_pitch * vc->vc_font.height + buf_align;
++		dsize &= ~buf_align;
++		dst = fb_get_buffer_offset(info, &info->sprite, dsize);
++		move_buf_aligned(info, &info->sprite, dst, src, d_pitch, s_pitch, vc->vc_font.height);
++		info->cursor.image.data = dst;
++		cursor.set |= FB_CUR_SETSHAPE;
++
+ 		if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
+-			char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
+-			int cur_height, size, i = 0;
++			char *mask = kmalloc(dsize, GFP_ATOMIC);
++			int cur_height, i, j, k;
+ 
+ 			if (!mask)	return;	
+-		
++
++			memset(mask, 0, dsize);
++
+ 			if (info->cursor.mask)
+ 				kfree(info->cursor.mask);
+ 			info->cursor.mask = mask;
+ 	
+ 			p->cursor_shape = vc->vc_cursor_type & 0x0f;
+-			cursor.set |= FB_CUR_SETSHAPE;
+ 
+ 			switch (vc->vc_cursor_type & 0x0f) {
+ 			case CUR_NONE:
+@@ -1090,17 +1045,19 @@ static void fbcon_cursor(struct vc_data 
+ 				cur_height = vc->vc_font.height;
+ 				break;
+ 			}
+-			size = (vc->vc_font.height - cur_height) * w;
+-			while (size--)
+-				mask[i++] = 0;
+-			size = cur_height * w;
+-			while (size--)
+-				mask[i++] = 0xff;
++			i = (vc->vc_font.height - cur_height) * d_pitch;
++			for (j = 0; j < cur_height; j++) {
++				for (k = 0; k < s_pitch; k++)
++					mask[i++] = 0xff;
++				i += (d_pitch - s_pitch);
++			}
+ 		}
+         	info->cursor.rop = ROP_XOR;
+ 		info->fbops->fb_cursor(info, &cursor);
++		atomic_dec(&info->sprite.count);
++		smp_mb__after_atomic_dec();
++		mod_timer(&cursor_timer, jiffies + HZ/5);
+ 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+-		break;
+ 	}
+ }
+ 
+@@ -1826,8 +1783,10 @@ static int fbcon_do_set_font(struct vc_d
+ 	vc->vc_font.height = h;
+ 	if (vc->vc_hi_font_mask && cnt == 256) {
+ 		vc->vc_hi_font_mask = 0;
+-		if (vc->vc_can_do_color)
++		if (vc->vc_can_do_color) {
+ 			vc->vc_complement_mask >>= 1;
++			vc->vc_s_complement_mask >>= 1;
++		}
+ 
+ 		/* ++Edmund: reorder the attribute bits */
+ 		if (vc->vc_can_do_color) {
+@@ -1847,8 +1806,10 @@ static int fbcon_do_set_font(struct vc_d
+ 		}
+ 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
+ 		vc->vc_hi_font_mask = 0x100;
+-		if (vc->vc_can_do_color)
++		if (vc->vc_can_do_color) {
+ 			vc->vc_complement_mask <<= 1;
++			vc->vc_s_complement_mask <<= 1;
++		}
+ 
+ 		/* ++Edmund: reorder the attribute bits */
+ 		{
+--- linux-2.6.0-test6/drivers/video/console/Makefile	2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/video/console/Makefile	2003-10-05 00:34:22.000000000 -0700
+@@ -3,18 +3,16 @@
+ # Rewritten to use lists instead of if-statements.
+ 
+ # Font handling
+-font-objs := fonts.o
++font-y := fonts.o
+ 
+-font-objs-$(CONFIG_FONT_SUN8x16)   += font_sun8x16.o
+-font-objs-$(CONFIG_FONT_SUN12x22)  += font_sun12x22.o
+-font-objs-$(CONFIG_FONT_8x8)       += font_8x8.o
+-font-objs-$(CONFIG_FONT_8x16)      += font_8x16.o
+-font-objs-$(CONFIG_FONT_6x11)      += font_6x11.o
+-font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
+-font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
+-font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+-
+-font-objs += $(font-objs-y)
++font-$(CONFIG_FONT_SUN8x16)   += font_sun8x16.o
++font-$(CONFIG_FONT_SUN12x22)  += font_sun12x22.o
++font-$(CONFIG_FONT_8x8)       += font_8x8.o
++font-$(CONFIG_FONT_8x16)      += font_8x16.o
++font-$(CONFIG_FONT_6x11)      += font_6x11.o
++font-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
++font-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
++font-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+ 
+ # Each configuration option enables a list of files.
+ 
+@@ -31,8 +29,11 @@ obj-$(CONFIG_FB_STI)              += sti
+ # Files generated that shall be removed upon make clean
+ clean-files := promcon_tbl.c
+ 
+-$(obj)/promcon_tbl.c: $(src)/prom.uni
+-	$(objtree)/scripts/conmakehash $< | \
++quiet_cmd_promtbl = GEN	$@
++	cmd_promtbl = scripts/conmakehash $< | \
+ 	sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
+ 	    -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+ 
++$(obj)/promcon_tbl.c: $(src)/prom.uni
++	$(call cmd,promtbl)
++
+--- linux-2.6.0-test6/drivers/video/console/sticore.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/console/sticore.c	2003-10-05 00:33:24.000000000 -0700
+@@ -988,7 +988,7 @@ static int __devinit sticore_pci_init(st
+ 	
+ 	if (!sti) {
+ 		printk(KERN_WARNING "Unable to handle STI device '%s'\n",
+-			pd->dev.name);
++			pci_name(pd));
+ 		return -ENODEV;
+ 	}
+ #endif /* CONFIG_PCI */
+--- linux-2.6.0-test6/drivers/video/controlfb.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/controlfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -136,8 +136,8 @@ static int controlfb_check_var (struct f
+ /*
+  * inititialization
+  */
+-int control_init(void);
+-void control_setup(char *);
++int controlfb_init(void);
++void controlfb_setup(char *);
+ 
+ /******************** Prototypes for internal functions **********************/
+ 
+@@ -553,7 +553,7 @@ static void control_set_hardware(struct 
+ /*
+  * Called from fbmem.c for probing & initializing
+  */
+-int __init control_init(void)
++int __init controlfb_init(void)
+ {
+ 	struct device_node *dp;
+ 
+@@ -1057,7 +1057,7 @@ static void control_cleanup(void)
+ /*
+  * Parse user speficied options (`video=controlfb:')
+  */
+-void __init control_setup(char *options)
++void __init controlfb_setup(char *options)
+ {
+ 	char *this_opt;
+ 
+--- linux-2.6.0-test6/drivers/video/epson1355fb.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/video/epson1355fb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,541 +1,714 @@
+ /*
+- * linux/drivers/video/epson1355fb.c
+- *	-- Support for the Epson SED1355 LCD/CRT controller
++ * linux/drivers/video/epson1355fb.c -- Epson S1D13505 frame buffer for 2.5.
+  *
+- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
++ * Epson Research S1D13505 Embedded RAMDAC LCD/CRT Controller
++ *   (previously known as SED1355)
+  *
+- * based on linux/drivers/video/skeletonfb.c, which was
++ * Cf. http://www.erd.epson.com/vdc/html/S1D13505.html
++ *
++ *
++ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
++ *
++ * Written by Christopher Hoover <ch@hpl.hp.com>
++ *
++ * Adapted from:
++ *
++ *  linux/drivers/video/skeletonfb.c
++ *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
+  *  Created 28 Dec 1997 by Geert Uytterhoeven
+  *
++ *  linux/drivers/video/epson1355fb.c (2.4 driver)
++ *  Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
++ *
+  * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file COPYING in the main directory of this archive
+- * for more details.
+- */
+-/* TODO (roughly in order of priority):
+- * 16 bpp support
+- * crt support
+- * hw cursor support
+- * SwivelView
++ * License. See the file COPYING in the main directory of this archive for
++ * more details.
++ *
++ *
++ * Noteworthy Issues
++ * -----------------
++ *
++ * This driver is complicated by the fact that this is a 16-bit chip
++ * and, on at least one platform (ceiva), we can only do 16-bit reads
++ * and writes to the framebuffer.  We hide this from user space
++ * except in the case of mmap().
++ *
++ *
++ * To Do
++ * -----
++ *
++ * - Test 8-bit pseudocolor mode
++ * - Allow setting bpp, virtual resolution
++ * - Implement horizontal panning
++ * - (maybe) Implement hardware cursor
+  */
+ 
+-#include <asm/io.h>
+-#include <linux/config.h>
+-#include <linux/delay.h>
+-#include <linux/errno.h>
+-#include <linux/fb.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/mm.h>
+ #include <linux/module.h>
+-#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
+ #include <linux/string.h>
++#include <linux/mm.h>
+ #include <linux/tty.h>
+-#include <video/fbcon-cfb8.h>
+-#include <video/fbcon-mfb.h>
+-#include <video/fbcon.h>
+-
+-/* Register defines.  The docs don't seem to provide nice mnemonic names
+- * so I made them up myself ... */
+-
+-#define E1355_PANEL	0x02
+-#define E1355_DISPLAY	0x0D
+-#define E1355_MISC	0x1B
+-#define E1355_GPIO	0x20
+-#define E1355_LUT_INDEX 0x24
+-#define E1355_LUT_DATA	0x26
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <asm/types.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#include <video/epson1355.h>
++
++static struct fb_info info;
++
++static struct epson1355fb_par {
++	unsigned long reg_addr;
++} par;
++
++static u32 pseudo_palette[16];
++
++/* ------------------------------------------------------------------------- */
+ 
+ #ifdef CONFIG_SUPERH
+-#define E1355_REG_BASE	CONFIG_E1355_REG_BASE
+-#define E1355_FB_BASE	CONFIG_E1355_FB_BASE
+ 
+-static inline u8 e1355_read_reg(int index)
++static inline u8 epson1355_read_reg(int index)
+ {
+-	return ctrl_inb(E1355_REG_BASE + index);
++	return ctrl_inb(par.reg_addr + index);
+ }
+ 
+-static inline void e1355_write_reg(u8 data, int index)
++static inline void epson1355_write_reg(u8 data, int index)
+ {
+-	ctrl_outb(data, E1355_REG_BASE + index);
++	ctrl_outb(data, par.reg_addr + index);
+ }
+ 
+-static inline u16 e1355_read_reg16(int index)
++#elif defined(CONFIG_ARM)
++
++# ifdef CONFIG_ARCH_CEIVA
++#  include <asm/arch/hardware.h>
++#  define EPSON1355FB_BASE_PHYS	(CEIVA_PHYS_SED1355)
++# endif
++
++static inline u8 epson1355_read_reg(int index)
+ {
+-	return e1355_read_reg(index) + (e1355_read_reg(index+1) << 8);
++	return __raw_readb(par.reg_addr + index);
+ }
+ 
+-static inline void e1355_write_reg16(u16 data, int index)
++static inline void epson1355_write_reg(u8 data, int index)
+ {
+-	e1355_write_reg((data&0xff), index);
+-	e1355_write_reg(((data>>8)&0xff), index + 1);
++	__raw_writeb(data, par.reg_addr + index);
+ }
++
+ #else
+-#error unknown architecture
++# error "no architecture-specific epson1355_{read,write}_reg"
+ #endif
+ 
+-struct e1355fb_info {
+-	struct fb_info_gen gen;
+-};
+-
+-static int current_par_valid = 0;
+-static struct display disp;
++#ifndef EPSON1355FB_BASE_PHYS
++# error  "EPSON1355FB_BASE_PHYS is not defined"
++#endif
+ 
+-static struct fb_var_screeninfo default_var;
++#define EPSON1355FB_REGS_OFS	(0)
++#define EPSON1355FB_REGS_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_REGS_OFS)
++#define EPSON1355FB_REGS_LEN	(64)
+ 
+-int e1355fb_init(void);
+-int e1355fb_setup(char*);
+-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *par,
+-			    struct fb_info_gen *info);
+-/* ------------------- chipset specific functions -------------------------- */
++#define EPSON1355FB_FB_OFS	(0x00200000)
++#define EPSON1355FB_FB_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_FB_OFS)
++#define EPSON1355FB_FB_LEN	(2 * 1024 * 1024)
+ 
++/* ------------------------------------------------------------------------- */
+ 
+-static void disable_hw_cursor(void)
++static inline u16 epson1355_read_reg16(int index)
+ {
+-	u8 curs;
++	u8 lo = epson1355_read_reg(index);
++	u8 hi = epson1355_read_reg(index + 1);
+ 
+-	curs = e1355_read_reg(0x27);
+-	curs &= ~0xc0;
+-	e1355_write_reg(curs, 0x27);
++	return (hi << 8) | lo;
+ }
+ 
+-static void e1355_detect(void)
++static inline void epson1355_write_reg16(u16 data, int index)
+ {
+-	u8 rev;
++	u8 lo = data & 0xff;
++	u8 hi = (data >> 8) & 0xff;
+ 
+-	e1355_write_reg(0x00, E1355_MISC);
++	epson1355_write_reg(lo, index);
++	epson1355_write_reg(hi, index + 1);
++}
+ 
+-	rev = e1355_read_reg(0x00);
++static inline u32 epson1355_read_reg20(int index)
++{
++	u8 b0 = epson1355_read_reg(index);
++	u8 b1 = epson1355_read_reg(index + 1);
++	u8 b2 = epson1355_read_reg(index + 2);
+ 
+-	if ((rev & 0xfc) != 0x0c) {
+-		printk(KERN_WARNING "Epson 1355 not detected\n");
+-	}
++	return (b2 & 0x0f) << 16 | (b1 << 8) | b0;
++}
+ 
+-	/* XXX */
+-	disable_hw_cursor();
++static inline void epson1355_write_reg20(u32 data, int index)
++{
++	u8 b0 = data & 0xff;
++	u8 b1 = (data >> 8) & 0xff;
++	u8 b2 = (data >> 16) & 0x0f;
+ 
+-	e1355_encode_var(&default_var, NULL, NULL);
++	epson1355_write_reg(b0, index);
++	epson1355_write_reg(b1, index + 1);
++	epson1355_write_reg(b2, index + 2);
+ }
+ 
+-struct e1355_par {
+-	u32 xres;
+-	u32 yres;
++/* ------------------------------------------------------------------------- */
+ 
+-	int bpp;
+-	int mem_bpp;
++static void set_lut(u8 index, u8 r, u8 g, u8 b)
++{
++	epson1355_write_reg(index, REG_LUT_ADDR);
++	epson1355_write_reg(r, REG_LUT_DATA);
++	epson1355_write_reg(g, REG_LUT_DATA);
++	epson1355_write_reg(b, REG_LUT_DATA);
++}
+ 
+-	u32 panel_xres;
+-	u32 panel_yres;
+-	
+-	int panel_width;
+-	int panel_ymul;
+-};
+ 
+-static int e1355_encode_fix(struct fb_fix_screeninfo *fix,
+-			    const void *raw_par,
+-			    struct fb_info_gen *info)
+-{
+-	const struct e1355_par *par = raw_par;
+-	
+-	memset(fix, 0, sizeof *fix);
+-	
+-	fix->type= FB_TYPE_PACKED_PIXELS;
++/**
++ *  	epson1355fb_setcolreg - sets a color register.
++ *      @regno: Which register in the CLUT we are programming
++ *      @red: The red value which can be up to 16 bits wide
++ *	@green: The green value which can be up to 16 bits wide
++ *	@blue:  The blue value which can be up to 16 bits wide.
++ *	@transp: If supported the alpha value which can be up to 16 bits wide.
++ *      @info: frame buffer info structure
++ *
++ *	Returns negative errno on error, or zero on success.
++ */
++static int epson1355fb_setcolreg(unsigned regno, unsigned r, unsigned g,
++				 unsigned b, unsigned transp,
++				 struct fb_info *info)
++{
++	if (info->var.grayscale)
++		r = g = b = (19595 * r + 38470 * g + 7471 * b) >> 16;
++
++	switch (info->fix.visual) {
++	case FB_VISUAL_TRUECOLOR:
++		if (regno >= 16)
++			return -EINVAL;
+ 
+-	if (!par)
+-		BUG();
++		((u32 *) info->pseudo_palette)[regno] =
++		    (r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;
+ 
+-	if (par->bpp == 1) {
+-		fix->visual = FB_VISUAL_MONO10;
+-	} else if (par->bpp <= 8) {
+-		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+-	} else {
+-		fix->visual = FB_VISUAL_TRUECOLOR;
+-	}
++		break;
++	case FB_VISUAL_PSEUDOCOLOR:
++		if (regno >= 256)
++			return -EINVAL;
+ 
+-	return 0;
+-}
++		set_lut(regno, r >> 8, g >> 8, b >> 8);
+ 
+-static int e1355_set_bpp(struct e1355_par *par, int bpp)
+-{
+-	int code;
+-	u8 disp;
+-	u16 bytes_per_line;
+-
+-	switch(bpp) {
+-	case 1:
+-		code = 0; break;
+-	case 2:
+-		code = 1; break;
+-	case 4:
+-		code = 2; break;
+-	case 8:
+-		code = 3; break;
+-	case 16:
+-		code = 5; break;
++		break;
+ 	default:
+-		return -EINVAL; break;
++		return -ENOSYS;
+ 	}
+-
+-	disp = e1355_read_reg(E1355_DISPLAY);
+-	disp &= ~0x1c;
+-	disp |= code << 2;
+-	e1355_write_reg(disp, E1355_DISPLAY);
+-	
+-	bytes_per_line = (par->xres * bpp) >> 3;
+-	
+-	e1355_write_reg16(bytes_per_line, 0x16);
+-
+-	par->bpp = bpp;
+-
+ 	return 0;
+ }
+-		
+-static int e1355_decode_var(const struct fb_var_screeninfo *var,
+-			    void *raw_par,
+-			    struct fb_info_gen *info)
++
++/* ------------------------------------------------------------------------- */
++
++/**
++ *      epson1355fb_pan_display - Pans the display.
++ *      @var: frame buffer variable screen structure
++ *      @info: frame buffer structure that represents a single frame buffer
++ *
++ *	Pan (or wrap, depending on the `vmode' field) the display using the
++ *  	`xoffset' and `yoffset' fields of the `var' structure.
++ *  	If the values don't fit, return -EINVAL.
++ *
++ *      Returns negative errno on error, or zero on success.
++ */
++static int epson1355fb_pan_display(struct fb_var_screeninfo *var,
++				   struct fb_info *info)
+ {
+-	struct e1355_par *par = raw_par;
+-	int ret;
++	u32 start;
+ 
+-	if (!par)
+-		BUG();
++	if (var->xoffset != 0)	/* not yet ... */
++		return -EINVAL;
+ 
+-	/*
+-	 * Don't allow setting any of these yet: xres and yres don't
+-	 * make sense for LCD panels; xres_virtual and yres_virtual
+-	 * should be supported fine by our hardware though.
+-	 */
+-	if (var->xres != par->xres ||
+-	    var->yres != par->yres ||
+-	    var->xres != var->xres_virtual ||
+-	    var->yres != var->yres_virtual ||
+-	    var->xoffset != 0 ||
+-	    var->yoffset != 0)
++	if (var->yoffset + info->var.yres > info->var.yres_virtual)
+ 		return -EINVAL;
+ 
+-	if(var->bits_per_pixel != par->bpp) {
+-		ret = e1355_set_bpp(par, var->bits_per_pixel);
++	start = (info->fix.line_length >> 1) * var->yoffset;
+ 
+-		if (ret)
+-			goto out_err;
+-	}
+-		
+-	return 0;
++	epson1355_write_reg20(start, REG_SCRN1_DISP_START_ADDR0);
+ 
+- out_err:
+-	return ret;
++	return 0;
+ }
+ 
+-static void dump_panel_data(void)
++/* ------------------------------------------------------------------------- */
++
++static void lcd_enable(int enable)
+ {
+-	u8 panel = e1355_read_reg(E1355_PANEL);
+-	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
++	u8 mode = epson1355_read_reg(REG_DISPLAY_MODE);
+ 
+-	printk("%s %s %s panel, width %d bits\n",
+-	       panel & 2 ? "dual" : "single",
+-	       panel & 4 ? "color" : "mono",
+-	       panel & 1 ? "TFT" : "passive",
+-	       width[panel&1][(panel>>4)&3]);
++	if (enable)
++		mode |= 1;
++	else
++		mode &= ~1;
+ 
+-	printk("resolution %d x %d\n",
+-	       (e1355_read_reg(0x04) + 1) * 8,
+-	       ((e1355_read_reg16(0x08) + 1) * (1 + ((panel & 3) == 2))));
++	epson1355_write_reg(mode, REG_DISPLAY_MODE);
+ }
+ 
+-static int e1355_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
++#if defined(CONFIG_ARCH_CEIVA)
++static void backlight_enable(int enable)
+ {
+-	switch(bpp) {
+-	case 1:
+-	case 2:
+-	case 4:
+-	case 8:
+-		var->bits_per_pixel = bpp;
+-		var->red.offset = var->green.offset = var->blue.offset = 0;
+-		var->red.length = var->green.length = var->blue.length = bpp;
++	/* ### this should be protected by a spinlock ... */
++	u8 pddr = clps_readb(PDDR);
++	if (enable)
++		pddr |= (1 << 5);
++	else
++		pddr &= ~(1 << 5);
++	clps_writeb(pddr, PDDR);
++}
++#else
++static void backlight_enable(int enable)
++{
++}
++#endif
++
++
++/**
++ *      epson1355fb_blank - blanks the display.
++ *      @blank_mode: the blank mode we want.
++ *      @info: frame buffer structure that represents a single frame buffer
++ *
++ *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
++ *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a
++ *      video mode which doesn't support it. Implements VESA suspend
++ *      and powerdown modes on hardware that supports disabling hsync/vsync:
++ *      blank_mode == 2: suspend vsync
++ *      blank_mode == 3: suspend hsync
++ *      blank_mode == 4: powerdown
++ *
++ *      Returns negative errno on error, or zero on success.
++ *
++ */
++static int epson1355fb_blank(int blank_mode, struct fb_info *info)
++{
++	switch (blank_mode) {
++	case VESA_NO_BLANKING:
++		lcd_enable(1);
++		backlight_enable(1);
+ 		break;
+-	case 16:
+-		var->bits_per_pixel = 16;
+-		var->red.offset = 11;
+-		var->red.length = 5;
+-		var->green.offset = 5;
+-		var->green.length = 6;
+-		var->blue.offset = 0;
+-		var->blue.length = 5;
++	case VESA_VSYNC_SUSPEND:
++	case VESA_HSYNC_SUSPEND:
++		backlight_enable(0);
+ 		break;
++	case VESA_POWERDOWN:
++		backlight_enable(0);
++		lcd_enable(0);
++		break;
++	default:
++		return -EINVAL;
+ 	}
+-
+ 	return 0;
+ }
+ 
+-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
+-			    struct fb_info_gen *info)
++/* ------------------------------------------------------------------------- */
++
++/*
++ * We can't use the cfb generic routines, as we have to limit
++ * ourselves to 16-bit or 8-bit loads and stores to this 16-bit
++ * chip.
++ */
++
++static inline void epson1355fb_fb_writel(unsigned long v, unsigned long *a)
+ {
+-	u8 panel, display;
+-	u32 xres, xres_virtual, yres;
+-	static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+-	static int bpp_tab[8] = { 1, 2, 4, 8, 15, 16 };
+-	int bpp, hw_bpp;
+-	int is_color, is_dual, is_tft;
+-	int lcd_enabled, crt_enabled;
++	u16 *p = (u16 *) a;
++	u16 l = v & 0xffff;
++	u16 h = v >> 16;
+ 
+-	panel = e1355_read_reg(E1355_PANEL);
+-	display = e1355_read_reg(E1355_DISPLAY);
++	fb_writew(l, p);
++	fb_writew(h, p + 1);
++}
+ 
+-	is_color = (panel & 0x04) != 0;
+-	is_dual  = (panel & 0x02) != 0;
+-	is_tft   = (panel & 0x01) != 0;
++static inline unsigned long epson1355fb_fb_readl(const unsigned long *a)
++{
++	const u16 *p = (u16 *) a;
++	u16 l = fb_readw(p);
++	u16 h = fb_readw(p + 1);
+ 
+-	bpp = bpp_tab[(display>>2)&7]; 
+-	e1355_bpp_to_var(bpp, var);
++	return (h << 16) | l;
++}
+ 
+-	crt_enabled = (display & 0x02) != 0;
+-	lcd_enabled = (display & 0x02) != 0;
++#define FB_READL epson1355fb_fb_readl
++#define FB_WRITEL epson1355fb_fb_writel
+ 
+-	hw_bpp = width[is_tft][(panel>>4)&3];
++/* ------------------------------------------------------------------------- */
+ 
+-	xres = e1355_read_reg(0x04) + 1;
+-	yres = e1355_read_reg16(0x08) + 1;
+-	
+-	xres *= 8;
+-	/* talk about weird hardware .. */
+-	yres *= (is_dual && !crt_enabled) ? 2 : 1;
+-
+-	xres_virtual = e1355_read_reg16(0x16);
+-	/* it's in 2-byte words initially */
+-	xres_virtual *= 16;
+-	xres_virtual /= var->bits_per_pixel;
++static inline unsigned long copy_from_user16(void *to, const void *from,
++					     unsigned long n)
++{
++	u16 *dst = (u16 *) to;
++	u16 *src = (u16 *) from;
+ 
+-	var->xres = xres;
+-	var->yres = yres;
+-	var->xres_virtual = xres_virtual;
+-	var->yres_virtual = yres;
++	if (!access_ok(VERIFY_READ, from, n))
++		return n;
+ 
+-	var->xoffset = var->yoffset = 0;
++	while (n > 1) {
++		u16 v;
++		if (__get_user(v, src))
++			return n;
+ 
+-	var->grayscale = !is_color;
+-	
+-	return 0;
+-}
++		fb_writew(v, dst);
+ 
+-#define is_dual(panel) (((panel)&3)==2)
++		src++, dst++;
++		n -= 2;
++	}
+ 
+-static void get_panel_data(struct e1355_par *par)
+-{
+-	u8 panel;
+-	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
++	if (n) {
++		u8 v;
+ 
+-	panel = e1355_read_reg(E1355_PANEL);
++		if (__get_user(v, ((u8 *) src)))
++			return n;
+ 
+-	par->panel_width = width[panel&1][(panel>>4)&3];
+-	par->panel_xres = (e1355_read_reg(0x04) + 1) * 8;
+-	par->panel_ymul = is_dual(panel) ? 2 : 1;
+-	par->panel_yres = ((e1355_read_reg16(0x08) + 1)
+-			   * par->panel_ymul);
++		fb_writeb(v, dst);
++	}
++	return 0;
+ }
+ 
+-static void e1355_get_par(void *raw_par, struct fb_info_gen *info)
++static inline unsigned long copy_to_user16(void *to, const void *from,
++					   unsigned long n)
+ {
+-	struct e1355_par *par = raw_par;
++	u16 *dst = (u16 *) to;
++	u16 *src = (u16 *) from;
+ 
+-	get_panel_data(par);
+-}
++	if (!access_ok(VERIFY_WRITE, to, n))
++		return n;
+ 
+-static void e1355_set_par(const void *par, struct fb_info_gen *info)
+-{
+-}
++	while (n > 1) {
++		u16 v = fb_readw(src);
+ 
+-static int e1355_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+-			   unsigned *blue, unsigned *transp,
+-			   struct fb_info *info)
+-{
+-	u8 r, g, b;
++		if (__put_user(v, dst))
++			return n;
+ 
+-	e1355_write_reg(regno, E1355_LUT_INDEX);
+-	r = e1355_read_reg(E1355_LUT_DATA);
+-	g = e1355_read_reg(E1355_LUT_DATA);
+-	b = e1355_read_reg(E1355_LUT_DATA);
++		src++, dst++;
++		n -= 2;
++	}
+ 
+-	*red = r << 8;
+-	*green = g << 8;
+-	*blue = b << 8;
++	if (n) {
++		u8 v = fb_readb(src);
+ 
++		if (__put_user(v, ((u8 *) dst)))
++			return n;
++	}
+ 	return 0;
+ }
+ 
+-static int e1355fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+-			     unsigned blue, unsigned transp,
+-			     struct fb_info *info)
+-{
+-	u8 r = (red >> 8) & 0xf0;
+-	u8 g = (green>>8) & 0xf0;
+-	u8 b = (blue>> 8) & 0xf0;
+-
+-	e1355_write_reg(regno, E1355_LUT_INDEX);
+-	e1355_write_reg(r, E1355_LUT_DATA);
+-	e1355_write_reg(g, E1355_LUT_DATA);
+-	e1355_write_reg(b, E1355_LUT_DATA);
+-	
+-	return 0;
+-}
+ 
+-static int e1355_pan_display(const struct fb_var_screeninfo *var,
+-			     struct fb_info_gen *info)
++static ssize_t
++epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+ {
+-	BUG();
+-	
+-	return -EINVAL;
++	unsigned long p = *ppos;
++
++	/* from fbmem.c except for our own copy_*_user */
++	if (p >= info.fix.smem_len)
++		return 0;
++	if (count >= info.fix.smem_len)
++		count = info.fix.smem_len;
++	if (count + p > info.fix.smem_len)
++		count = info.fix.smem_len - p;
++
++	if (count) {
++		char *base_addr;
++
++		base_addr = info.screen_base;
++		count -= copy_to_user16(buf, base_addr + p, count);
++		if (!count)
++			return -EFAULT;
++		*ppos += count;
++	}
++	return count;
+ }
+ 
+-/*
+- * The AERO_HACKS parts disable/enable the backlight on the Compaq Aero 8000.
+- * I'm not sure they aren't dangerous to the hardware, so be warned.
+- */
+-#undef AERO_HACKS
++static ssize_t
++epson1355fb_write(struct file *file, const char *buf,
++		  size_t count, loff_t * ppos)
++{
++	unsigned long p = *ppos;
++	int err;
++
++	/* from fbmem.c except for our own copy_*_user */
++	if (p > info.fix.smem_len)
++		return -ENOSPC;
++	if (count >= info.fix.smem_len)
++		count = info.fix.smem_len;
++	err = 0;
++	if (count + p > info.fix.smem_len) {
++		count = info.fix.smem_len - p;
++		err = -ENOSPC;
++	}
+ 
+-static int e1355_blank(int blank_mode, struct fb_info_gen *info)
+-{
+-	u8 disp;
++	if (count) {
++		char *base_addr;
+ 
+-	switch (blank_mode) {
+-	case VESA_NO_BLANKING:
+-		disp = e1355_read_reg(E1355_DISPLAY);
+-		disp |= 1;
+-		e1355_write_reg(disp, E1355_DISPLAY);
+- 		
+-#ifdef AERO_HACKS
+-		e1355_write_reg(0x6, 0x20);
+-#endif
+-		break;
++		base_addr = info.screen_base;
++		count -= copy_from_user16(base_addr + p, buf, count);
++		*ppos += count;
++		err = -EFAULT;
++	}
++	if (count)
++		return count;
++	return err;
++}
++
++/* ------------------------------------------------------------------------- */
++
++static struct fb_ops epson1355fb_fbops = {
++	.owner 		= THIS_MODULE,
++	.fb_setcolreg 	= epson1355fb_setcolreg,
++	.fb_pan_display = epson1355fb_pan_display,
++	.fb_blank 	= epson1355fb_blank,
++	.fb_fillrect 	= cfb_fillrect,
++	.fb_copyarea 	= cfb_copyarea,
++	.fb_imageblit 	= cfb_imageblit,
++	.fb_read 	= epson1355fb_read,
++	.fb_write 	= epson1355fb_write,
++	.fb_cursor 	= soft_cursor,
++};
+ 
+-	case VESA_VSYNC_SUSPEND:
+-	case VESA_HSYNC_SUSPEND:
+-	case VESA_POWERDOWN:
+-		disp = e1355_read_reg(E1355_DISPLAY);
+-		disp &= ~1;
+-		e1355_write_reg(disp, E1355_DISPLAY);
++/* ------------------------------------------------------------------------- */
+ 
+-#ifdef AERO_HACKS
+-		e1355_write_reg(0x0, 0x20);
+-#endif
+-		break;
++static __init unsigned int get_fb_size(struct fb_info *info)
++{
++	unsigned int size = 2 * 1024 * 1024;
++	char *p = info->screen_base;
+ 
+-	default:
+-		return -EINVAL;
+-	}
++	/* the 512k framebuffer is aliased at start + 0x80000 * n */
++	fb_writeb(1, p);
++	fb_writeb(0, p + 0x80000);
++	if (!fb_readb(p))
++		size = 512 * 1024;
+ 
+-	return 0;
++	fb_writeb(0, p);
++
++	return size;
+ }
+ 
+-static struct display_switch e1355_dispsw;
++static int epson1355_width_tab[2][4] __initdata =
++    { {4, 8, 16, -1}, {9, 12, 16, -1} };
++static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 };
+ 
+-static void e1355_set_disp(const void *unused, struct display *disp,
+-			   struct fb_info_gen *info)
++static void __init fetch_hw_state(struct fb_info *info)
+ {
+-	struct display_switch *d;
++	struct fb_var_screeninfo *var = &info->var;
++	struct fb_fix_screeninfo *fix = &info->fix;
++	u8 panel, display;
++	u16 offset;
++	u32 xres, yres;
++	u32 xres_virtual, yres_virtual;
++	int bpp, lcd_bpp;
++	int is_color, is_dual, is_tft;
++	int lcd_enabled, crt_enabled;
++
++	fix->type = FB_TYPE_PACKED_PIXELS;
+ 
+-	disp->dispsw = &e1355_dispsw;
+-	
+-	switch(disp->var.bits_per_pixel) {
+-#ifdef FBCON_HAS_MFB
+-	case 1:
+-		d = &fbcon_mfb; break;
+-#endif	       
+-#ifdef FBCON_HAS_CFB8
++	display = epson1355_read_reg(REG_DISPLAY_MODE);
++	bpp = epson1355_bpp_tab[(display >> 2) & 7];
++
++	switch (bpp) {
+ 	case 8:
+-		d = &fbcon_cfb8; break;
+-#endif
++		fix->visual = FB_VISUAL_PSEUDOCOLOR;
++		var->bits_per_pixel = 8;
++		var->red.offset = var->green.offset = var->blue.offset = 0;
++		var->red.length = var->green.length = var->blue.length = 8;
++		break;
++	case 16:
++		/* 5-6-5 RGB */
++		fix->visual = FB_VISUAL_TRUECOLOR;
++		var->bits_per_pixel = 16;
++		var->red.offset = 11;
++		var->red.length = 5;
++		var->green.offset = 5;
++		var->green.length = 6;
++		var->blue.offset = 0;
++		var->blue.length = 5;
++		break;
+ 	default:
+-		BUG(); break;
++		BUG();
+ 	}
+ 
+-	memcpy(&e1355_dispsw, d, sizeof *d);
++	if (fix->visual == FB_VISUAL_TRUECOLOR) {
++		info->pseudo_palette = &pseudo_palette;
++		fb_alloc_cmap(&(info->cmap), 16, 0);
++	} else
++		fb_alloc_cmap(&(info->cmap), 1 << bpp, 0);
++
++	panel = epson1355_read_reg(REG_PANEL_TYPE);
++	is_color = (panel & 0x04) != 0;
++	is_dual = (panel & 0x02) != 0;
++	is_tft = (panel & 0x01) != 0;
++	crt_enabled = (display & 0x02) != 0;
++	lcd_enabled = (display & 0x01) != 0;
++	lcd_bpp = epson1355_width_tab[is_tft][(panel >> 4) & 3];
++
++	xres = (epson1355_read_reg(REG_HORZ_DISP_WIDTH) + 1) * 8;
++	yres = (epson1355_read_reg16(REG_VERT_DISP_HEIGHT0) + 1) *
++	    ((is_dual && !crt_enabled) ? 2 : 1);
++	offset = epson1355_read_reg16(REG_MEM_ADDR_OFFSET0) & 0x7ff;
++	xres_virtual = offset * 16 / bpp;
++	yres_virtual = fix->smem_len / (offset * 2);
++
++	var->xres = xres;
++	var->yres = yres;
++	var->xres_virtual = xres_virtual;
++	var->yres_virtual = yres_virtual;
++	var->xoffset = var->yoffset = 0;
+ 
+-	/* reading is terribly slow for us */
+-#if 0 /* XXX: need to work out why this doesn't work */
+-	e1355_dispsw.bmove = fbcon_redraw_bmove;
++	fix->line_length = offset * 2;
++
++	fix->xpanstep = 0;	/* no pan yet */
++	fix->ypanstep = 1;
++	fix->ywrapstep = 0;
++	fix->accel = FB_ACCEL_NONE;
++
++	var->grayscale = !is_color;
++
++#ifdef DEBUG
++	printk(KERN_INFO
++	       "epson1355fb: xres=%d, yres=%d, "
++	       "is_color=%d, is_dual=%d, is_tft=%d\n",
++	       xres, yres, is_color, is_dual, is_tft);
++	printk(KERN_INFO
++	       "epson1355fb: bpp=%d, lcd_bpp=%d, "
++	       "crt_enabled=%d, lcd_enabled=%d\n",
++	       bpp, lcd_bpp, crt_enabled, lcd_enabled);
+ #endif
+ }
+ 
+-/* ------------ Interfaces to hardware functions ------------ */
+ 
++static void clearfb16(struct fb_info *info)
++{
++	u16 *dst = (u16 *) info->screen_base;
++	unsigned long n = info->fix.smem_len;
+ 
+-struct fbgen_hwswitch e1355_switch = {
+-	.detect =	e1355_detect,
+-	.encode_fix =	e1355_encode_fix,
+-	.decode_var =	e1355_decode_var,
+-	.encode_var =	e1355_encode_var,
+-	.get_par =	e1355_get_par,
+-	.set_par =	e1355_set_par,
+-	.getcolreg =	e1355_getcolreg,
+-	.pan_display =	e1355_pan_display,
+-	.blank =	e1355_blank,
+-	.set_disp =	e1355_set_disp,
+-};
++	while (n > 1) {
++		fb_writew(0, dst);
++		dst++, n -= 2;
++	}
+ 
++	if (n)
++		fb_writeb(0, dst);
++}
+ 
+-/* ------------ Hardware Independent Functions ------------ */
++static void epson1355fb_deinit(void);
+ 
++int __init epson1355fb_init(void)
++{
++	u8 revision;
++	int rc = 0;
+ 
+-static struct fb_ops e1355fb_ops = {
+-	.owner =	THIS_MODULE,
+-	.fb_get_fix =	fbgen_get_fix,
+-	.fb_get_var =	fbgen_get_var,
+-	.fb_set_var =	fbgen_set_var,
+-	.fb_get_cmap =	fbgen_get_cmap,
+-	.fb_set_cmap =	gen_set_cmap,
+-	.fb_setcolreg =	e1355fb_setcolreg,
+-	.fb_pan_display =fbgen_pan_display,
+-	.fb_blank =	fbgen_blank,
+-};
++	if (!request_mem_region
++	    (EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN,
++	     "S1D13505 registers")) {
++		printk(KERN_ERR "epson1355fb: unable to reserve "
++		       "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS);
++		rc = -EBUSY;
++		goto bail;
++	}
+ 
+-static struct e1355fb_info fb_info;
++	if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN,
++				"S1D13505 framebuffer")) {
++		printk(KERN_ERR "epson1355fb: unable to reserve "
++		       "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS);
++		rc = -EBUSY;
++		goto bail;
++	}
++
++	par.reg_addr = (unsigned long)
++	    ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
++	if (!par.reg_addr) {
++		printk(KERN_ERR "epson1355fb: unable to map registers\n");
++		rc = -ENOMEM;
++		goto bail;
++	}
++
++	info.screen_base =
++	    ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
++	if (!info.screen_base) {
++		printk(KERN_ERR
++		       "epson1355fb: unable to map framebuffer\n");
++		rc = -ENOMEM;
++		goto bail;
++	}
++
++	revision = epson1355_read_reg(REG_REVISION_CODE);
++	if ((revision >> 2) != 3) {
++		printk(KERN_INFO "epson1355fb: epson1355 not found\n");
++		rc = -ENODEV;
++		goto bail;
++	}
++
++	info.fix.mmio_start = EPSON1355FB_REGS_PHYS;
++	info.fix.mmio_len = EPSON1355FB_REGS_LEN;
++	info.fix.smem_start = EPSON1355FB_FB_PHYS;
++	info.fix.smem_len = get_fb_size(&info);
++
++	printk(KERN_INFO
++	       "epson1355fb: regs mapped at 0x%lx, fb %d KiB mapped at 0x%p\n",
++	       par.reg_addr, info.fix.smem_len / 1024, info.screen_base);
++
++	strcpy(info.fix.id, "S1D13505");
++	info.par = &par;
++	info.node = NODEV;
++	info.fbops = &epson1355fb_fbops;
++	info.flags = FBINFO_FLAG_DEFAULT;
++
++	/* we expect the boot loader to have initialized the chip
++	   with appropriate parameters from which we can determinte
++	   the flavor of lcd panel attached */
++	fetch_hw_state(&info);
++
++	/* turn this puppy on ... */
++	clearfb16(&info);
++	backlight_enable(1);
++	lcd_enable(1);
++
++	if (register_framebuffer(&info) < 0) {
++		rc = -EINVAL;
++		goto bail;
++	}
++
++	printk(KERN_INFO "fb%d: %s frame buffer device\n",
++	       minor(info.node), info.fix.id);
+ 
+-int __init e1355fb_setup(char *str)
+-{
+ 	return 0;
++
++      bail:
++	epson1355fb_deinit();
++	return rc;
+ }
+ 
+-int __init e1355fb_init(void)
++static void epson1355fb_deinit(void)
+ {
+-	fb_info.gen.fbhw = &e1355_switch;
+-	fb_info.gen.fbhw->detect();
+-	strcpy(fb_info.gen.info.modename, "SED1355");
+-	fb_info.gen.info.changevar = NULL;
+-	fb_info.gen.info.fbops = &e1355fb_ops;
+-	fb_info.gen.info.screen_base = (void *)E1355_FB_BASE;
+-	fb_info.gen.currcon = -1;
+-	fb_info.gen.info.disp = &disp;
+-	fb_info.gen.parsize = sizeof(struct e1355_par);
+-	fb_info.gen.info.switch_con = &fbgen_switch;
+-	fb_info.gen.info.updatevar = &fbgen_update_var;
+-	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+-	/* This should give a reasonable default video mode */
+-	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+-	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+-	fbgen_set_disp(-1, &fb_info.gen);
+-	if (disp.var.bits_per_pixel > 1) 
+-		do_install_cmap(0, &fb_info.gen);
+-	if (register_framebuffer(&fb_info.gen.info) < 0)
+-		return -EINVAL;
+-	printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.gen.info.node,
+-	       fb_info.gen.info.modename);
++	fb_dealloc_cmap(&info.cmap);
+ 
+-	return 0;
++	if (info.screen_base)
++		iounmap(info.screen_base);
++	if (par.reg_addr)
++		iounmap((void *) par.reg_addr);
++
++	release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
++	release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
+ }
+ 
++static void __exit epson1355fb_cleanup(void)
++{
++	backlight_enable(0);
++	lcd_enable(0);
+ 
+-    /*
+-     *  Cleanup
+-     */
+-
+-void e1355fb_cleanup(struct fb_info *info)
+-{
+-	/*
+-	 *  If your driver supports multiple boards, you should unregister and
+-	 *  clean up all instances.
+-	 */
+-	
+-	unregister_framebuffer(info);
+-	/* ... */
++	unregister_framebuffer(&info);
++	epson1355fb_deinit();
+ }
+ 
++/* ------------------------------------------------------------------------- */
++
++#ifdef MODULE
++module_init(epson1355fb_init);
++#endif
++module_exit(epson1355fb_cleanup);
++
++MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
++MODULE_DESCRIPTION("Framebuffer driver for Epson S1D13505");
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/drivers/video/fbmem.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/fbmem.c	2003-10-05 00:34:22.000000000 -0700
+@@ -25,7 +25,6 @@
+ #include <linux/mman.h>
+ #include <linux/tty.h>
+ #include <linux/init.h>
+-#include <linux/linux_logo.h>
+ #include <linux/proc_fs.h>
+ #ifdef CONFIG_KMOD
+ #include <linux/kmod.h>
+@@ -102,13 +101,13 @@ extern int hgafb_setup(char*);
+ extern int matroxfb_init(void);
+ extern int matroxfb_setup(char*);
+ extern int hpfb_init(void);
+-extern int control_init(void);
+-extern int control_setup(char*);
+-extern int platinum_init(void);
+-extern int platinum_setup(char*);
++extern int controlfb_init(void);
++extern int controlfb_setup(char*);
++extern int platinumfb_init(void);
++extern int platinumfb_setup(char*);
+ extern int valkyriefb_init(void);
+ extern int valkyriefb_setup(char*);
+-extern int chips_init(void);
++extern int chipsfb_init(void);
+ extern int g364fb_init(void);
+ extern int sa1100fb_init(void);
+ extern int fm2fb_init(void);
+@@ -135,14 +134,14 @@ extern int tx3912fb_init(void);
+ extern int tx3912fb_setup(char*);
+ extern int radeonfb_init(void);
+ extern int radeonfb_setup(char*);
+-extern int e1355fb_init(void);
+-extern int e1355fb_setup(char*);
++extern int epson1355fb_init(void);
+ extern int pvr2fb_init(void);
+ extern int pvr2fb_setup(char*);
+ extern int sstfb_init(void);
+ extern int sstfb_setup(char*);
+ extern int i810fb_init(void);
+ extern int i810fb_setup(char*);
++extern int asiliantfb_init(void);
+ extern int ffb_init(void);
+ extern int ffb_setup(char*);
+ extern int cg6_init(void);
+@@ -221,16 +220,16 @@ static struct {
+ 	{ "radeonfb", radeonfb_init, radeonfb_setup },
+ #endif
+ #ifdef CONFIG_FB_CONTROL
+-	{ "controlfb", control_init, control_setup },
++	{ "controlfb", controlfb_init, controlfb_setup },
+ #endif
+ #ifdef CONFIG_FB_PLATINUM
+-	{ "platinumfb", platinum_init, platinum_setup },
++	{ "platinumfb", platinumfb_init, platinumfb_setup },
+ #endif
+ #ifdef CONFIG_FB_VALKYRIE
+ 	{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
+ #endif
+ #ifdef CONFIG_FB_CT65550
+-	{ "chipsfb", chips_init, NULL },
++	{ "chipsfb", chipsfb_init, NULL },
+ #endif
+ #ifdef CONFIG_FB_IMSTT
+ 	{ "imsttfb", imsttfb_init, imsttfb_setup },
+@@ -342,8 +341,8 @@ static struct {
+ #ifdef CONFIG_FB_TX3912
+ 	{ "tx3912fb", tx3912fb_init, tx3912fb_setup },
+ #endif
+-#ifdef CONFIG_FB_E1355
+-	{ "e1355fb", e1355fb_init, e1355fb_setup },
++#ifdef CONFIG_FB_EPSON1355
++	{ "s1d1355fb", epson1355fb_init, NULL },
+ #endif
+ #ifdef CONFIG_FB_PVR2
+ 	{ "pvr2fb", pvr2fb_init, pvr2fb_setup },
+@@ -360,6 +359,10 @@ static struct {
+ #ifdef CONFIG_FB_VOODOO1
+ 	{ "sstfb", sstfb_init, sstfb_setup },
+ #endif
++#ifdef CONFIG_FB_ASILIANT
++	{ "asiliantfb", asiliantfb_init, NULL },
++#endif
++
+ 	/*
+ 	 * Generic drivers that don't use resource management (yet)
+ 	 */
+@@ -409,20 +412,20 @@ void sys_outbuf(u8 *src, u8 *dst, unsign
+ 	memcpy(dst, src, size);
+ }	
+ 
+-void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
+-			u32 s_pitch, u32 height)
++void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++			u32 d_pitch, u32 s_pitch, u32 height)
+ {
+ 	int i;
+ 
+ 	for (i = height; i--; ) {
+-		info->pixmap.outbuf(src, dst, s_pitch);
++		buf->outbuf(src, dst, s_pitch);
+ 		src += s_pitch;
+ 		dst += d_pitch;
+ 	}
+ }
+ 
+-void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
+-			u32 height, u32 mask, u32 shift_high, u32 shift_low,
++void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++			u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
+ 			u32 mod, u32 idx)
+ {
+ 	int i, j;
+@@ -430,21 +433,21 @@ void move_buf_unaligned(struct fb_info *
+ 
+ 	for (i = height; i--; ) {
+ 		for (j = 0; j < idx; j++) {
+-			tmp = info->pixmap.inbuf(dst+j);
++			tmp = buf->inbuf(dst+j);
+ 			tmp &= mask;
+ 			tmp |= *src >> shift_low;
+-			info->pixmap.outbuf(&tmp, dst+j, 1);
++			buf->outbuf(&tmp, dst+j, 1);
+ 			tmp = *src << shift_high;
+-			info->pixmap.outbuf(&tmp, dst+j+1, 1);
++			buf->outbuf(&tmp, dst+j+1, 1);
+ 			src++;
+ 		}
+-		tmp = info->pixmap.inbuf(dst+idx);
++		tmp = buf->inbuf(dst+idx);
+ 		tmp &= mask;
+ 		tmp |= *src >> shift_low;
+-		info->pixmap.outbuf(&tmp, dst+idx, 1);
++		buf->outbuf(&tmp, dst+idx, 1);
+ 		if (shift_high < mod) {
+ 			tmp = *src << shift_high;
+-			info->pixmap.outbuf(&tmp, dst+idx+1, 1);
++			buf->outbuf(&tmp, dst+idx+1, 1);
+ 		}	
+ 		src++;
+ 		dst += d_pitch;
+@@ -455,26 +458,29 @@ void move_buf_unaligned(struct fb_info *
+  * we need to lock this section since fb_cursor
+  * may use fb_imageblit()
+  */
+-u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
++char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+ {
+-	u32 align = info->pixmap.buf_align - 1;
++	u32 align = buf->buf_align - 1;
+ 	u32 offset, count = 1000;
++	char *addr = buf->addr;
+ 
+-	spin_lock(&info->pixmap.lock);
+-	offset = info->pixmap.offset + align;
+-	offset &= ~align;
+-	if (offset + size > info->pixmap.size) {
+-		while (atomic_read(&info->pixmap.count) && count--);
+-		if (info->fbops->fb_sync && 
+-		    info->pixmap.flags & FB_PIXMAP_SYNC)
+-			info->fbops->fb_sync(info);
+-		offset = 0;
++	spin_lock(&buf->lock);
++	if (!(buf->flags & FB_PIXMAP_IO)) {
++		offset = buf->offset + align;
++		offset &= ~align;
++		if (offset + size > buf->size) {
++			while (atomic_read(&buf->count) && count--);
++			if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
++				info->fbops->fb_sync(info);
++			offset = 0;
++		}
++		buf->offset = offset + size;
++		addr += offset;
+ 	}
+-	info->pixmap.offset = offset + size;
+-	atomic_inc(&info->pixmap.count);	
++	atomic_inc(&buf->count);
+ 	smp_mb__after_atomic_inc();
+-	spin_unlock(&info->pixmap.lock);
+-	return offset;
++	spin_unlock(&buf->lock);
++	return addr;
+ }
+ 
+ #ifdef CONFIG_LOGO
+@@ -656,7 +662,7 @@ int fb_prepare_logo(struct fb_info *info
+ 	}
+ 
+ 	/* Return if no suitable logo was found */
+-	fb_logo.logo = fb_find_logo(info->var.bits_per_pixel);
++	fb_logo.logo = find_logo(info->var.bits_per_pixel);
+ 	
+ 	if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
+ 		fb_logo.logo = NULL;
+@@ -726,8 +732,6 @@ int fb_show_logo(struct fb_info *info)
+ 	     x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
+ 		image.dx = x;
+ 		info->fbops->fb_imageblit(info, &image);
+-		//atomic_dec(&info->pixmap.count);
+-		//smp_mb__after_atomic_dec();
+ 	}
+ 	
+ 	if (palette != NULL)
+@@ -1238,6 +1242,22 @@ register_framebuffer(struct fb_info *fb_
+ 		fb_info->pixmap.inbuf = sys_inbuf;
+ 	spin_lock_init(&fb_info->pixmap.lock);
+ 
++	if (fb_info->sprite.addr == NULL) {
++		fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
++		if (fb_info->sprite.addr) {
++			fb_info->sprite.size = FBPIXMAPSIZE;
++			fb_info->sprite.buf_align = 1;
++			fb_info->sprite.scan_align = 1;
++			fb_info->sprite.flags = FB_PIXMAP_IO;
++		}
++	}
++	fb_info->sprite.offset = 0;
++	if (fb_info->sprite.outbuf == NULL)
++		fb_info->sprite.outbuf = sys_outbuf;
++	if (fb_info->sprite.inbuf == NULL)
++		fb_info->sprite.inbuf = sys_inbuf;
++	spin_lock_init(&fb_info->sprite.lock);
++
+ 	registered_fb[i] = fb_info;
+ 
+ 	devfs_mk_cdev(MKDEV(FB_MAJOR, i),
+@@ -1371,6 +1391,33 @@ int __init video_setup(char *options)
+ 
+ __setup("video=", video_setup);
+ 
++static int fbdev_dummy(void)
++{
++	return 0;
++}
++
++#define FBDEV_EMPTY (void *)fbdev_dummy
++
++const struct fb_ops dummy_fbdev = {
++	.fb_open	= FBDEV_EMPTY,
++	.fb_release	= FBDEV_EMPTY,
++	.fb_read	= FBDEV_EMPTY,
++	.fb_write	= FBDEV_EMPTY,
++	.fb_check_var	= FBDEV_EMPTY,
++	.fb_set_par	= FBDEV_EMPTY,
++	.fb_setcolreg	= FBDEV_EMPTY,
++	.fb_blank	= FBDEV_EMPTY,
++	.fb_pan_display	= FBDEV_EMPTY,
++	.fb_fillrect	= FBDEV_EMPTY,
++	.fb_copyarea	= FBDEV_EMPTY,
++	.fb_imageblit	= FBDEV_EMPTY,
++	.fb_cursor	= FBDEV_EMPTY,
++	.fb_rotate	= FBDEV_EMPTY,
++	.fb_sync	= FBDEV_EMPTY,
++	.fb_ioctl	= FBDEV_EMPTY,
++	.fb_mmap	= FBDEV_EMPTY,
++};
++
+     /*
+      *  Visible symbols for modules
+      */
+--- linux-2.6.0-test6/drivers/video/g364fb.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/drivers/video/g364fb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -127,20 +127,55 @@ static struct fb_ops g364fb_ops = {
+ 
+ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
++
++	/* Turn the cursor off before we start changing it. */
++	*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
++
++	if (cursor->set & FB_CUR_SETHOT)
++		info->cursor.hot = cursor->hot;
+ 	
+-	switch (cursor->enable) {
+-	case CM_ERASE:
+-		*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
+-		break;
++	if (cursor->set & FB_CUR_SETPOS) {
++		unsigned int tmp;
+ 
+-	case CM_MOVE:
+-	case CM_DRAW:
+-		*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
+-		*(unsigned int *) CURS_POS_REG =
+-		    ((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
+-						  info->var.yoffset);
+-		break;
++		info->cursor.image.dx = cursor->image.dx;
++		info->cursor.image.dy = cursor->image.dy;
++
++		tmp = cursor->image.dy - info->var.yoffset;
++		tmp |= (cursor->image.dx - info->var.xoffset) << 12;
++
++		*(unsigned int *) CURS_POS_REG = tmp;
++	}
++
++	if (cursor->set & FB_CUR_SETSIZE) {
++		info->cursor.image.height = cursor->image.height;
++		info->cursor.image.width = cursor->image.width;
++
++	 	/* set the whole cursor to transparent */
++		for (i = 0; i < 512; i++)
++			*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
+ 	}
++
++	if (cursor->set & FB_CUR_SETCMAP) {
++		volatile unsigned int *curs_pal_ptr =
++	    			(volatile unsigned int *) CURS_PAL_REG;
++
++		/* setup cursor */
++		curs_pal_ptr[0] |= 0x00ffffff;
++		curs_pal_ptr[2] |= 0x00ffffff;
++		curs_pal_ptr[4] |= 0x00ffffff;
++	}
++
++	if (cursor->set & FB_CUR_SETSHAPE) {
++		/*
++	 	 * switch the last two lines to cursor palette 3
++	 	 * we assume here, that FONTSIZE_X is 8
++	 	 */
++		*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
++		*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
++	}
++
++	if (info->cursor.enable)
++		*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
+ 	return 0;
+ }
+ 
+@@ -196,10 +231,6 @@ static int g364fb_setcolreg(u_int regno,
+  */
+ int __init g364fb_init(void)
+ {
+-	volatile unsigned int *pal_ptr =
+-	    (volatile unsigned int *) CLR_PAL_REG;
+-	volatile unsigned int *curs_pal_ptr =
+-	    (volatile unsigned int *) CURS_PAL_REG;
+ 	int mem, i, j;
+ 
+ 	/* TBD: G364 detection */
+@@ -212,23 +243,6 @@ int __init g364fb_init(void)
+ 	    (*((volatile unsigned int *) VDISPLAY_REG) & 0x00ffffff) / 2;
+ 	*(volatile unsigned int *) CTLA_REG |= ENABLE_VTG;
+ 
+-	/* setup cursor */
+-	curs_pal_ptr[0] |= 0x00ffffff;
+-	curs_pal_ptr[2] |= 0x00ffffff;
+-	curs_pal_ptr[4] |= 0x00ffffff;
+-
+-	/*
+-	 * first set the whole cursor to transparent
+-	 */
+-	for (i = 0; i < 512; i++)
+-		*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
+-
+-	/*
+-	 * switch the last two lines to cursor palette 3
+-	 * we assume here, that FONTSIZE_X is 8
+-	 */
+-	*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
+-	*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
+ 	fb_var.xres_virtual = fbvar.xres;
+ 	fb_fix.line_length = (xres / 8) * fb_var.bits_per_pixel;
+ 	fb_fix.smem_start = 0x40000000;	/* physical address */
+--- linux-2.6.0-test6/drivers/video/i810/Makefile	2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/video/i810/Makefile	2003-10-05 00:34:22.000000000 -0700
+@@ -1,16 +1,9 @@
+ #
+ # Makefile for the Intel 810/815 framebuffer driver
+ #
+-# Note! Dependencies are done automagically by 'make dep', which also
+-# removes any old dependencies. DON'T put your own dependencies here
+-# unless it's something special (ie not a .c file).
+-#
+-# Note 2! The CFLAGS definitions are now in the main makefile...
+-
+ 
+ obj-$(CONFIG_FB_I810)		+= i810fb.o
+ 
+-
+ i810fb-objs                     := i810_main.o i810_accel.o
+ 
+ ifdef CONFIG_FB_I810_GTF
+--- linux-2.6.0-test6/drivers/video/imsttfb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/imsttfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1495,6 +1495,8 @@ imsttfb_probe(struct pci_dev *pdev, cons
+ 		default:
+ 			printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
+ 					 "contact maintainer.\n", pdev->device);
++			release_mem_region(addr, size);
++			kfree(info);
+ 			return -ENODEV;
+ 	}
+ 
+--- linux-2.6.0-test6/drivers/video/Kconfig	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/video/Kconfig	2003-10-05 00:34:22.000000000 -0700
+@@ -188,19 +188,19 @@ config FB_AMIGA_AGA
+ 	  otherwise say N.
+ 
+ config FB_CYBER
+-	tristate "Amiga CyberVision support"
+-	depends on FB && ZORRO
++	tristate "Amiga CyberVision 64 support"
++	depends on FB && ZORRO && BROKEN
+ 	help
+ 	  This enables support for the Cybervision 64 graphics card from
+ 	  Phase5. Please note that its use is not all that intuitive (i.e. if
+ 	  you have any questions, be sure to ask!). Say N unless you have a
+ 	  Cybervision 64 or plan to get one before you next recompile the
+ 	  kernel. Please note that this driver DOES NOT support the
+-	  Cybervision 64 3D card, as they use incompatible video chips.
++	  Cybervision 64/3D card, as they use incompatible video chips.
+ 
+ config FB_VIRGE
+-	bool "Amiga CyberVision3D support "
+-	depends on FB && ZORRO
++	bool "Amiga CyberVision 64/3D support "
++	depends on FB && ZORRO && BROKEN
+ 	help
+ 	  This enables support for the Cybervision 64/3D graphics card from
+ 	  Phase5. Please note that its use is not all that intuitive (i.e. if
+@@ -210,8 +210,8 @@ config FB_VIRGE
+ 	  Cybervision 64 card, as they use incompatible video chips.
+ 
+ config FB_RETINAZ3
+-	tristate "Amiga RetinaZ3 support"
+-	depends on FB && ZORRO
++	tristate "Amiga Retina Z3 support"
++	depends on FB && ZORRO && BROKEN
+ 	help
+ 	  This enables support for the Retina Z3 graphics card. Say N unless
+ 	  you have a Retina Z3 or plan to get one before you next recompile
+@@ -226,7 +226,7 @@ config FB_FM2
+ 
+ config FB_ATARI
+ 	bool "Atari native chipset support"
+-	depends on FB && ATARI
++	depends on FB && ATARI && BROKEN
+ 	help
+ 	  This is the frame buffer device driver for the builtin graphics
+ 	  chipset found in Ataris.
+@@ -266,6 +266,10 @@ config FB_CT65550
+ 	  This is the frame buffer device driver for the Chips & Technologies
+ 	  65550 graphics chip in PowerBooks.
+ 
++config FB_ASILIANT
++	bool "Chips 69000 display support"
++	depends on FB && PCI
++
+ config FB_IMSTT
+ 	bool "IMS Twin Turbo display support"
+ 	depends on FB && PCI
+@@ -367,7 +371,7 @@ config BUS_I2C
+ 
+ config FB_SUN3
+ 	bool "Sun3 framebuffer support"
+-	depends on FB && (SUN3 || SUN3X)
++	depends on FB && (SUN3 || SUN3X) && BROKEN
+ 
+ config FB_BW2
+ 	bool "BWtwo support"
+@@ -414,35 +418,15 @@ config FB_PVR2_DEBUG
+ 	  messages. Most people will want to say N here. If unsure, you will
+ 	  also want to say N.
+ 
+-config FB_E1355
++config FB_EPSON1355
+ 	bool "Epson 1355 framebuffer support"
+-	depends on FB && SUPERH
++	depends on FB && (SUPERH || ARCH_CEIVA)
+ 	help
+ 	  Build in support for the SED1355 Epson Research Embedded RAMDAC
+ 	  LCD/CRT Controller (since redesignated as the S1D13505) as a
+ 	  framebuffer.  Product specs at
+ 	  <http://www.erd.epson.com/vdc/html/products.htm>.
+ 
+-config E1355_REG_BASE
+-	hex "Register Base Address"
+-	depends on FB_E1355
+-	default "a8000000"
+-	help
+-	  Epson SED1355/S1D13505 LCD/CRT controller register base address.
+-	  See the manuals at
+-	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
+-	  discussion.
+-
+-config E1355_FB_BASE
+-	hex "Framebuffer Base Address"
+-	depends on FB_E1355
+-	default "a8200000"
+-	help
+-	  Epson SED1355/S1D13505 LCD/CRT controller memory base address.  See
+-	  the manuals at
+-	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
+-	  discussion.
+-
+ config FB_RIVA
+ 	tristate "nVidia Riva support"
+ 	depends on FB && PCI
+@@ -703,26 +687,40 @@ config FB_ATY_XL_INIT
+ 	  Say Y here to support booting a Rage XL without BIOS support.
+ 
+ config FB_SIS
+-	tristate "SIS acceleration"
++	tristate "SiS acceleration"
+ 	depends on FB && PCI
+ 	help
+-	  This is the frame buffer device driver for the SiS 630 and 640 Super
+-	  Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
++	  This is the frame buffer device driver for the SiS 300, 315 and Xabre
++	  series VGA controller.
++
++	  Specs available at <http://www.sis.com.tw/>.
++
++	  See <http://www.winischhofer.net/linuxsisvga.shtml> for
++	  documentation and updates.
++
++	  The driver is also available as a module ( = code which can be
++	  inserted and removed from the running kernel whenever you want). The
++	  module will be called sisfb. If you want to compile it as a
++	  module, say M here and read Documentation/modules.txt.
+ 
+ config FB_SIS_300
+-	bool "SIS 630/540/730 support"
++	bool "SIS 300 series support"
+ 	depends on FB_SIS
+ 	help
+-	  This is the frame buffer device driver for the SiS 630 and related
+-	  Super Socket 7 UMA cards.  Specs available at
+-	  <http://www.sis.com.tw/>.
++	  This is the frame buffer device driver for the SiS 300 series VGA
++	  controllers. This includes the 300, 540, 630, 730.
++	  Documentation and updates available at
++	  http://www.winischhofer.net/linuxsisvga.shtml
+ 
+ config FB_SIS_315
+-	bool "SIS 315H/315 support"
++	bool "SIS 315/Xabre support"
+ 	depends on FB_SIS
+ 	help
+-	  This is the frame buffer device driver for the SiS 315 graphics
+-	  card.  Specs available at <http://www.sis.com.tw/>.
++	  This is the frame buffer device driver for the SiS 315 and Xabre
++	  series VGA controllers. This includes the 315, 315H, 315PRO, 650,
++	  651, M650, 652, M652, 740, 330 (Xabre), 660, M660, 760, M760.
++	  Documentation and updates available at
++	  http://www.winischhofer.net/linuxsisvga.shtml
+ 
+ config FB_NEOMAGIC
+ 	tristate "NeoMagic display support"
+--- linux-2.6.0-test6/drivers/video/logo/logo.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/drivers/video/logo/logo.c	2003-10-05 00:34:22.000000000 -0700
+@@ -32,8 +32,7 @@ extern const struct linux_logo logo_supe
+ extern const struct linux_logo logo_superh_vga16;
+ extern const struct linux_logo logo_superh_clut224;
+ 
+-
+-const struct linux_logo *fb_find_logo(int depth)
++const struct linux_logo *find_logo(int depth)
+ {
+ 	const struct linux_logo *logo = 0;
+ 
+--- linux-2.6.0-test6/drivers/video/Makefile	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/Makefile	2003-10-05 00:34:22.000000000 -0700
+@@ -22,7 +22,7 @@ obj-$(CONFIG_FB_Q40)              += q40
+ obj-$(CONFIG_FB_ATARI)            += atafb.o
+ obj-$(CONFIG_FB_68328)            += 68328fb.o
+ obj-$(CONFIG_FB_RADEON)		  += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o vgastate.o
+ obj-$(CONFIG_FB_IGA)              += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_CONTROL)          += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+@@ -68,9 +68,10 @@ obj-$(CONFIG_FB_HGA)              += hga
+ obj-$(CONFIG_FB_SA1100)           += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_VIRTUAL)          += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
+ obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_E1355)            += epson1355fb.o
+-obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_EPSON1355)        += epson1355fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbcillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_ASILIANT)         += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ 
+ obj-$(CONFIG_FB_FFB)               += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+ obj-$(CONFIG_FB_CG6)               += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+--- linux-2.6.0-test6/drivers/video/neofb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/neofb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -81,9 +81,10 @@ extern int tosh_smm(SMMRegisters *regs);
+ #include <asm/mtrr.h>
+ #endif
+ 
++#include <video/vga.h>
+ #include <video/neomagic.h>
+ 
+-#define NEOFB_VERSION "0.4.1"
++#define NEOFB_VERSION "0.4.2"
+ 
+ /* --------------------------------------------------------------------- */
+ 
+@@ -152,6 +153,16 @@ static biosMode bios32[] = {
+ };
+ #endif
+ 
++static inline u32 read_le32(int regindex, const struct neofb_par *par)
++{
++	return readl(par->neo2200 + par->cursorOff + regindex);
++}
++
++static inline void write_le32(int regindex, u32 val, const struct neofb_par *par)
++{
++	writel(val, par->neo2200 + par->cursorOff + regindex);
++}
++
+ static int neoFindMode(int xres, int yres, int depth)
+ {
+ 	int xres_s;
+@@ -363,44 +374,61 @@ static int vgaHWInit(const struct fb_var
+ 	par->Attribute[18] = 0x0F;
+ 	par->Attribute[19] = 0x00;
+ 	par->Attribute[20] = 0x00;
+-
+ 	return 0;
+ }
+ 
+-static void vgaHWLock(void)
++static void vgaHWLock(struct vgastate *state)
+ {
+ 	/* Protect CRTC[0-7] */
+-	VGAwCR(0x11, VGArCR(0x11) | 0x80);
++	vga_wcrt(state->vgabase, 0x11, vga_rcrt(state->vgabase, 0x11) | 0x80);
+ }
+ 
+ static void vgaHWUnlock(void)
+ {
+ 	/* Unprotect CRTC[0-7] */
+-	VGAwCR(0x11, VGArCR(0x11) & ~0x80);
++	vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) & ~0x80);
+ }
+ 
+-static void neoLock(void)
++static void neoLock(struct vgastate *state)
+ {
+-	VGAwGR(0x09, 0x00);
+-	vgaHWLock();
++	vga_wgfx(state->vgabase, 0x09, 0x00);
++	vgaHWLock(state);
+ }
+ 
+ static void neoUnlock(void)
+ {
+ 	vgaHWUnlock();
+-	VGAwGR(0x09, 0x26);
++	vga_wgfx(NULL, 0x09, 0x26);
+ }
+ 
+ /*
+- * vgaHWSeqReset
+- *      perform a sequencer reset.
++ * VGA Palette management
+  */
+-void vgaHWSeqReset(int start)
++static int paletteEnabled = 0;
++
++inline void VGAenablePalette(void)
+ {
+-	if (start)
+-		VGAwSEQ(0x00, 0x01);	/* Synchronous Reset */
++	vga_r(NULL, VGA_IS1_RC);
++	vga_w(NULL, VGA_ATT_W, 0x00);
++	paletteEnabled = 1;
++}
++
++inline void VGAdisablePalette(void)
++{
++	vga_r(NULL, VGA_IS1_RC);
++	vga_w(NULL, VGA_ATT_W, 0x20);
++	paletteEnabled = 0;
++}
++
++inline void VGAwATTR(u8 index, u8 value)
++{
++	if (paletteEnabled)
++		index &= ~0x20;
+ 	else
+-		VGAwSEQ(0x00, 0x03);	/* End Reset */
++		index |= 0x20;
++
++	vga_r(NULL, VGA_IS1_RC);
++	vga_wattr(NULL, index, value);
+ }
+ 
+ void vgaHWProtect(int on)
+@@ -411,21 +439,18 @@ void vgaHWProtect(int on)
+ 		/*
+ 		 * Turn off screen and disable sequencer.
+ 		 */
+-		tmp = VGArSEQ(0x01);
+-
+-		vgaHWSeqReset(1);	/* start synchronous reset */
+-		VGAwSEQ(0x01, tmp | 0x20);	/* disable the display */
++		tmp = vga_rseq(NULL, 0x01);
++		vga_wseq(NULL, 0x00, 0x01);		/* Synchronous Reset */
++		vga_wseq(NULL, 0x01, tmp | 0x20);	/* disable the display */
+ 
+ 		VGAenablePalette();
+ 	} else {
+ 		/*
+ 		 * Reenable sequencer, then turn on screen.
+ 		 */
+-
+-		tmp = VGArSEQ(0x01);
+-
+-		VGAwSEQ(0x01, tmp & ~0x20);	/* reenable display */
+-		vgaHWSeqReset(0);	/* clear synchronousreset */
++		tmp = vga_rseq(NULL, 0x01);
++		vga_wseq(NULL, 0x01, tmp & ~0x20);	/* reenable display */
++		vga_wseq(NULL, 0x00, 0x03);		/* clear synchronousreset */
+ 
+ 		VGAdisablePalette();
+ 	}
+@@ -436,19 +461,19 @@ static void vgaHWRestore(const struct fb
+ {
+ 	int i;
+ 
+-	VGAwMISC(par->MiscOutReg);
++	vga_w(NULL, VGA_MIS_W, par->MiscOutReg);
+ 
+ 	for (i = 1; i < 5; i++)
+-		VGAwSEQ(i, par->Sequencer[i]);
++		vga_wseq(NULL, i, par->Sequencer[i]);
+ 
+ 	/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
+-	VGAwCR(17, par->CRTC[17] & ~0x80);
++	vga_wcrt(NULL, 17, par->CRTC[17] & ~0x80);
+ 
+ 	for (i = 0; i < 25; i++)
+-		VGAwCR(i, par->CRTC[i]);
++		vga_wcrt(NULL, i, par->CRTC[i]);
+ 
+ 	for (i = 0; i < 9; i++)
+-		VGAwGR(i, par->Graphics[i]);
++		vga_wgfx(NULL, i, par->Graphics[i]);
+ 
+ 	VGAenablePalette();
+ 
+@@ -535,6 +560,36 @@ static inline void neo2200_accel_init(st
+ /* --------------------------------------------------------------------- */
+ 
+ static int
++neofb_open(struct fb_info *info, int user)
++{
++	struct neofb_par *par = (struct neofb_par *) info->par;
++	int cnt = atomic_read(&par->ref_count);
++
++	if (cnt) {
++		memset(&par->state, 0, sizeof(struct vgastate));
++		par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
++		save_vga(&par->state);
++	}
++	atomic_inc(&par->ref_count);
++	return 0;
++}
++
++static int
++neofb_release(struct fb_info *info, int user)
++{
++	struct neofb_par *par = (struct neofb_par *) info->par;
++	int cnt = atomic_read(&par->ref_count);
++
++	if (!cnt)
++		return -EINVAL;
++	if (cnt == 1) {
++		restore_vga(&par->state);
++	}
++	atomic_dec(&par->ref_count);
++	return 0;
++}
++
++static int
+ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
+ 	struct neofb_par *par = (struct neofb_par *) info->par;
+@@ -981,13 +1036,13 @@ static int neofb_set_par(struct fb_info 
+ 	}
+ 
+ 	/* alread unlocked above */
+-	/* BOGUS  VGAwGR (0x09, 0x26); */
++	/* BOGUS  vga_wgfx(NULL, 0x09, 0x26); */
+ 
+ 	/* don't know what this is, but it's 0 from bootup anyway */
+-	VGAwGR(0x15, 0x00);
++	vga_wgfx(NULL, 0x15, 0x00);
+ 
+ 	/* was set to 0x01 by my bios in text and vesa modes */
+-	VGAwGR(0x0A, par->GeneralLockReg);
++	vga_wgfx(NULL, 0x0A, par->GeneralLockReg);
+ 
+ 	/*
+ 	 * The color mode needs to be set before calling vgaHWRestore
+@@ -996,7 +1051,7 @@ static int neofb_set_par(struct fb_info 
+ 	 * NOTE: Make sure we don't change bits make sure we don't change
+ 	 * any reserved bits.
+ 	 */
+-	temp = VGArGR(0x90);
++	temp = vga_rgfx(NULL, 0x90);
+ 	switch (info->fix.accel) {
+ 	case FB_ACCEL_NEOMAGIC_NM2070:
+ 		temp &= 0xF0;	/* Save bits 7:4 */
+@@ -1015,7 +1070,7 @@ static int neofb_set_par(struct fb_info 
+ 		break;
+ 	}
+ 
+-	VGAwGR(0x90, temp);
++	vga_wgfx(NULL, 0x90, temp);
+ 
+ 	/*
+ 	 * In some rare cases a lockup might occur if we don't delay
+@@ -1027,9 +1082,9 @@ static int neofb_set_par(struct fb_info 
+ 	 * Disable horizontal and vertical graphics and text expansions so
+ 	 * that vgaHWRestore works properly.
+ 	 */
+-	temp = VGArGR(0x25);
++	temp = vga_rgfx(NULL, 0x25);
+ 	temp &= 0x39;
+-	VGAwGR(0x25, temp);
++	vga_wgfx(NULL, 0x25, temp);
+ 
+ 	/*
+ 	 * Sleep for 200ms to make sure that the two operations above have
+@@ -1041,19 +1096,18 @@ static int neofb_set_par(struct fb_info 
+ 	 * This function handles restoring the generic VGA registers.  */
+ 	vgaHWRestore(info, par);
+ 
+-
+-	VGAwGR(0x0E, par->ExtCRTDispAddr);
+-	VGAwGR(0x0F, par->ExtCRTOffset);
+-	temp = VGArGR(0x10);
++	vga_wgfx(NULL, 0x0E, par->ExtCRTDispAddr);
++	vga_wgfx(NULL, 0x0F, par->ExtCRTOffset);
++	temp = vga_rgfx(NULL, 0x10);
+ 	temp &= 0x0F;		/* Save bits 3:0 */
+ 	temp |= (par->SysIfaceCntl1 & ~0x0F);	/* VESA Bios sets bit 1! */
+-	VGAwGR(0x10, temp);
++	vga_wgfx(NULL, 0x10, temp);
+ 
+-	VGAwGR(0x11, par->SysIfaceCntl2);
+-	VGAwGR(0x15, 0 /*par->SingleAddrPage */ );
+-	VGAwGR(0x16, 0 /*par->DualAddrPage */ );
++	vga_wgfx(NULL, 0x11, par->SysIfaceCntl2);
++	vga_wgfx(NULL, 0x15, 0 /*par->SingleAddrPage */ );
++	vga_wgfx(NULL, 0x16, 0 /*par->DualAddrPage */ );
+ 
+-	temp = VGArGR(0x20);
++	temp = vga_rgfx(NULL, 0x20);
+ 	switch (info->fix.accel) {
+ 	case FB_ACCEL_NEOMAGIC_NM2070:
+ 		temp &= 0xFC;	/* Save bits 7:2 */
+@@ -1074,79 +1128,78 @@ static int neofb_set_par(struct fb_info 
+ 		temp |= (par->PanelDispCntlReg1 & ~0x98);
+ 		break;
+ 	}
+-	VGAwGR(0x20, temp);
++	vga_wgfx(NULL, 0x20, temp);
+ 
+-	temp = VGArGR(0x25);
++	temp = vga_rgfx(NULL, 0x25);
+ 	temp &= 0x38;		/* Save bits 5:3 */
+ 	temp |= (par->PanelDispCntlReg2 & ~0x38);
+-	VGAwGR(0x25, temp);
++	vga_wgfx(NULL, 0x25, temp);
+ 
+ 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
+-		temp = VGArGR(0x30);
++		temp = vga_rgfx(NULL, 0x30);
+ 		temp &= 0xEF;	/* Save bits 7:5 and bits 3:0 */
+ 		temp |= (par->PanelDispCntlReg3 & ~0xEF);
+-		VGAwGR(0x30, temp);
++		vga_wgfx(NULL, 0x30, temp);
+ 	}
+ 
+-	VGAwGR(0x28, par->PanelVertCenterReg1);
+-	VGAwGR(0x29, par->PanelVertCenterReg2);
+-	VGAwGR(0x2a, par->PanelVertCenterReg3);
++	vga_wgfx(NULL, 0x28, par->PanelVertCenterReg1);
++	vga_wgfx(NULL, 0x29, par->PanelVertCenterReg2);
++	vga_wgfx(NULL, 0x2a, par->PanelVertCenterReg3);
+ 
+ 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
+-		VGAwGR(0x32, par->PanelVertCenterReg4);
+-		VGAwGR(0x33, par->PanelHorizCenterReg1);
+-		VGAwGR(0x34, par->PanelHorizCenterReg2);
+-		VGAwGR(0x35, par->PanelHorizCenterReg3);
++		vga_wgfx(NULL, 0x32, par->PanelVertCenterReg4);
++		vga_wgfx(NULL, 0x33, par->PanelHorizCenterReg1);
++		vga_wgfx(NULL, 0x34, par->PanelHorizCenterReg2);
++		vga_wgfx(NULL, 0x35, par->PanelHorizCenterReg3);
+ 	}
+ 
+ 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160)
+-		VGAwGR(0x36, par->PanelHorizCenterReg4);
++		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
+ 
+ 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
+-		VGAwGR(0x36, par->PanelHorizCenterReg4);
+-		VGAwGR(0x37, par->PanelVertCenterReg5);
+-		VGAwGR(0x38, par->PanelHorizCenterReg5);
++		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
++		vga_wgfx(NULL, 0x37, par->PanelVertCenterReg5);
++		vga_wgfx(NULL, 0x38, par->PanelHorizCenterReg5);
+ 
+ 		clock_hi = 1;
+ 	}
+ 
+ 	/* Program VCLK3 if needed. */
+-	if (par->ProgramVCLK && ((VGArGR(0x9B) != par->VCLK3NumeratorLow)
+-				 || (VGArGR(0x9F) != par->VCLK3Denominator)
+-				 || (clock_hi && ((VGArGR(0x8F) & ~0x0f)
+-						  != (par->
+-						      VCLK3NumeratorHigh &
++	if (par->ProgramVCLK && ((vga_rgfx(NULL, 0x9B) != par->VCLK3NumeratorLow)
++				 || (vga_rgfx(NULL, 0x9F) != par->VCLK3Denominator)
++				 || (clock_hi && ((vga_rgfx(NULL, 0x8F) & ~0x0f)
++						  != (par->VCLK3NumeratorHigh &
+ 						      ~0x0F))))) {
+-		VGAwGR(0x9B, par->VCLK3NumeratorLow);
++		vga_wgfx(NULL, 0x9B, par->VCLK3NumeratorLow);
+ 		if (clock_hi) {
+-			temp = VGArGR(0x8F);
++			temp = vga_rgfx(NULL, 0x8F);
+ 			temp &= 0x0F;	/* Save bits 3:0 */
+ 			temp |= (par->VCLK3NumeratorHigh & ~0x0F);
+-			VGAwGR(0x8F, temp);
++			vga_wgfx(NULL, 0x8F, temp);
+ 		}
+-		VGAwGR(0x9F, par->VCLK3Denominator);
++		vga_wgfx(NULL, 0x9F, par->VCLK3Denominator);
+ 	}
+ 
+ 	if (par->biosMode)
+-		VGAwCR(0x23, par->biosMode);
++		vga_wcrt(NULL, 0x23, par->biosMode);
+ 
+-	VGAwGR(0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
++	vga_wgfx(NULL, 0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
+ 
+ 	/* Program vertical extension register */
+ 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
+ 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
+-		VGAwCR(0x70, par->VerticalExt);
++		vga_wcrt(NULL, 0x70, par->VerticalExt);
+ 	}
+ 
+ 	vgaHWProtect(0);	/* Turn on screen */
+ 
+ 	/* Calling this also locks offset registers required in update_start */
+-	neoLock();
++	neoLock(&par->state);
+ 
+ 	info->fix.line_length =
+ 	    info->var.xres_virtual * (info->var.bits_per_pixel >> 3);
+@@ -1167,6 +1220,8 @@ static int neofb_set_par(struct fb_info 
+ static void neofb_update_start(struct fb_info *info,
+ 			       struct fb_var_screeninfo *var)
+ {
++	struct neofb_par *par = (struct neofb_par *) info->par;
++	struct vgastate *state = &par->state;
+ 	int oldExtCRTDispAddr;
+ 	int Base;
+ 
+@@ -1180,18 +1235,18 @@ static void neofb_update_start(struct fb
+ 	/*
+ 	 * These are the generic starting address registers.
+ 	 */
+-	VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
+-	VGAwCR(0x0D, (Base & 0x00FF));
++	vga_wcrt(state->vgabase, 0x0C, (Base & 0x00FF00) >> 8);
++	vga_wcrt(state->vgabase, 0x0D, (Base & 0x00FF));
+ 
+ 	/*
+ 	 * Make sure we don't clobber some other bits that might already
+ 	 * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
+ 	 * be needed.
+ 	 */
+-	oldExtCRTDispAddr = VGArGR(0x0E);
+-	VGAwGR(0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
++	oldExtCRTDispAddr = vga_rgfx(NULL, 0x0E);
++	vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
+ 
+-	neoLock();
++	neoLock(state);
+ }
+ 
+ /*
+@@ -1353,7 +1408,7 @@ neo2200_fillrect(struct fb_info *info, c
+ 	}
+ 
+ 	par->neo2200->dstStart =
+-	    dst * ((info->var.bits_per_pixel + 7) / 8);
++	    dst * ((info->var.bits_per_pixel + 7) >> 3);
+ 	par->neo2200->xyExt =
+ 	    (rect->height << 16) | (rect->width & 0xffff);
+ }
+@@ -1361,24 +1416,20 @@ neo2200_fillrect(struct fb_info *info, c
+ static void
+ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+ {
+-	struct neofb_par *par = (struct neofb_par *) info->par;
+ 	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
++	struct neofb_par *par = (struct neofb_par *) info->par;
+ 	u_long src, dst, bltCntl;
+ 
+ 	bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
+ 
+-	if (sy < dy) {
++	if ((dy > sy) || ((dy == sy) && (dx > sx))) {
++		/* Start with the lower right corner */
+ 		sy += (area->height - 1);
+ 		dy += (area->height - 1);
+-
+-		bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
+-	}
+-
+-	if (area->sx < area->dx) {
+ 		sx += (area->width - 1);
+ 		dx += (area->width - 1);
+ 
+-		bltCntl |= NEO_BC0_X_DEC;
++		bltCntl |= NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
+ 	}
+ 
+ 	src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
+@@ -1496,8 +1547,60 @@ neofb_sync(struct fb_info *info)
+ 	return 0;		
+ }
+ 
++static int
++neofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
++{
++	struct neofb_par *par = (struct neofb_par *) info->par;
++
++	/* Disable cursor */
++	write_le32(NEOREG_CURSCNTL, ~NEO_CURS_ENABLE, par);
++
++	if (cursor->set & FB_CUR_SETPOS) {
++		u32 x = cursor->image.dx;
++		u32 y = cursor->image.dy;
++
++		info->cursor.image.dx = x;
++		info->cursor.image.dy = y;
++		write_le32(NEOREG_CURSX, x, par);
++		write_le32(NEOREG_CURSY, y, par);
++	}
++
++	if (cursor->set & FB_CUR_SETSIZE) {
++	}
++
++	if (cursor->set & FB_CUR_SETCMAP) {
++		if (cursor->image.depth == 1) {
++			u32 fg = cursor->image.fg_color;
++			u32 bg = cursor->image.bg_color;
++
++			info->cursor.image.fg_color = fg;
++			info->cursor.image.bg_color = bg;
++
++			fg = ((fg & 0xff0000) >> 16) | ((fg & 0xff) << 16) | (fg & 0xff00);
++			bg = ((bg & 0xff0000) >> 16) | ((bg & 0xff) << 16) | (bg & 0xff00);
++			write_le32(NEOREG_CURSFGCOLOR, fg, par);
++			write_le32(NEOREG_CURSBGCOLOR, bg, par);
++		}
++	}
++
++	if (cursor->set & FB_CUR_SETSHAPE) {
++		unsigned long dest = (unsigned long) par->cursorPad;
++		int i, j;
++
++		//memset_io(par->cursorPad, 0xff, 1);
++		//write_le32(NEOREG_CURSMEMPOS, ((0x000f & (dest >> 10)) << 8) |
++		//		((0x0ff0 & (dest >> 10)) >> 4), par);
++	}
++
++	if (info->cursor.enable)
++		write_le32(NEOREG_CURSCNTL, NEO_CURS_ENABLE, par);
++	return 0;
++}
++
+ static struct fb_ops neofb_ops = {
+ 	.owner		= THIS_MODULE,
++	.fb_open	= neofb_open,
++	.fb_release	= neofb_release,
+ 	.fb_check_var	= neofb_check_var,
+ 	.fb_set_par	= neofb_set_par,
+ 	.fb_setcolreg	= neofb_setcolreg,
+@@ -1507,7 +1610,7 @@ static struct fb_ops neofb_ops = {
+ 	.fb_fillrect	= neofb_fillrect,
+ 	.fb_copyarea	= neofb_copyarea,
+ 	.fb_imageblit	= neofb_imageblit,
+-	.fb_cursor	= soft_cursor,
++	.fb_cursor	= neofb_cursor,
+ };
+ 
+ /* --------------------------------------------------------------------- */
+@@ -1650,6 +1753,7 @@ static int __devinit neo_map_video(struc
+ 				   struct pci_dev *dev, int video_len)
+ {
+ 	struct neofb_par *par = (struct neofb_par *) info->par;
++	unsigned long addr;
+ 
+ 	DBG("neo_map_video");
+ 
+@@ -1681,6 +1785,10 @@ static int __devinit neo_map_video(struc
+ 
+ 	/* Clear framebuffer, it's all white in memory after boot */
+ 	memset(info->screen_base, 0, info->fix.smem_len);
++
++	/* Allocate Cursor drawing pad. */
++	addr = info->fix.smem_start + info->fix.smem_len;
++	par->cursorPad = (u8 *) ioremap(addr, info->sprite.size);
+ 	return 0;
+ }
+ 
+@@ -1725,16 +1833,16 @@ static int __devinit neo_init_hw(struct 
+ 	printk(KERN_DEBUG "--- Neo extended register dump ---\n");
+ 	for (w = 0; w < 0x85; w++)
+ 		printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
+-		       (void *) VGArCR(w));
++		       (void *) vga_rcrt(NULL, w);
+ 	for (w = 0; w < 0xC7; w++)
+ 		printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
+-		       (void *) VGArGR(w));
++		       (void *) vga_rgfx(NULL, w));
+ #endif
+ 
+ 	/* Determine the panel type */
+-	VGAwGR(0x09, 0x26);
+-	type = VGArGR(0x21);
+-	display = VGArGR(0x20);
++	vga_wgfx(NULL, 0x09, 0x26);
++	type = vga_rgfx(NULL, 0x21);
++	display = vga_rgfx(NULL, 0x20);
+ 	if (!par->internal_display && !par->external_display) {
+ 		par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
+ 		par->external_display = display & 1;
+@@ -1744,8 +1852,8 @@ static int __devinit neo_init_hw(struct 
+ 	}
+ 
+ 	/* Determine panel width -- used in NeoValidMode. */
+-	w = VGArGR(0x20);
+-	VGAwGR(0x09, 0x00);
++	w = vga_rgfx(NULL, 0x20);
++	vga_wgfx(NULL, 0x09, 0x00);
+ 	switch ((w & 0x18) >> 3) {
+ 	case 0x00:
+ 		par->NeoPanelWidth = 640;
+@@ -1870,10 +1978,20 @@ static int __devinit neo_init_hw(struct 
+ 		par->neo2200 = (Neo2200 *) par->mmio_vbase;
+ 		break;
+ 	}
+-
++	info->sprite.size = CursorMem;
++	info->sprite.addr = kmalloc(CursorMem, GFP_KERNEL);
++	info->sprite.scan_align = 1;
++	info->sprite.buf_align = 1;
++	info->sprite.flags = FB_PIXMAP_IO;
+ 	par->maxClock = maxClock;
+-
+-	return videoRam * 1024;
++	par->cursorOff = CursorOff;
++	/*
++	 * We decrease the size of the framebuffer by a page
++	 * instead of the size of the cursor pad to avoid
++	 * userland being able to page fault the cursor
++	 * region and start drawing in it.
++	 */
++	return ((videoRam * 1024) - PAGE_SIZE);
+ }
+ 
+ 
+--- linux-2.6.0-test6/drivers/video/platinumfb.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/platinumfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -104,9 +104,6 @@ static int platinum_var_to_par(const str
+  * Interface used by the world
+  */
+ 
+-int platinum_init(void);
+-int platinum_setup(char*);
+-
+ static struct fb_ops platinumfb_ops = {
+ 	.owner =	THIS_MODULE,
+ 	.fb_check_var	= platinumfb_check_var,
+@@ -492,7 +489,7 @@ static int platinum_par_to_var(struct fb
+ /* 
+  * Parse user speficied options (`video=platinumfb:')
+  */
+-int __init platinum_setup(char *options)
++int __init platinumfb_setup(char *options)
+ {
+ 	char *this_opt;
+ 
+@@ -672,7 +669,7 @@ static struct of_platform_driver platinu
+ 	.remove		= platinumfb_remove,
+ };
+ 
+-int __init platinum_init(void)
++int __init platinumfb_init(void)
+ {
+ 	of_register_driver(&platinum_driver);
+ 
+--- linux-2.6.0-test6/drivers/video/pm3fb.c	2003-06-14 12:18:02.000000000 -0700
++++ 25/drivers/video/pm3fb.c	2003-10-05 00:33:24.000000000 -0700
+@@ -54,7 +54,6 @@
+ 
+ #include <linux/config.h>
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+--- linux-2.6.0-test6/drivers/video/pvr2fb.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/drivers/video/pvr2fb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -166,6 +166,11 @@ static u_long videomemory = 0xa5000000, 
+ static int cable_type = -1;
+ static int video_output = -1;
+ 
++#ifdef CONFIG_MTRR
++static int enable_mtrr = 1;
++static int mtrr_handle;
++#endif
++
+ static int nopan = 0;
+ static int nowrap = 1;
+ 
+@@ -385,6 +390,7 @@ static int pvr2fb_set_par(struct fb_info
+ 
+ static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
++	struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
+ 	u_short vtotal, hsync_total;
+ 	u_long line_length;
+ 
+@@ -413,7 +419,7 @@ static int pvr2fb_check_var(struct fb_va
+ 
+ 	if (var->vmode & FB_VMODE_YWRAP) {
+ 		if (var->xoffset || var->yoffset < 0 || 
+-		    var->yoffset >= var->yres_virtual) {
++		    var->yoffset >= var->yres_virtual)
+ 			var->xoffset = var->yoffset = 0;
+ 		} else {
+ 			if (var->xoffset > var->xres_virtual - var->xres ||
+@@ -421,9 +427,8 @@ static int pvr2fb_check_var(struct fb_va
+ 			    var->xoffset < 0 || var->yoffset < 0)
+ 				var->xoffset = var->yoffset = 0;
+ 		}
+-	} else {
++	} else
+ 		var->xoffset = var->yoffset = 0;
+-	}
+ 
+ 	/* 
+ 	 * XXX: Need to be more creative with this (i.e. allow doublecan for
+@@ -456,7 +461,6 @@ static int pvr2fb_check_var(struct fb_va
+ 				DPRINTK("invalid hsync total for NTSC\n");
+ 				return -EINVAL;
+ 			}
+-		}
+ 	}
+ 	/* Check memory sizes */
+ 	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+@@ -599,10 +603,10 @@ static int pvr2_init_cable(void)
+ 
+ int __init pvr2fb_init(void)
+ {
++	struct fb_var_screeninfo var;
+ 	u_long modememused;
+-	int err = -EINVAL;
+ 
+-	if (!mach_is_dreamcast())
++	if (!MACH_DREAMCAST)
+ 		return -ENXIO;
+ 
+ 	fb_info = kmalloc(sizeof(struct fb_info) + sizeof(struct pvr2fb_par) +
+@@ -650,8 +654,8 @@ int __init pvr2fb_init(void)
+ 	
+ 	if (!fb_info->screen_base) {
+ 		printk("Failed to remap MMIO space\n");
+-		err = -ENXIO;
+-		goto out_err;
++		kfree(fb_info);
++		return -ENXIO;
+ 	}
+ 
+ 	memset_io((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len);
+@@ -665,6 +669,8 @@ int __init pvr2fb_init(void)
+ 	fb_info->pseudo_palette	= (void *)(fb_info->par + 1);
+ 	fb_info->flags		= FBINFO_FLAG_DEFAULT;
+ 
++	memset(&var, 0, sizeof(var));
++
+ 	if (video_output == VO_VGA)
+ 		defmode = DEFMODE_VGA;
+ 
+@@ -677,41 +683,46 @@ int __init pvr2fb_init(void)
+ 
+ 	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,
+ 	                "pvr2 VBL handler", fb_info)) {
+-		err = -EBUSY;
+-		goto out_err;
++		DPRINTK("couldn't register VBL int\n");
++		kfree(fb_info);
++		return 	-EBUSY;
+ 	}
+ 
+-	if (register_framebuffer(fb_info) < 0)
+-		goto reg_failed;
++#ifdef CONFIG_MTRR
++	if (enable_mtrr) {
++		mtrr_handle = mtrr_add(videomemory, videomemorysize, MTRR_TYPE_WRCOMB, 1);
++		printk("pvr2fb: MTRR turned on\n");
++	}
++#endif
+ 
+-	modememused = get_line_length(fb_info->var.xres_virtual,
+-				      fb_info->var.bits_per_pixel);
+-	modememused *= fb_info->var.yres_virtual;
++	if (register_framebuffer(fb_info) < 0) {
++		kfree(fb_info);
++		return -EINVAL;
++	}
+ 
++	modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
++	modememused *= var.yres_virtual;
+ 	printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
+ 	       fb_info->node, fb_info->fix.id, modememused>>10,
+ 	       videomemorysize>>10);
+ 	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 
+-	       fb_info->node, fb_info->var.xres, fb_info->var.yres,
+-	       fb_info->var.bits_per_pixel, 
+-	       get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
++	       fb_info->node, var.xres, var.yres, var.bits_per_pixel,
++	       get_line_length(var.xres, var.bits_per_pixel),
+ 	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),
+ 	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));
+ 
+ 	return 0;
+-
+-reg_failed:
+-	free_irq(HW_EVENT_VSYNC, 0);
+-out_err:
+-	kfree(fb_info);
+-
+-	return err;
+ }
+ 
+ static void __exit pvr2fb_exit(void)
+ {
++#ifdef CONFIG_MTRR
++	if (enable_mtrr) {
++		mtrr_del(mtrr_handle, videomemory, videomemorysize);
++		printk("pvr2fb: MTRR turned off\n");
++	}
++#endif
+ 	unregister_framebuffer(fb_info);
+-	free_irq(HW_EVENT_VSYNC, 0);
+ 	kfree(fb_info);
+ }
+ 
+@@ -767,6 +778,10 @@ int __init pvr2fb_setup(char *options)
+ 			nopan = 1;
+ 		} else if (!strncmp(this_opt, "nowrap", 6)) {
+ 			nowrap = 1;
++#ifdef CONFIG_MTRR
++		} else if (!strncmp(this_opt, "nomtrr", 6)) {
++			enable_mtrr = 0;
++#endif
+ 		} else {
+ 			mode_option = this_opt;
+ 		}
+--- linux-2.6.0-test6/drivers/video/radeonfb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/radeonfb.c	2003-10-05 00:34:47.000000000 -0700
+@@ -1099,7 +1099,7 @@ static int radeon_get_dfpinfo_BIOS(struc
+ 	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+ 		rinfo->panel_xres, rinfo->panel_yres);
+ 
+-	for(i=0; i<20; i++) {
++	for(i=0; i<21; i++) {
+ 		tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
+ 		if (tmp0 == 0)
+ 			break;
+@@ -2090,7 +2090,7 @@ static int radeonfb_set_par (struct fb_i
+ 	
+ 	}
+ 	/* Update fix */
+-        info->fix.line_length = rinfo->pitch*64;
++        info->fix.line_length = mode->xres_virtual*(mode->bits_per_pixel/8);
+         info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+ 
+ #ifdef CONFIG_BOOTX_TEXT
+--- linux-2.6.0-test6/drivers/video/riva/fbdev.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/video/riva/fbdev.c	2003-10-05 00:34:22.000000000 -0700
+@@ -143,7 +143,17 @@ enum riva_chips {
+ 	CH_GEFORCE4_TI_4200,
+ 	CH_QUADRO4_900XGL,
+ 	CH_QUADRO4_750XGL,
+-	CH_QUADRO4_700XGL
++	CH_QUADRO4_700XGL,
++	CH_GEFORCE4_TI_4800,
++	CH_GEFORCE4_TI_4280,
++	CH_GEFORCE4_TI_4800SE,
++	CH_GEFORCE4_4200_GO,
++	CH_GEFORCE_FX_5800_U,
++	CH_GEFORCE_FX_5800,
++	CH_GEFORCE_FX_5600_U,
++	CH_GEFORCE_FX_5600,
++	CH_GEFORCE_FX_5200_U,
++	CH_GEFORCE_FX_5200
+ };
+ 
+ /* directly indexed by riva_chips enum, above */
+@@ -190,7 +200,17 @@ static struct riva_chip_info {
+ 	{ "GeForce4 Ti 4200", NV_ARCH_20 },
+ 	{ "Quadro4-900-XGL", NV_ARCH_20 },
+ 	{ "Quadro4-750-XGL", NV_ARCH_20 },
+-	{ "Quadro4-700-XGL", NV_ARCH_20 }
++	{ "Quadro4-700-XGL", NV_ARCH_20 },
++	{ "GeForce4 Ti 4800", NV_ARCH_20 },
++	{ "GeForce4 Ti 4280", NV_ARCH_20},
++	{ "GeForce4 Ti 4800 SE", NV_ARCH_20},
++	{ "GeForce4 4200 GO", NV_ARCH_20},
++	{ "GeForce FX 5800 ULTRA", NV_ARCH_20},
++	{ "GeForce FX 5800", NV_ARCH_20},
++	{ "GeForce FX 5600 ULTRA", NV_ARCH_20},
++	{ "GeForce FX 5600", NV_ARCH_20},
++	{ "GeForce FX 5200 ULTRA", NV_ARCH_20},
++	{ "GeForce FX 5200", NV_ARCH_20}
+ };
+ 
+ static struct pci_device_id rivafb_pci_tbl[] = {
+@@ -274,6 +294,26 @@ static struct pci_device_id rivafb_pci_t
+ 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
+ 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
+ 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800 },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4280 },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800SE },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_4200_GO },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800_U },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800 },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600_U },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600 },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200_U },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200 },
+ 	{ 0, } /* terminate list */
+ };
+ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
+@@ -1469,8 +1509,6 @@ static void rivafb_imageblit(struct fb_i
+ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
+ 	struct riva_par *par = (struct riva_par *) info->par;
+-	u8 data[MAX_CURS * MAX_CURS/8];
+-	u8 mask[MAX_CURS * MAX_CURS/8];
+ 	u16 fg, bg;
+ 	int i;
+ 
+@@ -1492,7 +1530,6 @@ static int rivafb_cursor(struct fb_info 
+ 	if (cursor->set & FB_CUR_SETSIZE) {
+ 		info->cursor.image.height = cursor->image.height;
+ 		info->cursor.image.width = cursor->image.width;
+-		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+ 	}
+ 
+ 	if (cursor->set & FB_CUR_SETCMAP) {
+@@ -1503,29 +1540,22 @@ static int rivafb_cursor(struct fb_info 
+ 	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+ 		u32 bg_idx = info->cursor.image.bg_color;
+ 		u32 fg_idx = info->cursor.image.fg_color;
+-		u32 s_pitch = (info->cursor.image.width+7) >> 3;
+-		u32 d_pitch = MAX_CURS/8;
+-		u8 *dat = (u8 *) cursor->image.data;
++		u8 *dat = (u8 *) info->cursor.image.data;
+ 		u8 *msk = (u8 *) info->cursor.mask;
+ 		u8 src[64];	
+ 		
+ 		switch (info->cursor.rop) {
+ 		case ROP_XOR:
+-			for (i = 0; i < s_pitch * info->cursor.image.height; i++)
++			for (i = 0; i < info->sprite.size; i++)
+ 					src[i] = dat[i] ^ msk[i];
+ 			break;
+ 		case ROP_COPY:
+ 		default:
+-			for (i = 0; i < s_pitch * info->cursor.image.height; i++)
+-				
++			for (i = 0; i < info->sprite.size; i++)
+ 					src[i] = dat[i] & msk[i];
+ 			break;
+ 		}
+ 		
+-		move_buf_aligned(info, data, src, d_pitch, s_pitch, info->cursor.image.height);
+-
+-		move_buf_aligned(info, mask, msk, d_pitch, s_pitch, info->cursor.image.height);
+-
+ 		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+ 		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
+ 		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+@@ -1536,7 +1566,7 @@ static int rivafb_cursor(struct fb_info 
+ 
+ 		par->riva.LockUnlock(&par->riva, 0);
+ 
+-		rivafb_load_cursor_image(par, data, mask, bg, fg,
++		rivafb_load_cursor_image(par, dat, msk, bg, fg,
+ 					 info->cursor.image.width, 
+ 					 info->cursor.image.height);
+ 	}
+@@ -1572,7 +1602,7 @@ static struct fb_ops riva_fb_ops = {
+ 	.fb_fillrect 	= rivafb_fillrect,
+ 	.fb_copyarea 	= rivafb_copyarea,
+ 	.fb_imageblit 	= rivafb_imageblit,
+-	.fb_cursor	= rivafb_cursor,	
++	.fb_cursor	= soft_cursor,
+ 	.fb_sync 	= rivafb_sync,
+ };
+ 
+@@ -1603,6 +1633,15 @@ static int __devinit riva_set_fbinfo(str
+ 	info->pixmap.buf_align = 4;
+ 	info->pixmap.scan_align = 4;
+ 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
++/*
++	info->sprite.addr = (char *) par->riva.CURSOR;
++	info->sprite.size = MAX_CURS * MAX_CURS * 2;
++	info->sprite.buf_align = info->sprite.size;
++	info->sprite.scan_align = MAX_CURS >> 3;
++	info->sprite.access_align = 2;
++	info->sprite.flags = FB_PIXMAP_IO;
++	memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
++*/
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/drivers/video/riva/nv_type.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/video/riva/nv_type.h	2003-10-05 00:34:22.000000000 -0700
+@@ -50,8 +50,16 @@
+ #define NV_CHIP_QUADRO4_900XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL)
+ #define NV_CHIP_QUADRO4_750XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL)
+ #define NV_CHIP_QUADRO4_700XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL)
+-#define NV_CHIP_0x0280              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0280)
+-#define NV_CHIP_0x0281              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0281)
++#define NV_CHIP_GEFORCE4_TI_4800    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800)
++#define NV_CHIP_GEFORCE4_TI_4280    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280)
++#define NV_CHIP_GEFORCE4_TI_4800SE  ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE)
++#define NV_CHIP_GEFORCE4_4200_GO    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO)
++#define NV_CHIP_GEFORCE_FX_5800_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U)
++#define NV_CHIP_GEFORCE_FX_5800     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800)
++#define NV_CHIP_GEFORCE_FX_5600_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U)
++#define NV_CHIP_GEFORCE_FX_5600     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600)
++#define NV_CHIP_GEFORCE_FX_5200_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U)
++#define NV_CHIP_GEFORCE_FX_5200     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200)
+ #define NV_CHIP_0x0288              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0288)
+ #define NV_CHIP_0x0289              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0289)
+ 
+--- linux-2.6.0-test6/drivers/video/sis/300vtbl.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/drivers/video/sis/300vtbl.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,7 +1,37 @@
+-
+-
+-/* Register settings for SiS 300 series */
+-
++/* $XFree86$ */
++/*
++ * Register settings for SiS 300 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+ 
+ typedef struct _SiS300_StStruct
+ {
+@@ -39,470 +69,109 @@ static const SiS300_StStruct  SiS300_SMo
+ 	{0xff,     0,   0,   0,   0,   0,   0,   0}
+ };
+ 
+-typedef struct _SiS300_StandTableStruct
+-{
+-	UCHAR CRT_COLS;
+-	UCHAR ROWS;
+-	UCHAR CHAR_HEIGHT;
+-	USHORT CRT_LEN;
+-	UCHAR SR[4];
+-	UCHAR MISC;
+-	UCHAR CRTC[0x19];
+-	UCHAR ATTR[0x14];
+-	UCHAR GRC[9];
+-} SiS300_StandTableStruct;
+-
+-static const SiS300_StandTableStruct  SiS300_StandTable[] =
+-{
+- {0x28,0x18,0x08,0x0800,			/* 0x00 */
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x28,0x18,0x08,0x0800,			/* 0x01 */
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x08,0x1000,			/* 0x02 */
+-  {0x01,0x03,0x00,0x02},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x08,0x1000,			/* 0x03 */
+-  {0x01,0x03,0x00,0x02},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x28,0x18,0x08,0x4000,			/* 0x04 */
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+-   0xff},
+-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x03,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+-   0xff} },
+- {0x28,0x18,0x08,0x4000,			/* 0x05 */
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+-   0xff},
+-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x03,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+-   0xff} },
+- {0x50,0x18,0x08,0x4000,			/* 0x06 */
+-  {0x01,0x01,0x00,0x06},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+-   0xff},
+-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+-   0x01,0x00,0x01,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+-   0xff} },
+- {0x50,0x18,0x0e,0x1000,			/* 0x07 */
+-  {0x00,0x03,0x00,0x03},
+-  0xa6,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+-   0x0e,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+-   0xff} },
+-/* MDA_DAC*/
+- {0x00,0x00,0x00,0x0000,			/* 0x08 */
+-  {0x00,0x00,0x00,0x15},
+-  0x15,
+-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+-   0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15},
+-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x3f} },
+-/* CGA_DAC*/
+- {0x00,0x10,0x04,0x0114,			/* 0x09 */
+-  {0x11,0x09,0x15,0x00},
+-  0x10,
+-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+-   0x04},
+-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+-   0x3e,0x2b,0x3b,0x2f},
+-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+-   0x3f} },
+-/* EGA_DAC*/
+- {0x00,0x10,0x04,0x0114,			/* 0x0a */
+-  {0x11,0x05,0x15,0x20},
+-  0x30,
+-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+-   0x06},
+-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+-   0x1e,0x0b,0x1b,0x0f},
+-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+-   0x3f} },
+-/* VGA_DAC*/
+- {0x00,0x10,0x04,0x0114,			/* 0x0b */
+-  {0x11,0x09,0x15,0x2a},
+-  0x3a,
+-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+-   0x1f},
+-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+-   0x1c,0x0e,0x11,0x15},
+-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+-   0x04} },
+- {0x08,0x0c,0x10,0x0a08,			/* 0x0c */
+-  {0x0c,0x0e,0x10,0x0b},
+-  0x0c,
+-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+-   0x06},
+-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+-   0x00,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00} },
+- {0x28,0x18,0x08,0x2000,			/* 0x0d */
+-  {0x09,0x0f,0x00,0x06},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff} },
+- {0x50,0x18,0x08,0x4000,			/* 0x0e */
+-  {0x01,0x0f,0x00,0x06},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff} },
+- {0x00,0x00,0x00,0x0000,			/* 0x0f */	/* TW: Standtable for VGA modes */
+-  {0x01,0x0f,0x00,0x0e},
+-  0x23,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+-   0x01,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+-   0xff} },
+- {0x4a,0x36,0x00,0x00c0,			/* 0x10 */
+-  {0x00,0x00,0x00,0x00},
+-  0x00,
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
+-   0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00} },
+- {0x50,0x18,0x0e,0x8000,			/* 0x11 */
+-  {0x01,0x0f,0x00,0x06},
+-  0xa2,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+-   0xff},
+-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+-   0x0b,0x00,0x05,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+-   0xff} },
+- {0x50,0x18,0x0e,0x8000,			/* 0x12 */
+-  {0x01,0x0f,0x00,0x06},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff} },
+- {0x28,0x18,0x0e,0x0800,			/* 0x13 */
+-  {0x09,0x03,0x00,0x02},
+-  0xa3,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x28,0x18,0x0e,0x0800,			/* 0x14 */
+-  {0x09,0x03,0x00,0x02},
+-  0xa3,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x0e,0x1000,			/* 0x15 */
+-  {0x01,0x03,0x00,0x02},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x0e,0x1000,			/* 0x16 */
+-  {0x01,0x03,0x00,0x02},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x28,0x18,0x10,0x0800,			/* 0x17 */
+-  {0x08,0x03,0x00,0x02},
+-  0x67,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x0c,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x10,0x1000,			/* 0x18 */
+-  {0x00,0x03,0x00,0x02},
+-  0x67,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x0c,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff} },
+- {0x50,0x18,0x10,0x1000,			/* 0x19 */
+-  {0x00,0x03,0x00,0x02},
+-  0x66,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+-   0x0e,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+-   0xff} },
+- {0x50,0x1d,0x10,0xa000,			/* 0x1a */
+-  {0x01,0x0f,0x00,0x06},
+-  0xe3,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+-   0xff},
+-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+-   0xff} },
+- {0x50,0x1d,0x10,0xa000,			/* 0x1b */
+-  {0x01,0x0f,0x00,0x06},
+-  0xe3,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff} },
+- {0x28,0x18,0x08,0x2000,			/* 0x1c */
+-  {0x01,0x0f,0x00,0x0e},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
+-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+-   0x41,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+-   0xff} }
+-};
+-
+ typedef struct _SiS300_ExtStruct
+ {
+-	UCHAR Ext_ModeID;
++	UCHAR  Ext_ModeID;
+ 	USHORT Ext_ModeFlag;
+ 	USHORT Ext_ModeInfo;
+-	USHORT Ext_Point;
+ 	USHORT Ext_VESAID;
+-	UCHAR Ext_VESAMEMSize;
+-	UCHAR Ext_RESINFO;
+-	UCHAR VB_ExtTVFlickerIndex;
+-	UCHAR VB_ExtTVEdgeIndex;
+-	UCHAR VB_ExtTVYFilterIndex;
+-	UCHAR REFindex;
++	UCHAR  Ext_RESINFO;
++	UCHAR  VB_ExtTVFlickerIndex;
++	UCHAR  VB_ExtTVEdgeIndex;
++	UCHAR  VB_ExtTVYFilterIndex;
++	UCHAR  REFindex;
+ } SiS300_ExtStruct;
+ 
+ static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
+ {
+-	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x? */
+-	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
+-	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x8 */
+-	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
+-	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x8 */
+-	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x8 */
+-	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x16 */
+-	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x16 */
+-	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x32 */
+-	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x32 */
+-	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x? */
+-	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
+-	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
+-	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+-	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+-	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
+-	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
+-	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
+-	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
+-	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+-	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+-	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+-	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+-	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+-	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+-	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
+-	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
+-	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
+-	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
+-	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
+-	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  
+-	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, 
+-	{0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26},  /* TW: inserted 512x384x32 */
+-	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x16 */
+- 	{0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10},  /* TW: inserted 640x400x32 */
+-	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
+-	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+-	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+-	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+-	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+-	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
+-	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
+-	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
+-	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x8 - not in BIOS! */
+-	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x16 - not in BIOS! */
+-	{0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
+-	{0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
+-	/* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
+-	{0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x8 */
+-	{0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x8 */
+-	{0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x16 */
+-	{0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x16 */
+-	{0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x32 */
+-	{0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},	   /* 1024x576x32 */
+-	{0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x32 */
+-	{0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x8 */
+-	{0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x16 */
+-	/* TW: End of new 16:9 modes */
+-	{0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},    /* 1280x960x32 */
+-	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},    /* 1024x600 */
+-	{0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+-	{0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
+-	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},    /* 1152x768 */
+-	{0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+-	{0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+-	{0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},    /* TW: NEW 1152x864 - not in BIOS */
+-	{0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+-	{0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+-	{0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},    /* TW: NEW 848x480 - not in BIOS */
+-	{0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+-	{0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+-	{0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},    /* TW: NEW 856x480 - not in BIOS */
+-	{0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+-	{0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+-	{0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},    /* TW: NEW 1360x768 - not in BIOS */
+-	{0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+-	{0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+-	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
++	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x? */
++	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
++	{0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x8 */
++	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00},
++	{0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x8 */
++	{0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x8 */
++	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x16 */
++	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x16 */
++	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x32 */
++	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x32 */
++	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x? */
++	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x8 */
++	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
++	{0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++	{0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++	{0x40,0x921c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x15 */
++	{0x41,0x921d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x16 */
++	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
++	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
++	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x15 */
++	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x16 */
++	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++	{0x50,0x921b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x8  */
++	{0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x8  */
++	{0x52,0x921b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x8  */
++	{0x56,0x921d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x16 */
++	{0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x16 */
++	{0x58,0x921d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x16 */
++	{0x59,0x921b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x8  */
++	{0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x32 */
++	{0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x16 */
++ 	{0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x32 */
++	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
++	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x32 */
++	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++	{0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
++	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++	{0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
++	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
++	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
++	{0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x8 */
++	{0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x8 */
++	{0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x16 */
++	{0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x16 */
++	{0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x32 */
++	{0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x32 */
++	{0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x32 */
++	{0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x8 */
++	{0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x16 */
++	{0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x8 */
++	{0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x16 */
++	{0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x32 */
++	{0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},  /* 1024x600 */
++	{0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
++	{0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
++	{0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},  /* 1152x768 */
++	{0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
++	{0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
++	{0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},  /* 1152x864 */
++	{0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
++	{0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
++	{0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},  /* 848x480 */
++	{0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
++	{0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
++	{0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},  /* 856x480 */
++	{0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
++	{0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
++	{0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},  /* 1360x768 */
++	{0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
++	{0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
++	{0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x32 */
++	{0x53,0x921f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x32 */
++	{0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x32 */
++	{0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},  /* 1280x768   */
++	{0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
++	{0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
++	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x8 */
++	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x16 */
++	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x32 */
++	{0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
++	{0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
++	{0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
++	{0xff,0x0000,0x0000,0xffff,0x00,            0x00,0x00,0x00,0x00}
+ };
+ 
+ typedef struct _SiS300_Ext2Struct
+@@ -514,76 +183,77 @@ typedef struct _SiS300_Ext2Struct
+ 	UCHAR  ModeID;
+ 	USHORT XRes;
+ 	USHORT YRes;
+-	USHORT ROM_OFFSET;
+ } SiS300_Ext2Struct;
+ 
+ static const SiS300_Ext2Struct  SiS300_RefIndex[] =
+ { /* TW: Don't ever insert anything here, table is indexed */
+-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
+-	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
+-	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
+-	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
+-	{0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
+-	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
+-	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
+-	{0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
+-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
+-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
+-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
+-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
+-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
+-	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
+-	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
+-	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
+-	{0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
+-	{0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
+-	{0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
+-	{0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
+-        {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
+-	{0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
+-	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
+-	{0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
+-	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
+-	{0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
+-	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
+-	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
+-	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
+-	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
+-	{0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
+-	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
+-	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
+-	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
+-	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
+-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
+-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
+-	{0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
+-	{0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */  /* was c077 */
+-	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
+-	{0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
+-	{0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
+-	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
+-	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
+-	{0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */	/* VCLK 0x09 */
+-	{0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
+-	{0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
+-	{0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
+-	{0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
+-	{0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
+-	{0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
+-	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
+-	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
+-	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
+-	{0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
+-	{0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
+-	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
+-	{0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz  - Non-BIOS, new */
+-	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
+-	{0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz  - Non-BIOS, new */
+-	{0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
+-	{0xffff,0,0,0,0,0,0,0}
++	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */
++	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */
++	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */
++	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */
++	{0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */
++	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */
++	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */
++	{0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */
++	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */
++	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */
++	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */
++	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */
++	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */
++	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */
++	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */
++	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */
++	{0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */
++	{0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */
++	{0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */
++	{0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */
++        {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */
++	{0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */
++	{0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */
++	{0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */
++	{0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */
++	{0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */
++	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */
++	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */
++	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */
++	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */
++	{0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */
++	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */
++	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */
++	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */
++	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */
++	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */
++	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */
++	{0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */
++	{0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */  /* was c077 */
++	{0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */
++	{0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */
++	{0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */
++	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */
++	{0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */
++	{0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */	/* VCLK 0x09 */
++	{0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */
++	{0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */
++	{0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */
++	{0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */
++	{0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */
++	{0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */
++	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */
++	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */
++	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */
++	{0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */
++	{0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */
++	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */
++	{0xc067,0x40,0x3d,0x0b,0x39, 848, 480}, /* 39 848x480-60Hz  */
++	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */
++	{0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz  */
++	{0x0067,0x43,0x3e,0x0c,0x48,1360, 768}, /* 3c 1360x768-60Hz */
++	{0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */
++	{0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */
++	{0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
++	{0xffff,   0,   0,   0,   0,   0,   0}
+ };
+ 
+-/*add for 300 oem util*/
+ typedef struct _SiS_VBModeIDTableStruct
+ {
+ 	UCHAR  ModeID;
+@@ -649,9 +319,8 @@ static const SiS_VBModeIDTableStruct  Si
+ 	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ 	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+ 	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
+-	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* TW: added! */
++	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+ };
+-/*end*/
+ 
+ typedef struct _SiS300_CRT1TableStruct
+ {
+@@ -660,15 +329,32 @@ typedef struct _SiS300_CRT1TableStruct
+ 
+ static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
+ {
+- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 */
+-  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
++#if 1
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 - 320x200 */
++  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
++  0x00}},
++#endif
++#if 0
++ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f,    /* 0x00 - corrected 320x200-72 - does not work */
++  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
+   0x00}},
+- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
++#endif
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,    /* 0x01 */
++  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
+   0x00}},
+- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
++#if 0
++ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e,    /* 0x01 - corrected 320x240-60 - does not work */
++  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
++  0x00}},
++#endif
++ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 */
++  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
++  0x01}},
++#if 0
++ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 - corrected 400x300-60 */
+   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+   0x01}},
++#endif
+  {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+   0x01}},
+@@ -683,7 +369,7 @@ static const SiS300_CRT1TableStruct  SiS
+  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
+   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+   0x00}},
+- #if 0  
++#if 0
+  {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
+   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
+   0x00}},
+@@ -841,15 +527,10 @@ static const SiS300_CRT1TableStruct  SiS
+  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
+   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
+   0x01}},
+-#if 0
+- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
+-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+-  0x01}},
+-#endif
+- {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - TW: corrected */
++ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - corrected */
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}},
+- {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
++ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 */
+    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+    0x01}}, /* 0x35 */
+  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+@@ -864,7 +545,7 @@ static const SiS300_CRT1TableStruct  SiS
+  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+    0x01}}, /* 0x39 */
+- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   	/* TW: 95 was 15 - illegal HBE! */
++ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,  /* 95 was 15 - illegal HBE! */
+    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+    0x01}}, /* 0x3a */
+  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+@@ -875,36 +556,40 @@ static const SiS300_CRT1TableStruct  SiS
+    0x01}}, /* 0x3c */
+  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+-   0x01}}, /* 0x3d */			     /* TW: End of 16:9 modes --------------- */
+- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* TW: New, 1152x864-75 (not in any BIOS)   */
++   0x01}}, /* 0x3d */
++ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* 1152x864-75 */
+    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+    0x01}},  /* 0x3e */
+- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 848x480-38i, not in BIOS */
++ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* 848x480-38i */
+    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+    0x00}}, /* 0x3f */
+-#if 0
+- {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
+-   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+-   0x00}}, /* 0x40 */
+-#endif
+- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* TW: New, 848x480-60, not in BIOS */
++ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* 848x480-60  */
+    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+    0x00}}, /* 0x40 */
+- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 856x480-38i, not in BIOS */
++ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* 856x480-38i */
+    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+    0x00}}, /* 0x41 */
+- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 856x480-60, not in BIOS */
++ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* 856x480-60  */
+    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+    0x00}}, /* 0x42 */
+- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* TW: New, 1360x768-60, not in BIOS */
++ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* 1360x768-60 */
+    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+    0x01}}, /* 0x43 */
+- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* TW: New, 1152x864-84 (not in any BIOS)   */
++ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* 1152x864-84 */
+    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+-   0x01}}, /* 0x44 */   
+- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* TW: New, 1280x960-85 (not in any BIOS)   */
++   0x01}}, /* 0x44 */
++ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* 1280x960-85 */
+    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+-   0x01}}  /* 0x45 */
++   0x01}}, /* 0x45 */
++ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
++   0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
++   0x01}},  /* 0x46 */
++ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
++   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
++   0x01}},  /* 0x47 */
++ {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
++   0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
++   0x00}}   /* 0x48 */
+ };
+ 
+ typedef struct _SiS300_MCLKDataStruct
+@@ -913,8 +598,8 @@ typedef struct _SiS300_MCLKDataStruct
+ 	USHORT CLOCK;
+ } SiS300_MCLKDataStruct;
+ 
+-static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =	/* 630 */
+-{ /* TW: at 0x54 in BIOS */
++static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
++{
+ 	{ 0x5a,0x64,0x80, 66},
+ 	{ 0xb3,0x45,0x80, 83},
+ 	{ 0x37,0x61,0x80,100},
+@@ -925,8 +610,8 @@ static const SiS300_MCLKDataStruct  SiS3
+ 	{ 0x37,0x61,0x80,100}
+ };
+ 
+-static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =  /* 300 */
+-{ /* TW: at 0x54 in BIOS */
++static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
++{
+ 	{ 0x68,0x43,0x80,125},
+ 	{ 0x68,0x43,0x80,125},
+ 	{ 0x68,0x43,0x80,125},
+@@ -937,6 +622,7 @@ static const SiS300_MCLKDataStruct  SiS3
+ 	{ 0x37,0x61,0x80,100}
+ };
+ 
++#ifdef LINUXBIOS
+ typedef struct _SiS300_ECLKDataStruct
+ {
+ 	UCHAR SR2E,SR2F,SR30;
+@@ -954,6 +640,7 @@ static const SiS300_ECLKDataStruct  SiS3
+ 	{ 0x54,0x43,0x80,100},
+ 	{ 0x54,0x43,0x80,100}
+ };
++#endif
+ 
+ typedef struct _SiS300_VCLKDataStruct
+ {
+@@ -964,71 +651,77 @@ typedef struct _SiS300_VCLKDataStruct
+ static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
+ {
+ 	{ 0x1b,0xe1, 25}, /* 0x00 */
+-	{ 0x4e,0xe4, 28},
++	{ 0x4e,0xe4, 28}, /* 0x01 */
+ 	{ 0x57,0xe4, 32}, /* 0x02 */
+-	{ 0xc3,0xc8, 36},
++	{ 0xc3,0xc8, 36}, /* 0x03 */
+ 	{ 0x42,0xc3, 40}, /* 0x04 */
+-	{ 0x5d,0xc4, 45},
++	{ 0x5d,0xc4, 45}, /* 0x05 */
+ 	{ 0x52,0x65, 50}, /* 0x06 */
+-	{ 0x53,0x65, 50},
++	{ 0x53,0x65, 50}, /* 0x07 */
+ 	{ 0x6d,0x66, 56}, /* 0x08 */
+-	{ 0x5a,0x64, 65},
++	{ 0x5a,0x64, 65}, /* 0x09 */
+ 	{ 0x46,0x44, 68}, /* 0x0a */
+-	{ 0x3e,0x43, 75},
+-	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
+-	{ 0x41,0x43, 79},
++	{ 0x3e,0x43, 75}, /* 0x0b */
++	{ 0x6d,0x46, 76}, /* 0x0c */  /* 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
++	{ 0x41,0x43, 79}, /* 0x0d */
+ 	{ 0x31,0x42, 79}, /* 0x0e */
+-	{ 0x46,0x25, 85},
++	{ 0x46,0x25, 85}, /* 0x0f */
+ 	{ 0x78,0x29, 87}, /* 0x10 */
+-	{ 0x62,0x44, 95},
++	{ 0x62,0x44, 95}, /* 0x11 */
+ 	{ 0x2b,0x22,105}, /* 0x12 */
+-	{ 0x49,0x24,106},
++	{ 0x49,0x24,106}, /* 0x13 */
+ 	{ 0xc3,0x28,108}, /* 0x14 */
+-	{ 0x3c,0x23,109},
++	{ 0x3c,0x23,109}, /* 0x15 */
+ 	{ 0xf7,0x2c,132}, /* 0x16 */
+-	{ 0xd4,0x28,136},
++	{ 0xd4,0x28,136}, /* 0x17 */
+ 	{ 0x41,0x05,158}, /* 0x18 */
+-	{ 0x43,0x05,162},
++	{ 0x43,0x05,162}, /* 0x19 */
+ 	{ 0xe1,0x0f,175}, /* 0x1a */
+ 	{ 0xfc,0x12,189}, /* 0x1b */
+ 	{ 0xde,0x26,194}, /* 0x1c */
+-	{ 0x54,0x05,203},
++	{ 0x54,0x05,203}, /* 0x1d */
+ 	{ 0x3f,0x03,230}, /* 0x1e */
+-	{ 0x30,0x02,234},
++	{ 0x30,0x02,234}, /* 0x1f */
+ 	{ 0x24,0x01,266}, /* 0x20 */
+-	{ 0x52,0x2a, 54}, /* 301 TV */
+-	{ 0x52,0x6a, 27}, /* 301 TV */
+-	{ 0x62,0x24, 70}, /* 301 TV */
+-	{ 0x62,0x64, 70}, /* 301 TV */
+-	{ 0xa8,0x4c, 30}, /* 301 TV */
+-	{ 0x20,0x26, 33}, /* 301 TV */
+-	{ 0x31,0xc2, 39},
+-	{ 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
+-	{ 0x60,0x36, 30}, /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+-	{ 0x40,0x4a, 28},
+-	{ 0x9f,0x46, 44},
+-	{ 0x97,0x2c, 26},
+-	{ 0x44,0xe4, 25},
+-	{ 0x7e,0x32, 47},
+-	{ 0x8a,0x24, 31}, /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
+-	{ 0x97,0x2c, 26},
+-	{ 0xce,0x3c, 39},
+-	{ 0x52,0x4a, 36}, /* 0x32  CH/PAL 800x600 5/6 */
+-	{ 0x34,0x61, 95},
+-	{ 0x78,0x27,108},
+-	{ 0xce,0x25,189}, /* 0x35 */
+-	{ 0x45,0x6b, 21}, /* 0x36 */  /* TW: Added from Mitac */
+-	{ 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
+-	{ 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
+-	{ 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
+-	{ 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
+-	{ 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
+-	{ 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
+-	{ 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
+-	{ 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
+-	{ 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
+-	{ 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
+-	{ 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
++	{ 0x52,0x2a, 54}, /* 0x21 */  /* 301 TV */
++	{ 0x52,0x6a, 27}, /* 0x22 */  /* 301 TV */
++	{ 0x62,0x24, 70}, /* 0x23 */  /* 301 TV */
++	{ 0x62,0x64, 70}, /* 0x24 */  /* 301 TV */
++	{ 0xa8,0x4c, 30}, /* 0x25 */  /* 301 TV */
++	{ 0x20,0x26, 33}, /* 0x26 */  /* 301 TV */
++	{ 0x31,0xc2, 39}, /* 0x27 */
++	{ 0xbf,0xc8, 35}, /* 0x28 */  /* 856x480 */
++	{ 0x60,0x36, 30}, /* 0x29 */  /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
++	{ 0x40,0x4a, 28}, /* 0x2a */
++	{ 0x9f,0x46, 44}, /* 0x2b */
++	{ 0x97,0x2c, 26}, /* 0x2c */
++	{ 0x44,0xe4, 25}, /* 0x2d */
++	{ 0x7e,0x32, 47}, /* 0x2e */
++	{ 0x8a,0x24, 31}, /* 0x2f */  /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
++	{ 0x97,0x2c, 26}, /* 0x30 */
++	{ 0xce,0x3c, 39}, /* 0x31 */
++	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
++	{ 0x34,0x61, 95}, /* 0x33 */
++	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
++	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
++	{ 0x45,0x6b, 21}, /* 0x36 */
++	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
++	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
++	{ 0x70,0x44,108}, /* 0x39 */  /* 16:9 modes  */
++	{ 0x54,0x42,135}, /* 0x3a */  /* 16:9 modes  */
++	{ 0x41,0x22,157}, /* 0x3b */  /* 16:9 modes  */
++	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
++	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
++	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
++#if 0
++	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
++#endif
++        { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
++	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
++	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
++	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
++	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
++	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
+ 	{ 0xff,0x00,  0}   
+ };
+ 
+@@ -1089,66 +782,10 @@ static const SiS300_VCLKDataStruct  SiS3
+ static const UCHAR  SiS300_ScreenOffset[] =
+ {
+ 	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
+-        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,  /* 0x35 for 848 and 856 */
+-	0x55,0xff			     /* 0x55 for 1360 */	
++        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
++	0x55,0x30,0xff
+ };
+ 
+-typedef struct _SiS300_StResInfoStruct
+-{
+-	USHORT HTotal;
+-	USHORT VTotal;
+-} SiS300_StResInfoStruct;
+-
+-static const SiS300_StResInfoStruct  SiS300_StResInfo[] =
+-{
+-	{ 640,400},
+-	{ 640,350},
+-	{ 720,400},
+-	{ 720,350},
+-	{ 640,480}
+-};
+-
+-typedef struct _SiS300_ModeResInfoStruct
+-{
+-	USHORT HTotal;
+-	USHORT VTotal;
+-	UCHAR  XChar;
+-	UCHAR  YChar;
+-} SiS300_ModeResInfoStruct;
+-
+-static const SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
+-{
+-	{  320, 200, 8, 8},  /* 0x00 */
+-	{  320, 240, 8, 8},  /* 0x01 */
+-	{  320, 400, 8, 8},  /* 0x02 */
+-	{  400, 300, 8, 8},  /* 0x03 */
+-	{  512, 384, 8, 8},  /* 0x04 */
+-	{  640, 400, 8,16},  /* 0x05 */
+-	{  640, 480, 8,16},  /* 0x06 */
+-	{  800, 600, 8,16},  /* 0x07 */
+-	{ 1024, 768, 8,16},  /* 0x08 */
+-	{ 1280,1024, 8,16},  /* 0x09 */
+-	{ 1600,1200, 8,16},  /* 0x0a */
+-	{ 1920,1440, 8,16},  /* 0x0b */
+-	{  720, 480, 8,16},  /* 0x0c */
+-	{  720, 576, 8,16},  /* 0x0d */
+-	{ 1280, 960, 8,16},  /* 0x0e */
+-	{ 1024, 600, 8,16},  /* 0x0f */
+-	{ 1152, 768, 8,16},  /* 0x10 */
+-	{ 2048,1536, 8,16},  /* 0x11 - TW: Not in BIOS! */
+-	{  800, 480, 8,16},  /* 0x12 - TW: New, not in any BIOS */
+-	{ 1024, 576, 8,16},  /* 0x13 - TW: New, not in any BIOS */
+-	{ 1280, 720, 8,16},  /* 0x14 - TW: New, not in any BIOS */
+-	{ 1152, 864, 8,16},  /* 0x15 - TW: New, not in any BIOS */
+-	{  848, 480, 8,16},  /* 0x16 - TW: New, not in any BIOS */
+-	{  856, 480, 8,16},  /* 0x17 - TW: New, not in any BIOS */
+-	{ 1360, 768, 8,16}   /* 0x18 - TW: New, not in any BIOS */
+-};
+-
+-static const UCHAR SiS300_OutputSelect = 0x40;
+-
+-static const UCHAR SiS300_SoftSetting  = 0x30;
+-
+ #ifndef LINUX_XF86
+ static UCHAR SiS300_SR07 = 0x10;
+ #endif
+@@ -1183,7 +820,7 @@ static UCHAR SiS300_CRT2Data_4_10 = 0x80
+ static const USHORT SiS300_RGBSenseData = 0xd1;
+ static const USHORT SiS300_VideoSenseData = 0xb3;
+ static const USHORT SiS300_YCSenseData = 0xb9;
+-static const USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
++static const USHORT SiS300_RGBSenseData2 = 0x0190;
+ static const USHORT SiS300_VideoSenseData2 = 0x0174;
+ static const USHORT SiS300_YCSenseData2 = 0x016b;
+ 
+@@ -1192,15 +829,6 @@ static const UCHAR SiS300_CR40[5][4];
+ static UCHAR SiS300_CR49[2];
+ #endif
+ 
+-static const UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
+-static const UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00};  */
+-static const UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
+-static const UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
+-static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
+-static const UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
+-static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+-static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+-
+ typedef struct _SiS300_PanelDelayTblStruct
+ {
+ 	UCHAR timer[2];
+@@ -1208,7 +836,7 @@ typedef struct _SiS300_PanelDelayTblStru
+ 
+ static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
+ {
+-	{{0x05,0xaa}}, /* TW: From 2.04.5a */
++	{{0x05,0xaa}},
+ 	{{0x05,0x14}},
+ 	{{0x05,0x36}},
+ 	{{0x05,0x14}},
+@@ -1355,309 +983,6 @@ static const SiS300_LCDDataStruct  SiS30
+ 	{    1,   1,1688,1066,1688,1066}
+ };
+ 
+-static const SiS300_LCDDataStruct  SiS300_LCD1280x960Data[] =
+-{
+-	{    9,   2, 800, 500,1800,1000},
+-	{    9,   2, 800, 500,1800,1000},
+-	{    4,   1, 900, 500,1800,1000},
+-	{    4,   1, 900, 500,1800,1000},
+-	{    9,   2, 800, 500,1800,1000},
+-	{   30,  11,1056, 625,1800,1000},
+-	{    5,   3,1350, 800,1800,1000},
+-	{    1,   1,1576,1050,1576,1050},
+-	{    1,   1,1800,1000,1800,1000}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_ExtLCD1400x1050Data[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_ExtLCD1600x1200Data[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_StLCD1400x1050Data[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_StLCD1600x1200Data[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_NoScaleData1400x1050[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS300_LCDDataStruct  SiS300_NoScaleData1600x1200[] =  /* TW: New */
+-{
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0},
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-
+-typedef struct _SiS300_TVDataStruct
+-{
+-	USHORT RVBHCMAX;
+-	USHORT RVBHCFACT;
+-	USHORT VGAHT;
+-	USHORT VGAVT;
+-	USHORT TVHDE;
+-	USHORT TVVDE;
+-	USHORT RVBHRS;
+-	UCHAR FlickerMode;
+-	USHORT HALFRVBHRS;
+-	UCHAR RY1COE;
+-	UCHAR RY2COE;
+-	UCHAR RY3COE;
+-	UCHAR RY4COE;
+-} SiS300_TVDataStruct;
+-
+-static const SiS300_TVDataStruct  SiS300_StPALData[] =
+-{
+-	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+-	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+-	{    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+-	{    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+-	{    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+-	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+-};
+-
+-static const SiS300_TVDataStruct  SiS300_ExtPALData[] =
+-{
+-	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+-	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+-	{   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+-	{    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+-	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
+-	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
+-	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
+-	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}
+-
+-};
+-
+-static const SiS300_TVDataStruct  SiS300_StNTSCData[] =
+-{
+-	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+-	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+-	{    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+-	{    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+-	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+-};
+-
+-static const SiS300_TVDataStruct  SiS300_ExtNTSCData[] =
+-{
+-	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+-	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+-	{  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+-	{  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+-	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+-	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+-	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
+-	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
+-};
+-
+-#if 0
+-static const SiS300_TVDataStruct  SiS300_St1HiTVData[]=
+-{
+-  
+-};
+-#endif
+-
+-static const SiS300_TVDataStruct  SiS300_St2HiTVData[]=
+-{
+- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const SiS300_TVDataStruct  SiS300_ExtHiTVData[]=
+-{
+- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
+- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const UCHAR SiS300_NTSCTiming[] =
+-{
+-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,  /* (in 2.06.50) */
+-/*	0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17,     (in 2.04.5a) */
+-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,  /* (in 2.06.50) */
+-/*	0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02,     (in 2.04.5a) */
+-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+-};
+-
+-static const UCHAR SiS300_PALTiming[] =
+-{
+-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+-        0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,  /* (in 2.06.50) */
+-/*	0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17,     (in 2.04.5a) */
+-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,  /* (in 2.06.50) */
+-/*	0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02,     (in 2.04.5a) */
+-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVExtTiming[] =	 /* TW: New */
+-{
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVSt1Timing[] =   	/* TW: New */
+-{
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVSt2Timing[] =	/* TW: New */
+-{
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVTextTiming[] =   	/* TW: New */
+-{
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Data[] =   	/* TW: New */
+-{
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Simu[] =   	/* TW: New */
+-{
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS300_HiTVGroup3Text[] =   	/* TW: New */
+-{
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+ typedef struct _SiS300_LVDSDataStruct
+ {
+ 	USHORT VGAHT;
+@@ -1666,366 +991,14 @@ typedef struct _SiS300_LVDSDataStruct
+ 	USHORT LCDVT;
+ } SiS300_LVDSDataStruct;
+ 
+-static const SiS300_LVDSDataStruct  SiS300_LVDS320x480Data_1[] =
+-{
+-	{848, 433,400, 525},
+-	{848, 389,400, 525},
+-	{848, 433,400, 525},
+-	{848, 389,400, 525},
+-	{848, 518,400, 525},
+-	{1056,628,400, 525},
+-	{400, 525,400, 525},
+-	{800, 449,1000, 644},
+-	{800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[] =
+-{
+-	{848, 433,1060, 629},
+-	{848, 389,1060, 629},
+-	{848, 433,1060, 629},
+-	{848, 389,1060, 629},
+-	{848, 518,1060, 629},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{800, 449,1000, 644},
+-	{800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[] =
+-{
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{800, 449,1000, 644},
+-	{800, 525,1000, 635}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[] =
+-{
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 518,1344, 806},
+-	{1050, 638,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[] =
+-{
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=  
+-{	
+-	{1048, 442,1688,1066},
+-	{1048, 392,1688,1066},
+-	{1048, 442,1688,1066},
+-	{1048, 392,1688,1066},
+-	{1048, 522,1688,1066},
+-	{1208, 642,1688,1066},
+-	{1432, 810,1688,1066},
+-	{1688,1066,1688,1066}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=  
+-{	
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_1[] =   
+-{
+-        {928, 416, 1688, 1066},
+-	{928, 366, 1688, 1066},
+-	{928, 416, 1688, 1066},
+-	{928, 366, 1688, 1066},
+-	{928, 496, 1688, 1066},
+-	{1088, 616, 1688, 1066},
+-	{1312, 784, 1688, 1066},
+-	{1568, 1040, 1688, 1066},
+-	{1688, 1066, 1688, 1066}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_2[] =  
+-{
+-        {1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_1[]=  
+-{
+-        {1088, 450, 2048,1250},
+-	{1088, 400, 2048,1250},
+-	{1088, 450, 2048,1250},
+-	{1088, 400, 2048,1250},
+-	{1088, 530, 2048,1250},
+-	{1248, 650, 2048,1250},
+-	{1472, 818, 2048,1250},
+-	{1728,1066, 2048,1250},
+-	{1848,1066, 2048,1250},
+-	{2048,1250, 2048,1250}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_2[]= 
+-{
+-        {2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_1[]= 
+-{	
+-	{ 768, 438, 1408, 806},
+-	{ 768, 388, 1408, 806},
+-	{ 768, 438, 1408, 806},
+-	{ 768, 388, 1408, 806},
+-	{ 768, 518, 1408, 806},
+-	{ 928, 638, 1408, 806},
+-	{1152, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_2[]=  
+-{	
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[] =
+-{
+-	{840, 604,1344, 800},
+-	{840, 560,1344, 800},
+-	{840, 604,1344, 800},
+-	{840, 560,1344, 800},
+-	{840, 689,1344, 800},
+-	{1050, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{800, 449,1280, 789},
+-	{800, 525,1280, 785}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[] =
+-{
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{1344, 800,1344, 800},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[] =
+-{
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 518,1344, 806},
+-	{1050, 638,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[] =
+-{
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-/* TW: pass 1:1 data */
+-static const SiS300_LVDSDataStruct  SiS300_LVDSXXXxXXXData_1[]=  
+-{
+-        { 800, 449,  800, 449},
+-	{ 800, 449,  800, 449},
+-	{ 900, 449,  900, 449},
+-	{ 900, 449,  900, 449},
+-	{ 800, 525,  800, 525},  /*  640x480   */
+-	{1056, 628, 1056, 628},  /*  800x600   */
+-	{1344, 806, 1344, 806},  /* 1024x768   */
+-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
+-	/* No other panels ! */
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[] =
+-{
+-	{800, 449, 800, 449},
+-	{800, 449, 800, 449},
+-	{800, 449, 800, 449},
+-	{800, 449, 800, 449},
+-	{800, 525, 800, 525},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_1[] =   /* TW: New */
+-{
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 438,1344, 806},
+-	{840, 409,1344, 806},
+-	{840, 518,1344, 806},
+-	{1050, 638,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_2[] =   /* TW: New */
+-{
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_1[] =   /* TW: New */
+-{	/* TW: Might be temporary (invalid) data */
+-        {928, 416, 1688, 1066},
+-	{928, 366, 1688, 1066},
+-	{1008, 416, 1688, 1066},
+-	{1008, 366, 1688, 1066},
+-	{1200, 530, 1688, 1066},
+-	{1088, 616, 1688, 1066},
+-	{1312, 784, 1688, 1066},
+-	{1568, 1040, 1688, 1066},
+-	{1688, 1066, 1688, 1066}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_2[] =   /* TW: New */
+-{	/* TW: Temporary data. Not valid */
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_1[] =   /* TW: New */
+-{	/* TW: Temporary data. Not valid */
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{800, 449,1280, 801},
+-	{800, 525,1280, 813}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_2[] =   /* TW: New */
+-{	/* TW: Temporary data. Not valid */
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0}
+-};
+-
+-
+-/* TW: New: */
+-static const SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[] =
+-{
+-	{840, 600, 840, 600},
+-	{840, 600, 840, 600},
+-	{840, 600, 840, 600},
+-	{840, 600, 840, 600},
+-	{784, 600, 784, 600},
+-	{1064, 750,1064, 750}
+-};
+-
+-static const SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[] =
+-{
+-	{840, 525, 840, 525},
+-	{840, 525, 840, 525},
+-	{840, 525, 840, 525},
+-	{840, 525, 840, 525},
+-	{784, 525, 784, 525},
+-	{1040, 700,1040, 700}
+-};
+-
+ static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
+ {
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+-	{840, 750, 840, 750},
+-	{936, 836, 936, 836}
++	{ 840, 750, 840, 750},
++	{ 936, 836, 936, 836}
+ };
+ 
+ static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
+@@ -2034,8 +1007,8 @@ static const SiS300_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+-	{840, 625, 840, 625},
+-	{960, 750, 960, 750}
++	{ 840, 625, 840, 625},
++	{ 960, 750, 960, 750}
+ };
+ 
+ static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
+@@ -2044,12 +1017,10 @@ static const SiS300_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+-	{840, 500, 840, 500},
+-	{944, 625, 944, 625}
++	{ 840, 500, 840, 500},
++	{ 944, 625, 944, 625}
+ };
+ 
+-/* TW: new end */
+-
+ typedef struct _SiS300_LVDSDesStruct
+ {
+ 	USHORT LCDHDES;
+@@ -2058,57 +1029,90 @@ typedef struct _SiS300_LVDSDesStruct
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
+ {
++	{ 1059, 626 },   /* 2.08 */
++	{ 1059, 624 },
++	{ 1059, 626 },
++	{ 1059, 624 },
++	{ 1059, 624 },
++	{    0, 627 },
++	{    0, 627 },
++	{    0,   0 },
++	{    0,   0 }
++#if 0
+ 	{0, 626},
+ 	{0, 624},
+ 	{0, 626},
+ 	{0, 624},
+ 	{0, 624},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{0, 627},
++	{0, 627},
++	{0,   0},
++	{0,   0}
++#endif
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
+ {
++	{   0,   0 },  /* 2.08 */
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 },
++	{   0,   0 }
++#if 0
+ 	{1343, 798},
+ 	{1343, 794},
+ 	{1343, 798},
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
++#endif
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
+ {
++	{ 1059, 626 },  /* 2.08 */
++	{ 1059, 624 },
++	{ 1059, 626 },
++	{ 1059, 624 },
++	{ 1059, 624 },
++	{    0, 627 },
++	{    0, 627 },
++	{    0,   0 },
++	{    0,   0 }
++#if 0
+ 	{0, 626},
+ 	{0, 624},
+ 	{0, 626},
+ 	{0, 624},
+ 	{0, 624},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{0, 627},
++	{0, 627},
++	{0,   0},
++	{0,   0}
++#endif
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
+ {
+-	{ 8, 436},
+-	{ 8, 440},
+-	{ 8, 436},
+-	{ 8, 440},
+-	{ 8, 512},
++	{   8, 436},
++	{   8, 440},
++	{   8, 436},
++	{   8, 440},
++	{   8, 512},
+ 	{1343, 798},
+ 	{1343, 794},
+ 	{1343, 798},
+ 	{1343, 794}
+ };
+ 
+-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =
++static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =	/* 1280x1024 */
+ {
+ 	{1343, 798},
+ 	{1343, 794},
+@@ -2116,9 +1120,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
+@@ -2129,9 +1133,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
+@@ -2142,9 +1146,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
+@@ -2155,9 +1159,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
+@@ -2167,10 +1171,10 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1059, 626},
+ 	{1059, 624},
+ 	{1059, 624},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{   0, 627},
++	{   0, 627},
++	{   0,   0},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
+@@ -2181,9 +1185,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
+@@ -2193,23 +1197,23 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1059, 626},
+ 	{1059, 624},
+ 	{1059, 624},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{   0, 627},
++	{   0, 627},
++	{   0,   0},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
+ {
+-	{1343, 0},
+-	{1343, 0},
+-	{1343, 0},
+-	{1343, 0},
+-	{1343, 0},   /* 640x480 - BIOS 1343, 0 */
+-	{1343, 0},
+-	{ 0, 799},
+-	{ 0, 0},
+-	{ 0, 0}
++	{1343,   0},
++	{1343,   0},
++	{1343,   0},
++	{1343,   0},
++	{1343,   0},
++	{1343,   0},
++	{   0, 799},
++	{   0,   0},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
+@@ -2220,9 +1224,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
+@@ -2233,9 +1237,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
+@@ -2244,11 +1248,11 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343, 798},
+ 	{1343, 794},
+-	{1343,   0},  /* 640x480 */
+-	{1343,   0},  /* 800x600 */
+-	{ 0, 805},    /* 1024x768 */
+-	{ 0, 794},    /* 1280x1024 */
+-	{ 0,   0}     /* 1280x960 - not applicable */
++	{1343,   0},    /* 640x480 */
++	{1343,   0},    /* 800x600 */
++	{   0, 805},    /* 1024x768 */
++	{   0, 794},    /* 1280x1024 */
++	{   0,   0}     /* 1280x960 - not applicable */
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
+@@ -2259,9 +1263,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1343, 794},
+ 	{1343,   0},
+ 	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
+@@ -2271,10 +1275,10 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{  0, 627},
++	{  0, 627},
++	{  0,   0},
++	{  0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
+@@ -2285,9 +1289,9 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{1152, 597},
+ 	{1152, 662},
+ 	{1232, 722},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{   0, 805},
++	{   0, 794},
++	{   0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
+@@ -2297,10 +1301,10 @@ static const SiS300_LVDSDesStruct  SiS30
+ 	{976, 527},
+ 	{976, 502},
+ 	{976, 567},
+-	{ 0, 627},
+-	{ 0, 627},
+-	{ 0,   0},
+-	{ 0,   0}
++	{  0, 627},
++	{  0, 627},
++	{  0,   0},
++	{  0,   0}
+ };
+ 
+ static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
+@@ -2472,156 +1476,57 @@ static const SiS300_LVDSDesStruct  SiS30
+  	{   0,   0}
+ };
+ 
+-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_1[]= 
++/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
++static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =	/* 1280x1024 (1366x1024) */
+ {
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0, 806},
+-	{ 0, 0 }
+-};
+-
+-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_2[] = 
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] =   /* TW: New */
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] =   /* TW: New */
+-{
+-	{ 1152, 622 },
+-	{ 1152, 597 },
+-	{ 1152, 622 },
+-	{ 1152, 597 },
+-	{ 1152, 622 },
+-	{ 1232, 722 },
+-	{    0, 0   },
+-	{    0, 794 },
+-	{    0, 0   }
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] =   /* TW: New */
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] =   /* TW: New */
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] =   /* TW: New */
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] =   /* TW: New */
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-
+-/* TW: New */
+-static const SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[] =
+-{
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0}
+-};
+-
+-static const SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[] =
+-{
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0},
+- 	{ 0,   0}
+-};
+-
+-static const SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[] =
+-{
+- 	{256,   0},
+- 	{256,   0},
+- 	{256,   0},
+- 	{256,   0},
+- 	{  0,   0},
+- 	{  0,   0}
++	{1330, 798},  /* 320x200 */
++	{1330, 794},
++	{1330, 798},
++	{1330, 794},
++	{1330,   0},  /* 640x480 / 320x240  */
++	{1343,   0},  /* 800x600 / 400x300  */
++	{   0, 805},  /* 1024x768 / 512x384 */
++	{1688,1066},  /* 1280x1024          */
++	{   0,   0}   /* 1360x1024          */
+ };
+ 
+-static const SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[] =
++static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
+ {
+- 	{256,   0},
+- 	{256,   0},
+- 	{256,   0},
+- 	{256,   0},
+- 	{  0,   0},
+- 	{  0,   0}
++	{1152, 622},
++	{1152, 597},
++	{1152, 622},
++	{1152, 597},
++	{1152, 662},
++	{1232, 722},
++	{   0, 805},
++	{1688,1066},
++	{   0,   0}
++};
++
++/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
++static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =	/* 1024x768 */
++{
++	{1330, 798},  /* 320x200 */
++	{1330, 794},
++	{1330, 798},
++	{1330, 794},
++	{1330,   0},  /* 640x480 / 320x240  */
++	{1343,   0},  /* 800x600 / 400x300  */
++	{   0, 805}   /* 1024x768 / 512x384 */
++};
++
++static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
++{
++	{1152, 622},
++	{1152, 597},
++	{1152, 622},
++	{1152, 597},
++	{1152, 662},
++	{1232, 722},
++	{   0, 805}
+ };
+-/* TW: New end */
+ 
+-/* TW: New for SiS300+301LV */
++
+ typedef struct _SiS300_Part2PortTblStruct
+ {
+  	UCHAR CR[12];
+@@ -2726,6 +1631,28 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01 }}
+ };
+ 
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
++{
++	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
++	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
++	  0x00 }},
++	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
++	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
++	  0x00 }},
++	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
++	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
++	  0x00 }},
++	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
++	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
++	  0x00 }},
++	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
++	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
++	  0x00 }},
++	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
++	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
++	  0x01 }}
++};
++
+ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
+ { 
+ 	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+@@ -2751,55 +1678,31 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01}}
+ };
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
+-{
+-	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00 }},
+-	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00 }},
+-	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00 }},
+-	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00 }},
+-	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+-	  0x00 }},
+-	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+-	  0x01 }},
+-	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01 }}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
+ {
+-	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+-	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+-	  0x00 }},
+-	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+-	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+-	  0x00 }},
+-	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+-	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+-	  0x00 }},
+-	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+-	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+-	  0x00 }},
+-	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+-	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
++	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 	  0x00 }},
+-	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+-	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
++	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
++	  0x00}},
++	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++	  0x00}},
++	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
++	  0x00}},
++	{{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++	  0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
++	  0x00}},
++	{{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++	  0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
++	  0x01}},
++	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 	  0x01 }}
+-};
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
+-{
++#if 0
+ 	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+ 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+ 	  0x00 }},
+@@ -2821,6 +1724,32 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+ 	  0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
+ 	  0x01 }}
++#endif
++};
++
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
++{
++	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++	  0x00 }},
++	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++	  0x00 }},
++	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++	  0x00 }},
++	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++	  0x00 }},
++	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
++	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
++	  0x00 }},
++	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
++	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
++	  0x01 }},
++	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	  0x01 }}
+ };
+ 
+ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
+@@ -2870,32 +1799,29 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01 }}
+ };
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
+ {
+-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 	  0x00 }},
+-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 	  0x00 }},
+-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
++	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ 	  0x00 }},
+-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
++	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ 	  0x00 }},
+-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
++	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+ 	  0x00 }},
+-	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+-	  0x01 }},
+-	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
++	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+ 	  0x01 }}
+ };
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
+ {
+ 	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+ 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+@@ -2920,28 +1846,6 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01 }}
+ };
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
+-{
+-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+-	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+-	  0x00 }},
+-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+-	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+-	  0x00 }},
+-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+-	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+-	  0x00 }},
+-	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+-	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+-	  0x00 }},
+-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+-	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+-	  0x00 }},
+-	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+-	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+-	  0x01 }}
+-};
+-
+ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
+ {
+ 	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+@@ -2967,6 +1871,31 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01 }}
+ };
+ 
++static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
++{
++	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00 }},
++	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00 }},
++	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00 }},
++	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00 }},
++	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++	  0x00 }},
++	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++	  0x01 }},
++	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	  0x01 }}
++};
++
+ static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
+ {
+ 	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
+@@ -2992,207 +1921,6 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x01}}
+ };
+ 
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
+-{
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
+-{
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-          0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+-	  0x00}},
+-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
+-{
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
+-{
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
+-{
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
+-{
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+-	  0x00}},
+-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
+-{
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
+-{
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-/* TW: New */
+ static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
+ {
+ 	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+@@ -3302,9 +2030,7 @@ static const SiS300_LVDSCRT1DataStruct  
+ 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 	  0x01 }}
+ };
+-/* TW: New end */
+ 
+-/* TW: New */
+ typedef struct _SiS300_CHTVRegDataStruct
+ {
+ 	UCHAR Reg[16];
+@@ -3361,9 +2087,7 @@ static const SiS300_CHTVRegDataStruct Si
+ 	{{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
+ 	{{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
+ };
+-/* TW: New end */
+ 
+-/* TW: New */
+ static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+ 
+ static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+@@ -3375,6 +2099,5 @@ static const UCHAR SiS300_CHTVVCLKUPAL[]
+ static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+ 
+ static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+-/* TW: New end */
+ 
+ 
+--- linux-2.6.0-test6/drivers/video/sis/310vtbl.h	2003-06-14 12:18:23.000000000 -0700
++++ 25/drivers/video/sis/310vtbl.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,7 +1,37 @@
+-
+-
+-/* Register settings for SiS 310/325/330 series */
+-
++/* $XFree86$ */
++/*
++ * Register settings for SiS 315/330 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+ 
+ typedef struct _SiS310_StStruct
+ {
+@@ -39,466 +69,12 @@ static const SiS310_StStruct SiS310_SMod
+ 	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+ };
+ 
+-typedef struct _SiS310_StandTableStruct
+-{
+-	UCHAR CRT_COLS;
+-	UCHAR ROWS;
+-	UCHAR CHAR_HEIGHT;
+-	USHORT CRT_LEN;
+-	UCHAR SR[4];
+-	UCHAR MISC;
+-	UCHAR CRTC[0x19];
+-	UCHAR ATTR[0x14];
+-	UCHAR GRC[9];
+-} SiS310_StandTableStruct;
+-
+-static const SiS310_StandTableStruct SiS310_StandTable[]=
+-{
+-/* 0x00: MD_0_200 */
+- {
+-  0x28,0x18,0x08,0x0800,
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x01: MD_1_200 */
+- {
+-  0x28,0x18,0x08,0x0800,
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x02: MD_2_200 */
+- {
+-  0x50,0x18,0x08,0x1000,
+-  {0x01,0x03,0x00,0x02},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x03: MD_3_200 - mode 0x03 - 0 */
+- {
+-  0x50,0x18,0x08,0x1000,
+-  {0x01,0x03,0x00,0x02},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x04: MD_4 */
+- {
+-  0x28,0x18,0x08,0x4000,
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+-   0xff},
+-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x03,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+-   0xff}
+- },
+-/* 0x05: MD_5 */
+- {
+-  0x28,0x18,0x08,0x4000,
+-  {0x09,0x03,0x00,0x02},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+-   0xff},
+-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x03,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+-   0xff}
+- },
+-/* 0x06: MD_6 */
+- {
+-  0x50,0x18,0x08,0x4000,
+-  {0x01,0x01,0x00,0x06},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+-   0xff},
+-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+-   0x01,0x00,0x01,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+-   0xff}
+- },
+-/* 0x07: MD_7 */
+- {
+-  0x50,0x18,0x0e,0x1000,
+-  {0x00,0x03,0x00,0x03},
+-  0xa6,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+-   0x0e,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+-   0xff}
+- },
+-/* 0x08: MDA_DAC */
+- {
+-  0x00,0x00,0x00,0x0000,
+-  {0x00,0x00,0x00,0x15},
+-  0x15,
+-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+-   0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+-   0x15,0x15,0x15,0x15},
+-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x3f}
+- },
+-/* 0x09: CGA_DAC */
+- {
+-  0x00,0x10,0x04,0x0114,
+-  {0x11,0x09,0x15,0x00},
+-  0x10,
+-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+-   0x04},
+-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+-   0x3e,0x2b,0x3b,0x2f},
+-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+-   0x3f}
+- },
+-/* 0x0a: EGA_DAC */
+- {
+-  0x00,0x10,0x04,0x0114,
+-  {0x11,0x05,0x15,0x20},
+-  0x30,
+-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+-   0x06},
+-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+-   0x1e,0x0b,0x1b,0x0f},
+-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+-   0x3f}
+- },
+-/* 0x0b: VGA_DAC */
+- {
+-  0x00,0x10,0x04,0x0114,
+-  {0x11,0x09,0x15,0x2a},
+-  0x3a,
+-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+-   0x1f},
+-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+-   0x1c,0x0e,0x11,0x15},
+-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+-   0x04}
+- },
+-/* 0x0c */ 
+- {
+-  0x08,0x0c,0x10,0x0a08,
+-  {0x0c,0x0e,0x10,0x0b},
+-  0x0c,
+-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+-   0x06},
+-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+-   0x00,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00}
+- },
+-/* 0x0d: MD_D */
+- {
+-  0x28,0x18,0x08,0x2000,
+-  {0x09,0x0f,0x00,0x06},
+-  0x63,
+-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff}
+- },
+-/* 0x0e: MD_E */
+- {
+-  0x50,0x18,0x08,0x4000,
+-  {0x01,0x0f,0x00,0x06},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff}
+- },
+-/* 0x0f: ExtVGATable - modes > 0x13 */
+- {
+-  0x00,0x00,0x00,0x0000,
+-  {0x01,0x0f,0x00,0x0e},
+-  0x23,
+-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+-   0x01,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+-   0xff}
+- },
+-/* 0x10: ROM_SAVEPTR */
+- {
+-  0x9f,0x3b,0x00,0x00c0,
+-  {0x00,0x00,0x00,0x00},
+-  0x00,
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+-   0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00,0x00,0x00,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x00}
+- },
+-/* 0x11: MD_F */
+- {
+-  0x50,0x18,0x0e,0x8000,
+-  {0x01,0x0f,0x00,0x06},
+-  0xa2,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+-   0xff},
+-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+-   0x0b,0x00,0x05,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+-   0xff}
+- },
+-/* 0x12: MD_10 */
+- {
+-  0x50,0x18,0x0e,0x8000,
+-  {0x01,0x0f,0x00,0x06},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff}
+- },
+-/* 0x13: MD_0_350 */
+- {
+-  0x28,0x18,0x0e,0x0800,
+-  {0x09,0x03,0x00,0x02},
+-  0xa3,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x14: MD_1_350 */
+- {
+-  0x28,0x18,0x0e,0x0800,
+-  {0x09,0x03,0x00,0x02},
+-  0xa3,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x15: MD_2_350 */
+- {
+-  0x50,0x18,0x0e,0x1000,
+-  {0x01,0x03,0x00,0x02},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x16: MD_3_350 - mode 0x03 - 1 */
+- {
+-  0x50,0x18,0x0e,0x1000,
+-  {0x01,0x03,0x00,0x02},
+-  0xa3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x08,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x17: MD_0_1_400 */
+- {
+-  0x28,0x18,0x10,0x0800,
+-  {0x08,0x03,0x00,0x02},
+-  0x67,
+-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x0c,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
+- {
+-  0x50,0x18,0x10,0x1000,
+-  {0x00,0x03,0x00,0x02},
+-  0x67,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x0c,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+-   0xff}
+- },
+-/* 0x19: MD_7_400 */
+- {
+-  0x50,0x18,0x10,0x1000,
+-  {0x00,0x03,0x00,0x02},
+-  0x66,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+-   0x0e,0x00,0x0f,0x08},
+-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+-   0xff}
+- },
+-/* 0x1a: MD_11 */
+- {
+-  0x50,0x1d,0x10,0xa000,
+-  {0x01,0x0f,0x00,0x06},
+-  0xe3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
+-   0xff},
+-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+-   0xff}
+- },
+-/* 0x1b: ExtEGATable - Modes <= 0x02 */
+- {
+-  0x50,0x1d,0x10,0xa000,
+-  {0x01,0x0f,0x00,0x06},
+-  0xe3,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+-   0x01,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+-   0xff}
+- },
+-/* 0x1c: MD_13 */
+- {
+-  0x28,0x18,0x08,0x2000,
+-  {0x01,0x0f,0x00,0x0e},
+-  0x63,
+-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+-   0xff},
+-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+-   0x41,0x00,0x0f,0x00},
+-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+-   0xff}
+- }
+-};
+-
+ typedef struct _SiS310_ExtStruct
+ {
+ 	UCHAR Ext_ModeID;
+ 	USHORT Ext_ModeFlag;
+ 	USHORT Ext_ModeInfo;
+-	USHORT Ext_Point;    /* TW: Address of table entry in (older) BIOS image */
+ 	USHORT Ext_VESAID;
+-	UCHAR Ext_VESAMEMSize;
+ 	UCHAR Ext_RESINFO;
+ 	UCHAR VB_ExtTVFlickerIndex;
+ 	UCHAR VB_ExtTVEdgeIndex;
+@@ -506,93 +82,93 @@ typedef struct _SiS310_ExtStruct
+ 	UCHAR REFindex;
+ } SiS310_ExtStruct;
+ 
+-/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
+ static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
+ {
+-	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x? */
+-	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x8 */
+-/*	{0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},    */    /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
+-	{0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},          /* 640x400x8 */
+-/*	{0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},    */    /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
+-	{0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x8 */
+-/*	{0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},    */    /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
+-/*      {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},    */    /* 720x480x8 */
+-        {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x8 BIOS (301/LVDS) */
+-	{0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x8 */
+-	{0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x16 */
+-	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x16 */
+-	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x32 */
+-	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x32 */
+-	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x? */
+-	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x8 */
+-	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
+-	{0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
+-	{0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
+-	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
+-	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
+-	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
+-	{0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x16 */
+-	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
+-	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x16 */
+-	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+-	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x16 */
+-	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+-	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x16 */
+-	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240 */
+-	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
+-  	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 650/301 BIOS */
+-	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
+-	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
+- 	{0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},          /* BIOS (301+LVDS) */
+-	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200 */
+-	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x8 fstn add new mode*/
+-	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x16 fstn add new mode*/
+-	{0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28},          /* TW: inserted 512x384x32 */
+-	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+-	{0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10},          /* TW: Inserted 640x400x32 */
+-	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x32 */
+-	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x32 */
+-	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x32 */
+-	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
+-	{0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
+-	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x8 */
+-	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x16 */
+-	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x32 */
+-	{0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x8 */
+-	{0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x16 */
+-	{0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x32 */
+-	{0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x8 */
+-	{0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x8 */
+-	{0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x16 */
+-	{0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x16 */
+-	{0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x32 */
+-	{0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},	   /* 1024x576x32 */
+-	{0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x32 */
+-	{0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x8 */
+-	{0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x16 */
+-	{0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x8 - TW */
+-	{0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x16 - TW */
+-	{0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x32 - TW */
+-        /* TW: 650/LVDS BIOS new modes */
+-	{0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x8 */
+-	{0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x16 */
+-	{0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x32 */
+-	{0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x8 */
+-	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
+-	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
+-	{0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},    /* TW: NEW 1152x864 - not in BIOS */
+-	{0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+-	{0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+-	{0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},    /* TW: NEW 848x480 - not in BIOS */
+-	{0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+-	{0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+-	{0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},    /* TW: NEW 856x480 - not in BIOS */
+-	{0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+-	{0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+-	{0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},    /* TW: NEW 1360x768 - not in BIOS */
+-	{0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+-	{0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+-	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
++	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x? */
++	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x8 */
++        {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x10}, /* 640x400x8 */
++	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x8 */
++        {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x8 */
++	{0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x8 */
++	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x16 */
++	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x16 */
++	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x32 */
++	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x32 */
++	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */
++	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */
++	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
++	{0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
++	{0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
++	{0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x15 */
++	{0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x16 */
++	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x08},
++	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x16 */
++	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x00},
++	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x16 */
++	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
++	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */
++	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
++	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
++	{0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x8  */
++	{0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x8  */
++  	{0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x8  */
++	{0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x16 */
++	{0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x16 */
++ 	{0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x16 */
++	{0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x8  */
++	{0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x8  fstn */
++	{0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */
++	{0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x32 */
++	{0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x07,0x10},
++	{0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x07,0x10}, /* 640x400x32 */
++	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x32 */
++	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x32 */
++	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */
++	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
++	{0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
++	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
++	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
++	{0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
++	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
++	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
++	{0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
++	{0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x8 */
++	{0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */
++	{0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */
++	{0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
++	{0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x32 */
++	{0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */
++	{0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
++	{0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
++	{0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x16 */
++	{0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
++	{0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
++	{0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
++	{0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */
++	{0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */
++	{0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */
++	{0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
++	{0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
++	{0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
++	{0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */
++	{0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
++	{0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
++	{0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45}, /* 848x480 */
++	{0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
++	{0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
++	{0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47}, /* 856x480 */
++	{0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
++	{0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
++	{0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */
++	{0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
++	{0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
++	{0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x32 */
++	{0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x32 */
++	{0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x32 */
++	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x8 */
++	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x16 */
++	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x4a}, /* 768x576x32 */
++	{0xff,0x0000,0x0000,0x0000,0x00,            0x00,0x00,0x00,0x00}
+ };
+ 
+ typedef struct _SiS310_Ext2Struct
+@@ -604,89 +180,87 @@ typedef struct _SiS310_Ext2Struct
+ 	UCHAR  ModeID;
+ 	USHORT XRes;
+ 	USHORT YRes;
+-	USHORT ROM_OFFSET;
+ } SiS310_Ext2Struct;
+ 
+ static const SiS310_Ext2Struct SiS310_RefIndex[]=
+ {
+-/*	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81},    0x0 - TW: Patch for Chrontel 7019  */
+-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
+-	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
+-	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
+-	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
+-	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
+-	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
+-	{0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
+-	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
+-/*	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57},    0x8 - TW: Patch for Chrontel 7019  */
+-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
+-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
+-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
+-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
+-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
+-	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
+-	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
+-	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
+-	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
+-	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
+-	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
+-	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
+-	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
+-	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
+-	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
+-	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
+-	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
+-	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
+-	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
+-	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
+-	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
+-	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
+-	{0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
+-	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
+-	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
+-	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
+-	{0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
+-	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
+-	{0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
+-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
+-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
+-	{0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
+-	{0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
+-	{0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
+-	{0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
+-	{0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
+-	{0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
+-	{0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
+-	{0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
+-	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
+-	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
+-	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
+-	{0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
+-	{0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
+-	{0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
+-	{0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
+-	{0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
+-	{0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
+-	{0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
+-	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
+-	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
+-	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
+-	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+-	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
+-	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
+-	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
+-        {0x0077,0x42,0x12,0x08,0x23,1280, 768,0x0000}, /* 0x40 */  
+-	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */  
+-	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */    /* TW: new, not in any BIOS */
+-	{0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
+-	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
+-	{0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+-	{0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
+-	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+-	{0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
+-	{0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+-	{0xffff,0x00,0x00,0x00,0x00,   0,   0,0x0000}
+-}; 
++	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */
++	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */
++	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */
++	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */
++	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */
++	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */
++	{0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */
++	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */
++	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */
++	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */
++	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */
++	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */
++	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */
++	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */
++	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */
++	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */
++	{0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */
++	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */
++	{0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */
++	{0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */
++	{0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */
++	{0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */
++	{0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */
++	{0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */
++	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */
++	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */
++	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */
++	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */
++	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */
++	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */
++	{0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */
++	{0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */
++	{0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */
++	{0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */
++	{0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */
++	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */
++	{0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */
++	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */
++	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */
++	{0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */
++	{0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */
++	{0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */
++	{0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */
++	{0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */
++	{0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */
++	{0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */
++	{0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */
++	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */
++	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */
++	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */
++	{0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */
++	{0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */
++	{0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */
++	{0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */
++	{0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */
++	{0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */
++	{0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */
++	{0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */
++	{0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */
++	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */
++	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */
++	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */
++	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */
++	{0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */    /* FSTN 320x240 */
++        {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */    /* TW: 0x5b was 0x12 */
++	{0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */
++	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */
++	{0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */
++	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */
++	{0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
++	{0xc067,0x46,0x55,0x0b,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
++	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
++	{0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
++	{0x0067,0x49,0x58,0x0c,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
++	{0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */
++	{0xffff,0x00,0x00,0x00,0x00,   0,   0}
++};
+ 
+ typedef struct _SiS310_CRT1TableStruct
+ {
+@@ -710,7 +284,7 @@ static const SiS310_CRT1TableStruct SiS3
+  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
+    0x00}}, /* 0x4 */
+-#if 0   
++#if 0
+  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
+    0x00}}, /* 0x5 */
+@@ -940,19 +514,25 @@ static const SiS310_CRT1TableStruct SiS3
+    0x00}},  /* 0x4b */ 
+  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
+    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+-   0x01}}   /* 0x4c */
++   0x01}},  /* 0x4c */
++ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
++   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
++   0x01}},  /* 0x4d */
++ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
++   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}   /* 0x4e */
+ };
+ 
+-
+ typedef struct _SiS310_MCLKDataStruct
+ {
+ 	UCHAR SR28,SR29,SR2A;
+ 	USHORT CLOCK;
+ } SiS310_MCLKDataStruct;
+ 
++#ifdef LINUXBIOS
+ static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+ {
+-	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
++	{ 0x3b,0x22,0x01,143},
+ 	{ 0x5c,0x23,0x01,166},
+ 	{ 0x5c,0x23,0x01,166},
+ 	{ 0x5c,0x23,0x01,166},
+@@ -962,7 +542,7 @@ static const SiS310_MCLKDataStruct SiS31
+ 	{ 0x5c,0x23,0x01,166}
+ };
+ 
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
+ {
+ 	{ 0x5a,0x64,0x82, 66},
+ 	{ 0xb3,0x45,0x82, 83},
+@@ -973,8 +553,22 @@ static const SiS310_MCLKDataStruct SiS31
+ 	{ 0x37,0x22,0x82,133},
+ 	{ 0x37,0x22,0x82,133}
+ };
++#endif
++
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
++{
++	{ 0x5c,0x23,0x01,166},
++	{ 0x5c,0x23,0x01,166},
++	{ 0x7c,0x08,0x01,200},
++	{ 0x79,0x06,0x01,250},
++	{ 0x7c,0x08,0x01,200},
++	{ 0x7c,0x08,0x01,200},
++	{ 0x7c,0x08,0x01,200},
++	{ 0x79,0x06,0x01,250}
++};
+ 
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =   /* @ 0x54 */
++#ifdef LINUXBIOS
++static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
+ {
+ 	{ 0x5c,0x23,0x01,166},
+ 	{ 0x5c,0x23,0x01,166},
+@@ -985,8 +579,9 @@ static const SiS310_MCLKDataStruct SiS31
+ 	{ 0x7c,0x08,0x01,200},
+ 	{ 0x79,0x06,0x01,250}
+ };
++#endif
+ 
+-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
++static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
+ {
+         { 0x29,0x21,0x82,150},
+ 	{ 0x5c,0x23,0x82,166},
+@@ -998,6 +593,7 @@ static const SiS310_MCLKDataStruct SiS31
+ 	{ 0x37,0x22,0x82,133}
+ };
+ 
++#ifdef LINUXBIOS
+ typedef struct _SiS310_ECLKDataStruct
+ {
+  	UCHAR SR2E,SR2F,SR30;
+@@ -1011,6 +607,7 @@ static const SiS310_ECLKDataStruct SiS31
+ 	{ 0x5c,0x23,0x01,166},
+ 	{ 0x5c,0x23,0x01,166}
+ };
++#endif
+ 
+ typedef struct _SiS310_VCLKDataStruct
+ {
+@@ -1020,22 +617,22 @@ typedef struct _SiS310_VCLKDataStruct
+ 
+ static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
+ {
+-	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x5647 */
+-	{ 0x4e,0xe4, 28}, /* 0x1 */
+-	{ 0x57,0xe4, 31}, /* 0x2 */
+-	{ 0xc3,0xc8, 36}, /* 0x3 */
+-	{ 0x42,0xe2, 40}, /* 0x4 */
+-	{ 0xfe,0xcd, 43}, /* 0x5 */
+-	{ 0x5d,0xc4, 44}, /* 0x6 */
+-	{ 0x52,0xe2, 49}, /* 0x7 */
+-	{ 0x53,0xe2, 50}, /* 0x8 */
+-	{ 0x74,0x67, 52}, /* 0x9 */
+-	{ 0x6d,0x66, 56}, /* 0xa */
+-	{ 0x5a,0x64, 65}, /* 0xb */   /* TW: was 6c c3 - WRONG */
+-	{ 0x46,0x44, 67}, /* 0xc */
+-	{ 0xb1,0x46, 68}, /* 0xd */
+-	{ 0xd3,0x4a, 72}, /* 0xe */
+-	{ 0x29,0x61, 75}, /* 0xf */
++	{ 0x1b,0xe1, 25}, /* 0x00 */
++	{ 0x4e,0xe4, 28}, /* 0x01 */
++	{ 0x57,0xe4, 31}, /* 0x02 */
++	{ 0xc3,0xc8, 36}, /* 0x03 */
++	{ 0x42,0xe2, 40}, /* 0x04 */
++	{ 0xfe,0xcd, 43}, /* 0x05 */
++	{ 0x5d,0xc4, 44}, /* 0x06 */
++	{ 0x52,0xe2, 49}, /* 0x07 */
++	{ 0x53,0xe2, 50}, /* 0x08 */
++	{ 0x74,0x67, 52}, /* 0x09 */
++	{ 0x6d,0x66, 56}, /* 0x0a */
++	{ 0x5a,0x64, 65}, /* 0x0b */  /* TW: was 6c c3 - WRONG */
++	{ 0x46,0x44, 67}, /* 0x0c */
++	{ 0xb1,0x46, 68}, /* 0x0d */
++	{ 0xd3,0x4a, 72}, /* 0x0e */
++	{ 0x29,0x61, 75}, /* 0x0f */
+ 	{ 0x6e,0x46, 76}, /* 0x10 */
+ 	{ 0x2b,0x61, 78}, /* 0x11 */
+ 	{ 0x31,0x42, 79}, /* 0x12 */
+@@ -1045,7 +642,7 @@ static const SiS310_VCLKDataStruct SiS31
+ 	{ 0x62,0x44, 94}, /* 0x16 */
+ 	{ 0x2b,0x41,104}, /* 0x17 */
+ 	{ 0x3a,0x23,105}, /* 0x18 */
+-	{ 0x70,0x44,108}, /* 0x19 */
++	{ 0x70,0x44,108}, /* 0x19 */  /* 1400x1050 LCD */
+ 	{ 0x3c,0x23,109}, /* 0x1a */
+ 	{ 0x5e,0x43,113}, /* 0x1b */
+ 	{ 0xbc,0x44,116}, /* 0x1c */
+@@ -1078,12 +675,12 @@ static const SiS310_VCLKDataStruct SiS31
+ 	{ 0xea,0x08,340}, /* 0x37 */
+ 	{ 0xe8,0x07,376}, /* 0x38 */
+ 	{ 0xde,0x06,389}, /* 0x39 */
+-	{ 0x52,0x2a, 54}, /* 0x3a */
+-	{ 0x52,0x6a, 27}, /* 0x3b */
+-	{ 0x62,0x24, 70}, /* 0x3c */
+-	{ 0x62,0x64, 70}, /* 0x3d */
+-	{ 0xa8,0x4c, 30}, /* 0x3e */
+-	{ 0x20,0x26, 33}, /* 0x3f */
++	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
++	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
++	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
++	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
++	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
++	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
+ 	{ 0x31,0xc2, 39}, /* 0x40 */
+ 	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
+ 	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
+@@ -1096,7 +693,7 @@ static const SiS310_VCLKDataStruct SiS31
+ 	{ 0xce,0x3c, 39}, /* 0x49 */
+ 	{ 0x52,0x4a, 36}, /* 0x4a */  /* Chrontel */
+ 	{ 0x34,0x61, 95}, /* 0x4b */
+-	{ 0x78,0x27,108}, /* 0x4c - was 102 */  /* TW: Last entry in 650/301 BIOS */
++	{ 0x78,0x27,108}, /* 0x4c - was 102 */
+ 	{ 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
+ 	{ 0x41,0x4e, 21}, /* 0x4e */
+ 	{ 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
+@@ -1110,7 +707,8 @@ static const SiS310_VCLKDataStruct SiS31
+ 	{ 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
+ 	{ 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
+ 	{ 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
+-	{ 0x56,0x07,156}  /* 0x5a - added for 1400x1050-75 */
++	{ 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
++   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
+ };
+ 
+ typedef struct _SiS310_VBVCLKDataStruct
+@@ -1121,22 +719,22 @@ typedef struct _SiS310_VBVCLKDataStruct
+ 
+ static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+ {
+-	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x579c */
+-	{ 0x4e,0xe4, 28}, /* 0x1 */
+-	{ 0x57,0xe4, 31}, /* 0x2 */
+-	{ 0xc3,0xc8, 36}, /* 0x3 */
+-	{ 0x42,0x47, 40}, /* 0x4 */
+-	{ 0xfe,0xcd, 43}, /* 0x5 */
+-	{ 0x5d,0xc4, 44}, /* 0x6 */
+-	{ 0x52,0x47, 49}, /* 0x7 */
+-	{ 0x53,0x47, 50}, /* 0x8 */
+-	{ 0x74,0x67, 52}, /* 0x9 */
+-	{ 0x6d,0x66, 56}, /* 0xa */
+-	{ 0x35,0x62, 65}, /* 0xb */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
+-	{ 0x46,0x44, 67}, /* 0xc */
+-	{ 0xb1,0x46, 68}, /* 0xd */
+-	{ 0xd3,0x4a, 72}, /* 0xe */
+-	{ 0x29,0x61, 75}, /* 0xf */
++	{ 0x1b,0xe1, 25}, /* 0x00 */
++	{ 0x4e,0xe4, 28}, /* 0x01 */
++	{ 0x57,0xe4, 31}, /* 0x02 */
++	{ 0xc3,0xc8, 36}, /* 0x03 */
++	{ 0x42,0x47, 40}, /* 0x04 */
++	{ 0xfe,0xcd, 43}, /* 0x05 */
++	{ 0x5d,0xc4, 44}, /* 0x06 */
++	{ 0x52,0x47, 49}, /* 0x07 */
++	{ 0x53,0x47, 50}, /* 0x08 */
++	{ 0x74,0x67, 52}, /* 0x09 */
++	{ 0x6d,0x66, 56}, /* 0x0a */
++	{ 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
++	{ 0x46,0x44, 67}, /* 0x0c */
++	{ 0xb1,0x46, 68}, /* 0x0d */
++	{ 0xd3,0x4a, 72}, /* 0x0e */
++	{ 0x29,0x61, 75}, /* 0x0f */
+ 	{ 0x6d,0x46, 75}, /* 0x10 */
+ 	{ 0x41,0x43, 78}, /* 0x11 */
+ 	{ 0x31,0x42, 79}, /* 0x12 */
+@@ -1146,7 +744,7 @@ static const SiS310_VBVCLKDataStruct SiS
+ 	{ 0x62,0x44, 94}, /* 0x16 */
+ 	{ 0x2b,0x22,104}, /* 0x17 */
+ 	{ 0x49,0x24,105}, /* 0x18 */
+-	{ 0xf8,0x2f,108}, /* 0x19 */
++	{ 0xf8,0x2f,108}, /* 0x19 */  /* 1400x1050 LCD */
+ 	{ 0x3c,0x23,109}, /* 0x1a */
+ 	{ 0x5e,0x43,113}, /* 0x1b */
+ 	{ 0xbc,0x44,116}, /* 0x1c */
+@@ -1179,19 +777,19 @@ static const SiS310_VBVCLKDataStruct SiS
+ 	{ 0xea,0x08,340}, /* 0x37 */
+ 	{ 0xe8,0x07,376}, /* 0x38 */
+ 	{ 0xde,0x06,389}, /* 0x39 */
+-	{ 0x52,0x2a, 54}, /* 0x3a */
+-	{ 0x52,0x6a, 27}, /* 0x3b */
+-	{ 0x62,0x24, 70}, /* 0x3c */
+-	{ 0x62,0x64, 70}, /* 0x3d */
+-	{ 0xa8,0x4c, 30}, /* 0x3e */
+-	{ 0x20,0x26, 33}, /* 0x3f */
++	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
++	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
++	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
++	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
++	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
++	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
+ 	{ 0x31,0xc2, 39}, /* 0x40 */
+-	{ 0x2e,0x48, 25}, /* 0x41 */
+-	{ 0x24,0x46, 25}, /* 0x42 */
+-	{ 0x26,0x64, 28}, /* 0x43 */
+-	{ 0x37,0x64, 40}, /* 0x44 */
+-	{ 0xa1,0x42,108}, /* 0x45 */
+-	{ 0x37,0x61,100}, /* 0x46 */
++	{ 0x2e,0x48, 25}, /* 0x41 */  /* Replacement for LCD on 315 for index 0 */
++	{ 0x24,0x46, 25}, /* 0x42 */  /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
++	{ 0x26,0x64, 28}, /* 0x43 */  /* Replacement for LCD on 315 for index 1 */
++	{ 0x37,0x64, 40}, /* 0x44 */  /* Replacement for LCD on 315 for index 4 */
++	{ 0xa1,0x42,108}, /* 0x45 */  /* 1280x960 LCD */
++	{ 0x37,0x61,100}, /* 0x46 */  /* 1280x960 LCD */
+ 	{ 0x78,0x27,108}, /* 0x47 */
+ 	{ 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
+ 	{ 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
+@@ -1211,72 +809,17 @@ static const SiS310_VBVCLKDataStruct SiS
+ 	{ 0xbf,0xc8, 35}, /* 0x57 */  /* 856x480-38i,60  */
+ 	{ 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+ 	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  - UNUSED */
+-	{ 0x56,0x07,156}  /* 0x5a */  /* 1400x1050-75 - UNUSED */
++	{ 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 - UNUSED */
++   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
+ };
+ 
+ static const UCHAR SiS310_ScreenOffset[] = 
+ {
+         0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
+-	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
++	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
+ 	0xff
+-};      /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
+-
+-typedef struct _SiS310_StResInfoStruct
+-{
+-	USHORT HTotal;
+-	USHORT VTotal;
+-} SiS310_StResInfoStruct;
+-
+-static const SiS310_StResInfoStruct SiS310_StResInfo[]=
+-{
+-	{ 640,400},
+-	{ 640,350},
+-	{ 720,400},
+-	{ 720,350},
+-	{ 640,480}
+-};
+-
+-typedef struct _SiS310_ModeResInfoStruct
+-{
+-	USHORT HTotal;
+-	USHORT VTotal;
+-	UCHAR  XChar;
+-	UCHAR  YChar;
+-} SiS310_ModeResInfoStruct;
+-
+-static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
+-{
+-	{  320, 200, 8, 8},   /* 0x00 */
+-	{  320, 240, 8, 8},   /* 0x01 */
+-	{  320, 400, 8, 8},   /* 0x02 */
+-	{  400, 300, 8, 8},   /* 0x03 */
+-	{  512, 384, 8, 8},   /* 0x04 */
+-	{  640, 400, 8,16},   /* 0x05 */
+-	{  640, 480, 8,16},   /* 0x06 */
+-	{  800, 600, 8,16},   /* 0x07 */
+-	{ 1024, 768, 8,16},   /* 0x08 */
+-	{ 1280,1024, 8,16},   /* 0x09 */
+-	{ 1600,1200, 8,16},   /* 0x0a */
+-	{ 1920,1440, 8,16},   /* 0x0b */
+-	{ 2048,1536, 8,16},   /* 0x0c */
+-	{  720, 480, 8,16},   /* 0x0d */
+-	{  720, 576, 8,16},   /* 0x0e */
+-	{ 1280, 960, 8,16},   /* 0x0f */
+-	{  800, 480, 8,16},   /* 0x10 */
+-	{ 1024, 576, 8,16},   /* 0x11 */
+-	{ 1280, 720, 8,16},   /* 0x12 */
+-	{  856, 480, 8,16},   /* 0x13 - TW: New, not in any BIOS */
+-	{ 1280, 768, 8,16},   /* 0x14 20; TW: New */
+-	{ 1400,1050, 8,16},   /* 0x15 21; TW: New */
+-	{ 1152, 864, 8,16},   /* 0x16 - TW: New, not in any BIOS */
+-	{  848, 480, 8,16},   /* 0x17 - TW: New, not in any BIOS */
+-	{ 1360, 768, 8,16}    /* 0x18 - TW: New, not in any BIOS */
+ };
+ 
+-static const UCHAR SiS310_OutputSelect = 0x40;
+-
+-static const UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
+-
+ static const UCHAR SiS310_SR15[8][4]={
+ 	{0x00,0x04,0x60,0x60},
+ 	{0x0f,0x0f,0x0f,0x0f},
+@@ -1322,16 +865,6 @@ static const USHORT SiS310_VideoSenseDat
+ static const USHORT SiS310_YCSenseData2    = 0x016b;
+ #endif
+ 
+-static const UCHAR SiS310_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
+-static const UCHAR SiS310_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+-static const UCHAR SiS310_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};  /* TW: palm*/
+-static const UCHAR SiS310_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};  /* TW: paln*/
+-static const UCHAR SiS310_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
+-static const UCHAR SiS310_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
+-static const UCHAR SiS310_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};  /* TW: palm 301b*/
+-static const UCHAR SiS310_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};  /* TW: paln 301b*/
+-static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
+-
+ typedef struct _SiS310_LCDDataStruct
+ {
+ 	USHORT RVBHCMAX;
+@@ -1353,25 +886,6 @@ static const SiS310_LCDDataStruct  SiS31
+ 	{    1,   1,1344, 806,1344, 806}
+ };
+ 
+-#if 0   /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
+-static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] = 
+-{
+-	{   12,   5, 896, 512,1344, 806},
+-	{   12,   5, 896, 510,1344, 806},
+-	{   32,  15,1008, 505,1344, 806},
+-	{   32,  15,1008, 514,1344, 806},
+-	{   12,   5, 896, 500,1344, 806},
+-	{   42,  25,1024, 625,1344, 806},
+-	{    1,   1,1344, 806,1344, 806},
+-	{   12,   5, 896, 500,1344, 806},
+-	{   42,  25,1024, 625,1344, 806},
+-	{    1,   1,1344, 806,1344, 806},
+-	{   12,   5, 896, 500,1344, 806},
+-	{   42,  25,1024, 625,1344, 806},
+-	{    1,   1,1344, 806,1344, 806}
+-};
+-#endif
+-
+ static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
+ {
+ 	{   42,  25,1536, 419,1344, 806},
+@@ -1413,7 +927,7 @@ static const SiS310_LCDDataStruct  SiS31
+ 	{    1,   1,1688,1066,1688,1066}
+ };
+ 
+-static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] = 
++static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
+ {
+ 	{  211,  60,1024, 501,1688,1066},
+ 	{  211,  60,1024, 508,1688,1066},
+@@ -1450,7 +964,7 @@ static const SiS310_LCDDataStruct  SiS31
+ 	{    1,   1,1344, 806,1344, 806}
+ };
+ 
+-static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =  
++static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =
+ {
+         {    1,   1,1688,1066,1688,1066},
+ 	{    1,   1,1688,1066,1688,1066},
+@@ -1463,272 +977,15 @@ static const SiS310_LCDDataStruct  SiS31
+ 	{    1,   1,1688,1066,1688,1066}
+ };
+ 
+-static const SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
+-{
+-	{    9,   2, 800, 500,1800,1000},
+-	{    9,   2, 800, 500,1800,1000},
+-	{    4,   1, 900, 500,1800,1000},
+-	{    4,   1, 900, 500,1800,1000},
+-	{    9,   2, 800, 500,1800,1000},
+-	{   30,  11,1056, 625,1800,1000},
+-	{    5,   3,1350, 800,1800,1000},
+-	{    1,   1,1576,1050,1576,1050},
+-	{    1,   1,1800,1000,1800,1000}
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_StLCD1400x1050Data[] = 
+-{  /* TW: New from 1.11.6s */
+-	{ 211,  100, 2100,  408, 1688, 1066 },
+-	{ 211,   64, 1536,  358, 1688, 1066 },
+-	{ 211,  100, 2100,  408, 1688, 1066 },
+-	{ 211,   64, 1536,  358, 1688, 1066 },
+-	{ 211,   48,  840,  488, 1688, 1066 },
+-	{ 211,   72, 1008,  609, 1688, 1066 },
+-	{ 211,  128, 1400,  776, 1688, 1066 },
+-	{ 211,  205, 1680, 1041, 1688, 1066 },
+-	{   1,    1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_ExtLCD1400x1050Data[] = 
+-{  /* TW: New from 1.11.6s */
+-	{ 211,  100, 2100,  408, 1688, 1066 },
+-	{ 211,   64, 1536,  358, 1688, 1066 },
+-	{ 211,  100, 2100,  408, 1688, 1066 },
+-	{ 211,   64, 1536,  358, 1688, 1066 },
+-	{ 211,   48,  840,  488, 1688, 1066 },
+-	{ 211,   72, 1008,  609, 1688, 1066 },
+-	{ 211,  128, 1400,  776, 1688, 1066 },
+-	{ 211,  205, 1680, 1041, 1688, 1066 },
+-	{   1,    1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_NoScaleData1400x1050[] = 
+-{  /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 },
+-	{ 1, 1, 1688, 1066, 1688, 1066 }
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_StLCD1600x1200Data[] = 
+-{  /* TODO */
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_ExtLCD1600x1200Data[] = 
+-{  /* TODO */
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-static const SiS310_LCDDataStruct  SiS310_NoScaleData1600x1200[] = 
+-{  /* TODO */
+-	{    0,   0,   0,   0,   0,   0}
+-};
+-
+-typedef struct _SiS310_TVDataStruct
+-{
+-	USHORT RVBHCMAX;
+-	USHORT RVBHCFACT;
+-	USHORT VGAHT;
+-	USHORT VGAVT;
+-	USHORT TVHDE;
+-	USHORT TVVDE;
+-	USHORT RVBHRS;
+-	UCHAR FlickerMode;
+-	USHORT HALFRVBHRS;
+-	UCHAR RY1COE;
+-	UCHAR RY2COE;
+-	UCHAR RY3COE;
+-	UCHAR RY4COE;
+-} SiS310_TVDataStruct;
+-
+-static const SiS310_TVDataStruct  SiS310_StPALData[]=
+-{
+- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+-};
+-
+-static const SiS310_TVDataStruct  SiS310_ExtPALData[] =   
+-{
+- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480 */
+- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600 */
+- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x480/576 */
+- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
+-};
+-
+-static const SiS310_TVDataStruct  SiS310_StNTSCData[]=
+-{
+- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+-};
+-
+-static const SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
+-{
+- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},  /* 640x480 */
+- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},  /* 800x600  */
+- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},  /* 720x480/576 */
+- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08}   /* 1024x768 */
+-};
+-
+-#if 0
+-static const SiS310_TVDataStruct  SiS310_St1HiTVData[]=
+-{
+-  
+-};
+-#endif
+-
+-static const SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+-{
+- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+-{
+- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
+- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
+-};
+-
+-static const UCHAR SiS310_NTSCTiming[] = { 
+-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+-};
+-
+-static const UCHAR SiS310_PALTiming[] = {  
+-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+-	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVExtTiming[] = {  
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVSt1Timing[] = {  
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVSt2Timing[] = {  
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVTextTiming[] = {  
+-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Data[] = {  
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Simu[] = {  
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+-
+-static const UCHAR SiS310_HiTVGroup3Text[] = {  
+-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+-};
+ 
+ typedef struct _SiS310_PanelDelayTblStruct
+ {
+  	UCHAR timer[2];
+ } SiS310_PanelDelayTblStruct;
+ 
+-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  
++static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+ {
+-        {{0x10,0x40}},		/* TW: from 650/301LVx 1.10.6s BIOS */
++        {{0x10,0x40}},
+ 	{{0x10,0x40}},
+ 	{{0x10,0x40}},
+ 	{{0x10,0x40}},
+@@ -1744,24 +1001,6 @@ static const SiS310_PanelDelayTblStruct 
+ 	{{0x10,0x40}},
+ 	{{0x10,0x40}},
+ 	{{0x10,0x40}}
+-#if 0
+-	{{0x28,0xc8}},		/* TW: from 650/301LV BIOS */
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}},
+-	{{0x28,0xc8}}
+-#endif
+ };
+ 
+ static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+@@ -1792,363 +1031,7 @@ typedef struct _SiS310_LVDSDataStruct
+ 	USHORT LCDVT;
+ } SiS310_LVDSDataStruct;
+ 
+-static const SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
+-{
+-	{ 848, 433, 400, 525},
+-	{ 848, 389, 400, 525},
+-	{ 848, 433, 400, 525},
+-	{ 848, 389, 400, 525},
+-	{ 848, 518, 400, 525},
+-	{1056, 628, 400, 525},
+-	{ 400, 525, 400, 525},
+-	{ 800, 449,1000, 644},
+-	{ 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]= 
+-{
+-	{ 848, 433,1060, 629},
+-	{ 848, 389,1060, 629},
+-	{ 848, 433,1060, 629},
+-	{ 848, 389,1060, 629},
+-	{ 848, 518,1060, 629},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{ 800, 449,1000, 644},
+-	{ 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=  
+-{
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{ 800, 449,1000, 644},
+-	{ 800, 525,1000, 635}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=  
+-{
+-	{ 840, 438,1344, 806},
+-	{ 840, 409,1344, 806},
+-	{ 840, 438,1344, 806},
+-	{ 840, 409,1344, 806},
+-	{ 840, 518,1344, 806},   /* 640x480 */
+-	{1050, 638,1344, 806},   /* 800x600 */
+-	{1344, 806,1344, 806},   /* 1024x768 */
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]= 
+-{
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=  
+-{	
+-	{1048, 442,1688,1066},
+-	{1048, 392,1688,1066},
+-	{1048, 442,1688,1066},
+-	{1048, 392,1688,1066},
+-	{1048, 522,1688,1066},
+-	{1208, 642,1688,1066},
+-	{1432, 810,1688,1066},
+-	{1688,1066,1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=  
+-{	
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066},
+-	{1688,1066,1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=  
+-{
+-        { 928, 416, 1688,1066},
+-	{ 928, 366, 1688,1066},
+-	{ 928, 416, 1688,1066},
+-	{ 928, 366, 1688,1066},
+-	{ 928, 496, 1688,1066},
+-	{1088, 616, 1688,1066},
+-	{1312, 784, 1688,1066},
+-	{1568,1040, 1688,1066},
+-	{1688,1066, 1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]= 
+-{
+-        {1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-	{1688,1066, 1688,1066},
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_1[]=  
+-{
+-        {1088, 450, 2048,1250},
+-	{1088, 400, 2048,1250},
+-	{1088, 450, 2048,1250},
+-	{1088, 400, 2048,1250},
+-	{1088, 530, 2048,1250},
+-	{1248, 650, 2048,1250},
+-	{1472, 818, 2048,1250},
+-	{1728,1066, 2048,1250},
+-	{1848,1066, 2048,1250},
+-	{2048,1250, 2048,1250}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_2[]= 
+-{
+-        {2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250},
+-	{2048,1250, 2048,1250}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_1[]= 
+-{	
+-	{ 768, 438, 1408, 806},
+-	{ 768, 388, 1408, 806},
+-	{ 768, 438, 1408, 806},
+-	{ 768, 388, 1408, 806},
+-	{ 768, 518, 1408, 806},
+-	{ 928, 638, 1408, 806},
+-	{1152, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_2[]=  
+-{	
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806},
+-	{1408, 806, 1408, 806}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
+-{
+-	{ 840, 604, 1344, 800},
+-	{ 840, 560, 1344, 800},
+-	{ 840, 604, 1344, 800},
+-	{ 840, 560, 1344, 800},
+-	{ 840, 689, 1344, 800},
+-	{1050, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{ 800, 449, 1280, 801},
+-	{ 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
+-{
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{1344, 800, 1344, 800},
+-	{ 800, 449, 1280, 801},
+-	{ 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
+-{
+-	{ 840, 438, 1344, 806},
+-	{ 840, 409, 1344, 806},
+-	{ 840, 438, 1344, 806},
+-	{ 840, 409, 1344, 806},
+-	{ 840, 518, 1344, 806},
+-	{1050, 638, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{ 800, 449, 1280, 801},
+-	{ 800, 525, 1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
+-{
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{1344, 806, 1344, 806},
+-	{ 800, 449, 1280, 801},
+-	{ 800, 525, 1280, 813}
+-};
+-
+-/* TW: Pass 1:1 data */
+-static const SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=  
+-{
+-        { 800, 449,  800, 449},
+-	{ 800, 449,  800, 449},
+-	{ 900, 449,  900, 449},
+-	{ 900, 449,  900, 449},
+-	{ 800, 525,  800, 525},  /*  640x480   */
+-	{1056, 628, 1056, 628},  /*  800x600   */
+-	{1344, 806, 1344, 806},  /* 1024x768   */
+-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
+-	/* No other panels ! */
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=  
+-{
+-	{ 800, 449, 800, 449},
+-	{ 800, 449, 800, 449},
+-	{ 800, 449, 800, 449},
+-	{ 800, 449, 800, 449},
+-	{ 800, 525, 800, 525},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628},
+-	{1056, 628,1056, 628}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   
+-{
+-	{ 840, 438,1344, 806},
+-	{ 840, 409,1344, 806},
+-	{ 840, 438,1344, 806},
+-	{ 840, 409,1344, 806},
+-	{ 840, 518,1344, 806},
+-	{1050, 638,1344, 806},
+-	{1344, 806,1344, 806},
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=  
+-{
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-/* LCDA */
+-
+-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_1[]=   
+-{	/* TW: Might be temporary (invalid) data */
+-        { 928, 416, 1688,1066},
+-	{ 928, 366, 1688,1066},
+-	{1008, 416, 1688,1066},
+-	{1008, 366, 1688,1066},
+-	{1200, 530, 1688,1066},
+-	{1088, 616, 1688,1066},
+-	{1312, 784, 1688,1066},
+-	{1568,1040, 1688,1066},
+-	{1688,1066, 1688,1066}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_2[]=   
+-{	/* TW: Temporary data. Not valid */
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_1[]=  
+-{	/* TW: Temporary data. Not valid */
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{1344, 806,1344, 806},
+-	{ 800, 449,1280, 801},
+-	{ 800, 525,1280, 813}
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_2[]=  
+-{	/* TW: Temporary data. Not valid */
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0},
+-	{0, 0, 0, 0}
+-};
+-
+-/* Chrontel TV */
+-
+-static const SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   
+-{
+-	{ 840, 600, 840, 600},
+-	{ 840, 600, 840, 600},
+-	{ 840, 600, 840, 600},
+-	{ 840, 600, 840, 600},
+-	{ 784, 600, 784, 600},
+-	{1064, 750,1064, 750},
+-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   
+-{
+-	{ 840, 525, 840, 525},
+-	{ 840, 525, 840, 525},
+-	{ 840, 525, 840, 525},
+-	{ 840, 525, 840, 525},
+-	{ 784, 525, 784, 525},
+-	{1040, 700,1040, 700},
+-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
+-};
+-
+-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   
++static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
+ {
+ 	{1008, 625,1008, 625},
+ 	{1008, 625,1008, 625},
+@@ -2156,7 +1039,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{ 840, 625, 840, 625},
+ 	{ 960, 750, 960, 750},
+-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
++	{1400,1000,1400,1000}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
+@@ -2167,7 +1050,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{ 840, 625, 840, 625},
+ 	{ 944, 625, 944, 625},
+-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
++        {1400, 875,1400, 875}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
+@@ -2178,7 +1061,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{ 840, 600, 840, 600},
+ 	{ 784, 600, 784, 600},
+ 	{1064, 750,1064, 750},
+-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
++        {1160, 945,1160, 945}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
+@@ -2189,7 +1072,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{ 840, 525, 840, 525},
+ 	{ 784, 525, 784, 525},
+ 	{1040, 700,1040, 700},
+-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
++        {1160, 840,1160, 840}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
+@@ -2200,7 +1083,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{ 840, 625, 840, 625},
+ 	{ 960, 750, 960, 750},
+-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
++	{1400,1000,1400,1000}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
+@@ -2211,7 +1094,7 @@ static const SiS310_LVDSDataStruct  SiS3
+ 	{1008, 625,1008, 625},
+ 	{ 840, 625, 840, 625},
+ 	{ 944, 625, 944, 625},
+-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
++        {1400, 875,1400, 875}
+ };
+ 
+ static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
+@@ -2231,7 +1114,7 @@ typedef struct _SiS310_LVDSDesStruct
+ 	USHORT LCDVDES;
+ } SiS310_LVDSDesStruct;
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  
++static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
+ {
+ 	{ 0, 0},
+ 	{ 0, 0},
+@@ -2244,7 +1127,7 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{ 0, 0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   
++static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
+ {
+ 	{ 0, 0},
+ 	{ 0, 0},
+@@ -2257,7 +1140,7 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{ 0, 0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  
++static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
+ {
+ 	{ 0, 0},
+ 	{ 0, 0},
+@@ -2382,33 +1265,31 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{ 0, 0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]= 
+-{
+-	{1343, 798},
+-	{1343, 794},
+-	{1343, 798},
+-	{1343, 794},
+-	{1343,   0},
+-	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  
++static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
+ {
+-	{1343, 798},
+-	{1343, 794},
+-	{1343, 798},
+-	{1343, 794},
+-	{1343,   0},
+-	{1343,   0},
+-	{ 0, 805},
+-	{ 0, 794},
+-	{ 0,   0}
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 8, 524},
++	{ 0, 524}
++};
++
++static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
++{
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 0, 524},
++	{ 8, 524},
++	{ 0, 524}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]= 
++static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
+ {
+ 	{1343, 798},
+ 	{1343, 794},
+@@ -2604,7 +1485,7 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{   0,   0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  
++static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
+ {
+ 	{1152, 622},
+ 	{1152, 597},
+@@ -2617,7 +1498,7 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{ 0,   0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]= 
++static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
+ {
+ 	{1152, 622},
+ 	{1152, 597},
+@@ -2669,184 +1550,6 @@ static const SiS310_LVDSDesStruct  SiS31
+ 	{ 0,   0}
+ };
+ 
+-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_1[]= 
+-{
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 8,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0, 806},
+-	{ 0, 0 }
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_2[] = 
+-{
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=  
+-{  /* 1024x768 - Checked (1.10.6s) */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=  
+-{  /* 1024x768 - Checked (1.10.6s) */
+-	{ 1184, 622 },
+-	{ 1184, 597 },
+-	{ 1184, 622 },
+-	{ 1184, 597 },
+-	{ 1152, 622 },
+-	{ 1232, 722 },
+-	{    0, 0   },
+-	{    0, 794 },
+-	{    0, 0   }
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=  
+-{  /* 1280x1024 - Checked (1.10.6s) */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=  
+-{  /* 1280x1024 - Checked (1.10.6s) */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=  
+-{  /* 1400x1050 - Checked (1.10.6s) */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=  
+-{  /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
+-	{ 808 , 740},
+-	{ 0   , 715},
+-	{ 632 , 740},
+-	{ 632 , 715},
+-	{ 1307, 780},
+-	{ 1387,1157},
+-	{ 1499, 924},
+-	{ 1627,1052},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= 
+-{  /* 1600x1200 - Checked (1.10.6s) */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= 
+-{  /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0},
+-	{ 0 , 0}
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
+-{
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0}
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+-{
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0}
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+-{
+-	{256,   0},
+-	{256,   0},
+-	{256,   0},
+-	{256,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0}
+-};
+-
+-static const SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+-{
+-	{256,   0},
+-	{256,   0},
+-	{256,   0},
+-	{256,   0},
+-	{ 0,   0},
+-	{ 0,   0},
+-	{ 0,   0}
+-};
+-
+ typedef struct _SiS310_Part2PortTblStruct
+ {
+  	UCHAR CR[12];
+@@ -2866,16 +1569,15 @@ static const SiS310_Part2PortTblStruct S
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+-{	/* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{	/* TW: BIOS data invalid, last row taken from _3 */
++ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
++ {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
++ {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
++ {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
+@@ -2892,16 +1594,17 @@ static const SiS310_Part2PortTblStruct S
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+-{	/* TW: Temporary data, invalid */
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+@@ -2912,7 +1615,8 @@ static const SiS310_Part2PortTblStruct S
+  {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
+  {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
+  {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
+- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
++ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},  /* old  */
++/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24        new? */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+ };
+@@ -2944,21 +1648,23 @@ static const SiS310_Part2PortTblStruct S
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+-{	/* TW: Temporary data, invalid */
+- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+- {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+- {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+- {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
++{
++ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}},
++ {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}},
++ {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}},
++ {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}},
++ {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+ 
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+ {	/* TW: Data from 650/301LVx 1.10.6s */
++#if 0
+  {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+  {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+  {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+@@ -2968,56 +1674,56 @@ static const SiS310_Part2PortTblStruct S
+  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+  {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+-#if 0	/* TW: Data from 650/301LV */
+- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+-#endif
++#endif	/* Data from my 301LV */
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},   /* @@@@@ TEST */
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
++ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
+ };
+ 
+ /*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+-{	/* TW: Temporary data, invalid */
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++{
++ {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
+ {	
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
++ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+ };
+ 
+ static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
+-{	/* TW: Temporary data, invalid */
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
++{
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
++ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
+ };
+ 
+ typedef struct _SiS310_LCDACRT1DataStruct
+@@ -3054,7 +1760,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
+-{  /* TW: Checked (1.10.6s) */
++{
+  {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
+    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
+    0x00}},
+@@ -3079,7 +1785,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+-{  /* Checked (1.10.6s) */
++{
+  {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+    0x00}},
+@@ -3107,7 +1813,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
+-{    /* Checked (1.10.6s) */
++{
+  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+@@ -3200,7 +1906,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+-{  /* TW: Checked (1.10.6s) */
++{
+  {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+    0x00}},
+@@ -3225,7 +1931,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+-{   /* Checked (1.10.6s) */
++{
+  {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
+    0x00}},
+@@ -3250,7 +1956,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
+-{   /* Checked (1.10.6s) */
++{
+   {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+     0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+     0x00}},
+@@ -3343,7 +2049,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
+-{   /* Checked (1.10.6s) */
++{
+  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+    0x00}},
+@@ -3368,7 +2074,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+-{   /* Checked (1.10.6s) */
++{
+  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+    0x00}},
+@@ -3393,7 +2099,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
+-{    /* Checked (1.10.6s) */
++{
+  {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+    0x00}},
+@@ -3486,7 +2192,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
+-{   /* Checked (1.10.6s) */
++{
+  {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+    0x00 }},
+@@ -3511,7 +2217,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+-{   /* Checked (1.10.6s) */
++{
+  {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+    0x00 }},
+@@ -3536,7 +2242,7 @@ static const SiS310_LCDACRT1DataStruct  
+ };
+ 
+ static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
+-{  /* Checked (1.10.6s) */
++{
+  {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+    0x00}},
+@@ -3605,32 +2311,7 @@ typedef struct _SiS310_LVDSCRT1DataStruc
+  	UCHAR CR[15];
+ } SiS310_LVDSCRT1DataStruct;
+ 
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
+-{
+- {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+-   0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+-   0x00 }},
+- {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-   0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+-   0x00 }},
+- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+-   0x00 }},
+- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+-   0x01 }},
+- {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+-   0x00 }}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   
++static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
+ {
+  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
+    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+@@ -3924,63 +2605,7 @@ static const SiS310_LVDSCRT1DataStruct  
+    0x01}}
+ };
+ 
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =  
+-{
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+-   0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+-   0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+-   0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+-   0x00}},
+- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+-   0x00}},
+- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+-   0x01}},
+- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-   0x01}},
+- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+-   0x01}},
+- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] = 
+-{
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+-   0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+-   0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+-   0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+-   0x00}},
+- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+-   0x00}},
+- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+-   0x01}},
+- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =  
++static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
+ {
+   {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+     0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
+@@ -4220,332 +2845,8 @@ static const SiS310_LVDSCRT1DataStruct  
+ #endif   
+ };
+ 
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1[] =  
+-{	
+- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+-   0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+-   0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+-   0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+-   0x00}},
+- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
+-   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
+-   0x00}},
+- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
+-   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
+-   0x01}},
+- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
+-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1_H[] = 
+-{
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+-   0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+-   0x00}},
+- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+-   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
+-   0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+-   0x00}},
+- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+-   0x00}},
+- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
+-   0x01}},
+- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+-   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
+-   0x01}},
+- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+-   0x01}},
+- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2[] = 
++static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
+ {
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+-   0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+-   0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+-   0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+-   0x00}},
+- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
+-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
+-   0x01}},
+- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
+-   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
+-   0x01}},
+- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2_H[] =
+-{
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+-   0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+-   0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+-   0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+-   0x00}},
+- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
+-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
+-   0x01}},
+- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
+-   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
+-   0x01}},
+- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+-   0x01}},
+- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+-   0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
+-{
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
+-{
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-          0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+-	  0x00}},
+-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
+-{
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
+-{
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
+-{
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+-	  0x00}},
+-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+-	  0x00}},
+-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
+-{
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+-	  0x00}},
+-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+-	  0x00}},
+-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
+-{
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+-	  0x00}},
+-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+-	  0x01}},
+-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
+-{
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+-	  0x00}},
+-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+-	  0x01}},
+-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+-	  0x01}}
+-};
+-
+-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =  
+-{    
+  {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
+    0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
+    0x00}},
+@@ -4701,7 +3002,7 @@ static const SiS310_LVDSCRT1DataStruct  
+ 	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+ 	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+ 	  0x01 }},
+-	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
++	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
+ 	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+ 	  0x01}}
+ };
+@@ -4726,7 +3027,7 @@ static const SiS310_LVDSCRT1DataStruct  
+ 	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+ 	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+ 	  0x01 }},
+-	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
++	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
+ 	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+ 	  0x01 }}
+ };
+@@ -4751,7 +3052,7 @@ static const SiS310_LVDSCRT1DataStruct  
+ 	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+ 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+ 	  0x01 }},
+-	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
++	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
+ 	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+ 	  0x01}}
+ };
+@@ -4776,7 +3077,7 @@ static const SiS310_LVDSCRT1DataStruct  
+ 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 	  0x01 }},
+-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
++	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
+ 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 	  0x01 }}
+ };
+@@ -4801,12 +3102,11 @@ static const SiS310_LVDSCRT1DataStruct  
+ 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+ 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+ 	  0x01 }},
+-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
++	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
+ 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+ 	  0x01 }}
+ };
+ 
+-/* TW: Data for Chrontel 7019  */
+ typedef struct _SiS310_CHTVRegDataStruct
+ {
+  	UCHAR Reg[16];
+--- linux-2.6.0-test6/drivers/video/sis/init301.c	2003-07-13 21:44:34.000000000 -0700
++++ 25/drivers/video/sis/init301.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,27 +1,16 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
+ /*
+- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
+- * (Universal module for Linux kernel framebuffer, XFree86 4.x)
++ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330/660
++ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+  *
+  * Assembler-To-C translation
+  * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+- * Minor parts Copyright SiS, Inc.
++ * Formerly based on non-functional code-fragements by SiS, Inc.
+  *
+- * Based on BIOS
+- *     1.10.07, 1.10a for 650/CH7019
+- *     1.11.21a for 740/CH7019
+- *     1.11.05 for 650/LVDS (w/o Chrontel)
+- *     1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
+- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+- *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
+- *     1.09b for 315/301(B)
+- *     1.16.51 for 300+301LV (ECS A907)
+- *     1.01.03 for 330 (Xabre 400)
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
+  *
+- * Known bugs:
+- *   1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
+- *       therefore, we always do the scaling ourselves for now.
++ * Otherwise, the following terms apply:
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+@@ -73,8 +62,8 @@
+ #define SiS_I2CDELAYSHORT  150
+ 
+ BOOLEAN
+-SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
++SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+    USHORT ModeIdIndex;
+    USHORT RefreshRateTableIndex;
+@@ -85,9 +74,9 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
+       SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+    } else {
+       ModeIdIndex = 0;
+-   }      
++   }
+ 
+-   /* TW: Used for shifting CR33 */
++   /* Used for shifting CR33 */
+    SiS_Pr->SiS_SelectCRT2Rate = 4;
+ 
+    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+@@ -110,8 +99,6 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
+       return(TRUE);
+    }
+ 
+-   if(SiS_Pr->UseCustomMode) return(FALSE);
+-   
+    SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                    HwDeviceExtension);
+ 
+@@ -153,9 +140,9 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
+       	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
+ 	                 ModeNo,ModeIdIndex);
+ 
+-	   /* TW: For 301BDH (Panel link initialization): */
++	   /* For 301BDH (Panel link initialization): */
+ 	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+-	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {	 
++	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ 		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
+ 		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ 		       SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+@@ -176,10 +163,10 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
+ 	                      RefreshRateTableIndex,HwDeviceExtension);
+ 	   }
+ 	}
+-        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
+-     	   SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-	 	           RefreshRateTableIndex,HwDeviceExtension);
+-	}
++
++        SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
++	                RefreshRateTableIndex,HwDeviceExtension);
++
+ 	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ 	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+@@ -199,74 +186,64 @@ SiS_SetCRT2Group301(SiS_Private *SiS_Pr,
+    }
+ 
+ #ifdef SIS300
+-   if ( (HwDeviceExtension->jChipType == SIS_540) ||
+-        (HwDeviceExtension->jChipType == SIS_630) ||
+-        (HwDeviceExtension->jChipType == SIS_730) ||
+-        (HwDeviceExtension->jChipType == SIS_300) )
+-    {
+-	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+-	   if(SiS_Pr->SiS_UseOEM) {
+-	      if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+-	         if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+-	            SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+-	         }
+-	      } else {
+-       	         SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+-	      }
+-	   }
+-	}
+-    }
+-#endif
+-
+-#ifdef SIS315H
+-   if ( (HwDeviceExtension->jChipType == SIS_315H)  ||
+-        (HwDeviceExtension->jChipType == SIS_315)   ||
+-	(HwDeviceExtension->jChipType == SIS_315PRO)||
+-        (HwDeviceExtension->jChipType == SIS_550)   ||
+-        (HwDeviceExtension->jChipType == SIS_740)   ||
+-        (HwDeviceExtension->jChipType == SIS_650)   ||
+-	(HwDeviceExtension->jChipType == SIS_330) )
+-   {
+-        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+-	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
+-#if 0      /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
+-	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+-#endif
+-           if(SiS_Pr->SiS_UseOEM) {
+-              SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+-           }
+-           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
+-        }
+-   }
+-#endif
+-
+    if(HwDeviceExtension->jChipType < SIS_315H) {
++      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++	 if(SiS_Pr->SiS_UseOEM) {
++	    if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
++	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++	          SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++	       			    RefreshRateTableIndex);
++	       }
++	    } else {
++       	       SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++	       			 RefreshRateTableIndex);
++	    }
++	 }
++	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++            if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++	       SetOEMLCDData2(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,
++	                      ModeIdIndex,RefreshRateTableIndex);
++	    }
++            if(HwDeviceExtension->jChipType == SIS_730) {
++               SiS_DisplayOn(SiS_Pr);
++	    }
++         }
++      }
+       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+           if(HwDeviceExtension->jChipType != SIS_730) {
+              SiS_DisplayOn(SiS_Pr);
+ 	  }
+       }
+    }
++#endif
+ 
+-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-         if(HwDeviceExtension->jChipType == SIS_730) {
+-            SiS_DisplayOn(SiS_Pr);
+-	 }
++#ifdef SIS315H
++   if(HwDeviceExtension->jChipType >= SIS_315H) {
++      if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++	 SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
++         if(SiS_Pr->SiS_UseOEM) {
++            SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++         }
++         SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
+       }
++   }
++#endif
++
++   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+       SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+    }
+ 
+    SiS_DisplayOn(SiS_Pr);
+ 
+    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+-	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-	     /* TW: Disable LCD panel when using TV */
+-	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
+-	} else {
+-	     /* TW: Disable TV when using LCD */
+-	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+-	}
++      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++	 /* Disable LCD panel when using TV */
++	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
++      } else {
++	 /* Disable TV when using LCD */
++	 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
++      }
+    }
+ 
+    if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+@@ -283,7 +260,7 @@ SiS_LowModeStuff(SiS_Private *SiS_Pr, US
+     USHORT temp,temp1,temp2;
+ 
+     if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+-         return(1);
++       return(1);
+     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
+     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+     temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+@@ -304,7 +281,7 @@ SiS_LowModeStuff(SiS_Private *SiS_Pr, US
+     }
+ }
+ 
+-/* TW: Set Part1 registers */
++/* Set Part1 registers */
+ void
+ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+@@ -313,31 +290,35 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+   USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
+   USHORT  pushbx=0, CRT1Index=0;
+ #ifdef SIS315H
+-  USHORT  pushcx=0, tempbl=0;
++  USHORT  tempbl=0;
+ #endif
+   USHORT  modeflag, resinfo=0;
+ 
+-  if(ModeNo<=0x13) {
+-	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++  if(ModeNo <= 0x13) {
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
++     if(SiS_Pr->UseCustomMode) {
++	modeflag = SiS_Pr->CModeFlag;
++     } else {
+     	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ 	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++     }
+   }
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+-
+-	   SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+-                           RefreshRateTableIndex,HwDeviceExtension);
+ #ifdef SIS315H
+-	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+-     	                      HwDeviceExtension,RefreshRateTableIndex);
++     SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
++                     RefreshRateTableIndex,HwDeviceExtension);
++
++     SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
++                        HwDeviceExtension,RefreshRateTableIndex);
+ #endif
+   } else {
+ 
+      if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+          (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+-	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
+ 
+         SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+                         RefreshRateTableIndex,HwDeviceExtension);
+@@ -367,13 +348,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ #ifdef SIS300   /* ------------- 300 series --------------*/
+ 
+     		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
+-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
++    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
+ 
+     		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+-    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
++    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
+ 
+     		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
+-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
++    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
+ 
+     		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
+     		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+@@ -382,108 +363,129 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+     		tempcx += tempbx;
+ 
+     		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+-			        /* CRT1Index &= 0x3F; - Not any longer */
+-        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+-        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+-        			tempbx = (tempbx - 1) << 3;
+-        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+-        			tempcx &= 0x1F;
+-        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+-        			temp = (temp & 0x04) << (6-2);
+-        			tempcx = (tempcx | temp);
+-				tempcx--;
+-				tempcx <<= 3;
+-      			}
+-
+-    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+-        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+-      					tempbx = 1040;
+-      					tempcx = 1042;
+-      				}
+-    			}
++
++		   if(SiS_Pr->UseCustomMode) {
++		      tempbx = SiS_Pr->CHSyncStart + 12;
++		      tempcx = SiS_Pr->CHSyncEnd + 12;
++		   }
++
++      		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
++		      unsigned char cr4, cr14, cr5, cr15;
++		      if(SiS_Pr->UseCustomMode) {
++		         cr4  = SiS_Pr->CCRT1CRTC[4];
++			 cr14 = SiS_Pr->CCRT1CRTC[14];
++			 cr5  = SiS_Pr->CCRT1CRTC[5];
++			 cr15 = SiS_Pr->CCRT1CRTC[15];
++		      } else {
++		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
++			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
++			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
++		      }
++        	      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
++        	      tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
++      		   }
++
++    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
++        	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
++      			 tempbx = 1040;
++      			 tempcx = 1042;
++      		      }
++    		   }
+ 	        }
+ 
+     		temp = tempbx & 0x00FF;
+-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
++    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
+ #endif /* SIS300 */
+ 
+  	} else {
+ 
+-#ifdef SIS315H  /* ----------------- 310/325/330 series ------------- */
++#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
+ 
+ 	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
+-		pushcx = tempcx;
+ 		if(modeflag & HalfDCLK) {
+-#ifndef NEWCH701x		
+-		    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
+-#endif		    
++		    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ 		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
+ 			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+ 			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ 			      tempcx = SiS_Pr->SiS_HT - tempax;
+ 			  }
+-#ifndef NEWCH701x					  
+ 		    } else {
+ 			  tempcx >>= 1;
+ 		    }
+-#endif		    
+ 		}
+ 		tempcx--;
+ 
+ 		temp = tempcx & 0xff;
+-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
++		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
+ 
+ 		temp = ((tempcx & 0xff00) >> 8) << 4;
+-		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
++		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
+ 
+-		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
++		tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HDEE 0x0A,0x0C */
+ 		tempbx = SiS_Pr->SiS_VGAHDE;
+ 		tempcx -= tempbx;
+ 		tempcx >>= 2;
+ 		if(modeflag & HalfDCLK) {
+-		    tempbx >>= 1;
+-		    tempcx >>= 1;
++		   tempbx >>= 1;
++		   tempcx >>= 1;
+ 		}
+ 		tempbx += 16;
+ 
+ 		temp = tempbx & 0xff;
+-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
++		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
+ 
+ 		pushbx = tempbx;
+ 		tempcx >>= 1;
+ 		tempbx += tempcx;
+ 		tempcx += tempbx;
+ 
+-		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
++		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++
++		   if(SiS_Pr->UseCustomMode) {
++		      tempbx = SiS_Pr->CHSyncStart + 16;
++		      tempcx = SiS_Pr->CHSyncEnd + 16;
++		      tempax = SiS_Pr->SiS_VGAHT;
++		      if(modeflag & HalfDCLK) tempax >>= 1;
++		      tempax--;
++		      if(tempcx > tempax)  tempcx = tempax;
++		   }
++
+              	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+-                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+-                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+-                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
+-                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+-               		tempcx &= 0x1F;
+-                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+-                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
+-                	tempcx = (tempcx | temp);	  	  	/* (VGAHRE-3)*8 */
+-			tempcx -= 3;
+-			tempcx <<= 3;
+-			tempcx &= 0x00FF;
+-			tempcx |= (tempbx & 0xFF00);
+-                	tempbx += 16;
+-                	tempcx += 16;
+-			tempax = SiS_Pr->SiS_VGAHT;
+-			if(modeflag & HalfDCLK)  tempax >>= 1;
+-			tempax--;
+-			if(tempcx > tempax)  tempcx = tempax;
++		      unsigned char cr4, cr14, cr5, cr15;
++		      if(SiS_Pr->UseCustomMode) {
++		         cr4  = SiS_Pr->CCRT1CRTC[4];
++			 cr14 = SiS_Pr->CCRT1CRTC[14];
++			 cr5  = SiS_Pr->CCRT1CRTC[5];
++			 cr15 = SiS_Pr->CCRT1CRTC[15];
++		      } else {
++		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
++			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
++			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
++		      }
++                      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		/* (VGAHRS-3)*8 */
++                      tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; 	/* (VGAHRE-3)*8 */
++		      tempcx &= 0x00FF;
++		      tempcx |= (tempbx & 0xFF00);
++                      tempbx += 16;
++                      tempcx += 16;
++		      tempax = SiS_Pr->SiS_VGAHT;
++		      if(modeflag & HalfDCLK) tempax >>= 1;
++		      tempax--;
++		      if(tempcx > tempax)  tempcx = tempax;
+              	   }
+-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+-             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+-      		 	 tempbx = 1040;
+-      		 	 tempcx = 1042;
+-      	     	      }
++         	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++		      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++		         if(resinfo == SIS_RI_1024x768) {
++      		 	    tempbx = 1040;
++      		 	    tempcx = 1042;
++      	     	         }
++		      }
+          	   }
+-		   /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
+-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
++#if 0
++		   /* Makes no sense, but is in 650/30xLV 1.10.6s */
++         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+ 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+              	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+       		 	    tempbx = 1040;
+@@ -491,25 +493,26 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+       	     	         }
+ 		      }
+          	   }
++#endif
+                 }
+ 
+ 		temp = tempbx & 0xff;
+-	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
++	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
+ #endif  /* SIS315H */
+ 
+-     	}  /* 310/325/330 series */
++     	}  /* 315/330 series */
+ 
+-  	/* TW: The following is done for all bridge/chip types/series */
++  	/* The following is done for all bridge/chip types/series */
+ 
+   	tempax = tempbx & 0xFF00;
+   	tempbx = pushbx;
+   	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+   	tempax |= (tempbx & 0xFF00);
+   	temp = (tempax & 0xFF00) >> 8;
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
+ 
+   	temp = tempcx & 0x00FF;
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
+ 
+   	/* 2. Vertical setup */
+ 
+@@ -517,30 +520,30 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+   	temp = tempcx & 0x00FF;
+ 
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-	     if(HwDeviceExtension->jChipType < SIS_315H) {
+-	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+-		           temp--;
+-		       }
+-                  }
+-	     } else {
+- 		      temp--;
+-             }
++	   if(HwDeviceExtension->jChipType < SIS_315H) {
++	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
++	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
++	            temp--;
++	         }
++              }
++	   } else {
++ 	      temp--;
++           }
+         } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	    /* TW: 650/30xLV 1.10.6s */
+-	    temp--;
++	   /* 650/30xLV 1.10.6s */
++	   temp--;
+ 	}
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
+ 
+   	tempbx = SiS_Pr->SiS_VGAVDE - 1;
+   	temp = tempbx & 0x00FF;
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
+ 
+   	temp = ((tempbx & 0xFF00) << 3) >> 8;
+   	temp |= ((tempcx & 0xFF00) >> 8);
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
+ 
+-	/* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
++	/* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
+ 	if(HwDeviceExtension->jChipType >= SIS_315H) {
+            tempbx++;
+    	   tempax = tempbx;
+@@ -553,29 +556,44 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 	   tempcx += tempbx;
+ 	   tempcx++;
+ 	} else {
+-	   /* TW: 300 series, LVDS/301B: */
++	   /* 300 series, LVDS/301B: */
+   	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
+   	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
+ 	}
+ 
+   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+-      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+-      		if(temp & 0x04) tempbx |= 0x0100;
+-      		if(temp & 0x80) tempbx |= 0x0200;
+-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+-      		if(temp & 0x08) tempbx |= 0x0400;
+-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
+-      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
++
++	   if(SiS_Pr->UseCustomMode) {
++	      tempbx = SiS_Pr->CVSyncStart;
++	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
++	   }
++
++    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
++	      unsigned char cr8, cr7, cr13, cr9;
++	      if(SiS_Pr->UseCustomMode) {
++	         cr8  = SiS_Pr->CCRT1CRTC[8];
++		 cr7  = SiS_Pr->CCRT1CRTC[7];
++		 cr13 = SiS_Pr->CCRT1CRTC[13];
++		 cr9  = SiS_Pr->CCRT1CRTC[9];
++	      } else {
++	         cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
++		 cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
++		 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
++		 cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
++	      }
++      	      tempbx = cr8;
++      	      if(cr7 & 0x04)  tempbx |= 0x0100;
++      	      if(cr7 & 0x80)  tempbx |= 0x0200;
++      	      if(cr13 & 0x08) tempbx |= 0x0400;
++      	      tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
+     	   }
+   	}
+   	temp = tempbx & 0x00FF;
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
+ 
+   	temp = ((tempbx & 0xFF00) >> 8) << 4;
+   	temp |= (tempcx & 0x000F);
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+ 
+   	/* 3. Panel compensation delay */
+ 
+@@ -590,18 +608,18 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 		   temp = 0x10;
+ 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+ 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
+ 		}
+ 		if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ 		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+ 		}
+ 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
++		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
+ 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
+ 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+       		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
+       		   else 					temp = 0x20;
+     	        }
+-		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
++		if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ 		    if(ROMAddr[0x220] & 0x80) {
+ 		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
+ 				temp = ROMAddr[0x221];
+@@ -636,19 +654,20 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 		}
+ 	   }
+ 
+-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
++    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+ 
+ #endif  /* SIS300 */
+ 
+   	} else {
+ 
+-#ifdef SIS315H   /* ----------- 310/325/330 series ---------------*/
++#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
+ 
+ 	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+                 temp = 0x10;
+                 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+     	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
++		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
+ 		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ 		   temp = 0x08;
+ 		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+@@ -664,7 +683,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 		      }
+     	           }
+ 		}
+-		if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ 		   tempbl = 0x00;
+ 		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ 		      if(HwDeviceExtension->jChipType < SIS_330) {
+@@ -689,8 +708,16 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+ 		   }
+ 		}
++
++		if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
++		   temp = 0x08;
++		   tempbl = 0;
++		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
++		      if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
++		   }
++		}
+ 	   }
+-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
++	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
+ 
+     	   tempax = 0;
+     	   if (modeflag & DoubleScanMode) tempax |= 0x80;
+@@ -705,14 +732,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT
+ 
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+-        /* TW: For 301BDH, we set up the Panel Link */
+-        if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
+-	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
++        /* For 301BDH with LCD, we set up the Panel Link */
++        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+ 
+ 	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ 	                       HwDeviceExtension,RefreshRateTableIndex);
+ 
+-        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {                             
++        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ 
+     	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+ 	                      HwDeviceExtension,RefreshRateTableIndex);
+@@ -749,23 +775,27 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+   USHORT  push1,push2;
+   USHORT  tempax,tempbx,tempcx,temp;
+   USHORT  resinfo,modeflag;
++  unsigned char p1_7, p1_8;
+ 
+   if(ModeNo <= 0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   } else {
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++	resinfo = 0;
++     } else {
+     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     }
+   }
+ 
+-  /* TW: The following is only done if bridge is in slave mode: */
++  /* The following is only done if bridge is in slave mode: */
+ 
+   tempax = 0xFFFF;
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
+ 
+-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-  	modeflag |= Charx8Dot;
+-  }
++  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
+ 
+   if(modeflag & Charx8Dot) tempcx = 0x08;
+   else                     tempcx = 0x09;
+@@ -777,8 +807,7 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+   tempax = (tempax / tempcx) - 5;
+   tempbx = tempax & 0x00FF;
+ 
+-  temp = 0xFF;                                                  /* set MAX HT */
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0xff);                 /* set MAX HT */
+ 
+   tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
+   if(modeflag & HalfDCLK) tempax >>= 1;
+@@ -789,13 +818,13 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+ 
+   temp = (tempbx & 0xFF00) >> 8;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {        
+-    	    temp += 2;
+-        }
+-  }	
++     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
++        temp += 2;
++     }
++  }
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      if(SiS_Pr->SiS_HiVision == 3) {
+-              if(resinfo == 7) temp -= 2;
++        if(resinfo == SIS_RI_800x600) temp -= 2;
+      }
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
+@@ -804,140 +833,133 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+ 
+   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (SiS_Pr->SiS_HiVision == 3)) {
+-    temp = (tempbx & 0x00FF) - 1;
+-    if(!(modeflag & HalfDCLK)) {
+-      temp -= 6;
+-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-        temp -= 2;
+-        if(ModeNo > 0x13) temp -= 10;
+-      }
+-    }
++     temp = (tempbx & 0x00FF) - 1;
++     if(!(modeflag & HalfDCLK)) {
++        temp -= 6;
++        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++           temp -= 2;
++           if(ModeNo > 0x13) temp -= 10;
++        }
++     }
+   } else {
+-    tempcx = tempbx & 0x00FF;
+-    tempbx = (tempbx & 0xFF00) >> 8;
+-    tempcx = (tempcx + tempbx) >> 1;
+-    temp = (tempcx & 0x00FF) + 2;
+-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
+-       temp--;
+-       if(!(modeflag & HalfDCLK)){
+-          if((modeflag & Charx8Dot)){
+-             temp += 4;
+-             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
+-             if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	        if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
+-             }
+-          }
+-       }
+-    } else {
+-       if(!(modeflag & HalfDCLK)) {
+-          temp -= 4;
+-          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+-             if(SiS_Pr->SiS_VGAHDE >= 800) {
+-                temp -= 7;
+-	        if(HwDeviceExtension->jChipType < SIS_315H) {
+-	           /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+-                   if(SiS_Pr->SiS_ModeType == ModeEGA) {
+-                      if(SiS_Pr->SiS_VGAVDE == 1024) {
+-                         temp += 15;
+-                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) 
+-			    temp += 7;
+-                      }
+-                   }
+-	        }
+-                if(SiS_Pr->SiS_VGAHDE >= 1280) {
+-                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+-                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+-                   }
+-                }
+-             }
+-          }
+-       }
+-    }
++     tempcx = tempbx & 0x00FF;
++     tempbx = (tempbx & 0xFF00) >> 8;
++     tempcx = (tempcx + tempbx) >> 1;
++     temp = (tempcx & 0x00FF) + 2;
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        temp--;
++        if(!(modeflag & HalfDCLK)) {
++           if((modeflag & Charx8Dot)) {
++              temp += 4;
++              if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
++              if(HwDeviceExtension->jChipType >= SIS_315H) {
++	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
++              }
++           }
++        }
++     } else {
++        if(!(modeflag & HalfDCLK)) {
++           temp -= 4;
++           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
++              if(SiS_Pr->SiS_VGAHDE >= 800) {
++                 temp -= 7;
++	         if(HwDeviceExtension->jChipType < SIS_315H) {
++	            /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
++                    if(SiS_Pr->SiS_ModeType == ModeEGA) {
++                       if(SiS_Pr->SiS_VGAVDE == 1024) {
++                          temp += 15;
++                          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
++		  	     temp += 7;
++                       }
++                    }
++	         }
++                 if(SiS_Pr->SiS_VGAHDE >= 1280) {
++                    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
++                 }
++              }
++           }
++        }
++     }
+   }
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
+ 
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
++  p1_7 = temp;
++  p1_8 = 0x00;
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-            if(ModeNo <= 0x01) {
+-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
+-		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
+-		} else {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
+-		}
+-	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
+-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
+-		} else {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
+-		}
+-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
+-	    } else if(ModeNo <= 0x13) {
+-	        if(modeflag & HalfDCLK) {
+-		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+-		    } else {
+-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
+-		    }
+-		} else {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+-		}
+-	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
+-	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
+-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+-		} else {
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+-		}
+-	    }
+-
++        if(ModeNo <= 0x01) {
++	   p1_7 = 0x2a;
++	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61;
++	   else 	      			p1_8 = 0x41;
++	} else if(SiS_Pr->SiS_ModeType == ModeText) {
++	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54;
++	   else 	    			p1_7 = 0x55;
++	   p1_8 = 0x00;
++	} else if(ModeNo <= 0x13) {
++	   if(modeflag & HalfDCLK) {
++	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++		 p1_7 = 0x30;
++		 p1_8 = 0x03;
++	      } else {
++	 	 p1_7 = 0x2f;
++		 p1_8 = 0x02;
++	      }
++	   } else {
++	      p1_7 = 0x5b;
++	      p1_8 = 0x03;
++	   }
++	} else if( ((HwDeviceExtension->jChipType >= SIS_315H) &&
++	            ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
++	           ((HwDeviceExtension->jChipType < SIS_315H) &&
++		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
++	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++	      p1_7 = 0x30,
++	      p1_8 = 0x03;
++	   } else {
++	      p1_7 = 0x2f;
++	      p1_8 = 0x03;
++	   }
++        }
+      }
+   }
++
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      if(SiS_Pr->SiS_HiVision & 0x03) {
+-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
++	p1_7 = 0xb2;
+ 	if(SiS_Pr->SiS_HiVision & 0x02) {
+-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
++	   p1_7 = 0xab;
+ 	}
+      }
+   }
+ 
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
++
++
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
+ 
+   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+ 
+-  tempbx = SiS_Pr->SiS_VGAVT;
+-  push1 = tempbx;
+-
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+ 
+   tempcx = 0x121;
+   tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
+-  if(tempbx == 357) tempbx = 350;
+-  if(tempbx == 360) tempbx = 350;
+-  if(tempbx == 375) tempbx = 350;
+-  if(tempbx == 405) tempbx = 400;
+-  if(tempbx == 420) tempbx = 400;
+-  if(tempbx == 525) tempbx = 480;
++  if     (tempbx == 357) tempbx = 350;
++  else if(tempbx == 360) tempbx = 350;
++  else if(tempbx == 375) tempbx = 350;
++  else if(tempbx == 405) tempbx = 400;
++  else if(tempbx == 420) tempbx = 400;
++  else if(tempbx == 525) tempbx = 480;
+   push2 = tempbx;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+-        		if(tempbx == 350) tempbx += 5;
+-        		if(tempbx == 480) tempbx += 5;
+-      		}
+-    	}
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++      	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
++           if     (tempbx == 350) tempbx += 5;
++           else if(tempbx == 480) tempbx += 5;
++      	}
++     }
+   }
+-  tempbx--;
+-  temp = tempbx & 0x00FF;
+-  tempbx--;
++  tempbx -= 2;
+   temp = tempbx & 0x00FF;
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
+ 
+@@ -945,126 +967,91 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+   tempbx--;
+   temp = tempbx & 0x00FF;
+ #if 0
+-  /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
++  /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
+   if(xxx()) {
+       if(temp == 0xdf) temp = 0xda;
+   }
+ #endif
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
+ 
+-  if(tempbx & 0x0100) {
+-  	tempcx |= 0x0002;
+-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
+-  }
++  if(tempbx & 0x0100)  tempcx |= 0x0002;
+ 
+   tempax = 0x000B;
+   if(modeflag & DoubleScanMode) tempax |= 0x8000;
+ 
+-  if(tempbx & 0x0200) {
+-  	tempcx |= 0x0040;
+-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
+-  }
+-
+-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+-        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-	      if(SiS_Pr->SiS_VGAVDE == 480) {
+-	             tempax = (tempax & 0x00ff) | 0x2000;
+-		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
+-	      }
+-	}
+-  }
++  if(tempbx & 0x0200)  tempcx |= 0x0040;
+ 
+   temp = (tempax & 0xFF00) >> 8;
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
+ 
+-  if(tempbx & 0x0400) tempcx |= 0x0600;
++  if(tempbx & 0x0400)  tempcx |= 0x0600;
+ 
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+ 
+-  tempax = push1;
+-  tempax -= tempbx;
+-  tempax >>= 2;
+-  push1 = tempax;
++  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+ 
+-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+-        /* TW: 650/30xLV 1.10.6s */
+-        if(ModeNo > 0x13) {
+-	    if(resinfo != 0x09) {  /* 1280x1024 */
+-	        tempax <<= 1;
+-		tempbx += tempax;
+-	    }
+-	} else {
+-	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+-	        tempax <<= 1;
+-		tempbx += tempax;
+-	    }
+-	}
+-  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
+-    	tempax <<= 1;
+-    	tempbx += tempax;
++  if((ModeNo > 0x13) || (HwDeviceExtension->jChipType < SIS_315H)) {
++     if(resinfo != SIS_RI_1280x1024) {
++	tempbx += (tempax << 1);
++     }
++  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
++     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
++	tempbx += (tempax << 1);
++     }
+   }
+ 
+-  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+-      (SiS_Pr->SiS_HiVision == 3) ) {
+-    	tempbx -= 10;
++  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
++     (SiS_Pr->SiS_HiVision == 3)) {
++     tempbx -= 10;
+   } else {
+-    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+-                    tempbx += 40;
+-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
+-		    }
+-      	       }
+-	   }
+-    	}
++     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
++              tempbx += 40;
++	      if(HwDeviceExtension->jChipType >= SIS_315H) {
++	         if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
++	      }
++      	   }
++	}
++     }
+   }
+-  tempax = push1;
+   tempax >>= 2;
+   tempax++;
+   tempax += tempbx;
+   push1 = tempax;
+   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-    	if(tempbx <= 513)  {
+-      		if(tempax >= 513) tempbx = 513;
+-    	}
++     if(tempbx <= 513)  {
++     	if(tempax >= 513) tempbx = 513;
++     }
+   }
+   temp = tempbx & 0x00FF;
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
+ 
+-  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+-  	tempbx--;
+-  	temp = tempbx & 0x00FF;
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+-
+-	if(tempbx & 0x0100) tempcx |= 0x0008;
++  tempbx--;
++  temp = tempbx & 0x00FF;
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+ 
+-  	if(tempbx & 0x0200) {
+-    	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+-	}
++  if(tempbx & 0x0100) tempcx |= 0x0008;
+ 
+-  	tempbx++;
++  if(tempbx & 0x0200) {
++     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+   }
++  tempbx++;
++
+   if(tempbx & 0x0100) tempcx |= 0x0004;
+   if(tempbx & 0x0200) tempcx |= 0x0080;
+   if(tempbx & 0x0400) {
+-        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+-  	else                               tempcx |= 0x0C00;
++     if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
++     else                               tempcx |= 0x0C00;
+   }
+ 
+   tempbx = push1;
+-  temp = tempbx & 0x00FF;
+-  temp &= 0x0F;
++  temp = tempbx & 0x000F;
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
+ 
+   if(tempbx & 0x0010) tempcx |= 0x2000;
+ 
+   temp = tempcx & 0x00FF;
+-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+-	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
+-	}
+-  }
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
+ 
+   temp = (tempcx & 0xFF00) >> 8;
+@@ -1074,8 +1061,8 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+   temp = (tempax & 0xFF00) >> 8;
+   temp = (temp >> 1) & 0x09;
+   if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+-       /* Only use 8 dot clock */
+-       temp |= 0x01;
++     /* Only use 8 dot clock */
++     temp |= 0x01;
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
+ 
+@@ -1084,16 +1071,15 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, U
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
+ 
+   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+-       if(IS_SIS650) {
+-           /* TW: 650/30xLV 1.10.6s */
+-           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+-	       temp = 0x80;
+-	   }
+-       } else temp = 0x80;
+-  } else  temp = 0x00;
++     if(IS_SIS650) {
++        /* 650/30xLV 1.10.6s */
++        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
++	   temp = 0x80;
++	}
++     } else temp = 0x80;
++  } else temp = 0x00;
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
+ 
+-  return;
+ }
+ 
+ void
+@@ -1108,40 +1094,52 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ #endif
+   ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
+ 
++  /* This is not supported on LVDS */
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++  if(SiS_Pr->UseCustomMode) return;
++
+   if(ModeNo <= 0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   } else {
+-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   }
+ 
+-  /* TW: Set up Panel Link */
++  /* Set up Panel Link */
+ 
+   /* 1. Horizontal setup */
+ 
+   tempax = SiS_Pr->SiS_LCDHDES;
+ 
+-  if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
+-      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
+-  	tempax -= 8;
++  if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
++         (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
++  	   tempax -= 8;
++     }
+   }
+ 
+   tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
+ 
+   tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
+ 
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++     tempbx >>= 1;
++  }
++
+   if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+- 	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx =  800;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW */
+-    	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW */
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx = 1280;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; 
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400; 
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600; 
++        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++	   tempbx = SiS_Pr->PanelXRes;
++	} else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++	   tempbx = SiS_Pr->PanelXRes;
++	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++	      tempbx = 800;
++	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
++	         tempbx = 1024;
++	      }
++	   }
+         }
+      }
+   }
+@@ -1154,13 +1152,18 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+   if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+ 
+   push2 = tempax;
+-  
+-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 
+-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
+-     	   else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
++
++  if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
++     (!SiS_Pr->SiS_IF_DEF_DSTN) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
++     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++     	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
++	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
++     	      else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ 	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+ 	  	   if(HwDeviceExtension->jChipType < SIS_315H) {
+ 		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+@@ -1174,11 +1177,12 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 		   } else {
+ 		      tempcx = 0x0018;
+ 		   }
++	      }
++	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
++	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
++	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
++	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+ 	   }
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+         }
+      }
+   }
+@@ -1188,14 +1192,18 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   tempax = tempcx >> 3;                          /* BPLHRS */
+   temp = tempax & 0x00FF;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; Panel Link Horizontal Retrace Start  */
+ 
+   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+      temp = (tempax & 0x00FF) + 2;
+   } else {
+      temp = (tempax & 0x00FF) + 10;
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
++        if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
++	   (!SiS_Pr->SiS_IF_DEF_FSTN) &&
++	   (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++	   (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++	   (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ 	      temp += 6;
+               if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+@@ -1219,47 +1227,57 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   temp &= 0x1F;
+   temp |= ((tempcx & 0x0007) << 5);
+-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
++#if 0
++  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
++#endif
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
+ 
+   tempbx = push2;
+   tempcx = push1;                                /* lcdhdes  */
+ 
+   temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+ 
+   tempcx >>= 3;                                  /* BPLHDES */
+   temp = (tempcx & 0x00FF);
+-  if(ModeNo == 0x5b) temp--;                     
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
++#if 0 /* Not 550 FSTN */
++  if(HwDeviceExtension->jChipType >= SIS_315H) {
++     if(ModeNo == 0x5b) temp--; */
++  }
++#endif
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; Panel Link Horizontal Display Enable Start  */
+ 
+-  if(HwDeviceExtension->jChipType < SIS_315H) {  
++  if((HwDeviceExtension->jChipType < SIS_315H) ||
++     (SiS_Pr->SiS_IF_DEF_FSTN) ||
++     (SiS_Pr->SiS_IF_DEF_DSTN)) {
+      if(tempbx & 0x07) tempbx += 8;              
+   }
+   tempbx >>= 3;                                  /* BPLHDEE  */
+   temp = tempbx & 0x00FF;
+-  if(ModeNo == 0x5b) temp--;			 
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
++#if 0 /* Not 550 FSTN */
++  if(HwDeviceExtension->jChipType >= SIS_315H) {
++     if(ModeNo == 0x5b) temp--;
++  }
++#endif
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; Panel Link Horizontal Display Enable End  */
+ 
+   /* 2. Vertical setup */
+ 
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+      tempcx = SiS_Pr->SiS_VGAVT;
+      tempbx = SiS_Pr->SiS_VGAVDE;
+-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+-	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)       tempbx =  600;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx =  600;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx =  768;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx =  768;
+-	   else								tempbx = 1024;
+-        }
++     if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
++        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++	      tempbx = SiS_Pr->PanelYRes;
++           }
++	}
+      }
+      tempcx -= tempbx;
+ 
+   } else {
+ 
+-     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
++     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
+ 
+   }
+ 
+@@ -1268,18 +1286,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   tempax = SiS_Pr->SiS_VGAVDE;
+ 
+-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+-     if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   && 
+-         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+-         (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
+-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax =  600;
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax =  600;  
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax =  768;
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax =  768;  
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempax =  768;  
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; 
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; 
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; 
++  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++     if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++           tempax = 600;
++	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
++	      tempax = 768;
++	   }
++	}
++     } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
++                (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
++                ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
++	         (SiS_Pr->SiS_IF_DEF_FSTN) ||
++	         (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
++	tempax = SiS_Pr->PanelYRes;
+      }
+   }
+ 
+@@ -1290,11 +1310,25 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   tempcx >>= 1;
+ 
+-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+-     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0001;
+-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0001;
++  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
++     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++	tempcx = 0x0017;
++     } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
++  	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
++	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
++           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
++           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
++	   else 							  tempcx = 0x0057;
++        } else  {
++     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
++	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
+      	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+ 	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
+ 		   if(HwDeviceExtension->jChipType < SIS_315H) {
+@@ -1304,7 +1338,7 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 			    tempcx = 0x0003;
+ #endif
+ 		      } else {
+-		            tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
++		            tempcx = 0x0002;   /* A901; sometimes 0x0003; */
+ 		      }
+ 		   } else tempcx = 0x0003;
+            }
+@@ -1319,26 +1353,33 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   tempbx += tempcx;			 	/* BPLVRS  */
+ 
+-  if(HwDeviceExtension->jChipType < SIS_315H) {
+-      tempbx++;
++  if((HwDeviceExtension->jChipType < SIS_315H) ||
++     (SiS_Pr->SiS_IF_DEF_FSTN) ||
++     (SiS_Pr->SiS_IF_DEF_DSTN)) {
++     tempbx++;
+   }
+ 
+   if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+ 
+   temp = tempbx & 0x00FF;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
+ 
+   tempcx >>= 3;
+ 
+-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
++  if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
++     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
++     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if( (HwDeviceExtension->jChipType < SIS_315H) &&
+             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
++	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
++	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
+         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
+         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
+         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
+ 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
+-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;	 
++        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
+         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
+         else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
+         else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
+@@ -1360,26 +1401,37 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 
+   tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
+   temp = tempcx & 0x000F;
+-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
++  if(SiS_Pr->SiS_IF_DEF_FSTN ||
++     SiS_Pr->SiS_IF_DEF_DSTN ||
++     (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
++     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
++     temp |= 0x30;
++  }
++  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
+ 
+   temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
+-  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
+-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
++  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++     if(SiS_Pr->SiS_HDE != 640) {
++        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
++     }
++  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
++  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
+   if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+-      if(HwDeviceExtension->jChipType >= SIS_315H) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+-            temp |= 0x80;
+-         }
+-      } else {
+-	 if( (HwDeviceExtension->jChipType == SIS_630) ||
+-	     (HwDeviceExtension->jChipType == SIS_730) ) {
+-	    if(HwDeviceExtension->jChipRevision >= 0x30) {
+-	       temp |= 0x80;
+-	    }
+-	 }
+-      }
++     if(HwDeviceExtension->jChipType >= SIS_315H) {
++        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
++           temp |= 0x80;
++        }
++     } else {
++	if( (HwDeviceExtension->jChipType == SIS_630) ||
++	    (HwDeviceExtension->jChipType == SIS_730) ) {
++	   if(HwDeviceExtension->jChipRevision >= 0x30) {
++	      temp |= 0x80;
++	   }
++	}
++     }
+   }
+-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
++  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+ 
+   if (HwDeviceExtension->jChipType < SIS_315H) {
+ 
+@@ -1396,19 +1448,19 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+ 	}
+ 
+   	temp = (USHORT)(tempebx & 0x00FF);
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
++  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+ 
+ #endif /* SIS300 */
+ 
+   } else {
+ 
+-#ifdef SIS315H  /* 310/325 series */
++#ifdef SIS315H  /* 315 series */
+ 
+-#ifdef NEWCH701x
+-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+-#else
+-	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+-#endif	
++        if(HwDeviceExtension->jChipType == SIS_740) {
++           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
++        } else {
++	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
++	}
+ 
+ 	tempeax = SiS_Pr->SiS_VGAVDE << 18;
+     	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+@@ -1417,12 +1469,13 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+     	tempebx = tempeax;                         /* BPLVCFACT  */
+         tempvcfact = tempeax;
+     	temp = (USHORT)(tempebx & 0x00FF);
+-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
++    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
+     	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
++    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
+     	temp = (USHORT)((tempebx & 0x00030000) >> 16);
++	temp &= 0x03;
+     	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
++    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
+ 
+ #endif /* SIS315H */
+ 
+@@ -1434,47 +1487,50 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+   push1 = temp;					   
+ 
+   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
++   	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
+ 		if(HwDeviceExtension->jChipType < SIS_315H) {
+ 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+-      				if(resinfo == 15) tempcx++;
++      				if(resinfo == SIS_RI_1024x600) tempcx++;
+ 				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-					if(resinfo == 7) tempcx++;
++					if(resinfo == SIS_RI_800x600) tempcx++;
+ 		    		}
+ 			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-      				if(resinfo == 7) tempcx++;
+-				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
+-			} else  if(resinfo == 8) tempcx++;
++      				if(resinfo == SIS_RI_800x600)  tempcx++;
++				if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
++			} else  if(resinfo == SIS_RI_1024x768) tempcx++;
+ 		} else {
+ 			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-      				if(resinfo == 7) tempcx++;
++      				if(resinfo == SIS_RI_800x600)  tempcx++;
+ 			}
+ 		}
+ 	}
+   }
+ 
+   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+-     tempcx = SiS_Pr->SiS_VGAVDE;
+-     tempbx = SiS_Pr->SiS_VGAVDE - 1;
++     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++        tempcx = SiS_Pr->SiS_VGAVDE;
++        tempbx = SiS_Pr->SiS_VGAVDE - 1;
++     }
+   }
+ 
+   temp = ((tempbx & 0x0700) >> 8) << 3;
+   temp |= ((tempcx & 0x0700) >> 8);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
+ 
+   temp = tempbx & 0x00FF;
+-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
++  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; Panel Link Vertical Display Enable End  */
+ 
+   temp = tempcx & 0x00FF;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
+ 
+   /* 3. Additional horizontal setup (scaling, etc) */
+ 
+   tempecx = SiS_Pr->SiS_VGAHDE;
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-     if(modeflag & HalfDCLK)
+-        tempecx >>= 1;
++     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++        if(modeflag & HalfDCLK) tempecx >>= 1;
++     }
+   }
+   tempebx = SiS_Pr->SiS_HDE;
+   if(tempecx == tempebx) tempeax = 0xFFFF;
+@@ -1484,139 +1540,165 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,U
+      temp = (USHORT)(tempeax % tempebx);
+      tempeax = tempeax / tempebx;
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+-         if(temp) tempeax++;
++        if(temp) tempeax++;
+      }
+   }
+   tempecx = tempeax;
+ 
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      tempeax = SiS_Pr->SiS_VGAHDE;
+-      if(modeflag & HalfDCLK) tempeax >>= 1;
+-      tempeax <<= 16;
+-      tempeax = (tempeax / tempecx) - 1;
++     tempeax = SiS_Pr->SiS_VGAHDE;
++     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
++        if(modeflag & HalfDCLK) tempeax >>= 1;
++     }
++     tempeax <<= 16;
++     tempeax = (tempeax / tempecx) - 1;
+   } else {
+-      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
++     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+   }
+   tempecx <<= 16;
+   tempecx |= (tempeax & 0xFFFF);
+   temp = (USHORT)(tempecx & 0x00FF);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
+ 
+   tempbx = SiS_Pr->SiS_VDE;
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+-      tempbx = (USHORT)(tempeax & 0x0FFFF);
++     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
++     tempbx = (USHORT)(tempeax & 0x0FFFF);
+   } else {
+-      tempax = SiS_Pr->SiS_VGAVDE << 6;
+-      tempbx = push1;
+-      tempbx &= 0x3f;
+-      if(tempbx == 0) tempbx = 64;
+-      tempax = tempax / tempbx;
+-      tempbx = tempax;
++     tempeax = SiS_Pr->SiS_VGAVDE << 6;
++     tempbx = push1 & 0x3f;
++     if(tempbx == 0) tempbx = 64;
++     tempeax /= tempbx;
++     tempbx = (USHORT)(tempeax & 0x0FFFF);
+   }
+   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
++  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
++     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
++     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
++  }
+ 
+   temp = ((tempbx & 0xFF00) >> 8) << 3;
+   temp |= (USHORT)((tempecx & 0x0700) >> 8);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; Overflow register */
+ 
+   temp = tempbx & 0x00FF;
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; Panel Link Vertical Accumulator Register */
+ 
+   tempecx >>= 16;                               /* BPLHCFACT  */
+-  if(HwDeviceExtension->jChipType < SIS_315H) {
+-      if(modeflag & HalfDCLK) tempecx >>= 1;
++  if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
++     if(modeflag & HalfDCLK) tempecx >>= 1;
+   }
+   temp = (USHORT)((tempecx & 0xFF00) >> 8);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; Panel Link Horizontal Scaling Factor High */
+ 
+   temp = (USHORT)(tempecx & 0x00FF);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
++  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+ 
+   /* 630/301B and 630/LVDS do something for 640x480 panels here */
+ 
+ #ifdef SIS315H
+-  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
+-  if(SiS_Pr->SiS_IF_DEF_DSTN) {
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+-     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
+-     	temp = tempbx & 0x00FF;
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
+-     	temp=((tempbx & 0xFF00) >> 8) << 3;
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+-     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
+-     	temp = tempbx & 0x00FF;
+-     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+-     	tempbx = SiS_Pr->SiS_VDE / 2;
+-     	temp = tempbx & 0x00FF;
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
+-     	temp = ((tempbx & 0xFF00) >> 8) << 3;
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+-     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
+-     	tempebx = 128;
+-     	temp = (USHORT)(tempeax % tempebx);
+-     	tempeax = tempeax / tempebx;
+-     	if(temp != 0)  tempeax++;
+-     	temp = (USHORT)(tempeax & 0x003F);
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+-     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
+-     	pushcx = tempax;
+-     	temp = tempax & 0x00FF;
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
+-     	temp = ((tempax & 0xFF00) >> 8) << 3;
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+-     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+-     	tempeax = (tempax * pushcx);
+-     	tempebx = 0x00100000 + tempeax;
+-     	temp = (USHORT)tempebx & 0x000000FF;
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
+-     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
+-     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
+-     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
+-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
+-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+-     	if(SiS_Pr->SiS_IF_DEF_FSTN){
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
+-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
+-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
+-     	}
+-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
+-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
++  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
++     tempax = SiS_Pr->SiS_HDE;                       		/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++     tempax += 64;
++     temp = tempax & 0x00FF;
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
++     temp = ((tempax & 0xFF00) >> 8) << 3;
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
++     tempax += 32;		                     		/* Blpe=lBlps+32 */
++     temp = tempax & 0x00FF;
++     if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/* Bflml=0 */
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
++
++     tempax = SiS_Pr->SiS_VDE;
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++     tempax >>= 1;
++     temp = tempax & 0x00FF;
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
++     temp = ((tempax & 0xFF00) >> 8) << 3;
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
++
++     tempeax = SiS_Pr->SiS_HDE;
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
++     tempeax <<= 2;                       			/* BDxFIFOSTOP = (HDE*4)/128 */
++     tempebx = 128;
++     temp = (USHORT)(tempeax % tempebx);
++     tempeax = tempeax / tempebx;
++     if(temp) tempeax++;
++     temp = (USHORT)(tempeax & 0x003F);
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
++
++     tempax = SiS_Pr->SiS_HDE;
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++     tempax >>= 4;                        			/* BDxWadroff = HDE*4/8/8 */
++     pushcx = tempax;
++     temp = tempax & 0x00FF;
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
++     temp = ((tempax & 0xFF00) >> 8) << 3;
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
++
++     tempax = SiS_Pr->SiS_VDE;                             	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
++     tempeax = (tempax * pushcx);
++     tempebx = 0x00100000 + tempeax;
++     temp = (USHORT)tempebx & 0x000000FF;
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
++     temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
++     temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
++     temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
++
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0x38);
++
++     if(SiS_Pr->SiS_IF_DEF_FSTN) {
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,0x0c);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,0x80);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,0xA0);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3a,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3c,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3d,0x10);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3e,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3f,0x00);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,0x10);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,0x25);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,0x80);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,0x14);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x44,0x03);
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x45,0x0a);
++     }
+   }
+ #endif  /* SIS315H */
+ 
+-  return;
+-
+ }
+ 
+ #ifdef SIS315H
+@@ -1629,7 +1711,7 @@ SiS_CRT2AutoThreshold(SiS_Private *SiS_P
+ 
+ 
+ #ifdef SIS315H
+-/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
++/* For LVDS / 302B/30xLV - LCDA (this must only be called on 315 series!) */
+ void
+ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+@@ -1638,6 +1720,10 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+   USHORT push1,push2,tempax,tempbx,tempcx,temp;
+   ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+ 
++  /* This is not supported with LCDA */
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++  if(SiS_Pr->UseCustomMode) return;
++
+   if(IS_SIS330) {
+      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
+   } else if(IS_SIS740) {
+@@ -1645,7 +1731,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
+ 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+      } else {
+-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV 1.10.1i */
++        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV, 301BDH */
+      }
+   } else {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
+@@ -1669,10 +1755,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+   tempcx = SiS_Pr->SiS_HT;
+ 
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
+-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
+-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
+-	else 							      tempbx = 1280;
++        tempbx = SiS_Pr->PanelXRes;
+   }
+   tempcx -= tempbx;                        	            	/* HT-HDE  */
+   push1 = tempax;
+@@ -1684,7 +1767,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+ 
+   tempcx >>= 2;
+ 
+-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
++  /* 650/30xLV 1.10.6s, 740/LVDS */
+   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+@@ -1748,13 +1831,10 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+   tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
+   push1 = tempbx;                                      		
+   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempax = 768;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
+-    else                                                           tempax = 960;
+-  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
++     tempax = SiS_Pr->PanelYRes;
++  } else {
++     tempax = SiS_Pr->SiS_VGAVDE;
++  }
+ 
+   tempbx += tempax;
+   tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
+@@ -1764,7 +1844,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+  
+   tempcx >>= 2;	
+ 
+-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
++  /* 650/30xLV 1.10.6s, 740/LVDS */
+   if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+       ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+@@ -1806,7 +1886,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
+   } else {
+-     /* TW: 650/30xLV 1.10.6s, Xabre */
++     /* 650/30xLV 1.10.6s, Xabre */
+      temp |= 0xC0;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
+   }
+@@ -1823,7 +1903,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+      }
+   } else {
+      if(IS_SIS650) {
+-        /* TW: 650/30xLV 1.10.6s */
++        /* 650/30xLV 1.10.6s */
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+         }
+@@ -1839,7 +1919,7 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+ 
+   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-      if(resinfo == 7) tempcx++;
++      if(resinfo == SIS_RI_800x600) tempcx++;
+     }
+   }
+   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+@@ -1925,18 +2005,17 @@ SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, 
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+ 
+ #if 0
+-  /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
++  /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
+   if(xxx()) {
+       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
+   }
+ #endif
+ 
+-  /* TW: Only for LVDS and 301LV/302LV */
++  /* Only for LVDS and 301LV/302LV */
+   if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
+-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+   }
+ 
+-  return;
+ }
+ #endif  /* SIS 315 */
+ 
+@@ -1951,10 +2030,10 @@ void SiS_SetCRT2Offset(SiS_Private *SiS_
+ 
+   offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                          HwDeviceExtension);
+-#if 0
+-  if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
+-  if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
+-#endif			 
++
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
++
+   temp = (UCHAR)(offset & 0xFF);
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
+   temp = (UCHAR)((offset & 0xFF00) >> 8);
+@@ -1976,13 +2055,7 @@ SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+      modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+-  
+-     if(HwDeviceExtension->jChipType < SIS_315H ) {
+-    	index = (modeinfo >> 4) & 0xFF;
+-     } else {
+-    	index = (modeinfo >> 8) & 0xFF;
+-     }
+-
++     index = (modeinfo >> 8) & 0xFF;
+      temp = SiS_Pr->SiS_ScreenOffset[index];
+   }
+   
+@@ -1992,9 +2065,8 @@ SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR
+ 
+   temp *= colordepth;
+ 
+-  /* TW: For 1400x1050 and 856x480 */
+-  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || 
+-        ModeNo == 0x3f || 
++  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
++        ModeNo == 0x3f ||
+ 	ModeNo == 0x42 || 
+ 	ModeNo == 0x45 ) ||
+       (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+@@ -2012,7 +2084,8 @@ SiS_GetColorDepth(SiS_Private *SiS_Pr, U
+   SHORT  index;
+   USHORT modeflag;
+ 
+-  if(SiS_Pr->UseCustomMode) {
++  /* Do NOT check UseCustomMode, will skrew up FIFO */
++  if(ModeNo == 0xfe) {
+      modeflag = SiS_Pr->CModeFlag;
+   } else {
+      if(ModeNo <= 0x13)
+@@ -2035,7 +2108,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+   flag = 0;
+   tempbl = 0xC0;
+ 
+-  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++  if(SiS_Pr->UseCustomMode) {
++     infoflag = SiS_Pr->CInfoFlag;
++  } else {
++     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++  }
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
+ 
+@@ -2044,12 +2121,19 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+     } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+        tempah = SiS_Pr->SiS_LCDInfo;
+     } else tempah = infoflag >> 8;
+-    
++
+     tempah &= 0xC0;
+-    
++
+     tempah |= 0x20;
+     if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ 
++    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++          (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++	  tempah |= 0xc0;
++       }
++    }
++
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(HwDeviceExtension->jChipType >= SIS_315H) {
+           tempah >>= 3;
+@@ -2079,9 +2163,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+             tempah |= 0x20;
+             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ 
++#if 0
+             if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+-	       	/* TW: BIOS does something here @@@ */
++	       	/* BIOS does something here @@@ */
+             }
++#endif
+ 
+  	    tempah &= 0x3f;
+   	    tempah |= tempbl;
+@@ -2089,16 +2175,11 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+ 
+          } else {							/* 630 - 301 */
+ 
+-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-               tempah = SiS_Pr->SiS_LCDInfo;
+-	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
+-	          flag = 1;
+-	       }
+-            }
+-            if(flag != 1) tempah = infoflag >> 8;
++            tempah = infoflag >> 8;
+             tempah &= 0xC0;
+-            tempah |= 0x30;
+-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
++            tempah |= 0x20;
++	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
++            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ 
+          }
+ 
+@@ -2106,34 +2187,50 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+ 
+       } else {
+ 
+-#ifdef SIS315H  /* ----- 310/325 series ---- */
++#ifdef SIS315H  /* ------- 315 series ------ */
+ 
+-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 310/325 - 30xLV */
++         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
++
++	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++	       tempah = infoflag >> 8;
++	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++	          tempah = SiS_Pr->SiS_LCDInfo;
++	       }
++	    } else {
++               tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
++	    }
++	    tempah &= 0xC0;
+ 
+-            tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+-            tempah &= 0xC0;
+             tempah |= 0x20;
+             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ 
+-         } else {							/* 310/325 - 301, 301B */
++         } else {							/* 315 - 301, 301B */
+ 
+             tempah = infoflag >> 8;
+-            tempah &= 0xC0;
+-	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+-	          tempah = SiS_Pr->SiS_LCDInfo;
+-	          tempah &= 0xC0;
++	    if(!SiS_Pr->UseCustomMode) {
++	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++	          if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++	             tempah = SiS_Pr->SiS_LCDInfo;
++	          }
+ 	       }
+ 	    }
++	    tempah &= 0xC0;
+ 	    
+             tempah |= 0x20;
+             if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
++
+ #if 0
+             if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+-		/* TW: BIOS does something here @@@ */
++		/* BIOS does something here @@@ */
+             }
+-#endif	    
++#endif
++
++	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* TEST, imitate BIOS bug */
++	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++	          tempah |= 0xc0;
++	       }
++	    }
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ 
+          } 
+@@ -2143,7 +2240,7 @@ SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USH
+    }
+ }
+ 
+-/* TW: Set CRT2 FIFO on 300/630/730 */
++/* Set CRT2 FIFO on 300/630/730 */
+ #ifdef SIS300
+ void
+ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+@@ -2197,7 +2294,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+ 
+   if(!SiS_Pr->CRT1UsesCustomMode) {
+   
+-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
++     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 	/* get CRT1 ModeNo */
+      SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
+      SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+      SiS_Pr->SiS_SelectCRT2Rate = 0;
+@@ -2205,20 +2302,32 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+ 						modeidindex,HwDeviceExtension);
+ 
+      if(CRT1ModeNo >= 0x13) {
+-       index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+-       index &= 0x3F;
+-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
+-       data2 = SiS_Pr->SiS_ModeType - 2;
++        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
++        index &= 0x3F;
++        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
++
++	colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
++        colorth >>= 1;
++        if(!colorth) colorth++;
+      }
+-     
++
+   } else {
+   
+      CRT1ModeNo = 0xfe;
+-     VCLK = SiS_Pr->CSRClock;						/* Get VCLK */
+-     data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+-  
+-  }			
+-     
++     VCLK = SiS_Pr->CSRClock_CRT1;						/* Get VCLK */
++     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
++     switch(data2) {								/* Get color depth */
++        case 0 : colorth = 1; break;
++        case 1 : colorth = 1; break;
++        case 2 : colorth = 2; break;
++        case 3 : colorth = 2; break;
++        case 4 : colorth = 3; break;
++        case 5 : colorth = 4; break;
++        default: colorth = 2;
++     }
++
++  }
++
+   if(CRT1ModeNo >= 0x13) {
+     if(HwDeviceExtension->jChipType == SIS_300) {
+        index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+@@ -2227,22 +2336,8 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+     }
+     index &= 0x07;
+     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
+-    
+-#ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
+-    	CRT1ModeNo, VCLK, MCLK, data2);
+-#endif  
+-  
+-    switch(data2) {							/* Get color depth */
+-      case 0 : 	colorth = 1; break;
+-      case 1 : 	colorth = 1; break;
+-      case 2 : 	colorth = 2; break;
+-      case 3 : 	colorth = 2; break;
+-      case 4 : 	colorth = 3; break;
+-      case 5 : 	colorth = 4; break;
+-      default:  colorth = 2; break;
+-    }
+-    data2 = (colorth * VCLK) / MCLK;  
++
++    data2 = (colorth * VCLK) / MCLK;
+ 
+     temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+     temp = ((temp & 0x00FF) >> 6) << 1;
+@@ -2252,22 +2347,12 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+ 
+     data2 = temp - data2;
+     
+-#ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
+-    	data2);
+-#endif    
+-
+     if((28 * 16) % data2) {
+       	data2 = (28 * 16) / data2;
+       	data2++;
+     } else {
+       	data2 = (28 * 16) / data2;
+     }
+-    
+-#ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
+-    	data2);
+-#endif
+ 
+     if(HwDeviceExtension->jChipType == SIS_300) {
+ 
+@@ -2313,10 +2398,6 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+        temp &= 0x0F;   
+        tempal |= temp;
+ 
+-#ifdef TWDEBUG
+-       xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
+-#endif
+-      
+        tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+        tempbx = 0;        /* -- do it like the BIOS anyway... */
+        tempax = tempbx;
+@@ -2341,7 +2422,7 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+        SiS_SetReg4(0xcf8,0x800000A0);
+        eax = SiS_GetReg3(0xcfc);
+ #else
+-       /* TW: We use pci functions X offers. We use tag 0, because
++       /* We use pci functions X offers. We use tag 0, because
+         * we want to read/write to the host bridge (which is always
+         * 00:00.0 on 630, 730 and 540), not the VGA device.
+         */
+@@ -2368,43 +2449,41 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+        if(!(temp & 0x80)) data += 5;
+     }
+     
+-#ifdef TWDEBUG    
+-    xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
+-#endif
+-
+     data += data2;				/* CRT1 Request Period */
+     
+-#ifdef TWDEBUG    
+-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
+-#endif
+-
+-    CRT2ModeNo = ModeNo;
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+-    SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);    
+ 
+-    refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+-                                               modeidindex,HwDeviceExtension);
++    if(!SiS_Pr->UseCustomMode) {
++
++       CRT2ModeNo = ModeNo;
++       SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);
++
++       refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
++                                                  modeidindex,HwDeviceExtension);
++
++       index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
++                               refreshratetableindex,HwDeviceExtension);
++       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
++
++       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++	     if(ROMAddr[0x220] & 0x01) {
++                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
++	     }
++          }
++       }
++
++    } else {
++
++       CRT2ModeNo = 0xfe;
++       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
+ 
+-    index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
+-                            refreshratetableindex,HwDeviceExtension);
+-    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
+-    
+-    data2 = SiS_Pr->SiS_ModeType - 2;
+-    switch(data2) {							/* Get color depth */
+-      case 0 : 	colorth = 1; break;
+-      case 1 : 	colorth = 1; break;
+-      case 2 : 	colorth = 2; break;
+-      case 3 : 	colorth = 2; break;
+-      case 4 : 	colorth = 3; break;
+-      case 5 : 	colorth = 4; break;
+-      default:  colorth = 2; break;
+     }
+-    
+-#ifdef TWDEBUG    
+-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
+-    	CRT2ModeNo, VCLK, MCLK, data2, colorth);
+-#endif
++
++    colorth = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
++    colorth >>= 1;
++    if(!colorth) colorth++;
+ 
+     data = data * VCLK * colorth;
+     if(data % (MCLK << 4)) {
+@@ -2414,10 +2493,6 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+       	data = data / (MCLK << 4);
+     }
+     
+-#ifdef TWDEBUG    
+-    xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
+-#endif    
+-    
+     if(data <= 6) data = 6;
+     if(data > 0x14) data = 0x14;
+ 
+@@ -2456,13 +2531,13 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,
+ }
+ #endif
+ 
+-/* TW: Set FIFO on 310/325/330 series */
++/* Set FIFO on 315/330 series */
+ #ifdef SIS315H
+ void
+ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-
++#if 0   /* This code is obsolete */
+   UCHAR CombCode[]  = { 1, 1, 1, 4, 3, 1, 3, 4,
+                         4, 1, 4, 4, 5, 1, 5, 4};
+   UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
+@@ -2474,11 +2549,13 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
+   USHORT ModeIdIndex;
+   USHORT RefreshRateTableIndex;
+   USHORT SelectRate_backup;
+-  
++
+   SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+-  
++#endif
++
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+ 
++#if 0
+   if(!SiS_Pr->CRT1UsesCustomMode) {
+   
+      CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
+@@ -2489,28 +2566,27 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
+ 
+      /* Get REFIndex for crt1 refreshrate */
+      RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+-                                             ModeIdIndex,HwDeviceExtension);
++                                                ModeIdIndex,HwDeviceExtension);
++     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
++     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
+ 
+-     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
+-                          RefreshRateTableIndex,HwDeviceExtension);
+-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                        /* Get VCLK */
+-     
+      tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
+      tempbx >>= 1;
+-     if(!tempbx) tempbx++; 
+-     
++     if(!tempbx) tempbx++;
++
+   } else {
+-  
+-     tempax = SiS_Pr->CSRClock;						/* Get VCLK */
+-     tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
++
++     CRT1ModeNo = 0xfe;
++     tempax = SiS_Pr->CSRClock_CRT1;					/* Get VCLK */
++     tempbx = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+      switch(tempbx) {							/* Get color depth */
+-       case 0 : 	tempbx = 1; break;
+-       case 1 : 	tempbx = 1; break;
+-       case 2 : 	tempbx = 2; break;
+-       case 3 : 	tempbx = 2; break;
+-       case 4 : 	tempbx = 3; break;
+-       case 5 : 	tempbx = 4; break;
+-       default:  	tempbx = 2; break;
++       case 0 : tempbx = 1; break;
++       case 1 : tempbx = 1; break;
++       case 2 : tempbx = 2; break;
++       case 3 : tempbx = 2; break;
++       case 4 : tempbx = 3; break;
++       case 5 : tempbx = 4; break;
++       default: tempbx = 2;
+      }
+   
+   }
+@@ -2523,13 +2599,6 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
+ 
+   tempbx = tempax;
+ 
+-#if 0 /* TW: BIOS code is skrewed */
+-  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
+-   	tempax = 16;
+-  } else {
+-    	tempax = 8;
+-  }
+-#endif
+   tempax = 16;
+ 
+   tempax -= tempbx;
+@@ -2556,24 +2625,33 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
+ 
+   tempcx +=  temp3;                                      /* CRT1 Request Period */
+ 
+-  CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
+-  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);           /* Get ModeID Table */
+-
+   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+   SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+ 
+-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+-                                           ModeIdIndex,HwDeviceExtension);
++  if(!SiS_Pr->UseCustomMode) {
++
++     CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
++     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);
++
++     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
++                                                ModeIdIndex,HwDeviceExtension);
++
++     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
++                             RefreshRateTableIndex,HwDeviceExtension);
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
++        tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
++     } else {
++        tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;
++     }
+ 
+-  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
+-                          RefreshRateTableIndex,HwDeviceExtension);
+-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
+   } else {
+-     tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;                     /* Get VCLK  */
++
++     CRT2ModeNo = 0xfe;							  /* Get VCLK  */
++     tempax = SiS_Pr->CSRClock;
++
+   }
+ 
+-  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   /* Get colordepth */
++  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   	  /* Get colordepth */
+   tempbx >>= 1;
+   if(!tempbx) tempbx++;
+ 
+@@ -2590,12 +2668,16 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr,
+ 
+   if (tempax > 0x37)  tempax = 0x37;
+ 
+-  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
++  /* 650/LVDS, 650/301LV, 740, 330 overrule calculated value; 315 does not */
+   if(HwDeviceExtension->jChipType >= SIS_650) {
+   	tempax = 0x04;
+   }
+-  
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
++#else
++
++  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
++
++#endif
+ }
+ 
+ USHORT
+@@ -2611,9 +2693,10 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *
+     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+   }
+ }
++
+ #endif
+ 
+-/* TW: Checked against 650/LVDS 1.10.07 BIOS */
++/* Checked against 650/LVDS 1.10.07 BIOS */
+ void
+ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                    USHORT RefreshRateTableIndex,
+@@ -2623,7 +2706,15 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
+   USHORT PanelIndex,ResIndex;
+   const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
+ 
+-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
++  if((SiS_Pr->UseCustomMode) ||
++     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
++     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
++     SiS_Pr->SiS_LCDHDES = 0;
++     SiS_Pr->SiS_LCDVDES = 0;
++     return;
++  }
++
++  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ 
+ #ifdef SIS315H  
+      SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+@@ -2689,11 +2780,11 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
+      	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
+      	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
+ 	default:
+-		if(HwDeviceExtension->jChipType < SIS_315H)
+-		   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+-		else
+-		   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+-		break;
++		 if(HwDeviceExtension->jChipType < SIS_315H)
++		    PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
++		 else
++		    PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
++		 break;
+      }
+   }
+   SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+@@ -2710,7 +2801,7 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
+      } else {
+         if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+            if( (HwDeviceExtension->jChipType < SIS_315H) || 
+-	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {  
++	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
+               if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
+                  if(ModeNo <= 0x13) {
+ 	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+@@ -2737,7 +2828,7 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, 
+         }
+      }
+   }
+-  return;
++
+ }
+ 
+ void
+@@ -2757,11 +2848,11 @@ SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, U
+ 
+   tempbx = 0;
+   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+         tempbx = 50;
+         if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
+         if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+-        /* TW: Nothing special needed for SOverscan    */
++        /* Nothing special needed for SOverscan    */
+         /*     PALM uses NTSC data, PALN uses PAL data */
+      }
+   }
+@@ -2773,7 +2864,7 @@ SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, U
+         if(modeflag & HalfDCLK) tempbx++;
+      }
+   }
+-  /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
++  /* 630/LVDS and 650/LVDS (1.10.07) BIOS */
+   if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
+         tempal = 0x07;
+@@ -2833,14 +2924,13 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+      }
+   }
+   
+-  /* TW: BIOS does not do this (neither 301 nor LVDS) */
++  /* BIOS does not do this (neither 301 nor LVDS) */
+   /*     (But it's harmless; see SetCRT2Offset) */
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
+ 
+-  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ 
+-	/* TW:   1. for LVDS/302B/302LV **LCDA** */
++	/*   1. for LVDS/302B/302LV **LCDA** */
+ 
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
+@@ -2855,23 +2945,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+ #ifdef SIS300    /* ---- 300 series ---- */
+ 
+-      /* For 301BDH: */
++      /* For 301BDH: (with LCD via LVDS) */
+       if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+-	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
+-	  temp &= 0xef;
+-	  temp |= 0x02;
+-	  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+-	     temp |= 0x10;
+-	     temp &= 0xfd;
+-	  }
+-	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++	 temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
++	 temp &= 0xef;
++	 temp |= 0x02;
++	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
++	    temp |= 0x10;
++	    temp &= 0xfd;
++	 }
++	 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+       }
+ 
+       if(ModeNo > 0x13) {
+-        tempcl -= ModeVGA;
+-        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
+-           tempah = ((0x10 >> tempcl) | 0x80);
+-        }
++         tempcl -= ModeVGA;
++         if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
++            tempah = ((0x10 >> tempcl) | 0x80);
++         }
+       } else tempah = 0x80;
+ 
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
+@@ -2880,7 +2970,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+     } else {
+ 
+-#ifdef SIS315H    /* ---- 310/325/330 series ---- */
++#ifdef SIS315H    /* ------- 315/330 series ------ */
+ 
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+          if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
+@@ -2889,12 +2979,12 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+       }
+ 
+       if(ModeNo > 0x13) {
+-        tempcl -= ModeVGA;
+-        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
+-           tempah = (0x08 >> tempcl);
+-           if (tempah == 0) tempah = 1;
+-           tempah |= 0x40;
+-        }
++         tempcl -= ModeVGA;
++         if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
++            tempah = (0x08 >> tempcl);
++            if (tempah == 0) tempah = 1;
++            tempah |= 0x40;
++         }
+       } else tempah = 0x40;
+ 
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
+@@ -2921,7 +3011,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+-	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
++	/*   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
+ 
+     	tempah = 0x01;
+     	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+@@ -2938,7 +3028,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+     	if(HwDeviceExtension->jChipType < SIS_315H) {
+ 
+-		/* --- 300 series --- */
++		/* ---- 300 series ---- */
+ 
+       		tempah = (tempah << 5) & 0xFF;
+       		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+@@ -2946,7 +3036,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+     	} else {
+ 
+-		/* --- 310 series --- */
++		/* ---- 315 series ---- */
+ 
+       		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+ 
+@@ -2956,9 +3046,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+       		tempah |= 0x10;
+ 	}
+ 
+-	/* TW: 630/301 BIOS */
+ 	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
+-		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+ 			tempah |= 0x80;
+ 		}
+ 	} else {
+@@ -2996,28 +3086,31 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+       	      }
+ 	   }
+     	}
+-	/* TW: For 302LV dual-channel */
++
++	/* For 302LV dual-channel */
+ 	if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
+-		    tempah |= 0x40;
+-	    }
++	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++	      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
++	         tempah |= 0x40;
++	   }
+ 	}
+ 
+ 	if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+-	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+-		tempah |= 0x80;
++	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
++	   ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
++	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
++	   tempah |= 0x80;
+ 	}
+ 
+     	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+ 
+     } else {
+ 
+-    	/* TW: 3. for LVDS */
++    	/* 3. for LVDS */
+ 
+ 	if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 
+-	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
++	   /* Inserted this entire section (BIOS 650/LVDS); added ModeType check
+ 	    *     (LVDS can only be slave in 8bpp modes)
+ 	    */
+ 	   tempah = 0x80;
+@@ -3043,7 +3136,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+ 	} else {
+ 
+-	   /* TW: (added ModeType check) */
++	   /* (added ModeType check) */
+ 	   tempah = 0;
+ 	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+                	  tempah |= 0x02;
+@@ -3060,50 +3153,69 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 
+   }
+ 
+-  /* TW: Inserted the entire following section */
++  /* Inserted the entire following section */
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 
+ #ifdef SIS315H
++
++         unsigned char bridgerev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);;
++
++	 /* The following is nearly unpreditable and varies from machine
++	  * to machine. Especially the 301DH seems to be a real trouble
++	  * maker. Some BIOSes simply set the registers (like in the
++	  * NoLCD-if-statements here), some set them according to the
++	  * LCDA stuff. It is very likely that some machines are not
++	  * treated correctly in the following, very case-orientated
++	  * code. What do I do then...?
++	  */
++
++	 /* 740 variants match for 30xB, 301B-DH, 30xLV */
++
+          if(!(IS_SIS740)) {
+             tempah = 0x04;						   /* For all bridges */
+             tempbl = 0xfb;
+             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+                tempah = 0x00;
+-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
++	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ 	          tempbl = 0xff;
++	       }
+             }
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);   
+ 	 }
+-	 
+-	 if(IS_SIS740) {						
++
++	 /* The following two are responsible for eventually wrong colors
++	  * in TV output. The DH (VB_NoLCD) conditions are unknown; the
++	  * b0 was found in some 651 machine (Pim); the b1 version in a
++	  * 650 box (Jake). What is the criteria?
++	  */
++
++	 if(IS_SIS740) {
+ 	    tempah = 0x30;
+ 	    tempbl = 0xcf;
+ 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ 	       tempah = 0x00;
+ 	    }
+-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
++	 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
++	    /* Fixes "TV-blue-bug" on 315+301 */
++	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);          /* For 301   */
++	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
++	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xB-DH rev b0 (or "DH on 651"?) */
+ 	 } else {
+-	    /* TW: This in order to fix "TV-blue-bug" on 315+301 */
+-            if(SiS_Pr->SiS_VBType & VB_SIS301) {
+-	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);             /* For 301   */
+-	    } else {
+-	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
+-	       } else {
+-	          tempah = 0x30;					   /* For 301B  */
+-	          tempbl = 0xcf;
+-	          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+-	             tempah = 0x00;
+-		     if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+-		        tempbl = 0xff;
+-		     }
+-	          }
+-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
++	    tempah = 0x30;					     /* For 30xB (and 301BDH rev b1) */
++	    tempbl = 0xcf;
++	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
++	       tempah = 0x00;
++	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
++		  tempbl = 0xff;
+ 	       }
+ 	    }
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+ 	 }
+ 
+ 	 if(IS_SIS740) {
+@@ -3111,25 +3223,25 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+   	    tempbl = 0x3f;
+ 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ 	       tempah = 0x00;
+-	    } 
+-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
++	    }
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
++	 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xLV */
++	 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xB-DH rev b0 (or "DH on 651"? */
+ 	 } else {
+-	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* For 30xLV */
+-	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
+-	    } else {							/* For 301, 301B */ 
+-	        tempah = 0xc0;
+-	        tempbl = 0x3f;
+-	        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+-	           tempah = 0x00;
+-		   if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+-		      tempbl = 0xff;
+-		   }
+-	        }
+-	        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
++	    tempah = 0xc0;						/* For 301, 301B (and 301BDH rev b1) */
++	    tempbl = 0x3f;
++	    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
++	       tempah = 0x00;
++	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
++		  tempbl = 0xff;
++	       }
+ 	    }
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+ 	 }
+ 
+-	 if(IS_SIS740) {						
++	 if(IS_SIS740) {
+ 	    tempah = 0x80;
+ 	    tempbl = 0x7f;
+ 	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+@@ -3141,8 +3253,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+             tempbl = 0x7f;
+             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+                tempbl = 0xff;
+-	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
++	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+ 	          tempah |= 0x80;
++	       }
+             }
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+ 	 }
+@@ -3174,16 +3287,32 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr,
+ 	    tempbl = 0xfb;
+             if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+                tempah = 0x00;
+-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
++	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+ 	          tempbl = 0xff;
++	       }
+             }
+ 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+ 
+-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
++	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
++	    }
+ 
+ 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+ 
++	 } else if(HwDeviceExtension->jChipType == SIS_550) {
++
++#if 0
++	    tempah = 0x00;
++	    tempbl = 0xfb;
++	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
++	       tempah = 0x00;
++	       tempbl = 0xfb;
++	    }
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
++#endif
++	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
++
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+ 	 }
+ 
+       }
+@@ -3209,10 +3338,9 @@ SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCH
+ 	                      HwDeviceExtension);
+         } else {
+ 
+-	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+-	       (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+-	       
+-	      /* TW: Need LVDS Data for LCD on 301BDH */
++	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++
++	      /* Need LVDS Data for LCD on 301B-DH */
+ 	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ 	                          HwDeviceExtension);
+ 				  
+@@ -3282,18 +3410,16 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
+ 
+    } else {
+ 
+-      /* TW: 301BDH needs LVDS Data */
+-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++      /* 301BDH needs LVDS Data */
++      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+ 	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
+       }
+ 
+       SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex,HwDeviceExtension);
+ 
+-      /* TW: 301BDH needs LVDS Data */
+-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
++      /* 301BDH needs LVDS Data */
++      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+               SiS_Pr->SiS_IF_DEF_LVDS = 0;
+       }
+ 
+@@ -3321,11 +3447,18 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
+ 	case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
+ 	case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
+ 	case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
++	case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
++	case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
++	case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
++	case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
++	case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
++	case 84:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
++	case 85:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
+ 	case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
+       	case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
+       	case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
+       	case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
+-	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* TW: Super Overscan */
++	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* Super Overscan */
+ 	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+      }
+    }
+@@ -3337,67 +3470,36 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+-    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
+-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+-           SiS_Pr->SiS_HDE = 1024;
+-           SiS_Pr->SiS_VDE =  768;
+-         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
+-           SiS_Pr->SiS_HDE = 1280;
+-           SiS_Pr->SiS_VDE = 1024;
+-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
+-           SiS_Pr->SiS_HDE = 1400;
+-           SiS_Pr->SiS_VDE = 1050;
+-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
+-           SiS_Pr->SiS_HDE = 1600;
+-           SiS_Pr->SiS_VDE = 1200;
+-         } else {
+-	   SiS_Pr->SiS_HDE = 1280;
+-	   SiS_Pr->SiS_VDE =  960;
+-	 }
+-    }
++     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
++        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
++     }
+ 
+   } else {
+ 
+-    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+-      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+-          if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+-            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-              SiS_Pr->SiS_HDE =  800;
+-              SiS_Pr->SiS_VDE =  600;
+-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+-	      SiS_Pr->SiS_HDE = 1024;
+-              SiS_Pr->SiS_VDE =  600;  
+-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-              SiS_Pr->SiS_HDE = 1024;
+-              SiS_Pr->SiS_VDE =  768;
+- 	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+-	      SiS_Pr->SiS_HDE = 1152;
+-	      SiS_Pr->SiS_VDE =  768;	
+-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
+-	      SiS_Pr->SiS_HDE = 1152;
+-	      SiS_Pr->SiS_VDE =  864;  
+-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+-	      SiS_Pr->SiS_HDE = 1280;
+-	      SiS_Pr->SiS_VDE =  768;        
+-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-              SiS_Pr->SiS_HDE = 1280;
+-              SiS_Pr->SiS_VDE = 1024;
+-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-	      SiS_Pr->SiS_HDE = 1400;
+-              SiS_Pr->SiS_VDE = 1050;
+-	    } else {
+-	      SiS_Pr->SiS_HDE = 1600;
+-	      SiS_Pr->SiS_VDE = 1200;
+-	    }
+-            if(SiS_Pr->SiS_IF_DEF_FSTN) {
+-              SiS_Pr->SiS_HDE = 320;
+-              SiS_Pr->SiS_VDE = 480;
+-            }
+-          }
++     if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
++        if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
++           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
++              if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
++	         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
++                 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
++
++		 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++		    if(ResIndex < 0x08) {
++		       SiS_Pr->SiS_HDE = 1280;
++                       SiS_Pr->SiS_VDE = 1024;
++		    }
++		 }
++#if 0
++                 if(SiS_Pr->SiS_IF_DEF_FSTN) {
++                    SiS_Pr->SiS_HDE = 320;
++                    SiS_Pr->SiS_VDE = 480;
++                 }
++#endif
++              }
++           }
+         }
+-      }
+-    }
++     }
+   }
+ }
+ 
+@@ -3413,11 +3515,16 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
+   const SiS_TVDataStruct  *TVPtr  = NULL;
+ 
+   if(ModeNo <= 0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   } else {
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++	resinfo = 0;
++     } else {
+     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     }
+   }
+   
+   SiS_Pr->SiS_NewFlickerMode = 0;
+@@ -3429,17 +3536,26 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
+ 
+   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ 
+-  /* TW: For VGA2 ("RAMDAC2") */
+-
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+-     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+-                        HwDeviceExtension);
+-     return;
+-  }
+ 
+-  /* TW: For TV */
++     if(SiS_Pr->UseCustomMode) {
+ 
+-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        SiS_Pr->SiS_RVBHCMAX  = 1;
++        SiS_Pr->SiS_RVBHCFACT = 1;
++        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
++        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
++        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
++        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
++	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
++        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
++
++     } else {
++
++        SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++                           HwDeviceExtension);
++     }
++
++  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ 
+     SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                    &CRT2Index,&ResIndex,HwDeviceExtension);
+@@ -3452,7 +3568,7 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
+       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+-      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
++      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* Just to avoid a crash */
+     }
+ 
+     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
+@@ -3464,18 +3580,16 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
+     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
+     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+     if(modeflag & HalfDCLK) {
+-	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->HALFRVBHRS;
++	SiS_Pr->SiS_RVBHRS     = (TVPtr+ResIndex)->HALFRVBHRS;
+     }
+ 
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
+     
+        if(SiS_Pr->SiS_HiVision != 3) {
+-       
+-      	  if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
+-      	  if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
+-	  if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
+-	  
+-       } 
++      	  if(resinfo == SIS_RI_1024x768)  SiS_Pr->SiS_NewFlickerMode = 0x40;
++      	  if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40;
++	  if(resinfo == SIS_RI_1280x720)  SiS_Pr->SiS_NewFlickerMode = 0x40;
++       }
+        
+        switch(SiS_Pr->SiS_HiVision) {
+        case 2:
+@@ -3504,119 +3618,136 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr, 
+ 
+     } else {
+ 
+-      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+-      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+-      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+-      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+-
+-      if(modeflag & HalfDCLK) {
+-         SiS_Pr->SiS_RY1COE = 0x00;
+-         SiS_Pr->SiS_RY2COE = 0xf4;
+-         SiS_Pr->SiS_RY3COE = 0x10;
+-         SiS_Pr->SiS_RY4COE = 0x38;
+-      }
+-
+-      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-        SiS_Pr->SiS_HT = NTSCHT;
+-	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
+-	   if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+-	}  
+-        SiS_Pr->SiS_VT = NTSCVT;
+-      } else {
+-        SiS_Pr->SiS_HT = PALHT;
+-        SiS_Pr->SiS_VT = PALVT;
+-      }
++       SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
++       SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
++       SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
++       SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
++
++       if(modeflag & HalfDCLK) {
++          SiS_Pr->SiS_RY1COE = 0x00;
++          SiS_Pr->SiS_RY2COE = 0xf4;
++          SiS_Pr->SiS_RY3COE = 0x10;
++          SiS_Pr->SiS_RY4COE = 0x38;
++       }
++
++       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++          SiS_Pr->SiS_HT = NTSCHT;
++	  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++	     if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
++	  }
++          SiS_Pr->SiS_VT = NTSCVT;
++       } else {
++          SiS_Pr->SiS_HT = PALHT;
++          SiS_Pr->SiS_VT = PALVT;
++       }
+ 
+     }
+ 
+-    return;
+-  }
++  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ 
+-  /* TW: For LCD */
++     if(SiS_Pr->UseCustomMode) {
+ 
+-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++        SiS_Pr->SiS_RVBHCMAX  = 1;
++        SiS_Pr->SiS_RVBHCFACT = 1;
++        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
++        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
++        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
++        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
++	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
++        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
+ 
+-    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+-                   &CRT2Index,&ResIndex,HwDeviceExtension);
++     } else {
++
++        SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++                      &CRT2Index,&ResIndex,HwDeviceExtension);
++
++        switch(CRT2Index) {
++         case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
++         case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
++         case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
++         case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
++         case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
++         case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
++         case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
++         case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
++         case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
++         case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
++         case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
++         case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
++         case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
++         case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
++         case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
++         case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
++         case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
++         case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
++         case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;	          break; /* Generic no-scale data */
++#ifdef SIS315H
++	 case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data;	break;
++	 case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;			break;
++	 case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;	  		break;
++#endif
++         default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	  break; /* Just to avoid a crash */
++        }
++
++        SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
++        SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
++        SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
++        SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
++        SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
++        SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+ 
+-    switch (CRT2Index) {
+-      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
+-      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
+-      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
+-      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
+-      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
+-      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
+-      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
+-      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
+-      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
+-      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
+-      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
+-      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing (let panel scale) */
+-      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
+-      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
+-      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
+-      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
+-    }
+-
+-    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+-    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+-    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+-    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+-    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+-    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+-    
+ #ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO,
+-    	"GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+-#endif    
++        xf86DrvMsg(0, X_INFO,
++    	    "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
++#endif
+ 
+-    tempax = 1024;
+-    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+-      if(HwDeviceExtension->jChipType < SIS_315H) {
+-         if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+-         else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+-         else                               tempbx = 768;
+-      } else {      
+-         tempbx = 768; 
+-      }
+-    } else {
+-      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+-      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+-      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+-      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+-      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+-      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+-      else                               tempbx = 768;
+-    }
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-      tempax = 1280;
+-      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+-      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+-      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+-      else                               tempbx = 1024;
+-    }
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+-      tempax = 1280;
+-      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
+-      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
+-      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+-      else                                tempbx = 960;
+-    }
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-      tempax = 1400;
+-      tempbx = 1050;
+-    }
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+-      tempax = 1600;
+-      tempbx = 1200;
+-    }
+-    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-       tempax = SiS_Pr->SiS_VGAHDE;
+-       tempbx = SiS_Pr->SiS_VGAVDE;
+-    }
+-    SiS_Pr->SiS_HDE = tempax;
+-    SiS_Pr->SiS_VDE = tempbx;
+-    return;
++	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++           tempax = 1024;
++           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
++              if(HwDeviceExtension->jChipType < SIS_315H) {
++                 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
++                 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
++                 else                               tempbx = 768;
++              } else {
++                 tempbx = 768;
++              }
++           } else {
++              if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
++              else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
++              else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
++              else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
++              else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
++              else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
++              else                               tempbx = 768;
++           }
++	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++           tempax = 1280;
++           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
++           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
++           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
++           else                               tempbx = 1024;
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++           tempax = 1280;
++           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
++           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
++           else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
++           else                                tempbx = 960;
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++           tempax = 1600;
++           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
++           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
++           else                                tempbx = 1200;
++        } else {
++	   tempax = SiS_Pr->PanelXRes;
++           tempbx = SiS_Pr->PanelYRes;
++	}
++        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++           tempax = SiS_Pr->SiS_VGAHDE;
++           tempbx = SiS_Pr->SiS_VGAVDE;
++        }
++        SiS_Pr->SiS_HDE = tempax;
++        SiS_Pr->SiS_VDE = tempbx;
++     }
+   }
+ }
+ 
+@@ -3626,9 +3757,9 @@ SiS_GetResInfo(SiS_Private *SiS_Pr, UCHA
+   USHORT resindex;
+ 
+   if(ModeNo <= 0x13)
+-    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++     resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   else
+-    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ 
+   return(resindex);
+ }
+@@ -3639,41 +3770,46 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
+ {
+   USHORT xres,yres,modeflag=0,resindex;
+ 
++  if(SiS_Pr->UseCustomMode) {
++     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
++     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
++     return;
++  }
++
+   resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+ 
+   if(ModeNo <= 0x13) {
+-    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+-    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
++     xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
++     yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+   } else {
+-	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+-    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++     xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
++     yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
++     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+ 
+-  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+-      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+-          if(yres == 350) yres = 400;
+-      }
+-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+- 	  if(ModeNo == 0x12) yres = 400;
+-      }
+-  }
++  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
++
++     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
++        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
++           if(yres == 350) yres = 400;
++        }
++        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
++ 	   if(ModeNo == 0x12) yres = 400;
++        }
++     }
++
++     if(ModeNo > 0x13) {
++  	if(modeflag & HalfDCLK)       xres *= 2;
++  	if(modeflag & DoubleScanMode) yres *= 2;
++     }
+ 
+-  if(ModeNo > 0x13) {
+-      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
+-            xres *= 2;
+-            yres *= 2;
+-      } else {
+-  	    if(modeflag & HalfDCLK)       xres *= 2;
+-  	    if(modeflag & DoubleScanMode) yres *= 2;
+-      }
+   }
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+            if(xres == 720) xres = 640;
+ 	} else {
+-	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* TW: 301BDH */
++	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
+ 	        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                    if(xres == 720) xres = 640;
+ 		}
+@@ -3694,17 +3830,16 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
+ 	         if(xres == 720) xres = 640;
+ 	      }
+ 	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-		    if(ModeNo <= 0x13) {
+-		       /* TW: This is wrong for 640x400 *graphics* mode */
++		 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++		    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++		       /* BIOS bug - does this regardless of scaling */
+       		       if(yres == 400) yres = 405;
+ 		    }
+       		    if(yres == 350) yres = 360;
+       		    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+         	       if(yres == 360) yres = 375;
+       		    }
+-   	         }
+-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
++   	         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+       		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+         	       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+           	          if(yres == 350) yres = 357;
+@@ -3719,12 +3854,15 @@ SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, 
+   } else {
+     	if(xres == 720) xres = 640;
+ 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+-	      yres = 400;
+-	      if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+-	      } else {
+-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+-	      }
++	   yres = 400;
++	   if(HwDeviceExtension->jChipType >= SIS_315H) {
++	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
++	   } else {
++	      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
++	   }
++	   if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
++	      yres = 480;
++	   }
+ 	}
+   }
+   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+@@ -3739,6 +3877,13 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+   USHORT tempbx=0,tempal=0;
+   USHORT Flag,resinfo=0;
+ 
++  if(ModeNo <= 0x13) {
++     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++  } else {
++     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++  }
++
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
+@@ -3753,19 +3898,44 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+ 		        tempbx = 23;
+ 			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
+ 			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
++#if 0
++	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++		        tempbx = 26;
++			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 27;
++			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
++#endif
+ 		} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-			tempbx = 13;
+-			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
++			if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++			   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 13;
++			   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
++			   else 							 tempbx = 29;
++			} else {
++			   tempbx = 29;
++			   if(ModeNo >= 0x13) {
++			      /* 1280x768 and 1280x960 have same CRT2CRTC,
++			       * so we change it here if 1280x960 is chosen
++			       */
++			      if(resinfo == SIS_RI_1280x960) tempal = 10;
++			   }
++			}
+ 		} else {
+       		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
+       		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+         		tempbx += 5;
+                         /* GetRevisionID();  */
+-			/* TW: BIOS only adds 5 once */
++			/* BIOS only adds 5 once */
+         		tempbx += 5;
+        		   }
+ 	        }
+ 
++#ifdef SIS315H
++		if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++		   tempbx = 50;
++		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 51;
++		   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
++		}
++#endif
++
+      	} else {						  	/* TV */
+ 	
+        		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+@@ -3773,7 +3943,7 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+          		if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode);
+          		tempbx = 2;
+          		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-            			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12; 
++            			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12;
+          		}
+        		} else {
+          		if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
+@@ -3783,34 +3953,18 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+ 		
+      	}
+ 
+-     	if(ModeNo <= 0x13) {
+-       		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+-     	} else {
+-       		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+-		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+-        }
+-
+-     	tempal &= 0x3F;
+-
+-      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+-           (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
+-      		if(tempal == 0x06) tempal = 0x07;
+-        }
+-
+-	/* TW: 300/301LV BIOS */
+-	if((HwDeviceExtension->jChipType == SIS_300) &&
+-	   (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+-	    if(ModeNo > 0x13) {
+-	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 (index diff. on 310/325!) */
+-		    tempal = 6;
+-	    }
+-	}
++        tempal &= 0x3F;
+ 
+-	if(HwDeviceExtension->jChipType != SIS_300) {
+-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-              if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
++      	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
++	   if(ModeNo > 0x13) {
++      	      if(tempal == 6) tempal = 7;
++              if((resinfo == SIS_RI_720x480) ||
++	         (resinfo == SIS_RI_720x576) ||
++	         (resinfo == SIS_RI_768x576)) {
++		 tempal = 6;
++	      }
+ 	   }
+-	}
++        }
+ 
+      	*CRT2Index = tempbx;
+      	*ResIndex = tempal;
+@@ -3820,25 +3974,22 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+     	Flag = 1;
+     	tempbx = 0;
+     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-	
+-      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+-        		Flag = 0;
+-        		tempbx = 10;
+-			if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+-        		if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-				tempbx += 2;
+-				if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+-				if(SiS_Pr->SiS_CHPALM) {
+-					tempbx = 90;
+-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+-				} else if(SiS_Pr->SiS_CHPALN) {
+-					tempbx = 92;
+-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+-				}
+-				
+-			}
+-      		}
+-		
++      	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
++              Flag = 0;
++              tempbx = 10;
++	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++              if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++		 tempbx += 2;
++		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
++		 if(SiS_Pr->SiS_CHPALM) {
++		    tempbx = 90;
++		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++		 } else if(SiS_Pr->SiS_CHPALN) {
++		    tempbx = 92;
++		    if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
++	 	 }
++              }
++           }
+     	}
+ 
+     	if(Flag) {
+@@ -3846,11 +3997,19 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+ 		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+ 		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+    	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
++		   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++		      tempbx = 82;
++		      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
++		   }
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+ 		   tempbx = 18;
+ 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++; 
+-	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { 
++	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+ 		   tempbx = 6;
++		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
++		   tempbx = 30;
++		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++		   tempbx = 30;
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ 		   tempbx = 15;
+   		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
+@@ -3863,27 +4022,30 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+ 		   tempbx = 21;
+ 		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
++		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
++		   tempbx = 80;
++   	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+ 		}
+-		
++
+ 		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ 		   tempbx = 7;
+         	}
+-		
+-	}
+ 
+-    	if(ModeNo <= 0x13)
+-      		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+-    	else {
+-      		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+-		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++		if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++		   tempbx = 84;
++		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
++		}
++
+ 	}
+ 
++#if 0
+ 	if(SiS_Pr->SiS_IF_DEF_FSTN){
+        	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+          		tempbx = 14;
+          		tempal = 6;
+         	}
+     	}
++#endif
+ 
+ 	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+ 	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+@@ -3895,13 +4057,10 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHA
+ 
+ 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ 	    if(ModeNo > 0x13) {
+-	        if(HwDeviceExtension->jChipType < SIS_315H) {
+-	           if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
+-		       tempal = 6;
+-	        } else {
+-		   if((resinfo == 0x0d) || (resinfo == 0x0e))  /* 720 */
+-		       tempal = 6;
+-		}
++	       if((resinfo == SIS_RI_720x480) ||
++	          (resinfo == SIS_RI_720x576) ||
++		  (resinfo == SIS_RI_768x576))
++		  tempal = 6;
+ 	    }
+ 	}
+ 
+@@ -3940,7 +4099,7 @@ SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCH
+ void
+ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+ 		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+-		    USHORT *ResIndex)
++		    USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT tempbx,tempal;
+ 
+@@ -3954,6 +4113,16 @@ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
+   else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
+ 
++#ifdef SIS315H
++  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++        tempbx = 100;
++        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 101;
++  	else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
++     }
++  }
++#endif
++
+   *CRT2Index = tempbx;
+   *ResIndex = tempal & 0x3F;
+ }
+@@ -3962,15 +4131,17 @@ USHORT
+ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
+                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
++  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
+                                0x01, 0x01, 0x01, 0x01,
+ 			       0x01, 0x01, 0x01, 0x01,
+-			       0x01, 0x01, 0x01, 0x01 };
++			       0x01, 0x01, 0x01, 0x01,
++			       0x00, 0x00, 0x00, 0x00 };
+   USHORT RefreshRateTableIndex,i,backup_i;
+   USHORT modeflag,index,temp,backupindex;
+ 
+-  if(SiS_Pr->UseCustomMode) return 0;
+-  
++  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
++  if(ModeNo == 0xfe) return 0;
++
+   if(ModeNo <= 0x13)
+     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   else
+@@ -3984,7 +4155,7 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
+ 
+   if(ModeNo < 0x14) return(0xFFFF);
+ 
+- /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
++ /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
+   *     On LVDS machines, CRT2 index is always 0 and will be
+   *     set to 0 by the following code; this causes the function
+   *     to take the first non-interlaced mode in SiS_Ext2Struct
+@@ -3998,40 +4169,38 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
+   if(index > 0) index--;
+ 
+   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
+-      } else {
++     } else {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-	    if(SiS_Pr->SiS_VBType & VB_NoLCD)
+-	       	    index = 0;
+-	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
+-	    	    index = backupindex = 0;
++	   if(SiS_Pr->SiS_VBType & VB_NoLCD)
++	      index = 0;
++	   else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
++	      index = backupindex = 0;
+ 	}
+-      }
+-  }
++     }
+ 
+-  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+-    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-        		index = 0;
+-      		}
+-    	}
+-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+-      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-			if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+-           		   temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+-        		   if(index > temp) index = temp;
+-			}
+-      		} else {
+-        		index = 0;
+-      		}
+-    	}
++     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
++        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++           index = 0;
++        }
++     }
++     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++	   if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
++              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
++              if(index > temp) index = temp;
++	   }
++      	} else {
++           index = 0;
++      	}
++     }
+   }
+ 
+   RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+   ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
+ 
+-  /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
++  /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+         if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+@@ -4066,7 +4235,7 @@ SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, 
+     	backup_i = i;
+     	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+ 	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
+-		/* TW: This is for avoiding random data to be used; i is
++		/* This is for avoiding random data to be used; i is
+ 		 *     in an undefined state if no matching CRT2 mode is
+ 		 *     found.
+ 		 */
+@@ -4085,196 +4254,199 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
+   USHORT tempax,tempbx,resinfo;
+   USHORT modeflag,infoflag;
+ 
+-  if (ModeNo <= 0x13)
++  if(ModeNo <= 0x13) {
+     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-  else
++	resinfo = 0;
++  } else {
+     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++        resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++  }
+ 
+-  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ 
+   tempax = 0;
++
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+       		tempax |= SupportRAMDAC2;
+ 		if(HwDeviceExtension->jChipType >= SIS_315H) {
+-		    tempax |= SupportTV;
+-		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-			    if(resinfo == 0x0a) tempax |= SupportTV1024;
+-			}
+-		    }
++		   tempax |= SupportTV;
++		   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++		      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++			 if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024;
++		      }
++		   }
+ 		}
+-    	}
+-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+       		tempax |= SupportLCD;
+ 		if(HwDeviceExtension->jChipType >= SIS_315H) {
+                    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+ 		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+-		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++		         if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ 			    (*i) = 0;
+                             return(1);
+ 		         } else {
+       		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+-        		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+-           			if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+-				    return(0);
+-				} else {
+-             			    if((resinfo >= 9) && (resinfo != 0x14)) {
++        		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
++           			  if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
++				     return(0);
++				  } else {
++             			     if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) {
+                				return(0);
+-             			    }
+-           			}
+-        		      }
++             			     }
++           			  }
++        		       }
+ 		            }
+ 		         }
+ 		      }
+       		   }
+ 		} else {
+ 		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+-		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
++		     if( (resinfo != SIS_RI_1024x600) &&
++		         ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+-		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
++		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+-		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
++		     if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-		     if(resinfo > 9) return(0);
++		     if(resinfo > SIS_RI_1280x1024) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-		     if(resinfo > 8) return(0);
++		     if(resinfo > SIS_RI_1024x768) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-		     if((resinfo == 4) || (resinfo > 7)) return(0);
++		     if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0);
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+-		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
++		     if((resinfo == SIS_RI_512x384) ||
++		        (resinfo == SIS_RI_400x300) ||
++			(resinfo > SIS_RI_640x480)) return(0);
+ 		  }
+ 		}
+-    	}
+-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { 
++    	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+ 	        if(SiS_Pr->SiS_HiVision == 3) {
+ 		      	tempax |= SupportHiVisionTV2;
+       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+-        			if(resinfo == 4) return(0);
+-        			if(resinfo == 3) return(0);
+-				if(resinfo == 7) {
++        			if(resinfo == SIS_RI_512x384) return(0);
++        			if(resinfo == SIS_RI_400x300) return(0);
++				if(resinfo == SIS_RI_800x600) {
+ 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+         			}
+-        			if(resinfo > 7) return(0);
++        			if(resinfo > SIS_RI_800x600) return(0);
+ 			}
+ 		} else {  
+       			tempax |= SupportHiVisionTV;
+       			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+-        			if(resinfo == 4) return(0);
+-        			if((resinfo == 3) || (resinfo == 7)) {
++        			if(resinfo == SIS_RI_512x384) return(0);
++        			if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) {
+ 	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+         			}
+-        			if(resinfo > 7) return(0);
++        			if(resinfo > SIS_RI_800x600) return(0);
+ 			}
+ 		}
+-    	} else {
+-      	   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
++    	} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+         	tempax |= SupportTV;
+ 		tempax |= SupportTV1024;
+ 		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-			     if(resinfo != 8) {
+-			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
+-				     tempax &= ~(SupportTV1024);
+-				     if(HwDeviceExtension->jChipType >= SIS_315H) {
+-                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+-			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+-		                             }
+-				         }
+-		                     } else {
+-				         if( (resinfo != 3) ||
+-					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+-					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-						     if(resinfo == 3) return(0);
+-						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+-						 }
+-		                             }
+-                                         } else return(0);
+-				     }
+-				 }
+-			     }
+-			} else {
+-			    tempax &= ~(SupportTV1024);
+-			    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
++		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++		      if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
++		         if(resinfo != SIS_RI_1024x768) {
++			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) {
++			       tempax &= ~(SupportTV1024);
++			       if(HwDeviceExtension->jChipType >= SIS_315H) {
++                                  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++			             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++			                 ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+ 			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+-		                    }
+-		                }
+-			    } else {
+-			        if( (resinfo != 3) ||
+-				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+-				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-					     if(resinfo == 3) return(0);
+-					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+-					 }
+ 		                     }
+-                                } else return(0);
+-                            }
+-			}
+-		    } else {  /* slavemode */
+-			if(resinfo != 8) {
+-			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
+-				 tempax &= ~(SupportTV1024);
+-				 if(HwDeviceExtension->jChipType >= SIS_315H) {
+-				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+-			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
+-		                         }
++				  }
++		               } else {
++				  if( (resinfo != SIS_RI_400x300) ||
++				      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++				      (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++					if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++					   if(resinfo == SIS_RI_400x300) return(0);
++					   if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
++					}
+ 		                     }
+-			        } else {
+-				    if( (resinfo != 3) ||
+-				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+-				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-					         if(resinfo == 3) return(0);
+-					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+-					     }
+-		                         }
+-                                    } else return(0);
+-				}
++                                  } else return(0);
++			       }
+ 			    }
+-			}
+-		    }
+-		} else {   /* 301 */
+-		    tempax &= ~(SupportTV1024);
+-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+-			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+-		            }
+-		        }
+-		    } else {
+-		        if( (resinfo != 3) ||
+-			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+-			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-				    if(resinfo == 3) return(0);
+-				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+-				}
++			 }
++		      } else {
++			 tempax &= ~(SupportTV1024);
++			 if(HwDeviceExtension->jChipType >= SIS_315H) {
++			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++			       if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++			           ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++			          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++		               }
+ 		            }
+-                        } else return(0);
+-		    }
+-		}
+-           }
+-    	}
+-	
+-  } else {	/* TW: for LVDS  */
++			 } else {
++			    if( (resinfo != SIS_RI_400x300) ||
++			        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++				(SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++			       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++				  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++				     if(resinfo == SIS_RI_400x300) return(0);
++				     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++				  }
++		               }
++                            } else return(0);
++                         }
++		      }
++		   } else {  /* slavemode */
++		      if(resinfo != SIS_RI_1024x768) {
++			 if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++			     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
++			    tempax &= ~(SupportTV1024);
++			    if(HwDeviceExtension->jChipType >= SIS_315H) {
++			       if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++			          if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++			              ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++			             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
++		                  }
++		               }
++			    } else {
++			       if( (resinfo != SIS_RI_400x300) ||
++			           (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++			           (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++			          if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++				        if(resinfo == SIS_RI_400x300) return(0);
++				        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++				     }
++		                  }
++                               } else return(0);
++			    }
++		  	 }
++		      }
++		   }
++	        } else {   /* 301 */
++		   tempax &= ~(SupportTV1024);
++		   if(HwDeviceExtension->jChipType >= SIS_315H) {
++		      if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++		         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
++		             ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
++		            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
++		         }
++		      }
++		   } else {
++		      if( (resinfo != SIS_RI_400x300) ||
++			  (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++			  (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
++		         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++			    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++			       if(resinfo == SIS_RI_400x300) return(0);
++			       if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
++			    }
++		         }
++                      } else return(0);
++		   }
++	        }
++        }
++
++  } else {	/* for LVDS  */
+ 
+     	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+       		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+@@ -4284,24 +4456,33 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       		tempax |= SupportLCD;
+ 		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+-		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
++		     if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0);
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+-		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
++		     if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768))  return(0);
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+-		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
++		     if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768))   return(0);
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
++		     if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0);
++		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++                     if(resinfo > SIS_RI_1600x1200) return(0);
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-                     if(resinfo > 0x09) return(0);
++                     if(resinfo > SIS_RI_1280x1024) return(0);
+                 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-		     if(resinfo > 0x08) return(0);
++		     if(resinfo > SIS_RI_1024x768)  return(0);
+ 		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
+-		     if(resinfo > 0x07) return(0);
+-		     if(resinfo == 0x04) return(0);
++		     if(resinfo > SIS_RI_800x600)   return(0);
++		     if(resinfo == SIS_RI_512x384)  return(0);
++		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
++                     if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0);
++		}  else if(SiS_Pr->SiS_LCDResInfo == Panel_848x480) {
++                     if((resinfo != SIS_RI_1360x768) &&
++		        (resinfo != SIS_RI_848x480)  &&
++		        (resinfo > SIS_RI_1024x768)) return(0);
+ 		}
+     	}
+   }
+-  /* TW: Look backwards in table for matching CRT2 mode */
++
++  /* Look backwards in table for matching CRT2 mode */
+   for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+      	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+      	if(infoflag & tempax) {
+@@ -4309,7 +4490,7 @@ SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, 
+      	}
+      	if ((*i) == 0) break;
+   }
+-  /* TW: Look through the whole mode-section of the table from the beginning
++  /* Look through the whole mode-section of the table from the beginning
+    *     for a matching CRT2 mode if no mode was found yet.
+    */
+   for((*i) = 0; ; (*i)++) {
+@@ -4329,7 +4510,7 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, US
+ {
+   USHORT temp1,temp2;
+ 
+-  /* TW: We store CRT1 ModeNo in CR34 */
++  /* We store CRT1 ModeNo in CR34 */
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+   temp2 = ~(SetInSlaveMode >> 8);
+@@ -4345,16 +4526,16 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+   USHORT modeflag, resinfo=0;
+   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+ 
+-  if(SiS_Pr->UseCustomMode) {
+-        modeflag = SiS_Pr->CModeFlag;
++  if(ModeNo <= 0x13) {
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+-    if (ModeNo <= 0x13)
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-    else {
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++     } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+-    }
+-  }    
++     }
++  }
+ 
+   SiS_Pr->SiS_SetFlag = 0;
+ 
+@@ -4364,22 +4545,24 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+   if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {  
+     	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+ #if 0	
+-	/* SiS_HiVision is only used on 310/325/330+30xLV */
++	/* SiS_HiVision is only used on 315/330+30xLV */
+ 	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
+-	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/30xLV 1.10.6s */
++	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* New from 650/30xLV 1.10.6s */
+ 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
+ 	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
+ 	   }
+-	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/30xLV 1.10.6s */
++	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* New from 650/30xLV 1.10.6s */
+ 	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
+ 	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
+ 	   }
+ 	}
+-#endif	
++#endif
++#if 0
+     	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
+        		temp = (SetCRT2ToLCD | SetSimuScanMode);
+        		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
+     	}
++#endif
+     	tempbx |= temp;
+     	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
+         tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
+@@ -4519,7 +4702,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+       		tempbx |= SetSimuScanMode;
+     	}
+ 
+-	/* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
++	/* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
+ 	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ 	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ 	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+@@ -4527,12 +4710,12 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+ 	   }
+ 	}
+ 	
+-    	if(!(tempbx & SetSimuScanMode)){
++    	if(!(tempbx & SetSimuScanMode)) {
+       	    if(tempbx & SwitchToCRT2) {
+         	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ 		     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ 			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+-			 if(resinfo != 0x0a)
++			 if(resinfo != SIS_RI_1600x1200)
+                               tempbx |= SetSimuScanMode;
+ 		     } else {
+             		      tempbx |= SetSimuScanMode;
+@@ -4555,7 +4738,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+           	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ 	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+ 			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+-			     if(resinfo != 0x0a) {  /* TW: 650/301 BIOS */
++			     if(resinfo != SIS_RI_1600x1200) {  /* 650/301 BIOS */
+ 			          tempbx |= SetInSlaveMode;
+             		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+               		 	     if(tempbx & SetCRT2ToTV) {
+@@ -4563,7 +4746,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+ 					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
+               			     }
+                                   }
+-			     }                      /* TW: 650/301 BIOS */
++			     }                      /* 650/301 BIOS */
+ 		        } else {
+             		    tempbx |= SetInSlaveMode;
+             		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+@@ -4621,7 +4804,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+      	if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ 		    OutputSelect = ROMAddr[0xf3];
+-		    if(HwDeviceExtension->jChipType == SIS_330) {
++		    if(HwDeviceExtension->jChipType >= SIS_330) {
+ 			OutputSelect = ROMAddr[0x11b];
+ 		    }
+                 }
+@@ -4652,7 +4835,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+   SiS_Pr->SiS_VBInfo = tempbx;
+ 
+   if(HwDeviceExtension->jChipType == SIS_630) {
+-       SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
++       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+   }
+ 
+ #ifdef TWDEBUG
+@@ -4666,61 +4849,35 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHOR
+ #endif
+ #endif
+ 
+-#if 0  /* TW: Incomplete! (But does not seem to be required) */
+-  if(HwDeviceExtension->jChipType < SIS_315H) {
+-     /* TW: From A901/630+301B BIOS */
+-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+-     }
+-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+-	     if( [si] == 3) ModeIdIndex = 0x3f2b;
+-	 }
+-     }
+-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+-     if(ModeNo == 0x13) bp+4 = 0x03;
+-  } else {
+-     /* From 650/30xLV BIOS: */
+-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+-     if(ModeNo == 0x13) bp+4 = 0x03;
+-     else bp+4 = ModeNo;
+-  }
+-#endif
+-
+-  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
+-
+ }
+ 
++/* Setup general purpose IO for Chrontel communication */
+ void
+-SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
++SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
+ {
+-   unsigned long eax, temp;
+-   unsigned short temp1;
++   unsigned long  acpibase;
++   unsigned short temp;
+ 
+    if(!(SiS_Pr->SiS_ChSW)) return;
+ 
+ #ifndef LINUX_XF86
+-   SiS_SetReg4(0xcf8,0x80000874);
+-   eax = SiS_GetReg3(0xcfc);
++   SiS_SetReg4(0xcf8,0x80000874);		   /* get ACPI base */
++   acpibase = SiS_GetReg3(0xcfc);
+ #else
+-   eax = pciReadLong(0x00000800, 0x74);
++   acpibase = pciReadLong(0x00000800, 0x74);
+ #endif
+-   eax &= 0xFFFF;
+-   temp = eax;
+-   eax += 0x3c;
+-   temp1 = SiS_GetReg4((USHORT)eax);
+-   temp1 &= 0xFEFF;
+-   SiS_SetReg5((USHORT)eax, temp1);
+-   temp1 = SiS_GetReg4((USHORT)eax);
+-   eax = temp;
+-   eax += 0x3a;
+-   temp1 = SiS_GetReg4((USHORT)eax);
+-   temp1 &= 0xFEFF;
++   acpibase &= 0xFFFF;
++   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
++   temp &= 0xFEFF;
++   SiS_SetReg5((USHORT)(acpibase + 0x3c), temp);
++   temp = SiS_GetReg4((USHORT)(acpibase + 0x3c));
++   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
++   temp &= 0xFEFF;
+    if(!(myvbinfo & SetCRT2ToTV)) {
+-      temp1 |= 0x0100;
++      temp |= 0x0100;
+    }
+-   SiS_SetReg5((USHORT)eax, temp1);
+-   temp1 = SiS_GetReg4((USHORT)eax);
++   SiS_SetReg5((USHORT)(acpibase + 0x3a), temp);
++   temp = SiS_GetReg4((USHORT)(acpibase + 0x3a));
+ }
+ 
+ void
+@@ -4731,14 +4888,14 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
+   USHORT temp1=0,modeflag=0,tempcx=0;
+   USHORT StandTableIndex,CRT1Index;
+ #ifdef SIS315H   
+-  USHORT ResInfo,DisplayType,temp=0;
++  USHORT ResIndex,DisplayType,temp=0;
+   const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+ #endif
+ 
+   SiS_Pr->SiS_RVBHCMAX  = 1;
+   SiS_Pr->SiS_RVBHCFACT = 1;
+ 
+-  if(ModeNo <= 0x13){
++  if(ModeNo <= 0x13) {
+ 
+     	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+@@ -4752,7 +4909,7 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
+ 
+ #ifdef SIS315H     
+     	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-			RefreshRateTableIndex,&ResInfo,&DisplayType);
++			RefreshRateTableIndex,&ResIndex,&DisplayType);
+ 
+     	if(temp == 0)  return;
+ 
+@@ -4795,16 +4952,16 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
+ 		case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
+ 		default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
+     	}
+-	tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
+-	tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
++	tempax = (LVDSCRT1Ptr+ResIndex)->CR[0];
++	tempax |= (LVDSCRT1Ptr+ResIndex)->CR[14] << 8;
+ 	tempax &= 0x03FF;
+-    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
+-    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
++    	tempbx = (LVDSCRT1Ptr+ResIndex)->CR[6];
++    	tempcx = (LVDSCRT1Ptr+ResIndex)->CR[13] << 8;
+     	tempcx &= 0x0100;
+     	tempcx <<= 2;
+     	tempbx |= tempcx;
+-	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
+-#endif	
++	temp1  = (LVDSCRT1Ptr+ResIndex)->CR[7];
++#endif
+ 
+     } else {
+ 
+@@ -4840,11 +4997,12 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, 
+   if(modeflag & Charx8Dot) tempax *= 8;
+   else                     tempax *= 9;
+ 
+-  /* TW: From 650/30xLV 1.10.6s */
++  /* From 650/30xLV 1.10.6s */
+   if(modeflag & HalfDCLK)  tempax <<= 1;
+ 
+-  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+   tempbx++;
++
++  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+   SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
+ }
+ 
+@@ -4852,18 +5010,18 @@ void
+ SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+   if(HwDeviceExtension->jChipType >= SIS_315H)
+-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
++     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+   else
+-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
++     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+ }
+ 
+ void
+ SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+   if(HwDeviceExtension->jChipType >= SIS_315H)
+-    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
++     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+   else
+-     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
++     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
+ }
+ 
+ void
+@@ -4872,7 +5030,6 @@ SiS_EnableCRT2(SiS_Private *SiS_Pr)
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ }
+ 
+-/* Checked against all BIOSes */
+ void
+ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+@@ -4882,9 +5039,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+   USHORT temp=0;
+   UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ 
+-  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
++      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
+ 
+         if(HwDeviceExtension->jChipType < SIS_315H) {
+ 
+@@ -4940,9 +5097,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+         } else {
+ 
+-#ifdef SIS315H	   /* 310/325 series */
++#ifdef SIS315H	   /* 315 series */
+ 
+-           if(IS_SIS650740) {		/* 650, 740 */
++           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
+ 
+ #if 0
+ 	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
+@@ -4950,40 +5107,67 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	      modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+ 
+-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* LV */
+ 	      
+ 	         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ 		 
+ 		 if( (modenum <= 0x13) ||
+ 		     (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+ 		     (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+-	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
++	     	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
++		      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++		         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++		      }
+ 	         }
+-		 SiS_DDC2Delay(SiS_Pr,0xff00);
+-		 SiS_DDC2Delay(SiS_Pr,0x6000);
+-		 SiS_DDC2Delay(SiS_Pr,0x8000);
+ 
+-	         SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++		 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++		    SiS_DDC2Delay(SiS_Pr,0xff00);
++		    SiS_DDC2Delay(SiS_Pr,0x6000);
++		    SiS_DDC2Delay(SiS_Pr,0x8000);
+ 
+-                 pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-		 
+-		 if(IS_SIS740) {
+-		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++	            SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++
++                    pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
++
++		    if(IS_SIS740) {
++		       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++		    }
++
++	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++
++		    if(!(IS_SIS740)) {
++		       if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	                  tempah = 0xef;
++	                  if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	                     tempah = 0xf7;
++                          }
++	                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		       }
++	            }
+ 		 }
+ 
+-	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-		 
+-		 if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	            tempah = 0xef;
+-	            if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	               tempah = 0xf7;
+-                    }
+-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+-	         }
++              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* B-DH */
++	         /* This is actually bullshit. The B-DH bridge has cetainly no
++		  * Part4 Index 26, since it has no ability to drive LCD panels
++		  * at all. But as the BIOS does it, we do it, too...
++		  */
++	         if(HwDeviceExtension->jChipType == SIS_650) {
++	            if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
++	            }
++		    if((!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++		       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
++	     	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
++	            }
++		    SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 3);
++		 }
++	      }
+ 
+-              }
++	      if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
++	      }
+ 
+-              if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++              if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 	         tempah = 0x3f;
+ 	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ 	            tempah = 0x7f;
+@@ -4997,7 +5181,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+               if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ 	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+ 
+-	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 		    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+ 		    SiS_DisplayOff(SiS_Pr);
+ 		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+@@ -5020,7 +5204,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	      } else {
+ 
+-	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 		    if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 		       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+ 		       SiS_DisplayOff(SiS_Pr);
+@@ -5044,10 +5228,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	      }
+ 
+-	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++	      if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280)) {
++
++		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    		/* 1.10.8r, 8m */
+ 
+-		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    /* 1.10.8r */
+-		 
+ 	         tempah = 0x3f;
+ 	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ 	            tempah = 0x7f;
+@@ -5057,9 +5241,9 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 	         }
+ 	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ 
+-		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r */
++		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r, 8m */
+ 	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+-		 }								/* 1.10.8r */
++		 }								/* 1.10.8r, 8m */
+ 
+ 	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+@@ -5075,80 +5259,47 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+ 
+-  	      }
++  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ 
+-#if 0
+-          } else if(IS_SIS740) {	/* 740 */
+-	  
+-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* 30xLV */
+-	     
+-	        if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+-		    (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+-	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+-	        }
+-		
+-		SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++	         if(HwDeviceExtension->jChipType == SIS_650) {
++		    if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++		       (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
++		       if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++		          (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
++			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
++	     	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
++			  SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
++	               }
++		    }
++		 }
+ 
+-                pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-		
+-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++	      } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 
+-	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-		
+-		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-		   SiS_DisplayOff(SiS_Pr);
+-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+-	           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+-		} else {
+-		   SiS_DisplayOff(SiS_Pr);
+-	           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+-	           temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+-                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+-	           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+-		}
+-		
+-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF);  /* (from 650) */
+-		
+-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+-		
+-		if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+-	        }
+-		
+-		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-		   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	              if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+-	                 if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-		            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+-                         }
+-                      }
+-	           }
+-		}
+-	        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+-	     
+-	     } else {	/* (301,) 301B */
+-	  
+-	        if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+-	           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+-	        }
+-	     
+-	        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+-	        SiS_DisplayOff(SiS_Pr);
+-	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
++	         if(HwDeviceExtension->jChipType == SIS_650) {
++		    if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	               tempah = 0xef;
++	               if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++		          if(modenum > 0x13) {
++	                     tempah = 0xf7;
++			  }
++                       }
++	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		    }
++		    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++		       if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++		          (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)))) {
++		          if((!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
++		             (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)))) {
++			     SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 2);
++	     	             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
++			     SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 4);
++	                  }
++		       }
++		    }
++		 }
++
++	      }
+ 
+-	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+-		
+-	     }
+-#endif	  
+ 	  } else {			/* 315, 330 - all bridge types */
+ 
+ 	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+@@ -5193,13 +5344,13 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	}
+ 
+-      } else {     /* ============ TW: For 301 ================ */
++      } else {     /* ============ For 301 ================ */
+ 
+         if(HwDeviceExtension->jChipType < SIS_315H) {
+-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+-	    }
++            if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
++	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++	   }
+ 	}
+ 
+         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
+@@ -5218,18 +5369,23 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+ 	} else {
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
++	    if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
++	        (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
++		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
++		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
++	    }
+ 	}
+ 
+       }
+ 
+-  } else {     /* ============ TW: For LVDS =============*/
++  } else {     /* ============ For LVDS =============*/
+ 
+     if(HwDeviceExtension->jChipType < SIS_315H) {
+ 
+ #ifdef SIS300	/* 300 series */
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+-	    SiS_SetCH700x(SiS_Pr,0x090E);
++	   SiS_SetCH700x(SiS_Pr,0x090E);
+ 	}
+ 
+ 	if(HwDeviceExtension->jChipType == SIS_730) {
+@@ -5245,17 +5401,17 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+   
+-  	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+ 
+-                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+ 
+-		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+-		         SiS_DisplayOff(SiS_Pr);
+-	             }
++		    if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
++		        SiS_DisplayOff(SiS_Pr);
++	            }
+ 
+-	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+-	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-                  }
++	            SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
++	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++                 }
+               }
+ 	   }
+ 	}
+@@ -5279,29 +5435,40 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+     } else {
+ 
+-#ifdef SIS315H	/* 310/325 series */
++#ifdef SIS315H	/* 315 series */
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+-		temp = SiS_GetCH701x(SiS_Pr,0x61);
+-		if(temp < 1) {
+-		   SiS_SetCH701x(SiS_Pr,0xac76);
+-		   SiS_SetCH701x(SiS_Pr,0x0066);
+-		}
+-		
+-		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++
++		if(HwDeviceExtension->jChipType == SIS_740) {
++		   temp = SiS_GetCH701x(SiS_Pr,0x61);
++		   if(temp < 1) {
++		      SiS_SetCH701x(SiS_Pr,0xac76);
++		      SiS_SetCH701x(SiS_Pr,0x0066);
++		   }
++
++		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 			SiS_SetCH701x(SiS_Pr,0x3e49);
+-		} else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
++		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+ 			SiS_SetCH701x(SiS_Pr,0x3e49);
++		   }
+ 		}
+-		
++
+ 		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 			SiS_Chrontel701xBLOff(SiS_Pr);
+-			SiS_Chrontel701xOff(SiS_Pr);
++			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
+ 		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+ 			SiS_Chrontel701xBLOff(SiS_Pr);
+-			SiS_Chrontel701xOff(SiS_Pr);
++			SiS_Chrontel701xOff(SiS_Pr,HwDeviceExtension);
+ 		}
+-		
++
++		if(HwDeviceExtension->jChipType != SIS_740) {
++		   if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++			SiS_SetCH701x(SiS_Pr,0x0149);
++		   } else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
++			SiS_SetCH701x(SiS_Pr,0x0149);
++		   }
++		}
++
+ 	}
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+@@ -5325,6 +5492,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ 	}
+ 
++	if(HwDeviceExtension->jChipType == SIS_740) {
++	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
++	}
++
+ 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+@@ -5337,15 +5508,27 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ 	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++		   if(HwDeviceExtension->jChipType == SIS_550) {
++		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
++		      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
++		   }
++		}
++	} else {
++	   if(HwDeviceExtension->jChipType == SIS_740) {
++	        if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+ 		}
+-	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++	   } else {
++	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++		   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
++	        }
++	   }
+ 	}
+ 
+ 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ 	    	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
++			/* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
+ 		} else {
+ 			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+ 		}
+@@ -5353,7 +5536,10 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ 	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+ 
+-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
++	if(HwDeviceExtension->jChipType == SIS_550) {
++	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
++		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
++	} else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ 	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+@@ -5361,7 +5547,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+ 	}
+ 
+-#if 0  /* TW: BIOS code makes no sense */
++#if 0  /* BIOS code makes no sense */
+        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+            if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 	        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -5387,7 +5573,6 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, P
+ 
+ }
+ 
+-/* TW: Checked against all BIOSes */
+ void
+ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+@@ -5400,7 +5585,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+ 
+-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
++    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
+ 
+       if(HwDeviceExtension->jChipType < SIS_315H) {
+ 
+@@ -5497,48 +5682,95 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 
+       } else {
+ 
+-#ifdef SIS315H    /* 310/325 series */
++#ifdef SIS315H    /* 315 series */
+ 
+-	 if(IS_SIS650740) {		/* 650 */
++	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
+ 
+ #if 0
+ 	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
+ #endif
+ 
+ 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	    
+-	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);  /* 1.10.7u */
+-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);    /* 1.10.7u */
++
++	       if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);  /* 1.10.7u */
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);    /* 1.10.7u */
++	       }
+ 
+ 	       if(!(IS_SIS740)) {
+                   if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 	             tempah = 0x10;
+-	             if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	                tempah = 0x08;
+-                     }
+-	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++		        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
++			   if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
++			      tempah = 0x08;
++			   } else {
++			      tempah = 0x18;
++			   }
++			}
++			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		     } else {
++	                if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	                   tempah = 0x08;
++                        }
++			SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		     }
+ 	          }
+ 	       }
+ 
+-	       SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+-	       SiS_DisplayOff(SiS_Pr);
+-	       pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-	       if(IS_SIS740) {
+-	          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++	       if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++	          SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
++	          SiS_DisplayOff(SiS_Pr);
++	          pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
++	          if(IS_SIS740) {
++	             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
++	          }
+ 	       }
+ 
+ 	       if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ 	           (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+-                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+-		      SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+-		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+-	              SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+-	           }
++                  if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
++		     if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++		        SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
++		     }
++		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
++	             SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
++	          }
++	       }
++
++               if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++	          if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
++                     SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++		     delaylong = TRUE;
++		  }
++	       }
++
++	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
++
++	       if(HwDeviceExtension->jChipType == SIS_650) {
++	          if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
++	          }
++		  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++		      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
++		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
++		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
++		  }
+ 	       }
+ 
+-	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+-                  SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+-		  delaylong = TRUE;
++  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++
++	       if(HwDeviceExtension->jChipType == SIS_650) {
++		  if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	             tempah = 0x10;
++		     if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
++		        tempah = 0x18;
++		        if((SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
++			   tempah = 0x08;
++			}
++		     }
++	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
++		  }
+ 	       }
+ 
+ 	    }
+@@ -5547,13 +5779,17 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+                temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ 	       if(SiS_BridgeInSlave(SiS_Pr)) {
+                   tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+-                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
++                  if(!(tempah & SetCRT2ToRAMDAC)) {
++		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++		        if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x13) & 0x04)) temp |= 0x20;
++		     } else temp |= 0x20;
++		  }
+                }
+                SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ 
+ 	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+ 	       
+-	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++	       if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ 		  temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ 		  if(!(temp & 0x80)) {
+@@ -5565,12 +5801,12 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 	    }
+ 
+ 	    if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
++	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ 	    }
+ 
+ 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+ 
+-	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) || (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280)) {
+ 	       temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+ 	       if(!(temp & 0x80)) {
+ 		  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+@@ -5586,7 +5822,9 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 	    }
+             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ 
+-	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
++	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
++	       ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
++	        (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))))) {
+                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ 	    }
+ 
+@@ -5595,186 +5833,144 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);	/* All this from 1.10.7u */
+ 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+ 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);  
+-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);  
+-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);  
+-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
+-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+-	       
+-	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+-	    
++
++	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++
++		  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x08);
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x10);
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x4d);
++		  if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x02) {
++		     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
++	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
++	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
++		  }
++		  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++
++	       } else {
++
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x12);
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0xd0);
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x6b);
++	          if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) {   /* @@@@ really == ? */
++	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x0d);
++	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x70);
++	             SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x40);
++		     if(((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x03)) {
++		        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);
++	                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);
++	                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x33);  /* 00 */
++		     }
++	          }
++	          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++	          if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
++	             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
++	          }
++	       }
++
++	       if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
++	          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
++	       }
++
+ 	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);  /* 1.10.8r */
+ 
+-	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
++	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+ 
+-	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+ 	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
+-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+-		    if(delaylong) {
+-			SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+-		    }
+-                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+-	         }
+-	      }
++		     SiS_DisplayOn(SiS_Pr);
++		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++		     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++		     SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
++	             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
++		     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++		        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
++	  	     }
++		  }
+ 
+-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+-	      SiS_DisplayOn(SiS_Pr);
+-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
++	       } else {
+ 
+-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+-	      }
+-#if 0
+-              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
+-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
+-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
+-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+-#endif	      
++	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+ 
+-	  }
++	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	             if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++	                 ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
++		        SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++		        if(delaylong) {
++			   SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
++		        }
++                        SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++		        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
++	             }
++	          }
+ 
+-#if 0
+-         } else if(IS_SIS740) {		/* 740 */
+-	 
+-	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* 30xLV */
+-	   
+-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+-	      SiS_DisplayOff(SiS_Pr);
+-	      pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+-	      
+-	      if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+-	          (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+-                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+-		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+-	              SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+-		   }
+-	      }
+-	      
+-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+-	         if(SiS_BridgeInSlave(SiS_Pr)) {
+-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+-                 }
+-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++	          SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
++	          SiS_DisplayOn(SiS_Pr);
++	          SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+ 
+-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);  	
+-		 SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+-	      }
+-	      
+-	      if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+-	      }
+-	      
+-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10);  /* (taken from 650 1.10.8r) */
+-	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+-	      
+-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	         if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+-	             (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+-		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+-		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+-		    }
+-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+-		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+-	         }
+-              }
+-	      
+-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+-	      SiS_DisplayOn(SiS_Pr);
+-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+-	      
+-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+-	      }
+-	   
+-	   } else {	/* (301), 301B */
+-	 
+-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+-	         if(SiS_BridgeInSlave(SiS_Pr)) {
+-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+-                 }
+-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
++	          }
+ 
+-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
++	       }
+ 
+-	         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+-                 if(!(temp & 0x80))
+-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+-              }
++	    } if(SiS_Pr->SiS_VBType & VB_NoLCD) {
++
++	       if(HwDeviceExtension->jChipType == SIS_650) {
++	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++		     if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
++		         (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
++			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
++		     }
++		  }
++	       }
+ 
+-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
++  	    }
+ 
+-	      if(SiS_Is301B(SiS_Pr,BaseAddr)) { 
+-	         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+-	      } else {
+-	         SiS_VBLongWait(SiS_Pr);
+-                 SiS_DisplayOn(SiS_Pr);
+-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+-                 SiS_VBLongWait(SiS_Pr);
+-	      }
+-	      
+-	   }
+-#endif
+-	  
+ 	 } else {			/* 315, 330 */
+ 
+-	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	      temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+-	      if(SiS_BridgeInSlave(SiS_Pr)) {
+-                 tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+-                 if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+-              }
+-              SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
++	    if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
++	       if(SiS_BridgeInSlave(SiS_Pr)) {
++                  tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
++                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
++               }
++               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+ 
+-	      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
++	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+ 
+-	      temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+-              if(!(temp & 0x80))
+-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+-           }
++	       temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
++               if(!(temp & 0x80))
++                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++            }
+ 
+-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
++	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+ 
+-	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
++	    if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+ 
+-	      temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+-              if (!(temp & 0x80))
+-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++	       temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
++               if(!(temp & 0x80))
++                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
++
++	       tempah = 0xc0;
++	       if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	          tempah = 0x80;
++	          if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++	             tempah = 0x40;
++                  }
++	       }
++               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ 
+-	      tempah = 0xc0;
+-	      if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	         tempah = 0x80;
+-	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-	            tempah = 0x40;
+-                 }
+-	      }
+-              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
++	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ 
+-	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
++	    } else {
+ 
+-	   } else {
+-	   
+-	      SiS_VBLongWait(SiS_Pr);
+-              SiS_DisplayOn(SiS_Pr);
+-	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+-              SiS_VBLongWait(SiS_Pr);
++	       SiS_VBLongWait(SiS_Pr);
++               SiS_DisplayOn(SiS_Pr);
++	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
++               SiS_VBLongWait(SiS_Pr);
+ 
+-	   }
++	    }
+ 
+ 	 }   /* 315, 330 */
+ 
+@@ -5782,11 +5978,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 
+       }
+ 
+-    } else {	/* ============  TW: For 301 ================ */
++    } else {	/* ============  For 301 ================ */
+ 
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
++                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+ 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+ 	    }
+        }
+@@ -5818,13 +6014,13 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+             if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ 	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
++                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+ 	    }
+        }
+ 
+     }
+ 
+-  } else {   /* =================== TW: For LVDS ================== */
++  } else {   /* =================== For LVDS ================== */
+ 
+     if(HwDeviceExtension->jChipType < SIS_315H) {
+ 
+@@ -5847,35 +6043,35 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+       if(SiS_BridgeInSlave(SiS_Pr)) {
+-      	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
++      	 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+       } else {
+-      	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
++      	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+       }
+ 
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+-        if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+-	        SiS_SetCH700x(SiS_Pr,0x0B0E);
+-        }
++         if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
++	    SiS_SetCH700x(SiS_Pr,0x0B0E);
++         }
+       }
+ 
+       if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+-          if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+-              if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+-	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+-			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+-        		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+-		  }
+-		  SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+-                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+-              }
+-	  }
++         if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
++            if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
++	       if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
++		  SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++        	  SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
++	       }
++	       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
++               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
++            }
++	 }
+       }
+ 
+ #endif  /* SIS300 */
+ 
+     } else {
+ 
+-#ifdef SIS315H    /* 310/325 series */
++#ifdef SIS315H    /* 315 series */
+ 
+ #if 0  /* BIOS code makes no sense */
+        if(SiS_IsVAMode()) {
+@@ -5902,36 +6098,41 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+ 	  SiS_Chrontel701xBLOff(SiS_Pr);
+        }
+ 
+-       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+-       
+-#ifdef NEWCH701x
+-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+-           if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
++       if(HwDeviceExtension->jChipType != SIS_550) {
++          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
++       }
++
++       if(HwDeviceExtension->jChipType == SIS_740) {
++          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
++             if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
+ 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+-	   }
++	     }
++	  }
+        }
+-#endif       
+ 
+        temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+-       if (!(temp1 & 0x80))
++       if(!(temp1 & 0x80))
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+ 
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+            if(temp) {
+-	       SiS_Chrontel701xBLOn(SiS_Pr);
++	       SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+ 	   }
+        }
+ 
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+ 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
++		if(HwDeviceExtension->jChipType == SIS_550) {
++		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
++		   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
++		}
++	   }
++       } else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++           if(HwDeviceExtension->jChipType != SIS_740) {
++              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ 	   }
+-       } 
+-#ifndef NEWCH701x       
+-         else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+        }
+-#endif       
+ 
+        if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+@@ -5954,10 +6155,10 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PS
+        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+        	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+  	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	            		SiS_Chrontel701xBLOn(SiS_Pr);
++	            		SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+ 	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+            		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+-       				SiS_Chrontel701xBLOn(SiS_Pr);
++       				SiS_Chrontel701xBLOn(SiS_Pr, HwDeviceExtension);
+        				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+ 	   		}
+        		}
+@@ -5983,7 +6184,7 @@ SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS
+ {
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ 
+-  /* TW: Switch on LCD backlight on SiS30xLV */
++  /* Switch on LCD backlight on SiS30xLV */
+   if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+     if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+@@ -6001,7 +6202,7 @@ SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSI
+ {
+   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+ 
+-  /* TW: Switch off LCD backlight on SiS30xLV */
++  /* Switch off LCD backlight on SiS30xLV */
+   if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+       (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+ 	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+@@ -6023,12 +6224,14 @@ SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr,
+   UCHAR *ROMAddr;
+ 
+   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+-     temp >>= 4;
+-     temp = 1 << temp;
+-     temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+-     if(temp1 & temp) return(1);
+-     else return(0);
++     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
++        temp >>= 4;
++        temp = 1 << temp;
++        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
++        if(temp1 & temp) return(1);
++        else return(0);
++     } else return(0);
+   } else {
+      return(0);
+   }
+@@ -6041,12 +6244,14 @@ SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr,
+   UCHAR *ROMAddr;
+ 
+   if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+-     temp >>= 4;
+-     temp = 1 << temp;
+-     temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+-     if(temp1 & temp) return(1);
+-     else return(0);
++     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
++        temp >>= 4;
++        temp = 1 << temp;
++        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
++        if(temp1 & temp) return(1);
++        else return(0);
++     } else return(0);
+   } else {
+      return(0);
+   }
+@@ -6143,7 +6348,7 @@ SiS_SetPanelDelay(SiS_Private *SiS_Pr, U
+ 
+ #ifdef SIS315H
+ 
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
++      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS */
+ 
+           if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+               PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+@@ -6171,7 +6376,7 @@ SiS_SetPanelDelay(SiS_Private *SiS_Pr, U
+ 	      SiS_ShortDelay(SiS_Pr,Delay);
+ 	  }
+ 
+-      } else {							/* 310/325 series, 301(B) */
++      } else {							/* 315 series, 301(B) */
+ 
+           PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ 	  DelayIndex = PanelID >> 4;
+@@ -6271,14 +6476,7 @@ SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_H
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+      if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
+-#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
+-     else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-       if(flag) return(1);
+-       else     return(0);   			         
+-     }
+-#endif
+-     else
+-       return(0);
++     else return(0);
+   } else
+ #endif
+      return(0);
+@@ -6325,7 +6523,9 @@ SiS_IsNotM650or651(SiS_Private *SiS_Pr, 
+   if(HwDeviceExtension->jChipType == SIS_650) {
+      flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
+      flag &= 0xF0;
+-     if((flag == 0xb0) || (flag == 0x90)) return 0;
++     /* Check for revision != A0 only */
++     if((flag == 0xe0) || (flag == 0xc0) ||
++        (flag == 0xb0) || (flag == 0x90)) return 0;
+      else return 1;
+   } else
+ #endif
+@@ -6443,7 +6643,7 @@ SiS_BridgeIsEnable(SiS_Private *SiS_Pr, 
+       if((flag == 0x80) || (flag == 0x20)) return 0;
+       else	                           return 1;
+     } else {
+-      /* 310/325 series (650/30xLV 1.10.6s) */
++      /* 315 series (650/30xLV 1.10.6s) */
+       flag &= 0x50;
+       if((flag == 0x40) || (flag == 0x10)) return 0;
+       else                                 return 1;
+@@ -6487,14 +6687,14 @@ SiS_SetHiVision(SiS_Private *SiS_Pr, USH
+   }
+ }
+ 
+-BOOLEAN
++void
+ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+                   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT temp,modeflag,resinfo=0;
+   const unsigned char SiS300SeriesLCDRes[] =
+-         { 0, 1, 2, 3, 7, 4, 5, 8,
+-	   0, 0, 0, 0, 0, 0, 0, 0 };
++         { 0,  1,  2,  3,  7,  4,  5,  8,
++	   0,  0, 10,  0,  0,  0,  0, 15 };
+ 
+   SiS_Pr->SiS_LCDResInfo = 0;
+   SiS_Pr->SiS_LCDTypeInfo = 0;
+@@ -6511,17 +6711,19 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+      }
+   }
+ 
+-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
++  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return;
+ 
+-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
++  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return;
+ 
+   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+ 
++#if 0
+   /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
+   if(SiS_Pr->SiS_IF_DEF_FSTN) {
+    	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
+    	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+   }
++#endif
+ 
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+   	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+@@ -6530,14 +6732,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+   }
+   temp &= 0x0f;
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+-      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
++      /* Translate 300 series LCDRes to 315 series for unified usage */
+       temp = SiS300SeriesLCDRes[temp];
+   }
+   SiS_Pr->SiS_LCDResInfo = temp;
+ 
++#if 0
+   if(SiS_Pr->SiS_IF_DEF_FSTN){
+        	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
+   }
++#endif
+ 
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+@@ -6547,75 +6751,115 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+ 		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+   }
+ 
+-  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
++  if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
++     if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+   	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
++  }
++
++  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++     if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++        SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
++     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++        SiS_Pr->SiS_LCDResInfo = Panel_848x480;
++     }
++  }
++
++  switch(SiS_Pr->SiS_LCDResInfo) {
++     case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
++     case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
++     case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
++     case Panel_640x480_3:
++     case Panel_640x480_2:
++     case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
++     case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
++     case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
++     case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
++     case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
++     case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
++     case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
++     case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
++     case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
++     case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
++    			   SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
++			   break;
++     case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
++     case Panel_848x480:   SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480; break;
++     default:		   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
++  }
+ 
+   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
++#if 0
+   if(SiS_Pr->SiS_IF_DEF_FSTN){
+-        /* TW: Fake LVDS bridge for FSTN */
++        /* Fake LVDS bridge for FSTN */
+       	temp = 0x04;
+       	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
+   }
++#endif
+   SiS_Pr->SiS_LCDInfo = temp;
+-  
++
++  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++     if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg sync, RGB24 */
++     }
++  }
++
+   if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ 
+-  /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
++  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
++	   /* For non-standard LCD resolution, we let the panel scale */
++           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
++	      /* Bridge does not scale to 1280x960 */
++              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++	   }
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++           /* TEMP - no idea about the timing and zoom factors */
++           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++	   if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
++	      /* Bridge does not scale to 1280x1024 */
++	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++	   }
++	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++	   /* TEMP - no idea about the timing and zoom factors */
++	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
++	}
++     }
++  }
++
++
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+ #ifdef SIS315H
+-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+-		     /* Bridge does not scale to 1280x1024 */
+-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+-		 }
+-	     }
+-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-	         if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
+-		     /* TW: Bridge does not scale to 1280x960 */
+-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+-		 }
+-		 if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+-		     /* TW: Bridge does not scale to 640x400 */
+-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+-		 }
+-	     }
+-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-	         if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+-		     /* TW: Most panels can't scale to 640x400 */
+-		     SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+-		 }
+-	     }
+-	 }
+-     }
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+-         SiS_Pr->SiS_LCDInfo &= 0xFFEF;    
+-	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
++        SiS_Pr->SiS_LCDInfo &= 0xFFEF;
++	SiS_Pr->SiS_LCDInfo |= LCDPass11;
+      }
+ #endif
+   } else {
+ #ifdef SIS300
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+-           if(!(ROMAddr[0x235] & 0x02)) {
+-	      SiS_Pr->SiS_LCDInfo &= 0xEF;
++	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
++              if(!(ROMAddr[0x235] & 0x02)) {
++	         SiS_Pr->SiS_LCDInfo &= 0xEF;
++ 	      }
+ 	   }
+         }
+-     } else {
+-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-	   if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+-               SiS_Pr->SiS_LCDInfo &= 0xEF;
+-	   }
++     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
++           SiS_Pr->SiS_LCDInfo &= 0xEF;
+ 	}
+      }
+ #endif
+   }
+-  
+-  /* TW: With Trumpion, always Expanding */
+-  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
+-       SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
++
++  /* Trumpion: Assume non-expanding */
++  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
++     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+   }
+ 
+   if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+@@ -6624,7 +6868,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ 	   if(ModeNo > 0x13) {
+ 	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+-                 if((resinfo == 7) || (resinfo == 3)) {
++                 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+                     SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ 		 }
+               }
+@@ -6644,9 +6888,9 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+ 	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
+                  if(ModeNo > 0x13) {
+                     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
++                       if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+-                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
++                       if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                     }
+                  }
+ 	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+@@ -6665,19 +6909,21 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+   }
+ 
+ #ifdef SIS315H
+-  /* TW: 650/30xLV 1.10.6s */
++  /* 650/30xLV 1.10.6s */
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-    if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+-      /* Enable 302B/302LV dual link mode */
+-      /* (302B is a theory - not in any BIOS */
+-      temp = 0x00;
+-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
+-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
+-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
+-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
+-    } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
+-    }
++     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
++        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
++        if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
++           /* Enable 302B/302LV dual link mode.
++            * (302B is a theory - not in any BIOS)
++	    */
++           if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++              (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++	      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
++	   }
++  	}
++     }
+   }
+ #endif
+ 
+@@ -6693,20 +6939,6 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, U
+ 	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
+ #endif
+ 
+-  return 1;
+-}
+-
+-void
+-SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+-{
+-  return;
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
+-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
+ }
+ 
+ void
+@@ -6736,7 +6968,6 @@ SiS_VBLongWait(SiS_Private *SiS_Pr)
+   } else {
+     SiS_LongWait(SiS_Pr);
+   }
+-  return;
+ }
+ 
+ void
+@@ -6803,7 +7034,7 @@ SiS_WaitRetrace1(SiS_Private *SiS_Pr, PS
+ #endif
+   } else {
+ #ifdef SIS300
+-#if 0  /* TW: Not done in A901 BIOS */
++#if 0  /* Not done in A901 BIOS */
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+      }
+@@ -6898,7 +7129,51 @@ void SiS_SetRegOR(USHORT Port,USHORT Ind
+ 
+ /* ========================================================= */
+ 
+-/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
++static void
++SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
++{
++  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
++           if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);   /* 48 */
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);   /* de */
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
++	      if((SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
++	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x14);
++	      } else {
++	         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x15);
++	      }
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1b);
++	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
++           }
++        } else {
++	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x21);
++	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x5a);
++	}
++     }
++  }
++}
++
++/* Set 301 TV Encoder (and some LCD relevant) registers */
+ void
+ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
+               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+@@ -6911,67 +7186,46 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ #ifdef SIS315H   
+   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+   USHORT      resindex, CRT2Index;
+-#endif  
++#endif
+   USHORT      modeflag, resinfo, crt2crtc;
+-  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
++  ULONG       longtemp, tempeax;
++#ifdef SIS300
+   const UCHAR atable[] = {
+                  0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+ 	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+   };
++#endif
+ 
+ #ifdef SIS315H   
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+-     /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
++     /* 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
+-	   temp = 1;
+-	   if(ModeNo <= 0x13) temp = 3;
++	   temp = 0x01;
++	   if(ModeNo <= 0x13) temp = 0x03;
+ 	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+ 	}
+      }
+-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+-           }
+-         }
+-       }
+-     }
++     SiS_SetTVSpecial(SiS_Pr, ModeNo);
+      return;
+   }
+-#endif  
++#endif
+ 
+-  if(ModeNo<=0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++  if(ModeNo <= 0x13) {
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+   } else {
+-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++	resinfo = 0;
++	crt2crtc = 0;
++     } else {
++        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++     }
+   }
+ 
+   tempcx = SiS_Pr->SiS_VBInfo;
+@@ -6984,9 +7238,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   temp |= ((tempbx & 0x00FF) >> 3);
+   temp ^= 0x0C;
+ 
+-  /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
++  /* From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
+   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-  	temp |= 0x0c;
++     temp |= 0x0c;
+   }
+ 
+   PhasePoint  = SiS_Pr->SiS_PALPhase;
+@@ -6994,44 +7248,44 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          
+   
+-    temp ^= 0x01;
+-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+-        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+-      }
+-    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+-    
+-    if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
+-    
++     temp ^= 0x01;
++     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
++        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++           if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
++           else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
++        }
++     } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
++
++     if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
++
+   } else {
+-  
+-    if(SiS_Pr->SiS_VBInfo & SetPALTV){
+ 
+-      TimingPoint = SiS_Pr->SiS_PALTiming;
+-      PhasePoint  = SiS_Pr->SiS_PALPhase;
++     if(SiS_Pr->SiS_VBInfo & SetPALTV){
+ 
+-      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+-          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+-         PhasePoint = SiS_Pr->SiS_PALPhase2;
+-      }
++        TimingPoint = SiS_Pr->SiS_PALTiming;
++        PhasePoint  = SiS_Pr->SiS_PALPhase;
+ 
+-    } else {
++        if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++            ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++           PhasePoint = SiS_Pr->SiS_PALPhase2;
++        }
++
++     } else {
+ 
+         temp |= 0x10;
+-	TimingPoint = SiS_Pr->SiS_NTSCTiming;
+-	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
++        TimingPoint = SiS_Pr->SiS_NTSCTiming;
++        PhasePoint  = SiS_Pr->SiS_NTSCPhase;
+ 
+-        if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
++        if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+ 	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ 	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+-        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
++           PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+         }
+ 
+-    }
+-    
++     }
++
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
+ 
+@@ -7044,36 +7298,35 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+      temp = 0x38;
+   }
+   if(temp) {
+-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+-          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
+-          if(temp1 & EnablePALM) {	/* 0x40 */
+-              	PhasePoint = SiS_Pr->SiS_PALMPhase;
+-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+-	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
+-		}
+-	  }
+-          if(temp1 & EnablePALN) {	/* 0x80 */
+-               	PhasePoint = SiS_Pr->SiS_PALNPhase;
+-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+-	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
+-		}
+-	  }
+-      }
+-    }
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++           temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
++           if(temp1 & EnablePALM) {	/* 0x40 */
++              PhasePoint = SiS_Pr->SiS_PALMPhase;
++	      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++	         PhasePoint = SiS_Pr->SiS_PALMPhase2;
++	      }
++	   }
++           if(temp1 & EnablePALN) {	/* 0x80 */
++              PhasePoint = SiS_Pr->SiS_PALNPhase;
++	      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
++		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
++		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
++	         PhasePoint = SiS_Pr->SiS_PALNPhase2;
++	      }
++	   }
++        }
++     }
+   }
+ 
+ #ifdef SIS315H
+-  /* TW: 650/301LV BIOS */
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+            if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
++              if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ 	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
+ 	      }
+            }
+@@ -7094,12 +7347,12 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   }
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      if(!(SiS_Pr->SiS_ModeType & 0x07))
++     if(HwDeviceExtension->jChipType >= SIS_315H) {
++        if(!(SiS_Pr->SiS_ModeType & 0x07))
++           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
++     } else {
+         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+-    } else {
+-      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+-    }
++     }
+   }
+ 
+   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
+@@ -7110,11 +7363,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+-      if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
+-      else tempax = 440;
++     if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
++     else tempax = 440;
+   } else {
+-    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+-    else tempax = 440;
++     if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
++     else tempax = 440;
+   }
+ 
+   if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+@@ -7134,18 +7387,18 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+ 
+      if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+-        (SiS_Pr->SiS_HiVision != 3) &&
+-        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
++         (SiS_Pr->SiS_HiVision != 3) &&
++         (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+         if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
+            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
+         } else {
+            if(HwDeviceExtension->jChipType >= SIS_315H) {
+-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
+-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+ 	   } else {
+-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+ 	   }
+         }
+      }
+@@ -7154,7 +7407,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ 
+   tempcx = SiS_Pr->SiS_HT;
+ 
+-  /* TW: 650/30xLV 1.10.6s */
++  /* 650/30xLV 1.10.6s */
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+       	   tempcx >>= 1;
+@@ -7181,7 +7434,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   tempcx += 7;
+   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (SiS_Pr->SiS_HiVision == 3)) {
+-       tempcx -= 4;
++     tempcx -= 4;
+   }
+   temp = (tempcx & 0x00FF) << 4;
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
+@@ -7201,8 +7454,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   tempbx += 8;
+   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (SiS_Pr->SiS_HiVision == 3)) {
+-    tempbx -= 4;
+-    tempcx = tempbx;
++     tempbx -= 4;
++     tempcx = tempbx;
+   }
+   temp = (tempbx & 0x00FF) << 4;
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
+@@ -7231,8 +7484,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ 
+   tempcx -= 11;
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+-    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
+-    tempcx = tempax;
++     tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
++     tempcx = tempax;
+   }
+   temp = tempcx & 0x00FF;
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
+@@ -7242,38 +7495,38 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+   if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+-  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+   } else {
+-	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+-	   tempbx >>= 1;
+-	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-	      if(ModeNo <= 0x13) {
+-	         if(crt2crtc == 1) {
+-	            tempbx++;
+-                 }
+-	      }
+-	   } else {
+-              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
+-                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+-	      }
++     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
++	tempbx >>= 1;
++	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++	   if(ModeNo <= 0x13) {
++	      if(crt2crtc == 1) {
++	         tempbx++;
++              }
+ 	   }
+-        }
++	} else {
++           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++	      if(crt2crtc == 4)   /* BIOS calls GetRatePtrCRT2 here - does not make sense */
++                 if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
++	   }
++	}
++     }
+   }
+   tempbx -= 2;
+   temp = tempbx & 0x00FF;
+   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (SiS_Pr->SiS_HiVision == 3)) {
+-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-      if(ModeNo == 0x2f) temp++;
+-    }
++     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++        if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
++     }
+   }
+-  /* TW: From 1.10.7w - doesn't make sense */
++  /* From 1.10.7w - doesn't make sense */
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+ 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
+-	       if(ModeNo == 0x03) temp++;
++	      if(ModeNo == 0x03) temp++;
+ 	   }
+ 	}
+      }
+@@ -7285,15 +7538,15 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   tempax |= (tempbx & 0xFF00);
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
++        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* New from 630/301B (II) BIOS */
+            tempax |= 0x1000;
+            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
+         }
+      }
+   } else {
+      /* TODO Check this with other BIOSes */
+-     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) && 
+-        (SiS_Pr->SiS_HiVision == 3)) {
++     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV))
++         /* && (SiS_Pr->SiS_HiVision == 3) */ ) {
+ 	tempax |= 0x1000;
+         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
+      }
+@@ -7301,12 +7554,12 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   temp = (tempax & 0xFF00) >> 8;
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
+ 
+-  /* TW: 650/30xLV 1.10.6s */
++  /* 650/30xLV 1.10.6s */
+   if(HwDeviceExtension->jChipType > SIS_315H) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
+-            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
++           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+         }
+      }
+   }
+@@ -7322,79 +7575,70 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+      }
+   }
+ 
+-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {     
+-    tempbx = SiS_Pr->SiS_VDE;
+-    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+-         tempbx >>= 1;
+-    }
+-    tempbx -= 3;
+-    tempbx &= 0x03ff;
+-    temp = ((tempbx & 0xFF00) >> 8) << 5;
+-    temp |= 0x18;
+-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+-    temp = tempbx & 0x00FF;
+-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
+-    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: 650/30xLV 1.10.6s */
+-       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-          tempax = 0;
+-          if(SiS_Pr->SiS_HiVision & 0x03) {
+-	     tempax = 0x3000;
+-	     if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
+-	  }
+-	  temp = (tempax & 0xFF00) >> 8;
+-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
+-       }
+-    }
++  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++     tempbx = SiS_Pr->SiS_VDE;
++     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
++        tempbx >>= 1;
++     }
++     tempbx -= 3;
++     tempbx &= 0x03ff;
++     temp = ((tempbx & 0xFF00) >> 8) << 5;
++     temp |= 0x18;
++     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
++     temp = tempbx & 0x00FF;
++     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
++     if(HwDeviceExtension->jChipType >= SIS_315H) {
++        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++           tempax = 0;
++           if(SiS_Pr->SiS_HiVision & 0x03) {
++ 	      tempax = 0x3000;
++	      if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
++	   }
++	   temp = (tempax & 0xFF00) >> 8;
++           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
++        }
++     }
+   }
+ 
+   tempbx &= 0x00FF;
+   if(!(modeflag & HalfDCLK)) {
+-    tempcx = SiS_Pr->SiS_VGAHDE;
+-    if(tempcx >= SiS_Pr->SiS_HDE) {
+-      tempbx |= 0x2000;
+-      tempax &= 0x00FF;
+-    }
++     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
++        tempbx |= 0x2000;
++        tempax &= 0x00FF;
++     }
+   }
+ 
+   tempcx = 0x0101;
+-/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /*301b- TW: BIOS BUG? */
++/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /* BIOS BUG? */
+   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+-    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
+-        if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {   /* TW: This check not in 630/301B */
+-          tempcx = 0x1920;
+-          if(SiS_Pr->SiS_VGAHDE >= 1280) {
+-            tempcx = 0x1420;
+-            tempbx &= 0xDFFF;
+-          }
++     if(!(SiS_Pr->SiS_HiVision & 0x03)) {
++        if(SiS_Pr->SiS_VGAHDE >= 1024) {
++           if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {
++              tempcx = 0x1920;
++              if(SiS_Pr->SiS_VGAHDE >= 1280) {
++                 tempcx = 0x1420;
++                 tempbx &= 0xDFFF;
++              }
++           }
+         }
+-      }
+-    }
++     }
+   }
+ 
+   if(!(tempbx & 0x2000)) {
+-    if(modeflag & HalfDCLK) {
+-         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
+-    }
+-    push1 = tempbx;
+-    tempeax = SiS_Pr->SiS_VGAHDE;
+-    tempebx = (tempcx & 0xFF00) >> 8;
+-    longtemp = tempeax * tempebx;
+-    tempecx = tempcx & 0x00FF;
+-    longtemp /= tempecx;
+-    longtemp <<= 0x0d;
+-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++     if(modeflag & HalfDCLK) {
++        tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
++     }
++     longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
++     longtemp <<= 13;
++     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      	longtemp <<= 3;
+-    }
+-    tempecx = SiS_Pr->SiS_HDE;
+-    temp2 = longtemp % tempecx;
+-    tempeax = longtemp / tempecx;
+-    if(temp2 != 0) tempeax++;
+-    tempax = (USHORT)tempeax;
+-    tempbx = push1;
+-    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
+-    tempbx |= (tempax & 0x1F00);
+-    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
++     }
++     tempeax = longtemp / SiS_Pr->SiS_HDE;
++     if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
++     tempax = (USHORT)tempeax;
++     tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5));
++     tempbx |= (tempax & 0x1F00);
++     tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+   }
+ 
+   temp = (tempax & 0xFF00) >> 8;
+@@ -7403,33 +7647,32 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
+ 
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-       temp = tempcx & 0x00FF;
+-       if(tempbx & 0x2000) temp = 0;
+-       temp |= 0x18;
+-       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+-       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-             tempbx = 0x0382;  
+-             tempcx = 0x007e;  
+-       } else {
+-             tempbx = 0x0369;  
+-             tempcx = 0x0061;  
+-       }
+-       temp = (tempbx & 0x00FF) ;
+-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
+-       temp = (tempcx & 0x00FF) ;
+-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+-       tempbx &= 0x03FF;
+-       temp = (tempcx & 0xFF00) >> 8;
+-       temp = (temp & 0x0003) << 2;
+-       temp |= (tempbx >> 8);
+-       if(HwDeviceExtension->jChipType < SIS_315H) {
+-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
+-       } else {
+-          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+-       }
++     temp = tempcx & 0x00FF;
++     if(tempbx & 0x2000) temp = 0;
++     temp |= 0x18;
++     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+ 
+-       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
+-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
++     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
++        tempbx = 0x0382;
++        tempcx = 0x007e;
++     } else {
++        tempbx = 0x0369;
++        tempcx = 0x0061;
++     }
++     temp = (tempbx & 0x00FF) ;
++     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
++     temp = (tempcx & 0x00FF) ;
++     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
++     temp = (tempcx & 0x0300) >> (8 - 2);
++     temp |= ((tempbx >> 8) & 0x03);
++     if(HwDeviceExtension->jChipType < SIS_315H) {
++        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
++     } else {
++        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
++     }
++
++     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
++     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+   }
+ 
+   temp = 0;
+@@ -7440,23 +7683,33 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+      temp = 0x38;
+   }
+   if(temp) {
+-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+-               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
+-                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+-                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+-                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+-               }
+-          }
+-      }
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
++              SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
++              temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
++              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
++           }
++        }
++     }
+   }
+ 
++  if(HwDeviceExtension->jChipType >= SIS_315H) {
++     if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
++        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
++        }
++     }
++  }
++
++#if 0  /* Old: Why HiVision? */
+   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+       (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+-    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+-    }
++     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
++        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
++     }
+   }
++#endif
+ 
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+@@ -7465,74 +7718,43 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ 	return;
+      }
+   } else {
+-     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
++     /* !!! The following is a duplicate, done for LCDA as well (see above) */
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    
+-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+-	     }
+-           }
+-         }
+-       }
+-       return;
++        SiS_SetTVSpecial(SiS_Pr, ModeNo);
++        return;
+      }
+   }
+ 
+-  /* TW: From here: Part2 LCD setup */
++  /* From here: Part2 LCD setup */
+ 
+   tempbx = SiS_Pr->SiS_HDE;
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      /* TW: 650/30xLV 1.10.6s */
+-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
++     /* 650/30xLV 1.10.6s */
++     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+   }
+   tempbx--;			         	/* RHACTE=HDE-1 */
+   temp = tempbx & 0x00FF;
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
+-  temp = (tempbx & 0xFF00) >> 8;
+-  temp <<= 4;
++  temp = (tempbx & 0xFF00) >> 4;
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
+ 
+   temp = 0x01;
+   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-    if(SiS_Pr->SiS_ModeType == ModeEGA) {
+-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
+-        temp = 0x02;
+-	if(HwDeviceExtension->jChipType >= SIS_315H) {
+-           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+-             temp = 0x01;
++     if(SiS_Pr->SiS_ModeType == ModeEGA) {
++        if(SiS_Pr->SiS_VGAHDE >= 1024) {
++           temp = 0x02;
++	   if(HwDeviceExtension->jChipType >= SIS_315H) {
++              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
++                 temp = 0x01;
++	      }
+ 	   }
+-	}
+-      }
+-    }
++        }
++     }
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
+ 
+-  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
+-  push1 = tempbx;
+-
++  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO = VDE - 1 */
++  /* push1 = tempbx; */
+   tempbx--;
+   temp = tempbx & 0x00FF;
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
+@@ -7540,10 +7762,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
+ 
+   tempcx = SiS_Pr->SiS_VT;
+-  push2 = tempcx;
+-
++  /* push2 = tempcx; */
+   tempcx--;
+-  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
++  temp = tempcx & 0x00FF;  			 /* RVTVT = VT - 1 */
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
+ 
+   temp = (tempcx & 0xFF00) >> 8;
+@@ -7551,40 +7772,42 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   
+   /* Enable dithering; newer versions only do this for 32bpp mode */
+   if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+-    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
++     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+   } else if(HwDeviceExtension->jChipType < SIS_315H) {
+-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
+-    else {
+-      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
+-         temp |= 0x10;
+-    }
++     temp |= 0x10;
+   } else {
+-      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-         /* TW: 650/30xLV 1.10.6s */
+-         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+-            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
+-      	       temp |= 0x10;
+-	    }
+-         }
+-      } else {
+-         temp |= 0x10;
+-      }
++     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++        /* 650/30xLV 1.10.6s */
++        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
++           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
++              temp |= 0x10;
++	   }
++        }
++     } else {
++        temp |= 0x10;
++     }
+   }
+ 
+   /* 630/301 does not do all this */
+   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+      if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+-        /* TW: 650/30xLV 1.10.6s */
+-        temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
+-	temp |= 0x08;   					/* From 1.10.7w */
+-	if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
+-     } else {
+-        tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
+-        if(tempbx & LCDSync) {
+-           tempbx &= 0xFFE0;
+-           tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> 6);
+-           temp |= (tempbx & 0x00FF);
+-        }
++	if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
++	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
++#ifdef SIS315H
++	   if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++	      temp |= (SiS_Pr->SiS_LCDInfo >> 6);
++	   }
++#endif
++	} else {
++	   /* 650/30xLV 1.10.6s */
++           temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
++	   temp |= 0x08;   						/* From 1.10.7w */
++	   if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
++	}
++     } else {
++        if(SiS_Pr->SiS_LCDInfo & LCDSync) {
++	   temp |= (SiS_Pr->SiS_LCDInfo >> 6);
++	}
+      }
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
+@@ -7595,24 +7818,22 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
+   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
+ 
+-  /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
+-  if((HwDeviceExtension->jChipType >= SIS_315H)             && 
+-     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)                &&  
+-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
+-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
+-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
++  if((HwDeviceExtension->jChipType >= SIS_315H)         &&
++     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
++     ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
++      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
+      
+-#ifdef SIS315H 							/* ------------- 310/325/330 series ------------ */
++#ifdef SIS315H 							/* ------------- 315/330 series ------------ */
+ 
+-      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
+-      
+       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
+        * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
+        * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
+        */
+ 
+       SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+-                         &CRT2Index,&resindex);
++                         &CRT2Index,&resindex,HwDeviceExtension);
+ 
+       switch(CRT2Index) {
+         case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
+@@ -7627,6 +7848,9 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+         case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
+ 	case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
+ 	case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
++	case 100:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break;  /* Custom */
++	case 101:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
++	case 102:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
+ 	default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
+       }
+ 
+@@ -7653,8 +7877,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ 	  }
+ 	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ 	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+-	}
+-	if(SiS_Pr->SiS_VGAVDE == 420) {
++	} else if(SiS_Pr->SiS_VGAVDE == 420) {
+ 	  temp = 0x4d;
+ 	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ 	     temp++;
+@@ -7664,7 +7887,6 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+ 	}
+      }
+ 
+-     /* TW: 650/30xLV 1.10.6s: */
+      /* !!! This is a duplicate, done for LCDA as well - see above */
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+@@ -7683,59 +7905,46 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+        * the bridge scales all modes to 1024.
+        * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
+        */
+-  
++
++    /* cx = VT - 1 */
++
+     tempcx++;
+-    
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx =  768;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
+-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
+-    else if(SiS_Pr->SiS_VDE != 1024) 				  tempbx =  960;
+-    else            						  tempbx = 1024;
+-    
+-#if 0  /* old */
+-    tempbx = 768;
+-    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+-      tempbx = 1024;
+-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+-         tempbx = 1200;
+-         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+-            if(tempbx != SiS_Pr->SiS_VDE) {
+-               tempbx = 960;
+-            }
+-         }
+-      }
+-    }
+-#endif
+-    
++
++    tempbx = SiS_Pr->PanelYRes;
++
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+-      tempbx = SiS_Pr->SiS_VDE - 1;
+-      tempcx--;
++       tempbx = SiS_Pr->SiS_VDE - 1;
++       tempcx--;
+     }
+-    
++
+     tempax = 1;
+     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+-      if(tempbx != SiS_Pr->SiS_VDE) {
+-        tempax = tempbx;
+-/*	if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60;   in 650/301B BIOS */
+-        if(tempax < SiS_Pr->SiS_VDE) {
+-          tempax = 0;
+-          tempcx = 0;
+-        } else {
+-          tempax -= SiS_Pr->SiS_VDE;
+-        }
+-        tempax >>= 1;
+-      }
+-      tempcx -= tempax; /* lcdvdes */
+-      tempbx -= tempax; /* lcdvdee */
+-    } else {
+-      tempax >>= 1;
+-      tempcx -= tempax; /* lcdvdes */
+-      tempbx -= tempax; /* lcdvdee */
++       if(tempbx != SiS_Pr->SiS_VDE) {
++          tempax = tempbx;
++          if(tempax < SiS_Pr->SiS_VDE) {
++             tempax = 0;
++             tempcx = 0;
++          } else {
++             tempax -= SiS_Pr->SiS_VDE;
++          }
++          tempax >>= 1;
++       }
++       tempcx -= tempax; /* lcdvdes */
++       tempbx -= tempax; /* lcdvdee */
+     }
+-    
++#if 0  /* meaningless: 1 / 2 = 0... */
++    else {
++       tempax >>= 1;
++       tempcx -= tempax; /* lcdvdes */
++       tempbx -= tempax; /* lcdvdee */
++    }
++#endif
++
++    /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
++
+ #ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
+-#endif    
++    xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
++#endif
+ 
+     temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
+@@ -7746,140 +7955,178 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHOR
+     temp |= ((tempcx & 0xFF00) >> 8);
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+ 
+-    tempbx = push2;
+-    tempax = push1;
+-    tempcx = tempbx;
+-    tempcx -= tempax;
+-    tempcx >>= 4;
++    tempbx = SiS_Pr->SiS_VT;    /* push2; */
++    tempax = SiS_Pr->SiS_VDE;   /* push1; */
++    tempcx = (tempbx - tempax) >> 4;
+     tempbx += tempax;
+     tempbx >>= 1;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx -= 10;
+-    
++
++    /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
++
++    if(SiS_Pr->UseCustomMode) {
++       tempbx = SiS_Pr->CVSyncStart;
++    }
++
+ #ifdef TWDEBUG
+     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
+ #endif
+ 
+-    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
++    temp = tempbx & 0x00FF;   				/* RTVACTEE = lcdvrs */
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+ 
+     temp = ((tempbx & 0xFF00) >> 8) << 4;
+     tempbx += (tempcx + 1);
+     temp |= (tempbx & 0x000F);
++
++    if(SiS_Pr->UseCustomMode) {
++       temp &= 0xf0;
++       temp |= (SiS_Pr->CVSyncEnd & 0x0f);
++    }
++
++#ifdef TWDEBUG
++    xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
++#endif
++
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+ 
+-    /* TW: Code from 630/301B (I+II) BIOS */
++    /* Code from 630/301B (I+II) BIOS */
+ 
+-    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
+-            (HwDeviceExtension->jChipType == SIS_730) ) &&
+-          (HwDeviceExtension->jChipRevision > 2) )  &&
+-        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+-        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+-        (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+-            if(ModeNo == 0x13) {
+-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+-            } else {
+-              if((crt2crtc & 0x3F) == 4) {
++    if(!SiS_Pr->UseCustomMode) {
++       if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
++               (HwDeviceExtension->jChipType == SIS_730) ) &&
++             (HwDeviceExtension->jChipRevision > 2) )  &&
++           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
++           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
++           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
++          if(ModeNo == 0x13) {
++             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
++             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
++             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
++          } else {
++             if((crt2crtc & 0x3F) == 4) {
+                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
+                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
+                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+-              }
+-            }
++             }
++          }
++       }
+     }
+ 
+-    /* TW: Inserted missing code from 630/301B BIOS;
+-     *     Strangely, this is done in all 650 BIOSes as
+-     *     well (although LCDTypeInfo is not used there
+-     *     in the same way as on 300 series)
+-     */
+-
+-    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+-         crt2crtc &= 0x1f;
+-         tempcx = 0;
+-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+-           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-              tempcx += 7;
+-           }
+-         }
+-         tempcx += crt2crtc;
+-         if (crt2crtc >= 4) {
+-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
+-         }
++#ifdef SIS300
++    if(HwDeviceExtension->jChipType < SIS_315H) {
++       if(!SiS_Pr->UseCustomMode) {
++          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
++             crt2crtc &= 0x1f;
++             tempcx = 0;
++             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
++                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++                   tempcx += 7;
++                }
++             }
++             tempcx += crt2crtc;
++             if(crt2crtc >= 4) {
++                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
++             }
+ 
+-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-             if(crt2crtc == 4) {
+-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
++             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
++                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++                   if(crt2crtc == 4) {
++                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
++                   }
++                }
+              }
+-           }
+-         }
+-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
+-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
++             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
++             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
++          }
++       }
+     }
++#endif
+ 
+-    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
++    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
+     tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-         tempbx += 2;
++       tempbx += 2;
+     }
+     push1 = tempbx;
++
+ #ifdef TWDEBUG
+-    xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
+-#endif    
+-    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
++    xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
++#endif
++
++    temp = tempbx & 0x00FF;    			          /* RHEQPLE = lcdhdee */
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
+     temp = (tempbx & 0xFF00) >> 8;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
+ 
+     temp = 7;
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-         temp += 2;
++       temp += 2;
+     }
+-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes[7:0] */
++    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE = lcdhdes[7:0] */
+     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);	  /* lcdhdes [11:8] */
+ 
+     tempbx += tempcx;
+     push2 = tempbx;
++
++    if(SiS_Pr->UseCustomMode) {
++       tempbx = SiS_Pr->CHSyncStart + 7;
++       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++          tempbx += 2;
++       }
++    }
++
+ #ifdef TWDEBUG
+     xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
+ #endif
+-    temp = tempbx & 0x00FF;            		          /* RHBURSTS=lcdhrs */
+-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 
+-          if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
++
++    temp = tempbx & 0x00FF;            		          /* RHBURSTS = lcdhrs */
++    if(!SiS_Pr->UseCustomMode) {
++       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
++             if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
++          }
+        }
+     }
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
+-    temp = ((tempbx & 0xFF00) >> 8) << 4;
++    temp = (tempbx & 0x0F00) >> 4;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
+ 
+     tempbx = push2;
+     tempcx <<= 1;
+     tempbx += tempcx;
++
++    if(SiS_Pr->UseCustomMode) {
++       tempbx = SiS_Pr->CHSyncEnd + 7;
++       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++          tempbx += 2;
++       }
++    }
++
+ #ifdef TWDEBUG
+     xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
+-#endif    
+-    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
++#endif
++
++    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S = lcdhre */
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
+ 
+     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+-      if(SiS_Pr->SiS_VGAVDE == 525) {
+-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
+-    	   temp=0xC6;
+-        else
+-       	   temp=0xC3;
+-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+-      } else if(SiS_Pr->SiS_VGAVDE == 420) {
+-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
+-	   temp=0x4F;
+-        else
+-       	   temp=0x4D;   
+-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+-      }
++       if(SiS_Pr->SiS_VGAVDE == 525) {
++          if(SiS_Pr->SiS_ModeType <= ModeVGA)
++    	     temp=0xC6;
++          else
++       	     temp=0xC3;
++          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
++          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
++       } else if(SiS_Pr->SiS_VGAVDE == 420) {
++          if(SiS_Pr->SiS_ModeType <= ModeVGA)
++	     temp=0x4F;
++          else
++       	     temp=0x4D;
++          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
++       }
+     }
+     SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+                         RefreshRateTableIndex, BaseAddr, ModeNo);
+@@ -7898,7 +8145,7 @@ SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+   return((USHORT) tempax);
+ }
+ 
+-/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
++/* New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
+ void
+ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+     			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+@@ -7910,18 +8157,19 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr,
+ 
+   if(HwDeviceExtension->jChipType != SIS_300) return;
+   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
++  if(SiS_Pr->UseCustomMode) return;
+ 
+-  if(ModeNo<=0x13) {
+-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++  if(ModeNo <= 0x13) {
++     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+   } else {
+-    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+   }
+ 
+   resindex = crt2crtc & 0x3F;
+   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+   else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
+ 
+-  /* TW: The BIOS code (1.16.51) is obviously a fragment! */
++  /* The BIOS code (1.16.51) is obviously a fragment! */
+   if(ModeNo > 0x13) {
+      CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+      resindex = 4;
+@@ -7942,7 +8190,6 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr,
+   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+ }
+ 
+-/* TW: Set 301 Macrovision(tm) registers */
+ void
+ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+@@ -7954,24 +8201,35 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHOR
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+ 
+-  if(ModeNo<=0x13)
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-  else
++  if(ModeNo<=0x13) {
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++  } else {
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++     } else {
+     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++     }
++  }
+ 
++#ifndef SIS_CP
+   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
++#endif
++
++#ifdef SIS_CP
++  SIS_CP_INIT301_CP
++#endif
+ 
+   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
++     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
++     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+   } else {
+-    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
+-    } else {
+-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
+-    }
++     if(HwDeviceExtension->jChipType >= SIS_315H) {
++        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
++        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
++     } else {
++        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
++        SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
++     }
+   }
+ 
+   temp = 0;
+@@ -7982,38 +8240,41 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHOR
+      temp = 0x38;
+   }
+   if(temp) {
+-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+-              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
+-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
+-              }
+-          }
+-      }
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
++           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
++              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
++              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
++              SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
++           }
++        }
++     }
+   }
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+-    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+-    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+-      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
+-      if(!(modeflag & Charx8Dot)) {
+-        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
+-      }
+-    }
+-    if(SiS_Pr->SiS_HiVision & 0x03) {
+-       tempdi = SiS_HiTVGroup3_1;
+-       if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+-    }
+-    for(i=0; i<=0x3E; i++){
+-       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+-    }
++     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
++     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
++        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
++        if(!(modeflag & Charx8Dot)) {
++           tempdi = SiS_Pr->SiS_HiTVGroup3Text;
++        }
++     }
++     if(SiS_Pr->SiS_HiVision & 0x03) {
++        tempdi = SiS_HiTVGroup3_1;
++        if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
++     }
++     for(i=0; i<=0x3E; i++){
++        SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
++     }
+   }
+ 
+-  return;
++#ifdef SIS_CP
++  SIS_CP_INIT301_CP2
++#endif
++
+ }
+ 
+-/* TW: Set 301 VGA2 registers */
++/* Set 301 VGA2 registers */
+ void
+ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+@@ -8022,17 +8283,20 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
+   ULONG tempebx,tempeax,templong;
+ 
+-
+-  if(ModeNo<=0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+-	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++  if(ModeNo <= 0x13) {
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   } else {
++     if(SiS_Pr->UseCustomMode) {
++        modeflag = SiS_Pr->CModeFlag;
++	resinfo = 0;
++     } else {
+     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     }
+   }
+ 
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
+      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+            SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+@@ -8049,10 +8313,10 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	   /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
+-  	   /* TW: This is a duplicate; done at the end, too */
++	   /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
++  	   /* This is a duplicate; done at the end, too */
+ 	   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+-		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
++	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+ 	   }
+ 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ 	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+@@ -8090,39 +8354,33 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+   tempbx = SiS_Pr->SiS_VGAHDE;
+   if(modeflag & HalfDCLK)  tempbx >>= 1;
+ 
+-  /* TW: New for 650/301LV and 630/301B */
+   temp = 0xA0;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+-       temp = 0;
+-       if(tempbx > 800) {
+-          temp = 0xA0;
+-          if(tempbx != 1024) {
+-             temp = 0xC0;
+-             if(tempbx != 1280) temp = 0;
+-	  }
+-       }
+-  } else
+-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-      if(tempbx <= 800) {
+-         temp = 0x80;
+-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-            temp = 0;
+-            if(tempbx > 800) temp = 0x60;
+-         }
+-      }
++     temp = 0;
++     if(tempbx > 800) {
++        temp = 0xA0;
++        if(tempbx != 1024) {
++           temp = 0xC0;
++           if(tempbx != 1280) temp = 0;
++	}
++     }
++  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
++     if(tempbx <= 800) {
++        temp = 0x80;
++     }
+   } else {
+-      temp = 0x80;
+-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-            temp = 0;
+-            if(tempbx > 800) temp = 0x60;
+-      }
++     temp = 0x80;
++     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
++        temp = 0;
++        if(tempbx > 800) temp = 0x60;
++     }
+   }
+   if(SiS_Pr->SiS_HiVision & 0x03) {
+         temp = 0;
+ 	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
+   }
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+-  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
++     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
+   }
+ 
+   if(SiS_Pr->SiS_VBType & VB_SIS301) {
+@@ -8144,10 +8402,10 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+ 
+   tempeax = SiS_Pr->SiS_VGAVDE;
+   tempcx |= 0x4000;
+-  if(tempeax <= tempebx){
+-    tempcx ^= 0x4000;
++  if(tempeax <= tempebx) {
++     tempcx ^= 0x4000;
+   } else {
+-    tempeax -= tempebx;
++     tempeax -= tempebx;
+   }
+ 
+   templong = (tempeax * 256 * 1024) % tempebx;
+@@ -8173,64 +8431,64 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+          tempax = SiS_Pr->SiS_VGAHDE;
+          if(modeflag & HalfDCLK) tempax >>= 1;
+          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
+-	     if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
+-		 else if(tempax > 800) tempax -= 800;
+-	     } else {
+-                 if(tempax > 800) tempax -= 800;
+-             }
++	    if(HwDeviceExtension->jChipType >= SIS_315H) {
++	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
++	       else if(tempax > 800) tempax -= 800;
++	    } else {
++               if(tempax > 800) tempax -= 800;
++            }
+          }
+ 
+ /*       if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {  */
+  	 if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+-           if(tempax > 800) {
+-	      tempbx = 8;
+-              if(tempax == 1024)
+-	        tempax *= 25;
+-              else
+-	        tempax *= 20;
+-
+-	      temp = tempax % 32;
+-	      tempax /= 32;
+-	      tempax--;
+-	      if (temp!=0) tempax++;
+-           }
++            if(tempax > 800) {
++	       tempbx = 8;
++               if(tempax == 1024)
++	          tempax *= 25;
++               else
++	          tempax *= 20;
++
++	       temp = tempax % 32;
++	       tempax /= 32;
++	       tempax--;
++	       if (temp!=0) tempax++;
++            }
+          }
+ 	 tempax--;
+          temp = (tempax & 0xFF00) >> 8;
+          temp &= 0x03;
+-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {		/* From 1.10.7w */
+-	 	if(ModeNo > 0x13) {			/* From 1.10.7w */
+-			if(resinfo == 8) tempax = 0x1f;	/* From 1.10.7w */
+-		}					/* From 1.10.7w */
+-	 }						/* From 1.10.7w */
++	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* From 1.10.7w */
++	    if(ModeNo > 0x13) {					/* From 1.10.7w */
++	       if(resinfo == SIS_RI_1024x768) tempax = 0x1f;	/* From 1.10.7w */
++	    }							/* From 1.10.7w */
++	 }							/* From 1.10.7w */
+ 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
+ 	 temp <<= 4;
+ 	 temp |= tempbx;
+ 	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
+ 
+ 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	    if(IS_SIS650740) {
+-	        temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
++	    if(IS_SIS550650740660) {
++	       temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
+ 	    } else {
+-	        temp = 0x0036;
++	       temp = 0x0036;
+ 	    }
+ 	 } else {
+-	     temp = 0x0036;
++	    temp = 0x0036;
+ 	 }
+          if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+ 	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
+-		temp |= 0x01;
+-	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+-	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+-  	                  temp &= 0xFE;
+-		}
++	    temp |= 0x01;
++	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
++	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
++  	          temp &= 0xFE;
++	    }
+          }
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+ 
+ 	 tempbx = SiS_Pr->SiS_HT;
+ 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
++	    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+ 	 }
+          tempbx >>= 1;
+ 	 tempbx -= 2;
+@@ -8238,7 +8496,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
+          temp = tempbx & 0x00FF;
+          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
+-	 
++
+          if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ 	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+@@ -8246,24 +8504,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHOR
+ 	 }
+ 
+ 	 if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	     /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
+-	     /* 315, 330, 650+301B BIOS don't do this at all */
+-             /* TW: This is a duplicate; done for LCDA as well (see above) */
+-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+-		   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+-	        }
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+-	     }
++	    /* 650/LV BIOS does this for all bridge types - assumingly wrong */
++	    /* 315, 330, 650+301B BIOS don't do this at all */
++            /* This is a duplicate; done for LCDA as well (see above) */
++	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++	       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
++		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
++	       }
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++	    }
+          } else if(HwDeviceExtension->jChipType == SIS_300) {
+-	     /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
+-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+-	     }
++	    /* 300/301LV BIOS does this for all bridge types - assumingly wrong */
++	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
++	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++	    }
+ 	 }
+ 
+   }  /* 301B */
+@@ -8278,21 +8536,26 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USH
+                  USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT vclkindex;
+-  USHORT tempah;
++  USHORT temp, reg1, reg2;
+ 
+-  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+-                              HwDeviceExtension);
++  if(SiS_Pr->UseCustomMode) {
++     reg1 = SiS_Pr->CSR2B;
++     reg2 = SiS_Pr->CSR2C;
++  } else {
++     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
++                                 HwDeviceExtension);
++     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
++     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
++  }
+ 
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
++     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
++     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ 	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+-                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
++                 if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+ 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
+ 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
+ 		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
+@@ -8303,15 +8566,13 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USH
+      }
+   } else {	
+      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
+-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
++     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,reg2);
++     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,reg1);
+   }
+   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
+-  tempah = 0x08;
+-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
+-  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
++  temp = 0x08;
++  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
++  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
+ }
+ 
+ USHORT
+@@ -8319,23 +8580,24 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT tempbx;
+-  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
+-  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
++  const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
++  const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
++  const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
+ #ifdef SIS300
+-  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+-  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+-  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+-  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
++  const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
++  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
++  const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
++  const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
+ #endif
+ #ifdef SIS315H
+-  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+-  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+-  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+-  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
++  const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
++  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
++  const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
++  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
+ #endif
+   USHORT CRT2Index,VCLKIndex=0;
+   USHORT modeflag,resinfo;
+-  const UCHAR *CHTVVCLKPtr=NULL;
++  const UCHAR  *CHTVVCLKPtr = NULL;
+   const USHORT *LCDXlatVCLK1 = NULL;
+   const USHORT *LCDXlatVCLK2 = NULL;
+   const USHORT *LVDSXlatVCLK2 = NULL;
+@@ -8372,33 +8634,40 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+      if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+ 
+         CRT2Index >>= 6;
+-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
++        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
+             if(HwDeviceExtension->jChipType < SIS_315H) {
+-	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
++	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+ 	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
+-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
++	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
++	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+ 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
++	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+ 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+-	       else
++	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++	                VCLKIndex = VCLK81_300;	/* guessed */
++	       } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++		        VCLKIndex = VCLK108_3_300;
++		        if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
++	       } else {
+ 	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
++	       }
+ 	    } else {
+-               /* TW: 330, 650/301LV BIOS does not check expanding, 315 does  */
+-	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
++	       if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
+ 	           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+       	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-		     VCLKIndex = 0x19;
++		     VCLKIndex = VCLK108_2_315;
++		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
++		     VCLKIndex = VCLK81_315;  	/* guessed */
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-		     VCLKIndex = 0x19;
++		     VCLKIndex = VCLK108_2_315;
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+-		     VCLKIndex = 0x21;
++		     VCLKIndex = VCLK162_315;
++		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
++		     VCLKIndex = VCLK108_3_315;
++		     if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
+ 		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ 		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
+-                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+-		     VCLKIndex = 0x45;  /* TW: in VBVCLK table */
+-		     if(resinfo == 0x09) VCLKIndex++;
+ 	          } else {
+ 		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
+       	          }
+@@ -8408,12 +8677,18 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+         	   if(ModeNo > 0x13) {
+           		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+         	   }
+-		   if(ModeNo <= 0x13) {  /* TW: 315 BIOS */
+-		      if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
++		   if(ModeNo <= 0x13) {
++		      if(HwDeviceExtension->jChipType <= SIS_315PRO) {
++		         if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
++	              } else {
++		         if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
++		      }
++		   }
++		   if(HwDeviceExtension->jChipType <= SIS_315PRO) {
++		      if(VCLKIndex == 0) VCLKIndex = 0x41;
++		      if(VCLKIndex == 1) VCLKIndex = 0x43;
++		      if(VCLKIndex == 4) VCLKIndex = 0x44;
+ 		   }
+-		   if(VCLKIndex == 0) VCLKIndex = 0x41;
+-		   if(VCLKIndex == 1) VCLKIndex = 0x43;
+-		   if(VCLKIndex == 4) VCLKIndex = 0x44;
+ 	       }
+ 	    }
+         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
+@@ -8429,9 +8704,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+        			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
+             		else         		              VCLKIndex = TVVCLK;
+           	}
+-		if(HwDeviceExtension->jChipType >= SIS_315H) {
+-              		VCLKIndex += 25;
+-  		}
++		if(HwDeviceExtension->jChipType < SIS_315H) {
++              		VCLKIndex += TVCLKBASE_300;
++  		} else {
++			VCLKIndex += TVCLKBASE_315;
++		}
+         } else {         					/* RAMDAC2 */
+         	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+         	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+@@ -8441,7 +8718,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+           			VCLKIndex &= 0x3f;
+ 				if( (HwDeviceExtension->jChipType == SIS_630) &&
+ 				    (HwDeviceExtension->jChipRevision >= 0x30)) {
+-				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
++				     /* This is certainly wrong: It replaces clock
++				      * 108 by 47...
++				      */
++				     /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
++				     if(VCLKIndex == 0x14) VCLKIndex = 0x34;
+ 				}
+ 			}
+         	}
+@@ -8505,6 +8786,10 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+      		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+ 		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
+      			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
++		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
++		        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
++			SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
++			VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
+      		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+      			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+ 		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+@@ -8513,6 +8798,21 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+                         VCLKIndex = LVDSXlatVCLK2[VCLKIndex];			
+      		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+ 
++		if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++		   /* Special Timing: Barco iQ Pro R300/400/... */
++		   VCLKIndex = 0x44;
++		}
++
++		if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
++		   if(HwDeviceExtension->jChipType < SIS_315H) {
++		      VCLKIndex = VCLK34_300;
++		      /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
++		   } else {
++		      VCLKIndex = VCLK34_315;
++		      /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
++		   }
++		}
++
+ 	   } else {
+ 
+ 	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+@@ -8556,11 +8856,11 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCH
+ #ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+ #endif
+-  return (VCLKIndex);
++  return(VCLKIndex);
+ }
+ 
+-/* TW: Set 301 Palette address port registers */
+-/* TW: Checked against 650/301LV BIOS */
++/* Set 301 Palette address port registers */
++/* Checked against 650/301LV BIOS */
+ void
+ SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
+               UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+@@ -8568,7 +8868,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
+ 
+-  if(SiS_Pr->SiS_ModeType == ModeVGA){
++  if(SiS_Pr->SiS_ModeType == ModeVGA) {
+      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
+         SiS_EnableCRT2(SiS_Pr);
+         SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+@@ -8581,17 +8881,22 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
+                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT temp,tempah,i,modeflag,j;
+-  USHORT ResInfo,DisplayType;
++  USHORT ResIndex,DisplayType;
+   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+ 
+   if(ModeNo <= 0x13) {
+-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+ 
++  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
++     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
++     (SiS_Pr->SiS_CustomT == CUT_PANEL848))
++     return;
++
+   temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+-                            &ResInfo,&DisplayType);
++                            &ResIndex,&DisplayType);
+ 
+   if(temp == 0) return;
+ 
+@@ -8639,47 +8944,53 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
+     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
+     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
+     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
++    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
++    case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
++    case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
++    case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
++    case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
++    case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
+     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
+     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
+   }
+ 
+   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
+ 
+-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
++  tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+ 
+   for(i=0x02,j=1;i<=0x05;i++,j++){
+-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+   }
+   for(i=0x06,j=5;i<=0x07;i++,j++){
+-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+   }
+   for(i=0x10,j=7;i<=0x11;i++,j++){
+-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+   }
+   for(i=0x15,j=9;i<=0x16;i++,j++){
+-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+   }
+   for(i=0x0A,j=11;i<=0x0C;i++,j++){
+-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
++    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+   }
+ 
+-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
++  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
+   tempah &= 0xE0;
+-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     
++  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
+ 
+-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
++  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
+   tempah &= 0x01;
+   tempah <<= 5;
+   if(modeflag & DoubleScanMode)  tempah |= 0x080;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+ 
+-  /* TW: 650/LVDS BIOS - doesn't make sense */
++  /* 650/LVDS BIOS - doesn't make sense */
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      if(modeflag & HalfDCLK)
+         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+@@ -8688,7 +8999,7 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCH
+ 
+ BOOLEAN
+ SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
++		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
+ 		   USHORT *DisplayType)
+  {
+   USHORT tempbx,modeflag=0;
+@@ -8757,19 +9068,33 @@ SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, 
+            tempbx = 40;
+ 	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+ 	   if(modeflag & HalfDCLK) tempbx++;
++        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
++           tempbx = 54;
++	   if(modeflag & HalfDCLK) tempbx++;
++	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
++           tempbx = 52;
++	   if(modeflag & HalfDCLK) tempbx++;
++	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
++           tempbx = 50;
++	   if(modeflag & HalfDCLK) tempbx++;
+         }
++
+      }
+      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+         tempbx = 12;
+ 	if(modeflag & HalfDCLK) tempbx++;
+      }
+   }
+-  if(SiS_Pr->SiS_IF_DEF_FSTN){
++
++#if 0
++  if(SiS_Pr->SiS_IF_DEF_FSTN) {
+      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+         tempbx = 22;
+      }
+   }
+-  *ResInfo = CRT2CRTC & 0x3F;
++#endif
++
++  *ResIndex = CRT2CRTC & 0x3F;
+   *DisplayType = tempbx;
+   return 1;
+ }
+@@ -8778,54 +9103,54 @@ void
+ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-  USHORT tempah,tempal,pushax;
+-  USHORT vclkindex=0;
+-    
++  USHORT clkbase, vclkindex=0;
++  UCHAR  sr2b, sr2c;
++
+   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+ 	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+-        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+-    	tempal &= 0x3F;
+-	if(tempal == 2) RefreshRateTableIndex--;
++        if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
++	   RefreshRateTableIndex--;
++	}
+ 	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-                               RefreshRateTableIndex,HwDeviceExtension);
++                                    RefreshRateTableIndex,HwDeviceExtension);
+ 	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+   } else {
+         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-                               RefreshRateTableIndex,HwDeviceExtension);
++                                    RefreshRateTableIndex,HwDeviceExtension);
+   }
+-  
+-  tempal = 0x02B;
++
++  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
++  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
++
++  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
++     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++	if(ROMAddr[0x220] & 0x01) {
++           sr2b = ROMAddr[0x227];
++	   sr2c = ROMAddr[0x228];
++	}
++     }
++  }
++
++  clkbase = 0x02B;
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+-    	tempal += 3;
++    	clkbase += 3;
+      }
+   }
++
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+-  pushax = tempal;
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+-  tempal++;
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
+-  tempal = pushax;
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+-  tempal++;
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
+-  tempal = pushax;
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+-  tempal++;
+-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+-  return;
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase,sr2b);
++  SiS_SetReg1(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+ }
+ 
+-#if 0  /* TW: Not used */
++#if 0  /* Not used */
+ void
+ SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
+ {
+@@ -8844,7 +9169,7 @@ SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_P
+ }
+ #endif
+ 
+-/* TW: Start of Chrontel 70xx functions ---------------------- */
++/* Start of Chrontel 70xx functions ---------------------- */
+ 
+ /* Set-up the Chrontel Registers */
+ void
+@@ -8890,44 +9215,44 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ 
+ #ifdef SIS300
+-  
+-     /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
+ 
+-     /* TW: We don't support modes >800x600 */
++     /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
++
++     /* We don't support modes >800x600 */
+      if (resindex > 5) return;
+ 
+      if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+-    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+-    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
++    	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
++    	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
+      } else {
+-    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+-    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
++    	SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
++    	SiS_SetCH700x(SiS_Pr,0x7109);	/* Black level for NTSC (113)*/
+      }
+ 
+      temp = CHTVRegData[resindex].Reg[0];
+-     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
++     tempbx=((temp&0x00FF)<<8)|0x00;	/* Mode register */
+      SiS_SetCH700x(SiS_Pr,tempbx);
+      temp = CHTVRegData[resindex].Reg[1];
+-     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
++     tempbx=((temp&0x00FF)<<8)|0x07;	/* Start active video register */
+      SiS_SetCH700x(SiS_Pr,tempbx);
+      temp = CHTVRegData[resindex].Reg[2];
+-     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
++     tempbx=((temp&0x00FF)<<8)|0x08;	/* Position overflow register */
+      SiS_SetCH700x(SiS_Pr,tempbx);
+      temp = CHTVRegData[resindex].Reg[3];
+-     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
++     tempbx=((temp&0x00FF)<<8)|0x0A;	/* Horiz Position register */
+      SiS_SetCH700x(SiS_Pr,tempbx);
+      temp = CHTVRegData[resindex].Reg[4];
+-     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
++     tempbx=((temp&0x00FF)<<8)|0x0B;	/* Vertical Position register */
+      SiS_SetCH700x(SiS_Pr,tempbx);
+ 
+-     /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
++     /* Set minimum flicker filter for Luma channel (SR1-0=00),
+                 minimum text enhancement (S3-2=10),
+    	        maximum flicker filter for Chroma channel (S5-4=10)
+ 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
+       */
+      SiS_SetCH700x(SiS_Pr,0x2801);
+ 
+-     /* TW: Set video bandwidth
++     /* Set video bandwidth
+             High bandwith Luma composite video filter(S0=1)
+             low bandwith Luma S-video filter (S2-1=00)
+ 	    disable peak filter in S-video channel (S3=0)
+@@ -8936,22 +9261,24 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
+      */
+      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
+ 
+-     /* TW: Register 0x3D does not exist in non-macrovision register map
++     /* Register 0x3D does not exist in non-macrovision register map
+             (Maybe this is a macrovision register?)
+       */
+-     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
++#ifndef SIS_CP
++     SiS_SetCH70xx(SiS_Pr,0x003D);
++#endif
+ 
+-     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
++     /* Register 0x10 only contains 1 writable bit (S0) for sensing,
+             all other bits a read-only. Macrovision?
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
+ 
+-     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
++     /* Register 0x11 only contains 3 writable bits (S0-S2) for
+             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
+ 
+-     /* TW: Clear DSEN
++     /* Clear DSEN
+       */
+      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
+ 
+@@ -8994,7 +9321,7 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
+          }
+        }
+      } else {				/* ---- PAL ---- */
+-           /* TW: We don't play around with FSCI in PAL mode */
++           /* We don't play around with FSCI in PAL mode */
+          if (resindex == 0x04) {
+            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
+            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
+@@ -9012,7 +9339,7 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
+ 
+ #ifdef SIS315H
+ 
+-     /* TW: We don't support modes >1024x768 */
++     /* We don't support modes >1024x768 */
+      if (resindex > 6) return;
+ 
+      temp = CHTVRegData[resindex].Reg[0];
+@@ -9082,26 +9409,29 @@ SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHA
+ #endif	/* 315 */
+ 
+   }
++
++#ifdef SIS_CP
++  SIS_CP_INIT301_CP3
++#endif
++
+ }
+ 
+-/* TW: Chrontel 701x functions ================================= */
++/* Chrontel 701x functions ================================= */
+ 
+ void
+-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
++SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-#ifndef NEWCH701x
+   USHORT temp;
+-#endif  
+ 
+-  /* TW: Enable Chrontel 7019 LCD panel backlight */
++  /* Enable Chrontel 7019 LCD panel backlight */
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+-#ifdef NEWCH701x
++     if(HwDeviceExtension->jChipType == SIS_740) {
+         SiS_SetCH701x(SiS_Pr,0x6566);
+-#else  
++     } else {
+         temp = SiS_GetCH701x(SiS_Pr,0x66);
+         temp |= 0x20;
+ 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+-#endif	
++     }
+   }
+ }
+ 
+@@ -9110,7 +9440,7 @@ SiS_Chrontel701xBLOff(SiS_Private *SiS_P
+ {
+   USHORT temp;
+ 
+-  /* TW: Disable Chrontel 7019 LCD panel backlight */
++  /* Disable Chrontel 7019 LCD panel backlight */
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+         temp = SiS_GetCH701x(SiS_Pr,0x66);
+         temp &= 0xDF;
+@@ -9118,47 +9448,54 @@ SiS_Chrontel701xBLOff(SiS_Private *SiS_P
+   }
+ }
+ 
+-#ifdef SIS315H  /* -------- 310/325 series only --------- */
++#ifdef SIS315H  /* ----------- 315 series only ---------- */
+ 
+ void
+ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x  
+-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
+-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+-                        0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; 
+-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 			
+-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,         
+-                        0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 
+-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
+-#else
+-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
+-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+-                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; 
+-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; 			
+-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,   
+-                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; 
+-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
+-#endif			
++  UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
++                            0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
++  UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
++                            0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
++  UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++   			    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
++  UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++                            0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
++  UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
++  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
++  UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
++                            0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
++  UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
++   		   	    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
++  UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
++                            0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
++  UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
++  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
+   UCHAR *tableptr = NULL;
+   USHORT tempbh;
+   int i;
+ 
+-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-     tableptr = table1024;
+-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+-     tableptr = table1280;
+-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+-     tableptr = table1400;
+-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+-     tableptr = table1600;
+-  } else return;
++  if(HwDeviceExtension->jChipType == SIS_740) {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++        tableptr = table1024_740;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++        tableptr = table1280_740;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++        tableptr = table1400_740;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++        tableptr = table1600_740;
++     } else return;
++  } else {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++        tableptr = table1024_650;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++        tableptr = table1280_650;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
++        tableptr = table1400_650;
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
++        tableptr = table1600_650;
++     } else return;
++  }
+ 
+   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
+   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
+@@ -9172,54 +9509,64 @@ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr,
+         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+      }
+   }
+-#ifdef NEWCH701x     /* New from 740/LVDS: */    
+-  for(i=0; i<0x0d; i++) {	
+-#else
+-  for(i=0; i<0x0c; i++) {
+-#endif  
++
++  if(HwDeviceExtension->jChipType == SIS_740) {
++     tempbh = 0x0d;
++  } else {
++     tempbh = 0x0c;
++  }
++  for(i = 0; i < tempbh; i++) {
+      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+   }
+-  SiS_ChrontelPowerSequencing(SiS_Pr);
++  SiS_ChrontelPowerSequencing(SiS_Pr,HwDeviceExtension);
+   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
+   tempbh |= 0xc0;
+   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+-  
+-#ifdef NEWCH701x     /* 740/LVDS: */
+-  tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
+-  tempbh &= 0xfb;
+-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+-  SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
+-  tempbh = SiS_GetCH701x(SiS_Pr,0x64);
+-  tempbh |= 0x40;
+-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+-  tempbh = SiS_GetCH701x(SiS_Pr,0x03);
+-  tempbh &= 0x3f;
+-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+-#endif  /* End 740/LVDS */
++
++  if(HwDeviceExtension->jChipType == SIS_740) {
++     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
++     tempbh &= 0xfb;
++     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
++     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
++     tempbh = SiS_GetCH701x(SiS_Pr,0x64);
++     tempbh |= 0x40;
++     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
++     tempbh = SiS_GetCH701x(SiS_Pr,0x03);
++     tempbh &= 0x3f;
++     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
++  }
+ }
+ 
+ void
+-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
+-{
+-  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+-#ifdef NEWCH701x  
+-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+-  UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+-#else
+-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+-  UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+-#endif  
++SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
++  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
++  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
++  UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
++  UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+   UCHAR *tableptr = NULL;
+   int i;
+ 
+   /* Set up Power up/down timing */
+-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-     tableptr = table1024;
+-  } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+-            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+-	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+-     tableptr = table1400;
+-  } else return;
++
++  if(HwDeviceExtension->jChipType == SIS_740) {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++        tableptr = table1024_740;
++     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++        tableptr = table1400_740;
++     } else return;
++  } else {
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
++        tableptr = table1024_650;
++     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
++               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
++	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
++        tableptr = table1400_650;
++     } else return;
++  }
+   
+   for(i=0; i<5; i++) {
+      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+@@ -9232,66 +9579,72 @@ SiS_Chrontel701xOn(SiS_Private *SiS_Pr, 
+   USHORT temp;
+ 
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+-#ifdef NEWCH701x
+-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
+-     temp |= 0x04;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+-#endif 
++     if(HwDeviceExtension->jChipType == SIS_740) {
++        temp = SiS_GetCH701x(SiS_Pr,0x1c);
++        temp |= 0x04;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
++     }
+      if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+         temp = SiS_GetCH701x(SiS_Pr,0x01);
+ 	temp &= 0x3f;
+-	temp |= 0x80;	/* TW: Enable YPrPb (HDTV) */
++	temp |= 0x80;	/* Enable YPrPb (HDTV) */
+ 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+      }
+      if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+         temp = SiS_GetCH701x(SiS_Pr,0x01);
+ 	temp &= 0x3f;
+-	temp |= 0xc0;	/* TW: Enable SCART + CVBS */
++	temp |= 0xc0;	/* Enable SCART + CVBS */
+ 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+      }
+-#ifdef NEWCH701x
+-     SiS_ChrontelDoSomething5(SiS_Pr);
+-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
+-#else      
+-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
+-     temp = SiS_GetCH701x(SiS_Pr,0x49);
+-     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-        temp = SiS_GetCH701x(SiS_Pr,0x73);
+-	temp |= 0x60;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
++     if(HwDeviceExtension->jChipType == SIS_740) {
++        SiS_ChrontelDoSomething5(SiS_Pr);
++        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
++     } else {
++        SiS_SetCH701x(SiS_Pr,0x2049);   			/* Enable TV path */
++        temp = SiS_GetCH701x(SiS_Pr,0x49);
++        if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++           temp = SiS_GetCH701x(SiS_Pr,0x73);
++	   temp |= 0x60;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
++        }
++        temp = SiS_GetCH701x(SiS_Pr,0x47);
++        temp &= 0x7f;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
++        SiS_LongDelay(SiS_Pr,2);
++        temp = SiS_GetCH701x(SiS_Pr,0x47);
++        temp |= 0x80;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+      }
+-     temp = SiS_GetCH701x(SiS_Pr,0x47);
+-     temp &= 0x7f;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+-     SiS_LongDelay(SiS_Pr,2);
+-     temp = SiS_GetCH701x(SiS_Pr,0x47);
+-     temp |= 0x80;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+-#endif     
+   }
+ }
+ 
+ void
+-SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
++SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+   USHORT temp;
+ 
++  /* Complete power down of LVDS */
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
++     if(HwDeviceExtension->jChipType == SIS_740) {
++        SiS_LongDelay(SiS_Pr,1);
++	SiS_GenericDelay(SiS_Pr,0x16ff);
++	SiS_SetCH701x(SiS_Pr,0xac76);
++	SiS_SetCH701x(SiS_Pr,0x0066);
++     } else {
+         SiS_LongDelay(SiS_Pr,2);
+-	/* TW: Complete power down of LVDS */
+ 	temp = SiS_GetCH701x(SiS_Pr,0x76);
+ 	temp &= 0xfc;
+ 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ 	SiS_SetCH701x(SiS_Pr,0x0066);
++     }
+   }
+ }
+ 
+-#ifdef NEWCH701x
+ void
+ SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
+ {
+      unsigned char temp, temp1;
+-     
++
+      temp1 = SiS_GetCH701x(SiS_Pr,0x49);
+      SiS_SetCH701x(SiS_Pr,0x3e49);
+      temp = SiS_GetCH701x(SiS_Pr,0x47);
+@@ -9303,130 +9656,134 @@ SiS_ChrontelDoSomething5(SiS_Private *Si
+      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+      SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
+ }
+-#endif
+ 
+ void
+ SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+      USHORT temp;
+-     
+-     /* 740/LVDS: */
+-     temp = SiS_GetCH701x(SiS_Pr,0x4a);
+-     temp &= 0x01;
+-     if(!(temp)) {
+-     
+-        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	   temp = SiS_GetCH701x(SiS_Pr,0x49);
+-	   SiS_SetCH701x(SiS_Pr,0x3e49);
+-	}
+-	/* TW: Reset Chrontel 7019 datapath */
++
++     if(HwDeviceExtension->jChipType == SIS_740) {
++        temp = SiS_GetCH701x(SiS_Pr,0x4a);
++        temp &= 0x01;
++        if(!(temp)) {
++
++           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	      temp = SiS_GetCH701x(SiS_Pr,0x49);
++	      SiS_SetCH701x(SiS_Pr,0x3e49);
++	   }
++	   /* Reset Chrontel 7019 datapath */
++           SiS_SetCH701x(SiS_Pr,0x1048);
++           SiS_LongDelay(SiS_Pr,1);
++           SiS_SetCH701x(SiS_Pr,0x1848);
++
++	   if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	      SiS_ChrontelDoSomething5(SiS_Pr);
++	      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
++	   }
++
++        } else {
++
++           temp = SiS_GetCH701x(SiS_Pr,0x5c);
++	   temp &= 0xef;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
++	   temp |= 0x10;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
++	   temp &= 0xef;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
++	   temp = SiS_GetCH701x(SiS_Pr,0x61);
++	   if(!temp) {
++	      SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
++	   }
++        }
++     } else { /* 650 */
++        /* Reset Chrontel 7019 datapath */
+         SiS_SetCH701x(SiS_Pr,0x1048);
+         SiS_LongDelay(SiS_Pr,1);
+         SiS_SetCH701x(SiS_Pr,0x1848);
+-	
+-	if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	   SiS_ChrontelDoSomething5(SiS_Pr);
+-	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+-	}    
+-     } else {
+-     
+-        temp = SiS_GetCH701x(SiS_Pr,0x5c);
+-	temp &= 0xef;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
+-	temp |= 0x10;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
+-	temp &= 0xef;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+-	temp = SiS_GetCH701x(SiS_Pr,0x61);
+-	if(!temp) {
+-	   SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+-	}
+-     }
+-#else /* pre 740/LVDS code */     
+-     /* TW: Reset Chrontel 7019 datapath */
+-     SiS_SetCH701x(SiS_Pr,0x1048);
+-     SiS_LongDelay(SiS_Pr,1);
+-     SiS_SetCH701x(SiS_Pr,0x1848);
+-#endif     
++     }
+ }
+ 
+ void
+ SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+-     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+-        SiS_ChrontelDoSomething5(SiS_Pr);
+-     }
+-#else
+      USHORT temp;
+ 
+-     SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
+-     temp = SiS_GetCH701x(SiS_Pr,0x49);
+-     temp &= 1;
+-     if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
+-	temp = SiS_GetCH701x(SiS_Pr,0x47);
+-	temp &= 0x70;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
+-	SiS_LongDelay(SiS_Pr,3);
+-	temp = SiS_GetCH701x(SiS_Pr,0x47);
+-	temp |= 0x80;
+-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
++     if(HwDeviceExtension->jChipType == SIS_740) {
++
++        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++           SiS_ChrontelDoSomething5(SiS_Pr);
++        }
++
++     } else {
++
++        SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
++        temp = SiS_GetCH701x(SiS_Pr,0x49);
++        temp &= 1;
++        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
++	   temp = SiS_GetCH701x(SiS_Pr,0x47);
++	   temp &= 0x70;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
++	   SiS_LongDelay(SiS_Pr,3);
++	   temp = SiS_GetCH701x(SiS_Pr,0x47);
++	   temp |= 0x80;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
++        }
++
+      }
+-#endif     
+ }
+ 
+ void
+ SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                          USHORT BaseAddr)
+ {
+-#ifdef NEWCH701x
+-     USHORT temp;
+-     
+-     temp = SiS_GetCH701x(SiS_Pr,0x61);
+-     if(temp < 1) {
+-          temp++;
+-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+-     }
+-     SiS_SetCH701x(SiS_Pr,0x4566);
+-     SiS_SetCH701x(SiS_Pr,0xaf76);
+-     SiS_LongDelay(SiS_Pr,1);
+-     SiS_GenericDelay(SiS_Pr,0x16ff);
+-
+-#else
+      USHORT temp,temp1;
+-     
+-     temp1 = 0;
+-     temp = SiS_GetCH701x(SiS_Pr,0x61);
+-     if(temp < 2) {
+-          temp++;
+-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+-	  temp1 = 1;
+-     }
+-     SiS_SetCH701x(SiS_Pr,0xac76);
+-     temp = SiS_GetCH701x(SiS_Pr,0x66);
+-     temp |= 0x5f;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+-     if(ModeNo > 0x13) {
+-         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-	    SiS_GenericDelay(SiS_Pr,0x3ff);
+-	 } else {
+-	    SiS_GenericDelay(SiS_Pr,0x2ff);
+-	 }
+-     } else {
+-         if(!temp1)
+-	    SiS_GenericDelay(SiS_Pr,0x2ff);
++
++     if(HwDeviceExtension->jChipType == SIS_740) {
++
++        temp = SiS_GetCH701x(SiS_Pr,0x61);
++        if(temp < 1) {
++           temp++;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
++        }
++        SiS_SetCH701x(SiS_Pr,0x4566);
++        SiS_SetCH701x(SiS_Pr,0xaf76);
++        SiS_LongDelay(SiS_Pr,1);
++        SiS_GenericDelay(SiS_Pr,0x16ff);
++
++     } else {  /* 650 */
++
++        temp1 = 0;
++        temp = SiS_GetCH701x(SiS_Pr,0x61);
++        if(temp < 2) {
++           temp++;
++	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
++	   temp1 = 1;
++        }
++        SiS_SetCH701x(SiS_Pr,0xac76);
++        temp = SiS_GetCH701x(SiS_Pr,0x66);
++        temp |= 0x5f;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
++        if(ModeNo > 0x13) {
++           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++	      SiS_GenericDelay(SiS_Pr,0x3ff);
++	   } else {
++	      SiS_GenericDelay(SiS_Pr,0x2ff);
++	   }
++        } else {
++           if(!temp1)
++	      SiS_GenericDelay(SiS_Pr,0x2ff);
++        }
++        temp = SiS_GetCH701x(SiS_Pr,0x76);
++        temp |= 0x03;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
++        temp = SiS_GetCH701x(SiS_Pr,0x66);
++        temp &= 0x7f;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
++        SiS_LongDelay(SiS_Pr,1);
++
+      }
+-     temp = SiS_GetCH701x(SiS_Pr,0x76);
+-     temp |= 0x03;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+-     temp = SiS_GetCH701x(SiS_Pr,0x66);
+-     temp &= 0x7f;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+-     SiS_LongDelay(SiS_Pr,1);
+-#endif     
+ }
+ 
+ void
+@@ -9443,9 +9800,9 @@ SiS_ChrontelDoSomething2(SiS_Private *Si
+        temp &= 0x04;
+        if(temp == 0x04) break;
+        
+-#ifdef NEWCH701x
+-       SiS_SetCH701x(SiS_Pr,0xac76);    /* 740/LVDS */
+-#endif       
++       if(HwDeviceExtension->jChipType == SIS_740) {
++          SiS_SetCH701x(SiS_Pr,0xac76);
++       }
+ 
+        SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+ 
+@@ -9463,11 +9820,11 @@ SiS_ChrontelDoSomething2(SiS_Private *Si
+        temp = SiS_GetCH701x(SiS_Pr,0x76);
+        temp |= 0x04;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+-#ifdef NEWCH701x
+-       SiS_SetCH701x(SiS_Pr,0xe078);
+-#else       
+-       SiS_SetCH701x(SiS_Pr,0x6078);
+-#endif       
++       if(HwDeviceExtension->jChipType == SIS_740) {
++          SiS_SetCH701x(SiS_Pr,0xe078);
++       } else {
++          SiS_SetCH701x(SiS_Pr,0x6078);
++       }
+        SiS_LongDelay(SiS_Pr,2);
+     } while(0);
+ 
+@@ -9485,51 +9842,52 @@ SiS_ChrontelDoSomething1(SiS_Private *Si
+      temp &= 0xbf;	/* Set datapath 2 to LVDS */
+      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+      
+-#ifdef NEWCH701x   /* 740/LVDS: */
++     if(HwDeviceExtension->jChipType == SIS_740) {
++
++        temp = SiS_GetCH701x(SiS_Pr,0x1c);
++        temp &= 0xfb;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
++
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
++
++        temp = SiS_GetCH701x(SiS_Pr,0x64);
++        temp |= 0x40;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
++
++        temp = SiS_GetCH701x(SiS_Pr,0x03);
++        temp &= 0x3f;
++        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
++
++        temp = SiS_GetCH701x(SiS_Pr,0x66);
++        if(temp != 0x45) {
++           SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
++           SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
++	   temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
++           SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
++        }
++
++     } else { /* 650 */
+ 
+-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
+-     temp &= 0xfb;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+-     
+-     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+-     
+-     temp = SiS_GetCH701x(SiS_Pr,0x64);
+-     temp |= 0x40;
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+-     
+-     temp = SiS_GetCH701x(SiS_Pr,0x03);
+-     temp &= 0x3f;	
+-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+-     
+-     temp = SiS_GetCH701x(SiS_Pr,0x66);
+-     if(temp != 0x45) {
+         SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+-        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+-	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+-        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+-     }     
+ 
+-#else  /* pre-740/LVDS: */     
++        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+ 
+-     SiS_ChrontelResetDB(SiS_Pr);
++        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
++        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+ 
+-     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
++        SiS_SetCH701x(SiS_Pr,0xaf76);
+ 
+-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+-     SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
++     }
+ 
+-     SiS_SetCH701x(SiS_Pr,0xaf76);
+-     
+-#endif  /* End of pre-740/LVDS */
+ }
+ 
+-#endif  /* 310/325 series --------------------------------- */
++#endif  /* 315 series ------------------------------------ */
+ 
+-/* TW: End of Chrontel 701x functions ==================================== */
++/* End of Chrontel 701x functions ==================================== */
+ 
+-/* TW: Generic Read/write routines for Chrontel ========================== */
++/* Generic Read/write routines for Chrontel ========================== */
+ 
+-/* TW: The Chrontel is connected to the 630/730 via
++/* The Chrontel is connected to the 630/730 via
+  * the 630/730's DDC/I2C port.
+  *
+  * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
+@@ -9539,13 +9897,13 @@ SiS_ChrontelDoSomething1(SiS_Private *Si
+ void
+ SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
++   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+       SiS_SetCH700x(SiS_Pr,tempbx);
+    else
+       SiS_SetCH701x(SiS_Pr,tempbx);
+ }
+ 
+-/* TW: Write to Chrontel 700x */
++/* Write to Chrontel 700x */
+ /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+ void
+ SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+@@ -9553,100 +9911,100 @@ SiS_SetCH700x(SiS_Private *SiS_Pr, USHOR
+   USHORT tempah,temp,i;
+ 
+   if(!(SiS_Pr->SiS_ChrontelInit)) {
+-     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
++     SiS_Pr->SiS_DDC_Index = 0x11;		   /* Bit 0 = SC;  Bit 1 = SD */
+      SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
+      SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
+      SiS_Pr->SiS_DDC_DataShift = 0x00;
+-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
++     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* DAB (Device Address Byte) */
+   }
+ 
+-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
++  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
+     /* SiS_SetSwitchDDC2(SiS_Pr); */
+-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
++    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+-    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
+-    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
++    if(temp) continue;				/*    (ERROR: no ack) */
++    tempah = tempbx & 0x00FF;			/* Write RAB */
++    tempah |= 0x80;                             /* (set bit 7, see datasheet) */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
++    if(temp) continue;				/*    (ERROR: no ack) */
+     tempah = (tempbx & 0xFF00) >> 8;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
++    if(temp) continue;				/*    (ERROR: no ack) */
++    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
+     SiS_Pr->SiS_ChrontelInit = 1;
+     return;
+   }
+ 
+-  /* TW: For 630ST */
++  /* For 630ST */
+   if(!(SiS_Pr->SiS_ChrontelInit)) {
+-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
++     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 7 = SC;  Bit 6 = SD */
+      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
+      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+      SiS_Pr->SiS_DDC_DataShift = 0x00;
+-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
++     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
+ 
+-     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
++     for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
+        /* SiS_SetSwitchDDC2(SiS_Pr); */
+-       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
++       if (SiS_SetStart(SiS_Pr)) continue;	/* Set start condition */
+        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+-       if(temp) continue;			/* TW:    (ERROR: no ack) */
+-       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
+-       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
++       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
++       if(temp) continue;			/*    (ERROR: no ack) */
++       tempah = tempbx & 0x00FF;		/* Write RAB */
++       tempah |= 0x80;                          /* (set bit 7, see datasheet) */
+        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+-       if(temp) continue;			/* TW:    (ERROR: no ack) */
++       if(temp) continue;			/*    (ERROR: no ack) */
+        tempah = (tempbx & 0xFF00) >> 8;
+-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
+-       if(temp) continue;			/* TW:    (ERROR: no ack) */
+-       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
++       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
++       if(temp) continue;			/*    (ERROR: no ack) */
++       if(SiS_SetStop(SiS_Pr)) continue;	/* Set stop condition */
+        SiS_Pr->SiS_ChrontelInit = 1;
+        return;
+     }
+   }
+ }
+ 
+-/* TW: Write to Chrontel 701x */
++/* Write to Chrontel 701x */
+ /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
+ void
+ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+   USHORT tempah,temp,i;
+ 
+-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
++  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
+   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+   SiS_Pr->SiS_DDC_DataShift = 0x00;
+-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
++  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
+ 
+-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
+-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
++  for(i=0;i<10;i++) {	/* Do only 10 attempts to write */
++    if (SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
++    if(temp) continue;				/*    (ERROR: no ack) */
+     tempah = tempbx & 0x00FF;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write RAB */
++    if(temp) continue;				/*    (ERROR: no ack) */
+     tempah = (tempbx & 0xFF00) >> 8;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
+-    if(temp) continue;				/* TW:    (ERROR: no ack) */
+-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
++    if(temp) continue;				/*    (ERROR: no ack) */
++    if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
+     return;
+   }
+ }
+ 
+-/* TW: Read from Chrontel 70xx */
++/* Read from Chrontel 70xx */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
++   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+       return(SiS_GetCH700x(SiS_Pr,tempbx));
+    else
+       return(SiS_GetCH701x(SiS_Pr,tempbx));
+ }
+ 
+-/* TW: Read from Chrontel 700x */
++/* Read from Chrontel 700x */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+@@ -9654,57 +10012,57 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHOR
+   USHORT tempah,temp,i;
+ 
+   if(!(SiS_Pr->SiS_ChrontelInit)) {
+-     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
++     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
+      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
+      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
+      SiS_Pr->SiS_DDC_DataShift = 0x00;
+-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
++     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
+   }
+ 
+   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+ 
+-  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
++  for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
+     /* SiS_SetSwitchDDC2(SiS_Pr); */
+-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
++    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+-    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
++    if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
+     SiS_Pr->SiS_ChrontelInit = 1;
+     return(tempah);
+   }
+ 
+-  /* TW: For 630ST */
++  /* For 630ST */
+   if(!SiS_Pr->SiS_ChrontelInit) {
+-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
++     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 0 = SC;  Bit 1 = SD */
+      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
+      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+      SiS_Pr->SiS_DDC_DataShift = 0x00;
+-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
++     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* DAB (Device Address Byte) */
+ 
+-     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
++     for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
+        /* SiS_SetSwitchDDC2(SiS_Pr); */
+-       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
++       if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
+-       if(temp) continue;				/* TW:        (ERROR: no ack) */
+-       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
++       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* Write DAB (S0=0=write) */
++       if(temp) continue;				/*        (ERROR: no ack) */
++       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* Write RAB | 0x80 */
+        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+-       if(temp) continue;				/* TW:        (ERROR: no ack) */
+-       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
++       if(temp) continue;				/*        (ERROR: no ack) */
++       if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
+        tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
+-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
+-       if(temp) continue;				/* TW:        (ERROR: no ack) */
+-       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+-       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
++       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* DAB (S0=1=read) */
++       if(temp) continue;				/*        (ERROR: no ack) */
++       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
++       if (SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
+        SiS_Pr->SiS_ChrontelInit = 1;
+        return(tempah);
+      }
+@@ -9712,52 +10070,51 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHOR
+   return(0xFFFF);
+ }
+ 
+-/* TW: Read from Chrontel 701x */
++/* Read from Chrontel 701x */
+ /* Parameter is [Register no (S7-S0)] */
+ USHORT
+ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+ {
+   USHORT tempah,temp,i;
+ 
+-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
++  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
+   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+   SiS_Pr->SiS_DDC_DataShift = 0x00;
+-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
++  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
+   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+ 
+-   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
+-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
++   for(i=0;i<20;i++) {	/* Do only 20 attempts to read */
++    if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* Write RAB */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    if (SiS_SetStart(SiS_Pr)) continue;		/* Re-start */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
+-    if(temp) continue;				/* TW:        (ERROR: no ack) */
+-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+-    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
++    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
++    if(temp) continue;				/*        (ERROR: no ack) */
++    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
++    SiS_SetStop(SiS_Pr);			/* Stop condition */
+     return(tempah);
+    }
+   return 0xFFFF;
+ }
+ 
+-#ifdef LINUX_XF86
+-/* TW: Our own DDC functions */
++/* Our own DDC functions */
+ USHORT
+-SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
+-		BOOLEAN checkcr32)
++SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++                USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
+ {
+      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
+      unsigned char flag, cr32;
+      USHORT        temp = 0, myadaptnum = adaptnum;
+ 
+      if(adaptnum != 0) {
+-        if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
+-	if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
++        if(!(VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
++	if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+      }	
+      
+      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
+@@ -9771,8 +10128,9 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+      flag = 0xff;
+ 
+      cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
+-  
+-     if(pSiS->VBFlags & VB_SISBRIDGE) {
++
++#if 0
++     if(VBFlags & VB_SISBRIDGE) {
+ 	if(myadaptnum == 0) {
+ 	   if(!(cr32 & 0x20)) {
+ 	      myadaptnum = 2;
+@@ -9785,18 +10143,19 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+ 	   }
+         }
+      }
++#endif
+ 
+-     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
++     if(VGAEngine == SIS_300_VGA) {		/* 300 series */
+ 	
+         if(myadaptnum != 0) {
+ 	   flag = 0;
+-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
++	   if(VBFlags & VB_SISBRIDGE) {
+ 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+               SiS_Pr->SiS_DDC_Index = 0x0f;
+ 	   }
+         }
+ 
+-	if(!(pSiS->VBFlags & VB_301)) {
++	if(!(VBFlags & VB_301)) {
+ 	   if((cr32 & 0x80) && (checkcr32)) {
+               if(myadaptnum >= 1) {
+ 	         if(!(cr32 & 0x08)) {
+@@ -9810,11 +10169,11 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+ 	temp = 4 - (myadaptnum * 2);
+ 	if(flag) temp = 0;
+ 
+-     } else {						/* 310/325/330 series */
++     } else {						/* 315/330 series */
+ 
+      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
+ 	
+-	if(pSiS->VBFlags & VB_SISBRIDGE) {
++	if(VBFlags & VB_SISBRIDGE) {
+ 	   if(myadaptnum == 2) {
+ 	      myadaptnum = 1;
+            }
+@@ -9822,7 +10181,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+ 
+         if(myadaptnum == 1) {
+      	   flag = 0;
+-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
++	   if(VBFlags & VB_SISBRIDGE) {
+ 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+               SiS_Pr->SiS_DDC_Index = 0x0f;
+ 	   }
+@@ -9840,7 +10199,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+         temp = myadaptnum;
+         if(myadaptnum == 1) {
+            temp = 0;
+-	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
++	   if(VBFlags & VB_LVDS) flag = 0xff;
+         }
+ 
+ 	if(flag) temp = 0;
+@@ -9852,7 +10211,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, SIS
+ #ifdef TWDEBUG
+     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
+     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
+-#endif	 
++#endif
+     
+     return 0;
+ }
+@@ -9862,15 +10221,9 @@ SiS_WriteDABDDC(SiS_Private *SiS_Pr)
+ {
+    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
+-#ifdef TWDEBUG
+-        xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
+-#endif	 
+   	return 0xFFFF;
+    }
+    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
+-#ifdef TWDEBUG
+-        xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
+-#endif	 
+    	return 0xFFFF;
+    }
+    return(0);
+@@ -9881,9 +10234,6 @@ SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
+ {
+    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
+-#ifdef TWDEBUG
+-        xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
+-#endif	 
+    	return 0xFFFF;
+    }
+    return(0);
+@@ -9921,9 +10271,6 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
+     SiS_SetSwitchDDC2(SiS_Pr);
+     if(SiS_PrepareDDC(SiS_Pr)) {
+          SiS_SetStop(SiS_Pr);
+-#ifdef TWDEBUG
+-	 xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
+-#endif	 
+          return(0xFFFF);
+     }
+     mask = 0xf0;
+@@ -9972,7 +10319,7 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
+ }
+ 
+ USHORT
+-SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
++SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
+ {
+    USHORT flag, length, i;
+    unsigned char chksum,gotcha;
+@@ -10004,28 +10351,7 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr 
+    return(flag);
+ }
+ 
+-USHORT
+-SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
+-{
+-   USHORT i=0, flag=0;
+-
+-   length--;
+-   
+-   SiS_SetSwitchDDC2(SiS_Pr);
+-   if(!(SiS_PrepareDDC(SiS_Pr))) {
+-      for(i=0; i<length; i++) {
+-         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+-         SiS_SendACK(SiS_Pr, 0);
+-      }
+-      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+-      SiS_SendACK(SiS_Pr, 1);
+-   } else flag = 0xFFFF;
+-   
+-   SiS_SetStop(SiS_Pr);
+-   return(0);
+-}
+-
+-/* TW: Our private DDC function
++/* Our private DDC functions
+ 
+    It complies somewhat with the corresponding VESA function
+    in arguments and return values.
+@@ -10036,7 +10362,7 @@ SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHO
+ 
+    Arguments:
+        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
+-                 CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
++                 CRT2 DDC is only supported on SiS301, 301B, 302B.
+        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
+        buffer: ptr to 256 data bytes which will be filled with read data.
+ 
+@@ -10046,43 +10372,48 @@ SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHO
+ 
+  */
+ USHORT
+-SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+-              USHORT DDCdatatype, unsigned char *buffer)
++SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
+ {
+    if(adaptnum > 2) return 0xFFFF;
+    if(DDCdatatype > 4) return 0xFFFF;
+-   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
++   if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
++   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+    if(DDCdatatype == 0) {
+        return(SiS_ProbeDDC(SiS_Pr));
+    } else {
+-       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
++       return(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer));
+    }
+ }
+ 
++#ifdef LINUX_XF86
+ /* Sense the LCD parameters (CR36, CR37) via DDC */
+ /* SiS30x(B) only */
+ USHORT
+ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+ {
+-   USHORT DDCdatatype, paneltype, flag, xres, yres;
++   USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
+    USHORT index, myindex, lumsize, numcodes;
+    unsigned char cr37=0, seekcode;
+    BOOLEAN checkexpand = FALSE;
+    int retry, i;
+    unsigned char buffer[256];
+-   
++
++   for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
++   SiS_Pr->CP_HaveCustomData = FALSE;
++   SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
++
+    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+    if(pSiS->VBFlags & VB_30xBDH) return 0;
+   
+-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
++   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
+    
+    SiS_Pr->SiS_DDC_SecAddr = 0x00;
+    
+    /* Probe supported DA's */
+    flag = SiS_ProbeDDC(SiS_Pr);
+ #ifdef TWDEBUG   
+-   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
++   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+    	"CRT2 DDC capabilities 0x%x\n", flag);
+ #endif	
+    if(flag & 0x10) {
+@@ -10099,7 +10430,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+    /* Read the entire EDID */
+    retry = 2;
+    do {
+-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
++      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+ 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
+ 		(3-retry), (retry == 1) ? "giving up" : "retrying");
+@@ -10132,7 +10463,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+       }
+       
+       if((buffer[0x18] & 0x18) != 0x08) {
+-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+ 	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", 
+ 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
+ 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : 
+@@ -10140,103 +10471,226 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+ 		buffer[0x18]);
+ 	 return 0;
+       }
+-      
+-      /* Now analyze the first Detailed Timing Block and hope
+-       * that the preferred timing mode is stored there.
+-       */	
+-      xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+-      yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
++
++      /* Now analyze the first Detailed Timing Block and see
++       * if the preferred timing mode is stored there. If so,
++       * check if this is a standard panel for which we already
++       * know the timing.
++       */
++
++      paneltype = Panel_Custom;
+       checkexpand = FALSE;
+-      switch(xres) {
+-         case 800:
+-	     if(yres == 600) {
+-	     	paneltype = Panel310_800x600;
+-	     	checkexpand = TRUE;
+-	     }
+-	     break;
+-         case 1024:
+-	     if(yres == 768) {
+-	     	paneltype = Panel310_1024x768;
+-	     	checkexpand = FALSE;    /* expand causes error at 640x480, should otherwise be TRUE; */
+-	     }
+-	     break;
+-	 case 1280:
+-	     if(yres == 960) {
+-	        if(pSiS->VGAEngine == SIS_300_VGA) {
+-		   paneltype = Panel300_1280x960;
+-		} else {
+-		   paneltype = Panel310_1280x960; 
+-		}
+-	     } else if(yres == 1024) {
+-	     	paneltype = Panel310_1280x1024;  
+-		checkexpand = TRUE;
+-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
++
++      if(buffer[0x18] & 0x02) {
++
++         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
++         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
++
++	 SiS_Pr->CP_PreferredX = xres;
++	 SiS_Pr->CP_PreferredY = yres;
++
++         switch(xres) {
++            case 800:
++	        if(yres == 600) {
++	     	   paneltype = Panel_800x600;
++	     	   checkexpand = TRUE;
++	        }
++	        break;
++            case 1024:
+ 	        if(yres == 768) {
+-	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
+-		   checkexpand = TRUE;	
+-	        }	
+-	     }
+-	     break;
+-	 case 1400:
+-	     if(pSiS->VGAEngine == SIS_315_VGA) {
+-	        if(yres == 1050) {
+-	           paneltype = Panel310_1400x1050;
+-		   checkexpand = TRUE; 
+-	        } 
+-	     }
+-      	     break;
+-	 case 1600:
+-	     if(pSiS->VGAEngine == SIS_315_VGA) {
+-	        if(yres == 1200) {
+-	           paneltype = Panel310_1600x1200;
++	     	   paneltype = Panel_1024x768;
++	     	   checkexpand = TRUE;
++	        }
++	        break;
++	    case 1280:
++	        if(yres == 1024) {
++	     	   paneltype = Panel_1280x1024;
+ 		   checkexpand = TRUE;
+-	        } 
+-	     }
+-      	     break;
++	        } else if(yres == 960) {
++	           if(pSiS->VGAEngine == SIS_300_VGA) {
++		      paneltype = Panel300_1280x960;
++		   } else {
++		      paneltype = Panel310_1280x960;
++		   }
++	        } else if(yres == 768) {
++	       	   paneltype = Panel_1280x768;
++		   checkexpand = FALSE;
++		   cr37 |= 0x10;
++	        }
++	        break;
++	    case 1400:
++	        if(pSiS->VGAEngine == SIS_315_VGA) {
++	           if(yres == 1050) {
++	              paneltype = Panel310_1400x1050;
++		      checkexpand = TRUE;
++	           }
++	        }
++      	        break;
++#if 0	    /* Treat this as custom, as we have no valid timing data yet */
++	    case 1600:
++	        if(pSiS->VGAEngine == SIS_315_VGA) {
++	           if(yres == 1200) {
++	              paneltype = Panel310_1600x1200;
++		      checkexpand = TRUE;
++	           }
++	        }
++      	        break;
++#endif
++         }
++
++	 if(paneltype != Panel_Custom) {
++	    if((buffer[0x47] & 0x18) == 0x18) {
++	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
++	    } else {
++	       /* What now? There is no digital separate output timing... */
++	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++	       	   "CRT2: Unable to retrieve Sync polarity information\n");
++	    }
++	 }
++
+       }
+ 
+-      if(buffer[0x18] & 0x02) {
+-         /* If the preferred timing mode is stored in the first
+-	  * detailed timing block, we now can extract the sync
+-	  * polarisation information as well. This only works
+-	  * if the Flags indicate a digital separate output.
+-	  */
+-	  if((buffer[0x47] & 0x18) == 0x18) {
+-	     cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+-	  } else {
+-	     /* What now? There is no digital separate output timing... */
+-	     xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+-	     	"CRT2: Unable to retrieve Sync polarity information\n");
+-	  }
+-	  
+-      } else {
+-         /* If the preferred timing mode is *not* stored in the first
+-	  * detailed timing block, we need to guess the resolution
+-	  * from the supported Established Timings and assume the
+-	  * default sync polarity
+-	  */
++      /* If we still don't know what panel this is, we take it
++       * as a custom panel and derive the timing data from the
++       * detailed timing blocks
++       */
++      if(paneltype == Panel_Custom) {
++
++         BOOLEAN havesync = FALSE;
++	 int i, temp, base = 0x36;
++	 unsigned long estpack;
++	 unsigned short estx[] = {
++	 	720, 720, 640, 640, 640, 640, 800, 800,
++		800, 800, 832,1024,1024,1024,1024,1280,
++		1152
++	 };
++	 unsigned short esty[] = {
++	 	400, 400, 480, 480, 480, 480, 600, 600,
++		600, 600, 624, 768, 768, 768, 768,1024,
++		870
++	 };
++
+ 	 paneltype = 0;
+-	 if(buffer[0x24] & 0x01) { 	
+-	 	paneltype = Panel310_1280x1024;
+-		checkexpand = TRUE;
+-		cr37 |= 0x20;
+-	 } else if(buffer[0x24] & 0x0e) {
+-	 	paneltype = Panel310_1024x768;
+-		cr37 |= 0xe0;
+-		checkexpand = FALSE;		/* Bug at 640x480 */
+-	 } else if(buffer[0x23] & 0x01) {
+-	 	paneltype = Panel310_800x600;
+-		cr37 |= 0xe0;
+-		checkexpand = TRUE;
+-         }
++
++	 /* Find the maximum resolution */
++
++	 /* 1. From Established timings */
++	 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
++	 for(i=16; i>=0; i--) {
++	     if(estpack & (1 << i)) {
++	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
++		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
++	     }
++	 }
++
++	 /* 2. From Standard Timings */
++	 for(i=0x26; i < 0x36; i+=2) {
++	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
++	       temp = (buffer[i] + 31) * 8;
++	       if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
++	       switch((buffer[i+1] & 0xc0) >> 6) {
++	       case 0x03: temp = temp * 9 / 16; break;
++	       case 0x02: temp = temp * 4 / 5;  break;
++	       case 0x01: temp = temp * 3 / 4;  break;
++	       }
++	       if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
++	    }
++	 }
++
++	 /* Now extract the Detailed Timings and convert them into modes */
++
++         for(i = 0; i < 4; i++, base += 18) {
++
++	    /* Is this a detailed timing block or a monitor descriptor? */
++	    if(buffer[base] || buffer[base+1] || buffer[base+2]) {
++
++      	       xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
++               yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
++
++	       SiS_Pr->CP_HDisplay[i] = xres;
++	       SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
++               SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
++	       SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
++	       SiS_Pr->CP_HBlankStart[i] = xres + 1;
++	       SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
++
++	       SiS_Pr->CP_VDisplay[i] = yres;
++               SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
++               SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
++	       SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
++	       SiS_Pr->CP_VBlankStart[i] = yres + 1;
++	       SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
++
++	       SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
++
++	       SiS_Pr->CP_DataValid[i] = TRUE;
++
++	       /* Sort out invalid timings, interlace and too high clocks */
++	       if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
++	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
++	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
++	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
++	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
++	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
++	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
++	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
++	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
++	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
++	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
++	          (SiS_Pr->CP_Clock[i] > 108000)                       ||
++		  (buffer[base+17] & 0x80)) {
++
++	          SiS_Pr->CP_DataValid[i] = FALSE;
++
++	       } else {
++
++	          paneltype = Panel_Custom;
++
++		  SiS_Pr->CP_HaveCustomData = TRUE;
++
++		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
++	          if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
++		  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
++
++		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
++		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
++
++	          /* We must assume the panel can scale, since we have
++	           * no scaling data
++		   */
++	          checkexpand = FALSE;
++	          cr37 |= 0x10;
++
++	          /* Extract the sync polarisation information. This only works
++	           * if the Flags indicate a digital separate output.
++	           */
++	          if((buffer[base+17] & 0x18) == 0x18) {
++		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
++		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
++		     SiS_Pr->CP_SyncValid[i] = TRUE;
++		     if(!havesync) {
++	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
++			havesync = TRUE;
++	   	     }
++	          } else {
++		     SiS_Pr->CP_SyncValid[i] = FALSE;
++		  }
++	       }
++            }
++	 }
++	 if(!havesync) {
++	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++	       	   "CRT2: Unable to retrieve Sync polarity information\n");
++   	 }
+       }
+-      
+-      if(checkexpand) {
+-         /* If any of the Established low-res modes is supported, the 
++
++      if(paneltype && checkexpand) {
++         /* If any of the Established low-res modes is supported, the
+ 	  * panel can scale automatically. For 800x600 panels, we only 
+ 	  * check the even lower ones.
+ 	  */
+-	 if(paneltype == Panel310_800x600) {
++	 if(paneltype == Panel_800x600) {
+ 	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
+ 	 } else {
+             if(buffer[0x23])	    cr37 |= 0x10;
+@@ -10262,20 +10716,31 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+ 		buffer[0x41]);
+ 	 return 0;
+       }
+-   
+-      xres = buffer[0x76] | (buffer[0x77] << 8);
+-      yres = buffer[0x78] | (buffer[0x79] << 8);
++
++      paneltype = Panel_Custom;
++      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
++      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
+       switch(xres) {
+          case 800:
+ 	     if(yres == 600) {
+-	     	paneltype = Panel310_800x600;
++	     	paneltype = Panel_800x600;
+ 	     	checkexpand = TRUE;
+ 	     }
+ 	     break;
+          case 1024:
+ 	     if(yres == 768) {
+-	     	paneltype = Panel310_1024x768;
+-	     	checkexpand = FALSE;			/* Bug at 640x480; we do the scaling ourselves */
++	     	paneltype = Panel_1024x768;
++	     	checkexpand = TRUE;
++	     }
++	     break;
++	 case 1152:
++	     if(yres == 768) {
++	        if(pSiS->VGAEngine == SIS_300_VGA) {
++		   paneltype = Panel300_1152x768;
++		} else {
++		   paneltype = Panel310_1152x768;
++		}
++	     	checkexpand = TRUE;
+ 	     }
+ 	     break;
+ 	 case 1280:
+@@ -10286,45 +10751,46 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+ 		   paneltype = Panel300_1280x960;
+ 		}
+ 	     } else if(yres == 1024) {
+-	     	paneltype = Panel310_1280x1024;  
++	     	paneltype = Panel_1280x1024;
+ 		checkexpand = TRUE;
+-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
+-	        if(yres == 768) {
+-	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
+-		   checkexpand = TRUE;
+-	        }
+-	     } 
++	     } else if(yres == 768) {
++	        paneltype = Panel_1280x768;
++		checkexpand = FALSE;
++		cr37 |= 0x10;
++	     }
+ 	     break;
+ 	 case 1400:
+ 	     if(pSiS->VGAEngine == SIS_315_VGA) {
+ 	        if(yres == 1050) {
+ 	           paneltype = Panel310_1400x1050;
+ 		   checkexpand = TRUE;
+-	        } 
++	        }
+ 	     }
+       	     break;
++#if 0    /* Treat this one as custom since we have no timing data yet */
+ 	 case 1600:
+ 	     if(pSiS->VGAEngine == SIS_315_VGA) {
+ 	        if(yres == 1200) {
+ 	           paneltype = Panel310_1600x1200;
+ 		   checkexpand = TRUE;
+-	        } 
++	        }
+ 	     }
+       	     break;
++#endif
+       }
+-                 
++
+       /* Determine if RGB18 or RGB24 */
+       if(index) {
+          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
+ 	    cr37 |= 0x01;
+ 	 }
+       }
+-      
++
+       if(checkexpand) {
+          /* TODO - for now, we let the panel scale */
+ 	 cr37 |= 0x10;
+       }
+-     
++
+       /* Now seek 4-Byte Timing codes and extract sync pol info */
+       index = 0x80;
+       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
+@@ -10346,28 +10812,117 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SIS
+ 	 if(buffer[myindex] == seekcode) {
+ 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
+ 	 } else {
+-	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+-	    	"CRT2: Unable to retrieve Sync polarity information\n");    
++	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++	        "CRT2: Unable to retrieve Sync polarity information\n");
+ 	 }
+       } else {
+-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+-	    	"CRT2: Unable to retrieve Sync polarity information\n");
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
++	     "CRT2: Unable to retrieve Sync polarity information\n");
++      }
++
++      /* Now seek the detailed timing descriptions for custom panels */
++      if(paneltype == Panel_Custom) {
++         index += (numcodes * 4);
++	 numcodes = buffer[0x7f] & 0x07;
++	 for(i=0; i<numcodes; i++) {
++	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
++            yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
++
++	    SiS_Pr->CP_HDisplay[i] = xres;
++	    SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
++            SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
++	    SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
++	    SiS_Pr->CP_HBlankStart[i] = xres + 1;
++	    SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
++
++	    SiS_Pr->CP_VDisplay[i] = yres;
++            SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
++            SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
++	    SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
++	    SiS_Pr->CP_VBlankStart[i] = yres + 1;
++	    SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
++
++	    SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
++
++	    SiS_Pr->CP_DataValid[i] = TRUE;
++
++	    if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
++	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
++	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
++	       (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
++	       (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
++	       (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
++	       (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
++	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
++	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
++	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
++	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
++	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
++	       (SiS_Pr->CP_Clock[i] > 108000)                       ||
++	       (buffer[index + 17] & 0x80)) {
++
++	       SiS_Pr->CP_DataValid[i] = FALSE;
++
++	    } else {
++
++	       SiS_Pr->CP_HaveCustomData = TRUE;
++
++	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
++
++	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
++	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
++	       SiS_Pr->CP_SyncValid[i] = TRUE;
++
++	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
++	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
++
++	       /* We must assume the panel can scale, since we have
++	        * no scaling data
++    	        */
++	       cr37 |= 0x10;
++
++	    }
++	 }
++
+       }
+ 
+       break;
+-     
++
+    }
+-   
++
+    /* 1280x960 panels are always RGB24, unable to scale and use
+     * high active sync polarity
+     */
+    if(pSiS->VGAEngine == SIS_315_VGA) {
+-      if(paneltype == Panel310_1280x960) cr37 &= 0x0e; 
++      if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
+    } else {
+-      if(paneltype == Panel300_1280x960) cr37 &= 0x0e; 
++      if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
+    }
+-   
++
++   for(i = 0; i < 7; i++) {
++      if(SiS_Pr->CP_DataValid[i]) {
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++            "Non-standard LCD timing data no. %d:\n", i);
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
++	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
++	    SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++            "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
++            SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
++   	    SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
++         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
++	    "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
++	 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
++	    "   To use this, add \"%dx%d\" to the list of Modes in the Display section\n",
++	    SiS_Pr->CP_HDisplay[i],
++	    SiS_Pr->CP_VDisplay[i]);
++      }
++   }
++
+    if(paneltype) {
++       if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
++       if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
+        cr37 &= 0xf1;
+        cr37 |= 0x02;    /* SiS301 */
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
+@@ -10392,7 +10947,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
+    if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+ /* if(pSiS->VBFlags & VB_30xBDH) return 0;  */
+    
+-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
++   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
+    
+    SiS_Pr->SiS_DDC_SecAddr = 0x00;
+    
+@@ -10416,7 +10971,7 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
+    /* Read the entire EDID */
+    retry = 2;
+    do {
+-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
++      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+ 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
+ 		(3-retry), (retry == 1) ? "giving up" : "retrying");
+@@ -10435,6 +10990,8 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
+ 	  	"CRT2: Attached display expects digital input\n");
+       	  return 0;  	
+       }
++      SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
++      SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
+       foundcrt = TRUE;
+       break;
+    case 3:
+@@ -10448,198 +11005,19 @@ SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SI
+ 		buffer[0x41]);
+ 	  return 0;
+       }
++      SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
++      SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
+       foundcrt = TRUE;
+-      break;	  
++      break;
+    }
+-   
++
+    if(foundcrt) {
+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
+    }
+    return(0);
+ }
+ 
+-#if 0
+-   /* ----- */
+-USHORT
+-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+-{
+-   USHORT DDCdatatype, paneltype, flag;
+-   unsigned char cr36=0, cr37=0;
+-   unsigned char tempal, tempah, tempbl, tempbh;
+-   USHORT tempax, tempbx, tempcx, push1, push2, push3;
+-   unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
+-   int i;
+-   unsigned char buffer[256];
+-   
+-   if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
+-   if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
+-   
+-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;   
+-   
+-   flag = SiS_ProbeDDC(SiS_Pr);
+-   if(flag & 0x02) {
+-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
+-      DDCdatatype = 1;
+-      SiS_Pr->SiS_DDC_SecAddr = 0x3a;
+-   } else if(flag & 0x08) {
+-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
+-      DDCdatatype = 3;
+-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
+-   } else if(flag & 0x10) {
+-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
+-      DDCdatatype = 4;
+-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
+-   } else return 0xFFFF;
+-   
+-   
+-   SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
+-   tempbl = buffer[0];  /* 3a - 76 */
+-   tempbh = buffer[1];  /* 3b - 77 */
+-   
+-   if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+-   
+-      /* Read and analyze EDID V1 (res) */
+-   
+-      tempah = 0x02;				/* 1024x768 by default */
+-      tempbl &= 0xf0;
+-      if(tempbl != 0x40) {			
+-         tempah = 0x03;				/* 1280x1024 by default */
+-	 if(tempbl == 0x50) {
+-	    if(!tempbh) {
+-	       tempbh = buffer[3] & 0xf0;
+-	       if(tempbh == 0x30) {
+-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
+-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-		   tempbl = buffer[0];  /* 0x23 */
+-		   tempbh = buffer[1];  /* 0x24 */
+-		   if(tempbl) cr37 |= 0x10;
+-		   tempah = 0x0a;		/* 1280x768 */
+-	       }
+-	       if(tempbh == 0x40) {
+-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
+-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-		   tempbl = buffer[0];  /* 0x23 */
+-		   tempbh = buffer[1];  /* 0x24 */
+-		   if(tempbl) cr37 |= 0x10;
+-		   tempah = 0x03;		/* 1280x1024 */
+-	       }
+-	       tempbh = 0x00;
+-	    }
+-	 }
+-	 if(tempbh == 0x00) goto cr36ready;
+-	 tempah = 0x07;				/* 1280x960 */
+-	 if(tempbh == 0xc0) goto cr36ready;
+-      }
+-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+-      SiS_Pr->SiS_DDC_SecAddr = 0x18;		/* feature support */
+-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-      tempbl = buffer[0];
+-      tempbh = buffer[1];
+-      if(tempbl & 0x02) goto cr36ready;
+-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+-      SiS_Pr->SiS_DDC_SecAddr = 0x23;		/* Established Timings */
+-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-      tempbl = buffer[0];
+-      tempbh = buffer[1];
+-      tempah = 0x03;
+-      if(!(tempbh & 0x01)) tempah = 0x02;
+-      if(!tempbl) cr37 |= 0x10;
+-      
+-  } else {
+-  
+-      /* Read and analyze EDID V2 (res) */
+-      
+-      tempah = 0x02;
+-      tempbx = tempbl | (tempbh << 8);
+-      if(tempbx != 1024) tempah = 0x03;
+-      
+-  }     
+-
+-cr36ready:
+-  cr36 = tempah;      
+-  
+-  if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+-  
+-     /* Read and analyze EDID V1 (pol) */
+-  
+-     SiS_Pr->SiS_DDC_SecAddr = 0x47;
+-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-     tempah = buffer[0];
+-     tempah &= 0x06;
+-     tempah ^= 0x06;
+-     tempah <<= 5;
+-     tempah |= 0x20;
+-     cr37 &= 0x1f;
+-     cr37 |= tempah;
+-     if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+-     
+-  } else {
+-  
+-     /* Read and analyze EDID V2 (depth, pol) */
+-  
+-     push1 = tempah;
+-     SiS_Pr->SiS_DDC_SecAddr = 0x45;
+-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-     tempah = 0x01;
+-     if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {   /* RGB18 or 24? */
+-        tempah = 0x00;
+-     }
+-     cr37 &= 0xfe;
+-     cr37 |= tempah;
+-     
+-     SiS_Pr->SiS_DDC_SecAddr = 0x7e;
+-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-     tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
+-     push2 = tempax;
+-     tempax &= 0x0003;
+-     tempax *= 0x1b;
+-     push3 = tempax;
+-     tempax = (USHORT)buffer[0];
+-     tempax &= 0x001c;
+-     tempax >>= 2;
+-     tempax *= 8;
+-     tempbx = push3;
+-     tempbx += tempax;
+-     if(buffer[0] & 0x20) {		/* Luminance table provided? */
+-        SiS_Pr->SiS_DDC_SecAddr = 0x80;
+-	SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-	tempax = buffer[0] | (buffer[1] << 8);
+-	tempax &= 0x1f;
+-	if(buffer[0] & 0x70) tempax <<= 1;
+-	tempax++;	
+-	tempbx += tempax;        	/* yes -> skip it */
+-     }
+-     tempcx = push2;
+-     tempax = push1 << 8;
+-     tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
+-     if(tempcx & 0xf800) {
+-        tempal = addresstable[((tempax & 0xff00) >> 8)];
+-	tempcx &= 0xf8ff;
+-	tempcx >>= 11;
+-	for(i=0; i<tempcx; i++) {
+-	   SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
+-	   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+-	   tempbx += 0x04;
+-	   if(buffer[0] == tempal) break;
+-	}
+-	tempah = buffer[1];
+-	tempah &= 0x0c;
+-	tempah ^= 0x0c;
+-	tempah <<= 4;
+-	tempah |= 0x20;
+-        cr37 &= 0x1f;
+-        cr37 |= tempah;
+-	if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+-     }
+-  }
+-  xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
+-  return 0;
+-}
+-#endif
+-
+-/* TW: Generic I2C functions (compliant to i2c library) */
++/* Generic I2C functions (compliant to i2c library) */
+ 
+ #if 0
+ USHORT
+@@ -10675,16 +11053,14 @@ SiS_I2C_Stop(SiS_Private *SiS_Pr)
+ void
+ SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
+ {
+-  USHORT tempal,tempah,tempbl;
++  USHORT tempbl;
+ 
+-  tempal = tempax & 0x00FF;
+-  tempah =(tempax >> 8) & 0x00FF;
+-  tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
+-  tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
++  tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
++  tempbl = (((tempbl & tempbh) << 8) | tempax);
+   SiS_SetCH70xx(SiS_Pr,tempbl);
+ }
+ 
+-/* TW: Generic I2C functions for Chrontel --------- */
++/* Generic I2C functions for Chrontel --------- */
+ 
+ void
+ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+@@ -10698,37 +11074,37 @@ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+   SiS_WaitRetraceDDC(SiS_Pr);
+ }
+ 
+-/* TW: Set I2C start condition */
+-/* TW: This is done by a SD high-to-low transition while SC is high */
++/* Set I2C start condition */
++/* This is done by a SD high-to-low transition while SC is high */
+ USHORT
+ SiS_SetStart(SiS_Private *SiS_Pr)
+ {
+-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
++  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
+   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
+-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
++                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* SD->high */
++  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high */
+   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
+-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
++                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* SD->low = start condition */
++  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
+   return 0;
+ }
+ 
+-/* TW: Set I2C stop condition */
+-/* TW: This is done by a SD low-to-high transition while SC is high */
++/* Set I2C stop condition */
++/* This is done by a SD low-to-high transition while SC is high */
+ USHORT
+ SiS_SetStop(SiS_Private *SiS_Pr)
+ {
+-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
++  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
+   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
+-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
++                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* SD->low   */
++  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high  */
+   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
+-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
++                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* SD->high = stop condition */
++  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->high) */
+   return 0;
+ }
+ 
+-/* TW: Write 8 bits of data */
++/* Write 8 bits of data */
+ USHORT
+ SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+ {
+@@ -10736,18 +11112,18 @@ SiS_WriteDDC2Data(SiS_Private *SiS_Pr, U
+ 
+   flag=0x80;
+   for(i=0;i<8;i++) {
+-    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
++    SiS_SetSCLKLow(SiS_Pr);				                      /* SC->low */
+     if(tempax & flag) {
+       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
++                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* Write bit (1) to SD */
+     } else {
+       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
++                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* Write bit (0) to SD */
+     }
+-    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
++    SiS_SetSCLKHigh(SiS_Pr);				                      /* SC->high */
+     flag >>= 1;
+   }
+-  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
++  temp = SiS_CheckACK(SiS_Pr);				                      /* Check acknowledge */
+   return(temp);
+ }
+ 
+@@ -10808,27 +11184,27 @@ SiS_DDC2Delay(SiS_Private *SiS_Pr, USHOR
+   }
+ }
+ 
+-/* TW: Check I2C acknowledge */
++/* Check I2C acknowledge */
+ /* Returns 0 if ack ok, non-0 if ack not ok */
+ USHORT
+ SiS_CheckACK(SiS_Private *SiS_Pr)
+ {
+   USHORT tempah;
+ 
+-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
++  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
+   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
+-  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
+-  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
+-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
+-  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
++                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* (SD->high) */
++  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
++  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
++  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
++  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* Ack OK if bit = 0 */
+   else return(0);
+ }
+ 
+-/* TW: End of I2C functions ----------------------- */
++/* End of I2C functions ----------------------- */
+ 
+ 
+-/* =============== SiS 310/325/330 O.E.M. ================= */
++/* =============== SiS 315/330 O.E.M. ================= */
+ 
+ #ifdef SIS315H
+ 
+@@ -10838,11 +11214,11 @@ GetRAMDACromptr(SiS_Private *SiS_Pr, PSI
+   USHORT romptr;
+ 
+   if(HwDeviceExtension->jChipType < SIS_330) {
+-     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);  
++     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
+      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+   } else {
+-     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);  
++     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
+      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+         romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+   }
+@@ -10855,11 +11231,11 @@ GetLCDromptr(SiS_Private *SiS_Pr, PSIS_H
+   USHORT romptr;
+ 
+   if(HwDeviceExtension->jChipType < SIS_330) {
+-     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  
++     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+   } else {
+-     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);  
++     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+         romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
+   }
+@@ -10884,10 +11260,22 @@ GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW
+ }
+ 
+ static USHORT
+-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
++GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+ {
+   USHORT index;
+-  
++
++  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
++     if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
++        if((index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
++	   index >>= 4;
++	   index *= 3;
++	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
++           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
++           return index;
++	}
++     }
++  }
++
+   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
+   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
+   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
+@@ -10895,7 +11283,6 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
+   index *= 3;
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+-
+   return index;
+ }
+ 
+@@ -10945,8 +11332,9 @@ static void
+ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+              UCHAR *ROMAddr, USHORT ModeNo)
+ {
+-  USHORT delay,index,myindex,temp,romptr=0;
+-  
++  USHORT delay=0,index,myindex,temp,romptr=0;
++  BOOLEAN dochiptest = TRUE;
++
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
+      
+      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+@@ -10969,61 +11357,81 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+            delay = 0x00;
+      }
+-  
++
+   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
+-  
+-     index = GetLCDPtrIndexBIOS(SiS_Pr);
+-     myindex = GetLCDPtrIndex(SiS_Pr);
+-     
+-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
+-       if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+-          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+-#if 0	     /* Always use the second pointer on 650; some BIOSes */
+-             /* still carry old 301 data at the first location    */  
+-	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); 
+-	     if(SiS_Pr->SiS_VBType & VB_SIS302LV) 
+-#endif		
+-	        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+-	     if(!romptr) return;
+-	     delay = ROMAddr[(romptr + index)];
+-	  } else {
+-             delay = SiS310_LCDDelayCompensation_650301B[myindex];   
+-#if 0	     
++
++     BOOLEAN gotitfrompci = FALSE;
++
++     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++
++     /* This is a piece of typical SiS crap: They code the OEM LCD
++      * delay into the code, at none defined place in the BIOS.
++      * We now have to start doing a PCI subsystem check here.
++      */
++
++     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
++	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
++	   gotitfrompci = TRUE;
++	   dochiptest = FALSE;
++	   delay = 0x03;
++	}
++     }
++
++     if(!gotitfrompci) {
++
++        index = GetLCDPtrIndexBIOS(SiS_Pr, HwDeviceExtension, BaseAddr);
++        myindex = GetLCDPtrIndex(SiS_Pr);
++
++        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
++           if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
++             if((ROMAddr) && SiS_Pr->SiS_UseROM) {
++#if 0	        /* Always use the second pointer on 650; some BIOSes */
++                /* still carry old 301 data at the first location    */
++	        romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
++	        if(SiS_Pr->SiS_VBType & VB_SIS302LV)
++#endif
++	           romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
++	        if(!romptr) return;
++	        delay = ROMAddr[(romptr + index)];
++	     } else {
++                delay = SiS310_LCDDelayCompensation_650301B[myindex];
++#if 0
++	        if(SiS_Pr->SiS_VBType & VB_SIS302LV)
++	           delay = SiS310_LCDDelayCompensation_650301B[myindex];
++#endif
++	     }
++          } else {
++             delay = SiS310_LCDDelayCompensation_651301LV[myindex];
+ 	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+-	        delay = SiS310_LCDDelayCompensation_650301B[myindex];
+-#endif		
+-	  }
+-       } else {
+-          delay = SiS310_LCDDelayCompensation_651301LV[myindex];     
+-	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+-	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];  
+-       }
+-     } else {
+-        if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
+-	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { 
+-           romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+-	   if(!romptr) return;
+-	   delay = ROMAddr[(romptr + index)];
++	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
++          }
+         } else {
+-           delay = SiS310_LCDDelayCompensation_301[myindex];
+-           if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-#if 0 	      /* This data is (like the one in the BIOS) wrong. */	   
+-	      if(IS_SIS650740) {  /* V */
+-	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
+-	      } else {
+-#endif	      
+-                 delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
+-#if 0		 
++           if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
++	      (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
++              romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
++	      if(!romptr) return;
++	      delay = ROMAddr[(romptr + index)];
++           } else {
++              delay = SiS310_LCDDelayCompensation_301[myindex];
++              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++#if 0 	         /* This data is (like the one in the BIOS) wrong. */
++	         if(IS_SIS550650740660) {
++	            delay = SiS310_LCDDelayCompensation_650301B[myindex];
++	         } else {
++#endif
++                    delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
++#if 0
++	         }
++#endif
+ 	      }
+-#endif	      
+-	   }
+-           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-	      if(IS_SIS650) {
+-                 delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
+-	      } else {
+-	         delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
++              if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
++	         if(IS_SIS650) {
++                    delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
++	         } else {
++	            delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
++	         }
+ 	      }
+-	   }
++           }
+         }
+      }
+      
+@@ -11086,16 +11494,18 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_H
+         }
+      }
+   } else {
+-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
++     if(dochiptest && IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+         temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
+-        if(temp == 8) {
++        if(temp == 8) {		/* 1400x1050 BIOS */
+ 	   delay &= 0x0f;
+ 	   delay |= 0xb0;
+         } else if(temp == 6) {
+            delay &= 0x0f;
+ 	   delay |= 0xc0;
++        } else if(temp > 7) {	/* 1280x1024 BIOS */
++	   delay = 0x35;
+         }
+-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);
+      } else {
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+      }
+@@ -11118,7 +11528,7 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS
+ 
+   if(ROMAddr && SiS_Pr->SiS_UseROM) {
+      romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+-     if(HwDeviceExtension->jChipType == SIS_330) {
++     if(HwDeviceExtension->jChipType >= SIS_330) {
+         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+      }
+   }
+@@ -11150,7 +11560,7 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS
+ 
+   if(ROMAddr && SiS_Pr->SiS_UseROM) {
+      romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+-     if(HwDeviceExtension->jChipType == SIS_330) {
++     if(HwDeviceExtension->jChipType >= SIS_330) {
+         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+      }
+   }
+@@ -11198,7 +11608,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_
+ 
+   if(ROMAddr && SiS_Pr->SiS_UseROM) {
+   	OutputSelect = ROMAddr[0xf3];
+-	if(HwDeviceExtension->jChipType == SIS_330) {
++	if(HwDeviceExtension->jChipType >= SIS_330) {
+ 	    OutputSelect = ROMAddr[0x11b];
+ 	}
+   }
+@@ -11220,6 +11630,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_
+                  }
+               }
+          }
++	 /* PALN : Is this data correct? */
+          if(temp == EnablePALN) {
+               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+                  for(i=0x35, j=0; i<=0x38; i++, j++) {
+@@ -11247,13 +11658,13 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
+   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+ 
+   temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
+-  temp1 &=  (EnablePALM | EnablePALN);
++  temp1 &= (EnablePALM | EnablePALN);
+   if(temp1) return;
+ 
+-  if (ModeNo<=0x13) {
+-    resinfo =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
++  if(ModeNo<=0x13) {
++     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+   } else {
+-    resinfo =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
++     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+   }
+ 
+   temp = GetTVPtrIndex(SiS_Pr);
+@@ -11262,17 +11673,17 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
+    */
+   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+      romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+-     if(HwDeviceExtension->jChipType == SIS_330) {
++     if(HwDeviceExtension->jChipType >= SIS_330) {
+         romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+      }
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+-	if(HwDeviceExtension->jChipType == SIS_330) {
++	if(HwDeviceExtension->jChipType >= SIS_330) {
+ 	   romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+ 	}
+ 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
+ 	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+-	   if(HwDeviceExtension->jChipType == SIS_330) {
++	   if(HwDeviceExtension->jChipType >= SIS_330) {
+               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+            }
+ 	}
+@@ -11296,19 +11707,19 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_H
+      }
+   }
+ 
+-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
++  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+      if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
+-        if(resinfo == 6) {
++        if(resinfo == SIS_RI_640x480) {
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+-	} else if (resinfo == 7) {
++	} else if (resinfo == SIS_RI_800x600) {
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+-	} else if (resinfo == 8) {
++	} else if (resinfo == SIS_RI_1024x768) {
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
+@@ -11323,7 +11734,9 @@ SiS_OEM310Setting(SiS_Private *SiS_Pr, P
+                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+ {
+    SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+-   /* TW: The TV functions are not for LVDS */
++
++   if(SiS_Pr->UseCustomMode) return;
++
+    if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+        SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+        SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+@@ -11335,7 +11748,7 @@ SiS_OEM310Setting(SiS_Private *SiS_Pr, P
+ }
+ 
+ /* FinalizeLCD
+- * This finalizes some Part1 registers for the very panel used.
++ * This finalizes some CRT2 registers for the very panel used.
+  * If we have a backup if these registers, we use it; otherwise
+  * we set the register according to most BIOSes. However, this
+  * function looks quite different in every BIOS, so you better
+@@ -11350,6 +11763,11 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
+ 
+   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+ 
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++  if(SiS_Pr->UseCustomMode) return;
++
++  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ12802) return;
++
+   if(ModeNo <= 0x13) {
+ 	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ 	modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+@@ -11358,20 +11776,34 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
+ 	modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   }
+ 
++  if(IS_SIS650) {
++     if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
++        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
++     }
++  }
++
+   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+ 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+ 	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
++     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {   /* For all panels? */
++        /* Maybe ACER only? */
++        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
+      }
+      tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+      tempch &= 0xf0;
+      tempch >>= 4;
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
++        if(tempch == 0x03) {
++	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
++	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x25);
++	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x00);
++	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
++	}
+ 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ 	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+-	}
+-	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {	
++	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
+ 	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
+@@ -11387,14 +11819,14 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
+ 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
+ 	       if(ModeNo <= 0x13) {
+ 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
+-		  if((resinfo == 0) && (resinfo == 2)) return;
++		  if((resinfo == 0) || (resinfo == 2)) return;
+ 		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
+-		  if((resinfo == 1) && (resinfo == 3)) return;
++		  if((resinfo == 1) || (resinfo == 3)) return;
+ 	       }
+ 	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
+-	       if((ModeNo > 0x13) && (resinfo == 8)) {
++	       if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
+ 	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
+-#if 0	       
++#if 0
+ 	          tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
+ 		  tempbx--;
+ 		  temp = tempbx & 0xff;
+@@ -11449,7 +11881,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
+ 	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+ 	tempbx = (tempbh << 8) | tempbl;
+ 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+-	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
++	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
+ 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ 	      	tempbx = 770;
+ 	      } else {
+@@ -11477,67 +11909,56 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USH
+   }
+ }
+ 
+-#if 0
+-/* TW: New and checked from 650/301LV BIOS */
+-/* This might clash with newer "FinalizeLCD()" function */
++#endif
++
++
++/*  =================  SiS 300 O.E.M. ================== */
++
++#ifdef SIS300
++
+ void
+-SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+-                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
++SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
++              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
+ {
+-   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
+-
+-   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
++  USHORT crt2crtc=0, modeflag, myindex=0;
++  UCHAR  temp;
++  int i;
+ 
+-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+-      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+-      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
+-      tempbh &= 0x38;
+-      tempbh >>= 3;
+-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
+-      tempbx = (tempbh << 8) | tempbl;
+-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
+-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
+-      tempah = (tempbx & 0xff00) >> 8;
+-      tempah &= 0x07;
+-      tempah <<= 3;
+-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
+-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
+-      tempah &= 0x0f;
+-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
+-      tempah &= 0x0f;
+-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
+-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
+-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
+-      tempah -= 8;
+-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
+-   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+-      tempbh &= 0x70;
+-      tempbh >>= 4;
+-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+-      tempbx = (tempbh << 8) | tempbl;
+-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
+-           tempbx -= 0x1e;
+-	   tempcl &= 0x0f;
+-	   tempcl -= 4;
+-	   tempcl &= 0x0f;
+-      }
+-      tempbl = tempbx & 0x00ff;
+-      tempbh = (tempbx >> 8) & 0x00ff;
+-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
+-      tempbh <<= 4;
+-      tempbh |= tempcl;
+-      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
+-   }
+-}
+-#endif
++  if(ModeNo <= 0x13) {
++        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
++	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++  } else {
++        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++	crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
++  }
+ 
+-#endif
++  crt2crtc &= 0x3f;
+ 
++  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
++  }
+ 
+-/*  =================  SiS 300 O.E.M. ================== */
++  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++     if(modeflag & HalfDCLK) myindex = 1;
+ 
+-#ifdef SIS300
++     if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
++        for(i=0; i<7; i++) {
++           if(barco_p1[myindex][crt2crtc][i][0]) {
++	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
++	                      barco_p1[myindex][crt2crtc][i][0],
++	   	   	      barco_p1[myindex][crt2crtc][i][2],
++			      barco_p1[myindex][crt2crtc][i][1]);
++	   }
++        }
++     }
++     temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
++     if(temp & 0x80) {
++        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
++        temp++;
++        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);
++     }
++  }
++}
+ 
+ #if 0   /* Not used */
+ static USHORT
+@@ -11582,7 +12003,7 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_H
+ 
+   if(HwDeviceExtension->jChipType == SIS_300) {
+ 
+-    tempbx = SiS_Pr->SiS_LCDResInfo - 2;
++    tempbx = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
+     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
+@@ -11636,24 +12057,29 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS
+ {
+   USHORT index,temp,romptr=0;
+ 
++  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
++
+   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+      if(!(ROMAddr[0x237] & 0x01)) return;
+      if(!(ROMAddr[0x237] & 0x02)) return;
+      romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
+   }
+ 
+-  /* TW: The Panel Compensation Delay should be set according to tables
+-   *     here. Unfortunately, various BIOS versions don't case about
+-   *     a uniform way using eg. ROM byte 0x220, but use different
+-   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+-   *     Thus we don't set this if the user select a custom pdc or if
+-   *     we otherwise detected a valid pdc.
++  /* The Panel Compensation Delay should be set according to tables
++   * here. Unfortunately, various BIOS versions don't case about
++   * a uniform way using eg. ROM byte 0x220, but use different
++   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
++   * Thus we don't set this if the user select a custom pdc or if
++   * we otherwise detected a valid pdc.
+    */
+   if(HwDeviceExtension->pdc) return;
+ 
+   temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
+ 
+-  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
++  if(SiS_Pr->UseCustomMode)
++     index = 0;
++  else
++     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+ 
+   if(HwDeviceExtension->jChipType != SIS_300) {
+ 	if(romptr) {
+@@ -11700,9 +12126,9 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS
+ 
+ static void
+ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
++              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+ {
+-#if 0  /* TW: Unfinished; VData table missing */
++#if 0  /* Unfinished; Data table missing */
+   USHORT index,temp;
+ 
+   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+@@ -11899,25 +12325,29 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_
+ 
+ void
+ SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+-		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
++		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
++		  USHORT RefTableIndex)
+ {
+-  USHORT ModeIdIndex;
++  USHORT OEMModeIdIndex=0;
+ 
+-  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
+-  if(!(ModeIdIndex)) return;
++  if(!SiS_Pr->UseCustomMode) {
++     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
++     if(!(OEMModeIdIndex)) return;
++  }
+ 
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+-       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+        }
+   }
++  if(SiS_Pr->UseCustomMode) return;
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+-       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+-       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+-    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+-       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
++       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
++    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
++       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,OEMModeIdIndex);
+        }
+   }
+ }
+--- linux-2.6.0-test6/drivers/video/sis/init301.h	2003-06-14 12:18:21.000000000 -0700
++++ 25/drivers/video/sis/init301.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,20 +1,47 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
++/* $XFree86$ */
++/*
++ * Data and prototypes for init301.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
++
+ #ifndef  _INIT301_
+ #define  _INIT301_
+ 
+ #include "osdef.h"
++
+ #include "initdef.h"
+ #include "vgatypes.h"
+ #include "vstruct.h"
+ 
+-#ifdef TC
+-#include <stdio.h>
+-#include <string.h>
+-#include <conio.h>
+-#include <dos.h>
+-#include <stdlib.h>
+-#endif
+-
+ #ifdef LINUX_XF86
+ #include "xf86.h"
+ #include "xf86Pci.h"
+@@ -24,6 +51,9 @@
+ #endif
+ 
+ #ifdef LINUX_KERNEL
++#ifdef SIS_CP
++#undef SIS_CP
++#endif
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <asm/io.h>
+@@ -35,24 +65,60 @@
+ #endif
+ #endif
+ 
+-#ifdef WIN2000
+-#include <stdio.h>
+-#include <string.h>
+-#include <miniport.h>
+-#include "dderror.h"
+-#include "devioctl.h"
+-#include "miniport.h"
+-#include "ntddvdeo.h"
+-#include "video.h"
+-#include "sisv.h"
+-#endif
++const UCHAR SiS_HiVisionTable[3][64] = {
++  {
++    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
++    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
++    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
++    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
++    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
++    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
++    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
++    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
++  },
++  {
++    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
++    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
++    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
++    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
++    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
++    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
++    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
++    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
++  },
++  {
++    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
++    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
++    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
++    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
++    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
++    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
++    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
++    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
++  }
++};
+ 
+-#if 0
+-extern   const USHORT   SiS_MDA_DAC[];
+-extern   const USHORT   SiS_CGA_DAC[];
+-extern   const USHORT   SiS_EGA_DAC[];
+-extern   const USHORT   SiS_VGA_DAC[];
+-#endif
++const UCHAR SiS_HiTVGroup3_1[] = {
++    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
++    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
++    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
++    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
++    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
++    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
++    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
++    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
++};
++
++const UCHAR SiS_HiTVGroup3_2[] = {
++    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
++    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
++    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
++    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
++    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
++    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
++    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
++    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
++};
+ 
+ extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
+ 
+@@ -77,7 +143,8 @@ void     SiS_GetCRT2PtrA(SiS_Private *Si
+                          USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex);
+ #endif
+ void     SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+-		             USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex);
++		             USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex,
++			     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                             USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ USHORT   SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+@@ -129,7 +196,6 @@ void     SiS_GetVBInfo(SiS_Private *SiS_
+ BOOLEAN  SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+ BOOLEAN  SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+ BOOLEAN  SiS_BridgeInSlave(SiS_Private *SiS_Pr);
+-void     SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SetTVSystem(SiS_Private *SiS_Pr);
+ void     SiS_LongWait(SiS_Private *SiS_Pr);
+ USHORT   SiS_GetQueueConfig(SiS_Private *SiS_Pr);
+@@ -149,7 +215,7 @@ void     SiS_GetLVDSDesPtrA(SiS_Private 
+                             USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
+ #endif			    
+ void     SiS_SetTPData(SiS_Private *SiS_Pr);
+-void     SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
++void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
+ void     SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                          USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+@@ -178,30 +244,28 @@ USHORT   SiS_SetSCLKHigh(SiS_Private *Si
+ USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+ USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+ USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
+-USHORT   SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
+-#ifdef LINUX_XF86
+-USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+-USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+-#endif
++
+ #ifdef SIS315H
+ void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+                            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ void     SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+-                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
++                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
+ #endif
+ #ifdef SIS300
+ void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+-                           UCHAR *ROMAddr,USHORT ModeNo);
++                           UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
++void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
++			UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+ #endif
+ BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ 
+-BOOLEAN  SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
++void     SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ /* void    SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex); */
+ 
+-BOOLEAN  SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
++BOOLEAN  SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+ void     SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+@@ -237,19 +301,19 @@ void     SiS_VBWait(SiS_Private *SiS_Pr)
+ void     SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ 
+-void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
++void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+ #ifdef SIS315H
+ void     SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                             USHORT BaseAddr);
+-void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
++void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void     SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void     SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void     SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ void     SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ BOOLEAN  SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+-void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
++void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr,  PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+ #ifdef NEWCH701x
+ void     SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
+@@ -289,73 +353,21 @@ extern   void     SiS_LoadDAC(SiS_Privat
+ extern   UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ #endif
+ 
+-#ifdef LINUX_XF86
+ /* DDC functions */
+-USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
++USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++                         USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+ USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+ USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+ USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
+ void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+ USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+ USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
+-USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
+-USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+-                       USHORT DDCdatatype, unsigned char *buffer);
++USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
++USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++		       USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
++#ifdef LINUX_XF86
++USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
++USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+ #endif
+ 
+-const UCHAR SiS_HiVisionTable[3][64] = {
+-  { 
+-    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
+-    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
+-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
+-    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
+-    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
+-    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
+-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
+-    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+-  },
+-  { 
+-    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+-    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+-    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
+-    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
+-    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
+-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
+-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+-  },
+-  { 
+-    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 
+-    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 
+-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, 
+-    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, 
+-    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, 
+-    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, 
+-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, 
+-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 
+-  }
+-};
+-
+-const UCHAR SiS_HiTVGroup3_1[] = {
+-    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+-    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
+-    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+-    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
+-    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
+-    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
+-    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
+-    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
+-};
+-
+-const UCHAR SiS_HiTVGroup3_2[] = {
+-    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+-    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
+-    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+-    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
+-    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
+-    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
+-    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
+-    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
+-};
+-
+ #endif
+--- linux-2.6.0-test6/drivers/video/sis/init.c	2003-06-14 12:18:05.000000000 -0700
++++ 25/drivers/video/sis/init.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,24 +1,17 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
+ /*
+- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
++ * Mode switching code (CRT1 section) for
++ * SiS 300/540/630/730/315/550/650/M650/651/M652/740/330/660/M660/760
+  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+  *
+  * Assembler-To-C translation
+- * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+- * Minor parts Copyright SiS, Inc.
++ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
++ * Formerly based on non-functional code-fragements by SiS, Inc.
+  *
+- * Based on BIOS
+- *     1.10.07, 1.10a for 650/CH7019
+- *     1.11.21a for 740/CH7019
+- *     1.11.05 for 650/LVDS (w/o Chrontel)
+- *     1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
+- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+- *     2.06.50 for 630/301B (dual VGA)
+- *     2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
+- *     1.09b for 315/301(B)
+- *     1.16.51 for 300+301LV (ECS A907)
+- *     1.01.03 for 330 (Xabre 400)
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+@@ -61,12 +54,12 @@
+ #ifdef LINUX_XF86
+ BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+-DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
+-#ifdef SISDUALHEAD /* TW: For dual head */
++DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
++#ifdef SISDUALHEAD
+ BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                        ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+ BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+-                       ScrnInfoPtr pScrn, DisplayModePtr mode);
++                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+ #endif /* dual head */
+ #endif /* linux_xf86 */
+ 
+@@ -90,49 +83,201 @@ BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, 
+ static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
+                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ 
+-static void DelaySeconds(int seconds);
+-void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
+-
+ static void
+-DelaySeconds(int seconds)
+-{
+-  int i;
+-#ifdef WIN2000
+-  int j;
+-#endif
+-
+-  for (i=0;i<seconds;i++) {
+-#ifdef TC
+-    delay(1000);
+-#endif
+-
+-#ifdef WIN2000
+-    for (j=0;j<20000;j++)
+-      VideoPortStallExecution(50);
+-#endif
+-
+-#ifdef WINCE_HEADER
+-#endif
+-
+-#ifdef LINUX_KERNEL
+-#endif
+-  }
+-}
+-
+-void
+-SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
++InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
+-  OutPortByte(0x80, code);
+-  DelaySeconds(0x3);
++   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
++   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
++   SiS_Pr->SiS_StandTable    = SiS_StandTable;
++   if(HwDeviceExtension->jChipType < SIS_315H) {
++      SiS_StandTable[0x04].CRTC[4] = 0x2b;
++      SiS_StandTable[0x05].CRTC[4] = 0x2b;
++      SiS_StandTable[0x06].CRTC[4] = 0x54;
++      SiS_StandTable[0x06].CRTC[5] = 0x80;
++      SiS_StandTable[0x0d].CRTC[4] = 0x2b;
++      SiS_StandTable[0x0e].CRTC[4] = 0x54;
++      SiS_StandTable[0x0e].CRTC[5] = 0x80;
++      SiS_StandTable[0x11].CRTC[4] = 0x54;
++      SiS_StandTable[0x11].CRTC[5] = 0x80;
++      SiS_StandTable[0x11].CRTC[16] = 0x83;
++      SiS_StandTable[0x11].CRTC[17] = 0x85;
++      SiS_StandTable[0x12].CRTC[4] = 0x54;
++      SiS_StandTable[0x12].CRTC[5] = 0x80;
++      SiS_StandTable[0x12].CRTC[16] = 0x83;
++      SiS_StandTable[0x12].CRTC[17] = 0x85;
++      SiS_StandTable[0x13].CRTC[5] = 0xa0;
++      SiS_StandTable[0x17].CRTC[5] = 0xa0;
++      SiS_StandTable[0x1a].CRTC[4] = 0x54;
++      SiS_StandTable[0x1a].CRTC[5] = 0x80;
++      SiS_StandTable[0x1a].CRTC[16] = 0xea;
++      SiS_StandTable[0x1a].CRTC[17] = 0x8c;
++      SiS_StandTable[0x1b].CRTC[4] = 0x54;
++      SiS_StandTable[0x1b].CRTC[5] = 0x80;
++      SiS_StandTable[0x1b].CRTC[16] = 0xea;
++      SiS_StandTable[0x1b].CRTC[17] = 0x8c;
++      SiS_StandTable[0x1c].CRTC[4] = 0x54;
++      SiS_StandTable[0x1c].CRTC[5] = 0x80;
++   } else {
++      SiS_StandTable[0x04].CRTC[4] = 0x2c;
++      SiS_StandTable[0x05].CRTC[4] = 0x2c;
++      SiS_StandTable[0x06].CRTC[4] = 0x55;
++      SiS_StandTable[0x06].CRTC[5] = 0x81;
++      SiS_StandTable[0x0d].CRTC[4] = 0x2c;
++      SiS_StandTable[0x0e].CRTC[4] = 0x55;
++      SiS_StandTable[0x0e].CRTC[5] = 0x81;
++      SiS_StandTable[0x11].CRTC[4] = 0x55;
++      SiS_StandTable[0x11].CRTC[5] = 0x81;
++      SiS_StandTable[0x11].CRTC[16] = 0x82;
++      SiS_StandTable[0x11].CRTC[17] = 0x84;
++      SiS_StandTable[0x12].CRTC[4] = 0x55;
++      SiS_StandTable[0x12].CRTC[5] = 0x81;
++      SiS_StandTable[0x12].CRTC[16] = 0x82;
++      SiS_StandTable[0x12].CRTC[17] = 0x84;
++      SiS_StandTable[0x13].CRTC[5] = 0xb1;
++      SiS_StandTable[0x17].CRTC[5] = 0xb1;
++      SiS_StandTable[0x1a].CRTC[4] = 0x55;
++      SiS_StandTable[0x1a].CRTC[5] = 0x81;
++      SiS_StandTable[0x1a].CRTC[16] = 0xe9;
++      SiS_StandTable[0x1a].CRTC[17] = 0x8b;
++      SiS_StandTable[0x1b].CRTC[4] = 0x55;
++      SiS_StandTable[0x1b].CRTC[5] = 0x81;
++      SiS_StandTable[0x1b].CRTC[16] = 0xe9;
++      SiS_StandTable[0x1b].CRTC[17] = 0x8b;
++      SiS_StandTable[0x1c].CRTC[4] = 0x55;
++      SiS_StandTable[0x1c].CRTC[5] = 0x81;
++   }
++
++   SiS_Pr->SiS_NTSCPhase    = SiS_NTSCPhase;
++   SiS_Pr->SiS_PALPhase     = SiS_PALPhase;
++   SiS_Pr->SiS_NTSCPhase2   = SiS_NTSCPhase2;
++   SiS_Pr->SiS_PALPhase2    = SiS_PALPhase2;
++   SiS_Pr->SiS_PALMPhase    = SiS_PALMPhase;
++   SiS_Pr->SiS_PALNPhase    = SiS_PALNPhase;
++   SiS_Pr->SiS_PALMPhase2   = SiS_PALMPhase2;
++   SiS_Pr->SiS_PALNPhase2   = SiS_PALNPhase2;
++   SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
++
++   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
++   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
++   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
++   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
++   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
++   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
++   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
++   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
++   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
++
++   SiS_Pr->SiS_StPALData   = SiS_StPALData;
++   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
++   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
++   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
++/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData;  */
++   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
++   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
++
++   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
++   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
++
++   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
++   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
++   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
++   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
++   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
++   SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
++   SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
++   SiS_Pr->SiS_ExtLCD1280x768Data   = SiS_ExtLCD1280x768Data;
++   SiS_Pr->SiS_StLCD1280x768Data    = SiS_StLCD1280x768Data;
++   SiS_Pr->SiS_NoScaleData1280x768  = SiS_NoScaleData1280x768;
++   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
++
++   SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
++   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
++   SiS_Pr->SiS_LVDS800x600Data_2   = SiS_LVDS800x600Data_2;
++   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
++   SiS_Pr->SiS_LVDS1024x768Data_2  = SiS_LVDS1024x768Data_2;
++   SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
++   SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
++   SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
++   SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
++   SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
++   SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
++   SiS_Pr->SiS_LVDS1280x768Data_1  = SiS_LVDS1280x768Data_1;
++   SiS_Pr->SiS_LVDS1280x768Data_2  = SiS_LVDS1280x768Data_2;
++   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
++   SiS_Pr->SiS_LVDS1024x600Data_2  = SiS_LVDS1024x600Data_2;
++   SiS_Pr->SiS_LVDS1152x768Data_1  = SiS_LVDS1152x768Data_1;
++   SiS_Pr->SiS_LVDS1152x768Data_2  = SiS_LVDS1152x768Data_2;
++   SiS_Pr->SiS_LVDSXXXxXXXData_1   = SiS_LVDSXXXxXXXData_1;
++   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x960Data_1;
++   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x960Data_2;
++   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
++   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x1024Data_1;
++   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x1024Data_2;
++   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
++   SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
++
++   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
++   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
++   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
++   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
++   SiS_Pr->SiS_LVDS848x480Data_1   = SiS_LVDS848x480Data_1;
++   SiS_Pr->SiS_LVDS848x480Data_2   = SiS_LVDS848x480Data_2;
++
++   SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
++   SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
++   SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
++   SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
++   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
++   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
++
++   SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
++   SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
++   SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
++   SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
++   SiS_Pr->LVDS1024x768Des_2  = SiS_PanelType1076_2;
++   SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
++   SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
++   SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
++
++   SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
++   SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
++
++   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
++   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
++   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
++   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
++
++   SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
++   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
++   SiS_Pr->SiS_LVDSCRT11152x768_1    = SiS_LVDSCRT11152x768_1;
++   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = SiS_LVDSCRT11280x768_1_H;
++   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
++   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = SiS_LVDSCRT11152x768_1_H;
++   SiS_Pr->SiS_LVDSCRT11280x768_2    = SiS_LVDSCRT11280x768_2;
++   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
++   SiS_Pr->SiS_LVDSCRT11152x768_2    = SiS_LVDSCRT11152x768_2;
++   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = SiS_LVDSCRT11280x768_2_H;
++   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
++   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
++   SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
++   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS_LVDSCRT1XXXxXXX_1;
++   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS_LVDSCRT1XXXxXXX_1_H;
++   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
++   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
++   SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
++   SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
++   SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
++   SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
+ }
+ 
+ #ifdef SIS300
+ static void
+ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
++   InitCommonPointer(SiS_Pr, HwDeviceExtension);
++
+    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
+    SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
+-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
+    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
+    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
+    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+@@ -141,15 +286,12 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    } else {
+       SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
+    }
++#ifdef LINUXBIOS
+    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
++#endif
+    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+    SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
+-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
+-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
+-
+-   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
+-   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
+ 
+    SiS_Pr->SiS_SR15  = SiS300_SR15;
+ 
+@@ -178,15 +320,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
+ #endif
+ 
+-   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
+-   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
+-   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+-   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
+-   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
+-   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
+-   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
+-   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
+-
+    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
+    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
+    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
+@@ -195,68 +328,18 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
+    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
+    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
+-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
+-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
+-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
+-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
+-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
+-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
+-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
+-
+-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
+-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
+-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
+-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
+-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;  */
+-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
+-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
+-
+-   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
+-   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
+-   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
+-   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
+-   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+-   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+-   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+-   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+ 
+    SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
+ 
+-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
+-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
+-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
+-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
+-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
+-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
+-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
+-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
+-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
+-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
+-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
+-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
+-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
+-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
+-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
+-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
+-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
+-   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
+-   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
+-   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
+-   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
+-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
+-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
+    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
+    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
+-   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
+-   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
++   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; 			   /* not supported on 300 series */
++   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; 			   /* not supported on 300 series */
+    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
+    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
+    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
++
+    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
+    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
+    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
+@@ -289,32 +372,28 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
+    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
+    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
+-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
+-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
+-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
+-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
+-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
++
++   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
++      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
++      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
++   }
++   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
++      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
++      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
++   }
++
+    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
+    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
+    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
+-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
+-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
+    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
+    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
+    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
+-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
+-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
+    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
+    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
+    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
+-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
+-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
+    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
+    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
+    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
+-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
+-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
+    SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
+    SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
+    SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
+@@ -339,7 +418,6 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
+    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
+ 
+-   /* TW: New from 300/301LV BIOS */
+    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
+    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
+    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
+@@ -353,7 +431,7 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
+    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
+ 
+-   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
++   /* TW: LCDResInfo will on 300 series be translated to 315 series definitions */
+    SiS_Pr->SiS_Panel320x480   = Panel_320x480;
+    SiS_Pr->SiS_Panel640x480   = Panel_640x480;
+    SiS_Pr->SiS_Panel800x600   = Panel_800x600;
+@@ -362,13 +440,17 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
+    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
+    SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
+-   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
+-   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
+-   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
+-   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
++   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
++   SiS_Pr->SiS_Panel1600x1200 = 255;  		/* TW: Something illegal */
++   SiS_Pr->SiS_Panel1400x1050 = 255;  		/* TW: Something illegal */
++   SiS_Pr->SiS_Panel640x480_2 = 255;  		/* TW: Something illegal */
++   SiS_Pr->SiS_Panel640x480_3 = 255;  		/* TW: Something illegal */
++   SiS_Pr->SiS_Panel1152x864  = 255;   		/* TW: Something illegal */
+    SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
+    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
+    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
++   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
++   SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
+ }
+ #endif
+ 
+@@ -376,29 +458,33 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PS
+ static void
+ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+ {
++   InitCommonPointer(SiS_Pr, HwDeviceExtension);
++
+    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
+-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
+    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
+    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
+    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
+    /* TW: MCLK is different */
+-   if(HwDeviceExtension->jChipType == SIS_330) {
++#ifdef LINUXBIOS
++   if(HwDeviceExtension->jChipType >= SIS_660) {
++      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 660/760 */
++   } else if(HwDeviceExtension->jChipType == SIS_330) {
++#endif
+       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
++#ifdef LINUXBIOS
+    } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
+    } else {
+       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
+    }
++#endif
+    SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
++#ifdef LINUXBIOS
+    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
++#endif
+    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
+    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
+    SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
+-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
+-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
+-
+-   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
+-   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
+ 
+    SiS_Pr->SiS_SR15  = SiS310_SR15;
+ 
+@@ -427,16 +513,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
+ #endif
+ 
+-   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
+-   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
+-   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
+-   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
+-   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
+-   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
+-   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
+-   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
+-   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
+-
+    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
+    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
+    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
+@@ -445,62 +521,10 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
+    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
+    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
+-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
+-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
+-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
+-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
+-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
+-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
+-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
+-
+-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
+-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
+-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
+-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
+-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;  */
+-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
+-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
+-
+-   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
+-   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
+-   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
+-   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
+-   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+-   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
+-   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+-   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+-   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+ 
+-   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
++   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
+ 
+-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
+-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
+-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
+-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
+-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
+-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
+-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
+-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
+-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
+-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
+-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
+-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
+-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
+-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
+-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
+-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
+-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
+-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
+-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
+-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
+-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
+-   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
+-   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
+-   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
+-   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
+-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
+-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
+    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
+    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
+    SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
+@@ -508,6 +532,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
+    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
+    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
++
+    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
+    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
+    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
+@@ -540,19 +565,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
+    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
+    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
+-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
+-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
+ 
+-   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
+-   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
+-   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
+-   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
+-   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
+-   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
+-   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
+-   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
+-
+-   /* TW: New from 650/301LV BIOS */
+    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
+    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
+    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
+@@ -566,51 +579,32 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
+    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
+ 
+-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
+-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
+-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
+-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
+-
+    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
+    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
+    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
+    SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
+-   SiS_Pr->SiS_LVDSCRT11280x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
+-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
+-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
+    SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
+    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
+    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
+    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
+    SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
+-   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
+-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
+-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
+    SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
+    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
+    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
+    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
+    SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
+-   SiS_Pr->SiS_LVDSCRT11280x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
+-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
+-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
+    SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
+    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
+    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
+    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
+    SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
+-   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
+-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
+-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
+    SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
+-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
+-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
+-   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
+-   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+-   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+-   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+-   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+-   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
++   SiS_Pr->SiS_CHTVCRT1UNTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
++   SiS_Pr->SiS_CHTVCRT1ONTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
++   SiS_Pr->SiS_CHTVCRT1UPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
++   SiS_Pr->SiS_CHTVCRT1OPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
++   SiS_Pr->SiS_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
++
+    SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
+    SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
+    SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
+@@ -620,6 +614,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
+    SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
+    SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
++
+    SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
+    SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
+    SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
+@@ -640,6 +635,7 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
+    SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
+    SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
++
+    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+    SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+    SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
+@@ -662,9 +658,13 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PS
+    SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
+    SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
+    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
++   SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
++   SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
+    SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
+    SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
+    SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
++   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
++   SiS_Pr->SiS_PanelBarco1366 = 255;
+ }
+ #endif
+ 
+@@ -727,7 +727,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
+       (HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330))
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760))
+      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #endif
+ 
+@@ -896,7 +898,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
+       (HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330)) {
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760)) {
+    	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+    	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
+    }
+@@ -953,14 +957,16 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
+    if((HwDeviceExtension->jChipType == SIS_315H)   ||
+       (HwDeviceExtension->jChipType == SIS_315)    ||
+       (HwDeviceExtension->jChipType == SIS_315PRO) ||
+-      (HwDeviceExtension->jChipType == SIS_330) ) {
++      (HwDeviceExtension->jChipType == SIS_330)) {
+       	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
+         }
+    }
+    if((HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_650)) {
++      (HwDeviceExtension->jChipType == SIS_650) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760)) {
+         if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+           	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+         }
+@@ -977,7 +983,7 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
+    if((HwDeviceExtension->jChipType != SIS_540) &&
+       (HwDeviceExtension->jChipType != SIS_630) &&
+       (HwDeviceExtension->jChipType != SIS_730)){
+-     	for(i=0x15;i<0x1C;i++) {
++     	for(i=0x15; i<0x1C; i++) {
+        	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
+      	}
+    }
+@@ -1023,7 +1029,9 @@ SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEV
+       (HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330))
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760))
+      	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
+ #endif
+ 
+@@ -1180,7 +1188,9 @@ SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_P
+ #ifdef SIS315H
+   if((HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+-     (HwDeviceExtension->jChipType == SIS_330)) {
++     (HwDeviceExtension->jChipType == SIS_330) ||
++     (HwDeviceExtension->jChipType == SIS_660) ||
++     (HwDeviceExtension->jChipType == SIS_760)) {
+ #if 0 /* TW: This is not required */
+         /* TW: Read POWER_ON_TRAP and copy to CR37 */
+     	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+@@ -1299,7 +1309,7 @@ SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr,
+ #endif
+ /* ===============  SiS 300 dram sizing end    =============== */
+ 
+-/* ============  SiS 310/325 dram sizing begin  ============== */
++/* ============  SiS 315 dram sizing begin  ============== */
+ #ifdef SIS315H
+ 
+ /* TW: Moved Get310DRAMType further down */
+@@ -1893,8 +1903,7 @@ SiS_Get310DRAMType(SiS_Private *SiS_Pr, 
+    if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
+      data = *SiS_Pr->pSiS_SoftSetting & 0x03;
+    } else {
+-     if((HwDeviceExtension->jChipType > SIS_315PRO) &&
+-        (HwDeviceExtension->jChipType < SIS_330)) {
++     if(IS_SIS550650740660) {
+         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+      } else {	/* TW: 315, 330 */
+         data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+@@ -1934,13 +1943,17 @@ void SiSRegInit(SiS_Private *SiS_Pr, USH
+    SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+    SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+    SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+-   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
+-   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
+-   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
+-   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
+-   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
+-   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
+-   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
++   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
++   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
++   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
++   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;     /* Digital video interface registers (LCD) */
++   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;     /* 301 TV Encoder registers */
++   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;     /* 301 Macrovision registers */
++   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;     /* 301 VGA2 (and LCD) registers */
++   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
++   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                  /* DDC Port ( = P3C4, SR11/0A) */
++   SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
++   SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
+ }
+ 
+ void
+@@ -1965,7 +1978,9 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_
+       (HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330)) {
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760)) {
+       /* TW: This seems to be done the same way on these chipsets */
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
+@@ -1987,10 +2002,14 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_
+ 
+    SiS_Pr->SiS_ChrontelInit = 0;
+ 
+-   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
+-   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
+-   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
++#if 0
++   if(HwDeviceExtension->jChipType >= SIS_315H) {
++      if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
++   	 SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
++   	 SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
++      }
+    }
++#endif
+ 
+ #ifdef SIS300
+    if((HwDeviceExtension->jChipType == SIS_540) ||
+@@ -2015,11 +2034,15 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_
+    if((HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330))
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760))
+     {
+-        /* TW: CR37 is different on 310/325 series */
++        /* TW: CR37 is different on 315 series */
++#if 0
+         if(SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
+              SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
++#endif
+ 
+ 	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+       	temp = (temp & 0x0E) >> 1;
+@@ -2044,7 +2067,9 @@ SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_
+       (HwDeviceExtension->jChipType == SIS_550) ||
+       (HwDeviceExtension->jChipType == SIS_650) ||
+       (HwDeviceExtension->jChipType == SIS_740) ||
+-      (HwDeviceExtension->jChipType == SIS_330))
++      (HwDeviceExtension->jChipType == SIS_330) ||
++      (HwDeviceExtension->jChipType == SIS_660) ||
++      (HwDeviceExtension->jChipType == SIS_760))
+      InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #endif
+ 
+@@ -2073,14 +2098,21 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr
+ 	      SiS_Pr->SiS_UseROM = TRUE;
+ 	 else SiS_Pr->SiS_UseROM = FALSE;
+      } else if(HwDeviceExtension->jChipType < SIS_315H) {
++#if 0
+         /* TW: Rest of 300 series: We don't use the ROM image if
+ 	 *     the BIOS version < 2.0.0 as such old BIOSes don't
+ 	 *     have the needed data at the expected locations.
+ 	 */
+         if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
+ 	else                     SiS_Pr->SiS_UseROM = TRUE;
++#else
++	/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
++	 * the others do as well
++	 */
++	SiS_Pr->SiS_UseROM = TRUE;
++#endif
+      } else {
+-        /* TW: 310/325/330 series stick to the standard */
++        /* TW: 315/330 series stick to the standard */
+ 	SiS_Pr->SiS_UseROM = TRUE;
+      }
+    } else SiS_Pr->SiS_UseROM = FALSE;
+@@ -2104,24 +2136,27 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS
+    SiS_Pr->UseCustomMode = FALSE;
+ 
+    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+-   
+-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 
+-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+-		
++
++         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
++	 	SiS_Pr->CHDisplay,
++		(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
++		   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
++		      SiS_Pr->CVDisplay)));
++
+ 	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+-   
++
+    }
+-   
+-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
++
++   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
+    if(!ModeNo) return FALSE;
+ 
+-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
++   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+ 
+-   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));   
++   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+ }
+ 
+ #ifdef SISDUALHEAD
+-/* TW: Set CRT1 mode (used for dual head) */
++/* TW: Set CRT1 mode (used for dual head and MergedFB) */
+ BOOLEAN
+ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+                DisplayModePtr mode, BOOLEAN IsCustom)
+@@ -2134,31 +2169,37 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
+    SISEntPtr pSiSEnt = pSiS->entityPrivate;
+    unsigned char backupreg=0;
+    BOOLEAN backupcustom;
+-
+    UShort  ModeNo=0;
+    
+    SiS_Pr->UseCustomMode = FALSE;
+-   
++
+    if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+-   
++
++         USHORT temptemp = SiS_Pr->CVDisplay;
++
++         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
++         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
++
+          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+-	 	"Setting custom mode %dx%d in CRT1\n", 
+-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
++	 	"Setting custom mode %dx%d on CRT1\n",
++	 	SiS_Pr->CHDisplay, temptemp);
+ 	 ModeNo = 0xfe;
+-	 
++
+    } else {
+ 
+-         ModeNo = SiS_CalcModeIndex(pScrn, mode);
++         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->HaveCustomModes);
+          if(!ModeNo) return FALSE;
+ 
+          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+-	 	"Setting mode 0x%x on CRT1\n", ModeNo);
++	 	"Setting standard mode 0x%x on CRT1\n", ModeNo);
+    }
+ 
+    SiSInitPtr(SiS_Pr, HwDeviceExtension);
+ 
+    SiSRegInit(SiS_Pr, BaseAddr);
+ 
++   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+ 
+    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+@@ -2167,7 +2208,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
+ 
+    SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+ 
+-   /* TW: We don't clear the buffer under X */
++   /* We don't clear the buffer under X */
+    SiS_Pr->SiS_flag_clearbuffer = 0;
+ 
+    /* 1.Openkey */
+@@ -2175,8 +2216,8 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
+ 
+    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+ 
++   /* 2.Get ModeID Table  */
+    if(!SiS_Pr->UseCustomMode) {
+-      /* 2.Get ModeID Table  */
+       temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+       if(temp == 0)  return(0);
+    } else {
+@@ -2201,53 +2242,65 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
+    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ 
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
++         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+          }
+       }
+ 
+-      /* TW: New from 650/LV 1.10.6x */
+       if(IS_SIS650) {
+-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+-	  }
++         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
++	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
++	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
++	 }
+       }
+    }
+ 
+-   /* TW: Set mode on CRT1 */
++   /* Set mode on CRT1 */
+    SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+ 
+-   pSiSEnt->CRT1ModeNo = ModeNo;
+-   pSiSEnt->CRT1DMode = mode;
+-
+-   /* TW: SetPitch: Adapt to virtual size & position */
++   /* SetPitch: Adapt to virtual size & position */
+    SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+ 
++   if(pSiS->DualHeadMode) {
++      pSiSEnt->CRT1ModeNo = ModeNo;
++      pSiSEnt->CRT1DMode = mode;
++   }
++
++   if(SiS_Pr->UseCustomMode) {
++      SiS_Pr->CRT1UsesCustomMode = TRUE;
++      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
++      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
++   } else {
++      SiS_Pr->CRT1UsesCustomMode = FALSE;
++   }
++
+    /* We have to reset CRT2 if changing mode on CRT1 */
+-   if(pSiSEnt->CRT2ModeNo != -1) {
+-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+-				"(Re-)Setting mode 0x%x on CRT2\n",
+-				pSiSEnt->CRT2ModeNo);
+-	backupcustom = SiS_Pr->UseCustomMode;
+-	if(SiS_Pr->UseCustomMode) {
+-	   SiS_Pr->CRT1UsesCustomMode = TRUE;
+-	} else {
+-	   SiS_Pr->CRT1UsesCustomMode = FALSE;
+-	}
+-	SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
+-				pSiSEnt->CRT2DMode);
+-	SiS_Pr->UseCustomMode = backupcustom;
+-	SiS_Pr->CRT1UsesCustomMode = FALSE;
++   if(pSiS->DualHeadMode) {
++      if(pSiSEnt->CRT2ModeNo != -1) {
++         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++				"(Re-)Setting mode for CRT2\n");
++	 backupcustom = SiS_Pr->UseCustomMode;
++	 SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
++			    pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
++	 SiS_Pr->UseCustomMode = backupcustom;
++      }
+    }
+-   
++
++   /* Warning: From here, the custom mode entries in SiS_Pr are
++    * possibly overwritten
++    */
++
+    SiS_HandleCRT1(SiS_Pr);
+ 
++   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
++
+    SiS_DisplayOn(SiS_Pr);
+    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+ 
+-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+@@ -2266,7 +2319,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, 
+ /* TW: Set CRT2 mode (used for dual head) */
+ BOOLEAN
+ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+-               DisplayModePtr mode)
++               DisplayModePtr mode, BOOLEAN IsCustom)
+ {
+    ULONG   temp;
+    USHORT  ModeIdIndex;
+@@ -2276,16 +2329,52 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+    SISPtr  pSiS     = SISPTR(pScrn);
+    SISEntPtr pSiSEnt = pSiS->entityPrivate;
+    unsigned char tempr1, tempr2, backupreg=0;
+-   
++
+    SiS_Pr->UseCustomMode = FALSE;
+-   
+-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
+-   if(!ModeNo) return FALSE;
++
++   /* Remember: Custom modes for CRT2 are ONLY supported
++    * 		-) on 315/330 series,
++    *           -) on the 301 and 30xB, and
++    *           -) if CRT2 is LCD or VGA
++    */
++
++   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
++
++	 ModeNo = 0xfe;
++
++   } else {
++
++         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
++
++#ifdef SISMERGED
++	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
++#endif
++
++         ModeNo = SiS_CalcModeIndex(pScrn, mode, havecustommodes);
++         if(!ModeNo) return FALSE;
++
++   }
++
++   /* Save mode info so we can set it from within SetMode for CRT1 */
++   if(pSiS->DualHeadMode) {
++      pSiSEnt->CRT2ModeNo = ModeNo;
++      pSiSEnt->CRT2DMode = mode;
++      pSiSEnt->CRT2IsCustom = IsCustom;
++
++      /* We can't set CRT2 mode before CRT1 mode is set */
++      if(pSiSEnt->CRT1ModeNo == -1) {
++    	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
++   	 return TRUE;
++      }
++   }
+ 
+    SiSInitPtr(SiS_Pr, HwDeviceExtension);
+ 
+    SiSRegInit(SiS_Pr, BaseAddr);
+ 
++   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+    SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+ 
+    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+@@ -2294,22 +2383,26 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+ 
+    SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+ 
+-   /* TW: We don't clear the buffer under X */
++   /* We don't clear the buffer under X */
+    SiS_Pr->SiS_flag_clearbuffer=0;
+ 
+-   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
+-   pSiSEnt->CRT2ModeNo = ModeNo;
+-   pSiSEnt->CRT2DMode = mode;
+-
+-   /* TW: We can't set CRT2 mode before CRT1 mode is set */
+-   if(pSiSEnt->CRT1ModeNo == -1) {
+-   	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+-		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
+-   	return TRUE;
+-   }
++   if(SiS_Pr->UseCustomMode) {
++
++      USHORT temptemp = SiS_Pr->CVDisplay;
++
++      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
++      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
++
++      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++	  "Setting custom mode %dx%d on CRT2\n",
++	  SiS_Pr->CHDisplay, temptemp);
+ 
+-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+-   		"Setting mode 0x%x on CRT2\n", ModeNo);
++   } else {
++
++      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
++
++   }
+ 
+    /* 1.Openkey */
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+@@ -2317,10 +2410,14 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+ 
+    /* 2.Get ModeID */
+-   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+-   if(temp == 0)  return(0);
++   if(!SiS_Pr->UseCustomMode) {
++      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
++      if(temp == 0)  return(0);
++   } else {
++      ModeIdIndex = 0;
++   }
+ 
+-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
++   /* Determine VBType (301,301B,301LV,302B,302LV) */
+    SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+ 
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+@@ -2343,15 +2440,22 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+       }
+    }
+ 
+-   /* TW: Get VB information (connectors, connected devices) */
+-   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++   /* Get VB information (connectors, connected devices) */
++   if(!SiS_Pr->UseCustomMode) {
++      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++   } else {
++      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
++      SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
++   }
+    SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+    SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ 
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
++         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+          }
+       }
+    }
+@@ -2364,17 +2468,19 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+      case VB_CHIP_302:
+      case VB_CHIP_302B:
+      case VB_CHIP_302LV:
+-        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++        SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+         break;
+      case VB_CHIP_UNKNOWN:
+-        if (SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+-	    SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+-	    SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++        if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
++	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
++	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
++           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+   	}
+         break;
+    }
+ 
++   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
++
+    SiS_DisplayOn(SiS_Pr);
+    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+ 
+@@ -2386,7 +2492,6 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+       }
+    }
+ 
+-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -2412,7 +2517,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, 
+       }
+    }
+ 
+-   /* TW: SetPitch: Adapt to virtual size & position */
++   /* SetPitch: Adapt to virtual size & position */
+    SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+ 
+    return TRUE;
+@@ -2442,12 +2547,14 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+    
+    if(SiS_Pr->UseCustomMode) {
+       ModeNo = 0xfe;
+-   }      
+-   
++   }
++
+    SiSInitPtr(SiS_Pr, HwDeviceExtension);
+ 
+    SiSRegInit(SiS_Pr, BaseAddr);
+ 
++   SiS_GetSysFlags(SiS_Pr, HwDeviceExtension);
++
+ #ifdef LINUX_XF86
+    if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+    else
+@@ -2458,7 +2565,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+ #ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
+ #endif
+-#endif	 	 
++#endif
+ 
+    SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+ 
+@@ -2469,10 +2576,10 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+    if(!SiS_Pr->UseCustomMode) {
+       /* TW: Shift the clear-buffer-bit away */
+       ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+-   }      
++   }
+ 
+ #ifdef LINUX_XF86
+-   /* TW: We never clear the buffer in X */
++   /* We never clear the buffer in X */
+    ModeNo |= 0x8000;
+ #endif
+ 
+@@ -2490,21 +2597,21 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+    SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+ 
+    if(!SiS_Pr->UseCustomMode) {
+-   
++
+       /* 2.Get ModeID Table  */
+       temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+       if(temp == 0) return(0);
+-      
++
+    } else {
+-   
++
+       ModeIdIndex = 0;
+-      
++
+    }
+-    
+-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
++
++   /* Determine VBType (301,301B,301LV,302B,302LV) */
+    SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
+ 
+-   /* TW: Init/restore some VB registers */
++   /* Init/restore some VB registers */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(HwDeviceExtension->jChipType >= SIS_315H) {
+          SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+@@ -2525,8 +2632,12 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+        }
+    }
+    
+-   /* TW: Get VB information (connectors, connected devices) */
+-   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++   /* Get VB information (connectors, connected devices) */
++   if(SiS_Pr->UseCustomMode) {
++      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
++   } else {
++      SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
++   }
+    SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
+    SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+ 
+@@ -2535,22 +2646,32 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+    if(!temp) return(0);
+ 
+    if(HwDeviceExtension->jChipType >= SIS_315H) {
+-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++      if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
++         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+             if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
++         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
++            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+          }
+       }
+ 
+-      /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
+       if(IS_SIS650) {
+-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+-	  }
++         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
++	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
++	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
++	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
++	 }
+       }
+    }
+ 
+-   /* TW: Set mode on CRT1 */
++   if(SiS_Pr->UseCustomMode) {
++      SiS_Pr->CRT1UsesCustomMode = TRUE;
++      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
++      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
++   } else {
++      SiS_Pr->CRT1UsesCustomMode = FALSE;
++   }
++
++   /* Set mode on CRT1 */
+    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+    	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+    } else {
+@@ -2559,7 +2680,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+      }
+    }
+ 
+-   /* TW: Set mode on CRT2 */
++   /* Set mode on CRT2 */
+    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
+      switch (HwDeviceExtension->ujVBChipID) {
+      case VB_CHIP_301:
+@@ -2568,18 +2689,20 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+      case VB_CHIP_302:
+      case VB_CHIP_302B:
+      case VB_CHIP_302LV:
+-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+         break;
+      case VB_CHIP_UNKNOWN:
+ 	if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+ 	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+ 	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
+-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
++           SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+         break;
+      }
+    }
+    
+    SiS_HandleCRT1(SiS_Pr);
++
++   SiS_StrangeStuff(SiS_Pr, HwDeviceExtension);
+    
+    SiS_DisplayOn(SiS_Pr);
+    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+@@ -2592,7 +2715,6 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+       }
+    }
+ 
+-   /* TW: New from 650/LV 1.10.6x and 1.10.7w */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+@@ -2627,7 +2749,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+ 
+ #ifdef LINUX_XF86
+    if(pScrn) {
+-      /* TW: SetPitch: Adapt to virtual size & position */
++      /* SetPitch: Adapt to virtual size & position */
+       if((ModeNo > 0x13) && (dosetpitch)) {
+          SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
+       }
+@@ -2637,7 +2759,7 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+    }
+ #endif
+ 
+-#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
++#ifndef LINUX_XF86  /* We never lock registers in XF86 */
+    if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+    else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
+ #endif
+@@ -2646,10 +2768,15 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_
+ }
+ 
+ void
+-SiS_SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
++SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
++{
++   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
++}
++
++void
++SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+ {
+-   /* For 550 dstn */
+-   SiS_Pr->SiS_IF_DEF_DSTN = 1;
++   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
+ }
+ 
+ void
+@@ -2663,13 +2790,73 @@ SiS_HandleCRT1(SiS_Private *SiS_Pr)
+   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+ 
+ #if 0
+-  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
+-     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
++  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
++     if((SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
++        (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
++        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
++     }
+   }
+ #endif
+ }
+ 
+ void
++SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++   unsigned char cr5f, temp1, temp2;
++
++   /* You should use the macros, not these flags directly */
++
++   SiS_Pr->SiS_SysFlags = 0;
++   if(HwDeviceExtension->jChipType == SIS_650) {
++      cr5f = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
++      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
++      temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
++      temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++      if((!temp1) || (temp2)) {
++         switch(cr5f) {
++	    case 0x80:
++	    case 0x90:
++	    case 0xc0:
++	       SiS_Pr->SiS_SysFlags |= SF_IsM650;  break;
++	    case 0xa0:
++	    case 0xb0:
++	    case 0xe0:
++	       SiS_Pr->SiS_SysFlags |= SF_Is651;   break;
++	 }
++      } else {
++         switch(cr5f) {
++	    case 0x90:
++	       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
++	       switch(temp1) {
++	          case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
++		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
++		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
++	       }
++	       break;
++	    case 0xb0:
++	       SiS_Pr->SiS_SysFlags |= SF_Is652;  break;
++	    default:
++	       SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
++	 }
++      }
++   }
++}
++
++void
++SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
++{
++   if((IS_SIS651) || (IS_SISM650)) {
++      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
++      SiS_SetReg1(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
++      SiS_SetReg1(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
++      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
++      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
++   }
++   /* !!! This does not support modes < 0x13 !!! */
++}
++
++void
+ SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                  USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
+ {
+@@ -2683,6 +2870,9 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, UC
+     }
+   }
+ 
++  /* 550, 651 */
++  SiS_WhatTheHellIsThis(SiS_Pr,HwDeviceExtension,BaseAddr);
++
+   SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
+   SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
+   SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
+@@ -2759,15 +2949,20 @@ void
+ SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+ {
+    SISPtr pSiS = SISPTR(pScrn);
++   BOOLEAN isslavemode = FALSE;
++
++   if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
++       ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
++         ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
++      isslavemode = TRUE;
++   }
+ 
+-   /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
+-   if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
+-       ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+-         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+-           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
++   /* We need to set pitch for CRT1 if bridge is in slave mode, too */
++   if( (pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode) ) {
+    	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
+    }
+-   if (pSiS->VBFlags & DISPTYPE_DISP2) {
++   /* We must not set the pitch for CRT2 if bridge is in slave mode */
++   if( (pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode) ) {
+    	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+    }
+ }
+@@ -2790,7 +2985,7 @@ SiS_SetPitchCRT2(SiS_Private *SiS_Pr, Sc
+     SISPtr pSiS = SISPTR(pScrn);
+     ULong  HDisplay,temp;
+ 
+-    HDisplay = pSiS->scrnPitch / 8;
++    HDisplay = pSiS->scrnPitch2 / 8;
+ 
+     /* Unlock CRT2 */
+     if (pSiS->VGAEngine == SIS_315_VGA)
+@@ -2880,7 +3075,6 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, UC
+    return TRUE;
+ }
+ 
+-/* For SiS 300 oem util: Search VBModeID */
+ BOOLEAN
+ SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
+ {
+@@ -2946,6 +3140,81 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, UCHA
+    return index;
+ }
+ 
++static void
++SiS_WhatIsThis1a(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++   USHORT temp, tempbl, tempbh;
++
++   tempbl = tempbh = somevalue;
++   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
++   temp &= 0xf0;
++   tempbl >>= 4;
++   temp |= tempbl;
++   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
++   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
++   temp &= 0xf0;
++   tempbh &= 0x0f;
++   temp |= tempbh;
++   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
++}
++
++static void
++SiS_WhatIsThis1b(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++   USHORT temp, tempbl, tempbh;
++
++   tempbl = tempbh = somevalue;
++   temp = SiS_GetReg2(SiS_Pr->SiS_P3cb);
++   temp &= 0x0f;
++   tempbl &= 0xf0;
++   temp |= tempbl;
++   SiS_SetReg3(SiS_Pr->SiS_P3cb, temp);
++   temp = SiS_GetReg2(SiS_Pr->SiS_P3cd);
++   temp &= 0x0f;
++   tempbh <<= 4;
++   temp |= tempbh;
++   SiS_SetReg3(SiS_Pr->SiS_P3cd, temp);
++}
++
++static void
++SiS_WhatIsThis2b(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++   SiS_WhatIsThis1a(SiS_Pr, somevalue);
++   SiS_WhatIsThis1b(SiS_Pr, somevalue);
++}
++
++static void
++SiS_WhatIsThis1(SiS_Private *SiS_Pr)
++{
++   SiS_WhatIsThis2b(SiS_Pr, 0);
++}
++
++static void
++SiS_WhatIsThis2a(SiS_Private *SiS_Pr, USHORT somevalue)
++{
++   USHORT temp = somevalue >> 8;
++
++   temp &= 0x07;
++   temp |= (temp << 4);
++   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1d,temp);
++   SiS_WhatIsThis2b(SiS_Pr, somevalue);
++}
++
++static void
++SiS_WhatIsThis2(SiS_Private *SiS_Pr)
++{
++   SiS_WhatIsThis2a(SiS_Pr, 0);
++}
++
++void
++SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
++{
++   if(IS_SIS65x) {
++      SiS_WhatIsThis1(SiS_Pr);
++      SiS_WhatIsThis2(SiS_Pr);
++   }
++}
++
+ void
+ SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+ {
+@@ -3027,7 +3296,7 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCH
+       (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+-        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
++         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
+       }
+     }
+   }
+@@ -3065,7 +3334,7 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHA
+       }
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+          if(HwDeviceExtension->jChipType >= SIS_315H) {
+-	    if(IS_SIS650740 || IS_SIS550) {  
++	    if(IS_SIS550650740660) {
+ 	       /* 315, 330 don't do this */
+ 	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 
+ 	          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+@@ -3148,7 +3417,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
+   USHORT tempah,i,modeflag,j;
+ #ifdef SIS315H
+   USHORT temp;
+-  USHORT ResInfo,DisplayType;
++  USHORT ResIndex,DisplayType;
+   const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+ #endif
+ 
+@@ -3171,7 +3440,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
+      /* LCDA */
+ 
+      temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+-                       RefreshRateTableIndex,&ResInfo,&DisplayType);
++                       RefreshRateTableIndex,&ResIndex,&DisplayType);
+ 
+      switch(DisplayType) {
+       case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;      break;
+@@ -3197,30 +3466,30 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
+       default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
+      }
+ 
+-     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
++     tempah = (LCDACRT1Ptr+ResIndex)->CR[0];
+      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+      for(i=0x01,j=1;i<=0x07;i++,j++){
+-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+      }
+      for(i=0x10,j=8;i<=0x12;i++,j++){
+-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+      }
+      for(i=0x15,j=11;i<=0x16;i++,j++){
+-       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
++       tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+      }
+      for(i=0x0A,j=13;i<=0x0C;i++,j++){
+-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
++       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+        SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+      }
+ 
+-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
++     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
+      tempah &= 0x0E0;
+      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+ 
+-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
++     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
+      tempah &= 0x01;
+      tempah <<= 5;
+      if(modeflag & DoubleScanMode)  tempah |= 0x080;
+@@ -3301,7 +3570,7 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCH
+ 
+ BOOLEAN
+ SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
++		   USHORT RefreshRateTableIndex,USHORT *ResIndex,
+ 		   USHORT *DisplayType)
+  {
+   USHORT tempbx=0,modeflag=0;
+@@ -3320,7 +3589,7 @@ SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, 
+   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
+   if(modeflag & HalfDCLK)                 tempbx += 16;
+ 
+-  *ResInfo = CRT2CRTC & 0x3F;
++  *ResIndex = CRT2CRTC & 0x3F;
+   *DisplayType = tempbx;
+ 
+   return 1;
+@@ -3470,6 +3739,9 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
+   USHORT data,data2,data3;
+   USHORT infoflag=0,modeflag;
+   USHORT resindex,xres;
++#ifdef SIS315H
++  ULONG  longdata;
++#endif
+ 
+   if(SiS_Pr->UseCustomMode) {
+      modeflag = SiS_Pr->CModeFlag;
+@@ -3490,11 +3762,11 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
+ 
+   data2 = 0;
+   if(ModeNo > 0x13) {
+-    if(SiS_Pr->SiS_ModeType > 0x02) {
+-       data2 |= 0x02;
+-       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
+-       data2 |= data3;
+-    }
++     if(SiS_Pr->SiS_ModeType > 0x02) {
++        data2 |= 0x02;
++        data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
++        data2 |= data3;
++     }
+   }
+ #ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", 
+@@ -3517,7 +3789,8 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
+   if(HwDeviceExtension->jChipType != SIS_300) {
+      data = 0x0000;
+      if(infoflag & InterlaceMode) {
+-        if(xres == 1024) data = 0x0035;
++        if(xres <= 800)  data = 0x0020;
++        else if(xres <= 1024) data = 0x0035;
+         else data = 0x0048;
+      }
+      data2 = data & 0x00FF;
+@@ -3549,6 +3822,7 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
+      } else {
+         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
+      }
++     /* 651 BIOS does something for mode 0x12 here */
+   }
+ 
+   if(HwDeviceExtension->jChipType != SIS_300) {
+@@ -3604,9 +3878,9 @@ SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr,
+ 	  data2 *= data3;
+ 
+ 	  data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
+-	  data3 *= 1024;
++	  longdata = data3 * 1024;
+ 
+-	  data2 = data3 / data2;
++	  data2 = longdata / data2;
+ 
+ 	  if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+             if(data2 >= 0x19c)      data = 0xba;
+@@ -3679,7 +3953,7 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UC
+     if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+ 
+-  } else { 						/* 310/325 series */
++  } else { 						/* 315 series */
+ 
+     data = 0;
+     if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
+@@ -3688,12 +3962,6 @@ SiS_SetVCLKState(SiS_Private *SiS_Pr, UC
+     if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+     }
+-#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
+-    data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);	  	/* DAC pedestal */
+-    data &= 0xE7;
+-    if(VCLK<200) data |= 0x10;
+-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
+-#endif
+   }
+ 
+   data2 = 0x03;
+@@ -3918,7 +4186,9 @@ GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW
+ 
+   } else if((HwDeviceExtension->jChipType == SIS_550) ||
+             (HwDeviceExtension->jChipType == SIS_740) ||
+-            (HwDeviceExtension->jChipType == SIS_650)) {
++            (HwDeviceExtension->jChipType == SIS_650) ||
++	    (HwDeviceExtension->jChipType == SIS_660) ||
++	    (HwDeviceExtension->jChipType == SIS_760)) {
+ 
+   	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+       	counter++;
+@@ -4728,7 +4998,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
+           SiS_Pr->SiS_SetFlag = 0x00;
+           SiS_Pr->SiS_ModeType = ModeVGA;
+           SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+-          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
++          SiS_SetCRT2Group(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+           for(i=0;i<20;i++) {
+             SiS_LongWait(SiS_Pr);
+           }
+@@ -4766,7 +5036,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
+ #ifdef SIS315H
+ 	   if(HwDeviceExtension->jChipType >= SIS_315H) {
+ 	        OutputSelect = ROMAddr[0xf3];
+-		if(HwDeviceExtension->jChipType == SIS_330) {
++		if(HwDeviceExtension->jChipType >= SIS_330) {
+ 		     OutputSelect = ROMAddr[0x11b];
+ 		}
+ 	   }
+@@ -4814,7 +5084,7 @@ SiS_GetSenseStatus(SiS_Private *SiS_Pr, 
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
+       if(!(P2reg0 & 0x20)) {
+         SiS_Pr->SiS_VBInfo = DisableCRT2Display;
+-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
++        SiS_SetCRT2Group(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+       }
+     }
+   }
+@@ -4884,111 +5154,6 @@ SiS_SenseCHTV(SiS_Private *SiS_Pr)
+ }
+ #endif /* LINUXBIOS */
+ 
+-/*  ================ for TC only =================  */
+-
+-#ifdef TC
+-
+-int
+-INT1AReturnCode(union REGS regs)
+-{
+-  if (regs.x.cflag)
+-  {
+-    /*printf("Error to find pci device!\n"); */
+-    return 1;
+-  }
+-
+-  switch(regs.h.ah)
+-  {
+-    case 0: return 0;
+-            break;
+-    case 0x81: printf("Function not support\n");
+-               break;
+-    case 0x83: printf("bad vendor id\n");
+-               break;
+-    case 0x86: printf("device not found\n");
+-               break;
+-    case 0x87: printf("bad register number\n");
+-               break;
+-    case 0x88: printf("set failed\n");
+-               break;
+-    case 0x89: printf("buffer too small");
+-               break;
+-  }
+-  return 1;
+-}
+-
+-unsigned
+-FindPCIIOBase(unsigned index,unsigned deviceid)
+-{
+-  union REGS regs;
+-
+-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
+-  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
+-  regs.x.cx = deviceid;
+-  regs.x.dx = 0x1039;
+-  regs.x.si = index;  /* find n-th device */
+-
+-  int86(0x1A, &regs, &regs);
+-
+-  if (INT1AReturnCode(regs)!=0)
+-    return 0;
+-
+-  /* regs.h.bh *//* bus number */
+-  /* regs.h.bl *//* device number */
+-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
+-  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
+-  regs.x.cx = deviceid;
+-  regs.x.dx = 0x1039;
+-  regs.x.di = 0x18;  /* register number */
+-  int86(0x1A, &regs, &regs);
+-
+-  if (INT1AReturnCode(regs)!=0)
+-    return 0;
+-  return regs.x.cx;
+-}
+-
+-
+-void
+-main(int argc, char *argv[])
+-{
+-  SIS_HW_DEVICE_INFO  HwDeviceExtension;
+-  USHORT temp;
+-  USHORT ModeNo;
+-
+-  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
+-  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
+-
+-#ifdef SIS300  
+-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
+-  HwDeviceExtension.jChipType = SIS_630;
+-#endif
+-
+-#ifdef SIS315H  
+-//  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
+-//  HwDeviceExtension.jChipType = SIS_550;
+-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
+-  HwDeviceExtension.jChipType = SIS_315H;
+-#endif
+-
+-  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
+-  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
+-  HwDeviceExtension.bSkipDramSizing = FALSE;
+-  HwDeviceExtension.ulVideoMemorySize = 0;
+-  if(argc==2) {
+-    ModeNo=atoi(argv[1]);
+-  }
+-  else {
+-    ModeNo=0x2e;
+-    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
+-    /*ModeNo=0x38; *//* 1024x768x 8bpp */
+-    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
+-    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
+-  }
+- /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
+-  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
+-}
+-#endif /* TC END */
+-
+ /* ================ XFREE86 ================= */
+ 
+ /* Helper functions */
+@@ -5000,44 +5165,78 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
+    SISPtr pSiS = SISPTR(pScrn);
+    int    out_n, out_dn, out_div, out_sbit, out_scale;
+    int    depth = pSiS->CurrentLayout.bitsPerPixel;
+-   
+-#ifdef SISDUALHEAD
+-   if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
+-       ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
+-#else      
+-   if(VBFlags & DISPTYPE_DISP2) return 0; 
+-#endif   
++   unsigned int vclk[5];
++
++#define Midx         0
++#define Nidx         1
++#define VLDidx       2
++#define Pidx         3
++#define PSNidx       4
++
++   pSiS->SiS_Pr->CModeFlag = 0;
+    
+    pSiS->SiS_Pr->CDClock = mode->Clock;
+-   
++
+    pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
+    pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
+    pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
+    pSiS->SiS_Pr->CHTotal = mode->HTotal;
+-   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+-   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+-   
++
+    pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
+    pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
+    pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
+    pSiS->SiS_Pr->CVTotal = mode->VTotal;
++
++   pSiS->SiS_Pr->CFlags = mode->Flags;
++
++   if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
++         pSiS->SiS_Pr->CVDisplay >>= 1;
++	 pSiS->SiS_Pr->CVSyncStart >>= 1;
++	 pSiS->SiS_Pr->CVSyncEnd >>= 1;
++	 pSiS->SiS_Pr->CVTotal >>= 1;
++   }
++   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
++         /* pSiS->SiS_Pr->CDClock <<= 1; */
++	 pSiS->SiS_Pr->CVDisplay <<= 1;
++	 pSiS->SiS_Pr->CVSyncStart <<= 1;
++	 pSiS->SiS_Pr->CVSyncEnd <<= 1;
++	 pSiS->SiS_Pr->CVTotal <<= 1;
++   }
++
++   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
++   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
+    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+-   
+-   pSiS->SiS_Pr->CFlags = mode->Flags;
+ 
+-   SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
+-   
++   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
++      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
++      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
++      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
++      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
++      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+ #ifdef TWDEBUG
+-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+-      	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+-#endif	
+-
+-   pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+-   pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+-   pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+-   pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+-   pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
++      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
++        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
++#endif
++   } else {
++      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
++      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
++      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
++      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
++      if(vclk[Pidx] <= 4) {
++         /* postscale 1,2,3,4 */
++         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
++      } else {
++         /* postscale 6,8 */
++         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
++	 pSiS->SiS_Pr->CSR2C |= 0x80;
++      }
++#ifdef TWDEBUG
++      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
++        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
++#endif
++   }
++
+    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+ 
+    pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
+@@ -5045,9 +5244,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
+    pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
+    pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+    pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
+-   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | 
++   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
+        				  (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+-   
++
+    pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
+    pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
+  	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+@@ -5057,50 +5256,50 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
+ 	 			| (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
+ 	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ 	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
+-    
++
+    pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* cr9 */
+-    
+-#if 0    
++
++#if 0
+    if (mode->VScan >= 32)
+ 	regp->CRTC[9] |= 0x1F;
+    else if (mode->VScan > 1)
+ 	regp->CRTC[9] |= mode->VScan - 1;
+-#endif	
++#endif
+ 
+-   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF;	/* cr10 */
+-   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80;	/* cr11 */
+-   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF;		/* cr12 */
+-   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;	/* cr15 */
+-   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF;		/* cr16 */
+-   
+-   pSiS->SiS_Pr->CCRT1CRTC[13] = 
++   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart     ) & 0xFF;		/* cr10 */
++   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;	/* cr11 */
++   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay    - 1) & 0xFF;		/* cr12 */
++   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;		/* cr15 */
++   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd   - 1) & 0xFF;		/* cr16 */
++
++   pSiS->SiS_Pr->CCRT1CRTC[13] =
+                         GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
+                         GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
+                         GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+                         GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
+                         GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
+-                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd   -1),   4:4, 5:5) ;  
++                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
+ 
+-   pSiS->SiS_Pr->CCRT1CRTC[14] = 
++   pSiS->SiS_Pr->CCRT1CRTC[14] =
+                         GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
+                         GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
+                         GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+                         GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
+ 
+-        
++
+    pSiS->SiS_Pr->CCRT1CRTC[15] =
+                         GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+-                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ; 
+-			
++                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
++
+    switch(depth) {
+-   case 8: 			
+-      	pSiS->SiS_Pr->CModeFlag = 0x223b;
++   case 8:
++      	pSiS->SiS_Pr->CModeFlag |= 0x223b;
+ 	break;
+-   case 16: 			
+-      	pSiS->SiS_Pr->CModeFlag = 0x227d;
++   case 16:
++      	pSiS->SiS_Pr->CModeFlag |= 0x227d;
+ 	break;
+-   case 32: 			
+-      	pSiS->SiS_Pr->CModeFlag = 0x22ff;
++   case 32:
++      	pSiS->SiS_Pr->CModeFlag |= 0x22ff;
+ 	break;		
+    default: 
+    	return 0;	
+@@ -5114,9 +5313,9 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
+ 	pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+    if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
+         pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+-   
++
+    pSiS->SiS_Pr->CInfoFlag = 0x0007;
+-   if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 
++   if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
+    	pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+    if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 
+    	pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+@@ -5152,13 +5351,13 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pSc
+    	pSiS->SiS_Pr->CSR2B,
+ 	pSiS->SiS_Pr->CSR2C,
+ 	pSiS->SiS_Pr->CSRClock);
+-#endif   	
++#endif
+    return 1;
+ }
+ 
+ /* TW: Build a list of supported modes */
+ DisplayModePtr
+-SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
++SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
+ {
+    SISPtr         pSiS = SISPTR(pScrn);
+    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+@@ -5166,11 +5365,16 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
+    unsigned char  sr2b, sr2c;
+    float          num, denum, postscalar, divider;
+-   int            A, B, C, D, E, F, temp, i, j, index, vclkindex;
+-   DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
++   int            A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
++   DisplayModePtr new = NULL, current = NULL, first = NULL;
++   BOOLEAN        done = FALSE;
++#if 0
++   DisplayModePtr backup = NULL;
++#endif
+ 
+    pSiS->backupmodelist = NULL;
+-   
++   pSiS->AddedPlasmaModes = FALSE;
++
+    /* Initialize our pointers */
+    if(pSiS->VGAEngine == SIS_300_VGA) {
+ #ifdef SIS300
+@@ -5194,15 +5398,20 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+       if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
+ #endif      
+ 
+-      if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
+-      	 ((pSiS->DSTN) &&
+-	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
+-	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
+-	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480)))  {
++      /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
++      if((!pSiS->FSTN) &&
++	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a))  {
+            i++;
+       	   continue;
+       }
+-      
++      if((pSiS->FSTN) &&
++         (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
++	 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
++	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
++	   i++;
++	   continue;
++      }
++
+       if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+       memset(new, 0, sizeof(DisplayModeRec));
+       if(!(new->name = xalloc(10))) {
+@@ -5216,13 +5425,13 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+       }
+ 
+       current = new;
+-      
++
+       sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
+                                       pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
+ 
+       current->status = MODE_OK;
+ 
+-      current->type = M_T_DEFAULT; 
++      current->type = M_T_DEFAULT;
+ 
+       vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
+       if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
+@@ -5235,7 +5444,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+               ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
+       num = (sr2b & 0x7f) + 1.0;
+       denum = (sr2c & 0x1f) + 1.0;
+-      
++
+ #ifdef TWDEBUG
+       xf86DrvMsg(0, X_INFO, "------------\n");
+       xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
+@@ -5303,10 +5512,29 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+ 
+       D = B - F - C;
+ 
+-      current->HDisplay   = (E * 8);
+-      current->HSyncStart = (E * 8) + (F * 8);
+-      current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
+-      current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
++      if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
++	 ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
++	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
++
++	 /* Terrible hack, but correct CRTC data for
++	  * these modes only produces a black screen...
++	  * (HRE is 0, leading into a too large C and
++	  * a negative D. The CRT controller does not
++	  * seem to like correcting HRE to 50
++	  */
++	 current->HDisplay   = 320;
++         current->HSyncStart = 328;
++         current->HSyncEnd   = 376;
++         current->HTotal     = 400;
++
++      } else {
++
++         current->HDisplay   = (E * 8);
++         current->HSyncStart = (E * 8) + (F * 8);
++         current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
++         current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
++
++      }
+ 
+ #ifdef TWDEBUG
+       xf86DrvMsg(0, X_INFO,
+@@ -5430,7 +5658,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+ 	 current->VSyncStart <<= 1;
+ 	 current->VSyncEnd <<= 1;
+ 	 current->VTotal <<= 1;
+-	 current->VTotal |= 1; 
++	 current->VTotal |= 1;
+       }
+       if(current->Flags & V_DBLSCAN) {
+          current->Clock >>= 1;
+@@ -5440,6 +5668,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+ 	 current->VTotal >>= 1;
+       }
+ 
++#if 0
+       if((backup = xalloc(sizeof(DisplayModeRec)))) {
+          if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
+ 	 else {
+@@ -5458,6 +5687,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+ 	 backup->Flags = current->Flags;
+ 	 backup->Clock = current->Clock;
+       }
++#endif
+ 
+ #ifdef TWDEBUG
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+@@ -5470,6 +5700,187 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScr
+       i++;
+    }
+ 
++   /* Add non-standard LCD modes for panel's detailed timings */
++
++   if(!includelcdmodes) return first;
++
++   xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
++      pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
++
++   i = 0;
++   while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
++
++     if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
++
++        for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
++
++	    if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
++
++	       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++	       	  "Identified %s panel, adding specific modes\n",
++		  SiS_PlasmaTable[i].plasmaname);
++
++	       for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
++
++	          if(isfordvi) {
++		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
++		  } else {
++		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
++		  }
++
++	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
++
++                  memset(new, 0, sizeof(DisplayModeRec));
++                  if(!(new->name = xalloc(10))) {
++      		     xfree(new);
++		     return first;
++                  }
++                  if(!first) first = new;
++                  if(current) {
++                     current->next = new;
++	             new->prev = current;
++                  }
++
++                  current = new;
++
++		  pSiS->AddedPlasmaModes = TRUE;
++
++		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
++
++	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
++                                                  SiS_PlasmaMode[l].VDisplay);
++
++                  current->status = MODE_OK;
++
++                  current->type = M_T_BUILTIN;
++
++		  current->Clock = SiS_PlasmaMode[l].clock;
++            	  current->SynthClock = current->Clock;
++
++                  current->HDisplay   = SiS_PlasmaMode[l].HDisplay;
++                  current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
++                  current->HSyncEnd   = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
++                  current->HTotal     = SiS_PlasmaMode[l].HTotal;
++
++		  current->VDisplay   = SiS_PlasmaMode[l].VDisplay;
++                  current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
++                  current->VSyncEnd   = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
++                  current->VTotal     = SiS_PlasmaMode[l].VTotal;
++
++                  current->CrtcHDisplay = current->HDisplay;
++                  current->CrtcHBlankStart = current->HSyncStart;
++                  current->CrtcHSyncStart = current->HSyncStart;
++                  current->CrtcHSyncEnd = current->HSyncEnd;
++                  current->CrtcHBlankEnd = current->HSyncEnd;
++                  current->CrtcHTotal = current->HTotal;
++
++                  current->CrtcVDisplay = current->VDisplay;
++                  current->CrtcVBlankStart = current->VSyncStart;
++                  current->CrtcVSyncStart = current->VSyncStart;
++                  current->CrtcVSyncEnd = current->VSyncEnd;
++                  current->CrtcVBlankEnd = current->VSyncEnd;
++                  current->CrtcVTotal = current->VTotal;
++
++                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
++                     current->Flags |= V_PHSYNC;
++                  else
++                     current->Flags |= V_NHSYNC;
++
++                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
++                     current->Flags |= V_PVSYNC;
++                  else
++                     current->Flags |= V_NVSYNC;
++
++		  if(current->HDisplay > pSiS->LCDwidth)
++		     pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
++	          if(current->VDisplay > pSiS->LCDheight)
++		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
++
++               }
++	       done = TRUE;
++	       break;
++	    }
++	}
++     }
++
++     i++;
++
++   }
++
++   if(pSiS->SiS_Pr->CP_HaveCustomData) {
++
++      for(i=0; i<7; i++) {
++
++         if(pSiS->SiS_Pr->CP_DataValid[i]) {
++
++            if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
++
++            memset(new, 0, sizeof(DisplayModeRec));
++            if(!(new->name = xalloc(10))) {
++      		xfree(new);
++		return first;
++            }
++            if(!first) first = new;
++            if(current) {
++               current->next = new;
++	       new->prev = current;
++            }
++
++            current = new;
++
++            sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
++                                            pSiS->SiS_Pr->CP_VDisplay[i]);
++
++            current->status = MODE_OK;
++
++            current->type = M_T_BUILTIN;
++
++            current->Clock = pSiS->SiS_Pr->CP_Clock[i];
++            current->SynthClock = current->Clock;
++
++            current->HDisplay   = pSiS->SiS_Pr->CP_HDisplay[i];
++            current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
++            current->HSyncEnd   = pSiS->SiS_Pr->CP_HSyncEnd[i];
++            current->HTotal     = pSiS->SiS_Pr->CP_HTotal[i];
++
++            current->VDisplay   = pSiS->SiS_Pr->CP_VDisplay[i];
++            current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
++            current->VSyncEnd   = pSiS->SiS_Pr->CP_VSyncEnd[i];
++            current->VTotal     = pSiS->SiS_Pr->CP_VTotal[i];
++
++            current->CrtcHDisplay = current->HDisplay;
++            current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
++            current->CrtcHSyncStart = current->HSyncStart;
++            current->CrtcHSyncEnd = current->HSyncEnd;
++            current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
++            current->CrtcHTotal = current->HTotal;
++
++            current->CrtcVDisplay = current->VDisplay;
++            current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
++            current->CrtcVSyncStart = current->VSyncStart;
++            current->CrtcVSyncEnd = current->VSyncEnd;
++            current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
++            current->CrtcVTotal = current->VTotal;
++
++	    if(pSiS->SiS_Pr->CP_SyncValid[i]) {
++               if(pSiS->SiS_Pr->CP_HSync_P[i])
++                  current->Flags |= V_PHSYNC;
++               else
++                  current->Flags |= V_NHSYNC;
++
++               if(pSiS->SiS_Pr->CP_VSync_P[i])
++                  current->Flags |= V_PVSYNC;
++               else
++                  current->Flags |= V_NVSYNC;
++	    } else {
++	       /* No sync data? Use positive sync... */
++	       current->Flags |= V_PHSYNC;
++	       current->Flags |= V_PVSYNC;
++	    }
++         }
++      }
++   }
++
+    return first;
+ 
+ }
+@@ -5486,25 +5897,25 @@ sisfb_mode_rate_to_dclock(SiS_Private *S
+     UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+     ULONG  temp = 0;
+     int    Clock;
+-    
++
+     if(HwDeviceExtension->jChipType < SIS_315H) {
+ #ifdef SIS300
+        InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+ #else
+-       return 65;
++       return 65 * 1000 * 1000;
+ #endif
+     } else {
+ #ifdef SIS315H
+        InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+ #else
+-       return 65;
++       return 65 * 1000 * 1000;
+ #endif
+     }
+-    
++
+     temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
+     if(!temp) {
+     	printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+-    	return 65;
++    	return 65 * 1000 * 1000;
+     }
+     
+     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+@@ -5518,6 +5929,56 @@ sisfb_mode_rate_to_dclock(SiS_Private *S
+     return(Clock);
+ }
+ 
++BOOLEAN
++sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
++{
++    USHORT ModeNo = modeno;
++    USHORT ModeIdIndex = 0, CRT1Index = 0;
++    USHORT RefreshRateTableIndex = 0;
++    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
++    ULONG  temp = 0;
++    unsigned char  sr_data, cr_data, cr_data2;
++
++    if(HwDeviceExtension->jChipType < SIS_315H) {
++#ifdef SIS300
++       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
++#else
++       return FALSE;
++#endif
++    } else {
++#ifdef SIS315H
++       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
++#else
++       return FALSE;
++#endif
++    }
++
++    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
++    if(!temp) return FALSE;
++
++    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
++    RefreshRateTableIndex += (rateindex - 1);
++    CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++
++    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
++    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
++    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
++
++    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
++    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
++    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
++    *vtotal = ((cr_data & 0xFF) |
++               ((unsigned short)(cr_data2 & 0x01) <<  8) |
++	       ((unsigned short)(cr_data2 & 0x20) <<  4) |
++	       ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
++
++    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
++       *vtotal *= 2;
++
++    return TRUE;
++}
++
+ int
+ sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ 			 unsigned char modeno, unsigned char rateindex,
+@@ -5606,17 +6067,32 @@ sisfb_mode_rate_to_ddata(SiS_Private *Si
+     C = (temp > 0) ? temp : (temp + 64);
+ 
+     D = B - F - C;
+-    
+-    *left_margin = D * 8;
+-    *right_margin = F * 8;
+-    *hsync_len = C * 8;
++
++    if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
++       ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
++	(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
++
++	 /* Terrible hack, but the correct CRTC data for
++	  * these modes only produces a black screen...
++	  */
++       *left_margin = (400 - 376);
++       *right_margin = (328 - 320);
++       *hsync_len = (376 - 328);
++
++    } else {
++
++       *left_margin = D * 8;
++       *right_margin = F * 8;
++       *hsync_len = C * 8;
++
++    }
+ 
+     sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
+ 
+     cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
+-    
++
+     cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
+-    
++
+     /* Vertical total */
+     VT = (cr_data & 0xFF) |
+          ((unsigned short) (cr_data2 & 0x01) << 8) |
+@@ -5699,19 +6175,19 @@ sisfb_mode_rate_to_ddata(SiS_Private *Si
+ 	  j++;
+       }
+     }       
+-       
+-#if 0  /* That's bullshit, only the resolution needs to be shifted */    
++
+     if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
++#if 0  /* Do this? */
+        *upper_margin <<= 1;
+        *lower_margin <<= 1;
+        *vsync_len <<= 1;
++#endif
+     } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+        *upper_margin >>= 1;
+        *lower_margin >>= 1;
+        *vsync_len >>= 1;
+-    }  
+-#endif
+-          
++    }
++
+     return 1;       
+ }			  
+ 
+--- linux-2.6.0-test6/drivers/video/sis/initdef.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/video/sis/initdef.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,5 +1,37 @@
+ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+-
++/*
++ * Global definitions for init.c and init301.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+ 
+ #ifndef _INITDEF_
+ #define _INITDEF_
+@@ -22,12 +54,19 @@
+ #define VB_SIS301B302B          (VB_SIS301B|VB_SIS302B)
+ #define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
+ 
+-#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
+-
+ #define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
+ #define IS_SIS740		(HwDeviceExtension->jChipType == SIS_740)
+ #define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
+ #define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
++#define IS_SIS651	        (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
++#define IS_SISM650	        (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
++#define IS_SIS65x               (IS_SIS651 || IS_SISM650)
++#define IS_SIS660		(HwDeviceExtension->jChipType == SIS_660)
++#define IS_SIS760		(HwDeviceExtension->jChipType == SIS_760)
++#define IS_SIS650660            (IS_SIS650 || IS_SIS660)
++#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
++#define IS_SIS650740660         (IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
++#define IS_SIS550650740660      (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
+ 
+ #define CRT1Len                 17
+ #define LVDSCRT1Len             15
+@@ -63,7 +102,7 @@
+ #define SupportTV               0x0008
+ #define SupportHiVisionTV       0x0010
+ #define SupportLCD              0x0020
+-#define SupportRAMDAC2          0x0040  
++#define SupportRAMDAC2          0x0040
+ #define NoSupportTV             0x0070
+ #define NoSupportHiVisionTV     0x0060
+ #define NoSupportLCD            0x0058
+@@ -105,6 +144,24 @@
+ #define HotKeySwitch            0x8000  /* TW: ? */
+ #define SetCRT2ToLCDA           0x8000
+ 
++/* SetFlag */
++#define ProgrammingCRT2         0x01
++#define TVSimuMode              0x02
++#define RPLLDIV2XO              0x04
++#define LCDVESATiming           0x08
++#define EnableLVDSDDA           0x10
++#define SetDispDevSwitchFlag    0x20
++#define CheckWinDos             0x40
++#define SetDOSMode              0x80
++
++/* SysFlags */
++#define SF_Is651                0x0001
++#define SF_IsM650               0x0002
++#define SF_Is652		0x0004
++#define SF_IsM652		0x0008
++#define SF_IsM653		0x0010
++#define SF_Is660		0x8000
++
+ #define PanelRGB18Bit           0x0100
+ #define PanelRGB24Bit           0x0000
+ 
+@@ -112,7 +169,7 @@
+ #define TVOverScanShift         4
+ #define ClearBufferFlag         0x20
+ 
+-/* CR32 (Newer 630, and 310/325 series)
++/* CR32 (Newer 630, and 315 series)
+ 
+    [0]   VB connected with CVBS
+    [1]   VB connected with SVHS
+@@ -134,7 +191,7 @@
+ 	    011   LVDS + Tumpion Zurac
+ 	    100   LVDS + Chrontel 7005
+ 	    110   Chrontel 7005
+-	  310/325 series
++	  315 series
+ 	    001   SiS30x (never seen)
+ 	    010   LVDS
+ 	    011   LVDS + Chrontel 7019
+@@ -163,14 +220,15 @@
+ #define LCDSyncBit            0x00e0
+ #define LCDSyncShift               6
+ 
+-/* CR38 (310/325 series) */
++/* CR38 (315 series) */
+ #define EnableDualEdge 		0x01   
+ #define SetToLCDA		0x02   /* LCD channel A (302B/LV and 650+LVDS only) */
+ #define EnableSiSHiVision       0x04   /* HiVision (HDTV) on SiS bridge */
+ #define EnableLVDSScart         0x04   /* Scart on Ch7019 (unofficial definition - TW) */
+ #define EnableLVDSHiVision      0x08   /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
+-#define SiSHiVision1            0x10   /* See SetHiVision() */
+-#define SiSHiVision2            0x20
++#define EnableHiVision750       0x08   /* Enable 750P HiVision mode (30xLV only) */
++#define EnableHiVision525       0x10   /* Enable 525P HiVision mode (30xLV only) */
++#define SiSHiVision2            0x20   /* ? - |  --- mask 0x38 combinations have different meaning! */
+ #define EnablePALM              0x40   /* 1 = Set PALM */
+ #define EnablePALN              0x80   /* 1 = Set PALN */
+ 
+@@ -184,7 +242,7 @@
+ #define Enable302LV_DualLink    0x04   /* 30xNEW (302LV) only; set by mode switching function */
+ 
+ 
+-/* CR79 (310/325 series only)
++/* CR79 (315 series only)
+    [3-0] Notify driver
+          0001 Mode Switch event (set by BIOS)
+ 	 0010 Epansion On/Off event
+@@ -202,16 +260,6 @@
+    [7]   TV UnderScan/OverScan (set by BIOS)
+ */
+ 
+-/* SetFlag */
+-#define ProgrammingCRT2         0x01
+-#define TVSimuMode              0x02
+-#define RPLLDIV2XO              0x04
+-#define LCDVESATiming           0x08
+-#define EnableLVDSDDA           0x10
+-#define SetDispDevSwitchFlag    0x20
+-#define CheckWinDos             0x40
+-#define SetDOSMode              0x80
+-
+ /* LCDResInfo */
+ #define Panel300_800x600        0x01	/* CR36 */
+ #define Panel300_1024x768       0x02
+@@ -220,7 +268,10 @@
+ #define Panel300_640x480        0x05
+ #define Panel300_1024x600       0x06
+ #define Panel300_1152x768       0x07
+-#define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
++#define Panel300_1280x768       0x0a
++#define Panel300_320x480        0x0e 	/* fstn - TW: This is fake, can be any */
++#define Panel300_Custom		0x0f
++#define Panel300_Barco1366      0x10
+ 
+ #define Panel310_800x600        0x01
+ #define Panel310_1024x768       0x02
+@@ -231,9 +282,12 @@
+ #define Panel310_1280x960       0x07
+ #define Panel310_1152x768       0x08	/* LVDS only */
+ #define Panel310_1400x1050      0x09
+-#define Panel310_1280x768       0x0a    /* LVDS only */
++#define Panel310_1280x768       0x0a
+ #define Panel310_1600x1200      0x0b
+-#define Panel310_320x480        0x0c    /* fstn - TW: This is fake, can be any */
++#define Panel310_640x480_2      0x0c
++#define Panel310_640x480_3      0x0d
++#define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
++#define Panel310_Custom		0x0f
+ 
+ #define Panel_800x600           0x01	/* Unified values */
+ #define Panel_1024x768          0x02
+@@ -246,7 +300,43 @@
+ #define Panel_1400x1050         0x09
+ #define Panel_1280x768          0x0a    /* LVDS only */
+ #define Panel_1600x1200         0x0b
+-#define Panel_320x480           0x0c    /* fstn - TW: This is fake, can be any */
++#define Panel_640x480_2		0x0c
++#define Panel_640x480_3		0x0d
++#define Panel_320x480           0x0e    /* fstn - TW: This is fake, can be any */
++#define Panel_Custom		0x0f
++#define Panel_Barco1366         0x10
++#define Panel_848x480		0x11
++
++/* Index in ModeResInfo table */
++#define SIS_RI_320x200 0
++#define SIS_RI_320x240 1
++#define SIS_RI_320x400 2
++#define SIS_RI_400x300 3
++#define SIS_RI_512x384 4
++#define SIS_RI_640x400 5
++#define SIS_RI_640x480 6
++#define SIS_RI_800x600 7
++#define SIS_RI_1024x768 8
++#define SIS_RI_1280x1024 9
++#define SIS_RI_1600x1200 10
++#define SIS_RI_1920x1440 11
++#define SIS_RI_2048x1536 12
++#define SIS_RI_720x480 13
++#define SIS_RI_720x576 14
++#define SIS_RI_1280x960 15
++#define SIS_RI_800x480 16
++#define SIS_RI_1024x576 17
++#define SIS_RI_1280x720 18
++#define SIS_RI_856x480 19
++#define SIS_RI_1280x768 20
++#define SIS_RI_1400x1050 21
++#define SIS_RI_1152x864 22
++#define SIS_RI_848x480 23
++#define SIS_RI_1360x768 24
++#define SIS_RI_1024x600 25
++#define SIS_RI_1152x768 26
++#define SIS_RI_768x576 27
++#define SIS_RI_1360x1024 28
+ 
+ #define ExtChipType             0x0e
+ #define ExtChip301              0x02
+@@ -278,15 +368,34 @@
+ #define VCLKStartFreq           25
+ #define SoftDramType            0x80
+ 
+-#define VCLK40                  0x04   /* Index in VCLKData array */
+-#define VCLK65                  0x09   /* Index in VCLKData array */
+-#define VCLK108_2               0x14   /* Index in VCLKData array */
+-#define TVVCLKDIV2              0x21   /* Indices in (VB)VCLKData arrays */
+-#define TVVCLK                  0x22
+-#define HiTVVCLKDIV2            0x23
+-#define HiTVVCLK                0x24
+-#define HiTVSimuVCLK            0x25
+-#define HiTVTextVCLK            0x26
++/* Indices in (VB)VCLKData tables */
++
++#define VCLK28                  0x00   /* Index in VCLKData table (300 and 315) */
++#define VCLK40                  0x04   /* Index in VCLKData table (300 and 315) */
++#define VCLK65_300              0x09   /* Index in VCLKData table (300) */
++#define VCLK108_2_300           0x14   /* Index in VCLKData table (300) */
++#define VCLK81_300		0x3f   /* Index in VCLKData table (300) */
++#define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
++#define VCLK100_300             0x43   /* Index in VCLKData table (300) */
++#define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
++#define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
++#define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
++#define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
++#define VCLK162_315             0x21   /* Index in (VB)VCLKData table (315) */
++#define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
++#define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
++#define VCLK34_315              0x55   /* Index in VBVCLKData table (315) */
++
++#define TVCLKBASE_300		0x21   /* Indices on TV clocks in VCLKData table (300) */
++#define TVCLKBASE_315	        0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
++#define TVVCLKDIV2              0x00   /* Index relative to TVCLKBASE */
++#define TVVCLK                  0x01   /* Index relative to TVCLKBASE */
++#define HiTVVCLKDIV2            0x02   /* Index relative to TVCLKBASE */
++#define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
++#define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
++#define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
++
++/* ------------------------------ */
+ 
+ #define LoadDACFlag             0x1000
+ #define AfterLockCRT2           0x4000
+@@ -306,6 +415,8 @@
+ #define HotPlugFunction         0x08
+ #define StStructSize            0x06
+ 
++#define SIS_VIDEO_CAPTURE       0x00 - 0x30
++#define SIS_VIDEO_PLAYBACK      0x02 - 0x30
+ #define SIS_CRT2_PORT_04        0x04 - 0x30
+ #define SIS_CRT2_PORT_10        0x10 - 0x30
+ #define SIS_CRT2_PORT_12        0x12 - 0x30
+@@ -393,7 +504,7 @@
+ 
+ /*
+   =============================================================
+-   			for 310/325 series
++   			  for 315 series
+   =============================================================
+ */
+ #define SoftDRAMType        0x80
+--- linux-2.6.0-test6/drivers/video/sis/init.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/video/sis/init.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,19 +1,47 @@
++/* $XFree86$ */
++/*
++ * Data and prototypes for init.c
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
++
+ #ifndef _INIT_
+ #define _INIT_
+ 
+ #include "osdef.h"
++
+ #include "initdef.h"
+ #include "vgatypes.h"
+ #include "vstruct.h"
+ 
+-#ifdef TC
+-#include <stdio.h>
+-#include <string.h>
+-#include <conio.h>
+-#include <dos.h>
+-#include <stdlib.h>
+-#endif
+-
+ #ifdef LINUX_XF86
+ #include "xf86.h"
+ #include "xf86Pci.h"
+@@ -24,6 +52,9 @@
+ #endif
+ 
+ #ifdef LINUX_KERNEL
++#ifdef SIS_CP
++#undef SIS_CP
++#endif
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <linux/types.h>
+@@ -36,19 +67,6 @@
+ #endif
+ #endif
+ 
+-#ifdef WIN2000
+-#include <stdio.h>
+-#include <string.h>
+-#include <miniport.h>
+-#include "dderror.h"
+-#include "devioctl.h"
+-#include "miniport.h"
+-#include "ntddvdeo.h"
+-#include "video.h"
+-#include "sisv.h"
+-#include "tools.h"
+-#endif
+-
+ const USHORT SiS_DRAMType[17][5]={
+ 	{0x0C,0x0A,0x02,0x40,0x39},
+ 	{0x0D,0x0A,0x01,0x40,0x48},
+@@ -144,6 +162,2227 @@ const USHORT SiS_VGA_DAC[] =
+ 	0x0B,0x0C,0x0D,0x0F,0x10
+ };
+ 
++static const SiS_StResInfoStruct SiS_StResInfo[]=
++{
++	{ 640,400},
++	{ 640,350},
++	{ 720,400},
++	{ 720,350},
++	{ 640,480}
++};
++
++static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
++{
++	{  320, 200, 8, 8},   /* 0x00 */
++	{  320, 240, 8, 8},   /* 0x01 */
++	{  320, 400, 8, 8},   /* 0x02 */
++	{  400, 300, 8, 8},   /* 0x03 */
++	{  512, 384, 8, 8},   /* 0x04 */
++	{  640, 400, 8,16},   /* 0x05 */
++	{  640, 480, 8,16},   /* 0x06 */
++	{  800, 600, 8,16},   /* 0x07 */
++	{ 1024, 768, 8,16},   /* 0x08 */
++	{ 1280,1024, 8,16},   /* 0x09 */
++	{ 1600,1200, 8,16},   /* 0x0a */
++	{ 1920,1440, 8,16},   /* 0x0b */
++	{ 2048,1536, 8,16},   /* 0x0c */
++	{  720, 480, 8,16},   /* 0x0d */
++	{  720, 576, 8,16},   /* 0x0e */
++	{ 1280, 960, 8,16},   /* 0x0f */
++	{  800, 480, 8,16},   /* 0x10 */
++	{ 1024, 576, 8,16},   /* 0x11 */
++	{ 1280, 720, 8,16},   /* 0x12 */
++	{  856, 480, 8,16},   /* 0x13 */
++	{ 1280, 768, 8,16},   /* 0x14 */
++	{ 1400,1050, 8,16},   /* 0x15 */
++	{ 1152, 864, 8,16},   /* 0x16 */
++	{  848, 480, 8,16},   /* 0x17 */
++	{ 1360, 768, 8,16},   /* 0x18 */
++	{ 1024, 600, 8,16},   /* 0x19 */
++	{ 1152, 768, 8,16},   /* 0x1a */
++	{  768, 576, 8,16},   /* 0x1b */
++	{ 1360,1024, 8,16}    /* 0x1c */
++};
++
++static SiS_StandTableStruct SiS_StandTable[]=
++{
++/* 0x00: MD_0_200 */
++ {
++  0x28,0x18,0x08,0x0800,
++  {0x09,0x03,0x00,0x02},
++  0x63,
++  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x01: MD_1_200 */
++ {
++  0x28,0x18,0x08,0x0800,
++  {0x09,0x03,0x00,0x02},
++  0x63,
++  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x02: MD_2_200 */
++ {
++  0x50,0x18,0x08,0x1000,
++  {0x01,0x03,0x00,0x02},
++  0x63,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x03: MD_3_200 - mode 0x03 - 0 */
++ {
++  0x50,0x18,0x08,0x1000,
++  {0x01,0x03,0x00,0x02},
++  0x63,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x04: MD_4 */
++ {
++  0x28,0x18,0x08,0x4000,
++  {0x09,0x03,0x00,0x02},
++  0x63,
++  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
++   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
++   0xff},
++  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x01,0x00,0x03,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
++   0xff}
++ },
++/* 0x05: MD_5 */
++ {
++  0x28,0x18,0x08,0x4000,
++  {0x09,0x03,0x00,0x02},
++  0x63,
++  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
++   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
++   0xff},
++  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x01,0x00,0x03,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
++   0xff}
++ },
++/* 0x06: MD_6 */
++ {
++  0x50,0x18,0x08,0x4000,
++  {0x01,0x01,0x00,0x06},
++  0x63,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,   /* 55,81 is 54,80 for 300 */
++   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
++   0xff},
++  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
++   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
++   0x01,0x00,0x01,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
++   0xff}
++ },
++/* 0x07: MD_7 */
++ {
++  0x50,0x18,0x0e,0x1000,
++  {0x00,0x03,0x00,0x03},
++  0xa6,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
++   0xff},
++  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
++   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
++   0x0e,0x00,0x0f,0x08},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
++   0xff}
++ },
++/* 0x08: MDA_DAC */
++ {
++  0x00,0x00,0x00,0x0000,
++  {0x00,0x00,0x00,0x15},
++  0x15,
++  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
++   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
++   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
++   0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
++   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
++   0x15,0x15,0x15,0x15},
++  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++   0x3f}
++ },
++/* 0x09: CGA_DAC */
++ {
++  0x00,0x10,0x04,0x0114,
++  {0x11,0x09,0x15,0x00},
++  0x10,
++  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
++   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
++   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
++   0x04},
++  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
++   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
++   0x3e,0x2b,0x3b,0x2f},
++  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
++   0x3f}
++ },
++/* 0x0a: EGA_DAC */
++ {
++  0x00,0x10,0x04,0x0114,
++  {0x11,0x05,0x15,0x20},
++  0x30,
++  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
++   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
++   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
++   0x06},
++  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
++   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
++   0x1e,0x0b,0x1b,0x0f},
++  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
++   0x3f}
++ },
++/* 0x0b: VGA_DAC */
++ {
++  0x00,0x10,0x04,0x0114,
++  {0x11,0x09,0x15,0x2a},
++  0x3a,
++  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
++   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
++   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
++   0x1f},
++  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
++   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
++   0x1c,0x0e,0x11,0x15},
++  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
++   0x04}
++ },
++/* 0x0c */
++ {
++  0x08,0x0c,0x10,0x0a08,
++  {0x0c,0x0e,0x10,0x0b},
++  0x0c,
++  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
++   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
++   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
++   0x06},
++  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
++   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
++   0x00,0x00,0x00,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x00}
++ },
++/* 0x0d: MD_D */
++ {
++  0x28,0x18,0x08,0x2000,
++  {0x09,0x0f,0x00,0x06},
++  0x63,
++  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,     /* 2c is 2b for 300 */
++   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x01,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++   0xff}
++ },
++/* 0x0e: MD_E */
++ {
++  0x50,0x18,0x08,0x4000,
++  {0x01,0x0f,0x00,0x06},
++  0x63,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,     /* 55,81 is 54,80 for 300 */
++   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
++   0x01,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++   0xff}
++ },
++/* 0x0f: ExtVGATable - modes > 0x13 */
++ {
++  0x00,0x00,0x00,0x0000,
++  {0x01,0x0f,0x00,0x0e},
++  0x23,
++  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
++   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
++   0x01,0x00,0x00,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
++   0xff}
++ },
++/* 0x10: ROM_SAVEPTR - totally different for 300 */
++ {
++  0x9f,0x3b,0x00,0x00c0,
++  {0x00,0x00,0x00,0x00},
++  0x00,
++  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
++   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
++   0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x00,0x00,0x00,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x00}
++ },
++/* 0x11: MD_F */
++ {
++  0x50,0x18,0x0e,0x8000,
++  {0x01,0x0f,0x00,0x06},
++  0xa2,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
++   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
++   0xff},
++  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
++   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
++   0x0b,0x00,0x05,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
++   0xff}
++ },
++/* 0x12: MD_10 */
++ {
++  0x50,0x18,0x0e,0x8000,
++  {0x01,0x0f,0x00,0x06},
++  0xa3,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
++   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x01,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++   0xff}
++ },
++/* 0x13: MD_0_350 */
++ {
++  0x28,0x18,0x0e,0x0800,
++  {0x09,0x03,0x00,0x02},
++  0xa3,
++  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
++   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x14: MD_1_350 */
++ {
++  0x28,0x18,0x0e,0x0800,
++  {0x09,0x03,0x00,0x02},
++  0xa3,
++  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x15: MD_2_350 */
++ {
++  0x50,0x18,0x0e,0x1000,
++  {0x01,0x03,0x00,0x02},
++  0xa3,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x16: MD_3_350 - mode 0x03 - 1 */
++ {
++  0x50,0x18,0x0e,0x1000,
++  {0x01,0x03,0x00,0x02},
++  0xa3,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
++   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x08,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x17: MD_0_1_400 */
++ {
++  0x28,0x18,0x10,0x0800,
++  {0x08,0x03,0x00,0x02},
++  0x67,
++  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
++   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x0c,0x00,0x0f,0x08},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
++ {
++  0x50,0x18,0x10,0x1000,
++  {0x00,0x03,0x00,0x02},
++  0x67,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x0c,0x00,0x0f,0x08},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
++   0xff}
++ },
++/* 0x19: MD_7_400 */
++ {
++  0x50,0x18,0x10,0x1000,
++  {0x00,0x03,0x00,0x02},
++  0x66,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
++   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
++   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
++   0x0e,0x00,0x0f,0x08},
++  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
++   0xff}
++ },
++/* 0x1a: MD_11 */
++ {
++  0x50,0x1d,0x10,0xa000,
++  {0x01,0x0f,0x00,0x06},
++  0xe3,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
++   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,    /* e9,8b is ea,8c on 300 */
++   0xff},
++  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
++   0x01,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
++   0xff}
++ },
++/* 0x1b: ExtEGATable - Modes <= 0x02 */
++ {
++  0x50,0x1d,0x10,0xa000,
++  {0x01,0x0f,0x00,0x06},
++  0xe3,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
++   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
++   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,    /* e9,8b is ea,8c on 300 */
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
++   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
++   0x01,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
++   0xff}
++ },
++/* 0x1c: MD_13 */
++ {
++  0x28,0x18,0x08,0x2000,
++  {0x01,0x0f,0x00,0x0e},
++  0x63,
++  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
++   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
++   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
++   0xff},
++  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
++   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
++   0x41,0x00,0x0f,0x00},
++  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
++   0xff}
++ }
++};
++
++static const UCHAR SiS_NTSCTiming[] = {
++	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
++	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
++	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
++	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
++	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
++	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
++	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
++	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
++};
++
++static const UCHAR SiS_PALTiming[] = {
++	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
++	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
++	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
++	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
++	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
++	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
++	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
++	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
++};
++
++static const UCHAR SiS_HiTVExtTiming[] = {
++        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
++	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
++	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
++	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
++	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
++	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
++};
++
++static const UCHAR SiS_HiTVSt1Timing[] = {
++        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
++	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
++	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
++	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
++	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
++	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
++};
++
++static const UCHAR SiS_HiTVSt2Timing[] = {
++        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
++	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
++	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
++	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
++	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
++	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
++};
++
++static const UCHAR SiS_HiTVTextTiming[] = {
++        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
++	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
++	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
++	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
++	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
++	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
++        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
++	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
++};
++
++static const UCHAR SiS_HiTVGroup3Data[] = {
++        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
++	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
++	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
++	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
++	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
++	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_HiTVGroup3Simu[] = {
++        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
++	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
++	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
++	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
++	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
++	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_HiTVGroup3Text[] = {
++        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
++	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
++	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
++	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
++	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
++	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
++	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
++	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
++};
++
++static const UCHAR SiS_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* Was {0x21,0xed,0x8a,0x08}; */
++static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* Was {0x2a,0x05,0xd3,0x00};  */
++static const UCHAR SiS_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};
++static const UCHAR SiS_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};
++static const UCHAR SiS_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
++static const UCHAR SiS_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
++static const UCHAR SiS_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};
++static const UCHAR SiS_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};
++static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
++
++static const SiS_TVDataStruct  SiS_StPALData[]=
++{
++ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
++ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
++ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
++ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
++ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
++ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
++};
++
++static const SiS_TVDataStruct  SiS_ExtPALData[] =
++{
++ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
++ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
++ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
++ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
++ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
++ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 */
++ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
++ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
++};
++
++static const SiS_TVDataStruct  SiS_StNTSCData[]=
++{
++ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
++ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
++ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
++ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
++ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
++};
++
++static const SiS_TVDataStruct  SiS_ExtNTSCData[]=
++{
++ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
++ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
++ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
++ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
++ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
++ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
++ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
++/*{   2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},*/  /* 720x480  (old, from 650) */
++ {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08}     /* 1024x768 CORRECTED */
++/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 */
++#if 0  /* 300 series was: */
++ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
++ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
++ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
++ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
++ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
++ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
++ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
++ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
++#endif
++};
++
++
++static const SiS_TVDataStruct  SiS_St2HiTVData[]=
++{
++ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
++ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
++ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
++ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
++};
++
++static const SiS_TVDataStruct  SiS_ExtHiTVData[]=
++{
++ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
++ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},  /* 640x480   */
++ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x600   */
++ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
++ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
++ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
++ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
++ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
++};
++
++static const UCHAR SiS_OutputSelect = 0x40;
++
++static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
++
++static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
++{
++	{    9,   2, 800, 500,1800,1000},
++	{    9,   2, 800, 500,1800,1000},
++	{    4,   1, 900, 500,1800,1000},
++	{    4,   1, 900, 500,1800,1000},
++	{    9,   2, 800, 500,1800,1000},
++	{   30,  11,1056, 625,1800,1000},
++	{    5,   3,1350, 800,1800,1000},
++	{    1,   1,1576,1050,1576,1050},
++	{    1,   1,1800,1000,1800,1000}
++};
++
++static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
++{
++	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
++	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
++	{ 211,  100, 2100,  408, 1688,  802 },
++	{ 211,   64, 1536,  358, 1688,  802 },
++	{ 211,   48,  840,  488, 1688,  802 },
++	{ 211,   72, 1008,  609, 1688,  802 },
++	{ 211,  128, 1400,  776, 1688,  802 },
++	{ 211,  205, 1680, 1041, 1688,  802 },
++	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
++};
++
++static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
++{
++	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
++	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
++	{ 211,  100, 2100,  408, 1688,  802 },
++	{ 211,   64, 1536,  358, 1688,  802 },
++	{ 211,   48,  840,  488, 1688,  802 },
++	{ 211,   72, 1008,  609, 1688,  802 },
++	{ 211,  128, 1400,  776, 1688,  802 },
++	{ 211,  205, 1680, 1041, 1688,  802 },
++	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
++};
++
++static const SiS_LCDDataStruct  SiS_NoScaleData1280x768[] =
++{  /* All values guessed */
++        { 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802},
++	{ 1, 1, 1688,  802, 1688,  802}
++};
++
++static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
++{
++	{ 211,  100, 2100,  408, 1688, 1066 },
++	{ 211,   64, 1536,  358, 1688, 1066 },
++	{ 211,  100, 2100,  408, 1688, 1066 },
++	{ 211,   64, 1536,  358, 1688, 1066 },
++	{ 211,   48,  840,  488, 1688, 1066 },
++	{ 211,   72, 1008,  609, 1688, 1066 },
++	{ 211,  128, 1400,  776, 1688, 1066 },
++	{ 211,  205, 1680, 1041, 1688, 1066 },
++	{   1,    1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
++{
++	{ 211,  100, 2100,  408, 1688, 1066 },
++	{ 211,   64, 1536,  358, 1688, 1066 },
++	{ 211,  100, 2100,  408, 1688, 1066 },
++	{ 211,   64, 1536,  358, 1688, 1066 },
++	{ 211,   48,  840,  488, 1688, 1066 },
++	{ 211,   72, 1008,  609, 1688, 1066 },
++	{ 211,  128, 1400,  776, 1688, 1066 },
++	{ 211,  205, 1680, 1041, 1688, 1066 },
++	{   1,    1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct  SiS_NoScaleData1400x1050[] =
++{
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 },
++	{ 1, 1, 1688, 1066, 1688, 1066 }
++};
++
++static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
++{
++	{27,  4, 800, 500, 2160, 1250 },
++	{27,  4, 800, 500, 2160, 1250 },
++	{ 6,  1, 900, 500, 2160, 1250 },
++	{ 6,  1, 900, 500, 2160, 1250 },
++	{27,  1, 800, 500, 2160, 1250 },
++	{ 4,  1,1080, 625, 2160, 1250 },
++	{ 5,  2,1350, 800, 2160, 1250 },
++	{135,88,1600,1100, 2160, 1250 },
++	{135,88,1600,1100, 2160, 1250 },
++	{ 1,  1,2160,1250, 2160, 1250 }
++};
++
++static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
++{
++	{27, 4, 800, 500, 2160, 1250 },
++	{27, 4, 800, 500, 2160, 1250 },
++	{ 6, 1, 900, 500, 2160, 1250 },
++	{ 6, 1, 900, 500, 2160, 1250 },
++	{27, 1, 800, 500, 2160, 1250 },
++	{ 4, 1,1080, 625, 2160, 1250 },
++	{ 5, 2,1350, 800, 2160, 1250 },
++	{27,16,1500,1064, 2160, 1250 },
++	{27,16,1500,1064, 2160, 1250 },
++	{ 1, 1,2160,1250, 2160, 1250 }
++};
++
++static const SiS_LCDDataStruct  SiS_NoScaleData1600x1200[] =
++{
++        {1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++	{1,  1, 2160, 1250, 2048, 1250},
++};
++
++static const SiS_LCDDataStruct  SiS_NoScaleData[] =
++{
++	{ 1, 1, 800, 449, 800, 449 },
++	{ 1, 1, 800, 449, 800, 449 },
++	{ 1, 1, 900, 449, 900, 449 },
++	{ 1, 1, 900, 449, 900, 449 },
++	{ 1, 1, 800, 525, 800, 525 },
++	{ 1, 1,1056, 628,1056, 628 },
++	{ 1, 1,1344, 806,1344, 806 },
++	{ 1, 1,1688,1066,1688,1066 },
++        { 1, 1,1688, 802,1688, 802 },  /* 1280x768: 802 was 806 in both cases */
++        { 1, 1,2160,1250,2160,1250 },  /* 1600x1200 */
++	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
++{
++	{ 848, 433, 400, 525},
++	{ 848, 389, 400, 525},
++	{ 848, 433, 400, 525},
++	{ 848, 389, 400, 525},
++	{ 848, 518, 400, 525},
++	{1056, 628, 400, 525},
++	{ 400, 525, 400, 525},
++	{ 800, 449,1000, 644},
++	{ 800, 525,1000, 635}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
++{
++	{ 848, 433,1060, 629},
++	{ 848, 389,1060, 629},
++	{ 848, 433,1060, 629},
++	{ 848, 389,1060, 629},
++	{ 848, 518,1060, 629},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{ 800, 449,1000, 644},
++	{ 800, 525,1000, 635}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
++{
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{1056, 628,1056, 628},
++	{ 800, 449,1000, 644},
++	{ 800, 525,1000, 635}
++};
++
++
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
++{
++	{1048, 442,1688,1066},
++	{1048, 392,1688,1066},
++	{1048, 442,1688,1066},
++	{1048, 392,1688,1066},
++	{1048, 522,1688,1066},
++	{1208, 642,1688,1066},
++	{1432, 810,1688,1066},
++	{1688,1066,1688,1066}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
++{
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
++{
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 518,1344, 806},   /* 640x480 */
++	{1050, 638,1344, 806},   /* 800x600 */
++	{1344, 806,1344, 806},   /* 1024x768 */
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
++{
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++/* Custom data for Barco iQ R300 */
++static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_1[]=
++{
++	{ 832, 438,1331, 806},
++	{ 832, 388,1331, 806},
++	{ 832, 438,1331, 806},
++	{ 832, 388,1331, 806},
++	{ 832, 518,1331, 806},
++	{1050, 638,1344, 806},
++	{1344, 806,1344, 806},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066}   /* 1360x1024 */
++};
++
++/* Custom data for Barco iQ R300 */
++static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_2[]=
++{
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1688,1066,1688,1066},
++	{1688,1066,1688,1066}   /* 1360x1024 */
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_1[]=
++{
++	{ 832, 438,1331, 806},
++	{ 832, 409,1331, 806},
++	{ 832, 438,1331, 806},
++	{ 832, 409,1331, 806},
++	{ 832, 518,1331, 806},   /* 640x480 */
++	{1050, 638,1344, 806},   /* 800x600 */
++	{1344, 806,1344, 806},   /* 1024x768 */
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
++{
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
++{
++        { 928, 416, 1688,1066},
++	{ 928, 366, 1688,1066},
++	{ 928, 416, 1688,1066},
++	{ 928, 366, 1688,1066},
++	{ 928, 496, 1688,1066},
++	{1088, 616, 1688,1066},
++	{1312, 784, 1688,1066},
++	{1568,1040, 1688,1066},
++	{1688,1066, 1688,1066}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
++{
++        {1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++	{1688,1066, 1688,1066},
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
++{
++        {1088, 450, 2048,1250},
++	{1088, 400, 2048,1250},
++	{1088, 450, 2048,1250},
++	{1088, 400, 2048,1250},
++	{1088, 530, 2048,1250},
++	{1248, 650, 2048,1250},
++	{1472, 818, 2048,1250},
++	{1728,1066, 2048,1250},
++	{1848,1066, 2048,1250},
++	{2048,1250, 2048,1250}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
++{
++        {2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250},
++	{2048,1250, 2048,1250}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
++{
++	{ 768, 438, 1408, 806},
++	{ 768, 388, 1408, 806},
++	{ 768, 438, 1408, 806},
++	{ 768, 388, 1408, 806},
++	{ 768, 518, 1408, 806},
++	{ 928, 638, 1408, 806},
++	{1152, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
++{
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806},
++	{1408, 806, 1408, 806}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
++{
++	{840, 604,1344, 800},
++	{840, 560,1344, 800},
++	{840, 604,1344, 800},
++	{840, 560,1344, 800},
++	{840, 689,1344, 800},
++	{1050, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{800, 449,1280, 789},
++	{800, 525,1280, 785}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
++{
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{1344, 800,1344, 800},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
++{
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 518,1344, 806},
++	{1050, 638,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
++{
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++/* TW: Pass 1:1 data */
++static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
++{
++        { 800, 449,  800, 449},
++	{ 800, 449,  800, 449},
++	{ 900, 449,  900, 449},
++	{ 900, 449,  900, 449},
++	{ 800, 525,  800, 525},  /*  640x480   */
++	{1056, 628, 1056, 628},  /*  800x600   */
++	{1344, 806, 1344, 806},  /* 1024x768   */
++	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
++ 	{1688, 806, 1688, 806},  /* 1280x768   */
++	/* No other panels ! */
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_1[]=
++{
++	{ 800, 445, 800, 525},   /* 800, 449, 800, 449 */
++	{ 800, 395, 800, 525},
++	{ 800, 445, 800, 525},
++	{ 800, 395, 800, 525},
++	{ 800, 525, 800, 525},
++	{ 800, 525, 800, 525},   /* pseudo */
++	{ 800, 525, 800, 525}    /* pseudo */
++};
++
++/* FSTN 320x240 */
++static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_2[]=
++{
++	{ 800, 445, 800, 525},
++	{ 800, 395, 800, 525},
++	{ 800, 445, 800, 525},
++	{ 800, 395, 800, 525},
++	{ 800, 525, 800, 525},
++        { 800, 525, 800, 525},   /* pseudo */
++	{ 800, 525, 800, 525}    /* pseudo */
++};
++
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
++{
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 438,1344, 806},
++	{ 840, 409,1344, 806},
++	{ 840, 518,1344, 806},
++	{1050, 638,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
++{
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_1[]=
++{
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{1088, 525,1088, 525},  /* 640x480 TODO */
++	{1088, 525,1088, 525},  /* 800x600 TODO */
++	{1088, 525,1088, 525},  /* 1024x768 TODO */
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{1088, 525,1088, 525},  /* 848x480 */
++	{1088, 525,1088, 525}   /* 1360x768 TODO */
++};
++
++static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_2[]=
++{
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{1088, 525,1088, 525},  /*  640x480 */
++	{1088, 525,1088, 525},  /*  800x600 */
++	{1088, 525,1088, 525},  /* 1024x768 */
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{   0,   0,   0,   0},
++	{1088, 525,1088, 525},  /* 848x480 */
++	{1088, 525,1088, 525}	/* 1360x768 TODO */
++};
++
++/* LCDA */
++
++static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
++{	/* TW: Might be temporary (invalid) data */
++        { 928, 416, 1688,1066},
++	{ 928, 366, 1688,1066},
++	{1008, 416, 1688,1066},
++	{1008, 366, 1688,1066},
++	{1200, 530, 1688,1066},
++	{1088, 616, 1688,1066},
++	{1312, 784, 1688,1066},
++	{1568,1040, 1688,1066},
++	{1688,1066, 1688,1066}
++};
++
++static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
++{	/* TW: Temporary data. Not valid */
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
++{	/* TW: Temporary data. Not valid */
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{1344, 806,1344, 806},
++	{ 800, 449,1280, 801},
++	{ 800, 525,1280, 813}
++};
++
++static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_2[]=
++{	/* TW: Temporary data. Not valid */
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0},
++	{0, 0, 0, 0}
++};
++
++static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
++{
++	{ 840, 600, 840, 600},
++	{ 840, 600, 840, 600},
++	{ 840, 600, 840, 600},
++	{ 840, 600, 840, 600},
++	{ 784, 600, 784, 600},
++	{1064, 750,1064, 750},
++        {1160, 945,1160, 945}
++};
++
++static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
++{
++	{ 840, 525, 840, 525},
++	{ 840, 525, 840, 525},
++	{ 840, 525, 840, 525},
++	{ 840, 525, 840, 525},
++	{ 784, 525, 784, 525},
++	{1040, 700,1040, 700},
++        {1160, 840,1160, 840}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
++{  /* 1024x768 */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
++{  /* 1024x768 */
++	{ 1184, 622 },
++	{ 1184, 597 },
++	{ 1184, 622 },
++	{ 1184, 597 },
++	{ 1152, 622 },
++	{ 1232, 722 },
++	{    0, 0   },
++	{    0, 794 },
++	{    0, 0   }
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
++{  /* 1280x1024 */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
++{  /* 1280x1024 */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
++{  /* 1400x1050 */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
++{  /* 1400x1050 - looks heavily invalid */
++	{ 808 , 740},
++	{ 0   , 715},
++	{ 632 , 740},
++	{ 632 , 715},
++	{ 1307, 780},
++	{ 1387,1157},
++	{ 1499, 924},
++	{ 1627,1052},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
++{  /* 1600x1200 */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
++{  /* 1600x1200 - BIOS looks heavily invalid, not copied */
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
++{
++	{ 8,   0},
++	{ 8,   0},
++	{ 8,   0},
++	{ 8,   0},
++	{ 8,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0, 806},
++	{ 0, 0 }
++};
++
++static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
++{
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0},
++	{ 0 , 0}
++};
++
++static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
++{
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0}
++};
++
++static const SiS_LVDSDesStruct  SiS_CHTVONTSCDesData[]=
++{
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0}
++};
++
++static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
++{
++	{256,   0},
++	{256,   0},
++	{256,   0},
++	{256,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0}
++};
++
++static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
++{
++	{256,   0},
++	{256,   0},
++	{256,   0},
++	{256,   0},
++	{ 0,   0},
++	{ 0,   0},
++	{ 0,   0}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++   0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00 }},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++   0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00 }},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++   0x00 }},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01 }},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00 }}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1[] =
++{
++        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
++	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
++	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
++	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
++	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
++	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
++	  0x00}},
++        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
++	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
++	  0x01}},
++        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
++	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1_H[] =
++{
++        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++          0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
++	  0x00}},
++        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
++	  0x01}},
++        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2[] =
++{
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++	  0x01}},
++        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2_H[] =
++{
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
++	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
++	  0x01}},
++        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1[] =
++{
++        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
++	  0x00}},
++        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
++	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
++	  0x00}},
++        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
++	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
++	  0x01}},
++        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1_H[] =
++{
++        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
++	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
++	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
++	  0x00}},
++        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
++	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
++	  0x00}},
++        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
++	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
++	  0x01}},
++        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2[] =
++{
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
++	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
++	  0x00}},
++        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
++	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
++	  0x01}},
++        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2_H[] =
++{
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
++	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
++	  0x00}},
++        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
++	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
++	  0x01}},
++        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
++	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++	  0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1[] =
++{
++ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
++   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
++   0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
++   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
++   0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
++   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
++   0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
++   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
++   0x00}},
++ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
++   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
++   0x00}},
++ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
++   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
++   0x01}},
++ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
++   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
++   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
++   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1_H[] =
++{
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
++   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
++   0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
++   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
++   0x00}},
++ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
++   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
++   0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
++   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
++   0x00}},
++ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
++   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
++   0x00}},
++ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
++   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
++   0x01}},
++ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
++   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
++   0x01}},
++ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
++   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
++   0x01}},
++ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
++   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2[] =
++{
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
++   0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
++   0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
++   0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
++   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
++   0x00}},
++ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
++   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
++   0x01}},
++ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
++   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
++   0x01}},
++ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
++{
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
++   0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
++   0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
++   0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
++   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
++   0x00}},
++ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
++   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
++   0x01}},
++ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
++   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
++   0x01}},
++ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++   0x01}},
++ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
++   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}},
++ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
++   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
++   0x01}},
++ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
++   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
++   0x01}},
++ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
++   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1_H[] =
++{
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++   0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++   0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++   0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
++   0x00}},
++ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}},
++ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
++   0x01}},
++ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
++   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1_H[] =
++{
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
++   0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
++   0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
++   0x00}},
++ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
++   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
++   0x00}},
++ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
++{
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
++   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}
++};
++
++static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
++{
++ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
++   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
++   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
++   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
++   0x00}},
++ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
++   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
++   0x00}},
++ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
++   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
++   0x01}},
++ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
++   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
++   0x00}}
++};
++
++#define SIS_PL_HSYNCP 0x01
++#define SIS_PL_HSYNCN 0x02
++#define SIS_PL_VSYNCP 0x04
++#define SIS_PL_VSYNCN 0x08
++#define SIS_PL_DVI    0x80
++
++typedef struct _SiS_PlasmaModes
++{
++  const char *name;
++  ULONG  clock;
++  USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
++  USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
++  UCHAR  SyncFlags;
++} SiS_PlasmaModes;
++
++
++typedef struct _SiS_PlasmaTables
++{
++   USHORT vendor;
++   UCHAR  productnum;
++   USHORT product[5];
++   const char *plasmaname;
++   UCHAR  modenum;
++   UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
++} SiS_PlasmaTables;
++
++static const SiS_PlasmaModes SiS_PlasmaMode[] = {
++   {  "640x400",		/* 00: IBM 400@70 */
++      25175,
++       640,  800, 17,  64,
++       400,  449, 13,   2,
++      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++   {  "640x480",		/* 01: VESA 480@72 */
++      31500,
++       640,  832, 24,  40,
++       480,  520,  9,   3,
++      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++   {  "800x600",		/* 02: VESA 600@72 */
++      50000,
++       800, 1040, 56, 120,
++       600,  666, 37,   6,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "864x480",		/* 03: Cereb wide 1 */
++      42526,
++       864, 1134, 22,  86,
++       480,  500,  1,   3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
++   {  "848x480",		/* 04: VESA wide (NEC1) */
++      33750,
++       848, 1088, 16, 112,
++       480,  517,  6,   8,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1024x576",		/* 05: VESA wide (NEC2) */
++      47250,
++      1024, 1320, 16, 144,
++       576,  596,  2,   4,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1280x720",		/* 06: VESA wide (NEC3) */
++      76500,
++      1280, 1696, 48, 176,
++       720,  750,  4,   8,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1360x765",		/* 07: VESA wide (NEC4) */
++      85500,
++      1360, 1792, 64, 176,
++       765,  795,  4,   8,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1024x600",		/* 08: CEREB wide 2 */
++      51200,
++      1024, 1352, 51, 164,
++       600,  628,  1,   4,
++      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
++   {  "1024x768",		/* 09: VESA 768@75 */
++      78750,
++      1024, 1312,  16, 96,
++       768,  800,   1,  3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1152x864",		/* 10: VESA 1152x864@75 */
++      108000,
++      1152, 1600, 64, 128,
++       864,  900,  1,   3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1280x1024",		/* 11: VESA 1024@60 */
++      108000,
++      1280, 1688, 48, 112,
++      1024, 1066,  1,   3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1280x768",		/* 12: W_XGA */
++      81000,
++      1280, 1688, 48, 112,
++       768,  802,  3,   6,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
++   {  "1280x768",		/* 13: I/O Data W_XGA@56Hz */
++      76064,
++      1280, 1688, 48, 112,
++       768,  802,  2,   3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1376x768",		/* 14: I/O Wide XGA */
++      87340,
++      1376, 1808, 32, 128,
++       768,  806,  3,   6,
++      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
++   {  "1280x960",		/* 15: VESA 960@60 */
++      108000,
++      1280, 1800, 96, 112,
++       960, 1000,  1,   3,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "1400x1050",		/* 16: VESA 1050@60Hz */
++      108000,
++      1400, 1688, 48, 112,
++      1050, 1066,  1,   3,
++      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
++   {  "1360x768",		/* 17: VESA wide (NEC4/2) */
++      85500,
++      1360, 1792, 64, 112,
++       765,  795,  3,   6,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
++   {  "800x600",		/* 18: VESA 600@56 */
++      36000,
++       800, 1024, 24,   2,
++       600,  625,  1,   2,
++      SIS_PL_HSYNCP | SIS_PL_VSYNCP }
++};
++
++static const SiS_PlasmaTables SiS_PlasmaTable[] = {
++#if 0  /* Product IDs missing */
++   { 0x38a3, 4,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
++     14,   /* All DVI, except 0, 7, 13; 3, 15, 16 unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,12|0xc0,
++      13|0x40,14|0xc0,15|0xc0,16|0xc0, 0     , 0     , 0     , 0     , 0     , 0 }
++   },
++   { 0x38a3, 3,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42PD1/50PD1/50PD2",
++     5,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42PD3",
++     10,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 2,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42VM3/61XM1",
++     11,  /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
++      17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 2,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42MP1/42MP2",
++     6,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 50MP1",
++     10,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++#endif
++   { 0x38a3, 4,
++     { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
++     11,   /* All DVI except 0, 7, 13, 17 */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
++      17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++#if 0  /* Product IDs missing */
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 3300W",
++     3,
++     { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 4200W",
++     4,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0     , 0     , 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 4210W",
++     6,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x38a3, 1,
++     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "NEC PlasmaSync 5000W",
++     7,   /* DVI entirely unknown */
++     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++#endif
++   { 0x412f, 2,
++     { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
++     "Pioneer 503CMX/PDA-5002",
++     6,   /* DVI unknown */
++     { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x34a9, 1,
++     { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
++     "Panasonic TH-42",
++     5,   /* No DVI output */
++     { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
++       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
++   },
++   { 0x0000 }
++};
++
+ void     SiS_SetReg1(USHORT, USHORT, USHORT);
+ void     SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
+ void     SiS_SetReg3(USHORT, USHORT);
+@@ -158,6 +2397,7 @@ void     SiS_SetMemoryClock(SiS_Private 
+ void     SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
+ void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
++void     SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ 
+ #ifdef SIS300
+ void     SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+@@ -192,12 +2432,15 @@ void     SiS_VerifyMclk(SiS_Private *SiS
+ 
+ void     SiS_HandleCRT1(SiS_Private *SiS_Pr);
+ void     SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
+-void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
++void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
++void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+ void     SiS_Delay15us(SiS_Private *SiS_Pr);
+ BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+ BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                              USHORT ModeNo,USHORT ModeIdIndex);
+ UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
++void     SiS_WhatTheHellIsThis(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
++void     SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ void     SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+ void     SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+ void     SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+@@ -267,26 +2510,26 @@ void    	SiS_SetPitchCRT1(SiS_Private *S
+ void    	SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+ extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ 	     	 		    int *out_sbit, int *out_scale);
++extern void 	SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
++
+ extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
+ extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+-extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
++extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN hcm);
+ #endif
+ 
+ extern USHORT    SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+ extern void      SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+-extern BOOLEAN   SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+-                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
+-extern void      SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
+-                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern BOOLEAN   SiS_SetCRT2Group(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
++                                  PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+ extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+ extern BOOLEAN   SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
+ extern BOOLEAN   SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+ extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                                USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
+-extern BOOLEAN   SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
++extern void      SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+                                    USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern void      SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern USHORT    SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+@@ -321,10 +2564,12 @@ int    sisfb_mode_rate_to_dclock(SiS_Pri
+ 			      unsigned char modeno, unsigned char rateindex);
+ int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+ 			 unsigned char modeno, unsigned char rateindex,
+-			 ULONG *left_margin, ULONG *right_margin, 
++			 ULONG *left_margin, ULONG *right_margin,
+ 			 ULONG *upper_margin, ULONG *lower_margin,
+ 			 ULONG *hsync_len, ULONG *vsync_len,
+ 			 ULONG *sync, ULONG *vmode);
++BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+ #endif
+ 
+ #endif
+--- linux-2.6.0-test6/drivers/video/sis/oem300.h	2003-06-14 12:18:05.000000000 -0700
++++ 25/drivers/video/sis/oem300.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,5 +1,37 @@
+-
+-/* OEM Data for 300 series */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
++/*
++ * OEM Data for 300 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+ 
+ const UCHAR SiS300_OEMTVDelay301[8][4] =
+ {
+@@ -680,325 +712,147 @@ const UCHAR SiS300_Filter2[10][9][7] =
+     }
+ };
+ 
+-const UCHAR SiS300_LCDHData[24][11][5] = {
++/* Custom data for Barco iQ Pro R300 */
++const UCHAR barco_p1[2][9][7][3] = {
+     {
+-        {0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-        {0x4e,0x18,0x90,0x38,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9a,0x56,0x00},
+-        {0x67,0x11,0x9a,0x56,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-        {0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x8e,0x18,0x28,0x78,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x4e,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9a,0x56,0x00},
+-	{0x67,0x11,0x9a,0x56,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x67,0x91,0x84,0x5e,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x65,0xef,0x83,0x5c,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00},
+-	{0x8a,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-        {0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-    	{0x65,0xEF,0x83,0x5C,0x00},
+-    	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x67,0x91,0x84,0x5E,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x65,0xEF,0x83,0x5C,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
+-    },
+-    {
+-    	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x8E,0x18,0x28,0x78,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x4E,0x18,0x90,0x38,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x67,0x11,0x9A,0x56,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00},
+-	{0x8A,0x14,0x00,0x80,0x00}
++	{  { 0x16, 0xcf, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x19, 0x00 }
++	},
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x1e, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x16, 0x00 }
++	},
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x19, 0x00 },
++	   {    0,    0,    0 }
++	},
++	{
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x1e, 0x00 },
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0xd1, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x11, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x26, 0x00 }
++	},
++	{
++	   { 0x16, 0xd1, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x30, 0x00 },
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0x00, 0x00 },
++	   { 0x17, 0xa0, 0x00 },
++	   { 0x1a, 0xa0, 0x00 },
++	   { 0x1b, 0x2a, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0x00, 0x00 },
++	   { 0x17, 0xaa, 0x00 },
++	   { 0x1a, 0xa0, 0x00 },
++	   { 0x1b, 0x2a, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   {    0,    0,    0 }
++	}
++    },
++    {
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x19, 0x00 }
++	},
++	{
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x19, 0x00 },
++	},
++	{
++	   {    0,    0,    0 }
++	},
++	{
++	   { 0x16, 0xcf, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe7, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x1e, 0x00 }
++	},
++	{
++	   { 0x16, 0xd1, 0x00 },
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe6, 0x00 },
++	   { 0x1b, 0x11, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x26, 0x00 }
++	},
++	{
++	   { 0x18, 0x00, 0x00 },
++	   { 0x1a, 0xe0, 0x00 },
++	   { 0x1b, 0x26, 0x00 },
++	   { 0x1c, 0xff, 0x00 },
++	   { 0x1d, 0x1c, 0x00 },
++	   { 0x1e, 0x30, 0x00 },
++	   {    0,    0,    0 }
++	},
++	{
++	   {    0,    0,    0 }
++	},
++	{
++	   {    0,    0,    0 }
++	}
+     }
+ };
+ 
+-#if 0
+-const UCHAR SiS300_LCDVData[24][11][6] = {
+-    {
+-        {
+-    },
+-};
+-#endif
++
++
++
++
++
+--- linux-2.6.0-test6/drivers/video/sis/oem310.h	2003-06-14 12:17:55.000000000 -0700
++++ 25/drivers/video/sis/oem310.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,5 +1,37 @@
+-
+-/* OEM Data for 310/325/330 series */
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
++/*
++ * OEM Data for 315/330 series
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Based on code by Silicon Intergrated Systems
++ *
++ */
+ 
+ const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
+ {
+@@ -100,7 +132,7 @@ const UCHAR SiS310_LCDDelayCompensation_
+ 
+ const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
+ {
+-                 0x33,0x33,0x33,    /*   800x600 (guessed) */
++                 0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
+ 		 0x33,0x33,0x33,    /*  1024x768 */
+ 		 0x33,0x33,0x33,    /* 1280x1024 */
+ 		 0x33,0x33,0x33,    /*   640x480 (unknown) */
+@@ -361,5 +393,55 @@ const UCHAR SiS310_TVPhaseIncr2[3][2][4]
+  }
+ };
+ 
++/* OEM data for Compaq Presario 3045US */
++static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
++{
++	{  211,  60,1024, 501,1688,1066},
++	{  211,  60,1024, 508,1688,1066},
++	{  211,  60,1024, 501,1688,1066},
++	{  211,  60,1024, 508,1688,1066},
++	{   32,  15,1696, 501,1696,1066},
++	{  212,  75,1024, 621,1696,1066},
++	{    4,   3,1696, 810,1696,1066},
++	{    1,   1,1696,1066,1696,1066}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] =
++{
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
++ {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}},
++ {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] =
++{
++ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
++ {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}},
++ {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}},
++ {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}},
++ {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}}
++};
++
++static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] =
++{
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
++ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
++};
++
+ 
+ 
+--- linux-2.6.0-test6/drivers/video/sis/osdef.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/video/sis/osdef.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,79 +1,43 @@
+-/* #define WINCE_HEADER */
+-/* #define WIN2000 */
+-/* #define TC */
++
++/* OS depending defines */
++
++/* The choices are: */
++
+ #define LINUX_KERNEL	   /* Kernel framebuffer */
+ /* #define LINUX_XF86 */   /* XFree86 */
+ 
+ /**********************************************************************/
+-#ifdef LINUX_KERNEL
+-	#include <linux/config.h>
+-	#include <linux/version.h>
+-	#ifdef CONFIG_FB_SIS_300
+- 		#define SIS300
+-	#endif
+-
+-	#ifdef CONFIG_FB_SIS_315
+-		#define SIS315H
+-	#endif
+-	#if 1
+-		#define SISFBACCEL	/* Include 2D acceleration */
+-	#endif
+-	#if 1
+-		#define SISFB_PAN	/* Include Y-Panning code */
+-	#endif
+-#else
+-/*	#define SIS300*/
+-	#define SIS315H
+-#endif
+-#ifdef LINUX_XF86
+-	#define SIS300
+-	/* #define SIS315H */ /* TW: done above */
+-#endif
++#ifdef LINUX_KERNEL  /* -------------------------- */
++#include <linux/config.h>
++#include <linux/version.h>
+ 
+-/**********************************************************************/
+-#ifdef TC
+-#endif
+-#ifdef WIN2000
+-#endif
+-#ifdef WINCE_HEADER
+-#endif
+-#ifdef LINUX_XF86
++#ifdef CONFIG_FB_SIS_300
++#define SIS300
+ #endif
+-#ifdef LINUX_KERNEL
+-#endif
+-/**********************************************************************/
+-#ifdef TC
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+-#endif
+-#ifdef WIN2000
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
++
++#ifdef CONFIG_FB_SIS_315
++#define SIS315H
+ #endif
+-#ifdef WINCE_HEADER
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
++
++#if 1
++#define SISFBACCEL	/* Include 2D acceleration */
+ #endif
+-#ifdef LINUX_XF86
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
++
+ #endif
+-#ifdef LINUX_KERNEL
+-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
++
++#ifdef LINUX_XF86 /* ----------------------------- */
++#define SIS300
++#define SIS315H
+ #endif
+-/**********************************************************************/
+ 
+ /**********************************************************************/
+-
+-#ifdef TC
+-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+-#endif
+-#ifdef WIN2000
+-#define SiS_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
+-#endif
+-#ifdef WINCE_HEADER
+-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
+-#endif
+ #ifdef LINUX_XF86
++#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+ #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+ #endif
++
+ #ifdef LINUX_KERNEL
++#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+ #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
+ #endif
+ 
+@@ -104,19 +68,6 @@
+ #endif /* InPortLong */
+ 
+ /**********************************************************************/
+-/*  TC                                                                */
+-/**********************************************************************/
+-
+-#ifdef TC
+-#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
+-#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
+-#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
+-#define InPortByte(p)    inp((unsigned short)(p))
+-#define InPortWord(p)    inp((unsigned short)(p))
+-#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
+-#endif
+-
+-/**********************************************************************/
+ /*  LINUX XF86                                                        */
+ /**********************************************************************/
+ 
+@@ -142,29 +93,4 @@
+ #define InPortLong(p)    inl((u16)(p))
+ #endif
+ 
+-/**********************************************************************/
+-/*  WIN 2000                                                          */
+-/**********************************************************************/
+-
+-#ifdef WIN2000
+-#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
+-#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
+-#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
+-#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
+-#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
+-#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
+-#endif
+ 
+-
+-/**********************************************************************/
+-/*  WIN CE                                                            */
+-/**********************************************************************/
+-
+-#ifdef WINCE_HEADER
+-#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
+-#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
+-#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
+-#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
+-#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
+-#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
+-#endif
+--- linux-2.6.0-test6/drivers/video/sis/sis_accel.c	2003-06-14 12:18:52.000000000 -0700
++++ 25/drivers/video/sis/sis_accel.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
++ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
+  * for Linux kernels 2.4.x and 2.5.x
+  *
+  * 2D acceleration part
+@@ -211,7 +211,7 @@ SiS300SubsequentSolidFillRect(int x, int
+ 	SiS300DoCMD
+ }
+ 
+-/* 310/325 series ------------------------------------------------ */
++/* 315 series ---------------------------------------------------- */
+ 
+ static void
+ SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+@@ -230,7 +230,7 @@ SiS310SetupForScreenToScreenCopy(int xdi
+ 		/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
+ 	}
+ 	SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+-	/* TW: The 310/325 series is smart enough to know the direction */
++	/* The 315 series is smart enough to know the direction */
+ }
+ 
+ static void
+@@ -328,11 +328,13 @@ void sisfb_syncaccel(void)
+     }
+ }
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
+ 
+ int fbcon_sis_sync(struct fb_info *info)
+ {
+-   if(!sisfb_accel) return 0;
++   if(!ivideo.accel)
++   	return 0;
++
+    CRITFLAGS
+    if(sisvga_engine == SIS_300_VGA) {
+       SiS300Sync();
+@@ -352,7 +354,7 @@ void fbcon_sis_fillrect(struct fb_info *
+    if(!rect->width || !rect->height)
+    	return;
+ 
+-   if(!sisfb_accel) {
++   if(!ivideo.accel) {
+ 	cfb_fillrect(info, rect);
+ 	return;
+    }
+@@ -388,7 +390,7 @@ void fbcon_sis_copyarea(struct fb_info *
+    CRITFLAGS
+ 
+    TWDEBUG("Inside sis_copyarea");
+-   if(!sisfb_accel) {
++   if(!ivideo.accel) {
+    	cfb_copyarea(info, area);
+ 	return;
+    }
+@@ -418,7 +420,7 @@ void fbcon_sis_copyarea(struct fb_info *
+ 
+ #endif
+ 
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)  /* ------ KERNEL <2.5.34 ------ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
+ 
+ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
+ 			    int dsty, int dstx, int height, int width)
+@@ -591,38 +593,38 @@ void fbcon_sis_revc(struct display *p, i
+ 
+ #ifdef FBCON_HAS_CFB8
+ struct display_switch fbcon_sis8 = {
+-	setup:			fbcon_cfb8_setup,
+-	bmove:			fbcon_sis_bmove,
+-	clear:			fbcon_sis_clear8,
+-	putc:			fbcon_cfb8_putc,
+-	putcs:			fbcon_cfb8_putcs,
+-	revc:			fbcon_cfb8_revc,
+-	clear_margins:		fbcon_cfb8_clear_margins,
+-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++	.setup			= fbcon_cfb8_setup,
++	.bmove			= fbcon_sis_bmove,
++	.clear			= fbcon_sis_clear8,
++	.putc			= fbcon_cfb8_putc,
++	.putcs			= fbcon_cfb8_putcs,
++	.revc			= fbcon_cfb8_revc,
++	.clear_margins		= fbcon_cfb8_clear_margins,
++	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+ #ifdef FBCON_HAS_CFB16
+ struct display_switch fbcon_sis16 = {
+-	setup:			fbcon_cfb16_setup,
+-	bmove:			fbcon_sis_bmove,
+-	clear:			fbcon_sis_clear16,
+-	putc:			fbcon_cfb16_putc,
+-	putcs:			fbcon_cfb16_putcs,
+-	revc:			fbcon_sis_revc,
+-	clear_margins:		fbcon_cfb16_clear_margins,
+-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++	.setup			= fbcon_cfb16_setup,
++	.bmove			= fbcon_sis_bmove,
++	.clear			= fbcon_sis_clear16,
++	.putc			= fbcon_cfb16_putc,
++	.putcs			= fbcon_cfb16_putcs,
++	.revc			= fbcon_sis_revc,
++	.clear_margins		= fbcon_cfb16_clear_margins,
++	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+ #ifdef FBCON_HAS_CFB32
+ struct display_switch fbcon_sis32 = {
+-	setup:			fbcon_cfb32_setup,
+-	bmove:			fbcon_sis_bmove,
+-	clear:			fbcon_sis_clear32,
+-	putc:			fbcon_cfb32_putc,
+-	putcs:			fbcon_cfb32_putcs,
+-	revc:			fbcon_sis_revc,
+-	clear_margins:		fbcon_cfb32_clear_margins,
+-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++	.setup			= fbcon_cfb32_setup,
++	.bmove			= fbcon_sis_bmove,
++	.clear			= fbcon_sis_clear32,
++	.putc			= fbcon_cfb32_putc,
++	.putcs			= fbcon_cfb32_putcs,
++	.revc			= fbcon_sis_revc,
++	.clear_margins		= fbcon_cfb32_clear_margins,
++	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ };
+ #endif
+ 
+--- linux-2.6.0-test6/drivers/video/sis/sis_accel.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/video/sis/sis_accel.h	2003-10-05 00:34:22.000000000 -0700
+@@ -47,7 +47,7 @@
+ #define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
+ #define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
+ 
+-/* Additional engine commands for 310/325 */
++/* Additional engine commands for 315 */
+ #define ALPHA_BLEND		0x00000007  /* Alpha blend ? */
+ #define A3D_FUNCTION		0x00000008  /* 3D command ? */
+ #define	CLEAR_Z_BUFFER		0x00000009  /* ? */
+@@ -90,11 +90,11 @@
+ #define NO_RESET_COUNTER        0x00400000
+ #define NO_LAST_PIXEL           0x00200000
+ 
+-/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
++/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
+ #define COLOR_TO_MONO		0x00100000
+ #define AA_TEXT			0x00200000
+ 
+-/* Some general registers for 310/325 series */
++/* Some general registers for 315 series */
+ #define SRC_ADDR		0x8200
+ #define SRC_PITCH		0x8204
+ #define AGP_BASE		0x8206 /* color-depth dependent value */
+@@ -326,7 +326,7 @@ int     CmdQueLen;
+ 
+ 
+ 
+-/* ----------- SiS 310/325 series --------------- */
++/* -------------- SiS 315 series --------------- */
+ 
+ /* Q_STATUS:
+    bit 31 = 1: All engines idle and all queues empty
+@@ -342,16 +342,27 @@ int     CmdQueLen;
+    bits 7:0:   2D counter 1
+ 
+    Where is the command queue length (current amount of commands the queue
+-   can accept) on the 310/325 series? (The current implementation is taken
+-   from 300 series and certainly wrong...)
++   can accept) on the 315 series?
+ */
+ 
+ /* TW: FIXME: CmdQueLen is... where....? */
++/* We assume a length of 4 bytes per command; since 512K of
++ * of RAM are allocated, the number of commands is easily
++ * calculated (assuming that there is no 3D support yet)
++ * We calculate it very cautiously (128K only) and let the
++ * rest to the (never?)-to-come (?) 3D engine. (The 3D engine
++ * can use a similar technique, using the remaining 384K,
++ * hence a queue overflow is avoided)
++ * UPDATE: This technique causes a terrible system latency
++ * on integrated chipsets. Disable the queue handling for
++ * now.
++ */
+ #define SiS310Idle \
+   { \
+   while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+   while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+-  CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, Q_STATUS); \
++  CmdQueLen = 0; \
++  /*CmdQueLen = ((128 * 1024) / 4) - 64; */ \
+   }
+ 
+ #define SiS310SetupSRCBase(base) \
+--- linux-2.6.0-test6/drivers/video/sis/sis_main.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/video/sis/sis_main.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,25 +1,20 @@
+ /*
+- * SiS 300/630/730/540/315/550/650/740 frame buffer device
++ * SiS 300/630/730/540/315/550/650/740/330/660/760 frame buffer driver
+  * for Linux kernels 2.4.x and 2.5.x
+  *
+- * Partly based on the VBE 2.0 compliant graphic boards framebuffer driver,
++ * (C) 1999 Silicon Integrated Systems, Inc.
++ * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
++ *
++ * Author:   	Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Author of code base:
++ *		SiS (www.sis.com.tw)
++ *
++ * See http://www.winischhofer.net/ for more information and updates
++ *
++ * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
+  * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+  *
+- * Authors:   	SiS (www.sis.com.tw)
+- *		(Various others)
+- *		Thomas Winischhofer <thomas@winischhofer.net>:
+- *			- SiS Xabre (330) support
+- *			- many fixes and enhancements for all chipset series,
+- *			- extended bridge handling, TV output for Chrontel 7005
+- *                      - 650/LVDS support (for LCD panels up to 1600x1200)
+- *                      - 650/740/Chrontel 7019 support
+- *                      - 30xB/30xLV LCD, TV and VGA2 support
+- *			- memory queue handling enhancements,
+- *                      - 2D acceleration and y-panning,
+- *                      - portation to 2.5 API
+- *			- etc.
+- *			(see http://www.winischhofer.net/
+- *			for more information and updates)
+  */
+ 
+ #include <linux/config.h>
+@@ -43,6 +38,8 @@
+ #include <linux/fs.h>
+ #include <linux/agp_backend.h>
+ #include <linux/types.h>
++#include <linux/vmalloc.h>
++#include <asm/uaccess.h>
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ #include <linux/spinlock.h>
+@@ -79,6 +76,12 @@
+ #endif
+ #endif
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
++#error "This version of sisfb requires at least 2.5.69"
++#endif
++#endif
++
+ /* -------------------- Macro definitions ---------------------------- */
+ 
+ #undef SISFBDEBUG 	/* TW: no debugging */
+@@ -134,9 +137,19 @@ sisfb_query_VGA_config_space(PSIS_HW_DEV
+ 
+ 	if (!init) {
+ 		init = TRUE;
+-		pdev = pci_find_device(PCI_VENDOR_ID_SI, ivideo.chip_id, pdev);
+-		if (pdev)
+-			valid_pdev = TRUE;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++		pci_for_each_dev(pdev) {
++#else
++		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++			DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
++			         pdev->device, ivideo.chip_id);
++			if ((pdev->vendor == PCI_VENDOR_ID_SI)
++			           && (pdev->device == ivideo.chip_id)) {
++				valid_pdev = TRUE;
++				break;
++			}
++		}
+ 	}
+ 
+ 	if (!valid_pdev) {
+@@ -163,6 +176,7 @@ BOOLEAN sisfb_query_north_bridge_space(P
+ 	if (!init) {
+ 		init = TRUE;
+ 		switch (ivideo.chip) {
++#ifdef CONFIG_FB_SIS_300
+ 		case SIS_540:
+ 			nbridge_id = PCI_DEVICE_ID_SI_540;
+ 			break;
+@@ -172,23 +186,42 @@ BOOLEAN sisfb_query_north_bridge_space(P
+ 		case SIS_730:
+ 			nbridge_id = PCI_DEVICE_ID_SI_730;
+ 			break;
++#endif
++#ifdef CONFIG_FB_SIS_315
+ 		case SIS_550:
+ 			nbridge_id = PCI_DEVICE_ID_SI_550;
+ 			break;
+ 		case SIS_650:
+ 			nbridge_id = PCI_DEVICE_ID_SI_650;
+ 			break;
+-		case SIS_740:			
++		case SIS_740:
+ 			nbridge_id = PCI_DEVICE_ID_SI_740;
+ 			break;
++		case SIS_660:
++			nbridge_id = PCI_DEVICE_ID_SI_660;
++			break;
++		case SIS_760:
++			nbridge_id = PCI_DEVICE_ID_SI_760;
++			break;
++#endif
+ 		default:
+ 			nbridge_id = 0;
+ 			break;
+ 		}
+ 
+-		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+-		if (pdev)
+-			valid_pdev = TRUE;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++		pci_for_each_dev(pdev) {
++#else
++		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++			DPRINTK("Current: 0x%x, target: 0x%x\n",
++					pdev->device, ivideo.chip_id);
++			if ((pdev->vendor == PCI_VENDOR_ID_SI)
++					&& (pdev->device == nbridge_id)) {
++				valid_pdev = TRUE;
++				break;
++			}
++		}
+ 	}
+ 
+ 	if (!valid_pdev) {
+@@ -207,66 +240,291 @@ BOOLEAN sisfb_query_north_bridge_space(P
+ 
+ /* ------------------ Internal helper routines ----------------- */
+ 
+-static void sisfb_search_mode(const char *name)
++static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
+ {
+-	int i = 0, j = 0;
++	int htotal, vtotal;
++	unsigned int dclock, hsync;
+ 
+-	if(name == NULL) {
+-	   printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+-	   sisfb_mode_idx = DEFAULT_MODE;
+-	   return;
++	if(!monitor->datavalid) return TRUE;
++
++	if(mode_idx < 0) return FALSE;
++
++	if(rate < (monitor->vmin - 1)) return FALSE;
++	if(rate > (monitor->vmax + 1)) return FALSE;
++
++	if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
++	                          &htotal, &vtotal, rate_idx)) {
++		dclock = (htotal * vtotal * rate) / 1000;
++		if(dclock > (monitor->dclockmax + 1000)) return FALSE;
++		hsync = dclock / htotal;
++		if(hsync < (monitor->hmin - 1)) return FALSE;
++		if(hsync > (monitor->hmax + 1)) return FALSE;
++        } else {
++	  	return FALSE;
+ 	}
+-		
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		
+-        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
+-	   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+-	   sisfb_mode_idx = DEFAULT_MODE;
+-	   return;
++	return TRUE;
++};
++
++static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer)
++{
++	int i, j, xres, yres, refresh, index;
++	u32 emodes;
++
++	if(buffer[0] != 0x00 || buffer[1] != 0xff ||
++	   buffer[2] != 0xff || buffer[3] != 0xff ||
++	   buffer[4] != 0xff || buffer[5] != 0xff ||
++	   buffer[6] != 0xff || buffer[7] != 0x00) {
++	   printk(KERN_DEBUG "sisfb: Bad EDID header\n");
++	   return FALSE;
+ 	}
+-#endif		
+ 
+-	while(sisbios_mode[i].mode_no != 0) {
+-		if (!strcmp(name, sisbios_mode[i].name)) {
+-			sisfb_mode_idx = i;
+-			j = 1;
+-			break;
+-		}
+-		i++;
++	if(buffer[0x12] != 0x01) {
++	   printk(KERN_INFO "sisfb: EDID version %d not supported\n",
++	   	buffer[0x12]);
++	   return FALSE;
++	}
++
++	monitor->feature = buffer[0x18];
++
++	if(!buffer[0x14] & 0x80) {
++	   if(!(buffer[0x14] & 0x08)) {
++	      printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
++	   }
++	}
++
++	if(buffer[0x13] >= 0x01) {
++	   /* EDID V1 rev 1 and 2: Search for monitor descriptor
++	    * to extract ranges
++	    */
++	    j = 0x36;
++	    for(i=0; i<4; i++) {
++	       if(buffer[j]     == 0x00 && buffer[j + 1] == 0x00 &&
++	          buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
++		  buffer[j + 4] == 0x00) {
++		  monitor->hmin = buffer[j + 7];
++		  monitor->hmax = buffer[j + 8];
++		  monitor->vmin = buffer[j + 5];
++		  monitor->vmax = buffer[j + 6];
++		  monitor->dclockmax = buffer[j + 9] * 10 * 1000;
++		  monitor->datavalid = TRUE;
++		  break;
++	       }
++	       j += 18;
++	    }
++	}
++
++	if(!monitor->datavalid) {
++	   /* Otherwise: Get a range from the list of supported
++	    * Estabished Timings. This is not entirely accurate,
++	    * because fixed frequency monitors are not supported
++	    * that way.
++	    */
++	   monitor->hmin = 65535; monitor->hmax = 0;
++	   monitor->vmin = 65535; monitor->vmax = 0;
++	   monitor->dclockmax = 0;
++	   emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
++	   for(i = 0; i < 13; i++) {
++	      if(emodes & sisfb_ddcsmodes[i].mask) {
++	         if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
++		 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
++		 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
++		 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
++		 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
++	      }
++	   }
++	   index = 0x26;
++	   for(i = 0; i < 8; i++) {
++	      xres = (buffer[index] + 31) * 8;
++	      switch(buffer[index + 1] & 0xc0) {
++	         case 0xc0: yres = (xres * 9) / 16; break;
++	         case 0x80: yres = (xres * 4) /  5; break;
++	         case 0x40: yres = (xres * 3) /  4; break;
++	         default:   yres = xres;	    break;
++	      }
++	      refresh = (buffer[index + 1] & 0x3f) + 60;
++	      if((xres >= 640) && (yres >= 480)) {
++                 for(j = 0; j < 8; j++) {
++	            if((xres == sisfb_ddcfmodes[j].x) &&
++	               (yres == sisfb_ddcfmodes[j].y) &&
++		       (refresh == sisfb_ddcfmodes[j].v)) {
++		      if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
++		      if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
++		      if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
++		      if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
++		      if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
++	            }
++	         }
++	      }
++	      index += 2;
++           }
++	   if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
++	      monitor->datavalid = TRUE;
++	   }
++	}
++
++ 	return(monitor->datavalid);
++}
++
++static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
++{
++	USHORT        temp, i, realcrtno = crtno;
++   	unsigned char buffer[256];
++
++	monitor->datavalid = FALSE;
++
++	if(crtno) {
++       	   if(ivideo.vbflags & CRT2_LCD)      realcrtno = 1;
++      	   else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
++      	   else return;
++   	}
++
++	if((sisfb_crt1off) && (!crtno)) return;
++
++    	temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
++   	if((!temp) || (temp == 0xffff)) {
++      	   printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
++	   return;
++   	} else {
++      	   printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
++      	   printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
++	   	crtno + 1,
++	   	(temp & 0x1a) ? "" : "[none of the supported]",
++	   	(temp & 0x02) ? "2 " : "",
++	   	(temp & 0x08) ? "D&P" : "",
++           	(temp & 0x10) ? "FPDI-2" : "");
++      	   if(temp & 0x02) {
++	      i = 3;  /* Number of retrys */
++	      do {
++	    	 temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
++				     realcrtno, 1, &buffer[0]);
++	      } while((temp) && i--);
++              if(!temp) {
++	    	 if(sisfb_interpret_edid(monitor, &buffer[0])) {
++		    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
++		    	monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
++			monitor->dclockmax / 1000);
++		 } else {
++	       	    printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
++	    	 }
++	      } else {
++            	 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
++	      }
++	   } else {
++	      printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
++	   }
+ 	}
+-	if(!j) printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
+ }
+ 
+-static void sisfb_search_vesamode(unsigned int vesamode)
++static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
+ {
+ 	int i = 0, j = 0;
+ 
+ 	if(vesamode == 0) {
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 		sisfb_mode_idx = MODE_INDEX_NONE;
+ #else
+-		printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
++		if(!quiet)
++		   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+ 		sisfb_mode_idx = DEFAULT_MODE;
+-#endif		
++#endif
+ 		return;
+ 	}
+ 
+ 	vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
+ 
++	while(sisbios_mode[i++].mode_no != 0) {
++		if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
++		    (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
++		    if(sisfb_fstn) {
++		       if(sisbios_mode[i-1].mode_no == 0x50 ||
++		          sisbios_mode[i-1].mode_no == 0x56 ||
++		          sisbios_mode[i-1].mode_no == 0x53) continue;
++	            } else {
++		       if(sisbios_mode[i-1].mode_no == 0x5a ||
++		          sisbios_mode[i-1].mode_no == 0x5b) continue;
++		    }
++		    sisfb_mode_idx = i - 1;
++		    j = 1;
++		    break;
++		}
++	}
++	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
++}
++
++static void sisfb_search_mode(char *name, BOOLEAN quiet)
++{
++	int i = 0;
++	unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
++	char strbuf[16], strbuf1[20];
++	char *nameptr = name;
++
++	if(name == NULL) {
++	   if(!quiet)
++	      printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
++	   sisfb_mode_idx = DEFAULT_MODE;
++	   return;
++	}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++        if (!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
++	   if(!quiet)
++	      printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
++	   sisfb_mode_idx = DEFAULT_MODE;
++	   return;
++	}
++#endif
++	if(strlen(name) <= 19) {
++	   strcpy(strbuf1, name);
++	   for(i=0; i<strlen(strbuf1); i++) {
++	      if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
++	   }
++
++	   /* This does some fuzzy mode naming detection */
++	   if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
++	      if((rate <= 32) || (depth > 32)) {
++	         j = rate; rate = depth; depth = j;
++	      }
++	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
++	      nameptr = strbuf;
++	      ivideo.refresh_rate = sisfb_parm_rate = rate;
++	   } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
++	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
++	      nameptr = strbuf;
++	   } else {
++	      xres = 0;
++	      if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
++	         sprintf(strbuf, "%ux%ux8", xres, yres);
++	         nameptr = strbuf;
++	      } else {
++	         sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
++	         return;
++	      }
++	   }
++	}
++
++	i = 0; j = 0;
+ 	while(sisbios_mode[i].mode_no != 0) {
+-		if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
+-		    (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
+-			sisfb_mode_idx = i;
+-			j = 1;
+-			break;
++		if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
++		   if(sisfb_fstn) {
++		      if(sisbios_mode[i-1].mode_no == 0x50 ||
++		         sisbios_mode[i-1].mode_no == 0x56 ||
++		         sisbios_mode[i-1].mode_no == 0x53) continue;
++	           } else {
++		      if(sisbios_mode[i-1].mode_no == 0x5a ||
++		         sisbios_mode[i-1].mode_no == 0x5b) continue;
++		   }
++		   sisfb_mode_idx = i - 1;
++		   j = 1;
++		   break;
+ 		}
+-		i++;
+ 	}
+-	if(!j) printk(KERN_INFO "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
++	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
++
+ }
+ 
+-static int sisfb_validate_mode(int myindex)
++static int sisfb_validate_mode(int myindex, unsigned long vbflags)
+ {
+-   u16 xres, yres;
++   u16 xres, yres, myres;
+ 
+ #ifdef CONFIG_FB_SIS_300
+    if(sisvga_engine == SIS_300_VGA) {
+@@ -283,8 +541,10 @@ static int sisfb_validate_mode(int myind
+    }
+ #endif
+ 
+-   switch (ivideo.disp_state & DISPTYPE_DISP2) {
+-     case DISPTYPE_LCD:
++   myres = sisbios_mode[myindex].yres;
++
++   switch (vbflags & VB_DISPTYPE_DISP2) {
++     case CRT2_LCD:
+ 	switch (sishw_ext.ulCRT2LCDType) {
+ 	case LCD_640x480:
+ 		xres =  640; yres =  480;  break;
+@@ -306,140 +566,209 @@ static int sisfb_validate_mode(int myind
+ 		xres = 1400; yres = 1050;  break;		
+ 	case LCD_1600x1200:
+ 		xres = 1600; yres = 1200;  break;
+-	case LCD_320x480:				/* TW: FSTN */
++	case LCD_320x480:				/* FSTN (old) */
+ 		xres =  320; yres =  480;  break;
++	case LCD_640x480_2:				/* FSTN (new) */
++	case LCD_640x480_3:
++		xres =  640; yres =  480;  break;
+ 	default:
+ 	        xres =    0; yres =    0;  break;
+ 	}
+-	if(sisbios_mode[myindex].xres > xres) {
+-	        return(-1);
++
++	if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
++	   	xres = 1360; yres = 1024;
+ 	}
+-        if(sisbios_mode[myindex].yres > yres) {
++
++	if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
++	   	xres = 848;  yres =  480;
++	} else {
++	   if(sisbios_mode[myindex].xres > xres) {
++	        return(-1);
++	   }
++           if(myres > yres) {
+ 	        return(-1);
++	   }
+ 	}
+-	if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
+-           (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
+-	   (sishw_ext.Is301BDH)) {		   /* 301B-DH */
++
++	if(vbflags & (VB_LVDS | VB_30xBDH)) {
+ 	   switch (sisbios_mode[myindex].xres) {
++	   	case 320:
++			if((myres != 200) && (myres != 240))
++		          	return(-1);
++			if((myres == 240) || (myres == 480)) {
++			   	if(!sisfb_fstn) {
++				   if(sisbios_mode[myindex].mode_no == 0x5a ||
++				      sisbios_mode[myindex].mode_no == 0x5b)
++					return(-1);
++			        } else {
++				   if(sisbios_mode[myindex].mode_no == 0x50 ||
++				      sisbios_mode[myindex].mode_no == 0x56 ||
++				      sisbios_mode[myindex].mode_no == 0x53)
++					return(-1);
++				}
++			}
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++			break;
++		case 400:
++	       		if(myres != 300) return(-1);
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++	       		break;
+ 	   	case 512:
+-	       		if(sisbios_mode[myindex].yres != 512) return -1;
+-			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
++	       		if(myres != 384) return(-1);
++			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return(-1);
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ 	       		break;
+ 	   	case 640:
+-		       	if((sisbios_mode[myindex].yres != 400) &&
+-	           	   (sisbios_mode[myindex].yres != 480))
++		       	if((myres != 400) && (myres != 480))
+ 		          	return -1;
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
++			   if(myres == 400)
++			 	return(-1);
++			}
+ 	       		break;
+ 	   	case 800:
+-		       	if(sisbios_mode[myindex].yres != 600) return -1;
++		       	if(myres != 600) return(-1);
++	       		break;
++		case 848:
++		        if(SiS_Pr.SiS_CustomT != CUT_PANEL848) return(-1);
++		       	if(myres != 480) return(-1);
+ 	       		break;
+ 	   	case 1024:
+-		       	if((sisbios_mode[myindex].yres != 600) &&
+-	           	   (sisbios_mode[myindex].yres != 768))
+-		          	return -1;
+-			if((sisbios_mode[myindex].yres == 600) &&
++		       	if((myres != 600) && (myres != 768))
++		          	return(-1);
++			if((myres == 600) &&
+ 			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
+-			   	return -1;
++			   	return(-1);
+ 			break;
+ 		case 1152:
+-			if((sisbios_mode[myindex].yres) != 768) return -1;
+-			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
++			if(myres != 768) return(-1);
++			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
+ 			break;
+ 	   	case 1280:
+-		   	if((sisbios_mode[myindex].yres != 768) &&
+-	           	   (sisbios_mode[myindex].yres != 1024))
+-		          	return -1;
+-			if((sisbios_mode[myindex].yres == 768) &&
++		   	if((myres != 768) && (myres != 1024))
++		          	return(-1);
++			if((myres == 768) &&
+ 			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
+-			   	return -1;				
++			   	return(-1);
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
++			break;
++		case 1360:
++			if(SiS_Pr.SiS_CustomT != CUT_BARCO1366) return(-1);
++			if(myres != 1024) return(-1);
+ 			break;
+ 	   	case 1400:
+-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
++		   	if(myres != 1050) return(-1);
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ 			break;
+ 	   	case 1600:
+-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
++		   	if(myres != 1200) return(-1);
++			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+ 			break;
+ 	   	default:
+-		        return -1;		
++		        return(-1);
+ 	   }
+ 	} else {
+ 	   switch (sisbios_mode[myindex].xres) {
++	   	case 320:
++			if((myres != 200) && (myres != 240))
++		          	return -1;
++			break;
++		case 400:
++	       		if(myres != 300) return(-1);
++	       		break;
+ 	   	case 512:
+-	       		if(sisbios_mode[myindex].yres != 512) return -1;
++	       		if(myres != 384) return(-1);
+ 	       		break;
+ 	   	case 640:
+-		       	if((sisbios_mode[myindex].yres != 400) &&
+-	           	   (sisbios_mode[myindex].yres != 480))
+-		          	return -1;
++		       	if((myres != 400) && (myres != 480))
++		          	return(-1);
+ 	       		break;
+ 	   	case 800:
+-		       	if(sisbios_mode[myindex].yres != 600) return -1;
++		       	if(myres != 600) return(-1);
+ 	       		break;
+ 	   	case 1024:
+-		       	if(sisbios_mode[myindex].yres != 768) return -1;
++		       	if(myres != 768) return(-1);
+ 			break;
+ 	   	case 1280:
+-		   	if((sisbios_mode[myindex].yres != 960) &&
+-	           	   (sisbios_mode[myindex].yres != 1024))
+-		          	return -1;
+-			if(sisbios_mode[myindex].yres == 960) {
+-			    if(sishw_ext.ulCRT2LCDType == LCD_1400x1050) 
+-			   	return -1;
++		   	if((myres != 960) && (myres != 768) && (myres != 1024))
++		          	return(-1);
++			if((myres == 768) || (myres == 960)) {
++			    	if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
++			   		return(-1);
++			}
++			if(myres == 768) {
++			    	if(sishw_ext.ulCRT2LCDType == LCD_1280x960)
++			   		return(-1);
+ 			}
+ 			break;
+ 	   	case 1400:
+-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
++		   	if(myres != 1050) return(-1);
+ 			break;
+ 	   	case 1600:
+-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
++		   	if(myres != 1200) return(-1);
+ 			break;
+ 	   	default:
+-		        return -1;		
++		        return(-1);
+ 	   }
+ 	}
+ 	break;
+-     case DISPTYPE_TV:
++
++     case CRT2_TV:
+ 	switch (sisbios_mode[myindex].xres) {
++	case 320:
++		if(vbflags & VB_CHRONTEL) return(-1);
++		if((myres != 200) && (myres != 240))
++		       	return(-1);
++		break;
++	case 400:
++		if(vbflags & VB_CHRONTEL) return(-1);
++		if(myres != 300) return(-1);
++		break;
+ 	case 512:
++		if(vbflags & VB_CHRONTEL) return(-1);
++		if((vbflags & VB_SISBRIDGE) && (vbflags & TV_NTSC))
++		   	return(-1);
++		if(myres != 384) return(-1);
++		break;
+ 	case 640:
+-	case 800:
++		if((myres != 400) && (myres != 480))
++		       	return(-1);
++		if((vbflags & VB_CHRONTEL) && (myres == 400))
++		   	return(-1);
+ 		break;
+ 	case 720:
+-		if (ivideo.TV_type == TVMODE_NTSC) {
+-			if (sisbios_mode[myindex].yres != 480) {
+-				return(-1);
+-			}
+-		} else if (ivideo.TV_type == TVMODE_PAL) {
+-			if (sisbios_mode[myindex].yres != 576) {
+-				return(-1);
+-			}
+-		}
+-		/* TW: LVDS/CHRONTEL does not support 720 */
+-		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+-					ivideo.hasVB == HASVB_CHRONTEL) {
+-				return(-1);
+-		}
++		if(vbflags & VB_CHRONTEL) return(-1);
++		if((vbflags & TV_NTSC) && (myres != 480))
++			return(-1);
++		if((vbflags & TV_PAL) && (myres != 576))
++			return(-1);
++		break;
++	case 768:
++		if(vbflags & VB_CHRONTEL) return(-1);
++		if(!(vbflags & TV_PAL)) return(-1);
++		if(myres != 576) return(-1);
++		break;
++	case 800:
++		if(myres != 600) return(-1);
+ 		break;
+ 	case 1024:
+-		if (ivideo.TV_type == TVMODE_NTSC) {
+-			if(sisbios_mode[myindex].bpp == 32) {
+-			       return(-1);
+-			}
+-		}
+-		/* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
+-		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+-					ivideo.hasVB == HASVB_CHRONTEL) {
+-		    if(ivideo.chip < SIS_315H) {
++		if(vbflags & VB_301) return(-1);
++		if(vbflags & VB_CHRONTEL) {
++		    	if(ivideo.chip < SIS_315H) {
+ 				return(-1);
+-		    }
++		    	}
+ 		}
+ 		break;
+ 	default:
+ 		return(-1);
+ 	}
+ 	break;
+-     case DISPTYPE_CRT2:	
+-        if(sisbios_mode[myindex].xres > 1280) return -1;
++
++     case CRT2_VGA:
++        if(sisbios_mode[myindex].xres > 1600) return(-1);
++	if(!(vbflags & (VB_301B|VB_302B))) {
++	   if(sisbios_mode[myindex].xres > 1400) return(-1);
++	}
+ 	break;	
+      }
+      return(myindex);
+@@ -453,15 +782,20 @@ static void sisfb_search_crt2type(const 
+ 		return;
+ 
+ 	while(sis_crt2type[i].type_no != -1) {
+-		if (!strcmp(name, sis_crt2type[i].name)) {
++		if (!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+ 			sisfb_crt2type = sis_crt2type[i].type_no;
+ 			sisfb_tvplug = sis_crt2type[i].tvplug_no;
++			sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
++			sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
+ 			break;
+ 		}
+ 		i++;
+ 	}
+ 	if(sisfb_crt2type < 0)
+-		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
++		printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
++        if(ivideo.chip != SIS_550) {
++	   sisfb_dstn = sisfb_fstn = 0;
++	}
+ }
+ 
+ static void sisfb_search_queuemode(const char *name)
+@@ -472,23 +806,23 @@ static void sisfb_search_queuemode(const
+ 		return;
+ 
+ 	while (sis_queuemode[i].type_no != -1) {
+-		if (!strcmp(name, sis_queuemode[i].name)) {
++		if (!strnicmp(name, sis_queuemode[i].name, strlen(sis_queuemode[i].name))) {
+ 			sisfb_queuemode = sis_queuemode[i].type_no;
+ 			break;
+ 		}
+ 		i++;
+ 	}
+ 	if (sisfb_queuemode < 0)
+-		printk(KERN_INFO "sisfb: Invalid queuemode type: %s\n", name);
++		printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
+ }
+ 
+-static u8 sisfb_search_refresh_rate(unsigned int rate)
++static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
+ {
+ 	u16 xres, yres;
+ 	int i = 0;
+ 
+-	xres = sisbios_mode[sisfb_mode_idx].xres;
+-	yres = sisbios_mode[sisfb_mode_idx].yres;
++	xres = sisbios_mode[mode_idx].xres;
++	yres = sisbios_mode[mode_idx].yres;
+ 
+ 	sisfb_rate_idx = 0;
+ 	while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
+@@ -536,23 +870,60 @@ static void sisfb_search_tvstd(const cha
+ 		return;
+ 
+ 	while (sis_tvtype[i].type_no != -1) {
+-		if (!strcmp(name, sis_tvtype[i].name)) {
+-			sisfb_tvmode = sis_tvtype[i].type_no;
++		if (!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
++			ivideo.vbflags |= sis_tvtype[i].type_no;
+ 			break;
+ 		}
+ 		i++;
+ 	}
+ }
+ 
++static void sisfb_search_specialtiming(const char *name)
++{
++	int i = 0;
++	BOOLEAN found = FALSE;
++
++	if(name == NULL)
++		return;
++
++	if(!strnicmp(name, "none", 4)) {
++	        SiS_Pr.SiS_CustomT = CUT_FORCENONE;
++		printk(KERN_DEBUG "sisfb: Special timing disabled\n");
++	} else {
++	   while(mycustomttable[i].chipID != 0) {
++	      if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
++		 SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
++		 found = TRUE;
++		 printk(KERN_INFO "sisfb: Special timing for %s %s forced\n",
++		 mycustomttable[i].vendorName, mycustomttable[i].cardName);
++		 break;
++	      }
++	      i++;
++	   }
++	   if(!found) {
++	      printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
++	      printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
++	      i = 0;
++	      while(mycustomttable[i].chipID != 0) {
++		 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
++		     mycustomttable[i].optionName,
++		     mycustomttable[i].vendorName,
++		     mycustomttable[i].cardName);
++		 i++;
++	      }
++           }
++ 	}
++}
++
+ static BOOLEAN sisfb_bridgeisslave(void)
+ {
+-   unsigned char usScratchP1_00;
++   unsigned char P1_00;
+ 
+-   if(ivideo.hasVB == HASVB_NONE) return FALSE;
++   if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
+ 
+-   inSISIDXREG(SISPART1,0x00,usScratchP1_00);
+-   if( ((sisvga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
+-       ((sisvga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
++   inSISIDXREG(SISPART1,0x00,P1_00);
++   if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
++       ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+ 	   return TRUE;
+    } else {
+            return FALSE;
+@@ -597,7 +968,7 @@ static BOOLEAN sisfbcheckvretracecrt2(vo
+ 
+ static BOOLEAN sisfb_CheckVBRetrace(void) 
+ {
+-   if(ivideo.disp_state & DISPTYPE_DISP2) {
++   if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+       if(sisfb_bridgeisslave()) {
+          return(sisfbcheckvretracecrt1());
+       } else {
+@@ -607,60 +978,195 @@ static BOOLEAN sisfb_CheckVBRetrace(void
+    return(sisfbcheckvretracecrt1());
+ }
+ 
++static int sisfb_myblank(int blank)
++{
++   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
++   BOOLEAN backlight = TRUE;
++
++   switch(blank) {
++   case 0:	/* on */
++      sr01  = 0x00;
++      sr11  = 0x00;
++      sr1f  = 0x00;
++      cr63  = 0x00;
++      p2_0  = 0x20;
++      p1_13 = 0x00;
++      backlight = TRUE;
++      break;
++   case 1:	/* blank */
++      sr01  = 0x20;
++      sr11  = 0x00;
++      sr1f  = 0x00;
++      cr63  = 0x00;
++      p2_0  = 0x20;
++      p1_13 = 0x00;
++      backlight = TRUE;
++      break;
++   case 2:	/* no vsync */
++      sr01  = 0x20;
++      sr11  = 0x08;
++      sr1f  = 0x80;
++      cr63  = 0x40;
++      p2_0  = 0x40;
++      p1_13 = 0x80;
++      backlight = FALSE;
++      break;
++   case 3:	/* no hsync */
++      sr01  = 0x20;
++      sr11  = 0x08;
++      sr1f  = 0x40;
++      cr63  = 0x40;
++      p2_0  = 0x80;
++      p1_13 = 0x40;
++      backlight = FALSE;
++      break;
++   case 4:	/* off */
++      sr01  = 0x20;
++      sr11  = 0x08;
++      sr1f  = 0xc0;
++      cr63  = 0x40;
++      p2_0  = 0xc0;
++      p1_13 = 0xc0;
++      backlight = FALSE;
++      break;
++   default:
++      return 1;
++   }
++
++   if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
++
++      setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
++
++      if( (!sisfb_thismonitor.datavalid) ||
++          ((sisfb_thismonitor.datavalid) &&
++           (sisfb_thismonitor.feature & 0xe0))) {
++
++	 if(sisvga_engine == SIS_315_VGA) {
++	    setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
++	 }
++
++	 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
++      }
++
++   }
++
++   if(ivideo.currentvbflags & CRT2_LCD) {
++
++      if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++	 if(backlight) {
++	    SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
++	 } else {
++	    SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
++	 }
++      } else if(sisvga_engine == SIS_315_VGA) {
++	 if(ivideo.vbflags & VB_CHRONTEL) {
++	    if(backlight) {
++	       SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
++	    } else {
++	       SiS_Chrontel701xBLOff(&SiS_Pr);
++	    }
++	 }
++      }
++
++      if(((sisvga_engine == SIS_300_VGA) &&
++          (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
++         ((sisvga_engine == SIS_315_VGA) &&
++          ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
++          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
++      }
++
++      if(sisvga_engine == SIS_300_VGA) {
++         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
++            (!(ivideo.vbflags & VB_30xBDH))) {
++	    setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
++	 }
++      } else if(sisvga_engine == SIS_315_VGA) {
++         if((ivideo.vbflags & (VB_301B|VB_302B)) &&
++            (!(ivideo.vbflags & VB_30xBDH))) {
++	    setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
++	 }
++      }
++
++   } else if(ivideo.currentvbflags & CRT2_VGA) {
++
++      if(ivideo.vbflags & (VB_301B|VB_302B)) {
++         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
++      }
++
++   }
++
++   return(0);
++}
++
+ /* ----------- FBDev related routines for all series ----------- */
+ 
++static void sisfb_set_vparms(void)
++{
++   switch(ivideo.video_bpp) {
++   case 8:
++       	ivideo.DstColor = 0x0000;
++	ivideo.SiS310_AccelDepth = 0x00000000;
++	ivideo.video_cmap_len = 256;
++       	break;
++   case 16:
++       	ivideo.DstColor = 0x8000;
++       	ivideo.SiS310_AccelDepth = 0x00010000;
++	ivideo.video_cmap_len = 16;
++       	break;
++   case 32:
++       	ivideo.DstColor = 0xC000;
++	ivideo.SiS310_AccelDepth = 0x00020000;
++	ivideo.video_cmap_len = 16;
++       	break;
++   default:
++ 	ivideo.video_cmap_len = 16;
++	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
++	ivideo.accel = 0;
++	break;
++   }
++}
++
+ static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+ 		      struct fb_info *info)
+ {
+-	unsigned int htotal =
+-		var->left_margin + var->xres + var->right_margin +
+-		var->hsync_len;
+-	unsigned int vtotal = 0; 
++	unsigned int htotal = 0, vtotal = 0;
+ 	double drate = 0, hrate = 0;
+ 	int found_mode = 0;
+ 	int old_mode;
+-	unsigned char reg;
++	u32 pixclock;
+ 
+-	TWDEBUG("Inside do_set_var");
+-	
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+-	inSISIDXREG(SISCR,0x34,reg);
+-	if(reg & 0x80) {
+-	   printk(KERN_INFO "sisfb: Cannot change display mode, X server is active\n");
+-	   return -EBUSY;
+-	}
+-#endif	
++	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
++
++	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
++
++	pixclock = var->pixclock;
+ 
+ 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+-		vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;
++		vtotal += var->yres;
+ 		vtotal <<= 1;
+ 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+-		vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;
++		vtotal += var->yres;
+ 		vtotal <<= 2;
+ 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+-		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+-		         var->vsync_len; 
+-	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;
++		vtotal += var->yres;
++		vtotal <<= 1;
++	} else 	vtotal += var->yres;
+ 
+ 	if(!(htotal) || !(vtotal)) {
+ 		DPRINTK("sisfb: Invalid 'var' information\n");
+ 		return -EINVAL;
+ 	}
+ 
+-	if(var->pixclock && htotal && vtotal) {
+-	   drate = 1E12 / var->pixclock;
++	if(pixclock && htotal && vtotal) {
++	   drate = 1E12 / pixclock;
+ 	   hrate = drate / htotal;
+ 	   ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+ 	} else ivideo.refresh_rate = 60;
+ 
+-	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+-	if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;
+-
++#if 0
+ 	printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
+ 		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
++#endif
+ 
+ 	old_mode = sisfb_mode_idx;
+ 	sisfb_mode_idx = 0;
+@@ -678,7 +1184,7 @@ static int sisfb_do_set_var(struct fb_va
+ 	}
+ 
+ 	if(found_mode)
+-		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
++		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+ 	else
+ 		sisfb_mode_idx = -1;
+ 
+@@ -689,12 +1195,21 @@ static int sisfb_do_set_var(struct fb_va
+ 		return -EINVAL;
+ 	}
+ 
+-	if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
++	if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
+ 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+ 		ivideo.refresh_rate = 60;
+ 	}
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++	if(sisfb_thismonitor.datavalid) {
++	   if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
++	                         sisfb_rate_idx, ivideo.refresh_rate)) {
++	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++	   }
++	}
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
+ #else
+ 	if(isactive) {
+@@ -708,14 +1223,6 @@ static int sisfb_do_set_var(struct fb_va
+ 
+ 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ 
+-		sisfb_post_setmode();
+-
+-		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",
+-			sisbios_mode[sisfb_mode_idx].xres,
+-			sisbios_mode[sisfb_mode_idx].yres,
+-			sisbios_mode[sisfb_mode_idx].bpp,
+-			ivideo.refresh_rate);
+-
+ 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
+ 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+ 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
+@@ -725,53 +1232,38 @@ static int sisfb_do_set_var(struct fb_va
+ 		if(sisfb_accel) {
+ 		   ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
+ 		}
+-		switch(ivideo.video_bpp) {
+-        	case 8:
+-            		ivideo.DstColor = 0x0000;
+-	    		ivideo.SiS310_AccelDepth = 0x00000000;
+-			ivideo.video_cmap_len = 256;
+-            		break;
+-        	case 16:
+-            		ivideo.DstColor = 0x8000;
+-            		ivideo.SiS310_AccelDepth = 0x00010000;
+-			ivideo.video_cmap_len = 16;
+-            		break;
+-        	case 32:
+-            		ivideo.DstColor = 0xC000;
+-	    		ivideo.SiS310_AccelDepth = 0x00020000;
+-			ivideo.video_cmap_len = 16;
+-            		break;
+-		default:
+-			ivideo.video_cmap_len = 16;
+-		        printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+-			ivideo.accel = 0;
+-			break;
+-    		}
++
++		sisfb_set_vparms();
++
++		ivideo.current_width = ivideo.video_width;
++		ivideo.current_height = ivideo.video_height;
++		ivideo.current_bpp = ivideo.video_bpp;
++		ivideo.current_htotal = htotal;
++		ivideo.current_vtotal = vtotal;
++		ivideo.current_pixclock = var->pixclock;
++		ivideo.current_refresh_rate = ivideo.refresh_rate;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++                sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
++#endif
++
++		sisfb_post_setmode();
+ 
+ 	}
+-	TWDEBUG("End of do_set_var");
+ 	return 0;
+ }
+ 
+-#ifdef SISFB_PAN
+ static int sisfb_pan_var(struct fb_var_screeninfo *var)
+ {
+ 	unsigned int base;
+ 
+-	TWDEBUG("Inside pan_var");
+-	
+ 	if (var->xoffset > (var->xres_virtual - var->xres)) {
+-	        printk(KERN_INFO "Pan: xo: %d xv %d xr %d\n",
+-			var->xoffset, var->xres_virtual, var->xres);
+ 		return -EINVAL;
+ 	}
+ 	if(var->yoffset > (var->yres_virtual - var->yres)) {
+-		printk(KERN_INFO "Pan: yo: %d yv %d yr %d\n",
+-			var->yoffset, var->yres_virtual, var->yres);
+ 		return -EINVAL;
+ 	}
+ 
+-        base = var->yoffset * var->xres_virtual + var->xoffset;
++	base = var->yoffset * var->xres_virtual + var->xoffset;
+ 
+         /* calculate base bpp dep. */
+         switch(var->bits_per_pixel) {
+@@ -794,7 +1286,7 @@ static int sisfb_pan_var(struct fb_var_s
+ 	if(sisvga_engine == SIS_315_VGA) {
+ 		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+ 	}
+-        if(ivideo.disp_state & DISPTYPE_DISP2) {
++        if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+         	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
+         	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
+@@ -803,10 +1295,8 @@ static int sisfb_pan_var(struct fb_var_s
+ 			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+ 		}
+         }
+-	TWDEBUG("End of pan_var");
+ 	return 0;
+ }
+-#endif
+ 
+ static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
+ {
+@@ -843,22 +1333,24 @@ static void sisfb_bpp_to_var(struct fb_v
+ 
+ void sis_dispinfo(struct ap_data *rec)
+ {
+-	rec->minfo.bpp    = ivideo.video_bpp;
+-	rec->minfo.xres   = ivideo.video_width;
+-	rec->minfo.yres   = ivideo.video_height;
+-	rec->minfo.v_xres = ivideo.video_vwidth;
+-	rec->minfo.v_yres = ivideo.video_vheight;
+-	rec->minfo.org_x  = ivideo.org_x;
+-	rec->minfo.org_y  = ivideo.org_y;
+-	rec->minfo.vrate  = ivideo.refresh_rate;
+-	rec->iobase       = ivideo.vga_base - 0x30;
+-	rec->mem_size     = ivideo.video_size;
+-	rec->disp_state   = ivideo.disp_state; 
+-	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
+-	rec->hasVB        = ivideo.hasVB; 
+-	rec->TV_type      = ivideo.TV_type; 
+-	rec->TV_plug      = ivideo.TV_plug; 
+-	rec->chip         = ivideo.chip;
++	rec->minfo.bpp      = ivideo.video_bpp;
++	rec->minfo.xres     = ivideo.video_width;
++	rec->minfo.yres     = ivideo.video_height;
++	rec->minfo.v_xres   = ivideo.video_vwidth;
++	rec->minfo.v_yres   = ivideo.video_vheight;
++	rec->minfo.org_x    = ivideo.org_x;
++	rec->minfo.org_y    = ivideo.org_y;
++	rec->minfo.vrate    = ivideo.refresh_rate;
++	rec->iobase         = ivideo.vga_base - 0x30;
++	rec->mem_size       = ivideo.video_size;
++	rec->disp_state     = ivideo.disp_state;
++	rec->version        = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
++	rec->hasVB          = ivideo.hasVB;
++	rec->TV_type        = ivideo.TV_type;
++	rec->TV_plug        = ivideo.TV_plug;
++	rec->chip           = ivideo.chip;
++	rec->vbflags	    = ivideo.vbflags;
++	rec->currentvbflags = ivideo.currentvbflags;
+ }
+ 
+ /* ------------ FBDev related routines for 2.4 series ----------- */
+@@ -873,7 +1365,6 @@ static void sisfb_crtc_to_var(struct fb_
+ 	int A, B, C, D, E, F, temp;
+ 	double hrate, drate;
+ 
+-	TWDEBUG("Inside crtc_to_var");
+ 	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
+ 
+ 	if (sr_data & SIS_INTERLACED_MODE)
+@@ -921,6 +1412,8 @@ static void sisfb_crtc_to_var(struct fb_
+ 
+ 	inSISIDXREG(SISCR, 0x09, cr_data3);
+ 
++	if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
++
+ 	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
+ 	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+ 
+@@ -939,26 +1432,22 @@ static void sisfb_crtc_to_var(struct fb_
+ 	D = B - F - C;
+ 
+         var->yres = E;
+-#ifndef SISFB_PAN
+-	var->yres_virtual = E;
+-#endif
+-	/* TW: We have to report the physical dimension to the console! */
++	var->upper_margin = D;
++	var->lower_margin = F;
++	var->vsync_len = C;
++
+ 	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ 		var->yres <<= 1;
+-#ifndef SISFB_PAN
+-		var->yres_virtual <<= 1;
+-#endif
++		var->upper_margin <<= 1;
++		var->lower_margin <<= 1;
++		var->vsync_len <<= 1;
+ 	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ 		var->yres >>= 1;
+-#ifndef SISFB_PAN
+-		var->yres_virtual >>= 1;
+-#endif
++		var->upper_margin >>= 1;
++		var->lower_margin >>= 1;
++		var->vsync_len >>= 1;
+ 	}
+ 
+-	var->upper_margin = D;
+-	var->lower_margin = F;
+-	var->vsync_len = C;
+-
+ 	inSISIDXREG(SISSR, 0x0b, sr_data);
+ 
+ 	inSISIDXREG(SISCR, 0x00, cr_data);
+@@ -999,10 +1488,20 @@ static void sisfb_crtc_to_var(struct fb_
+ 	D = B - F - C;
+ 
+ 	var->xres = var->xres_virtual = E * 8;
+-	var->left_margin = D * 8;
+-	var->right_margin = F * 8;
+-	var->hsync_len = C * 8;
+ 
++	if((var->xres == 320) &&
++	   (var->yres == 200 || var->yres == 240)) {
++		/* Terrible hack, but the correct CRTC data for
++	  	 * these modes only produces a black screen...
++	  	 */
++       		var->left_margin = (400 - 376);
++       		var->right_margin = (328 - 320);
++       		var->hsync_len = (376 - 328);
++	} else {
++	   	var->left_margin = D * 8;
++	   	var->right_margin = F * 8;
++	   	var->hsync_len = C * 8;
++	}
+ 	var->activate = FB_ACTIVATE_NOW;
+ 
+ 	var->sync = 0;
+@@ -1022,21 +1521,21 @@ static void sisfb_crtc_to_var(struct fb_
+ 	VT <<= 1;
+ 	HT = (HT + 5) * 8;
+ 
++	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
++		VT <<= 1;
++	}
+ 	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
+ 	drate = hrate * HT;
+ 	var->pixclock = (u32) (1E12 / drate);
+ 
+-#ifdef SISFB_PAN
+ 	if(sisfb_ypan) {
+ 	    var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+ 	    if(var->yres_virtual <= var->yres) {
+ 	        var->yres_virtual = var->yres;
+ 	    }
+ 	} else
+-#endif
+-	   var->yres_virtual = var->yres;
++	    var->yres_virtual = var->yres;
+ 
+-        TWDEBUG("end of crtc_to_var");
+ }
+ 
+ static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+@@ -1069,7 +1568,7 @@ static int sisfb_setcolreg(unsigned regn
+ 		outSISREG(SISDACD, (red >> 10));
+ 		outSISREG(SISDACD, (green >> 10));
+ 		outSISREG(SISDACD, (blue >> 10));
+-		if (ivideo.disp_state & DISPTYPE_DISP2) {
++		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ 		        outSISREG(SISDAC2A, regno);
+ 			outSISREG(SISDAC2D, (red >> 8));
+ 			outSISREG(SISDAC2D, (green >> 8));
+@@ -1118,7 +1617,7 @@ static void sisfb_set_disp(int con, stru
+ 	display->ywrapstep = fix.ywrapstep;
+ 	display->line_length = fix.line_length;
+ 	display->next_line = fix.line_length;
+-	display->can_soft_blank = 0;
++	display->can_soft_blank = 1;
+ 	display->inverse = sisfb_inverse;
+ 	display->var = *var;
+ 
+@@ -1162,17 +1661,12 @@ static void sisfb_set_disp(int con, stru
+ 	display->dispsw = &sisfb_sw;
+ 	restore_flags(flags);
+ 
+-#ifdef SISFB_PAN
+-        if((ivideo.accel) && (sisfb_ypan)) {
+-  	    /* display->scrollmode = SCROLL_YPAN; - not defined */
++        if(sisfb_ypan) {
++  	    /* display->scrollmode = 0;  */
+ 	} else {
+ 	    display->scrollmode = SCROLL_YREDRAW;
+ 	    sisfb_sw.bmove = fbcon_redraw_bmove;
+ 	}
+-#else
+-	display->scrollmode = SCROLL_YREDRAW;
+-	sisfb_sw.bmove = fbcon_redraw_bmove;
+-#endif
+ }
+ 
+ static void sisfb_do_install_cmap(int con, struct fb_info *info)
+@@ -1191,17 +1685,16 @@ static void sisfb_do_install_cmap(int co
+ static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+ 			 struct fb_info *info)
+ {
+-	TWDEBUG("inside get_var");
+ 	if(con == -1)
+ 		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
+ 	else
+ 		*var = fb_display[con].var;
+ 
+- 	/* For FSTN, DSTN */
+-	if (var->xres == 320 && var->yres == 480)
++	if(sisfb_fstn) {
++	   if (var->xres == 320 && var->yres == 480)
+ 		var->yres = 240;
+-		
+-	TWDEBUG("end of get_var");
++        }
++
+ 	return 0;
+ }
+ 
+@@ -1211,8 +1704,6 @@ static int sisfb_set_var(struct fb_var_s
+ 	int err;
+ 	unsigned int cols, rows;
+ 
+-	TWDEBUG("inside set_var");
+-
+ 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
+         if(sisfb_do_set_var(var, con == currcon, info)) {
+ 		sisfb_crtc_to_var(var);
+@@ -1233,16 +1724,17 @@ static int sisfb_set_var(struct fb_var_s
+ 
+ 	cols = sisbios_mode[sisfb_mode_idx].cols;
+ 	rows = sisbios_mode[sisfb_mode_idx].rows;
+-	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
++#if 0
++	/* Why was this called here? */
++ 	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
++#endif
+ 
+-	TWDEBUG("end of set_var");
+ 	return 0;
+ }
+ 
+ static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ 			  struct fb_info *info)
+ {
+-	TWDEBUG("inside get_cmap");
+         if (con == currcon)
+ 		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+ 
+@@ -1251,7 +1743,6 @@ static int sisfb_get_cmap(struct fb_cmap
+ 	else
+ 		fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
+ 
+-	TWDEBUG("end of get_cmap");
+ 	return 0;
+ }
+ 
+@@ -1260,7 +1751,6 @@ static int sisfb_set_cmap(struct fb_cmap
+ {
+ 	int err;
+ 
+-	TWDEBUG("inside set_cmap");
+ 	if (!fb_display[con].cmap.len) {
+ 		err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
+ 		if (err)
+@@ -1272,17 +1762,15 @@ static int sisfb_set_cmap(struct fb_cmap
+ 
+ 	else
+ 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+-	TWDEBUG("end of set_cmap");
++
+ 	return 0;
+ }
+ 
+-#ifdef SISFB_PAN
+ static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
+ 			     struct fb_info* info)
+ {
+ 	int err;
+-	
+-	TWDEBUG("inside pan_display");
++
+ 	if (var->vmode & FB_VMODE_YWRAP) {
+ 		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
+ 			return -EINVAL;
+@@ -1303,10 +1791,8 @@ static int sisfb_pan_display(struct fb_v
+ 	else
+ 		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+ 
+-	TWDEBUG("end of pan_display");
+ 	return 0;
+ }
+-#endif
+ 
+ static int sisfb_mmap(struct fb_info *info, struct file *file,
+ 		      struct vm_area_struct *vma)
+@@ -1316,7 +1802,6 @@ static int sisfb_mmap(struct fb_info *in
+ 	unsigned long off;
+ 	u32 len, mmio_off;
+ 
+-	TWDEBUG("inside mmap");
+ 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
+ 
+ 	off = vma->vm_pgoff << PAGE_SHIFT;
+@@ -1351,11 +1836,11 @@ static int sisfb_mmap(struct fb_info *in
+ 	if (boot_cpu_data.x86 > 3)
+ 		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ #endif
++        /* RedHat requires vma as the first paramater to the following call */
+ 	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+ 				vma->vm_page_prot))
+ 		return -EAGAIN;
+ 
+-        TWDEBUG("end of mmap");
+ 	return 0;
+ }
+ 
+@@ -1368,7 +1853,6 @@ static void sis_get_glyph(struct fb_info
+ 	u8 *gbuf = gly->gmask;
+ 	int size;
+ 
+-	TWDEBUG("Inside get_glyph");
+ 	gly->fontheight = fontheight(p);
+ 	gly->fontwidth = fontwidth(p);
+ 	widthb = (fontwidth(p) + 7) / 8;
+@@ -1382,16 +1866,11 @@ static void sis_get_glyph(struct fb_info
+ 	size = fontheight(p) * widthb;
+ 	memcpy(gbuf, cdat, size);
+ 	gly->ngmask = size;
+-	TWDEBUG("End of get_glyph");
+ }
+ 
+ static int sisfb_update_var(int con, struct fb_info *info)
+ {
+-#ifdef SISFB_PAN
+         return(sisfb_pan_var(&fb_display[con].var));
+-#else
+-	return 0;
+-#endif	
+ }
+ 
+ static int sisfb_switch(int con, struct fb_info *info)
+@@ -1428,127 +1907,7 @@ static int sisfb_switch(int con, struct 
+ 
+ static void sisfb_blank(int blank, struct fb_info *info)
+ {
+-	u8 reg;
+-
+-	inSISIDXREG(SISCR, 0x17, reg);
+-
+-	if(blank > 0)
+-		reg &= 0x7f;
+-	else
+-		reg |= 0x80;
+-
+-        outSISIDXREG(SISCR, 0x17, reg);		
+-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
+-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
+-	printk(KERN_DEBUG "sisfb_blank() called (%d)\n", blank);
+-}
+-
+-
+-static int sisfb_ioctl(struct inode *inode, struct file *file,
+-		       unsigned int cmd, unsigned long arg, int con,
+-		       struct fb_info *info)
+-{
+-	TWDEBUG("inside ioctl");
+-	switch (cmd) {
+-	   case FBIO_ALLOC:
+-		if (!capable(CAP_SYS_RAWIO))
+-			return -EPERM;
+-		sis_malloc((struct sis_memreq *) arg);
+-		break;
+-	   case FBIO_FREE:
+-		if (!capable(CAP_SYS_RAWIO))
+-			return -EPERM;
+-		sis_free(*(unsigned long *) arg);
+-		break;
+-	   case FBIOGET_GLYPH:
+-                sis_get_glyph(info,(SIS_GLYINFO *) arg);
+-		break;	
+-	   case FBIOGET_HWCINFO:
+-		{
+-			unsigned long *hwc_offset = (unsigned long *) arg;
+-
+-			if (sisfb_caps & HW_CURSOR_CAP)
+-				*hwc_offset = sisfb_hwcursor_vbase -
+-				    (unsigned long) ivideo.video_vbase;
+-			else
+-				*hwc_offset = 0;
+-
+-			break;
+-		}
+-	   case FBIOPUT_MODEINFO:
+-		{
+-			struct mode_info *x = (struct mode_info *)arg;
+-
+-			ivideo.video_bpp        = x->bpp;
+-			ivideo.video_width      = x->xres;
+-			ivideo.video_height     = x->yres;
+-			ivideo.video_vwidth     = x->v_xres;
+-			ivideo.video_vheight    = x->v_yres;
+-			ivideo.org_x            = x->org_x;
+-			ivideo.org_y            = x->org_y;
+-			ivideo.refresh_rate     = x->vrate;
+-			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+-			switch(ivideo.video_bpp) {
+-        		case 8:
+-            			ivideo.DstColor = 0x0000;
+-	    			ivideo.SiS310_AccelDepth = 0x00000000;
+-				ivideo.video_cmap_len = 256;
+-            			break;
+-        		case 16:
+-            			ivideo.DstColor = 0x8000;
+-            			ivideo.SiS310_AccelDepth = 0x00010000;
+-				ivideo.video_cmap_len = 16;
+-            			break;
+-        		case 32:
+-            			ivideo.DstColor = 0xC000;
+-	    			ivideo.SiS310_AccelDepth = 0x00020000;
+-				ivideo.video_cmap_len = 16;
+-            			break;
+-			default:
+-				ivideo.video_cmap_len = 16;
+-		       	 	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+-				ivideo.accel = 0;
+-				break;
+-    			}
+-
+-			break;
+-		}
+-	   case FBIOGET_DISPINFO:
+-		sis_dispinfo((struct ap_data *)arg);
+-		break;
+-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
+-	        {
+-			sisfb_info *x = (sisfb_info *)arg;
+-
+-			x->sisfb_id = SISFB_ID;
+-			x->sisfb_version = VER_MAJOR;
+-			x->sisfb_revision = VER_MINOR;
+-			x->sisfb_patchlevel = VER_LEVEL;
+-			x->chip_id = ivideo.chip_id;
+-			x->memory = ivideo.video_size / 1024;
+-			x->heapstart = ivideo.heapstart / 1024;
+-			x->fbvidmode = sisfb_mode_no;
+-			x->sisfb_caps = sisfb_caps;
+-			x->sisfb_tqlen = 512; /* yet unused */
+-			x->sisfb_pcibus = ivideo.pcibus;
+-			x->sisfb_pcislot = ivideo.pcislot;
+-			x->sisfb_pcifunc = ivideo.pcifunc;
+-			x->sisfb_lcdpdc = sisfb_detectedpdc;
+-			x->sisfb_lcda = sisfb_detectedlcda;
+-	                break;
+-		}
+-	   case SISFB_GET_VBRSTATUS:
+-	        {
+-			unsigned long *vbrstatus = (unsigned long *) arg;
+-			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+-			else		           *vbrstatus = 0;
+-		}
+-	   default:
+-		return -EINVAL;
+-	}
+-	TWDEBUG("end of ioctl");
+-	return 0;
+-
++	sisfb_myblank(blank);
+ }
+ #endif
+ 
+@@ -1575,11 +1934,9 @@ static int sisfb_get_cmap_len(const stru
+ 		rc = 256;	
+ 		break;
+ 	case 16:
+-		rc = 16;	
+-		break;		
+ 	case 32:
+ 		rc = 16;
+-		break;	
++		break;
+ 	}
+ 	return rc;
+ }
+@@ -1596,7 +1953,7 @@ static int sisfb_setcolreg(unsigned regn
+ 		outSISREG(SISDACD, (red >> 10));
+ 		outSISREG(SISDACD, (green >> 10));
+ 		outSISREG(SISDACD, (blue >> 10));
+-		if (ivideo.disp_state & DISPTYPE_DISP2) {
++		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ 		        outSISREG(SISDAC2A, regno);
+ 			outSISREG(SISDAC2D, (red >> 8));
+ 			outSISREG(SISDAC2D, (green >> 8));
+@@ -1622,63 +1979,52 @@ static int sisfb_set_par(struct fb_info 
+ {
+ 	int err;
+ 
+-	TWDEBUG("inside set_par");
+         if((err = sisfb_do_set_var(&info->var, 1, info)))
+ 		return err;
+ 
+ 	sisfb_get_fix(&info->fix, info->currcon, info);
+ 
+-	TWDEBUG("end of set_par");
+ 	return 0;
+ }
+ 
+ static int sisfb_check_var(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
+ {
+-	unsigned int htotal =
+-		var->left_margin + var->xres + var->right_margin +
+-		var->hsync_len;
+-	unsigned int vtotal = 0;
++	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
+ 	double drate = 0, hrate = 0;
+ 	int found_mode = 0;
+ 	int refresh_rate, search_idx;
++	BOOLEAN recalc_clock = FALSE;
++	u32 pixclock;
++
++	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
++
++	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
+ 
+-	TWDEBUG("Inside check_var");
++	pixclock = var->pixclock;
+ 
+ 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+-		vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;   
++		vtotal += var->yres;
+ 		vtotal <<= 1;
+ 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+-		vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;   
++		vtotal += var->yres;
+ 		vtotal <<= 2;
+ 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+-		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+-		         var->vsync_len;   
+-	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
+-		         var->vsync_len;
++		vtotal += var->yres;
++		vtotal <<= 1;
++	} else 	vtotal += var->yres;
+ 
+ 	if(!(htotal) || !(vtotal)) {
+ 		SISFAIL("sisfb: no valid timing data");
+ 	}
+ 
+-	if((var->pixclock) && (htotal)) {
+-	   drate = 1E12 / var->pixclock;
+-	   hrate = drate / htotal;
+-	   refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+-	} else refresh_rate = 60;
+-
+-	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+-	if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
+-
+ 	search_idx = 0;
+ 	while( (sisbios_mode[search_idx].mode_no != 0) &&
+ 	       (sisbios_mode[search_idx].xres <= var->xres) ) {
+ 		if( (sisbios_mode[search_idx].xres == var->xres) &&
+ 		    (sisbios_mode[search_idx].yres == var->yres) &&
+ 		    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
+-		        if(sisfb_validate_mode(search_idx) > 0) {
++		        if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ 			   found_mode = 1;
+ 			   break;
+ 			}
+@@ -1687,38 +2033,95 @@ static int sisfb_check_var(struct fb_var
+ 	}
+ 
+ 	if(!found_mode) {
+-	
+-		printk(KERN_ERR "sisfb: %dx%dx%d is no valid mode\n", 
+-			var->xres, var->yres, var->bits_per_pixel);
+-			
++
+                 search_idx = 0;
+ 		while(sisbios_mode[search_idx].mode_no != 0) {
+-		       
+ 		   if( (var->xres <= sisbios_mode[search_idx].xres) &&
+-		       (var->yres <= sisbios_mode[search_idx].yres) && 
++		       (var->yres <= sisbios_mode[search_idx].yres) &&
+ 		       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
+-		          if(sisfb_validate_mode(search_idx) > 0) {
++		          if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ 			     found_mode = 1;
+ 			     break;
+ 			  }
+ 		   }
+ 		   search_idx++;
+-	        }			
++	        }
+ 		if(found_mode) {
++			printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
++		   		var->xres, var->yres, var->bits_per_pixel,
++				sisbios_mode[search_idx].xres,
++				sisbios_mode[search_idx].yres,
++				var->bits_per_pixel);
+ 			var->xres = sisbios_mode[search_idx].xres;
+ 		      	var->yres = sisbios_mode[search_idx].yres;
+-		      	printk(KERN_DEBUG "sisfb: Adapted to mode %dx%dx%d\n",
+-		   		var->xres, var->yres, var->bits_per_pixel);
+-		   
++
++
+ 		} else {
+-		   	printk(KERN_ERR "sisfb: Failed to find similar mode to %dx%dx%d\n", 
++		   	printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
+ 				var->xres, var->yres, var->bits_per_pixel);
+ 		   	return -EINVAL;
+ 		}
+ 	}
+ 
+-	/* TW: TODO: Check the refresh rate */		
+-	
++	if( ((ivideo.vbflags & VB_LVDS) ||			/* Slave modes on LVDS and 301B-DH */
++	     ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
++	    (var->bits_per_pixel == 8) ) {
++	    	refresh_rate = 60;
++		recalc_clock = TRUE;
++	} else if( (ivideo.current_htotal == htotal) &&		/* x=x & y=y & c=c -> assume depth change */
++	    	   (ivideo.current_vtotal == vtotal) &&
++	    	   (ivideo.current_pixclock == pixclock) ) {
++		drate = 1E12 / pixclock;
++	   	hrate = drate / htotal;
++	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
++	} else if( ( (ivideo.current_htotal != htotal) ||	/* x!=x | y!=y & c=c -> invalid pixclock */
++	    	     (ivideo.current_vtotal != vtotal) ) &&
++	    	   (ivideo.current_pixclock == var->pixclock) ) {
++		if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
++			refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
++		} else if(sisfb_parm_rate != -1) {
++			refresh_rate = sisfb_parm_rate;
++		} else {
++			refresh_rate = 60;
++		}
++		recalc_clock = TRUE;
++	} else if((pixclock) && (htotal) && (vtotal)) {
++	   	drate = 1E12 / pixclock;
++	   	hrate = drate / htotal;
++	   	refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
++	} else if(ivideo.current_refresh_rate) {
++		refresh_rate = ivideo.current_refresh_rate;
++		recalc_clock = TRUE;
++	} else {
++		refresh_rate = 60;
++		recalc_clock = TRUE;
++	}
++
++	myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
++
++	/* Eventually recalculate timing and clock */
++	if(recalc_clock) {
++	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
++	   var->pixclock = (u32) (1E12 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
++						sisbios_mode[search_idx].mode_no, myrateindex));
++	   sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
++		 			sisbios_mode[search_idx].mode_no, myrateindex,
++		 			&var->left_margin, &var->right_margin,
++		 			&var->upper_margin, &var->lower_margin,
++		 			&var->hsync_len, &var->vsync_len,
++		 			&var->sync, &var->vmode);
++	   if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
++		var->pixclock <<= 1;
++	   }
++	}
++
++	if(sisfb_thismonitor.datavalid) {
++	   if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
++	                         myrateindex, refresh_rate)) {
++	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++	   }
++	}
++
+ 	/* Adapt RGB settings */
+ 	sisfb_bpp_to_var(var);	
+ 	
+@@ -1732,17 +2135,19 @@ static int sisfb_check_var(struct fb_var
+ 	if(var->xres != var->xres_virtual)
+ 		var->xres_virtual = var->xres;
+ 
+-	if(!sisfb_ypan) {
+-		if(var->yres != var->yres_virtual)
+-			var->yres_virtual = var->yres;
+-	} else {
++	if(sisfb_ypan) {
+ 	   /* TW: Now patch yres_virtual if we use panning */
+ 	   /* *** May I do this? *** */
+ 	   var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+-	    if(var->yres_virtual <= var->yres) {
++	   if(var->yres_virtual <= var->yres) {
+ 	    	/* TW: Paranoia check */
+ 	        var->yres_virtual = var->yres;
+-	    }
++	   }
++	} else {
++	   if(var->yres != var->yres_virtual)
++		var->yres_virtual = var->yres;
++	   var->xoffset = 0;
++	   var->yoffset = 0;
+ 	}
+ 	
+ 	/* Truncate offsets to maximum if too high */
+@@ -1757,28 +2162,25 @@ static int sisfb_check_var(struct fb_var
+ 	    var->green.msb_right =
+ 	    var->blue.msb_right =
+ 	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;		
+-		
+-	TWDEBUG("end of check_var");
++
+ 	return 0;
+ }
+ 
+-#ifdef SISFB_PAN
+ static int sisfb_pan_display(struct fb_var_screeninfo *var,
+ 			     struct fb_info* info)
+ {
+ 	int err;
+-	
+-	TWDEBUG("inside pan_display");
+-	
++
+ 	if (var->xoffset > (var->xres_virtual - var->xres))
+ 		return -EINVAL;
+ 	if (var->yoffset > (var->yres_virtual - var->yres))
+ 		return -EINVAL;
+ 
+ 	if (var->vmode & FB_VMODE_YWRAP) {
+-		if (var->yoffset < 0
+-		    || var->yoffset >= info->var.yres_virtual
+-		    || var->xoffset) return -EINVAL;
++		if (var->yoffset < 0 ||
++		    var->yoffset >= info->var.yres_virtual ||
++		    var->xoffset)
++		    	return -EINVAL;
+ 	} else {
+ 		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+ 		    var->yoffset + info->var.yres > info->var.yres_virtual)
+@@ -1794,10 +2196,8 @@ static int sisfb_pan_display(struct fb_v
+ 	else
+ 		info->var.vmode &= ~FB_VMODE_YWRAP;
+ 
+-	TWDEBUG("end of pan_display");
+ 	return 0;
+ }
+-#endif
+ 
+ static int sisfb_mmap(struct fb_info *info, struct file *file,
+ 		      struct vm_area_struct *vma)
+@@ -1806,7 +2206,6 @@ static int sisfb_mmap(struct fb_info *in
+ 	unsigned long off;
+ 	u32 len, mmio_off;
+ 
+-	TWDEBUG("inside mmap");
+ 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
+ 
+ 	off = vma->vm_pgoff << PAGE_SHIFT;
+@@ -1844,139 +2243,143 @@ static int sisfb_mmap(struct fb_info *in
+ 				vma->vm_page_prot))
+ 		return -EAGAIN;
+ 
+-        TWDEBUG("end of mmap");
+ 	return 0;
+ }
+ 
+ static int sisfb_blank(int blank, struct fb_info *info)
+ {
+-	u8 reg;
++	return(sisfb_myblank(blank));
++}
+ 
+-	inSISIDXREG(SISCR, 0x17, reg);
++#endif
+ 
+-	if(blank > 0)
+-		reg &= 0x7f;
+-	else
+-		reg |= 0x80;
++/* ----------- FBDev related routines for all series ---------- */
+ 
+-        outSISIDXREG(SISCR, 0x17, reg);		
+-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
+-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
+-        return(0);
+-}
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++static int sisfb_ioctl(struct inode *inode, struct file *file,
++		       unsigned int cmd, unsigned long arg,
++		       struct fb_info *info)
++#else
+ static int sisfb_ioctl(struct inode *inode, struct file *file,
+-		       unsigned int cmd, unsigned long arg, 
++		       unsigned int cmd, unsigned long arg, int con,
+ 		       struct fb_info *info)
++#endif
+ {
+-	TWDEBUG("inside ioctl");
++	struct sis_memreq sismemreq;
++	struct ap_data sisapdata;
++	unsigned long sismembase = 0;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++	SIS_GLYINFO sisglyinfo;
++#endif
++
+ 	switch (cmd) {
+ 	   case FBIO_ALLOC:
+-		if (!capable(CAP_SYS_RAWIO))
++		if(!capable(CAP_SYS_RAWIO))
+ 			return -EPERM;
+-		sis_malloc((struct sis_memreq *) arg);
++		if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
++		   	return -EFAULT;
++        	sis_malloc(&sismemreq);
++		if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
++			sis_free(sismemreq.offset);
++		    	return -EFAULT;
++		}
+ 		break;
+ 	   case FBIO_FREE:
+-		if (!capable(CAP_SYS_RAWIO))
++		if(!capable(CAP_SYS_RAWIO))
+ 			return -EPERM;
+-		sis_free(*(unsigned long *) arg);
++		if(get_user(sismembase, (unsigned long *) arg))
++			return -EFAULT;
++		sis_free(sismembase);
+ 		break;
+-	   case FBIOGET_HWCINFO:
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++	   case FBIOGET_GLYPH:
++	        if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
++			return -EFAULT;
++                sis_get_glyph(info, &sisglyinfo);
++		break;
++	   case FBIOPUT_MODEINFO:
+ 		{
+-			unsigned long *hwc_offset = (unsigned long *) arg;
++			struct mode_info x;
+ 
+-			if (sisfb_caps & HW_CURSOR_CAP)
+-				*hwc_offset = sisfb_hwcursor_vbase -
+-				    (unsigned long) ivideo.video_vbase;
+-			else
+-				*hwc_offset = 0;
++			if(copy_from_user(&x, (void *)arg, sizeof(x)))
++				return -EFAULT;
+ 
++			ivideo.video_bpp        = x.bpp;
++			ivideo.video_width      = x.xres;
++			ivideo.video_height     = x.yres;
++			ivideo.video_vwidth     = x.v_xres;
++			ivideo.video_vheight    = x.v_yres;
++			ivideo.org_x            = x.org_x;
++			ivideo.org_y            = x.org_y;
++			ivideo.refresh_rate     = x.vrate;
++			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
++			sisfb_set_vparms();
+ 			break;
+ 		}
+-	   case FBIOPUT_MODEINFO:
++#endif
++	   case FBIOGET_HWCINFO:
+ 		{
+-			struct mode_info *x = (struct mode_info *)arg;
++			unsigned long myhwcoffset = 0;
+ 
+-			ivideo.video_bpp        = x->bpp;
+-			ivideo.video_width      = x->xres;
+-			ivideo.video_height     = x->yres;
+-			ivideo.video_vwidth     = x->v_xres;
+-			ivideo.video_vheight    = x->v_yres;
+-			ivideo.org_x            = x->org_x;
+-			ivideo.org_y            = x->org_y;
+-			ivideo.refresh_rate     = x->vrate;
+-			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+-			switch(ivideo.video_bpp) {
+-        		case 8:
+-            			ivideo.DstColor = 0x0000;
+-	    			ivideo.SiS310_AccelDepth = 0x00000000;
+-				ivideo.video_cmap_len = 256;
+-            			break;
+-        		case 16:
+-            			ivideo.DstColor = 0x8000;
+-            			ivideo.SiS310_AccelDepth = 0x00010000;
+-				ivideo.video_cmap_len = 16;
+-            			break;
+-        		case 32:
+-            			ivideo.DstColor = 0xC000;
+-	    			ivideo.SiS310_AccelDepth = 0x00020000;
+-				ivideo.video_cmap_len = 16;
+-            			break;
+-			default:
+-				ivideo.video_cmap_len = 16;
+-		       	 	printk(KERN_ERR "sisfb: Unsupported accel depth %d", ivideo.video_bpp);
+-				ivideo.accel = 0;
+-				break;
+-    			}
++			if(sisfb_caps & HW_CURSOR_CAP)
++				myhwcoffset = sisfb_hwcursor_vbase -
++				    (unsigned long) ivideo.video_vbase;
++
++			return put_user(myhwcoffset, (unsigned long *)arg);
+ 
+ 			break;
+ 		}
+ 	   case FBIOGET_DISPINFO:
+-		sis_dispinfo((struct ap_data *)arg);
++	   	sis_dispinfo(&sisapdata);
++		if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
++			return -EFAULT;
+ 		break;
+-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
++	   case SISFB_GET_INFO:  /* For communication with X driver */
+ 	        {
+-			sisfb_info *x = (sisfb_info *)arg;
++			sisfb_info x;
+ 
+-			x->sisfb_id = SISFB_ID;
+-			x->sisfb_version = VER_MAJOR;
+-			x->sisfb_revision = VER_MINOR;
+-			x->sisfb_patchlevel = VER_LEVEL;
+-			x->chip_id = ivideo.chip_id;
+-			x->memory = ivideo.video_size / 1024;
+-			x->heapstart = ivideo.heapstart / 1024;
+-			x->fbvidmode = sisfb_mode_no;
+-			x->sisfb_caps = sisfb_caps;
+-			x->sisfb_tqlen = 512; /* yet unused */
+-			x->sisfb_pcibus = ivideo.pcibus;
+-			x->sisfb_pcislot = ivideo.pcislot;
+-			x->sisfb_pcifunc = ivideo.pcifunc;
+-			x->sisfb_lcdpdc = sisfb_detectedpdc;
+-			x->sisfb_lcda = sisfb_detectedlcda;
++			x.sisfb_id = SISFB_ID;
++			x.sisfb_version = VER_MAJOR;
++			x.sisfb_revision = VER_MINOR;
++			x.sisfb_patchlevel = VER_LEVEL;
++			x.chip_id = ivideo.chip_id;
++			x.memory = ivideo.video_size / 1024;
++			x.heapstart = ivideo.heapstart / 1024;
++			x.fbvidmode = sisfb_mode_no;
++			x.sisfb_caps = sisfb_caps;
++			x.sisfb_tqlen = 512; /* yet unused */
++			x.sisfb_pcibus = ivideo.pcibus;
++			x.sisfb_pcislot = ivideo.pcislot;
++			x.sisfb_pcifunc = ivideo.pcifunc;
++			x.sisfb_lcdpdc = sisfb_detectedpdc;
++			x.sisfb_lcda = sisfb_detectedlcda;
++			x.sisfb_vbflags = ivideo.vbflags;
++			x.sisfb_currentvbflags = ivideo.currentvbflags;
++			x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
++			x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
++			if(copy_to_user((void *)arg, &x, sizeof(x)))
++				return -EFAULT;
+ 	                break;
+ 		}
+ 	   case SISFB_GET_VBRSTATUS:
+ 	        {
+-			unsigned long *vbrstatus = (unsigned long *) arg;
+-			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+-			else		           *vbrstatus = 0;
++			if(sisfb_CheckVBRetrace())
++				return put_user(1UL, (unsigned long *) arg);
++			else
++				return put_user(0UL, (unsigned long *) arg);
++			break;
+ 		}
+ 	   default:
+ 		return -EINVAL;
+ 	}
+-	TWDEBUG("end of ioctl");
+ 	return 0;
+-
+ }
+ 
+-#endif
+-
+-/* ----------- FBDev related routines for all series ---------- */
+ 
+ static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ 			 struct fb_info *info)
+ {
+-	TWDEBUG("inside get_fix");
+ 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+@@ -1987,45 +2390,47 @@ static int sisfb_get_fix(struct fb_fix_s
+ 
+ 	fix->smem_start = ivideo.video_base;
+ 
+-        /* TW */
+         if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+-	    if (ivideo.video_size > 0x1000000) {
+-	        fix->smem_len = 0xc00000;
+-	    } else if (ivideo.video_size > 0x800000)
+-		fix->smem_len = 0x800000;
+-	    else
+-		fix->smem_len = 0x400000;
++	    if(sisvga_engine == SIS_300_VGA) {
++	       if(ivideo.video_size > 0x1000000) {
++	          	fix->smem_len = 0xc00000;
++	       } else if(ivideo.video_size > 0x800000)
++		  	fix->smem_len = 0x800000;
++	       else
++		  	fix->smem_len = 0x400000;
++            } else {
++	       	fix->smem_len = ivideo.video_size - 0x100000;
++	    }
+         } else
+ 		fix->smem_len = sisfb_mem * 1024;
+ 
+-	fix->type        = video_type;
++	fix->type        = FB_TYPE_PACKED_PIXELS;
+ 	fix->type_aux    = 0;
+ 	if(ivideo.video_bpp == 8)
+ 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ 	else
+ 		fix->visual = FB_VISUAL_TRUECOLOR;
+ 	fix->xpanstep    = 0;
+-#ifdef SISFB_PAN
++
+         if(sisfb_ypan) 	 fix->ypanstep = 1;
+-#endif
++
+ 	fix->ywrapstep   = 0;
+ 	fix->line_length = ivideo.video_linelength;
+ 	fix->mmio_start  = ivideo.mmio_base;
+ 	fix->mmio_len    = sisfb_mmio_size;
+ 	if(sisvga_engine == SIS_300_VGA) 
+ 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
+-	else if(ivideo.chip == SIS_330)
++	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660) || (ivideo.chip == SIS_760))
+ 	   fix->accel    = FB_ACCEL_SIS_XABRE;
+-	else 
++	else
+ 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
+-	
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 	fix->reserved[0] = ivideo.video_size & 0xFFFF;
+ 	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
+ 	fix->reserved[2] = sisfb_caps;
+-#endif	
++#endif
+ 
+-	TWDEBUG("end of get_fix");
+ 	return 0;
+ }
+ 
+@@ -2033,17 +2438,15 @@ static int sisfb_get_fix(struct fb_fix_s
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ static struct fb_ops sisfb_ops = {
+-	owner:		THIS_MODULE,
+-	fb_get_fix:	sisfb_get_fix,
+-	fb_get_var:	sisfb_get_var,
+-	fb_set_var:	sisfb_set_var,
+-	fb_get_cmap:	sisfb_get_cmap,
+-	fb_set_cmap:	sisfb_set_cmap,
+-#ifdef SISFB_PAN
+-        fb_pan_display:	sisfb_pan_display,
+-#endif
+-	fb_ioctl:	sisfb_ioctl,
+-	fb_mmap:	sisfb_mmap,
++	.owner		= THIS_MODULE,
++	.fb_get_fix	= sisfb_get_fix,
++	.fb_get_var	= sisfb_get_var,
++	.fb_set_var	= sisfb_set_var,
++	.fb_get_cmap	= sisfb_get_cmap,
++	.fb_set_cmap	= sisfb_set_cmap,
++        .fb_pan_display = sisfb_pan_display,
++	.fb_ioctl	= sisfb_ioctl,
++	.fb_mmap	= sisfb_mmap,
+ };
+ #endif
+ 
+@@ -2056,9 +2459,7 @@ static struct fb_ops sisfb_ops = {
+ 	.fb_check_var = sisfb_check_var,
+ 	.fb_set_par   = sisfb_set_par,
+ 	.fb_setcolreg = sisfb_setcolreg,
+-#ifdef SISFB_PAN
+         .fb_pan_display = sisfb_pan_display,
+-#endif	
+         .fb_blank     = sisfb_blank,
+ 	.fb_fillrect  = fbcon_sis_fillrect,
+ 	.fb_copyarea  = fbcon_sis_copyarea,
+@@ -2105,35 +2506,42 @@ static int sisfb_get_dram_size_300(void)
+ 
+ 	} else {		/* 540, 630, 730 */
+ 
+-		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+-		if (pdev) {
+-			pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
+-			pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+-			ivideo.video_size = (unsigned int)(1 << (pci_data+21));
+-			pdev_valid = 1;
+-
+-			reg = SIS_DATA_BUS_64 << 6;
+-			switch (pci_data) {
+-			   case BRI_DRAM_SIZE_2MB:
+-				reg |= SIS_DRAM_SIZE_2MB;
+-				break;
+-			   case BRI_DRAM_SIZE_4MB:
+-				reg |= SIS_DRAM_SIZE_4MB;
+-				break;
+-			   case BRI_DRAM_SIZE_8MB:
+-				reg |= SIS_DRAM_SIZE_8MB;
+-				break;
+-			   case BRI_DRAM_SIZE_16MB:
+-				reg |= SIS_DRAM_SIZE_16MB;
+-				break;
+-			   case BRI_DRAM_SIZE_32MB:
+-				reg |= SIS_DRAM_SIZE_32MB;
+-				break;
+-			   case BRI_DRAM_SIZE_64MB:
+-				reg |= SIS_DRAM_SIZE_64MB;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++		pci_for_each_dev(pdev) {
++#else
++		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++			if ((pdev->vendor == PCI_VENDOR_ID_SI)
++				       && (pdev->device == nbridge_id)) {
++				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
++				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
++				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
++				pdev_valid = 1;
++
++				reg = SIS_DATA_BUS_64 << 6;
++				switch (pci_data) {
++				   case BRI_DRAM_SIZE_2MB:
++					reg |= SIS_DRAM_SIZE_2MB;
++					break;
++				   case BRI_DRAM_SIZE_4MB:
++					reg |= SIS_DRAM_SIZE_4MB;
++					break;
++				   case BRI_DRAM_SIZE_8MB:
++					reg |= SIS_DRAM_SIZE_8MB;
++					break;
++				   case BRI_DRAM_SIZE_16MB:
++					reg |= SIS_DRAM_SIZE_16MB;
++					break;
++				   case BRI_DRAM_SIZE_32MB:
++					reg |= SIS_DRAM_SIZE_32MB;
++					break;
++				   case BRI_DRAM_SIZE_64MB:
++					reg |= SIS_DRAM_SIZE_64MB;
++					break;
++				}
++				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ 				break;
+ 			}
+-			outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ 		}
+ 	
+ 		if (!pdev_valid)  return -1;
+@@ -2141,171 +2549,10 @@ static int sisfb_get_dram_size_300(void)
+ 	return 0;
+ }
+ 
+-static void sisfb_detect_VB_connect_300()
+-{
+-	u8 sr16, sr17, cr32, temp;
+-
+-	ivideo.TV_plug = ivideo.TV_type = 0;
+-
+-        switch(ivideo.hasVB) {
+-	  case HASVB_LVDS_CHRONTEL:
+-	  case HASVB_CHRONTEL:
+-	     SiS_SenseCh();
+-	     break;
+-	  case HASVB_301:
+-	  case HASVB_302:
+-	     SiS_Sense30x();
+-	     break;
+-	}
+-
+-	inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
+-        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+-
+-	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
+-
+-		if ((sr17 & 0x01) && !sisfb_crt1off)
+-			sisfb_crt1off = 0;
+-		else {
+-			if (sr17 & 0x0E)
+-				sisfb_crt1off = 1;
+-			else
+-				sisfb_crt1off = 0;
+-		}
+-
+-		if (sisfb_crt2type != -1)
+-			/* TW: override detected CRT2 type */
+-			ivideo.disp_state = sisfb_crt2type;
+-                else if (sr17 & 0x04)
+-			ivideo.disp_state = DISPTYPE_TV;			
+-		else if (sr17 & 0x02)
+-			ivideo.disp_state = DISPTYPE_LCD;			
+-		else if (sr17 & 0x08 )
+-			ivideo.disp_state = DISPTYPE_CRT2;
+-		else
+-			ivideo.disp_state = 0;
+-
+-		if(sisfb_tvplug != -1)
+-			/* PR/TW: override detected TV type */
+-			ivideo.TV_plug = sisfb_tvplug;
+-		else if (sr17 & 0x20)
+-			ivideo.TV_plug = TVPLUG_SVIDEO;
+-		else if (sr17 & 0x10)
+-			ivideo.TV_plug = TVPLUG_COMPOSITE;
+-
+-		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
+-		if (sr16 & 0x20)
+-			ivideo.TV_type = TVMODE_PAL;
+-		else
+-			ivideo.TV_type = TVMODE_NTSC;
+-
+-	} else {
+-
+-		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
+-			sisfb_crt1off = 0;
+-		else {
+-			if (cr32 & 0x5F)
+-				sisfb_crt1off = 1;
+-			else
+-				sisfb_crt1off = 0;
+-		}
+-
+-		if (sisfb_crt2type != -1)
+-			/* TW: override detected CRT2 type */
+-			ivideo.disp_state = sisfb_crt2type;
+-		else if (cr32 & SIS_VB_TV)
+-			ivideo.disp_state = DISPTYPE_TV;
+-		else if (cr32 & SIS_VB_LCD)
+-			ivideo.disp_state = DISPTYPE_LCD;
+-		else if (cr32 & SIS_VB_CRT2)
+-			ivideo.disp_state = DISPTYPE_CRT2;
+-		else
+-			ivideo.disp_state = 0;
+-
+-		/* TW: Detect TV plug & type */
+-		if(sisfb_tvplug != -1)
+-			/* PR/TW: override with option */
+-		        ivideo.TV_plug = sisfb_tvplug;
+-		else if (cr32 & SIS_VB_HIVISION) {
+-			ivideo.TV_type = TVMODE_HIVISION;
+-			ivideo.TV_plug = TVPLUG_SVIDEO;
+-		}
+-		else if (cr32 & SIS_VB_SVIDEO)
+-			ivideo.TV_plug = TVPLUG_SVIDEO;
+-		else if (cr32 & SIS_VB_COMPOSITE)
+-			ivideo.TV_plug = TVPLUG_COMPOSITE;
+-		else if (cr32 & SIS_VB_SCART)
+-			ivideo.TV_plug = TVPLUG_SCART;
+-
+-		if (ivideo.TV_type == 0) {
+-		        inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
+-			if (temp & 0x01)
+-				ivideo.TV_type = TVMODE_PAL;
+-			else
+-				ivideo.TV_type = TVMODE_NTSC;
+-		}
+-
+-	}
+-
+-	/* TW: Copy forceCRT1 option to CRT1off if option is given */
+-    	if (sisfb_forcecrt1 != -1) {
+-    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
+-		else                sisfb_crt1off = 1;
+-    	}
+-}
+-
+-static void sisfb_get_VB_type_300(void)
+-{
+-	u8 reg;
+-
+-	if(ivideo.chip != SIS_300) {
+-		if(!sisfb_has_VB_300()) {
+-		        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+-			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+-			   case SIS_EXTERNAL_CHIP_LVDS:
+-				ivideo.hasVB = HASVB_LVDS;
+-				break;
+-			   case SIS_EXTERNAL_CHIP_TRUMPION:
+-				ivideo.hasVB = HASVB_TRUMPION;
+-				break;
+-			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+-				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+-				break;
+-			   case SIS_EXTERNAL_CHIP_CHRONTEL:
+-				ivideo.hasVB = HASVB_CHRONTEL;
+-				break;
+-			   default:
+-				break;
+-			}
+-		}
+-	} else {
+-		sisfb_has_VB_300();
+-	}
+-}
+-
+-static int sisfb_has_VB_300(void)
+-{
+-	u8 vb_chipid;
+-
+-	inSISIDXREG(SISPART4, 0x00, vb_chipid);
+-	switch (vb_chipid) {
+-	   case 0x01:
+-		ivideo.hasVB = HASVB_301;
+-		break;
+-	   case 0x02:
+-		ivideo.hasVB = HASVB_302;
+-		break;
+-	   default:
+-		ivideo.hasVB = HASVB_NONE;
+-		return FALSE;
+-	}
+-	return TRUE;
+-
+-}
+-
+ #endif  /* CONFIG_FB_SIS_300 */
+ 
+ 
+-#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330 */
++#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330/660/760 */
+ 
+ static int sisfb_get_dram_size_315(void)
+ {
+@@ -2314,21 +2561,33 @@ static int sisfb_get_dram_size_315(void)
+ 	u8  pci_data;
+ 	u8  reg = 0;
+ 
+-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
++	if (ivideo.chip == SIS_550 ||
++	    ivideo.chip == SIS_650 ||
++	    ivideo.chip == SIS_740 ||
++	    ivideo.chip == SIS_660 ||
++	    ivideo.chip == SIS_760) {
+ 
+ #ifdef LINUXBIOS
+ 
+-		while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev)) != NULL) {
+-			if ((pdev->device == PCI_DEVICE_ID_SI_550) ||
+-			     (pdev->device == PCI_DEVICE_ID_SI_650) ||
+-			     (pdev->device == PCI_DEVICE_ID_SI_740)) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++		pci_for_each_dev(pdev) {
++#else
++		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++
++			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
++				&& ( (pdev->device == PCI_DEVICE_ID_SI_550) ||
++				     (pdev->device == PCI_DEVICE_ID_SI_650) ||
++				     (pdev->device == PCI_DEVICE_ID_SI_740) ||
++				     (pdev->device == PCI_DEVICE_ID_SI_660) ||
++				     (pdev->device == PCI_DEVICE_ID_SI_760))) {
+ 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+ 				                     &pci_data);
+ 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+ 				ivideo.video_size = (unsigned int)(1 << (pci_data + 21));
+ 				pdev_valid = 1;
+ 
+-				/* TW: Initialize SR14 "by hand" */
++				/* Initialize SR14 "by hand" */
+ 				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ 				reg &= 0xC0;
+ 				switch (pci_data) {
+@@ -2390,7 +2649,15 @@ static int sisfb_get_dram_size_315(void)
+ 			       "now reading from PCI config\n");
+ 			pdev_valid = 0;
+ 
+-			while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550, pdev)) != NULL) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++			pci_for_each_dev(pdev) {
++#else
++			while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
++
++			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)
++			         && (pdev->device == PCI_DEVICE_ID_SI_550) ) {
++
+ 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
+ 				                     &pci_data);
+ 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+@@ -2415,6 +2682,7 @@ static int sisfb_get_dram_size_315(void)
+ 					return -1;
+ 				}
+ 				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
++			   }
+ 			}
+ 			if (!pdev_valid) {
+ 				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
+@@ -2425,7 +2693,7 @@ static int sisfb_get_dram_size_315(void)
+ #endif
+ 		return 0;
+ 
+-	} else {	/* 315 */
++	} else {	/* 315, 330 */
+ 
+ 	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+ 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
+@@ -2458,7 +2726,7 @@ static int sisfb_get_dram_size_315(void)
+ 		reg >>= 2;
+ 		
+ 		if(ivideo.chip == SIS_330) {
+-		
++
+ 		   if(reg) ivideo.video_size <<= 1;
+ 		
+ 		} else {
+@@ -2470,7 +2738,7 @@ static int sisfb_get_dram_size_315(void)
+ 		      case SIS315_DUAL_CHANNEL_1_RANK:
+ 			   ivideo.video_size <<= 1;
+ 			   break;
+-		      case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
++		      case SIS315_ASYM_DDR:		/* TW: DDR asymetric */
+ 			   ivideo.video_size += (ivideo.video_size/2);
+ 			   break;
+ 		   }
+@@ -2483,127 +2751,241 @@ static int sisfb_get_dram_size_315(void)
+ 	
+ }
+ 
+-static void sisfb_detect_VB_connect_315(void)
++#endif   /* CONFIG_FB_SIS_315 */
++
++
++/* -------------- video bridge detection --------------- */
++
++static void sisfb_detect_VB_connect()
+ {
+-	u8 cr32, temp=0;
++	u8 sr16, sr17, cr32, temp;
++
++	if(sisvga_engine == SIS_300_VGA) {
+ 
+-	ivideo.TV_plug = ivideo.TV_type = 0;
++		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
++
++		if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
++
++			/* Old BIOSes store the detected CRT2 type in SR17
++		 	 * instead of CR32. However, since our detection
++			 * routines store their results to CR32, we now copy
++			 * the remaining bits (for LCD and VGA) to CR32 for
++			 * unified usage.
++			 * SR17[0] CRT1    [1] LCD     [2] TV    [3] VGA2
++			 *     [4] AVIDEO  [5] SVIDEO
++			 */
++
++#if 0
++			if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
++			else		 andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
++
++			if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
++			else		 andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
++
++			/* no HiVision and no DVI connector here */
++			andSISIDXREG(SISCR, 0x32, ~0xc0);
++#endif
++
++			/* PAL/NTSC is stored on SR16 on such machines */
++			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
++		   		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
++				if (sr16 & 0x20)
++					ivideo.vbflags |= TV_PAL;
++				else
++					ivideo.vbflags |= TV_NTSC;
++			}
++
++		}
+ 
+-        switch(ivideo.hasVB) {
+-	  case HASVB_LVDS_CHRONTEL:
+-	  case HASVB_CHRONTEL:
+-	     SiS_SenseCh();
+-	     break;
+-	  case HASVB_301:
+-	  case HASVB_302:
+-	     SiS_Sense30x();
+-	     break;
+ 	}
+ 
+ 	inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+ 
+-	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
++	if (cr32 & SIS_CRT1)
+ 		sisfb_crt1off = 0;
+ 	else {
+-		if (cr32 & 0x5F)   
++		if (cr32 & 0x5F)
+ 			sisfb_crt1off = 1;
+ 		else
+ 			sisfb_crt1off = 0;
+ 	}
+ 
+-	if (sisfb_crt2type != -1)
+-		/* TW: Override with option */
+-		ivideo.disp_state = sisfb_crt2type;
+-	else if (cr32 & SIS_VB_TV)
+-		ivideo.disp_state = DISPTYPE_TV;		
+-	else if (cr32 & SIS_VB_LCD)
+-		ivideo.disp_state = DISPTYPE_LCD;		
+-	else if (cr32 & SIS_VB_CRT2)
+-		ivideo.disp_state = DISPTYPE_CRT2;
+-	else
+-		ivideo.disp_state = 0;
++	ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+ 
++	if (cr32 & SIS_VB_TV)
++		ivideo.vbflags |= CRT2_TV;
++	if (cr32 & SIS_VB_LCD)
++		ivideo.vbflags |= CRT2_LCD;
++	if (cr32 & SIS_VB_CRT2)
++		ivideo.vbflags |= CRT2_VGA;
++
++	/* TW: Detect/set TV plug & type */
+ 	if(sisfb_tvplug != -1)
+-		/* PR/TW: Override with option */
+-	        ivideo.TV_plug = sisfb_tvplug;
+-	else if (cr32 & SIS_VB_HIVISION) {
+-		ivideo.TV_type = TVMODE_HIVISION;
+-		ivideo.TV_plug = TVPLUG_SVIDEO;
+-	}
++	        ivideo.vbflags |= sisfb_tvplug;
++	if (cr32 & SIS_VB_HIVISION)
++		ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);
+ 	else if (cr32 & SIS_VB_SVIDEO)
+-		ivideo.TV_plug = TVPLUG_SVIDEO;
++		ivideo.vbflags |= TV_SVIDEO;
+ 	else if (cr32 & SIS_VB_COMPOSITE)
+-		ivideo.TV_plug = TVPLUG_COMPOSITE;
++		ivideo.vbflags |= TV_AVIDEO;
+ 	else if (cr32 & SIS_VB_SCART)
+-		ivideo.TV_plug = TVPLUG_SCART;
++		ivideo.vbflags |= TV_SCART;
+ 
+-	if(ivideo.TV_type == 0) {
+-	    /* TW: PAL/NTSC changed for 650 */
+-	    if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+-
+-                inSISIDXREG(SISCR, 0x38, temp);
+-		if(temp & 0x10)
+-			ivideo.TV_type = TVMODE_PAL;
+-		else
+-			ivideo.TV_type = TVMODE_NTSC;
++	if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
++		if(sisvga_engine == SIS_300_VGA) {
++	        	inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
++			if (temp & 0x01)
++				ivideo.vbflags |= TV_PAL;
++			else
++				ivideo.vbflags |= TV_NTSC;
++		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
+ 
+-	    } else {
++                	inSISIDXREG(SISCR, 0x38, temp);
++			if(temp & 0x10)
++				ivideo.vbflags |= TV_PAL;
++			else
++				ivideo.vbflags |= TV_NTSC;
+ 
+-	        inSISIDXREG(SISCR, 0x79, temp);
+-		if(temp & 0x20)
+-			ivideo.TV_type = TVMODE_PAL;
+-		else
+-			ivideo.TV_type = TVMODE_NTSC;
+-	    }
++	    	} else {
++
++	        	inSISIDXREG(SISCR, 0x79, temp);
++			if(temp & 0x20)
++				ivideo.vbflags |= TV_PAL;
++			else
++				ivideo.vbflags |= TV_NTSC;
++	    	}
+ 	}
+ 
+ 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
+     	if (sisfb_forcecrt1 != -1) {
+-    		if (sisfb_forcecrt1) sisfb_crt1off = 0;
+-		else   	             sisfb_crt1off = 1;
++    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
++		else                sisfb_crt1off = 1;
+     	}
+-}
+-
+-static void sisfb_get_VB_type_315(void)
+-{
+-	u8 reg;
+ 
+-	if (!sisfb_has_VB_315()) {
+-	        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+-		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+-	 	   case SIS310_EXTERNAL_CHIP_LVDS:
+-			ivideo.hasVB = HASVB_LVDS;
+-			break;
+-		   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+-			ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+-			break;
+-		   default:
+-			break;
+-		}
+-	}
+ }
+ 
+-
+-static int sisfb_has_VB_315(void)
++static void sisfb_get_VB_type(void)
+ {
+ 	u8 vb_chipid;
++	u8 reg;
++	char stdstr[]    = "sisfb: Detected";
++	char bridgestr[] = "video bridge";
++	char lvdsstr[]   = "LVDS transmitter";
++  	char chrstr[]    = "Chrontel TV encoder";
++
++	ivideo.hasVB = HASVB_NONE;
++	sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
++	sishw_ext.Is301BDH = FALSE;
++	sishw_ext.usExternalChip = 0;
+ 
+ 	inSISIDXREG(SISPART4, 0x00, vb_chipid);
+ 	switch (vb_chipid) {
+ 	   case 0x01:
+ 		ivideo.hasVB = HASVB_301;
++		inSISIDXREG(SISPART4, 0x01, reg);
++		if(reg < 0xb0) {
++			ivideo.vbflags |= VB_301;
++			sishw_ext.ujVBChipID = VB_CHIP_301;
++			printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
++		} else if(reg < 0xd0) {
++		 	ivideo.vbflags |= VB_301B;
++			sishw_ext.ujVBChipID = VB_CHIP_301B;
++			printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
++		} else if(reg < 0xe0) {
++			ivideo.vbflags |= VB_301LV;
++			sishw_ext.ujVBChipID = VB_CHIP_301LV;
++			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
++		} else if(reg <= 0xe1) {
++			ivideo.vbflags |= VB_302LV;
++			sishw_ext.ujVBChipID = VB_CHIP_302LV;
++			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
++		}
+ 		break;
+ 	   case 0x02:
+ 		ivideo.hasVB = HASVB_302;
++		inSISIDXREG(SISPART4, 0x01, reg);
++		if(reg < 0xd0) {
++			ivideo.vbflags |= VB_302B;
++			sishw_ext.ujVBChipID = VB_CHIP_302B;
++			printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
++		} else if(reg < 0xe0) {
++		 	ivideo.vbflags |= VB_301LV;
++			sishw_ext.ujVBChipID = VB_CHIP_301LV;
++			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
++		} else if(reg <= 0xe1) {
++			ivideo.vbflags |= VB_302LV;
++			sishw_ext.ujVBChipID = VB_CHIP_302LV;
++			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
++		}
+ 		break;
+-	   default:
+-		ivideo.hasVB = HASVB_NONE;
+-		return FALSE;
+ 	}
+-	return TRUE;
+-}
+ 
+-#endif   /* CONFIG_FB_SIS_315 */
++	if(ivideo.vbflags & (VB_301B | VB_302B)) {
++		inSISIDXREG(SISPART4,0x23,reg);
++		if(!(reg & 0x02)) {
++			sishw_ext.Is301BDH = TRUE;
++			ivideo.vbflags |= VB_30xBDH;
++			printk(KERN_INFO "This %s does not support LCD output\n", bridgestr);
++		}
++	}
++
++	if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
++		inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
++		reg &= SIS_EXTERNAL_CHIP_MASK;
++		reg >>= 1;
++		if(sisvga_engine == SIS_300_VGA) {
++			switch (reg) {
++			   case SIS_EXTERNAL_CHIP_LVDS:
++				ivideo.hasVB = HASVB_LVDS;
++				ivideo.vbflags |= VB_LVDS;
++				sishw_ext.usExternalChip = 0x01;
++				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
++				break;
++			   case SIS_EXTERNAL_CHIP_TRUMPION:
++				ivideo.hasVB = HASVB_TRUMPION;
++				ivideo.vbflags |= VB_TRUMPION;
++				sishw_ext.usExternalChip = 0x02;
++				printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
++				break;
++			   case SIS_EXTERNAL_CHIP_CHRONTEL:
++				ivideo.hasVB = HASVB_CHRONTEL;
++				ivideo.vbflags |= VB_CHRONTEL;
++				sishw_ext.usExternalChip = 0x04;
++				printk(KERN_INFO "%s %s\n", stdstr, chrstr);
++				break;
++			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
++				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
++				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
++				sishw_ext.usExternalChip = 0x05;
++				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
++				break;
++			}
++		} else {
++			switch (reg) {
++	 	   	   case SIS310_EXTERNAL_CHIP_LVDS:
++				ivideo.hasVB = HASVB_LVDS;
++				ivideo.vbflags |= VB_LVDS;
++				sishw_ext.usExternalChip = 0x01;
++				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
++				break;
++		   	   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
++				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
++				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
++				sishw_ext.usExternalChip = 0x05;
++				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
++				break;
++			}
++		}
++
++	}
++
++	if(ivideo.vbflags & VB_SISBRIDGE) {
++		SiS_Sense30x();
++	} else if(ivideo.vbflags & VB_CHRONTEL) {
++		SiS_SenseCh();
++	}
++
++}
+ 
+ /* ------------------ Sensing routines ------------------ */
+ 
+@@ -2621,34 +3003,39 @@ SISDoSense(int tempbl, int tempbh, int t
+     inSISIDXREG(SISPART4,0x03,temp);
+     temp ^= 0x0e;
+     temp &= tempch;
+-    return(temp);
++    return((temp == tempch));
+ }
+ 
+ void
+ SiS_Sense30x(void)
+ {
+-  u8 backupP4_0d;
++  u8 backupP4_0d,backupP2_00;
+   u8 testsvhs_tempbl, testsvhs_tempbh;
+   u8 testsvhs_tempcl, testsvhs_tempch;
+   u8 testcvbs_tempbl, testcvbs_tempbh;
+   u8 testcvbs_tempcl, testcvbs_tempch;
+   u8 testvga2_tempbl, testvga2_tempbh;
+   u8 testvga2_tempcl, testvga2_tempch;
+-  int myflag, result;
++  int myflag, result, haveresult, i, j;
++  char stdstr[] = "sisfb: Detected";
++  char tvstr[]  = "TV connected to";
+ 
+   inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+   outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
+ 
++  inSISIDXREG(SISPART2,0x00,backupP2_00);
++  outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
++
+   if(sisvga_engine == SIS_300_VGA) {
+ 
+-  	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+-        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+-	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+-	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+-	   (sishw_ext.ujVBChipID != VB_CHIP_302) ) {
+-	   testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+-	   testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+-	   testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++	if(ivideo.vbflags & (VB_301B|VB_302B|VB_301LV|VB_302LV)) {
++	   	testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
++	   	testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
++	   	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++	} else {
++		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
++        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
++		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ 	}
+ 	inSISIDXREG(SISPART4,0x01,myflag);
+ 	if(myflag & 0x04) {
+@@ -2657,35 +3044,36 @@ SiS_Sense30x(void)
+ 	   testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ 	}
+ 	testvga2_tempch = 0x0e;	testvga2_tempcl = 0x08;
+-	testsvhs_tempch = 0x06;	testsvhs_tempcl = 0x04;
++	testsvhs_tempch = 0x04;	testsvhs_tempcl = 0x04;
+ 	testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
++	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++	   	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++	   	testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
++	 }
+ 	if(ivideo.chip == SIS_300) {
+ 	   inSISIDXREG(SISSR,0x3b,myflag);
+ 	   if(!(myflag & 0x01)) {
+-	      testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+-	      testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
++	      	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++	      	testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+ 	   }
+ 	}
+ 
+   } else {
+ 
+-	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+-        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+-	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+-	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+-	   (sishw_ext.ujVBChipID != VB_CHIP_302)) {
+-	      testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+-	      testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+-	      testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+-	      if(sishw_ext.ujVBChipID == VB_CHIP_301LV ||
+-	         sishw_ext.ujVBChipID == VB_CHIP_302LV) {
+-	         testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+-	         testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
+-	         testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
+-	      }
++	if(ivideo.vbflags & (VB_301B|VB_302B)) {
++		testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
++		testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
++		testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
++	} else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
++	      	testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
++	      	testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
++	      	testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
++	} else {
++		testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
++        	testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
++		testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+ 	}
+-	if(sishw_ext.ujVBChipID != VB_CHIP_301LV &&
+-	   sishw_ext.ujVBChipID != VB_CHIP_302LV) {
++	if(ivideo.vbflags & (VB_301|VB_301B|VB_302B)) {
+ 	   inSISIDXREG(SISPART4,0x01,myflag);
+ 	   if(myflag & 0x04) {
+ 	      testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+@@ -2693,49 +3081,78 @@ SiS_Sense30x(void)
+ 	      testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+ 	   }
+ 	}
+-	if((sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+-	   (sishw_ext.ujVBChipID == VB_CHIP_302LV) ) {
++	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+ 	   testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+ 	   testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+ 	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
+ 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+ 	} else {
+ 	   testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+-	   testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
++	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x04;
+ 	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+ 	}
+     } 
+ 
+     if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
+-        result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
+-                            testvga2_tempcl, testvga2_tempch);
+- 	if(result) {
+-        	printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
+-		orSISIDXREG(SISCR, 0x32, 0x10);
+-	}
++       haveresult = 0;
++       for(j = 0; j < 10; j++) {
++          result = 0;
++          for(i = 0; i < 3; i++) {
++             if(SISDoSense(testvga2_tempbl, testvga2_tempbh,
++                           testvga2_tempcl, testvga2_tempch))
++	        result++;
++          }
++	  if((result == 0) || (result >= 2)) break;
++       }
++       if(result) {
++          printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
++	  orSISIDXREG(SISCR, 0x32, 0x10);
++       } else {
++	  andSISIDXREG(SISCR, 0x32, ~0x10);
++       }
++    }
++
++    haveresult = 0;
++    for(j = 0; j < 10; j++) {
++       result = 0;
++       for(i = 0; i < 3; i++) {
++          if(SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
++                        testsvhs_tempcl, testsvhs_tempch))
++	        result++;
++       }
++       if((result == 0) || (result >= 2)) break;
+     }
+-    
+-    result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
+-                        testsvhs_tempcl, testsvhs_tempch);
+     if(result) {
+-        printk(KERN_INFO "sisfb: Detected TV connected to SVHS output\n");
+-        /* TW: So we can be sure that there IS a SVHS output */
+-	ivideo.TV_plug = TVPLUG_SVIDEO;
++        printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
++	ivideo.vbflags |= TV_SVIDEO;
+ 	orSISIDXREG(SISCR, 0x32, 0x02);
++	andSISIDXREG(SISCR, 0x32, ~0x05);
+     }
+ 
+     if(!result) {
+-        result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
+-	                    testcvbs_tempcl, testcvbs_tempch);
++
++	haveresult = 0;
++       	for(j = 0; j < 10; j++) {
++           result = 0;
++           for(i = 0; i < 3; i++) {
++              if(SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
++	                    testcvbs_tempcl, testcvbs_tempch))
++	        result++;
++           }
++           if((result == 0) || (result >= 2)) break;
++        }
+ 	if(result) {
+-	    printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
+-	    /* TW: So we can be sure that there IS a CVBS output */
+-	    ivideo.TV_plug = TVPLUG_COMPOSITE;
++	    printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
++	    ivideo.vbflags |= TV_AVIDEO;
+ 	    orSISIDXREG(SISCR, 0x32, 0x01);
++	    andSISIDXREG(SISCR, 0x32, ~0x06);
++	} else {
++	    andSISIDXREG(SISCR, 0x32, ~0x07);
+ 	}
+     }
+     SISDoSense(0, 0, 0, 0);
+ 
++    outSISIDXREG(SISPART2,0x00,backupP2_00);
+     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ }
+ 
+@@ -2744,51 +3161,84 @@ void
+ SiS_SenseCh(void)
+ {
+ 
+-   u8 temp1;
+-#ifdef CONFIG_FB_SIS_315
+-   u8 temp2;
++   u8 temp1, temp2;
++#ifdef CONFIG_FB_SIS_300
++   unsigned char test[3];
++   int i;
+ #endif
++   char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
+ 
+    if(ivideo.chip < SIS_315H) {
+ 
+ #ifdef CONFIG_FB_SIS_300
+-       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* TW: Chrontel 7005 */
++       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* Chrontel 700x */
++       SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);	/* Set general purpose IO for Chrontel communication */
++       SiS_DDC2Delay(&SiS_Pr, 1000);
+        temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
+-       if ((temp1 >= 50) && (temp1 <= 100)) {
+-	   /* TW: Read power status */
++       /* TW: See Chrontel TB31 for explanation */
++       temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
++       if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
++	  SiS_SetCH700x(&SiS_Pr, 0x0b0e);
++	  SiS_DDC2Delay(&SiS_Pr, 300);
++       }
++       temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
++       if(temp2 != temp1) temp1 = temp2;
++
++       if((temp1 >= 0x22) && (temp1 <= 0x50)) {
++	   /* Read power status */
+ 	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+ 	   if((temp1 & 0x03) != 0x03) {
+-     	        /* TW: Power all outputs */
+-		SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
++     	        /* Power all outputs */
++		SiS_SetCH700x(&SiS_Pr, 0x0B0E);
++		SiS_DDC2Delay(&SiS_Pr, 300);
+ 	   }
+-	   /* TW: Sense connected TV devices */
+-	   SiS_SetCH700x(&SiS_Pr, 0x0110);
+-	   SiS_SetCH700x(&SiS_Pr, 0x0010);
+-	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+-	   if(!(temp1 & 0x08)) {
+-		printk(KERN_INFO
+-		   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+-		/* TW: So we can be sure that there IS a SVHS output */
+-		ivideo.TV_plug = TVPLUG_SVIDEO;
++	   /* Sense connected TV devices */
++	   for(i = 0; i < 3; i++) {
++	       SiS_SetCH700x(&SiS_Pr, 0x0110);
++	       SiS_DDC2Delay(&SiS_Pr, 0x96);
++	       SiS_SetCH700x(&SiS_Pr, 0x0010);
++	       SiS_DDC2Delay(&SiS_Pr, 0x96);
++	       temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
++	       if(!(temp1 & 0x08))       test[i] = 0x02;
++	       else if(!(temp1 & 0x02))  test[i] = 0x01;
++	       else                      test[i] = 0;
++	       SiS_DDC2Delay(&SiS_Pr, 0x96);
++	   }
++
++	   if(test[0] == test[1])      temp1 = test[0];
++	   else if(test[0] == test[2]) temp1 = test[0];
++	   else if(test[1] == test[2]) temp1 = test[1];
++	   else {
++	   	printk(KERN_INFO
++			"sisfb: TV detection unreliable - test results varied\n");
++		temp1 = test[2];
++	   }
++	   if(temp1 == 0x02) {
++		printk(KERN_INFO "%s SVIDEO output\n", stdstr);
++		ivideo.vbflags |= TV_SVIDEO;
+ 		orSISIDXREG(SISCR, 0x32, 0x02);
+-	   } else if (!(temp1 & 0x02)) {
+-		printk(KERN_INFO
+-		   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+-		/* TW: So we can be sure that there IS a CVBS output */
+-		ivideo.TV_plug = TVPLUG_COMPOSITE;
++		andSISIDXREG(SISCR, 0x32, ~0x05);
++	   } else if (temp1 == 0x01) {
++		printk(KERN_INFO "%s CVBS output\n", stdstr);
++		ivideo.vbflags |= TV_AVIDEO;
+ 		orSISIDXREG(SISCR, 0x32, 0x01);
++		andSISIDXREG(SISCR, 0x32, ~0x06);
+ 	   } else {
+  		SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
++		andSISIDXREG(SISCR, 0x32, ~0x07);
+ 	   }
+        } else if(temp1 == 0) {
+ 	  SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
++	  andSISIDXREG(SISCR, 0x32, ~0x07);
+        }
++       /* Set general purpose IO for Chrontel communication */
++       SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
+ #endif
+ 
+    } else {
+ 
+ #ifdef CONFIG_FB_SIS_315
+-	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* TW: Chrontel 7019 */
++	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* Chrontel 7019 */
+         temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
+ 	SiS_SetCH701x(&SiS_Pr, 0x2049);
+ 	SiS_DDC2Delay(&SiS_Pr, 0x96);
+@@ -2808,22 +3258,24 @@ SiS_SenseCh(void)
+ 	if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
+ 	switch(temp1) {
+ 	case 0x01:
+-	     printk(KERN_INFO
+-		"sisfb: Chrontel: Detected TV connected to CVBS output\n");
+-	     ivideo.TV_plug = TVPLUG_COMPOSITE;
++	     printk(KERN_INFO "%s CVBS output\n", stdstr);
++	     ivideo.vbflags |= TV_AVIDEO;
+ 	     orSISIDXREG(SISCR, 0x32, 0x01);
++	     andSISIDXREG(SISCR, 0x32, ~0x06);
+              break;
+ 	case 0x02:
+-	     printk(KERN_INFO
+-		"sisfb: Chrontel: Detected TV connected to SVHS output\n");
+-	     ivideo.TV_plug = TVPLUG_SVIDEO;
++	     printk(KERN_INFO "%s SVIDEO output\n", stdstr);
++	     ivideo.vbflags |= TV_SVIDEO;
+ 	     orSISIDXREG(SISCR, 0x32, 0x02);
++	     andSISIDXREG(SISCR, 0x32, ~0x05);
+              break;
+ 	case 0x04:
+-	     /* TW: This should not happen */
+-	     printk(KERN_INFO
+-		"sisfb: Chrontel: Detected TV connected to SCART output\n");
++	     printk(KERN_INFO "%s SCART output\n", stdstr);
++	     orSISIDXREG(SISCR, 0x32, 0x04);
++	     andSISIDXREG(SISCR, 0x32, ~0x03);
+              break;
++	default:
++	     andSISIDXREG(SISCR, 0x32, ~0x07);
+ 	}
+ #endif
+ 
+@@ -2845,8 +3297,8 @@ static int sisfb_heap_init(void)
+ 	unsigned long *write_port = 0;
+ 	SIS_CMDTYPE    cmd_type;
+ #ifndef AGPOFF
+-	struct agp_kern_info  *agp_info;
+-	struct agp_memory     *agp;
++	agp_kern_info  *agp_info;
++	agp_memory     *agp;
+ 	u32            agp_phys;
+ #endif
+ #endif
+@@ -2860,14 +3312,21 @@ static int sisfb_heap_init(void)
+  *     in XF86Config-4.
+  *     The heap start can also be specified by parameter "mem" when starting the sisfb
+  *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
++ *
++ *     On the 315 and Xabre series, the default is a 1MB heap since DRI is not
++ *     supported there.
+  */
+      if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+-        if (ivideo.video_size > 0x1000000) {
++        if(sisvga_engine == SIS_300_VGA) {
++           if (ivideo.video_size > 0x1000000) {
+ 	        ivideo.heapstart = 0xc00000;
+-	} else if (ivideo.video_size > 0x800000) {
++	   } else if (ivideo.video_size > 0x800000) {
+ 	        ivideo.heapstart = 0x800000;
+-	} else {
++	   } else {
+ 		ivideo.heapstart = 0x400000;
++	   }
++	} else {
++	   ivideo.heapstart = ivideo.video_size - 0x100000;
+ 	}
+      } else {
+            ivideo.heapstart = sisfb_mem * 1024;
+@@ -2883,7 +3342,7 @@ static int sisfb_heap_init(void)
+ #ifdef CONFIG_FB_SIS_315
+      if (sisvga_engine == SIS_315_VGA) {
+         /* TW: Now initialize the 310 series' command queue mode.
+-	 * On 310/325, there are three queue modes available which
++	 * On 315, there are three queue modes available which
+ 	 * are chosen by setting bits 7:5 in SR26:
+ 	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
+ 	 *    track of the queue, the FIFO, command parsing and so
+@@ -2923,8 +3382,8 @@ static int sisfb_heap_init(void)
+ 
+ #ifndef AGPOFF
+ 	if (sisfb_queuemode == AGP_CMD_QUEUE) {
+-		agp_info = vmalloc(sizeof(*agp_info));
+-		memset((void*)agp_info, 0x00, sizeof(*agp_info));
++		agp_info = vmalloc(sizeof(agp_kern_info));
++		memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+ 		agp_copy_info(agp_info);
+ 
+ 		agp_backend_acquire();
+@@ -3025,10 +3484,6 @@ static int sisfb_heap_init(void)
+ 		break;
+ 
+ 	   default:  /* MMIO */
+-	   	/* TW: This previously only wrote SIS_MMIO_CMD_ENABLE
+-		 * to IND_SIS_CMDQUEUE_SET. I doubt that this is
+-		 * enough. Reserve memory in any way.
+-		 */
+ 	   	sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
+ 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+ 
+@@ -3037,7 +3492,7 @@ static int sisfb_heap_init(void)
+ 
+ 		*write_port = *read_port;
+ 
+-		/* TW: Set Auto_Correction bit */
++		/* Set Auto_Correction bit */
+ 		temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+ 		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+ 
+@@ -3333,7 +3788,6 @@ void sis_malloc(struct sis_memreq *req)
+ 		req->offset = poh->offset;
+ 		req->size = poh->size;
+ 	}
+-
+ }
+ 
+ void sis_free(unsigned long base)
+@@ -3352,35 +3806,70 @@ void sis_free(unsigned long base)
+ 
+ static void sisfb_pre_setmode(void)
+ {
+-	u8 cr30 = 0, cr31 = 0;
++	u8 cr30 = 0, cr31 = 0, cr33 = 0;
++
++	ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
+ 
+ 	inSISIDXREG(SISCR, 0x31, cr31);
+ 	cr31 &= ~0x60;
++	cr31 |= 0x04;
+ 
+-	switch (ivideo.disp_state & DISPTYPE_DISP2) {
+-	   case DISPTYPE_CRT2:
+-		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+-		cr31 |= SIS_DRIVER_MODE;
+-		break;
+-	   case DISPTYPE_LCD:
+-		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+-		cr31 |= SIS_DRIVER_MODE;
+-		break;
+-	   case DISPTYPE_TV:
+-		if (ivideo.TV_type == TVMODE_HIVISION)
++	cr33 = sisfb_rate_idx & 0x0F;
++
++	SiS_SetEnableDstn(&SiS_Pr, FALSE);
++	SiS_SetEnableFstn(&SiS_Pr, FALSE);
++
++	switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
++	   case CRT2_TV:
++		ivideo.disp_state = DISPTYPE_TV;
++		if (ivideo.vbflags & TV_HIVISION) {
+ 			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
+-		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
++			ivideo.currentvbflags |= (TV_HIVISION | TV_SVIDEO);
++			ivideo.TV_type = TVMODE_HIVISION;
++			ivideo.TV_plug = TVPLUG_SVIDEO;
++		} else if (ivideo.vbflags & TV_SVIDEO) {
+ 			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
+-		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
++			ivideo.currentvbflags |= TV_SVIDEO;
++			ivideo.TV_plug = TVPLUG_SVIDEO;
++		} else if (ivideo.vbflags & TV_AVIDEO) {
+ 			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
+-		else if (ivideo.TV_plug == TVPLUG_SCART)
++			ivideo.currentvbflags |= TV_AVIDEO;
++			ivideo.TV_plug = TVPLUG_COMPOSITE;
++		} else if (ivideo.vbflags & TV_SCART) {
+ 			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
++			ivideo.currentvbflags |= TV_SCART;
++			ivideo.TV_plug = TVPLUG_SCART;
++		}
+ 		cr31 |= SIS_DRIVER_MODE;
+ 
+-	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
+-			cr31 |= 0x01;
+-                else
+-                        cr31 &= ~0x01;
++		if(!(ivideo.vbflags & TV_HIVISION)) {
++	        	if (ivideo.vbflags & TV_PAL) {
++		 		cr31 |= 0x01;
++				ivideo.currentvbflags |= TV_PAL;
++				ivideo.TV_type = TVMODE_PAL;
++                	} else {
++		       		cr31 &= ~0x01;
++				ivideo.currentvbflags |= TV_NTSC;
++				ivideo.TV_type = TVMODE_NTSC;
++			}
++		}
++		break;
++	   case CRT2_LCD:
++		ivideo.disp_state = DISPTYPE_LCD;
++		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
++		cr31 |= SIS_DRIVER_MODE;
++		SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
++	        SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
++		break;
++	   case CRT2_VGA:
++		ivideo.disp_state = DISPTYPE_CRT2;
++		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
++		cr31 |= SIS_DRIVER_MODE;
++		if(sisfb_nocrt2rate) {
++			cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
++		} else {
++			cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
++		}
+ 		break;
+ 	   default:	/* disable CRT2 */
+ 		cr30 = 0x00;
+@@ -3389,8 +3878,14 @@ static void sisfb_pre_setmode(void)
+ 
+ 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
+ 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
++	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
+ 
+-        outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, (sisfb_rate_idx & 0x0F));
++#ifdef CONFIG_FB_SIS_315
++        if(sisvga_engine == SIS_315_VGA) {
++	   /* Clear LCDA and PAL-N/M bits */
++	   andSISIDXREG(SISCR,0x38,~0xc3);
++	}
++#endif
+ 
+ 	if(ivideo.accel) sisfb_syncaccel();
+ 
+@@ -3400,67 +3895,89 @@ static void sisfb_pre_setmode(void)
+ static void sisfb_post_setmode(void)
+ {
+ 	u8 reg;
++	BOOLEAN crt1isoff = FALSE;
++#ifdef CONFIG_FB_SIS_315
++	u8 reg1;
++#endif
++#ifdef CONFIG_FB_SIS_300
+ 	BOOLEAN doit = TRUE;
+-#if 0	/* TW: Wrong: Is not in MMIO space, but in RAM */
+-	/* Backup mode number to MMIO space */
+-	if(ivideo.mmio_vbase) {
+-	  *(volatile u8 *)(((u8*)ivideo.mmio_vbase) + 0x449) = (unsigned char)sisfb_mode_no;
+-	}
+-#endif	
+-
+-	if (ivideo.video_bpp == 8) {
+-		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
+-		if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
+-			doit = FALSE;
+-		}
+-		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
+-		if ( (sishw_ext.Is301BDH) && (ivideo.disp_state & DISPTYPE_LCD) ) {
+-	        	doit = FALSE;
+-	        }
+-	}
+-
++#endif
+ 	/* TW: We can't switch off CRT1 if bridge is in slave mode */
+-	if(ivideo.hasVB != HASVB_NONE) {
+-		inSISIDXREG(SISPART1, 0x00, reg);
++	if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++#ifdef CONFIG_FB_SIS_300
+ 		if(sisvga_engine == SIS_300_VGA) {
++			inSISIDXREG(SISPART1, 0x00, reg);
+ 			if((reg & 0xa0) == 0x20) {
+ 				doit = FALSE;
+ 			}
+ 		}
+-		if(sisvga_engine == SIS_315_VGA) {
+-			if((reg & 0x50) == 0x10) {
+-				doit = FALSE;
+-			}
+-		}
++#endif
+ 	} else sisfb_crt1off = 0;
+ 
+-	inSISIDXREG(SISCR, 0x17, reg);
+-	if((sisfb_crt1off) && (doit))
+-		reg &= ~0x80;
+-	else 	      
+-		reg |= 0x80;
+-	outSISIDXREG(SISCR, 0x17, reg);
++	if(sisvga_engine == SIS_300_VGA) {
+ 
+-        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
++#ifdef CONFIG_FB_SIS_300
++	   if((sisfb_crt1off) && (doit)) {
++	        crt1isoff = TRUE;
++		reg = 0x00;
++	   } else {
++	        crt1isoff = FALSE;
++		reg = 0x80;
++	   }
++	   setSISIDXREG(SISCR, 0x17, 0x7f, reg);
++#endif
++
++	} else {
++
++#ifdef CONFIG_FB_SIS_315
++	   if(sisfb_crt1off) {
++	        crt1isoff = TRUE;
++		reg  = 0x40;
++		reg1 = 0xc0;
++	   } else {
++	        crt1isoff = FALSE;
++		reg  = 0x00;
++		reg1 = 0x00;
+ 
+-	if((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
++	   }
++	   setSISIDXREG(SISCR, 0x63, ~0x40, reg);
++	   setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
++#endif
++
++	}
++
++	if(crt1isoff) {
++	   ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
++	   ivideo.currentvbflags |= VB_SINGLE_MODE;
++	   ivideo.disp_state |= DISPMODE_SINGLE;
++	} else {
++	   ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
++	   ivideo.disp_state |= DISPTYPE_CRT1;
++	   if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
++	  	ivideo.currentvbflags |= VB_MIRROR_MODE;
++		ivideo.disp_state |= DISPMODE_MIRROR;
++	   } else {
++	 	ivideo.currentvbflags |= VB_SINGLE_MODE;
++		ivideo.disp_state |= DISPMODE_SINGLE;
++	   }
++	}
+ 
+-	   inSISIDXREG(SISPART4, 0x01, reg);
++        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+ 
+-	   if(reg < 0xB0) {        	/* Set filter for SiS301 */
++	if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) {  /* Set filter for SiS301 */
+ 
+ 		switch (ivideo.video_width) {
+ 		   case 320:
+-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
++			filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
+ 			break;
+ 		   case 640:
+-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
++			filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
+ 			break;
+ 		   case 720:
+-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
++			filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
+ 			break;
+ 		   case 800:
+-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
++			filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
+ 			break;
+ 		   default:
+ 			filter = -1;
+@@ -3469,15 +3986,15 @@ static void sisfb_post_setmode(void)
+ 
+ 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+ 
+-		if(ivideo.TV_type == TVMODE_NTSC) {
++		if(ivideo.vbflags & TV_NTSC) {
+ 
+ 		        andSISIDXREG(SISPART2, 0x3a, 0x1f);
+ 
+-			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
++			if (ivideo.vbflags & TV_SVIDEO) {
+ 
+ 			        andSISIDXREG(SISPART2, 0x30, 0xdf);
+ 
+-			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
++			} else if (ivideo.vbflags & TV_AVIDEO) {
+ 
+ 			        orSISIDXREG(SISPART2, 0x30, 0x20);
+ 
+@@ -3503,15 +4020,15 @@ static void sisfb_post_setmode(void)
+ 				}
+ 			}
+ 
+-		} else if(ivideo.TV_type == TVMODE_PAL) {
++		} else if(ivideo.vbflags & TV_PAL) {
+ 
+ 			andSISIDXREG(SISPART2, 0x3A, 0x1F);
+ 
+-			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
++			if (ivideo.vbflags & TV_SVIDEO) {
+ 
+ 			        andSISIDXREG(SISPART2, 0x30, 0xDF);
+ 
+-			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
++			} else if (ivideo.vbflags & TV_AVIDEO) {
+ 
+ 			        orSISIDXREG(SISPART2, 0x30, 0x20);
+ 
+@@ -3539,7 +4056,7 @@ static void sisfb_post_setmode(void)
+ 		}
+ 
+ 		if ((filter >= 0) && (filter <=7)) {
+-			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 
++			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
+ 				sis_TV_filter[filter_tb].filter[filter][0],
+ 				sis_TV_filter[filter_tb].filter[filter][1],
+ 				sis_TV_filter[filter_tb].filter[filter][2],
+@@ -3550,8 +4067,6 @@ static void sisfb_post_setmode(void)
+ 			outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
+ 			outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
+ 		}
+-
+-	     }
+ 	  
+ 	}
+ 
+@@ -3567,8 +4082,10 @@ int sisfb_setup(char *options)
+ #endif	
+ 
+ 	ivideo.refresh_rate = 0;
++	SiS_Pr.SiS_CustomT = CUT_NONE;
++	SiS_Pr.UsePanelScaler = -1;
+ 
+-        printk(KERN_INFO "sisfb: Options %s\n", options);
++        printk(KERN_DEBUG "sisfb: Options %s\n", options);
+ 
+ 	if (!options || !*options)
+ 		return 0;
+@@ -3577,72 +4094,75 @@ int sisfb_setup(char *options)
+ 
+ 		if (!*this_opt)	continue;
+ 
+-		if (!strncmp(this_opt, "mode:", 5)) {
+-			sisfb_search_mode(this_opt + 5);
+-		} else if (!strncmp(this_opt, "vesa:", 5)) {
+-			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)			
+-		} else if (!strcmp(this_opt, "inverse")) {
++		if (!strnicmp(this_opt, "mode:", 5)) {
++			sisfb_search_mode(this_opt + 5, FALSE);
++		} else if (!strnicmp(this_opt, "vesa:", 5)) {
++			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++		} else if (!strnicmp(this_opt, "inverse", 7)) {
+ 			sisfb_inverse = 1;
+ 			/* fb_invert_cmaps(); */
+-		} else if (!strncmp(this_opt, "font:", 5)) {
++		} else if (!strnicmp(this_opt, "font:", 5)) {
+ 			strcpy(sis_fb_info.fontname, this_opt + 5);
+-#endif			
+-		} else if (!strncmp(this_opt, "mode:", 5)) {
+-			sisfb_search_mode(this_opt + 5);
+-		} else if (!strncmp(this_opt, "vesa:", 5)) {
+-			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+-		} else if (!strncmp(this_opt, "vrate:", 6)) {
++#endif
++		} else if (!strnicmp(this_opt, "vrate:", 6)) {
+ 			ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
+-		} else if (!strncmp(this_opt, "rate:", 5)) {
++			sisfb_parm_rate = ivideo.refresh_rate;
++		} else if (!strnicmp(this_opt, "rate:", 5)) {
+ 			ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
+-		} else if (!strncmp(this_opt, "off", 3)) {
++			sisfb_parm_rate = ivideo.refresh_rate;
++		} else if (!strnicmp(this_opt, "off", 3)) {
+ 			sisfb_off = 1;
+-		} else if (!strncmp(this_opt, "crt1off", 7)) {
++		} else if (!strnicmp(this_opt, "crt1off", 7)) {
+ 			sisfb_crt1off = 1;
+-		} else if (!strncmp(this_opt, "filter:", 7)) {
++		} else if (!strnicmp(this_opt, "filter:", 7)) {
+ 			filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+-		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
++		} else if (!strnicmp(this_opt, "forcecrt2type:", 14)) {
+ 			sisfb_search_crt2type(this_opt + 14);
+-		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
++		} else if (!strnicmp(this_opt, "forcecrt1:", 10)) {
+ 			sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
+-                } else if (!strncmp(this_opt, "tvmode:",7)) {
++                } else if (!strnicmp(this_opt, "tvmode:",7)) {
+ 		        sisfb_search_tvstd(this_opt + 7);
+-                } else if (!strncmp(this_opt, "tvstandard:",11)) {
++                } else if (!strnicmp(this_opt, "tvstandard:",11)) {
+ 			sisfb_search_tvstd(this_opt + 7);
+-                } else if (!strncmp(this_opt, "mem:",4)) {
++                } else if (!strnicmp(this_opt, "mem:",4)) {
+ 		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
+-                } else if (!strncmp(this_opt, "dstn", 4)) {
+-			enable_dstn = 1;
+-			/* TW: DSTN overrules forcecrt2type */
+-			sisfb_crt2type = DISPTYPE_LCD;
+-		} else if (!strncmp(this_opt, "queuemode:", 10)) {
++		} else if (!strnicmp(this_opt, "queuemode:", 10)) {
+ 			sisfb_search_queuemode(this_opt + 10);
+-		} else if (!strncmp(this_opt, "pdc:", 4)) {
++		} else if (!strnicmp(this_opt, "pdc:", 4)) {
+ 		        sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
+ 		        if(sisfb_pdc & ~0x3c) {
+ 			   printk(KERN_INFO "sisfb: Illegal pdc parameter\n");
+ 			   sisfb_pdc = 0;
+ 		        }
+-		} else if (!strncmp(this_opt, "noaccel", 7)) {
++		} else if (!strnicmp(this_opt, "noaccel", 7)) {
+ 			sisfb_accel = 0;
+-		} else if (!strncmp(this_opt, "noypan", 6)) {
++		} else if (!strnicmp(this_opt, "noypan", 6)) {
+ 		        sisfb_ypan = 0;
+-		} else if (!strncmp(this_opt, "userom:", 7)) {
++		} else if (!strnicmp(this_opt, "userom:", 7)) {
+ 			sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
+-		} else if (!strncmp(this_opt, "useoem:", 7)) {
++		} else if (!strnicmp(this_opt, "useoem:", 7)) {
+ 			sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
++		} else if (!strnicmp(this_opt, "nocrt2rate", 10)) {
++			sisfb_nocrt2rate = 1;
++	 	} else if (!strnicmp(this_opt, "scalelcd:", 9)) {
++		        unsigned long temp = 2;
++		        temp = simple_strtoul(this_opt + 9, NULL, 0);
++		        if((temp == 0) || (temp == 1)) {
++			   SiS_Pr.UsePanelScaler = temp ^ 1;
++		        }
++		} else if (!strnicmp(this_opt, "specialtiming:", 14)) {
++			sisfb_search_specialtiming(this_opt + 14);
++		} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
++			sisfb_search_mode(this_opt, TRUE);
+ 		} else {
+ 			printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
+ 		}
+ 
+ 		/* TW: Acceleration only with MMIO mode */
+ 		if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+-			sisfb_ypan = 0;
+ 			sisfb_accel = 0;
+ 		}
+-		/* TW: Panning only with acceleration */
+-		if(sisfb_accel == 0) sisfb_ypan = 0;
+ 
+ 	}
+ 	return 0;
+@@ -3661,14 +4181,14 @@ static char *sis_find_rom(void)
+         char *sis_sig_300[4] = {
+           "300", "540", "630", "730"
+         };
+-        char *sis_sig_310[7] = {
+-          "315", "315", "315", "5315", "6325", "6325", "Xabre"
++        char *sis_sig_310[9] = {
++          "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330", "6330"
+         };
+ 	ushort sis_nums_300[4] = {
+ 	  SIS_300, SIS_540, SIS_630, SIS_730
+ 	};
+-	unsigned short sis_nums_310[7] = {
+-	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
++	unsigned short sis_nums_310[9] = {
++	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660, SIS_760
+ 	};
+ 
+         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+@@ -3705,7 +4225,7 @@ static char *sis_find_rom(void)
+                     }
+                 }
+ 		if(stage != 4) {
+-                   for(i = 0;(i < 7) && (stage != 4); i++) {
++                   for(i = 0;(i < 9) && (stage != 4); i++) {
+                       if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
+ 		          if(sis_nums_310[i] == ivideo.chip) {
+                              stage = 4;
+@@ -3735,7 +4255,7 @@ int __init sisfb_init(void)
+ 	int pdev_valid = 0;
+ 	u32 reg32;
+ 	u16 reg16;
+-	u8  reg, reg1;
++	u8  reg;
+ 
+ 	/* outb(0x77, 0x80); */  /* What is this? */
+ 
+@@ -3751,18 +4271,24 @@ int __init sisfb_init(void)
+ 	if (sisfb_off)
+ 		return -ENXIO;
+ 
+-	if (enable_dstn)
+-		SiS_SetEnableDstn(&SiS_Pr);
+-		
+ 	sisfb_registered = 0;
++	sisfb_thismonitor.datavalid = FALSE;
+ 
+ 	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++        memset(&sisfb_lastrates[0], 0, 128);
++#endif
+ 	
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+ 	memset(&sis_disp, 0, sizeof(sis_disp));
+ #endif	
+ 
+-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
++	pci_for_each_dev(pdev) {
++#else
++	while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
++#endif
+ 		for (b = sisdev_list; b->vendor; b++) {
+ 			if ((b->vendor == pdev->vendor)
+ 			    && (b->device == pdev->device)) {
+@@ -3804,18 +4330,17 @@ int __init sisfb_init(void)
+ 		break;
+ 	   case PCI_DEVICE_ID_SI_630_VGA:
+ 		{
++			ivideo.chip = SIS_630;
+ 			sisfb_set_reg4(0xCF8, 0x80000000);
+ 			reg32 = sisfb_get_reg3(0xCFC);
+ 			if(reg32 == 0x07301039) {
+ 				ivideo.chip = SIS_730;
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+ 				strcpy(sis_fb_info.modename, "SIS 730");
+ #else
+ 				strcpy(myid, "SIS 730");
+-#endif				
+-			} else
+-				ivideo.chip = SIS_630;
+-
++#endif
++			}
+ 			sisvga_engine = SIS_300_VGA;
+ 			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
+ 			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
+@@ -3860,11 +4385,11 @@ int __init sisfb_init(void)
+ 			reg32 = sisfb_get_reg3(0xCFC);
+ 			if(reg32 == 0x07401039) {
+ 				ivideo.chip = SIS_740;
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+ 				strcpy(sis_fb_info.modename, "SIS 740");
+ #else
+-				strcpy(myid, "SIS 740");				
+-#endif				
++				strcpy(myid, "SIS 740");
++#endif
+ 			}
+ 			sisvga_engine = SIS_315_VGA;
+ 			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+@@ -3877,6 +4402,24 @@ int __init sisfb_init(void)
+ 		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+ 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+ 		break;
++	   case PCI_DEVICE_ID_SI_660_VGA:
++	   	{
++			ivideo.chip = SIS_660;
++			sisfb_set_reg4(0xCF8, 0x80000000);
++			reg32 = sisfb_get_reg3(0xCFC);
++			if(reg32 == 0x07601039) {
++				ivideo.chip = SIS_760;
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
++				strcpy(sis_fb_info.modename, "SIS 760");
++#else
++				strcpy(myid, "SIS 760");
++#endif
++			}
++			sisvga_engine = SIS_315_VGA;
++			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
++			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
++			break;
++		}
+ #endif
+            default:
+ 	        return -ENODEV;
+@@ -3903,29 +4446,31 @@ int __init sisfb_init(void)
+         SiS_Pr.SiS_CHOverScan = -1;
+         SiS_Pr.SiS_ChSW = FALSE;
+ 	SiS_Pr.SiS_UseLCDA = FALSE;
+-	SiS_Pr.UsePanelScaler = -1;
+ 	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
+ 
+ #ifdef CONFIG_FB_SIS_300
+-	/* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
++	/* TW: Find PCI systems for Chrontel/GPIO communication setup */
+ 	if(ivideo.chip == SIS_630) {
+-	  int i=0;
+-          do {
+-	    if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
+-	       mychswtable[i].subsysCard   == ivideo.subsysdevice) {
+-		SiS_Pr.SiS_ChSW = TRUE;
+-            }
+-            i++;
+-          } while(mychswtable[i].subsysVendor != 0);
++	   int i=0;
++           do {
++	      if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
++	         mychswtable[i].subsysCard   == ivideo.subsysdevice) {
++		 SiS_Pr.SiS_ChSW = TRUE;
++		 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
++		        mychswtable[i].vendorName, mychswtable[i].cardName);
++		 break;
++              }
++              i++;
++           } while(mychswtable[i].subsysVendor != 0);
+ 	}
+ #endif
+ 
+         outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
+-#ifdef MODULE	
++#ifdef MODULE
+ 	inSISIDXREG(SISCR,0x34,reg);
+-	if(reg & 0x80) {
++	if((reg & 0x80) && (reg != 0xff)) {
+ 	   if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
+ 	      printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
+ 	      return -EBUSY;
+@@ -3938,7 +4483,7 @@ int __init sisfb_init(void)
+ 
+ #ifdef CONFIG_FB_SIS_300
+ 	if (sisvga_engine == SIS_300_VGA) {
+-	        outSISIDXREG(SISSR, 0x28, 0x37);
++	        outSISIDXREG(SISSR, 0x28, 0x37);	/* Reset memory clock */
+ 
+                 outSISIDXREG(SISSR, 0x29, 0x61);
+ 
+@@ -3946,7 +4491,9 @@ int __init sisfb_init(void)
+ 	}
+ #endif
+ #ifdef CONFIG_FB_SIS_315
+-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
++	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 ||
++	    ivideo.chip == SIS_740 || ivideo.chip == SIS_660 ||
++	    ivideo.chip == SIS_760) {
+ 	        outSISIDXREG(SISSR, 0x28, 0x5a);
+ 
+                 outSISIDXREG(SISSR, 0x29, 0x64);
+@@ -3967,6 +4514,8 @@ int __init sisfb_init(void)
+ 		   case SIS_550:
+ 		   case SIS_650:
+ 		   case SIS_740:
++		   case SIS_660:
++		   case SIS_760:
+ 			sishw_ext.bIntegratedMMEnabled = TRUE;
+ 			break;
+ 		   default:
+@@ -4006,13 +4555,56 @@ int __init sisfb_init(void)
+ 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
+ 	strcpy(sishw_ext.szVBIOSVer, "0.84");
+ 
+-	/* TW: Mode numbers for 1280x960 are different for 300 and 310/325 series */
++        /* Find systems for special custom timing */
++	if((sishw_ext.UseROM) && (SiS_Pr.SiS_CustomT == CUT_NONE)) {
++	   int i=0,j;
++	   unsigned char *biosver = sishw_ext.pjVirtualRomBase + 0x06;
++           unsigned char *biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
++	   BOOLEAN footprint;
++	   unsigned long chksum = 0;
++
++           for(i=0; i<32768; i++) chksum += sishw_ext.pjVirtualRomBase[i];
++
++	   i=0;
++           do {
++	      if( (mycustomttable[i].chipID == ivideo.chip) &&
++	          ((!strlen(mycustomttable[i].biosversion)) ||
++		   (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion)))) &&
++	          ((!strlen(mycustomttable[i].biosdate)) ||
++		   (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate)))) &&
++		  ((!mycustomttable[i].bioschksum) ||
++	           (mycustomttable[i].bioschksum == chksum))	&&
++		  (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
++		  (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
++		 footprint = TRUE;
++	         for(j=0; j<5; j++) {
++	           if(mycustomttable[i].biosFootprintAddr[j]) {
++	              if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
++		      		mycustomttable[i].biosFootprintData[j])
++		         footprint = FALSE;
++		   }
++	         }
++	         if(footprint) {
++	 	    SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
++		    printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
++		        mycustomttable[i].vendorName,
++			mycustomttable[i].cardName);
++	            break;
++                 }
++	      }
++              i++;
++           } while(mycustomttable[i].chipID);
++	}
++
++#ifdef CONFIG_FB_SIS_300
++	/* Mode numbers for 1280x768 are different for 300 and 315 series */
+ 	if(sisvga_engine == SIS_300_VGA) {
+-		sisbios_mode[MODEINDEX_1280x960].mode_no = 0x6e;
+-		sisbios_mode[MODEINDEX_1280x960+1].mode_no = 0x6f;
+-		sisbios_mode[MODEINDEX_1280x960+2].mode_no = 0x7b;
+-		sisbios_mode[MODEINDEX_1280x960+3].mode_no = 0x7b;
++		sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
++		sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
++		sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
++		sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
+ 	}
++#endif
+ 
+ 	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
+ 	if (sishw_ext.pSR == NULL) {
+@@ -4168,120 +4760,53 @@ int __init sisfb_init(void)
+ 
+ 	ivideo.mtrr = (unsigned int) 0;
+ 
+-	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+-
+-#ifdef CONFIG_FB_SIS_300
+-		if (sisvga_engine == SIS_300_VGA) {
+-			sisfb_get_VB_type_300();
+-		}
+-#endif
++	ivideo.vbflags = 0;
+ 
+-#ifdef CONFIG_FB_SIS_315
+-		if (sisvga_engine == SIS_315_VGA) {
+-			sisfb_get_VB_type_315();
+-		}
+-#endif
++	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+ 
+ 		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+ 		sishw_ext.Is301BDH = FALSE;
+ 		sishw_ext.usExternalChip = 0;
+ 
+-		switch (ivideo.hasVB) {
++		sisfb_get_VB_type();
+ 
+-		case HASVB_301:
+-		        inSISIDXREG(SISPART4, 0x01, reg);
+-			if (reg >= 0xE0) {
+-				sishw_ext.ujVBChipID = VB_CHIP_302LV;
+-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+-	  		} else if (reg >= 0xD0) {
+-				sishw_ext.ujVBChipID = VB_CHIP_301LV;
+-				printk(KERN_INFO "sisfb: SiS301LV bridge detected (revision 0x%02x)\n",reg);
+-	  		} else if (reg >= 0xB0) {
+-				sishw_ext.ujVBChipID = VB_CHIP_301B;
+-				inSISIDXREG(SISPART4,0x23,reg1);
+-				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
+-				printk(KERN_INFO "sisfb: SiS301B%s bridge detected (revision 0x%02x)\n",
+-					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
+-			} else {
+-				sishw_ext.ujVBChipID = VB_CHIP_301;
+-				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
+-			}
+-			break;
+-		case HASVB_302:
+-		        inSISIDXREG(SISPART4, 0x01, reg);
+-			if (reg >= 0xE0) {
+-				sishw_ext.ujVBChipID = VB_CHIP_302LV;
+-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+-	  		} else if (reg >= 0xD0) {
+-				sishw_ext.ujVBChipID = VB_CHIP_301LV;
+-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+-	  		} else if (reg >= 0xB0) {
+-				inSISIDXREG(SISPART4,0x23,reg1);
+-				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
+-			        sishw_ext.ujVBChipID = VB_CHIP_302B;
+-				printk(KERN_INFO "sisfb: SiS302B%s bridge detected (revision 0x%02x)\n",
+-					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
+-			} else {
+-			        sishw_ext.ujVBChipID = VB_CHIP_302;
+-				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
+-			}
+-			break;
+-		case HASVB_LVDS:
+-			sishw_ext.usExternalChip = 0x1;
+-			printk(KERN_INFO "sisfb: LVDS transmitter detected\n");
+-			break;
+-		case HASVB_TRUMPION:
+-			sishw_ext.usExternalChip = 0x2;
+-			printk(KERN_INFO "sisfb: Trumpion Zurac LVDS scaler detected\n");
+-			break;
+-		case HASVB_CHRONTEL:
+-			sishw_ext.usExternalChip = 0x4;
+-			printk(KERN_INFO "sisfb: Chrontel TV encoder detected\n");
+-			break;
+-		case HASVB_LVDS_CHRONTEL:
+-			sishw_ext.usExternalChip = 0x5;
+-			printk(KERN_INFO "sisfb: LVDS transmitter and Chrontel TV encoder detected\n");
+-			break;
+-		default:
+-			printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
+-			break;
++		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++			sisfb_detect_VB_connect();
+ 		}
+ 
+-		if (ivideo.hasVB != HASVB_NONE) {
+-#ifdef CONFIG_FB_SIS_300
+-		      if (sisvga_engine == SIS_300_VGA) {
+-				sisfb_detect_VB_connect_300();
+-                      }
+-#endif
+-#ifdef CONFIG_FB_SIS_315
+-		      if (sisvga_engine == SIS_315_VGA) {
+-				sisfb_detect_VB_connect_315();
+-                      }
+-#endif
+-		}
++		ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
+ 
+-		if (ivideo.disp_state & DISPTYPE_DISP2) {
+-			if (sisfb_crt1off)
+-				ivideo.disp_state |= DISPMODE_SINGLE;
+-			else
+-				ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
+-		} else {
+-			ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
++		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
++		   if(sisfb_crt2type != -1) {
++		      if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
++		         ivideo.currentvbflags |= CRT2_LCD;
++		      } else if(sisfb_crt2type != CRT2_LCD) {
++		         ivideo.currentvbflags |= sisfb_crt2type;
++		      }
++		   } else {
++		      /* Chrontel 700x TV detection often unreliable, therefore use a
++		       * different default order on such machines
++		       */
++		      if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
++		         if(ivideo.vbflags & CRT2_LCD)      ivideo.currentvbflags |= CRT2_LCD;
++		         else if(ivideo.vbflags & CRT2_TV)  ivideo.currentvbflags |= CRT2_TV;
++		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
++		      } else {
++		         if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
++		         else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
++		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
++		      }
++		   }
+ 		}
+ 
+-		if (ivideo.disp_state & DISPTYPE_LCD) {
+-		    if (!enable_dstn) {
+-		        inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+-			reg &= 0x0f;
+-			if (sisvga_engine == SIS_300_VGA) {
+-			    sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+-			} else {
+-			    sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+-			}
+-		    } else {
+-		        /* TW: FSTN/DSTN */
+-			sishw_ext.ulCRT2LCDType = LCD_320x480;
+-		    }
++		if(ivideo.vbflags & CRT2_LCD) {
++		   inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
++		   reg &= 0x0f;
++		   if(sisvga_engine == SIS_300_VGA) {
++		      sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
++		   } else {
++		      sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
++		   }
+ 		}
+ 		
+ 		sisfb_detectedpdc = 0;
+@@ -4289,9 +4814,7 @@ int __init sisfb_init(void)
+ #ifdef CONFIG_FB_SIS_300
+                 /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
+ 		if(sisvga_engine == SIS_300_VGA) {
+-	          if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
+-		     (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
+-		     (sishw_ext.Is301BDH)) {		     /* 301B-DH */
++	          if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
+ 		       int tmp;
+ 		       inSISIDXREG(SISCR,0x30,tmp);
+ 		       if(tmp & 0x20) {
+@@ -4320,54 +4843,57 @@ int __init sisfb_init(void)
+ #ifdef CONFIG_FB_SIS_315
+                 /* TW: Try to find about LCDA */
+ 		if(sisvga_engine == SIS_315_VGA) {
+-	          if((sishw_ext.ujVBChipID == VB_CHIP_302B) ||
+-		     (sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+-		     (sishw_ext.ujVBChipID == VB_CHIP_302LV)) {
+-		       int tmp;
+-		       inSISIDXREG(SISCR,0x34,tmp);
+-		       if(tmp <= 0x13) {	
+-		          /* Currently on LCDA? (Some BIOSes leave CR38) */
+-		          inSISIDXREG(SISCR,0x38,tmp);
+-			  if((tmp & 0x03) == 0x03) {
+-			     SiS_Pr.SiS_UseLCDA = TRUE;
+-			  } else {
+-			     /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
+-			     inSISIDXREG(SISCR,0x35,tmp);
+-			     if(tmp & 0x01) {
+-			        SiS_Pr.SiS_UseLCDA = TRUE;
+-			     } else {
+-			        /* Currently on LCD? If so, we can find out 
+-				   by peeking the mode register 
+-				 */
+-			        inSISIDXREG(SISCR,0x30,tmp);
+-			        if(tmp & 0x20) {
+-			           inSISIDXREG(SISPART1,0x13,tmp);
+-				   if(tmp & 0x04) {
+-				      SiS_Pr.SiS_UseLCDA = TRUE;
+-				   }
+-			        }
+-			     }
+-			  }
+-		       } 
+-		       if(SiS_Pr.SiS_UseLCDA) {
+-		          sisfb_detectedlcda = 0x03;
+-		          printk(KERN_INFO
+-			         "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+-		       }
++		   if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
++		      int tmp;
++		      inSISIDXREG(SISCR,0x34,tmp);
++		      if((tmp <= 0x13) || (tmp == 0xff)) {
++		         /* Currently on LCDA? (Some BIOSes leave CR38) */
++		         inSISIDXREG(SISCR,0x38,tmp);
++			 if((tmp & 0x03) == 0x03)  SiS_Pr.SiS_UseLCDA = TRUE;
++			 else {
++			    /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
++			    inSISIDXREG(SISCR,0x35,tmp);
++			    if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
++			    else {
++			       /* Currently on LCD? If so, we can find out
++			        * by peeking the mode register
++				*/
++			       inSISIDXREG(SISCR,0x30,tmp);
++			       if(tmp & 0x20) {
++			          inSISIDXREG(SISPART1,0x13,tmp);
++				  if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
++			       }
++			    }
++			 }
++		      }
++		      if(SiS_Pr.SiS_UseLCDA) {
++		         sisfb_detectedlcda = 0x03;
++		         printk(KERN_DEBUG
++			        "sisfb: Bridge uses LCDA for low resolution and text modes\n");
++		      }
+ 	          }
+ 		}
+ #endif
+ #endif
+ 
++		if (!sisfb_crt1off) {
++		   	sisfb_handle_ddc(&sisfb_thismonitor, 0);
++		} else {
++		   	if ((ivideo.vbflags & (VB_301|VB_301B|VB_302B)) &&
++		      	    (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
++		      		sisfb_handle_ddc(&sisfb_thismonitor, 1);
++		   	}
++		}
++
+ 		if (sisfb_mode_idx >= 0)
+-			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
++			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+ 
+ 		if (sisfb_mode_idx < 0) {
+-			switch (ivideo.disp_state & DISPTYPE_DISP2) {
+-			   case DISPTYPE_LCD:
++			switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
++			   case CRT2_LCD:
+ 				sisfb_mode_idx = DEFAULT_LCDMODE;
+ 				break;
+-			   case DISPTYPE_TV:
++			   case CRT2_TV:
+ 				sisfb_mode_idx = DEFAULT_TVMODE;
+ 				break;
+ 			   default:
+@@ -4379,39 +4905,27 @@ int __init sisfb_init(void)
+ 		sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+ 
+ 		if (ivideo.refresh_rate != 0)
+-			sisfb_search_refresh_rate(ivideo.refresh_rate);
++			sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
+ 
+ 		if (sisfb_rate_idx == 0) {
+ 			sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
+ 			ivideo.refresh_rate = 60;
+ 		}
+ 
++		if (sisfb_thismonitor.datavalid) {
++			if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
++			                      sisfb_rate_idx, ivideo.refresh_rate)) {
++				printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
++			}
++		}
++
+ 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
+ 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
+ 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
+ 		ivideo.org_x = ivideo.org_y = 0;
+ 		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+-		switch(ivideo.video_bpp) {
+-        	case 8:
+-            		ivideo.DstColor = 0x0000;
+-	    		ivideo.SiS310_AccelDepth = 0x00000000;
+-			ivideo.video_cmap_len = 256;
+-            		break;
+-        	case 16:
+-            		ivideo.DstColor = 0x8000;
+-            		ivideo.SiS310_AccelDepth = 0x00010000;
+-			ivideo.video_cmap_len = 16;
+-            		break;
+-        	case 32:
+-            		ivideo.DstColor = 0xC000;
+-	    		ivideo.SiS310_AccelDepth = 0x00020000;
+-			ivideo.video_cmap_len = 16;
+-            		break;
+-		default:
+-			ivideo.video_cmap_len = 16;
+-		        printk(KERN_INFO "sisfb: Unsupported depth %d", ivideo.video_bpp);
+-			break;
+-    		}
++
++		sisfb_set_vparms();
+ 		
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+ 
+@@ -4424,27 +4938,49 @@ int __init sisfb_init(void)
+ 		sisfb_pre_setmode();
+ 
+ 		if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+-			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed, using default mode\n", 
++			printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
+ 				sisfb_mode_no);
+-			return -1;
++			vfree(sishw_ext.pSR);
++			vfree(sishw_ext.pCR);
++			release_mem_region(ivideo.video_base, ivideo.video_size);
++			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
++			return -EINVAL;
+ 		}
+ 
+ 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ 
+ 		sisfb_post_setmode();
+ 
++		ivideo.accel = 0;
++		if(sisfb_accel) {
++		   ivideo.accel = -1;
++		   default_var.accel_flags |= FB_ACCELF_TEXT;
++		   sisfb_initaccel();
++		}
++
+ 		sisfb_crtc_to_var(&default_var);
+ 		
++		sis_fb_info.node = -1;
++		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
++		sis_fb_info.blank = &sisfb_blank;
++		sis_fb_info.fbops = &sisfb_ops;
++		sis_fb_info.switch_con = &sisfb_switch;
++		sis_fb_info.updatevar = &sisfb_update_var;
++		sis_fb_info.changevar = NULL;
++		sis_fb_info.disp = &sis_disp;
++
++		sisfb_set_disp(-1, &default_var, &sis_fb_info);
++
+ #else		/* --------- For 2.5: Setup a somewhat sane default var ------------ */
+ 
+ 		printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
+ 	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
+ 			ivideo.refresh_rate);
+-			
++
+ 		default_var.xres = default_var.xres_virtual = ivideo.video_width;
+ 		default_var.yres = default_var.yres_virtual = ivideo.video_height;
+ 		default_var.bits_per_pixel = ivideo.video_bpp;
+-		
++
+ 		sisfb_bpp_to_var(&default_var);
+ 		
+ 		default_var.pixclock = (u32) (1E12 /
+@@ -4457,28 +4993,10 @@ int __init sisfb_init(void)
+ 			 &default_var.upper_margin, &default_var.lower_margin,
+ 			 &default_var.hsync_len, &default_var.vsync_len,
+ 			 &default_var.sync, &default_var.vmode)) {
+-			 
+-		   if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+-		      default_var.yres <<= 1;
+-		      default_var.yres_virtual <<= 1;
+-		   } else if((default_var.vmode	& FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+-		      default_var.pixclock >>= 1;
+-		      default_var.yres >>= 1;
+-		      default_var.yres_virtual >>= 1;
+-		   }
+-		   
++			if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
++				default_var.pixclock <<= 1;
++	   		}
+ 	        }
+-#ifdef SISFB_PAN
+-		if(sisfb_ypan) {
+-	    		default_var.yres_virtual = 
+-				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
+-	    		if(default_var.yres_virtual <= default_var.yres) {
+-	        		default_var.yres_virtual = default_var.yres;
+-	    		}
+-		} 
+-#endif
+-		
+-#endif
+ 
+ 		ivideo.accel = 0;
+ 		if(sisfb_accel) {
+@@ -4487,20 +5005,14 @@ int __init sisfb_init(void)
+ 		   sisfb_initaccel();
+ 		}
+ 
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		/* ---- 2.4 series init ---- */
+-		sis_fb_info.node = -1;
+-		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+-		sis_fb_info.blank = &sisfb_blank;
+-		sis_fb_info.fbops = &sisfb_ops;
+-		sis_fb_info.switch_con = &sisfb_switch;
+-		sis_fb_info.updatevar = &sisfb_update_var;
+-		sis_fb_info.changevar = NULL;
+-		sis_fb_info.disp = &sis_disp;
+-			
+-		sisfb_set_disp(-1, &default_var, &sis_fb_info);
+-#endif
++		if(sisfb_ypan) {
++	    		default_var.yres_virtual =
++				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
++	    		if(default_var.yres_virtual <= default_var.yres) {
++	        		default_var.yres_virtual = default_var.yres;
++	    		}
++		}
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		/* ---- 2.5 series init ---- */
+ 		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+ 		sis_fb_info.var = default_var;
+ 		sis_fb_info.fix = sisfb_fix;
+@@ -4513,6 +5025,8 @@ int __init sisfb_init(void)
+ 		fb_alloc_cmap(&sis_fb_info.cmap, 256 , 0);
+ #endif
+ 
++		printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
++
+ #ifdef CONFIG_MTRR
+ 		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
+ 				(unsigned int) ivideo.video_size,
+@@ -4520,20 +5034,28 @@ int __init sisfb_init(void)
+ 		if(ivideo.mtrr) {
+ 			printk(KERN_INFO "sisfb: Added MTRRs\n");
+ 		}
++
+ #endif
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 		vc_resize_con(1, 1, 0);
+ #endif
+ 
+-		TWDEBUG("Before calling register_framebuffer");
+-		
+-		if(register_framebuffer(&sis_fb_info) < 0)
++		if(register_framebuffer(&sis_fb_info) < 0) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++			vfree(sishw_ext.pSR);
++			vfree(sishw_ext.pCR);
++			release_mem_region(ivideo.video_base, ivideo.video_size);
++			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
++#endif
++			printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
+ 			return -EINVAL;
+-			
++		}
++
+ 		sisfb_registered = 1;			
+ 
+ 		printk(KERN_INFO "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
++		printk(KERN_INFO "sisfb: Installed SISFB_GET_VBRSTATUS ioctl (%x)\n", SISFB_GET_VBRSTATUS);
+ 		
+ 		printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
+ 		     sisfb_accel ? "enabled" : "disabled",
+@@ -4547,9 +5069,11 @@ int __init sisfb_init(void)
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
+-	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);			     
++	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+ #endif
+ 
++		printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer. All rights reserved.\n");
++
+ 	}	/* TW: if mode = "none" */
+ 	return 0;
+ }
+@@ -4562,7 +5086,6 @@ static int          vesa = -1;
+ static unsigned int rate = 0;
+ static unsigned int crt1off = 1;
+ static unsigned int mem = 0;
+-static unsigned int dstn = 0;
+ static char         *forcecrt2type = NULL;
+ static int          forcecrt1 = -1;
+ static char         *queuemode = NULL;
+@@ -4575,25 +5098,33 @@ static int          inverse = 0;
+ static int          userom = 1;
+ static int          useoem = -1;
+ static char         *tvstandard = NULL;
++static int	    nocrt2rate = 0;
++static int          scalelcd = -1;
++static char	    *specialtiming = NULL;
+ 
+-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
++MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330/660/760 framebuffer driver");
+ MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("SiS; Thomas Winischhofer <thomas@winischhofer.net>; Various others");
++MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode,
+        "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+-         "800x600x16 (default: none if sisfb is a module; this leaves the\n"
+-	 "console untouched and the driver will only do the video memory\n"
+-	 "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
++         "1024x768x16. Other formats supported include XxY-Depth and\n"
++	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
++	 "number, it will be interpreted as a VESA mode number. (default: none if\n"
++	 "sisfb is a module; this leaves the console untouched and the driver will\n"
++	 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
++	 "is in the kernel)");
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
+ MODULE_PARM(mode, "s");
+ MODULE_PARM_DESC(mode,
+-       "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
+-         "eg. 1024x768x16 (default: 800x600x8)");
+-#endif	 
++       "\nSelects the desired default display mode in the format XxYxDepth,\n"
++         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
++	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
++	 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
++#endif
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MODULE_PARM(vesa, "i");
+@@ -4603,17 +5134,18 @@ MODULE_PARM_DESC(vesa,
+ 	 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
+ 	 "0x0103 if sisfb is in the kernel)");
+ #endif
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ MODULE_PARM(vesa, "i");
+ MODULE_PARM_DESC(vesa,
+        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+          "0x117 (default: 0x0103)");
+-#endif	 
++#endif
+ 
+ MODULE_PARM(rate, "i");
+ MODULE_PARM_DESC(rate,
+ 	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
+-	"(default: 60)");
++	  "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
++	  "will be ignored (default: 60)");
+ 
+ MODULE_PARM(crt1off,   "i");
+ MODULE_PARM_DESC(crt1off,
+@@ -4624,14 +5156,9 @@ MODULE_PARM_DESC(filter,
+ 	"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+ 	  "(Possible values 0-7, default: [no filter])");
+ 
+-MODULE_PARM(dstn,   "i");
+-MODULE_PARM_DESC(dstn,
+-	"\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
+-	  "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
+-
+ MODULE_PARM(queuemode,   "s");
+ MODULE_PARM_DESC(queuemode,
+-	"\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
++	"\nSelects the queue mode on 315/550/650/740/330/660. Possible choices are AGP, VRAM,\n"
+   	  "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
+ 	  "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
+ 	  "require a totally different way of programming the engines. If any mode than\n"
+@@ -4642,11 +5169,12 @@ MODULE_PARM_DESC(queuemode,
+ MODULE_PARM(mem,    "i");
+ MODULE_PARM_DESC(mem,
+ 	"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+-	  "for video RAM management for eg. DRM/DRI. The default depends on the amount\n"
+-	  "of video RAM available. If 8MB of video RAM or less is available, the heap\n"
+-	  "starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise\n"
+-	  "at 12288KB. The value is to be specified without 'KB' and should match\n"
+-	  "the MaxXFBMem setting for XFree 4.x (x>=2).");
++	  "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
++	  "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
++	  "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
++	  "otherwise at 12288KB. On 315 and Xabre series, the heap is 1MB by default. The\n"
++	  "value is to be specified without 'KB' and should match the MaxXFBMem setting for\n"
++	  "XFree 4.x (x>=2).");
+ 
+ MODULE_PARM(forcecrt2type, "s");
+ MODULE_PARM_DESC(forcecrt2type,
+@@ -4673,56 +5201,76 @@ MODULE_PARM_DESC(pdc,
+ MODULE_PARM(noaccel, "i");
+ MODULE_PARM_DESC(noaccel,
+         "\nIf set to anything other than 0, 2D acceleration and y-panning will be\n"
+-	"disabled. (default: 0)");
++	  "disabled. (default: 0)");
+ 
+ MODULE_PARM(noypan, "i");
+ MODULE_PARM_DESC(noypan,
+         "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+-	"will be performed by redrawing the screen. This required 2D acceleration, so\n"
+-	"if the option noaccel is set, y-panning will be disabled. (default: 0)");
++ 	  "will be performed by redrawing the screen. (default: 0)");
+ 
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+ MODULE_PARM(inverse, "i");
+ MODULE_PARM_DESC(inverse,
+         "\nSetting this to anything but 0 should invert the display colors, but this\n"
+-	"does not seem to work. (default: 0)");
++	  "does not seem to work. (default: 0)");
+ #endif	
+ 
+ MODULE_PARM(userom, "i");
+ MODULE_PARM_DESC(userom,
+         "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
+-	"for some LCD and TV setup. (default: 1)");
++	  "for some LCD and TV setup. (default: 1)");
+ 
+ MODULE_PARM(useoem, "i");
+ MODULE_PARM_DESC(useoem,
+         "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
+-	"panels and TV connector types. (default: auto)");
++	  "panels and TV connector types. (default: [auto])");
+ 
+ MODULE_PARM(tvstandard, "s");
+ MODULE_PARM_DESC(tvstandard,
+ 	"\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+-	"pal and ntsc. (default: auto)");
++	  "pal and ntsc. (default: [auto])");
++
++MODULE_PARM(nocrt2rate, "i");
++MODULE_PARM_DESC(nocrt2rate,
++	"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
++	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)");
++
++MODULE_PARM(scalelcd, "i");
++MODULE_PARM_DESC(scalelcd,
++	"\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
++	  "native resolution. Setting it to 0 will disable scaling; if the panel can scale\n"
++	  "by itself, it will probably do this, otherwise you will see a black bar around\n"
++	  "the screen image. Default: [autodetect if panel can scale]");
++
++MODULE_PARM(specialtiming, "s");
+ 
+ int init_module(void)
+ {
+ 	int err;
+-	
++
++	SiS_Pr.UsePanelScaler = -1;
++	SiS_Pr.SiS_CustomT = CUT_NONE;
++
++	ivideo.refresh_rate = sisfb_parm_rate = rate;
++
++	if((scalelcd == 0) || (scalelcd == 1)) {
++	   SiS_Pr.UsePanelScaler = scalelcd ^ 1;
++	}
++
+ 	if(mode)
+-		sisfb_search_mode(mode);
++		sisfb_search_mode(mode, FALSE);
+ 	else if(vesa != -1)
+-		sisfb_search_vesamode(vesa);
+-	else  
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
++		sisfb_search_vesamode(vesa, FALSE);
++	else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 		/* For 2.4, set mode=none if no mode is given  */
+ 		sisfb_mode_idx = MODE_INDEX_NONE;
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+-		/* For 2.5, we don't need this "mode=none" stuff anymore */	
++		/* For 2.5, we don't need this "mode=none" stuff anymore */
+ 		sisfb_mode_idx = DEFAULT_MODE;
+ #endif
+ 
+-	ivideo.refresh_rate = rate;
+-
+ 	if(forcecrt2type)
+ 		sisfb_search_crt2type(forcecrt2type);
+ 
+@@ -4745,9 +5293,6 @@ int init_module(void)
+ 
+ 	if(noypan == 1)       sisfb_ypan = 0;
+ 	else if(noypan == 0)  sisfb_ypan = 1;
+-
+-	/* TW: Panning only with acceleration */
+-	if(sisfb_accel == 0)  sisfb_ypan = 0;
+ 	
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ 	if(inverse)           sisfb_inverse = 1;
+@@ -4759,17 +5304,11 @@ int init_module(void)
+ 
+ 	sisfb_useoem = useoem;
+ 
+-	enable_dstn = dstn;
+-
+-	/* TW: DSTN overrules forcecrt2type */
+-	if (enable_dstn)      sisfb_crt2type = DISPTYPE_LCD;
+-
+ 	if (queuemode)        sisfb_search_queuemode(queuemode);
+ 	
+ 	/* TW: If other queuemode than MMIO, disable 2D accel and ypan */
+ 	if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+ 	        sisfb_accel = 0;
+-		sisfb_ypan = 0;
+ 	}
+ 
+         if(pdc) {
+@@ -4778,6 +5317,11 @@ int init_module(void)
+ 	   }
+ 	}
+ 
++	sisfb_nocrt2rate = nocrt2rate;
++
++	if(specialtiming)
++		sisfb_search_specialtiming(specialtiming);
++
+ 	if((err = sisfb_init()) < 0) return err;
+ 
+ 	return 0;
+@@ -4788,7 +5332,7 @@ void cleanup_module(void)
+ 	/* TW: Release mem regions */
+ 	release_mem_region(ivideo.video_base, ivideo.video_size);
+ 	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+-	
++
+ #ifdef CONFIG_MTRR
+ 	/* TW: Release MTRR region */
+ 	if(ivideo.mtrr) {
+@@ -4802,11 +5346,17 @@ void cleanup_module(void)
+ 	if(sisfb_registered) {
+ 		unregister_framebuffer(&sis_fb_info);
+ 	}
+-	
++
+ 	if(sishw_ext.pSR) vfree(sishw_ext.pSR);
+ 	if(sishw_ext.pCR) vfree(sishw_ext.pCR);
+ 	
+-	/* TODO: Restore the initial mode */
++	/* TODO: Restore the initial mode
++	 * This sounds easy but is as good as impossible
++	 * on many machines with SiS chip and video bridge
++	 * since text modes are always set up differently
++	 * from machine to machine. Depends on the type
++	 * of integration between chipset and bridge.
++	 */
+ 	
+ 	printk(KERN_INFO "sisfb: Module unloaded\n");
+ }
+--- linux-2.6.0-test6/drivers/video/sis/sis_main.h	2003-06-14 12:18:04.000000000 -0700
++++ 25/drivers/video/sis/sis_main.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,8 +1,6 @@
+ #ifndef _SISFB_MAIN
+ #define _SISFB_MAIN
+ 
+-/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
+-
+ #include "vstruct.h"
+ 
+ /* ------------------- Constant Definitions ------------------------- */
+@@ -14,11 +12,11 @@
+ 
+ #define VER_MAJOR                 1
+ #define VER_MINOR                 6
+-#define VER_LEVEL                 1
++#define VER_LEVEL                 13
+ 
+ #include "sis.h"
+ 
+-/* TW: To be included in pci_ids.h */
++/* To be included in pci_ids.h */
+ #ifndef PCI_DEVICE_ID_SI_650_VGA
+ #define PCI_DEVICE_ID_SI_650_VGA  0x6325
+ #endif
+@@ -31,13 +29,22 @@
+ #ifndef PCI_DEVICE_ID_SI_330
+ #define PCI_DEVICE_ID_SI_330      0x0330
+ #endif
++#ifndef PCI_DEVICE_ID_SI_660
++#define PCI_DEVICE_ID_SI_660      0x0660
++#endif
++#ifndef PCI_DEVICE_ID_SI_660_VGA
++#define PCI_DEVICE_ID_SI_660_VGA  0x6330
++#endif
++#ifndef PCI_DEVICE_ID_SI_760
++#define PCI_DEVICE_ID_SI_760      0x0760
++#endif
+ 
+ /* To be included in fb.h */
+ #ifndef FB_ACCEL_SIS_GLAMOUR_2
+ #define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 740		*/
+ #endif
+ #ifndef FB_ACCEL_SIS_XABRE
+-#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre")		*/
++#define FB_ACCEL_SIS_XABRE      41	/* SiS 330, 660, 760 ("Xabre")	*/
+ #endif
+ 
+ #define MAX_ROM_SCAN              0x10000
+@@ -53,13 +60,12 @@
+ #define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
+ #endif
+ 
+-/* For 315 series */
++/* For 315/Xabre series */
+ #ifdef CONFIG_FB_SIS_315
+ #define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
+ #define COMMAND_QUEUE_THRESHOLD   0x1F
+ #endif
+ 
+-/* TW */
+ #define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
+ #define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
+ 
+@@ -283,48 +289,46 @@
+ /* Fbcon variables */
+ static struct fb_info sis_fb_info;
+ 
+-static int    video_type = FB_TYPE_PACKED_PIXELS;
+-
+ static struct fb_var_screeninfo default_var = {
+-	.xres		= 0,
+-	.yres		= 0,
+-	.xres_virtual	= 0,
+-	.yres_virtual	= 0,
+-	.xoffset	= 0,
+-	.yoffset	= 0,
+-	.bits_per_pixel	= 0,
+-	.grayscale	= 0,
+-	.red		= {0, 8, 0},
+-	.green		= {0, 8, 0},
+-	.blue		= {0, 8, 0},
+-	.transp		= {0, 0, 0},
+-	.nonstd		= 0,
+-	.activate	= FB_ACTIVATE_NOW,
+-	.height		= -1,
+-	.width		= -1,
+-	.accel_flags	= 0,
+-	.pixclock	= 0,
+-	.left_margin	= 0,
+-	.right_margin	= 0,
+-	.upper_margin	= 0,
+-	.lower_margin	= 0,
+-	.hsync_len	= 0,
+-	.vsync_len	= 0,
+-	.sync		= 0,
+-	.vmode		= FB_VMODE_NONINTERLACED,
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+-	.reserved	= {0, 0, 0, 0, 0, 0}
+-#endif	
++	.xres            = 0,
++	.yres            = 0,
++	.xres_virtual    = 0,
++	.yres_virtual    = 0,
++	.xoffset         = 0,
++	.yoffset         = 0,
++	.bits_per_pixel  = 0,
++	.grayscale       = 0,
++	.red             = {0, 8, 0},
++	.green           = {0, 8, 0},
++	.blue            = {0, 8, 0},
++	.transp          = {0, 0, 0},
++	.nonstd          = 0,
++	.activate        = FB_ACTIVATE_NOW,
++	.height          = -1,
++	.width           = -1,
++	.accel_flags     = 0,
++	.pixclock        = 0,
++	.left_margin     = 0,
++	.right_margin    = 0,
++	.upper_margin    = 0,
++	.lower_margin    = 0,
++	.hsync_len       = 0,
++	.vsync_len       = 0,
++	.sync            = 0,
++	.vmode           = FB_VMODE_NONINTERLACED,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++	.reserved        = {0, 0, 0, 0, 0, 0}
++#endif
+ };
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ static struct fb_fix_screeninfo sisfb_fix = {
+ 	.id		= "SiS",
+ 	.type		= FB_TYPE_PACKED_PIXELS,
+-	.xpanstep	= 1,
++	.xpanstep	= 0,
+ 	.ypanstep	= 1,
+ };
+-static char myid[20];
++static char myid[40];
+ static u32 pseudo_palette[17];
+ #endif
+ 
+@@ -347,26 +351,24 @@ static union {
+ } sis_fbcon_cmap;
+ 
+ static int sisfb_inverse = 0;
++static int currcon = 0;
+ #endif
+ 
+-/* display status */
++/* global flags */
+ static int sisfb_off = 0;
+ static int sisfb_crt1off = 0;
+ static int sisfb_forcecrt1 = -1;
+ static int sisvga_enabled = 0;
+ static int sisfb_userom = 1;
+ static int sisfb_useoem = -1;
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static int currcon = 0;
+-#endif
+-
+-/* global flags */
+-static int sisfb_registered;
+-static int sisfb_tvmode = 0;
++static int sisfb_parm_rate = -1;
++static int sisfb_registered = 0;
+ static int sisfb_mem = 0;
+ static int sisfb_pdc = 0;
+-static int enable_dstn = 0;
+ static int sisfb_ypan = -1;
++static int sisfb_nocrt2rate = 0;
++static int sisfb_dstn = 0;
++static int sisfb_fstn = 0;
+ 
+ VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
+ int 	   sisfb_accel = -1;
+@@ -375,22 +377,22 @@ int 	   sisfb_accel = -1;
+ static int sisfb_hwcursor_size = 0;
+ static int sisfb_CRT2_write_enable = 0;
+ 
+-int sisfb_crt2type  = -1;	/* TW: CRT2 type (for overriding autodetection) */
+-int sisfb_tvplug    = -1;	/* PR: Tv plug type (for overriding autodetection) */
++int sisfb_crt2type  = -1;	/* CRT2 type (for overriding autodetection) */
++int sisfb_tvplug    = -1;	/* Tv plug type (for overriding autodetection) */
+ 
+-int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310/325 series only) */
++int sisfb_queuemode = -1; 	/* Use MMIO queue mode by default (315 series only) */
+ 
+ unsigned char sisfb_detectedpdc = 0;
+ 
+ unsigned char sisfb_detectedlcda = 0xff;
+ 
+-/* data for sis components */
++/* data for sis hardware ("par") */
+ struct video_info ivideo;
+ 
+-/* TW: For ioctl SISFB_GET_INFO */
++/* For ioctl SISFB_GET_INFO */
+ sisfb_info sisfbinfo;
+ 
+-/* TW: Hardware extension; contains data on hardware */
++/* Hardware extension; contains data on hardware */
+ HW_DEVICE_EXTENSION sishw_ext = {
+ 	NULL, NULL, FALSE, NULL, NULL,
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0,
+@@ -399,10 +401,10 @@ HW_DEVICE_EXTENSION sishw_ext = {
+ 	0
+ };
+ 
+-/* TW: SiS private structure */
++/* SiS private structure */
+ SiS_Private  SiS_Pr;
+ 
+-/* card parameters */
++/* Card parameters */
+ static unsigned long sisfb_mmio_size = 0;
+ static u8            sisfb_caps = 0;
+ 
+@@ -412,7 +414,7 @@ typedef enum _SIS_CMDTYPE {
+ 	VM_CMD_QUEUE,
+ } SIS_CMDTYPE;
+ 
+-/* Supported SiS Chips list */
++/* List of supported chips */
+ static struct board {
+ 	u16 vendor, device;
+ 	const char *name;
+@@ -424,16 +426,17 @@ static struct board {
+ 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     "SIS 315"},
+ 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  "SIS 315PRO"},
+ 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
+-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
++	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/M652/740 VGA"},
+ 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
++	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 660/M660/760/M760 VGA"},
+ 	{0, 0, NULL}
+ };
+ 
+ #define MD_SIS300 1
+ #define MD_SIS315 2
+ 
+-/* mode table */
+-/* NOT const - will be patched for 1280x960 mode number chaos reasons */
++/* Mode table */
++/* NOT const - will be patched for 1280x768 mode number chaos reasons */
+ struct _sisbios_mode {
+ 	char name[15];
+ 	u8 mode_no;
+@@ -447,14 +450,33 @@ struct _sisbios_mode {
+ 	u16 rows;
+ 	u8  chipset;
+ } sisbios_mode[] = {
+-#define MODE_INDEX_NONE           0  /* TW: index for mode=none */
+-	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},  /* TW: for mode "none" */
+-	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,           MD_SIS315},
+-	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+-	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+-	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
++#define MODE_INDEX_NONE           0  /* index for mode=none */
++	{"none",         0xff, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},
++	{"320x200x8",    0x59, 0x0138, 0x0000,  320,  200,  8, 1,  40, 12, MD_SIS300|MD_SIS315},
++	{"320x200x16",   0x41, 0x010e, 0x0000,  320,  200, 16, 1,  40, 12, MD_SIS300|MD_SIS315},
++	{"320x200x24",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
++	{"320x200x32",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},
++	{"320x240x8",    0x50, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15, MD_SIS300|MD_SIS315},
++	{"320x240x16",   0x56, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
++	{"320x240x24",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
++	{"320x240x32",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
++	{"320x240x8",    0x5a, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
++	{"320x240x16",   0x5b, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
++	{"400x300x8",    0x51, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
++	{"400x300x16",   0x57, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
++	{"400x300x24",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
++	{"400x300x32",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
++	{"512x384x8",    0x52, 0x0000, 0x0000,  512,  384,  8, 1,  64, 24, MD_SIS300|MD_SIS315},
++	{"512x384x16",   0x58, 0x0000, 0x0000,  512,  384, 16, 1,  64, 24, MD_SIS300|MD_SIS315},
++	{"512x384x24",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
++	{"512x384x32",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
++	{"640x400x8",    0x2f, 0x0000, 0x0000,  640,  400,  8, 1,  80, 25, MD_SIS300|MD_SIS315},
++	{"640x400x16",   0x5d, 0x0000, 0x0000,  640,  400, 16, 1,  80, 25, MD_SIS300|MD_SIS315},
++	{"640x400x24",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
++	{"640x400x32",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
++	{"640x480x8",    0x2e, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
+ 	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
+-	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
++	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
+ 	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
+ 	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
+ 	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
+@@ -464,63 +486,87 @@ struct _sisbios_mode {
+ 	{"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_SIS300|MD_SIS315},
+ 	{"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+ 	{"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
++	{"768x576x8",    0x5f, 0x0000, 0x0000,  768,  576,  8, 1,  96, 36, MD_SIS300|MD_SIS315},
++	{"768x576x16",   0x60, 0x0000, 0x0000,  768,  576, 16, 1,  96, 36, MD_SIS300|MD_SIS315},
++	{"768x576x24",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
++	{"768x576x32",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
+ 	{"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_SIS300|MD_SIS315},
+ 	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
+ 	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+ 	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+-#define DEFAULT_MODE              20 /* TW: index for 800x600x8 */
+-#define DEFAULT_LCDMODE           20 /* TW: index for 800x600x8 */
+-#define DEFAULT_TVMODE            20 /* TW: index for 800x600x8 */
++#define DEFAULT_MODE              43 /* index for 800x600x8 */
++#define DEFAULT_LCDMODE           43 /* index for 800x600x8 */
++#define DEFAULT_TVMODE            43 /* index for 800x600x8 */
+ 	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
+ 	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
+ 	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+ 	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
++	{"848x480x8",    0x39, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
++	{"848x480x16",   0x3b, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
++	{"848x480x24",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
++	{"848x480x32",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
++	{"856x480x8",    0x3f, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
++	{"856x480x16",   0x42, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
++	{"856x480x24",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
++	{"856x480x32",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+ 	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
+ 	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+ 	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+ 	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+-	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },  /* TW: 300 series only */
++	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
+ 	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
+ 	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+ 	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+ 	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
+-	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
++	{"1024x768x16",  0x4a, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+ 	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+ 	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+-	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },  /* TW: 300 series only */
++	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
+ 	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
+ 	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+ 	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
++	{"1152x864x8",   0x29, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
++	{"1152x864x16",  0x2a, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
++	{"1152x864x24",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
++	{"1152x864x32",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+ 	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
+ 	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+ 	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+ 	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+-	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_SIS315},  /* TW: 310/325 series only */
+-	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_SIS315},
+-	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
+-	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
+-#define MODEINDEX_1280x960 48
+-	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},  /* TW: Modenumbers being patched */
+-	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+-	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+-	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+-	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
+-	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
++#define MODEINDEX_1280x768 79
++	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
++	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
++	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
++	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
++	{"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
++	{"1280x960x16",  0x7d, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
++	{"1280x960x24",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
++	{"1280x960x32",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
++	{"1280x1024x8",  0x3a, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
++	{"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+ 	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+ 	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+-	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},  /* TW: 310/325 series only */
++	{"1360x768x8",   0x48, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
++	{"1360x768x16",  0x4b, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
++	{"1360x768x24",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
++	{"1360x768x32",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
++	{"1360x1024x8",  0x67, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
++	{"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
++	{"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
++	{"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
++	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
+ 	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
+ 	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+ 	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+-	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
+-	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
++	{"1600x1200x8",  0x3c, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
++	{"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+ 	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ 	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ 	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
+ 	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
+-	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+-	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+-	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},  /* TW: 310/325 series only */
++	{"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
++	{"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
++	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
+ 	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
+ 	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+ 	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+@@ -538,37 +584,36 @@ u8  sisfb_rate_idx = 0;
+ 
+ /* TW: CR36 evaluation */
+ const USHORT sis300paneltype[] =
+-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
+-      LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
+-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768,
+-      LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
++    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
++      LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
++      LCD_1024x768,  LCD_1024x768,  LCD_1024x768,  LCD_1024x768,
++      LCD_1024x768,  LCD_1024x768,  LCD_320x480,   LCD_1024x768 };
+ 
+ const USHORT sis310paneltype[] =
+-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
+-      LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
+-      LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
+-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
++    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
++      LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
++      LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
++      LCD_640x480_2, LCD_640x480_3, LCD_320x480,   LCD_1024x768 };
++
++#define FL_550_DSTN 0x01
++#define FL_550_FSTN 0x02
+ 
+ static const struct _sis_crt2type {
+ 	char name[10];
+ 	int type_no;
+ 	int tvplug_no;
++	unsigned short flags;
+ } sis_crt2type[] = {
+-	{"NONE", 	0, 		-1},
+-	{"LCD",  	DISPTYPE_LCD, 	-1},
+-	{"TV",   	DISPTYPE_TV, 	-1},
+-	{"VGA",  	DISPTYPE_CRT2, 	-1},
+-	{"SVIDEO", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
+-	{"COMPOSITE", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
+-	{"SCART", 	DISPTYPE_TV, 	TVPLUG_SCART},
+-	{"none", 	0, 		-1},
+-	{"lcd",  	DISPTYPE_LCD, 	-1},
+-	{"tv",   	DISPTYPE_TV, 	-1},
+-	{"vga",  	DISPTYPE_CRT2, 	-1},
+-	{"svideo", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
+-	{"composite", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
+-	{"scart", 	DISPTYPE_TV, 	TVPLUG_SCART},
+-	{"\0",  	-1, 		-1}
++	{"NONE", 	0, 		-1,        0},
++	{"LCD",  	CRT2_LCD, 	-1,        0},
++	{"TV",   	CRT2_TV, 	-1,        0},
++	{"VGA",  	CRT2_VGA, 	-1,        0},
++	{"SVIDEO", 	CRT2_TV, 	TV_SVIDEO, 0},
++	{"COMPOSITE", 	CRT2_TV, 	TV_AVIDEO, 0},
++	{"SCART", 	CRT2_TV, 	TV_SCART,  0},
++	{"DSTN",        CRT2_LCD,       -1,        FL_550_DSTN},
++	{"FSTN",        CRT2_LCD,       -1,        FL_550_FSTN},
++	{"\0",  	-1, 		-1,        0}
+ };
+ 
+ /* Queue mode selection for 310 series */
+@@ -579,9 +624,6 @@ static const struct _sis_queuemode {
+ 	{"AGP",  	AGP_CMD_QUEUE},
+ 	{"VRAM", 	VM_CMD_QUEUE},
+ 	{"MMIO", 	MMIO_CMD},
+-	{"agp",  	AGP_CMD_QUEUE},
+-	{"vram", 	VM_CMD_QUEUE},
+-	{"mmio", 	MMIO_CMD},
+ 	{"\0",   	-1}
+ };
+ 
+@@ -590,10 +632,8 @@ static const struct _sis_tvtype {
+ 	char name[6];
+ 	int type_no;
+ } sis_tvtype[] = {
+-	{"PAL",  	1},
+-	{"NTSC", 	2},
+-	{"pal", 	1},
+-	{"ntsc",  	2},
++	{"PAL",  	TV_PAL},
++	{"NTSC", 	TV_NTSC},
+ 	{"\0",   	-1}
+ };
+ 
+@@ -602,33 +642,102 @@ static const struct _sis_vrate {
+ 	u16 xres;
+ 	u16 yres;
+ 	u16 refresh;
++	BOOLEAN SiS730valid32bpp;
+ } sisfb_vrate[] = {
+-	{1,  640,  480, 60}, {2,  640,  480,  72}, {3, 640,   480,  75}, {4,  640, 480,  85},
+-	{5,  640,  480,100}, {6,  640,  480, 120}, {7, 640,   480, 160}, {8,  640, 480, 200},
+-	{1,  720,  480, 60},
+-	{1,  720,  576, 58},
+-	{1,  800,  480, 60}, {2,  800,  480,  75}, {3, 800,   480,  85},
+-	{1,  800,  600, 56}, {2,  800,  600,  60}, {3, 800,   600,  72}, {4,  800, 600,  75},
+-	{5,  800,  600, 85}, {6,  800,  600, 100}, {7, 800,   600, 120}, {8,  800, 600, 160},
+-	{1, 1024,  768, 43}, {2, 1024,  768,  60}, {3, 1024,  768,  70}, {4, 1024, 768,  75},
+-	{5, 1024,  768, 85}, {6, 1024,  768, 100}, {7, 1024,  768, 120},
+-	{1, 1024,  576, 60}, {2, 1024,  576,  75}, {3, 1024,  576,  85},
+-	{1, 1024,  600, 60},
+-	{1, 1152,  768, 60},
+-	{1, 1280,  720, 60}, {2, 1280,  720,  75}, {3, 1280,  720,  85},
+-	{1, 1280,  768, 60},
+-	{1, 1280, 1024, 43}, {2, 1280, 1024,  60}, {3, 1280, 1024,  75}, {4, 1280, 1024,  85},
+-	{1, 1280,  960, 70},
+-	{1, 1400, 1050, 60},
+-	{1, 1600, 1200, 60}, {2, 1600, 1200,  65}, {3, 1600, 1200,  70}, {4, 1600, 1200,  75},
+-	{5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
+-	{1, 1920, 1440, 60}, {2, 1920, 1440,  65}, {3, 1920, 1440,  70}, {4, 1920, 1440,  75},
+-	{5, 1920, 1440, 85}, {6, 1920, 1440, 100},
+-	{1, 2048, 1536, 60}, {2, 2048, 1536,  65}, {3, 2048, 1536,  70}, {4, 2048, 1536,  75},
+-	{5, 2048, 1536, 85},
+-	{0, 0, 0, 0}
++	{1,  320,  200,  70,  TRUE},
++	{1,  320,  240,  60,  TRUE},
++	{1,  320,  480,  60,  TRUE},
++	{1,  400,  300,  60,  TRUE},
++	{1,  512,  384,  60,  TRUE},
++	{1,  640,  400,  72,  TRUE},
++	{1,  640,  480,  60,  TRUE}, {2,  640,  480,  72,  TRUE}, {3,  640,  480,  75,  TRUE},
++	{4,  640,  480,  85,  TRUE}, {5,  640,  480, 100,  TRUE}, {6,  640,  480, 120,  TRUE},
++	{7,  640,  480, 160,  TRUE}, {8,  640,  480, 200,  TRUE},
++	{1,  720,  480,  60,  TRUE},
++	{1,  720,  576,  58,  TRUE},
++	{1,  800,  480,  60,  TRUE}, {2,  800,  480,  75,  TRUE}, {3,  800,  480,  85,  TRUE},
++	{1,  800,  600,  56,  TRUE}, {2,  800,  600,  60,  TRUE}, {3,  800,  600,  72,  TRUE},
++	{4,  800,  600,  75,  TRUE}, {5,  800,  600,  85,  TRUE}, {6,  800,  600, 105,  TRUE},
++	{7,  800,  600, 120,  TRUE}, {8,  800,  600, 160,  TRUE},
++	{1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
++	{1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
++	{1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
++	{1, 1024,  600,  60,  TRUE},
++	{1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
++	{4, 1024,  768,  75, FALSE}, {5, 1024,  768,  85,  TRUE}, {6, 1024,  768, 100,  TRUE},
++	{7, 1024,  768, 120,  TRUE},
++	{1, 1152,  768,  60,  TRUE},
++	{1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
++	{1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
++	{1, 1280,  768,  60,  TRUE},
++	{1, 1280,  960,  60,  TRUE}, {2, 1280,  960,  85,  TRUE},
++	{1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
++	{4, 1280, 1024,  85,  TRUE},
++	{1, 1360,  768,  60,  TRUE},
++	{1, 1360, 1024,  59,  TRUE},
++	{1, 1400, 1050,  60,  TRUE}, {2, 1400, 1050,  75,  TRUE},
++	{1, 1600, 1200,  60,  TRUE}, {2, 1600, 1200,  65,  TRUE}, {3, 1600, 1200,  70,  TRUE},
++	{4, 1600, 1200,  75,  TRUE}, {5, 1600, 1200,  85,  TRUE}, {6, 1600, 1200, 100,  TRUE},
++	{7, 1600, 1200, 120,  TRUE},
++	{1, 1920, 1440,  60,  TRUE}, {2, 1920, 1440,  65,  TRUE}, {3, 1920, 1440,  70,  TRUE},
++	{4, 1920, 1440,  75,  TRUE}, {5, 1920, 1440,  85,  TRUE}, {6, 1920, 1440, 100,  TRUE},
++	{1, 2048, 1536,  60,  TRUE}, {2, 2048, 1536,  65,  TRUE}, {3, 2048, 1536,  70,  TRUE},
++	{4, 2048, 1536,  75,  TRUE}, {5, 2048, 1536,  85,  TRUE},
++	{0,    0,    0,   0, FALSE}
+ };
+ 
++static struct sisfb_monitor {
++	u16 hmin;
++	u16 hmax;
++	u16 vmin;
++	u16 vmax;
++	u32 dclockmax;
++	u8  feature;
++	BOOLEAN datavalid;
++} sisfb_thismonitor;
++
++static const struct _sisfbddcsmodes {
++	u32 mask;
++	u16 h;
++	u16 v;
++	u32 d;
++} sisfb_ddcsmodes[] = {
++	{ 0x10000, 67, 75, 108000},
++	{ 0x08000, 48, 72,  50000},
++	{ 0x04000, 46, 75,  49500},
++	{ 0x01000, 35, 43,  44900},
++	{ 0x00800, 48, 60,  65000},
++	{ 0x00400, 56, 70,  75000},
++	{ 0x00200, 60, 75,  78800},
++	{ 0x00100, 80, 75, 135000},
++	{ 0x00020, 31, 60,  25200},
++	{ 0x00008, 38, 72,  31500},
++	{ 0x00004, 37, 75,  31500},
++	{ 0x00002, 35, 56,  36000},
++	{ 0x00001, 38, 60,  40000}
++};
++
++static const struct _sisfbddcfmodes {
++	u16 x;
++	u16 y;
++	u16 v;
++	u16 h;
++	u32 d;
++} sisfb_ddcfmodes[] = {
++       { 1280, 1024, 85, 92, 157500},
++       { 1600, 1200, 60, 75, 162000},
++       { 1600, 1200, 65, 82, 175500},
++       { 1600, 1200, 70, 88, 189000},
++       { 1600, 1200, 75, 94, 202500},
++       { 1600, 1200, 85, 107,229500},
++       { 1920, 1440, 60, 90, 234000},
++       { 1920, 1440, 75, 113,297000}
++};
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++static u8 sisfb_lastrates[128];
++#endif
++
+ static const struct _chswtable {
+     int subsysVendor;
+     int subsysCard;
+@@ -636,9 +745,61 @@ static const struct _chswtable {
+     char *cardName;
+ } mychswtable[] = {
+         { 0x1631, 0x1002, "Mitachi", "0x1002" },
++	{ 0x1071, 0x7521, "Mitac"  , "7521P"  },
+ 	{ 0,      0,      ""       , ""       }
+ };
+ 
++static const struct _customttable {
++    unsigned short chipID;
++    char *biosversion;
++    char *biosdate;
++    unsigned long bioschksum;
++    unsigned short biosFootprintAddr[5];
++    unsigned char biosFootprintData[5];
++    unsigned short pcisubsysvendor;
++    unsigned short pcisubsyscard;
++    char *vendorName;
++    char *cardName;
++    unsigned long SpecialID;
++    char *optionName;
++} mycustomttable[] = {
++        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
++	  0x3240A8,
++	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
++	  {  0x01,  0xe3,  0x9a,  0x6a,  0x00 },
++	  0x1039, 0x6300,
++	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
++	},
++	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
++	  0x323FBD,
++	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
++	  {  0x00,  0x5a,  0x64,  0x41,  0x00 },
++	  0x1039, 0x6300,
++	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
++	},
++	{ SIS_650, "", "",
++	  0,
++	  { 0, 0, 0, 0, 0 },
++	  { 0, 0, 0, 0, 0 },
++	  0x0e11, 0x083c,
++	  "Compaq", "Presario 3045US", CUT_COMPAQ12802, "COMPAQ1280"
++	},
++	{ 4321, "", "",			/* This is hopefully NEVER autodetected */
++	  0,
++	  { 0, 0, 0, 0, 0 },
++	  { 0, 0, 0, 0, 0 },
++	  0, 0,
++	  "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
++	},
++	{ 0, "", "",
++	  0,
++	  { 0, 0, 0, 0 },
++	  { 0, 0, 0, 0 },
++	  0, 0,
++	  "", "", CUT_NONE, ""
++	}
++};
++
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ /* Offscreen layout */
+ typedef struct _SIS_GLYINFO {
+@@ -677,7 +838,6 @@ static unsigned long sisfb_heap_end;
+ static unsigned long sisfb_heap_size;
+ static SIS_HEAP      sisfb_heap;
+ 
+-// Eden Chen
+ static const struct _sis_TV_filter {
+ 	u8 filter[9][4];
+ } sis_TV_filter[] = {
+@@ -829,9 +989,8 @@ static const struct _sis_TV_filter {
+ 
+ static int           filter = -1;
+ static unsigned char filter_tb;
+-//~Eden Chen
+ 
+-/* ---------------------- Routine prototypes ------------------------- */
++/* ---------------------- Prototypes ------------------------- */
+ 
+ /* Interface used by the world */
+ #ifndef MODULE
+@@ -894,10 +1053,6 @@ extern void     fbcon_sis_fillrect(struc
+                                    const struct fb_fillrect *rect);
+ extern void     fbcon_sis_copyarea(struct fb_info *info, 
+                                    const struct fb_copyarea *area);
+-#if 0				   
+-extern void     cfb_imageblit(struct fb_info *info, 
+-                              const struct fb_image *image);
+-#endif			      
+ extern int      fbcon_sis_sync(struct fb_info *info);
+ static int      sisfb_ioctl(struct inode *inode, 
+ 	 		    struct file *file,
+@@ -912,7 +1067,7 @@ extern int      sisfb_mode_rate_to_ddata
+ 			 unsigned int *left_margin, unsigned int *right_margin, 
+ 			 unsigned int *upper_margin, unsigned int *lower_margin,
+ 			 unsigned int *hsync_len, unsigned int *vsync_len,
+-			 unsigned int *sync, unsigned int *vmode);			      		    			      
++			 unsigned int *sync, unsigned int *vmode);
+ #endif
+ 			
+ static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+@@ -923,9 +1078,9 @@ extern int      sisfb_initaccel(void);
+ extern void     sisfb_syncaccel(void);
+ 
+ /* Internal general routines */
+-static void     sisfb_search_mode(const char *name);
+-static int      sisfb_validate_mode(int modeindex);
+-static u8       sisfb_search_refresh_rate(unsigned int rate);
++static void     sisfb_search_mode(char *name, BOOLEAN quiet);
++static int      sisfb_validate_mode(int modeindex, unsigned long vbflags);
++static u8       sisfb_search_refresh_rate(unsigned int rate, int index);
+ static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ 			unsigned blue, unsigned transp,
+ 			struct fb_info *fb_info);
+@@ -939,6 +1094,12 @@ static BOOLEAN  sisfb_CheckVBRetrace(voi
+ static BOOLEAN  sisfbcheckvretracecrt2(void);
+ static BOOLEAN  sisfbcheckvretracecrt1(void);
+ static BOOLEAN  sisfb_bridgeisslave(void);
++static void     sisfb_detect_VB_connect(void);
++static void     sisfb_get_VB_type(void);
++
++static void     sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
++static BOOLEAN  sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
++
+ 
+ /* SiS-specific Export functions */
+ void            sis_dispinfo(struct ap_data *rec);
+@@ -952,15 +1113,9 @@ u32             sisfb_get_reg3(u16 port)
+ /* Chipset-dependent internal routines */
+ #ifdef CONFIG_FB_SIS_300
+ static int      sisfb_get_dram_size_300(void);
+-static void     sisfb_detect_VB_connect_300(void);
+-static void     sisfb_get_VB_type_300(void);
+-static int      sisfb_has_VB_300(void);
+ #endif
+ #ifdef CONFIG_FB_SIS_315
+ static int      sisfb_get_dram_size_315(void);
+-static void     sisfb_detect_VB_connect_315(void);
+-static void     sisfb_get_VB_type_315(void);
+-static int      sisfb_has_VB_315(void);
+ #endif
+ 
+ /* Internal heap routines */
+@@ -978,23 +1133,33 @@ BOOLEAN         sisfb_query_VGA_config_s
+ BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+ 	         	unsigned long offset, unsigned long set, unsigned long *value);
+ 
+-
+ /* Routines from init.c/init301.c */
+ extern void 	SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+ extern BOOLEAN  SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+-extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
++extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
++extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+ extern void     SiS_LongWait(SiS_Private *SiS_Pr);
+ 
+-/* TW: Chrontel TV functions */
++extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
++		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
++
++/* Chrontel TV functions */
+ extern USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void 	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern USHORT 	SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void 	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+ extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+ extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
++extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
++extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
++		              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
++extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
++extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
++extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+ 
+-/* TW: Sensing routines */
++/* Sensing routines */
+ void            SiS_Sense30x(void);
+ int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
+ void            SiS_SenseCh(void);			
+--- linux-2.6.0-test6/drivers/video/sis/vgatypes.h	2003-06-14 12:17:55.000000000 -0700
++++ 25/drivers/video/sis/vgatypes.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,3 +1,36 @@
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
++/*
++ * General type definitions for universal mode switching modules
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *		Silicon Integrated Systems
++ *
++ */
+ #ifndef _VGATYPES_
+ #define _VGATYPES_
+ 
+@@ -5,7 +38,7 @@
+ #include "xf86Pci.h"
+ #endif
+ 
+-#ifdef LINUX_KERNEL  /* TW: We don't want the X driver to depend on kernel source */
++#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
+ #include <linux/ioctl.h>
+ #endif
+ 
+@@ -72,18 +105,15 @@ typedef void VOID;
+ typedef UCHAR BOOLEAN;
+ #endif
+ 
+-#ifndef WINCE_HEADER
+ #ifndef bool
+ typedef UCHAR bool;
+ #endif
+-#endif /*WINCE_HEADER*/
+ 
+ #ifndef VBIOS_VER_MAX_LENGTH
+ #define VBIOS_VER_MAX_LENGTH         4
+ #endif
+ 
+ #ifndef LINUX_KERNEL   /* For kernel, this is defined in sisfb.h */
+-#ifndef WIN2000
+ #ifndef SIS_CHIP_TYPE
+ typedef enum _SIS_CHIP_TYPE {
+     SIS_VGALegacy = 0,
+@@ -101,19 +131,19 @@ typedef enum _SIS_CHIP_TYPE {
+     SIS_550,
+     SIS_650,
+     SIS_740,
+-    SIS_330, 
++    SIS_330,
++    SIS_660,
++    SIS_760,
+     MAX_SIS_CHIP
+ } SIS_CHIP_TYPE;
+ #endif
+ #endif
+-#endif
+ 
+-#ifndef WIN2000
+ #ifndef SIS_VB_CHIP_TYPE
+ typedef enum _SIS_VB_CHIP_TYPE {
+     VB_CHIP_Legacy = 0,
+     VB_CHIP_301,
+-    VB_CHIP_301B,      
++    VB_CHIP_301B,
+     VB_CHIP_301LV,
+     VB_CHIP_302,
+     VB_CHIP_302B,
+@@ -122,9 +152,7 @@ typedef enum _SIS_VB_CHIP_TYPE {
+     MAX_VB_CHIP
+ } SIS_VB_CHIP_TYPE;
+ #endif
+-#endif
+ 
+-#ifndef WIN2000
+ #ifndef SIS_LCD_TYPE
+ typedef enum _SIS_LCD_TYPE {
+     LCD_INVALID = 0,
+@@ -136,18 +164,20 @@ typedef enum _SIS_LCD_TYPE {
+     LCD_1600x1200,
+     LCD_1920x1440,
+     LCD_2048x1536,
+-    LCD_320x480,       /* TW: FSTN */
++    LCD_320x480,       /* FSTN, DSTN */
+     LCD_1400x1050,
+     LCD_1152x864,
+     LCD_1152x768,
+     LCD_1280x768,
+     LCD_1024x600,
++    LCD_640x480_2,     /* FSTN, DSTN */
++    LCD_640x480_3,     /* FSTN, DSTN */
++    LCD_848x480,
++    LCD_CUSTOM,
+     LCD_UNKNOWN
+ } SIS_LCD_TYPE;
+ #endif
+-#endif
+ 
+-#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
+ #ifndef PSIS_DSReg
+ typedef struct _SIS_DSReg
+ {
+@@ -162,7 +192,6 @@ typedef struct _SIS_HW_DEVICE_INFO  SIS_
+ 
+ typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+ 
+-
+ struct _SIS_HW_DEVICE_INFO
+ {
+     PVOID  pDevice;              /* The pointer to the physical device data structure
+@@ -173,7 +202,7 @@ struct _SIS_HW_DEVICE_INFO
+                                  /* Note:ROM image file is the file of VBIOS ROM */
+ 
+     BOOLEAN UseROM;		 /* TW: Use the ROM image if provided */
+- 
++
+     UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
+                                  /* wincE:ROM image file is the file for OEM */
+                                  /*       customized table */
+@@ -195,7 +224,7 @@ struct _SIS_HW_DEVICE_INFO
+                                  /* defined in the data structure type */
+                                  /* "SIS_VB_CHIP_TYPE" */
+ 
+-    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
++    USHORT usExternalChip;       /* NO VB or other video bridge (other than  */
+                                  /* SiS video bridge) */
+                                  /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+                                  /* then bit0=1 : LVDS,bit1=1 : trumpion, */
+@@ -207,7 +236,7 @@ struct _SIS_HW_DEVICE_INFO
+                                  /*             011:Trumpion LVDS Scaling Chip */
+                                  /*             100:LVDS(LCD-out)+Chrontel 7005 */
+                                  /*             101:Single Chrontel 7005 */
+-				 /* TW: This has changed on 310/325 series! */
++				 /* TW: This has changed on 315 series! */
+ 
+     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
+                                  /* "SIS_LCD_TYPE" */
+@@ -244,7 +273,6 @@ struct _SIS_HW_DEVICE_INFO
+ #endif
+ };
+ #endif
+-#endif 
+ 
+ 
+ /* TW: Addtional IOCTL for communication sisfb <> X driver        */
+@@ -284,12 +312,16 @@ struct _SISFB_INFO {
+ 	
+ 	unsigned char sisfb_lcda;
+ 
+-	char reserved[235]; 		/* for future use */
++	unsigned long sisfb_vbflags;
++	unsigned long sisfb_currentvbflags;
++
++	int sisfb_scalelcd;
++	unsigned long sisfb_specialtiming;
++
++	char reserved[219]; 		/* for future use */
+ };
+ #endif
+ 
+-#ifndef WIN2000
+-#ifndef WINCE_HEADER
+ #ifndef BUS_DATA_TYPE
+ typedef enum _BUS_DATA_TYPE {
+     ConfigurationSpaceUndefined = -1,
+@@ -307,7 +339,6 @@ typedef enum _BUS_DATA_TYPE {
+     MaximumBusDataType
+ } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
+ #endif
+-#endif /* WINCE_HEADER */
+ 
+ #ifndef PCI_TYPE0_ADDRESSES
+ #define PCI_TYPE0_ADDRESSES             6
+@@ -317,7 +348,6 @@ typedef enum _BUS_DATA_TYPE {
+ #define PCI_TYPE1_ADDRESSES             2
+ #endif
+ 
+-#ifndef WINCE_HEADER
+ #ifndef PCI_COMMON_CONFIG
+ typedef struct _PCI_COMMON_CONFIG {
+     USHORT  VendorID;                   /* (ro)                 */
+@@ -355,7 +385,6 @@ typedef struct _PCI_COMMON_CONFIG {
+ 
+ } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
+ #endif
+-#endif /* WINCE_HEADER */
+ 
+ #ifndef FIELD_OFFSET
+ #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
+@@ -364,6 +393,6 @@ typedef struct _PCI_COMMON_CONFIG {
+ #ifndef PCI_COMMON_HDR_LENGTH
+ #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
+ #endif
+-#endif
+ 
+ #endif
++
+--- linux-2.6.0-test6/drivers/video/sis/vstruct.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/video/sis/vstruct.h	2003-10-05 00:34:22.000000000 -0700
+@@ -1,3 +1,37 @@
++/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
++/*
++ * General structure definitions for universal mode switching modules
++ *
++ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the linux kernel, the contents of this file
++ * is entirely covered by the GPL.
++ *
++ * Otherwise, the following terms apply:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that
++ * copyright notice and this permission notice appear in supporting
++ * documentation, and that the name of the copyright holder not be used in
++ * advertising or publicity pertaining to distribution of the software without
++ * specific, written prior permission.  The copyright holder makes no representations
++ * about the suitability of this software for any purpose.  It is provided
++ * "as is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
++ *              Silicon Integrated Systems
++ *
++ */
++
+ #ifdef _INIT_
+ #define EXTERN
+ #else
+@@ -58,7 +92,6 @@ typedef struct _SiS_LVDSCRT1DataStruct
+ 	UCHAR  CR[15];
+ } SiS_LVDSCRT1DataStruct;
+ 
+-/*add for LCDA*/
+ typedef struct _SiS_LCDACRT1DataStruct
+ {
+ 	UCHAR  CR[17];
+@@ -111,9 +144,7 @@ typedef struct _SiS_ExtStruct
+ 	UCHAR  Ext_ModeID;
+ 	USHORT Ext_ModeFlag;
+ 	USHORT Ext_ModeInfo;
+-	USHORT Ext_Point;
+ 	USHORT Ext_VESAID;
+-	UCHAR  Ext_VESAMEMSize;
+ 	UCHAR  Ext_RESINFO;
+ 	UCHAR  VB_ExtTVFlickerIndex;
+ 	UCHAR  VB_ExtTVEdgeIndex;
+@@ -130,7 +161,6 @@ typedef struct _SiS_Ext2Struct
+ 	UCHAR  ModeID;
+ 	USHORT XRes;
+ 	USHORT YRes;
+-	USHORT ROM_OFFSET;
+ } SiS_Ext2Struct;
+ 
+ typedef struct _SiS_Part2PortTblStruct
+@@ -183,6 +213,15 @@ typedef struct _SiS_ModeResInfoStruct
+ 
+ typedef UCHAR DRAM4Type[4];
+ 
++/* Defines for SiS_Customt */
++#define CUT_NONE        0
++#define CUT_FORCENONE   1
++#define CUT_BARCO1366   2
++#define CUT_BARCO1024   3
++#define CUT_COMPAQ1280  4
++#define CUT_COMPAQ12802 5
++#define CUT_PANEL848    6
++
+ typedef struct _SiS_Private
+ {
+ #ifdef LINUX_KERNEL
+@@ -198,25 +237,34 @@ typedef struct _SiS_Private
+ 	USHORT SiS_P3c7;
+ 	USHORT SiS_P3c8;
+ 	USHORT SiS_P3c9;
++	USHORT SiS_P3cb;
++	USHORT SiS_P3cd;
+ 	USHORT SiS_P3da;
+ 	USHORT SiS_Part1Port;
+ 	USHORT SiS_Part2Port;
+ 	USHORT SiS_Part3Port;
+ 	USHORT SiS_Part4Port;
+ 	USHORT SiS_Part5Port;
++	USHORT SiS_VidCapt;
++	USHORT SiS_VidPlay;
+ 	USHORT SiS_IF_DEF_LVDS;
+ 	USHORT SiS_IF_DEF_TRUMPION;
+ 	USHORT SiS_IF_DEF_DSTN;
+ 	USHORT SiS_IF_DEF_FSTN;
+ 	USHORT SiS_IF_DEF_CH70xx;
+ 	USHORT SiS_IF_DEF_HiVision;
++	USHORT SiS_SysFlags;
+ 	UCHAR  SiS_VGAINFO;
++#ifndef LINUX_KERNEL
++        USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
++#endif
+ 	BOOLEAN SiS_UseROM;
+ 	int    SiS_CHOverScan;
+ 	BOOLEAN SiS_CHSOverScan;
+ 	BOOLEAN SiS_ChSW;
+ 	BOOLEAN SiS_UseLCDA;
+ 	int    SiS_UseOEM;
++	ULONG  SiS_CustomT;
+ 	USHORT SiS_Backup70xx;
+ 	USHORT SiS_CRT1Mode;
+ 	USHORT SiS_flag_clearbuffer;
+@@ -270,15 +318,18 @@ typedef struct _SiS_Private
+ 	USHORT SiS_Panel1280x768;
+ 	USHORT SiS_Panel1024x600;
+ 	USHORT SiS_Panel640x480;
++	USHORT SiS_Panel640x480_2;
++	USHORT SiS_Panel640x480_3;
+ 	USHORT SiS_Panel1152x864;
++	USHORT SiS_PanelCustom;
++	USHORT SiS_PanelBarco1366;
+ 	USHORT SiS_PanelMax;
+ 	USHORT SiS_PanelMinLVDS;
+ 	USHORT SiS_PanelMin301;
+ 	USHORT SiS_ChrontelInit;
+ 	
+-	/* Pointers: */
+ 	const SiS_StStruct          *SiS_SModeIDTable;
+-	const SiS_StandTableStruct  *SiS_StandTable;
++	SiS_StandTableStruct        *SiS_StandTable;
+ 	const SiS_ExtStruct         *SiS_EModeIDTable;
+ 	const SiS_Ext2Struct        *SiS_RefIndex;
+ 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
+@@ -316,7 +367,7 @@ typedef struct _SiS_Private
+ 	const USHORT *pSiS_RGBSenseData;
+ 	const USHORT *pSiS_VideoSenseData;
+ 	const USHORT *pSiS_YCSenseData;
+-	const USHORT *pSiS_RGBSenseData2; /*301b*/
++	const USHORT *pSiS_RGBSenseData2;
+ 	const USHORT *pSiS_VideoSenseData2;
+ 	const USHORT *pSiS_YCSenseData2;
+ #endif
+@@ -340,15 +391,18 @@ typedef struct _SiS_Private
+ 	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
+ 	const SiS_LCDDataStruct  *SiS_NoScaleData1400x1050;
+ 	const SiS_LCDDataStruct  *SiS_NoScaleData1600x1200;
++	const SiS_LCDDataStruct  *SiS_NoScaleData1280x768;
+ 	const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
+ 	const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
++	const SiS_LCDDataStruct  *SiS_StLCD1280x768Data;
+ 	const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
+ 	const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
++	const SiS_LCDDataStruct  *SiS_ExtLCD1280x768Data;
++	const SiS_LCDDataStruct  *SiS_NoScaleData;
+ 	const SiS_TVDataStruct   *SiS_StPALData;
+ 	const SiS_TVDataStruct   *SiS_ExtPALData;
+ 	const SiS_TVDataStruct   *SiS_StNTSCData;
+ 	const SiS_TVDataStruct   *SiS_ExtNTSCData;
+-/*	const SiS_TVDataStruct   *SiS_St1HiTVData;  */
+ 	const SiS_TVDataStruct   *SiS_St2HiTVData;
+ 	const SiS_TVDataStruct   *SiS_ExtHiTVData;
+ 	const UCHAR *SiS_NTSCTiming;
+@@ -381,12 +435,19 @@ typedef struct _SiS_Private
+ 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
+ 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
+ 	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
++	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
+ 	const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
+ 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
+ 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
+ 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
+ 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
+ 	const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
++	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
++	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
++	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_1;
++	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_2;
++	const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_1;
++	const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_2;
+ 	const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
+ 	const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
+ 	const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
+@@ -478,6 +539,12 @@ typedef struct _SiS_Private
+ 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
+ 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
+ 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1_H;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
++	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
+ 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
+ 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
+ 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
+@@ -507,7 +574,6 @@ typedef struct _SiS_Private
+ 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
+ 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
+ 
+-	/* TW: New for 650/301LV */
+ 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+ 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+ 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
+@@ -539,6 +605,9 @@ typedef struct _SiS_Private
+ 	const UCHAR *SiS_CHTVVCLKUPALN;
+ 	const UCHAR *SiS_CHTVVCLKOPALN;
+ 	const UCHAR *SiS_CHTVVCLKSOPAL;
++
++	USHORT  PanelXRes;
++	USHORT  PanelYRes;
+ 	
+ 	BOOLEAN UseCustomMode;
+ 	BOOLEAN CRT1UsesCustomMode;
+@@ -560,8 +629,11 @@ typedef struct _SiS_Private
+ 	UCHAR   CSR2B;
+ 	UCHAR   CSR2C;
+ 	USHORT  CSRClock;
++	USHORT  CSRClock_CRT1;
+ 	USHORT  CModeFlag;
++	USHORT  CModeFlag_CRT1;
+ 	USHORT  CInfoFlag;
++
+ 	BOOLEAN SiS_CHPALM;
+ 	BOOLEAN SiS_CHPALN;
+ 	
+@@ -578,7 +650,21 @@ typedef struct _SiS_Private
+ 	UCHAR Backup_1c;
+ 	UCHAR Backup_1d;
+ 	
+-	int    UsePanelScaler;
++	int     UsePanelScaler;
++
++	USHORT  CP_Vendor, CP_Product;
++	BOOLEAN CP_HaveCustomData;
++	int     CP_PreferredX, CP_PreferredY;
++	int	CP_MaxX, CP_MaxY, CP_MaxClock;
++	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
++    	int     CP_HTotal[7], CP_VTotal[7];
++    	int     CP_HSyncStart[7], CP_VSyncStart[7];
++    	int     CP_HSyncEnd[7], CP_VSyncEnd[7];
++	int     CP_HBlankStart[7], CP_VBlankStart[7];
++	int     CP_HBlankEnd[7], CP_VBlankEnd[7];
++    	int     CP_Clock[7];
++	BOOLEAN CP_DataValid[7];
++	BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+ } SiS_Private;
+ 
+ #endif
+--- linux-2.6.0-test6/drivers/video/skeletonfb.c	2003-06-14 12:17:59.000000000 -0700
++++ 25/drivers/video/skeletonfb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -1,7 +1,7 @@
+ /*
+  * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+  *
+- *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
++ *  Modified to new api Jan 2001 by James Simmons (jsimmons@infradead.org)
+  *
+  *  Created 28 Dec 1997 by Geert Uytterhoeven
+  *
+@@ -469,15 +469,71 @@ void xxxfb_imageblit(struct fb_info *p, 
+ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+ {
+ /*
+- *      @set: 	Which fields we are altering in struct fb_cursor 
++ *      @set: 	 Which fields we are altering in struct fb_cursor
+  *	@enable: Disable or enable the cursor 
+- *      @rop: 	The bit operation we want to do. 
+- *      @mask:  This is the cursor mask bitmap. 
+- *      @dest:  A image of the area we are going to display the cursor.
+- *		Used internally by the driver.	 
+- *      @hot:	The hot spot. 
+- *	@image:	The actual data for the cursor image.
+- */
++ *      @rop: 	 The bit operation we want to do.
++ *      @hot:	 The hot spot.
++ *	@image:	 The actual data for the cursor image.
++ *      @mask:   This is the cursor mask bitmap.
++ */
++
++   /* Disable hardware cursor. We don't want to display the cursor
++      while changing it. Note we use the enable and rop fields in
++      struct fb_cursor that is apart of struct fb_info. Not the
++      cursor data passed in from userland. */
++
++   if (cursor->set & FB_CUR_SETHOT) {
++	info->cursor.hot = cursor->hot;
++   	/* Set the hardware cursor's hot spot  */
++   }
++
++   if (cursor->set & FB_CUR_SETPOS) {
++	info->cursor.image.dx = cursor->image.dx;
++	info->cursor.image.dy = cursor->image.dy;
++   	/* Set the hardware cursor's position */
++   }
++
++   if (cursor->set & FB_CUR_SETSIZE) {
++	info->cursor.image.height = cursor->image.height;
++	info->cursor.image.width = cursor->image.width;
++   	/* Set the hardware cursor's size */
++   }
++
++   if (cursor->set & FB_CUR_SETCMAP) {
++	if (cursor->image.depth == 1) {
++		info->cursor.image.fg_color = cursor->image.fg_color;
++		info->cursor.image.bg_color = cursor->image.bg_color;
++	} else {
++		if (cursor->image.cmap.len)
++			fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
++	}
++	info->curosr.image.depth = cursor->image.depth;
++
++   	/* Set the hardware cursor's color map */
++   }
++
++   /*
++    * Set the cursor shape. The two pieces needed to create
++    * the final image is mask and image.data. The mask is
++    * combined with image.data according to the rop field.
++    */
++   if (cursor->set & FB_CUR_SETSHAPE) {
++ 	switch (info->cursor.rop) {
++	case ROP_XOR:
++		/* ... */
++		break;
++	case ROP_COPY:
++	default:
++		/* ... */
++		break;
++   	}
++	/* ... */
++   }
++
++   if (info->cursor.enable) {
++	/* Now we turn the hardware cursor on */
++   }
++   return 0;
+ }
+ 
+ /**
+--- linux-2.6.0-test6/drivers/video/softcursor.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/video/softcursor.c	2003-10-05 00:34:28.000000000 -0700
+@@ -21,8 +21,13 @@ int soft_cursor(struct fb_info *info, st
+ {
+ 	unsigned int scan_align = info->pixmap.scan_align - 1;
+ 	unsigned int buf_align = info->pixmap.buf_align - 1;
+-	unsigned int i, size, dsize, s_pitch, d_pitch;
+-	u8 *dst, src[64];
++	u8 *dst = (u8 *) info->cursor.image.data;
++	unsigned int i, size, pitch;
++
++	pitch = ((info->cursor.image.width + 7) >> 3) + scan_align;
++	pitch &= ~scan_align;
++	size = pitch * info->cursor.image.height + buf_align;
++	size &= ~buf_align;
+ 
+ 	if (cursor->set & FB_CUR_SETSIZE) {
+ 		info->cursor.image.height = cursor->image.height;
+@@ -48,34 +53,33 @@ int soft_cursor(struct fb_info *info, st
+ 		info->cursor.image.depth = cursor->image.depth;
+ 	}	
+ 
+-	s_pitch = (info->cursor.image.width + 7) >> 3;
+-	dsize = s_pitch * info->cursor.image.height;
+-	d_pitch = (s_pitch + scan_align) & ~scan_align;
+-	size = d_pitch * info->cursor.image.height + buf_align;
+-	size &= ~buf_align;
+-	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+-
+-	if (info->cursor.enable) {
++	if (cursor->set & FB_CUR_SETSHAPE) {
+ 		switch (info->cursor.rop) {
+ 		case ROP_XOR:
+-			for (i = 0; i < dsize; i++)
+-				src[i] = cursor->image.data[i] ^ info->cursor.mask[i]; 
++			for (i = 0; i < size; i++)
++				dst[i] ^= info->cursor.mask[i];
+ 			break;
+ 		case ROP_COPY:
+ 		default:
+-			for (i = 0; i < dsize; i++)
+-				src[i] = cursor->image.data[i] & info->cursor.mask[i];
++			for (i = 0; i < size; i++)
++				dst[i] &= info->cursor.mask[i];
+ 			break;
+ 		}
+-	} else 
+-		memcpy(src, cursor->image.data, dsize);
+-	
+-	move_buf_aligned(info, dst, src, d_pitch, s_pitch, info->cursor.image.height);
+-	info->cursor.image.data = dst;
++	}
+ 	
+-	info->fbops->fb_imageblit(info, &info->cursor.image);
+-	atomic_dec(&info->pixmap.count);
+-	smp_mb__after_atomic_dec();
++	if (!info->cursor.enable) {
++		for (i = 0; i < size; i++)
++			dst[i] ^= info->cursor.mask[i];
++	}
++
++	if (info->cursor.image.data)
++		info->fbops->fb_imageblit(info, &info->cursor.image);
++
++	if (!info->cursor.enable) {
++		for (i = 0; i < size; i++)
++			dst[i] ^= info->cursor.mask[i];
++	}
++
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/drivers/video/sstfb.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/sstfb.c	2003-10-05 00:33:24.000000000 -0700
+@@ -94,7 +94,6 @@
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+ #include <linux/init.h>
+-#include <linux/version.h>
+ #include <linux/slab.h>
+ #include <asm/io.h>
+ #include <asm/ioctl.h>
+--- linux-2.6.0-test6/drivers/video/stifb.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/stifb.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1238,7 +1238,7 @@ stifb_init_fb(struct sti_struct *sti, in
+ 
+ 
+ 	/* get framebuffer physical and virtual base addr & len (64bit ready) */
+-	fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000;
++	fix->smem_start = F_EXTEND(fb->sti->regions_phys[1]);
+ 	fix->smem_len = fb->sti->regions[1].region_desc.length * 4096;
+ 
+ 	fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
+--- linux-2.6.0-test6/drivers/video/valkyriefb.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/drivers/video/valkyriefb.c	2003-10-05 00:34:22.000000000 -0700
+@@ -51,7 +51,6 @@
+ #include <linux/delay.h>
+ #include <linux/interrupt.h>
+ #include <linux/fb.h>
+-#include <linux/selection.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
+ #include <linux/nvram.h>
+--- linux-2.6.0-test6/fs/adfs/super.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/adfs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -18,6 +18,7 @@
+ #include <linux/init.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ 
+ #include <asm/bitops.h>
+ #include <asm/uaccess.h>
+@@ -133,50 +134,56 @@ static void adfs_put_super(struct super_
+ 	sb->s_fs_info = NULL;
+ }
+ 
++enum {Opt_uid, Opt_gid, Opt_ownmask, Opt_othmask, Opt_err};
++
++static match_table_t tokens = {
++	{Opt_uid, "uid=%u"},
++	{Opt_gid, "gid=%u"},
++	{Opt_ownmask, "ownmask=%o"},
++	{Opt_othmask, "othmask=%o"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(struct super_block *sb, char *options)
+ {
+-	char *value, *opt;
++	char *p;
+ 	struct adfs_sb_info *asb = ADFS_SB(sb);
++	int option;
+ 
+ 	if (!options)
+ 		return 0;
+ 
+-	while ((opt = strsep(&options, ",")) != NULL) {
+-		if (!*opt)
++	while ((p = strsep(&options, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		value = strchr(opt, '=');
+-		if (value)
+-			*value++ = '\0';
+ 
+-		if (!strcmp(opt, "uid")) {	/* owner of all files */
+-			if (!value || !*value)
+-				return -EINVAL;
+-			asb->s_uid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		} else
+-		if (!strcmp(opt, "gid")) {	/* group owner of all files */
+-			if (!value || !*value)
+-				return -EINVAL;
+-			asb->s_gid = simple_strtoul(value, &value, 0);
+-			if (*value)
+-				return -EINVAL;
+-		} else
+-		if (!strcmp(opt, "ownmask")) {	/* owner permission mask */
+-			if (!value || !*value)
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_uid:
++			if (match_int(args, &option))
+ 				return -EINVAL;
+-			asb->s_owner_mask = simple_strtoul(value, &value, 8);
+-			if (*value)
++			asb->s_uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(args, &option))
+ 				return -EINVAL;
+-		} else
+-		if (!strcmp(opt, "othmask")) {	/* others permission mask */
+-			if (!value || !*value)
++			asb->s_gid = option;
++			break;
++		case Opt_ownmask:
++			if (match_octal(args, &option))
+ 				return -EINVAL;
+-			asb->s_other_mask = simple_strtoul(value, &value, 8);
+-			if (*value)
++			asb->s_owner_mask = option;
++			break;
++		case Opt_othmask:
++			if (match_octal(args, &option))
+ 				return -EINVAL;
+-		} else {			/* eh? say again. */
+-			printk("ADFS-fs: unrecognised mount option %s\n", opt);
++			asb->s_other_mask = option;
++			break;
++		default:
++			printk("ADFS-fs: unrecognised mount option \"%s\" "
++					"or missing value\n", p);
+ 			return -EINVAL;
+ 		}
+ 	}
+--- linux-2.6.0-test6/fs/affs/file.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/affs/file.c	2003-10-05 00:33:24.000000000 -0700
+@@ -39,7 +39,7 @@ static int affs_grow_extcache(struct ino
+ static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
+ static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
+ static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
+-static ssize_t affs_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);
++static ssize_t affs_file_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos);
+ static int affs_file_open(struct inode *inode, struct file *filp);
+ static int affs_file_release(struct inode *inode, struct file *filp);
+ 
+@@ -491,7 +491,8 @@ affs_getemptyblk_ino(struct inode *inode
+ }
+ 
+ static ssize_t
+-affs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
++affs_file_write(struct file *file, const char __user *buf,
++		size_t count, loff_t *ppos)
+ {
+ 	ssize_t retval;
+ 
+--- linux-2.6.0-test6/fs/affs/super.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/fs/affs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -28,6 +28,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ 
+@@ -142,12 +143,37 @@ static struct super_operations affs_sops
+ 	.remount_fs	= affs_remount,
+ };
+ 
++enum {
++	Opt_bs, Opt_mode, Opt_mufs, Opt_prefix, Opt_protect,
++	Opt_reserved, Opt_root, Opt_setgid, Opt_setuid,
++	Opt_verbose, Opt_volume, Opt_ignore, Opt_err,
++};
++
++static match_table_t tokens = {
++	{Opt_bs, "bs=%d"},
++	{Opt_mode, "mode=%o"},
++	{Opt_mufs, "mufs"},
++	{Opt_prefix, "prefix=%s"},
++	{Opt_protect, "protect"},
++	{Opt_reserved, "reserved=%d"},
++	{Opt_root, "root=%d"},
++	{Opt_setgid, "setgid=%d"},
++	{Opt_setuid, "setuid=%d"},
++	{Opt_verbose, "verbose"},
++	{Opt_volume, "volume=%s"},
++	{Opt_ignore, "grpquota"},
++	{Opt_ignore, "noquota"},
++	{Opt_ignore, "quota"},
++	{Opt_ignore, "usrquota"},
++	{Opt_err, NULL},
++};
++
+ static int
+ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s32 *root,
+ 		int *blocksize, char **prefix, char *volume, unsigned long *mount_opts)
+ {
+-	char	*this_char, *value, *optn;
+-	int	 f;
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
+ 
+ 	/* Fill in defaults */
+ 
+@@ -161,109 +187,85 @@ parse_options(char *options, uid_t *uid,
+ 	*mount_opts = 0;
+ 	if (!options)
+ 		return 1;
+-	while ((this_char = strsep(&options, ",")) != NULL) {
+-		if (!*this_char)
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token, n, option;
++		if (!*p)
+ 			continue;
+-		f = 0;
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+-		if ((optn = "protect") && !strcmp(this_char, optn)) {
+-			if (value)
+-				goto out_inv_arg;
+-			*mount_opts |= SF_IMMUTABLE;
+-		} else if ((optn = "verbose") && !strcmp(this_char, optn)) {
+-			if (value)
+-				goto out_inv_arg;
+-			*mount_opts |= SF_VERBOSE;
+-		} else if ((optn = "mufs") && !strcmp(this_char, optn)) {
+-			if (value)
+-				goto out_inv_arg;
+-			*mount_opts |= SF_MUFS;
+-		} else if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
+-			if (value) {
+-				if (!*value) {
+-					printk("AFFS: Argument for set[ug]id option missing\n");
+-					return 0;
+-				} else {
+-					(f ? *uid : *gid) = simple_strtoul(value,&value,0);
+-					if (*value) {
+-						printk("AFFS: Bad set[ug]id argument\n");
+-						return 0;
+-					}
+-					*mount_opts |= f ? SF_SETUID : SF_SETGID;
+-				}
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_bs:
++			if (match_int(&args[0], &n))
++				return -EINVAL;
++			if (n != 512 && n != 1024 && n != 2048
++			    && n != 4096) {
++				printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
++				return 0;
+ 			}
+-		} else if (!strcmp(this_char,"prefix")) {
+-			optn = "prefix";
+-			if (!value || !*value)
+-				goto out_no_arg;
++			*blocksize = n;
++			break;
++		case Opt_mode:
++			if (match_octal(&args[0], &option))
++				return 1;
++			*mode = option & 0777;
++			*mount_opts |= SF_SETMODE;
++			break;
++		case Opt_mufs:
++			*mount_opts |= SF_MUFS;
++			break;
++		case Opt_prefix:
+ 			if (*prefix) {		/* Free any previous prefix */
+ 				kfree(*prefix);
+ 				*prefix = NULL;
+ 			}
+-			*prefix = kmalloc(strlen(value) + 1,GFP_KERNEL);
++			*prefix = match_strdup(&args[0]);
+ 			if (!*prefix)
+ 				return 0;
+-			strcpy(*prefix,value);
+ 			*mount_opts |= SF_PREFIX;
+-		} else if (!strcmp(this_char,"volume")) {
+-			optn = "volume";
+-			if (!value || !*value)
+-				goto out_no_arg;
+-			strlcpy(volume,value,31);
+-		} else if (!strcmp(this_char,"mode")) {
+-			optn = "mode";
+-			if (!value || !*value)
+-				goto out_no_arg;
+-			*mode = simple_strtoul(value,&value,8) & 0777;
+-			if (*value)
+-				return 0;
+-			*mount_opts |= SF_SETMODE;
+-		} else if (!strcmp(this_char,"reserved")) {
+-			optn = "reserved";
+-			if (!value || !*value)
+-				goto out_no_arg;
+-			*reserved = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 0;
+-		} else if (!strcmp(this_char,"root")) {
+-			optn = "root";
+-			if (!value || !*value)
+-				goto out_no_arg;
+-			*root = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 0;
+-		} else if (!strcmp(this_char,"bs")) {
+-			optn = "bs";
+-			if (!value || !*value)
+-				goto out_no_arg;
+-			*blocksize = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 0;
+-			if (*blocksize != 512 && *blocksize != 1024 && *blocksize != 2048
+-			    && *blocksize != 4096) {
+-				printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
+-				return 0;
+-			}
+-		} else if (!strcmp (this_char, "grpquota")
+-			 || !strcmp (this_char, "noquota")
+-			 || !strcmp (this_char, "quota")
+-			 || !strcmp (this_char, "usrquota"))
+-			 /* Silently ignore the quota options */
+-			;
+-		else {
+-			printk("AFFS: Unrecognized mount option %s\n", this_char);
++			break;
++		case Opt_protect:
++			*mount_opts |= SF_IMMUTABLE;
++			break;
++		case Opt_reserved:
++			if (match_int(&args[0], reserved))
++				return 1;
++			break;
++		case Opt_root:
++			if (match_int(&args[0], root))
++				return 1;
++			break;
++		case Opt_setgid:
++			if (match_int(&args[0], &option))
++				return 1;
++			*gid = option;
++			*mount_opts |= SF_SETGID;
++			break;
++		case Opt_setuid:
++			if (match_int(&args[0], &option))
++				return -EINVAL;
++			*uid = option;
++			*mount_opts |= SF_SETUID;
++			break;
++		case Opt_verbose:
++			*mount_opts |= SF_VERBOSE;
++			break;
++		case Opt_volume: {
++			char *vol = match_strdup(&args[0]);
++			strlcpy(volume, vol, 32);
++			kfree(vol);
++			break;
++		}
++		case Opt_ignore:
++		 	/* Silently ignore the quota options */
++			break;
++		default:
++			printk("AFFS: Unrecognized mount option \"%s\" "
++					"or missing value\n", p);
+ 			return 0;
+ 		}
+ 	}
+ 	return 1;
+-
+-out_no_arg:
+-	printk("AFFS: The %s option requires an argument\n", optn);
+-	return 0;
+-out_inv_arg:
+-	printk("AFFS: Option %s does not take an argument\n", optn);
+-	return 0;
+ }
+ 
+ /* This function definitely needs to be split up. Some fine day I'll
+--- linux-2.6.0-test6/fs/aio.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/aio.c	2003-10-05 00:37:05.000000000 -0700
+@@ -27,6 +27,8 @@
+ #include <linux/aio.h>
+ #include <linux/highmem.h>
+ #include <linux/workqueue.h>
++#include <linux/writeback.h>
++#include <linux/pagemap.h>
+ 
+ #include <asm/kmap_types.h>
+ #include <asm/uaccess.h>
+@@ -38,6 +40,9 @@
+ #define dprintk(x...)	do { ; } while (0)
+ #endif
+ 
++long aio_run = 0; /* for testing only */
++long aio_wakeups = 0; /* for testing only */
++
+ /*------ sysctl variables----*/
+ atomic_t aio_nr = ATOMIC_INIT(0);	/* current system wide number of aio requests */
+ unsigned aio_max_nr = 0x10000;	/* system wide maximum number of aio requests */
+@@ -47,6 +52,7 @@ static kmem_cache_t	*kiocb_cachep;
+ static kmem_cache_t	*kioctx_cachep;
+ 
+ static struct workqueue_struct *aio_wq;
++static struct workqueue_struct *aio_fput_wq;
+ 
+ /* Used for rare fput completion. */
+ static void aio_fput_routine(void *);
+@@ -74,6 +80,7 @@ static int __init aio_setup(void)
+ 		panic("unable to create kioctx cache");
+ 
+ 	aio_wq = create_workqueue("aio");
++	aio_fput_wq = create_workqueue("aio_fput");
+ 
+ 	pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
+ 
+@@ -281,6 +288,7 @@ static void aio_cancel_all(struct kioctx
+ 		struct kiocb *iocb = list_kiocb(pos);
+ 		list_del_init(&iocb->ki_list);
+ 		cancel = iocb->ki_cancel;
++		kiocbSetCancelled(iocb);
+ 		if (cancel) {
+ 			iocb->ki_users++;
+ 			spin_unlock_irq(&ctx->ctx_lock);
+@@ -341,6 +349,11 @@ void exit_aio(struct mm_struct *mm)
+ 		aio_cancel_all(ctx);
+ 
+ 		wait_for_all_aios(ctx);
++		/*
++		 * this is an overkill, but ensures we don't leave
++		 * the ctx on the aio_wq
++		 */
++		flush_workqueue(aio_wq);
+ 
+ 		if (1 != atomic_read(&ctx->users))
+ 			printk(KERN_DEBUG
+@@ -395,6 +408,7 @@ static struct kiocb *__aio_get_req(struc
+ 	req->ki_cancel = NULL;
+ 	req->ki_retry = NULL;
+ 	req->ki_user_obj = NULL;
++	INIT_LIST_HEAD(&req->ki_run_list);
+ 
+ 	/* Check if the completion queue has enough free space to
+ 	 * accept an event from this io.
+@@ -494,7 +508,7 @@ static int __aio_put_req(struct kioctx *
+ 		spin_lock(&fput_lock);
+ 		list_add(&req->ki_list, &fput_head);
+ 		spin_unlock(&fput_lock);
+-		queue_work(aio_wq, &fput_work);
++		queue_work(aio_fput_wq, &fput_work);
+ 	} else
+ 		really_put_req(ctx, req);
+ 	return 1;
+@@ -536,65 +550,307 @@ struct kioctx *lookup_ioctx(unsigned lon
+ 	return ioctx;
+ }
+ 
++/*
++ * use_mm
++ * 	Makes the calling kernel thread take on the specified
++ * 	mm context.
++ * 	Called by the retry thread execute retries within the
++ * 	iocb issuer's mm context, so that copy_from/to_user
++ * 	operations work seamlessly for aio.
++ * 	(Note: this routine is intended to be called only
++ * 	from a kernel thread context)
++ */
+ static void use_mm(struct mm_struct *mm)
+ {
+-	struct mm_struct *active_mm = current->active_mm;
++	struct mm_struct *active_mm;
++	struct task_struct *tsk = current;
++
++	task_lock(tsk);
++	active_mm = tsk->active_mm;
+ 	atomic_inc(&mm->mm_count);
+-	current->mm = mm;
+-	if (mm != active_mm) {
+-		current->active_mm = mm;
+-		activate_mm(active_mm, mm);
+-	}
++	tsk->mm = mm;
++	tsk->active_mm = mm;
++	activate_mm(active_mm, mm);
++	task_unlock(tsk);
++
+ 	mmdrop(active_mm);
+ }
+ 
+-static void unuse_mm(struct mm_struct *mm)
++/*
++ * unuse_mm
++ * 	Reverses the effect of use_mm, i.e. releases the
++ * 	specified mm context which was earlier taken on
++ * 	by the calling kernel thread
++ * 	(Note: this routine is intended to be called only
++ * 	from a kernel thread context)
++ *
++ * Comments: Called with ctx->ctx_lock held. This nests
++ * task_lock instead ctx_lock.
++ */
++void unuse_mm(struct mm_struct *mm)
+ {
+-	current->mm = NULL;
++	struct task_struct *tsk = current;
++
++	task_lock(tsk);
++	tsk->mm = NULL;
+ 	/* active_mm is still 'mm' */
+-	enter_lazy_tlb(mm, current);
++	enter_lazy_tlb(mm, tsk);
++	task_unlock(tsk);
+ }
+ 
+-/* Run on kevent's context.  FIXME: needs to be per-cpu and warn if an
+- * operation blocks.
++/*
++ * Queue up a kiocb to be retried. Assumes that the kiocb
++ * has already been marked as kicked, and places it on
++ * the retry run list for the corresponding ioctx, if it
++ * isn't already queued. Returns 1 if it actually queued
++ * the kiocb (to tell the caller to activate the work
++ * queue to process it), or 0, if it found that it was
++ * already queued.
++ *
++ * Should be called with the spin lock iocb->ki_ctx->ctx_lock
++ * held
+  */
+-static void aio_kick_handler(void *data)
++static inline int __queue_kicked_iocb(struct kiocb *iocb)
+ {
+-	struct kioctx *ctx = data;
++	struct kioctx	*ctx = iocb->ki_ctx;
+ 
+-	use_mm(ctx->mm);
++	if (list_empty(&iocb->ki_run_list)) {
++		list_add_tail(&iocb->ki_run_list,
++			&ctx->run_list);
++		iocb->ki_queued++;
++		return 1;
++	}
++	return 0;
++}
+ 
+-	spin_lock_irq(&ctx->ctx_lock);
+-	while (!list_empty(&ctx->run_list)) {
+-		struct kiocb *iocb;
+-		long ret;
++/* aio_run_iocb
++ * 	 This is the core aio execution routine. It is
++ * 	 invoked both for initial i/o submission and
++ * 	 subsequent retries via the aio_kick_handler.
++ *       Expects to be invoked with iocb->ki_ctx->lock
++ *       already held. The lock is released and reaquired
++ *       as needed during processing.
++ *
++ * Calls the iocb retry method (already setup for the
++ * iocb on initial submission) for operation specific
++ * handling, but takes care of most of common retry
++ * execution details for a given iocb. The retry method
++ * needs to be non-blocking as far as possible, to avoid
++ * holding up other iocbs waiting to be serviced by the
++ * retry kernel thread.
++ *
++ * The trickier parts in this code have to do with
++ * ensuring that only one retry instance is in progress
++ * for a given iocb at any time. Providing that guarantee
++ * simplifies the coding of individual aio operations as
++ * it avoids various potential races.
++ */
++static ssize_t aio_run_iocb(struct kiocb *iocb)
++{
++	struct kioctx	*ctx = iocb->ki_ctx;
++	ssize_t (*retry)(struct kiocb *);
++	ssize_t ret;
+ 
+-		iocb = list_entry(ctx->run_list.next, struct kiocb,
+-				  ki_run_list);
+-		list_del(&iocb->ki_run_list);
+-		iocb->ki_users ++;
+-		spin_unlock_irq(&ctx->ctx_lock);
++	if (iocb->ki_retried++ > 1024*1024) {
++		printk("Maximal retry count.  Bytes done %Zd\n",
++			iocb->ki_nbytes - iocb->ki_left);
++		return -EAGAIN;
++	}
++
++	if (!(iocb->ki_retried & 0xff)) {
++		pr_debug("%ld retry: %d of %d (kick %ld, Q %ld run %ld, wake %ld)\n",
++			iocb->ki_retried,
++			iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++			iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++	}
++
++	if (!(retry = iocb->ki_retry)) {
++		printk("aio_run_iocb: iocb->ki_retry = NULL\n");
++		return 0;
++	}
++
++	/*
++	 * We don't want the next retry iteration for this
++	 * operation to start until this one has returned and
++	 * updated the iocb state. However, wait_queue functions
++	 * can trigger a kick_iocb from interrupt context in the
++	 * meantime, indicating that data is available for the next
++	 * iteration. We want to remember that and enable the
++	 * next retry iteration _after_ we are through with
++	 * this one.
++	 *
++	 * So, in order to be able to register a "kick", but
++	 * prevent it from being queued now, we clear the kick
++	 * flag, but make the kick code *think* that the iocb is
++	 * still on the run list until we are actually done.
++	 * When we are done with this iteration, we check if
++	 * the iocb was kicked in the meantime and if so, queue
++	 * it up afresh.
++	 */
++
++	kiocbClearKicked(iocb);
++
++	/*
++	 * This is so that aio_complete knows it doesn't need to
++	 * pull the iocb off the run list (We can't just call
++	 * INIT_LIST_HEAD because we don't want a kick_iocb to
++	 * queue this on the run list yet)
++	 */
++	iocb->ki_run_list.next = iocb->ki_run_list.prev = NULL;
++	iocb->ki_retry = NULL;
++	spin_unlock_irq(&ctx->ctx_lock);
++
++	/* Quit retrying if the i/o has been cancelled */
++	if (kiocbIsCancelled(iocb)) {
++		ret = -EINTR;
++		aio_complete(iocb, ret, 0);
++		/* must not access the iocb after this */
++		goto out;
++	}
++
++	/*
++	 * Now we are all set to call the retry method in async
++	 * context. By setting this thread's io_wait context
++	 * to point to the wait queue entry inside the currently
++	 * running iocb for the duration of the retry, we ensure
++	 * that async notification wakeups are queued by the
++	 * operation instead of blocking waits, and when notified,
++	 * cause the iocb to be kicked for continuation (through
++	 * the aio_wake_function callback).
++	 */
++	BUG_ON(current->io_wait != NULL);
++	current->io_wait = &iocb->ki_wait;
++	ret = retry(iocb);
++	current->io_wait = NULL;
+ 
+-		kiocbClearKicked(iocb);
+-		ret = iocb->ki_retry(iocb);
++	if (-EIOCBRETRY != ret) {
+ 		if (-EIOCBQUEUED != ret) {
++			BUG_ON(!list_empty(&iocb->ki_wait.task_list));
+ 			aio_complete(iocb, ret, 0);
+-			iocb = NULL;
++			/* must not access the iocb after this */
+ 		}
++	} else {
++		/*
++		 * Issue an additional retry to avoid waiting forever if
++		 * no waits were queued (e.g. in case of a short read).
++		 */
++		if (list_empty(&iocb->ki_wait.task_list))
++			kiocbSetKicked(iocb);
++	}
++out:
++	spin_lock_irq(&ctx->ctx_lock);
+ 
+-		spin_lock_irq(&ctx->ctx_lock);
+-		if (NULL != iocb)
+-			__aio_put_req(ctx, iocb);
++	if (-EIOCBRETRY == ret) {
++		/*
++		 * OK, now that we are done with this iteration
++		 * and know that there is more left to go,
++		 * this is where we let go so that a subsequent
++		 * "kick" can start the next iteration
++		 */
++		iocb->ki_retry = retry;
++		/* will make __queue_kicked_iocb succeed from here on */
++		INIT_LIST_HEAD(&iocb->ki_run_list);
++		/* we must queue the next iteration ourselves, if it
++		 * has already been kicked */
++		if (kiocbIsKicked(iocb)) {
++			__queue_kicked_iocb(iocb);
++		}
+ 	}
++	return ret;
++}
++
++/*
++ * __aio_run_iocbs:
++ * 	Process all pending retries queued on the ioctx
++ * 	run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context. Expects to be called with ctx->ctx_lock held
++ */
++static void __aio_run_iocbs(struct kioctx *ctx)
++{
++	struct kiocb *iocb;
++	int count = 0;
++
++	while (!list_empty(&ctx->run_list)) {
++		iocb = list_entry(ctx->run_list.next, struct kiocb,
++			ki_run_list);
++		list_del(&iocb->ki_run_list);
++		/*
++		 * Hold an extra reference while retrying i/o.
++		 */
++		iocb->ki_users++;	/* grab extra reference */
++		aio_run_iocb(iocb);
++		if (__aio_put_req(ctx, iocb))  /* drop extra ref */
++			put_ioctx(ctx);
++		count++;
++	}
++	aio_run++;
++}
++
++/*
++ * aio_run_iocbs:
++ * 	Process all pending retries queued on the ioctx
++ * 	run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context.
++ */
++static inline void aio_run_iocbs(struct kioctx *ctx)
++{
++	spin_lock_irq(&ctx->ctx_lock);
++	__aio_run_iocbs(ctx);
+ 	spin_unlock_irq(&ctx->ctx_lock);
++}
++
++/*
++ * aio_kick_handler:
++ * 	Work queue handler triggered to process pending
++ * 	retries on an ioctx. Takes on the aio issuer's
++ * 	mm context before running the iocbs.
++ * Run on aiod's context.
++ */
++static void aio_kick_handler(void *data)
++{
++	struct kioctx *ctx = data;
+ 
++	use_mm(ctx->mm);
++	spin_lock_irq(&ctx->ctx_lock);
++	__aio_run_iocbs(ctx);
+ 	unuse_mm(ctx->mm);
++	spin_unlock_irq(&ctx->ctx_lock);
+ }
+ 
+-void kick_iocb(struct kiocb *iocb)
++
++/*
++ * Called by kick_iocb to queue the kiocb for retry
++ * and if required activate the aio work queue to process
++ * it
++ */
++void queue_kicked_iocb(struct kiocb *iocb)
+ {
+ 	struct kioctx	*ctx = iocb->ki_ctx;
++	unsigned long flags;
++	int run = 0;
+ 
++	WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
++
++	spin_lock_irqsave(&ctx->ctx_lock, flags);
++	run = __queue_kicked_iocb(iocb);
++	spin_unlock_irqrestore(&ctx->ctx_lock, flags);
++	if (run) {
++		queue_work(aio_wq, &ctx->wq);
++		aio_wakeups++;
++	}
++}
++
++/*
++ * kick_iocb:
++ * 	Called typically from a wait queue callback context
++ * 	(aio_wake_function) to trigger a retry of the iocb.
++ * 	The retry is usually executed by aio workqueue
++ * 	threads (See aio_kick_handler).
++ */
++void kick_iocb(struct kiocb *iocb)
++{
+ 	/* sync iocbs are easy: they can only ever be executing from a 
+ 	 * single context. */
+ 	if (is_sync_kiocb(iocb)) {
+@@ -603,12 +859,10 @@ void kick_iocb(struct kiocb *iocb)
+ 		return;
+ 	}
+ 
++	iocb->ki_kicked++;
++	/* If its already kicked we shouldn't queue it again */
+ 	if (!kiocbTryKick(iocb)) {
+-		unsigned long flags;
+-		spin_lock_irqsave(&ctx->ctx_lock, flags);
+-		list_add_tail(&iocb->ki_run_list, &ctx->run_list);
+-		spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+-		schedule_work(&ctx->wq);
++		queue_kicked_iocb(iocb);
+ 	}
+ }
+ 
+@@ -661,6 +915,9 @@ int aio_complete(struct kiocb *iocb, lon
+ 	 */
+ 	spin_lock_irqsave(&ctx->ctx_lock, flags);
+ 
++	if (iocb->ki_run_list.prev && !list_empty(&iocb->ki_run_list))
++		list_del_init(&iocb->ki_run_list);
++
+ 	ring = kmap_atomic(info->ring_pages[0], KM_IRQ1);
+ 
+ 	tail = info->tail;
+@@ -689,6 +946,11 @@ int aio_complete(struct kiocb *iocb, lon
+ 
+ 	pr_debug("added to ring %p at [%lu]\n", iocb, tail);
+ 
++	pr_debug("%ld retries: %d of %d (kicked %ld, Q %ld run %ld wake %ld)\n",
++		iocb->ki_retried,
++		iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++		iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++
+ 	/* everything turned out well, dispose of the aiocb. */
+ 	ret = __aio_put_req(ctx, iocb);
+ 
+@@ -803,6 +1065,7 @@ static int read_events(struct kioctx *ct
+ 	int			i = 0;
+ 	struct io_event		ent;
+ 	struct timeout		to;
++	int 			event_loop = 0; /* testing only */
+ 
+ 	/* needed to zero any padding within an entry (there shouldn't be 
+ 	 * any, but C is fun!
+@@ -852,7 +1115,6 @@ static int read_events(struct kioctx *ct
+ 		add_wait_queue_exclusive(&ctx->wait, &wait);
+ 		do {
+ 			set_task_state(tsk, TASK_INTERRUPTIBLE);
+-
+ 			ret = aio_read_evt(ctx, &ent);
+ 			if (ret)
+ 				break;
+@@ -862,6 +1124,7 @@ static int read_events(struct kioctx *ct
+ 			if (to.timed_out)	/* Only check after read evt */
+ 				break;
+ 			schedule();
++			event_loop++;
+ 			if (signal_pending(tsk)) {
+ 				ret = -EINTR;
+ 				break;
+@@ -889,6 +1152,9 @@ static int read_events(struct kioctx *ct
+ 	if (timeout)
+ 		clear_timeout(&to);
+ out:
++	pr_debug("event loop executed %d times\n", event_loop);
++	pr_debug("aio_run %ld\n", aio_run);
++	pr_debug("aio_wakeups %ld\n", aio_wakeups);
+ 	return i ? i : ret;
+ }
+ 
+@@ -918,6 +1184,11 @@ static void io_destroy(struct kioctx *io
+ 
+ 	aio_cancel_all(ioctx);
+ 	wait_for_all_aios(ioctx);
++	/*
++	 * this is an overkill, but ensures we don't leave
++	 * the ctx on the aio_wq
++	 */
++	flush_workqueue(aio_wq);
+ 	put_ioctx(ioctx);	/* once for the lookup */
+ }
+ 
+@@ -980,13 +1251,192 @@ asmlinkage long sys_io_destroy(aio_conte
+ 	return -EINVAL;
+ }
+ 
++/*
++ * Retry method for aio_read (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pread(struct kiocb *iocb)
++{
++	struct file *file = iocb->ki_filp;
++	ssize_t ret = 0;
++
++	ret = file->f_op->aio_read(iocb, iocb->ki_buf,
++		iocb->ki_left, iocb->ki_pos);
++
++	/*
++	 * Can't just depend on iocb->ki_left to determine
++	 * whether we are done. This may have been a short read.
++	 */
++	if (ret > 0) {
++		iocb->ki_buf += ret;
++		iocb->ki_left -= ret;
++
++		ret = -EIOCBRETRY;
++	}
++
++	/* This means we must have transferred all that we could */
++	/* No need to retry anymore */
++	if ((ret == 0) || (iocb->ki_left == 0))
++		ret = iocb->ki_nbytes - iocb->ki_left;
++
++	return ret;
++}
++
++/*
++ * Retry method for aio_write (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pwrite(struct kiocb *iocb)
++{
++	struct file *file = iocb->ki_filp;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	ssize_t ret = 0;
++
++	ret = file->f_op->aio_write(iocb, iocb->ki_buf,
++				iocb->ki_left, iocb->ki_pos);
++
++	/*
++	 * Even if iocb->ki_left = 0, we may need to wait
++	 * for a balance_dirty_pages to complete
++	 */
++	if (ret > 0) {
++		iocb->ki_buf += iocb->ki_buf ? ret : 0;
++		iocb->ki_left -= ret;
++
++		ret = -EIOCBRETRY;
++	}
++
++	/* This means we must have transferred all that we could */
++	/* No need to retry anymore unless we need to osync data */
++	if (ret == 0) {
++		ret = iocb->ki_nbytes - iocb->ki_left;
++		if (!iocb->ki_buf)
++			return ret;
++
++		/* Set things up for potential O_SYNC */
++		if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++			iocb->ki_buf = NULL;
++			iocb->ki_pos -= ret; /* back up fpos */
++			iocb->ki_left = ret; /* sync what we have written out */
++			iocb->ki_nbytes = ret;
++			ret = -EIOCBRETRY;
++		}
++	}
++
++	return ret;
++}
++
++static ssize_t aio_fdsync(struct kiocb *iocb)
++{
++	struct file *file = iocb->ki_filp;
++	ssize_t ret = -EINVAL;
++
++	if (file->f_op->aio_fsync)
++		ret = file->f_op->aio_fsync(iocb, 1);
++	return ret;
++}
++
++static ssize_t aio_fsync(struct kiocb *iocb)
++{
++	struct file *file = iocb->ki_filp;
++	ssize_t ret = -EINVAL;
++
++	if (file->f_op->aio_fsync)
++		ret = file->f_op->aio_fsync(iocb, 0);
++	return ret;
++}
++
++/*
++ * aio_setup_iocb:
++ *	Performs the initial checks and aio retry method
++ *	setup for the kiocb at the time of io submission.
++ */
++ssize_t aio_setup_iocb(struct kiocb *kiocb)
++{
++	struct file *file = kiocb->ki_filp;
++	ssize_t ret = 0;
++
++	switch (kiocb->ki_opcode) {
++	case IOCB_CMD_PREAD:
++		ret = -EBADF;
++		if (unlikely(!(file->f_mode & FMODE_READ)))
++			break;
++		ret = -EFAULT;
++		if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
++			kiocb->ki_left)))
++			break;
++		ret = -EINVAL;
++		if (file->f_op->aio_read)
++			kiocb->ki_retry = aio_pread;
++		break;
++	case IOCB_CMD_PWRITE:
++		ret = -EBADF;
++		if (unlikely(!(file->f_mode & FMODE_WRITE)))
++			break;
++		ret = -EFAULT;
++		if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
++			kiocb->ki_left)))
++			break;
++		ret = -EINVAL;
++		if (file->f_op->aio_write)
++			kiocb->ki_retry = aio_pwrite;
++		break;
++	case IOCB_CMD_FDSYNC:
++		ret = -EINVAL;
++		if (file->f_op->aio_fsync)
++			kiocb->ki_retry = aio_fdsync;
++		break;
++	case IOCB_CMD_FSYNC:
++		ret = -EINVAL;
++		if (file->f_op->aio_fsync)
++			kiocb->ki_retry = aio_fsync;
++		break;
++	default:
++		dprintk("EINVAL: io_submit: no operation provided\n");
++		ret = -EINVAL;
++	}
++
++	if (!kiocb->ki_retry)
++		return ret;
++
++	return 0;
++}
++
++/*
++ * aio_wake_function:
++ * 	wait queue callback function for aio notification,
++ * 	Simply triggers a retry of the operation via kick_iocb.
++ *
++ * 	This callback is specified in the wait queue entry in
++ *	a kiocb	(current->io_wait points to this wait queue
++ *	entry when an aio operation executes; it is used
++ * 	instead of a synchronous wait when an i/o blocking
++ *	condition is encountered during aio).
++ *
++ * Note:
++ * This routine is executed with the wait queue lock held.
++ * Since kick_iocb acquires iocb->ctx->ctx_lock, it nests
++ * the ioctx lock inside the wait queue lock. This is safe
++ * because this callback isn't used for wait queues which
++ * are nested inside ioctx lock (i.e. ctx->wait)
++ */
++int aio_wake_function(wait_queue_t *wait, unsigned mode, int sync)
++{
++	struct kiocb *iocb = container_of(wait, struct kiocb, ki_wait);
++
++	list_del_init(&wait->task_list);
++	kick_iocb(iocb);
++	return 1;
++}
++
+ int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
+ 			 struct iocb *iocb)
+ {
+ 	struct kiocb *req;
+ 	struct file *file;
+ 	ssize_t ret;
+-	char *buf;
++	int need_putctx;
+ 
+ 	/* enforce forwards compatibility on users */
+ 	if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
+@@ -1027,51 +1477,41 @@ int io_submit_one(struct kioctx *ctx, st
+ 	req->ki_user_data = iocb->aio_data;
+ 	req->ki_pos = iocb->aio_offset;
+ 
+-	buf = (char *)(unsigned long)iocb->aio_buf;
++	req->ki_buf = (char *)(unsigned long)iocb->aio_buf;
++	req->ki_left = req->ki_nbytes = iocb->aio_nbytes;
++	req->ki_opcode = iocb->aio_lio_opcode;
++	init_waitqueue_func_entry(&req->ki_wait, aio_wake_function);
++	INIT_LIST_HEAD(&req->ki_wait.task_list);
++	req->ki_run_list.next = req->ki_run_list.prev = NULL;
++	req->ki_retry = NULL;
++	req->ki_retried = 0;
++	req->ki_kicked = 0;
++	req->ki_queued = 0;
++	aio_run = 0;
++	aio_wakeups = 0;
+ 
+-	switch (iocb->aio_lio_opcode) {
+-	case IOCB_CMD_PREAD:
+-		ret = -EBADF;
+-		if (unlikely(!(file->f_mode & FMODE_READ)))
+-			goto out_put_req;
+-		ret = -EFAULT;
+-		if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
+-			goto out_put_req;
+-		ret = -EINVAL;
+-		if (file->f_op->aio_read)
+-			ret = file->f_op->aio_read(req, buf,
+-					iocb->aio_nbytes, req->ki_pos);
+-		break;
+-	case IOCB_CMD_PWRITE:
+-		ret = -EBADF;
+-		if (unlikely(!(file->f_mode & FMODE_WRITE)))
+-			goto out_put_req;
+-		ret = -EFAULT;
+-		if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
+-			goto out_put_req;
+-		ret = -EINVAL;
+-		if (file->f_op->aio_write)
+-			ret = file->f_op->aio_write(req, buf,
+-					iocb->aio_nbytes, req->ki_pos);
+-		break;
+-	case IOCB_CMD_FDSYNC:
+-		ret = -EINVAL;
+-		if (file->f_op->aio_fsync)
+-			ret = file->f_op->aio_fsync(req, 1);
+-		break;
+-	case IOCB_CMD_FSYNC:
+-		ret = -EINVAL;
+-		if (file->f_op->aio_fsync)
+-			ret = file->f_op->aio_fsync(req, 0);
+-		break;
+-	default:
+-		dprintk("EINVAL: io_submit: no operation provided\n");
+-		ret = -EINVAL;
+-	}
++	ret = aio_setup_iocb(req);
++
++	if (ret)
++		goto out_put_req;
++
++	spin_lock_irq(&ctx->ctx_lock);
++	/*
++	 * Hold an extra reference while submitting the i/o.
++	 * This prevents races between the aio code path referencing the
++	 * req (after submitting it) and aio_complete() freeing the req.
++	 */
++	req->ki_users++;			/* grab extra reference */
++	ret = aio_run_iocb(req);
++	need_putctx = __aio_put_req(ctx, req);	/* drop the extra reference */
++	spin_unlock_irq(&ctx->ctx_lock);
++
++	if (-EIOCBRETRY == ret)
++		queue_work(aio_wq, &ctx->wq);
++
++	if (need_putctx)
++		put_ioctx(ctx);
+ 
+-	if (likely(-EIOCBQUEUED == ret))
+-		return 0;
+-	aio_complete(req, ret, 0);
+ 	return 0;
+ 
+ out_put_req:
+--- linux-2.6.0-test6/fs/autofs4/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/autofs4/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/file.h>
+ #include <linux/pagemap.h>
++#include <linux/parser.h>
+ #include <asm/bitops.h>
+ #include "autofs_i.h"
+ #include <linux/module.h>
+@@ -94,11 +95,25 @@ static struct super_operations autofs4_s
+ 	.statfs		= simple_statfs,
+ };
+ 
++enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
++
++static match_table_t tokens = {
++	{Opt_fd, "fd=%d"},
++	{Opt_uid, "uid=%d"},
++	{Opt_gid, "gid=%d"},
++	{Opt_pgrp, "pgrp=%d"},
++	{Opt_minproto, "minproto=%d"},
++	{Opt_maxproto, "maxproto=%d"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
+ 			 pid_t *pgrp, int *minproto, int *maxproto)
+ {
+-	char *this_char, *value;
+-	
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
++	int option;
++
+ 	*uid = current->uid;
+ 	*gid = current->gid;
+ 	*pgrp = process_group(current);
+@@ -108,55 +123,48 @@ static int parse_options(char *options, 
+ 
+ 	*pipefd = -1;
+ 
+-	if ( !options ) return 1;
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++	if (!options)
++		return 1;
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp(this_char,"fd")) {
+-			if (!value || !*value)
+-				return 1;
+-			*pipefd = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"uid")) {
+-			if (!value || !*value)
+-				return 1;
+-			*uid = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"gid")) {
+-			if (!value || !*value)
+-				return 1;
+-			*gid = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"pgrp")) {
+-			if (!value || !*value)
+-				return 1;
+-			*pgrp = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"minproto")) {
+-			if (!value || !*value)
+-				return 1;
+-			*minproto = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"maxproto")) {
+-			if (!value || !*value)
+-				return 1;
+-			*maxproto = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_fd:
++			if (match_int(args, pipefd))
++				return 1;
++			break;
++		case Opt_uid:
++			if (match_int(args, &option))
++				return 1;
++			*uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(args, &option))
++				return 1;
++			*gid = option;
++			break;
++		case Opt_pgrp:
++			if (match_int(args, &option))
++				return 1;
++			*pgrp = option;
++			break;
++		case Opt_minproto:
++			if (match_int(args, &option))
++				return 1;
++			*minproto = option;
++			break;
++		case Opt_maxproto:
++			if (match_int(args, &option))
++				return 1;
++			*maxproto = option;
++			break;
++		default:
++			return 1;
+ 		}
+-		else break;
+ 	}
+ 	return (*pipefd < 0);
+ }
+--- linux-2.6.0-test6/fs/autofs/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/autofs/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -14,6 +14,7 @@
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/file.h>
++#include <linux/parser.h>
+ #include <asm/bitops.h>
+ #include "autofs_i.h"
+ #include <linux/module.h>
+@@ -45,10 +46,24 @@ static struct super_operations autofs_so
+ 	.statfs		= simple_statfs,
+ };
+ 
++enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
++
++static match_table_t autofs_tokens = {
++	{Opt_fd, "fd=%d"},
++	{Opt_uid, "uid=%d"},
++	{Opt_gid, "gid=%d"},
++	{Opt_pgrp, "pgrp=%d"},
++	{Opt_minproto, "minproto=%d"},
++	{Opt_maxproto, "maxproto=%d"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
+ {
+-	char *this_char, *value;
+-	
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
++	int option;
++
+ 	*uid = current->uid;
+ 	*gid = current->gid;
+ 	*pgrp = process_group(current);
+@@ -57,55 +72,49 @@ static int parse_options(char *options, 
+ 
+ 	*pipefd = -1;
+ 
+-	if ( !options ) return 1;
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++	if (!options)
++		return 1;
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp(this_char,"fd")) {
+-			if (!value || !*value)
+-				return 1;
+-			*pipefd = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"uid")) {
+-			if (!value || !*value)
+-				return 1;
+-			*uid = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"gid")) {
+-			if (!value || !*value)
+-				return 1;
+-			*gid = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"pgrp")) {
+-			if (!value || !*value)
+-				return 1;
+-			*pgrp = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"minproto")) {
+-			if (!value || !*value)
+-				return 1;
+-			*minproto = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
+-		}
+-		else if (!strcmp(this_char,"maxproto")) {
+-			if (!value || !*value)
+-				return 1;
+-			*maxproto = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 1;
++
++		token = match_token(p, autofs_tokens, args);
++		switch (token) {
++		case Opt_fd:
++			if (match_int(&args[0], &option))
++				return 1;
++			*pipefd = option;
++			break;
++		case Opt_uid:
++			if (match_int(&args[0], &option))
++				return 1;
++			*uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(&args[0], &option))
++				return 1;
++			*gid = option;
++			break;
++		case Opt_pgrp:
++			if (match_int(&args[0], &option))
++				return 1;
++			*pgrp = option;
++			break;
++		case Opt_minproto:
++			if (match_int(&args[0], &option))
++				return 1;
++			*minproto = option;
++			break;
++		case Opt_maxproto:
++			if (match_int(&args[0], &option))
++				return 1;
++			*maxproto = option;
++			break;
++		default:
++			return 1;
+ 		}
+-		else break;
+ 	}
+ 	return (*pipefd < 0);
+ }
+--- linux-2.6.0-test6/fs/befs/linuxvfs.c	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/befs/linuxvfs.c	2003-10-05 00:33:24.000000000 -0700
+@@ -13,6 +13,7 @@
+ #include <linux/nls.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ 
+ #include "befs.h"
+ #include "btree.h"
+@@ -39,7 +40,7 @@ static struct inode *befs_alloc_inode(st
+ static void befs_destroy_inode(struct inode *inode);
+ static int befs_init_inodecache(void);
+ static void befs_destroy_inodecache(void);
+-static int befs_readlink(struct dentry *, char *, int);
++static int befs_readlink(struct dentry *, char __user *, int);
+ static int befs_follow_link(struct dentry *, struct nameidata *nd);
+ static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
+ 			char **out, int *out_len);
+@@ -494,7 +495,7 @@ befs_follow_link(struct dentry *dentry, 
+ }
+ 
+ static int
+-befs_readlink(struct dentry *dentry, char *buffer, int buflen)
++befs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+ 	struct super_block *sb = dentry->d_sb;
+ 	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
+@@ -667,12 +668,27 @@ befs_nls2utf(struct super_block *sb, con
+ 	return -EILSEQ;
+ }
+ 
++/**
++ * Use the
++ *
++ */
++enum {
++	Opt_uid, Opt_gid, Opt_charset, Opt_debug,
++};
++
++static match_table_t befs_tokens = {
++	{Opt_uid, "uid=%d"},
++	{Opt_gid, "gid=%d"},
++	{Opt_charset, "iocharset=%s"},
++	{Opt_debug, "debug"}
++};
++
+ static int
+ parse_options(char *options, befs_mount_options * opts)
+ {
+-	char *this_char;
+-	char *value;
+-	int ret = 1;
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
++	int option;
+ 
+ 	/* Initialize options */
+ 	opts->uid = 0;
+@@ -683,64 +699,56 @@ parse_options(char *options, befs_mount_
+ 	opts->debug = 0;
+ 
+ 	if (!options)
+-		return ret;
+-
+-	while ((this_char = strsep(&options, ",")) != NULL) {
+-
+-		if ((value = strchr(this_char, '=')) != NULL)
+-			*value++ = 0;
++		return 1;
+ 
+-		if (!strcmp(this_char, "uid")) {
+-			if (!value || !*value) {
+-				ret = 0;
+-			} else {
+-				opts->uid = simple_strtoul(value, &value, 0);
+-				opts->use_uid = 1;
+-				if (*value) {
+-					printk(KERN_ERR "BEFS: Invalid uid "
+-					       "option: %s\n", value);
+-					ret = 0;
+-				}
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token;
++		if (!*p)
++			continue;
++
++		token = match_token(p, befs_tokens, args);
++		switch (token) {
++		case Opt_uid:
++			if (match_int(&args[0], &option))
++				return 0;
++			if (option < 0) {
++				printk(KERN_ERR "BeFS: Invalid uid %d, "
++						"using default\n", option);
++				break;
+ 			}
+-		} else if (!strcmp(this_char, "gid")) {
+-			if (!value || !*value)
+-				ret = 0;
+-			else {
+-				opts->gid = simple_strtoul(value, &value, 0);
+-				opts->use_gid = 1;
+-				if (*value) {
+-					printk(KERN_ERR
+-					       "BEFS: Invalid gid option: "
+-					       "%s\n", value);
+-					ret = 0;
+-				}
++			opts->uid = option;
++			opts->use_uid = 1;
++			break;
++		case Opt_gid:
++			if (match_int(&args[0], &option))
++				return 0;
++			if (option < 0) {
++				printk(KERN_ERR "BeFS: Invalid gid %d, "
++						"using default\n", option);
++				break;
+ 			}
+-		} else if (!strcmp(this_char, "iocharset") && value) {
+-			char *p = value;
+-			int len;
+-
+-			while (*value && *value != ',')
+-				value++;
+-			len = value - p;
+-			if (len) {
+-				char *buffer = kmalloc(len + 1, GFP_NOFS);
+-				if (buffer) {
+-					opts->iocharset = buffer;
+-					memcpy(buffer, p, len);
+-					buffer[len] = 0;
+-
+-				} else {
+-					printk(KERN_ERR "BEFS: "
+-					       "cannot allocate memory\n");
+-					ret = 0;
+-				}
++			opts->gid = option;
++			opts->use_gid = 1;
++			break;
++		case Opt_charset:
++			kfree(opts->iocharset);
++			opts->iocharset = match_strdup(&args[0]);
++			if (!opts->iocharset) {
++				printk(KERN_ERR "BeFS: allocation failure for "
++						"iocharset string\n");
++				return 0;
+ 			}
+-		} else if (!strcmp(this_char, "debug")) {
++			break;
++		case Opt_debug:
+ 			opts->debug = 1;
++			break;
++		default:
++			printk(KERN_ERR "BeFS: Unrecognized mount option \"%s\" "
++					"or missing value\n", p);
++			return 0;
+ 		}
+ 	}
+-
+-	return ret;
++	return 1;
+ }
+ 
+ /* This function has the responsibiltiy of getting the
+@@ -939,9 +947,19 @@ init_befs_fs(void)
+ 
+ 	err = befs_init_inodecache();
+ 	if (err)
+-		return err;
++		goto unaquire_none;
++
++	err = register_filesystem(&befs_fs_type);
++	if (err)
++		goto unaquire_inodecache;
++
++	return 0;
++
++unaquire_inodecache:
++	befs_destroy_inodecache();
+ 
+-	return register_filesystem(&befs_fs_type);
++unaquire_none:
++	return err;
+ }
+ 
+ static void __exit
+--- linux-2.6.0-test6/fs/binfmt_elf.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/binfmt_elf.c	2003-10-05 00:36:15.000000000 -0700
+@@ -134,7 +134,7 @@ create_elf_tables(struct linux_binprm *b
+ 	elf_addr_t *sp, *u_platform;
+ 	const char *k_platform = ELF_PLATFORM;
+ 	int items;
+-	elf_addr_t elf_info[40];
++	elf_addr_t *elf_info;
+ 	int ei_index = 0;
+ 	struct task_struct *tsk = current;
+ 
+@@ -169,6 +169,7 @@ create_elf_tables(struct linux_binprm *b
+ 	}
+ 
+ 	/* Create the ELF interpreter info */
++	elf_info = (elf_addr_t *) current->mm->saved_auxv;
+ #define NEW_AUX_ENT(id, val) \
+ 	do { elf_info[ei_index++] = id; elf_info[ei_index++] = val; } while (0)
+ 
+@@ -196,8 +197,13 @@ create_elf_tables(struct linux_binprm *b
+ 	if (k_platform) {
+ 		NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(long)u_platform);
+ 	}
+-	NEW_AUX_ENT(AT_NULL, 0);
+ #undef NEW_AUX_ENT
++	/* AT_NULL is zero; clear the rest too */
++	memset(&elf_info[ei_index], 0,
++	       sizeof current->mm->saved_auxv - ei_index * sizeof elf_info[0]);
++
++	/* And advance past the AT_NULL entry.  */
++	ei_index += 2;
+ 
+ 	sp = STACK_ADD(p, ei_index);
+ 
+@@ -1078,7 +1084,7 @@ static void fill_prstatus(struct elf_prs
+ 	prstatus->pr_pid = p->pid;
+ 	prstatus->pr_ppid = p->parent->pid;
+ 	prstatus->pr_pgrp = process_group(p);
+-	prstatus->pr_sid = p->session;
++	prstatus->pr_sid = process_session(p);
+ 	jiffies_to_timeval(p->utime, &prstatus->pr_utime);
+ 	jiffies_to_timeval(p->stime, &prstatus->pr_stime);
+ 	jiffies_to_timeval(p->cutime, &prstatus->pr_cutime);
+@@ -1106,7 +1112,7 @@ static void fill_psinfo(struct elf_prpsi
+ 	psinfo->pr_pid = p->pid;
+ 	psinfo->pr_ppid = p->parent->pid;
+ 	psinfo->pr_pgrp = process_group(p);
+-	psinfo->pr_sid = p->session;
++	psinfo->pr_sid = process_session(p);
+ 
+ 	i = p->state ? ffz(~p->state) + 1 : 0;
+ 	psinfo->pr_state = i;
+@@ -1186,7 +1192,7 @@ static int elf_dump_thread_status(long s
+  */
+ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
+ {
+-#define	NUM_NOTES	5
++#define	NUM_NOTES	6
+ 	int has_dumped = 0;
+ 	mm_segment_t fs;
+ 	int segs;
+@@ -1196,7 +1202,7 @@ static int elf_core_dump(long signr, str
+ 	struct elfhdr *elf = NULL;
+ 	off_t offset = 0, dataoff;
+ 	unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
+-	int numnote = NUM_NOTES;
++	int numnote;
+ 	struct memelfnote *notes = NULL;
+ 	struct elf_prstatus *prstatus = NULL;	/* NT_PRSTATUS */
+ 	struct elf_prpsinfo *psinfo = NULL;	/* NT_PRPSINFO */
+@@ -1208,6 +1214,7 @@ static int elf_core_dump(long signr, str
+ 	elf_fpxregset_t *xfpu = NULL;
+ #endif
+ 	int thread_status_size = 0;
++	elf_addr_t *auxv;
+ 
+ 	/*
+ 	 * We no longer stop all VM operations.
+@@ -1287,18 +1294,25 @@ static int elf_core_dump(long signr, str
+ 	
+ 	fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
+   
++	numnote = 3;
++
++	auxv = (elf_addr_t *) current->mm->saved_auxv;
++
++	i = 0;
++	do
++		i += 2;
++	while (auxv[i - 2] != AT_NULL);
++	fill_note(&notes[numnote++], "CORE", NT_AUXV,
++		  i * sizeof (elf_addr_t), auxv);
++
+   	/* Try to dump the FPU. */
+ 	if ((prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, fpu)))
+-		fill_note(notes +3, "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
+-	else
+-		--numnote;
++		fill_note(notes + numnote++,
++			  "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
+ #ifdef ELF_CORE_COPY_XFPREGS
+ 	if (elf_core_copy_task_xfpregs(current, xfpu))
+-		fill_note(notes +4, "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
+-	else
+-		--numnote;
+-#else
+-	numnote--;
++		fill_note(notes + numnote++,
++			  "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
+ #endif	
+   
+ 	fs = get_fs();
+--- linux-2.6.0-test6/fs/block_dev.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/block_dev.c	2003-10-05 00:34:12.000000000 -0700
+@@ -25,6 +25,22 @@
+ #include <linux/namei.h>
+ #include <asm/uaccess.h>
+ 
++struct bdev_inode {
++	struct block_device bdev;
++	struct inode vfs_inode;
++};
++
++static inline struct bdev_inode *BDEV_I(struct inode *inode)
++{
++	return container_of(inode, struct bdev_inode, vfs_inode);
++}
++
++inline struct block_device *I_BDEV(struct inode *inode)
++{
++	return &BDEV_I(inode)->bdev;
++}
++
++EXPORT_SYMBOL(I_BDEV);
+ 
+ static sector_t max_block(struct block_device *bdev)
+ {
+@@ -70,6 +86,8 @@ int set_blocksize(struct block_device *b
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(set_blocksize);
++
+ int sb_set_blocksize(struct super_block *sb, int size)
+ {
+ 	int bits;
+@@ -82,6 +100,8 @@ int sb_set_blocksize(struct super_block 
+ 	return sb->s_blocksize;
+ }
+ 
++EXPORT_SYMBOL(sb_set_blocksize);
++
+ int sb_min_blocksize(struct super_block *sb, int size)
+ {
+ 	int minsize = bdev_hardsect_size(sb->s_bdev);
+@@ -90,14 +110,16 @@ int sb_min_blocksize(struct super_block 
+ 	return sb_set_blocksize(sb, size);
+ }
+ 
++EXPORT_SYMBOL(sb_min_blocksize);
++
+ static int
+ blkdev_get_block(struct inode *inode, sector_t iblock,
+ 		struct buffer_head *bh, int create)
+ {
+-	if (iblock >= max_block(inode->i_bdev))
++	if (iblock >= max_block(I_BDEV(inode)))
+ 		return -EIO;
+ 
+-	bh->b_bdev = inode->i_bdev;
++	bh->b_bdev = I_BDEV(inode);
+ 	bh->b_blocknr = iblock;
+ 	set_buffer_mapped(bh);
+ 	return 0;
+@@ -107,10 +129,10 @@ static int
+ blkdev_get_blocks(struct inode *inode, sector_t iblock,
+ 		unsigned long max_blocks, struct buffer_head *bh, int create)
+ {
+-	if ((iblock + max_blocks) > max_block(inode->i_bdev))
++	if ((iblock + max_blocks) > max_block(I_BDEV(inode)))
+ 		return -EIO;
+ 
+-	bh->b_bdev = inode->i_bdev;
++	bh->b_bdev = I_BDEV(inode);
+ 	bh->b_blocknr = iblock;
+ 	bh->b_size = max_blocks << inode->i_blkbits;
+ 	set_buffer_mapped(bh);
+@@ -122,9 +144,9 @@ blkdev_direct_IO(int rw, struct kiocb *i
+ 			loff_t offset, unsigned long nr_segs)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode *inode = file->f_mapping->host;
+ 
+-	return blockdev_direct_IO(rw, iocb, inode, inode->i_bdev, iov, offset,
++	return blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
+ 				nr_segs, blkdev_get_blocks, NULL);
+ }
+ 
+@@ -155,11 +177,10 @@ static int blkdev_commit_write(struct fi
+  */
+ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
+ {
+-	struct inode *bd_inode;
++	struct inode *bd_inode = file->f_mapping->host;
+ 	loff_t size;
+ 	loff_t retval;
+ 
+-	bd_inode = file->f_dentry->d_inode->i_bdev->bd_inode;
+ 	down(&bd_inode->i_sem);
+ 	size = i_size_read(bd_inode);
+ 
+@@ -182,15 +203,13 @@ static loff_t block_llseek(struct file *
+ }
+ 	
+ /*
+- *	Filp may be NULL when we are called by an msync of a vma
+- *	since the vma has no handle.
++ *	Filp is never NULL; the only case when ->fsync() is called with
++ *	NULL first argument is nfsd_sync_dir() and that's not a directory.
+  */
+  
+ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+ {
+-	struct inode * inode = dentry->d_inode;
+-
+-	return sync_blockdev(inode->i_bdev);
++	return sync_blockdev(I_BDEV(filp->f_mapping->host));
+ }
+ 
+ /*
+@@ -200,16 +219,6 @@ static int block_fsync(struct file *filp
+ static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ static kmem_cache_t * bdev_cachep;
+ 
+-struct bdev_inode {
+-	struct block_device bdev;
+-	struct inode vfs_inode;
+-};
+-
+-static inline struct bdev_inode *BDEV_I(struct inode *inode)
+-{
+-	return container_of(inode, struct bdev_inode, vfs_inode);
+-}
+-
+ static struct inode *bdev_alloc_inode(struct super_block *sb)
+ {
+ 	struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL);
+@@ -243,7 +252,6 @@ static inline void __bd_forget(struct in
+ {
+ 	list_del_init(&inode->i_devices);
+ 	inode->i_bdev = NULL;
+-	inode->i_mapping = &inode->i_data;
+ }
+ 
+ static void bdev_clear_inode(struct inode *inode)
+@@ -358,6 +366,8 @@ struct block_device *bdget(dev_t dev)
+ 	return bdev;
+ }
+ 
++EXPORT_SYMBOL(bdget);
++
+ long nr_blockdev_pages(void)
+ {
+ 	struct list_head *p;
+@@ -376,27 +386,29 @@ void bdput(struct block_device *bdev)
+ {
+ 	iput(bdev->bd_inode);
+ }
++
++EXPORT_SYMBOL(bdput);
+  
+-int bd_acquire(struct inode *inode)
++static struct block_device *bd_acquire(struct inode *inode)
+ {
+ 	struct block_device *bdev;
+ 	spin_lock(&bdev_lock);
+-	if (inode->i_bdev && igrab(inode->i_bdev->bd_inode)) {
++	bdev = inode->i_bdev;
++	if (bdev && igrab(bdev->bd_inode)) {
+ 		spin_unlock(&bdev_lock);
+-		return 0;
++		return bdev;
+ 	}
+ 	spin_unlock(&bdev_lock);
+ 	bdev = bdget(inode->i_rdev);
+-	if (!bdev)
+-		return -ENOMEM;
+-	spin_lock(&bdev_lock);
+-	if (inode->i_bdev)
+-		__bd_forget(inode);
+-	inode->i_bdev = bdev;
+-	inode->i_mapping = bdev->bd_inode->i_mapping;
+-	list_add(&inode->i_devices, &bdev->bd_inodes);
+-	spin_unlock(&bdev_lock);
+-	return 0;
++	if (bdev) {
++		spin_lock(&bdev_lock);
++		if (inode->i_bdev)
++			__bd_forget(inode);
++		inode->i_bdev = bdev;
++		list_add(&inode->i_devices, &bdev->bd_inodes);
++		spin_unlock(&bdev_lock);
++	}
++	return bdev;
+ }
+ 
+ /* Call when you free inode */
+@@ -444,6 +456,8 @@ int bd_claim(struct block_device *bdev, 
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(bd_claim);
++
+ void bd_release(struct block_device *bdev)
+ {
+ 	spin_lock(&bdev_lock);
+@@ -454,6 +468,8 @@ void bd_release(struct block_device *bde
+ 	spin_unlock(&bdev_lock);
+ }
+ 
++EXPORT_SYMBOL(bd_release);
++
+ /*
+  * Tries to open block device by device number.  Use it ONLY if you
+  * really do not have anything better - i.e. when you are behind a
+@@ -471,6 +487,8 @@ struct block_device *open_by_devnum(dev_
+ 	return err ? ERR_PTR(err) : bdev;
+ }
+ 
++EXPORT_SYMBOL(open_by_devnum);
++
+ /*
+  * This routine checks whether a removable media has been changed,
+  * and invalidates all buffer-cache-entries in that case. This
+@@ -500,6 +518,8 @@ int check_disk_change(struct block_devic
+ 	return 1;
+ }
+ 
++EXPORT_SYMBOL(check_disk_change);
++
+ static void bd_set_size(struct block_device *bdev, loff_t size)
+ {
+ 	unsigned bsize = bdev_hardsect_size(bdev);
+@@ -513,13 +533,14 @@ static void bd_set_size(struct block_dev
+ 	bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+ }
+ 
+-static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
++static int do_open(struct block_device *bdev, struct file *file)
+ {
+ 	struct module *owner = NULL;
+ 	struct gendisk *disk;
+ 	int ret = -ENXIO;
+ 	int part;
+ 
++	file->f_mapping = bdev->bd_inode->i_mapping;
+ 	lock_kernel();
+ 	disk = get_gendisk(bdev->bd_dev, &part);
+ 	if (!disk) {
+@@ -536,7 +557,7 @@ static int do_open(struct block_device *
+ 		if (!part) {
+ 			struct backing_dev_info *bdi;
+ 			if (disk->fops->open) {
+-				ret = disk->fops->open(inode, file);
++				ret = disk->fops->open(bdev, file);
+ 				if (ret)
+ 					goto out_first;
+ 			}
+@@ -581,7 +602,7 @@ static int do_open(struct block_device *
+ 		module_put(owner);
+ 		if (bdev->bd_contains == bdev) {
+ 			if (bdev->bd_disk->fops->open) {
+-				ret = bdev->bd_disk->fops->open(inode, file);
++				ret = bdev->bd_disk->fops->open(bdev, file);
+ 				if (ret)
+ 					goto out;
+ 			}
+@@ -629,9 +650,11 @@ int blkdev_get(struct block_device *bdev
+ 	fake_file.f_dentry = &fake_dentry;
+ 	fake_dentry.d_inode = bdev->bd_inode;
+ 
+-	return do_open(bdev, bdev->bd_inode, &fake_file);
++	return do_open(bdev, &fake_file);
+ }
+ 
++EXPORT_SYMBOL(blkdev_get);
++
+ int blkdev_open(struct inode * inode, struct file * filp)
+ {
+ 	struct block_device *bdev;
+@@ -645,10 +668,9 @@ int blkdev_open(struct inode * inode, st
+ 	 */
+ 	filp->f_flags |= O_LARGEFILE;
+ 
+-	bd_acquire(inode);
+-	bdev = inode->i_bdev;
++	bdev = bd_acquire(inode);
+ 
+-	res = do_open(bdev, inode, filp);
++	res = do_open(bdev, filp);
+ 	if (res)
+ 		return res;
+ 
+@@ -662,10 +684,11 @@ int blkdev_open(struct inode * inode, st
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(blkdev_open);
++
+ int blkdev_put(struct block_device *bdev, int kind)
+ {
+ 	int ret = 0;
+-	struct inode *bd_inode = bdev->bd_inode;
+ 	struct gendisk *disk = bdev->bd_disk;
+ 
+ 	down(&bdev->bd_sem);
+@@ -674,14 +697,14 @@ int blkdev_put(struct block_device *bdev
+ 		switch (kind) {
+ 		case BDEV_FILE:
+ 		case BDEV_FS:
+-			sync_blockdev(bd_inode->i_bdev);
++			sync_blockdev(bdev);
+ 			break;
+ 		}
+ 		kill_bdev(bdev);
+ 	}
+ 	if (bdev->bd_contains == bdev) {
+ 		if (disk->fops->release)
+-			ret = disk->fops->release(bd_inode, NULL);
++			ret = disk->fops->release(disk);
+ 	} else {
+ 		down(&bdev->bd_contains->bd_sem);
+ 		bdev->bd_contains->bd_part_count--;
+@@ -710,11 +733,14 @@ int blkdev_put(struct block_device *bdev
+ 	return ret;
+ }
+ 
+-int blkdev_close(struct inode * inode, struct file * filp)
++EXPORT_SYMBOL(blkdev_put);
++
++static int blkdev_close(struct inode * inode, struct file * filp)
+ {
+-	if (inode->i_bdev->bd_holder == filp)
+-		bd_release(inode->i_bdev);
+-	return blkdev_put(inode->i_bdev, BDEV_FILE);
++	struct block_device *bdev = I_BDEV(filp->f_mapping->host);
++	if (bdev->bd_holder == filp)
++		bd_release(bdev);
++	return blkdev_put(bdev, BDEV_FILE);
+ }
+ 
+ static ssize_t blkdev_file_write(struct file *file, const char __user *buf,
+@@ -733,6 +759,11 @@ static ssize_t blkdev_file_aio_write(str
+ 	return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
+ }
+ 
++static int block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
++			unsigned long arg)
++{
++	return blkdev_ioctl(I_BDEV(file->f_mapping->host), file, cmd, arg);
++}
+ 
+ struct address_space_operations def_blk_aops = {
+ 	.readpage	= blkdev_readpage,
+@@ -754,22 +785,26 @@ struct file_operations def_blk_fops = {
+   	.aio_write	= blkdev_file_aio_write, 
+ 	.mmap		= generic_file_mmap,
+ 	.fsync		= block_fsync,
+-	.ioctl		= blkdev_ioctl,
++	.ioctl		= block_ioctl,
+ 	.readv		= generic_file_readv,
+ 	.writev		= generic_file_writev,
+ 	.sendfile	= generic_file_sendfile,
+ };
+ 
++EXPORT_SYMBOL(def_blk_fops);
++
+ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
+ {
+ 	int res;
+ 	mm_segment_t old_fs = get_fs();
+ 	set_fs(KERNEL_DS);
+-	res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg);
++	res = blkdev_ioctl(bdev, NULL, cmd, arg);
+ 	set_fs(old_fs);
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(ioctl_by_bdev);
++
+ /**
+  * lookup_bdev  - lookup a struct block_device by name
+  *
+@@ -800,11 +835,10 @@ struct block_device *lookup_bdev(const c
+ 	error = -EACCES;
+ 	if (nd.mnt->mnt_flags & MNT_NODEV)
+ 		goto fail;
+-	error = bd_acquire(inode);
+-	if (error)
++	error = -ENOMEM;
++	bdev = bd_acquire(inode);
++	if (!bdev)
+ 		goto fail;
+-	bdev = inode->i_bdev;
+-
+ out:
+ 	path_release(&nd);
+ 	return bdev;
+@@ -854,6 +888,8 @@ blkdev_put:
+ 	return ERR_PTR(error);
+ }
+ 
++EXPORT_SYMBOL(open_bdev_excl);
++
+ /**
+  * close_bdev_excl  -  release a blockdevice openen by open_bdev_excl()
+  *
+@@ -867,3 +903,5 @@ void close_bdev_excl(struct block_device
+ 	bd_release(bdev);
+ 	blkdev_put(bdev, kind);
+ }
++
++EXPORT_SYMBOL(close_bdev_excl);
+--- linux-2.6.0-test6/fs/buffer.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/buffer.c	2003-10-05 00:36:59.000000000 -0700
+@@ -116,27 +116,50 @@ void unlock_buffer(struct buffer_head *b
+ }
+ 
+ /*
+- * Block until a buffer comes unlocked.  This doesn't stop it
++ * Wait until a buffer comes unlocked.  This doesn't stop it
+  * from becoming locked again - you have to lock it yourself
+  * if you want to preserve its state.
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, we just queue up the callback
++ * on the wait queue for async notification when the buffer gets
++ * unlocked.
++ * A NULL wait queue parameter defaults to synchronous behaviour
+  */
+-void __wait_on_buffer(struct buffer_head * bh)
++int __wait_on_buffer_wq(struct buffer_head * bh, wait_queue_t *wait)
+ {
+ 	wait_queue_head_t *wqh = bh_waitq_head(bh);
+-	DEFINE_WAIT(wait);
++	DEFINE_WAIT(local_wait);
++
++	if (!wait)
++		wait = &local_wait;
+ 
+ 	if (atomic_read(&bh->b_count) == 0 &&
+ 			(!bh->b_page || !PageLocked(bh->b_page)))
+ 		buffer_error();
+ 
+ 	do {
+-		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++		prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+ 		if (buffer_locked(bh)) {
+ 			blk_run_queues();
++			if (!is_sync_wait(wait)) {
++				/*
++				 * if we've queued an async wait queue
++				 * callback do not block; just tell the
++				 * caller to return and retry later when
++				 * the callback is notified
++				 */
++				return -EIOCBRETRY;
++			}
+ 			io_schedule();
+ 		}
+ 	} while (buffer_locked(bh));
+-	finish_wait(wqh, &wait);
++	finish_wait(wqh, wait);
++	return 0;
++}
++
++void __wait_on_buffer(struct buffer_head * bh)
++{
++	__wait_on_buffer_wq(bh, NULL);
+ }
+ 
+ static void
+@@ -314,8 +337,7 @@ int file_fsync(struct file *filp, struct
+ asmlinkage long sys_fsync(unsigned int fd)
+ {
+ 	struct file * file;
+-	struct dentry * dentry;
+-	struct inode * inode;
++	struct address_space *mapping;
+ 	int ret, err;
+ 
+ 	ret = -EBADF;
+@@ -323,8 +345,7 @@ asmlinkage long sys_fsync(unsigned int f
+ 	if (!file)
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
++	mapping = file->f_mapping;
+ 
+ 	ret = -EINVAL;
+ 	if (!file->f_op || !file->f_op->fsync) {
+@@ -333,17 +354,17 @@ asmlinkage long sys_fsync(unsigned int f
+ 	}
+ 
+ 	/* We need to protect against concurrent writers.. */
+-	down(&inode->i_sem);
++	down(&mapping->host->i_sem);
+ 	current->flags |= PF_SYNCWRITE;
+-	ret = filemap_fdatawrite(inode->i_mapping);
+-	err = file->f_op->fsync(file, dentry, 0);
++	ret = filemap_fdatawrite(mapping);
++	err = file->f_op->fsync(file, file->f_dentry, 0);
+ 	if (!ret)
+ 		ret = err;
+-	err = filemap_fdatawait(inode->i_mapping);
++	err = filemap_fdatawait(mapping);
+ 	if (!ret)
+ 		ret = err;
+ 	current->flags &= ~PF_SYNCWRITE;
+-	up(&inode->i_sem);
++	up(&mapping->host->i_sem);
+ 
+ out_putf:
+ 	fput(file);
+@@ -354,8 +375,7 @@ out:
+ asmlinkage long sys_fdatasync(unsigned int fd)
+ {
+ 	struct file * file;
+-	struct dentry * dentry;
+-	struct inode * inode;
++	struct address_space *mapping;
+ 	int ret, err;
+ 
+ 	ret = -EBADF;
+@@ -363,24 +383,23 @@ asmlinkage long sys_fdatasync(unsigned i
+ 	if (!file)
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
+-
+ 	ret = -EINVAL;
+ 	if (!file->f_op || !file->f_op->fsync)
+ 		goto out_putf;
+ 
+-	down(&inode->i_sem);
++	mapping = file->f_mapping;
++
++	down(&mapping->host->i_sem);
+ 	current->flags |= PF_SYNCWRITE;
+-	ret = filemap_fdatawrite(inode->i_mapping);
+-	err = file->f_op->fsync(file, dentry, 1);
++	ret = filemap_fdatawrite(mapping);
++	err = file->f_op->fsync(file, file->f_dentry, 1);
+ 	if (!ret)
+ 		ret = err;
+-	err = filemap_fdatawait(inode->i_mapping);
++	err = filemap_fdatawait(mapping);
+ 	if (!ret)
+ 		ret = err;
+ 	current->flags &= ~PF_SYNCWRITE;
+-	up(&inode->i_sem);
++	up(&mapping->host->i_sem);
+ 
+ out_putf:
+ 	fput(file);
+@@ -1296,9 +1315,12 @@ void __bforget(struct buffer_head *bh)
+ 	__brelse(bh);
+ }
+ 
+-static struct buffer_head *__bread_slow(struct buffer_head *bh)
++static struct buffer_head *__bread_slow_wq(struct buffer_head *bh,
++		wait_queue_t *wait)
+ {
+-	lock_buffer(bh);
++	if (-EIOCBRETRY == lock_buffer_wq(bh, wait))
++		return ERR_PTR(-EIOCBRETRY);
++
+ 	if (buffer_uptodate(bh)) {
+ 		unlock_buffer(bh);
+ 		return bh;
+@@ -1308,7 +1330,8 @@ static struct buffer_head *__bread_slow(
+ 		get_bh(bh);
+ 		bh->b_end_io = end_buffer_read_sync;
+ 		submit_bh(READ, bh);
+-		wait_on_buffer(bh);
++		if (-EIOCBRETRY == wait_on_buffer_wq(bh, wait))
++			return ERR_PTR(-EIOCBRETRY);
+ 		if (buffer_uptodate(bh))
+ 			return bh;
+ 	}
+@@ -1316,6 +1339,11 @@ static struct buffer_head *__bread_slow(
+ 	return NULL;
+ }
+ 
++static inline struct buffer_head *__bread_slow(struct buffer_head *bh)
++{
++	return __bread_slow_wq(bh, NULL);
++}
++
+ /*
+  * Per-cpu buffer LRU implementation.  To reduce the cost of __find_get_block().
+  * The bhs[] array is sorted - newest buffer is at bhs[0].  Buffers have their
+@@ -1503,6 +1531,18 @@ __bread(struct block_device *bdev, secto
+ }
+ EXPORT_SYMBOL(__bread);
+ 
++struct buffer_head *
++__bread_wq(struct block_device *bdev, sector_t block, int size,
++	wait_queue_t *wait)
++{
++	struct buffer_head *bh = __getblk(bdev, block, size);
++
++	if (!buffer_uptodate(bh))
++		bh = __bread_slow_wq(bh, wait);
++	return bh;
++}
++EXPORT_SYMBOL(__bread_wq);
++
+ /*
+  * invalidate_bh_lrus() is called rarely - at unmount.  Because it is only for
+  * unmount it only needs to ensure that all buffers from the target device are
+@@ -1980,8 +2020,9 @@ static int __block_prepare_write(struct 
+ 	/*
+ 	 * If we issued read requests - let them complete.
+ 	 */
+-	while(wait_bh > wait) {
+-		wait_on_buffer(*--wait_bh);
++	while (wait_bh > wait) {
++		if ((err = wait_on_buffer_wq(*--wait_bh, current->io_wait)))
++			return err;
+ 		if (!buffer_uptodate(*wait_bh))
+ 			return -EIO;
+ 	}
+@@ -3035,3 +3076,32 @@ void __init buffer_init(void)
+ 				(void *)(long)smp_processor_id());
+ 	register_cpu_notifier(&buffer_nb);
+ }
++
++EXPORT_SYMBOL(__bforget);
++EXPORT_SYMBOL(__brelse);
++EXPORT_SYMBOL(__wait_on_buffer);
++EXPORT_SYMBOL(__wait_on_buffer_wq);
++EXPORT_SYMBOL(block_commit_write);
++EXPORT_SYMBOL(block_prepare_write);
++EXPORT_SYMBOL(block_read_full_page);
++EXPORT_SYMBOL(block_sync_page);
++EXPORT_SYMBOL(block_truncate_page);
++EXPORT_SYMBOL(block_write_full_page);
++EXPORT_SYMBOL(buffer_insert_list);
++EXPORT_SYMBOL(cont_prepare_write);
++EXPORT_SYMBOL(end_buffer_async_write);
++EXPORT_SYMBOL(end_buffer_read_sync);
++EXPORT_SYMBOL(end_buffer_write_sync);
++EXPORT_SYMBOL(file_fsync);
++EXPORT_SYMBOL(fsync_bdev);
++EXPORT_SYMBOL(fsync_buffers_list);
++EXPORT_SYMBOL(generic_block_bmap);
++EXPORT_SYMBOL(generic_commit_write);
++EXPORT_SYMBOL(generic_cont_expand);
++EXPORT_SYMBOL(init_buffer);
++EXPORT_SYMBOL(invalidate_bdev);
++EXPORT_SYMBOL(ll_rw_block);
++EXPORT_SYMBOL(mark_buffer_dirty);
++EXPORT_SYMBOL(submit_bh);
++EXPORT_SYMBOL(sync_dirty_buffer);
++EXPORT_SYMBOL(unlock_buffer);
+--- linux-2.6.0-test6/fs/coda/file.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/coda/file.c	2003-10-05 00:34:03.000000000 -0700
+@@ -89,6 +89,7 @@ coda_file_mmap(struct file *coda_file, s
+ 
+ 	coda_inode = coda_file->f_dentry->d_inode;
+ 	host_inode = host_file->f_dentry->d_inode;
++	coda_file->f_mapping = host_file->f_mapping;
+ 	if (coda_inode->i_mapping == &coda_inode->i_data)
+ 		coda_inode->i_mapping = host_inode->i_mapping;
+ 
+--- linux-2.6.0-test6/fs/compat_ioctl.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/compat_ioctl.c	2003-10-05 00:34:44.000000000 -0700
+@@ -106,6 +106,7 @@
+ #include <linux/nbd.h>
+ #include <linux/random.h>
+ #include <linux/filter.h>
++#include <linux/msdos_fs.h>
+ 
+ #undef INCLUDES
+ #endif
+@@ -576,54 +577,45 @@ static int ethtool_ioctl(unsigned int fd
+ 
+ static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
+ {
+-	struct ifreq ifr;
++	struct ifreq kifr;
++	struct ifreq *uifr;
++	struct ifreq32 *ifr32 = (struct ifreq32 *) arg;
+ 	mm_segment_t old_fs;
+-	int err, len;
++	int err;
+ 	u32 data;
+-	
+-	if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+-		return -EFAULT;
+-	ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
+-	if (!ifr.ifr_data)
+-		return -EAGAIN;
++	void *datap;
+ 
+ 	switch (cmd) {
+ 	case SIOCBONDENSLAVE:
+ 	case SIOCBONDRELEASE:
+ 	case SIOCBONDSETHWADDR:
+ 	case SIOCBONDCHANGEACTIVE:
+-		len = IFNAMSIZ * sizeof(char);
+-		break;
++		if (copy_from_user(&kifr, ifr32, sizeof(struct ifreq32)))
++			return -EFAULT;
++
++		old_fs = get_fs();
++		set_fs (KERNEL_DS);
++		err = sys_ioctl (fd, cmd, (unsigned long)&kifr);
++		set_fs (old_fs);
++
++		return err;
+ 	case SIOCBONDSLAVEINFOQUERY:
+-		len = sizeof(struct ifslave);
+-		break;
+ 	case SIOCBONDINFOQUERY:
+-		len = sizeof(struct ifbond);
+-		break;
+-	default:
+-		err = -EINVAL;
+-		goto out;
+-	};
++		uifr = compat_alloc_user_space(sizeof(*uifr));
++		if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
++			return -EFAULT;
+ 
+-	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+-	if (copy_from_user(ifr.ifr_data, compat_ptr(data), len)) {
+-		err = -EFAULT;
+-		goto out;
+-	}
++		if (get_user(data, &ifr32->ifr_ifru.ifru_data))
++			return -EFAULT;
+ 
+-	old_fs = get_fs();
+-	set_fs (KERNEL_DS);
+-	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+-	set_fs (old_fs);
+-	if (!err) {
+-		len = copy_to_user(compat_ptr(data), ifr.ifr_data, len);
+-		if (len)
+-			err = -EFAULT;
+-	}
++		datap = compat_ptr(data);
++		if (put_user(datap, &uifr->ifr_ifru.ifru_data))
++			return -EFAULT;
+ 
+-out:
+-	free_page((unsigned long)ifr.ifr_data);
+-	return err;
++		return sys_ioctl (fd, cmd, (unsigned long)uifr);
++	default:
++		return -EINVAL;
++	};
+ }
+ 
+ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+@@ -1035,6 +1027,7 @@ static int sg_build_iovec(sg_io_hdr_t *s
+ 			return -EFAULT;
+ 	}
+ 
++	sgio->dxferp = iov;
+ 	return 0;
+ }
+ 
+@@ -1581,7 +1574,7 @@ static int vt_check(struct file *file)
+ 	 * To have permissions to do most of the vt ioctls, we either have
+ 	 * to be the owner of the tty, or super-user.
+ 	 */
+-	if (current->tty == tty || capable(CAP_SYS_ADMIN))
++	if (process_tty(current) == tty || capable(CAP_SYS_ADMIN))
+ 		return 1;
+ 	return 0;                                                    
+ }
+@@ -2310,6 +2303,572 @@ static int mtd_rw_oob(unsigned int fd, u
+ 	return err;
+ }	
+ 
++#define	VFAT_IOCTL_READDIR_BOTH32	_IOR('r', 1, struct compat_dirent[2])
++#define	VFAT_IOCTL_READDIR_SHORT32	_IOR('r', 2, struct compat_dirent[2])
++
++static long
++put_dirent32 (struct dirent *d, struct compat_dirent *d32)
++{
++        int ret;
++
++        if ((ret = verify_area(VERIFY_WRITE, d32,
++                               sizeof(struct compat_dirent))))
++                return ret;
++
++        __put_user(d->d_ino, &d32->d_ino);
++        __put_user(d->d_off, &d32->d_off);
++        __put_user(d->d_reclen, &d32->d_reclen);
++        __copy_to_user(d32->d_name, d->d_name, d->d_reclen);
++        return ret;
++}
++
++static int vfat_ioctl32(unsigned fd, unsigned cmd,  void *ptr)
++{
++	int ret;
++	mm_segment_t oldfs = get_fs();
++	struct dirent d[2];
++
++	switch(cmd)
++	{
++        	case VFAT_IOCTL_READDIR_BOTH32:
++                	cmd = VFAT_IOCTL_READDIR_BOTH;
++                	break;
++        	case VFAT_IOCTL_READDIR_SHORT32:
++                	cmd = VFAT_IOCTL_READDIR_SHORT;
++                	break;
++	}
++
++	set_fs(KERNEL_DS);
++	ret = sys_ioctl(fd,cmd,(unsigned long)&d);
++	set_fs(oldfs);
++	if (ret >= 0) {
++		ret |= put_dirent32(&d[0], (struct compat_dirent *)ptr);
++		ret |= put_dirent32(&d[1], ((struct compat_dirent *)ptr) + 1);
++	}
++	return ret;
++}
++
++#define REISERFS_IOC_UNPACK32               _IOW(0xCD,1,int)
++
++static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
++{
++        if (cmd == REISERFS_IOC_UNPACK32)
++                cmd = REISERFS_IOC_UNPACK;
++
++        return sys_ioctl(fd,cmd,ptr);
++}
++
++struct raw32_config_request
++{
++        compat_int_t    raw_minor;
++        __u64   block_major;
++        __u64   block_minor;
++} __attribute__((packed));
++
++static int get_raw32_request(struct raw_config_request *req, struct raw32_config_request *user_req)
++{
++        __u32   lo_maj, hi_maj, lo_min, hi_min;
++        int ret;
++
++        if ((ret = verify_area(VERIFY_READ, user_req,
++                               sizeof(struct raw32_config_request))))
++                return ret;
++
++        __get_user(req->raw_minor, &user_req->raw_minor);
++        __get_user(lo_maj, (__u32*)&user_req->block_major);
++        __get_user(hi_maj, ((__u32*)(&user_req->block_major) + 1));
++        __get_user(lo_min, (__u32*)&user_req->block_minor);
++        __get_user(hi_min, ((__u32*)(&user_req->block_minor) + 1));
++
++        req->block_major = lo_maj | (((__u64)hi_maj) << 32);
++        req->block_minor = lo_min | (((__u64)lo_min) << 32);
++
++        return ret;
++}
++
++static int set_raw32_request(struct raw_config_request *req, struct raw32_config_request *user_req)
++{
++	int ret;
++
++        if ((ret = verify_area(VERIFY_WRITE, user_req,
++                               sizeof(struct raw32_config_request))))
++                return ret;
++
++        __put_user(req->raw_minor, &user_req->raw_minor);
++        __put_user((__u32)(req->block_major), (__u32*)&user_req->block_major);
++        __put_user((__u32)(req->block_major >> 32), ((__u32*)(&user_req->block_major) + 1));
++        __put_user((__u32)(req->block_minor), (__u32*)&user_req->block_minor);
++        __put_user((__u32)(req->block_minor >> 32), ((__u32*)(&user_req->block_minor) + 1));
++
++        return ret;
++}
++
++static int raw_ioctl(unsigned fd, unsigned cmd,  void *ptr)
++{
++        int ret;
++
++        switch (cmd) {
++        case RAW_SETBIND:
++        case RAW_GETBIND: {
++                struct raw_config_request req;
++                struct raw32_config_request *user_req = ptr;
++                mm_segment_t oldfs = get_fs();
++
++                if ((ret = get_raw32_request(&req, user_req)))
++                        return ret;
++
++                set_fs(KERNEL_DS);
++                ret = sys_ioctl(fd,cmd,(unsigned long)&req);
++                set_fs(oldfs);
++
++                if ((!ret) && (cmd == RAW_GETBIND)) {
++                        ret = set_raw32_request(&req, user_req);
++                }
++                break;
++        }
++        default:
++                ret = sys_ioctl(fd,cmd,(unsigned long)ptr);
++                break;
++        }
++        return ret;
++}
++
++struct serial_struct32 {
++        compat_int_t    type;
++        compat_int_t    line;
++        compat_uint_t   port;
++        compat_int_t    irq;
++        compat_int_t    flags;
++        compat_int_t    xmit_fifo_size;
++        compat_int_t    custom_divisor;
++        compat_int_t    baud_base;
++        unsigned short  close_delay;
++        char    io_type;
++        char    reserved_char[1];
++        compat_int_t    hub6;
++        unsigned short  closing_wait; /* time to wait before closing */
++        unsigned short  closing_wait2; /* no longer used... */
++        compat_uint_t   iomem_base;
++        unsigned short  iomem_reg_shift;
++        unsigned int    port_high;
++        compat_int_t    reserved[1];
++};
++
++static int serial_struct_ioctl(unsigned fd, unsigned cmd,  void *ptr)
++{
++        typedef struct serial_struct SS;
++        typedef struct serial_struct32 SS32;
++        struct serial_struct32 *ss32 = ptr;
++        int err;
++        struct serial_struct ss;
++        mm_segment_t oldseg = get_fs();
++        __u32 udata;
++
++        if (cmd == TIOCSSERIAL) {
++                if (verify_area(VERIFY_READ, ss32, sizeof(SS32)))
++                        return -EFAULT;
++                __copy_from_user(&ss, ss32, offsetof(SS32, iomem_base));
++                __get_user(udata, &ss32->iomem_base);
++                ss.iomem_base = compat_ptr(udata);
++                __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
++                __get_user(ss.port_high, &ss32->port_high);
++                ss.iomap_base = 0UL;
++        }
++        set_fs(KERNEL_DS);
++                err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
++        set_fs(oldseg);
++        if (cmd == TIOCGSERIAL && err >= 0) {
++                if (verify_area(VERIFY_WRITE, ss32, sizeof(SS32)))
++                        return -EFAULT;
++                __copy_to_user(ss32,&ss,offsetof(SS32,iomem_base));
++                __put_user((unsigned long)ss.iomem_base  >> 32 ?
++                            0xffffffff : (unsigned)(unsigned long)ss.iomem_base,
++                            &ss32->iomem_base);
++                __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
++                __put_user(ss.port_high, &ss32->port_high);
++
++        }
++        return err;
++}
++
++struct usbdevfs_ctrltransfer32 {
++        u8 bRequestType;
++        u8 bRequest;
++        u16 wValue;
++        u16 wIndex;
++        u16 wLength;
++        u32 timeout;  /* in milliseconds */
++        compat_caddr_t data;
++};
++
++#define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
++
++static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++        struct usbdevfs_ctrltransfer kctrl;
++        struct usbdevfs_ctrltransfer32 *uctrl;
++        mm_segment_t old_fs;
++        __u32 udata;
++        void *uptr, *kptr;
++        int err;
++
++        uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
++
++        if (copy_from_user(&kctrl, uctrl,
++                           (sizeof(struct usbdevfs_ctrltransfer32) -
++                            sizeof(compat_caddr_t))))
++                return -EFAULT;
++
++        if (get_user(udata, &uctrl->data))
++                return -EFAULT;
++        uptr = compat_ptr(udata);
++        /* In usbdevice_fs, it limits the control buffer to a page,
++         * for simplicity so do we.
++         */
++        if (!uptr || kctrl.wLength > PAGE_SIZE)
++                return -EINVAL;
++
++        kptr = (void *)__get_free_page(GFP_KERNEL);
++
++        if ((kctrl.bRequestType & USB_DIR_IN) == 0) {
++                err = -EFAULT;
++                if (copy_from_user(kptr, uptr, kctrl.wLength))
++                        goto out;
++        }
++
++        kctrl.data = kptr;
++
++        old_fs = get_fs();
++        set_fs(KERNEL_DS);
++        err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
++        set_fs(old_fs);
++
++        if (err >= 0 &&
++            ((kctrl.bRequestType & USB_DIR_IN) != 0)) {
++                if (copy_to_user(uptr, kptr, kctrl.wLength))
++                        err = -EFAULT;
++        }
++
++out:
++        free_page((unsigned long) kptr);
++        return err;
++}
++
++
++struct usbdevfs_bulktransfer32 {
++        compat_uint_t ep;
++        compat_uint_t len;
++        compat_uint_t timeout; /* in milliseconds */
++        compat_caddr_t data;
++};
++
++#define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
++
++static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++        struct usbdevfs_bulktransfer kbulk;
++        struct usbdevfs_bulktransfer32 *ubulk;
++        mm_segment_t old_fs;
++        __u32 udata;
++        void *uptr, *kptr;
++        int err;
++
++	ubulk = (struct usbdevfs_bulktransfer32 *) arg;
++
++        if (get_user(kbulk.ep, &ubulk->ep) ||
++            get_user(kbulk.len, &ubulk->len) ||
++            get_user(kbulk.timeout, &ubulk->timeout) ||
++            get_user(udata, &ubulk->data))
++                return -EFAULT;
++
++        uptr = compat_ptr(udata);
++
++        /* In usbdevice_fs, it limits the control buffer to a page,
++         * for simplicity so do we.
++         */
++        if (!uptr || kbulk.len > PAGE_SIZE)
++                return -EINVAL;
++
++        kptr = (void *) __get_free_page(GFP_KERNEL);
++
++        if ((kbulk.ep & 0x80) == 0) {
++                err = -EFAULT;
++	        if (copy_from_user(kptr, uptr, kbulk.len))
++                        goto out;
++        }
++
++        kbulk.data = kptr;
++
++	old_fs = get_fs();
++        set_fs(KERNEL_DS);
++        err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
++        set_fs(old_fs);
++
++        if (err >= 0 &&
++            ((kbulk.ep & 0x80) != 0)) {
++                if (copy_to_user(uptr, kptr, kbulk.len))
++                        err = -EFAULT;
++        }
++
++out:
++        free_page((unsigned long) kptr);
++        return err;
++}
++
++/* This needs more work before we can enable it.  Unfortunately
++ * because of the fancy asynchronous way URB status/error is written
++ * back to userspace, we'll need to fiddle with USB devio internals
++ * and/or reimplement entirely the frontend of it ourselves. -DaveM
++ *
++ * The issue is:
++ *
++ *	When an URB is submitted via usbdevicefs it is put onto an
++ *	asynchronous queue.  When the URB completes, it may be reaped
++ *	via another ioctl.  During this reaping the status is written
++ *	back to userspace along with the length of the transfer.
++ *
++ *	We must translate into 64-bit kernel types so we pass in a kernel
++ *	space copy of the usbdevfs_urb structure.  This would mean that we
++ *	must do something to deal with the async entry reaping.  First we
++ *	have to deal somehow with this transitory memory we've allocated.
++ *	This is problematic since there are many call sites from which the
++ *	async entries can be destroyed (and thus when we'd need to free up
++ *	this kernel memory).  One of which is the close() op of usbdevicefs.
++ *	To handle that we'd need to make our own file_operations struct which
++ *	overrides usbdevicefs's release op with our own which runs usbdevicefs's
++ *	real release op then frees up the kernel memory.
++ *
++ *	But how to keep track of these kernel buffers?  We'd need to either
++ *	keep track of them in some table _or_ know about usbdevicefs internals
++ *	(ie. the exact layout of its file private, which is actually defined
++ *	in linux/usbdevice_fs.h, the layout of the async queues are private to
++ *	devio.c)
++ *
++ * There is one possible other solution I considered, also involving knowledge
++ * of usbdevicefs internals:
++ *
++ *	After an URB is submitted, we "fix up" the address back to the user
++ *	space one.  This would work if the status/length fields written back
++ *	by the async URB completion lines up perfectly in the 32-bit type with
++ *	the 64-bit kernel type.  Unfortunately, it does not because the iso
++ *	frame descriptors, at the end of the struct, can be written back.
++ *
++ * I think we'll just need to simply duplicate the devio URB engine here.
++ */
++#if 0
++struct usbdevfs_urb32 {
++	unsigned char type;
++	unsigned char endpoint;
++	compat_int_t status;
++	compat_uint_t flags;
++	compat_caddr_t buffer;
++	compat_int_t buffer_length;
++	compat_int_t actual_length;
++	compat_int_t start_frame;
++	compat_int_t number_of_packets;
++	compat_int_t error_count;
++	compat_uint_t signr;
++	compat_caddr_t usercontext; /* unused */
++	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
++};
++
++#define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
++
++static int get_urb32(struct usbdevfs_urb *kurb,
++		     struct usbdevfs_urb32 *uurb)
++{
++	if (get_user(kurb->type, &uurb->type) ||
++	    __get_user(kurb->endpoint, &uurb->endpoint) ||
++	    __get_user(kurb->status, &uurb->status) ||
++	    __get_user(kurb->flags, &uurb->flags) ||
++	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
++	    __get_user(kurb->actual_length, &uurb->actual_length) ||
++	    __get_user(kurb->start_frame, &uurb->start_frame) ||
++	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
++	    __get_user(kurb->error_count, &uurb->error_count) ||
++	    __get_user(kurb->signr, &uurb->signr))
++		return -EFAULT;
++
++	kurb->usercontext = 0; /* unused currently */
++
++	return 0;
++}
++
++/* Just put back the values which usbdevfs actually changes. */
++static int put_urb32(struct usbdevfs_urb *kurb,
++		     struct usbdevfs_urb32 *uurb)
++{
++	if (put_user(kurb->status, &uurb->status) ||
++	    __put_user(kurb->actual_length, &uurb->actual_length) ||
++	    __put_user(kurb->error_count, &uurb->error_count))
++		return -EFAULT;
++
++	if (kurb->number_of_packets != 0) {
++		int i;
++
++		for (i = 0; i < kurb->number_of_packets; i++) {
++			if (__put_user(kurb->iso_frame_desc[i].actual_length,
++				       &uurb->iso_frame_desc[i].actual_length) ||
++			    __put_user(kurb->iso_frame_desc[i].status,
++				       &uurb->iso_frame_desc[i].status))
++				return -EFAULT;
++		}
++	}
++
++	return 0;
++}
++
++static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
++			       struct usbdevfs_urb32 *uurb)
++{
++	unsigned int totlen;
++	int i;
++
++	if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
++		kurb->number_of_packets = 0;
++		return 0;
++	}
++
++	if (kurb->number_of_packets < 1 ||
++	    kurb->number_of_packets > 128)
++		return -EINVAL;
++
++	if (copy_from_user(&kurb->iso_frame_desc[0],
++			   &uurb->iso_frame_desc[0],
++			   sizeof(struct usbdevfs_iso_packet_desc) *
++			   kurb->number_of_packets))
++		return -EFAULT;
++
++	totlen = 0;
++	for (i = 0; i < kurb->number_of_packets; i++) {
++		unsigned int this_len;
++
++		this_len = kurb->iso_frame_desc[i].length;
++		if (this_len > 1023)
++			return -EINVAL;
++
++		totlen += this_len;
++	}
++
++	if (totlen > 32768)
++		return -EINVAL;
++
++	kurb->buffer_length = totlen;
++
++	return 0;
++}
++
++static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++	struct usbdevfs_urb *kurb;
++	struct usbdevfs_urb32 *uurb;
++	mm_segment_t old_fs;
++	__u32 udata;
++	void *uptr, *kptr;
++	unsigned int buflen;
++	int err;
++
++	uurb = (struct usbdevfs_urb32 *) arg;
++
++	err = -ENOMEM;
++	kurb = kmalloc(sizeof(struct usbdevfs_urb) +
++		       (sizeof(struct usbdevfs_iso_packet_desc) * 128),
++		       GFP_KERNEL);
++	if (!kurb)
++		goto out;
++
++	err = -EFAULT;
++	if (get_urb32(kurb, uurb))
++		goto out;
++
++	err = get_urb32_isoframes(kurb, uurb);
++	if (err)
++		goto out;
++
++	err = -EFAULT;
++	if (__get_user(udata, &uurb->buffer))
++		goto out;
++	uptr = compat_ptr(udata);
++
++	buflen = kurb->buffer_length;
++	err = verify_area(VERIFY_WRITE, uptr, buflen);
++	if (err)
++		goto out;
++
++
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++	err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
++	set_fs(old_fs);
++
++	if (err >= 0) {
++		/* RED-PEN Shit, this doesn't work for async URBs :-( XXX */
++		if (put_urb32(kurb, uurb)) {
++			err = -EFAULT;
++		}
++	}
++
++out:
++	kfree(kurb);
++	return err;
++}
++#endif
++
++#define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
++#define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
++
++static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++        mm_segment_t old_fs;
++        void *kptr;
++        int err;
++
++        old_fs = get_fs();
++        set_fs(KERNEL_DS);
++        err = sys_ioctl(fd,
++                        (cmd == USBDEVFS_REAPURB32 ?
++                         USBDEVFS_REAPURB :
++                         USBDEVFS_REAPURBNDELAY),
++                        (unsigned long) &kptr);
++        set_fs(old_fs);
++
++        if (err >= 0 &&
++            put_user((u32)(u64)kptr, (u32 *)arg))
++                err = -EFAULT;
++
++        return err;
++}
++
++struct usbdevfs_disconnectsignal32 {
++        compat_int_t signr;
++        compat_caddr_t context;
++};
++
++#define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
++
++static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++        struct usbdevfs_disconnectsignal kdis;
++        struct usbdevfs_disconnectsignal32 *udis;
++        mm_segment_t old_fs;
++        u32 uctx;
++        int err;
++
++        udis = (struct usbdevfs_disconnectsignal32 *) arg;
++
++        if (get_user(kdis.signr, &udis->signr) ||
++            __get_user(uctx, &udis->context))
++                return -EFAULT;
++
++        kdis.context = (void *) (long)uctx;
++
++        old_fs = get_fs();
++        set_fs(KERNEL_DS);
++        err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
++        set_fs(old_fs);
++
++        return err;
++}
+ #undef CODE
+ #endif
+ 
+@@ -2451,6 +3010,22 @@ HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_io
+ HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
+ HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
+ HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
+-
++/* vfat */
++HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
++HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
++HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
++/* Raw devices */
++HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
++HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
++/* Serial */
++HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
++HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
++/* Usbdevfs */
++HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
++HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
++/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
++HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
++HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
++HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+ #undef DECLARES
+ #endif
+--- linux-2.6.0-test6/fs/dcache.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/dcache.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1639,3 +1639,27 @@ void __init vfs_caches_init(unsigned lon
+ 	bdev_cache_init();
+ 	chrdev_init();
+ }
++
++EXPORT_SYMBOL(d_alloc);
++EXPORT_SYMBOL(d_alloc_anon);
++EXPORT_SYMBOL(d_alloc_root);
++EXPORT_SYMBOL(d_delete);
++EXPORT_SYMBOL(d_find_alias);
++EXPORT_SYMBOL(d_instantiate);
++EXPORT_SYMBOL(d_invalidate);
++EXPORT_SYMBOL(d_lookup);
++EXPORT_SYMBOL(d_move);
++EXPORT_SYMBOL(d_path);
++EXPORT_SYMBOL(d_prune_aliases);
++EXPORT_SYMBOL(d_rehash);
++EXPORT_SYMBOL(d_splice_alias);
++EXPORT_SYMBOL(d_validate);
++EXPORT_SYMBOL(dget_locked);
++EXPORT_SYMBOL(dput);
++EXPORT_SYMBOL(find_inode_number);
++EXPORT_SYMBOL(have_submounts);
++EXPORT_SYMBOL(is_subdir);
++EXPORT_SYMBOL(names_cachep);
++EXPORT_SYMBOL(shrink_dcache_anon);
++EXPORT_SYMBOL(shrink_dcache_parent);
++EXPORT_SYMBOL(shrink_dcache_sb);
+--- linux-2.6.0-test6/fs/devfs/base.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/devfs/base.c	2003-10-05 00:36:10.000000000 -0700
+@@ -973,8 +973,9 @@ static struct devfs_entry *_devfs_search
+ 
+ /**
+  *	_devfs_alloc_entry - Allocate a devfs entry.
+- *	@name:  The name of the entry.
+- *	@namelen:  The number of characters in @name.
++ *	@name:     the name of the entry
++ *	@namelen:  the number of characters in @name
++ *      @mode:     the mode for the entry
+  *
+  *  Allocate a devfs entry and returns a pointer to the entry on success, else
+  *   %NULL.
+@@ -1954,15 +1955,9 @@ static int devfs_notify_change (struct d
+     return 0;
+ }   /*  End Function devfs_notify_change  */
+ 
+-static void devfs_clear_inode (struct inode *inode)
+-{
+-    if ( S_ISBLK (inode->i_mode) ) bdput (inode->i_bdev);
+-}   /*  End Function devfs_clear_inode  */
+-
+ static struct super_operations devfs_sops =
+ { 
+     .drop_inode    = generic_delete_inode,
+-    .clear_inode   = devfs_clear_inode,
+     .statfs        = simple_statfs,
+ };
+ 
+@@ -2014,11 +2009,7 @@ static struct inode *_devfs_get_vfs_inod
+ 	inode->i_rdev = de->u.cdev.dev;
+     }
+     else if ( S_ISBLK (de->mode) )
+-    {
+-	inode->i_rdev = de->u.bdev.dev;
+-	if (bd_acquire (inode) != 0)
+-		PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
+-    }
++	init_special_inode(inode, de->mode, de->u.bdev.dev);
+     else if ( S_ISFIFO (de->mode) )
+     	inode->i_fop = &def_fifo_fops;
+     else if ( S_ISDIR (de->mode) )
+@@ -2117,11 +2108,7 @@ static int devfs_open (struct inode *ino
+     if (de == NULL) return -ENODEV;
+     if ( S_ISDIR (de->mode) ) return 0;
+     file->private_data = de->info;
+-    if ( S_ISBLK (inode->i_mode) )
+-    {
+-	file->f_op = &def_blk_fops;
+-	err = def_blk_fops.open (inode, file); /* Module refcount unchanged */
+-    } else if (S_ISCHR(inode->i_mode)) {
++    if (S_ISCHR(inode->i_mode)) {
+ 	ops = devfs_get_ops (de);  /*  Now have module refcount  */
+ 	file->f_op = ops;
+ 	if (file->f_op)
+--- linux-2.6.0-test6/fs/direct-io.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/direct-io.c	2003-10-05 00:36:53.000000000 -0700
+@@ -51,6 +51,10 @@
+  *
+  * If blkfactor is zero then the user's request was aligned to the filesystem's
+  * blocksize.
++ *
++ * needs_locking is set for regular files on direct-IO-naive filesystems.  It
++ * determines whether we need to do the fancy locking which prevents direct-IO
++ * from being able to read uninitialised disk blocks.
+  */
+ 
+ struct dio {
+@@ -58,6 +62,7 @@ struct dio {
+ 	struct bio *bio;		/* bio under assembly */
+ 	struct inode *inode;
+ 	int rw;
++	int needs_locking;		/* doesn't change */
+ 	unsigned blkbits;		/* doesn't change */
+ 	unsigned blkfactor;		/* When we're using an alignment which
+ 					   is finer than the filesystem's soft
+@@ -205,6 +210,8 @@ static void dio_complete(struct dio *dio
+ {
+ 	if (dio->end_io)
+ 		dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
++	if (dio->needs_locking)
++		up_read(&dio->inode->i_alloc_sem);
+ }
+ 
+ /*
+@@ -448,6 +455,7 @@ static int get_more_blocks(struct dio *d
+ 	unsigned long fs_count;	/* Number of filesystem-sized blocks */
+ 	unsigned long dio_count;/* Number of dio_block-sized blocks */
+ 	unsigned long blkmask;
++	int beyond_eof = 0;
+ 
+ 	/*
+ 	 * If there was a memory error and we've overwritten all the
+@@ -465,8 +473,19 @@ static int get_more_blocks(struct dio *d
+ 		if (dio_count & blkmask)	
+ 			fs_count++;
+ 
++		if (dio->needs_locking) {
++			if (dio->block_in_file >= (i_size_read(dio->inode) >>
++							dio->blkbits))
++				beyond_eof = 1;
++		}
++		/*
++		 * For writes inside i_size we forbid block creations: only
++		 * overwrites are permitted.  We fall back to buffered writes
++		 * at a higher level for inside-i_size block-instantiating
++		 * writes.
++		 */
+ 		ret = (*dio->get_blocks)(dio->inode, fs_startblk, fs_count,
+-				map_bh, dio->rw == WRITE);
++				map_bh, (dio->rw == WRITE) && beyond_eof);
+ 	}
+ 	return ret;
+ }
+@@ -773,6 +792,10 @@ do_holes:
+ 			if (!buffer_mapped(map_bh)) {
+ 				char *kaddr;
+ 
++				/* AKPM: eargh, -ENOTBLK is a hack */
++				if (dio->rw == WRITE)
++					return -ENOTBLK;
++
+ 				if (dio->block_in_file >=
+ 					i_size_read(dio->inode)>>blkbits) {
+ 					/* We hit eof */
+@@ -838,21 +861,21 @@ out:
+ 	return ret;
+ }
+ 
++/*
++ * Releases both i_sem and i_alloc_sem
++ */
+ static int
+ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, 
+ 	const struct iovec *iov, loff_t offset, unsigned long nr_segs, 
+-	unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io)
++	unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io,
++	struct dio *dio)
+ {
+ 	unsigned long user_addr; 
+ 	int seg;
+ 	int ret = 0;
+ 	int ret2;
+-	struct dio *dio;
+ 	size_t bytes;
+ 
+-	dio = kmalloc(sizeof(*dio), GFP_KERNEL);
+-	if (!dio)
+-		return -ENOMEM;
+ 	dio->is_async = !is_sync_kiocb(iocb);
+ 
+ 	dio->bio = NULL;
+@@ -863,7 +886,6 @@ direct_io_worker(int rw, struct kiocb *i
+ 	dio->start_zero_done = 0;
+ 	dio->block_in_file = offset >> blkbits;
+ 	dio->blocks_available = 0;
+-
+ 	dio->cur_page = NULL;
+ 
+ 	dio->boundary = 0;
+@@ -946,6 +968,13 @@ direct_io_worker(int rw, struct kiocb *i
+ 		dio_bio_submit(dio);
+ 
+ 	/*
++	 * All new block allocations have been performed.  We can let i_sem
++	 * go now.
++	 */
++	if (dio->needs_locking)
++		up(&dio->inode->i_sem);
++
++	/*
+ 	 * OK, all BIOs are submitted, so we can decrement bio_count to truly
+ 	 * reflect the number of to-be-processed BIOs.
+ 	 */
+@@ -980,11 +1009,17 @@ direct_io_worker(int rw, struct kiocb *i
+ 
+ /*
+  * This is a library function for use by filesystem drivers.
++ *
++ * For writes to S_ISREG files, we are called under i_sem and return with i_sem
++ * held, even though it is internally dropped.
++ *
++ * For writes to S_ISBLK files, i_sem is not held on entry; it is never taken.
+  */
+ int
+-blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, 
++__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
+ 	struct block_device *bdev, const struct iovec *iov, loff_t offset, 
+-	unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io)
++	unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
++	int needs_special_locking)
+ {
+ 	int seg;
+ 	size_t size;
+@@ -993,6 +1028,8 @@ blockdev_direct_IO(int rw, struct kiocb 
+ 	unsigned bdev_blkbits = 0;
+ 	unsigned blocksize_mask = (1 << blkbits) - 1;
+ 	ssize_t retval = -EINVAL;
++	struct dio *dio;
++	int needs_locking;
+ 
+ 	if (bdev)
+ 		bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
+@@ -1018,8 +1055,37 @@ blockdev_direct_IO(int rw, struct kiocb 
+ 		}
+ 	}
+ 
+-	retval = direct_io_worker(rw, iocb, inode, iov, offset, 
+-				nr_segs, blkbits, get_blocks, end_io);
++	dio = kmalloc(sizeof(*dio), GFP_KERNEL);
++	retval = -ENOMEM;
++	if (!dio)
++		goto out;
++
++	/*
++	 * For regular files,
++	 *	readers need to grab i_sem and i_alloc_sem
++	 *	writers need to grab i_alloc_sem only (i_sem is already held)
++	 */
++	needs_locking = 0;
++	if (S_ISREG(inode->i_mode) && needs_special_locking) {
++		needs_locking = 1;
++		if (rw == READ) {
++			down(&inode->i_sem);
++			retval = filemap_write_and_wait(inode->i_mapping);
++			if (retval) {
++				up(&inode->i_sem);
++				kfree(dio);
++				goto out;
++			}
++		}
++		down_read(&inode->i_alloc_sem);
++	}
++	dio->needs_locking = needs_locking;
++
++	retval = direct_io_worker(rw, iocb, inode, iov, offset,
++				nr_segs, blkbits, get_blocks, end_io, dio);
++	if (needs_locking && rw == WRITE)
++		down(&inode->i_sem);
+ out:
+ 	return retval;
+ }
++EXPORT_SYMBOL(__blockdev_direct_IO);
+--- linux-2.6.0-test6/fs/dquot.c	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/dquot.c	2003-10-05 00:36:15.000000000 -0700
+@@ -668,12 +668,12 @@ static void print_warning(struct dquot *
+ 
+ 	if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
+ 		return;
+-	tty_write_message(current->tty, dquot->dq_sb->s_id);
++	tty_write_message(process_tty(current), dquot->dq_sb->s_id);
+ 	if (warntype == ISOFTWARN || warntype == BSOFTWARN)
+-		tty_write_message(current->tty, ": warning, ");
++		tty_write_message(process_tty(current), ": warning, ");
+ 	else
+-		tty_write_message(current->tty, ": write failed, ");
+-	tty_write_message(current->tty, quotatypes[dquot->dq_type]);
++		tty_write_message(process_tty(current), ": write failed, ");
++	tty_write_message(process_tty(current), quotatypes[dquot->dq_type]);
+ 	switch (warntype) {
+ 		case IHARDWARN:
+ 			msg = " file limit reached.\n";
+@@ -694,7 +694,7 @@ static void print_warning(struct dquot *
+ 			msg = " block quota exceeded.\n";
+ 			break;
+ 	}
+-	tty_write_message(current->tty, msg);
++	tty_write_message(process_tty(current), msg);
+ }
+ 
+ static inline void flush_warnings(struct dquot **dquots, char *warntype)
+--- linux-2.6.0-test6/fs/efs/super.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/fs/efs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -218,7 +218,11 @@ int efs_fill_super(struct super_block *s
+ 	memset(sb, 0, sizeof(struct efs_sb_info));
+  
+ 	s->s_magic		= EFS_SUPER_MAGIC;
+-	sb_set_blocksize(s, EFS_BLOCKSIZE);
++	if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
++		printk(KERN_ERR "EFS: device does not support %d byte blocks\n",
++			EFS_BLOCKSIZE);
++		goto out_no_fs_ul;
++	}
+   
+ 	/* read the vh (volume header) block */
+ 	bh = sb_bread(s, 0);
+--- linux-2.6.0-test6/fs/eventpoll.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/eventpoll.c	2003-10-05 00:34:03.000000000 -0700
+@@ -740,6 +740,7 @@ static int ep_getfd(int *efd, struct ino
+ 	d_add(dentry, inode);
+ 	file->f_vfsmnt = mntget(eventpoll_mnt);
+ 	file->f_dentry = dget(dentry);
++	file->f_mapping = inode->i_mapping;
+ 
+ 	file->f_pos = 0;
+ 	file->f_flags = O_RDONLY;
+--- linux-2.6.0-test6/fs/exec.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/exec.c	2003-10-05 00:36:15.000000000 -0700
+@@ -83,6 +83,8 @@ int register_binfmt(struct linux_binfmt 
+ 	return 0;	
+ }
+ 
++EXPORT_SYMBOL(register_binfmt);
++
+ int unregister_binfmt(struct linux_binfmt * fmt)
+ {
+ 	struct linux_binfmt ** tmp = &formats;
+@@ -100,6 +102,8 @@ int unregister_binfmt(struct linux_binfm
+ 	return -EINVAL;
+ }
+ 
++EXPORT_SYMBOL(unregister_binfmt);
++
+ static inline void put_binfmt(struct linux_binfmt * fmt)
+ {
+ 	module_put(fmt->module);
+@@ -281,6 +285,8 @@ int copy_strings_kernel(int argc,char **
+ 	return r;
+ }
+ 
++EXPORT_SYMBOL(copy_strings_kernel);
++
+ #ifdef CONFIG_MMU
+ /*
+  * This routine is used to map in a page into an address space: needed by
+@@ -443,6 +449,8 @@ int setup_arg_pages(struct linux_binprm 
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(setup_arg_pages);
++
+ #define free_arg_pages(bprm) do { } while (0)
+ 
+ #else
+@@ -493,6 +501,8 @@ out:
+ 	goto out;
+ }
+ 
++EXPORT_SYMBOL(open_exec);
++
+ int kernel_read(struct file *file, unsigned long offset,
+ 	char *addr, unsigned long count)
+ {
+@@ -508,6 +518,8 @@ int kernel_read(struct file *file, unsig
+ 	return result;
+ }
+ 
++EXPORT_SYMBOL(kernel_read);
++
+ static int exec_mmap(struct mm_struct *mm)
+ {
+ 	struct task_struct *tsk;
+@@ -584,6 +596,11 @@ static inline int de_thread(struct task_
+ 		newsig->group_stop_count = 0;
+ 		newsig->curr_target = NULL;
+ 		init_sigpending(&newsig->shared_pending);
++
++		newsig->pgrp = oldsig->pgrp;
++		newsig->session = oldsig->session;
++		newsig->leader = oldsig->leader;
++		newsig->tty_old_pgrp = oldsig->tty_old_pgrp;
+ 	}
+ 
+ 	if (thread_group_empty(current))
+@@ -822,6 +839,8 @@ out:
+ 	return retval;
+ }
+ 
++EXPORT_SYMBOL(flush_old_exec);
++
+ /*
+  * We mustn't allow tracing of suid binaries, unless
+  * the tracer has the capability to trace anything..
+@@ -878,6 +897,8 @@ int prepare_binprm(struct linux_binprm *
+ 	return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
+ }
+ 
++EXPORT_SYMBOL(prepare_binprm);
++
+ /*
+  * This function is used to produce the new IDs and capabilities
+  * from the old ones and the file's capabilities.
+@@ -918,6 +939,8 @@ void compute_creds(struct linux_binprm *
+ 	security_bprm_compute_creds(bprm);
+ }
+ 
++EXPORT_SYMBOL(compute_creds);
++
+ void remove_arg_zero(struct linux_binprm *bprm)
+ {
+ 	if (bprm->argc) {
+@@ -942,6 +965,8 @@ inside:
+ 	}
+ }
+ 
++EXPORT_SYMBOL(remove_arg_zero);
++
+ /*
+  * cycle the list of binary formats handler, until one recognizes the image
+  */
+@@ -1037,6 +1062,8 @@ int search_binary_handler(struct linux_b
+ 	return retval;
+ }
+ 
++EXPORT_SYMBOL(search_binary_handler);
++
+ /*
+  * sys_execve() executes a new program.
+  */
+@@ -1133,6 +1160,8 @@ out_file:
+ 	return retval;
+ }
+ 
++EXPORT_SYMBOL(do_execve);
++
+ int set_binfmt(struct linux_binfmt *new)
+ {
+ 	struct linux_binfmt *old = current->binfmt;
+@@ -1147,6 +1176,8 @@ int set_binfmt(struct linux_binfmt *new)
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(set_binfmt);
++
+ #define CORENAME_MAX_SIZE 64
+ 
+ /* format_corename will inspect the pattern parameter, and output a
+--- linux-2.6.0-test6/fs/ext2/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/ext2/inode.c	2003-10-05 00:36:59.000000000 -0700
+@@ -257,11 +257,12 @@ static int ext2_block_to_path(struct ino
+  *	or when it reads all @depth-1 indirect blocks successfully and finds
+  *	the whole chain, all way to the data (returns %NULL, *err == 0).
+  */
+-static Indirect *ext2_get_branch(struct inode *inode,
++static Indirect *ext2_get_branch_wq(struct inode *inode,
+ 				 int depth,
+ 				 int *offsets,
+ 				 Indirect chain[4],
+-				 int *err)
++				 int *err,
++				 wait_queue_t *wait)
+ {
+ 	struct super_block *sb = inode->i_sb;
+ 	Indirect *p = chain;
+@@ -273,8 +274,8 @@ static Indirect *ext2_get_branch(struct 
+ 	if (!p->key)
+ 		goto no_block;
+ 	while (--depth) {
+-		bh = sb_bread(sb, le32_to_cpu(p->key));
+-		if (!bh)
++		bh = sb_bread_wq(sb, le32_to_cpu(p->key), wait);
++		if (!bh || IS_ERR(bh))
+ 			goto failure;
+ 		read_lock(&EXT2_I(inode)->i_meta_lock);
+ 		if (!verify_chain(chain, p))
+@@ -292,11 +293,21 @@ changed:
+ 	*err = -EAGAIN;
+ 	goto no_block;
+ failure:
+-	*err = -EIO;
++	*err = IS_ERR(bh) ? PTR_ERR(bh) : -EIO;
+ no_block:
+ 	return p;
+ }
+ 
++static Indirect *ext2_get_branch(struct inode *inode,
++				 int depth,
++				 int *offsets,
++				 Indirect chain[4],
++				 int *err)
++{
++	return ext2_get_branch_wq(inode, depth, offsets, chain,
++		err, NULL);
++}
++
+ /**
+  *	ext2_find_near - find a place for allocation with sufficient locality
+  *	@inode: owner
+@@ -536,7 +547,8 @@ changed:
+  * reachable from inode.
+  */
+ 
+-static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
++static int ext2_get_block_wq(struct inode *inode, sector_t iblock,
++	struct buffer_head *bh_result, int create, wait_queue_t *wait)
+ {
+ 	int err = -EIO;
+ 	int offsets[4];
+@@ -551,7 +563,8 @@ static int ext2_get_block(struct inode *
+ 		goto out;
+ 
+ reread:
+-	partial = ext2_get_branch(inode, depth, offsets, chain, &err);
++	partial = ext2_get_branch_wq(inode, depth, offsets, chain, &err,
++		wait);
+ 
+ 	/* Simplest case - block found, no allocation needed */
+ 	if (!partial) {
+@@ -565,7 +578,7 @@ got_it:
+ 	}
+ 
+ 	/* Next simple case - plain lookup or failed read of indirect block */
+-	if (!create || err == -EIO) {
++	if (!create || err == -EIO || err == -EIOCBRETRY) {
+ cleanup:
+ 		while (partial > chain) {
+ 			brelse(partial->bh);
+@@ -606,6 +619,19 @@ changed:
+ 	goto reread;
+ }
+ 
++static int ext2_get_block_async(struct inode *inode, sector_t iblock,
++	struct buffer_head *bh_result, int create)
++{
++	return ext2_get_block_wq(inode, iblock, bh_result, create,
++		current->io_wait);
++}
++
++static int ext2_get_block(struct inode *inode, sector_t iblock,
++	struct buffer_head *bh_result, int create)
++{
++	return ext2_get_block_wq(inode, iblock, bh_result, create, NULL);
++}
++
+ static int ext2_writepage(struct page *page, struct writeback_control *wbc)
+ {
+ 	return block_write_full_page(page, ext2_get_block, wbc);
+@@ -627,7 +653,7 @@ static int
+ ext2_prepare_write(struct file *file, struct page *page,
+ 			unsigned from, unsigned to)
+ {
+-	return block_prepare_write(page,from,to,ext2_get_block);
++	return block_prepare_write(page,from,to,ext2_get_block_async);
+ }
+ 
+ static int
+@@ -659,7 +685,7 @@ ext2_direct_IO(int rw, struct kiocb *ioc
+ 			loff_t offset, unsigned long nr_segs)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode *inode = file->f_mapping->host;
+ 
+ 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ 				offset, nr_segs, ext2_get_blocks, NULL);
+@@ -1228,6 +1254,7 @@ static int ext2_update_inode(struct inod
+ 			raw_inode->i_block[0] = 0;
+ 			raw_inode->i_block[1] =
+ 				cpu_to_le32(new_encode_dev(inode->i_rdev));
++			raw_inode->i_block[2] = 0;
+ 		}
+ 	} else for (n = 0; n < EXT2_N_BLOCKS; n++)
+ 		raw_inode->i_block[n] = ei->i_data[n];
+--- linux-2.6.0-test6/fs/ext2/super.c	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/ext2/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -22,6 +22,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
++#include <linux/parser.h>
+ #include <linux/random.h>
+ #include <linux/buffer_head.h>
+ #include <linux/smp_lock.h>
+@@ -265,149 +266,157 @@ static unsigned long get_sb_block(void *
+ 	return sb_block;
+ }
+ 
+-static int want_value(char *value, char *option)
+-{
+-	if (!value || !*value) {
+-		printk(KERN_NOTICE "EXT2-fs: the %s option needs an argument\n",
+-		       option);
+-		return -1;
+-	}
+-	return 0;
+-}
+-
+-static int want_null_value(char *value, char *option)
+-{
+-	if (*value) {
+-		printk(KERN_NOTICE "EXT2-fs: Invalid %s argument: %s\n",
+-		       option, value);
+-		return -1;
+-	}
+-	return 0;
+-}
++enum {
++	Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
++	Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
++	Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
++	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
++	Opt_ignore, Opt_err,
++};
+ 
+-static int want_numeric(char *value, char *option, unsigned long *number)
+-{
+-	if (want_value(value, option))
+-		return -1;
+-	*number = simple_strtoul(value, &value, 0);
+-	if (want_null_value(value, option))
+-		return -1;
+-	return 0;
+-}
++static match_table_t tokens = {
++	{Opt_bsd_df, "bsddf"},
++	{Opt_minix_df, "minixdf"},
++	{Opt_grpid, "grpid"},
++	{Opt_grpid, "bsdgroups"},
++	{Opt_nogrpid, "nogrpid"},
++	{Opt_nogrpid, "sysvgroups"},
++	{Opt_resgid, "resgid=%d"},
++	{Opt_resuid, "resuid=%d"},
++	{Opt_sb, "sb=%d"},
++	{Opt_err_cont, "errors=continue"},
++	{Opt_err_panic, "errors=panic"},
++	{Opt_err_ro, "errors=remount-ro"},
++	{Opt_nouid32, "nouid32"},
++	{Opt_nocheck, "check=none"},
++	{Opt_nocheck, "nocheck"},
++	{Opt_check, "check"},
++	{Opt_debug, "debug"},
++	{Opt_oldalloc, "oldalloc"},
++	{Opt_orlov, "orlov"},
++	{Opt_nobh, "nobh"},
++	{Opt_user_xattr, "user_xattr"},
++	{Opt_nouser_xattr, "nouser_xattr"},
++	{Opt_acl, "acl"},
++	{Opt_noacl, "noacl"},
++	{Opt_ignore, "grpquota"},
++	{Opt_ignore, "noquota"},
++	{Opt_ignore, "quota"},
++	{Opt_ignore, "usrquota"},
++	{Opt_err, NULL}
++};
+ 
+-/*
+- * This function has been shamelessly adapted from the msdos fs
+- */
+ static int parse_options (char * options,
+ 			  struct ext2_sb_info *sbi)
+ {
+-	char * this_char;
+-	char * value;
++	char * p;
++	substring_t args[MAX_OPT_ARGS];
++	unsigned long kind = EXT2_MOUNT_ERRORS_CONT;
++	int option;
+ 
+ 	if (!options)
+ 		return 1;
+-	while ((this_char = strsep (&options, ",")) != NULL) {
+-		if (!*this_char)
++
++	while ((p = strsep (&options, ",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr (this_char, '=')) != NULL)
+-			*value++ = 0;
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_bsd_df:
++			clear_opt (sbi->s_mount_opt, MINIX_DF);
++			break;
++		case Opt_minix_df:
++			set_opt (sbi->s_mount_opt, MINIX_DF);
++			break;
++		case Opt_grpid:
++			set_opt (sbi->s_mount_opt, GRPID);
++			break;
++		case Opt_nogrpid:
++			clear_opt (sbi->s_mount_opt, GRPID);
++			break;
++		case Opt_resuid:
++			if (match_int(&args[0], &option))
++				return 0;
++			sbi->s_resuid = option;
++			break;
++		case Opt_resgid:
++			if (match_int(&args[0], &option))
++				return 0;
++			sbi->s_resgid = option;
++			break;
++		case Opt_sb:
++			/* handled by get_sb_block() instead of here */
++			/* *sb_block = match_int(&args[0]); */
++			break;
++		case Opt_err_panic:
++			kind = EXT2_MOUNT_ERRORS_PANIC;
++			break;
++		case Opt_err_ro:
++			kind = EXT2_MOUNT_ERRORS_RO;
++			break;
++		case Opt_err_cont:
++			kind = EXT2_MOUNT_ERRORS_CONT;
++			break;
++		case Opt_nouid32:
++			set_opt (sbi->s_mount_opt, NO_UID32);
++			break;
++		case Opt_check:
++#ifdef CONFIG_EXT2_CHECK
++			set_opt (sbi->s_mount_opt, CHECK);
++#else
++			printk("EXT2 Check option not supported\n");
++#endif
++			break;
++		case Opt_nocheck:
++			clear_opt (sbi->s_mount_opt, CHECK);
++			break;
++		case Opt_debug:
++			set_opt (sbi->s_mount_opt, DEBUG);
++			break;
++		case Opt_oldalloc:
++			set_opt (sbi->s_mount_opt, OLDALLOC);
++			break;
++		case Opt_orlov:
++			clear_opt (sbi->s_mount_opt, OLDALLOC);
++			break;
++		case Opt_nobh:
++			set_opt (sbi->s_mount_opt, NOBH);
++			break;
+ #ifdef CONFIG_EXT2_FS_XATTR
+-		if (!strcmp (this_char, "user_xattr"))
++		case Opt_user_xattr:
+ 			set_opt (sbi->s_mount_opt, XATTR_USER);
+-		else if (!strcmp (this_char, "nouser_xattr"))
++			break;
++		case Opt_nouser_xattr:
+ 			clear_opt (sbi->s_mount_opt, XATTR_USER);
+-		else
++			break;
++#else
++		case Opt_user_xattr:
++		case Opt_nouser_xattr:
++			printk("EXT2 (no)user_xattr options not supported\n");
++			break;
+ #endif
+ #ifdef CONFIG_EXT2_FS_POSIX_ACL
+-		if (!strcmp(this_char, "acl"))
++		case Opt_acl:
+ 			set_opt(sbi->s_mount_opt, POSIX_ACL);
+-		else if (!strcmp(this_char, "noacl"))
++			break;
++		case Opt_noacl:
+ 			clear_opt(sbi->s_mount_opt, POSIX_ACL);
+-		else
+-#endif
+-		if (!strcmp (this_char, "bsddf"))
+-			clear_opt (sbi->s_mount_opt, MINIX_DF);
+-		else if (!strcmp (this_char, "nouid32")) {
+-			set_opt (sbi->s_mount_opt, NO_UID32);
+-		}
+-		else if (!strcmp (this_char, "check")) {
+-			if (!value || !*value || !strcmp (value, "none"))
+-				clear_opt (sbi->s_mount_opt, CHECK);
+-			else
+-#ifdef CONFIG_EXT2_CHECK
+-				set_opt (sbi->s_mount_opt, CHECK);
++			break;
+ #else
+-				printk("EXT2 Check option not supported\n");
++		case Opt_acl:
++		case Opt_noacl:
++			printk("EXT2 (no)acl options not supported\n");
++			break;
+ #endif
+-		}
+-		else if (!strcmp (this_char, "debug"))
+-			set_opt (sbi->s_mount_opt, DEBUG);
+-		else if (!strcmp (this_char, "errors")) {
+-			if (!value || !*value) {
+-				printk ("EXT2-fs: the errors option requires "
+-					"an argument\n");
+-				return 0;
+-			}
+-			if (!strcmp (value, "continue")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+-				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-				set_opt (sbi->s_mount_opt, ERRORS_CONT);
+-			}
+-			else if (!strcmp (value, "remount-ro")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+-				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-				set_opt (sbi->s_mount_opt, ERRORS_RO);
+-			}
+-			else if (!strcmp (value, "panic")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+-				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+-				set_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-			}
+-			else {
+-				printk ("EXT2-fs: Invalid errors option: %s\n",
+-					value);
+-				return 0;
+-			}
+-		}
+-		else if (!strcmp (this_char, "grpid") ||
+-			 !strcmp (this_char, "bsdgroups"))
+-			set_opt (sbi->s_mount_opt, GRPID);
+-		else if (!strcmp (this_char, "minixdf"))
+-			set_opt (sbi->s_mount_opt, MINIX_DF);
+-		else if (!strcmp (this_char, "nocheck"))
+-			clear_opt (sbi->s_mount_opt, CHECK);
+-		else if (!strcmp (this_char, "nogrpid") ||
+-			 !strcmp (this_char, "sysvgroups"))
+-			clear_opt (sbi->s_mount_opt, GRPID);
+-		else if (!strcmp (this_char, "resgid")) {
+-			unsigned long v;
+-			if (want_numeric(value, "resgid", &v))
+-				return 0;
+-			sbi->s_resgid = v;
+-		}
+-		else if (!strcmp (this_char, "resuid")) {
+-			unsigned long v;
+-			if (want_numeric(value, "resuid", &v))
+-				return 0;
+-			sbi->s_resuid = v;
+-		}
+-		else if (!strcmp (this_char, "oldalloc"))
+-			set_opt (sbi->s_mount_opt, OLDALLOC);
+-		else if (!strcmp (this_char, "orlov"))
+-			clear_opt (sbi->s_mount_opt, OLDALLOC);
+-		else if (!strcmp (this_char, "nobh"))
+-			set_opt(sbi->s_mount_opt, NOBH);
+-		/* Silently ignore the quota options */
+-		else if (!strcmp (this_char, "grpquota")
+-		         || !strcmp (this_char, "noquota")
+-		         || !strcmp (this_char, "quota")
+-		         || !strcmp (this_char, "usrquota"))
+-			/* Don't do anything ;-) */ ;
+-		else {
+-			printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
++		case Opt_ignore:
++			break;
++		default:
+ 			return 0;
+ 		}
+ 	}
++	sbi->s_mount_opt |= kind;
+ 	return 1;
+ }
+ 
+--- linux-2.6.0-test6/fs/ext3/file.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/ext3/file.c	2003-10-05 00:33:24.000000000 -0700
+@@ -47,7 +47,7 @@ static int ext3_release_file (struct ino
+  * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
+  * on this flag in sys_open.
+  */
+-static int ext3_open_file (struct inode * inode, struct file * filp)
++static int ext3_open_file (struct inode *inode, struct file *filp)
+ {
+ 	if (!(filp->f_flags & O_LARGEFILE) &&
+ 	    inode->i_size > 0x7FFFFFFFLL)
+@@ -56,7 +56,7 @@ static int ext3_open_file (struct inode 
+ }
+ 
+ static ssize_t
+-ext3_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
++ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+ {
+ 	struct file *file = iocb->ki_filp;
+ 	struct inode *inode = file->f_dentry->d_inode;
+@@ -117,8 +117,8 @@ struct file_operations ext3_file_operati
+ 	.llseek		= generic_file_llseek,
+ 	.read		= do_sync_read,
+ 	.write		= do_sync_write,
+-	.aio_read		= generic_file_aio_read,
+-	.aio_write		= ext3_file_write,
++	.aio_read	= generic_file_aio_read,
++	.aio_write	= ext3_file_write,
+ 	.readv		= generic_file_readv,
+ 	.writev		= generic_file_writev,
+ 	.ioctl		= ext3_ioctl,
+--- linux-2.6.0-test6/fs/ext3/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/ext3/inode.c	2003-10-05 00:36:12.000000000 -0700
+@@ -812,15 +812,17 @@ out:
+ 	if (err == -EAGAIN)
+ 		goto changed;
+ 
+-	if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0)
++	down(&ei->truncate_sem);
++	if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0) {
++		up(&ei->truncate_sem);
+ 		goto changed;
++	}
+ 
+ 	left = (chain + depth) - partial;
+ 
+ 	/*
+ 	 * Block out ext3_truncate while we alter the tree
+ 	 */
+-	down_read(&ei->truncate_sem);
+ 	err = ext3_alloc_branch(handle, inode, left, goal,
+ 					offsets+(partial-chain), partial);
+ 
+@@ -832,7 +834,7 @@ out:
+ 	if (!err)
+ 		err = ext3_splice_branch(handle, inode, iblock, chain,
+ 					 partial, left);
+-	up_read(&ei->truncate_sem);
++	up(&ei->truncate_sem);
+ 	if (err == -EAGAIN)
+ 		goto changed;
+ 	if (err)
+@@ -1537,7 +1539,7 @@ static int ext3_direct_IO(int rw, struct
+ 			unsigned long nr_segs)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode *inode = file->f_mapping->host;
+ 	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	handle_t *handle = NULL;
+ 	int ret;
+@@ -2205,7 +2207,7 @@ void ext3_truncate(struct inode * inode)
+ 	 * From here we block out all ext3_get_block() callers who want to
+ 	 * modify the block allocation tree.
+ 	 */
+-	down_write(&ei->truncate_sem);
++	down(&ei->truncate_sem);
+ 
+ 	if (n == 1) {		/* direct blocks */
+ 		ext3_free_data(handle, inode, NULL, i_data+offsets[0],
+@@ -2269,7 +2271,7 @@ do_indirects:
+ 		case EXT3_TIND_BLOCK:
+ 			;
+ 	}
+-	up_write(&ei->truncate_sem);
++	up(&ei->truncate_sem);
+ 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 
+@@ -2679,6 +2681,7 @@ static int ext3_do_update_inode(handle_t
+ 			raw_inode->i_block[0] = 0;
+ 			raw_inode->i_block[1] =
+ 				cpu_to_le32(new_encode_dev(inode->i_rdev));
++			raw_inode->i_block[2] = 0;
+ 		}
+ 	} else for (block = 0; block < EXT3_N_BLOCKS; block++)
+ 		raw_inode->i_block[block] = ei->i_data[block];
+--- linux-2.6.0-test6/fs/ext3/super.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/ext3/super.c	2003-10-05 00:36:12.000000000 -0700
+@@ -27,6 +27,7 @@
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/blkdev.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+@@ -459,7 +460,7 @@ static void init_once(void * foo, kmem_c
+ #ifdef CONFIG_EXT3_FS_XATTR
+ 		init_rwsem(&ei->xattr_sem);
+ #endif
+-		init_rwsem(&ei->truncate_sem);
++		init_MUTEX(&ei->truncate_sem);
+ 		inode_init_once(&ei->vfs_inode);
+ 	}
+ }
+@@ -526,36 +527,54 @@ static struct export_operations ext3_exp
+ 	.get_parent = ext3_get_parent,
+ };
+ 
++enum {
++	Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
++	Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
++	Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
++	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
++	Opt_commit, Opt_journal_update, Opt_journal_inum,
++	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
++	Opt_ignore, Opt_err,
++};
+ 
+-static int want_value(char *value, char *option)
+-{
+-	if (!value || !*value) {
+-		printk(KERN_NOTICE "EXT3-fs: the %s option needs an argument\n",
+-		       option);
+-		return -1;
+-	}
+-	return 0;
+-}
+-
+-static int want_null_value(char *value, char *option)
+-{
+-	if (*value) {
+-		printk(KERN_NOTICE "EXT3-fs: Invalid %s argument: %s\n",
+-		       option, value);
+-		return -1;
+-	}
+-	return 0;
+-}
+-
+-static int want_numeric(char *value, char *option, unsigned long *number)
+-{
+-	if (want_value(value, option))
+-		return -1;
+-	*number = simple_strtoul(value, &value, 0);
+-	if (want_null_value(value, option))
+-		return -1;
+-	return 0;
+-}
++static match_table_t tokens = {
++	{Opt_bsd_df, "bsddf"},
++	{Opt_minix_df, "minixdf"},
++	{Opt_grpid, "grpid"},
++	{Opt_grpid, "bsdgroups"},
++	{Opt_nogrpid, "nogrpid"},
++	{Opt_nogrpid, "sysvgroups"},
++	{Opt_resgid, "resgid=%d"},
++	{Opt_resuid, "resuid=%d"},
++	{Opt_sb, "sb=%d"},
++	{Opt_err_cont, "errors=continue"},
++	{Opt_err_panic, "errors=panic"},
++	{Opt_err_ro, "errors=remount-ro"},
++	{Opt_nouid32, "nouid32"},
++	{Opt_nocheck, "nocheck"},
++	{Opt_nocheck, "check=none"},
++	{Opt_check, "check"},
++	{Opt_debug, "debug"},
++	{Opt_oldalloc, "oldalloc"},
++	{Opt_orlov, "orlov"},
++	{Opt_user_xattr, "user_xattr"},
++	{Opt_nouser_xattr, "nouser_xattr"},
++	{Opt_acl, "acl"},
++	{Opt_noacl, "noacl"},
++	{Opt_noload, "noload"},
++	{Opt_commit, "commit=%u"},
++	{Opt_journal_update, "journal=update"},
++	{Opt_journal_inum, "journal=%u"},
++	{Opt_abort, "abort"},
++	{Opt_data_journal, "data=journal"},
++	{Opt_data_ordered, "data=ordered"},
++	{Opt_data_writeback, "data=writeback"},
++	{Opt_ignore, "grpquota"},
++	{Opt_ignore, "noquota"},
++	{Opt_ignore, "quota"},
++	{Opt_ignore, "usrquota"},
++	{Opt_err, NULL}
++};
+ 
+ static unsigned long get_sb_block(void **data)
+ {
+@@ -577,175 +596,180 @@ static unsigned long get_sb_block(void *
+ 	return sb_block;
+ }
+ 
+-/*
+- * This function has been shamelessly adapted from the msdos fs
+- */
+ static int parse_options (char * options, struct ext3_sb_info *sbi,
+ 			  unsigned long * inum, int is_remount)
+ {
+-	char * this_char;
+-	char * value;
++	char * p;
++	substring_t args[MAX_OPT_ARGS];
++	int data_opt = 0;
++	int option;
+ 
+ 	if (!options)
+ 		return 1;
+-	while ((this_char = strsep (&options, ",")) != NULL) {
+-		if (!*this_char)
++
++	while ((p = strsep (&options, ",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr (this_char, '=')) != NULL)
+-			*value++ = 0;
+-#ifdef CONFIG_EXT3_FS_XATTR
+-		if (!strcmp (this_char, "user_xattr"))
+-			set_opt (sbi->s_mount_opt, XATTR_USER);
+-		else if (!strcmp (this_char, "nouser_xattr"))
+-			clear_opt (sbi->s_mount_opt, XATTR_USER);
+-		else
+-#endif
+-#ifdef CONFIG_EXT3_FS_POSIX_ACL
+-		if (!strcmp(this_char, "acl"))
+-			set_opt (sbi->s_mount_opt, POSIX_ACL);
+-		else if (!strcmp(this_char, "noacl"))
+-			clear_opt (sbi->s_mount_opt, POSIX_ACL);
+-		else
+-#endif
+-		if (!strcmp (this_char, "bsddf"))
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_bsd_df:
+ 			clear_opt (sbi->s_mount_opt, MINIX_DF);
+-		else if (!strcmp (this_char, "nouid32")) {
++			break;
++		case Opt_minix_df:
++			set_opt (sbi->s_mount_opt, MINIX_DF);
++			break;
++		case Opt_grpid:
++			set_opt (sbi->s_mount_opt, GRPID);
++			break;
++		case Opt_nogrpid:
++			clear_opt (sbi->s_mount_opt, GRPID);
++			break;
++		case Opt_resuid:
++			if (match_int(&args[0], &option))
++				return 0;
++			sbi->s_resuid = option;
++			break;
++		case Opt_resgid:
++			if (match_int(&args[0], &option))
++				return 0;
++			sbi->s_resgid = option;
++			break;
++		case Opt_sb:
++			/* handled by get_sb_block() instead of here */
++			/* *sb_block = match_int(&args[0]); */
++			break;
++		case Opt_err_panic:
++			clear_opt (sbi->s_mount_opt, ERRORS_CONT);
++			clear_opt (sbi->s_mount_opt, ERRORS_RO);
++			set_opt (sbi->s_mount_opt, ERRORS_PANIC);
++			break;
++		case Opt_err_ro:
++			clear_opt (sbi->s_mount_opt, ERRORS_CONT);
++			clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
++			set_opt (sbi->s_mount_opt, ERRORS_RO);
++			break;
++		case Opt_err_cont:
++			clear_opt (sbi->s_mount_opt, ERRORS_RO);
++			clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
++			set_opt (sbi->s_mount_opt, ERRORS_CONT);
++			break;
++		case Opt_nouid32:
+ 			set_opt (sbi->s_mount_opt, NO_UID32);
+-		}
+-		else if (!strcmp (this_char, "abort"))
+-			set_opt (sbi->s_mount_opt, ABORT);
+-		else if (!strcmp (this_char, "check")) {
+-			if (!value || !*value || !strcmp (value, "none"))
+-				clear_opt (sbi->s_mount_opt, CHECK);
+-			else
++			break;
++		case Opt_check:
+ #ifdef CONFIG_EXT3_CHECK
+-				set_opt (sbi->s_mount_opt, CHECK);
++			set_opt (sbi->s_mount_opt, CHECK);
+ #else
+-				printk(KERN_ERR 
+-				       "EXT3 Check option not supported\n");
++			printk(KERN_ERR
++			       "EXT3 Check option not supported\n");
+ #endif
+-		}
+-		else if (!strcmp (this_char, "debug"))
+-			set_opt (sbi->s_mount_opt, DEBUG);
+-		else if (!strcmp (this_char, "errors")) {
+-			if (want_value(value, "errors"))
+-				return 0;
+-			if (!strcmp (value, "continue")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+-				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-				set_opt (sbi->s_mount_opt, ERRORS_CONT);
+-			}
+-			else if (!strcmp (value, "remount-ro")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+-				clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-				set_opt (sbi->s_mount_opt, ERRORS_RO);
+-			}
+-			else if (!strcmp (value, "panic")) {
+-				clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+-				clear_opt (sbi->s_mount_opt, ERRORS_RO);
+-				set_opt (sbi->s_mount_opt, ERRORS_PANIC);
+-			}
+-			else {
+-				printk (KERN_ERR
+-					"EXT3-fs: Invalid errors option: %s\n",
+-					value);
+-				return 0;
+-			}
+-		}
+-		else if (!strcmp (this_char, "grpid") ||
+-			 !strcmp (this_char, "bsdgroups"))
+-			set_opt (sbi->s_mount_opt, GRPID);
+-		else if (!strcmp (this_char, "minixdf"))
+-			set_opt (sbi->s_mount_opt, MINIX_DF);
+-		else if (!strcmp (this_char, "nocheck"))
++			break;
++		case Opt_nocheck:
+ 			clear_opt (sbi->s_mount_opt, CHECK);
+-		else if (!strcmp (this_char, "nogrpid") ||
+-			 !strcmp (this_char, "sysvgroups"))
+-			clear_opt (sbi->s_mount_opt, GRPID);
+-		else if (!strcmp (this_char, "resgid")) {
+-			unsigned long v;
+-			if (want_numeric(value, "resgid", &v))
+-				return 0;
+-			sbi->s_resgid = v;
+-		}
+-		else if (!strcmp (this_char, "resuid")) {
+-			unsigned long v;
+-			if (want_numeric(value, "resuid", &v))
+-				return 0;
+-			sbi->s_resuid = v;
+-		}
+-		else if (!strcmp (this_char, "oldalloc"))
++			break;
++		case Opt_debug:
++			set_opt (sbi->s_mount_opt, DEBUG);
++			break;
++		case Opt_oldalloc:
+ 			set_opt (sbi->s_mount_opt, OLDALLOC);
+-		else if (!strcmp (this_char, "orlov"))
++			break;
++		case Opt_orlov:
+ 			clear_opt (sbi->s_mount_opt, OLDALLOC);
+-		/* Silently ignore the quota options */
+-		else if (!strcmp (this_char, "grpquota")
+-		         || !strcmp (this_char, "noquota")
+-		         || !strcmp (this_char, "quota")
+-		         || !strcmp (this_char, "usrquota"))
+-			/* Don't do anything ;-) */ ;
+-		else if (!strcmp (this_char, "journal")) {
++			break;
++#ifdef CONFIG_EXT3_FS_XATTR
++		case Opt_user_xattr:
++			set_opt (sbi->s_mount_opt, XATTR_USER);
++			break;
++		case Opt_nouser_xattr:
++			clear_opt (sbi->s_mount_opt, XATTR_USER);
++			break;
++#else
++		case Opt_user_xattr:
++		case Opt_nouser_xattr:
++			printk("EXT3 (no)user_xattr options not supported\n");
++			break;
++#endif
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++		case Opt_acl:
++			set_opt(sbi->s_mount_opt, POSIX_ACL);
++			break;
++		case Opt_noacl:
++			clear_opt(sbi->s_mount_opt, POSIX_ACL);
++			break;
++#else
++		case Opt_acl:
++		case Opt_noacl:
++			printk("EXT3 (no)acl options not supported\n");
++			break;
++#endif
++		case Opt_journal_update:
+ 			/* @@@ FIXME */
+ 			/* Eventually we will want to be able to create
+-                           a journal file here.  For now, only allow the
+-                           user to specify an existing inode to be the
+-                           journal file. */
++			   a journal file here.  For now, only allow the
++			   user to specify an existing inode to be the
++			   journal file. */
+ 			if (is_remount) {
+ 				printk(KERN_ERR "EXT3-fs: cannot specify "
+ 				       "journal on remount\n");
+ 				return 0;
+ 			}
+-
+-			if (want_value(value, "journal"))
++			set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
++			break;
++		case Opt_journal_inum:
++			if (is_remount) {
++				printk(KERN_ERR "EXT3-fs: cannot specify "
++				       "journal on remount\n");
+ 				return 0;
+-			if (!strcmp (value, "update"))
+-				set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
+-			else if (want_numeric(value, "journal", inum))
++			}
++			if (match_int(&args[0], &option))
+ 				return 0;
+-		}
+-		else if (!strcmp (this_char, "noload"))
++			*inum = option;
++			break;
++		case Opt_noload:
+ 			set_opt (sbi->s_mount_opt, NOLOAD);
+-		else if (!strcmp (this_char, "data")) {
+-			int data_opt = 0;
+-
+-			if (want_value(value, "data"))
+-				return 0;
+-			if (!strcmp (value, "journal"))
+-				data_opt = EXT3_MOUNT_JOURNAL_DATA;
+-			else if (!strcmp (value, "ordered"))
+-				data_opt = EXT3_MOUNT_ORDERED_DATA;
+-			else if (!strcmp (value, "writeback"))
+-				data_opt = EXT3_MOUNT_WRITEBACK_DATA;
+-			else {
+-				printk (KERN_ERR 
+-					"EXT3-fs: Invalid data option: %s\n",
+-					value);
++			break;
++		case Opt_commit:
++			if (match_int(&args[0], &option))
+ 				return 0;
+-			}
++			sbi->s_commit_interval = HZ * option;
++			break;
++		case Opt_data_journal:
++			data_opt = EXT3_MOUNT_JOURNAL_DATA;
++			goto datacheck;
++		case Opt_data_ordered:
++			data_opt = EXT3_MOUNT_ORDERED_DATA;
++			goto datacheck;
++		case Opt_data_writeback:
++			data_opt = EXT3_MOUNT_WRITEBACK_DATA;
++		datacheck:
+ 			if (is_remount) {
+-				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) !=
+-							data_opt) {
++				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
++						!= data_opt) {
+ 					printk(KERN_ERR
+-					       "EXT3-fs: cannot change data "
+-					       "mode on remount\n");
++						"EXT3-fs: cannot change data "
++						"mode on remount\n");
+ 					return 0;
+ 				}
+ 			} else {
+ 				sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
+ 				sbi->s_mount_opt |= data_opt;
+ 			}
+-		} else if (!strcmp (this_char, "commit")) {
+-			unsigned long v;
+-			if (want_numeric(value, "commit", &v))
+-				return 0;
+-			sbi->s_commit_interval = (HZ * v);
+-		} else {
+-			printk (KERN_ERR 
+-				"EXT3-fs: Unrecognized mount option %s\n",
+-				this_char);
++			break;
++		case Opt_abort:
++			set_opt(sbi->s_mount_opt, ABORT);
++			break;
++		case Opt_ignore:
++			break;
++		default:
++			printk (KERN_ERR
++				"EXT3-fs: Unrecognized mount option \"%s\" "
++				"or missing value\n", p);
+ 			return 0;
+ 		}
+ 	}
++
+ 	return 1;
+ }
+ 
+--- linux-2.6.0-test6/fs/ext3/symlink.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/fs/ext3/symlink.c	2003-10-05 00:33:24.000000000 -0700
+@@ -22,7 +22,8 @@
+ #include <linux/ext3_fs.h>
+ #include "xattr.h"
+ 
+-static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int
++ext3_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+ 	struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
+ 	return vfs_readlink(dentry, buffer, buflen, (char*)ei->i_data);
+--- linux-2.6.0-test6/fs/fat/dir.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/fat/dir.c	2003-10-05 00:33:24.000000000 -0700
+@@ -663,7 +663,7 @@ int fat_dir_ioctl(struct inode * inode, 
+ 		return -EINVAL;
+ 	}
+ 
+-	d1 = (struct dirent *)arg;
++	d1 = (struct dirent __user *)arg;
+ 	if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
+ 		return -EFAULT;
+ 	/*
+--- linux-2.6.0-test6/fs/fat/inode.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/fat/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -20,6 +20,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/mount.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/unaligned.h>
+ 
+ /*
+@@ -183,20 +184,6 @@ void fat_put_super(struct super_block *s
+ 	kfree(sbi);
+ }
+ 
+-static int simple_getbool(char *s, int *setval)
+-{
+-	if (s) {
+-		if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true"))
+-			*setval = 1;
+-		else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false"))
+-			*setval = 0;
+-		else
+-			return 0;
+-	} else
+-		*setval = 1;
+-	return 1;
+-}
+-
+ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
+ {
+ 	struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
+@@ -259,11 +246,95 @@ static int fat_show_options(struct seq_f
+ 	return 0;
+ }
+ 
++static void print_obsolete_option(char *optname)
++{
++	printk(KERN_INFO "FAT: %s option is obsolete, "
++			"not supported now\n", optname);
++}
++
++enum {
++	Opt_blocksize, Opt_charset, Opt_check_n, Opt_check_r, Opt_check_s,
++	Opt_fat, Opt_codepage, Opt_conv_a, Opt_conv_b, Opt_conv_t,
++	Opt_debug, Opt_dots, Opt_err, Opt_gid, Opt_immutable,
++	Opt_nocase, Opt_nodots, Opt_quiet, Opt_showexec, Opt_uid,
++	Opt_shortname_lower, Opt_shortname_win95, Opt_shortname_winnt, Opt_shortname_mixed,
++	Opt_umask, Opt_dmask, Opt_fmask, Opt_posix, Opt_cvf_format, Opt_cvf_options,
++	Opt_utf8_off, Opt_utf8_no, Opt_utf8_false,
++	Opt_utf8_on, Opt_utf8_yes, Opt_utf8_true, Opt_utf8_opt,
++	Opt_uni_xl_off, Opt_uni_xl_no, Opt_uni_xl_false,
++	Opt_uni_xl_on, Opt_uni_xl_yes, Opt_uni_xl_true, Opt_uni_xl_opt,
++	Opt_nonumtail_off, Opt_nonumtail_no, Opt_nonumtail_false,
++	Opt_nonumtail_on, Opt_nonumtail_yes, Opt_nonumtail_true, Opt_nonumtail_opt,
++};
++
++static match_table_t FAT_tokens = {
++	{Opt_check_r, "check=relaxed"},
++	{Opt_check_s, "check=strict"},
++	{Opt_check_n, "check=normal"},
++	{Opt_check_r, "check=r"},
++	{Opt_check_s, "check=s"},
++	{Opt_check_n, "check=n"},
++	{Opt_conv_b, "conv=binary"},
++	{Opt_conv_t, "conv=text"},
++	{Opt_conv_a, "conv=auto"},
++	{Opt_conv_b, "conv=b"},
++	{Opt_conv_t, "conv=t"},
++	{Opt_conv_a, "conv=a"},
++	{Opt_nodots, "nodots"},
++	{Opt_nodots, "dotsOK=no"},
++	{Opt_dots, "dotsOK=yes"},
++	{Opt_dots, "dots"},
++	{Opt_uid, "uid=%d"},
++	{Opt_gid, "gid=%d"},
++	{Opt_umask, "umask=%o"},
++	{Opt_dmask, "dmask=%o"},
++	{Opt_fmask, "fmask=%o"},
++	{Opt_fat, "fat=%d"},
++	{Opt_codepage, "codepage=%d"},
++	{Opt_charset, "iocharset=%s"},
++	{Opt_blocksize, "blocksize=%d"},
++	{Opt_nocase, "nocase"},
++	{Opt_cvf_format, "cvf_format=%20s"},
++	{Opt_cvf_options, "cvf_options=%100s"},
++	{Opt_shortname_lower, "shortname=lower"},
++	{Opt_shortname_win95, "shortname=win95"},
++	{Opt_shortname_winnt, "shortname=winnt"},
++	{Opt_shortname_mixed, "shortname=mixed"},
++	{Opt_utf8_off, "utf8=0"},	/* 0 or no or false */
++	{Opt_utf8_no, "utf8=no"},
++	{Opt_utf8_false, "utf8=false"},
++	{Opt_utf8_on, "utf8=1"},	/* empty or 1 or yes or true */
++	{Opt_utf8_yes, "utf8=yes"},
++	{Opt_utf8_true, "utf8=true"},
++	{Opt_utf8_opt, "utf8"},
++	{Opt_uni_xl_off, "uni_xlate=0"},	/* 0 or no or false */
++	{Opt_uni_xl_no, "uni_xlate=no"},
++	{Opt_uni_xl_false, "uni_xlate=false"},
++	{Opt_uni_xl_on, "uni_xlate=1"},		/* empty or 1 or yes or true */
++	{Opt_uni_xl_yes, "uni_xlate=yes"},
++	{Opt_uni_xl_true, "uni_xlate=true"},
++	{Opt_uni_xl_opt, "uni_xlate"},
++	{Opt_nonumtail_off, "nonumtail=0"},	/* 0 or no or false */
++	{Opt_nonumtail_no, "nonumtail=no"},
++	{Opt_nonumtail_false, "nonumtail=false"},
++	{Opt_nonumtail_on, "nonumtail=1"},	/* empty or 1 or yes or true */
++	{Opt_nonumtail_yes, "nonumtail=yes"},
++	{Opt_nonumtail_true, "nonumtail=true"},
++	{Opt_nonumtail_opt, "nonumtail"},
++	{Opt_quiet, "quiet"},
++	{Opt_showexec, "showexec"},
++	{Opt_debug, "debug"},
++	{Opt_immutable, "sys_immutable"},
++	{Opt_posix, "posix"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options, int is_vfat, int *debug,
+ 			 struct fat_mount_options *opts)
+ {
+-	char *this_char, *value, *p;
+-	int ret = 1, val, len;
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
++	int option;
+ 
+ 	opts->isvfat = is_vfat;
+ 
+@@ -284,183 +355,198 @@ static int parse_options(char *options, 
+ 	*debug = 0;
+ 
+ 	if (!options)
+-		goto out;
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++		return 1;
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+ 
+-		if (!strcmp(this_char,"check") && value) {
+-			if (value[0] && !value[1] && strchr("rns",*value))
+-				opts->name_check = *value;
+-			else if (!strcmp(value,"relaxed"))
+-				opts->name_check = 'r';
+-			else if (!strcmp(value,"normal"))
+-				opts->name_check = 'n';
+-			else if (!strcmp(value,"strict"))
+-				opts->name_check = 's';
+-			else ret = 0;
+-		}
+-		else if (!strcmp(this_char,"conv") && value) {
+-			printk(KERN_INFO "FAT: conv option is obsolete, "
+-			       "not supported now\n");
+-		}
+-		else if (!strcmp(this_char,"nocase")) {
++		token = match_token(p, FAT_tokens, args);
++		switch (token) {
++		case Opt_check_s:
++			opts->name_check = 's';
++			break;
++		case Opt_check_r:
++ 				opts->name_check = 'r';
++			break;
++		case Opt_check_n:
++ 				opts->name_check = 'n';
++			break;
++		case Opt_dots:		/* msdos specific */
++			if (!is_vfat)
++				opts->dotsOK = 1;
++			break;
++		case Opt_nodots:	/* msdos specific */
++			if (!is_vfat)
++				opts->dotsOK = 0;
++			break;
++		case Opt_nocase:
+ 			if (!is_vfat)
+ 				opts->nocase = 1;
+ 			else {
+-				/* for backward compatible */
++				/* for backward compatibility */
+ 				opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ 					| VFAT_SFN_CREATE_WIN95;
+ 			}
+-		}
+-		else if (!strcmp(this_char,"showexec")) {
++			break;
++		case Opt_quiet:
++			opts->quiet = 1;
++			break;
++		case Opt_showexec:
+ 			opts->showexec = 1;
+-		}
+-		else if (!strcmp(this_char,"uid")) {
+-			if (!value || !*value) ret = 0;
+-			else {
+-				opts->fs_uid = simple_strtoul(value,&value,0);
+-				if (*value) ret = 0;
+-			}
+-		}
+-		else if (!strcmp(this_char,"gid")) {
+-			if (!value || !*value) ret= 0;
+-			else {
+-				opts->fs_gid = simple_strtoul(value,&value,0);
+-				if (*value) ret = 0;
+-			}
+-		}
+-		else if (!strcmp(this_char,"umask")) {
+-			if (!value || !*value) ret = 0;
+-			else {
+-				opts->fs_fmask = opts->fs_dmask =
+-					simple_strtoul(value,&value,8);
+-				if (*value) ret = 0;
+-			}
+-		}
+-		else if (!strcmp(this_char,"fmask")) {
+-			if (!value || !*value) ret = 0;
+-			else {
+-				opts->fs_fmask = simple_strtoul(value,&value,8);
+-				if (*value) ret = 0;
+-			}
+-		}
+-		else if (!strcmp(this_char,"dmask")) {
+-			if (!value || !*value) ret = 0;
+-			else {
+-				opts->fs_dmask = simple_strtoul(value,&value,8);
+-				if (*value) ret = 0;
+-			}
+-		}
+-		else if (!strcmp(this_char,"debug")) {
+-			if (value) ret = 0;
+-			else *debug = 1;
+-		}
+-		else if (!strcmp(this_char,"fat")) {
+-			printk(KERN_INFO "FAT: fat option is obsolete, "
+-			       "not supported now\n");
+-		}
+-		else if (!strcmp(this_char,"quiet")) {
+-			if (value) ret = 0;
+-			else opts->quiet = 1;
+-		}
+-		else if (!strcmp(this_char,"blocksize")) {
+-			printk(KERN_INFO "FAT: blocksize option is obsolete, "
+-			       "not supported now\n");
+-		}
+-		else if (!strcmp(this_char,"sys_immutable")) {
+-			if (value) ret = 0;
+-			else opts->sys_immutable = 1;
+-		}
+-		else if (!strcmp(this_char,"codepage") && value) {
+-			opts->codepage = simple_strtoul(value,&value,0);
+-			if (*value) ret = 0;
+-		}
+-
+-		/* msdos specific */
+-		else if (!is_vfat && !strcmp(this_char,"dots")) {
+-			opts->dotsOK = 1;
+-		}
+-		else if (!is_vfat && !strcmp(this_char,"nodots")) {
+-			opts->dotsOK = 0;
+-		}
+-		else if (!is_vfat && !strcmp(this_char,"dotsOK") && value) {
+-			if (!strcmp(value,"yes")) opts->dotsOK = 1;
+-			else if (!strcmp(value,"no")) opts->dotsOK = 0;
+-			else ret = 0;
+-		}
++			break;
++		case Opt_debug:
++			*debug = 1;
++			break;
++		case Opt_immutable:
++			opts->sys_immutable = 1;
++			break;
++		case Opt_uid:
++			if (match_int(&args[0], &option))
++				return 0;
++			opts->fs_uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(&args[0], &option))
++				return 0;
++			opts->fs_gid = option;
++			break;
++		case Opt_umask:
++			if (match_octal(&args[0], &option))
++				return 0;
++			opts->fs_fmask = opts->fs_dmask = option;
++			break;
++		case Opt_dmask:
++			if (match_octal(&args[0], &option))
++				return 0;
++			opts->fs_dmask = option;
++			break;
++		case Opt_fmask:
++			if (match_octal(&args[0], &option))
++				return 0;
++			opts->fs_fmask = option;
++			break;
++		case Opt_codepage:
++			if (match_int(&args[0], &option))
++				return 0;
++			opts->codepage = option;
++			printk("MSDOS FS: Using codepage %d\n",
++ 					opts->codepage);
++			break;
+ 
+ 		/* vfat specific */
+-		else if (is_vfat && !strcmp(this_char,"iocharset") && value) {
+-			p = value;
+-			while (*value && *value != ',')
+-				value++;
+-			len = value - p;
+-			if (len) {
+-				char *buffer;
+-
+-				if (opts->iocharset != NULL) {
+-					kfree(opts->iocharset);
+-					opts->iocharset = NULL;
+-				}
+-				buffer = kmalloc(len + 1, GFP_KERNEL);
+-				if (buffer != NULL) {
+-					opts->iocharset = buffer;
+-					memcpy(buffer, p, len);
+-					buffer[len] = 0;
+-				} else
+-					ret = 0;
++		case Opt_charset:
++			if (is_vfat) {
++				kfree(opts->iocharset);
++				opts->iocharset = match_strdup(&args[0]);
++				if (!opts->iocharset)
++					return 0;
++				printk("MSDOS FS: IO charset %s\n",
++					opts->iocharset);
+ 			}
+-		}
+-		else if (is_vfat && !strcmp(this_char,"utf8")) {
+-			ret = simple_getbool(value, &val);
+-			if (ret) opts->utf8 = val;
+-		}
+-		else if (is_vfat && !strcmp(this_char,"uni_xlate")) {
+-			ret = simple_getbool(value, &val);
+-			if (ret) opts->unicode_xlate = val;
+-		}
+-		else if (is_vfat && !strcmp(this_char,"posix")) {
+-			printk(KERN_INFO "FAT: posix option is obsolete, "
+-			       "not supported now\n");
+-		}
+-		else if (is_vfat && !strcmp(this_char,"nonumtail")) {
+-			ret = simple_getbool(value, &val);
+-			if (ret) {
+-				opts->numtail = !val;
+-			}
+-		}
+-		else if (is_vfat && !strcmp(this_char, "shortname")) {
+-			if (!strcmp(value, "lower"))
++			break;
++		case Opt_shortname_lower:
++			if (is_vfat) {
+ 				opts->shortname = VFAT_SFN_DISPLAY_LOWER
+ 						| VFAT_SFN_CREATE_WIN95;
+-			else if (!strcmp(value, "win95"))
++			}
++			break;
++		case Opt_shortname_win95:
++			if (is_vfat) {
+ 				opts->shortname = VFAT_SFN_DISPLAY_WIN95
+ 						| VFAT_SFN_CREATE_WIN95;
+-			else if (!strcmp(value, "winnt"))
++			}
++			break;
++		case Opt_shortname_winnt:
++			if (is_vfat) {
+ 				opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ 						| VFAT_SFN_CREATE_WINNT;
+-			else if (!strcmp(value, "mixed"))
++			}
++			break;
++		case Opt_shortname_mixed:
++			if (is_vfat) {
+ 				opts->shortname = VFAT_SFN_DISPLAY_WINNT
+ 						| VFAT_SFN_CREATE_WIN95;
+-			else
+-				ret = 0;
+-		} else {
+-			printk(KERN_ERR "FAT: Unrecognized mount option %s\n",
+-			       this_char);
+-			ret = 0;
+-		}
++			}
++			break;
++		case Opt_utf8_off:	/* 0 or no or false */
++		case Opt_utf8_no:
++		case Opt_utf8_false:
++			if (is_vfat) {
++				opts->utf8 = 0;
++			}
++			break;
++		case Opt_utf8_on:	/* empty or 1 or yes or true */
++		case Opt_utf8_opt:
++		case Opt_utf8_yes:
++		case Opt_utf8_true:
++			if (is_vfat) {
++				opts->utf8 = 1;
++			}
++			break;
++		case Opt_uni_xl_off:	/* 0 or no or false */
++		case Opt_uni_xl_no:
++		case Opt_uni_xl_false:
++			if (is_vfat) {
++				opts->unicode_xlate = 0;
++			}
++			break;
++		case Opt_uni_xl_on:	/* empty or 1 or yes or true */
++		case Opt_uni_xl_yes:
++		case Opt_uni_xl_true:
++		case Opt_uni_xl_opt:
++			if (is_vfat) {
++				opts->unicode_xlate = 1;
++			}
++			break;
++		case Opt_nonumtail_off:		/* 0 or no or false */
++		case Opt_nonumtail_no:
++		case Opt_nonumtail_false:
++			if (is_vfat) {
++					opts->numtail = 1;	/* negated option */
++			}
++			break;
++		case Opt_nonumtail_on:		/* empty or 1 or yes or true */
++		case Opt_nonumtail_yes:
++		case Opt_nonumtail_true:
++		case Opt_nonumtail_opt:
++			if (is_vfat) {
++					opts->numtail = 0;	/* negated option */
++			}
++			break;
+ 
+-		if (ret == 0)
++		/* obsolete mount options */
++		case Opt_conv_b:
++		case Opt_conv_t:
++		case Opt_conv_a:
++			print_obsolete_option("conv");
++			break;
++		case Opt_blocksize:
++			print_obsolete_option("blocksize");
++			break;
++		case Opt_posix:
++			print_obsolete_option("posix");
++			break;
++		case Opt_fat:
++			print_obsolete_option("fat");
++			break;
++		case Opt_cvf_format:
++		case Opt_cvf_options:
++			print_obsolete_option("cvf");
+ 			break;
++		/* unknown option */
++		default:
++			printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" "
++					"or missing value\n", p);
++			return 0;
++		}
+ 	}
+-out:
++
+ 	if (opts->unicode_xlate)
+ 		opts->utf8 = 0;
+ 	
+-	return ret;
++	return 1;
+ }
+ 
+ static int fat_calc_dir_size(struct inode *inode)
+--- linux-2.6.0-test6/fs/fcntl.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/fcntl.c	2003-10-05 00:34:08.000000000 -0700
+@@ -229,8 +229,8 @@ static int setfl(int fd, struct file * f
+ 		   arg |= O_NONBLOCK;
+ 
+ 	if (arg & O_DIRECT) {
+-		if (!inode->i_mapping || !inode->i_mapping->a_ops ||
+-			!inode->i_mapping->a_ops->direct_IO)
++		if (!filp->f_mapping || !filp->f_mapping->a_ops ||
++			!filp->f_mapping->a_ops->direct_IO)
+ 				return -EINVAL;
+ 	}
+ 
+@@ -619,3 +619,6 @@ module_init(fasync_init)
+ 
+ EXPORT_SYMBOL(f_setown);
+ EXPORT_SYMBOL(f_delown);
++#ifdef CONFIG_NET
++EXPORT_SYMBOL(__kill_fasync);
++#endif
+--- linux-2.6.0-test6/fs/file_table.c	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/file_table.c	2003-10-05 00:34:03.000000000 -0700
+@@ -114,6 +114,7 @@ int open_private_file(struct file *filp,
+ 	filp->f_mode   = (flags+1) & O_ACCMODE;
+ 	atomic_set(&filp->f_count, 1);
+ 	filp->f_dentry = dentry;
++	filp->f_mapping = dentry->d_inode->i_mapping;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+@@ -285,3 +286,5 @@ void __init files_init(unsigned long mem
+ 		files_stat.max_files = NR_FILE;
+ } 
+ 
++/* Needed by unix.o */
++EXPORT_SYMBOL(files_stat);
+--- linux-2.6.0-test6/fs/freevxfs/vxfs_immed.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/fs/freevxfs/vxfs_immed.c	2003-10-05 00:33:24.000000000 -0700
+@@ -39,7 +39,7 @@
+ #include "vxfs_inode.h"
+ 
+ 
+-static int	vxfs_immed_readlink(struct dentry *, char *, int);
++static int	vxfs_immed_readlink(struct dentry *, char __user *, int);
+ static int	vxfs_immed_follow_link(struct dentry *, struct nameidata *);
+ 
+ static int	vxfs_immed_readpage(struct file *, struct page *);
+@@ -77,7 +77,7 @@ struct address_space_operations vxfs_imm
+  *   Number of bytes successfully copied to userspace.
+  */
+ static int
+-vxfs_immed_readlink(struct dentry *dp, char *bp, int buflen)
++vxfs_immed_readlink(struct dentry *dp, char __user *bp, int buflen)
+ {
+ 	struct vxfs_inode_info		*vip = VXFS_INO(dp->d_inode);
+ 
+--- linux-2.6.0-test6/fs/fs-writeback.c	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/fs-writeback.c	2003-10-05 00:34:09.000000000 -0700
+@@ -510,7 +510,7 @@ void write_inode_now(struct inode *inode
+  *    OSYNC_INODE:    the inode itself
+  */
+ 
+-int generic_osync_inode(struct inode *inode, int what)
++int generic_osync_inode(struct inode *inode, struct address_space *mapping, int what)
+ {
+ 	int err = 0;
+ 	int need_write_inode_now = 0;
+@@ -518,14 +518,14 @@ int generic_osync_inode(struct inode *in
+ 
+ 	current->flags |= PF_SYNCWRITE;
+ 	if (what & OSYNC_DATA)
+-		err = filemap_fdatawrite(inode->i_mapping);
++		err = filemap_fdatawrite(mapping);
+ 	if (what & (OSYNC_METADATA|OSYNC_DATA)) {
+-		err2 = sync_mapping_buffers(inode->i_mapping);
++		err2 = sync_mapping_buffers(mapping);
+ 		if (!err)
+ 			err = err2;
+ 	}
+ 	if (what & OSYNC_DATA) {
+-		err2 = filemap_fdatawait(inode->i_mapping);
++		err2 = filemap_fdatawait(mapping);
+ 		if (!err)
+ 			err = err2;
+ 	}
+--- linux-2.6.0-test6/fs/hfs/file.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/fs/hfs/file.c	2003-10-05 00:33:24.000000000 -0700
+@@ -25,10 +25,10 @@
+ 
+ /*================ Forward declarations ================*/
+ 
+-static hfs_rwret_t hfs_file_read(struct file *, char *, hfs_rwarg_t,
++static hfs_rwret_t hfs_file_read(struct file *, char __user *, hfs_rwarg_t,
+ 				 loff_t *);
+-static hfs_rwret_t hfs_file_write(struct file *, const char *, hfs_rwarg_t,
+-				  loff_t *);
++static hfs_rwret_t hfs_file_write(struct file *, const char __user *,
++				  hfs_rwarg_t, loff_t *);
+ static void hfs_file_truncate(struct inode *);
+ 
+ /*================ Global variables ================*/
+@@ -139,7 +139,7 @@ int hfs_get_block(struct inode *inode, s
+  * user-space at the address 'buf'.  Returns the number of bytes
+  * successfully transferred.  This function checks the arguments, does
+  * some setup and then calls hfs_do_read() to do the actual transfer.  */
+-static hfs_rwret_t hfs_file_read(struct file * filp, char * buf, 
++static hfs_rwret_t hfs_file_read(struct file *filp, char __user *buf, 
+ 				 hfs_rwarg_t count, loff_t *ppos)
+ {
+         struct inode *inode = filp->f_dentry->d_inode;
+@@ -181,7 +181,7 @@ static hfs_rwret_t hfs_file_read(struct 
+  * 'file->f_pos' from user-space at the address 'buf'.  The return
+  * value is the number of bytes actually transferred.
+  */
+-static hfs_rwret_t hfs_file_write(struct file * filp, const char * buf,
++static hfs_rwret_t hfs_file_write(struct file *filp, const char __user *buf,
+ 				  hfs_rwarg_t count, loff_t *ppos)
+ {
+         struct inode    *inode = filp->f_dentry->d_inode;
+@@ -242,7 +242,7 @@ static void hfs_file_truncate(struct ino
+  *
+  * Like copy_to_user() while translating CR->NL.
+  */
+-static inline void xlate_to_user(char *buf, const char *data, int count)
++static inline void xlate_to_user(char __user *buf, const char *data, int count)
+ {
+ 	char ch;
+ 
+@@ -257,7 +257,8 @@ static inline void xlate_to_user(char *b
+  *
+  * Like copy_from_user() while translating NL->CR;
+  */
+-static inline int xlate_from_user(char *data, const char *buf, int count)
++static inline
++int xlate_from_user(char *data, const char __user *buf, int count)
+ {
+ 	int i;
+ 
+@@ -290,8 +291,8 @@ static inline int xlate_from_user(char *
+  * This is based on Linus's minix_file_read().
+  * It has been changed to take into account that HFS files have no holes.
+  */
+-hfs_s32 hfs_do_read(struct inode *inode, struct hfs_fork * fork, hfs_u32 pos,
+-		    char * buf, hfs_u32 count)
++hfs_s32 hfs_do_read(struct inode *inode, struct hfs_fork *fork, hfs_u32 pos,
++		    char __user *buf, hfs_u32 count)
+ {
+ 	hfs_s32 size, chars, offset, block, blocks, read = 0;
+ 	int bhrequest, uptodate;
+@@ -436,8 +437,8 @@ hfs_s32 hfs_do_read(struct inode *inode,
+  * 
+  * This is just a minor edit of Linus's minix_file_write().
+  */
+-hfs_s32 hfs_do_write(struct inode *inode, struct hfs_fork * fork, hfs_u32 pos,
+-		     const char * buf, hfs_u32 count)
++hfs_s32 hfs_do_write(struct inode *inode, struct hfs_fork *fork, hfs_u32 pos,
++		     const char __user *buf, hfs_u32 count)
+ {
+ 	hfs_s32 written, c;
+ 	struct buffer_head * bh;
+--- linux-2.6.0-test6/fs/hfs/file_cap.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/fs/hfs/file_cap.c	2003-10-05 00:33:24.000000000 -0700
+@@ -29,9 +29,9 @@
+ /*================ Forward declarations ================*/
+ static loff_t      cap_info_llseek(struct file *, loff_t,
+                                    int);
+-static hfs_rwret_t cap_info_read(struct file *, char *,
++static hfs_rwret_t cap_info_read(struct file *, char __user *,
+ 				 hfs_rwarg_t, loff_t *);
+-static hfs_rwret_t cap_info_write(struct file *, const char *,
++static hfs_rwret_t cap_info_write(struct file *, const char __user *,
+ 				  hfs_rwarg_t, loff_t *);
+ /*================ Function-like macros ================*/
+ 
+@@ -121,7 +121,7 @@ static loff_t cap_info_llseek(struct fil
+  * 'file->f_pos' to user-space at the address 'buf'.  The return value
+  * is the number of bytes actually transferred.
+  */
+-static hfs_rwret_t cap_info_read(struct file *filp, char *buf,
++static hfs_rwret_t cap_info_read(struct file *filp, char __user *buf,
+ 				 hfs_rwarg_t count, loff_t *ppos)
+ {
+ 	struct inode *inode = filp->f_dentry->d_inode;
+@@ -189,7 +189,7 @@ static hfs_rwret_t cap_info_read(struct 
+  * '*ppos' from user-space at the address 'buf'.
+  * The return value is the number of bytes actually transferred.
+  */
+-static hfs_rwret_t cap_info_write(struct file *filp, const char *buf, 
++static hfs_rwret_t cap_info_write(struct file *filp, const char __user *buf, 
+ 				  hfs_rwarg_t count, loff_t *ppos)
+ {
+         struct inode *inode = filp->f_dentry->d_inode;
+--- linux-2.6.0-test6/fs/hfs/file_hdr.c	2003-06-14 12:18:25.000000000 -0700
++++ 25/fs/hfs/file_hdr.c	2003-10-05 00:33:24.000000000 -0700
+@@ -41,8 +41,9 @@
+ 
+ /*================ Forward declarations ================*/
+ static loff_t      hdr_llseek(struct file *, loff_t, int);
+-static hfs_rwret_t hdr_read(struct file *, char *, hfs_rwarg_t, loff_t *);
+-static hfs_rwret_t hdr_write(struct file *, const char *,
++static hfs_rwret_t hdr_read(struct file *, char __user *,
++			    hfs_rwarg_t, loff_t *);
++static hfs_rwret_t hdr_write(struct file *, const char __user *,
+ 			     hfs_rwarg_t, loff_t *);
+ /*================ Global variables ================*/
+ 
+@@ -382,7 +383,7 @@ loff_t hdr_llseek(struct file *file, lof
+  * successfully transferred.
+  */
+ /* XXX: what about the entry count changing on us? */
+-static hfs_rwret_t hdr_read(struct file * filp, char * buf, 
++static hfs_rwret_t hdr_read(struct file *filp, char __user *buf, 
+ 			    hfs_rwarg_t count, loff_t *ppos)
+ {
+ 	struct inode *inode = filp->f_dentry->d_inode;
+@@ -633,7 +634,7 @@ done:
+  * '*ppos' from user-space at the address 'buf'.
+  * The return value is the number of bytes actually transferred.
+  */
+-static hfs_rwret_t hdr_write(struct file *filp, const char *buf,
++static hfs_rwret_t hdr_write(struct file *filp, const char __user *buf,
+ 			     hfs_rwarg_t count, loff_t *ppos)
+ {
+ 	struct inode *inode = filp->f_dentry->d_inode;
+--- linux-2.6.0-test6/fs/hfs/super.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/fs/hfs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -31,6 +31,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/vfs.h>
+ 
+@@ -211,6 +212,60 @@ static int hfs_statfs(struct super_block
+ 	return 0;
+ }
+ 
++enum {
++	Opt_version, Opt_uid, Opt_gid, Opt_umask, Opt_part,
++	Opt_type, Opt_creator, Opt_quiet, Opt_afpd,
++	Opt_names_netatalk, Opt_names_trivial, Opt_names_alpha, Opt_names_latin,
++	Opt_names_7bit, Opt_names_8bit, Opt_names_cap,
++	Opt_fork_netatalk, Opt_fork_single, Opt_fork_double, Opt_fork_cap,
++	Opt_case_lower, Opt_case_asis,
++	Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
++};
++
++static match_table_t tokens = {
++	{Opt_version, "version=%u"},
++	{Opt_uid, "uid=%u"},
++	{Opt_gid, "gid=%u"},
++	{Opt_umask, "umask=%o"},
++	{Opt_part, "part=%u"},
++	{Opt_type, "type=%s"},
++	{Opt_creator, "creator=%s"},
++	{Opt_quiet, "quiet"},
++	{Opt_afpd, "afpd"},
++	{Opt_names_netatalk, "names=netatalk"},
++	{Opt_names_trivial, "names=trivial"},
++	{Opt_names_alpha, "names=alpha"},
++	{Opt_names_latin, "names=latin"},
++	{Opt_names_7bit, "names=7bit"},
++	{Opt_names_8bit, "names=8bit"},
++	{Opt_names_cap, "names=cap"},
++	{Opt_names_netatalk, "names=n"},
++	{Opt_names_trivial, "names=t"},
++	{Opt_names_alpha, "names=a"},
++	{Opt_names_latin, "names=l"},
++	{Opt_names_7bit, "names=7"},
++	{Opt_names_8bit, "names=8"},
++	{Opt_names_cap, "names=c"},
++	{Opt_fork_netatalk, "fork=netatalk"},
++	{Opt_fork_single, "fork=single"},
++	{Opt_fork_double, "fork=double"},
++	{Opt_fork_cap, "fork=cap"},
++	{Opt_fork_netatalk, "fork=n"},
++	{Opt_fork_single, "fork=s"},
++	{Opt_fork_double, "fork=d"},
++	{Opt_fork_cap, "fork=c"},
++	{Opt_case_lower, "case=lower"},
++	{Opt_case_asis, "case=asis"},
++	{Opt_case_lower, "case=l"},
++	{Opt_case_asis, "case=a"},
++	{Opt_conv_binary, "conv=binary"},
++	{Opt_conv_text, "conv=text"},
++	{Opt_conv_auto, "conv=auto"},
++	{Opt_conv_binary, "conv=b"},
++	{Opt_conv_text, "conv=t"},
++	{Opt_conv_auto, "conv=a"},
++};
++
+ /*
+  * parse_options()
+  * 
+@@ -219,8 +274,10 @@ static int hfs_statfs(struct super_block
+  */
+ static int parse_options(char *options, struct hfs_sb_info *hsb, int *part)
+ {
+-	char *this_char, *value;
++	char *p;
+ 	char names, fork;
++	substring_t args[MAX_OPT_ARGS];
++	int option;
+ 
+ 	/* initialize the sb with defaults */
+ 	memset(hsb, 0, sizeof(*hsb));
+@@ -243,117 +300,109 @@ static int parse_options(char *options, 
+ 	if (!options) {
+ 		goto done;
+ 	}
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++	while ((p = strsep(&options,",")) != NULL) {
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char,'=')) != NULL) {
+-			*value++ = 0;
+-		}
+-	/* Numeric-valued options */
+-		if (!strcmp(this_char, "version")) {
+-			if (!value || !*value) {
+-				return 0;
+-			}
+-			hsb->s_version = simple_strtoul(value,&value,0);
+-			if (*value) {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"uid")) {
+-			if (!value || !*value) {
+-				return 0;
+-			}
+-			hsb->s_uid = simple_strtoul(value,&value,0);
+-			if (*value) {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"gid")) {
+-			if (!value || !*value) {
+-				return 0;
+-			}
+-			hsb->s_gid = simple_strtoul(value,&value,0);
+-			if (*value) {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"umask")) {
+-			if (!value || !*value) {
+-				return 0;
+-			}
+-			hsb->s_umask = simple_strtoul(value,&value,8);
+-			if (*value) {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"part")) {
+-			if (!value || !*value) {
+-				return 0;
+-			}
+-			*part = simple_strtoul(value,&value,0);
+-			if (*value) {
+-				return 0;
+-			}
+-	/* String-valued options */
+-		} else if (!strcmp(this_char,"type") && value) {
+-			if (strlen(value) != 4) {
+-				return 0;
+-			}
+-			hsb->s_type = hfs_get_nl(value);
+-		} else if (!strcmp(this_char,"creator") && value) {
+-			if (strlen(value) != 4) {
+-				return 0;
+-			}
+-			hsb->s_creator = hfs_get_nl(value);
+-	/* Boolean-valued options */
+-		} else if (!strcmp(this_char,"quiet")) {
+-			if (value) {
+-				return 0;
+-			}
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		/* Numeric-valued options */
++		case Opt_version:
++			if (match_int(&args[0], &option))
++				return 0;
++			hsb->s_version = option;
++			break;
++		case Opt_uid:
++			if (match_int(&args[0], &option))
++				return 0;
++			hsb->s_uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(&args[0], &option))
++				return 0;
++			hsb->s_gid = option;
++			break;
++		case Opt_umask:
++			if (match_octal(&args[0], &option))
++				return 0;
++			hsb->s_umask = option;
++			break;
++		case Opt_part:
++			if (match_int(&args[0], &option))
++				return 0;
++			*part = option;
++			break;
++		/* String-valued options */
++		case Opt_type:
++			if (strlen(args[0].from) != 4) {
++				return 0;
++			}
++			hsb->s_type = hfs_get_nl(args[0].from);
++			break;
++		case Opt_creator:
++			if (strlen(args[0].from) != 4) {
++				return 0;
++			}
++			hsb->s_creator = hfs_get_nl(args[0].from);
++			break;
++		/* Boolean-valued options */
++		case Opt_quiet:
+ 			hsb->s_quiet = 1;
+-		} else if (!strcmp(this_char,"afpd")) {
+-			if (value) {
+-				return 0;
+-			}
++			break;
++		case Opt_afpd:
+ 			hsb->s_afpd = 1;
+-	/* Multiple choice options */
+-		} else if (!strcmp(this_char,"names") && value) {
+-			if ((*value && !value[1] && strchr("ntal78c",*value)) ||
+-			    !strcmp(value,"netatalk") ||
+-			    !strcmp(value,"trivial") ||
+-			    !strcmp(value,"alpha") ||
+-			    !strcmp(value,"latin") ||
+-			    !strcmp(value,"7bit") ||
+-			    !strcmp(value,"8bit") ||
+-			    !strcmp(value,"cap")) {
+-				names = *value;
+-			} else {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"fork") && value) {
+-			if ((*value && !value[1] && strchr("nsdc",*value)) ||
+-			    !strcmp(value,"netatalk") ||
+-			    !strcmp(value,"single") ||
+-			    !strcmp(value,"double") ||
+-			    !strcmp(value,"cap")) {
+-				fork = *value;
+-			} else {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"case") && value) {
+-			if ((*value && !value[1] && strchr("la",*value)) ||
+-			    !strcmp(value,"lower") ||
+-			    !strcmp(value,"asis")) {
+-				hsb->s_lowercase = (*value == 'l');
+-			} else {
+-				return 0;
+-			}
+-		} else if (!strcmp(this_char,"conv") && value) {
+-			if ((*value && !value[1] && strchr("bta",*value)) ||
+-			    !strcmp(value,"binary") ||
+-			    !strcmp(value,"text") ||
+-			    !strcmp(value,"auto")) {
+-				hsb->s_conv = *value;
+-			} else {
+-				return 0;
+-			}
+-		} else {
++			break;
++		/* Multiple choice options */
++		case Opt_names_netatalk:
++			names = 'n';
++			break;
++		case Opt_names_trivial:
++			names = 't';
++			break;
++		case Opt_names_alpha:
++			names = 'a';
++			break;
++		case Opt_names_latin:
++			names = 'l';
++			break;
++		case Opt_names_7bit:
++			names = '7';
++			break;
++		case Opt_names_8bit:
++			names = '8';
++			break;
++		case Opt_names_cap:
++			names = 'c';
++			break;
++		case Opt_fork_netatalk:
++			fork = 'n';
++			break;
++		case Opt_fork_single:
++			fork = 's';
++			break;
++		case Opt_fork_double:
++			fork = 'd';
++			break;
++		case Opt_fork_cap:
++			fork = 'c';
++			break;
++		case Opt_case_lower:
++			hsb->s_lowercase = 1;
++			break;
++		case Opt_case_asis:
++			hsb->s_lowercase = 0;
++			break;
++		case Opt_conv_binary:
++			hsb->s_conv = 'b';
++			break;
++		case Opt_conv_text:
++			hsb->s_conv = 't';
++			break;
++		case Opt_conv_auto:
++			hsb->s_conv = 'a';
++			break;
++		default:
+ 			return 0;
+ 		}
+ 	}
+--- linux-2.6.0-test6/fs/hpfs/file.c	2003-06-14 12:18:35.000000000 -0700
++++ 25/fs/hpfs/file.c	2003-10-05 00:33:24.000000000 -0700
+@@ -124,7 +124,8 @@ struct address_space_operations hpfs_aop
+ 	.bmap = _hpfs_bmap
+ };
+ 
+-ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
++ssize_t hpfs_file_write(struct file *file, const char __user *buf,
++			size_t count, loff_t *ppos)
+ {
+ 	ssize_t retval;
+ 
+--- linux-2.6.0-test6/fs/hpfs/hpfs_fn.h	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/hpfs/hpfs_fn.h	2003-10-05 00:33:24.000000000 -0700
+@@ -249,7 +249,7 @@ int hpfs_file_fsync(struct file *, struc
+ secno hpfs_bmap(struct inode *, unsigned);
+ void hpfs_truncate(struct inode *);
+ int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create);
+-ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
++ssize_t hpfs_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
+ 
+ /* inode.c */
+ 
+--- linux-2.6.0-test6/fs/hpfs/super.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/fs/hpfs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -10,6 +10,7 @@
+ #include <linux/string.h>
+ #include "hpfs_fn.h"
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/init.h>
+ #include <linux/vfs.h>
+ 
+@@ -219,15 +220,52 @@ static struct super_operations hpfs_sops
+ 
+ /*
+  * A tiny parser for option strings, stolen from dosfs.
+- *
+  * Stolen again from read-only hpfs.
++ * And updated for table-driven option parsing.
+  */
+ 
++enum {
++	Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis,
++	Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
++	Opt_check_none, Opt_check_normal, Opt_check_strict,
++	Opt_err_cont, Opt_err_ro, Opt_err_panic,
++	Opt_eas_no, Opt_eas_ro, Opt_eas_rw,
++	Opt_chkdsk_no, Opt_chkdsk_errors, Opt_chkdsk_always,
++	Opt_timeshift, Opt_err,
++};
++
++static match_table_t tokens = {
++	{Opt_help, "help"},
++	{Opt_uid, "uid=%u"},
++	{Opt_gid, "gid=%u"},
++	{Opt_umask, "umask=%o"},
++	{Opt_case_lower, "case=lower"},
++	{Opt_case_asis, "case=asis"},
++	{Opt_conv_binary, "conv=binary"},
++	{Opt_conv_text, "conv=text"},
++	{Opt_conv_auto, "conv=auto"},
++	{Opt_check_none, "check=none"},
++	{Opt_check_normal, "check=normal"},
++	{Opt_check_strict, "check=strict"},
++	{Opt_err_cont, "errors=continue"},
++	{Opt_err_ro, "errors=remount-ro"},
++	{Opt_err_panic, "errors=panic"},
++	{Opt_eas_no, "eas=no"},
++	{Opt_eas_ro, "eas=ro"},
++	{Opt_eas_rw, "eas=rw"},
++	{Opt_chkdsk_no, "chkdsk=no"},
++	{Opt_chkdsk_errors, "chkdsk=errors"},
++	{Opt_chkdsk_always, "chkdsk=always"},
++	{Opt_timeshift, "timeshift=%d"},
++	{Opt_err, NULL},
++};
++
+ int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
+ 	       int *lowercase, int *conv, int *eas, int *chk, int *errs,
+ 	       int *chkdsk, int *timeshift)
+ {
+-	char *p, *rhs;
++	char *p;
++	int option;
+ 
+ 	if (!opts)
+ 		return 1;
+@@ -235,34 +273,85 @@ int parse_opts(char *opts, uid_t *uid, g
+ 	/*printk("Parsing opts: '%s'\n",opts);*/
+ 
+ 	while ((p = strsep(&opts, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
+ 		if (!*p)
+ 			continue;
+-		if ((rhs = strchr(p, '=')) != 0)
+-			*rhs++ = '\0';
+-		if (!strcmp(p, "help")) return 2;
+-		if (!strcmp(p, "uid")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			*uid = simple_strtoul(rhs, &rhs, 0);
+-			if (*rhs)
+-				return 0;
+-		}
+-		else if (!strcmp(p, "gid")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			*gid = simple_strtoul(rhs, &rhs, 0);
+-			if (*rhs)
+-				return 0;
+-		}
+-		else if (!strcmp(p, "umask")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			*umask = simple_strtoul(rhs, &rhs, 8);
+-			if (*rhs)
+-				return 0;
+-		}
+-		else if (!strcmp(p, "timeshift")) {
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_help:
++			return 2;
++		case Opt_uid:
++			if (match_int(args, &option))
++				return 0;
++			*uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(args, &option))
++				return 0;
++			*gid = option;
++			break;
++		case Opt_umask:
++			if (match_octal(args, &option))
++				return 0;
++			*umask = option;
++			break;
++		case Opt_case_lower:
++			*lowercase = 1;
++			break;
++		case Opt_case_asis:
++			*lowercase = 0;
++			break;
++		case Opt_conv_binary:
++			*conv = CONV_BINARY;
++			break;
++		case Opt_conv_text:
++			*conv = CONV_TEXT;
++			break;
++		case Opt_conv_auto:
++			*conv = CONV_AUTO;
++			break;
++		case Opt_check_none:
++			*chk = 0;
++			break;
++		case Opt_check_normal:
++			*chk = 1;
++			break;
++		case Opt_check_strict:
++			*chk = 2;
++			break;
++		case Opt_err_cont:
++			*errs = 0;
++			break;
++		case Opt_err_ro:
++			*errs = 1;
++			break;
++		case Opt_err_panic:
++			*errs = 2;
++			break;
++		case Opt_eas_no:
++			*eas = 0;
++			break;
++		case Opt_eas_ro:
++			*eas = 1;
++			break;
++		case Opt_eas_rw:
++			*eas = 2;
++			break;
++		case Opt_chkdsk_no:
++			*chkdsk = 0;
++			break;
++		case Opt_chkdsk_errors:
++			*chkdsk = 1;
++			break;
++		case Opt_chkdsk_always:
++			*chkdsk = 2;
++			break;
++		case Opt_timeshift:
++		{
+ 			int m = 1;
++			char *rhs = args[0].from;
+ 			if (!rhs || !*rhs)
+ 				return 0;
+ 			if (*rhs == '-') m = -1;
+@@ -270,79 +359,11 @@ int parse_opts(char *opts, uid_t *uid, g
+ 			*timeshift = simple_strtoul(rhs, &rhs, 0) * m;
+ 			if (*rhs)
+ 				return 0;
++			break;
+ 		}
+-		else if (!strcmp(p, "case")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "lower"))
+-				*lowercase = 1;
+-			else if (!strcmp(rhs, "asis"))
+-				*lowercase = 0;
+-			else
+-				return 0;
+-		}
+-		else if (!strcmp(p, "conv")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "binary"))
+-				*conv = CONV_BINARY;
+-			else if (!strcmp(rhs, "text"))
+-				*conv = CONV_TEXT;
+-			else if (!strcmp(rhs, "auto"))
+-				*conv = CONV_AUTO;
+-			else
+-				return 0;
+-		}
+-		else if (!strcmp(p, "check")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "none"))
+-				*chk = 0;
+-			else if (!strcmp(rhs, "normal"))
+-				*chk = 1;
+-			else if (!strcmp(rhs, "strict"))
+-				*chk = 2;
+-			else
+-				return 0;
+-		}
+-		else if (!strcmp(p, "errors")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "continue"))
+-				*errs = 0;
+-			else if (!strcmp(rhs, "remount-ro"))
+-				*errs = 1;
+-			else if (!strcmp(rhs, "panic"))
+-				*errs = 2;
+-			else
+-				return 0;
+-		}
+-		else if (!strcmp(p, "eas")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "no"))
+-				*eas = 0;
+-			else if (!strcmp(rhs, "ro"))
+-				*eas = 1;
+-			else if (!strcmp(rhs, "rw"))
+-				*eas = 2;
+-			else
+-				return 0;
+-		}
+-		else if (!strcmp(p, "chkdsk")) {
+-			if (!rhs || !*rhs)
+-				return 0;
+-			if (!strcmp(rhs, "no"))
+-				*chkdsk = 0;
+-			else if (!strcmp(rhs, "errors"))
+-				*chkdsk = 1;
+-			else if (!strcmp(rhs, "always"))
+-				*chkdsk = 2;
+-			else
+-				return 0;
+-		}
+-		else
++		default:
+ 			return 0;
++		}
+ 	}
+ 	return 1;
+ }
+--- linux-2.6.0-test6/fs/hugetlbfs/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/hugetlbfs/inode.c	2003-10-05 00:37:03.000000000 -0700
+@@ -165,7 +165,7 @@ void truncate_hugepages(struct address_s
+ 	pagevec_init(&pvec, 0);
+ 	next = start;
+ 	while (1) {
+-		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++		if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ 			if (next == start)
+ 				break;
+ 			next = start;
+@@ -176,9 +176,6 @@ void truncate_hugepages(struct address_s
+ 			struct page *page = pvec.pages[i];
+ 
+ 			lock_page(page);
+-			if (page->index > next)
+-				next = page->index;
+-			++next;
+ 			truncate_huge_page(page);
+ 			unlock_page(page);
+ 			hugetlb_put_quota(mapping);
+@@ -648,11 +645,6 @@ hugetlbfs_fill_super(struct super_block 
+ 	struct hugetlbfs_config config;
+ 	struct hugetlbfs_sb_info *sbinfo;
+ 
+-	sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
+-	if (!sbinfo)
+-		return -ENOMEM;
+-	sb->s_fs_info = sbinfo;
+-
+ 	config.nr_blocks = -1; /* No limit on size by default */
+ 	config.nr_inodes = -1; /* No limit on number of inodes by default */
+ 	config.uid = current->fsuid;
+@@ -663,6 +655,10 @@ hugetlbfs_fill_super(struct super_block 
+ 	if (ret)
+ 		return ret;
+ 
++	sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
++	if (!sbinfo)
++		return -ENOMEM;
++	sb->s_fs_info = sbinfo;
+ 	spin_lock_init(&sbinfo->stat_lock);
+ 	sbinfo->max_blocks = config.nr_blocks;
+ 	sbinfo->free_blocks = config.nr_blocks;
+@@ -675,15 +671,18 @@ hugetlbfs_fill_super(struct super_block 
+ 	inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
+ 					S_IFDIR | config.mode, 0);
+ 	if (!inode)
+-		return -ENOMEM;
++		goto out_free;
+ 
+ 	root = d_alloc_root(inode);
+ 	if (!root) {
+ 		iput(inode);
+-		return -ENOMEM;
++		goto out_free;
+ 	}
+ 	sb->s_root = root;
+ 	return 0;
++out_free:
++	kfree(sbinfo);
++	return -ENOMEM;
+ }
+ 
+ int hugetlb_get_quota(struct address_space *mapping)
+@@ -772,6 +771,7 @@ struct file *hugetlb_zero_setup(size_t s
+ 	inode->i_nlink = 0;
+ 	file->f_vfsmnt = mntget(hugetlbfs_vfsmount);
+ 	file->f_dentry = dentry;
++	file->f_mapping = inode->i_mapping;
+ 	file->f_op = &hugetlbfs_file_operations;
+ 	file->f_mode = FMODE_WRITE | FMODE_READ;
+ 	return file;
+--- linux-2.6.0-test6/fs/inode.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/inode.c	2003-10-05 00:36:52.000000000 -0700
+@@ -183,6 +183,7 @@ void inode_init_once(struct inode *inode
+ 	INIT_LIST_HEAD(&inode->i_dentry);
+ 	INIT_LIST_HEAD(&inode->i_devices);
+ 	sema_init(&inode->i_sem, 1);
++	init_rwsem(&inode->i_alloc_sem);
+ 	INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
+ 	spin_lock_init(&inode->i_data.page_lock);
+ 	init_MUTEX(&inode->i_data.i_shared_sem);
+@@ -195,6 +196,8 @@ void inode_init_once(struct inode *inode
+ 	i_size_ordered_init(inode);
+ }
+ 
++EXPORT_SYMBOL(inode_init_once);
++
+ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+ {
+ 	struct inode * inode = (struct inode *) foo;
+@@ -229,7 +232,6 @@ void __iget(struct inode * inode)
+  * that the inode is no longer useful. We just
+  * terminate it with extreme prejudice.
+  */
+- 
+ void clear_inode(struct inode *inode)
+ {
+ 	invalidate_inode_buffers(inode);
+@@ -251,7 +253,12 @@ void clear_inode(struct inode *inode)
+ 	inode->i_state = I_CLEAR;
+ }
+ 
++EXPORT_SYMBOL(clear_inode);
++
+ /*
++ * dispose_list - dispose of the contents of a local list
++ * @head: the head of the list to free
++ *
+  * Dispose-list gets a local list with local inodes in it, so it doesn't
+  * need to worry about list corruption and SMP locks.
+  */
+@@ -327,7 +334,6 @@ static int invalidate_list(struct list_h
+  *	fails because there are busy inodes then a non zero value is returned.
+  *	If the discard is successful all the inodes have been discarded.
+  */
+- 
+ int invalidate_inodes(struct super_block * sb)
+ {
+ 	int busy;
+@@ -346,6 +352,8 @@ int invalidate_inodes(struct super_block
+ 
+ 	return busy;
+ }
++
++EXPORT_SYMBOL(invalidate_inodes);
+  
+ int __invalidate_device(struct block_device *bdev, int do_sync)
+ {
+@@ -372,6 +380,8 @@ int __invalidate_device(struct block_dev
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(__invalidate_device);
++
+ static int can_unuse(struct inode *inode)
+ {
+ 	if (inode->i_state)
+@@ -532,7 +542,6 @@ repeat:
+  *
+  *	Allocates a new inode for given superblock.
+  */
+- 
+ struct inode *new_inode(struct super_block *sb)
+ {
+ 	static unsigned long last_ino;
+@@ -552,6 +561,8 @@ struct inode *new_inode(struct super_blo
+ 	return inode;
+ }
+ 
++EXPORT_SYMBOL(new_inode);
++
+ void unlock_new_inode(struct inode *inode)
+ {
+ 	/*
+@@ -565,6 +576,7 @@ void unlock_new_inode(struct inode *inod
+ 	inode->i_state &= ~(I_LOCK|I_NEW);
+ 	wake_up_inode(inode);
+ }
++
+ EXPORT_SYMBOL(unlock_new_inode);
+ 
+ /*
+@@ -685,7 +697,6 @@ static inline unsigned long hash(struct 
+  *	With a large number of inodes live on the file system this function
+  *	currently becomes quite slow.
+  */
+- 
+ ino_t iunique(struct super_block *sb, ino_t max_reserved)
+ {
+ 	static ino_t counter;
+@@ -709,6 +720,8 @@ retry:
+ 	
+ }
+ 
++EXPORT_SYMBOL(iunique);
++
+ struct inode *igrab(struct inode *inode)
+ {
+ 	spin_lock(&inode_lock);
+@@ -725,14 +738,16 @@ struct inode *igrab(struct inode *inode)
+ 	return inode;
+ }
+ 
++EXPORT_SYMBOL(igrab);
++
+ /**
+  * ifind - internal function, you want ilookup5() or iget5().
+  * @sb:		super block of file system to search
+- * @hashval:	hash value (usually inode number) to search for
++ * @head:       the head of the list to search
+  * @test:	callback used for comparisons between inodes
+  * @data:	opaque data pointer to pass to @test
+  *
+- * ifind() searches for the inode specified by @hashval and @data in the inode
++ * ifind() searches for the inode specified by @data in the inode
+  * cache. This is a generalized version of ifind_fast() for file systems where
+  * the inode number is not sufficient for unique identification of an inode.
+  *
+@@ -764,6 +779,7 @@ static inline struct inode *ifind(struct
+ /**
+  * ifind_fast - internal function, you want ilookup() or iget().
+  * @sb:		super block of file system to search
++ * @head:       head of the list to search
+  * @ino:	inode number to search for
+  *
+  * ifind_fast() searches for the inode @ino in the inode cache. This is for
+@@ -818,6 +834,7 @@ struct inode *ilookup5(struct super_bloc
+ 
+ 	return ifind(sb, head, test, data);
+ }
++
+ EXPORT_SYMBOL(ilookup5);
+ 
+ /**
+@@ -840,6 +857,7 @@ struct inode *ilookup(struct super_block
+ 
+ 	return ifind_fast(sb, head, ino);
+ }
++
+ EXPORT_SYMBOL(ilookup);
+ 
+ /**
+@@ -880,6 +898,7 @@ struct inode *iget5_locked(struct super_
+ 	 */
+ 	return get_new_inode(sb, head, test, set, data);
+ }
++
+ EXPORT_SYMBOL(iget5_locked);
+ 
+ /**
+@@ -913,6 +932,7 @@ struct inode *iget_locked(struct super_b
+ 	 */
+ 	return get_new_inode_fast(sb, head, ino);
+ }
++
+ EXPORT_SYMBOL(iget_locked);
+ 
+ /**
+@@ -923,7 +943,6 @@ EXPORT_SYMBOL(iget_locked);
+  *
+  *	Add an inode to the inode hash for this superblock.
+  */
+- 
+ void __insert_inode_hash(struct inode *inode, unsigned long hashval)
+ {
+ 	struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
+@@ -932,13 +951,14 @@ void __insert_inode_hash(struct inode *i
+ 	spin_unlock(&inode_lock);
+ }
+ 
++EXPORT_SYMBOL(__insert_inode_hash);
++
+ /**
+  *	remove_inode_hash - remove an inode from the hash
+  *	@inode: inode to unhash
+  *
+  *	Remove an inode from the superblock.
+  */
+- 
+ void remove_inode_hash(struct inode *inode)
+ {
+ 	spin_lock(&inode_lock);
+@@ -946,6 +966,8 @@ void remove_inode_hash(struct inode *ino
+ 	spin_unlock(&inode_lock);
+ }
+ 
++EXPORT_SYMBOL(remove_inode_hash);
++
+ /*
+  * Tell the filesystem that this inode is no longer of any interest and should
+  * be completely destroyed.
+@@ -988,6 +1010,7 @@ void generic_delete_inode(struct inode *
+ 		BUG();
+ 	destroy_inode(inode);
+ }
++
+ EXPORT_SYMBOL(generic_delete_inode);
+ 
+ static void generic_forget_inode(struct inode *inode)
+@@ -1059,7 +1082,6 @@ static inline void iput_final(struct ino
+  *	Puts an inode, dropping its usage count. If the inode use count hits
+  *	zero the inode is also then freed and may be destroyed.
+  */
+- 
+ void iput(struct inode *inode)
+ {
+ 	if (inode) {
+@@ -1076,6 +1098,8 @@ void iput(struct inode *inode)
+ 	}
+ }
+ 
++EXPORT_SYMBOL(iput);
++
+ /**
+  *	bmap	- find a block number in a file
+  *	@inode: inode of file
+@@ -1087,7 +1111,6 @@ void iput(struct inode *inode)
+  *	disk block relative to the disk start that holds that block of the 
+  *	file.
+  */
+- 
+ sector_t bmap(struct inode * inode, sector_t block)
+ {
+ 	sector_t res = 0;
+@@ -1096,6 +1119,8 @@ sector_t bmap(struct inode * inode, sect
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(bmap);
++
+ /*
+  * Return true if the filesystem which backs this inode considers the two
+  * passed timespecs to be sufficiently different to warrant flushing the
+@@ -1117,7 +1142,6 @@ static int inode_times_differ(struct ino
+  *	This function automatically handles read only file systems and media,
+  *	as well as the "noatime" flag and inode specific "noatime" markers.
+  */
+- 
+ void update_atime(struct inode *inode)
+ {
+ 	struct timespec now;
+@@ -1139,6 +1163,8 @@ void update_atime(struct inode *inode)
+ 	}
+ }
+ 
++EXPORT_SYMBOL(update_atime);
++
+ /**
+  *	inode_update_time	-	update mtime and ctime time
+  *	@inode: inode accessed
+@@ -1170,6 +1196,7 @@ void inode_update_time(struct inode *ino
+ 	if (sync_it)
+ 		mark_inode_dirty_sync(inode);
+ }
++
+ EXPORT_SYMBOL(inode_update_time);
+ 
+ int inode_needs_sync(struct inode *inode)
+@@ -1180,6 +1207,7 @@ int inode_needs_sync(struct inode *inode
+ 		return 1;
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(inode_needs_sync);
+ 
+ /*
+@@ -1375,3 +1403,5 @@ void init_special_inode(struct inode *in
+ 		printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n",
+ 		       mode);
+ }
++
++EXPORT_SYMBOL(init_special_inode);
+--- linux-2.6.0-test6/fs/intermezzo/file.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/intermezzo/file.c	2003-10-05 00:34:01.000000000 -0700
+@@ -337,7 +337,7 @@ static void presto_apply_write_policy(st
+                                 unlock_kernel();
+                                 return; 
+                         }
+-                        error = presto_journal_close(&rec, fset, file,
++                        error = presto_journal_close(&rec, fset, fdata,
+                                                      file->f_dentry,
+                                                      &fdata->fd_version,
+                                                      &new_file_ver);
+--- linux-2.6.0-test6/fs/intermezzo/intermezzo_fs.h	2003-07-10 18:50:31.000000000 -0700
++++ 25/fs/intermezzo/intermezzo_fs.h	2003-10-05 00:34:01.000000000 -0700
+@@ -603,7 +603,7 @@ int presto_journal_rename(struct rec_inf
+ int presto_journal_open(struct rec_info *, struct presto_file_set *,
+                         struct dentry *, struct presto_version *old_ver);
+ int presto_journal_close(struct rec_info *rec, struct presto_file_set *,
+-                         struct file *, struct dentry *,
++                         struct presto_file_data *, struct dentry *,
+                          struct presto_version *old_file_ver,
+                          struct presto_version *new_file_ver);
+ int presto_write_lml_close(struct rec_info *rec,
+--- linux-2.6.0-test6/fs/intermezzo/journal.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/intermezzo/journal.c	2003-10-05 00:34:01.000000000 -0700
+@@ -2104,12 +2104,11 @@ int presto_journal_unlink(struct rec_inf
+ 
+ int
+ presto_journal_close(struct rec_info *rec, struct presto_file_set *fset,
+-                     struct file *file, struct dentry *dentry,
++                     struct presto_file_data *fd, struct dentry *dentry,
+                      struct presto_version *old_file_ver,
+                      struct presto_version *new_file_ver)
+ {
+         int opcode = KML_OPCODE_CLOSE;
+-        struct presto_file_data *fd;
+         char *buffer, *path, *logrecord, record[316];
+         struct dentry *root;
+         int error, size, i;
+@@ -2138,7 +2137,6 @@ presto_journal_close(struct rec_info *re
+ 
+         root = fset->fset_dentry;
+ 
+-        fd = (struct presto_file_data *)file->private_data;
+         if (fd) {
+                 open_ngroups = fd->fd_ngroups;
+                 for (i = 0; i < fd->fd_ngroups; i++)
+--- linux-2.6.0-test6/fs/intermezzo/presto.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/intermezzo/presto.c	2003-10-05 00:34:01.000000000 -0700
+@@ -260,11 +260,8 @@ int lento_cancel_lml(char *path, 
+ 
+ 
+         if (info->flags & LENTO_FL_WRITE_KML) {
+-                struct file file;
+-                file.private_data = NULL;
+-                file.f_dentry = dentry; 
+                 presto_getversion(&new_ver, dentry->d_inode);
+-                error = presto_journal_close(&rec, fset, &file, dentry, 
++                error = presto_journal_close(&rec, fset, NULL, dentry, 
+                                              &new_ver);
+                 if ( error ) {
+                         EXIT; 
+--- linux-2.6.0-test6/fs/intermezzo/vfs.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/intermezzo/vfs.c	2003-10-05 00:34:03.000000000 -0700
+@@ -322,7 +322,7 @@ int presto_do_close(struct presto_file_s
+         }
+ 
+         if (fdata->fd_info.flags & LENTO_FL_KML) 
+-                rc = presto_journal_close(&rec, fset, file, file->f_dentry,
++                rc = presto_journal_close(&rec, fset, fdata, file->f_dentry,
+                                           &fdata->fd_version, 
+                                           &fdata->fd_info.remote_version);
+         if (rc) { 
+@@ -432,14 +432,11 @@ int presto_do_setattr(struct presto_file
+ 
+         if ( presto_do_kml(info, dentry) ) {
+                 if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
+-                        struct file file;
+                         /* Journal a close whenever we see a potential truncate
+                         * At the receiving end, lento should explicitly remove
+                         * ATTR_SIZE from the list of valid attributes */
+                         presto_getversion(&new_ver, inode);
+-                        file.private_data = NULL;
+-                        file.f_dentry = dentry;
+-                        error = presto_journal_close(&rec, fset, &file, dentry,
++                        error = presto_journal_close(&rec, fset, NULL, dentry,
+                                                      &old_ver, &new_ver);
+                 }
+ 
+@@ -2087,7 +2084,9 @@ static struct file *presto_filp_dopen(st
+                 }
+         }
+ 
++	/* XXX: where the fuck is ->f_vfsmnt? */
+         f->f_dentry = dentry;
++        f->f_mapping = dentry->d_inode->i_mapping;
+         f->f_pos = 0;
+         //f->f_reada = 0;
+         f->f_op = NULL;
+--- linux-2.6.0-test6/fs/ioctl.c	2003-07-13 21:44:35.000000000 -0700
++++ 25/fs/ioctl.c	2003-10-05 00:34:08.000000000 -0700
+@@ -22,7 +22,7 @@ static int file_ioctl(struct file *filp,
+ 	switch (cmd) {
+ 		case FIBMAP:
+ 		{
+-			struct address_space *mapping = inode->i_mapping;
++			struct address_space *mapping = filp->f_mapping;
+ 			int res;
+ 			/* do we support this mess? */
+ 			if (!mapping->a_ops->bmap)
+--- linux-2.6.0-test6/fs/isofs/inode.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/isofs/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -29,6 +29,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
++#include <linux/parser.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ 
+@@ -328,9 +329,52 @@ isofs_dentry_cmpi_ms(struct dentry *dent
+ }
+ #endif
+ 
++enum {
++	Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
++	Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
++	Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
++	Opt_nocompress,
++};
++
++static match_table_t tokens = {
++	{Opt_norock, "norock"},
++	{Opt_nojoliet, "nojoliet"},
++	{Opt_unhide, "unhide"},
++	{Opt_cruft, "cruft"},
++	{Opt_utf8, "utf8"},
++	{Opt_iocharset, "iocharset=%s"},
++	{Opt_map_a, "map=acorn"},
++	{Opt_map_a, "map=a"},
++	{Opt_map_n, "map=normal"},
++	{Opt_map_n, "map=n"},
++	{Opt_map_o, "map=off"},
++	{Opt_map_o, "map=o"},
++	{Opt_session, "session=%u"},
++	{Opt_sb, "sbsector=%u"},
++	{Opt_check_r, "check=relaxed"},
++	{Opt_check_r, "check=r"},
++	{Opt_check_s, "check=strict"},
++	{Opt_check_s, "check=s"},
++	{Opt_uid, "uid=%u"},
++	{Opt_gid, "gid=%u"},
++	{Opt_mode, "mode=%u"},
++	{Opt_block, "block=%u"},
++	{Opt_ignore, "conv=binary"},
++	{Opt_ignore, "conv=b"},
++	{Opt_ignore, "conv=text"},
++	{Opt_ignore, "conv=t"},
++	{Opt_ignore, "conv=mtext"},
++	{Opt_ignore, "conv=m"},
++	{Opt_ignore, "conv=auto"},
++	{Opt_ignore, "conv=a"},
++	{Opt_nocompress, "nocompress"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options, struct iso9660_options * popt)
+ {
+-	char *this_char,*value;
++	char *p;
++	int option;
+ 
+ 	popt->map = 'n';
+ 	popt->rock = 'y';
+@@ -350,112 +394,101 @@ static int parse_options(char *options, 
+ 	popt->utf8 = 0;
+ 	popt->session=-1;
+ 	popt->sbsector=-1;
+-	if (!options) return 1;
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++	if (!options)
++		return 1;
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token;
++		substring_t args[MAX_OPT_ARGS];
++		unsigned n;
++
++		if (!*p)
+ 			continue;
+-	        if (strncmp(this_char,"norock",6) == 0) {
+-		  popt->rock = 'n';
+-		  continue;
+-		}
+-	        if (strncmp(this_char,"nojoliet",8) == 0) {
+-		  popt->joliet = 'n';
+-		  continue;
+-		}
+-	        if (strncmp(this_char,"unhide",6) == 0) {
+-		  popt->unhide = 'y';
+-		  continue;
+-		}
+-	        if (strncmp(this_char,"cruft",5) == 0) {
+-		  popt->cruft = 'y';
+-		  continue;
+-		}
+-	        if (strncmp(this_char,"utf8",4) == 0) {
+-		  popt->utf8 = 1;
+-		  continue;
+-		}
+-	        if (strncmp(this_char,"nocompress",10) == 0) {
+-		  popt->nocompress = 1;
+-		  continue;
+-		}
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+ 
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_norock:
++			popt->rock = 'n';
++			break;
++		case Opt_nojoliet:
++			popt->joliet = 'n';
++			break;
++		case Opt_unhide:
++			popt->unhide = 'y';
++			break;
++		case Opt_cruft:
++			popt->cruft = 'y';
++			break;
++		case Opt_utf8:
++			popt->utf8 = 1;
++			break;
+ #ifdef CONFIG_JOLIET
+-		if (!strcmp(this_char,"iocharset") && value) {
+-			popt->iocharset = value;
+-			while (*value && *value != ',')
+-				value++;
+-			if (value == popt->iocharset)
+-				return 0;
+-			*value = 0;
+-		} else
++		case Opt_iocharset:
++			popt->iocharset = match_strdup(&args[0]);
++			break;
+ #endif
+-		if (!strcmp(this_char,"map") && value) {
+-			if (value[0] && !value[1] && strchr("ano",*value))
+-				popt->map = *value;
+-			else if (!strcmp(value,"off")) popt->map = 'o';
+-			else if (!strcmp(value,"normal")) popt->map = 'n';
+-			else if (!strcmp(value,"acorn")) popt->map = 'a';
+-			else return 0;
+-		}
+-		if (!strcmp(this_char,"session") && value) {
+-			char * vpnt = value;
+-			unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+-			if(ivalue < 0 || ivalue >99) return 0;
+-			popt->session=ivalue+1;
+-		}
+-		if (!strcmp(this_char,"sbsector") && value) {
+-			char * vpnt = value;
+-			unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+-			if(ivalue < 0 || ivalue >660*512) return 0;
+-			popt->sbsector=ivalue;
+-		}
+-		else if (!strcmp(this_char,"check") && value) {
+-			if (value[0] && !value[1] && strchr("rs",*value))
+-				popt->check = *value;
+-			else if (!strcmp(value,"relaxed")) popt->check = 'r';
+-			else if (!strcmp(value,"strict")) popt->check = 's';
+-			else return 0;
+-		}
+-		else if (!strcmp(this_char,"conv") && value) {
+-			/* no conversion is done anymore;
+-			   we still accept the same mount options,
+-			   but ignore them */
+-			if (value[0] && !value[1] && strchr("btma",*value)) ;
+-			else if (!strcmp(value,"binary")) ;
+-			else if (!strcmp(value,"text")) ;
+-			else if (!strcmp(value,"mtext")) ;
+-			else if (!strcmp(value,"auto")) ;
+-			else return 0;
+-		}
+-		else if (value &&
+-			 (!strcmp(this_char,"block") ||
+-			  !strcmp(this_char,"mode") ||
+-			  !strcmp(this_char,"uid") ||
+-			  !strcmp(this_char,"gid"))) {
+-		  char * vpnt = value;
+-		  unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
+-		  if (*vpnt) return 0;
+-		  switch(*this_char) {
+-		  case 'b':
+-		    if (   ivalue != 512
+-			&& ivalue != 1024
+-			&& ivalue != 2048) return 0;
+-		    popt->blocksize = ivalue;
+-		    break;
+-		  case 'u':
+-		    popt->uid = ivalue;
+-		    break;
+-		  case 'g':
+-		    popt->gid = ivalue;
+-		    break;
+-		  case 'm':
+-		    popt->mode = ivalue;
+-		    break;
+-		  }
++		case Opt_map_a:
++			popt->map = 'a';
++			break;
++		case Opt_map_o:
++			popt->map = 'o';
++			break;
++		case Opt_map_n:
++			popt->map = 'n';
++			break;
++		case Opt_session:
++			if (match_int(&args[0], &option))
++				return 0;
++			n = option;
++			if (n > 99)
++				return 0;
++			popt->session = n + 1;
++			break;
++		case Opt_sb:
++			if (match_int(&args[0], &option))
++				return 0;
++			n = option;
++			if (n > 660 * 512)
++				return 0;
++			popt->sbsector = n;
++			break;
++		case Opt_check_r:
++			popt->check = 'r';
++			break;
++		case Opt_check_s:
++			popt->check = 's';
++			break;
++		case Opt_ignore:
++			break;
++		case Opt_uid:
++			if (match_int(&args[0], &option))
++				return 0;
++			popt->uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(&args[0], &option))
++				return 0;
++			popt->gid = option;
++			break;
++		case Opt_mode:
++			if (match_int(&args[0], &option))
++				return 0;
++			popt->mode = option;
++			break;
++		case Opt_block:
++			if (match_int(&args[0], &option))
++				return 0;
++			n = option;
++			if (n != 512 && n != 1024 && n != 2048)
++				return 0;
++			popt->blocksize = n;
++			break;
++		case Opt_nocompress:
++			popt->nocompress = 1;
++			break;
++		default:
++			return 0;
+ 		}
+-		else return 1;
+ 	}
+ 	return 1;
+ }
+@@ -842,6 +875,9 @@ root_found:
+ 	if (opt.check == 'r') table++;
+ 	s->s_root->d_op = &isofs_dentry_ops[table];
+ 
++	if (opt.iocharset)
++		kfree(opt.iocharset);
++
+ 	return 0;
+ 
+ 	/*
+@@ -879,6 +915,8 @@ out_unknown_format:
+ out_freebh:
+ 	brelse(bh);
+ out_freesbi:
++	if (opt.iocharset)
++		kfree(opt.iocharset);
+ 	kfree(sbi);
+ 	s->s_fs_info = NULL;
+ 	return -EINVAL;
+--- linux-2.6.0-test6/fs/jbd/journal.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/jbd/journal.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1800,7 +1800,7 @@ int read_jbd_debug(char *page, char **st
+ 	return ret;
+ }
+ 
+-int write_jbd_debug(struct file *file, const char *buffer,
++int write_jbd_debug(struct file *file, const char __user *buffer,
+ 			   unsigned long count, void *data)
+ {
+ 	char buf[32];
+--- linux-2.6.0-test6/fs/jffs/intrep.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/jffs/intrep.c	2003-10-05 00:34:48.000000000 -0700
+@@ -3337,18 +3337,16 @@ jffs_garbage_collect_thread(void *ptr)
+ 	int result = 0;
+ 	D1(int i = 1);
+ 
++	daemonize("jffs_gcd");
++
+ 	c->gc_task = current;
+ 
+ 	lock_kernel();
+-	exit_mm(c->gc_task);
+-
+-	set_special_pids(1, 1);
+ 	init_completion(&c->gc_thread_comp); /* barrier */ 
+ 	spin_lock_irq(&current->sighand->siglock);
+ 	siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
+ 	recalc_sigpending();
+ 	spin_unlock_irq(&current->sighand->siglock);
+-	strcpy(current->comm, "jffs_gcd");
+ 
+ 	D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n"));
+ 
+--- linux-2.6.0-test6/fs/jfs/inode.c	2003-09-08 13:58:58.000000000 -0700
++++ 25/fs/jfs/inode.c	2003-10-05 00:34:07.000000000 -0700
+@@ -302,7 +302,7 @@ static int jfs_direct_IO(int rw, struct 
+ 			loff_t offset, unsigned long nr_segs)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode *inode = file->f_mapping->host;
+ 
+ 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ 				offset, nr_segs, jfs_get_blocks, NULL);
+--- linux-2.6.0-test6/fs/jfs/jfs_debug.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/fs/jfs/jfs_debug.c	2003-10-05 00:33:24.000000000 -0700
+@@ -81,7 +81,7 @@ static int loglevel_read(char *page, cha
+ 	return len;
+ }
+ 
+-static int loglevel_write(struct file *file, const char *buffer,
++static int loglevel_write(struct file *file, const char __user *buffer,
+ 			unsigned long count, void *data)
+ {
+ 	char c;
+--- linux-2.6.0-test6/fs/jfs/jfs_imap.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/jfs/jfs_imap.c	2003-10-05 00:33:24.000000000 -0700
+@@ -838,7 +838,7 @@ int diWrite(tid_t tid, struct inode *ip)
+ 	 */
+ 	if (S_ISDIR(ip->i_mode)
+ 	    && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
+-		bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(struct dasd));
++		memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
+ #endif				/*  _JFS_FASTDASD */
+ 
+ 	/* release the buffer holding the updated on-disk inode. 
+--- linux-2.6.0-test6/fs/jfs/super.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/jfs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/config.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/completion.h>
+ #include <linux/vfs.h>
+ #include <asm/uaccess.h>
+@@ -164,59 +165,82 @@ static void jfs_put_super(struct super_b
+ 	kfree(sbi);
+ }
+ 
++enum {
++	Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
++	Opt_ignore, Opt_err,
++};
++
++static match_table_t tokens = {
++	{Opt_integrity, "integrity"},
++	{Opt_nointegrity, "nointegrity"},
++	{Opt_iocharset, "iocharset=%s"},
++	{Opt_resize, "resize=%u"},
++	{Opt_ignore, "noquota"},
++	{Opt_ignore, "quota"},
++	{Opt_ignore, "usrquota"},
++	{Opt_ignore, "grpquota"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
+ 			 int *flag)
+ {
+ 	void *nls_map = NULL;
+-	char *this_char;
+-	char *value;
++	char *p;
+ 	struct jfs_sb_info *sbi = JFS_SBI(sb);
+ 
+ 	*newLVSize = 0;
+ 
+ 	if (!options)
+ 		return 1;
+-	while ((this_char = strsep(&options, ",")) != NULL) {
+-		if (!*this_char)
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char, '=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp(this_char, "integrity")) {
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_integrity:
+ 			*flag &= ~JFS_NOINTEGRITY;
+-		} else 	if (!strcmp(this_char, "nointegrity")) {
++			break;
++		case Opt_nointegrity:
+ 			*flag |= JFS_NOINTEGRITY;
+-		} else if (!strcmp(this_char, "iocharset")) {
+-			if (!value || !*value)
+-				goto needs_arg;
++			break;
++		case Opt_ignore:
++			/* Silently ignore the quota options */
++			/* Don't do anything ;-) */
++			break;
++		case Opt_iocharset:
+ 			if (nls_map)	/* specified iocharset twice! */
+ 				unload_nls(nls_map);
+-			nls_map = load_nls(value);
++			nls_map = load_nls(args[0].from);
+ 			if (!nls_map) {
+ 				printk(KERN_ERR "JFS: charset not found\n");
+ 				goto cleanup;
+ 			}
+-		} else if (!strcmp(this_char, "resize")) {
+-			if (!value || !*value) {
++			break;
++		case Opt_resize:
++		{
++			char *resize = args[0].from;
++			if (!resize || !*resize) {
+ 				*newLVSize = sb->s_bdev->bd_inode->i_size >>
+ 					sb->s_blocksize_bits;
+ 				if (*newLVSize == 0)
+ 					printk(KERN_ERR
+-					 "JFS: Cannot determine volume size\n");
++					"JFS: Cannot determine volume size\n");
+ 			} else
+-				*newLVSize = simple_strtoull(value, &value, 0);
+-
+-			/* Silently ignore the quota options */
+-		} else if (!strcmp(this_char, "grpquota")
+-			   || !strcmp(this_char, "noquota")
+-			   || !strcmp(this_char, "quota")
+-			   || !strcmp(this_char, "usrquota"))
+-			/* Don't do anything ;-) */ ;
+-		else {
+-			printk("jfs: Unrecognized mount option %s\n",
+-			       this_char);
++				*newLVSize = simple_strtoull(resize, &resize, 0);
++			break;
++		}
++		default:
++			printk("jfs: Unrecognized mount option \"%s\" "
++					" or missing value\n", p);
+ 			goto cleanup;
+ 		}
+ 	}
++
+ 	if (nls_map) {
+ 		/* Discard old (if remount) */
+ 		if (sbi->nls_tab)
+@@ -224,8 +248,7 @@ static int parse_options(char *options, 
+ 		sbi->nls_tab = nls_map;
+ 	}
+ 	return 1;
+-needs_arg:
+-	printk(KERN_ERR "JFS: %s needs an argument\n", this_char);
++
+ cleanup:
+ 	if (nls_map)
+ 		unload_nls(nls_map);
+--- linux-2.6.0-test6/fs/jfs/symlink.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/fs/jfs/symlink.c	2003-10-05 00:33:24.000000000 -0700
+@@ -26,7 +26,7 @@ static int jfs_follow_link(struct dentry
+ 	return vfs_follow_link(nd, s);
+ }
+ 
+-static int jfs_readlink(struct dentry *dentry, char *buffer, int buflen)
++static int jfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+ 	char *s = JFS_IP(dentry->d_inode)->i_inline;
+ 	return vfs_readlink(dentry, buffer, buflen, s);
+--- linux-2.6.0-test6/fs/Kconfig	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/Kconfig	2003-10-05 00:36:47.000000000 -0700
+@@ -874,6 +874,7 @@ config TMPFS
+ 
+ config HUGETLBFS
+ 	bool "HugeTLB file system support"
++	depends X86 || IA64 || PPC64 || SPARC64 || X86_64 || BROKEN
+ 
+ config HUGETLB_PAGE
+ 	def_bool HUGETLBFS
+@@ -1254,6 +1255,8 @@ menu "Network File Systems"
+ config NFS_FS
+ 	tristate "NFS file system support"
+ 	depends on INET
++	select LOCKD
++	select SUNRPC
+ 	help
+ 	  If you are connected to some other (usually local) Unix computer
+ 	  (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing
+@@ -1306,9 +1309,36 @@ config NFS_V4
+ 
+ 	  If unsure, say N.
+ 
++config NFS_DIRECTIO
++	bool
++	depends on NFS_FS
++	default y
++	help
++	  This option enables applications to perform uncached I/O on files
++	  in NFS file systems using the O_DIRECT open() flag.  When O_DIRECT
++	  is set for a file, its data is not cached in the system's page
++	  cache.  Data is moved to and from user-level application buffers
++	  directly.  Unlike local disk-based file systems, NFS O_DIRECT has
++	  no alignment restrictions.
++
++	  Unless your program is designed to use O_DIRECT properly, you are
++	  much better off allowing the NFS client to manage data caching for
++	  you.  Misusing O_DIRECT can cause poor server performance or network
++	  storms.  This kernel build option defaults OFF to avoid exposing
++	  system administrators unwittingly to a potentially hazardous
++	  feature.
++
++	  For more details on NFS O_DIRECT, see fs/nfs/direct.c.
++
++	  If unsure, say N.  This reduces the size of the NFS client, and
++	  causes open() to return EINVAL if a file residing in NFS is
++	  opened with the O_DIRECT flag.
++
+ config NFSD
+ 	tristate "NFS server support"
+ 	depends on INET
++	select LOCKD
++	select SUNRPC
+ 	help
+ 	  If you want your Linux box to act as an NFS *server*, so that other
+ 	  computers on your local network which support NFS can access certain
+@@ -1371,8 +1401,6 @@ config ROOT_NFS
+ 
+ config LOCKD
+ 	tristate
+-	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
+-	default y if NFS_FS=y || NFSD=y
+ 
+ config LOCKD_V4
+ 	bool
+@@ -1385,8 +1413,6 @@ config EXPORTFS
+ 
+ config SUNRPC
+ 	tristate
+-	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
+-	default y if NFS_FS=y || NFSD=y
+ 
+ config SUNRPC_GSS
+ 	tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)"
+@@ -1565,6 +1591,7 @@ config AFS_FS
+ # for fs/nls/Config.in
+ 	tristate "Andrew File System support (AFS) (Experimental)"
+ 	depends on INET && EXPERIMENTAL
++	select RXRPC
+ 	help
+ 	  If you say Y here, you will get an experimental Andrew File System
+ 	  driver. It currently only supports unsecured read-only AFS access.
+@@ -1575,8 +1602,6 @@ config AFS_FS
+ 
+ config RXRPC
+ 	tristate
+-	default m if AFS_FS=m
+-	default y if AFS_FS=y
+ 
+ endmenu
+ 
+--- linux-2.6.0-test6/fs/libfs.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/libfs.c	2003-10-05 00:33:24.000000000 -0700
+@@ -429,3 +429,26 @@ void simple_release_fs(struct vfsmount *
+ 	spin_unlock(&pin_fs_lock);
+ 	mntput(mnt);
+ }
++
++EXPORT_SYMBOL(dcache_dir_close);
++EXPORT_SYMBOL(dcache_dir_lseek);
++EXPORT_SYMBOL(dcache_dir_open);
++EXPORT_SYMBOL(dcache_readdir);
++EXPORT_SYMBOL(generic_read_dir);
++EXPORT_SYMBOL(simple_commit_write);
++EXPORT_SYMBOL(simple_dir_inode_operations);
++EXPORT_SYMBOL(simple_dir_operations);
++EXPORT_SYMBOL(simple_empty);
++EXPORT_SYMBOL(simple_fill_super);
++EXPORT_SYMBOL(simple_getattr);
++EXPORT_SYMBOL(simple_link);
++EXPORT_SYMBOL(simple_lookup);
++EXPORT_SYMBOL(simple_pin_fs);
++EXPORT_SYMBOL(simple_prepare_write);
++EXPORT_SYMBOL(simple_readpage);
++EXPORT_SYMBOL(simple_release_fs);
++EXPORT_SYMBOL(simple_rename);
++EXPORT_SYMBOL(simple_rmdir);
++EXPORT_SYMBOL(simple_statfs);
++EXPORT_SYMBOL(simple_sync_file);
++EXPORT_SYMBOL(simple_unlink);
+--- linux-2.6.0-test6/fs/locks.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/locks.c	2003-10-05 00:36:10.000000000 -0700
+@@ -928,10 +928,10 @@ int locks_mandatory_locked(struct inode 
+  * locks_mandatory_area - Check for a conflicting lock
+  * @read_write: %FLOCK_VERIFY_WRITE for exclusive access, %FLOCK_VERIFY_READ
+  *		for shared
+- * @inode: the file to check
+- * @file: how the file was opened (if it was)
+- * @offset: start of area to check
+- * @count: length of area to check
++ * @inode:      the file to check
++ * @filp:       how the file was opened (if it was)
++ * @offset:     start of area to check
++ * @count:      length of area to check
+  *
+  * Searches the inode's list of locks to find any POSIX locks which conflict.
+  * This function is called from locks_verify_area() and
+@@ -1119,6 +1119,7 @@ out:
+ /**
+  *	lease_get_mtime
+  *	@inode: the inode
++ *      @time:  pointer to a timespec which will contain the last modified time
+  *
+  * This is to force NFS clients to flush their caches for files with
+  * exclusive leases.  The justification is that if someone has an
+@@ -1434,7 +1435,7 @@ int fcntl_setlk(struct file *filp, unsig
+ 	 */
+ 	if (IS_MANDLOCK(inode) &&
+ 	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
+-		struct address_space *mapping = inode->i_mapping;
++		struct address_space *mapping = filp->f_mapping;
+ 
+ 		if (!list_empty(&mapping->i_mmap_shared)) {
+ 			error = -EAGAIN;
+@@ -1572,7 +1573,7 @@ int fcntl_setlk64(struct file *filp, uns
+ 	 */
+ 	if (IS_MANDLOCK(inode) &&
+ 	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
+-		struct address_space *mapping = inode->i_mapping;
++		struct address_space *mapping = filp->f_mapping;
+ 
+ 		if (!list_empty(&mapping->i_mmap_shared)) {
+ 			error = -EAGAIN;
+@@ -1726,6 +1727,7 @@ posix_block_lock(struct file_lock *block
+ 
+ /**
+  *	posix_unblock_lock - stop waiting for a file lock
++ *      @filp:   how the file was opened
+  *	@waiter: the lock which was waiting
+  *
+  *	lockd needs to block waiting for locks.
+--- linux-2.6.0-test6/fs/namei.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/namei.c	2003-10-05 00:33:24.000000000 -0700
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <linux/init.h>
++#include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/namei.h>
+@@ -218,7 +219,7 @@ int permission(struct inode * inode,int 
+ 	if (retval)
+ 		return retval;
+ 
+-	return security_inode_permission(inode, mask);
++	return security_inode_permission(inode, mask, nd);
+ }
+ 
+ /*
+@@ -302,7 +303,8 @@ static struct dentry * cached_lookup(str
+  * short-cut DAC fails, then call permission() to do more
+  * complete permission check.
+  */
+-static inline int exec_permission_lite(struct inode *inode)
++static inline int exec_permission_lite(struct inode *inode,
++				       struct nameidata *nd)
+ {
+ 	umode_t	mode = inode->i_mode;
+ 
+@@ -325,7 +327,7 @@ static inline int exec_permission_lite(s
+ 
+ 	return -EACCES;
+ ok:
+-	return security_inode_permission(inode, MAY_EXEC);
++	return security_inode_permission(inode, MAY_EXEC, nd);
+ }
+ 
+ /*
+@@ -584,7 +586,7 @@ int link_path_walk(const char * name, st
+ 		struct qstr this;
+ 		unsigned int c;
+ 
+-		err = exec_permission_lite(inode);
++		err = exec_permission_lite(inode, nd);
+ 		if (err == -EAGAIN) { 
+ 			err = permission(inode, MAY_EXEC, nd);
+ 		}
+@@ -2275,3 +2277,33 @@ struct inode_operations page_symlink_ino
+ 	.readlink	= page_readlink,
+ 	.follow_link	= page_follow_link,
+ };
++
++EXPORT_SYMBOL(__user_walk);
++EXPORT_SYMBOL(follow_down);
++EXPORT_SYMBOL(follow_up);
++EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
++EXPORT_SYMBOL(getname);
++EXPORT_SYMBOL(lock_rename);
++EXPORT_SYMBOL(lookup_create);
++EXPORT_SYMBOL(lookup_hash);
++EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(page_follow_link);
++EXPORT_SYMBOL(page_readlink);
++EXPORT_SYMBOL(page_symlink);
++EXPORT_SYMBOL(page_symlink_inode_operations);
++EXPORT_SYMBOL(path_lookup);
++EXPORT_SYMBOL(path_release);
++EXPORT_SYMBOL(path_walk);
++EXPORT_SYMBOL(permission);
++EXPORT_SYMBOL(unlock_rename);
++EXPORT_SYMBOL(vfs_create);
++EXPORT_SYMBOL(vfs_follow_link);
++EXPORT_SYMBOL(vfs_link);
++EXPORT_SYMBOL(vfs_mkdir);
++EXPORT_SYMBOL(vfs_mknod);
++EXPORT_SYMBOL(vfs_permission);
++EXPORT_SYMBOL(vfs_readlink);
++EXPORT_SYMBOL(vfs_rename);
++EXPORT_SYMBOL(vfs_rmdir);
++EXPORT_SYMBOL(vfs_symlink);
++EXPORT_SYMBOL(vfs_unlink);
+--- linux-2.6.0-test6/fs/nfs/direct.c	2003-06-26 22:07:25.000000000 -0700
++++ 25/fs/nfs/direct.c	2003-10-05 00:36:46.000000000 -0700
+@@ -1,7 +1,7 @@
+ /*
+  * linux/fs/nfs/direct.c
+  *
+- * Copyright (C) 2001 by Chuck Lever <cel@netapp.com>
++ * Copyright (C) 2003 by Chuck Lever <cel@netapp.com>
+  *
+  * High-performance uncached I/O for the Linux NFS client
+  *
+@@ -26,19 +26,23 @@
+  * also supports uncaching whole NFS partitions with "-o forcedirectio,"
+  * an undocumented mount option.
+  *
+- * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust.
++ * Designed by Jeff Kimmel, Chuck Lever, and Trond Myklebust, with
++ * help from Andrew Morton.
+  *
+  * 18 Dec 2001	Initial implementation for 2.4  --cel
+  * 08 Jul 2002	Version for 2.4.19, with bug fixes --trondmy
+- * 24 Sep 2002	Rewrite to use asynchronous RPCs, port to 2.5  --cel
++ * 08 Jun 2003	Port to 2.5 APIs  --cel
+  *
+  */
+ 
+ #include <linux/config.h>
++#include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
++#include <linux/smp_lock.h>
+ #include <linux/file.h>
+-#include <linux/errno.h>
++#include <linux/pagemap.h>
++
+ #include <linux/nfs_fs.h>
+ #include <linux/nfs_page.h>
+ #include <linux/sunrpc/clnt.h>
+@@ -46,35 +50,41 @@
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ 
+-#define NFSDBG_FACILITY		(NFSDBG_PAGECACHE | NFSDBG_VFS)
++#define NFSDBG_FACILITY		NFSDBG_VFS
+ #define VERF_SIZE		(2 * sizeof(__u32))
++#define MAX_DIRECTIO_SIZE	(4096UL << PAGE_SHIFT)
+ 
+ 
+ /**
+- * nfs_get_user_pages - find and set up page representing user buffer
+- * addr: user-space address of target buffer
+- * size: total size in bytes of target buffer
+- * @pages: returned array of page struct pointers underlying target buffer
+- * write: whether or not buffer is target of a write operation
++ * nfs_get_user_pages - find and set up pages underlying user's buffer
++ * rw: direction (read or write)
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * @pages: returned array of page struct pointers underlying user's buffer
+  */
+ static inline int
+-nfs_get_user_pages(unsigned long addr, size_t size,
+-		struct page ***pages, int rw)
++nfs_get_user_pages(int rw, unsigned long user_addr, size_t size,
++		struct page ***pages)
+ {
+ 	int result = -ENOMEM;
+-	unsigned page_count = (unsigned) size >> PAGE_SHIFT;
+-	unsigned array_size = (page_count * sizeof(struct page *)) + 2U;
++	unsigned long page_count;
++	size_t array_size;
++
++	/* set an arbitrary limit to prevent arithmetic overflow */
++	if (size > MAX_DIRECTIO_SIZE)
++		return -EFBIG;
+ 
+-	*pages = (struct page **) kmalloc(array_size, GFP_KERNEL);
++	page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
++	page_count -= user_addr >> PAGE_SHIFT;
++
++	array_size = (page_count * sizeof(struct page *));
++	*pages = kmalloc(array_size, GFP_KERNEL);
+ 	if (*pages) {
+ 		down_read(&current->mm->mmap_sem);
+-		result = get_user_pages(current, current->mm, addr,
+-					page_count, (rw == WRITE), 0,
++		result = get_user_pages(current, current->mm, user_addr,
++					page_count, (rw == READ), 0,
+ 					*pages, NULL);
+ 		up_read(&current->mm->mmap_sem);
+-		if (result < 0)
+-			printk(KERN_ERR "%s: get_user_pages result %d\n",
+-					__FUNCTION__, result);
+ 	}
+ 	return result;
+ }
+@@ -84,176 +94,349 @@ nfs_get_user_pages(unsigned long addr, s
+  * @pages: array of page struct pointers underlying target buffer
+  */
+ static inline void
+-nfs_free_user_pages(struct page **pages, unsigned count)
++nfs_free_user_pages(struct page **pages)
+ {
+-	unsigned page = 0;
++	kfree(pages);
++}
+ 
+-	while (count--)
+-		page_cache_release(pages[page++]);
++/**
++ * nfs_direct_read_seg - Read in one iov segment.  Generate separate
++ *                        read RPCs for each "rsize" bytes.
++ * @inode: target inode
++ * @cred: user's credential
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * file_offset: offset in file to begin the operation
++ * @pages: array of addresses of page structs defining user's buffer
++ * nr_pages: size of pages array
++ */
++static int
++nfs_direct_read_seg(struct inode *inode, struct rpc_cred *cred,
++		unsigned long user_addr, size_t count, loff_t file_offset,
++		struct page **pages, int nr_pages)
++{
++	const unsigned int rsize = NFS_SERVER(inode)->rsize;
++	int tot_bytes = 0;
++	int curpage = 0;
++	struct nfs_read_data	rdata = {
++		.flags		= 0,
++		.cred		= cred,
++		.inode		= inode,
++		.args		= {
++			.fh		= NFS_FH(inode),
++		},
++		.res		= {
++			.fattr		= &rdata.fattr,
++		},
++	};
++
++        do {
++		int request, result;
++
++                request = count;
++                if (count > rsize)
++                        request = rsize;
++		rdata.args.count = request,
++		rdata.args.pgbase = user_addr & ~PAGE_MASK;
++		rdata.args.offset = file_offset;
++		rdata.args.pages = &pages[curpage];
++
++		dprintk("NFS: direct read: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
++			rdata.args.count, (long long) rdata.args.offset,
++			user_addr, rdata.args.pgbase, curpage);
++
++		lock_kernel();
++		result = NFS_PROTO(inode)->read(&rdata);
++		unlock_kernel();
++
++		if (result < 0) {
++			if (result == -EISDIR)
++				result = -EINVAL;
++			return result;
++		}
+ 
+-	kfree(pages);
++                tot_bytes += result;
++                count -= result;
++                file_offset += result;
++		user_addr += result;
++
++		if (rdata.res.eof)
++			break;
++
++		curpage += (rdata.args.pgbase + result) >> PAGE_SHIFT;
++	} while (count);
++
++	/* XXX: should we zero the rest of the user's buffer if we
++	 *      hit eof? */
++
++	return tot_bytes;
+ }
+ 
+ /**
+- * nfs_iov2pagelist - convert an array of iovecs to a list of page requests
+- * @inode: inode of target file
+- * @cred: credentials of user who requested I/O
++ * nfs_direct_read - For each iov segment, map the user's buffer
++ *                   then generate read RPCs.
++ * @inode: target inode
++ * @cred: user's credential
+  * @iov: array of vectors that define I/O buffer
+- * offset: where in file to begin the read
++ * file_offset: offset in file to begin the operation
+  * nr_segs: size of iovec array
+- * @requests: append new page requests to this list head
++ *
++ * generic_file_direct_IO has already pushed out any non-direct
++ * writes so that this read will see them when we read from the
++ * server.
+  */
+ static int
+-nfs_iov2pagelist(int rw, const struct inode *inode,
+-		const struct rpc_cred *cred,
+-		const struct iovec *iov, loff_t offset,
+-		unsigned long nr_segs, struct list_head *requests)
++nfs_direct_read(struct inode *inode, struct rpc_cred *cred,
++		const struct iovec *iov, loff_t file_offset,
++		unsigned long nr_segs)
+ {
+-	unsigned seg;
+ 	int tot_bytes = 0;
+-	struct page **pages;
++	unsigned long seg = 0;
+ 
+-	/* for each iovec in the array... */
+-	for (seg = 0; seg < nr_segs; seg++) {
+-		const unsigned long user_addr =
+-					(unsigned long) iov[seg].iov_base;
+-		size_t bytes = iov[seg].iov_len;
+-		unsigned int pg_offset = (user_addr & ~PAGE_MASK);
+-		int page_count, page = 0;
+-
+-		page_count = nfs_get_user_pages(user_addr, bytes, &pages, rw);
+-		if (page_count < 0) {
+-			nfs_release_list(requests);
+-			return page_count;
++	while ((seg < nr_segs) && (tot_bytes >= 0)) {
++		int result, page_count;
++		struct page **pages;
++		const struct iovec *vec = &iov[seg++];
++		unsigned long user_addr = (unsigned long) vec->iov_base;
++		size_t size = vec->iov_len;
++
++                page_count = nfs_get_user_pages(READ, user_addr, size, &pages);
++                if (page_count < 0) {
++                        nfs_free_user_pages(pages);
++                        return page_count;
++                }
++
++		result = nfs_direct_read_seg(inode, cred, user_addr, size,
++				file_offset, pages, page_count);
++		if (result < 0)
++			tot_bytes = result;
++		else {
++			tot_bytes += result;
++			file_offset += result;
+ 		}
+ 
+-		/* ...build as many page requests as required */
+-		while (bytes > 0) {
+-			struct nfs_page *new;
+-			const unsigned int pg_bytes = (bytes > PAGE_SIZE) ?
+-							PAGE_SIZE : bytes;
+-
+-			new = nfs_create_request((struct rpc_cred *) cred,
+-						 (struct inode *) inode,
+-						 pages[page],
+-						 pg_offset, pg_bytes);
+-			if (IS_ERR(new)) {
+-				nfs_free_user_pages(pages, page_count);
+-				nfs_release_list(requests);
+-				return PTR_ERR(new);
+-			}
+-			new->wb_index = offset;
+-			nfs_list_add_request(new, requests);
+-
+-			/* after the first page */
+-			pg_offset = 0;
+-			offset += PAGE_SIZE;
+-			tot_bytes += pg_bytes;
+-			bytes -= pg_bytes;
+-			page++;
++		nfs_free_user_pages(pages);
++	}
++
++	return tot_bytes;
++}
++
++/**
++ * nfs_direct_write_seg - Write out one iov segment.  Generate separate
++ *                        write RPCs for each "wsize" bytes, then commit.
++ * @inode: target inode
++ * @cred: user's credential
++ * user_addr: starting address of this segment of user's buffer
++ * count: size of this segment
++ * file_offset: offset in file to begin the operation
++ * @pages: array of addresses of page structs defining user's buffer
++ * nr_pages: size of pages array
++ */
++static int
++nfs_direct_write_seg(struct inode *inode, struct rpc_cred *cred,
++		unsigned long user_addr, size_t count, loff_t file_offset,
++		struct page **pages, int nr_pages)
++{
++	const unsigned int wsize = NFS_SERVER(inode)->wsize;
++	loff_t save_offset = file_offset;
++	size_t save_count = count;
++	int need_commit = 0;
++	int tot_bytes = 0;
++	int curpage = 0;
++	struct nfs_writeverf first_verf;
++	struct nfs_write_data	wdata = {
++		.cred		= cred,
++		.inode		= inode,
++		.args		= {
++			.fh		= NFS_FH(inode),
++		},
++		.res		= {
++			.fattr		= &wdata.fattr,
++			.verf		= &wdata.verf,
++		},
++	};
++
++	wdata.args.stable = NFS_UNSTABLE;
++	if (IS_SYNC(inode) || NFS_PROTO(inode)->version == 2 || count <= wsize)
++		wdata.args.stable = NFS_FILE_SYNC;
++
++retry:
++        do {
++		int request, result;
++
++                request = count;
++                if (count > wsize)
++                        request = wsize;
++		wdata.args.count = request,
++		wdata.args.pgbase = user_addr & ~PAGE_MASK;
++		wdata.args.offset = file_offset;
++		wdata.args.pages = &pages[curpage];
++
++		dprintk("NFS: direct write: c=%u o=%Ld ua=%lu, pb=%u, cp=%u\n",
++			wdata.args.count, (long long) wdata.args.offset,
++			user_addr, wdata.args.pgbase, curpage);
++
++		lock_kernel();
++		result = NFS_PROTO(inode)->write(&wdata);
++		unlock_kernel();
++
++		if (result < 0)
++			return result;
++
++		if (!tot_bytes)
++			memcpy(&first_verf.verifier, &wdata.verf.verifier,
++								VERF_SIZE);
++		if (wdata.verf.committed != NFS_FILE_SYNC) {
++			need_commit = 1;
++			if (memcmp(&first_verf.verifier,
++					&wdata.verf.verifier, VERF_SIZE))
++				goto sync_retry;
+ 		}
+ 
+-		/* don't release pages here -- I/O completion will do that */
+-		nfs_free_user_pages(pages, 0);
++                tot_bytes += result;
++                count -= result;
++                file_offset += result;
++		user_addr += result;
++
++		curpage += (wdata.args.pgbase + result) >> PAGE_SHIFT;
++	} while (count);
++
++	/*
++	 * Commit data written so far, even in the event of an error
++	 */
++	if (need_commit) {
++		int result;
++
++		wdata.args.count = tot_bytes;
++		wdata.args.offset = save_offset;
++
++		lock_kernel();
++		result = NFS_PROTO(inode)->commit(&wdata);
++		unlock_kernel();
++
++		if (result < 0)
++			goto sync_retry;
++		if (memcmp(&first_verf.verifier, &wdata.verf.verifier,
++								VERF_SIZE))
++			goto sync_retry;
+ 	}
+ 
+ 	return tot_bytes;
++
++sync_retry:
++	wdata.args.stable = NFS_FILE_SYNC;
++	file_offset = save_offset;
++	count = save_count;
++	goto retry;
+ }
+ 
+ /**
+- * do_nfs_direct_IO - Read or write data without caching
+- * @inode: inode of target file
+- * @cred: credentials of user who requested I/O
++ * nfs_direct_write - For each iov segment, map the user's buffer
++ *                    then generate write and commit RPCs.
++ * @inode: target inode
++ * @cred: user's credential
+  * @iov: array of vectors that define I/O buffer
+- * offset: where in file to begin the read
++ * file_offset: offset in file to begin the operation
+  * nr_segs: size of iovec array
+  *
+- * Break the passed-in iovec into a series of page-sized or smaller
+- * requests, where each page is mapped for direct user-land I/O.
+- *
+- * For each of these pages, create an NFS page request and
+- * append it to an automatic list of page requests.
+- *
+- * When all page requests have been queued, start the I/O on the
+- * whole list.  The underlying routines coalesce the pages on the
+- * list into a bunch of asynchronous "r/wsize" network requests.
+- *
+- * I/O completion automatically unmaps and releases the pages.
++ * Upon return, generic_file_direct_IO invalidates any cached pages
++ * that non-direct readers might access, so they will pick up these
++ * writes immediately.
+  */
+ static int
+-do_nfs_direct_IO(int rw, const struct inode *inode,
+-		const struct rpc_cred *cred, const struct iovec *iov,
+-		loff_t offset, unsigned long nr_segs)
++nfs_direct_write(struct inode *inode, struct rpc_cred *cred,
++		const struct iovec *iov, loff_t file_offset,
++		unsigned long nr_segs)
+ {
+-	LIST_HEAD(requests);
+-	int result, tot_bytes;
++	int tot_bytes = 0;
++	unsigned long seg = 0;
+ 
+-	result = nfs_iov2pagelist(rw, inode, cred, iov, offset, nr_segs,
+-								&requests);
+-	if (result < 0)
+-		return result;
+-	tot_bytes = result;
++	while ((seg < nr_segs) && (tot_bytes >= 0)) {
++		int result, page_count;
++		struct page **pages;
++		const struct iovec *vec = &iov[seg++];
++		unsigned long user_addr = (unsigned long) vec->iov_base;
++		size_t size = vec->iov_len;
++
++                page_count = nfs_get_user_pages(WRITE, user_addr, size, &pages);
++                if (page_count < 0) {
++                        nfs_free_user_pages(pages);
++                        return page_count;
++                }
+ 
+-	switch (rw) {
+-	case READ:
+-		if (IS_SYNC(inode) || (NFS_SERVER(inode)->rsize < PAGE_SIZE)) {
+-			result = nfs_direct_read_sync(inode, cred, iov, offset, nr_segs);
+-			break;
++		result = nfs_direct_write_seg(inode, cred, user_addr, size,
++				file_offset, pages, page_count);
++		if (result < 0)
++			tot_bytes = result;
++		else {
++			tot_bytes += result;
++			file_offset += result;
+ 		}
+-		result = nfs_pagein_list(&requests, NFS_SERVER(inode)->rpages);
+-		nfs_wait_for_reads(&requests);
+-		break;
+-	case WRITE:
+-		if (IS_SYNC(inode) || (NFS_SERVER(inode)->wsize < PAGE_SIZE))
+-			result = nfs_direct_write_sync(inode, cred, iov, offset, nr_segs);
+-		else
+-			result = nfs_flush_list(&requests,
+-					NFS_SERVER(inode)->wpages, FLUSH_WAIT);
+ 
+-		/* invalidate cache so non-direct readers pick up changes */
+-		invalidate_inode_pages((struct inode *) inode);
+-		break;
+-	default:
+-		result = -EINVAL;
+-		break;
++		nfs_free_user_pages(pages);
+ 	}
+ 
+-	if (result < 0)
+-		return result;
+ 	return tot_bytes;
+ }
+ 
+ /**
+  * nfs_direct_IO - NFS address space operation for direct I/O
+  * rw: direction (read or write)
+- * @file: file struct of target file
++ * @iocb: target I/O control block
+  * @iov: array of vectors that define I/O buffer
+- * offset: offset in file to begin the operation
++ * file_offset: offset in file to begin the operation
+  * nr_segs: size of iovec array
+  *
++ * Usually a file system implements direct I/O by calling out to
++ * blockdev_direct_IO.  The NFS client doesn't have a backing block
++ * device, so we do everything by hand instead.
++ *
+  * The inode's i_sem is no longer held by the VFS layer before it calls
+  * this function to do a write.
+  */
+ int
+ nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+-		loff_t offset, unsigned long nr_segs)
++		loff_t file_offset, unsigned long nr_segs)
+ {
+-	/* None of this works yet, so prevent it from compiling. */
+-#if 0
+-	int result;
++	int result = -EINVAL;
++	struct file *file = iocb->ki_filp;
+ 	struct dentry *dentry = file->f_dentry;
+-	const struct inode *inode = dentry->d_inode->i_mapping->host;
+-	const struct rpc_cred *cred = nfs_file_cred(file);
+-#endif
+-
+-	dfprintk(VFS, "NFS: direct_IO(%s) (%s/%s) off/no(%Lu/%lu)\n",
+-				((rw == READ) ? "READ" : "WRITE"),
+-				dentry->d_parent->d_name.name,
+-				dentry->d_name.name, offset, nr_segs);
++	struct inode *inode = dentry->d_inode;
++	struct rpc_cred *cred;
++
++	/*
++	 * No support for async yet
++	 */
++	if (!is_sync_kiocb(iocb))
++		goto out;
++
++	cred = get_rpccred(nfs_file_cred(file));
++	if (!cred)
++		cred = get_rpccred(NFS_I(inode)->mm_cred);
++
++	switch (rw) {
++	case READ:
++		dprintk("NFS: direct_IO(read) (%s) off/no(%Lu/%lu)\n",
++				dentry->d_name.name, file_offset, nr_segs);
++
++		result = nfs_direct_read(inode, cred, iov,
++						file_offset, nr_segs);
++		break;
++	case WRITE:
++		dprintk("NFS: direct_IO(write) (%s) off/no(%Lu/%lu)\n",
++				dentry->d_name.name, file_offset, nr_segs);
+ 
+-	result = do_nfs_direct_IO(rw, inode, cred, iov, offset, nr_segs);
++		result = nfs_direct_write(inode, cred, iov,
++						file_offset, nr_segs);
++		break;
++	default:
++		break;
++	}
+ 
+-	dfprintk(VFS, "NFS: direct_IO result = %d\n", result);
++	if (cred)
++		put_rpccred(cred);
+ 
++out:
++	dprintk("NFS: direct_IO result=%d\n", result);
+ 	return result;
+ }
+--- linux-2.6.0-test6/fs/nfsd/nfsctl.c	2003-07-02 14:53:16.000000000 -0700
++++ 25/fs/nfsd/nfsctl.c	2003-10-05 00:33:24.000000000 -0700
+@@ -429,6 +429,7 @@ static struct file_system_type nfsd_fs_t
+ 
+ static int __init init_nfsd(void)
+ {
++	int retval;
+ 	printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
+ 
+ 	nfsd_stat_init();	/* Statistics */
+@@ -441,8 +442,16 @@ static int __init init_nfsd(void)
+ 		if (entry)
+ 			entry->proc_fops =  &exports_operations;
+ 	}
+-	register_filesystem(&nfsd_fs_type);
+-	return 0;
++	retval = register_filesystem(&nfsd_fs_type);
++	if (retval) {
++		nfsd_export_shutdown();
++		nfsd_cache_shutdown();
++		remove_proc_entry("fs/nfs/exports", NULL);
++		remove_proc_entry("fs/nfs", NULL);
++		nfsd_stat_shutdown();
++		nfsd_lockd_shutdown();
++	}
++	return retval;
+ }
+ 
+ static void __exit exit_nfsd(void)
+--- linux-2.6.0-test6/fs/nfs/file.c	2003-07-10 18:50:32.000000000 -0700
++++ 25/fs/nfs/file.c	2003-10-05 00:34:08.000000000 -0700
+@@ -262,7 +262,7 @@ out_swapfile:
+ int
+ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-	struct inode * inode = filp->f_dentry->d_inode;
++	struct inode * inode = filp->f_mapping->host;
+ 	int	status = 0;
+ 	int	status2;
+ 
+@@ -305,13 +305,13 @@ nfs_lock(struct file *filp, int cmd, str
+ 	 * Flush all pending writes before doing anything
+ 	 * with locks..
+ 	 */
+-	status = filemap_fdatawrite(inode->i_mapping);
++	status = filemap_fdatawrite(filp->f_mapping);
+ 	down(&inode->i_sem);
+ 	status2 = nfs_wb_all(inode);
+ 	if (!status)
+ 		status = status2;
+ 	up(&inode->i_sem);
+-	status2 = filemap_fdatawait(inode->i_mapping);
++	status2 = filemap_fdatawait(filp->f_mapping);
+ 	if (!status)
+ 		status = status2;
+ 	if (status < 0)
+@@ -331,11 +331,11 @@ nfs_lock(struct file *filp, int cmd, str
+ 	 */
+  out_ok:
+ 	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
+-		filemap_fdatawrite(inode->i_mapping);
++		filemap_fdatawrite(filp->f_mapping);
+ 		down(&inode->i_sem);
+ 		nfs_wb_all(inode);      /* we may have slept */
+ 		up(&inode->i_sem);
+-		filemap_fdatawait(inode->i_mapping);
++		filemap_fdatawait(filp->f_mapping);
+ 		nfs_zap_caches(inode);
+ 	}
+ 	return status;
+--- linux-2.6.0-test6/fs/nfs/nfs3proc.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/nfs/nfs3proc.c	2003-10-05 00:36:45.000000000 -0700
+@@ -225,81 +225,74 @@ nfs3_proc_readlink(struct inode *inode, 
+ }
+ 
+ static int
+-nfs3_proc_read(struct inode *inode, struct rpc_cred *cred,
+-	       struct nfs_fattr *fattr, int flags,
+-	       unsigned int base, unsigned int count, struct page *page,
+-	       int *eofp)
+-{
+-	u64			offset = page_offset(page) + base;
+-	struct nfs_readargs	arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.pgbase		= base,
+-		.pages		= &page
+-	};
+-	struct nfs_readres	res = {
+-		.fattr		= fattr,
+-		.count		= count,
+-	};
++nfs3_proc_read(struct nfs_read_data *rdata)
++{
++	int			flags = rdata->flags;
++	struct inode *		inode = rdata->inode;
++	struct nfs_fattr *	fattr = rdata->res.fattr;
+ 	struct rpc_message	msg = {
+ 		.rpc_proc	= &nfs3_procedures[NFS3PROC_READ],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred
++		.rpc_argp	= &rdata->args,
++		.rpc_resp	= &rdata->res,
++		.rpc_cred	= rdata->cred,
+ 	};
+ 	int			status;
+ 
+-	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
++			(long long) rdata->args.offset);
+ 	fattr->valid = 0;
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+ 	if (status >= 0)
+ 		nfs_refresh_inode(inode, fattr);
+ 	dprintk("NFS reply read: %d\n", status);
+-	*eofp = res.eof;
+ 	return status;
+ }
+ 
+ static int
+-nfs3_proc_write(struct inode *inode, struct rpc_cred *cred,
+-		struct nfs_fattr *fattr, int flags,
+-		unsigned int base, unsigned int count,
+-		struct page *page, struct nfs_writeverf *verf)
++nfs3_proc_write(struct nfs_write_data *wdata)
+ {
+-	u64			offset = page_offset(page) + base;
+-	struct nfs_writeargs	arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.stable		= NFS_FILE_SYNC,
+-		.pgbase		= base,
+-		.pages		= &page
+-	};
+-	struct nfs_writeres	res = {
+-		.fattr		= fattr,
+-		.verf		= verf,
+-	};
++	int			rpcflags = wdata->flags;
++	struct inode *		inode = wdata->inode;
++	struct nfs_fattr *	fattr = wdata->res.fattr;
+ 	struct rpc_message	msg = {
+ 		.rpc_proc	= &nfs3_procedures[NFS3PROC_WRITE],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred
++		.rpc_argp	= &wdata->args,
++		.rpc_resp	= &wdata->res,
++		.rpc_cred	= wdata->cred,
+ 	};
+-	int			status, rpcflags = 0;
++	int			status;
+ 
+-	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
++			(long long) wdata->args.offset);
+ 	fattr->valid = 0;
+-	if (flags & NFS_RW_SWAP)
+-		rpcflags |= NFS_RPC_SWAPFLAGS;
+-	arg.stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE;
+-
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
+-
+ 	if (status >= 0)
+ 		nfs3_write_refresh_inode(inode, fattr);
++	dprintk("NFS reply write: %d\n", status);
++	return status < 0? status : wdata->res.count;
++}
+ 
+-	dprintk("NFS reply read: %d\n", status);
+-	return status < 0? status : res.count;
++static int
++nfs3_proc_commit(struct nfs_write_data *cdata)
++{
++	struct inode *		inode = cdata->inode;
++	struct nfs_fattr *	fattr = cdata->res.fattr;
++	struct rpc_message	msg = {
++		.rpc_proc	= &nfs3_procedures[NFS3PROC_COMMIT],
++		.rpc_argp	= &cdata->args,
++		.rpc_resp	= &cdata->res,
++		.rpc_cred	= cdata->cred,
++	};
++	int			status;
++
++	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
++			(long long) cdata->args.offset);
++	fattr->valid = 0;
++	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
++	if (status >= 0)
++		nfs3_write_refresh_inode(inode, fattr);
++	dprintk("NFS reply commit: %d\n", status);
++	return status;
+ }
+ 
+ /*
+@@ -863,6 +856,7 @@ struct nfs_rpc_ops	nfs_v3_clientops = {
+ 	.readlink	= nfs3_proc_readlink,
+ 	.read		= nfs3_proc_read,
+ 	.write		= nfs3_proc_write,
++	.commit		= nfs3_proc_commit,
+ 	.create		= nfs3_proc_create,
+ 	.remove		= nfs3_proc_remove,
+ 	.unlink_setup	= nfs3_proc_unlink_setup,
+--- linux-2.6.0-test6/fs/nfs/nfs4proc.c	2003-06-26 22:07:25.000000000 -0700
++++ 25/fs/nfs/nfs4proc.c	2003-10-05 00:36:45.000000000 -0700
+@@ -1012,45 +1012,36 @@ nfs4_proc_readlink(struct inode *inode, 
+ }
+ 
+ static int
+-nfs4_proc_read(struct inode *inode, struct rpc_cred *cred,
+-	       struct nfs_fattr *fattr, int flags,
+-	       unsigned int base, unsigned int count,
+-	       struct page *page, int *eofp)
++nfs4_proc_read(struct nfs_read_data *rdata)
+ {
++	int flags = rdata->flags;
++	struct inode *inode = rdata->inode;
++	struct nfs_fattr *fattr = rdata->res.fattr;
++	nfs4_stateid *stateid = &rdata->args.stateid;
+ 	struct nfs_server *server = NFS_SERVER(inode);
+ 	struct nfs4_shareowner	*sp;
+-	uint64_t offset = page_offset(page) + base;
+-	struct nfs_readargs arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.pgbase		= base,
+-		.pages		= &page,
+-	};
+-	struct nfs_readres res = {
+-		.fattr		= fattr,
+-		.count		= count,
+-	};
+ 	struct rpc_message msg = {
+ 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_READ],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred,
++		.rpc_argp	= &rdata->args,
++		.rpc_resp	= &rdata->res,
++		.rpc_cred	= rdata->cred,
+ 	};
+ 	unsigned long timestamp = jiffies;
+ 	int status;
+ 
+-	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
++			(long long) rdata->args.offset);
++
+ 	/*
+-	* Try first to use O_RDONLY, then O_RDWR stateid.
+-	*/
++	 * Try first to use O_RDONLY, then O_RDWR stateid.
++	 */
+ 	sp = nfs4_get_inode_share(inode, O_RDONLY);
+ 	if (!sp)
+ 		sp = nfs4_get_inode_share(inode, O_RDWR);
+ 	if (sp)
+-		memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
++		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
+ 	else
+-		memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
++		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
+ 
+ 	fattr->valid = 0;
+ 	status = rpc_call_sync(server->client, &msg, flags);
+@@ -1061,56 +1052,82 @@ nfs4_proc_read(struct inode *inode, stru
+ 			nfs_zap_caches(inode);
+ 	}
+ 	dprintk("NFS reply read: %d\n", status);
+-	*eofp = res.eof;
+ 	return status;
+ }
+ 
+ static int
+-nfs4_proc_write(struct inode *inode, struct rpc_cred *cred,
+-		struct nfs_fattr *fattr, int flags,
+-		unsigned int base, unsigned int count,
+-		struct page *page, struct nfs_writeverf *verf)
++nfs4_proc_write(struct nfs_write_data *wdata)
+ {
++	int rpcflags = wdata->flags;
++	struct inode *inode = wdata->inode;
++	struct nfs_fattr *fattr = wdata->res.fattr;
++	nfs4_stateid *stateid = &wdata->args.stateid;
+ 	struct nfs_server *server = NFS_SERVER(inode);
+-	struct nfs4_shareowner	*sp;
+-	uint64_t offset = page_offset(page) + base;
+-	struct nfs_writeargs arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.stable		= (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE,
+-		.pgbase		= base,
+-		.pages		= &page,
+-	};
+-	struct nfs_writeres res = {
+-		.fattr		= fattr,
+-		.count		= count,
+-		.verf		= verf,
+-	};
++	struct nfs4_shareowner *sp;
+ 	struct rpc_message msg = {
+ 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_WRITE],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred,
++		.rpc_argp	= &wdata->args,
++		.rpc_resp	= &wdata->res,
++		.rpc_cred	= wdata->cred,
++	};
++	int status;
++
++	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
++			(long long) wdata->args.offset);
++
++	/*
++	 * Try first to use O_WRONLY, then O_RDWR stateid.
++	 */
++	sp = nfs4_get_inode_share(inode, O_WRONLY);
++	if (!sp)
++		sp = nfs4_get_inode_share(inode, O_RDWR);
++
++	if (sp)
++		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
++	else
++		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
++
++	fattr->valid = 0;
++	status = rpc_call_sync(server->client, &msg, rpcflags);
++	dprintk("NFS reply write: %d\n", status);
++	return status;
++}
++
++static int
++nfs4_proc_commit(struct nfs_write_data *cdata)
++{
++	struct inode *inode = cdata->inode;
++	struct nfs_fattr *fattr = cdata->res.fattr;
++	nfs4_stateid *stateid = &cdata->args.stateid;
++	struct nfs_server *server = NFS_SERVER(inode);
++	struct nfs4_shareowner *sp;
++	struct rpc_message msg = {
++		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
++		.rpc_argp	= &cdata->args,
++		.rpc_resp	= &cdata->res,
++		.rpc_cred	= cdata->cred,
+ 	};
+-	int			rpcflags = (flags & NFS_RW_SWAP) ? NFS_RPC_SWAPFLAGS : 0;
++	int status;
+ 
+-	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
++			(long long) cdata->args.offset);
+ 
+ 	/*
+-	* Try first to use O_WRONLY, then O_RDWR stateid.
+-	*/
++	 * Try first to use O_WRONLY, then O_RDWR stateid.
++	 */
+ 	sp = nfs4_get_inode_share(inode, O_WRONLY);
+ 	if (!sp)
+ 		sp = nfs4_get_inode_share(inode, O_RDWR);
+ 
+ 	if (sp)
+-		memcpy(arg.stateid,sp->so_stateid, sizeof(nfs4_stateid));
++		memcpy(stateid, sp->so_stateid, sizeof(nfs4_stateid));
+ 	else
+-		memcpy(arg.stateid, zero_stateid, sizeof(nfs4_stateid));
++		memcpy(stateid, zero_stateid, sizeof(nfs4_stateid));
+ 
+ 	fattr->valid = 0;
+-	return rpc_call_sync(server->client, &msg, rpcflags);
++	status = rpc_call_sync(server->client, &msg, 0);
++	dprintk("NFS reply commit: %d\n", status);
++	return status;
+ }
+ 
+ /*
+@@ -1752,7 +1769,7 @@ struct nfs_rpc_ops	nfs_v4_clientops = {
+ 	.readlink	= nfs4_proc_readlink,
+ 	.read		= nfs4_proc_read,
+ 	.write		= nfs4_proc_write,
+-	.commit		= NULL,
++	.commit		= nfs4_proc_commit,
+ 	.create		= nfs4_proc_create,
+ 	.remove		= nfs4_proc_remove,
+ 	.unlink_setup	= nfs4_proc_unlink_setup,
+--- linux-2.6.0-test6/fs/nfs/pagelist.c	2003-06-26 22:07:25.000000000 -0700
++++ 25/fs/nfs/pagelist.c	2003-10-05 00:36:43.000000000 -0700
+@@ -154,26 +154,6 @@ nfs_release_request(struct nfs_page *req
+ }
+ 
+ /**
+- * nfs_release_list - cleanly dispose of an unattached list of page requests
+- * @list: list of doomed page requests
+- */
+-void
+-nfs_release_list(struct list_head *list)
+-{
+-	while (!list_empty(list)) {
+-		struct nfs_page *req = nfs_list_entry(list);
+-
+-		nfs_list_remove_request(req);
+-
+-		page_cache_release(req->wb_page);
+-
+-		/* Release struct file or cached credential */
+-		nfs_clear_request(req);
+-		nfs_page_free(req);
+-	}
+-}
+-
+-/**
+  * nfs_list_add_request - Insert a request into a sorted list
+  * @req: request
+  * @head: head of list into which to insert the request.
+@@ -222,37 +202,6 @@ nfs_wait_on_request(struct nfs_page *req
+ }
+ 
+ /**
+- * nfs_wait_for_reads - wait for outstanding requests to complete
+- * @head: list of page requests to wait for
+- */
+-int
+-nfs_wait_for_reads(struct list_head *head)
+-{
+-	struct list_head *p = head->next;
+-	unsigned int res = 0;
+-
+-	while (p != head) {
+-		struct nfs_page *req = nfs_list_entry(p);
+-		int error;
+-
+-		if (!NFS_WBACK_BUSY(req))
+-			continue;
+-
+-		req->wb_count++;
+-		error = nfs_wait_on_request(req);
+-		if (error < 0)
+-			return error;
+-		nfs_list_remove_request(req);
+-		nfs_clear_request(req);
+-		nfs_page_free(req);
+-
+-		p = head->next;
+-		res++;
+-	}
+-	return res;
+-}
+-
+-/**
+  * nfs_coalesce_requests - Split coalesced requests out from a list.
+  * @head: source list
+  * @dst: destination list
+--- linux-2.6.0-test6/fs/nfs/proc.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/nfs/proc.c	2003-10-05 00:36:44.000000000 -0700
+@@ -149,82 +149,62 @@ nfs_proc_readlink(struct inode *inode, s
+ }
+ 
+ static int
+-nfs_proc_read(struct inode *inode, struct rpc_cred *cred,
+-	      struct nfs_fattr *fattr, int flags,
+-	      unsigned int base, unsigned int count, struct page *page,
+-	      int *eofp)
+-{
+-	u64			offset = page_offset(page) + base;
+-	struct nfs_readargs	arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.pgbase		= base,
+-		.pages		= &page
+-	};
+-	struct nfs_readres	res = {
+-		.fattr		= fattr,
+-		.count		= count
+-	};
++nfs_proc_read(struct nfs_read_data *rdata)
++{
++	int			flags = rdata->flags;
++	struct inode *		inode = rdata->inode;
++	struct nfs_fattr *	fattr = rdata->res.fattr;
+ 	struct rpc_message	msg = {
+ 		.rpc_proc	= &nfs_procedures[NFSPROC_READ],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred
++		.rpc_argp	= &rdata->args,
++		.rpc_resp	= &rdata->res,
++		.rpc_cred	= rdata->cred,
+ 	};
+ 	int			status;
+ 
+-	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
++			(long long) rdata->args.offset);
+ 	fattr->valid = 0;
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+-
+-	if (status >= 0)
++	if (status >= 0) {
+ 		nfs_refresh_inode(inode, fattr);
++		/* NFSv2 reads don't return an eof flag, so we make
++		 * up a value here.  XDR has already set eof to 0. */
++		if (status < rdata->args.count)
++			rdata->res.eof = 1;
++	}
+ 	dprintk("NFS reply read: %d\n", status);
+-	*eofp = res.eof;
+ 	return status;
+ }
+ 
+ static int
+-nfs_proc_write(struct inode *inode, struct rpc_cred *cred,
+-	       struct nfs_fattr *fattr, int how,
+-	       unsigned int base, unsigned int count,
+-	       struct page *page, struct nfs_writeverf *verf)
++nfs_proc_write(struct nfs_write_data *wdata)
+ {
+-	u64			offset = page_offset(page) + base;
+-	struct nfs_writeargs	arg = {
+-		.fh		= NFS_FH(inode),
+-		.offset		= offset,
+-		.count		= count,
+-		.stable		= NFS_FILE_SYNC,
+-		.pgbase		= base,
+-		.pages		= &page
+-	};
+-	struct nfs_writeres     res = {
+-		.fattr		= fattr,
+-		.verf		= verf,
+-		.count		= count
+-	};
++	int			flags = wdata->flags;
++	struct inode *		inode = wdata->inode;
++	struct nfs_fattr *	fattr = wdata->res.fattr;
+ 	struct rpc_message	msg = {
+ 		.rpc_proc	= &nfs_procedures[NFSPROC_WRITE],
+-		.rpc_argp	= &arg,
+-		.rpc_resp	= &res,
+-		.rpc_cred	= cred
++		.rpc_argp	= &wdata->args,
++		.rpc_resp	= &wdata->res,
++		.rpc_cred	= wdata->cred
+ 	};
+-	int			status, flags = 0;
++	int			status;
+ 
+-	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
++	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
++			(long long) wdata->args.offset);
+ 	fattr->valid = 0;
+-	if (how & NFS_RW_SWAP)
+-		flags |= NFS_RPC_SWAPFLAGS;
+ 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
+-
+-	if (status >= 0)
++	if (status >= 0) {
+ 		nfs_write_refresh_inode(inode, fattr);
+-
++		/* NFSv2 writes don't return a byte count or write
++		 * verifier, so we make up values here.  Note that
++		 * v2 writes are always NFS_FILE_SYNC writes. */
++		wdata->res.count = wdata->args.count;
++		wdata->verf.committed = NFS_FILE_SYNC;
++	}
+ 	dprintk("NFS reply write: %d\n", status);
+-	verf->committed = NFS_FILE_SYNC;      /* NFSv2 always syncs data */
+-	return status < 0? status : count;
++	return status < 0? status : wdata->res.count;
+ }
+ 
+ static int
+--- linux-2.6.0-test6/fs/nfs/read.c	2003-06-26 22:07:25.000000000 -0700
++++ 25/fs/nfs/read.c	2003-10-05 00:36:44.000000000 -0700
+@@ -69,19 +69,28 @@ void nfs_readdata_release(struct rpc_tas
+ static int
+ nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
+ {
+-	struct rpc_cred	*cred = NULL;
+-	struct nfs_fattr fattr;
+-	unsigned int	offset = 0;
+ 	unsigned int	rsize = NFS_SERVER(inode)->rsize;
+ 	unsigned int	count = PAGE_CACHE_SIZE;
+ 	int		result;
+-	int		flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0;
+-	int		eof;
++	struct nfs_read_data	rdata = {
++		.flags		= (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0),
++		.cred		= NULL,
++		.inode		= inode,
++		.args		= {
++			.fh		= NFS_FH(inode),
++			.pages		= &page,
++			.pgbase		= 0UL,
++			.count		= rsize,
++		},
++		.res		= {
++			.fattr		= &rdata.fattr,
++		}
++	};
+ 
+ 	dprintk("NFS: nfs_readpage_sync(%p)\n", page);
+ 
+ 	if (file)
+-		cred = nfs_file_cred(file);
++		rdata.cred = nfs_file_cred(file);
+ 
+ 	/*
+ 	 * This works now because the socket layer never tries to DMA
+@@ -89,17 +98,19 @@ nfs_readpage_sync(struct file *file, str
+ 	 */
+ 	do {
+ 		if (count < rsize)
+-			rsize = count;
++			rdata.args.count = count;
++		rdata.res.count = rdata.args.count;
++		rdata.args.offset = page_offset(page) + rdata.args.pgbase;
+ 
+ 		dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
+ 			NFS_SERVER(inode)->hostname,
+ 			inode->i_sb->s_id,
+ 			(long long)NFS_FILEID(inode),
+-			(unsigned long long)offset, rsize);
++			(unsigned long long)rdata.args.pgbase,
++			rdata.args.count);
+ 
+ 		lock_kernel();
+-		result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
+-						offset, rsize, page, &eof);
++		result = NFS_PROTO(inode)->read(&rdata);
+ 		unlock_kernel();
+ 
+ 		/*
+@@ -111,14 +122,15 @@ nfs_readpage_sync(struct file *file, str
+ 				result = -EINVAL;
+ 			goto io_error;
+ 		}
+-		count  -= result;
+-		offset += result;
+-		if (result < rsize)	/* NFSv2ism */
++		count -= result;
++		rdata.args.pgbase += result;
++
++		if (rdata.res.eof)
+ 			break;
+ 	} while (count);
+ 
+ 	if (count)
+-		memclear_highpage_flush(page, offset, count);
++		memclear_highpage_flush(page, rdata.args.pgbase, count);
+ 	SetPageUptodate(page);
+ 	if (PageError(page))
+ 		ClearPageError(page);
+--- linux-2.6.0-test6/fs/nfs/write.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/nfs/write.c	2003-10-05 00:36:44.000000000 -0700
+@@ -132,66 +132,73 @@ static int
+ nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
+ 		   unsigned int offset, unsigned int count)
+ {
+-	struct rpc_cred	*cred = NULL;
+-	loff_t		base;
+ 	unsigned int	wsize = NFS_SERVER(inode)->wsize;
+-	int		result, refresh = 0, written = 0, flags;
+-	u8		*buffer;
+-	struct nfs_fattr fattr;
+-	struct nfs_writeverf verf;
+-
++	int		result, written = 0;
++	int		swapfile = IS_SWAPFILE(inode);
++	struct nfs_write_data	wdata = {
++		.flags		= swapfile ? NFS_RPC_SWAPFLAGS : 0,
++		.cred		= NULL,
++		.inode		= inode,
++		.args		= {
++			.fh		= NFS_FH(inode),
++			.pages		= &page,
++			.stable		= NFS_FILE_SYNC,
++			.pgbase		= offset,
++			.count		= wsize,
++		},
++		.res		= {
++			.fattr		= &wdata.fattr,
++			.verf		= &wdata.verf,
++		},
++	};
+ 
+ 	if (file)
+-		cred = get_rpccred(nfs_file_cred(file));
+-	if (!cred)
+-		cred = get_rpccred(NFS_I(inode)->mm_cred);
++		wdata.cred = get_rpccred(nfs_file_cred(file));
++	if (!wdata.cred)
++		wdata.cred = get_rpccred(NFS_I(inode)->mm_cred);
+ 
+ 	dprintk("NFS:      nfs_writepage_sync(%s/%Ld %d@%Ld)\n",
+ 		inode->i_sb->s_id,
+ 		(long long)NFS_FILEID(inode),
+ 		count, (long long)(page_offset(page) + offset));
+ 
+-	base = page_offset(page) + offset;
+-
+-	flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC;
+-
+ 	do {
+-		if (count < wsize && !IS_SWAPFILE(inode))
+-			wsize = count;
++		if (count < wsize && !swapfile)
++			wdata.args.count = count;
++		wdata.args.offset = page_offset(page) + wdata.args.pgbase;
+ 
+-		result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags,
+-						 offset, wsize, page, &verf);
++		result = NFS_PROTO(inode)->write(&wdata);
+ 
+ 		if (result < 0) {
+ 			/* Must mark the page invalid after I/O error */
+ 			ClearPageUptodate(page);
+ 			goto io_error;
+ 		}
+-		if (result != wsize)
+-			printk("NFS: short write, wsize=%u, result=%d\n",
+-			wsize, result);
+-		refresh = 1;
+-		buffer  += wsize;
+-		base    += wsize;
+-	        offset  += wsize;
+-		written += wsize;
+-		count   -= wsize;
++		if (result < wdata.args.count)
++			printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n",
++					wdata.args.count, result);
++
++		wdata.args.offset += result;
++	        wdata.args.pgbase += result;
++		written += result;
++		count -= result;
++
+ 		/*
+ 		 * If we've extended the file, update the inode
+ 		 * now so we don't invalidate the cache.
+ 		 */
+-		if (base > i_size_read(inode))
+-			i_size_write(inode, base);
++		if (wdata.args.offset > i_size_read(inode))
++			i_size_write(inode, wdata.args.offset);
+ 	} while (count);
+ 
+ 	if (PageError(page))
+ 		ClearPageError(page);
+ 
+ io_error:
+-	if (cred)
+-		put_rpccred(cred);
++	if (wdata.cred)
++		put_rpccred(wdata.cred);
+ 
+-	return written? written : result;
++	return written ? written : result;
+ }
+ 
+ static int
+--- linux-2.6.0-test6/fs/open.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/open.c	2003-10-05 00:36:52.000000000 -0700
+@@ -190,7 +190,9 @@ int do_truncate(struct dentry *dentry, l
+ 	newattrs.ia_size = length;
+ 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ 	down(&dentry->d_inode->i_sem);
++	down_write(&dentry->d_inode->i_alloc_sem);
+ 	err = notify_change(dentry, &newattrs);
++	up_write(&dentry->d_inode->i_alloc_sem);
+ 	up(&dentry->d_inode->i_sem);
+ 	return err;
+ }
+@@ -772,7 +774,8 @@ struct file *dentry_open(struct dentry *
+ 			goto cleanup_file;
+ 	}
+ 
+-	file_ra_state_init(&f->f_ra, inode->i_mapping);
++	f->f_mapping = inode->i_mapping;
++	file_ra_state_init(&f->f_ra, f->f_mapping);
+ 	f->f_dentry = dentry;
+ 	f->f_vfsmnt = mnt;
+ 	f->f_pos = 0;
+@@ -788,8 +791,8 @@ struct file *dentry_open(struct dentry *
+ 
+ 	/* NB: we're sure to have correct a_ops only after f_op->open */
+ 	if (f->f_flags & O_DIRECT) {
+-		if (!inode->i_mapping || !inode->i_mapping->a_ops ||
+-			!inode->i_mapping->a_ops->direct_IO) {
++		if (!f->f_mapping || !f->f_mapping->a_ops ||
++			!f->f_mapping->a_ops->direct_IO) {
+ 				fput(f);
+ 				f = ERR_PTR(-EINVAL);
+ 		}
+@@ -1019,7 +1022,7 @@ out_unlock:
+ asmlinkage long sys_vhangup(void)
+ {
+ 	if (capable(CAP_SYS_TTY_CONFIG)) {
+-		tty_vhangup(current->tty);
++		tty_vhangup(process_tty(current));
+ 		return 0;
+ 	}
+ 	return -EPERM;
+--- linux-2.6.0-test6/fs/pipe.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/pipe.c	2003-10-05 00:34:03.000000000 -0700
+@@ -580,6 +580,7 @@ int do_pipe(int *fd)
+ 	d_add(dentry, inode);
+ 	f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
+ 	f1->f_dentry = f2->f_dentry = dget(dentry);
++	f1->f_mapping = f2->f_mapping = inode->i_mapping;
+ 
+ 	/* read file */
+ 	f1->f_pos = f2->f_pos = 0;
+--- linux-2.6.0-test6/fs/proc/array.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/proc/array.c	2003-10-05 00:36:15.000000000 -0700
+@@ -304,9 +304,9 @@ int proc_pid_stat(struct task_struct *ta
+ 	mm = task->mm;
+ 	if(mm)
+ 		mm = mmgrab(mm);
+-	if (task->tty) {
+-		tty_pgrp = task->tty->pgrp;
+-		tty_nr = new_encode_dev(tty_devnum(task->tty));
++	if (process_tty(task)) {
++		tty_pgrp = process_tty(task)->pgrp;
++		tty_nr = new_encode_dev(tty_devnum(process_tty(task)));
+ 	}
+ 	task_unlock(task);
+ 	if (mm) {
+@@ -345,7 +345,7 @@ int proc_pid_stat(struct task_struct *ta
+ 		state,
+ 		ppid,
+ 		process_group(task),
+-		task->session,
++		process_session(task),
+ 		tty_nr,
+ 		tty_pgrp,
+ 		task->flags,
+--- linux-2.6.0-test6/fs/proc/base.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/proc/base.c	2003-10-05 00:36:09.000000000 -0700
+@@ -53,6 +53,7 @@ enum pid_directory_inos {
+ 	PROC_TGID_EXE,
+ 	PROC_TGID_FD,
+ 	PROC_TGID_ENVIRON,
++	PROC_TGID_AUXV,
+ 	PROC_TGID_CMDLINE,
+ 	PROC_TGID_STAT,
+ 	PROC_TGID_STATM,
+@@ -75,6 +76,7 @@ enum pid_directory_inos {
+ 	PROC_TID_EXE,
+ 	PROC_TID_FD,
+ 	PROC_TID_ENVIRON,
++	PROC_TID_AUXV,
+ 	PROC_TID_CMDLINE,
+ 	PROC_TID_STAT,
+ 	PROC_TID_STATM,
+@@ -104,6 +106,7 @@ static struct pid_entry tgid_base_stuff[
+ 	E(PROC_TGID_TASK,      "task",    S_IFDIR|S_IRUGO|S_IXUGO),
+ 	E(PROC_TGID_FD,        "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
+ 	E(PROC_TGID_ENVIRON,   "environ", S_IFREG|S_IRUSR),
++	E(PROC_TGID_AUXV,      "auxv",	  S_IFREG|S_IRUSR),
+ 	E(PROC_TGID_STATUS,    "status",  S_IFREG|S_IRUGO),
+ 	E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
+ 	E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
+@@ -125,6 +128,7 @@ static struct pid_entry tgid_base_stuff[
+ static struct pid_entry tid_base_stuff[] = {
+ 	E(PROC_TID_FD,         "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
+ 	E(PROC_TID_ENVIRON,    "environ", S_IFREG|S_IRUSR),
++	E(PROC_TID_AUXV,       "auxv",	  S_IFREG|S_IRUSR),
+ 	E(PROC_TID_STATUS,     "status",  S_IFREG|S_IRUGO),
+ 	E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
+ 	E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
+@@ -322,6 +326,25 @@ out:
+ 	return res;
+ }
+ 
++static int proc_pid_auxv(struct task_struct *task, char *buffer)
++{
++	int res = 0;
++	struct mm_struct *mm = get_task_mm(task);
++	if (mm) {
++		unsigned int nwords = 0;
++		do
++			nwords += 2;
++		while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
++		res = nwords * sizeof(mm->saved_auxv[0]);
++		if (res > PAGE_SIZE)
++			res = PAGE_SIZE;
++		memcpy(buffer, mm->saved_auxv, res);
++		mmput(mm);
++	}
++	return res;
++}
++
++
+ #ifdef CONFIG_KALLSYMS
+ /*
+  * Provides a wchan file via kallsyms in a proper one-value-per-file format.
+@@ -1271,6 +1294,11 @@ static struct dentry *proc_pident_lookup
+ 			inode->i_fop = &proc_info_file_operations;
+ 			ei->op.proc_read = proc_pid_environ;
+ 			break;
++		case PROC_TID_AUXV:
++		case PROC_TGID_AUXV:
++			inode->i_fop = &proc_info_file_operations;
++			ei->op.proc_read = proc_pid_auxv;
++			break;
+ 		case PROC_TID_STATUS:
+ 		case PROC_TGID_STATUS:
+ 			inode->i_fop = &proc_info_file_operations;
+--- linux-2.6.0-test6/fs/proc/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/proc/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -14,6 +14,7 @@
+ #include <linux/limits.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ 
+ #include <asm/system.h>
+@@ -135,34 +136,47 @@ static struct super_operations proc_sops
+ 	.statfs		= simple_statfs,
+ };
+ 
++enum {
++	Opt_uid, Opt_gid, Opt_err
++};
++
++static match_table_t tokens = {
++	{Opt_uid, "uid=%u"},
++	{Opt_gid, "gid=%u"},
++	{Opt_err, NULL}
++};
++
+ static int parse_options(char *options,uid_t *uid,gid_t *gid)
+ {
+-	char *this_char,*value;
++	char *p;
++	int option;
+ 
+ 	*uid = current->uid;
+ 	*gid = current->gid;
+ 	if (!options)
+ 		return 1;
+-	while ((this_char = strsep(&options,",")) != NULL) {
+-		if (!*this_char)
++
++	while ((p = strsep(&options, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr(this_char,'=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp(this_char,"uid")) {
+-			if (!value || !*value)
+-				return 0;
+-			*uid = simple_strtoul(value,&value,0);
+-			if (*value)
+-				return 0;
+-		}
+-		else if (!strcmp(this_char,"gid")) {
+-			if (!value || !*value)
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_uid:
++			if (match_int(args, &option))
+ 				return 0;
+-			*gid = simple_strtoul(value,&value,0);
+-			if (*value)
++			*uid = option;
++			break;
++		case Opt_gid:
++			if (match_int(args, &option))
+ 				return 0;
++			*gid = option;
++			break;
++		default:
++			return 0;
+ 		}
+-		else return 1;
+ 	}
+ 	return 1;
+ }
+--- linux-2.6.0-test6/fs/proc/proc_misc.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/proc/proc_misc.c	2003-10-05 00:36:40.000000000 -0700
+@@ -638,6 +638,36 @@ static void create_seq_entry(char *name,
+ 		entry->proc_fops = f;
+ }
+ 
++#ifdef CONFIG_LOCKMETER
++extern ssize_t get_lockmeter_info(char *, size_t, loff_t *);
++extern ssize_t put_lockmeter_info(const char *, size_t);
++extern int get_lockmeter_info_size(void);
++
++/*
++ * This function accesses lock metering information.
++ */
++static ssize_t read_lockmeter(struct file *file, char *buf,
++			      size_t count, loff_t *ppos)
++{
++	return get_lockmeter_info(buf, count, ppos);
++}
++
++/*
++ * Writing to /proc/lockmeter resets the counters
++ */
++static ssize_t write_lockmeter(struct file * file, const char * buf,
++			       size_t count, loff_t *ppos)
++{
++	return put_lockmeter_info(buf, count);
++}
++
++static struct file_operations proc_lockmeter_operations = {
++	NULL,           /* lseek */
++	read:		read_lockmeter,
++	write:		write_lockmeter,
++};
++#endif  /* CONFIG_LOCKMETER */
++
+ void __init proc_misc_init(void)
+ {
+ 	struct proc_dir_entry *entry;
+@@ -705,6 +735,13 @@ void __init proc_misc_init(void)
+ 	if (entry)
+ 		entry->proc_fops = &proc_sysrq_trigger_operations;
+ #endif
++#ifdef CONFIG_LOCKMETER
++	entry = create_proc_entry("lockmeter", S_IWUSR | S_IRUGO, NULL);
++	if (entry) {
++		entry->proc_fops = &proc_lockmeter_operations;
++		entry->size = get_lockmeter_info_size();
++	}
++#endif
+ #ifdef CONFIG_PPC32
+ 	{
+ 		extern struct file_operations ppc_htab_operations;
+--- linux-2.6.0-test6/fs/read_write.c	2003-07-13 21:44:35.000000000 -0700
++++ 25/fs/read_write.c	2003-10-05 00:34:07.000000000 -0700
+@@ -26,7 +26,7 @@ struct file_operations generic_ro_fops =
+ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
+ {
+ 	long long retval;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode *inode = file->f_mapping->host;
+ 
+ 	down(&inode->i_sem);
+ 	switch (origin) {
+--- linux-2.6.0-test6/fs/reiserfs/file.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/reiserfs/file.c	2003-10-05 00:34:11.000000000 -0700
+@@ -1052,7 +1052,7 @@ ssize_t reiserfs_file_write( struct file
+     /* Check if we can write to specified region of file, file
+        is not overly big and this kind of stuff. Adjust pos and
+        count, if needed */
+-    res = generic_write_checks(inode, file, &pos, &count, 0);
++    res = generic_write_checks(file, &pos, &count, 0);
+     if (res)
+ 	goto out;
+ 
+@@ -1179,7 +1179,7 @@ ssize_t reiserfs_file_write( struct file
+     }
+ 
+     if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+-	res = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
++	res = generic_osync_inode(inode, file->f_mapping, OSYNC_METADATA|OSYNC_DATA);
+ 
+     up(&inode->i_sem);
+     return (already_written != 0)?already_written:res;
+--- linux-2.6.0-test6/fs/reiserfs/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/reiserfs/inode.c	2003-10-05 00:34:07.000000000 -0700
+@@ -2375,7 +2375,7 @@ static int reiserfs_direct_IO(int rw, st
+ 			      loff_t offset, unsigned long nr_segs)
+ {
+     struct file *file = iocb->ki_filp;
+-    struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++    struct inode *inode = file->f_mapping->host;
+ 
+     return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ 			      offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
+--- linux-2.6.0-test6/fs/reiserfs/journal.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/reiserfs/journal.c	2003-10-05 00:34:11.000000000 -0700
+@@ -1937,18 +1937,13 @@ static int journal_init_dev( struct supe
+ 
+ 	journal -> j_dev_file = filp_open( jdev_name, 0, 0 );
+ 	if( !IS_ERR( journal -> j_dev_file ) ) {
+-		struct inode *jdev_inode;
+-
+-		jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode;
+-		journal -> j_dev_bd = jdev_inode -> i_bdev;
++		struct inode *jdev_inode = journal->j_dev_file->f_mapping->host;
+ 		if( !S_ISBLK( jdev_inode -> i_mode ) ) {
+ 			printk( "journal_init_dev: '%s' is not a block device\n", jdev_name );
+ 			result = -ENOTBLK;
+-		} else if( jdev_inode -> i_bdev == NULL ) {
+-			printk( "journal_init_dev: bdev uninitialized for '%s'\n", jdev_name );
+-			result = -ENOMEM;
+ 		} else  {
+ 			/* ok */
++			journal->j_dev_bd = I_BDEV(jdev_inode);
+ 			set_blocksize(journal->j_dev_bd, super->s_blocksize);
+ 		}
+ 	} else {
+--- linux-2.6.0-test6/fs/seq_file.c	2003-06-14 12:18:28.000000000 -0700
++++ 25/fs/seq_file.c	2003-10-05 00:33:24.000000000 -0700
+@@ -6,6 +6,7 @@
+  */
+ 
+ #include <linux/fs.h>
++#include <linux/module.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
+ 
+@@ -37,6 +38,8 @@ int seq_open(struct file *file, struct s
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(seq_open);
++
+ /**
+  *	seq_read -	->read() method for sequential files.
+  *	@file, @buf, @size, @ppos: see file_operations method
+@@ -144,6 +147,8 @@ Efault:
+ 	goto Done;
+ }
+ 
++EXPORT_SYMBOL(seq_read);
++
+ static int traverse(struct seq_file *m, loff_t offset)
+ {
+ 	loff_t pos = 0;
+@@ -228,6 +233,8 @@ loff_t seq_lseek(struct file *file, loff
+ 	return retval;
+ }
+ 
++EXPORT_SYMBOL(seq_lseek);
++
+ /**
+  *	seq_release -	free the structures associated with sequential file.
+  *	@file: file in question
+@@ -244,6 +251,8 @@ int seq_release(struct inode *inode, str
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(seq_release);
++
+ /**
+  *	seq_escape -	print string into buffer, escaping some characters
+  *	@m:	target buffer
+@@ -279,6 +288,8 @@ int seq_escape(struct seq_file *m, const
+         return 0;
+ }
+ 
++EXPORT_SYMBOL(seq_escape);
++
+ int seq_printf(struct seq_file *m, const char *f, ...)
+ {
+ 	va_list args;
+@@ -297,9 +308,11 @@ int seq_printf(struct seq_file *m, const
+ 	return -1;
+ }
+ 
++EXPORT_SYMBOL(seq_printf);
++
+ int seq_path(struct seq_file *m,
+-		struct vfsmount *mnt, struct dentry *dentry,
+-		char *esc)
++	     struct vfsmount *mnt, struct dentry *dentry,
++	     char *esc)
+ {
+ 	if (m->count < m->size) {
+ 		char *s = m->buf + m->count;
+@@ -328,6 +341,8 @@ int seq_path(struct seq_file *m,
+ 	return -1;
+ }
+ 
++EXPORT_SYMBOL(seq_path);
++
+ static void *single_start(struct seq_file *p, loff_t *pos)
+ {
+ 	return NULL + (*pos == 0);
+@@ -343,7 +358,8 @@ static void single_stop(struct seq_file 
+ {
+ }
+ 
+-int single_open(struct file *file, int (*show)(struct seq_file *, void*), void *data)
++int single_open(struct file *file, int (*show)(struct seq_file *, void *),
++		void *data)
+ {
+ 	struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL);
+ 	int res = -ENOMEM;
+@@ -362,6 +378,8 @@ int single_open(struct file *file, int (
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(single_open);
++
+ int single_release(struct inode *inode, struct file *file)
+ {
+ 	struct seq_operations *op = ((struct seq_file *)file->private_data)->op;
+@@ -370,6 +388,8 @@ int single_release(struct inode *inode, 
+ 	return res;
+ }
+ 
++EXPORT_SYMBOL(single_release);
++
+ int seq_release_private(struct inode *inode, struct file *file)
+ {
+ 	struct seq_file *seq = file->private_data;
+@@ -379,3 +399,4 @@ int seq_release_private(struct inode *in
+ 	return seq_release(inode, file);
+ }
+ 
++EXPORT_SYMBOL(seq_release_private);
+--- linux-2.6.0-test6/fs/smbfs/inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/smbfs/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -551,8 +551,8 @@ int smb_fill_super(struct super_block *s
+ 	if (ver == SMB_MOUNT_OLDVERSION) {
+ 		mnt->version = oldmnt->version;
+ 
+-		mnt->uid = low2highuid(oldmnt->uid);
+-		mnt->gid = low2highuid(oldmnt->gid);
++		mnt->uid = OLD_TO_NEW_UID(oldmnt->uid);
++		mnt->gid = OLD_TO_NEW_GID(oldmnt->gid);
+ 
+ 		mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
+ 		mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
+--- linux-2.6.0-test6/fs/super.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/super.c	2003-10-05 00:36:10.000000000 -0700
+@@ -21,6 +21,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/smp_lock.h>
+ #include <linux/acct.h>
+@@ -134,9 +135,11 @@ void deactivate_super(struct super_block
+ 	}
+ }
+ 
++EXPORT_SYMBOL(deactivate_super);
++
+ /**
+- *	grab_super	- acquire an active reference
+- *	@s	- reference we are trying to make active
++ *	grab_super - acquire an active reference
++ *	@s: reference we are trying to make active
+  *
+  *	Tries to acquire an active reference.  grab_super() is used when we
+  * 	had just found a superblock in super_blocks or fs_type->fs_supers
+@@ -214,6 +217,8 @@ void generic_shutdown_super(struct super
+ 	up_write(&sb->s_umount);
+ }
+ 
++EXPORT_SYMBOL(generic_shutdown_super);
++
+ /**
+  *	sget	-	find or create a superblock
+  *	@type:	filesystem type superblock should belong to
+@@ -226,13 +231,10 @@ struct super_block *sget(struct file_sys
+ 			int (*set)(struct super_block *,void *),
+ 			void *data)
+ {
+-	struct super_block *s = alloc_super();
++	struct super_block *s = NULL;
+ 	struct list_head *p;
+ 	int err;
+ 
+-	if (!s)
+-		return ERR_PTR(-ENOMEM);
+-
+ retry:
+ 	spin_lock(&sb_lock);
+ 	if (test) list_for_each(p, &type->fs_supers) {
+@@ -242,9 +244,18 @@ retry:
+ 			continue;
+ 		if (!grab_super(old))
+ 			goto retry;
+-		destroy_super(s);
++		if (s)
++			destroy_super(s);
+ 		return old;
+ 	}
++	if (!s) {
++		spin_unlock(&sb_lock);
++		s = alloc_super();
++		if (!s)
++			return ERR_PTR(-ENOMEM);
++		goto retry;
++	}
++		
+ 	err = set(s, data);
+ 	if (err) {
+ 		spin_unlock(&sb_lock);
+@@ -259,12 +270,16 @@ retry:
+ 	return s;
+ }
+ 
++EXPORT_SYMBOL(sget);
++
+ void drop_super(struct super_block *sb)
+ {
+ 	up_read(&sb->s_umount);
+ 	put_super(sb);
+ }
+ 
++EXPORT_SYMBOL(drop_super);
++
+ static inline void write_super(struct super_block *sb)
+ {
+ 	lock_super(sb);
+@@ -353,8 +368,8 @@ restart:
+ }
+ 
+ /**
+- *	get_super	-	get the superblock of a device
+- *	@dev: device to get the superblock for
++ *	get_super - get the superblock of a device
++ *	@bdev: device to get the superblock for
+  *	
+  *	Scans the superblock list and finds the superblock of the file system
+  *	mounted on the device given. %NULL is returned if no match is found.
+@@ -382,6 +397,8 @@ rescan:
+ 	spin_unlock(&sb_lock);
+ 	return NULL;
+ }
++
++EXPORT_SYMBOL(get_super);
+  
+ struct super_block * user_get_super(dev_t dev)
+ {
+@@ -405,6 +422,8 @@ rescan:
+ 	return NULL;
+ }
+ 
++EXPORT_SYMBOL(user_get_super);
++
+ asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
+ {
+         struct super_block *s;
+@@ -442,10 +461,11 @@ static void mark_files_ro(struct super_b
+ }
+ 
+ /**
+- *	do_remount_sb	-	asks filesystem to change mount options.
++ *	do_remount_sb - asks filesystem to change mount options.
+  *	@sb:	superblock in question
+  *	@flags:	numeric part of options
+  *	@data:	the rest of options
++ *      @force: whether or not to force the change
+  *
+  *	Alters the mount options of a mounted file system.
+  */
+@@ -534,6 +554,8 @@ int set_anon_super(struct super_block *s
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL(set_anon_super);
++
+ void kill_anon_super(struct super_block *sb)
+ {
+ 	int slot = MINOR(sb->s_dev);
+@@ -543,6 +565,8 @@ void kill_anon_super(struct super_block 
+ 	spin_unlock(&unnamed_dev_lock);
+ }
+ 
++EXPORT_SYMBOL(kill_anon_super);
++
+ void kill_litter_super(struct super_block *sb)
+ {
+ 	if (sb->s_root)
+@@ -550,6 +574,8 @@ void kill_litter_super(struct super_bloc
+ 	kill_anon_super(sb);
+ }
+ 
++EXPORT_SYMBOL(kill_litter_super);
++
+ static int set_bdev_super(struct super_block *s, void *data)
+ {
+ 	s->s_bdev = data;
+@@ -608,6 +634,8 @@ out:
+ 	return s;
+ }
+ 
++EXPORT_SYMBOL(get_sb_bdev);
++
+ void kill_block_super(struct super_block *sb)
+ {
+ 	struct block_device *bdev = sb->s_bdev;
+@@ -616,6 +644,8 @@ void kill_block_super(struct super_block
+ 	close_bdev_excl(bdev, BDEV_FS);
+ }
+ 
++EXPORT_SYMBOL(kill_block_super);
++
+ struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+ 	int flags, void *data,
+ 	int (*fill_super)(struct super_block *, void *, int))
+@@ -638,6 +668,8 @@ struct super_block *get_sb_nodev(struct 
+ 	return s;
+ }
+ 
++EXPORT_SYMBOL(get_sb_nodev);
++
+ static int compare_single(struct super_block *s, void *p)
+ {
+ 	return 1;
+@@ -667,6 +699,8 @@ struct super_block *get_sb_single(struct
+ 	return s;
+ }
+ 
++EXPORT_SYMBOL(get_sb_single);
++
+ struct vfsmount *
+ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
+ {
+@@ -709,3 +743,5 @@ struct vfsmount *kern_mount(struct file_
+ {
+ 	return do_kern_mount(type->name, 0, type->name, NULL);
+ }
++
++EXPORT_SYMBOL(kern_mount);
+--- linux-2.6.0-test6/fs/sysfs/dir.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/sysfs/dir.c	2003-10-05 00:34:36.000000000 -0700
+@@ -82,8 +82,16 @@ static void remove_dir(struct dentry * d
+ {
+ 	struct dentry * parent = dget(d->d_parent);
+ 	down(&parent->d_inode->i_sem);
+-	d_delete(d);
+-	simple_rmdir(parent->d_inode,d);
++	/*
++	 * It is possible that parent has already been removed, in which
++	 * case directory is already unhashed and dput.
++	 * Note that this won't update parent->d_inode->i_nlink; OTOH
++	 * parent should already be dead
++	 */
++	if (!d_unhashed(d)) {
++		d_delete(d);
++		simple_rmdir(parent->d_inode,d);
++	}
+ 
+ 	pr_debug(" o %s removing done (%d)\n",d->d_name.name,
+ 		 atomic_read(&d->d_count));
+--- linux-2.6.0-test6/fs/udf/inode.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/fs/udf/inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -127,6 +127,7 @@ no_delete:
+ void udf_clear_inode(struct inode *inode)
+ {
+ 	kfree(UDF_I_DATA(inode));
++	UDF_I_DATA(inode) = NULL;
+ }
+ 
+ void udf_discard_prealloc(struct inode * inode)
+--- linux-2.6.0-test6/fs/udf/super.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/fs/udf/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -50,6 +50,7 @@
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/parser.h>
+ #include <linux/stat.h>
+ #include <linux/cdrom.h>
+ #include <linux/nls.h>
+@@ -132,8 +133,10 @@ static void init_once(void * foo, kmem_c
+ 	struct udf_inode_info *ei = (struct udf_inode_info *) foo;
+ 
+ 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+-	    SLAB_CTOR_CONSTRUCTOR)
++	    SLAB_CTOR_CONSTRUCTOR) {
++		ei->i_ext.i_data = NULL;
+ 		inode_init_once(&ei->vfs_inode);
++	}
+ }
+ 
+ static int init_inodecache(void)
+@@ -225,7 +228,7 @@ module_exit(exit_udf_fs)
+  *	gid=		Set the default group.
+  *	umask=		Set the default umask.
+  *	uid=		Set the default user.
+- *	bs=			Set the block size.
++ *	bs=		Set the block size.
+  *	unhide		Show otherwise hidden files.
+  *	undelete	Show deleted files in lists.
+  *	adinicb		Embed data in the inode (default)
+@@ -259,18 +262,53 @@ module_exit(exit_udf_fs)
+  *	uopts		Pointer to mount options variable.
+  *
+  * POST-CONDITIONS
+- *	<return>	0	Mount options parsed okay.
+- *	<return>	-1	Error parsing mount options.
++ *	<return>	1	Mount options parsed okay.
++ *	<return>	0	Error parsing mount options.
+  *
+  * HISTORY
+  *	July 1, 1997 - Andrew E. Mileski
+  *	Written, tested, and released.
+  */
+ 
++enum {
++	Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
++	Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
++	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
++	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
++	Opt_rootdir, Opt_utf8, Opt_iocharset,
++	Opt_err
++};
++
++static match_table_t tokens = {
++	{Opt_novrs, "novrs"},
++	{Opt_nostrict, "nostrict"},
++	{Opt_bs, "bs=%u"},
++	{Opt_unhide, "unhide"},
++	{Opt_undelete, "undelete"},
++	{Opt_noadinicb, "noadinicb"},
++	{Opt_adinicb, "adinicb"},
++	{Opt_shortad, "shortad"},
++	{Opt_longad, "longad"},
++	{Opt_gid, "gid=%u"},
++	{Opt_uid, "uid=%u"},
++	{Opt_umask, "umask=%o"},
++	{Opt_session, "session=%u"},
++	{Opt_lastblock, "lastblock=%u"},
++	{Opt_anchor, "anchor=%u"},
++	{Opt_volume, "volume=%u"},
++	{Opt_partition, "partition=%u"},
++	{Opt_fileset, "fileset=%u"},
++	{Opt_rootdir, "rootdir=%u"},
++	{Opt_utf8, "utf8"},
++	{Opt_iocharset, "iocharset=%s"},
++	{Opt_err, NULL}
++};
++
+ static int
+ udf_parse_options(char *options, struct udf_options *uopt)
+ {
+-	char *opt, *val;
++	char *p;
++	int option;
+ 
+ 	uopt->novrs = 0;
+ 	uopt->blocksize = 2048;
+@@ -286,71 +324,106 @@ udf_parse_options(char *options, struct 
+ 	if (!options)
+ 		return 1;
+ 
+-	while ((opt = strsep(&options, ",")) != NULL)
+-	{
+-		if (!*opt)
++	while ((p = strsep(&options, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		/* Make "opt=val" into two strings */
+-		val = strchr(opt, '=');
+-		if (val)
+-			*(val++) = 0;
+-		if (!strcmp(opt, "novrs") && !val)
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_novrs:
+ 			uopt->novrs = 1;
+-		else if (!strcmp(opt, "bs") && val)
+-			uopt->blocksize = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "unhide") && !val)
++			break;
++		case Opt_bs:
++			if (match_int(&args[0], &option))
++				return 0;
++			uopt->blocksize = option;
++			break;
++		case Opt_unhide:
+ 			uopt->flags |= (1 << UDF_FLAG_UNHIDE);
+-		else if (!strcmp(opt, "undelete") && !val)
++			break;
++		case Opt_undelete:
+ 			uopt->flags |= (1 << UDF_FLAG_UNDELETE);
+-		else if (!strcmp(opt, "noadinicb") && !val)
++			break;
++		case Opt_noadinicb:
+ 			uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
+-		else if (!strcmp(opt, "adinicb") && !val)
++			break;
++		case Opt_adinicb:
+ 			uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
+-		else if (!strcmp(opt, "shortad") && !val)
++			break;
++		case Opt_shortad:
+ 			uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
+-		else if (!strcmp(opt, "longad") && !val)
++			break;
++		case Opt_longad:
+ 			uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
+-		else if (!strcmp(opt, "gid") && val)
+-			uopt->gid = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "umask") && val)
+-			uopt->umask = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "nostrict") && !val)
++			break;
++		case Opt_gid:
++			if (match_int(args, &option))
++				return 0;
++			uopt->gid = option;
++			break;
++		case Opt_uid:
++			if (match_int(args, &option))
++				return 0;
++			uopt->uid = option;
++			break;
++		case Opt_umask:
++			if (match_octal(args, &option))
++				return 0;
++			uopt->umask = option;
++			break;
++		case Opt_nostrict:
+ 			uopt->flags &= ~(1 << UDF_FLAG_STRICT);
+-		else if (!strcmp(opt, "uid") && val)
+-			uopt->uid = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "session") && val)
+-			uopt->session = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "lastblock") && val)
+-			uopt->lastblock = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "anchor") && val)
+-			uopt->anchor = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "volume") && val)
+-			uopt->volume = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "partition") && val)
+-			uopt->partition = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "fileset") && val)
+-			uopt->fileset = simple_strtoul(val, NULL, 0);
+-		else if (!strcmp(opt, "rootdir") && val)
+-			uopt->rootdir = simple_strtoul(val, NULL, 0);
++			break;
++		case Opt_session:
++			if (match_int(args, &option))
++				return 0;
++			uopt->session = option;
++			break;
++		case Opt_lastblock:
++			if (match_int(args, &option))
++				return 0;
++			uopt->lastblock = option;
++			break;
++		case Opt_anchor:
++			if (match_int(args, &option))
++				return 0;
++			uopt->anchor = option;
++			break;
++		case Opt_volume:
++			if (match_int(args, &option))
++				return 0;
++			uopt->volume = option;
++			break;
++		case Opt_partition:
++			if (match_int(args, &option))
++				return 0;
++			uopt->partition = option;
++			break;
++		case Opt_fileset:
++			if (match_int(args, &option))
++				return 0;
++			uopt->fileset = option;
++			break;
++		case Opt_rootdir:
++			if (match_int(args, &option))
++				return 0;
++			uopt->rootdir = option;
++			break;
++		case Opt_utf8:
++			uopt->flags |= (1 << UDF_FLAG_UTF8);
++			break;
+ #ifdef CONFIG_NLS
+-		else if (!strcmp(opt, "iocharset") && val)
+-		{
+-			uopt->nls_map = load_nls(val);
++		case Opt_iocharset:
++			uopt->nls_map = load_nls(args[0].from);
+ 			uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+-		}
++			break;
+ #endif
+-		else if (!strcmp(opt, "utf8") && !val)
+-			uopt->flags |= (1 << UDF_FLAG_UTF8);
+-		else if (val)
+-		{
+-			printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
+-				opt, val);
+-			return 0;
+-		}
+-		else
+-		{
+-			printk(KERN_ERR "udf: bad mount option \"%s\"\n",
+-				opt);
++		default:
++			printk(KERN_ERR "udf: bad mount option \"%s\" "
++					"or missing value\n",
++				p);
+ 			return 0;
+ 		}
+ 	}
+--- linux-2.6.0-test6/fs/ufs/super.c	2003-06-22 12:04:44.000000000 -0700
++++ 25/fs/ufs/super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -79,6 +79,7 @@
+ #include <linux/string.h>
+ #include <linux/blkdev.h>
+ #include <linux/init.h>
++#include <linux/parser.h>
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
+ #include <linux/vfs.h>
+@@ -250,64 +251,99 @@ void ufs_warning (struct super_block * s
+ 		sb->s_id, function, error_buf);
+ }
+ 
++enum {
++	Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_44bsd,
++	Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
++	Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
++	Opt_onerror_umount, Opt_onerror_repair, Opt_err
++};
++
++static match_table_t tokens = {
++	{Opt_type_old, "ufstype=old"},
++	{Opt_type_sunx86, "ufstype=sunx86"},
++	{Opt_type_sun, "ufstype=sun"},
++	{Opt_type_44bsd, "ufstype=44bsd"},
++	{Opt_type_hp, "ufstype=hp"},
++	{Opt_type_nextstepcd, "ufstype=nextstep-cd"},
++	{Opt_type_nextstep, "ufstype=nextstep"},
++	{Opt_type_openstep, "ufstype=openstep"},
++	{Opt_onerror_panic, "onerror=panic"},
++	{Opt_onerror_lock, "onerror=lock"},
++	{Opt_onerror_umount, "onerror=umount"},
++	{Opt_onerror_repair, "onerror=repair"},
++	{Opt_err, NULL}
++};
++
+ static int ufs_parse_options (char * options, unsigned * mount_options)
+ {
+-	char * this_char;
+-	char * value;
++	char * p;
+ 	
+ 	UFSD(("ENTER\n"))
+ 	
+ 	if (!options)
+ 		return 1;
+ 
+-	while ((this_char = strsep (&options, ",")) != NULL) {
+-		if (!*this_char)
++	while ((p = strsep(&options, ",")) != NULL) {
++		substring_t args[MAX_OPT_ARGS];
++		int token;
++		if (!*p)
+ 			continue;
+-		if ((value = strchr (this_char, '=')) != NULL)
+-			*value++ = 0;
+-		if (!strcmp (this_char, "ufstype")) {
++
++		token = match_token(p, tokens, args);
++		switch (token) {
++		case Opt_type_old:
+ 			ufs_clear_opt (*mount_options, UFSTYPE);
+-			if (!strcmp (value, "old"))
+-				ufs_set_opt (*mount_options, UFSTYPE_OLD);
+-			else if (!strcmp (value, "sun"))
+-				ufs_set_opt (*mount_options, UFSTYPE_SUN);
+-			else if (!strcmp (value, "44bsd"))
+-				ufs_set_opt (*mount_options, UFSTYPE_44BSD);
+-			else if (!strcmp (value, "nextstep"))
+-				ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
+-			else if (!strcmp (value, "nextstep-cd"))
+-				ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
+-			else if (!strcmp (value, "openstep"))
+-				ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
+-			else if (!strcmp (value, "sunx86"))
+-				ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
+-			else if (!strcmp (value, "hp"))
+-				ufs_set_opt (*mount_options, UFSTYPE_HP);
+-			else {
+-				printk ("UFS-fs: Invalid type option: %s\n", value);
+-				return 0;
+-			}
+-		}
+-		else if (!strcmp (this_char, "onerror")) {
++			ufs_set_opt (*mount_options, UFSTYPE_OLD);
++			break;
++		case Opt_type_sunx86:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
++			break;
++		case Opt_type_sun:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_SUN);
++			break;
++		case Opt_type_44bsd:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_44BSD);
++			break;
++		case Opt_type_hp:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_HP);
++			break;
++		case Opt_type_nextstepcd:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
++			break;
++		case Opt_type_nextstep:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
++			break;
++		case Opt_type_openstep:
++			ufs_clear_opt (*mount_options, UFSTYPE);
++			ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
++			break;
++		case Opt_onerror_panic:
+ 			ufs_clear_opt (*mount_options, ONERROR);
+-			if (!strcmp (value, "panic"))
+-				ufs_set_opt (*mount_options, ONERROR_PANIC);
+-			else if (!strcmp (value, "lock"))
+-				ufs_set_opt (*mount_options, ONERROR_LOCK);
+-			else if (!strcmp (value, "umount"))
+-				ufs_set_opt (*mount_options, ONERROR_UMOUNT);
+-			else if (!strcmp (value, "repair")) {
+-				printk("UFS-fs: Unable to do repair on error, "
+-					"will lock lock instead \n");
+-				ufs_set_opt (*mount_options, ONERROR_REPAIR);
+-			}
+-			else {
+-				printk ("UFS-fs: Invalid action onerror: %s\n", value);
+-				return 0;
+-			}
+-		}
+-		else {
+-			printk("UFS-fs: Invalid option: %s\n", this_char);
++			ufs_set_opt (*mount_options, ONERROR_PANIC);
++			break;
++		case Opt_onerror_lock:
++			ufs_clear_opt (*mount_options, ONERROR);
++			ufs_set_opt (*mount_options, ONERROR_LOCK);
++			break;
++		case Opt_onerror_umount:
++			ufs_clear_opt (*mount_options, ONERROR);
++			ufs_set_opt (*mount_options, ONERROR_UMOUNT);
++			break;
++		case Opt_onerror_repair:
++			printk("UFS-fs: Unable to do repair on error, "
++				"will lock lock instead\n");
++			ufs_clear_opt (*mount_options, ONERROR);
++			ufs_set_opt (*mount_options, ONERROR_REPAIR);
++			break;
++		default:
++			printk("UFS-fs: Invalid option: \"%s\" "
++					"or missing value\n", p);
+ 			return 0;
+ 		}
+ 	}
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_aops.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_aops.c	2003-10-05 00:36:53.000000000 -0700
+@@ -461,7 +461,8 @@ map_unwritten(
+ 		struct page		*page;
+ 
+ 		tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+-		tloff = min(tlast, start_page->index + pb->pb_page_count - 1);
++		tloff = (mp->pbm_offset + mp->pbm_bsize) >> PAGE_CACHE_SHIFT;
++		tloff = min(tlast, tloff);
+ 		for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
+ 			page = probe_unwritten_page(mapping, tindex, mp, pb,
+ 						PAGE_CACHE_SIZE, &bs, bbits);
+@@ -973,7 +974,7 @@ linvfs_direct_IO(
+ 	unsigned long		nr_segs)
+ {
+ 	struct file	*file = iocb->ki_filp;
+-	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode	*inode = file->f_mapping->host;
+ 	vnode_t		*vp = LINVFS_GET_VP(inode);
+ 	page_buf_bmap_t	pbmap;
+ 	int		maps = 1;
+@@ -983,7 +984,7 @@ linvfs_direct_IO(
+ 	if (error)
+ 		return -error;
+ 
+-        return blockdev_direct_IO(rw, iocb, inode,
++        return blockdev_direct_IO_no_locking(rw, iocb, inode,
+ 		pbmap.pbm_target->pbr_bdev,
+ 		iov, offset, nr_segs,
+ 		linvfs_get_blocks_direct,
+@@ -1041,6 +1042,8 @@ count_page_state(
+ 	do {
+ 		if (buffer_uptodate(bh) && !buffer_mapped(bh))
+ 			(*unmapped) = 1;
++		else if (buffer_unwritten(bh) && !buffer_delay(bh))
++			clear_buffer_unwritten(bh);
+ 		else if (buffer_unwritten(bh))
+ 			(*unwritten) = 1;
+ 		else if (buffer_delay(bh))
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_file.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/xfs/linux/xfs_file.c	2003-10-05 00:34:07.000000000 -0700
+@@ -86,7 +86,7 @@ linvfs_write(
+ {
+ 	struct iovec	iov = {(void *)buf, count};
+ 	struct file	*file = iocb->ki_filp;
+-	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode	*inode = file->f_mapping->host;
+ 	vnode_t		*vp = LINVFS_GET_VP(inode);
+ 	int		error;
+ 	int		direct = file->f_flags & O_DIRECT;
+@@ -111,7 +111,7 @@ linvfs_readv(
+ 	unsigned long		nr_segs,
+ 	loff_t			*ppos)
+ {
+-	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode	*inode = file->f_mapping->host;
+ 	vnode_t		*vp = LINVFS_GET_VP(inode);
+ 	struct		kiocb kiocb;
+ 	int		error;
+@@ -133,7 +133,7 @@ linvfs_writev(
+ 	unsigned long		nr_segs,
+ 	loff_t			*ppos)
+ {
+-	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
++	struct inode	*inode = file->f_mapping->host;
+ 	vnode_t		*vp = LINVFS_GET_VP(inode);
+ 	struct		kiocb kiocb;
+ 	int		error;
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_iops.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_iops.c	2003-10-05 00:33:24.000000000 -0700
+@@ -386,6 +386,7 @@ linvfs_readlink(
+ 	uio.uio_segflg = UIO_USERSPACE;
+ 	uio.uio_resid = size;
+ 	uio.uio_iovcnt = 1;
++	uio.uio_fmode = 0;
+ 
+ 	VOP_READLINK(vp, &uio, NULL, error);
+ 	if (error)
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_lrw.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_lrw.c	2003-10-05 00:33:24.000000000 -0700
+@@ -218,7 +218,7 @@ xfs_read(
+ 		int error;
+ 		vrwlock_t locktype = VRWLOCK_READ;
+ 
+-		error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, *offset, size,
++		error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, size,
+ 				      FILP_DELAY_FLAG(file), &locktype);
+ 		if (error) {
+ 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+@@ -278,7 +278,7 @@ xfs_sendfile(
+ 		vrwlock_t locktype = VRWLOCK_READ;
+ 		int error;
+ 
+-		error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, *offset, count,
++		error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, count,
+ 				      FILP_DELAY_FLAG(filp), &locktype);
+ 		if (error) {
+ 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+@@ -612,7 +612,7 @@ start:
+ 		loff_t		savedsize = *offset;
+ 
+ 		xfs_iunlock(xip, XFS_ILOCK_EXCL);
+-		error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, bdp,
++		error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,
+ 				      *offset, size,
+ 				      FILP_DELAY_FLAG(file), &locktype);
+ 		if (error) {
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_stats.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_stats.c	2003-10-05 00:33:24.000000000 -0700
+@@ -33,7 +33,7 @@
+ #include "xfs.h"
+ #include <linux/proc_fs.h>
+ 
+-struct xfsstats xfsstats;
++DEFINE_PER_CPU(struct xfsstats, xfsstats);
+ 
+ STATIC int
+ xfs_read_xfsstats(
+@@ -44,7 +44,11 @@ xfs_read_xfsstats(
+ 	int		*eof,
+ 	void		*data)
+ {
+-	int		i, j, len;
++	int		c, i, j, len, val;
++	__uint64_t	xs_xstrat_bytes = 0;
++	__uint64_t	xs_write_bytes = 0;
++	__uint64_t	xs_read_bytes = 0;
++
+ 	static struct xstats_entry {
+ 		char	*desc;
+ 		int	endpoint;
+@@ -65,21 +69,32 @@ xfs_read_xfsstats(
+ 		{ "vnodes",		XFSSTAT_END_VNODE_OPS		},
+ 	};
+ 
++	/* Loop over all stats groups */
+ 	for (i=j=len = 0; i < sizeof(xstats)/sizeof(struct xstats_entry); i++) {
+ 		len += sprintf(buffer + len, xstats[i].desc);
+ 		/* inner loop does each group */
+ 		while (j < xstats[i].endpoint) {
+-			len += sprintf(buffer + len, " %u",
+-					*(((__u32*)&xfsstats) + j));
++			val = 0;
++			/* sum over all cpus */
++			for (c = 0; c < NR_CPUS; c++) {
++				if (!cpu_possible(c)) continue;
++				val += *(((__u32*)&per_cpu(xfsstats, c) + j));
++			}
++			len += sprintf(buffer + len, " %u", val);
+ 			j++;
+ 		}
+ 		buffer[len++] = '\n';
+ 	}
+ 	/* extra precision counters */
++	for (i = 0; i < NR_CPUS; i++) {
++		if (!cpu_possible(i)) continue;
++		xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
++		xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
++		xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
++	}
++
+ 	len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n",
+-			xfsstats.xs_xstrat_bytes,
+-			xfsstats.xs_write_bytes,
+-			xfsstats.xs_read_bytes);
++			xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
+ 	len += sprintf(buffer + len, "debug %u\n",
+ #if defined(XFSDEBUG)
+ 		1);
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_stats.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_stats.h	2003-10-05 00:33:24.000000000 -0700
+@@ -35,6 +35,8 @@
+ 
+ #if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
+ 
++#include <linux/percpu.h>
++
+ /*
+  * XFS global statistics
+  */
+@@ -126,11 +128,13 @@ struct xfsstats {
+ 	__uint64_t		xs_read_bytes;
+ };
+ 
+-extern struct xfsstats xfsstats;
++DECLARE_PER_CPU(struct xfsstats, xfsstats);
+ 
+-# define XFS_STATS_INC(count)		( xfsstats.count++ )
+-# define XFS_STATS_DEC(count)		( xfsstats.count-- )
+-# define XFS_STATS_ADD(count, inc)	( xfsstats.count += (inc) )
++/* We don't disable preempt, not too worried about poking the
++ * wrong cpu's stat for now */
++#define XFS_STATS_INC(count)		(__get_cpu_var(xfsstats).count++)
++#define XFS_STATS_DEC(count)		(__get_cpu_var(xfsstats).count--)
++#define XFS_STATS_ADD(count, inc)	(__get_cpu_var(xfsstats).count += (inc))
+ 
+ extern void xfs_init_procfs(void);
+ extern void xfs_cleanup_procfs(void);
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_super.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_super.c	2003-10-05 00:33:24.000000000 -0700
+@@ -315,8 +315,8 @@ xfs_setsize_buftarg(
+ 
+ 	if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+ 		printk(KERN_WARNING
+-			"XFS: Cannot set_blocksize to %u on device %u:%u\n",
+-			sectorsize, MAJOR(btp->pbr_dev), MINOR(btp->pbr_dev));
++			"XFS: Cannot set_blocksize to %u on device %s\n",
++			sectorsize, XFS_BUFTARG_NAME(btp));
+ 	}
+ }
+ 
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_sysctl.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_sysctl.c	2003-10-05 00:33:24.000000000 -0700
+@@ -48,17 +48,23 @@ xfs_stats_clear_proc_handler(
+ 	void		*buffer,
+ 	size_t		*lenp)
+ {
+-	int		ret, *valp = ctl->data;
++	int		c, ret, *valp = ctl->data;
+ 	__uint32_t	vn_active;
+ 
+ 	ret = proc_doulongvec_minmax(ctl, write, filp, buffer, lenp);
+ 
+ 	if (!ret && write && *valp) {
+ 		printk("XFS Clearing xfsstats\n");
+-		/* save vn_active, it's a universal truth! */
+-		vn_active = xfsstats.vn_active;
+-		memset(&xfsstats, 0, sizeof(xfsstats));
+-		xfsstats.vn_active = vn_active;
++		for (c = 0; c < NR_CPUS; c++) {
++			if (!cpu_possible(c)) continue;
++			preempt_disable();
++			/* save vn_active, it's a universal truth! */
++			vn_active = per_cpu(xfsstats, c).vn_active;
++			memset(&per_cpu(xfsstats, c), 0,
++			       sizeof(struct xfsstats));
++			per_cpu(xfsstats, c).vn_active = vn_active;
++			preempt_enable();
++		}
+ 		xfs_stats_clear = 0;
+ 	}
+ 
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_vnode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/linux/xfs_vnode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -200,7 +200,7 @@ vn_revalidate(
+ 	vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
+ 	ASSERT(vp->v_fbhv != NULL);
+ 
+-	va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT;
++	va.va_mask = XFS_AT_STAT|XFS_AT_XFLAGS;
+ 	VOP_GETATTR(vp, &va, 0, NULL, error);
+ 	if (!error) {
+ 		inode = LINVFS_GET_IP(vp);
+--- linux-2.6.0-test6/fs/xfs/linux/xfs_vnode.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/xfs/linux/xfs_vnode.h	2003-10-05 00:33:24.000000000 -0700
+@@ -28,6 +28,37 @@
+  * For further information regarding this notice, see:
+  *
+  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
++ *
++ * Portions Copyright (c) 1989, 1993
++ *      The Regents of the University of California.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *      This product includes software developed by the University of
++ *      California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
+  */
+ #ifndef __XFS_VNODE_H__
+ #define __XFS_VNODE_H__
+@@ -39,19 +70,9 @@ struct page_buf_bmap_s;
+ struct attrlist_cursor_kern;
+ 
+ /*
+- * Vnode types (unrelated to on-disk inodes).  VNON means no type.
++ * Vnode types.  VNON means no type.
+  */
+-typedef enum vtype {
+-	VNON	= 0,
+-	VREG	= 1,
+-	VDIR	= 2,
+-	VBLK	= 3,
+-	VCHR	= 4,
+-	VLNK	= 5,
+-	VFIFO	= 6,
+-	VBAD	= 7,
+-	VSOCK	= 8
+-} vtype_t;
++enum vtype	{ VNON, VREG, VDIR, VBLK, VCHR, VLNK, VFIFO, VBAD, VSOCK };
+ 
+ typedef xfs_ino_t vnumber_t;
+ typedef struct dentry vname_t;
+@@ -115,14 +136,15 @@ typedef enum {
+ #define LINVFS_GET_IP(vp)	(&(vp)->v_inode)
+ 
+ /*
+- * Conversion between vnode types/modes and encoded type/mode as
+- * seen by stat(2) and mknod(2).
++ * Convert between vnode types and inode formats (since POSIX.1
++ * defines mode word of stat structure in terms of inode formats).
+  */
+-extern enum vtype       iftovt_tab[];
+-extern ushort           vttoif_tab[];
+-#define IFTOVT(M)       (iftovt_tab[((M) & S_IFMT) >> 12])
+-#define VTTOIF(T)       (vttoif_tab[(int)(T)])
+-#define MAKEIMODE(T, M)	(VTTOIF(T) | ((M) & ~S_IFMT))
++extern enum vtype	iftovt_tab[];
++extern u_short		vttoif_tab[];
++#define IFTOVT(mode)	(iftovt_tab[((mode) & S_IFMT) >> 12])
++#define VTTOIF(indx)	(vttoif_tab[(int)(indx)])
++#define MAKEIMODE(indx, mode)	(int)(VTTOIF(indx) | (mode))
++
+ 
+ /*
+  * Vnode flags.
+@@ -370,31 +392,29 @@ typedef struct vnodeops {
+ 
+ /*
+  * Vnode attributes.  va_mask indicates those attributes the caller
+- * wants to set (setattr) or extract (getattr).
++ * wants to set or extract.
+  */
+ typedef struct vattr {
+-	int		va_mask;	/* bit-mask of attributes */
+-	vtype_t		va_type;	/* vnode type (for create) */
+-	mode_t		va_mode;	/* file access mode */
++	int		va_mask;	/* bit-mask of attributes present */
++	enum vtype	va_type;	/* vnode type (for create) */
++	mode_t		va_mode;	/* file access mode and type */
++	nlink_t		va_nlink;	/* number of references to file */
+ 	uid_t		va_uid;		/* owner user id */
+ 	gid_t		va_gid;		/* owner group id */
+-	xfs_dev_t	va_fsid;	/* file system id (dev for now) */
+-	xfs_ino_t	va_nodeid;	/* node id */
+-	nlink_t		va_nlink;	/* number of references to file */
++	xfs_ino_t	va_nodeid;	/* file id */
+ 	xfs_off_t	va_size;	/* file size in bytes */
+-	timespec_t	va_atime;	/* time of last access */
+-	timespec_t	va_mtime;	/* time of last modification */
+-	timespec_t	va_ctime;	/* time file ``created'' */
+-	xfs_dev_t	va_rdev;	/* device the file represents */
+-	u_long		va_blksize;	/* fundamental block size */
+-	__int64_t	va_nblocks;	/* # of blocks allocated */
+-	u_long		va_vcode;	/* version code */
++	u_long		va_blocksize;	/* blocksize preferred for i/o */
++	struct timespec	va_atime;	/* time of last access */
++	struct timespec	va_mtime;	/* time of last modification */
++	struct timespec	va_ctime;	/* time file changed */
++	u_int		va_gen;		/* generation number of file */
++	xfs_dev_t	va_rdev;	/* device the special file represents */
++	__int64_t	va_nblocks;	/* number of blocks allocated */
+ 	u_long		va_xflags;	/* random extended file flags */
+ 	u_long		va_extsize;	/* file extent size */
+ 	u_long		va_nextents;	/* number of extents in file */
+ 	u_long		va_anextents;	/* number of attr extents in file */
+ 	int		va_projid;	/* project id */
+-	u_int		va_gencount;	/* object generation count */
+ } vattr_t;
+ 
+ /*
+@@ -450,11 +470,17 @@ typedef struct vattr {
+ 		XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\
+ 		XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT)
+ 
+-#define VREAD		00400
+-#define VWRITE		00200
+-#define VEXEC		00100
+-#define VSGID		02000		/* set group id on execution */
+-#define MODEMASK	07777		/* mode bits plus permission bits */
++/*
++ *  Modes.
++ */
++#define VSUID	S_ISUID		/* set user id on execution */
++#define VSGID	S_ISGID		/* set group id on execution */
++#define VSVTX	S_ISVTX		/* save swapped text even after use */
++#define VREAD	S_IRUSR		/* read, write, execute permissions */
++#define VWRITE	S_IWUSR
++#define VEXEC	S_IXUSR
++
++#define MODEMASK S_IALLUGO	/* mode bits plus permission bits */
+ 
+ /*
+  * Check whether mandatory file locking is enabled.
+@@ -569,13 +595,9 @@ static __inline__ void vn_flagclr(struct
+  * Flags to VOP_SETATTR/VOP_GETATTR.
+  */
+ #define	ATTR_UTIME	0x01	/* non-default utime(2) request */
+-#define	ATTR_EXEC	0x02	/* invocation from exec(2) */
+-#define	ATTR_COMM	0x04	/* yield common vp attributes */
+ #define	ATTR_DMI	0x08	/* invocation from a DMI function */
+ #define	ATTR_LAZY	0x80	/* set/get attributes lazily */
+ #define	ATTR_NONBLOCK	0x100	/* return EAGAIN if operation would block */
+-#define ATTR_NOLOCK	0x200	/* Don't grab any conflicting locks */
+-#define ATTR_NOSIZETOK	0x400	/* Don't get the DVN_SIZE_READ token */
+ 
+ /*
+  * Flags to VOP_FSYNC and VOP_RECLAIM.
+--- linux-2.6.0-test6/fs/xfs/pagebuf/page_buf.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/pagebuf/page_buf.c	2003-10-05 00:33:24.000000000 -0700
+@@ -141,7 +141,7 @@ pagebuf_param_t pb_params = {
+  * Pagebuf statistics variables
+  */
+ 
+-struct pbstats pbstats;
++DEFINE_PER_CPU(struct pbstats, pbstats);
+ 
+ /*
+  * Pagebuf allocation / freeing.
+@@ -293,7 +293,7 @@ _pagebuf_initialize(
+ 	atomic_set(&pb->pb_pin_count, 0);
+ 	init_waitqueue_head(&pb->pb_waiters);
+ 
+-	PB_STATS_INC(pbstats.pb_create);
++	PB_STATS_INC(pb_create);
+ 	PB_TRACE(pb, PB_TRACE_REC(get), target);
+ }
+ 
+@@ -485,7 +485,7 @@ _pagebuf_lookup_pages(
+ 			page = find_or_create_page(aspace, index, gfp_mask);
+ 			if (!page) {
+ 				if (--retry_count > 0) {
+-					PB_STATS_INC(pbstats.pb_page_retries);
++					PB_STATS_INC(pb_page_retries);
+ 					pagebuf_daemon_wakeup(1);
+ 					current->state = TASK_UNINTERRUPTIBLE;
+ 					schedule_timeout(10);
+@@ -495,7 +495,7 @@ _pagebuf_lookup_pages(
+ 				all_mapped = 0;
+ 				continue;
+ 			}
+-			PB_STATS_INC(pbstats.pb_page_found);
++			PB_STATS_INC(pb_page_found);
+ 			mark_page_accessed(page);
+ 			pb->pb_pages[pi] = page;
+ 		} else {
+@@ -645,7 +645,7 @@ _pagebuf_find(				/* find buffer for blo
+ 		h->pb_count++;
+ 		list_add(&new_pb->pb_hash_list, &h->pb_hash);
+ 	} else {
+-		PB_STATS_INC(pbstats.pb_miss_locked);
++		PB_STATS_INC(pb_miss_locked);
+ 	}
+ 
+ 	spin_unlock(&h->pb_hash_lock);
+@@ -665,7 +665,7 @@ found:
+ 			/* wait for buffer ownership */
+ 			PB_TRACE(pb, PB_TRACE_REC(get_lk), 0);
+ 			pagebuf_lock(pb);
+-			PB_STATS_INC(pbstats.pb_get_locked_waited);
++			PB_STATS_INC(pb_get_locked_waited);
+ 		} else {
+ 			/* We asked for a trylock and failed, no need
+ 			 * to look at file offset and length here, we
+@@ -675,7 +675,7 @@ found:
+ 			 */
+ 
+ 			pagebuf_rele(pb);
+-			PB_STATS_INC(pbstats.pb_busy_locked);
++			PB_STATS_INC(pb_busy_locked);
+ 			return (NULL);
+ 		}
+ 	} else {
+@@ -691,7 +691,7 @@ found:
+ 				_PBF_ADDR_ALLOCATED | \
+ 				_PBF_MEM_ALLOCATED;
+ 	PB_TRACE(pb, PB_TRACE_REC(got_lk), 0);
+-	PB_STATS_INC(pbstats.pb_get_locked);
++	PB_STATS_INC(pb_get_locked);
+ 	return (pb);
+ }
+ 
+@@ -747,7 +747,7 @@ pagebuf_get(				/* allocate a buffer		*/
+ 			return (NULL);
+ 	}
+ 
+-	PB_STATS_INC(pbstats.pb_get);
++	PB_STATS_INC(pb_get);
+ 
+ 	/* fill in any missing pages */
+ 	error = _pagebuf_lookup_pages(pb, pb->pb_target->pbr_mapping, flags);
+@@ -766,7 +766,7 @@ pagebuf_get(				/* allocate a buffer		*/
+ 	if (flags & PBF_READ) {
+ 		if (PBF_NOT_DONE(pb)) {
+ 			PB_TRACE(pb, PB_TRACE_REC(get_read), flags);
+-			PB_STATS_INC(pbstats.pb_get_read);
++			PB_STATS_INC(pb_get_read);
+ 			pagebuf_iostart(pb, flags);
+ 		} else if (flags & PBF_ASYNC) {
+ 			/*
+@@ -1677,6 +1677,9 @@ pagebuf_daemon(
+ 					break;
+ 				}
+ 
++				pb->pb_flags &= ~PBF_DELWRI;
++				pb->pb_flags |= PBF_WRITE;
++
+ 				list_del(&pb->pb_list);
+ 				list_add(&pb->pb_list, &tmp);
+ 
+@@ -1688,8 +1691,6 @@ pagebuf_daemon(
+ 		while (!list_empty(&tmp)) {
+ 			pb = list_entry(tmp.next, page_buf_t, pb_list);
+ 			list_del_init(&pb->pb_list);
+-			pb->pb_flags &= ~PBF_DELWRI;
+-			pb->pb_flags |= PBF_WRITE;
+ 
+ 			pagebuf_iostrategy(pb);
+ 		}
+@@ -1720,6 +1721,7 @@ pagebuf_delwri_flush(
+ 	int			flush_cnt = 0;
+ 
+ 	pagebuf_runall_queues(pagebuf_dataio_workqueue);
++	pagebuf_runall_queues(pagebuf_logio_workqueue);
+ 
+ 	spin_lock(&pbd_delwrite_lock);
+ 	INIT_LIST_HEAD(&tmp);
+@@ -1742,47 +1744,32 @@ pagebuf_delwri_flush(
+ 			continue;
+ 		}
+ 
+-		if (flags & PBDF_TRYLOCK) {
+-			if (!pagebuf_cond_lock(pb)) {
+-				pincount++;
+-				continue;
+-			}
+-		}
+-
+-		list_del_init(&pb->pb_list);
+-		if (flags & PBDF_WAIT) {
+-			list_add(&pb->pb_list, &tmp);
+-			pb->pb_flags &= ~PBF_ASYNC;
+-		}
+-
+-		spin_unlock(&pbd_delwrite_lock);
+-
+-		if ((flags & PBDF_TRYLOCK) == 0) {
+-			pagebuf_lock(pb);
+-		}
+-
+ 		pb->pb_flags &= ~PBF_DELWRI;
+ 		pb->pb_flags |= PBF_WRITE;
++		list_move(&pb->pb_list, &tmp);
++	}
++	/* ok found all the items that can be worked on 
++	 * drop the lock and process the private list */
++	spin_unlock(&pbd_delwrite_lock);
++
++	list_for_each_safe(curr, next, &tmp) {
++		pb = list_entry(curr, page_buf_t, pb_list);
++
++		if (flags & PBDF_WAIT)
++			pb->pb_flags &= ~PBF_ASYNC;
++		else
++			list_del_init(curr);
+ 
++		pagebuf_lock(pb);
+ 		pagebuf_iostrategy(pb);
+ 		if (++flush_cnt > 32) {
+ 			blk_run_queues();
+ 			flush_cnt = 0;
+ 		}
+-
+-		spin_lock(&pbd_delwrite_lock);
+ 	}
+ 
+-	spin_unlock(&pbd_delwrite_lock);
+-
+ 	blk_run_queues();
+ 
+-	if (pinptr)
+-		*pinptr = pincount;
+-
+-	if ((flags & PBDF_WAIT) == 0)
+-		return;
+-
+ 	while (!list_empty(&tmp)) {
+ 		pb = list_entry(tmp.next, page_buf_t, pb_list);
+ 
+@@ -1792,6 +1779,9 @@ pagebuf_delwri_flush(
+ 			pagebuf_unlock(pb);
+ 		pagebuf_rele(pb);
+ 	}
++
++	if (pinptr)
++		*pinptr = pincount;
+ }
+ 
+ STATIC int
+@@ -1846,14 +1836,18 @@ pb_stats_clear_handler(
+ 	void			*buffer,
+ 	size_t			*lenp)
+ {
+-	int			ret;
++	int			c, ret;
+ 	int			*valp = ctl->data;
+ 
+ 	ret = proc_doulongvec_minmax(ctl, write, filp, buffer, lenp);
+ 
+ 	if (!ret && write && *valp) {
+ 		printk("XFS Clearing pbstats\n");
+-		memset(&pbstats, 0, sizeof(pbstats));
++		for (c = 0; c < NR_CPUS; c++) {
++			if (!cpu_possible(c)) continue;
++				memset(&per_cpu(pbstats, c), 0,
++				       sizeof(struct pbstats));
++		}
+ 		pb_params.stats_clear.val = 0;
+ 	}
+ 
+@@ -1907,13 +1901,17 @@ pagebuf_readstats(
+ 	int			*eof,
+ 	void			*data)
+ {
+-	int			i, len;
++	int			c, i, len, val;
+ 
+ 	len = 0;
+ 	len += sprintf(buffer + len, "pagebuf");
+-	for (i = 0; i < sizeof(pbstats) / sizeof(u_int32_t); i++) {
+-		len += sprintf(buffer + len, " %u",
+-			*(((u_int32_t*)&pbstats) + i));
++	for (i = 0; i < sizeof(struct pbstats) / sizeof(u_int32_t); i++) {
++		val = 0;
++		for (c = 0 ; c < NR_CPUS; c++) {
++			if (!cpu_possible(c)) continue;
++			val += *(((u_int32_t*)&per_cpu(pbstats, c) + i));
++		}
++		len += sprintf(buffer + len, " %u", val);
+ 	}
+ 	buffer[len++] = '\n';
+ 
+--- linux-2.6.0-test6/fs/xfs/pagebuf/page_buf.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/xfs/pagebuf/page_buf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -136,9 +136,6 @@ typedef enum page_buf_flags_e {		/* pb_f
+ #define PBF_NOT_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) != 0)
+ #define PBF_DONE(pb) (((pb)->pb_flags & (PBF_PARTIAL|PBF_NONE)) == 0)
+ 
+-#define PBR_SECTOR_ONLY	1	/* only use sector size buffer heads */
+-#define PBR_ALIGNED_ONLY 2	/* only use aligned I/O */
+-
+ typedef struct pb_target {
+ 	dev_t			pbr_dev;
+ 	struct block_device	*pbr_bdev;
+@@ -371,7 +368,6 @@ extern int pagebuf_ispin(		/* check if b
+ /* Delayed Write Buffer Routines */
+ 
+ #define PBDF_WAIT    0x01
+-#define PBDF_TRYLOCK 0x02
+ extern void pagebuf_delwri_flush(
+ 		pb_target_t *,
+ 		unsigned long,
+--- linux-2.6.0-test6/fs/xfs/pagebuf/page_buf_internal.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/pagebuf/page_buf_internal.h	2003-10-05 00:33:24.000000000 -0700
+@@ -37,6 +37,7 @@
+ #ifndef __PAGE_BUF_PRIVATE_H__
+ #define __PAGE_BUF_PRIVATE_H__
+ 
++#include <linux/percpu.h>
+ #include "page_buf.h"
+ 
+ #define _PAGE_BUF_INTERNAL_
+@@ -120,9 +121,11 @@ struct pbstats {
+ 	u_int32_t	pb_get_read;
+ };
+ 
+-extern struct pbstats pbstats;
++DECLARE_PER_CPU(struct pbstats, pbstats);
+ 
+-#define PB_STATS_INC(count)	( count ++ )
++/* We don't disable preempt, not too worried about poking the
++ * wrong cpu's stat for now */
++#define PB_STATS_INC(count)	(__get_cpu_var(pbstats).count++)
+ 
+ #ifndef STATIC
+ # define STATIC	static
+--- linux-2.6.0-test6/fs/xfs/quota/xfs_dquot.c	2003-06-14 12:18:09.000000000 -0700
++++ 25/fs/xfs/quota/xfs_dquot.c	2003-10-05 00:33:24.000000000 -0700
+@@ -87,9 +87,9 @@
+ STATIC void		xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *);
+ 
+ #ifdef DEBUG
+-dev_t xfs_dqerror_dev = 0;
+-int xfs_do_dqerror = 0;
+-int xfs_dqreq_num = 0;
++xfs_buftarg_t *xfs_dqerror_target;
++int xfs_do_dqerror;
++int xfs_dqreq_num;
+ int xfs_dqerror_mod = 33;
+ #endif
+ 
+@@ -911,7 +911,7 @@ xfs_qm_dqget(
+ 
+ #ifdef DEBUG
+ 	if (xfs_do_dqerror) {
+-		if ((xfs_dqerror_dev == mp->m_dev) &&
++		if ((xfs_dqerror_target == mp->m_ddev_targp) &&
+ 		    (xfs_dqreq_num++ % xfs_dqerror_mod) == 0) {
+ 			cmn_err(CE_DEBUG, "Returning error in dqget");
+ 			return (EIO);
+--- linux-2.6.0-test6/fs/xfs/quota/xfs_qm.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/fs/xfs/quota/xfs_qm.h	2003-10-05 00:33:24.000000000 -0700
+@@ -165,9 +165,9 @@ typedef struct xfs_dquot_acct {
+  * Users are allowed to have a usage exceeding their softlimit for
+  * a period this long.
+  */
+-#define XFS_QM_BTIMELIMIT	DQ_BTIMELIMIT
+-#define XFS_QM_RTBTIMELIMIT	DQ_BTIMELIMIT
+-#define XFS_QM_ITIMELIMIT	DQ_FTIMELIMIT
++#define XFS_QM_BTIMELIMIT	(7 * 24*60*60)          /* 1 week */
++#define XFS_QM_RTBTIMELIMIT	(7 * 24*60*60)          /* 1 week */
++#define XFS_QM_ITIMELIMIT	(7 * 24*60*60)          /* 1 week */
+ 
+ #define XFS_QM_BWARNLIMIT	5
+ #define XFS_QM_IWARNLIMIT	5
+--- linux-2.6.0-test6/fs/xfs/support/move.c	2003-06-14 12:18:22.000000000 -0700
++++ 25/fs/xfs/support/move.c	2003-10-05 00:33:24.000000000 -0700
+@@ -38,57 +38,37 @@
+ #include "debug.h"
+ #include "move.h"
+ 
+-/*
+- * Move "n" bytes at byte address "cp"; "rw" indicates the direction
+- * of the move, and the I/O parameters are provided in "uio", which is
+- * update to reflect the data which was moved.  Returns 0 on success or
+- * a non-zero errno on failure.
++/* Read from kernel buffer at src to user/kernel buffer defined
++ * by the uio structure. Advance the pointer in the uio struct
++ * as we go.
+  */
+ int
+-uiomove(void *cp, size_t n, enum uio_rw rw, struct uio *uio)
++uio_read(caddr_t src, size_t len, struct uio *uio)
+ {
+-	register struct iovec *iov;
++	struct iovec *iov;
+ 	u_int cnt;
+ 	int error;
+ 
+-	while (n > 0 && uio->uio_resid) {
++	if (len > 0 && uio->uio_resid) {
+ 		iov = uio->uio_iov;
+ 		cnt = (u_int)iov->iov_len;
+-		if (cnt == 0) {
+-			uio->uio_iov++;
+-			uio->uio_iovcnt--;
+-			continue;
+-		}
+-		if (cnt > n)
+-			cnt = (u_int)n;
+-		switch (uio->uio_segflg) {
+-		case UIO_USERSPACE:
+-			if (rw == UIO_READ)
+-				error = copy_to_user(iov->iov_base, cp, cnt);
+-			else
+-				error = copy_from_user(cp, iov->iov_base, cnt);
++		if (cnt == 0)
++			return 0;
++		if (cnt > len)
++			cnt = (u_int)len;
++		if (uio->uio_segflg == UIO_USERSPACE) {
++			error = copy_to_user(iov->iov_base, src, cnt);
+ 			if (error)
+ 				return EFAULT;
+-			break;
+-
+-
+-		case UIO_SYSSPACE:
+-			if (rw == UIO_READ)
+-				memcpy(iov->iov_base, cp, cnt);
+-			else
+-				memcpy(cp, iov->iov_base, cnt);
+-			break;
+-
+-		default:
++		} else if (uio->uio_segflg == UIO_SYSSPACE) {
++			memcpy(iov->iov_base, src, cnt);
++		} else {
+ 			ASSERT(0);
+-			break;
+ 		}
+ 		iov->iov_base = (void *)((char *)iov->iov_base + cnt);
+ 		iov->iov_len -= cnt;
+ 		uio->uio_resid -= cnt;
+ 		uio->uio_offset += cnt;
+-		cp = (void *)((char *)cp + cnt);
+-		n -= cnt;
+ 	}
+ 	return 0;
+ }
+--- linux-2.6.0-test6/fs/xfs/support/move.h	2003-06-14 12:18:20.000000000 -0700
++++ 25/fs/xfs/support/move.h	2003-10-05 00:33:24.000000000 -0700
+@@ -48,11 +48,6 @@ typedef struct uio {
+ } uio_t;
+ 
+ /*
+- * I/O direction.
+- */
+-typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t;
+-
+-/*
+  * Segment flag values.
+  */
+ typedef enum uio_seg {
+@@ -60,7 +55,6 @@ typedef enum uio_seg {
+ 	UIO_SYSSPACE,           /* uio_iov describes system space */
+ } uio_seg_t;
+ 
+-
+-extern int	uiomove (void *, size_t, uio_rw_t, uio_t *);
++extern int	uio_read (caddr_t, size_t, uio_t *);
+ 
+ #endif  /* __XFS_SUPPORT_MOVE_H__ */
+--- linux-2.6.0-test6/fs/xfs/xfs_attr_fetch.c	2003-06-14 12:18:25.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,100 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of version 2 of the GNU General Public License as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it would be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+- *
+- * Further, this software is distributed without any warranty that it is
+- * free of the rightful claim of any third person regarding infringement
+- * or the like.  Any license provided herein, whether implied or
+- * otherwise, applies only to this software file.  Patent licenses, if
+- * any, provided herein do not apply to combinations of this program with
+- * other software, or any other product whatsoever.
+- *
+- * You should have received a copy of the GNU General Public License along
+- * with this program; if not, write the Free Software Foundation, Inc., 59
+- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+- *
+- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+- * Mountain View, CA  94043, or:
+- *
+- * http://www.sgi.com
+- *
+- * For further information regarding this notice, see:
+- *
+- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+- */
+-
+-#include "xfs.h"
+-
+-#include "xfs_macros.h"
+-#include "xfs_types.h"
+-#include "xfs_inum.h"
+-#include "xfs_log.h"
+-#include "xfs_trans.h"
+-#include "xfs_sb.h"
+-#include "xfs_ag.h"
+-#include "xfs_dir.h"
+-#include "xfs_dir2.h"
+-#include "xfs_dmapi.h"
+-#include "xfs_mount.h"
+-#include "xfs_alloc_btree.h"
+-#include "xfs_bmap_btree.h"
+-#include "xfs_ialloc_btree.h"
+-#include "xfs_itable.h"
+-#include "xfs_btree.h"
+-#include "xfs_ialloc.h"
+-#include "xfs_alloc.h"
+-#include "xfs_attr_sf.h"
+-#include "xfs_dir_sf.h"
+-#include "xfs_dir2_sf.h"
+-#include "xfs_dinode.h"
+-#include "xfs_inode_item.h"
+-#include "xfs_inode.h"
+-#include "xfs_bmap.h"
+-#include "xfs_da_btree.h"
+-#include "xfs_attr.h"
+-#include "xfs_attr_leaf.h"
+-
+-int
+-xfs_attr_fetch(xfs_inode_t *ip, char *name, char *value, int valuelen)
+-{
+-	xfs_da_args_t args;
+-	int error;
+-
+-	if (XFS_IFORK_Q(ip) == 0)
+-		return ENOATTR;
+-	/*
+-	 * Do the argument setup for the xfs_attr routines.
+-	 */
+-	memset((char *)&args, 0, sizeof(args));
+-	args.dp = ip;
+-	args.flags = ATTR_ROOT;
+-	args.whichfork = XFS_ATTR_FORK;
+-	args.name = name;
+-	args.namelen = strlen(name);
+-	args.value = value;
+-	args.valuelen = valuelen;
+-	args.hashval = xfs_da_hashname(args.name, args.namelen);
+-	args.oknoent = 1;
+-
+-	/*
+-	 * Decide on what work routines to call based on the inode size.
+-	 */
+-	if (args.dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
+-		error = xfs_attr_shortform_getvalue(&args);
+-	else if (xfs_bmap_one_block(args.dp, XFS_ATTR_FORK))
+-		error = xfs_attr_leaf_get(&args);
+-	else
+-		error = xfs_attr_node_get(&args);
+-
+-	if (error == EEXIST)
+-		error = 0;
+-
+-	return(error);
+-}
+--- linux-2.6.0-test6/fs/xfs/xfs_bmap.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_bmap.c	2003-10-05 00:33:24.000000000 -0700
+@@ -5553,7 +5553,7 @@ xfs_getbmap(
+ 	    && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)
+ 	    && whichfork == XFS_DATA_FORK) {
+ 
+-		error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, 0, 0, 0, NULL);
++		error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL);
+ 		if (error)
+ 			return XFS_ERROR(error);
+ 	}
+--- linux-2.6.0-test6/fs/xfs/xfs_buf.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/xfs/xfs_buf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -194,7 +194,10 @@ extern inline xfs_caddr_t xfs_buf_offset
+ 	(bp)->pb_target = (target)
+ 
+ #define XFS_BUF_TARGET(bp)	((bp)->pb_target)
+-#define XFS_BUF_TARGET_DEV(bp)	((bp)->pb_target->pbr_dev)
++
++#define XFS_BUFTARG_NAME(target) \
++	({ char __b[BDEVNAME_SIZE]; bdevname((target->pbr_bdev), __b); __b; })
++	
+ #define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
+ #define XFS_BUF_SET_VTYPE(bp, type)
+ #define XFS_BUF_SET_REF(bp, ref)
+--- linux-2.6.0-test6/fs/xfs/xfs_buf_item.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/fs/xfs/xfs_buf_item.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1007,7 +1007,7 @@ xfs_buf_iodone_callbacks(
+ {
+ 	xfs_log_item_t	*lip;
+ 	static ulong	lasttime;
+-	static dev_t	lastdev;
++	static xfs_buftarg_t *lasttarg;
+ 	xfs_mount_t	*mp;
+ 
+ 	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
+@@ -1045,15 +1045,15 @@ xfs_buf_iodone_callbacks(
+ 			return;
+ 		}
+ 
+-		if ((XFS_BUF_TARGET_DEV(bp) != lastdev) ||
++		if ((XFS_BUF_TARGET(bp) != lasttarg) ||
+ 		    (time_after(jiffies, (lasttime + 5*HZ)))) {
+ 			lasttime = jiffies;
+ 			prdev("XFS write error in file system meta-data "
+ 			      "block 0x%Lx in %s",
+-			      XFS_BUF_TARGET_DEV(bp),
++			      XFS_BUF_TARGET(bp),
+ 			      XFS_BUF_ADDR(bp), mp->m_fsname);
+ 		}
+-		lastdev = XFS_BUF_TARGET_DEV(bp);
++		lasttarg = XFS_BUF_TARGET(bp);
+ 
+ 		if (XFS_BUF_ISASYNC(bp)) {
+ 			/*
+--- linux-2.6.0-test6/fs/xfs/xfs_da_btree.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_da_btree.c	2003-10-05 00:33:24.000000000 -0700
+@@ -2450,7 +2450,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bp
+ 	dabuf->dirty = 0;
+ #ifdef XFS_DABUF_DEBUG
+ 	dabuf->ra = ra;
+-	dabuf->dev = XFS_BUF_TARGET_DEV(bps[0]);
++	dabuf->target = XFS_BUF_TARGET(bps[0]);
+ 	dabuf->blkno = XFS_BUF_ADDR(bps[0]);
+ #endif
+ 	if (nbuf == 1) {
+@@ -2480,7 +2480,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bp
+ 		s = mutex_spinlock(&xfs_dabuf_global_lock);
+ 		for (p = xfs_dabuf_global_list; p; p = p->next) {
+ 			ASSERT(p->blkno != dabuf->blkno ||
+-			       p->dev != dabuf->dev);
++			       p->target != dabuf->target);
+ 		}
+ 		dabuf->prev = NULL;
+ 		if (xfs_dabuf_global_list)
+--- linux-2.6.0-test6/fs/xfs/xfs_da_btree.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_da_btree.h	2003-10-05 00:33:24.000000000 -0700
+@@ -212,7 +212,7 @@ typedef struct xfs_dabuf {
+ 	inst_t		*ra;		/* return address of caller to make */
+ 	struct xfs_dabuf *next;		/* next in global chain */
+ 	struct xfs_dabuf *prev;		/* previous in global chain */
+-	dev_t		dev;		/* device for buffer */
++	struct xfs_buftarg *target;	/* device for buffer */
+ 	xfs_daddr_t	blkno;		/* daddr first in bps[0] */
+ #endif
+ 	struct xfs_buf	*bps[1];	/* actually nbuf of these */
+--- linux-2.6.0-test6/fs/xfs/xfs_dinode.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_dinode.h	2003-10-05 00:33:24.000000000 -0700
+@@ -439,25 +439,21 @@ void xfs_dfork_next_set(xfs_dinode_t *di
+ /*
+  * File types (mode field)
+  */
+-#define	IFMT		0170000		/* type of file */
+-#define	IFIFO		0010000		/* named pipe (fifo) */
+-#define	IFCHR		0020000		/* character special */
+-#define	IFDIR		0040000		/* directory */
+-#define	IFBLK		0060000		/* block special */
+-#define	IFREG		0100000		/* regular */
+-#define	IFLNK		0120000		/* symbolic link */
+-#define	IFSOCK		0140000		/* socket */
+-#define	IFMNT		0160000		/* mount point */
++#define	IFMT		S_IFMT
++#define	IFSOCK		S_IFSOCK
++#define	IFLNK		S_IFLNK
++#define	IFREG		S_IFREG
++#define	IFBLK		S_IFBLK
++#define	IFDIR		S_IFDIR
++#define	IFCHR		S_IFCHR
++#define	IFIFO		S_IFIFO
+ 
+-/*
+- * File execution and access modes.
+- */
+-#define	ISUID		04000		/* set user id on execution */
+-#define	ISGID		02000		/* set group id on execution */
+-#define	ISVTX		01000		/* sticky directory */
+-#define	IREAD		0400		/* read, write, execute permissions */
+-#define	IWRITE		0200
+-#define	IEXEC		0100
++#define	ISUID		S_ISUID
++#define	ISGID		S_ISGID
++#define	ISVTX		S_ISVTX
++#define	IREAD		S_IRUSR
++#define	IWRITE		S_IWUSR
++#define	IEXEC		S_IXUSR
+ 
+ #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_DINODE)
+ xfs_dinode_t *xfs_buf_to_dinode(struct xfs_buf *bp);
+--- linux-2.6.0-test6/fs/xfs/xfs_dir2.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_dir2.c	2003-10-05 00:33:24.000000000 -0700
+@@ -773,7 +773,7 @@ xfs_dir2_put_dirent64_uio(
+ 	idbp->d_off = pa->cook;
+ 	idbp->d_name[namelen] = '\0';
+ 	memcpy(idbp->d_name, pa->name, namelen);
+-	rval = uiomove((caddr_t)idbp, reclen, UIO_READ, uio);
++	rval = uio_read((caddr_t)idbp, reclen, uio);
+ 	pa->done = (rval == 0);
+ 	return rval;
+ }
+--- linux-2.6.0-test6/fs/xfs/xfs_dir_leaf.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_dir_leaf.c	2003-10-05 00:33:24.000000000 -0700
+@@ -2225,7 +2225,7 @@ xfs_dir_put_dirent64_uio(xfs_dir_put_arg
+ 	idbp->d_off = pa->cook.o;
+ 	idbp->d_name[namelen] = '\0';
+ 	memcpy(idbp->d_name, pa->name, namelen);
+-	retval = uiomove((caddr_t)idbp, reclen, UIO_READ, uio);
++	retval = uio_read((caddr_t)idbp, reclen, uio);
+ 	pa->done = (retval == 0);
+ 	return retval;
+ }
+--- linux-2.6.0-test6/fs/xfs/xfs_error.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_error.c	2003-10-05 00:33:24.000000000 -0700
+@@ -329,6 +329,7 @@ xfs_corruption_error(
+ 	int		linenum,
+ 	inst_t		*ra)
+ {
+-	xfs_hex_dump(p, 16);
++	if (level <= xfs_error_level)
++		xfs_hex_dump(p, 16);
+ 	xfs_error_report(tag, level, mp, fname, linenum, ra);
+ }
+--- linux-2.6.0-test6/fs/xfs/xfs_error.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_error.h	2003-10-05 00:33:24.000000000 -0700
+@@ -32,8 +32,8 @@
+ #ifndef	__XFS_ERROR_H__
+ #define	__XFS_ERROR_H__
+ 
+-#define prdev(fmt,dev,args...) \
+-	printk("XFS: device %u:%u- " fmt "\n", MAJOR(dev), MINOR(dev), ## args)
++#define prdev(fmt,targ,args...) \
++	printk("XFS: device %s- " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
+ 
+ #define XFS_ERECOVER	1	/* Failure to recover log */
+ #define XFS_ELOGSTAT	2	/* Failure to stat log in user space */
+--- linux-2.6.0-test6/fs/xfs/xfs_fs.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_fs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -392,22 +392,17 @@ typedef struct xfs_fsop_attrmulti_handle
+ } xfs_fsop_attrmulti_handlereq_t;
+ 
+ /*
+- * File system identifier. Should be unique (at least per machine).
++ * per machine unique filesystem identifier types.
+  */
+-typedef struct {
+-	__u32 val[2];			/* file system id type */
+-} xfs_fsid_t;
++typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
++
+ 
+-/*
+- * File identifier.  Should be unique per filesystem on a single machine.
+- * This is typically called by a stateless file server in order to generate
+- * "file handles".
+- */
+ #ifndef HAVE_FID
+ #define MAXFIDSZ	46
++
+ typedef struct fid {
+ 	__u16		fid_len;		/* length of data in bytes */
+-	unsigned char	fid_data[MAXFIDSZ];	/* data (variable length)  */
++	unsigned char	fid_data[MAXFIDSZ];	/* data (fid_len worth)  */
+ } fid_t;
+ #endif
+ 
+--- linux-2.6.0-test6/fs/xfs/xfsidbg.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfsidbg.c	2003-10-05 00:33:24.000000000 -0700
+@@ -3739,9 +3739,9 @@ xfsidbg_xdabuf(xfs_dabuf_t *dabuf)
+ 		kdb_printf(" %d:0x%p", i, dabuf->bps[i]);
+ 	kdb_printf("\n");
+ #ifdef XFS_DABUF_DEBUG
+-	kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev %u:%u blkno 0x%x\n",
++	kdb_printf(" ra 0x%x prev 0x%x next 0x%x dev %s blkno 0x%x\n",
+ 		dabuf->ra, dabuf->prev, dabuf->next,
+-		MAJOR(dabuf->dev), MINOR(dabuf->dev), dabuf->blkno);
++		XFS_BUFTARG_NAME(dabuf->dev), dabuf->blkno);
+ #endif
+ }
+ 
+@@ -4269,9 +4269,8 @@ xfsidbg_xlog(xlog_t *log)
+ 			xfsidbg_get_cstate(log->l_covered_state));
+ 	kdb_printf("flags: ");
+ 	printflags(log->l_flags, t_flags,"log");
+-	kdb_printf("  dev: %u:%u logBBstart: %lld logsize: %d logBBsize: %d\n",
+-		MAJOR(log->l_dev), MINOR(log->l_dev),
+-		(long long) log->l_logBBstart,
++	kdb_printf("  dev: %s logBBstart: %lld logsize: %d logBBsize: %d\n",
++		XFS_BUFTARG_NAME(log->l_targ), (long long) log->l_logBBstart,
+ 		log->l_logsize,log->l_logBBsize);
+ 	kdb_printf("curr_cycle: %d  prev_cycle: %d  curr_block: %d  prev_block: %d\n",
+ 	     log->l_curr_cycle, log->l_prev_cycle, log->l_curr_block,
+@@ -4646,14 +4645,14 @@ xfsidbg_xmount(xfs_mount_t *mp)
+ 		XFS_MTOVFS(mp), mp->m_tid, &mp->m_ail_lock, &mp->m_ail);
+ 	kdb_printf("ail_gen 0x%x &sb 0x%p\n",
+ 		mp->m_ail_gen, &mp->m_sb);
+-	kdb_printf("sb_lock 0x%p sb_bp 0x%p dev %u:%u logdev %u:%u rtdev %u:%u\n",
++	kdb_printf("sb_lock 0x%p sb_bp 0x%p dev %s logdev %s rtdev %s\n",
+ 		&mp->m_sb_lock, mp->m_sb_bp,
+-		mp->m_ddev_targp ? MAJOR(mp->m_ddev_targp->pbr_dev) : 0,
+-		mp->m_ddev_targp ? MINOR(mp->m_ddev_targp->pbr_dev) : 0,
+-		mp->m_logdev_targp ? MAJOR(mp->m_logdev_targp->pbr_dev) : 0,
+-		mp->m_logdev_targp ? MINOR(mp->m_logdev_targp->pbr_dev) : 0,
+-		mp->m_rtdev_targp ? MAJOR(mp->m_rtdev_targp->pbr_dev) : 0,
+-		mp->m_rtdev_targp ? MINOR(mp->m_rtdev_targp->pbr_dev) : 0);
++		mp->m_ddev_targp ?
++			XFS_BUFTARG_NAME(mp->m_ddev_targp) : "none",
++		mp->m_logdev_targp ?
++			XFS_BUFTARG_NAME(mp->m_logdev_targp) : "none",
++		mp->m_rtdev_targp ?
++			XFS_BUFTARG_NAME(mp->m_rtdev_targp) : "none");
+ 	kdb_printf("bsize %d agfrotor %d agirotor %d ihash 0x%p ihsize %d\n",
+ 		mp->m_bsize, mp->m_agfrotor, mp->m_agirotor,
+ 		mp->m_ihash, mp->m_ihsize);
+@@ -4824,9 +4823,8 @@ xfsidbg_xnode(xfs_inode_t *ip)
+ 		ip->i_mnext,
+ 		ip->i_mprev,
+ 		XFS_ITOV_NULL(ip));
+-	kdb_printf("dev %u:%u ino %s\n",
+-		MAJOR(ip->i_mount->m_dev),
+-		MINOR(ip->i_mount->m_dev),
++	kdb_printf("dev %s ino %s\n",
++		XFS_BUFTARG_NAME(ip->i_mount->m_ddev_targp),
+ 		xfs_fmtino(ip->i_ino, ip->i_mount));
+ 	kdb_printf("blkno 0x%llx len 0x%x boffset 0x%x\n",
+ 		(long long) ip->i_blkno,
+--- linux-2.6.0-test6/fs/xfs/xfs_inode.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -408,8 +408,9 @@ xfs_itobp(
+ 		if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
+ 				 XFS_RANDOM_ITOBP_INOTOBP))) {
+ #ifdef DEBUG
+-			prdev("bad inode magic/vsn daddr 0x%llx #%d (magic=%x)",
+-				mp->m_dev, (unsigned long long)imap.im_blkno, i,
++			prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
++				mp->m_ddev_targp,
++				(unsigned long long)imap.im_blkno, i,
+ 				INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
+ #endif
+ 			XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH,
+--- linux-2.6.0-test6/fs/xfs/xfs_log.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_log.c	2003-10-05 00:33:24.000000000 -0700
+@@ -65,7 +65,7 @@ STATIC int	 xlog_bdstrat_cb(struct xfs_b
+ STATIC int	 xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket,
+ 				    xlog_in_core_t **, xfs_lsn_t *);
+ STATIC xlog_t *  xlog_alloc_log(xfs_mount_t	*mp,
+-				dev_t		log_dev,
++				xfs_buftarg_t	*log_target,
+ 				xfs_daddr_t	blk_offset,
+ 				int		num_bblks);
+ STATIC int	 xlog_space_left(xlog_t *log, int cycle, int bytes);
+@@ -155,7 +155,7 @@ int xlog_error_mod = 33;
+  */
+ #if defined(XLOG_NOLOG) || defined(DEBUG)
+ int   xlog_debug = 1;
+-dev_t xlog_devt  = 0;
++xfs_buftarg_t *xlog_target;
+ #endif
+ 
+ #if defined(XFS_LOG_TRACE)
+@@ -274,7 +274,7 @@ xfs_log_done(xfs_mount_t	*mp,
+ 	xfs_lsn_t	lsn	= 0;
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return 0;
+ #endif
+ 
+@@ -339,7 +339,7 @@ xfs_log_force(xfs_mount_t *mp,
+ 	xlog_t *log = mp->m_log;
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return 0;
+ #endif
+ 
+@@ -378,7 +378,7 @@ xfs_log_notify(xfs_mount_t	  *mp,		/* mo
+ 	int	abortflg, spl;
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return 0;
+ #endif
+ 	cb->cb_next = 0;
+@@ -436,7 +436,7 @@ xfs_log_reserve(xfs_mount_t	 *mp,
+ 	int		retval;
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return 0;
+ #endif
+ 	retval = 0;
+@@ -472,7 +472,7 @@ xfs_log_reserve(xfs_mount_t	 *mp,
+  * Mount a log filesystem
+  *
+  * mp		- ubiquitous xfs mount point structure
+- * log_dev	- device number of on-disk log device
++ * log_target	- buftarg of on-disk log device
+  * blk_offset	- Start block # where block size is 512 bytes (BBSIZE)
+  * num_bblocks	- Number of BBSIZE blocks in on-disk log
+  *
+@@ -480,7 +480,7 @@ xfs_log_reserve(xfs_mount_t	 *mp,
+  */
+ int
+ xfs_log_mount(xfs_mount_t	*mp,
+-	      dev_t		log_dev,
++	      xfs_buftarg_t	*log_target,
+ 	      xfs_daddr_t	blk_offset,
+ 	      int		num_bblks)
+ {
+@@ -493,12 +493,11 @@ xfs_log_mount(xfs_mount_t	*mp,
+ 		ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
+ 	}
+ 
+-	mp->m_log = xlog_alloc_log(mp, log_dev, blk_offset, num_bblks);
++	mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug) {
+-		cmn_err(CE_NOTE, "log dev: %u:%u",
+-			MAJOR(log_dev), MINOR(log_dev));
++	if (!xlog_debug) {
++		cmn_err(CE_NOTE, "log dev: %s", XFS_BUFTARG_NAME(log_target));
+ 		return 0;
+ 	}
+ #endif
+@@ -606,7 +605,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
+ 	} magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (! xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return 0;
+ #endif
+ 
+@@ -734,9 +733,9 @@ xfs_log_write(xfs_mount_t *	mp,
+ {
+ 	int	error;
+ 	xlog_t *log = mp->m_log;
+-#if defined(DEBUG) || defined(XLOG_NOLOG)
+ 
+-	if (! xlog_debug && xlog_devt == log->l_dev) {
++#if defined(DEBUG) || defined(XLOG_NOLOG)
++	if (!xlog_debug && xlog_target == log->l_targ) {
+ 		*start_lsn = 0;
+ 		return 0;
+ 	}
+@@ -761,7 +760,7 @@ xfs_log_move_tail(xfs_mount_t	*mp,
+ 	SPLDECL(s);
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+-	if (!xlog_debug && xlog_devt == log->l_dev)
++	if (!xlog_debug && xlog_target == log->l_targ)
+ 		return;
+ #endif
+ 	/* XXXsup tmp */
+@@ -1059,14 +1058,14 @@ xlog_get_iclog_buffer_size(xfs_mount_t	*
+ 	/*
+ 	 * When logbufs == 0, someone has disabled the log from the FSTAB
+ 	 * file.  This is not a documented feature.  We need to set xlog_debug
+-	 * to zero (this deactivates the log) and set xlog_devt to the
++	 * to zero (this deactivates the log) and set xlog_target to the
+ 	 * appropriate dev_t.  Only one filesystem may be affected as such
+ 	 * since this is just a performance hack to test what we might be able
+ 	 * to get if the log were not present.
+ 	 */
+ 	if (mp->m_logbufs == 0) {
+ 		xlog_debug = 0;
+-		xlog_devt = log->l_dev;
++		xlog_target = log->l_targ;
+ 		log->l_iclog_bufs = XLOG_MIN_ICLOGS;
+ 	} else
+ #endif
+@@ -1089,8 +1088,8 @@ xlog_get_iclog_buffer_size(xfs_mount_t	*
+ 
+ #if defined(DEBUG) || defined(XLOG_NOLOG)
+ 		/* We are reactivating a filesystem after it was active */
+-		if (log->l_dev == xlog_devt) {
+-			xlog_devt = 1;
++		if (log->l_targ == xlog_target) {
++			xlog_target = 1; /* XXX(hch): WTF? */
+ 			xlog_debug = 1;
+ 		}
+ #endif
+@@ -1176,7 +1175,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t	*
+  */
+ STATIC xlog_t *
+ xlog_alloc_log(xfs_mount_t	*mp,
+-	       dev_t		log_dev,
++	       xfs_buftarg_t	*log_target,
+ 	       xfs_daddr_t	blk_offset,
+ 	       int		num_bblks)
+ {
+@@ -1191,7 +1190,7 @@ xlog_alloc_log(xfs_mount_t	*mp,
+ 	log = (xlog_t *)kmem_zalloc(sizeof(xlog_t), KM_SLEEP);
+ 
+ 	log->l_mp	   = mp;
+-	log->l_dev	   = log_dev;
++	log->l_targ	   = log_target;
+ 	log->l_logsize     = BBTOB(num_bblks);
+ 	log->l_logBBstart  = blk_offset;
+ 	log->l_logBBsize   = num_bblks;
+--- linux-2.6.0-test6/fs/xfs/xfs_log.h	2003-06-14 12:18:52.000000000 -0700
++++ 25/fs/xfs/xfs_log.h	2003-10-05 00:33:24.000000000 -0700
+@@ -153,10 +153,10 @@ xfs_lsn_t xfs_log_done(struct xfs_mount 
+ int	  xfs_log_force(struct xfs_mount *mp,
+ 			xfs_lsn_t	 lsn,
+ 			uint		 flags);
+-int	  xfs_log_mount(struct xfs_mount *mp,
+-			dev_t		 log_dev,
+-			xfs_daddr_t		 start_block,
+-			int		 num_bblocks);
++int	  xfs_log_mount(struct xfs_mount	*mp,
++			struct xfs_buftarg	*log_target,
++			xfs_daddr_t		start_block,
++			int		 	num_bblocks);
+ int	  xfs_log_mount_finish(struct xfs_mount *mp, int);
+ void	  xfs_log_move_tail(struct xfs_mount	*mp,
+ 			    xfs_lsn_t		tail_lsn);
+--- linux-2.6.0-test6/fs/xfs/xfs_log_priv.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/xfs/xfs_log_priv.h	2003-10-05 00:33:24.000000000 -0700
+@@ -504,7 +504,7 @@ typedef struct log {
+ 	struct xfs_mount	*l_mp;	        /* mount point */
+ 	struct xfs_buf		*l_xbuf;        /* extra buffer for log
+ 						 * wrapping */
+-	dev_t			l_dev;	        /* dev_t of log */
++	struct xfs_buftarg	*l_targ;        /* buftarg of log */
+ 	xfs_daddr_t		l_logBBstart;   /* start block of log */
+ 	int			l_logsize;      /* size of log in bytes */
+ 	int			l_logBBsize;    /* size of log in BB chunks */
+--- linux-2.6.0-test6/fs/xfs/xfs_log_recover.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_log_recover.c	2003-10-05 00:33:24.000000000 -0700
+@@ -2179,8 +2179,8 @@ xlog_recover_do_buffer_trans(
+ 		break;
+ 	default:
+ 		xfs_fs_cmn_err(CE_ALERT, log->l_mp,
+-			"xfs_log_recover: unknown buffer type 0x%x, dev %u:%u",
+-			buf_f->blf_type, MAJOR(log->l_dev), MINOR(log->l_dev));
++			"xfs_log_recover: unknown buffer type 0x%x, dev %s",
++			buf_f->blf_type, XFS_BUFTARG_NAME(log->l_targ));
+ 		XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
+ 				 XFS_ERRLEVEL_LOW, log->l_mp);
+ 		return XFS_ERROR(EFSCORRUPTED);
+@@ -3889,9 +3889,8 @@ xlog_recover(
+ 		}
+ 
+ 		cmn_err(CE_NOTE,
+-			"Starting XFS recovery on filesystem: %s (dev: %d/%d)",
+-			log->l_mp->m_fsname, MAJOR(log->l_dev),
+-			MINOR(log->l_dev));
++			"Starting XFS recovery on filesystem: %s (dev: %s)",
++			log->l_mp->m_fsname, XFS_BUFTARG_NAME(log->l_targ));
+ 
+ 		error = xlog_do_recover(log, head_blk, tail_blk);
+ 		log->l_flags |= XLOG_RECOVERY_NEEDED;
+@@ -3939,10 +3938,8 @@ xlog_recover_finish(
+ 		xlog_recover_check_summary(log);
+ 
+ 		cmn_err(CE_NOTE,
+-			"Ending XFS recovery on filesystem: %s (dev: %d/%d)",
+-			log->l_mp->m_fsname, MAJOR(log->l_dev),
+-			MINOR(log->l_dev));
+-
++			"Ending XFS recovery on filesystem: %s (dev: %s)",
++			log->l_mp->m_fsname, XFS_BUFTARG_NAME(log->l_targ));
+ 		log->l_flags &= ~XLOG_RECOVERY_NEEDED;
+ 	} else {
+ 		cmn_err(CE_DEBUG,
+--- linux-2.6.0-test6/fs/xfs/xfs_mount.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_mount.c	2003-10-05 00:33:24.000000000 -0700
+@@ -285,9 +285,9 @@ xfs_mount_validate_sb(
+ #if !XFS_BIG_BLKNOS
+ 	if (unlikely(
+ 	    (sbp->sb_dblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
+-		> INT_MAX ||
++		> UINT_MAX ||
+ 	    (sbp->sb_rblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT))
+-		> INT_MAX)) {
++		> UINT_MAX)) {
+ 		cmn_err(CE_WARN,
+ 	"XFS: File system is too large to be mounted on this system.");
+ 		return XFS_ERROR(E2BIG);
+@@ -949,7 +949,7 @@ xfs_mountfs(
+ 	 * log's mount-time initialization. Perform 1st part recovery if needed
+ 	 */
+ 	if (likely(sbp->sb_logblocks > 0)) {	/* check for volume case */
+-		error = xfs_log_mount(mp, mp->m_logdev_targp->pbr_dev,
++		error = xfs_log_mount(mp, mp->m_logdev_targp,
+ 				      XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
+ 				      XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
+ 		if (error) {
+@@ -980,7 +980,7 @@ xfs_mountfs(
+ 	if (unlikely((rip->i_d.di_mode & IFMT) != IFDIR)) {
+ 		cmn_err(CE_WARN, "XFS: corrupted root inode");
+ 		prdev("Root inode %llu is not a directory",
+-		      mp->m_dev, (unsigned long long)rip->i_ino);
++		      mp->m_ddev_targp, (unsigned long long)rip->i_ino);
+ 		xfs_iunlock(rip, XFS_ILOCK_EXCL);
+ 		XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
+ 				 mp);
+--- linux-2.6.0-test6/fs/xfs/xfs_mount.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_mount.h	2003-10-05 00:33:24.000000000 -0700
+@@ -91,10 +91,10 @@ struct xfs_bmap_free;
+  * Prototypes and functions for the Data Migration subsystem.
+  */
+ 
+-typedef int	(*xfs_send_data_t)(int, struct bhv_desc *,
++typedef int	(*xfs_send_data_t)(int, struct vnode *,
+ 			xfs_off_t, size_t, int, vrwlock_t *);
+ typedef int	(*xfs_send_mmap_t)(struct vm_area_struct *, uint);
+-typedef int	(*xfs_send_destroy_t)(struct bhv_desc *, dm_right_t);
++typedef int	(*xfs_send_destroy_t)(struct vnode *, dm_right_t);
+ typedef int	(*xfs_send_namesp_t)(dm_eventtype_t, struct vnode *,
+ 			dm_right_t, struct vnode *, dm_right_t,
+ 			char *, char *, mode_t, int, int);
+@@ -109,12 +109,12 @@ typedef struct xfs_dmops {
+ 	xfs_send_unmount_t	xfs_send_unmount;
+ } xfs_dmops_t;
+ 
+-#define XFS_SEND_DATA(mp, ev,bdp,off,len,fl,lock) \
+-	(*(mp)->m_dm_ops.xfs_send_data)(ev,bdp,off,len,fl,lock)
++#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \
++	(*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock)
+ #define XFS_SEND_MMAP(mp, vma,fl) \
+ 	(*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl)
+-#define XFS_SEND_DESTROY(mp, bdp,right) \
+-	(*(mp)->m_dm_ops.xfs_send_destroy)(bdp,right)
++#define XFS_SEND_DESTROY(mp, vp,right) \
++	(*(mp)->m_dm_ops.xfs_send_destroy)(vp,right)
+ #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
+ 	(*(mp)->m_dm_ops.xfs_send_namesp)(ev,b1,r1,b2,r2,n1,n2,mode,rval,fl)
+ #define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \
+--- linux-2.6.0-test6/fs/xfs/xfs_rw.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_rw.c	2003-10-05 00:33:24.000000000 -0700
+@@ -260,11 +260,10 @@ xfs_ioerror_alert(
+ 	xfs_daddr_t		blkno)
+ {
+ 	cmn_err(CE_ALERT,
+- "I/O error in filesystem (\"%s\") meta-data dev %u:%u block 0x%llx"
++ "I/O error in filesystem (\"%s\") meta-data dev %s block 0x%llx"
+  "       (\"%s\") error %d buf count %u",
+ 		(!mp || !mp->m_fsname) ? "(fs name not set)" : mp->m_fsname,
+-		MAJOR(XFS_BUF_TARGET_DEV(bp)),
+-		MINOR(XFS_BUF_TARGET_DEV(bp)),
++		XFS_BUFTARG_NAME(bp->pb_target),
+ 		(__uint64_t)blkno,
+ 		func,
+ 		XFS_BUF_GETERROR(bp),
+--- linux-2.6.0-test6/fs/xfs/xfs_trans_buf.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/fs/xfs/xfs_trans_buf.c	2003-10-05 00:33:24.000000000 -0700
+@@ -264,7 +264,7 @@ xfs_trans_getsb(xfs_trans_t	*tp,
+ }
+ 
+ #ifdef DEBUG
+-dev_t	xfs_error_dev = 0;
++xfs_buftarg_t *xfs_error_target;
+ int	xfs_do_error;
+ int	xfs_req_num;
+ int	xfs_error_mod = 33;
+@@ -322,7 +322,7 @@ xfs_trans_read_buf(
+ 		}
+ #ifdef DEBUG
+ 		if (xfs_do_error && (bp != NULL)) {
+-			if (xfs_error_dev == target->pbr_dev) {
++			if (xfs_error_target == target) {
+ 				if (((xfs_req_num++) % xfs_error_mod) == 0) {
+ 					xfs_buf_relse(bp);
+ 					printk("Returning error!\n");
+@@ -425,7 +425,7 @@ xfs_trans_read_buf(
+ 	}
+ #ifdef DEBUG
+ 	if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
+-		if (xfs_error_dev == target->pbr_dev) {
++		if (xfs_error_target == target) {
+ 			if (((xfs_req_num++) % xfs_error_mod) == 0) {
+ 				xfs_force_shutdown(tp->t_mountp,
+ 						   XFS_METADATA_IO_ERROR);
+--- linux-2.6.0-test6/fs/xfs/xfs_trans.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/xfs/xfs_trans.h	2003-10-05 00:33:24.000000000 -0700
+@@ -995,7 +995,6 @@ void		xfs_trans_dquot_buf(xfs_trans_t *,
+ void		xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
+ int		xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
+ 			       xfs_ino_t , uint, struct xfs_inode **);
+-void		xfs_trans_iput(xfs_trans_t *, struct xfs_inode *, uint);
+ void		xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
+ void		xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
+ void		xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
+--- linux-2.6.0-test6/fs/xfs/xfs_trans_inode.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/fs/xfs/xfs_trans_inode.c	2003-10-05 00:33:24.000000000 -0700
+@@ -188,106 +188,6 @@ xfs_trans_iget(
+ 
+ 
+ /*
+- * Release the inode ip which was previously acquired with xfs_trans_iget()
+- * or added with xfs_trans_ijoin(). This will decrement the lock
+- * recursion count of the inode item.  If the count goes to less than 0,
+- * the inode will be unlocked and disassociated from the transaction.
+- *
+- * If the inode has been modified within the transaction, it will not be
+- * unlocked until the transaction commits.
+- */
+-void
+-xfs_trans_iput(
+-	xfs_trans_t	*tp,
+-	xfs_inode_t	*ip,
+-	uint		lock_flags)
+-{
+-	xfs_inode_log_item_t	*iip;
+-	xfs_log_item_desc_t	*lidp;
+-
+-	/*
+-	 * If the transaction pointer is NULL, just call xfs_iput().
+-	 */
+-	if (tp == NULL) {
+-		xfs_iput(ip, lock_flags);
+-	}
+-
+-	ASSERT(ip->i_transp == tp);
+-	iip = ip->i_itemp;
+-	ASSERT(iip != NULL);
+-
+-	/*
+-	 * Find the item descriptor pointing to this inode's
+-	 * log item.  It must be there.
+-	 */
+-	lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)iip);
+-	ASSERT(lidp != NULL);
+-	ASSERT(lidp->lid_item == (xfs_log_item_t*)iip);
+-
+-	/*
+-	 * Be consistent about the bookkeeping for the inode's
+-	 * io lock, but it doesn't mean much really.
+-	 */
+-	ASSERT((iip->ili_flags & XFS_ILI_IOLOCKED_ANY) != XFS_ILI_IOLOCKED_ANY);
+-	if (lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)) {
+-		ASSERT(iip->ili_flags & XFS_ILI_IOLOCKED_ANY);
+-		ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
+-		       (iip->ili_flags & XFS_ILI_IOLOCKED_EXCL));
+-		ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
+-		       (iip->ili_flags &
+-			(XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED)));
+-		if (iip->ili_iolock_recur > 0) {
+-			iip->ili_iolock_recur--;
+-		}
+-	}
+-
+-	/*
+-	 * If the release is just for a recursive lock on the inode lock,
+-	 * then decrement the count and return.  We can assert that
+-	 * the caller is dropping an EXCL lock on the inode, because
+-	 * inode must be locked EXCL within transactions.
+-	 */
+-	ASSERT(lock_flags & XFS_ILOCK_EXCL);
+-	if (iip->ili_ilock_recur > 0) {
+-		iip->ili_ilock_recur--;
+-		return;
+-	}
+-	ASSERT(iip->ili_iolock_recur == 0);
+-
+-	/*
+-	 * If the inode was dirtied within this transaction, it cannot
+-	 * be released until the transaction commits.
+-	 */
+-	if (lidp->lid_flags & XFS_LID_DIRTY) {
+-		return;
+-	}
+-
+-	xfs_trans_free_item(tp, lidp);
+-
+-	/*
+-	 * Clear the hold and iolocked flags in the inode log item.
+-	 * We wouldn't want the next user of the inode to
+-	 * get confused.  Assert that if the iolocked flag is set
+-	 * in the item then we are unlocking it in the call to xfs_iput()
+-	 * below.
+-	 */
+-	ASSERT((!(iip->ili_flags & XFS_ILI_IOLOCKED_ANY)) ||
+-	       (lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)));
+-	if (iip->ili_flags & (XFS_ILI_HOLD | XFS_ILI_IOLOCKED_ANY)) {
+-		iip->ili_flags &= ~(XFS_ILI_HOLD | XFS_ILI_IOLOCKED_ANY);
+-	}
+-
+-	/*
+-	 * Unlike xfs_brelse() the inode log item cannot be
+-	 * freed, because it is embedded within the inode.
+-	 * All we have to do is release the inode.
+-	 */
+-	xfs_iput(ip, lock_flags);
+-	return;
+-}
+-
+-
+-/*
+  * Add the locked inode to the transaction.
+  * The inode must be locked, and it cannot be associated with any
+  * transaction.  The caller must specify the locks already held
+--- linux-2.6.0-test6/fs/xfs/xfs_types.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_types.h	2003-10-05 00:33:24.000000000 -0700
+@@ -83,7 +83,7 @@ typedef __uint64_t __psunsigned_t;
+  * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
+  * as requiring XFS_BIG_BLKNOS to be set.
+  */
+-#if defined(CONFIG_LBD) || (defined(HAVE_SECTOR_T) && (BITS_PER_LONG == 64))
++#if defined(CONFIG_LBD) || (BITS_PER_LONG == 64)
+ # define XFS_BIG_BLKNOS	1
+ # if BITS_PER_LONG == 64
+ #  define XFS_BIG_INUMS	1
+--- linux-2.6.0-test6/fs/xfs/xfs_vfsops.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_vfsops.c	2003-10-05 00:33:24.000000000 -0700
+@@ -1776,7 +1776,6 @@ xfs_showargs(
+ 	};
+ 	struct proc_xfs_info	*xfs_infop;
+ 	struct xfs_mount	*mp = XFS_BHVTOM(bhv);
+-	char			b[BDEVNAME_SIZE];
+ 
+ 	for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
+ 		if (mp->m_flags & xfs_infop->flag)
+@@ -1792,14 +1791,13 @@ xfs_showargs(
+ 	if (mp->m_logbsize > 0)
+ 		seq_printf(m, "," MNTOPT_LOGBSIZE "=%d", mp->m_logbsize);
+ 
+-	if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
++	if (mp->m_ddev_targp != mp->m_logdev_targp)
+ 		seq_printf(m, "," MNTOPT_LOGDEV "=%s",
+-				bdevname(mp->m_logdev_targp->pbr_bdev, b));
++				XFS_BUFTARG_NAME(mp->m_logdev_targp));
+ 
+-	if (mp->m_rtdev_targp &&
+-	    mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
++	if (mp->m_rtdev_targp && mp->m_ddev_targp != mp->m_rtdev_targp)
+ 		seq_printf(m, "," MNTOPT_RTDEV "=%s",
+-				bdevname(mp->m_rtdev_targp->pbr_bdev, b));
++				XFS_BUFTARG_NAME(mp->m_rtdev_targp));
+ 
+ 	if (mp->m_dalign > 0)
+ 		seq_printf(m, "," MNTOPT_SUNIT "=%d",
+--- linux-2.6.0-test6/fs/xfs/xfs_vnodeops.c	2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/xfs/xfs_vnodeops.c	2003-10-05 00:33:24.000000000 -0700
+@@ -144,14 +144,11 @@ xfs_getattr(
+ 		xfs_ilock(ip, XFS_ILOCK_SHARED);
+ 
+ 	vap->va_size = ip->i_d.di_size;
+-	if (vap->va_mask == XFS_AT_SIZE) {
+-		if (!(flags & ATTR_LAZY))
+-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-		return 0;
+-	}
++	if (vap->va_mask == XFS_AT_SIZE)
++		goto all_done;
++
+ 	vap->va_nblocks =
+ 		XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
+-	vap->va_fsid = mp->m_dev;
+ 	vap->va_nodeid = ip->i_ino;
+ #if XFS_BIG_INUMS
+ 	vap->va_nodeid += mp->m_inoadd;
+@@ -163,11 +160,8 @@ xfs_getattr(
+ 	 */
+ 	if ((vap->va_mask &
+ 	    ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID|
+-	      XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0) {
+-		if (!(flags & ATTR_LAZY))
+-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-		return 0;
+-	}
++	      XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0)
++		goto all_done;
+ 
+ 	/*
+ 	 * Copy from in-core inode.
+@@ -194,7 +188,7 @@ xfs_getattr(
+ 			 * stripe size through is not a good
+ 			 * idea for now.
+ 			 */
+-			vap->va_blksize = mp->m_swidth ?
++			vap->va_blocksize = mp->m_swidth ?
+ 				/*
+ 				 * If the underlying volume is a stripe, then
+ 				 * return the stripe width in bytes as the
+@@ -211,7 +205,7 @@ xfs_getattr(
+ 					       mp->m_writeio_log));
+ 
+ #else
+-			vap->va_blksize =
++			vap->va_blocksize =
+ 				/*
+ 				 * Return the largest of the preferred buffer
+ 				 * sizes since doing small I/Os into larger
+@@ -229,13 +223,13 @@ xfs_getattr(
+ 			 * realtime extent size or the realtime volume's
+ 			 * extent size.
+ 			 */
+-			vap->va_blksize = ip->i_d.di_extsize ?
++			vap->va_blocksize = ip->i_d.di_extsize ?
+ 				(ip->i_d.di_extsize << mp->m_sb.sb_blocklog) :
+ 				(mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog);
+ 		}
+ 	} else {
+ 		vap->va_rdev = ip->i_df.if_u2.if_rdev;
+-		vap->va_blksize = BLKDEV_IOSIZE;
++		vap->va_blocksize = BLKDEV_IOSIZE;
+ 	}
+ 
+ 	vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec;
+@@ -251,46 +245,53 @@ xfs_getattr(
+ 	 */
+ 	if ((vap->va_mask &
+ 	     (XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|
+-	      XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) {
+-		if (!(flags & ATTR_LAZY))
+-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-		return 0;
+-	}
++	      XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0)
++		goto all_done;
++
+ 	/*
+ 	 * convert di_flags to xflags
+ 	 */
+-	vap->va_xflags =
+-		((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+-			XFS_XFLAG_REALTIME : 0) |
+-		((ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) ?
+-			XFS_XFLAG_PREALLOC : 0) |
+-	        ((ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) ?
+-		        XFS_XFLAG_IMMUTABLE : 0) |
+-		((ip->i_d.di_flags & XFS_DIFLAG_APPEND) ?
+-		        XFS_XFLAG_APPEND : 0) |
+-		((ip->i_d.di_flags & XFS_DIFLAG_SYNC) ?
+-		        XFS_XFLAG_SYNC : 0) |
+-		((ip->i_d.di_flags & XFS_DIFLAG_NOATIME) ?
+-		        XFS_XFLAG_NOATIME : 0) |
+-		((ip->i_d.di_flags & XFS_DIFLAG_NODUMP) ?
+-		        XFS_XFLAG_NODUMP: 0) |
+-		(XFS_IFORK_Q(ip) ?
+-			XFS_XFLAG_HASATTR : 0);
++	vap->va_xflags = 0;
++	if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
++		vap->va_xflags |= XFS_XFLAG_REALTIME;
++	if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC)
++		vap->va_xflags |= XFS_XFLAG_PREALLOC;
++	if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
++		vap->va_xflags |= XFS_XFLAG_IMMUTABLE;
++	if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
++		vap->va_xflags |= XFS_XFLAG_APPEND;
++	if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
++		vap->va_xflags |= XFS_XFLAG_SYNC;
++	if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
++		vap->va_xflags |= XFS_XFLAG_NOATIME;
++	if (ip->i_d.di_flags & XFS_DIFLAG_NODUMP)
++		vap->va_xflags |= XFS_XFLAG_NODUMP;
++	if (XFS_IFORK_Q(ip))
++		vap->va_xflags |= XFS_XFLAG_HASATTR;
++	/*
++	 * Exit for inode revalidate.  See if any of the rest of
++	 * the fields to be filled in are needed.
++	 */
++	if ((vap->va_mask &
++	     (XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|
++	      XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0)
++		goto all_done;
++
+ 	vap->va_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog;
+ 	vap->va_nextents =
+ 		(ip->i_df.if_flags & XFS_IFEXTENTS) ?
+ 			ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) :
+ 			ip->i_d.di_nextents;
+-	if (ip->i_afp != NULL)
++	if (ip->i_afp)
+ 		vap->va_anextents =
+ 			(ip->i_afp->if_flags & XFS_IFEXTENTS) ?
+ 				ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) :
+ 				 ip->i_d.di_anextents;
+ 	else
+ 		vap->va_anextents = 0;
+-	vap->va_gencount = ip->i_d.di_gen;
+-	vap->va_vcode = 0L;
++	vap->va_gen = ip->i_d.di_gen;
+ 
++ all_done:
+ 	if (!(flags & ATTR_LAZY))
+ 		xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ 	return 0;
+@@ -415,7 +416,7 @@ xfs_setattr(
+ 	} else {
+ 		if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
+ 		    !(flags & ATTR_DMI)) {
+-			code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, bdp,
++			code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
+ 				vap->va_size, 0, AT_DELAY_FLAG(flags), NULL);
+ 			if (code) {
+ 				lock_flags = 0;
+@@ -1042,7 +1043,7 @@ xfs_readlink(
+ 	pathlen = (int)ip->i_d.di_size;
+ 
+ 	if (ip->i_df.if_flags & XFS_IFINLINE) {
+-		error = uiomove(ip->i_df.if_u1.if_data, pathlen, UIO_READ, uiop);
++		error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
+ 	}
+ 	else {
+ 		/*
+@@ -1073,8 +1074,7 @@ xfs_readlink(
+ 				byte_cnt = pathlen;
+ 			pathlen -= byte_cnt;
+ 
+-			error = uiomove(XFS_BUF_PTR(bp), byte_cnt,
+-					 UIO_READ, uiop);
++			error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
+ 			xfs_buf_relse (bp);
+ 		}
+ 
+@@ -1729,7 +1729,7 @@ xfs_inactive(
+ 
+ 	if (ip->i_d.di_nlink == 0 &&
+ 	    DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
+-		(void) XFS_SEND_DESTROY(mp, bdp, DM_RIGHT_NULL);
++		(void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL);
+ 	}
+ 
+ 	error = 0;
+@@ -4163,7 +4163,7 @@ xfs_alloc_file_space(
+ 		end_dmi_offset = offset+len;
+ 		if (end_dmi_offset > ip->i_d.di_size)
+ 			end_dmi_offset = ip->i_d.di_size;
+-		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOBHV(ip),
++		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
+ 			offset, end_dmi_offset - offset,
+ 			0, NULL);
+ 		if (error)
+@@ -4410,7 +4410,7 @@ xfs_free_file_space(
+ 	    DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
+ 		if (end_dmi_offset > ip->i_d.di_size)
+ 			end_dmi_offset = ip->i_d.di_size;
+-		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOBHV(ip),
++		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
+ 				offset, end_dmi_offset - offset,
+ 				AT_DELAY_FLAG(attr_flags), NULL);
+ 		if (error)
+--- linux-2.6.0-test6/include/acpi/acconfig.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/acpi/acconfig.h	2003-10-05 00:33:24.000000000 -0700
+@@ -64,7 +64,7 @@
+ 
+ /* Version string */
+ 
+-#define ACPI_CA_VERSION                 0x20030813
++#define ACPI_CA_VERSION                 0x20030918
+ 
+ /* Maximum objects in the various object caches */
+ 
+--- linux-2.6.0-test6/include/acpi/acdisasm.h	2003-06-14 12:18:22.000000000 -0700
++++ 25/include/acpi/acdisasm.h	2003-10-05 00:33:24.000000000 -0700
+@@ -152,10 +152,6 @@ void
+ acpi_dm_decode_internal_object (
+ 	union acpi_operand_object       *obj_desc);
+ 
+-void
+-acpi_dm_decode_node (
+-	struct acpi_namespace_node      *node);
+-
+ u32
+ acpi_dm_block_type (
+ 	union acpi_parse_object         *op);
+--- linux-2.6.0-test6/include/acpi/acstruct.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/acpi/acstruct.h	2003-10-05 00:33:24.000000000 -0700
+@@ -91,11 +91,12 @@ struct acpi_walk_state
+ 	struct acpi_namespace_node          arguments[ACPI_METHOD_NUM_ARGS];    /* Control method arguments */
+ 	union acpi_operand_object           **caller_return_desc;
+ 	union acpi_generic_state            *control_state;                     /* List of control states (nested IFs) */
++	struct acpi_namespace_node          *deferred_node;                      /* Used when executing deferred opcodes */
+ 	struct acpi_namespace_node          local_variables[ACPI_METHOD_NUM_LOCALS];    /* Control method locals */
+ 	struct acpi_namespace_node          *method_call_node;                  /* Called method Node*/
+ 	union acpi_parse_object             *method_call_op;                    /* method_call Op if running a method */
+ 	union acpi_operand_object           *method_desc;                       /* Method descriptor if running a method */
+-	struct acpi_namespace_node          *method_node;                       /* Method Node if running a method */
++	struct acpi_namespace_node          *method_node;                       /* Method node if running a method. */
+ 	union acpi_parse_object             *op;                                /* Current parser op */
+ 	union acpi_operand_object           *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
+ 	const struct acpi_opcode_info       *op_info;                           /* Info on current opcode */
+--- linux-2.6.0-test6/include/asm-alpha/cacheflush.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/include/asm-alpha/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -10,6 +10,8 @@
+ #define flush_cache_range(vma, start, end)	do { } while (0)
+ #define flush_cache_page(vma, vmaddr)		do { } while (0)
+ #define flush_dcache_page(page)			do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
+ 
+ /* Note that the following two definitions are _highly_ dependent
+    on the contexts in which they are used in the kernel.  I personally
+@@ -60,4 +62,11 @@ extern void flush_icache_user_range(stru
+ #define flush_icache_page(vma, page) \
+   flush_icache_user_range((vma), (page), 0, 0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ #endif /* _ALPHA_CACHEFLUSH_H */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-alpha/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,90 @@
++/*
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Peter Rival (frival@zk3.dec.com)
++ */
++
++#ifndef _ALPHA_LOCKMETER_H
++#define _ALPHA_LOCKMETER_H
++
++#include <asm/hwrpb.h>
++#define CPU_CYCLE_FREQUENCY	hwrpb->cycle_freq
++
++#define get_cycles64()		get_cycles()
++
++#define THIS_CPU_NUMBER		smp_processor_id()
++
++#include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++	__save_and_cli(x)
++#define local_irq_restore(x) \
++	__restore_flags(x)
++#endif	/* Linux version 2.2.x */
++
++#define SPINLOCK_MAGIC_INIT /**/
++
++/*
++ * Macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * We also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ * Note: although these defines and macros are the same as what is being used
++ *       in include/asm-i386/lockmeter.h, they are present here to easily
++ *	 allow an alternate Alpha implementation.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++	/* remember, Alpha is little endian */
++	unsigned short lock;
++	unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv)	((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)		((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++	volatile int lock;
++	unsigned short index;
++	unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv)	((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)		((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)	((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)		((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) (((inst_rwlock_t *)rwlock_ptr)->lock & 1)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++
++#define RWLOCK_READERS(rwlock_ptr)	rwlock_readers(rwlock_ptr)
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++	int tmp = (int) ((inst_rwlock_t *)rwlock_ptr)->lock;
++	/* readers subtract 2, so we have to:		*/
++	/* 	- andnot off a possible writer (bit 0)	*/
++	/*	- get the absolute value		*/
++	/*	- divide by 2 (right shift by one)	*/
++	/* to find the number of readers		*/
++	if (tmp == 0) return(0);
++	else return(IABS(tmp & ~1)>>1);
++}
++
++#endif /* _ALPHA_LOCKMETER_H */
+--- linux-2.6.0-test6/include/asm-alpha/numnodes.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/include/asm-alpha/numnodes.h	2003-10-05 00:34:38.000000000 -0700
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+ 
+-#define MAX_NUMNODES		128 /* Marvel */
++/* Max 128 Nodes - Marvel */
++#define NODES_SHIFT	7
+ 
+ #endif /* _ASM_MAX_NUMNODES_H */
+--- linux-2.6.0-test6/include/asm-alpha/pgtable.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/include/asm-alpha/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -49,7 +49,6 @@
+ #else
+ #define VMALLOC_START		(-2*PGDIR_SIZE)
+ #endif
+-#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+ #define VMALLOC_END		(-PGDIR_SIZE)
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-alpha/spinlock.h	2003-06-26 22:07:25.000000000 -0700
++++ 25/include/asm-alpha/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -6,6 +6,10 @@
+ #include <linux/kernel.h>
+ #include <asm/current.h>
+ 
++#ifdef CONFIG_LOCKMETER
++#undef DEBUG_SPINLOCK
++#undef DEBUG_RWLOCK
++#endif
+ 
+ /*
+  * Simple spin lock operations.  There are two variants, one clears IRQ's
+@@ -95,9 +99,18 @@ static inline int _raw_spin_trylock(spin
+ 
+ typedef struct {
+ 	volatile int write_lock:1, read_counter:31;
++#ifdef CONFIG_LOCKMETER
++	/* required for LOCKMETER since all bits in lock are used */
++	/* need this storage for CPU and lock INDEX ............. */
++	unsigned magic;
++#endif
+ } /*__attribute__((aligned(32)))*/ rwlock_t;
+ 
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+ 
+ #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x)	(*(volatile int *)(x) != 0)
+@@ -169,4 +182,41 @@ static inline void _raw_read_unlock(rwlo
+ 	: "m" (*lock) : "memory");
+ }
+ 
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_write_trylock(rwlock_t *lock)
++{
++	long temp,result;
++
++	__asm__ __volatile__(
++	"	ldl_l %1,%0\n"
++	"	mov $31,%2\n"
++	"	bne %1,1f\n"
++	"	or $31,1,%2\n"
++	"	stl_c %2,%0\n"
++	"1:	mb\n"
++	: "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++	: "m" (*(volatile int *)lock)
++	);
++
++	return (result);
++}
++
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++	unsigned long temp,result;
++
++	__asm__ __volatile__(
++	"	ldl_l %1,%0\n"
++	"	mov $31,%2\n"
++	"	blbs %1,1f\n"
++	"	subl %1,2,%2\n"
++	"	stl_c %2,%0\n"
++	"1:	mb\n"
++	: "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++	: "m" (*(volatile int *)lock)
++	);
++	return (result);
++}
++#endif /* CONFIG_LOCKMETER */
++
+ #endif /* _ALPHA_SPINLOCK_H */
+--- linux-2.6.0-test6/include/asm-arm26/cacheflush.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-arm26/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -25,6 +25,8 @@
+ #define flush_cache_range(vma,start,end)        do { } while (0)
+ #define flush_cache_page(vma,vmaddr)            do { } while (0)
+ #define flush_page_to_ram(page)                 do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
+ 
+ #define invalidate_dcache_range(start,end)      do { } while (0)
+ #define clean_dcache_range(start,end)           do { } while (0)
+@@ -37,6 +39,11 @@
+ #define flush_icache_range(start,end)           do { } while (0)
+ #define flush_icache_page(vma,page)             do { } while (0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ /* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
+ /* IM : Yes, it will, but only if setup to do so (we do this). */
+ #define clean_cache_area(_start,_size)          do { } while (0)
+--- linux-2.6.0-test6/include/asm-arm26/pgtable.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-arm26/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -173,7 +173,6 @@ extern struct page *empty_zero_page;
+  * area for the same reason. ;) FIXME: surely 1 page not 4k ?
+  */
+ #define VMALLOC_START     0x01a00000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       0x01c00000
+ 
+ /* Is pmd_page supposed to return a pointer to a page in some arches? ours seems to
+--- linux-2.6.0-test6/include/asm-arm/arch-adifcc/vmalloc.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/include/asm-arm/arch-adifcc/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (0xe8000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-anakin/vmalloc.h	2003-06-14 12:18:04.000000000 -0700
++++ 25/include/asm-arm/arch-anakin/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -19,8 +19,7 @@
+  * linux/arch/arm/kernel/traps.c)
+  */
+ #define VMALLOC_ARCH_OFFSET	(8 * 1024 * 1024)
+-#define VMALLOC_VMADDR(a)	((unsigned int) (a))
+-#define VMALLOC_START		((VMALLOC_VMADDR(high_memory) + VMALLOC_ARCH_OFFSET) & ~(VMALLOC_ARCH_OFFSET - 1))
++#define VMALLOC_START		(((unsigned long) (high_memory) + VMALLOC_ARCH_OFFSET) & ~(VMALLOC_ARCH_OFFSET - 1))
+ #define VMALLOC_END		(PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-cl7500/vmalloc.h	2003-06-14 12:18:32.000000000 -0700
++++ 25/include/asm-arm/arch-cl7500/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x1c000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-clps711x/memory.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-arm/arch-clps711x/memory.h	2003-10-05 00:34:40.000000000 -0700
+@@ -109,8 +109,6 @@
+  * 	node 3:  0xd8000000 - 0xdfffffff
+  */
+ 
+-#define NR_NODES	4
+-
+ /*
+  * Given a kernel address, find the home node of the underlying memory.
+  */
+--- linux-2.6.0-test6/include/asm-arm/arch-clps711x/vmalloc.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-arm/arch-clps711x/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-ebsa110/vmalloc.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/asm-arm/arch-ebsa110/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -18,7 +18,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x1f000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-ebsa285/vmalloc.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-arm/arch-ebsa285/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -18,7 +18,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ 
+ #ifdef CONFIG_ARCH_FOOTBRIDGE
+ #define VMALLOC_END       (PAGE_OFFSET + 0x30000000)
+--- linux-2.6.0-test6/include/asm-arm/arch-epxa10db/vmalloc.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/include/asm-arm/arch-epxa10db/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-integrator/irqs.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-arm/arch-integrator/irqs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -19,116 +19,39 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+-/* Use the integrator definitions */
+-#include <asm/arch/platform.h>
+-
+-/* 
+- *  IRQ interrupts definitions are the same the INT definitions
+- *  held within platform.h
+- */
+-#define IRQ_SOFTINT                     INT_SOFTINT
+-#define IRQ_UARTINT0                    INT_UARTINT0
+-#define IRQ_UARTINT1                    INT_UARTINT1
+-#define IRQ_KMIINT0                     INT_KMIINT0
+-#define IRQ_KMIINT1                     INT_KMIINT1
+-#define IRQ_TIMERINT0                   INT_TIMERINT0
+-#define IRQ_TIMERINT1                   INT_TIMERINT1
+-#define IRQ_TIMERINT2                   INT_TIMERINT2
+-#define IRQ_RTCINT                      INT_RTCINT
+-#define IRQ_EXPINT0                     INT_EXPINT0
+-#define IRQ_EXPINT1                     INT_EXPINT1
+-#define IRQ_EXPINT2                     INT_EXPINT2
+-#define IRQ_EXPINT3                     INT_EXPINT3
+-#define IRQ_PCIINT0                     INT_PCIINT0
+-#define IRQ_PCIINT1                     INT_PCIINT1
+-#define IRQ_PCIINT2                     INT_PCIINT2
+-#define IRQ_PCIINT3                     INT_PCIINT3
+-#define IRQ_V3INT                       INT_V3INT
+-#define IRQ_CPINT0                      INT_CPINT0
+-#define IRQ_CPINT1                      INT_CPINT1
+-#define IRQ_LBUSTIMEOUT                 INT_LBUSTIMEOUT
+-#define IRQ_APCINT                      INT_APCINT
+-
+-#define IRQMASK_SOFTINT                 INTMASK_SOFTINT
+-#define IRQMASK_UARTINT0                INTMASK_UARTINT0
+-#define IRQMASK_UARTINT1                INTMASK_UARTINT1
+-#define IRQMASK_KMIINT0                 INTMASK_KMIINT0
+-#define IRQMASK_KMIINT1                 INTMASK_KMIINT1
+-#define IRQMASK_TIMERINT0               INTMASK_TIMERINT0
+-#define IRQMASK_TIMERINT1               INTMASK_TIMERINT1
+-#define IRQMASK_TIMERINT2               INTMASK_TIMERINT2
+-#define IRQMASK_RTCINT                  INTMASK_RTCINT
+-#define IRQMASK_EXPINT0                 INTMASK_EXPINT0
+-#define IRQMASK_EXPINT1                 INTMASK_EXPINT1
+-#define IRQMASK_EXPINT2                 INTMASK_EXPINT2
+-#define IRQMASK_EXPINT3                 INTMASK_EXPINT3
+-#define IRQMASK_PCIINT0                 INTMASK_PCIINT0
+-#define IRQMASK_PCIINT1                 INTMASK_PCIINT1
+-#define IRQMASK_PCIINT2                 INTMASK_PCIINT2
+-#define IRQMASK_PCIINT3                 INTMASK_PCIINT3
+-#define IRQMASK_V3INT                   INTMASK_V3INT
+-#define IRQMASK_CPINT0                  INTMASK_CPINT0
+-#define IRQMASK_CPINT1                  INTMASK_CPINT1
+-#define IRQMASK_LBUSTIMEOUT             INTMASK_LBUSTIMEOUT
+-#define IRQMASK_APCINT                  INTMASK_APCINT
+-
+ /* 
+- *  FIQ interrupts definitions are the same the INT definitions.
++ *  Interrupt numbers
+  */
+-#define FIQ_SOFTINT                     INT_SOFTINT
+-#define FIQ_UARTINT0                    INT_UARTINT0
+-#define FIQ_UARTINT1                    INT_UARTINT1
+-#define FIQ_KMIINT0                     INT_KMIINT0
+-#define FIQ_KMIINT1                     INT_KMIINT1
+-#define FIQ_TIMERINT0                   INT_TIMERINT0
+-#define FIQ_TIMERINT1                   INT_TIMERINT1
+-#define FIQ_TIMERINT2                   INT_TIMERINT2
+-#define FIQ_RTCINT                      INT_RTCINT
+-#define FIQ_EXPINT0                     INT_EXPINT0
+-#define FIQ_EXPINT1                     INT_EXPINT1
+-#define FIQ_EXPINT2                     INT_EXPINT2
+-#define FIQ_EXPINT3                     INT_EXPINT3
+-#define FIQ_PCIINT0                     INT_PCIINT0
+-#define FIQ_PCIINT1                     INT_PCIINT1
+-#define FIQ_PCIINT2                     INT_PCIINT2
+-#define FIQ_PCIINT3                     INT_PCIINT3
+-#define FIQ_V3INT                       INT_V3INT
+-#define FIQ_CPINT0                      INT_CPINT0
+-#define FIQ_CPINT1                      INT_CPINT1
+-#define FIQ_LBUSTIMEOUT                 INT_LBUSTIMEOUT
+-#define FIQ_APCINT                      INT_APCINT
+-
+-#define FIQMASK_SOFTINT                 INTMASK_SOFTINT
+-#define FIQMASK_UARTINT0                INTMASK_UARTINT0
+-#define FIQMASK_UARTINT1                INTMASK_UARTINT1
+-#define FIQMASK_KMIINT0                 INTMASK_KMIINT0
+-#define FIQMASK_KMIINT1                 INTMASK_KMIINT1
+-#define FIQMASK_TIMERINT0               INTMASK_TIMERINT0
+-#define FIQMASK_TIMERINT1               INTMASK_TIMERINT1
+-#define FIQMASK_TIMERINT2               INTMASK_TIMERINT2
+-#define FIQMASK_RTCINT                  INTMASK_RTCINT
+-#define FIQMASK_EXPINT0                 INTMASK_EXPINT0
+-#define FIQMASK_EXPINT1                 INTMASK_EXPINT1
+-#define FIQMASK_EXPINT2                 INTMASK_EXPINT2
+-#define FIQMASK_EXPINT3                 INTMASK_EXPINT3
+-#define FIQMASK_PCIINT0                 INTMASK_PCIINT0
+-#define FIQMASK_PCIINT1                 INTMASK_PCIINT1
+-#define FIQMASK_PCIINT2                 INTMASK_PCIINT2
+-#define FIQMASK_PCIINT3                 INTMASK_PCIINT3
+-#define FIQMASK_V3INT                   INTMASK_V3INT
+-#define FIQMASK_CPINT0                  INTMASK_CPINT0
+-#define FIQMASK_CPINT1                  INTMASK_CPINT1
+-#define FIQMASK_LBUSTIMEOUT             INTMASK_LBUSTIMEOUT
+-#define FIQMASK_APCINT                  INTMASK_APCINT
+-
+-/* 
+- *  Misc. interrupt definitions
+- */
+-#define IRQ_KEYBDINT                    INT_KMIINT0
+-#define IRQ_MOUSEINT                    INT_KMIINT1
+-
+-#define IRQMASK_KEYBDINT                INTMASK_KMIINT0
+-#define IRQMASK_MOUSEINT                INTMASK_KMIINT1
++#define IRQ_PIC_START			0
++#define IRQ_SOFTINT			0
++#define IRQ_UARTINT0			1
++#define IRQ_UARTINT1			2
++#define IRQ_KMIINT0			3
++#define IRQ_KMIINT1			4
++#define IRQ_TIMERINT0			5
++#define IRQ_TIMERINT1			6
++#define IRQ_TIMERINT2			7
++#define IRQ_RTCINT			8
++#define IRQ_AP_EXPINT0			9
++#define IRQ_AP_EXPINT1			10
++#define IRQ_AP_EXPINT2			11
++#define IRQ_AP_EXPINT3			12
++#define IRQ_AP_PCIINT0			13
++#define IRQ_AP_PCIINT1			14
++#define IRQ_AP_PCIINT2			15
++#define IRQ_AP_PCIINT3			16
++#define IRQ_AP_V3INT			17
++#define IRQ_AP_CPINT0			18
++#define IRQ_AP_CPINT1			19
++#define IRQ_AP_LBUSTIMEOUT 		20
++#define IRQ_AP_APCINT			21
++#define IRQ_PIC_END			31
++
++#define IRQ_CIC_START			32
++#define IRQ_CM_SOFTINT			32
++#define IRQ_CM_COMMRX			33
++#define IRQ_CM_COMMTX			34
++#define IRQ_CIC_END			34
+ 
+-#define NR_IRQS                         (MAXIRQNUM + 1)
++#define NR_IRQS                         47
+ 
+--- linux-2.6.0-test6/include/asm-arm/arch-integrator/platform.h	2003-06-14 12:18:22.000000000 -0700
++++ 25/include/asm-arm/arch-integrator/platform.h	2003-10-05 00:33:24.000000000 -0700
+@@ -386,85 +386,6 @@
+  * 
+  */
+ 
+-/* 
+- *  As the interrupt bit definitions for FIQ/IRQ there is a common
+- *  set of definitions prefixed INT/INTMASK.  The FIQ/IRQ definitions
+- *  have been left to maintain backwards compatible.
+- * 
+- */
+-
+-/* 
+- *  Interrupt numbers
+- * 
+- */
+-#define INT_SOFTINT                     0
+-#define INT_UARTINT0                    1
+-#define INT_UARTINT1                    2
+-#define INT_KMIINT0                     3
+-#define INT_KMIINT1                     4
+-#define INT_TIMERINT0                   5
+-#define INT_TIMERINT1                   6
+-#define INT_TIMERINT2                   7
+-#define INT_RTCINT                      8
+-#define INT_EXPINT0                     9
+-#define INT_EXPINT1                     10
+-#define INT_EXPINT2                     11
+-#define INT_EXPINT3                     12
+-#define INT_PCIINT0                     13
+-#define INT_PCIINT1                     14
+-#define INT_PCIINT2                     15
+-#define INT_PCIINT3                     16
+-#define INT_V3INT                       17
+-#define INT_CPINT0                      18
+-#define INT_CPINT1                      19
+-#define INT_LBUSTIMEOUT                 20
+-#define INT_APCINT                      21
+-#define INT_CM_SOFTINT                  24
+-#define INT_CM_COMMRX                   25
+-#define INT_CM_COMMTX                   26
+-
+-/* 
+- *  Interrupt bit positions
+- * 
+- */
+-#define INTMASK_SOFTINT                 (1 << INT_SOFTINT)
+-#define INTMASK_UARTINT0                (1 << INT_UARTINT0)
+-#define INTMASK_UARTINT1                (1 << INT_UARTINT1)
+-#define INTMASK_KMIINT0                 (1 << INT_KMIINT0)
+-#define INTMASK_KMIINT1                 (1 << INT_KMIINT1)
+-#define INTMASK_TIMERINT0               (1 << INT_TIMERINT0)
+-#define INTMASK_TIMERINT1               (1 << INT_TIMERINT1)
+-#define INTMASK_TIMERINT2               (1 << INT_TIMERINT2)
+-#define INTMASK_RTCINT                  (1 << INT_RTCINT)
+-#define INTMASK_EXPINT0                 (1 << INT_EXPINT0)
+-#define INTMASK_EXPINT1                 (1 << INT_EXPINT1)
+-#define INTMASK_EXPINT2                 (1 << INT_EXPINT2)
+-#define INTMASK_EXPINT3                 (1 << INT_EXPINT3)
+-#define INTMASK_PCIINT0                 (1 << INT_PCIINT0)
+-#define INTMASK_PCIINT1                 (1 << INT_PCIINT1)
+-#define INTMASK_PCIINT2                 (1 << INT_PCIINT2)
+-#define INTMASK_PCIINT3                 (1 << INT_PCIINT3)
+-#define INTMASK_V3INT                   (1 << INT_V3INT)
+-#define INTMASK_CPINT0                  (1 << INT_CPINT0)
+-#define INTMASK_CPINT1                  (1 << INT_CPINT1)
+-#define INTMASK_LBUSTIMEOUT             (1 << INT_LBUSTIMEOUT)
+-#define INTMASK_APCINT                  (1 << INT_APCINT)
+-#define INTMASK_CM_SOFTINT              (1 << INT_CM_SOFTINT)
+-#define INTMASK_CM_COMMRX               (1 << INT_CM_COMMRX)
+-#define INTMASK_CM_COMMTX               (1 << INT_CM_COMMTX)
+-
+-/* 
+- *  INTEGRATOR_CM_INT0      - Interrupt number of first CM interrupt
+- *  INTEGRATOR_SC_VALID_INT - Mask of valid system controller interrupts
+- * 
+- */
+-#define INTEGRATOR_CM_INT0              INT_CM_SOFTINT
+-#define INTEGRATOR_SC_VALID_INT         0x003FFFFF
+-
+-#define MAXIRQNUM                       31
+-#define MAXFIQNUM                       31
+-#define MAXSWINUM                       31
+- 
+ /* ------------------------------------------------------------------------
+  *  LED's - The header LED is not accessible via the uHAL API
+  * ------------------------------------------------------------------------
+--- linux-2.6.0-test6/include/asm-arm/arch-integrator/time.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-arm/arch-integrator/time.h	2003-10-05 00:33:24.000000000 -0700
+@@ -86,7 +86,7 @@ static unsigned long integrator_gettimeo
+ 	/*
+ 	 * Interrupt pending?  If so, we've reloaded once already.
+ 	 */
+-	if (status & IRQMASK_TIMERINT1)
++	if (status & (1 << IRQ_TIMERINT1))
+ 		ticks1 += TIMER_RELOAD;
+ 
+ 	/*
+--- linux-2.6.0-test6/include/asm-arm/arch-integrator/vmalloc.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-arm/arch-integrator/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -28,7 +28,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-iop3xx/vmalloc.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/include/asm-arm/arch-iop3xx/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (0xe8000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-l7200/vmalloc.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/include/asm-arm/arch-l7200/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-nexuspci/vmalloc.h	2003-06-14 12:18:21.000000000 -0700
++++ 25/include/asm-arm/arch-nexuspci/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x20000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-pxa/irqs.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/include/asm-arm/arch-pxa/irqs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,7 +13,7 @@
+ #include <linux/config.h>
+ 
+ #define PXA_IRQ_SKIP	7	/* The first 7 IRQs are not yet used */
+-#define PXA_IRQ(x)		((x) - PXA_IRQ_SKIP)
++#define PXA_IRQ(x)	((x) - PXA_IRQ_SKIP)
+ 
+ #define IRQ_HWUART	PXA_IRQ(7)	/* HWUART Transmit/Receive/Error */
+ #define	IRQ_GPIO0	PXA_IRQ(8)	/* GPIO0 Edge Detect */
+@@ -47,7 +47,7 @@
+ 
+ #define IRQ_TO_GPIO_2_80(i)	\
+ 			((i) - PXA_IRQ(32) + 2)
+-#define IRQ_TO_GPIO(i)	((i) - (((i) > IRQ_GPIO1) ? IRQ_GPIO(2) : IRQ_GPIO(0)))
++#define IRQ_TO_GPIO(i)	((i) - (((i) > IRQ_GPIO1) ? IRQ_GPIO(2) - 2 : IRQ_GPIO(0)))
+ 
+ /*
+  * The next 16 interrupts are for board specific purposes.  Since
+@@ -131,8 +131,10 @@
+ #define LUBBOCK_IRQ(x)		(IRQ_BOARD_START + (x))
+ #define LUBBOCK_SD_IRQ		LUBBOCK_IRQ(0)
+ #define LUBBOCK_SA1111_IRQ	LUBBOCK_IRQ(1)
+-#define LUBBOCK_USB_IRQ		LUBBOCK_IRQ(2)
++#define LUBBOCK_USB_IRQ		LUBBOCK_IRQ(2)  /* usb connect */
+ #define LUBBOCK_ETH_IRQ		LUBBOCK_IRQ(3)
+ #define LUBBOCK_UCB1400_IRQ	LUBBOCK_IRQ(4)
+ #define LUBBOCK_BB_IRQ		LUBBOCK_IRQ(5)
++#define LUBBOCK_USB_DISC_IRQ	LUBBOCK_IRQ(6)  /* usb disconnect */
++#define LUBBOCK_LAST_IRQ	LUBBOCK_IRQ(6)
+ 
+--- linux-2.6.0-test6/include/asm-arm/arch-pxa/lubbock.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/include/asm-arm/arch-pxa/lubbock.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,8 @@
+ 
+ #define LUBBOCK_FPGA_PHYS	PXA_CS2_PHYS
+ #define LUBBOCK_FPGA_VIRT	(0xf0000000)	/* phys 0x08000000 */
+-#define LUBBOCK_ETH_BASE	(0xf1000000)	/* phys 0x0c000000 */
++#define LUBBOCK_ETH_PHYS	PXA_CS3_PHYS
++#define LUBBOCK_ETH_VIRT	(0xf1000000)
+ 
+ #define LUB_P2V(x)		((x) - LUBBOCK_FPGA_PHYS + LUBBOCK_FPGA_VIRT)
+ #define LUB_V2P(x)		((x) - LUBBOCK_FPGA_VIRT + LUBBOCK_FPGA_PHYS)
+--- linux-2.6.0-test6/include/asm-arm/arch-pxa/vmalloc.h	2003-06-14 12:18:21.000000000 -0700
++++ 25/include/asm-arm/arch-pxa/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -19,7 +19,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (0xe8000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-rpc/vmalloc.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/include/asm-arm/arch-rpc/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -18,7 +18,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x1c000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-sa1100/memory.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-arm/arch-sa1100/memory.h	2003-10-05 00:34:40.000000000 -0700
+@@ -74,8 +74,6 @@
+  * 	node 3:  0xd8000000 - 0xdfffffff
+  */
+ 
+-#define NR_NODES	4
+-
+ /*
+  * Given a kernel address, find the home node of the underlying memory.
+  */
+--- linux-2.6.0-test6/include/asm-arm/arch-sa1100/vmalloc.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-arm/arch-sa1100/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (0xe8000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-shark/vmalloc.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/include/asm-arm/arch-shark/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/arch-tbox/vmalloc.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-arm/arch-tbox/vmalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -12,7 +12,6 @@
+  */
+ #define VMALLOC_OFFSET	  (8*1024*1024)
+ #define VMALLOC_START	  (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+ 
+ #define MODULE_START	(PAGE_OFFSET - 16*1048576)
+--- linux-2.6.0-test6/include/asm-arm/cacheflush.h	2003-09-27 18:57:46.000000000 -0700
++++ 25/include/asm-arm/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -207,6 +207,15 @@ extern void dmac_inv_range(unsigned long
+ extern void dmac_clean_range(unsigned long, unsigned long);
+ extern void dmac_flush_range(unsigned long, unsigned long);
+ 
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ #endif
+ 
+ /*
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-arm/mach/flash.h	2003-10-05 00:33:24.000000000 -0700
+@@ -0,0 +1,19 @@
++/*
++ *  linux/include/asm-arm/mach/flash.h
++ *
++ *  Copyright (C) 2003 Russell King, All Rights Reserved.
++ */
++#ifndef ASMARM_MACH_FLASH_H
++#define ASMAMR_MACH_FLASH_H
++
++struct mtd_partition;
++
++struct flash_platform_data {
++	const char	*map_name;
++	int		width;
++	int		(*init)(void);
++	void		(*exit)(void);
++	void		(*set_vpp)(int on);
++};
++
++#endif
+--- linux-2.6.0-test6/include/asm-arm/memory.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-arm/memory.h	2003-10-05 00:34:41.000000000 -0700
+@@ -84,24 +84,24 @@ static inline void *phys_to_virt(unsigne
+ 
+ #define PHYS_TO_NID(addr)	(0)
+ 
+-#else
++#else /* CONFIG_DISCONTIGMEM */
++
+ /*
+  * This is more complex.  We have a set of mem_map arrays spread
+  * around in memory.
+  */
++#include <linux/numa.h>
++
+ #define page_to_pfn(page)					\
+ 	(( (page) - page_zone(page)->zone_mem_map)		\
+ 	  + page_zone(page)->zone_start_pfn)
+-
+ #define pfn_to_page(pfn)					\
+ 	(PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
+-
+-#define pfn_valid(pfn)		(PFN_TO_NID(pfn) < NR_NODES)
++#define pfn_valid(pfn)		(PFN_TO_NID(pfn) < MAX_NUMNODES)
+ 
+ #define virt_to_page(kaddr)					\
+ 	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+-
+-#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < NR_NODES)
++#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
+ 
+ /*
+  * Common discontigmem stuff.
+@@ -109,7 +109,7 @@ static inline void *phys_to_virt(unsigne
+  */
+ #define PHYS_TO_NID(addr)	PFN_TO_NID((addr) >> PAGE_SHIFT)
+ 
+-#endif
++#endif /* !CONFIG_DISCONTIGMEM */
+ 
+ /*
+  * For BIO.  "will die".  Kill me when bio_to_phys() and bvec_to_phys() die.
+--- linux-2.6.0-test6/include/asm-arm/numnodes.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/asm-arm/numnodes.h	2003-10-05 00:34:40.000000000 -0700
+@@ -10,8 +10,7 @@
+ #ifndef __ASM_ARM_NUMNODES_H
+ #define __ASM_ARM_NUMNODES_H
+ 
+-#include <asm/memory.h>
+-
+-#define MAX_NUMNODES	NR_NODES
++/* Max 4 Nodes */
++#define NODES_SHIFT	2
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-arm/unistd.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-arm/unistd.h	2003-10-05 00:33:24.000000000 -0700
+@@ -32,7 +32,7 @@
+ #define __NR_write			(__NR_SYSCALL_BASE+  4)
+ #define __NR_open			(__NR_SYSCALL_BASE+  5)
+ #define __NR_close			(__NR_SYSCALL_BASE+  6)
+-#define __NR_waitpid			(__NR_SYSCALL_BASE+  7)	/* removed */
++					/* 7 was sys_waitpid */
+ #define __NR_creat			(__NR_SYSCALL_BASE+  8)
+ #define __NR_link			(__NR_SYSCALL_BASE+  9)
+ #define __NR_unlink			(__NR_SYSCALL_BASE+ 10)
+@@ -42,7 +42,7 @@
+ #define __NR_mknod			(__NR_SYSCALL_BASE+ 14)
+ #define __NR_chmod			(__NR_SYSCALL_BASE+ 15)
+ #define __NR_lchown			(__NR_SYSCALL_BASE+ 16)
+-#define __NR_break			(__NR_SYSCALL_BASE+ 17)	/* removed */
++					/* 17 was sys_break */
+ 					/* 18 was sys_stat */
+ #define __NR_lseek			(__NR_SYSCALL_BASE+ 19)
+ #define __NR_getpid			(__NR_SYSCALL_BASE+ 20)
+@@ -53,14 +53,14 @@
+ #define __NR_stime			(__NR_SYSCALL_BASE+ 25)
+ #define __NR_ptrace			(__NR_SYSCALL_BASE+ 26)
+ #define __NR_alarm			(__NR_SYSCALL_BASE+ 27)
+-
++					/* 28 was sys_fstat */
+ #define __NR_pause			(__NR_SYSCALL_BASE+ 29)
+ #define __NR_utime			(__NR_SYSCALL_BASE+ 30)
+-#define __NR_stty			(__NR_SYSCALL_BASE+ 31)	/* removed */
+-#define __NR_gtty			(__NR_SYSCALL_BASE+ 32)	/* removed */
++					/* 31 was sys_stty */
++					/* 32 was sys_gtty */
+ #define __NR_access			(__NR_SYSCALL_BASE+ 33)
+ #define __NR_nice			(__NR_SYSCALL_BASE+ 34)
+-#define __NR_ftime			(__NR_SYSCALL_BASE+ 35)	/* removed */
++					/* 35 was sys_ftime */
+ #define __NR_sync			(__NR_SYSCALL_BASE+ 36)
+ #define __NR_kill			(__NR_SYSCALL_BASE+ 37)
+ #define __NR_rename			(__NR_SYSCALL_BASE+ 38)
+@@ -69,21 +69,21 @@
+ #define __NR_dup			(__NR_SYSCALL_BASE+ 41)
+ #define __NR_pipe			(__NR_SYSCALL_BASE+ 42)
+ #define __NR_times			(__NR_SYSCALL_BASE+ 43)
+-#define __NR_prof			(__NR_SYSCALL_BASE+ 44)	/* removed */
++					/* 44 was sys_prof */
+ #define __NR_brk			(__NR_SYSCALL_BASE+ 45)
+ #define __NR_setgid			(__NR_SYSCALL_BASE+ 46)
+ #define __NR_getgid			(__NR_SYSCALL_BASE+ 47)
+-#define __NR_signal			(__NR_SYSCALL_BASE+ 48)	/* removed */
++					/* 48 was sys_signal */
+ #define __NR_geteuid			(__NR_SYSCALL_BASE+ 49)
+ #define __NR_getegid			(__NR_SYSCALL_BASE+ 50)
+ #define __NR_acct			(__NR_SYSCALL_BASE+ 51)
+ #define __NR_umount2			(__NR_SYSCALL_BASE+ 52)
+-#define __NR_lock			(__NR_SYSCALL_BASE+ 53)	/* removed */
++					/* 53 was sys_lock */
+ #define __NR_ioctl			(__NR_SYSCALL_BASE+ 54)
+ #define __NR_fcntl			(__NR_SYSCALL_BASE+ 55)
+-#define __NR_mpx			(__NR_SYSCALL_BASE+ 56)	/* removed */
++					/* 56 was sys_mpx */
+ #define __NR_setpgid			(__NR_SYSCALL_BASE+ 57)
+-#define __NR_ulimit			(__NR_SYSCALL_BASE+ 58)	/* removed */
++					/* 58 was sys_ulimit */
+ 					/* 59 was sys_olduname */
+ #define __NR_umask			(__NR_SYSCALL_BASE+ 60)
+ #define __NR_chroot			(__NR_SYSCALL_BASE+ 61)
+@@ -93,8 +93,8 @@
+ #define __NR_getpgrp			(__NR_SYSCALL_BASE+ 65)
+ #define __NR_setsid			(__NR_SYSCALL_BASE+ 66)
+ #define __NR_sigaction			(__NR_SYSCALL_BASE+ 67)
+-#define __NR_sgetmask			(__NR_SYSCALL_BASE+ 68)	/* removed */
+-#define __NR_ssetmask			(__NR_SYSCALL_BASE+ 69)	/* removed */
++					/* 68 was sys_sgetmask */
++					/* 69 was sys_ssetmask */
+ #define __NR_setreuid			(__NR_SYSCALL_BASE+ 70)
+ #define __NR_setregid			(__NR_SYSCALL_BASE+ 71)
+ #define __NR_sigsuspend			(__NR_SYSCALL_BASE+ 72)
+@@ -123,10 +123,10 @@
+ #define __NR_fchown			(__NR_SYSCALL_BASE+ 95)
+ #define __NR_getpriority		(__NR_SYSCALL_BASE+ 96)
+ #define __NR_setpriority		(__NR_SYSCALL_BASE+ 97)
+-#define __NR_profil			(__NR_SYSCALL_BASE+ 98)	/* removed */
++					/* 98 was sys_profil */
+ #define __NR_statfs			(__NR_SYSCALL_BASE+ 99)
+ #define __NR_fstatfs			(__NR_SYSCALL_BASE+100)
+-#define __NR_ioperm			(__NR_SYSCALL_BASE+101)
++					/* 101 was sys_ioperm */
+ #define __NR_socketcall			(__NR_SYSCALL_BASE+102)
+ #define __NR_syslog			(__NR_SYSCALL_BASE+103)
+ #define __NR_setitimer			(__NR_SYSCALL_BASE+104)
+@@ -137,7 +137,7 @@
+ 					/* 109 was sys_uname */
+ 					/* 110 was sys_iopl */
+ #define __NR_vhangup			(__NR_SYSCALL_BASE+111)
+-#define __NR_idle			(__NR_SYSCALL_BASE+112)
++					/* 112 was sys_idle */
+ #define __NR_syscall			(__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
+ #define __NR_wait4			(__NR_SYSCALL_BASE+114)
+ #define __NR_swapoff			(__NR_SYSCALL_BASE+115)
+@@ -148,21 +148,21 @@
+ #define __NR_clone			(__NR_SYSCALL_BASE+120)
+ #define __NR_setdomainname		(__NR_SYSCALL_BASE+121)
+ #define __NR_uname			(__NR_SYSCALL_BASE+122)
+-#define __NR_modify_ldt			(__NR_SYSCALL_BASE+123)
++					/* 123 was sys_modify_ldt */
+ #define __NR_adjtimex			(__NR_SYSCALL_BASE+124)
+ #define __NR_mprotect			(__NR_SYSCALL_BASE+125)
+ #define __NR_sigprocmask		(__NR_SYSCALL_BASE+126)
+-#define __NR_create_module		(__NR_SYSCALL_BASE+127)	/* removed */
++					/* 127 was sys_create_module */
+ #define __NR_init_module		(__NR_SYSCALL_BASE+128)
+ #define __NR_delete_module		(__NR_SYSCALL_BASE+129)
+-#define __NR_get_kernel_syms		(__NR_SYSCALL_BASE+130)	/* removed */
++					/* 130 was sys_get_kernel_syms */
+ #define __NR_quotactl			(__NR_SYSCALL_BASE+131)
+ #define __NR_getpgid			(__NR_SYSCALL_BASE+132)
+ #define __NR_fchdir			(__NR_SYSCALL_BASE+133)
+ #define __NR_bdflush			(__NR_SYSCALL_BASE+134)
+ #define __NR_sysfs			(__NR_SYSCALL_BASE+135)
+ #define __NR_personality		(__NR_SYSCALL_BASE+136)
+-#define __NR_afs_syscall		(__NR_SYSCALL_BASE+137) /* Syscall for Andrew File System */
++					/* 137 was sys_afs_syscall */
+ #define __NR_setfsuid			(__NR_SYSCALL_BASE+138)
+ #define __NR_setfsgid			(__NR_SYSCALL_BASE+139)
+ #define __NR__llseek			(__NR_SYSCALL_BASE+140)
+@@ -191,8 +191,8 @@
+ #define __NR_mremap			(__NR_SYSCALL_BASE+163)
+ #define __NR_setresuid			(__NR_SYSCALL_BASE+164)
+ #define __NR_getresuid			(__NR_SYSCALL_BASE+165)
+-#define __NR_vm86			(__NR_SYSCALL_BASE+166)	/* removed */
+-#define __NR_query_module		(__NR_SYSCALL_BASE+167)	/* removed */
++					/* 166 was sys_vm86 */
++					/* 167 was sys_query_module */
+ #define __NR_poll			(__NR_SYSCALL_BASE+168)
+ #define __NR_nfsservctl			(__NR_SYSCALL_BASE+169)
+ #define __NR_setresgid			(__NR_SYSCALL_BASE+170)
+--- linux-2.6.0-test6/include/asm-cris/arch-v10/pgtable.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-cris/arch-v10/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,11 +7,9 @@
+ 
+ #ifdef CONFIG_CRIS_LOW_MAP
+ #define VMALLOC_START     KSEG_7
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       KSEG_8
+ #else
+ #define VMALLOC_START     KSEG_D
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END       KSEG_E
+ #endif
+ 
+--- linux-2.6.0-test6/include/asm-cris/cacheflush.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-cris/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -16,6 +16,13 @@
+ #define flush_icache_range(start, end)		do { } while (0)
+ #define flush_icache_page(vma,pg)		do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ void global_flush_tlb(void); 
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+--- linux-2.6.0-test6/include/asm-h8300/cacheflush.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/asm-h8300/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -11,7 +11,6 @@
+  */
+ 
+ #define flush_cache_all()
+-#define	flush_cache_all()
+ #define	flush_cache_mm(mm)
+ #define	flush_cache_range(vma,a,b)
+ #define	flush_cache_page(vma,p)
+@@ -20,6 +19,8 @@
+ #define	flush_icache()
+ #define	flush_icache_page(vma,page)
+ #define	flush_icache_range(start,len)
++#define flush_cache_vmap(start, end)
++#define flush_cache_vunmap(start, end)
+ #define	cache_push_v(vaddr,len)
+ #define	cache_push(paddr,len)
+ #define	cache_clear(paddr,len)
+@@ -28,4 +29,9 @@
+ 
+ #define	flush_icache_user_range(vma,page,addr,len)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ #endif /* _ASM_H8300_CACHEFLUSH_H */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/atomic_kmap.h	2003-10-05 00:36:48.000000000 -0700
+@@ -0,0 +1,95 @@
++/*
++ * atomic_kmap.h: temporary virtual kernel memory mappings
++ *
++ * Copyright (C) 2003 Ingo Molnar <mingo@redhat.com>
++ */
++
++#ifndef _ASM_ATOMIC_KMAP_H
++#define _ASM_ATOMIC_KMAP_H
++
++#ifdef __KERNEL__
++
++#include <linux/config.h>
++#include <asm/tlbflush.h>
++
++#ifdef CONFIG_DEBUG_HIGHMEM
++#define HIGHMEM_DEBUG 1
++#else
++#define HIGHMEM_DEBUG 0
++#endif
++
++extern pte_t *kmap_pte;
++#define kmap_prot PAGE_KERNEL
++
++#define PKMAP_BASE (0xff000000UL)
++#define NR_SHARED_PMDS ((0xffffffff-PKMAP_BASE+1)/PMD_SIZE)
++
++static inline unsigned long __kmap_atomic_vaddr(enum km_type type)
++{
++	enum fixed_addresses idx;
++
++	idx = type + KM_TYPE_NR*smp_processor_id();
++	return __fix_to_virt(FIX_KMAP_BEGIN + idx);
++}
++
++static inline void *__kmap_atomic_noflush(struct page *page, enum km_type type)
++{
++	enum fixed_addresses idx;
++	unsigned long vaddr;
++
++	idx = type + KM_TYPE_NR*smp_processor_id();
++	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++	/*
++	 * NOTE: entries that rely on some secondary TLB-flush
++	 * effect must not be global:
++	 */
++	set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
++
++	return (void*) vaddr;
++}
++
++static inline void *__kmap_atomic(struct page *page, enum km_type type)
++{
++	enum fixed_addresses idx;
++	unsigned long vaddr;
++
++	idx = type + KM_TYPE_NR*smp_processor_id();
++	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++#if HIGHMEM_DEBUG
++	BUG_ON(!pte_none(*(kmap_pte-idx)));
++#else
++	/*
++	 * Performance optimization - do not flush if the new
++	 * pte is the same as the old one:
++	 */
++	if (pte_val(*(kmap_pte-idx)) == pte_val(mk_pte(page, kmap_prot)))
++		return (void *) vaddr;
++#endif
++	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
++	__flush_tlb_one(vaddr);
++
++	return (void*) vaddr;
++}
++
++static inline void __kunmap_atomic(void *kvaddr, enum km_type type)
++{
++#if HIGHMEM_DEBUG
++	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
++	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
++
++	BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
++	/*
++	 * force other mappings to Oops if they'll try to access
++	 * this pte without first remap it
++	 */
++	pte_clear(kmap_pte-idx);
++	__flush_tlb_one(vaddr);
++#endif
++}
++
++#define __kunmap_atomic_type(type) \
++		__kunmap_atomic((void *)__kmap_atomic_vaddr(type), (type))
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_ATOMIC_KMAP_H */
+--- linux-2.6.0-test6/include/asm-i386/bugs.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-i386/bugs.h	2003-10-05 00:33:38.000000000 -0700
+@@ -1,11 +1,11 @@
+ /*
+  *  include/asm-i386/bugs.h
+  *
+- *  Copyright (C) 1994  Linus Torvalds
++ *  Copyright (C) 1994	Linus Torvalds
+  *
+  *  Cyrix stuff, June 1998 by:
+  *	- Rafael R. Reilova (moved everything from head.S),
+- *        <rreilova@ececs.uc.edu>
++ *	  <rreilova@ececs.uc.edu>
+  *	- Channing Corn (tests & fixes),
+  *	- Andrew D. Balsa (code cleanup).
+  *
+@@ -25,7 +25,20 @@
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+ #include <asm/msr.h>
+-
++#ifdef CONFIG_KGDB
++/*
++ * Provied the command line "gdb" initial break
++ */
++int __init kgdb_initial_break(char * str)
++{
++	if (*str == '\0'){
++		breakpoint();
++		return 1;
++	}
++	return 0;
++}
++__setup("gdb",kgdb_initial_break);
++#endif
+ static int __init no_halt(char *s)
+ {
+ 	boot_cpu_data.hlt_works_ok = 0;
+@@ -140,7 +153,7 @@ static void __init check_popad(void)
+ 	  : "ecx", "edi" );
+ 	/* If this fails, it means that any user program may lock the CPU hard. Too bad. */
+ 	if (res != 12345678) printk( "Buggy.\n" );
+-		        else printk( "OK.\n" );
++			else printk( "OK.\n" );
+ #endif
+ }
+ 
+--- linux-2.6.0-test6/include/asm-i386/cacheflush.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-i386/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,6 +13,13 @@
+ #define flush_icache_range(start, end)		do { } while (0)
+ #define flush_icache_page(vma,pg)		do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ void global_flush_tlb(void); 
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+--- linux-2.6.0-test6/include/asm-i386/checksum.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-i386/checksum.h	2003-10-05 00:36:48.000000000 -0700
+@@ -25,7 +25,7 @@ asmlinkage unsigned int csum_partial(con
+  * better 64-bit) boundary
+  */
+ 
+-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
++asmlinkage unsigned int direct_csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+ 						   int *src_err_ptr, int *dst_err_ptr);
+ 
+ /*
+@@ -39,14 +39,19 @@ static __inline__
+ unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+ 					int len, int sum)
+ {
+-	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
++	/*
++	 * The direct function is OK for kernel-space => kernel-space copies:
++	 */
++	return direct_csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+ }
+ 
+ static __inline__
+ unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+ 						int len, int sum, int *err_ptr)
+ {
+-	return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
++	if (copy_from_user(dst, src, len))
++		*err_ptr = -EFAULT;
++	return csum_partial(dst, len, sum);
+ }
+ 
+ /*
+@@ -171,11 +176,26 @@ static __inline__ unsigned short int csu
+  *	Copy and checksum to user
+  */
+ #define HAVE_CSUM_COPY_USER
+-static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, char *dst,
+ 				    int len, int sum, int *err_ptr)
+ {
+ 	if (access_ok(VERIFY_WRITE, dst, len))
+-		return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++		return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++
++	if (len)
++		*err_ptr = -EFAULT;
++
++	return -1; /* invalid checksum */
++}
++
++static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++				    int len, int sum, int *err_ptr)
++{
++	if (access_ok(VERIFY_WRITE, dst, len)) {
++		if (copy_to_user(dst, src, len))
++			*err_ptr = -EFAULT;
++		return csum_partial(src, len, sum);
++	}
+ 
+ 	if (len)
+ 		*err_ptr = -EFAULT;
+--- linux-2.6.0-test6/include/asm-i386/desc.h	2003-06-14 12:17:55.000000000 -0700
++++ 25/include/asm-i386/desc.h	2003-10-05 00:36:48.000000000 -0700
+@@ -21,6 +21,13 @@ struct Xgt_desc_struct {
+ 
+ extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
+ 
++extern void trap_init_virtual_IDT(void);
++extern void trap_init_virtual_GDT(void);
++
++asmlinkage int system_call(void);
++asmlinkage void lcall7(void);
++asmlinkage void lcall27(void);
++
+ #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
+ #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
+ 
+@@ -30,6 +37,7 @@ extern struct Xgt_desc_struct idt_descr,
+  */
+ extern struct desc_struct default_ldt[];
+ extern void set_intr_gate(unsigned int irq, void * addr);
++extern void set_trap_gate(unsigned int n, void *addr);
+ 
+ #define _set_tssldt_desc(n,addr,limit,type) \
+ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
+@@ -90,31 +98,8 @@ static inline void load_TLS(struct threa
+ #undef C
+ }
+ 
+-static inline void clear_LDT(void)
+-{
+-	int cpu = get_cpu();
+-
+-	set_ldt_desc(cpu, &default_ldt[0], 5);
+-	load_LDT_desc();
+-	put_cpu();
+-}
+-
+-/*
+- * load one particular LDT into the current CPU
+- */
+-static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
+-{
+-	void *segments = pc->ldt;
+-	int count = pc->size;
+-
+-	if (likely(!count)) {
+-		segments = &default_ldt[0];
+-		count = 5;
+-	}
+-		
+-	set_ldt_desc(cpu, segments, count);
+-	load_LDT_desc();
+-}
++extern struct page *default_ldt_page;
++extern void load_LDT_nolock(mm_context_t *pc, int cpu);
+ 
+ static inline void load_LDT(mm_context_t *pc)
+ {
+@@ -123,6 +108,6 @@ static inline void load_LDT(mm_context_t
+ 	put_cpu();
+ }
+ 
+-#endif /* !__ASSEMBLY__ */
+ 
++#endif /* !__ASSEMBLY__ */
+ #endif
+--- linux-2.6.0-test6/include/asm-i386/elf.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/include/asm-i386/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -127,11 +127,6 @@ extern int dump_task_extended_fpu (struc
+ #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+ #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
+ 
+-#ifdef CONFIG_SMP
+-extern void dump_smp_unlazy_fpu(void);
+-#define ELF_CORE_SYNC dump_smp_unlazy_fpu
+-#endif
+-
+ #define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
+ #define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
+ #define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
+@@ -162,7 +157,10 @@ do {									      \
+ 	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+ 		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
+ 		if (phdr.p_type == PT_LOAD) {				      \
++			BUG_ON(ofs != 0);				      \
+ 			ofs = phdr.p_offset = offset;			      \
++			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);	      \
++			phdr.p_filesz = phdr.p_memsz;			      \
+ 			offset += phdr.p_filesz;			      \
+ 		}							      \
+ 		else							      \
+@@ -180,7 +178,7 @@ do {									      \
+ 	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+ 		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
+ 			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
+-				   vsyscall_phdrs[i].p_filesz);		      \
++				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
+ 	}								      \
+ } while (0)
+ 
+--- linux-2.6.0-test6/include/asm-i386/fixmap.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-i386/fixmap.h	2003-10-05 00:36:48.000000000 -0700
+@@ -18,17 +18,15 @@
+ #include <asm/acpi.h>
+ #include <asm/apicdef.h>
+ #include <asm/page.h>
+-#ifdef CONFIG_HIGHMEM
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+-#endif
+ 
+ /*
+  * Here we define all the compile-time 'special' virtual
+  * addresses. The point is to have a constant address at
+  * compile time, but to set the physical address only
+- * in the boot process. We allocate these special addresses
+- * from the end of virtual memory (0xfffff000) backwards.
++ * in the boot process. We allocate these special  addresses
++ * from the end of virtual memory (0xffffe000) backwards.
+  * Also this lets us do fail-safe vmalloc(), we
+  * can guarantee that these special addresses and
+  * vmalloc()-ed addresses never overlap.
+@@ -41,11 +39,20 @@
+  * TLB entries of such buffers will not be flushed across
+  * task switches.
+  */
++
++/*
++ * on UP currently we will have no trace of the fixmap mechanizm,
++ * no page table allocations, etc. This might change in the
++ * future, say framebuffers for the console driver(s) could be
++ * fix-mapped?
++ */
+ enum fixed_addresses {
+ 	FIX_HOLE,
+ 	FIX_VSYSCALL,
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
++#else
++	FIX_VSTACK_HOLE_1,
+ #endif
+ #ifdef CONFIG_X86_IO_APIC
+ 	FIX_IO_APIC_BASE_0,
+@@ -57,16 +64,21 @@ enum fixed_addresses {
+ 	FIX_LI_PCIA,	/* Lithium PCI Bridge A */
+ 	FIX_LI_PCIB,	/* Lithium PCI Bridge B */
+ #endif
+-#ifdef CONFIG_X86_F00F_BUG
+-	FIX_F00F_IDT,	/* Virtual mapping for IDT */
+-#endif
++	FIX_IDT,
++	FIX_GDT_1,
++	FIX_GDT_0,
++	FIX_TSS_3,
++	FIX_TSS_2,
++	FIX_TSS_1,
++	FIX_TSS_0,
++	FIX_ENTRY_TRAMPOLINE_1,
++	FIX_ENTRY_TRAMPOLINE_0,
+ #ifdef CONFIG_X86_CYCLONE_TIMER
+ 	FIX_CYCLONE_TIMER, /*cyclone timer register*/
++	FIX_VSTACK_HOLE_2,
+ #endif 
+-#ifdef CONFIG_HIGHMEM
+ 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+ 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+-#endif
+ #ifdef CONFIG_ACPI_BOOT
+ 	FIX_ACPI_BEGIN,
+ 	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
+@@ -95,12 +107,15 @@ extern void __set_fixmap (enum fixed_add
+ 		__set_fixmap(idx, 0, __pgprot(0))
+ 
+ /*
+- * used by vmalloc.c.
++ * used by vmalloc.c and various other places.
+  *
+  * Leave one empty page between vmalloc'ed areas and
+  * the start of the fixmap.
++ *
++ * IMPORTANT: dont change FIXADDR_TOP without adjusting KM_VSTACK0
++ * and KM_VSTACK1 so that the virtual stack is 8K aligned.
+  */
+-#define FIXADDR_TOP	(0xfffff000UL)
++#define FIXADDR_TOP	(0xffffe000UL)
+ #define __FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+ #define FIXADDR_START	(FIXADDR_TOP - __FIXADDR_SIZE)
+ 
+--- linux-2.6.0-test6/include/asm-i386/highmem.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/highmem.h	2003-10-05 00:36:48.000000000 -0700
+@@ -25,26 +25,19 @@
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+ 
+ /* declarations for highmem.c */
+ extern unsigned long highstart_pfn, highend_pfn;
+ 
+-extern pte_t *kmap_pte;
+-extern pgprot_t kmap_prot;
+ extern pte_t *pkmap_page_table;
+-
+-extern void kmap_init(void);
++extern void kmap_init(void) __init;
+ 
+ /*
+  * Right now we initialize only a single pte table. It can be extended
+  * easily, subsequent pte tables have to be allocated in one physical
+  * chunk of RAM.
+  */
+-#if NR_CPUS <= 32
+-#define PKMAP_BASE (0xff800000UL)
+-#else
+-#define PKMAP_BASE (0xff600000UL)
+-#endif
+ #ifdef CONFIG_X86_PAE
+ #define LAST_PKMAP 512
+ #else
+@@ -63,6 +56,8 @@ void *kmap_atomic(struct page *page, enu
+ void kunmap_atomic(void *kvaddr, enum km_type type);
+ struct page *kmap_atomic_to_page(void *ptr);
+ 
++#define flush_cache_kmaps()	do { } while (0)
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _ASM_HIGHMEM_H */
+--- linux-2.6.0-test6/include/asm-i386/hw_irq.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/hw_irq.h	2003-10-05 00:36:27.000000000 -0700
+@@ -25,8 +25,9 @@
+  * Interrupt entry/exit code at both C and assembly level
+  */
+ 
+-extern int irq_vector[NR_IRQS];
+-#define IO_APIC_VECTOR(irq)	irq_vector[irq]
++extern u8 *irq_vector;
++#define IO_APIC_VECTOR(irq)	((int)irq_vector[(irq)])
++extern int nr_irqs;
+ 
+ extern void (*interrupt[NR_IRQS])(void);
+ 
+@@ -41,6 +42,7 @@ asmlinkage void apic_timer_interrupt(voi
+ asmlinkage void error_interrupt(void);
+ asmlinkage void spurious_interrupt(void);
+ asmlinkage void thermal_interrupt(struct pt_regs);
++#define platform_legacy_irq(irq)	((irq) < 16)
+ #endif
+ 
+ void mask_irq(unsigned int irq);
+--- linux-2.6.0-test6/include/asm-i386/io_apic.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/io_apic.h	2003-10-05 00:36:21.000000000 -0700
+@@ -13,6 +13,46 @@
+ 
+ #ifdef CONFIG_X86_IO_APIC
+ 
++#ifdef CONFIG_PCI_USE_VECTOR
++static inline int use_pci_vector(void)	{return 1;}
++static inline void disable_edge_ioapic_vector(unsigned int vector) { }
++static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
++static inline void end_edge_ioapic_vector (unsigned int vector) { }
++#define startup_level_ioapic	startup_level_ioapic_vector
++#define shutdown_level_ioapic	mask_IO_APIC_vector
++#define enable_level_ioapic	unmask_IO_APIC_vector
++#define disable_level_ioapic	mask_IO_APIC_vector
++#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
++#define end_level_ioapic	end_level_ioapic_vector
++#define set_ioapic_affinity	set_ioapic_affinity_vector
++
++#define startup_edge_ioapic 	startup_edge_ioapic_vector
++#define shutdown_edge_ioapic 	disable_edge_ioapic_vector
++#define enable_edge_ioapic 	unmask_IO_APIC_vector
++#define disable_edge_ioapic 	disable_edge_ioapic_vector
++#define ack_edge_ioapic 	ack_edge_ioapic_vector
++#define end_edge_ioapic 	end_edge_ioapic_vector
++#else
++static inline int use_pci_vector(void)	{return 0;}
++static inline void disable_edge_ioapic_irq(unsigned int irq) { }
++static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
++static inline void end_edge_ioapic_irq (unsigned int irq) { }
++#define startup_level_ioapic	startup_level_ioapic_irq
++#define shutdown_level_ioapic	mask_IO_APIC_irq
++#define enable_level_ioapic	unmask_IO_APIC_irq
++#define disable_level_ioapic	mask_IO_APIC_irq
++#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
++#define end_level_ioapic	end_level_ioapic_irq
++#define set_ioapic_affinity	set_ioapic_affinity_irq
++
++#define startup_edge_ioapic 	startup_edge_ioapic_irq
++#define shutdown_edge_ioapic 	disable_edge_ioapic_irq
++#define enable_edge_ioapic 	unmask_IO_APIC_irq
++#define disable_edge_ioapic 	disable_edge_ioapic_irq
++#define ack_edge_ioapic 	ack_edge_ioapic_irq
++#define end_edge_ioapic 	end_edge_ioapic_irq
++#endif
++
+ #define APIC_MISMATCH_DEBUG
+ 
+ #define IO_APIC_BASE(idx) \
+@@ -177,4 +217,6 @@ extern int io_apic_set_pci_routing (int 
+ #define io_apic_assign_pci_irqs 0
+ #endif
+ 
++extern int assign_irq_vector(int irq);
++
+ #endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/kgdb.h	2003-10-05 00:33:50.000000000 -0700
+@@ -0,0 +1,76 @@
++#ifndef __KGDB
++#define __KGDB
++
++/*
++ * This file should not include ANY others.  This makes it usable
++ * most anywhere without the fear of include order or inclusion.
++ * Make it so!
++ *
++ * This file may be included all the time.  It is only active if
++ * CONFIG_KGDB is defined, otherwise it stubs out all the macros
++ * and entry points.
++ */
++#if defined(CONFIG_KGDB) && !defined(__ASSEMBLY__)
++
++extern void breakpoint(void);
++#define INIT_KGDB_INTS kgdb_enable_ints()
++
++#ifndef BREAKPOINT
++#define BREAKPOINT   asm("   int $3")
++#endif
++
++struct sk_buff;
++
++extern int kgdb_eth;
++extern unsigned kgdb_remoteip;
++extern unsigned short kgdb_listenport;
++extern unsigned short kgdb_sendport;
++extern unsigned char kgdb_remotemac[6];
++extern unsigned char kgdb_localmac[6];
++extern int kgdb_eth_need_breakpoint[];
++
++extern int kgdb_tty_hook(void);
++extern int kgdb_eth_hook(void);
++extern int gdb_net_interrupt(struct sk_buff *skb);
++
++/*
++ * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
++ * pointer to its routine and it will be entered as the first thing
++ * when a trap occurs.
++ *
++ * Return values are, at present, undefined.
++ *
++ * The debug hook routine does not necessarily return to its caller.
++ * It has the register image and thus may choose to resume execution
++ * anywhere it pleases.
++ */
++struct pt_regs;
++struct sk_buff;
++
++extern int kgdb_handle_exception(int trapno,
++				 int signo, int err_code, struct pt_regs *regs);
++extern int in_kgdb(struct pt_regs *regs);
++extern int kgdb_net_interrupt(struct sk_buff *skb);
++
++#ifdef CONFIG_KGDB_TS
++void kgdb_tstamp(int line, char *source, int data0, int data1);
++/*
++ * This is the time stamp function.  The macro adds the source info and
++ * does a cast on the data to allow most any 32-bit value.
++ */
++
++#define kgdb_ts(data0,data1) kgdb_tstamp(__LINE__,__FILE__,(int)data0,(int)data1)
++#else
++#define kgdb_ts(data0,data1)
++#endif
++#else				/* CONFIG_KGDB  && ! __ASSEMBLY__ ,stubs follow... */
++#ifndef BREAKPOINT
++#define BREAKPOINT
++#endif
++#define kgdb_ts(data0,data1)
++#define in_kgdb
++#define kgdb_handle_exception
++#define breakpoint
++#define INIT_KGDB_INTS
++#endif
++#endif				/* __KGDB */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/kgdb_local.h	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,102 @@
++#ifndef __KGDB_LOCAL
++#define ___KGDB_LOCAL
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/serial.h>
++#include <linux/serialP.h>
++#include <linux/spinlock.h>
++#include <asm/processor.h>
++#include <asm/msr.h>
++#include <asm/kgdb.h>
++
++#define PORT 0x3f8
++#ifdef CONFIG_KGDB_PORT
++#undef PORT
++#define PORT CONFIG_KGDB_PORT
++#endif
++#define IRQ 4
++#ifdef CONFIG_KGDB_IRQ
++#undef IRQ
++#define IRQ CONFIG_KGDB_IRQ
++#endif
++#define SB_CLOCK 1843200
++#define SB_BASE (SB_CLOCK/16)
++#define SB_BAUD9600 SB_BASE/9600
++#define SB_BAUD192  SB_BASE/19200
++#define SB_BAUD384  SB_BASE/38400
++#define SB_BAUD576  SB_BASE/57600
++#define SB_BAUD1152 SB_BASE/115200
++#ifdef CONFIG_KGDB_9600BAUD
++#define SB_BAUD SB_BAUD9600
++#endif
++#ifdef CONFIG_KGDB_19200BAUD
++#define SB_BAUD SB_BAUD192
++#endif
++#ifdef CONFIG_KGDB_38400BAUD
++#define SB_BAUD SB_BAUD384
++#endif
++#ifdef CONFIG_KGDB_57600BAUD
++#define SB_BAUD SB_BAUD576
++#endif
++#ifdef CONFIG_KGDB_115200BAUD
++#define SB_BAUD SB_BAUD1152
++#endif
++#ifndef SB_BAUD
++#define SB_BAUD SB_BAUD1152	/* Start with this if not given */
++#endif
++
++#ifndef CONFIG_X86_TSC
++#undef rdtsc
++#define rdtsc(a,b) if (a++ > 10000){a = 0; b++;}
++#undef rdtscll
++#define rdtscll(s) s++
++#endif
++
++#ifdef _raw_read_unlock		/* must use a name that is "define"ed, not an inline */
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#define spin_lock	 _raw_spin_lock
++#define spin_trylock	 _raw_spin_trylock
++#define spin_unlock	 _raw_spin_unlock
++#else
++#endif
++#undef spin_unlock_wait
++#define spin_unlock_wait(x)  do { cpu_relax(); barrier();} \
++                                     while(spin_is_locked(x))
++
++#define SB_IER 1
++#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
++
++#define FLAGS 0
++#define SB_STATE { \
++     magic: SSTATE_MAGIC, \
++     baud_base: SB_BASE,  \
++     port:      PORT,     \
++     irq:       IRQ,      \
++     flags:     FLAGS,    \
++     custom_divisor:SB_BAUD}
++#define SB_INFO  { \
++      magic: SERIAL_MAGIC, \
++      port:  PORT,0,FLAGS, \
++      state: &state,       \
++      tty:   (struct tty_struct *)&state, \
++      IER:   SB_IER,       \
++      MCR:   SB_MCR}
++extern void putDebugChar(int);
++/* RTAI support needs us to really stop/start interrupts */
++
++#define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
++#define kgdb_cli() __asm__ __volatile__("cli": : :"memory")
++#define kgdb_local_save_flags(x) __asm__ __volatile__(\
++                                   "pushfl ; popl %0":"=g" (x): /* no input */)
++#define kgdb_local_irq_restore(x) __asm__ __volatile__(\
++                                   "pushl %0 ; popfl": \
++                                     /* no output */ :"g" (x):"memory", "cc")
++#define kgdb_local_irq_save(x) kgdb_local_save_flags(x); kgdb_cli()
++
++#ifdef CONFIG_SERIAL
++extern void shutdown_for_kgdb(struct async_struct *info);
++#endif
++#define INIT_KDEBUG putDebugChar("+");
++#endif				/* __KGDB_LOCAL */
+--- linux-2.6.0-test6/include/asm-i386/kmap_types.h	2003-06-14 12:18:28.000000000 -0700
++++ 25/include/asm-i386/kmap_types.h	2003-10-05 00:36:48.000000000 -0700
+@@ -3,30 +3,36 @@
+ 
+ #include <linux/config.h>
+ 
+-#ifdef CONFIG_DEBUG_HIGHMEM
+-# define D(n) __KM_FENCE_##n ,
+-#else
+-# define D(n)
+-#endif
+-
+ enum km_type {
+-D(0)	KM_BOUNCE_READ,
+-D(1)	KM_SKB_SUNRPC_DATA,
+-D(2)	KM_SKB_DATA_SOFTIRQ,
+-D(3)	KM_USER0,
+-D(4)	KM_USER1,
+-D(5)	KM_BIO_SRC_IRQ,
+-D(6)	KM_BIO_DST_IRQ,
+-D(7)	KM_PTE0,
+-D(8)	KM_PTE1,
+-D(9)	KM_PTE2,
+-D(10)	KM_IRQ0,
+-D(11)	KM_IRQ1,
+-D(12)	KM_SOFTIRQ0,
+-D(13)	KM_SOFTIRQ1,
+-D(14)	KM_TYPE_NR
+-};
+-
+-#undef D
++	/*
++	 * IMPORTANT: don't move these 3 entries, and only add entries in
++	 * pairs: the 4G/4G virtual stack must be 8K aligned on each cpu.
++	 */
++	KM_BOUNCE_READ,
++	KM_VSTACK1,
++	KM_VSTACK0,
+ 
++	KM_LDT_PAGE15,
++	KM_LDT_PAGE0 = KM_LDT_PAGE15 + 16-1,
++	KM_USER_COPY,
++	KM_VSTACK_HOLE,
++	KM_SKB_SUNRPC_DATA,
++	KM_SKB_DATA_SOFTIRQ,
++	KM_USER0,
++	KM_USER1,
++	KM_BIO_SRC_IRQ,
++	KM_BIO_DST_IRQ,
++	KM_PTE0,
++	KM_PTE1,
++	KM_PTE2,
++	KM_IRQ0,
++	KM_IRQ1,
++	KM_SOFTIRQ0,
++	KM_SOFTIRQ1,
++	/*
++	 * Add new entries in pairs:
++	 * the 4G/4G virtual stack must be 8K aligned on each cpu.
++	 */
++	KM_TYPE_NR
++};
+ #endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,127 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com)
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks.
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ *  Moved machine dependent code here from include/lockmeter.h.
++ *
++ */
++
++#ifndef _I386_LOCKMETER_H
++#define _I386_LOCKMETER_H
++
++#include <asm/spinlock.h>
++#include <asm/rwlock.h>
++
++#include <linux/version.h>
++
++#ifdef __KERNEL__
++extern unsigned long cpu_khz;
++#define CPU_CYCLE_FREQUENCY	(cpu_khz * 1000)
++#else
++#define CPU_CYCLE_FREQUENCY	450000000
++#endif
++
++#define THIS_CPU_NUMBER		smp_processor_id()
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++    __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
++
++#define local_irq_restore(x) \
++    __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
++#endif	/* Linux version 2.2.x */
++
++/*
++ * macros to cache and retrieve an index value inside of a spin lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.  Not normally a problem!!
++ * we also assume that the hash table has less than 65535 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++	/* remember, Intel is little endian */
++	unsigned short lock;
++	unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++	volatile int lock;
++	unsigned short index;
++	unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++	int tmp = (int) rwlock_ptr->lock;
++	/* read and write lock attempts may cause the lock value to temporarily */
++	/* be negative.  Until it is >= 0 we know nothing (i. e. can't tell if  */
++	/* is -1 because it was write locked and somebody tried to read lock it */
++	/* or if it is -1 because it was read locked and somebody tried to write*/
++	/* lock it. ........................................................... */
++	do {
++		tmp = (int) rwlock_ptr->lock;
++	} while (tmp < 0);
++	if (tmp == 0) return(0);
++	else return(RW_LOCK_BIAS-tmp);
++}
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock <= 0)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((IABS((rwlock_ptr)->lock) % RW_LOCK_BIAS) != 0)
++
++/* this is a lot of typing just to get gcc to emit "rdtsc" */
++static inline long long get_cycles64 (void)
++{
++#ifndef CONFIG_X86_TSC
++	#error this code requires CONFIG_X86_TSC
++#else
++	union longlong_u {
++		long long intlong;
++		struct intint_s {
++			uint32_t eax;
++			uint32_t edx;
++		} intint;
++	} longlong;
++
++	rdtsc(longlong.intint.eax,longlong.intint.edx);
++	return longlong.intlong;
++#endif
++}
++
++#endif /* _I386_LOCKMETER_H */
+--- linux-2.6.0-test6/include/asm-i386/mach-default/irq_vectors.h	2003-06-14 12:18:04.000000000 -0700
++++ 25/include/asm-i386/mach-default/irq_vectors.h	2003-10-05 00:36:20.000000000 -0700
+@@ -76,11 +76,21 @@
+  * Since vectors 0x00-0x1f are used/reserved for the CPU,
+  * the usable vector space is 0x20-0xff (224 vectors)
+  */
++/*
++ * The maximum number of vectors supported by i386 processors
++ * is limited to 256. For processors other than i386, NR_VECTORS
++ * should be changed accordingly.
++ */
++#define NR_VECTORS 256
++#ifdef CONFIG_PCI_USE_VECTOR
++#define NR_IRQS FIRST_SYSTEM_VECTOR
++#else
+ #ifdef CONFIG_X86_IO_APIC
+ #define NR_IRQS 224
+ #else
+ #define NR_IRQS 16
+ #endif
++#endif
+ 
+ #define FPU_IRQ			13
+ 
+--- linux-2.6.0-test6/include/asm-i386/mman.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mman.h	2003-10-05 00:33:24.000000000 -0700
+@@ -8,8 +8,6 @@
+ #define PROT_NONE	0x0		/* page can not be accessed */
+ #define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
+ #define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
+-#define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
+-#define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
+ 
+ #define MAP_SHARED	0x01		/* Share changes */
+ #define MAP_PRIVATE	0x02		/* Changes are private */
+--- linux-2.6.0-test6/include/asm-i386/mmu_context.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/mmu_context.h	2003-10-05 00:36:48.000000000 -0700
+@@ -29,6 +29,10 @@ static inline void switch_mm(struct mm_s
+ {
+ 	int cpu = smp_processor_id();
+ 
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++	if (tsk->mm)
++		tsk->thread_info->user_pgd = (void *)__pa(tsk->mm->pgd);
++#endif
+ 	if (likely(prev != next)) {
+ 		/* stop flush ipis for the previous mm */
+ 		cpu_clear(cpu, prev->cpu_vm_mask);
+@@ -39,12 +43,14 @@ static inline void switch_mm(struct mm_s
+ 		cpu_set(cpu, next->cpu_vm_mask);
+ 
+ 		/* Re-load page tables */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+ 		load_cr3(next->pgd);
++#endif
+ 
+ 		/*
+ 		 * load the LDT, if the LDT is different:
+ 		 */
+-		if (unlikely(prev->context.ldt != next->context.ldt))
++		if (unlikely(prev->context.size + next->context.size))
+ 			load_LDT_nolock(&next->context, cpu);
+ 	}
+ #ifdef CONFIG_SMP
+@@ -56,7 +62,9 @@ static inline void switch_mm(struct mm_s
+ 			/* We were in lazy tlb mode and leave_mm disabled 
+ 			 * tlb flush IPI delivery. We must reload %cr3.
+ 			 */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+ 			load_cr3(next->pgd);
++#endif
+ 			load_LDT_nolock(&next->context, cpu);
+ 		}
+ 	}
+@@ -67,6 +75,6 @@ static inline void switch_mm(struct mm_s
+ 	asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
+ 
+ #define activate_mm(prev, next) \
+-	switch_mm((prev),(next),NULL)
++	switch_mm((prev),(next),current)
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-i386/mmu.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/include/asm-i386/mmu.h	2003-10-05 00:36:48.000000000 -0700
+@@ -8,10 +8,13 @@
+  *
+  * cpu_vm_mask is used to optimize ldt flushing.
+  */
++
++#define MAX_LDT_PAGES 16
++
+ typedef struct { 
+ 	int size;
+ 	struct semaphore sem;
+-	void *ldt;
++	struct page *ldt_pages[MAX_LDT_PAGES];
+ } mm_context_t;
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-i386/numaq.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/numaq.h	2003-10-05 00:34:38.000000000 -0700
+@@ -28,7 +28,6 @@
+ 
+ #ifdef CONFIG_X86_NUMAQ
+ 
+-#define MAX_NUMNODES		16
+ extern int get_memcfg_numaq(void);
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-i386/numnodes.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/numnodes.h	2003-10-05 00:34:38.000000000 -0700
+@@ -4,11 +4,15 @@
+ #include <linux/config.h>
+ 
+ #ifdef CONFIG_X86_NUMAQ
+-#include <asm/numaq.h>
+-#elif CONFIG_ACPI_SRAT
+-#include <asm/srat.h>
+-#else
+-#define MAX_NUMNODES	1
++
++/* Max 16 Nodes */
++#define NODES_SHIFT	4
++
++#elif defined(CONFIG_ACPI_SRAT)
++
++/* Max 8 Nodes */
++#define NODES_SHIFT	3
++
+ #endif /* CONFIG_X86_NUMAQ */
+ 
+ #endif /* _ASM_MAX_NUMNODES_H */
+--- linux-2.6.0-test6/include/asm-i386/page.h	2003-06-26 22:07:25.000000000 -0700
++++ 25/include/asm-i386/page.h	2003-10-05 00:36:48.000000000 -0700
+@@ -1,6 +1,8 @@
+ #ifndef _I386_PAGE_H
+ #define _I386_PAGE_H
+ 
++#include <linux/config.h>
++
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT	12
+ #define PAGE_SIZE	(1UL << PAGE_SHIFT)
+@@ -9,11 +11,10 @@
+ #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+ #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+ 
+-#ifdef __KERNEL__
+-#ifndef __ASSEMBLY__
+-
+ #include <linux/config.h>
+ 
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
+ #ifdef CONFIG_X86_USE_3DNOW
+ 
+ #include <asm/mmx.h>
+@@ -88,8 +89,19 @@ typedef struct { unsigned long pgprot; }
+  *
+  * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+  * and CONFIG_HIGHMEM64G options in the kernel configuration.
++ *
++ * Note: on PAE the kernel must never go below 32 MB, we use the
++ * first 8 entries of the 2-level boot pgd for PAE magic.
+  */
+ 
++#ifdef CONFIG_X86_4G_VM_LAYOUT
++#define __PAGE_OFFSET		(0x02000000)
++#define TASK_SIZE		(0xff000000)
++#else
++#define __PAGE_OFFSET		(0xc0000000)
++#define TASK_SIZE		(0xc0000000)
++#endif
++
+ /*
+  * This much address space is reserved for vmalloc() and iomap()
+  * as well as fixmap mappings.
+@@ -114,16 +126,10 @@ static __inline__ int get_order(unsigned
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+-#ifdef __ASSEMBLY__
+-#define __PAGE_OFFSET		(0xC0000000)
+-#else
+-#define __PAGE_OFFSET		(0xC0000000UL)
+-#endif
+-
+-
+ #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
+ #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
+-#define MAXMEM			(-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define __MAXMEM		(-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define MAXMEM			((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
+ #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+ #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+ #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+--- linux-2.6.0-test6/include/asm-i386/pgtable.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-i386/pgtable.h	2003-10-05 00:36:48.000000000 -0700
+@@ -32,16 +32,17 @@
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+ extern unsigned long empty_zero_page[1024];
+ extern pgd_t swapper_pg_dir[1024];
+-extern kmem_cache_t *pgd_cache;
+-extern kmem_cache_t *pmd_cache;
++extern kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+ extern spinlock_t pgd_lock;
+ extern struct list_head pgd_list;
+ 
+ void pmd_ctor(void *, kmem_cache_t *, unsigned long);
++void kpmd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_dtor(void *, kmem_cache_t *, unsigned long);
+ void pgtable_cache_init(void);
+ void paging_init(void);
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end);
+ 
+ #endif /* !__ASSEMBLY__ */
+ 
+@@ -51,6 +52,11 @@ void paging_init(void);
+  * newer 3-level PAE-mode page tables.
+  */
+ #ifndef __ASSEMBLY__
++
++extern void set_system_gate(unsigned int n, void *addr);
++extern void init_entry_mappings(void);
++extern void entry_trampoline_setup(void);
++
+ #ifdef CONFIG_X86_PAE
+ # include <asm/pgtable-3level.h>
+ #else
+@@ -63,7 +69,12 @@ void paging_init(void);
+ #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK	(~(PGDIR_SIZE-1))
+ 
+-#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
++#if defined(CONFIG_X86_PAE) && defined(CONFIG_X86_4G_VM_LAYOUT)
++# define USER_PTRS_PER_PGD	4
++#else
++# define USER_PTRS_PER_PGD	((TASK_SIZE/PGDIR_SIZE) + ((TASK_SIZE % PGDIR_SIZE) + PGDIR_SIZE-1)/PGDIR_SIZE)
++#endif
++
+ #define FIRST_USER_PGD_NR	0
+ 
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+@@ -85,7 +96,6 @@ void paging_init(void);
+ #define VMALLOC_OFFSET	(8*1024*1024)
+ #define VMALLOC_START	(((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
+ 						~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #ifdef CONFIG_HIGHMEM
+ # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
+ #else
+@@ -234,6 +244,7 @@ static inline void ptep_mkdirty(pte_t *p
+ 
+ #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+ #define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
++#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+ 
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+--- linux-2.6.0-test6/include/asm-i386/processor.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/processor.h	2003-10-05 00:36:49.000000000 -0700
+@@ -291,11 +291,6 @@ extern unsigned int machine_submodel_id;
+ extern unsigned int BIOS_revision;
+ extern unsigned int mca_pentium_flag;
+ 
+-/*
+- * User space process size: 3GB (default).
+- */
+-#define TASK_SIZE	(PAGE_OFFSET)
+-
+ /* This decides where the kernel will search for a free chunk of vm
+  * space during mmap's.
+  */
+@@ -406,6 +401,7 @@ struct tss_struct {
+ struct thread_struct {
+ /* cached TLS descriptors. */
+ 	struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
++	void *stack_page0, *stack_page1;
+ 	unsigned long	esp0;
+ 	unsigned long	eip;
+ 	unsigned long	esp;
+@@ -491,6 +487,13 @@ extern void prepare_to_copy(struct task_
+  */
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+ 
++#ifdef CONFIG_X86_HIGH_ENTRY
++#define virtual_esp0(tsk) \
++	((unsigned long)(tsk)->thread_info->virtual_stack + ((tsk)->thread.esp0 - (unsigned long)(tsk)->thread_info->real_stack))
++#else
++# define virtual_esp0(tsk) ((tsk)->thread.esp0)
++#endif
++
+ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ void show_trace(struct task_struct *task, unsigned long *stack);
+ 
+@@ -585,12 +588,12 @@ static inline void rep_nop(void)
+ 
+ /* Prefetch instructions for Pentium III and AMD Athlon */
+ /* It's not worth to care about 3dnow! prefetches for the K6
+-   because they are microcoded there and very slow. */
++   because they are microcoded there and very slow.
++   However we don't do prefetches for pre XP Athlons currently
++   That should be fixed. */
+ #define ARCH_HAS_PREFETCH
+ extern inline void prefetch(const void *x)
+ {
+-	if (cpu_data[0].x86_vendor == X86_VENDOR_AMD)
+-		return;		/* Some athlons fault if the address is bad */
+ 	alternative_input(ASM_NOP4,
+ 			  "prefetchnta (%1)",
+ 			  X86_FEATURE_XMM,
+--- linux-2.6.0-test6/include/asm-i386/rwlock.h	2003-06-26 22:07:25.000000000 -0700
++++ 25/include/asm-i386/rwlock.h	2003-10-05 00:34:17.000000000 -0700
+@@ -20,28 +20,52 @@
+ #define RW_LOCK_BIAS		 0x01000000
+ #define RW_LOCK_BIAS_STR	"0x01000000"
+ 
+-#define __build_read_lock_ptr(rw, helper)   \
+-	asm volatile(LOCK "subl $1,(%0)\n\t" \
+-		     "js 2f\n" \
+-		     "1:\n" \
+-		     LOCK_SECTION_START("") \
+-		     "2:\tcall " helper "\n\t" \
+-		     "jmp 1b\n" \
+-		     LOCK_SECTION_END \
+-		     ::"a" (rw) : "memory")
+-
+-#define __build_read_lock_const(rw, helper)   \
+-	asm volatile(LOCK "subl $1,%0\n\t" \
+-		     "js 2f\n" \
+-		     "1:\n" \
+-		     LOCK_SECTION_START("") \
+-		     "2:\tpushl %%eax\n\t" \
+-		     "leal %0,%%eax\n\t" \
+-		     "call " helper "\n\t" \
+-		     "popl %%eax\n\t" \
+-		     "jmp 1b\n" \
+-		     LOCK_SECTION_END \
+-		     :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++	#define __build_read_lock_ptr(rw, helper)   \
++		asm volatile(LOCK "subl $1,(%0)\n\t" \
++			     "jns 1f\n\t" \
++			     "call " helper "\n\t" \
++			     "1:\t" \
++			     ::"a" (rw) : "memory")
++
++	#define __build_read_lock_const(rw, helper)   \
++		asm volatile(LOCK "subl $1,%0\n\t" \
++			     "jns 1f\n\t" \
++			     "pushl %%eax\n\t" \
++			     "leal %0,%%eax\n\t" \
++			     "call " helper "\n\t" \
++			     "popl %%eax\n\t" \
++			     "1:\t" \
++			     :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++	#define __build_read_lock_ptr(rw, helper)   \
++		asm volatile(LOCK "subl $1,(%0)\n\t" \
++			     "js 2f\n" \
++			     "1:\n" \
++			     LOCK_SECTION_START("") \
++			     "2:\tcall " helper "\n\t" \
++			     "jmp 1b\n" \
++			     LOCK_SECTION_END \
++			     ::"a" (rw) : "memory")
++
++	#define __build_read_lock_const(rw, helper)   \
++		asm volatile(LOCK "subl $1,%0\n\t" \
++			     "js 2f\n" \
++			     "1:\n" \
++			     LOCK_SECTION_START("") \
++			     "2:\tpushl %%eax\n\t" \
++			     "leal %0,%%eax\n\t" \
++			     "call " helper "\n\t" \
++			     "popl %%eax\n\t" \
++			     "jmp 1b\n" \
++			     LOCK_SECTION_END \
++			     :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
++
+ 
+ #define __build_read_lock(rw, helper)	do { \
+ 						if (__builtin_constant_p(rw)) \
+@@ -50,28 +74,51 @@
+ 							__build_read_lock_ptr(rw, helper); \
+ 					} while (0)
+ 
+-#define __build_write_lock_ptr(rw, helper) \
+-	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+-		     "jnz 2f\n" \
+-		     "1:\n" \
+-		     LOCK_SECTION_START("") \
+-		     "2:\tcall " helper "\n\t" \
+-		     "jmp 1b\n" \
+-		     LOCK_SECTION_END \
+-		     ::"a" (rw) : "memory")
+-
+-#define __build_write_lock_const(rw, helper) \
+-	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
+-		     "jnz 2f\n" \
+-		     "1:\n" \
+-		     LOCK_SECTION_START("") \
+-		     "2:\tpushl %%eax\n\t" \
+-		     "leal %0,%%eax\n\t" \
+-		     "call " helper "\n\t" \
+-		     "popl %%eax\n\t" \
+-		     "jmp 1b\n" \
+-		     LOCK_SECTION_END \
+-		     :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++	#define __build_write_lock_ptr(rw, helper) \
++		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++			     "jz 1f\n\t" \
++			     "call " helper "\n\t" \
++			     "1:\n" \
++			     ::"a" (rw) : "memory")
++
++	#define __build_write_lock_const(rw, helper) \
++		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++			     "jz 1f\n\t" \
++			     "pushl %%eax\n\t" \
++			     "leal %0,%%eax\n\t" \
++			     "call " helper "\n\t" \
++			     "popl %%eax\n\t" \
++			     "1:\n" \
++			     :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++	#define __build_write_lock_ptr(rw, helper) \
++		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++			     "jnz 2f\n" \
++			     "1:\n" \
++			     LOCK_SECTION_START("") \
++			     "2:\tcall " helper "\n\t" \
++			     "jmp 1b\n" \
++			     LOCK_SECTION_END \
++			     ::"a" (rw) : "memory")
++
++	#define __build_write_lock_const(rw, helper) \
++		asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++			     "jnz 2f\n" \
++			     "1:\n" \
++			     LOCK_SECTION_START("") \
++			     "2:\tpushl %%eax\n\t" \
++			     "leal %0,%%eax\n\t" \
++			     "call " helper "\n\t" \
++			     "popl %%eax\n\t" \
++			     "jmp 1b\n" \
++			     LOCK_SECTION_END \
++			     :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
+ 
+ #define __build_write_lock(rw, helper)	do { \
+ 						if (__builtin_constant_p(rw)) \
+--- linux-2.6.0-test6/include/asm-i386/setup.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/setup.h	2003-10-05 00:36:22.000000000 -0700
+@@ -29,6 +29,11 @@
+ #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
+ #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
+ #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
++#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
++#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
++#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
++#define EFI_MEMMAP ((efi_memory_desc_t *) *((unsigned long *)(PARAM+0x1d0)))
++#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4)))
+ #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
+ #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
+ #define VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
+--- linux-2.6.0-test6/include/asm-i386/spinlock.h	2003-06-26 22:07:25.000000000 -0700
++++ 25/include/asm-i386/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -43,18 +43,35 @@ typedef struct {
+ #define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
+ #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
+ 
+-#define spin_lock_string \
+-	"\n1:\t" \
+-	"lock ; decb %0\n\t" \
+-	"js 2f\n" \
+-	LOCK_SECTION_START("") \
+-	"2:\t" \
+-	"rep;nop\n\t" \
+-	"cmpb $0,%0\n\t" \
+-	"jle 2b\n\t" \
+-	"jmp 1b\n" \
+-	LOCK_SECTION_END
++#ifdef CONFIG_SPINLINE
+ 
++	#define spin_lock_string \
++		"\n1:\t" \
++		"lock ; decb %0\n\t" \
++		"js 2f\n" \
++		"jmp 3f\n" \
++		"2:\t" \
++		"rep;nop\n\t" \
++		"cmpb $0,%0\n\t" \
++		"jle 2b\n\t" \
++		"jmp 1b\n" \
++		"3:\t"
++
++#else /* !CONFIG_SPINLINE */
++
++	#define spin_lock_string \
++		"\n1:\t" \
++		"lock ; decb %0\n\t" \
++		"js 2f\n" \
++		LOCK_SECTION_START("") \
++		"2:\t" \
++		"rep;nop\n\t" \
++		"cmpb $0,%0\n\t" \
++		"jle 2b\n\t" \
++		"jmp 1b\n" \
++		LOCK_SECTION_END
++
++#endif /* CONFIG_SPINLINE */
+ /*
+  * This works. Despite all the confusion.
+  * (except on PPro SMP or if we are using OOSTORE)
+@@ -138,6 +155,11 @@ here:
+  */
+ typedef struct {
+ 	volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++	/* required for LOCKMETER since all bits in lock are used */
++	/* and we need this storage for CPU and lock INDEX        */
++	unsigned lockmeter_magic;
++#endif
+ #ifdef CONFIG_DEBUG_SPINLOCK
+ 	unsigned magic;
+ #endif
+@@ -145,11 +167,19 @@ typedef struct {
+ 
+ #define RWLOCK_MAGIC	0xdeaf1eed
+ 
++#ifdef CONFIG_LOCKMETER
++#ifdef CONFIG_DEBUG_SPINLOCK
++#define RWLOCK_MAGIC_INIT	, 0, RWLOCK_MAGIC
++#else
++#define RWLOCK_MAGIC_INIT	, 0
++#endif
++#else /* !CONFIG_LOCKMETER */
+ #ifdef CONFIG_DEBUG_SPINLOCK
+ #define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
+ #else
+ #define RWLOCK_MAGIC_INIT	/* */
+ #endif
++#endif /* !CONFIG_LOCKMETER */
+ 
+ #define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
+ 
+@@ -196,4 +226,58 @@ static inline int _raw_write_trylock(rwl
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++/* FIXME -- replace with assembler */
++	atomic_t *count = (atomic_t *)lock;
++	atomic_dec(count);
++	if (count->counter > 0)
++		return 1;
++	atomic_inc(count);
++	return 0;
++}
++#endif
++
++#if defined(CONFIG_LOCKMETER) && defined(CONFIG_HAVE_DEC_LOCK)
++extern void _metered_spin_lock  (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ *  Matches what is in arch/i386/lib/dec_and_lock.c, except this one is
++ *  "static inline" so that the spin_lock(), if actually invoked, is charged
++ *  against the real caller, not against the catch-all atomic_dec_and_lock
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++	int counter;
++	int newcount;
++
++repeat:
++	counter = atomic_read(atomic);
++	newcount = counter-1;
++
++	if (!newcount)
++		goto slow_path;
++
++	asm volatile("lock; cmpxchgl %1,%2"
++		:"=a" (newcount)
++		:"r" (newcount), "m" (atomic->counter), "0" (counter));
++
++	/* If the above failed, "eax" will have changed */
++	if (newcount != counter)
++		goto repeat;
++	return 0;
++
++slow_path:
++	_metered_spin_lock(lock);
++	if (atomic_dec_and_test(atomic))
++		return 1;
++	_metered_spin_unlock(lock);
++	return 0;
++}
++
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /* __ASM_SPINLOCK_H */
+--- linux-2.6.0-test6/include/asm-i386/srat.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/srat.h	2003-10-05 00:34:38.000000000 -0700
+@@ -31,7 +31,6 @@
+ #error CONFIG_ACPI_SRAT not defined, and srat.h header has been included
+ #endif
+ 
+-#define MAX_NUMNODES		8
+ extern int get_memcfg_from_srat(void);
+ extern unsigned long *get_zholes_size(int);
+ 
+--- linux-2.6.0-test6/include/asm-i386/string.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-i386/string.h	2003-10-05 00:36:48.000000000 -0700
+@@ -56,6 +56,29 @@ __asm__ __volatile__(
+ return dest;
+ }
+ 
++/*
++ * This is a more generic variant of strncpy_count() suitable for
++ * implementing string-access routines with all sorts of return
++ * code semantics. It's used by mm/usercopy.c.
++ */
++static inline size_t strncpy_count(char * dest,const char *src,size_t count)
++{
++	__asm__ __volatile__(
++
++	"1:\tdecl %0\n\t"
++	"js 2f\n\t"
++	"lodsb\n\t"
++	"stosb\n\t"
++	"testb %%al,%%al\n\t"
++	"jne 1b\n\t"
++	"2:"
++	"incl %0"
++	: "=c" (count)
++	:"S" (src),"D" (dest),"0" (count) : "memory");
++
++	return count;
++}
++
+ #define __HAVE_ARCH_STRCAT
+ static inline char * strcat(char * dest,const char * src)
+ {
+--- linux-2.6.0-test6/include/asm-i386/thread_info.h	2003-07-27 12:14:40.000000000 -0700
++++ 25/include/asm-i386/thread_info.h	2003-10-05 00:36:48.000000000 -0700
+@@ -33,23 +33,12 @@ struct thread_info {
+ 					 	   0-0xBFFFFFFF for user-thead
+ 						   0-0xFFFFFFFF for kernel-thread
+ 						*/
+-	struct restart_block    restart_block;
++	void *real_stack, *virtual_stack, *user_pgd;
+ 
++	struct restart_block    restart_block;
+ 	__u8			supervisor_stack[0];
+ };
+ 
+-#else /* !__ASSEMBLY__ */
+-
+-/* offsets into the thread_info struct for assembly code access */
+-#define TI_TASK		0x00000000
+-#define TI_EXEC_DOMAIN	0x00000004
+-#define TI_FLAGS	0x00000008
+-#define TI_STATUS	0x0000000C
+-#define TI_CPU		0x00000010
+-#define TI_PRE_COUNT	0x00000014
+-#define TI_ADDR_LIMIT	0x00000018
+-#define TI_RESTART_BLOCK 0x000001C
+-
+ #endif
+ 
+ #define PREEMPT_ACTIVE		0x4000000
+@@ -61,7 +50,7 @@ struct thread_info {
+  */
+ #ifndef __ASSEMBLY__
+ 
+-#define INIT_THREAD_INFO(tsk)			\
++#define INIT_THREAD_INFO(tsk, thread_info)	\
+ {						\
+ 	.task		= &tsk,			\
+ 	.exec_domain	= &default_exec_domain,	\
+@@ -72,6 +61,7 @@ struct thread_info {
+ 	.restart_block = {			\
+ 		.fn = do_no_restart_syscall,	\
+ 	},					\
++	.real_stack	= &thread_info,		\
+ }
+ 
+ #define init_thread_info	(init_thread_union.thread_info)
+@@ -113,6 +103,7 @@ static inline struct thread_info *curren
+ #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+ #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
+ #define TIF_IRET		5	/* return with iret */
++#define TIF_DB7			6	/* has debug registers */
+ #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+ 
+ #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+@@ -121,6 +112,7 @@ static inline struct thread_info *curren
+ #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+ #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
+ #define _TIF_IRET		(1<<TIF_IRET)
++#define _TIF_DB7		(1<<TIF_DB7)
+ #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+ 
+ #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+--- linux-2.6.0-test6/include/asm-i386/tlbflush.h	2003-06-14 12:18:35.000000000 -0700
++++ 25/include/asm-i386/tlbflush.h	2003-10-05 00:36:48.000000000 -0700
+@@ -85,22 +85,28 @@ extern unsigned long pgkern_mask;
+ 
+ static inline void flush_tlb_mm(struct mm_struct *mm)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ 	if (mm == current->active_mm)
+ 		__flush_tlb();
++#endif
+ }
+ 
+ static inline void flush_tlb_page(struct vm_area_struct *vma,
+ 	unsigned long addr)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ 	if (vma->vm_mm == current->active_mm)
+ 		__flush_tlb_one(addr);
++#endif
+ }
+ 
+ static inline void flush_tlb_range(struct vm_area_struct *vma,
+ 	unsigned long start, unsigned long end)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+ 	if (vma->vm_mm == current->active_mm)
+ 		__flush_tlb();
++#endif
+ }
+ 
+ #else
+@@ -111,11 +117,10 @@ static inline void flush_tlb_range(struc
+ 	__flush_tlb()
+ 
+ extern void flush_tlb_all(void);
+-extern void flush_tlb_current_task(void);
+ extern void flush_tlb_mm(struct mm_struct *);
+ extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+ 
+-#define flush_tlb()	flush_tlb_current_task()
++#define flush_tlb()	flush_tlb_all()
+ 
+ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
+ {
+--- linux-2.6.0-test6/include/asm-i386/uaccess.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/uaccess.h	2003-10-05 00:36:48.000000000 -0700
+@@ -26,7 +26,7 @@
+ 
+ 
+ #define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFFUL)
+-#define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
++#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
+ 
+ #define get_ds()	(KERNEL_DS)
+ #define get_fs()	(current_thread_info()->addr_limit)
+@@ -149,6 +149,45 @@ extern void __get_user_4(void);
+ 		:"=a" (ret),"=d" (x) \
+ 		:"0" (ptr))
+ 
++extern int get_user_size(unsigned int size, void *val, const void *ptr);
++extern int put_user_size(unsigned int size, const void *val, void *ptr);
++extern int zero_user_size(unsigned int size, void *ptr);
++extern int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr);
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++
++
++# define indirect_get_user(x,ptr)					\
++({	int __ret_gu,__val_gu;						\
++	__typeof__(ptr) __ptr_gu = (ptr);				\
++	__ret_gu = get_user_size(sizeof(*__ptr_gu), &__val_gu,__ptr_gu) ? -EFAULT : 0;\
++	(x) = (__typeof__(*__ptr_gu))__val_gu;				\
++	__ret_gu;							\
++})
++#define indirect_put_user(x,ptr)					\
++({									\
++	__typeof__(*(ptr)) *__ptr_pu = (ptr), __x_pu = (x);		\
++	put_user_size(sizeof(*__ptr_pu), &__x_pu, __ptr_pu) ? -EFAULT : 0; \
++})
++#define __indirect_put_user indirect_put_user
++#define __indirect_get_user indirect_get_user
++
++#define indirect_copy_from_user(to,from,n) get_user_size(n,to,from)
++#define indirect_copy_to_user(to,from,n) put_user_size(n,from,to)
++
++#define __indirect_copy_from_user indirect_copy_from_user
++#define __indirect_copy_to_user indirect_copy_to_user
++
++#define indirect_strncpy_from_user(dst, src, count) \
++		copy_str_fromuser_size(count, dst, src)
++
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++#define indirect_strnlen_user(str, n) strlen_fromuser_size(n, str)
++#define indirect_strlen_user(str) indirect_strnlen_user(str, ~0UL >> 1)
++
++extern int zero_user_size(unsigned int size, void *ptr);
++
++#define indirect_clear_user(mem, len) zero_user_size(len, mem)
++#define __indirect_clear_user clear_user
+ 
+ /* Careful: we have to cast the result to the type of the pointer for sign reasons */
+ /**
+@@ -168,7 +207,7 @@ extern void __get_user_4(void);
+  * Returns zero on success, or -EFAULT on error.
+  * On error, the variable @x is set to zero.
+  */
+-#define get_user(x,ptr)							\
++#define direct_get_user(x,ptr)						\
+ ({	int __ret_gu,__val_gu;						\
+ 	switch(sizeof (*(ptr))) {					\
+ 	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;		\
+@@ -198,7 +237,7 @@ extern void __put_user_bad(void);
+  *
+  * Returns zero on success, or -EFAULT on error.
+  */
+-#define put_user(x,ptr)							\
++#define direct_put_user(x,ptr)						\
+   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+ 
+ 
+@@ -222,7 +261,7 @@ extern void __put_user_bad(void);
+  * Returns zero on success, or -EFAULT on error.
+  * On error, the variable @x is set to zero.
+  */
+-#define __get_user(x,ptr) \
++#define __direct_get_user(x,ptr) \
+   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+ 
+ 
+@@ -245,7 +284,7 @@ extern void __put_user_bad(void);
+  *
+  * Returns zero on success, or -EFAULT on error.
+  */
+-#define __put_user(x,ptr) \
++#define __direct_put_user(x,ptr) \
+   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+ 
+ #define __put_user_nocheck(x,ptr,size)				\
+@@ -396,7 +435,7 @@ unsigned long __copy_from_user_ll(void *
+  * On success, this will be zero.
+  */
+ static inline unsigned long
+-__copy_to_user(void __user *to, const void *from, unsigned long n)
++__direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ 	if (__builtin_constant_p(n)) {
+ 		unsigned long ret;
+@@ -434,7 +473,7 @@ __copy_to_user(void __user *to, const vo
+  * data to the requested size using zero bytes.
+  */
+ static inline unsigned long
+-__copy_from_user(void *to, const void __user *from, unsigned long n)
++__direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ 	if (__builtin_constant_p(n)) {
+ 		unsigned long ret;
+@@ -468,11 +507,11 @@ __copy_from_user(void *to, const void __
+  * On success, this will be zero.
+  */
+ static inline unsigned long
+-copy_to_user(void __user *to, const void *from, unsigned long n)
++direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ 	might_sleep();
+ 	if (access_ok(VERIFY_WRITE, to, n))
+-		n = __copy_to_user(to, from, n);
++		n = __direct_copy_to_user(to, from, n);
+ 	return n;
+ }
+ 
+@@ -493,11 +532,11 @@ copy_to_user(void __user *to, const void
+  * data to the requested size using zero bytes.
+  */
+ static inline unsigned long
+-copy_from_user(void *to, const void __user *from, unsigned long n)
++direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ 	might_sleep();
+ 	if (access_ok(VERIFY_READ, from, n))
+-		n = __copy_from_user(to, from, n);
++		n = __direct_copy_from_user(to, from, n);
+ 	else
+ 		memset(to, 0, n);
+ 	return n;
+@@ -520,10 +559,68 @@ long __strncpy_from_user(char *dst, cons
+  * If there is a limit on the length of a valid string, you may wish to
+  * consider using strnlen_user() instead.
+  */
+-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+ 
+-long strnlen_user(const char __user *str, long n);
+-unsigned long clear_user(void __user *mem, unsigned long len);
+-unsigned long __clear_user(void __user *mem, unsigned long len);
++long direct_strncpy_from_user(char *dst, const char *src, long count);
++long __direct_strncpy_from_user(char *dst, const char *src, long count);
++#define direct_strlen_user(str) direct_strnlen_user(str, ~0UL >> 1)
++long direct_strnlen_user(const char *str, long n);
++unsigned long direct_clear_user(void *mem, unsigned long len);
++unsigned long __direct_clear_user(void *mem, unsigned long len);
++
++extern int indirect_uaccess;
++
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++
++/*
++ * Return code and zeroing semantics:
++
++ __clear_user          0                      <-> bytes not done
++ clear_user            0                      <-> bytes not done
++ __copy_to_user        0                      <-> bytes not done
++ copy_to_user          0                      <-> bytes not done
++ __copy_from_user      0                      <-> bytes not done, zero rest
++ copy_from_user        0                      <-> bytes not done, zero rest
++ __get_user            0                      <-> -EFAULT
++ get_user              0                      <-> -EFAULT
++ __put_user            0                      <-> -EFAULT
++ put_user              0                      <-> -EFAULT
++ strlen_user           strlen + 1             <-> 0
++ strnlen_user          strlen + 1 (or n+1)    <-> 0
++ strncpy_from_user     strlen (or n)          <-> -EFAULT
++
++ */
++
++#define __clear_user(mem,len) __indirect_clear_user(mem,len)
++#define clear_user(mem,len) indirect_clear_user(mem,len)
++#define __copy_to_user(to,from,n) __indirect_copy_to_user(to,from,n)
++#define copy_to_user(to,from,n) indirect_copy_to_user(to,from,n)
++#define __copy_from_user(to,from,n) __indirect_copy_from_user(to,from,n)
++#define copy_from_user(to,from,n) indirect_copy_from_user(to,from,n)
++#define __get_user(val,ptr) __indirect_get_user(val,ptr)
++#define get_user(val,ptr) indirect_get_user(val,ptr)
++#define __put_user(val,ptr) __indirect_put_user(val,ptr)
++#define put_user(val,ptr) indirect_put_user(val,ptr)
++#define strlen_user(str) indirect_strlen_user(str)
++#define strnlen_user(src,count) indirect_strnlen_user(src,count)
++#define strncpy_from_user(dst,src,count) \
++			indirect_strncpy_from_user(dst,src,count)
++
++#else
++
++#define __clear_user __direct_clear_user
++#define clear_user direct_clear_user
++#define __copy_to_user __direct_copy_to_user
++#define copy_to_user direct_copy_to_user
++#define __copy_from_user __direct_copy_from_user
++#define copy_from_user direct_copy_from_user
++#define __get_user __direct_get_user
++#define get_user direct_get_user
++#define __put_user __direct_put_user
++#define put_user direct_put_user
++#define strlen_user direct_strlen_user
++#define strnlen_user direct_strnlen_user
++#define strncpy_from_user direct_strncpy_from_user
++
++#endif /* CONFIG_X86_UACCESS_INDIRECT */
+ 
+ #endif /* __i386_UACCESS_H */
+--- linux-2.6.0-test6/include/asm-i386/unistd.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/unistd.h	2003-10-05 00:33:24.000000000 -0700
+@@ -278,8 +278,9 @@
+ #define __NR_tgkill		270
+ #define __NR_utimes		271
+ #define __NR_fadvise64_64	272
++#define __NR_vserver		273
+ 
+-#define NR_syscalls 273
++#define NR_syscalls 274
+ 
+ /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
+ 
+--- linux-2.6.0-test6/include/asm-ia64/acpi.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ia64/acpi.h	2003-10-05 00:34:41.000000000 -0700
+@@ -99,7 +99,7 @@ int acpi_get_addr_space (void *obj, u8 t
+ /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
+ #define MAX_PXM_DOMAINS (256)
+ extern int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+-extern int __initdata nid_to_pxm_map[NR_NODES];
++extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
+ #endif
+ 
+ #endif /*__KERNEL__*/
+--- linux-2.6.0-test6/include/asm-ia64/cacheflush.h	2003-06-14 12:18:00.000000000 -0700
++++ 25/include/asm-ia64/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -21,6 +21,8 @@
+ #define flush_cache_range(vma, start, end)	do { } while (0)
+ #define flush_cache_page(vma, vmaddr)		do { } while (0)
+ #define flush_icache_page(vma,page)		do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
+ 
+ #define flush_dcache_page(page)			\
+ do {						\
+@@ -35,4 +37,11 @@ do {												\
+ 	flush_icache_range(_addr, _addr + (len));						\
+ } while (0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ #endif /* _ASM_IA64_CACHEFLUSH_H */
+--- linux-2.6.0-test6/include/asm-ia64/elf.h	2003-07-27 12:14:40.000000000 -0700
++++ 25/include/asm-ia64/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -206,42 +206,46 @@ do {										\
+ 	NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);		\
+ } while (0)
+ 
++
+ /*
+- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out extra segments
+- * containing the gate DSO contents.  Dumping its contents makes post-mortem fully
+- * interpretable later without matching up the same kernel and hardware config to see what
+- * IP values meant.  Dumping its extra ELF program headers includes all the other
+- * information a debugger needs to easily find how the gate DSO was being used.
++ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
++ * extra segments containing the gate DSO contents.  Dumping its
++ * contents makes post-mortem fully interpretable later without matching up
++ * the same kernel and hardware config to see what PC values meant.
++ * Dumping its extra ELF program headers includes all the other information
++ * a debugger needs to easily find how the gate DSO was being used.
+  */
+ #define ELF_CORE_EXTRA_PHDRS		(GATE_EHDR->e_phnum)
+ #define ELF_CORE_WRITE_EXTRA_PHDRS						\
+ do {										\
+-	const struct elf_phdr *const gate_phdrs =				\
+-		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);	\
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
+ 	int i;									\
+-	Elf64_Off ofs = 0;							\
++	Elf32_Off ofs = 0;						      \
+ 	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {				\
+-		struct elf_phdr phdr = gate_phdrs[i];				\
++		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
+ 		if (phdr.p_type == PT_LOAD) {					\
++			BUG_ON(ofs != 0);				      \
+ 			ofs = phdr.p_offset = offset;				\
++			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);	      \
++			phdr.p_filesz = phdr.p_memsz;			      \
+ 			offset += phdr.p_filesz;				\
+-		} else								\
++		}							      \
++		else							      \
+ 			phdr.p_offset += ofs;					\
+ 		phdr.p_paddr = 0; /* match other core phdrs */			\
+ 		DUMP_WRITE(&phdr, sizeof(phdr));				\
+ 	}									\
+ } while (0)
+-
+ #define ELF_CORE_WRITE_EXTRA_DATA					\
+ do {									\
+-	const struct elf_phdr *const gate_phdrs =			\
+-		(const struct elf_phdr *) (GATE_ADDR			\
+-					   + GATE_EHDR->e_phoff);	\
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
+ 	int i;								\
+ 	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {			\
+-		if (gate_phdrs[i].p_type == PT_LOAD)			\
+-			DUMP_WRITE((void *) gate_phdrs[i].p_vaddr,	\
+-				   gate_phdrs[i].p_filesz);		\
++		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
++			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
++				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
+ 	}								\
+ } while (0)
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-ia64/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,72 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ */
++
++#ifndef _IA64_LOCKMETER_H
++#define _IA64_LOCKMETER_H
++
++#ifdef local_cpu_data
++#define CPU_CYCLE_FREQUENCY	local_cpu_data->itc_freq
++#else
++#define CPU_CYCLE_FREQUENCY	my_cpu_data.itc_freq
++#endif
++#define get_cycles64()		get_cycles()
++
++#define THIS_CPU_NUMBER		smp_processor_id()
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++	/* remember, Intel is little endian */
++	volatile unsigned short lock;
++	volatile unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++	volatile int read_counter:31;
++	volatile int write_lock:1;
++	volatile unsigned short index;
++	volatile unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)	((rwlock_ptr)->read_counter)
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->write_lock)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->read_counter)
++
++#endif /* _IA64_LOCKMETER_H */
++
+--- linux-2.6.0-test6/include/asm-ia64/mmzone.h	2003-06-14 12:18:52.000000000 -0700
++++ 25/include/asm-ia64/mmzone.h	2003-10-05 00:34:41.000000000 -0700
+@@ -92,14 +92,12 @@
+ extern unsigned long max_low_pfn;
+ 
+ 
+-#ifdef CONFIG_IA64_DIG
++#if defined(CONFIG_IA64_DIG)
+ 
+ /*
+  * Platform definitions for DIG platform with contiguous memory.
+  */
+-#define MAX_PHYSNODE_ID	8	/* Maximum node number +1 */
+-#define NR_NODES	8	/* Maximum number of nodes in SSI */
+-
++#define MAX_PHYSNODE_ID	8		/* Maximum node number +1 */
+ #define MAX_PHYS_MEMORY	(1UL << 40)	/* 1 TB */
+ 
+ /*
+@@ -119,37 +117,34 @@ extern unsigned long max_low_pfn;
+ # error Unsupported bank and nodesize!
+ #endif
+ #define BANKSIZE		(1UL << BANKSHIFT)
+-#define BANK_OFFSET(addr)	((unsigned long)(addr) & (BANKSIZE-1))
+-#define NR_BANKS		(NR_BANKS_PER_NODE * NR_NODES)
+-
+-/*
+- * VALID_MEM_KADDR returns a boolean to indicate if a kaddr is
+- * potentially a valid cacheable identity mapped RAM memory address.
+- * Note that the RAM may or may not actually be present!!
+- */
+-#define VALID_MEM_KADDR(kaddr)	1
+-
+-/*
+- * Given a nodeid & a bank number, find the address of the mem_map
+- * entry for the first page of the bank.
+- */
+-#define BANK_MEM_MAP_INDEX(kaddr) \
+-	(((unsigned long)(kaddr) & (MAX_PHYS_MEMORY-1)) >> BANKSHIFT)
+ 
+ #elif defined(CONFIG_IA64_SGI_SN2)
++
+ /*
+  * SGI SN2 discontig definitions
+  */
+ #define MAX_PHYSNODE_ID	2048	/* 2048 node ids (also called nasid) */
+-#define NR_NODES	128	/* Maximum number of nodes in SSI */
+ #define MAX_PHYS_MEMORY	(1UL << 49)
+ 
+-#define BANKSHIFT		38
+ #define NR_BANKS_PER_NODE	4
++#define BANKSHIFT		38
+ #define SN2_NODE_SIZE		(64UL*1024*1024*1024)	/* 64GB per node */
+ #define BANKSIZE		(SN2_NODE_SIZE/NR_BANKS_PER_NODE)
++
++#endif /* CONFIG_IA64_DIG */
++
++#if defined(CONFIG_IA64_DIG) || defined (CONFIG_IA64_SGI_SN2)
++/* Common defines for both platforms */
++#include <asm/numnodes.h>
+ #define BANK_OFFSET(addr)	((unsigned long)(addr) & (BANKSIZE-1))
+-#define NR_BANKS		(NR_BANKS_PER_NODE * NR_NODES)
++#define NR_BANKS		(NR_BANKS_PER_NODE * (1 << NODES_SHIFT))
++#define NR_MEMBLKS		(NR_BANKS)
++
++/*
++ * VALID_MEM_KADDR returns a boolean to indicate if a kaddr is
++ * potentially a valid cacheable identity mapped RAM memory address.
++ * Note that the RAM may or may not actually be present!!
++ */
+ #define VALID_MEM_KADDR(kaddr)	1
+ 
+ /*
+@@ -159,5 +154,6 @@ extern unsigned long max_low_pfn;
+ #define BANK_MEM_MAP_INDEX(kaddr) \
+ 	(((unsigned long)(kaddr) & (MAX_PHYS_MEMORY-1)) >> BANKSHIFT)
+ 
+-#endif /* CONFIG_IA64_DIG */
++#endif /* CONFIG_IA64_DIG || CONFIG_IA64_SGI_SN2 */
++
+ #endif /* _ASM_IA64_MMZONE_H */
+--- linux-2.6.0-test6/include/asm-ia64/nodedata.h	2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-ia64/nodedata.h	2003-10-05 00:34:41.000000000 -0700
+@@ -8,12 +8,10 @@
+  * Copyright (c) 2002 Erich Focht <efocht@ess.nec.de>
+  * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
+  */
+-
+-
+ #ifndef _ASM_IA64_NODEDATA_H
+ #define _ASM_IA64_NODEDATA_H
+ 
+-
++#include <linux/numa.h>
+ #include <asm/mmzone.h>
+ 
+ /*
+@@ -24,9 +22,9 @@ struct pglist_data;
+ struct ia64_node_data {
+ 	short			active_cpu_count;
+ 	short			node;
+-        struct pglist_data	*pg_data_ptrs[NR_NODES];
++	struct pglist_data	*pg_data_ptrs[MAX_NUMNODES];
+ 	struct page		*bank_mem_map_base[NR_BANKS];
+-	struct ia64_node_data	*node_data_ptrs[NR_NODES];
++	struct ia64_node_data	*node_data_ptrs[MAX_NUMNODES];
+ 	short			node_id_map[NR_BANKS];
+ };
+ 
+--- linux-2.6.0-test6/include/asm-ia64/numa.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ia64/numa.h	2003-10-05 00:34:41.000000000 -0700
+@@ -16,17 +16,11 @@
+ 
+ #ifdef CONFIG_NUMA
+ 
+-#ifdef CONFIG_DISCONTIGMEM
+-# include <asm/mmzone.h>
+-# define NR_MEMBLKS   (NR_BANKS)
+-#else
+-# define NR_NODES     (8)
+-# define NR_MEMBLKS   (NR_NODES * 8)
+-#endif
+-
++#include <linux/numa.h>
+ #include <linux/cache.h>
++
+ extern volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+-extern volatile cpumask_t node_to_cpu_mask[NR_NODES] __cacheline_aligned;
++extern volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+ 
+ /* Stuff below this line could be architecture independent */
+ 
+@@ -60,7 +54,7 @@ extern struct node_cpuid_s node_cpuid[NR
+  * proportional to the memory access latency ratios.
+  */
+ 
+-extern u8 numa_slit[NR_NODES * NR_NODES];
++extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
+ #define node_distance(from,to) (numa_slit[from * numnodes + to])
+ 
+ extern int paddr_to_nid(unsigned long paddr);
+--- linux-2.6.0-test6/include/asm-ia64/numnodes.h	2003-06-14 12:18:52.000000000 -0700
++++ 25/include/asm-ia64/numnodes.h	2003-10-05 00:34:41.000000000 -0700
+@@ -1,7 +1,12 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+ 
+-#include <asm/mmzone.h>
+-#define MAX_NUMNODES	NR_NODES
++#ifdef CONFIG_IA64_DIG
++/* Max 8 Nodes */
++#define NODES_SHIFT	3
++#elif defined(CONFIG_IA64_SGI_SN2)
++/* Max 128 Nodes */
++#define NODES_SHIFT	7
++#endif
+ 
+ #endif /* _ASM_MAX_NUMNODES_H */
+--- linux-2.6.0-test6/include/asm-ia64/pgtable.h	2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-ia64/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -207,7 +207,6 @@ ia64_phys_addr_valid (unsigned long addr
+ #define RGN_KERNEL	7
+ 
+ #define VMALLOC_START		0xa000000200000000
+-#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+ #ifdef CONFIG_VIRTUAL_MEM_MAP
+ # define VMALLOC_END_INIT	(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+ # define VMALLOC_END		vmalloc_end
+--- linux-2.6.0-test6/include/asm-ia64/sn/pda.h	2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-ia64/sn/pda.h	2003-10-05 00:34:41.000000000 -0700
+@@ -10,6 +10,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/cache.h>
++#include <linux/numa.h>
+ #include <asm/percpu.h>
+ #include <asm/system.h>
+ #include <asm/processor.h>
+@@ -56,7 +57,7 @@ typedef struct pda_s {
+ 
+ 	unsigned long	sn_soft_irr[4];
+ 	unsigned long	sn_in_service_ivecs[4];
+-	short		cnodeid_to_nasid_table[NR_NODES];	
++	short		cnodeid_to_nasid_table[MAX_NUMNODES];
+ 	int		sn_lb_int_war_ticks;
+ 	int		sn_last_irq;
+ 	int		sn_first_irq;
+--- linux-2.6.0-test6/include/asm-ia64/spinlock.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ia64/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -110,8 +110,18 @@ do {											\
+ typedef struct {
+ 	volatile int read_counter	: 31;
+ 	volatile int write_lock		:  1;
++#ifdef CONFIG_LOCKMETER
++	/* required for LOCKMETER since all bits in lock are used */
++	/* and we need this storage for CPU and lock INDEX        */
++	unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
++
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+ 
+ #define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x)	(*(volatile int *) (x) != 0)
+@@ -127,6 +137,48 @@ do {											\
+ 	}										\
+ } while (0)
+ 
++#ifdef CONFIG_LOCKMETER
++/*
++ * HACK: This works, but still have a timing window that affects performance:
++ * we see that no one owns the Write lock, then someone * else grabs for Write
++ * lock before we do a read_lock().
++ * This means that on rare occasions our read_lock() will stall and spin-wait
++ * until we acquire for Read, instead of simply returning a trylock failure.
++ */
++static inline int _raw_read_trylock(rwlock_t *rw)
++{
++	if (rw->write_lock) {
++		return 0;
++	} else {
++		_raw_read_lock(rw);
++		return 1;
++	}
++}
++
++static inline int _raw_write_trylock(rwlock_t *rw)
++{
++	if (!(rw->write_lock)) {
++	    /* isn't currently write-locked... that looks promising... */
++	    if (test_and_set_bit(31, rw) == 0) {
++		/* now it is write-locked by me... */
++		if (rw->read_counter) {
++		    /* really read-locked, so release write-lock and fail */
++		    clear_bit(31, rw);
++		} else {
++		    /* we've the the write-lock, no read-lockers... success! */
++		    barrier();
++		    return 1;
++		}
++
++	    }
++	}
++
++	/* falls through ... fails to write-lock */
++	barrier();
++	return 0;
++}
++#endif
++
+ #define _raw_read_unlock(rw)					\
+ do {								\
+ 	rwlock_t *__read_lock_ptr = (rw);			\
+@@ -190,4 +242,25 @@ do {										\
+ 	clear_bit(31, (x));								\
+ })
+ 
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock  (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ *  Use a less efficient, and inline, atomic_dec_and_lock() if lockmetering
++ *  so we can see the callerPC of who is actually doing the spin_lock().
++ *  Otherwise, all we see is the generic rollup of all locks done by
++ *  atomic_dec_and_lock().
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++	_metered_spin_lock(lock);
++	if (atomic_dec_and_test(atomic))
++		return 1;
++	_metered_spin_unlock(lock);
++	return 0;
++}
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /*  _ASM_IA64_SPINLOCK_H */
+--- linux-2.6.0-test6/include/asm-m68k/bitops.h	2003-06-14 12:18:52.000000000 -0700
++++ 25/include/asm-m68k/bitops.h	2003-10-05 00:33:24.000000000 -0700
+@@ -164,9 +164,10 @@ extern __inline__ int test_bit(int nr, c
+ 	return ((1UL << (nr & 31)) & (((const volatile unsigned long *) vaddr)[nr >> 5])) != 0;
+ }
+ 
+-extern __inline__ int find_first_zero_bit(unsigned long * vaddr, unsigned size)
++extern __inline__ int find_first_zero_bit(const unsigned long *vaddr,
++					  unsigned size)
+ {
+-	unsigned long *p = vaddr, *addr = vaddr;
++	const unsigned long *p = vaddr, *addr = vaddr;
+ 	unsigned long allones = ~0UL;
+ 	int res;
+ 	unsigned long num;
+@@ -187,11 +188,11 @@ extern __inline__ int find_first_zero_bi
+ 	return ((p - addr) << 5) + (res ^ 31);
+ }
+ 
+-extern __inline__ int find_next_zero_bit (unsigned long *vaddr, int size,
++extern __inline__ int find_next_zero_bit (const unsigned long *vaddr, int size,
+ 				      int offset)
+ {
+-	unsigned long *addr = vaddr;
+-	unsigned long *p = addr + (offset >> 5);
++	const unsigned long *addr = vaddr;
++	const unsigned long *p = addr + (offset >> 5);
+ 	int set = 0, bit = offset & 31UL, res;
+ 
+ 	if (offset >= size)
+@@ -263,7 +264,7 @@ static inline int fls(int x)
+  * unlikely to be set. It's guaranteed that at least one of the 140
+  * bits is cleared.
+  */
+-static inline int sched_find_first_bit(unsigned long *b)
++static inline int sched_find_first_bit(const unsigned long *b)
+ {
+ 	if (unlikely(b[0]))
+ 		return __ffs(b[0]);
+--- linux-2.6.0-test6/include/asm-m68k/cacheflush.h	2003-07-27 12:14:40.000000000 -0700
++++ 25/include/asm-m68k/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -80,6 +80,9 @@ extern void cache_push_v(unsigned long v
+ 
+ #define flush_cache_all() __flush_cache_all()
+ 
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
++
+ extern inline void flush_cache_mm(struct mm_struct *mm)
+ {
+ 	if (mm == current->mm)
+@@ -127,6 +130,10 @@ extern inline void __flush_page_to_ram(v
+ #define flush_dcache_page(page)		__flush_page_to_ram(page_address(page))
+ #define flush_icache_page(vma, page)	__flush_page_to_ram(page_address(page))
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ extern void flush_icache_range(unsigned long address, unsigned long endaddr);
+ 
+--- linux-2.6.0-test6/include/asm-m68knommu/cacheflush.h	2003-06-14 12:18:34.000000000 -0700
++++ 25/include/asm-m68knommu/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -15,7 +15,13 @@
+ #define flush_icache_range(start,len)		__flush_cache_all()
+ #define flush_icache_page(vma,pg)		do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ extern inline void __flush_cache_all(void)
+ {
+--- linux-2.6.0-test6/include/asm-m68k/pci.h	2003-06-14 12:18:09.000000000 -0700
++++ 25/include/asm-m68k/pci.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,6 +7,8 @@
+  * Written by Wout Klaren.
+  */
+ 
++#include <asm/scatterlist.h>
++
+ struct pci_ops;
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-m68k/pgtable.h	2003-06-14 12:18:32.000000000 -0700
++++ 25/include/asm-m68k/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -79,12 +79,10 @@
+  */
+ #define VMALLOC_OFFSET	(8*1024*1024)
+ #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END KMAP_START
+ #else
+ extern unsigned long vmalloc_end;
+ #define VMALLOC_START 0x0f800000
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END vmalloc_end
+ #endif /* CONFIG_SUN3 */
+ 
+--- linux-2.6.0-test6/include/asm-m68k/zorro.h	2003-06-14 12:18:03.000000000 -0700
++++ 25/include/asm-m68k/zorro.h	2003-10-05 00:33:24.000000000 -0700
+@@ -42,4 +42,4 @@ extern inline void *z_remap_fullcache(un
+ #define z_iounmap iounmap
+ #define z_ioremap z_remap_nocache_ser
+ 
+-#endif /* _ASM_ZORRO_H */
++#endif /* _ASM_M68K_ZORRO_H */
+--- linux-2.6.0-test6/include/asm-mips/cacheflush.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-mips/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -43,7 +43,15 @@ extern void (*flush_icache_page)(struct 
+ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+ #define flush_icache_user_range(vma, page, addr, len)   \
+ 					flush_icache_page(vma, page)
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ extern void (*flush_cache_sigtramp)(unsigned long addr);
+ extern void (*flush_icache_all)(void);
+--- linux-2.6.0-test6/include/asm-mips/highmem.h	2003-07-02 14:53:17.000000000 -0700
++++ 25/include/asm-mips/highmem.h	2003-10-05 00:33:24.000000000 -0700
+@@ -54,6 +54,8 @@ extern void *kmap_atomic(struct page *pa
+ extern void kunmap_atomic(void *kvaddr, enum km_type type);
+ extern struct page *kmap_atomic_to_page(void *ptr);
+ 
++#define flush_cache_kmaps()	flush_cache_all()
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _ASM_HIGHMEM_H */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-mips/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,126 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *  Ported to mips32 for Asita Technologies
++ *   by D.J. Barrow ( dj.barrow@asitatechnologies.com )
++ */
++#ifndef _ASM_LOCKMETER_H
++#define _ASM_LOCKMETER_H
++
++/* do_gettimeoffset is a function pointer on mips */
++/* & it is not included by <linux/time.h> */
++#include <asm/time.h>
++#include <linux/time.h>
++#include <asm/div64.h>
++
++#define SPINLOCK_MAGIC_INIT	/* */
++
++#define CPU_CYCLE_FREQUENCY	get_cpu_cycle_frequency()
++
++#define THIS_CPU_NUMBER		smp_processor_id()
++
++static uint32_t cpu_cycle_frequency = 0;
++
++static uint32_t get_cpu_cycle_frequency(void)
++{
++    /* a total hack, slow and invasive, but ... it works */
++    int sec;
++    uint32_t start_cycles;
++    struct timeval tv;
++
++    if (cpu_cycle_frequency == 0) {	/* uninitialized */
++	do_gettimeofday(&tv);
++	sec = tv.tv_sec;	/* set up to catch the tv_sec rollover */
++	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++	sec = tv.tv_sec;	/* rolled over to a new sec value */
++	start_cycles = get_cycles();
++	while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++	cpu_cycle_frequency = get_cycles() - start_cycles;
++    }
++
++    return cpu_cycle_frequency;
++}
++
++extern struct timeval xtime;
++
++static uint64_t get_cycles64(void)
++{
++    static uint64_t last_get_cycles64 = 0;
++    uint64_t ret;
++    unsigned long sec;
++    unsigned long usec, usec_offset;
++
++again:
++    sec  = xtime.tv_sec;
++    usec = xtime.tv_usec;
++    usec_offset = do_gettimeoffset();
++    if ((xtime.tv_sec != sec)  ||
++	(xtime.tv_usec != usec)||
++	(usec_offset >= 20000))
++	goto again;
++
++    ret = ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency);
++    /* We can't do a normal 64 bit division on mips without libgcc.a */
++    do_div(ret,1000000);
++    ret +=  ((uint64_t)sec * cpu_cycle_frequency);
++
++    /* XXX why does time go backwards?  do_gettimeoffset?  general time adj? */
++    if (ret <= last_get_cycles64)
++	ret  = last_get_cycles64+1;
++    last_get_cycles64 = ret;
++
++    return ret;
++}
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ */
++#define INDEX_MASK   0x7FFF0000
++#define READERS_MASK 0x0000FFFF
++#define INDEX_SHIFT 16
++#define PUT_INDEX(lockp,index)   \
++        lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
++#define GET_INDEX(lockp) \
++        (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++	volatile int lock;
++	unsigned short index;
++	unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++	int tmp = (int) rwlock_ptr->lock;
++	return (tmp >= 0) ? tmp : 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->lock > 0)
++
++#endif /* _ASM_LOCKMETER_H */
+--- linux-2.6.0-test6/include/asm-mips/pgtable-32.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-mips/pgtable-32.h	2003-10-05 00:33:24.000000000 -0700
+@@ -79,7 +79,6 @@ extern int add_temporary_entry(unsigned 
+ #define FIRST_USER_PGD_NR	0
+ 
+ #define VMALLOC_START     KSEG2
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ 
+ #if CONFIG_HIGHMEM
+ # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
+--- linux-2.6.0-test6/include/asm-mips/pgtable-64.h	2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-mips/pgtable-64.h	2003-10-05 00:33:24.000000000 -0700
+@@ -64,7 +64,6 @@
+ #define FIRST_USER_PGD_NR	0
+ 
+ #define VMALLOC_START		XKSEG
+-#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+ #define VMALLOC_END	\
+ 	(VMALLOC_START + ((1 << PGD_ORDER) * PTRS_PER_PTE * PAGE_SIZE))
+ 
+--- linux-2.6.0-test6/include/asm-mips/spinlock.h	2003-07-02 14:53:17.000000000 -0700
++++ 25/include/asm-mips/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -91,9 +91,18 @@ static inline unsigned int _raw_spin_try
+ 
+ typedef struct {
+ 	volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++	/* required for LOCKMETER since all bits in lock are used */
++	/* and we need this storage for CPU and lock INDEX        */
++	unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
+ 
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
++#endif
+ 
+ #define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ 
+--- linux-2.6.0-test6/include/asm-parisc/atomic.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/atomic.h	2003-10-05 00:33:24.000000000 -0700
+@@ -129,8 +129,9 @@ __cmpxchg(volatile void *ptr, unsigned l
+ 
+ 
+ /* It's possible to reduce all atomic operations to either
+- * __atomic_add_return, __atomic_set and __atomic_ret (the latter
+- * is there only for consistency). */
++ * __atomic_add_return, atomic_set and atomic_read (the latter
++ * is there only for consistency).
++ */
+ 
+ static __inline__ int __atomic_add_return(int i, atomic_t *v)
+ {
+@@ -144,7 +145,7 @@ static __inline__ int __atomic_add_retur
+ 	return ret;
+ }
+ 
+-static __inline__ void __atomic_set(atomic_t *v, int i) 
++static __inline__ void atomic_set(atomic_t *v, int i) 
+ {
+ 	unsigned long flags;
+ 	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(v), flags);
+@@ -154,28 +155,25 @@ static __inline__ void __atomic_set(atom
+ 	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(v), flags);
+ }
+ 
+-static __inline__ int __atomic_read(atomic_t *v)
++static __inline__ int atomic_read(const atomic_t *v)
+ {
+ 	return v->counter;
+ }
+ 
+ /* exported interface */
+ 
+-#define atomic_add(i,v)		((void)(__atomic_add_return( (i),(v))))
+-#define atomic_sub(i,v)		((void)(__atomic_add_return(-(i),(v))))
+-#define atomic_inc(v)		((void)(__atomic_add_return(   1,(v))))
+-#define atomic_dec(v)		((void)(__atomic_add_return(  -1,(v))))
++#define atomic_add(i,v)	((void)(__atomic_add_return( ((int)i),(v))))
++#define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)i),(v))))
++#define atomic_inc(v)	((void)(__atomic_add_return(   1,(v))))
++#define atomic_dec(v)	((void)(__atomic_add_return(  -1,(v))))
+ 
+-#define atomic_add_return(i,v)	(__atomic_add_return( (i),(v)))
+-#define atomic_sub_return(i,v)	(__atomic_add_return(-(i),(v)))
++#define atomic_add_return(i,v)	(__atomic_add_return( ((int)i),(v)))
++#define atomic_sub_return(i,v)	(__atomic_add_return(-((int)i),(v)))
+ #define atomic_inc_return(v)	(__atomic_add_return(   1,(v)))
+ #define atomic_dec_return(v)	(__atomic_add_return(  -1,(v)))
+ 
+ #define atomic_dec_and_test(v)	(atomic_dec_return(v) == 0)
+ 
+-#define atomic_set(v,i)		(__atomic_set((v),i))
+-#define atomic_read(v)		(__atomic_read(v))
+-
+ #define ATOMIC_INIT(i)	{ (i) }
+ 
+ #define smp_mb__before_atomic_dec()	smp_mb()
+--- linux-2.6.0-test6/include/asm-parisc/bitops.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/bitops.h	2003-10-05 00:33:24.000000000 -0700
+@@ -232,24 +232,24 @@ static __inline__ unsigned long __ffs(un
+ #if BITS_PER_LONG > 32
+ 		" ldi       63,%1\n"
+ 		" extrd,u,*<>  %0,63,32,%%r0\n"
+-		" extrd,u,*TR  %0,31,32,%0\n"
++		" extrd,u,*TR  %0,31,32,%0\n"	/* move top 32-bits down */
+ 		" addi    -32,%1,%1\n"
+ #else
+ 		" ldi       31,%1\n"
+ #endif
+ 		" extru,<>  %0,31,16,%%r0\n"
+-		" extru,TR  %0,15,16,%0\n"
++		" extru,TR  %0,15,16,%0\n"	/* xxxx0000 -> 0000xxxx */
+ 		" addi    -16,%1,%1\n"
+ 		" extru,<>  %0,31,8,%%r0\n"
+-		" extru,TR  %0,23,8,%0\n"
++		" extru,TR  %0,23,8,%0\n"	/* 0000xx00 -> 000000xx */
+ 		" addi    -8,%1,%1\n"
+ 		" extru,<>  %0,31,4,%%r0\n"
+-		" extru,TR  %0,27,4,%0\n"
++		" extru,TR  %0,27,4,%0\n"	/* 000000x0 -> 0000000x */
+ 		" addi    -4,%1,%1\n"
+ 		" extru,<>  %0,31,2,%%r0\n"
+-		" extru,TR  %0,29,2,%0\n"
++		" extru,TR  %0,29,2,%0\n"	/* 0000000y, 1100b -> 0011b */
+ 		" addi    -2,%1,%1\n"
+-		" extru,=  %0,31,1,%%r0\n"
++		" extru,=  %0,31,1,%%r0\n"	/* check last bit */
+ 		" addi    -1,%1,%1\n"
+ 			: "+r" (x), "=r" (ret) );
+ 	return ret;
+@@ -291,7 +291,7 @@ static __inline__ int fls(int x)
+ 	"	zdep,TR		%0,27,28,%0\n"		/* x0000000 */
+ 	"	addi		4,%1,%1\n"
+ 	"	extru,<>	%0,1,2,%%r0\n"
+-	"	zdep,TR		%0,29,30,%0\n"		/* y0000000 (y&3 = 0 */
++	"	zdep,TR		%0,29,30,%0\n"		/* y0000000 (y&3 = 0) */
+ 	"	addi		2,%1,%1\n"
+ 	"	extru,=		%0,0,1,%%r0\n"
+ 	"	addi		1,%1,%1\n"		/* if y & 8, add 1 */
+--- linux-2.6.0-test6/include/asm-parisc/cacheflush.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -30,6 +30,9 @@ static inline void flush_cache_all(void)
+ 	on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1);
+ }
+ 
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
++
+ /* The following value needs to be tuned and probably scaled with the
+  * cache size.
+  */
+@@ -82,6 +85,13 @@ static inline void flush_dcache_page(str
+         flush_user_dcache_range(addr, addr + len); \
+ 	flush_user_icache_range(addr, addr + len); } while (0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ static inline void flush_cache_range(struct vm_area_struct *vma,
+ 		unsigned long start, unsigned long end)
+ {
+--- linux-2.6.0-test6/include/asm-parisc/dma-mapping.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/asm-parisc/dma-mapping.h	2003-10-05 00:33:24.000000000 -0700
+@@ -2,6 +2,7 @@
+ #define _PARISC_DMA_MAPPING_H
+ 
+ #include <linux/mm.h>
++#include <linux/config.h>
+ #include <asm/cacheflush.h>
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-parisc/elf.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -144,6 +144,30 @@
+ #define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+ #define R_PARISC_HIRESERVE	255
+ 
++#define PA_PLABEL_FDESC		0x02	/* bit set if PLABEL points to
++					 * a function descriptor, not
++					 * an address */
++
++/* The following are PA function descriptors 
++ *
++ * addr:	the absolute address of the function
++ * gp:		either the data pointer (r27) for non-PIC code or the
++ *		the PLT pointer (r19) for PIC code */
++
++/* Format for the Elf32 Function descriptor */
++typedef struct elf32_fdesc {
++	__u32	addr;
++	__u32	gp;
++} Elf32_Fdesc;
++
++/* Format for the Elf64 Function descriptor */
++typedef struct elf64_fdesc {
++	__u64	dummy[2]; /* FIXME: nothing uses these, why waste
++			   * the space */
++	__u64	addr;
++	__u64	gp;
++} Elf64_Fdesc;
++
+ /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+ 
+ #define PT_HP_TLS		(PT_LOOS + 0x0)
+@@ -215,7 +239,10 @@ typedef unsigned long elf_greg_t;
+ 
+ #ifdef __KERNEL__
+ #define SET_PERSONALITY(ex, ibcs2) \
+-	current->personality = PER_LINUX
++	current->personality = PER_LINUX; \
++	current->thread.map_base = DEFAULT_MAP_BASE; \
++	current->thread.task_size = DEFAULT_TASK_SIZE \
++
+ #endif
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-parisc/ioctl.h	2003-06-14 12:17:55.000000000 -0700
++++ 25/include/asm-parisc/ioctl.h	2003-10-05 00:33:24.000000000 -0700
+@@ -44,11 +44,21 @@
+ 	 ((nr)   << _IOC_NRSHIFT) | \
+ 	 ((size) << _IOC_SIZESHIFT))
+ 
++/* provoke compile error for invalid uses of size argument */
++extern int __invalid_size_argument_for_IOC;
++#define _IOC_TYPECHECK(t) \
++	((sizeof(t) == sizeof(t[1]) && \
++	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
++	  sizeof(t) : __invalid_size_argument_for_IOC)
++
+ /* used to create numbers */
+ #define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+-#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+-#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+-#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
++#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
++#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
++#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+ 
+ /* used to decode ioctl numbers.. */
+ #define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+--- linux-2.6.0-test6/include/asm-parisc/irq.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/asm-parisc/irq.h	2003-10-05 00:33:24.000000000 -0700
+@@ -17,6 +17,7 @@
+ 
+ #include <linux/string.h>
+ #include <linux/interrupt.h>
++#include <linux/config.h>
+ 
+ 
+ #define CPU_IRQ_REGION		1
+--- linux-2.6.0-test6/include/asm-parisc/keyboard.h	2003-06-14 12:18:04.000000000 -0700
++++ 25/include/asm-parisc/keyboard.h	2003-10-05 00:33:24.000000000 -0700
+@@ -25,8 +25,6 @@
+ #ifndef _PARISC_KEYBOARD_H
+ #define _PARISC_KEYBOARD_H
+ 
+-#include <linux/config.h>
+-
+ #ifdef __KERNEL__
+ 
+ #include <linux/kernel.h>
+--- linux-2.6.0-test6/include/asm-parisc/page.h	2003-06-14 12:18:00.000000000 -0700
++++ 25/include/asm-parisc/page.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,6 +7,7 @@
+ #define PAGE_MASK	(~(PAGE_SIZE-1))
+ 
+ #ifdef __KERNEL__
++#include <linux/config.h>
+ #ifndef __ASSEMBLY__
+ 
+ #include <asm/cache.h>
+--- linux-2.6.0-test6/include/asm-parisc/param.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-parisc/param.h	2003-10-05 00:33:24.000000000 -0700
+@@ -2,6 +2,7 @@
+ #define _ASMPARISC_PARAM_H
+ 
+ #ifdef __KERNEL__
++#include <linux/config.h>
+ # ifdef CONFIG_PA20
+ #  define HZ		1000		/* Faster machines */
+ # else
+--- linux-2.6.0-test6/include/asm-parisc/pci.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-parisc/pci.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,6 +1,7 @@
+ #ifndef __ASM_PARISC_PCI_H
+ #define __ASM_PARISC_PCI_H
+ 
++#include <linux/config.h>
+ #include <asm/scatterlist.h>
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-parisc/pdc.h	2003-06-14 12:17:55.000000000 -0700
++++ 25/include/asm-parisc/pdc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,6 +1,8 @@
+ #ifndef _PARISC_PDC_H
+ #define _PARISC_PDC_H
+ 
++#include <linux/config.h>
++
+ /*
+  *	PDC return values ...
+  *	All PDC calls return a subset of these errors. 
+@@ -191,8 +193,8 @@ typedef struct {
+ 
+ #define PDC_IO		135		/* log error info, reset IO system */
+ #define PDC_IO_READ_AND_CLEAR_ERRORS	0
+-#define PDC_IO_READ_AND_LOG_ERRORS	1
+-#define PDC_IO_SUSPEND_USB		2
++#define PDC_IO_RESET			1
++#define PDC_IO_RESET_DEVICES		2
+ /* sets bits 6&7 (little endian) of the HcControl Register */
+ #define PDC_IO_USB_SUSPEND	0xC000000000000000
+ #define PDC_IO_EEPROM_IO_ERR_TABLE_FULL	-5	/* return value */
+@@ -951,7 +953,8 @@ int pdc_do_firm_test_reset(unsigned long
+ int pdc_do_reset(void);
+ int pdc_soft_power_info(unsigned long *power_reg);
+ int pdc_soft_power_button(int sw_control);
+-void pdc_suspend_usb(void);
++void pdc_io_reset(void);
++void pdc_io_reset_devices(void);
+ int pdc_iodc_getc(void);
+ void pdc_iodc_putc(unsigned char c);
+ void pdc_iodc_outc(unsigned char c);
+--- linux-2.6.0-test6/include/asm-parisc/pgalloc.h	2003-06-14 12:18:35.000000000 -0700
++++ 25/include/asm-parisc/pgalloc.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,7 +1,6 @@
+ #ifndef _ASM_PGALLOC_H
+ #define _ASM_PGALLOC_H
+ 
+-#include <linux/config.h>
+ #include <linux/gfp.h>
+ #include <linux/mm.h>
+ #include <linux/threads.h>
+--- linux-2.6.0-test6/include/asm-parisc/pgtable.h	2003-07-13 21:44:35.000000000 -0700
++++ 25/include/asm-parisc/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -1,6 +1,7 @@
+ #ifndef _PARISC_PGTABLE_H
+ #define _PARISC_PGTABLE_H
+ 
++#include <linux/config.h>
+ #include <asm/fixmap.h>
+ 
+ #ifndef __ASSEMBLY__
+@@ -108,7 +109,6 @@
+ extern  void *vmalloc_start;
+ #define PCXL_DMA_MAP_SIZE   (8*1024*1024)
+ #define VMALLOC_START   ((unsigned long)vmalloc_start)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ /* this is a fixmap remnant, see fixmap.h */
+ #define VMALLOC_END	(TMPALIAS_MAP_START)
+ #endif
+--- linux-2.6.0-test6/include/asm-parisc/processor.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/processor.h	2003-10-05 00:33:24.000000000 -0700
+@@ -36,10 +36,18 @@
+ #define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; })
+ 
+ #define TASK_SIZE               (current->thread.task_size)
+-#define DEFAULT_TASK_SIZE       (0xFFF00000UL)
+-
+ #define TASK_UNMAPPED_BASE      (current->thread.map_base)
+-#define DEFAULT_MAP_BASE        (0x40000000UL)
++
++#define DEFAULT_TASK_SIZE32	(0xFFF00000UL)
++#define DEFAULT_MAP_BASE32	(0x40000000UL)
++
++#ifdef __LP64__
++#define DEFAULT_TASK_SIZE       (MAX_ADDRESS-0xf000000)
++#define DEFAULT_MAP_BASE        (0x200000000UL)
++#else
++#define DEFAULT_TASK_SIZE	DEFAULT_TASK_SIZE32
++#define DEFAULT_MAP_BASE	DEFAULT_MAP_BASE32
++#endif
+ 
+ #ifndef __ASSEMBLY__
+ 
+@@ -247,8 +255,18 @@ on downward growing arches, it looks lik
+  *
+  * Note that the S/390 people took the easy way out and hacked their
+  * GCC to make the stack grow downwards.
++ *
++ * Final Note: For entry from syscall, the W (wide) bit of the PSW
++ * is stuffed into the lowest bit of the user sp (%r30), so we fill
++ * it in here from the current->personality
+  */
+ 
++#ifdef __LP64__
++#define USER_WIDE_MODE	(personality(current->personality) == PER_LINUX)
++#else
++#define USER_WIDE_MODE	0
++#endif
++
+ #define start_thread(regs, new_pc, new_sp) do {		\
+ 	elf_addr_t *sp = (elf_addr_t *)new_sp;		\
+ 	__u32 spaceid = (__u32)current->mm->context;	\
+@@ -266,12 +284,12 @@ on downward growing arches, it looks lik
+ 	regs->sr[5] = spaceid;				\
+ 	regs->sr[6] = spaceid;				\
+ 	regs->sr[7] = spaceid;				\
+-	regs->gr[ 0] = USER_PSW;                        \
++	regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \
+ 	regs->fr[ 0] = 0LL;                            	\
+ 	regs->fr[ 1] = 0LL;                            	\
+ 	regs->fr[ 2] = 0LL;                            	\
+ 	regs->fr[ 3] = 0LL;                            	\
+-	regs->gr[30] = ((unsigned long)sp + 63) &~ 63;	\
++	regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \
+ 	regs->gr[31] = pc;				\
+ 							\
+ 	get_user(regs->gr[25], (argv - 1));		\
+@@ -299,8 +317,6 @@ static inline unsigned long get_wchan(st
+ #define KSTK_EIP(tsk)	((tsk)->thread.regs.iaoq[0])
+ #define KSTK_ESP(tsk)	((tsk)->thread.regs.gr[30])
+ 
+-#endif /* __ASSEMBLY__ */
+-
+ #ifdef  CONFIG_PA20
+ #define ARCH_HAS_PREFETCH
+ extern inline void prefetch(const void *addr)
+@@ -317,4 +333,6 @@ extern inline void prefetchw(const void 
+ 
+ #define cpu_relax()	barrier()
+ 
++#endif /* __ASSEMBLY__ */
++
+ #endif /* __ASM_PARISC_PROCESSOR_H */
+--- linux-2.6.0-test6/include/asm-parisc/rt_sigframe.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-parisc/rt_sigframe.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,7 +13,20 @@ struct rt_sigframe {
+  * which Linux/parisc uses is sp-20 for the saved return pointer...)
+  * Then, the stack pointer must be rounded to a cache line (64 bytes).
+  */
++#define SIGFRAME32		64
++#define FUNCTIONCALLFRAME32	48
++#define PARISC_RT_SIGFRAME_SIZE32					\
++	(((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
++
++#ifdef __LP64__
++#define	SIGFRAME		128
++#define FUNCTIONCALLFRAME	96
+ #define PARISC_RT_SIGFRAME_SIZE					\
+-	(((sizeof(struct rt_sigframe) + 48) + 63) & -64)
++	(((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME) + SIGFRAME) & -SIGFRAME)
++#else
++#define	SIGFRAME		SIGFRAME32
++#define FUNCTIONCALLFRAME	FUNCTIONCALLFRAME32
++#define PARISC_RT_SIGFRAME_SIZE	PARISC_RT_SIGFRAME_SIZE32
++#endif
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-parisc/tlbflush.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-parisc/tlbflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -3,6 +3,7 @@
+ 
+ /* TLB flushing routines.... */
+ 
++#include <linux/config.h>
+ #include <linux/mm.h>
+ #include <asm/mmu_context.h>
+ 
+--- linux-2.6.0-test6/include/asm-ppc64/cacheflush.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-ppc64/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -14,12 +14,22 @@
+ #define flush_cache_range(vma, start, end)	do { } while (0)
+ #define flush_cache_page(vma, vmaddr)		do { } while (0)
+ #define flush_icache_page(vma, page)		do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
+ 
+ extern void flush_dcache_page(struct page *page);
+ extern void flush_icache_range(unsigned long, unsigned long);
+ extern void flush_icache_user_range(struct vm_area_struct *vma,
+ 				    struct page *page, unsigned long addr,
+ 				    int len);
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ extern void __flush_dcache_icache(void *page_va);
+ 
+ #endif /* _PPC64_CACHEFLUSH_H */
+--- linux-2.6.0-test6/include/asm-ppc64/elf.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-ppc64/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -128,11 +128,6 @@ static inline int dump_task_regs(struct 
+ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); 
+ #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+ 
+-#ifdef CONFIG_SMP
+-extern void dump_smp_unlazy_fpu(void);
+-#define ELF_CORE_SYNC dump_smp_unlazy_fpu
+-#endif
+-
+ #endif
+ 
+ /* This yields a mask that user programs can use to figure out what
+--- linux-2.6.0-test6/include/asm-ppc64/numnodes.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-ppc64/numnodes.h	2003-10-05 00:34:38.000000000 -0700
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+ 
+-#define MAX_NUMNODES 16
++/* Max 16 Nodes */
++#define NODES_SHIFT	4
+ 
+ #endif /* _ASM_MAX_NUMNODES_H */
+--- linux-2.6.0-test6/include/asm-ppc64/pgtable.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc64/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -45,7 +45,6 @@
+  * Define the address range of the vmalloc VM area.
+  */
+ #define VMALLOC_START (0xD000000000000000)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END   (VMALLOC_START + VALID_EA_BITS)
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-ppc64/semaphore.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc64/semaphore.h	2003-10-05 00:34:19.000000000 -0700
+@@ -22,6 +22,7 @@ struct semaphore {
+ 	 * sleeping on `wait'.
+ 	 */
+ 	atomic_t count;
++	int sleepers;
+ 	wait_queue_head_t wait;
+ #ifdef WAITQUEUE_DEBUG
+ 	long __magic;
+@@ -37,6 +38,7 @@ struct semaphore {
+ 
+ #define __SEMAPHORE_INITIALIZER(name, count) \
+ 	{ ATOMIC_INIT(count), \
++	  0, \
+ 	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+ 	  __SEM_DEBUG_INIT(name) }
+ 
+@@ -52,6 +54,7 @@ struct semaphore {
+ static inline void sema_init (struct semaphore *sem, int val)
+ {
+ 	atomic_set(&sem->count, val);
++	sem->sleepers = 0;
+ 	init_waitqueue_head(&sem->wait);
+ #ifdef WAITQUEUE_DEBUG
+ 	sem->__magic = (long)&sem->__magic;
+--- linux-2.6.0-test6/include/asm-ppc/cacheflush.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-ppc/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -24,12 +24,21 @@
+ #define flush_cache_range(vma, a, b)	do { } while (0)
+ #define flush_cache_page(vma, p)	do { } while (0)
+ #define flush_icache_page(vma, page)	do { } while (0)
++#define flush_cache_vmap(start, end)	do { } while (0)
++#define flush_cache_vunmap(start, end)	do { } while (0)
+ 
+ extern void flush_dcache_page(struct page *page);
+ extern void flush_icache_range(unsigned long, unsigned long);
+ extern void flush_icache_user_range(struct vm_area_struct *vma,
+ 		struct page *page, unsigned long addr, int len);
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ extern void __flush_dcache_icache(void *page_va);
+ extern void __flush_dcache_icache_phys(unsigned long physaddr);
+ 
+--- linux-2.6.0-test6/include/asm-ppc/highmem.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc/highmem.h	2003-10-05 00:33:24.000000000 -0700
+@@ -132,6 +132,8 @@ static inline struct page *kmap_atomic_t
+ 	return pte_page(kmap_pte[idx]);
+ }
+ 
++#define flush_cache_kmaps()	flush_cache_all()
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _ASM_HIGHMEM_H */
+--- linux-2.6.0-test6/include/asm-ppc/pgtable.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -129,7 +129,6 @@ extern unsigned long ioremap_bot, iorema
+ #else
+ #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+ #endif
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END	ioremap_bot
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-ppc/zorro.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-ppc/zorro.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,4 +27,4 @@ extern void *__ioremap(unsigned long add
+ #define z_ioremap ioremap
+ #define z_iounmap iounmap
+ 
+-#endif /* _ASM_ZORRO_H */
++#endif /* _ASM_PPC_ZORRO_H */
+--- linux-2.6.0-test6/include/asm-s390/cacheflush.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-s390/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,5 +13,12 @@
+ #define flush_icache_range(start, end)		do { } while (0)
+ #define flush_icache_page(vma,pg)		do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ #endif /* _S390_CACHEFLUSH_H */
+--- linux-2.6.0-test6/include/asm-s390/pgtable.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-s390/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -117,7 +117,6 @@ extern char empty_zero_page[PAGE_SIZE];
+ #define VMALLOC_OFFSET  (8*1024*1024)
+ #define VMALLOC_START   (((unsigned long) high_memory + VMALLOC_OFFSET) \
+ 			 & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #ifndef __s390x__
+ # define VMALLOC_END     (0x7fffffffL)
+ #else /* __s390x__ */
+--- linux-2.6.0-test6/include/asm-sh/cacheflush.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/asm-sh/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -10,4 +10,14 @@ extern void __flush_purge_region(void *s
+ /* Flush (invalidate only) a region (smaller than a page) */
+ extern void __flush_invalidate_region(void *start, int size);
+ 
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ #endif /* __ASM_SH_CACHEFLUSH_H */
+--- linux-2.6.0-test6/include/asm-sh/mmzone.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/asm-sh/mmzone.h	2003-10-05 00:34:40.000000000 -0700
+@@ -10,14 +10,14 @@
+ 
+ #include <linux/config.h>
+ 
++#ifdef CONFIG_DISCONTIGMEM
++
+ /* Currently, just for HP690 */
+ #define PHYSADDR_TO_NID(phys)	((((phys) - __MEMORY_START) >= 0x01000000)?1:0)
+-#define NR_NODES 2
+ 
+-extern pg_data_t discontig_page_data[NR_NODES];
+-extern bootmem_data_t discontig_node_bdata[NR_NODES];
++extern pg_data_t discontig_page_data[MAX_NUMNODES];
++extern bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
+ 
+-#ifdef CONFIG_DISCONTIGMEM
+ /*
+  * Following are macros that each numa implmentation must define.
+  */
+@@ -46,7 +46,7 @@ static inline int is_valid_page(struct p
+ {
+ 	unsigned int i;
+ 
+-	for (i = 0; i < NR_NODES; i++) {
++	for (i = 0; i < MAX_NUMNODES; i++) {
+ 		if (page >= NODE_MEM_MAP(i) &&
+ 		    page < NODE_MEM_MAP(i) + NODE_DATA(i)->node_size)
+ 			return 1;
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sh/numnodes.h	2003-10-05 00:34:40.000000000 -0700
+@@ -0,0 +1,7 @@
++#ifndef _ASM_MAX_NUMNODES_H
++#define _ASM_MAX_NUMNODES_H
++
++/* Max 2 Nodes */
++#define NODES_SHIFT	1
++
++#endif /* _ASM_MAX_NUMNODES_H */
+--- linux-2.6.0-test6/include/asm-sh/pgtable.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/asm-sh/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -51,7 +51,6 @@ extern unsigned long empty_zero_page[102
+  * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c)
+  */
+ #define VMALLOC_START	(P3SEG+0x00100000)
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END	P4SEG
+ 
+ /*			0x001     WT-bit on SH-4, 0 on SH-3 */
+--- linux-2.6.0-test6/include/asm-sparc64/cacheflush.h	2003-06-14 12:18:35.000000000 -0700
++++ 25/include/asm-sparc64/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -33,21 +33,17 @@ extern void flush_dcache_page_all(struct
+ 
+ extern void __flush_dcache_range(unsigned long start, unsigned long end);
+ 
+-extern void __flush_cache_all(void);
+-
+-#ifndef CONFIG_SMP
+-
+-#define flush_cache_all()	__flush_cache_all()
+-
+-#else /* CONFIG_SMP */
+-
+-extern void smp_flush_cache_all(void);
+-
+-#endif /* ! CONFIG_SMP */
+-
+ #define flush_icache_page(vma, pg)	do { } while(0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ extern void flush_dcache_page(struct page *page);
+ 
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
++
+ #endif /* _SPARC64_CACHEFLUSH_H */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sparc64/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
++ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
++ */
++
++#ifndef _SPARC64_LOCKMETER_H
++#define _SPARC64_LOCKMETER_H
++
++#include <linux/smp.h>
++#include <asm/spinlock.h>
++#include <asm/timer.h>
++#include <asm/timex.h>
++
++/* Actually, this is not the CPU frequency by the system tick
++ * frequency which is good enough for lock metering.
++ */
++#define CPU_CYCLE_FREQUENCY	(timer_tick_offset * HZ)
++#define THIS_CPU_NUMBER		smp_processor_id()
++
++#define PUT_INDEX(lock_ptr,indexv)	(lock_ptr)->index = (indexv)
++#define GET_INDEX(lock_ptr)		(lock_ptr)->index
++
++#define PUT_RWINDEX(rwlock_ptr,indexv) (rwlock_ptr)->index = (indexv)
++#define GET_RWINDEX(rwlock_ptr)        (rwlock_ptr)->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    (rwlock_ptr)->cpu = (cpuv)
++#define GET_RW_CPU(rwlock_ptr)         (rwlock_ptr)->cpu
++
++#define RWLOCK_READERS(rwlock_ptr)	rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++	signed int tmp = rwlock_ptr->lock;
++
++	if (tmp > 0)
++		return tmp;
++	else
++		return 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr)	((signed int)((rwlock_ptr)->lock) < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)	((signed int)((rwlock_ptr)->lock) > 0)
++
++#define get_cycles64()	get_cycles()
++
++#endif /* _SPARC64_LOCKMETER_H */
+--- linux-2.6.0-test6/include/asm-sparc64/pgtable.h	2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-sparc64/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -30,7 +30,6 @@
+ #define MODULES_LEN		0x000000007e000000
+ #define MODULES_END		0x0000000080000000
+ #define VMALLOC_START		0x0000000140000000
+-#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+ #define VMALLOC_END		0x0000000200000000
+ #define LOW_OBP_ADDRESS		0x00000000f0000000
+ #define HI_OBP_ADDRESS		0x0000000100000000
+--- linux-2.6.0-test6/include/asm-sparc64/spinlock.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/asm-sparc64/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -30,15 +30,23 @@
+ 
+ #ifndef CONFIG_DEBUG_SPINLOCK
+ 
+-typedef unsigned char spinlock_t;
+-#define SPIN_LOCK_UNLOCKED	0
++typedef struct {
++	unsigned char lock;
++	unsigned int  index;
++} spinlock_t;
+ 
+-#define spin_lock_init(lock)	(*((unsigned char *)(lock)) = 0)
+-#define spin_is_locked(lock)	(*((volatile unsigned char *)(lock)) != 0)
++#ifdef CONFIG_LOCKMETER
++#define SPIN_LOCK_UNLOCKED	(spinlock_t) {0, 0}
++#else
++#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
++#endif
+ 
+-#define spin_unlock_wait(lock)	\
++#define spin_lock_init(__lock)	do { *(__lock) = SPIN_LOCK_UNLOCKED; } while(0)
++#define spin_is_locked(__lock)	(*((volatile unsigned char *)(&((__lock)->lock))) != 0)
++
++#define spin_unlock_wait(__lock)	\
+ do {	membar("#LoadLoad");	\
+-} while(*((volatile unsigned char *)lock))
++} while(*((volatile unsigned char *)(&(((spinlock_t *)__lock)->lock))))
+ 
+ static __inline__ void _raw_spin_lock(spinlock_t *lock)
+ {
+@@ -109,18 +117,34 @@ extern int _spin_trylock (spinlock_t *lo
+ 
+ #ifndef CONFIG_DEBUG_SPINLOCK
+ 
+-typedef unsigned int rwlock_t;
+-#define RW_LOCK_UNLOCKED	0
+-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
+-#define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
++#ifdef CONFIG_LOCKMETER
++typedef struct {
++	unsigned int lock;
++	unsigned int index;
++	unsigned int cpu;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED       (rwlock_t) { 0, 0, 0xff }
++#else
++typedef struct {
++	unsigned int lock;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED        (rwlock_t) { 0 }
++#endif
++
++#define rwlock_init(lp)		do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
++#define rwlock_is_locked(x)	((x)->lock != 0)
+ 
++extern int __read_trylock(rwlock_t *);
+ extern void __read_lock(rwlock_t *);
+ extern void __read_unlock(rwlock_t *);
++extern int __write_trylock(rwlock_t *);
+ extern void __write_lock(rwlock_t *);
+ extern void __write_unlock(rwlock_t *);
+ 
++#define _raw_read_trylock(p)	__read_trylock(p)
+ #define _raw_read_lock(p)	__read_lock(p)
+ #define _raw_read_unlock(p)	__read_unlock(p)
++#define _raw_write_trylock(p)	__write_trylock(p)
+ #define _raw_write_lock(p)	__write_lock(p)
+ #define _raw_write_unlock(p)	__write_unlock(p)
+ 
+--- linux-2.6.0-test6/include/asm-sparc64/tlbflush.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-sparc64/tlbflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -70,7 +70,6 @@ extern void smp_flush_tlb_range(struct m
+ extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
+ extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page);
+ 
+-#define flush_cache_all()	smp_flush_cache_all()
+ #define flush_tlb_all()		smp_flush_tlb_all()
+ #define flush_tlb_mm(mm)	smp_flush_tlb_mm(mm)
+ #define flush_tlb_range(vma, start, end) \
+--- linux-2.6.0-test6/include/asm-sparc64/unistd.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-sparc64/unistd.h	2003-10-05 00:33:24.000000000 -0700
+@@ -285,7 +285,8 @@
+ #define __NR_timer_getoverrun	264
+ #define __NR_timer_delete	265
+ #define __NR_timer_create	266
+-/* WARNING: You MAY NOT add syscall numbers larger than 266, since
++/* #define __NR_vserver		267 Reserved for VSERVER */
++/* WARNING: You MAY NOT add syscall numbers larger than 267, since
+  *          all of the syscall tables in the Sparc kernel are
+  *          sized to have 267 entries (starting at zero).  Therefore
+  *          find a free slot in the 0-266 range.
+--- linux-2.6.0-test6/include/asm-sparc64/visasm.h	2003-06-14 12:17:58.000000000 -0700
++++ 25/include/asm-sparc64/visasm.h	2003-10-05 00:33:24.000000000 -0700
+@@ -17,7 +17,8 @@
+ 	andcc		%o5, (FPRS_FEF|FPRS_DU), %g0;	\
+ 	be,pt		%icc, 297f;			\
+ 	 sethi		%hi(297f), %g7;			\
+-	ba,pt		%xcc, VISenter;			\
++	sethi		%hi(VISenter), %g1;		\
++	jmpl		%g1 + %lo(VISenter), %g0;	\
+ 	 or		%g7, %lo(297f), %g7;		\
+ 297:	wr		%g0, FPRS_FEF, %fprs;		\
+ 
+@@ -32,7 +33,8 @@
+ 	andcc		%o5, FPRS_FEF, %g0;		\
+ 	be,pt		%icc, 297f;			\
+ 	 sethi		%hi(298f), %g7;			\
+-	ba,pt		%xcc, VISenterhalf;		\
++	sethi		%hi(VISenterhalf), %g1;		\
++	jmpl		%g1 + %lo(VISenterhalf), %g0;	\
+ 	 or		%g7, %lo(298f), %g7;		\
+ 	clr		%o5;				\
+ 297:	wr		%o5, FPRS_FEF, %fprs;		\
+@@ -48,7 +50,8 @@ static __inline__ void save_and_clear_fp
+ "		andcc %%o5, %0, %%g0\n"
+ "		be,pt %%icc, 299f\n"
+ "		 sethi %%hi(298f), %%g7\n"
+-"		ba VISenter	! Note. This cannot be bp, as it may be too far from VISenter.\n"
++"		sethi %%hi(VISenter), %%g1\n"
++"		jmpl %%g1 + %%lo(VISenter), %%g0\n"
+ "		 or %%g7, %%lo(298f), %%g7\n"
+ "	298:	wr %%g0, 0, %%fprs\n"
+ "	299:\n"
+--- linux-2.6.0-test6/include/asm-sparc/cacheflush.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/include/asm-sparc/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -56,6 +56,11 @@ BTFIXUPDEF_CALL(void, flush_cache_page, 
+ 
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++
+ BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
+ BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
+ 
+@@ -66,4 +71,7 @@ extern void sparc_flush_page_to_ram(stru
+ 
+ #define flush_dcache_page(page)			sparc_flush_page_to_ram(page)
+ 
++#define flush_cache_vmap(start, end)		flush_cache_all()
++#define flush_cache_vunmap(start, end)		flush_cache_all()
++
+ #endif /* _SPARC_CACHEFLUSH_H */
+--- linux-2.6.0-test6/include/asm-sparc/highmem.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-sparc/highmem.h	2003-10-05 00:33:24.000000000 -0700
+@@ -89,6 +89,8 @@ static inline struct page *kmap_atomic_t
+ 	return pte_page(*pte);
+ }
+ 
++#define flush_cache_kmaps()	flush_cache_all()
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _ASM_HIGHMEM_H */
+--- linux-2.6.0-test6/include/asm-sparc/pgtable.h	2003-06-14 12:18:22.000000000 -0700
++++ 25/include/asm-sparc/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -101,8 +101,6 @@ BTFIXUPDEF_SIMM13(ptrs_per_pmd)
+ BTFIXUPDEF_SIMM13(ptrs_per_pgd)
+ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
+ 
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+-
+ #define pte_ERROR(e)   __builtin_trap()
+ #define pmd_ERROR(e)   __builtin_trap()
+ #define pgd_ERROR(e)   __builtin_trap()
+--- linux-2.6.0-test6/include/asm-sparc/unistd.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-sparc/unistd.h	2003-10-05 00:33:24.000000000 -0700
+@@ -283,7 +283,8 @@
+ #define __NR_timer_getoverrun	264
+ #define __NR_timer_delete	265
+ #define __NR_timer_create	266
+-/* WARNING: You MAY NOT add syscall numbers larger than 266, since
++/* #define __NR_vserver		267 Reserved for VSERVER */
++/* WARNING: You MAY NOT add syscall numbers larger than 267, since
+  *          all of the syscall tables in the Sparc kernel are
+  *          sized to have 267 entries (starting at zero).  Therefore
+  *          find a free slot in the 0-266 range.
+--- linux-2.6.0-test6/include/asm-um/archparam-i386.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-um/archparam-i386.h	2003-10-05 00:34:32.000000000 -0700
+@@ -56,6 +56,65 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
+ 	pr_reg[16] = PT_REGS_SS(regs);		\
+ } while(0);
+ 
++#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
++#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
++#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
++extern void *__kernel_vsyscall;
++
++/*
++ * Architecture-neutral AT_ values in 0-17, leave some room
++ * for more of them, start the x86-specific ones at 32.
++ */
++#define AT_SYSINFO		32
++#define AT_SYSINFO_EHDR		33
++
++#define ARCH_DLINFO						\
++do {								\
++		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
++		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
++} while (0)
++
++/*
++ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
++ * extra segments containing the vsyscall DSO contents.  Dumping its
++ * contents makes post-mortem fully interpretable later without matching up
++ * the same kernel and hardware config to see what PC values meant.
++ * Dumping its extra ELF program headers includes all the other information
++ * a debugger needs to easily find how the vsyscall DSO was being used.
++ */
++#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
++#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
++do {									      \
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (VSYSCALL_BASE		      \
++					   + VSYSCALL_EHDR->e_phoff);	      \
++	int i;								      \
++	Elf32_Off ofs = 0;						      \
++	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
++		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
++		if (phdr.p_type == PT_LOAD) {				      \
++			ofs = phdr.p_offset = offset;			      \
++			offset += phdr.p_filesz;			      \
++		}							      \
++		else							      \
++			phdr.p_offset += ofs;				      \
++		phdr.p_paddr = 0; /* match other core phdrs */		      \
++		DUMP_WRITE(&phdr, sizeof(phdr));			      \
++	}								      \
++} while (0)
++#define ELF_CORE_WRITE_EXTRA_DATA					      \
++do {									      \
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (VSYSCALL_BASE		      \
++					   + VSYSCALL_EHDR->e_phoff);	      \
++	int i;								      \
++	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
++		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
++			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
++				   vsyscall_phdrs[i].p_filesz);		      \
++	}								      \
++} while (0)
++
+ /********* Bits for asm-um/delay.h **********/
+ 
+ typedef unsigned long um_udelay_t;
+--- linux-2.6.0-test6/include/asm-um/common.lds.S	2003-06-14 12:18:00.000000000 -0700
++++ 25/include/asm-um/common.lds.S	2003-10-05 00:34:32.000000000 -0700
+@@ -1,3 +1,5 @@
++#include <asm-generic/vmlinux.lds.h>
++
+   .fini      : { *(.fini)    } =0x9090
+   _etext = .;
+   PROVIDE (etext = .);
+@@ -67,6 +69,10 @@
+   }
+   __initcall_end = .;
+ 
++  __con_initcall_start = .;
++  .con_initcall.init : { *(.con_initcall.init) }
++  __con_initcall_end = .;
++
+   __uml_initcall_start = .;
+   .uml.initcall.init : { *(.uml.initcall.init) }
+   __uml_initcall_end = .;
+@@ -80,7 +86,33 @@
+   .uml.exitcall : { *(.uml.exitcall.exit) }
+   __uml_exitcall_end = .;
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(4);
++  __alt_instructions = .;
++  .altinstructions : { *(.altinstructions) } 
++  __alt_instructions_end = .; 
++  .altinstr_replacement : { *(.altinstr_replacement) } 
++  /* .exit.text is discard at runtime, not link time, to deal with references
++     from .altinstructions and .eh_frame */
++  .exit.text : { *(.exit.text) }
++  .exit.data : { *(.exit.data) }
++ 
++  __preinit_array_start = .;
++  .preinit_array : { *(.preinit_array) }
++  __preinit_array_end = .;
++  __init_array_start = .;
++  .init_array : { *(.init_array) }
++  __init_array_end = .;
++  __fini_array_start = .;
++  .fini_array : { *(.fini_array) }
++  __fini_array_end = .;
++
++   . = ALIGN(4096);
+   __initramfs_start = .;
+   .init.ramfs : { *(.init.ramfs) }
+   __initramfs_end = .;
++
++  /* Sections to be discarded */
++  /DISCARD/ : {
++ 	*(.exitcall.exit)
++  }
++ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/cpufeature.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,6 @@
++#ifndef __UM_CPUFEATURE_H
++#define __UM_CPUFEATURE_H
++
++#include "asm/arch/cpufeature.h"
++
++#endif
+--- linux-2.6.0-test6/include/asm-um/current.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-um/current.h	2003-10-05 00:34:32.000000000 -0700
+@@ -16,8 +16,10 @@ struct thread_info;
+ #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
+ 			        (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
+ 
+-#define current ({ int dummy; \
+-                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
++#define current_thread \
++	({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
++
++#define current (current_thread->task)
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+--- linux-2.6.0-test6/include/asm-um/fixmap.h	2003-06-14 12:18:33.000000000 -0700
++++ 25/include/asm-um/fixmap.h	2003-10-05 00:34:32.000000000 -0700
+@@ -34,6 +34,7 @@ enum fixed_addresses {
+ 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+ 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ #endif
++	FIX_VSYSCALL,
+ 	__end_of_fixed_addresses
+ };
+ 
+@@ -63,6 +64,13 @@ extern unsigned long get_kmem_end(void);
+ #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+ #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+ 
++/*
++ * This is the range that is readable by user mode, and things
++ * acting like user mode such as get_user_pages.
++ */
++#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
++#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
++
+ extern void __this_fixmap_does_not_exist(void);
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-um/irq.h	2003-06-14 12:18:49.000000000 -0700
++++ 25/include/asm-um/irq.h	2003-10-05 00:34:32.000000000 -0700
+@@ -1,15 +1,6 @@
+ #ifndef __UM_IRQ_H
+ #define __UM_IRQ_H
+ 
+-/* The i386 irq.h has a struct task_struct in a prototype without including
+- * sched.h.  This forward declaration kills the resulting warning.
+- */
+-struct task_struct;
+-
+-#include "asm/ptrace.h"
+-
+-#undef NR_IRQS
+-
+ #define TIMER_IRQ		0
+ #define UMN_IRQ			1
+ #define CONSOLE_IRQ		2
+@@ -28,8 +19,4 @@ struct task_struct;
+ #define LAST_IRQ XTERM_IRQ
+ #define NR_IRQS (LAST_IRQ + 1)
+ 
+-extern int um_request_irq(unsigned int irq, int fd, int type,
+-			  void (*handler)(int, void *, struct pt_regs *),
+-			  unsigned long irqflags,  const char * devname,
+-			  void *dev_id);
+ #endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/local.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,6 @@
++#ifndef __UM_LOCAL_H
++#define __UM_LOCAL_H
++
++#include "asm/arch/local.h"
++
++#endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/module-generic.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,6 @@
++#ifndef __UM_MODULE_GENERIC_H
++#define __UM_MODULE_GENERIC_H
++
++#include "asm/arch/module.h"
++
++#endif
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/module-i386.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,13 @@
++#ifndef __UM_MODULE_I386_H
++#define __UM_MODULE_I386_H
++
++/* UML is simple */
++struct mod_arch_specific
++{
++};
++
++#define Elf_Shdr Elf32_Shdr
++#define Elf_Sym Elf32_Sym
++#define Elf_Ehdr Elf32_Ehdr
++
++#endif
+--- linux-2.6.0-test6/include/asm-um/page.h	2003-06-14 12:18:23.000000000 -0700
++++ 25/include/asm-um/page.h	2003-10-05 00:34:32.000000000 -0700
+@@ -4,7 +4,6 @@
+ struct page;
+ 
+ #include "asm/arch/page.h"
+-#include "asm/bug.h"
+ 
+ #undef __pa
+ #undef __va
+--- linux-2.6.0-test6/include/asm-um/pgtable.h	2003-06-14 12:18:52.000000000 -0700
++++ 25/include/asm-um/pgtable.h	2003-10-05 00:34:32.000000000 -0700
+@@ -69,7 +69,6 @@ extern unsigned long high_physmem;
+ 
+ #define VMALLOC_OFFSET	(__va_space)
+ #define VMALLOC_START	(((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ 
+ #ifdef CONFIG_HIGHMEM
+ # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
+@@ -79,12 +78,13 @@ extern unsigned long high_physmem;
+ 
+ #define _PAGE_PRESENT	0x001
+ #define _PAGE_NEWPAGE	0x002
+-#define _PAGE_PROTNONE	0x004	/* If not present */
+-#define _PAGE_RW	0x008
+-#define _PAGE_USER	0x010
+-#define _PAGE_ACCESSED	0x020
+-#define _PAGE_DIRTY	0x040
+-#define _PAGE_NEWPROT   0x080
++#define _PAGE_NEWPROT   0x004
++#define _PAGE_FILE	0x008   /* set:pagecache unset:swap */
++#define _PAGE_PROTNONE	0x010	/* If not present */
++#define _PAGE_RW	0x020
++#define _PAGE_USER	0x040
++#define _PAGE_ACCESSED	0x080
++#define _PAGE_DIRTY	0x100
+ 
+ #define REGION_MASK	0xf0000000
+ #define REGION_SHIFT	28
+@@ -203,6 +203,16 @@ extern unsigned long pfn_to_phys(unsigne
+ #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
+ #define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
+ 
++/*
++ * Bits 0 through 3 are taken
++ */
++#define PTE_FILE_MAX_BITS	28
++
++#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
++
++#define pgoff_to_pte(off) \
++	((pte_t) { ((off) << 4) + _PAGE_FILE })
++
+ static inline pte_t pte_mknewprot(pte_t pte)
+ {
+  	pte_val(pte) |= _PAGE_NEWPROT;
+@@ -236,6 +246,12 @@ static inline void set_pte(pte_t *pteptr
+  * The following only work if pte_present() is true.
+  * Undefined behaviour if not..
+  */
++static inline int pte_user(pte_t pte)
++{ 
++	return((pte_val(pte) & _PAGE_USER) && 
++	       !(pte_val(pte) & _PAGE_PROTNONE));
++}
++
+ static inline int pte_read(pte_t pte)
+ { 
+ 	return((pte_val(pte) & _PAGE_USER) && 
+@@ -253,6 +269,14 @@ static inline int pte_write(pte_t pte)
+ 	       !(pte_val(pte) & _PAGE_PROTNONE));
+ }
+ 
++/*
++ * The following only works if pte_present() is not true.
++ */
++static inline int pte_file(pte_t pte)
++{ 
++	return (pte).pte_low & _PAGE_FILE; 
++}
++
+ static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_DIRTY; }
+ static inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
+ static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
+@@ -355,14 +379,26 @@ static inline pte_t pte_modify(pte_t pte
+ #define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
+ 		       ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
+ 
+-/* to find an entry in a page-table-directory. */
++/*
++ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
++ *
++ * this macro returns the index of the entry in the pgd page which would
++ * control the given virtual address
++ */
+ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ 
+-/* to find an entry in a page-table-directory */
++/*
++ * pgd_offset() returns a (pgd_t *)
++ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
++ */
+ #define pgd_offset(mm, address) \
+ ((mm)->pgd + ((address) >> PGDIR_SHIFT))
+ 
+-/* to find an entry in a kernel page-table-directory */
++
++/*
++ * a shortcut which implies the use of the kernel's pgd, instead
++ * of a process's
++ */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
+ 
+ #define pmd_index(address) \
+@@ -374,7 +410,12 @@ static inline pmd_t * pmd_offset(pgd_t *
+ 	return (pmd_t *) dir;
+ }
+ 
+-/* Find an entry in the third-level page table.. */ 
++/*
++ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
++ *
++ * this macro returns the index of the entry in the pte page which would
++ * control the given virtual address
++ */
+ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ #define pte_offset_kernel(dir, address) \
+ 	((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
+@@ -400,11 +441,11 @@ typedef pte_t *pte_addr_t;
+ #define update_mmu_cache(vma,address,pte) do ; while (0)
+ 
+ /* Encode and de-code a swap entry */
+-#define __swp_type(x)			(((x).val >> 3) & 0x7f)
+-#define __swp_offset(x)			((x).val >> 10)
++#define __swp_type(x)			(((x).val >> 4) & 0x3f)
++#define __swp_offset(x)			((x).val >> 11)
+ 
+ #define __swp_entry(type, offset) \
+-	((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
++	((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
+ #define __pte_to_swp_entry(pte) \
+ 	((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+ #define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+--- linux-2.6.0-test6/include/asm-um/processor-generic.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/include/asm-um/processor-generic.h	2003-10-05 00:34:32.000000000 -0700
+@@ -11,9 +11,7 @@ struct pt_regs;
+ struct task_struct;
+ 
+ #include "linux/config.h"
+-#include "linux/signal.h"
+ #include "asm/ptrace.h"
+-#include "asm/siginfo.h"
+ #include "choose-mode.h"
+ 
+ struct mm_struct;
+@@ -101,14 +99,19 @@ typedef struct {
+ } mm_segment_t;
+ 
+ extern struct task_struct *alloc_task_struct(void);
+-extern void free_task_struct(struct task_struct *task);
+ 
+ extern void release_thread(struct task_struct *);
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+ extern void dump_thread(struct pt_regs *regs, struct user *u);
++extern void prepare_to_copy(struct task_struct *tsk);
+ 
+ extern unsigned long thread_saved_pc(struct task_struct *t);
+ 
++static inline void mm_copy_segments(struct mm_struct *from_mm, 
++				    struct mm_struct *new_mm)
++{
++}
++
+ #define init_stack	(init_thread_union.stack)
+ 
+ /*
+--- linux-2.6.0-test6/include/asm-um/processor-i386.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/asm-um/processor-i386.h	2003-10-05 00:34:32.000000000 -0700
+@@ -6,8 +6,8 @@
+ #ifndef __UM_PROCESSOR_I386_H
+ #define __UM_PROCESSOR_I386_H
+ 
+-extern int cpu_has_xmm;
+-extern int cpu_has_cmov;
++extern int host_has_xmm;
++extern int host_has_cmov;
+ 
+ struct arch_thread {
+ 	unsigned long debugregs[8];
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/sections.h	2003-10-05 00:34:32.000000000 -0700
+@@ -0,0 +1,7 @@
++#ifndef _UM_SECTIONS_H
++#define _UM_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+--- linux-2.6.0-test6/include/asm-um/smp.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-um/smp.h	2003-10-05 00:34:32.000000000 -0700
+@@ -10,7 +10,7 @@
+ 
+ extern cpumask_t cpu_online_map;
+ 
+-#define smp_processor_id() (current->thread_info->cpu)
++#define smp_processor_id() (current_thread->cpu)
+ #define cpu_logical_map(n) (n)
+ #define cpu_number_map(n) (n)
+ #define PROC_CHANGE_PENALTY	15 /* Pick a number, any number */
+--- linux-2.6.0-test6/include/asm-um/system-generic.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-um/system-generic.h	2003-10-05 00:34:32.000000000 -0700
+@@ -23,8 +23,10 @@ extern int get_signals(void);
+ extern void block_signals(void);
+ extern void unblock_signals(void);
+ 
+-#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
+-#define local_irq_restore(flags) do { set_signals(flags); } while(0)
++#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
++				     (flags) = get_signals(); } while(0)
++#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
++				      set_signals(flags); } while(0)
+ 
+ #define local_irq_save(flags) do { local_save_flags(flags); \
+                                    local_irq_disable(); } while(0)
+@@ -39,4 +41,7 @@ extern void unblock_signals(void);
+         (flags == 0);                   \
+ })
+ 
++extern void *_switch_to(void *prev, void *next, void *last);
++#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
++
+ #endif
+--- linux-2.6.0-test6/include/asm-um/thread_info.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/include/asm-um/thread_info.h	2003-10-05 00:34:32.000000000 -0700
+@@ -9,6 +9,7 @@
+ #ifndef __ASSEMBLY__
+ 
+ #include <asm/processor.h>
++#include <asm/types.h>
+ 
+ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
+@@ -43,15 +44,18 @@ struct thread_info {
+ static inline struct thread_info *current_thread_info(void)
+ {
+ 	struct thread_info *ti;
+-	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
++	unsigned long mask = PAGE_SIZE * 
++		(1 << CONFIG_KERNEL_STACK_ORDER) - 1;
++	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
+ 	return ti;
+ }
+ 
+ /* thread information allocation */
+-#define THREAD_SIZE (4*PAGE_SIZE)
+-#define alloc_thread_info(tsk) ((struct thread_info *) \
+-	__get_free_pages(GFP_KERNEL,2))
+-#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
++#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
++#define alloc_thread_info(tsk) \
++	((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
++#define free_thread_info(ti) kfree(ti)
++	
+ #define get_thread_info(ti) get_task_struct((ti)->task)
+ #define put_thread_info(ti) put_task_struct((ti)->task)
+ 
+@@ -65,11 +69,13 @@ static inline struct thread_info *curren
+ #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
+ 					 * TIF_NEED_RESCHED 
+ 					 */
++#define TIF_RESTART_BLOCK 	4
+ 
+ #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+ #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+ #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
++#define _TIF_RESTART_BLOCK	(1 << TIF_RESTART_BLOCK)
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/include/asm-um/timex.h	2003-06-14 12:18:24.000000000 -0700
++++ 25/include/asm-um/timex.h	2003-10-05 00:34:32.000000000 -0700
+@@ -1,8 +1,6 @@
+ #ifndef __UM_TIMEX_H
+ #define __UM_TIMEX_H
+ 
+-#include "linux/time.h"
+-
+ typedef unsigned long cycles_t;
+ 
+ #define cacheflush_time (0)
+--- linux-2.6.0-test6/include/asm-v850/cacheflush.h	2003-07-27 12:14:40.000000000 -0700
++++ 25/include/asm-v850/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -27,6 +27,8 @@
+ #define flush_cache_range(vma, start, end)	((void)0)
+ #define flush_cache_page(vma, vmaddr)		((void)0)
+ #define flush_dcache_page(page)			((void)0)
++#define flush_cache_vmap(start, end)		((void)0)
++#define flush_cache_vunmap(start, end)		((void)0)
+ 
+ #ifdef CONFIG_NO_CACHE
+ 
+@@ -55,5 +57,11 @@ extern void flush_cache_sigtramp (unsign
+ 
+ #endif /* CONFIG_NO_CACHE */
+ 
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++do { memcpy(dst, src, len); \
++     flush_icache_user_range(vma, page, vaddr, len); \
++} while (0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ #endif /* __V850_CACHEFLUSH_H__ */
+--- linux-2.6.0-test6/include/asm-x86_64/cacheflush.h	2003-06-14 12:17:59.000000000 -0700
++++ 25/include/asm-x86_64/cacheflush.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,6 +13,13 @@
+ #define flush_icache_range(start, end)		do { } while (0)
+ #define flush_icache_page(vma,pg)		do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
++#define flush_cache_vmap(start, end)		do { } while (0)
++#define flush_cache_vunmap(start, end)		do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++	memcpy(dst, src, len)
+ 
+ void global_flush_tlb(void); 
+ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+--- linux-2.6.0-test6/include/asm-x86_64/elf.h	2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-x86_64/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -150,11 +150,6 @@ extern int dump_task_fpu (struct task_st
+ #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+ #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+ 
+-#ifdef CONFIG_SMP
+-extern void dump_smp_unlazy_fpu(void);
+-#define ELF_CORE_SYNC dump_smp_unlazy_fpu
+-#endif
+-
+ #endif
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-x86_64/mmzone.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-x86_64/mmzone.h	2003-10-05 00:34:38.000000000 -0700
+@@ -10,7 +10,6 @@
+ 
+ #define VIRTUAL_BUG_ON(x) 
+ 
+-#include <asm/numnodes.h>
+ #include <asm/smp.h>
+ 
+ #define MAXNODE 8 
+--- linux-2.6.0-test6/include/asm-x86_64/numnodes.h	2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-x86_64/numnodes.h	2003-10-05 00:34:38.000000000 -0700
+@@ -3,10 +3,7 @@
+ 
+ #include <linux/config.h>
+ 
+-#ifdef CONFIG_DISCONTIGMEM
+-#define MAX_NUMNODES 8	/* APIC limit currently */
+-#else
+-#define MAX_NUMNODES 1
+-#endif
++/* Max 8 Nodes - APIC limit currently */
++#define NODES_SHIFT	3
+ 
+ #endif
+--- linux-2.6.0-test6/include/asm-x86_64/pgtable.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/asm-x86_64/pgtable.h	2003-10-05 00:33:24.000000000 -0700
+@@ -126,7 +126,6 @@ static inline void set_pml4(pml4_t *dst,
+ #ifndef __ASSEMBLY__
+ #define VMALLOC_START    0xffffff0000000000
+ #define VMALLOC_END      0xffffff7fffffffff
+-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define MODULES_VADDR    0xffffffffa0000000
+ #define MODULES_END      0xffffffffafffffff
+ #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
+--- linux-2.6.0-test6/include/linux/acpi.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/acpi.h	2003-10-05 00:33:24.000000000 -0700
+@@ -424,17 +424,17 @@ int ec_write(u8 addr, u8 val);
+ 
+ #endif /*CONFIG_ACPI_EC*/
+ 
+-#ifdef CONFIG_ACPI
++#ifdef CONFIG_ACPI_INTERPRETER
+ 
+ int acpi_blacklisted(void);
+ 
+-#else
++#else /*!CONFIG_ACPI_INTERPRETER*/
+ 
+ static inline int acpi_blacklisted(void)
+ {
+ 	return 0;
+ }
+ 
+-#endif /*CONFIG_ACPI*/
++#endif /*!CONFIG_ACPI_INTERPRETER*/
+ 
+ #endif /*_LINUX_ACPI_H*/
+--- linux-2.6.0-test6/include/linux/aio.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/linux/aio.h	2003-10-05 00:37:05.000000000 -0700
+@@ -29,21 +29,26 @@ struct kioctx;
+ #define KIF_LOCKED		0
+ #define KIF_KICKED		1
+ #define KIF_CANCELLED		2
++#define KIF_SYNCED		3
+ 
+ #define kiocbTryLock(iocb)	test_and_set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbTryKick(iocb)	test_and_set_bit(KIF_KICKED, &(iocb)->ki_flags)
++#define kiocbTrySync(iocb)	test_and_set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ 
+ #define kiocbSetLocked(iocb)	set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbSetKicked(iocb)	set_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbSetCancelled(iocb)	set_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbSetSynced(iocb)	set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ 
+ #define kiocbClearLocked(iocb)	clear_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbClearKicked(iocb)	clear_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbClearCancelled(iocb)	clear_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbClearSynced(iocb)	clear_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ 
+ #define kiocbIsLocked(iocb)	test_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbIsKicked(iocb)	test_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbIsCancelled(iocb)	test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbIsSynced(iocb)	test_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ 
+ struct kiocb {
+ 	struct list_head	ki_run_list;
+@@ -54,7 +59,7 @@ struct kiocb {
+ 	struct file		*ki_filp;
+ 	struct kioctx		*ki_ctx;	/* may be NULL for sync ops */
+ 	int			(*ki_cancel)(struct kiocb *, struct io_event *);
+-	long			(*ki_retry)(struct kiocb *);
++	ssize_t			(*ki_retry)(struct kiocb *);
+ 
+ 	struct list_head	ki_list;	/* the aio core uses this
+ 						 * for cancellation */
+@@ -63,6 +68,16 @@ struct kiocb {
+ 	__u64			ki_user_data;	/* user's data for completion */
+ 	loff_t			ki_pos;
+ 
++	/* State that we remember to be able to restart/retry  */
++	unsigned short		ki_opcode;
++	size_t			ki_nbytes; 	/* copy of iocb->aio_nbytes */
++	char 			*ki_buf;	/* remaining iocb->aio_buf */
++	size_t			ki_left; 	/* remaining bytes */
++	wait_queue_t		ki_wait;
++	long			ki_retried; 	/* just for testing */
++	long			ki_kicked; 	/* just for testing */
++	long			ki_queued; 	/* just for testing */
++
+ 	char			private[KIOCB_PRIVATE_SIZE];
+ };
+ 
+@@ -77,6 +92,8 @@ struct kiocb {
+ 		(x)->ki_ctx = &tsk->active_mm->default_kioctx;	\
+ 		(x)->ki_cancel = NULL;			\
+ 		(x)->ki_user_obj = tsk;			\
++		(x)->ki_user_data = 0;			\
++		init_wait((&(x)->ki_wait));		\
+ 	} while (0)
+ 
+ #define AIO_RING_MAGIC			0xa10a10a1
+@@ -159,6 +176,17 @@ int FASTCALL(io_submit_one(struct kioctx
+ #define get_ioctx(kioctx)	do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
+ #define put_ioctx(kioctx)	do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
+ 
++#define in_aio() !is_sync_wait(current->io_wait)
++/* may be used for debugging */
++#define warn_if_async()	if (in_aio()) {\
++	printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
++	__FUNCTION__, __FILE__, __LINE__); \
++	dump_stack(); \
++	}
++
++#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
++#define is_retried_kiocb(iocb) ((iocb)->ki_retried > 1)
++
+ #include <linux/aio_abi.h>
+ 
+ static inline struct kiocb *list_kiocb(struct list_head *h)
+--- linux-2.6.0-test6/include/linux/blkdev.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/blkdev.h	2003-10-05 00:36:58.000000000 -0700
+@@ -585,6 +585,7 @@ extern void blk_queue_free_tags(request_
+ extern int blk_queue_resize_tags(request_queue_t *, int);
+ extern void blk_queue_invalidate_tags(request_queue_t *);
+ extern void blk_congestion_wait(int rw, long timeout);
++extern int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait);
+ 
+ extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
+ extern void blk_rq_prep_restart(struct request *);
+--- linux-2.6.0-test6/include/linux/buffer_head.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/buffer_head.h	2003-10-05 00:37:00.000000000 -0700
+@@ -162,6 +162,7 @@ void mark_buffer_async_write(struct buff
+ void invalidate_bdev(struct block_device *, int);
+ int sync_blockdev(struct block_device *bdev);
+ void __wait_on_buffer(struct buffer_head *);
++int __wait_on_buffer_wq(struct buffer_head *, wait_queue_t *wait);
+ wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
+ void wake_up_buffer(struct buffer_head *bh);
+ int fsync_bdev(struct block_device *);
+@@ -173,6 +174,8 @@ void __brelse(struct buffer_head *);
+ void __bforget(struct buffer_head *);
+ void __breadahead(struct block_device *, sector_t block, int size);
+ struct buffer_head *__bread(struct block_device *, sector_t block, int size);
++struct buffer_head *__bread_wq(struct block_device *, sector_t block,
++	int size, wait_queue_t *wait);
+ struct buffer_head *alloc_buffer_head(int gfp_flags);
+ void free_buffer_head(struct buffer_head * bh);
+ void FASTCALL(unlock_buffer(struct buffer_head *bh));
+@@ -207,12 +210,6 @@ int nobh_prepare_write(struct page*, uns
+ int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
+ int nobh_truncate_page(struct address_space *, loff_t);
+ 
+-#define OSYNC_METADATA	(1<<0)
+-#define OSYNC_DATA	(1<<1)
+-#define OSYNC_INODE	(1<<2)
+-int generic_osync_inode(struct inode *, int);
+-
+-
+ /*
+  * inline definitions
+  */
+@@ -230,13 +227,13 @@ static inline void put_bh(struct buffer_
+ 
+ static inline void brelse(struct buffer_head *bh)
+ {
+-	if (bh)
++	if (bh && !IS_ERR(bh))
+ 		__brelse(bh);
+ }
+ 
+ static inline void bforget(struct buffer_head *bh)
+ {
+-	if (bh)
++	if (bh && !IS_ERR(bh))
+ 		__bforget(bh);
+ }
+ 
+@@ -253,7 +250,12 @@ sb_breadahead(struct super_block *sb, se
+ }
+ 
+ static inline struct buffer_head *
+-sb_getblk(struct super_block *sb, sector_t block)
++sb_bread_wq(struct super_block *sb, sector_t block, wait_queue_t *wait)
++{
++	return __bread_wq(sb->s_bdev, block, sb->s_blocksize, wait);
++}
++
++static inline struct buffer_head *sb_getblk(struct super_block *sb, sector_t block)
+ {
+ 	return __getblk(sb->s_bdev, block, sb->s_blocksize);
+ }
+@@ -277,16 +279,34 @@ map_bh(struct buffer_head *bh, struct su
+  * __wait_on_buffer() just to trip a debug check.  Because debug code in inline
+  * functions is bloaty.
+  */
+-static inline void wait_on_buffer(struct buffer_head *bh)
++
++static inline int wait_on_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
+ {
+ 	if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0)
+-		__wait_on_buffer(bh);
++		return __wait_on_buffer_wq(bh, wait);
++
++	return 0;
++}
++
++static inline void wait_on_buffer(struct buffer_head *bh)
++{
++	wait_on_buffer_wq(bh, NULL);
++}
++
++static inline int lock_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
++{
++	while (test_set_buffer_locked(bh)) {
++		int ret = __wait_on_buffer_wq(bh, wait);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
+ }
+ 
+ static inline void lock_buffer(struct buffer_head *bh)
+ {
+-	while (test_set_buffer_locked(bh))
+-		__wait_on_buffer(bh);
++	lock_buffer_wq(bh, NULL);
+ }
+ 
+ #endif /* _LINUX_BUFFER_HEAD_H */
+--- linux-2.6.0-test6/include/linux/cdrom.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/linux/cdrom.h	2003-10-05 00:33:59.000000000 -0700
+@@ -743,6 +743,7 @@ struct cdrom_device_info {
+ /* per-device flags */
+         __u8 sanyo_slot		: 2;	/* Sanyo 3 CD changer support */
+         __u8 reserved		: 6;	/* not used yet */
++	int for_data;
+ 	struct cdrom_write_settings write;
+ };
+ 
+@@ -776,9 +777,9 @@ struct cdrom_device_ops {
+ };
+ 
+ /* the general block_device operations structure: */
+-extern int cdrom_open(struct cdrom_device_info *, struct inode *, struct file *);
+-extern int cdrom_release(struct cdrom_device_info *, struct file *);
+-extern int cdrom_ioctl(struct cdrom_device_info *, struct inode *, unsigned, unsigned long);
++extern int cdrom_open(struct cdrom_device_info *, struct block_device *, struct file *);
++extern int cdrom_release(struct cdrom_device_info *);
++extern int cdrom_ioctl(struct cdrom_device_info *, struct block_device *, unsigned, unsigned long);
+ extern int cdrom_media_changed(struct cdrom_device_info *);
+ 
+ extern int register_cdrom(struct cdrom_device_info *cdi);
+--- linux-2.6.0-test6/include/linux/compat.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/compat.h	2003-10-05 00:34:44.000000000 -0700
+@@ -90,5 +90,12 @@ struct compat_statfs64 {
+ 	__u32 f_spare[5];
+ };
+ 
++struct compat_dirent {
++	u32		d_ino;
++	compat_off_t	d_off;
++	u16		d_reclen;
++	char		d_name[256];
++};
++
+ #endif /* CONFIG_COMPAT */
+ #endif /* _LINUX_COMPAT_H */
+--- linux-2.6.0-test6/include/linux/compat_ioctl.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/compat_ioctl.h	2003-10-05 00:33:24.000000000 -0700
+@@ -68,7 +68,7 @@ COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
+ COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+ COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
+ COMPATIBLE_IOCTL(HDIO_SET_NICE)
+-#ifndef CONFIG_ARCH_S390
++#ifdef CONFIG_BLK_DEV_FD
+ /* 0x02 -- Floppy ioctls */
+ COMPATIBLE_IOCTL(FDMSGON)
+ COMPATIBLE_IOCTL(FDMSGOFF)
+--- linux-2.6.0-test6/include/linux/compiler-gcc.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/compiler-gcc.h	2003-10-05 00:34:18.000000000 -0700
+@@ -13,5 +13,5 @@
+    shouldn't recognize the original var, and make assumptions about it */
+ #define RELOC_HIDE(ptr, off)					\
+   ({ unsigned long __ptr;					\
+-    __asm__ ("" : "=g"(__ptr) : "0"(ptr));		\
++	__asm__ ("" : "=r"(__ptr) : "0"(ptr));			\
+     (typeof(ptr)) (__ptr + (off)); })
+--- linux-2.6.0-test6/include/linux/config.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/linux/config.h	2003-10-05 00:33:43.000000000 -0700
+@@ -2,5 +2,8 @@
+ #define _LINUX_CONFIG_H
+ 
+ #include <linux/autoconf.h>
++#if defined(__i386__) && !defined(IN_BOOTLOADER)
++#include <asm/kgdb.h>
++#endif
+ 
+ #endif
+--- linux-2.6.0-test6/include/linux/dqblk_xfs.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/linux/dqblk_xfs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -105,15 +105,6 @@ typedef struct fs_disk_quota {
+ #define FS_DQ_TIMER_MASK	(FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
+ 
+ /*
+- * The following constants define the default amount of time given a user
+- * before the soft limits are treated as hard limits (usually resulting
+- * in an allocation failure).  These may be modified by the quotactl(2)
+- * system call with the Q_XSETQLIM command.
+- */
+-#define	DQ_FTIMELIMIT	(7 * 24*60*60)		/* 1 week */
+-#define	DQ_BTIMELIMIT	(7 * 24*60*60)		/* 1 week */
+-
+-/*
+  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
+  */
+ #define XFS_QUOTA_UDQ_ACCT	(1<<0)  /* user quota accounting */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/dwarf2.h	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,738 @@
++/* Declarations and definitions of codes relating to the DWARF2 symbolic
++   debugging information format.
++   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002
++   Free Software Foundation, Inc.
++
++   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
++   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
++   provided support for this effort -- June 21, 1995.
++
++   Derived from the DWARF 1 implementation written by Ron Guilmette
++   (rfg@netcom.com), November 1990.
++
++   This file is part of GCC.
++
++   GCC 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, or (at your option) any later
++   version.
++
++   GCC 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 GCC; see the file COPYING.  If not, write to the Free
++   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
++   02111-1307, USA.  */
++
++/* This file is derived from the DWARF specification (a public document)
++   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
++   Programming Languages Special Interest Group (UI/PLSIG) and distributed
++   by UNIX International.  Copies of this specification are available from
++   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
++
++   This file also now contains definitions from the DWARF 3 specification.  */
++
++/* This file is shared between GCC and GDB, and should not contain
++   prototypes.	*/
++
++#ifndef _ELF_DWARF2_H
++#define _ELF_DWARF2_H
++
++/* Structure found in the .debug_line section.	*/
++#ifndef __ASSEMBLY__
++typedef struct
++{
++  unsigned char li_length	   [4];
++  unsigned char li_version	   [2];
++  unsigned char li_prologue_length [4];
++  unsigned char li_min_insn_length [1];
++  unsigned char li_default_is_stmt [1];
++  unsigned char li_line_base	   [1];
++  unsigned char li_line_range	   [1];
++  unsigned char li_opcode_base	   [1];
++}
++DWARF2_External_LineInfo;
++
++typedef struct
++{
++  unsigned long  li_length;
++  unsigned short li_version;
++  unsigned int	 li_prologue_length;
++  unsigned char  li_min_insn_length;
++  unsigned char  li_default_is_stmt;
++  int		 li_line_base;
++  unsigned char  li_line_range;
++  unsigned char  li_opcode_base;
++}
++DWARF2_Internal_LineInfo;
++
++/* Structure found in .debug_pubnames section.	*/
++typedef struct
++{
++  unsigned char pn_length  [4];
++  unsigned char pn_version [2];
++  unsigned char pn_offset  [4];
++  unsigned char pn_size    [4];
++}
++DWARF2_External_PubNames;
++
++typedef struct
++{
++  unsigned long  pn_length;
++  unsigned short pn_version;
++  unsigned long  pn_offset;
++  unsigned long  pn_size;
++}
++DWARF2_Internal_PubNames;
++
++/* Structure found in .debug_info section.  */
++typedef struct
++{
++  unsigned char  cu_length	  [4];
++  unsigned char  cu_version	  [2];
++  unsigned char  cu_abbrev_offset [4];
++  unsigned char  cu_pointer_size  [1];
++}
++DWARF2_External_CompUnit;
++
++typedef struct
++{
++  unsigned long  cu_length;
++  unsigned short cu_version;
++  unsigned long  cu_abbrev_offset;
++  unsigned char  cu_pointer_size;
++}
++DWARF2_Internal_CompUnit;
++
++typedef struct
++{
++  unsigned char  ar_length	 [4];
++  unsigned char  ar_version	 [2];
++  unsigned char  ar_info_offset  [4];
++  unsigned char  ar_pointer_size [1];
++  unsigned char  ar_segment_size [1];
++}
++DWARF2_External_ARange;
++
++typedef struct
++{
++  unsigned long  ar_length;
++  unsigned short ar_version;
++  unsigned long  ar_info_offset;
++  unsigned char  ar_pointer_size;
++  unsigned char  ar_segment_size;
++}
++DWARF2_Internal_ARange;
++
++#define ENUM(name) enum name {
++#define IF_NOT_ASM(a) a
++#define COMMA ,
++#else
++#define ENUM(name)
++#define IF_NOT_ASM(a)
++#define COMMA
++
++#endif
++
++/* Tag names and codes.  */
++ENUM(dwarf_tag)
++
++    DW_TAG_padding = 0x00 COMMA
++    DW_TAG_array_type = 0x01 COMMA
++    DW_TAG_class_type = 0x02 COMMA
++    DW_TAG_entry_point = 0x03 COMMA
++    DW_TAG_enumeration_type = 0x04 COMMA
++    DW_TAG_formal_parameter = 0x05 COMMA
++    DW_TAG_imported_declaration = 0x08 COMMA
++    DW_TAG_label = 0x0a COMMA
++    DW_TAG_lexical_block = 0x0b COMMA
++    DW_TAG_member = 0x0d COMMA
++    DW_TAG_pointer_type = 0x0f COMMA
++    DW_TAG_reference_type = 0x10 COMMA
++    DW_TAG_compile_unit = 0x11 COMMA
++    DW_TAG_string_type = 0x12 COMMA
++    DW_TAG_structure_type = 0x13 COMMA
++    DW_TAG_subroutine_type = 0x15 COMMA
++    DW_TAG_typedef = 0x16 COMMA
++    DW_TAG_union_type = 0x17 COMMA
++    DW_TAG_unspecified_parameters = 0x18 COMMA
++    DW_TAG_variant = 0x19 COMMA
++    DW_TAG_common_block = 0x1a COMMA
++    DW_TAG_common_inclusion = 0x1b COMMA
++    DW_TAG_inheritance = 0x1c COMMA
++    DW_TAG_inlined_subroutine = 0x1d COMMA
++    DW_TAG_module = 0x1e COMMA
++    DW_TAG_ptr_to_member_type = 0x1f COMMA
++    DW_TAG_set_type = 0x20 COMMA
++    DW_TAG_subrange_type = 0x21 COMMA
++    DW_TAG_with_stmt = 0x22 COMMA
++    DW_TAG_access_declaration = 0x23 COMMA
++    DW_TAG_base_type = 0x24 COMMA
++    DW_TAG_catch_block = 0x25 COMMA
++    DW_TAG_const_type = 0x26 COMMA
++    DW_TAG_constant = 0x27 COMMA
++    DW_TAG_enumerator = 0x28 COMMA
++    DW_TAG_file_type = 0x29 COMMA
++    DW_TAG_friend = 0x2a COMMA
++    DW_TAG_namelist = 0x2b COMMA
++    DW_TAG_namelist_item = 0x2c COMMA
++    DW_TAG_packed_type = 0x2d COMMA
++    DW_TAG_subprogram = 0x2e COMMA
++    DW_TAG_template_type_param = 0x2f COMMA
++    DW_TAG_template_value_param = 0x30 COMMA
++    DW_TAG_thrown_type = 0x31 COMMA
++    DW_TAG_try_block = 0x32 COMMA
++    DW_TAG_variant_part = 0x33 COMMA
++    DW_TAG_variable = 0x34 COMMA
++    DW_TAG_volatile_type = 0x35 COMMA
++    /* DWARF 3.  */
++    DW_TAG_dwarf_procedure = 0x36 COMMA
++    DW_TAG_restrict_type = 0x37 COMMA
++    DW_TAG_interface_type = 0x38 COMMA
++    DW_TAG_namespace = 0x39 COMMA
++    DW_TAG_imported_module = 0x3a COMMA
++    DW_TAG_unspecified_type = 0x3b COMMA
++    DW_TAG_partial_unit = 0x3c COMMA
++    DW_TAG_imported_unit = 0x3d COMMA
++    /* SGI/MIPS Extensions.  */
++    DW_TAG_MIPS_loop = 0x4081 COMMA
++    /* GNU extensions.	*/
++    DW_TAG_format_label = 0x4101 COMMA	/* For FORTRAN 77 and Fortran 90.  */
++    DW_TAG_function_template = 0x4102 COMMA	/* For C++.  */
++    DW_TAG_class_template = 0x4103 COMMA	/* For C++.  */
++    DW_TAG_GNU_BINCL = 0x4104 COMMA
++    DW_TAG_GNU_EINCL = 0x4105 COMMA
++    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
++    DW_TAG_upc_shared_type = 0x8765 COMMA
++    DW_TAG_upc_strict_type = 0x8766 COMMA
++    DW_TAG_upc_relaxed_type = 0x8767
++IF_NOT_ASM(};)
++
++#define DW_TAG_lo_user	0x4080
++#define DW_TAG_hi_user	0xffff
++
++/* Flag that tells whether entry has a child or not.  */
++#define DW_children_no	 0
++#define	DW_children_yes  1
++
++/* Form names and codes.  */
++ENUM(dwarf_form)
++
++    DW_FORM_addr = 0x01 COMMA
++    DW_FORM_block2 = 0x03 COMMA
++    DW_FORM_block4 = 0x04 COMMA
++    DW_FORM_data2 = 0x05 COMMA
++    DW_FORM_data4 = 0x06 COMMA
++    DW_FORM_data8 = 0x07 COMMA
++    DW_FORM_string = 0x08 COMMA
++    DW_FORM_block = 0x09 COMMA
++    DW_FORM_block1 = 0x0a COMMA
++    DW_FORM_data1 = 0x0b COMMA
++    DW_FORM_flag = 0x0c COMMA
++    DW_FORM_sdata = 0x0d COMMA
++    DW_FORM_strp = 0x0e COMMA
++    DW_FORM_udata = 0x0f COMMA
++    DW_FORM_ref_addr = 0x10 COMMA
++    DW_FORM_ref1 = 0x11 COMMA
++    DW_FORM_ref2 = 0x12 COMMA
++    DW_FORM_ref4 = 0x13 COMMA
++    DW_FORM_ref8 = 0x14 COMMA
++    DW_FORM_ref_udata = 0x15 COMMA
++    DW_FORM_indirect = 0x16
++IF_NOT_ASM(};)
++
++/* Attribute names and codes.  */
++
++ENUM(dwarf_attribute)
++
++    DW_AT_sibling = 0x01 COMMA
++    DW_AT_location = 0x02 COMMA
++    DW_AT_name = 0x03 COMMA
++    DW_AT_ordering = 0x09 COMMA
++    DW_AT_subscr_data = 0x0a COMMA
++    DW_AT_byte_size = 0x0b COMMA
++    DW_AT_bit_offset = 0x0c COMMA
++    DW_AT_bit_size = 0x0d COMMA
++    DW_AT_element_list = 0x0f COMMA
++    DW_AT_stmt_list = 0x10 COMMA
++    DW_AT_low_pc = 0x11 COMMA
++    DW_AT_high_pc = 0x12 COMMA
++    DW_AT_language = 0x13 COMMA
++    DW_AT_member = 0x14 COMMA
++    DW_AT_discr = 0x15 COMMA
++    DW_AT_discr_value = 0x16 COMMA
++    DW_AT_visibility = 0x17 COMMA
++    DW_AT_import = 0x18 COMMA
++    DW_AT_string_length = 0x19 COMMA
++    DW_AT_common_reference = 0x1a COMMA
++    DW_AT_comp_dir = 0x1b COMMA
++    DW_AT_const_value = 0x1c COMMA
++    DW_AT_containing_type = 0x1d COMMA
++    DW_AT_default_value = 0x1e COMMA
++    DW_AT_inline = 0x20 COMMA
++    DW_AT_is_optional = 0x21 COMMA
++    DW_AT_lower_bound = 0x22 COMMA
++    DW_AT_producer = 0x25 COMMA
++    DW_AT_prototyped = 0x27 COMMA
++    DW_AT_return_addr = 0x2a COMMA
++    DW_AT_start_scope = 0x2c COMMA
++    DW_AT_stride_size = 0x2e COMMA
++    DW_AT_upper_bound = 0x2f COMMA
++    DW_AT_abstract_origin = 0x31 COMMA
++    DW_AT_accessibility = 0x32 COMMA
++    DW_AT_address_class = 0x33 COMMA
++    DW_AT_artificial = 0x34 COMMA
++    DW_AT_base_types = 0x35 COMMA
++    DW_AT_calling_convention = 0x36 COMMA
++    DW_AT_count = 0x37 COMMA
++    DW_AT_data_member_location = 0x38 COMMA
++    DW_AT_decl_column = 0x39 COMMA
++    DW_AT_decl_file = 0x3a COMMA
++    DW_AT_decl_line = 0x3b COMMA
++    DW_AT_declaration = 0x3c COMMA
++    DW_AT_discr_list = 0x3d COMMA
++    DW_AT_encoding = 0x3e COMMA
++    DW_AT_external = 0x3f COMMA
++    DW_AT_frame_base = 0x40 COMMA
++    DW_AT_friend = 0x41 COMMA
++    DW_AT_identifier_case = 0x42 COMMA
++    DW_AT_macro_info = 0x43 COMMA
++    DW_AT_namelist_items = 0x44 COMMA
++    DW_AT_priority = 0x45 COMMA
++    DW_AT_segment = 0x46 COMMA
++    DW_AT_specification = 0x47 COMMA
++    DW_AT_static_link = 0x48 COMMA
++    DW_AT_type = 0x49 COMMA
++    DW_AT_use_location = 0x4a COMMA
++    DW_AT_variable_parameter = 0x4b COMMA
++    DW_AT_virtuality = 0x4c COMMA
++    DW_AT_vtable_elem_location = 0x4d COMMA
++    /* DWARF 3 values.	*/
++    DW_AT_allocated	= 0x4e COMMA
++    DW_AT_associated	= 0x4f COMMA
++    DW_AT_data_location = 0x50 COMMA
++    DW_AT_stride	= 0x51 COMMA
++    DW_AT_entry_pc	= 0x52 COMMA
++    DW_AT_use_UTF8	= 0x53 COMMA
++    DW_AT_extension	= 0x54 COMMA
++    DW_AT_ranges	= 0x55 COMMA
++    DW_AT_trampoline	= 0x56 COMMA
++    DW_AT_call_column	= 0x57 COMMA
++    DW_AT_call_file	= 0x58 COMMA
++    DW_AT_call_line	= 0x59 COMMA
++    /* SGI/MIPS extensions.  */
++    DW_AT_MIPS_fde = 0x2001 COMMA
++    DW_AT_MIPS_loop_begin = 0x2002 COMMA
++    DW_AT_MIPS_tail_loop_begin = 0x2003 COMMA
++    DW_AT_MIPS_epilog_begin = 0x2004 COMMA
++    DW_AT_MIPS_loop_unroll_factor = 0x2005 COMMA
++    DW_AT_MIPS_software_pipeline_depth = 0x2006 COMMA
++    DW_AT_MIPS_linkage_name = 0x2007 COMMA
++    DW_AT_MIPS_stride = 0x2008 COMMA
++    DW_AT_MIPS_abstract_name = 0x2009 COMMA
++    DW_AT_MIPS_clone_origin = 0x200a COMMA
++    DW_AT_MIPS_has_inlines = 0x200b COMMA
++    /* GNU extensions.	*/
++    DW_AT_sf_names   = 0x2101 COMMA
++    DW_AT_src_info   = 0x2102 COMMA
++    DW_AT_mac_info   = 0x2103 COMMA
++    DW_AT_src_coords = 0x2104 COMMA
++    DW_AT_body_begin = 0x2105 COMMA
++    DW_AT_body_end   = 0x2106 COMMA
++    DW_AT_GNU_vector = 0x2107 COMMA
++    /* VMS extensions.	*/
++    DW_AT_VMS_rtnbeg_pd_address = 0x2201 COMMA
++    /* UPC extension.  */
++    DW_AT_upc_threads_scaled = 0x3210
++IF_NOT_ASM(};)
++
++#define DW_AT_lo_user	0x2000	/* Implementation-defined range start.	*/
++#define DW_AT_hi_user	0x3ff0	/* Implementation-defined range end.  */
++
++/* Location atom names and codes.  */
++ENUM(dwarf_location_atom)
++
++    DW_OP_addr = 0x03 COMMA
++    DW_OP_deref = 0x06 COMMA
++    DW_OP_const1u = 0x08 COMMA
++    DW_OP_const1s = 0x09 COMMA
++    DW_OP_const2u = 0x0a COMMA
++    DW_OP_const2s = 0x0b COMMA
++    DW_OP_const4u = 0x0c COMMA
++    DW_OP_const4s = 0x0d COMMA
++    DW_OP_const8u = 0x0e COMMA
++    DW_OP_const8s = 0x0f COMMA
++    DW_OP_constu = 0x10 COMMA
++    DW_OP_consts = 0x11 COMMA
++    DW_OP_dup = 0x12 COMMA
++    DW_OP_drop = 0x13 COMMA
++    DW_OP_over = 0x14 COMMA
++    DW_OP_pick = 0x15 COMMA
++    DW_OP_swap = 0x16 COMMA
++    DW_OP_rot = 0x17 COMMA
++    DW_OP_xderef = 0x18 COMMA
++    DW_OP_abs = 0x19 COMMA
++    DW_OP_and = 0x1a COMMA
++    DW_OP_div = 0x1b COMMA
++    DW_OP_minus = 0x1c COMMA
++    DW_OP_mod = 0x1d COMMA
++    DW_OP_mul = 0x1e COMMA
++    DW_OP_neg = 0x1f COMMA
++    DW_OP_not = 0x20 COMMA
++    DW_OP_or = 0x21 COMMA
++    DW_OP_plus = 0x22 COMMA
++    DW_OP_plus_uconst = 0x23 COMMA
++    DW_OP_shl = 0x24 COMMA
++    DW_OP_shr = 0x25 COMMA
++    DW_OP_shra = 0x26 COMMA
++    DW_OP_xor = 0x27 COMMA
++    DW_OP_bra = 0x28 COMMA
++    DW_OP_eq = 0x29 COMMA
++    DW_OP_ge = 0x2a COMMA
++    DW_OP_gt = 0x2b COMMA
++    DW_OP_le = 0x2c COMMA
++    DW_OP_lt = 0x2d COMMA
++    DW_OP_ne = 0x2e COMMA
++    DW_OP_skip = 0x2f COMMA
++    DW_OP_lit0 = 0x30 COMMA
++    DW_OP_lit1 = 0x31 COMMA
++    DW_OP_lit2 = 0x32 COMMA
++    DW_OP_lit3 = 0x33 COMMA
++    DW_OP_lit4 = 0x34 COMMA
++    DW_OP_lit5 = 0x35 COMMA
++    DW_OP_lit6 = 0x36 COMMA
++    DW_OP_lit7 = 0x37 COMMA
++    DW_OP_lit8 = 0x38 COMMA
++    DW_OP_lit9 = 0x39 COMMA
++    DW_OP_lit10 = 0x3a COMMA
++    DW_OP_lit11 = 0x3b COMMA
++    DW_OP_lit12 = 0x3c COMMA
++    DW_OP_lit13 = 0x3d COMMA
++    DW_OP_lit14 = 0x3e COMMA
++    DW_OP_lit15 = 0x3f COMMA
++    DW_OP_lit16 = 0x40 COMMA
++    DW_OP_lit17 = 0x41 COMMA
++    DW_OP_lit18 = 0x42 COMMA
++    DW_OP_lit19 = 0x43 COMMA
++    DW_OP_lit20 = 0x44 COMMA
++    DW_OP_lit21 = 0x45 COMMA
++    DW_OP_lit22 = 0x46 COMMA
++    DW_OP_lit23 = 0x47 COMMA
++    DW_OP_lit24 = 0x48 COMMA
++    DW_OP_lit25 = 0x49 COMMA
++    DW_OP_lit26 = 0x4a COMMA
++    DW_OP_lit27 = 0x4b COMMA
++    DW_OP_lit28 = 0x4c COMMA
++    DW_OP_lit29 = 0x4d COMMA
++    DW_OP_lit30 = 0x4e COMMA
++    DW_OP_lit31 = 0x4f COMMA
++    DW_OP_reg0 = 0x50 COMMA
++    DW_OP_reg1 = 0x51 COMMA
++    DW_OP_reg2 = 0x52 COMMA
++    DW_OP_reg3 = 0x53 COMMA
++    DW_OP_reg4 = 0x54 COMMA
++    DW_OP_reg5 = 0x55 COMMA
++    DW_OP_reg6 = 0x56 COMMA
++    DW_OP_reg7 = 0x57 COMMA
++    DW_OP_reg8 = 0x58 COMMA
++    DW_OP_reg9 = 0x59 COMMA
++    DW_OP_reg10 = 0x5a COMMA
++    DW_OP_reg11 = 0x5b COMMA
++    DW_OP_reg12 = 0x5c COMMA
++    DW_OP_reg13 = 0x5d COMMA
++    DW_OP_reg14 = 0x5e COMMA
++    DW_OP_reg15 = 0x5f COMMA
++    DW_OP_reg16 = 0x60 COMMA
++    DW_OP_reg17 = 0x61 COMMA
++    DW_OP_reg18 = 0x62 COMMA
++    DW_OP_reg19 = 0x63 COMMA
++    DW_OP_reg20 = 0x64 COMMA
++    DW_OP_reg21 = 0x65 COMMA
++    DW_OP_reg22 = 0x66 COMMA
++    DW_OP_reg23 = 0x67 COMMA
++    DW_OP_reg24 = 0x68 COMMA
++    DW_OP_reg25 = 0x69 COMMA
++    DW_OP_reg26 = 0x6a COMMA
++    DW_OP_reg27 = 0x6b COMMA
++    DW_OP_reg28 = 0x6c COMMA
++    DW_OP_reg29 = 0x6d COMMA
++    DW_OP_reg30 = 0x6e COMMA
++    DW_OP_reg31 = 0x6f COMMA
++    DW_OP_breg0 = 0x70 COMMA
++    DW_OP_breg1 = 0x71 COMMA
++    DW_OP_breg2 = 0x72 COMMA
++    DW_OP_breg3 = 0x73 COMMA
++    DW_OP_breg4 = 0x74 COMMA
++    DW_OP_breg5 = 0x75 COMMA
++    DW_OP_breg6 = 0x76 COMMA
++    DW_OP_breg7 = 0x77 COMMA
++    DW_OP_breg8 = 0x78 COMMA
++    DW_OP_breg9 = 0x79 COMMA
++    DW_OP_breg10 = 0x7a COMMA
++    DW_OP_breg11 = 0x7b COMMA
++    DW_OP_breg12 = 0x7c COMMA
++    DW_OP_breg13 = 0x7d COMMA
++    DW_OP_breg14 = 0x7e COMMA
++    DW_OP_breg15 = 0x7f COMMA
++    DW_OP_breg16 = 0x80 COMMA
++    DW_OP_breg17 = 0x81 COMMA
++    DW_OP_breg18 = 0x82 COMMA
++    DW_OP_breg19 = 0x83 COMMA
++    DW_OP_breg20 = 0x84 COMMA
++    DW_OP_breg21 = 0x85 COMMA
++    DW_OP_breg22 = 0x86 COMMA
++    DW_OP_breg23 = 0x87 COMMA
++    DW_OP_breg24 = 0x88 COMMA
++    DW_OP_breg25 = 0x89 COMMA
++    DW_OP_breg26 = 0x8a COMMA
++    DW_OP_breg27 = 0x8b COMMA
++    DW_OP_breg28 = 0x8c COMMA
++    DW_OP_breg29 = 0x8d COMMA
++    DW_OP_breg30 = 0x8e COMMA
++    DW_OP_breg31 = 0x8f COMMA
++    DW_OP_regx = 0x90 COMMA
++    DW_OP_fbreg = 0x91 COMMA
++    DW_OP_bregx = 0x92 COMMA
++    DW_OP_piece = 0x93 COMMA
++    DW_OP_deref_size = 0x94 COMMA
++    DW_OP_xderef_size = 0x95 COMMA
++    DW_OP_nop = 0x96 COMMA
++    /* DWARF 3 extensions.  */
++    DW_OP_push_object_address = 0x97 COMMA
++    DW_OP_call2 = 0x98 COMMA
++    DW_OP_call4 = 0x99 COMMA
++    DW_OP_call_ref = 0x9a COMMA
++    /* GNU extensions.	*/
++    DW_OP_GNU_push_tls_address = 0xe0
++IF_NOT_ASM(};)
++
++#define DW_OP_lo_user	0xe0	/* Implementation-defined range start.	*/
++#define DW_OP_hi_user	0xff	/* Implementation-defined range end.  */
++
++/* Type encodings.  */
++ENUM(dwarf_type)
++
++    DW_ATE_void = 0x0 COMMA
++    DW_ATE_address = 0x1 COMMA
++    DW_ATE_boolean = 0x2 COMMA
++    DW_ATE_complex_float = 0x3 COMMA
++    DW_ATE_float = 0x4 COMMA
++    DW_ATE_signed = 0x5 COMMA
++    DW_ATE_signed_char = 0x6 COMMA
++    DW_ATE_unsigned = 0x7 COMMA
++    DW_ATE_unsigned_char = 0x8 COMMA
++    /* DWARF 3.  */
++    DW_ATE_imaginary_float = 0x9
++IF_NOT_ASM(};)
++
++#define	DW_ATE_lo_user 0x80
++#define	DW_ATE_hi_user 0xff
++
++/* Array ordering names and codes.  */
++ENUM(dwarf_array_dim_ordering)
++
++    DW_ORD_row_major = 0 COMMA
++    DW_ORD_col_major = 1
++IF_NOT_ASM(};)
++
++/* Access attribute.  */
++ENUM(dwarf_access_attribute)
++
++    DW_ACCESS_public = 1 COMMA
++    DW_ACCESS_protected = 2 COMMA
++    DW_ACCESS_private = 3
++IF_NOT_ASM(};)
++
++/* Visibility.	*/
++ENUM(dwarf_visibility_attribute)
++
++    DW_VIS_local = 1 COMMA
++    DW_VIS_exported = 2 COMMA
++    DW_VIS_qualified = 3
++IF_NOT_ASM(};)
++
++/* Virtuality.	*/
++ENUM(dwarf_virtuality_attribute)
++
++    DW_VIRTUALITY_none = 0 COMMA
++    DW_VIRTUALITY_virtual = 1 COMMA
++    DW_VIRTUALITY_pure_virtual = 2
++IF_NOT_ASM(};)
++
++/* Case sensitivity.  */
++ENUM(dwarf_id_case)
++
++    DW_ID_case_sensitive = 0 COMMA
++    DW_ID_up_case = 1 COMMA
++    DW_ID_down_case = 2 COMMA
++    DW_ID_case_insensitive = 3
++IF_NOT_ASM(};)
++
++/* Calling convention.	*/
++ENUM(dwarf_calling_convention)
++
++    DW_CC_normal = 0x1 COMMA
++    DW_CC_program = 0x2 COMMA
++    DW_CC_nocall = 0x3
++IF_NOT_ASM(};)
++
++#define DW_CC_lo_user 0x40
++#define DW_CC_hi_user 0xff
++
++/* Inline attribute.  */
++ENUM(dwarf_inline_attribute)
++
++    DW_INL_not_inlined = 0 COMMA
++    DW_INL_inlined = 1 COMMA
++    DW_INL_declared_not_inlined = 2 COMMA
++    DW_INL_declared_inlined = 3
++IF_NOT_ASM(};)
++
++/* Discriminant lists.	*/
++ENUM(dwarf_discrim_list)
++
++    DW_DSC_label = 0 COMMA
++    DW_DSC_range = 1
++IF_NOT_ASM(};)
++
++/* Line number opcodes.  */
++ENUM(dwarf_line_number_ops)
++
++    DW_LNS_extended_op = 0 COMMA
++    DW_LNS_copy = 1 COMMA
++    DW_LNS_advance_pc = 2 COMMA
++    DW_LNS_advance_line = 3 COMMA
++    DW_LNS_set_file = 4 COMMA
++    DW_LNS_set_column = 5 COMMA
++    DW_LNS_negate_stmt = 6 COMMA
++    DW_LNS_set_basic_block = 7 COMMA
++    DW_LNS_const_add_pc = 8 COMMA
++    DW_LNS_fixed_advance_pc = 9 COMMA
++    /* DWARF 3.  */
++    DW_LNS_set_prologue_end = 10 COMMA
++    DW_LNS_set_epilogue_begin = 11 COMMA
++    DW_LNS_set_isa = 12
++IF_NOT_ASM(};)
++
++/* Line number extended opcodes.  */
++ENUM(dwarf_line_number_x_ops)
++
++    DW_LNE_end_sequence = 1 COMMA
++    DW_LNE_set_address = 2 COMMA
++    DW_LNE_define_file = 3
++IF_NOT_ASM(};)
++
++/* Call frame information.  */
++ENUM(dwarf_call_frame_info)
++
++    DW_CFA_advance_loc = 0x40 COMMA
++    DW_CFA_offset = 0x80 COMMA
++    DW_CFA_restore = 0xc0 COMMA
++    DW_CFA_nop = 0x00 COMMA
++    DW_CFA_set_loc = 0x01 COMMA
++    DW_CFA_advance_loc1 = 0x02 COMMA
++    DW_CFA_advance_loc2 = 0x03 COMMA
++    DW_CFA_advance_loc4 = 0x04 COMMA
++    DW_CFA_offset_extended = 0x05 COMMA
++    DW_CFA_restore_extended = 0x06 COMMA
++    DW_CFA_undefined = 0x07 COMMA
++    DW_CFA_same_value = 0x08 COMMA
++    DW_CFA_register = 0x09 COMMA
++    DW_CFA_remember_state = 0x0a COMMA
++    DW_CFA_restore_state = 0x0b COMMA
++    DW_CFA_def_cfa = 0x0c COMMA
++    DW_CFA_def_cfa_register = 0x0d COMMA
++    DW_CFA_def_cfa_offset = 0x0e COMMA
++
++    /* DWARF 3.  */
++    DW_CFA_def_cfa_expression = 0x0f COMMA
++    DW_CFA_expression = 0x10 COMMA
++    DW_CFA_offset_extended_sf = 0x11 COMMA
++    DW_CFA_def_cfa_sf = 0x12 COMMA
++    DW_CFA_def_cfa_offset_sf = 0x13 COMMA
++
++    /* SGI/MIPS specific.  */
++    DW_CFA_MIPS_advance_loc8 = 0x1d COMMA
++
++    /* GNU extensions.	*/
++    DW_CFA_GNU_window_save = 0x2d COMMA
++    DW_CFA_GNU_args_size = 0x2e COMMA
++    DW_CFA_GNU_negative_offset_extended = 0x2f
++IF_NOT_ASM(};)
++
++#define DW_CIE_ID	  0xffffffff
++#define DW_CIE_VERSION	  1
++
++#define DW_CFA_extended   0
++#define DW_CFA_lo_user	  0x1c
++#define DW_CFA_hi_user	  0x3f
++
++#define DW_CHILDREN_no		     0x00
++#define DW_CHILDREN_yes		     0x01
++
++#define DW_ADDR_none		0
++
++/* Source language names and codes.  */
++ENUM(dwarf_source_language)
++
++    DW_LANG_C89 = 0x0001 COMMA
++    DW_LANG_C = 0x0002 COMMA
++    DW_LANG_Ada83 = 0x0003 COMMA
++    DW_LANG_C_plus_plus = 0x0004 COMMA
++    DW_LANG_Cobol74 = 0x0005 COMMA
++    DW_LANG_Cobol85 = 0x0006 COMMA
++    DW_LANG_Fortran77 = 0x0007 COMMA
++    DW_LANG_Fortran90 = 0x0008 COMMA
++    DW_LANG_Pascal83 = 0x0009 COMMA
++    DW_LANG_Modula2 = 0x000a COMMA
++    DW_LANG_Java = 0x000b COMMA
++    /* DWARF 3.  */
++    DW_LANG_C99 = 0x000c COMMA
++    DW_LANG_Ada95 = 0x000d COMMA
++    DW_LANG_Fortran95 = 0x000e COMMA
++    /* MIPS.  */
++    DW_LANG_Mips_Assembler = 0x8001 COMMA
++    /* UPC.  */
++    DW_LANG_Upc = 0x8765
++IF_NOT_ASM(};)
++
++#define DW_LANG_lo_user 0x8000	/* Implementation-defined range start.	*/
++#define DW_LANG_hi_user 0xffff	/* Implementation-defined range start.	*/
++
++/* Names and codes for macro information.  */
++ENUM(dwarf_macinfo_record_type)
++
++    DW_MACINFO_define = 1 COMMA
++    DW_MACINFO_undef = 2 COMMA
++    DW_MACINFO_start_file = 3 COMMA
++    DW_MACINFO_end_file = 4 COMMA
++    DW_MACINFO_vendor_ext = 255
++IF_NOT_ASM(};)
++
++/* @@@ For use with GNU frame unwind information.  */
++
++#define DW_EH_PE_absptr		0x00
++#define DW_EH_PE_omit		0xff
++
++#define DW_EH_PE_uleb128	0x01
++#define DW_EH_PE_udata2		0x02
++#define DW_EH_PE_udata4		0x03
++#define DW_EH_PE_udata8		0x04
++#define DW_EH_PE_sleb128	0x09
++#define DW_EH_PE_sdata2		0x0A
++#define DW_EH_PE_sdata4		0x0B
++#define DW_EH_PE_sdata8		0x0C
++#define DW_EH_PE_signed		0x08
++
++#define DW_EH_PE_pcrel		0x10
++#define DW_EH_PE_textrel	0x20
++#define DW_EH_PE_datarel	0x30
++#define DW_EH_PE_funcrel	0x40
++#define DW_EH_PE_aligned	0x50
++
++#define DW_EH_PE_indirect	0x80
++
++#endif /* _ELF_DWARF2_H */
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/dwarf2-lang.h	2003-10-05 00:33:38.000000000 -0700
+@@ -0,0 +1,132 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++#include <linux/dwarf2.h>
++
++/*
++ * This 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, or (at your option) any later
++ * version.
++ */
++/*
++ * This file defines macros that allow generation of DWARF debug records
++ * for asm files.  This file is platform independent.  Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++#define DWARF_preamble()	.section	.debug_frame,"",@progbits
++/*
++ * This macro starts a debug frame section.  The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc,	pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply.  If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets.  If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that.  This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number).  The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example).  So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset.  If <40> was the 40th
++ * 4-byte element in that structure you would want 4.  And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align)	\
++.section	.debug_frame,"",@progbits ;		\
++frame/**/_/**/ORD:						\
++	.long end/**/_/**/ORD-start/**/_/**/ORD;			\
++start/**/_/**/ORD:						\
++	.long	DW_CIE_ID;				\
++	.byte	DW_CIE_VERSION;			\
++	.byte 0	 ;				\
++	.uleb128 code_align;				\
++	.sleb128 data_align;				\
++	.byte pc;
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state.  This starts with defining the reference
++ * register and, usually the pc.  Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset)	\
++	.byte DW_CFA_def_cfa;			\
++	.uleb128 reg;				\
++	.uleb128 (offset);
++
++#define CFA_define_offset(reg, offset)		\
++	.byte (DW_CFA_offset + reg);		\
++	.uleb128 (offset);
++
++#define CFI_postamble(ORD)			\
++	.align 4;				\
++end/**/_/**/ORD:
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do.  This starts a running description of
++ * the call frame.  You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?).  Like the
++ * above, it has a preamble and a postamble.  It also is tied to the CFI
++ * above.
++ * The first entry after the preamble must be the location in the code
++ * that the call frame is being described for.
++ */
++#define FDE_preamble(ORD, fde_no, initial_address, length)	\
++	.long FDE_end/**/_/**/fde_no-FDE_start/**/_/**/fde_no;		\
++FDE_start/**/_/**/fde_no:						\
++	.long frame/**/_/**/ORD;					\
++	.long initial_address;					\
++	.long length;
++
++#define FDE_postamble(fde_no)			\
++	.align 4;				\
++FDE_end/**/_/**/fde_no:
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference.  You can also define a new
++ * area of code the info applies to.  For discontinuous bits you should
++ * start a new FDE.  You may have as many as you like.
++ */
++
++/*
++ * To advance the address by <bytes>
++ */
++
++#define FDE_advance(bytes)			\
++	.byte DW_CFA_advance_loc4		\
++	.long bytes
++
++
++
++/*
++ * With the above you can define all the register locations.  But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment.  This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset) \
++	.byte $DW_CFA_def_cfa_offset; \
++	.uleb128 (offset);
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg)		\
++	.byte DW_CFA_def_cfa_register;		\
++	.uleb128 reg;
++
++#endif
+--- linux-2.6.0-test6/include/linux/efi.h	2003-08-08 22:55:14.000000000 -0700
++++ 25/include/linux/efi.h	2003-10-05 00:36:22.000000000 -0700
+@@ -16,6 +16,8 @@
+ #include <linux/time.h>
+ #include <linux/types.h>
+ #include <linux/proc_fs.h>
++#include <linux/rtc.h>
++#include <linux/ioport.h>
+ 
+ #include <asm/page.h>
+ #include <asm/system.h>
+@@ -89,6 +91,11 @@ typedef	struct {
+ 
+ #define EFI_PAGE_SHIFT		12
+ 
++/*
++ * For current x86 implementations of EFI, there is
++ * additional padding in the mem descriptors.  This is not
++ * the case in ia64.  Need to have this fixed in the f/w.
++ */
+ typedef struct {
+ 	u32 type;
+ 	u32 pad;
+@@ -96,6 +103,9 @@ typedef struct {
+ 	u64 virt_addr;
+ 	u64 num_pages;
+ 	u64 attribute;
++#if defined (__i386__)
++	u64 pad1;
++#endif
+ } efi_memory_desc_t;
+ 
+ typedef int efi_freemem_callback_t (unsigned long start, unsigned long end, void *arg);
+@@ -132,6 +142,7 @@ typedef struct {
+  */
+ #define EFI_RESET_COLD 0
+ #define EFI_RESET_WARM 1
++#define EFI_RESET_SHUTDOWN 2
+ 
+ /*
+  * EFI Runtime Services table
+@@ -169,6 +180,10 @@ typedef efi_status_t efi_set_variable_t 
+ typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
+ typedef void efi_reset_system_t (int reset_type, efi_status_t status,
+ 				 unsigned long data_size, efi_char16_t *data);
++typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_size,
++						unsigned long descriptor_size,
++						u32 descriptor_version,
++						efi_memory_desc_t *virtual_map);
+ 
+ /*
+  *  EFI Configuration Table and GUID definitions
+@@ -194,6 +209,9 @@ typedef void efi_reset_system_t (int res
+ #define HCDP_TABLE_GUID	\
+     EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
+ 
++#define UGA_IO_PROTOCOL_GUID \
++    EFI_GUID(  0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 )
++
+ typedef struct {
+ 	efi_guid_t guid;
+ 	unsigned long table;
+@@ -218,6 +236,13 @@ typedef struct {
+ 	unsigned long tables;
+ } efi_system_table_t;
+ 
++struct efi_memory_map {
++	efi_memory_desc_t *phys_map;
++	efi_memory_desc_t *map;
++	int nr_map;
++	unsigned long desc_version;
++};
++
+ /*
+  * All runtime access to EFI goes through this structure:
+  */
+@@ -230,6 +255,7 @@ extern struct efi {
+ 	void *sal_systab;		/* SAL system table */
+ 	void *boot_info;		/* boot info table */
+ 	void *hcdp;			/* HCDP table */
++	void *uga;			/* UGA table */
+ 	efi_get_time_t *get_time;
+ 	efi_set_time_t *set_time;
+ 	efi_get_wakeup_time_t *get_wakeup_time;
+@@ -239,6 +265,7 @@ extern struct efi {
+ 	efi_set_variable_t *set_variable;
+ 	efi_get_next_high_mono_count_t *get_next_high_mono_count;
+ 	efi_reset_system_t *reset_system;
++	efi_set_virtual_address_map_t *set_virtual_address_map;
+ } efi;
+ 
+ static inline int
+@@ -260,12 +287,18 @@ efi_guid_unparse(efi_guid_t *guid, char 
+ 
+ extern void efi_init (void);
+ extern void efi_map_pal_code (void);
++extern void efi_map_memmap(void);
+ extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
+ extern void efi_gettimeofday (struct timespec *ts);
+ extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+ extern u64 efi_get_iobase (void);
+ extern u32 efi_mem_type (unsigned long phys_addr);
+ extern u64 efi_mem_attributes (unsigned long phys_addr);
++extern void efi_initialize_iomem_resources(struct resource *code_resource,
++					struct resource *data_resource);
++extern efi_status_t phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
++extern struct efi_memory_map memmap;
++extern int efi_enabled;
+ 
+ /*
+  * Variable Attributes
+--- linux-2.6.0-test6/include/linux/eisa.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/eisa.h	2003-10-05 00:36:11.000000000 -0700
+@@ -4,16 +4,6 @@
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ 
+-#ifdef CONFIG_EISA
+-# ifdef CONFIG_EISA_ALWAYS
+-#  define EISA_bus 1
+-# else
+-   extern int EISA_bus;
+-# endif
+-#else
+-# define EISA_bus 0
+-#endif
+-
+ #define EISA_SIG_LEN   8
+ #define EISA_MAX_SLOTS 8
+ 
+@@ -108,4 +98,10 @@ struct eisa_root_device {
+ 
+ int eisa_root_register (struct eisa_root_device *root);
+ 
++#ifdef CONFIG_EISA
++extern int EISA_bus;
++#else
++# define EISA_bus 0
++#endif
++
+ #endif
+--- linux-2.6.0-test6/include/linux/elevator.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/elevator.h	2003-10-05 00:34:17.000000000 -0700
+@@ -94,6 +94,11 @@ extern elevator_t iosched_deadline;
+  */
+ extern elevator_t iosched_as;
+ 
++/*
++ * completely fair queueing I/O scheduler
++ */
++extern elevator_t iosched_cfq;
++
+ extern int elevator_init(request_queue_t *, elevator_t *);
+ extern void elevator_exit(request_queue_t *);
+ extern inline int elv_rq_merge_ok(struct request *, struct bio *);
+--- linux-2.6.0-test6/include/linux/elf.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/elf.h	2003-10-05 00:33:24.000000000 -0700
+@@ -395,6 +395,7 @@ typedef struct elf64_shdr {
+ #define NT_PRFPREG	2
+ #define NT_PRPSINFO	3
+ #define NT_TASKSTRUCT	4
++#define NT_AUXV		6
+ #define NT_PRXFPREG     0x46e62b7f      /* copied from gdb5.1/include/elf/common.h */
+ 
+ 
+--- linux-2.6.0-test6/include/linux/errno.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/linux/errno.h	2003-10-05 00:36:54.000000000 -0700
+@@ -22,6 +22,7 @@
+ #define EBADTYPE	527	/* Type not supported by server */
+ #define EJUKEBOX	528	/* Request initiated, but will not complete before timeout */
+ #define EIOCBQUEUED	529	/* iocb queued, will get completion event */
++#define EIOCBRETRY	530	/* iocb queued, will trigger a retry */
+ 
+ #endif
+ 
+--- linux-2.6.0-test6/include/linux/ext3_fs_i.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/linux/ext3_fs_i.h	2003-10-05 00:36:12.000000000 -0700
+@@ -106,7 +106,7 @@ struct ext3_inode_info {
+ 	 * during recovery.  Hence we must fix the get_block-vs-truncate race
+ 	 * by other means, so we have truncate_sem.
+ 	 */
+-	struct rw_semaphore truncate_sem;
++	struct semaphore truncate_sem;
+ 	struct inode vfs_inode;
+ };
+ 
+--- linux-2.6.0-test6/include/linux/fb.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/include/linux/fb.h	2003-10-05 00:34:22.000000000 -0700
+@@ -2,7 +2,6 @@
+ #define _LINUX_FB_H
+ 
+ #include <linux/tty.h>
+-#include <linux/workqueue.h>
+ #include <asm/types.h>
+ #include <asm/io.h>
+ 
+@@ -326,28 +325,38 @@ struct fb_cursor {
+ 	struct fb_image	image;	/* Cursor image */
+ };
+ 
++#ifdef __KERNEL__
++
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/workqueue.h>
++#include <linux/devfs_fs_kernel.h>
++
++/*
++ * The purpose of this structure is to translate data
++ * from the hardwre independent format of fbdev to what
++ * format the hardware needs.
++ */
++
+ #define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
+ #define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
+ #define FB_PIXMAP_IO      4     /* memory is iomapped       */
+ #define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
+ 
+ struct fb_pixmap {
+-        __u8  *addr;                      /* pointer to memory             */  
+-	__u32 size;                       /* size of buffer in bytes       */
+-	__u32 offset;                     /* current offset to buffer      */
+-	__u32 buf_align;                  /* byte alignment of each bitmap */
+-	__u32 scan_align;                 /* alignment per scanline        */
+-	__u32 flags;                      /* see FB_PIXMAP_*               */
+-					  /* access methods                */
+-	void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
+-	u8   (*inbuf) (u8 *addr);
+-	spinlock_t lock;                  /* spinlock                      */
++	u8  *addr;		/* pointer to memory 			*/
++	u32 size;		/* size of buffer in bytes 		*/
++	u32 offset;		/* current offset to buffer 		*/
++	u32 buf_align;		/* byte alignment of each bitmap 	*/
++	u32 scan_align;		/* alignment per scanline 		*/
++	u32 access_align;	/* alignment per read/write		*/
++	u32 flags;		/* see FB_PIXMAP_* 			*/
++	spinlock_t lock;	/* spinlock 				*/
+ 	atomic_t count;
++	/* access methods */
++	void (*outbuf)(u8 *addr, u8 *dst, unsigned int size);
++	u8   (*inbuf) (u8 *addr);
+ };
+-#ifdef __KERNEL__
+-
+-#include <linux/fs.h>
+-#include <linux/init.h>
+ 
+ struct fb_info;
+ struct vm_area_struct;
+@@ -396,24 +405,24 @@ struct fb_ops {
+ };
+ 
+ struct fb_info {
+-   int node;
+-   int flags;
+-   int open;                            /* Has this been open already ? */
++	int node;
++	int flags;
+ #define FBINFO_FLAG_MODULE	1	/* Low-level driver is a module */
+-   struct fb_var_screeninfo var;        /* Current var */
+-   struct fb_fix_screeninfo fix;        /* Current fix */
+-   struct fb_monspecs monspecs;         /* Current Monitor specs */
+-   struct fb_cursor cursor;		/* Current cursor */	
+-   struct work_struct queue;		/* Framebuffer event queue */
+-   struct fb_pixmap pixmap;	        /* Current pixmap */
+-   struct fb_cmap cmap;                 /* Current cmap */
+-   struct fb_ops *fbops;
+-   char *screen_base;                   /* Virtual address */
+-   struct vc_data *display_fg;		/* Console visible on this display */
+-   int currcon;				/* Current VC. */	
+-   void *pseudo_palette;                /* Fake palette of 16 colors */ 
+-   /* From here on everything is device dependent */
+-   void *par;	
++	struct fb_var_screeninfo var;	/* Current var */
++	struct fb_fix_screeninfo fix;	/* Current fix */
++	struct fb_monspecs monspecs;	/* Current Monitor specs */
++	struct fb_cursor cursor;	/* Current cursor */
++	struct work_struct queue;	/* Framebuffer event queue */
++	struct fb_pixmap pixmap;	/* Image HW mapper */
++	struct fb_pixmap sprite;	/* Cursor HW mapper */
++	struct fb_cmap cmap;		/* Current cmap */
++	struct fb_ops *fbops;
++	char *screen_base;		/* Virtual address */
++	struct vc_data *display_fg;	/* Console visible on this display */
++	void *pseudo_palette;		/* Fake palette of 16 colors */
++	int currcon;			/* Current VC. */
++	/* From here on everything is device dependent */
++	void *par;
+ };
+ 
+ #ifdef MODULE
+@@ -481,12 +490,12 @@ extern int register_framebuffer(struct f
+ extern int unregister_framebuffer(struct fb_info *fb_info);
+ extern int fb_prepare_logo(struct fb_info *fb_info);
+ extern int fb_show_logo(struct fb_info *fb_info);
+-extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
+-extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+-			     	u32 height, u32 mask, u32 shift_high, u32 shift_low,
++extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
++extern void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++				u32 d_pitch, u32 height, u32 mask, u32 shift_high, u32 shift_low,
+ 				u32 mod, u32 idx);
+-extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+-			     u32 s_pitch, u32 height);
++extern void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u8 *src,
++			     u32 d_pitch, u32 s_pitch, u32 height);
+ extern struct fb_info *registered_fb[FB_MAX];
+ extern int num_registered_fb;
+ 
+--- linux-2.6.0-test6/include/linux/fs.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/fs.h	2003-10-05 00:37:00.000000000 -0700
+@@ -388,6 +388,7 @@ struct inode {
+ 	unsigned short          i_bytes;
+ 	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
+ 	struct semaphore	i_sem;
++	struct rw_semaphore	i_alloc_sem;
+ 	struct inode_operations	*i_op;
+ 	struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
+ 	struct super_block	*i_sb;
+@@ -480,6 +481,8 @@ static inline unsigned imajor(struct ino
+ 	return MAJOR(inode->i_rdev);
+ }
+ 
++extern struct block_device *I_BDEV(struct inode *inode);
++
+ struct fown_struct {
+ 	rwlock_t lock;          /* protects pid, uid, euid fields */
+ 	int pid;		/* pid or -pgrp where SIGIO should be sent */
+@@ -526,6 +529,7 @@ struct file {
+ 	/* Used by fs/eventpoll.c to link all the hooks to this file */
+ 	struct list_head	f_ep_links;
+ 	spinlock_t		f_ep_lock;
++	struct address_space	*f_mapping;
+ };
+ extern spinlock_t files_lock;
+ #define file_list_lock() spin_lock(&files_lock);
+@@ -749,6 +753,11 @@ extern int vfs_rename(struct inode *, st
+ #define DT_SOCK		12
+ #define DT_WHT		14
+ 
++#define OSYNC_METADATA	(1<<0)
++#define OSYNC_DATA	(1<<1)
++#define OSYNC_INODE	(1<<2)
++int generic_osync_inode(struct inode *, struct address_space *, int);
++
+ /*
+  * This is the "filldir" function type, used by readdir() to let
+  * the kernel specify what kind of dirent layout it wants to have.
+@@ -758,9 +767,9 @@ extern int vfs_rename(struct inode *, st
+ typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned);
+ 
+ struct block_device_operations {
+-	int (*open) (struct inode *, struct file *);
+-	int (*release) (struct inode *, struct file *);
+-	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
++	int (*open) (struct block_device *, struct file *);
++	int (*release) (struct gendisk *);
++	int (*ioctl) (struct block_device *, struct file *, unsigned, unsigned long);
+ 	int (*media_changed) (struct gendisk *);
+ 	int (*revalidate_disk) (struct gendisk *);
+ 	struct module *owner;
+@@ -1123,11 +1132,9 @@ enum {BDEV_FILE, BDEV_SWAP, BDEV_FS, BDE
+ extern int register_blkdev(unsigned int, const char *);
+ extern int unregister_blkdev(unsigned int, const char *);
+ extern struct block_device *bdget(dev_t);
+-extern int bd_acquire(struct inode *inode);
+ extern void bd_forget(struct inode *inode);
+ extern void bdput(struct block_device *);
+ extern int blkdev_open(struct inode *, struct file *);
+-extern int blkdev_close(struct inode *, struct file *);
+ extern struct block_device *open_by_devnum(dev_t, unsigned, int);
+ extern struct file_operations def_blk_fops;
+ extern struct address_space_operations def_blk_aops;
+@@ -1135,7 +1142,7 @@ extern struct file_operations def_chr_fo
+ extern struct file_operations bad_sock_fops;
+ extern struct file_operations def_fifo_fops;
+ extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
+-extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
++extern int blkdev_ioctl(struct block_device *, struct file *, unsigned, unsigned long);
+ extern int blkdev_get(struct block_device *, mode_t, unsigned, int);
+ extern int blkdev_put(struct block_device *, int);
+ extern int bd_claim(struct block_device *, void *);
+@@ -1202,6 +1209,7 @@ extern void write_inode_now(struct inode
+ extern int filemap_fdatawrite(struct address_space *);
+ extern int filemap_flush(struct address_space *);
+ extern int filemap_fdatawait(struct address_space *);
++extern int filemap_write_and_wait(struct address_space *mapping);
+ extern void sync_supers(void);
+ extern void sync_filesystems(int wait);
+ extern void emergency_sync(void);
+@@ -1295,8 +1303,7 @@ extern int generic_file_readonly_mmap(st
+ extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
+ extern int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
+ extern ssize_t generic_file_read(struct file *, char __user *, size_t, loff_t *);
+-int generic_write_checks(struct inode *inode, struct file *file,
+-			loff_t *pos, size_t *count, int isblk);
++int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
+ extern ssize_t generic_file_write(struct file *, const char __user *, size_t, loff_t *);
+ extern ssize_t generic_file_aio_read(struct kiocb *, char __user *, size_t, loff_t);
+ extern ssize_t __generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t *);
+@@ -1314,9 +1321,6 @@ extern void
+ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
+ extern ssize_t generic_file_direct_IO(int rw, struct kiocb *iocb,
+ 	const struct iovec *iov, loff_t offset, unsigned long nr_segs);
+-extern int blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, 
+-	struct block_device *bdev, const struct iovec *iov, loff_t offset, 
+-	unsigned long nr_segs, get_blocks_t *get_blocks, dio_iodone_t *end_io);
+ extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 
+ 	unsigned long nr_segs, loff_t *ppos);
+ ssize_t generic_file_writev(struct file *filp, const struct iovec *iov, 
+@@ -1330,7 +1334,7 @@ static inline void do_generic_file_read(
+ 					read_descriptor_t * desc,
+ 					read_actor_t actor)
+ {
+-	do_generic_mapping_read(filp->f_dentry->d_inode->i_mapping,
++	do_generic_mapping_read(filp->f_mapping,
+ 				&filp->f_ra,
+ 				filp,
+ 				ppos,
+@@ -1338,6 +1342,32 @@ static inline void do_generic_file_read(
+ 				actor);
+ }
+ 
++int __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
++	struct block_device *bdev, const struct iovec *iov, loff_t offset,
++	unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
++	int needs_special_locking);
++
++/*
++ * For filesystems which need locking between buffered and direct access
++ */
++static inline int blockdev_direct_IO(int rw, struct kiocb *iocb,
++	struct inode *inode, struct block_device *bdev, const struct iovec *iov,
++	loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
++	dio_iodone_t end_io)
++{
++	return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
++				nr_segs, get_blocks, end_io, 1);
++}
++
++static inline int blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
++	struct inode *inode, struct block_device *bdev, const struct iovec *iov,
++	loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
++	dio_iodone_t end_io)
++{
++	return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
++				nr_segs, get_blocks, end_io, 0);
++}
++
+ extern struct file_operations generic_ro_fops;
+ 
+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
+--- linux-2.6.0-test6/include/linux/ftape.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/ftape.h	2003-10-05 00:33:24.000000000 -0700
+@@ -35,7 +35,6 @@
+ #include <linux/mm.h>
+ #endif
+ #include <linux/types.h>
+-#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/mtio.h>
+ 
+--- linux-2.6.0-test6/include/linux/hdlcdrv.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/hdlcdrv.h	2003-10-05 00:33:24.000000000 -0700
+@@ -359,11 +359,11 @@ static inline int hdlcdrv_ptt(struct hdl
+ void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
+ void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
+ void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
+-int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops,
+-			     unsigned int privsize, char *ifname,
+-			     unsigned int baseaddr, unsigned int irq, 
+-			     unsigned int dma);
+-int hdlcdrv_unregister_hdlcdrv(struct net_device *dev);
++struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
++				    unsigned int privsize, const char *ifname,
++				    unsigned int baseaddr, unsigned int irq, 
++				    unsigned int dma);
++void hdlcdrv_unregister(struct net_device *dev);
+ 
+ /* -------------------------------------------------------------------- */
+ 
+--- linux-2.6.0-test6/include/linux/hfs_fs.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/linux/hfs_fs.h	2003-10-05 00:33:24.000000000 -0700
+@@ -267,9 +267,9 @@ extern void hfs_nat_drop_dentry(struct d
+ 
+ /* file.c */
+ extern hfs_s32 hfs_do_read(struct inode *, struct hfs_fork *, hfs_u32,
+-			   char *, hfs_u32);
++			   char __user *, hfs_u32);
+ extern hfs_s32 hfs_do_write(struct inode *, struct hfs_fork *, hfs_u32,
+-			    const char *, hfs_u32);
++			    const char __user *, hfs_u32);
+ extern void hfs_file_fix_mode(struct hfs_cat_entry *entry);
+ extern struct inode_operations hfs_file_inode_operations;
+ extern struct file_operations hfs_file_operations;
+--- linux-2.6.0-test6/include/linux/highuid.h	2003-06-14 12:18:23.000000000 -0700
++++ 25/include/linux/highuid.h	2003-10-05 00:33:24.000000000 -0700
+@@ -56,6 +56,8 @@ extern int overflowgid;
+ #define SET_GID16(var, gid)	var = high2lowgid(gid)
+ #define NEW_TO_OLD_UID(uid)	high2lowuid(uid)
+ #define NEW_TO_OLD_GID(gid)	high2lowgid(gid)
++#define OLD_TO_NEW_UID(uid)	low2highuid(uid)
++#define OLD_TO_NEW_GID(gid)	low2highgid(gid)
+ 
+ /* specific to fs/stat.c */
+ #define SET_OLDSTAT_UID(stat, uid)	(stat).st_uid = high2lowuid(uid)
+@@ -69,6 +71,8 @@ extern int overflowgid;
+ #define SET_GID16(var, gid)	do { ; } while (0)
+ #define NEW_TO_OLD_UID(uid)	(uid)
+ #define NEW_TO_OLD_GID(gid)	(gid)
++#define OLD_TO_NEW_UID(uid)	(uid)
++#define OLD_TO_NEW_GID(gid)	(gid)
+ 
+ #define SET_OLDSTAT_UID(stat, uid)	(stat).st_uid = (uid)
+ #define SET_OLDSTAT_GID(stat, gid)	(stat).st_gid = (gid)
+--- linux-2.6.0-test6/include/linux/init_task.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/init_task.h	2003-10-05 00:36:54.000000000 -0700
+@@ -108,6 +108,7 @@
+ 	.proc_lock	= SPIN_LOCK_UNLOCKED,				\
+ 	.switch_lock	= SPIN_LOCK_UNLOCKED,				\
+ 	.journal_info	= NULL,						\
++	.io_wait	= NULL,						\
+ }
+ 
+ 
+--- linux-2.6.0-test6/include/linux/input.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/input.h	2003-10-05 00:34:14.000000000 -0700
+@@ -870,6 +870,7 @@ struct input_handler {
+ 	char *name;
+ 
+ 	struct input_device_id *id_table;
++	struct input_device_id *blacklist;
+ 
+ 	struct list_head	h_list;
+ 	struct list_head	node;
+--- linux-2.6.0-test6/include/linux/istallion.h	2003-06-14 12:18:01.000000000 -0700
++++ 25/include/linux/istallion.h	2003-10-05 00:33:24.000000000 -0700
+@@ -21,6 +21,8 @@
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
++#include <linux/version.h>
++
+ /*****************************************************************************/
+ #ifndef	_ISTALLION_H
+ #define	_ISTALLION_H
+--- linux-2.6.0-test6/include/linux/linux_logo.h	2003-06-14 12:18:05.000000000 -0700
++++ 25/include/linux/linux_logo.h	2003-10-05 00:34:22.000000000 -0700
+@@ -16,13 +16,11 @@
+ 
+ #include <linux/init.h>
+ 
+-
+ #define LINUX_LOGO_MONO		1	/* monochrome black/white */
+ #define LINUX_LOGO_VGA16	2	/* 16 colors VGA text palette */
+ #define LINUX_LOGO_CLUT224	3	/* 224 colors */
+ #define LINUX_LOGO_GRAY256	4	/* 256 levels grayscale */
+ 
+-
+ struct linux_logo {
+ 	int type;			/* one of LINUX_LOGO_* */
+ 	unsigned int width;
+@@ -32,6 +30,6 @@ struct linux_logo {
+ 	const unsigned char *data;
+ };
+ 
+-extern const struct linux_logo *fb_find_logo(int depth);
++extern const struct linux_logo *find_logo(int depth);
+ 
+ #endif /* _LINUX_LINUX_LOGO_H */
+--- linux-2.6.0-test6/include/linux/list.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/linux/list.h	2003-10-05 00:36:37.000000000 -0700
+@@ -142,8 +142,11 @@ static inline void __list_del(struct lis
+  * Note: list_empty on entry does not return true after this, the entry is
+  * in an undefined state.
+  */
++#include <linux/kernel.h>	/* BUG_ON */
+ static inline void list_del(struct list_head *entry)
+ {
++	BUG_ON(entry->prev->next != entry);
++	BUG_ON(entry->next->prev != entry);
+ 	__list_del(entry->prev, entry->next);
+ 	entry->next = LIST_POISON1;
+ 	entry->prev = LIST_POISON2;
+@@ -325,6 +328,19 @@ static inline void list_splice_init(stru
+ 	     pos = list_entry(pos->member.prev, typeof(*pos), member),	\
+ 		     prefetch(pos->member.prev))
+ 
++/**
++ * list_for_each_entry_continue -	iterate over list of given type
++ *			continuing after existing point
++ * @pos:	the type * to use as a loop counter.
++ * @head:	the head for your list.
++ * @member:	the name of the list_struct within the struct.
++ */
++#define list_for_each_entry_continue(pos, head, member) 		\
++	for (pos = list_entry(pos->member.next, typeof(*pos), member),	\
++		     prefetch(pos->member.next);			\
++	     &pos->member != (head);					\
++	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
++		     prefetch(pos->member.next))
+ 
+ /**
+  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+@@ -436,7 +452,7 @@ static __inline__ void hlist_del(struct 
+ 
+ /**
+  * hlist_del_rcu - deletes entry from hash list without re-initialization
+- * @entry: the element to delete from the hash list.
++ * @n: the element to delete from the hash list.
+  *
+  * Note: list_unhashed() on entry does not return true after this, 
+  * the entry is in an undefined state. It is useful for RCU based
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/lockmeter.h	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,320 @@
++/*
++ *  Copyright (C) 1999-2002 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com) Feb-Apr 2000
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ *  Moved machine dependent code to include/asm/lockmeter.h.
++ *
++ */
++
++#ifndef _LINUX_LOCKMETER_H
++#define _LINUX_LOCKMETER_H
++
++
++/*---------------------------------------------------
++ *	architecture-independent lockmeter.h
++ *-------------------------------------------------*/
++
++/*
++ * raybry -- version 2: added efficient hold time statistics
++ *           requires lstat recompile, so flagged as new version
++ * raybry -- version 3: added global reader lock data
++ * hawkes -- version 4: removed some unnecessary fields to simplify mips64 port
++ */
++#define LSTAT_VERSION	5
++
++int	lstat_update(void*, void*, int);
++int	lstat_update_time(void*, void*, int, uint32_t);
++
++/*
++ * Currently, the mips64 and sparc64 kernels talk to a 32-bit lockstat, so we
++ * need to force compatibility in the inter-communication data structure.
++ */
++
++#if defined(CONFIG_MIPS32_COMPAT)
++#define TIME_T		uint32_t
++#elif defined(CONFIG_SPARC) || defined(CONFIG_SPARC64)
++#define TIME_T		uint64_t
++#else
++#define TIME_T		time_t
++#endif
++
++#if defined(__KERNEL__) || (!defined(CONFIG_MIPS32_COMPAT) && !defined(CONFIG_SPARC) && !defined(CONFIG_SPARC64)) || (_MIPS_SZLONG==32)
++#define POINTER		void *
++#else
++#define	POINTER		int64_t
++#endif
++
++/*
++ * Values for the "action" parameter passed to lstat_update.
++ *	ZZZ - do we want a try-success status here???
++ */
++#define LSTAT_ACT_NO_WAIT	0
++#define LSTAT_ACT_SPIN		1
++#define LSTAT_ACT_REJECT	2
++#define LSTAT_ACT_WW_SPIN       3
++#define LSTAT_ACT_SLEPT		4 /* UNUSED */
++
++#define LSTAT_ACT_MAX_VALUES	4 /* NOTE: Increase to 5 if use ACT_SLEPT */
++
++/*
++ * Special values for the low 2 bits of an RA passed to
++ * lstat_update.
++ */
++/* we use these values to figure out what kind of lock data */
++/* is stored in the statistics table entry at index ....... */
++#define LSTAT_RA_SPIN           0  /* spin lock data */
++#define LSTAT_RA_READ           1  /* read lock statistics */
++#define LSTAT_RA_SEMA		2  /* RESERVED */
++#define LSTAT_RA_WRITE          3  /* write lock statistics*/
++
++#define LSTAT_RA(n)	\
++	((void*)( ((unsigned long)__builtin_return_address(0) & ~3) | n) )
++
++/*
++ * Constants used for lock addresses in the lstat_directory
++ * to indicate special values of the lock address.
++ */
++#define	LSTAT_MULTI_LOCK_ADDRESS	NULL
++
++/*
++ * Maximum size of the lockstats tables. Increase this value
++ * if its not big enough. (Nothing bad happens if its not
++ * big enough although some locks will not be monitored.)
++ * We record overflows of this quantity in lstat_control.dir_overflows
++ *
++ * Note:  The max value here must fit into the field set
++ * and obtained by the macro's PUT_INDEX() and GET_INDEX().
++ * This value depends on how many bits are available in the
++ * lock word in the particular machine implementation we are on.
++ */
++#define LSTAT_MAX_STAT_INDEX		2000
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE		4096		/* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK		(LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ *	This defines an entry in the lockstat directory. It contains
++ *	information about a lock being monitored.
++ *	A directory entry only contains the lock identification -
++ *	counts on usage of the lock are kept elsewhere in a per-cpu
++ *	data structure to minimize cache line pinging.
++ */
++typedef struct {
++	POINTER	caller_ra;		  /* RA of code that set lock */
++	POINTER	lock_ptr;		  /* lock address */
++	ushort	next_stat_index;  /* Used to link multiple locks that have the same hash table value */
++} lstat_directory_entry_t;
++
++/*
++ *	A multi-dimensioned array used to contain counts for lock accesses.
++ *	The array is 3-dimensional:
++ *		- CPU number. Keep from thrashing cache lines between CPUs
++ *		- Directory entry index. Identifies the lock
++ *		- Action. Indicates what kind of contention occurred on an
++ *		  access to the lock.
++ *
++ *	The index of an entry in the directory is the same as the 2nd index
++ *	of the entry in the counts array.
++ */
++/*
++ *  This table contains data for spin_locks, write locks, and read locks
++ *  Not all data is used for all cases.  In particular, the hold time
++ *  information is not stored here for read locks since that is a global
++ *  (e. g. cannot be separated out by return address) quantity.
++ *  See the lstat_read_lock_counts_t structure for the global read lock
++ *  hold time.
++ */
++typedef struct {
++	uint64_t    cum_wait_ticks;	/* sum of wait times               */
++	                                /* for write locks, sum of time a  */
++					/* writer is waiting for a reader  */
++	int64_t	    cum_hold_ticks;	/* cumulative sum of holds         */
++	                                /* not used for read mode locks    */
++					/* must be signed. ............... */
++	uint32_t    max_wait_ticks;	/* max waiting time                */
++	uint32_t    max_hold_ticks;	/* max holding time                */
++	uint64_t    cum_wait_ww_ticks;  /* sum times writer waits on writer*/
++	uint32_t    max_wait_ww_ticks;  /* max wait time writer vs writer  */
++	                                /* prev 2 only used for write locks*/
++	uint32_t    acquire_time;       /* time lock acquired this CPU     */
++	uint32_t    count[LSTAT_ACT_MAX_VALUES];
++} lstat_lock_counts_t;
++
++typedef lstat_lock_counts_t	lstat_cpu_counts_t[LSTAT_MAX_STAT_INDEX];
++
++/*
++ * User request to:
++ *	- turn statistic collection on/off, or to reset
++ */
++#define LSTAT_OFF	 0
++#define LSTAT_ON	 1
++#define LSTAT_RESET      2
++#define LSTAT_RELEASE    3
++
++#define LSTAT_MAX_READ_LOCK_INDEX 1000
++typedef struct {
++	POINTER	    lock_ptr;            /* address of lock for output stats */
++	uint32_t    read_lock_count;
++	int64_t     cum_hold_ticks;       /* sum of read lock hold times over */
++	                                  /* all callers. ....................*/
++	uint32_t    write_index;          /* last write lock hash table index */
++	uint32_t    busy_periods;         /* count of busy periods ended this */
++	uint64_t    start_busy;           /* time this busy period started. ..*/
++	uint64_t    busy_ticks;           /* sum of busy periods this lock. ..*/
++	uint64_t    max_busy;             /* longest busy period for this lock*/
++	uint32_t    max_readers;          /* maximum number of readers ...... */
++#ifdef USER_MODE_TESTING
++	rwlock_t    entry_lock;           /* lock for this read lock entry... */
++	                                  /* avoid having more than one rdr at*/
++	                                  /* needed for user space testing... */
++	                                  /* not needed for kernel 'cause it  */
++					  /* is non-preemptive. ............. */
++#endif
++} lstat_read_lock_counts_t;
++typedef lstat_read_lock_counts_t	lstat_read_lock_cpu_counts_t[LSTAT_MAX_READ_LOCK_INDEX];
++
++#if defined(__KERNEL__) || defined(USER_MODE_TESTING)
++
++#ifndef USER_MODE_TESTING
++#include <asm/lockmeter.h>
++#else
++#include "asm_newlockmeter.h"
++#endif
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE		4096		/* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK		(LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ * This version eliminates the per processor lock stack.  What we do is to
++ * store the index of the lock hash structure in unused bits in the lock
++ * itself.  Then on unlock we can find the statistics record without doing
++ * any additional hash or lock stack lookup.  This works for spin_locks.
++ * Hold time reporting is now basically as cheap as wait time reporting
++ * so we ignore the difference between LSTAT_ON_HOLD and LSTAT_ON_WAIT
++ * as in version 1.1.* of lockmeter.
++ *
++ * For rw_locks, we store the index of a global reader stats structure in
++ * the lock and the writer index is stored in the latter structure.
++ * For read mode locks we hash at the time of the lock to find an entry
++ * in the directory for reader wait time and the like.
++ * At unlock time for read mode locks, we update just the global structure
++ * so we don't need to know the reader directory index value at unlock time.
++ *
++ */
++
++/*
++ * Protocol to change lstat_control.state
++ *   This is complicated because we don't want the cum_hold_time for
++ * a rw_lock to be decremented in _read_lock_ without making sure it
++ * is incremented in _read_lock_ and vice versa.  So here is the
++ * way we change the state of lstat_control.state:
++ * I.  To Turn Statistics On
++ *     After allocating storage, set lstat_control.state non-zero.
++ * This works because we don't start updating statistics for in use
++ * locks until the reader lock count goes to zero.
++ * II. To Turn Statistics Off:
++ * (0)  Disable interrupts on this CPU
++ * (1)  Seize the lstat_control.directory_lock
++ * (2)  Obtain the current value of lstat_control.next_free_read_lock_index
++ * (3)  Store a zero in lstat_control.state.
++ * (4)  Release the lstat_control.directory_lock
++ * (5)  For each lock in the read lock list up to the saved value
++ *      (well, -1) of the next_free_read_lock_index, do the following:
++ *      (a)  Check validity of the stored lock address
++ *           by making sure that the word at the saved addr
++ *           has an index that matches this entry.  If not
++ *           valid, then skip this entry.
++ *      (b)  If there is a write lock already set on this lock,
++ *           skip to (d) below.
++ *      (c)  Set a non-metered write lock on the lock
++ *      (d)  set the cached INDEX in the lock to zero
++ *      (e)  Release the non-metered write lock.
++ * (6)  Re-enable interrupts
++ *
++ * These rules ensure that a read lock will not have its statistics
++ * partially updated even though the global lock recording state has
++ * changed.  See put_lockmeter_info() for implementation.
++ *
++ * The reason for (b) is that there may be write locks set on the
++ * syscall path to put_lockmeter_info() from user space.  If we do
++ * not do this check, then we can deadlock.  A similar problem would
++ * occur if the lock was read locked by the current CPU.  At the
++ * moment this does not appear to happen.
++ */
++
++/*
++ * Main control structure for lockstat. Used to turn statistics on/off
++ * and to maintain directory info.
++ */
++typedef struct {
++	int				state;
++	spinlock_t		control_lock;		/* used to serialize turning statistics on/off   */
++	spinlock_t		directory_lock;		/* for serialize adding entries to directory     */
++	volatile int	next_free_dir_index;/* next free entry in the directory */
++	/* FIXME not all of these fields are used / needed .............. */
++                /* the following fields represent data since     */
++		/* first "lstat on" or most recent "lstat reset" */
++	TIME_T      first_started_time;     /* time when measurement first enabled */
++	TIME_T      started_time;           /* time when measurement last started  */
++	TIME_T      ending_time;            /* time when measurement last disabled */
++	uint64_t    started_cycles64;       /* cycles when measurement last started          */
++	uint64_t    ending_cycles64;        /* cycles when measurement last disabled         */
++	uint64_t    enabled_cycles64;       /* total cycles with measurement enabled         */
++	int         intervals;              /* number of measurement intervals recorded      */
++	                                    /* i. e. number of times did lstat on;lstat off  */
++	lstat_directory_entry_t	*dir;		/* directory */
++	int         dir_overflow;           /* count of times ran out of space in directory  */
++	int         rwlock_overflow;        /* count of times we couldn't allocate a rw block*/
++	ushort		*hashtab;		 	    /* hash table for quick dir scans */
++	lstat_cpu_counts_t	*counts[NR_CPUS];	 /* Array of pointers to per-cpu stats */
++    int         next_free_read_lock_index;   /* next rwlock reader (global) stats block  */
++    lstat_read_lock_cpu_counts_t *read_lock_counts[NR_CPUS]; /* per cpu read lock stats  */
++} lstat_control_t;
++
++#endif	/* defined(__KERNEL__) || defined(USER_MODE_TESTING) */
++
++typedef struct {
++	short		lstat_version;		/* version of the data */
++	short		state;			/* the current state is returned */
++	int		maxcpus;		/* Number of cpus present */
++	int		next_free_dir_index;	/* index of the next free directory entry */
++	TIME_T          first_started_time;	/* when measurement enabled for first time */
++	TIME_T          started_time;		/* time in secs since 1969 when stats last turned on  */
++	TIME_T		ending_time;		/* time in secs since 1969 when stats last turned off */
++	uint32_t	cycleval;		/* cycles per second */
++#ifdef notyet
++	void		*kernel_magic_addr;	/* address of kernel_magic */
++	void		*kernel_end_addr;	/* contents of kernel magic (points to "end") */
++#endif
++	int              next_free_read_lock_index; /* index of next (global) read lock stats struct */
++	uint64_t         started_cycles64;	/* cycles when measurement last started        */
++	uint64_t         ending_cycles64;	/* cycles when stats last turned off           */
++	uint64_t         enabled_cycles64;	/* total cycles with measurement enabled       */
++	int              intervals;		/* number of measurement intervals recorded      */
++						/* i.e. number of times we did lstat on;lstat off*/
++	int              dir_overflow;		/* number of times we wanted more space in directory */
++	int              rwlock_overflow;	/* # of times we wanted more space in read_locks_count */
++	struct new_utsname   uts;		/* info about machine where stats are measured */
++						/* -T option of lockstat allows data to be     */
++						/* moved to another machine. ................. */
++} lstat_user_request_t;
++
++#endif /* _LINUX_LOCKMETER_H */
+--- linux-2.6.0-test6/include/linux/mca.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/mca.h	2003-10-05 00:33:24.000000000 -0700
+@@ -136,10 +136,6 @@ extern void mca_unregister_driver(struct
+ /* WARNING: only called by the boot time device setup */
+ extern int mca_register_device(int bus, struct mca_device *mca_dev);
+ 
+-#ifdef CONFIG_MCA_LEGACY
+-#include <linux/mca-legacy.h>
+-#endif
+-
+ #ifdef CONFIG_MCA_PROC_FS
+ extern void mca_do_proc_init(void);
+ extern void mca_set_adapter_procfn(int slot, MCA_ProcFn, void* dev);
+--- linux-2.6.0-test6/include/linux/mca-legacy.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/linux/mca-legacy.h	2003-10-05 00:33:24.000000000 -0700
+@@ -7,6 +7,8 @@
+ #ifndef _LINUX_MCA_LEGACY_H
+ #define _LINUX_MCA_LEGACY_H
+ 
++#include <linux/mca.h>
++
+ #warning "MCA legacy - please move your driver to the new sysfs api"
+ 
+ /* MCA_NOTFOUND is an error condition.  The other two indicate
+--- linux-2.6.0-test6/include/linux/mman.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/mman.h	2003-10-05 00:34:49.000000000 -0700
+@@ -28,8 +28,13 @@ static inline void vm_unacct_memory(long
+ 	vm_acct_memory(-pages);
+ }
+ 
+-/* Optimisation macro. */
+-#define _calc_vm_trans(x,bit1,bit2) \
++/*
++ * Optimisation macro.  It is equivalent to:
++ *      (x & bit1) ? bit2 : 0
++ * but this version is faster.
++ * ("bit1" and "bit2" must be single bits)
++ */
++#define _calc_vm_trans(x, bit1, bit2) \
+   ((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \
+    : ((x) & (bit1)) / ((bit1) / (bit2)))
+ 
+--- linux-2.6.0-test6/include/linux/mm.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/mm.h	2003-10-05 00:34:41.000000000 -0700
+@@ -196,7 +196,7 @@ struct page {
+ #if defined(WANT_PAGE_VIRTUAL)
+ 	void *virtual;			/* Kernel virtual address (NULL if
+ 					   not kmapped, ie. highmem) */
+-#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
++#endif /* WANT_PAGE_VIRTUAL */
+ };
+ 
+ /*
+@@ -323,7 +323,6 @@ static inline void put_page(struct page 
+  * The zone field is never updated after free_area_init_core()
+  * sets it, so none of the operations on it need to be atomic.
+  */
+-#define NODE_SHIFT 4
+ #define ZONE_SHIFT (BITS_PER_LONG - 8)
+ 
+ struct zone;
+--- linux-2.6.0-test6/include/linux/mmzone.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/mmzone.h	2003-10-05 00:34:41.000000000 -0700
+@@ -10,13 +10,8 @@
+ #include <linux/wait.h>
+ #include <linux/cache.h>
+ #include <linux/threads.h>
++#include <linux/numa.h>
+ #include <asm/atomic.h>
+-#ifdef CONFIG_DISCONTIGMEM
+-#include <asm/numnodes.h>
+-#endif
+-#ifndef MAX_NUMNODES
+-#define MAX_NUMNODES 1
+-#endif
+ 
+ /* Free memory management - zoned buddy allocator.  */
+ #ifndef CONFIG_FORCE_MAX_ZONEORDER
+@@ -303,19 +298,34 @@ extern void setup_per_zone_pages_min(voi
+ #define numa_node_id()		(cpu_to_node(smp_processor_id()))
+ 
+ #ifndef CONFIG_DISCONTIGMEM
++
+ extern struct pglist_data contig_page_data;
+ #define NODE_DATA(nid)		(&contig_page_data)
+ #define NODE_MEM_MAP(nid)	mem_map
+-#define MAX_NR_NODES		1
++#define MAX_NODES_SHIFT		0
++
+ #else /* CONFIG_DISCONTIGMEM */
+ 
+ #include <asm/mmzone.h>
+ 
+-/* page->zone is currently 8 bits ... */
+-#define MAX_NR_NODES		(255 / MAX_NR_ZONES)
++#if BITS_PER_LONG == 32
++/*
++ * with 32 bit flags field, page->zone is currently 8 bits.
++ * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
++ */
++#define MAX_NODES_SHIFT		6
++#elif BITS_PER_LONG == 64
++/*
++ * with 64 bit flags field, there's plenty of room.
++ */
++#define MAX_NODES_SHIFT		10
++#endif
+ 
+ #endif /* !CONFIG_DISCONTIGMEM */
+ 
++#if NODES_SHIFT > MAX_NODES_SHIFT
++#error NODES_SHIFT > MAX_NODES_SHIFT
++#endif
+ 
+ extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
+ extern DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS);
+--- linux-2.6.0-test6/include/linux/moduleparam.h	2003-06-16 22:32:21.000000000 -0700
++++ 25/include/linux/moduleparam.h	2003-10-05 00:33:24.000000000 -0700
+@@ -3,6 +3,7 @@
+ /* (C) Copyright 2001, 2002 Rusty Russell IBM Corporation */
+ #include <linux/init.h>
+ #include <linux/stringify.h>
++#include <linux/kernel.h>
+ 
+ /* You can override this manually, but generally this should match the
+    module name. */
+@@ -33,6 +34,17 @@ struct kparam_string {
+ 	char *string;
+ };
+ 
++/* Special one for arrays */
++struct kparam_array
++{
++	unsigned int max;
++	unsigned int *num;
++	param_set_fn set;
++	param_get_fn get;
++	unsigned int elemsize;
++	void *elem;
++};
++
+ /* This is the fundamental function for registering boot/module
+    parameters.  perm sets the visibility in driverfs: 000 means it's
+    not there, read bits mean it's readable, write bits mean it's
+@@ -112,10 +124,16 @@ extern int param_set_invbool(const char 
+ extern int param_get_invbool(char *buffer, struct kernel_param *kp);
+ #define param_check_invbool(name, p) __param_check(name, p, int)
+ 
+-/* First two elements are the max and min array length (which don't change) */
+-extern int param_set_intarray(const char *val, struct kernel_param *kp);
+-extern int param_get_intarray(char *buffer, struct kernel_param *kp);
+-#define param_check_intarray(name, p) __param_check(name, p, int *)
++/* Comma-separated array: num is set to number they actually specified. */
++#define module_param_array(name, type, num, perm)			\
++	static struct kparam_array __param_arr_##name			\
++	= { ARRAY_SIZE(name), &num, param_set_##type, param_get_##type,	\
++	    sizeof(name[0]), name };					\
++	module_param_call(name, param_array_set, param_array_get, 	\
++			  &__param_arr_##name, perm)
++
++extern int param_array_set(const char *val, struct kernel_param *kp);
++extern int param_array_get(char *buffer, struct kernel_param *kp);
+ 
+ extern int param_set_copystring(const char *val, struct kernel_param *kp);
+ 
+@@ -123,5 +141,6 @@ int param_array(const char *name,
+ 		const char *val,
+ 		unsigned int min, unsigned int max,
+ 		void *elem, int elemsize,
+-		int (*set)(const char *, struct kernel_param *kp));
++		int (*set)(const char *, struct kernel_param *kp),
++		int *num);
+ #endif /* _LINUX_MODULE_PARAM_TYPES_H */
+--- linux-2.6.0-test6/include/linux/netdevice.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/netdevice.h	2003-10-05 00:33:46.000000000 -0700
+@@ -456,6 +456,13 @@ struct net_device
+ 	/* bridge stuff */
+ 	struct net_bridge_port	*br_port;
+ 
++#ifdef CONFIG_KGDB
++	int			kgdb_is_trapped;
++#endif
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	void			(*poll_controller)(struct net_device *);
++#endif
++
+ #ifdef CONFIG_NET_FASTROUTE
+ #define NETDEV_FASTROUTE_HMASK 0xF
+ 	/* Semi-private data. Keep it at the end of device struct. */
+@@ -530,6 +537,11 @@ extern int		dev_new_index(void);
+ extern struct net_device	*dev_get_by_index(int ifindex);
+ extern struct net_device	*__dev_get_by_index(int ifindex);
+ extern int		dev_restart(struct net_device *dev);
++#ifdef CONFIG_KGDB
++extern int		kgdb_eth_is_trapped(void);
++extern int		kgdb_net_interrupt(struct sk_buff *skb);
++extern void		kgdb_send_arp_request(void);
++#endif
+ 
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+ extern int		register_gifconf(unsigned int family, gifconf_func_t * gifconf);
+@@ -588,12 +600,22 @@ static inline void netif_start_queue(str
+ 
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++	if (kgdb_eth_is_trapped()) {
++		return;
++	}
++#endif
+ 	if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+ 		__netif_schedule(dev);
+ }
+ 
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++	if (kgdb_eth_is_trapped()) {
++		return;
++	}
++#endif
+ 	set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+ 
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/netfilter_bridge/ebt_limit.h	2003-10-05 00:33:24.000000000 -0700
+@@ -0,0 +1,23 @@
++#ifndef __LINUX_BRIDGE_EBT_LIMIT_H
++#define __LINUX_BRIDGE_EBT_LIMIT_H
++
++#define EBT_LIMIT_MATCH "limit"
++
++/* timings are in milliseconds. */
++#define EBT_LIMIT_SCALE 10000
++
++/* 1/10,000 sec period => max of 10,000/sec.  Min rate is then 429490
++   seconds, or one every 59 hours. */
++
++struct ebt_limit_info
++{
++	u_int32_t avg;    /* Average secs between packets * scale */
++	u_int32_t burst;  /* Period multiplier for upper limit. */
++
++	/* Used internally by the kernel */
++	unsigned long prev;
++	u_int32_t credit;
++	u_int32_t credit_cap, cost;
++};
++
++#endif
+--- linux-2.6.0-test6/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2003-06-14 12:18:29.000000000 -0700
++++ 25/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2003-10-05 00:33:24.000000000 -0700
+@@ -62,6 +62,14 @@ struct ip_conntrack_tuple
+ 	} dst;
+ };
+ 
++/* This is optimized opposed to a memset of the whole structure.  Everything we
++ * really care about is the  source/destination unions */
++#define IP_CT_TUPLE_U_BLANK(tuple) 				\
++	do {							\
++		(tuple)->src.u.all = 0;				\
++		(tuple)->dst.u.all = 0;				\
++	} while (0)
++
+ enum ip_conntrack_dir
+ {
+ 	IP_CT_DIR_ORIGINAL,
+--- linux-2.6.0-test6/include/linux/netfilter_ipv4/ip_nat_rule.h	2003-06-14 12:18:33.000000000 -0700
++++ 25/include/linux/netfilter_ipv4/ip_nat_rule.h	2003-10-05 00:33:24.000000000 -0700
+@@ -14,5 +14,10 @@ extern int ip_nat_rule_find(struct sk_bu
+ 			    const struct net_device *out,
+ 			    struct ip_conntrack *ct,
+ 			    struct ip_nat_info *info);
++
++extern unsigned int
++alloc_null_binding(struct ip_conntrack *conntrack,
++		   struct ip_nat_info *info,
++		   unsigned int hooknum);
+ #endif
+ #endif /* _IP_NAT_RULE_H */
+--- linux-2.6.0-test6/include/linux/nfs_fs.h	2003-07-27 12:14:40.000000000 -0700
++++ 25/include/linux/nfs_fs.h	2003-10-05 00:36:42.000000000 -0700
+@@ -271,7 +271,7 @@ nfs_file_cred(struct file *file)
+ /*
+  * linux/fs/nfs/direct.c
+  */
+-extern int nfs_direct_IO(int, struct file *, const struct iovec *, loff_t,
++extern int nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
+ 			unsigned long);
+ 
+ /*
+--- linux-2.6.0-test6/include/linux/nfs_page.h	2003-06-26 22:07:26.000000000 -0700
++++ 25/include/linux/nfs_page.h	2003-10-05 00:36:43.000000000 -0700
+@@ -46,7 +46,6 @@ extern	struct nfs_page *nfs_create_reque
+ 					    unsigned int, unsigned int);
+ extern	void nfs_clear_request(struct nfs_page *req);
+ extern	void nfs_release_request(struct nfs_page *req);
+-extern	void nfs_release_list(struct list_head *list);
+ 
+ 
+ extern	void nfs_list_add_request(struct nfs_page *, struct list_head *);
+@@ -56,7 +55,6 @@ extern	int nfs_scan_list(struct list_hea
+ extern	int nfs_coalesce_requests(struct list_head *, struct list_head *,
+ 				  unsigned int);
+ extern  int nfs_wait_on_request(struct nfs_page *);
+-extern	int nfs_wait_for_reads(struct list_head *);
+ 
+ extern	spinlock_t nfs_wreq_lock;
+ 
+--- linux-2.6.0-test6/include/linux/nfs_xdr.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/nfs_xdr.h	2003-10-05 00:36:45.000000000 -0700
+@@ -591,6 +591,7 @@ struct nfs4_compound {
+ #endif /* CONFIG_NFS_V4 */
+ 
+ struct nfs_read_data {
++	int			flags;
+ 	struct rpc_task		task;
+ 	struct inode		*inode;
+ 	struct rpc_cred		*cred;
+@@ -605,6 +606,7 @@ struct nfs_read_data {
+ };
+ 
+ struct nfs_write_data {
++	int			flags;
+ 	struct rpc_task		task;
+ 	struct inode		*inode;
+ 	struct rpc_cred		*cred;
+@@ -634,16 +636,9 @@ struct nfs_rpc_ops {
+ 			    struct nfs_fh *, struct nfs_fattr *);
+ 	int	(*access)  (struct inode *, struct rpc_cred *, int);
+ 	int	(*readlink)(struct inode *, struct page *);
+-	int	(*read)    (struct inode *, struct rpc_cred *,
+-			    struct nfs_fattr *,
+-			    int, unsigned int, unsigned int,
+-			    struct page *, int *eofp);
+-	int	(*write)   (struct inode *, struct rpc_cred *,
+-			    struct nfs_fattr *,
+-			    int, unsigned int, unsigned int,
+-			    struct page *, struct nfs_writeverf *verfp);
+-	int	(*commit)  (struct inode *, struct nfs_fattr *,
+-			    unsigned long, unsigned int);
++	int	(*read)    (struct nfs_read_data *);
++	int	(*write)   (struct nfs_write_data *);
++	int	(*commit)  (struct nfs_write_data *);
+ 	int	(*create)  (struct inode *, struct qstr *, struct iattr *,
+ 			    int, struct nfs_fh *, struct nfs_fattr *);
+ 	int	(*remove)  (struct inode *, struct qstr *);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/numa.h	2003-10-05 00:34:41.000000000 -0700
+@@ -0,0 +1,16 @@
++#ifndef _LINUX_NUMA_H
++#define _LINUX_NUMA_H
++
++#include <linux/config.h>
++
++#ifdef CONFIG_DISCONTIGMEM
++#include <asm/numnodes.h>
++#endif
++
++#ifndef NODES_SHIFT
++#define NODES_SHIFT     0
++#endif
++
++#define MAX_NUMNODES    (1 << NODES_SHIFT)
++
++#endif /* _LINUX_NUMA_H */
+--- linux-2.6.0-test6/include/linux/pagemap.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/pagemap.h	2003-10-05 00:37:03.000000000 -0700
+@@ -71,7 +71,7 @@ extern struct page * find_trylock_page(s
+ extern struct page * find_or_create_page(struct address_space *mapping,
+ 				unsigned long index, unsigned int gfp_mask);
+ extern unsigned int find_get_pages(struct address_space *mapping,
+-				pgoff_t start, unsigned int nr_pages,
++				pgoff_t *next, unsigned int nr_pages,
+ 				struct page **pages);
+ 
+ /*
+@@ -153,17 +153,27 @@ static inline void ___add_to_page_cache(
+ extern void FASTCALL(__lock_page(struct page *page));
+ extern void FASTCALL(unlock_page(struct page *page));
+ 
+-static inline void lock_page(struct page *page)
++
++extern int FASTCALL(__lock_page_wq(struct page *page, wait_queue_t *wait));
++static inline int lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+ 	if (TestSetPageLocked(page))
+-		__lock_page(page);
++		return __lock_page_wq(page, wait);
++	else
++		return 0;
++}
++
++static inline void lock_page(struct page *page)
++{
++	lock_page_wq(page, NULL);
+ }
+ 	
+ /*
+  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
+  * Never use this directly!
+  */
+-extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr));
++extern int FASTCALL(wait_on_page_bit_wq(struct page *page, int bit_nr,
++	wait_queue_t *wait));
+ 
+ /* 
+  * Wait for a page to be unlocked.
+@@ -172,19 +182,33 @@ extern void FASTCALL(wait_on_page_bit(st
+  * ie with increased "page->count" so that the page won't
+  * go away during the wait..
+  */
+-static inline void wait_on_page_locked(struct page *page)
++static inline int wait_on_page_locked_wq(struct page *page, wait_queue_t *wait)
+ {
+ 	if (PageLocked(page))
+-		wait_on_page_bit(page, PG_locked);
++		return wait_on_page_bit_wq(page, PG_locked, wait);
++	return 0;
++}
++
++static inline int wait_on_page_writeback_wq(struct page *page,
++						wait_queue_t *wait)
++{
++	if (PageWriteback(page))
++		return wait_on_page_bit_wq(page, PG_writeback, wait);
++	return 0;
++}
++
++static inline void wait_on_page_locked(struct page *page)
++{
++	wait_on_page_locked_wq(page, NULL);
+ }
+ 
+ /* 
+  * Wait for a page to complete writeback
+  */
++
+ static inline void wait_on_page_writeback(struct page *page)
+ {
+-	if (PageWriteback(page))
+-		wait_on_page_bit(page, PG_writeback);
++	wait_on_page_writeback_wq(page, NULL);
+ }
+ 
+ extern void end_page_writeback(struct page *page);
+--- linux-2.6.0-test6/include/linux/pagevec.h	2003-06-14 12:18:51.000000000 -0700
++++ 25/include/linux/pagevec.h	2003-10-05 00:37:03.000000000 -0700
+@@ -23,7 +23,7 @@ void __pagevec_lru_add(struct pagevec *p
+ void __pagevec_lru_add_active(struct pagevec *pvec);
+ void pagevec_strip(struct pagevec *pvec);
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+-		pgoff_t start, unsigned int nr_pages);
++		pgoff_t *next, unsigned int nr_pages);
+ 
+ static inline void pagevec_init(struct pagevec *pvec, int cold)
+ {
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/parser.h	2003-10-05 00:33:24.000000000 -0700
+@@ -0,0 +1,21 @@
++struct match_token {
++	int token;
++	char *pattern;
++};
++
++typedef struct match_token match_table_t[];
++
++enum {MAX_OPT_ARGS = 3};
++
++typedef struct {
++	char *from;
++	char *to;
++} substring_t;
++
++int match_token(char *s, match_table_t table, substring_t args[]);
++
++int match_int(substring_t *, int *result);
++int match_octal(substring_t *, int *result);
++int match_hex(substring_t *, int *result);
++void match_strcpy(char *, substring_t *);
++char *match_strdup(substring_t *);
+--- linux-2.6.0-test6/include/linux/pci.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/pci.h	2003-10-05 00:36:20.000000000 -0700
+@@ -36,6 +36,7 @@
+ #define  PCI_COMMAND_WAIT 	0x80	/* Enable address/data stepping */
+ #define  PCI_COMMAND_SERR	0x100	/* Enable SERR */
+ #define  PCI_COMMAND_FAST_BACK	0x200	/* Enable back-to-back writes */
++#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+ 
+ #define PCI_STATUS		0x06	/* 16 bits */
+ #define  PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
+@@ -198,6 +199,8 @@
+ #define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
+ #define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
+ #define  PCI_CAP_ID_PCIX	0x07	/* PCI-X */
++#define  PCI_CAP_ID_EXP 	0x10	/* PCI Express */
++#define  PCI_CAP_ID_MSIX	0x11	/* MSI-X */
+ #define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
+ #define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
+ #define PCI_CAP_SIZEOF		4
+@@ -275,11 +278,13 @@
+ #define  PCI_MSI_FLAGS_QSIZE	0x70	/* Message queue size configured */
+ #define  PCI_MSI_FLAGS_QMASK	0x0e	/* Maximum queue size available */
+ #define  PCI_MSI_FLAGS_ENABLE	0x01	/* MSI feature enabled */
++#define  PCI_MSI_FLAGS_MASKBIT	0x100	/* 64-bit mask bits allowed */
+ #define PCI_MSI_RFU		3	/* Rest of capability flags */
+ #define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
+ #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+ #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
+ #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
++#define PCI_MSI_MASK_BIT	16	/* Mask bits register */
+ 
+ /* CompactPCI Hotswap Register */
+ 
+@@ -515,7 +520,6 @@ struct pci_driver {
+ 	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
+ 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
+ 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+-	int  (*save_state) (struct pci_dev *dev, u32 state);    /* Save Device Context */
+ 	int  (*suspend) (struct pci_dev *dev, u32 state);	/* Device suspended */
+ 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
+ 	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
+@@ -696,6 +700,18 @@ void pci_pool_free (struct pci_pool *poo
+ extern struct pci_dev *isa_bridge;
+ #endif
+ 
++#ifndef CONFIG_PCI_USE_VECTOR
++static inline void pci_scan_msi_device(struct pci_dev *dev) {}
++static inline int pci_enable_msi(struct pci_dev *dev) {return -1;}
++static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
++#else
++extern void pci_scan_msi_device(struct pci_dev *dev);
++extern int pci_enable_msi(struct pci_dev *dev);
++extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
++extern int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec);
++extern int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec);
++#endif
++
+ #endif /* CONFIG_PCI */
+ 
+ /* Include architecture-dependent settings and functions */
+--- linux-2.6.0-test6/include/linux/pci_ids.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/pci_ids.h	2003-10-05 00:36:28.000000000 -0700
+@@ -519,6 +519,7 @@
+ #define PCI_DEVICE_ID_CT_65550		0x00e0
+ #define PCI_DEVICE_ID_CT_65554		0x00e4
+ #define PCI_DEVICE_ID_CT_65555		0x00e5
++#define PCI_DEVICE_ID_CT_69000		0x00c0
+ 
+ #define PCI_VENDOR_ID_MIRO		0x1031
+ #define PCI_DEVICE_ID_MIRO_36050	0x5601
+@@ -896,6 +897,7 @@
+ 
+ #define PCI_VENDOR_ID_SGI		0x10a9
+ #define PCI_DEVICE_ID_SGI_IOC3		0x0003
++#define PCI_DEVICE_ID_SGI_IOC4		0x100a
+ #define PCI_VENDOR_ID_SGI_LITHIUM	0x1002
+ 
+ #define PCI_VENDOR_ID_ACC		0x10aa
+@@ -1060,6 +1062,16 @@
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
+ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800	0x0280
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280	0x0281
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE 0x0282
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO	0x0286
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U	0x0301
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800	0x0302
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U	0x0311
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600	0x0312
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U	0x0321
++#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200	0x0322
+ 
+ #define PCI_VENDOR_ID_IMS		0x10e0
+ #define PCI_DEVICE_ID_IMS_8849		0x8849
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/pci_msi.h	2003-10-05 00:36:20.000000000 -0700
+@@ -0,0 +1,193 @@
++/*
++ *	../include/linux/pci_msi.h
++ *
++ */
++
++#ifndef _ASM_PCI_MSI_H
++#define _ASM_PCI_MSI_H
++
++#include <linux/pci.h>
++
++#define MSI_AUTO -1
++#define NR_REPEATS	23
++#define NR_RESERVED_VECTORS 3 /*FIRST_DEVICE_VECTOR,FIRST_SYSTEM_VECTOR,0x80 */
++
++/*
++ * Assume the maximum number of hot plug slots supported by the system is about
++ * ten. The worstcase is that each of these slots is hot-added with a device,
++ * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
++ * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
++ * as below to ensure at least one message is assigned to each detected MSI/
++ * MSI-X device function.
++ */
++#define NR_HP_RESERVED_VECTORS 	20
++
++extern int vector_irq[NR_IRQS];
++extern cpumask_t pending_irq_balance_cpumask[NR_IRQS];
++extern void (*interrupt[NR_IRQS])(void);
++
++#ifdef CONFIG_SMP
++#define set_msi_irq_affinity	set_msi_affinity
++#else
++#define set_msi_irq_affinity	NULL
++static inline void move_msi(int vector) {}
++#endif
++
++#ifndef CONFIG_X86_IO_APIC
++static inline int get_ioapic_vector(struct pci_dev *dev) { return -1;}
++static inline void restore_ioapic_irq_handler(int irq) {}
++#else
++extern void restore_ioapic_irq_handler(int irq);
++#endif
++
++/*
++ * MSI-X Address Register
++ */
++#define PCI_MSIX_FLAGS_QSIZE		0x7FF
++#define PCI_MSIX_FLAGS_ENABLE		(1 << 15)
++#define PCI_MSIX_FLAGS_BIRMASK		(7 << 0)
++#define PCI_MSIX_FLAGS_BITMASK		(1 << 0)
++
++#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET	0
++#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET	4
++#define PCI_MSIX_ENTRY_DATA_OFFSET		8
++#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET	12
++#define PCI_MSIX_ENTRY_SIZE			16
++
++#define msi_control_reg(base)		(base + PCI_MSI_FLAGS)
++#define msi_lower_address_reg(base)	(base + PCI_MSI_ADDRESS_LO)
++#define msi_upper_address_reg(base)	(base + PCI_MSI_ADDRESS_HI)
++#define msi_data_reg(base, is64bit)	\
++	( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
++#define msi_mask_bits_reg(base, is64bit) \
++	( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
++#define msi_disable(control)		control &= ~PCI_MSI_FLAGS_ENABLE
++#define multi_msi_capable(control) \
++	(1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
++#define multi_msi_enable(control, num) \
++	control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
++#define is_64bit_address(control)	(control & PCI_MSI_FLAGS_64BIT)
++#define is_mask_bit_support(control)	(control & PCI_MSI_FLAGS_MASKBIT)
++#define msi_enable(control, num) multi_msi_enable(control, num); \
++	control |= PCI_MSI_FLAGS_ENABLE
++
++#define msix_control_reg		msi_control_reg
++#define msix_table_offset_reg(base)	(base + 0x04)
++#define msix_pba_offset_reg(base)	(base + 0x08)
++#define msix_enable(control)	 	control |= PCI_MSIX_FLAGS_ENABLE
++#define msix_disable(control)	 	control &= ~PCI_MSIX_FLAGS_ENABLE
++#define msix_table_size(control) 	((control & PCI_MSIX_FLAGS_QSIZE)+1)
++#define multi_msix_capable		msix_table_size
++#define msix_unmask(address)	 	(address & ~PCI_MSIX_FLAGS_BITMASK)
++#define msix_mask(address)		(address | PCI_MSIX_FLAGS_BITMASK)
++#define msix_is_pending(address) 	(address & PCI_MSIX_FLAGS_PENDMASK)
++
++extern char __dbg_str_buf[256];
++#define _DEFINE_DBG_BUFFER	char __dbg_str_buf[256];
++#define _DBG_K_TRACE_ENTRY	((unsigned int)0x00000001)
++#define _DBG_K_TRACE_EXIT	((unsigned int)0x00000002)
++#define _DBG_K_INFO		((unsigned int)0x00000004)
++#define _DBG_K_ERROR		((unsigned int)0x00000008)
++#define _DBG_K_TRACE	(_DBG_K_TRACE_ENTRY | _DBG_K_TRACE_EXIT)
++
++#define _DEBUG_LEVEL	(_DBG_K_INFO | _DBG_K_ERROR | _DBG_K_TRACE)
++#define _DBG_PRINT( dbg_flags, args... )		\
++if ( _DEBUG_LEVEL & (dbg_flags) )			\
++{							\
++	int len;					\
++	len = sprintf(__dbg_str_buf, "%s:%d: %s ", 	\
++		__FILE__, __LINE__, __FUNCTION__ ); 	\
++	sprintf(__dbg_str_buf + len, args);		\
++	printk(KERN_INFO "%s\n", __dbg_str_buf);	\
++}
++
++#define MSI_FUNCTION_TRACE_ENTER	\
++	_DBG_PRINT (_DBG_K_TRACE_ENTRY, "%s", "[Entry]");
++#define MSI_FUNCTION_TRACE_EXIT		\
++	_DBG_PRINT (_DBG_K_TRACE_EXIT, "%s", "[Entry]");
++
++/*
++ * MSI Defined Data Structures
++ */
++#define MSI_ADDRESS_HEADER		0xfee
++#define MSI_ADDRESS_HEADER_SHIFT	12
++#define MSI_ADDRESS_HEADER_MASK		0xfff000
++#define MSI_TARGET_CPU_SHIFT		4
++#define MSI_TARGET_CPU_MASK		0xff
++#define MSI_DELIVERY_MODE		0
++#define MSI_LEVEL_MODE			1	/* Edge always assert */
++#define MSI_TRIGGER_MODE		0	/* MSI is edge sensitive */
++#define MSI_LOGICAL_MODE		1
++#define MSI_REDIRECTION_HINT_MODE	0
++#ifdef CONFIG_SMP
++#define MSI_TARGET_CPU			logical_smp_processor_id()
++#else
++#define MSI_TARGET_CPU			TARGET_CPUS
++#endif
++
++struct msg_data {
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++	__u32	vector		:  8;
++	__u32	delivery_mode	:  3;	/* 000b: FIXED | 001b: lowest prior */
++	__u32	reserved_1	:  3;
++	__u32	level		:  1;	/* 0: deassert | 1: assert */
++	__u32	trigger		:  1;	/* 0: edge | 1: level */
++	__u32	reserved_2	: 16;
++#elif defined(__BIG_ENDIAN_BITFIELD)
++	__u32	reserved_2	: 16;
++	__u32	trigger		:  1;	/* 0: edge | 1: level */
++	__u32	level		:  1;	/* 0: deassert | 1: assert */
++	__u32	reserved_1	:  3;
++	__u32	delivery_mode	:  3;	/* 000b: FIXED | 001b: lowest prior */
++	__u32	vector		:  8;
++#else
++#error "Bitfield endianness not defined! Check your byteorder.h"
++#endif
++} __attribute__ ((packed));
++
++struct msg_address {
++	union {
++		struct {
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++			__u32	reserved_1	:  2;
++			__u32	dest_mode	:  1;	/*0:physic | 1:logic */
++			__u32	redirection_hint:  1;  	/*0: dedicated CPU
++							  1: lowest priority */
++			__u32	reserved_2	:  4;
++ 			__u32	dest_id		: 24;	/* Destination ID */
++#elif defined(__BIG_ENDIAN_BITFIELD)
++ 			__u32	dest_id		: 24;	/* Destination ID */
++			__u32	reserved_2	:  4;
++			__u32	redirection_hint:  1;  	/*0: dedicated CPU
++							  1: lowest priority */
++			__u32	dest_mode	:  1;	/*0:physic | 1:logic */
++			__u32	reserved_1	:  2;
++#else
++#error "Bitfield endianness not defined! Check your byteorder.h"
++#endif
++      		}u;
++       		__u32  value;
++	}lo_address;
++	__u32 	hi_address;
++} __attribute__ ((packed));
++
++struct msi_desc {
++	struct {
++		__u8	type	: 5; 	/* {0: unused, 5h:MSI, 11h:MSI-X} */
++		__u8	maskbit	: 1; 	/* mask-pending bit supported ?   */
++		__u8	reserved: 2; 	/* reserved			  */
++		__u8	entry_nr;    	/* specific enabled entry 	  */
++		__u8	default_vector; /* default pre-assigned vector    */
++		__u8	current_cpu; 	/* current destination cpu	  */
++	}msi_attrib;
++
++	struct {
++		__u16	head;
++		__u16	tail;
++	}link;
++
++	unsigned long mask_base;
++	struct pci_dev *dev;
++};
++
++#endif /* _ASM_PCI_MSI_H */
+--- linux-2.6.0-test6/include/linux/raw.h	2003-06-14 12:18:25.000000000 -0700
++++ 25/include/linux/raw.h	2003-10-05 00:33:24.000000000 -0700
+@@ -13,4 +13,6 @@ struct raw_config_request 
+ 	__u64	block_minor;
+ };
+ 
++#define MAX_RAW_MINORS CONFIG_MAX_RAW_DEVS
++
+ #endif /* __LINUX_RAW_H */
+--- linux-2.6.0-test6/include/linux/rcupdate.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/rcupdate.h	2003-10-05 00:33:24.000000000 -0700
+@@ -15,7 +15,7 @@
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  *
+- * Copyright (c) IBM Corporation, 2001
++ * Copyright (C) IBM Corporation, 2001
+  *
+  * Author: Dipankar Sarma <dipankar@in.ibm.com>
+  * 
+--- linux-2.6.0-test6/include/linux/sched.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/sched.h	2003-10-05 00:36:54.000000000 -0700
+@@ -151,6 +151,7 @@ extern void init_idle(task_t *idle, int 
+ 
+ extern void show_state(void);
+ extern void show_regs(struct pt_regs *);
++extern void show_trace_task(task_t *tsk);
+ 
+ /*
+  * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+@@ -207,6 +208,8 @@ struct mm_struct {
+ 	cpumask_t cpu_vm_mask;
+ 	unsigned long swap_address;
+ 
++	unsigned long saved_auxv[40]; /* for /proc/PID/auxv */
++
+ 	unsigned dumpable:1;
+ #ifdef CONFIG_HUGETLB_PAGE
+ 	int used_hugetlb;
+@@ -262,6 +265,15 @@ struct signal_struct {
+ 
+ 	/* thread group stop support, overloads group_exit_code too */
+ 	int			group_stop_count;
++
++	/* job control IDs */
++	pid_t pgrp;
++	pid_t tty_old_pgrp;
++	pid_t session;
++	/* boolean value for session group leader */
++	int leader;
++
++	struct tty_struct *tty; /* NULL if no tty */
+ };
+ 
+ /*
+@@ -364,12 +376,7 @@ struct task_struct {
+ 	unsigned long personality;
+ 	int did_exec:1;
+ 	pid_t pid;
+-	pid_t __pgrp;		/* Accessed via process_group() */
+-	pid_t tty_old_pgrp;
+-	pid_t session;
+ 	pid_t tgid;
+-	/* boolean value for session group leader */
+-	int leader;
+ 	/* 
+ 	 * pointers to (original) parent process, youngest child, younger sibling,
+ 	 * older sibling, respectively.  (p->father can be replaced with 
+@@ -413,7 +420,6 @@ struct task_struct {
+ 	char comm[16];
+ /* file system info */
+ 	int link_count, total_link_count;
+-	struct tty_struct *tty; /* NULL if no tty */
+ 	unsigned int locks; /* How many file locks are being held */
+ /* ipc stuff */
+ 	struct sysv_sem sysvsem;
+@@ -463,11 +469,33 @@ struct task_struct {
+ 
+ 	unsigned long ptrace_message;
+ 	siginfo_t *last_siginfo; /* For ptrace use.  */
++/*
++ * current io wait handle: wait queue entry to use for io waits
++ * If this thread is processing aio, this points at the waitqueue
++ * inside the currently handled kiocb. It may be NULL (i.e. default
++ * to a stack based synchronous wait) if its doing sync IO.
++ */
++	wait_queue_t *io_wait;
+ };
+ 
+ static inline pid_t process_group(struct task_struct *tsk)
+ {
+-	return tsk->group_leader->__pgrp;
++	return tsk->signal->pgrp;
++}
++
++static inline pid_t process_session(struct task_struct *tsk)
++{
++	return tsk->signal->session;
++}
++
++static inline int process_session_leader(struct task_struct *tsk)
++{
++	return tsk->signal->leader;
++}
++
++static inline struct tty_struct *process_tty(struct task_struct *tsk)
++{
++	return tsk->signal->tty;
+ }
+ 
+ extern void __put_task_struct(struct task_struct *tsk);
+--- linux-2.6.0-test6/include/linux/sctp.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/sctp.h	2003-10-05 00:33:24.000000000 -0700
+@@ -524,113 +524,4 @@ typedef struct sctp_addip_chunk {
+ 	sctp_addiphdr_t addip_hdr;
+ } sctp_addip_chunk_t __attribute__((packed));
+ 
+-/* FIXME:  Cleanup needs to continue below this line. */
+-
+-
+-/* ADDIP Section 3.1.1
+- *
+- * ASCONF-Request Correlation ID: 32 bits (unsigned integer)
+- *
+- * This is an opaque integer assigned by the sender to identify each
+- * request parameter. It is in host byte order and is only meaningful
+- * to the sender. The receiver of the ASCONF Chunk will copy this 32
+- * bit value into the ASCONF Correlation ID field of the
+- * ASCONF-ACK. The sender of the ASCONF can use this same value in the
+- * ASCONF-ACK to find which request the response is for.
+- *
+- * ASCONF Parameter: TLV format
+- *
+- * Each Address configuration change is represented by a TLV parameter
+- * as defined in Section 3.2. One or more requests may be present in
+- * an ASCONF Chunk.
+- */
+-typedef struct {
+-	__u32	correlation;
+-	sctp_paramhdr_t p;
+-	__u8		payload[0];
+-} sctpAsconfReq_t;
+-
+-/* ADDIP
+- * 3.1.1  Address/Stream Configuration Change Chunk (ASCONF)
+- *
+- * This chunk is used to communicate to the remote endpoint one of the
+- * configuration change requests that MUST be acknowledged.  The
+- * information carried in the ASCONF Chunk uses the form of a
+- * Tag-Length-Value (TLV), as described in "3.2.1
+- * Optional/Variable-length Parameter Format" in [RFC2960], for all
+- * variable parameters.
+- */
+-typedef struct {
+-	__u32	serial;
+-	__u8	reserved[3];
+-	__u8	addr_type;
+-	__u32	addr[4];
+-	sctpAsconfReq_t requests[0];
+-} sctpAsconf_t;
+-
+-/* ADDIP
+- * 3.1.2 Address/Stream Configuration Acknowledgment Chunk (ASCONF-ACK)
+- *
+- * ASCONF-Request Correlation ID: 32 bits (unsigned integer)
+- *
+- * This value is copied from the ASCONF Correlation ID received in the
+- * ASCONF Chunk. It is used by the receiver of the ASCONF-ACK to identify
+- * which ASCONF parameter this response is associated with.
+- *
+- * ASCONF Parameter Response : TLV format
+- *
+- * The ASCONF Parameter Response is used in the ASCONF-ACK to report
+- * status of ASCONF processing. By default, if a responding endpoint
+- * does not include any Error Cause, a success is indicated. Thus a
+- * sender of an ASCONF-ACK MAY indicate complete success of all TLVs in
+- * an ASCONF by returning only the Chunk Type, Chunk Flags, Chunk Length
+- * (set to 8) and the Serial Number.
+- */
+-typedef union {
+-	struct {
+-		__u32		correlation;
+-		sctp_paramhdr_t header;	/* success report */
+-	} success;
+-	struct {
+-		__u32		correlation;
+-		sctp_paramhdr_t header;	/* error cause indication */
+-		sctp_paramhdr_t errcause;
+-		uint8_t request[0];	/* original request from ASCONF */
+-	} error;
+-#define __correlation	success.correlation
+-#define __header	success.header
+-#define __cause		error.errcause
+-#define __request	error.request
+-}  sctpAsconfAckRsp_t;
+-
+-/* ADDIP
+- * 3.1.2 Address/Stream Configuration Acknowledgment Chunk (ASCONF-ACK)
+- *
+- * This chunk is used by the receiver of an ASCONF Chunk to
+- * acknowledge the reception. It carries zero or more results for any
+- * ASCONF Parameters that were processed by the receiver.
+- */
+-typedef struct {
+-	__u32	serial;
+-	sctpAsconfAckRsp_t responses[0];
+-} sctpAsconfAck_t;
+-
+-/*********************************************************************
+- * Internal structures
+- *
+- * These are data structures which never go out on the wire.
+- *********************************************************************/
+-
+-/* What is this data structure for?  The TLV isn't one--it is just a
+- * value.  Perhaps this data structure ought to have a type--otherwise
+- * it is not unambigiously parseable.  --piggy
+- */
+-typedef struct {
+-	struct list_head hook;
+-	int length;	/* length of the TLV */
+-
+-	/* the actually TLV to be copied into ASCONF_ACK */
+-	sctpAsconfAckRsp_t TLV;
+-} sctpAsconfAckRspNode_t;
+-
+ #endif /* __LINUX_SCTP_H__ */
+--- linux-2.6.0-test6/include/linux/security.h	2003-07-10 18:50:32.000000000 -0700
++++ 25/include/linux/security.h	2003-10-05 00:33:24.000000000 -0700
+@@ -334,6 +334,7 @@ struct swap_info_struct;
+  *	called when the actual read/write operations are performed.
+  *	@inode contains the inode structure to check.
+  *	@mask contains the permission mask.
++ *     @nd contains the nameidata (may be NULL).
+  *	Return 0 if permission is granted.
+  * @inode_setattr:
+  *	Check permission before setting file attributes.  Note that the kernel
+@@ -1055,7 +1056,7 @@ struct security_operations {
+ 	                           struct dentry *new_dentry);
+ 	int (*inode_readlink) (struct dentry *dentry);
+ 	int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
+-	int (*inode_permission) (struct inode *inode, int mask);
++	int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
+ 	int (*inode_setattr)	(struct dentry *dentry, struct iattr *attr);
+ 	int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
+         void (*inode_delete) (struct inode *inode);
+@@ -1474,9 +1475,10 @@ static inline int security_inode_follow_
+ 	return security_ops->inode_follow_link (dentry, nd);
+ }
+ 
+-static inline int security_inode_permission (struct inode *inode, int mask)
++static inline int security_inode_permission (struct inode *inode, int mask,
++					     struct nameidata *nd)
+ {
+-	return security_ops->inode_permission (inode, mask);
++	return security_ops->inode_permission (inode, mask, nd);
+ }
+ 
+ static inline int security_inode_setattr (struct dentry *dentry,
+@@ -2110,7 +2112,8 @@ static inline int security_inode_follow_
+ 	return 0;
+ }
+ 
+-static inline int security_inode_permission (struct inode *inode, int mask)
++static inline int security_inode_permission (struct inode *inode, int mask,
++					     struct nameidata *nd)
+ {
+ 	return 0;
+ }
+--- linux-2.6.0-test6/include/linux/serial_core.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/serial_core.h	2003-10-05 00:33:38.000000000 -0700
+@@ -158,7 +158,9 @@ struct uart_port {
+ 	unsigned char		x_char;			/* xon/xoff char */
+ 	unsigned char		regshift;		/* reg offset shift */
+ 	unsigned char		iotype;			/* io access style */
+-
++#ifdef CONFIG_KGDB
++	int			kgdb;			/* in use by kgdb */
++#endif
+ #define UPIO_PORT		(0)
+ #define UPIO_HUB6		(1)
+ #define UPIO_MEM		(2)
+--- linux-2.6.0-test6/include/linux/serialP.h	2003-06-14 12:17:57.000000000 -0700
++++ 25/include/linux/serialP.h	2003-10-05 00:33:25.000000000 -0700
+@@ -19,6 +19,7 @@
+  * For definitions of the flags field, see tty.h
+  */
+ 
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/termios.h>
+ #include <linux/workqueue.h>
+--- linux-2.6.0-test6/include/linux/serio.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/serio.h	2003-10-05 00:34:15.000000000 -0700
+@@ -53,6 +53,7 @@ struct serio_dev {
+ 	irqreturn_t (*interrupt)(struct serio *, unsigned char,
+ 			unsigned int, struct pt_regs *);
+ 	void (*connect)(struct serio *, struct serio_dev *dev);
++	int  (*reconnect)(struct serio *);
+ 	void (*disconnect)(struct serio *);
+ 	void (*cleanup)(struct serio *);
+ 
+@@ -62,12 +63,13 @@ struct serio_dev {
+ int serio_open(struct serio *serio, struct serio_dev *dev);
+ void serio_close(struct serio *serio);
+ void serio_rescan(struct serio *serio);
++void serio_reconnect(struct serio *serio);
+ irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
+ 
+ void serio_register_port(struct serio *serio);
+-void serio_register_slave_port(struct serio *serio);
++void __serio_register_port(struct serio *serio);
+ void serio_unregister_port(struct serio *serio);
+-void serio_unregister_slave_port(struct serio *serio);
++void __serio_unregister_port(struct serio *serio);
+ void serio_register_device(struct serio_dev *dev);
+ void serio_unregister_device(struct serio_dev *dev);
+ 
+--- linux-2.6.0-test6/include/linux/skbuff.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/skbuff.h	2003-10-05 00:36:10.000000000 -0700
+@@ -152,6 +152,7 @@ struct skb_shared_info {
+  *	@sk: Socket we are owned by
+  *	@stamp: Time we arrived
+  *	@dev: Device we arrived on/are leaving by
++ *      @real_dev: The real device we are using
+  *	@h: Transport layer header
+  *	@nh: Network layer header
+  *	@mac: Link layer header
+@@ -179,6 +180,7 @@ struct skb_shared_info {
+  *	@nfct: Associated connection, if any
+  *	@nf_debug: Netfilter debugging
+  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
++ *      @private: Data which is private to the HIPPI implementation
+  *	@tc_index: Traffic control index
+  */
+ 
+@@ -885,7 +887,7 @@ static inline char *__skb_pull(struct sk
+  */
+ static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
+ {
+-	return (len > skb->len) ? NULL : __skb_pull(skb, len);
++	return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
+ }
+ 
+ extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta);
+@@ -901,7 +903,7 @@ static inline char *__pskb_pull(struct s
+ 
+ static inline unsigned char *pskb_pull(struct sk_buff *skb, unsigned int len)
+ {
+-	return (len > skb->len) ? NULL : __pskb_pull(skb, len);
++	return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len);
+ }
+ 
+ static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
+@@ -1052,7 +1054,7 @@ static inline struct sk_buff *__dev_allo
+ 					      int gfp_mask)
+ {
+ 	struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
+-	if (skb)
++	if (likely(skb))
+ 		skb_reserve(skb, 16);
+ 	return skb;
+ }
+--- linux-2.6.0-test6/include/linux/spinlock.h	2003-07-02 14:53:18.000000000 -0700
++++ 25/include/linux/spinlock.h	2003-10-05 00:36:40.000000000 -0700
+@@ -15,6 +15,12 @@
+ 
+ #include <asm/processor.h>	/* for cpu relax */
+ #include <asm/system.h>
++#ifdef CONFIG_KGDB
++#include <asm/current.h>
++#define SET_WHO(x, him) (x)->who = him;
++#else
++#define SET_WHO(x, him)
++#endif
+ 
+ /*
+  * Must define these before including other files, inline functions need them
+@@ -55,6 +61,9 @@ typedef struct {
+ 	const char *module;
+ 	char *owner;
+ 	int oline;
++#ifdef CONFIG_KGDB
++	struct task_struct *who;
++#endif
+ } spinlock_t;
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0}
+ 
+@@ -66,6 +75,7 @@ typedef struct {
+ 		(x)->module = __FILE__; \
+ 		(x)->owner = NULL; \
+ 		(x)->oline = 0; \
++                SET_WHO(x, NULL) \
+ 	} while (0)
+ 
+ #define CHECK_LOCK(x) \
+@@ -88,6 +98,7 @@ typedef struct {
+ 		(x)->lock = 1; \
+ 		(x)->owner = __FILE__; \
+ 		(x)->oline = __LINE__; \
++                SET_WHO(x, current)       \
+ 	} while (0)
+ 
+ /* without debugging, spin_is_locked on UP always says
+@@ -118,6 +129,7 @@ typedef struct {
+ 		(x)->lock = 1; \
+ 		(x)->owner = __FILE__; \
+ 		(x)->oline = __LINE__; \
++                SET_WHO(x, current)       \
+ 		1; \
+ 	})
+ 
+@@ -184,6 +196,17 @@ typedef struct {
+ 
+ #endif /* !SMP */
+ 
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock   (spinlock_t *lock);
++extern void _metered_spin_unlock (spinlock_t *lock);
++extern int  _metered_spin_trylock(spinlock_t *lock);
++extern void _metered_read_lock    (rwlock_t *lock);
++extern void _metered_read_unlock  (rwlock_t *lock);
++extern void _metered_write_lock   (rwlock_t *lock);
++extern void _metered_write_unlock (rwlock_t *lock);
++extern int  _metered_write_trylock(rwlock_t *lock);
++#endif
++
+ /*
+  * Define the various spin_lock and rw_lock methods.  Note we define these
+  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
+@@ -389,6 +412,141 @@ do { \
+ 				_raw_spin_trylock(lock) ? 1 : \
+ 				({preempt_enable(); local_bh_enable(); 0;});})
+ 
++#ifdef CONFIG_LOCKMETER
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#undef spin_lock_irqsave
++#undef spin_lock_irq
++#undef spin_lock_bh
++#undef read_lock
++#undef read_unlock
++#undef write_lock
++#undef write_unlock
++#undef write_trylock
++#undef spin_unlock_bh
++#undef read_lock_irqsave
++#undef read_lock_irq
++#undef read_lock_bh
++#undef read_unlock_bh
++#undef write_lock_irqsave
++#undef write_lock_irq
++#undef write_lock_bh
++#undef write_unlock_bh
++
++#define spin_lock(lock) \
++do { \
++	preempt_disable(); \
++	_metered_spin_lock(lock); \
++} while(0)
++
++#define spin_trylock(lock)     ({preempt_disable(); _metered_spin_trylock(lock) ? \
++				1 : ({preempt_enable(); 0;});})
++#define spin_unlock(lock) \
++do { \
++	_metered_spin_unlock(lock); \
++	preempt_enable(); \
++} while (0)
++
++#define spin_lock_irqsave(lock, flags) \
++do { \
++	local_irq_save(flags); \
++	preempt_disable(); \
++	_metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_irq(lock) \
++do { \
++	local_irq_disable(); \
++	preempt_disable(); \
++	_metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_bh(lock) \
++do { \
++	local_bh_disable(); \
++	preempt_disable(); \
++	_metered_spin_lock(lock); \
++} while (0)
++
++#define spin_unlock_bh(lock) \
++do { \
++	_metered_spin_unlock(lock); \
++	preempt_enable(); \
++	local_bh_enable(); \
++} while (0)
++
++
++#define read_lock(lock)                ({preempt_disable(); _metered_read_lock(lock);})
++#define read_unlock(lock)      ({_metered_read_unlock(lock); preempt_enable();})
++#define write_lock(lock)       ({preempt_disable(); _metered_write_lock(lock);})
++#define write_unlock(lock)     ({_metered_write_unlock(lock); preempt_enable();})
++#define write_trylock(lock)    ({preempt_disable();_metered_write_trylock(lock) ? \
++				1 : ({preempt_enable(); 0;});})
++#define spin_unlock_no_resched(lock) \
++do { \
++	_metered_spin_unlock(lock); \
++	preempt_enable_no_resched(); \
++} while (0)
++
++#define read_lock_irqsave(lock, flags) \
++do { \
++	local_irq_save(flags); \
++	preempt_disable(); \
++	_metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_irq(lock) \
++do { \
++	local_irq_disable(); \
++	preempt_disable(); \
++	_metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_bh(lock) \
++do { \
++	local_bh_disable(); \
++	preempt_disable(); \
++	_metered_read_lock(lock); \
++} while (0)
++
++#define read_unlock_bh(lock) \
++do { \
++	_metered_read_unlock(lock); \
++	preempt_enable(); \
++	local_bh_enable(); \
++} while (0)
++
++#define write_lock_irqsave(lock, flags) \
++do { \
++	local_irq_save(flags); \
++	preempt_disable(); \
++	_metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_irq(lock) \
++do { \
++	local_irq_disable(); \
++	preempt_disable(); \
++	_metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_bh(lock) \
++do { \
++	local_bh_disable(); \
++	preempt_disable(); \
++	_metered_write_lock(lock); \
++} while (0)
++
++#define write_unlock_bh(lock) \
++do { \
++	_metered_write_unlock(lock); \
++	preempt_enable(); \
++	local_bh_enable(); \
++} while (0)
++
++#endif /* !CONFIG_LOCKMETER */
++
+ /* "lock on reference count zero" */
+ #ifndef ATOMIC_DEC_AND_LOCK
+ #include <asm/atomic.h>
+--- linux-2.6.0-test6/include/linux/stallion.h	2003-06-14 12:18:32.000000000 -0700
++++ 25/include/linux/stallion.h	2003-10-05 00:33:25.000000000 -0700
+@@ -21,6 +21,8 @@
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
++#include <linux/version.h>
++
+ /*****************************************************************************/
+ #ifndef	_STALLION_H
+ #define	_STALLION_H
+--- linux-2.6.0-test6/include/linux/sysctl.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/sysctl.h	2003-10-05 00:33:25.000000000 -0700
+@@ -244,6 +244,7 @@ enum
+ 	NET_IPV4_NEIGH=17,
+ 	NET_IPV4_ROUTE=18,
+ 	NET_IPV4_FIB_HASH=19,
++	NET_IPV4_NETFILTER=20,
+ 
+ 	NET_IPV4_TCP_TIMESTAMPS=33,
+ 	NET_IPV4_TCP_WINDOW_SCALING=34,
+@@ -358,6 +359,24 @@ enum
+ 	NET_IPV4_CONF_NOPOLICY=16,
+ };
+ 
++/* /proc/sys/net/ipv4/netfilter */
++enum
++{
++	NET_IPV4_NF_CONNTRACK_MAX=1,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
++	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
++	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
++	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
++	NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
++	NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
++};
++ 
+ /* /proc/sys/net/ipv6 */
+ enum {
+ 	NET_IPV6_CONF=16,
+--- linux-2.6.0-test6/include/linux/toshiba.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/toshiba.h	2003-10-05 00:33:25.000000000 -0700
+@@ -33,4 +33,13 @@ typedef struct {
+ 	unsigned int edi __attribute__ ((packed));
+ } SMMRegisters;
+ 
++#ifdef CONFIG_PROC_FS
++static int tosh_get_info(char *, char **, off_t, int);
++#else /* !CONFIG_PROC_FS */
++inline int tosh_get_info(char *buffer, char **start, off_t fpos, int lenght)
++{
++	return 0;
++}
++#endif /* CONFIG_PROC_FS */
++
+ #endif
+--- linux-2.6.0-test6/include/linux/usb.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/usb.h	2003-10-05 00:33:25.000000000 -0700
+@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *
+ #define dbg(format, arg...) do {} while (0)
+ #endif
+ 
+-#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
+-#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg)
+-#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg)
++#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
++#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
++#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
+ 
+ 
+ #endif  /* __KERNEL__ */
+--- linux-2.6.0-test6/include/linux/wait.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/wait.h	2003-10-05 00:36:54.000000000 -0700
+@@ -80,6 +80,15 @@ static inline int waitqueue_active(wait_
+ 	return !list_empty(&q->task_list);
+ }
+ 
++/*
++ * Used to distinguish between sync and async io wait context:
++ * sync i/o typically specifies a NULL wait queue entry or a wait
++ * queue entry bound to a task (current task) to wake up.
++ * aio specifies a wait queue entry with an async notification
++ * callback routine, not associated with any task.
++ */
++#define is_sync_wait(wait)	(!(wait) || ((wait)->task))
++
+ extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
+ extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
+ extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
+--- linux-2.6.0-test6/include/linux/writeback.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/writeback.h	2003-10-05 00:37:01.000000000 -0700
+@@ -84,9 +84,13 @@ int dirty_writeback_centisecs_handler(st
+ 				      void __user *, size_t *);
+ 
+ void page_writeback_init(void);
+-void balance_dirty_pages_ratelimited(struct address_space *mapping);
++int balance_dirty_pages_ratelimited(struct address_space *mapping);
+ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+ int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++			loff_t pos, size_t count);
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++		*mapping, loff_t pos, size_t count);
+ 
+ /* pdflush.c */
+ extern int nr_pdflush_threads;	/* Global so it can be exported to sysctl
+--- linux-2.6.0-test6/include/net/irda/irda_device.h	2003-08-22 19:23:42.000000000 -0700
++++ 25/include/net/irda/irda_device.h	2003-10-05 00:33:25.000000000 -0700
+@@ -128,6 +128,7 @@ struct dongle_reg {
+ 	void (*close)(dongle_t *dongle);
+ 	int  (*reset)(struct irda_task *task);
+ 	int  (*change_speed)(struct irda_task *task);
++	struct module *owner;
+ };
+ 
+ /* 
+@@ -223,6 +224,7 @@ int  irda_device_set_raw_mode(struct net
+ int  irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts);
+ int  irda_device_change_speed(struct net_device *dev, __u32 speed);
+ void irda_device_setup(struct net_device *dev);
++struct net_device *alloc_irdadev(int sizeof_priv);
+ 
+ /* Dongle interface */
+ void irda_device_unregister_dongle(struct dongle_reg *dongle);
+--- linux-2.6.0-test6/include/net/pkt_sched.h	2003-08-08 22:55:14.000000000 -0700
++++ 25/include/net/pkt_sched.h	2003-10-05 00:33:25.000000000 -0700
+@@ -8,6 +8,7 @@
+ #define PSCHED_CLOCK_SOURCE	PSCHED_JIFFIES
+ 
+ #include <linux/config.h>
++#include <linux/netdevice.h>
+ #include <linux/types.h>
+ #include <linux/pkt_sched.h>
+ #include <net/pkt_cls.h>
+--- linux-2.6.0-test6/include/net/scm.h	2003-06-14 12:18:20.000000000 -0700
++++ 25/include/net/scm.h	2003-10-05 00:33:25.000000000 -0700
+@@ -39,7 +39,7 @@ static __inline__ int scm_send(struct so
+ 	memset(scm, 0, sizeof(*scm));
+ 	scm->creds.uid = current->uid;
+ 	scm->creds.gid = current->gid;
+-	scm->creds.pid = current->pid;
++	scm->creds.pid = current->tgid;
+ 	if (msg->msg_controllen <= 0)
+ 		return 0;
+ 	return __scm_send(sock, msg, scm);
+--- linux-2.6.0-test6/include/net/sctp/command.h	2003-08-08 22:55:14.000000000 -0700
++++ 25/include/net/sctp/command.h	2003-10-05 00:33:25.000000000 -0700
+@@ -1,5 +1,6 @@
+-/* SCTP kernel reference Implementation Copyright (C) 1999-2001
+- * Cisco, Motorola, and IBM
++/* SCTP kernel reference Implementation
++ * (C) Copyright IBM Corp. 2001, 2003
++ * Copyright (C) 1999-2001 Cisco, Motorola
+  *
+  * This file is part of the SCTP kernel reference Implementation
+  *
+@@ -88,6 +89,7 @@ typedef enum {
+ 	SCTP_CMD_PART_DELIVER,	 /* Partial data delivery considerations. */
+ 	SCTP_CMD_RENEGE,         /* Renege data on an association. */
+ 	SCTP_CMD_SETUP_T4,	 /* ADDIP, setup T4 RTO timer parms. */
++	SCTP_CMD_PROCESS_OPERR,  /* Process an ERROR chunk. */
+ 	SCTP_CMD_LAST
+ } sctp_verb_t;
+ 
+--- linux-2.6.0-test6/include/net/sctp/sctp.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/net/sctp/sctp.h	2003-10-05 00:33:25.000000000 -0700
+@@ -116,6 +116,9 @@
+ #define SCTP_STATIC static
+ #endif
+ 
++#define MSECS_TO_JIFFIES(msec) (msec * HZ / 1000)
++#define JIFFIES_TO_MSECS(jiff) (jiff * 1000 / HZ)
++
+ /*
+  * Function declarations.
+  */
+@@ -495,22 +498,19 @@ for (err = (sctp_errhdr_t *)((void *)chu
+ #define tv_lt(s, t) \
+    (s.tv_sec < t.tv_sec || (s.tv_sec == t.tv_sec && s.tv_usec < t.tv_usec))
+ 
+-/* Stolen from net/profile.h.  Using it from there is more grief than
+- * it is worth.
+- */
+-static inline void tv_add(const struct timeval *entered, struct timeval *leaved)
+-{
+-	time_t usecs = leaved->tv_usec + entered->tv_usec;
+-	time_t secs = leaved->tv_sec + entered->tv_sec;
+-
+-	if (usecs >= 1000000) {
+-		usecs -= 1000000;
+-		secs++;
+-	}
+-	leaved->tv_sec = secs;
+-	leaved->tv_usec = usecs;
+-}
+-
++/* Add tv1 to tv2. */
++#define TIMEVAL_ADD(tv1, tv2) \
++({ \
++        suseconds_t usecs = (tv2).tv_usec + (tv1).tv_usec; \
++        time_t secs = (tv2).tv_sec + (tv1).tv_sec; \
++\
++        if (usecs >= 1000000) { \
++                usecs -= 1000000; \
++                secs++; \
++        } \
++        (tv2).tv_sec = secs; \
++        (tv2).tv_usec = usecs; \
++})
+ 
+ /* External references. */
+ 
+--- linux-2.6.0-test6/include/net/sctp/sm.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/net/sctp/sm.h	2003-10-05 00:33:25.000000000 -0700
+@@ -265,13 +265,19 @@ struct sctp_chunk *sctp_make_op_error(co
+ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
+ 				    union sctp_addr *addr,
+ 				    int vparam_len);
++struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
++					      union sctp_addr *,
++					      struct sockaddr *,
++					      int, int);
++struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
++					     union sctp_addr *addr);
++struct sctp_chunk *sctp_make_asconf_ack(struct sctp_association *asoc,
++					int serial, int vparam_len);
++
+ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
+ 				       struct sctp_chunk *asconf,
+ 				       int vparam_len);
+ 
+-struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+-					     union sctp_addr *addr);
+-
+ void sctp_chunk_assign_tsn(struct sctp_chunk *);
+ void sctp_chunk_assign_ssn(struct sctp_chunk *);
+ 
+--- linux-2.6.0-test6/include/net/sctp/structs.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/net/sctp/structs.h	2003-10-05 00:33:25.000000000 -0700
+@@ -1085,6 +1085,10 @@ int sctp_add_bind_addr(struct sctp_bind_
+ int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
+ int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
+ 			 struct sctp_opt *);
++union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
++					const union sctp_addr	*addrs,
++					int			addrcnt,
++					struct sctp_opt		*opt);
+ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
+ 					 int *addrs_len, int gfp);
+ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
+@@ -1389,6 +1393,10 @@ struct sctp_association {
+ 		__u8	ipv4_address;	 /* Peer understands IPv4 addresses? */
+ 		__u8	ipv6_address;	 /* Peer understands IPv6 addresses? */
+ 		__u8	hostname_address;/* Peer understands DNS addresses? */
++
++		/* Does peer support ADDIP? */
++		__u8    asconf_capable;
++
+ 		struct sctp_inithdr i;
+ 		int cookie_len;
+ 		void *cookie;
+--- linux-2.6.0-test6/include/sound/sndmagic.h	2003-06-14 12:18:06.000000000 -0700
++++ 25/include/sound/sndmagic.h	2003-10-05 00:33:25.000000000 -0700
+@@ -198,6 +198,8 @@ static inline int _snd_magic_bad(void *o
+ #define vx_pipe_t_magic				0xa15a4112
+ #define azf3328_t_magic				0xa15a4200
+ 
++#define snd_card_harmony_t_magic		0xa15a4300
++
+ #else
+ 
+ #define snd_magic_kcalloc(type, extra, flags) (type *) snd_kcalloc(sizeof(type) + extra, flags)
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/include/video/epson1355.h	2003-10-05 00:34:22.000000000 -0700
+@@ -0,0 +1,64 @@
++/*
++ * include/video/epson13xx.h -- Epson 13xx frame buffer
++ *
++ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
++ *
++ * Written by Christopher Hoover <ch@hpl.hp.com>
++ *
++ */
++
++#ifndef _EPSON13XX_H_
++#define _EPSON13XX_H_
++
++#define REG_REVISION_CODE              0x00
++#define REG_MEMORY_CONFIG              0x01
++#define REG_PANEL_TYPE                 0x02
++#define REG_MOD_RATE                   0x03
++#define REG_HORZ_DISP_WIDTH            0x04
++#define REG_HORZ_NONDISP_PERIOD        0x05
++#define REG_HRTC_START_POSITION        0x06
++#define REG_HRTC_PULSE_WIDTH           0x07
++#define REG_VERT_DISP_HEIGHT0          0x08
++#define REG_VERT_DISP_HEIGHT1          0x09
++#define REG_VERT_NONDISP_PERIOD        0x0A
++#define REG_VRTC_START_POSITION        0x0B
++#define REG_VRTC_PULSE_WIDTH           0x0C
++#define REG_DISPLAY_MODE               0x0D
++#define REG_SCRN1_LINE_COMPARE0        0x0E
++#define REG_SCRN1_LINE_COMPARE1        0x0F
++#define REG_SCRN1_DISP_START_ADDR0     0x10
++#define REG_SCRN1_DISP_START_ADDR1     0x11
++#define REG_SCRN1_DISP_START_ADDR2     0x12
++#define REG_SCRN2_DISP_START_ADDR0     0x13
++#define REG_SCRN2_DISP_START_ADDR1     0x14
++#define REG_SCRN2_DISP_START_ADDR2     0x15
++#define REG_MEM_ADDR_OFFSET0           0x16
++#define REG_MEM_ADDR_OFFSET1           0x17
++#define REG_PIXEL_PANNING              0x18
++#define REG_CLOCK_CONFIG               0x19
++#define REG_POWER_SAVE_CONFIG          0x1A
++#define REG_MISC                       0x1B
++#define REG_MD_CONFIG_READBACK0        0x1C
++#define REG_MD_CONFIG_READBACK1        0x1D
++#define REG_GPIO_CONFIG0               0x1E
++#define REG_GPIO_CONFIG1               0x1F
++#define REG_GPIO_CONTROL0              0x20
++#define REG_GPIO_CONTROL1              0x21
++#define REG_PERF_ENHANCEMENT0          0x22
++#define REG_PERF_ENHANCEMENT1          0x23
++#define REG_LUT_ADDR                   0x24
++#define REG_RESERVED_1                 0x25
++#define REG_LUT_DATA                   0x26
++#define REG_INK_CURSOR_CONTROL         0x27
++#define REG_CURSOR_X_POSITION0         0x28
++#define REG_CURSOR_X_POSITION1         0x29
++#define REG_CURSOR_Y_POSITION0         0x2A
++#define REG_CURSOR_Y_POSITION1         0x2B
++#define REG_INK_CURSOR_COLOR0_0        0x2C
++#define REG_INK_CURSOR_COLOR0_1        0x2D
++#define REG_INK_CURSOR_COLOR1_0        0x2E
++#define REG_INK_CURSOR_COLOR1_1        0x2F
++#define REG_INK_CURSOR_START_ADDR      0x30
++#define REG_ALTERNATE_FRM              0x31
++
++#endif
+--- linux-2.6.0-test6/include/video/neomagic.h	2003-06-14 12:18:07.000000000 -0700
++++ 25/include/video/neomagic.h	2003-10-05 00:34:22.000000000 -0700
+@@ -55,6 +55,20 @@
+ #define NEO_MODE1_X_1600        0x1c00
+ #define NEO_MODE1_BLT_ON_ADDR   0x2000
+ 
++/* These are offseted in MMIO space by par->CursorOff */
++#define NEOREG_CURSCNTL		0x00
++#define NEOREG_CURSX		0x04
++#define NEOREG_CURSY		0x08
++#define NEOREG_CURSBGCOLOR	0x0C
++#define NEOREG_CURSFGCOLOR	0x10
++#define NEOREG_CURSMEMPOS	0x14
++
++#define NEO_CURS_DISABLE	0x00000000
++#define NEO_CURS_ENABLE		0x00000001
++#define NEO_ICON64_ENABLE	0x00000008
++#define NEO_ICON128_ENABLE	0x0000000C
++#define NEO_ICON_BLANK		0x00000010
++
+ #ifdef __KERNEL__
+ 
+ #ifdef NEOFB_DEBUG
+@@ -75,45 +89,45 @@
+ 
+ 
+ struct xtimings {
+-  unsigned int pixclock;
+-  unsigned int HDisplay;
+-  unsigned int HSyncStart;
+-  unsigned int HSyncEnd;
+-  unsigned int HTotal;
+-  unsigned int VDisplay;
+-  unsigned int VSyncStart;
+-  unsigned int VSyncEnd;
+-  unsigned int VTotal;
+-  unsigned int sync;
+-  int	       dblscan;
+-  int	       interlaced;
++	unsigned int pixclock;
++	unsigned int HDisplay;
++	unsigned int HSyncStart;
++	unsigned int HSyncEnd;
++	unsigned int HTotal;
++	unsigned int VDisplay;
++	unsigned int VSyncStart;
++	unsigned int VSyncEnd;
++	unsigned int VTotal;
++	unsigned int sync;
++	int dblscan;
++	int interlaced;
+ };
+ 
+ 
+ /* --------------------------------------------------------------------- */
+ 
+ typedef volatile struct {
+-  __u32 bltStat;
+-  __u32 bltCntl;
+-  __u32 xpColor;
+-  __u32 fgColor;
+-  __u32 bgColor;
+-  __u32 pitch;
+-  __u32 clipLT;
+-  __u32 clipRB;
+-  __u32 srcBitOffset;
+-  __u32 srcStart;
+-  __u32 reserved0;
+-  __u32 dstStart;
+-  __u32 xyExt;
+-
+-  __u32 reserved1[19];
+-
+-  __u32 pageCntl;
+-  __u32 pageBase;
+-  __u32 postBase;
+-  __u32 postPtr;
+-  __u32 dataPtr;
++	__u32 bltStat;
++	__u32 bltCntl;
++	__u32 xpColor;
++	__u32 fgColor;
++	__u32 bgColor;
++	__u32 pitch;
++	__u32 clipLT;
++	__u32 clipRB;
++	__u32 srcBitOffset;
++	__u32 srcStart;
++	__u32 reserved0;
++	__u32 dstStart;
++	__u32 xyExt;
++
++	__u32 reserved1[19];
++
++	__u32 pageCntl;
++	__u32 pageBase;
++	__u32 postBase;
++	__u32 postPtr;
++	__u32 dataPtr;
+ } Neo2200;
+ 
+ #define NR_PALETTE	256
+@@ -124,142 +138,69 @@ typedef volatile struct {
+ #define NEO_EXT_GR_MAX 0xC7
+ 
+ struct neofb_par {
+-  
+-  unsigned char MiscOutReg;     /* Misc */
+-  unsigned char CRTC[25];       /* Crtc Controller */
+-  unsigned char Sequencer[5];   /* Video Sequencer */
+-  unsigned char Graphics[9];    /* Video Graphics */
+-  unsigned char Attribute[21];  /* Video Atribute */
+-
+-  unsigned char GeneralLockReg;
+-  unsigned char ExtCRTDispAddr;
+-  unsigned char ExtCRTOffset;
+-  unsigned char SysIfaceCntl1;
+-  unsigned char SysIfaceCntl2;
+-  unsigned char ExtColorModeSelect;
+-  unsigned char biosMode;
+-
+-  unsigned char PanelDispCntlReg1;
+-  unsigned char PanelDispCntlReg2;
+-  unsigned char PanelDispCntlReg3;
+-  unsigned char PanelVertCenterReg1;
+-  unsigned char PanelVertCenterReg2;
+-  unsigned char PanelVertCenterReg3;
+-  unsigned char PanelVertCenterReg4;
+-  unsigned char PanelVertCenterReg5;
+-  unsigned char PanelHorizCenterReg1;
+-  unsigned char PanelHorizCenterReg2;
+-  unsigned char PanelHorizCenterReg3;
+-  unsigned char PanelHorizCenterReg4;
+-  unsigned char PanelHorizCenterReg5;
+-
+-  int           ProgramVCLK;
+-  unsigned char VCLK3NumeratorLow;
+-  unsigned char VCLK3NumeratorHigh;
+-  unsigned char VCLK3Denominator;
+-  unsigned char VerticalExt;
++	struct vgastate state;
++	atomic_t ref_count;
++
++	unsigned char MiscOutReg;	/* Misc */
++	unsigned char CRTC[25];		/* Crtc Controller */
++	unsigned char Sequencer[5];	/* Video Sequencer */
++	unsigned char Graphics[9];	/* Video Graphics */
++	unsigned char Attribute[21];	/* Video Atribute */
++
++	unsigned char GeneralLockReg;
++	unsigned char ExtCRTDispAddr;
++	unsigned char ExtCRTOffset;
++	unsigned char SysIfaceCntl1;
++	unsigned char SysIfaceCntl2;
++	unsigned char ExtColorModeSelect;
++	unsigned char biosMode;
++
++	unsigned char PanelDispCntlReg1;
++	unsigned char PanelDispCntlReg2;
++	unsigned char PanelDispCntlReg3;
++	unsigned char PanelVertCenterReg1;
++	unsigned char PanelVertCenterReg2;
++	unsigned char PanelVertCenterReg3;
++	unsigned char PanelVertCenterReg4;
++	unsigned char PanelVertCenterReg5;
++	unsigned char PanelHorizCenterReg1;
++	unsigned char PanelHorizCenterReg2;
++	unsigned char PanelHorizCenterReg3;
++	unsigned char PanelHorizCenterReg4;
++	unsigned char PanelHorizCenterReg5;
++
++	int ProgramVCLK;
++	unsigned char VCLK3NumeratorLow;
++	unsigned char VCLK3NumeratorHigh;
++	unsigned char VCLK3Denominator;
++	unsigned char VerticalExt;
+ 
+ #ifdef CONFIG_MTRR
+-  int    mtrr;
++	int mtrr;
+ #endif
+-  u8    *mmio_vbase;
+-
+-  Neo2200 *neo2200;
+-
+-  /* Panels size */
+-  int NeoPanelWidth;
+-  int NeoPanelHeight;
+-
+-  int maxClock;
+-
+-  int pci_burst;
+-  int lcd_stretch;
+-  int internal_display;
+-  int external_display;
+-  int libretto;
++	u8 *mmio_vbase;
++	u8 cursorOff;
++	u8 *cursorPad;		/* Must die !! */
++
++	Neo2200 *neo2200;
++
++	/* Panels size */
++	int NeoPanelWidth;
++	int NeoPanelHeight;
++
++	int maxClock;
++
++	int pci_burst;
++	int lcd_stretch;
++	int internal_display;
++	int external_display;
++	int libretto;
+ };
+ 
+ typedef struct {
+-    int x_res;
+-    int y_res;
+-    int mode;
++	int x_res;
++	int y_res;
++	int mode;
+ } biosMode;
+ 
+-/* vga IO functions */
+-static inline u8 VGArCR (u8 index)
+-{
+-  outb (index, 0x3d4);
+-  return inb (0x3d5);
+-}
+-
+-static inline void VGAwCR (u8 index, u8 val)
+-{
+-  outb (index, 0x3d4);
+-  outb (val, 0x3d5);
+-}
+-
+-static inline u8 VGArGR (u8 index)
+-{
+-  outb (index, 0x3ce);
+-  return inb (0x3cf);
+-}
+-
+-static inline void VGAwGR (u8 index, u8 val)
+-{
+-  outb (index, 0x3ce);
+-  outb (val, 0x3cf);
+-}
+-
+-static inline u8 VGArSEQ (u8 index)
+-{
+-  outb (index, 0x3c4);
+-  return inb (0x3c5);
+-}
+-
+-static inline void VGAwSEQ (u8 index, u8 val)
+-{
+-  outb (index, 0x3c4);
+-  outb (val, 0x3c5);
+-}
+-
+-
+-static int paletteEnabled = 0;
+-
+-static inline void VGAenablePalette (void)
+-{
+-  u8 tmp;
+-
+-  tmp = inb (0x3da);
+-  outb (0x00, 0x3c0);
+-  paletteEnabled = 1;
+-}
+-
+-static inline void VGAdisablePalette (void)
+-{
+-  u8 tmp;
+-
+-  tmp = inb (0x3da);
+-  outb (0x20, 0x3c0);
+-  paletteEnabled = 0;
+-}
+-
+-static inline void VGAwATTR (u8 index, u8 value)
+-{
+-  u8 tmp;
+-
+-  if (paletteEnabled)
+-    index &= ~0x20;
+-  else
+-    index |= 0x20;
+-
+-  tmp = inb (0x3da);
+-  outb (index, 0x3c0);
+-  outb (value, 0x3c0);
+-}
+-
+-static inline void VGAwMISC (u8 value)
+-{
+-  outb (value, 0x3c2);
+-}
+ #endif
+-
+--- linux-2.6.0-test6/include/video/sisfb.h	2003-09-08 13:58:59.000000000 -0700
++++ 25/include/video/sisfb.h	2003-10-05 00:34:22.000000000 -0700
+@@ -6,6 +6,53 @@
+ #include <asm/ioctl.h>
+ #include <asm/types.h>
+ 
++/* TW: vbflags */
++#define CRT2_DEFAULT            0x00000001
++#define CRT2_LCD                0x00000002  /* TW: Never change the order of the CRT2_XXX entries */
++#define CRT2_TV                 0x00000004  /*     (see SISCycleCRT2Type())                       */
++#define CRT2_VGA                0x00000008
++#define CRT2_ENABLE		(CRT2_LCD | CRT2_TV | CRT2_VGA)
++#define VB_DISPTYPE_DISP2	CRT2_ENABLE
++#define VB_DISPTYPE_CRT2	CRT2_ENABLE
++#define TV_NTSC                 0x00000010
++#define TV_PAL                  0x00000020
++#define TV_HIVISION             0x00000040
++#define TV_HIVISION_LV          0x00000080
++#define TV_TYPE                 (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV)
++#define TV_AVIDEO               0x00000100
++#define TV_SVIDEO               0x00000200
++#define TV_SCART                0x00000400
++#define TV_INTERFACE            (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV)
++#define VB_USELCDA		0x00000800
++#define TV_PALM                 0x00001000
++#define TV_PALN                 0x00002000
++#define TV_CHSCART              0x00008000
++#define TV_CHHDTV               0x00010000
++#define VGA2_CONNECTED          0x00040000
++#define VB_DISPTYPE_CRT1	0x00080000  	/* CRT1 connected and used */
++#define VBDISPTYPE_DISP1	VB_DISPTYPE_CRT1
++#define VB_301                  0x00100000	/* Video bridge type */
++#define VB_301B                 0x00200000
++#define VB_302B                 0x00400000
++#define VB_30xBDH		0x00800000      /* 30xB DH version (w/o LCD support) */
++#define VB_LVDS                 0x01000000
++#define VB_CHRONTEL             0x02000000
++#define VB_301LV                0x04000000
++#define VB_302LV                0x08000000
++#define VB_TRUMPION		0x10000000
++#define VB_VIDEOBRIDGE		(VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV| \
++				 VB_LVDS|VB_CHRONTEL|VB_TRUMPION)
++#define VB_SISBRIDGE            (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV)
++#define VB_SINGLE_MODE          0x20000000   	 /* CRT1 or CRT2; determined by VB_DISPTYPE_CRTx */
++#define VB_DISPMODE_SINGLE	VB_SINGLE_MODE
++#define VB_MIRROR_MODE		0x40000000   	 /* CRT1 + CRT2 identical (mirror mode) */
++#define VB_DISPMODE_MIRROR	VB_MIRROR_MODE
++#define VB_DUALVIEW_MODE	0x80000000   	 /* CRT1 + CRT2 independent (dual head mode) */
++#define VB_DISPMODE_DUAL	VB_DUALVIEW_MODE
++#define VB_DISPLAY_MODE         (VB_SINGLE_MODE | VB_MIRROR_MODE | VB_DUALVIEW_MODE)
++
++
++/* entries for disp_state - deprecated as of 1.6.02 */
+ #define DISPTYPE_CRT1       0x00000008L
+ #define DISPTYPE_CRT2       0x00000004L
+ #define DISPTYPE_LCD        0x00000002L
+@@ -16,6 +63,7 @@
+ #define DISPMODE_MIRROR	    0x00000010L
+ #define DISPMODE_DUALVIEW   0x00000040L
+ 
++/* Deprecated as of 1.6.02 - use vbflags instead */
+ #define HASVB_NONE      	0x00
+ #define HASVB_301       	0x01
+ #define HASVB_LVDS      	0x02
+@@ -39,6 +87,8 @@ typedef enum _SIS_CHIP_TYPE {
+ 	SIS_650,
+ 	SIS_740,
+ 	SIS_330,
++	SIS_660,
++	SIS_760,
+ 	MAX_SIS_CHIP
+ } SIS_CHIP_TYPE;
+ 
+@@ -83,13 +133,15 @@ struct ap_data {
+ 	struct mode_info minfo;
+ 	unsigned long iobase;
+ 	unsigned int  mem_size;
+-	unsigned long disp_state;    	
++	unsigned long disp_state;  /* deprecated */
+ 	SIS_CHIP_TYPE chip;
+ 	unsigned char hasVB;
+-	SIS_TV_TYPE TV_type;
+-	SIS_TV_PLUG TV_plug;
++	SIS_TV_TYPE TV_type;	   /* deprecated */
++	SIS_TV_PLUG TV_plug;	   /* deprecated */
+ 	unsigned long version;
+-	char reserved[256];
++	unsigned long vbflags;	   /* replaces deprecated entries above */
++	unsigned long currentvbflags;
++	char reserved[248];
+ };
+ 
+ struct video_info {
+@@ -114,10 +166,10 @@ struct video_info {
+ 	int    video_linelength;
+ 	unsigned int refresh_rate;
+ 
+-	unsigned long disp_state;
+-	unsigned char hasVB;
+-	unsigned char TV_type;
+-	unsigned char TV_plug;
++	unsigned long disp_state;		/* DEPRECATED */
++	unsigned char hasVB;			/* DEPRECATED */
++	unsigned char TV_type;			/* DEPRECATED */
++	unsigned char TV_plug;			/* DEPRECATED */
+ 
+ 	SIS_CHIP_TYPE chip;
+ 	unsigned char revision_id;
+@@ -137,7 +189,18 @@ struct video_info {
+ 	unsigned short subsysvendor;
+ 	unsigned short subsysdevice;
+ 
+-	char reserved[236];
++	unsigned long  vbflags;			/* Replacing deprecated stuff from above */
++	unsigned long  currentvbflags;
++
++	int    current_bpp;
++	int    current_width;
++	int    current_height;
++	int    current_htotal;
++	int    current_vtotal;
++	__u32  current_pixclock;
++	int    current_refresh_rate;
++
++	char reserved[200];
+ };
+ 
+ 
+@@ -185,7 +248,13 @@ struct _SISFB_INFO {
+ 	
+ 	unsigned char sisfb_lcda;	/* Detected status of LCDA for low res/text modes */
+ 
+-	char reserved[235]; 		/* for future use */
++	unsigned long sisfb_vbflags;
++	unsigned long sisfb_currentvbflags;
++
++	int sisfb_scalelcd;
++	unsigned long sisfb_specialtiming;
++
++	char reserved[219]; 		/* for future use */
+ };
+ 
+ #ifdef __KERNEL__
+--- linux-2.6.0-test6/init/do_mounts.h	2003-09-27 18:57:47.000000000 -0700
++++ 25/init/do_mounts.h	2003-10-05 00:33:25.000000000 -0700
+@@ -104,4 +104,3 @@ void md_run_setup(void);
+ static inline void md_run_setup(void) {}
+ 
+ #endif
+-
+--- linux-2.6.0-test6/init/do_mounts_initrd.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/init/do_mounts_initrd.c	2003-10-05 00:33:53.000000000 -0700
+@@ -9,6 +9,8 @@
+ 
+ #include "do_mounts.h"
+ 
++unsigned long initrd_start, initrd_end;
++int initrd_below_start_ok;
+ unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
+ static int __initdata old_fd, root_fd;
+ static int __initdata mount_initrd = 1;
+@@ -99,18 +101,20 @@ static void __init handle_initrd(void)
+ 
+ int __init initrd_load(void)
+ {
+-	if (!mount_initrd)
+-		return 0;
+-
+-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+-	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+-	/* Load the initrd data into /dev/ram0. Execute it as initrd unless
+-	 * /dev/ram0 is supposed to be our actual root device, in
+-	 * that case the ram disk is just set up here, and gets
+-	 * mounted in the normal path. */
+-	if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) {
+-		handle_initrd();
+-		return 1;
++	if (mount_initrd) {
++		create_dev("/dev/ram", Root_RAM0, NULL);
++		/*
++		 * Load the initrd data into /dev/ram0. Execute it as initrd
++		 * unless /dev/ram0 is supposed to be our actual root device,
++		 * in that case the ram disk is just set up here, and gets
++		 * mounted in the normal path.
++		 */
++		if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) {
++			sys_unlink("/dev/initrd");
++			handle_initrd();
++			return 1;
++		}
+ 	}
++	sys_unlink("/dev/initrd");
+ 	return 0;
+ }
+--- linux-2.6.0-test6/init/initramfs.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/init/initramfs.c	2003-10-05 00:33:53.000000000 -0700
+@@ -8,9 +8,11 @@
+ #include <linux/delay.h>
+ #include <linux/string.h>
+ 
++static __initdata char *message;
+ static void __init error(char *x)
+ {
+-	panic("populate_root: %s\n", x);
++	if (!message)
++		message = x;
+ }
+ 
+ static void __init *malloc(int size)
+@@ -63,7 +65,7 @@ static char __init *find_link(int major,
+ 	}
+ 	q = (struct hash *)malloc(sizeof(struct hash));
+ 	if (!q)
+-		error("can't allocate link hash entry");
++		panic("can't allocate link hash entry");
+ 	q->ino = ino;
+ 	q->minor = minor;
+ 	q->major = major;
+@@ -119,7 +121,7 @@ static void __init parse_header(char *s)
+ 
+ /* FSM */
+ 
+-enum state {
++static __initdata enum state {
+ 	Start,
+ 	Collect,
+ 	GotHeader,
+@@ -130,9 +132,11 @@ enum state {
+ 	Reset
+ } state, next_state;
+ 
+-char *victim;
+-unsigned count;
+-loff_t this_header, next_header;
++static __initdata char *victim;
++static __initdata unsigned count;
++static __initdata loff_t this_header, next_header;
++
++static __initdata int dry_run;
+ 
+ static inline void eat(unsigned n)
+ {
+@@ -185,23 +189,30 @@ static int __init do_collect(void)
+ 
+ static int __init do_header(void)
+ {
++	if (memcmp(collected, "070701", 6)) {
++		error("no cpio magic");
++		return 1;
++	}
+ 	parse_header(collected);
+ 	next_header = this_header + N_ALIGN(name_len) + body_len;
+ 	next_header = (next_header + 3) & ~3;
++	if (dry_run) {
++		read_into(name_buf, N_ALIGN(name_len), GotName);
++		return 0;
++	}
++	state = SkipIt;
+ 	if (name_len <= 0 || name_len > PATH_MAX)
+-		state = SkipIt;
+-	else if (S_ISLNK(mode)) {
++		return 0;
++	if (S_ISLNK(mode)) {
+ 		if (body_len > PATH_MAX)
+-			state = SkipIt;
+-		else {
+-			collect = collected = symlink_buf;
+-			remains = N_ALIGN(name_len) + body_len;
+-			next_state = GotSymlink;
+-			state = Collect;
+-		}
+-	} else if (body_len && !S_ISREG(mode))
+-		state = SkipIt;
+-	else
++			return 0;
++		collect = collected = symlink_buf;
++		remains = N_ALIGN(name_len) + body_len;
++		next_state = GotSymlink;
++		state = Collect;
++		return 0;
++	}
++	if (S_ISREG(mode) || !body_len)
+ 		read_into(name_buf, N_ALIGN(name_len), GotName);
+ 	return 0;
+ }
+@@ -248,6 +259,8 @@ static int __init do_name(void)
+ 		next_state = Reset;
+ 		return 0;
+ 	}
++	if (dry_run)
++		return 0;
+ 	if (S_ISREG(mode)) {
+ 		if (maybe_link() >= 0) {
+ 			wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
+@@ -268,8 +281,7 @@ static int __init do_name(void)
+ 			sys_chown(collected, uid, gid);
+ 			sys_chmod(collected, mode);
+ 		}
+-	} else
+-		panic("populate_root: bogus mode: %o\n", mode);
++	}
+ 	return 0;
+ }
+ 
+@@ -323,13 +335,14 @@ static int __init write_buffer(char *buf
+ static void __init flush_buffer(char *buf, unsigned len)
+ {
+ 	int written;
+-	while ((written = write_buffer(buf, len)) < len) {
++	if (message)
++		return;
++	while ((written = write_buffer(buf, len)) < len && !message) {
+ 		char c = buf[written];
+ 		if (c == '0') {
+ 			buf += written;
+ 			len -= written;
+ 			state = Start;
+-			continue;
+ 		} else
+ 			error("junk in compressed archive");
+ 	}
+@@ -408,18 +421,20 @@ static void __init flush_window(void)
+ 	outcnt = 0;
+ }
+ 
+-static void __init unpack_to_rootfs(char *buf, unsigned len)
++char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+ {
+ 	int written;
++	dry_run = check_only;
+ 	header_buf = malloc(110);
+ 	symlink_buf = malloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1);
+ 	name_buf = malloc(N_ALIGN(PATH_MAX));
+ 	window = malloc(WSIZE);
+ 	if (!window || !header_buf || !symlink_buf || !name_buf)
+-		error("can't allocate buffers");
++		panic("can't allocate buffers");
+ 	state = Start;
+ 	this_header = 0;
+-	while (len) {
++	message = NULL;
++	while (!message && len) {
+ 		loff_t saved_offset = this_header;
+ 		if (*buf == '0' && !(this_header & 3)) {
+ 			state = Start;
+@@ -427,7 +442,8 @@ static void __init unpack_to_rootfs(char
+ 			buf += written;
+ 			len -= written;
+ 			continue;
+-		} else if (!*buf) {
++		}
++		if (!*buf) {
+ 			buf++;
+ 			len--;
+ 			this_header++;
+@@ -442,7 +458,7 @@ static void __init unpack_to_rootfs(char
+ 		crc = (ulg)0xffffffffL; /* shift register contents */
+ 		makecrc();
+ 		if (gunzip())
+-			error("ungzip failed");
++			message = "ungzip failed";
+ 		if (state != Reset)
+ 			error("junk in gzipped archive");
+ 		this_header = saved_offset + inptr;
+@@ -453,12 +469,41 @@ static void __init unpack_to_rootfs(char
+ 	free(name_buf);
+ 	free(symlink_buf);
+ 	free(header_buf);
++	return message;
+ }
+ 
+ extern char __initramfs_start, __initramfs_end;
++#ifdef CONFIG_BLK_DEV_INITRD
++#include <linux/initrd.h>
++#endif
+ 
+ void __init populate_rootfs(void)
+ {
+-	unpack_to_rootfs(&__initramfs_start,
+-			 &__initramfs_end - &__initramfs_start);
++	char *err = unpack_to_rootfs(&__initramfs_start,
++			 &__initramfs_end - &__initramfs_start, 0);
++	if (err)
++		panic(err);
++#ifdef CONFIG_BLK_DEV_INITRD
++	if (initrd_start) {
++		int fd;
++		printk(KERN_INFO "checking if image is initramfs...");
++		err = unpack_to_rootfs((char *)initrd_start,
++			initrd_end - initrd_start, 1);
++		if (!err) {
++			printk(" it is\n");
++			unpack_to_rootfs((char *)initrd_start,
++				initrd_end - initrd_start, 0);
++			free_initrd_mem(initrd_start, initrd_end);
++			return;
++		}
++		printk("it isn't (%s); looks like an initrd\n", err);
++		fd = sys_open("/dev/initrd", O_WRONLY|O_CREAT, 700);
++		if (fd >= 0) {
++			sys_write(fd, (char *)initrd_start,
++					initrd_end - initrd_start);
++			sys_close(fd);
++			free_initrd_mem(initrd_start, initrd_end);
++		}
++	}
++#endif
+ }
+--- linux-2.6.0-test6/init/main.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/init/main.c	2003-10-05 00:36:25.000000000 -0700
+@@ -37,6 +37,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/writeback.h>
+ #include <linux/cpu.h>
++#include <linux/efi.h>
+ 
+ #include <asm/io.h>
+ #include <asm/bugs.h>
+@@ -436,6 +437,10 @@ asmlinkage void __init start_kernel(void
+ 	pidmap_init();
+ 	pgtable_cache_init();
+ 	pte_chain_init();
++#ifdef CONFIG_X86
++	if (efi_enabled)
++		efi_enter_virtual_mode();
++#endif
+ 	fork_init(num_physpages);
+ 	proc_caches_init();
+ 	buffer_init();
+--- linux-2.6.0-test6/kernel/acct.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/acct.c	2003-10-05 00:36:15.000000000 -0700
+@@ -343,7 +343,7 @@ static void do_acct_process(long exitcod
+ 	/* we really need to bite the bullet and change layout */
+ 	ac.ac_uid = current->uid;
+ 	ac.ac_gid = current->gid;
+-	ac.ac_tty = current->tty ? old_encode_dev(tty_devnum(current->tty)) : 0;
++	ac.ac_tty = process_tty(current) ? old_encode_dev(tty_devnum(process_tty(current))) : 0;
+ 
+ 	ac.ac_flag = 0;
+ 	if (current->flags & PF_FORKNOEXEC)
+--- linux-2.6.0-test6/kernel/exit.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/exit.c	2003-10-05 00:36:15.000000000 -0700
+@@ -119,13 +119,13 @@ int session_of_pgrp(int pgrp)
+ 
+ 	read_lock(&tasklist_lock);
+ 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid)
+-		if (p->session > 0) {
+-			sid = p->session;
++		if (process_session(p) > 0) {
++			sid = process_session(p);
+ 			goto out;
+ 		}
+ 	p = find_task_by_pid(pgrp);
+ 	if (p)
+-		sid = p->session;
++		sid = process_session(p);
+ out:
+ 	read_unlock(&tasklist_lock);
+ 	
+@@ -153,7 +153,7 @@ static int will_become_orphaned_pgrp(int
+ 				|| p->real_parent->pid == 1)
+ 			continue;
+ 		if (process_group(p->real_parent) != pgrp
+-			    && p->real_parent->session == p->session) {
++			    && process_session(p->real_parent) == process_session(p)) {
+ 			ret = 0;
+ 			break;
+ 		}
+@@ -242,14 +242,14 @@ void __set_special_pids(pid_t session, p
+ {
+ 	struct task_struct *curr = current;
+ 
+-	if (curr->session != session) {
++	if (process_session(curr) != session) {
+ 		detach_pid(curr, PIDTYPE_SID);
+-		curr->session = session;
++		curr->signal->session = session;
+ 		attach_pid(curr, PIDTYPE_SID, session);
+ 	}
+ 	if (process_group(curr) != pgrp) {
+ 		detach_pid(curr, PIDTYPE_PGID);
+-		curr->group_leader->__pgrp = pgrp;
++		curr->signal->pgrp = pgrp;
+ 		attach_pid(curr, PIDTYPE_PGID, pgrp);
+ 	}
+ }
+@@ -303,7 +303,7 @@ void daemonize(const char *name, ...)
+ 	exit_mm(current);
+ 
+ 	set_special_pids(1, 1);
+-	current->tty = NULL;
++	current->signal->tty = NULL;
+ 
+ 	/* Block and flush all signals */
+ 	sigfillset(&blocked);
+@@ -509,7 +509,7 @@ static inline void reparent_thread(task_
+ 	 * outside, so the child pgrp is now orphaned.
+ 	 */
+ 	if ((process_group(p) != process_group(father)) &&
+-	    (p->session == father->session)) {
++	    (process_session(p) == process_session(father))) {
+ 		int pgrp = process_group(p);
+ 
+ 		if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
+@@ -619,7 +619,7 @@ static void exit_notify(struct task_stru
+ 	t = tsk->real_parent;
+ 	
+ 	if ((process_group(t) != process_group(tsk)) &&
+-	    (t->session == tsk->session) &&
++	    (process_session(t) == process_session(tsk)) &&
+ 	    will_become_orphaned_pgrp(process_group(tsk), tsk) &&
+ 	    has_stopped_jobs(process_group(tsk))) {
+ 		__kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
+@@ -714,7 +714,7 @@ NORET_TYPE void do_exit(long code)
+ 	exit_itimers(tsk);
+ 	exit_thread();
+ 
+-	if (tsk->leader)
++	if (process_session_leader(tsk))
+ 		disassociate_ctty(1);
+ 
+ 	module_put(tsk->thread_info->exec_domain->module);
+--- linux-2.6.0-test6/kernel/fork.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/fork.c	2003-10-05 00:36:54.000000000 -0700
+@@ -121,7 +121,12 @@ void prepare_to_wait(wait_queue_head_t *
+ {
+ 	unsigned long flags;
+ 
+-	__set_current_state(state);
++	/*
++	 * don't alter the task state if this is just going to
++	 * queue an async wait queue callback
++	 */
++	if (is_sync_wait(wait))
++		__set_current_state(state);
+ 	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
+ 	spin_lock_irqsave(&q->lock, flags);
+ 	if (list_empty(&wait->task_list))
+@@ -134,7 +139,12 @@ prepare_to_wait_exclusive(wait_queue_hea
+ {
+ 	unsigned long flags;
+ 
+-	__set_current_state(state);
++	/*
++	 * don't alter the task state if this is just going to
++	 * queue an async wait queue callback
++	 */
++	if (is_sync_wait(wait))
++		__set_current_state(state);
+ 	wait->flags |= WQ_FLAG_EXCLUSIVE;
+ 	spin_lock_irqsave(&q->lock, flags);
+ 	if (list_empty(&wait->task_list))
+@@ -274,9 +284,9 @@ static inline int dup_mmap(struct mm_str
+ 				atomic_dec(&inode->i_writecount);
+       
+ 			/* insert tmp into the share list, just after mpnt */
+-			down(&inode->i_mapping->i_shared_sem);
++			down(&file->f_mapping->i_shared_sem);
+ 			list_add_tail(&tmp->shared, &mpnt->shared);
+-			up(&inode->i_mapping->i_shared_sem);
++			up(&file->f_mapping->i_shared_sem);
+ 		}
+ 
+ 		/*
+@@ -725,6 +735,12 @@ static inline int copy_signal(unsigned l
+ 	sig->curr_target = NULL;
+ 	init_sigpending(&sig->shared_pending);
+ 
++	sig->tty = process_tty(current);
++	sig->pgrp = process_group(current);
++	sig->session = process_session(current);
++	sig->leader = 0;	/* session leadership doesn't inherit */
++	sig->tty_old_pgrp = 0;
++
+ 	return 0;
+ }
+ 
+@@ -771,7 +787,9 @@ struct task_struct *copy_process(unsigne
+ 	 * Thread groups must share signals as well, and detached threads
+ 	 * can only be started up within the thread group.
+ 	 */
+-	if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND))
++	if ((clone_flags & CLONE_THREAD) &&
++		(clone_flags & (CLONE_SIGHAND|CLONE_DETACHED)) !=
++			(CLONE_SIGHAND|CLONE_DETACHED))
+ 		return ERR_PTR(-EINVAL);
+ 
+ 	/*
+@@ -876,8 +894,6 @@ struct task_struct *copy_process(unsigne
+ 	init_timer(&p->real_timer);
+ 	p->real_timer.data = (unsigned long) p;
+ 
+-	p->leader = 0;		/* session leadership doesn't inherit */
+-	p->tty_old_pgrp = 0;
+ 	p->utime = p->stime = 0;
+ 	p->cutime = p->cstime = 0;
+ 	p->array = NULL;
+@@ -885,6 +901,7 @@ struct task_struct *copy_process(unsigne
+ 	p->start_time = get_jiffies_64();
+ 	p->security = NULL;
+ 	p->io_context = NULL;
++	p->io_wait = NULL;
+ 
+ 	retval = -ENOMEM;
+ 	if ((retval = security_task_alloc(p)))
+@@ -1022,7 +1039,7 @@ struct task_struct *copy_process(unsigne
+ 	if (thread_group_leader(p)) {
+ 		attach_pid(p, PIDTYPE_TGID, p->tgid);
+ 		attach_pid(p, PIDTYPE_PGID, process_group(p));
+-		attach_pid(p, PIDTYPE_SID, p->session);
++		attach_pid(p, PIDTYPE_SID, process_session(p));
+ 		if (p->pid)
+ 			__get_cpu_var(process_counts)++;
+ 	} else
+--- linux-2.6.0-test6/kernel/futex.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/futex.c	2003-10-05 00:34:38.000000000 -0700
+@@ -45,6 +45,9 @@
+  * Futexes are matched on equal values of this key.
+  * The key type depends on whether it's a shared or private mapping.
+  * Don't rearrange members without looking at hash_futex().
++ *
++ * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
++ * We set bit 0 to indicate if it's an inode-based key.
+  */
+ union futex_key {
+ 	struct {
+@@ -66,12 +69,20 @@ union futex_key {
+ 
+ /*
+  * We use this hashed waitqueue instead of a normal wait_queue_t, so
+- * we can wake only the relevant ones (hashed queues may be shared):
++ * we can wake only the relevant ones (hashed queues may be shared).
++ *
++ * A futex_q has a woken state, just like tasks have TASK_RUNNING.
++ * It is considered woken when list_empty(&q->list) || q->lock_ptr == 0.
++ * The order of wakup is always to make the first condition true, then
++ * wake up q->waiters, then make the second condition true.
+  */
+ struct futex_q {
+ 	struct list_head list;
+ 	wait_queue_head_t waiters;
+ 
++	/* Which hash list lock to use. */
++	spinlock_t *lock_ptr;
++
+ 	/* Key which the futex is hashed on. */
+ 	union futex_key key;
+ 
+@@ -124,8 +135,7 @@ static inline int match_futex(union fute
+  * Returns: 0, or negative error code.
+  * The key words are stored in *key on success.
+  *
+- * Should be called with &current->mm->mmap_sem,
+- * but NOT &futex_lock or &current->mm->page_table_lock.
++ * Should be called with &current->mm->mmap_sem but NOT any spinlocks.
+  */
+ static int get_futex_key(unsigned long uaddr, union futex_key *key)
+ {
+@@ -172,9 +182,10 @@ static int get_futex_key(unsigned long u
+ 	}
+ 
+ 	/*
+-	 * Linear mappings are also simple.
++	 * Linear file mappings are also simple.
+ 	 */
+ 	key->shared.inode = vma->vm_file->f_dentry->d_inode;
++	key->both.offset++; /* Bit 0 of offset indicates inode-based key. */
+ 	if (likely(!(vma->vm_flags & VM_NONLINEAR))) {
+ 		key->shared.pgoff = (((uaddr - vma->vm_start) >> PAGE_SHIFT)
+ 				     + vma->vm_pgoff);
+@@ -214,16 +225,68 @@ static int get_futex_key(unsigned long u
+ 	return err;
+ }
+ 
++/*
++ * Take a reference to the resource addressed by a key.
++ * Can be called while holding spinlocks.
++ *
++ * NOTE: mmap_sem MUST be held between get_futex_key() and calling this
++ * function, if it is called at all.  mmap_sem keeps key->shared.inode valid.
++ */
++static inline void get_key_refs(union futex_key *key)
++{
++	if (key->both.ptr != 0) {
++		if (key->both.offset & 1)
++			atomic_inc(&key->shared.inode->i_count);
++		else
++			atomic_inc(&key->private.mm->mm_count);
++	}
++}
++
++/*
++ * Drop a reference to the resource addressed by a key.
++ * The hash bucket spinlock must not be held.
++ */
++static void drop_key_refs(union futex_key *key)
++{
++	if (key->both.ptr != 0) {
++		if (key->both.offset & 1)
++			iput(key->shared.inode);
++		else
++			mmdrop(key->private.mm);
++	}
++}
++
++/*
++ * The hash bucket lock must be held when this is called.
++ * Afterwards, the futex_q must not be accessed.
++ */
++static void wake_futex(struct futex_q *q)
++{
++	list_del_init(&q->list);
++	if (q->filp)
++		send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
++	/*
++	 * The lock in wake_up_all() is a crucial memory barrier after the
++	 * list_del_init() and also before assigning to q->lock_ptr.
++	 */
++	wake_up_all(&q->waiters);
++	/*
++	 * The waiting task can free the futex_q as soon as this is written,
++	 * without taking any locks.  This must come last.
++	 */
++	q->lock_ptr = 0;
++}
+ 
+ /*
+  * Wake up all waiters hashed on the physical page that is mapped
+  * to this virtual address:
+  */
+-static int futex_wake(unsigned long uaddr, int num)
++static int futex_wake(unsigned long uaddr, int nr_wake)
+ {
+-	struct list_head *i, *next, *head;
+-	struct futex_hash_bucket *bh;
+ 	union futex_key key;
++	struct futex_hash_bucket *bh;
++	struct list_head *head;
++	struct futex_q *this, *next;
+ 	int ret;
+ 
+ 	down_read(&current->mm->mmap_sem);
+@@ -236,21 +299,15 @@ static int futex_wake(unsigned long uadd
+ 	spin_lock(&bh->lock);
+ 	head = &bh->chain;
+ 
+-	list_for_each_safe(i, next, head) {
+-		struct futex_q *this = list_entry(i, struct futex_q, list);
+-
++	list_for_each_entry_safe(this, next, head, list) {
+ 		if (match_futex (&this->key, &key)) {
+-			list_del_init(i);
+-			wake_up_all(&this->waiters);
+-			if (this->filp)
+-				send_sigio(&this->filp->f_owner, this->fd, POLL_IN);
+-			ret++;
+-			if (ret >= num)
++			wake_futex(this);
++			if (++ret >= nr_wake)
+ 				break;
+ 		}
+ 	}
+-	spin_unlock(&bh->lock);
+ 
++	spin_unlock(&bh->lock);
+ out:
+ 	up_read(&current->mm->mmap_sem);
+ 	return ret;
+@@ -263,10 +320,11 @@ out:
+ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
+ 				int nr_wake, int nr_requeue)
+ {
+-	struct list_head *i, *next, *head1, *head2;
+-	struct futex_hash_bucket *bh1, *bh2;
+ 	union futex_key key1, key2;
+-	int ret;
++	struct futex_hash_bucket *bh1, *bh2;
++	struct list_head *head1;
++	struct futex_q *this, *next;
++	int ret, drop_count = 0;
+ 
+ 	down_read(&current->mm->mmap_sem);
+ 
+@@ -279,78 +337,107 @@ static int futex_requeue(unsigned long u
+ 
+ 	bh1 = hash_futex(&key1);
+ 	bh2 = hash_futex(&key2);
+-	if (bh1 < bh2) {
++
++	if (bh1 < bh2)
++		spin_lock(&bh1->lock);
++	spin_lock(&bh2->lock);
++	if (bh1 > bh2)
+ 		spin_lock(&bh1->lock);
+-		spin_lock(&bh2->lock);
+-	} else {
+-		spin_lock(&bh2->lock);
+-		if (bh1 > bh2)
+-			spin_lock(&bh1->lock);
+-	}
+-	head1 = &bh1->chain;
+-	head2 = &bh2->chain;
+ 
+-	list_for_each_safe(i, next, head1) {
+-		struct futex_q *this = list_entry(i, struct futex_q, list);
++	head1 = &bh1->chain;
++	list_for_each_entry_safe(this, next, head1, list) {
++		if (!match_futex (&this->key, &key1))
++			continue;
++		if (++ret <= nr_wake) {
++			wake_futex(this);
++		} else {
++			list_move_tail(&this->list, &bh2->chain);
++			this->lock_ptr = &bh2->lock;
++			this->key = key2;
++			get_key_refs(&key2);
++			drop_count++;
+ 
+-		if (match_futex (&this->key, &key1)) {
+-			list_del_init(i);
+-			if (++ret <= nr_wake) {
+-				wake_up_all(&this->waiters);
+-				if (this->filp)
+-					send_sigio(&this->filp->f_owner,
+-							this->fd, POLL_IN);
+-			} else {
+-				list_add_tail(i, head2);
+-				this->key = key2;
+-				if (ret - nr_wake >= nr_requeue)
+-					break;
+-				/* Make sure to stop if key1 == key2 */
+-				if (head1 == head2 && head1 != next)
+-					head1 = i;
+-			}
++			if (ret - nr_wake >= nr_requeue)
++				break;
++			/* Make sure to stop if key1 == key2 */
++			if (head1 == &bh2->chain && head1 != &next->list)
++				head1 = &this->list;
+ 		}
+ 	}
+-	if (bh1 < bh2) {
+-		spin_unlock(&bh2->lock);
+-		spin_unlock(&bh1->lock);
+-	} else {
+-		if (bh1 > bh2)
+-			spin_unlock(&bh1->lock);
++
++	spin_unlock(&bh1->lock);
++	if (bh1 != bh2)
+ 		spin_unlock(&bh2->lock);
+-	}
++
++	/* drop_key_refs() must be called outside the spinlocks. */
++	while (--drop_count >= 0)
++		drop_key_refs(&key1);
++
+ out:
+ 	up_read(&current->mm->mmap_sem);
+ 	return ret;
+ }
+ 
+-static inline void queue_me(struct futex_q *q, union futex_key *key,
+-			    int fd, struct file *filp)
++/*
++ * queue_me and unqueue_me must be called as a pair, each
++ * exactly once.  They are called with the hashed spinlock held.
++ */
++
++/* The key must be already stored in q->key. */
++static void queue_me(struct futex_q *q, int fd, struct file *filp)
+ {
+-	struct futex_hash_bucket *bh = hash_futex(key);
+-	struct list_head *head = &bh->chain;
++	struct futex_hash_bucket *bh;
+ 
+-	q->key = *key;
+ 	q->fd = fd;
+ 	q->filp = filp;
+ 
++	init_waitqueue_head(&q->waiters);
++
++	get_key_refs(&q->key);
++	bh = hash_futex(&q->key);
++	q->lock_ptr = &bh->lock;
++
+ 	spin_lock(&bh->lock);
+-	list_add_tail(&q->list, head);
++	list_add_tail(&q->list, &bh->chain);
+ 	spin_unlock(&bh->lock);
+ }
+ 
+ /* Return 1 if we were still queued (ie. 0 means we were woken) */
+-static inline int unqueue_me(struct futex_q *q)
++static int unqueue_me(struct futex_q *q)
+ {
+-	struct futex_hash_bucket *bh = hash_futex(&q->key);
+ 	int ret = 0;
++	spinlock_t *lock_ptr;
+ 
+-	spin_lock(&bh->lock);
+-	if (!list_empty(&q->list)) {
+-		list_del(&q->list);
+-		ret = 1;
++	/* In the common case we don't take the spinlock, which is nice. */
++ retry:
++	lock_ptr = q->lock_ptr;
++	if (lock_ptr != 0) {
++		spin_lock(lock_ptr);
++		/*
++		 * q->lock_ptr can change between reading it and
++		 * spin_lock(), causing us to take the wrong lock.  This
++		 * corrects the race condition.
++		 *
++		 * Reasoning goes like this: if we have the wrong lock,
++		 * q->lock_ptr must have changed (maybe several times)
++		 * between reading it and the spin_lock().  It can
++		 * change again after the spin_lock() but only if it was
++		 * already changed before the spin_lock().  It cannot,
++		 * however, change back to the original value.  Therefore
++		 * we can detect whether we acquired the correct lock.
++		 */
++		if (unlikely(lock_ptr != q->lock_ptr)) {
++			spin_unlock(lock_ptr);
++			goto retry;
++		}
++		if (likely(!list_empty(&q->list))) {
++			list_del(&q->list);
++			ret = 1;
++		}
++		spin_unlock(lock_ptr);
+ 	}
+-	spin_unlock(&bh->lock);
++
++	drop_key_refs(&q->key);
+ 	return ret;
+ }
+ 
+@@ -358,19 +445,15 @@ static int futex_wait(unsigned long uadd
+ {
+ 	DECLARE_WAITQUEUE(wait, current);
+ 	int ret, curval;
+-	union futex_key key;
+ 	struct futex_q q;
+-	struct futex_hash_bucket *bh = NULL;
+-
+-	init_waitqueue_head(&q.waiters);
+ 
+ 	down_read(&current->mm->mmap_sem);
+ 
+-	ret = get_futex_key(uaddr, &key);
++	ret = get_futex_key(uaddr, &q.key);
+ 	if (unlikely(ret != 0))
+ 		goto out_release_sem;
+ 
+-	queue_me(&q, &key, -1, NULL);
++	queue_me(&q, -1, NULL);
+ 
+ 	/*
+ 	 * Access the page after the futex is queued.
+@@ -400,23 +483,17 @@ static int futex_wait(unsigned long uadd
+ 	 * rely on the futex_wake() code removing us from hash when it
+ 	 * wakes us up.
+ 	 */
+-	add_wait_queue(&q.waiters, &wait);
+-	bh = hash_futex(&key);
+-	spin_lock(&bh->lock);
+-	set_current_state(TASK_INTERRUPTIBLE);
+-
+-	if (unlikely(list_empty(&q.list))) {
+-		/*
+-		 * We were woken already.
+-		 */
+-		spin_unlock(&bh->lock);
+-		set_current_state(TASK_RUNNING);
+-		return 0;
+-	}
+ 
+-	spin_unlock(&bh->lock);
+-	time = schedule_timeout(time);
+-	set_current_state(TASK_RUNNING);
++	/* add_wait_queue is the barrier after __set_current_state. */
++	__set_current_state(TASK_INTERRUPTIBLE);
++	add_wait_queue(&q.waiters, &wait);
++	/*
++	 * !list_empty() is safe here without any lock.
++	 * q.lock_ptr != 0 is not safe, because of ordering against wakeup.
++	 */
++	if (likely(!list_empty(&q.list)))
++		time = schedule_timeout(time);
++	__set_current_state(TASK_RUNNING);
+ 
+ 	/*
+ 	 * NOTE: we don't remove ourselves from the waitqueue because
+@@ -446,7 +523,7 @@ static int futex_close(struct inode *ino
+ 	struct futex_q *q = filp->private_data;
+ 
+ 	unqueue_me(q);
+-	kfree(filp->private_data);
++	kfree(q);
+ 	return 0;
+ }
+ 
+@@ -455,14 +532,16 @@ static unsigned int futex_poll(struct fi
+ 			       struct poll_table_struct *wait)
+ {
+ 	struct futex_q *q = filp->private_data;
+-	struct futex_hash_bucket *bh = hash_futex(&q->key);
+ 	int ret = 0;
+ 
+ 	poll_wait(filp, &q->waiters, wait);
+-	spin_lock(&bh->lock);
++
++	/*
++	 * list_empty() is safe here without any lock.
++	 * q->lock_ptr != 0 is not safe, because of ordering against wakeup.
++	 */
+ 	if (list_empty(&q->list))
+ 		ret = POLLIN | POLLRDNORM;
+-	spin_unlock(&bh->lock);
+ 
+ 	return ret;
+ }
+@@ -472,12 +551,13 @@ static struct file_operations futex_fops
+ 	.poll		= futex_poll,
+ };
+ 
+-/* Signal allows caller to avoid the race which would occur if they
+-   set the sigio stuff up afterwards. */
++/*
++ * Signal allows caller to avoid the race which would occur if they
++ * set the sigio stuff up afterwards.
++ */
+ static int futex_fd(unsigned long uaddr, int signal)
+ {
+ 	struct futex_q *q;
+-	union futex_key key;
+ 	struct file *filp;
+ 	int ret, err;
+ 
+@@ -497,6 +577,7 @@ static int futex_fd(unsigned long uaddr,
+ 	filp->f_op = &futex_fops;
+ 	filp->f_vfsmnt = mntget(futex_mnt);
+ 	filp->f_dentry = dget(futex_mnt->mnt_root);
++	filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+ 
+ 	if (signal) {
+ 		int err;
+@@ -519,20 +600,24 @@ static int futex_fd(unsigned long uaddr,
+ 	}
+ 
+ 	down_read(&current->mm->mmap_sem);
+-	err = get_futex_key(uaddr, &key);
+-	up_read(&current->mm->mmap_sem);
++	err = get_futex_key(uaddr, &q->key);
+ 
+ 	if (unlikely(err != 0)) {
++		up_read(&current->mm->mmap_sem);
+ 		put_unused_fd(ret);
+ 		put_filp(filp);
+ 		kfree(q);
+ 		return err;
+ 	}
+ 
+-	init_waitqueue_head(&q->waiters);
++	/*
++	 * queue_me() must be called before releasing mmap_sem, because
++	 * key->shared.inode needs to be referenced while holding it.
++	 */
+ 	filp->private_data = q;
+ 
+-	queue_me(q, &key, ret, filp);
++	queue_me(q, ret, filp);
++	up_read(&current->mm->mmap_sem);
+ 
+ 	/* Now we map fd to filp, so userspace can access it */
+ 	fd_install(ret, filp);
+--- linux-2.6.0-test6/kernel/kmod.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/kernel/kmod.c	2003-10-05 00:36:10.000000000 -0700
+@@ -47,7 +47,8 @@ char modprobe_path[256] = "/sbin/modprob
+ 
+ /**
+  * request_module - try to load a kernel module
+- * @module_name: Name of module
++ * @fmt:     printf style format string for the name of the module
++ * @varargs: arguements as specified in the format string
+  *
+  * Load a module using the user mode module loader. The function returns
+  * zero on success or a negative errno code on failure. Note that a
+@@ -184,14 +185,19 @@ static int wait_for_helper(void *data)
+ 
+ 	sub_info->retval = 0;
+ 	pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
+-	if (pid < 0)
++	if (pid < 0) {
+ 		sub_info->retval = pid;
+-	else
++	} else {
+ 		/* We don't have a SIGCHLD signal handler, so this
+ 		 * always returns -ECHILD, but the important thing is
+ 		 * that it blocks. */
+-		sys_wait4(pid, NULL, 0, NULL);
++		mm_segment_t fs;
+ 
++		fs = get_fs();
++		set_fs(KERNEL_DS);
++		sys_wait4(pid, &sub_info->retval, 0, NULL);
++		set_fs(fs);
++	}
+ 	complete(sub_info->complete);
+ 	return 0;
+ }
+@@ -209,7 +215,7 @@ static void __call_usermodehelper(void *
+ 	 * until that is done.  */
+ 	if (sub_info->wait)
+ 		pid = kernel_thread(wait_for_helper, sub_info,
+-				    CLONE_KERNEL | SIGCHLD);
++				    CLONE_FS | CLONE_FILES | SIGCHLD);
+ 	else
+ 		pid = kernel_thread(____call_usermodehelper, sub_info,
+ 				    CLONE_VFORK | SIGCHLD);
+--- linux-2.6.0-test6/kernel/ksyms.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/ksyms.c	2003-10-05 00:36:58.000000000 -0700
+@@ -45,8 +45,6 @@
+ #include <linux/uio.h>
+ #include <linux/tty.h>
+ #include <linux/in6.h>
+-#include <linux/completion.h>
+-#include <linux/seq_file.h>
+ #include <linux/binfmts.h>
+ #include <linux/namei.h>
+ #include <linux/buffer_head.h>
+@@ -126,11 +124,11 @@ EXPORT_SYMBOL(get_unmapped_area);
+ EXPORT_SYMBOL(init_mm);
+ EXPORT_SYMBOL(blk_queue_bounce);
+ EXPORT_SYMBOL(blk_congestion_wait);
++EXPORT_SYMBOL(blk_congestion_wait_wq);
+ #ifdef CONFIG_HIGHMEM
+ EXPORT_SYMBOL(kmap_high);
+ EXPORT_SYMBOL(kunmap_high);
+ EXPORT_SYMBOL(highmem_start_page);
+-EXPORT_SYMBOL(kmap_prot);
+ EXPORT_SYMBOL(kmap_pte);
+ #endif
+ #ifdef HASHED_PAGE_VIRTUAL
+@@ -139,49 +137,12 @@ EXPORT_SYMBOL(page_address);
+ EXPORT_SYMBOL(get_user_pages);
+ 
+ /* filesystem internal functions */
+-EXPORT_SYMBOL(def_blk_fops);
+-EXPORT_SYMBOL(update_atime);
+ EXPORT_SYMBOL(get_fs_type);
+-EXPORT_SYMBOL(user_get_super);
+-EXPORT_SYMBOL(get_super);
+-EXPORT_SYMBOL(drop_super);
+-EXPORT_SYMBOL(getname);
+-EXPORT_SYMBOL(names_cachep);
+ EXPORT_SYMBOL(fput);
+ EXPORT_SYMBOL(fget);
+-EXPORT_SYMBOL(igrab);
+-EXPORT_SYMBOL(iunique);
+-EXPORT_SYMBOL(iput);
+-EXPORT_SYMBOL(inode_init_once);
+-EXPORT_SYMBOL(follow_up);
+-EXPORT_SYMBOL(follow_down);
+ EXPORT_SYMBOL(lookup_mnt);
+-EXPORT_SYMBOL(lookup_create);
+-EXPORT_SYMBOL(path_lookup);
+-EXPORT_SYMBOL(path_walk);
+-EXPORT_SYMBOL(path_release);
+-EXPORT_SYMBOL(__user_walk);
+-EXPORT_SYMBOL(lookup_one_len);
+-EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
+-EXPORT_SYMBOL(d_alloc_root);
+-EXPORT_SYMBOL(d_delete);
+-EXPORT_SYMBOL(dget_locked);
+-EXPORT_SYMBOL(d_validate);
+-EXPORT_SYMBOL(d_rehash);
+-EXPORT_SYMBOL(d_invalidate);	/* May be it will be better in dcache.h? */
+-EXPORT_SYMBOL(d_move);
+-EXPORT_SYMBOL(d_instantiate);
+-EXPORT_SYMBOL(d_alloc);
+-EXPORT_SYMBOL(d_alloc_anon);
+-EXPORT_SYMBOL(d_splice_alias);
+-EXPORT_SYMBOL(d_lookup);
+-EXPORT_SYMBOL(d_path);
+-EXPORT_SYMBOL(mark_buffer_dirty);
+-EXPORT_SYMBOL(end_buffer_read_sync);
+-EXPORT_SYMBOL(end_buffer_write_sync);
+-EXPORT_SYMBOL(end_buffer_async_write);
+ EXPORT_SYMBOL(__mark_inode_dirty);
+ EXPORT_SYMBOL(get_empty_filp);
+ EXPORT_SYMBOL(open_private_file);
+@@ -190,79 +151,20 @@ EXPORT_SYMBOL(filp_open);
+ EXPORT_SYMBOL(filp_close);
+ EXPORT_SYMBOL(put_filp);
+ EXPORT_SYMBOL(files_lock);
+-EXPORT_SYMBOL(check_disk_change);
+-EXPORT_SYMBOL(invalidate_bdev);
+-EXPORT_SYMBOL(invalidate_inodes);
+-EXPORT_SYMBOL(__invalidate_device);
+ EXPORT_SYMBOL(invalidate_inode_pages);
+ EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
+ EXPORT_SYMBOL(truncate_inode_pages);
+-EXPORT_SYMBOL(fsync_bdev);
+-EXPORT_SYMBOL(permission);
+-EXPORT_SYMBOL(vfs_permission);
+ EXPORT_SYMBOL(inode_setattr);
+ EXPORT_SYMBOL(inode_change_ok);
+ EXPORT_SYMBOL(write_inode_now);
+ EXPORT_SYMBOL(notify_change);
+-EXPORT_SYMBOL(set_blocksize);
+-EXPORT_SYMBOL(sb_set_blocksize);
+-EXPORT_SYMBOL(sb_min_blocksize);
+-EXPORT_SYMBOL(bdget);
+-EXPORT_SYMBOL(bdput);
+-EXPORT_SYMBOL(bd_claim);
+-EXPORT_SYMBOL(bd_release);
+-EXPORT_SYMBOL(open_bdev_excl);
+-EXPORT_SYMBOL(close_bdev_excl);
+-EXPORT_SYMBOL(open_by_devnum);
+-EXPORT_SYMBOL(__brelse);
+-EXPORT_SYMBOL(__bforget);
+-EXPORT_SYMBOL(ll_rw_block);
+-EXPORT_SYMBOL(sync_dirty_buffer);
+-EXPORT_SYMBOL(submit_bh);
+-EXPORT_SYMBOL(unlock_buffer);
+-EXPORT_SYMBOL(__wait_on_buffer);
+-EXPORT_SYMBOL(blockdev_direct_IO);
+-EXPORT_SYMBOL(block_write_full_page);
+-EXPORT_SYMBOL(block_read_full_page);
+-EXPORT_SYMBOL(block_prepare_write);
+-EXPORT_SYMBOL(block_sync_page);
+-EXPORT_SYMBOL(generic_cont_expand);
+-EXPORT_SYMBOL(cont_prepare_write);
+-EXPORT_SYMBOL(generic_commit_write);
+-EXPORT_SYMBOL(block_commit_write);
+-EXPORT_SYMBOL(block_truncate_page);
+-EXPORT_SYMBOL(generic_block_bmap);
+-EXPORT_SYMBOL(generic_file_read);
+-EXPORT_SYMBOL(generic_file_sendfile);
+-EXPORT_SYMBOL(do_generic_mapping_read);
+ EXPORT_SYMBOL(file_ra_state_init);
+-EXPORT_SYMBOL(generic_file_write);
+-EXPORT_SYMBOL(generic_file_write_nolock);
+-EXPORT_SYMBOL(generic_file_mmap);
+-EXPORT_SYMBOL(generic_file_readonly_mmap);
+ EXPORT_SYMBOL(generic_ro_fops);
+-EXPORT_SYMBOL(dput);
+-EXPORT_SYMBOL(have_submounts);
+-EXPORT_SYMBOL(d_find_alias);
+-EXPORT_SYMBOL(d_prune_aliases);
+-EXPORT_SYMBOL(shrink_dcache_sb);
+-EXPORT_SYMBOL(shrink_dcache_parent);
+-EXPORT_SYMBOL(shrink_dcache_anon);
+-EXPORT_SYMBOL(find_inode_number);
+-EXPORT_SYMBOL(is_subdir);
+ EXPORT_SYMBOL(get_unused_fd);
+ EXPORT_SYMBOL(vfs_read);
+ EXPORT_SYMBOL(vfs_readv);
+ EXPORT_SYMBOL(vfs_write);
+ EXPORT_SYMBOL(vfs_writev);
+-EXPORT_SYMBOL(vfs_create);
+-EXPORT_SYMBOL(vfs_mkdir);
+-EXPORT_SYMBOL(vfs_mknod);
+-EXPORT_SYMBOL(vfs_symlink);
+-EXPORT_SYMBOL(vfs_link);
+-EXPORT_SYMBOL(vfs_rmdir);
+-EXPORT_SYMBOL(vfs_unlink);
+-EXPORT_SYMBOL(vfs_rename);
+ EXPORT_SYMBOL(vfs_statfs);
+ EXPORT_SYMBOL(vfs_fstat);
+ EXPORT_SYMBOL(vfs_stat);
+@@ -272,9 +174,6 @@ EXPORT_SYMBOL(inode_add_bytes);
+ EXPORT_SYMBOL(inode_sub_bytes);
+ EXPORT_SYMBOL(inode_get_bytes);
+ EXPORT_SYMBOL(inode_set_bytes);
+-EXPORT_SYMBOL(lock_rename);
+-EXPORT_SYMBOL(unlock_rename);
+-EXPORT_SYMBOL(generic_read_dir);
+ EXPORT_SYMBOL(generic_fillattr);
+ EXPORT_SYMBOL(generic_file_llseek);
+ EXPORT_SYMBOL(remote_llseek);
+@@ -282,70 +181,21 @@ EXPORT_SYMBOL(no_llseek);
+ EXPORT_SYMBOL(poll_initwait);
+ EXPORT_SYMBOL(poll_freewait);
+ EXPORT_SYMBOL(ROOT_DEV);
+-EXPORT_SYMBOL(find_get_page);
+-EXPORT_SYMBOL(find_lock_page);
+-EXPORT_SYMBOL(find_trylock_page);
+-EXPORT_SYMBOL(find_or_create_page);
+-EXPORT_SYMBOL(grab_cache_page_nowait);
+-EXPORT_SYMBOL(read_cache_page);
+ EXPORT_SYMBOL(read_cache_pages);
+ EXPORT_SYMBOL(mark_page_accessed);
+-EXPORT_SYMBOL(vfs_readlink);
+-EXPORT_SYMBOL(vfs_follow_link);
+-EXPORT_SYMBOL(page_readlink);
+-EXPORT_SYMBOL(page_follow_link);
+-EXPORT_SYMBOL(page_symlink_inode_operations);
+-EXPORT_SYMBOL(page_symlink);
+ EXPORT_SYMBOL(vfs_readdir);
+ EXPORT_SYMBOL(__break_lease);
+ EXPORT_SYMBOL(lease_get_mtime);
+ EXPORT_SYMBOL(lock_may_read);
+ EXPORT_SYMBOL(lock_may_write);
+-EXPORT_SYMBOL(dcache_dir_open);
+-EXPORT_SYMBOL(dcache_dir_close);
+-EXPORT_SYMBOL(dcache_dir_lseek);
+-EXPORT_SYMBOL(dcache_readdir);
+-EXPORT_SYMBOL(simple_getattr);
+-EXPORT_SYMBOL(simple_statfs);
+-EXPORT_SYMBOL(simple_lookup);
+-EXPORT_SYMBOL(simple_dir_operations);
+-EXPORT_SYMBOL(simple_dir_inode_operations);
+-EXPORT_SYMBOL(simple_link);
+-EXPORT_SYMBOL(simple_unlink);
+-EXPORT_SYMBOL(simple_rmdir);
+-EXPORT_SYMBOL(simple_rename);
+-EXPORT_SYMBOL(simple_sync_file);
+-EXPORT_SYMBOL(simple_readpage);
+-EXPORT_SYMBOL(simple_prepare_write);
+-EXPORT_SYMBOL(simple_commit_write);
+-EXPORT_SYMBOL(simple_empty);
+-EXPORT_SYMBOL(simple_fill_super);
+-EXPORT_SYMBOL(simple_pin_fs);
+-EXPORT_SYMBOL(simple_release_fs);
+ EXPORT_SYMBOL(fd_install);
+ EXPORT_SYMBOL(put_unused_fd);
+-EXPORT_SYMBOL(get_sb_bdev);
+-EXPORT_SYMBOL(kill_block_super);
+-EXPORT_SYMBOL(get_sb_nodev);
+-EXPORT_SYMBOL(get_sb_single);
+-EXPORT_SYMBOL(kill_anon_super);
+-EXPORT_SYMBOL(kill_litter_super);
+-EXPORT_SYMBOL(generic_shutdown_super);
+-EXPORT_SYMBOL(deactivate_super);
+-EXPORT_SYMBOL(sget);
+-EXPORT_SYMBOL(set_anon_super);
+ EXPORT_SYMBOL(do_select);
+ 
+ /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
+ EXPORT_SYMBOL(default_llseek);
+ EXPORT_SYMBOL(dentry_open);
+-#ifdef CONFIG_MMU
+-EXPORT_SYMBOL(filemap_nopage);
+-#endif
+-EXPORT_SYMBOL(filemap_fdatawrite);
+-EXPORT_SYMBOL(filemap_fdatawait);
+ EXPORT_SYMBOL(lock_page);
+-EXPORT_SYMBOL(unlock_page);
+ 
+ /* device registration */
+ EXPORT_SYMBOL(register_blkdev);
+@@ -355,16 +205,7 @@ EXPORT_SYMBOL(tty_unregister_driver);
+ EXPORT_SYMBOL(tty_std_termios);
+ 
+ /* block device driver support */
+-EXPORT_SYMBOL(bmap);
+-EXPORT_SYMBOL(blkdev_open);
+-EXPORT_SYMBOL(blkdev_get);
+-EXPORT_SYMBOL(blkdev_put);
+-EXPORT_SYMBOL(ioctl_by_bdev);
+ EXPORT_SYMBOL(read_dev_sector);
+-EXPORT_SYMBOL(init_buffer);
+-EXPORT_SYMBOL_GPL(generic_file_direct_IO);
+-EXPORT_SYMBOL(generic_file_readv);
+-EXPORT_SYMBOL(generic_file_writev);
+ EXPORT_SYMBOL(iov_shorten);
+ EXPORT_SYMBOL_GPL(default_backing_dev_info);
+ 
+@@ -375,32 +216,9 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
+ /* filesystem registration */
+ EXPORT_SYMBOL(register_filesystem);
+ EXPORT_SYMBOL(unregister_filesystem);
+-EXPORT_SYMBOL(kern_mount);
+ EXPORT_SYMBOL(__mntput);
+ EXPORT_SYMBOL(may_umount);
+ 
+-/* executable format registration */
+-EXPORT_SYMBOL(register_binfmt);
+-EXPORT_SYMBOL(unregister_binfmt);
+-EXPORT_SYMBOL(search_binary_handler);
+-EXPORT_SYMBOL(prepare_binprm);
+-EXPORT_SYMBOL(compute_creds);
+-EXPORT_SYMBOL(remove_arg_zero);
+-EXPORT_SYMBOL(set_binfmt);
+-
+-/* sysctl table registration */
+-EXPORT_SYMBOL(register_sysctl_table);
+-EXPORT_SYMBOL(unregister_sysctl_table);
+-EXPORT_SYMBOL(sysctl_string);
+-EXPORT_SYMBOL(sysctl_intvec);
+-EXPORT_SYMBOL(sysctl_jiffies);
+-EXPORT_SYMBOL(proc_dostring);
+-EXPORT_SYMBOL(proc_dointvec);
+-EXPORT_SYMBOL(proc_dointvec_jiffies);
+-EXPORT_SYMBOL(proc_dointvec_minmax);
+-EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
+-EXPORT_SYMBOL(proc_doulongvec_minmax);
+-
+ /* interrupt handling */
+ EXPORT_SYMBOL(request_irq);
+ EXPORT_SYMBOL(free_irq);
+@@ -414,10 +232,6 @@ EXPORT_SYMBOL(prepare_to_wait_exclusive)
+ EXPORT_SYMBOL(finish_wait);
+ EXPORT_SYMBOL(autoremove_wake_function);
+ 
+-/* completion handling */
+-EXPORT_SYMBOL(wait_for_completion);
+-EXPORT_SYMBOL(complete);
+-
+ /* The notion of irq probe/assignment is foreign to S/390 */
+ 
+ #if !defined(CONFIG_ARCH_S390)
+@@ -449,30 +263,11 @@ EXPORT_SYMBOL(iomem_resource);
+ 
+ /* process management */
+ EXPORT_SYMBOL(complete_and_exit);
+-EXPORT_SYMBOL(default_wake_function);
+-EXPORT_SYMBOL(__wake_up);
+ #ifdef CONFIG_SMP
+ EXPORT_SYMBOL_GPL(__wake_up_sync); /* internal use only */
+ #endif
+-EXPORT_SYMBOL(wake_up_process);
+-EXPORT_SYMBOL(sleep_on);
+-EXPORT_SYMBOL(sleep_on_timeout);
+-EXPORT_SYMBOL(interruptible_sleep_on);
+-EXPORT_SYMBOL(interruptible_sleep_on_timeout);
+-EXPORT_SYMBOL(schedule);
+-#ifdef CONFIG_PREEMPT
+-EXPORT_SYMBOL(preempt_schedule);
+-#endif
+ EXPORT_SYMBOL(schedule_timeout);
+-EXPORT_SYMBOL(yield);
+-EXPORT_SYMBOL(io_schedule);
+-EXPORT_SYMBOL(__cond_resched);
+-EXPORT_SYMBOL(set_user_nice);
+-EXPORT_SYMBOL(task_nice);
+ EXPORT_SYMBOL_GPL(idle_cpu);
+-#ifdef CONFIG_SMP
+-EXPORT_SYMBOL_GPL(set_cpus_allowed);
+-#endif
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+ EXPORT_SYMBOL(kernel_flag);
+ #endif
+@@ -485,18 +280,10 @@ EXPORT_SYMBOL(do_settimeofday);
+ #if (BITS_PER_LONG < 64)
+ EXPORT_SYMBOL(get_jiffies_64);
+ #endif
+-#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
+-EXPORT_SYMBOL(__might_sleep);
+-#endif
+-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
+-EXPORT_SYMBOL(__preempt_spin_lock);
+-EXPORT_SYMBOL(__preempt_write_lock);
+-#endif
+ #if !defined(__ia64__)
+ EXPORT_SYMBOL(loops_per_jiffy);
+ #endif
+ 
+-
+ /* misc */
+ EXPORT_SYMBOL(panic);
+ EXPORT_SYMBOL(panic_notifier_list);
+@@ -524,45 +311,16 @@ EXPORT_SYMBOL(securebits);
+ EXPORT_SYMBOL(cap_bset);
+ EXPORT_SYMBOL(daemonize);
+ EXPORT_SYMBOL(csum_partial); /* for networking and md */
+-EXPORT_SYMBOL(seq_escape);
+-EXPORT_SYMBOL(seq_printf);
+-EXPORT_SYMBOL(seq_path);
+-EXPORT_SYMBOL(seq_open);
+-EXPORT_SYMBOL(seq_release);
+-EXPORT_SYMBOL(seq_read);
+-EXPORT_SYMBOL(seq_lseek);
+-EXPORT_SYMBOL(single_open);
+-EXPORT_SYMBOL(single_release);
+-EXPORT_SYMBOL(seq_release_private);
+-
+-/* Program loader interfaces */
+-#ifdef CONFIG_MMU
+-EXPORT_SYMBOL(setup_arg_pages);
+-#endif
+-EXPORT_SYMBOL(copy_strings_kernel);
+-EXPORT_SYMBOL(do_execve);
+-EXPORT_SYMBOL(flush_old_exec);
+-EXPORT_SYMBOL(kernel_read);
+-EXPORT_SYMBOL(open_exec);
+ 
+ /* Miscellaneous access points */
+ EXPORT_SYMBOL(si_meminfo);
+ 
+ /* Added to make file system as module */
+ EXPORT_SYMBOL(sys_tz);
+-EXPORT_SYMBOL(file_fsync);
+-EXPORT_SYMBOL(fsync_buffers_list);
+-EXPORT_SYMBOL(clear_inode);
+-EXPORT_SYMBOL(init_special_inode);
+-EXPORT_SYMBOL(new_inode);
+-EXPORT_SYMBOL(__insert_inode_hash);
+-EXPORT_SYMBOL(remove_inode_hash);
+-EXPORT_SYMBOL(buffer_insert_list);
+ EXPORT_SYMBOL(make_bad_inode);
+ EXPORT_SYMBOL(is_bad_inode);
+ EXPORT_SYMBOL(__inode_dir_notify);
+ EXPORT_SYMBOL(generic_osync_inode);
+-EXPORT_SYMBOL(remove_suid);
+ 
+ #ifdef CONFIG_UID16
+ EXPORT_SYMBOL(overflowuid);
+@@ -575,9 +333,6 @@ EXPORT_SYMBOL(fs_overflowgid);
+ EXPORT_SYMBOL(fasync_helper);
+ EXPORT_SYMBOL(kill_fasync);
+ 
+-/* binfmt_aout */
+-EXPORT_SYMBOL(get_write_access);
+-
+ /* library functions */
+ EXPORT_SYMBOL(strnicmp);
+ EXPORT_SYMBOL(strspn);
+@@ -607,6 +362,16 @@ EXPORT_SYMBOL(__per_cpu_offset);
+ EXPORT_SYMBOL(set_fs_pwd);
+ EXPORT_SYMBOL(set_fs_root);
+ 
++#if defined(CONFIG_LOCKMETER)
++EXPORT_SYMBOL(_metered_spin_lock);
++EXPORT_SYMBOL(_metered_spin_unlock);
++EXPORT_SYMBOL(_metered_spin_trylock);
++EXPORT_SYMBOL(_metered_read_lock);
++EXPORT_SYMBOL(_metered_read_unlock);
++EXPORT_SYMBOL(_metered_write_lock);
++EXPORT_SYMBOL(_metered_write_unlock);
++#endif
++
+ /* debug */
+ EXPORT_SYMBOL(dump_stack);
+ EXPORT_SYMBOL(ptrace_notify);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/kernel/lockmeter.c	2003-10-05 00:36:40.000000000 -0700
+@@ -0,0 +1,1169 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.c by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com)
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ */
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/threads.h>
++#include <linux/version.h>
++#include <linux/vmalloc.h>
++#include <linux/spinlock.h>
++#include <linux/utsname.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++
++#include <linux/lockmeter.h>
++
++#define ASSERT(cond)
++#define bzero(loc,size)		memset(loc,0,size)
++
++/*<---------------------------------------------------*/
++/*              lockmeter.c                           */
++/*>---------------------------------------------------*/
++
++static lstat_control_t lstat_control __cacheline_aligned =
++	{ LSTAT_OFF, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED,
++	  19 * 0, NR_CPUS * 0, 0, NR_CPUS * 0 };
++
++static ushort lstat_make_dir_entry(void *, void *);
++
++/*
++ * lstat_lookup
++ *
++ * Given a RA, locate the directory entry for the lock.
++ */
++static ushort
++lstat_lookup(void *lock_ptr, void *caller_ra)
++{
++	ushort index;
++	lstat_directory_entry_t *dirp;
++
++	dirp = lstat_control.dir;
++
++	index = lstat_control.hashtab[DIRHASH(caller_ra)];
++	while (dirp[index].caller_ra != caller_ra) {
++		if (index == 0) {
++			return lstat_make_dir_entry(lock_ptr, caller_ra);
++		}
++		index = dirp[index].next_stat_index;
++	}
++
++	if (dirp[index].lock_ptr != NULL && dirp[index].lock_ptr != lock_ptr) {
++		dirp[index].lock_ptr = NULL;
++	}
++
++	return index;
++}
++
++/*
++ * lstat_make_dir_entry
++ * Called to add a new lock to the lock directory.
++ */
++static ushort
++lstat_make_dir_entry(void *lock_ptr, void *caller_ra)
++{
++	lstat_directory_entry_t *dirp;
++	ushort index, hindex;
++	unsigned long flags;
++
++	/* lock the table without recursively reentering this metering code */
++	local_irq_save(flags);
++	_raw_spin_lock(&lstat_control.directory_lock);
++
++	hindex = DIRHASH(caller_ra);
++	index = lstat_control.hashtab[hindex];
++	dirp = lstat_control.dir;
++	while (index && dirp[index].caller_ra != caller_ra)
++		index = dirp[index].next_stat_index;
++
++	if (index == 0) {
++		if (lstat_control.next_free_dir_index < LSTAT_MAX_STAT_INDEX) {
++			index = lstat_control.next_free_dir_index++;
++			lstat_control.dir[index].caller_ra = caller_ra;
++			lstat_control.dir[index].lock_ptr = lock_ptr;
++			lstat_control.dir[index].next_stat_index =
++				lstat_control.hashtab[hindex];
++			lstat_control.hashtab[hindex] = index;
++		} else {
++			lstat_control.dir_overflow++;
++		}
++	}
++	_raw_spin_unlock(&lstat_control.directory_lock);
++	local_irq_restore(flags);
++	return index;
++}
++
++int
++lstat_update(void *lock_ptr, void *caller_ra, int action)
++{
++	int index;
++	int cpu;
++
++	ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++	if (lstat_control.state == LSTAT_OFF)
++		return 0;
++
++	index = lstat_lookup(lock_ptr, caller_ra);
++	cpu = THIS_CPU_NUMBER;
++	(*lstat_control.counts[cpu])[index].count[action]++;
++	(*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++	return index;
++}
++
++int
++lstat_update_time(void *lock_ptr, void *caller_ra, int action, uint32_t ticks)
++{
++	ushort index;
++	int cpu;
++
++	ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++	if (lstat_control.state == LSTAT_OFF)
++		return 0;
++
++	index = lstat_lookup(lock_ptr, caller_ra);
++	cpu = THIS_CPU_NUMBER;
++	(*lstat_control.counts[cpu])[index].count[action]++;
++	(*lstat_control.counts[cpu])[index].cum_wait_ticks += (uint64_t) ticks;
++	if ((*lstat_control.counts[cpu])[index].max_wait_ticks < ticks)
++		(*lstat_control.counts[cpu])[index].max_wait_ticks = ticks;
++
++	(*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++	return index;
++}
++
++void
++_metered_spin_lock(spinlock_t * lock_ptr)
++{
++	if (lstat_control.state == LSTAT_OFF) {
++		_raw_spin_lock(lock_ptr);	/* do the real lock */
++		PUT_INDEX(lock_ptr, 0);	/* clean index in case lockmetering  */
++		/* gets turned on before unlock */
++	} else {
++		void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++		int index;
++
++		if (_raw_spin_trylock(lock_ptr)) {
++			index = lstat_update(lock_ptr, this_pc,
++						LSTAT_ACT_NO_WAIT);
++		} else {
++			uint32_t start_cycles = get_cycles();
++			_raw_spin_lock(lock_ptr);	/* do the real lock */
++			index = lstat_update_time(lock_ptr, this_pc,
++				LSTAT_ACT_SPIN, get_cycles() - start_cycles);
++		}
++		/* save the index in the lock itself for use in spin unlock */
++		PUT_INDEX(lock_ptr, index);
++	}
++}
++
++int
++_metered_spin_trylock(spinlock_t * lock_ptr)
++{
++	if (lstat_control.state == LSTAT_OFF) {
++		return _raw_spin_trylock(lock_ptr);
++	} else {
++		int retval;
++		void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++
++		if ((retval = _raw_spin_trylock(lock_ptr))) {
++			int index = lstat_update(lock_ptr, this_pc,
++						LSTAT_ACT_NO_WAIT);
++			/*
++			 * save the index in the lock itself for use in spin
++			 * unlock
++			 */
++			PUT_INDEX(lock_ptr, index);
++		} else {
++			lstat_update(lock_ptr, this_pc, LSTAT_ACT_REJECT);
++		}
++
++		return retval;
++	}
++}
++
++void
++_metered_spin_unlock(spinlock_t * lock_ptr)
++{
++	int index = -1;
++
++	if (lstat_control.state != LSTAT_OFF) {
++		index = GET_INDEX(lock_ptr);
++		/*
++		 * If statistics were turned off when we set the lock,
++		 * then the index can be zero.  If that is the case,
++		 * then collect no stats on this call.
++		 */
++		if (index > 0) {
++			uint32_t hold_time;
++			int cpu = THIS_CPU_NUMBER;
++			hold_time = get_cycles() -
++			 (*lstat_control.counts[cpu])[index].acquire_time;
++			(*lstat_control.counts[cpu])[index].cum_hold_ticks +=
++				(uint64_t) hold_time;
++			if ((*lstat_control.counts[cpu])[index].max_hold_ticks <
++			    hold_time)
++				(*lstat_control.counts[cpu])[index].
++				    max_hold_ticks = hold_time;
++		}
++	}
++
++	/* make sure we don't have a stale index value saved */
++	PUT_INDEX(lock_ptr, 0);
++	_raw_spin_unlock(lock_ptr);	/* do the real unlock */
++}
++
++/*
++ * allocate the next global read lock structure and store its index
++ * in the rwlock at "lock_ptr".
++ */
++uint32_t
++alloc_rwlock_struct(rwlock_t * rwlock_ptr)
++{
++	int index;
++	unsigned long flags;
++	int cpu = THIS_CPU_NUMBER;
++
++	/* If we've already overflowed, then do a quick exit */
++	if (lstat_control.next_free_read_lock_index >
++			LSTAT_MAX_READ_LOCK_INDEX) {
++		lstat_control.rwlock_overflow++;
++		return 0;
++	}
++
++	local_irq_save(flags);
++	_raw_spin_lock(&lstat_control.directory_lock);
++
++	/* It is possible this changed while we were waiting for the directory_lock */
++	if (lstat_control.state == LSTAT_OFF) {
++		index = 0;
++		goto unlock;
++	}
++
++	/* It is possible someone else got here first and set the index */
++	if ((index = GET_RWINDEX(rwlock_ptr)) == 0) {
++		/*
++		 * we can't turn on read stats for this lock while there are
++		 * readers (this would mess up the running hold time sum at
++		 * unlock time)
++		 */
++		if (RWLOCK_READERS(rwlock_ptr) != 0) {
++			index = 0;
++			goto unlock;
++		}
++
++		/*
++		 * if stats are turned on after being off, we may need to
++		 * return an old index from when the statistics were on last
++		 * time.
++		 */
++		for (index = 1; index < lstat_control.next_free_read_lock_index;
++				index++)
++			if ((*lstat_control.read_lock_counts[cpu])[index].
++					lock_ptr == rwlock_ptr)
++				goto put_index_and_unlock;
++
++		/* allocate the next global read lock structure */
++		if (lstat_control.next_free_read_lock_index >=
++		    LSTAT_MAX_READ_LOCK_INDEX) {
++			lstat_control.rwlock_overflow++;
++			index = 0;
++			goto unlock;
++		}
++		index = lstat_control.next_free_read_lock_index++;
++
++		/*
++		 * initialize the global read stats data structure for each
++		 * cpu
++		 */
++		for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++			(*lstat_control.read_lock_counts[cpu])[index].lock_ptr =
++				rwlock_ptr;
++		}
++put_index_and_unlock:
++		/* store the index for the read lock structure into the lock */
++		PUT_RWINDEX(rwlock_ptr, index);
++	}
++
++unlock:
++	_raw_spin_unlock(&lstat_control.directory_lock);
++	local_irq_restore(flags);
++	return index;
++}
++
++void
++_metered_read_lock(rwlock_t * rwlock_ptr)
++{
++	void *this_pc;
++	uint32_t start_cycles;
++	int index;
++	int cpu;
++	unsigned long flags;
++	int readers_before, readers_after;
++	uint64_t cycles64;
++
++	if (lstat_control.state == LSTAT_OFF) {
++		_raw_read_lock(rwlock_ptr);
++		/* clean index in case lockmetering turns on before an unlock */
++		PUT_RWINDEX(rwlock_ptr, 0);
++		return;
++	}
++
++	this_pc = LSTAT_RA(LSTAT_RA_READ);
++	cpu = THIS_CPU_NUMBER;
++	index = GET_RWINDEX(rwlock_ptr);
++
++	/* allocate the global stats entry for this lock, if needed */
++	if (index == 0)
++		index = alloc_rwlock_struct(rwlock_ptr);
++
++	readers_before = RWLOCK_READERS(rwlock_ptr);
++	if (_raw_read_trylock(rwlock_ptr)) {
++		/*
++		 * We have decremented the lock to count a new reader,
++		 * and have confirmed that no writer has it locked.
++		 */
++		/* update statistics if enabled */
++		if (index > 0) {
++			local_irq_save(flags);
++			lstat_update((void *) rwlock_ptr, this_pc,
++					LSTAT_ACT_NO_WAIT);
++			/* preserve value of TSC so cum_hold_ticks and start_busy use same value */
++			cycles64 = get_cycles64();
++			(*lstat_control.read_lock_counts[cpu])[index].
++				cum_hold_ticks -= cycles64;
++
++			/* record time and cpu of start of busy period */
++			/* this is not perfect (some race conditions are possible) */
++			if (readers_before == 0) {
++				(*lstat_control.read_lock_counts[cpu])[index].
++					start_busy = cycles64;
++				PUT_RW_CPU(rwlock_ptr, cpu);
++			}
++			readers_after = RWLOCK_READERS(rwlock_ptr);
++			if (readers_after >
++				(*lstat_control.read_lock_counts[cpu])[index].
++					max_readers)
++				(*lstat_control.read_lock_counts[cpu])[index].
++					max_readers = readers_after;
++			local_irq_restore(flags);
++		}
++
++		return;
++	}
++	/* If we get here, then we could not quickly grab the read lock */
++
++	start_cycles = get_cycles();	/* start counting the wait time */
++
++	/* Now spin until read_lock is successful */
++	_raw_read_lock(rwlock_ptr);
++
++	lstat_update_time((void *) rwlock_ptr, this_pc, LSTAT_ACT_SPIN,
++			  get_cycles() - start_cycles);
++
++	/* update statistics if they are enabled for this lock */
++	if (index > 0) {
++		local_irq_save(flags);
++		cycles64 = get_cycles64();
++		(*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks -=
++				cycles64;
++
++		/* this is not perfect (some race conditions are possible) */
++		if (readers_before == 0) {
++			(*lstat_control.read_lock_counts[cpu])[index].
++				start_busy = cycles64;
++			PUT_RW_CPU(rwlock_ptr, cpu);
++		}
++		readers_after = RWLOCK_READERS(rwlock_ptr);
++		if (readers_after >
++		    (*lstat_control.read_lock_counts[cpu])[index].max_readers)
++			(*lstat_control.read_lock_counts[cpu])[index].
++				max_readers = readers_after;
++		local_irq_restore(flags);
++	}
++}
++
++void
++_metered_read_unlock(rwlock_t * rwlock_ptr)
++{
++	int index;
++	int cpu;
++	unsigned long flags;
++	uint64_t busy_length;
++	uint64_t cycles64;
++
++	if (lstat_control.state == LSTAT_OFF) {
++		_raw_read_unlock(rwlock_ptr);
++		return;
++	}
++
++	index = GET_RWINDEX(rwlock_ptr);
++	cpu = THIS_CPU_NUMBER;
++
++	if (index > 0) {
++		local_irq_save(flags);
++		/*
++		 * preserve value of TSC so cum_hold_ticks and busy_ticks are
++		 * consistent.
++		 */
++		cycles64 = get_cycles64();
++		(*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks +=
++			cycles64;
++		(*lstat_control.read_lock_counts[cpu])[index].read_lock_count++;
++
++		/*
++		 * once again, this is not perfect (some race conditions are
++		 * possible)
++		 */
++		if (RWLOCK_READERS(rwlock_ptr) == 1) {
++			int cpu1 = GET_RW_CPU(rwlock_ptr);
++			uint64_t last_start_busy =
++				(*lstat_control.read_lock_counts[cpu1])[index].
++					start_busy;
++			(*lstat_control.read_lock_counts[cpu])[index].
++				busy_periods++;
++			if (cycles64 > last_start_busy) {
++				busy_length = cycles64 - last_start_busy;
++				(*lstat_control.read_lock_counts[cpu])[index].
++					busy_ticks += busy_length;
++				if (busy_length >
++					(*lstat_control.
++						read_lock_counts[cpu])[index].
++							max_busy)
++					(*lstat_control.
++					 read_lock_counts[cpu])[index].
++						max_busy = busy_length;
++			}
++		}
++		local_irq_restore(flags);
++	}
++	_raw_read_unlock(rwlock_ptr);
++}
++
++void
++_metered_write_lock(rwlock_t * rwlock_ptr)
++{
++	uint32_t start_cycles;
++	void *this_pc;
++	uint32_t spin_ticks = 0; /* in anticipation of a potential wait */
++	int index;
++	int write_index = 0;
++	int cpu;
++	enum {
++		writer_writer_conflict,
++		writer_reader_conflict
++	} why_wait = writer_writer_conflict;
++
++	if (lstat_control.state == LSTAT_OFF) {
++		_raw_write_lock(rwlock_ptr);
++		/* clean index in case lockmetering turns on before an unlock */
++		PUT_RWINDEX(rwlock_ptr, 0);
++		return;
++	}
++
++	this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++	cpu = THIS_CPU_NUMBER;
++	index = GET_RWINDEX(rwlock_ptr);
++
++	/* allocate the global stats entry for this lock, if needed */
++	if (index == 0) {
++		index = alloc_rwlock_struct(rwlock_ptr);
++	}
++
++	if (_raw_write_trylock(rwlock_ptr)) {
++		/* We acquired the lock on the first try */
++		write_index = lstat_update((void *) rwlock_ptr, this_pc,
++					LSTAT_ACT_NO_WAIT);
++		/* save the write_index for use in unlock if stats enabled */
++		if (index > 0)
++			(*lstat_control.read_lock_counts[cpu])[index].
++				write_index = write_index;
++		return;
++	}
++
++	/* If we get here, then we could not quickly grab the write lock */
++	start_cycles = get_cycles();	/* start counting the wait time */
++
++	why_wait = RWLOCK_READERS(rwlock_ptr) ?
++			writer_reader_conflict : writer_writer_conflict;
++
++	/* Now set the lock and wait for conflicts to disappear */
++	_raw_write_lock(rwlock_ptr);
++
++	spin_ticks = get_cycles() - start_cycles;
++
++	/* update stats -- if enabled */
++	if (index > 0 && spin_ticks) {
++		if (why_wait == writer_reader_conflict) {
++			/* waited due to a reader holding the lock */
++			write_index = lstat_update_time((void *)rwlock_ptr,
++					this_pc, LSTAT_ACT_SPIN, spin_ticks);
++		} else {
++			/*
++			 * waited due to another writer holding the lock
++			 */
++			write_index = lstat_update_time((void *)rwlock_ptr,
++				this_pc, LSTAT_ACT_WW_SPIN, spin_ticks);
++			(*lstat_control.counts[cpu])[write_index].
++				cum_wait_ww_ticks += spin_ticks;
++			if (spin_ticks >
++				(*lstat_control.counts[cpu])[write_index].
++					max_wait_ww_ticks) {
++				(*lstat_control.counts[cpu])[write_index].
++					max_wait_ww_ticks = spin_ticks;
++			}
++		}
++
++		/* save the directory index for use on write_unlock */
++		(*lstat_control.read_lock_counts[cpu])[index].
++			write_index = write_index;
++	}
++}
++
++void
++_metered_write_unlock(rwlock_t * rwlock_ptr)
++{
++	int index;
++	int cpu;
++	int write_index;
++	uint32_t hold_time;
++
++	if (lstat_control.state == LSTAT_OFF) {
++		_raw_write_unlock(rwlock_ptr);
++		return;
++	}
++
++	cpu = THIS_CPU_NUMBER;
++	index = GET_RWINDEX(rwlock_ptr);
++
++	/* update statistics if stats enabled for this lock */
++	if (index > 0) {
++		write_index =
++		    (*lstat_control.read_lock_counts[cpu])[index].write_index;
++
++		hold_time = get_cycles() -
++			(*lstat_control.counts[cpu])[write_index].acquire_time;
++		(*lstat_control.counts[cpu])[write_index].cum_hold_ticks +=
++			(uint64_t) hold_time;
++		if ((*lstat_control.counts[cpu])[write_index].max_hold_ticks <
++				hold_time)
++			(*lstat_control.counts[cpu])[write_index].
++				max_hold_ticks = hold_time;
++	}
++	_raw_write_unlock(rwlock_ptr);
++}
++
++int
++_metered_write_trylock(rwlock_t * rwlock_ptr)
++{
++	int retval;
++	void *this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++
++	if ((retval = _raw_write_trylock(rwlock_ptr))) {
++		lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_NO_WAIT);
++	} else {
++		lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_REJECT);
++	}
++
++	return retval;
++}
++
++static void
++init_control_space(void)
++{
++	/* Set all control space pointers to null and indices to "empty" */
++	int cpu;
++
++	/*
++	 * Access CPU_CYCLE_FREQUENCY at the outset, which in some
++	 * architectures may trigger a runtime calculation that uses a
++	 * spinlock.  Let's do this before lockmetering is turned on.
++	 */
++	if (CPU_CYCLE_FREQUENCY == 0)
++		BUG();
++
++	lstat_control.hashtab = NULL;
++	lstat_control.dir = NULL;
++	for (cpu = 0; cpu < NR_CPUS; cpu++) {
++		lstat_control.counts[cpu] = NULL;
++		lstat_control.read_lock_counts[cpu] = NULL;
++	}
++}
++
++static int
++reset_lstat_data(void)
++{
++	int cpu, flags;
++
++	flags = 0;
++	lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
++	lstat_control.next_free_read_lock_index = 1;
++	lstat_control.dir_overflow = 0;
++	lstat_control.rwlock_overflow = 0;
++
++	lstat_control.started_cycles64 = 0;
++	lstat_control.ending_cycles64 = 0;
++	lstat_control.enabled_cycles64 = 0;
++	lstat_control.first_started_time = 0;
++	lstat_control.started_time = 0;
++	lstat_control.ending_time = 0;
++	lstat_control.intervals = 0;
++
++	/*
++	 * paranoia -- in case someone does a "lockstat reset" before
++	 * "lockstat on"
++	 */
++	if (lstat_control.hashtab) {
++		bzero(lstat_control.hashtab,
++			LSTAT_HASH_TABLE_SIZE * sizeof (short));
++		bzero(lstat_control.dir, LSTAT_MAX_STAT_INDEX *
++				sizeof (lstat_directory_entry_t));
++
++		for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++			bzero(lstat_control.counts[cpu],
++				sizeof (lstat_cpu_counts_t));
++			bzero(lstat_control.read_lock_counts[cpu],
++				sizeof (lstat_read_lock_cpu_counts_t));
++		}
++	}
++#ifdef NOTDEF
++	_raw_spin_unlock(&lstat_control.directory_lock);
++	local_irq_restore(flags);
++#endif
++	return 1;
++}
++
++static void
++release_control_space(void)
++{
++	/*
++	 * Called when either (1) allocation of kmem
++	 * or (2) when user writes LSTAT_RELEASE to /pro/lockmeter.
++	 * Assume that all pointers have been initialized to zero,
++	 * i.e., nonzero pointers are valid addresses.
++	 */
++	int cpu;
++
++	if (lstat_control.hashtab) {
++		kfree(lstat_control.hashtab);
++		lstat_control.hashtab = NULL;
++	}
++
++	if (lstat_control.dir) {
++		vfree(lstat_control.dir);
++		lstat_control.dir = NULL;
++	}
++
++	for (cpu = 0; cpu < NR_CPUS; cpu++) {
++		if (lstat_control.counts[cpu]) {
++			vfree(lstat_control.counts[cpu]);
++			lstat_control.counts[cpu] = NULL;
++		}
++		if (lstat_control.read_lock_counts[cpu]) {
++			kfree(lstat_control.read_lock_counts[cpu]);
++			lstat_control.read_lock_counts[cpu] = NULL;
++		}
++	}
++}
++
++int
++get_lockmeter_info_size(void)
++{
++	return sizeof (lstat_user_request_t)
++		+ num_online_cpus() * sizeof (lstat_cpu_counts_t)
++		+ num_online_cpus() * sizeof (lstat_read_lock_cpu_counts_t)
++		+ (LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t));
++}
++
++ssize_t
++get_lockmeter_info(char *buffer, size_t max_len, loff_t * last_index)
++{
++	lstat_user_request_t req;
++	struct timeval tv;
++	ssize_t next_ret_bcount;
++	ssize_t actual_ret_bcount = 0;
++	int cpu;
++
++	*last_index = 0;	/* a one-shot read */
++
++	req.lstat_version = LSTAT_VERSION;
++	req.state = lstat_control.state;
++	req.maxcpus = num_online_cpus();
++	req.cycleval = CPU_CYCLE_FREQUENCY;
++#ifdef notyet
++	req.kernel_magic_addr = (void *) &_etext;
++	req.kernel_end_addr = (void *) &_etext;
++#endif
++	req.uts = system_utsname;
++	req.intervals = lstat_control.intervals;
++
++	req.first_started_time = lstat_control.first_started_time;
++	req.started_time = lstat_control.started_time;
++	req.started_cycles64 = lstat_control.started_cycles64;
++
++	req.next_free_dir_index = lstat_control.next_free_dir_index;
++	req.next_free_read_lock_index = lstat_control.next_free_read_lock_index;
++	req.dir_overflow = lstat_control.dir_overflow;
++	req.rwlock_overflow = lstat_control.rwlock_overflow;
++
++	if (lstat_control.state == LSTAT_OFF) {
++		if (req.intervals == 0) {
++			/* mesasurement is off and no valid data present */
++			next_ret_bcount = sizeof (lstat_user_request_t);
++			req.enabled_cycles64 = 0;
++
++			if ((actual_ret_bcount + next_ret_bcount) > max_len)
++				return actual_ret_bcount;
++
++			copy_to_user(buffer, (void *) &req, next_ret_bcount);
++			actual_ret_bcount += next_ret_bcount;
++			return actual_ret_bcount;
++		} else {
++			/*
++			 * measurement is off but valid data present
++			 * fetch time info from lstat_control
++			 */
++			req.ending_time = lstat_control.ending_time;
++			req.ending_cycles64 = lstat_control.ending_cycles64;
++			req.enabled_cycles64 = lstat_control.enabled_cycles64;
++		}
++	} else {
++		/*
++		 * this must be a read while data active--use current time,
++		 * etc
++		 */
++		do_gettimeofday(&tv);
++		req.ending_time = tv.tv_sec;
++		req.ending_cycles64 = get_cycles64();
++		req.enabled_cycles64 = req.ending_cycles64 -
++			req.started_cycles64 + lstat_control.enabled_cycles64;
++	}
++
++	next_ret_bcount = sizeof (lstat_user_request_t);
++	if ((actual_ret_bcount + next_ret_bcount) > max_len)
++		return actual_ret_bcount;
++
++	copy_to_user(buffer, (void *) &req, next_ret_bcount);
++	actual_ret_bcount += next_ret_bcount;
++
++	if (!lstat_control.counts[0])	/* not initialized? */
++		return actual_ret_bcount;
++
++	next_ret_bcount = sizeof (lstat_cpu_counts_t);
++	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++		if ((actual_ret_bcount + next_ret_bcount) > max_len)
++			return actual_ret_bcount;	/* leave early */
++		copy_to_user(buffer + actual_ret_bcount,
++				lstat_control.counts[cpu], next_ret_bcount);
++		actual_ret_bcount += next_ret_bcount;
++	}
++
++	next_ret_bcount = LSTAT_MAX_STAT_INDEX *
++			sizeof (lstat_directory_entry_t);
++	if (((actual_ret_bcount + next_ret_bcount) > max_len)
++			|| !lstat_control.dir)
++		return actual_ret_bcount;	/* leave early */
++
++	copy_to_user(buffer + actual_ret_bcount, lstat_control.dir,
++			next_ret_bcount);
++	actual_ret_bcount += next_ret_bcount;
++
++	next_ret_bcount = sizeof (lstat_read_lock_cpu_counts_t);
++	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++		if (actual_ret_bcount + next_ret_bcount > max_len)
++			return actual_ret_bcount;
++		copy_to_user(buffer + actual_ret_bcount,
++				lstat_control.read_lock_counts[cpu],
++				next_ret_bcount);
++		actual_ret_bcount += next_ret_bcount;
++	}
++
++	return actual_ret_bcount;
++}
++
++/*
++ *  Writing to the /proc lockmeter node enables or disables metering.
++ *  based upon the first byte of the "written" data.
++ *  The following values are defined:
++ *  LSTAT_ON: 1st call: allocates storage, intializes and turns on measurement
++ *            subsequent calls just turn on measurement
++ *  LSTAT_OFF: turns off measurement
++ *  LSTAT_RESET: resets statistics
++ *  LSTAT_RELEASE: releases statistics storage
++ *
++ *  This allows one to accumulate statistics over several lockstat runs:
++ *
++ *  lockstat on
++ *  lockstat off
++ *  ...repeat above as desired...
++ *  lockstat get
++ *  ...now start a new set of measurements...
++ *  lockstat reset
++ *  lockstat on
++ *  ...
++ *
++ */
++ssize_t
++put_lockmeter_info(const char *buffer, size_t len)
++{
++	int error = 0;
++	int dirsize, countsize, read_lock_countsize, hashsize;
++	int cpu;
++	char put_char;
++	int i, read_lock_blocks;
++	unsigned long flags;
++	rwlock_t *lock_ptr;
++	struct timeval tv;
++
++	if (len <= 0)
++		return -EINVAL;
++
++	_raw_spin_lock(&lstat_control.control_lock);
++
++	get_user(put_char, buffer);
++	switch (put_char) {
++
++	case LSTAT_OFF:
++		if (lstat_control.state != LSTAT_OFF) {
++			/*
++			 * To avoid seeing read lock hold times in an
++			 * inconsisent state, we have to follow this protocol
++			 * to turn off statistics
++			 */
++			local_irq_save(flags);
++			/*
++			 * getting this lock will stop any read lock block
++			 * allocations
++			 */
++			_raw_spin_lock(&lstat_control.directory_lock);
++			/*
++			 * keep any more read lock blocks from being
++			 * allocated
++			 */
++			lstat_control.state = LSTAT_OFF;
++			/* record how may read lock blocks there are */
++			read_lock_blocks =
++				lstat_control.next_free_read_lock_index;
++			_raw_spin_unlock(&lstat_control.directory_lock);
++			/* now go through the list of read locks */
++			cpu = THIS_CPU_NUMBER;
++			for (i = 1; i < read_lock_blocks; i++) {
++				lock_ptr =
++				    (*lstat_control.read_lock_counts[cpu])[i].
++				    lock_ptr;
++				/* is this saved lock address still valid? */
++				if (GET_RWINDEX(lock_ptr) == i) {
++					/*
++					 * lock address appears to still be
++					 * valid because we only hold one lock
++					 * at a time, this can't cause a
++					 * deadlock unless this is a lock held
++					 * as part of the current system call
++					 * path. At the moment there
++					 * are no READ mode locks held to get
++					 * here from user space, so we solve
++					 * this by skipping locks held in
++					 * write mode.
++					 */
++					if (RWLOCK_IS_WRITE_LOCKED(lock_ptr)) {
++						PUT_RWINDEX(lock_ptr, 0);
++						continue;
++					}
++					/*
++					 * now we know there are no read
++					 * holders of this lock! stop
++					 * statistics collection for this
++					 * lock
++					 */
++					_raw_write_lock(lock_ptr);
++					PUT_RWINDEX(lock_ptr, 0);
++					_raw_write_unlock(lock_ptr);
++				}
++				/*
++				 * it may still be possible for the hold time
++				 * sum to be negative e.g. if a lock is
++				 * reallocated while "busy" we will have to fix
++				 * this up in the data reduction program.
++				 */
++			}
++			local_irq_restore(flags);
++			lstat_control.intervals++;
++			lstat_control.ending_cycles64 = get_cycles64();
++			lstat_control.enabled_cycles64 +=
++				lstat_control.ending_cycles64 -
++				lstat_control.started_cycles64;
++			do_gettimeofday(&tv);
++			lstat_control.ending_time = tv.tv_sec;
++			/*
++			 * don't deallocate the structures -- we may do a
++			 * lockstat on to add to the data that is already
++			 * there. Use LSTAT_RELEASE to release storage
++			 */
++		} else {
++			error = -EBUSY;	/* already OFF */
++		}
++		break;
++
++	case LSTAT_ON:
++		if (lstat_control.state == LSTAT_OFF) {
++#ifdef DEBUG_LOCKMETER
++			printk("put_lockmeter_info(cpu=%d): LSTAT_ON\n",
++				THIS_CPU_NUMBER);
++#endif
++			lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
++
++			dirsize = LSTAT_MAX_STAT_INDEX *
++					sizeof (lstat_directory_entry_t);
++			hashsize =
++				(1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++			countsize = sizeof (lstat_cpu_counts_t);
++			read_lock_countsize =
++				sizeof (lstat_read_lock_cpu_counts_t);
++#ifdef DEBUG_LOCKMETER
++			printk(" dirsize:%d", dirsize);
++			printk(" hashsize:%d", hashsize);
++			printk(" countsize:%d", countsize);
++			printk(" read_lock_countsize:%d\n",
++				read_lock_countsize);
++#endif
++#ifdef DEBUG_LOCKMETER
++			{
++				int secs;
++				unsigned long cycles;
++				uint64_t cycles64;
++
++				do_gettimeofday(&tv);
++				secs = tv.tv_sec;
++				do {
++					do_gettimeofday(&tv);
++				} while (secs == tv.tv_sec);
++				cycles = get_cycles();
++				cycles64 = get_cycles64();
++				secs = tv.tv_sec;
++				do {
++					do_gettimeofday(&tv);
++				} while (secs == tv.tv_sec);
++				cycles = get_cycles() - cycles;
++				cycles64 = get_cycles64() - cycles;
++				printk("lockmeter: cycleFrequency:%d "
++					"cycles:%d cycles64:%d\n",
++					CPU_CYCLE_FREQUENCY, cycles, cycles64);
++			}
++#endif
++
++			/*
++			 * if this is the first call, allocate storage and
++			 * initialize
++			 */
++			if (!lstat_control.hashtab) {
++
++				spin_lock_init(&lstat_control.directory_lock);
++
++				/* guarantee all pointers at zero */
++				init_control_space();
++
++				lstat_control.hashtab =
++				    kmalloc(hashsize, GFP_KERNEL);
++				if (!lstat_control.hashtab) {
++					error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++					printk("!!error kmalloc of hashtab\n");
++#endif
++				}
++				lstat_control.dir = vmalloc(dirsize);
++				if (!lstat_control.dir) {
++					error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++					printk("!!error kmalloc of dir\n");
++#endif
++				}
++
++				for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++					lstat_control.counts[cpu] =
++						vmalloc(countsize);
++					if (!lstat_control.counts[cpu]) {
++						error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++						printk("!!error vmalloc of "
++							"counts[%d]\n", cpu);
++#endif
++					}
++					lstat_control.read_lock_counts[cpu] =
++						(lstat_read_lock_cpu_counts_t *)
++						kmalloc(read_lock_countsize,
++							GFP_KERNEL);
++					if (!lstat_control.
++							read_lock_counts[cpu]) {
++						error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++						printk("!!error kmalloc of "
++						  "read_lock_counts[%d]\n",
++							cpu);
++#endif
++					}
++				}
++			}
++
++			if (error) {
++				/*
++				 * One or more kmalloc failures -- free
++				 * everything
++				 */
++				release_control_space();
++			} else {
++
++				if (!reset_lstat_data()) {
++					error = -EINVAL;
++					break;
++				};
++
++				/*
++				 * record starting and ending times and the
++				 * like
++				 */
++				if (lstat_control.intervals == 0) {
++					do_gettimeofday(&tv);
++					lstat_control.first_started_time =
++						tv.tv_sec;
++				}
++				lstat_control.started_cycles64 = get_cycles64();
++				do_gettimeofday(&tv);
++				lstat_control.started_time = tv.tv_sec;
++
++				lstat_control.state = LSTAT_ON;
++			}
++		} else {
++			error = -EBUSY;	/* already ON */
++		}
++		break;
++
++	case LSTAT_RESET:
++		if (lstat_control.state == LSTAT_OFF) {
++			if (!reset_lstat_data())
++				error = -EINVAL;
++		} else {
++			error = -EBUSY;	/* still on; can't reset */
++		}
++		break;
++
++	case LSTAT_RELEASE:
++		if (lstat_control.state == LSTAT_OFF) {
++			release_control_space();
++			lstat_control.intervals = 0;
++			lstat_control.enabled_cycles64 = 0;
++		} else {
++			error = -EBUSY;
++		}
++		break;
++
++	default:
++		error = -EINVAL;
++	}			/* switch */
++
++	_raw_spin_unlock(&lstat_control.control_lock);
++	return error ? error : len;
++}
++
++#ifdef USER_MODE_TESTING
++/* following used for user mode testing */
++void
++lockmeter_init()
++{
++	int dirsize, hashsize, countsize, read_lock_countsize, cpu;
++
++	printf("lstat_control is at %x size=%d\n", &lstat_control,
++		sizeof (lstat_control));
++	printf("sizeof(spinlock_t)=%d\n", sizeof (spinlock_t));
++	lstat_control.state = LSTAT_ON;
++
++	lstat_control.directory_lock = SPIN_LOCK_UNLOCKED;
++	lstat_control.next_free_dir_index = 1;	/* 0 is for overflows */
++	lstat_control.next_free_read_lock_index = 1;
++
++	dirsize = LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t);
++	hashsize = (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++	countsize = sizeof (lstat_cpu_counts_t);
++	read_lock_countsize = sizeof (lstat_read_lock_cpu_counts_t);
++
++	lstat_control.hashtab = (ushort *) malloc(hashsize);
++
++	if (lstat_control.hashtab == 0) {
++		printf("malloc failure for at line %d in lockmeter.c\n",
++			__LINE__);
++		exit(0);
++	}
++
++	lstat_control.dir = (lstat_directory_entry_t *) malloc(dirsize);
++
++	if (lstat_control.dir == 0) {
++		printf("malloc failure for at line %d in lockmeter.c\n", cpu,
++			__LINE__);
++		exit(0);
++	}
++
++	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++		int j, k;
++		j = (int) (lstat_control.counts[cpu] =
++			   (lstat_cpu_counts_t *) malloc(countsize));
++		k = (int) (lstat_control.read_lock_counts[cpu] =
++			   (lstat_read_lock_cpu_counts_t *)
++			   malloc(read_lock_countsize));
++		if (j * k == 0) {
++			printf("malloc failure for cpu=%d at line %d in "
++				"lockmeter.c\n", cpu, __LINE__);
++			exit(0);
++		}
++	}
++
++	memset(lstat_control.hashtab, 0, hashsize);
++	memset(lstat_control.dir, 0, dirsize);
++
++	for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++		memset(lstat_control.counts[cpu], 0, countsize);
++		memset(lstat_control.read_lock_counts[cpu], 0,
++			read_lock_countsize);
++	}
++}
++
++asm(" \
++.align	4 \
++.globl	__write_lock_failed \
++__write_lock_failed: \
++	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax) \
++1:	cmpl	$" RW_LOCK_BIAS_STR ",(%eax) \
++	jne	1b \
++\
++	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax) \
++	jnz	__write_lock_failed \
++	ret \
++\
++\
++.align	4 \
++.globl	__read_lock_failed \
++__read_lock_failed: \
++	lock ; incl	(%eax) \
++1:	cmpl	$1,(%eax) \
++	js	1b \
++\
++	lock ; decl	(%eax) \
++	js	__read_lock_failed \
++	ret \
++");
++#endif
+--- linux-2.6.0-test6/kernel/Makefile	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/Makefile	2003-10-05 00:36:40.000000000 -0700
+@@ -11,6 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o
+ obj-$(CONFIG_FUTEX) += futex.o
+ obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+ obj-$(CONFIG_SMP) += cpu.o
++obj-$(CONFIG_LOCKMETER) += lockmeter.o
+ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_MODULES) += ksyms.o module.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+--- linux-2.6.0-test6/kernel/module.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/kernel/module.c	2003-10-05 00:33:25.000000000 -0700
+@@ -844,6 +844,7 @@ int set_obsolete(const char *val, struct
+ {
+ 	unsigned int min, max;
+ 	unsigned int size, maxsize;
++	int dummy;
+ 	char *endp;
+ 	const char *p;
+ 	struct obsolete_modparm *obsparm = kp->arg;
+@@ -866,19 +867,19 @@ int set_obsolete(const char *val, struct
+ 	switch (*endp) {
+ 	case 'b':
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   1, param_set_byte);
++				   1, param_set_byte, &dummy);
+ 	case 'h':
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   sizeof(short), param_set_short);
++				   sizeof(short), param_set_short, &dummy);
+ 	case 'i':
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   sizeof(int), param_set_int);
++				   sizeof(int), param_set_int, &dummy);
+ 	case 'l':
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   sizeof(long), param_set_long);
++				   sizeof(long), param_set_long, &dummy);
+ 	case 's':
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   sizeof(char *), param_set_charp);
++				   sizeof(char *), param_set_charp, &dummy);
+ 
+ 	case 'c':
+ 		/* Undocumented: 1-5c50 means 1-5 strings of up to 49 chars,
+@@ -895,7 +896,7 @@ int set_obsolete(const char *val, struct
+ 		if (size >= maxsize) 
+ 			goto oversize;
+ 		return param_array(kp->name, val, min, max, obsparm->addr,
+-				   maxsize, obsparm_copy_string);
++				   maxsize, obsparm_copy_string, &dummy);
+ 	}
+ 	printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type);
+ 	return -EINVAL;
+--- linux-2.6.0-test6/kernel/params.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/kernel/params.c	2003-10-05 00:33:25.000000000 -0700
+@@ -242,10 +242,10 @@ int param_array(const char *name,
+ 		const char *val,
+ 		unsigned int min, unsigned int max,
+ 		void *elem, int elemsize,
+-		int (*set)(const char *, struct kernel_param *kp))
++		int (*set)(const char *, struct kernel_param *kp),
++		int *num)
+ {
+ 	int ret;
+-	unsigned int count = 0;
+ 	struct kernel_param kp;
+ 	char save;
+ 
+@@ -259,11 +259,12 @@ int param_array(const char *name,
+ 		return -EINVAL;
+ 	}
+ 
++	*num = 0;
+ 	/* We expect a comma-separated list of values. */
+ 	do {
+ 		int len;
+ 
+-		if (count > max) {
++		if (*num == max) {
+ 			printk(KERN_ERR "%s: can only take %i arguments\n",
+ 			       name, max);
+ 			return -EINVAL;
+@@ -279,10 +280,10 @@ int param_array(const char *name,
+ 			return ret;
+ 		kp.arg += elemsize;
+ 		val += len+1;
+-		count++;
++		(*num)++;
+ 	} while (save == ',');
+ 
+-	if (count < min) {
++	if (*num < min) {
+ 		printk(KERN_ERR "%s: needs at least %i arguments\n",
+ 		       name, min);
+ 		return -EINVAL;
+@@ -290,29 +291,32 @@ int param_array(const char *name,
+ 	return 0;
+ }
+ 
+-/* First two elements are the max and min array length (which don't change) */
+-int param_set_intarray(const char *val, struct kernel_param *kp)
++int param_array_set(const char *val, struct kernel_param *kp)
+ {
+-	int *array;
++	struct kparam_array *arr = kp->arg;
+ 
+-	/* Grab min and max as first two elements */
+-	array = kp->arg;
+-	return param_array(kp->name, val, array[0], array[1], &array[2],
+-			   sizeof(int), param_set_int);
++	return param_array(kp->name, val, 1, arr->max, arr->elem,
++			   arr->elemsize, arr->set, arr->num);
+ }
+ 
+-int param_get_intarray(char *buffer, struct kernel_param *kp)
++int param_array_get(char *buffer, struct kernel_param *kp)
+ {
+-	int max;
+-	int *array;
+-	unsigned int i;
+-
+-	array = kp->arg;
+-	max = array[1];
+-
+-	for (i = 2; i < max + 2; i++)
+-		sprintf(buffer, "%s%i", i > 2 ? "," : "", array[i]);
+-	return strlen(buffer);
++	int i, off, ret;
++	struct kparam_array *arr = kp->arg;
++	struct kernel_param p;
++
++	p = *kp;
++	for (i = off = 0; i < *arr->num; i++) {
++		if (i)
++			buffer[off++] = ',';
++		p.arg = arr->elem + arr->elemsize * i;
++		ret = arr->get(buffer + off, &p);
++		if (ret < 0)
++			return ret;
++		off += ret;
++	}
++	buffer[off] = '\0';
++	return off;
+ }
+ 
+ int param_set_copystring(const char *val, struct kernel_param *kp)
+@@ -346,6 +350,6 @@ EXPORT_SYMBOL(param_set_bool);
+ EXPORT_SYMBOL(param_get_bool);
+ EXPORT_SYMBOL(param_set_invbool);
+ EXPORT_SYMBOL(param_get_invbool);
+-EXPORT_SYMBOL(param_set_intarray);
+-EXPORT_SYMBOL(param_get_intarray);
++EXPORT_SYMBOL(param_array_set);
++EXPORT_SYMBOL(param_array_get);
+ EXPORT_SYMBOL(param_set_copystring);
+--- linux-2.6.0-test6/kernel/pid.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/pid.c	2003-10-05 00:36:15.000000000 -0700
+@@ -250,14 +250,14 @@ void switch_exec_pids(task_t *leader, ta
+ 
+ 	attach_pid(thread, PIDTYPE_PID, thread->pid);
+ 	attach_pid(thread, PIDTYPE_TGID, thread->tgid);
+-	attach_pid(thread, PIDTYPE_PGID, leader->__pgrp);
+-	attach_pid(thread, PIDTYPE_SID, thread->session);
++	attach_pid(thread, PIDTYPE_PGID, thread->signal->pgrp);
++	attach_pid(thread, PIDTYPE_SID, thread->signal->session);
+ 	list_add_tail(&thread->tasks, &init_task.tasks);
+ 
+ 	attach_pid(leader, PIDTYPE_PID, leader->pid);
+ 	attach_pid(leader, PIDTYPE_TGID, leader->tgid);
+-	attach_pid(leader, PIDTYPE_PGID, leader->__pgrp);
+-	attach_pid(leader, PIDTYPE_SID, leader->session);
++	attach_pid(leader, PIDTYPE_PGID, leader->signal->pgrp);
++	attach_pid(leader, PIDTYPE_SID, leader->signal->session);
+ }
+ 
+ /*
+@@ -265,6 +265,9 @@ void switch_exec_pids(task_t *leader, ta
+  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
+  * more.
+  */
++#ifdef CONFIG_KGDB
++int kgdb_pid_init_done; /* so we don't call prior to... */
++#endif
+ void __init pidhash_init(void)
+ {
+ 	int i, j, pidhash_size;
+@@ -286,6 +289,9 @@ void __init pidhash_init(void)
+ 		for (j = 0; j < pidhash_size; j++)
+ 			INIT_LIST_HEAD(&pid_hash[i][j]);
+ 	}
++#ifdef CONFIG_KGDB
++	kgdb_pid_init_done++;
++#endif
+ }
+ 
+ void __init pidmap_init(void)
+--- linux-2.6.0-test6/kernel/printk.c	2003-07-02 14:53:18.000000000 -0700
++++ 25/kernel/printk.c	2003-10-05 00:36:41.000000000 -0700
+@@ -29,11 +29,11 @@
+ #include <linux/delay.h>
+ #include <linux/smp.h>
+ #include <linux/security.h>
++#include <linux/bootmem.h>
+ 
+ #include <asm/uaccess.h>
+ 
+-#define LOG_BUF_LEN	(1 << CONFIG_LOG_BUF_SHIFT)
+-#define LOG_BUF_MASK	(LOG_BUF_LEN-1)
++#define __LOG_BUF_LEN	(1 << CONFIG_LOG_BUF_SHIFT)
+ 
+ /* printk's without a loglevel use this.. */
+ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
+@@ -68,17 +68,21 @@ struct console *console_drivers;
+  */
+ static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
+ 
+-static char log_buf[LOG_BUF_LEN];
++static char __log_buf[__LOG_BUF_LEN];
++static char *log_buf = __log_buf;
++static int log_buf_len = __LOG_BUF_LEN;
++
++#define LOG_BUF_MASK	(log_buf_len-1)
+ #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
+ 
+ /*
+- * The indices into log_buf are not constrained to LOG_BUF_LEN - they
++ * The indices into log_buf are not constrained to log_buf_len - they
+  * must be masked before subscripting
+  */
+-static unsigned long log_start;			/* Index into log_buf: next char to be read by syslog() */
+-static unsigned long con_start;			/* Index into log_buf: next char to be sent to consoles */
+-static unsigned long log_end;			/* Index into log_buf: most-recently-written-char + 1 */
+-static unsigned long logged_chars;		/* Number of chars produced since last read+clear operation */
++static unsigned long log_start;	/* Index into log_buf: next char to be read by syslog() */
++static unsigned long con_start;	/* Index into log_buf: next char to be sent to consoles */
++static unsigned long log_end;	/* Index into log_buf: most-recently-written-char + 1 */
++static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */
+ 
+ struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+ static int preferred_console = -1;
+@@ -141,6 +145,45 @@ static int __init console_setup(char *st
+ 
+ __setup("console=", console_setup);
+ 
++static int __init log_buf_len_setup(char *str)
++{
++	unsigned long size = memparse(str, &str);
++
++	if (size > log_buf_len) {
++		unsigned long start, dest_idx, offset;
++		char * new_log_buf;
++
++		new_log_buf = alloc_bootmem(size);
++		if (!new_log_buf) {
++			printk("log_buf_len: allocation failed\n");
++			goto out;
++		}
++
++		spin_lock_irq(&logbuf_lock);
++		log_buf_len = size;
++		log_buf = new_log_buf;
++
++		offset = start = min(con_start, log_start);
++		dest_idx = 0;
++		while (start != log_end) {
++			log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)];
++			start++;
++			dest_idx++;
++		}
++		log_start -= offset;
++		con_start -= offset;
++		log_end -= offset;
++		spin_unlock_irq(&logbuf_lock);
++
++		printk("log_buf_len: %d\n", log_buf_len);
++	}
++out:
++
++	return 1;
++}
++
++__setup("log_buf_len=", log_buf_len_setup);
++
+ /*
+  * Commands to do_syslog:
+  *
+@@ -213,8 +256,8 @@ int do_syslog(int type, char __user * bu
+ 		if (error)
+ 			goto out;
+ 		count = len;
+-		if (count > LOG_BUF_LEN)
+-			count = LOG_BUF_LEN;
++		if (count > log_buf_len)
++			count = log_buf_len;
+ 		spin_lock_irq(&logbuf_lock);
+ 		if (count > logged_chars)
+ 			count = logged_chars;
+@@ -229,7 +272,7 @@ int do_syslog(int type, char __user * bu
+ 		 */
+ 		for(i = 0; i < count && !error; i++) {
+ 			j = limit-1-i;
+-			if (j+LOG_BUF_LEN < log_end)
++			if (j + log_buf_len < log_end)
+ 				break;
+ 			c = LOG_BUF(j);
+ 			spin_unlock_irq(&logbuf_lock);
+@@ -302,12 +345,15 @@ static void __call_console_drivers(unsig
+ /*
+  * Write out chars from start to end - 1 inclusive
+  */
+-static void _call_console_drivers(unsigned long start, unsigned long end, int msg_log_level)
++static void _call_console_drivers(unsigned long start,
++				unsigned long end, int msg_log_level)
+ {
+-	if (msg_log_level < console_loglevel && console_drivers && start != end) {
++	if (msg_log_level < console_loglevel &&
++			console_drivers && start != end) {
+ 		if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
+ 			/* wrapped write */
+-			__call_console_drivers(start & LOG_BUF_MASK, LOG_BUF_LEN);
++			__call_console_drivers(start & LOG_BUF_MASK,
++						log_buf_len);
+ 			__call_console_drivers(0, end & LOG_BUF_MASK);
+ 		} else {
+ 			__call_console_drivers(start, end);
+@@ -370,11 +416,11 @@ static void emit_log_char(char c)
+ {
+ 	LOG_BUF(log_end) = c;
+ 	log_end++;
+-	if (log_end - log_start > LOG_BUF_LEN)
+-		log_start = log_end - LOG_BUF_LEN;
+-	if (log_end - con_start > LOG_BUF_LEN)
+-		con_start = log_end - LOG_BUF_LEN;
+-	if (logged_chars < LOG_BUF_LEN)
++	if (log_end - log_start > log_buf_len)
++		log_start = log_end - log_buf_len;
++	if (log_end - con_start > log_buf_len)
++		con_start = log_end - log_buf_len;
++	if (logged_chars < log_buf_len)
+ 		logged_chars++;
+ }
+ 
+@@ -399,9 +445,13 @@ asmlinkage int printk(const char *fmt, .
+ 	char *p;
+ 	static char printk_buf[1024];
+ 	static int log_level_unknown = 1;
++	static int printk_cpu = -1;
+ 
+-	if (oops_in_progress) {
+-		/* If a crash is occurring, make sure we can't deadlock */
++	if (oops_in_progress && printk_cpu == smp_processor_id()) {
++		/*
++		 * If a crash is occurring during printk() on this CPU, make
++		 * sure we can't deadlock
++		 */
+ 		spin_lock_init(&logbuf_lock);
+ 		/* And make sure that we print immediately */
+ 		init_MUTEX(&console_sem);
+@@ -409,6 +459,7 @@ asmlinkage int printk(const char *fmt, .
+ 
+ 	/* This stops the holder of console_sem just where we want him */
+ 	spin_lock_irqsave(&logbuf_lock, flags);
++	printk_cpu = smp_processor_id();
+ 
+ 	/* Emit the output into the temporary buffer */
+ 	va_start(args, fmt);
+--- linux-2.6.0-test6/kernel/ptrace.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/kernel/ptrace.c	2003-10-05 00:33:25.000000000 -0700
+@@ -179,19 +179,14 @@ int access_process_vm(struct task_struct
+ 
+ 		flush_cache_page(vma, addr);
+ 
+-		/*
+-		 * FIXME!  We used to have flush_page_to_ram() in here, but
+-		 * that was wrong.  davem says we need a new per-arch primitive
+-		 * to handle this correctly.
+-		 */
+-
+ 		maddr = kmap(page);
+ 		if (write) {
+-			memcpy(maddr + offset, buf, bytes);
+-			flush_icache_user_range(vma, page, addr, bytes);
++			copy_to_user_page(vma, page, addr,
++					  maddr + offset, buf, bytes);
+ 			set_page_dirty_lock(page);
+ 		} else {
+-			memcpy(buf, maddr + offset, bytes);
++			copy_from_user_page(vma, page, addr,
++					    buf, maddr + offset, bytes);
+ 		}
+ 		kunmap(page);
+ 		page_cache_release(page);
+--- linux-2.6.0-test6/kernel/rcupdate.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/kernel/rcupdate.c	2003-10-05 00:33:25.000000000 -0700
+@@ -15,7 +15,7 @@
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  *
+- * Copyright (c) IBM Corporation, 2001
++ * Copyright (C) IBM Corporation, 2001
+  *
+  * Author: Dipankar Sarma <dipankar@in.ibm.com>
+  * 
+--- linux-2.6.0-test6/kernel/sched.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/sched.c	2003-10-05 00:36:39.000000000 -0700
+@@ -18,6 +18,7 @@
+  */
+ 
+ #include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/nmi.h>
+ #include <linux/init.h>
+ #include <asm/uaccess.h>
+@@ -642,6 +643,8 @@ int wake_up_process(task_t * p)
+ 	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 0);
+ }
+ 
++EXPORT_SYMBOL(wake_up_process);
++
+ int wake_up_process_kick(task_t * p)
+ {
+ 	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 1);
+@@ -1585,6 +1588,8 @@ switch_tasks:
+ 		goto need_resched;
+ }
+ 
++EXPORT_SYMBOL(schedule);
++
+ #ifdef CONFIG_PREEMPT
+ /*
+  * this is is the entry point to schedule() from in-kernel preemption
+@@ -1612,6 +1617,8 @@ need_resched:
+ 	if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
+ 		goto need_resched;
+ }
++
++EXPORT_SYMBOL(preempt_schedule);
+ #endif /* CONFIG_PREEMPT */
+ 
+ int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
+@@ -1620,6 +1627,8 @@ int default_wake_function(wait_queue_t *
+ 	return try_to_wake_up(p, mode, sync, 0);
+ }
+ 
++EXPORT_SYMBOL(default_wake_function);
++
+ /*
+  * The core wakeup function.  Non-exclusive wakeups (nr_exclusive == 0) just
+  * wake everything up.  If it's an exclusive wakeup (nr_exclusive == small +ve
+@@ -1660,6 +1669,8 @@ void __wake_up(wait_queue_head_t *q, uns
+ 	spin_unlock_irqrestore(&q->lock, flags);
+ }
+ 
++EXPORT_SYMBOL(__wake_up);
++
+ /*
+  * Same as __wake_up but called with the spinlock in wait_queue_head_t held.
+  */
+@@ -1696,6 +1707,8 @@ void __wake_up_sync(wait_queue_head_t *q
+ 	spin_unlock_irqrestore(&q->lock, flags);
+ }
+ 
++EXPORT_SYMBOL(__wake_up_sync);
++
+ void complete(struct completion *x)
+ {
+ 	unsigned long flags;
+@@ -1706,6 +1719,8 @@ void complete(struct completion *x)
+ 	spin_unlock_irqrestore(&x->wait.lock, flags);
+ }
+ 
++EXPORT_SYMBOL(complete);
++
+ void complete_all(struct completion *x)
+ {
+ 	unsigned long flags;
+@@ -1737,6 +1752,8 @@ void wait_for_completion(struct completi
+ 	spin_unlock_irq(&x->wait.lock);
+ }
+ 
++EXPORT_SYMBOL(wait_for_completion);
++
+ #define	SLEEP_ON_VAR				\
+ 	unsigned long flags;			\
+ 	wait_queue_t wait;			\
+@@ -1763,6 +1780,8 @@ void interruptible_sleep_on(wait_queue_h
+ 	SLEEP_ON_TAIL
+ }
+ 
++EXPORT_SYMBOL(interruptible_sleep_on);
++
+ long interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
+ {
+ 	SLEEP_ON_VAR
+@@ -1776,6 +1795,8 @@ long interruptible_sleep_on_timeout(wait
+ 	return timeout;
+ }
+ 
++EXPORT_SYMBOL(interruptible_sleep_on_timeout);
++
+ void sleep_on(wait_queue_head_t *q)
+ {
+ 	SLEEP_ON_VAR
+@@ -1787,6 +1808,8 @@ void sleep_on(wait_queue_head_t *q)
+ 	SLEEP_ON_TAIL
+ }
+ 
++EXPORT_SYMBOL(sleep_on);
++
+ long sleep_on_timeout(wait_queue_head_t *q, long timeout)
+ {
+ 	SLEEP_ON_VAR
+@@ -1800,6 +1823,8 @@ long sleep_on_timeout(wait_queue_head_t 
+ 	return timeout;
+ }
+ 
++EXPORT_SYMBOL(sleep_on_timeout);
++
+ void scheduling_functions_end_here(void) { }
+ 
+ void set_user_nice(task_t *p, long nice)
+@@ -1849,6 +1874,15 @@ out_unlock:
+ 	task_rq_unlock(rq, &flags);
+ }
+ 
++EXPORT_SYMBOL(set_user_nice);
++
++#if defined( CONFIG_KGDB)
++struct task_struct * kgdb_get_idle(int this_cpu)
++{
++        return cpu_rq(this_cpu)->idle;
++}
++#endif
++
+ #ifndef __alpha__
+ 
+ /*
+@@ -1915,6 +1949,8 @@ int task_nice(task_t *p)
+ 	return TASK_NICE(p);
+ }
+ 
++EXPORT_SYMBOL(task_nice);
++
+ /**
+  * task_curr - is this task currently executing on a CPU?
+  * @p: the task in question.
+@@ -1933,6 +1969,8 @@ int idle_cpu(int cpu)
+ 	return cpu_curr(cpu) == cpu_rq(cpu)->idle;
+ }
+ 
++EXPORT_SYMBOL(idle_cpu);
++
+ /**
+  * find_process_by_pid - find a process with a matching PID value.
+  * @pid: the pid in question.
+@@ -2260,6 +2298,8 @@ void __cond_resched(void)
+ 	schedule();
+ }
+ 
++EXPORT_SYMBOL(__cond_resched);
++
+ /**
+  * yield - yield the current processor to other threads.
+  *
+@@ -2272,6 +2312,8 @@ void yield(void)
+ 	sys_sched_yield();
+ }
+ 
++EXPORT_SYMBOL(yield);
++
+ /*
+  * This task is about to go to sleep on IO.  Increment rq->nr_iowait so
+  * that process accounting knows that this is a task in IO wait state.
+@@ -2288,6 +2330,8 @@ void io_schedule(void)
+ 	atomic_dec(&rq->nr_iowait);
+ }
+ 
++EXPORT_SYMBOL(io_schedule);
++
+ long io_schedule_timeout(long timeout)
+ {
+ 	struct runqueue *rq = this_rq();
+@@ -2402,17 +2446,16 @@ static inline struct task_struct *younge
+ 
+ static void show_task(task_t * p)
+ {
+-	unsigned long free = 0;
+ 	task_t *relative;
+-	int state;
+-	static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
++	unsigned state;
++	static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
+ 
+ 	printk("%-13.13s ", p->comm);
+ 	state = p->state ? __ffs(p->state) + 1 : 0;
+-	if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
++	if (state < ARRAY_SIZE(stat_nam))
+ 		printk(stat_nam[state]);
+ 	else
+-		printk(" ");
++		printk("?");
+ #if (BITS_PER_LONG == 32)
+ 	if (p == current)
+ 		printk(" current  ");
+@@ -2424,13 +2467,7 @@ static void show_task(task_t * p)
+ 	else
+ 		printk(" %016lx ", thread_saved_pc(p));
+ #endif
+-	{
+-		unsigned long * n = (unsigned long *) (p->thread_info+1);
+-		while (!*n)
+-			n++;
+-		free = (unsigned long) n - (unsigned long)(p+1);
+-	}
+-	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
++	printk("%5d %6d ", p->pid, p->parent->pid);
+ 	if ((relative = eldest_child(p)))
+ 		printk("%5d ", relative->pid);
+ 	else
+@@ -2457,12 +2494,12 @@ void show_state(void)
+ 
+ #if (BITS_PER_LONG == 32)
+ 	printk("\n"
+-	       "                         free                        sibling\n");
+-	printk("  task             PC    stack   pid father child younger older\n");
++	       "                                               sibling\n");
++	printk("  task             PC      pid father child younger older\n");
+ #else
+ 	printk("\n"
+-	       "                                 free                        sibling\n");
+-	printk("  task                 PC        stack   pid father child younger older\n");
++	       "                                                       sibling\n");
++	printk("  task                 PC          pid father child younger older\n");
+ #endif
+ 	read_lock(&tasklist_lock);
+ 	do_each_thread(g, p) {
+@@ -2574,6 +2611,8 @@ int set_cpus_allowed(task_t *p, cpumask_
+ 	return 0;
+ }
+ 
++EXPORT_SYMBOL_GPL(set_cpus_allowed);
++
+ /* Move (not current) task off this cpu, onto dest cpu. */
+ static void move_task_away(struct task_struct *p, int dest_cpu)
+ {
+@@ -2819,6 +2858,7 @@ void __might_sleep(char *file, int line)
+ 	}
+ #endif
+ }
++EXPORT_SYMBOL(__might_sleep);
+ #endif
+ 
+ 
+@@ -2847,6 +2887,8 @@ void __preempt_spin_lock(spinlock_t *loc
+ 	} while (!_raw_spin_trylock(lock));
+ }
+ 
++EXPORT_SYMBOL(__preempt_spin_lock);
++
+ void __preempt_write_lock(rwlock_t *lock)
+ {
+ 	if (preempt_count() > 1) {
+@@ -2861,4 +2903,6 @@ void __preempt_write_lock(rwlock_t *lock
+ 		preempt_disable();
+ 	} while (!_raw_write_trylock(lock));
+ }
+-#endif
++
++EXPORT_SYMBOL(__preempt_write_lock);
++#endif /* defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) */
+--- linux-2.6.0-test6/kernel/signal.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/signal.c	2003-10-05 00:36:15.000000000 -0700
+@@ -593,7 +593,8 @@ static int check_kill_permission(int sig
+ 	error = -EPERM;
+ 	if ((!info || ((unsigned long)info != 1 &&
+ 			(unsigned long)info != 2 && SI_FROMUSER(info)))
+-	    && ((sig != SIGCONT) || (current->session != t->session))
++	    && ((sig != SIGCONT) ||
++		(process_session(current) != process_session(t)))
+ 	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
+ 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
+ 	    && !capable(CAP_KILL))
+@@ -1102,7 +1103,7 @@ kill_sl_info(int sig, struct siginfo *in
+ 	retval = -ESRCH;
+ 	read_lock(&tasklist_lock);
+ 	for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) {
+-		if (!p->leader)
++		if (!process_session_leader(p))
+ 			continue;
+ 		err = group_send_sig_info(sig, info, p);
+ 		if (retval)
+--- linux-2.6.0-test6/kernel/sys.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/sys.c	2003-10-05 00:36:15.000000000 -0700
+@@ -951,7 +951,7 @@ asmlinkage long sys_setpgid(pid_t pid, p
+ 
+ 	if (p->parent == current || p->real_parent == current) {
+ 		err = -EPERM;
+-		if (p->session != current->session)
++		if (process_session(p) != process_session(current))
+ 			goto out;
+ 		err = -EACCES;
+ 		if (p->did_exec)
+@@ -963,7 +963,7 @@ asmlinkage long sys_setpgid(pid_t pid, p
+ 	}
+ 
+ 	err = -EPERM;
+-	if (p->leader)
++	if (process_session_leader(p))
+ 		goto out;
+ 
+ 	if (pgid != pid) {
+@@ -972,7 +972,7 @@ asmlinkage long sys_setpgid(pid_t pid, p
+ 		struct list_head *l;
+ 
+ 		for_each_task_pid(pgid, PIDTYPE_PGID, p, l, pid)
+-			if (p->session == current->session)
++			if (process_session(p) == process_session(current))
+ 				goto ok_pgid;
+ 		goto out;
+ 	}
+@@ -984,7 +984,7 @@ ok_pgid:
+ 
+ 	if (process_group(p) != pgid) {
+ 		detach_pid(p, PIDTYPE_PGID);
+-		p->group_leader->__pgrp = pgid;
++		p->signal->pgrp = pgid;
+ 		attach_pid(p, PIDTYPE_PGID, pgid);
+ 	}
+ 
+@@ -1026,7 +1026,7 @@ asmlinkage long sys_getpgrp(void)
+ asmlinkage long sys_getsid(pid_t pid)
+ {
+ 	if (!pid) {
+-		return current->session;
++		return process_session(current);
+ 	} else {
+ 		int retval;
+ 		struct task_struct *p;
+@@ -1038,7 +1038,7 @@ asmlinkage long sys_getsid(pid_t pid)
+ 		if(p) {
+ 			retval = security_task_getsid(p);
+ 			if (!retval)
+-				retval = p->session;
++				retval = process_session(p);
+ 		}
+ 		read_unlock(&tasklist_lock);
+ 		return retval;
+@@ -1059,10 +1059,10 @@ asmlinkage long sys_setsid(void)
+ 	if (pid)
+ 		goto out;
+ 
+-	current->leader = 1;
++	current->signal->leader = 1;
+ 	__set_special_pids(current->pid, current->pid);
+-	current->tty = NULL;
+-	current->tty_old_pgrp = 0;
++	current->signal->tty = NULL;
++	current->signal->tty_old_pgrp = 0;
+ 	err = process_group(current);
+ out:
+ 	write_unlock_irq(&tasklist_lock);
+--- linux-2.6.0-test6/kernel/sysctl.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/sysctl.c	2003-10-05 00:33:25.000000000 -0700
+@@ -19,6 +19,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/swap.h>
+ #include <linux/slab.h>
+@@ -136,17 +137,14 @@ extern ctl_table random_table[];
+ 
+ static ssize_t proc_readsys(struct file *, char __user *, size_t, loff_t *);
+ static ssize_t proc_writesys(struct file *, const char __user *, size_t, loff_t *);
+-static int proc_sys_permission(struct inode *, int, struct nameidata *);
++static int proc_opensys(struct inode *, struct file *);
+ 
+ struct file_operations proc_sys_file_operations = {
++	.open		= proc_opensys,
+ 	.read		= proc_readsys,
+ 	.write		= proc_writesys,
+ };
+ 
+-static struct inode_operations proc_sys_inode_operations = {
+-	.permission	= proc_sys_permission,
+-};
+-
+ extern struct proc_dir_entry *proc_sys_root;
+ 
+ static void register_proc_table(ctl_table *, struct proc_dir_entry *);
+@@ -1140,10 +1138,8 @@ static void register_proc_table(ctl_tabl
+ 			if (!de)
+ 				continue;
+ 			de->data = (void *) table;
+-			if (table->proc_handler) {
++			if (table->proc_handler)
+ 				de->proc_fops = &proc_sys_file_operations;
+-				de->proc_iops = &proc_sys_inode_operations;
+-			}
+ 		}
+ 		table->de = de;
+ 		if (de->mode & S_IFDIR)
+@@ -1212,6 +1208,20 @@ static ssize_t do_rw_proc(int write, str
+ 	return res;
+ }
+ 
++static int proc_opensys(struct inode *inode, struct file *file)
++{
++	if (file->f_mode & FMODE_WRITE) {
++		/*
++		 * sysctl entries that are not writable,
++		 * are _NOT_ writable, capabilities or not.
++		 */
++		if (!(inode->i_mode & S_IWUSR))
++			return -EPERM;
++	}
++
++	return 0;
++}
++
+ static ssize_t proc_readsys(struct file * file, char __user * buf,
+ 			    size_t count, loff_t *ppos)
+ {
+@@ -1224,11 +1234,6 @@ static ssize_t proc_writesys(struct file
+ 	return do_rw_proc(1, file, (char __user *) buf, count, ppos);
+ }
+ 
+-static int proc_sys_permission(struct inode *inode, int op, struct nameidata *nd)
+-{
+-	return test_perm(inode->i_mode, op);
+-}
+-
+ /**
+  * proc_dostring - read a string sysctl
+  * @table: the sysctl table
+@@ -1994,3 +1999,19 @@ void unregister_sysctl_table(struct ctl_
+ }
+ 
+ #endif /* CONFIG_SYSCTL */
++
++/*
++ * No sense putting this after each symbol definition, twice,
++ * exception granted :-)
++ */
++EXPORT_SYMBOL(proc_dointvec);
++EXPORT_SYMBOL(proc_dointvec_jiffies);
++EXPORT_SYMBOL(proc_dointvec_minmax);
++EXPORT_SYMBOL(proc_dostring);
++EXPORT_SYMBOL(proc_doulongvec_minmax);
++EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
++EXPORT_SYMBOL(register_sysctl_table);
++EXPORT_SYMBOL(sysctl_intvec);
++EXPORT_SYMBOL(sysctl_jiffies);
++EXPORT_SYMBOL(sysctl_string);
++EXPORT_SYMBOL(unregister_sysctl_table);
+--- linux-2.6.0-test6/lib/kobject.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/lib/kobject.c	2003-10-05 00:34:36.000000000 -0700
+@@ -236,8 +236,6 @@ static void unlink(struct kobject * kobj
+ 		list_del_init(&kobj->entry);
+ 		up_write(&kobj->kset->subsys->rwsem);
+ 	}
+-	if (kobj->parent) 
+-		kobject_put(kobj->parent);
+ 	kobject_put(kobj);
+ }
+ 
+@@ -448,6 +446,8 @@ void kobject_cleanup(struct kobject * ko
+ 	if (kobj->k_name != kobj->name)
+ 		kfree(kobj->k_name);
+ 	kobj->k_name = NULL;
++	if (kobj->parent)
++		kobject_put(kobj->parent);
+ 	if (t && t->release)
+ 		t->release(kobj);
+ 	if (s)
+--- linux-2.6.0-test6/lib/Makefile	2003-09-27 18:57:47.000000000 -0700
++++ 25/lib/Makefile	2003-10-05 00:33:25.000000000 -0700
+@@ -5,7 +5,7 @@
+ 
+ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+ 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
+-	 kobject.o idr.o div64.o
++	 kobject.o idr.o div64.o parser.o
+ 
+ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/lib/parser.c	2003-10-05 00:33:25.000000000 -0700
+@@ -0,0 +1,138 @@
++/*
++ * lib/parser.c - simple parser for mount, etc. options.
++ *
++ * This source code is licensed under the GNU General Public License,
++ * Version 2.  See the file COPYING for more details.
++ */
++
++#include <linux/ctype.h>
++#include <linux/module.h>
++#include <linux/parser.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++
++static int match_one(char *s, char *p, substring_t args[])
++{
++	char *meta;
++	int argc = 0;
++
++	if (!p)
++		return 1;
++
++	while(1) {
++		int len = -1;
++		meta = strchr(p, '%');
++		if (!meta)
++			return strcmp(p, s) == 0;
++
++		if (strncmp(p, s, meta-p))
++			return 0;
++
++		s += meta - p;
++		p = meta + 1;
++
++		if (isdigit(*p))
++			len = simple_strtoul(p, &p, 10);
++		else if (*p == '%') {
++			if (*s++ != '%')
++				return 0;
++			continue;
++		}
++
++		if (argc >= MAX_OPT_ARGS)
++			return 0;
++
++		args[argc].from = s;
++		switch (*p++) {
++		case 's':
++			if (len == -1 || len > strlen(s))
++				len = strlen(s);
++			args[argc].to = s + len;
++			break;
++		case 'd':
++			simple_strtol(s, &args[argc].to, 0);
++			goto num;
++		case 'u':
++			simple_strtoul(s, &args[argc].to, 0);
++			goto num;
++		case 'o':
++			simple_strtoul(s, &args[argc].to, 8);
++			goto num;
++		case 'x':
++			simple_strtoul(s, &args[argc].to, 16);
++		num:
++			if (args[argc].to == args[argc].from)
++				return 0;
++			break;
++		default:
++			return 0;
++		}
++		s = args[argc].to;
++		argc++;
++	}
++}
++
++int match_token(char *s, match_table_t table, substring_t args[])
++{
++	struct match_token *p;
++
++	for (p = table; !match_one(s, p->pattern, args) ; p++)
++		;
++
++	return p->token;
++}
++
++static int match_number(substring_t *s, int *result, int base)
++{
++	char *endp;
++	char *buf;
++	int ret;
++
++	buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++	memcpy(buf, s->from, s->to - s->from);
++	buf[s->to - s->from] = '\0';
++	*result = simple_strtol(buf, &endp, base);
++	ret = 0;
++	if (endp == buf)
++		ret = -EINVAL;
++	kfree(buf);
++	return ret;
++}
++
++int match_int(substring_t *s, int *result)
++{
++	return match_number(s, result, 0);
++}
++
++int match_octal(substring_t *s, int *result)
++{
++	return match_number(s, result, 8);
++}
++
++int match_hex(substring_t *s, int *result)
++{
++	return match_number(s, result, 16);
++}
++
++void match_strcpy(char *to, substring_t *s)
++{
++	memcpy(to, s->from, s->to - s->from);
++	to[s->to - s->from] = '\0';
++}
++
++char *match_strdup(substring_t *s)
++{
++	char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
++	if (p)
++		match_strcpy(p, s);
++	return p;
++}
++
++EXPORT_SYMBOL(match_token);
++EXPORT_SYMBOL(match_int);
++EXPORT_SYMBOL(match_octal);
++EXPORT_SYMBOL(match_hex);
++EXPORT_SYMBOL(match_strcpy);
++EXPORT_SYMBOL(match_strdup);
+--- linux-2.6.0-test6/MAINTAINERS	2003-09-27 18:57:43.000000000 -0700
++++ 25/MAINTAINERS	2003-10-05 00:34:22.000000000 -0700
+@@ -114,8 +114,8 @@ W:	http://sourceforge.net/projects/gkern
+ S:	Maintained
+ 
+ 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
+-P:	Theodore Ts'o
+-M:	tytso@mit.edu
++P:	Russell King
++M:	rmk+serial@arm.linux.org.uk
+ L:	linux-serial@vger.kernel.org
+ W:	http://serial.sourceforge.net
+ S:	Maintained
+@@ -284,6 +284,16 @@ P:	Jonathan Layes
+ L:	linux-net@vger.kernel.org
+ S:	Maintained
+ 
++ASUS ACPI EXTRAS DRIVER
++P:	Karol Kozimor
++M:	sziwan@users.sourceforge.net
++P:	Julien Lerouge
++M:	julien.lerouge@free.fr
++L:	acpi4asus-user@lists.sourceforge.net
++W:	http://sourceforge.net/projects/acpi4asus
++W:	http://julien.lerouge.free.fr
++S:	Maintained
++
+ ATM
+ P:	Chas Williams
+ M:	chas@cmf.nrl.navy.mil
+@@ -509,7 +519,7 @@ S:	Maintained
+ 
+ CRYPTO API
+ P:	James Morris
+-M:	jmorris@intercode.com.au
++M:	jmorris@redhat.com
+ P:	David S. Miller
+ M:	davem@redhat.com
+ W	http://samba.org/~jamesm/crypto/
+@@ -624,7 +634,7 @@ DIGIBOARD PC/XE AND PC/XI DRIVER
+ P:	Christoph Lameter
+ M:	christoph@lameter.com
+ W:	http://www.digi.com
+-L:	digilnux@dgii.com
++L:	digilnux@digi.com
+ S:	Orphaned
+ 
+ DIRECTORY NOTIFICATION
+@@ -669,6 +679,12 @@ M:	romieu@cogenit.fr
+ M:	romieu@ensta.fr
+ S:	Maintained
+ 
++DVB SUBSYSTEM AND DRIVERS
++P:	LinuxTV.org Project
++L: 	linux-dvb@linuxtv.org
++W:	http://linuxtv.org/developer/dvb.xml
++S:	Supported
++
+ EATA-DMA SCSI DRIVER
+ P:	Michael Neuffer
+ L:	linux-eata@i-connect.net, linux-scsi@vger.kernel.org
+@@ -706,6 +722,11 @@ L:	emu10k1-devel@lists.sourceforge.net
+ W:	http://sourceforge.net/projects/emu10k1/
+ S:	Maintained
+ 
++EPSON 1355 FRAMEBUFFER DRIVER
++P:	Christopher Hoover
++M:	ch@murgatroid.com, ch@hpl.hp.com
++S:	Maintained
++
+ ETHEREXPRESS-16 NETWORK DRIVER
+ P:	Philip Blundell
+ M:	Philip.Blundell@pobox.com
+@@ -1139,6 +1160,12 @@ W:	http://sf.net/projects/kernel-janitor
+ W:	http://developer.osdl.org/rddunlap/kj-patches/
+ S:	Maintained
+ 
++KGDB FOR I386 PLATFORM
++P:	George Anzinger
++M:	george@mvista.com
++L:	linux-net@vger.kernel.org
++S:	Supported
++
+ KERNEL NFSD
+ P:	Neil Brown
+ M:	neilb@cse.unsw.edu.au
+@@ -1386,7 +1413,7 @@ M:	kuznet@ms2.inr.ac.ru
+ P:	Pekka Savola (ipv6)
+ M:	pekkas@netcore.fi
+ P:	James Morris
+-M:	jmorris@intercode.com.au
++M:	jmorris@redhat.com
+ P:	Hideaki YOSHIFUJI
+ M:	yoshfuji@linux-ipv6.org
+ L:	netdev@oss.sgi.com
+@@ -1658,6 +1685,12 @@ L:	linux-390@vm.marist.edu
+ W:	http://oss.software.ibm.com/developerworks/opensource/linux390
+ S:	Supported
+ 
++SAA7146 VIDEO4LINUX-2 DRIVER
++P:	Michael Hunold
++M:	michael@mihu.de
++W:	http://www.mihu.de/linux/saa7146
++S:	Maintained
++
+ SA1100 SUPPORT
+ P:	Nicolas Pitre
+ M:	nico@cam.org
+--- linux-2.6.0-test6/Makefile	2003-09-27 18:57:43.000000000 -0700
++++ 25/Makefile	2003-10-05 00:37:37.000000000 -0700
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 0
+-EXTRAVERSION = -test6
++EXTRAVERSION = -test6-mm4
+ 
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -37,7 +37,7 @@ ifdef V
+   endif
+ endif
+ ifndef KBUILD_VERBOSE
+-  KBUILD_VERBOSE = 0 
++  KBUILD_VERBOSE = 0
+ endif
+ 
+ # Call sparse as part of compilation of C files
+@@ -79,16 +79,24 @@ ifdef O
+   endif
+ endif
+ 
++# That's our default target when none is given on the command line
++.PHONY: all
++all:
++  
+ ifneq ($(KBUILD_OUTPUT),)
+ # Invoke a second make in the output directory, passing relevant variables
+-	KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT); /bin/pwd)
++# check that the output directory actually exists
++saved-output := $(KBUILD_OUTPUT)
++KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
++$(if $(wildcard $(KBUILD_OUTPUT)),, \
++     $(error output directory "$(saved-output)" does not exist))
+ 
+-.PHONY: $(MAKECMDGOALS) all
++.PHONY: $(MAKECMDGOALS)
+ 
+-$(MAKECMDGOALS) all:
++$(filter-out all,$(MAKECMDGOALS)) all:
+ 	$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT)		\
+ 	KBUILD_SRC=$(CURDIR)	KBUILD_VERBOSE=$(KBUILD_VERBOSE)	\
+-	KBUILD_CHECK=$(KBUILD_CHECK) -f $(CURDIR)/Makefile $(MAKECMDGOALS)
++	KBUILD_CHECK=$(KBUILD_CHECK) -f $(CURDIR)/Makefile $@
+ 
+ # Leave processing to above invocation of make
+ skip-makefile := 1
+@@ -156,13 +164,6 @@ HOSTCXX  	= g++
+ HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+ HOSTCXXFLAGS	= -O2
+ 
+-
+-# 	That's our default target when none is given on the command line
+-#	Note that 'modules' will be added as a prerequisite as well, 
+-#	in the CONFIG_MODULES part below
+-
+-all:	vmlinux
+-
+ # 	Decide whether to build built-in, modular, or both.
+ #	Normally, just do built-in.
+ 
+@@ -366,6 +367,12 @@ else
+ # Build targets only - this includes vmlinux, arch specific targets, clean
+ # targets and others. In general all targets except *config targets.
+ 
++# That's our default target when none is given on the command line
++# Note that 'modules' will be added as a prerequisite as well, 
++# in the CONFIG_MODULES part below
++
++all:	vmlinux
++
+ # Objects we will link into vmlinux / subdirs we need to visit
+ init-y		:= init/
+ drivers-y	:= drivers/ sound/
+@@ -753,7 +760,7 @@ MRPROPER_FILES += \
+ 	.menuconfig.log \
+ 	include/asm \
+ 	.hdepend include/linux/modversions.h \
+-	tags TAGS cscope.out kernel.spec \
++	tags TAGS cscope* kernel.spec \
+ 	.tmp*
+ 
+ # Directories removed with 'make mrproper'
+@@ -877,7 +884,7 @@ help:
+ 	@echo  '  mrproper	  - remove all generated files + config + various backup files'
+ 	@echo  ''
+ 	@echo  'Configuration targets:'
+-	@$(MAKE) -f scripts/kconfig/Makefile help
++	@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
+ 	@echo  ''
+ 	@echo  'Other generic targets:'
+ 	@echo  '  all		  - Build all targets marked with [*]'
+@@ -890,7 +897,7 @@ help:
+ 	@echo  '  tags/TAGS	  - Generate tags file for editors'
+ 	@echo  ''
+ 	@echo  'Documentation targets:'
+-	@$(MAKE) -f Documentation/DocBook/Makefile dochelp
++	@$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
+ 	@echo  ''
+ 	@echo  'Architecture specific targets ($(ARCH)):'
+ 	@$(if $(archhelp),$(archhelp),\
+--- linux-2.6.0-test6/mm/bootmem.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/mm/bootmem.c	2003-10-05 00:33:25.000000000 -0700
+@@ -146,7 +146,7 @@ static void __init free_bootmem_core(boo
+  * We 'merge' subsequent allocations to save space. We might 'lose'
+  * some fraction of a page if allocations cannot be satisfied due to
+  * size constraints on boxes where there is physical RAM space
+- * fragmentation - in these cases * (mostly large memory boxes) this
++ * fragmentation - in these cases (mostly large memory boxes) this
+  * is not a problem.
+  *
+  * On low memory boxes we get it right in 100% of the cases.
+--- linux-2.6.0-test6/mm/fadvise.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/fadvise.c	2003-10-05 00:34:08.000000000 -0700
+@@ -23,7 +23,6 @@
+ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+ {
+ 	struct file *file = fget(fd);
+-	struct inode *inode;
+ 	struct address_space *mapping;
+ 	struct backing_dev_info *bdi;
+ 	pgoff_t start_index;
+@@ -33,8 +32,7 @@ asmlinkage long sys_fadvise64_64(int fd,
+ 	if (!file)
+ 		return -EBADF;
+ 
+-	inode = file->f_dentry->d_inode;
+-	mapping = inode->i_mapping;
++	mapping = file->f_mapping;
+ 	if (!mapping) {
+ 		ret = -EINVAL;
+ 		goto out;
+--- linux-2.6.0-test6/mm/filemap.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/filemap.c	2003-10-05 00:37:07.000000000 -0700
+@@ -61,6 +61,9 @@
+  *        ->swap_device_lock	(exclusive_swap_page, others)
+  *          ->mapping->page_lock
+  *
++ *  ->i_sem
++ *    ->i_shared_sem		(truncate->invalidate_mmap_range)
++ *
+  *  ->mmap_sem
+  *    ->i_shared_sem		(various places)
+  *
+@@ -70,6 +73,9 @@
+  *  ->mmap_sem
+  *    ->i_sem			(msync)
+  *
++ *  ->i_sem
++ *    ->i_alloc_sem             (various)
++ *
+  *  ->inode_lock
+  *    ->sb_lock			(fs/fs-writeback.c)
+  *    ->mapping->page_lock	(__sync_single_inode)
+@@ -151,6 +157,8 @@ int filemap_fdatawrite(struct address_sp
+ 	return __filemap_fdatawrite(mapping, WB_SYNC_ALL);
+ }
+ 
++EXPORT_SYMBOL(filemap_fdatawrite);
++
+ /*
+  * This is a mostly non-blocking flush.  Not suitable for data-integrity
+  * purposes.
+@@ -216,6 +224,20 @@ restart:
+ 	return ret;
+ }
+ 
++EXPORT_SYMBOL(filemap_fdatawait);
++
++int filemap_write_and_wait(struct address_space *mapping)
++{
++	int retval = 0;
++
++	if (mapping->nrpages) {
++		retval = filemap_fdatawrite(mapping);
++		if (retval == 0)
++			retval = filemap_fdatawait(mapping);
++	}
++	return retval;
++}
++
+ /*
+  * This adds a page to the page cache, starting out as locked, unreferenced,
+  * not uptodate and with no errors.
+@@ -253,6 +275,7 @@ int add_to_page_cache(struct page *page,
+ 	}
+ 	return error;
+ }
++
+ EXPORT_SYMBOL(add_to_page_cache);
+ 
+ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
+@@ -281,21 +304,42 @@ static wait_queue_head_t *page_waitqueue
+ 	return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+ }
+ 
+-void wait_on_page_bit(struct page *page, int bit_nr)
++/*
++ * wait for the specified page bit to be cleared
++ * this could be a synchronous wait or could just queue an async
++ * notification callback depending on the wait queue entry parameter
++ *
++ * A NULL wait queue parameter defaults to sync behaviour
++ */
++int wait_on_page_bit_wq(struct page *page, int bit_nr, wait_queue_t *wait)
+ {
+ 	wait_queue_head_t *waitqueue = page_waitqueue(page);
+-	DEFINE_WAIT(wait);
++	DEFINE_WAIT(local_wait);
++
++	if (!wait)
++		wait = &local_wait; /* default to a sync wait entry */
+ 
+ 	do {
+-		prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
++		prepare_to_wait(waitqueue, wait, TASK_UNINTERRUPTIBLE);
+ 		if (test_bit(bit_nr, &page->flags)) {
+ 			sync_page(page);
++			if (!is_sync_wait(wait)) {
++				/*
++				 * if we've queued an async wait queue
++				 * callback do not block; just tell the
++				 * caller to return and retry later when
++				 * the callback is notified
++				 */
++				return -EIOCBRETRY;
++			}
+ 			io_schedule();
+ 		}
+ 	} while (test_bit(bit_nr, &page->flags));
+-	finish_wait(waitqueue, &wait);
++	finish_wait(waitqueue, wait);
++
++	return 0;
+ }
+-EXPORT_SYMBOL(wait_on_page_bit);
++EXPORT_SYMBOL(wait_on_page_bit_wq);
+ 
+ /**
+  * unlock_page() - unlock a locked page
+@@ -305,7 +349,9 @@ EXPORT_SYMBOL(wait_on_page_bit);
+  * Unlocks the page and wakes up sleepers in ___wait_on_page_locked().
+  * Also wakes sleepers in wait_on_page_writeback() because the wakeup
+  * mechananism between PageLocked pages and PageWriteback pages is shared.
+- * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
++ * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep,
++ * or in case the wakeup notifies async wait queue entries, as in the case
++ * of aio, retries would be triggered and may re-queue their callbacks.
+  *
+  * The first mb is necessary to safely close the critical section opened by the
+  * TestSetPageLocked(), the second mb is necessary to enforce ordering between
+@@ -323,6 +369,8 @@ void unlock_page(struct page *page)
+ 		wake_up_all(waitqueue);
+ }
+ 
++EXPORT_SYMBOL(unlock_page);
++
+ /*
+  * End writeback against a page.
+  */
+@@ -339,30 +387,57 @@ void end_page_writeback(struct page *pag
+ 	if (waitqueue_active(waitqueue))
+ 		wake_up_all(waitqueue);
+ }
++
+ EXPORT_SYMBOL(end_page_writeback);
+ 
+ /*
+- * Get a lock on the page, assuming we need to sleep to get it.
++ * Get a lock on the page, assuming we need to either sleep to get it
++ * or to queue an async notification callback to try again when its
++ * available.
++ *
++ * A NULL wait queue parameter defaults to sync behaviour. Otherwise
++ * it specifies the wait queue entry to be used for async notification
++ * or waiting.
+  *
+  * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary.  If some
+  * random driver's requestfn sets TASK_RUNNING, we could busywait.  However
+  * chances are that on the second loop, the block layer's plug list is empty,
+  * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
+  */
+-void __lock_page(struct page *page)
++int __lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+ 	wait_queue_head_t *wqh = page_waitqueue(page);
+-	DEFINE_WAIT(wait);
++	DEFINE_WAIT(local_wait);
++
++	if (!wait)
++		wait = &local_wait;
+ 
+ 	while (TestSetPageLocked(page)) {
+-		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++		prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+ 		if (PageLocked(page)) {
+ 			sync_page(page);
++			if (!is_sync_wait(wait)) {
++				/*
++				 * if we've queued an async wait queue
++				 * callback do not block; just tell the
++				 * caller to return and retry later when
++				 * the callback is notified
++				 */
++				return -EIOCBRETRY;
++			}
+ 			io_schedule();
+ 		}
+ 	}
+-	finish_wait(wqh, &wait);
++	finish_wait(wqh, wait);
++	return 0;
++}
++EXPORT_SYMBOL(__lock_page_wq);
++
++void __lock_page(struct page *page)
++{
++	__lock_page_wq(page, NULL);
+ }
++
+ EXPORT_SYMBOL(__lock_page);
+ 
+ /*
+@@ -385,6 +460,8 @@ struct page * find_get_page(struct addre
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(find_get_page);
++
+ /*
+  * Same as above, but trylock it instead of incrementing the count.
+  */
+@@ -400,6 +477,8 @@ struct page *find_trylock_page(struct ad
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(find_trylock_page);
++
+ /**
+  * find_lock_page - locate, pin and lock a pagecache page
+  *
+@@ -411,8 +490,8 @@ struct page *find_trylock_page(struct ad
+  *
+  * Returns zero if the page was not present. find_lock_page() may sleep.
+  */
+-struct page *find_lock_page(struct address_space *mapping,
+-				unsigned long offset)
++struct page *find_lock_page_wq(struct address_space *mapping,
++				unsigned long offset, wait_queue_t *wait)
+ {
+ 	struct page *page;
+ 
+@@ -423,7 +502,10 @@ repeat:
+ 		page_cache_get(page);
+ 		if (TestSetPageLocked(page)) {
+ 			spin_unlock(&mapping->page_lock);
+-			lock_page(page);
++			if (-EIOCBRETRY == lock_page_wq(page, wait)) {
++				page_cache_release(page);
++				return ERR_PTR(-EIOCBRETRY);
++			}
+ 			spin_lock(&mapping->page_lock);
+ 
+ 			/* Has the page been truncated while we slept? */
+@@ -438,6 +520,14 @@ repeat:
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(find_lock_page);
++
++struct page *find_lock_page(struct address_space *mapping,
++				unsigned long offset)
++{
++	return find_lock_page_wq(mapping, offset, NULL);
++}
++
+ /**
+  * find_or_create_page - locate or add a pagecache page
+  *
+@@ -482,6 +572,8 @@ repeat:
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(find_or_create_page);
++
+ /**
+  * find_get_pages - gang pagecache lookup
+  * @mapping:	The address_space to search
+@@ -496,9 +588,12 @@ repeat:
+  * The search returns a group of mapping-contiguous pages with ascending
+  * indexes.  There may be holes in the indices due to not-present pages.
+  *
+- * find_get_pages() returns the number of pages which were found.
++ * find_get_pages() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+  */
+-unsigned int find_get_pages(struct address_space *mapping, pgoff_t start,
++unsigned int find_get_pages(struct address_space *mapping, pgoff_t *next,
+ 			    unsigned int nr_pages, struct page **pages)
+ {
+ 	unsigned int i;
+@@ -506,9 +601,12 @@ unsigned int find_get_pages(struct addre
+ 
+ 	spin_lock(&mapping->page_lock);
+ 	ret = radix_tree_gang_lookup(&mapping->page_tree,
+-				(void **)pages, start, nr_pages);
++				(void **)pages, *next, nr_pages);
+ 	for (i = 0; i < ret; i++)
+ 		page_cache_get(pages[i]);
++	if (ret)
++		*next = pages[ret - 1]->index + 1;
++
+ 	spin_unlock(&mapping->page_lock);
+ 	return ret;
+ }
+@@ -543,6 +641,8 @@ grab_cache_page_nowait(struct address_sp
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(grab_cache_page_nowait);
++
+ /*
+  * This is a generic file read routine, and uses the
+  * inode->i_op->readpage() function for the actual low-level
+@@ -560,21 +660,47 @@ void do_generic_mapping_read(struct addr
+ 			     read_actor_t actor)
+ {
+ 	struct inode *inode = mapping->host;
+-	unsigned long index, offset;
++	unsigned long index, offset, first, last, end_index;
+ 	struct page *cached_page;
++	loff_t isize = i_size_read(inode);
+ 	int error;
+ 
+ 	cached_page = NULL;
+-	index = *ppos >> PAGE_CACHE_SHIFT;
++	first = *ppos >> PAGE_CACHE_SHIFT;
+ 	offset = *ppos & ~PAGE_CACHE_MASK;
+ 
++	last = (*ppos + desc->count) >> PAGE_CACHE_SHIFT;
++	end_index = isize >> PAGE_CACHE_SHIFT;
++	if (last > end_index)
++		last = end_index;
++
++	/* Don't repeat the readahead if we are executing aio retries */
++	if (in_aio()) {
++		if (is_retried_kiocb(io_wait_to_kiocb(current->io_wait)))
++			goto done_readahead;
++	}
++
++	/*
++	 * Let the readahead logic know upfront about all
++	 * the pages we'll need to satisfy this request
++	 */
++	for (index = first ; index < last; index++)
++		page_cache_readahead(mapping, ra, filp, index);
++
++	if (ra->next_size == -1UL) {
++		/* the readahead window was maximally shrunk */
++		/* explicitly readahead at least what is needed now */
++		for (index = first; index < last; index++)
++			handle_ra_miss(mapping, ra, index);
++		do_page_cache_readahead(mapping, filp, first, last - first);
++	}
++
++done_readahead:
++	index = first;
+ 	for (;;) {
+ 		struct page *page;
+-		unsigned long end_index, nr, ret;
+-		loff_t isize = i_size_read(inode);
++		unsigned long nr, ret;
+ 
+-		end_index = isize >> PAGE_CACHE_SHIFT;
+-			
+ 		if (index > end_index)
+ 			break;
+ 		nr = PAGE_CACHE_SIZE;
+@@ -585,7 +711,6 @@ void do_generic_mapping_read(struct addr
+ 		}
+ 
+ 		cond_resched();
+-		page_cache_readahead(mapping, ra, filp, index);
+ 
+ 		nr = nr - offset;
+ find_page:
+@@ -635,7 +760,12 @@ page_not_up_to_date:
+ 			goto page_ok;
+ 
+ 		/* Get exclusive access to the page ... */
+-		lock_page(page);
++
++		if (lock_page_wq(page, current->io_wait)) {
++			pr_debug("queued lock page \n");
++			error = -EIOCBRETRY;
++			goto sync_error;
++		}
+ 
+ 		/* Did it get unhashed before we got the lock? */
+ 		if (!page->mapping) {
+@@ -657,13 +787,23 @@ readpage:
+ 		if (!error) {
+ 			if (PageUptodate(page))
+ 				goto page_ok;
+-			wait_on_page_locked(page);
++			if (wait_on_page_locked_wq(page, current->io_wait)) {
++				pr_debug("queued wait_on_page \n");
++				error = -EIOCBRETRY;
++				goto sync_error;
++			}
++
+ 			if (PageUptodate(page))
+ 				goto page_ok;
+ 			error = -EIO;
+ 		}
+ 
+-		/* UHHUH! A synchronous read error occurred. Report it */
++sync_error:
++		/* We don't have uptodate data in the page yet */
++		/* Could be due to an error or because we need to
++		 * retry when we get an async i/o notification.
++		 * Report the reason.
++		 */
+ 		desc->error = error;
+ 		page_cache_release(page);
+ 		break;
+@@ -699,6 +839,8 @@ no_cached_page:
+ 	update_atime(inode);
+ }
+ 
++EXPORT_SYMBOL(do_generic_mapping_read);
++
+ int file_read_actor(read_descriptor_t *desc, struct page *page,
+ 			unsigned long offset, unsigned long size)
+ {
+@@ -775,7 +917,7 @@ __generic_file_aio_read(struct kiocb *io
+ 		struct address_space *mapping;
+ 		struct inode *inode;
+ 
+-		mapping = filp->f_dentry->d_inode->i_mapping;
++		mapping = filp->f_mapping;
+ 		inode = mapping->host;
+ 		retval = 0;
+ 		if (!count)
+@@ -815,20 +957,19 @@ __generic_file_aio_read(struct kiocb *io
+ out:
+ 	return retval;
+ }
++EXPORT_SYMBOL(__generic_file_aio_read);
+ 
+-ssize_t
+-generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
++ssize_t generic_file_aio_read(struct kiocb *iocb, char __user *buf,
++				size_t count, loff_t pos)
+ {
+ 	struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+ 
+-	BUG_ON(iocb->ki_pos != pos);
+ 	return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos);
+ }
+ EXPORT_SYMBOL(generic_file_aio_read);
+-EXPORT_SYMBOL(__generic_file_aio_read);
+ 
+-ssize_t
+-generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
++ssize_t generic_file_read(struct file *filp, char __user *buf,
++				size_t count, loff_t *ppos)
+ {
+ 	struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+ 	struct kiocb kiocb;
+@@ -840,8 +981,10 @@ generic_file_read(struct file *filp, cha
+ 		ret = wait_on_sync_kiocb(&kiocb);
+ 	return ret;
+ }
++EXPORT_SYMBOL(generic_file_read);
+ 
+-int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
++int file_send_actor(read_descriptor_t * desc, struct page *page,
++				unsigned long offset, unsigned long size)
+ {
+ 	ssize_t written;
+ 	unsigned long count = desc->count;
+@@ -880,6 +1023,8 @@ ssize_t generic_file_sendfile(struct fil
+ 	return desc.error;
+ }
+ 
++EXPORT_SYMBOL(generic_file_sendfile);
++
+ static ssize_t
+ do_readahead(struct address_space *mapping, struct file *filp,
+ 	     unsigned long index, unsigned long nr)
+@@ -901,7 +1046,7 @@ asmlinkage ssize_t sys_readahead(int fd,
+ 	file = fget(fd);
+ 	if (file) {
+ 		if (file->f_mode & FMODE_READ) {
+-			struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++			struct address_space *mapping = file->f_mapping;
+ 			unsigned long start = offset >> PAGE_CACHE_SHIFT;
+ 			unsigned long end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
+ 			unsigned long len = end - start + 1;
+@@ -920,7 +1065,7 @@ asmlinkage ssize_t sys_readahead(int fd,
+ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
+ static int page_cache_read(struct file * file, unsigned long offset)
+ {
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct page *page; 
+ 	int error;
+ 
+@@ -959,7 +1104,7 @@ struct page * filemap_nopage(struct vm_a
+ {
+ 	int error;
+ 	struct file *file = area->vm_file;
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct file_ra_state *ra = &file->f_ra;
+ 	struct inode *inode = mapping->host;
+ 	struct page *page;
+@@ -1126,10 +1271,12 @@ page_not_uptodate:
+ 	return NULL;
+ }
+ 
++EXPORT_SYMBOL(filemap_nopage);
++
+ static struct page * filemap_getpage(struct file *file, unsigned long pgoff,
+ 					int nonblock)
+ {
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct page *page;
+ 	int error;
+ 
+@@ -1241,7 +1388,7 @@ static int filemap_populate(struct vm_ar
+ 			int nonblock)
+ {
+ 	struct file *file = vma->vm_file;
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct inode *inode = mapping->host;
+ 	unsigned long size;
+ 	struct mm_struct *mm = vma->vm_mm;
+@@ -1300,7 +1447,7 @@ static struct vm_operations_struct gener
+ 
+ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
+ {
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	struct inode *inode = mapping->host;
+ 
+ 	if (!mapping->a_ops->readpage)
+@@ -1330,6 +1477,9 @@ int generic_file_readonly_mmap(struct fi
+ }
+ #endif /* CONFIG_MMU */
+ 
++EXPORT_SYMBOL(generic_file_mmap);
++EXPORT_SYMBOL(generic_file_readonly_mmap);
++
+ static inline struct page *__read_cache_page(struct address_space *mapping,
+ 				unsigned long index,
+ 				int (*filler)(void *,struct page*),
+@@ -1406,6 +1556,8 @@ retry:
+ 	return page;
+ }
+ 
++EXPORT_SYMBOL(read_cache_page);
++
+ /*
+  * If the page was newly created, increment its refcount and add it to the
+  * caller's lru-buffering pagevec.  This function is specifically for
+@@ -1418,7 +1570,9 @@ __grab_cache_page(struct address_space *
+ 	int err;
+ 	struct page *page;
+ repeat:
+-	page = find_lock_page(mapping, index);
++	page = find_lock_page_wq(mapping, index, current->io_wait);
++	if (IS_ERR(page))
++		return page;
+ 	if (!page) {
+ 		if (!*cached_page) {
+ 			*cached_page = page_cache_alloc(mapping);
+@@ -1456,6 +1610,8 @@ void remove_suid(struct dentry *dentry)
+ 	}
+ }
+ 
++EXPORT_SYMBOL(remove_suid);
++
+ /*
+  * Copy as much as we can into the page and return the number of bytes which
+  * were sucessfully copied.  If a fault is encountered then clear the page
+@@ -1561,9 +1717,9 @@ filemap_set_next_iovec(const struct iove
+  * Returns appropriate error code that caller should return or
+  * zero in case that write should be allowed.
+  */
+-inline int generic_write_checks(struct inode *inode,
+-		struct file *file, loff_t *pos, size_t *count, int isblk)
++inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
+ {
++	struct inode *inode = file->f_mapping->host;
+ 	unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+ 
+         if (unlikely(*pos < 0))
+@@ -1625,7 +1781,7 @@ inline int generic_write_checks(struct i
+ 			*count = inode->i_sb->s_maxbytes - *pos;
+ 	} else {
+ 		loff_t isize;
+-		if (bdev_read_only(inode->i_bdev))
++		if (bdev_read_only(I_BDEV(inode)))
+ 			return -EPERM;
+ 		isize = i_size_read(inode);
+ 		if (*pos >= isize) {
+@@ -1638,10 +1794,12 @@ inline int generic_write_checks(struct i
+ 	}
+ 	return 0;
+ }
++
+ EXPORT_SYMBOL(generic_write_checks);
+ 
+ /*
+  * Write to a file through the page cache. 
++ * Called under i_sem for S_ISREG files.
+  *
+  * We put everything into the page cache prior to writing it. This is not a
+  * problem when writing full pages. With partial pages, however, we first have
+@@ -1650,11 +1808,11 @@ EXPORT_SYMBOL(generic_write_checks);
+  *							okir@monad.swb.de
+  */
+ ssize_t
+-generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++__generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
+ 				unsigned long nr_segs, loff_t *ppos)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct address_space * mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space * mapping = file->f_mapping;
+ 	struct address_space_operations *a_ops = mapping->a_ops;
+ 	size_t ocount;		/* original count */
+ 	size_t count;		/* after file limit checks */
+@@ -1701,11 +1859,10 @@ generic_file_aio_write_nolock(struct kio
+ 	current->backing_dev_info = mapping->backing_dev_info;
+ 	written = 0;
+ 
+-	err = generic_write_checks(inode, file, &pos, &count, isblk);
++	err = generic_write_checks(file, &pos, &count, isblk);
+ 	if (err)
+ 		goto out;
+ 
+-
+ 	if (count == 0)
+ 		goto out;
+ 
+@@ -1730,12 +1887,19 @@ generic_file_aio_write_nolock(struct kio
+ 		/*
+ 		 * Sync the fs metadata but not the minor inode changes and
+ 		 * of course not the data as we did direct DMA for the IO.
++		 * i_sem is held, which protects generic_osync_inode() from
++		 * livelocking.
+ 		 */
+ 		if (written >= 0 && file->f_flags & O_SYNC)
+-			status = generic_osync_inode(inode, OSYNC_METADATA);
++			status = generic_osync_inode(inode, mapping, OSYNC_METADATA);
+ 		if (written >= 0 && !is_sync_kiocb(iocb))
+ 			written = -EIOCBQUEUED;
+-		goto out_status;
++		if (written != -ENOTBLK)
++			goto out_status;
++		/*
++		 * direct-io write to a hole: fall through to buffered I/O
++		 */
++		written = 0;
+ 	}
+ 
+ 	buf = iov->iov_base;
+@@ -1759,6 +1923,10 @@ generic_file_aio_write_nolock(struct kio
+ 		fault_in_pages_readable(buf, bytes);
+ 
+ 		page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
++		if (IS_ERR(page)) {
++			status = PTR_ERR(page);
++			break;
++		}
+ 		if (!page) {
+ 			status = -ENOMEM;
+ 			break;
+@@ -1807,7 +1975,11 @@ generic_file_aio_write_nolock(struct kio
+ 		page_cache_release(page);
+ 		if (status < 0)
+ 			break;
+-		balance_dirty_pages_ratelimited(mapping);
++		status = balance_dirty_pages_ratelimited(mapping);
++		if (status < 0) {
++			pr_debug("async balance_dirty_pages\n");
++			break;
++		}
+ 		cond_resched();
+ 	} while (count);
+ 	*ppos = pos;
+@@ -1818,12 +1990,22 @@ generic_file_aio_write_nolock(struct kio
+ 	/*
+ 	 * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
+ 	 */
+-	if (status >= 0) {
+-		if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+-			status = generic_osync_inode(inode,
+-					OSYNC_METADATA|OSYNC_DATA);
+-	}
++	if (likely(status >= 0)) {
++		if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++			if (!a_ops->writepage)
++				status = generic_osync_inode(inode, mapping,
++						OSYNC_METADATA|OSYNC_DATA);
++		}
++  	}
+ 	
++	/*
++	 * If we get here for O_DIRECT writes then we must have fallen through
++	 * to buffered writes (block instantiation inside i_size).  So we sync
++	 * the file data here, to try to honour O_DIRECT expectations.
++	 */
++	if (unlikely(file->f_flags & O_DIRECT) && written)
++		status = filemap_write_and_wait(mapping);
++
+ out_status:	
+ 	err = written ? written : status;
+ out:
+@@ -1832,6 +2014,57 @@ out:
+ 	return err;
+ }
+ 
++EXPORT_SYMBOL(generic_file_aio_write_nolock);
++
++ssize_t
++generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++				unsigned long nr_segs, loff_t *ppos)
++{
++	struct file *file = iocb->ki_filp;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	ssize_t ret;
++	loff_t pos = *ppos;
++
++	if (!iov->iov_base && !is_sync_kiocb(iocb)) {
++		/* nothing to transfer, may just need to sync data */
++		ret = iov->iov_len; /* vector AIO not supported yet */
++		goto osync;
++	}
++
++	ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, ppos);
++
++	/*
++	 * Avoid doing a sync in parts for aio - its more efficient to
++	 * call in again after all the data has been copied
++	 */
++	if (!is_sync_kiocb(iocb))
++		return ret;
++
++osync:
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		ret = sync_page_range_nolock(inode, mapping, pos, ret);
++		if (ret >= 0)
++			*ppos = pos + ret;
++	}
++	return ret;
++}
++
++
++ssize_t
++__generic_file_write_nolock(struct file *file, const struct iovec *iov,
++				unsigned long nr_segs, loff_t *ppos)
++{
++	struct kiocb kiocb;
++	ssize_t ret;
++
++	init_sync_kiocb(&kiocb, file);
++	ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
++	if (-EIOCBQUEUED == ret)
++		ret = wait_on_sync_kiocb(&kiocb);
++	return ret;
++}
++
+ ssize_t
+ generic_file_write_nolock(struct file *file, const struct iovec *iov,
+ 				unsigned long nr_segs, loff_t *ppos)
+@@ -1846,39 +2079,69 @@ generic_file_write_nolock(struct file *f
+ 	return ret;
+ }
+ 
++EXPORT_SYMBOL(generic_file_write_nolock);
++
+ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
+ 			       size_t count, loff_t pos)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+-	ssize_t err;
+-	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	ssize_t ret;
++	struct iovec local_iov = { .iov_base = (void __user *)buf,
++					.iov_len = count };
+ 
+-	BUG_ON(iocb->ki_pos != pos);
++	if (!buf && !is_sync_kiocb(iocb)) {
++		/* nothing to transfer, may just need to sync data */
++		ret = count;
++		goto osync;
++	}
+ 
+ 	down(&inode->i_sem);
+-	err = generic_file_aio_write_nolock(iocb, &local_iov, 1, 
++	ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
+ 						&iocb->ki_pos);
+ 	up(&inode->i_sem);
+ 
+-	return err;
++	/*
++	 * Avoid doing a sync in parts for aio - its more efficient to
++	 * call in again after all the data has been copied
++	 */
++	if (!is_sync_kiocb(iocb))
++		return ret;
++
++osync:
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		ret = sync_page_range(inode, mapping, pos, ret);
++		if (ret >= 0)
++			iocb->ki_pos = pos + ret;
++	}
++	return ret;
+ }
+ EXPORT_SYMBOL(generic_file_aio_write);
+-EXPORT_SYMBOL(generic_file_aio_write_nolock);
+ 
+ ssize_t generic_file_write(struct file *file, const char __user *buf,
+ 			   size_t count, loff_t *ppos)
+ {
+-	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
+-	ssize_t		err;
+-	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
++	ssize_t	ret;
++	struct iovec local_iov = { .iov_base = (void __user *)buf,
++					.iov_len = count };
+ 
+ 	down(&inode->i_sem);
+-	err = generic_file_write_nolock(file, &local_iov, 1, ppos);
++	ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
+ 	up(&inode->i_sem);
+ 
+-	return err;
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		ssize_t err;
++
++		err = sync_page_range(inode, mapping, *ppos - ret, ret);
++		if (err < 0)
++			ret = err;
++	}
++	return ret;
+ }
++EXPORT_SYMBOL(generic_file_write);
+ 
+ ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
+ 			unsigned long nr_segs, loff_t *ppos)
+@@ -1893,37 +2156,50 @@ ssize_t generic_file_readv(struct file *
+ 	return ret;
+ }
+ 
++EXPORT_SYMBOL(generic_file_readv);
++
+ ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
+-			unsigned long nr_segs, loff_t * ppos) 
++			unsigned long nr_segs, loff_t *ppos)
+ {
+-	struct inode *inode = file->f_dentry->d_inode;
++	struct address_space *mapping = file->f_mapping;
++	struct inode *inode = mapping->host;
+ 	ssize_t ret;
+ 
+ 	down(&inode->i_sem);
+-	ret = generic_file_write_nolock(file, iov, nr_segs, ppos);
++	ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
+ 	up(&inode->i_sem);
++
++	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++		ssize_t err;
++
++		err = sync_page_range(inode, mapping, *ppos - ret, ret);
++		if (err < 0)
++			ret = err;
++	}
+ 	return ret;
+ }
+ 
++EXPORT_SYMBOL(generic_file_writev);
++
++/*
++ * Called under i_sem for writes to S_ISREG files
++ */
+ ssize_t
+ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ 	loff_t offset, unsigned long nr_segs)
+ {
+ 	struct file *file = iocb->ki_filp;
+-	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++	struct address_space *mapping = file->f_mapping;
+ 	ssize_t retval;
+ 
+-	if (mapping->nrpages) {
+-		retval = filemap_fdatawrite(mapping);
+-		if (retval == 0)
+-			retval = filemap_fdatawait(mapping);
+-		if (retval)
+-			goto out;
++	retval = filemap_write_and_wait(mapping);
++	if (retval == 0) {
++		retval = mapping->a_ops->direct_IO(rw, iocb, iov,
++						offset, nr_segs);
++		if (rw == WRITE && mapping->nrpages)
++			invalidate_inode_pages2(mapping);
+ 	}
+-
+-	retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
+-	if (rw == WRITE && mapping->nrpages)
+-		invalidate_inode_pages2(mapping);
+-out:
+ 	return retval;
+ }
++
++EXPORT_SYMBOL_GPL(generic_file_direct_IO);
+--- linux-2.6.0-test6/mm/highmem.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/mm/highmem.c	2003-10-05 00:33:25.000000000 -0700
+@@ -24,6 +24,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/init.h>
+ #include <linux/hash.h>
++#include <linux/highmem.h>
+ #include <asm/pgalloc.h>
+ #include <asm/tlbflush.h>
+ 
+@@ -62,7 +63,7 @@ static void flush_all_zero_pkmaps(void)
+ {
+ 	int i;
+ 
+-	flush_cache_all();
++	flush_cache_kmaps();
+ 
+ 	for (i = 0; i < LAST_PKMAP; i++) {
+ 		struct page *page;
+--- linux-2.6.0-test6/mm/madvise.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/mm/madvise.c	2003-10-05 00:34:07.000000000 -0700
+@@ -65,7 +65,7 @@ static long madvise_willneed(struct vm_a
+ 		end = vma->vm_end;
+ 	end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+ 
+-	force_page_cache_readahead(file->f_dentry->d_inode->i_mapping,
++	force_page_cache_readahead(file->f_mapping,
+ 			file, start, max_sane_readahead(end - start));
+ 	return 0;
+ }
+--- linux-2.6.0-test6/mm/Makefile	2003-09-08 13:58:59.000000000 -0700
++++ 25/mm/Makefile	2003-10-05 00:36:48.000000000 -0700
+@@ -12,3 +12,6 @@ obj-y			:= bootmem.o filemap.o mempool.o
+ 			   slab.o swap.o truncate.o vmscan.o $(mmu-y)
+ 
+ obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
++
++obj-$(CONFIG_X86_4G) += usercopy.o
++
+--- linux-2.6.0-test6/mm/memory.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/memory.c	2003-10-05 00:36:48.000000000 -0700
+@@ -100,7 +100,8 @@ static inline void free_one_pmd(struct m
+ 	pte_free_tlb(tlb, page);
+ }
+ 
+-static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir)
++static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir,
++							int pgd_idx)
+ {
+ 	int j;
+ 	pmd_t * pmd;
+@@ -114,8 +115,11 @@ static inline void free_one_pgd(struct m
+ 	}
+ 	pmd = pmd_offset(dir, 0);
+ 	pgd_clear(dir);
+-	for (j = 0; j < PTRS_PER_PMD ; j++)
++	for (j = 0; j < PTRS_PER_PMD ; j++) {
++		if (pgd_idx * PGDIR_SIZE + j * PMD_SIZE >= TASK_SIZE)
++			break;
+ 		free_one_pmd(tlb, pmd+j);
++	}
+ 	pmd_free_tlb(tlb, pmd);
+ }
+ 
+@@ -128,11 +132,13 @@ static inline void free_one_pgd(struct m
+ void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr)
+ {
+ 	pgd_t * page_dir = tlb->mm->pgd;
++	int pgd_idx = first;
+ 
+ 	page_dir += first;
+ 	do {
+-		free_one_pgd(tlb, page_dir);
++		free_one_pgd(tlb, page_dir, pgd_idx);
+ 		page_dir++;
++		pgd_idx++;
+ 	} while (--nr);
+ }
+ 
+@@ -430,7 +436,7 @@ zap_pmd_range(struct mmu_gather *tlb, pg
+ 		unsigned long address, unsigned long size)
+ {
+ 	pmd_t * pmd;
+-	unsigned long end;
++	unsigned long end, pgd_boundary;
+ 
+ 	if (pgd_none(*dir))
+ 		return;
+@@ -441,8 +447,9 @@ zap_pmd_range(struct mmu_gather *tlb, pg
+ 	}
+ 	pmd = pmd_offset(dir, address);
+ 	end = address + size;
+-	if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
+-		end = ((address + PGDIR_SIZE) & PGDIR_MASK);
++	pgd_boundary = ((address + PGDIR_SIZE) & PGDIR_MASK);
++	if (pgd_boundary && (end > pgd_boundary))
++		end = pgd_boundary;
+ 	do {
+ 		zap_pte_range(tlb, pmd, address, end - address);
+ 		address = (address + PMD_SIZE) & PMD_MASK; 
+@@ -518,7 +525,7 @@ int unmap_vmas(struct mmu_gather **tlbp,
+ 		unsigned long end_addr, unsigned long *nr_accounted)
+ {
+ 	unsigned long zap_bytes = ZAP_BLOCK_SIZE;
+-	unsigned long tlb_start;	/* For tlb_finish_mmu */
++	unsigned long tlb_start = 0;	/* For tlb_finish_mmu */
+ 	int tlb_start_valid = 0;
+ 	int ret = 0;
+ 
+@@ -596,6 +603,11 @@ void zap_page_range(struct vm_area_struc
+ 	might_sleep();
+ 
+ 	if (is_vm_hugetlb_page(vma)) {
++		static int x;
++		if (x < 10) {
++			x++;
++			dump_stack();
++		}
+ 		zap_hugepage_range(vma, address, size);
+ 		return;
+ 	}
+@@ -678,6 +690,7 @@ int get_user_pages(struct task_struct *t
+ 		struct page **pages, struct vm_area_struct **vmas)
+ {
+ 	int i;
++	int vm_io;
+ 	unsigned int flags;
+ 
+ 	/* 
+@@ -734,8 +747,10 @@ int get_user_pages(struct task_struct *t
+ 		}
+ #endif
+ 
+-		if (!vma || (pages && (vma->vm_flags & VM_IO))
+-				|| !(flags & vma->vm_flags))
++		if (!vma)
++			return i ? : -EFAULT;
++		vm_io = vma->vm_flags & VM_IO;
++		if ((pages && vm_io) || !(flags & vma->vm_flags))
+ 			return i ? : -EFAULT;
+ 
+ 		if (is_vm_hugetlb_page(vma)) {
+@@ -743,9 +758,17 @@ int get_user_pages(struct task_struct *t
+ 						&start, &len, i);
+ 			continue;
+ 		}
++
+ 		spin_lock(&mm->page_table_lock);
+ 		do {
+-			struct page *map;
++			struct page *map = NULL;
++
++			/*
++			 * We don't follow pagetables for VM_IO regions - they
++			 * may have no pageframes.
++			 */
++			if (vm_io)
++				goto no_follow;
+ 			while (!(map = follow_page(mm, start, write))) {
+ 				spin_unlock(&mm->page_table_lock);
+ 				switch (handle_mm_fault(mm,vma,start,write)) {
+@@ -777,6 +800,7 @@ int get_user_pages(struct task_struct *t
+ 				if (!PageReserved(pages[i]))
+ 					page_cache_get(pages[i]);
+ 			}
++no_follow:
+ 			if (vmas)
+ 				vmas[i] = vma;
+ 			i++;
+@@ -1398,7 +1422,7 @@ do_no_page(struct mm_struct *mm, struct 
+ 	spin_unlock(&mm->page_table_lock);
+ 
+ 	if (vma->vm_file) {
+-		mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
++		mapping = vma->vm_file->f_mapping;
+ 		sequence = atomic_read(&mapping->truncate_count);
+ 	}
+ 	smp_rmb();  /* Prevent CPU from reordering lock-free ->nopage() */
+@@ -1441,6 +1465,7 @@ retry:
+ 		sequence = atomic_read(&mapping->truncate_count);
+ 		spin_unlock(&mm->page_table_lock);
+ 		page_cache_release(new_page);
++		pte_chain_free(pte_chain);
+ 		goto retry;
+ 	}
+ 	page_table = pte_offset_map(pmd, address);
+--- linux-2.6.0-test6/mm/mincore.c	2003-06-14 12:18:48.000000000 -0700
++++ 25/mm/mincore.c	2003-10-05 00:34:07.000000000 -0700
+@@ -26,7 +26,7 @@ static unsigned char mincore_page(struct
+ 	unsigned long pgoff)
+ {
+ 	unsigned char present = 0;
+-	struct address_space * as = vma->vm_file->f_dentry->d_inode->i_mapping;
++	struct address_space * as = vma->vm_file->f_mapping;
+ 	struct page * page;
+ 
+ 	page = find_get_page(as, pgoff);
+--- linux-2.6.0-test6/mm/mmap.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/mmap.c	2003-10-05 00:36:32.000000000 -0700
+@@ -79,11 +79,10 @@ static void remove_shared_vm_struct(stru
+ 	struct file *file = vma->vm_file;
+ 
+ 	if (file) {
+-		struct inode *inode = file->f_dentry->d_inode;
+-
+-		down(&inode->i_mapping->i_shared_sem);
+-		__remove_shared_vm_struct(vma, inode);
+-		up(&inode->i_mapping->i_shared_sem);
++		struct address_space *mapping = file->f_mapping;
++		down(&mapping->i_shared_sem);
++		__remove_shared_vm_struct(vma, file->f_dentry->d_inode);
++		up(&mapping->i_shared_sem);
+ 	}
+ }
+ 
+@@ -234,11 +233,10 @@ static inline void __vma_link_file(struc
+ 
+ 	file = vma->vm_file;
+ 	if (file) {
+-		struct inode * inode = file->f_dentry->d_inode;
+-		struct address_space *mapping = inode->i_mapping;
++		struct address_space *mapping = file->f_mapping;
+ 
+ 		if (vma->vm_flags & VM_DENYWRITE)
+-			atomic_dec(&inode->i_writecount);
++			atomic_dec(&file->f_dentry->d_inode->i_writecount);
+ 
+ 		if (vma->vm_flags & VM_SHARED)
+ 			list_add_tail(&vma->shared, &mapping->i_mmap_shared);
+@@ -264,7 +262,7 @@ static void vma_link(struct mm_struct *m
+ 	struct address_space *mapping = NULL;
+ 
+ 	if (vma->vm_file)
+-		mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
++		mapping = vma->vm_file->f_mapping;
+ 
+ 	if (mapping)
+ 		down(&mapping->i_shared_sem);
+@@ -280,6 +278,26 @@ static void vma_link(struct mm_struct *m
+ }
+ 
+ /*
++ * Insert vm structure into process list sorted by address and into the inode's
++ * i_mmap ring. The caller should hold mm->page_table_lock and
++ * ->f_mappping->i_shared_sem if vm_file is non-NULL.
++ */
++static void
++__insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
++{
++	struct vm_area_struct * __vma, * prev;
++	struct rb_node ** rb_link, * rb_parent;
++
++	__vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent);
++	if (__vma && __vma->vm_start < vma->vm_end)
++		BUG();
++	__vma_link(mm, vma, prev, rb_link, rb_parent);
++	mark_mm_hugetlb(mm, vma);
++	mm->map_count++;
++	validate_mm(mm);
++}
++
++/*
+  * If the vma has a ->close operation then the driver probably needs to release
+  * per-vma resources, so we don't attempt to merge those.
+  */
+@@ -351,7 +369,8 @@ static int vma_merge(struct mm_struct *m
+ 			unsigned long end, unsigned long vm_flags,
+ 			struct file *file, unsigned long pgoff)
+ {
+-	spinlock_t * lock = &mm->page_table_lock;
++	spinlock_t *lock = &mm->page_table_lock;
++	struct semaphore *i_shared_sem;
+ 
+ 	/*
+ 	 * We later require that vma->vm_flags == vm_flags, so this tests
+@@ -360,6 +379,8 @@ static int vma_merge(struct mm_struct *m
+ 	if (vm_flags & VM_SPECIAL)
+ 		return 0;
+ 
++	i_shared_sem = file ? &file->f_mapping->i_shared_sem : NULL;
++
+ 	if (!prev) {
+ 		prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
+ 		goto merge_next;
+@@ -377,7 +398,7 @@ static int vma_merge(struct mm_struct *m
+ 
+ 		if (unlikely(file && prev->vm_next &&
+ 				prev->vm_next->vm_file == file)) {
+-			down(&inode->i_mapping->i_shared_sem);
++			down(i_shared_sem);
+ 			need_up = 1;
+ 		}
+ 		spin_lock(lock);
+@@ -395,7 +416,7 @@ static int vma_merge(struct mm_struct *m
+ 			__remove_shared_vm_struct(next, inode);
+ 			spin_unlock(lock);
+ 			if (need_up)
+-				up(&inode->i_mapping->i_shared_sem);
++				up(i_shared_sem);
+ 			if (file)
+ 				fput(file);
+ 
+@@ -405,7 +426,7 @@ static int vma_merge(struct mm_struct *m
+ 		}
+ 		spin_unlock(lock);
+ 		if (need_up)
+-			up(&inode->i_mapping->i_shared_sem);
++			up(i_shared_sem);
+ 		return 1;
+ 	}
+ 
+@@ -419,14 +440,17 @@ static int vma_merge(struct mm_struct *m
+ 				pgoff, (end - addr) >> PAGE_SHIFT))
+ 			return 0;
+ 		if (end == prev->vm_start) {
++			if (file)
++				down(i_shared_sem); /* invalidate_mmap_range */
+ 			spin_lock(lock);
+ 			prev->vm_start = addr;
+ 			prev->vm_pgoff -= (end - addr) >> PAGE_SHIFT;
+ 			spin_unlock(lock);
++			if (file)
++				up(i_shared_sem);
+ 			return 1;
+ 		}
+ 	}
+-
+ 	return 0;
+ }
+ 
+@@ -1136,6 +1160,7 @@ int split_vma(struct mm_struct * mm, str
+ 	      unsigned long addr, int new_below)
+ {
+ 	struct vm_area_struct *new;
++	struct address_space *mapping = NULL;
+ 
+ 	if (mm->map_count >= MAX_MAP_COUNT)
+ 		return -ENOMEM;
+@@ -1149,12 +1174,9 @@ int split_vma(struct mm_struct * mm, str
+ 
+ 	INIT_LIST_HEAD(&new->shared);
+ 
+-	if (new_below) {
++	if (new_below)
+ 		new->vm_end = addr;
+-		vma->vm_start = addr;
+-		vma->vm_pgoff += ((addr - new->vm_start) >> PAGE_SHIFT);
+-	} else {
+-		vma->vm_end = addr;
++	else {
+ 		new->vm_start = addr;
+ 		new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
+ 	}
+@@ -1165,7 +1187,25 @@ int split_vma(struct mm_struct * mm, str
+ 	if (new->vm_ops && new->vm_ops->open)
+ 		new->vm_ops->open(new);
+ 
+-	insert_vm_struct(mm, new);
++	if (vma->vm_file)
++		 mapping = vma->vm_file->f_mapping;
++
++	if (mapping)
++		down(&mapping->i_shared_sem);
++	spin_lock(&mm->page_table_lock);
++
++	if (new_below) {
++		vma->vm_start = addr;
++		vma->vm_pgoff += ((addr - new->vm_start) >> PAGE_SHIFT);
++	} else
++		vma->vm_end = addr;
++
++	__insert_vm_struct(mm, new);
++
++	spin_unlock(&mm->page_table_lock);
++	if (mapping)
++		up(&mapping->i_shared_sem);
++
+ 	return 0;
+ }
+ 
+--- linux-2.6.0-test6/mm/msync.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/mm/msync.c	2003-10-05 00:34:08.000000000 -0700
+@@ -146,20 +146,20 @@ static int msync_interval(struct vm_area
+ 		ret = filemap_sync(vma, start, end-start, flags);
+ 
+ 		if (!ret && (flags & MS_SYNC)) {
+-			struct inode *inode = file->f_dentry->d_inode;
++			struct address_space *mapping = file->f_mapping;
+ 			int err;
+ 
+-			down(&inode->i_sem);
+-			ret = filemap_fdatawrite(inode->i_mapping);
++			down(&mapping->host->i_sem);
++			ret = filemap_fdatawrite(mapping);
+ 			if (file->f_op && file->f_op->fsync) {
+ 				err = file->f_op->fsync(file,file->f_dentry,1);
+ 				if (err && !ret)
+ 					ret = err;
+ 			}
+-			err = filemap_fdatawait(inode->i_mapping);
++			err = filemap_fdatawait(mapping);
+ 			if (!ret)
+ 				ret = err;
+-			up(&inode->i_sem);
++			up(&mapping->host->i_sem);
+ 		}
+ 	}
+ 	return ret;
+--- linux-2.6.0-test6/mm/page_alloc.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/page_alloc.c	2003-10-05 00:34:39.000000000 -0700
+@@ -50,7 +50,7 @@ EXPORT_SYMBOL(nr_swap_pages);
+  * Used by page_zone() to look up the address of the struct zone whose
+  * id is encoded in the upper bits of page->flags
+  */
+-struct zone *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
++struct zone *zone_table[MAX_NR_ZONES*MAX_NUMNODES];
+ EXPORT_SYMBOL(zone_table);
+ 
+ static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+--- linux-2.6.0-test6/mm/page-writeback.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/page-writeback.c	2003-10-05 00:37:06.000000000 -0700
+@@ -28,6 +28,7 @@
+ #include <linux/smp.h>
+ #include <linux/sysctl.h>
+ #include <linux/cpu.h>
++#include <linux/pagevec.h>
+ 
+ /*
+  * The maximum number of pages to writeout in a single bdflush/kupdate
+@@ -146,7 +147,7 @@ get_dirty_limits(struct page_state *ps, 
+  * If we're over `background_thresh' then pdflush is woken to perform some
+  * writeout.
+  */
+-static void balance_dirty_pages(struct address_space *mapping)
++static int balance_dirty_pages(struct address_space *mapping)
+ {
+ 	struct page_state ps;
+ 	long nr_reclaimable;
+@@ -163,6 +164,7 @@ static void balance_dirty_pages(struct a
+ 			.sync_mode	= WB_SYNC_NONE,
+ 			.older_than_this = NULL,
+ 			.nr_to_write	= write_chunk,
++			.nonblocking	= !is_sync_wait(current->io_wait)
+ 		};
+ 
+ 		get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
+@@ -189,7 +191,11 @@ static void balance_dirty_pages(struct a
+ 			if (pages_written >= write_chunk)
+ 				break;		/* We've done our duty */
+ 		}
+-		blk_congestion_wait(WRITE, HZ/10);
++		if (-EIOCBRETRY == blk_congestion_wait_wq(WRITE, HZ/10,
++			current->io_wait)) {
++			pr_debug("async blk congestion wait\n");
++			return -EIOCBRETRY;
++		}
+ 	}
+ 
+ 	if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+@@ -197,6 +203,8 @@ static void balance_dirty_pages(struct a
+ 
+ 	if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
+ 		pdflush_operation(background_writeout, 0);
++
++	return 0;
+ }
+ 
+ /**
+@@ -212,7 +220,7 @@ static void balance_dirty_pages(struct a
+  * decrease the ratelimiting by a lot, to prevent individual processes from
+  * overshooting the limit by (ratelimit_pages) each.
+  */
+-void balance_dirty_pages_ratelimited(struct address_space *mapping)
++int balance_dirty_pages_ratelimited(struct address_space *mapping)
+ {
+ 	static DEFINE_PER_CPU(int, ratelimits) = 0;
+ 	long ratelimit;
+@@ -228,10 +236,10 @@ void balance_dirty_pages_ratelimited(str
+ 	if (get_cpu_var(ratelimits)++ >= ratelimit) {
+ 		__get_cpu_var(ratelimits) = 0;
+ 		put_cpu_var(ratelimits);
+-		balance_dirty_pages(mapping);
+-		return;
++		return balance_dirty_pages(mapping);
+ 	}
+ 	put_cpu_var(ratelimits);
++	return 0;
+ }
+ 
+ /*
+@@ -566,3 +574,152 @@ int test_clear_page_dirty(struct page *p
+ 	return 0;
+ }
+ EXPORT_SYMBOL(test_clear_page_dirty);
++
++
++static ssize_t operate_on_page_range(struct address_space *mapping,
++		loff_t pos, size_t count, int (*operator)(struct page *))
++{
++	pgoff_t first = pos >> PAGE_CACHE_SHIFT;
++	pgoff_t last = (pos + count - 1) >> PAGE_CACHE_SHIFT;	/* inclusive */
++	pgoff_t next = first, curr = first;
++	struct pagevec pvec;
++	ssize_t ret = 0, bytes = 0;
++	int i, nr;
++
++	if (count == 0)
++		return 0;
++
++	pagevec_init(&pvec, 0);
++	while ((nr = pagevec_lookup(&pvec, mapping, &next,
++				min((pgoff_t)PAGEVEC_SIZE, last - next + 1)))) {
++		for (i = 0; i < pagevec_count(&pvec); i++) {
++			struct page *page = pvec.pages[i];
++
++			curr = page->index;
++			if (page->mapping != mapping) /* truncated ?*/ {
++				curr = next;
++				break;
++			} else {
++				ret = (*operator)(page);
++				if (ret == -EIOCBRETRY)
++					break;
++				if (PageError(page)) {
++					if (!ret)
++						ret = -EIO;
++				} else
++					curr++;
++			}
++		}
++		pagevec_release(&pvec);
++		if ((ret == -EIOCBRETRY) || (next > last))
++			break;
++	}
++	if (!nr)
++		curr = last + 1;
++
++	bytes = (curr << PAGE_CACHE_SHIFT) - pos;
++	if (bytes > count)
++		bytes = count;
++	return (bytes && (!ret || (ret == -EIOCBRETRY))) ? bytes : ret;
++}
++
++static int page_waiter(struct page *page)
++{
++	return wait_on_page_writeback_wq(page, current->io_wait);
++}
++
++static size_t
++wait_on_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++	return operate_on_page_range(mapping, pos, count, page_waiter);
++}
++
++static int page_writer(struct page *page)
++{
++	struct writeback_control wbc = {
++		.sync_mode	= WB_SYNC_ALL,
++		.nr_to_write	= 1,
++	};
++
++	lock_page(page);
++	if (!page->mapping) {	/* truncated */
++		unlock_page(page);
++		return 0;
++	}
++	if (!test_clear_page_dirty(page)) {
++		unlock_page(page);
++		return 0;
++	}
++	wait_on_page_writeback(page);
++	return page->mapping->a_ops->writepage(page, &wbc);
++}
++
++static ssize_t
++write_out_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++	return operate_on_page_range(mapping, pos, count, page_writer);
++}
++
++/*
++ * Write and wait upon all the pages in the passed range.  This is a "data
++ * integrity" operation.  It waits upon in-flight writeout before starting and
++ * waiting upon new writeout.  If there was an IO error, return it.
++ *
++ * We need to re-take i_sem during the generic_osync_inode list walk because
++ * it is otherwise livelockable.
++ */
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++			loff_t pos, size_t count)
++{
++	int ret = 0;
++
++	if (in_aio()) {
++		/* Already issued writeouts for this iocb ? */
++		if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++			goto do_wait; /* just need to check if done */
++	}
++	if (!mapping->a_ops->writepage)
++		return 0;
++	if (mapping->backing_dev_info->memory_backed)
++		return 0;
++	ret = write_out_page_range(mapping, pos, count);
++	if (ret >= 0) {
++		down(&inode->i_sem);
++		ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++		up(&inode->i_sem);
++	}
++do_wait:
++	if (ret >= 0)
++		ret = wait_on_page_range(mapping, pos, count);
++	return ret;
++}
++
++/*
++ * It is really better to use sync_page_range, rather than call
++ * sync_page_range_nolock while holding i_sem, if you don't
++ * want to block parallel O_SYNC writes until the pages in this
++ * range are written out.
++ */
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++	*mapping, loff_t pos, size_t count)
++{
++	ssize_t ret = 0;
++
++	if (in_aio()) {
++		/* Already issued writeouts for this iocb ? */
++		if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++			goto do_wait; /* just need to check if done */
++	}
++	if (!mapping->a_ops->writepage)
++		return 0;
++	if (mapping->backing_dev_info->memory_backed)
++		return 0;
++	ret = write_out_page_range(mapping, pos, count);
++	if (ret >= 0) {
++		ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++	}
++do_wait:
++	if (ret >= 0)
++		ret = wait_on_page_range(mapping, pos, count);
++	return ret;
++}
+--- linux-2.6.0-test6/mm/pdflush.c	2003-06-14 12:18:52.000000000 -0700
++++ 25/mm/pdflush.c	2003-10-05 00:34:35.000000000 -0700
+@@ -84,6 +84,8 @@ struct pdflush_work {
+ 	unsigned long when_i_went_to_sleep;
+ };
+ 
++static int wakeup_count = 100;
++
+ static int __pdflush(struct pdflush_work *my_work)
+ {
+ 	daemonize("pdflush");
+@@ -112,7 +114,10 @@ static int __pdflush(struct pdflush_work
+ 
+ 		spin_lock_irq(&pdflush_lock);
+ 		if (!list_empty(&my_work->list)) {
+-			printk("pdflush: bogus wakeup!\n");
++			if (wakeup_count > 0) {
++				wakeup_count--;
++				printk("pdflush: bogus wakeup!\n");
++			}
+ 			my_work->fn = NULL;
+ 			continue;
+ 		}
+@@ -182,6 +187,7 @@ int pdflush_operation(void (*fn)(unsigne
+ {
+ 	unsigned long flags;
+ 	int ret = 0;
++	static int poke_count = 0;
+ 
+ 	if (fn == NULL)
+ 		BUG();		/* Hard to diagnose if it's deferred */
+@@ -190,9 +196,19 @@ int pdflush_operation(void (*fn)(unsigne
+ 	if (list_empty(&pdflush_list)) {
+ 		spin_unlock_irqrestore(&pdflush_lock, flags);
+ 		ret = -1;
++		if (wakeup_count < 100 && poke_count < 10) {
++			printk("%s: no threads\n", __FUNCTION__);
++			dump_stack();
++			poke_count++;
++		}
+ 	} else {
+ 		struct pdflush_work *pdf;
+ 
++		if (wakeup_count < 100 && poke_count < 10) {
++			printk("%s: found a thread\n", __FUNCTION__);
++			dump_stack();
++			poke_count++;
++		}
+ 		pdf = list_entry(pdflush_list.next, struct pdflush_work, list);
+ 		list_del_init(&pdf->list);
+ 		if (list_empty(&pdflush_list))
+--- linux-2.6.0-test6/mm/shmem.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/shmem.c	2003-10-05 00:34:11.000000000 -0700
+@@ -1147,7 +1147,7 @@ shmem_file_write(struct file *file, cons
+ 	pos = *ppos;
+ 	written = 0;
+ 
+-	err = generic_write_checks(inode, file, &pos, &count, 0);
++	err = generic_write_checks(file, &pos, &count, 0);
+ 	if (err || !count)
+ 		goto out;
+ 
+@@ -1933,6 +1933,7 @@ struct file *shmem_file_setup(char *name
+ 	inode->i_nlink = 0;	/* It is unlinked */
+ 	file->f_vfsmnt = mntget(shm_mnt);
+ 	file->f_dentry = dentry;
++	file->f_mapping = inode->i_mapping;
+ 	file->f_op = &shmem_file_operations;
+ 	file->f_mode = FMODE_WRITE | FMODE_READ;
+ 	return(file);
+--- linux-2.6.0-test6/mm/slab.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/mm/slab.c	2003-10-05 00:36:48.000000000 -0700
+@@ -250,7 +250,7 @@ struct kmem_cache_s {
+ 	unsigned int		limit;
+ /* 2) touched by every alloc & free from the backend */
+ 	struct kmem_list3	lists;
+-	/* NUMA: kmem_3list_t	*nodelists[NR_NODES] */
++	/* NUMA: kmem_3list_t	*nodelists[MAX_NUMNODES] */
+ 	unsigned int		objsize;
+ 	unsigned int	 	flags;	/* constant flags */
+ 	unsigned int		num;	/* # of objs per slab */
+@@ -1178,7 +1178,8 @@ next:
+ 		cachep = NULL;
+ 		goto opps;
+ 	}
+-	slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab));
++	slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t) +
++			sizeof(struct slab));
+ 
+ 	/*
+ 	 * If the slab has been placed off-slab, and we have enough space then
+@@ -1222,10 +1223,13 @@ next:
+ 			 * the cache that's used by kmalloc(24), otherwise
+ 			 * the creation of further caches will BUG().
+ 			 */
+-			cachep->array[smp_processor_id()] = &initarray_generic.cache;
++			cachep->array[smp_processor_id()] =
++					&initarray_generic.cache;
+ 			g_cpucache_up = PARTIAL;
+ 		} else {
+-			cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL);
++			cachep->array[smp_processor_id()] =
++				kmalloc(sizeof(struct arraycache_init),
++					GFP_KERNEL);
+ 		}
+ 		BUG_ON(!ac_data(cachep));
+ 		ac_data(cachep)->avail = 0;
+@@ -1239,7 +1243,7 @@ next:
+ 	} 
+ 
+ 	cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
+-					((unsigned long)cachep)%REAPTIMEOUT_LIST3;
++				((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+ 
+ 	/* Need the semaphore to access the chain. */
+ 	down(&cache_chain_sem);
+@@ -1252,16 +1256,24 @@ next:
+ 		list_for_each(p, &cache_chain) {
+ 			kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+ 			char tmp;
+-			/* This happens when the module gets unloaded and doesn't
+-			   destroy its slab cache and noone else reuses the vmalloc
+-			   area of the module. Print a warning. */
+-			if (__get_user(tmp,pc->name)) { 
+-				printk("SLAB: cache with size %d has lost its name\n", 
+-					pc->objsize); 
++
++			/*
++			 * This happens when the module gets unloaded and
++			 * doesn't destroy its slab cache and noone else reuses
++			 * the vmalloc area of the module. Print a warning.
++			 */
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++			if (__direct_get_user(tmp,pc->name)) {
++#else
++			if (__get_user(tmp,pc->name)) {
++#endif
++				printk("SLAB: cache with size %d has lost its "
++						"name\n", pc->objsize);
+ 				continue; 
+ 			} 	
+ 			if (!strcmp(pc->name,name)) { 
+-				printk("kmem_cache_create: duplicate cache %s\n",name); 
++				printk("kmem_cache_create: duplicate "
++						"cache %s\n",name);
+ 				up(&cache_chain_sem); 
+ 				BUG(); 
+ 			}	
+@@ -2675,8 +2687,8 @@ struct seq_operations slabinfo_op = {
+  * slabinfo_write - Tuning for the slab allocator
+  * @file: unused
+  * @buffer: user buffer
+- * @count: data len
+- * @data: unused
++ * @count: data length
++ * @ppos: unused
+  */
+ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
+ 				size_t count, loff_t *ppos)
+--- linux-2.6.0-test6/mm/swap.c	2003-07-10 18:50:32.000000000 -0700
++++ 25/mm/swap.c	2003-10-05 00:37:03.000000000 -0700
+@@ -339,12 +339,15 @@ void pagevec_strip(struct pagevec *pvec)
+  * The search returns a group of mapping-contiguous pages with ascending
+  * indexes.  There may be holes in the indices due to not-present pages.
+  *
+- * pagevec_lookup() returns the number of pages which were found.
++ * pagevec_lookup() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+  */
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+-		pgoff_t start, unsigned int nr_pages)
++		pgoff_t *next, unsigned int nr_pages)
+ {
+-	pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
++	pvec->nr = find_get_pages(mapping, next, nr_pages, pvec->pages);
+ 	return pagevec_count(pvec);
+ }
+ 
+--- linux-2.6.0-test6/mm/swapfile.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/mm/swapfile.c	2003-10-05 00:34:11.000000000 -0700
+@@ -912,7 +912,7 @@ static int setup_swap_extents(struct swa
+ 	sector_t last_block;
+ 	int ret;
+ 
+-	inode = sis->swap_file->f_dentry->d_inode;
++	inode = sis->swap_file->f_mapping->host;
+ 	if (S_ISBLK(inode->i_mode)) {
+ 		ret = add_swap_extent(sis, 0, sis->max, 0);
+ 		goto done;
+@@ -1031,13 +1031,13 @@ asmlinkage long sys_swapoff(const char _
+ 	if (IS_ERR(victim))
+ 		goto out;
+ 
+-	mapping = victim->f_dentry->d_inode->i_mapping;
++	mapping = victim->f_mapping;
+ 	prev = -1;
+ 	swap_list_lock();
+ 	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
+ 		p = swap_info + type;
+ 		if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) {
+-			if (p->swap_file->f_dentry->d_inode->i_mapping==mapping)
++			if (p->swap_file->f_mapping == mapping)
+ 				break;
+ 		}
+ 		prev = type;
+@@ -1099,13 +1099,12 @@ asmlinkage long sys_swapoff(const char _
+ 	swap_device_unlock(p);
+ 	swap_list_unlock();
+ 	vfree(swap_map);
+-	if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode)) {
+-		struct block_device *bdev;
+-		bdev = swap_file->f_dentry->d_inode->i_bdev;
++	if (S_ISBLK(mapping->host->i_mode)) {
++		struct block_device *bdev = I_BDEV(mapping->host);
+ 		set_blocksize(bdev, p->old_block_size);
+ 		bd_release(bdev);
+ 	} else {
+-		up(&swap_file->f_dentry->d_inode->i_mapping->host->i_sem);
++		up(&mapping->host->i_sem);
+ 	}
+ 	filp_close(swap_file, NULL);
+ 	err = 0;
+@@ -1231,8 +1230,8 @@ asmlinkage long sys_swapon(const char __
+ 	int swapfilesize;
+ 	unsigned short *swap_map;
+ 	struct page *page = NULL;
+-	struct inode *inode;
+-	struct inode *downed_inode = NULL;
++	struct inode *inode = NULL;
++	int did_down = 0;
+ 
+ 	if (!capable(CAP_SYS_ADMIN))
+ 		return -EPERM;
+@@ -1279,8 +1278,8 @@ asmlinkage long sys_swapon(const char __
+ 	}
+ 
+ 	p->swap_file = swap_file;
+-	inode = swap_file->f_dentry->d_inode;
+-	mapping = swap_file->f_dentry->d_inode->i_mapping;
++	mapping = swap_file->f_mapping;
++	inode = mapping->host;
+ 
+ 	error = -EBUSY;
+ 	for (i = 0; i < nr_swapfiles; i++) {
+@@ -1288,32 +1287,32 @@ asmlinkage long sys_swapon(const char __
+ 
+ 		if (i == type || !q->swap_file)
+ 			continue;
+-		if (mapping == q->swap_file->f_dentry->d_inode->i_mapping)
++		if (mapping == q->swap_file->f_mapping)
+ 			goto bad_swap;
+ 	}
+ 
+ 	error = -EINVAL;
+ 	if (S_ISBLK(inode->i_mode)) {
+-		bdev = inode->i_bdev;
++		bdev = I_BDEV(inode);
+ 		error = bd_claim(bdev, sys_swapon);
+ 		if (error < 0) {
+ 			bdev = NULL;
+ 			goto bad_swap;
+ 		}
+ 		p->old_block_size = block_size(bdev);
+-		error = set_blocksize(inode->i_bdev, PAGE_SIZE);
++		error = set_blocksize(bdev, PAGE_SIZE);
+ 		if (error < 0)
+ 			goto bad_swap;
+ 		p->bdev = bdev;
+ 	} else if (S_ISREG(inode->i_mode)) {
+ 		p->bdev = inode->i_sb->s_bdev;
+-		downed_inode = mapping->host;
+-		down(&downed_inode->i_sem);
++		down(&inode->i_sem);
++		did_down = 1;
+ 	} else {
+ 		goto bad_swap;
+ 	}
+ 
+-	swapfilesize = i_size_read(mapping->host) >> PAGE_SHIFT;
++	swapfilesize = i_size_read(inode) >> PAGE_SHIFT;
+ 
+ 	/*
+ 	 * Read the swap header.
+@@ -1461,8 +1460,8 @@ out:
+ 	}
+ 	if (name)
+ 		putname(name);
+-	if (error && downed_inode)
+-		up(&downed_inode->i_sem);
++	if (error && did_down)
++		up(&inode->i_sem);
+ 	return error;
+ }
+ 
+--- linux-2.6.0-test6/mm/truncate.c	2003-06-14 12:18:34.000000000 -0700
++++ 25/mm/truncate.c	2003-10-05 00:37:03.000000000 -0700
+@@ -121,14 +121,10 @@ void truncate_inode_pages(struct address
+ 
+ 	pagevec_init(&pvec, 0);
+ 	next = start;
+-	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++	while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ 		for (i = 0; i < pagevec_count(&pvec); i++) {
+ 			struct page *page = pvec.pages[i];
+-			pgoff_t page_index = page->index;
+ 
+-			if (page_index > next)
+-				next = page_index;
+-			next++;
+ 			if (TestSetPageLocked(page))
+ 				continue;
+ 			if (PageWriteback(page)) {
+@@ -154,7 +150,7 @@ void truncate_inode_pages(struct address
+ 
+ 	next = start;
+ 	for ( ; ; ) {
+-		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++		if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ 			if (next == start)
+ 				break;
+ 			next = start;
+@@ -165,9 +161,6 @@ void truncate_inode_pages(struct address
+ 
+ 			lock_page(page);
+ 			wait_on_page_writeback(page);
+-			if (page->index > next)
+-				next = page->index;
+-			next++;
+ 			truncate_complete_page(mapping, page);
+ 			unlock_page(page);
+ 		}
+@@ -198,17 +191,13 @@ unsigned long invalidate_mapping_pages(s
+ 
+ 	pagevec_init(&pvec, 0);
+ 	while (next <= end &&
+-			pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++			pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ 		for (i = 0; i < pagevec_count(&pvec); i++) {
+ 			struct page *page = pvec.pages[i];
+ 
+ 			if (TestSetPageLocked(page)) {
+-				next++;
+ 				continue;
+ 			}
+-			if (page->index > next)
+-				next = page->index;
+-			next++;
+ 			if (PageDirty(page) || PageWriteback(page))
+ 				goto unlock;
+ 			if (page_mapped(page))
+@@ -245,14 +234,13 @@ void invalidate_inode_pages2(struct addr
+ 	int i;
+ 
+ 	pagevec_init(&pvec, 0);
+-	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++	while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+ 		for (i = 0; i < pagevec_count(&pvec); i++) {
+ 			struct page *page = pvec.pages[i];
+ 
+ 			lock_page(page);
+ 			if (page->mapping == mapping) {	/* truncate race? */
+ 				wait_on_page_writeback(page);
+-				next = page->index + 1;
+ 				if (page_mapped(page))
+ 					clear_page_dirty(page);
+ 				else
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/mm/usercopy.c	2003-10-05 00:36:48.000000000 -0700
+@@ -0,0 +1,279 @@
++/*
++ * linux/mm/usercopy.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * Generic implementation of all the user-VM access functions, without
++ * relying on being able to access the VM directly.
++ */
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/highmem.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/ptrace.h>
++#include <linux/interrupt.h>
++
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++#include <asm/atomic_kmap.h>
++
++/*
++ * Get kernel address of the user page and pin it.
++ */
++static inline struct page *pin_page(unsigned long addr, int write)
++{
++	struct mm_struct *mm = current->mm ? : &init_mm;
++	struct page *page = NULL;
++	int ret;
++
++	spin_lock(&mm->page_table_lock);
++	/*
++	 * Do a quick atomic lookup first - this is the fastpath.
++	 */
++	page = follow_page(mm, addr, write);
++	if (likely(page != NULL)) {
++		if (!PageReserved(page))
++			get_page(page);
++		spin_unlock(&mm->page_table_lock);
++		return page;
++	}
++
++	/*
++	 * No luck - bad address or need to fault in the page:
++	 */
++	spin_unlock(&mm->page_table_lock);
++
++	/*
++	 * In the context of filemap_copy_from_user(), we are not allowed
++	 * to sleep.  We must fail this usercopy attempt and allow
++	 * filemap_copy_from_user() to recover: drop its atomic kmap and use
++	 * a sleeping kmap instead.
++	 */
++	if (in_atomic())
++		return NULL;
++
++	down_read(&mm->mmap_sem);
++	ret = get_user_pages(current, mm, addr, 1, write, 0, &page, NULL);
++	up_read(&mm->mmap_sem);
++	if (ret <= 0)
++		return NULL;
++	return page;
++}
++
++static inline void unpin_page(struct page *page)
++{
++	put_page(page);
++}
++
++/*
++ * Access another process' address space.
++ * Source/target buffer must be kernel space,
++ * Do not walk the page table directly, use get_user_pages
++ */
++static int rw_vm(unsigned long addr, void *buf, int len, int write)
++{
++	if (!len)
++		return 0;
++
++	/* ignore errors, just check how much was sucessfully transfered */
++	while (len) {
++		struct page *page = NULL;
++		int bytes, offset;
++		void *maddr;
++
++		page = pin_page(addr, write);
++		if (!page)
++			break;
++
++		bytes = len;
++		offset = addr & (PAGE_SIZE-1);
++		if (bytes > PAGE_SIZE-offset)
++			bytes = PAGE_SIZE-offset;
++
++		maddr = kmap_atomic(page, KM_USER_COPY);
++
++#define HANDLE_TYPE(type) \
++	case sizeof(type): *(type *)(maddr+offset) = *(type *)(buf); break;
++
++		if (write) {
++			switch (bytes) {
++			HANDLE_TYPE(char);
++			HANDLE_TYPE(int);
++			HANDLE_TYPE(long long);
++			default:
++				memcpy(maddr + offset, buf, bytes);
++			}
++		} else {
++#undef HANDLE_TYPE
++#define HANDLE_TYPE(type) \
++	case sizeof(type): *(type *)(buf) = *(type *)(maddr+offset); break;
++			switch (bytes) {
++			HANDLE_TYPE(char);
++			HANDLE_TYPE(int);
++			HANDLE_TYPE(long long);
++			default:
++				memcpy(buf, maddr + offset, bytes);
++			}
++#undef HANDLE_TYPE
++		}
++		kunmap_atomic(maddr, KM_USER_COPY);
++		unpin_page(page);
++		len -= bytes;
++		buf += bytes;
++		addr += bytes;
++	}
++
++	return len;
++}
++
++static int str_vm(unsigned long addr, void *buf0, int len, int copy)
++{
++	struct mm_struct *mm = current->mm ? : &init_mm;
++	struct page *page;
++	void *buf = buf0;
++
++	if (!len)
++		return len;
++
++	down_read(&mm->mmap_sem);
++	/* ignore errors, just check how much was sucessfully transfered */
++	while (len) {
++		int bytes, ret, offset, left, copied;
++		char *maddr;
++
++		ret = get_user_pages(current, mm, addr, 1, copy == 2, 0, &page, NULL);
++		if (ret <= 0) {
++			up_read(&mm->mmap_sem);
++			return -EFAULT;
++		}
++
++		bytes = len;
++		offset = addr & (PAGE_SIZE-1);
++		if (bytes > PAGE_SIZE-offset)
++			bytes = PAGE_SIZE-offset;
++
++		maddr = kmap_atomic(page, KM_USER_COPY);
++		if (copy == 2) {
++			memset(maddr + offset, 0, bytes);
++			copied = bytes;
++			left = 0;
++		} else if (copy == 1) {
++			left = strncpy_count(buf, maddr + offset, bytes);
++			copied = bytes - left;
++		} else {
++			copied = strnlen(maddr + offset, bytes);
++			left = bytes - copied;
++		}
++		BUG_ON(bytes < 0 || copied < 0);
++		kunmap_atomic(maddr, KM_USER_COPY);
++		page_cache_release(page);
++		len -= copied;
++		buf += copied;
++		addr += copied;
++		if (left)
++			break;
++	}
++	up_read(&mm->mmap_sem);
++
++	return len;
++}
++
++/*
++ * Copies memory from userspace (ptr) into kernelspace (val).
++ *
++ * returns # of bytes not copied.
++ */
++int get_user_size(unsigned int size, void *val, const void *ptr)
++{
++	int ret;
++
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++		__direct_copy_from_user(val, ptr, size);
++		return 0;
++	}
++	ret = rw_vm((unsigned long)ptr, val, size, 0);
++	if (ret)
++		/*
++		 * Zero the rest:
++		 */
++		memset(val + size - ret, 0, ret);
++	return ret;
++}
++
++/*
++ * Copies memory from kernelspace (val) into userspace (ptr).
++ *
++ * returns # of bytes not copied.
++ */
++int put_user_size(unsigned int size, const void *val, void *ptr)
++{
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++		__direct_copy_to_user(ptr, val, size);
++		return 0;
++	}
++	return rw_vm((unsigned long)ptr, (void *)val, size, 1);
++}
++
++int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr)
++{
++	int copied, left;
++
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++		left = strncpy_count(val, ptr, size);
++		copied = size - left;
++		BUG_ON(copied < 0);
++
++		return copied;
++	}
++	left = str_vm((unsigned long)ptr, val, size, 1);
++	if (left < 0)
++		return left;
++	copied = size - left;
++	BUG_ON(copied < 0);
++
++	return copied;
++}
++
++int strlen_fromuser_size(unsigned int size, const void *ptr)
++{
++	int copied, left;
++
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++		copied = strnlen(ptr, size) + 1;
++		BUG_ON(copied < 0);
++
++		return copied;
++	}
++	left = str_vm((unsigned long)ptr, NULL, size, 0);
++	if (left < 0)
++		return 0;
++	copied = size - left + 1;
++	BUG_ON(copied < 0);
++
++	return copied;
++}
++
++int zero_user_size(unsigned int size, void *ptr)
++{
++	int left;
++
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++		memset(ptr, 0, size);
++		return 0;
++	}
++	left = str_vm((unsigned long)ptr, NULL, size, 2);
++	if (left < 0)
++		return size;
++	return left;
++}
++
++EXPORT_SYMBOL(get_user_size);
++EXPORT_SYMBOL(put_user_size);
++EXPORT_SYMBOL(zero_user_size);
++EXPORT_SYMBOL(copy_str_fromuser_size);
++EXPORT_SYMBOL(strlen_fromuser_size);
++
+--- linux-2.6.0-test6/mm/vmalloc.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/mm/vmalloc.c	2003-10-05 00:33:25.000000000 -0700
+@@ -135,23 +135,23 @@ static int map_area_pmd(pmd_t *pmd, unsi
+ 
+ void unmap_vm_area(struct vm_struct *area)
+ {
+-	unsigned long address = VMALLOC_VMADDR(area->addr);
++	unsigned long address = (unsigned long) area->addr;
+ 	unsigned long end = (address + area->size);
+ 	pgd_t *dir;
+ 
+ 	dir = pgd_offset_k(address);
+-	flush_cache_all();
++	flush_cache_vunmap(address, end);
+ 	do {
+ 		unmap_area_pmd(dir, address, end - address);
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
+-	flush_tlb_kernel_range(VMALLOC_VMADDR(area->addr), end);
++	flush_tlb_kernel_range((unsigned long) area->addr, end);
+ }
+ 
+ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
+ {
+-	unsigned long address = VMALLOC_VMADDR(area->addr);
++	unsigned long address = (unsigned long) area->addr;
+ 	unsigned long end = address + (area->size-PAGE_SIZE);
+ 	pgd_t *dir;
+ 	int err = 0;
+@@ -174,7 +174,7 @@ int map_vm_area(struct vm_struct *area, 
+ 	} while (address && (address < end));
+ 
+ 	spin_unlock(&init_mm.page_table_lock);
+-	flush_cache_all();
++	flush_cache_vmap((unsigned long) area->addr, end);
+ 	return err;
+ }
+ 
+--- linux-2.6.0-test6/net/802/fddi.c	2003-06-14 12:18:30.000000000 -0700
++++ 25/net/802/fddi.c	2003-10-05 00:33:25.000000000 -0700
+@@ -27,6 +27,7 @@
+  */
+  
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <asm/system.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+@@ -163,3 +164,5 @@ unsigned short fddi_type_trans(struct sk
+ 
+ 	return(type);
+ }
++
++EXPORT_SYMBOL(fddi_type_trans);
+--- linux-2.6.0-test6/net/802/hippi.c	2003-06-14 12:18:21.000000000 -0700
++++ 25/net/802/hippi.c	2003-10-05 00:33:25.000000000 -0700
+@@ -20,6 +20,7 @@
+  *		2 of the License, or (at your option) any later version.
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -151,3 +152,5 @@ unsigned short hippi_type_trans(struct s
+ 
+ 	return hip->snap.ethertype;
+ }
++
++EXPORT_SYMBOL(hippi_type_trans);
+--- linux-2.6.0-test6/net/802/p8023.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/net/802/p8023.c	2003-10-05 00:33:25.000000000 -0700
+@@ -12,22 +12,24 @@
+  *	running raw 802.3 on different devices. Thankfully nobody else
+  *	has done anything like the old IPX.
+  */
+- 
++
++#include <linux/in.h>
++#include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
++
+ #include <net/datalink.h>
+-#include <linux/mm.h>
+-#include <linux/in.h>
+ 
+ /*
+  *	Place an 802.3 header on a packet. The driver will do the mac
+  *	addresses, we just need to give it the buffer length.
+  */
+- 
+-static int p8023_request(struct datalink_proto *dl, 
+-		struct sk_buff *skb, unsigned char *dest_node)
++static int p8023_request(struct datalink_proto *dl,
++			 struct sk_buff *skb, unsigned char *dest_node)
+ {
+-	struct net_device	*dev = skb->dev;
++	struct net_device *dev = skb->dev;
++
+ 	dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
+ 	return dev_queue_xmit(skb);
+ }
+@@ -35,16 +37,13 @@ static int p8023_request(struct datalink
+ /*
+  *	Create an 802.3 client. Note there can be only one 802.3 client
+  */
+- 
+ struct datalink_proto *make_8023_client(void)
+ {
+-	struct datalink_proto	*proto;
++	struct datalink_proto *proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
+ 
+-	proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
+-	if (proto != NULL) 
+-	{
++	if (proto) {
+ 		proto->header_length = 0;
+-		proto->request = p8023_request;
++		proto->request	     = p8023_request;
+ 	}
+ 	return proto;
+ }
+@@ -52,10 +51,11 @@ struct datalink_proto *make_8023_client(
+ /*
+  *	Destroy the 802.3 client.
+  */
+- 
+ void destroy_8023_client(struct datalink_proto *dl)
+ {
+ 	if (dl)
+ 		kfree(dl);
+ }
+ 
++EXPORT_SYMBOL(destroy_8023_client);
++EXPORT_SYMBOL(make_8023_client);
+--- linux-2.6.0-test6/net/802/tr.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/802/tr.c	2003-10-05 00:33:25.000000000 -0700
+@@ -18,6 +18,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/jiffies.h>
+@@ -600,3 +601,6 @@ static int __init rif_init(void)
+ }
+ 
+ module_init(rif_init);
++
++EXPORT_SYMBOL(tr_source_route);
++EXPORT_SYMBOL(tr_type_trans);
+--- /dev/null	2002-08-30 16:31:37.000000000 -0700
++++ 25/net/bridge/netfilter/ebt_limit.c	2003-10-05 00:33:25.000000000 -0700
+@@ -0,0 +1,104 @@
++/*
++ *  ebt_limit
++ *
++ *	Authors:
++ *	Tom Marshall <tommy@home.tig-grr.com>
++ *
++ *	Mostly copied from netfilter's ipt_limit.c, see that file for
++ *	more explanation
++ *
++ *  September, 2003
++ *
++ */
++
++#include <linux/netfilter_bridge/ebtables.h>
++#include <linux/netfilter_bridge/ebt_limit.h>
++#include <linux/module.h>
++
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++
++static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
++
++#define CREDITS_PER_JIFFY 128
++
++static int ebt_limit_match(const struct sk_buff *skb,
++   const struct net_device *in, const struct net_device *out,
++   const void *data, unsigned int datalen)
++{
++	struct ebt_limit_info *info = (struct ebt_limit_info *)data;
++	unsigned long now = jiffies;
++
++	spin_lock_bh(&limit_lock);
++	info->credit += (now - xchg(&info->prev, now)) * CREDITS_PER_JIFFY;
++	if (info->credit > info->credit_cap)
++		info->credit = info->credit_cap;
++
++	if (info->credit >= info->cost) {
++		/* We're not limited. */
++		info->credit -= info->cost;
++		spin_unlock_bh(&limit_lock);
++		return EBT_MATCH;
++	}
++
++	spin_unlock_bh(&limit_lock);
++	return EBT_NOMATCH;
++}
++
++/* Precision saver. */
++static u_int32_t
++user2credits(u_int32_t user)
++{
++	/* If multiplying would overflow... */
++	if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
++		/* Divide first. */
++		return (user / EBT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
++
++	return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
++}
++
++static int ebt_limit_check(const char *tablename, unsigned int hookmask,
++   const struct ebt_entry *e, void *data, unsigned int datalen)
++{
++	struct ebt_limit_info *info = (struct ebt_limit_info *)data;
++
++	if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
++		return -EINVAL;
++
++	/* Check for overflow. */
++	if (info->burst == 0 ||
++	    user2credits(info->avg * info->burst) < user2credits(info->avg)) {
++		printk("Overflow in ebt_limit: %u/%u\n",
++			info->avg, info->burst);
++		return -EINVAL;
++	}
++
++	/* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
++	info->prev = jiffies;
++	info->credit = user2credits(info->avg * info->burst);
++	info->credit_cap = user2credits(info->avg * info->burst);
++	info->cost = user2credits(info->avg);
++	return 0;
++}
++
++static struct ebt_match ebt_limit_reg =
++{
++	.name		= EBT_LIMIT_MATCH,
++	.match		= ebt_limit_match,
++	.check		= ebt_limit_check,
++	.me		= THIS_MODULE,
++};
++
++static int __init init(void)
++{
++	return ebt_register_match(&ebt_limit_reg);
++}
++
++static void __exit fini(void)
++{
++	ebt_unregister_match(&ebt_limit_reg);
++}
++
++module_init(init);
++module_exit(fini);
++MODULE_LICENSE("GPL");
+--- linux-2.6.0-test6/net/bridge/netfilter/ebt_vlan.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/net/bridge/netfilter/ebt_vlan.c	2003-10-05 00:33:25.000000000 -0700
+@@ -48,7 +48,7 @@ ebt_filter_vlan(const struct sk_buff *sk
+ 		const void *data, unsigned int datalen)
+ {
+ 	struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
+-	struct vlan_ethhdr frame;
++	struct vlan_hdr frame;
+ 
+ 	unsigned short TCI;	/* Whole TCI, given from parsed frame */
+ 	unsigned short id;	/* VLAN ID, given from frame TCI */
+--- linux-2.6.0-test6/net/bridge/netfilter/Kconfig	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/bridge/netfilter/Kconfig	2003-10-05 00:33:25.000000000 -0700
+@@ -73,6 +73,17 @@ config BRIDGE_EBT_IP
+ 
+ 	  To compile it as a module, choose M here.  If unsure, say N.
+ 
++config BRIDGE_EBT_LIMIT
++	tristate "ebt: limit match support"
++	depends on BRIDGE_NF_EBTABLES
++	help
++	  This option adds the limit match, which allows you to control
++	  the rate at which a rule can be matched. This match is the
++	  equivalent of the iptables limit match.
++
++	  If you want to compile it as a module, say M here and read
++	  <file:Documentation/modules.txt>.  If unsure, say `N'.
++
+ config BRIDGE_EBT_MARK
+ 	tristate "ebt: mark filter support"
+ 	depends on BRIDGE_NF_EBTABLES
+--- linux-2.6.0-test6/net/bridge/netfilter/Makefile	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/bridge/netfilter/Makefile	2003-10-05 00:33:25.000000000 -0700
+@@ -13,6 +13,7 @@ obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtabl
+ obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o
+ obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o
+ obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o
++obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o
+ obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o
+ obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o
+ obj-$(CONFIG_BRIDGE_EBT_STP) += ebt_stp.o
+--- linux-2.6.0-test6/net/core/datagram.c	2003-06-14 12:18:24.000000000 -0700
++++ 25/net/core/datagram.c	2003-10-05 00:33:25.000000000 -0700
+@@ -33,6 +33,7 @@
+  *
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <asm/uaccess.h>
+@@ -485,3 +486,10 @@ unsigned int datagram_poll(struct file *
+ 
+ 	return mask;
+ }
++
++EXPORT_SYMBOL(datagram_poll);
++EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
++EXPORT_SYMBOL(skb_copy_datagram);
++EXPORT_SYMBOL(skb_copy_datagram_iovec);
++EXPORT_SYMBOL(skb_free_datagram);
++EXPORT_SYMBOL(skb_recv_datagram);
+--- linux-2.6.0-test6/net/core/dev.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/core/dev.c	2003-10-05 00:36:10.000000000 -0700
+@@ -111,6 +111,10 @@
+ #endif	/* CONFIG_NET_RADIO */
+ #include <asm/current.h>
+ 
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#endif
++
+ /* This define, if set, will randomly drop a packet when congestion
+  * is more than moderate.  It helps fairness in the multi-interface
+  * case when one of them is a hog, but it kills performance for the
+@@ -915,6 +919,8 @@ int unregister_netdevice_notifier(struct
+ 
+ /**
+  *	call_netdevice_notifiers - call all network notifier blocks
++ *      @val: value passed unmodified to notifier function
++ *      @v:   pointer passed unmodified to notifier function
+  *
+  *	Call all network notifier blocks.  Parameters and return value
+  *	are as for notifier_call_chain().
+@@ -1322,7 +1328,6 @@ static void sample_queue(unsigned long d
+ }
+ #endif
+ 
+-
+ /**
+  *	netif_rx	-	post buffer to the network code
+  *	@skb: buffer to post
+@@ -1347,6 +1352,21 @@ int netif_rx(struct sk_buff *skb)
+ 	struct softnet_data *queue;
+ 	unsigned long flags;
+ 
++#ifdef CONFIG_KGDB
++	/* See if kgdb_eth wants this packet */
++	if (!kgdb_net_interrupt(skb)) {
++		/* No.. if we're 'trapped' then junk it */
++		if (kgdb_eth_is_trapped()) {
++			kfree_skb(skb);
++			return NET_RX_DROP;
++		}
++	} else {
++		/* kgdb_eth ate the packet... drop it silently */
++		kfree_skb(skb);
++		return NET_RX_DROP;
++	}
++#endif
++
+ 	if (!skb->stamp.tv_sec)
+ 		do_gettimeofday(&skb->stamp);
+ 
+@@ -1488,6 +1508,18 @@ static void net_tx_action(struct softirq
+ 	}
+ }
+ 
++static __inline__ int deliver_skb(struct sk_buff *skb,
++				  struct packet_type *pt_prev, int last)
++{
++	if (unlikely(!pt_prev->data))
++		return deliver_to_old_ones(pt_prev, skb, last);
++	else {
++		atomic_inc(&skb->users);
++		return pt_prev->func(skb, skb->dev, pt_prev);
++	}
++}
++
++
+ #if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
+ int (*br_handle_frame_hook)(struct sk_buff *skb);
+ 
+@@ -1495,15 +1527,8 @@ static __inline__ int handle_bridge(stru
+ 				     struct packet_type *pt_prev)
+ {
+ 	int ret = NET_RX_DROP;
+-
+-	if (pt_prev) {
+-		if (!pt_prev->data)
+-			ret = deliver_to_old_ones(pt_prev, skb, 0);
+-		else {
+-			atomic_inc(&skb->users);
+-			ret = pt_prev->func(skb, skb->dev, pt_prev);
+-		}
+-	}
++	if (pt_prev)
++		ret = deliver_skb(skb, pt_prev, 0);
+ 
+ 	return ret;
+ }
+@@ -1551,16 +1576,8 @@ int netif_receive_skb(struct sk_buff *sk
+ 	rcu_read_lock();
+ 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
+ 		if (!ptype->dev || ptype->dev == skb->dev) {
+-			if (pt_prev) {
+-				if (!pt_prev->data) {
+-					ret = deliver_to_old_ones(pt_prev,
+-								  skb, 0);
+-				} else {
+-					atomic_inc(&skb->users);
+-					ret = pt_prev->func(skb, skb->dev,
+-							    pt_prev);
+-				}
+-			}
++			if (pt_prev) 
++				ret = deliver_skb(skb, pt_prev, 0);
+ 			pt_prev = ptype;
+ 		}
+ 	}
+@@ -1573,16 +1590,8 @@ int netif_receive_skb(struct sk_buff *sk
+ 	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
+ 		if (ptype->type == type &&
+ 		    (!ptype->dev || ptype->dev == skb->dev)) {
+-			if (pt_prev) {
+-				if (!pt_prev->data) {
+-					ret = deliver_to_old_ones(pt_prev,
+-								  skb, 0);
+-				} else {
+-					atomic_inc(&skb->users);
+-					ret = pt_prev->func(skb, skb->dev,
+-							    pt_prev);
+-				}
+-			}
++			if (pt_prev) 
++				ret = deliver_skb(skb, pt_prev, 0);
+ 			pt_prev = ptype;
+ 		}
+ 	}
+@@ -1637,8 +1646,8 @@ static int process_backlog(struct net_de
+ #ifdef CONFIG_NET_HW_FLOWCONTROL
+ 		if (queue->throttle &&
+ 		    queue->input_pkt_queue.qlen < no_cong_thresh ) {
++			queue->throttle = 0;
+ 			if (atomic_dec_and_test(&netdev_dropping)) {
+-				queue->throttle = 0;
+ 				netdev_wakeup();
+ 				break;
+ 			}
+@@ -3036,3 +3045,63 @@ out:
+ }
+ 
+ subsys_initcall(net_dev_init);
++
++EXPORT_SYMBOL(__dev_get);
++EXPORT_SYMBOL(__dev_get_by_flags);
++EXPORT_SYMBOL(__dev_get_by_index);
++EXPORT_SYMBOL(__dev_get_by_name);
++EXPORT_SYMBOL(__dev_remove_pack);
++EXPORT_SYMBOL(__skb_linearize);
++EXPORT_SYMBOL(call_netdevice_notifiers);
++EXPORT_SYMBOL(dev_add_pack);
++EXPORT_SYMBOL(dev_alloc);
++EXPORT_SYMBOL(dev_alloc_name);
++EXPORT_SYMBOL(dev_close);
++EXPORT_SYMBOL(dev_get_by_flags);
++EXPORT_SYMBOL(dev_get_by_index);
++EXPORT_SYMBOL(dev_get_by_name);
++EXPORT_SYMBOL(dev_getbyhwaddr);
++EXPORT_SYMBOL(dev_ioctl);
++EXPORT_SYMBOL(dev_new_index);
++EXPORT_SYMBOL(dev_open);
++EXPORT_SYMBOL(dev_queue_xmit);
++EXPORT_SYMBOL(dev_queue_xmit_nit);
++EXPORT_SYMBOL(dev_remove_pack);
++EXPORT_SYMBOL(dev_set_allmulti);
++EXPORT_SYMBOL(dev_set_promiscuity);
++EXPORT_SYMBOL(free_netdev);
++EXPORT_SYMBOL(netdev_boot_setup_check);
++EXPORT_SYMBOL(netdev_set_master);
++EXPORT_SYMBOL(netdev_state_change);
++EXPORT_SYMBOL(netif_receive_skb);
++EXPORT_SYMBOL(netif_rx);
++EXPORT_SYMBOL(register_gifconf);
++EXPORT_SYMBOL(register_netdevice);
++EXPORT_SYMBOL(register_netdevice_notifier);
++EXPORT_SYMBOL(skb_checksum_help);
++EXPORT_SYMBOL(synchronize_net);
++EXPORT_SYMBOL(unregister_netdevice);
++EXPORT_SYMBOL(unregister_netdevice_notifier);
++
++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
++EXPORT_SYMBOL(br_handle_frame_hook);
++#endif
++/* for 801q VLAN support */
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++EXPORT_SYMBOL(dev_change_flags);
++#endif
++#ifdef CONFIG_KMOD
++EXPORT_SYMBOL(dev_load);
++#endif
++#ifdef CONFIG_NET_HW_FLOWCONTROL
++EXPORT_SYMBOL(netdev_dropping);
++EXPORT_SYMBOL(netdev_fc_xoff);
++EXPORT_SYMBOL(netdev_register_fc);
++EXPORT_SYMBOL(netdev_unregister_fc);
++#endif
++#ifdef CONFIG_NET_FASTROUTE
++EXPORT_SYMBOL(netdev_fastroute);
++EXPORT_SYMBOL(netdev_fastroute_obstacles);
++#endif
++
++EXPORT_PER_CPU_SYMBOL(softnet_data);
+--- linux-2.6.0-test6/net/core/dev_mcast.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/net/core/dev_mcast.c	2003-10-05 00:33:25.000000000 -0700
+@@ -22,6 +22,7 @@
+  */
+ 
+ #include <linux/config.h> 
++#include <linux/module.h> 
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+@@ -273,3 +274,6 @@ void __init dev_mcast_init(void)
+ #endif
+ }
+ 
++EXPORT_SYMBOL(dev_mc_add);
++EXPORT_SYMBOL(dev_mc_delete);
++EXPORT_SYMBOL(dev_mc_upload);
+--- linux-2.6.0-test6/net/core/dst.c	2003-06-14 12:18:23.000000000 -0700
++++ 25/net/core/dst.c	2003-10-05 00:33:25.000000000 -0700
+@@ -6,15 +6,16 @@
+  */
+ 
+ #include <linux/bitops.h>
+-#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/init.h>
+ #include <linux/kernel.h>
+-#include <linux/sched.h>
+ #include <linux/mm.h>
+-#include <linux/string.h>
+-#include <linux/errno.h>
++#include <linux/module.h>
+ #include <linux/netdevice.h>
++#include <linux/sched.h>
+ #include <linux/skbuff.h>
+-#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/types.h>
+ 
+ #include <net/dst.h>
+ 
+@@ -257,3 +258,7 @@ void __init dst_init(void)
+ {
+ 	register_netdevice_notifier(&dst_dev_notifier);
+ }
++
++EXPORT_SYMBOL(__dst_free);
++EXPORT_SYMBOL(dst_alloc);
++EXPORT_SYMBOL(dst_destroy);
+--- linux-2.6.0-test6/net/core/dv.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/dv.c	2003-10-05 00:33:25.000000000 -0700
+@@ -10,6 +10,7 @@
+  * 		Dave Miller:	improvement on the code (correctness, performance and source files)
+  *
+  */
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -237,7 +238,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 		default:
+ 			return -EINVAL;
+-		};
++		}
+ 
+ 		break;
+ 
+@@ -281,7 +282,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -301,7 +302,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -321,7 +322,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -337,7 +338,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -353,7 +354,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -373,7 +374,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -389,7 +390,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -405,7 +406,7 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+@@ -425,19 +426,19 @@ int divert_ioctl(unsigned int cmd, struc
+ 
+ 			default:
+ 				return -EINVAL;
+-			};
++			}
+ 
+ 			break;
+ 
+ 		default:
+ 			return -EINVAL;
+-		};
++		}
+ 
+ 		break;
+ 
+ 	default:
+ 		return -EINVAL;
+-	};
++	}
+ 
+ 	return 0;
+ }
+@@ -550,8 +551,8 @@ void divert_frame(struct sk_buff *skb)
+ 			}
+ 		}
+ 		break;
+-	};
+-
+-	return;
++	}
+ }
+ 
++EXPORT_SYMBOL(alloc_divert_blk);
++EXPORT_SYMBOL(free_divert_blk);
+--- linux-2.6.0-test6/net/core/ethtool.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/ethtool.c	2003-10-05 00:33:25.000000000 -0700
+@@ -9,6 +9,7 @@
+  * It's GPL, stupid.
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+ #include <linux/ethtool.h>
+@@ -727,3 +728,11 @@ int dev_ethtool(struct ifreq *ifr)
+ 		return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
+ 	return -EOPNOTSUPP;
+ }
++
++EXPORT_SYMBOL(ethtool_op_get_link);
++EXPORT_SYMBOL(ethtool_op_get_sg);
++EXPORT_SYMBOL(ethtool_op_get_tso);
++EXPORT_SYMBOL(ethtool_op_get_tx_csum);
++EXPORT_SYMBOL(ethtool_op_set_sg);
++EXPORT_SYMBOL(ethtool_op_set_tso);
++EXPORT_SYMBOL(ethtool_op_set_tx_csum);
+--- linux-2.6.0-test6/net/core/filter.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/net/core/filter.c	2003-10-05 00:33:25.000000000 -0700
+@@ -424,3 +424,6 @@ int sk_attach_filter(struct sock_fprog *
+ 		sk_filter_release(sk, fp);
+ 	return err;
+ }
++
++EXPORT_SYMBOL(sk_chk_filter);
++EXPORT_SYMBOL(sk_run_filter);
+--- linux-2.6.0-test6/net/core/flow.c	2003-06-22 12:04:45.000000000 -0700
++++ 25/net/core/flow.c	2003-10-05 00:33:25.000000000 -0700
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/list.h>
+ #include <linux/jhash.h>
+ #include <linux/interrupt.h>
+@@ -401,3 +402,6 @@ static int __init flow_cache_init(void)
+ }
+ 
+ module_init(flow_cache_init);
++
++EXPORT_SYMBOL(flow_cache_genid);
++EXPORT_SYMBOL(flow_cache_lookup);
+--- linux-2.6.0-test6/net/core/iovec.c	2003-06-14 12:18:52.000000000 -0700
++++ 25/net/core/iovec.c	2003-10-05 00:33:25.000000000 -0700
+@@ -16,8 +16,8 @@
+  *		Andi Kleen	:	Fix csum*fromiovecend for IPv6.
+  */
+ 
+-
+ #include <linux/errno.h>
++#include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+@@ -254,3 +254,9 @@ out_fault:
+ 	err = -EFAULT;
+ 	goto out;
+ }
++
++EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
++EXPORT_SYMBOL(memcpy_fromiovec);
++EXPORT_SYMBOL(memcpy_fromiovecend);
++EXPORT_SYMBOL(memcpy_toiovec);
++EXPORT_SYMBOL(memcpy_tokerneliovec);
+--- linux-2.6.0-test6/net/core/link_watch.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/link_watch.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Linux network device link state notifaction
++ * Linux network device link state notification
+  *
+  * Author:
+  *     Stefan Rompf <sux@loplof.de>
+@@ -12,6 +12,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/if.h>
+ #include <linux/rtnetlink.h>
+@@ -132,3 +133,4 @@ void linkwatch_fire_event(struct net_dev
+ 	}
+ }
+ 
++EXPORT_SYMBOL(linkwatch_fire_event);
+--- linux-2.6.0-test6/net/core/neighbour.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/core/neighbour.c	2003-10-05 00:33:25.000000000 -0700
+@@ -17,6 +17,7 @@
+ #include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/socket.h>
+ #include <linux/sched.h>
+ #include <linux/netdevice.h>
+@@ -1683,3 +1684,34 @@ void neigh_sysctl_unregister(struct neig
+ }
+ 
+ #endif	/* CONFIG_SYSCTL */
++
++EXPORT_SYMBOL(__neigh_event_send);
++EXPORT_SYMBOL(neigh_add);
++EXPORT_SYMBOL(neigh_changeaddr);
++EXPORT_SYMBOL(neigh_compat_output);
++EXPORT_SYMBOL(neigh_connected_output);
++EXPORT_SYMBOL(neigh_create);
++EXPORT_SYMBOL(neigh_delete);
++EXPORT_SYMBOL(neigh_destroy);
++EXPORT_SYMBOL(neigh_dump_info);
++EXPORT_SYMBOL(neigh_event_ns);
++EXPORT_SYMBOL(neigh_ifdown);
++EXPORT_SYMBOL(neigh_lookup);
++EXPORT_SYMBOL(neigh_parms_alloc);
++EXPORT_SYMBOL(neigh_parms_release);
++EXPORT_SYMBOL(neigh_rand_reach_time);
++EXPORT_SYMBOL(neigh_resolve_output);
++EXPORT_SYMBOL(neigh_table_clear);
++EXPORT_SYMBOL(neigh_table_init);
++EXPORT_SYMBOL(neigh_update);
++EXPORT_SYMBOL(neigh_update_hhs);
++EXPORT_SYMBOL(pneigh_enqueue);
++EXPORT_SYMBOL(pneigh_lookup);
++
++#ifdef CONFIG_ARPD
++EXPORT_SYMBOL(neigh_app_ns);
++#endif
++#ifdef CONFIG_SYSCTL
++EXPORT_SYMBOL(neigh_sysctl_register);
++EXPORT_SYMBOL(neigh_sysctl_unregister);
++#endif
+--- linux-2.6.0-test6/net/core/netfilter.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/netfilter.c	2003-10-05 00:33:25.000000000 -0700
+@@ -759,3 +759,17 @@ void __init netfilter_init(void)
+ 			INIT_LIST_HEAD(&nf_hooks[i][h]);
+ 	}
+ }
++
++EXPORT_SYMBOL(ip_ct_attach);
++EXPORT_SYMBOL(ip_route_me_harder);
++EXPORT_SYMBOL(nf_getsockopt);
++EXPORT_SYMBOL(nf_hook_slow);
++EXPORT_SYMBOL(nf_hooks);
++EXPORT_SYMBOL(nf_register_hook);
++EXPORT_SYMBOL(nf_register_queue_handler);
++EXPORT_SYMBOL(nf_register_sockopt);
++EXPORT_SYMBOL(nf_reinject);
++EXPORT_SYMBOL(nf_setsockopt);
++EXPORT_SYMBOL(nf_unregister_hook);
++EXPORT_SYMBOL(nf_unregister_queue_handler);
++EXPORT_SYMBOL(nf_unregister_sockopt);
+--- linux-2.6.0-test6/net/core/rtnetlink.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/rtnetlink.c	2003-10-05 00:33:25.000000000 -0700
+@@ -18,6 +18,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/errno.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/socket.h>
+ #include <linux/kernel.h>
+@@ -556,7 +557,6 @@ struct notifier_block rtnetlink_dev_noti
+ 	.notifier_call	= rtnetlink_event,
+ };
+ 
+-
+ void __init rtnetlink_init(void)
+ {
+ 	rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv);
+@@ -567,3 +567,13 @@ void __init rtnetlink_init(void)
+ 	rtnetlink_links[PF_UNSPEC] = link_rtnetlink_table;
+ 	rtnetlink_links[PF_PACKET] = link_rtnetlink_table;
+ }
++
++EXPORT_SYMBOL(__rta_fill);
++EXPORT_SYMBOL(rtattr_parse);
++EXPORT_SYMBOL(rtnetlink_dump_ifinfo);
++EXPORT_SYMBOL(rtnetlink_links);
++EXPORT_SYMBOL(rtnetlink_put_metrics);
++EXPORT_SYMBOL(rtnl);
++EXPORT_SYMBOL(rtnl_lock);
++EXPORT_SYMBOL(rtnl_sem);
++EXPORT_SYMBOL(rtnl_unlock);
+--- linux-2.6.0-test6/net/core/scm.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/scm.c	2003-10-05 00:33:25.000000000 -0700
+@@ -9,6 +9,7 @@
+  *		2 of the License, or (at your option) any later version.
+  */
+ 
++#include <linux/module.h>
+ #include <linux/signal.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+@@ -282,3 +283,9 @@ struct scm_fp_list *scm_fp_dup(struct sc
+ 	}
+ 	return new_fpl;
+ }
++
++EXPORT_SYMBOL(__scm_destroy);
++EXPORT_SYMBOL(__scm_send);
++EXPORT_SYMBOL(put_cmsg);
++EXPORT_SYMBOL(scm_detach_fds);
++EXPORT_SYMBOL(scm_fp_dup);
+--- linux-2.6.0-test6/net/core/skbuff.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/skbuff.c	2003-10-05 00:33:25.000000000 -0700
+@@ -39,6 +39,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -1103,3 +1104,22 @@ void __init skb_init(void)
+ 	if (!skbuff_head_cache)
+ 		panic("cannot create skbuff cache");
+ }
++
++EXPORT_SYMBOL(___pskb_trim);
++EXPORT_SYMBOL(__kfree_skb);
++EXPORT_SYMBOL(__pskb_pull_tail);
++EXPORT_SYMBOL(alloc_skb);
++EXPORT_SYMBOL(pskb_copy);
++EXPORT_SYMBOL(pskb_expand_head);
++EXPORT_SYMBOL(skb_checksum);
++EXPORT_SYMBOL(skb_clone);
++EXPORT_SYMBOL(skb_clone_fraglist);
++EXPORT_SYMBOL(skb_copy);
++EXPORT_SYMBOL(skb_copy_and_csum_bits);
++EXPORT_SYMBOL(skb_copy_and_csum_dev);
++EXPORT_SYMBOL(skb_copy_bits);
++EXPORT_SYMBOL(skb_copy_expand);
++EXPORT_SYMBOL(skb_over_panic);
++EXPORT_SYMBOL(skb_pad);
++EXPORT_SYMBOL(skb_realloc_headroom);
++EXPORT_SYMBOL(skb_under_panic);
+--- linux-2.6.0-test6/net/core/sock.c	2003-06-14 12:18:29.000000000 -0700
++++ 25/net/core/sock.c	2003-10-05 00:33:25.000000000 -0700
+@@ -98,6 +98,7 @@
+ #include <linux/in.h>
+ #include <linux/kernel.h>
+ #include <linux/major.h>
++#include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/timer.h>
+ #include <linux/string.h>
+@@ -1111,3 +1112,40 @@ void sock_init_data(struct socket *sock,
+ 
+ 	atomic_set(&sk->sk_refcnt, 1);
+ }
++
++EXPORT_SYMBOL(__lock_sock);
++EXPORT_SYMBOL(__release_sock);
++EXPORT_SYMBOL(sk_alloc);
++EXPORT_SYMBOL(sk_free);
++EXPORT_SYMBOL(sk_send_sigurg);
++EXPORT_SYMBOL(sock_alloc_send_pskb);
++EXPORT_SYMBOL(sock_alloc_send_skb);
++EXPORT_SYMBOL(sock_getsockopt);
++EXPORT_SYMBOL(sock_init_data);
++EXPORT_SYMBOL(sock_kfree_s);
++EXPORT_SYMBOL(sock_kmalloc);
++EXPORT_SYMBOL(sock_no_accept);
++EXPORT_SYMBOL(sock_no_bind);
++EXPORT_SYMBOL(sock_no_connect);
++EXPORT_SYMBOL(sock_no_getname);
++EXPORT_SYMBOL(sock_no_getsockopt);
++EXPORT_SYMBOL(sock_no_ioctl);
++EXPORT_SYMBOL(sock_no_listen);
++EXPORT_SYMBOL(sock_no_mmap);
++EXPORT_SYMBOL(sock_no_poll);
++EXPORT_SYMBOL(sock_no_recvmsg);
++EXPORT_SYMBOL(sock_no_release);
++EXPORT_SYMBOL(sock_no_sendmsg);
++EXPORT_SYMBOL(sock_no_sendpage);
++EXPORT_SYMBOL(sock_no_setsockopt);
++EXPORT_SYMBOL(sock_no_shutdown);
++EXPORT_SYMBOL(sock_no_socketpair);
++EXPORT_SYMBOL(sock_rfree);
++EXPORT_SYMBOL(sock_rmalloc);
++EXPORT_SYMBOL(sock_setsockopt);
++EXPORT_SYMBOL(sock_wfree);
++EXPORT_SYMBOL(sock_wmalloc);
++#ifdef CONFIG_SYSCTL
++EXPORT_SYMBOL(sysctl_rmem_max);
++EXPORT_SYMBOL(sysctl_wmem_max);
++#endif
+--- linux-2.6.0-test6/net/core/utils.c	2003-06-14 12:17:55.000000000 -0700
++++ 25/net/core/utils.c	2003-10-05 00:33:25.000000000 -0700
+@@ -13,13 +13,15 @@
+  *      2 of the License, or (at your option) any later version.
+  */
+ 
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/jiffies.h>
+-#include <linux/string.h>
++#include <linux/kernel.h>
+ #include <linux/mm.h>
++#include <linux/string.h>
++#include <linux/types.h>
++
++#include <asm/system.h>
++#include <asm/uaccess.h>
+ 
+ static unsigned long net_rand_seed = 152L;
+ 
+@@ -71,3 +73,7 @@ int net_ratelimit(void)
+ 	spin_unlock_irqrestore(&ratelimit_lock, flags);
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(net_random);
++EXPORT_SYMBOL(net_ratelimit);
++EXPORT_SYMBOL(net_srandom);
+--- linux-2.6.0-test6/net/core/wireless.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/core/wireless.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1365,3 +1365,10 @@ void wireless_spy_update(struct net_devi
+ #endif /* IW_WIRELESS_THRSPY */
+ #endif /* IW_WIRELESS_SPY */
+ }
++
++EXPORT_SYMBOL(iw_handler_get_spy);
++EXPORT_SYMBOL(iw_handler_get_thrspy);
++EXPORT_SYMBOL(iw_handler_set_spy);
++EXPORT_SYMBOL(iw_handler_set_thrspy);
++EXPORT_SYMBOL(wireless_send_event);
++EXPORT_SYMBOL(wireless_spy_update);
+--- linux-2.6.0-test6/net/ethernet/eth.c	2003-06-22 12:04:45.000000000 -0700
++++ 25/net/ethernet/eth.c	2003-10-05 00:33:25.000000000 -0700
+@@ -37,6 +37,7 @@
+  *		as published by the Free Software Foundation; either version
+  *		2 of the License, or (at your option) any later version.
+  */
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -241,3 +242,5 @@ void eth_header_cache_update(struct hh_c
+ 	memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
+ 	       haddr, dev->addr_len);
+ }
++
++EXPORT_SYMBOL(eth_type_trans);
+--- linux-2.6.0-test6/net/ethernet/pe2.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/net/ethernet/pe2.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,27 +1,28 @@
++#include <linux/in.h>
++#include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/skbuff.h>
++
+ #include <net/datalink.h>
+-#include <linux/mm.h>
+-#include <linux/in.h>
+ 
+-static int pEII_request(struct datalink_proto *dl, 
+-		struct sk_buff *skb, unsigned char *dest_node)
++static int pEII_request(struct datalink_proto *dl,
++			struct sk_buff *skb, unsigned char *dest_node)
+ {
+-	struct net_device	*dev = skb->dev;
++	struct net_device *dev = skb->dev;
+ 
+-	skb->protocol = htons (ETH_P_IPX);
+-	if(dev->hard_header)
+-		dev->hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len);
++	skb->protocol = htons(ETH_P_IPX);
++	if (dev->hard_header)
++		dev->hard_header(skb, dev, ETH_P_IPX,
++				 dest_node, NULL, skb->len);
+ 	return dev_queue_xmit(skb);
+ }
+ 
+-struct datalink_proto *
+-make_EII_client(void)
++struct datalink_proto *make_EII_client(void)
+ {
+-	struct datalink_proto	*proto;
++	struct datalink_proto *proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
+ 
+-	proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
+-	if (proto != NULL) {
++	if (proto) {
+ 		proto->header_length = 0;
+ 		proto->request = pEII_request;
+ 	}
+@@ -34,3 +35,6 @@ void destroy_EII_client(struct datalink_
+ 	if (dl)
+ 		kfree(dl);
+ }
++
++EXPORT_SYMBOL(destroy_EII_client);
++EXPORT_SYMBOL(make_EII_client);
+--- linux-2.6.0-test6/net/ipv4/af_inet.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/af_inet.c	2003-10-05 00:33:25.000000000 -0700
+@@ -74,6 +74,7 @@
+ #include <linux/in.h>
+ #include <linux/kernel.h>
+ #include <linux/major.h>
++#include <linux/module.h>
+ #include <linux/sched.h>
+ #include <linux/timer.h>
+ #include <linux/string.h>
+@@ -1246,4 +1247,33 @@ int __init ipv4_proc_init(void)
+ 	return 0;
+ }
+ #endif /* CONFIG_PROC_FS */
++
+ MODULE_ALIAS_NETPROTO(PF_INET);
++
++EXPORT_SYMBOL(inet_accept);
++EXPORT_SYMBOL(inet_bind);
++EXPORT_SYMBOL(inet_dgram_connect);
++EXPORT_SYMBOL(inet_dgram_ops);
++EXPORT_SYMBOL(inet_family_ops);
++EXPORT_SYMBOL(inet_getname);
++EXPORT_SYMBOL(inet_getsockopt);
++EXPORT_SYMBOL(inet_ioctl);
++EXPORT_SYMBOL(inet_listen);
++EXPORT_SYMBOL(inet_recvmsg);
++EXPORT_SYMBOL(inet_register_protosw);
++EXPORT_SYMBOL(inet_release);
++EXPORT_SYMBOL(inet_sendmsg);
++EXPORT_SYMBOL(inet_setsockopt);
++EXPORT_SYMBOL(inet_shutdown);
++EXPORT_SYMBOL(inet_sock_destruct);
++EXPORT_SYMBOL(inet_sock_release);
++EXPORT_SYMBOL(inet_stream_connect);
++EXPORT_SYMBOL(inet_stream_ops);
++EXPORT_SYMBOL(inet_unregister_protosw);
++EXPORT_SYMBOL(net_statistics);
++EXPORT_SYMBOL(tcp_protocol);
++EXPORT_SYMBOL(udp_protocol);
++
++#ifdef INET_REFCNT_DEBUG
++EXPORT_SYMBOL(inet_sock_nr);
++#endif
+--- linux-2.6.0-test6/net/ipv4/arp.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/arp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -69,6 +69,7 @@
+  *		Arnaldo C. Melo :	convert /proc/net/arp to seq_file
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+@@ -630,12 +631,6 @@ int arp_process(struct sk_buff *skb)
+ 	if (in_dev == NULL)
+ 		goto out;
+ 
+-	/* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
+-	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
+-				 (2 * dev->addr_len) +
+-				 (2 * sizeof(u32)))))
+-		goto out;
+-
+ 	arp = skb->nh.arph;
+ 
+ 	switch (dev_type) {
+@@ -835,8 +830,15 @@ out:
+ 
+ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+ {
+-	struct arphdr *arp = skb->nh.arph;
++	struct arphdr *arp;
++
++	/* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
++	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++				 (2 * dev->addr_len) +
++				 (2 * sizeof(u32)))))
++		goto freeskb;
+ 
++	arp = skb->nh.arph;
+ 	if (arp->ar_hln != dev->addr_len ||
+ 	    dev->flags & IFF_NOARP ||
+ 	    skb->pkt_type == PACKET_OTHERHOST ||
+@@ -1429,3 +1431,13 @@ static int __init arp_proc_init(void)
+ }
+ 
+ #endif /* CONFIG_PROC_FS */
++
++EXPORT_SYMBOL(arp_broken_ops);
++EXPORT_SYMBOL(arp_find);
++EXPORT_SYMBOL(arp_rcv);
++EXPORT_SYMBOL(arp_send);
++EXPORT_SYMBOL(arp_tbl);
++
++#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
++EXPORT_SYMBOL(clip_tbl_hook);
++#endif
+--- linux-2.6.0-test6/net/ipv4/devinet.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/ipv4/devinet.c	2003-10-05 00:33:25.000000000 -0700
+@@ -32,6 +32,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -1354,3 +1355,11 @@ void __init devinet_init(void)
+ 	devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
+ #endif
+ }
++
++EXPORT_SYMBOL(devinet_ioctl);
++EXPORT_SYMBOL(in_dev_finish_destroy);
++EXPORT_SYMBOL(inet_select_addr);
++EXPORT_SYMBOL(inetdev_by_index);
++EXPORT_SYMBOL(inetdev_lock);
++EXPORT_SYMBOL(register_inetaddr_notifier);
++EXPORT_SYMBOL(unregister_inetaddr_notifier);
+--- linux-2.6.0-test6/net/ipv4/fib_frontend.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/net/ipv4/fib_frontend.c	2003-10-05 00:33:25.000000000 -0700
+@@ -16,6 +16,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+@@ -605,3 +606,6 @@ void __init ip_fib_init(void)
+ 	register_inetaddr_notifier(&fib_inetaddr_notifier);
+ }
+ 
++EXPORT_SYMBOL(inet_addr_type);
++EXPORT_SYMBOL(ip_dev_find);
++EXPORT_SYMBOL(ip_rt_ioctl);
+--- linux-2.6.0-test6/net/ipv4/icmp.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/icmp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -65,6 +65,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/jiffies.h>
+ #include <linux/kernel.h>
+@@ -1126,3 +1127,8 @@ void __init icmp_init(struct net_proto_f
+ 		per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk);
+ 	}
+ }
++
++EXPORT_SYMBOL(icmp_err_convert);
++EXPORT_SYMBOL(icmp_send);
++EXPORT_SYMBOL(icmp_statistics);
++EXPORT_SYMBOL(xrlim_allow);
+--- linux-2.6.0-test6/net/ipv4/igmp.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/igmp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -72,8 +72,8 @@
+  *					Vinay Kulkarni
+  */
+ 
+-
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <linux/types.h>
+@@ -2438,3 +2438,6 @@ int __init igmp_mc_proc_init(void)
+ }
+ #endif
+ 
++EXPORT_SYMBOL(ip_mc_dec_group);
++EXPORT_SYMBOL(ip_mc_inc_group);
++EXPORT_SYMBOL(ip_mc_join_group);
+--- linux-2.6.0-test6/net/ipv4/inetpeer.c	2003-06-14 12:18:33.000000000 -0700
++++ 25/net/ipv4/inetpeer.c	2003-10-05 00:33:25.000000000 -0700
+@@ -8,6 +8,7 @@
+  *  Authors:	Andrey V. Savochkin <saw@msu.ru>
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+@@ -452,3 +453,5 @@ static void peer_check_expire(unsigned l
+ 			peer_total / inet_peer_threshold * HZ;
+ 	add_timer(&peer_periodic_timer);
+ }
++
++EXPORT_SYMBOL(inet_peer_idlock);
+--- linux-2.6.0-test6/net/ipv4/ip_fragment.c	2003-06-14 12:18:05.000000000 -0700
++++ 25/net/ipv4/ip_fragment.c	2003-10-05 00:33:25.000000000 -0700
+@@ -23,6 +23,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/jiffies.h>
+@@ -675,3 +676,5 @@ void ipfrag_init(void)
+ 	ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;
+ 	add_timer(&ipfrag_secret_timer);
+ }
++
++EXPORT_SYMBOL(ip_defrag);
+--- linux-2.6.0-test6/net/ipv4/ip_input.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ip_input.c	2003-10-05 00:33:25.000000000 -0700
+@@ -116,6 +116,7 @@
+  */
+ 
+ #include <asm/system.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+@@ -432,3 +433,5 @@ out:
+         return NET_RX_DROP;
+ }
+ 
++EXPORT_SYMBOL(ip_rcv);
++EXPORT_SYMBOL(ip_statistics);
+--- linux-2.6.0-test6/net/ipv4/ipip.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/ipv4/ipip.c	2003-10-05 00:33:25.000000000 -0700
+@@ -483,6 +483,11 @@ static int ipip_rcv(struct sk_buff *skb)
+ 
+ 	read_lock(&ipip_lock);
+ 	if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
++		if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
++			kfree_skb(skb);
++			return 0;
++		}
++
+ 		tunnel->stat.rx_packets++;
+ 		tunnel->stat.rx_bytes += skb->len;
+ 		skb->dev = tunnel->dev;
+--- linux-2.6.0-test6/net/ipv4/ip_options.c	2003-06-14 12:18:28.000000000 -0700
++++ 25/net/ipv4/ip_options.c	2003-10-05 00:33:25.000000000 -0700
+@@ -11,6 +11,7 @@
+  *		
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <asm/uaccess.h>
+ #include <linux/skbuff.h>
+@@ -617,3 +618,6 @@ int ip_options_rcv_srr(struct sk_buff *s
+ 	}
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(ip_options_compile);
++EXPORT_SYMBOL(ip_options_undo);
+--- linux-2.6.0-test6/net/ipv4/ip_output.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ip_output.c	2003-10-05 00:33:25.000000000 -0700
+@@ -46,6 +46,7 @@
+ 
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -1317,3 +1318,13 @@ void __init ip_init(void)
+ 	igmp_mc_proc_init();
+ #endif
+ }
++
++EXPORT_SYMBOL(ip_finish_output);
++EXPORT_SYMBOL(ip_fragment);
++EXPORT_SYMBOL(ip_generic_getfrag);
++EXPORT_SYMBOL(ip_queue_xmit);
++EXPORT_SYMBOL(ip_send_check);
++
++#ifdef CONFIG_SYSCTL
++EXPORT_SYMBOL(sysctl_ip_default_ttl);
++#endif
+--- linux-2.6.0-test6/net/ipv4/ip_sockglue.c	2003-06-14 12:18:06.000000000 -0700
++++ 25/net/ipv4/ip_sockglue.c	2003-10-05 00:33:25.000000000 -0700
+@@ -18,6 +18,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/sched.h>
+@@ -1055,3 +1056,10 @@ int ip_getsockopt(struct sock *sk, int l
+ 	}
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(ip_cmsg_recv);
++
++#ifdef CONFIG_IP_SCTP_MODULE
++EXPORT_SYMBOL(ip_getsockopt);
++EXPORT_SYMBOL(ip_setsockopt);
++#endif
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_lblc.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_lblc.c	2003-10-05 00:33:25.000000000 -0700
+@@ -458,10 +458,11 @@ __ip_vs_wlc_schedule(struct ip_vs_servic
+ 	 * The server with weight=0 is quiesced and will not receive any
+ 	 * new connection.
+ 	 */
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (least->flags & IP_VS_DEST_F_OVERLOAD)
++	list_for_each_entry(dest, &svc->destinations, n_list) {
++		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+-		if (atomic_read(&least->weight) > 0) {
++		if (atomic_read(&dest->weight) > 0) {
++			least = dest;
+ 			loh = atomic_read(&least->activeconns) * 50
+ 				+ atomic_read(&least->inactconns);
+ 			goto nextstage;
+@@ -473,7 +474,7 @@ __ip_vs_wlc_schedule(struct ip_vs_servic
+ 	 *    Find the destination with the least load.
+ 	 */
+   nextstage:
+-	list_for_each_entry(dest, &svc->destinations, n_list) {
++	list_for_each_entry_continue(dest, &svc->destinations, n_list) {
+ 		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+ 
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_lblcr.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_lblcr.c	2003-10-05 00:33:25.000000000 -0700
+@@ -711,11 +711,12 @@ __ip_vs_wlc_schedule(struct ip_vs_servic
+ 	 * The server with weight=0 is quiesced and will not receive any
+ 	 * new connection.
+ 	 */
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (least->flags & IP_VS_DEST_F_OVERLOAD)
++	list_for_each_entry(dest, &svc->destinations, n_list) {
++		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+ 
+-		if (atomic_read(&least->weight) > 0) {
++		if (atomic_read(&dest->weight) > 0) {
++			least = dest;
+ 			loh = atomic_read(&least->activeconns) * 50
+ 				+ atomic_read(&least->inactconns);
+ 			goto nextstage;
+@@ -727,7 +728,7 @@ __ip_vs_wlc_schedule(struct ip_vs_servic
+ 	 *    Find the destination with the least load.
+ 	 */
+   nextstage:
+-	list_for_each_entry(dest, &svc->destinations, n_list) {
++	list_for_each_entry_continue(dest, &svc->destinations, n_list) {
+ 		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+ 
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_lc.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_lc.c	2003-10-05 00:33:25.000000000 -0700
+@@ -65,8 +65,8 @@ ip_vs_lc_dest_overhead(struct ip_vs_dest
+ static struct ip_vs_dest *
+ ip_vs_lc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-	struct ip_vs_dest *dest, *least;
+-	unsigned int loh, doh;
++	struct ip_vs_dest *dest, *least = NULL;
++	unsigned int loh = 0, doh;
+ 
+ 	IP_VS_DBG(6, "ip_vs_lc_schedule(): Scheduling...\n");
+ 
+@@ -79,31 +79,18 @@ ip_vs_lc_schedule(struct ip_vs_service *
+ 	 * served, but no new connection is assigned to the server.
+ 	 */
+ 
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (least->flags & IP_VS_DEST_F_OVERLOAD)
+-			continue;
+-		if (atomic_read(&least->weight) > 0) {
+-			loh = ip_vs_lc_dest_overhead(least);
+-			goto nextstage;
+-		}
+-	}
+-	return NULL;
+-
+-	/*
+-	 *    Find the destination with the least load.
+-	 */
+-  nextstage:
+ 	list_for_each_entry(dest, &svc->destinations, n_list) {
+ 		if ((dest->flags & IP_VS_DEST_F_OVERLOAD) ||
+ 		    atomic_read(&dest->weight) == 0)
+ 			continue;
+ 		doh = ip_vs_lc_dest_overhead(dest);
+-		if (doh < loh) {
++		if (!least || doh < loh) {
+ 			least = dest;
+ 			loh = doh;
+ 		}
+ 	}
+ 
++	if (least)
+ 	IP_VS_DBG(6, "LC: server %u.%u.%u.%u:%u activeconns %d inactconns %d\n",
+ 		  NIPQUAD(least->addr), ntohs(least->port),
+ 		  atomic_read(&least->activeconns),
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_nq.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_nq.c	2003-10-05 00:33:25.000000000 -0700
+@@ -81,8 +81,8 @@ ip_vs_nq_dest_overhead(struct ip_vs_dest
+ static struct ip_vs_dest *
+ ip_vs_nq_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+ {
+-	struct ip_vs_dest *dest, *least;
+-	unsigned int loh, doh;
++	struct ip_vs_dest *dest, *least = NULL;
++	unsigned int loh = 0, doh;
+ 
+ 	IP_VS_DBG(6, "ip_vs_nq_schedule(): Scheduling...\n");
+ 
+@@ -99,27 +99,10 @@ ip_vs_nq_schedule(struct ip_vs_service *
+ 	 * new connections.
+ 	 */
+ 
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+-		    atomic_read(&least->weight) > 0) {
+-			loh = ip_vs_nq_dest_overhead(least);
+-
+-			/* return the server directly if it is idle */
+-			if (atomic_read(&least->activeconns) == 0)
+-				goto out;
+-
+-			goto nextstage;
+-		}
+-	}
+-	return NULL;
+-
+-	/*
+-	 *    Find the destination with the least load.
+-	 */
+-  nextstage:
+ 	list_for_each_entry(dest, &svc->destinations, n_list) {
+ 
+-		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
++		if (dest->flags & IP_VS_DEST_F_OVERLOAD ||
++		    !atomic_read(&dest->weight))
+ 			continue;
+ 
+ 		doh = ip_vs_nq_dest_overhead(dest);
+@@ -127,16 +110,21 @@ ip_vs_nq_schedule(struct ip_vs_service *
+ 		/* return the server directly if it is idle */
+ 		if (atomic_read(&dest->activeconns) == 0) {
+ 			least = dest;
++			loh = doh;
+ 			goto out;
+ 		}
+ 
+-		if (loh * atomic_read(&dest->weight) >
+-		    doh * atomic_read(&least->weight)) {
++		if (!least ||
++		    (loh * atomic_read(&dest->weight) >
++		     doh * atomic_read(&least->weight))) {
+ 			least = dest;
+ 			loh = doh;
+ 		}
+ 	}
+ 
++	if (!least)
++		return NULL;
++
+   out:
+ 	IP_VS_DBG(6, "NQ: server %u.%u.%u.%u:%u "
+ 		  "activeconns %d refcnt %d weight %d overhead %d\n",
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_sed.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_sed.c	2003-10-05 00:33:25.000000000 -0700
+@@ -103,9 +103,10 @@ ip_vs_sed_schedule(struct ip_vs_service 
+ 	 * new connections.
+ 	 */
+ 
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+-		    atomic_read(&least->weight) > 0) {
++	list_for_each_entry(dest, &svc->destinations, n_list) {
++		if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
++		    atomic_read(&dest->weight) > 0) {
++			least = dest;
+ 			loh = ip_vs_sed_dest_overhead(least);
+ 			goto nextstage;
+ 		}
+@@ -116,7 +117,7 @@ ip_vs_sed_schedule(struct ip_vs_service 
+ 	 *    Find the destination with the least load.
+ 	 */
+   nextstage:
+-	list_for_each_entry(dest, &svc->destinations, n_list) {
++	list_for_each_entry_continue(dest, &svc->destinations, n_list) {
+ 		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+ 		doh = ip_vs_sed_dest_overhead(dest);
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_wlc.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_wlc.c	2003-10-05 00:33:25.000000000 -0700
+@@ -91,9 +91,10 @@ ip_vs_wlc_schedule(struct ip_vs_service 
+ 	 * new connections.
+ 	 */
+ 
+-	list_for_each_entry(least, &svc->destinations, n_list) {
+-		if (!(least->flags & IP_VS_DEST_F_OVERLOAD) &&
+-		    atomic_read(&least->weight) > 0) {
++	list_for_each_entry(dest, &svc->destinations, n_list) {
++		if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
++		    atomic_read(&dest->weight) > 0) {
++			least = dest;
+ 			loh = ip_vs_wlc_dest_overhead(least);
+ 			goto nextstage;
+ 		}
+@@ -104,7 +105,7 @@ ip_vs_wlc_schedule(struct ip_vs_service 
+ 	 *    Find the destination with the least load.
+ 	 */
+   nextstage:
+-	list_for_each_entry(dest, &svc->destinations, n_list) {
++	list_for_each_entry_continue(dest, &svc->destinations, n_list) {
+ 		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+ 			continue;
+ 		doh = ip_vs_wlc_dest_overhead(dest);
+--- linux-2.6.0-test6/net/ipv4/ipvs/ip_vs_wrr.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/ipvs/ip_vs_wrr.c	2003-10-05 00:33:25.000000000 -0700
+@@ -58,26 +58,18 @@ static int ip_vs_wrr_gcd_weight(struct i
+ {
+ 	struct ip_vs_dest *dest;
+ 	int weight;
+-	int g = 1;
++	int g = 0;
+ 
+ 	list_for_each_entry(dest, &svc->destinations, n_list) {
+ 		weight = atomic_read(&dest->weight);
+ 		if (weight > 0) {
+-			g = weight;
+-			goto search_gcd;
++			if (g > 0)
++				g = gcd(weight, g);
++			else
++				g = weight;
+ 		}
+ 	}
+-
+-	return g;
+-
+- search_gcd:
+-	list_for_each_entry(dest, &svc->destinations, n_list) {
+-		weight = atomic_read(&dest->weight);
+-		if (weight > 0)
+-			g = gcd(weight, g);
+-	}
+-
+-	return g;
++	return g ? g : 1;
+ }
+ 
+ 
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_core.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_core.c	2003-10-05 00:33:25.000000000 -0700
+@@ -59,7 +59,7 @@ LIST_HEAD(ip_conntrack_expect_list);
+ LIST_HEAD(protocol_list);
+ static LIST_HEAD(helpers);
+ unsigned int ip_conntrack_htable_size = 0;
+-static int ip_conntrack_max;
++int ip_conntrack_max;
+ static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
+ struct list_head *ip_conntrack_hash;
+ static kmem_cache_t *ip_conntrack_cachep;
+@@ -301,7 +301,7 @@ clean_from_lists(struct ip_conntrack *ct
+ static void
+ destroy_conntrack(struct nf_conntrack *nfct)
+ {
+-	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
++	struct ip_conntrack *ct = (struct ip_conntrack *)nfct, *master = NULL;
+ 	struct ip_conntrack_protocol *proto;
+ 
+ 	DEBUGP("destroy_conntrack(%p)\n", ct);
+@@ -328,12 +328,15 @@ destroy_conntrack(struct nf_conntrack *n
+ 			/* can't call __unexpect_related here,
+ 			 * since it would screw up expect_list */
+ 			list_del(&ct->master->expected_list);
+-			ip_conntrack_put(ct->master->expectant);
++			master = ct->master->expectant;
+ 		}
+ 		kfree(ct->master);
+ 	}
+ 	WRITE_UNLOCK(&ip_conntrack_lock);
+ 
++	if (master)
++		ip_conntrack_put(master);
++
+ 	DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
+ 	kmem_cache_free(ip_conntrack_cachep, ct);
+ 	atomic_dec(&ip_conntrack_count);
+@@ -1276,11 +1279,14 @@ getorigdst(struct sock *sk, int optval, 
+ {
+ 	struct inet_opt *inet = inet_sk(sk);
+ 	struct ip_conntrack_tuple_hash *h;
+-	struct ip_conntrack_tuple tuple = { { inet->rcv_saddr,
+-						{ .tcp = { inet->sport } } },
+-					    { inet->daddr,
+-						{ .tcp = { inet->dport } },
+-					      IPPROTO_TCP } };
++	struct ip_conntrack_tuple tuple;
++	
++	IP_CT_TUPLE_U_BLANK(&tuple);
++	tuple.src.ip = inet->rcv_saddr;
++	tuple.src.u.tcp.port = inet->sport;
++	tuple.dst.ip = inet->daddr;
++	tuple.dst.u.tcp.port = inet->dport;
++	tuple.dst.protonum = IPPROTO_TCP;
+ 
+ 	/* We only do TCP at the moment: is there a better way? */
+ 	if (strcmp(sk->sk_prot->name, "TCP")) {
+@@ -1325,45 +1331,6 @@ static struct nf_sockopt_ops so_getorigd
+ 	.get		= &getorigdst,
+ };
+ 
+-#define NET_IP_CONNTRACK_MAX 2089
+-#define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max"
+-
+-#ifdef CONFIG_SYSCTL
+-static struct ctl_table_header *ip_conntrack_sysctl_header;
+-
+-static ctl_table ip_conntrack_table[] = {
+-	{
+-		.ctl_name	= NET_IP_CONNTRACK_MAX,
+-		.procname	= NET_IP_CONNTRACK_MAX_NAME,
+-		.data		= &ip_conntrack_max,
+-		.maxlen		= sizeof(ip_conntrack_max),
+-		.mode		= 0644,
+-		.proc_handler	= proc_dointvec
+-	},
+- 	{ .ctl_name = 0 }
+-};
+-
+-static ctl_table ip_conntrack_dir_table[] = {
+-	{
+-		.ctl_name	= NET_IPV4,
+-		.procname	= "ipv4",
+-		.mode		= 0555,
+-		.child		= ip_conntrack_table
+-	},
+-	{ .ctl_name = 0 }
+-};
+-
+-static ctl_table ip_conntrack_root_table[] = {
+-	{
+-		.ctl_name	= CTL_NET,
+-		.procname	= "net",
+-		.mode		= 0555,
+-		.child		= ip_conntrack_dir_table
+-	},
+-	{ .ctl_name = 0 }
+-};
+-#endif /*CONFIG_SYSCTL*/
+-
+ static int kill_all(const struct ip_conntrack *i, void *data)
+ {
+ 	return 1;
+@@ -1373,9 +1340,6 @@ static int kill_all(const struct ip_conn
+    supposed to kill the mall. */
+ void ip_conntrack_cleanup(void)
+ {
+-#ifdef CONFIG_SYSCTL
+-	unregister_sysctl_table(ip_conntrack_sysctl_header);
+-#endif
+ 	ip_ct_attach = NULL;
+ 	/* This makes sure all current packets have passed through
+            netfilter framework.  Roll on, two-stage module
+@@ -1453,25 +1417,10 @@ int __init ip_conntrack_init(void)
+ 	for (i = 0; i < ip_conntrack_htable_size; i++)
+ 		INIT_LIST_HEAD(&ip_conntrack_hash[i]);
+ 
+-/* This is fucking braindead.  There is NO WAY of doing this without
+-   the CONFIG_SYSCTL unless you don't want to detect errors.
+-   Grrr... --RR */
+-#ifdef CONFIG_SYSCTL
+-	ip_conntrack_sysctl_header
+-		= register_sysctl_table(ip_conntrack_root_table, 0);
+-	if (ip_conntrack_sysctl_header == NULL) {
+-		goto err_free_ct_cachep;
+-	}
+-#endif /*CONFIG_SYSCTL*/
+-
+ 	/* For use by ipt_REJECT */
+ 	ip_ct_attach = ip_conntrack_attach;
+ 	return ret;
+ 
+-#ifdef CONFIG_SYSCTL
+-err_free_ct_cachep:
+-	kmem_cache_destroy(ip_conntrack_cachep);
+-#endif /*CONFIG_SYSCTL*/
+ err_free_hash:
+ 	vfree(ip_conntrack_hash);
+ err_unreg_sockopt:
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_irc.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_irc.c	2003-10-05 00:33:25.000000000 -0700
+@@ -177,7 +177,10 @@ static int help(struct sk_buff *skb,
+ 			DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
+ 				HIPQUAD(dcc_ip), dcc_port);
+ 
+-			if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)) {
++			/* dcc_ip can be the internal OR external (NAT'ed) IP
++			 * Tiago Sousa <mirage@kaotik.org> */
++			if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)
++			    && ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != htonl(dcc_ip)) {
+ 				if (net_ratelimit())
+ 					printk(KERN_WARNING
+ 						"Forged DCC command from "
+@@ -201,7 +204,7 @@ static int help(struct sk_buff *skb,
+ 
+ 			exp->tuple = ((struct ip_conntrack_tuple)
+ 				{ { 0, { 0 } },
+-				  { htonl(dcc_ip), { .tcp = { htons(dcc_port) } },
++				  { ct->tuplehash[dir].tuple.src.ip, { .tcp = { htons(dcc_port) } },
+ 				    IPPROTO_TCP }});
+ 			exp->mask = ((struct ip_conntrack_tuple)
+ 				{ { 0, { 0 } },
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-06-14 12:18:07.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-10-05 00:33:25.000000000 -0700
+@@ -4,7 +4,7 @@
+ #include <linux/netfilter.h>
+ #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+ 
+-#define GENERIC_TIMEOUT (600*HZ)
++unsigned long ip_ct_generic_timeout = 600*HZ;
+ 
+ static int generic_pkt_to_tuple(const struct sk_buff *skb,
+ 				unsigned int dataoff,
+@@ -44,7 +44,7 @@ static int packet(struct ip_conntrack *c
+ 		  const struct sk_buff *skb,
+ 		  enum ip_conntrack_info conntrackinfo)
+ {
+-	ip_ct_refresh(conntrack, GENERIC_TIMEOUT);
++	ip_ct_refresh(conntrack, ip_ct_generic_timeout);
+ 	return NF_ACCEPT;
+ }
+ 
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-06-14 12:17:56.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -6,7 +6,7 @@
+ #include <linux/icmp.h>
+ #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+ 
+-#define ICMP_TIMEOUT (30*HZ)
++unsigned long ip_ct_icmp_timeout = 30*HZ;
+ 
+ #if 0
+ #define DEBUGP printk
+@@ -86,7 +86,7 @@ static int icmp_packet(struct ip_conntra
+ 			ct->timeout.function((unsigned long)ct);
+ 	} else {
+ 		atomic_inc(&ct->proto.icmp.count);
+-		ip_ct_refresh(ct, ICMP_TIMEOUT);
++		ip_ct_refresh(ct, ip_ct_icmp_timeout);
+ 	}
+ 
+ 	return NF_ACCEPT;
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -49,20 +49,28 @@ static const char *tcp_conntrack_names[]
+ #define HOURS * 60 MINS
+ #define DAYS * 24 HOURS
+ 
+-
+-static unsigned long tcp_timeouts[]
+-= { 30 MINS, 	/*	TCP_CONNTRACK_NONE,	*/
+-    5 DAYS,	/*	TCP_CONNTRACK_ESTABLISHED,	*/
+-    2 MINS,	/*	TCP_CONNTRACK_SYN_SENT,	*/
+-    60 SECS,	/*	TCP_CONNTRACK_SYN_RECV,	*/
+-    2 MINS,	/*	TCP_CONNTRACK_FIN_WAIT,	*/
+-    2 MINS,	/*	TCP_CONNTRACK_TIME_WAIT,	*/
+-    10 SECS,	/*	TCP_CONNTRACK_CLOSE,	*/
+-    60 SECS,	/*	TCP_CONNTRACK_CLOSE_WAIT,	*/
+-    30 SECS,	/*	TCP_CONNTRACK_LAST_ACK,	*/
+-    2 MINS,	/*	TCP_CONNTRACK_LISTEN,	*/
+-};
+-
++unsigned long ip_ct_tcp_timeout_syn_sent =      2 MINS;
++unsigned long ip_ct_tcp_timeout_syn_recv =     60 SECS;
++unsigned long ip_ct_tcp_timeout_established =   5 DAYS;
++unsigned long ip_ct_tcp_timeout_fin_wait =      2 MINS;
++unsigned long ip_ct_tcp_timeout_close_wait =    3 DAYS;
++unsigned long ip_ct_tcp_timeout_last_ack =     30 SECS;
++unsigned long ip_ct_tcp_timeout_time_wait =     2 MINS;
++unsigned long ip_ct_tcp_timeout_close =        10 SECS;
++
++static unsigned long * tcp_timeouts[]
++= { 0,                                 /*      TCP_CONNTRACK_NONE */
++    &ip_ct_tcp_timeout_established,    /*      TCP_CONNTRACK_ESTABLISHED,      */
++    &ip_ct_tcp_timeout_syn_sent,       /*      TCP_CONNTRACK_SYN_SENT, */
++    &ip_ct_tcp_timeout_syn_recv,       /*      TCP_CONNTRACK_SYN_RECV, */
++    &ip_ct_tcp_timeout_fin_wait,       /*      TCP_CONNTRACK_FIN_WAIT, */
++    &ip_ct_tcp_timeout_time_wait,      /*      TCP_CONNTRACK_TIME_WAIT,        */
++    &ip_ct_tcp_timeout_close,          /*      TCP_CONNTRACK_CLOSE,    */
++    &ip_ct_tcp_timeout_close_wait,     /*      TCP_CONNTRACK_CLOSE_WAIT,       */
++    &ip_ct_tcp_timeout_last_ack,       /*      TCP_CONNTRACK_LAST_ACK, */
++    0,                                 /*      TCP_CONNTRACK_LISTEN */
++ };
++ 
+ #define sNO TCP_CONNTRACK_NONE
+ #define sES TCP_CONNTRACK_ESTABLISHED
+ #define sSS TCP_CONNTRACK_SYN_SENT
+@@ -204,7 +212,7 @@ static int tcp_packet(struct ip_conntrac
+ 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 
+ 		WRITE_UNLOCK(&tcp_lock);
+-		ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]);
++		ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
+ 	}
+ 
+ 	return NF_ACCEPT;
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-06-14 12:17:55.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -6,8 +6,8 @@
+ #include <linux/udp.h>
+ #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
+ 
+-#define UDP_TIMEOUT (30*HZ)
+-#define UDP_STREAM_TIMEOUT (180*HZ)
++unsigned long ip_ct_udp_timeout = 30*HZ;
++unsigned long ip_ct_udp_timeout_stream = 180*HZ;
+ 
+ static int udp_pkt_to_tuple(const struct sk_buff *skb,
+ 			     unsigned int dataoff,
+@@ -57,11 +57,11 @@ static int udp_packet(struct ip_conntrac
+ 	/* If we've seen traffic both ways, this is some kind of UDP
+ 	   stream.  Extend timeout. */
+ 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+-		ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
++		ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
+ 		/* Also, more likely to be important, and not a probe */
+ 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 	} else
+-		ip_ct_refresh(conntrack, UDP_TIMEOUT);
++		ip_ct_refresh(conntrack, ip_ct_udp_timeout);
+ 
+ 	return NF_ACCEPT;
+ }
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_conntrack_standalone.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_conntrack_standalone.c	2003-10-05 00:33:25.000000000 -0700
+@@ -7,6 +7,7 @@
+ /* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
+    Public Licence. */
+ 
++#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/ip.h>
+ #include <linux/netfilter.h>
+@@ -14,6 +15,9 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/proc_fs.h>
++#ifdef CONFIG_SYSCTL
++#include <linux/sysctl.h>
++#endif
+ #include <net/checksum.h>
+ 
+ #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
+@@ -256,6 +260,98 @@ static struct nf_hook_ops ip_conntrack_l
+ 	.priority	= NF_IP_PRI_LAST-1,
+ };
+ 
++/* Sysctl support */
++
++#ifdef CONFIG_SYSCTL
++
++/* From ip_conntrack_core.c */
++extern int ip_conntrack_max;
++
++/* From ip_conntrack_proto_tcp.c */
++extern unsigned long ip_ct_tcp_timeout_syn_sent;
++extern unsigned long ip_ct_tcp_timeout_syn_recv;
++extern unsigned long ip_ct_tcp_timeout_established;
++extern unsigned long ip_ct_tcp_timeout_fin_wait;
++extern unsigned long ip_ct_tcp_timeout_close_wait;
++extern unsigned long ip_ct_tcp_timeout_last_ack;
++extern unsigned long ip_ct_tcp_timeout_time_wait;
++extern unsigned long ip_ct_tcp_timeout_close;
++
++/* From ip_conntrack_proto_udp.c */
++extern unsigned long ip_ct_udp_timeout;
++extern unsigned long ip_ct_udp_timeout_stream;
++
++/* From ip_conntrack_proto_icmp.c */
++extern unsigned long ip_ct_icmp_timeout;
++
++/* From ip_conntrack_proto_icmp.c */
++extern unsigned long ip_ct_generic_timeout;
++
++static struct ctl_table_header *ip_ct_sysctl_header;
++
++static ctl_table ip_ct_sysctl_table[] = {
++	{NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max",
++	 &ip_conntrack_max, sizeof(int), 0644, NULL,
++	 &proc_dointvec},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent",
++	 &ip_ct_tcp_timeout_syn_sent, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "ip_conntrack_tcp_timeout_syn_recv",
++	 &ip_ct_tcp_timeout_syn_recv, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "ip_conntrack_tcp_timeout_established",
++	 &ip_ct_tcp_timeout_established, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "ip_conntrack_tcp_timeout_fin_wait",
++	 &ip_ct_tcp_timeout_fin_wait, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "ip_conntrack_tcp_timeout_close_wait",
++	 &ip_ct_tcp_timeout_close_wait, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "ip_conntrack_tcp_timeout_last_ack",
++	 &ip_ct_tcp_timeout_last_ack, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "ip_conntrack_tcp_timeout_time_wait",
++	 &ip_ct_tcp_timeout_time_wait, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "ip_conntrack_tcp_timeout_close",
++	 &ip_ct_tcp_timeout_close, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, "ip_conntrack_udp_timeout",
++	 &ip_ct_udp_timeout, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "ip_conntrack_udp_timeout_stream",
++	 &ip_ct_udp_timeout_stream, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, "ip_conntrack_icmp_timeout",
++	 &ip_ct_icmp_timeout, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout",
++	 &ip_ct_generic_timeout, sizeof(unsigned int), 0644, NULL,
++	 &proc_dointvec_jiffies},
++	{0}
++};
++
++#define NET_IP_CONNTRACK_MAX 2089
++
++static ctl_table ip_ct_netfilter_table[] = {
++	{NET_IPV4_NETFILTER, "netfilter", NULL, 0, 0555, ip_ct_sysctl_table, 0, 0, 0, 0, 0},
++	{NET_IP_CONNTRACK_MAX, "ip_conntrack_max",
++	 &ip_conntrack_max, sizeof(int), 0644, NULL,
++	 &proc_dointvec},
++	{0}
++};
++
++static ctl_table ip_ct_ipv4_table[] = {
++	{NET_IPV4, "ipv4", NULL, 0, 0555, ip_ct_netfilter_table, 0, 0, 0, 0, 0},
++	{0}
++};
++
++static ctl_table ip_ct_net_table[] = {
++	{CTL_NET, "net", NULL, 0, 0555, ip_ct_ipv4_table, 0, 0, 0, 0, 0},
++	{0}
++};
++#endif
+ static int init_or_cleanup(int init)
+ {
+ 	struct proc_dir_entry *proc;
+@@ -291,10 +387,20 @@ static int init_or_cleanup(int init)
+ 		printk("ip_conntrack: can't register local in hook.\n");
+ 		goto cleanup_inoutandlocalops;
+ 	}
++#ifdef CONFIG_SYSCTL
++	ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
++	if (ip_ct_sysctl_header == NULL) {
++		printk("ip_conntrack: can't register to sysctl.\n");
++		goto cleanup;
++	}
++#endif
+ 
+ 	return ret;
+ 
+  cleanup:
++#ifdef CONFIG_SYSCTL
++ 	unregister_sysctl_table(ip_ct_sysctl_header);
++#endif
+ 	nf_unregister_hook(&ip_conntrack_local_in_ops);
+  cleanup_inoutandlocalops:
+ 	nf_unregister_hook(&ip_conntrack_out_ops);
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_nat_core.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_nat_core.c	2003-10-05 00:33:25.000000000 -0700
+@@ -516,12 +516,14 @@ ip_nat_setup_info(struct ip_conntrack *c
+ 	struct ip_conntrack_tuple new_tuple, inv_tuple, reply;
+ 	struct ip_conntrack_tuple orig_tp;
+ 	struct ip_nat_info *info = &conntrack->nat.info;
++	int in_hashes = info->initialized;
+ 
+ 	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
+ 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
+ 		     || hooknum == NF_IP_POST_ROUTING
+ 		     || hooknum == NF_IP_LOCAL_OUT);
+ 	IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
++	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
+ 
+ 	/* What we've got will look like inverse of reply. Normally
+ 	   this is what is in the conntrack, except for prior
+@@ -638,6 +640,14 @@ ip_nat_setup_info(struct ip_conntrack *c
+ 
+ 	/* It's done. */
+ 	info->initialized |= (1 << HOOK2MANIP(hooknum));
++
++	if (in_hashes) {
++		IP_NF_ASSERT(info->bysource.conntrack);
++		replace_in_hashes(conntrack, info);
++	} else {
++		place_in_hashes(conntrack, info);
++	}
++
+ 	return NF_ACCEPT;
+ }
+ 
+@@ -761,11 +771,6 @@ do_bindings(struct ip_conntrack *ct,
+ 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+ 	int proto = (*pskb)->nh.iph->protocol;
+ 
+-	/* Skip everything and don't call helpers if there are no
+-	 * manips for this connection */
+-	if (info->num_manips == 0)
+-		return NF_ACCEPT;
+-
+ 	/* Need nat lock to protect against modification, but neither
+ 	   conntrack (referenced) and helper (deleted with
+ 	   synchronize_bh()) can vanish. */
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_nat_helper.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_nat_helper.c	2003-10-05 00:33:25.000000000 -0700
+@@ -122,7 +122,6 @@ static void mangle_contents(struct sk_bu
+ 	/* fix IP hdr checksum information */
+ 	skb->nh.iph->tot_len = htons(skb->len);
+ 	ip_send_check(skb->nh.iph);
+-	skb->csum = csum_partial(data, skb->len - dataoff, 0);
+ }
+ 
+ /* Unusual, but possible case. */
+@@ -167,6 +166,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff 
+ {
+ 	struct iphdr *iph;
+ 	struct tcphdr *tcph;
++	int datalen;
+ 
+ 	if (!skb_ip_make_writable(pskb, (*pskb)->len))
+ 		return 0;
+@@ -184,11 +184,11 @@ ip_nat_mangle_tcp_packet(struct sk_buff 
+ 	mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,
+ 			match_offset, match_len, rep_buffer, rep_len);
+ 
++	datalen = (*pskb)->len - iph->ihl*4;
+ 	tcph->check = 0;
+-	tcph->check = tcp_v4_check(tcph, (*pskb)->len - iph->ihl*4,
+-				   iph->saddr, iph->daddr,
+-				   csum_partial((char *)tcph, tcph->doff*4,
+-						(*pskb)->csum));
++	tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr,
++				   csum_partial((char *)tcph, datalen, 0));
++
+ 	adjust_tcp_sequence(ntohl(tcph->seq),
+ 			    (int)rep_len - (int)match_len,
+ 			    ct, ctinfo);
+@@ -216,7 +216,12 @@ ip_nat_mangle_udp_packet(struct sk_buff 
+ {
+ 	struct iphdr *iph;
+ 	struct udphdr *udph;
+-	int need_csum = ((*pskb)->csum != 0);
++
++	/* UDP helpers might accidentally mangle the wrong packet */
++	iph = (*pskb)->nh.iph;
++	if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) + 
++	                       match_offset + match_len)
++		return 0;
+ 
+ 	if (!skb_ip_make_writable(pskb, (*pskb)->len))
+ 		return 0;
+@@ -235,17 +240,15 @@ ip_nat_mangle_udp_packet(struct sk_buff 
+ 	udph->len = htons((*pskb)->len - iph->ihl*4);
+ 
+ 	/* fix udp checksum if udp checksum was previously calculated */
+-	if (need_csum) {
++	if (udph->check) {
++		int datalen = (*pskb)->len - iph->ihl * 4;
+ 		udph->check = 0;
+-		udph->check
+-			= csum_tcpudp_magic(iph->saddr, iph->daddr,
+-					    (*pskb)->len - iph->ihl*4,
+-					    IPPROTO_UDP,
+-					    csum_partial((char *)udph,
+-							 sizeof(struct udphdr),
+-							 (*pskb)->csum));
+-	} else
+-		(*pskb)->csum = 0;
++		udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
++		                                datalen, IPPROTO_UDP,
++		                                csum_partial((char *)udph,
++		                                             datalen, 0));
++	}
++
+ 	return 1;
+ }
+ 
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_nat_rule.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_nat_rule.c	2003-10-05 00:33:25.000000000 -0700
+@@ -233,7 +233,7 @@ static int ipt_dnat_checkentry(const cha
+ 	return 1;
+ }
+ 
+-static inline unsigned int
++inline unsigned int
+ alloc_null_binding(struct ip_conntrack *conntrack,
+ 		   struct ip_nat_info *info,
+ 		   unsigned int hooknum)
+--- linux-2.6.0-test6/net/ipv4/netfilter/ip_nat_standalone.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ip_nat_standalone.c	2003-10-05 00:33:25.000000000 -0700
+@@ -119,7 +119,6 @@ ip_nat_fn(unsigned int hooknum,
+ 		/* Seen it before?  This can happen for loopback, retrans,
+ 		   or local packets.. */
+ 		if (!(info->initialized & (1 << maniptype))) {
+-			int in_hashes = info->initialized;
+ 			unsigned int ret;
+ 
+ 			if (ct->master
+@@ -130,9 +129,10 @@ ip_nat_fn(unsigned int hooknum,
+ 			} else {
+ #ifdef CONFIG_IP_NF_NAT_LOCAL
+ 				/* LOCAL_IN hook doesn't have a chain!  */
+-				if (hooknum == NF_IP_LOCAL_IN) {
+-					ret = NF_ACCEPT;
+-				} else
++				if (hooknum == NF_IP_LOCAL_IN)
++					ret = alloc_null_binding(ct, info,
++								 hooknum);
++				else
+ #endif
+ 				ret = ip_nat_rule_find(pskb, hooknum, in, out,
+ 						       ct, info);
+@@ -142,13 +142,6 @@ ip_nat_fn(unsigned int hooknum,
+ 				WRITE_UNLOCK(&ip_nat_lock);
+ 				return ret;
+ 			}
+-
+-			if (in_hashes) {
+-				IP_NF_ASSERT(info->bysource.conntrack);
+-				replace_in_hashes(ct, info);
+-			} else {
+-				place_in_hashes(ct, info);
+-			}
+ 		} else
+ 			DEBUGP("Already setup manip %s for ct %p\n",
+ 			       maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
+@@ -199,6 +192,7 @@ ip_nat_out(unsigned int hooknum,
+ 	return ip_nat_fn(hooknum, pskb, in, out, okfn);
+ }
+ 
++#ifdef CONFIG_IP_NF_NAT_LOCAL
+ static unsigned int
+ ip_nat_local_fn(unsigned int hooknum,
+ 		struct sk_buff **pskb,
+@@ -224,6 +218,7 @@ ip_nat_local_fn(unsigned int hooknum,
+ 		return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ 	return ret;
+ }
++#endif
+ 
+ /* We must be after connection tracking and before packet filtering. */
+ 
+@@ -245,6 +240,7 @@ static struct nf_hook_ops ip_nat_out_ops
+ 	.priority	= NF_IP_PRI_NAT_SRC,
+ };
+ 
++#ifdef CONFIG_IP_NF_NAT_LOCAL
+ /* Before packet filtering, change destination */
+ static struct nf_hook_ops ip_nat_local_out_ops = {
+ 	.hook		= ip_nat_local_fn,
+@@ -254,7 +250,7 @@ static struct nf_hook_ops ip_nat_local_o
+ 	.priority	= NF_IP_PRI_NAT_DST,
+ };
+ 
+-#ifdef CONFIG_IP_NF_NAT_LOCAL
++/* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */
+ static struct nf_hook_ops ip_nat_local_in_ops = {
+ 	.hook		= ip_nat_fn,
+ 	.owner		= THIS_MODULE,
+@@ -324,12 +320,12 @@ static int init_or_cleanup(int init)
+ 		printk("ip_nat_init: can't register out hook.\n");
+ 		goto cleanup_inops;
+ 	}
++#ifdef CONFIG_IP_NF_NAT_LOCAL
+ 	ret = nf_register_hook(&ip_nat_local_out_ops);
+ 	if (ret < 0) {
+ 		printk("ip_nat_init: can't register local out hook.\n");
+ 		goto cleanup_outops;
+ 	}
+-#ifdef CONFIG_IP_NF_NAT_LOCAL
+ 	ret = nf_register_hook(&ip_nat_local_in_ops);
+ 	if (ret < 0) {
+ 		printk("ip_nat_init: can't register local in hook.\n");
+@@ -342,9 +338,9 @@ static int init_or_cleanup(int init)
+ #ifdef CONFIG_IP_NF_NAT_LOCAL
+ 	nf_unregister_hook(&ip_nat_local_in_ops);
+  cleanup_localoutops:
+-#endif
+ 	nf_unregister_hook(&ip_nat_local_out_ops);
+  cleanup_outops:
++#endif
+ 	nf_unregister_hook(&ip_nat_out_ops);
+  cleanup_inops:
+ 	nf_unregister_hook(&ip_nat_in_ops);
+--- linux-2.6.0-test6/net/ipv4/netfilter/ipt_owner.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/ipv4/netfilter/ipt_owner.c	2003-10-05 00:36:15.000000000 -0700
+@@ -90,7 +90,7 @@ match_sid(const struct sk_buff *skb, pid
+ 	read_lock(&tasklist_lock);
+ 	do_each_thread(g, p) {
+ 		struct files_struct *files;
+-		if (p->session != sid)
++		if (process_session(p) != sid)
+ 			continue;
+ 
+ 		task_lock(p);
+--- linux-2.6.0-test6/net/ipv4/netfilter/ipt_REJECT.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/netfilter/ipt_REJECT.c	2003-10-05 00:33:25.000000000 -0700
+@@ -40,16 +40,17 @@ static void connection_attach(struct sk_
+ 	}
+ }
+ 
+-static inline struct rtable *route_reverse(struct sk_buff *skb, int local)
++static inline struct rtable *route_reverse(struct sk_buff *skb, int hook)
+ {
+ 	struct iphdr *iph = skb->nh.iph;
+ 	struct dst_entry *odst;
+ 	struct flowi fl = {};
+ 	struct rtable *rt;
+ 
+-	if (local) {
++	if (hook != NF_IP_FORWARD) {
+ 		fl.nl_u.ip4_u.daddr = iph->saddr;
+-		fl.nl_u.ip4_u.saddr = iph->daddr;
++		if (hook == NF_IP_LOCAL_IN)
++			fl.nl_u.ip4_u.saddr = iph->daddr;
+ 		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
+ 
+ 		if (ip_route_output_key(&rt, &fl) != 0)
+@@ -81,7 +82,7 @@ static inline struct rtable *route_rever
+ }
+ 
+ /* Send RST reply */
+-static void send_reset(struct sk_buff *oldskb, int local)
++static void send_reset(struct sk_buff *oldskb, int hook)
+ {
+ 	struct sk_buff *nskb;
+ 	struct tcphdr otcph, *tcph;
+@@ -104,7 +105,7 @@ static void send_reset(struct sk_buff *o
+ 		return;
+ 
+ 	/* FIXME: Check checksum --RR */
+-	if ((rt = route_reverse(oldskb, local)) == NULL)
++	if ((rt = route_reverse(oldskb, hook)) == NULL)
+ 		return;
+ 
+ 	hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
+@@ -390,7 +391,7 @@ static unsigned int reject(struct sk_buf
+ 		send_unreach(*pskb, ICMP_PKT_FILTERED);
+ 		break;
+ 	case IPT_TCP_RESET:
+-		send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
++		send_reset(*pskb, hooknum);
+ 	case IPT_ICMP_ECHOREPLY:
+ 		/* Doesn't happen. */
+ 		break;
+--- linux-2.6.0-test6/net/ipv4/protocol.c	2003-06-14 12:17:58.000000000 -0700
++++ 25/net/ipv4/protocol.c	2003-10-05 00:33:25.000000000 -0700
+@@ -27,6 +27,7 @@
+ 
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -95,3 +96,6 @@ int inet_del_protocol(struct inet_protoc
+ 
+ 	return ret;
+ }
++
++EXPORT_SYMBOL(inet_add_protocol);
++EXPORT_SYMBOL(inet_del_protocol);
+--- linux-2.6.0-test6/net/ipv4/route.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/route.c	2003-10-05 00:33:25.000000000 -0700
+@@ -62,6 +62,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+@@ -2823,3 +2824,7 @@ out_enomem1:
+ 	rc = -ENOMEM;
+ 	goto out;
+ }
++
++EXPORT_SYMBOL(__ip_select_ident);
++EXPORT_SYMBOL(ip_route_input);
++EXPORT_SYMBOL(ip_route_output_key);
+--- linux-2.6.0-test6/net/ipv4/sysctl_net_ipv4.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/ipv4/sysctl_net_ipv4.c	2003-10-05 00:33:25.000000000 -0700
+@@ -8,6 +8,7 @@
+  */
+ 
+ #include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/sysctl.h>
+ #include <linux/config.h>
+ #include <net/snmp.h>
+@@ -587,3 +588,5 @@ ctl_table ipv4_table[] = {
+ };
+ 
+ #endif /* CONFIG_SYSCTL */
++
++EXPORT_SYMBOL(ipv4_config);
+--- linux-2.6.0-test6/net/ipv4/tcp.c	2003-06-22 12:04:45.000000000 -0700
++++ 25/net/ipv4/tcp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -248,6 +248,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+ #include <linux/poll.h>
+@@ -2682,3 +2683,26 @@ void __init tcp_init(void)
+ 
+ 	tcpdiag_init();
+ }
++
++EXPORT_SYMBOL(__tcp_mem_reclaim);
++EXPORT_SYMBOL(sysctl_tcp_rmem);
++EXPORT_SYMBOL(sysctl_tcp_wmem);
++EXPORT_SYMBOL(tcp_accept);
++EXPORT_SYMBOL(tcp_close);
++EXPORT_SYMBOL(tcp_close_state);
++EXPORT_SYMBOL(tcp_destroy_sock);
++EXPORT_SYMBOL(tcp_disconnect);
++EXPORT_SYMBOL(tcp_getsockopt);
++EXPORT_SYMBOL(tcp_ioctl);
++EXPORT_SYMBOL(tcp_openreq_cachep);
++EXPORT_SYMBOL(tcp_poll);
++EXPORT_SYMBOL(tcp_read_sock);
++EXPORT_SYMBOL(tcp_recvmsg);
++EXPORT_SYMBOL(tcp_sendmsg);
++EXPORT_SYMBOL(tcp_sendpage);
++EXPORT_SYMBOL(tcp_setsockopt);
++EXPORT_SYMBOL(tcp_shutdown);
++EXPORT_SYMBOL(tcp_sockets_allocated);
++EXPORT_SYMBOL(tcp_statistics);
++EXPORT_SYMBOL(tcp_timewait_cachep);
++EXPORT_SYMBOL(tcp_write_space);
+--- linux-2.6.0-test6/net/ipv4/tcp_input.c	2003-07-27 12:14:40.000000000 -0700
++++ 25/net/ipv4/tcp_input.c	2003-10-05 00:33:25.000000000 -0700
+@@ -65,6 +65,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/sysctl.h>
+ #include <net/tcp.h>
+ #include <net/inet_common.h>
+@@ -4089,3 +4090,10 @@ discard:
+ 	}
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(sysctl_tcp_ecn);
++EXPORT_SYMBOL(sysctl_tcp_reordering);
++EXPORT_SYMBOL(tcp_cwnd_application_limited);
++EXPORT_SYMBOL(tcp_parse_options);
++EXPORT_SYMBOL(tcp_rcv_established);
++EXPORT_SYMBOL(tcp_rcv_state_process);
+--- linux-2.6.0-test6/net/ipv4/tcp_ipv4.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/tcp_ipv4.c	2003-10-05 00:33:25.000000000 -0700
+@@ -56,6 +56,7 @@
+ 
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
++#include <linux/module.h>
+ #include <linux/random.h>
+ #include <linux/cache.h>
+ #include <linux/jhash.h>
+@@ -2644,3 +2645,32 @@ void __init tcp_v4_init(struct net_proto
+ 	 */
+ 	tcp_socket->sk->sk_prot->unhash(tcp_socket->sk);
+ }
++
++EXPORT_SYMBOL(ipv4_specific);
++EXPORT_SYMBOL(tcp_bind_hash);
++EXPORT_SYMBOL(tcp_bucket_create);
++EXPORT_SYMBOL(tcp_hashinfo);
++EXPORT_SYMBOL(tcp_inherit_port);
++EXPORT_SYMBOL(tcp_listen_wlock);
++EXPORT_SYMBOL(tcp_port_rover);
++EXPORT_SYMBOL(tcp_prot);
++EXPORT_SYMBOL(tcp_put_port);
++EXPORT_SYMBOL(tcp_unhash);
++EXPORT_SYMBOL(tcp_v4_conn_request);
++EXPORT_SYMBOL(tcp_v4_connect);
++EXPORT_SYMBOL(tcp_v4_do_rcv);
++EXPORT_SYMBOL(tcp_v4_lookup_listener);
++EXPORT_SYMBOL(tcp_v4_rebuild_header);
++EXPORT_SYMBOL(tcp_v4_remember_stamp);
++EXPORT_SYMBOL(tcp_v4_send_check);
++EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
++
++#ifdef CONFIG_PROC_FS
++EXPORT_SYMBOL(tcp_proc_register);
++EXPORT_SYMBOL(tcp_proc_unregister);
++#endif
++#ifdef CONFIG_SYSCTL
++EXPORT_SYMBOL(sysctl_local_port_range);
++EXPORT_SYMBOL(sysctl_max_syn_backlog);
++EXPORT_SYMBOL(sysctl_tcp_low_latency);
++#endif
+--- linux-2.6.0-test6/net/ipv4/tcp_minisocks.c	2003-07-02 14:53:18.000000000 -0700
++++ 25/net/ipv4/tcp_minisocks.c	2003-10-05 00:33:25.000000000 -0700
+@@ -22,6 +22,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/sysctl.h>
+ #include <linux/workqueue.h>
+ #include <net/tcp.h>
+@@ -1053,3 +1054,13 @@ int tcp_child_process(struct sock *paren
+ 	sock_put(child);
+ 	return ret;
+ }
++
++EXPORT_SYMBOL(tcp_check_req);
++EXPORT_SYMBOL(tcp_child_process);
++EXPORT_SYMBOL(tcp_create_openreq_child);
++EXPORT_SYMBOL(tcp_timewait_state_process);
++EXPORT_SYMBOL(tcp_tw_deschedule);
++
++#ifdef CONFIG_SYSCTL
++EXPORT_SYMBOL(sysctl_tcp_tw_recycle);
++#endif
+--- linux-2.6.0-test6/net/ipv4/tcp_output.c	2003-07-02 14:53:18.000000000 -0700
++++ 25/net/ipv4/tcp_output.c	2003-10-05 00:33:25.000000000 -0700
+@@ -39,6 +39,7 @@
+ #include <net/tcp.h>
+ 
+ #include <linux/compiler.h>
++#include <linux/module.h>
+ #include <linux/smp_lock.h>
+ 
+ /* People can turn this off for buggy TCP's found in printers etc. */
+@@ -1542,3 +1543,14 @@ void tcp_send_probe0(struct sock *sk)
+ 				      min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL));
+ 	}
+ }
++
++EXPORT_SYMBOL(tcp_acceptable_seq);
++EXPORT_SYMBOL(tcp_connect);
++EXPORT_SYMBOL(tcp_connect_init);
++EXPORT_SYMBOL(tcp_make_synack);
++EXPORT_SYMBOL(tcp_send_synack);
++EXPORT_SYMBOL(tcp_simple_retransmit);
++EXPORT_SYMBOL(tcp_sync_mss);
++EXPORT_SYMBOL(tcp_transmit_skb);
++EXPORT_SYMBOL(tcp_write_wakeup);
++EXPORT_SYMBOL(tcp_write_xmit);
+--- linux-2.6.0-test6/net/ipv4/tcp_timer.c	2003-06-16 22:32:21.000000000 -0700
++++ 25/net/ipv4/tcp_timer.c	2003-10-05 00:33:25.000000000 -0700
+@@ -20,6 +20,7 @@
+  *		Jorge Cwik, <jorge@laser.satlink.net>
+  */
+ 
++#include <linux/module.h>
+ #include <net/tcp.h>
+ 
+ int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; 
+@@ -656,3 +657,8 @@ out:
+ 	bh_unlock_sock(sk);
+ 	sock_put(sk);
+ }
++
++EXPORT_SYMBOL(tcp_clear_xmit_timers);
++EXPORT_SYMBOL(tcp_delete_keepalive_timer);
++EXPORT_SYMBOL(tcp_init_xmit_timers);
++EXPORT_SYMBOL(tcp_reset_keepalive_timer);
+--- linux-2.6.0-test6/net/ipv4/udp.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/ipv4/udp.c	2003-10-05 00:33:25.000000000 -0700
+@@ -83,6 +83,7 @@
+ #include <asm/ioctls.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
++#include <linux/module.h>
+ #include <linux/socket.h>
+ #include <linux/sockios.h>
+ #include <linux/in.h>
+@@ -1532,3 +1533,17 @@ void udp4_proc_exit(void)
+ 	udp_proc_unregister(&udp4_seq_afinfo);
+ }
+ #endif /* CONFIG_PROC_FS */
++
++EXPORT_SYMBOL(udp_connect);
++EXPORT_SYMBOL(udp_disconnect);
++EXPORT_SYMBOL(udp_hash);
++EXPORT_SYMBOL(udp_hash_lock);
++EXPORT_SYMBOL(udp_ioctl);
++EXPORT_SYMBOL(udp_port_rover);
++EXPORT_SYMBOL(udp_prot);
++EXPORT_SYMBOL(udp_sendmsg);
++
++#ifdef CONFIG_PROC_FS
++EXPORT_SYMBOL(udp_proc_register);
++EXPORT_SYMBOL(udp_proc_unregister);
++#endif
+--- linux-2.6.0-test6/net/ipv4/utils.c	2003-07-02 14:53:18.000000000 -0700
++++ 25/net/ipv4/utils.c	2003-10-05 00:33:25.000000000 -0700
+@@ -21,6 +21,7 @@
+  *		2 of the License, or (at your option) any later version.
+  */
+ 
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <asm/byteorder.h>
+ 
+@@ -55,3 +56,4 @@ __u32 in_aton(const char *str)
+ 	return(htonl(l));
+ }
+ 
++EXPORT_SYMBOL(in_aton);
+--- linux-2.6.0-test6/net/ipv4/xfrm4_tunnel.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/ipv4/xfrm4_tunnel.c	2003-10-05 00:33:25.000000000 -0700
+@@ -169,6 +169,7 @@ static struct xfrm_type ipip_type = {
+ static struct inet_protocol ipip_protocol = {
+ 	.handler	=	ipip_rcv,
+ 	.err_handler	=	ipip_err,
++	.no_policy	=	1,
+ };
+ 
+ static int __init ipip_init(void)
+--- linux-2.6.0-test6/net/ipv6/netfilter/ip6t_ipv6header.c	2003-06-14 12:18:51.000000000 -0700
++++ 25/net/ipv6/netfilter/ip6t_ipv6header.c	2003-10-05 00:33:25.000000000 -0700
+@@ -126,18 +126,11 @@ ipv6header_checkentry(const char *tablen
+ 	return 1;
+ }
+ 
+-static void
+-ipv6header_destroy(void *matchinfo,
+-		   unsigned int matchinfosize)
+-{
+-	return;
+-}
+-
+ static struct ip6t_match ip6t_ipv6header_match = {
+ 	.name		= "ipv6header",
+ 	.match		= &ipv6header_match,
+ 	.checkentry	= &ipv6header_checkentry,
+-	.destroy	= &ipv6header_destroy,
++	.destroy	= NULL,
+ 	.me		= THIS_MODULE,
+ };
+ 
+--- linux-2.6.0-test6/net/ipv6/netfilter/ip6t_owner.c	2003-06-14 12:18:30.000000000 -0700
++++ 25/net/ipv6/netfilter/ip6t_owner.c	2003-10-05 00:36:15.000000000 -0700
+@@ -56,7 +56,7 @@ match_sid(const struct sk_buff *skb, pid
+ 	read_lock(&tasklist_lock);
+ 	do_each_thread(g, p) {
+ 		struct files_struct *files;
+-		if (p->session != sid)
++		if (process_session(p) != sid)
+ 			continue;
+ 
+ 		task_lock(p);
+--- linux-2.6.0-test6/net/irda/irda_device.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/irda/irda_device.c	2003-10-05 00:33:25.000000000 -0700
+@@ -85,7 +85,7 @@ static void irda_task_timer_expired(void
+ 
+ int __init irda_device_init( void)
+ {
+-	dongles = hashbin_new(HB_LOCK);
++	dongles = hashbin_new(HB_NOLOCK);
+ 	if (dongles == NULL) {
+ 		printk(KERN_WARNING "IrDA: Can't allocate dongles hashbin!\n");
+ 		return -ENOMEM;
+@@ -109,7 +109,9 @@ void __exit irda_device_cleanup(void)
+ 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+ 
+ 	hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
++	spin_lock(&dongles->hb_spinlock);
+ 	hashbin_delete(dongles, NULL);
++	spin_unlock(&dongles->hb_spinlock);
+ }
+ 
+ /*
+@@ -378,8 +380,6 @@ void irda_device_setup(struct net_device
+         dev->hard_header_len = 0;
+         dev->addr_len        = 0;
+ 
+-	dev->destructor      = free_netdev;
+-
+         dev->type            = ARPHRD_IRDA;
+         dev->tx_queue_len    = 8; /* Window size + 1 s-frame */
+ 
+@@ -390,6 +390,17 @@ void irda_device_setup(struct net_device
+ }
+ 
+ /*
++ * Funciton  alloc_irdadev 
++ * 	Allocates and sets up an IRDA device in a manner similar to
++ * 	alloc_etherdev.
++ */
++struct net_device *alloc_irdadev(int sizeof_priv)
++{
++	return alloc_netdev(sizeof_priv, "irda%d", irda_device_setup);
++}
++
++
++/*
+  * Function irda_device_txqueue_empty (dev)
+  *
+  *    Check if there is still some frames in the transmit queue for this
+@@ -415,25 +426,34 @@ int irda_device_txqueue_empty(struct net
+ dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
+ {
+ 	struct dongle_reg *reg;
+-	dongle_t *dongle;
++	dongle_t *dongle = NULL;
++
++	might_sleep();
+ 
+-	ASSERT(dev != NULL, return NULL;);
++	spin_lock(&dongles->hb_spinlock);
++	reg = hashbin_find(dongles, type, NULL);
+ 
+ #ifdef CONFIG_KMOD
+-	ASSERT(!in_interrupt(), return NULL;);
+ 	/* Try to load the module needed */
+-	request_module("irda-dongle-%d", type);
++	if (!reg && capable(CAP_SYS_MODULE)) {
++		spin_unlock(&dongles->hb_spinlock);
++	
++		request_module("irda-dongle-%d", type);
++		
++		spin_lock(&dongles->hb_spinlock);
++		reg = hashbin_find(dongles, type, NULL);
++	}
+ #endif
+ 
+-	if (!(reg = hashbin_lock_find(dongles, type, NULL))) {
+-		ERROR("IrDA: Unable to find requested dongle\n");
+-		return NULL;
++	if (!reg || !try_module_get(reg->owner) ) {
++		ERROR("IrDA: Unable to find requested dongle type %x\n", type);
++		goto out;
+ 	}
+ 
+ 	/* Allocate dongle info for this instance */
+ 	dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL);
+ 	if (!dongle)
+-		return NULL;
++		goto out;
+ 
+ 	memset(dongle, 0, sizeof(dongle_t));
+ 
+@@ -441,6 +461,8 @@ dongle_t *irda_device_dongle_init(struct
+ 	dongle->issue = reg;
+ 	dongle->dev = dev;
+ 
++ out:
++	spin_unlock(&dongles->hb_spinlock);
+ 	return dongle;
+ }
+ 
+@@ -452,7 +474,7 @@ int irda_device_dongle_cleanup(dongle_t 
+ 	ASSERT(dongle != NULL, return -1;);
+ 
+ 	dongle->issue->close(dongle);
+-
++	module_put(dongle->issue->owner);
+ 	kfree(dongle);
+ 
+ 	return 0;
+@@ -463,14 +485,16 @@ int irda_device_dongle_cleanup(dongle_t 
+  */
+ int irda_device_register_dongle(struct dongle_reg *new)
+ {
++	spin_lock(&dongles->hb_spinlock);
+ 	/* Check if this dongle has been registered before */
+-	if (hashbin_lock_find(dongles, new->type, NULL)) {
+-		MESSAGE("%s: Dongle already registered\n", __FUNCTION__);
+-                return 0;
+-        }
+-
+-	/* Insert IrDA dongle into hashbin */
+-	hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
++	if (hashbin_find(dongles, new->type, NULL)) {
++		MESSAGE("%s: Dongle type %x already registered\n", 
++			__FUNCTION__, new->type);
++        } else {
++		/* Insert IrDA dongle into hashbin */
++		hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
++	}
++	spin_unlock(&dongles->hb_spinlock);
+ 
+         return 0;
+ }
+@@ -485,11 +509,11 @@ void irda_device_unregister_dongle(struc
+ {
+ 	struct dongle *node;
+ 
++	spin_lock(&dongles->hb_spinlock);
+ 	node = hashbin_remove(dongles, dongle->type, NULL);
+-	if (!node) {
++	if (!node) 
+ 		ERROR("%s: dongle not found!\n", __FUNCTION__);
+-		return;
+-	}
++	spin_unlock(&dongles->hb_spinlock);
+ }
+ 
+ /*
+--- linux-2.6.0-test6/net/irda/irsyms.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/irda/irsyms.c	2003-10-05 00:33:25.000000000 -0700
+@@ -150,6 +150,7 @@ EXPORT_SYMBOL(irlap_close);
+ EXPORT_SYMBOL(irda_init_max_qos_capabilies);
+ EXPORT_SYMBOL(irda_qos_bits_to_value);
+ EXPORT_SYMBOL(irda_device_setup);
++EXPORT_SYMBOL(alloc_irdadev);
+ EXPORT_SYMBOL(irda_device_set_media_busy);
+ EXPORT_SYMBOL(irda_device_txqueue_empty);
+ 
+--- linux-2.6.0-test6/net/Makefile	2003-06-14 12:18:08.000000000 -0700
++++ 25/net/Makefile	2003-10-05 00:33:25.000000000 -0700
+@@ -40,6 +40,5 @@ obj-$(CONFIG_VLAN_8021Q)	+= 8021q/
+ obj-$(CONFIG_IP_SCTP)		+= sctp/
+ 
+ ifeq ($(CONFIG_NET),y)
+-obj-$(CONFIG_MODULES)		+= netsyms.o
+ obj-$(CONFIG_SYSCTL)		+= sysctl_net.o
+ endif
+--- linux-2.6.0-test6/net/netlink/af_netlink.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/netlink/af_netlink.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1133,4 +1133,22 @@ core_initcall(netlink_proto_init);
+ module_exit(netlink_proto_exit);
+ 
+ MODULE_LICENSE("GPL");
++
+ MODULE_ALIAS_NETPROTO(PF_NETLINK);
++
++EXPORT_SYMBOL(netlink_ack);
++EXPORT_SYMBOL(netlink_broadcast);
++EXPORT_SYMBOL(netlink_broadcast_deliver);
++EXPORT_SYMBOL(netlink_dump_start);
++EXPORT_SYMBOL(netlink_kernel_create);
++EXPORT_SYMBOL(netlink_register_notifier);
++EXPORT_SYMBOL(netlink_set_err);
++EXPORT_SYMBOL(netlink_set_nonroot);
++EXPORT_SYMBOL(netlink_unicast);
++EXPORT_SYMBOL(netlink_unregister_notifier);
++
++#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
++EXPORT_SYMBOL(netlink_attach);
++EXPORT_SYMBOL(netlink_detach);
++EXPORT_SYMBOL(netlink_post);
++#endif
+--- linux-2.6.0-test6/net/netsyms.c	2003-09-27 18:57:47.000000000 -0700
++++ /dev/null	2002-08-30 16:31:37.000000000 -0700
+@@ -1,640 +0,0 @@
+-/*
+- *  linux/net/netsyms.c
+- *
+- *  Symbol table for the linux networking subsystem. Moved here to
+- *  make life simpler in ksyms.c.
+- */
+-
+-#include <linux/config.h>
+-#include <linux/module.h>
+-
+-#include <linux/types.h>
+-#include <linux/net.h>
+-#include <linux/in.h>
+-#include <linux/netdevice.h>
+-#include <linux/inetdevice.h>
+-#include <linux/fddidevice.h>
+-#include <linux/trdevice.h>
+-#include <linux/fcdevice.h>
+-#include <linux/ioport.h>
+-#include <linux/tty.h>
+-#include <linux/ethtool.h>
+-#include <net/neighbour.h>
+-#include <net/snmp.h>
+-#include <net/dst.h>
+-#include <net/checksum.h>
+-#include <linux/etherdevice.h>
+-#include <net/route.h>
+-#ifdef CONFIG_HIPPI
+-#include <linux/hippidevice.h>
+-#endif
+-#include <net/pkt_sched.h>
+-#include <net/scm.h>
+-#include <linux/if_bridge.h>
+-#include <linux/if_vlan.h>
+-#include <linux/random.h>
+-#ifdef CONFIG_NET_DIVERT
+-#include <linux/divert.h>
+-#endif /* CONFIG_NET_DIVERT */
+-
+-#ifdef CONFIG_NET
+-extern __u32 sysctl_wmem_max;
+-extern __u32 sysctl_rmem_max;
+-#endif
+-
+-#ifdef CONFIG_INET
+-#include <linux/ip.h>
+-#include <net/protocol.h>
+-#include <net/arp.h>
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-#include <net/atmclip.h>
+-#endif
+-#include <net/ip.h>
+-#include <net/udp.h>
+-#include <net/tcp.h>
+-#include <net/icmp.h>
+-#include <net/inet_common.h>
+-#include <linux/inet.h>
+-#include <linux/mroute.h>
+-#include <linux/igmp.h>
+-#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
+-#include <net/ah.h>
+-#endif
+-#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
+-#include <net/esp.h>
+-#endif
+-
+-extern struct net_proto_family inet_family_ops;
+-
+-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) \
+-   || defined (CONFIG_IP_SCTP_MODULE)
+-#include <linux/in6.h>
+-#include <linux/icmpv6.h>
+-#include <net/ipv6.h>
+-#include <net/ndisc.h>
+-#include <net/transp_v6.h>
+-#include <net/addrconf.h>
+-
+-extern int sysctl_local_port_range[2];
+-extern int tcp_port_rover;
+-extern int udp_port_rover;
+-#endif
+-
+-#endif
+-
+-#include <linux/rtnetlink.h>
+-
+-#ifdef CONFIG_IPX_MODULE
+-extern struct datalink_proto   *make_EII_client(void);
+-extern struct datalink_proto   *make_8023_client(void);
+-extern void destroy_EII_client(struct datalink_proto *);
+-extern void destroy_8023_client(struct datalink_proto *);
+-#endif
+-
+-#ifdef CONFIG_ATALK_MODULE
+-#include <net/sock.h>
+-#endif
+-
+-#ifdef CONFIG_SYSCTL
+-extern int sysctl_max_syn_backlog;
+-#endif
+-
+-/* Skbuff symbols. */
+-EXPORT_SYMBOL(skb_over_panic);
+-EXPORT_SYMBOL(skb_under_panic);
+-
+-/* Socket layer registration */
+-EXPORT_SYMBOL(sock_register);
+-EXPORT_SYMBOL(sock_unregister);
+-
+-/* Socket locking */
+-EXPORT_SYMBOL(__lock_sock);
+-EXPORT_SYMBOL(__release_sock);
+-
+-/* Socket layer support routines */
+-EXPORT_SYMBOL(memcpy_fromiovec);
+-EXPORT_SYMBOL(memcpy_tokerneliovec);
+-EXPORT_SYMBOL(sock_create);
+-EXPORT_SYMBOL(sock_alloc);
+-EXPORT_SYMBOL(sock_release);
+-EXPORT_SYMBOL(sock_setsockopt);
+-EXPORT_SYMBOL(sock_getsockopt);
+-EXPORT_SYMBOL(sock_sendmsg);
+-EXPORT_SYMBOL(sock_recvmsg);
+-EXPORT_SYMBOL(sk_alloc);
+-EXPORT_SYMBOL(sk_free);
+-EXPORT_SYMBOL(sk_send_sigurg);
+-EXPORT_SYMBOL(sock_wake_async);
+-EXPORT_SYMBOL(sock_alloc_send_skb);
+-EXPORT_SYMBOL(sock_alloc_send_pskb);
+-EXPORT_SYMBOL(sock_init_data);
+-EXPORT_SYMBOL(sock_no_release);
+-EXPORT_SYMBOL(sock_no_bind);
+-EXPORT_SYMBOL(sock_no_connect);
+-EXPORT_SYMBOL(sock_no_socketpair);
+-EXPORT_SYMBOL(sock_no_accept);
+-EXPORT_SYMBOL(sock_no_getname);
+-EXPORT_SYMBOL(sock_no_poll);
+-EXPORT_SYMBOL(sock_no_ioctl);
+-EXPORT_SYMBOL(sock_no_listen);
+-EXPORT_SYMBOL(sock_no_shutdown);
+-EXPORT_SYMBOL(sock_no_getsockopt);
+-EXPORT_SYMBOL(sock_no_setsockopt);
+-EXPORT_SYMBOL(sock_no_sendmsg);
+-EXPORT_SYMBOL(sock_no_recvmsg);
+-EXPORT_SYMBOL(sock_no_mmap);
+-EXPORT_SYMBOL(sock_no_sendpage);
+-EXPORT_SYMBOL(sock_rfree);
+-EXPORT_SYMBOL(sock_wfree);
+-EXPORT_SYMBOL(sock_wmalloc);
+-EXPORT_SYMBOL(sock_rmalloc);
+-EXPORT_SYMBOL(__skb_linearize);
+-EXPORT_SYMBOL(skb_checksum);
+-EXPORT_SYMBOL(skb_checksum_help);
+-EXPORT_SYMBOL(skb_recv_datagram);
+-EXPORT_SYMBOL(skb_free_datagram);
+-EXPORT_SYMBOL(skb_copy_datagram);
+-EXPORT_SYMBOL(skb_copy_datagram_iovec);
+-EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
+-EXPORT_SYMBOL(skb_copy_bits);
+-EXPORT_SYMBOL(skb_copy_and_csum_bits);
+-EXPORT_SYMBOL(skb_copy_and_csum_dev);
+-EXPORT_SYMBOL(skb_copy_expand);
+-EXPORT_SYMBOL(___pskb_trim);
+-EXPORT_SYMBOL(__pskb_pull_tail);
+-EXPORT_SYMBOL(pskb_expand_head);
+-EXPORT_SYMBOL(pskb_copy);
+-EXPORT_SYMBOL(skb_realloc_headroom);
+-EXPORT_SYMBOL(datagram_poll);
+-EXPORT_SYMBOL(put_cmsg);
+-EXPORT_SYMBOL(sock_kmalloc);
+-EXPORT_SYMBOL(sock_kfree_s);
+-EXPORT_SYMBOL(sock_map_fd);
+-EXPORT_SYMBOL(sockfd_lookup);
+-
+-EXPORT_SYMBOL(sk_run_filter);
+-EXPORT_SYMBOL(sk_chk_filter);
+-
+-EXPORT_SYMBOL(neigh_table_init);
+-EXPORT_SYMBOL(neigh_table_clear);
+-EXPORT_SYMBOL(neigh_resolve_output);
+-EXPORT_SYMBOL(neigh_connected_output);
+-EXPORT_SYMBOL(neigh_update);
+-EXPORT_SYMBOL(neigh_create);
+-EXPORT_SYMBOL(neigh_lookup);
+-EXPORT_SYMBOL(__neigh_event_send);
+-EXPORT_SYMBOL(neigh_event_ns);
+-EXPORT_SYMBOL(neigh_ifdown);
+-#ifdef CONFIG_ARPD
+-EXPORT_SYMBOL(neigh_app_ns);
+-#endif
+-#ifdef CONFIG_SYSCTL
+-EXPORT_SYMBOL(neigh_sysctl_register);
+-EXPORT_SYMBOL(neigh_sysctl_unregister);
+-#endif
+-EXPORT_SYMBOL(pneigh_lookup);
+-EXPORT_SYMBOL(pneigh_enqueue);
+-EXPORT_SYMBOL(neigh_destroy);
+-EXPORT_SYMBOL(neigh_parms_alloc);
+-EXPORT_SYMBOL(neigh_parms_release);
+-EXPORT_SYMBOL(neigh_rand_reach_time);
+-EXPORT_SYMBOL(neigh_compat_output); 
+-EXPORT_SYMBOL(neigh_changeaddr); 
+-
+-/*	dst_entry	*/
+-EXPORT_SYMBOL(dst_alloc);
+-EXPORT_SYMBOL(__dst_free);
+-EXPORT_SYMBOL(dst_destroy);
+-
+-/*	misc. support routines */
+-EXPORT_SYMBOL(net_ratelimit);
+-EXPORT_SYMBOL(net_random);
+-EXPORT_SYMBOL(net_srandom);
+-
+-/* Needed by smbfs.o */
+-EXPORT_SYMBOL(__scm_destroy);
+-EXPORT_SYMBOL(__scm_send);
+-
+-/* Needed by unix.o */
+-EXPORT_SYMBOL(scm_fp_dup);
+-EXPORT_SYMBOL(files_stat);
+-EXPORT_SYMBOL(memcpy_toiovec);
+-
+-#ifdef CONFIG_IPX_MODULE
+-EXPORT_SYMBOL(make_8023_client);
+-EXPORT_SYMBOL(destroy_8023_client);
+-EXPORT_SYMBOL(make_EII_client);
+-EXPORT_SYMBOL(destroy_EII_client);
+-#endif
+-
+-/* for 801q VLAN support */
+-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+-EXPORT_SYMBOL(dev_change_flags);
+-#endif
+-
+-EXPORT_SYMBOL(scm_detach_fds);
+-
+-#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+-EXPORT_SYMBOL(br_handle_frame_hook);
+-#endif
+-
+-#ifdef CONFIG_NET_DIVERT
+-EXPORT_SYMBOL(alloc_divert_blk);
+-EXPORT_SYMBOL(free_divert_blk);
+-#endif /* CONFIG_NET_DIVERT */
+-
+-#ifdef CONFIG_INET
+-/* Internet layer registration */
+-EXPORT_SYMBOL(inetdev_lock);
+-EXPORT_SYMBOL(inet_add_protocol);
+-EXPORT_SYMBOL(inet_del_protocol);
+-EXPORT_SYMBOL(inet_register_protosw);
+-EXPORT_SYMBOL(inet_unregister_protosw);
+-EXPORT_SYMBOL(ip_route_output_key);
+-EXPORT_SYMBOL(ip_route_input);
+-EXPORT_SYMBOL(icmp_send);
+-EXPORT_SYMBOL(icmp_statistics);
+-EXPORT_SYMBOL(icmp_err_convert);
+-EXPORT_SYMBOL(ip_options_compile);
+-EXPORT_SYMBOL(ip_options_undo);
+-EXPORT_SYMBOL(arp_send);
+-EXPORT_SYMBOL(arp_broken_ops);
+-EXPORT_SYMBOL(__ip_select_ident);
+-EXPORT_SYMBOL(ip_send_check);
+-EXPORT_SYMBOL(ip_fragment);
+-EXPORT_SYMBOL(inet_family_ops);
+-EXPORT_SYMBOL(in_aton);
+-EXPORT_SYMBOL(ip_mc_inc_group);
+-EXPORT_SYMBOL(ip_mc_dec_group);
+-EXPORT_SYMBOL(ip_mc_join_group);
+-EXPORT_SYMBOL(ip_finish_output);
+-EXPORT_SYMBOL(inet_stream_ops);
+-EXPORT_SYMBOL(inet_dgram_ops);
+-EXPORT_SYMBOL(ip_cmsg_recv);
+-EXPORT_SYMBOL(inet_addr_type); 
+-EXPORT_SYMBOL(inet_select_addr);
+-EXPORT_SYMBOL(ip_dev_find);
+-EXPORT_SYMBOL(inetdev_by_index);
+-EXPORT_SYMBOL(in_dev_finish_destroy);
+-EXPORT_SYMBOL(ip_defrag);
+-EXPORT_SYMBOL(inet_peer_idlock);
+-
+-/* Route manipulation */
+-EXPORT_SYMBOL(ip_rt_ioctl);
+-EXPORT_SYMBOL(devinet_ioctl);
+-EXPORT_SYMBOL(register_inetaddr_notifier);
+-EXPORT_SYMBOL(unregister_inetaddr_notifier);
+-
+-/* proc */
+-#ifdef CONFIG_PROC_FS
+-EXPORT_SYMBOL(udp_proc_register);
+-EXPORT_SYMBOL(udp_proc_unregister);
+-EXPORT_SYMBOL(tcp_proc_register);
+-EXPORT_SYMBOL(tcp_proc_unregister);
+-#endif
+-
+-/* needed for ip_gre -cw */
+-EXPORT_SYMBOL(ip_statistics);
+-#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
+-EXPORT_SYMBOL_GPL(skb_cow_data);
+-EXPORT_SYMBOL_GPL(pskb_put);
+-EXPORT_SYMBOL_GPL(skb_to_sgvec);
+-#endif
+-
+-EXPORT_SYMBOL(flow_cache_lookup);
+-EXPORT_SYMBOL(flow_cache_genid);
+-
+-#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE)
+-/* inet functions common to v4 and v6 */
+-EXPORT_SYMBOL(inet_release);
+-EXPORT_SYMBOL(inet_stream_connect);
+-EXPORT_SYMBOL(inet_dgram_connect);
+-EXPORT_SYMBOL(inet_accept);
+-EXPORT_SYMBOL(inet_listen);
+-EXPORT_SYMBOL(inet_shutdown);
+-EXPORT_SYMBOL(inet_setsockopt);
+-EXPORT_SYMBOL(inet_getsockopt);
+-EXPORT_SYMBOL(inet_sendmsg);
+-EXPORT_SYMBOL(inet_recvmsg);
+-#ifdef INET_REFCNT_DEBUG
+-EXPORT_SYMBOL(inet_sock_nr);
+-#endif
+-EXPORT_SYMBOL(inet_sock_destruct);
+-EXPORT_SYMBOL(inet_sock_release);
+-
+-/* Socket demultiplexing. */
+-EXPORT_SYMBOL(tcp_hashinfo);
+-EXPORT_SYMBOL(tcp_listen_wlock);
+-EXPORT_SYMBOL(udp_hash);
+-EXPORT_SYMBOL(udp_hash_lock);
+-
+-EXPORT_SYMBOL(tcp_destroy_sock);
+-EXPORT_SYMBOL(ip_queue_xmit);
+-EXPORT_SYMBOL(memcpy_fromiovecend);
+-EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
+-EXPORT_SYMBOL(tcp_v4_lookup_listener);
+-/* UDP/TCP exported functions for TCPv6 */
+-EXPORT_SYMBOL(udp_ioctl);
+-EXPORT_SYMBOL(udp_connect);
+-EXPORT_SYMBOL(udp_disconnect);
+-EXPORT_SYMBOL(udp_sendmsg);
+-EXPORT_SYMBOL(tcp_bind_hash);
+-EXPORT_SYMBOL(tcp_close);
+-EXPORT_SYMBOL(tcp_disconnect);
+-EXPORT_SYMBOL(tcp_accept);
+-EXPORT_SYMBOL(tcp_write_wakeup);
+-EXPORT_SYMBOL(tcp_write_space);
+-EXPORT_SYMBOL(tcp_poll);
+-EXPORT_SYMBOL(tcp_ioctl);
+-EXPORT_SYMBOL(tcp_shutdown);
+-EXPORT_SYMBOL(tcp_setsockopt);
+-EXPORT_SYMBOL(tcp_getsockopt);
+-EXPORT_SYMBOL(tcp_recvmsg);
+-EXPORT_SYMBOL(tcp_send_synack);
+-EXPORT_SYMBOL(tcp_check_req);
+-EXPORT_SYMBOL(tcp_child_process);
+-EXPORT_SYMBOL(tcp_parse_options);
+-EXPORT_SYMBOL(tcp_rcv_established);
+-EXPORT_SYMBOL(tcp_init_xmit_timers);
+-EXPORT_SYMBOL(tcp_clear_xmit_timers);
+-EXPORT_SYMBOL(tcp_statistics);
+-EXPORT_SYMBOL(tcp_rcv_state_process);
+-EXPORT_SYMBOL(tcp_timewait_state_process);
+-EXPORT_SYMBOL(tcp_timewait_cachep);
+-EXPORT_SYMBOL(tcp_sendmsg);
+-EXPORT_SYMBOL(tcp_v4_rebuild_header);
+-EXPORT_SYMBOL(tcp_v4_send_check);
+-EXPORT_SYMBOL(tcp_v4_conn_request);
+-EXPORT_SYMBOL(tcp_create_openreq_child);
+-EXPORT_SYMBOL(tcp_bucket_create);
+-EXPORT_SYMBOL(tcp_put_port);
+-EXPORT_SYMBOL(tcp_inherit_port);
+-EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
+-EXPORT_SYMBOL(tcp_v4_do_rcv);
+-EXPORT_SYMBOL(tcp_v4_connect);
+-EXPORT_SYMBOL(tcp_unhash);
+-EXPORT_SYMBOL(udp_prot);
+-EXPORT_SYMBOL(tcp_prot);
+-EXPORT_SYMBOL(tcp_openreq_cachep);
+-EXPORT_SYMBOL(ipv4_specific);
+-EXPORT_SYMBOL(tcp_simple_retransmit);
+-EXPORT_SYMBOL(tcp_transmit_skb);
+-EXPORT_SYMBOL(tcp_connect);
+-EXPORT_SYMBOL(tcp_make_synack);
+-EXPORT_SYMBOL(tcp_tw_deschedule);
+-EXPORT_SYMBOL(tcp_delete_keepalive_timer);
+-EXPORT_SYMBOL(tcp_reset_keepalive_timer);
+-EXPORT_SYMBOL(sysctl_local_port_range);
+-EXPORT_SYMBOL(tcp_port_rover);
+-EXPORT_SYMBOL(udp_port_rover);
+-EXPORT_SYMBOL(tcp_sync_mss);
+-EXPORT_SYMBOL(net_statistics); 
+-EXPORT_SYMBOL(__tcp_mem_reclaim);
+-EXPORT_SYMBOL(tcp_sockets_allocated);
+-EXPORT_SYMBOL(sysctl_tcp_reordering);
+-EXPORT_SYMBOL(sysctl_tcp_rmem);
+-EXPORT_SYMBOL(sysctl_tcp_wmem);
+-EXPORT_SYMBOL(sysctl_tcp_ecn);
+-EXPORT_SYMBOL(tcp_cwnd_application_limited);
+-EXPORT_SYMBOL(tcp_sendpage);
+-EXPORT_SYMBOL(sysctl_tcp_low_latency);
+-
+-EXPORT_SYMBOL(tcp_write_xmit);
+-
+-EXPORT_SYMBOL(tcp_v4_remember_stamp); 
+-
+-extern int sysctl_tcp_tw_recycle;
+-
+-#ifdef CONFIG_SYSCTL
+-EXPORT_SYMBOL(sysctl_tcp_tw_recycle); 
+-EXPORT_SYMBOL(sysctl_max_syn_backlog);
+-#endif
+-
+-EXPORT_SYMBOL(ip_generic_getfrag);
+-
+-#endif
+-
+-EXPORT_SYMBOL(tcp_read_sock);
+-
+-#ifdef CONFIG_IP_SCTP_MODULE
+-EXPORT_SYMBOL(ip_setsockopt);
+-EXPORT_SYMBOL(ip_getsockopt);
+-EXPORT_SYMBOL(inet_ioctl);
+-EXPORT_SYMBOL(inet_bind);
+-EXPORT_SYMBOL(inet_getname);
+-#endif /* CONFIG_IP_SCTP_MODULE */
+-
+-EXPORT_SYMBOL(netlink_set_err);
+-EXPORT_SYMBOL(netlink_broadcast);
+-EXPORT_SYMBOL(netlink_unicast);
+-EXPORT_SYMBOL(netlink_kernel_create);
+-EXPORT_SYMBOL(netlink_dump_start);
+-EXPORT_SYMBOL(netlink_ack);
+-EXPORT_SYMBOL(netlink_set_nonroot);
+-EXPORT_SYMBOL(netlink_register_notifier);
+-EXPORT_SYMBOL(netlink_unregister_notifier);
+-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
+-EXPORT_SYMBOL(netlink_attach);
+-EXPORT_SYMBOL(netlink_detach);
+-EXPORT_SYMBOL(netlink_post);
+-#endif
+-
+-EXPORT_SYMBOL(rtattr_parse);
+-EXPORT_SYMBOL(__rta_fill);
+-EXPORT_SYMBOL(neigh_delete);
+-EXPORT_SYMBOL(neigh_add);
+-EXPORT_SYMBOL(neigh_dump_info);
+-
+-
+-/* ABI emulation layers need this */
+-EXPORT_SYMBOL(move_addr_to_kernel);
+-EXPORT_SYMBOL(move_addr_to_user);
+-                  
+-/* Used by at least ipip.c.  */
+-EXPORT_SYMBOL(ipv4_config);
+-
+-/* Used by other modules */
+-EXPORT_SYMBOL(xrlim_allow);
+-
+-EXPORT_SYMBOL(ip_rcv);
+-EXPORT_SYMBOL(arp_rcv);
+-EXPORT_SYMBOL(arp_tbl);
+-#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+-EXPORT_SYMBOL(clip_tbl_hook);
+-#endif
+-EXPORT_SYMBOL(arp_find);
+-
+-#endif  /* CONFIG_INET */
+-
+-#ifdef CONFIG_TR
+-EXPORT_SYMBOL(tr_source_route);
+-EXPORT_SYMBOL(tr_type_trans);
+-#endif
+-
+-/* Device callback registration */
+-EXPORT_SYMBOL(register_netdevice_notifier);
+-EXPORT_SYMBOL(unregister_netdevice_notifier);
+-EXPORT_SYMBOL(call_netdevice_notifiers);
+-
+-/* support for loadable net drivers */
+-#ifdef CONFIG_NET
+-EXPORT_SYMBOL(loopback_dev);
+-EXPORT_SYMBOL(register_netdevice);
+-EXPORT_SYMBOL(unregister_netdevice);
+-EXPORT_SYMBOL(free_netdev);
+-EXPORT_SYMBOL(synchronize_net);
+-EXPORT_SYMBOL(netdev_state_change);
+-EXPORT_SYMBOL(netdev_boot_setup_check);
+-EXPORT_SYMBOL(dev_new_index);
+-EXPORT_SYMBOL(dev_get_by_flags);
+-EXPORT_SYMBOL(__dev_get_by_flags);
+-EXPORT_SYMBOL(dev_get_by_index);
+-EXPORT_SYMBOL(__dev_get_by_index);
+-EXPORT_SYMBOL(dev_get_by_name);
+-EXPORT_SYMBOL(__dev_get_by_name);
+-EXPORT_SYMBOL(dev_getbyhwaddr);
+-EXPORT_SYMBOL(netdev_set_master);
+-EXPORT_SYMBOL(eth_type_trans);
+-#ifdef CONFIG_FDDI
+-EXPORT_SYMBOL(fddi_type_trans);
+-#endif /* CONFIG_FDDI */
+-#if 0
+-EXPORT_SYMBOL(eth_copy_and_sum);
+-#endif
+-EXPORT_SYMBOL(alloc_skb);
+-EXPORT_SYMBOL(__kfree_skb);
+-EXPORT_SYMBOL(skb_clone);
+-EXPORT_SYMBOL(skb_copy);
+-EXPORT_SYMBOL(skb_pad);
+-EXPORT_SYMBOL(netif_rx);
+-EXPORT_SYMBOL(netif_receive_skb);
+-EXPORT_SYMBOL(dev_add_pack);
+-EXPORT_SYMBOL(dev_remove_pack);
+-EXPORT_SYMBOL(__dev_remove_pack);
+-EXPORT_SYMBOL(__dev_get);
+-EXPORT_SYMBOL(dev_alloc);
+-EXPORT_SYMBOL(dev_alloc_name);
+-EXPORT_SYMBOL(__netdev_watchdog_up);
+-#ifdef CONFIG_KMOD
+-EXPORT_SYMBOL(dev_load);
+-#endif
+-EXPORT_SYMBOL(dev_ioctl);
+-EXPORT_SYMBOL(dev_queue_xmit);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-EXPORT_SYMBOL(netdev_dropping);
+-EXPORT_SYMBOL(netdev_register_fc);
+-EXPORT_SYMBOL(netdev_unregister_fc);
+-EXPORT_SYMBOL(netdev_fc_xoff);
+-#endif
+-EXPORT_SYMBOL(dev_base);
+-EXPORT_SYMBOL(dev_base_lock);
+-EXPORT_SYMBOL(dev_open);
+-EXPORT_SYMBOL(dev_close);
+-EXPORT_SYMBOL(dev_mc_add);
+-EXPORT_SYMBOL(dev_mc_delete);
+-EXPORT_SYMBOL(dev_mc_upload);
+-EXPORT_SYMBOL(dev_set_allmulti);
+-EXPORT_SYMBOL(dev_set_promiscuity);
+-EXPORT_SYMBOL(__kill_fasync);
+-
+-EXPORT_SYMBOL(rtnl);
+-EXPORT_SYMBOL(rtnetlink_links);
+-EXPORT_SYMBOL(rtnetlink_dump_ifinfo);
+-EXPORT_SYMBOL(rtnetlink_put_metrics);
+-EXPORT_SYMBOL(rtnl_sem);
+-EXPORT_SYMBOL(rtnl_lock);
+-EXPORT_SYMBOL(rtnl_unlock);
+-
+-#ifdef CONFIG_HIPPI
+-EXPORT_SYMBOL(hippi_type_trans);
+-#endif
+-
+-#ifdef CONFIG_NET_FASTROUTE
+-EXPORT_SYMBOL(netdev_fastroute);
+-#endif
+-
+-#ifdef CONFIG_SYSCTL
+-EXPORT_SYMBOL(sysctl_wmem_max);
+-EXPORT_SYMBOL(sysctl_rmem_max);
+-#ifdef CONFIG_INET
+-EXPORT_SYMBOL(sysctl_ip_default_ttl);
+-#endif
+-#endif
+-
+-/* Packet scheduler modules want these. */
+-EXPORT_SYMBOL(qdisc_destroy);
+-EXPORT_SYMBOL(qdisc_reset);
+-EXPORT_SYMBOL(qdisc_restart);
+-EXPORT_SYMBOL(qdisc_create_dflt);
+-EXPORT_SYMBOL(noop_qdisc);
+-EXPORT_SYMBOL(qdisc_tree_lock);
+-#ifdef CONFIG_NET_SCHED
+-PSCHED_EXPORTLIST;
+-EXPORT_SYMBOL(pfifo_qdisc_ops);
+-EXPORT_SYMBOL(bfifo_qdisc_ops);
+-EXPORT_SYMBOL(register_qdisc);
+-EXPORT_SYMBOL(unregister_qdisc);
+-EXPORT_SYMBOL(qdisc_get_rtab);
+-EXPORT_SYMBOL(qdisc_put_rtab);
+-EXPORT_SYMBOL(qdisc_copy_stats);
+-#ifdef CONFIG_NET_ESTIMATOR
+-EXPORT_SYMBOL(qdisc_new_estimator);
+-EXPORT_SYMBOL(qdisc_kill_estimator);
+-#endif
+-#ifdef CONFIG_NET_CLS_POLICE
+-EXPORT_SYMBOL(tcf_police);
+-EXPORT_SYMBOL(tcf_police_locate);
+-EXPORT_SYMBOL(tcf_police_destroy);
+-EXPORT_SYMBOL(tcf_police_dump);
+-#endif
+-#endif
+-#ifdef CONFIG_NET_CLS
+-EXPORT_SYMBOL(register_tcf_proto_ops);
+-EXPORT_SYMBOL(unregister_tcf_proto_ops);
+-#endif
+-#ifdef CONFIG_NETFILTER
+-#include <linux/netfilter.h>
+-EXPORT_SYMBOL(nf_register_hook);
+-EXPORT_SYMBOL(nf_unregister_hook);
+-EXPORT_SYMBOL(nf_register_sockopt);
+-EXPORT_SYMBOL(nf_unregister_sockopt);
+-EXPORT_SYMBOL(nf_reinject);
+-EXPORT_SYMBOL(nf_register_queue_handler);
+-EXPORT_SYMBOL(nf_unregister_queue_handler);
+-EXPORT_SYMBOL(nf_hook_slow);
+-EXPORT_SYMBOL(nf_hooks);
+-EXPORT_SYMBOL(nf_setsockopt);
+-EXPORT_SYMBOL(nf_getsockopt);
+-EXPORT_SYMBOL(ip_ct_attach);
+-#ifdef CONFIG_INET
+-#include <linux/netfilter_ipv4.h>
+-EXPORT_SYMBOL(ip_route_me_harder);
+-#endif
+-#endif
+-
+-EXPORT_SYMBOL(register_gifconf);
+-
+-EXPORT_PER_CPU_SYMBOL(softnet_data);
+-
+-#ifdef CONFIG_NET_RADIO
+-#include <net/iw_handler.h>		/* Wireless Extensions driver API */
+-EXPORT_SYMBOL(wireless_send_event);
+-EXPORT_SYMBOL(iw_handler_set_spy);
+-EXPORT_SYMBOL(iw_handler_get_spy);
+-EXPORT_SYMBOL(iw_handler_set_thrspy);
+-EXPORT_SYMBOL(iw_handler_get_thrspy);
+-EXPORT_SYMBOL(wireless_spy_update);
+-#endif	/* CONFIG_NET_RADIO */
+-
+-EXPORT_SYMBOL(linkwatch_fire_event);
+-
+-/* ethtool.c */
+-EXPORT_SYMBOL(ethtool_op_get_link);
+-EXPORT_SYMBOL(ethtool_op_get_tx_csum);
+-EXPORT_SYMBOL(ethtool_op_set_tx_csum);
+-EXPORT_SYMBOL(ethtool_op_get_sg);
+-EXPORT_SYMBOL(ethtool_op_set_sg);
+-EXPORT_SYMBOL(ethtool_op_get_tso);
+-EXPORT_SYMBOL(ethtool_op_set_tso);
+-
+-#endif  /* CONFIG_NET */
+--- linux-2.6.0-test6/net/sched/cls_api.c	2003-06-14 12:18:03.000000000 -0700
++++ 25/net/sched/cls_api.c	2003-10-05 00:33:25.000000000 -0700
+@@ -467,3 +467,6 @@ int __init tc_filter_init(void)
+ #endif
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(register_tcf_proto_ops);
++EXPORT_SYMBOL(unregister_tcf_proto_ops);
+--- linux-2.6.0-test6/net/sched/estimator.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/sched/estimator.c	2003-10-05 00:33:25.000000000 -0700
+@@ -12,6 +12,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/jiffies.h>
+@@ -194,3 +195,5 @@ void qdisc_kill_estimator(struct tc_stat
+ 	}
+ }
+ 
++EXPORT_SYMBOL(qdisc_kill_estimator);
++EXPORT_SYMBOL(qdisc_new_estimator);
+--- linux-2.6.0-test6/net/sched/police.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/sched/police.c	2003-10-05 00:33:25.000000000 -0700
+@@ -13,6 +13,7 @@
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+@@ -248,3 +249,12 @@ rtattr_failure:
+ 	skb_trim(skb, b - skb->data);
+ 	return -1;
+ }
++
++EXPORT_SYMBOL(tcf_police);
++EXPORT_SYMBOL(tcf_police_destroy);
++EXPORT_SYMBOL(tcf_police_dump);
++EXPORT_SYMBOL(tcf_police_hash);
++EXPORT_SYMBOL(tcf_police_ht);
++EXPORT_SYMBOL(tcf_police_locate);
++EXPORT_SYMBOL(tcf_police_lookup);
++EXPORT_SYMBOL(tcf_police_new_index);
+--- linux-2.6.0-test6/net/sched/sch_api.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/sched/sch_api.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1255,3 +1255,10 @@ int __init pktsched_init(void)
+ 
+ 	return 0;
+ }
++
++EXPORT_SYMBOL(qdisc_copy_stats);
++EXPORT_SYMBOL(qdisc_get_rtab);
++EXPORT_SYMBOL(qdisc_put_rtab);
++EXPORT_SYMBOL(register_qdisc);
++EXPORT_SYMBOL(unregister_qdisc);
++PSCHED_EXPORTLIST;
+--- linux-2.6.0-test6/net/sched/sch_fifo.c	2003-07-10 18:50:32.000000000 -0700
++++ 25/net/sched/sch_fifo.c	2003-10-05 00:33:25.000000000 -0700
+@@ -203,3 +203,6 @@ struct Qdisc_ops bfifo_qdisc_ops = {
+ 	.dump		=	fifo_dump,
+ 	.owner		=	THIS_MODULE,
+ };
++
++EXPORT_SYMBOL(bfifo_qdisc_ops);
++EXPORT_SYMBOL(pfifo_qdisc_ops);
+--- linux-2.6.0-test6/net/sched/sch_generic.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/net/sched/sch_generic.c	2003-10-05 00:33:25.000000000 -0700
+@@ -531,3 +531,12 @@ void dev_shutdown(struct net_device *dev
+ 	spin_unlock_bh(&dev->queue_lock);
+ 	write_unlock(&qdisc_tree_lock);
+ }
++
++EXPORT_SYMBOL(__netdev_watchdog_up);
++EXPORT_SYMBOL(noop_qdisc);
++EXPORT_SYMBOL(noop_qdisc_ops);
++EXPORT_SYMBOL(qdisc_create_dflt);
++EXPORT_SYMBOL(qdisc_destroy);
++EXPORT_SYMBOL(qdisc_reset);
++EXPORT_SYMBOL(qdisc_restart);
++EXPORT_SYMBOL(qdisc_tree_lock);
+--- linux-2.6.0-test6/net/sctp/associola.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/associola.c	2003-10-05 00:33:25.000000000 -0700
+@@ -141,9 +141,9 @@ struct sctp_association *sctp_associatio
+ 	 * socket values.
+ 	 */
+ 	asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
+-	asoc->rto_initial = sp->rtoinfo.srto_initial * HZ / 1000;
+-	asoc->rto_max = sp->rtoinfo.srto_max * HZ / 1000;
+-	asoc->rto_min = sp->rtoinfo.srto_min * HZ / 1000;
++	asoc->rto_initial = MSECS_TO_JIFFIES(sp->rtoinfo.srto_initial);
++	asoc->rto_max = MSECS_TO_JIFFIES(sp->rtoinfo.srto_max);
++	asoc->rto_min = MSECS_TO_JIFFIES(sp->rtoinfo.srto_min);
+ 
+ 	asoc->overall_error_count = 0;
+ 
+@@ -168,7 +168,8 @@ struct sctp_association *sctp_associatio
+ 	asoc->c.sinit_num_ostreams  = sp->initmsg.sinit_num_ostreams;
+ 	asoc->max_init_attempts	= sp->initmsg.sinit_max_attempts;
+ 
+-	asoc->max_init_timeo    = sp->initmsg.sinit_max_init_timeo * HZ / 1000;
++	asoc->max_init_timeo =
++		 MSECS_TO_JIFFIES(sp->initmsg.sinit_max_init_timeo);
+ 
+ 	/* Allocate storage for the ssnmap after the inbound and outbound
+ 	 * streams have been negotiated during Init.
+@@ -246,6 +247,11 @@ struct sctp_association *sctp_associatio
+ 	 */
+ 	asoc->peer.sack_needed = 1;
+ 
++	/* Assume that the peer recongizes ASCONF until reported otherwise
++	 * via an ERROR chunk.
++	 */
++	asoc->peer.asconf_capable = 1;
++
+ 	/* Create an input queue.  */
+ 	sctp_inq_init(&asoc->base.inqueue);
+ 	sctp_inq_set_th_handler(&asoc->base.inqueue,
+@@ -495,7 +501,7 @@ struct sctp_transport *sctp_assoc_add_pe
+ 	/* Initialize the peer's heartbeat interval based on the
+ 	 * sock configured value.
+ 	 */
+-	peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ;
++	peer->hb_interval = MSECS_TO_JIFFIES(sp->paddrparam.spp_hbinterval);
+ 
+ 	/* Set the path max_retrans.  */
+ 	peer->max_retrans = asoc->max_retrans;
+--- linux-2.6.0-test6/net/sctp/bind_addr.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/bind_addr.c	2003-10-05 00:33:25.000000000 -0700
+@@ -324,6 +324,43 @@ int sctp_bind_addr_match(struct sctp_bin
+ 	return 0;
+ }
+ 
++/* Find the first address in the bind address list that is not present in
++ * the addrs packed array.
++ */
++union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
++					const union sctp_addr	*addrs,
++					int			addrcnt,
++					struct sctp_opt		*opt)
++{
++	struct sctp_sockaddr_entry	*laddr;
++	union sctp_addr			*addr;
++	void 				*addr_buf;
++	struct sctp_af			*af;
++	struct list_head		*pos;
++	int				i;
++
++	list_for_each(pos, &bp->address_list) {
++		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
++		
++		addr_buf = (union sctp_addr *)addrs;
++		for (i = 0; i < addrcnt; i++) {
++			addr = (union sctp_addr *)addr_buf;
++			af = sctp_get_af_specific(addr->v4.sin_family);
++			if (!af) 
++				return NULL;
++
++			if (opt->pf->cmp_addr(&laddr->a, addr, opt))
++				break;
++
++			addr_buf += af->sockaddr_len;
++		}
++		if (i == addrcnt)
++			return &laddr->a;
++	}
++
++	return NULL;
++}
++
+ /* Copy out addresses from the global local address list. */
+ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, 
+ 			      union sctp_addr *addr,
+--- linux-2.6.0-test6/net/sctp/endpointola.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/net/sctp/endpointola.c	2003-10-05 00:33:25.000000000 -0700
+@@ -129,7 +129,7 @@ struct sctp_endpoint *sctp_endpoint_init
+ 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
+ 		SCTP_DEFAULT_TIMEOUT_T1_INIT;
+ 	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
+-		sp->rtoinfo.srto_initial * HZ / 1000;
++		MSECS_TO_JIFFIES(sp->rtoinfo.srto_initial);
+ 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
+ 	ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0;
+ 
+@@ -138,7 +138,7 @@ struct sctp_endpoint *sctp_endpoint_init
+ 	 * recommended value of 5 times 'RTO.Max'.
+ 	 */
+         ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
+-		= 5 * (sp->rtoinfo.srto_max * HZ / 1000);
++		= 5 * MSECS_TO_JIFFIES(sp->rtoinfo.srto_max);
+ 
+ 	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
+ 		SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+--- linux-2.6.0-test6/net/sctp/sm_make_chunk.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/sm_make_chunk.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,5 +1,5 @@
+ /* SCTP kernel reference Implementation
+- * Copyright (C) IBM Corp. 2001, 2003
++ * (C) Copyright IBM Corp. 2001, 2003
+  * Copyright (c) 1999-2000 Cisco, Inc.
+  * Copyright (c) 1999-2001 Motorola, Inc.
+  * Copyright (c) 2001-2002 Intel Corp.
+@@ -1288,7 +1288,7 @@ sctp_cookie_param_t *sctp_pack_cookie(co
+ 
+ 	/* Set an expiration time for the cookie.  */
+ 	do_gettimeofday(&cookie->c.expiration);
+-	tv_add(&asoc->cookie_life, &cookie->c.expiration);
++	TIMEVAL_ADD(asoc->cookie_life, cookie->c.expiration);
+ 
+ 	/* Copy the peer's init packet.  */
+ 	memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
+@@ -2021,11 +2021,11 @@ struct sctp_chunk *sctp_make_asconf(stru
+ 	sctp_addiphdr_t asconf;
+ 	struct sctp_chunk *retval;
+ 	int length = sizeof(asconf) + vparam_len;
+-	union sctp_params addrparam;
++	union sctp_addr_param addrparam;
+ 	int addrlen;
+ 	struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
+ 
+-	addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
++	addrlen = af->to_addr_param(addr, &addrparam);
+ 	if (!addrlen)
+ 		return NULL;
+ 	length += addrlen;
+@@ -2046,6 +2046,83 @@ struct sctp_chunk *sctp_make_asconf(stru
+ }
+ 
+ /* ADDIP
++ * 3.2.1 Add IP Address
++ * 	0                   1                   2                   3
++ * 	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |        Type = 0xC001          |    Length = Variable          |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |               ASCONF-Request Correlation ID                   |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |                       Address Parameter                       |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *
++ * 3.2.2 Delete IP Address
++ * 	0                   1                   2                   3
++ * 	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |        Type = 0xC002          |    Length = Variable          |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |               ASCONF-Request Correlation ID                   |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *     |                       Address Parameter                       |
++ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++ *
++ */
++struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
++					      union sctp_addr	      *laddr,
++					      struct sockaddr	      *addrs,
++					      int		      addrcnt,
++					      int		      flags)
++{
++	sctp_addip_param_t	param;
++	struct sctp_chunk	*retval;
++	union sctp_addr_param	addr_param;
++	union sctp_addr		*addr;
++	void			*addr_buf;
++	struct sctp_af		*af;
++	int			paramlen = sizeof(param);
++	int			addr_param_len = 0;
++	int 			totallen = 0;
++	int 			i;
++
++	/* Get total length of all the address parameters. */
++	addr_buf = addrs;
++	for (i = 0; i < addrcnt; i++) {
++		addr = (union sctp_addr *)addr_buf;
++		af = sctp_get_af_specific(addr->v4.sin_family);
++		addr_param_len = af->to_addr_param(addr, &addr_param);
++
++		totallen += paramlen;
++		totallen += addr_param_len;
++
++		addr_buf += af->sockaddr_len;
++	}
++
++	/* Create an asconf chunk with the required length. */
++	retval = sctp_make_asconf(asoc, laddr, totallen);
++	if (!retval)
++		return NULL;
++
++	/* Add the address parameters to the asconf chunk. */
++	addr_buf = addrs;
++	for (i = 0; i < addrcnt; i++) {
++		addr = (union sctp_addr *)addr_buf;
++		af = sctp_get_af_specific(addr->v4.sin_family);
++		addr_param_len = af->to_addr_param(addr, &addr_param);
++		param.param_hdr.type = flags;
++		param.param_hdr.length = htons(paramlen + addr_param_len);
++		param.crr_id = htonl(i);
++
++		sctp_addto_chunk(retval, paramlen, &param);
++		sctp_addto_chunk(retval, addr_param_len, &addr_param);
++
++		addr_buf += af->sockaddr_len;
++	}
++	return retval;
++}
++
++/* ADDIP
+  * 3.2.4 Set Primary IP Address
+  *	0                   1                   2                   3
+  *	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+@@ -2065,11 +2142,11 @@ struct sctp_chunk *sctp_make_asconf_set_
+ 	sctp_addip_param_t	param;
+ 	struct sctp_chunk 	*retval;
+ 	int 			len = sizeof(param);
+-	union sctp_params	addrparam;
++	union sctp_addr_param	addrparam;
+ 	int			addrlen;
+ 	struct sctp_af		*af = sctp_get_af_specific(addr->v4.sin_family);
+ 
+-	addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
++	addrlen = af->to_addr_param(addr, &addrparam);
+ 	if (!addrlen)
+ 		return NULL;
+ 	len += addrlen;
+@@ -2089,11 +2166,7 @@ struct sctp_chunk *sctp_make_asconf_set_
+ 	return retval;
+ }
+ 
+-/*
+- * Unpack the parameters in an ASCONF chunk into an association and
+- * generate ASCONF-ACK chunk.
+- *
+- * ADDIP 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
++/* ADDIP 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
+  *      0                   1                   2                   3
+  *      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+@@ -2110,8 +2183,28 @@ struct sctp_chunk *sctp_make_asconf_set_
+  *     |                 ASCONF Parameter Response#N                   |
+  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  *
+- * All the parameter respoinces will be added in this function.
++ * Create an ASCONF_ACK chunk with enough space for the parameter responses. 
+  */
++struct sctp_chunk *sctp_make_asconf_ack(struct sctp_association	*asoc,
++					int serial, int vparam_len)
++{
++	sctp_addiphdr_t		asconf;
++	struct sctp_chunk	*retval;
++	int			length = sizeof(asconf) + vparam_len;
++
++	/* Create the chunk.  */
++	retval = sctp_make_chunk(asoc, SCTP_CID_ASCONF_ACK, 0, length);
++	if (!retval)
++		return NULL;
++
++	asconf.serial = serial;
++
++	retval->subh.addip_hdr =
++		sctp_addto_chunk(retval, sizeof(asconf), &asconf);
++
++	return retval;
++}
++
+ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
+ 					struct sctp_chunk *asconf,
+ 					int vparam_len)
+--- linux-2.6.0-test6/net/sctp/sm_sideeffect.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/net/sctp/sm_sideeffect.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,7 +1,7 @@
+ /* SCTP kernel reference Implementation
++ * (C) Copyright IBM Corp. 2001, 2003
+  * Copyright (c) 1999 Cisco, Inc.
+  * Copyright (c) 1999-2001 Motorola, Inc.
+- * Copyright (c) 2001-2002 International Business Machines Corp.
+  *
+  * This file is part of the SCTP kernel reference Implementation
+  *
+@@ -690,6 +690,44 @@ static void sctp_cmd_setup_t4(sctp_cmd_s
+ 	chunk->transport = t;
+ }
+ 
++/* Process an incoming Operation Error Chunk. */ 
++static void sctp_cmd_process_operr(sctp_cmd_seq_t *cmds,
++				   struct sctp_association *asoc,
++				   struct sctp_chunk *chunk)
++{
++	struct sctp_operr_chunk *operr_chunk;
++	struct sctp_errhdr *err_hdr;
++
++	operr_chunk = (struct sctp_operr_chunk *)chunk->chunk_hdr;
++	err_hdr = &operr_chunk->err_hdr;
++
++	switch (err_hdr->cause) {
++	case SCTP_ERROR_UNKNOWN_CHUNK:
++	{
++		struct sctp_chunkhdr *unk_chunk_hdr;
++
++		unk_chunk_hdr = (struct sctp_chunkhdr *)err_hdr->variable;
++		switch (unk_chunk_hdr->type) {
++		/* ADDIP 4.1 A9) If the peer responds to an ASCONF with an
++		 * ERROR chunk reporting that it did not recognized the ASCONF
++		 * chunk type, the sender of the ASCONF MUST NOT send any
++		 * further ASCONF chunks and MUST stop its T-4 timer.
++		 */
++		case SCTP_CID_ASCONF:
++			asoc->peer.asconf_capable = 0;
++			sctp_add_cmd_sf(cmds, SCTP_CMD_TIMER_STOP,
++					SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
++			break;
++		default:
++			break;
++		}
++		break;
++	}
++	default:
++		break;
++	}
++}
++
+ /* These three macros allow us to pull the debugging code out of the
+  * main flow of sctp_do_sm() to keep attention focused on the real
+  * functionality there.
+@@ -1205,6 +1243,9 @@ int sctp_cmd_interpreter(sctp_event_t ev
+ 			sctp_cmd_setup_t4(commands, asoc, cmd->obj.ptr);
+ 			break;
+ 
++		case SCTP_CMD_PROCESS_OPERR:
++			sctp_cmd_process_operr(commands, asoc, chunk);
++			break;
+ 		default:
+ 			printk(KERN_WARNING "Impossible command: %u, %p\n",
+ 			       cmd->verb, cmd->obj.ptr);
+--- linux-2.6.0-test6/net/sctp/sm_statefuns.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/sm_statefuns.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,7 +1,7 @@
+ /* SCTP kernel reference Implementation
++ * (C) Copyright IBM Corp. 2001, 2003
+  * Copyright (c) 1999-2000 Cisco, Inc.
+  * Copyright (c) 1999-2001 Motorola, Inc.
+- * Copyright (c) 2001-2002 International Business Machines, Corp.
+  * Copyright (c) 2001-2002 Intel Corp.
+  * Copyright (c) 2002      Nokia Corp.
+  *
+@@ -2864,6 +2864,9 @@ sctp_disposition_t sctp_sf_operr_notify(
+ 			sctp_ulpevent_free(ev);
+ 			goto nomem;
+ 		}
++
++		sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
++				SCTP_CHUNK(chunk));	
+ 	}
+ 	return SCTP_DISPOSITION_CONSUME;
+ 
+--- linux-2.6.0-test6/net/sctp/socket.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/socket.c	2003-10-05 00:33:25.000000000 -0700
+@@ -97,6 +97,8 @@ static void sctp_wait_for_close(struct s
+ static inline int sctp_verify_addr(struct sock *, union sctp_addr *, int);
+ static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
+ static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
++static int sctp_send_asconf_add_ip(struct sock *, struct sockaddr *, int);
++static int sctp_send_asconf_del_ip(struct sock *, struct sockaddr *, int);
+ static int sctp_do_bind(struct sock *, union sctp_addr *, int);
+ static int sctp_autobind(struct sock *sk);
+ static void sctp_sock_migrate(struct sock *, struct sock *,
+@@ -349,6 +351,106 @@ err_bindx_add:
+ 	return retval;
+ }
+ 
++/* Send an ASCONF chunk with Add IP address parameters to all the peers of the
++ * associations that are part of the endpoint indicating that a list of local
++ * addresses are added to the endpoint.
++ *
++ * If any of the addresses is already in the bind address list of the 
++ * association, we do not send the chunk for that association.  But it will not
++ * affect other associations.
++ *
++ * Only sctp_setsockopt_bindx() is supposed to call this function.
++ */
++static int sctp_send_asconf_add_ip(struct sock		*sk, 
++				   struct sockaddr	*addrs,
++				   int 			addrcnt)
++{
++	struct sctp_opt			*sp;
++	struct sctp_endpoint		*ep;
++	struct sctp_association		*asoc;
++	struct sctp_bind_addr		*bp;
++	struct sctp_chunk		*chunk;
++	struct sctp_sockaddr_entry	*laddr;
++	union sctp_addr			*addr;
++	void				*addr_buf;
++	struct sctp_af			*af;
++	struct list_head		*pos;
++	struct list_head		*p;
++	int 				i;
++	int 				retval = 0;
++
++	sp = sctp_sk(sk);
++	ep = sp->ep;
++
++	SCTP_DEBUG_PRINTK("%s: (sk: %p, addrs: %p, addrcnt: %d)\n",
++			  __FUNCTION__, sk, addrs, addrcnt);
++
++	list_for_each(pos, &ep->asocs) {
++		asoc = list_entry(pos, struct sctp_association, asocs);
++
++		if (!sctp_state(asoc, ESTABLISHED))
++			continue;
++
++		if (!asoc->peer.asconf_capable)
++			continue;
++		
++		/* Check if any address in the packed array of addresses is
++	         * in the bind address list of the association. If so, 
++		 * do not send the asconf chunk to its peer, but continue with 
++		 * other associations.
++		 */
++		addr_buf = addrs;
++		for (i = 0; i < addrcnt; i++) {
++			addr = (union sctp_addr *)addr_buf;
++			af = sctp_get_af_specific(addr->v4.sin_family);
++			if (!af) {
++				retval = -EINVAL;
++				goto out;
++			}
++
++			if (sctp_assoc_lookup_laddr(asoc, addr))		
++				break;
++			
++			addr_buf += af->sockaddr_len;
++		}
++		if (i < addrcnt)
++			continue;
++
++		/* Use the first address in bind addr list of association as
++		 * Address Parameter of ASCONF CHUNK.
++		 */
++		sctp_read_lock(&asoc->base.addr_lock);
++		bp = &asoc->base.bind_addr;
++		p = bp->address_list.next;
++		laddr = list_entry(p, struct sctp_sockaddr_entry, list);
++		sctp_read_unlock(&asoc->base.addr_lock);
++
++		chunk = sctp_make_asconf_update_ip(asoc, &laddr->a, addrs,
++						   addrcnt, SCTP_PARAM_ADD_IP);
++		if (!chunk) {
++			retval = -ENOMEM;
++			goto out;
++		}
++
++		retval = sctp_primitive_ASCONF(asoc, chunk);
++		if (retval) {
++			sctp_chunk_free(chunk);
++			goto out;
++		}
++
++		/* FIXME: After sending the add address ASCONF chunk, we 
++		 * cannot append the address to the association's binding 
++		 * address list, because the new address may be used as the
++		 * source of a message sent to the peer before the ASCONF
++		 * chunk is received by the peer.  So we should wait until
++		 * ASCONF_ACK is received.
++		 */
++	}
++
++out:
++	return retval;
++}
++
+ /* Remove a list of addresses from bind addresses list.  Do not remove the
+  * last address.
+  *
+@@ -436,6 +538,106 @@ err_bindx_rem:
+ 	return retval;
+ }
+ 
++/* Send an ASCONF chunk with Delete IP address parameters to all the peers of
++ * the associations that are part of the endpoint indicating that a list of
++ * local addresses are removed from the endpoint.
++ *
++ * If any of the addresses is already in the bind address list of the 
++ * association, we do not send the chunk for that association.  But it will not
++ * affect other associations.
++ *
++ * Only sctp_setsockopt_bindx() is supposed to call this function.
++ */
++static int sctp_send_asconf_del_ip(struct sock		*sk,
++				   struct sockaddr	*addrs,
++				   int			addrcnt)
++{
++	struct sctp_opt		*sp;
++	struct sctp_endpoint	*ep;
++	struct sctp_association	*asoc;
++	struct sctp_bind_addr	*bp;
++	struct sctp_chunk	*chunk;
++	union sctp_addr		*laddr;
++	void			*addr_buf;
++	struct sctp_af		*af;
++	struct list_head	*pos;
++	int 			i;
++	int 			retval = 0;
++
++	sp = sctp_sk(sk);
++	ep = sp->ep;
++
++	SCTP_DEBUG_PRINTK("%s: (sk: %p, addrs: %p, addrcnt: %d)\n",
++			  __FUNCTION__, sk, addrs, addrcnt);
++
++	list_for_each(pos, &ep->asocs) {
++		asoc = list_entry(pos, struct sctp_association, asocs);
++
++		if (!sctp_state(asoc, ESTABLISHED))
++			continue;
++
++		if (!asoc->peer.asconf_capable)
++			continue;
++
++		/* Check if any address in the packed array of addresses is
++	         * not present in the bind address list of the association.
++		 * If so, do not send the asconf chunk to its peer, but
++		 * continue with other associations.
++		 */
++		addr_buf = addrs;
++		for (i = 0; i < addrcnt; i++) {
++			laddr = (union sctp_addr *)addr_buf;
++			af = sctp_get_af_specific(laddr->v4.sin_family);
++			if (!af) {
++				retval = -EINVAL;
++				goto out;
++			}
++
++			if (!sctp_assoc_lookup_laddr(asoc, laddr))		
++				break;
++			
++			addr_buf += af->sockaddr_len;
++		}
++		if (i < addrcnt)
++			continue;
++
++		/* Find one address in the association's bind address list
++		 * that is not in the packed array of addresses. This is to
++		 * make sure that we do not delete all the addresses in the
++		 * association.
++		 */
++		sctp_read_lock(&asoc->base.addr_lock);
++		bp = &asoc->base.bind_addr;
++		laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs,
++					       addrcnt, sp);
++		sctp_read_unlock(&asoc->base.addr_lock);		
++		if (!laddr)
++			continue;
++
++		chunk = sctp_make_asconf_update_ip(asoc, laddr, addrs, addrcnt, 
++						   SCTP_PARAM_DEL_IP);
++		if (!chunk) {
++			retval = -ENOMEM;
++			goto out;
++		}
++
++		retval = sctp_primitive_ASCONF(asoc, chunk);
++		if (retval) {
++			sctp_chunk_free(chunk);
++			goto out;
++		}
++
++		/* FIXME: After sending the delete address ASCONF chunk, we
++		 * cannot remove the addresses from the association's bind
++		 * address list, because there maybe some packet send to
++		 * the delete addresses, so we should wait until ASCONF_ACK 
++		 * packet is received.
++		 */
++	}
++out:
++	return retval;
++}
++
+ /* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
+  *
+  * API 8.1
+@@ -564,10 +766,16 @@ SCTP_STATIC int sctp_setsockopt_bindx(st
+ 	switch (op) {
+ 	case SCTP_BINDX_ADD_ADDR:
+ 		err = sctp_bindx_add(sk, kaddrs, addrcnt);
++		if (err)
++			goto out;
++		err = sctp_send_asconf_add_ip(sk, kaddrs, addrcnt);
+ 		break;
+ 
+ 	case SCTP_BINDX_REM_ADDR:
+ 		err = sctp_bindx_rem(sk, kaddrs, addrcnt);
++		if (err)
++			goto out;
++		err = sctp_send_asconf_del_ip(sk, kaddrs, addrcnt);
+ 		break;
+ 
+ 	default:
+@@ -575,6 +783,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(st
+ 		break;
+         };
+ 
++out:
+ 	kfree(kaddrs);
+ 
+ 	return err;
+@@ -962,8 +1171,8 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+ 					= sinit->sinit_max_attempts;
+ 			}
+ 			if (sinit->sinit_max_init_timeo) {
+-				asoc->max_init_timeo
+-					= sinit->sinit_max_init_timeo * HZ;
++				asoc->max_init_timeo = 
++				 MSECS_TO_JIFFIES(sinit->sinit_max_init_timeo);
+ 			}
+ 		}
+ 
+@@ -1401,7 +1610,8 @@ static int sctp_setsockopt_peer_addr_par
+ 	 */
+ 		if (params.spp_hbinterval) {
+ 			trans->hb_allowed = 1;
+-			trans->hb_interval = params.spp_hbinterval * HZ / 1000;
++			trans->hb_interval = 
++				MSECS_TO_JIFFIES(params.spp_hbinterval);
+ 		} else
+ 			trans->hb_allowed = 0;
+ 	}
+@@ -1560,11 +1770,12 @@ static int sctp_setsockopt_rtoinfo(struc
+ 
+ 	if (asoc) {
+ 		if (rtoinfo.srto_initial != 0)
+-			asoc->rto_initial = rtoinfo.srto_initial * HZ / 1000;
++			asoc->rto_initial = 
++				MSECS_TO_JIFFIES(rtoinfo.srto_initial);
+ 		if (rtoinfo.srto_max != 0)
+-			asoc->rto_max = rtoinfo.srto_max * HZ / 1000;
++			asoc->rto_max = MSECS_TO_JIFFIES(rtoinfo.srto_max);
+ 		if (rtoinfo.srto_min != 0)
+-			asoc->rto_min = rtoinfo.srto_min * HZ / 1000;
++			asoc->rto_min = MSECS_TO_JIFFIES(rtoinfo.srto_min);
+ 	} else {
+ 		/* If there is no association or the association-id = 0
+ 		 * set the values to the endpoint.
+@@ -2088,14 +2299,14 @@ SCTP_STATIC int sctp_init_sock(struct so
+ 	sp->initmsg.sinit_num_ostreams   = sctp_max_outstreams;
+ 	sp->initmsg.sinit_max_instreams  = sctp_max_instreams;
+ 	sp->initmsg.sinit_max_attempts   = sctp_max_retrans_init;
+-	sp->initmsg.sinit_max_init_timeo = (sctp_rto_max / HZ) * 1000;
++	sp->initmsg.sinit_max_init_timeo = JIFFIES_TO_MSECS(sctp_rto_max);
+ 
+ 	/* Initialize default RTO related parameters.  These parameters can
+ 	 * be modified for with the SCTP_RTOINFO socket option.
+ 	 */
+-	sp->rtoinfo.srto_initial = (sctp_rto_initial / HZ) * 1000;
+-	sp->rtoinfo.srto_max     = (sctp_rto_max / HZ) * 1000;
+-	sp->rtoinfo.srto_min     = (sctp_rto_min / HZ) * 1000;
++	sp->rtoinfo.srto_initial = JIFFIES_TO_MSECS(sctp_rto_initial);
++	sp->rtoinfo.srto_max     = JIFFIES_TO_MSECS(sctp_rto_max);
++	sp->rtoinfo.srto_min     = JIFFIES_TO_MSECS(sctp_rto_min);
+ 
+ 	/* Initialize default association related parameters. These parameters
+ 	 * can be modified with the SCTP_ASSOCINFO socket option.
+@@ -2104,8 +2315,8 @@ SCTP_STATIC int sctp_init_sock(struct so
+ 	sp->assocparams.sasoc_number_peer_destinations = 0;
+ 	sp->assocparams.sasoc_peer_rwnd = 0;
+ 	sp->assocparams.sasoc_local_rwnd = 0;
+-	sp->assocparams.sasoc_cookie_life = (sctp_valid_cookie_life / HZ)
+-					* 1000;
++	sp->assocparams.sasoc_cookie_life = 
++		JIFFIES_TO_MSECS(sctp_valid_cookie_life);
+ 
+ 	/* Initialize default event subscriptions. By default, all the
+ 	 * options are off. 
+@@ -2115,7 +2326,7 @@ SCTP_STATIC int sctp_init_sock(struct so
+ 	/* Default Peer Address Parameters.  These defaults can
+ 	 * be modified via SCTP_PEER_ADDR_PARAMS
+ 	 */
+-	sp->paddrparam.spp_hbinterval = (sctp_hb_interval / HZ) * 1000;
++	sp->paddrparam.spp_hbinterval = JIFFIES_TO_MSECS(sctp_hb_interval);
+ 	sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path;
+ 
+ 	/* If enabled no SCTP message fragmentation will be performed.
+@@ -2265,7 +2476,7 @@ static int sctp_getsockopt_sctp_status(s
+ 	status.sstat_primary.spinfo_state = transport->active;
+ 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
+ 	status.sstat_primary.spinfo_srtt = transport->srtt;
+-	status.sstat_primary.spinfo_rto = (transport->rto / HZ) * 1000;
++	status.sstat_primary.spinfo_rto = JIFFIES_TO_MSECS(transport->rto);
+ 	status.sstat_primary.spinfo_mtu = transport->pmtu;
+ 
+ 	if (put_user(len, optlen)) {
+@@ -2320,7 +2531,7 @@ static int sctp_getsockopt_peer_addr_inf
+ 	pinfo.spinfo_state = transport->active;
+ 	pinfo.spinfo_cwnd = transport->cwnd;
+ 	pinfo.spinfo_srtt = transport->srtt;
+-	pinfo.spinfo_rto = (transport->rto / HZ) * 1000;
++	pinfo.spinfo_rto = JIFFIES_TO_MSECS(transport->rto);
+ 	pinfo.spinfo_mtu = transport->pmtu;
+ 
+ 	if (put_user(len, optlen)) {
+@@ -2524,7 +2735,7 @@ static int sctp_getsockopt_peer_addr_par
+ 	if (!trans->hb_allowed)
+ 		params.spp_hbinterval = 0;
+ 	else
+-		params.spp_hbinterval = trans->hb_interval * 1000 / HZ;
++		params.spp_hbinterval = JIFFIES_TO_MSECS(trans->hb_interval);
+ 
+ 	/* spp_pathmaxrxt contains the maximum number of retransmissions
+ 	 * before this address shall be considered unreachable.
+@@ -2582,10 +2793,8 @@ static int sctp_getsockopt_peer_addrs_nu
+ 	list_for_each(pos, &asoc->peer.transport_addr_list) {
+ 		cnt ++;
+ 	}
+-	if (copy_to_user(optval, &cnt, sizeof(int)))
+-		return -EFAULT;
+ 
+-	return 0;
++	return cnt;
+ }
+ 
+ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+@@ -2666,10 +2875,8 @@ static int sctp_getsockopt_local_addrs_n
+ 	list_for_each(pos, &bp->address_list) {
+ 		cnt ++;
+ 	}
+-	if (copy_to_user(optval, &cnt, sizeof(int)))
+-		return -EFAULT;
+ 
+-	return 0;
++	return cnt;
+ }
+ 
+ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+@@ -2879,9 +3086,9 @@ static int sctp_getsockopt_rtoinfo(struc
+ 
+ 	/* Values corresponding to the specific association. */
+ 	if (asoc) {
+-		rtoinfo.srto_initial = (asoc->rto_initial / HZ) * 1000;
+-		rtoinfo.srto_max = (asoc->rto_max / HZ) * 1000;
+-		rtoinfo.srto_min = (asoc->rto_min / HZ) * 1000;
++		rtoinfo.srto_initial = JIFFIES_TO_MSECS(asoc->rto_initial);
++		rtoinfo.srto_max = JIFFIES_TO_MSECS(asoc->rto_max);
++		rtoinfo.srto_min = JIFFIES_TO_MSECS(asoc->rto_min);
+ 	} else {
+ 		/* Values corresponding to the endpoint. */
+ 		struct sctp_opt *sp = sctp_sk(sk);
+--- linux-2.6.0-test6/net/sctp/sysctl.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/sctp/sysctl.c	2003-10-05 00:33:25.000000000 -0700
+@@ -44,7 +44,7 @@
+ #include <linux/sysctl.h>
+ 
+ static ctl_handler sctp_sysctl_jiffies_ms;
+-static long rto_timer_min = 0;
++static long rto_timer_min = 1;
+ static long rto_timer_max = 86400000; /* One day */
+ 
+ static ctl_table sctp_table[] = {
+--- linux-2.6.0-test6/net/socket.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/socket.c	2003-10-05 00:34:03.000000000 -0700
+@@ -394,6 +394,7 @@ int sock_map_fd(struct socket *sock)
+ 		file->f_dentry->d_op = &sockfs_dentry_operations;
+ 		d_add(file->f_dentry, SOCK_INODE(sock));
+ 		file->f_vfsmnt = mntget(sock_mnt);
++		file->f_mapping = file->f_dentry->d_inode->i_mapping;
+ 
+ 		sock->file = file;
+ 		file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
+@@ -1989,3 +1990,18 @@ void socket_seq_show(struct seq_file *se
+ 	seq_printf(seq, "sockets: used %d\n", counter);
+ }
+ #endif /* CONFIG_PROC_FS */
++
++/* ABI emulation layers need these two */
++EXPORT_SYMBOL(move_addr_to_kernel);
++EXPORT_SYMBOL(move_addr_to_user);
++EXPORT_SYMBOL(sock_alloc);
++EXPORT_SYMBOL(sock_alloc_inode);
++EXPORT_SYMBOL(sock_create);
++EXPORT_SYMBOL(sock_map_fd);
++EXPORT_SYMBOL(sock_recvmsg);
++EXPORT_SYMBOL(sock_register);
++EXPORT_SYMBOL(sock_release);
++EXPORT_SYMBOL(sock_sendmsg);
++EXPORT_SYMBOL(sock_unregister);
++EXPORT_SYMBOL(sock_wake_async);
++EXPORT_SYMBOL(sockfd_lookup);
+--- linux-2.6.0-test6/net/unix/af_unix.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/unix/af_unix.c	2003-10-05 00:33:25.000000000 -0700
+@@ -448,7 +448,7 @@ static int unix_listen(struct socket *so
+ 	sk->sk_max_ack_backlog	= backlog;
+ 	sk->sk_state		= TCP_LISTEN;
+ 	/* set credentials so connect can copy them */
+-	sk->sk_peercred.pid	= current->pid;
++	sk->sk_peercred.pid	= current->tgid;
+ 	sk->sk_peercred.uid	= current->euid;
+ 	sk->sk_peercred.gid	= current->egid;
+ 	err = 0;
+@@ -983,7 +983,7 @@ restart:
+ 	unix_peer(newsk)	= sk;
+ 	newsk->sk_state		= TCP_ESTABLISHED;
+ 	newsk->sk_type		= SOCK_STREAM;
+-	newsk->sk_peercred.pid	= current->pid;
++	newsk->sk_peercred.pid	= current->tgid;
+ 	newsk->sk_peercred.uid	= current->euid;
+ 	newsk->sk_peercred.gid	= current->egid;
+ 	newu = unix_sk(newsk);
+@@ -1045,7 +1045,7 @@ static int unix_socketpair(struct socket
+ 	sock_hold(skb);
+ 	unix_peer(ska)=skb;
+ 	unix_peer(skb)=ska;
+-	ska->sk_peercred.pid = skb->sk_peercred.pid = current->pid;
++	ska->sk_peercred.pid = skb->sk_peercred.pid = current->tgid;
+ 	ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
+ 	ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
+ 
+--- linux-2.6.0-test6/net/x25/af_x25.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/net/x25/af_x25.c	2003-10-05 00:34:48.000000000 -0700
+@@ -345,10 +345,8 @@ void x25_destroy_socket(struct sock *sk)
+ 	if (atomic_read(&sk->sk_wmem_alloc) ||
+ 	    atomic_read(&sk->sk_rmem_alloc)) {
+ 		/* Defer: outstanding buffers */
+-		init_timer(&sk->sk_timer);
+ 		sk->sk_timer.expires  = jiffies + 10 * HZ;
+ 		sk->sk_timer.function = x25_destroy_timer;
+-		sk->sk_timer.data     = (unsigned long)sk;
+ 		add_timer(&sk->sk_timer);
+ 	} else {
+ 		/* drop last reference so sock_put will free */
+@@ -463,6 +461,8 @@ frees:
+ 	goto out;
+ }
+ 
++void x25_init_timers(struct sock *sk);
++
+ static int x25_create(struct socket *sock, int protocol)
+ {
+ 	struct sock *sk;
+@@ -481,7 +481,7 @@ static int x25_create(struct socket *soc
+ 	sock_init_data(sock, sk);
+ 	sk_set_owner(sk, THIS_MODULE);
+ 
+-	init_timer(&x25->timer);
++	x25_init_timers(sk);
+ 
+ 	sock->ops    = &x25_proto_ops;
+ 	sk->sk_protocol = protocol;
+@@ -537,7 +537,7 @@ static struct sock *x25_make_new(struct 
+ 	x25->facilities = ox25->facilities;
+ 	x25->qbitincl   = ox25->qbitincl;
+ 
+-	init_timer(&x25->timer);
++	x25_init_timers(sk);
+ out:
+ 	return sk;
+ }
+--- linux-2.6.0-test6/net/x25/x25_link.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/net/x25/x25_link.c	2003-10-05 00:34:48.000000000 -0700
+@@ -51,15 +51,9 @@ static void x25_t20timer_expiry(unsigned
+ /*
+  *	Linux set/reset timer routines
+  */
+-static void x25_start_t20timer(struct x25_neigh *nb)
++static inline void x25_start_t20timer(struct x25_neigh *nb)
+ {
+-	del_timer(&nb->t20timer);
+-
+-	nb->t20timer.data     = (unsigned long)nb;
+-	nb->t20timer.function = &x25_t20timer_expiry;
+-	nb->t20timer.expires  = jiffies + nb->t20;
+-
+-	add_timer(&nb->t20timer);
++	mod_timer(&nb->t20timer, jiffies + nb->t20);
+ }
+ 
+ static void x25_t20timer_expiry(unsigned long param)
+@@ -71,12 +65,12 @@ static void x25_t20timer_expiry(unsigned
+ 	x25_start_t20timer(nb);
+ }
+ 
+-static void x25_stop_t20timer(struct x25_neigh *nb)
++static inline void x25_stop_t20timer(struct x25_neigh *nb)
+ {
+ 	del_timer(&nb->t20timer);
+ }
+ 
+-static int x25_t20timer_pending(struct x25_neigh *nb)
++static inline int x25_t20timer_pending(struct x25_neigh *nb)
+ {
+ 	return timer_pending(&nb->t20timer);
+ }
+@@ -291,6 +285,8 @@ void x25_link_device_up(struct net_devic
+ 	skb_queue_head_init(&nb->queue);
+ 
+ 	init_timer(&nb->t20timer);
++	nb->t20timer.data     = (unsigned long)nb;
++	nb->t20timer.function = &x25_t20timer_expiry;
+ 
+ 	dev_hold(dev);
+ 	nb->dev      = dev;
+--- linux-2.6.0-test6/net/x25/x25_timer.c	2003-06-14 12:17:57.000000000 -0700
++++ 25/net/x25/x25_timer.c	2003-10-05 00:34:48.000000000 -0700
+@@ -43,15 +43,22 @@
+ static void x25_heartbeat_expiry(unsigned long);
+ static void x25_timer_expiry(unsigned long);
+ 
+-void x25_start_heartbeat(struct sock *sk)
++void x25_init_timers(struct sock *sk)
+ {
+-	del_timer(&sk->sk_timer);
++	struct x25_opt *x25 = x25_sk(sk);
+ 
++	init_timer(&x25->timer);
++	x25->timer.data     = (unsigned long)sk;
++	x25->timer.function = &x25_timer_expiry;
++
++	/* initialized by sock_init_data */
+ 	sk->sk_timer.data     = (unsigned long)sk;
+ 	sk->sk_timer.function = &x25_heartbeat_expiry;
+-	sk->sk_timer.expires  = jiffies + 5 * HZ;
++}
+ 
+-	add_timer(&sk->sk_timer);
++void x25_start_heartbeat(struct sock *sk)
++{
++	mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+ }
+ 
+ void x25_stop_heartbeat(struct sock *sk)
+@@ -63,52 +70,28 @@ void x25_start_t2timer(struct sock *sk)
+ {
+ 	struct x25_opt *x25 = x25_sk(sk);
+ 
+-	del_timer(&x25->timer);
+-
+-	x25->timer.data     = (unsigned long)sk;
+-	x25->timer.function = &x25_timer_expiry;
+-	x25->timer.expires  = jiffies + x25->t2;
+-
+-	add_timer(&x25->timer);
++	mod_timer(&x25->timer, jiffies + x25->t2);
+ }
+ 
+ void x25_start_t21timer(struct sock *sk)
+ {
+ 	struct x25_opt *x25 = x25_sk(sk);
+ 
+-	del_timer(&x25->timer);
+-
+-	x25->timer.data     = (unsigned long)sk;
+-	x25->timer.function = &x25_timer_expiry;
+-	x25->timer.expires  = jiffies + x25->t21;
+-
+-	add_timer(&x25->timer);
++	mod_timer(&x25->timer, jiffies + x25->t21);
+ }
+ 
+ void x25_start_t22timer(struct sock *sk)
+ {
+ 	struct x25_opt *x25 = x25_sk(sk);
+ 
+-	del_timer(&x25->timer);
+-
+-	x25->timer.data     = (unsigned long)sk;
+-	x25->timer.function = &x25_timer_expiry;
+-	x25->timer.expires  = jiffies + x25->t22;
+-
+-	add_timer(&x25->timer);
++	mod_timer(&x25->timer, jiffies + x25->t22);
+ }
+ 
+ void x25_start_t23timer(struct sock *sk)
+ {
+ 	struct x25_opt *x25 = x25_sk(sk);
+ 
+-	del_timer(&x25->timer);
+-
+-	x25->timer.data     = (unsigned long)sk;
+-	x25->timer.function = &x25_timer_expiry;
+-	x25->timer.expires  = jiffies + x25->t23;
+-
+-	add_timer(&x25->timer);
++	mod_timer(&x25->timer, jiffies + x25->t23);
+ }
+ 
+ void x25_stop_timer(struct sock *sk)
+--- linux-2.6.0-test6/net/xfrm/xfrm_algo.c	2003-08-22 19:23:42.000000000 -0700
++++ 25/net/xfrm/xfrm_algo.c	2003-10-05 00:33:25.000000000 -0700
+@@ -8,7 +8,9 @@
+  * Software Foundation; either version 2 of the License, or (at your option) 
+  * any later version.
+  */
++
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/pfkeyv2.h>
+ #include <net/xfrm.h>
+@@ -617,6 +619,7 @@ skb_to_sgvec(struct sk_buff *skb, struct
+ 		BUG();
+ 	return elt;
+ }
++EXPORT_SYMBOL_GPL(skb_to_sgvec);
+ 
+ /* Check that skb data bits are writable. If they are not, copy data
+  * to newly created private area. If "tailbits" is given, make sure that
+@@ -717,6 +720,7 @@ int skb_cow_data(struct sk_buff *skb, in
+ 
+ 	return elt;
+ }
++EXPORT_SYMBOL_GPL(skb_cow_data);
+ 
+ void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
+ {
+@@ -726,4 +730,5 @@ void *pskb_put(struct sk_buff *skb, stru
+ 	}
+ 	return skb_put(tail, len);
+ }
++EXPORT_SYMBOL_GPL(pskb_put);
+ #endif
+--- linux-2.6.0-test6/scripts/bin2c.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/scripts/bin2c.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,3 +1,12 @@
++/*
++ * Unloved program to convert a binary on stdin to a C include on stdout
++ *
++ * Jan 1999 Matt Mackall <mpm@selenic.com>
++ *
++ * This software may be used and distributed according to the terms
++ * of the GNU General Public License, incorporated herein by reference.
++ */
++
+ #include <stdio.h>
+ 
+ int main(int argc, char *argv[])
+--- linux-2.6.0-test6/scripts/pnmtologo.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/scripts/pnmtologo.c	2003-10-05 00:33:25.000000000 -0700
+@@ -119,7 +119,8 @@ static unsigned int get_number255(FILE *
+ static void read_image(void)
+ {
+     FILE *fp;
+-    int i, j, magic;
++    unsigned int i, j;
++    int magic;
+     unsigned int maxval;
+ 
+     /* open image file */
+@@ -274,7 +275,7 @@ static void write_hex(unsigned char byte
+ 
+ static void write_logo_mono(void)
+ {
+-    int i, j;
++    unsigned int i, j;
+     unsigned char val, bit;
+ 
+     /* validate image */
+@@ -302,7 +303,7 @@ static void write_logo_mono(void)
+ 
+ static void write_logo_vga16(void)
+ {
+-    int i, j, k;
++    unsigned int i, j, k;
+     unsigned char val;
+ 
+     /* validate image */
+@@ -342,7 +343,7 @@ static void write_logo_vga16(void)
+ 
+ static void write_logo_clut224(void)
+ {
+-    int i, j, k;
++    unsigned int i, j, k;
+ 
+     /* validate image */
+     for (i = 0; i < logo_height; i++)
+@@ -388,7 +389,7 @@ static void write_logo_clut224(void)
+ 
+ static void write_logo_gray256(void)
+ {
+-    int i, j;
++    unsigned int i, j;
+ 
+     /* validate image */
+     for (i = 0; i < logo_height; i++)
+--- linux-2.6.0-test6/security/dummy.c	2003-07-10 18:50:32.000000000 -0700
++++ 25/security/dummy.c	2003-10-05 00:33:25.000000000 -0700
+@@ -364,7 +364,7 @@ static int dummy_inode_follow_link (stru
+ 	return 0;
+ }
+ 
+-static int dummy_inode_permission (struct inode *inode, int mask)
++static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata *nd)
+ {
+ 	return 0;
+ }
+--- linux-2.6.0-test6/security/selinux/hooks.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/security/selinux/hooks.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1730,13 +1730,18 @@ static int selinux_inode_follow_link(str
+ 	return dentry_has_perm(current, NULL, dentry, FILE__READ);
+ }
+ 
+-static int selinux_inode_permission(struct inode *inode, int mask)
++static int selinux_inode_permission(struct inode *inode, int mask,
++				    struct nameidata *nd)
+ {
+ 	if (!mask) {
+ 		/* No permission to check.  Existence test. */
+ 		return 0;
+ 	}
+ 
++	if (nd && nd->dentry)
++		return dentry_has_perm(current, nd->mnt, nd->dentry,
++				       file_mask_to_av(inode->i_mode, mask));
++
+ 	return inode_has_perm(current, inode,
+ 			       file_mask_to_av(inode->i_mode, mask), NULL, NULL);
+ }
+--- linux-2.6.0-test6/security/selinux/ss/services.c	2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/ss/services.c	2003-10-05 00:33:25.000000000 -0700
+@@ -896,7 +896,7 @@ static int convert_context(u32 key,
+ 	struct user_datum *usrdatum;
+ 	char *s;
+ 	u32 len;
+-	int rc = -EINVAL;
++	int rc;
+ 
+ 	args = p;
+ 
+@@ -904,6 +904,8 @@ static int convert_context(u32 key,
+ 	if (rc)
+ 		goto out;
+ 
++	rc = -EINVAL;
++
+ 	/* Convert the user. */
+ 	usrdatum = hashtab_search(args->newp->p_users.table,
+ 	                          args->oldp->p_user_val_to_name[c->user - 1]);
+--- linux-2.6.0-test6/sound/oss/ac97_codec.c	2003-09-27 18:57:47.000000000 -0700
++++ 25/sound/oss/ac97_codec.c	2003-10-05 00:33:25.000000000 -0700
+@@ -46,7 +46,6 @@
+  *	Isolated from trident.c to support multiple ac97 codec
+  */
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+--- linux-2.6.0-test6/sound/oss/ali5455.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/ali5455.c	2003-10-05 00:33:25.000000000 -0700
+@@ -47,7 +47,6 @@
+  */
+ 
+ #include <linux/module.h>
+-#include <linux/version.h>
+ #include <linux/string.h>
+ #include <linux/ctype.h>
+ #include <linux/ioport.h>
+--- linux-2.6.0-test6/sound/oss/au1000.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/au1000.c	2003-10-05 00:33:25.000000000 -0700
+@@ -50,7 +50,6 @@
+  *                channels [stevel].
+  *
+  */
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+@@ -2223,8 +2222,9 @@ static int __init au1000_setup(char *opt
+ 	if (!options || !*options)
+ 		return 0;
+ 
+-	for(this_opt=strtok(options, ",");
+-	    this_opt; this_opt=strtok(NULL, ",")) {
++	while (this_opt = strsep(&options, ",")) {
++		if (!*this_opt)
++			continue;
+ 		if (!strncmp(this_opt, "vra", 3)) {
+ 			vra = 1;
+ 		}
+--- linux-2.6.0-test6/sound/oss/btaudio.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/btaudio.c	2003-10-05 00:33:25.000000000 -0700
+@@ -177,8 +177,11 @@ static int alloc_buffer(struct btaudio *
+ 		bta->risc_size = PAGE_SIZE;
+ 		bta->risc_cpu = pci_alloc_consistent
+ 			(bta->pci, bta->risc_size, &bta->risc_dma);
+-		if (NULL == bta->risc_cpu)
++		if (NULL == bta->risc_cpu) {
++			pci_free_consistent(bta->pci, bta->buf_size, bta->buf_cpu, bta->buf_dma);
++			bta->buf_cpu = NULL;
+ 			return -ENOMEM;
++		}
+ 	}
+ 	return 0;
+ }
+--- linux-2.6.0-test6/sound/oss/dmasound/dac3550a.c	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/oss/dmasound/dac3550a.c	2003-10-05 00:33:25.000000000 -0700
+@@ -7,7 +7,6 @@
+  *  for more details.
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/sound/oss/dmasound/Kconfig	2003-09-27 18:57:47.000000000 -0700
++++ 25/sound/oss/dmasound/Kconfig	2003-10-05 00:33:25.000000000 -0700
+@@ -1,7 +1,7 @@
+-# drivers/sound/dmasound/Config.in
+ config DMASOUND_ATARI
+ 	tristate "Atari DMA sound support"
+ 	depends on ATARI && SOUND
++	select DMASOUND
+ 	help
+ 	  If you want to use the internal audio of your Atari in Linux, answer
+ 	  Y to this question. This will provide a Sun-like /dev/audio,
+@@ -15,6 +15,7 @@ config DMASOUND_ATARI
+ config DMASOUND_PMAC
+ 	tristate "PowerMac DMA sound support"
+ 	depends on PPC_PMAC && SOUND && I2C
++ 	select DMASOUND
+ 	help
+ 	  If you want to use the internal audio of your PowerMac in Linux,
+ 	  answer Y to this question. This will provide a Sun-like /dev/audio,
+@@ -28,6 +29,7 @@ config DMASOUND_PMAC
+ config DMASOUND_PAULA
+ 	tristate "Amiga DMA sound support"
+ 	depends on (AMIGA || APUS) && SOUND
++	select DMASOUND
+ 	help
+ 	  If you want to use the internal audio of your Amiga in Linux, answer
+ 	  Y to this question. This will provide a Sun-like /dev/audio,
+@@ -41,6 +43,7 @@ config DMASOUND_PAULA
+ config DMASOUND_Q40
+ 	tristate "Q40 sound support"
+ 	depends on Q40 && SOUND
++	select DMASOUND
+ 	help
+ 	  If you want to use the internal audio of your Q40 in Linux, answer
+ 	  Y to this question. This will provide a Sun-like /dev/audio,
+@@ -53,13 +56,3 @@ config DMASOUND_Q40
+ 
+ config DMASOUND
+ 	tristate
+-	depends on SOUND!=n
+-	default m if DMASOUND_ATARI!=y && DMASOUND_AWACS!=y && DMASOUND_PAULA!=y && DMASOUND_Q40!=y && (DMASOUND_ATARI=m || DMASOUND_AWACS=m || DMASOUND_PAULA=m || DMASOUND_Q40=m)
+-	default y if DMASOUND_ATARI=y || DMASOUND_AWACS=y || DMASOUND_PAULA=y || DMASOUND_Q40=y
+-	help
+-	  Support built-in audio chips accessible by DMA on various machines
+-	  that have them.  Note that this symbol does not affect the kernel
+-	  directly; rather, it controls whether configuration questions
+-	  enabling DMA sound drivers for various specific machine
+-	  architectures will be used.
+-
+--- linux-2.6.0-test6/sound/oss/dmasound/tas3001c.c	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/oss/dmasound/tas3001c.c	2003-10-05 00:33:25.000000000 -0700
+@@ -15,7 +15,6 @@
+  *
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/sound/oss/dmasound/tas3004.c	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/oss/dmasound/tas3004.c	2003-10-05 00:33:25.000000000 -0700
+@@ -13,7 +13,6 @@
+  *
+  */
+ 
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/sound/oss/dmasound/tas_common.c	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/oss/dmasound/tas_common.c	2003-10-05 00:33:25.000000000 -0700
+@@ -1,4 +1,3 @@
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+--- linux-2.6.0-test6/sound/oss/harmony.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/harmony.c	2003-10-05 00:33:25.000000000 -0700
+@@ -28,14 +28,14 @@ TODO:
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/pci.h>
+ 
+-#include <asm/gsc.h>
++#include <asm/parisc-device.h>
+ #include <asm/io.h>
+-#include <asm/pgalloc.h>
+ 
+ #include "sound_config.h"
+ 
+--- linux-2.6.0-test6/sound/oss/ite8172.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/ite8172.c	2003-10-05 00:33:25.000000000 -0700
+@@ -54,7 +54,6 @@
+  *    07.30.2003  Removed initialisation to zero for static variables
+  *		   (spdif[NR_DEVICE], i2s_fmt[NR_DEVICE], and devindex)
+  */
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+@@ -2238,8 +2237,9 @@ static int __init it8172_setup(char *opt
+ 	if (!options || !*options)
+ 		return 0;
+ 
+-	for(this_opt=strtok(options, ",");
+-	    this_opt; this_opt=strtok(NULL, ",")) {
++	while (this_opt = strsep(&options, ",")) {
++		if (!*this_opt)
++			continue;
+ 		if (!strncmp(this_opt, "spdif", 5)) {
+ 			spdif[nr_dev] = 1;
+ 		} else if (!strncmp(this_opt, "i2s:", 4)) {
+--- linux-2.6.0-test6/sound/oss/opl3sa2.c	2003-08-22 19:23:43.000000000 -0700
++++ 25/sound/oss/opl3sa2.c	2003-10-05 00:33:25.000000000 -0700
+@@ -324,15 +324,6 @@ static void opl3sa3_set_treble(opl3sa2_s
+ }
+ 
+ 
+-static void opl3sa3_set_wide(opl3sa2_state_t* devc, int left, int right)
+-{	
+-	unsigned char wide;
+-
+-	wide = left ? ((unsigned char) (8 * left / 101)) : 0; 
+-	wide |= (right ? ((unsigned char) (8 * right / 101)) : 0) << 4;
+-
+-	opl3sa2_write(devc->cfg_port, OPL3SA3_WIDE, wide);
+-}
+ 
+ 
+ static void opl3sa2_mixer_reset(opl3sa2_state_t* devc)
+@@ -401,7 +392,7 @@ static inline int ret_vol_stereo(int lef
+ 
+ static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+ {
+-	int cmdf = cmd & 0xff;
++	int retval, value, cmdf = cmd & 0xff;
+ 
+ 	opl3sa2_state_t* devc = &opl3sa2_state[dev];
+ 	
+@@ -422,23 +413,31 @@ static int opl3sa2_mixer_ioctl(int dev, 
+ 	if (((cmd >> 8) & 0xff) != 'M')
+ 		return -EINVAL;
+ 		
++	retval = 0;
+ 	if (_SIOC_DIR (cmd) & _SIOC_WRITE) {
+ 		switch (cmdf) {
+ 			case SOUND_MIXER_VOLUME:
+-				arg_to_vol_stereo(*(unsigned int*)arg,
+-						  &devc->volume_l, &devc->volume_r); 
++				retval = get_user(value, (unsigned int *) arg);
++				if (retval)
++					break;
++				arg_to_vol_stereo(value, &devc->volume_l, &devc->volume_r);
+ 				opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
+-				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
+-				return 0;
++				value = ret_vol_stereo(devc->volume_l, devc->volume_r);
++				retval = put_user(value, (int *) arg);
++				break;
+ 		  
+ 			case SOUND_MIXER_MIC:
+-				arg_to_vol_mono(*(unsigned int*)arg, &devc->mic);
++				retval = get_user(value, (unsigned int *) arg);
++				if (retval)
++					break;
++				arg_to_vol_mono(value, &devc->mic);
+ 				opl3sa2_set_mic(devc, devc->mic);
+-				*(int*)arg = ret_vol_mono(devc->mic);
+-				return 0;
++				value = ret_vol_mono(devc->mic);
++				retval = put_user(value, (int *) arg);
++				break;
+ 
+ 			default:
+-				return -EINVAL;
++				retval = -EINVAL;
+ 		}
+ 	}
+ 	else {
+@@ -447,122 +446,72 @@ static int opl3sa2_mixer_ioctl(int dev, 
+ 		 */
+ 		switch (cmdf) {
+ 			case SOUND_MIXER_DEVMASK:
+-				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
+-				return 0;
++				retval = put_user(SOUND_MASK_VOLUME | SOUND_MASK_MIC, (int *) arg);
++				break;
+ 		  
+ 			case SOUND_MIXER_STEREODEVS:
+-				*(int*)arg = SOUND_MASK_VOLUME;
+-				return 0;
++				retval = put_user(SOUND_MASK_VOLUME, (int *) arg);
++				break;
+ 		  
+ 			case SOUND_MIXER_RECMASK:
+ 				/* No recording devices */
+-				return (*(int*)arg = 0);
++				retval = put_user(0, (int *) arg);
++				break;
+ 
+ 			case SOUND_MIXER_CAPS:
+-				*(int*)arg = SOUND_CAP_EXCL_INPUT;
+-				return 0;
++				retval = put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
++				break;
+ 
+ 			case SOUND_MIXER_RECSRC:
+ 				/* No recording source */
+-				return (*(int*)arg = 0);
++				retval = put_user(0, (int *) arg);
++				break;
+ 
+ 			case SOUND_MIXER_VOLUME:
+-				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
+-				return 0;
++				value = ret_vol_stereo(devc->volume_l, devc->volume_r);
++				retval = put_user(value, (int *) arg);
++				break;
+ 			  
+ 			case SOUND_MIXER_MIC:
+-				*(int*)arg = ret_vol_mono(devc->mic);
+-				return 0;
++				value = ret_vol_mono(devc->mic);
++				put_user(value, (int *) arg);
++				break;
+ 
+ 			default:
+-				return -EINVAL;
++				retval = -EINVAL;
+ 		}
+ 	}
++	return retval;
+ }
+ /* opl3sa2_mixer_ioctl end */
+ 
+ 
+ static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+ {
+-	int cmdf = cmd & 0xff;
++	int value, retval, cmdf = cmd & 0xff;
+ 
+ 	opl3sa2_state_t* devc = &opl3sa2_state[dev];
+ 
+ 	switch (cmdf) {
+-		case SOUND_MIXER_BASS:
+-		case SOUND_MIXER_TREBLE:
+-		case SOUND_MIXER_DIGITAL1:
+-		case SOUND_MIXER_DEVMASK:
+-		case SOUND_MIXER_STEREODEVS: 
+-			break;
+-
+-		default:
+-			return opl3sa2_mixer_ioctl(dev, cmd, arg);
+-	}
+-
+-	if (((cmd >> 8) & 0xff) != 'M')
+-		return -EINVAL;
++	case SOUND_MIXER_BASS:
++		value = ret_vol_stereo(devc->bass_l, devc->bass_r);
++		retval = put_user(value, (int *) arg);
++		break;
+ 		
+-	if (_SIOC_DIR (cmd) & _SIOC_WRITE) {
+-		switch (cmdf) {
+-			case SOUND_MIXER_BASS:
+-				arg_to_vol_stereo(*(unsigned int*)arg,
+-						  &devc->bass_l, &devc->bass_r); 
+-				opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
+-				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
+-				return 0;
+-		  
+-			case SOUND_MIXER_TREBLE:
+-				arg_to_vol_stereo(*(unsigned int*)arg,
+-						  &devc->treble_l, &devc->treble_r); 
+-				opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
+-				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
+-				return 0;
+-
+-			case SOUND_MIXER_DIGITAL1:
+-				arg_to_vol_stereo(*(unsigned int*)arg,
+-						  &devc->wide_l, &devc->wide_r); 
+-				opl3sa3_set_wide(devc, devc->wide_l, devc->wide_r);
+-				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
+-				return 0;
++	case SOUND_MIXER_TREBLE:
++		value = ret_vol_stereo(devc->treble_l, devc->treble_r);
++		retval = put_user(value, (int *) arg);
++		break;
+ 
+-			default:
+-				return -EINVAL;
+-		}
+-	}
+-	else			
+-	{
+-		/*
+-		 * Return parameters
+-		 */
+-		switch (cmdf) {
+-			case SOUND_MIXER_DEVMASK:
+-				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC |
+-					      SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+-					      SOUND_MASK_DIGITAL1);
+-				return 0;
+-		  
+-			case SOUND_MIXER_STEREODEVS:
+-				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_BASS |
+-					      SOUND_MASK_TREBLE | SOUND_MASK_DIGITAL1);
+-				return 0;
+-		  
+-			case SOUND_MIXER_BASS:
+-				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
+-				return 0;
+-			  
+-			case SOUND_MIXER_TREBLE:
+-				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
+-				return 0;
+-
+-			case SOUND_MIXER_DIGITAL1:
+-				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
+-				return 0;
++	case SOUND_MIXER_DIGITAL1:
++		value = ret_vol_stereo(devc->wide_l, devc->wide_r);
++		retval = put_user(value, (int *) arg);
++		break;
+ 
+-			default:
+-				return -EINVAL;
+-		}
++	default:
++		retval = -EINVAL;
+ 	}
++	return retval;
+ }
+ /* opl3sa3_mixer_ioctl end */
+ 
+--- linux-2.6.0-test6/sound/oss/swarm_cs4297a.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/swarm_cs4297a.c	2003-10-05 00:33:25.000000000 -0700
+@@ -59,7 +59,6 @@
+ *******************************************************************************/
+ 
+ #include <linux/list.h>
+-#include <linux/version.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/ioport.h>
+--- linux-2.6.0-test6/sound/oss/via82cxxx_audio.c	2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/via82cxxx_audio.c	2003-10-05 00:36:10.000000000 -0700
+@@ -1844,6 +1844,7 @@ static void via_ac97_cleanup (struct via
+ 
+ /**
+  *	via_intr_channel - handle an interrupt for a single channel
++ *      @card: unused
+  *	@chan: handle interrupt for this channel
+  *
+  *	This is the "meat" of the interrupt handler,
+--- linux-2.6.0-test6/sound/parisc/harmony.c	2003-08-22 19:23:43.000000000 -0700
++++ 25/sound/parisc/harmony.c	2003-10-05 00:33:25.000000000 -0700
+@@ -66,6 +66,7 @@
+ #include <linux/delay.h>
+ #include <sound/driver.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/time.h>
+ #include <linux/wait.h>
+@@ -77,8 +78,8 @@
+ #include <sound/initval.h>
+ #include <sound/info.h>
+ #include <asm/hardware.h>
+-#include <asm/gsc.h>
+ #include <asm/io.h>
++#include <asm/parisc-device.h>
+ 
+ MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>");
+ MODULE_DESCRIPTION("ALSA Harmony sound driver");
+@@ -709,8 +710,8 @@ static int snd_card_harmony_playback_ope
+ 	 * harmony is not "real" pci, but we need a pci_dev
+ 	 * to alloc PCI DMA pages
+ 	 */
+-	substream->dma_private = harmony->fake_pci_dev;
+-	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
++	substream->runtime->dma_private = harmony->fake_pci_dev;
++//	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
+ 	
+ 	harmony->playback_substream = substream;
+ 	runtime->hw = snd_card_harmony_playback;
+@@ -733,8 +734,8 @@ static int snd_card_harmony_capture_open
+ 	 * harmony is not "real" pci, but we need a pci_dev
+ 	 * to alloc PCI DMA pages
+ 	 */
+-	substream->dma_private = harmony->fake_pci_dev;
+-	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
++	substream->runtime->dma_private = harmony->fake_pci_dev;
++//	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
+ 
+ 	harmony->capture_substream = substream;
+ 	runtime->hw = snd_card_harmony_capture;
+--- linux-2.6.0-test6/sound/pci/cmipci.c	2003-08-08 22:55:15.000000000 -0700
++++ 25/sound/pci/cmipci.c	2003-10-05 00:33:25.000000000 -0700
+@@ -2791,6 +2791,7 @@ static int __devinit snd_cmipci_mixer_ne
+  * proc interface
+  */
+ 
++#ifdef CONFIG_PROC_FS
+ static void snd_cmipci_proc_read(snd_info_entry_t *entry, 
+ 				 snd_info_buffer_t *buffer)
+ {
+@@ -2817,6 +2818,9 @@ static void __devinit snd_cmipci_proc_in
+ 	if (! snd_card_proc_new(cm->card, "cmipci", &entry))
+ 		snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
+ }
++#else /* !CONFIG_PROC_FS */
++static inline void snd_cmipci_proc_init(cmipci_t *cm) {}
++#endif
+ 
+ 
+ static struct pci_device_id snd_cmipci_ids[] = {
+--- linux-2.6.0-test6/sound/pci/intel8x0.c	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/pci/intel8x0.c	2003-10-05 00:34:31.000000000 -0700
+@@ -2271,10 +2271,8 @@ static void __devinit intel8x0_measure_a
+ 
+ 	t = stop_time.tv_sec - start_time.tv_sec;
+ 	t *= 1000000;
+-	if (stop_time.tv_usec < start_time.tv_usec)
+-		t -= start_time.tv_usec - stop_time.tv_usec;
+-	else
+-		t += stop_time.tv_usec - start_time.tv_usec;
++	t += stop_time.tv_usec - start_time.tv_usec;
++	printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
+ 	if (t == 0) {
+ 		snd_printk(KERN_ERR "?? calculation error..\n");
+ 		return;
+--- linux-2.6.0-test6/sound/pci/Kconfig	2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/pci/Kconfig	2003-10-05 00:34:45.000000000 -0700
+@@ -17,7 +17,8 @@ config SND_AZT3328
+ 
+ config SND_CS46XX
+ 	tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for Cirrus Logic CS4610 / CS4612 /
+ 	  CS4614 / CS4615 / CS4622 / CS4624 / CS4630 / CS4280 chips.
+@@ -30,7 +31,8 @@ config SND_CS46XX_NEW_DSP
+ 
+ config SND_CS4281
+ 	tristate "Cirrus Logic (Sound Fusion) CS4281"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for Cirrus Logic CS4281.
+ 
+@@ -83,7 +85,8 @@ config SND_HDSP
+ 
+ config SND_TRIDENT
+ 	tristate "Trident 4D-Wave DX/NX; SiS 7018"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for Trident 4D-Wave DX/NX and
+ 	  SiS 7018 soundcards.
+@@ -110,20 +113,23 @@ config SND_CMIPCI
+ 
+ config SND_ENS1370
+ 	tristate "(Creative) Ensoniq AudioPCI 1370"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370.
+ 
+ config SND_ENS1371
+ 	tristate "(Creative) Ensoniq AudioPCI 1371/1373"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and
+ 	  Sound Blaster PCI 64 or 128 soundcards.
+ 
+ config SND_ES1938
+ 	tristate "ESS ES1938/1946/1969 (Solo-1)"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946, ES1969)
+ 	  soundcard.
+@@ -173,7 +179,8 @@ config SND_INTEL8X0
+ 
+ config SND_SONICVIBES
+ 	tristate "S3 SonicVibes"
+-	depends on SND && GAMEPORT
++	depends on SND
++	select GAMEPORT
+ 	help
+ 	  Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
+ 
diff --git a/lustre/kernel_patches/patches/add_page_private-2.4.19-pre1.patch b/lustre/kernel_patches/patches/add_page_private-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a7e087d010c1ba6e64ded7e751bc7b06eac34f5c
--- /dev/null
+++ b/lustre/kernel_patches/patches/add_page_private-2.4.19-pre1.patch
@@ -0,0 +1,15 @@
+ include/linux/mm.h |    1 +
+ 1 files changed, 1 insertion(+)
+
+Index: linux-2.4.19-pre1/include/linux/mm.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/mm.h	2003-11-20 19:24:06.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/mm.h	2003-11-21 02:00:13.000000000 +0300
+@@ -162,6 +162,7 @@
+ 	wait_queue_head_t wait;		/* Page locked?  Stand in line... */
+ 	struct page **pprev_hash;	/* Complement to *next_hash. */
+ 	struct buffer_head * buffers;	/* Buffer maps us to a disk block. */
++	unsigned long private;
+ 	void *virtual;			/* Kernel virtual address (NULL if
+ 					   not kmapped, ie. highmem) */
+ 	struct zone_struct *zone;	/* Memory zone we are in. */
diff --git a/lustre/kernel_patches/patches/add_page_private.patch b/lustre/kernel_patches/patches/add_page_private.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f82fb92d920be24744bbf4449bbdadbb03b82eef
--- /dev/null
+++ b/lustre/kernel_patches/patches/add_page_private.patch
@@ -0,0 +1,15 @@
+ include/linux/mm.h |    1 +
+ 1 files changed, 1 insertion(+)
+
+--- linux-2.4.20-b_llpio-l21/include/linux/mm.h~add_page_private	2003-07-21 21:42:50.000000000 -0700
++++ linux-2.4.20-b_llpio-l21-zab/include/linux/mm.h	2003-07-21 21:44:16.000000000 -0700
+@@ -162,6 +162,7 @@ typedef struct page {
+ 					   protected by pagemap_lru_lock !! */
+ 	struct page **pprev_hash;	/* Complement to *next_hash. */
+ 	struct buffer_head * buffers;	/* Buffer maps us to a disk block. */
++	unsigned long private;
+ 
+ 	/*
+ 	 * On machines where all RAM is mapped into kernel address space,
+
+_
diff --git a/lustre/kernel_patches/patches/bproc-patch-2.4.20 b/lustre/kernel_patches/patches/bproc-patch-2.4.20
new file mode 100644
index 0000000000000000000000000000000000000000..00bb337cef27a0e4c7a3f772a891e284c5da1689
--- /dev/null
+++ b/lustre/kernel_patches/patches/bproc-patch-2.4.20
@@ -0,0 +1,1826 @@
+$Id: bproc-patch-2.4.20,v 1.2 2003/12/03 03:13:30 phil Exp $
+
+Index: linux/fs/exec.c
+===================================================================
+--- linux.orig/fs/exec.c	2003-09-03 17:52:00.000000000 -0400
++++ linux/fs/exec.c	2003-09-03 17:52:04.000000000 -0400
+@@ -38,6 +38,7 @@
+ #include <linux/utsname.h>
+ #define __NO_VERSION__
+ #include <linux/module.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -953,9 +954,11 @@
+ 	xa_call_actions (XA_EXEC, XA_KOE, NULL);
+ 
+ 	retval = search_binary_handler(&bprm,regs);
+-	if (retval >= 0)
++	if (retval >= 0) {
+ 		/* execve success */
++ 		bproc_hook_im(do_execve,());
+ 		return retval;
++	}
+ 
+ out:
+ 	/* Something went wrong, return the inode and free the argument pages*/
+Index: linux/fs/binfmt_script.c
+===================================================================
+--- linux.orig/fs/binfmt_script.c	2002-08-02 20:39:45.000000000 -0400
++++ linux/fs/binfmt_script.c	2003-09-03 17:52:04.000000000 -0400
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/file.h>
+ #include <linux/smp_lock.h>
++#include <linux/bproc.h>
+ 
+ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+ {
+@@ -67,7 +68,7 @@
+ 	 * user environment and arguments are stored.
+ 	 */
+ 	remove_arg_zero(bprm);
+-	retval = copy_strings_kernel(1, &bprm->filename, bprm);
++	retval = copy_strings_kernel(1,bproc_hook_v(&bprm->filename,load_script,(&bprm->filename)), bprm);
+ 	if (retval < 0) return retval; 
+ 	bprm->argc++;
+ 	if (i_arg) {
+Index: linux/fs/binfmt_elf.c
+===================================================================
+--- linux.orig/fs/binfmt_elf.c	2002-08-02 20:39:45.000000000 -0400
++++ linux/fs/binfmt_elf.c	2003-09-03 17:52:04.000000000 -0400
+@@ -73,7 +73,7 @@
+ #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
+ #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
+ 
+-static struct linux_binfmt elf_format = {
++struct linux_binfmt elf_format = {
+ 	NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
+ };
+ 
+Index: linux/fs/proc/base.c
+===================================================================
+--- linux.orig/fs/proc/base.c	2003-09-03 17:52:00.000000000 -0400
++++ linux/fs/proc/base.c	2003-09-03 17:52:04.000000000 -0400
+@@ -25,6 +25,7 @@
+ #include <linux/string.h>
+ #include <linux/seq_file.h>
+ #include <linux/namespace.h>
++#include <linux/bproc.h>
+ 
+ /*
+  * For hysterical raisins we keep the same inumbers as in the old procfs.
+@@ -304,6 +305,7 @@
+ 	if (!(page = __get_free_page(GFP_KERNEL)))
+ 		return -ENOMEM;
+ 
++	if (bproc_isghost(task)) bproc_hook(refresh_status,(task));
+ 	length = inode->u.proc_i.op.proc_read(task, (char*)page);
+ 
+ 	if (length < 0) {
+@@ -976,14 +978,14 @@
+ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+ 	char tmp[30];
+-	sprintf(tmp, "%d", current->pid);
++	sprintf(tmp, "%d", bproc_hook_imv(current->pid,proc3,()));
+ 	return vfs_readlink(dentry,buffer,buflen,tmp);
+ }
+ 
+ static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+ 	char tmp[30];
+-	sprintf(tmp, "%d", current->pid);
++	sprintf(tmp, "%d", bproc_hook_imv(current->pid,proc3,()));
+ 	return vfs_follow_link(nd,tmp);
+ }	
+ 
+@@ -1031,6 +1033,7 @@
+ 			goto out;
+ 	}
+ 
++	pid = bproc_hook_imv(pid,proc2,(pid));
+ 	read_lock(&tasklist_lock);
+ 	task = find_task_by_pid(pid);
+ 	if (task)
+@@ -1082,7 +1085,7 @@
+ 	index--;
+ 	read_lock(&tasklist_lock);
+ 	for_each_task(p) {
+-		int pid = p->pid;
++		int pid = bproc_hook_imv(p->pid,proc1,(p));
+ 		if (!pid)
+ 			continue;
+ 		if (--index >= 0)
+Index: linux/fs/proc/array.c
+===================================================================
+--- linux.orig/fs/proc/array.c	2002-08-02 20:39:45.000000000 -0400
++++ linux/fs/proc/array.c	2003-09-03 17:52:04.000000000 -0400
+@@ -70,6 +70,7 @@
+ #include <linux/smp.h>
+ #include <linux/signal.h>
+ #include <linux/highmem.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -130,7 +131,8 @@
+ 
+ static inline const char * get_task_state(struct task_struct *tsk)
+ {
+-	unsigned int state = tsk->state & (TASK_RUNNING |
++	unsigned int state = (bproc_hook_v(tsk->state,get_task_state,(tsk)))
++					& (TASK_RUNNING |
+ 					   TASK_INTERRUPTIBLE |
+ 					   TASK_UNINTERRUPTIBLE |
+ 					   TASK_ZOMBIE |
+@@ -158,7 +160,8 @@
+ 		"Uid:\t%d\t%d\t%d\t%d\n"
+ 		"Gid:\t%d\t%d\t%d\t%d\n",
+ 		get_task_state(p), p->tgid,
+-		p->pid, p->pid ? p->p_opptr->pid : 0, 0,
++		bproc_hook_imv(p->pid, proc_pid, (p)),
++		bproc_hook_imv(p->p_opptr->pid, proc_ppid, (p)), 0,
+ 		p->uid, p->euid, p->suid, p->fsuid,
+ 		p->gid, p->egid, p->sgid, p->fsgid);
+ 	read_unlock(&tasklist_lock);	
+@@ -305,7 +308,7 @@
+ 	sigset_t sigign, sigcatch;
+ 	char state;
+ 	int res;
+-	pid_t ppid;
++	pid_t pid, ppid;
+ 	struct mm_struct *mm;
+ 
+ 	state = *get_task_state(task);
+@@ -343,12 +346,14 @@
+ 	nice = task->nice;
+ 
+ 	read_lock(&tasklist_lock);
+-	ppid = task->pid ? task->p_opptr->pid : 0;
++	pid  = bproc_hook_imv(task->pid, proc_pid, (task)),
++	ppid = bproc_hook_imv(task->pid ? task->p_opptr->pid : 0,
++			      proc_ppid, (task));
+ 	read_unlock(&tasklist_lock);
+ 	res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+ %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
+ %lu %lu %lu %lu %lu %lu %lu %lu %d %d\n",
+-		task->pid,
++		pid,
+ 		task->comm,
+ 		state,
+ 		ppid,
+Index: linux/kernel/timer.c
+===================================================================
+--- linux.orig/kernel/timer.c	2003-09-03 17:51:01.000000000 -0400
++++ linux/kernel/timer.c	2003-09-03 17:52:04.000000000 -0400
+@@ -22,6 +22,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel_stat.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -754,7 +755,7 @@
+  */
+ asmlinkage long sys_getpid(void)
+ {
+-	return current->tgid;
++	return bproc_hook_imv(current->tgid, sys_getpid, ());
+ }
+ 
+ /*
+@@ -788,7 +789,7 @@
+ 
+ 	parent = me->p_opptr;
+ 	for (;;) {
+-		pid = parent->pid;
++ 		pid = bproc_hook_imv(parent->pid,sys_getppid,(parent));
+ #if CONFIG_SMP
+ {
+ 		struct task_struct *old = parent;
+Index: linux/kernel/signal.c
+===================================================================
+--- linux.orig/kernel/signal.c	2003-09-03 17:51:01.000000000 -0400
++++ linux/kernel/signal.c	2003-09-03 17:52:04.000000000 -0400
+@@ -16,6 +16,8 @@
+ 
+ #include <asm/uaccess.h>
+ 
++#include <linux/bproc.h>
++
+ /*
+  * SLAB caches for signal bits.
+  */
+@@ -548,6 +550,9 @@
+ 	if (sig < SIGRTMIN && sigismember(&t->pending.signal, sig))
+ 		goto out;
+ 
++	if (bproc_hook_v(0, send_sig_info, (sig, info, t)))
++		goto out;
++
+ 	ret = deliver_signal(sig, info, t);
+ out:
+ 	spin_unlock_irqrestore(&t->sigmask_lock, flags);
+@@ -590,6 +595,9 @@
+ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+ {
+ 	int retval = -EINVAL;
++
++	if (bproc_hook_imv(0,kill_pg_info, (sig, info, &pgrp, &retval)) == 1)
++		return retval;
+ 	if (pgrp > 0) {
+ 		struct task_struct *p;
+ 
+@@ -617,6 +625,7 @@
+ kill_sl_info(int sig, struct siginfo *info, pid_t sess)
+ {
+ 	int retval = -EINVAL;
++	/* XXX bproc: Need ways to deal with session leaders...*/
+ 	if (sess > 0) {
+ 		struct task_struct *p;
+ 
+@@ -640,6 +649,9 @@
+ 	int error;
+ 	struct task_struct *p;
+ 
++	if (bproc_hook_imv(0, kill_proc_info,(sig, info, &pid, &error)) == 1)
++		return error;
++
+ 	read_lock(&tasklist_lock);
+ 	p = find_task_by_pid(pid);
+ 	error = -ESRCH;
+@@ -684,6 +696,7 @@
+ 		read_unlock(&tasklist_lock);
+ 		return count ? retval : -ESRCH;
+ 	} else if (pid < 0) {
++		/* XXX pid masq - do PG stuff. */
+ 		return kill_pg_info(sig, info, -pid);
+ 	} else {
+ 		return kill_proc_info(sig, info, pid);
+@@ -815,6 +828,7 @@
+ EXPORT_SYMBOL(recalc_sigpending);
+ EXPORT_SYMBOL(send_sig);
+ EXPORT_SYMBOL(send_sig_info);
++EXPORT_SYMBOL(kill_something_info);
+ EXPORT_SYMBOL(block_all_signals);
+ EXPORT_SYMBOL(unblock_all_signals);
+ 
+Index: linux/kernel/sched.c
+===================================================================
+--- linux.orig/kernel/sched.c	2003-09-03 17:51:05.000000000 -0400
++++ linux/kernel/sched.c	2003-09-03 17:52:04.000000000 -0400
+@@ -30,6 +30,7 @@
+ #include <linux/dump.h>
+ #include <linux/prefetch.h>
+ #include <linux/compiler.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/mmu_context.h>
+@@ -370,6 +371,8 @@
+ 
+ inline int wake_up_process(struct task_struct * p)
+ {
++	if (p->state == TASK_STOPPED && bproc_ismasq(p))
++		bproc_hook(wake_up_process, (p));
+ 	return try_to_wake_up(p, 0);
+ }
+ 
+Index: linux/kernel/ksyms.c
+===================================================================
+--- linux.orig/kernel/ksyms.c	2003-09-03 17:52:02.000000000 -0400
++++ linux/kernel/ksyms.c	2003-09-03 17:52:04.000000000 -0400
+@@ -68,6 +68,10 @@
+ extern void set_device_ro(kdev_t dev,int flag);
+ 
+ extern void *sys_call_table;
++extern struct task_struct *child_reaper;
++#if defined(CONFIG_BINFMT_ELF)
++extern struct linux_binfmt elf_format;
++#endif
+ 
+ extern struct timezone sys_tz;
+ extern int request_dma(unsigned int dmanr, char * deviceID);
+@@ -104,9 +108,17 @@
+ EXPORT_SYMBOL(do_munmap);
+ EXPORT_SYMBOL(do_brk);
+ EXPORT_SYMBOL(exit_mm);
++EXPORT_SYMBOL(do_exit);
+ EXPORT_SYMBOL(exit_files);
+ EXPORT_SYMBOL(exit_fs);
+ EXPORT_SYMBOL(exit_sighand);
++EXPORT_SYMBOL(is_orphaned_pgrp);
++EXPORT_SYMBOL(child_reaper);
++#if defined(CONFIG_BINFMT_ELF)
++EXPORT_SYMBOL(elf_format);
++#endif
++EXPORT_SYMBOL(alloc_uid);
++EXPORT_SYMBOL(free_uid);
+ EXPORT_SYMBOL(copy_fs_struct);
+ EXPORT_SYMBOL_GPL(make_pages_present);
+ 
+@@ -584,6 +596,7 @@
+ EXPORT_SYMBOL(read_ahead);
+ EXPORT_SYMBOL(get_hash_table);
+ EXPORT_SYMBOL(new_inode);
++EXPORT_SYMBOL(get_empty_inode);
+ EXPORT_SYMBOL(insert_inode_hash);
+ EXPORT_SYMBOL(remove_inode_hash);
+ EXPORT_SYMBOL(buffer_insert_inode_queue);
+Index: linux/kernel/fork.c
+===================================================================
+--- linux.orig/kernel/fork.c	2003-09-03 17:52:00.000000000 -0400
++++ linux/kernel/fork.c	2003-09-03 17:52:04.000000000 -0400
+@@ -23,6 +23,8 @@
+ #include <linux/personality.h>
+ #include <linux/compiler.h>
+ 
++#include <linux/bproc.h>
++
+ #include <asm/pgtable.h>
+ #include <asm/pgalloc.h>
+ #include <asm/uaccess.h>
+@@ -413,6 +415,7 @@
+ 
+ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
+ {
++	if (!current->fs) return 0;
+ 	if (clone_flags & CLONE_FS) {
+ 		atomic_inc(&current->fs->count);
+ 		return 0;
+@@ -781,7 +784,8 @@
+ 	 *
+ 	 * Let it rip!
+ 	 */
+-	retval = p->pid;
++ 	if ((retval = bproc_hook_v(p->pid, do_fork, (p, clone_flags))) < 0)
++		goto bad_fork_cleanup_mm;
+ 	p->tgid = retval;
+ 	INIT_LIST_HEAD(&p->thread_group);
+ 
+@@ -805,6 +809,7 @@
+ 	SET_LINKS(p);
+ 	hash_pid(p);
+ 	nr_threads++;
++	bproc_hook(do_fork_2, (p));
+ 	write_unlock_irq(&tasklist_lock);
+ 
+ 	if (p->ptrace & PT_PTRACED)
+@@ -816,6 +821,7 @@
+ 		wait_for_completion(&vfork);
+ 
+ fork_out:
++	bproc_clear_kcall();
+ 	return retval;
+ 
+ bad_fork_cleanup_namespace:
+Index: linux/kernel/exit.c
+===================================================================
+--- linux.orig/kernel/exit.c	2003-09-03 17:52:00.000000000 -0400
++++ linux/kernel/exit.c	2003-09-03 17:52:04.000000000 -0400
+@@ -22,6 +22,8 @@
+ #include <asm/pgtable.h>
+ #include <asm/mmu_context.h>
+ 
++#include <linux/bproc.h>
++
+ extern void sem_exit (void);
+ extern struct task_struct *child_reaper;
+ 
+@@ -47,6 +49,7 @@
+ 		}
+ 		task_unlock(p);
+ #endif
++		bproc_hook(release,(p));
+ 		atomic_dec(&p->user->processes);
+ 		free_uid(p->user);
+ 		unhash_process(p);
+@@ -130,7 +133,8 @@
+ 
+ int is_orphaned_pgrp(int pgrp)
+ {
+-	return will_become_orphaned_pgrp(pgrp, 0);
++	return bproc_hook_imv(will_become_orphaned_pgrp(pgrp, 0),
++			      is_orphaned_pgrp,(pgrp));
+ }
+ 
+ static inline int has_stopped_jobs(int pgrp)
+@@ -170,7 +174,7 @@
+ 			p->self_exec_id++;
+ 
+ 			/* Make sure we're not reparenting to ourselves */
+-			p->p_opptr = child_reaper;
++			p->p_opptr = bproc_hook_v(child_reaper, child_reaper, (p));
+ 
+ 			if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
+ 		}
+@@ -450,6 +454,7 @@
+ #endif
+ 	__exit_mm(tsk);
+ 
++	bproc_hook(do_exit, (tsk,code));
+ 	lock_kernel();
+ 	sem_exit();
+ 	__exit_files(tsk);
+@@ -501,6 +506,7 @@
+ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
+ {
+ 	int flag, retval;
++	pid_t orig_pid = pid;
+ 	DECLARE_WAITQUEUE(wait, current);
+ 	struct task_struct *tsk;
+ 
+@@ -512,6 +518,9 @@
+ 	flag = 0;
+ 	current->state = TASK_INTERRUPTIBLE;
+ 	read_lock(&tasklist_lock);
++	pid = orig_pid;
++	if (bproc_hook_imv(0, sys_wait4_1, (&pid, stat_addr, options, ru, &retval)))
++		goto end_wait4;		/* handler will unlock tasklist_lock */
+ 	tsk = current;
+ 	do {
+ 		struct task_struct *p;
+@@ -535,7 +544,7 @@
+ 			    && !(options & __WALL))
+ 				continue;
+ 			flag = 1;
+-			switch (p->state) {
++			switch (bproc_hook_v(p->state,sys_wait4_2,(p))) {
+ 			case TASK_STOPPED:
+ 				if (!p->exit_code)
+ 					continue;
+@@ -547,7 +556,7 @@
+ 					retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
+ 				if (!retval) {
+ 					p->exit_code = 0;
+-					retval = p->pid;
++					retval = bproc_hook_imv(p->pid, sys_wait4_3, (p));
+ 				}
+ 				goto end_wait4;
+ 			case TASK_ZOMBIE:
+@@ -559,7 +568,7 @@
+ 					retval = put_user(p->exit_code, stat_addr);
+ 				if (retval)
+ 					goto end_wait4; 
+-				retval = p->pid;
++				retval = bproc_hook_imv(p->pid, sys_wait4_3, (p));
+ 				if (p->p_opptr != p->p_pptr) {
+ 					write_lock_irq(&tasklist_lock);
+ 					REMOVE_LINKS(p);
+@@ -569,6 +578,7 @@
+ 					write_unlock_irq(&tasklist_lock);
+ 				} else
+ 					release_task(p);
++ 				bproc_hook_im(sys_wait4_4,(retval, options));
+ 				goto end_wait4;
+ 			default:
+ 				continue;
+@@ -593,6 +603,7 @@
+ end_wait4:
+ 	current->state = TASK_RUNNING;
+ 	remove_wait_queue(&current->wait_chldexit,&wait);
++ 	bproc_clear_kcall();
+ 	return retval;
+ }
+ 
+Index: linux/kernel/sys.c
+===================================================================
+--- linux.orig/kernel/sys.c	2003-09-03 17:51:05.000000000 -0400
++++ linux/kernel/sys.c	2003-09-03 17:52:04.000000000 -0400
+@@ -21,6 +21,8 @@
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ 
++#include <linux/bproc.h>
++
+ /*
+  * this is where the system-wide overflow UID and GID are defined, for
+  * architectures that now have 32-bit UID/GID but didn't in the past
+@@ -448,6 +450,7 @@
+ 	current->fsgid = new_egid;
+ 	current->egid = new_egid;
+ 	current->gid = new_rgid;
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+ 
+@@ -480,6 +483,7 @@
+ 	}
+ 	else
+ 		return -EPERM;
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+   
+@@ -614,6 +618,7 @@
+ 		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+ 	}
+ 
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+ 
+@@ -658,6 +663,8 @@
+ 		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+ 	}
+ 
++	bproc_hook_im(set_creds, ());
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+ 
+@@ -746,6 +753,7 @@
+ 		current->gid = rgid;
+ 	if (sgid != (gid_t) -1)
+ 		current->sgid = sgid;
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+ 
+@@ -803,6 +811,7 @@
+ 		}
+ 	}
+ 
++	if (current->fsuid != old_fsuid) bproc_hook_im(set_creds, ());
+ 	return old_fsuid;
+ }
+ 
+@@ -825,6 +834,8 @@
+ 		}
+ 		current->fsgid = gid;
+ 	}
++
++ 	if (current->fsgid != old_fsgid) bproc_hook_im(set_creds, ());
+ 	return old_fsgid;
+ }
+ 
+@@ -860,6 +871,8 @@
+ 	struct task_struct * p;
+ 	int err = -EINVAL;
+ 
++	bproc_hook_imr(sys_setpgid1, (pid, pgid));
++
+ 	if (!pid)
+ 		pid = current->pid;
+ 	if (!pgid)
+@@ -901,6 +914,7 @@
+ 
+ ok_pgid:
+ 	p->pgrp = pgid;
++	if (bproc_isghost(p)) bproc_hook(sys_setpgid2, (p));
+ 	err = 0;
+ out:
+ 	/* All paths lead to here, thus we are safe. -DaveM */
+@@ -910,6 +924,7 @@
+ 
+ asmlinkage long sys_getpgid(pid_t pid)
+ {
++	bproc_hook_imr(sys_getpgid,(pid));
+ 	if (!pid) {
+ 		return current->pgrp;
+ 	} else {
+@@ -930,23 +945,25 @@
+ asmlinkage long sys_getpgrp(void)
+ {
+ 	/* SMP - assuming writes are word atomic this is fine */
+-	return current->pgrp;
++	return bproc_hook_imv(current->pgrp,sys_getpgrp,());
+ }
+ 
+ asmlinkage long sys_getsid(pid_t pid)
+ {
+ 	if (!pid) {
+-		return current->session;
++ 		return bproc_hook_imv(current->session,sys_getsid1,());
+ 	} else {
+ 		int retval;
+ 		struct task_struct *p;
++ 		if (bproc_hook_imv(0,sys_getsid2, (&pid, &retval))==1)
++ 			return retval;
+ 
+ 		read_lock(&tasklist_lock);
+ 		p = find_task_by_pid(pid);
+ 
+ 		retval = -ESRCH;
+ 		if(p)
+-			retval = p->session;
++ 			retval = bproc_hook_imv(p->session,sys_getsid3,(p));
+ 		read_unlock(&tasklist_lock);
+ 		return retval;
+ 	}
+@@ -957,6 +974,8 @@
+ 	struct task_struct * p;
+ 	int err = -EPERM;
+ 
++	bproc_hook_imr(sys_setsid,());
++
+ 	read_lock(&tasklist_lock);
+ 	for_each_task(p) {
+ 		if (p->pgrp == current->pid)
+@@ -1011,6 +1030,7 @@
+ 	if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
+ 		return -EFAULT;
+ 	current->ngroups = gidsetsize;
++	bproc_hook_im(set_creds, ());
+ 	return 0;
+ }
+ 
+Index: linux/kernel/ptrace.c
+===================================================================
+--- linux.orig/kernel/ptrace.c	2003-09-03 17:51:04.000000000 -0400
++++ linux/kernel/ptrace.c	2003-09-03 17:52:04.000000000 -0400
+@@ -12,6 +12,7 @@
+ #include <linux/mm.h>
+ #include <linux/highmem.h>
+ #include <linux/smp_lock.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
+@@ -25,8 +26,13 @@
+ 	if (!(child->ptrace & PT_PTRACED))
+ 		return -ESRCH;
+ 
+-	if (child->p_pptr != current)
+-		return -ESRCH;
++  	if (child->p_pptr != current &&
++	    !bproc_hook_v(0,ptrace_slave_call,
++			  (PTRACE_DETACH, child, current->bproc.arg)))
++ 		return -ESRCH;
++
++	if (bproc_isghost(child))
++		return 0;
+ 
+ 	if (!kill) {
+ 		if (child->state != TASK_STOPPED)
+@@ -55,6 +61,7 @@
+ 
+ int ptrace_attach(struct task_struct *task)
+ {
++	long ret;
+ 	task_lock(task);
+ 	if (task->pid <= 1)
+ 		goto bad;
+@@ -83,16 +90,22 @@
+ 		task->ptrace |= PT_PTRACE_CAP;
+ 	task_unlock(task);
+ 
++	ret = 0;
+ 	write_lock_irq(&tasklist_lock);
+ 	if (task->p_pptr != current) {
++		if (bproc_isghost(current) && !bproc_isghost(task)) ret = 1;
+ 		REMOVE_LINKS(task);
+ 		task->p_pptr = current;
+ 		SET_LINKS(task);
+ 	}
++	if (bproc_ismasq(task))
++		bproc_hook(ptrace_attach, (task, current->bproc.arg, &ret));
+ 	write_unlock_irq(&tasklist_lock);
+-
+-	send_sig(SIGSTOP, task, 1);
+-	return 0;
++	if (bproc_isghost(task))
++		bproc_hook(ptraceg,(PTRACE_ATTACH, task, 0, 0, &ret, 0));
++	else
++		send_sig(SIGSTOP, task, 1);
++	return ret;
+ 
+ bad:
+ 	task_unlock(task);
+@@ -101,6 +114,7 @@
+ 
+ int ptrace_detach(struct task_struct *child, unsigned int data)
+ {
++	long ret = 0;
+ 	if ((unsigned long) data > _NSIG)
+ 		return	-EIO;
+ 
+@@ -111,14 +125,19 @@
+ 	child->ptrace = 0;
+ 	child->exit_code = data;
+ 	write_lock_irq(&tasklist_lock);
++	if (bproc_isghost(current) && !bproc_isghost(child) && 
++	    child->p_pptr != child->p_opptr)
++		ret = 1;
+ 	REMOVE_LINKS(child);
++	if (bproc_ismasq(child))
++		bproc_hook(ptrace_detach,(child,(long*)&ret));
+ 	child->p_pptr = child->p_opptr;
+ 	SET_LINKS(child);
+ 	write_unlock_irq(&tasklist_lock);
+ 
+ 	/* .. and wake it up. */
+ 	wake_up_process(child);
+-	return 0;
++	return ret;
+ }
+ 
+ /*
+Index: linux/kernel/Makefile
+===================================================================
+--- linux.orig/kernel/Makefile	2003-09-03 17:51:06.000000000 -0400
++++ linux/kernel/Makefile	2003-09-03 17:52:04.000000000 -0400
+@@ -9,7 +9,7 @@
+ 
+ O_TARGET := kernel.o
+ 
+-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
++export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o bproc_hook.o
+ 
+ obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
+ 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
+@@ -24,6 +24,7 @@
+ obj-$(CONFIG_MODULES) += ksyms.o
+ obj-$(CONFIG_PM) += pm.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
++obj-$(CONFIG_BPROC) += bproc_hook.o
+ 
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+Index: linux/kernel/bproc_hook.c
+===================================================================
+--- linux.orig/kernel/bproc_hook.c	2003-09-03 17:52:04.000000000 -0400
++++ linux/kernel/bproc_hook.c	2003-09-03 17:52:04.000000000 -0400
+@@ -0,0 +1,36 @@
++/*-------------------------------------------------------------------------
++ *  bproc_hook.c: Beowulf distributed PID space (bproc) definitions
++ *
++ *  Copyright (C) 2000 by Erik Hendriks <hendriks@scyld.com>
++ *
++ *  This program 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.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * $Id: bproc-patch-2.4.20,v 1.2 2003/12/03 03:13:30 phil Exp $
++ *-----------------------------------------------------------------------*/
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++
++#define bprocdeclhook(ret,func,args) \
++        ret (* bproc_hook_ ## func ## _hook) args = 0;\
++        EXPORT_SYMBOL( bproc_hook_ ## func ## _hook )
++
++#include <linux/bproc.h>
++
++/*
++ * Local variables:
++ * c-basic-offset: 4
++ * End:
++ */
+Index: linux/include/linux/sched.h
+===================================================================
+--- linux.orig/include/linux/sched.h	2003-09-03 17:51:06.000000000 -0400
++++ linux/include/linux/sched.h	2003-09-03 17:52:04.000000000 -0400
+@@ -430,6 +430,14 @@
+ 
+ /* journalling filesystem info */
+ 	void *journal_info;
++
++/* bproc */
++	struct {
++		long flag;
++		long arg;
++		struct bproc_masq_proc_t  *masq;
++		struct bproc_ghost_proc_t *ghost;
++	} bproc;
+ };
+ 
+ /*
+@@ -526,6 +534,7 @@
+     alloc_lock:		SPIN_LOCK_UNLOCKED,				\
+     exit_actions:       NULL,						\
+     journal_info:	NULL,						\
++    bproc:		{0, 0, 0, 0}					\
+ }
+ 
+ 
+Index: linux/include/linux/bproc.h
+===================================================================
+--- linux.orig/include/linux/bproc.h	2003-09-03 17:52:04.000000000 -0400
++++ linux/include/linux/bproc.h	2003-09-03 17:52:04.000000000 -0400
+@@ -0,0 +1,155 @@
++/*-------------------------------------------------------------------------
++ *  bproc.h: Beowulf distributed PID space (bproc) definitions
++ *
++ *  Copyright (C) 1999-2001 by Erik Hendriks <erik@hendriks.cx>
++ *
++ *  This program 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.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * $Id: bproc-patch-2.4.20,v 1.2 2003/12/03 03:13:30 phil Exp $
++ *-----------------------------------------------------------------------*/
++#ifndef _LINUX_BPROC_H
++#define _LINUX_BPROC_H
++
++#include <linux/config.h>
++#include <linux/types.h>
++
++#ifdef CONFIG_BPROC
++
++#ifndef bprocdeclhook
++/* Function pointers for bproc hooks. */
++#define bprocdeclhook(ret,func,args)  extern ret (* bproc_hook_ ## func ## _hook) args
++#endif
++
++struct bproc_ghost_proc_t;
++struct task_struct;
++struct rusage;
++struct siginfo;
++
++/*----- fs/exec.c -------------------------------------------------------*/
++bprocdeclhook(void,  do_execve,       (void));
++/*----- fs/binfmt_script.c ----------------------------------------------*/
++bprocdeclhook(char**,load_script,     (char **));
++/*----- fs/proc/array.c ----------------------------------------------------*/
++bprocdeclhook(void,  refresh_status,  (struct task_struct *));
++bprocdeclhook(int,   get_task_state,  (struct task_struct *));
++bprocdeclhook(int,   proc_pid,        (struct task_struct *));
++bprocdeclhook(int,   proc_ppid,       (struct task_struct *));
++bprocdeclhook(int,   proc1,           (struct task_struct *));
++bprocdeclhook(int,   proc2,           (int));
++bprocdeclhook(int,   proc3,           (void));
++/*----- kernel/timer.c --------------------------------------------------*/
++bprocdeclhook(int,   sys_getpid,      (void));
++bprocdeclhook(int,   sys_getppid,     (struct task_struct *));
++/*----- kernel/sched.c --------------------------------------------------*/
++bprocdeclhook(void,  wake_up_process, (struct task_struct *));
++/*----- kernel/exit.c ---------------------------------------------------*/
++bprocdeclhook(void,  release,         (struct task_struct *));
++bprocdeclhook(int,   is_orphaned_pgrp,(int));
++bprocdeclhook(struct task_struct *,child_reaper,(struct task_struct *));
++bprocdeclhook(void,  do_exit,         (struct task_struct *, long code));
++bprocdeclhook(int,   sys_wait4_1,     (pid_t *, unsigned int *, int,
++				       struct rusage *, int *));
++bprocdeclhook(long,  sys_wait4_2,     (struct task_struct *));
++bprocdeclhook(int,   sys_wait4_3,     (struct task_struct *));
++bprocdeclhook(void,  sys_wait4_4,     (pid_t, int options));
++/*----- kernel/fork.c ---------------------------------------------------*/
++bprocdeclhook(int,   do_fork,         (struct task_struct *, unsigned long));
++bprocdeclhook(void,  do_fork_2,       (struct task_struct *));
++/*----- kernel/signal.c -------------------------------------------------*/
++bprocdeclhook(int,   send_sig_info,   (int, struct siginfo *,
++				       struct task_struct *));
++bprocdeclhook(int,   kill_pg_info,    (int, struct siginfo *, pid_t *, int *));
++bprocdeclhook(int,   kill_proc_info,  (int, struct siginfo *, pid_t *, int *));
++/*----- kernel/sys.c ----------------------------------------------------*/
++bprocdeclhook(int,   sys_setpgid1,    (pid_t, pid_t));
++bprocdeclhook(void,  sys_setpgid2,    (struct task_struct *p));
++bprocdeclhook(int,   sys_getpgid,     (pid_t pid));
++bprocdeclhook(int,   sys_getpgrp,     (void));
++bprocdeclhook(int,   sys_getsid1,     (void));
++bprocdeclhook(int,   sys_getsid2,     (pid_t *pid, int *error));
++bprocdeclhook(int,   sys_getsid3,     (struct task_struct *p));
++bprocdeclhook(int,   sys_setsid,      (void));
++bprocdeclhook(void,  set_creds,       (void));
++/*----- arch/???/kernel/ptrace.c,signal.c -------------------------------*/
++bprocdeclhook(void,  stop_notify,     (int));
++bprocdeclhook(int,   ptracem,         (long, long *, long, long,
++				       long *, long *));
++bprocdeclhook(void,  ptrace_attach,   (struct task_struct *, long, long *));
++bprocdeclhook(void,  ptraceg,         (long, struct task_struct *, long,
++				       long, long *, long *));
++bprocdeclhook(int,   ptrace_slave_call,(long, struct task_struct *, long));
++bprocdeclhook(void,  ptrace_detach,   (struct task_struct *, long *));
++bprocdeclhook(int,   sys_execve,      (struct pt_regs *, char *,
++				       char **, char **));
++
++/* Macro suffixes:
++ * (none)   = execute this hook if it's present.
++ * im       = if masq'ed
++ * nkc      = no kernel call (kcall must be 0 to call hook)
++ * r        = return the value of this hook
++ * v        = hook returns a value.
++ */
++#define hookname(func) bproc_hook_ ## func ## _hook
++#define bproc_hook(func,args)          do{if(hookname(func))hookname(func)args;}while(0)
++#define bproc_hook_im(func,args)       do{if(hookname(func)&&current->bproc.masq)hookname(func)args;}while(0)
++#define bproc_hook_imr(func,args)      do{if(hookname(func)&&current->bproc.masq)return hookname(func)args;}while(0)
++#define bproc_hook_v(defl,func,args)   ( hookname(func)                      ?hookname(func)args:defl)
++#define bproc_hook_imv(defl,func,args) ((hookname(func)&&current->bproc.masq)?hookname(func)args:defl)
++
++#define bproc_isghost(tsk)             ((tsk)->bproc.ghost != 0)
++#define bproc_ismasq(tsk)              ((tsk)->bproc.masq != 0)
++#define bproc_set_arg(x)               do{current->bproc.arg=(x);}while(0)
++
++/* Kernel call weirdness... a kernel call is a call made from the
++ * kernel which we do not want to be subject to the usual rules for
++ * PID masquerading.  This is mostly used for drivers which create and
++ * possibly wait for kernel threads which they create.  These
++ * functions are called from the relevant places within the kernel
++ * (like within kernel_thread) to set a flag so that things will be
++ * handled correctly later on. */
++static inline void bproc_no_kcall(void) {
++    current->bproc.flag = (current->bproc.flag & ~3) | 2;
++}
++static inline void bproc_clear_kcall(void) {
++    current->bproc.flag &= ~3;
++}
++static inline void bproc_kcall(void) {
++    if (current->bproc.flag & 2)
++	bproc_clear_kcall();
++    else
++	current->bproc.flag |= 1; /* set kernel call flag */
++}
++
++#else
++/* Stubs for when hooks are not compiled in */
++#define bproc_hook(func,args)          do{}while(0)
++#define bproc_hook_im(func,args)       do{}while(0)
++#define bproc_hook_imr(func,args)      do{}while(0)
++#define bproc_hook_v(defl,func,args)   (defl)
++#define bproc_hook_imv(defl,func,args) (defl)
++#define bproc_isghost(tsk)             (0)
++#define bproc_ismasq(tsk)              (0)
++#define bproc_set_arg(x)               do{}while(0)
++#define bproc_no_kcall()               do{}while(0)
++#define bproc_clear_kcall()            do{}while(0)
++#define bproc_kcall()                  do{}while(0)
++#endif
++#endif
++
++/*
++ * Local variables:
++ * c-basic-offset: 4
++ * End:
++ */
+Index: linux/include/asm-i386/unistd.h
+===================================================================
+--- linux.orig/include/asm-i386/unistd.h	2002-11-28 18:53:15.000000000 -0500
++++ linux/include/asm-i386/unistd.h	2003-09-03 17:52:04.000000000 -0400
+@@ -349,6 +349,7 @@
+ 
+ #ifdef __KERNEL_SYSCALLS__
+ 
++#include <linux/bproc.h>
+ /*
+  * we need this inline - forking from kernel space will result
+  * in NO COPY ON WRITE (!!!), until an execve is executed. This
+@@ -373,7 +374,16 @@
+ static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+ static inline _syscall1(int,close,int,fd)
+ static inline _syscall1(int,_exit,int,exitcode)
+-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
++static inline pid_t waitpid(pid_t pid, int *wait_stat, int options) {
++	long __res;
++	bproc_kcall();
++	__asm__ volatile ("int $0x80"
++			  : "=a" (__res)
++			  : "0" (__NR_waitpid),"b" ((long)(pid)),"c" ((long)(wait_stat)),
++			  "d" ((long)(options)));
++	__syscall_return(pid_t,__res);
++}
++
+ static inline _syscall1(int,delete_module,const char *,name)
+ 
+ static inline pid_t wait(int * wait_stat)
+Index: linux/include/asm-alpha/unistd.h
+===================================================================
+--- linux.orig/include/asm-alpha/unistd.h	2002-08-02 20:39:45.000000000 -0400
++++ linux/include/asm-alpha/unistd.h	2003-09-03 17:52:04.000000000 -0400
+@@ -519,6 +519,7 @@
+ 
+ #include <linux/string.h>
+ #include <linux/signal.h>
++#include <linux/bproc.h>
+ 
+ extern void sys_idle(void);
+ static inline void idle(void)
+@@ -591,11 +592,13 @@
+ 
+ static inline pid_t waitpid(int pid, int * wait_stat, int flags)
+ {
++	bproc_kcall();
+ 	return sys_wait4(pid, wait_stat, flags, NULL);
+ }
+ 
+ static inline pid_t wait(int * wait_stat)
+ {
++	bproc_kcall();
+ 	return waitpid(-1,wait_stat,0);
+ }
+ 
+Index: linux/net/socket.c
+===================================================================
+--- linux.orig/net/socket.c	2003-09-03 17:51:05.000000000 -0400
++++ linux/net/socket.c	2003-09-03 17:52:04.000000000 -0400
+@@ -111,7 +111,7 @@
+  *	in the operation structures but are done directly via the socketcall() multiplexor.
+  */
+ 
+-static struct file_operations socket_file_ops = {
++struct file_operations socket_file_ops = {
+ 	llseek:		no_llseek,
+ 	read:		sock_read,
+ 	write:		sock_write,
+@@ -298,13 +298,13 @@
+ 	return sb;
+ }
+ 
+-static struct vfsmount *sock_mnt;
++struct vfsmount *sock_mnt;
+ static DECLARE_FSTYPE(sock_fs_type, "sockfs", sockfs_read_super, FS_NOMOUNT);
+ static int sockfs_delete_dentry(struct dentry *dentry)
+ {
+ 	return 1;
+ }
+-static struct dentry_operations sockfs_dentry_operations = {
++struct dentry_operations sockfs_dentry_operations = {
+ 	d_delete:	sockfs_delete_dentry,
+ };
+ 
+Index: linux/net/netsyms.c
+===================================================================
+--- linux.orig/net/netsyms.c	2003-09-03 17:52:04.000000000 -0400
++++ linux/net/netsyms.c	2003-09-03 17:52:04.000000000 -0400
+@@ -599,4 +599,11 @@
+ EXPORT_SYMBOL(wireless_send_event);
+ #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
+ 
++extern struct vfsmount *sock_mnt;
++extern struct dentry_operations sockfs_dentry_operations;
++extern struct file_operations socket_file_ops;
++EXPORT_SYMBOL(sock_mnt);
++EXPORT_SYMBOL(sockfs_dentry_operations);
++EXPORT_SYMBOL(socket_file_ops);
++
+ #endif  /* CONFIG_NET */
+Index: linux/arch/i386/config.in
+===================================================================
+--- linux.orig/arch/i386/config.in	2003-09-03 17:51:06.000000000 -0400
++++ linux/arch/i386/config.in	2003-09-03 17:52:04.000000000 -0400
+@@ -285,6 +285,7 @@
+ 
+ bool 'System V IPC' CONFIG_SYSVIPC
+ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
++bool 'Beowulf Distributed Process Space' CONFIG_BPROC
+ bool 'Sysctl support' CONFIG_SYSCTL
+ if [ "$CONFIG_PROC_FS" = "y" ]; then
+    choice 'Kernel core (/proc/kcore) format' \
+Index: linux/arch/i386/kernel/signal.c
+===================================================================
+--- linux.orig/arch/i386/kernel/signal.c	2002-08-02 20:39:42.000000000 -0400
++++ linux/arch/i386/kernel/signal.c	2003-09-03 17:52:04.000000000 -0400
+@@ -20,6 +20,7 @@
+ #include <linux/stddef.h>
+ #include <linux/tty.h>
+ #include <linux/personality.h>
++#include <linux/bproc.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+ #include <asm/i387.h>
+@@ -612,6 +613,7 @@
+ 			/* Let the debugger run.  */
+ 			current->exit_code = signr;
+ 			current->state = TASK_STOPPED;
++			bproc_hook_im(stop_notify,(signr));
+ 			notify_parent(current, SIGCHLD);
+ 			schedule();
+ 
+@@ -670,6 +672,7 @@
+ 				struct signal_struct *sig;
+ 				current->state = TASK_STOPPED;
+ 				current->exit_code = signr;
++				bproc_hook_im(stop_notify,(signr));
+ 				sig = current->p_pptr->sig;
+ 				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+ 					notify_parent(current, SIGCHLD);
+Index: linux/arch/i386/kernel/ptrace.c
+===================================================================
+--- linux.orig/arch/i386/kernel/ptrace.c	2002-08-02 20:39:42.000000000 -0400
++++ linux/arch/i386/kernel/ptrace.c	2003-09-03 17:52:04.000000000 -0400
+@@ -21,6 +21,8 @@
+ #include <asm/i387.h>
+ #include <asm/debugreg.h>
+ 
++#include <linux/bproc.h>
++
+ /*
+  * does not yet catch signals sent when the child dies.
+  * in exit.c or in signal.c.
+@@ -152,6 +154,15 @@
+ 	struct task_struct *child;
+ 	struct user * dummy = NULL;
+ 	int i, ret;
++	long orig_pid;
++
++	orig_pid = pid;
++ retry_ptrace:
++	pid = orig_pid;
++	if (bproc_hook_imv(0, ptracem, (request,&pid,addr,data,(long*)&ret,0))) {
++		if (ret == -ELOOP) goto retry_ptrace;
++		return ret;
++	}
+ 
+ 	lock_kernel();
+ 	ret = -EPERM;
+@@ -178,14 +189,21 @@
+ 		goto out_tsk;
+ 
+ 	if (request == PTRACE_ATTACH) {
++		bproc_set_arg(addr);
+ 		ret = ptrace_attach(child);
+ 		goto out_tsk;
+ 	}
+ 
++	bproc_set_arg(request == PTRACE_DETACH ? addr : 0);
+ 	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ 	if (ret < 0)
+ 		goto out_tsk;
+ 
++	if (bproc_isghost(child)) {
++		bproc_hook(ptraceg, (request,child,addr,data,(long*)&ret,0));
++		goto out_tsk;
++	}
++
+ 	switch (request) {
+ 	/* when I and D space are separate, these will need to be fixed. */
+ 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+@@ -427,6 +445,7 @@
+ 	free_task_struct(child);
+ out:
+ 	unlock_kernel();
++	if (ret == -ELOOP) goto retry_ptrace;
+ 	return ret;
+ }
+ 
+@@ -440,6 +459,7 @@
+ 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ 					? 0x80 : 0);
+ 	current->state = TASK_STOPPED;
++	bproc_hook_im(stop_notify,(SIGTRAP));
+ 	notify_parent(current, SIGCHLD);
+ 	schedule();
+ 	/*
+Index: linux/arch/i386/kernel/process.c
+===================================================================
+--- linux.orig/arch/i386/kernel/process.c	2003-09-03 17:51:02.000000000 -0400
++++ linux/arch/i386/kernel/process.c	2003-09-03 17:52:04.000000000 -0400
+@@ -33,6 +33,7 @@
+ #include <linux/reboot.h>
+ #include <linux/init.h>
+ #include <linux/mc146818rtc.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -489,6 +490,7 @@
+ {
+ 	long retval, d0;
+ 
++	bproc_kcall();
+ 	__asm__ __volatile__(
+ 		"movl %%esp,%%esi\n\t"
+ 		"int $0x80\n\t"		/* Linux/i386 system call */
+@@ -789,6 +791,11 @@
+ 		current->ptrace &= ~PT_DTRACE;
+ 	putname(filename);
+ out:
++	if (error == -ENOENT)
++		error = bproc_hook_imv(error, sys_execve,
++				       (&regs,(char *)regs.ebx,
++					(char **)regs.ecx, (char **)regs.edx));
++
+ 	return error;
+ }
+ 
+Index: linux/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux.orig/arch/i386/kernel/i386_ksyms.c	2003-09-03 17:51:04.000000000 -0400
++++ linux/arch/i386/kernel/i386_ksyms.c	2003-09-03 17:52:04.000000000 -0400
+@@ -107,6 +107,11 @@
+ EXPORT_SYMBOL(__generic_copy_to_user);
+ EXPORT_SYMBOL(strnlen_user);
+ 
++asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
++EXPORT_SYMBOL_NOVERS(ret_from_sys_call);
++asmlinkage void syscall_trace(void);
++EXPORT_SYMBOL(syscall_trace);
++
+ EXPORT_SYMBOL(pci_alloc_consistent);
+ EXPORT_SYMBOL(pci_free_consistent);
+ 
+Index: linux/arch/alpha/config.in
+===================================================================
+--- linux.orig/arch/alpha/config.in	2003-09-03 17:51:04.000000000 -0400
++++ linux/arch/alpha/config.in	2003-09-03 17:52:04.000000000 -0400
+@@ -271,6 +271,7 @@
+ 
+ bool 'Networking support' CONFIG_NET
+ bool 'System V IPC' CONFIG_SYSVIPC
++bool 'Beowulf Distributed Process Space' CONFIG_BPROC
+ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+ bool 'Sysctl support' CONFIG_SYSCTL
+ if [ "$CONFIG_PROC_FS" = "y" ]; then
+Index: linux/arch/alpha/kernel/signal.c
+===================================================================
+--- linux.orig/arch/alpha/kernel/signal.c	2002-08-02 20:39:42.000000000 -0400
++++ linux/arch/alpha/kernel/signal.c	2003-09-03 17:52:04.000000000 -0400
+@@ -23,6 +23,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/sigcontext.h>
+ #include <asm/ucontext.h>
++#include <linux/bproc.h>
+ 
+ #include "proto.h"
+ 
+@@ -643,6 +644,7 @@
+ 			/* Let the debugger run.  */
+ 			current->exit_code = signr;
+ 			current->state = TASK_STOPPED;
++			bproc_hook_im(stop_notify,(signr));
+ 			notify_parent(current, SIGCHLD);
+ 			schedule();
+ 			single_stepping |= ptrace_cancel_bpt(current);
+@@ -701,6 +703,7 @@
+ 			case SIGSTOP:
+ 				current->state = TASK_STOPPED;
+ 				current->exit_code = signr;
++				bproc_hook_im(stop_notify,(signr));
+ 				if (!(current->p_pptr->sig->action[SIGCHLD-1]
+ 				      .sa.sa_flags & SA_NOCLDSTOP))
+ 					notify_parent(current, SIGCHLD);
+Index: linux/arch/alpha/kernel/osf_sys.c
+===================================================================
+--- linux.orig/arch/alpha/kernel/osf_sys.c	2002-08-02 20:39:42.000000000 -0400
++++ linux/arch/alpha/kernel/osf_sys.c	2003-09-03 17:52:04.000000000 -0400
+@@ -33,6 +33,7 @@
+ #include <linux/file.h>
+ #include <linux/types.h>
+ #include <linux/ipc.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/fpu.h>
+ #include <asm/io.h>
+@@ -219,8 +220,8 @@
+ 	 * isn't actually going to matter, as if the parent happens
+ 	 * to change we can happily return either of the pids.
+ 	 */
+-	(&regs)->r20 = tsk->p_opptr->tgid;
+-	return tsk->tgid;
++	(&regs)->r20 = bproc_hook_imv(tsk->p_opptr->tgid,sys_getppid,(tsk->p_opptr));
++	return bproc_hook_imv(tsk->tgid,sys_getpid,());
+ }
+ 
+ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
+Index: linux/arch/alpha/kernel/entry.S
+===================================================================
+--- linux.orig/arch/alpha/kernel/entry.S	2003-09-03 17:52:01.000000000 -0400
++++ linux/arch/alpha/kernel/entry.S	2003-09-03 17:52:04.000000000 -0400
+@@ -212,8 +212,10 @@
+  * stack buildup, as we can't do system calls from kernel space.
+  */
+ .align 3
++.globl  kernel_clone
+ .ent	kernel_clone
+ kernel_clone:
++	ldgp	$29,0($27)	/* we can be called from a module */
+ 	.frame $30, 0, $26
+ 	.prologue 0
+ 	subq	$30,6*8,$30
+@@ -230,6 +232,23 @@
+ 	br	ret_from_sys_call
+ .end	kernel_clone
+ 
++.align 3
++.globl  ret_to_user_space
++.ent    ret_to_user_space
++ret_to_user_space:	
++	ldgp $29, 0($27)	/* We can jump here from a module */
++	bsr $1, undo_switch_stack
++	lda  $1, 8($31)		/* Set ps = 8 */
++	stq  $1, 0xB8($30)
++
++	/* This tidbit ripped from entSys.  Is this appropriate here ? */
++	blt	$0,syscall_error	/* the call failed */
++	stq	$0,0($30)
++	stq	$31,72($30)		/* a3=0 => no error */
++
++	br ret_from_sys_call
++.end    ret_to_user_space
++	
+ /*
+  * arch_kernel_thread(fn, arg, clone_flags)
+  */
+@@ -240,19 +259,24 @@
+ 	ldgp	$29,0($27)	/* we can be called from a module */
+ 	.frame $30, 4*8, $26
+ 	subq	$30,4*8,$30
++	stq	$11,24($30)
+ 	stq	$10,16($30)
+ 	stq	$9,8($30)
+-	lda	$0,CLONE_VM
+ 	stq	$26,0($30)
+ 	.prologue 1
+ 	mov	$16,$9		/* save fn */		
+ 	mov	$17,$10		/* save arg */
+-	or	$18,$0,$16	/* shuffle flags to front; add CLONE_VM.  */
+-	bsr	$26,kernel_clone
++	mov	$18,$11		/* save flags */
++	bsr	$26,bproc_kcall_
++	lda	$0,CLONE_VM
++	or	$11,$0,$16	/* shuffle flags to front; add CLONE_VM.  */
++	jsr	$26,kernel_clone
++	ldgp	$29,0($26)
+ 	bne	$20,1f		/* $20 is non-zero in child */
+ 	ldq	$26,0($30)
+ 	ldq	$9,8($30)
+ 	ldq	$10,16($30)
++	ldq	$11,24($30)
+ 	addq	$30,4*8,$30
+ 	ret	$31,($26),1
+ /* this is in child: look out as we don't have any stack here.. */
+@@ -290,6 +314,7 @@
+ .end	__kernel_execve
+ 
+ .align 3
++.globl  do_switch_stack
+ .ent	do_switch_stack
+ do_switch_stack:
+ 	lda	$30,-SWITCH_STACK_SIZE($30)
+@@ -339,6 +364,7 @@
+ .end do_switch_stack
+ 
+ .align 3
++.globl  undo_switch_stack
+ .ent	undo_switch_stack
+ undo_switch_stack:
+ 	ldq	$9,0($30)
+@@ -1062,7 +1088,7 @@
+ 	.quad alpha_ni_syscall
+ 	.quad alpha_ni_syscall
+ 	.quad alpha_ni_syscall			/* 290 */
+-	.quad alpha_ni_syscall
++	.quad sys_ni_syscall			/* bproc: please shut up... */
+ 	.quad alpha_ni_syscall
+ 	.quad alpha_ni_syscall
+ 	.quad alpha_ni_syscall
+Index: linux/arch/alpha/kernel/alpha_ksyms.c
+===================================================================
+--- linux.orig/arch/alpha/kernel/alpha_ksyms.c	2002-08-02 20:39:42.000000000 -0400
++++ linux/arch/alpha/kernel/alpha_ksyms.c	2003-09-03 17:52:04.000000000 -0400
+@@ -164,6 +164,17 @@
+ EXPORT_SYMBOL(sys_sync);
+ EXPORT_SYMBOL(sys_wait4);
+ 
++extern void kernel_clone(void);
++extern void ret_to_user_space(void);
++extern void do_switch_stack(void);
++extern void undo_switch_stack(void);
++asmlinkage void syscall_trace(void);
++EXPORT_SYMBOL_NOVERS(kernel_clone);
++EXPORT_SYMBOL_NOVERS(ret_to_user_space);
++EXPORT_SYMBOL_NOVERS(do_switch_stack);
++EXPORT_SYMBOL_NOVERS(undo_switch_stack);
++EXPORT_SYMBOL(syscall_trace);
++
+ /* Networking helper routines. */
+ EXPORT_SYMBOL(csum_tcpudp_magic);
+ EXPORT_SYMBOL(ip_compute_csum);
+Index: linux/arch/alpha/kernel/process.c
+===================================================================
+--- linux.orig/arch/alpha/kernel/process.c	2001-09-30 15:26:08.000000000 -0400
++++ linux/arch/alpha/kernel/process.c	2003-09-03 17:52:04.000000000 -0400
+@@ -30,6 +30,7 @@
+ #include <linux/reboot.h>
+ #include <linux/tty.h>
+ #include <linux/console.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/reg.h>
+ #include <asm/uaccess.h>
+@@ -430,6 +431,9 @@
+ 	error = do_execve(filename, argv, envp, &regs);
+ 	putname(filename);
+ out:
++	if (error == -ENOENT)
++		error = bproc_hook_imv(error, sys_execve,
++				       (&regs,ufilename,argv,envp));
+ 	return error;
+ }
+ 
+@@ -465,3 +469,10 @@
+ 	}
+ 	return pc;
+ }
++
++/* This is usually inlined.  It's packaged in a function here so that
++ * we can call it from ASM code on this architecture. */
++void bproc_kcall_(void)
++{
++	bproc_kcall();
++}
+Index: linux/arch/alpha/kernel/ptrace.c
+===================================================================
+--- linux.orig/arch/alpha/kernel/ptrace.c	2001-09-18 20:03:51.000000000 -0400
++++ linux/arch/alpha/kernel/ptrace.c	2003-09-03 17:52:04.000000000 -0400
+@@ -13,6 +13,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
+ #include <linux/slab.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -248,7 +249,15 @@
+ 	   int a4, int a5, struct pt_regs regs)
+ {
+ 	struct task_struct *child;
+-	long ret;
++	long ret, orig_pid;
++	
++ 	orig_pid = pid;
++ retry_ptrace:
++ 	pid = orig_pid;
++ 	if (bproc_hook_imv(0, ptracem, (request,&pid,addr,data,&ret,&regs.r0))) {
++		if (ret == -ELOOP && regs.r0) goto retry_ptrace;
++		return ret;
++ 	}
+ 
+ 	lock_kernel();
+ 	DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
+@@ -274,6 +283,7 @@
+ 	if (!child)
+ 		goto out_notsk;
+ 	if (request == PTRACE_ATTACH) {
++		bproc_set_arg(addr);
+ 		ret = ptrace_attach(child);
+ 		goto out;
+ 	}
+@@ -282,15 +292,20 @@
+ 		DBG(DBG_MEM, ("child not traced\n"));
+ 		goto out;
+ 	}
++	if (child->p_pptr != current &&
++	    !bproc_hook_v(0,ptrace_slave_call,(request,child,addr))) {
++		DBG(DBG_MEM, ("child not parent of this process\n"));
++		goto out;
++	}
++	if (bproc_isghost(child)) {
++		bproc_hook(ptraceg,(request,child,addr,data,&ret,&regs.r0));
++		goto out;
++	}
+ 	if (child->state != TASK_STOPPED) {
+ 		DBG(DBG_MEM, ("child process not stopped\n"));
+ 		if (request != PTRACE_KILL)
+ 			goto out;
+ 	}
+-	if (child->p_pptr != current) {
+-		DBG(DBG_MEM, ("child not parent of this process\n"));
+-		goto out;
+-	}
+ 
+ 	switch (request) {
+ 	/* When I and D space are separate, these will need to be fixed.  */
+@@ -384,6 +399,7 @@
+ 	free_task_struct(child);
+  out_notsk:
+ 	unlock_kernel();
++	if (ret == -ELOOP && regs.r0) goto retry_ptrace;
+ 	return ret;
+ }
+ 
+@@ -395,6 +411,7 @@
+ 		return;
+ 	current->exit_code = SIGTRAP;
+ 	current->state = TASK_STOPPED;
++	bproc_hook_im(stop_notify,(SIGTRAP));
+ 	notify_parent(current, SIGCHLD);
+ 	schedule();
+ 	/*
+Index: linux/arch/ppc/config.in
+===================================================================
+--- linux.orig/arch/ppc/config.in	2002-11-28 18:53:11.000000000 -0500
++++ linux/arch/ppc/config.in	2003-09-03 17:52:04.000000000 -0400
+@@ -162,6 +162,7 @@
+ bool 'Networking support' CONFIG_NET
+ bool 'Sysctl support' CONFIG_SYSCTL
+ bool 'System V IPC' CONFIG_SYSVIPC
++bool 'Beowulf Distributed Process Space' CONFIG_BPROC
+ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+ 
+ # only elf supported, a.out is not -- Cort
+Index: linux/arch/ppc/kernel/signal.c
+===================================================================
+--- linux.orig/arch/ppc/kernel/signal.c	2002-11-28 18:53:11.000000000 -0500
++++ linux/arch/ppc/kernel/signal.c	2003-09-03 17:52:04.000000000 -0400
+@@ -29,6 +29,7 @@
+ #include <linux/unistd.h>
+ #include <linux/stddef.h>
+ #include <linux/elf.h>
++#include <linux/bproc.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -579,6 +580,7 @@
+ 			/* Let the debugger run.  */
+ 			current->exit_code = signr;
+ 			current->state = TASK_STOPPED;
++			bproc_hook_im(stop_notify,(signr));
+ 			notify_parent(current, SIGCHLD);
+ 			schedule();
+ 
+@@ -636,6 +638,7 @@
+ 			case SIGSTOP:
+ 				current->state = TASK_STOPPED;
+ 				current->exit_code = signr;
++				bproc_hook_im(stop_notify,(signr));
+ 				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+ 					notify_parent(current, SIGCHLD);
+ 				schedule();
+Index: linux/arch/ppc/kernel/ptrace.c
+===================================================================
+--- linux.orig/arch/ppc/kernel/ptrace.c	2002-11-28 18:53:11.000000000 -0500
++++ linux/arch/ppc/kernel/ptrace.c	2003-09-03 17:52:04.000000000 -0400
+@@ -27,6 +27,7 @@
+ #include <linux/errno.h>
+ #include <linux/ptrace.h>
+ #include <linux/user.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/page.h>
+@@ -161,6 +162,15 @@
+ {
+ 	struct task_struct *child;
+ 	int ret = -EPERM;
++	long orig_pid;
++
++	orig_pid = pid;
++ retry_ptrace:
++	pid = orig_pid;
++	if (bproc_hook_imv(0, ptracem,(request,&pid,addr,data,(long*)&ret,0))){
++		if (ret == -ELOOP) goto retry_ptrace;
++		return ret;
++	}
+ 
+ 	lock_kernel();
+ 	if (request == PTRACE_TRACEME) {
+@@ -186,14 +196,21 @@
+ 		goto out_tsk;
+ 
+ 	if (request == PTRACE_ATTACH) {
++		bproc_set_arg(addr);
+ 		ret = ptrace_attach(child);
+ 		goto out_tsk;
+ 	}
+ 
++	bproc_set_arg(request == PTRACE_DETACH ? addr : 0);
+ 	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ 	if (ret < 0)
+ 		goto out_tsk;
+ 
++	if (bproc_isghost(child)) {
++		bproc_hook(ptraceg, (request,child,addr,data,(long*)&ret,0));
++		goto out_tsk;
++	}
++
+ 	switch (request) {
+ 	/* when I and D space are separate, these will need to be fixed. */
+ 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+@@ -342,6 +359,7 @@
+ 	free_task_struct(child);
+ out:
+ 	unlock_kernel();
++	if (ret == -ELOOP) goto retry_ptrace;
+ 	return ret;
+ }
+ 
+@@ -352,6 +370,7 @@
+ 		return;
+ 	current->exit_code = SIGTRAP;
+ 	current->state = TASK_STOPPED;
++	bproc_hook_im(stop_notify,(SIGTRAP));
+ 	notify_parent(current, SIGCHLD);
+ 	schedule();
+ 	/*
+Index: linux/arch/ppc/kernel/ppc_ksyms.c
+===================================================================
+--- linux.orig/arch/ppc/kernel/ppc_ksyms.c	2002-11-28 18:53:11.000000000 -0500
++++ linux/arch/ppc/kernel/ppc_ksyms.c	2003-09-03 17:52:04.000000000 -0400
+@@ -366,3 +366,5 @@
+ EXPORT_SYMBOL_NOVERS(agp_special_page);
+ #endif /* defined(CONFIG_ALL_PPC) */
+ 
++asmlinkage void ret_from_syscall_1(void) __asm__("ret_from_syscall_1");
++EXPORT_SYMBOL_NOVERS(ret_from_syscall_1);
+Index: linux/arch/ppc/kernel/misc.S
+===================================================================
+--- linux.orig/arch/ppc/kernel/misc.S	2003-09-03 17:51:02.000000000 -0400
++++ linux/arch/ppc/kernel/misc.S	2003-09-03 17:52:04.000000000 -0400
+@@ -901,6 +901,20 @@
+  *   arch_kernel_thread(fn, arg, flags)
+  */
+ _GLOBAL(arch_kernel_thread)
++	stwu	r1,-28(r1)	/* Setup stack frame to save args */
++	mflr	r0
++	stw     r3, 16(r1)
++	stw     r4, 20(r1)
++	stw     r5, 24(r1)
++	stw	r0, 32(r1)
++	bl	bproc_kcall_	/* Call bproc_kcall_ hook */
++	lwz	r0, 32(r1)	/* Restore stack + arguments */
++	lwz     r5, 24(r1)
++	lwz     r4, 20(r1)
++	lwz     r3, 16(r1)
++	mtlr	r0
++	addi	r1,r1,28
++
+ 	mr	r6,r3		/* function */
+ 	ori	r3,r5,CLONE_VM	/* flags */
+ 	li	r0,__NR_clone
+@@ -941,7 +955,29 @@
+ SYSCALL(execve)
+ SYSCALL(open)
+ SYSCALL(close)
+-SYSCALL(waitpid)
++_GLOBAL(waitpid)
++	stwu	r1,-28(r1)	/* Setup stack frame to save args */
++	mflr	r0
++	stw     r3, 16(r1)
++	stw     r4, 20(r1)
++	stw     r5, 24(r1)
++	stw	r0, 32(r1)
++	bl	bproc_kcall_	/* Call bproc_kcall_ hook */
++	lwz	r0, 32(r1)	/* Restore stack + arguments */
++	lwz     r5, 24(r1)
++	lwz     r4, 20(r1)
++	lwz     r3, 16(r1)
++	mtlr	r0
++	addi	r1,r1,28
++	
++	li	r0,__NR_waitpid
++	sc
++	bnslr
++	lis	r4,errno@ha
++	stw	r3,errno@l(r4)
++	li	r3,-1
++	blr
++
+ SYSCALL(fork)
+ SYSCALL(delete_module)
+ SYSCALL(_exit)
+Index: linux/arch/ppc/kernel/process.c
+===================================================================
+--- linux.orig/arch/ppc/kernel/process.c	2001-11-26 08:29:17.000000000 -0500
++++ linux/arch/ppc/kernel/process.c	2003-09-03 17:52:04.000000000 -0400
+@@ -34,6 +34,7 @@
+ #include <linux/user.h>
+ #include <linux/elf.h>
+ #include <linux/init.h>
++#include <linux/bproc.h>
+ 
+ #include <asm/pgtable.h>
+ #include <asm/uaccess.h>
+@@ -443,6 +444,10 @@
+ 		current->ptrace &= ~PT_DTRACE;
+ 	putname(filename);
+ out:
++	if (error == -ENOENT)
++		error = bproc_hook_imv(error, sys_execve,
++				       (regs,(char*)a0,(char**)a1,(char**)a2));
++
+ 	return error;
+ }
+ 
+@@ -605,3 +610,10 @@
+ 	} while (count++ < 16);
+ 	return 0;
+ }
++
++/* This is usually inlined.  It's packaged in a function here so that
++ * we can call it from ASM code on this architecture. */
++void bproc_kcall_(void)
++{
++	bproc_kcall();
++}
+Index: linux/fs/inode.c
+===================================================================
+--- linux.orig/fs/inode.c	2003-09-03 17:52:00.000000000 -0400
++++ linux/fs/inode.c	2003-09-03 17:52:04.000000000 -0400
+@@ -816,6 +816,76 @@
+ 	return inode;
+ }
+ 
++/*
++ * This just initializes the inode fields
++ * to known values before returning the inode..
++ *
++ * i_sb, i_ino, i_count, i_state and the lists have
++ * been initialized elsewhere..
++ */
++static void clean_inode(struct inode *inode)
++{
++	static struct address_space_operations empty_aops;
++	static struct inode_operations empty_iops;
++	static struct file_operations empty_fops;
++	memset(&inode->u, 0, sizeof(inode->u));
++	inode->i_sock = 0;
++	inode->i_op = &empty_iops;
++	inode->i_fop = &empty_fops;
++	inode->i_nlink = 1;
++	atomic_set(&inode->i_writecount, 0);
++	inode->i_size = 0;
++	inode->i_blocks = 0;
++	inode->i_generation = 0;
++	memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
++	inode->i_pipe = NULL;
++	inode->i_bdev = NULL;
++	inode->i_cdev = NULL;
++	inode->i_data.a_ops = &empty_aops;
++	inode->i_data.host = inode;
++	inode->i_data.gfp_mask = GFP_HIGHUSER;
++	inode->i_mapping = &inode->i_data;
++}
++
++/**
++ * get_empty_inode 	- obtain an inode
++ *
++ * This is called by things like the networking layer
++ * etc that want to get an inode without any inode
++ * number, or filesystems that allocate new inodes with
++ * no pre-existing information.
++ *
++ * On a successful return the inode pointer is returned. On a failure
++ * a %NULL pointer is returned. The returned inode is not on any superblock
++ * lists.
++ */
++ 
++struct inode * get_empty_inode(void)
++{
++	static unsigned long last_ino;
++	struct inode * inode;
++
++	spin_lock_prefetch(&inode_lock);
++	
++	inode = (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL);
++	if (inode)
++	{
++		spin_lock(&inode_lock);
++		inodes_stat.nr_inodes++;
++		list_add(&inode->i_list, &inode_in_use);
++		inode->i_sb = NULL;
++		inode->i_dev = 0;
++		inode->i_blkbits = 0;
++		inode->i_ino = ++last_ino;
++		inode->i_flags = 0;
++		atomic_set(&inode->i_count, 1);
++		inode->i_state = 0;
++		spin_unlock(&inode_lock);
++		clean_inode(inode);
++	}
++	return inode;
++}
++
+ /**
+  *	new_inode 	- obtain an inode
+  *	@sb: superblock
+Index: linux/include/linux/fs.h
+===================================================================
+--- linux.orig/include/linux/fs.h	2003-09-03 17:52:02.000000000 -0400
++++ linux/include/linux/fs.h	2003-09-03 17:52:04.000000000 -0400
+@@ -1440,6 +1440,7 @@
+ 
+ extern void clear_inode(struct inode *);
+ extern struct inode *new_inode(struct super_block *sb);
++extern struct inode * get_empty_inode(void);
+ extern void remove_suid(struct inode *inode);
+ 
+ extern void insert_inode_hash(struct inode *);
+Index: linux/arch/i386/kernel/setup.c
+===================================================================
+--- linux.orig/arch/i386/kernel/setup.c	2003-09-03 17:51:01.000000000 -0400
++++ linux/arch/i386/kernel/setup.c	2003-09-03 17:53:05.000000000 -0400
+@@ -172,6 +172,8 @@
+ static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 };
+ extern int blk_nohighio;
+ 
++int enable_acpi_smp_table;
++
+ /*
+  * This is set up by the setup-routine at boot-time
+  */
diff --git a/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch b/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch
index 1b589b963c94c8570e0f1060345146d12bbab69e..a02c57f7a001cbf34729889036c27988bef08164 100644
--- a/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch
+++ b/lustre/kernel_patches/patches/dev_read_only_2.4.20-rh.patch
@@ -3,9 +3,11 @@
  drivers/ide/ide-disk.c |    5 +++++
  3 files changed, 43 insertions(+)
 
---- kernel-2.4.20-6chaos_18_7/drivers/block/blkpg.c~dev_read_only_2.4.20-rh	2003-05-15 21:12:48.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/drivers/block/blkpg.c	2003-07-12 15:10:31.000000000 -0600
-@@ -297,3 +297,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
+Index: linux-2.4.20-rh-20.9/drivers/block/blkpg.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/drivers/block/blkpg.c	2003-11-13 17:19:32.000000000 +0300
++++ linux-2.4.20-rh-20.9/drivers/block/blkpg.c	2003-11-13 17:20:28.000000000 +0300
+@@ -297,3 +297,38 @@
  }
  
  EXPORT_SYMBOL(blk_ioctl);
@@ -44,9 +46,11 @@
 +EXPORT_SYMBOL(dev_set_rdonly);
 +EXPORT_SYMBOL(dev_check_rdonly);
 +EXPORT_SYMBOL(dev_clear_rdonly);
---- kernel-2.4.20-6chaos_18_7/drivers/block/loop.c~dev_read_only_2.4.20-rh	2003-05-15 21:12:50.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/drivers/block/loop.c	2003-07-12 15:10:31.000000000 -0600
-@@ -491,6 +491,9 @@ static int loop_make_request(request_que
+Index: linux-2.4.20-rh-20.9/drivers/block/loop.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/drivers/block/loop.c	2003-11-13 17:19:32.000000000 +0300
++++ linux-2.4.20-rh-20.9/drivers/block/loop.c	2003-11-13 17:20:28.000000000 +0300
+@@ -491,6 +491,9 @@
  	spin_unlock_irq(&lo->lo_lock);
  
  	if (rw == WRITE) {
@@ -56,19 +60,19 @@
  		if (lo->lo_flags & LO_FLAGS_READ_ONLY)
  			goto err;
  	} else if (rw == READA) {
---- kernel-2.4.20-6chaos_18_7/drivers/ide/ide-disk.c~dev_read_only_2.4.20-rh	2003-05-15 21:13:09.000000000 -0600
-+++ kernel-2.4.20-6chaos_18_7-braam/drivers/ide/ide-disk.c	2003-07-12 15:12:03.000000000 -0600
-@@ -371,6 +371,11 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
+Index: linux-2.4.20-rh-20.9/drivers/ide/ide-disk.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/drivers/ide/ide-disk.c	2003-11-13 17:19:32.000000000 +0300
++++ linux-2.4.20-rh-20.9/drivers/ide/ide-disk.c	2003-11-13 18:13:46.000000000 +0300
+@@ -371,6 +371,11 @@
  	if (driver_blocked)
  		panic("Request while ide driver is blocked?");
  
 +  	if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
-+  		ide_end_request(1, HWGROUP(drive));
++  		ide_end_request(drive, 1);
 +  		return ide_stopped;
 +  	}
 +
  	if (IDE_CONTROL_REG)
  		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
  
-
-_
diff --git a/lustre/kernel_patches/patches/dev_read_only_2.6.0.patch b/lustre/kernel_patches/patches/dev_read_only_2.6.0.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f0f79dfdb1cb95259fd21f9fb4e0ee57e9b46bad
--- /dev/null
+++ b/lustre/kernel_patches/patches/dev_read_only_2.6.0.patch
@@ -0,0 +1,81 @@
+ drivers/block/ll_rw_blk.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/blkdev.h    |    1 
+ 2 files changed, 50 insertions(+)
+
+--- linux-2.6.0-test6/drivers/block/ll_rw_blk.c~dev_read_only_2.6.0	2003-10-14 19:56:55.000000000 +0400
++++ linux-2.6.0-test6-alexey/drivers/block/ll_rw_blk.c	2003-10-22 01:35:56.000000000 +0400
+@@ -2213,6 +2213,9 @@ end_io:
+ 
+ 		if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))
+ 			goto end_io;
++		if (test_bit(QUEUE_FLAG_RDONLY, &q->queue_flags)
++				&& bio->bi_rw == WRITE)
++			goto end_io;
+ 
+ 		/*
+ 		 * If this device has partitions, remap block n
+@@ -2867,6 +2870,52 @@ void blk_unregister_queue(struct gendisk
+ 	}
+ }
+ 
++#define MAX_RDONLY_DEVS		16
++
++static struct block_device *rdonly_devs[MAX_RDONLY_DEVS] = {0, };
++
++/*
++ * Debug code for turning block devices "read-only" (will discard writes
++ * silently).  This is for filesystem crash/recovery testing.
++ */
++void dev_set_rdonly(struct block_device *bdev, int no_write)
++{
++	if (bdev) {
++		request_queue_t *q;
++
++		q = bdev_get_queue(bdev);
++		if (!q) {
++			printk(KERN_ERR
++				"dev_set_rdonly() for non-existing device\n");
++			return;
++		}
++		printk(KERN_WARNING "Turning device %s read-only\n",
++				bdev->bd_disk ? bdev->bd_disk->disk_name : "?");
++		set_bit(QUEUE_FLAG_RDONLY, &q->queue_flags);
++		rdonly_devs[no_write] = bdev;
++	}
++}
++
++void dev_clear_rdonly(int no_write)
++{
++	request_queue_t *q;
++	
++	if (rdonly_devs[no_write] == NULL)
++		return;
++	
++	q = bdev_get_queue(rdonly_devs[no_write]);
++	if (!q) {
++		printk(KERN_ERR
++			"dev_clear_rdonly: no queue for device at slot %d\n",
++			no_write);
++		return;
++	}
++	clear_bit(QUEUE_FLAG_RDONLY, &q->queue_flags);
++	rdonly_devs[no_write] = NULL;
++}
++
++EXPORT_SYMBOL(dev_set_rdonly);
++EXPORT_SYMBOL(dev_clear_rdonly);
+ 
+ EXPORT_SYMBOL(process_that_request_first);
+ EXPORT_SYMBOL(end_that_request_first);
+--- linux-2.6.0-test6/include/linux/blkdev.h~dev_read_only_2.6.0	2003-10-14 19:57:05.000000000 +0400
++++ linux-2.6.0-test6-alexey/include/linux/blkdev.h	2003-10-21 23:31:18.000000000 +0400
+@@ -367,6 +367,7 @@ struct request_queue
+ #define	QUEUE_FLAG_READFULL	3	/* write queue has been filled */
+ #define QUEUE_FLAG_WRITEFULL	4	/* read queue has been filled */
+ #define QUEUE_FLAG_DEAD		5	/* queue being torn down */
++#define QUEUE_FLAG_RDONLY	6	/* queue accepts reads only */
+ 
+ #define blk_queue_plugged(q)	!list_empty(&(q)->plug_list)
+ #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
+
+_
diff --git a/lustre/kernel_patches/patches/dsp.patch b/lustre/kernel_patches/patches/dsp.patch
index f2e5b932a175f11afdefd0fee354861e16173ed6..d072af9ef309a63e006152a3ed52ff624beee8b3 100644
--- a/lustre/kernel_patches/patches/dsp.patch
+++ b/lustre/kernel_patches/patches/dsp.patch
@@ -6,9 +6,11 @@
  kernel/bootimg_pic.c     |    6 ++++--
  6 files changed, 36 insertions(+), 12 deletions(-)
 
---- linux-rh-2.4.20-8/kernel/bootimg.c~dsp	2003-05-07 19:30:47.000000000 +0800
-+++ linux-rh-2.4.20-8-root/kernel/bootimg.c	2003-05-07 19:31:12.000000000 +0800
-@@ -238,9 +238,20 @@ int boot_image()
+Index: linux-2.4.20-rh/kernel/bootimg.c
+===================================================================
+--- linux-2.4.20-rh.orig/kernel/bootimg.c	2003-10-29 23:56:02.000000000 +0800
++++ linux-2.4.20-rh/kernel/bootimg.c	2003-10-29 23:56:17.000000000 +0800
+@@ -238,9 +238,20 @@
  	int error = -ENOMEM;
  
  	if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) 
@@ -30,9 +32,11 @@
  	code_page = get_identity_mapped_page();
  	if (!code_page) goto out3;
  	code = (relocate_and_jump_t) virt_to_phys((void *) code_page);
---- linux-rh-2.4.20-8/kernel/bootimg_pic.c~dsp	2003-05-07 19:30:47.000000000 +0800
-+++ linux-rh-2.4.20-8-root/kernel/bootimg_pic.c	2003-05-07 19:31:12.000000000 +0800
-@@ -69,7 +69,8 @@ void __bootimg relocate_and_jump(void)
+Index: linux-2.4.20-rh/kernel/bootimg_pic.c
+===================================================================
+--- linux-2.4.20-rh.orig/kernel/bootimg_pic.c	2003-10-29 23:56:02.000000000 +0800
++++ linux-2.4.20-rh/kernel/bootimg_pic.c	2003-10-29 23:56:17.000000000 +0800
+@@ -69,7 +69,8 @@
  			for (j = i+1; j < dsc.pages; j++) {
  				table = dsc.page_dir+FROM_TABLE(j);
  				if (((unsigned long) *table) == to) {
@@ -42,7 +46,7 @@
  					break;
  				}
  				if ((*table)[PAGE_NR(j)] == to) {
-@@ -79,7 +80,8 @@ void __bootimg relocate_and_jump(void)
+@@ -79,7 +80,8 @@
  				}
  				table = dsc.page_dir+TO_TABLE(j);
  				if (((unsigned long) *table) == to) {
@@ -52,19 +56,25 @@
  					break;
  				}
  			}
---- linux-rh-2.4.20-8/include/asm-i386/apic.h~dsp	2003-05-07 17:00:16.000000000 +0800
-+++ linux-rh-2.4.20-8-root/include/asm-i386/apic.h	2003-05-07 19:31:12.000000000 +0800
-@@ -86,6 +86,7 @@ extern struct pm_dev *apic_pm_register(p
+Index: linux-2.4.20-rh/include/asm-i386/apic.h
+===================================================================
+--- linux-2.4.20-rh.orig/include/asm-i386/apic.h	2003-10-29 23:58:49.000000000 +0800
++++ linux-2.4.20-rh/include/asm-i386/apic.h	2003-10-29 23:59:40.000000000 +0800
+@@ -86,6 +86,9 @@
  extern void apic_pm_unregister(struct pm_dev*);
  
  extern int check_nmi_watchdog (void);
 +extern void disable_apic_nmi_watchdog(void);
++
++
  
  extern unsigned int nmi_watchdog;
  #define NMI_NONE	0
---- linux-rh-2.4.20-8/include/linux/crash.h~dsp	2003-05-07 19:30:47.000000000 +0800
-+++ linux-rh-2.4.20-8-root/include/linux/crash.h	2003-05-07 19:31:12.000000000 +0800
-@@ -71,7 +71,7 @@ extern void stop_this_cpu(void *);
+Index: linux-2.4.20-rh/include/linux/crash.h
+===================================================================
+--- linux-2.4.20-rh.orig/include/linux/crash.h	2003-10-29 23:56:02.000000000 +0800
++++ linux-2.4.20-rh/include/linux/crash.h	2003-10-29 23:56:17.000000000 +0800
+@@ -71,7 +71,7 @@
  #define CRASH_ZALLOC_PAGES 16*5*2	/* 2 to handle crash in crash */
  #define CRASH_LOW_WATER_PAGES 100
  
@@ -73,8 +83,10 @@
  
  #define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
  #define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags))
---- linux-rh-2.4.20-8/arch/i386/kernel/crash.c~dsp	2003-05-07 19:30:47.000000000 +0800
-+++ linux-rh-2.4.20-8-root/arch/i386/kernel/crash.c	2003-05-07 19:31:39.000000000 +0800
+Index: linux-2.4.20-rh/arch/i386/kernel/crash.c
+===================================================================
+--- linux-2.4.20-rh.orig/arch/i386/kernel/crash.c	2003-10-29 23:56:02.000000000 +0800
++++ linux-2.4.20-rh/arch/i386/kernel/crash.c	2003-10-29 23:56:17.000000000 +0800
 @@ -9,6 +9,8 @@
  #include <linux/crash.h>
  #include <linux/reboot.h>
@@ -84,7 +96,7 @@
  
  inline void crash_save_regs(void) {
  	static unsigned long regs[8];
-@@ -30,15 +32,23 @@ inline void crash_save_regs(void) {
+@@ -30,15 +32,23 @@
   */
  void crash_save_current_state(struct task_struct *tp)
  {
@@ -115,9 +127,11 @@
  
  	save_core();
  
---- linux-rh-2.4.20-8/arch/i386/kernel/nmi.c~dsp	2003-05-07 19:30:47.000000000 +0800
-+++ linux-rh-2.4.20-8-root/arch/i386/kernel/nmi.c	2003-05-07 19:31:12.000000000 +0800
-@@ -138,7 +138,7 @@ __setup("nmi_watchdog=", setup_nmi_watch
+Index: linux-2.4.20-rh/arch/i386/kernel/nmi.c
+===================================================================
+--- linux-2.4.20-rh.orig/arch/i386/kernel/nmi.c	2003-10-29 23:56:02.000000000 +0800
++++ linux-2.4.20-rh/arch/i386/kernel/nmi.c	2003-10-29 23:56:17.000000000 +0800
+@@ -138,7 +138,7 @@
  
  struct pm_dev *nmi_pmdev;
  
@@ -126,5 +140,3 @@
  {
  	switch (boot_cpu_data.x86_vendor) {
  	case X86_VENDOR_AMD:
-
-_
diff --git a/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch b/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b93e2f90b51760eef2c0c019a541f8ffb9636af6
--- /dev/null
+++ b/lustre/kernel_patches/patches/dump_netdev_over_netpoll.patch
@@ -0,0 +1,761 @@
+Index: linux-2.6.0-test6/drivers/dump/dump_netdev.c
+===================================================================
+--- linux-2.6.0-test6.orig/drivers/dump/dump_netdev.c	2003-10-07 16:08:57.000000000 +0800
++++ linux-2.6.0-test6/drivers/dump/dump_netdev.c	2003-10-09 17:36:18.000000000 +0800
+@@ -14,6 +14,7 @@
+  *
+  * Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
+  * Copyright (C) 2002 International Business Machines Corp. 
++ * Rewrited with netpoll by wangdi <wangdi@clusterfs.com>
+  *
+  *  This code is released under version 2 of the GNU GPL.
+  */
+@@ -26,29 +27,19 @@
+ #include <linux/module.h>
+ #include <linux/dump.h>
+ #include <linux/dump_netdev.h>
++#include <linux/netpoll.h>
+ 
+ #include <asm/unaligned.h>
+ 
+ static int startup_handshake;
+ static int page_counter;
+-static struct net_device *dump_ndev;
+ static struct in_device *dump_in_dev;
+-static u16 source_port, target_port;
+-static u32 source_ip, target_ip;
+-static unsigned char daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ;
+-static spinlock_t dump_skb_lock = SPIN_LOCK_UNLOCKED;
+-static int dump_nr_skbs;
+-static struct sk_buff *dump_skb;
+ static unsigned long flags_global;
+ static int netdump_in_progress;
+ static char device_name[IFNAMSIZ];
++int new_req = 0;
++static req_t req;
+ 
+-/*
+- * security depends on the trusted path between the netconsole
+- * server and netconsole client, since none of the packets are
+- * encrypted. The random magic number protects the protocol
+- * against spoofing.
+- */
+ static u64 dump_magic;
+ 
+ #define MAX_UDP_CHUNK 1460
+@@ -64,300 +55,28 @@
+ #define MAX_SKB_SIZE \
+ 		(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
+ 				sizeof(struct iphdr) + sizeof(struct ethhdr))
++static char send_buffer[MAX_UDP_CHUNK];
+ 
+-static void
+-dump_refill_skbs(void)
+-{
+-	struct sk_buff *skb;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&dump_skb_lock, flags);
+-	while (dump_nr_skbs < DUMP_MAX_SKBS) {
+-		skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
+-		if (!skb)
+-			break;
+-		if (dump_skb)
+-			skb->next = dump_skb;
+-		else
+-			skb->next = NULL;
+-		dump_skb = skb;
+-		dump_nr_skbs++;
+-	}
+-	spin_unlock_irqrestore(&dump_skb_lock, flags);
+-}
+-
+-static struct
+-sk_buff * dump_get_skb(void)
+-{
+-	struct sk_buff *skb;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&dump_skb_lock, flags);
+-	skb = dump_skb;
+-	if (skb) {
+-		dump_skb = skb->next;
+-		skb->next = NULL;
+-		dump_nr_skbs--;
+-	}
+-	spin_unlock_irqrestore(&dump_skb_lock, flags);
+-        
+-	return skb;
+-}
+-
+-/*
+- * Zap completed output skbs.
+- */
+-static void
+-zap_completion_queue(void)
+-{
+-	int count;
+-	unsigned long flags;
+-	int cpu = smp_processor_id();
+-	struct softnet_data *softnet_data;
+-       	
+-
+-	softnet_data = &__get_cpu_var(softnet_data);
+-	count=0;
+-	if (softnet_data[cpu].completion_queue) {
+-		struct sk_buff *clist;
+-	
+-		local_irq_save(flags);
+-		clist = softnet_data[cpu].completion_queue;
+-		softnet_data[cpu].completion_queue = NULL;
+-		local_irq_restore(flags);
+-
+-		while (clist != NULL) {
+-			struct sk_buff *skb = clist;
+-			clist = clist->next;
+-			__kfree_skb(skb);
+-			count++;
+-			if (count > 10000)
+-				printk("Error in sk list\n");
+-		}
+-	}
+-}
+-
+-static void
+-dump_send_skb(struct net_device *dev, const char *msg, unsigned int msg_len,
+-		reply_t *reply)
+-{
+-	int once = 1;
+-	int total_len, eth_len, ip_len, udp_len, count = 0;
+-	struct sk_buff *skb;
+-	struct udphdr *udph;
+-	struct iphdr *iph;
+-	struct ethhdr *eth; 
+-
+-	udp_len = msg_len + HEADER_LEN + sizeof(*udph);
+-	ip_len = eth_len = udp_len + sizeof(*iph);
+-	total_len = eth_len + ETH_HLEN;
+-
+-repeat_loop:
+-	zap_completion_queue();
+-	if (dump_nr_skbs < DUMP_MAX_SKBS)
+-		dump_refill_skbs();
+-
+-	skb = alloc_skb(total_len, GFP_ATOMIC);
+-	if (!skb) {
+-		skb = dump_get_skb();
+-		if (!skb) {
+-			count++;
+-			if (once && (count == 1000000)) {
+-				printk("possibly FATAL: out of netconsole "
+-					"skbs!!! will keep retrying.\n");
+-				once = 0;
+-			}
+-			dev->poll_controller(dev);
+-			goto repeat_loop;
+-		}
+-	}
+-
+-	atomic_set(&skb->users, 1);
+-	skb_reserve(skb, total_len - msg_len - HEADER_LEN);
+-	skb->data[0] = NETCONSOLE_VERSION;
+-
+-	put_unaligned(htonl(reply->nr), (u32 *) (skb->data + 1));
+-	put_unaligned(htonl(reply->code), (u32 *) (skb->data + 5));
+-	put_unaligned(htonl(reply->info), (u32 *) (skb->data + 9));
+-
+-	memcpy(skb->data + HEADER_LEN, msg, msg_len);
+-	skb->len += msg_len + HEADER_LEN;
+-
+-	udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
+-	udph->source = source_port;
+-	udph->dest = target_port;
+-	udph->len = htons(udp_len);
+-	udph->check = 0;
+-
+-	iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
+-
+-	iph->version  = 4;
+-	iph->ihl      = 5;
+-	iph->tos      = 0;
+-	iph->tot_len  = htons(ip_len);
+-	iph->id       = 0;
+-	iph->frag_off = 0;
+-	iph->ttl      = 64;
+-	iph->protocol = IPPROTO_UDP;
+-	iph->check    = 0;
+-	iph->saddr    = source_ip;
+-	iph->daddr    = target_ip;
+-	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
+-
+-	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
+-
+-	eth->h_proto = htons(ETH_P_IP);
+-	memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+-	memcpy(eth->h_dest, daddr, dev->addr_len);
++extern void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty);
++static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len);
+ 
+-	count=0;
+-repeat_poll:
+-	spin_lock(&dev->xmit_lock);
+-	dev->xmit_lock_owner = smp_processor_id();
+-
+-	count++;
+-
+-
+-	if (netif_queue_stopped(dev)) {
+-		dev->xmit_lock_owner = -1;
+-		spin_unlock(&dev->xmit_lock);
+-
+-		dev->poll_controller(dev);
+-		zap_completion_queue();
+-
+-
+-		goto repeat_poll;
+-	}
+-
+-	dev->hard_start_xmit(skb, dev);
+-
+-	dev->xmit_lock_owner = -1;
+-	spin_unlock(&dev->xmit_lock);
+-}
+-
+-static unsigned short
+-udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr,
+-	       	unsigned long base)
+-{
+-	return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base);
+-}
+-
+-static int
+-udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
+-			     unsigned short ulen, u32 saddr, u32 daddr)
+-{
+-	if (uh->check == 0) {
+-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+-	} else if (skb->ip_summed == CHECKSUM_HW) {
+-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+-		if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
+-			return 0;
+-		skb->ip_summed = CHECKSUM_NONE;
+-	}
+-	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+-		skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen,
+-				IPPROTO_UDP, 0);
+-	/* Probably, we should checksum udp header (it should be in cache
+-	 * in any case) and data in tiny packets (< rx copybreak).
+-	 */
+-	return 0;
+-}
+-
+-static __inline__ int
+-__udp_checksum_complete(struct sk_buff *skb)
+-{
+-	return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len,
+-				skb->csum));
+-}
+-
+-static __inline__
+-int udp_checksum_complete(struct sk_buff *skb)
+-{
+-	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+-		__udp_checksum_complete(skb);
+-}
+-
+-int new_req = 0;
+-static req_t req;
++static struct netpoll np = {
++	.name = "netdumpoe",
++	.dev_name = "eth0",
++	.rx_hook = dump_rx_hook,
++	.local_port = 0,
++	.remote_port = 0,
++	.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
++};
+ 
+-static int
+-dump_rx_hook(struct sk_buff *skb)
++static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len)
+ {
+-	int proto;
+-	struct iphdr *iph;
+-	struct udphdr *uh;
+-	__u32 len, saddr, daddr, ulen;
+ 	req_t *__req;
+-
+-	/* 
+-	 * First check if were are dumping or doing startup handshake, if
+-	 * not quickly return.
+-	 */
++	
+ 	if (!netdump_in_progress)
+-		return NET_RX_SUCCESS;
++               goto out;
++	__req = (req_t *)msg;
+ 
+-	if (skb->dev->type != ARPHRD_ETHER)
+-		goto out;
+-
+-	proto = ntohs(skb->mac.ethernet->h_proto);
+-	if (proto != ETH_P_IP)
+-		goto out;
+-
+-	if (skb->pkt_type == PACKET_OTHERHOST)
+-		goto out;
+-
+-	if (skb_shared(skb))
+-		goto out;
+-
+-	 /* IP header correctness testing: */
+-	iph = (struct iphdr *)skb->data;
+-	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+-		goto out;
+-
+-	if (iph->ihl < 5 || iph->version != 4)
+-		goto out;
+-
+-	if (!pskb_may_pull(skb, iph->ihl*4))
+-		goto out;
+-
+-	if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
+-		goto out;
+-
+-	len = ntohs(iph->tot_len);
+-	if (skb->len < len || len < iph->ihl*4)
+-		goto out;
+-
+-	saddr = iph->saddr;
+-	daddr = iph->daddr;
+-	if (iph->protocol != IPPROTO_UDP)
+-		goto out;
+-
+-	if (source_ip != daddr)
+-		goto out;
+-
+-	if (target_ip != saddr)
+-		goto out;
+-
+-	len -= iph->ihl*4;
+-	uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
+-	ulen = ntohs(uh->len);
+-
+-	if (ulen != len || ulen < (sizeof(*uh) + sizeof(*__req)))
+-		goto out;
+-
+-	if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
+-		goto out;
+-
+-	if (udp_checksum_complete(skb))
+-		goto out;
+-
+-	if (source_port != uh->dest)
+-		goto out;
+-
+-	if (target_port != uh->source)
+-		goto out;
+-
+-	__req = (req_t *)(uh + 1);
+ 	if ((ntohl(__req->command) != COMM_GET_MAGIC) &&
+ 	    (ntohl(__req->command) != COMM_HELLO) &&
+ 	    (ntohl(__req->command) != COMM_START_WRITE_NETDUMP_ACK) &&
+@@ -372,11 +91,27 @@
+ 	req.nr = ntohl(__req->nr);
+ 	new_req = 1;
+ out:
+-	return NET_RX_DROP;
++	return;
+ }
+ 
+ static void
+-dump_send_mem(struct net_device *dev, req_t *req, const char* buff, size_t len)
++dump_send_skb(const char *msg, unsigned int msg_len, reply_t *reply)
++{
++	/*copy the msg to send buffer*/
++	send_buffer[0] = NETCONSOLE_VERSION;
++
++	put_unaligned(htonl(reply->nr), (u32 *) (send_buffer + 1));
++	put_unaligned(htonl(reply->code), (u32 *) (send_buffer + 5));
++	put_unaligned(htonl(reply->info), (u32 *) (send_buffer + 9));
++	memcpy(send_buffer + 1 + sizeof(reply_t), msg, msg_len);
++
++	if (!np.dev)
++		return;
++	netpoll_send_udp(&np, send_buffer, (msg_len + 1 + sizeof(reply_t)));
++}
++
++static void
++dump_send_mem( req_t *req, const char* buff, size_t len)
+ {
+ 	int i;
+ 
+@@ -392,7 +127,7 @@
+ 		unsigned int offset = i*1024;
+ 		reply.code = REPLY_MEM;
+ 		reply.info = offset;
+-                dump_send_skb(dev, buff + offset, 1024, &reply);
++                dump_send_skb(buff + offset, 1024, &reply);
+ 	}
+ }
+ static void dump_do_sysrq(int key)
+@@ -400,9 +135,16 @@
+         struct pt_regs regs;
+         
+ 	get_current_regs(&regs);
+-	handle_sysrq(key, &regs, NULL, NULL);
++	handle_sysrq(key, &regs, NULL);
+ }
+ 
++static void netdump_netpoll_poll(struct netpoll *np)
++{
++	/*FIXME netpoll_set_trap(0) may have impacts to other parts */
++	netpoll_set_trap(1);
++	netpoll_poll(np);
++	netpoll_set_trap(0);
++}
+ /*
+  * This function waits for the client to acknowledge the receipt
+  * of the netdump startup reply, with the possibility of packets
+@@ -433,24 +175,27 @@
+ 	
+ 	/* send 300 handshake packets before declaring failure */
+ 	for (i = 0; i < 300; i++) {
+-		dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
+-
++		dump_send_skb(tmp, strlen(tmp), &reply);
++#if 0
+ 		/* wait 1 sec */
++			udelay(100);
++			netpoll_poll(&np);
++			if (new_req)
++				break;
++		}
++#endif
+ 		for (j = 0; j < 10000; j++) {
+ 			udelay(100);
+-			dump_ndev->poll_controller(dump_ndev);
+-			zap_completion_queue();
++			netdump_netpoll_poll(&np);
+ 			if (new_req)
+ 				break;
+ 		}
+-
+ 		/* 
+ 		 * if there is no new request, try sending the handshaking
+ 		 * packet again
+ 		 */
+ 		if (!new_req)
+ 			continue;
+-
+ 		/* 
+ 		 * check if the new request is of the expected type,
+ 		 * if so, return, else try sending the handshaking
+@@ -504,10 +249,12 @@
+ 	repeatCounter = 0;
+ 	total_loop = 0;
+ 	while (1) {
+-                if (!new_req) {
+-			dump_ndev->poll_controller(dump_ndev);
+-			zap_completion_queue();
++                while (!new_req) {
++			netdump_netpoll_poll(&np);
++			if (new_req)
++				break;
+ 		}
++#if 0
+ 		if (!new_req) {
+ 			repeatCounter++;
+ 
+@@ -532,13 +279,15 @@
+ 		repeatCounter = 0;
+ 		counter = 0;
+ 		total_loop = 0;
++#endif
++		
+ 		new_req = 0;
+ 		switch (req.command) {
+ 		case COMM_NONE:
+ 			break;
+ 
+ 		case COMM_SEND_MEM:
+-			dump_send_mem(dump_ndev, &req, buff, len);
++			dump_send_mem(&req, buff, len);
+ 			break;
+ 
+ 		case COMM_EXIT:
+@@ -549,10 +298,11 @@
+ 		case COMM_HELLO:
+ 			sprintf(tmp, "Hello, this is netdump version "
+ 					"0.%02d\n", NETCONSOLE_VERSION);
++			
+ 			reply.code = REPLY_HELLO;
+ 			reply.nr = req.nr;
+                         reply.info = net_dev->curr_offset;
+-			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			dump_send_skb(tmp, strlen(tmp), &reply);
+ 			break;
+ 
+ 		case COMM_GET_PAGE_SIZE:
+@@ -560,7 +310,7 @@
+ 			reply.code = REPLY_PAGE_SIZE;
+ 			reply.nr = req.nr;
+ 			reply.info = PAGE_SIZE;
+-			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			dump_send_skb(tmp, strlen(tmp), &reply);
+ 			break;
+ 
+ 		case COMM_GET_NR_PAGES:
+@@ -569,15 +319,14 @@
+ 			reply.info = num_physpages;
+                         reply.info = page_counter;
+ 			sprintf(tmp, "Number of pages: %ld\n", num_physpages);
+-			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			dump_send_skb(tmp, strlen(tmp), &reply);
+ 			break;
+ 
+ 		case COMM_GET_MAGIC:
+ 			reply.code = REPLY_MAGIC;
+ 			reply.nr = req.nr;
+ 			reply.info = NETCONSOLE_VERSION;
+-			dump_send_skb(dump_ndev, (char *)&dump_magic,
+-					sizeof(dump_magic), &reply);
++			dump_send_skb((char *)&dump_magic, sizeof(dump_magic), &reply);
+ 			break;
+                 case COMM_SYSRQ:
+ 			dump_do_sysrq(req.from);
+@@ -585,7 +334,7 @@
+ 			reply.nr = req.nr;
+ 			reply.info = req.from;
+ 			sprintf(tmp, "SYSRQ command %d \n", req.from);
+-			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			dump_send_skb(tmp, strlen(tmp), &reply);
+ 			break;
+ 		default:
+ 			reply.code = REPLY_ERROR;
+@@ -593,7 +342,7 @@
+ 			reply.info = req.command;
+ 			sprintf(tmp, "Got unknown command code %d!\n",
+ 					req.command);
+-			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			dump_send_skb(tmp, strlen(tmp), &reply);
+ 			break;
+ 		}
+ 	}
+@@ -605,45 +354,45 @@
+ static int
+ dump_validate_config(void)
+ {
+-	source_ip = dump_in_dev->ifa_list->ifa_local;
+-	if (!source_ip) {
++#if 0
++	np.local_ip = dump_in_dev->ifa_list->ifa_local;
++	if (!np.local_ip) {
+ 		printk("network device %s has no local address, "
+ 				"aborting.\n", device_name);
+ 		return -1;
+ 	}
+-
+-#define IP(x) ((unsigned char *)&source_ip)[x]
++#endif
++#define IP(x) ((unsigned char *)&np.local_ip)[x]
+ 	printk("Source %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
+ #undef IP
+ 
+-	if (!source_port) {
++	if (!np.local_port) {
+ 		printk("source_port parameter not specified, aborting.\n");
+ 		return -1;
+ 	}
+-	printk(":%i\n", source_port);
+-	source_port = htons(source_port);
++	printk(":%i\n", np.local_port);
+ 
+-	if (!target_ip) {
++	if (!np.remote_ip) {
+ 		printk("target_ip parameter not specified, aborting.\n");
+ 		return -1;
+ 	}
+ 
+-#define IP(x) ((unsigned char *)&target_ip)[x]
++#define IP(x) ((unsigned char *)&np.remote_ip)[x]
+ 	printk("Target %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
+ #undef IP
+ 
+-	if (!target_port) {
++	if (!np.remote_port) {
+ 		printk("target_port parameter not specified, aborting.\n");
+ 		return -1;
+ 	}
+-	printk(":%i\n", target_port);
+-	target_port = htons(target_port);
++	printk(":%i\n", np.remote_port);
+ 
+ 	printk("Target Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x",
+-		daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]);
++		np.remote_mac[0], np.remote_mac[1], np.remote_mac[2], 
++		np.remote_mac[3], np.remote_mac[4], np.remote_mac[5]);
+ 
+-	if ((daddr[0] & daddr[1] & daddr[2] & daddr[3] & daddr[4] & 
+-				daddr[5]) == 255)
++	if ((np.remote_mac[0] & np.remote_mac[1] & np.remote_mac[2] & 
++		np.remote_mac[3] & np.remote_mac[4] & np.remote_mac[5]) == 255)
+ 		printk("(Broadcast)");
+ 	printk("\n");
+ 	return 0;
+@@ -659,31 +408,24 @@
+ dump_net_open(struct dump_dev *net_dev, unsigned long arg)
+ {
+ 	int retval = 0;
+-
++#if 0
+ 	/* get the interface name */
+ 	if (copy_from_user(device_name, (void *)arg, IFNAMSIZ))
+ 		return -EFAULT;
+ 
+-	if (!(dump_ndev = dev_get_by_name(device_name))) {
++	if (!(np.dev = dev_get_by_name(device_name))) {
+ 		printk("network device %s does not exist, aborting.\n",
+ 				device_name);
+ 		return -ENODEV;
+ 	}
+-
+-	if (!dump_ndev->poll_controller) {
+-		printk("network device %s does not implement polling yet, "
+-				"aborting.\n", device_name);
+-		retval = -1; /* return proper error */
+-		goto err1;
+-	}
+-
+-	if (!(dump_in_dev = in_dev_get(dump_ndev))) {
++#endif
++	if (!(dump_in_dev = in_dev_get(np.dev))) {
+ 		printk("network device %s is not an IP protocol device, "
+ 				"aborting.\n", device_name);
+ 		retval = -EINVAL;
+ 		goto err1;
+ 	}
+-
++	
+ 	if ((retval = dump_validate_config()) < 0)
+ 		goto err2;
+ 
+@@ -694,7 +436,7 @@
+ err2:
+ 	in_dev_put(dump_in_dev);
+ err1:
+-	dev_put(dump_ndev);	
++	dev_put(np.dev);	
+ 	return retval;
+ }
+ 
+@@ -707,8 +449,8 @@
+ {
+ 	if (dump_in_dev)
+ 		in_dev_put(dump_in_dev);
+-	if (dump_ndev)
+-		dev_put(dump_ndev);
++	if (np.dev)
++		dev_put(np.dev);
+ 	return 0;
+ }
+ 
+@@ -720,7 +462,6 @@
+ dump_net_silence(struct dump_dev *net_dev)
+ {
+ 	local_irq_save(flags_global);
+-	dump_ndev->rx_hook = dump_rx_hook;
+         startup_handshake = 1;
+ 	net_dev->curr_offset = 0;
+ 	printk("Dumping to network device %s on CPU %d ...\n", device_name,
+@@ -740,7 +481,7 @@
+ 	reply_t reply;
+ 	char tmp[200];
+ 
+-        if (!dump_ndev)
++        if (!np.dev)
+ 		return (0);
+ 
+ 	sprintf(tmp, "NETDUMP end.\n");
+@@ -748,11 +489,10 @@
+ 		reply.code = REPLY_END_NETDUMP;
+ 		reply.nr = 0;
+ 		reply.info = 0;
+-		dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++		dump_send_skb(tmp, strlen(tmp), &reply);
+ 	}
+ 	printk("NETDUMP END!\n");
+ 	local_irq_restore(flags_global);
+-	dump_ndev->rx_hook = NULL;
+ 	startup_handshake = 0;
+ 	return 0;
+ }
+@@ -809,18 +549,19 @@
+ static int
+ dump_net_ioctl(struct dump_dev *net_dev, unsigned int cmd, unsigned long arg)
+ {
++	#if 0
+ 	switch (cmd) {
+ 	case DIOSTARGETIP:
+-		target_ip = arg;
++		np.remote_ip = arg;
+ 		break;
+ 	case DIOSTARGETPORT:
+-		target_port = (u16)arg;
++		np.remote_port = (u16)arg;
+ 		break;
+ 	case DIOSSOURCEPORT:
+-		source_port = (u16)arg;
++		np.local_port = (u16)arg;
+ 		break;
+ 	case DIOSETHADDR:
+-		return copy_from_user(daddr, (void *)arg, 6);
++		return copy_from_user(np.remote_mac, (void *)arg, 6);
+ 		break;
+ 	case DIOGTARGETIP:
+ 	case DIOGTARGETPORT:
+@@ -830,6 +571,7 @@
+ 	default:
+ 		return -EINVAL;
+ 	}
++	#endif
+ 	return 0;
+ }
+ 
+@@ -851,17 +593,28 @@
+ 	.curr_offset = 0
+ };
+ 
++static int option_setup(char *opt)
++{
++	return netpoll_parse_options(&np, opt);
++}
++
++__setup("netdumpoe=", option_setup);
++
++
+ static int __init
+ dump_netdev_init(void)
+ {
+         default_dump_netdev.curr_offset = 0;
+ 
++	if(!np.remote_ip || netpoll_setup(&np))
++		return 1;
++
+ 	if (dump_register_device(&default_dump_netdev) < 0) {
+ 		printk("network dump device driver registration failed\n");
+ 		return -1;
+ 	}
+ 	printk("network device driver for LKCD registered\n");
+- 
++
+ 	get_random_bytes(&dump_magic, sizeof(dump_magic));
+ 	return 0;
+ }
+@@ -870,6 +623,7 @@
+ dump_netdev_cleanup(void)
+ {
+ 	dump_unregister_device(&default_dump_netdev);
++	netpoll_cleanup(&np);
+ }
+ 
+ MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
diff --git a/lustre/kernel_patches/patches/dynamic-locks-2.4.18-chaos.patch b/lustre/kernel_patches/patches/dynamic-locks-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a1cef3e16e84be8d78a9d58c308d292b40daed42
--- /dev/null
+++ b/lustre/kernel_patches/patches/dynamic-locks-2.4.18-chaos.patch
@@ -0,0 +1,212 @@
+ include/linux/dynlocks.h |   33 ++++++++++
+ lib/Makefile             |    4 -
+ lib/dynlocks.c           |  152 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 187 insertions(+), 2 deletions(-)
+
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/include/linux/dynlocks.h	2003-09-01 16:33:25.000000000 +0400
+@@ -0,0 +1,33 @@
++#ifndef _LINUX_DYNLOCKS_H
++#define _LINUX_DYNLOCKS_H
++
++#include <linux/list.h>
++#include <linux/wait.h>
++
++struct dynlock_member {
++	struct list_head	dl_list;
++	unsigned long		dl_value;	/* lock value */
++	int			dl_refcount;	/* number of users */
++	int			dl_readers;
++	int			dl_writers;
++	int			dl_pid;		/* holder of the lock */
++	wait_queue_head_t	dl_wait;
++};
++
++/*
++ * lock's namespace:
++ *   - list of locks
++ *   - lock to protect this list
++ */
++struct dynlock {
++	struct list_head dl_list;
++	spinlock_t dl_list_lock;
++};
++
++void dynlock_init(struct dynlock *dl);
++void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp);
++void dynlock_unlock(struct dynlock *dl, void *lock);
++
++
++#endif
++
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/lib/dynlocks.c	2003-09-01 16:36:00.000000000 +0400
+@@ -0,0 +1,152 @@
++/*
++ * Dynamic Locks
++ *
++ * struct dynlock is lockspace
++ * one may request lock (exclusive or shared) for some value
++ * in that lockspace
++ *
++ */
++
++#include <linux/dynlocks.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++/*
++ * dynlock_init
++ *
++ * initialize lockspace
++ *
++ */
++void dynlock_init(struct dynlock *dl)
++{
++	spin_lock_init(&dl->dl_list_lock);
++	INIT_LIST_HEAD(&dl->dl_list);
++}
++
++/*
++ * dynlock_lock
++ *
++ * acquires lock (exclusive or shared) in specified lockspace
++ * each lock in lockspace is allocated separately, so user have
++ * to specify GFP flags.
++ * routine returns pointer to lock. this pointer is intended to
++ * be passed to dynlock_unlock
++ *
++ */
++void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp)
++{
++	struct dynlock_member *nhl = NULL; 
++	struct dynlock_member *hl; 
++	struct list_head *cur;
++
++repeat:
++	/* find requested lock in lockspace */
++	spin_lock(&dl->dl_list_lock);
++	list_for_each(cur, &dl->dl_list) {
++		hl = list_entry(cur, struct dynlock_member, dl_list);
++		if (hl->dl_value == value) {
++			/* lock is found */
++			if (nhl) {
++				/* someone else just allocated
++				 * lock we didn't find and just created
++				 * so, we drop our lock
++				 */
++				kfree(nhl);
++				nhl = NULL;
++			}
++			hl->dl_refcount++;
++			goto found;
++		}
++	}
++	/* lock not found */
++	if (nhl) {
++		/* we already have allocated lock. use it */
++		hl = nhl;
++		nhl = NULL;
++		list_add(&hl->dl_list, &dl->dl_list);
++		goto found;
++	}
++	spin_unlock(&dl->dl_list_lock);
++	
++	/* lock not found and we haven't allocated lock yet. allocate it */
++	nhl = kmalloc(sizeof(struct dynlock_member), gfp);
++	if (nhl == NULL)
++		return NULL;
++	nhl->dl_refcount = 1;
++	nhl->dl_value = value;
++	nhl->dl_readers = 0;
++	nhl->dl_writers = 0;
++	init_waitqueue_head(&nhl->dl_wait);
++
++	/* while lock is being allocated, someone else may allocate it
++	 * and put onto to list. check this situation
++	 */
++	goto repeat;
++
++found:
++	if (rw) {
++		/* exclusive lock: user don't want to share lock at all
++		 * NOTE: one process may take the same lock several times
++		 * this functionaly is useful for rename operations */
++		while ((hl->dl_writers && hl->dl_pid != current->pid) ||
++				hl->dl_readers) {
++			spin_unlock(&dl->dl_list_lock);
++			wait_event(hl->dl_wait,
++				hl->dl_writers == 0 && hl->dl_readers == 0);
++			spin_lock(&dl->dl_list_lock);
++		}
++		hl->dl_writers++;
++	} else {
++		/* shared lock: user do not want to share lock with writer */
++		while (hl->dl_writers) {
++			spin_unlock(&dl->dl_list_lock);
++			wait_event(hl->dl_wait, hl->dl_writers == 0);
++			spin_lock(&dl->dl_list_lock);
++		}
++		hl->dl_readers++;
++	}
++	hl->dl_pid = current->pid;
++	spin_unlock(&dl->dl_list_lock);
++
++	return hl;
++}
++
++
++/*
++ * dynlock_unlock
++ *
++ * user have to specify lockspace (dl) and pointer to lock structure
++ * returned by dynlock_lock()
++ *
++ */
++void dynlock_unlock(struct dynlock *dl, void *lock)
++{
++	struct dynlock_member *hl = lock;
++	int wakeup = 0;
++	
++	spin_lock(&dl->dl_list_lock);
++	if (hl->dl_writers) {
++		hl->dl_writers--;
++		if (hl->dl_writers == 0)
++			wakeup = 1;
++	} else {
++		hl->dl_readers--;
++		if (hl->dl_readers == 0)
++			wakeup = 1;
++	}
++	if (wakeup) {
++		hl->dl_pid = 0;
++		wake_up(&hl->dl_wait);
++	}
++	if (--(hl->dl_refcount) == 0) 
++		list_del(&hl->dl_list);
++	spin_unlock(&dl->dl_list_lock);
++	if (hl->dl_refcount == 0)
++		kfree(hl);
++}
++
++EXPORT_SYMBOL(dynlock_init);
++EXPORT_SYMBOL(dynlock_lock);
++EXPORT_SYMBOL(dynlock_unlock);
++
+--- linux-2.4.18/lib/Makefile~dynamic-locks-2.4.18-chaos	2003-08-29 11:57:40.000000000 +0400
++++ linux-2.4.18-alexey/lib/Makefile	2003-09-01 16:35:23.000000000 +0400
+@@ -8,9 +8,9 @@
+ 
+ L_TARGET := lib.a
+ 
+-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
++export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o dynlocks.o
+ 
+-obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
++obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o dynlocks.o
+ 
+ obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+ obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+
+_
diff --git a/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch b/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..59f0a3eef4099475f2ba205c610049c55104c56b
--- /dev/null
+++ b/lustre/kernel_patches/patches/dynamic-locks-2.4.20-rh.patch
@@ -0,0 +1,217 @@
+ include/linux/dynlocks.h |   33 ++++++++++
+ lib/Makefile             |    4 -
+ lib/dynlocks.c           |  152 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 187 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.20-rh/include/linux/dynlocks.h
+===================================================================
+--- linux-2.4.20-rh.orig/include/linux/dynlocks.h	2003-09-04 18:25:49.000000000 +0800
++++ linux-2.4.20-rh/include/linux/dynlocks.h	2003-09-04 18:25:49.000000000 +0800
+@@ -0,0 +1,33 @@
++#ifndef _LINUX_DYNLOCKS_H
++#define _LINUX_DYNLOCKS_H
++
++#include <linux/list.h>
++#include <linux/wait.h>
++
++struct dynlock_member {
++	struct list_head	dl_list;
++	unsigned long		dl_value;	/* lock value */
++	int			dl_refcount;	/* number of users */
++	int			dl_readers;
++	int			dl_writers;
++	int			dl_pid;		/* holder of the lock */
++	wait_queue_head_t	dl_wait;
++};
++
++/*
++ * lock's namespace:
++ *   - list of locks
++ *   - lock to protect this list
++ */
++struct dynlock {
++	struct list_head dl_list;
++	spinlock_t dl_list_lock;
++};
++
++void dynlock_init(struct dynlock *dl);
++void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp);
++void dynlock_unlock(struct dynlock *dl, void *lock);
++
++
++#endif
++
+Index: linux-2.4.20-rh/lib/dynlocks.c
+===================================================================
+--- linux-2.4.20-rh.orig/lib/dynlocks.c	2003-09-04 18:25:49.000000000 +0800
++++ linux-2.4.20-rh/lib/dynlocks.c	2003-09-04 18:25:49.000000000 +0800
+@@ -0,0 +1,152 @@
++/*
++ * Dynamic Locks
++ *
++ * struct dynlock is lockspace
++ * one may request lock (exclusive or shared) for some value
++ * in that lockspace
++ *
++ */
++
++#include <linux/dynlocks.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++/*
++ * dynlock_init
++ *
++ * initialize lockspace
++ *
++ */
++void dynlock_init(struct dynlock *dl)
++{
++	spin_lock_init(&dl->dl_list_lock);
++	INIT_LIST_HEAD(&dl->dl_list);
++}
++
++/*
++ * dynlock_lock
++ *
++ * acquires lock (exclusive or shared) in specified lockspace
++ * each lock in lockspace is allocated separately, so user have
++ * to specify GFP flags.
++ * routine returns pointer to lock. this pointer is intended to
++ * be passed to dynlock_unlock
++ *
++ */
++void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp)
++{
++	struct dynlock_member *nhl = NULL; 
++	struct dynlock_member *hl; 
++	struct list_head *cur;
++
++repeat:
++	/* find requested lock in lockspace */
++	spin_lock(&dl->dl_list_lock);
++	list_for_each(cur, &dl->dl_list) {
++		hl = list_entry(cur, struct dynlock_member, dl_list);
++		if (hl->dl_value == value) {
++			/* lock is found */
++			if (nhl) {
++				/* someone else just allocated
++				 * lock we didn't find and just created
++				 * so, we drop our lock
++				 */
++				kfree(nhl);
++				nhl = NULL;
++			}
++			hl->dl_refcount++;
++			goto found;
++		}
++	}
++	/* lock not found */
++	if (nhl) {
++		/* we already have allocated lock. use it */
++		hl = nhl;
++		nhl = NULL;
++		list_add(&hl->dl_list, &dl->dl_list);
++		goto found;
++	}
++	spin_unlock(&dl->dl_list_lock);
++	
++	/* lock not found and we haven't allocated lock yet. allocate it */
++	nhl = kmalloc(sizeof(struct dynlock_member), gfp);
++	if (nhl == NULL)
++		return NULL;
++	nhl->dl_refcount = 1;
++	nhl->dl_value = value;
++	nhl->dl_readers = 0;
++	nhl->dl_writers = 0;
++	init_waitqueue_head(&nhl->dl_wait);
++
++	/* while lock is being allocated, someone else may allocate it
++	 * and put onto to list. check this situation
++	 */
++	goto repeat;
++
++found:
++	if (rw) {
++		/* exclusive lock: user don't want to share lock at all
++		 * NOTE: one process may take the same lock several times
++		 * this functionaly is useful for rename operations */
++		while ((hl->dl_writers && hl->dl_pid != current->pid) ||
++				hl->dl_readers) {
++			spin_unlock(&dl->dl_list_lock);
++			wait_event(hl->dl_wait,
++				hl->dl_writers == 0 && hl->dl_readers == 0);
++			spin_lock(&dl->dl_list_lock);
++		}
++		hl->dl_writers++;
++	} else {
++		/* shared lock: user do not want to share lock with writer */
++		while (hl->dl_writers) {
++			spin_unlock(&dl->dl_list_lock);
++			wait_event(hl->dl_wait, hl->dl_writers == 0);
++			spin_lock(&dl->dl_list_lock);
++		}
++		hl->dl_readers++;
++	}
++	hl->dl_pid = current->pid;
++	spin_unlock(&dl->dl_list_lock);
++
++	return hl;
++}
++
++
++/*
++ * dynlock_unlock
++ *
++ * user have to specify lockspace (dl) and pointer to lock structure
++ * returned by dynlock_lock()
++ *
++ */
++void dynlock_unlock(struct dynlock *dl, void *lock)
++{
++	struct dynlock_member *hl = lock;
++	int wakeup = 0;
++	
++	spin_lock(&dl->dl_list_lock);
++	if (hl->dl_writers) {
++		hl->dl_writers--;
++		if (hl->dl_writers == 0)
++			wakeup = 1;
++	} else {
++		hl->dl_readers--;
++		if (hl->dl_readers == 0)
++			wakeup = 1;
++	}
++	if (wakeup) {
++		hl->dl_pid = 0;
++		wake_up(&hl->dl_wait);
++	}
++	if (--(hl->dl_refcount) == 0) 
++		list_del(&hl->dl_list);
++	spin_unlock(&dl->dl_list_lock);
++	if (hl->dl_refcount == 0)
++		kfree(hl);
++}
++
++EXPORT_SYMBOL(dynlock_init);
++EXPORT_SYMBOL(dynlock_lock);
++EXPORT_SYMBOL(dynlock_unlock);
++
+Index: linux-2.4.20-rh/lib/Makefile
+===================================================================
+--- linux-2.4.20-rh.orig/lib/Makefile	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-rh/lib/Makefile	2003-09-04 18:27:26.000000000 +0800
+@@ -8,10 +8,10 @@
+ 
+ L_TARGET := lib.a
+ 
+-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
++export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o dynlocks.o
+ 
+ obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \
+-	 bust_spinlocks.o rbtree.o dump_stack.o
++	 bust_spinlocks.o rbtree.o dump_stack.o dynlocks.o
+ 
+ obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+ obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
diff --git a/lustre/kernel_patches/patches/export-add_to_page_cache.patch b/lustre/kernel_patches/patches/export-add_to_page_cache.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0d3b5daab01938ad0776b843c9c31a88d61a216f
--- /dev/null
+++ b/lustre/kernel_patches/patches/export-add_to_page_cache.patch
@@ -0,0 +1,23 @@
+ mm/filemap.c |    2 ++
+ 1 files changed, 2 insertions(+)
+
+--- linux-2.4.20-l19/mm/filemap.c~export-add_to_page_cache	2003-07-15 03:05:47.000000000 -0500
++++ linux-2.4.20-l19-zab/mm/filemap.c	2003-07-15 15:33:01.000000000 -0500
+@@ -670,6 +670,7 @@ void add_to_page_cache(struct page * pag
+ 	spin_unlock(&pagecache_lock);
+ 	lru_cache_add(page);
+ }
++EXPORT_SYMBOL_GPL(add_to_page_cache);
+ 
+ int add_to_page_cache_unique(struct page * page,
+ 	struct address_space *mapping, unsigned long offset,
+@@ -692,6 +693,7 @@ int add_to_page_cache_unique(struct page
+ 		lru_cache_add(page);
+ 	return err;
+ }
++EXPORT_SYMBOL_GPL(add_to_page_cache_unique);
+ 
+ /*
+  * This adds the requested page to the page cache if it isn't already there,
+
+_
diff --git a/lustre/kernel_patches/patches/export-netpoll.patch b/lustre/kernel_patches/patches/export-netpoll.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6d309417fcf9c897676026647920e98b030d9fc4
--- /dev/null
+++ b/lustre/kernel_patches/patches/export-netpoll.patch
@@ -0,0 +1,16 @@
+Index: linux-2.6.0-test5/net/core/netpoll.c
+===================================================================
+--- linux-2.6.0-test5.orig/net/core/netpoll.c	2003-09-26 15:42:10.000000000 +0800
++++ linux-2.6.0-test5/net/core/netpoll.c	2003-09-26 15:42:32.000000000 +0800
+@@ -630,3 +630,11 @@
+ {
+ 	trapped = trap;
+ }
++EXPORT_SYMBOL(netpoll_set_trap);
++EXPORT_SYMBOL(netpoll_trap);
++EXPORT_SYMBOL(netpoll_parse_options);
++EXPORT_SYMBOL(netpoll_setup);
++EXPORT_SYMBOL(netpoll_cleanup);
++EXPORT_SYMBOL(netpoll_send_skb);
++EXPORT_SYMBOL(netpoll_send_udp);
++EXPORT_SYMBOL(netpoll_poll);
diff --git a/lustre/kernel_patches/patches/export_symbols-2.6.0-test6.patch b/lustre/kernel_patches/patches/export_symbols-2.6.0-test6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..93aa5ff2bbea2e07acfcc7aee75b08c492c7e87a
--- /dev/null
+++ b/lustre/kernel_patches/patches/export_symbols-2.6.0-test6.patch
@@ -0,0 +1,68 @@
+Index: linux-2.6.0-test6/fs/filesystems.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/filesystems.c	2003-09-28 08:50:40.000000000 +0800
++++ linux-2.6.0-test6/fs/filesystems.c	2003-10-07 18:07:58.000000000 +0800
+@@ -27,7 +27,7 @@
+  */
+ 
+ static struct file_system_type *file_systems;
+-static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
++rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
+ 
+ /* WARNING: This can be used only if we _already_ own a reference */
+ void get_filesystem(struct file_system_type *fs)
+Index: linux-2.6.0-test6/include/linux/fs.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/fs.h	2003-10-07 16:09:11.000000000 +0800
++++ linux-2.6.0-test6/include/linux/fs.h	2003-10-09 19:47:24.996871688 +0800
+@@ -1385,6 +1385,7 @@
+ 
+ extern struct file_operations generic_ro_fops;
+ 
++extern rwlock_t file_systems_lock;
+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
+ 
+ extern int vfs_readlink(struct dentry *, char __user *, int, const char *);
+Index: linux-2.6.0-test6/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/ksyms.c	2003-10-07 16:09:09.000000000 +0800
++++ linux-2.6.0-test6/kernel/ksyms.c	2003-10-07 18:07:58.000000000 +0800
+@@ -393,3 +393,4 @@
+ EXPORT_SYMBOL(dump_oncpu);
+ EXPORT_SYMBOL(dump_function_ptr);
+ #endif
++EXPORT_SYMBOL(file_systems_lock);
+Index: linux-2.6.0-test6/include/linux/ext2_fs_sb.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/ext2_fs_sb.h	2003-09-28 08:50:57.000000000 +0800
++++ linux-2.6.0-test6/include/linux/ext2_fs_sb.h	2003-10-07 18:07:58.000000000 +0800
+@@ -16,9 +16,11 @@
+ #ifndef _LINUX_EXT2_FS_SB
+ #define _LINUX_EXT2_FS_SB
+ 
++#ifndef EXT_INCLUDE
++#define EXT_INCLUDE
+ #include <linux/blockgroup_lock.h>
+ #include <linux/percpu_counter.h>
+-
++#endif
+ /*
+  * second extended-fs super-block data in memory
+  */
+Index: linux-2.6.0-test6/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/ext3_fs_sb.h	2003-09-28 08:51:00.000000000 +0800
++++ linux-2.6.0-test6/include/linux/ext3_fs_sb.h	2003-10-07 18:07:58.000000000 +0800
+@@ -19,9 +19,12 @@
+ #ifdef __KERNEL__
+ #include <linux/timer.h>
+ #include <linux/wait.h>
++#ifndef EXT_INCLUDE
++#define EXT_INCLUDE
+ #include <linux/blockgroup_lock.h>
+ #include <linux/percpu_counter.h>
+ #endif
++#endif
+ 
+ /*
+  * third extended-fs super-block data in memory
diff --git a/lustre/kernel_patches/patches/exports_2.4.19-pre1.patch b/lustre/kernel_patches/patches/exports_2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9c37bbc0d78a59d6a015cb9f0aaca6e18b073cf4
--- /dev/null
+++ b/lustre/kernel_patches/patches/exports_2.4.19-pre1.patch
@@ -0,0 +1,62 @@
+
+
+
+ fs/ext3/Makefile   |    4 +++-
+ fs/ext3/super.c    |    2 +-
+ include/linux/fs.h |    1 +
+ kernel/ksyms.c     |    5 +++++
+ 4 files changed, 10 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.19-pre1/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/Makefile	2003-11-21 02:39:49.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/Makefile	2003-11-21 02:41:04.000000000 +0300
+@@ -9,6 +9,8 @@
+ 
+ O_TARGET := ext3.o
+ 
++export-objs :=	super.o inode.o
++
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+Index: linux-2.4.19-pre1/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/super.c	2003-11-21 02:39:49.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/super.c	2003-11-21 02:41:04.000000000 +0300
+@@ -1744,7 +1744,7 @@
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
+-EXPORT_NO_SYMBOLS;
++EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+Index: linux-2.4.19-pre1/include/linux/fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs.h	2003-11-21 02:39:49.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs.h	2003-11-21 02:41:41.000000000 +0300
+@@ -984,6 +984,7 @@
+ extern struct vfsmount *kern_mount(struct file_system_type *);
+ extern int may_umount(struct vfsmount *);
+ extern long do_mount(char *, char *, char *, unsigned long, void *);
++struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
+ 
+ #define kern_umount mntput
+ 
+Index: linux-2.4.19-pre1/kernel/ksyms.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/ksyms.c	2003-11-21 02:39:49.000000000 +0300
++++ linux-2.4.19-pre1/kernel/ksyms.c	2003-11-21 02:41:04.000000000 +0300
+@@ -271,6 +271,10 @@
+ EXPORT_SYMBOL(lock_may_write);
+ EXPORT_SYMBOL(dcache_readdir);
+ 
++/* lustre */
++EXPORT_SYMBOL(panic_notifier_list);
++EXPORT_SYMBOL(do_kern_mount);
++
+ /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
+ EXPORT_SYMBOL(default_llseek);
+ EXPORT_SYMBOL(dentry_open);
diff --git a/lustre/kernel_patches/patches/exports_2.4.19-suse.patch b/lustre/kernel_patches/patches/exports_2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..feaeec6ddd796c40f955dc558659d9bc7924f85f
--- /dev/null
+++ b/lustre/kernel_patches/patches/exports_2.4.19-suse.patch
@@ -0,0 +1,53 @@
+ fs/ext3/Makefile   |    2 ++
+ fs/ext3/super.c    |    2 +-
+ include/linux/fs.h |    1 +
+ kernel/ksyms.c     |    4 ++++
+ 4 files changed, 8 insertions(+), 1 deletion(-)
+
+--- linux/fs/ext3/Makefile~exports_2.4.20	Wed Apr  9 10:07:14 2003
++++ linux-mmonroe/fs/ext3/Makefile	Wed Apr  9 10:19:53 2003
+@@ -9,6 +9,8 @@
+ 
+ O_TARGET := ext3.o
+ 
++export-objs :=	super.o inode.o
++
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+--- linux/fs/ext3/super.c~exports_2.4.20	Wed Apr  9 10:07:14 2003
++++ linux-mmonroe/fs/ext3/super.c	Wed Apr  9 10:19:53 2003
+@@ -1769,7 +1769,7 @@ static void __exit exit_ext3_fs(void)
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
+-EXPORT_NO_SYMBOLS;
++EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+--- linux/include/linux/fs.h~exports_2.4.20	Wed Apr  9 10:07:14 2003
++++ linux-mmonroe/include/linux/fs.h	Wed Apr  9 10:19:53 2003
+@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct 
+ extern struct vfsmount *kern_mount(struct file_system_type *);
+ extern int may_umount(struct vfsmount *);
+ extern long do_mount(char *, char *, char *, unsigned long, void *);
++struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
+ 
+ #define kern_umount mntput
+ 
+--- linux/kernel/ksyms.c~exports_2.4.20	Wed Apr  9 10:07:14 2003
++++ linux-mmonroe/kernel/ksyms.c	Wed Apr  9 10:19:53 2003
+@@ -308,6 +308,10 @@ EXPORT_SYMBOL(dcache_dir_fsync);
+ EXPORT_SYMBOL(dcache_readdir);
+ EXPORT_SYMBOL(dcache_dir_ops);
+ 
++/* lustre */
++EXPORT_SYMBOL(pagecache_lock_cacheline);
++EXPORT_SYMBOL(do_kern_mount);
++
+ /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
+ EXPORT_SYMBOL(default_llseek);
+ EXPORT_SYMBOL(dentry_open);
+
+_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch
index b59cea2cb12ed757ea802c2256f083317ebdf2fd..3de6a8f88b65a71d2e3f16f30fecb70887be9d28 100644
--- a/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch
+++ b/lustre/kernel_patches/patches/ext-2.4-patch-1-chaos.patch
@@ -1190,28 +1190,28 @@
 +
 +static void dx_sort_map (struct dx_map_entry *map, unsigned count)
 +{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
++	struct dx_map_entry *p, *q, *top = map + count - 1;
++	int more;
++	/* Combsort until bubble sort doesn't suck */
++	while (count > 2)
 +	{
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
++		count = count*10/13;
++		if (count - 9 < 2) /* 9, 10 -> 11 */
++			count = 11;
++		for (p = top, q = p - count; q >= map; p--, q--)
++			if (p->hash < q->hash)
++				swap(*p, *q);
++	}
++	/* Garden variety bubble sort */
++	do {
++		more = 0;
++		q = top;
++		while (q-- > map)
 +		{
-+                        if (q[1].hash >= q[0].hash)
++			if (q[1].hash >= q[0].hash)
 +				continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
++			swap(*(q+1), *q);
++			more = 1;
 +		}
 +	} while(more);
 +}
@@ -1381,7 +1381,7 @@
  	}
  	d_add(dentry, inode);
  	return NULL;
-@@ -238,6 +952,300 @@ static inline void ext3_set_de_type(stru
+@@ -238,6 +952,301 @@ static inline void ext3_set_de_type(stru
  		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
  }
  
@@ -1642,7 +1642,8 @@
 +	data1 = bh2->b_data;
 +
 +	/* The 0th block becomes the root, move the dirents out */
-+	de = (struct ext3_dir_entry_2 *) &root->info;
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
 +	len = ((char *) root) + blocksize - (char *) de;
 +	memcpy (data1, de, len);
 +	de = (struct ext3_dir_entry_2 *) data1;
@@ -2192,7 +2193,7 @@
 -	inode->u.ext3_i.i_disksize = inode->i_size;
 + 	EXT3_I(inode)->i_disksize = inode->i_size;
  	err = ext3_add_nondir(handle, dentry, inode);
-+  	ext3_mark_inode_dirty(handle, inode);
++	ext3_mark_inode_dirty(handle, inode);
  out_stop:
  	ext3_journal_stop(handle, dir);
  	return err;
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1-suse.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..748671feedb886b57c01de29f82cb5e7eb717fc5
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext-2.4-patch-1-suse.patch
@@ -0,0 +1,2528 @@
+ fs/ext3/Makefile           |    2 
+ fs/ext3/dir.c              |  299 +++++++++
+ fs/ext3/file.c             |    3 
+ fs/ext3/hash.c             |  215 ++++++
+ fs/ext3/namei.c            | 1387 ++++++++++++++++++++++++++++++++++++++++-----
+ fs/ext3/super.c            |    7 
+ include/linux/ext3_fs.h    |   85 ++
+ include/linux/ext3_fs_sb.h |    2 
+ include/linux/ext3_jbd.h   |    2 
+ include/linux/rbtree.h     |    2 
+ lib/rbtree.c               |   42 +
+ 11 files changed, 1886 insertions(+), 160 deletions(-)
+
+--- linux-2.4.20/fs/ext3/Makefile~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/fs/ext3/Makefile	Sat Apr  5 03:57:05 2003
+@@ -12,7 +12,7 @@ O_TARGET := ext3.o
+ export-objs :=	super.o inode.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o
++		ioctl.o namei.o super.o symlink.o hash.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.20/fs/ext3/dir.c~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/fs/ext3/dir.c	Sat Apr  5 03:56:31 2003
+@@ -21,12 +21,16 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/slab.h>
++#include <linux/rbtree.h>
+ 
+ static unsigned char ext3_filetype_table[] = {
+ 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+ };
+ 
+ static int ext3_readdir(struct file *, void *, filldir_t);
++static int ext3_dx_readdir(struct file * filp,
++			   void * dirent, filldir_t filldir);
+ 
+ struct file_operations ext3_dir_operations = {
+ 	read:		generic_read_dir,
+@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
+ 	fsync:		ext3_sync_file,		/* BKL held */
+ };
+ 
++
++static unsigned char get_dtype(struct super_block *sb, int filetype)
++{
++	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
++	    (filetype >= EXT3_FT_MAX))
++		return DT_UNKNOWN;
++
++	return (ext3_filetype_table[filetype]);
++}
++			       
++
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ 			  struct ext3_dir_entry_2 * de,
+ 			  struct buffer_head * bh,
+@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
+ 
+ 	sb = inode->i_sb;
+ 
++	if (is_dx(inode)) {
++		err = ext3_dx_readdir(filp, dirent, filldir);
++		if (err != ERR_BAD_DX_DIR)
++			return err;
++		/*
++		 * We don't set the inode dirty flag since it's not
++		 * critical that it get flushed back to the disk.
++		 */
++		EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
++	}
+ 	stored = 0;
+ 	bh = NULL;
+ 	offset = filp->f_pos & (sb->s_blocksize - 1);
+@@ -162,18 +187,12 @@ revalidate:
+ 				 * during the copy operation.
+ 				 */
+ 				unsigned long version = filp->f_version;
+-				unsigned char d_type = DT_UNKNOWN;
+ 
+-				if (EXT3_HAS_INCOMPAT_FEATURE(sb,
+-						EXT3_FEATURE_INCOMPAT_FILETYPE)
+-						&& de->file_type < EXT3_FT_MAX)
+-					d_type =
+-					  ext3_filetype_table[de->file_type];
+ 				error = filldir(dirent, de->name,
+ 						de->name_len,
+ 						filp->f_pos,
+ 						le32_to_cpu(de->inode),
+-						d_type);
++						get_dtype(sb, de->file_type));
+ 				if (error)
+ 					break;
+ 				if (version != filp->f_version)
+@@ -188,3 +207,269 @@ revalidate:
+ 	UPDATE_ATIME(inode);
+ 	return 0;
+ }
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * These functions convert from the major/minor hash to an f_pos
++ * value.
++ * 
++ * Currently we only use major hash numer.  This is unfortunate, but
++ * on 32-bit machines, the same VFS interface is used for lseek and
++ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
++ * lseek/telldir/seekdir will blow out spectacularly, and from within
++ * the ext2 low-level routine, we don't know if we're being called by
++ * a 64-bit version of the system call or the 32-bit version of the
++ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
++ * cookie.  Sigh.
++ */
++#define hash2pos(major, minor)	(major >> 1)
++#define pos2maj_hash(pos)	((pos << 1) & 0xffffffff)
++#define pos2min_hash(pos)	(0)
++
++/*
++ * This structure holds the nodes of the red-black tree used to store
++ * the directory entry in hash order.
++ */
++struct fname {
++	__u32		hash;
++	__u32		minor_hash;
++	rb_node_t	rb_hash; 
++	struct fname	*next;
++	__u32		inode;
++	__u8		name_len;
++	__u8		file_type;
++	char		name[0];
++};
++
++/*
++ * This functoin implements a non-recursive way of freeing all of the
++ * nodes in the red-black tree.
++ */
++static void free_rb_tree_fname(rb_root_t *root)
++{
++	rb_node_t	*n = root->rb_node;
++	rb_node_t	*parent;
++	struct fname	*fname;
++
++	while (n) {
++		/* Do the node's children first */
++		if ((n)->rb_left) {
++			n = n->rb_left;
++			continue;
++		}
++		if (n->rb_right) {
++			n = n->rb_right;
++			continue;
++		}
++		/*
++		 * The node has no children; free it, and then zero
++		 * out parent's link to it.  Finally go to the
++		 * beginning of the loop and try to free the parent
++		 * node.
++		 */
++		parent = n->rb_parent;
++		fname = rb_entry(n, struct fname, rb_hash);
++		kfree(fname);
++		if (!parent)
++			root->rb_node = 0;
++		else if (parent->rb_left == n)
++			parent->rb_left = 0;
++		else if (parent->rb_right == n)
++			parent->rb_right = 0;
++		n = parent;
++	}
++	root->rb_node = 0;
++}
++
++
++struct dir_private_info *create_dir_info(loff_t pos)
++{
++	struct dir_private_info *p;
++
++	p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
++	if (!p)
++		return NULL;
++	p->root.rb_node = 0;
++	p->curr_node = 0;
++	p->extra_fname = 0;
++	p->last_pos = 0;
++	p->curr_hash = pos2maj_hash(pos);
++	p->curr_minor_hash = pos2min_hash(pos);
++	p->next_hash = 0;
++	return p;
++}
++
++void ext3_htree_free_dir_info(struct dir_private_info *p)
++{
++	free_rb_tree_fname(&p->root);
++	kfree(p);
++}
++		
++/*
++ * Given a directory entry, enter it into the fname rb tree.
++ */
++void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++			     __u32 minor_hash,
++			     struct ext3_dir_entry_2 *dirent)
++{
++	rb_node_t **p, *parent = NULL;
++	struct fname * fname, *new_fn;
++	struct dir_private_info *info;
++	int len;
++
++	info = (struct dir_private_info *) dir_file->private_data;
++	p = &info->root.rb_node;
++
++	/* Create and allocate the fname structure */
++	len = sizeof(struct fname) + dirent->name_len + 1;
++	new_fn = kmalloc(len, GFP_KERNEL);
++	memset(new_fn, 0, len);
++	new_fn->hash = hash;
++	new_fn->minor_hash = minor_hash;
++	new_fn->inode = le32_to_cpu(dirent->inode);
++	new_fn->name_len = dirent->name_len;
++	new_fn->file_type = dirent->file_type;
++	memcpy(new_fn->name, dirent->name, dirent->name_len);
++	new_fn->name[dirent->name_len] = 0;
++	
++	while (*p) {
++		parent = *p;
++		fname = rb_entry(parent, struct fname, rb_hash);
++
++		/*
++		 * If the hash and minor hash match up, then we put
++		 * them on a linked list.  This rarely happens...
++		 */
++		if ((new_fn->hash == fname->hash) &&
++		    (new_fn->minor_hash == fname->minor_hash)) {
++			new_fn->next = fname->next;
++			fname->next = new_fn;
++			return;
++		}
++			
++		if (new_fn->hash < fname->hash)
++			p = &(*p)->rb_left;
++		else if (new_fn->hash > fname->hash)
++			p = &(*p)->rb_right;
++		else if (new_fn->minor_hash < fname->minor_hash)
++			p = &(*p)->rb_left;
++		else /* if (new_fn->minor_hash > fname->minor_hash) */
++			p = &(*p)->rb_right;
++	}
++
++	rb_link_node(&new_fn->rb_hash, parent, p);
++	rb_insert_color(&new_fn->rb_hash, &info->root);
++}
++
++
++
++/*
++ * This is a helper function for ext3_dx_readdir.  It calls filldir
++ * for all entres on the fname linked list.  (Normally there is only
++ * one entry on the linked list, unless there are 62 bit hash collisions.)
++ */
++static int call_filldir(struct file * filp, void * dirent,
++			filldir_t filldir, struct fname *fname)
++{
++	struct dir_private_info *info = filp->private_data;
++	loff_t	curr_pos;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct super_block * sb;
++	int error;
++
++	sb = inode->i_sb;
++	
++	if (!fname) {
++		printk("call_filldir: called with null fname?!?\n");
++		return 0;
++	}
++	curr_pos = hash2pos(fname->hash, fname->minor_hash);
++	while (fname) {
++		error = filldir(dirent, fname->name,
++				fname->name_len, curr_pos, 
++				fname->inode,
++				get_dtype(sb, fname->file_type));
++		if (error) {
++			filp->f_pos = curr_pos;
++			info->extra_fname = fname->next;
++			return error;
++		}
++		fname = fname->next;
++	}
++	return 0;
++}
++
++static int ext3_dx_readdir(struct file * filp,
++			 void * dirent, filldir_t filldir)
++{
++	struct dir_private_info *info = filp->private_data;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct fname *fname;
++	int	ret;
++
++	if (!info) {
++		info = create_dir_info(filp->f_pos);
++		if (!info)
++			return -ENOMEM;
++		filp->private_data = info;
++	}
++
++	/* Some one has messed with f_pos; reset the world */
++	if (info->last_pos != filp->f_pos) {
++		free_rb_tree_fname(&info->root);
++		info->curr_node = 0;
++		info->extra_fname = 0;
++		info->curr_hash = pos2maj_hash(filp->f_pos);
++		info->curr_minor_hash = pos2min_hash(filp->f_pos);
++	}
++
++	/*
++	 * If there are any leftover names on the hash collision
++	 * chain, return them first.
++	 */
++	if (info->extra_fname &&
++	    call_filldir(filp, dirent, filldir, info->extra_fname))
++		goto finished;
++
++	if (!info->curr_node)
++		info->curr_node = rb_get_first(&info->root);
++
++	while (1) {
++		/*
++		 * Fill the rbtree if we have no more entries,
++		 * or the inode has changed since we last read in the
++		 * cached entries. 
++		 */
++		if ((!info->curr_node) ||
++		    (filp->f_version != inode->i_version)) {
++			info->curr_node = 0;
++			free_rb_tree_fname(&info->root);
++			filp->f_version = inode->i_version;
++			ret = ext3_htree_fill_tree(filp, info->curr_hash,
++						   info->curr_minor_hash,
++						   &info->next_hash);
++			if (ret < 0)
++				return ret;
++			if (ret == 0)
++				break;
++			info->curr_node = rb_get_first(&info->root);
++		}
++
++		fname = rb_entry(info->curr_node, struct fname, rb_hash);
++		info->curr_hash = fname->hash;
++		info->curr_minor_hash = fname->minor_hash;
++		if (call_filldir(filp, dirent, filldir, fname))
++			break;
++
++		info->curr_node = rb_get_next(info->curr_node);
++		if (!info->curr_node) {
++			info->curr_hash = info->next_hash;
++			info->curr_minor_hash = 0;
++		}
++	}
++finished:
++	info->last_pos = filp->f_pos;
++	UPDATE_ATIME(inode);
++	return 0;
++}
++#endif
+--- linux-2.4.20/fs/ext3/file.c~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/fs/ext3/file.c	Sat Apr  5 03:56:31 2003
+@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino
+ {
+ 	if (filp->f_mode & FMODE_WRITE)
+ 		ext3_discard_prealloc (inode);
++	if (is_dx(inode) && filp->private_data)
++		ext3_htree_free_dir_info(filp->private_data);
++
+ 	return 0;
+ }
+ 
+--- /dev/null	Fri Aug 30 17:31:37 2002
++++ linux-2.4.20-braam/fs/ext3/hash.c	Sat Apr  5 03:56:31 2003
+@@ -0,0 +1,215 @@
++/*
++ *  linux/fs/ext3/hash.c
++ *
++ * Copyright (C) 2002 by Theodore Ts'o
++ *
++ * This file is released under the GPL v2.
++ * 
++ * This file may be redistributed under the terms of the GNU Public
++ * License.
++ */
++
++#include <linux/fs.h>
++#include <linux/jbd.h>
++#include <linux/sched.h>
++#include <linux/ext3_fs.h>
++
++#define DELTA 0x9E3779B9
++
++static void TEA_transform(__u32 buf[4], __u32 const in[])
++{
++	__u32	sum = 0;
++	__u32	b0 = buf[0], b1 = buf[1];
++	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
++	int	n = 16;
++
++	do {							
++		sum += DELTA;					
++		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
++		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
++	} while(--n);
++
++	buf[0] += b0;
++	buf[1] += b1;
++}
++
++/* F, G and H are basic MD4 functions: selection, majority, parity */
++#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
++#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
++#define H(x, y, z) ((x) ^ (y) ^ (z))
++
++/*
++ * The generic round function.  The application is so specific that
++ * we don't bother protecting all the arguments with parens, as is generally
++ * good macro practice, in favor of extra legibility.
++ * Rotation is separate from addition to prevent recomputation
++ */
++#define ROUND(f, a, b, c, d, x, s)	\
++	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
++#define K1 0
++#define K2 013240474631UL
++#define K3 015666365641UL
++
++/*
++ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
++ */
++static void halfMD4Transform (__u32 buf[4], __u32 const in[])
++{
++	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
++
++	/* Round 1 */
++	ROUND(F, a, b, c, d, in[0] + K1,  3);
++	ROUND(F, d, a, b, c, in[1] + K1,  7);
++	ROUND(F, c, d, a, b, in[2] + K1, 11);
++	ROUND(F, b, c, d, a, in[3] + K1, 19);
++	ROUND(F, a, b, c, d, in[4] + K1,  3);
++	ROUND(F, d, a, b, c, in[5] + K1,  7);
++	ROUND(F, c, d, a, b, in[6] + K1, 11);
++	ROUND(F, b, c, d, a, in[7] + K1, 19);
++
++	/* Round 2 */
++	ROUND(G, a, b, c, d, in[1] + K2,  3);
++	ROUND(G, d, a, b, c, in[3] + K2,  5);
++	ROUND(G, c, d, a, b, in[5] + K2,  9);
++	ROUND(G, b, c, d, a, in[7] + K2, 13);
++	ROUND(G, a, b, c, d, in[0] + K2,  3);
++	ROUND(G, d, a, b, c, in[2] + K2,  5);
++	ROUND(G, c, d, a, b, in[4] + K2,  9);
++	ROUND(G, b, c, d, a, in[6] + K2, 13);
++
++	/* Round 3 */
++	ROUND(H, a, b, c, d, in[3] + K3,  3);
++	ROUND(H, d, a, b, c, in[7] + K3,  9);
++	ROUND(H, c, d, a, b, in[2] + K3, 11);
++	ROUND(H, b, c, d, a, in[6] + K3, 15);
++	ROUND(H, a, b, c, d, in[1] + K3,  3);
++	ROUND(H, d, a, b, c, in[5] + K3,  9);
++	ROUND(H, c, d, a, b, in[0] + K3, 11);
++	ROUND(H, b, c, d, a, in[4] + K3, 15);
++
++	buf[0] += a;
++	buf[1] += b;
++	buf[2] += c;
++	buf[3] += d;
++}
++
++#undef ROUND
++#undef F
++#undef G
++#undef H
++#undef K1
++#undef K2
++#undef K3
++
++/* The old legacy hash */
++static __u32 dx_hack_hash (const char *name, int len)
++{
++	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++	while (len--) {
++		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++		
++		if (hash & 0x80000000) hash -= 0x7fffffff;
++		hash1 = hash0;
++		hash0 = hash;
++	}
++	return (hash0 << 1);
++}
++
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++{
++	__u32	pad, val;
++	int	i;
++
++	pad = (__u32)len | ((__u32)len << 8);
++	pad |= pad << 16;
++
++	val = pad;
++	if (len > num*4)
++		len = num * 4;
++	for (i=0; i < len; i++) {
++		if ((i % 4) == 0)
++			val = pad;
++		val = msg[i] + (val << 8);
++		if ((i % 4) == 3) {
++			*buf++ = val;
++			val = pad;
++			num--;
++		}
++	}
++	if (--num >= 0)
++		*buf++ = val;
++	while (--num >= 0)
++		*buf++ = pad;
++}
++
++/*
++ * Returns the hash of a filename.  If len is 0 and name is NULL, then
++ * this function can be used to test whether or not a hash version is
++ * supported.
++ * 
++ * The seed is an 4 longword (32 bits) "secret" which can be used to
++ * uniquify a hash.  If the seed is all zero's, then some default seed
++ * may be used.
++ * 
++ * A particular hash version specifies whether or not the seed is
++ * represented, and whether or not the returned hash is 32 bits or 64
++ * bits.  32 bit hashes will return 0 for the minor hash.
++ */
++int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
++{
++	__u32	hash;
++	__u32	minor_hash = 0;
++	const char	*p;
++	int		i;
++	__u32 		in[8], buf[4];
++
++	/* Initialize the default seed for the hash checksum functions */
++	buf[0] = 0x67452301;
++	buf[1] = 0xefcdab89;
++	buf[2] = 0x98badcfe;
++	buf[3] = 0x10325476;
++
++	/* Check to see if the seed is all zero's */
++	if (hinfo->seed) {
++		for (i=0; i < 4; i++) {
++			if (hinfo->seed[i])
++				break;
++		}
++		if (i < 4)
++			memcpy(buf, hinfo->seed, sizeof(buf));
++	}
++		
++	switch (hinfo->hash_version) {
++	case DX_HASH_LEGACY:
++		hash = dx_hack_hash(name, len);
++		break;
++	case DX_HASH_HALF_MD4:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 8);
++			halfMD4Transform(buf, in);
++			len -= 32;
++			p += 32;
++		}
++		minor_hash = buf[2];
++		hash = buf[1];
++		break;
++	case DX_HASH_TEA:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 4);
++			TEA_transform(buf, in);
++			len -= 16;
++			p += 16;
++		}
++		hash = buf[0];
++		minor_hash = buf[1];
++		break;
++	default:
++		hinfo->hash = 0;
++		return -1;
++	}
++	hinfo->hash = hash & ~1;
++	hinfo->minor_hash = minor_hash;
++	return 0;
++}
+--- linux-2.4.20/fs/ext3/namei.c~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/fs/ext3/namei.c	Sat Apr  5 03:56:31 2003
+@@ -16,6 +16,12 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  *  Directory entry file type support and forward compatibility hooks
+  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
++ *  Hash Tree Directory indexing (c)
++ *  	Daniel Phillips, 2001
++ *  Hash Tree Directory indexing porting
++ *  	Christopher Li, 2002
++ *  Hash Tree Directory indexing cleanup
++ * 	Theodore Ts'o, 2002
+  */
+ 
+ #include <linux/fs.h>
+@@ -38,6 +44,630 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+ 
++static struct buffer_head *ext3_append(handle_t *handle,
++					struct inode *inode,
++					u32 *block, int *err)
++{
++	struct buffer_head *bh;
++
++	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
++
++	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++		inode->i_size += inode->i_sb->s_blocksize;
++		EXT3_I(inode)->i_disksize = inode->i_size;
++		ext3_journal_get_write_access(handle,bh);
++	}
++	return bh;
++}
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#ifndef swap
++#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
++#endif
++
++typedef struct { u32 v; } le_u32;
++typedef struct { u16 v; } le_u16;
++
++#ifdef DX_DEBUG
++#define dxtrace(command) command
++#else
++#define dxtrace(command) 
++#endif
++
++struct fake_dirent
++{
++	/*le*/u32 inode;
++	/*le*/u16 rec_len;
++	u8 name_len;
++	u8 file_type;
++};
++
++struct dx_countlimit
++{
++	le_u16 limit;
++	le_u16 count;
++};
++
++struct dx_entry
++{
++	le_u32 hash;
++	le_u32 block;
++};
++
++/*
++ * dx_root_info is laid out so that if it should somehow get overlaid by a
++ * dirent the two low bits of the hash version will be zero.  Therefore, the
++ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
++ */
++
++struct dx_root
++{
++	struct fake_dirent dot;
++	char dot_name[4];
++	struct fake_dirent dotdot;
++	char dotdot_name[4];
++	struct dx_root_info
++	{
++		le_u32 reserved_zero;
++		u8 hash_version;
++		u8 info_length; /* 8 */
++		u8 indirect_levels;
++		u8 unused_flags;
++	}
++	info;
++	struct dx_entry	entries[0];
++};
++
++struct dx_node
++{
++	struct fake_dirent fake;
++	struct dx_entry	entries[0];
++};
++
++
++struct dx_frame
++{
++	struct buffer_head *bh;
++	struct dx_entry *entries;
++	struct dx_entry *at;
++};
++
++struct dx_map_entry
++{
++	u32 hash;
++	u32 offs;
++};
++
++#ifdef CONFIG_EXT3_INDEX
++static inline unsigned dx_get_block (struct dx_entry *entry);
++static void dx_set_block (struct dx_entry *entry, unsigned value);
++static inline unsigned dx_get_hash (struct dx_entry *entry);
++static void dx_set_hash (struct dx_entry *entry, unsigned value);
++static unsigned dx_get_count (struct dx_entry *entries);
++static unsigned dx_get_limit (struct dx_entry *entries);
++static void dx_set_count (struct dx_entry *entries, unsigned value);
++static void dx_set_limit (struct dx_entry *entries, unsigned value);
++static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
++static unsigned dx_node_limit (struct inode *dir);
++static struct dx_frame *dx_probe(struct dentry *dentry,
++				 struct inode *dir,
++				 struct dx_hash_info *hinfo,
++				 struct dx_frame *frame,
++				 int *err);
++static void dx_release (struct dx_frame *frames);
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
++static void dx_sort_map(struct dx_map_entry *map, unsigned count);
++static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
++		struct dx_map_entry *offsets, int count);
++static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
++static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash);
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err);
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode);
++
++/*
++ * Future: use high four bits of block for coalesce-on-delete flags
++ * Mask them off for now.
++ */
++
++static inline unsigned dx_get_block (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->block.v) & 0x00ffffff;
++}
++
++static inline void dx_set_block (struct dx_entry *entry, unsigned value)
++{
++	entry->block.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_hash (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->hash.v);
++}
++
++static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
++{
++	entry->hash.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_count (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
++}
++
++static inline unsigned dx_get_limit (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
++}
++
++static inline void dx_set_count (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
++}
++
++static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
++}
++
++static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
++		EXT3_DIR_REC_LEN(2) - infosize;
++	return 0? 20: entry_space / sizeof(struct dx_entry);
++}
++
++static inline unsigned dx_node_limit (struct inode *dir)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
++	return 0? 22: entry_space / sizeof(struct dx_entry);
++}
++
++/*
++ * Debug
++ */
++#ifdef DX_DEBUG
++struct stats
++{ 
++	unsigned names;
++	unsigned space;
++	unsigned bcount;
++};
++
++static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
++				 int size, int show_names)
++{
++	unsigned names = 0, space = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	printk("names: ");
++	while ((char *) de < base + size)
++	{
++		if (de->inode)
++		{
++			if (show_names)
++			{
++				int len = de->name_len;
++				char *name = de->name;
++				while (len--) printk("%c", *name++);
++				ext3fs_dirhash(de->name, de->name_len, &h);
++				printk(":%x.%u ", h.hash,
++				       ((char *) de - base));
++			}
++			space += EXT3_DIR_REC_LEN(de->name_len);
++	 		names++;
++		}
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	printk("(%i)\n", names);
++	return (struct stats) { names, space, 1 };
++}
++
++struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
++			     struct dx_entry *entries, int levels)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
++	unsigned bcount = 0;
++	struct buffer_head *bh;
++	int err;
++	printk("%i indexed blocks...\n", count);
++	for (i = 0; i < count; i++, entries++)
++	{
++		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
++		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
++		struct stats stats;
++		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
++		if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
++		stats = levels?
++		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
++		   dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
++		names += stats.names;
++		space += stats.space;
++		bcount += stats.bcount;
++		brelse (bh);
++	}
++	if (bcount)
++		printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
++			names, space/bcount,(space/bcount)*100/blocksize);
++	return (struct stats) { names, space, bcount};
++}
++#endif /* DX_DEBUG */
++
++/*
++ * Probe for a directory leaf block to search.
++ *
++ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
++ * error in the directory index, and the caller should fall back to
++ * searching the directory normally.  The callers of dx_probe **MUST**
++ * check for this error code, and make sure it never gets reflected
++ * back to userspace.
++ */
++static struct dx_frame *
++dx_probe(struct dentry *dentry, struct inode *dir,
++	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
++{
++	unsigned count, indirect;
++	struct dx_entry *at, *entries, *p, *q, *m;
++	struct dx_root *root;
++	struct buffer_head *bh;
++	struct dx_frame *frame = frame_in;
++	u32 hash;
++
++	frame->bh = NULL;
++	if (dentry)
++		dir = dentry->d_parent->d_inode;
++	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
++		goto fail;
++	root = (struct dx_root *) bh->b_data;
++	if (root->info.hash_version != DX_HASH_TEA &&
++	    root->info.hash_version != DX_HASH_HALF_MD4 &&
++	    root->info.hash_version != DX_HASH_LEGACY) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unrecognised inode hash code %d",
++			     root->info.hash_version);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++	hinfo->hash_version = root->info.hash_version;
++	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	if (dentry)
++		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	hash = hinfo->hash;
++
++	if (root->info.unused_flags & 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash flags: %#06x",
++			     root->info.unused_flags);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	if ((indirect = root->info.indirect_levels) > 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash depth: %#06x",
++			     root->info.indirect_levels);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	while (1)
++	{
++		count = dx_get_count(entries);
++		assert (count && count <= dx_get_limit(entries));
++		p = entries + 1;
++		q = entries + count - 1;
++		while (p <= q)
++		{
++			m = p + (q - p)/2;
++			dxtrace(printk("."));
++			if (dx_get_hash(m) > hash)
++				q = m - 1;
++			else
++				p = m + 1;
++		}
++
++		if (0) // linear search cross check
++		{
++			unsigned n = count - 1;
++			at = entries;
++			while (n--)
++			{
++				dxtrace(printk(","));
++				if (dx_get_hash(++at) > hash)
++				{
++					at--;
++					break;
++				}
++			}
++			assert (at == p - 1);
++		}
++
++		at = p - 1;
++		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		frame->bh = bh;
++		frame->entries = entries;
++		frame->at = at;
++		if (!indirect--) return frame;
++		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++			goto fail2;
++		at = entries = ((struct dx_node *) bh->b_data)->entries;
++		assert (dx_get_limit(entries) == dx_node_limit (dir));
++		frame++;
++	}
++fail2:
++	while (frame >= frame_in) {
++		brelse(frame->bh);
++		frame--;
++	}
++fail:
++	return NULL;
++}
++
++static void dx_release (struct dx_frame *frames)
++{
++	if (frames[0].bh == NULL)
++		return;
++
++	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++		brelse(frames[1].bh);
++	brelse(frames[0].bh);
++}
++
++/*
++ * This function increments the frame pointer to search the next leaf
++ * block, and reads in the necessary intervening nodes if the search
++ * should be necessary.  Whether or not the search is necessary is
++ * controlled by the hash parameter.  If the hash value is even, then
++ * the search is only continued if the next block starts with that
++ * hash value.  This is used if we are searching for a specific file.
++ *
++ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
++ *
++ * This function returns 1 if the caller should continue to search,
++ * or 0 if it should not.  If there is an error reading one of the
++ * index blocks, it will return -1.
++ *
++ * If start_hash is non-null, it will be filled in with the starting
++ * hash of the next page.
++ */
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash)
++{
++	struct dx_frame *p;
++	struct buffer_head *bh;
++	int num_frames = 0;
++	__u32 bhash;
++
++	*err = ENOENT;
++	p = frame;
++	/*
++	 * Find the next leaf page by incrementing the frame pointer.
++	 * If we run out of entries in the interior node, loop around and
++	 * increment pointer in the parent node.  When we break out of
++	 * this loop, num_frames indicates the number of interior
++	 * nodes need to be read.
++	 */
++	while (1) {
++		if (++(p->at) < p->entries + dx_get_count(p->entries))
++			break;
++		if (p == frames)
++			return 0;
++		num_frames++;
++		p--;
++	}
++
++	/*
++	 * If the hash is 1, then continue only if the next page has a
++	 * continuation hash of any value.  This is used for readdir
++	 * handling.  Otherwise, check to see if the hash matches the
++	 * desired contiuation hash.  If it doesn't, return since
++	 * there's no point to read in the successive index pages.
++	 */
++	bhash = dx_get_hash(p->at);
++	if (start_hash)
++		*start_hash = bhash;
++	if ((hash & 1) == 0) {
++		if ((bhash & ~1) != hash)
++			return 0;
++	}
++	/*
++	 * If the hash is HASH_NB_ALWAYS, we always go to the next
++	 * block so no check is necessary
++	 */
++	while (num_frames--) {
++		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
++				      0, err)))
++			return -1; /* Failure */
++		p++;
++		brelse (p->bh);
++		p->bh = bh;
++		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++	}
++	return 1;
++}
++
++
++/*
++ * p is at least 6 bytes before the end of page
++ */
++static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
++{
++	return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
++}
++
++/*
++ * This function fills a red-black tree with information from a
++ * directory.  We start scanning the directory in hash order, starting
++ * at start_hash and start_minor_hash.
++ *
++ * This function returns the number of entries inserted into the tree,
++ * or a negative error code.
++ */
++int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++			 __u32 start_minor_hash, __u32 *next_hash)
++{
++	struct dx_hash_info hinfo;
++	struct buffer_head *bh;
++	struct ext3_dir_entry_2 *de, *top;
++	static struct dx_frame frames[2], *frame;
++	struct inode *dir;
++	int block, err;
++	int count = 0;
++	int ret;
++	__u32 hashval;
++	
++	dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
++		       start_minor_hash));
++	dir = dir_file->f_dentry->d_inode;
++	hinfo.hash = start_hash;
++	hinfo.minor_hash = 0;
++	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++
++	while (1) {
++		block = dx_get_block(frame->at);
++		dxtrace(printk("Reading block %d\n", block));
++		if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
++			goto errout;
++	
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de)) {
++			ext3fs_dirhash(de->name, de->name_len, &hinfo);
++			if ((hinfo.hash < start_hash) ||
++			    ((hinfo.hash == start_hash) &&
++			     (hinfo.minor_hash < start_minor_hash)))
++				continue;
++			ext3_htree_store_dirent(dir_file, hinfo.hash,
++						hinfo.minor_hash, de);
++			count++;
++		}
++		brelse (bh);
++		hashval = ~1;
++		ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
++					    frame, frames, &err, &hashval);
++		if (next_hash)
++			*next_hash = hashval;
++		if (ret == -1)
++			goto errout;
++		/*
++		 * Stop if:  (a) there are no more entries, or
++		 * (b) we have inserted at least one entry and the
++		 * next hash value is not a continuation
++		 */
++		if ((ret == 0) ||
++		    (count && ((hashval & 1) == 0)))
++			break;
++	}
++	dx_release(frames);
++	dxtrace(printk("Fill tree: returned %d entries\n", count));
++	return count;
++errout:
++	dx_release(frames);
++	return (err);
++}
++
++
++/*
++ * Directory block splitting, compacting
++ */
++
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
++{
++	int count = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	while ((char *) de < base + size)
++	{
++		if (de->name_len && de->inode) {
++			ext3fs_dirhash(de->name, de->name_len, &h);
++			map_tail--;
++			map_tail->hash = h.hash;
++			map_tail->offs = (u32) ((char *) de - base);
++			count++;
++		}
++		/* XXX: do we need to check rec_len == 0 case? -Chris */
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	return count;
++}
++
++static void dx_sort_map (struct dx_map_entry *map, unsigned count)
++{
++	struct dx_map_entry *p, *q, *top = map + count - 1;
++	int more;
++	/* Combsort until bubble sort doesn't suck */
++	while (count > 2)
++	{
++		count = count*10/13;
++		if (count - 9 < 2) /* 9, 10 -> 11 */
++			count = 11;
++		for (p = top, q = p - count; q >= map; p--, q--)
++			if (p->hash < q->hash)
++				swap(*p, *q);
++	}
++	/* Garden variety bubble sort */
++	do {
++		more = 0;
++		q = top;
++		while (q-- > map)
++		{
++			if (q[1].hash >= q[0].hash)
++				continue;
++			swap(*(q+1), *q);
++			more = 1;
++		}
++	} while(more);
++}
++
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++{
++	struct dx_entry *entries = frame->entries;
++	struct dx_entry *old = frame->at, *new = old + 1;
++	int count = dx_get_count(entries);
++
++	assert(count < dx_get_limit(entries));
++	assert(old < entries + count);
++	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++	dx_set_hash(new, hash);
++	dx_set_block(new, block);
++	dx_set_count(entries, count + 1);
++}
++#endif
++
++
++static void ext3_update_dx_flag(struct inode *inode)
++{
++	if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
++				     EXT3_FEATURE_COMPAT_DIR_INDEX))
++		EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
++}
++
+ /*
+  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+  *
+@@ -94,6 +724,7 @@ static int inline search_dirblock(struct
+ 	return 0;
+ }
+ 
++
+ /*
+  *	ext3_find_entry()
+  *
+@@ -105,6 +736,8 @@ static int inline search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
++
++	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+ 					struct ext3_dir_entry_2 ** res_dir)
+ {
+@@ -119,12 +752,32 @@ static struct buffer_head * ext3_find_en
+ 	int num = 0;
+ 	int nblocks, i, err;
+ 	struct inode *dir = dentry->d_parent->d_inode;
++	int namelen;
++	const u8 *name;
++	unsigned blocksize;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+-
++	blocksize = sb->s_blocksize;
++	namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++	if (namelen > EXT3_NAME_LEN)
++		return NULL;
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		/*
++		 * On success, or if the error was file not found,
++		 * return.  Otherwise, fall back to doing a search the
++		 * old fashioned way.
++		 */
++		if (bh || (err != ERR_BAD_DX_DIR))
++			return bh;
++		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++	}
++#endif
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+-	start = dir->u.ext3_i.i_dir_start_lookup;
++	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+ 		start = 0;
+ 	block = start;
+@@ -165,7 +818,7 @@ restart:
+ 		i = search_dirblock(bh, dir, dentry,
+ 			    block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
+ 		if (i == 1) {
+-			dir->u.ext3_i.i_dir_start_lookup = block;
++			EXT3_I(dir)->i_dir_start_lookup = block;
+ 			ret = bh;
+ 			goto cleanup_and_exit;
+ 		} else {
+@@ -196,6 +849,66 @@ cleanup_and_exit:
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err)
++{
++	struct super_block * sb;
++	struct dx_hash_info	hinfo;
++	u32 hash;
++	struct dx_frame frames[2], *frame;
++	struct ext3_dir_entry_2 *de, *top;
++	struct buffer_head *bh;
++	unsigned long block;
++	int retval;
++	int namelen = dentry->d_name.len;
++	const u8 *name = dentry->d_name.name;
++	struct inode *dir = dentry->d_parent->d_inode;
++	
++	sb = dir->i_sb;
++	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++		return NULL;
++	hash = hinfo.hash;
++	do {
++		block = dx_get_block(frame->at);
++		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
++			goto errout;
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de))
++		if (ext3_match (namelen, name, de)) {
++			if (!ext3_check_dir_entry("ext3_find_entry",
++						  dir, de, bh,
++				  (block<<EXT3_BLOCK_SIZE_BITS(sb))
++					  +((char *)de - bh->b_data))) {
++				brelse (bh);
++				goto errout;
++			}
++			*res_dir = de;
++			dx_release (frames);
++			return bh;
++		}
++		brelse (bh);
++		/* Check to see if we should continue to search */
++		retval = ext3_htree_next_block(dir, hash, frame,
++					       frames, err, 0);
++		if (retval == -1) {
++			ext3_warning(sb, __FUNCTION__,
++			     "error reading index page in directory #%lu",
++			     dir->i_ino);
++			goto errout;
++		}
++	} while (retval == 1);
++	
++	*err = -ENOENT;
++errout:
++	dxtrace(printk("%s not found\n", name));
++	dx_release (frames);
++	return NULL;
++}
++#endif
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+@@ -212,8 +925,9 @@ static struct dentry *ext3_lookup(struct
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+-		if (!inode)
++		if (!inode) {
+ 			return ERR_PTR(-EACCES);
++		}
+ 	}
+ 	d_add(dentry, inode);
+ 	return NULL;
+@@ -237,6 +951,301 @@ static inline void ext3_set_de_type(stru
+ 		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct ext3_dir_entry_2 *
++dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
++{
++	unsigned rec_len = 0;
++
++	while (count--) {
++		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		rec_len = EXT3_DIR_REC_LEN(de->name_len);
++		memcpy (to, de, rec_len);
++		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
++		de->inode = 0;
++		map++;
++		to += rec_len;
++	}
++	return (struct ext3_dir_entry_2 *) (to - rec_len);
++}
++
++static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
++{
++	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	unsigned rec_len = 0;
++
++	prev = to = de;
++	while ((char*)de < base + size) {
++		next = (struct ext3_dir_entry_2 *) ((char *) de +
++						    le16_to_cpu(de->rec_len));
++		if (de->inode && de->name_len) {
++			rec_len = EXT3_DIR_REC_LEN(de->name_len);
++			if (de > to)
++				memmove(to, de, rec_len);
++			to->rec_len = rec_len;
++			prev = to;
++			to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
++		}
++		de = next;
++	}
++	return prev;
++}
++
++static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
++			struct buffer_head **bh,struct dx_frame *frame,
++			struct dx_hash_info *hinfo, int *error)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count, continued;
++	struct buffer_head *bh2;
++	u32 newblock;
++	u32 hash2;
++	struct dx_map_entry *map;
++	char *data1 = (*bh)->b_data, *data2;
++	unsigned split;
++	struct ext3_dir_entry_2 *de = NULL, *de2;
++	int	err;
++
++	bh2 = ext3_append (handle, dir, &newblock, error);
++	if (!(bh2)) {
++		brelse(*bh);
++		*bh = NULL;
++		goto errout;
++	}
++
++	BUFFER_TRACE(*bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, *bh);
++	if (err) {
++	journal_error:
++		brelse(*bh);
++		brelse(bh2);
++		*bh = NULL;
++		ext3_std_error(dir->i_sb, err);
++		goto errout;
++	}
++	BUFFER_TRACE(frame->bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, frame->bh);
++	if (err)
++		goto journal_error;
++
++	data2 = bh2->b_data;
++
++	/* create map in the end of data2 block */
++	map = (struct dx_map_entry *) (data2 + blocksize);
++	count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
++			     blocksize, hinfo, map);
++	map -= count;
++	split = count/2; // need to adjust to actual middle
++	dx_sort_map (map, count);
++	hash2 = map[split].hash;
++	continued = hash2 == map[split - 1].hash;
++	dxtrace(printk("Split block %i at %x, %i/%i\n",
++		dx_get_block(frame->at), hash2, split, count-split));
++
++	/* Fancy dance to stay within two buffers */
++	de2 = dx_move_dirents(data1, data2, map + split, count - split);
++	de = dx_pack_dirents(data1,blocksize);
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++
++	/* Which block gets the new entry? */
++	if (hinfo->hash >= hash2)
++	{
++		swap(*bh, bh2);
++		de = de2;
++	}
++	dx_insert_block (frame, hash2 + continued, newblock);
++	err = ext3_journal_dirty_metadata (handle, bh2);
++	if (err)
++		goto journal_error;
++	err = ext3_journal_dirty_metadata (handle, frame->bh);
++	if (err)
++		goto journal_error;
++	brelse (bh2);
++	dxtrace(dx_show_index ("frame", frame->entries));
++errout:
++	return de;
++}
++#endif
++
++
++/*
++ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
++ * it points to a directory entry which is guaranteed to be large
++ * enough for new directory entry.  If de is NULL, then
++ * add_dirent_to_buf will attempt search the directory block for
++ * space.  It will return -ENOSPC if no space is available, and -EIO
++ * and -EEXIST if directory entry already exists.
++ * 
++ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
++ * all other cases bh is released.
++ */
++static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode, struct ext3_dir_entry_2 *de,
++			     struct buffer_head * bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	unsigned long	offset = 0;
++	unsigned short	reclen;
++	int		nlen, rlen, err;
++	char		*top;
++	
++	reclen = EXT3_DIR_REC_LEN(namelen);
++	if (!de) {
++		de = (struct ext3_dir_entry_2 *)bh->b_data;
++		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
++		while ((char *) de <= top) {
++			if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
++						  bh, offset)) {
++				brelse (bh);
++				return -EIO;
++			}
++			if (ext3_match (namelen, name, de)) {
++				brelse (bh);
++				return -EEXIST;
++			}
++			nlen = EXT3_DIR_REC_LEN(de->name_len);
++			rlen = le16_to_cpu(de->rec_len);
++			if ((de->inode? rlen - nlen: rlen) >= reclen)
++				break;
++			de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
++			offset += rlen;
++		}
++		if ((char *) de > top)
++			return -ENOSPC;
++	}
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err) {
++		ext3_std_error(dir->i_sb, err);
++		brelse(bh);
++		return err;
++	}
++	
++	/* By now the buffer is marked for journaling */
++	nlen = EXT3_DIR_REC_LEN(de->name_len);
++	rlen = le16_to_cpu(de->rec_len);
++	if (de->inode) {
++		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		de1->rec_len = cpu_to_le16(rlen - nlen);
++		de->rec_len = cpu_to_le16(nlen);
++		de = de1;
++	}
++	de->file_type = EXT3_FT_UNKNOWN;
++	if (inode) {
++		de->inode = cpu_to_le32(inode->i_ino);
++		ext3_set_de_type(dir->i_sb, de, inode->i_mode);
++	} else
++		de->inode = 0;
++	de->name_len = namelen;
++	memcpy (de->name, name, namelen);
++	/*
++	 * XXX shouldn't update any times until successful
++	 * completion of syscall, but too many callers depend
++	 * on this.
++	 *
++	 * XXX similarly, too many callers depend on
++	 * ext3_new_inode() setting the times, but error
++	 * recovery deletes the inode, so the worst that can
++	 * happen is that the times are slightly out of date
++	 * and/or different from the directory change time.
++	 */
++	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
++	ext3_update_dx_flag(dir);
++	dir->i_version = ++event;
++	ext3_mark_inode_dirty(handle, dir);
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		ext3_std_error(dir->i_sb, err);
++	brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * This converts a one block unindexed directory to a 3 block indexed
++ * directory, and adds the dentry to the indexed directory.
++ */
++static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
++			    struct inode *inode, struct buffer_head *bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	struct buffer_head *bh2;
++	struct dx_root	*root;
++	struct dx_frame	frames[2], *frame;
++	struct dx_entry *entries;
++	struct ext3_dir_entry_2	*de, *de2;
++	char		*data1, *top;
++	unsigned	len;
++	int		retval;
++	unsigned	blocksize;
++	struct dx_hash_info hinfo;
++	u32		block;
++		
++	blocksize =  dir->i_sb->s_blocksize;
++	dxtrace(printk("Creating index\n"));
++	retval = ext3_journal_get_write_access(handle, bh);
++	if (retval) {
++		ext3_std_error(dir->i_sb, retval);
++		brelse(bh);
++		return retval;
++	}
++	root = (struct dx_root *) bh->b_data;
++		
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	bh2 = ext3_append (handle, dir, &block, &retval);
++	if (!(bh2)) {
++		brelse(bh);
++		return retval;
++	}
++	data1 = bh2->b_data;
++
++	/* The 0th block becomes the root, move the dirents out */
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
++	len = ((char *) root) + blocksize - (char *) de;
++	memcpy (data1, de, len);
++	de = (struct ext3_dir_entry_2 *) data1;
++	top = data1 + len;
++	while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
++		de = de2;
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	/* Initialize the root; the dot dirents already exist */
++	de = (struct ext3_dir_entry_2 *) (&root->dotdot);
++	de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++	memset (&root->info, 0, sizeof(root->info));
++	root->info.info_length = sizeof(root->info);
++	root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
++	entries = root->entries;
++	dx_set_block (entries, 1);
++	dx_set_count (entries, 1);
++	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
++
++	/* Initialize as for dx_probe */
++	hinfo.hash_version = root->info.hash_version;
++	hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	ext3fs_dirhash(name, namelen, &hinfo);
++	frame = frames;
++	frame->entries = entries;
++	frame->at = entries;
++	frame->bh = bh;
++	bh = bh2;
++	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	dx_release (frames);
++	if (!(de))
++		return retval;
++
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
++#endif
++
+ /*
+  *	ext3_add_entry()
+  *
+@@ -247,127 +1255,198 @@ static inline void ext3_set_de_type(stru
+  * may not sleep between calling this and putting something into
+  * the entry, as someone else might have used it while you slept.
+  */
+-
+-/*
+- * AKPM: the journalling code here looks wrong on the error paths
+- */
+ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+ 	struct inode *inode)
+ {
+ 	struct inode *dir = dentry->d_parent->d_inode;
+-	const char *name = dentry->d_name.name;
+-	int namelen = dentry->d_name.len;
+ 	unsigned long offset;
+-	unsigned short rec_len;
+ 	struct buffer_head * bh;
+-	struct ext3_dir_entry_2 * de, * de1;
++	struct ext3_dir_entry_2 *de;
+ 	struct super_block * sb;
+ 	int	retval;
++#ifdef CONFIG_EXT3_INDEX
++	int	dx_fallback=0;
++#endif
++	unsigned blocksize;
++	unsigned nlen, rlen;
++	u32 block, blocks;
+ 
+ 	sb = dir->i_sb;
+-
+-	if (!namelen)
++	blocksize = sb->s_blocksize;
++	if (!dentry->d_name.len)
+ 		return -EINVAL;
+-	bh = ext3_bread (handle, dir, 0, 0, &retval);
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		retval = ext3_dx_add_entry(handle, dentry, inode);
++		if (!retval || (retval != ERR_BAD_DX_DIR))
++			return retval;
++		EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
++		dx_fallback++;
++		ext3_mark_inode_dirty(handle, dir);
++	}
++#endif
++	blocks = dir->i_size >> sb->s_blocksize_bits;
++	for (block = 0, offset = 0; block < blocks; block++) {
++		bh = ext3_bread(handle, dir, block, 0, &retval);
++		if(!bh)
++			return retval;
++		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++		if (retval != -ENOSPC)
++			return retval;
++
++#ifdef CONFIG_EXT3_INDEX
++		if (blocks == 1 && !dx_fallback &&
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
++			return make_indexed_dir(handle, dentry, inode, bh);
++#endif
++		brelse(bh);
++	}
++	bh = ext3_append(handle, dir, &block, &retval);
+ 	if (!bh)
+ 		return retval;
+-	rec_len = EXT3_DIR_REC_LEN(namelen);
+-	offset = 0;
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+-	while (1) {
+-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+-			brelse (bh);
+-			bh = NULL;
+-			bh = ext3_bread (handle, dir,
+-				offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
+-			if (!bh)
+-				return retval;
+-			if (dir->i_size <= offset) {
+-				if (dir->i_size == 0) {
+-					brelse(bh);
+-					return -ENOENT;
+-				}
++	de->inode = 0;
++	de->rec_len = cpu_to_le16(rlen = blocksize);
++	nlen = 0;
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
+ 
+-				ext3_debug ("creating next block\n");
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * Returns 0 for success, or a negative error value
++ */
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode)
++{
++	struct dx_frame frames[2], *frame;
++	struct dx_entry *entries, *at;
++	struct dx_hash_info hinfo;
++	struct buffer_head * bh;
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block * sb = dir->i_sb;
++	struct ext3_dir_entry_2 *de;
++	int err;
+ 
+-				BUFFER_TRACE(bh, "get_write_access");
+-				ext3_journal_get_write_access(handle, bh);
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-				de->inode = 0;
+-				de->rec_len = le16_to_cpu(sb->s_blocksize);
+-				dir->u.ext3_i.i_disksize =
+-					dir->i_size = offset + sb->s_blocksize;
+-				dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-				ext3_mark_inode_dirty(handle, dir);
+-			} else {
++	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++	entries = frame->entries;
++	at = frame->at;
+ 
+-				ext3_debug ("skipping to next block\n");
++	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++		goto cleanup;
+ 
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-			}
+-		}
+-		if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
+-					   offset)) {
+-			brelse (bh);
+-			return -ENOENT;
+-		}
+-		if (ext3_match (namelen, name, de)) {
+-				brelse (bh);
+-				return -EEXIST;
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err)
++		goto journal_error;
++
++	err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++	if (err != -ENOSPC) {
++		bh = 0;
++		goto cleanup;
++	}
++
++	/* Block full, should compress but for now just split */
++	dxtrace(printk("using %u of %u node entries\n",
++		       dx_get_count(entries), dx_get_limit(entries)));
++	/* Need to split index? */
++	if (dx_get_count(entries) == dx_get_limit(entries)) {
++		u32 newblock;
++		unsigned icount = dx_get_count(entries);
++		int levels = frame - frames;
++		struct dx_entry *entries2;
++		struct dx_node *node2;
++		struct buffer_head *bh2;
++
++		if (levels && (dx_get_count(frames->entries) ==
++			       dx_get_limit(frames->entries))) {
++			ext3_warning(sb, __FUNCTION__,
++				     "Directory index full!\n");
++			err = -ENOSPC;
++			goto cleanup;
+ 		}
+-		if ((le32_to_cpu(de->inode) == 0 &&
+-				le16_to_cpu(de->rec_len) >= rec_len) ||
+-		    (le16_to_cpu(de->rec_len) >=
+-				EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
+-			BUFFER_TRACE(bh, "get_write_access");
+-			ext3_journal_get_write_access(handle, bh);
+-			/* By now the buffer is marked for journaling */
+-			offset += le16_to_cpu(de->rec_len);
+-			if (le32_to_cpu(de->inode)) {
+-				de1 = (struct ext3_dir_entry_2 *) ((char *) de +
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de1->rec_len =
+-					cpu_to_le16(le16_to_cpu(de->rec_len) -
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de->rec_len = cpu_to_le16(
+-						EXT3_DIR_REC_LEN(de->name_len));
+-				de = de1;
++		bh2 = ext3_append (handle, dir, &newblock, &err);
++		if (!(bh2))
++			goto cleanup;
++		node2 = (struct dx_node *)(bh2->b_data);
++		entries2 = node2->entries;
++		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
++		node2->fake.inode = 0;
++		BUFFER_TRACE(frame->bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, frame->bh);
++		if (err)
++			goto journal_error;
++		if (levels) {
++			unsigned icount1 = icount/2, icount2 = icount - icount1;
++			unsigned hash2 = dx_get_hash(entries + icount1);
++			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
++				
++			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++			err = ext3_journal_get_write_access(handle,
++							     frames[0].bh);
++			if (err)
++				goto journal_error;
++				
++			memcpy ((char *) entries2, (char *) (entries + icount1),
++				icount2 * sizeof(struct dx_entry));
++			dx_set_count (entries, icount1);
++			dx_set_count (entries2, icount2);
++			dx_set_limit (entries2, dx_node_limit(dir));
++
++			/* Which index block gets the new entry? */
++			if (at - entries >= icount1) {
++				frame->at = at = at - entries - icount1 + entries2;
++				frame->entries = entries = entries2;
++				swap(frame->bh, bh2);
+ 			}
+-			de->file_type = EXT3_FT_UNKNOWN;
+-			if (inode) {
+-				de->inode = cpu_to_le32(inode->i_ino);
+-				ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-			} else
+-				de->inode = 0;
+-			de->name_len = namelen;
+-			memcpy (de->name, name, namelen);
+-			/*
+-			 * XXX shouldn't update any times until successful
+-			 * completion of syscall, but too many callers depend
+-			 * on this.
+-			 *
+-			 * XXX similarly, too many callers depend on
+-			 * ext3_new_inode() setting the times, but error
+-			 * recovery deletes the inode, so the worst that can
+-			 * happen is that the times are slightly out of date
+-			 * and/or different from the directory change time.
+-			 */
+-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+-			dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-			dir->i_version = ++event;
+-			ext3_mark_inode_dirty(handle, dir);
+-			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-			ext3_journal_dirty_metadata(handle, bh);
+-			brelse(bh);
+-			return 0;
++			dx_insert_block (frames + 0, hash2, newblock);
++			dxtrace(dx_show_index ("node", frames[1].entries));
++			dxtrace(dx_show_index ("node",
++			       ((struct dx_node *) bh2->b_data)->entries));
++			err = ext3_journal_dirty_metadata(handle, bh2);
++			if (err)
++				goto journal_error;
++			brelse (bh2);
++		} else {
++			dxtrace(printk("Creating second level index...\n"));
++			memcpy((char *) entries2, (char *) entries,
++			       icount * sizeof(struct dx_entry));
++			dx_set_limit(entries2, dx_node_limit(dir));
++
++			/* Set up root */
++			dx_set_count(entries, 1);
++			dx_set_block(entries + 0, newblock);
++			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++
++			/* Add new access path frame */
++			frame = frames + 1;
++			frame->at = at = at - entries + entries2;
++			frame->entries = entries = entries2;
++			frame->bh = bh2;
++			err = ext3_journal_get_write_access(handle,
++							     frame->bh);
++			if (err)
++				goto journal_error;
+ 		}
+-		offset += le16_to_cpu(de->rec_len);
+-		de = (struct ext3_dir_entry_2 *)
+-			((char *) de + le16_to_cpu(de->rec_len));
++		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	brelse (bh);
+-	return -ENOSPC;
++	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	if (!de)
++		goto cleanup;
++	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	bh = 0;
++	goto cleanup;
++	
++journal_error:
++	ext3_std_error(dir->i_sb, err);
++cleanup:
++	if (bh)
++		brelse(bh);
++	dx_release(frames);
++	return err;
+ }
++#endif
+ 
+ /*
+  * ext3_delete_entry deletes a directory entry by merging it with the
+@@ -451,9 +1530,11 @@ static int ext3_create (struct inode * d
+ 	struct inode * inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -478,9 +1559,11 @@ static int ext3_mknod (struct inode * di
+ 	struct inode *inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -507,9 +1590,11 @@ static int ext3_mkdir(struct inode * dir
+ 	if (dir->i_nlink >= EXT3_LINK_MAX)
+ 		return -EMLINK;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -521,7 +1606,7 @@ static int ext3_mkdir(struct inode * dir
+ 
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+-	inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
++	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+ 	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+@@ -554,21 +1639,19 @@ static int ext3_mkdir(struct inode * dir
+ 		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+-	if (err)
+-		goto out_no_entry;
++	if (err) {
++		inode->i_nlink = 0;
++		ext3_mark_inode_dirty(handle, inode);
++		iput (inode);
++		goto out_stop;
++	}
+ 	dir->i_nlink++;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	d_instantiate(dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	inode->i_nlink = 0;
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ /*
+@@ -655,7 +1738,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	int err = 0, rc;
+ 	
+ 	lock_super(sb);
+-	if (!list_empty(&inode->u.ext3_i.i_orphan))
++	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+ 	/* Orphan handling is only valid for files with data blocks
+@@ -696,7 +1779,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	 * This is safe: on error we're going to ignore the orphan list
+ 	 * anyway on the next recovery. */
+ 	if (!err)
+-		list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
++		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
+ 
+ 	jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+@@ -714,25 +1797,26 @@ out_unlock:
+ int ext3_orphan_del(handle_t *handle, struct inode *inode)
+ {
+ 	struct list_head *prev;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct ext3_sb_info *sbi;
+ 	ino_t ino_next; 
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 	
+ 	lock_super(inode->i_sb);
+-	if (list_empty(&inode->u.ext3_i.i_orphan)) {
++	if (list_empty(&ei->i_orphan)) {
+ 		unlock_super(inode->i_sb);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+-	prev = inode->u.ext3_i.i_orphan.prev;
++	prev = ei->i_orphan.prev;
+ 	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
+ 
+-	list_del(&inode->u.ext3_i.i_orphan);
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++	list_del(&ei->i_orphan);
++	INIT_LIST_HEAD(&ei->i_orphan);
+ 
+ 	/* If we're on an error path, we may not have a valid
+ 	 * transaction handle with which to update the orphan list on
+@@ -793,8 +1877,9 @@ static int ext3_rmdir (struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	retval = -ENOENT;
+ 	bh = ext3_find_entry (dentry, &de);
+@@ -832,7 +1917,7 @@ static int ext3_rmdir (struct inode * di
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+ end_rmdir:
+@@ -850,8 +1935,9 @@ static int ext3_unlink(struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -878,7 +1964,7 @@ static int ext3_unlink(struct inode * di
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	inode->i_nlink--;
+ 	if (!inode->i_nlink)
+@@ -904,9 +1990,11 @@ static int ext3_symlink (struct inode * 
+ 	if (l > dir->i_sb->s_blocksize)
+ 		return -ENAMETOOLONG;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -916,7 +2004,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+ 
+-	if (l > sizeof (inode->u.ext3_i.i_data)) {
++	if (l > sizeof (EXT3_I(inode)->i_data)) {
+ 		inode->i_op = &page_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+@@ -925,25 +2013,23 @@ static int ext3_symlink (struct inode * 
+ 		 * i_size in generic_commit_write().
+ 		 */
+ 		err = block_symlink(inode, symname, l);
+-		if (err)
+-			goto out_no_entry;
++		if (err) {
++			ext3_dec_count(handle, inode);
++			ext3_mark_inode_dirty(handle, inode);
++			iput (inode);
++			goto out_stop;
++		}
+ 	} else {
+ 		inode->i_op = &ext3_fast_symlink_inode_operations;
+-		memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
++		memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
+ 		inode->i_size = l-1;
+ 	}
+-	inode->u.ext3_i.i_disksize = inode->i_size;
++	EXT3_I(inode)->i_disksize = inode->i_size;
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ 	ext3_mark_inode_dirty(handle, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	ext3_dec_count(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ static int ext3_link (struct dentry * old_dentry,
+@@ -956,12 +2042,15 @@ static int ext3_link (struct dentry * ol
+ 	if (S_ISDIR(inode->i_mode))
+ 		return -EPERM;
+ 
+-	if (inode->i_nlink >= EXT3_LINK_MAX)
++	if (inode->i_nlink >= EXT3_LINK_MAX) {
+ 		return -EMLINK;
++	}
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -995,9 +2084,11 @@ static int ext3_rename (struct inode * o
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+@@ -1077,7 +2168,7 @@ static int ext3_rename (struct inode * o
+ 		new_inode->i_ctime = CURRENT_TIME;
+ 	}
+ 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+-	old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(old_dir);
+ 	if (dir_bh) {
+ 		BUFFER_TRACE(dir_bh, "get_write_access");
+ 		ext3_journal_get_write_access(handle, dir_bh);
+@@ -1089,7 +2180,7 @@ static int ext3_rename (struct inode * o
+ 			new_inode->i_nlink--;
+ 		} else {
+ 			new_dir->i_nlink++;
+-			new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++			ext3_update_dx_flag(new_dir);
+ 			ext3_mark_inode_dirty(handle, new_dir);
+ 		}
+ 	}
+--- linux-2.4.20/fs/ext3/super.c~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/fs/ext3/super.c	Sat Apr  5 03:56:31 2003
+@@ -707,6 +707,7 @@ static int ext3_setup_super(struct super
+ 	es->s_mtime = cpu_to_le32(CURRENT_TIME);
+ 	ext3_update_dynamic_rev(sb);
+ 	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
++
+ 	ext3_commit_super (sb, es, 1);
+ 	if (test_opt (sb, DEBUG))
+ 		printk (KERN_INFO
+@@ -717,6 +718,7 @@ static int ext3_setup_super(struct super
+ 			EXT3_BLOCKS_PER_GROUP(sb),
+ 			EXT3_INODES_PER_GROUP(sb),
+ 			sbi->s_mount_opt);
++
+ 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
+ 				bdevname(sb->s_dev));
+ 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+@@ -890,6 +892,7 @@ static loff_t ext3_max_size(int bits)
+ 	return res;
+ }
+ 
++
+ struct super_block * ext3_read_super (struct super_block * sb, void * data,
+ 				      int silent)
+ {
+@@ -1066,6 +1069,9 @@ struct super_block * ext3_read_super (st
+ 	sbi->s_mount_state = le16_to_cpu(es->s_state);
+ 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+ 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++	for (i=0; i < 4; i++)
++		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
++	sbi->s_def_hash_version = es->s_def_hash_version;
+ 
+ 	if (sbi->s_blocks_per_group > blocksize * 8) {
+ 		printk (KERN_ERR
+@@ -1769,6 +1775,7 @@ static void __exit exit_ext3_fs(void)
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
++EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+--- linux-2.4.20/include/linux/ext3_fs.h~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/include/linux/ext3_fs.h	Sat Apr  5 03:56:31 2003
+@@ -40,6 +40,11 @@
+ #define EXT3FS_VERSION		"2.4-0.9.19"
+ 
+ /*
++ * Always enable hashed directories
++ */
++#define CONFIG_EXT3_INDEX
++
++/*
+  * Debug code
+  */
+ #ifdef EXT3FS_DEBUG
+@@ -437,8 +442,11 @@ struct ext3_super_block {
+ /*E0*/	__u32	s_journal_inum;		/* inode number of journal file */
+ 	__u32	s_journal_dev;		/* device number of journal file */
+ 	__u32	s_last_orphan;		/* start of list of inodes to delete */
+-
+-/*EC*/	__u32	s_reserved[197];	/* Padding to the end of the block */
++	__u32	s_hash_seed[4];		/* HTREE hash seed */
++	__u8	s_def_hash_version;	/* Default hash version to use */
++	__u8	s_reserved_char_pad;
++	__u16	s_reserved_word_pad;
++	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+ #ifdef __KERNEL__
+@@ -575,9 +583,46 @@ struct ext3_dir_entry_2 {
+ #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
+ 					 ~EXT3_DIR_ROUND)
++/*
++ * Hash Tree Directory indexing
++ * (c) Daniel Phillips, 2001
++ */
++
++#ifdef CONFIG_EXT3_INDEX
++  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++					      EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++		      (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
++#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#else
++  #define is_dx(dir) 0
++#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
++#endif
++
++/* Legal values for the dx_root hash_version field: */
++
++#define DX_HASH_LEGACY		0
++#define DX_HASH_HALF_MD4	1
++#define DX_HASH_TEA		2
++
++/* hash info structure used by the directory hash */
++struct dx_hash_info
++{
++	u32		hash;
++	u32		minor_hash;
++	int		hash_version;
++	u32		*seed;
++};
+ 
+ #ifdef __KERNEL__
+ /*
++ * Control parameters used by ext3_htree_next_block
++ */
++#define HASH_NB_ALWAYS		1
++
++
++/*
+  * Describe an inode's exact location on disk and in memory
+  */
+ struct ext3_iloc
+@@ -587,6 +632,27 @@ struct ext3_iloc
+ 	unsigned long block_group;
+ };
+ 
++
++/*
++ * This structure is stuffed into the struct file's private_data field
++ * for directories.  It is where we put information so that we can do
++ * readdir operations in hash tree order.
++ */
++struct dir_private_info {
++	rb_root_t	root;
++	rb_node_t	*curr_node;
++	struct fname	*extra_fname;
++	loff_t		last_pos;
++	__u32		curr_hash;
++	__u32		curr_minor_hash;
++	__u32		next_hash;
++};
++
++/*
++ * Special error return code only used by dx_probe() and its callers.
++ */
++#define ERR_BAD_DX_DIR	-75000
++
+ /*
+  * Function prototypes
+  */
+@@ -614,11 +680,20 @@ extern struct ext3_group_desc * ext3_get
+ 
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
+-				struct ext3_dir_entry_2 *, struct buffer_head *,
+-				unsigned long);
++				struct ext3_dir_entry_2 *,
++				struct buffer_head *, unsigned long);
++extern void ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++				    __u32 minor_hash,
++				    struct ext3_dir_entry_2 *dirent);
++extern void ext3_htree_free_dir_info(struct dir_private_info *p);
++
+ /* fsync.c */
+ extern int ext3_sync_file (struct file *, struct dentry *, int);
+ 
++/* hash.c */
++extern int ext3fs_dirhash(const char *name, int len, struct
++			  dx_hash_info *hinfo);
++
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+@@ -650,6 +725,8 @@ extern int ext3_ioctl (struct inode *, s
+ /* namei.c */
+ extern int ext3_orphan_add(handle_t *, struct inode *);
+ extern int ext3_orphan_del(handle_t *, struct inode *);
++extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++				__u32 start_minor_hash, __u32 *next_hash);
+ 
+ /* super.c */
+ extern void ext3_error (struct super_block *, const char *, const char *, ...)
+--- linux-2.4.20/include/linux/ext3_fs_sb.h~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/include/linux/ext3_fs_sb.h	Sat Apr  5 03:56:31 2003
+@@ -62,6 +62,8 @@ struct ext3_sb_info {
+ 	int s_inode_size;
+ 	int s_first_ino;
+ 	u32 s_next_generation;
++	u32 s_hash_seed[4];
++	int s_def_hash_version;
+ 
+ 	/* Journaling */
+ 	struct inode * s_journal_inode;
+--- linux-2.4.20/include/linux/ext3_jbd.h~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/include/linux/ext3_jbd.h	Sat Apr  5 03:56:31 2003
+@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s
+ 
+ #define EXT3_RESERVE_TRANS_BLOCKS	12
+ 
++#define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
++
+ int
+ ext3_mark_iloc_dirty(handle_t *handle, 
+ 		     struct inode *inode,
+--- linux-2.4.20/include/linux/rbtree.h~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/include/linux/rbtree.h	Sat Apr  5 03:56:31 2003
+@@ -120,6 +120,8 @@ rb_root_t;
+ 
+ extern void rb_insert_color(rb_node_t *, rb_root_t *);
+ extern void rb_erase(rb_node_t *, rb_root_t *);
++extern rb_node_t *rb_get_first(rb_root_t *root);
++extern rb_node_t *rb_get_next(rb_node_t *n);
+ 
+ static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+ {
+--- linux-2.4.20/lib/rbtree.c~ext-2.4-patch-1	Sat Apr  5 03:56:31 2003
++++ linux-2.4.20-braam/lib/rbtree.c	Sat Apr  5 03:56:31 2003
+@@ -17,6 +17,8 @@
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+   linux/lib/rbtree.c
++
++  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+ */
+ 
+ #include <linux/rbtree.h>
+@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_
+ 		__rb_erase_color(child, parent, root);
+ }
+ EXPORT_SYMBOL(rb_erase);
++
++/*
++ * This function returns the first node (in sort order) of the tree.
++ */
++rb_node_t *rb_get_first(rb_root_t *root)
++{
++	rb_node_t	*n;
++
++	n = root->rb_node;
++	if (!n)
++		return 0;
++	while (n->rb_left)
++		n = n->rb_left;
++	return n;
++}
++EXPORT_SYMBOL(rb_get_first);
++
++/*
++ * Given a node, this function will return the next node in the tree.
++ */
++rb_node_t *rb_get_next(rb_node_t *n)
++{
++	rb_node_t	*parent;
++
++	if (n->rb_right) {
++		n = n->rb_right;
++		while (n->rb_left)
++			n = n->rb_left;
++		return n;
++	} else {
++		while ((parent = n->rb_parent)) {
++			if (n == parent->rb_left)
++				return parent;
++			n = parent;
++		}
++		return 0;
++	}
++}
++EXPORT_SYMBOL(rb_get_next);
++
+
+_
diff --git a/lustre/kernel_patches/patches/ext-2.4-patch-1.patch b/lustre/kernel_patches/patches/ext-2.4-patch-1.patch
index 09caec148c8d7d70bddc8bf9fcb1329618312b95..748671feedb886b57c01de29f82cb5e7eb717fc5 100644
--- a/lustre/kernel_patches/patches/ext-2.4-patch-1.patch
+++ b/lustre/kernel_patches/patches/ext-2.4-patch-1.patch
@@ -1190,28 +1190,28 @@
 +
 +static void dx_sort_map (struct dx_map_entry *map, unsigned count)
 +{
-+        struct dx_map_entry *p, *q, *top = map + count - 1;
-+        int more;
-+        /* Combsort until bubble sort doesn't suck */
-+        while (count > 2)
++	struct dx_map_entry *p, *q, *top = map + count - 1;
++	int more;
++	/* Combsort until bubble sort doesn't suck */
++	while (count > 2)
 +	{
-+                count = count*10/13;
-+                if (count - 9 < 2) /* 9, 10 -> 11 */
-+                        count = 11;
-+                for (p = top, q = p - count; q >= map; p--, q--)
-+                        if (p->hash < q->hash)
-+                                swap(*p, *q);
-+        }
-+        /* Garden variety bubble sort */
-+        do {
-+                more = 0;
-+                q = top;
-+                while (q-- > map)
++		count = count*10/13;
++		if (count - 9 < 2) /* 9, 10 -> 11 */
++			count = 11;
++		for (p = top, q = p - count; q >= map; p--, q--)
++			if (p->hash < q->hash)
++				swap(*p, *q);
++	}
++	/* Garden variety bubble sort */
++	do {
++		more = 0;
++		q = top;
++		while (q-- > map)
 +		{
-+                        if (q[1].hash >= q[0].hash)
++			if (q[1].hash >= q[0].hash)
 +				continue;
-+                        swap(*(q+1), *q);
-+                        more = 1;
++			swap(*(q+1), *q);
++			more = 1;
 +		}
 +	} while(more);
 +}
@@ -1381,7 +1381,7 @@
  	}
  	d_add(dentry, inode);
  	return NULL;
-@@ -237,6 +951,300 @@ static inline void ext3_set_de_type(stru
+@@ -237,6 +951,301 @@ static inline void ext3_set_de_type(stru
  		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
  }
  
@@ -1642,7 +1642,8 @@
 +	data1 = bh2->b_data;
 +
 +	/* The 0th block becomes the root, move the dirents out */
-+	de = (struct ext3_dir_entry_2 *) &root->info;
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
 +	len = ((char *) root) + blocksize - (char *) de;
 +	memcpy (data1, de, len);
 +	de = (struct ext3_dir_entry_2 *) data1;
diff --git a/lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro-2.patch b/lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro-2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bbfe6a9c2e97fef1ed0574ba302117939abd2f88
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-2.4.18-ino_sb_macro-2.patch
@@ -0,0 +1,1478 @@
+ fs/ext3/balloc.c              |  134 +-
+ fs/ext3/dir.c                 |    2 
+ fs/ext3/ialloc.c              |  102 -
+ fs/ext3/inode.c               |  202 +--
+ fs/ext3/ioctl.c               |   13 
+ fs/ext3/namei.c               |    9 
+ fs/ext3/super.c               |   22 
+ fs/ext3/symlink.c             |    8 
+ include/linux/ext3_fs.h       |   64 
+ include/linux/ext3_jbd.h      |    2 
+ 19 files changed, 5574 insertions(+), 290 deletions(-)
+
+--- linux-2.4.18-chaos/fs/ext3/balloc.c~ext3-2.4.18-ino_sb_macro-2	2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/balloc.c	2003-09-16 23:34:40.000000000 +0400
+@@ -46,18 +46,18 @@ struct ext3_group_desc * ext3_get_group_
+ 	unsigned long desc;
+ 	struct ext3_group_desc * gdp;
+ 
+-	if (block_group >= sb->u.ext3_sb.s_groups_count) {
++	if (block_group >= EXT3_SB(sb)->s_groups_count) {
+ 		ext3_error (sb, "ext3_get_group_desc",
+ 			    "block_group >= groups_count - "
+ 			    "block_group = %d, groups_count = %lu",
+-			    block_group, sb->u.ext3_sb.s_groups_count);
++			    block_group, EXT3_SB(sb)->s_groups_count);
+ 
+ 		return NULL;
+ 	}
+ 	
+ 	group_desc = block_group / EXT3_DESC_PER_BLOCK(sb);
+ 	desc = block_group % EXT3_DESC_PER_BLOCK(sb);
+-	if (!sb->u.ext3_sb.s_group_desc[group_desc]) {
++	if (!EXT3_SB(sb)->s_group_desc[group_desc]) {
+ 		ext3_error (sb, "ext3_get_group_desc",
+ 			    "Group descriptor not loaded - "
+ 			    "block_group = %d, group_desc = %lu, desc = %lu",
+@@ -66,9 +66,9 @@ struct ext3_group_desc * ext3_get_group_
+ 	}
+ 	
+ 	gdp = (struct ext3_group_desc *) 
+-	      sb->u.ext3_sb.s_group_desc[group_desc]->b_data;
++	      EXT3_SB(sb)->s_group_desc[group_desc]->b_data;
+ 	if (bh)
+-		*bh = sb->u.ext3_sb.s_group_desc[group_desc];
++		*bh = EXT3_SB(sb)->s_group_desc[group_desc];
+ 	return gdp + desc;
+ }
+ 
+@@ -104,8 +104,8 @@ static int read_block_bitmap (struct sup
+ 	 * this group.  The IO will be retried next time.
+ 	 */
+ error_out:
+-	sb->u.ext3_sb.s_block_bitmap_number[bitmap_nr] = block_group;
+-	sb->u.ext3_sb.s_block_bitmap[bitmap_nr] = bh;
++	EXT3_SB(sb)->s_block_bitmap_number[bitmap_nr] = block_group;
++	EXT3_SB(sb)->s_block_bitmap[bitmap_nr] = bh;
+ 	return retval;
+ }
+ 
+@@ -128,16 +128,17 @@ static int __load_block_bitmap (struct s
+ 	int i, j, retval = 0;
+ 	unsigned long block_bitmap_number;
+ 	struct buffer_head * block_bitmap;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 
+-	if (block_group >= sb->u.ext3_sb.s_groups_count)
++	if (block_group >= sbi->s_groups_count)
+ 		ext3_panic (sb, "load_block_bitmap",
+ 			    "block_group >= groups_count - "
+ 			    "block_group = %d, groups_count = %lu",
+-			    block_group, sb->u.ext3_sb.s_groups_count);
++			    block_group, EXT3_SB(sb)->s_groups_count);
+ 
+-	if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED) {
+-		if (sb->u.ext3_sb.s_block_bitmap[block_group]) {
+-			if (sb->u.ext3_sb.s_block_bitmap_number[block_group] ==
++	if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED) {
++		if (sbi->s_block_bitmap[block_group]) {
++			if (sbi->s_block_bitmap_number[block_group] ==
+ 			    block_group)
+ 				return block_group;
+ 			ext3_error (sb, "__load_block_bitmap",
+@@ -149,21 +150,20 @@ static int __load_block_bitmap (struct s
+ 		return block_group;
+ 	}
+ 
+-	for (i = 0; i < sb->u.ext3_sb.s_loaded_block_bitmaps &&
+-		    sb->u.ext3_sb.s_block_bitmap_number[i] != block_group; i++)
++	for (i = 0; i < sbi->s_loaded_block_bitmaps &&
++		    sbi->s_block_bitmap_number[i] != block_group; i++)
+ 		;
+-	if (i < sb->u.ext3_sb.s_loaded_block_bitmaps &&
+-  	    sb->u.ext3_sb.s_block_bitmap_number[i] == block_group) {
+-		block_bitmap_number = sb->u.ext3_sb.s_block_bitmap_number[i];
+-		block_bitmap = sb->u.ext3_sb.s_block_bitmap[i];
++	if (i < sbi->s_loaded_block_bitmaps &&
++  	    sbi->s_block_bitmap_number[i] == block_group) {
++		block_bitmap_number = sbi->s_block_bitmap_number[i];
++		block_bitmap = sbi->s_block_bitmap[i];
+ 		for (j = i; j > 0; j--) {
+-			sb->u.ext3_sb.s_block_bitmap_number[j] =
+-				sb->u.ext3_sb.s_block_bitmap_number[j - 1];
+-			sb->u.ext3_sb.s_block_bitmap[j] =
+-				sb->u.ext3_sb.s_block_bitmap[j - 1];
++			sbi->s_block_bitmap_number[j] =
++				sbi->s_block_bitmap_number[j - 1];
++			sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1];
+ 		}
+-		sb->u.ext3_sb.s_block_bitmap_number[0] = block_bitmap_number;
+-		sb->u.ext3_sb.s_block_bitmap[0] = block_bitmap;
++		sbi->s_block_bitmap_number[0] = block_bitmap_number;
++		sbi->s_block_bitmap[0] = block_bitmap;
+ 
+ 		/*
+ 		 * There's still one special case here --- if block_bitmap == 0
+@@ -173,17 +173,14 @@ static int __load_block_bitmap (struct s
+ 		if (!block_bitmap)
+ 			retval = read_block_bitmap (sb, block_group, 0);
+ 	} else {
+-		if (sb->u.ext3_sb.s_loaded_block_bitmaps<EXT3_MAX_GROUP_LOADED)
+-			sb->u.ext3_sb.s_loaded_block_bitmaps++;
++		if (sbi->s_loaded_block_bitmaps<EXT3_MAX_GROUP_LOADED)
++			sbi->s_loaded_block_bitmaps++;
+ 		else
+-			brelse (sb->u.ext3_sb.s_block_bitmap
+-					[EXT3_MAX_GROUP_LOADED - 1]);
+-		for (j = sb->u.ext3_sb.s_loaded_block_bitmaps - 1;
+-					j > 0;  j--) {
+-			sb->u.ext3_sb.s_block_bitmap_number[j] =
+-				sb->u.ext3_sb.s_block_bitmap_number[j - 1];
+-			sb->u.ext3_sb.s_block_bitmap[j] =
+-				sb->u.ext3_sb.s_block_bitmap[j - 1];
++			brelse(sbi->s_block_bitmap[EXT3_MAX_GROUP_LOADED - 1]);
++		for (j = sbi->s_loaded_block_bitmaps - 1; j > 0;  j--) {
++			sbi->s_block_bitmap_number[j] =
++				sbi->s_block_bitmap_number[j - 1];
++			sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1];
+ 		}
+ 		retval = read_block_bitmap (sb, block_group, 0);
+ 	}
+@@ -206,24 +203,25 @@ static int __load_block_bitmap (struct s
+ static inline int load_block_bitmap (struct super_block * sb,
+ 				     unsigned int block_group)
+ {
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 	int slot;
+-	
++
+ 	/*
+ 	 * Do the lookup for the slot.  First of all, check if we're asking
+ 	 * for the same slot as last time, and did we succeed that last time?
+ 	 */
+-	if (sb->u.ext3_sb.s_loaded_block_bitmaps > 0 &&
+-	    sb->u.ext3_sb.s_block_bitmap_number[0] == block_group &&
+-	    sb->u.ext3_sb.s_block_bitmap[0]) {
++	if (sbi->s_loaded_block_bitmaps > 0 &&
++	    sbi->s_block_bitmap_number[0] == block_group &&
++	    sbi->s_block_bitmap[0]) {
+ 		return 0;
+ 	}
+ 	/*
+ 	 * Or can we do a fast lookup based on a loaded group on a filesystem
+ 	 * small enough to be mapped directly into the superblock?
+ 	 */
+-	else if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED && 
+-		 sb->u.ext3_sb.s_block_bitmap_number[block_group]==block_group
+-			&& sb->u.ext3_sb.s_block_bitmap[block_group]) {
++	else if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED &&
++		 sbi->s_block_bitmap_number[block_group] == block_group
++			&& sbi->s_block_bitmap[block_group]) {
+ 		slot = block_group;
+ 	}
+ 	/*
+@@ -243,7 +241,7 @@ static inline int load_block_bitmap (str
+ 	 * If it's a valid slot, we may still have cached a previous IO error,
+ 	 * in which case the bh in the superblock cache will be zero.
+ 	 */
+-	if (!sb->u.ext3_sb.s_block_bitmap[slot])
++	if (!sbi->s_block_bitmap[slot])
+ 		return -EIO;
+ 	
+ 	/*
+@@ -275,7 +273,7 @@ void ext3_free_blocks (handle_t *handle,
+ 		return;
+ 	}
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
+ 	if (block < le32_to_cpu(es->s_first_data_block) ||
+ 	    block + count < block ||
+ 	    (block + count) > le32_to_cpu(es->s_blocks_count)) {
+@@ -305,7 +303,7 @@ do_more:
+ 	if (bitmap_nr < 0)
+ 		goto error_return;
+ 	
+-	bitmap_bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
++	bitmap_bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
+ 	gdp = ext3_get_group_desc (sb, block_group, &gd_bh);
+ 	if (!gdp)
+ 		goto error_return;
+@@ -330,8 +328,8 @@ do_more:
+ 	if (err)
+ 		goto error_return;
+ 
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
+-	err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
+ 	if (err)
+ 		goto error_return;
+ 
+@@ -339,7 +337,7 @@ do_more:
+ 		if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
+ 		    block == le32_to_cpu(gdp->bg_inode_bitmap) ||
+ 		    in_range(block, le32_to_cpu(gdp->bg_inode_table),
+-			     sb->u.ext2_sb.s_itb_per_group)) {
++			     EXT3_SB(sb)->s_itb_per_group)) {
+ 			ext3_error(sb, __FUNCTION__,
+ 				   "Freeing block in system zone - block = %lu",
+ 				   block);
+@@ -412,8 +410,8 @@ do_more:
+ 	if (!err) err = ret;
+ 
+ 	/* And the superblock */
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "dirtied superblock");
+-	ret = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "dirtied superblock");
++	ret = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+ 	if (!err) err = ret;
+ 
+ 	if (overflow && !err) {
+@@ -566,12 +564,12 @@ int ext3_new_block (handle_t *handle, st
+ 	}
+ 
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
+ 	if (le32_to_cpu(es->s_free_blocks_count) <=
+ 			le32_to_cpu(es->s_r_blocks_count) &&
+-	    ((sb->u.ext3_sb.s_resuid != current->fsuid) &&
+-	     (sb->u.ext3_sb.s_resgid == 0 ||
+-	      !in_group_p (sb->u.ext3_sb.s_resgid)) && 
++	    ((EXT3_SB(sb)->s_resuid != current->fsuid) &&
++	     (EXT3_SB(sb)->s_resgid == 0 ||
++	      !in_group_p (EXT3_SB(sb)->s_resgid)) &&
+ 	     !capable(CAP_SYS_RESOURCE)))
+ 		goto out;
+ 
+@@ -601,7 +599,7 @@ repeat:
+ 		if (bitmap_nr < 0)
+ 			goto io_error;
+ 		
+-		bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
++		bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
+ 
+ 		ext3_debug ("goal is at %d:%d.\n", i, j);
+ 
+@@ -624,9 +622,9 @@ repeat:
+ 	 * Now search the rest of the groups.  We assume that 
+ 	 * i and gdp correctly point to the last group visited.
+ 	 */
+-	for (k = 0; k < sb->u.ext3_sb.s_groups_count; k++) {
++	for (k = 0; k < EXT3_SB(sb)->s_groups_count; k++) {
+ 		i++;
+-		if (i >= sb->u.ext3_sb.s_groups_count)
++		if (i >= EXT3_SB(sb)->s_groups_count)
+ 			i = 0;
+ 		gdp = ext3_get_group_desc (sb, i, &bh2);
+ 		if (!gdp) {
+@@ -638,7 +636,7 @@ repeat:
+ 			if (bitmap_nr < 0)
+ 				goto io_error;
+ 	
+-			bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr];
++			bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
+ 			j = find_next_usable_block(-1, bh, 
+ 						   EXT3_BLOCKS_PER_GROUP(sb));
+ 			if (j >= 0) 
+@@ -676,8 +674,8 @@ got_block:
+ 	fatal = ext3_journal_get_write_access(handle, bh2);
+ 	if (fatal) goto out;
+ 
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
+-	fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
++	fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
+ 	if (fatal) goto out;
+ 
+ 	tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb)
+@@ -810,7 +808,7 @@ got_block:
+ 	if (!fatal) fatal = err;
+ 	
+ 	BUFFER_TRACE(bh, "journal_dirty_metadata for superblock");
+-	err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
++	err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+ 	if (!fatal) fatal = err;
+ 
+ 	sb->s_dirt = 1;
+@@ -848,11 +846,11 @@ unsigned long ext3_count_free_blocks (st
+ 	int i;
+ 	
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+ 	gdp = NULL;
+-	for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
++	for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+ 		gdp = ext3_get_group_desc (sb, i, NULL);
+ 		if (!gdp)
+ 			continue;
+@@ -861,7 +859,7 @@ unsigned long ext3_count_free_blocks (st
+ 		if (bitmap_nr < 0)
+ 			continue;
+ 		
+-		x = ext3_count_free (sb->u.ext3_sb.s_block_bitmap[bitmap_nr],
++		x = ext3_count_free (EXT3_SB(sb)->s_block_bitmap[bitmap_nr],
+ 				     sb->s_blocksize);
+ 		printk ("group %d: stored = %d, counted = %lu\n",
+ 			i, le16_to_cpu(gdp->bg_free_blocks_count), x);
+@@ -872,7 +870,7 @@ unsigned long ext3_count_free_blocks (st
+ 	unlock_super (sb);
+ 	return bitmap_count;
+ #else
+-	return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_blocks_count);
++	return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count);
+ #endif
+ }
+ 
+@@ -881,7 +879,7 @@ static inline int block_in_use (unsigned
+ 				unsigned char * map)
+ {
+ 	return ext3_test_bit ((block -
+-		le32_to_cpu(sb->u.ext3_sb.s_es->s_first_data_block)) %
++		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
+ 			 EXT3_BLOCKS_PER_GROUP(sb), map);
+ }
+ 
+@@ -949,11 +947,11 @@ void ext3_check_blocks_bitmap (struct su
+ 	struct ext3_group_desc * gdp;
+ 	int i;
+ 
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+ 	gdp = NULL;
+-	for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
++	for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+ 		gdp = ext3_get_group_desc (sb, i, NULL);
+ 		if (!gdp)
+ 			continue;
+@@ -987,7 +985,7 @@ void ext3_check_blocks_bitmap (struct su
+ 				    "Inode bitmap for group %d is marked free",
+ 				    i);
+ 
+-		for (j = 0; j < sb->u.ext3_sb.s_itb_per_group; j++)
++		for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++)
+ 			if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
+ 							sb, bh->b_data))
+ 				ext3_error (sb, "ext3_check_blocks_bitmap",
+--- linux-2.4.18-chaos/fs/ext3/dir.c~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/dir.c	2003-09-16 23:34:40.000000000 +0400
+@@ -67,7 +67,7 @@ int ext3_check_dir_entry (const char * f
+ 	else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+ 		error_msg = "directory entry across blocks";
+ 	else if (le32_to_cpu(de->inode) >
+-			le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
++			le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
+ 		error_msg = "inode out of bounds";
+ 
+ 	if (error_msg != NULL)
+--- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c	2003-09-16 23:34:40.000000000 +0400
+@@ -74,8 +74,8 @@ static int read_inode_bitmap (struct sup
+ 	 * this group.  The IO will be retried next time.
+ 	 */
+ error_out:
+-	sb->u.ext3_sb.s_inode_bitmap_number[bitmap_nr] = block_group;
+-	sb->u.ext3_sb.s_inode_bitmap[bitmap_nr] = bh;
++	EXT3_SB(sb)->s_inode_bitmap_number[bitmap_nr] = block_group;
++	EXT3_SB(sb)->s_inode_bitmap[bitmap_nr] = bh;
+ 	return retval;
+ }
+ 
+@@ -227,7 +227,7 @@ void ext3_free_inode (handle_t *handle, 
+ 	clear_inode (inode);
+ 
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
+ 	if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
+ 		ext3_error (sb, "ext3_free_inode",
+ 			    "reserved or nonexistent inode %lu", ino);
+@@ -239,7 +239,7 @@ void ext3_free_inode (handle_t *handle, 
+ 	if (bitmap_nr < 0)
+ 		goto error_return;
+ 
+-	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
++	bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
+ 
+ 	BUFFER_TRACE(bh, "get_write_access");
+ 	fatal = ext3_journal_get_write_access(handle, bh);
+@@ -257,8 +257,8 @@ void ext3_free_inode (handle_t *handle, 
+ 		fatal = ext3_journal_get_write_access(handle, bh2);
+ 		if (fatal) goto error_return;
+ 
+-		BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get write access");
+-		fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
++		BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get write access");
++		fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
+ 		if (fatal) goto error_return;
+ 
+ 		if (gdp) {
+@@ -273,9 +273,9 @@ void ext3_free_inode (handle_t *handle, 
+ 		if (!fatal) fatal = err;
+ 		es->s_free_inodes_count =
+ 			cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1);
+-		BUFFER_TRACE(sb->u.ext3_sb.s_sbh,
++		BUFFER_TRACE(EXT3_SB(sb)->s_sbh,
+ 					"call ext3_journal_dirty_metadata");
+-		err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
++		err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+ 		if (!fatal) fatal = err;
+ 	}
+ 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+@@ -307,6 +307,8 @@ struct inode * ext3_new_inode (handle_t 
+ 	int i, j, avefreei;
+ 	struct inode * inode;
+ 	int bitmap_nr;
++	struct ext3_inode_info *ei;
++	struct ext3_sb_info *sbi;
+ 	struct ext3_group_desc * gdp;
+ 	struct ext3_group_desc * tmp;
+ 	struct ext3_super_block * es;
+@@ -320,7 +322,9 @@ struct inode * ext3_new_inode (handle_t 
+ 	inode = new_inode(sb);
+ 	if (!inode)
+ 		return ERR_PTR(-ENOMEM);
+-	init_rwsem(&inode->u.ext3_i.truncate_sem);
++	sbi = EXT3_SB(sb);
++	ei = EXT3_I(inode);
++	init_rwsem(&ei->truncate_sem);
+ 
+ 	lock_super (sb);
+ 	es = sb->u.ext3_sb.s_es;
+@@ -330,9 +334,9 @@ repeat:
+ 
+ 	if (S_ISDIR(mode)) {
+ 		avefreei = le32_to_cpu(es->s_free_inodes_count) /
+-			sb->u.ext3_sb.s_groups_count;
++			sbi->s_groups_count;
+ 		if (!gdp) {
+-			for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) {
++			for (j = 0; j < sbi->s_groups_count; j++) {
+ 				struct buffer_head *temp_buffer;
+ 				tmp = ext3_get_group_desc (sb, j, &temp_buffer);
+ 				if (tmp &&
+@@ -352,7 +356,7 @@ repeat:
+ 		/*
+ 		 * Try to place the inode in its parent directory
+ 		 */
+-		i = dir->u.ext3_i.i_block_group;
++		i = EXT3_I(dir)->i_block_group;
+ 		tmp = ext3_get_group_desc (sb, i, &bh2);
+ 		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
+ 			gdp = tmp;
+@@ -362,10 +366,10 @@ repeat:
+ 			 * Use a quadratic hash to find a group with a
+ 			 * free inode
+ 			 */
+-			for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) {
++			for (j = 1; j < sbi->s_groups_count; j <<= 1) {
+ 				i += j;
+-				if (i >= sb->u.ext3_sb.s_groups_count)
+-					i -= sb->u.ext3_sb.s_groups_count;
++				if (i >= sbi->s_groups_count)
++					i -= sbi->s_groups_count;
+ 				tmp = ext3_get_group_desc (sb, i, &bh2);
+ 				if (tmp &&
+ 				    le16_to_cpu(tmp->bg_free_inodes_count)) {
+@@ -378,9 +382,9 @@ repeat:
+ 			/*
+ 			 * That failed: try linear search for a free inode
+ 			 */
+-			i = dir->u.ext3_i.i_block_group + 1;
+-			for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) {
+-				if (++i >= sb->u.ext3_sb.s_groups_count)
++			i = EXT3_I(dir)->i_block_group + 1;
++			for (j = 2; j < sbi->s_groups_count; j++) {
++				if (++i >= sbi->s_groups_count)
+ 					i = 0;
+ 				tmp = ext3_get_group_desc (sb, i, &bh2);
+ 				if (tmp &&
+@@ -401,11 +405,11 @@ repeat:
+ 	if (bitmap_nr < 0)
+ 		goto fail;
+ 
+-	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
++	bh = sbi->s_inode_bitmap[bitmap_nr];
+ 
+ 	if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
+-				      EXT3_INODES_PER_GROUP(sb))) <
+-	    EXT3_INODES_PER_GROUP(sb)) {
++				      sbi->s_inodes_per_group)) <
++	    sbi->s_inodes_per_group) {
+ 		BUFFER_TRACE(bh, "get_write_access");
+ 		err = ext3_journal_get_write_access(handle, bh);
+ 		if (err) goto fail;
+@@ -459,13 +463,13 @@ repeat:
+ 	err = ext3_journal_dirty_metadata(handle, bh2);
+ 	if (err) goto fail;
+ 	
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
+-	err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(sbi->s_sbh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, sbi->s_sbh);
+ 	if (err) goto fail;
+ 	es->s_free_inodes_count =
+ 		cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "call ext3_journal_dirty_metadata");
+-	err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(sbi->s_sbh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, sbi->s_sbh);
+ 	sb->s_dirt = 1;
+ 	if (err) goto fail;
+ 
+@@ -485,31 +489,31 @@ repeat:
+ 	inode->i_blksize = PAGE_SIZE;
+ 	inode->i_blocks = 0;
+ 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+-	inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL;
++	ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
+ 	if (S_ISLNK(mode))
+-		inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
++		ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
+ #ifdef EXT3_FRAGMENTS
+-	inode->u.ext3_i.i_faddr = 0;
+-	inode->u.ext3_i.i_frag_no = 0;
+-	inode->u.ext3_i.i_frag_size = 0;
++	ei->i_faddr = 0;
++	ei->i_frag_no = 0;
++	ei->i_frag_size = 0;
+ #endif
+-	inode->u.ext3_i.i_file_acl = 0;
+-	inode->u.ext3_i.i_dir_acl = 0;
+-	inode->u.ext3_i.i_dtime = 0;
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++	ei->i_file_acl = 0;
++	ei->i_dir_acl = 0;
++	ei->i_dtime = 0;
++	INIT_LIST_HEAD(&ei->i_orphan);
+ #ifdef EXT3_PREALLOCATE
+-	inode->u.ext3_i.i_prealloc_count = 0;
++	ei->i_prealloc_count = 0;
+ #endif
+-	inode->u.ext3_i.i_block_group = i;
++	ei->i_block_group = i;
+ 	
+-	if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL)
++	if (ei->i_flags & EXT3_SYNC_FL)
+ 		inode->i_flags |= S_SYNC;
+ 	if (IS_SYNC(inode))
+ 		handle->h_sync = 1;
+ 	insert_inode_hash(inode);
+-	inode->i_generation = sb->u.ext3_sb.s_next_generation++;
++	inode->i_generation = sbi->s_next_generation++;
+ 
+-	inode->u.ext3_i.i_state = EXT3_STATE_NEW;
++	ei->i_state = EXT3_STATE_NEW;
+ 	err = ext3_mark_inode_dirty(handle, inode);
+ 	if (err) goto fail;
+ 	
+@@ -588,19 +592,19 @@ struct inode *ext3_orphan_get(struct sup
+ 
+ unsigned long ext3_count_free_inodes (struct super_block * sb)
+ {
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	struct ext3_super_block *es = sbi->s_es;
+ #ifdef EXT3FS_DEBUG
+-	struct ext3_super_block * es;
+ 	unsigned long desc_count, bitmap_count, x;
+ 	int bitmap_nr;
+ 	struct ext3_group_desc * gdp;
+ 	int i;
+ 
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+ 	gdp = NULL;
+-	for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
++	for (i = 0; i < sbi->s_groups_count; i++) {
+ 		gdp = ext3_get_group_desc (sb, i, NULL);
+ 		if (!gdp)
+ 			continue;
+@@ -609,8 +613,8 @@ unsigned long ext3_count_free_inodes (st
+ 		if (bitmap_nr < 0)
+ 			continue;
+ 
+-		x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr],
+-				     EXT3_INODES_PER_GROUP(sb) / 8);
++		x = ext3_count_free(sbi->s_inode_bitmap[bitmap_nr],
++				    sbi->s_inodes_per_group / 8);
+ 		printk ("group %d: stored = %d, counted = %lu\n",
+ 			i, le16_to_cpu(gdp->bg_free_inodes_count), x);
+ 		bitmap_count += x;
+@@ -620,7 +624,7 @@ unsigned long ext3_count_free_inodes (st
+ 	unlock_super (sb);
+ 	return desc_count;
+ #else
+-	return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_inodes_count);
++	return le32_to_cpu(es->s_free_inodes_count);
+ #endif
+ }
+ 
+@@ -629,16 +633,18 @@ unsigned long ext3_count_free_inodes (st
+ void ext3_check_inodes_bitmap (struct super_block * sb)
+ {
+ 	struct ext3_super_block * es;
++	struct ext3_sb_info *sbi;
+ 	unsigned long desc_count, bitmap_count, x;
+ 	int bitmap_nr;
+ 	struct ext3_group_desc * gdp;
+ 	int i;
+ 
+-	es = sb->u.ext3_sb.s_es;
++	sbi = EXT3_SB(sb);
++	es = sbi->s_es;
+ 	desc_count = 0;
+ 	bitmap_count = 0;
+ 	gdp = NULL;
+-	for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) {
++	for (i = 0; i < sbi->s_groups_count; i++) {
+ 		gdp = ext3_get_group_desc (sb, i, NULL);
+ 		if (!gdp)
+ 			continue;
+@@ -647,7 +653,7 @@ void ext3_check_inodes_bitmap (struct su
+ 		if (bitmap_nr < 0)
+ 			continue;
+ 
+-		x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr],
++		x = ext3_count_free (sbi->s_inode_bitmap[bitmap_nr],
+ 				     EXT3_INODES_PER_GROUP(sb) / 8);
+ 		if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
+ 			ext3_error (sb, "ext3_check_inodes_bitmap",
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c	2003-09-16 23:34:40.000000000 +0400
+@@ -206,7 +206,7 @@ void ext3_delete_inode (struct inode * i
+ 	 * (Well, we could do this if we need to, but heck - it works)
+ 	 */
+ 	ext3_orphan_del(handle, inode);
+-	inode->u.ext3_i.i_dtime	= CURRENT_TIME;
++	EXT3_I(inode)->i_dtime = CURRENT_TIME;
+ 
+ 	/* 
+ 	 * One subtle ordering requirement: if anything has gone wrong
+@@ -230,13 +230,14 @@ no_delete:
+ void ext3_discard_prealloc (struct inode * inode)
+ {
+ #ifdef EXT3_PREALLOCATE
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	lock_kernel();
+ 	/* Writer: ->i_prealloc* */
+-	if (inode->u.ext3_i.i_prealloc_count) {
+-		unsigned short total = inode->u.ext3_i.i_prealloc_count;
+-		unsigned long block = inode->u.ext3_i.i_prealloc_block;
+-		inode->u.ext3_i.i_prealloc_count = 0;
+-		inode->u.ext3_i.i_prealloc_block = 0;
++	if (ei->i_prealloc_count) {
++		unsigned short total = ei->i_prealloc_count;
++		unsigned long block = ei->i_prealloc_block;
++		ei->i_prealloc_count = 0;
++		ei->i_prealloc_block = 0;
+ 		/* Writer: end */
+ 		ext3_free_blocks (inode, block, total);
+ 	}
+@@ -253,13 +254,15 @@ static int ext3_alloc_block (handle_t *h
+ 	unsigned long result;
+ 
+ #ifdef EXT3_PREALLOCATE
++	struct ext3_inode_info *ei = EXT3_I(inode);
++
+ 	/* Writer: ->i_prealloc* */
+-	if (inode->u.ext3_i.i_prealloc_count &&
+-	    (goal == inode->u.ext3_i.i_prealloc_block ||
+-	     goal + 1 == inode->u.ext3_i.i_prealloc_block))
++	if (ei->i_prealloc_count &&
++	    (goal == ei->i_prealloc_block ||
++	     goal + 1 == ei->i_prealloc_block))
+ 	{
+-		result = inode->u.ext3_i.i_prealloc_block++;
+-		inode->u.ext3_i.i_prealloc_count--;
++		result = ei->i_prealloc_block++;
++		ei->i_prealloc_count--;
+ 		/* Writer: end */
+ 		ext3_debug ("preallocation hit (%lu/%lu).\n",
+ 			    ++alloc_hits, ++alloc_attempts);
+@@ -269,8 +272,8 @@ static int ext3_alloc_block (handle_t *h
+ 			    alloc_hits, ++alloc_attempts);
+ 		if (S_ISREG(inode->i_mode))
+ 			result = ext3_new_block (inode, goal, 
+-				 &inode->u.ext3_i.i_prealloc_count,
+-				 &inode->u.ext3_i.i_prealloc_block, err);
++				 &ei->i_prealloc_count,
++				 &ei->i_prealloc_block, err);
+ 		else
+ 			result = ext3_new_block (inode, goal, 0, 0, err);
+ 		/*
+@@ -404,7 +407,7 @@ static Indirect *ext3_get_branch(struct 
+ 
+ 	*err = 0;
+ 	/* i_data is not going away, no lock needed */
+-	add_chain (chain, NULL, inode->u.ext3_i.i_data + *offsets);
++	add_chain (chain, NULL, EXT3_I(inode)->i_data + *offsets);
+ 	if (!p->key)
+ 		goto no_block;
+ 	while (--depth) {
+@@ -448,7 +451,8 @@ no_block:
+ 
+ static inline unsigned long ext3_find_near(struct inode *inode, Indirect *ind)
+ {
+-	u32 *start = ind->bh ? (u32*) ind->bh->b_data : inode->u.ext3_i.i_data;
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	u32 *start = ind->bh ? (u32*) ind->bh->b_data : ei->i_data;
+ 	u32 *p;
+ 
+ 	/* Try to find previous block */
+@@ -464,9 +468,8 @@ static inline unsigned long ext3_find_ne
+ 	 * It is going to be refered from inode itself? OK, just put it into
+ 	 * the same cylinder group then.
+ 	 */
+-	return (inode->u.ext3_i.i_block_group * 
+-		EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
+-	       le32_to_cpu(inode->i_sb->u.ext3_sb.s_es->s_first_data_block);
++	return (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
++	       le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
+ }
+ 
+ /**
+@@ -485,14 +488,15 @@ static inline unsigned long ext3_find_ne
+ static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4],
+ 			  Indirect *partial, unsigned long *goal)
+ {
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	/* Writer: ->i_next_alloc* */
+-	if (block == inode->u.ext3_i.i_next_alloc_block + 1) {
+-		inode->u.ext3_i.i_next_alloc_block++;
+-		inode->u.ext3_i.i_next_alloc_goal++;
++	if (block == ei->i_next_alloc_block + 1) {
++		ei->i_next_alloc_block++;
++		ei->i_next_alloc_goal++;
+ 	}
+ #ifdef SEARCH_FROM_ZERO
+-	inode->u.ext3_i.i_next_alloc_block = 0;
+-	inode->u.ext3_i.i_next_alloc_goal = 0;
++	ei->i_next_alloc_block = 0;
++	ei->i_next_alloc_goal = 0;
+ #endif
+ 	/* Writer: end */
+ 	/* Reader: pointers, ->i_next_alloc* */
+@@ -501,8 +505,8 @@ static int ext3_find_goal(struct inode *
+ 		 * try the heuristic for sequential allocation,
+ 		 * failing that at least try to get decent locality.
+ 		 */
+-		if (block == inode->u.ext3_i.i_next_alloc_block)
+-			*goal = inode->u.ext3_i.i_next_alloc_goal;
++		if (block == ei->i_next_alloc_block)
++			*goal = ei->i_next_alloc_goal;
+ 		if (!*goal)
+ 			*goal = ext3_find_near(inode, partial);
+ #ifdef SEARCH_FROM_ZERO
+@@ -628,6 +632,7 @@ static int ext3_splice_branch(handle_t *
+ {
+ 	int i;
+ 	int err = 0;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 
+ 	/*
+ 	 * If we're splicing into a [td]indirect block (as opposed to the
+@@ -650,11 +655,11 @@ static int ext3_splice_branch(handle_t *
+ 	/* That's it */
+ 
+ 	*where->p = where->key;
+-	inode->u.ext3_i.i_next_alloc_block = block;
+-	inode->u.ext3_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key);
++	ei->i_next_alloc_block = block;
++	ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key);
+ #ifdef SEARCH_FROM_ZERO
+-	inode->u.ext3_i.i_next_alloc_block = 0;
+-	inode->u.ext3_i.i_next_alloc_goal = 0;
++	ei->i_next_alloc_block = 0;
++	ei->i_next_alloc_goal = 0;
+ #endif
+ 	/* Writer: end */
+ 
+@@ -738,6 +743,7 @@ static int ext3_get_block_handle(handle_
+ 	unsigned long goal;
+ 	int left;
+ 	int depth = ext3_block_to_path(inode, iblock, offsets);
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	loff_t new_size;
+ 
+ 	J_ASSERT(handle != NULL || create == 0);
+@@ -791,7 +797,7 @@ out:
+ 	/*
+ 	 * Block out ext3_truncate while we alter the tree
+ 	 */
+-	down_read(&inode->u.ext3_i.truncate_sem);
++	down_read(&ei->truncate_sem);
+ 	err = ext3_alloc_branch(handle, inode, left, goal,
+ 					offsets+(partial-chain), partial);
+ 
+@@ -803,7 +809,7 @@ out:
+ 	if (!err)
+ 		err = ext3_splice_branch(handle, inode, iblock, chain,
+ 					 partial, left);
+-	up_read(&inode->u.ext3_i.truncate_sem);
++	up_read(&ei->truncate_sem);
+ 	if (err == -EAGAIN)
+ 		goto changed;
+ 	if (err)
+@@ -816,8 +822,8 @@ out:
+ 	 * truncate is in progress.  It is racy between multiple parallel
+ 	 * instances of get_block, but we have the BKL.
+ 	 */
+-	if (new_size > inode->u.ext3_i.i_disksize)
+-		inode->u.ext3_i.i_disksize = new_size;
++	if (new_size > ei->i_disksize)
++		ei->i_disksize = new_size;
+ 
+ 	bh_result->b_state |= (1UL << BH_New);
+ 	goto got_it;
+@@ -932,7 +938,7 @@ struct buffer_head *ext3_bread(handle_t 
+ 		struct buffer_head *tmp_bh;
+ 
+ 		for (i = 1;
+-		     inode->u.ext3_i.i_prealloc_count &&
++		     EXT3_I(inode)->i_prealloc_count &&
+ 		     i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
+ 		     i++) {
+ 			/*
+@@ -1152,8 +1158,8 @@ static int ext3_commit_write(struct file
+ 			kunmap(page);
+ 		}
+ 	}
+-	if (inode->i_size > inode->u.ext3_i.i_disksize) {
+-		inode->u.ext3_i.i_disksize = inode->i_size;
++	if (inode->i_size > EXT3_I(inode)->i_disksize) {
++		EXT3_I(inode)->i_disksize = inode->i_size;
+ 		ret2 = ext3_mark_inode_dirty(handle, inode);
+ 		if (!ret) 
+ 			ret = ret2;
+@@ -1873,7 +1879,8 @@ static void ext3_free_branches(handle_t 
+ void ext3_truncate(struct inode * inode)
+ {
+ 	handle_t *handle;
+-	u32 *i_data = inode->u.ext3_i.i_data;
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	u32 *i_data = EXT3_I(inode)->i_data;
+ 	int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb);
+ 	int offsets[4];
+ 	Indirect chain[4];
+@@ -1934,13 +1941,13 @@ void ext3_truncate(struct inode * inode)
+ 	 * on-disk inode. We do this via i_disksize, which is the value which
+ 	 * ext3 *really* writes onto the disk inode.
+ 	 */
+-	inode->u.ext3_i.i_disksize = inode->i_size;
++	ei->i_disksize = inode->i_size;
+ 
+ 	/*
+ 	 * From here we block out all ext3_get_block() callers who want to
+ 	 * modify the block allocation tree.
+ 	 */
+-	down_write(&inode->u.ext3_i.truncate_sem);
++	down_write(&ei->truncate_sem);
+ 
+ 	if (n == 1) {		/* direct blocks */
+ 		ext3_free_data(handle, inode, NULL, i_data+offsets[0],
+@@ -2004,7 +2011,7 @@ do_indirects:
+ 		case EXT3_TIND_BLOCK:
+ 			;
+ 	}
+-	up_write(&inode->u.ext3_i.truncate_sem);
++	up_write(&ei->truncate_sem);
+ 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 
+@@ -2041,6 +2048,8 @@ out_unlock:
+ 
+ int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
+ {
++	struct super_block *sb = inode->i_sb;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 	struct buffer_head *bh = 0;
+ 	unsigned long block;
+ 	unsigned long block_group;
+@@ -2051,25 +2060,21 @@ int ext3_get_inode_loc (struct inode *in
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+-		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+-		inode->i_ino > le32_to_cpu(
+-			inode->i_sb->u.ext3_sb.s_es->s_inodes_count)) {
+-		ext3_error (inode->i_sb, "ext3_get_inode_loc",
+-			    "bad inode number: %lu", inode->i_ino);
++		inode->i_ino < EXT3_FIRST_INO(sb)) ||
++		inode->i_ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
++		ext3_error (sb, __FUNCTION__, "bad inode #%lu", inode->i_ino);
+ 		goto bad_inode;
+ 	}
+-	block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb);
+-	if (block_group >= inode->i_sb->u.ext3_sb.s_groups_count) {
+-		ext3_error (inode->i_sb, "ext3_get_inode_loc",
+-			    "group >= groups count");
++	block_group = (inode->i_ino - 1) / sbi->s_inodes_per_group;
++	if (block_group >= sbi->s_groups_count) {
++		ext3_error(sb, __FUNCTION__, "group >= groups count");
+ 		goto bad_inode;
+ 	}
+-	group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
+-	desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
+-	bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc];
++	group_desc = block_group >> sbi->s_desc_per_block_bits;
++	desc = block_group & (sbi->s_desc_per_block - 1);
++	bh = sbi->s_group_desc[group_desc];
+ 	if (!bh) {
+-		ext3_error (inode->i_sb, "ext3_get_inode_loc",
+-			    "Descriptor not loaded");
++		ext3_error(sb, __FUNCTION__, "Descriptor not loaded");
+ 		goto bad_inode;
+ 	}
+ 
+@@ -2077,17 +2082,17 @@ int ext3_get_inode_loc (struct inode *in
+ 	/*
+ 	 * Figure out the offset within the block group inode table
+ 	 */
+-	offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
+-		EXT3_INODE_SIZE(inode->i_sb);
++	offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) *
++		sbi->s_inode_size;
+ 	block = le32_to_cpu(gdp[desc].bg_inode_table) +
+-		(offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
+-	if (!(bh = sb_bread(inode->i_sb, block))) {
+-		ext3_error (inode->i_sb, "ext3_get_inode_loc",
++		(offset >> EXT3_BLOCK_SIZE_BITS(sb));
++	if (!(bh = sb_bread(sb, block))) {
++		ext3_error (sb, __FUNCTION__,
+ 			    "unable to read inode block - "
+ 			    "inode=%lu, block=%lu", inode->i_ino, block);
+ 		goto bad_inode;
+ 	}
+-	offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
++	offset &= (EXT3_BLOCK_SIZE(sb) - 1);
+ 
+ 	iloc->bh = bh;
+ 	iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
+@@ -2103,6 +2108,7 @@ void ext3_read_inode(struct inode * inod
+ {
+ 	struct ext3_iloc iloc;
+ 	struct ext3_inode *raw_inode;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct buffer_head *bh;
+ 	int block;
+ 	
+@@ -2110,7 +2116,7 @@ void ext3_read_inode(struct inode * inod
+ 		goto bad_inode;
+ 	bh = iloc.bh;
+ 	raw_inode = iloc.raw_inode;
+-	init_rwsem(&inode->u.ext3_i.truncate_sem);
++	init_rwsem(&ei->truncate_sem);
+ 	inode->i_mode = le16_to_cpu(raw_inode->i_mode);
+ 	inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
+ 	inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
+@@ -2123,7 +2129,7 @@ void ext3_read_inode(struct inode * inod
+ 	inode->i_atime = le32_to_cpu(raw_inode->i_atime);
+ 	inode->i_ctime = le32_to_cpu(raw_inode->i_ctime);
+ 	inode->i_mtime = le32_to_cpu(raw_inode->i_mtime);
+-	inode->u.ext3_i.i_dtime = le32_to_cpu(raw_inode->i_dtime);
++	ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
+ 	/* We now have enough fields to check if the inode was active or not.
+ 	 * This is needed because nfsd might try to access dead inodes
+ 	 * the test is that same one that e2fsck uses
+@@ -2131,7 +2137,7 @@ void ext3_read_inode(struct inode * inod
+ 	 */
+ 	if (inode->i_nlink == 0) {
+ 		if (inode->i_mode == 0 ||
+-		    !(inode->i_sb->u.ext3_sb.s_mount_state & EXT3_ORPHAN_FS)) {
++		    !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) {
+ 			/* this inode is deleted */
+ 			brelse (bh);
+ 			goto bad_inode;
+@@ -2146,33 +2152,33 @@ void ext3_read_inode(struct inode * inod
+ 					 * size */  
+ 	inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
+ 	inode->i_version = ++event;
+-	inode->u.ext3_i.i_flags = le32_to_cpu(raw_inode->i_flags);
++	ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+ #ifdef EXT3_FRAGMENTS
+-	inode->u.ext3_i.i_faddr = le32_to_cpu(raw_inode->i_faddr);
+-	inode->u.ext3_i.i_frag_no = raw_inode->i_frag;
+-	inode->u.ext3_i.i_frag_size = raw_inode->i_fsize;
++	ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
++	ei->i_frag_no = raw_inode->i_frag;
++	ei->i_frag_size = raw_inode->i_fsize;
+ #endif
+-	inode->u.ext3_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
++	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
+ 	if (!S_ISREG(inode->i_mode)) {
+-		inode->u.ext3_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
++		ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
+ 	} else {
+ 		inode->i_size |=
+ 			((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
+ 	}
+-	inode->u.ext3_i.i_disksize = inode->i_size;
++	ei->i_disksize = inode->i_size;
+ 	inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+ #ifdef EXT3_PREALLOCATE
+-	inode->u.ext3_i.i_prealloc_count = 0;
++	ei->i_prealloc_count = 0;
+ #endif
+-	inode->u.ext3_i.i_block_group = iloc.block_group;
++	ei->i_block_group = iloc.block_group;
+ 
+ 	/*
+ 	 * NOTE! The in-memory inode i_data array is in little-endian order
+ 	 * even on big-endian machines: we do NOT byteswap the block numbers!
+ 	 */
+ 	for (block = 0; block < EXT3_N_BLOCKS; block++)
+-		inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++		ei->i_data[block] = iloc.raw_inode->i_block[block];
++	INIT_LIST_HEAD(&ei->i_orphan);
+ 
+ 	brelse (iloc.bh);
+ 
+@@ -2194,19 +2200,19 @@ void ext3_read_inode(struct inode * inod
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
+ 	/* inode->i_attr_flags = 0;				unused */
+-	if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
++	if (ei->i_flags & EXT3_SYNC_FL) {
+ 		/* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
+ 		inode->i_flags |= S_SYNC;
+ 	}
+-	if (inode->u.ext3_i.i_flags & EXT3_APPEND_FL) {
++	if (ei->i_flags & EXT3_APPEND_FL) {
+ 		/* inode->i_attr_flags |= ATTR_FLAG_APPEND;	unused */
+ 		inode->i_flags |= S_APPEND;
+ 	}
+-	if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) {
++	if (ei->i_flags & EXT3_IMMUTABLE_FL) {
+ 		/* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE;	unused */
+ 		inode->i_flags |= S_IMMUTABLE;
+ 	}
+-	if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) {
++	if (ei->i_flags & EXT3_NOATIME_FL) {
+ 		/* inode->i_attr_flags |= ATTR_FLAG_NOATIME;	unused */
+ 		inode->i_flags |= S_NOATIME;
+ 	}
+@@ -2228,6 +2234,7 @@ static int ext3_do_update_inode(handle_t
+ 				struct ext3_iloc *iloc)
+ {
+ 	struct ext3_inode *raw_inode = iloc->raw_inode;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct buffer_head *bh = iloc->bh;
+ 	int err = 0, rc, block;
+ 
+@@ -2245,7 +2252,7 @@ static int ext3_do_update_inode(handle_t
+  * Fix up interoperability with old kernels. Otherwise, old inodes get
+  * re-used with the upper 16 bits of the uid/gid intact
+  */
+-		if(!inode->u.ext3_i.i_dtime) {
++		if(!ei->i_dtime) {
+ 			raw_inode->i_uid_high =
+ 				cpu_to_le16(high_16_bits(inode->i_uid));
+ 			raw_inode->i_gid_high =
+@@ -2263,34 +2270,33 @@ static int ext3_do_update_inode(handle_t
+ 		raw_inode->i_gid_high = 0;
+ 	}
+ 	raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
+-	raw_inode->i_size = cpu_to_le32(inode->u.ext3_i.i_disksize);
++	raw_inode->i_size = cpu_to_le32(ei->i_disksize);
+ 	raw_inode->i_atime = cpu_to_le32(inode->i_atime);
+ 	raw_inode->i_ctime = cpu_to_le32(inode->i_ctime);
+ 	raw_inode->i_mtime = cpu_to_le32(inode->i_mtime);
+ 	raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
+-	raw_inode->i_dtime = cpu_to_le32(inode->u.ext3_i.i_dtime);
+-	raw_inode->i_flags = cpu_to_le32(inode->u.ext3_i.i_flags);
++	raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
++	raw_inode->i_flags = cpu_to_le32(ei->i_flags);
+ #ifdef EXT3_FRAGMENTS
+-	raw_inode->i_faddr = cpu_to_le32(inode->u.ext3_i.i_faddr);
+-	raw_inode->i_frag = inode->u.ext3_i.i_frag_no;
+-	raw_inode->i_fsize = inode->u.ext3_i.i_frag_size;
++	raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
++	raw_inode->i_frag = ei->i_frag_no;
++	raw_inode->i_fsize = ei->i_frag_size;
+ #else
+ 	/* If we are not tracking these fields in the in-memory inode,
+ 	 * then preserve them on disk, but still initialise them to zero
+ 	 * for new inodes. */
+-	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
++	if (ei->i_state & EXT3_STATE_NEW) {
+ 		raw_inode->i_faddr = 0;
+ 		raw_inode->i_frag = 0;
+ 		raw_inode->i_fsize = 0;
+ 	}
+ #endif
+-	raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl);
++	raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
+ 	if (!S_ISREG(inode->i_mode)) {
+-		raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext3_i.i_dir_acl);
++		raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
+ 	} else {
+-		raw_inode->i_size_high =
+-			cpu_to_le32(inode->u.ext3_i.i_disksize >> 32);
+-		if (inode->u.ext3_i.i_disksize > 0x7fffffffULL) {
++		raw_inode->i_size_high = cpu_to_le32(ei->i_disksize >> 32);
++		if (ei->i_disksize > MAX_NON_LFS) {
+ 			struct super_block *sb = inode->i_sb;
+ 			if (!EXT3_HAS_RO_COMPAT_FEATURE(sb,
+ 					EXT3_FEATURE_RO_COMPAT_LARGE_FILE) ||
+@@ -2300,7 +2306,7 @@ static int ext3_do_update_inode(handle_t
+ 				* created, add a flag to the superblock.
+ 				*/
+ 				err = ext3_journal_get_write_access(handle,
+-						sb->u.ext3_sb.s_sbh);
++						EXT3_SB(sb)->s_sbh);
+ 				if (err)
+ 					goto out_brelse;
+ 				ext3_update_dynamic_rev(sb);
+@@ -2309,7 +2315,7 @@ static int ext3_do_update_inode(handle_t
+ 				sb->s_dirt = 1;
+ 				handle->h_sync = 1;
+ 				err = ext3_journal_dirty_metadata(handle,
+-						sb->u.ext3_sb.s_sbh);
++						EXT3_SB(sb)->s_sbh);
+ 			}
+ 		}
+ 	}
+@@ -2318,13 +2324,13 @@ static int ext3_do_update_inode(handle_t
+ 		raw_inode->i_block[0] =
+ 			cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
+ 	else for (block = 0; block < EXT3_N_BLOCKS; block++)
+-		raw_inode->i_block[block] = inode->u.ext3_i.i_data[block];
++		raw_inode->i_block[block] = ei->i_data[block];
+ 
+ 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+ 	rc = ext3_journal_dirty_metadata(handle, bh);
+ 	if (!err)
+ 		err = rc;
+-	EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
++	ei->i_state &= ~EXT3_STATE_NEW;
+ 
+ out_brelse:
+ 	brelse (bh);
+@@ -2432,7 +2438,7 @@ int ext3_setattr(struct dentry *dentry, 
+ 		}
+ 		
+ 		error = ext3_orphan_add(handle, inode);
+-		inode->u.ext3_i.i_disksize = attr->ia_size;
++		EXT3_I(inode)->i_disksize = attr->ia_size;
+ 		rc = ext3_mark_inode_dirty(handle, inode);
+ 		if (!error)
+ 			error = rc;
+@@ -2675,9 +2681,9 @@ int ext3_change_inode_journal_flag(struc
+ 	 */
+ 
+ 	if (val)
+-		inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL;
++		EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
+ 	else
+-		inode->u.ext3_i.i_flags &= ~EXT3_JOURNAL_DATA_FL;
++		EXT3_I(inode)->i_flags &= ~EXT3_JOURNAL_DATA_FL;
+ 
+ 	journal_unlock_updates(journal);
+ 
+--- linux-2.4.18-chaos/fs/ext3/ioctl.c~ext3-2.4.18-ino_sb_macro-2	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.18-chaos-alexey/fs/ext3/ioctl.c	2003-09-16 23:34:40.000000000 +0400
+@@ -18,13 +18,14 @@
+ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
+ 		unsigned long arg)
+ {
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	unsigned int flags;
+ 
+ 	ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
+ 
+ 	switch (cmd) {
+ 	case EXT3_IOC_GETFLAGS:
+-		flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
++		flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
+ 		return put_user(flags, (int *) arg);
+ 	case EXT3_IOC_SETFLAGS: {
+ 		handle_t *handle = NULL;
+@@ -42,7 +43,7 @@ int ext3_ioctl (struct inode * inode, st
+ 		if (get_user(flags, (int *) arg))
+ 			return -EFAULT;
+ 
+-		oldflags = inode->u.ext3_i.i_flags;
++		oldflags = ei->i_flags;
+ 
+ 		/* The JOURNAL_DATA flag is modifiable only by root */
+ 		jflag = flags & EXT3_JOURNAL_DATA_FL;
+@@ -79,7 +80,7 @@ int ext3_ioctl (struct inode * inode, st
+ 		
+ 		flags = flags & EXT3_FL_USER_MODIFIABLE;
+ 		flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
+-		inode->u.ext3_i.i_flags = flags;
++		ei->i_flags = flags;
+ 
+ 		if (flags & EXT3_SYNC_FL)
+ 			inode->i_flags |= S_SYNC;
+@@ -155,12 +156,12 @@ flags_err:
+ 			int ret = 0;
+ 
+ 			set_current_state(TASK_INTERRUPTIBLE);
+-			add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
+-			if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) {
++			add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
++			if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) {
+ 				schedule();
+ 				ret = 1;
+ 			}
+-			remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
++			remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
+ 			return ret;
+ 		}
+ #endif
+--- linux-2.4.18-chaos/fs/ext3/namei.c~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/namei.c	2003-09-16 23:34:40.000000000 +0400
+@@ -1764,8 +1764,8 @@ int ext3_orphan_add(handle_t *handle, st
+ 	J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 		S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
+ 
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access");
+-	err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
+ 	if (err)
+ 		goto out_unlock;
+ 	
+@@ -1776,7 +1776,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	/* Insert this inode at the head of the on-disk orphan list... */
+ 	NEXT_ORPHAN(inode) = le32_to_cpu(EXT3_SB(sb)->s_es->s_last_orphan);
+ 	EXT3_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
+-	err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh);
++	err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+ 	rc = ext3_mark_iloc_dirty(handle, inode, &iloc);
+ 	if (!err)
+ 		err = rc;
+@@ -1850,8 +1850,7 @@ int ext3_orphan_del(handle_t *handle, st
+ 		err = ext3_journal_dirty_metadata(handle, sbi->s_sbh);
+ 	} else {
+ 		struct ext3_iloc iloc2;
+-		struct inode *i_prev =
+-			list_entry(prev, struct inode, u.ext3_i.i_orphan);
++		struct inode *i_prev = orphan_list_entry(prev);
+ 
+ 		jbd_debug(4, "orphan inode %lu will point to %lu\n",
+ 			  i_prev->i_ino, ino_next);
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c	2003-09-16 23:34:40.000000000 +0400
+@@ -124,7 +124,7 @@ static int ext3_error_behaviour(struct s
+ 	/* If no overrides were specified on the mount, then fall back
+ 	 * to the default behaviour set in the filesystem's superblock
+ 	 * on disk. */
+-	switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) {
++	switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) {
+ 	case EXT3_ERRORS_PANIC:
+ 		return EXT3_ERRORS_PANIC;
+ 	case EXT3_ERRORS_RO:
+@@ -272,9 +272,9 @@ void ext3_abort (struct super_block * sb
+ 		return;
+ 	
+ 	printk (KERN_CRIT "Remounting filesystem read-only\n");
+-	sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
++	EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
+ 	sb->s_flags |= MS_RDONLY;
+-	sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT;
++	EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+ 	journal_abort(EXT3_SB(sb)->s_journal, -EIO);
+ }
+ 
+@@ -380,8 +380,6 @@ static int ext3_blkdev_remove(struct ext
+ 	return ret;
+ }
+ 
+-#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan)
+-
+ static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi)
+ {
+ 	struct list_head *l;
+@@ -825,7 +823,7 @@ static void ext3_orphan_cleanup (struct 
+ 		sb->s_flags &= ~MS_RDONLY;
+ 	}
+ 
+-	if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) {
++	if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {
+ 		if (es->s_last_orphan)
+ 			jbd_debug(1, "Errors on filesystem, "
+ 				  "clearing orphan list.\n");
+@@ -1474,12 +1472,14 @@ static void ext3_commit_super (struct su
+ 			       struct ext3_super_block * es,
+ 			       int sync)
+ {
++	struct buffer_head *sbh = EXT3_SB(sb)->s_sbh;
++
+ 	es->s_wtime = cpu_to_le32(CURRENT_TIME);
+-	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty");
+-	mark_buffer_dirty(sb->u.ext3_sb.s_sbh);
++	BUFFER_TRACE(sbh, "marking dirty");
++	mark_buffer_dirty(sbh);
+ 	if (sync) {
+-		ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh);
+-		wait_on_buffer(sb->u.ext3_sb.s_sbh);
++		ll_rw_block(WRITE, 1, &sbh);
++		wait_on_buffer(sbh);
+ 	}
+ }
+ 
+@@ -1530,7 +1530,7 @@ static void ext3_clear_journal_err(struc
+ 		ext3_warning(sb, __FUNCTION__, "Marking fs in need of "
+ 			     "filesystem check.");
+ 		
+-		sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;
++		EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
+ 		es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
+ 		ext3_commit_super (sb, es, 1);
+ 
+--- linux-2.4.18-chaos/fs/ext3/symlink.c~ext3-2.4.18-ino_sb_macro-2	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.18-chaos-alexey/fs/ext3/symlink.c	2003-09-16 23:34:40.000000000 +0400
+@@ -23,14 +23,14 @@
+ 
+ static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+-	char *s = (char *)dentry->d_inode->u.ext3_i.i_data;
+-	return vfs_readlink(dentry, buffer, buflen, s);
++	struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
++	return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data);
+ }
+ 
+ static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+-	char *s = (char *)dentry->d_inode->u.ext3_i.i_data;
+-	return vfs_follow_link(nd, s);
++	struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
++	return vfs_follow_link(nd, (char*)ei->i_data);
+ }
+ 
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h	2003-09-16 23:34:40.000000000 +0400
+@@ -87,22 +87,25 @@
+ #define EXT3_MIN_BLOCK_SIZE		1024
+ #define	EXT3_MAX_BLOCK_SIZE		4096
+ #define EXT3_MIN_BLOCK_LOG_SIZE		  10
++
+ #ifdef __KERNEL__
+-# define EXT3_BLOCK_SIZE(s)		((s)->s_blocksize)
+-#else
+-# define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+-#endif
+-#define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+-#ifdef __KERNEL__
+-# define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+-#else
+-# define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
+-#endif
+-#ifdef __KERNEL__
+-#define	EXT3_ADDR_PER_BLOCK_BITS(s)	((s)->u.ext3_sb.s_addr_per_block_bits)
+-#define EXT3_INODE_SIZE(s)		((s)->u.ext3_sb.s_inode_size)
+-#define EXT3_FIRST_INO(s)		((s)->u.ext3_sb.s_first_ino)
++#define EXT3_SB(sb)	(&((sb)->u.ext3_sb))
++#define EXT3_I(inode)	(&((inode)->u.ext3_i))
++
++#define EXT3_BLOCK_SIZE(s)		((s)->s_blocksize)
++#define EXT3_BLOCK_SIZE_BITS(s)		((s)->s_blocksize_bits)
++#define	EXT3_ADDR_PER_BLOCK_BITS(s)	(EXT3_SB(s)->s_addr_per_block_bits)
++#define EXT3_INODE_SIZE(s)		(EXT3_SB(s)->s_inode_size)
++#define EXT3_FIRST_INO(s)		(EXT3_SB(s)->s_first_ino)
+ #else
++
++/* Assume that user mode programs are passing in an ext3fs superblock, not
++ * a kernel struct super_block.  This will allow us to call the feature-test
++ * macros from user land. */
++#define EXT3_SB(sb)	(sb)
++
++#define EXT3_BLOCK_SIZE(s)	(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
++#define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
+ #define EXT3_INODE_SIZE(s)	(((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \
+ 				 EXT3_GOOD_OLD_INODE_SIZE : \
+ 				 (s)->s_inode_size)
+@@ -110,6 +113,7 @@
+ 				 EXT3_GOOD_OLD_FIRST_INO : \
+ 				 (s)->s_first_ino)
+ #endif
++#define EXT3_ADDR_PER_BLOCK(s)	(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ 
+ /*
+  * Macro-instructions used to manage fragments
+@@ -118,8 +122,8 @@
+ #define	EXT3_MAX_FRAG_SIZE		4096
+ #define EXT3_MIN_FRAG_LOG_SIZE		  10
+ #ifdef __KERNEL__
+-# define EXT3_FRAG_SIZE(s)		((s)->u.ext3_sb.s_frag_size)
+-# define EXT3_FRAGS_PER_BLOCK(s)	((s)->u.ext3_sb.s_frags_per_block)
++# define EXT3_FRAG_SIZE(s)		(EXT3_SB(s)->s_frag_size)
++# define EXT3_FRAGS_PER_BLOCK(s)	(EXT3_SB(s)->s_frags_per_block)
+ #else
+ # define EXT3_FRAG_SIZE(s)		(EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+ # define EXT3_FRAGS_PER_BLOCK(s)	(EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
+@@ -143,15 +147,13 @@ struct ext3_group_desc
+ /*
+  * Macro-instructions used to manage group descriptors
+  */
++# define EXT3_BLOCKS_PER_GROUP(s)	(EXT3_SB(s)->s_blocks_per_group)
++# define EXT3_INODES_PER_GROUP(s)	(EXT3_SB(s)->s_inodes_per_group)
+ #ifdef __KERNEL__
+-# define EXT3_BLOCKS_PER_GROUP(s)	((s)->u.ext3_sb.s_blocks_per_group)
+-# define EXT3_DESC_PER_BLOCK(s)		((s)->u.ext3_sb.s_desc_per_block)
+-# define EXT3_INODES_PER_GROUP(s)	((s)->u.ext3_sb.s_inodes_per_group)
+-# define EXT3_DESC_PER_BLOCK_BITS(s)	((s)->u.ext3_sb.s_desc_per_block_bits)
++# define EXT3_DESC_PER_BLOCK(s)		(EXT3_SB(s)->s_desc_per_block)
++# define EXT3_DESC_PER_BLOCK_BITS(s)	(EXT3_SB(s)->s_desc_per_block_bits)
+ #else
+-# define EXT3_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
+ # define EXT3_DESC_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
+-# define EXT3_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
+ #endif
+ 
+ /*
+@@ -325,7 +327,7 @@ struct ext3_inode {
+ #ifndef _LINUX_EXT2_FS_H
+ #define clear_opt(o, opt)		o &= ~EXT3_MOUNT_##opt
+ #define set_opt(o, opt)			o |= EXT3_MOUNT_##opt
+-#define test_opt(sb, opt)		((sb)->u.ext3_sb.s_mount_opt & \
++#define test_opt(sb, opt)		(EXT3_SB(sb)->s_mount_opt & \
+ 					 EXT3_MOUNT_##opt)
+ #else
+ #define EXT2_MOUNT_NOLOAD		EXT3_MOUNT_NOLOAD
+@@ -425,17 +427,11 @@ struct ext3_super_block {
+ 	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+-#ifdef __KERNEL__
+-#define EXT3_SB(sb)	(&((sb)->u.ext3_sb))
+-#define EXT3_I(inode)	(&((inode)->u.ext3_i))
+-#else
+-/* Assume that user mode programs are passing in an ext3fs superblock, not
+- * a kernel struct super_block.  This will allow us to call the feature-test
+- * macros from user land. */
+-#define EXT3_SB(sb)	(sb)
+-#endif
+-
+-#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime
++#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime
++static inline struct inode *orphan_list_entry(struct list_head *l)
++{
++	return list_entry(l, struct inode, u.ext3_i.i_orphan);
++}
+ 
+ /*
+  * Codes for operating systems
+--- linux-2.4.18-chaos/include/linux/ext3_jbd.h~ext3-2.4.18-ino_sb_macro-2	2003-09-16 23:34:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_jbd.h	2003-09-16 23:34:40.000000000 +0400
+@@ -297,7 +297,7 @@ static inline int ext3_should_journal_da
+ 		return 1;
+ 	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
+ 		return 1;
+-	if (inode->u.ext3_i.i_flags & EXT3_JOURNAL_DATA_FL)
++	if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL)
+ 		return 1;
+ 	return 0;
+ }
diff --git a/lustre/kernel_patches/patches/ext3-compat-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-compat-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..68a2244af4f0521d74cd0ecd2ffe581b45ee323c
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-compat-2.4.18-chaos.patch
@@ -0,0 +1,46 @@
+ fs/ext3/namei.c |    3 ++-
+ lib/rbtree.c    |    6 +++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- linux-2.4.18-chaos-pdirops/fs/ext3/namei.c~ext3-compat-2.4.18-chaos	2003-09-23 13:13:10.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/namei.c	2003-09-23 13:13:28.000000000 +0400
+@@ -28,6 +28,7 @@
+ #include <linux/string.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
++#include <linux/slab.h>
+ 
+ 
+ /*
+@@ -830,9 +831,9 @@ static int ext3_rmdir (struct inode * di
+ 	 * recovery. */
+ 	inode->i_size = 0;
+ 	ext3_orphan_add(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
+ 	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+--- linux-2.4.18-chaos-pdirops/lib/rbtree.c~ext3-compat-2.4.18-chaos	2003-07-28 17:52:20.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/lib/rbtree.c	2003-09-23 13:13:15.000000000 +0400
+@@ -219,6 +219,8 @@ static void __rb_erase_color(rb_node_t *
+ 		node->rb_color = RB_BLACK;
+ }
+ 
++EXPORT_SYMBOL_GPL(rb_insert_color);
++
+ void rb_erase(rb_node_t * node, rb_root_t * root)
+ {
+ 	rb_node_t * child, * parent;
+@@ -292,6 +294,4 @@ void rb_erase(rb_node_t * node, rb_root_
+ 	if (color == RB_BLACK)
+ 		__rb_erase_color(child, parent, root);
+ }
+-
+-EXPORT_SYMBOL_GPL(rb_insert_color);
+-EXPORT_SYMBOL_GPL(rb_erase);
++EXPORT_SYMBOL(rb_erase);
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.18-2.patch b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.18-2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1e2295c0b9f22cee8eeae179ce61a904b768f30c
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.18-2.patch
@@ -0,0 +1,474 @@
+ fs/ext3/file.c             |    4 
+ fs/ext3/inode.c            |  112 +++++++++++++++++++++
+ fs/ext3/super.c            |  231 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_fs.h    |    5 
+ include/linux/ext3_fs_sb.h |   10 +
+ 5 files changed, 362 insertions(+)
+
+--- linux-2.4.18-chaos/fs/ext3/file.c~ext3-delete_thread-2.4.18-2	2003-09-16 23:34:07.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/file.c	2003-09-16 23:42:34.000000000 +0400
+@@ -124,7 +124,11 @@ struct file_operations ext3_file_operati
+ };
+ 
+ struct inode_operations ext3_file_inode_operations = {
++#ifdef EXT3_DELETE_THREAD
++	truncate:	ext3_truncate_thread,	/* BKL held */
++#else
+ 	truncate:	ext3_truncate,		/* BKL held */
++#endif
+ 	setattr:	ext3_setattr,		/* BKL held */
+ };
+ 
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-delete_thread-2.4.18-2	2003-09-16 23:39:37.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c	2003-09-16 23:42:34.000000000 +0400
+@@ -2041,6 +2041,118 @@ out_unlock:
+ 	return;		/* AKPM: return what? */
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/* Move blocks from to-be-truncated inode over to a new inode, and delete
++ * that one from the delete thread instead.  This avoids a lot of latency
++ * when truncating large files.
++ *
++ * If we have any problem deferring the truncate, just truncate it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++void ext3_truncate_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	handle_t *handle;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_truncate;
++
++	/* XXX This is a temporary limitation for code simplicity.
++	 *     We could truncate to arbitrary sizes at some later time.
++	 */
++	if (old_inode->i_size != 0)
++		goto out_truncate;
++
++	/* We may want to truncate the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
++	    old_inode->i_size > oei->i_disksize)
++		goto out_truncate;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_truncate;
++	}
++
++	ext3_discard_prealloc(old_inode);
++
++	/* old_inode   = 1
++	 * new_inode   = sb + GDT + ibitmap
++	 * orphan list = 1 inode/superblock for add, 2 inodes for del
++	 * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
++	 */
++	handle = ext3_journal_start(old_inode, 7);
++	if (IS_ERR(handle))
++		goto out_truncate;
++
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++	if (IS_ERR(new_inode)) {
++		ext3_debug("truncate inode %lu directly (no new inodes)\n",
++			   old_inode->i_ino);
++		goto out_journal;
++	}
++
++	nei = EXT3_I(new_inode);
++
++	down_write(&oei->truncate_sem);
++	new_inode->i_size = old_inode->i_size;
++	new_inode->i_blocks = old_inode->i_blocks;
++	new_inode->i_uid = old_inode->i_uid;
++	new_inode->i_gid = old_inode->i_gid;
++	new_inode->i_nlink = 0;
++
++	/* FIXME when we do arbitrary truncates */
++	old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
++	old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
++
++	memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
++	memset(oei->i_data, 0, sizeof(oei->i_data));
++
++	nei->i_disksize = oei->i_disksize;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up_write(&oei->truncate_sem);
++
++	if (ext3_orphan_add(handle, new_inode) < 0)
++		goto out_journal;
++
++	if (ext3_orphan_del(handle, old_inode) < 0) {
++		ext3_orphan_del(handle, new_inode);
++		iput(new_inode);
++		goto out_journal;
++	}
++
++	ext3_journal_stop(handle, old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_journal:
++	ext3_journal_stop(handle, old_inode);
++out_truncate:
++	ext3_truncate(old_inode);
++}
++#endif /* EXT3_DELETE_THREAD */
++
+ /* 
+  * ext3_get_inode_loc returns with an extra refcount against the
+  * inode's underlying buffer_head on success. 
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-delete_thread-2.4.18-2	2003-09-16 23:42:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c	2003-09-16 23:42:34.000000000 +0400
+@@ -398,6 +398,220 @@ static void dump_orphan_list(struct supe
+ 	}
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/*
++ * Delete inodes in a loop until there are no more to be deleted.
++ * Normally, we run in the background doing the deletes and sleeping again,
++ * and clients just add new inodes to be deleted onto the end of the list.
++ * If someone is concerned about free space (e.g. block allocation or similar)
++ * then they can sleep on s_delete_waiter_queue and be woken up when space
++ * has been freed.
++ */
++int ext3_delete_thread(void *data)
++{
++	struct super_block *sb = data;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	struct task_struct *tsk = current;
++
++	/* Almost like daemonize, but not quite */
++	exit_mm(current);
++	tsk->session = 1;
++	tsk->pgrp = 1;
++	tsk->tty = NULL;
++	exit_files(current);
++	reparent_to_init();
++
++	sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev));
++	sigfillset(&tsk->blocked);
++
++	/*tsk->flags |= PF_KERNTHREAD;*/
++
++	INIT_LIST_HEAD(&sbi->s_delete_list);
++	wake_up(&sbi->s_delete_waiter_queue);
++	ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev));
++
++	/* main loop */
++	for (;;) {
++		wait_event_interruptible(sbi->s_delete_thread_queue,
++					 !list_empty(&sbi->s_delete_list) ||
++					 !test_opt(sb, ASYNCDEL));
++		ext3_debug("%s woken up: %lu inodes, %lu blocks\n",
++			   tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks);
++
++		spin_lock(&sbi->s_delete_lock);
++		if (list_empty(&sbi->s_delete_list)) {
++			clear_opt(sbi->s_mount_opt, ASYNCDEL);
++			memset(&sbi->s_delete_list, 0,
++			       sizeof(sbi->s_delete_list));
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("delete thread on %s exiting\n",
++				   kdevname(sb->s_dev));
++			wake_up(&sbi->s_delete_waiter_queue);
++			break;
++		}
++
++		while (!list_empty(&sbi->s_delete_list)) {
++			struct inode *inode=list_entry(sbi->s_delete_list.next,
++						       struct inode, i_dentry);
++			unsigned long blocks = inode->i_blocks >>
++							(inode->i_blkbits - 9);
++
++			list_del_init(&inode->i_dentry);
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("%s delete ino %lu blk %lu\n",
++				   tsk->comm, inode->i_ino, blocks);
++
++			iput(inode);
++
++			spin_lock(&sbi->s_delete_lock);
++			sbi->s_delete_blocks -= blocks;
++			sbi->s_delete_inodes--;
++		}
++		if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) {
++			ext3_warning(sb, __FUNCTION__,
++				     "%lu blocks, %lu inodes on list?\n",
++				     sbi->s_delete_blocks,sbi->s_delete_inodes);
++			sbi->s_delete_blocks = 0;
++			sbi->s_delete_inodes = 0;
++		}
++		spin_unlock(&sbi->s_delete_lock);
++		wake_up(&sbi->s_delete_waiter_queue);
++	}
++
++	return 0;
++}
++
++static void ext3_start_delete_thread(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	int rc;
++
++	spin_lock_init(&sbi->s_delete_lock);
++	init_waitqueue_head(&sbi->s_delete_thread_queue);
++	init_waitqueue_head(&sbi->s_delete_waiter_queue);
++
++	if (!test_opt(sb, ASYNCDEL))
++		return;
++
++	rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES);
++	if (rc < 0)
++		printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n",
++		       rc);
++	else
++		wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next);
++}
++
++static void ext3_stop_delete_thread(struct ext3_sb_info *sbi)
++{
++	if (sbi->s_delete_list.next == 0)	/* thread never started */
++		return;
++
++	clear_opt(sbi->s_mount_opt, ASYNCDEL);
++	wake_up(&sbi->s_delete_thread_queue);
++	wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++}
++
++/* Instead of playing games with the inode flags, destruction, etc we just
++ * create a new inode locally and put it on a list for the truncate thread.
++ * We need large parts of the inode struct in order to complete the
++ * truncate and unlink, so we may as well just have a real inode to do it.
++ *
++ * If we have any problem deferring the delete, just delete it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++static void ext3_delete_inode_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (is_bad_inode(old_inode)) {
++		clear_inode(old_inode);
++		return;
++	}
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_delete;
++
++	/* We may want to delete the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS)
++		goto out_delete;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_delete;
++	}
++
++	/* We can iget this inode again here, because our caller has unhashed
++	 * old_inode, so new_inode will be in a different inode struct.
++	 *
++	 * We need to ensure that the i_orphan pointers in the other inodes
++	 * point at the new inode copy instead of the old one so the orphan
++	 * list doesn't get corrupted when the old orphan inode is freed.
++	 */
++	down(&sbi->s_orphan_lock);
++
++	sbi->s_mount_state |= EXT3_ORPHAN_FS;
++	new_inode = iget(old_inode->i_sb, old_inode->i_ino);
++	sbi->s_mount_state &= ~EXT3_ORPHAN_FS;
++	if (is_bad_inode(new_inode)) {
++		printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino);
++		iput(new_inode);
++		new_inode = NULL;
++	}
++	if (!new_inode) {
++		up(&sbi->s_orphan_lock);
++		ext3_debug("delete inode %lu directly (bad read)\n",
++			   old_inode->i_ino);
++		goto out_delete;
++	}
++	J_ASSERT(new_inode != old_inode);
++
++	J_ASSERT(!list_empty(&oei->i_orphan));
++
++	nei = EXT3_I(new_inode);
++	/* Ugh.  We need to insert new_inode into the same spot on the list
++	 * as old_inode was, to ensure the in-memory orphan list is still
++	 * in the same order as the on-disk orphan list (badness otherwise).
++	 */
++	nei->i_orphan = oei->i_orphan;
++	nei->i_orphan.next->prev = &nei->i_orphan;
++	nei->i_orphan.prev->next = &nei->i_orphan;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up(&sbi->s_orphan_lock);
++
++	clear_inode(old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_delete:
++	ext3_delete_inode(old_inode);
++}
++#else
++#define ext3_start_delete_thread(sbi) do {} while(0)
++#define ext3_stop_delete_thread(sbi) do {} while(0)
++#endif /* EXT3_DELETE_THREAD */
++
+ void ext3_put_super (struct super_block * sb)
+ {
+ 	struct ext3_sb_info *sbi = EXT3_SB(sb);
+@@ -405,6 +619,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+@@ -453,7 +668,11 @@ static struct super_operations ext3_sops
+ 	write_inode:	ext3_write_inode,	/* BKL not held.  Don't need */
+ 	dirty_inode:	ext3_dirty_inode,	/* BKL not held.  We take it */
+ 	put_inode:	ext3_put_inode,		/* BKL not held.  Don't need */
++#ifdef EXT3_DELETE_THREAD
++	delete_inode:	ext3_delete_inode_thread,/* BKL not held. We take it */
++#else
+ 	delete_inode:	ext3_delete_inode,	/* BKL not held.  We take it */
++#endif
+ 	put_super:	ext3_put_super,		/* BKL held */
+ 	write_super:	ext3_write_super,	/* BKL held */
+ 	sync_fs:	ext3_sync_fs,
+@@ -514,6 +733,14 @@ static int parse_options (char * options
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef EXT3_DELETE_THREAD
++		if (!strcmp(this_char, "asyncdel"))
++			set_opt(*mount_options, ASYNCDEL);
++		else if (!strcmp(this_char, "noasyncdel"))
++			clear_opt(*mount_options, ASYNCDEL);
++		else
++#endif
++
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -1203,6 +1430,7 @@ struct super_block * ext3_read_super (st
+ 	}
+ 
+ 	ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
++	ext3_start_delete_thread(sb);
+ 	/*
+ 	 * akpm: core read_super() calls in here with the superblock locked.
+ 	 * That deadlocks, because orphan cleanup needs to lock the superblock
+@@ -1643,6 +1871,9 @@ int ext3_remount (struct super_block * s
+ 	if (!parse_options(data, &tmp, sbi, &tmp, 1))
+ 		return -EINVAL;
+ 
++	if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY))
++		ext3_stop_delete_thread(sbi);
++
+ 	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+ 		ext3_abort(sb, __FUNCTION__, "Abort forced by user");
+ 
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-delete_thread-2.4.18-2	2003-09-16 23:39:37.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h	2003-09-16 23:42:34.000000000 +0400
+@@ -195,6 +195,7 @@ struct ext3_group_desc
+  */
+ #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
+ #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
++#define EXT3_STATE_DELETE		0x00000010 /* deferred delete inode */
+ 
+ /*
+  * ioctl commands
+@@ -322,6 +323,7 @@ struct ext3_inode {
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_ASYNCDEL		0x20000	/* Delayed deletion */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -708,6 +710,9 @@ extern void ext3_discard_prealloc (struc
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++#ifdef EXT3_DELETE_THREAD
++extern void ext3_truncate_thread(struct inode *inode);
++#endif
+ 
+ /* ioctl.c */
+ extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
+--- linux-2.4.18-chaos/include/linux/ext3_fs_sb.h~ext3-delete_thread-2.4.18-2	2003-09-16 23:42:33.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_sb.h	2003-09-16 23:42:34.000000000 +0400
+@@ -29,6 +29,8 @@
+ 
+ #define EXT3_MAX_GROUP_LOADED	32
+ 
++#define EXT3_DELETE_THREAD
++
+ /*
+  * third extended-fs super-block data in memory
+  */
+@@ -76,6 +78,14 @@ struct ext3_sb_info {
+ 	struct timer_list turn_ro_timer;	/* For turning read-only (crash simulation) */
+ 	wait_queue_head_t ro_wait_queue;	/* For people waiting for the fs to go read-only */
+ #endif
++#ifdef EXT3_DELETE_THREAD
++	spinlock_t s_delete_lock;
++	struct list_head s_delete_list;
++	unsigned long s_delete_blocks;
++	unsigned long s_delete_inodes;
++	wait_queue_head_t s_delete_thread_queue;
++	wait_queue_head_t s_delete_waiter_queue;
++#endif
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.19-suse.patch b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4bcefcefb3efc9beb17ee7a78cf149b33efc42a6
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.19-suse.patch
@@ -0,0 +1,481 @@
+ fs/ext3/file.c             |    4 
+ fs/ext3/inode.c            |  116 ++++++++++++++++++++++
+ fs/ext3/super.c            |  230 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_fs.h    |    5 
+ include/linux/ext3_fs_sb.h |   10 +
+ 5 files changed, 365 insertions(+)
+
+Index: linux-2.4.19.SuSE/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/super.c	Sun Nov 16 01:18:04 2003
++++ linux-2.4.19.SuSE/fs/ext3/super.c	Sun Nov 16 01:19:22 2003
+@@ -401,6 +401,220 @@
+ 	}
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/*
++ * Delete inodes in a loop until there are no more to be deleted.
++ * Normally, we run in the background doing the deletes and sleeping again,
++ * and clients just add new inodes to be deleted onto the end of the list.
++ * If someone is concerned about free space (e.g. block allocation or similar)
++ * then they can sleep on s_delete_waiter_queue and be woken up when space
++ * has been freed.
++ */
++int ext3_delete_thread(void *data)
++{
++	struct super_block *sb = data;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	struct task_struct *tsk = current;
++
++	/* Almost like daemonize, but not quite */
++	exit_mm(current);
++	tsk->session = 1;
++	tsk->pgrp = 1;
++	tsk->tty = NULL;
++	exit_files(current);
++	reparent_to_init();
++
++	sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev));
++	sigfillset(&tsk->blocked);
++
++	/*tsk->flags |= PF_KERNTHREAD;*/
++
++	INIT_LIST_HEAD(&sbi->s_delete_list);
++	wake_up(&sbi->s_delete_waiter_queue);
++	ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev));
++
++	/* main loop */
++	for (;;) {
++		wait_event_interruptible(sbi->s_delete_thread_queue,
++					 !list_empty(&sbi->s_delete_list) ||
++					 !test_opt(sb, ASYNCDEL));
++		ext3_debug("%s woken up: %lu inodes, %lu blocks\n",
++			   tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks);
++
++		spin_lock(&sbi->s_delete_lock);
++		if (list_empty(&sbi->s_delete_list)) {
++			clear_opt(sbi->s_mount_opt, ASYNCDEL);
++			memset(&sbi->s_delete_list, 0,
++			       sizeof(sbi->s_delete_list));
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("delete thread on %s exiting\n",
++				   kdevname(sb->s_dev));
++			wake_up(&sbi->s_delete_waiter_queue);
++			break;
++		}
++
++		while (!list_empty(&sbi->s_delete_list)) {
++			struct inode *inode=list_entry(sbi->s_delete_list.next,
++						       struct inode, i_dentry);
++			unsigned long blocks = inode->i_blocks >>
++							(inode->i_blkbits - 9);
++
++			list_del_init(&inode->i_dentry);
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("%s delete ino %lu blk %lu\n",
++				   tsk->comm, inode->i_ino, blocks);
++
++			iput(inode);
++
++			spin_lock(&sbi->s_delete_lock);
++			sbi->s_delete_blocks -= blocks;
++			sbi->s_delete_inodes--;
++		}
++		if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) {
++			ext3_warning(sb, __FUNCTION__,
++				     "%lu blocks, %lu inodes on list?\n",
++				     sbi->s_delete_blocks,sbi->s_delete_inodes);
++			sbi->s_delete_blocks = 0;
++			sbi->s_delete_inodes = 0;
++		}
++		spin_unlock(&sbi->s_delete_lock);
++		wake_up(&sbi->s_delete_waiter_queue);
++	}
++
++	return 0;
++}
++
++static void ext3_start_delete_thread(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	int rc;
++
++	spin_lock_init(&sbi->s_delete_lock);
++	init_waitqueue_head(&sbi->s_delete_thread_queue);
++	init_waitqueue_head(&sbi->s_delete_waiter_queue);
++
++	if (!test_opt(sb, ASYNCDEL))
++		return;
++
++	rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES);
++	if (rc < 0)
++		printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n",
++		       rc);
++	else
++		wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next);
++}
++
++static void ext3_stop_delete_thread(struct ext3_sb_info *sbi)
++{
++	if (sbi->s_delete_list.next == 0)	/* thread never started */
++		return;
++
++	clear_opt(sbi->s_mount_opt, ASYNCDEL);
++	wake_up(&sbi->s_delete_thread_queue);
++	wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++}
++
++/* Instead of playing games with the inode flags, destruction, etc we just
++ * create a new inode locally and put it on a list for the truncate thread.
++ * We need large parts of the inode struct in order to complete the
++ * truncate and unlink, so we may as well just have a real inode to do it.
++ *
++ * If we have any problem deferring the delete, just delete it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++static void ext3_delete_inode_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (is_bad_inode(old_inode)) {
++		clear_inode(old_inode);
++		return;
++	}
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_delete;
++
++	/* We may want to delete the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS)
++		goto out_delete;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_delete;
++	}
++
++	/* We can iget this inode again here, because our caller has unhashed
++	 * old_inode, so new_inode will be in a different inode struct.
++	 *
++	 * We need to ensure that the i_orphan pointers in the other inodes
++	 * point at the new inode copy instead of the old one so the orphan
++	 * list doesn't get corrupted when the old orphan inode is freed.
++	 */
++	down(&sbi->s_orphan_lock);
++
++	sbi->s_mount_state |= EXT3_ORPHAN_FS;
++	new_inode = iget(old_inode->i_sb, old_inode->i_ino);
++	sbi->s_mount_state &= ~EXT3_ORPHAN_FS;
++	if (is_bad_inode(new_inode)) {
++		printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino);
++		iput(new_inode);
++		new_inode = NULL;
++	}
++	if (!new_inode) {
++		up(&sbi->s_orphan_lock);
++		ext3_debug("delete inode %lu directly (bad read)\n",
++			   old_inode->i_ino);
++		goto out_delete;
++	}
++	J_ASSERT(new_inode != old_inode);
++
++	J_ASSERT(!list_empty(&oei->i_orphan));
++
++	nei = EXT3_I(new_inode);
++	/* Ugh.  We need to insert new_inode into the same spot on the list
++	 * as old_inode was, to ensure the in-memory orphan list is still
++	 * in the same order as the on-disk orphan list (badness otherwise).
++	 */
++	nei->i_orphan = oei->i_orphan;
++	nei->i_orphan.next->prev = &nei->i_orphan;
++	nei->i_orphan.prev->next = &nei->i_orphan;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up(&sbi->s_orphan_lock);
++
++	clear_inode(old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_delete:
++	ext3_delete_inode(old_inode);
++}
++#else
++#define ext3_start_delete_thread(sbi) do {} while(0)
++#define ext3_stop_delete_thread(sbi) do {} while(0)
++#endif /* EXT3_DELETE_THREAD */
++
+ void ext3_put_super (struct super_block * sb)
+ {
+ 	struct ext3_sb_info *sbi = EXT3_SB(sb);
+@@ -408,6 +622,7 @@
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+@@ -476,7 +691,11 @@
+ 	write_inode:	ext3_write_inode,	/* BKL not held.  Don't need */
+ 	dirty_inode:	ext3_dirty_inode,	/* BKL not held.  We take it */
+ 	put_inode:	ext3_put_inode,		/* BKL not held.  Don't need */
++#ifdef EXT3_DELETE_THREAD
++	delete_inode:	ext3_delete_inode_thread,/* BKL not held. We take it */
++#else
+ 	delete_inode:	ext3_delete_inode,	/* BKL not held.  We take it */
++#endif
+ 	put_super:	ext3_put_super,		/* BKL held */
+ 	write_super:	ext3_write_super,	/* BKL held */
+ 	sync_fs:	ext3_sync_fs,
+@@ -553,6 +772,13 @@
+ 			clear_opt (*mount_options, POSIX_ACL);
+ 		else
+ #endif
++#ifdef EXT3_DELETE_THREAD
++		if (!strcmp(this_char, "asyncdel"))
++			set_opt(*mount_options, ASYNCDEL);
++		else if (!strcmp(this_char, "noasyncdel"))
++			clear_opt(*mount_options, ASYNCDEL);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -1254,6 +1480,7 @@
+ 	}
+ 
+ 	ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
++	ext3_start_delete_thread(sb);
+ 	/*
+ 	 * akpm: core read_super() calls in here with the superblock locked.
+ 	 * That deadlocks, because orphan cleanup needs to lock the superblock
+@@ -1692,6 +1919,9 @@
+ 	if (!parse_options(data, &tmp, sbi, &tmp, 1))
+ 		return -EINVAL;
+ 
++	if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY))
++		ext3_stop_delete_thread(sbi);
++
+ 	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+ 		ext3_abort(sb, __FUNCTION__, "Abort forced by user");
+ 
+Index: linux-2.4.19.SuSE/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/inode.c	Sun Nov 16 01:02:56 2003
++++ linux-2.4.19.SuSE/fs/ext3/inode.c	Sun Nov 16 01:19:22 2003
+@@ -2114,6 +2114,118 @@
+ 	ext3_journal_stop(handle, inode);
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/* Move blocks from to-be-truncated inode over to a new inode, and delete
++ * that one from the delete thread instead.  This avoids a lot of latency
++ * when truncating large files.
++ *
++ * If we have any problem deferring the truncate, just truncate it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++void ext3_truncate_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	handle_t *handle;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_truncate;
++
++	/* XXX This is a temporary limitation for code simplicity.
++	 *     We could truncate to arbitrary sizes at some later time.
++	 */
++	if (old_inode->i_size != 0)
++		goto out_truncate;
++
++	/* We may want to truncate the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
++	    old_inode->i_size > oei->i_disksize)
++		goto out_truncate;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_truncate;
++	}
++
++	ext3_discard_prealloc(old_inode);
++
++	/* old_inode   = 1
++	 * new_inode   = sb + GDT + ibitmap
++	 * orphan list = 1 inode/superblock for add, 2 inodes for del
++	 * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
++	 */
++	handle = ext3_journal_start(old_inode, 7);
++	if (IS_ERR(handle))
++		goto out_truncate;
++
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++	if (IS_ERR(new_inode)) {
++		ext3_debug("truncate inode %lu directly (no new inodes)\n",
++			   old_inode->i_ino);
++		goto out_journal;
++	}
++
++	nei = EXT3_I(new_inode);
++
++	down_write(&oei->truncate_sem);
++	new_inode->i_size = old_inode->i_size;
++	new_inode->i_blocks = old_inode->i_blocks;
++	new_inode->i_uid = old_inode->i_uid;
++	new_inode->i_gid = old_inode->i_gid;
++	new_inode->i_nlink = 0;
++
++	/* FIXME when we do arbitrary truncates */
++	old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
++	old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
++
++	memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
++	memset(oei->i_data, 0, sizeof(oei->i_data));
++
++	nei->i_disksize = oei->i_disksize;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up_write(&oei->truncate_sem);
++
++	if (ext3_orphan_add(handle, new_inode) < 0)
++		goto out_journal;
++
++	if (ext3_orphan_del(handle, old_inode) < 0) {
++		ext3_orphan_del(handle, new_inode);
++		iput(new_inode);
++		goto out_journal;
++	}
++
++	ext3_journal_stop(handle, old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_journal:
++	ext3_journal_stop(handle, old_inode);
++out_truncate:
++	ext3_truncate(old_inode);
++}
++#endif /* EXT3_DELETE_THREAD */
++
+ /* 
+  * ext3_get_inode_loc returns with an extra refcount against the
+  * inode's underlying buffer_head on success. 
+Index: linux-2.4.19.SuSE/fs/ext3/file.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/file.c	Sun Nov 16 00:40:59 2003
++++ linux-2.4.19.SuSE/fs/ext3/file.c	Sun Nov 16 01:19:22 2003
+@@ -132,7 +132,11 @@
+ };
+ 
+ struct inode_operations ext3_file_inode_operations = {
++#ifdef EXT3_DELETE_THREAD
++	truncate:	ext3_truncate_thread,	/* BKL held */
++#else
+ 	truncate:	ext3_truncate,		/* BKL held */
++#endif
+ 	setattr:	ext3_setattr,		/* BKL held */
+ 	setxattr:	ext3_setxattr,		/* BKL held */
+ 	getxattr:	ext3_getxattr,		/* BKL held */
+Index: linux-2.4.19.SuSE/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/ext3_fs.h	Sun Nov 16 01:02:51 2003
++++ linux-2.4.19.SuSE/include/linux/ext3_fs.h	Sun Nov 16 01:20:06 2003
+@@ -193,6 +193,7 @@
+  */
+ #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
+ #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
++#define EXT3_STATE_DELETE		0x00000010 /* deferred delete inode */
+ 
+ /*
+  * ioctl commands
+@@ -321,6 +322,7 @@
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ #define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
++#define EXT3_MOUNT_ASYNCDEL		0x20000 /* Delayed deletion */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -695,6 +697,9 @@
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++#ifdef EXT3_DELETE_THREAD
++extern void ext3_truncate_thread(struct inode *inode);
++#endif
+ 
+ /* ioctl.c */
+ extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
+Index: linux-2.4.19.SuSE/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/ext3_fs_sb.h	Sun Nov 16 01:18:41 2003
++++ linux-2.4.19.SuSE/include/linux/ext3_fs_sb.h	Sun Nov 16 01:19:22 2003
+@@ -29,6 +29,8 @@
+ 
+ #define EXT3_MAX_GROUP_LOADED	8
+ 
++#define EXT3_DELETE_THREAD
++
+ /*
+  * third extended-fs super-block data in memory
+  */
+@@ -75,6 +77,14 @@
+ 	struct timer_list turn_ro_timer;	/* For turning read-only (crash simulation) */
+ 	wait_queue_head_t ro_wait_queue;	/* For people waiting for the fs to go read-only */
+ #endif
++#ifdef EXT3_DELETE_THREAD
++	spinlock_t s_delete_lock;
++	struct list_head s_delete_list;
++	unsigned long s_delete_blocks;
++	unsigned long s_delete_inodes;
++	wait_queue_head_t s_delete_thread_queue;
++	wait_queue_head_t s_delete_waiter_queue;
++#endif
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch b/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..083e02860f13ce5c686bd7cb89d351ad09a46959
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch
@@ -0,0 +1,481 @@
+ fs/ext3/file.c             |    4 
+ fs/ext3/inode.c            |  116 ++++++++++++++++++++++
+ fs/ext3/super.c            |  230 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_fs.h    |    5 
+ include/linux/ext3_fs_sb.h |   10 +
+ 5 files changed, 365 insertions(+)
+
+Index: linux-2.4.21-suse/fs/ext3/super.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/super.c	2003-10-30 02:03:04.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/super.c	2003-10-30 02:05:38.000000000 +0300
+@@ -400,6 +400,220 @@
+ 	}
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/*
++ * Delete inodes in a loop until there are no more to be deleted.
++ * Normally, we run in the background doing the deletes and sleeping again,
++ * and clients just add new inodes to be deleted onto the end of the list.
++ * If someone is concerned about free space (e.g. block allocation or similar)
++ * then they can sleep on s_delete_waiter_queue and be woken up when space
++ * has been freed.
++ */
++int ext3_delete_thread(void *data)
++{
++	struct super_block *sb = data;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	struct task_struct *tsk = current;
++
++	/* Almost like daemonize, but not quite */
++	exit_mm(current);
++	tsk->session = 1;
++	tsk->pgrp = 1;
++	tsk->tty = NULL;
++	exit_files(current);
++	reparent_to_init();
++
++	sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev));
++	sigfillset(&tsk->blocked);
++
++	/*tsk->flags |= PF_KERNTHREAD;*/
++
++	INIT_LIST_HEAD(&sbi->s_delete_list);
++	wake_up(&sbi->s_delete_waiter_queue);
++	ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev));
++
++	/* main loop */
++	for (;;) {
++		wait_event_interruptible(sbi->s_delete_thread_queue,
++					 !list_empty(&sbi->s_delete_list) ||
++					 !test_opt(sb, ASYNCDEL));
++		ext3_debug("%s woken up: %lu inodes, %lu blocks\n",
++			   tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks);
++
++		spin_lock(&sbi->s_delete_lock);
++		if (list_empty(&sbi->s_delete_list)) {
++			clear_opt(sbi->s_mount_opt, ASYNCDEL);
++			memset(&sbi->s_delete_list, 0,
++			       sizeof(sbi->s_delete_list));
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("delete thread on %s exiting\n",
++				   kdevname(sb->s_dev));
++			wake_up(&sbi->s_delete_waiter_queue);
++			break;
++		}
++
++		while (!list_empty(&sbi->s_delete_list)) {
++			struct inode *inode=list_entry(sbi->s_delete_list.next,
++						       struct inode, i_dentry);
++			unsigned long blocks = inode->i_blocks >>
++							(inode->i_blkbits - 9);
++
++			list_del_init(&inode->i_dentry);
++			spin_unlock(&sbi->s_delete_lock);
++			ext3_debug("%s delete ino %lu blk %lu\n",
++				   tsk->comm, inode->i_ino, blocks);
++
++			iput(inode);
++
++			spin_lock(&sbi->s_delete_lock);
++			sbi->s_delete_blocks -= blocks;
++			sbi->s_delete_inodes--;
++		}
++		if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) {
++			ext3_warning(sb, __FUNCTION__,
++				     "%lu blocks, %lu inodes on list?\n",
++				     sbi->s_delete_blocks,sbi->s_delete_inodes);
++			sbi->s_delete_blocks = 0;
++			sbi->s_delete_inodes = 0;
++		}
++		spin_unlock(&sbi->s_delete_lock);
++		wake_up(&sbi->s_delete_waiter_queue);
++	}
++
++	return 0;
++}
++
++static void ext3_start_delete_thread(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++	int rc;
++
++	spin_lock_init(&sbi->s_delete_lock);
++	init_waitqueue_head(&sbi->s_delete_thread_queue);
++	init_waitqueue_head(&sbi->s_delete_waiter_queue);
++
++	if (!test_opt(sb, ASYNCDEL))
++		return;
++
++	rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES);
++	if (rc < 0)
++		printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n",
++		       rc);
++	else
++		wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next);
++}
++
++static void ext3_stop_delete_thread(struct ext3_sb_info *sbi)
++{
++	if (sbi->s_delete_list.next == 0)	/* thread never started */
++		return;
++
++	clear_opt(sbi->s_mount_opt, ASYNCDEL);
++	wake_up(&sbi->s_delete_thread_queue);
++	wait_event(sbi->s_delete_waiter_queue, list_empty(&sbi->s_delete_list));
++}
++
++/* Instead of playing games with the inode flags, destruction, etc we just
++ * create a new inode locally and put it on a list for the truncate thread.
++ * We need large parts of the inode struct in order to complete the
++ * truncate and unlink, so we may as well just have a real inode to do it.
++ *
++ * If we have any problem deferring the delete, just delete it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++static void ext3_delete_inode_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (is_bad_inode(old_inode)) {
++		clear_inode(old_inode);
++		return;
++	}
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_delete;
++
++	/* We may want to delete the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS)
++		goto out_delete;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_delete;
++	}
++
++	/* We can iget this inode again here, because our caller has unhashed
++	 * old_inode, so new_inode will be in a different inode struct.
++	 *
++	 * We need to ensure that the i_orphan pointers in the other inodes
++	 * point at the new inode copy instead of the old one so the orphan
++	 * list doesn't get corrupted when the old orphan inode is freed.
++	 */
++	down(&sbi->s_orphan_lock);
++
++	sbi->s_mount_state |= EXT3_ORPHAN_FS;
++	new_inode = iget(old_inode->i_sb, old_inode->i_ino);
++	sbi->s_mount_state &= ~EXT3_ORPHAN_FS;
++	if (is_bad_inode(new_inode)) {
++		printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino);
++		iput(new_inode);
++		new_inode = NULL;
++	}
++	if (!new_inode) {
++		up(&sbi->s_orphan_lock);
++		ext3_debug("delete inode %lu directly (bad read)\n",
++			   old_inode->i_ino);
++		goto out_delete;
++	}
++	J_ASSERT(new_inode != old_inode);
++
++	J_ASSERT(!list_empty(&oei->i_orphan));
++
++	nei = EXT3_I(new_inode);
++	/* Ugh.  We need to insert new_inode into the same spot on the list
++	 * as old_inode was, to ensure the in-memory orphan list is still
++	 * in the same order as the on-disk orphan list (badness otherwise).
++	 */
++	nei->i_orphan = oei->i_orphan;
++	nei->i_orphan.next->prev = &nei->i_orphan;
++	nei->i_orphan.prev->next = &nei->i_orphan;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up(&sbi->s_orphan_lock);
++
++	clear_inode(old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_delete:
++	ext3_delete_inode(old_inode);
++}
++#else
++#define ext3_start_delete_thread(sbi) do {} while(0)
++#define ext3_stop_delete_thread(sbi) do {} while(0)
++#endif /* EXT3_DELETE_THREAD */
++
+ void ext3_put_super (struct super_block * sb)
+ {
+ 	struct ext3_sb_info *sbi = EXT3_SB(sb);
+@@ -407,6 +621,7 @@
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+@@ -455,7 +670,11 @@
+ 	write_inode:	ext3_write_inode,	/* BKL not held.  Don't need */
+ 	dirty_inode:	ext3_dirty_inode,	/* BKL not held.  We take it */
+ 	put_inode:	ext3_put_inode,		/* BKL not held.  Don't need */
++#ifdef EXT3_DELETE_THREAD
++	delete_inode:	ext3_delete_inode_thread,/* BKL not held. We take it */
++#else
+ 	delete_inode:	ext3_delete_inode,	/* BKL not held.  We take it */
++#endif
+ 	put_super:	ext3_put_super,		/* BKL held */
+ 	write_super:	ext3_write_super,	/* BKL held */
+ 	sync_fs:	ext3_sync_fs,
+@@ -524,6 +743,13 @@
+ 			clear_opt (*mount_options, XATTR_USER);
+ 		else
+ #endif
++#ifdef EXT3_DELETE_THREAD
++		if (!strcmp(this_char, "asyncdel"))
++			set_opt(*mount_options, ASYNCDEL);
++		else if (!strcmp(this_char, "noasyncdel"))
++			clear_opt(*mount_options, ASYNCDEL);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -1223,6 +1449,7 @@
+ 	}
+ 
+ 	ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
++	ext3_start_delete_thread(sb);
+ 	/*
+ 	 * akpm: core read_super() calls in here with the superblock locked.
+ 	 * That deadlocks, because orphan cleanup needs to lock the superblock
+@@ -1678,6 +1905,9 @@
+ 	if (!parse_options(data, &tmp, sbi, &tmp, 1))
+ 		return -EINVAL;
+ 
++	if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY))
++		ext3_stop_delete_thread(sbi);
++
+ 	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+ 		ext3_abort(sb, __FUNCTION__, "Abort forced by user");
+ 
+Index: linux-2.4.21-suse/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/inode.c	2003-10-30 02:03:57.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/inode.c	2003-10-30 02:05:38.000000000 +0300
+@@ -2552,6 +2552,118 @@
+ 	return err;
+ }
+ 
++#ifdef EXT3_DELETE_THREAD
++/* Move blocks from to-be-truncated inode over to a new inode, and delete
++ * that one from the delete thread instead.  This avoids a lot of latency
++ * when truncating large files.
++ *
++ * If we have any problem deferring the truncate, just truncate it right away.
++ * If we defer it, we also mark how many blocks it would free, so that we
++ * can keep the statfs data correct, and we know if we should sleep on the
++ * delete thread when we run out of space.
++ */
++void ext3_truncate_thread(struct inode *old_inode)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb);
++	struct ext3_inode_info *nei, *oei = EXT3_I(old_inode);
++	struct inode *new_inode;
++	handle_t *handle;
++	unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9);
++
++	if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next)
++		goto out_truncate;
++
++	/* XXX This is a temporary limitation for code simplicity.
++	 *     We could truncate to arbitrary sizes at some later time.
++	 */
++	if (old_inode->i_size != 0)
++		goto out_truncate;
++
++	/* We may want to truncate the inode immediately and not defer it */
++	if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS ||
++	    old_inode->i_size > oei->i_disksize)
++		goto out_truncate;
++
++	/* We can't use the delete thread as-is during real orphan recovery,
++	 * as we add to the orphan list here, causing ext3_orphan_cleanup()
++	 * to loop endlessly.  It would be nice to do so, but needs work.
++	 */
++	if (oei->i_state & EXT3_STATE_DELETE ||
++	    sbi->s_mount_state & EXT3_ORPHAN_FS) {
++		ext3_debug("doing deferred inode %lu delete (%lu blocks)\n",
++			   old_inode->i_ino, blocks);
++		goto out_truncate;
++	}
++
++	ext3_discard_prealloc(old_inode);
++
++	/* old_inode   = 1
++	 * new_inode   = sb + GDT + ibitmap
++	 * orphan list = 1 inode/superblock for add, 2 inodes for del
++	 * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS
++	 */
++	handle = ext3_journal_start(old_inode, 7);
++	if (IS_ERR(handle))
++		goto out_truncate;
++
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++	if (IS_ERR(new_inode)) {
++		ext3_debug("truncate inode %lu directly (no new inodes)\n",
++			   old_inode->i_ino);
++		goto out_journal;
++	}
++
++	nei = EXT3_I(new_inode);
++
++	down_write(&oei->truncate_sem);
++	new_inode->i_size = old_inode->i_size;
++	new_inode->i_blocks = old_inode->i_blocks;
++	new_inode->i_uid = old_inode->i_uid;
++	new_inode->i_gid = old_inode->i_gid;
++	new_inode->i_nlink = 0;
++
++	/* FIXME when we do arbitrary truncates */
++	old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0;
++	old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME;
++
++	memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data));
++	memset(oei->i_data, 0, sizeof(oei->i_data));
++
++	nei->i_disksize = oei->i_disksize;
++	nei->i_state |= EXT3_STATE_DELETE;
++	up_write(&oei->truncate_sem);
++
++	if (ext3_orphan_add(handle, new_inode) < 0)
++		goto out_journal;
++
++	if (ext3_orphan_del(handle, old_inode) < 0) {
++		ext3_orphan_del(handle, new_inode);
++		iput(new_inode);
++		goto out_journal;
++	}
++
++	ext3_journal_stop(handle, old_inode);
++
++	spin_lock(&sbi->s_delete_lock);
++	J_ASSERT(list_empty(&new_inode->i_dentry));
++	list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list);
++	sbi->s_delete_blocks += blocks;
++	sbi->s_delete_inodes++;
++	spin_unlock(&sbi->s_delete_lock);
++
++	ext3_debug("delete inode %lu (%lu blocks) by thread\n",
++		   new_inode->i_ino, blocks);
++
++	wake_up(&sbi->s_delete_thread_queue);
++	return;
++
++out_journal:
++	ext3_journal_stop(handle, old_inode);
++out_truncate:
++	ext3_truncate(old_inode);
++}
++#endif /* EXT3_DELETE_THREAD */
++
+ /* 
+  * On success, We end up with an outstanding reference count against
+  * iloc->bh.  This _must_ be cleaned up later. 
+Index: linux-2.4.21-suse/fs/ext3/file.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/file.c	2003-10-30 01:40:33.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/file.c	2003-10-30 02:05:38.000000000 +0300
+@@ -125,7 +125,11 @@
+ };
+ 
+ struct inode_operations ext3_file_inode_operations = {
++#ifdef EXT3_DELETE_THREAD
++	truncate:	ext3_truncate_thread,	/* BKL held */
++#else
+ 	truncate:	ext3_truncate,		/* BKL held */
++#endif
+ 	setattr:	ext3_setattr,		/* BKL held */
+ 	setxattr:	ext3_setxattr,		/* BKL held */
+ 	getxattr:	ext3_getxattr,		/* BKL held */
+Index: linux-2.4.21-suse/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs.h	2003-10-30 02:03:57.000000000 +0300
++++ linux-2.4.21-suse/include/linux/ext3_fs.h	2003-10-30 02:06:05.000000000 +0300
+@@ -193,6 +193,7 @@
+  */
+ #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
+ #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
++#define EXT3_STATE_DELETE		0x00000010 /* deferred delete inode */
+ 
+ /*
+  * ioctl commands
+@@ -320,6 +321,7 @@
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
++#define EXT3_MOUNT_ASYNCDEL		0x20000 /* Delayed deletion */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -697,6 +699,9 @@
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++#ifdef EXT3_DELETE_THREAD
++extern void ext3_truncate_thread(struct inode *inode);
++#endif
+ extern void ext3_set_inode_flags(struct inode *);
+ 
+ /* ioctl.c */
+Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h	2003-10-30 02:03:04.000000000 +0300
++++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h	2003-10-30 02:05:38.000000000 +0300
+@@ -29,6 +29,8 @@
+ 
+ #define EXT3_MAX_GROUP_LOADED	8
+ 
++#define EXT3_DELETE_THREAD
++
+ /*
+  * third extended-fs super-block data in memory
+  */
+@@ -76,6 +78,14 @@
+ 	struct timer_list turn_ro_timer;	/* For turning read-only (crash simulation) */
+ 	wait_queue_head_t ro_wait_queue;	/* For people waiting for the fs to go read-only */
+ #endif
++#ifdef EXT3_DELETE_THREAD
++	spinlock_t s_delete_lock;
++	struct list_head s_delete_list;
++	unsigned long s_delete_blocks;
++	unsigned long s_delete_inodes;
++	wait_queue_head_t s_delete_thread_queue;
++	wait_queue_head_t s_delete_waiter_queue;
++#endif
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bc6ee7700018c96dfb30077b9287cb02af29fca8
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.18-chaos.patch
@@ -0,0 +1,760 @@
+ fs/ext3/ialloc.c          |    6 
+ fs/ext3/inode.c           |   10 
+ fs/ext3/super.c           |    4 
+ fs/ext3/xattr.c           |  598 +++++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/ext3_fs.h   |    2 
+ include/linux/ext3_fs_i.h |    3 
+ 6 files changed, 613 insertions(+), 10 deletions(-)
+
+--- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c	2003-10-08 15:08:45.000000000 +0400
+@@ -586,6 +586,12 @@ repeat:
+ 	insert_inode_hash(inode);
+ 	inode->i_generation = sbi->s_next_generation++;
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
++		ei->i_extra_isize = sizeof(__u16)	/* i_extra_isize */
++				+ sizeof(__u16);	/* i_pad1 */
++	} else
++		ei->i_extra_isize = 0;
++
+ 	ei->i_state = EXT3_STATE_NEW;
+ 	err = ext3_get_inode_loc_new(inode, &iloc, 1);
+ 	if (err) goto fail;
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c	2003-10-08 15:08:45.000000000 +0400
+@@ -2459,6 +2459,11 @@ void ext3_read_inode(struct inode * inod
+ 		ei->i_data[block] = iloc.raw_inode->i_block[block];
+ 	INIT_LIST_HEAD(&ei->i_orphan);
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
++	else
++		ei->i_extra_isize = 0;
++
+ 	brelse (iloc.bh);
+ 
+ 	if (S_ISREG(inode->i_mode)) {
+@@ -2523,6 +2528,8 @@ static int ext3_do_update_inode(handle_t
+ 		if (err)
+ 			goto out_brelse;
+ 	}
++	if (ei->i_state & EXT3_STATE_NEW)
++		memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); 
+ 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
+ 	if(!(test_opt(inode->i_sb, NO_UID32))) {
+ 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
+@@ -2606,6 +2613,9 @@ static int ext3_do_update_inode(handle_t
+ 	else for (block = 0; block < EXT3_N_BLOCKS; block++)
+ 		raw_inode->i_block[block] = ei->i_data[block];
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
++
+ 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+ 	rc = ext3_journal_dirty_metadata(handle, bh);
+ 	if (!err)
+--- linux-2.4.18-chaos/fs/ext3/xattr.c~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:01.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/xattr.c	2003-10-12 16:16:44.000000000 +0400
+@@ -102,6 +102,9 @@
+ static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
+ 			   struct ext3_xattr_header *);
+ 
++int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,
++			void *, size_t, int);
++
+ #ifdef CONFIG_EXT3_FS_XATTR_SHARING
+ 
+ static int ext3_xattr_cache_insert(struct buffer_head *);
+@@ -362,17 +365,12 @@ ext3_removexattr(struct dentry *dentry, 
+ }
+ 
+ /*
+- * ext3_xattr_get()
+- *
+- * Copy an extended attribute into the buffer
+- * provided, or compute the buffer size required.
+- * Buffer is NULL to compute the size of the buffer required.
++ * ext3_xattr_block_get()
+  *
+- * Returns a negative error number on failure, or the number of bytes
+- * used / required on success.
++ * routine looks for attribute in EA block and returns it's value and size
+  */
+ int
+-ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+ 	       void *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+@@ -461,6 +459,94 @@ cleanup:
+ }
+ 
+ /*
++ * ext3_xattr_ibode_get()
++ *
++ * routine looks for attribute in inode body and returns it's value and size
++ */
++int
++ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	int size, name_len = strlen(name), storage_size;
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOENT;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret)
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len))
++			goto found;
++		last = next;
++	}
++
++	/* can't find EA */
++	brelse(iloc.bh);
++	return -ENOENT;
++	
++found:
++	size = le32_to_cpu(last->e_value_size);
++	if (buffer) {
++		ret = -ERANGE;
++		if (buffer_size >= size) {
++			memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
++			size);
++			ret = size;
++		}
++	} else
++		ret = size;
++	brelse(iloc.bh);
++	return ret;
++}
++
++int ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++			void *buffer, size_t buffer_size)
++{
++	int err;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_get(inode, name_index, name,
++					buffer, buffer_size);
++	if (err < 0) 
++		/* search was unsuccessful, try to find EA in dedicated block */
++		err = ext3_xattr_block_get(inode, name_index, name,
++				buffer, buffer_size);
++	return err;
++}
++
++/*
+  * ext3_xattr_list()
+  *
+  * Copy a list of attribute names into the buffer
+@@ -471,7 +557,7 @@ cleanup:
+  * used / required on success.
+  */
+ int
+-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+ 	struct ext3_xattr_entry *entry;
+@@ -547,6 +633,131 @@ cleanup:
+ 	return error;
+ }
+ 
++/* ext3_xattr_ibody_list()
++ *
++ * generate list of attributes stored in inode body
++ */
++int
++ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	char *start, *end, *buf;
++	struct ext3_iloc iloc;
++	int storage_size;
++	int ret;
++	int size = 0;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return 0;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret) 
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return 0;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++
++	if (!buffer) {
++		ret = size;
++		goto cleanup;
++	} else {
++		ret = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	last = (struct ext3_xattr_entry *) start;
++	buf = buffer;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++	ret = size;
++cleanup:
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	int error;
++	int size = buffer_size;
++
++	/* get list of attributes stored in inode body */
++	error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
++	if (error < 0) {
++		/* some error occured while collecting 
++		 * attributes in inode body */
++		size = 0;
++		goto cleanup;
++	}
++	size = error;
++
++	/* get list of attributes stored in dedicated block */
++	if (buffer) {
++		buffer_size -= error;
++		if (buffer_size <= 0) {
++			buffer = NULL;
++			buffer_size = 0;
++		} else 
++			buffer += error;
++	}
++
++	error = ext3_xattr_block_list(inode, buffer, buffer_size);
++	if (error < 0) 
++		/* listing was successful, so we return len */
++		size = 0;
++
++cleanup:
++	return error + size;
++}
++
+ /*
+  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+  * not set, set it.
+@@ -570,6 +781,279 @@ static void ext3_xattr_update_super_bloc
+ }
+ 
+ /*
++ * ext3_xattr_ibody_find()
++ *
++ * search attribute and calculate free space in inode body
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_ibody_find(struct inode *inode, int name_index, 
++		const char *name, struct ext3_xattr_entry *rentry, int *free)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return ret;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err) 
++		return -EIO;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	*free = storage_size - sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len)) {
++			memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
++			ret = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(last->e_name_len);
++			*free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++	
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_block_find()
++ *
++ * search attribute and calculate free space in EA block (if it allocated)
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
++	       struct ext3_xattr_entry *rentry, int *free)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	char *end;
++	int name_len, error = -ENOENT;
++
++	if (!EXT3_I(inode)->i_file_acl) {
++		*free = inode->i_sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) -
++			sizeof(__u32);
++		return -ENOENT;
++	}
++	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
++	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino,
++			EXT3_I(inode)->i_file_acl);
++		brelse(bh);
++		return -EIO;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++	*free = bh->b_size - sizeof(__u32);
++
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0) {
++			memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
++			error = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(entry->e_name_len);
++			*free -= le32_to_cpu(entry->e_value_size);
++		}
++		entry = next;
++	}
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_inode_set()
++ * 
++ * this routine add/remove/replace attribute in inode body
++ */
++int
++ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
++		      const char *name, const void *value, size_t value_len,
++		      int flags)
++{
++	struct ext3_xattr_entry *last, *next, *here = NULL;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int esize = EXT3_XATTR_LEN(name_len);
++	struct buffer_head *bh;
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	int free, min_offs;
++	char *start, *end;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOSPC;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err)
++		return err;
++	raw_inode = iloc.raw_inode;
++	bh = iloc.bh;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
++		/* inode had no attributes before */
++		*((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++	min_offs = storage_size;
++	free = storage_size - sizeof(__u32);
++
++	last = (struct ext3_xattr_entry *) start;	
++	while (!IS_LAST_ENTRY(last)) {
++		next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
++				"inode %ld", inode->i_ino);
++			brelse(bh);
++			return -EIO;
++		}
++		
++		if (last->e_value_size) {
++			int offs = le16_to_cpu(last->e_value_offs);
++			if (offs < min_offs)
++				min_offs = offs;
++		}
++		if (name_index == last->e_name_index &&
++			name_len == last->e_name_len &&
++			!memcmp(name, last->e_name, name_len)) 
++			here = last;
++		else {
++			/* we calculate all but our attribute
++			 * because it will be removed before changing */
++			free -= EXT3_XATTR_LEN(last->e_name_len);
++			free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++
++	if (value && (esize + value_len > free)) {
++		brelse(bh);
++		return -ENOSPC;
++	}
++	
++	err = ext3_reserve_inode_write(handle, inode, &iloc);
++	if (err) {
++		brelse(bh);	
++		return err;
++	}
++
++	if (here) {
++		/* time to remove old value */
++		struct ext3_xattr_entry *e;
++		int size = le32_to_cpu(here->e_value_size);
++		int border = le16_to_cpu(here->e_value_offs);
++		char *src;
++
++		/* move tail */
++		memmove(start + min_offs + size, start + min_offs,
++				border - min_offs);
++
++		/* recalculate offsets */
++		e = (struct ext3_xattr_entry *) start;
++		while (!IS_LAST_ENTRY(e)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
++			int offs = le16_to_cpu(e->e_value_offs); 
++			if (offs < border) 
++				e->e_value_offs = 
++					cpu_to_le16(offs + size);
++			e = next;
++		}
++		min_offs += size;
++
++		/* remove entry */
++		border = EXT3_XATTR_LEN(here->e_name_len);
++		src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
++		size = (char *) last - src;
++		if ((char *) here + size > end)
++			printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
++					__FILE__, __LINE__, here, size, end);
++		memmove(here, src, size);
++		last = (struct ext3_xattr_entry *) ((char *) last - border);
++		*((__u32 *) last) = 0;
++	}
++	
++	if (value) {
++		int offs = min_offs - value_len;
++		/* use last to create new entry */
++		last->e_name_len = strlen(name);
++		last->e_name_index = name_index;
++		last->e_value_offs = cpu_to_le16(offs);
++		last->e_value_size = cpu_to_le32(value_len);
++		last->e_hash = last->e_value_block = 0;
++		memset(last->e_name, 0, esize);
++		memcpy(last->e_name, name, last->e_name_len);
++		if (start + offs + value_len > end)
++			printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n",
++					__FILE__, __LINE__, start, offs,
++					value_len, end);
++		memcpy(start + offs, value, value_len);
++		last = EXT3_XATTR_NEXT(last);
++		*((__u32 *) last) = 0;
++	}
++	
++	ext3_mark_iloc_dirty(handle, inode, &iloc);
++	brelse(bh);
++
++	return 0;
++}
++
++/*
+  * ext3_xattr_set()
+  *
+  * Create, replace or remove an extended attribute for this inode. Buffer
+@@ -583,6 +1067,100 @@ static void ext3_xattr_update_super_bloc
+  */
+ int
+ ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++		const char *name, void *value, size_t value_len, int flags)
++{
++	struct ext3_xattr_entry entry;
++	int err, where = 0, found = 0, total;
++	int free1 = -1, free2 = -1;
++	int name_len;
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
++		return -ERANGE;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
++	if (err == 0) {
++		/* found EA in inode */
++		found = 1;
++		where = 0;
++	} else if (err == -ENOENT) {
++		/* there is no such attribute in inode body */
++		/* try to find attribute in dedicated block */
++		err = ext3_xattr_block_find(inode, name_index, name,
++						&entry, &free2);
++		if (err != 0 && err != -ENOENT) {
++			/* not found EA in block */
++			goto finish;	
++		}
++		/* found EA in block */
++		where = 1;
++		found = 1;
++	} else
++		goto finish;
++
++	/* check flags: may replace? may create ? */
++	if (found && (flags & XATTR_CREATE)) {
++		err = -EEXIST;
++		goto finish;
++	} else if (!found && (flags & XATTR_REPLACE)) {
++		err = -ENODATA;
++		goto finish;
++	}
++
++	/* check if we have enough space to store attribute */
++	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
++	if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) {
++		/* have no enough space */
++		err = -ENOSPC;
++		goto finish;
++	}
++	
++	/* time to remove attribute */
++	if (found) {
++		if (where == 0) {
++			/* EA is stored in inode body */
++			ext3_xattr_ibody_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		} else {
++			/* EA is stored in separated block */
++			ext3_xattr_block_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		}
++	}
++
++	/* try to store EA in inode body */
++	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
++				value, value_len, flags);
++	if (err) {
++		/* can't store EA in inode body */
++		/* try to store in block */
++		err = ext3_xattr_block_set(handle, inode, name_index,
++					name, value, value_len, flags);	
++	}
++
++finish:	
++	return err;
++}
++
++/*
++ * ext3_xattr_block_set()
++ * 
++ * this routine add/remove/replace attribute in EA block
++ */
++int
++ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
+ 	       const char *name, void *value, size_t value_len, int flags)
+ {
+ 	struct super_block *sb = inode->i_sb;
+@@ -619,6 +1197,7 @@ ext3_xattr_set(handle_t *handle, struct 
+ 	name_len = strlen(name);
+ 	if (name_len > 255 || value_len > sb->s_blocksize)
+ 		return -ERANGE;
++
+ 	ext3_xattr_lock();
+ 
+ 	if (EXT3_I(inode)->i_file_acl) {
+@@ -819,6 +1398,7 @@ cleanup:
+ 	brelse(bh);
+ 	if (!(bh && header == HDR(bh)))
+ 		kfree(header);
++
+ 	ext3_xattr_unlock();
+ 
+ 	return error;
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h	2003-10-08 15:08:45.000000000 +0400
+@@ -264,6 +264,8 @@ struct ext3_inode {
+ 			__u32	m_i_reserved2[2];
+ 		} masix2;
+ 	} osd2;				/* OS dependent 2 */
++	__u16	i_extra_isize;
++	__u16	i_pad1;
+ };
+ 
+ #define i_size_high	i_dir_acl
+--- linux-2.4.18-chaos/include/linux/ext3_fs_i.h~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_i.h	2003-10-08 15:08:45.000000000 +0400
+@@ -62,6 +62,9 @@ struct ext3_inode_info {
+ 	 */
+ 	loff_t	i_disksize;
+ 
++	/* on-disk additional lenght */
++	__u16 i_extra_isize;
++
+ 	/*
+ 	 * truncate_sem is for serialising ext3_truncate() against
+ 	 * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-ea-in-inode-2.4.18-chaos	2003-10-08 10:38:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c	2003-10-08 15:08:45.000000000 +0400
+@@ -1292,7 +1292,9 @@ struct super_block * ext3_read_super (st
+ 	} else {
+ 		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+ 		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+-		if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) {
++		if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
++		    (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
++		    (sbi->s_inode_size > blocksize)) {
+ 			printk (KERN_ERR
+ 				"EXT3-fs: unsupported inode size: %d\n",
+ 				sbi->s_inode_size);
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cd569f4a967e72bd2078732c9a96817ed433ad69
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.20.patch
@@ -0,0 +1,748 @@
+ fs/ext3/ialloc.c          |    6 
+ fs/ext3/inode.c           |   12 
+ fs/ext3/super.c           |    6 
+ fs/ext3/xattr.c           |  597 +++++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/ext3_fs.h   |    2 
+ include/linux/ext3_fs_i.h |    3 
+ 6 files changed, 615 insertions(+), 11 deletions(-)
+
+--- linux-2.4.20/fs/ext3/ialloc.c~ext3-ea-in-inode-2.4.20	2003-10-08 23:18:08.000000000 +0400
++++ linux-2.4.20-alexey/fs/ext3/ialloc.c	2003-10-12 16:25:21.000000000 +0400
+@@ -577,6 +577,12 @@ repeat:
+ 	insert_inode_hash(inode);
+ 	inode->i_generation = sb->u.ext3_sb.s_next_generation++;
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
++		inode->u.ext3_i.i_extra_isize = sizeof(__u16)	/* i_extra_isize */
++				+ sizeof(__u16);	/* i_pad1 */
++	} else
++		inode->u.ext3_i.i_extra_isize = 0;
++
+ 	inode->u.ext3_i.i_state = EXT3_STATE_NEW;
+  	err = ext3_get_inode_loc_new(inode, &iloc, 1);
+   	if (err) goto fail;
+--- linux-2.4.20/fs/ext3/inode.c~ext3-ea-in-inode-2.4.20	2003-10-08 23:18:08.000000000 +0400
++++ linux-2.4.20-alexey/fs/ext3/inode.c	2003-10-12 16:25:21.000000000 +0400
+@@ -2209,6 +2209,12 @@ void ext3_read_inode(struct inode * inod
+ 		inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
+ 	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		inode->u.ext3_i.i_extra_isize =
++			le16_to_cpu(raw_inode->i_extra_isize);
++	else
++		inode->u.ext3_i.i_extra_isize = 0;
++
+ 	brelse (iloc.bh);
+ 
+ 	if (S_ISREG(inode->i_mode)) {
+@@ -2274,6 +2280,8 @@ static int ext3_do_update_inode(handle_t
+ 		if (err)
+ 			goto out_brelse;
+ 	}
++	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW)
++		memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); 
+ 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
+ 	if(!(test_opt(inode->i_sb, NO_UID32))) {
+ 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
+@@ -2357,6 +2365,10 @@ static int ext3_do_update_inode(handle_t
+ 	else for (block = 0; block < EXT3_N_BLOCKS; block++)
+ 		raw_inode->i_block[block] = inode->u.ext3_i.i_data[block];
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		raw_inode->i_extra_isize =
++			cpu_to_le16(EXT3_I(inode)->i_extra_isize);
++
+ 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+ 	rc = ext3_journal_dirty_metadata(handle, bh);
+ 	if (!err)
+--- linux-2.4.20/fs/ext3/xattr.c~ext3-ea-in-inode-2.4.20	2003-10-08 23:18:06.000000000 +0400
++++ linux-2.4.20-alexey/fs/ext3/xattr.c	2003-10-12 16:26:31.000000000 +0400
+@@ -100,6 +100,9 @@
+ static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
+ 			   struct ext3_xattr_header *);
+ 
++int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,
++			const void *, size_t, int);
++
+ #ifdef CONFIG_EXT3_FS_XATTR_SHARING
+ 
+ static int ext3_xattr_cache_insert(struct buffer_head *);
+@@ -348,17 +351,12 @@ ext3_removexattr(struct dentry *dentry, 
+ }
+ 
+ /*
+- * ext3_xattr_get()
+- *
+- * Copy an extended attribute into the buffer
+- * provided, or compute the buffer size required.
+- * Buffer is NULL to compute the size of the buffer required.
++ * ext3_xattr_block_get()
+  *
+- * Returns a negative error number on failure, or the number of bytes
+- * used / required on success.
++ * routine looks for attribute in EA block and returns it's value and size
+  */
+ int
+-ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+ 	       void *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+@@ -447,6 +445,94 @@ cleanup:
+ }
+ 
+ /*
++ * ext3_xattr_ibode_get()
++ *
++ * routine looks for attribute in inode body and returns it's value and size
++ */
++int
++ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	int size, name_len = strlen(name), storage_size;
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOENT;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret)
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len))
++			goto found;
++		last = next;
++	}
++
++	/* can't find EA */
++	brelse(iloc.bh);
++	return -ENOENT;
++	
++found:
++	size = le32_to_cpu(last->e_value_size);
++	if (buffer) {
++		ret = -ERANGE;
++		if (buffer_size >= size) {
++			memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
++			size);
++			ret = size;
++		}
++	} else
++		ret = size;
++	brelse(iloc.bh);
++	return ret;
++}
++
++int ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++			void *buffer, size_t buffer_size)
++{
++	int err;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_get(inode, name_index, name,
++					buffer, buffer_size);
++	if (err < 0) 
++		/* search was unsuccessful, try to find EA in dedicated block */
++		err = ext3_xattr_block_get(inode, name_index, name,
++				buffer, buffer_size);
++	return err;
++}
++
++/*
+  * ext3_xattr_list()
+  *
+  * Copy a list of attribute names into the buffer
+@@ -457,7 +543,7 @@ cleanup:
+  * used / required on success.
+  */
+ int
+-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+ 	struct ext3_xattr_entry *entry;
+@@ -530,6 +616,131 @@ cleanup:
+ 	return error;
+ }
+ 
++/* ext3_xattr_ibody_list()
++ *
++ * generate list of attributes stored in inode body
++ */
++int
++ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	char *start, *end, *buf;
++	struct ext3_iloc iloc;
++	int storage_size;
++	int ret;
++	int size = 0;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return 0;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret) 
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return 0;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++
++	if (!buffer) {
++		ret = size;
++		goto cleanup;
++	} else {
++		ret = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	last = (struct ext3_xattr_entry *) start;
++	buf = buffer;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++	ret = size;
++cleanup:
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	int error;
++	int size = buffer_size;
++
++	/* get list of attributes stored in inode body */
++	error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
++	if (error < 0) {
++		/* some error occured while collecting 
++		 * attributes in inode body */
++		size = 0;
++		goto cleanup;
++	}
++	size = error;
++
++	/* get list of attributes stored in dedicated block */
++	if (buffer) {
++		buffer_size -= error;
++		if (buffer_size <= 0) {
++			buffer = NULL;
++			buffer_size = 0;
++		} else 
++			buffer += error;
++	}
++
++	error = ext3_xattr_block_list(inode, buffer, buffer_size);
++	if (error < 0) 
++		/* listing was successful, so we return len */
++		size = 0;
++
++cleanup:
++	return error + size;
++}
++
+ /*
+  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+  * not set, set it.
+@@ -553,6 +764,279 @@ static void ext3_xattr_update_super_bloc
+ }
+ 
+ /*
++ * ext3_xattr_ibody_find()
++ *
++ * search attribute and calculate free space in inode body
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_ibody_find(struct inode *inode, int name_index, 
++		const char *name, struct ext3_xattr_entry *rentry, int *free)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return ret;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err) 
++		return -EIO;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	*free = storage_size - sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len)) {
++			memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
++			ret = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(last->e_name_len);
++			*free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++	
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_block_find()
++ *
++ * search attribute and calculate free space in EA block (if it allocated)
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
++	       struct ext3_xattr_entry *rentry, int *free)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	char *end;
++	int name_len, error = -ENOENT;
++
++	if (!EXT3_I(inode)->i_file_acl) {
++		*free = inode->i_sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) -
++			sizeof(__u32);
++		return -ENOENT;
++	}
++	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
++	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino,
++			EXT3_I(inode)->i_file_acl);
++		brelse(bh);
++		return -EIO;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++	*free = bh->b_size - sizeof(__u32);
++
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0) {
++			memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
++			error = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(entry->e_name_len);
++			*free -= le32_to_cpu(entry->e_value_size);
++		}
++		entry = next;
++	}
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_inode_set()
++ * 
++ * this routine add/remove/replace attribute in inode body
++ */
++int
++ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
++		      const char *name, const void *value, size_t value_len,
++		      int flags)
++{
++	struct ext3_xattr_entry *last, *next, *here = NULL;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int esize = EXT3_XATTR_LEN(name_len);
++	struct buffer_head *bh;
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	int free, min_offs;
++	char *start, *end;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOSPC;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err)
++		return err;
++	raw_inode = iloc.raw_inode;
++	bh = iloc.bh;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
++		/* inode had no attributes before */
++		*((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++	min_offs = storage_size;
++	free = storage_size - sizeof(__u32);
++
++	last = (struct ext3_xattr_entry *) start;	
++	while (!IS_LAST_ENTRY(last)) {
++		next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
++				"inode %ld", inode->i_ino);
++			brelse(bh);
++			return -EIO;
++		}
++		
++		if (last->e_value_size) {
++			int offs = le16_to_cpu(last->e_value_offs);
++			if (offs < min_offs)
++				min_offs = offs;
++		}
++		if (name_index == last->e_name_index &&
++			name_len == last->e_name_len &&
++			!memcmp(name, last->e_name, name_len)) 
++			here = last;
++		else {
++			/* we calculate all but our attribute
++			 * because it will be removed before changing */
++			free -= EXT3_XATTR_LEN(last->e_name_len);
++			free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++
++	if (value && (esize + value_len > free)) {
++		brelse(bh);
++		return -ENOSPC;
++	}
++	
++	err = ext3_reserve_inode_write(handle, inode, &iloc);
++	if (err) {
++		brelse(bh);	
++		return err;
++	}
++
++	if (here) {
++		/* time to remove old value */
++		struct ext3_xattr_entry *e;
++		int size = le32_to_cpu(here->e_value_size);
++		int border = le16_to_cpu(here->e_value_offs);
++		char *src;
++
++		/* move tail */
++		memmove(start + min_offs + size, start + min_offs,
++				border - min_offs);
++
++		/* recalculate offsets */
++		e = (struct ext3_xattr_entry *) start;
++		while (!IS_LAST_ENTRY(e)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
++			int offs = le16_to_cpu(e->e_value_offs); 
++			if (offs < border) 
++				e->e_value_offs = 
++					cpu_to_le16(offs + size);
++			e = next;
++		}
++		min_offs += size;
++
++		/* remove entry */
++		border = EXT3_XATTR_LEN(here->e_name_len);
++		src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
++		size = (char *) last - src;
++		if ((char *) here + size > end)
++			printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
++					__FILE__, __LINE__, here, size, end);
++		memmove(here, src, size);
++		last = (struct ext3_xattr_entry *) ((char *) last - border);
++		*((__u32 *) last) = 0;
++	}
++	
++	if (value) {
++		int offs = min_offs - value_len;
++		/* use last to create new entry */
++		last->e_name_len = strlen(name);
++		last->e_name_index = name_index;
++		last->e_value_offs = cpu_to_le16(offs);
++		last->e_value_size = cpu_to_le32(value_len);
++		last->e_hash = last->e_value_block = 0;
++		memset(last->e_name, 0, esize);
++		memcpy(last->e_name, name, last->e_name_len);
++		if (start + offs + value_len > end)
++			printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n",
++					__FILE__, __LINE__, start, offs,
++					value_len, end);
++		memcpy(start + offs, value, value_len);
++		last = EXT3_XATTR_NEXT(last);
++		*((__u32 *) last) = 0;
++	}
++	
++	ext3_mark_iloc_dirty(handle, inode, &iloc);
++	brelse(bh);
++
++	return 0;
++}
++
++/*
+  * ext3_xattr_set()
+  *
+  * Create, replace or remove an extended attribute for this inode. Buffer
+@@ -566,6 +1050,100 @@ static void ext3_xattr_update_super_bloc
+  */
+ int
+ ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++		const char *name, const void *value, size_t value_len, int flags)
++{
++	struct ext3_xattr_entry entry;
++	int err, where = 0, found = 0, total;
++	int free1 = -1, free2 = -1;
++	int name_len;
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
++		return -ERANGE;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
++	if (err == 0) {
++		/* found EA in inode */
++		found = 1;
++		where = 0;
++	} else if (err == -ENOENT) {
++		/* there is no such attribute in inode body */
++		/* try to find attribute in dedicated block */
++		err = ext3_xattr_block_find(inode, name_index, name,
++						&entry, &free2);
++		if (err != 0 && err != -ENOENT) {
++			/* not found EA in block */
++			goto finish;	
++		}
++		/* found EA in block */
++		where = 1;
++		found = 1;
++	} else
++		goto finish;
++
++	/* check flags: may replace? may create ? */
++	if (found && (flags & XATTR_CREATE)) {
++		err = -EEXIST;
++		goto finish;
++	} else if (!found && (flags & XATTR_REPLACE)) {
++		err = -ENODATA;
++		goto finish;
++	}
++
++	/* check if we have enough space to store attribute */
++	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
++	if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) {
++		/* have no enough space */
++		err = -ENOSPC;
++		goto finish;
++	}
++	
++	/* time to remove attribute */
++	if (found) {
++		if (where == 0) {
++			/* EA is stored in inode body */
++			ext3_xattr_ibody_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		} else {
++			/* EA is stored in separated block */
++			ext3_xattr_block_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		}
++	}
++
++	/* try to store EA in inode body */
++	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
++				value, value_len, flags);
++	if (err) {
++		/* can't store EA in inode body */
++		/* try to store in block */
++		err = ext3_xattr_block_set(handle, inode, name_index,
++					name, value, value_len, flags);	
++	}
++
++finish:	
++	return err;
++}
++
++/*
++ * ext3_xattr_block_set()
++ * 
++ * this routine add/remove/replace attribute in EA block
++ */
++int
++ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
+ 	       const char *name, const void *value, size_t value_len, int flags)
+ {
+ 	struct super_block *sb = inode->i_sb;
+--- linux-2.4.20/include/linux/ext3_fs.h~ext3-ea-in-inode-2.4.20	2003-10-08 23:18:08.000000000 +0400
++++ linux-2.4.20-alexey/include/linux/ext3_fs.h	2003-10-12 16:35:46.000000000 +0400
+@@ -264,6 +264,8 @@ struct ext3_inode {
+ 			__u32	m_i_reserved2[2];
+ 		} masix2;
+ 	} osd2;				/* OS dependent 2 */
++	__u16	i_extra_isize;
++	__u16	i_pad1;
+ };
+ 
+ #define i_size_high	i_dir_acl
+--- linux-2.4.20/include/linux/ext3_fs_i.h~ext3-ea-in-inode-2.4.20	2001-11-22 22:46:19.000000000 +0300
++++ linux-2.4.20-alexey/include/linux/ext3_fs_i.h	2003-10-12 16:34:14.000000000 +0400
+@@ -62,6 +62,9 @@ struct ext3_inode_info {
+ 	 */
+ 	loff_t	i_disksize;
+ 
++	/* on-disk additional lenght */
++	__u16 i_extra_isize;
++
+ 	/*
+ 	 * truncate_sem is for serialising ext3_truncate() against
+ 	 * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's
+--- linux-2.4.20/fs/ext3/super.c~ext3-ea-in-inode-2.4.20	2003-10-08 23:18:09.000000000 +0400
++++ linux-2.4.20-alexey/fs/ext3/super.c	2003-10-12 16:25:21.000000000 +0400
+@@ -1292,8 +1292,10 @@ struct super_block * ext3_read_super (st
+ 	} else {
+ 		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+ 		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+-		if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) {
+-			printk (KERN_ERR
++		if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
++				(sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
++				(sbi->s_inode_size > blocksize)) {
++  			printk (KERN_ERR
+ 				"EXT3-fs: unsupported inode size: %d\n",
+ 				sbi->s_inode_size);
+ 			goto failed_mount;
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.22-rh.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5800fe0ebc4babe42937c4a0c12e4172590d66ba
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.22-rh.patch
@@ -0,0 +1,756 @@
+ fs/ext3/ialloc.c          |    6 
+ fs/ext3/inode.c           |   12 
+ fs/ext3/super.c           |    6 
+ fs/ext3/xattr.c           |  597 +++++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/ext3_fs.h   |    2 
+ include/linux/ext3_fs_i.h |    3 
+ 6 files changed, 615 insertions(+), 11 deletions(-)
+
+--- linux-2.4.22-ac1/fs/ext3/ialloc.c~ext3-ea-in-inode-2.4.22-rh	2003-10-08 13:57:56.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c	2003-10-08 15:13:31.000000000 +0400
+@@ -715,6 +715,12 @@ have_bit_and_group:
+ 	insert_inode_hash(inode);
+ 	inode->i_generation = sb->u.ext3_sb.s_next_generation++;
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
++		inode->u.ext3_i.i_extra_isize = sizeof(__u16)	/* i_extra_isize */
++				+ sizeof(__u16);	/* i_pad1 */
++	} else
++		inode->u.ext3_i.i_extra_isize = 0;
++
+ 	inode->u.ext3_i.i_state = EXT3_STATE_NEW;
+  	err = ext3_get_inode_loc_new(inode, &iloc, 1);
+   	if (err) goto fail;
+--- linux-2.4.22-ac1/fs/ext3/inode.c~ext3-ea-in-inode-2.4.22-rh	2003-10-08 13:57:57.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c	2003-10-08 15:14:57.000000000 +0400
+@@ -2229,6 +2229,12 @@ void ext3_read_inode(struct inode * inod
+ 		inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
+ 	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		inode->u.ext3_i.i_extra_isize =
++			le16_to_cpu(raw_inode->i_extra_isize);
++	else
++		inode->u.ext3_i.i_extra_isize = 0;
++
+ 	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+@@ -2277,6 +2283,8 @@ static int ext3_do_update_inode(handle_t
+ 		if (err)
+ 			goto out_brelse;
+ 	}
++	if (EXT3_I(inode)->i_state & EXT3_STATE_NEW)
++		memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); 
+ 	raw_inode->i_mode = cpu_to_le16(inode->i_mode);
+ 	if(!(test_opt(inode->i_sb, NO_UID32))) {
+ 		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
+@@ -2360,6 +2368,10 @@ static int ext3_do_update_inode(handle_t
+ 	else for (block = 0; block < EXT3_N_BLOCKS; block++)
+ 		raw_inode->i_block[block] = inode->u.ext3_i.i_data[block];
+ 
++	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
++		raw_inode->i_extra_isize =
++			cpu_to_le16(EXT3_I(inode)->i_extra_isize);
++
+ 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+ 	rc = ext3_journal_dirty_metadata(handle, bh);
+ 	if (!err)
+--- linux-2.4.22-ac1/fs/ext3/super.c~ext3-ea-in-inode-2.4.22-rh	2003-10-08 13:57:57.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/super.c	2003-10-08 15:13:31.000000000 +0400
+@@ -1299,8 +1299,10 @@ struct super_block * ext3_read_super (st
+ 	} else {
+ 		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+ 		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+-		if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) {
+-			printk (KERN_ERR
++		if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) ||
++				(sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
++				(sbi->s_inode_size > blocksize)) {
++  			printk (KERN_ERR
+ 				"EXT3-fs: unsupported inode size: %d\n",
+ 				sbi->s_inode_size);
+ 			goto failed_mount;
+--- linux-2.4.22-ac1/fs/ext3/xattr.c~ext3-ea-in-inode-2.4.22-rh	2003-10-08 13:57:56.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/xattr.c	2003-10-12 16:36:07.000000000 +0400
+@@ -100,6 +100,9 @@
+ static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
+ 			   struct ext3_xattr_header *);
+ 
++int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,
++			const void *, size_t, int);
++
+ #ifdef CONFIG_EXT3_FS_XATTR_SHARING
+ 
+ static int ext3_xattr_cache_insert(struct buffer_head *);
+@@ -348,17 +351,12 @@ ext3_removexattr(struct dentry *dentry, 
+ }
+ 
+ /*
+- * ext3_xattr_get()
+- *
+- * Copy an extended attribute into the buffer
+- * provided, or compute the buffer size required.
+- * Buffer is NULL to compute the size of the buffer required.
++ * ext3_xattr_block_get()
+  *
+- * Returns a negative error number on failure, or the number of bytes
+- * used / required on success.
++ * routine looks for attribute in EA block and returns it's value and size
+  */
+ int
+-ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+ 	       void *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+@@ -447,6 +445,94 @@ cleanup:
+ }
+ 
+ /*
++ * ext3_xattr_ibode_get()
++ *
++ * routine looks for attribute in inode body and returns it's value and size
++ */
++int
++ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	int size, name_len = strlen(name), storage_size;
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOENT;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret)
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len))
++			goto found;
++		last = next;
++	}
++
++	/* can't find EA */
++	brelse(iloc.bh);
++	return -ENOENT;
++	
++found:
++	size = le32_to_cpu(last->e_value_size);
++	if (buffer) {
++		ret = -ERANGE;
++		if (buffer_size >= size) {
++			memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
++			size);
++			ret = size;
++		}
++	} else
++		ret = size;
++	brelse(iloc.bh);
++	return ret;
++}
++
++int ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++			void *buffer, size_t buffer_size)
++{
++	int err;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_get(inode, name_index, name,
++					buffer, buffer_size);
++	if (err < 0) 
++		/* search was unsuccessful, try to find EA in dedicated block */
++		err = ext3_xattr_block_get(inode, name_index, name,
++				buffer, buffer_size);
++	return err;
++}
++
++/*
+  * ext3_xattr_list()
+  *
+  * Copy a list of attribute names into the buffer
+@@ -457,7 +543,7 @@ cleanup:
+  * used / required on success.
+  */
+ int
+-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+ {
+ 	struct buffer_head *bh = NULL;
+ 	struct ext3_xattr_entry *entry;
+@@ -530,6 +616,131 @@ cleanup:
+ 	return error;
+ }
+ 
++/* ext3_xattr_ibody_list()
++ *
++ * generate list of attributes stored in inode body
++ */
++int
++ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	char *start, *end, *buf;
++	struct ext3_iloc iloc;
++	int storage_size;
++	int ret;
++	int size = 0;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return 0;
++
++	ret = ext3_get_inode_loc(inode, &iloc);
++	if (ret) 
++		return ret;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return 0;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++
++	if (!buffer) {
++		ret = size;
++		goto cleanup;
++	} else {
++		ret = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	last = (struct ext3_xattr_entry *) start;
++	buf = buffer;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		struct ext3_xattr_handler *handler;
++		handler = ext3_xattr_handler(last->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, last->e_name,
++					      last->e_name_len);
++		last = next;
++	}
++	ret = size;
++cleanup:
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	int error;
++	int size = buffer_size;
++
++	/* get list of attributes stored in inode body */
++	error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
++	if (error < 0) {
++		/* some error occured while collecting 
++		 * attributes in inode body */
++		size = 0;
++		goto cleanup;
++	}
++	size = error;
++
++	/* get list of attributes stored in dedicated block */
++	if (buffer) {
++		buffer_size -= error;
++		if (buffer_size <= 0) {
++			buffer = NULL;
++			buffer_size = 0;
++		} else 
++			buffer += error;
++	}
++
++	error = ext3_xattr_block_list(inode, buffer, buffer_size);
++	if (error < 0) 
++		/* listing was successful, so we return len */
++		size = 0;
++
++cleanup:
++	return error + size;
++}
++
+ /*
+  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+  * not set, set it.
+@@ -553,6 +764,279 @@ static void ext3_xattr_update_super_bloc
+ }
+ 
+ /*
++ * ext3_xattr_ibody_find()
++ *
++ * search attribute and calculate free space in inode body
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_ibody_find(struct inode *inode, int name_index, 
++		const char *name, struct ext3_xattr_entry *rentry, int *free)
++{
++	struct ext3_xattr_entry *last;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	char *start, *end;
++	int ret = -ENOENT;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return ret;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err) 
++		return -EIO;
++	raw_inode = iloc.raw_inode;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	*free = storage_size - sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
++		brelse(iloc.bh);
++		return -ENOENT;
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++
++	last = (struct ext3_xattr_entry *) start;
++	while (!IS_LAST_ENTRY(last)) {
++		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
++				"inode %ld", inode->i_ino);
++			brelse(iloc.bh);
++			return -EIO;
++		}
++
++		if (name_index == last->e_name_index &&
++		    name_len == last->e_name_len &&
++		    !memcmp(name, last->e_name, name_len)) {
++			memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
++			ret = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(last->e_name_len);
++			*free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++	
++	brelse(iloc.bh);
++	return ret;
++}
++
++/*
++ * ext3_xattr_block_find()
++ *
++ * search attribute and calculate free space in EA block (if it allocated)
++ * NOTE: free space includes space our attribute hold
++ */
++int
++ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
++	       struct ext3_xattr_entry *rentry, int *free)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	char *end;
++	int name_len, error = -ENOENT;
++
++	if (!EXT3_I(inode)->i_file_acl) {
++		*free = inode->i_sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) -
++			sizeof(__u32);
++		return -ENOENT;
++	}
++	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
++	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino,
++			EXT3_I(inode)->i_file_acl);
++		brelse(bh);
++		return -EIO;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++	*free = bh->b_size - sizeof(__u32);
++
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0) {
++			memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
++			error = 0;
++		} else {
++			*free -= EXT3_XATTR_LEN(entry->e_name_len);
++			*free -= le32_to_cpu(entry->e_value_size);
++		}
++		entry = next;
++	}
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_inode_set()
++ * 
++ * this routine add/remove/replace attribute in inode body
++ */
++int
++ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
++		      const char *name, const void *value, size_t value_len,
++		      int flags)
++{
++	struct ext3_xattr_entry *last, *next, *here = NULL;
++	struct ext3_inode *raw_inode;
++	int name_len = strlen(name);
++	int esize = EXT3_XATTR_LEN(name_len);
++	struct buffer_head *bh;
++	int err, storage_size;
++	struct ext3_iloc iloc;
++	int free, min_offs;
++	char *start, *end;
++	
++	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
++		return -ENOSPC;
++
++	err = ext3_get_inode_loc(inode, &iloc);
++	if (err)
++		return err;
++	raw_inode = iloc.raw_inode;
++	bh = iloc.bh;
++
++	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
++				EXT3_GOOD_OLD_INODE_SIZE -
++				EXT3_I(inode)->i_extra_isize -
++				sizeof(__u32);
++	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
++			EXT3_I(inode)->i_extra_isize;
++	if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
++		/* inode had no attributes before */
++		*((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
++	}
++	start += sizeof(__u32);
++	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
++	min_offs = storage_size;
++	free = storage_size - sizeof(__u32);
++
++	last = (struct ext3_xattr_entry *) start;	
++	while (!IS_LAST_ENTRY(last)) {
++		next = EXT3_XATTR_NEXT(last);
++		if (le32_to_cpu(last->e_value_size) > storage_size ||
++				(char *) next >= end) {
++			ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
++				"inode %ld", inode->i_ino);
++			brelse(bh);
++			return -EIO;
++		}
++		
++		if (last->e_value_size) {
++			int offs = le16_to_cpu(last->e_value_offs);
++			if (offs < min_offs)
++				min_offs = offs;
++		}
++		if (name_index == last->e_name_index &&
++			name_len == last->e_name_len &&
++			!memcmp(name, last->e_name, name_len)) 
++			here = last;
++		else {
++			/* we calculate all but our attribute
++			 * because it will be removed before changing */
++			free -= EXT3_XATTR_LEN(last->e_name_len);
++			free -= le32_to_cpu(last->e_value_size);
++		}
++		last = next;
++	}
++
++	if (value && (esize + value_len > free)) {
++		brelse(bh);
++		return -ENOSPC;
++	}
++	
++	err = ext3_reserve_inode_write(handle, inode, &iloc);
++	if (err) {
++		brelse(bh);	
++		return err;
++	}
++
++	if (here) {
++		/* time to remove old value */
++		struct ext3_xattr_entry *e;
++		int size = le32_to_cpu(here->e_value_size);
++		int border = le16_to_cpu(here->e_value_offs);
++		char *src;
++
++		/* move tail */
++		memmove(start + min_offs + size, start + min_offs,
++				border - min_offs);
++
++		/* recalculate offsets */
++		e = (struct ext3_xattr_entry *) start;
++		while (!IS_LAST_ENTRY(e)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
++			int offs = le16_to_cpu(e->e_value_offs); 
++			if (offs < border) 
++				e->e_value_offs = 
++					cpu_to_le16(offs + size);
++			e = next;
++		}
++		min_offs += size;
++
++		/* remove entry */
++		border = EXT3_XATTR_LEN(here->e_name_len);
++		src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
++		size = (char *) last - src;
++		if ((char *) here + size > end)
++			printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
++					__FILE__, __LINE__, here, size, end);
++		memmove(here, src, size);
++		last = (struct ext3_xattr_entry *) ((char *) last - border);
++		*((__u32 *) last) = 0;
++	}
++	
++	if (value) {
++		int offs = min_offs - value_len;
++		/* use last to create new entry */
++		last->e_name_len = strlen(name);
++		last->e_name_index = name_index;
++		last->e_value_offs = cpu_to_le16(offs);
++		last->e_value_size = cpu_to_le32(value_len);
++		last->e_hash = last->e_value_block = 0;
++		memset(last->e_name, 0, esize);
++		memcpy(last->e_name, name, last->e_name_len);
++		if (start + offs + value_len > end)
++			printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n",
++					__FILE__, __LINE__, start, offs,
++					value_len, end);
++		memcpy(start + offs, value, value_len);
++		last = EXT3_XATTR_NEXT(last);
++		*((__u32 *) last) = 0;
++	}
++	
++	ext3_mark_iloc_dirty(handle, inode, &iloc);
++	brelse(bh);
++
++	return 0;
++}
++
++/*
+  * ext3_xattr_set()
+  *
+  * Create, replace or remove an extended attribute for this inode. Buffer
+@@ -566,6 +1050,100 @@ static void ext3_xattr_update_super_bloc
+  */
+ int
+ ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++		const char *name, const void *value, size_t value_len, int flags)
++{
++	struct ext3_xattr_entry entry;
++	int err, where = 0, found = 0, total;
++	int free1 = -1, free2 = -1;
++	int name_len;
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
++		return -ERANGE;
++
++	/* try to find attribute in inode body */
++	err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
++	if (err == 0) {
++		/* found EA in inode */
++		found = 1;
++		where = 0;
++	} else if (err == -ENOENT) {
++		/* there is no such attribute in inode body */
++		/* try to find attribute in dedicated block */
++		err = ext3_xattr_block_find(inode, name_index, name,
++						&entry, &free2);
++		if (err != 0 && err != -ENOENT) {
++			/* not found EA in block */
++			goto finish;	
++		}
++		/* found EA in block */
++		where = 1;
++		found = 1;
++	} else
++		goto finish;
++
++	/* check flags: may replace? may create ? */
++	if (found && (flags & XATTR_CREATE)) {
++		err = -EEXIST;
++		goto finish;
++	} else if (!found && (flags & XATTR_REPLACE)) {
++		err = -ENODATA;
++		goto finish;
++	}
++
++	/* check if we have enough space to store attribute */
++	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
++	if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) {
++		/* have no enough space */
++		err = -ENOSPC;
++		goto finish;
++	}
++	
++	/* time to remove attribute */
++	if (found) {
++		if (where == 0) {
++			/* EA is stored in inode body */
++			ext3_xattr_ibody_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		} else {
++			/* EA is stored in separated block */
++			ext3_xattr_block_set(handle, inode, name_index, name,
++					NULL, 0, flags);
++		}
++	}
++
++	/* try to store EA in inode body */
++	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
++				value, value_len, flags);
++	if (err) {
++		/* can't store EA in inode body */
++		/* try to store in block */
++		err = ext3_xattr_block_set(handle, inode, name_index,
++					name, value, value_len, flags);	
++	}
++
++finish:	
++	return err;
++}
++
++/*
++ * ext3_xattr_block_set()
++ * 
++ * this routine add/remove/replace attribute in EA block
++ */
++int
++ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
+ 	       const char *name, const void *value, size_t value_len, int flags)
+ {
+ 	struct super_block *sb = inode->i_sb;
+@@ -603,6 +1181,7 @@ ext3_xattr_set(handle_t *handle, struct 
+ 	name_len = strlen(name);
+ 	if (name_len > 255 || value_len > sb->s_blocksize)
+ 		return -ERANGE;
++
+ 	down(&ext3_xattr_sem);
+ 
+ 	if (block) {
+--- linux-2.4.22-ac1/include/linux/ext3_fs.h~ext3-ea-in-inode-2.4.22-rh	2003-10-08 13:57:57.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h	2003-10-08 15:13:31.000000000 +0400
+@@ -265,6 +265,8 @@ struct ext3_inode {
+ 			__u32	m_i_reserved2[2];
+ 		} masix2;
+ 	} osd2;				/* OS dependent 2 */
++	__u16	i_extra_isize;
++	__u16	i_pad1;
+ };
+ 
+ #define i_size_high	i_dir_acl
+--- linux-2.4.22-ac1/include/linux/ext3_fs_i.h~ext3-ea-in-inode-2.4.22-rh	2003-09-26 00:54:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_i.h	2003-10-08 15:13:31.000000000 +0400
+@@ -62,6 +62,9 @@ struct ext3_inode_info {
+ 	 */
+ 	loff_t	i_disksize;
+ 
++	/* on-disk additional lenght */
++	__u16 i_extra_isize;
++
+ 	/*
+ 	 * truncate_sem is for serialising ext3_truncate() against
+ 	 * ext3_getblock().  In the 2.4 ext2 design, great chunks of inode's
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c931e8d593a52cc0fb575c438a0603836d6fa5f0
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch
@@ -0,0 +1,1891 @@
+ fs/ext3/Makefile           |    3 
+ fs/ext3/extents.c          | 1624 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/ialloc.c           |    4 
+ fs/ext3/inode.c            |   30 
+ fs/ext3/super.c            |    8 
+ include/linux/ext3_fs.h    |   18 
+ include/linux/ext3_fs_i.h  |    4 
+ include/linux/ext3_fs_sb.h |   10 
+ 8 files changed, 1693 insertions(+), 8 deletions(-)
+
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/extents.c	2003-09-23 18:09:30.000000000 +0400
+@@ -0,0 +1,1624 @@
++/*
++ *
++ * linux/fs/ext3/extents.c
++ *
++ * Extents support for EXT3
++ *
++ * 07/08/2003    Alex Tomas <bzzz@tmi.comex.ru>
++ * 
++ * TODO:
++ *   - ext3*_error() should be used in some situations
++ *   - find_goal() [to be tested and improved]
++ *   - error handling
++ *   - we could leak allocated block in some error cases
++ *   - quick search for index/leaf in ext3_ext_find_extent()
++ *   - tree reduction
++ *   - cache last found extent
++ *   - arch-independent
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/time.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/smp_lock.h>
++#include <linux/highuid.h>
++#include <linux/pagemap.h>
++#include <linux/quotaops.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/locks.h>
++
++/*
++ * with AGRESSIVE_TEST defined capacity of index/leaf blocks
++ * become very little, so index split, in-depth growing and
++ * other hard changes happens much more often
++ * this is for debug purposes only
++ */
++#define AGRESSIVE_TEST_
++
++/*
++ * if EXT_DEBUG defined you can use 'extdebug' mount option
++ * to get lots of info what's going on
++ */
++#define EXT_DEBUG
++#ifdef EXT_DEBUG
++#define ext_debug(inode,fmt,a...) 		\
++do {						\
++	if (test_opt((inode)->i_sb, EXTDEBUG))	\
++		printk(fmt, ##a);		\
++} while (0);
++#else
++#define ext_debug(inode,fmt,a...)
++#endif
++
++#define EXT3_ALLOC_NEEDED	2	/* block bitmap + group descriptor */
++
++/*
++ * ext3_inode has i_block array (total 60 bytes)
++ * first 4 bytes are used to store:
++ *  - tree depth (0 mean there is no tree yet. all extents in the inode)
++ *  - number of alive extents in the inode
++ */
++
++/*
++ * this is extent on-disk structure
++ * it's used at the bottom of the tree
++ */
++struct ext3_extent {
++	__u32	e_block;	/* first logical block extent covers */
++	__u32	e_start;	/* first physical block extents lives */
++	__u32	e_num;		/* number of blocks covered by extent */
++};
++
++/*
++ * this is index on-disk structure
++ * it's used at all the levels, but the bottom
++ */
++struct ext3_extent_idx {
++	__u32	e_block;	/* index covers logical blocks from 'block' */
++	__u32	e_leaf;		/* pointer to the physical block of the next *
++				 * level. leaf or next index could bet here */
++};
++
++/*
++ * each block (leaves and indexes), even inode-stored has header
++ */
++struct ext3_extent_header {	
++	__u16	e_num;		/* number of valid entries */
++	__u16	e_max;		/* capacity of store in entries */
++};
++
++/*
++ * array of ext3_ext_path contains path to some extent
++ * creation/lookup routines use it for traversal/splitting/etc
++ * truncate uses it to simulate recursive walking
++ */
++struct ext3_ext_path {
++	__u32				p_block;
++	__u16				p_depth;
++	struct ext3_extent		*p_ext;
++	struct ext3_extent_idx		*p_idx;
++	struct ext3_extent_header	*p_hdr;
++	struct buffer_head		*p_bh;
++};
++
++#define EXT_FIRST_EXTENT(__hdr__) \
++	((struct ext3_extent *) (((char *) (__hdr__)) +		\
++				 sizeof(struct ext3_extent_header)))
++#define EXT_FIRST_INDEX(__hdr__) \
++	((struct ext3_extent_idx *) (((char *) (__hdr__)) +	\
++				     sizeof(struct ext3_extent_header)))
++#define EXT_HAS_FREE_INDEX(__path__) \
++	((__path__)->p_hdr->e_num < (__path__)->p_hdr->e_max)
++#define EXT_LAST_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_LAST_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_MAX_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_max - 1)
++#define EXT_MAX_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_max - 1)
++
++
++#define EXT_ASSERT(__x__) if (!(__x__)) BUG();
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ */
++static int ext3_ext_get_access(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_get_write_access(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return 0;
++}
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ *  - EIO
++ */
++static int ext3_ext_dirty(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_dirty_metadata(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return ext3_mark_inode_dirty(handle, inode);
++}
++
++static inline int ext3_ext_space_block(struct inode *inode)
++{
++	int size;
++
++	size = (inode->i_sb->s_blocksize - sizeof(struct ext3_extent_header))
++		/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 6; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 3; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode_idx(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent_idx);
++#ifdef AGRESSIVE_TEST
++	size = 4; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static void ext3_ext_show_path(struct inode *inode, struct ext3_ext_path *path)
++{
++	int k, l = path->p_depth;
++
++	ext_debug(inode, "path:");
++	for (k = 0; k <= l; k++, path++) {
++		if (path->p_idx) {
++			ext_debug(inode, "  %d->%d", path->p_idx->e_block,
++					path->p_idx->e_leaf);
++		} else if (path->p_ext) {
++			ext_debug(inode, "  %d:%d:%d",
++					path->p_ext->e_block,
++					path->p_ext->e_start,
++					path->p_ext->e_num);
++		} else
++			ext_debug(inode, "  []");
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_show_leaf(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *eh = path[depth].p_hdr;
++	struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
++	int i;
++
++	for (i = 0; i < eh->e_num; i++, ex++) {
++		ext_debug(inode, "%d:%d:%d ",
++				ex->e_block, ex->e_start, ex->e_num);
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_drop_refs(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = path->p_depth;
++	int i;
++
++	for (i = 0; i <= depth; i++, path++)
++		if (path->p_bh) {
++			brelse(path->p_bh);
++			path->p_bh = NULL;
++		}
++}
++
++static int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	unsigned long bg_start;
++	unsigned long colour;
++	int depth;
++	
++	if (path) {
++		depth = path->p_depth;
++		/* try to find previous block */
++		if (path[depth].p_ext)
++			return path[depth].p_ext->e_start +
++				path[depth].p_ext->e_num - 1;
++		
++		/* it looks index is empty
++		 * try to find starting from index itself */
++		if (path[depth].p_bh)
++			return path[depth].p_bh->b_blocknr;
++	}
++
++	/* OK. use inode's group */
++	bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
++		le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
++	colour = (current->pid % 16) *
++			(EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16);
++	return bg_start + colour;
++}
++
++static struct ext3_ext_path *
++ext3_ext_find_extent(struct inode *inode, int block, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	struct ext3_extent_header *eh = (void *) ei->i_data;
++	struct ext3_extent_idx *ix;
++	struct buffer_head *bh;
++	struct ext3_extent *ex;
++	int depth, i, k, ppos = 0, prev = 0;
++	
++	eh = (struct ext3_extent_header *) ei->i_data;
++
++	/* initialize capacity of leaf in inode for first time */
++	if (eh->e_max == 0)
++		eh->e_max = ext3_ext_space_inode(inode);
++	i = depth = ei->i_depth;
++	EXT_ASSERT(i == 0 || eh->e_num > 0);
++	
++	/* account possible depth increase */
++	if (!path) {
++		path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2),
++				GFP_NOFS);
++		if (!path)
++			return ERR_PTR(-ENOMEM);
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	/* walk through the tree */
++	while (i) {
++		ext_debug(inode, "depth %d: num %d, max %d\n",
++				ppos, eh->e_num, eh->e_max);
++		ix = EXT_FIRST_INDEX(eh);
++		if (eh->e_num) {
++			EXT_ASSERT(prev == 0 || ix->e_block == prev);
++			path[ppos].p_idx = ix;
++		}
++		EXT_ASSERT(eh->e_num <= eh->e_max);
++		for (k = 0; k < eh->e_num; k++, ix++) {
++			ext_debug(inode, "index: %d -> %d\n",
++					ix->e_block, ix->e_leaf);
++			EXT_ASSERT((k == 0 && prev <= (int)ix->e_block) ||
++					(k > 0 && prev < (int)ix->e_block));
++			if (block < ix->e_block)
++				break;
++			prev = ix->e_block;
++			path[ppos].p_idx = ix;
++		}
++		path[ppos].p_block = path[ppos].p_idx->e_leaf;
++		path[ppos].p_depth = i;
++		path[ppos].p_hdr = eh;
++		path[ppos].p_ext = NULL;
++
++		bh = sb_bread(inode->i_sb, path[ppos].p_block);
++		if (!bh) {
++			ext3_ext_drop_refs(inode, path);
++			kfree(path);
++			return ERR_PTR(-EIO);
++		}
++		eh = (struct ext3_extent_header *) bh->b_data;
++		ppos++;
++		EXT_ASSERT(ppos <= depth);
++		path[ppos].p_bh = bh;
++		i--;
++	}
++
++	path[ppos].p_depth = i;
++	path[ppos].p_hdr = eh;
++	path[ppos].p_ext = NULL;
++	
++	/* find extent */
++	ex = EXT_FIRST_EXTENT(eh);
++	if (eh->e_num)
++		path[ppos].p_ext = ex;
++	EXT_ASSERT(eh->e_num <= eh->e_max);
++	for (k = 0; k < eh->e_num; k++, ex++) {
++		EXT_ASSERT(ex->e_num < EXT3_BLOCKS_PER_GROUP(inode->i_sb));
++		EXT_ASSERT((k == 0 && prev <= (int)ex->e_block) ||
++				(k > 0 && prev < (int)ex->e_block));
++		if (block < ex->e_block) 
++			break;
++		prev = ex->e_block;
++		path[ppos].p_ext = ex;
++	}
++
++	ext3_ext_show_path(inode, path);
++
++	return path;
++}
++
++static void ext3_ext_check_boundary(struct inode *inode,
++					struct ext3_ext_path *curp,
++					void *addr, int len)
++{
++	void *end;
++
++	if (!len)
++		return;
++	if (curp->p_bh)
++		end = (void *) curp->p_hdr + inode->i_sb->s_blocksize;
++	else
++		end = (void *) curp->p_hdr + sizeof(EXT3_I(inode)->i_data);
++	if (((unsigned long) addr) + len > (unsigned long) end) {
++		printk("overflow! 0x%p > 0x%p\n", addr + len, end);
++		BUG();
++	}
++	if ((unsigned long) addr < (unsigned long) curp->p_hdr) {
++		printk("underflow! 0x%p < 0x%p\n", addr, curp->p_hdr);
++		BUG();
++	}
++}
++
++/*
++ * insert new index [logical;ptr] into the block at cupr
++ * it check where to insert: before curp or after curp
++ */
++static int ext3_ext_insert_index(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *curp, int logical,
++				int ptr)
++{
++	struct ext3_extent_idx *ix;
++	int len, err;
++
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		return err;
++
++	EXT_ASSERT(logical != curp->p_idx->e_block);
++	len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
++	if (logical > curp->p_idx->e_block) {
++		/* insert after */
++		len = (len - 1) * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d after: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				(curp->p_idx + 1), (curp->p_idx + 2));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 2, len);
++		memmove(curp->p_idx + 2, curp->p_idx + 1, len);
++		ix = curp->p_idx + 1;
++	} else {
++		/* insert before */
++		len = len * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d before: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				curp->p_idx, (curp->p_idx + 1));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 1, len);
++		memmove(curp->p_idx + 1, curp->p_idx, len);
++		ix = curp->p_idx;
++	}
++
++	ix->e_block = logical;
++	ix->e_leaf = ptr;
++	curp->p_hdr->e_num++;
++
++	err = ext3_ext_dirty(handle, inode, curp);
++	ext3_std_error(inode->i_sb, err);
++
++	return err;
++}
++
++/*
++ * routine inserts new subtree into the path, using free index entry
++ * at depth 'at:
++ *  - allocates all needed blocks (new leaf and all intermediate index blocks)
++ *  - makes decision where to split
++ *  - moves remaining extens and index entries (right to the split point)
++ *    into the newly allocated blocks
++ *  - initialize subtree
++ */
++static int ext3_ext_split(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext, int at)
++{
++	struct buffer_head *bh = NULL;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	struct ext3_extent *ex;
++	int i = at, k, m, a;
++	long newblock, oldblock, border;
++	int *ablocks = NULL; /* array of allocated blocks */
++	int err = 0;
++
++	/* make decision: where to split? */
++	/* FIXME: now desicion is simplest: at current extent */
++
++	/* if current leaf will be splitted, then we should use 
++	 * border from split point */
++	
++	if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		border = path[depth].p_ext[1].e_block;
++		ext_debug(inode, "leaf will be splitted."
++				" next leaf starts at %d\n",
++				(int)border);
++	} else {
++		border = newext->e_block;
++		ext_debug(inode, "leaf will be added."
++				" next leaf starts at %d\n",
++				(int)border);
++	}
++
++	/* 
++	 * if error occurs, then we break processing
++	 * and turn filesystem read-only. so, index won't
++	 * be inserted and tree will be in consistent
++	 * state. next mount will repair buffers too
++	 */
++
++	/*
++	 * get array to track all allocated blocks
++	 * we need this to handle errors and free blocks
++	 * upon them
++	 */
++	ablocks = kmalloc(sizeof(long) * depth, GFP_NOFS);
++	if (!ablocks)
++		return -ENOMEM;
++	memset(ablocks, 0, sizeof(long) * depth);
++
++	/* allocate all needed blocks */
++	ext_debug(inode, "allocate %d blocks for indexes/leaf\n", depth - at);
++	newblock = 0; /* FIXME: something more sophisticated needed here */ 
++	for (a = 0; newext->e_num > 0 && a < depth - at; a++) {
++		newblock = ablocks[a] = newext->e_start++;
++		newext->e_num--;
++	}
++	for (; a < depth - at; a++) {
++		newblock = ext3_new_block(handle, inode,
++						newblock + 1, 0, 0, &err);
++		if (newblock == 0)
++			goto cleanup;
++		ablocks[a] = newblock;
++	}
++
++	/* initialize new leaf */
++	newblock = ablocks[--a];
++	EXT_ASSERT(newblock);
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		goto cleanup;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh)))
++		goto cleanup;
++
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_num = 0;
++	neh->e_max = ext3_ext_space_block(inode);
++	ex = EXT_FIRST_EXTENT(neh);
++
++	/* move remain of path[depth] to the new leaf */
++	EXT_ASSERT(path[depth].p_hdr->e_num ==
++			path[depth].p_hdr->e_max);
++	/* start copy from next extent */
++	/* TODO: we could do it by single memmove */
++	m = 0;
++	path[depth].p_ext++;
++	while (path[depth].p_ext <=
++			EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		ext_debug(inode, "move %d:%d:%d in new leaf\n",
++				path[depth].p_ext->e_block,
++				path[depth].p_ext->e_start,
++				path[depth].p_ext->e_num);
++		memmove(ex++, path[depth].p_ext++,
++				sizeof(struct ext3_extent));
++		neh->e_num++;
++		m++;
++	}
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto cleanup;	
++	brelse(bh);
++	bh = NULL;
++
++	/* correct old leaf */
++	if (m) {
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			goto cleanup;
++		path[depth].p_hdr->e_num -= m;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			goto cleanup;
++		
++	}
++
++	/* create intermediate indexes */
++	k = depth - at - 1;
++	EXT_ASSERT(k >= 0);
++	if (k)
++		ext_debug(inode,
++				"create %d intermediate indices\n", k);
++	/* insert new index into current index block */
++	/* current depth stored in i var */
++	i = depth - 1;
++	while (k--) {
++		oldblock = newblock;
++		newblock = ablocks[--a];
++		bh = sb_getblk(inode->i_sb, newblock);
++		if (!bh) {
++			err = -EIO;
++			goto cleanup;
++		}
++		lock_buffer(bh);
++
++		if ((err = ext3_journal_get_create_access(handle, bh)))
++			goto cleanup;
++
++		neh = (struct ext3_extent_header *) bh->b_data;
++		neh->e_num = 1;
++		neh->e_max = ext3_ext_space_block(inode);
++		fidx = EXT_FIRST_INDEX(neh);
++		fidx->e_block = border;
++		fidx->e_leaf = oldblock;
++
++		ext_debug(inode,
++				"int.index at %d (block %u): %d -> %d\n",
++				i, (unsigned) newblock,
++				(int) border,
++				(int) oldblock);
++		/* copy indexes */
++		m = 0;
++		path[i].p_idx++;
++		ext_debug(inode, "cur 0x%p, last 0x%p\n", path[i].p_idx,
++				EXT_MAX_INDEX(path[i].p_hdr));
++		EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) ==
++				EXT_LAST_INDEX(path[i].p_hdr));
++		while (path[i].p_idx <=
++				EXT_MAX_INDEX(path[i].p_hdr)) {
++			ext_debug(inode, "%d: move %d:%d in new index\n",
++					i, path[i].p_idx->e_block,
++					path[i].p_idx->e_leaf);
++			memmove(++fidx, path[i].p_idx++,
++					sizeof(struct ext3_extent_idx));
++			neh->e_num++;
++			m++;
++		}
++
++		mark_buffer_uptodate(bh, 1);
++		unlock_buffer(bh);
++
++		if ((err = ext3_journal_dirty_metadata(handle, bh)))
++			goto cleanup;
++		brelse(bh);
++		bh = NULL;
++
++		/* correct old index */
++		if (m) {
++			err = ext3_ext_get_access(handle,inode,path+i);
++			if (err)
++				goto cleanup;
++			path[i].p_hdr->e_num -= m;
++			err = ext3_ext_dirty(handle, inode, path + i);
++			if (err)
++				goto cleanup;
++		}
++
++		i--;
++	}
++
++	/* insert new index */
++	if (!err)
++		err = ext3_ext_insert_index(handle, inode, path + at,
++						border, newblock);
++
++cleanup:
++	if (bh) {
++		if (buffer_locked(bh))
++			unlock_buffer(bh);
++		brelse(bh);
++	}
++
++	if (err) {
++		/* free all allocated blocks in error case */
++		for (i = 0; i < depth; i++)
++			if (!ablocks[i])
++				continue;
++			ext3_free_blocks(handle, inode, ablocks[i], 1);
++	}
++	kfree(ablocks);
++
++	return err;
++}
++
++/*
++ * routine implements tree growing procedure:
++ *  - allocates new block
++ *  - moves top-level data (index block or leaf) into the new block
++ *  - initialize new top-level, creating index that points to the
++ *    just created block
++ */
++static int ext3_ext_grow_indepth(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	struct buffer_head *bh;
++	struct ext3_ext_path *curp = path;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	int len, err = 0;
++	long newblock;
++
++	/*
++	 * use already allocated by the called block for new root block
++	 */
++	newblock = newext->e_start++;
++	if (newext->e_num == 0) {
++		/* 
++		 * FIXME: if this may happen, then we have to handle
++		 * possible error and free allocated block
++		 */
++		printk("grow_indepth with zero blocks\n");
++		newblock = ext3_new_block(handle, inode,
++						newblock, 0, 0, &err);
++	} else
++		newext->e_num--;
++	
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		ext3_std_error(inode->i_sb, err);
++		return err;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh))) {
++		unlock_buffer(bh);
++		goto out;	
++	}
++
++	/* move top-level index/leaf into new block */
++	len = sizeof(struct ext3_extent_header) +
++		sizeof(struct ext3_extent) * curp->p_hdr->e_max;
++	EXT_ASSERT(len >= 0 && len < 4096);
++	memmove(bh->b_data, curp->p_hdr, len);
++
++	/* set size of new block */
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_max = ext3_ext_space_block(inode);
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto out;
++
++	/* create index in new top-level index: num,max,pointer */
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		goto out;
++
++	curp->p_hdr->e_max = ext3_ext_space_inode_idx(inode);
++	curp->p_hdr->e_num = 1;
++	curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
++	curp->p_idx->e_block = EXT_FIRST_EXTENT(path[0].p_hdr)->e_block;
++	curp->p_idx->e_leaf = newblock;
++
++	neh = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	fidx = EXT_FIRST_INDEX(neh);
++	ext_debug(inode, "new root: num %d(%d), lblock %d, ptr %d\n",
++			neh->e_num, neh->e_max, fidx->e_block, fidx->e_leaf); 
++
++	EXT3_I(inode)->i_depth++;
++	err = ext3_ext_dirty(handle, inode, curp);
++out:
++	brelse(bh);
++
++	return err;
++}
++
++/*
++ * routine finds empty index and adds new leaf. if no free index found
++ * then it requests in-depth growing
++ */
++static int ext3_ext_create_new_leaf(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	long newblock = newext->e_start;
++	struct ext3_ext_path *curp;
++	int depth, i, err = 0;
++
++repeat:
++	i = depth = EXT3_I(inode)->i_depth;
++	
++	/* walk up to the tree and look for free index entry */
++	curp = path + depth;
++	while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
++		i--;
++		curp--;
++	}
++
++	/* we use already allocated block for index block
++	 * so, subsequent data blocks should be contigoues */
++	if (EXT_HAS_FREE_INDEX(curp)) {
++		/* if we found index with free entry, then use that
++		 * entry: create all needed subtree and add new leaf */
++		err = ext3_ext_split(handle, inode, path, newext, i);
++
++		/* refill path */
++		ext3_ext_drop_refs(inode, path);
++		path = ext3_ext_find_extent(inode, newext->e_block, path);
++		if (IS_ERR(path))
++			err = PTR_ERR(path);
++	} else {
++		/* tree is full, time to grow in depth */
++		err = ext3_ext_grow_indepth(handle, inode, path, newext);
++
++		/* refill path */
++		ext3_ext_drop_refs(inode, path);
++		path = ext3_ext_find_extent(inode, newext->e_block, path);
++		if (IS_ERR(path))
++			err = PTR_ERR(path);
++	
++		/*
++		 * only first (depth 0 -> 1) produces free space
++		 * in all other cases we have to split growed tree
++		 */
++		depth = EXT3_I(inode)->i_depth;
++		if (path[depth].p_hdr->e_num == path[depth].p_hdr->e_max) {
++			/* now we need split */
++			goto repeat;
++		}
++	}
++
++	if (err)
++		return err;
++
++	/*
++	 * probably we've used some blocks from extent
++	 * let's allocate new block for it
++	 */
++	if (newext->e_num == 0 && !err) {
++		newext->e_start =
++			ext3_new_block(handle, inode, newblock,
++					0, 0, &err);
++		if (newext->e_start != 0)
++			newext->e_num = 1;
++	}
++
++	return 0;
++}
++
++/*
++ * returns next allocated block or 0xffffffff
++ * NOTE: it consider block number from index entry as
++ * allocated block. thus, index entries have to be consistent
++ * with leafs
++ */
++static inline unsigned ext3_ext_next_allocated_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	if (depth == 0 && path->p_ext == NULL)
++		return 0xffffffff;
++
++	/* FIXME: what if index isn't full ?! */
++	while (depth >= 0) {
++		if (depth == path->p_depth) {
++			/* leaf */
++			if (path[depth].p_ext !=
++					EXT_LAST_EXTENT(path[depth].p_hdr))
++				return path[depth].p_ext[1].e_block;
++		} else {
++			/* index */
++			if (path[depth].p_idx !=
++					EXT_LAST_INDEX(path[depth].p_hdr))
++				return path[depth].p_idx[1].e_block;
++		}
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * returns first allocated block from next leaf or 0xffffffff
++ */
++static unsigned ext3_ext_next_leaf_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	/* zero-tree has no leaf blocks at all */
++	if (depth == 0)
++		return 0xffffffff;
++
++	/* go to index block */
++	depth--;
++	
++	while (depth >= 0) {
++		if (path[depth].p_idx !=
++				EXT_LAST_INDEX(path[depth].p_hdr))
++			return path[depth].p_idx[1].e_block;
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * if leaf gets modified and modified extent is first in the leaf
++ * then we have to correct all indexes above
++ * TODO: do we need to correct tree in all cases?
++ */
++int ext3_ext_correct_indexes(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;	
++	struct ext3_extent_header *eh;
++	struct ext3_extent *ex;
++	long border;
++	int k, err = 0;
++	
++	eh = path[depth].p_hdr;
++	ex = path[depth].p_ext;
++
++	EXT_ASSERT(ex);
++	EXT_ASSERT(eh);
++	
++	if (depth == 0) {
++		/* there is no tree at all */
++		return 0;
++	}
++	
++	if (ex != EXT_FIRST_EXTENT(eh)) {
++		/* we correct tree if first leaf got modified only */
++		return 0;
++	}
++	
++	/*
++	 * TODO: we need correction if border is smaller then current one
++	 */
++	k = depth - 1;
++	border = path[depth].p_ext->e_block;
++	if ((err = ext3_ext_get_access(handle, inode, path + k)))
++		return err;
++	path[k].p_idx->e_block = border;
++	if ((err = ext3_ext_dirty(handle, inode, path + k)))
++		return err;
++
++	while (k--) {
++		/* change all left-side indexes */
++		if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr))
++			break;
++		if ((err = ext3_ext_get_access(handle, inode, path + k)))
++			break;
++		path[k].p_idx->e_block = border;
++		if ((err = ext3_ext_dirty(handle, inode, path + k)))
++			break;
++	}
++
++	return err;
++}
++
++/*
++ * this routine tries to merge requsted extent into the existing
++ * extent or inserts requested extent as new one into the tree,
++ * creating new leaf in no-space case
++ */
++int ext3_ext_insert_extent(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext)
++{
++	int depth, len;
++	struct ext3_extent_header * eh;
++	struct ext3_extent *ex;
++	struct ext3_extent *nearex; /* nearest extent */
++	struct ext3_ext_path *npath = NULL;
++	int err;
++
++	depth = EXT3_I(inode)->i_depth;	
++	if ((ex = path[depth].p_ext)) {
++		/* try to insert block into found extent and return */
++		if (ex->e_block + ex->e_num == newext->e_block &&
++				ex->e_start + ex->e_num == newext->e_start) {
++#ifdef AGRESSIVE_TEST
++			if (ex->e_num >= 2)
++				goto repeat;
++#endif
++			if ((err = ext3_ext_get_access(handle, inode,
++							path + depth)))
++				return err;
++			ext_debug(inode, "append %d block to %d:%d (from %d)\n",
++					newext->e_num, ex->e_block, ex->e_num,
++					ex->e_start);
++			ex->e_num += newext->e_num;
++			err = ext3_ext_dirty(handle, inode, path + depth);
++			return err;
++		}
++	}
++
++repeat:
++	depth = EXT3_I(inode)->i_depth;	
++	eh = path[depth].p_hdr;
++	if (eh->e_num == eh->e_max) {
++		/* probably next leaf has space for us? */
++		int next = ext3_ext_next_leaf_block(inode, path);
++		if (next != 0xffffffff) {
++			ext_debug(inode, "next leaf block - %d\n", next);
++			EXT_ASSERT(!npath);
++			npath = ext3_ext_find_extent(inode, next, NULL);
++			if (IS_ERR(npath))
++				return PTR_ERR(npath);
++			EXT_ASSERT(npath->p_depth == path->p_depth);
++			eh = npath[depth].p_hdr;
++			if (eh->e_num < eh->e_max) {
++				ext_debug(inode,
++						"next leaf has free ext(%d)\n",
++						eh->e_num);
++				path = npath;
++				goto repeat;
++			}
++			ext_debug(inode, "next leaf hasno free space(%d,%d)\n",
++					eh->e_num, eh->e_max);
++		}
++		/*
++		 * there is no free space in found leaf
++		 * we're gonna add new leaf in the tree
++		 */
++		err = ext3_ext_create_new_leaf(handle, inode, path, newext);
++		if (err)
++			goto cleanup;
++		goto repeat;
++	}
++
++	nearex = path[depth].p_ext;
++
++	if ((err = ext3_ext_get_access(handle, inode, path + depth)))
++		goto cleanup;
++
++	if (!nearex) {
++		/* there is no extent in this leaf, create first one */
++		ext_debug(inode, "first extent in the leaf: %d:%d:%d\n",
++				newext->e_block, newext->e_start,
++				newext->e_num);
++		eh->e_num++;
++		path[depth].p_ext = EXT_FIRST_EXTENT(eh);
++
++	} else if (newext->e_block > nearex->e_block) {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = EXT_MAX_EXTENT(eh) - nearex;
++		len = (len - 1) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d after: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		ext3_ext_check_boundary(inode, path + depth, nearex + 2, len);
++		memmove(nearex + 2, nearex + 1, len);
++		path[depth].p_ext = nearex + 1;
++		eh->e_num++;
++	} else {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d before: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		
++		memmove(nearex + 1, nearex, len);
++		path[depth].p_ext = nearex;
++	}
++
++	if (!err) {
++		eh->e_num++;
++		nearex = path[depth].p_ext;
++		nearex->e_block = newext->e_block;
++		nearex->e_start = newext->e_start;
++		nearex->e_num = newext->e_num;
++		EXT_ASSERT(nearex->e_num < EXT3_BLOCKS_PER_GROUP(inode->i_sb) &&
++				nearex->e_num > 0);
++
++		/* time to correct all indexes above */
++		err = ext3_ext_correct_indexes(handle, inode, path);
++	}
++
++	err = ext3_ext_dirty(handle, inode, path + depth);
++
++cleanup:
++	if (npath) {
++		ext3_ext_drop_refs(inode, npath);
++		kfree(npath);
++	}
++		
++	return err;
++}
++
++int ext3_ext_get_block(handle_t *handle, struct inode *inode, long iblock,
++			struct buffer_head *bh_result, int create,
++			int extend_disksize)
++{
++	struct ext3_ext_path *path;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent newex;
++	struct ext3_extent *ex;
++	int goal, newblock, err = 0;
++
++	ext_debug(inode, "block %d requested for inode %u, bh_result 0x%p\n",
++			(int) iblock, (unsigned) inode->i_ino, bh_result);
++	bh_result->b_state &= ~(1UL << BH_New);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* find extent for this block */
++	path = ext3_ext_find_extent(inode, iblock, NULL);
++	if (IS_ERR(path)) {
++		err = PTR_ERR(path);
++		goto out2;
++	}
++
++	if ((ex = path[depth].p_ext)) {
++		/* if found exent covers block, simple return it */
++		if (iblock >= ex->e_block && iblock < ex->e_block + ex->e_num) {
++			newblock = iblock - ex->e_block + ex->e_start;
++			ext_debug(inode, "%d fit into %d:%d -> %d\n",
++					(int) iblock, ex->e_block, ex->e_num,
++					newblock);
++			goto out;
++		}
++	}
++
++	/*
++	 * we couldn't try to create block if create flag is zero 
++	 */
++	if (!create) 
++		goto out2;
++
++	/* allocate new block */
++	goal = ext3_ext_find_goal(inode, path);
++	newblock = ext3_new_block(handle, inode, goal, 0, 0, &err);
++	if (!newblock)
++		goto out2;
++	ext_debug(inode, "allocate new block: goal %d, found %d\n",
++			goal, newblock);
++
++	/* try to insert new extent into found leaf and return */
++	newex.e_block = iblock;
++	newex.e_start = newblock;
++	newex.e_num = 1;
++	err = ext3_ext_insert_extent(handle, inode, path, &newex);
++	if (err)
++		goto out2;
++	
++	/* previous routine could use block we allocated */
++	newblock = newex.e_start;
++	bh_result->b_state |= (1UL << BH_New);
++
++out:
++	ext3_ext_show_leaf(inode, path);
++	bh_result->b_dev = inode->i_dev;
++	bh_result->b_blocknr = newblock;
++	bh_result->b_state |= (1UL << BH_Mapped);
++out2:
++	ext3_ext_drop_refs(inode, path);
++	kfree(path);
++	up(&EXT3_I(inode)->i_ext_sem);
++
++	return err;	
++}
++
++/*
++ * returns 1 if current index have to be freed (even partial)
++ */
++static int ext3_ext_more_to_truncate(struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	EXT_ASSERT(path->p_idx);
++
++	if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr))
++		return 0;
++
++	/*
++	 * if truncate on deeper level happened it it wasn't partial
++	 * so we have to consider current index for truncation
++	 */
++	if (path->p_hdr->e_num == path->p_block)
++		return 0;
++
++	/*
++	 * put actual number of indexes to know is this number got
++	 * changed at the next iteration
++	 */
++	path->p_block = path->p_hdr->e_num;
++	
++	return 1;
++}
++
++/*
++ * routine removes index from the index block
++ * it's used in truncate case only. thus all requests are for
++ * last index in the block only
++ */
++int ext3_ext_remove_index(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	struct buffer_head *bh;
++	int err;
++	
++	/* free index block */
++	path--;
++	EXT_ASSERT(path->p_hdr->e_num);
++	if ((err = ext3_ext_get_access(handle, inode, path)))
++		return err;
++	path->p_hdr->e_num--;
++	if ((err = ext3_ext_dirty(handle, inode, path)))
++		return err;
++	bh = sb_get_hash_table(inode->i_sb, path->p_idx->e_leaf);
++	ext3_forget(handle, 0, inode, bh, path->p_idx->e_leaf);
++	ext3_free_blocks(handle, inode, path->p_idx->e_leaf, 1);
++
++	ext_debug(inode, "index is empty, remove it, free block %d\n",
++			path->p_idx->e_leaf);
++	return err;
++}
++
++/*
++ * returns 1 if current extent needs to be freed (even partial)
++ * instead, returns 0
++ */
++int ext3_ext_more_leaves_to_truncate(struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	struct ext3_extent *ex = path->p_ext;
++	int last_block; 
++
++	EXT_ASSERT(ex);
++
++	/* is there leave in the current leaf? */
++	if (ex < EXT_FIRST_EXTENT(path->p_hdr))
++		return 0;
++	
++	last_block = (inode->i_size + blocksize-1)
++			>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++
++	if (last_block >= ex->e_block + ex->e_num)
++		return 0;
++
++	/* seems it extent have to be freed */
++	return 1;
++}
++
++handle_t *ext3_ext_journal_restart(handle_t *handle, int needed)
++{
++	int err;
++
++	if (handle->h_buffer_credits > needed)
++		return handle;
++	if (!ext3_journal_extend(handle, needed))
++		return handle;
++	err = ext3_journal_restart(handle, needed);
++	
++	return handle;
++}
++
++/*
++ * this routine calculate max number of blocks to be modified
++ * while freeing extent and is intended to be used in truncate path
++ */
++static int ext3_ext_calc_credits(struct inode *inode,
++					struct ext3_ext_path *path,
++					int num)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	int needed;
++	
++	/*
++	 * extent couldn't cross group, so we will modify
++	 * single bitmap block and single group descriptor
++	 */
++	needed = 2;
++
++	/*
++	 * if this is last extent in a leaf, then we have to
++	 * free leaf block and remove pointer from index above.
++	 * that pointer could be last in index block, so we'll
++	 * have to remove it too. this way we could modify/free
++	 * the whole path + root index (inode stored) will be
++	 * modified
++	 */
++	if (!path || (num == path->p_ext->e_num &&
++				path->p_ext == EXT_FIRST_EXTENT(path->p_hdr)))
++		needed += (depth * EXT3_ALLOC_NEEDED) + 1;
++
++	/*
++	 * it seems current calculation has bug
++	 * this is workaround -bzzz
++	 */
++	needed += 10;
++
++	return needed;
++}
++
++/*
++ * core of the truncate procedure:
++ * - calculated what part of each extent in the requested leaf
++ *   need to be freed
++ * - frees and forgets these blocks
++ *
++ * TODO: we could optimize and free several extents during
++ *       single journal_restart()-journal_restart() cycle
++ */
++static int ext3_ext_truncate_leaf(handle_t *handle,
++					struct inode *inode,
++					struct ext3_ext_path *path,
++					int depth)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	int last_block; 
++	int i, err = 0, sf, num;
++
++	ext_debug(inode, "level %d - leaf\n", depth);
++	if (!path->p_hdr)
++		path->p_hdr =
++			(struct ext3_extent_header *) path->p_bh->b_data;
++
++	EXT_ASSERT(path->p_hdr->e_num <= path->p_hdr->e_max);
++	
++	last_block = (inode->i_size + blocksize-1)
++					>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++	path->p_ext = EXT_LAST_EXTENT(path->p_hdr);
++	while (ext3_ext_more_leaves_to_truncate(inode, path)) {
++
++		/* what part of extent have to be freed? */
++		sf = last_block > path->p_ext->e_block ?
++			last_block : path->p_ext->e_block;
++
++		/* number of blocks from extent to be freed */
++		num = path->p_ext->e_block + path->p_ext->e_num - sf;
++
++		/* calc physical first physical block to be freed */
++		sf = path->p_ext->e_start + (sf - path->p_ext->e_block);
++
++		i = ext3_ext_calc_credits(inode, path, num);
++		handle = ext3_ext_journal_restart(handle, i);
++		if (IS_ERR(handle))
++			return PTR_ERR(handle);
++		
++		ext_debug(inode, "free extent %d:%d:%d -> free %d:%d\n",
++				path->p_ext->e_block, path->p_ext->e_start,
++				path->p_ext->e_num, sf, num);
++		for (i = 0; i < num; i++) {
++			struct buffer_head *bh =
++				sb_get_hash_table(inode->i_sb, sf + i);
++			ext3_forget(handle, 0, inode, bh, sf + i);
++		}
++		ext3_free_blocks(handle, inode, sf, num);
++
++		/* collect extents usage stats */
++		spin_lock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++		EXT3_SB(inode->i_sb)->s_ext_extents++;
++		EXT3_SB(inode->i_sb)->s_ext_blocks += num;
++		spin_unlock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++
++		/* reduce extent */
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			return err;
++		path->p_ext->e_num -= num;
++		if (path->p_ext->e_num == 0)
++			path->p_hdr->e_num--;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			return err;
++
++		path->p_ext--;
++	}
++	
++	/* if this leaf is free, then we should
++	 * remove it from index block above */
++	if (path->p_hdr->e_num == 0 && depth > 0) 
++		err = ext3_ext_remove_index(handle, inode, path);
++
++	return err;
++}
++
++static void ext3_ext_collect_stats(struct inode *inode)
++{
++	int depth;
++	
++	/* skip inodes with old good bitmap */
++	if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++		return;
++	
++	/* collect on full truncate only */
++	if (inode->i_size)
++		return;
++
++	depth = EXT3_I(inode)->i_depth;
++	if (depth < EXT3_SB(inode->i_sb)->s_ext_mindepth)
++		 EXT3_SB(inode->i_sb)->s_ext_mindepth = depth;
++	if (depth > EXT3_SB(inode->i_sb)->s_ext_maxdepth)
++		 EXT3_SB(inode->i_sb)->s_ext_maxdepth = depth;
++	EXT3_SB(inode->i_sb)->s_ext_sum += depth;
++	EXT3_SB(inode->i_sb)->s_ext_count++;
++	
++}
++
++void ext3_ext_truncate(struct inode * inode)
++{
++	struct address_space *mapping = inode->i_mapping;
++	struct ext3_ext_path *path;
++	struct page * page;
++	handle_t *handle;
++	int i, depth, err = 0;
++
++	ext3_ext_collect_stats(inode);
++
++	/*
++	 * We have to lock the EOF page here, because lock_page() nests
++	 * outside journal_start().
++	 */
++	if ((inode->i_size & (inode->i_sb->s_blocksize - 1)) == 0) {
++		/* Block boundary? Nothing to do */
++		page = NULL;
++	} else {
++		page = grab_cache_page(mapping,
++				inode->i_size >> PAGE_CACHE_SHIFT);
++		if (!page)
++			return;
++	}
++
++	/*
++	 * probably first extent we're gonna free will be last in block
++	 */
++	i = ext3_ext_calc_credits(inode, NULL, 0);
++	handle = ext3_journal_start(inode, i);
++	if (IS_ERR(handle)) {
++		if (page) {
++			clear_highpage(page);
++			flush_dcache_page(page);
++			unlock_page(page);
++			page_cache_release(page);
++		}
++		return;
++	}
++
++	if (page)
++		ext3_block_truncate_page(handle, mapping, inode->i_size, page,
++						inode->i_sb->s_blocksize);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* 
++	 * TODO: optimization is possible here
++	 * probably we need not scaning at all,
++	 * because page truncation is enough
++	 */
++	if (ext3_orphan_add(handle, inode))
++		goto out_stop;
++
++	/* we have to know where to truncate from in crash case */
++	EXT3_I(inode)->i_disksize = inode->i_size;
++	ext3_mark_inode_dirty(handle, inode);
++
++	/*
++	 * we start scanning from right side freeing all the blocks
++	 * after i_size and walking into the deep
++	 */
++	i = 0;
++	depth = EXT3_I(inode)->i_depth;
++	path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL);
++	if (IS_ERR(path)) {
++		ext3_error(inode->i_sb, "ext3_ext_truncate",
++				"Can't allocate path array");
++		goto out_stop;
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	path[i].p_hdr = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	while (i >= 0 && err == 0) {
++		if (i == depth) {
++			/* this is leaf block */
++			err = ext3_ext_truncate_leaf(handle, inode,
++							path + i, i);
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			continue;
++		}
++		
++		/* this is index block */
++		if (!path[i].p_hdr) {
++			path[i].p_hdr =
++				(struct ext3_extent_header *) path[i].p_bh->b_data;
++			ext_debug(inode, "initialize header\n");
++		}
++
++		EXT_ASSERT(path[i].p_hdr->e_num <= path[i].p_hdr->e_max);
++		
++		if (!path[i].p_idx) {
++			/* this level hasn't touched yet */
++			path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr);
++			path[i].p_block = path[i].p_hdr->e_num + 1;
++			ext_debug(inode, "init index ptr: hdr 0x%p, num %d\n",
++					path[i].p_hdr, path[i].p_hdr->e_num);
++		} else {
++			/* we've already was here, see at next index */
++			path[i].p_idx--;
++		}
++
++		ext_debug(inode, "level %d - index, first 0x%p, cur 0x%p\n",
++				i, EXT_FIRST_INDEX(path[i].p_hdr),
++				path[i].p_idx);
++		if (ext3_ext_more_to_truncate(inode, path + i)) {
++			/* go to the next level */
++			ext_debug(inode, "move to level %d (block %d)\n", i+1,
++					path[i].p_idx->e_leaf);
++			memset(path + i + 1, 0, sizeof(*path));
++			path[i+1].p_bh = sb_bread(inode->i_sb,
++							path[i].p_idx->e_leaf);
++			if (!path[i+1].p_bh) {
++				/* should we reset i_size? */
++				err = -EIO;
++				break;
++			}
++			i++;
++		} else {
++			/* we finish processing this index, go up */
++			if (path[i].p_hdr->e_num == 0 && i > 0) {
++				/* index is empty, remove it
++				 * handle must be already prepared by the
++				 * truncate_leaf()
++				 */
++				err = ext3_ext_remove_index(handle, inode,
++								path + i);
++			}
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			ext_debug(inode, "return to level %d\n", i);
++		}
++	}
++
++	/* TODO: flexible tree reduction should be here */
++	if (path->p_hdr->e_num == 0) {
++		/*
++		 * truncate to zero freed all the tree
++		 * so, we need to correct i_depth
++		 */
++		EXT3_I(inode)->i_depth = 0;
++		path->p_hdr->e_max = 0;
++		ext3_mark_inode_dirty(handle, inode);
++	}
++
++	kfree(path);
++
++	/* In a multi-transaction truncate, we only make the final
++	 * transaction synchronous */
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++out_stop:
++	/*
++	 * If this was a simple ftruncate(), and the file will remain alive
++	 * then we need to clear up the orphan record which we created above.
++	 * However, if this was a real unlink then we were called by
++	 * ext3_delete_inode(), and we allow that function to clean up the
++	 * orphan info for us.
++	 */
++	if (inode->i_nlink)
++		ext3_orphan_del(handle, inode);
++
++	up(&EXT3_I(inode)->i_ext_sem);
++	ext3_journal_stop(handle, inode);
++}
++
++/*
++ * this routine calculate max number of blocks we could modify
++ * in order to allocate new block for an inode
++ */
++int ext3_ext_writepage_trans_blocks(struct inode *inode, int num)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	int depth = ei->i_depth + 1;
++	int needed;
++	
++	/*
++	 * the worste case we're expecting is creation of the
++	 * new root (growing in depth) with index splitting
++	 * for splitting we have to consider depth + 1 because
++	 * previous growing could increase it
++	 */
++
++	/* 
++	 * growing in depth:
++	 * block allocation + new root + old root
++	 */
++	needed = EXT3_ALLOC_NEEDED + 2;
++
++	/* index split. we may need:
++	 *   allocate intermediate indexes and new leaf
++	 *   change two blocks at each level, but root
++	 *   modify root block (inode)
++	 */
++	needed += (depth * EXT3_ALLOC_NEEDED) + (2 * depth) + 1;
++
++	/* caller want to allocate num blocks */
++	needed *= num;
++	
++#ifdef CONFIG_QUOTA
++	/* 
++	 * FIXME: real calculation should be here
++	 * it depends on blockmap format of qouta file
++	 */
++	needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS;
++#endif
++
++	return needed;
++}
++
++/*
++ * called at mount time
++ */
++void ext3_ext_init(struct super_block *sb)
++{
++	/*
++	 * possible initialization would be here
++	 */
++
++	if (test_opt(sb, EXTENTS))
++		printk("EXT3-fs: file extents enabled\n");
++	spin_lock_init(&EXT3_SB(sb)->s_ext_lock);
++}
++
++/*
++ * called at umount time
++ */
++void ext3_ext_release(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++
++	/* show collected stats */
++	if (sbi->s_ext_count && sbi->s_ext_extents)
++		printk("EXT3-fs: min depth - %d, max depth - %d, "
++				"ave. depth - %d, ave. blocks/extent - %d\n",
++				sbi->s_ext_mindepth,
++				sbi->s_ext_maxdepth,
++				sbi->s_ext_sum / sbi->s_ext_count,
++				sbi->s_ext_blocks / sbi->s_ext_extents);
++}
++
+--- linux-2.4.18-chaos-pdirops/fs/ext3/ialloc.c~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:53.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/ialloc.c	2003-09-23 14:29:32.000000000 +0400
+@@ -573,6 +573,10 @@ repeat:
+ 	ei->i_prealloc_count = 0;
+ #endif
+ 	ei->i_block_group = i;
++	if (test_opt(sb, EXTENTS))
++		EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL;
++	ei->i_depth = 0;
++	sema_init(&ei->i_ext_sem, 1);
+ 
+ 	if (ei->i_flags & EXT3_SYNC_FL)
+ 		inode->i_flags |= S_SYNC;
+--- linux-2.4.18-chaos-pdirops/fs/ext3/inode.c~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:53.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/inode.c	2003-09-23 14:29:32.000000000 +0400
+@@ -842,6 +842,15 @@ changed:
+ 	goto reread;
+ }
+ 
++static inline int
++ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block,
++		struct buffer_head *bh, int create, int extend_disksize)
++{
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_get_block(handle, inode, block, bh, create, 1);
++	return ext3_get_block_handle(handle, inode, block, bh, create, 1);
++}
++
+ /*
+  * The BKL is not held on entry here.
+  */
+@@ -855,7 +864,7 @@ static int ext3_get_block(struct inode *
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock,
++	ret = ext3_get_block_wrap(handle, inode, iblock,
+ 				bh_result, create, 1);
+ 	return ret;
+ }
+@@ -882,7 +891,7 @@ ext3_direct_io_get_block(struct inode *i
+ 		}
+ 	}
+ 	if (ret == 0)
+-		ret = ext3_get_block_handle(handle, inode, iblock,
++		ret = ext3_get_block_wrap(handle, inode, iblock,
+ 					bh_result, create, 0);
+ 	if (ret == 0)
+ 		bh_result->b_size = (1 << inode->i_blkbits);
+@@ -904,7 +913,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
++	*errp = ext3_get_block_wrap(handle, inode, block, &dummy, create, 1);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1520,7 +1529,7 @@ ext3_block_truncate_page_prepare(struct 
+  * This required during truncate. We need to physically zero the tail end
+  * of that block so it doesn't yield old data if the file is later grown.
+  */
+-static int ext3_block_truncate_page(handle_t *handle,
++int ext3_block_truncate_page(handle_t *handle,
+ 				    struct address_space *mapping, loff_t from,
+ 				    struct page *page, unsigned blocksize)
+ {
+@@ -1998,6 +2007,9 @@ void ext3_truncate(struct inode * inode)
+ 
+ 	ext3_discard_prealloc(inode);
+ 
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_truncate(inode);
++
+ 	blocksize = inode->i_sb->s_blocksize;
+ 	last_block = (inode->i_size + blocksize-1)
+ 					>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
+@@ -2436,6 +2448,8 @@ void ext3_read_inode(struct inode * inod
+ 	ei->i_prealloc_count = 0;
+ #endif
+ 	ei->i_block_group = iloc.block_group;
++	ei->i_depth = raw_inode->osd2.linux2.l_i_depth;
++	sema_init(&ei->i_ext_sem, 1);
+ 
+ 	/*
+ 	 * NOTE! The in-memory inode i_data array is in little-endian order
+@@ -2559,6 +2573,7 @@ static int ext3_do_update_inode(handle_t
+ 		raw_inode->i_fsize = 0;
+ 	}
+ #endif
++ 	raw_inode->osd2.linux2.l_i_depth = ei->i_depth;
+ 	raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
+ 	if (!S_ISREG(inode->i_mode)) {
+ 		raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
+@@ -2762,6 +2777,9 @@ int ext3_writepage_trans_blocks(struct i
+ 	int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
+ 	int ret;
+ 	
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_writepage_trans_blocks(inode, bpp);
++
+ 	if (ext3_should_journal_data(inode))
+ 		ret = 3 * (bpp + indirects) + 2;
+ 	else
+@@ -3085,7 +3103,7 @@ int ext3_prep_san_write(struct inode *in
+ 
+ 	/* alloc blocks one by one */
+ 	for (i = 0; i < nblocks; i++) {
+-		ret = ext3_get_block_handle(handle, inode, blocks[i],
++		ret = ext3_get_block_wrap(handle, inode, blocks[i],
+ 						&bh_tmp, 1, 1);
+ 		if (ret)
+ 			break;
+@@ -3146,7 +3164,7 @@ int ext3_map_inode_page(struct inode *in
+                 if (blocks[i] != 0)
+                         continue;
+ 
+-                rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1, 1);
++                rc = ext3_get_block_wrap(handle, inode, iblock, &dummy, 1, 1);
+                 if (rc) {
+                         printk(KERN_INFO "ext3_map_inode_page: error reading "
+                                "block %ld\n", iblock);
+--- linux-2.4.18-chaos-pdirops/fs/ext3/Makefile~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:48.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/Makefile	2003-09-23 14:29:32.000000000 +0400
+@@ -12,7 +12,8 @@ O_TARGET := ext3.o
+ export-objs :=	ext3-exports.o
+ 
+ obj-y    := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o
++		ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o \
++		extents.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.18-chaos-pdirops/fs/ext3/super.c~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:53.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/super.c	2003-09-23 14:29:33.000000000 +0400
+@@ -619,6 +619,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_ext_release(sb);
+ 	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+@@ -741,6 +742,12 @@ static int parse_options (char * options
+ 		else
+ #endif
+ 
++		if (!strcmp (this_char, "extents"))
++			set_opt (sbi->s_mount_opt, EXTENTS);
++		else
++		if (!strcmp (this_char, "extdebug"))
++			set_opt (sbi->s_mount_opt, EXTDEBUG);
++		else
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -1471,6 +1478,7 @@ struct super_block * ext3_read_super (st
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
+ 		"writeback");
++	ext3_ext_init(sb);
+ 
+ 	if (test_opt(sb, PDIROPS)) {
+ 		printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n");
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_fs.h~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:53.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_fs.h	2003-09-23 14:29:33.000000000 +0400
+@@ -188,6 +188,7 @@ struct ext3_group_desc
+ #define EXT3_IMAGIC_FL			0x00002000 /* AFS directory */
+ #define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
+ #define EXT3_RESERVED_FL		0x80000000 /* reserved for ext3 lib */
++#define EXT3_EXTENTS_FL			0x00080000 /* Inode uses extents */
+ 
+ #define EXT3_FL_USER_VISIBLE		0x00005FFF /* User visible flags */
+ #define EXT3_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+@@ -248,7 +249,7 @@ struct ext3_inode {
+ 		struct {
+ 			__u8	l_i_frag;	/* Fragment number */
+ 			__u8	l_i_fsize;	/* Fragment size */
+-			__u16	i_pad1;
++			__u16	l_i_depth;
+ 			__u16	l_i_uid_high;	/* these 2 fields    */
+ 			__u16	l_i_gid_high;	/* were reserved2[0] */
+ 			__u32	l_i_reserved2;
+@@ -329,6 +330,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_IOPEN		0x8000	/* Allow access via iopen */
+ #define EXT3_MOUNT_IOPEN_NOPRIV		0x10000	/* Make iopen world-readable */
+ #define EXT3_MOUNT_ASYNCDEL		0x20000	/* Delayed deletion */
++#define EXT3_MOUNT_EXTENTS		0x40000	/* Extents support */
++#define EXT3_MOUNT_EXTDEBUG		0x80000	/* Extents debug */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -720,6 +723,12 @@ extern void ext3_discard_prealloc (struc
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++extern int ext3_block_truncate_page(handle_t *handle,
++				    struct address_space *mapping, loff_t from,
++				    struct page *page, unsigned blocksize);
++extern int ext3_forget(handle_t *handle, int is_metadata,
++		       struct inode *inode, struct buffer_head *bh,
++		       int blocknr);
+ #ifdef EXT3_DELETE_THREAD
+ extern void ext3_truncate_thread(struct inode *inode);
+ #endif
+@@ -781,6 +790,13 @@ extern struct inode_operations ext3_dir_
+ /* symlink.c */
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
++/* extents.c */
++extern int ext3_ext_writepage_trans_blocks(struct inode *, int);
++extern int ext3_ext_get_block(handle_t *, struct inode *, long,
++				struct buffer_head *, int, int);
++extern void ext3_ext_truncate(struct inode *);
++extern void ext3_ext_init(struct super_block *);
++extern void ext3_ext_release(struct super_block *);
+ 
+ #endif	/* __KERNEL__ */
+ 
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_fs_i.h~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:44:53.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_fs_i.h	2003-09-23 14:29:33.000000000 +0400
+@@ -79,6 +79,10 @@ struct ext3_inode_info {
+ 	struct dynlock i_htree_lock;
+ 	struct semaphore i_append_sem;
+ 	struct semaphore i_rename_sem;
++
++ 	/* extents-related data */
++ 	struct semaphore i_ext_sem;
++ 	__u16 i_depth;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_I */
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_fs_sb.h~ext3-extents-2.4.18-chaos-pdirops	2003-09-23 13:34:51.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_fs_sb.h	2003-09-23 14:29:33.000000000 +0400
+@@ -86,6 +86,16 @@ struct ext3_sb_info {
+ 	wait_queue_head_t s_delete_thread_queue;
+ 	wait_queue_head_t s_delete_waiter_queue;
+ #endif
++
++	/* extents */
++	int s_ext_debug;
++	int s_ext_mindepth;
++	int s_ext_maxdepth;
++	int s_ext_sum;
++	int s_ext_count;
++	spinlock_t s_ext_lock;
++	int s_ext_extents;
++	int s_ext_blocks;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a0ff220de06fdaeebf20f2f29a964f7863ac3a50
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch
@@ -0,0 +1,1879 @@
+ fs/ext3/Makefile           |    3 
+ fs/ext3/extents.c          | 1615 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/ialloc.c           |    4 
+ fs/ext3/inode.c            |   30 
+ fs/ext3/super.c            |    8 
+ include/linux/ext3_fs.h    |   18 
+ include/linux/ext3_fs_i.h  |    4 
+ include/linux/ext3_fs_sb.h |   10 
+ 8 files changed, 1684 insertions(+), 8 deletions(-)
+
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-chaos-alexey/fs/ext3/extents.c	2003-09-23 18:08:59.000000000 +0400
+1inux/fs/ext3/extents.c
++ *
++ * Extents support for EXT3
++ *
++ * 07/08/2003    Alex Tomas <bzzz@tmi.comex.ru>
++ * 
++ * TODO:
++ *   - ext3*_error() should be used in some situations
++ *   - find_goal() [to be tested and improved]
++ *   - error handling
++ *   - we could leak allocated block in some error cases
++ *   - quick search for index/leaf in ext3_ext_find_extent()
++ *   - tree reduction
++ *   - cache last found extent
++ *   - arch-independent
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/time.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/smp_lock.h>
++#include <linux/highuid.h>
++#include <linux/pagemap.h>
++#include <linux/quotaops.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/locks.h>
++
++/*
++ * with AGRESSIVE_TEST defined capacity of index/leaf blocks
++ * become very little, so index split, in-depth growing and
++ * other hard changes happens much more often
++ * this is for debug purposes only
++ */
++#define AGRESSIVE_TEST_
++
++/*
++ * if EXT_DEBUG defined you can use 'extdebug' mount option
++ * to get lots of info what's going on
++ */
++#define EXT_DEBUG
++#ifdef EXT_DEBUG
++#define ext_debug(inode,fmt,a...) 		\
++do {						\
++	if (test_opt((inode)->i_sb, EXTDEBUG))	\
++		printk(fmt, ##a);		\
++} while (0);
++#else
++#define ext_debug(inode,fmt,a...)
++#endif
++
++#define EXT3_ALLOC_NEEDED	2	/* block bitmap + group descriptor */
++
++/*
++ * ext3_inode has i_block array (total 60 bytes)
++ * first 4 bytes are used to store:
++ *  - tree depth (0 mean there is no tree yet. all extents in the inode)
++ *  - number of alive extents in the inode
++ */
++
++/*
++ * this is extent on-disk structure
++ * it's used at the bottom of the tree
++ */
++struct ext3_extent {
++	__u32	e_block;	/* first logical block extent covers */
++	__u32	e_start;	/* first physical block extents lives */
++	__u32	e_num;		/* number of blocks covered by extent */
++};
++
++/*
++ * this is index on-disk structure
++ * it's used at all the levels, but the bottom
++ */
++struct ext3_extent_idx {
++	__u32	e_block;	/* index covers logical blocks from 'block' */
++	__u32	e_leaf;		/* pointer to the physical block of the next *
++				 * level. leaf or next index could bet here */
++};
++
++/*
++ * each block (leaves and indexes), even inode-stored has header
++ */
++struct ext3_extent_header {	
++	__u16	e_num;		/* number of valid entries */
++	__u16	e_max;		/* capacity of store in entries */
++};
++
++/*
++ * array of ext3_ext_path contains path to some extent
++ * creation/lookup routines use it for traversal/splitting/etc
++ * truncate uses it to simulate recursive walking
++ */
++struct ext3_ext_path {
++	__u32				p_block;
++	__u16				p_depth;
++	struct ext3_extent		*p_ext;
++	struct ext3_extent_idx		*p_idx;
++	struct ext3_extent_header	*p_hdr;
++	struct buffer_head		*p_bh;
++};
++
++#define EXT_FIRST_EXTENT(__hdr__) \
++	((struct ext3_extent *) (((char *) (__hdr__)) +		\
++				 sizeof(struct ext3_extent_header)))
++#define EXT_FIRST_INDEX(__hdr__) \
++	((struct ext3_extent_idx *) (((char *) (__hdr__)) +	\
++				     sizeof(struct ext3_extent_header)))
++#define EXT_HAS_FREE_INDEX(__path__) \
++	((__path__)->p_hdr->e_num < (__path__)->p_hdr->e_max)
++#define EXT_LAST_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_LAST_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_MAX_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_max - 1)
++#define EXT_MAX_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_max - 1)
++
++
++#define EXT_ASSERT(__x__) if (!(__x__)) BUG();
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ */
++static int ext3_ext_get_access(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_get_write_access(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return 0;
++}
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ *  - EIO
++ */
++static int ext3_ext_dirty(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_dirty_metadata(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return ext3_mark_inode_dirty(handle, inode);
++}
++
++static inline int ext3_ext_space_block(struct inode *inode)
++{
++	int size;
++
++	size = (inode->i_sb->s_blocksize - sizeof(struct ext3_extent_header))
++		/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 6; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 3; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode_idx(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent_idx);
++#ifdef AGRESSIVE_TEST
++	size = 4; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static void ext3_ext_show_path(struct inode *inode, struct ext3_ext_path *path)
++{
++	int k, l = path->p_depth;
++
++	ext_debug(inode, "path:");
++	for (k = 0; k <= l; k++, path++) {
++		if (path->p_idx) {
++			ext_debug(inode, "  %d->%d", path->p_idx->e_block,
++					path->p_idx->e_leaf);
++		} else if (path->p_ext) {
++			ext_debug(inode, "  %d:%d:%d",
++					path->p_ext->e_block,
++					path->p_ext->e_start,
++					path->p_ext->e_num);
++		} else
++			ext_debug(inode, "  []");
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_show_leaf(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *eh = path[depth].p_hdr;
++	struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
++	int i;
++
++	for (i = 0; i < eh->e_num; i++, ex++) {
++		ext_debug(inode, "%d:%d:%d ",
++				ex->e_block, ex->e_start, ex->e_num);
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_drop_refs(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = path->p_depth;
++	int i;
++
++	for (i = 0; i <= depth; i++, path++)
++		if (path->p_bh) {
++			brelse(path->p_bh);
++			path->p_bh = NULL;
++		}
++}
++
++static int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	unsigned long bg_start;
++	unsigned long colour;
++	int depth;
++	
++	if (path) {
++		depth = path->p_depth;
++		/* try to find previous block */
++		if (path[depth].p_ext)
++			return path[depth].p_ext->e_start +
++				path[depth].p_ext->e_num - 1;
++		
++		/* it looks index is empty
++		 * try to find starting from index itself */
++		if (path[depth].p_bh)
++			return path[depth].p_bh->b_blocknr;
++	}
++
++	/* OK. use inode's group */
++	bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
++		le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
++	colour = (current->pid % 16) *
++			(EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16);
++	return bg_start + colour;
++}
++
++static struct ext3_ext_path *
++ext3_ext_find_extent(struct inode *inode, int block, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	struct ext3_extent_header *eh = (void *) ei->i_data;
++	struct ext3_extent_idx *ix;
++	struct buffer_head *bh;
++	struct ext3_extent *ex;
++	int depth, i, k, ppos = 0, prev = 0;
++	
++	eh = (struct ext3_extent_header *) ei->i_data;
++
++	/* initialize capacity of leaf in inode for first time */
++	if (eh->e_max == 0)
++		eh->e_max = ext3_ext_space_inode(inode);
++	i = depth = ei->i_depth;
++	EXT_ASSERT(i == 0 || eh->e_num > 0);
++	
++	/* account possible depth increase */
++	if (!path) {
++		path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2),
++				GFP_NOFS);
++		if (!path)
++			return ERR_PTR(-ENOMEM);
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	/* walk through the tree */
++	while (i) {
++		ext_debug(inode, "depth %d: num %d, max %d\n",
++				ppos, eh->e_num, eh->e_max);
++		ix = EXT_FIRST_INDEX(eh);
++		if (eh->e_num) {
++			EXT_ASSERT(prev == 0 || ix->e_block == prev);
++			path[ppos].p_idx = ix;
++		}
++		EXT_ASSERT(eh->e_num <= eh->e_max);
++		for (k = 0; k < eh->e_num; k++, ix++) {
++			ext_debug(inode, "index: %d -> %d\n",
++					ix->e_block, ix->e_leaf);
++			EXT_ASSERT((k == 0 && prev <= (int)ix->e_block) ||
++					(k > 0 && prev < (int)ix->e_block));
++			if (block < ix->e_block)
++				break;
++			prev = ix->e_block;
++			path[ppos].p_idx = ix;
++		}
++		path[ppos].p_block = path[ppos].p_idx->e_leaf;
++		path[ppos].p_depth = i;
++		path[ppos].p_hdr = eh;
++		path[ppos].p_ext = NULL;
++
++		bh = sb_bread(inode->i_sb, path[ppos].p_block);
++		if (!bh) {
++			ext3_ext_drop_refs(inode, path);
++			kfree(path);
++			return ERR_PTR(-EIO);
++		}
++		eh = (struct ext3_extent_header *) bh->b_data;
++		ppos++;
++		EXT_ASSERT(ppos <= depth);
++		path[ppos].p_bh = bh;
++		i--;
++	}
++
++	path[ppos].p_depth = i;
++	path[ppos].p_hdr = eh;
++	path[ppos].p_ext = NULL;
++	
++	/* find extent */
++	ex = EXT_FIRST_EXTENT(eh);
++	if (eh->e_num)
++		path[ppos].p_ext = ex;
++	EXT_ASSERT(eh->e_num <= eh->e_max);
++	for (k = 0; k < eh->e_num; k++, ex++) {
++		EXT_ASSERT(ex->e_num < EXT3_BLOCKS_PER_GROUP(inode->i_sb));
++		EXT_ASSERT((k == 0 && prev <= (int)ex->e_block) ||
++				(k > 0 && prev < (int)ex->e_block));
++		if (block < ex->e_block) 
++			break;
++		prev = ex->e_block;
++		path[ppos].p_ext = ex;
++	}
++
++	ext3_ext_show_path(inode, path);
++
++	return path;
++}
++
++static void ext3_ext_check_boundary(struct inode *inode,
++					struct ext3_ext_path *curp,
++					void *addr, int len)
++{
++	void *end;
++
++	if (!len)
++		return;
++	if (curp->p_bh)
++		end = (void *) curp->p_hdr + inode->i_sb->s_blocksize;
++	else
++		end = (void *) curp->p_hdr + sizeof(EXT3_I(inode)->i_data);
++	if (((unsigned long) addr) + len > (unsigned long) end) {
++		printk("overflow! 0x%p > 0x%p\n", addr + len, end);
++		BUG();
++	}
++	if ((unsigned long) addr < (unsigned long) curp->p_hdr) {
++		printk("underflow! 0x%p < 0x%p\n", addr, curp->p_hdr);
++		BUG();
++	}
++}
++
++/*
++ * insert new index [logical;ptr] into the block at cupr
++ * it check where to insert: before curp or after curp
++ */
++static int ext3_ext_insert_index(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *curp, int logical,
++				int ptr)
++{
++	struct ext3_extent_idx *ix;
++	int len, err;
++
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		return err;
++
++	EXT_ASSERT(logical != curp->p_idx->e_block);
++	len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
++	if (logical > curp->p_idx->e_block) {
++		/* insert after */
++		len = (len - 1) * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d after: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				(curp->p_idx + 1), (curp->p_idx + 2));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 2, len);
++		memmove(curp->p_idx + 2, curp->p_idx + 1, len);
++		ix = curp->p_idx + 1;
++	} else {
++		/* insert before */
++		len = len * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d before: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				curp->p_idx, (curp->p_idx + 1));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 1, len);
++		memmove(curp->p_idx + 1, curp->p_idx, len);
++		ix = curp->p_idx;
++	}
++
++	ix->e_block = logical;
++	ix->e_leaf = ptr;
++	curp->p_hdr->e_num++;
++
++	err = ext3_ext_dirty(handle, inode, curp);
++	ext3_std_error(inode->i_sb, err);
++
++	return err;
++}
++
++/*
++ * routine inserts new subtree into the path, using free index entry
++ * at depth 'at:
++ *  - allocates all needed blocks (new leaf and all intermediate index blocks)
++ *  - makes decision where to split
++ *  - moves remaining extens and index entries (right to the split point)
++ *    into the newly allocated blocks
++ *  - initialize subtree
++ */
++static int ext3_ext_split(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext, int at)
++{
++	struct buffer_head *bh = NULL;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	struct ext3_extent *ex;
++	int i = at, k, m, a;
++	long newblock, oldblock, border;
++	int *ablocks = NULL; /* array of allocated blocks */
++	int err = 0;
++
++	/* make decision: where to split? */
++	/* FIXME: now desicion is simplest: at current extent */
++
++	/* if current leaf will be splitted, then we should use 
++	 * border from split point */
++	
++	if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		border = path[depth].p_ext[1].e_block;
++		ext_debug(inode, "leaf will be splitted."
++				" next leaf starts at %d\n",
++				(int)border);
++	} else {
++		border = newext->e_block;
++		ext_debug(inode, "leaf will be added."
++				" next leaf starts at %d\n",
++				(int)border);
++	}
++
++	/* 
++	 * if error occurs, then we break processing
++	 * and turn filesystem read-only. so, index won't
++	 * be inserted and tree will be in consistent
++	 * state. next mount will repair buffers too
++	 */
++
++	/*
++	 * get array to track all allocated blocks
++	 * we need this to handle errors and free blocks
++	 * upon them
++	 */
++	ablocks = kmalloc(sizeof(long) * depth, GFP_NOFS);
++	if (!ablocks)
++		return -ENOMEM;
++	memset(ablocks, 0, sizeof(long) * depth);
++
++	/* allocate all needed blocks */
++	ext_debug(inode, "allocate %d blocks for indexes/leaf\n", depth - at);
++	newblock = 0; /* FIXME: something more sophisticated needed here */ 
++	for (a = 0; newext->e_num > 0 && a < depth - at; a++) {
++		newblock = ablocks[a] = newext->e_start++;
++		newext->e_num--;
++	}
++	for (; a < depth - at; a++) {
++		newblock = ext3_new_block(handle, inode,
++						newblock + 1, 0, 0, &err);
++		if (newblock == 0)
++			goto cleanup;
++		ablocks[a] = newblock;
++	}
++
++	/* initialize new leaf */
++	newblock = ablocks[--a];
++	EXT_ASSERT(newblock);
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		goto cleanup;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh)))
++		goto cleanup;
++
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_num = 0;
++	neh->e_max = ext3_ext_space_block(inode);
++	ex = EXT_FIRST_EXTENT(neh);
++
++	/* move remain of path[depth] to the new leaf */
++	EXT_ASSERT(path[depth].p_hdr->e_num ==
++			path[depth].p_hdr->e_max);
++	/* start copy from next extent */
++	/* TODO: we could do it by single memmove */
++	m = 0;
++	path[depth].p_ext++;
++	while (path[depth].p_ext <=
++			EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		ext_debug(inode, "move %d:%d:%d in new leaf\n",
++				path[depth].p_ext->e_block,
++				path[depth].p_ext->e_start,
++				path[depth].p_ext->e_num);
++		memmove(ex++, path[depth].p_ext++,
++				sizeof(struct ext3_extent));
++		neh->e_num++;
++		m++;
++	}
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto cleanup;	
++	brelse(bh);
++	bh = NULL;
++
++	/* correct old leaf */
++	if (m) {
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			goto cleanup;
++		path[depth].p_hdr->e_num -= m;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			goto cleanup;
++		
++	}
++
++	/* create intermediate indexes */
++	k = depth - at - 1;
++	EXT_ASSERT(k >= 0);
++	if (k)
++		ext_debug(inode,
++				"create %d intermediate indices\n", k);
++	/* insert new index into current index block */
++	/* current depth stored in i var */
++	i = depth - 1;
++	while (k--) {
++		oldblock = newblock;
++		newblock = ablocks[--a];
++		bh = sb_getblk(inode->i_sb, newblock);
++		if (!bh) {
++			err = -EIO;
++			goto cleanup;
++		}
++		lock_buffer(bh);
++
++		if ((err = ext3_journal_get_create_access(handle, bh)))
++			goto cleanup;
++
++		neh = (struct ext3_extent_header *) bh->b_data;
++		neh->e_num = 1;
++		neh->e_max = ext3_ext_space_block(inode);
++		fidx = EXT_FIRST_INDEX(neh);
++		fidx->e_block = border;
++		fidx->e_leaf = oldblock;
++
++		ext_debug(inode,
++				"int.index at %d (block %u): %d -> %d\n",
++				i, (unsigned) newblock,
++				(int) border,
++				(int) oldblock);
++		/* copy indexes */
++		m = 0;
++		path[i].p_idx++;
++		ext_debug(inode, "cur 0x%p, last 0x%p\n", path[i].p_idx,
++				EXT_MAX_INDEX(path[i].p_hdr));
++		EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) ==
++				EXT_LAST_INDEX(path[i].p_hdr));
++		while (path[i].p_idx <=
++				EXT_MAX_INDEX(path[i].p_hdr)) {
++			ext_debug(inode, "%d: move %d:%d in new index\n",
++					i, path[i].p_idx->e_block,
++					path[i].p_idx->e_leaf);
++			memmove(++fidx, path[i].p_idx++,
++					sizeof(struct ext3_extent_idx));
++			neh->e_num++;
++			m++;
++		}
++
++		mark_buffer_uptodate(bh, 1);
++		unlock_buffer(bh);
++
++		if ((err = ext3_journal_dirty_metadata(handle, bh)))
++			goto cleanup;
++		brelse(bh);
++		bh = NULL;
++
++		/* correct old index */
++		if (m) {
++			err = ext3_ext_get_access(handle,inode,path+i);
++			if (err)
++				goto cleanup;
++			path[i].p_hdr->e_num -= m;
++			err = ext3_ext_dirty(handle, inode, path + i);
++			if (err)
++				goto cleanup;
++		}
++
++		i--;
++	}
++
++	/* insert new index */
++	if (!err)
++		err = ext3_ext_insert_index(handle, inode, path + at,
++						border, newblock);
++
++cleanup:
++	if (bh) {
++		if (buffer_locked(bh))
++			unlock_buffer(bh);
++		brelse(bh);
++	}
++
++	if (err) {
++		/* free all allocated blocks in error case */
++		for (i = 0; i < depth; i++)
++			if (!ablocks[i])
++				continue;
++			ext3_free_blocks(handle, inode, ablocks[i], 1);
++	}
++	kfree(ablocks);
++
++	return err;
++}
++
++/*
++ * routine implements tree growing procedure:
++ *  - allocates new block
++ *  - moves top-level data (index block or leaf) into the new block
++ *  - initialize new top-level, creating index that points to the
++ *    just created block
++ */
++static int ext3_ext_grow_indepth(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	struct buffer_head *bh;
++	struct ext3_ext_path *curp = path;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	int len, err = 0;
++	long newblock;
++
++	/*
++	 * use already allocated by the called block for new root block
++	 */
++	newblock = newext->e_start++;
++	if (newext->e_num == 0) {
++		/* 
++		 * FIXME: if this may happen, then we have to handle
++		 * possible error and free allocated block
++		 */
++		printk("grow_indepth with zero blocks\n");
++		newblock = ext3_new_block(handle, inode,
++						newblock, 0, 0, &err);
++	} else
++		newext->e_num--;
++	
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		ext3_std_error(inode->i_sb, err);
++		return err;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh))) {
++		unlock_buffer(bh);
++		goto out;	
++	}
++
++	/* move top-level index/leaf into new block */
++	len = sizeof(struct ext3_extent_header) +
++		sizeof(struct ext3_extent) * curp->p_hdr->e_max;
++	EXT_ASSERT(len >= 0 && len < 4096);
++	memmove(bh->b_data, curp->p_hdr, len);
++
++	/* set size of new block */
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_max = ext3_ext_space_block(inode);
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto out;
++
++	/* create index in new top-level index: num,max,pointer */
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		goto out;
++
++	curp->p_hdr->e_max = ext3_ext_space_inode_idx(inode);
++	curp->p_hdr->e_num = 1;
++	curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
++	curp->p_idx->e_block = EXT_FIRST_EXTENT(path[0].p_hdr)->e_block;
++	curp->p_idx->e_leaf = newblock;
++
++	neh = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	fidx = EXT_FIRST_INDEX(neh);
++	ext_debug(inode, "new root: num %d(%d), lblock %d, ptr %d\n",
++			neh->e_num, neh->e_max, fidx->e_block, fidx->e_leaf); 
++
++	EXT3_I(inode)->i_depth++;
++	err = ext3_ext_dirty(handle, inode, curp);
++out:
++	brelse(bh);
++
++	return err;
++}
++
++/*
++ * routine finds empty index and adds new leaf. if no free index found
++ * then it requests in-depth growing
++ */
++static int ext3_ext_create_new_leaf(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	long newblock = newext->e_start;
++	struct ext3_ext_path *curp;
++	int depth, i, err = 0;
++
++repeat:
++	i = depth = EXT3_I(inode)->i_depth;
++	
++	/* walk up to the tree and look for free index entry */
++	curp = path + depth;
++	while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
++		i--;
++		curp--;
++	}
++
++	/* we use already allocated block for index block
++	 * so, subsequent data blocks should be contigoues */
++	if (EXT_HAS_FREE_INDEX(curp)) {
++		/* if we found index with free entry, then use that
++		 * entry: create all needed subtree and add new leaf */
++		err = ext3_ext_split(handle, inode, path, newext, i);
++
++		/* refill path */
++		ext3_ext_drop_refs(inode, path);
++		path = ext3_ext_find_extent(inode, newext->e_block, path);
++		if (IS_ERR(path))
++			err = PTR_ERR(path);
++	} else {
++		/* tree is full, time to grow in depth */
++		err = ext3_ext_grow_indepth(handle, inode, path, newext);
++
++		/* refill path */
++		ext3_ext_drop_refs(inode, path);
++		path = ext3_ext_find_extent(inode, newext->e_block, path);
++		if (IS_ERR(path))
++			err = PTR_ERR(path);
++	
++		/*
++		 * only first (depth 0 -> 1) produces free space
++		 * in all other cases we have to split growed tree
++		 */
++		depth = EXT3_I(inode)->i_depth;
++		if (path[depth].p_hdr->e_num == path[depth].p_hdr->e_max) {
++			/* now we need split */
++			goto repeat;
++		}
++	}
++
++	if (err)
++		return err;
++
++	/*
++	 * probably we've used some blocks from extent
++	 * let's allocate new block for it
++	 */
++	if (newext->e_num == 0 && !err) {
++		newext->e_start =
++			ext3_new_block(handle, inode, newblock,
++					0, 0, &err);
++		if (newext->e_start != 0)
++			newext->e_num = 1;
++	}
++
++	return 0;
++}
++
++/*
++ * returns next allocated block or 0xffffffff
++ * NOTE: it consider block number from index entry as
++ * allocated block. thus, index entries have to be consistent
++ * with leafs
++ */
++static inline unsigned ext3_ext_next_allocated_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	if (depth == 0 && path->p_ext == NULL)
++		return 0xffffffff;
++
++	/* FIXME: what if index isn't full ?! */
++	while (depth >= 0) {
++		if (depth == path->p_depth) {
++			/* leaf */
++			if (path[depth].p_ext !=
++					EXT_LAST_EXTENT(path[depth].p_hdr))
++				return path[depth].p_ext[1].e_block;
++		} else {
++			/* index */
++			if (path[depth].p_idx !=
++					EXT_LAST_INDEX(path[depth].p_hdr))
++				return path[depth].p_idx[1].e_block;
++		}
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * returns first allocated block from next leaf or 0xffffffff
++ */
++static unsigned ext3_ext_next_leaf_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	/* zero-tree has no leaf blocks at all */
++	if (depth == 0)
++		return 0xffffffff;
++
++	/* go to index block */
++	depth--;
++	
++	while (depth >= 0) {
++		if (path[depth].p_idx !=
++				EXT_LAST_INDEX(path[depth].p_hdr))
++			return path[depth].p_idx[1].e_block;
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * if leaf gets modified and modified extent is first in the leaf
++ * then we have to correct all indexes above
++ * TODO: do we need to correct tree in all cases?
++ */
++int ext3_ext_correct_indexes(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;	
++	struct ext3_extent_header *eh;
++	struct ext3_extent *ex;
++	long border;
++	int k, err = 0;
++	
++	eh = path[depth].p_hdr;
++	ex = path[depth].p_ext;
++
++	EXT_ASSERT(ex);
++	EXT_ASSERT(eh);
++	
++	if (depth == 0) {
++		/* there is no tree at all */
++		return 0;
++	}
++	
++	if (ex != EXT_FIRST_EXTENT(eh)) {
++		/* we correct tree if first leaf got modified only */
++		return 0;
++	}
++	
++	/*
++	 * TODO: we need correction if border is smaller then current one
++	 */
++	k = depth - 1;
++	border = path[depth].p_ext->e_block;
++	if ((err = ext3_ext_get_access(handle, inode, path + k)))
++		return err;
++	path[k].p_idx->e_block = border;
++	if ((err = ext3_ext_dirty(handle, inode, path + k)))
++		return err;
++
++	while (k--) {
++		/* change all left-side indexes */
++		if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr))
++			break;
++		if ((err = ext3_ext_get_access(handle, inode, path + k)))
++			break;
++		path[k].p_idx->e_block = border;
++		if ((err = ext3_ext_dirty(handle, inode, path + k)))
++			break;
++	}
++
++	return err;
++}
++
++/*
++ * this routine tries to merge requsted extent into the existing
++ * extent or inserts requested extent as new one into the tree,
++ * creating new leaf in no-space case
++ */
++int ext3_ext_insert_extent(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext)
++{
++	int depth, len;
++	struct ext3_extent_header * eh;
++	struct ext3_extent *ex;
++	struct ext3_extent *nearex; /* nearest extent */
++	struct ext3_ext_path *npath = NULL;
++	int err;
++
++	depth = EXT3_I(inode)->i_depth;	
++	if ((ex = path[depth].p_ext)) {
++		/* try to insert block into found extent and return */
++		if (ex->e_block + ex->e_num == newext->e_block &&
++				ex->e_start + ex->e_num == newext->e_start) {
++#ifdef AGRESSIVE_TEST
++			if (ex->e_num >= 2)
++				goto repeat;
++#endif
++			if ((err = ext3_ext_get_access(handle, inode,
++							path + depth)))
++				return err;
++			ext_debug(inode, "append %d block to %d:%d (from %d)\n",
++					newext->e_num, ex->e_block, ex->e_num,
++					ex->e_start);
++			ex->e_num += newext->e_num;
++			err = ext3_ext_dirty(handle, inode, path + depth);
++			return err;
++		}
++	}
++
++repeat:
++	depth = EXT3_I(inode)->i_depth;	
++	eh = path[depth].p_hdr;
++	if (eh->e_num == eh->e_max) {
++		/* probably next leaf has space for us? */
++		int next = ext3_ext_next_leaf_block(inode, path);
++		if (next != 0xffffffff) {
++			ext_debug(inode, "next leaf block - %d\n", next);
++			EXT_ASSERT(!npath);
++			npath = ext3_ext_find_extent(inode, next, NULL);
++			if (IS_ERR(npath))
++				return PTR_ERR(npath);
++			EXT_ASSERT(npath->p_depth == path->p_depth);
++			eh = npath[depth].p_hdr;
++			if (eh->e_num < eh->e_max) {
++				ext_debug(inode,
++						"next leaf has free ext(%d)\n",
++						eh->e_num);
++				path = npath;
++				goto repeat;
++			}
++			ext_debug(inode, "next leaf hasno free space(%d,%d)\n",
++					eh->e_num, eh->e_max);
++		}
++		/*
++		 * there is no free space in found leaf
++		 * we're gonna add new leaf in the tree
++		 */
++		err = ext3_ext_create_new_leaf(handle, inode, path, newext);
++		if (err)
++			goto cleanup;
++		goto repeat;
++	}
++
++	nearex = path[depth].p_ext;
++
++	if ((err = ext3_ext_get_access(handle, inode, path + depth)))
++		goto cleanup;
++
++	if (!nearex) {
++		/* there is no extent in this leaf, create first one */
++		ext_debug(inode, "first extent in the leaf: %d:%d:%d\n",
++				newext->e_block, newext->e_start,
++				newext->e_num);
++		path[depth].p_ext = EXT_FIRST_EXTENT(eh);
++	} else if (newext->e_block > nearex->e_block) {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = EXT_MAX_EXTENT(eh) - nearex;
++		len = (len - 1) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d after: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		ext3_ext_check_boundary(inode, path + depth, nearex + 2, len);
++		memmove(nearex + 2, nearex + 1, len);
++		path[depth].p_ext = nearex + 1;
++	} else {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d before: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		
++		memmove(nearex + 1, nearex, len);
++		path[depth].p_ext = nearex;
++	}
++
++	if (!err) {
++		eh->e_num++;
++		nearex = path[depth].p_ext;
++		nearex->e_block = newext->e_block;
++		nearex->e_start = newext->e_start;
++		nearex->e_num = newext->e_num;
++		EXT_ASSERT(nearex->e_num < EXT3_BLOCKS_PER_GROUP(inode->i_sb) &&
++				nearex->e_num > 0);
++
++		/* time to correct all indexes above */
++		err = ext3_ext_correct_indexes(handle, inode, path);
++	}
++
++	err = ext3_ext_dirty(handle, inode, path + depth);
++
++cleanup:
++	if (npath) {
++		ext3_ext_drop_refs(inode, npath);
++		kfree(npath);
++	}
++		
++	return err;
++}
++
++int ext3_ext_get_block(handle_t *handle, struct inode *inode, long iblock,
++			struct buffer_head *bh_result, int create,
++			int extend_disksize)
++{
++	struct ext3_ext_path *path;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent newex;
++	struct ext3_extent *ex;
++	int goal, newblock, err = 0;
++
++	ext_debug(inode, "block %d requested for inode %u, bh_result 0x%p\n",
++			(int) iblock, (unsigned) inode->i_ino, bh_result);
++	bh_result->b_state &= ~(1UL << BH_New);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* find extent for this block */
++	path = ext3_ext_find_extent(inode, iblock, NULL);
++	if (IS_ERR(path)) {
++		err = PTR_ERR(path);
++		goto out2;
++	}
++
++	if ((ex = path[depth].p_ext)) {
++		/* if found exent covers block, simple return it */
++		if (iblock >= ex->e_block && iblock < ex->e_block + ex->e_num) {
++			newblock = iblock - ex->e_block + ex->e_start;
++			ext_debug(inode, "%d fit into %d:%d -> %d\n",
++					(int) iblock, ex->e_block, ex->e_num,
++					newblock);
++			goto out;
++		}
++	}
++
++	/*
++	 * we couldn't try to create block if create flag is zero 
++	 */
++	if (!create) 
++		goto out2;
++
++	/* allocate new block */
++	goal = ext3_ext_find_goal(inode, path);
++	newblock = ext3_new_block(handle, inode, goal, 0, 0, &err);
++	if (!newblock)
++		goto out2;
++	ext_debug(inode, "allocate new block: goal %d, found %d\n",
++			goal, newblock);
++
++	/* try to insert new extent into found leaf and return */
++	newex.e_block = iblock;
++	newex.e_start = newblock;
++	newex.e_num = 1;
++	err = ext3_ext_insert_extent(handle, inode, path, &newex);
++	if (err)
++		goto out2;
++	
++	/* previous routine could use block we allocated */
++	newblock = newex.e_start;
++	bh_result->b_state |= (1UL << BH_New);
++
++out:
++	ext3_ext_show_leaf(inode, path);
++	bh_result->b_dev = inode->i_dev;
++	bh_result->b_blocknr = newblock;
++	bh_result->b_state |= (1UL << BH_Mapped);
++out2:
++	ext3_ext_drop_refs(inode, path);
++	kfree(path);
++	up(&EXT3_I(inode)->i_ext_sem);
++
++	return err;	
++}
++
++/*
++ * returns 1 if current index have to be freed (even partial)
++ */
++static int ext3_ext_more_to_truncate(struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	EXT_ASSERT(path->p_idx);
++
++	if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr))
++		return 0;
++
++	/*
++	 * if truncate on deeper level happened it it wasn't partial
++	 * so we have to consider current index for truncation
++	 */
++	if (path->p_hdr->e_num == path->p_block)
++		return 0;
++
++	/*
++	 * put actual number of indexes to know is this number got
++	 * changed at the next iteration
++	 */
++	path->p_block = path->p_hdr->e_num;
++	
++	return 1;
++}
++
++/*
++ * routine removes index from the index block
++ * it's used in truncate case only. thus all requests are for
++ * last index in the block only
++ */
++int ext3_ext_remove_index(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	struct buffer_head *bh;
++	int err;
++	
++	/* free index block */
++	path--;
++	EXT_ASSERT(path->p_hdr->e_num);
++	if ((err = ext3_ext_get_access(handle, inode, path)))
++		return err;
++	path->p_hdr->e_num--;
++	if ((err = ext3_ext_dirty(handle, inode, path)))
++		return err;
++	bh = sb_get_hash_table(inode->i_sb, path->p_idx->e_leaf);
++	ext3_forget(handle, 0, inode, bh, path->p_idx->e_leaf);
++	ext3_free_blocks(handle, inode, path->p_idx->e_leaf, 1);
++
++	ext_debug(inode, "index is empty, remove it, free block %d\n",
++			path->p_idx->e_leaf);
++	return err;
++}
++
++/*
++ * returns 1 if current extent needs to be freed (even partial)
++ * instead, returns 0
++ */
++int ext3_ext_more_leaves_to_truncate(struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	struct ext3_extent *ex = path->p_ext;
++	int last_block; 
++
++	EXT_ASSERT(ex);
++
++	/* is there leave in the current leaf? */
++	if (ex < EXT_FIRST_EXTENT(path->p_hdr))
++		return 0;
++	
++	last_block = (inode->i_size + blocksize-1)
++			>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++
++	if (last_block >= ex->e_block + ex->e_num)
++		return 0;
++
++	/* seems it extent have to be freed */
++	return 1;
++}
++
++handle_t *ext3_ext_journal_restart(handle_t *handle, int needed)
++{
++	int err;
++
++	if (handle->h_buffer_credits > needed)
++		return handle;
++	if (!ext3_journal_extend(handle, needed))
++		return handle;
++	err = ext3_journal_restart(handle, needed);
++	
++	return handle;
++}
++
++/*
++ * this routine calculate max number of blocks to be modified
++ * while freeing extent and is intended to be used in truncate path
++ */
++static int ext3_ext_calc_credits(struct inode *inode,
++					struct ext3_ext_path *path,
++					int num)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	int needed;
++	
++	/*
++	 * extent couldn't cross group, so we will modify
++	 * single bitmap block and single group descriptor
++	 */
++	needed = 3;
++
++	/*
++	 * if this is last extent in a leaf, then we have to
++	 * free leaf block and remove pointer from index above.
++	 * that pointer could be last in index block, so we'll
++	 * have to remove it too. this way we could modify/free
++	 * the whole path + root index (inode stored) will be
++	 * modified
++	 */
++	if (!path || (num == path->p_ext->e_num &&
++				path->p_ext == EXT_FIRST_EXTENT(path->p_hdr)))
++		needed += (depth * (EXT3_ALLOC_NEEDED + 1)) + 1;
++
++	return needed;
++}
++
++/*
++ * core of the truncate procedure:
++ * - calculated what part of each extent in the requested leaf
++ *   need to be freed
++ * - frees and forgets these blocks
++ *
++ * TODO: we could optimize and free several extents during
++ *       single journal_restart()-journal_restart() cycle
++ */
++static int ext3_ext_truncate_leaf(handle_t *handle,
++					struct inode *inode,
++					struct ext3_ext_path *path,
++					int depth)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	int last_block; 
++	int i, err = 0, sf, num;
++
++	ext_debug(inode, "level %d - leaf\n", depth);
++	if (!path->p_hdr)
++		path->p_hdr =
++			(struct ext3_extent_header *) path->p_bh->b_data;
++
++	EXT_ASSERT(path->p_hdr->e_num <= path->p_hdr->e_max);
++	
++	last_block = (inode->i_size + blocksize-1)
++					>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++	path->p_ext = EXT_LAST_EXTENT(path->p_hdr);
++	while (ext3_ext_more_leaves_to_truncate(inode, path)) {
++
++		/* what part of extent have to be freed? */
++		sf = last_block > path->p_ext->e_block ?
++			last_block : path->p_ext->e_block;
++
++		/* number of blocks from extent to be freed */
++		num = path->p_ext->e_block + path->p_ext->e_num - sf;
++
++		/* calc physical first physical block to be freed */
++		sf = path->p_ext->e_start + (sf - path->p_ext->e_block);
++
++		i = ext3_ext_calc_credits(inode, path, num);
++		handle = ext3_ext_journal_restart(handle, i);
++		if (IS_ERR(handle))
++			return PTR_ERR(handle);
++		
++		ext_debug(inode, "free extent %d:%d:%d -> free %d:%d\n",
++				path->p_ext->e_block, path->p_ext->e_start,
++				path->p_ext->e_num, sf, num);
++		for (i = 0; i < num; i++) {
++			struct buffer_head *bh =
++				sb_get_hash_table(inode->i_sb, sf + i);
++			ext3_forget(handle, 0, inode, bh, sf + i);
++		}
++		ext3_free_blocks(handle, inode, sf, num);
++
++		/* collect extents usage stats */
++		spin_lock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++		EXT3_SB(inode->i_sb)->s_ext_extents++;
++		EXT3_SB(inode->i_sb)->s_ext_blocks += num;
++		spin_unlock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++
++		/* reduce extent */
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			return err;
++		path->p_ext->e_num -= num;
++		if (path->p_ext->e_num == 0)
++			path->p_hdr->e_num--;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			return err;
++
++		path->p_ext--;
++	}
++	
++	/* if this leaf is free, then we should
++	 * remove it from index block above */
++	if (path->p_hdr->e_num == 0 && depth > 0) 
++		err = ext3_ext_remove_index(handle, inode, path);
++
++	return err;
++}
++
++static void ext3_ext_collect_stats(struct inode *inode)
++{
++	int depth;
++	
++	/* skip inodes with old good bitmap */
++	if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++		return;
++	
++	/* collect on full truncate only */
++	if (inode->i_size)
++		return;
++
++	depth = EXT3_I(inode)->i_depth;
++	if (depth < EXT3_SB(inode->i_sb)->s_ext_mindepth)
++		 EXT3_SB(inode->i_sb)->s_ext_mindepth = depth;
++	if (depth > EXT3_SB(inode->i_sb)->s_ext_maxdepth)
++		 EXT3_SB(inode->i_sb)->s_ext_maxdepth = depth;
++	EXT3_SB(inode->i_sb)->s_ext_sum += depth;
++	EXT3_SB(inode->i_sb)->s_ext_count++;
++	
++}
++
++void ext3_ext_truncate(struct inode * inode)
++{
++	struct address_space *mapping = inode->i_mapping;
++	struct ext3_ext_path *path;
++	struct page * page;
++	handle_t *handle;
++	int i, depth, err = 0;
++
++	ext3_ext_collect_stats(inode);
++
++	/*
++	 * We have to lock the EOF page here, because lock_page() nests
++	 * outside journal_start().
++	 */
++	if ((inode->i_size & (inode->i_sb->s_blocksize - 1)) == 0) {
++		/* Block boundary? Nothing to do */
++		page = NULL;
++	} else {
++		page = grab_cache_page(mapping,
++				inode->i_size >> PAGE_CACHE_SHIFT);
++		if (!page)
++			return;
++	}
++
++	/*
++	 * probably first extent we're gonna free will be last in block
++	 */
++	i = ext3_ext_calc_credits(inode, NULL, 0);
++	handle = ext3_journal_start(inode, i);
++	if (IS_ERR(handle)) {
++		if (page) {
++			clear_highpage(page);
++			flush_dcache_page(page);
++			unlock_page(page);
++			page_cache_release(page);
++		}
++		return;
++	}
++
++	if (page)
++		ext3_block_truncate_page(handle, mapping, inode->i_size, page,
++						inode->i_sb->s_blocksize);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* 
++	 * TODO: optimization is possible here
++	 * probably we need not scaning at all,
++	 * because page truncation is enough
++	 */
++	if (ext3_orphan_add(handle, inode))
++		goto out_stop;
++
++	/* we have to know where to truncate from in crash case */
++	EXT3_I(inode)->i_disksize = inode->i_size;
++	ext3_mark_inode_dirty(handle, inode);
++
++	/*
++	 * we start scanning from right side freeing all the blocks
++	 * after i_size and walking into the deep
++	 */
++	i = 0;
++	depth = EXT3_I(inode)->i_depth;
++	path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL);
++	if (IS_ERR(path)) {
++		ext3_error(inode->i_sb, "ext3_ext_truncate",
++				"Can't allocate path array");
++		goto out_stop;
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	path[i].p_hdr = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	while (i >= 0 && err == 0) {
++		if (i == depth) {
++			/* this is leaf block */
++			err = ext3_ext_truncate_leaf(handle, inode,
++							path + i, i);
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			continue;
++		}
++		
++		/* this is index block */
++		if (!path[i].p_hdr) {
++			path[i].p_hdr =
++				(struct ext3_extent_header *) path[i].p_bh->b_data;
++			ext_debug(inode, "initialize header\n");
++		}
++
++		EXT_ASSERT(path[i].p_hdr->e_num <= path[i].p_hdr->e_max);
++		
++		if (!path[i].p_idx) {
++			/* this level hasn't touched yet */
++			path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr);
++			path[i].p_block = path[i].p_hdr->e_num + 1;
++			ext_debug(inode, "init index ptr: hdr 0x%p, num %d\n",
++					path[i].p_hdr, path[i].p_hdr->e_num);
++		} else {
++			/* we've already was here, see at next index */
++			path[i].p_idx--;
++		}
++
++		ext_debug(inode, "level %d - index, first 0x%p, cur 0x%p\n",
++				i, EXT_FIRST_INDEX(path[i].p_hdr),
++				path[i].p_idx);
++		if (ext3_ext_more_to_truncate(inode, path + i)) {
++			/* go to the next level */
++			ext_debug(inode, "move to level %d (block %d)\n", i+1,
++					path[i].p_idx->e_leaf);
++			memset(path + i + 1, 0, sizeof(*path));
++			path[i+1].p_bh = sb_bread(inode->i_sb,
++							path[i].p_idx->e_leaf);
++			if (!path[i+1].p_bh) {
++				/* should we reset i_size? */
++				err = -EIO;
++				break;
++			}
++			i++;
++		} else {
++			/* we finish processing this index, go up */
++			if (path[i].p_hdr->e_num == 0 && i > 0) {
++				/* index is empty, remove it
++				 * handle must be already prepared by the
++				 * truncate_leaf()
++				 */
++				err = ext3_ext_remove_index(handle, inode,
++								path + i);
++			}
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			ext_debug(inode, "return to level %d\n", i);
++		}
++	}
++
++	/* TODO: flexible tree reduction should be here */
++	if (path->p_hdr->e_num == 0) {
++		/*
++		 * truncate to zero freed all the tree
++		 * so, we need to correct i_depth
++		 */
++		EXT3_I(inode)->i_depth = 0;
++		path->p_hdr->e_max = 0;
++		ext3_mark_inode_dirty(handle, inode);
++	}
++
++	kfree(path);
++
++	/* In a multi-transaction truncate, we only make the final
++	 * transaction synchronous */
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++out_stop:
++	/*
++	 * If this was a simple ftruncate(), and the file will remain alive
++	 * then we need to clear up the orphan record which we created above.
++	 * However, if this was a real unlink then we were called by
++	 * ext3_delete_inode(), and we allow that function to clean up the
++	 * orphan info for us.
++	 */
++	if (inode->i_nlink)
++		ext3_orphan_del(handle, inode);
++
++	up(&EXT3_I(inode)->i_ext_sem);
++	ext3_journal_stop(handle, inode);
++}
++
++/*
++ * this routine calculate max number of blocks we could modify
++ * in order to allocate new block for an inode
++ */
++int ext3_ext_writepage_trans_blocks(struct inode *inode, int num)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	int depth = ei->i_depth + 1;
++	int needed;
++	
++	/*
++	 * the worste case we're expecting is creation of the
++	 * new root (growing in depth) with index splitting
++	 * for splitting we have to consider depth + 1 because
++	 * previous growing could increase it
++	 */
++
++	/* 
++	 * growing in depth:
++	 * block allocation + new root + old root
++	 */
++	needed = EXT3_ALLOC_NEEDED + 2;
++
++	/* index split. we may need:
++	 *   allocate intermediate indexes and new leaf
++	 *   change two blocks at each level, but root
++	 *   modify root block (inode)
++	 */
++	needed += (depth * EXT3_ALLOC_NEEDED) + (2 * depth) + 1;
++
++	/* caller want to allocate num blocks */
++	needed *= num;
++	
++#ifdef CONFIG_QUOTA
++	/* 
++	 * FIXME: real calculation should be here
++	 * it depends on blockmap format of qouta file
++	 */
++	needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS;
++#endif
++
++	return needed;
++}
++
++/*
++ * called at mount time
++ */
++void ext3_ext_init(struct super_block *sb)
++{
++	/*
++	 * possible initialization would be here
++	 */
++
++	if (test_opt(sb, EXTENTS))
++		printk("EXT3-fs: file extents enabled\n");
++	spin_lock_init(&EXT3_SB(sb)->s_ext_lock);
++}
++
++/*
++ * called at umount time
++ */
++void ext3_ext_release(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++
++	/* show collected stats */
++	if (sbi->s_ext_count && sbi->s_ext_extents)
++		printk("EXT3-fs: min depth - %d, max depth - %d, "
++				"ave. depth - %d, ave. blocks/extent - %d\n",
++				sbi->s_ext_mindepth,
++				sbi->s_ext_maxdepth,
++				sbi->s_ext_sum / sbi->s_ext_count,
++				sbi->s_ext_blocks / sbi->s_ext_extents);
++}
++
+--- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-extents-2.4.18-chaos	2003-09-19 22:07:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c	2003-09-20 00:18:43.000000000 +0400
+@@ -573,6 +573,10 @@ repeat:
+ 	ei->i_prealloc_count = 0;
+ #endif
+ 	ei->i_block_group = i;
++	if (test_opt(sb, EXTENTS))
++		EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL;
++	ei->i_depth = 0;
++	sema_init(&ei->i_ext_sem, 1);
+ 
+ 	if (ei->i_flags & EXT3_SYNC_FL)
+ 		inode->i_flags |= S_SYNC;
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-extents-2.4.18-chaos	2003-09-19 22:07:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c	2003-09-22 15:40:30.000000000 +0400
+@@ -842,6 +842,15 @@ changed:
+ 	goto reread;
+ }
+ 
++static inline int
++ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block,
++		struct buffer_head *bh, int create, int extend_disksize)
++{
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_get_block(handle, inode, block, bh, create, 1);
++	return ext3_get_block_handle(handle, inode, block, bh, create, 1);
++}
++
+ /*
+  * The BKL is not held on entry here.
+  */
+@@ -855,7 +864,7 @@ static int ext3_get_block(struct inode *
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock,
++	ret = ext3_get_block_wrap(handle, inode, iblock,
+ 				bh_result, create, 1);
+ 	return ret;
+ }
+@@ -882,7 +891,7 @@ ext3_direct_io_get_block(struct inode *i
+ 		}
+ 	}
+ 	if (ret == 0)
+-		ret = ext3_get_block_handle(handle, inode, iblock,
++		ret = ext3_get_block_wrap(handle, inode, iblock,
+ 					bh_result, create, 0);
+ 	if (ret == 0)
+ 		bh_result->b_size = (1 << inode->i_blkbits);
+@@ -904,7 +913,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
++	*errp = ext3_get_block_wrap(handle, inode, block, &dummy, create, 1);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1520,7 +1529,7 @@ ext3_block_truncate_page_prepare(struct 
+  * This required during truncate. We need to physically zero the tail end
+  * of that block so it doesn't yield old data if the file is later grown.
+  */
+-static int ext3_block_truncate_page(handle_t *handle,
++int ext3_block_truncate_page(handle_t *handle,
+ 				    struct address_space *mapping, loff_t from,
+ 				    struct page *page, unsigned blocksize)
+ {
+@@ -1998,6 +2007,9 @@ void ext3_truncate(struct inode * inode)
+ 
+ 	ext3_discard_prealloc(inode);
+ 
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_truncate(inode);
++
+ 	blocksize = inode->i_sb->s_blocksize;
+ 	last_block = (inode->i_size + blocksize-1)
+ 					>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
+@@ -2436,6 +2448,8 @@ void ext3_read_inode(struct inode * inod
+ 	ei->i_prealloc_count = 0;
+ #endif
+ 	ei->i_block_group = iloc.block_group;
++	ei->i_depth = raw_inode->osd2.linux2.l_i_depth;
++	sema_init(&ei->i_ext_sem, 1);
+ 
+ 	/*
+ 	 * NOTE! The in-memory inode i_data array is in little-endian order
+@@ -2556,6 +2570,7 @@ static int ext3_do_update_inode(handle_t
+ 		raw_inode->i_fsize = 0;
+ 	}
+ #endif
++ 	raw_inode->osd2.linux2.l_i_depth = ei->i_depth;
+ 	raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
+ 	if (!S_ISREG(inode->i_mode)) {
+ 		raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
+@@ -2759,6 +2774,9 @@ int ext3_writepage_trans_blocks(struct i
+ 	int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
+ 	int ret;
+ 	
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_writepage_trans_blocks(inode, bpp);
++
+ 	if (ext3_should_journal_data(inode))
+ 		ret = 3 * (bpp + indirects) + 2;
+ 	else
+@@ -3082,7 +3100,7 @@ int ext3_prep_san_write(struct inode *in
+ 
+ 	/* alloc blocks one by one */
+ 	for (i = 0; i < nblocks; i++) {
+-		ret = ext3_get_block_handle(handle, inode, blocks[i],
++		ret = ext3_get_block_wrap(handle, inode, blocks[i],
+ 						&bh_tmp, 1, 1);
+ 		if (ret)
+ 			break;
+@@ -3143,7 +3161,7 @@ int ext3_map_inode_page(struct inode *in
+                 if (blocks[i] != 0)
+                         continue;
+ 
+-                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
++                rc = ext3_get_block_wrap(handle, inode, iblock, &bh, 1, 1);
+                 if (rc) {
+                         printk(KERN_INFO "ext3_map_inode_page: error %d "
+                                "allocating block %ld\n", rc, iblock);
+--- linux-2.4.18-chaos/fs/ext3/Makefile~ext3-extents-2.4.18-chaos	2003-09-19 22:07:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/Makefile	2003-09-20 00:18:43.000000000 +0400
+@@ -12,7 +12,8 @@ O_TARGET := ext3.o
+ export-objs :=	ext3-exports.o
+ 
+ obj-y    := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o
++		ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o \
++		extents.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-extents-2.4.18-chaos	2003-09-19 22:07:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c	2003-09-20 00:18:43.000000000 +0400
+@@ -619,6 +619,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_ext_release(sb);
+ 	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+@@ -741,6 +742,12 @@ static int parse_options (char * options
+ 		else
+ #endif
+ 
++		if (!strcmp (this_char, "extents"))
++			set_opt (sbi->s_mount_opt, EXTENTS);
++		else
++		if (!strcmp (this_char, "extdebug"))
++			set_opt (sbi->s_mount_opt, EXTDEBUG);
++		else
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -1468,6 +1475,7 @@ struct super_block * ext3_read_super (st
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
+ 		"writeback");
++	ext3_ext_init(sb);
+ 
+ 	return sb;
+ 
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-extents-2.4.18-chaos	2003-09-19 22:07:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h	2003-09-20 00:18:43.000000000 +0400
+@@ -183,6 +183,7 @@ struct ext3_group_desc
+ #define EXT3_IMAGIC_FL			0x00002000 /* AFS directory */
+ #define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
+ #define EXT3_RESERVED_FL		0x80000000 /* reserved for ext3 lib */
++#define EXT3_EXTENTS_FL			0x00080000 /* Inode uses extents */
+ 
+ #define EXT3_FL_USER_VISIBLE		0x00005FFF /* User visible flags */
+ #define EXT3_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+@@ -243,7 +244,7 @@ struct ext3_inode {
+ 		struct {
+ 			__u8	l_i_frag;	/* Fragment number */
+ 			__u8	l_i_fsize;	/* Fragment size */
+-			__u16	i_pad1;
++			__u16	l_i_depth;
+ 			__u16	l_i_uid_high;	/* these 2 fields    */
+ 			__u16	l_i_gid_high;	/* were reserved2[0] */
+ 			__u32	l_i_reserved2;
+@@ -324,6 +325,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_IOPEN		0x8000	/* Allow access via iopen */
+ #define EXT3_MOUNT_IOPEN_NOPRIV		0x10000	/* Make iopen world-readable */
+ #define EXT3_MOUNT_ASYNCDEL		0x20000	/* Delayed deletion */
++#define EXT3_MOUNT_EXTENTS		0x40000	/* Extents support */
++#define EXT3_MOUNT_EXTDEBUG		0x80000	/* Extents debug */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -663,6 +666,12 @@ extern void ext3_discard_prealloc (struc
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++extern int ext3_block_truncate_page(handle_t *handle,
++				    struct address_space *mapping, loff_t from,
++				    struct page *page, unsigned blocksize);
++extern int ext3_forget(handle_t *handle, int is_metadata,
++		       struct inode *inode, struct buffer_head *bh,
++		       int blocknr);
+ #ifdef EXT3_DELETE_THREAD
+ extern void ext3_truncate_thread(struct inode *inode);
+ #endif
+@@ -722,6 +731,13 @@ extern struct inode_operations ext3_dir_
+ /* symlink.c */
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
++/* extents.c */
++extern int ext3_ext_writepage_trans_blocks(struct inode *, int);
++extern int ext3_ext_get_block(handle_t *, struct inode *, long,
++				struct buffer_head *, int, int);
++extern void ext3_ext_truncate(struct inode *);
++extern void ext3_ext_init(struct super_block *);
++extern void ext3_ext_release(struct super_block *);
+ 
+ #endif	/* __KERNEL__ */
+ 
+--- linux-2.4.18-chaos/include/linux/ext3_fs_i.h~ext3-extents-2.4.18-chaos	2001-11-22 22:46:19.000000000 +0300
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_i.h	2003-09-20 00:18:43.000000000 +0400
+@@ -73,6 +73,10 @@ struct ext3_inode_info {
+ 	 * by other means, so we have truncate_sem.
+ 	 */
+ 	struct rw_semaphore truncate_sem;
++
++	/* extents-related data */
++	struct semaphore i_ext_sem;
++	__u16 i_depth;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_I */
+--- linux-2.4.18-chaos/include/linux/ext3_fs_sb.h~ext3-extents-2.4.18-chaos	2003-09-19 22:07:13.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs_sb.h	2003-09-20 00:18:43.000000000 +0400
+@@ -84,6 +84,16 @@ struct ext3_sb_info {
+ 	wait_queue_head_t s_delete_thread_queue;
+ 	wait_queue_head_t s_delete_waiter_queue;
+ #endif
++
++	/* extents */
++	int s_ext_debug;
++	int s_ext_mindepth;
++	int s_ext_maxdepth;
++	int s_ext_sum;
++	int s_ext_count;
++	spinlock_t s_ext_lock;
++	int s_ext_extents;
++	int s_ext_blocks;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7c63464fe2d847d8566b18ae4cf82815f5e63bd3
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch
@@ -0,0 +1,1824 @@
+ fs/ext3/Makefile           |    3 
+ fs/ext3/extents.c          | 1570 +++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/ialloc.c           |    4 
+ fs/ext3/inode.c            |   28 
+ fs/ext3/super.c            |    6 
+ include/linux/ext3_fs.h    |   16 
+ include/linux/ext3_fs_i.h  |    4 
+ include/linux/ext3_fs_sb.h |   10 
+ 8 files changed, 1634 insertions(+), 7 deletions(-)
+
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.20-vanilla-alexey/fs/ext3/extents.c	2003-09-15 19:57:29.000000000 +0400
+@@ -0,0 +1,1570 @@
++/*
++ *
++ * linux/fs/ext3/extents.c
++ *
++ * Extents support for EXT3
++ *
++ * 07/08/2003    Alex Tomas <bzzz@tmi.comex.ru>
++ * 
++ * TODO:
++ *   - ext3*_error() should be used in some situations
++ *   - find_goal() [to be tested and improved]
++ *   - error handling
++ *   - we could leak allocated block in some error cases
++ *   - quick search for index/leaf in ext3_ext_find_extent()
++ *   - tree reduction
++ *   - cache last found extent
++ *   - arch-independent
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/time.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/smp_lock.h>
++#include <linux/highuid.h>
++#include <linux/pagemap.h>
++#include <linux/quotaops.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/locks.h>
++
++/*
++ * with AGRESSIVE_TEST defined capacity of index/leaf blocks
++ * become very little, so index split, in-depth growing and
++ * other hard changes happens much more often
++ * this is for debug purposes only
++ */
++#define AGRESSIVE_TEST_
++
++/*
++ * if EXT_DEBUG defined you can use 'extdebug' mount option
++ * to get lots of info what's going on
++ */
++#define EXT_DEBUG
++#ifdef EXT_DEBUG
++#define ext_debug(inode,fmt,a...) 		\
++do {						\
++	if (test_opt((inode)->i_sb, EXTDEBUG))	\
++		printk(fmt, ##a);		\
++} while (0);
++#else
++#define ext_debug(inode,fmt,a...)
++#endif
++
++#define EXT3_ALLOC_NEEDED	2	/* block bitmap + group descriptor */
++
++/*
++ * ext3_inode has i_block array (total 60 bytes)
++ * first 4 bytes are used to store:
++ *  - tree depth (0 mean there is no tree yet. all extents in the inode)
++ *  - number of alive extents in the inode
++ */
++
++/*
++ * this is extent on-disk structure
++ * it's used at the bottom of the tree
++ */
++struct ext3_extent {
++	__u32	e_block;	/* first logical block extent covers */
++	__u32	e_start;	/* first physical block extents lives */
++	__u32	e_num;		/* number of blocks covered by extent */
++};
++
++/*
++ * this is index on-disk structure
++ * it's used at all the levels, but the bottom
++ */
++struct ext3_extent_idx {
++	__u32	e_block;	/* index covers logical blocks from 'block' */
++	__u32	e_leaf;		/* pointer to the physical block of the next *
++				 * level. leaf or next index could bet here */
++};
++
++/*
++ * each block (leaves and indexes), even inode-stored has header
++ */
++struct ext3_extent_header {	
++	__u16	e_num;		/* number of valid entries */
++	__u16	e_max;		/* capacity of store in entries */
++};
++
++/*
++ * array of ext3_ext_path contains path to some extent
++ * creation/lookup routines use it for traversal/splitting/etc
++ * truncate uses it to simulate recursive walking
++ */
++struct ext3_ext_path {
++	__u32				p_block;
++	__u16				p_depth;
++	struct ext3_extent		*p_ext;
++	struct ext3_extent_idx		*p_idx;
++	struct ext3_extent_header	*p_hdr;
++	struct buffer_head		*p_bh;
++};
++
++#define EXT_FIRST_EXTENT(__hdr__) \
++	((struct ext3_extent *) (((char *) (__hdr__)) +		\
++				 sizeof(struct ext3_extent_header)))
++#define EXT_FIRST_INDEX(__hdr__) \
++	((struct ext3_extent_idx *) (((char *) (__hdr__)) +	\
++				     sizeof(struct ext3_extent_header)))
++#define EXT_HAS_FREE_INDEX(__path__) \
++	((__path__)->p_hdr->e_num < (__path__)->p_hdr->e_max)
++#define EXT_LAST_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_LAST_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_num - 1)
++#define EXT_MAX_EXTENT(__hdr__) \
++	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->e_max - 1)
++#define EXT_MAX_INDEX(__hdr__) \
++	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->e_max - 1)
++
++
++#define EXT_ASSERT(__x__) if (!(__x__)) BUG();
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ */
++static int ext3_ext_get_access(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_get_write_access(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return 0;
++}
++
++/*
++ * could return:
++ *  - EROFS
++ *  - ENOMEM
++ *  - EIO
++ */
++static int ext3_ext_dirty(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	if (path->p_bh) {
++		/* path points to block */
++		return ext3_journal_dirty_metadata(handle, path->p_bh);
++	}
++
++	/* path points to leaf/index in inode body */
++	return ext3_mark_inode_dirty(handle, inode);
++}
++
++static inline int ext3_ext_space_block(struct inode *inode)
++{
++	int size;
++
++	size = (inode->i_sb->s_blocksize - sizeof(struct ext3_extent_header))
++		/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 6; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent);
++#ifdef AGRESSIVE_TEST
++	size = 3; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static inline int ext3_ext_space_inode_idx(struct inode *inode)
++{
++	int size;
++
++	size = (sizeof(EXT3_I(inode)->i_data) -
++			sizeof(struct ext3_extent_header))
++			/ sizeof(struct ext3_extent_idx);
++#ifdef AGRESSIVE_TEST
++	size = 4; /* FIXME: for debug, remove this line */
++#endif
++	return size;
++}
++
++static void ext3_ext_show_path(struct inode *inode, struct ext3_ext_path *path)
++{
++	int k, l = path->p_depth;
++
++	ext_debug(inode, "path:");
++	for (k = 0; k <= l; k++, path++) {
++		if (path->p_idx) {
++			ext_debug(inode, "  %d->%d", path->p_idx->e_block,
++					path->p_idx->e_leaf);
++		} else if (path->p_ext) {
++			ext_debug(inode, "  %d:%d:%d",
++					path->p_ext->e_block,
++					path->p_ext->e_start,
++					path->p_ext->e_num);
++		} else
++			ext_debug(inode, "  []");
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_show_leaf(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *eh = path[depth].p_hdr;
++	struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
++	int i;
++
++	for (i = 0; i < eh->e_num; i++, ex++) {
++		ext_debug(inode, "%d:%d:%d ",
++				ex->e_block, ex->e_start, ex->e_num);
++	}
++	ext_debug(inode, "\n");
++}
++
++static void ext3_ext_drop_refs(struct inode *inode, struct ext3_ext_path *path)
++{
++	int depth = path->p_depth;
++	int i;
++
++	for (i = 0; i <= depth; i++, path++)
++		if (path->p_bh) {
++			brelse(path->p_bh);
++			path->p_bh = NULL;
++		}
++}
++
++static int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	unsigned long bg_start;
++	unsigned long colour;
++	int depth;
++	
++	if (path) {
++		depth = path->p_depth;
++		/* try to find previous block */
++		if (path[depth].p_ext)
++			return path[depth].p_ext->e_start +
++				path[depth].p_ext->e_num - 1;
++		
++		/* it looks index is empty
++		 * try to find starting from index itself */
++		if (path[depth].p_bh)
++			return path[depth].p_bh->b_blocknr;
++	}
++
++	/* OK. use inode's group */
++	bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) +
++		le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
++	colour = (current->pid % 16) *
++			(EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16);
++	return bg_start + colour;
++}
++
++static struct ext3_ext_path *
++ext3_ext_find_extent(struct inode *inode, int block, struct ext3_ext_path *path)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	struct ext3_extent_header *eh = (void *) ei->i_data;
++	struct ext3_extent_idx *ix;
++	struct buffer_head *bh;
++	struct ext3_extent *ex;
++	int depth, i, k, ppos = 0;
++	
++	eh = (struct ext3_extent_header *) ei->i_data;
++
++	/* initialize capacity of leaf in inode for first time */
++	if (eh->e_max == 0)
++		eh->e_max = ext3_ext_space_inode(inode);
++	i = depth = ei->i_depth;
++	EXT_ASSERT(i == 0 || eh->e_num > 0);
++	
++	/* account possible depth increase */
++	if (!path) {
++		path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2),
++				GFP_NOFS);
++		if (!path)
++			return ERR_PTR(-ENOMEM);
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	/* walk through the tree */
++	while (i) {
++		ext_debug(inode, "depth %d: num %d, max %d\n",
++				ppos, eh->e_num, eh->e_max);
++		ix = EXT_FIRST_INDEX(eh);
++		if (eh->e_num)
++			path[ppos].p_idx = ix;
++		EXT_ASSERT(eh->e_num <= eh->e_max);
++		for (k = 0; k < eh->e_num; k++, ix++) {
++			ext_debug(inode, "index: %d -> %d\n",
++					ix->e_block, ix->e_leaf);
++			if (block < ix->e_block)
++				break;
++			path[ppos].p_idx = ix;
++		}
++		path[ppos].p_block = path[ppos].p_idx->e_leaf;
++		path[ppos].p_depth = i;
++		path[ppos].p_hdr = eh;
++		path[ppos].p_ext = NULL;
++
++		bh = sb_bread(inode->i_sb, path[ppos].p_block);
++		if (!bh) {
++			ext3_ext_drop_refs(inode, path);
++			kfree(path);
++			return ERR_PTR(-EIO);
++		}
++		eh = (struct ext3_extent_header *) bh->b_data;
++		ppos++;
++		EXT_ASSERT(ppos <= depth);
++		path[ppos].p_bh = bh;
++		i--;
++	}
++
++	path[ppos].p_depth = i;
++	path[ppos].p_hdr = eh;
++	path[ppos].p_ext = NULL;
++	
++	/* find extent */
++	ex = EXT_FIRST_EXTENT(eh);
++	if (eh->e_num)
++		path[ppos].p_ext = ex;
++	EXT_ASSERT(eh->e_num <= eh->e_max);
++	for (k = 0; k < eh->e_num; k++, ex++) {
++		if (block < ex->e_block) 
++			break;
++		path[ppos].p_ext = ex;
++	}
++
++	ext3_ext_show_path(inode, path);
++
++	return path;
++}
++
++static void ext3_ext_check_boundary(struct inode *inode,
++					struct ext3_ext_path *curp,
++					void *addr, int len)
++{
++	void *end;
++
++	if (!len)
++		return;
++	if (curp->p_bh)
++		end = (void *) curp->p_hdr + inode->i_sb->s_blocksize;
++	else
++		end = (void *) curp->p_hdr + sizeof(EXT3_I(inode)->i_data);
++	if (((unsigned long) addr) + len > (unsigned long) end) {
++		printk("overflow! 0x%p > 0x%p\n", addr + len, end);
++		BUG();
++	}
++	if ((unsigned long) addr < (unsigned long) curp->p_hdr) {
++		printk("underflow! 0x%p < 0x%p\n", addr, curp->p_hdr);
++		BUG();
++	}
++}
++
++/*
++ * insert new index [logical;ptr] into the block at cupr
++ * it check where to insert: before curp or after curp
++ */
++static int ext3_ext_insert_index(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *curp, int logical,
++				int ptr)
++{
++	struct ext3_extent_idx *ix;
++	int len, err;
++
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		return err;
++
++	EXT_ASSERT(logical != curp->p_idx->e_block);
++	len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
++	if (logical > curp->p_idx->e_block) {
++		/* insert after */
++		len = (len - 1) * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d after: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				(curp->p_idx + 1), (curp->p_idx + 2));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 2, len);
++		memmove(curp->p_idx + 2, curp->p_idx + 1, len);
++		ix = curp->p_idx + 1;
++	} else {
++		/* insert before */
++		len = len * sizeof(struct ext3_extent_idx);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert new index %d before: %d. "
++				"move %d from 0x%p to 0x%p\n",
++				logical, ptr, len,
++				curp->p_idx, (curp->p_idx + 1));
++
++		ext3_ext_check_boundary(inode, curp, curp->p_idx + 1, len);
++		memmove(curp->p_idx + 1, curp->p_idx, len);
++		ix = curp->p_idx;
++	}
++
++	ix->e_block = logical;
++	ix->e_leaf = ptr;
++	curp->p_hdr->e_num++;
++
++	err = ext3_ext_dirty(handle, inode, curp);
++	ext3_std_error(inode->i_sb, err);
++
++	return err;
++}
++
++/*
++ * routine inserts new subtree into the path, using free index entry
++ * at depth 'at:
++ *  - allocates all needed blocks (new leaf and all intermediate index blocks)
++ *  - makes decision where to split
++ *  - moves remaining extens and index entries (right to the split point)
++ *    into the newly allocated blocks
++ *  - initialize subtree
++ */
++static int ext3_ext_split(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext, int at)
++{
++	struct buffer_head *bh = NULL;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	struct ext3_extent *ex;
++	int i = at, k, m, a;
++	long newblock, oldblock, border;
++	int *ablocks = NULL; /* array of allocated blocks */
++	int err = 0;
++
++	/* make decision: where to split? */
++	/* FIXME: now desicion is simplest: at current extent */
++
++	/* if current leaf will be splitted, then we should use 
++	 * border from split point */
++	if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		border = path[depth].p_ext[1].e_block;
++		ext_debug(inode, "leaf will be splitted."
++				" next leaf starts at %d\n",
++				(int)border);
++	} else {
++		border = newext->e_block;
++		ext_debug(inode, "leaf will be added."
++				" next leaf starts at %d\n",
++				(int)border);
++	}
++
++	/* 
++	 * if error occurs, then we break processing
++	 * and turn filesystem read-only. so, index won't
++	 * be inserted and tree will be in consistent
++	 * state. next mount will repair buffers too
++	 */
++
++	/*
++	 * get array to track all allocated blocks
++	 * we need this to handle errors and free blocks
++	 * upon them
++	 */
++	ablocks = kmalloc(sizeof(long) * depth, GFP_NOFS);
++	if (!ablocks)
++		return -ENOMEM;
++	memset(ablocks, 0, sizeof(long) * depth);
++
++	/* allocate all needed blocks */
++	ext_debug(inode, "allocate %d blocks for indexes and leaf\n",
++			depth - at);
++	ablocks[0] = newext->e_start++;
++	newext->e_num--;
++	for (a = 1; a < depth - at; a++) {
++		newblock = ext3_new_block(handle, inode, newext->e_start,
++						0, 0, &err);
++		if (newblock == 0)
++			goto cleanup;
++		ablocks[a] = newblock;
++	}
++
++	/* initialize new leaf */
++	newblock = ablocks[--a];
++	EXT_ASSERT(newblock);
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		goto cleanup;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh)))
++		goto cleanup;
++
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_num = 0;
++	neh->e_max = ext3_ext_space_block(inode);
++	ex = EXT_FIRST_EXTENT(neh);
++
++	/* move remain of path[depth] to the new leaf */
++	EXT_ASSERT(path[depth].p_hdr->e_num ==
++			path[depth].p_hdr->e_max);
++	/* start copy from next extent */
++	/* TODO: we could do it by single memmove */
++	m = 0;
++	path[depth].p_ext++;
++	while (path[depth].p_ext <=
++			EXT_MAX_EXTENT(path[depth].p_hdr)) {
++		ext_debug(inode, "move %d:%d:%d in new leaf\n",
++				path[depth].p_ext->e_block,
++				path[depth].p_ext->e_start,
++				path[depth].p_ext->e_num);
++		memmove(ex++, path[depth].p_ext++,
++				sizeof(struct ext3_extent));
++		neh->e_num++;
++		m++;
++	}
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto cleanup;	
++	brelse(bh);
++	bh = NULL;
++
++	/* correct old leaf */
++	if (m) {
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			goto cleanup;
++		path[depth].p_hdr->e_num -= m;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			goto cleanup;
++		
++	}
++
++	/* create intermediate indexes */
++	k = depth - at - 1;
++	EXT_ASSERT(k >= 0);
++	if (k)
++		ext_debug(inode,
++				"create %d intermediate indices\n", k);
++	/* insert new index into current index block */
++	/* current depth stored in i var */
++	i = depth - 1;
++	while (k--) {
++		oldblock = newblock;
++		newblock = ablocks[--a];
++		bh = sb_getblk(inode->i_sb, newblock);
++		if (!bh) {
++			err = -EIO;
++			goto cleanup;
++		}
++		lock_buffer(bh);
++
++		if ((err = ext3_journal_get_create_access(handle, bh)))
++			goto cleanup;
++
++		neh = (struct ext3_extent_header *) bh->b_data;
++		neh->e_num = 1;
++		neh->e_max = ext3_ext_space_block(inode);
++		fidx = EXT_FIRST_INDEX(neh);
++		fidx->e_block = border;
++		fidx->e_leaf = oldblock;
++
++		ext_debug(inode,
++				"int.index at %d (block %u): %d -> %d\n",
++				i, (unsigned) newblock,
++				(int) border,
++				(int) oldblock);
++		/* copy indexes */
++		m = 0;
++		path[i].p_idx++;
++		EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) ==
++				EXT_LAST_INDEX(path[i].p_hdr));
++		ext_debug(inode, "cur 0x%p, last 0x%p\n", path[i].p_idx,
++				EXT_MAX_INDEX(path[i].p_hdr));
++		while (path[i].p_idx <=
++				EXT_MAX_INDEX(path[i].p_hdr)) {
++			ext_debug(inode, "%d: move %d:%d in new index\n",
++					i, path[i].p_idx->e_block,
++					path[i].p_idx->e_leaf);
++			memmove(++fidx, path[i].p_idx++,
++					sizeof(struct ext3_extent_idx));
++			neh->e_num++;
++			m++;
++		}
++
++		mark_buffer_uptodate(bh, 1);
++		unlock_buffer(bh);
++
++		if ((err = ext3_journal_dirty_metadata(handle, bh)))
++			goto cleanup;
++		brelse(bh);
++		bh = NULL;
++
++		/* correct old index */
++		if (m) {
++			err = ext3_ext_get_access(handle,inode,path+i);
++			if (err)
++				goto cleanup;
++			path[i].p_hdr->e_num -= m;
++			err = ext3_ext_dirty(handle, inode, path + i);
++			if (err)
++				goto cleanup;
++		}
++
++		i--;
++	}
++
++	/* insert new index */
++	if (!err) 
++		err = ext3_ext_insert_index(handle, inode, path + at,
++						border, newblock);
++
++cleanup:
++	if (bh) {
++		if (buffer_locked(bh))
++			unlock_buffer(bh);
++		brelse(bh);
++	}
++
++	if (err) {
++		/* free all allocated blocks in error case */
++		for (i = 0; i < depth; i++)
++			if (!ablocks[i])
++				continue;
++			ext3_free_blocks(handle, inode, ablocks[i], 1);
++	}
++	kfree(ablocks);
++
++	return err;
++}
++
++/*
++ * routine implements tree growing procedure:
++ *  - allocates new block
++ *  - moves top-level data (index block or leaf) into the new block
++ *  - initialize new top-level, creating index that points to the
++ *    just created block
++ */
++static int ext3_ext_grow_indepth(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	struct buffer_head *bh;
++	struct ext3_ext_path *curp = path;
++	struct ext3_extent_header *neh;
++	struct ext3_extent_idx *fidx;
++	int len, err = 0;
++	long newblock;
++
++	/*
++	 * use already allocated by the called block for new root block
++	 */
++	newblock = newext->e_start++;
++	newext->e_num--;
++	
++	bh = sb_getblk(inode->i_sb, newblock);
++	if (!bh) {
++		err = -EIO;
++		ext3_std_error(inode->i_sb, err);
++		return err;
++	}
++	lock_buffer(bh);
++
++	if ((err = ext3_journal_get_create_access(handle, bh))) {
++		unlock_buffer(bh);
++		goto out;	
++	}
++
++	/* move top-level index/leaf into new block */
++	len = sizeof(struct ext3_extent_header) +
++		sizeof(struct ext3_extent) * curp->p_hdr->e_max;
++	EXT_ASSERT(len >= 0 && len < 4096);
++	memmove(bh->b_data, curp->p_hdr, len);
++
++	/* set size of new block */
++	neh = (struct ext3_extent_header *) bh->b_data;
++	neh->e_max = ext3_ext_space_block(inode);
++	mark_buffer_uptodate(bh, 1);
++	unlock_buffer(bh);
++
++	if ((err = ext3_journal_dirty_metadata(handle, bh)))
++		goto out;
++
++	/* create index in new top-level index: num,max,pointer */
++	if ((err = ext3_ext_get_access(handle, inode, curp)))
++		goto out;
++
++	curp->p_hdr->e_max = ext3_ext_space_inode_idx(inode);
++	curp->p_hdr->e_num = 1;
++	curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
++	curp->p_idx->e_block = EXT_FIRST_EXTENT(path[0].p_hdr)->e_block;
++	curp->p_idx->e_leaf = newblock;
++
++	neh = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	fidx = EXT_FIRST_INDEX(neh);
++	ext_debug(inode, "new root: num %d(%d), lblock %d, ptr %d\n",
++			neh->e_num, neh->e_max, fidx->e_block, fidx->e_leaf); 
++
++	EXT3_I(inode)->i_depth++;
++	err = ext3_ext_dirty(handle, inode, curp);
++out:
++	brelse(bh);
++
++	return err;
++}
++
++/*
++ * routine finds empty index and adds new leaf. if no free index found
++ * then it requests in-depth growing
++ */
++static int ext3_ext_create_new_leaf(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path,
++					struct ext3_extent *newext)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_ext_path *curp;
++	int i = depth, err = 0;
++	long newblock = newext->e_start;
++
++	/* walk up to the tree and look for free index entry */
++	curp = path + depth;
++	while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
++		i--;
++		curp--;
++	}
++
++	/* we use already allocated block for index block
++	 * so, subsequent data blocks should be contigoues */
++	if (EXT_HAS_FREE_INDEX(curp)) {
++		/* if we found index with free entry, then use that
++		 * entry: create all needed subtree and add new leaf */
++		err = ext3_ext_split(handle, inode, path, newext, i);
++	} else {
++		/* tree is full, time to grow in depth */
++		err = ext3_ext_grow_indepth(handle, inode, path, newext);
++	}
++
++	if (!err) {
++		/* refill path */
++		ext3_ext_drop_refs(inode, path);
++		path = ext3_ext_find_extent(inode, newext->e_block, path);
++		if (IS_ERR(path))
++			err = PTR_ERR(path);
++
++		/*
++		 * probably we've used some blocks from extent
++		 * let's allocate new block for it
++		 */
++		if (newext->e_num == 0 && !err) {
++			newext->e_start =
++				ext3_new_block(handle, inode, newblock,
++						0, 0, &err);
++			newext->e_num = 1;
++		}
++	}
++
++	return err;
++}
++
++/*
++ * returns next allocated block or 0xffffffff
++ * NOTE: it consider block number from index entry as
++ * allocated block. thus, index entries have to be consistent
++ * with leafs
++ */
++static inline unsigned ext3_ext_next_allocated_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	if (depth == 0 && path->p_ext == NULL)
++		return 0xffffffff;
++
++	/* FIXME: what if index isn't full ?! */
++	while (depth >= 0) {
++		if (depth == path->p_depth) {
++			/* leaf */
++			if (path[depth].p_ext !=
++					EXT_LAST_EXTENT(path[depth].p_hdr))
++				return path[depth].p_ext[1].e_block;
++		} else {
++			/* index */
++			if (path[depth].p_idx !=
++					EXT_LAST_INDEX(path[depth].p_hdr))
++				return path[depth].p_idx[1].e_block;
++		}
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * returns first allocated block from next leaf or 0xffffffff
++ */
++static unsigned ext3_ext_next_leaf_block(struct inode *inode,
++                                               struct ext3_ext_path *path)
++{
++	int depth;
++
++	EXT_ASSERT(path != NULL);
++	depth = path->p_depth;
++
++	/* zero-tree has no leaf blocks at all */
++	if (depth == 0)
++		return 0xffffffff;
++
++	/* go to index block */
++	depth--;
++	
++	while (depth >= 0) {
++		if (path[depth].p_idx !=
++				EXT_LAST_INDEX(path[depth].p_hdr))
++			return path[depth].p_idx[1].e_block;
++		depth--;        
++	}
++
++	return 0xffffffff;
++}
++
++/*
++ * if leaf gets modified and modified extent is first in the leaf
++ * then we have to correct all indexes above
++ * TODO: do we need to correct tree in all cases?
++ */
++int ext3_ext_correct_indexes(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	int depth = EXT3_I(inode)->i_depth;	
++	struct ext3_extent_header *eh;
++	struct ext3_extent *ex;
++	long border;
++	int k, err = 0;
++	
++	eh = path[depth].p_hdr;
++	ex = path[depth].p_ext;
++
++	EXT_ASSERT(ex);
++	EXT_ASSERT(eh);
++	
++	if (depth == 0) {
++		/* there is no tree at all */
++		return 0;
++	}
++	
++	if (ex != EXT_FIRST_EXTENT(eh)) {
++		/* we correct tree if first leaf got modified only */
++		return 0;
++	}
++	
++	k = depth - 1;
++	border = path[depth].p_ext->e_block;
++	if ((err = ext3_ext_get_access(handle, inode, path + k)))
++		return err;
++	path[k].p_idx->e_block = border;
++	if ((err = ext3_ext_dirty(handle, inode, path + k)))
++		return err;
++
++	while (k--) {
++		/* change all left-side indexes */
++		if (path[k].p_idx != EXT_FIRST_INDEX(path[k].p_hdr)
++				&& k != 0)
++			break;
++		if ((err = ext3_ext_get_access(handle, inode, path + k)))
++			break;
++		path[k].p_idx->e_block = border;
++		if ((err = ext3_ext_dirty(handle, inode, path + k)))
++			break;
++	}
++
++	return err;
++}
++
++/*
++ * this routine tries to merge requsted extent into the existing
++ * extent or inserts requested extent as new one into the tree,
++ * creating new leaf in no-space case
++ */
++int ext3_ext_insert_extent(handle_t *handle, struct inode *inode,
++				struct ext3_ext_path *path,
++				struct ext3_extent *newext)
++{
++	int depth, len;
++	struct ext3_extent_header * eh;
++	struct ext3_extent *ex;
++	struct ext3_extent *nearex; /* nearest extent */
++	struct ext3_ext_path *npath = NULL;
++	int err;
++
++	depth = EXT3_I(inode)->i_depth;	
++	if ((ex = path[depth].p_ext)) {
++		/* try to insert block into found extent and return */
++		if (ex->e_block + ex->e_num == newext->e_block &&
++				ex->e_start + ex->e_num == newext->e_start) {
++#ifdef AGRESSIVE_TEST
++			if (ex->e_num >= 2)
++				goto repeat;
++#endif
++			if ((err = ext3_ext_get_access(handle, inode,
++							path + depth)))
++				return err;
++			ext_debug(inode, "append %d block to %d:%d (from %d)\n",
++					newext->e_num, ex->e_block, ex->e_num,
++					ex->e_start);
++			ex->e_num += newext->e_num;
++			err = ext3_ext_dirty(handle, inode, path + depth);
++			return err;
++		}
++	}
++
++repeat:
++	depth = EXT3_I(inode)->i_depth;	
++	eh = path[depth].p_hdr;
++	if (eh->e_num == eh->e_max) {
++		/* probably next leaf has space for us? */
++		int next = ext3_ext_next_leaf_block(inode, path);
++		if (next != 0xffffffff) {
++			ext_debug(inode, "next leaf block - %d\n", next);
++			EXT_ASSERT(!npath);
++			npath = ext3_ext_find_extent(inode, next, NULL);
++			if (IS_ERR(npath))
++				return PTR_ERR(npath);
++			EXT_ASSERT(npath->p_depth == path->p_depth);
++			eh = npath[depth].p_hdr;
++			if (eh->e_num < eh->e_max) {
++				ext_debug(inode,
++						"next leaf has free ext(%d)\n",
++						eh->e_num);
++				path = npath;
++				goto repeat;
++			}
++			ext_debug(inode, "next leaf hasno free space(%d,%d)\n",
++					eh->e_num, eh->e_max);
++		}
++		/*
++		 * there is no free space in found leaf
++		 * we're gonna add new leaf in the tree
++		 */
++		err = ext3_ext_create_new_leaf(handle, inode, path, newext);
++		if (err)
++			goto cleanup;
++		goto repeat;
++	}
++
++	nearex = path[depth].p_ext;
++
++	if ((err = ext3_ext_get_access(handle, inode, path + depth)))
++		goto cleanup;
++
++	if (!nearex) {
++		/* there is no extent in this leaf, create first one */
++		ext_debug(inode, "first extent in the leaf: %d:%d:%d\n",
++				newext->e_block, newext->e_start,
++				newext->e_num);
++		eh->e_num++;
++		path[depth].p_ext = EXT_FIRST_EXTENT(eh);
++
++	} else if (newext->e_block > nearex->e_block) {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = EXT_MAX_EXTENT(eh) - nearex;
++		len = (len - 1) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d after: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		ext3_ext_check_boundary(inode, path + depth, nearex + 2, len);
++		memmove(nearex + 2, nearex + 1, len);
++		path[depth].p_ext = nearex + 1;
++		eh->e_num++;
++	} else {
++		EXT_ASSERT(newext->e_block != nearex->e_block);
++		len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent);
++		len = len < 0 ? 0 : len;
++		ext_debug(inode, "insert %d:%d:%d before: nearest 0x%p, "
++				"move %d from 0x%p to 0x%p\n",
++				newext->e_block, newext->e_start, newext->e_num,
++				nearex, len, nearex + 1, nearex + 2);
++		memmove(nearex + 1, nearex, len);
++		path[depth].p_ext = nearex;
++		eh->e_num++;
++
++		/* time to correct all indexes above */
++		err = ext3_ext_correct_indexes(handle, inode, path);
++	}
++
++	if (!err) {
++		nearex = path[depth].p_ext;
++		nearex->e_block = newext->e_block;
++		nearex->e_start = newext->e_start;
++		nearex->e_num = newext->e_num;
++	}
++
++	err = ext3_ext_dirty(handle, inode, path + depth);
++
++cleanup:
++	if (npath) {
++		ext3_ext_drop_refs(inode, npath);
++		kfree(npath);
++	}
++		
++	return err;
++}
++
++int ext3_ext_get_block(handle_t *handle, struct inode *inode, long iblock,
++			struct buffer_head *bh_result, int create)
++{
++	struct ext3_ext_path *path;
++	int depth = EXT3_I(inode)->i_depth;
++	struct ext3_extent newex;
++	struct ext3_extent *ex;
++	int goal, newblock, err = 0;
++
++	ext_debug(inode, "block %d requested for inode %u, bh_result 0x%p\n",
++			(int) iblock, (unsigned) inode->i_ino, bh_result);
++	bh_result->b_state &= ~(1UL << BH_New);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* find extent for this block */
++	path = ext3_ext_find_extent(inode, iblock, NULL);
++	if (IS_ERR(path)) {
++		err = PTR_ERR(path);
++		goto out2;
++	}
++
++	if ((ex = path[depth].p_ext)) {
++		/* if found exent covers block, simple return it */
++		if (iblock >= ex->e_block && iblock < ex->e_block + ex->e_num) {
++			newblock = iblock - ex->e_block + ex->e_start;
++			ext_debug(inode, "%d fit into %d:%d -> %d\n",
++					(int) iblock, ex->e_block, ex->e_num,
++					newblock);
++			goto out;
++		}
++	}
++
++	/*
++	 * we couldn't try to create block if create flag is zero 
++	 */
++	if (!create) 
++		goto out2;
++
++	/* allocate new block */
++	goal = ext3_ext_find_goal(inode, path);
++	newblock = ext3_new_block(handle, inode, goal, 0, 0, &err);
++	if (!newblock)
++		goto out2;
++	ext_debug(inode, "allocate new block: goal %d, found %d\n",
++			goal, newblock);
++
++	/* try to insert new extent into found leaf and return */
++	newex.e_block = iblock;
++	newex.e_start = newblock;
++	newex.e_num = 1;
++	err = ext3_ext_insert_extent(handle, inode, path, &newex);
++	if (err)
++		goto out2;
++	
++	/* previous routine could use block we allocated */
++	newblock = newex.e_start;
++	bh_result->b_state |= (1UL << BH_New);
++
++out:
++	ext3_ext_show_leaf(inode, path);
++	bh_result->b_dev = inode->i_dev;
++	bh_result->b_blocknr = newblock;
++	bh_result->b_state |= (1UL << BH_Mapped);
++out2:
++	ext3_ext_drop_refs(inode, path);
++	kfree(path);
++	up(&EXT3_I(inode)->i_ext_sem);
++
++	return err;	
++}
++
++/*
++ * returns 1 if current index have to be freed (even partial)
++ */
++static int ext3_ext_more_to_truncate(struct inode *inode,
++				struct ext3_ext_path *path)
++{
++	EXT_ASSERT(path->p_idx);
++
++	if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr))
++		return 0;
++
++	/*
++	 * if truncate on deeper level happened it it wasn't partial
++	 * so we have to consider current index for truncation
++	 */
++	if (path->p_hdr->e_num == path->p_block)
++		return 0;
++
++	/*
++	 * put actual number of indexes to know is this number got
++	 * changed at the next iteration
++	 */
++	path->p_block = path->p_hdr->e_num;
++	
++	return 1;
++}
++
++/*
++ * routine removes index from the index block
++ * it's used in truncate case only. thus all requests are for
++ * last index in the block only
++ */
++int ext3_ext_remove_index(handle_t *handle, struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	struct buffer_head *bh;
++	int err;
++	
++	/* free index block */
++	path--;
++	EXT_ASSERT(path->p_hdr->e_num);
++	if ((err = ext3_ext_get_access(handle, inode, path)))
++		return err;
++	path->p_hdr->e_num--;
++	if ((err = ext3_ext_dirty(handle, inode, path)))
++		return err;
++	bh = sb_get_hash_table(inode->i_sb, path->p_idx->e_leaf);
++	ext3_forget(handle, 0, inode, bh, path->p_idx->e_leaf);
++	ext3_free_blocks(handle, inode, path->p_idx->e_leaf, 1);
++
++	ext_debug(inode, "index is empty, remove it, free block %d\n",
++			path->p_idx->e_leaf);
++	return err;
++}
++
++/*
++ * returns 1 if current extent needs to be freed (even partial)
++ * instead, returns 0
++ */
++int ext3_ext_more_leaves_to_truncate(struct inode *inode,
++					struct ext3_ext_path *path)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	struct ext3_extent *ex = path->p_ext;
++	int last_block; 
++
++	EXT_ASSERT(ex);
++
++	/* is there leave in the current leaf? */
++	if (ex < EXT_FIRST_EXTENT(path->p_hdr))
++		return 0;
++	
++	last_block = (inode->i_size + blocksize-1)
++			>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++
++	if (last_block >= ex->e_block + ex->e_num)
++		return 0;
++
++	/* seems it extent have to be freed */
++	return 1;
++}
++
++handle_t *ext3_ext_journal_restart(handle_t *handle, int needed)
++{
++	int err;
++
++	if (handle->h_buffer_credits > needed)
++		return handle;
++	if (!ext3_journal_extend(handle, needed))
++		return handle;
++	err = ext3_journal_restart(handle, needed);
++	
++	return handle;
++}
++
++/*
++ * this routine calculate max number of blocks to be modified
++ * while freeing extent and is intended to be used in truncate path
++ */
++static int ext3_ext_calc_credits(struct inode *inode,
++					struct ext3_ext_path *path,
++					int num)
++{
++	int depth = EXT3_I(inode)->i_depth;
++	int needed;
++	
++	/*
++	 * extent couldn't cross group, so we will modify
++	 * single bitmap block and single group descriptor
++	 */
++	needed = 2;
++
++	/*
++	 * if this is last extent in a leaf, then we have to
++	 * free leaf block and remove pointer from index above.
++	 * that pointer could be last in index block, so we'll
++	 * have to remove it too. this way we could modify/free
++	 * the whole path + root index (inode stored) will be
++	 * modified
++	 */
++	if (!path || (num == path->p_ext->e_num &&
++				path->p_ext == EXT_FIRST_EXTENT(path->p_hdr)))
++		needed += (depth * EXT3_ALLOC_NEEDED) + 1;
++
++	return needed;
++}
++
++/*
++ * core of the truncate procedure:
++ * - calculated what part of each extent in the requested leaf
++ *   need to be freed
++ * - frees and forgets these blocks
++ *
++ * TODO: we could optimize and free several extents during
++ *       single journal_restart()-journal_restart() cycle
++ */
++static int ext3_ext_truncate_leaf(handle_t *handle,
++					struct inode *inode,
++					struct ext3_ext_path *path,
++					int depth)
++{
++	unsigned blocksize = inode->i_sb->s_blocksize;
++	int last_block; 
++	int i, err = 0, sf, num;
++
++	ext_debug(inode, "level %d - leaf\n", depth);
++	if (!path->p_hdr)
++		path->p_hdr =
++			(struct ext3_extent_header *) path->p_bh->b_data;
++
++	EXT_ASSERT(path->p_hdr->e_num <= path->p_hdr->e_max);
++	
++	last_block = (inode->i_size + blocksize-1)
++					>> EXT3_BLOCK_SIZE_BITS(inode->i_sb);
++	path->p_ext = EXT_LAST_EXTENT(path->p_hdr);
++	while (ext3_ext_more_leaves_to_truncate(inode, path)) {
++
++		/* what part of extent have to be freed? */
++		sf = last_block > path->p_ext->e_block ?
++			last_block : path->p_ext->e_block;
++
++		/* number of blocks from extent to be freed */
++		num = path->p_ext->e_block + path->p_ext->e_num - sf;
++
++		/* calc physical first physical block to be freed */
++		sf = path->p_ext->e_start + (sf - path->p_ext->e_block);
++
++		i = ext3_ext_calc_credits(inode, path, num);
++		handle = ext3_ext_journal_restart(handle, i);
++		if (IS_ERR(handle))
++			return PTR_ERR(handle);
++		
++		ext_debug(inode, "free extent %d:%d:%d -> free %d:%d\n",
++				path->p_ext->e_block, path->p_ext->e_start,
++				path->p_ext->e_num, sf, num);
++		for (i = 0; i < num; i++) {
++			struct buffer_head *bh =
++				sb_get_hash_table(inode->i_sb, sf + i);
++			ext3_forget(handle, 0, inode, bh, sf + i);
++		}
++		ext3_free_blocks(handle, inode, sf, num);
++
++		/* collect extents usage stats */
++		spin_lock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++		EXT3_SB(inode->i_sb)->s_ext_extents++;
++		EXT3_SB(inode->i_sb)->s_ext_blocks += num;
++		spin_unlock(&EXT3_SB(inode->i_sb)->s_ext_lock);
++
++		/* reduce extent */
++		if ((err = ext3_ext_get_access(handle, inode, path)))
++			return err;
++		path->p_ext->e_num -= num;
++		if (path->p_ext->e_num == 0)
++			path->p_hdr->e_num--;
++		if ((err = ext3_ext_dirty(handle, inode, path)))
++			return err;
++
++		path->p_ext--;
++	}
++	
++	/* if this leaf is free, then we should
++	 * remove it from index block above */
++	if (path->p_hdr->e_num == 0 && depth > 0) 
++		err = ext3_ext_remove_index(handle, inode, path);
++
++	return err;
++}
++
++static void ext3_ext_collect_stats(struct inode *inode)
++{
++	int depth;
++	
++	/* skip inodes with old good bitmap */
++	if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++		return;
++	
++	/* collect on full truncate only */
++	if (inode->i_size)
++		return;
++
++	depth = EXT3_I(inode)->i_depth;
++	if (depth < EXT3_SB(inode->i_sb)->s_ext_mindepth)
++		 EXT3_SB(inode->i_sb)->s_ext_mindepth = depth;
++	if (depth > EXT3_SB(inode->i_sb)->s_ext_maxdepth)
++		 EXT3_SB(inode->i_sb)->s_ext_maxdepth = depth;
++	EXT3_SB(inode->i_sb)->s_ext_sum += depth;
++	EXT3_SB(inode->i_sb)->s_ext_count++;
++	
++}
++
++void ext3_ext_truncate(struct inode * inode)
++{
++	struct address_space *mapping = inode->i_mapping;
++	struct ext3_ext_path *path;
++	struct page * page;
++	handle_t *handle;
++	int i, depth, err = 0;
++
++	ext3_ext_collect_stats(inode);
++
++	/*
++	 * We have to lock the EOF page here, because lock_page() nests
++	 * outside journal_start().
++	 */
++	if ((inode->i_size & (inode->i_sb->s_blocksize - 1)) == 0) {
++		/* Block boundary? Nothing to do */
++		page = NULL;
++	} else {
++		page = grab_cache_page(mapping,
++				inode->i_size >> PAGE_CACHE_SHIFT);
++		if (!page)
++			return;
++	}
++
++	/*
++	 * probably first extent we're gonna free will be last in block
++	 */
++	i = ext3_ext_calc_credits(inode, NULL, 0);
++	handle = ext3_journal_start(inode, i);
++	if (IS_ERR(handle)) {
++		if (page) {
++			clear_highpage(page);
++			flush_dcache_page(page);
++			unlock_page(page);
++			page_cache_release(page);
++		}
++		return;
++	}
++
++	if (page)
++		ext3_block_truncate_page(handle, mapping, inode->i_size);
++
++	down(&EXT3_I(inode)->i_ext_sem);
++
++	/* 
++	 * TODO: optimization is possible here
++	 * probably we need not scaning at all,
++	 * because page truncation is enough
++	 */
++	if (ext3_orphan_add(handle, inode))
++		goto out_stop;
++
++	/* we have to know where to truncate from in crash case */
++	EXT3_I(inode)->i_disksize = inode->i_size;
++	ext3_mark_inode_dirty(handle, inode);
++
++	/*
++	 * we start scanning from right side freeing all the blocks
++	 * after i_size and walking into the deep
++	 */
++	i = 0;
++	depth = EXT3_I(inode)->i_depth;
++	path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL);
++	if (IS_ERR(path)) {
++		ext3_error(inode->i_sb, "ext3_ext_truncate",
++				"Can't allocate path array");
++		goto out_stop;
++	}
++	memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1));
++
++	path[i].p_hdr = (struct ext3_extent_header *) EXT3_I(inode)->i_data;
++	while (i >= 0 && err == 0) {
++		if (i == depth) {
++			/* this is leaf block */
++			err = ext3_ext_truncate_leaf(handle, inode,
++							path + i, i);
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			continue;
++		}
++		
++		/* this is index block */
++		if (!path[i].p_hdr) {
++			path[i].p_hdr =
++				(struct ext3_extent_header *) path[i].p_bh->b_data;
++			ext_debug(inode, "initialize header\n");
++		}
++
++		EXT_ASSERT(path[i].p_hdr->e_num <= path[i].p_hdr->e_max);
++		
++		if (!path[i].p_idx) {
++			/* this level hasn't touched yet */
++			path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr);
++			path[i].p_block = path[i].p_hdr->e_num + 1;
++			ext_debug(inode, "init index ptr: hdr 0x%p, num %d\n",
++					path[i].p_hdr, path[i].p_hdr->e_num);
++		} else {
++			/* we've already was here, see at next index */
++			path[i].p_idx--;
++		}
++
++		ext_debug(inode, "level %d - index, first 0x%p, cur 0x%p\n",
++				i, EXT_FIRST_INDEX(path[i].p_hdr),
++				path[i].p_idx);
++		if (ext3_ext_more_to_truncate(inode, path + i)) {
++			/* go to the next level */
++			ext_debug(inode, "move to level %d (block %d)\n", i+1,
++					path[i].p_idx->e_leaf);
++			memset(path + i + 1, 0, sizeof(*path));
++			path[i+1].p_bh = sb_bread(inode->i_sb,
++							path[i].p_idx->e_leaf);
++			if (!path[i+1].p_bh) {
++				/* should we reset i_size? */
++				err = -EIO;
++				break;
++			}
++			i++;
++		} else {
++			/* we finish processing this index, go up */
++			if (path[i].p_hdr->e_num == 0 && i > 0) {
++				/* index is empty, remove it
++				 * handle must be already prepared by the
++				 * truncate_leaf()
++				 */
++				err = ext3_ext_remove_index(handle, inode,
++								path + i);
++			}
++			/* root level have p_bh == NULL, brelse() eats this */
++			brelse(path[i].p_bh);
++			i--;
++			ext_debug(inode, "return to level %d\n", i);
++		}
++	}
++
++	/* TODO: flexible tree reduction should be here */
++	if (path->p_hdr->e_num == 0) {
++		/*
++		 * truncate to zero freed all the tree
++		 * so, we need to correct i_depth
++		 */
++		EXT3_I(inode)->i_depth = 0;
++		path->p_hdr->e_max = 0;
++		ext3_mark_inode_dirty(handle, inode);
++	}
++
++	kfree(path);
++
++	/* In a multi-transaction truncate, we only make the final
++	 * transaction synchronous */
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++out_stop:
++	/*
++	 * If this was a simple ftruncate(), and the file will remain alive
++	 * then we need to clear up the orphan record which we created above.
++	 * However, if this was a real unlink then we were called by
++	 * ext3_delete_inode(), and we allow that function to clean up the
++	 * orphan info for us.
++	 */
++	if (inode->i_nlink)
++		ext3_orphan_del(handle, inode);
++
++	up(&EXT3_I(inode)->i_ext_sem);
++	ext3_journal_stop(handle, inode);
++}
++
++/*
++ * this routine calculate max number of blocks we could modify
++ * in order to allocate new block for an inode
++ */
++int ext3_ext_writepage_trans_blocks(struct inode *inode, int num)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	int depth = ei->i_depth + 1;
++	int needed;
++	
++	/*
++	 * the worste case we're expecting is creation of the
++	 * new root (growing in depth) with index splitting
++	 * for splitting we have to consider depth + 1 because
++	 * previous growing could increase it
++	 */
++
++	/* 
++	 * growing in depth:
++	 * block allocation + new root + old root
++	 */
++	needed = EXT3_ALLOC_NEEDED + 2;
++
++	/* index split. we may need:
++	 *   allocate intermediate indexes and new leaf
++	 *   change two blocks at each level, but root
++	 *   modify root block (inode)
++	 */
++	needed += (depth * EXT3_ALLOC_NEEDED) + (2 * depth) + 1;
++
++	/* caller want to allocate num blocks */
++	needed *= num;
++	
++#ifdef CONFIG_QUOTA
++	/* 
++	 * FIXME: real calculation should be here
++	 * it depends on blockmap format of qouta file
++	 */
++	needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS;
++#endif
++
++	return needed;
++}
++
++/*
++ * called at mount time
++ */
++void ext3_ext_init(struct super_block *sb)
++{
++	/*
++	 * possible initialization would be here
++	 */
++
++	if (test_opt(sb, EXTENTS))
++		printk("EXT3-fs: file extents enabled\n");
++	spin_lock_init(&EXT3_SB(sb)->s_ext_lock);
++}
++
++/*
++ * called at umount time
++ */
++void ext3_ext_release(struct super_block *sb)
++{
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
++
++	/* show collected stats */
++	if (sbi->s_ext_count && sbi->s_ext_extents)
++		printk("EXT3-fs: min depth - %d, max depth - %d, "
++				"ave. depth - %d, ave. blocks/extent - %d\n",
++				sbi->s_ext_mindepth,
++				sbi->s_ext_maxdepth,
++				sbi->s_ext_sum / sbi->s_ext_count,
++				sbi->s_ext_blocks / sbi->s_ext_extents);
++}
++
+--- linux-2.4.20-vanilla/fs/ext3/ialloc.c~ext3-extents-2.4.20	2003-09-15 18:54:58.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/ext3/ialloc.c	2003-09-15 19:31:40.000000000 +0400
+@@ -569,6 +569,10 @@ repeat:
+ 	inode->u.ext3_i.i_prealloc_count = 0;
+ #endif
+ 	inode->u.ext3_i.i_block_group = i;
++ 	if (test_opt(sb, EXTENTS))
++ 		inode->u.ext3_i.i_flags |= EXT3_EXTENTS_FL;
++ 	inode->u.ext3_i.i_depth = 0;
++ 	sema_init(&inode->u.ext3_i.i_ext_sem, 1);
+ 	
+ 	if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL)
+ 		inode->i_flags |= S_SYNC;
+--- linux-2.4.20-vanilla/fs/ext3/inode.c~ext3-extents-2.4.20	2003-09-15 18:54:58.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/ext3/inode.c	2003-09-15 19:53:10.000000000 +0400
+@@ -848,6 +848,15 @@ changed:
+ 	goto reread;
+ }
+ 
++static inline int
++ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block,
++		struct buffer_head *bh, int create)
++{
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_get_block(handle, inode, block, bh, create);
++	return ext3_get_block_handle(handle, inode, block, bh, create);
++}
++
+ /*
+  * The BKL is not held on entry here.
+  */
+@@ -861,7 +870,7 @@ static int ext3_get_block(struct inode *
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
++	ret = ext3_get_block_wrap(handle, inode, iblock, bh_result, create);
+ 	return ret;
+ }
+ 
+@@ -879,7 +888,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
++	*errp = ext3_get_block_wrap(handle, inode, block, &dummy, create);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1403,7 +1412,7 @@ struct address_space_operations ext3_aop
+  * This required during truncate. We need to physically zero the tail end
+  * of that block so it doesn't yield old data if the file is later grown.
+  */
+-static int ext3_block_truncate_page(handle_t *handle,
++int ext3_block_truncate_page(handle_t *handle,
+ 		struct address_space *mapping, loff_t from)
+ {
+ 	unsigned long index = from >> PAGE_CACHE_SHIFT;
+@@ -1888,6 +1897,9 @@ void ext3_truncate(struct inode * inode)
+ 
+ 	ext3_discard_prealloc(inode);
+ 
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_truncate(inode);
++
+ 	handle = start_transaction(inode);
+ 	if (IS_ERR(handle))
+ 		return;		/* AKPM: return what? */
+@@ -2200,6 +2212,8 @@ void ext3_read_inode(struct inode * inod
+ 	inode->u.ext3_i.i_prealloc_count = 0;
+ #endif
+ 	inode->u.ext3_i.i_block_group = iloc.block_group;
++ 	inode->u.ext3_i.i_depth = raw_inode->osd2.linux2.l_i_depth;
++ 	sema_init(&inode->u.ext3_i.i_ext_sem, 1);
+ 
+ 	/*
+ 	 * NOTE! The in-memory inode i_data array is in little-endian order
+@@ -2321,6 +2335,7 @@ static int ext3_do_update_inode(handle_t
+ 		raw_inode->i_fsize = 0;
+ 	}
+ #endif
++  	raw_inode->osd2.linux2.l_i_depth = inode->u.ext3_i.i_depth;
+ 	raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl);
+ 	if (!S_ISREG(inode->i_mode)) {
+ 		raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext3_i.i_dir_acl);
+@@ -2525,6 +2540,9 @@ int ext3_writepage_trans_blocks(struct i
+ 	int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3;
+ 	int ret;
+ 	
++	if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
++		return ext3_ext_writepage_trans_blocks(inode, bpp);
++
+ 	if (ext3_should_journal_data(inode))
+ 		ret = 3 * (bpp + indirects) + 2;
+ 	else
+@@ -2961,7 +2979,7 @@ int ext3_prep_san_write(struct inode *in
+ 
+ 	/* alloc blocks one by one */
+ 	for (i = 0; i < nblocks; i++) {
+-		ret = ext3_get_block_handle(handle, inode, blocks[i],
++		ret = ext3_get_block_wrap(handle, inode, blocks[i],
+ 						&bh_tmp, 1);
+ 		if (ret)
+ 			break;
+@@ -3022,7 +3040,7 @@ int ext3_map_inode_page(struct inode *in
+                 if (blocks[i] != 0)
+                         continue;
+ 
+-                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
++                rc = ext3_get_block_wrap(handle, inode, iblock, &bh, 1);
+                 if (rc) {
+                         printk(KERN_INFO "ext3_map_inode_page: error %d "
+                                "allocating block %ld\n", rc, iblock);
+--- linux-2.4.20-vanilla/fs/ext3/Makefile~ext3-extents-2.4.20	2003-09-15 18:54:58.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/ext3/Makefile	2003-09-15 19:41:08.000000000 +0400
+@@ -12,7 +12,8 @@ O_TARGET := ext3.o
+ export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+-		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
++		extents.o
+ obj-m    := $(O_TARGET)
+ 
+ export-objs += xattr.o
+--- linux-2.4.20-vanilla/fs/ext3/super.c~ext3-extents-2.4.20	2003-09-15 18:54:59.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/ext3/super.c	2003-09-15 19:42:57.000000000 +0400
+@@ -619,6 +619,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_ext_release(sb);
+ 	ext3_stop_delete_thread(sbi);
+ 	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+@@ -765,6 +766,10 @@ static int parse_options (char * options
+ 				       "EXT3 Check option not supported\n");
+ #endif
+ 		}
++		else if (!strcmp (this_char, "extents"))
++ 			set_opt (sbi->s_mount_opt, EXTENTS);
++ 		else if (!strcmp (this_char, "extdebug"))
++ 			set_opt (sbi->s_mount_opt, EXTDEBUG);
+ 		else if (!strcmp (this_char, "debug"))
+ 			set_opt (*mount_options, DEBUG);
+ 		else if (!strcmp (this_char, "errors")) {
+@@ -1478,6 +1483,7 @@ struct super_block * ext3_read_super (st
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA ? "journal":
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
+ 		"writeback");
++	ext3_ext_init(sb);
+ 
+ 	return sb;
+ 
+--- linux-2.4.20-vanilla/include/linux/ext3_fs.h~ext3-extents-2.4.20	2003-09-15 18:54:58.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/ext3_fs.h	2003-09-15 20:15:52.000000000 +0400
+@@ -184,6 +184,7 @@ struct ext3_group_desc
+ #define EXT3_IMAGIC_FL			0x00002000 /* AFS directory */
+ #define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
+ #define EXT3_RESERVED_FL		0x80000000 /* reserved for ext3 lib */
++#define EXT3_EXTENTS_FL			0x00080000 /* Inode uses extents */
+ 
+ #define EXT3_FL_USER_VISIBLE		0x00005FFF /* User visible flags */
+ #define EXT3_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+@@ -244,7 +245,7 @@ struct ext3_inode {
+ 		struct {
+ 			__u8	l_i_frag;	/* Fragment number */
+ 			__u8	l_i_fsize;	/* Fragment size */
+-			__u16	i_pad1;
++			__u16	l_i_depth;
+ 			__u16	l_i_uid_high;	/* these 2 fields    */
+ 			__u16	l_i_gid_high;	/* were reserved2[0] */
+ 			__u32	l_i_reserved2;
+@@ -325,6 +326,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_IOPEN		0x8000	/* Allow access via iopen */
+ #define EXT3_MOUNT_IOPEN_NOPRIV		0x10000	/* Make iopen world-readable */
+ #define EXT3_MOUNT_ASYNCDEL		0x20000 /* Delayed deletion */
++#define EXT3_MOUNT_EXTENTS		0x40000	/* Extents support */
++#define EXT3_MOUNT_EXTDEBUG		0x80000	/* Extents debug */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -702,6 +705,10 @@ extern void ext3_discard_prealloc (struc
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern void ext3_truncate (struct inode *);
++extern int ext3_block_truncate_page(handle_t *, struct address_space *, loff_t);
++extern int ext3_forget(handle_t *handle, int is_metadata,
++		       struct inode *inode, struct buffer_head *bh,
++		       int blocknr);
+ #ifdef EXT3_DELETE_THREAD
+ extern void ext3_truncate_thread(struct inode *inode);
+ #endif
+@@ -765,6 +772,13 @@ extern struct inode_operations ext3_spec
+ extern struct inode_operations ext3_symlink_inode_operations;
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
++/* extents.c */
++extern int ext3_ext_writepage_trans_blocks(struct inode *, int);
++extern int ext3_ext_get_block(handle_t *, struct inode *, long,
++				struct buffer_head *, int);
++extern void ext3_ext_truncate(struct inode *);
++extern void ext3_ext_init(struct super_block *);
++extern void ext3_ext_release(struct super_block *);
+ 
+ #endif	/* __KERNEL__ */
+ 
+--- linux-2.4.20-vanilla/include/linux/ext3_fs_i.h~ext3-extents-2.4.20	2003-09-15 10:16:38.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/ext3_fs_i.h	2003-09-15 20:14:40.000000000 +0400
+@@ -73,6 +73,10 @@ struct ext3_inode_info {
+ 	 * by other means, so we have truncate_sem.
+ 	 */
+ 	struct rw_semaphore truncate_sem;
++
++	/* extents-related data */
++	struct semaphore i_ext_sem;
++	__u16 i_depth;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_I */
+--- linux-2.4.20-vanilla/include/linux/ext3_fs_sb.h~ext3-extents-2.4.20	2003-09-15 18:54:57.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/ext3_fs_sb.h	2003-09-15 20:14:40.000000000 +0400
+@@ -86,6 +86,16 @@ struct ext3_sb_info {
+ 	wait_queue_head_t s_delete_thread_queue;
+ 	wait_queue_head_t s_delete_waiter_queue;
+ #endif
++
++	/* extents */
++	int s_ext_debug;
++	int s_ext_mindepth;
++	int s_ext_maxdepth;
++	int s_ext_sum;
++	int s_ext_count;
++	spinlock_t s_ext_lock;
++	int s_ext_extents;
++	int s_ext_blocks;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_SB */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-extents-oflag-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-extents-oflag-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..53e00a460fe30ccbef7c401563c7bde648bdea69
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-extents-oflag-2.4.18-chaos.patch
@@ -0,0 +1,310 @@
+ fs/ext3/ialloc.c            |    5 +++--
+ fs/ext3/inode.c             |    2 +-
+ fs/ext3/namei.c             |   43 +++++++++++++++++++++++++++++++++++++------
+ include/asm-alpha/fcntl.h   |    1 +
+ include/asm-arm/fcntl.h     |    1 +
+ include/asm-cris/fcntl.h    |    1 +
+ include/asm-i386/fcntl.h    |    1 +
+ include/asm-ia64/fcntl.h    |    1 +
+ include/asm-m68k/fcntl.h    |    1 +
+ include/asm-mips/fcntl.h    |    1 +
+ include/asm-mips64/fcntl.h  |    1 +
+ include/asm-parisc/fcntl.h  |    1 +
+ include/asm-ppc/fcntl.h     |    1 +
+ include/asm-s390/fcntl.h    |    1 +
+ include/asm-s390x/fcntl.h   |    1 +
+ include/asm-sh/fcntl.h      |    1 +
+ include/asm-sparc/fcntl.h   |    1 +
+ include/asm-sparc64/fcntl.h |    1 +
+ include/linux/ext3_fs.h     |    2 +-
+ 19 files changed, 57 insertions(+), 10 deletions(-)
+
+--- linux-2.4.18-chaos/fs/ext3/ialloc.c~ext3-extents-oflag-2.4.18-chaos	2003-10-08 10:29:12.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/ialloc.c	2003-10-08 10:29:30.000000000 +0400
+@@ -331,7 +331,8 @@ int ext3_itable_block_used(struct super_
+  */
+ struct inode * ext3_new_inode (handle_t *handle,
+ 				const struct inode * dir, int mode,
+-				unsigned long goal)
++				unsigned long goal,
++				struct lookup_intent *it)
+ {
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+@@ -573,7 +574,7 @@ repeat:
+ 	ei->i_prealloc_count = 0;
+ #endif
+ 	ei->i_block_group = i;
+-	if (test_opt(sb, EXTENTS))
++	if (test_opt(sb, EXTENTS) && it && (it->it_flags & O_EXTENTS))
+ 		EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL;
+ 	ei->i_depth = 0;
+ 	sema_init(&ei->i_ext_sem, 1);
+--- linux-2.4.18-chaos/fs/ext3/namei.c~ext3-extents-oflag-2.4.18-chaos	2003-10-08 10:29:11.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/namei.c	2003-10-08 10:36:33.000000000 +0400
+@@ -1204,7 +1204,9 @@ static int ext3_add_nondir(handle_t *han
+ }
+ 
+ static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
+-						int mode, struct dentry *dentry)
++						int mode, struct dentry *dentry,
++						struct lookup_intent *it)
++
+ {
+ 	unsigned long inum = 0;
+ 
+@@ -1213,7 +1215,7 @@ static struct inode * ext3_new_inode_wan
+ 			(struct dentry_params *) dentry->d_fsdata;
+ 		inum = param->p_inum;
+ 	}
+-	return ext3_new_inode(handle, dir, mode, inum);
++	return ext3_new_inode(handle, dir, mode, inum, it);
+ }
+ 
+ /*
+@@ -1238,7 +1240,35 @@ static int ext3_create (struct inode * d
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry, NULL);
++	err = PTR_ERR(inode);
++	if (!IS_ERR(inode)) {
++		inode->i_op = &ext3_file_inode_operations;
++		inode->i_fop = &ext3_file_operations;
++		inode->i_mapping->a_ops = &ext3_aops;
++		err = ext3_add_nondir(handle, dentry, inode);
++		ext3_mark_inode_dirty(handle, inode);
++	}
++	ext3_journal_stop(handle, dir);
++	return err;
++}
++
++static int ext3_create_it (struct inode * dir, struct dentry * dentry, int mode,
++				struct lookup_intent *it)
++{
++	handle_t *handle; 
++	struct inode * inode;
++	int err;
++
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++
++	if (IS_SYNC(dir))
++		handle->h_sync = 1;
++
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry, it);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+@@ -1266,7 +1296,7 @@ static int ext3_mknod (struct inode * di
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry, NULL);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		init_special_inode(inode, mode, rdev);
+@@ -1296,7 +1326,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR|mode, dentry, NULL);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1688,7 +1718,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry,NULL);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1892,6 +1922,7 @@ end_rename:
+  * directories can handle most operations...
+  */
+ struct inode_operations ext3_dir_inode_operations = {
++	create_it:	ext3_create_it,		/* BKL held */
+ 	create:		ext3_create,		/* BKL held */
+ 	lookup:		ext3_lookup,		/* BKL held */
+ 	link:		ext3_link,		/* BKL held */
+--- linux-2.4.18-chaos/include/asm-alpha/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:07.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-alpha/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -22,6 +22,7 @@
+ #define O_LARGEFILE	0400000 /* will be set by the kernel on every open */
+ #define O_ATOMICLOOKUP	01000000 /* do atomic file lookup */
+ #define O_DIRECT	02000000 /* direct disk access - should check with OSF/1 */
++#define O_EXTENTS	04000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-arm/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:07.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-arm/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -21,6 +21,7 @@
+ #define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+ #define O_LARGEFILE	0400000
+ #define O_ATOMICLOOKUP 01000000
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-cris/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2001-02-09 03:32:44.000000000 +0300
++++ linux-2.4.18-chaos-alexey/include/asm-cris/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -22,6 +22,7 @@
+ #define O_LARGEFILE	0100000
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
++#define O_EXTENTS	01000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get f_flags */
+--- linux-2.4.18-chaos/include/asm-i386/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:09.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-i386/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -21,6 +21,7 @@
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
+ #define O_ATOMICLOOKUP	01000000 /* do atomic file lookup */
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-ia64/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:09.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-ia64/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -29,6 +29,7 @@
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
+ #define O_ATOMICLOOKUP  01000000 /* do atomic file lookup */
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-m68k/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2000-11-28 05:00:49.000000000 +0300
++++ linux-2.4.18-chaos-alexey/include/asm-m68k/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -20,6 +20,7 @@
+ #define O_NOFOLLOW	0100000	/* don't follow links */
+ #define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+ #define O_LARGEFILE	0400000
++#define O_EXTENTS	01000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-mips64/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-mips64/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -27,6 +27,7 @@
+ #define O_DIRECTORY	0x10000	/* must be a directory */
+ #define O_NOFOLLOW	0x20000	/* don't follow links */
+ #define O_ATOMICLOOKUP	0x40000
++#define O_EXTENTS	0x80000 /* create file with extents if possible */
+ 
+ #define O_NDELAY	O_NONBLOCK
+ 
+--- linux-2.4.18-chaos/include/asm-mips/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:14.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-mips/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -27,6 +27,7 @@
+ #define O_DIRECTORY	0x10000	/* must be a directory */
+ #define O_NOFOLLOW	0x20000	/* don't follow links */
+ #define O_ATOMICLOOKUP	0x40000
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define O_NDELAY	O_NONBLOCK
+ 
+--- linux-2.4.18-chaos/include/asm-parisc/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2000-12-05 23:29:39.000000000 +0300
++++ linux-2.4.18-chaos-alexey/include/asm-parisc/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -19,6 +19,7 @@
+ #define O_NOCTTY	00400000 /* not fcntl */
+ #define O_DSYNC		01000000 /* HPUX only */
+ #define O_RSYNC		02000000 /* HPUX only */
++#define O_EXTENTS	04000000 /* create file with extents if possible */
+ 
+ #define FASYNC		00020000 /* fcntl, for BSD compatibility */
+ #define O_DIRECT	00040000 /* direct disk access hint - currently ignored */
+--- linux-2.4.18-chaos/include/asm-ppc/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-ppc/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -24,6 +24,7 @@
+ #define O_LARGEFILE     0200000
+ #define O_DIRECT	0400000	/* direct disk access hint */
+ #define O_ATOMICLOOKUP 01000000	/* do atomic file lookup */
++#define O_EXTENT	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-s390/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-s390/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -28,6 +28,7 @@
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
+ #define O_ATOMICLOOKUP	01000000 /* do atomic file lookup */
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-s390x/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-s390x/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -28,6 +28,7 @@
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
+ #define O_ATOMICLOOKUP 01000000	/* do atomic file lookup */
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-sh/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:15.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-sh/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -21,6 +21,7 @@
+ #define O_DIRECTORY	0200000	/* must be a directory */
+ #define O_NOFOLLOW	0400000 /* don't follow links */
+ #define O_ATOMICLOOKUP  01000000
++#define O_EXTENTS	02000000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/asm-sparc64/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-sparc64/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -22,6 +22,7 @@
+ #define O_LARGEFILE	0x40000
+ #define O_ATOMICLOOKUP	0x80000 /* do atomic file lookup */
+ #define O_DIRECT        0x100000 /* direct disk access hint */
++#define O_EXTENTS	0x200000 /* create file with extents if possible */
+ 
+ 
+ #define F_DUPFD		0	/* dup */
+--- linux-2.4.18-chaos/include/asm-sparc/fcntl.h~ext3-extents-oflag-2.4.18-chaos	2003-07-28 17:52:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/asm-sparc/fcntl.h	2003-10-08 10:29:30.000000000 +0400
+@@ -22,6 +22,7 @@
+ #define O_LARGEFILE	0x40000
+ #define O_ATOMICLOOKUP	0x80000 /* do atomic file lookup */
+ #define O_DIRECT        0x100000 /* direct disk access hint */
++#define O_EXTENTS	0x200000 /* create file with extents if possible */
+ 
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+--- linux-2.4.18-chaos/include/linux/ext3_fs.h~ext3-extents-oflag-2.4.18-chaos	2003-10-08 10:29:12.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/ext3_fs.h	2003-10-08 10:29:30.000000000 +0400
+@@ -641,7 +641,7 @@ extern int ext3_sync_file (struct file *
+ 
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int,
+-				      unsigned long);
++				      unsigned long, struct lookup_intent *);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+ extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
+ extern unsigned long ext3_count_free_inodes (struct super_block *);
+--- linux-2.4.18-chaos/fs/ext3/inode.c~ext3-extents-oflag-2.4.18-chaos	2003-10-08 10:29:12.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/inode.c	2003-10-08 10:29:30.000000000 +0400
+@@ -2204,7 +2204,7 @@ void ext3_truncate_thread(struct inode *
+ 	if (IS_ERR(handle))
+ 		goto out_truncate;
+ 
+-	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0);
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0, 0);
+ 	if (IS_ERR(new_inode)) {
+ 		ext3_debug("truncate inode %lu directly (no new inodes)\n",
+ 			   old_inode->i_ino);
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-htree-2.4.19-pre1.patch b/lustre/kernel_patches/patches/ext3-htree-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..711e1f2f45d32f38aac81a74eae65287d89c128e
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-htree-2.4.19-pre1.patch
@@ -0,0 +1,2584 @@
+ fs/ext3/Makefile           |    2 
+ fs/ext3/dir.c              |  302 +++++++++
+ fs/ext3/file.c             |    3 
+ fs/ext3/hash.c             |  215 ++++++
+ fs/ext3/namei.c            | 1420 ++++++++++++++++++++++++++++++++++++++++-----
+ fs/ext3/super.c            |    7 
+ include/linux/ext3_fs.h    |   85 ++
+ include/linux/ext3_fs_sb.h |    2 
+ include/linux/ext3_jbd.h   |    2 
+ include/linux/rbtree.h     |    2 
+ lib/rbtree.c               |   42 +
+ 11 files changed, 1921 insertions(+), 161 deletions(-)
+
+Index: linux-2.4.19-pre1/fs/ext3/dir.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/dir.c	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/dir.c	2003-11-20 23:05:26.000000000 +0300
+@@ -21,12 +21,16 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/slab.h>
++#include <linux/rbtree.h>
+ 
+ static unsigned char ext3_filetype_table[] = {
+ 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+ };
+ 
+ static int ext3_readdir(struct file *, void *, filldir_t);
++static int ext3_dx_readdir(struct file * filp,
++			   void * dirent, filldir_t filldir);
+ 
+ struct file_operations ext3_dir_operations = {
+ 	read:		generic_read_dir,
+@@ -35,6 +39,17 @@
+ 	fsync:		ext3_sync_file,		/* BKL held */
+ };
+ 
++
++static unsigned char get_dtype(struct super_block *sb, int filetype)
++{
++	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
++	    (filetype >= EXT3_FT_MAX))
++		return DT_UNKNOWN;
++
++	return (ext3_filetype_table[filetype]);
++}
++			       
++
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ 			  struct ext3_dir_entry_2 * de,
+ 			  struct buffer_head * bh,
+@@ -79,6 +94,16 @@
+ 
+ 	sb = inode->i_sb;
+ 
++	if (is_dx(inode)) {
++		err = ext3_dx_readdir(filp, dirent, filldir);
++		if (err != ERR_BAD_DX_DIR)
++			return err;
++		/*
++		 * We don't set the inode dirty flag since it's not
++		 * critical that it get flushed back to the disk.
++		 */
++		EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
++	}
+ 	stored = 0;
+ 	bh = NULL;
+ 	offset = filp->f_pos & (sb->s_blocksize - 1);
+@@ -162,18 +187,12 @@
+ 				 * during the copy operation.
+ 				 */
+ 				unsigned long version = filp->f_version;
+-				unsigned char d_type = DT_UNKNOWN;
+ 
+-				if (EXT3_HAS_INCOMPAT_FEATURE(sb,
+-						EXT3_FEATURE_INCOMPAT_FILETYPE)
+-						&& de->file_type < EXT3_FT_MAX)
+-					d_type =
+-					  ext3_filetype_table[de->file_type];
+ 				error = filldir(dirent, de->name,
+ 						de->name_len,
+ 						filp->f_pos,
+ 						le32_to_cpu(de->inode),
+-						d_type);
++						get_dtype(sb, de->file_type));
+ 				if (error)
+ 					break;
+ 				if (version != filp->f_version)
+@@ -188,3 +207,272 @@
+ 	UPDATE_ATIME(inode);
+ 	return 0;
+ }
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * These functions convert from the major/minor hash to an f_pos
++ * value.
++ * 
++ * Currently we only use major hash numer.  This is unfortunate, but
++ * on 32-bit machines, the same VFS interface is used for lseek and
++ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
++ * lseek/telldir/seekdir will blow out spectacularly, and from within
++ * the ext2 low-level routine, we don't know if we're being called by
++ * a 64-bit version of the system call or the 32-bit version of the
++ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
++ * cookie.  Sigh.
++ */
++#define hash2pos(major, minor)	(major >> 1)
++#define pos2maj_hash(pos)	((pos << 1) & 0xffffffff)
++#define pos2min_hash(pos)	(0)
++
++/*
++ * This structure holds the nodes of the red-black tree used to store
++ * the directory entry in hash order.
++ */
++struct fname {
++	__u32		hash;
++	__u32		minor_hash;
++	rb_node_t	rb_hash; 
++	struct fname	*next;
++	__u32		inode;
++	__u8		name_len;
++	__u8		file_type;
++	char		name[0];
++};
++
++/*
++ * This functoin implements a non-recursive way of freeing all of the
++ * nodes in the red-black tree.
++ */
++static void free_rb_tree_fname(rb_root_t *root)
++{
++	rb_node_t	*n = root->rb_node;
++	rb_node_t	*parent;
++	struct fname	*fname;
++
++	while (n) {
++		/* Do the node's children first */
++		if ((n)->rb_left) {
++			n = n->rb_left;
++			continue;
++		}
++		if (n->rb_right) {
++			n = n->rb_right;
++			continue;
++		}
++		/*
++		 * The node has no children; free it, and then zero
++		 * out parent's link to it.  Finally go to the
++		 * beginning of the loop and try to free the parent
++		 * node.
++		 */
++		parent = n->rb_parent;
++		fname = rb_entry(n, struct fname, rb_hash);
++		kfree(fname);
++		if (!parent)
++			root->rb_node = 0;
++		else if (parent->rb_left == n)
++			parent->rb_left = 0;
++		else if (parent->rb_right == n)
++			parent->rb_right = 0;
++		n = parent;
++	}
++	root->rb_node = 0;
++}
++
++
++struct dir_private_info *create_dir_info(loff_t pos)
++{
++	struct dir_private_info *p;
++
++	p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
++	if (!p)
++		return NULL;
++	p->root.rb_node = 0;
++	p->curr_node = 0;
++	p->extra_fname = 0;
++	p->last_pos = 0;
++	p->curr_hash = pos2maj_hash(pos);
++	p->curr_minor_hash = pos2min_hash(pos);
++	p->next_hash = 0;
++	return p;
++}
++
++void ext3_htree_free_dir_info(struct dir_private_info *p)
++{
++	free_rb_tree_fname(&p->root);
++	kfree(p);
++}
++		
++/*
++ * Given a directory entry, enter it into the fname rb tree.
++ */
++int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++			     __u32 minor_hash,
++			     struct ext3_dir_entry_2 *dirent)
++{
++	rb_node_t **p, *parent = NULL;
++	struct fname * fname, *new_fn;
++	struct dir_private_info *info;
++	int len;
++
++	info = (struct dir_private_info *) dir_file->private_data;
++	p = &info->root.rb_node;
++
++	/* Create and allocate the fname structure */
++	len = sizeof(struct fname) + dirent->name_len + 1;
++	new_fn = kmalloc(len, GFP_KERNEL);
++	if (!new_fn)
++		return -ENOMEM;
++	memset(new_fn, 0, len);
++	new_fn->hash = hash;
++	new_fn->minor_hash = minor_hash;
++	new_fn->inode = le32_to_cpu(dirent->inode);
++	new_fn->name_len = dirent->name_len;
++	new_fn->file_type = dirent->file_type;
++	memcpy(new_fn->name, dirent->name, dirent->name_len);
++	new_fn->name[dirent->name_len] = 0;
++	
++	while (*p) {
++		parent = *p;
++		fname = rb_entry(parent, struct fname, rb_hash);
++
++		/*
++		 * If the hash and minor hash match up, then we put
++		 * them on a linked list.  This rarely happens...
++		 */
++		if ((new_fn->hash == fname->hash) &&
++		    (new_fn->minor_hash == fname->minor_hash)) {
++			new_fn->next = fname->next;
++			fname->next = new_fn;
++			return 0;
++		}
++			
++		if (new_fn->hash < fname->hash)
++			p = &(*p)->rb_left;
++		else if (new_fn->hash > fname->hash)
++			p = &(*p)->rb_right;
++		else if (new_fn->minor_hash < fname->minor_hash)
++			p = &(*p)->rb_left;
++		else /* if (new_fn->minor_hash > fname->minor_hash) */
++			p = &(*p)->rb_right;
++	}
++
++	rb_link_node(&new_fn->rb_hash, parent, p);
++	rb_insert_color(&new_fn->rb_hash, &info->root);
++	return 0;
++}
++
++
++
++/*
++ * This is a helper function for ext3_dx_readdir.  It calls filldir
++ * for all entres on the fname linked list.  (Normally there is only
++ * one entry on the linked list, unless there are 62 bit hash collisions.)
++ */
++static int call_filldir(struct file * filp, void * dirent,
++			filldir_t filldir, struct fname *fname)
++{
++	struct dir_private_info *info = filp->private_data;
++	loff_t	curr_pos;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct super_block * sb;
++	int error;
++
++	sb = inode->i_sb;
++	
++	if (!fname) {
++		printk("call_filldir: called with null fname?!?\n");
++		return 0;
++	}
++	curr_pos = hash2pos(fname->hash, fname->minor_hash);
++	while (fname) {
++		error = filldir(dirent, fname->name,
++				fname->name_len, curr_pos, 
++				fname->inode,
++				get_dtype(sb, fname->file_type));
++		if (error) {
++			filp->f_pos = curr_pos;
++			info->extra_fname = fname->next;
++			return error;
++		}
++		fname = fname->next;
++	}
++	return 0;
++}
++
++static int ext3_dx_readdir(struct file * filp,
++			 void * dirent, filldir_t filldir)
++{
++	struct dir_private_info *info = filp->private_data;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct fname *fname;
++	int	ret;
++
++	if (!info) {
++		info = create_dir_info(filp->f_pos);
++		if (!info)
++			return -ENOMEM;
++		filp->private_data = info;
++	}
++
++	/* Some one has messed with f_pos; reset the world */
++	if (info->last_pos != filp->f_pos) {
++		free_rb_tree_fname(&info->root);
++		info->curr_node = 0;
++		info->extra_fname = 0;
++		info->curr_hash = pos2maj_hash(filp->f_pos);
++		info->curr_minor_hash = pos2min_hash(filp->f_pos);
++	}
++
++	/*
++	 * If there are any leftover names on the hash collision
++	 * chain, return them first.
++	 */
++	if (info->extra_fname &&
++	    call_filldir(filp, dirent, filldir, info->extra_fname))
++		goto finished;
++
++	if (!info->curr_node)
++		info->curr_node = rb_get_first(&info->root);
++
++	while (1) {
++		/*
++		 * Fill the rbtree if we have no more entries,
++		 * or the inode has changed since we last read in the
++		 * cached entries. 
++		 */
++		if ((!info->curr_node) ||
++		    (filp->f_version != inode->i_version)) {
++			info->curr_node = 0;
++			free_rb_tree_fname(&info->root);
++			filp->f_version = inode->i_version;
++			ret = ext3_htree_fill_tree(filp, info->curr_hash,
++						   info->curr_minor_hash,
++						   &info->next_hash);
++			if (ret < 0)
++				return ret;
++			if (ret == 0)
++				break;
++			info->curr_node = rb_get_first(&info->root);
++		}
++
++		fname = rb_entry(info->curr_node, struct fname, rb_hash);
++		info->curr_hash = fname->hash;
++		info->curr_minor_hash = fname->minor_hash;
++		if (call_filldir(filp, dirent, filldir, fname))
++			break;
++
++		info->curr_node = rb_get_next(info->curr_node);
++		if (!info->curr_node) {
++			info->curr_hash = info->next_hash;
++			info->curr_minor_hash = 0;
++		}
++	}
++finished:
++	info->last_pos = filp->f_pos;
++	UPDATE_ATIME(inode);
++	return 0;
++}
++#endif
+Index: linux-2.4.19-pre1/fs/ext3/file.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/file.c	2001-11-16 00:37:55.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/file.c	2003-11-20 23:05:26.000000000 +0300
+@@ -35,6 +35,9 @@
+ {
+ 	if (filp->f_mode & FMODE_WRITE)
+ 		ext3_discard_prealloc (inode);
++	if (is_dx(inode) && filp->private_data)
++		ext3_htree_free_dir_info(filp->private_data);
++
+ 	return 0;
+ }
+ 
+Index: linux-2.4.19-pre1/fs/ext3/hash.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/hash.c	2003-11-20 23:05:26.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/hash.c	2003-11-20 23:05:26.000000000 +0300
+@@ -0,0 +1,215 @@
++/*
++ *  linux/fs/ext3/hash.c
++ *
++ * Copyright (C) 2002 by Theodore Ts'o
++ *
++ * This file is released under the GPL v2.
++ * 
++ * This file may be redistributed under the terms of the GNU Public
++ * License.
++ */
++
++#include <linux/fs.h>
++#include <linux/jbd.h>
++#include <linux/sched.h>
++#include <linux/ext3_fs.h>
++
++#define DELTA 0x9E3779B9
++
++static void TEA_transform(__u32 buf[4], __u32 const in[])
++{
++	__u32	sum = 0;
++	__u32	b0 = buf[0], b1 = buf[1];
++	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
++	int	n = 16;
++
++	do {							
++		sum += DELTA;					
++		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
++		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
++	} while(--n);
++
++	buf[0] += b0;
++	buf[1] += b1;
++}
++
++/* F, G and H are basic MD4 functions: selection, majority, parity */
++#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
++#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
++#define H(x, y, z) ((x) ^ (y) ^ (z))
++
++/*
++ * The generic round function.  The application is so specific that
++ * we don't bother protecting all the arguments with parens, as is generally
++ * good macro practice, in favor of extra legibility.
++ * Rotation is separate from addition to prevent recomputation
++ */
++#define ROUND(f, a, b, c, d, x, s)	\
++	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
++#define K1 0
++#define K2 013240474631UL
++#define K3 015666365641UL
++
++/*
++ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
++ */
++static void halfMD4Transform (__u32 buf[4], __u32 const in[])
++{
++	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
++
++	/* Round 1 */
++	ROUND(F, a, b, c, d, in[0] + K1,  3);
++	ROUND(F, d, a, b, c, in[1] + K1,  7);
++	ROUND(F, c, d, a, b, in[2] + K1, 11);
++	ROUND(F, b, c, d, a, in[3] + K1, 19);
++	ROUND(F, a, b, c, d, in[4] + K1,  3);
++	ROUND(F, d, a, b, c, in[5] + K1,  7);
++	ROUND(F, c, d, a, b, in[6] + K1, 11);
++	ROUND(F, b, c, d, a, in[7] + K1, 19);
++
++	/* Round 2 */
++	ROUND(G, a, b, c, d, in[1] + K2,  3);
++	ROUND(G, d, a, b, c, in[3] + K2,  5);
++	ROUND(G, c, d, a, b, in[5] + K2,  9);
++	ROUND(G, b, c, d, a, in[7] + K2, 13);
++	ROUND(G, a, b, c, d, in[0] + K2,  3);
++	ROUND(G, d, a, b, c, in[2] + K2,  5);
++	ROUND(G, c, d, a, b, in[4] + K2,  9);
++	ROUND(G, b, c, d, a, in[6] + K2, 13);
++
++	/* Round 3 */
++	ROUND(H, a, b, c, d, in[3] + K3,  3);
++	ROUND(H, d, a, b, c, in[7] + K3,  9);
++	ROUND(H, c, d, a, b, in[2] + K3, 11);
++	ROUND(H, b, c, d, a, in[6] + K3, 15);
++	ROUND(H, a, b, c, d, in[1] + K3,  3);
++	ROUND(H, d, a, b, c, in[5] + K3,  9);
++	ROUND(H, c, d, a, b, in[0] + K3, 11);
++	ROUND(H, b, c, d, a, in[4] + K3, 15);
++
++	buf[0] += a;
++	buf[1] += b;
++	buf[2] += c;
++	buf[3] += d;
++}
++
++#undef ROUND
++#undef F
++#undef G
++#undef H
++#undef K1
++#undef K2
++#undef K3
++
++/* The old legacy hash */
++static __u32 dx_hack_hash (const char *name, int len)
++{
++	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++	while (len--) {
++		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++		
++		if (hash & 0x80000000) hash -= 0x7fffffff;
++		hash1 = hash0;
++		hash0 = hash;
++	}
++	return (hash0 << 1);
++}
++
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++{
++	__u32	pad, val;
++	int	i;
++
++	pad = (__u32)len | ((__u32)len << 8);
++	pad |= pad << 16;
++
++	val = pad;
++	if (len > num*4)
++		len = num * 4;
++	for (i=0; i < len; i++) {
++		if ((i % 4) == 0)
++			val = pad;
++		val = msg[i] + (val << 8);
++		if ((i % 4) == 3) {
++			*buf++ = val;
++			val = pad;
++			num--;
++		}
++	}
++	if (--num >= 0)
++		*buf++ = val;
++	while (--num >= 0)
++		*buf++ = pad;
++}
++
++/*
++ * Returns the hash of a filename.  If len is 0 and name is NULL, then
++ * this function can be used to test whether or not a hash version is
++ * supported.
++ * 
++ * The seed is an 4 longword (32 bits) "secret" which can be used to
++ * uniquify a hash.  If the seed is all zero's, then some default seed
++ * may be used.
++ * 
++ * A particular hash version specifies whether or not the seed is
++ * represented, and whether or not the returned hash is 32 bits or 64
++ * bits.  32 bit hashes will return 0 for the minor hash.
++ */
++int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
++{
++	__u32	hash;
++	__u32	minor_hash = 0;
++	const char	*p;
++	int		i;
++	__u32 		in[8], buf[4];
++
++	/* Initialize the default seed for the hash checksum functions */
++	buf[0] = 0x67452301;
++	buf[1] = 0xefcdab89;
++	buf[2] = 0x98badcfe;
++	buf[3] = 0x10325476;
++
++	/* Check to see if the seed is all zero's */
++	if (hinfo->seed) {
++		for (i=0; i < 4; i++) {
++			if (hinfo->seed[i])
++				break;
++		}
++		if (i < 4)
++			memcpy(buf, hinfo->seed, sizeof(buf));
++	}
++		
++	switch (hinfo->hash_version) {
++	case DX_HASH_LEGACY:
++		hash = dx_hack_hash(name, len);
++		break;
++	case DX_HASH_HALF_MD4:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 8);
++			halfMD4Transform(buf, in);
++			len -= 32;
++			p += 32;
++		}
++		minor_hash = buf[2];
++		hash = buf[1];
++		break;
++	case DX_HASH_TEA:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 4);
++			TEA_transform(buf, in);
++			len -= 16;
++			p += 16;
++		}
++		hash = buf[0];
++		minor_hash = buf[1];
++		break;
++	default:
++		hinfo->hash = 0;
++		return -1;
++	}
++	hinfo->hash = hash & ~1;
++	hinfo->minor_hash = minor_hash;
++	return 0;
++}
+Index: linux-2.4.19-pre1/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/Makefile	2003-11-20 19:01:58.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/Makefile	2003-11-20 23:05:26.000000000 +0300
+@@ -12,7 +12,7 @@
+ export-objs :=	super.o inode.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o
++		ioctl.o namei.o super.o symlink.o hash.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.19-pre1/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/namei.c	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/namei.c	2003-11-20 23:22:54.000000000 +0300
+@@ -16,6 +16,12 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  *  Directory entry file type support and forward compatibility hooks
+  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
++ *  Hash Tree Directory indexing (c)
++ *  	Daniel Phillips, 2001
++ *  Hash Tree Directory indexing porting
++ *  	Christopher Li, 2002
++ *  Hash Tree Directory indexing cleanup
++ * 	Theodore Ts'o, 2002
+  */
+ 
+ #include <linux/fs.h>
+@@ -38,6 +44,642 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+ 
++static struct buffer_head *ext3_append(handle_t *handle,
++					struct inode *inode,
++					u32 *block, int *err)
++{
++	struct buffer_head *bh;
++
++	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
++
++	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++		inode->i_size += inode->i_sb->s_blocksize;
++		EXT3_I(inode)->i_disksize = inode->i_size;
++		ext3_journal_get_write_access(handle,bh);
++	}
++	return bh;
++}
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#ifndef swap
++#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
++#endif
++
++typedef struct { u32 v; } le_u32;
++typedef struct { u16 v; } le_u16;
++
++#ifdef DX_DEBUG
++#define dxtrace(command) command
++#else
++#define dxtrace(command) 
++#endif
++
++struct fake_dirent
++{
++	/*le*/u32 inode;
++	/*le*/u16 rec_len;
++	u8 name_len;
++	u8 file_type;
++};
++
++struct dx_countlimit
++{
++	le_u16 limit;
++	le_u16 count;
++};
++
++struct dx_entry
++{
++	le_u32 hash;
++	le_u32 block;
++};
++
++/*
++ * dx_root_info is laid out so that if it should somehow get overlaid by a
++ * dirent the two low bits of the hash version will be zero.  Therefore, the
++ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
++ */
++
++struct dx_root
++{
++	struct fake_dirent dot;
++	char dot_name[4];
++	struct fake_dirent dotdot;
++	char dotdot_name[4];
++	struct dx_root_info
++	{
++		le_u32 reserved_zero;
++		u8 hash_version;
++		u8 info_length; /* 8 */
++		u8 indirect_levels;
++		u8 unused_flags;
++	}
++	info;
++	struct dx_entry	entries[0];
++};
++
++struct dx_node
++{
++	struct fake_dirent fake;
++	struct dx_entry	entries[0];
++};
++
++
++struct dx_frame
++{
++	struct buffer_head *bh;
++	struct dx_entry *entries;
++	struct dx_entry *at;
++};
++
++struct dx_map_entry
++{
++	u32 hash;
++	u32 offs;
++};
++
++#ifdef CONFIG_EXT3_INDEX
++static inline unsigned dx_get_block (struct dx_entry *entry);
++static void dx_set_block (struct dx_entry *entry, unsigned value);
++static inline unsigned dx_get_hash (struct dx_entry *entry);
++static void dx_set_hash (struct dx_entry *entry, unsigned value);
++static unsigned dx_get_count (struct dx_entry *entries);
++static unsigned dx_get_limit (struct dx_entry *entries);
++static void dx_set_count (struct dx_entry *entries, unsigned value);
++static void dx_set_limit (struct dx_entry *entries, unsigned value);
++static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
++static unsigned dx_node_limit (struct inode *dir);
++static struct dx_frame *dx_probe(struct dentry *dentry,
++				 struct inode *dir,
++				 struct dx_hash_info *hinfo,
++				 struct dx_frame *frame,
++				 int *err);
++static void dx_release (struct dx_frame *frames);
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
++static void dx_sort_map(struct dx_map_entry *map, unsigned count);
++static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
++		struct dx_map_entry *offsets, int count);
++static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
++static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash);
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err);
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode);
++
++/*
++ * Future: use high four bits of block for coalesce-on-delete flags
++ * Mask them off for now.
++ */
++
++static inline unsigned dx_get_block (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->block.v) & 0x00ffffff;
++}
++
++static inline void dx_set_block (struct dx_entry *entry, unsigned value)
++{
++	entry->block.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_hash (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->hash.v);
++}
++
++static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
++{
++	entry->hash.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_count (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
++}
++
++static inline unsigned dx_get_limit (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
++}
++
++static inline void dx_set_count (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
++}
++
++static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
++}
++
++static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
++		EXT3_DIR_REC_LEN(2) - infosize;
++	return 0? 20: entry_space / sizeof(struct dx_entry);
++}
++
++static inline unsigned dx_node_limit (struct inode *dir)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
++	return 0? 22: entry_space / sizeof(struct dx_entry);
++}
++
++/*
++ * Debug
++ */
++#ifdef DX_DEBUG
++struct stats
++{ 
++	unsigned names;
++	unsigned space;
++	unsigned bcount;
++};
++
++static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
++				 int size, int show_names)
++{
++	unsigned names = 0, space = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	printk("names: ");
++	while ((char *) de < base + size)
++	{
++		if (de->inode)
++		{
++			if (show_names)
++			{
++				int len = de->name_len;
++				char *name = de->name;
++				while (len--) printk("%c", *name++);
++				ext3fs_dirhash(de->name, de->name_len, &h);
++				printk(":%x.%u ", h.hash,
++				       ((char *) de - base));
++			}
++			space += EXT3_DIR_REC_LEN(de->name_len);
++	 		names++;
++		}
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	printk("(%i)\n", names);
++	return (struct stats) { names, space, 1 };
++}
++
++struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
++			     struct dx_entry *entries, int levels)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
++	unsigned bcount = 0;
++	struct buffer_head *bh;
++	int err;
++	printk("%i indexed blocks...\n", count);
++	for (i = 0; i < count; i++, entries++)
++	{
++		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
++		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
++		struct stats stats;
++		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
++		if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
++		stats = levels?
++		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
++		   dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
++		names += stats.names;
++		space += stats.space;
++		bcount += stats.bcount;
++		brelse (bh);
++	}
++	if (bcount)
++		printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
++			names, space/bcount,(space/bcount)*100/blocksize);
++	return (struct stats) { names, space, bcount};
++}
++#endif /* DX_DEBUG */
++
++/*
++ * Probe for a directory leaf block to search.
++ *
++ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
++ * error in the directory index, and the caller should fall back to
++ * searching the directory normally.  The callers of dx_probe **MUST**
++ * check for this error code, and make sure it never gets reflected
++ * back to userspace.
++ */
++static struct dx_frame *
++dx_probe(struct dentry *dentry, struct inode *dir,
++	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
++{
++	unsigned count, indirect;
++	struct dx_entry *at, *entries, *p, *q, *m;
++	struct dx_root *root;
++	struct buffer_head *bh;
++	struct dx_frame *frame = frame_in;
++	u32 hash;
++
++	frame->bh = NULL;
++	if (dentry)
++		dir = dentry->d_parent->d_inode;
++	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
++		goto fail;
++	root = (struct dx_root *) bh->b_data;
++	if (root->info.hash_version != DX_HASH_TEA &&
++	    root->info.hash_version != DX_HASH_HALF_MD4 &&
++	    root->info.hash_version != DX_HASH_LEGACY) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unrecognised inode hash code %d",
++			     root->info.hash_version);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++	hinfo->hash_version = root->info.hash_version;
++	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	if (dentry)
++		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	hash = hinfo->hash;
++
++	if (root->info.unused_flags & 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash flags: %#06x",
++			     root->info.unused_flags);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	if ((indirect = root->info.indirect_levels) > 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash depth: %#06x",
++			     root->info.indirect_levels);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	while (1)
++	{
++		count = dx_get_count(entries);
++		assert (count && count <= dx_get_limit(entries));
++		p = entries + 1;
++		q = entries + count - 1;
++		while (p <= q)
++		{
++			m = p + (q - p)/2;
++			dxtrace(printk("."));
++			if (dx_get_hash(m) > hash)
++				q = m - 1;
++			else
++				p = m + 1;
++		}
++
++		if (0) // linear search cross check
++		{
++			unsigned n = count - 1;
++			at = entries;
++			while (n--)
++			{
++				dxtrace(printk(","));
++				if (dx_get_hash(++at) > hash)
++				{
++					at--;
++					break;
++				}
++			}
++			assert (at == p - 1);
++		}
++
++		at = p - 1;
++		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		frame->bh = bh;
++		frame->entries = entries;
++		frame->at = at;
++		if (!indirect--) return frame;
++		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++			goto fail2;
++		at = entries = ((struct dx_node *) bh->b_data)->entries;
++		assert (dx_get_limit(entries) == dx_node_limit (dir));
++		frame++;
++	}
++fail2:
++	while (frame >= frame_in) {
++		brelse(frame->bh);
++		frame--;
++	}
++fail:
++	return NULL;
++}
++
++static void dx_release (struct dx_frame *frames)
++{
++	if (frames[0].bh == NULL)
++		return;
++
++	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++		brelse(frames[1].bh);
++	brelse(frames[0].bh);
++}
++
++/*
++ * This function increments the frame pointer to search the next leaf
++ * block, and reads in the necessary intervening nodes if the search
++ * should be necessary.  Whether or not the search is necessary is
++ * controlled by the hash parameter.  If the hash value is even, then
++ * the search is only continued if the next block starts with that
++ * hash value.  This is used if we are searching for a specific file.
++ *
++ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
++ *
++ * This function returns 1 if the caller should continue to search,
++ * or 0 if it should not.  If there is an error reading one of the
++ * index blocks, it will return -1.
++ *
++ * If start_hash is non-null, it will be filled in with the starting
++ * hash of the next page.
++ */
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash)
++{
++	struct dx_frame *p;
++	struct buffer_head *bh;
++	int num_frames = 0;
++	__u32 bhash;
++
++	*err = ENOENT;
++	p = frame;
++	/*
++	 * Find the next leaf page by incrementing the frame pointer.
++	 * If we run out of entries in the interior node, loop around and
++	 * increment pointer in the parent node.  When we break out of
++	 * this loop, num_frames indicates the number of interior
++	 * nodes need to be read.
++	 */
++	while (1) {
++		if (++(p->at) < p->entries + dx_get_count(p->entries))
++			break;
++		if (p == frames)
++			return 0;
++		num_frames++;
++		p--;
++	}
++
++	/*
++	 * If the hash is 1, then continue only if the next page has a
++	 * continuation hash of any value.  This is used for readdir
++	 * handling.  Otherwise, check to see if the hash matches the
++	 * desired contiuation hash.  If it doesn't, return since
++	 * there's no point to read in the successive index pages.
++	 */
++	bhash = dx_get_hash(p->at);
++	if (start_hash)
++		*start_hash = bhash;
++	if ((hash & 1) == 0) {
++		if ((bhash & ~1) != hash)
++			return 0;
++	}
++	/*
++	 * If the hash is HASH_NB_ALWAYS, we always go to the next
++	 * block so no check is necessary
++	 */
++	while (num_frames--) {
++		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
++				      0, err)))
++			return -1; /* Failure */
++		p++;
++		brelse (p->bh);
++		p->bh = bh;
++		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++	}
++	return 1;
++}
++
++
++/*
++ * p is at least 6 bytes before the end of page
++ */
++static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
++{
++	return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
++}
++
++/*
++ * This function fills a red-black tree with information from a
++ * directory.  We start scanning the directory in hash order, starting
++ * at start_hash and start_minor_hash.
++ *
++ * This function returns the number of entries inserted into the tree,
++ * or a negative error code.
++ */
++int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++			 __u32 start_minor_hash, __u32 *next_hash)
++{
++	struct dx_hash_info hinfo;
++	struct buffer_head *bh;
++	struct ext3_dir_entry_2 *de, *top;
++	static struct dx_frame frames[2], *frame;
++	struct inode *dir;
++	int block, err;
++	int count = 0;
++	int ret;
++	__u32 hashval;
++	
++	dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
++		       start_minor_hash));
++	dir = dir_file->f_dentry->d_inode;
++	hinfo.hash = start_hash;
++	hinfo.minor_hash = 0;
++	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++
++	/* Add '.' and '..' from the htree header */
++	if (!start_hash && !start_minor_hash) {
++		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		de = ext3_next_entry(de);
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		count += 2;
++	}
++
++	while (1) {
++		block = dx_get_block(frame->at);
++		dxtrace(printk("Reading block %d\n", block));
++		if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
++			goto errout;
++	
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de)) {
++			ext3fs_dirhash(de->name, de->name_len, &hinfo);
++			if ((hinfo.hash < start_hash) ||
++			    ((hinfo.hash == start_hash) &&
++			     (hinfo.minor_hash < start_minor_hash)))
++				continue;
++			if ((err = ext3_htree_store_dirent(dir_file,
++				   hinfo.hash, hinfo.minor_hash, de)) != 0)
++				goto errout;
++			count++;
++		}
++		brelse (bh);
++		hashval = ~1;
++		ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
++					    frame, frames, &err, &hashval);
++		if (next_hash)
++			*next_hash = hashval;
++		if (ret == -1)
++			goto errout;
++		/*
++		 * Stop if:  (a) there are no more entries, or
++		 * (b) we have inserted at least one entry and the
++		 * next hash value is not a continuation
++		 */
++		if ((ret == 0) ||
++		    (count && ((hashval & 1) == 0)))
++			break;
++	}
++	dx_release(frames);
++	dxtrace(printk("Fill tree: returned %d entries\n", count));
++	return count;
++errout:
++	dx_release(frames);
++	return (err);
++}
++
++
++/*
++ * Directory block splitting, compacting
++ */
++
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
++{
++	int count = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	while ((char *) de < base + size)
++	{
++		if (de->name_len && de->inode) {
++			ext3fs_dirhash(de->name, de->name_len, &h);
++			map_tail--;
++			map_tail->hash = h.hash;
++			map_tail->offs = (u32) ((char *) de - base);
++			count++;
++		}
++		/* XXX: do we need to check rec_len == 0 case? -Chris */
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	return count;
++}
++
++static void dx_sort_map (struct dx_map_entry *map, unsigned count)
++{
++        struct dx_map_entry *p, *q, *top = map + count - 1;
++        int more;
++        /* Combsort until bubble sort doesn't suck */
++        while (count > 2)
++	{
++                count = count*10/13;
++                if (count - 9 < 2) /* 9, 10 -> 11 */
++                        count = 11;
++                for (p = top, q = p - count; q >= map; p--, q--)
++                        if (p->hash < q->hash)
++                                swap(*p, *q);
++        }
++        /* Garden variety bubble sort */
++        do {
++                more = 0;
++                q = top;
++                while (q-- > map)
++		{
++                        if (q[1].hash >= q[0].hash)
++				continue;
++                        swap(*(q+1), *q);
++                        more = 1;
++		}
++	} while(more);
++}
++
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++{
++	struct dx_entry *entries = frame->entries;
++	struct dx_entry *old = frame->at, *new = old + 1;
++	int count = dx_get_count(entries);
++
++	assert(count < dx_get_limit(entries));
++	assert(old < entries + count);
++	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++	dx_set_hash(new, hash);
++	dx_set_block(new, block);
++	dx_set_count(entries, count + 1);
++}
++#endif
++
++
++static void ext3_update_dx_flag(struct inode *inode)
++{
++	if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
++				     EXT3_FEATURE_COMPAT_DIR_INDEX))
++		EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
++}
++
+ /*
+  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+  *
+@@ -94,6 +736,7 @@
+ 	return 0;
+ }
+ 
++
+ /*
+  *	ext3_find_entry()
+  *
+@@ -105,6 +748,8 @@
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
++
++	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+ 					struct ext3_dir_entry_2 ** res_dir)
+ {
+@@ -119,12 +764,32 @@
+ 	int num = 0;
+ 	int nblocks, i, err;
+ 	struct inode *dir = dentry->d_parent->d_inode;
++	int namelen;
++	const u8 *name;
++	unsigned blocksize;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+-
++	blocksize = sb->s_blocksize;
++	namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++	if (namelen > EXT3_NAME_LEN)
++		return NULL;
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		/*
++		 * On success, or if the error was file not found,
++		 * return.  Otherwise, fall back to doing a search the
++		 * old fashioned way.
++		 */
++		if (bh || (err != ERR_BAD_DX_DIR))
++			return bh;
++		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++	}
++#endif
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+-	start = dir->u.ext3_i.i_dir_start_lookup;
++	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+ 		start = 0;
+ 	block = start;
+@@ -165,7 +830,7 @@
+ 		i = search_dirblock(bh, dir, dentry,
+ 			    block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
+ 		if (i == 1) {
+-			dir->u.ext3_i.i_dir_start_lookup = block;
++			EXT3_I(dir)->i_dir_start_lookup = block;
+ 			ret = bh;
+ 			goto cleanup_and_exit;
+ 		} else {
+@@ -196,6 +861,66 @@
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err)
++{
++	struct super_block * sb;
++	struct dx_hash_info	hinfo;
++	u32 hash;
++	struct dx_frame frames[2], *frame;
++	struct ext3_dir_entry_2 *de, *top;
++	struct buffer_head *bh;
++	unsigned long block;
++	int retval;
++	int namelen = dentry->d_name.len;
++	const u8 *name = dentry->d_name.name;
++	struct inode *dir = dentry->d_parent->d_inode;
++	
++	sb = dir->i_sb;
++	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++		return NULL;
++	hash = hinfo.hash;
++	do {
++		block = dx_get_block(frame->at);
++		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
++			goto errout;
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de))
++		if (ext3_match (namelen, name, de)) {
++			if (!ext3_check_dir_entry("ext3_find_entry",
++						  dir, de, bh,
++				  (block<<EXT3_BLOCK_SIZE_BITS(sb))
++					  +((char *)de - bh->b_data))) {
++				brelse (bh);
++				goto errout;
++			}
++			*res_dir = de;
++			dx_release (frames);
++			return bh;
++		}
++		brelse (bh);
++		/* Check to see if we should continue to search */
++		retval = ext3_htree_next_block(dir, hash, frame,
++					       frames, err, 0);
++		if (retval == -1) {
++			ext3_warning(sb, __FUNCTION__,
++			     "error reading index page in directory #%lu",
++			     dir->i_ino);
++			goto errout;
++		}
++	} while (retval == 1);
++	
++	*err = -ENOENT;
++errout:
++	dxtrace(printk("%s not found\n", name));
++	dx_release (frames);
++	return NULL;
++}
++#endif
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+@@ -212,8 +937,9 @@
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+-		if (!inode)
++		if (!inode) {
+ 			return ERR_PTR(-EACCES);
++		}
+ 	}
+ 	d_add(dentry, inode);
+ 	return NULL;
+@@ -237,6 +963,301 @@
+ 		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct ext3_dir_entry_2 *
++dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
++{
++	unsigned rec_len = 0;
++
++	while (count--) {
++		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		rec_len = EXT3_DIR_REC_LEN(de->name_len);
++		memcpy (to, de, rec_len);
++		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
++		de->inode = 0;
++		map++;
++		to += rec_len;
++	}
++	return (struct ext3_dir_entry_2 *) (to - rec_len);
++}
++
++static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
++{
++	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	unsigned rec_len = 0;
++
++	prev = to = de;
++	while ((char*)de < base + size) {
++		next = (struct ext3_dir_entry_2 *) ((char *) de +
++						    le16_to_cpu(de->rec_len));
++		if (de->inode && de->name_len) {
++			rec_len = EXT3_DIR_REC_LEN(de->name_len);
++			if (de > to)
++				memmove(to, de, rec_len);
++			to->rec_len = rec_len;
++			prev = to;
++			to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
++		}
++		de = next;
++	}
++	return prev;
++}
++
++static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
++			struct buffer_head **bh,struct dx_frame *frame,
++			struct dx_hash_info *hinfo, int *error)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count, continued;
++	struct buffer_head *bh2;
++	u32 newblock;
++	u32 hash2;
++	struct dx_map_entry *map;
++	char *data1 = (*bh)->b_data, *data2;
++	unsigned split;
++	struct ext3_dir_entry_2 *de = NULL, *de2;
++	int	err;
++
++	bh2 = ext3_append (handle, dir, &newblock, error);
++	if (!(bh2)) {
++		brelse(*bh);
++		*bh = NULL;
++		goto errout;
++	}
++
++	BUFFER_TRACE(*bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, *bh);
++	if (err) {
++	journal_error:
++		brelse(*bh);
++		brelse(bh2);
++		*bh = NULL;
++		ext3_std_error(dir->i_sb, err);
++		goto errout;
++	}
++	BUFFER_TRACE(frame->bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, frame->bh);
++	if (err)
++		goto journal_error;
++
++	data2 = bh2->b_data;
++
++	/* create map in the end of data2 block */
++	map = (struct dx_map_entry *) (data2 + blocksize);
++	count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
++			     blocksize, hinfo, map);
++	map -= count;
++	split = count/2; // need to adjust to actual middle
++	dx_sort_map (map, count);
++	hash2 = map[split].hash;
++	continued = hash2 == map[split - 1].hash;
++	dxtrace(printk("Split block %i at %x, %i/%i\n",
++		dx_get_block(frame->at), hash2, split, count-split));
++
++	/* Fancy dance to stay within two buffers */
++	de2 = dx_move_dirents(data1, data2, map + split, count - split);
++	de = dx_pack_dirents(data1,blocksize);
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++
++	/* Which block gets the new entry? */
++	if (hinfo->hash >= hash2)
++	{
++		swap(*bh, bh2);
++		de = de2;
++	}
++	dx_insert_block (frame, hash2 + continued, newblock);
++	err = ext3_journal_dirty_metadata (handle, bh2);
++	if (err)
++		goto journal_error;
++	err = ext3_journal_dirty_metadata (handle, frame->bh);
++	if (err)
++		goto journal_error;
++	brelse (bh2);
++	dxtrace(dx_show_index ("frame", frame->entries));
++errout:
++	return de;
++}
++#endif
++
++
++/*
++ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
++ * it points to a directory entry which is guaranteed to be large
++ * enough for new directory entry.  If de is NULL, then
++ * add_dirent_to_buf will attempt search the directory block for
++ * space.  It will return -ENOSPC if no space is available, and -EIO
++ * and -EEXIST if directory entry already exists.
++ * 
++ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
++ * all other cases bh is released.
++ */
++static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode, struct ext3_dir_entry_2 *de,
++			     struct buffer_head * bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	unsigned long	offset = 0;
++	unsigned short	reclen;
++	int		nlen, rlen, err;
++	char		*top;
++	
++	reclen = EXT3_DIR_REC_LEN(namelen);
++	if (!de) {
++		de = (struct ext3_dir_entry_2 *)bh->b_data;
++		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
++		while ((char *) de <= top) {
++			if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
++						  bh, offset)) {
++				brelse (bh);
++				return -EIO;
++			}
++			if (ext3_match (namelen, name, de)) {
++				brelse (bh);
++				return -EEXIST;
++			}
++			nlen = EXT3_DIR_REC_LEN(de->name_len);
++			rlen = le16_to_cpu(de->rec_len);
++			if ((de->inode? rlen - nlen: rlen) >= reclen)
++				break;
++			de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
++			offset += rlen;
++		}
++		if ((char *) de > top)
++			return -ENOSPC;
++	}
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err) {
++		ext3_std_error(dir->i_sb, err);
++		brelse(bh);
++		return err;
++	}
++	
++	/* By now the buffer is marked for journaling */
++	nlen = EXT3_DIR_REC_LEN(de->name_len);
++	rlen = le16_to_cpu(de->rec_len);
++	if (de->inode) {
++		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		de1->rec_len = cpu_to_le16(rlen - nlen);
++		de->rec_len = cpu_to_le16(nlen);
++		de = de1;
++	}
++	de->file_type = EXT3_FT_UNKNOWN;
++	if (inode) {
++		de->inode = cpu_to_le32(inode->i_ino);
++		ext3_set_de_type(dir->i_sb, de, inode->i_mode);
++	} else
++		de->inode = 0;
++	de->name_len = namelen;
++	memcpy (de->name, name, namelen);
++	/*
++	 * XXX shouldn't update any times until successful
++	 * completion of syscall, but too many callers depend
++	 * on this.
++	 *
++	 * XXX similarly, too many callers depend on
++	 * ext3_new_inode() setting the times, but error
++	 * recovery deletes the inode, so the worst that can
++	 * happen is that the times are slightly out of date
++	 * and/or different from the directory change time.
++	 */
++	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
++	ext3_update_dx_flag(dir);
++	dir->i_version = ++event;
++	ext3_mark_inode_dirty(handle, dir);
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		ext3_std_error(dir->i_sb, err);
++	brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * This converts a one block unindexed directory to a 3 block indexed
++ * directory, and adds the dentry to the indexed directory.
++ */
++static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
++			    struct inode *inode, struct buffer_head *bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	struct buffer_head *bh2;
++	struct dx_root	*root;
++	struct dx_frame	frames[2], *frame;
++	struct dx_entry *entries;
++	struct ext3_dir_entry_2	*de, *de2;
++	char		*data1, *top;
++	unsigned	len;
++	int		retval;
++	unsigned	blocksize;
++	struct dx_hash_info hinfo;
++	u32		block;
++		
++	blocksize =  dir->i_sb->s_blocksize;
++	dxtrace(printk("Creating index\n"));
++	retval = ext3_journal_get_write_access(handle, bh);
++	if (retval) {
++		ext3_std_error(dir->i_sb, retval);
++		brelse(bh);
++		return retval;
++	}
++	root = (struct dx_root *) bh->b_data;
++		
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	bh2 = ext3_append (handle, dir, &block, &retval);
++	if (!(bh2)) {
++		brelse(bh);
++		return retval;
++	}
++	data1 = bh2->b_data;
++
++	/* The 0th block becomes the root, move the dirents out */
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
++	len = ((char *) root) + blocksize - (char *) de;
++	memcpy (data1, de, len);
++	de = (struct ext3_dir_entry_2 *) data1;
++	top = data1 + len;
++	while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
++		de = de2;
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	/* Initialize the root; the dot dirents already exist */
++	de = (struct ext3_dir_entry_2 *) (&root->dotdot);
++	de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++	memset (&root->info, 0, sizeof(root->info));
++	root->info.info_length = sizeof(root->info);
++	root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
++	entries = root->entries;
++	dx_set_block (entries, 1);
++	dx_set_count (entries, 1);
++	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
++
++	/* Initialize as for dx_probe */
++	hinfo.hash_version = root->info.hash_version;
++	hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	ext3fs_dirhash(name, namelen, &hinfo);
++	frame = frames;
++	frame->entries = entries;
++	frame->at = entries;
++	frame->bh = bh;
++	bh = bh2;
++	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	dx_release (frames);
++	if (!(de))
++		return retval;
++
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
++#endif
++
+ /*
+  *	ext3_add_entry()
+  *
+@@ -247,127 +1268,198 @@
+  * may not sleep between calling this and putting something into
+  * the entry, as someone else might have used it while you slept.
+  */
+-
+-/*
+- * AKPM: the journalling code here looks wrong on the error paths
+- */
+ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+ 	struct inode *inode)
+ {
+ 	struct inode *dir = dentry->d_parent->d_inode;
+-	const char *name = dentry->d_name.name;
+-	int namelen = dentry->d_name.len;
+ 	unsigned long offset;
+-	unsigned short rec_len;
+ 	struct buffer_head * bh;
+-	struct ext3_dir_entry_2 * de, * de1;
++	struct ext3_dir_entry_2 *de;
+ 	struct super_block * sb;
+ 	int	retval;
++#ifdef CONFIG_EXT3_INDEX
++	int	dx_fallback=0;
++#endif
++	unsigned blocksize;
++	unsigned nlen, rlen;
++	u32 block, blocks;
+ 
+ 	sb = dir->i_sb;
+-
+-	if (!namelen)
++	blocksize = sb->s_blocksize;
++	if (!dentry->d_name.len)
+ 		return -EINVAL;
+-	bh = ext3_bread (handle, dir, 0, 0, &retval);
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		retval = ext3_dx_add_entry(handle, dentry, inode);
++		if (!retval || (retval != ERR_BAD_DX_DIR))
++			return retval;
++		EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
++		dx_fallback++;
++		ext3_mark_inode_dirty(handle, dir);
++	}
++#endif
++	blocks = dir->i_size >> sb->s_blocksize_bits;
++	for (block = 0, offset = 0; block < blocks; block++) {
++		bh = ext3_bread(handle, dir, block, 0, &retval);
++		if(!bh)
++			return retval;
++		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++		if (retval != -ENOSPC)
++			return retval;
++
++#ifdef CONFIG_EXT3_INDEX
++		if (blocks == 1 && !dx_fallback &&
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
++			return make_indexed_dir(handle, dentry, inode, bh);
++#endif
++		brelse(bh);
++	}
++	bh = ext3_append(handle, dir, &block, &retval);
+ 	if (!bh)
+ 		return retval;
+-	rec_len = EXT3_DIR_REC_LEN(namelen);
+-	offset = 0;
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+-	while (1) {
+-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+-			brelse (bh);
+-			bh = NULL;
+-			bh = ext3_bread (handle, dir,
+-				offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
+-			if (!bh)
+-				return retval;
+-			if (dir->i_size <= offset) {
+-				if (dir->i_size == 0) {
+-					brelse(bh);
+-					return -ENOENT;
+-				}
++	de->inode = 0;
++	de->rec_len = cpu_to_le16(rlen = blocksize);
++	nlen = 0;
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
+ 
+-				ext3_debug ("creating next block\n");
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * Returns 0 for success, or a negative error value
++ */
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode)
++{
++	struct dx_frame frames[2], *frame;
++	struct dx_entry *entries, *at;
++	struct dx_hash_info hinfo;
++	struct buffer_head * bh;
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block * sb = dir->i_sb;
++	struct ext3_dir_entry_2 *de;
++	int err;
+ 
+-				BUFFER_TRACE(bh, "get_write_access");
+-				ext3_journal_get_write_access(handle, bh);
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-				de->inode = 0;
+-				de->rec_len = le16_to_cpu(sb->s_blocksize);
+-				dir->u.ext3_i.i_disksize =
+-					dir->i_size = offset + sb->s_blocksize;
+-				dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-				ext3_mark_inode_dirty(handle, dir);
+-			} else {
++	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++	entries = frame->entries;
++	at = frame->at;
+ 
+-				ext3_debug ("skipping to next block\n");
++	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++		goto cleanup;
+ 
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-			}
+-		}
+-		if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
+-					   offset)) {
+-			brelse (bh);
+-			return -ENOENT;
+-		}
+-		if (ext3_match (namelen, name, de)) {
+-				brelse (bh);
+-				return -EEXIST;
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err)
++		goto journal_error;
++
++	err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++	if (err != -ENOSPC) {
++		bh = 0;
++		goto cleanup;
++	}
++
++	/* Block full, should compress but for now just split */
++	dxtrace(printk("using %u of %u node entries\n",
++		       dx_get_count(entries), dx_get_limit(entries)));
++	/* Need to split index? */
++	if (dx_get_count(entries) == dx_get_limit(entries)) {
++		u32 newblock;
++		unsigned icount = dx_get_count(entries);
++		int levels = frame - frames;
++		struct dx_entry *entries2;
++		struct dx_node *node2;
++		struct buffer_head *bh2;
++
++		if (levels && (dx_get_count(frames->entries) ==
++			       dx_get_limit(frames->entries))) {
++			ext3_warning(sb, __FUNCTION__,
++				     "Directory index full!\n");
++			err = -ENOSPC;
++			goto cleanup;
+ 		}
+-		if ((le32_to_cpu(de->inode) == 0 &&
+-				le16_to_cpu(de->rec_len) >= rec_len) ||
+-		    (le16_to_cpu(de->rec_len) >=
+-				EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
+-			BUFFER_TRACE(bh, "get_write_access");
+-			ext3_journal_get_write_access(handle, bh);
+-			/* By now the buffer is marked for journaling */
+-			offset += le16_to_cpu(de->rec_len);
+-			if (le32_to_cpu(de->inode)) {
+-				de1 = (struct ext3_dir_entry_2 *) ((char *) de +
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de1->rec_len =
+-					cpu_to_le16(le16_to_cpu(de->rec_len) -
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de->rec_len = cpu_to_le16(
+-						EXT3_DIR_REC_LEN(de->name_len));
+-				de = de1;
++		bh2 = ext3_append (handle, dir, &newblock, &err);
++		if (!(bh2))
++			goto cleanup;
++		node2 = (struct dx_node *)(bh2->b_data);
++		entries2 = node2->entries;
++		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
++		node2->fake.inode = 0;
++		BUFFER_TRACE(frame->bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, frame->bh);
++		if (err)
++			goto journal_error;
++		if (levels) {
++			unsigned icount1 = icount/2, icount2 = icount - icount1;
++			unsigned hash2 = dx_get_hash(entries + icount1);
++			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
++				
++			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++			err = ext3_journal_get_write_access(handle,
++							     frames[0].bh);
++			if (err)
++				goto journal_error;
++				
++			memcpy ((char *) entries2, (char *) (entries + icount1),
++				icount2 * sizeof(struct dx_entry));
++			dx_set_count (entries, icount1);
++			dx_set_count (entries2, icount2);
++			dx_set_limit (entries2, dx_node_limit(dir));
++
++			/* Which index block gets the new entry? */
++			if (at - entries >= icount1) {
++				frame->at = at = at - entries - icount1 + entries2;
++				frame->entries = entries = entries2;
++				swap(frame->bh, bh2);
+ 			}
+-			de->file_type = EXT3_FT_UNKNOWN;
+-			if (inode) {
+-				de->inode = cpu_to_le32(inode->i_ino);
+-				ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-			} else
+-				de->inode = 0;
+-			de->name_len = namelen;
+-			memcpy (de->name, name, namelen);
+-			/*
+-			 * XXX shouldn't update any times until successful
+-			 * completion of syscall, but too many callers depend
+-			 * on this.
+-			 *
+-			 * XXX similarly, too many callers depend on
+-			 * ext3_new_inode() setting the times, but error
+-			 * recovery deletes the inode, so the worst that can
+-			 * happen is that the times are slightly out of date
+-			 * and/or different from the directory change time.
+-			 */
+-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+-			dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-			ext3_mark_inode_dirty(handle, dir);
+-			dir->i_version = ++event;
+-			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-			ext3_journal_dirty_metadata(handle, bh);
+-			brelse(bh);
+-			return 0;
++			dx_insert_block (frames + 0, hash2, newblock);
++			dxtrace(dx_show_index ("node", frames[1].entries));
++			dxtrace(dx_show_index ("node",
++			       ((struct dx_node *) bh2->b_data)->entries));
++			err = ext3_journal_dirty_metadata(handle, bh2);
++			if (err)
++				goto journal_error;
++			brelse (bh2);
++		} else {
++			dxtrace(printk("Creating second level index...\n"));
++			memcpy((char *) entries2, (char *) entries,
++			       icount * sizeof(struct dx_entry));
++			dx_set_limit(entries2, dx_node_limit(dir));
++
++			/* Set up root */
++			dx_set_count(entries, 1);
++			dx_set_block(entries + 0, newblock);
++			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++
++			/* Add new access path frame */
++			frame = frames + 1;
++			frame->at = at = at - entries + entries2;
++			frame->entries = entries = entries2;
++			frame->bh = bh2;
++			err = ext3_journal_get_write_access(handle,
++							     frame->bh);
++			if (err)
++				goto journal_error;
+ 		}
+-		offset += le16_to_cpu(de->rec_len);
+-		de = (struct ext3_dir_entry_2 *)
+-			((char *) de + le16_to_cpu(de->rec_len));
++		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	brelse (bh);
+-	return -ENOSPC;
++	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	if (!de)
++		goto cleanup;
++	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	bh = 0;
++	goto cleanup;
++	
++journal_error:
++	ext3_std_error(dir->i_sb, err);
++cleanup:
++	if (bh)
++		brelse(bh);
++	dx_release(frames);
++	return err;
+ }
++#endif
+ 
+ /*
+  * ext3_delete_entry deletes a directory entry by merging it with the
+@@ -451,9 +1543,11 @@
+ 	struct inode * inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -478,9 +1572,11 @@
+ 	struct inode *inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -507,9 +1603,11 @@
+ 	if (dir->i_nlink >= EXT3_LINK_MAX)
+ 		return -EMLINK;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -521,7 +1619,7 @@
+ 
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+-	inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
++	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+ 	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+@@ -554,21 +1652,19 @@
+ 		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+-	if (err)
+-		goto out_no_entry;
++	if (err) {
++		inode->i_nlink = 0;
++		ext3_mark_inode_dirty(handle, inode);
++		iput (inode);
++		goto out_stop;
++	}
+ 	dir->i_nlink++;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	d_instantiate(dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	inode->i_nlink = 0;
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ /*
+@@ -655,7 +1751,7 @@
+ 	int err = 0, rc;
+ 	
+ 	lock_super(sb);
+-	if (!list_empty(&inode->u.ext3_i.i_orphan))
++	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+ 	/* Orphan handling is only valid for files with data blocks
+@@ -696,7 +1792,7 @@
+ 	 * This is safe: on error we're going to ignore the orphan list
+ 	 * anyway on the next recovery. */
+ 	if (!err)
+-		list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
++		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
+ 
+ 	jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+@@ -714,25 +1810,26 @@
+ int ext3_orphan_del(handle_t *handle, struct inode *inode)
+ {
+ 	struct list_head *prev;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct ext3_sb_info *sbi;
+ 	ino_t ino_next; 
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 	
+ 	lock_super(inode->i_sb);
+-	if (list_empty(&inode->u.ext3_i.i_orphan)) {
++	if (list_empty(&ei->i_orphan)) {
+ 		unlock_super(inode->i_sb);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+-	prev = inode->u.ext3_i.i_orphan.prev;
++	prev = ei->i_orphan.prev;
+ 	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
+ 
+-	list_del(&inode->u.ext3_i.i_orphan);
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++	list_del(&ei->i_orphan);
++	INIT_LIST_HEAD(&ei->i_orphan);
+ 
+ 	/* If we're on an error path, we may not have a valid
+ 	 * transaction handle with which to update the orphan list on
+@@ -793,8 +1890,9 @@
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	retval = -ENOENT;
+ 	bh = ext3_find_entry (dentry, &de);
+@@ -832,7 +1930,7 @@
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+ end_rmdir:
+@@ -850,8 +1948,9 @@
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -878,7 +1977,7 @@
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	inode->i_nlink--;
+ 	if (!inode->i_nlink)
+@@ -904,9 +2003,11 @@
+ 	if (l > dir->i_sb->s_blocksize)
+ 		return -ENAMETOOLONG;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -916,7 +2017,7 @@
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+ 
+-	if (l > sizeof (inode->u.ext3_i.i_data)) {
++	if (l > sizeof (EXT3_I(inode)->i_data)) {
+ 		inode->i_op = &page_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+@@ -925,8 +2026,12 @@
+ 		 * i_size in generic_commit_write().
+ 		 */
+ 		err = block_symlink(inode, symname, l);
+-		if (err)
+-			goto out_no_entry;
++		if (err) {
++			ext3_dec_count(handle, inode);
++			ext3_mark_inode_dirty(handle, inode);
++			iput (inode);
++			goto out_stop;
++		}
+ 	} else {
+ 		inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
+@@ -938,12 +2043,6 @@
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	ext3_dec_count(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ static int ext3_link (struct dentry * old_dentry,
+@@ -956,12 +2055,15 @@
+ 	if (S_ISDIR(inode->i_mode))
+ 		return -EPERM;
+ 
+-	if (inode->i_nlink >= EXT3_LINK_MAX)
++	if (inode->i_nlink >= EXT3_LINK_MAX) {
+ 		return -EMLINK;
++	}
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -995,9 +2097,11 @@
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+@@ -1070,14 +2174,33 @@
+ 	/*
+ 	 * ok, that's it
+ 	 */
+-	ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	retval = ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	if (retval == -ENOENT) {
++		/*
++		 * old_de could have moved out from under us.
++		 */
++		struct buffer_head *old_bh2;
++		struct ext3_dir_entry_2 *old_de2;
++		
++		old_bh2 = ext3_find_entry(old_dentry, &old_de2);
++		if (old_bh2) {
++			retval = ext3_delete_entry(handle, old_dir,
++						   old_de2, old_bh2);
++			brelse(old_bh2);
++		}
++	}
++	if (retval) {
++		ext3_warning(old_dir->i_sb, "ext3_rename",
++				"Deleting old file (%lu), %d, error=%d",
++				old_dir->i_ino, old_dir->i_nlink, retval);
++	}
+ 
+ 	if (new_inode) {
+ 		new_inode->i_nlink--;
+ 		new_inode->i_ctime = CURRENT_TIME;
+ 	}
+ 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+-	old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(old_dir);
+ 	if (dir_bh) {
+ 		BUFFER_TRACE(dir_bh, "get_write_access");
+ 		ext3_journal_get_write_access(handle, dir_bh);
+@@ -1089,7 +2212,7 @@
+ 			new_inode->i_nlink--;
+ 		} else {
+ 			new_dir->i_nlink++;
+-			new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++			ext3_update_dx_flag(new_dir);
+ 			ext3_mark_inode_dirty(handle, new_dir);
+ 		}
+ 	}
+Index: linux-2.4.19-pre1/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/super.c	2003-11-20 19:01:58.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/super.c	2003-11-20 23:05:26.000000000 +0300
+@@ -702,6 +702,7 @@
+ 	es->s_mtime = cpu_to_le32(CURRENT_TIME);
+ 	ext3_update_dynamic_rev(sb);
+ 	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
++
+ 	ext3_commit_super (sb, es, 1);
+ 	if (test_opt (sb, DEBUG))
+ 		printk (KERN_INFO
+@@ -712,6 +713,7 @@
+ 			EXT3_BLOCKS_PER_GROUP(sb),
+ 			EXT3_INODES_PER_GROUP(sb),
+ 			sbi->s_mount_opt);
++
+ 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
+ 				bdevname(sb->s_dev));
+ 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+@@ -886,6 +888,7 @@
+ 	return res;
+ }
+ 
++
+ struct super_block * ext3_read_super (struct super_block * sb, void * data,
+ 				      int silent)
+ {
+@@ -1062,6 +1065,9 @@
+ 	sbi->s_mount_state = le16_to_cpu(es->s_state);
+ 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+ 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++	for (i=0; i < 4; i++)
++		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
++	sbi->s_def_hash_version = es->s_def_hash_version;
+ 
+ 	if (sbi->s_blocks_per_group > blocksize * 8) {
+ 		printk (KERN_ERR
+@@ -1744,6 +1750,7 @@
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
++EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+Index: linux-2.4.19-pre1/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_fs.h	2003-11-20 19:01:38.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_fs.h	2003-11-20 23:05:26.000000000 +0300
+@@ -40,6 +40,11 @@
+ #define EXT3FS_VERSION		"2.4-0.9.17"
+ 
+ /*
++ * Always enable hashed directories
++ */
++#define CONFIG_EXT3_INDEX
++
++/*
+  * Debug code
+  */
+ #ifdef EXT3FS_DEBUG
+@@ -437,8 +442,11 @@
+ /*E0*/	__u32	s_journal_inum;		/* inode number of journal file */
+ 	__u32	s_journal_dev;		/* device number of journal file */
+ 	__u32	s_last_orphan;		/* start of list of inodes to delete */
+-
+-/*EC*/	__u32	s_reserved[197];	/* Padding to the end of the block */
++	__u32	s_hash_seed[4];		/* HTREE hash seed */
++	__u8	s_def_hash_version;	/* Default hash version to use */
++	__u8	s_reserved_char_pad;
++	__u16	s_reserved_word_pad;
++	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+ #ifdef __KERNEL__
+@@ -575,9 +583,46 @@
+ #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
+ 					 ~EXT3_DIR_ROUND)
++/*
++ * Hash Tree Directory indexing
++ * (c) Daniel Phillips, 2001
++ */
++
++#ifdef CONFIG_EXT3_INDEX
++  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++					      EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++		      (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
++#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#else
++  #define is_dx(dir) 0
++#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
++#endif
++
++/* Legal values for the dx_root hash_version field: */
++
++#define DX_HASH_LEGACY		0
++#define DX_HASH_HALF_MD4	1
++#define DX_HASH_TEA		2
++
++/* hash info structure used by the directory hash */
++struct dx_hash_info
++{
++	u32		hash;
++	u32		minor_hash;
++	int		hash_version;
++	u32		*seed;
++};
+ 
+ #ifdef __KERNEL__
+ /*
++ * Control parameters used by ext3_htree_next_block
++ */
++#define HASH_NB_ALWAYS		1
++
++
++/*
+  * Describe an inode's exact location on disk and in memory
+  */
+ struct ext3_iloc
+@@ -587,6 +632,27 @@
+ 	unsigned long block_group;
+ };
+ 
++
++/*
++ * This structure is stuffed into the struct file's private_data field
++ * for directories.  It is where we put information so that we can do
++ * readdir operations in hash tree order.
++ */
++struct dir_private_info {
++	rb_root_t	root;
++	rb_node_t	*curr_node;
++	struct fname	*extra_fname;
++	loff_t		last_pos;
++	__u32		curr_hash;
++	__u32		curr_minor_hash;
++	__u32		next_hash;
++};
++
++/*
++ * Special error return code only used by dx_probe() and its callers.
++ */
++#define ERR_BAD_DX_DIR	-75000
++
+ /*
+  * Function prototypes
+  */
+@@ -614,11 +680,20 @@
+ 
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
+-				struct ext3_dir_entry_2 *, struct buffer_head *,
+-				unsigned long);
++				struct ext3_dir_entry_2 *,
++				struct buffer_head *, unsigned long);
++extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++				    __u32 minor_hash,
++				    struct ext3_dir_entry_2 *dirent);
++extern void ext3_htree_free_dir_info(struct dir_private_info *p);
++
+ /* fsync.c */
+ extern int ext3_sync_file (struct file *, struct dentry *, int);
+ 
++/* hash.c */
++extern int ext3fs_dirhash(const char *name, int len, struct
++			  dx_hash_info *hinfo);
++
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+@@ -650,6 +725,8 @@
+ /* namei.c */
+ extern int ext3_orphan_add(handle_t *, struct inode *);
+ extern int ext3_orphan_del(handle_t *, struct inode *);
++extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++				__u32 start_minor_hash, __u32 *next_hash);
+ 
+ /* super.c */
+ extern void ext3_error (struct super_block *, const char *, const char *, ...)
+Index: linux-2.4.19-pre1/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_fs_sb.h	2003-11-20 19:01:38.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_fs_sb.h	2003-11-20 23:05:26.000000000 +0300
+@@ -62,6 +62,8 @@
+ 	int s_inode_size;
+ 	int s_first_ino;
+ 	u32 s_next_generation;
++	u32 s_hash_seed[4];
++	int s_def_hash_version;
+ 
+ 	/* Journaling */
+ 	struct inode * s_journal_inode;
+Index: linux-2.4.19-pre1/include/linux/ext3_jbd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_jbd.h	2001-12-21 20:42:03.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_jbd.h	2003-11-20 23:05:26.000000000 +0300
+@@ -63,6 +63,8 @@
+ 
+ #define EXT3_RESERVE_TRANS_BLOCKS	12
+ 
++#define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
++
+ int
+ ext3_mark_iloc_dirty(handle_t *handle, 
+ 		     struct inode *inode,
+Index: linux-2.4.19-pre1/include/linux/rbtree.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/rbtree.h	2001-11-22 22:46:18.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/rbtree.h	2003-11-20 23:05:26.000000000 +0300
+@@ -120,6 +120,8 @@
+ 
+ extern void rb_insert_color(rb_node_t *, rb_root_t *);
+ extern void rb_erase(rb_node_t *, rb_root_t *);
++extern rb_node_t *rb_get_first(rb_root_t *root);
++extern rb_node_t *rb_get_next(rb_node_t *n);
+ 
+ static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+ {
+Index: linux-2.4.19-pre1/lib/rbtree.c
+===================================================================
+--- linux-2.4.19-pre1.orig/lib/rbtree.c	2001-09-18 02:30:23.000000000 +0400
++++ linux-2.4.19-pre1/lib/rbtree.c	2003-11-20 23:25:57.000000000 +0300
+@@ -17,6 +17,8 @@
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+   linux/lib/rbtree.c
++
++  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+ */
+ 
+ #include <linux/rbtree.h>
+@@ -291,3 +293,43 @@
+ 	if (color == RB_BLACK)
+ 		__rb_erase_color(child, parent, root);
+ }
++
++/*
++ * This function returns the first node (in sort order) of the tree.
++ */
++rb_node_t *rb_get_first(rb_root_t *root)
++{
++	rb_node_t	*n;
++
++	n = root->rb_node;
++	if (!n)
++		return 0;
++	while (n->rb_left)
++		n = n->rb_left;
++	return n;
++}
++EXPORT_SYMBOL(rb_get_first);
++
++/*
++ * Given a node, this function will return the next node in the tree.
++ */
++rb_node_t *rb_get_next(rb_node_t *n)
++{
++	rb_node_t	*parent;
++
++	if (n->rb_right) {
++		n = n->rb_right;
++		while (n->rb_left)
++			n = n->rb_left;
++		return n;
++	} else {
++		while ((parent = n->rb_parent)) {
++			if (n == parent->rb_left)
++				return parent;
++			n = parent;
++		}
++		return 0;
++	}
++}
++EXPORT_SYMBOL(rb_get_next);
++
diff --git a/lustre/kernel_patches/patches/ext3-htree-2.4.22-rh.patch b/lustre/kernel_patches/patches/ext3-htree-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3230853da3220019b88d2f066d473cfaf2b0b58f
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-htree-2.4.22-rh.patch
@@ -0,0 +1,2569 @@
+ fs/ext3/Makefile           |    2 
+ fs/ext3/dir.c              |  302 +++++++++
+ fs/ext3/file.c             |    3 
+ fs/ext3/hash.c             |  215 ++++++
+ fs/ext3/namei.c            | 1421 ++++++++++++++++++++++++++++++++++++++++-----
+ fs/ext3/super.c            |    7 
+ include/linux/ext3_fs.h    |   85 ++
+ include/linux/ext3_fs_sb.h |    2 
+ include/linux/ext3_jbd.h   |    2 
+ include/linux/rbtree.h     |    2 
+ lib/rbtree.c               |   42 +
+ 11 files changed, 1922 insertions(+), 161 deletions(-)
+
+--- linux-2.4.22-ac1/fs/ext3/dir.c~ext3-htree-2.4.22-rh	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/dir.c	2003-09-25 14:58:30.000000000 +0400
+@@ -21,12 +21,16 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/slab.h>
++#include <linux/rbtree.h>
+ 
+ static unsigned char ext3_filetype_table[] = {
+ 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+ };
+ 
+ static int ext3_readdir(struct file *, void *, filldir_t);
++static int ext3_dx_readdir(struct file * filp,
++			   void * dirent, filldir_t filldir);
+ 
+ struct file_operations ext3_dir_operations = {
+ 	read:		generic_read_dir,
+@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
+ 	fsync:		ext3_sync_file,		/* BKL held */
+ };
+ 
++
++static unsigned char get_dtype(struct super_block *sb, int filetype)
++{
++	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
++	    (filetype >= EXT3_FT_MAX))
++		return DT_UNKNOWN;
++
++	return (ext3_filetype_table[filetype]);
++}
++			       
++
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ 			  struct ext3_dir_entry_2 * de,
+ 			  struct buffer_head * bh,
+@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
+ 
+ 	sb = inode->i_sb;
+ 
++	if (is_dx(inode)) {
++		err = ext3_dx_readdir(filp, dirent, filldir);
++		if (err != ERR_BAD_DX_DIR)
++			return err;
++		/*
++		 * We don't set the inode dirty flag since it's not
++		 * critical that it get flushed back to the disk.
++		 */
++		EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
++	}
+ 	stored = 0;
+ 	bh = NULL;
+ 	offset = filp->f_pos & (sb->s_blocksize - 1);
+@@ -162,18 +187,12 @@ revalidate:
+ 				 * during the copy operation.
+ 				 */
+ 				unsigned long version = filp->f_version;
+-				unsigned char d_type = DT_UNKNOWN;
+ 
+-				if (EXT3_HAS_INCOMPAT_FEATURE(sb,
+-						EXT3_FEATURE_INCOMPAT_FILETYPE)
+-						&& de->file_type < EXT3_FT_MAX)
+-					d_type =
+-					  ext3_filetype_table[de->file_type];
+ 				error = filldir(dirent, de->name,
+ 						de->name_len,
+ 						filp->f_pos,
+ 						le32_to_cpu(de->inode),
+-						d_type);
++						get_dtype(sb, de->file_type));
+ 				if (error)
+ 					break;
+ 				if (version != filp->f_version)
+@@ -188,3 +207,272 @@ revalidate:
+ 	UPDATE_ATIME(inode);
+ 	return 0;
+ }
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * These functions convert from the major/minor hash to an f_pos
++ * value.
++ * 
++ * Currently we only use major hash numer.  This is unfortunate, but
++ * on 32-bit machines, the same VFS interface is used for lseek and
++ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
++ * lseek/telldir/seekdir will blow out spectacularly, and from within
++ * the ext2 low-level routine, we don't know if we're being called by
++ * a 64-bit version of the system call or the 32-bit version of the
++ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
++ * cookie.  Sigh.
++ */
++#define hash2pos(major, minor)	(major >> 1)
++#define pos2maj_hash(pos)	((pos << 1) & 0xffffffff)
++#define pos2min_hash(pos)	(0)
++
++/*
++ * This structure holds the nodes of the red-black tree used to store
++ * the directory entry in hash order.
++ */
++struct fname {
++	__u32		hash;
++	__u32		minor_hash;
++	rb_node_t	rb_hash; 
++	struct fname	*next;
++	__u32		inode;
++	__u8		name_len;
++	__u8		file_type;
++	char		name[0];
++};
++
++/*
++ * This functoin implements a non-recursive way of freeing all of the
++ * nodes in the red-black tree.
++ */
++static void free_rb_tree_fname(rb_root_t *root)
++{
++	rb_node_t	*n = root->rb_node;
++	rb_node_t	*parent;
++	struct fname	*fname;
++
++	while (n) {
++		/* Do the node's children first */
++		if ((n)->rb_left) {
++			n = n->rb_left;
++			continue;
++		}
++		if (n->rb_right) {
++			n = n->rb_right;
++			continue;
++		}
++		/*
++		 * The node has no children; free it, and then zero
++		 * out parent's link to it.  Finally go to the
++		 * beginning of the loop and try to free the parent
++		 * node.
++		 */
++		parent = n->rb_parent;
++		fname = rb_entry(n, struct fname, rb_hash);
++		kfree(fname);
++		if (!parent)
++			root->rb_node = 0;
++		else if (parent->rb_left == n)
++			parent->rb_left = 0;
++		else if (parent->rb_right == n)
++			parent->rb_right = 0;
++		n = parent;
++	}
++	root->rb_node = 0;
++}
++
++
++struct dir_private_info *create_dir_info(loff_t pos)
++{
++	struct dir_private_info *p;
++
++	p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
++	if (!p)
++		return NULL;
++	p->root.rb_node = 0;
++	p->curr_node = 0;
++	p->extra_fname = 0;
++	p->last_pos = 0;
++	p->curr_hash = pos2maj_hash(pos);
++	p->curr_minor_hash = pos2min_hash(pos);
++	p->next_hash = 0;
++	return p;
++}
++
++void ext3_htree_free_dir_info(struct dir_private_info *p)
++{
++	free_rb_tree_fname(&p->root);
++	kfree(p);
++}
++		
++/*
++ * Given a directory entry, enter it into the fname rb tree.
++ */
++int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++			     __u32 minor_hash,
++			     struct ext3_dir_entry_2 *dirent)
++{
++	rb_node_t **p, *parent = NULL;
++	struct fname * fname, *new_fn;
++	struct dir_private_info *info;
++	int len;
++
++	info = (struct dir_private_info *) dir_file->private_data;
++	p = &info->root.rb_node;
++
++	/* Create and allocate the fname structure */
++	len = sizeof(struct fname) + dirent->name_len + 1;
++	new_fn = kmalloc(len, GFP_KERNEL);
++	if (!new_fn)
++		return -ENOMEM;
++	memset(new_fn, 0, len);
++	new_fn->hash = hash;
++	new_fn->minor_hash = minor_hash;
++	new_fn->inode = le32_to_cpu(dirent->inode);
++	new_fn->name_len = dirent->name_len;
++	new_fn->file_type = dirent->file_type;
++	memcpy(new_fn->name, dirent->name, dirent->name_len);
++	new_fn->name[dirent->name_len] = 0;
++	
++	while (*p) {
++		parent = *p;
++		fname = rb_entry(parent, struct fname, rb_hash);
++
++		/*
++		 * If the hash and minor hash match up, then we put
++		 * them on a linked list.  This rarely happens...
++		 */
++		if ((new_fn->hash == fname->hash) &&
++		    (new_fn->minor_hash == fname->minor_hash)) {
++			new_fn->next = fname->next;
++			fname->next = new_fn;
++			return 0;
++		}
++			
++		if (new_fn->hash < fname->hash)
++			p = &(*p)->rb_left;
++		else if (new_fn->hash > fname->hash)
++			p = &(*p)->rb_right;
++		else if (new_fn->minor_hash < fname->minor_hash)
++			p = &(*p)->rb_left;
++		else /* if (new_fn->minor_hash > fname->minor_hash) */
++			p = &(*p)->rb_right;
++	}
++
++	rb_link_node(&new_fn->rb_hash, parent, p);
++	rb_insert_color(&new_fn->rb_hash, &info->root);
++	return 0;
++}
++
++
++
++/*
++ * This is a helper function for ext3_dx_readdir.  It calls filldir
++ * for all entres on the fname linked list.  (Normally there is only
++ * one entry on the linked list, unless there are 62 bit hash collisions.)
++ */
++static int call_filldir(struct file * filp, void * dirent,
++			filldir_t filldir, struct fname *fname)
++{
++	struct dir_private_info *info = filp->private_data;
++	loff_t	curr_pos;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct super_block * sb;
++	int error;
++
++	sb = inode->i_sb;
++	
++	if (!fname) {
++		printk("call_filldir: called with null fname?!?\n");
++		return 0;
++	}
++	curr_pos = hash2pos(fname->hash, fname->minor_hash);
++	while (fname) {
++		error = filldir(dirent, fname->name,
++				fname->name_len, curr_pos, 
++				fname->inode,
++				get_dtype(sb, fname->file_type));
++		if (error) {
++			filp->f_pos = curr_pos;
++			info->extra_fname = fname->next;
++			return error;
++		}
++		fname = fname->next;
++	}
++	return 0;
++}
++
++static int ext3_dx_readdir(struct file * filp,
++			 void * dirent, filldir_t filldir)
++{
++	struct dir_private_info *info = filp->private_data;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct fname *fname;
++	int	ret;
++
++	if (!info) {
++		info = create_dir_info(filp->f_pos);
++		if (!info)
++			return -ENOMEM;
++		filp->private_data = info;
++	}
++
++	/* Some one has messed with f_pos; reset the world */
++	if (info->last_pos != filp->f_pos) {
++		free_rb_tree_fname(&info->root);
++		info->curr_node = 0;
++		info->extra_fname = 0;
++		info->curr_hash = pos2maj_hash(filp->f_pos);
++		info->curr_minor_hash = pos2min_hash(filp->f_pos);
++	}
++
++	/*
++	 * If there are any leftover names on the hash collision
++	 * chain, return them first.
++	 */
++	if (info->extra_fname &&
++	    call_filldir(filp, dirent, filldir, info->extra_fname))
++		goto finished;
++
++	if (!info->curr_node)
++		info->curr_node = rb_get_first(&info->root);
++
++	while (1) {
++		/*
++		 * Fill the rbtree if we have no more entries,
++		 * or the inode has changed since we last read in the
++		 * cached entries. 
++		 */
++		if ((!info->curr_node) ||
++		    (filp->f_version != inode->i_version)) {
++			info->curr_node = 0;
++			free_rb_tree_fname(&info->root);
++			filp->f_version = inode->i_version;
++			ret = ext3_htree_fill_tree(filp, info->curr_hash,
++						   info->curr_minor_hash,
++						   &info->next_hash);
++			if (ret < 0)
++				return ret;
++			if (ret == 0)
++				break;
++			info->curr_node = rb_get_first(&info->root);
++		}
++
++		fname = rb_entry(info->curr_node, struct fname, rb_hash);
++		info->curr_hash = fname->hash;
++		info->curr_minor_hash = fname->minor_hash;
++		if (call_filldir(filp, dirent, filldir, fname))
++			break;
++
++		info->curr_node = rb_get_next(info->curr_node);
++		if (!info->curr_node) {
++			info->curr_hash = info->next_hash;
++			info->curr_minor_hash = 0;
++		}
++	}
++finished:
++	info->last_pos = filp->f_pos;
++	UPDATE_ATIME(inode);
++	return 0;
++}
++#endif
+--- linux-2.4.22-ac1/fs/ext3/file.c~ext3-htree-2.4.22-rh	2003-08-25 15:44:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/file.c	2003-09-25 14:55:12.000000000 +0400
+@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino
+ {
+ 	if (filp->f_mode & FMODE_WRITE)
+ 		ext3_discard_prealloc (inode);
++	if (is_dx(inode) && filp->private_data)
++		ext3_htree_free_dir_info(filp->private_data);
++
+ 	return 0;
+ }
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/hash.c	2003-09-25 14:55:12.000000000 +0400
+@@ -0,0 +1,215 @@
++/*
++ *  linux/fs/ext3/hash.c
++ *
++ * Copyright (C) 2002 by Theodore Ts'o
++ *
++ * This file is released under the GPL v2.
++ * 
++ * This file may be redistributed under the terms of the GNU Public
++ * License.
++ */
++
++#include <linux/fs.h>
++#include <linux/jbd.h>
++#include <linux/sched.h>
++#include <linux/ext3_fs.h>
++
++#define DELTA 0x9E3779B9
++
++static void TEA_transform(__u32 buf[4], __u32 const in[])
++{
++	__u32	sum = 0;
++	__u32	b0 = buf[0], b1 = buf[1];
++	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
++	int	n = 16;
++
++	do {							
++		sum += DELTA;					
++		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
++		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
++	} while(--n);
++
++	buf[0] += b0;
++	buf[1] += b1;
++}
++
++/* F, G and H are basic MD4 functions: selection, majority, parity */
++#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
++#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
++#define H(x, y, z) ((x) ^ (y) ^ (z))
++
++/*
++ * The generic round function.  The application is so specific that
++ * we don't bother protecting all the arguments with parens, as is generally
++ * good macro practice, in favor of extra legibility.
++ * Rotation is separate from addition to prevent recomputation
++ */
++#define ROUND(f, a, b, c, d, x, s)	\
++	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
++#define K1 0
++#define K2 013240474631UL
++#define K3 015666365641UL
++
++/*
++ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
++ */
++static void halfMD4Transform (__u32 buf[4], __u32 const in[])
++{
++	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
++
++	/* Round 1 */
++	ROUND(F, a, b, c, d, in[0] + K1,  3);
++	ROUND(F, d, a, b, c, in[1] + K1,  7);
++	ROUND(F, c, d, a, b, in[2] + K1, 11);
++	ROUND(F, b, c, d, a, in[3] + K1, 19);
++	ROUND(F, a, b, c, d, in[4] + K1,  3);
++	ROUND(F, d, a, b, c, in[5] + K1,  7);
++	ROUND(F, c, d, a, b, in[6] + K1, 11);
++	ROUND(F, b, c, d, a, in[7] + K1, 19);
++
++	/* Round 2 */
++	ROUND(G, a, b, c, d, in[1] + K2,  3);
++	ROUND(G, d, a, b, c, in[3] + K2,  5);
++	ROUND(G, c, d, a, b, in[5] + K2,  9);
++	ROUND(G, b, c, d, a, in[7] + K2, 13);
++	ROUND(G, a, b, c, d, in[0] + K2,  3);
++	ROUND(G, d, a, b, c, in[2] + K2,  5);
++	ROUND(G, c, d, a, b, in[4] + K2,  9);
++	ROUND(G, b, c, d, a, in[6] + K2, 13);
++
++	/* Round 3 */
++	ROUND(H, a, b, c, d, in[3] + K3,  3);
++	ROUND(H, d, a, b, c, in[7] + K3,  9);
++	ROUND(H, c, d, a, b, in[2] + K3, 11);
++	ROUND(H, b, c, d, a, in[6] + K3, 15);
++	ROUND(H, a, b, c, d, in[1] + K3,  3);
++	ROUND(H, d, a, b, c, in[5] + K3,  9);
++	ROUND(H, c, d, a, b, in[0] + K3, 11);
++	ROUND(H, b, c, d, a, in[4] + K3, 15);
++
++	buf[0] += a;
++	buf[1] += b;
++	buf[2] += c;
++	buf[3] += d;
++}
++
++#undef ROUND
++#undef F
++#undef G
++#undef H
++#undef K1
++#undef K2
++#undef K3
++
++/* The old legacy hash */
++static __u32 dx_hack_hash (const char *name, int len)
++{
++	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++	while (len--) {
++		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++		
++		if (hash & 0x80000000) hash -= 0x7fffffff;
++		hash1 = hash0;
++		hash0 = hash;
++	}
++	return (hash0 << 1);
++}
++
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++{
++	__u32	pad, val;
++	int	i;
++
++	pad = (__u32)len | ((__u32)len << 8);
++	pad |= pad << 16;
++
++	val = pad;
++	if (len > num*4)
++		len = num * 4;
++	for (i=0; i < len; i++) {
++		if ((i % 4) == 0)
++			val = pad;
++		val = msg[i] + (val << 8);
++		if ((i % 4) == 3) {
++			*buf++ = val;
++			val = pad;
++			num--;
++		}
++	}
++	if (--num >= 0)
++		*buf++ = val;
++	while (--num >= 0)
++		*buf++ = pad;
++}
++
++/*
++ * Returns the hash of a filename.  If len is 0 and name is NULL, then
++ * this function can be used to test whether or not a hash version is
++ * supported.
++ * 
++ * The seed is an 4 longword (32 bits) "secret" which can be used to
++ * uniquify a hash.  If the seed is all zero's, then some default seed
++ * may be used.
++ * 
++ * A particular hash version specifies whether or not the seed is
++ * represented, and whether or not the returned hash is 32 bits or 64
++ * bits.  32 bit hashes will return 0 for the minor hash.
++ */
++int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
++{
++	__u32	hash;
++	__u32	minor_hash = 0;
++	const char	*p;
++	int		i;
++	__u32 		in[8], buf[4];
++
++	/* Initialize the default seed for the hash checksum functions */
++	buf[0] = 0x67452301;
++	buf[1] = 0xefcdab89;
++	buf[2] = 0x98badcfe;
++	buf[3] = 0x10325476;
++
++	/* Check to see if the seed is all zero's */
++	if (hinfo->seed) {
++		for (i=0; i < 4; i++) {
++			if (hinfo->seed[i])
++				break;
++		}
++		if (i < 4)
++			memcpy(buf, hinfo->seed, sizeof(buf));
++	}
++		
++	switch (hinfo->hash_version) {
++	case DX_HASH_LEGACY:
++		hash = dx_hack_hash(name, len);
++		break;
++	case DX_HASH_HALF_MD4:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 8);
++			halfMD4Transform(buf, in);
++			len -= 32;
++			p += 32;
++		}
++		minor_hash = buf[2];
++		hash = buf[1];
++		break;
++	case DX_HASH_TEA:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 4);
++			TEA_transform(buf, in);
++			len -= 16;
++			p += 16;
++		}
++		hash = buf[0];
++		minor_hash = buf[1];
++		break;
++	default:
++		hinfo->hash = 0;
++		return -1;
++	}
++	hinfo->hash = hash & ~1;
++	hinfo->minor_hash = minor_hash;
++	return 0;
++}
+--- linux-2.4.22-ac1/fs/ext3/Makefile~ext3-htree-2.4.22-rh	2003-09-25 14:39:01.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/Makefile	2003-09-25 14:55:12.000000000 +0400
+@@ -12,7 +12,7 @@ O_TARGET := ext3.o
+ export-objs :=	super.o inode.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o
++		ioctl.o namei.o super.o symlink.o hash.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.22-ac1/fs/ext3/namei.c~ext3-htree-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c	2003-09-25 14:58:37.000000000 +0400
+@@ -16,6 +16,12 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  *  Directory entry file type support and forward compatibility hooks
+  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
++ *  Hash Tree Directory indexing (c)
++ *  	Daniel Phillips, 2001
++ *  Hash Tree Directory indexing porting
++ *  	Christopher Li, 2002
++ *  Hash Tree Directory indexing cleanup
++ * 	Theodore Ts'o, 2002
+  */
+ 
+ #include <linux/fs.h>
+@@ -38,6 +44,642 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+ 
++static struct buffer_head *ext3_append(handle_t *handle,
++					struct inode *inode,
++					u32 *block, int *err)
++{
++	struct buffer_head *bh;
++
++	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
++
++	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++		inode->i_size += inode->i_sb->s_blocksize;
++		EXT3_I(inode)->i_disksize = inode->i_size;
++		ext3_journal_get_write_access(handle,bh);
++	}
++	return bh;
++}
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#ifndef swap
++#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
++#endif
++
++typedef struct { u32 v; } le_u32;
++typedef struct { u16 v; } le_u16;
++
++#ifdef DX_DEBUG
++#define dxtrace(command) command
++#else
++#define dxtrace(command) 
++#endif
++
++struct fake_dirent
++{
++	/*le*/u32 inode;
++	/*le*/u16 rec_len;
++	u8 name_len;
++	u8 file_type;
++};
++
++struct dx_countlimit
++{
++	le_u16 limit;
++	le_u16 count;
++};
++
++struct dx_entry
++{
++	le_u32 hash;
++	le_u32 block;
++};
++
++/*
++ * dx_root_info is laid out so that if it should somehow get overlaid by a
++ * dirent the two low bits of the hash version will be zero.  Therefore, the
++ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
++ */
++
++struct dx_root
++{
++	struct fake_dirent dot;
++	char dot_name[4];
++	struct fake_dirent dotdot;
++	char dotdot_name[4];
++	struct dx_root_info
++	{
++		le_u32 reserved_zero;
++		u8 hash_version;
++		u8 info_length; /* 8 */
++		u8 indirect_levels;
++		u8 unused_flags;
++	}
++	info;
++	struct dx_entry	entries[0];
++};
++
++struct dx_node
++{
++	struct fake_dirent fake;
++	struct dx_entry	entries[0];
++};
++
++
++struct dx_frame
++{
++	struct buffer_head *bh;
++	struct dx_entry *entries;
++	struct dx_entry *at;
++};
++
++struct dx_map_entry
++{
++	u32 hash;
++	u32 offs;
++};
++
++#ifdef CONFIG_EXT3_INDEX
++static inline unsigned dx_get_block (struct dx_entry *entry);
++static void dx_set_block (struct dx_entry *entry, unsigned value);
++static inline unsigned dx_get_hash (struct dx_entry *entry);
++static void dx_set_hash (struct dx_entry *entry, unsigned value);
++static unsigned dx_get_count (struct dx_entry *entries);
++static unsigned dx_get_limit (struct dx_entry *entries);
++static void dx_set_count (struct dx_entry *entries, unsigned value);
++static void dx_set_limit (struct dx_entry *entries, unsigned value);
++static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
++static unsigned dx_node_limit (struct inode *dir);
++static struct dx_frame *dx_probe(struct dentry *dentry,
++				 struct inode *dir,
++				 struct dx_hash_info *hinfo,
++				 struct dx_frame *frame,
++				 int *err);
++static void dx_release (struct dx_frame *frames);
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
++static void dx_sort_map(struct dx_map_entry *map, unsigned count);
++static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
++		struct dx_map_entry *offsets, int count);
++static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
++static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash);
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err);
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode);
++
++/*
++ * Future: use high four bits of block for coalesce-on-delete flags
++ * Mask them off for now.
++ */
++
++static inline unsigned dx_get_block (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->block.v) & 0x00ffffff;
++}
++
++static inline void dx_set_block (struct dx_entry *entry, unsigned value)
++{
++	entry->block.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_hash (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->hash.v);
++}
++
++static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
++{
++	entry->hash.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_count (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
++}
++
++static inline unsigned dx_get_limit (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
++}
++
++static inline void dx_set_count (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
++}
++
++static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
++}
++
++static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
++		EXT3_DIR_REC_LEN(2) - infosize;
++	return 0? 20: entry_space / sizeof(struct dx_entry);
++}
++
++static inline unsigned dx_node_limit (struct inode *dir)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
++	return 0? 22: entry_space / sizeof(struct dx_entry);
++}
++
++/*
++ * Debug
++ */
++#ifdef DX_DEBUG
++struct stats
++{ 
++	unsigned names;
++	unsigned space;
++	unsigned bcount;
++};
++
++static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
++				 int size, int show_names)
++{
++	unsigned names = 0, space = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	printk("names: ");
++	while ((char *) de < base + size)
++	{
++		if (de->inode)
++		{
++			if (show_names)
++			{
++				int len = de->name_len;
++				char *name = de->name;
++				while (len--) printk("%c", *name++);
++				ext3fs_dirhash(de->name, de->name_len, &h);
++				printk(":%x.%u ", h.hash,
++				       ((char *) de - base));
++			}
++			space += EXT3_DIR_REC_LEN(de->name_len);
++	 		names++;
++		}
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	printk("(%i)\n", names);
++	return (struct stats) { names, space, 1 };
++}
++
++struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
++			     struct dx_entry *entries, int levels)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
++	unsigned bcount = 0;
++	struct buffer_head *bh;
++	int err;
++	printk("%i indexed blocks...\n", count);
++	for (i = 0; i < count; i++, entries++)
++	{
++		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
++		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
++		struct stats stats;
++		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
++		if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
++		stats = levels?
++		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
++		   dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
++		names += stats.names;
++		space += stats.space;
++		bcount += stats.bcount;
++		brelse (bh);
++	}
++	if (bcount)
++		printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
++			names, space/bcount,(space/bcount)*100/blocksize);
++	return (struct stats) { names, space, bcount};
++}
++#endif /* DX_DEBUG */
++
++/*
++ * Probe for a directory leaf block to search.
++ *
++ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
++ * error in the directory index, and the caller should fall back to
++ * searching the directory normally.  The callers of dx_probe **MUST**
++ * check for this error code, and make sure it never gets reflected
++ * back to userspace.
++ */
++static struct dx_frame *
++dx_probe(struct dentry *dentry, struct inode *dir,
++	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
++{
++	unsigned count, indirect;
++	struct dx_entry *at, *entries, *p, *q, *m;
++	struct dx_root *root;
++	struct buffer_head *bh;
++	struct dx_frame *frame = frame_in;
++	u32 hash;
++
++	frame->bh = NULL;
++	if (dentry)
++		dir = dentry->d_parent->d_inode;
++	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
++		goto fail;
++	root = (struct dx_root *) bh->b_data;
++	if (root->info.hash_version != DX_HASH_TEA &&
++	    root->info.hash_version != DX_HASH_HALF_MD4 &&
++	    root->info.hash_version != DX_HASH_LEGACY) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unrecognised inode hash code %d",
++			     root->info.hash_version);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++	hinfo->hash_version = root->info.hash_version;
++	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	if (dentry)
++		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	hash = hinfo->hash;
++
++	if (root->info.unused_flags & 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash flags: %#06x",
++			     root->info.unused_flags);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	if ((indirect = root->info.indirect_levels) > 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash depth: %#06x",
++			     root->info.indirect_levels);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	while (1)
++	{
++		count = dx_get_count(entries);
++		assert (count && count <= dx_get_limit(entries));
++		p = entries + 1;
++		q = entries + count - 1;
++		while (p <= q)
++		{
++			m = p + (q - p)/2;
++			dxtrace(printk("."));
++			if (dx_get_hash(m) > hash)
++				q = m - 1;
++			else
++				p = m + 1;
++		}
++
++		if (0) // linear search cross check
++		{
++			unsigned n = count - 1;
++			at = entries;
++			while (n--)
++			{
++				dxtrace(printk(","));
++				if (dx_get_hash(++at) > hash)
++				{
++					at--;
++					break;
++				}
++			}
++			assert (at == p - 1);
++		}
++
++		at = p - 1;
++		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		frame->bh = bh;
++		frame->entries = entries;
++		frame->at = at;
++		if (!indirect--) return frame;
++		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++			goto fail2;
++		at = entries = ((struct dx_node *) bh->b_data)->entries;
++		assert (dx_get_limit(entries) == dx_node_limit (dir));
++		frame++;
++	}
++fail2:
++	while (frame >= frame_in) {
++		brelse(frame->bh);
++		frame--;
++	}
++fail:
++	return NULL;
++}
++
++static void dx_release (struct dx_frame *frames)
++{
++	if (frames[0].bh == NULL)
++		return;
++
++	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++		brelse(frames[1].bh);
++	brelse(frames[0].bh);
++}
++
++/*
++ * This function increments the frame pointer to search the next leaf
++ * block, and reads in the necessary intervening nodes if the search
++ * should be necessary.  Whether or not the search is necessary is
++ * controlled by the hash parameter.  If the hash value is even, then
++ * the search is only continued if the next block starts with that
++ * hash value.  This is used if we are searching for a specific file.
++ *
++ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
++ *
++ * This function returns 1 if the caller should continue to search,
++ * or 0 if it should not.  If there is an error reading one of the
++ * index blocks, it will return -1.
++ *
++ * If start_hash is non-null, it will be filled in with the starting
++ * hash of the next page.
++ */
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash)
++{
++	struct dx_frame *p;
++	struct buffer_head *bh;
++	int num_frames = 0;
++	__u32 bhash;
++
++	*err = ENOENT;
++	p = frame;
++	/*
++	 * Find the next leaf page by incrementing the frame pointer.
++	 * If we run out of entries in the interior node, loop around and
++	 * increment pointer in the parent node.  When we break out of
++	 * this loop, num_frames indicates the number of interior
++	 * nodes need to be read.
++	 */
++	while (1) {
++		if (++(p->at) < p->entries + dx_get_count(p->entries))
++			break;
++		if (p == frames)
++			return 0;
++		num_frames++;
++		p--;
++	}
++
++	/*
++	 * If the hash is 1, then continue only if the next page has a
++	 * continuation hash of any value.  This is used for readdir
++	 * handling.  Otherwise, check to see if the hash matches the
++	 * desired contiuation hash.  If it doesn't, return since
++	 * there's no point to read in the successive index pages.
++	 */
++	bhash = dx_get_hash(p->at);
++	if (start_hash)
++		*start_hash = bhash;
++	if ((hash & 1) == 0) {
++		if ((bhash & ~1) != hash)
++			return 0;
++	}
++	/*
++	 * If the hash is HASH_NB_ALWAYS, we always go to the next
++	 * block so no check is necessary
++	 */
++	while (num_frames--) {
++		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
++				      0, err)))
++			return -1; /* Failure */
++		p++;
++		brelse (p->bh);
++		p->bh = bh;
++		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++	}
++	return 1;
++}
++
++
++/*
++ * p is at least 6 bytes before the end of page
++ */
++static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
++{
++	return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
++}
++
++/*
++ * This function fills a red-black tree with information from a
++ * directory.  We start scanning the directory in hash order, starting
++ * at start_hash and start_minor_hash.
++ *
++ * This function returns the number of entries inserted into the tree,
++ * or a negative error code.
++ */
++int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++			 __u32 start_minor_hash, __u32 *next_hash)
++{
++	struct dx_hash_info hinfo;
++	struct buffer_head *bh;
++	struct ext3_dir_entry_2 *de, *top;
++	static struct dx_frame frames[2], *frame;
++	struct inode *dir;
++	int block, err;
++	int count = 0;
++	int ret;
++	__u32 hashval;
++	
++	dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
++		       start_minor_hash));
++	dir = dir_file->f_dentry->d_inode;
++	hinfo.hash = start_hash;
++	hinfo.minor_hash = 0;
++	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++
++	/* Add '.' and '..' from the htree header */
++	if (!start_hash && !start_minor_hash) {
++		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		de = ext3_next_entry(de);
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		count += 2;
++	}
++
++	while (1) {
++		block = dx_get_block(frame->at);
++		dxtrace(printk("Reading block %d\n", block));
++		if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
++			goto errout;
++	
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de)) {
++			ext3fs_dirhash(de->name, de->name_len, &hinfo);
++			if ((hinfo.hash < start_hash) ||
++			    ((hinfo.hash == start_hash) &&
++			     (hinfo.minor_hash < start_minor_hash)))
++				continue;
++			if ((err = ext3_htree_store_dirent(dir_file,
++				   hinfo.hash, hinfo.minor_hash, de)) != 0)
++				goto errout;
++			count++;
++		}
++		brelse (bh);
++		hashval = ~1;
++		ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
++					    frame, frames, &err, &hashval);
++		if (next_hash)
++			*next_hash = hashval;
++		if (ret == -1)
++			goto errout;
++		/*
++		 * Stop if:  (a) there are no more entries, or
++		 * (b) we have inserted at least one entry and the
++		 * next hash value is not a continuation
++		 */
++		if ((ret == 0) ||
++		    (count && ((hashval & 1) == 0)))
++			break;
++	}
++	dx_release(frames);
++	dxtrace(printk("Fill tree: returned %d entries\n", count));
++	return count;
++errout:
++	dx_release(frames);
++	return (err);
++}
++
++
++/*
++ * Directory block splitting, compacting
++ */
++
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
++{
++	int count = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	while ((char *) de < base + size)
++	{
++		if (de->name_len && de->inode) {
++			ext3fs_dirhash(de->name, de->name_len, &h);
++			map_tail--;
++			map_tail->hash = h.hash;
++			map_tail->offs = (u32) ((char *) de - base);
++			count++;
++		}
++		/* XXX: do we need to check rec_len == 0 case? -Chris */
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	return count;
++}
++
++static void dx_sort_map (struct dx_map_entry *map, unsigned count)
++{
++	struct dx_map_entry *p, *q, *top = map + count - 1;
++	int more;
++	/* Combsort until bubble sort doesn't suck */
++	while (count > 2)
++	{
++		count = count*10/13;
++		if (count - 9 < 2) /* 9, 10 -> 11 */
++			count = 11;
++		for (p = top, q = p - count; q >= map; p--, q--)
++			if (p->hash < q->hash)
++				swap(*p, *q);
++	}
++	/* Garden variety bubble sort */
++	do {
++		more = 0;
++		q = top;
++		while (q-- > map)
++		{
++			if (q[1].hash >= q[0].hash)
++				continue;
++			swap(*(q+1), *q);
++			more = 1;
++		}
++	} while(more);
++}
++
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++{
++	struct dx_entry *entries = frame->entries;
++	struct dx_entry *old = frame->at, *new = old + 1;
++	int count = dx_get_count(entries);
++
++	assert(count < dx_get_limit(entries));
++	assert(old < entries + count);
++	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++	dx_set_hash(new, hash);
++	dx_set_block(new, block);
++	dx_set_count(entries, count + 1);
++}
++#endif
++
++
++static void ext3_update_dx_flag(struct inode *inode)
++{
++	if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
++				     EXT3_FEATURE_COMPAT_DIR_INDEX))
++		EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
++}
++
+ /*
+  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+  *
+@@ -94,6 +736,7 @@ static int inline search_dirblock(struct
+ 	return 0;
+ }
+ 
++
+ /*
+  *	ext3_find_entry()
+  *
+@@ -105,6 +748,8 @@ static int inline search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
++
++	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+ 					struct ext3_dir_entry_2 ** res_dir)
+ {
+@@ -119,12 +764,32 @@ static struct buffer_head * ext3_find_en
+ 	int num = 0;
+ 	int nblocks, i, err;
+ 	struct inode *dir = dentry->d_parent->d_inode;
++	int namelen;
++	const u8 *name;
++	unsigned blocksize;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+-
++	blocksize = sb->s_blocksize;
++	namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++	if (namelen > EXT3_NAME_LEN)
++		return NULL;
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		/*
++		 * On success, or if the error was file not found,
++		 * return.  Otherwise, fall back to doing a search the
++		 * old fashioned way.
++		 */
++		if (bh || (err != ERR_BAD_DX_DIR))
++			return bh;
++		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++	}
++#endif
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+-	start = dir->u.ext3_i.i_dir_start_lookup;
++	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+ 		start = 0;
+ 	block = start;
+@@ -166,7 +831,7 @@ restart:
+ 		i = search_dirblock(bh, dir, dentry,
+ 			    block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
+ 		if (i == 1) {
+-			dir->u.ext3_i.i_dir_start_lookup = block;
++			EXT3_I(dir)->i_dir_start_lookup = block;
+ 			ret = bh;
+ 			goto cleanup_and_exit;
+ 		} else {
+@@ -197,6 +862,66 @@ cleanup_and_exit:
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err)
++{
++	struct super_block * sb;
++	struct dx_hash_info	hinfo;
++	u32 hash;
++	struct dx_frame frames[2], *frame;
++	struct ext3_dir_entry_2 *de, *top;
++	struct buffer_head *bh;
++	unsigned long block;
++	int retval;
++	int namelen = dentry->d_name.len;
++	const u8 *name = dentry->d_name.name;
++	struct inode *dir = dentry->d_parent->d_inode;
++	
++	sb = dir->i_sb;
++	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++		return NULL;
++	hash = hinfo.hash;
++	do {
++		block = dx_get_block(frame->at);
++		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
++			goto errout;
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de))
++		if (ext3_match (namelen, name, de)) {
++			if (!ext3_check_dir_entry("ext3_find_entry",
++						  dir, de, bh,
++				  (block<<EXT3_BLOCK_SIZE_BITS(sb))
++					  +((char *)de - bh->b_data))) {
++				brelse (bh);
++				goto errout;
++			}
++			*res_dir = de;
++			dx_release (frames);
++			return bh;
++		}
++		brelse (bh);
++		/* Check to see if we should continue to search */
++		retval = ext3_htree_next_block(dir, hash, frame,
++					       frames, err, 0);
++		if (retval == -1) {
++			ext3_warning(sb, __FUNCTION__,
++			     "error reading index page in directory #%lu",
++			     dir->i_ino);
++			goto errout;
++		}
++	} while (retval == 1);
++	
++	*err = -ENOENT;
++errout:
++	dxtrace(printk("%s not found\n", name));
++	dx_release (frames);
++	return NULL;
++}
++#endif
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+@@ -213,8 +938,9 @@ static struct dentry *ext3_lookup(struct
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+-		if (!inode)
++		if (!inode) {
+ 			return ERR_PTR(-EACCES);
++		}
+ 	}
+ 	d_add(dentry, inode);
+ 	return NULL;
+@@ -238,6 +964,301 @@ static inline void ext3_set_de_type(stru
+ 		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct ext3_dir_entry_2 *
++dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
++{
++	unsigned rec_len = 0;
++
++	while (count--) {
++		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		rec_len = EXT3_DIR_REC_LEN(de->name_len);
++		memcpy (to, de, rec_len);
++		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
++		de->inode = 0;
++		map++;
++		to += rec_len;
++	}
++	return (struct ext3_dir_entry_2 *) (to - rec_len);
++}
++
++static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
++{
++	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	unsigned rec_len = 0;
++
++	prev = to = de;
++	while ((char*)de < base + size) {
++		next = (struct ext3_dir_entry_2 *) ((char *) de +
++						    le16_to_cpu(de->rec_len));
++		if (de->inode && de->name_len) {
++			rec_len = EXT3_DIR_REC_LEN(de->name_len);
++			if (de > to)
++				memmove(to, de, rec_len);
++			to->rec_len = rec_len;
++			prev = to;
++			to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
++		}
++		de = next;
++	}
++	return prev;
++}
++
++static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
++			struct buffer_head **bh,struct dx_frame *frame,
++			struct dx_hash_info *hinfo, int *error)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count, continued;
++	struct buffer_head *bh2;
++	u32 newblock;
++	u32 hash2;
++	struct dx_map_entry *map;
++	char *data1 = (*bh)->b_data, *data2;
++	unsigned split;
++	struct ext3_dir_entry_2 *de = NULL, *de2;
++	int	err;
++
++	bh2 = ext3_append (handle, dir, &newblock, error);
++	if (!(bh2)) {
++		brelse(*bh);
++		*bh = NULL;
++		goto errout;
++	}
++
++	BUFFER_TRACE(*bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, *bh);
++	if (err) {
++	journal_error:
++		brelse(*bh);
++		brelse(bh2);
++		*bh = NULL;
++		ext3_std_error(dir->i_sb, err);
++		goto errout;
++	}
++	BUFFER_TRACE(frame->bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, frame->bh);
++	if (err)
++		goto journal_error;
++
++	data2 = bh2->b_data;
++
++	/* create map in the end of data2 block */
++	map = (struct dx_map_entry *) (data2 + blocksize);
++	count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
++			     blocksize, hinfo, map);
++	map -= count;
++	split = count/2; // need to adjust to actual middle
++	dx_sort_map (map, count);
++	hash2 = map[split].hash;
++	continued = hash2 == map[split - 1].hash;
++	dxtrace(printk("Split block %i at %x, %i/%i\n",
++		dx_get_block(frame->at), hash2, split, count-split));
++
++	/* Fancy dance to stay within two buffers */
++	de2 = dx_move_dirents(data1, data2, map + split, count - split);
++	de = dx_pack_dirents(data1,blocksize);
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++
++	/* Which block gets the new entry? */
++	if (hinfo->hash >= hash2)
++	{
++		swap(*bh, bh2);
++		de = de2;
++	}
++	dx_insert_block (frame, hash2 + continued, newblock);
++	err = ext3_journal_dirty_metadata (handle, bh2);
++	if (err)
++		goto journal_error;
++	err = ext3_journal_dirty_metadata (handle, frame->bh);
++	if (err)
++		goto journal_error;
++	brelse (bh2);
++	dxtrace(dx_show_index ("frame", frame->entries));
++errout:
++	return de;
++}
++#endif
++
++
++/*
++ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
++ * it points to a directory entry which is guaranteed to be large
++ * enough for new directory entry.  If de is NULL, then
++ * add_dirent_to_buf will attempt search the directory block for
++ * space.  It will return -ENOSPC if no space is available, and -EIO
++ * and -EEXIST if directory entry already exists.
++ * 
++ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
++ * all other cases bh is released.
++ */
++static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode, struct ext3_dir_entry_2 *de,
++			     struct buffer_head * bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	unsigned long	offset = 0;
++	unsigned short	reclen;
++	int		nlen, rlen, err;
++	char		*top;
++	
++	reclen = EXT3_DIR_REC_LEN(namelen);
++	if (!de) {
++		de = (struct ext3_dir_entry_2 *)bh->b_data;
++		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
++		while ((char *) de <= top) {
++			if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
++						  bh, offset)) {
++				brelse (bh);
++				return -EIO;
++			}
++			if (ext3_match (namelen, name, de)) {
++				brelse (bh);
++				return -EEXIST;
++			}
++			nlen = EXT3_DIR_REC_LEN(de->name_len);
++			rlen = le16_to_cpu(de->rec_len);
++			if ((de->inode? rlen - nlen: rlen) >= reclen)
++				break;
++			de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
++			offset += rlen;
++		}
++		if ((char *) de > top)
++			return -ENOSPC;
++	}
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err) {
++		ext3_std_error(dir->i_sb, err);
++		brelse(bh);
++		return err;
++	}
++	
++	/* By now the buffer is marked for journaling */
++	nlen = EXT3_DIR_REC_LEN(de->name_len);
++	rlen = le16_to_cpu(de->rec_len);
++	if (de->inode) {
++		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		de1->rec_len = cpu_to_le16(rlen - nlen);
++		de->rec_len = cpu_to_le16(nlen);
++		de = de1;
++	}
++	de->file_type = EXT3_FT_UNKNOWN;
++	if (inode) {
++		de->inode = cpu_to_le32(inode->i_ino);
++		ext3_set_de_type(dir->i_sb, de, inode->i_mode);
++	} else
++		de->inode = 0;
++	de->name_len = namelen;
++	memcpy (de->name, name, namelen);
++	/*
++	 * XXX shouldn't update any times until successful
++	 * completion of syscall, but too many callers depend
++	 * on this.
++	 *
++	 * XXX similarly, too many callers depend on
++	 * ext3_new_inode() setting the times, but error
++	 * recovery deletes the inode, so the worst that can
++	 * happen is that the times are slightly out of date
++	 * and/or different from the directory change time.
++	 */
++	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
++	ext3_update_dx_flag(dir);
++	dir->i_version = ++event;
++	ext3_mark_inode_dirty(handle, dir);
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		ext3_std_error(dir->i_sb, err);
++	brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * This converts a one block unindexed directory to a 3 block indexed
++ * directory, and adds the dentry to the indexed directory.
++ */
++static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
++			    struct inode *inode, struct buffer_head *bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	struct buffer_head *bh2;
++	struct dx_root	*root;
++	struct dx_frame	frames[2], *frame;
++	struct dx_entry *entries;
++	struct ext3_dir_entry_2	*de, *de2;
++	char		*data1, *top;
++	unsigned	len;
++	int		retval;
++	unsigned	blocksize;
++	struct dx_hash_info hinfo;
++	u32		block;
++		
++	blocksize =  dir->i_sb->s_blocksize;
++	dxtrace(printk("Creating index\n"));
++	retval = ext3_journal_get_write_access(handle, bh);
++	if (retval) {
++		ext3_std_error(dir->i_sb, retval);
++		brelse(bh);
++		return retval;
++	}
++	root = (struct dx_root *) bh->b_data;
++		
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	bh2 = ext3_append (handle, dir, &block, &retval);
++	if (!(bh2)) {
++		brelse(bh);
++		return retval;
++	}
++	data1 = bh2->b_data;
++
++	/* The 0th block becomes the root, move the dirents out */
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
++	len = ((char *) root) + blocksize - (char *) de;
++	memcpy (data1, de, len);
++	de = (struct ext3_dir_entry_2 *) data1;
++	top = data1 + len;
++	while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
++		de = de2;
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	/* Initialize the root; the dot dirents already exist */
++	de = (struct ext3_dir_entry_2 *) (&root->dotdot);
++	de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++	memset (&root->info, 0, sizeof(root->info));
++	root->info.info_length = sizeof(root->info);
++	root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
++	entries = root->entries;
++	dx_set_block (entries, 1);
++	dx_set_count (entries, 1);
++	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
++
++	/* Initialize as for dx_probe */
++	hinfo.hash_version = root->info.hash_version;
++	hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	ext3fs_dirhash(name, namelen, &hinfo);
++	frame = frames;
++	frame->entries = entries;
++	frame->at = entries;
++	frame->bh = bh;
++	bh = bh2;
++	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	dx_release (frames);
++	if (!(de))
++		return retval;
++
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
++#endif
++
+ /*
+  *	ext3_add_entry()
+  *
+@@ -248,127 +1269,198 @@ static inline void ext3_set_de_type(stru
+  * may not sleep between calling this and putting something into
+  * the entry, as someone else might have used it while you slept.
+  */
+-
+-/*
+- * AKPM: the journalling code here looks wrong on the error paths
+- */
+ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+ 	struct inode *inode)
+ {
+ 	struct inode *dir = dentry->d_parent->d_inode;
+-	const char *name = dentry->d_name.name;
+-	int namelen = dentry->d_name.len;
+ 	unsigned long offset;
+-	unsigned short rec_len;
+ 	struct buffer_head * bh;
+-	struct ext3_dir_entry_2 * de, * de1;
++	struct ext3_dir_entry_2 *de;
+ 	struct super_block * sb;
+ 	int	retval;
++#ifdef CONFIG_EXT3_INDEX
++	int	dx_fallback=0;
++#endif
++	unsigned blocksize;
++	unsigned nlen, rlen;
++	u32 block, blocks;
+ 
+ 	sb = dir->i_sb;
+-
+-	if (!namelen)
++	blocksize = sb->s_blocksize;
++	if (!dentry->d_name.len)
+ 		return -EINVAL;
+-	bh = ext3_bread (handle, dir, 0, 0, &retval);
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		retval = ext3_dx_add_entry(handle, dentry, inode);
++		if (!retval || (retval != ERR_BAD_DX_DIR))
++			return retval;
++		EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
++		dx_fallback++;
++		ext3_mark_inode_dirty(handle, dir);
++	}
++#endif
++	blocks = dir->i_size >> sb->s_blocksize_bits;
++	for (block = 0, offset = 0; block < blocks; block++) {
++		bh = ext3_bread(handle, dir, block, 0, &retval);
++		if(!bh)
++			return retval;
++		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++		if (retval != -ENOSPC)
++			return retval;
++
++#ifdef CONFIG_EXT3_INDEX
++		if (blocks == 1 && !dx_fallback &&
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
++			return make_indexed_dir(handle, dentry, inode, bh);
++#endif
++		brelse(bh);
++	}
++	bh = ext3_append(handle, dir, &block, &retval);
+ 	if (!bh)
+ 		return retval;
+-	rec_len = EXT3_DIR_REC_LEN(namelen);
+-	offset = 0;
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+-	while (1) {
+-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+-			brelse (bh);
+-			bh = NULL;
+-			bh = ext3_bread (handle, dir,
+-				offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
+-			if (!bh)
+-				return retval;
+-			if (dir->i_size <= offset) {
+-				if (dir->i_size == 0) {
+-					brelse(bh);
+-					return -ENOENT;
+-				}
++	de->inode = 0;
++	de->rec_len = cpu_to_le16(rlen = blocksize);
++	nlen = 0;
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
+ 
+-				ext3_debug ("creating next block\n");
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * Returns 0 for success, or a negative error value
++ */
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode)
++{
++	struct dx_frame frames[2], *frame;
++	struct dx_entry *entries, *at;
++	struct dx_hash_info hinfo;
++	struct buffer_head * bh;
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block * sb = dir->i_sb;
++	struct ext3_dir_entry_2 *de;
++	int err;
+ 
+-				BUFFER_TRACE(bh, "get_write_access");
+-				ext3_journal_get_write_access(handle, bh);
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-				de->inode = 0;
+-				de->rec_len = le16_to_cpu(sb->s_blocksize);
+-				dir->u.ext3_i.i_disksize =
+-					dir->i_size = offset + sb->s_blocksize;
+-				dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-				ext3_mark_inode_dirty(handle, dir);
+-			} else {
++	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++	entries = frame->entries;
++	at = frame->at;
+ 
+-				ext3_debug ("skipping to next block\n");
++	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++		goto cleanup;
+ 
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-			}
+-		}
+-		if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
+-					   offset)) {
+-			brelse (bh);
+-			return -ENOENT;
+-		}
+-		if (ext3_match (namelen, name, de)) {
+-				brelse (bh);
+-				return -EEXIST;
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err)
++		goto journal_error;
++
++	err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++	if (err != -ENOSPC) {
++		bh = 0;
++		goto cleanup;
++	}
++
++	/* Block full, should compress but for now just split */
++	dxtrace(printk("using %u of %u node entries\n",
++		       dx_get_count(entries), dx_get_limit(entries)));
++	/* Need to split index? */
++	if (dx_get_count(entries) == dx_get_limit(entries)) {
++		u32 newblock;
++		unsigned icount = dx_get_count(entries);
++		int levels = frame - frames;
++		struct dx_entry *entries2;
++		struct dx_node *node2;
++		struct buffer_head *bh2;
++
++		if (levels && (dx_get_count(frames->entries) ==
++			       dx_get_limit(frames->entries))) {
++			ext3_warning(sb, __FUNCTION__,
++				     "Directory index full!\n");
++			err = -ENOSPC;
++			goto cleanup;
+ 		}
+-		if ((le32_to_cpu(de->inode) == 0 &&
+-				le16_to_cpu(de->rec_len) >= rec_len) ||
+-		    (le16_to_cpu(de->rec_len) >=
+-				EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
+-			BUFFER_TRACE(bh, "get_write_access");
+-			ext3_journal_get_write_access(handle, bh);
+-			/* By now the buffer is marked for journaling */
+-			offset += le16_to_cpu(de->rec_len);
+-			if (le32_to_cpu(de->inode)) {
+-				de1 = (struct ext3_dir_entry_2 *) ((char *) de +
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de1->rec_len =
+-					cpu_to_le16(le16_to_cpu(de->rec_len) -
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de->rec_len = cpu_to_le16(
+-						EXT3_DIR_REC_LEN(de->name_len));
+-				de = de1;
++		bh2 = ext3_append (handle, dir, &newblock, &err);
++		if (!(bh2))
++			goto cleanup;
++		node2 = (struct dx_node *)(bh2->b_data);
++		entries2 = node2->entries;
++		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
++		node2->fake.inode = 0;
++		BUFFER_TRACE(frame->bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, frame->bh);
++		if (err)
++			goto journal_error;
++		if (levels) {
++			unsigned icount1 = icount/2, icount2 = icount - icount1;
++			unsigned hash2 = dx_get_hash(entries + icount1);
++			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
++				
++			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++			err = ext3_journal_get_write_access(handle,
++							     frames[0].bh);
++			if (err)
++				goto journal_error;
++				
++			memcpy ((char *) entries2, (char *) (entries + icount1),
++				icount2 * sizeof(struct dx_entry));
++			dx_set_count (entries, icount1);
++			dx_set_count (entries2, icount2);
++			dx_set_limit (entries2, dx_node_limit(dir));
++
++			/* Which index block gets the new entry? */
++			if (at - entries >= icount1) {
++				frame->at = at = at - entries - icount1 + entries2;
++				frame->entries = entries = entries2;
++				swap(frame->bh, bh2);
+ 			}
+-			de->file_type = EXT3_FT_UNKNOWN;
+-			if (inode) {
+-				de->inode = cpu_to_le32(inode->i_ino);
+-				ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-			} else
+-				de->inode = 0;
+-			de->name_len = namelen;
+-			memcpy (de->name, name, namelen);
+-			/*
+-			 * XXX shouldn't update any times until successful
+-			 * completion of syscall, but too many callers depend
+-			 * on this.
+-			 *
+-			 * XXX similarly, too many callers depend on
+-			 * ext3_new_inode() setting the times, but error
+-			 * recovery deletes the inode, so the worst that can
+-			 * happen is that the times are slightly out of date
+-			 * and/or different from the directory change time.
+-			 */
+-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+-			dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-			dir->i_version = ++event;
+-			ext3_mark_inode_dirty(handle, dir);
+-			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-			ext3_journal_dirty_metadata(handle, bh);
+-			brelse(bh);
+-			return 0;
++			dx_insert_block (frames + 0, hash2, newblock);
++			dxtrace(dx_show_index ("node", frames[1].entries));
++			dxtrace(dx_show_index ("node",
++			       ((struct dx_node *) bh2->b_data)->entries));
++			err = ext3_journal_dirty_metadata(handle, bh2);
++			if (err)
++				goto journal_error;
++			brelse (bh2);
++		} else {
++			dxtrace(printk("Creating second level index...\n"));
++			memcpy((char *) entries2, (char *) entries,
++			       icount * sizeof(struct dx_entry));
++			dx_set_limit(entries2, dx_node_limit(dir));
++
++			/* Set up root */
++			dx_set_count(entries, 1);
++			dx_set_block(entries + 0, newblock);
++			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++
++			/* Add new access path frame */
++			frame = frames + 1;
++			frame->at = at = at - entries + entries2;
++			frame->entries = entries = entries2;
++			frame->bh = bh2;
++			err = ext3_journal_get_write_access(handle,
++							     frame->bh);
++			if (err)
++				goto journal_error;
+ 		}
+-		offset += le16_to_cpu(de->rec_len);
+-		de = (struct ext3_dir_entry_2 *)
+-			((char *) de + le16_to_cpu(de->rec_len));
++		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	brelse (bh);
+-	return -ENOSPC;
++	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	if (!de)
++		goto cleanup;
++	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	bh = 0;
++	goto cleanup;
++	
++journal_error:
++	ext3_std_error(dir->i_sb, err);
++cleanup:
++	if (bh)
++		brelse(bh);
++	dx_release(frames);
++	return err;
+ }
++#endif
+ 
+ /*
+  * ext3_delete_entry deletes a directory entry by merging it with the
+@@ -455,9 +1547,11 @@ static int ext3_create (struct inode * d
+ 	struct inode * inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -481,9 +1575,11 @@ static int ext3_mknod (struct inode * di
+ 	struct inode *inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -509,9 +1605,11 @@ static int ext3_mkdir(struct inode * dir
+ 	if (dir->i_nlink >= EXT3_LINK_MAX)
+ 		return -EMLINK;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -523,7 +1621,7 @@ static int ext3_mkdir(struct inode * dir
+ 
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+-	inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
++	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+ 	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+@@ -556,21 +1654,19 @@ static int ext3_mkdir(struct inode * dir
+ 		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+-	if (err)
+-		goto out_no_entry;
++	if (err) {
++		inode->i_nlink = 0;
++		ext3_mark_inode_dirty(handle, inode);
++		iput (inode);
++		goto out_stop;
++	}
+ 	dir->i_nlink++;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	d_instantiate(dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	inode->i_nlink = 0;
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ /*
+@@ -657,7 +1753,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	int err = 0, rc;
+ 	
+ 	lock_super(sb);
+-	if (!list_empty(&inode->u.ext3_i.i_orphan))
++	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+ 	/* Orphan handling is only valid for files with data blocks
+@@ -698,7 +1794,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	 * This is safe: on error we're going to ignore the orphan list
+ 	 * anyway on the next recovery. */
+ 	if (!err)
+-		list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
++		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
+ 
+ 	jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+@@ -716,25 +1812,26 @@ out_unlock:
+ int ext3_orphan_del(handle_t *handle, struct inode *inode)
+ {
+ 	struct list_head *prev;
++ 	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct ext3_sb_info *sbi;
+ 	unsigned long ino_next;
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 
+ 	lock_super(inode->i_sb);
+-	if (list_empty(&inode->u.ext3_i.i_orphan)) {
++ 	if (list_empty(&ei->i_orphan)) {
+ 		unlock_super(inode->i_sb);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+-	prev = inode->u.ext3_i.i_orphan.prev;
++ 	prev = ei->i_orphan.prev;
+ 	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+ 
+-	list_del(&inode->u.ext3_i.i_orphan);
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++ 	list_del(&ei->i_orphan);
++ 	INIT_LIST_HEAD(&ei->i_orphan);
+ 
+ 	/* If we're on an error path, we may not have a valid
+ 	 * transaction handle with which to update the orphan list on
+@@ -795,8 +1892,9 @@ static int ext3_rmdir (struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	retval = -ENOENT;
+ 	bh = ext3_find_entry (dentry, &de);
+@@ -834,7 +1932,7 @@ static int ext3_rmdir (struct inode * di
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+ end_rmdir:
+@@ -852,8 +1950,9 @@ static int ext3_unlink(struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -880,7 +1979,7 @@ static int ext3_unlink(struct inode * di
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	inode->i_nlink--;
+ 	if (!inode->i_nlink)
+@@ -906,9 +2005,11 @@ static int ext3_symlink (struct inode * 
+ 	if (l > dir->i_sb->s_blocksize)
+ 		return -ENAMETOOLONG;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -918,7 +2019,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+ 
+-	if (l > sizeof (inode->u.ext3_i.i_data)) {
++	if (l > sizeof (EXT3_I(inode)->i_data)) {
+ 		inode->i_op = &page_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+@@ -927,24 +2028,22 @@ static int ext3_symlink (struct inode * 
+ 		 * i_size in generic_commit_write().
+ 		 */
+ 		err = block_symlink(inode, symname, l);
+-		if (err)
+-			goto out_no_entry;
++ 		if (err) {
++ 			ext3_dec_count(handle, inode);
++ 			ext3_mark_inode_dirty(handle, inode);
++ 			iput (inode);
++ 			goto out_stop;
++ 		}
+ 	} else {
+ 		inode->i_op = &ext3_fast_symlink_inode_operations;
+-		memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
++ 		memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
+ 		inode->i_size = l-1;
+ 	}
+-	inode->u.ext3_i.i_disksize = inode->i_size;
++ 	EXT3_I(inode)->i_disksize = inode->i_size;
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	ext3_dec_count(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ static int ext3_link (struct dentry * old_dentry,
+@@ -957,12 +2056,15 @@ static int ext3_link (struct dentry * ol
+ 	if (S_ISDIR(inode->i_mode))
+ 		return -EPERM;
+ 
+-	if (inode->i_nlink >= EXT3_LINK_MAX)
++	if (inode->i_nlink >= EXT3_LINK_MAX) {
+ 		return -EMLINK;
++	}
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -995,9 +2097,11 @@ static int ext3_rename (struct inode * o
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+@@ -1070,14 +2174,33 @@ static int ext3_rename (struct inode * o
+ 	/*
+ 	 * ok, that's it
+ 	 */
+-	ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	retval = ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	if (retval == -ENOENT) {
++		/*
++		 * old_de could have moved out from under us.
++		 */
++		struct buffer_head *old_bh2;
++		struct ext3_dir_entry_2 *old_de2;
++		
++		old_bh2 = ext3_find_entry(old_dentry, &old_de2);
++		if (old_bh2) {
++			retval = ext3_delete_entry(handle, old_dir,
++						   old_de2, old_bh2);
++			brelse(old_bh2);
++		}
++	}
++	if (retval) {
++		ext3_warning(old_dir->i_sb, "ext3_rename",
++				"Deleting old file (%lu), %d, error=%d",
++				old_dir->i_ino, old_dir->i_nlink, retval);
++	}
+ 
+ 	if (new_inode) {
+ 		new_inode->i_nlink--;
+ 		new_inode->i_ctime = CURRENT_TIME;
+ 	}
+ 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+-	old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(old_dir);
+ 	if (dir_bh) {
+ 		BUFFER_TRACE(dir_bh, "get_write_access");
+ 		ext3_journal_get_write_access(handle, dir_bh);
+@@ -1089,7 +2212,7 @@ static int ext3_rename (struct inode * o
+ 			new_inode->i_nlink--;
+ 		} else {
+ 			new_dir->i_nlink++;
+-			new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++			ext3_update_dx_flag(new_dir);
+ 			ext3_mark_inode_dirty(handle, new_dir);
+ 		}
+ 	}
+--- linux-2.4.22-ac1/fs/ext3/super.c~ext3-htree-2.4.22-rh	2003-09-25 14:39:01.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/super.c	2003-09-25 14:55:12.000000000 +0400
+@@ -714,6 +714,7 @@ static int ext3_setup_super(struct super
+ 	es->s_mtime = cpu_to_le32(CURRENT_TIME);
+ 	ext3_update_dynamic_rev(sb);
+ 	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
++
+ 	ext3_commit_super (sb, es, 1);
+ 	if (test_opt (sb, DEBUG))
+ 		printk (KERN_INFO
+@@ -724,6 +725,7 @@ static int ext3_setup_super(struct super
+ 			EXT3_BLOCKS_PER_GROUP(sb),
+ 			EXT3_INODES_PER_GROUP(sb),
+ 			sbi->s_mount_opt);
++
+ 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
+ 				bdevname(sb->s_dev));
+ 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+@@ -897,6 +899,7 @@ static loff_t ext3_max_size(int bits)
+ 	return res;
+ }
+ 
++
+ struct super_block * ext3_read_super (struct super_block * sb, void * data,
+ 				      int silent)
+ {
+@@ -1073,6 +1076,9 @@ struct super_block * ext3_read_super (st
+ 	sbi->s_mount_state = le16_to_cpu(es->s_state);
+ 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+ 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++	for (i=0; i < 4; i++)
++		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
++	sbi->s_def_hash_version = es->s_def_hash_version;
+ 
+ 	if (sbi->s_blocks_per_group > blocksize * 8) {
+ 		printk (KERN_ERR
+@@ -1846,6 +1852,7 @@ static void __exit exit_ext3_fs(void)
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
++EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+--- linux-2.4.22-ac1/include/linux/ext3_fs.h~ext3-htree-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h	2003-09-25 14:58:30.000000000 +0400
+@@ -40,6 +40,11 @@
+ #define EXT3FS_VERSION		"2.4-0.9.19"
+ 
+ /*
++ * Always enable hashed directories
++ */
++#define CONFIG_EXT3_INDEX
++
++/*
+  * Debug code
+  */
+ #ifdef EXT3FS_DEBUG
+@@ -440,8 +445,11 @@ struct ext3_super_block {
+ /*E0*/	__u32	s_journal_inum;		/* inode number of journal file */
+ 	__u32	s_journal_dev;		/* device number of journal file */
+ 	__u32	s_last_orphan;		/* start of list of inodes to delete */
+-
+-/*EC*/	__u32	s_reserved[197];	/* Padding to the end of the block */
++	__u32	s_hash_seed[4];		/* HTREE hash seed */
++	__u8	s_def_hash_version;	/* Default hash version to use */
++	__u8	s_reserved_char_pad;
++	__u16	s_reserved_word_pad;
++	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+ #ifdef __KERNEL__
+@@ -578,9 +586,46 @@ struct ext3_dir_entry_2 {
+ #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
+ 					 ~EXT3_DIR_ROUND)
++/*
++ * Hash Tree Directory indexing
++ * (c) Daniel Phillips, 2001
++ */
++
++#ifdef CONFIG_EXT3_INDEX
++  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++					      EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++		      (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
++#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#else
++  #define is_dx(dir) 0
++#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
++#endif
++
++/* Legal values for the dx_root hash_version field: */
++
++#define DX_HASH_LEGACY		0
++#define DX_HASH_HALF_MD4	1
++#define DX_HASH_TEA		2
++
++/* hash info structure used by the directory hash */
++struct dx_hash_info
++{
++	u32		hash;
++	u32		minor_hash;
++	int		hash_version;
++	u32		*seed;
++};
+ 
+ #ifdef __KERNEL__
+ /*
++ * Control parameters used by ext3_htree_next_block
++ */
++#define HASH_NB_ALWAYS		1
++
++
++/*
+  * Describe an inode's exact location on disk and in memory
+  */
+ struct ext3_iloc
+@@ -590,6 +635,27 @@ struct ext3_iloc
+ 	unsigned long block_group;
+ };
+ 
++
++/*
++ * This structure is stuffed into the struct file's private_data field
++ * for directories.  It is where we put information so that we can do
++ * readdir operations in hash tree order.
++ */
++struct dir_private_info {
++	rb_root_t	root;
++	rb_node_t	*curr_node;
++	struct fname	*extra_fname;
++	loff_t		last_pos;
++	__u32		curr_hash;
++	__u32		curr_minor_hash;
++	__u32		next_hash;
++};
++
++/*
++ * Special error return code only used by dx_probe() and its callers.
++ */
++#define ERR_BAD_DX_DIR	-75000
++
+ /*
+  * Function prototypes
+  */
+@@ -617,11 +683,20 @@ extern struct ext3_group_desc * ext3_get
+ 
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
+-				struct ext3_dir_entry_2 *, struct buffer_head *,
+-				unsigned long);
++				struct ext3_dir_entry_2 *,
++				struct buffer_head *, unsigned long);
++extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++				    __u32 minor_hash,
++				    struct ext3_dir_entry_2 *dirent);
++extern void ext3_htree_free_dir_info(struct dir_private_info *p);
++
+ /* fsync.c */
+ extern int ext3_sync_file (struct file *, struct dentry *, int);
+ 
++/* hash.c */
++extern int ext3fs_dirhash(const char *name, int len, struct
++			  dx_hash_info *hinfo);
++
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+@@ -655,6 +730,8 @@ extern int ext3_ioctl (struct inode *, s
+ /* namei.c */
+ extern int ext3_orphan_add(handle_t *, struct inode *);
+ extern int ext3_orphan_del(handle_t *, struct inode *);
++extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++				__u32 start_minor_hash, __u32 *next_hash);
+ 
+ /* super.c */
+ extern void ext3_error (struct super_block *, const char *, const char *, ...)
+--- linux-2.4.22-ac1/include/linux/ext3_fs_sb.h~ext3-htree-2.4.22-rh	2003-09-25 14:16:34.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_sb.h	2003-09-25 14:55:12.000000000 +0400
+@@ -62,6 +62,8 @@ struct ext3_sb_info {
+ 	int s_inode_size;
+ 	int s_first_ino;
+ 	u32 s_next_generation;
++	u32 s_hash_seed[4];
++	int s_def_hash_version;
+ 
+ 	unsigned long s_dir_count;
+ 	u8 *s_debts;
+--- linux-2.4.22-ac1/include/linux/ext3_jbd.h~ext3-htree-2.4.22-rh	2003-06-13 18:51:38.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_jbd.h	2003-09-25 14:55:12.000000000 +0400
+@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s
+ 
+ #define EXT3_RESERVE_TRANS_BLOCKS	12U
+ 
++#define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
++
+ int
+ ext3_mark_iloc_dirty(handle_t *handle, 
+ 		     struct inode *inode,
+--- linux-2.4.22-ac1/include/linux/rbtree.h~ext3-htree-2.4.22-rh	2001-11-22 22:46:18.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/rbtree.h	2003-09-25 14:55:12.000000000 +0400
+@@ -120,6 +120,8 @@ rb_root_t;
+ 
+ extern void rb_insert_color(rb_node_t *, rb_root_t *);
+ extern void rb_erase(rb_node_t *, rb_root_t *);
++extern rb_node_t *rb_get_first(rb_root_t *root);
++extern rb_node_t *rb_get_next(rb_node_t *n);
+ 
+ static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+ {
+--- linux-2.4.22-ac1/lib/rbtree.c~ext3-htree-2.4.22-rh	2002-08-03 04:39:46.000000000 +0400
++++ linux-2.4.22-ac1-alexey/lib/rbtree.c	2003-09-25 14:55:12.000000000 +0400
+@@ -17,6 +17,8 @@
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+   linux/lib/rbtree.c
++
++  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+ */
+ 
+ #include <linux/rbtree.h>
+@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_
+ 		__rb_erase_color(child, parent, root);
+ }
+ EXPORT_SYMBOL(rb_erase);
++
++/*
++ * This function returns the first node (in sort order) of the tree.
++ */
++rb_node_t *rb_get_first(rb_root_t *root)
++{
++	rb_node_t	*n;
++
++	n = root->rb_node;
++	if (!n)
++		return 0;
++	while (n->rb_left)
++		n = n->rb_left;
++	return n;
++}
++EXPORT_SYMBOL(rb_get_first);
++
++/*
++ * Given a node, this function will return the next node in the tree.
++ */
++rb_node_t *rb_get_next(rb_node_t *n)
++{
++	rb_node_t	*parent;
++
++	if (n->rb_right) {
++		n = n->rb_right;
++		while (n->rb_left)
++			n = n->rb_left;
++		return n;
++	} else {
++		while ((parent = n->rb_parent)) {
++			if (n == parent->rb_left)
++				return parent;
++			n = parent;
++		}
++		return 0;
++	}
++}
++EXPORT_SYMBOL(rb_get_next);
++
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-htree-suse.patch b/lustre/kernel_patches/patches/ext3-htree-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ea55ad1c8d13ddb77d063b2fddeb6ca07ac3e01c
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-htree-suse.patch
@@ -0,0 +1,2553 @@
+ fs/ext3/Makefile           |    2 
+ fs/ext3/dir.c              |  302 +++++++++
+ fs/ext3/file.c             |    3 
+ fs/ext3/hash.c             |  215 ++++++
+ fs/ext3/namei.c            | 1420 ++++++++++++++++++++++++++++++++++++++++-----
+ fs/ext3/super.c            |    7 
+ include/linux/ext3_fs.h    |   85 ++
+ include/linux/ext3_fs_sb.h |    2 
+ include/linux/ext3_jbd.h   |    2 
+ include/linux/rbtree.h     |    2 
+ lib/rbtree.c               |   42 +
+ 11 files changed, 1921 insertions(+), 161 deletions(-)
+
+Index: linux-2.4.21-suse/fs/ext3/dir.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/dir.c	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/dir.c	2003-10-29 23:17:20.000000000 +0300
+@@ -21,12 +21,16 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/slab.h>
++#include <linux/rbtree.h>
+ 
+ static unsigned char ext3_filetype_table[] = {
+ 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+ };
+ 
+ static int ext3_readdir(struct file *, void *, filldir_t);
++static int ext3_dx_readdir(struct file * filp,
++			   void * dirent, filldir_t filldir);
+ 
+ struct file_operations ext3_dir_operations = {
+ 	read:		generic_read_dir,
+@@ -35,6 +39,17 @@
+ 	fsync:		ext3_sync_file,		/* BKL held */
+ };
+ 
++
++static unsigned char get_dtype(struct super_block *sb, int filetype)
++{
++	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
++	    (filetype >= EXT3_FT_MAX))
++		return DT_UNKNOWN;
++
++	return (ext3_filetype_table[filetype]);
++}
++			       
++
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ 			  struct ext3_dir_entry_2 * de,
+ 			  struct buffer_head * bh,
+@@ -79,6 +94,16 @@
+ 
+ 	sb = inode->i_sb;
+ 
++	if (is_dx(inode)) {
++		err = ext3_dx_readdir(filp, dirent, filldir);
++		if (err != ERR_BAD_DX_DIR)
++			return err;
++		/*
++		 * We don't set the inode dirty flag since it's not
++		 * critical that it get flushed back to the disk.
++		 */
++		EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
++	}
+ 	stored = 0;
+ 	bh = NULL;
+ 	offset = filp->f_pos & (sb->s_blocksize - 1);
+@@ -162,18 +187,12 @@
+ 				 * during the copy operation.
+ 				 */
+ 				unsigned long version = filp->f_version;
+-				unsigned char d_type = DT_UNKNOWN;
+ 
+-				if (EXT3_HAS_INCOMPAT_FEATURE(sb,
+-						EXT3_FEATURE_INCOMPAT_FILETYPE)
+-						&& de->file_type < EXT3_FT_MAX)
+-					d_type =
+-					  ext3_filetype_table[de->file_type];
+ 				error = filldir(dirent, de->name,
+ 						de->name_len,
+ 						filp->f_pos,
+ 						le32_to_cpu(de->inode),
+-						d_type);
++						get_dtype(sb, de->file_type));
+ 				if (error)
+ 					break;
+ 				if (version != filp->f_version)
+@@ -188,3 +207,272 @@
+ 	UPDATE_ATIME(inode);
+ 	return 0;
+ }
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * These functions convert from the major/minor hash to an f_pos
++ * value.
++ * 
++ * Currently we only use major hash numer.  This is unfortunate, but
++ * on 32-bit machines, the same VFS interface is used for lseek and
++ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
++ * lseek/telldir/seekdir will blow out spectacularly, and from within
++ * the ext2 low-level routine, we don't know if we're being called by
++ * a 64-bit version of the system call or the 32-bit version of the
++ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
++ * cookie.  Sigh.
++ */
++#define hash2pos(major, minor)	(major >> 1)
++#define pos2maj_hash(pos)	((pos << 1) & 0xffffffff)
++#define pos2min_hash(pos)	(0)
++
++/*
++ * This structure holds the nodes of the red-black tree used to store
++ * the directory entry in hash order.
++ */
++struct fname {
++	__u32		hash;
++	__u32		minor_hash;
++	rb_node_t	rb_hash; 
++	struct fname	*next;
++	__u32		inode;
++	__u8		name_len;
++	__u8		file_type;
++	char		name[0];
++};
++
++/*
++ * This functoin implements a non-recursive way of freeing all of the
++ * nodes in the red-black tree.
++ */
++static void free_rb_tree_fname(rb_root_t *root)
++{
++	rb_node_t	*n = root->rb_node;
++	rb_node_t	*parent;
++	struct fname	*fname;
++
++	while (n) {
++		/* Do the node's children first */
++		if ((n)->rb_left) {
++			n = n->rb_left;
++			continue;
++		}
++		if (n->rb_right) {
++			n = n->rb_right;
++			continue;
++		}
++		/*
++		 * The node has no children; free it, and then zero
++		 * out parent's link to it.  Finally go to the
++		 * beginning of the loop and try to free the parent
++		 * node.
++		 */
++		parent = n->rb_parent;
++		fname = rb_entry(n, struct fname, rb_hash);
++		kfree(fname);
++		if (!parent)
++			root->rb_node = 0;
++		else if (parent->rb_left == n)
++			parent->rb_left = 0;
++		else if (parent->rb_right == n)
++			parent->rb_right = 0;
++		n = parent;
++	}
++	root->rb_node = 0;
++}
++
++
++struct dir_private_info *create_dir_info(loff_t pos)
++{
++	struct dir_private_info *p;
++
++	p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
++	if (!p)
++		return NULL;
++	p->root.rb_node = 0;
++	p->curr_node = 0;
++	p->extra_fname = 0;
++	p->last_pos = 0;
++	p->curr_hash = pos2maj_hash(pos);
++	p->curr_minor_hash = pos2min_hash(pos);
++	p->next_hash = 0;
++	return p;
++}
++
++void ext3_htree_free_dir_info(struct dir_private_info *p)
++{
++	free_rb_tree_fname(&p->root);
++	kfree(p);
++}
++		
++/*
++ * Given a directory entry, enter it into the fname rb tree.
++ */
++int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++			     __u32 minor_hash,
++			     struct ext3_dir_entry_2 *dirent)
++{
++	rb_node_t **p, *parent = NULL;
++	struct fname * fname, *new_fn;
++	struct dir_private_info *info;
++	int len;
++
++	info = (struct dir_private_info *) dir_file->private_data;
++	p = &info->root.rb_node;
++
++	/* Create and allocate the fname structure */
++	len = sizeof(struct fname) + dirent->name_len + 1;
++	new_fn = kmalloc(len, GFP_KERNEL);
++	if (!new_fn)
++		return -ENOMEM;
++	memset(new_fn, 0, len);
++	new_fn->hash = hash;
++	new_fn->minor_hash = minor_hash;
++	new_fn->inode = le32_to_cpu(dirent->inode);
++	new_fn->name_len = dirent->name_len;
++	new_fn->file_type = dirent->file_type;
++	memcpy(new_fn->name, dirent->name, dirent->name_len);
++	new_fn->name[dirent->name_len] = 0;
++	
++	while (*p) {
++		parent = *p;
++		fname = rb_entry(parent, struct fname, rb_hash);
++
++		/*
++		 * If the hash and minor hash match up, then we put
++		 * them on a linked list.  This rarely happens...
++		 */
++		if ((new_fn->hash == fname->hash) &&
++		    (new_fn->minor_hash == fname->minor_hash)) {
++			new_fn->next = fname->next;
++			fname->next = new_fn;
++			return 0;
++		}
++			
++		if (new_fn->hash < fname->hash)
++			p = &(*p)->rb_left;
++		else if (new_fn->hash > fname->hash)
++			p = &(*p)->rb_right;
++		else if (new_fn->minor_hash < fname->minor_hash)
++			p = &(*p)->rb_left;
++		else /* if (new_fn->minor_hash > fname->minor_hash) */
++			p = &(*p)->rb_right;
++	}
++
++	rb_link_node(&new_fn->rb_hash, parent, p);
++	rb_insert_color(&new_fn->rb_hash, &info->root);
++	return 0;
++}
++
++
++
++/*
++ * This is a helper function for ext3_dx_readdir.  It calls filldir
++ * for all entres on the fname linked list.  (Normally there is only
++ * one entry on the linked list, unless there are 62 bit hash collisions.)
++ */
++static int call_filldir(struct file * filp, void * dirent,
++			filldir_t filldir, struct fname *fname)
++{
++	struct dir_private_info *info = filp->private_data;
++	loff_t	curr_pos;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct super_block * sb;
++	int error;
++
++	sb = inode->i_sb;
++	
++	if (!fname) {
++		printk("call_filldir: called with null fname?!?\n");
++		return 0;
++	}
++	curr_pos = hash2pos(fname->hash, fname->minor_hash);
++	while (fname) {
++		error = filldir(dirent, fname->name,
++				fname->name_len, curr_pos, 
++				fname->inode,
++				get_dtype(sb, fname->file_type));
++		if (error) {
++			filp->f_pos = curr_pos;
++			info->extra_fname = fname->next;
++			return error;
++		}
++		fname = fname->next;
++	}
++	return 0;
++}
++
++static int ext3_dx_readdir(struct file * filp,
++			 void * dirent, filldir_t filldir)
++{
++	struct dir_private_info *info = filp->private_data;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct fname *fname;
++	int	ret;
++
++	if (!info) {
++		info = create_dir_info(filp->f_pos);
++		if (!info)
++			return -ENOMEM;
++		filp->private_data = info;
++	}
++
++	/* Some one has messed with f_pos; reset the world */
++	if (info->last_pos != filp->f_pos) {
++		free_rb_tree_fname(&info->root);
++		info->curr_node = 0;
++		info->extra_fname = 0;
++		info->curr_hash = pos2maj_hash(filp->f_pos);
++		info->curr_minor_hash = pos2min_hash(filp->f_pos);
++	}
++
++	/*
++	 * If there are any leftover names on the hash collision
++	 * chain, return them first.
++	 */
++	if (info->extra_fname &&
++	    call_filldir(filp, dirent, filldir, info->extra_fname))
++		goto finished;
++
++	if (!info->curr_node)
++		info->curr_node = rb_get_first(&info->root);
++
++	while (1) {
++		/*
++		 * Fill the rbtree if we have no more entries,
++		 * or the inode has changed since we last read in the
++		 * cached entries. 
++		 */
++		if ((!info->curr_node) ||
++		    (filp->f_version != inode->i_version)) {
++			info->curr_node = 0;
++			free_rb_tree_fname(&info->root);
++			filp->f_version = inode->i_version;
++			ret = ext3_htree_fill_tree(filp, info->curr_hash,
++						   info->curr_minor_hash,
++						   &info->next_hash);
++			if (ret < 0)
++				return ret;
++			if (ret == 0)
++				break;
++			info->curr_node = rb_get_first(&info->root);
++		}
++
++		fname = rb_entry(info->curr_node, struct fname, rb_hash);
++		info->curr_hash = fname->hash;
++		info->curr_minor_hash = fname->minor_hash;
++		if (call_filldir(filp, dirent, filldir, fname))
++			break;
++
++		info->curr_node = rb_get_next(info->curr_node);
++		if (!info->curr_node) {
++			info->curr_hash = info->next_hash;
++			info->curr_minor_hash = 0;
++		}
++	}
++finished:
++	info->last_pos = filp->f_pos;
++	UPDATE_ATIME(inode);
++	return 0;
++}
++#endif
+Index: linux-2.4.21-suse/fs/ext3/file.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/file.c	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/file.c	2003-10-29 23:17:20.000000000 +0300
+@@ -35,6 +35,9 @@
+ {
+ 	if (filp->f_mode & FMODE_WRITE)
+ 		ext3_discard_prealloc (inode);
++	if (is_dx(inode) && filp->private_data)
++		ext3_htree_free_dir_info(filp->private_data);
++
+ 	return 0;
+ }
+ 
+Index: linux-2.4.21-suse/fs/ext3/hash.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/hash.c	2003-10-29 23:17:20.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/hash.c	2003-10-29 23:17:20.000000000 +0300
+@@ -0,0 +1,215 @@
++/*
++ *  linux/fs/ext3/hash.c
++ *
++ * Copyright (C) 2002 by Theodore Ts'o
++ *
++ * This file is released under the GPL v2.
++ * 
++ * This file may be redistributed under the terms of the GNU Public
++ * License.
++ */
++
++#include <linux/fs.h>
++#include <linux/jbd.h>
++#include <linux/sched.h>
++#include <linux/ext3_fs.h>
++
++#define DELTA 0x9E3779B9
++
++static void TEA_transform(__u32 buf[4], __u32 const in[])
++{
++	__u32	sum = 0;
++	__u32	b0 = buf[0], b1 = buf[1];
++	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
++	int	n = 16;
++
++	do {							
++		sum += DELTA;					
++		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
++		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
++	} while(--n);
++
++	buf[0] += b0;
++	buf[1] += b1;
++}
++
++/* F, G and H are basic MD4 functions: selection, majority, parity */
++#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
++#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
++#define H(x, y, z) ((x) ^ (y) ^ (z))
++
++/*
++ * The generic round function.  The application is so specific that
++ * we don't bother protecting all the arguments with parens, as is generally
++ * good macro practice, in favor of extra legibility.
++ * Rotation is separate from addition to prevent recomputation
++ */
++#define ROUND(f, a, b, c, d, x, s)	\
++	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
++#define K1 0
++#define K2 013240474631UL
++#define K3 015666365641UL
++
++/*
++ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
++ */
++static void halfMD4Transform (__u32 buf[4], __u32 const in[])
++{
++	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
++
++	/* Round 1 */
++	ROUND(F, a, b, c, d, in[0] + K1,  3);
++	ROUND(F, d, a, b, c, in[1] + K1,  7);
++	ROUND(F, c, d, a, b, in[2] + K1, 11);
++	ROUND(F, b, c, d, a, in[3] + K1, 19);
++	ROUND(F, a, b, c, d, in[4] + K1,  3);
++	ROUND(F, d, a, b, c, in[5] + K1,  7);
++	ROUND(F, c, d, a, b, in[6] + K1, 11);
++	ROUND(F, b, c, d, a, in[7] + K1, 19);
++
++	/* Round 2 */
++	ROUND(G, a, b, c, d, in[1] + K2,  3);
++	ROUND(G, d, a, b, c, in[3] + K2,  5);
++	ROUND(G, c, d, a, b, in[5] + K2,  9);
++	ROUND(G, b, c, d, a, in[7] + K2, 13);
++	ROUND(G, a, b, c, d, in[0] + K2,  3);
++	ROUND(G, d, a, b, c, in[2] + K2,  5);
++	ROUND(G, c, d, a, b, in[4] + K2,  9);
++	ROUND(G, b, c, d, a, in[6] + K2, 13);
++
++	/* Round 3 */
++	ROUND(H, a, b, c, d, in[3] + K3,  3);
++	ROUND(H, d, a, b, c, in[7] + K3,  9);
++	ROUND(H, c, d, a, b, in[2] + K3, 11);
++	ROUND(H, b, c, d, a, in[6] + K3, 15);
++	ROUND(H, a, b, c, d, in[1] + K3,  3);
++	ROUND(H, d, a, b, c, in[5] + K3,  9);
++	ROUND(H, c, d, a, b, in[0] + K3, 11);
++	ROUND(H, b, c, d, a, in[4] + K3, 15);
++
++	buf[0] += a;
++	buf[1] += b;
++	buf[2] += c;
++	buf[3] += d;
++}
++
++#undef ROUND
++#undef F
++#undef G
++#undef H
++#undef K1
++#undef K2
++#undef K3
++
++/* The old legacy hash */
++static __u32 dx_hack_hash (const char *name, int len)
++{
++	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++	while (len--) {
++		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++		
++		if (hash & 0x80000000) hash -= 0x7fffffff;
++		hash1 = hash0;
++		hash0 = hash;
++	}
++	return (hash0 << 1);
++}
++
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++{
++	__u32	pad, val;
++	int	i;
++
++	pad = (__u32)len | ((__u32)len << 8);
++	pad |= pad << 16;
++
++	val = pad;
++	if (len > num*4)
++		len = num * 4;
++	for (i=0; i < len; i++) {
++		if ((i % 4) == 0)
++			val = pad;
++		val = msg[i] + (val << 8);
++		if ((i % 4) == 3) {
++			*buf++ = val;
++			val = pad;
++			num--;
++		}
++	}
++	if (--num >= 0)
++		*buf++ = val;
++	while (--num >= 0)
++		*buf++ = pad;
++}
++
++/*
++ * Returns the hash of a filename.  If len is 0 and name is NULL, then
++ * this function can be used to test whether or not a hash version is
++ * supported.
++ * 
++ * The seed is an 4 longword (32 bits) "secret" which can be used to
++ * uniquify a hash.  If the seed is all zero's, then some default seed
++ * may be used.
++ * 
++ * A particular hash version specifies whether or not the seed is
++ * represented, and whether or not the returned hash is 32 bits or 64
++ * bits.  32 bit hashes will return 0 for the minor hash.
++ */
++int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
++{
++	__u32	hash;
++	__u32	minor_hash = 0;
++	const char	*p;
++	int		i;
++	__u32 		in[8], buf[4];
++
++	/* Initialize the default seed for the hash checksum functions */
++	buf[0] = 0x67452301;
++	buf[1] = 0xefcdab89;
++	buf[2] = 0x98badcfe;
++	buf[3] = 0x10325476;
++
++	/* Check to see if the seed is all zero's */
++	if (hinfo->seed) {
++		for (i=0; i < 4; i++) {
++			if (hinfo->seed[i])
++				break;
++		}
++		if (i < 4)
++			memcpy(buf, hinfo->seed, sizeof(buf));
++	}
++		
++	switch (hinfo->hash_version) {
++	case DX_HASH_LEGACY:
++		hash = dx_hack_hash(name, len);
++		break;
++	case DX_HASH_HALF_MD4:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 8);
++			halfMD4Transform(buf, in);
++			len -= 32;
++			p += 32;
++		}
++		minor_hash = buf[2];
++		hash = buf[1];
++		break;
++	case DX_HASH_TEA:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 4);
++			TEA_transform(buf, in);
++			len -= 16;
++			p += 16;
++		}
++		hash = buf[0];
++		minor_hash = buf[1];
++		break;
++	default:
++		hinfo->hash = 0;
++		return -1;
++	}
++	hinfo->hash = hash & ~1;
++	hinfo->minor_hash = minor_hash;
++	return 0;
++}
+Index: linux-2.4.21-suse/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/Makefile	2003-10-29 22:39:14.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/Makefile	2003-10-29 23:17:20.000000000 +0300
+@@ -12,7 +12,7 @@
+ export-objs :=	super.o inode.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o
++		ioctl.o namei.o super.o symlink.o hash.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.21-suse/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/namei.c	2003-06-13 18:51:37.000000000 +0400
++++ linux-2.4.21-suse/fs/ext3/namei.c	2003-10-29 23:25:23.000000000 +0300
+@@ -16,6 +16,12 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  *  Directory entry file type support and forward compatibility hooks
+  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
++ *  Hash Tree Directory indexing (c)
++ *  	Daniel Phillips, 2001
++ *  Hash Tree Directory indexing porting
++ *  	Christopher Li, 2002
++ *  Hash Tree Directory indexing cleanup
++ * 	Theodore Ts'o, 2002
+  */
+ 
+ #include <linux/fs.h>
+@@ -38,6 +44,642 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+ 
++static struct buffer_head *ext3_append(handle_t *handle,
++					struct inode *inode,
++					u32 *block, int *err)
++{
++	struct buffer_head *bh;
++
++	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
++
++	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++		inode->i_size += inode->i_sb->s_blocksize;
++		EXT3_I(inode)->i_disksize = inode->i_size;
++		ext3_journal_get_write_access(handle,bh);
++	}
++	return bh;
++}
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#ifndef swap
++#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
++#endif
++
++typedef struct { u32 v; } le_u32;
++typedef struct { u16 v; } le_u16;
++
++#ifdef DX_DEBUG
++#define dxtrace(command) command
++#else
++#define dxtrace(command) 
++#endif
++
++struct fake_dirent
++{
++	/*le*/u32 inode;
++	/*le*/u16 rec_len;
++	u8 name_len;
++	u8 file_type;
++};
++
++struct dx_countlimit
++{
++	le_u16 limit;
++	le_u16 count;
++};
++
++struct dx_entry
++{
++	le_u32 hash;
++	le_u32 block;
++};
++
++/*
++ * dx_root_info is laid out so that if it should somehow get overlaid by a
++ * dirent the two low bits of the hash version will be zero.  Therefore, the
++ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
++ */
++
++struct dx_root
++{
++	struct fake_dirent dot;
++	char dot_name[4];
++	struct fake_dirent dotdot;
++	char dotdot_name[4];
++	struct dx_root_info
++	{
++		le_u32 reserved_zero;
++		u8 hash_version;
++		u8 info_length; /* 8 */
++		u8 indirect_levels;
++		u8 unused_flags;
++	}
++	info;
++	struct dx_entry	entries[0];
++};
++
++struct dx_node
++{
++	struct fake_dirent fake;
++	struct dx_entry	entries[0];
++};
++
++
++struct dx_frame
++{
++	struct buffer_head *bh;
++	struct dx_entry *entries;
++	struct dx_entry *at;
++};
++
++struct dx_map_entry
++{
++	u32 hash;
++	u32 offs;
++};
++
++#ifdef CONFIG_EXT3_INDEX
++static inline unsigned dx_get_block (struct dx_entry *entry);
++static void dx_set_block (struct dx_entry *entry, unsigned value);
++static inline unsigned dx_get_hash (struct dx_entry *entry);
++static void dx_set_hash (struct dx_entry *entry, unsigned value);
++static unsigned dx_get_count (struct dx_entry *entries);
++static unsigned dx_get_limit (struct dx_entry *entries);
++static void dx_set_count (struct dx_entry *entries, unsigned value);
++static void dx_set_limit (struct dx_entry *entries, unsigned value);
++static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
++static unsigned dx_node_limit (struct inode *dir);
++static struct dx_frame *dx_probe(struct dentry *dentry,
++				 struct inode *dir,
++				 struct dx_hash_info *hinfo,
++				 struct dx_frame *frame,
++				 int *err);
++static void dx_release (struct dx_frame *frames);
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
++static void dx_sort_map(struct dx_map_entry *map, unsigned count);
++static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
++		struct dx_map_entry *offsets, int count);
++static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
++static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash);
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err);
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode);
++
++/*
++ * Future: use high four bits of block for coalesce-on-delete flags
++ * Mask them off for now.
++ */
++
++static inline unsigned dx_get_block (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->block.v) & 0x00ffffff;
++}
++
++static inline void dx_set_block (struct dx_entry *entry, unsigned value)
++{
++	entry->block.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_hash (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->hash.v);
++}
++
++static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
++{
++	entry->hash.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_count (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
++}
++
++static inline unsigned dx_get_limit (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
++}
++
++static inline void dx_set_count (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
++}
++
++static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
++}
++
++static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
++		EXT3_DIR_REC_LEN(2) - infosize;
++	return 0? 20: entry_space / sizeof(struct dx_entry);
++}
++
++static inline unsigned dx_node_limit (struct inode *dir)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
++	return 0? 22: entry_space / sizeof(struct dx_entry);
++}
++
++/*
++ * Debug
++ */
++#ifdef DX_DEBUG
++struct stats
++{ 
++	unsigned names;
++	unsigned space;
++	unsigned bcount;
++};
++
++static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
++				 int size, int show_names)
++{
++	unsigned names = 0, space = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	printk("names: ");
++	while ((char *) de < base + size)
++	{
++		if (de->inode)
++		{
++			if (show_names)
++			{
++				int len = de->name_len;
++				char *name = de->name;
++				while (len--) printk("%c", *name++);
++				ext3fs_dirhash(de->name, de->name_len, &h);
++				printk(":%x.%u ", h.hash,
++				       ((char *) de - base));
++			}
++			space += EXT3_DIR_REC_LEN(de->name_len);
++	 		names++;
++		}
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	printk("(%i)\n", names);
++	return (struct stats) { names, space, 1 };
++}
++
++struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
++			     struct dx_entry *entries, int levels)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
++	unsigned bcount = 0;
++	struct buffer_head *bh;
++	int err;
++	printk("%i indexed blocks...\n", count);
++	for (i = 0; i < count; i++, entries++)
++	{
++		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
++		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
++		struct stats stats;
++		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
++		if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
++		stats = levels?
++		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
++		   dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
++		names += stats.names;
++		space += stats.space;
++		bcount += stats.bcount;
++		brelse (bh);
++	}
++	if (bcount)
++		printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
++			names, space/bcount,(space/bcount)*100/blocksize);
++	return (struct stats) { names, space, bcount};
++}
++#endif /* DX_DEBUG */
++
++/*
++ * Probe for a directory leaf block to search.
++ *
++ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
++ * error in the directory index, and the caller should fall back to
++ * searching the directory normally.  The callers of dx_probe **MUST**
++ * check for this error code, and make sure it never gets reflected
++ * back to userspace.
++ */
++static struct dx_frame *
++dx_probe(struct dentry *dentry, struct inode *dir,
++	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
++{
++	unsigned count, indirect;
++	struct dx_entry *at, *entries, *p, *q, *m;
++	struct dx_root *root;
++	struct buffer_head *bh;
++	struct dx_frame *frame = frame_in;
++	u32 hash;
++
++	frame->bh = NULL;
++	if (dentry)
++		dir = dentry->d_parent->d_inode;
++	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
++		goto fail;
++	root = (struct dx_root *) bh->b_data;
++	if (root->info.hash_version != DX_HASH_TEA &&
++	    root->info.hash_version != DX_HASH_HALF_MD4 &&
++	    root->info.hash_version != DX_HASH_LEGACY) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unrecognised inode hash code %d",
++			     root->info.hash_version);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++	hinfo->hash_version = root->info.hash_version;
++	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	if (dentry)
++		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	hash = hinfo->hash;
++
++	if (root->info.unused_flags & 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash flags: %#06x",
++			     root->info.unused_flags);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	if ((indirect = root->info.indirect_levels) > 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash depth: %#06x",
++			     root->info.indirect_levels);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	while (1)
++	{
++		count = dx_get_count(entries);
++		assert (count && count <= dx_get_limit(entries));
++		p = entries + 1;
++		q = entries + count - 1;
++		while (p <= q)
++		{
++			m = p + (q - p)/2;
++			dxtrace(printk("."));
++			if (dx_get_hash(m) > hash)
++				q = m - 1;
++			else
++				p = m + 1;
++		}
++
++		if (0) // linear search cross check
++		{
++			unsigned n = count - 1;
++			at = entries;
++			while (n--)
++			{
++				dxtrace(printk(","));
++				if (dx_get_hash(++at) > hash)
++				{
++					at--;
++					break;
++				}
++			}
++			assert (at == p - 1);
++		}
++
++		at = p - 1;
++		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		frame->bh = bh;
++		frame->entries = entries;
++		frame->at = at;
++		if (!indirect--) return frame;
++		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++			goto fail2;
++		at = entries = ((struct dx_node *) bh->b_data)->entries;
++		assert (dx_get_limit(entries) == dx_node_limit (dir));
++		frame++;
++	}
++fail2:
++	while (frame >= frame_in) {
++		brelse(frame->bh);
++		frame--;
++	}
++fail:
++	return NULL;
++}
++
++static void dx_release (struct dx_frame *frames)
++{
++	if (frames[0].bh == NULL)
++		return;
++
++	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++		brelse(frames[1].bh);
++	brelse(frames[0].bh);
++}
++
++/*
++ * This function increments the frame pointer to search the next leaf
++ * block, and reads in the necessary intervening nodes if the search
++ * should be necessary.  Whether or not the search is necessary is
++ * controlled by the hash parameter.  If the hash value is even, then
++ * the search is only continued if the next block starts with that
++ * hash value.  This is used if we are searching for a specific file.
++ *
++ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
++ *
++ * This function returns 1 if the caller should continue to search,
++ * or 0 if it should not.  If there is an error reading one of the
++ * index blocks, it will return -1.
++ *
++ * If start_hash is non-null, it will be filled in with the starting
++ * hash of the next page.
++ */
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash)
++{
++	struct dx_frame *p;
++	struct buffer_head *bh;
++	int num_frames = 0;
++	__u32 bhash;
++
++	*err = ENOENT;
++	p = frame;
++	/*
++	 * Find the next leaf page by incrementing the frame pointer.
++	 * If we run out of entries in the interior node, loop around and
++	 * increment pointer in the parent node.  When we break out of
++	 * this loop, num_frames indicates the number of interior
++	 * nodes need to be read.
++	 */
++	while (1) {
++		if (++(p->at) < p->entries + dx_get_count(p->entries))
++			break;
++		if (p == frames)
++			return 0;
++		num_frames++;
++		p--;
++	}
++
++	/*
++	 * If the hash is 1, then continue only if the next page has a
++	 * continuation hash of any value.  This is used for readdir
++	 * handling.  Otherwise, check to see if the hash matches the
++	 * desired contiuation hash.  If it doesn't, return since
++	 * there's no point to read in the successive index pages.
++	 */
++	bhash = dx_get_hash(p->at);
++	if (start_hash)
++		*start_hash = bhash;
++	if ((hash & 1) == 0) {
++		if ((bhash & ~1) != hash)
++			return 0;
++	}
++	/*
++	 * If the hash is HASH_NB_ALWAYS, we always go to the next
++	 * block so no check is necessary
++	 */
++	while (num_frames--) {
++		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
++				      0, err)))
++			return -1; /* Failure */
++		p++;
++		brelse (p->bh);
++		p->bh = bh;
++		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++	}
++	return 1;
++}
++
++
++/*
++ * p is at least 6 bytes before the end of page
++ */
++static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
++{
++	return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
++}
++
++/*
++ * This function fills a red-black tree with information from a
++ * directory.  We start scanning the directory in hash order, starting
++ * at start_hash and start_minor_hash.
++ *
++ * This function returns the number of entries inserted into the tree,
++ * or a negative error code.
++ */
++int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++			 __u32 start_minor_hash, __u32 *next_hash)
++{
++	struct dx_hash_info hinfo;
++	struct buffer_head *bh;
++	struct ext3_dir_entry_2 *de, *top;
++	static struct dx_frame frames[2], *frame;
++	struct inode *dir;
++	int block, err;
++	int count = 0;
++	int ret;
++	__u32 hashval;
++	
++	dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
++		       start_minor_hash));
++	dir = dir_file->f_dentry->d_inode;
++	hinfo.hash = start_hash;
++	hinfo.minor_hash = 0;
++	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++
++	/* Add '.' and '..' from the htree header */
++	if (!start_hash && !start_minor_hash) {
++		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		de = ext3_next_entry(de);
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		count += 2;
++	}
++
++	while (1) {
++		block = dx_get_block(frame->at);
++		dxtrace(printk("Reading block %d\n", block));
++		if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
++			goto errout;
++	
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de)) {
++			ext3fs_dirhash(de->name, de->name_len, &hinfo);
++			if ((hinfo.hash < start_hash) ||
++			    ((hinfo.hash == start_hash) &&
++			     (hinfo.minor_hash < start_minor_hash)))
++				continue;
++			if ((err = ext3_htree_store_dirent(dir_file,
++				   hinfo.hash, hinfo.minor_hash, de)) != 0)
++				goto errout;
++			count++;
++		}
++		brelse (bh);
++		hashval = ~1;
++		ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
++					    frame, frames, &err, &hashval);
++		if (next_hash)
++			*next_hash = hashval;
++		if (ret == -1)
++			goto errout;
++		/*
++		 * Stop if:  (a) there are no more entries, or
++		 * (b) we have inserted at least one entry and the
++		 * next hash value is not a continuation
++		 */
++		if ((ret == 0) ||
++		    (count && ((hashval & 1) == 0)))
++			break;
++	}
++	dx_release(frames);
++	dxtrace(printk("Fill tree: returned %d entries\n", count));
++	return count;
++errout:
++	dx_release(frames);
++	return (err);
++}
++
++
++/*
++ * Directory block splitting, compacting
++ */
++
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
++{
++	int count = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	while ((char *) de < base + size)
++	{
++		if (de->name_len && de->inode) {
++			ext3fs_dirhash(de->name, de->name_len, &h);
++			map_tail--;
++			map_tail->hash = h.hash;
++			map_tail->offs = (u32) ((char *) de - base);
++			count++;
++		}
++		/* XXX: do we need to check rec_len == 0 case? -Chris */
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	return count;
++}
++
++static void dx_sort_map (struct dx_map_entry *map, unsigned count)
++{
++        struct dx_map_entry *p, *q, *top = map + count - 1;
++        int more;
++        /* Combsort until bubble sort doesn't suck */
++        while (count > 2)
++	{
++                count = count*10/13;
++                if (count - 9 < 2) /* 9, 10 -> 11 */
++                        count = 11;
++                for (p = top, q = p - count; q >= map; p--, q--)
++                        if (p->hash < q->hash)
++                                swap(*p, *q);
++        }
++        /* Garden variety bubble sort */
++        do {
++                more = 0;
++                q = top;
++                while (q-- > map)
++		{
++                        if (q[1].hash >= q[0].hash)
++				continue;
++                        swap(*(q+1), *q);
++                        more = 1;
++		}
++	} while(more);
++}
++
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++{
++	struct dx_entry *entries = frame->entries;
++	struct dx_entry *old = frame->at, *new = old + 1;
++	int count = dx_get_count(entries);
++
++	assert(count < dx_get_limit(entries));
++	assert(old < entries + count);
++	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++	dx_set_hash(new, hash);
++	dx_set_block(new, block);
++	dx_set_count(entries, count + 1);
++}
++#endif
++
++
++static void ext3_update_dx_flag(struct inode *inode)
++{
++	if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
++				     EXT3_FEATURE_COMPAT_DIR_INDEX))
++		EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
++}
++
+ /*
+  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+  *
+@@ -94,6 +736,7 @@
+ 	return 0;
+ }
+ 
++
+ /*
+  *	ext3_find_entry()
+  *
+@@ -105,6 +748,8 @@
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
++
++	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+ 					struct ext3_dir_entry_2 ** res_dir)
+ {
+@@ -119,12 +764,32 @@
+ 	int num = 0;
+ 	int nblocks, i, err;
+ 	struct inode *dir = dentry->d_parent->d_inode;
++	int namelen;
++	const u8 *name;
++	unsigned blocksize;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+-
++	blocksize = sb->s_blocksize;
++	namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++	if (namelen > EXT3_NAME_LEN)
++		return NULL;
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		/*
++		 * On success, or if the error was file not found,
++		 * return.  Otherwise, fall back to doing a search the
++		 * old fashioned way.
++		 */
++		if (bh || (err != ERR_BAD_DX_DIR))
++			return bh;
++		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++	}
++#endif
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+-	start = dir->u.ext3_i.i_dir_start_lookup;
++	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+ 		start = 0;
+ 	block = start;
+@@ -165,7 +830,7 @@
+ 		i = search_dirblock(bh, dir, dentry,
+ 			    block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
+ 		if (i == 1) {
+-			dir->u.ext3_i.i_dir_start_lookup = block;
++			EXT3_I(dir)->i_dir_start_lookup = block;
+ 			ret = bh;
+ 			goto cleanup_and_exit;
+ 		} else {
+@@ -196,6 +861,66 @@
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err)
++{
++	struct super_block * sb;
++	struct dx_hash_info	hinfo;
++	u32 hash;
++	struct dx_frame frames[2], *frame;
++	struct ext3_dir_entry_2 *de, *top;
++	struct buffer_head *bh;
++	unsigned long block;
++	int retval;
++	int namelen = dentry->d_name.len;
++	const u8 *name = dentry->d_name.name;
++	struct inode *dir = dentry->d_parent->d_inode;
++	
++	sb = dir->i_sb;
++	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++		return NULL;
++	hash = hinfo.hash;
++	do {
++		block = dx_get_block(frame->at);
++		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
++			goto errout;
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de))
++		if (ext3_match (namelen, name, de)) {
++			if (!ext3_check_dir_entry("ext3_find_entry",
++						  dir, de, bh,
++				  (block<<EXT3_BLOCK_SIZE_BITS(sb))
++					  +((char *)de - bh->b_data))) {
++				brelse (bh);
++				goto errout;
++			}
++			*res_dir = de;
++			dx_release (frames);
++			return bh;
++		}
++		brelse (bh);
++		/* Check to see if we should continue to search */
++		retval = ext3_htree_next_block(dir, hash, frame,
++					       frames, err, 0);
++		if (retval == -1) {
++			ext3_warning(sb, __FUNCTION__,
++			     "error reading index page in directory #%lu",
++			     dir->i_ino);
++			goto errout;
++		}
++	} while (retval == 1);
++	
++	*err = -ENOENT;
++errout:
++	dxtrace(printk("%s not found\n", name));
++	dx_release (frames);
++	return NULL;
++}
++#endif
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+@@ -212,8 +937,9 @@
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+-		if (!inode)
++		if (!inode) {
+ 			return ERR_PTR(-EACCES);
++		}
+ 	}
+ 	d_add(dentry, inode);
+ 	return NULL;
+@@ -237,6 +963,301 @@
+ 		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct ext3_dir_entry_2 *
++dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
++{
++	unsigned rec_len = 0;
++
++	while (count--) {
++		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		rec_len = EXT3_DIR_REC_LEN(de->name_len);
++		memcpy (to, de, rec_len);
++		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
++		de->inode = 0;
++		map++;
++		to += rec_len;
++	}
++	return (struct ext3_dir_entry_2 *) (to - rec_len);
++}
++
++static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
++{
++	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	unsigned rec_len = 0;
++
++	prev = to = de;
++	while ((char*)de < base + size) {
++		next = (struct ext3_dir_entry_2 *) ((char *) de +
++						    le16_to_cpu(de->rec_len));
++		if (de->inode && de->name_len) {
++			rec_len = EXT3_DIR_REC_LEN(de->name_len);
++			if (de > to)
++				memmove(to, de, rec_len);
++			to->rec_len = rec_len;
++			prev = to;
++			to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
++		}
++		de = next;
++	}
++	return prev;
++}
++
++static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
++			struct buffer_head **bh,struct dx_frame *frame,
++			struct dx_hash_info *hinfo, int *error)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count, continued;
++	struct buffer_head *bh2;
++	u32 newblock;
++	u32 hash2;
++	struct dx_map_entry *map;
++	char *data1 = (*bh)->b_data, *data2;
++	unsigned split;
++	struct ext3_dir_entry_2 *de = NULL, *de2;
++	int	err;
++
++	bh2 = ext3_append (handle, dir, &newblock, error);
++	if (!(bh2)) {
++		brelse(*bh);
++		*bh = NULL;
++		goto errout;
++	}
++
++	BUFFER_TRACE(*bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, *bh);
++	if (err) {
++	journal_error:
++		brelse(*bh);
++		brelse(bh2);
++		*bh = NULL;
++		ext3_std_error(dir->i_sb, err);
++		goto errout;
++	}
++	BUFFER_TRACE(frame->bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, frame->bh);
++	if (err)
++		goto journal_error;
++
++	data2 = bh2->b_data;
++
++	/* create map in the end of data2 block */
++	map = (struct dx_map_entry *) (data2 + blocksize);
++	count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
++			     blocksize, hinfo, map);
++	map -= count;
++	split = count/2; // need to adjust to actual middle
++	dx_sort_map (map, count);
++	hash2 = map[split].hash;
++	continued = hash2 == map[split - 1].hash;
++	dxtrace(printk("Split block %i at %x, %i/%i\n",
++		dx_get_block(frame->at), hash2, split, count-split));
++
++	/* Fancy dance to stay within two buffers */
++	de2 = dx_move_dirents(data1, data2, map + split, count - split);
++	de = dx_pack_dirents(data1,blocksize);
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++
++	/* Which block gets the new entry? */
++	if (hinfo->hash >= hash2)
++	{
++		swap(*bh, bh2);
++		de = de2;
++	}
++	dx_insert_block (frame, hash2 + continued, newblock);
++	err = ext3_journal_dirty_metadata (handle, bh2);
++	if (err)
++		goto journal_error;
++	err = ext3_journal_dirty_metadata (handle, frame->bh);
++	if (err)
++		goto journal_error;
++	brelse (bh2);
++	dxtrace(dx_show_index ("frame", frame->entries));
++errout:
++	return de;
++}
++#endif
++
++
++/*
++ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
++ * it points to a directory entry which is guaranteed to be large
++ * enough for new directory entry.  If de is NULL, then
++ * add_dirent_to_buf will attempt search the directory block for
++ * space.  It will return -ENOSPC if no space is available, and -EIO
++ * and -EEXIST if directory entry already exists.
++ * 
++ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
++ * all other cases bh is released.
++ */
++static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode, struct ext3_dir_entry_2 *de,
++			     struct buffer_head * bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	unsigned long	offset = 0;
++	unsigned short	reclen;
++	int		nlen, rlen, err;
++	char		*top;
++	
++	reclen = EXT3_DIR_REC_LEN(namelen);
++	if (!de) {
++		de = (struct ext3_dir_entry_2 *)bh->b_data;
++		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
++		while ((char *) de <= top) {
++			if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
++						  bh, offset)) {
++				brelse (bh);
++				return -EIO;
++			}
++			if (ext3_match (namelen, name, de)) {
++				brelse (bh);
++				return -EEXIST;
++			}
++			nlen = EXT3_DIR_REC_LEN(de->name_len);
++			rlen = le16_to_cpu(de->rec_len);
++			if ((de->inode? rlen - nlen: rlen) >= reclen)
++				break;
++			de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
++			offset += rlen;
++		}
++		if ((char *) de > top)
++			return -ENOSPC;
++	}
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err) {
++		ext3_std_error(dir->i_sb, err);
++		brelse(bh);
++		return err;
++	}
++	
++	/* By now the buffer is marked for journaling */
++	nlen = EXT3_DIR_REC_LEN(de->name_len);
++	rlen = le16_to_cpu(de->rec_len);
++	if (de->inode) {
++		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		de1->rec_len = cpu_to_le16(rlen - nlen);
++		de->rec_len = cpu_to_le16(nlen);
++		de = de1;
++	}
++	de->file_type = EXT3_FT_UNKNOWN;
++	if (inode) {
++		de->inode = cpu_to_le32(inode->i_ino);
++		ext3_set_de_type(dir->i_sb, de, inode->i_mode);
++	} else
++		de->inode = 0;
++	de->name_len = namelen;
++	memcpy (de->name, name, namelen);
++	/*
++	 * XXX shouldn't update any times until successful
++	 * completion of syscall, but too many callers depend
++	 * on this.
++	 *
++	 * XXX similarly, too many callers depend on
++	 * ext3_new_inode() setting the times, but error
++	 * recovery deletes the inode, so the worst that can
++	 * happen is that the times are slightly out of date
++	 * and/or different from the directory change time.
++	 */
++	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
++	ext3_update_dx_flag(dir);
++	dir->i_version = ++event;
++	ext3_mark_inode_dirty(handle, dir);
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		ext3_std_error(dir->i_sb, err);
++	brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * This converts a one block unindexed directory to a 3 block indexed
++ * directory, and adds the dentry to the indexed directory.
++ */
++static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
++			    struct inode *inode, struct buffer_head *bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	struct buffer_head *bh2;
++	struct dx_root	*root;
++	struct dx_frame	frames[2], *frame;
++	struct dx_entry *entries;
++	struct ext3_dir_entry_2	*de, *de2;
++	char		*data1, *top;
++	unsigned	len;
++	int		retval;
++	unsigned	blocksize;
++	struct dx_hash_info hinfo;
++	u32		block;
++		
++	blocksize =  dir->i_sb->s_blocksize;
++	dxtrace(printk("Creating index\n"));
++	retval = ext3_journal_get_write_access(handle, bh);
++	if (retval) {
++		ext3_std_error(dir->i_sb, retval);
++		brelse(bh);
++		return retval;
++	}
++	root = (struct dx_root *) bh->b_data;
++		
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	bh2 = ext3_append (handle, dir, &block, &retval);
++	if (!(bh2)) {
++		brelse(bh);
++		return retval;
++	}
++	data1 = bh2->b_data;
++
++	/* The 0th block becomes the root, move the dirents out */
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
++	len = ((char *) root) + blocksize - (char *) de;
++	memcpy (data1, de, len);
++	de = (struct ext3_dir_entry_2 *) data1;
++	top = data1 + len;
++	while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
++		de = de2;
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	/* Initialize the root; the dot dirents already exist */
++	de = (struct ext3_dir_entry_2 *) (&root->dotdot);
++	de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++	memset (&root->info, 0, sizeof(root->info));
++	root->info.info_length = sizeof(root->info);
++	root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
++	entries = root->entries;
++	dx_set_block (entries, 1);
++	dx_set_count (entries, 1);
++	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
++
++	/* Initialize as for dx_probe */
++	hinfo.hash_version = root->info.hash_version;
++	hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	ext3fs_dirhash(name, namelen, &hinfo);
++	frame = frames;
++	frame->entries = entries;
++	frame->at = entries;
++	frame->bh = bh;
++	bh = bh2;
++	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	dx_release (frames);
++	if (!(de))
++		return retval;
++
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
++#endif
++
+ /*
+  *	ext3_add_entry()
+  *
+@@ -247,127 +1268,198 @@
+  * may not sleep between calling this and putting something into
+  * the entry, as someone else might have used it while you slept.
+  */
+-
+-/*
+- * AKPM: the journalling code here looks wrong on the error paths
+- */
+ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+ 	struct inode *inode)
+ {
+ 	struct inode *dir = dentry->d_parent->d_inode;
+-	const char *name = dentry->d_name.name;
+-	int namelen = dentry->d_name.len;
+ 	unsigned long offset;
+-	unsigned short rec_len;
+ 	struct buffer_head * bh;
+-	struct ext3_dir_entry_2 * de, * de1;
++	struct ext3_dir_entry_2 *de;
+ 	struct super_block * sb;
+ 	int	retval;
++#ifdef CONFIG_EXT3_INDEX
++	int	dx_fallback=0;
++#endif
++	unsigned blocksize;
++	unsigned nlen, rlen;
++	u32 block, blocks;
+ 
+ 	sb = dir->i_sb;
+-
+-	if (!namelen)
++	blocksize = sb->s_blocksize;
++	if (!dentry->d_name.len)
+ 		return -EINVAL;
+-	bh = ext3_bread (handle, dir, 0, 0, &retval);
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		retval = ext3_dx_add_entry(handle, dentry, inode);
++		if (!retval || (retval != ERR_BAD_DX_DIR))
++			return retval;
++		EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
++		dx_fallback++;
++		ext3_mark_inode_dirty(handle, dir);
++	}
++#endif
++	blocks = dir->i_size >> sb->s_blocksize_bits;
++	for (block = 0, offset = 0; block < blocks; block++) {
++		bh = ext3_bread(handle, dir, block, 0, &retval);
++		if(!bh)
++			return retval;
++		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++		if (retval != -ENOSPC)
++			return retval;
++
++#ifdef CONFIG_EXT3_INDEX
++		if (blocks == 1 && !dx_fallback &&
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
++			return make_indexed_dir(handle, dentry, inode, bh);
++#endif
++		brelse(bh);
++	}
++	bh = ext3_append(handle, dir, &block, &retval);
+ 	if (!bh)
+ 		return retval;
+-	rec_len = EXT3_DIR_REC_LEN(namelen);
+-	offset = 0;
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+-	while (1) {
+-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+-			brelse (bh);
+-			bh = NULL;
+-			bh = ext3_bread (handle, dir,
+-				offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
+-			if (!bh)
+-				return retval;
+-			if (dir->i_size <= offset) {
+-				if (dir->i_size == 0) {
+-					brelse(bh);
+-					return -ENOENT;
+-				}
++	de->inode = 0;
++	de->rec_len = cpu_to_le16(rlen = blocksize);
++	nlen = 0;
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
+ 
+-				ext3_debug ("creating next block\n");
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * Returns 0 for success, or a negative error value
++ */
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode)
++{
++	struct dx_frame frames[2], *frame;
++	struct dx_entry *entries, *at;
++	struct dx_hash_info hinfo;
++	struct buffer_head * bh;
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block * sb = dir->i_sb;
++	struct ext3_dir_entry_2 *de;
++	int err;
+ 
+-				BUFFER_TRACE(bh, "get_write_access");
+-				ext3_journal_get_write_access(handle, bh);
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-				de->inode = 0;
+-				de->rec_len = le16_to_cpu(sb->s_blocksize);
+-				dir->u.ext3_i.i_disksize =
+-					dir->i_size = offset + sb->s_blocksize;
+-				dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-				ext3_mark_inode_dirty(handle, dir);
+-			} else {
++	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++	entries = frame->entries;
++	at = frame->at;
+ 
+-				ext3_debug ("skipping to next block\n");
++	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++		goto cleanup;
+ 
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-			}
+-		}
+-		if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
+-					   offset)) {
+-			brelse (bh);
+-			return -ENOENT;
+-		}
+-		if (ext3_match (namelen, name, de)) {
+-				brelse (bh);
+-				return -EEXIST;
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err)
++		goto journal_error;
++
++	err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++	if (err != -ENOSPC) {
++		bh = 0;
++		goto cleanup;
++	}
++
++	/* Block full, should compress but for now just split */
++	dxtrace(printk("using %u of %u node entries\n",
++		       dx_get_count(entries), dx_get_limit(entries)));
++	/* Need to split index? */
++	if (dx_get_count(entries) == dx_get_limit(entries)) {
++		u32 newblock;
++		unsigned icount = dx_get_count(entries);
++		int levels = frame - frames;
++		struct dx_entry *entries2;
++		struct dx_node *node2;
++		struct buffer_head *bh2;
++
++		if (levels && (dx_get_count(frames->entries) ==
++			       dx_get_limit(frames->entries))) {
++			ext3_warning(sb, __FUNCTION__,
++				     "Directory index full!\n");
++			err = -ENOSPC;
++			goto cleanup;
+ 		}
+-		if ((le32_to_cpu(de->inode) == 0 &&
+-				le16_to_cpu(de->rec_len) >= rec_len) ||
+-		    (le16_to_cpu(de->rec_len) >=
+-				EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
+-			BUFFER_TRACE(bh, "get_write_access");
+-			ext3_journal_get_write_access(handle, bh);
+-			/* By now the buffer is marked for journaling */
+-			offset += le16_to_cpu(de->rec_len);
+-			if (le32_to_cpu(de->inode)) {
+-				de1 = (struct ext3_dir_entry_2 *) ((char *) de +
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de1->rec_len =
+-					cpu_to_le16(le16_to_cpu(de->rec_len) -
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de->rec_len = cpu_to_le16(
+-						EXT3_DIR_REC_LEN(de->name_len));
+-				de = de1;
++		bh2 = ext3_append (handle, dir, &newblock, &err);
++		if (!(bh2))
++			goto cleanup;
++		node2 = (struct dx_node *)(bh2->b_data);
++		entries2 = node2->entries;
++		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
++		node2->fake.inode = 0;
++		BUFFER_TRACE(frame->bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, frame->bh);
++		if (err)
++			goto journal_error;
++		if (levels) {
++			unsigned icount1 = icount/2, icount2 = icount - icount1;
++			unsigned hash2 = dx_get_hash(entries + icount1);
++			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
++				
++			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++			err = ext3_journal_get_write_access(handle,
++							     frames[0].bh);
++			if (err)
++				goto journal_error;
++				
++			memcpy ((char *) entries2, (char *) (entries + icount1),
++				icount2 * sizeof(struct dx_entry));
++			dx_set_count (entries, icount1);
++			dx_set_count (entries2, icount2);
++			dx_set_limit (entries2, dx_node_limit(dir));
++
++			/* Which index block gets the new entry? */
++			if (at - entries >= icount1) {
++				frame->at = at = at - entries - icount1 + entries2;
++				frame->entries = entries = entries2;
++				swap(frame->bh, bh2);
+ 			}
+-			de->file_type = EXT3_FT_UNKNOWN;
+-			if (inode) {
+-				de->inode = cpu_to_le32(inode->i_ino);
+-				ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-			} else
+-				de->inode = 0;
+-			de->name_len = namelen;
+-			memcpy (de->name, name, namelen);
+-			/*
+-			 * XXX shouldn't update any times until successful
+-			 * completion of syscall, but too many callers depend
+-			 * on this.
+-			 *
+-			 * XXX similarly, too many callers depend on
+-			 * ext3_new_inode() setting the times, but error
+-			 * recovery deletes the inode, so the worst that can
+-			 * happen is that the times are slightly out of date
+-			 * and/or different from the directory change time.
+-			 */
+-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+-			dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-			dir->i_version = ++event;
+-			ext3_mark_inode_dirty(handle, dir);
+-			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-			ext3_journal_dirty_metadata(handle, bh);
+-			brelse(bh);
+-			return 0;
++			dx_insert_block (frames + 0, hash2, newblock);
++			dxtrace(dx_show_index ("node", frames[1].entries));
++			dxtrace(dx_show_index ("node",
++			       ((struct dx_node *) bh2->b_data)->entries));
++			err = ext3_journal_dirty_metadata(handle, bh2);
++			if (err)
++				goto journal_error;
++			brelse (bh2);
++		} else {
++			dxtrace(printk("Creating second level index...\n"));
++			memcpy((char *) entries2, (char *) entries,
++			       icount * sizeof(struct dx_entry));
++			dx_set_limit(entries2, dx_node_limit(dir));
++
++			/* Set up root */
++			dx_set_count(entries, 1);
++			dx_set_block(entries + 0, newblock);
++			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++
++			/* Add new access path frame */
++			frame = frames + 1;
++			frame->at = at = at - entries + entries2;
++			frame->entries = entries = entries2;
++			frame->bh = bh2;
++			err = ext3_journal_get_write_access(handle,
++							     frame->bh);
++			if (err)
++				goto journal_error;
+ 		}
+-		offset += le16_to_cpu(de->rec_len);
+-		de = (struct ext3_dir_entry_2 *)
+-			((char *) de + le16_to_cpu(de->rec_len));
++		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	brelse (bh);
+-	return -ENOSPC;
++	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	if (!de)
++		goto cleanup;
++	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	bh = 0;
++	goto cleanup;
++	
++journal_error:
++	ext3_std_error(dir->i_sb, err);
++cleanup:
++	if (bh)
++		brelse(bh);
++	dx_release(frames);
++	return err;
+ }
++#endif
+ 
+ /*
+  * ext3_delete_entry deletes a directory entry by merging it with the
+@@ -454,9 +1546,11 @@
+ 	struct inode * inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -480,9 +1574,11 @@
+ 	struct inode *inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -508,9 +1604,11 @@
+ 	if (dir->i_nlink >= EXT3_LINK_MAX)
+ 		return -EMLINK;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -522,7 +1620,7 @@
+ 
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+-	inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
++	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+ 	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+@@ -555,21 +1653,19 @@
+ 		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+-	if (err)
+-		goto out_no_entry;
++	if (err) {
++		inode->i_nlink = 0;
++		ext3_mark_inode_dirty(handle, inode);
++		iput (inode);
++		goto out_stop;
++	}
+ 	dir->i_nlink++;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	d_instantiate(dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	inode->i_nlink = 0;
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ /*
+@@ -656,7 +1752,7 @@
+ 	int err = 0, rc;
+ 	
+ 	lock_super(sb);
+-	if (!list_empty(&inode->u.ext3_i.i_orphan))
++	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+ 	/* Orphan handling is only valid for files with data blocks
+@@ -697,7 +1793,7 @@
+ 	 * This is safe: on error we're going to ignore the orphan list
+ 	 * anyway on the next recovery. */
+ 	if (!err)
+-		list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
++		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
+ 
+ 	jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+@@ -794,8 +1890,9 @@
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	retval = -ENOENT;
+ 	bh = ext3_find_entry (dentry, &de);
+@@ -833,7 +1930,7 @@
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+ end_rmdir:
+@@ -851,8 +1948,9 @@
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -879,7 +1977,7 @@
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	inode->i_nlink--;
+ 	if (!inode->i_nlink)
+@@ -905,9 +2003,11 @@
+ 	if (l > dir->i_sb->s_blocksize)
+ 		return -ENAMETOOLONG;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -917,7 +2017,7 @@
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+ 
+-	if (l > sizeof (inode->u.ext3_i.i_data)) {
++	if (l > sizeof (EXT3_I(inode)->i_data)) {
+ 		inode->i_op = &page_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+@@ -926,8 +2026,12 @@
+ 		 * i_size in generic_commit_write().
+ 		 */
+ 		err = block_symlink(inode, symname, l);
+-		if (err)
+-			goto out_no_entry;
++		if (err) {
++			ext3_dec_count(handle, inode);
++			ext3_mark_inode_dirty(handle, inode);
++			iput (inode);
++			goto out_stop;
++		}
+ 	} else {
+ 		inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
+@@ -938,12 +2042,6 @@
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	ext3_dec_count(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ static int ext3_link (struct dentry * old_dentry,
+@@ -956,12 +2054,15 @@
+ 	if (S_ISDIR(inode->i_mode))
+ 		return -EPERM;
+ 
+-	if (inode->i_nlink >= EXT3_LINK_MAX)
++	if (inode->i_nlink >= EXT3_LINK_MAX) {
+ 		return -EMLINK;
++	}
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -994,9 +2095,11 @@
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+@@ -1069,14 +2172,33 @@
+ 	/*
+ 	 * ok, that's it
+ 	 */
+-	ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	retval = ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	if (retval == -ENOENT) {
++		/*
++		 * old_de could have moved out from under us.
++		 */
++		struct buffer_head *old_bh2;
++		struct ext3_dir_entry_2 *old_de2;
++		
++		old_bh2 = ext3_find_entry(old_dentry, &old_de2);
++		if (old_bh2) {
++			retval = ext3_delete_entry(handle, old_dir,
++						   old_de2, old_bh2);
++			brelse(old_bh2);
++		}
++	}
++	if (retval) {
++		ext3_warning(old_dir->i_sb, "ext3_rename",
++				"Deleting old file (%lu), %d, error=%d",
++				old_dir->i_ino, old_dir->i_nlink, retval);
++	}
+ 
+ 	if (new_inode) {
+ 		new_inode->i_nlink--;
+ 		new_inode->i_ctime = CURRENT_TIME;
+ 	}
+ 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+-	old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(old_dir);
+ 	if (dir_bh) {
+ 		BUFFER_TRACE(dir_bh, "get_write_access");
+ 		ext3_journal_get_write_access(handle, dir_bh);
+@@ -1088,7 +2210,7 @@
+ 			new_inode->i_nlink--;
+ 		} else {
+ 			new_dir->i_nlink++;
+-			new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++			ext3_update_dx_flag(new_dir);
+ 			ext3_mark_inode_dirty(handle, new_dir);
+ 		}
+ 	}
+Index: linux-2.4.21-suse/fs/ext3/super.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/super.c	2003-10-29 22:39:14.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/super.c	2003-10-29 23:17:20.000000000 +0300
+@@ -710,6 +710,7 @@
+ 	es->s_mtime = cpu_to_le32(CURRENT_TIME);
+ 	ext3_update_dynamic_rev(sb);
+ 	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
++
+ 	ext3_commit_super (sb, es, 1);
+ 	if (test_opt (sb, DEBUG))
+ 		printk (KERN_INFO
+@@ -720,6 +721,7 @@
+ 			EXT3_BLOCKS_PER_GROUP(sb),
+ 			EXT3_INODES_PER_GROUP(sb),
+ 			sbi->s_mount_opt);
++
+ 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
+ 				bdevname(sb->s_dev));
+ 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+@@ -893,6 +895,7 @@
+ 	return res;
+ }
+ 
++
+ struct super_block * ext3_read_super (struct super_block * sb, void * data,
+ 				      int silent)
+ {
+@@ -1069,6 +1072,9 @@
+ 	sbi->s_mount_state = le16_to_cpu(es->s_state);
+ 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+ 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++	for (i=0; i < 4; i++)
++		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
++	sbi->s_def_hash_version = es->s_def_hash_version;
+ 
+ 	if (sbi->s_blocks_per_group > blocksize * 8) {
+ 		printk (KERN_ERR
+@@ -1770,6 +1776,7 @@
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
++EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+Index: linux-2.4.21-suse/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs.h	2003-06-14 02:28:25.000000000 +0400
++++ linux-2.4.21-suse/include/linux/ext3_fs.h	2003-10-29 23:17:20.000000000 +0300
+@@ -40,6 +40,11 @@
+ #define EXT3FS_VERSION		"2.4-0.9.19"
+ 
+ /*
++ * Always enable hashed directories
++ */
++#define CONFIG_EXT3_INDEX
++
++/*
+  * Debug code
+  */
+ #ifdef EXT3FS_DEBUG
+@@ -438,8 +443,11 @@
+ /*E0*/	__u32	s_journal_inum;		/* inode number of journal file */
+ 	__u32	s_journal_dev;		/* device number of journal file */
+ 	__u32	s_last_orphan;		/* start of list of inodes to delete */
+-
+-/*EC*/	__u32	s_reserved[197];	/* Padding to the end of the block */
++	__u32	s_hash_seed[4];		/* HTREE hash seed */
++	__u8	s_def_hash_version;	/* Default hash version to use */
++	__u8	s_reserved_char_pad;
++	__u16	s_reserved_word_pad;
++	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+ #ifdef __KERNEL__
+@@ -576,9 +584,46 @@
+ #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
+ 					 ~EXT3_DIR_ROUND)
++/*
++ * Hash Tree Directory indexing
++ * (c) Daniel Phillips, 2001
++ */
++
++#ifdef CONFIG_EXT3_INDEX
++  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++					      EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++		      (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
++#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#else
++  #define is_dx(dir) 0
++#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
++#endif
++
++/* Legal values for the dx_root hash_version field: */
++
++#define DX_HASH_LEGACY		0
++#define DX_HASH_HALF_MD4	1
++#define DX_HASH_TEA		2
++
++/* hash info structure used by the directory hash */
++struct dx_hash_info
++{
++	u32		hash;
++	u32		minor_hash;
++	int		hash_version;
++	u32		*seed;
++};
+ 
+ #ifdef __KERNEL__
+ /*
++ * Control parameters used by ext3_htree_next_block
++ */
++#define HASH_NB_ALWAYS		1
++
++
++/*
+  * Describe an inode's exact location on disk and in memory
+  */
+ struct ext3_iloc
+@@ -588,6 +633,27 @@
+ 	unsigned long block_group;
+ };
+ 
++
++/*
++ * This structure is stuffed into the struct file's private_data field
++ * for directories.  It is where we put information so that we can do
++ * readdir operations in hash tree order.
++ */
++struct dir_private_info {
++	rb_root_t	root;
++	rb_node_t	*curr_node;
++	struct fname	*extra_fname;
++	loff_t		last_pos;
++	__u32		curr_hash;
++	__u32		curr_minor_hash;
++	__u32		next_hash;
++};
++
++/*
++ * Special error return code only used by dx_probe() and its callers.
++ */
++#define ERR_BAD_DX_DIR	-75000
++
+ /*
+  * Function prototypes
+  */
+@@ -615,11 +681,20 @@
+ 
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
+-				struct ext3_dir_entry_2 *, struct buffer_head *,
+-				unsigned long);
++				struct ext3_dir_entry_2 *,
++				struct buffer_head *, unsigned long);
++extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++				    __u32 minor_hash,
++				    struct ext3_dir_entry_2 *dirent);
++extern void ext3_htree_free_dir_info(struct dir_private_info *p);
++
+ /* fsync.c */
+ extern int ext3_sync_file (struct file *, struct dentry *, int);
+ 
++/* hash.c */
++extern int ext3fs_dirhash(const char *name, int len, struct
++			  dx_hash_info *hinfo);
++
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+@@ -652,6 +727,8 @@
+ /* namei.c */
+ extern int ext3_orphan_add(handle_t *, struct inode *);
+ extern int ext3_orphan_del(handle_t *, struct inode *);
++extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++				__u32 start_minor_hash, __u32 *next_hash);
+ 
+ /* super.c */
+ extern void ext3_error (struct super_block *, const char *, const char *, ...)
+Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h	2003-06-14 02:26:52.000000000 +0400
++++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h	2003-10-29 23:17:20.000000000 +0300
+@@ -62,6 +62,8 @@
+ 	int s_inode_size;
+ 	int s_first_ino;
+ 	u32 s_next_generation;
++	u32 s_hash_seed[4];
++	int s_def_hash_version;
+ 
+ 	/* Journaling */
+ 	struct inode * s_journal_inode;
+Index: linux-2.4.21-suse/include/linux/ext3_jbd.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_jbd.h	2003-06-14 02:28:25.000000000 +0400
++++ linux-2.4.21-suse/include/linux/ext3_jbd.h	2003-10-29 23:17:20.000000000 +0300
+@@ -63,6 +63,8 @@
+ 
+ #define EXT3_RESERVE_TRANS_BLOCKS	12U
+ 
++#define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
++
+ int
+ ext3_mark_iloc_dirty(handle_t *handle, 
+ 		     struct inode *inode,
+Index: linux-2.4.21-suse/include/linux/rbtree.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/rbtree.h	2003-06-14 02:26:51.000000000 +0400
++++ linux-2.4.21-suse/include/linux/rbtree.h	2003-10-29 23:17:20.000000000 +0300
+@@ -120,6 +120,8 @@
+ 
+ extern void rb_insert_color(rb_node_t *, rb_root_t *);
+ extern void rb_erase(rb_node_t *, rb_root_t *);
++extern rb_node_t *rb_get_first(rb_root_t *root);
++extern rb_node_t *rb_get_next(rb_node_t *n);
+ 
+ static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+ {
+Index: linux-2.4.21-suse/lib/rbtree.c
+===================================================================
+--- linux-2.4.21-suse.orig/lib/rbtree.c	2002-08-03 04:39:46.000000000 +0400
++++ linux-2.4.21-suse/lib/rbtree.c	2003-10-29 23:17:20.000000000 +0300
+@@ -17,6 +17,8 @@
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+   linux/lib/rbtree.c
++
++  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+ */
+ 
+ #include <linux/rbtree.h>
+@@ -294,3 +296,43 @@
+ 		__rb_erase_color(child, parent, root);
+ }
+ EXPORT_SYMBOL(rb_erase);
++
++/*
++ * This function returns the first node (in sort order) of the tree.
++ */
++rb_node_t *rb_get_first(rb_root_t *root)
++{
++	rb_node_t	*n;
++
++	n = root->rb_node;
++	if (!n)
++		return 0;
++	while (n->rb_left)
++		n = n->rb_left;
++	return n;
++}
++EXPORT_SYMBOL(rb_get_first);
++
++/*
++ * Given a node, this function will return the next node in the tree.
++ */
++rb_node_t *rb_get_next(rb_node_t *n)
++{
++	rb_node_t	*parent;
++
++	if (n->rb_right) {
++		n = n->rb_right;
++		while (n->rb_left)
++			n = n->rb_left;
++		return n;
++	} else {
++		while ((parent = n->rb_parent)) {
++			if (n == parent->rb_left)
++				return parent;
++			n = parent;
++		}
++		return 0;
++	}
++}
++EXPORT_SYMBOL(rb_get_next);
++
diff --git a/lustre/kernel_patches/patches/ext3-htree.patch b/lustre/kernel_patches/patches/ext3-htree.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1c1c1ad2a4db7da260df9f2f6c64dd324c08c197
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-htree.patch
@@ -0,0 +1,2570 @@
+ fs/ext3/Makefile           |    2 
+ fs/ext3/dir.c              |  302 +++++++++
+ fs/ext3/file.c             |    3 
+ fs/ext3/hash.c             |  215 ++++++
+ fs/ext3/namei.c            | 1420 ++++++++++++++++++++++++++++++++++++++++-----
+ fs/ext3/super.c            |    7 
+ include/linux/ext3_fs.h    |   85 ++
+ include/linux/ext3_fs_sb.h |    2 
+ include/linux/ext3_jbd.h   |    2 
+ include/linux/rbtree.h     |    2 
+ lib/rbtree.c               |   42 +
+ 11 files changed, 1921 insertions(+), 161 deletions(-)
+
+--- linux-2.4.18-chaos-pdirops/fs/ext3/dir.c~ext3-htree	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/dir.c	2003-09-23 12:12:04.000000000 +0400
+@@ -21,12 +21,16 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/slab.h>
++#include <linux/rbtree.h>
+ 
+ static unsigned char ext3_filetype_table[] = {
+ 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+ };
+ 
+ static int ext3_readdir(struct file *, void *, filldir_t);
++static int ext3_dx_readdir(struct file * filp,
++			   void * dirent, filldir_t filldir);
+ 
+ struct file_operations ext3_dir_operations = {
+ 	read:		generic_read_dir,
+@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio
+ 	fsync:		ext3_sync_file,		/* BKL held */
+ };
+ 
++
++static unsigned char get_dtype(struct super_block *sb, int filetype)
++{
++	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
++	    (filetype >= EXT3_FT_MAX))
++		return DT_UNKNOWN;
++
++	return (ext3_filetype_table[filetype]);
++}
++			       
++
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ 			  struct ext3_dir_entry_2 * de,
+ 			  struct buffer_head * bh,
+@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi
+ 
+ 	sb = inode->i_sb;
+ 
++	if (is_dx(inode)) {
++		err = ext3_dx_readdir(filp, dirent, filldir);
++		if (err != ERR_BAD_DX_DIR)
++			return err;
++		/*
++		 * We don't set the inode dirty flag since it's not
++		 * critical that it get flushed back to the disk.
++		 */
++		EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
++	}
+ 	stored = 0;
+ 	bh = NULL;
+ 	offset = filp->f_pos & (sb->s_blocksize - 1);
+@@ -162,18 +187,12 @@ revalidate:
+ 				 * during the copy operation.
+ 				 */
+ 				unsigned long version = filp->f_version;
+-				unsigned char d_type = DT_UNKNOWN;
+ 
+-				if (EXT3_HAS_INCOMPAT_FEATURE(sb,
+-						EXT3_FEATURE_INCOMPAT_FILETYPE)
+-						&& de->file_type < EXT3_FT_MAX)
+-					d_type =
+-					  ext3_filetype_table[de->file_type];
+ 				error = filldir(dirent, de->name,
+ 						de->name_len,
+ 						filp->f_pos,
+ 						le32_to_cpu(de->inode),
+-						d_type);
++						get_dtype(sb, de->file_type));
+ 				if (error)
+ 					break;
+ 				if (version != filp->f_version)
+@@ -188,3 +207,272 @@ revalidate:
+ 	UPDATE_ATIME(inode);
+ 	return 0;
+ }
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * These functions convert from the major/minor hash to an f_pos
++ * value.
++ * 
++ * Currently we only use major hash numer.  This is unfortunate, but
++ * on 32-bit machines, the same VFS interface is used for lseek and
++ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
++ * lseek/telldir/seekdir will blow out spectacularly, and from within
++ * the ext2 low-level routine, we don't know if we're being called by
++ * a 64-bit version of the system call or the 32-bit version of the
++ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
++ * cookie.  Sigh.
++ */
++#define hash2pos(major, minor)	(major >> 1)
++#define pos2maj_hash(pos)	((pos << 1) & 0xffffffff)
++#define pos2min_hash(pos)	(0)
++
++/*
++ * This structure holds the nodes of the red-black tree used to store
++ * the directory entry in hash order.
++ */
++struct fname {
++	__u32		hash;
++	__u32		minor_hash;
++	rb_node_t	rb_hash; 
++	struct fname	*next;
++	__u32		inode;
++	__u8		name_len;
++	__u8		file_type;
++	char		name[0];
++};
++
++/*
++ * This functoin implements a non-recursive way of freeing all of the
++ * nodes in the red-black tree.
++ */
++static void free_rb_tree_fname(rb_root_t *root)
++{
++	rb_node_t	*n = root->rb_node;
++	rb_node_t	*parent;
++	struct fname	*fname;
++
++	while (n) {
++		/* Do the node's children first */
++		if ((n)->rb_left) {
++			n = n->rb_left;
++			continue;
++		}
++		if (n->rb_right) {
++			n = n->rb_right;
++			continue;
++		}
++		/*
++		 * The node has no children; free it, and then zero
++		 * out parent's link to it.  Finally go to the
++		 * beginning of the loop and try to free the parent
++		 * node.
++		 */
++		parent = n->rb_parent;
++		fname = rb_entry(n, struct fname, rb_hash);
++		kfree(fname);
++		if (!parent)
++			root->rb_node = 0;
++		else if (parent->rb_left == n)
++			parent->rb_left = 0;
++		else if (parent->rb_right == n)
++			parent->rb_right = 0;
++		n = parent;
++	}
++	root->rb_node = 0;
++}
++
++
++struct dir_private_info *create_dir_info(loff_t pos)
++{
++	struct dir_private_info *p;
++
++	p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
++	if (!p)
++		return NULL;
++	p->root.rb_node = 0;
++	p->curr_node = 0;
++	p->extra_fname = 0;
++	p->last_pos = 0;
++	p->curr_hash = pos2maj_hash(pos);
++	p->curr_minor_hash = pos2min_hash(pos);
++	p->next_hash = 0;
++	return p;
++}
++
++void ext3_htree_free_dir_info(struct dir_private_info *p)
++{
++	free_rb_tree_fname(&p->root);
++	kfree(p);
++}
++		
++/*
++ * Given a directory entry, enter it into the fname rb tree.
++ */
++int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++			     __u32 minor_hash,
++			     struct ext3_dir_entry_2 *dirent)
++{
++	rb_node_t **p, *parent = NULL;
++	struct fname * fname, *new_fn;
++	struct dir_private_info *info;
++	int len;
++
++	info = (struct dir_private_info *) dir_file->private_data;
++	p = &info->root.rb_node;
++
++	/* Create and allocate the fname structure */
++	len = sizeof(struct fname) + dirent->name_len + 1;
++	new_fn = kmalloc(len, GFP_KERNEL);
++	if (!new_fn)
++		return -ENOMEM;
++	memset(new_fn, 0, len);
++	new_fn->hash = hash;
++	new_fn->minor_hash = minor_hash;
++	new_fn->inode = le32_to_cpu(dirent->inode);
++	new_fn->name_len = dirent->name_len;
++	new_fn->file_type = dirent->file_type;
++	memcpy(new_fn->name, dirent->name, dirent->name_len);
++	new_fn->name[dirent->name_len] = 0;
++	
++	while (*p) {
++		parent = *p;
++		fname = rb_entry(parent, struct fname, rb_hash);
++
++		/*
++		 * If the hash and minor hash match up, then we put
++		 * them on a linked list.  This rarely happens...
++		 */
++		if ((new_fn->hash == fname->hash) &&
++		    (new_fn->minor_hash == fname->minor_hash)) {
++			new_fn->next = fname->next;
++			fname->next = new_fn;
++			return 0;
++		}
++			
++		if (new_fn->hash < fname->hash)
++			p = &(*p)->rb_left;
++		else if (new_fn->hash > fname->hash)
++			p = &(*p)->rb_right;
++		else if (new_fn->minor_hash < fname->minor_hash)
++			p = &(*p)->rb_left;
++		else /* if (new_fn->minor_hash > fname->minor_hash) */
++			p = &(*p)->rb_right;
++	}
++
++	rb_link_node(&new_fn->rb_hash, parent, p);
++	rb_insert_color(&new_fn->rb_hash, &info->root);
++	return 0;
++}
++
++
++
++/*
++ * This is a helper function for ext3_dx_readdir.  It calls filldir
++ * for all entres on the fname linked list.  (Normally there is only
++ * one entry on the linked list, unless there are 62 bit hash collisions.)
++ */
++static int call_filldir(struct file * filp, void * dirent,
++			filldir_t filldir, struct fname *fname)
++{
++	struct dir_private_info *info = filp->private_data;
++	loff_t	curr_pos;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct super_block * sb;
++	int error;
++
++	sb = inode->i_sb;
++	
++	if (!fname) {
++		printk("call_filldir: called with null fname?!?\n");
++		return 0;
++	}
++	curr_pos = hash2pos(fname->hash, fname->minor_hash);
++	while (fname) {
++		error = filldir(dirent, fname->name,
++				fname->name_len, curr_pos, 
++				fname->inode,
++				get_dtype(sb, fname->file_type));
++		if (error) {
++			filp->f_pos = curr_pos;
++			info->extra_fname = fname->next;
++			return error;
++		}
++		fname = fname->next;
++	}
++	return 0;
++}
++
++static int ext3_dx_readdir(struct file * filp,
++			 void * dirent, filldir_t filldir)
++{
++	struct dir_private_info *info = filp->private_data;
++	struct inode *inode = filp->f_dentry->d_inode;
++	struct fname *fname;
++	int	ret;
++
++	if (!info) {
++		info = create_dir_info(filp->f_pos);
++		if (!info)
++			return -ENOMEM;
++		filp->private_data = info;
++	}
++
++	/* Some one has messed with f_pos; reset the world */
++	if (info->last_pos != filp->f_pos) {
++		free_rb_tree_fname(&info->root);
++		info->curr_node = 0;
++		info->extra_fname = 0;
++		info->curr_hash = pos2maj_hash(filp->f_pos);
++		info->curr_minor_hash = pos2min_hash(filp->f_pos);
++	}
++
++	/*
++	 * If there are any leftover names on the hash collision
++	 * chain, return them first.
++	 */
++	if (info->extra_fname &&
++	    call_filldir(filp, dirent, filldir, info->extra_fname))
++		goto finished;
++
++	if (!info->curr_node)
++		info->curr_node = rb_get_first(&info->root);
++
++	while (1) {
++		/*
++		 * Fill the rbtree if we have no more entries,
++		 * or the inode has changed since we last read in the
++		 * cached entries. 
++		 */
++		if ((!info->curr_node) ||
++		    (filp->f_version != inode->i_version)) {
++			info->curr_node = 0;
++			free_rb_tree_fname(&info->root);
++			filp->f_version = inode->i_version;
++			ret = ext3_htree_fill_tree(filp, info->curr_hash,
++						   info->curr_minor_hash,
++						   &info->next_hash);
++			if (ret < 0)
++				return ret;
++			if (ret == 0)
++				break;
++			info->curr_node = rb_get_first(&info->root);
++		}
++
++		fname = rb_entry(info->curr_node, struct fname, rb_hash);
++		info->curr_hash = fname->hash;
++		info->curr_minor_hash = fname->minor_hash;
++		if (call_filldir(filp, dirent, filldir, fname))
++			break;
++
++		info->curr_node = rb_get_next(info->curr_node);
++		if (!info->curr_node) {
++			info->curr_hash = info->next_hash;
++			info->curr_minor_hash = 0;
++		}
++	}
++finished:
++	info->last_pos = filp->f_pos;
++	UPDATE_ATIME(inode);
++	return 0;
++}
++#endif
+--- linux-2.4.18-chaos-pdirops/fs/ext3/file.c~ext3-htree	2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/file.c	2003-09-23 12:11:54.000000000 +0400
+@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino
+ {
+ 	if (filp->f_mode & FMODE_WRITE)
+ 		ext3_discard_prealloc (inode);
++	if (is_dx(inode) && filp->private_data)
++		ext3_htree_free_dir_info(filp->private_data);
++
+ 	return 0;
+ }
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/hash.c	2003-09-23 12:11:54.000000000 +0400
+@@ -0,0 +1,215 @@
++/*
++ *  linux/fs/ext3/hash.c
++ *
++ * Copyright (C) 2002 by Theodore Ts'o
++ *
++ * This file is released under the GPL v2.
++ * 
++ * This file may be redistributed under the terms of the GNU Public
++ * License.
++ */
++
++#include <linux/fs.h>
++#include <linux/jbd.h>
++#include <linux/sched.h>
++#include <linux/ext3_fs.h>
++
++#define DELTA 0x9E3779B9
++
++static void TEA_transform(__u32 buf[4], __u32 const in[])
++{
++	__u32	sum = 0;
++	__u32	b0 = buf[0], b1 = buf[1];
++	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
++	int	n = 16;
++
++	do {							
++		sum += DELTA;					
++		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
++		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
++	} while(--n);
++
++	buf[0] += b0;
++	buf[1] += b1;
++}
++
++/* F, G and H are basic MD4 functions: selection, majority, parity */
++#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
++#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
++#define H(x, y, z) ((x) ^ (y) ^ (z))
++
++/*
++ * The generic round function.  The application is so specific that
++ * we don't bother protecting all the arguments with parens, as is generally
++ * good macro practice, in favor of extra legibility.
++ * Rotation is separate from addition to prevent recomputation
++ */
++#define ROUND(f, a, b, c, d, x, s)	\
++	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
++#define K1 0
++#define K2 013240474631UL
++#define K3 015666365641UL
++
++/*
++ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
++ */
++static void halfMD4Transform (__u32 buf[4], __u32 const in[])
++{
++	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
++
++	/* Round 1 */
++	ROUND(F, a, b, c, d, in[0] + K1,  3);
++	ROUND(F, d, a, b, c, in[1] + K1,  7);
++	ROUND(F, c, d, a, b, in[2] + K1, 11);
++	ROUND(F, b, c, d, a, in[3] + K1, 19);
++	ROUND(F, a, b, c, d, in[4] + K1,  3);
++	ROUND(F, d, a, b, c, in[5] + K1,  7);
++	ROUND(F, c, d, a, b, in[6] + K1, 11);
++	ROUND(F, b, c, d, a, in[7] + K1, 19);
++
++	/* Round 2 */
++	ROUND(G, a, b, c, d, in[1] + K2,  3);
++	ROUND(G, d, a, b, c, in[3] + K2,  5);
++	ROUND(G, c, d, a, b, in[5] + K2,  9);
++	ROUND(G, b, c, d, a, in[7] + K2, 13);
++	ROUND(G, a, b, c, d, in[0] + K2,  3);
++	ROUND(G, d, a, b, c, in[2] + K2,  5);
++	ROUND(G, c, d, a, b, in[4] + K2,  9);
++	ROUND(G, b, c, d, a, in[6] + K2, 13);
++
++	/* Round 3 */
++	ROUND(H, a, b, c, d, in[3] + K3,  3);
++	ROUND(H, d, a, b, c, in[7] + K3,  9);
++	ROUND(H, c, d, a, b, in[2] + K3, 11);
++	ROUND(H, b, c, d, a, in[6] + K3, 15);
++	ROUND(H, a, b, c, d, in[1] + K3,  3);
++	ROUND(H, d, a, b, c, in[5] + K3,  9);
++	ROUND(H, c, d, a, b, in[0] + K3, 11);
++	ROUND(H, b, c, d, a, in[4] + K3, 15);
++
++	buf[0] += a;
++	buf[1] += b;
++	buf[2] += c;
++	buf[3] += d;
++}
++
++#undef ROUND
++#undef F
++#undef G
++#undef H
++#undef K1
++#undef K2
++#undef K3
++
++/* The old legacy hash */
++static __u32 dx_hack_hash (const char *name, int len)
++{
++	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++	while (len--) {
++		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++		
++		if (hash & 0x80000000) hash -= 0x7fffffff;
++		hash1 = hash0;
++		hash0 = hash;
++	}
++	return (hash0 << 1);
++}
++
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++{
++	__u32	pad, val;
++	int	i;
++
++	pad = (__u32)len | ((__u32)len << 8);
++	pad |= pad << 16;
++
++	val = pad;
++	if (len > num*4)
++		len = num * 4;
++	for (i=0; i < len; i++) {
++		if ((i % 4) == 0)
++			val = pad;
++		val = msg[i] + (val << 8);
++		if ((i % 4) == 3) {
++			*buf++ = val;
++			val = pad;
++			num--;
++		}
++	}
++	if (--num >= 0)
++		*buf++ = val;
++	while (--num >= 0)
++		*buf++ = pad;
++}
++
++/*
++ * Returns the hash of a filename.  If len is 0 and name is NULL, then
++ * this function can be used to test whether or not a hash version is
++ * supported.
++ * 
++ * The seed is an 4 longword (32 bits) "secret" which can be used to
++ * uniquify a hash.  If the seed is all zero's, then some default seed
++ * may be used.
++ * 
++ * A particular hash version specifies whether or not the seed is
++ * represented, and whether or not the returned hash is 32 bits or 64
++ * bits.  32 bit hashes will return 0 for the minor hash.
++ */
++int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
++{
++	__u32	hash;
++	__u32	minor_hash = 0;
++	const char	*p;
++	int		i;
++	__u32 		in[8], buf[4];
++
++	/* Initialize the default seed for the hash checksum functions */
++	buf[0] = 0x67452301;
++	buf[1] = 0xefcdab89;
++	buf[2] = 0x98badcfe;
++	buf[3] = 0x10325476;
++
++	/* Check to see if the seed is all zero's */
++	if (hinfo->seed) {
++		for (i=0; i < 4; i++) {
++			if (hinfo->seed[i])
++				break;
++		}
++		if (i < 4)
++			memcpy(buf, hinfo->seed, sizeof(buf));
++	}
++		
++	switch (hinfo->hash_version) {
++	case DX_HASH_LEGACY:
++		hash = dx_hack_hash(name, len);
++		break;
++	case DX_HASH_HALF_MD4:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 8);
++			halfMD4Transform(buf, in);
++			len -= 32;
++			p += 32;
++		}
++		minor_hash = buf[2];
++		hash = buf[1];
++		break;
++	case DX_HASH_TEA:
++		p = name;
++		while (len > 0) {
++			str2hashbuf(p, len, in, 4);
++			TEA_transform(buf, in);
++			len -= 16;
++			p += 16;
++		}
++		hash = buf[0];
++		minor_hash = buf[1];
++		break;
++	default:
++		hinfo->hash = 0;
++		return -1;
++	}
++	hinfo->hash = hash & ~1;
++	hinfo->minor_hash = minor_hash;
++	return 0;
++}
+--- linux-2.4.18-chaos-pdirops/fs/ext3/Makefile~ext3-htree	2003-09-23 11:52:24.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/Makefile	2003-09-23 12:11:54.000000000 +0400
+@@ -12,7 +12,7 @@ O_TARGET := ext3.o
+ export-objs :=	super.o inode.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o
++		ioctl.o namei.o super.o symlink.o hash.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.18-chaos-pdirops/fs/ext3/namei.c~ext3-htree	2003-09-23 11:52:34.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/namei.c	2003-09-23 12:12:09.000000000 +0400
+@@ -16,6 +16,12 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  *  Directory entry file type support and forward compatibility hooks
+  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
++ *  Hash Tree Directory indexing (c)
++ *  	Daniel Phillips, 2001
++ *  Hash Tree Directory indexing porting
++ *  	Christopher Li, 2002
++ *  Hash Tree Directory indexing cleanup
++ * 	Theodore Ts'o, 2002
+  */
+ 
+ #include <linux/fs.h>
+@@ -38,6 +44,642 @@
+ #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+ #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+ 
++static struct buffer_head *ext3_append(handle_t *handle,
++					struct inode *inode,
++					u32 *block, int *err)
++{
++	struct buffer_head *bh;
++
++	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
++
++	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
++		inode->i_size += inode->i_sb->s_blocksize;
++		EXT3_I(inode)->i_disksize = inode->i_size;
++		ext3_journal_get_write_access(handle,bh);
++	}
++	return bh;
++}
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#ifndef swap
++#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
++#endif
++
++typedef struct { u32 v; } le_u32;
++typedef struct { u16 v; } le_u16;
++
++#ifdef DX_DEBUG
++#define dxtrace(command) command
++#else
++#define dxtrace(command) 
++#endif
++
++struct fake_dirent
++{
++	/*le*/u32 inode;
++	/*le*/u16 rec_len;
++	u8 name_len;
++	u8 file_type;
++};
++
++struct dx_countlimit
++{
++	le_u16 limit;
++	le_u16 count;
++};
++
++struct dx_entry
++{
++	le_u32 hash;
++	le_u32 block;
++};
++
++/*
++ * dx_root_info is laid out so that if it should somehow get overlaid by a
++ * dirent the two low bits of the hash version will be zero.  Therefore, the
++ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
++ */
++
++struct dx_root
++{
++	struct fake_dirent dot;
++	char dot_name[4];
++	struct fake_dirent dotdot;
++	char dotdot_name[4];
++	struct dx_root_info
++	{
++		le_u32 reserved_zero;
++		u8 hash_version;
++		u8 info_length; /* 8 */
++		u8 indirect_levels;
++		u8 unused_flags;
++	}
++	info;
++	struct dx_entry	entries[0];
++};
++
++struct dx_node
++{
++	struct fake_dirent fake;
++	struct dx_entry	entries[0];
++};
++
++
++struct dx_frame
++{
++	struct buffer_head *bh;
++	struct dx_entry *entries;
++	struct dx_entry *at;
++};
++
++struct dx_map_entry
++{
++	u32 hash;
++	u32 offs;
++};
++
++#ifdef CONFIG_EXT3_INDEX
++static inline unsigned dx_get_block (struct dx_entry *entry);
++static void dx_set_block (struct dx_entry *entry, unsigned value);
++static inline unsigned dx_get_hash (struct dx_entry *entry);
++static void dx_set_hash (struct dx_entry *entry, unsigned value);
++static unsigned dx_get_count (struct dx_entry *entries);
++static unsigned dx_get_limit (struct dx_entry *entries);
++static void dx_set_count (struct dx_entry *entries, unsigned value);
++static void dx_set_limit (struct dx_entry *entries, unsigned value);
++static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
++static unsigned dx_node_limit (struct inode *dir);
++static struct dx_frame *dx_probe(struct dentry *dentry,
++				 struct inode *dir,
++				 struct dx_hash_info *hinfo,
++				 struct dx_frame *frame,
++				 int *err);
++static void dx_release (struct dx_frame *frames);
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
++static void dx_sort_map(struct dx_map_entry *map, unsigned count);
++static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
++		struct dx_map_entry *offsets, int count);
++static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
++static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash);
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err);
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode);
++
++/*
++ * Future: use high four bits of block for coalesce-on-delete flags
++ * Mask them off for now.
++ */
++
++static inline unsigned dx_get_block (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->block.v) & 0x00ffffff;
++}
++
++static inline void dx_set_block (struct dx_entry *entry, unsigned value)
++{
++	entry->block.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_hash (struct dx_entry *entry)
++{
++	return le32_to_cpu(entry->hash.v);
++}
++
++static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
++{
++	entry->hash.v = cpu_to_le32(value);
++}
++
++static inline unsigned dx_get_count (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->count.v);
++}
++
++static inline unsigned dx_get_limit (struct dx_entry *entries)
++{
++	return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v);
++}
++
++static inline void dx_set_count (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value);
++}
++
++static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
++{
++	((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value);
++}
++
++static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) -
++		EXT3_DIR_REC_LEN(2) - infosize;
++	return 0? 20: entry_space / sizeof(struct dx_entry);
++}
++
++static inline unsigned dx_node_limit (struct inode *dir)
++{
++	unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0);
++	return 0? 22: entry_space / sizeof(struct dx_entry);
++}
++
++/*
++ * Debug
++ */
++#ifdef DX_DEBUG
++struct stats
++{ 
++	unsigned names;
++	unsigned space;
++	unsigned bcount;
++};
++
++static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de,
++				 int size, int show_names)
++{
++	unsigned names = 0, space = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	printk("names: ");
++	while ((char *) de < base + size)
++	{
++		if (de->inode)
++		{
++			if (show_names)
++			{
++				int len = de->name_len;
++				char *name = de->name;
++				while (len--) printk("%c", *name++);
++				ext3fs_dirhash(de->name, de->name_len, &h);
++				printk(":%x.%u ", h.hash,
++				       ((char *) de - base));
++			}
++			space += EXT3_DIR_REC_LEN(de->name_len);
++	 		names++;
++		}
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	printk("(%i)\n", names);
++	return (struct stats) { names, space, 1 };
++}
++
++struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
++			     struct dx_entry *entries, int levels)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
++	unsigned bcount = 0;
++	struct buffer_head *bh;
++	int err;
++	printk("%i indexed blocks...\n", count);
++	for (i = 0; i < count; i++, entries++)
++	{
++		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
++		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
++		struct stats stats;
++		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
++		if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue;
++		stats = levels?
++		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
++		   dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0);
++		names += stats.names;
++		space += stats.space;
++		bcount += stats.bcount;
++		brelse (bh);
++	}
++	if (bcount)
++		printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
++			names, space/bcount,(space/bcount)*100/blocksize);
++	return (struct stats) { names, space, bcount};
++}
++#endif /* DX_DEBUG */
++
++/*
++ * Probe for a directory leaf block to search.
++ *
++ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
++ * error in the directory index, and the caller should fall back to
++ * searching the directory normally.  The callers of dx_probe **MUST**
++ * check for this error code, and make sure it never gets reflected
++ * back to userspace.
++ */
++static struct dx_frame *
++dx_probe(struct dentry *dentry, struct inode *dir,
++	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
++{
++	unsigned count, indirect;
++	struct dx_entry *at, *entries, *p, *q, *m;
++	struct dx_root *root;
++	struct buffer_head *bh;
++	struct dx_frame *frame = frame_in;
++	u32 hash;
++
++	frame->bh = NULL;
++	if (dentry)
++		dir = dentry->d_parent->d_inode;
++	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
++		goto fail;
++	root = (struct dx_root *) bh->b_data;
++	if (root->info.hash_version != DX_HASH_TEA &&
++	    root->info.hash_version != DX_HASH_HALF_MD4 &&
++	    root->info.hash_version != DX_HASH_LEGACY) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unrecognised inode hash code %d",
++			     root->info.hash_version);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++	hinfo->hash_version = root->info.hash_version;
++	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	if (dentry)
++		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	hash = hinfo->hash;
++
++	if (root->info.unused_flags & 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash flags: %#06x",
++			     root->info.unused_flags);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	if ((indirect = root->info.indirect_levels) > 1) {
++		ext3_warning(dir->i_sb, __FUNCTION__,
++			     "Unimplemented inode hash depth: %#06x",
++			     root->info.indirect_levels);
++		brelse(bh);
++		*err = ERR_BAD_DX_DIR;
++		goto fail;
++	}
++
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	while (1)
++	{
++		count = dx_get_count(entries);
++		assert (count && count <= dx_get_limit(entries));
++		p = entries + 1;
++		q = entries + count - 1;
++		while (p <= q)
++		{
++			m = p + (q - p)/2;
++			dxtrace(printk("."));
++			if (dx_get_hash(m) > hash)
++				q = m - 1;
++			else
++				p = m + 1;
++		}
++
++		if (0) // linear search cross check
++		{
++			unsigned n = count - 1;
++			at = entries;
++			while (n--)
++			{
++				dxtrace(printk(","));
++				if (dx_get_hash(++at) > hash)
++				{
++					at--;
++					break;
++				}
++			}
++			assert (at == p - 1);
++		}
++
++		at = p - 1;
++		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		frame->bh = bh;
++		frame->entries = entries;
++		frame->at = at;
++		if (!indirect--) return frame;
++		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++			goto fail2;
++		at = entries = ((struct dx_node *) bh->b_data)->entries;
++		assert (dx_get_limit(entries) == dx_node_limit (dir));
++		frame++;
++	}
++fail2:
++	while (frame >= frame_in) {
++		brelse(frame->bh);
++		frame--;
++	}
++fail:
++	return NULL;
++}
++
++static void dx_release (struct dx_frame *frames)
++{
++	if (frames[0].bh == NULL)
++		return;
++
++	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++		brelse(frames[1].bh);
++	brelse(frames[0].bh);
++}
++
++/*
++ * This function increments the frame pointer to search the next leaf
++ * block, and reads in the necessary intervening nodes if the search
++ * should be necessary.  Whether or not the search is necessary is
++ * controlled by the hash parameter.  If the hash value is even, then
++ * the search is only continued if the next block starts with that
++ * hash value.  This is used if we are searching for a specific file.
++ *
++ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
++ *
++ * This function returns 1 if the caller should continue to search,
++ * or 0 if it should not.  If there is an error reading one of the
++ * index blocks, it will return -1.
++ *
++ * If start_hash is non-null, it will be filled in with the starting
++ * hash of the next page.
++ */
++static int ext3_htree_next_block(struct inode *dir, __u32 hash,
++				 struct dx_frame *frame,
++				 struct dx_frame *frames, int *err,
++				 __u32 *start_hash)
++{
++	struct dx_frame *p;
++	struct buffer_head *bh;
++	int num_frames = 0;
++	__u32 bhash;
++
++	*err = ENOENT;
++	p = frame;
++	/*
++	 * Find the next leaf page by incrementing the frame pointer.
++	 * If we run out of entries in the interior node, loop around and
++	 * increment pointer in the parent node.  When we break out of
++	 * this loop, num_frames indicates the number of interior
++	 * nodes need to be read.
++	 */
++	while (1) {
++		if (++(p->at) < p->entries + dx_get_count(p->entries))
++			break;
++		if (p == frames)
++			return 0;
++		num_frames++;
++		p--;
++	}
++
++	/*
++	 * If the hash is 1, then continue only if the next page has a
++	 * continuation hash of any value.  This is used for readdir
++	 * handling.  Otherwise, check to see if the hash matches the
++	 * desired contiuation hash.  If it doesn't, return since
++	 * there's no point to read in the successive index pages.
++	 */
++	bhash = dx_get_hash(p->at);
++	if (start_hash)
++		*start_hash = bhash;
++	if ((hash & 1) == 0) {
++		if ((bhash & ~1) != hash)
++			return 0;
++	}
++	/*
++	 * If the hash is HASH_NB_ALWAYS, we always go to the next
++	 * block so no check is necessary
++	 */
++	while (num_frames--) {
++		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
++				      0, err)))
++			return -1; /* Failure */
++		p++;
++		brelse (p->bh);
++		p->bh = bh;
++		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++	}
++	return 1;
++}
++
++
++/*
++ * p is at least 6 bytes before the end of page
++ */
++static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p)
++{
++	return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
++}
++
++/*
++ * This function fills a red-black tree with information from a
++ * directory.  We start scanning the directory in hash order, starting
++ * at start_hash and start_minor_hash.
++ *
++ * This function returns the number of entries inserted into the tree,
++ * or a negative error code.
++ */
++int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++			 __u32 start_minor_hash, __u32 *next_hash)
++{
++	struct dx_hash_info hinfo;
++	struct buffer_head *bh;
++	struct ext3_dir_entry_2 *de, *top;
++	static struct dx_frame frames[2], *frame;
++	struct inode *dir;
++	int block, err;
++	int count = 0;
++	int ret;
++	__u32 hashval;
++	
++	dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
++		       start_minor_hash));
++	dir = dir_file->f_dentry->d_inode;
++	hinfo.hash = start_hash;
++	hinfo.minor_hash = 0;
++	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++
++	/* Add '.' and '..' from the htree header */
++	if (!start_hash && !start_minor_hash) {
++		de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data;
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		de = ext3_next_entry(de);
++		if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0)
++			goto errout;
++		count += 2;
++	}
++
++	while (1) {
++		block = dx_get_block(frame->at);
++		dxtrace(printk("Reading block %d\n", block));
++		if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
++			goto errout;
++	
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de)) {
++			ext3fs_dirhash(de->name, de->name_len, &hinfo);
++			if ((hinfo.hash < start_hash) ||
++			    ((hinfo.hash == start_hash) &&
++			     (hinfo.minor_hash < start_minor_hash)))
++				continue;
++			if ((err = ext3_htree_store_dirent(dir_file,
++				   hinfo.hash, hinfo.minor_hash, de)) != 0)
++				goto errout;
++			count++;
++		}
++		brelse (bh);
++		hashval = ~1;
++		ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, 
++					    frame, frames, &err, &hashval);
++		if (next_hash)
++			*next_hash = hashval;
++		if (ret == -1)
++			goto errout;
++		/*
++		 * Stop if:  (a) there are no more entries, or
++		 * (b) we have inserted at least one entry and the
++		 * next hash value is not a continuation
++		 */
++		if ((ret == 0) ||
++		    (count && ((hashval & 1) == 0)))
++			break;
++	}
++	dx_release(frames);
++	dxtrace(printk("Fill tree: returned %d entries\n", count));
++	return count;
++errout:
++	dx_release(frames);
++	return (err);
++}
++
++
++/*
++ * Directory block splitting, compacting
++ */
++
++static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
++			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
++{
++	int count = 0;
++	char *base = (char *) de;
++	struct dx_hash_info h = *hinfo;
++	
++	while ((char *) de < base + size)
++	{
++		if (de->name_len && de->inode) {
++			ext3fs_dirhash(de->name, de->name_len, &h);
++			map_tail--;
++			map_tail->hash = h.hash;
++			map_tail->offs = (u32) ((char *) de - base);
++			count++;
++		}
++		/* XXX: do we need to check rec_len == 0 case? -Chris */
++		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++	}
++	return count;
++}
++
++static void dx_sort_map (struct dx_map_entry *map, unsigned count)
++{
++        struct dx_map_entry *p, *q, *top = map + count - 1;
++        int more;
++        /* Combsort until bubble sort doesn't suck */
++        while (count > 2)
++	{
++                count = count*10/13;
++                if (count - 9 < 2) /* 9, 10 -> 11 */
++                        count = 11;
++                for (p = top, q = p - count; q >= map; p--, q--)
++                        if (p->hash < q->hash)
++                                swap(*p, *q);
++        }
++        /* Garden variety bubble sort */
++        do {
++                more = 0;
++                q = top;
++                while (q-- > map)
++		{
++                        if (q[1].hash >= q[0].hash)
++				continue;
++                        swap(*(q+1), *q);
++                        more = 1;
++		}
++	} while(more);
++}
++
++static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++{
++	struct dx_entry *entries = frame->entries;
++	struct dx_entry *old = frame->at, *new = old + 1;
++	int count = dx_get_count(entries);
++
++	assert(count < dx_get_limit(entries));
++	assert(old < entries + count);
++	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
++	dx_set_hash(new, hash);
++	dx_set_block(new, block);
++	dx_set_count(entries, count + 1);
++}
++#endif
++
++
++static void ext3_update_dx_flag(struct inode *inode)
++{
++	if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
++				     EXT3_FEATURE_COMPAT_DIR_INDEX))
++		EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL;
++}
++
+ /*
+  * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure.
+  *
+@@ -94,6 +736,7 @@ static int inline search_dirblock(struct
+ 	return 0;
+ }
+ 
++
+ /*
+  *	ext3_find_entry()
+  *
+@@ -105,6 +748,8 @@ static int inline search_dirblock(struct
+  * The returned buffer_head has ->b_count elevated.  The caller is expected
+  * to brelse() it when appropriate.
+  */
++
++	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+ 					struct ext3_dir_entry_2 ** res_dir)
+ {
+@@ -119,12 +764,32 @@ static struct buffer_head * ext3_find_en
+ 	int num = 0;
+ 	int nblocks, i, err;
+ 	struct inode *dir = dentry->d_parent->d_inode;
++	int namelen;
++	const u8 *name;
++	unsigned blocksize;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+-
++	blocksize = sb->s_blocksize;
++	namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++	if (namelen > EXT3_NAME_LEN)
++		return NULL;
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		/*
++		 * On success, or if the error was file not found,
++		 * return.  Otherwise, fall back to doing a search the
++		 * old fashioned way.
++		 */
++		if (bh || (err != ERR_BAD_DX_DIR))
++			return bh;
++		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++	}
++#endif
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+-	start = dir->u.ext3_i.i_dir_start_lookup;
++	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+ 		start = 0;
+ 	block = start;
+@@ -166,7 +831,7 @@ restart:
+ 		i = search_dirblock(bh, dir, dentry,
+ 			    block << EXT3_BLOCK_SIZE_BITS(sb), res_dir);
+ 		if (i == 1) {
+-			dir->u.ext3_i.i_dir_start_lookup = block;
++			EXT3_I(dir)->i_dir_start_lookup = block;
+ 			ret = bh;
+ 			goto cleanup_and_exit;
+ 		} else {
+@@ -197,6 +862,66 @@ cleanup_and_exit:
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
++		       struct ext3_dir_entry_2 **res_dir, int *err)
++{
++	struct super_block * sb;
++	struct dx_hash_info	hinfo;
++	u32 hash;
++	struct dx_frame frames[2], *frame;
++	struct ext3_dir_entry_2 *de, *top;
++	struct buffer_head *bh;
++	unsigned long block;
++	int retval;
++	int namelen = dentry->d_name.len;
++	const u8 *name = dentry->d_name.name;
++	struct inode *dir = dentry->d_parent->d_inode;
++	
++	sb = dir->i_sb;
++	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++		return NULL;
++	hash = hinfo.hash;
++	do {
++		block = dx_get_block(frame->at);
++		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
++			goto errout;
++		de = (struct ext3_dir_entry_2 *) bh->b_data;
++		top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize -
++				       EXT3_DIR_REC_LEN(0));
++		for (; de < top; de = ext3_next_entry(de))
++		if (ext3_match (namelen, name, de)) {
++			if (!ext3_check_dir_entry("ext3_find_entry",
++						  dir, de, bh,
++				  (block<<EXT3_BLOCK_SIZE_BITS(sb))
++					  +((char *)de - bh->b_data))) {
++				brelse (bh);
++				goto errout;
++			}
++			*res_dir = de;
++			dx_release (frames);
++			return bh;
++		}
++		brelse (bh);
++		/* Check to see if we should continue to search */
++		retval = ext3_htree_next_block(dir, hash, frame,
++					       frames, err, 0);
++		if (retval == -1) {
++			ext3_warning(sb, __FUNCTION__,
++			     "error reading index page in directory #%lu",
++			     dir->i_ino);
++			goto errout;
++		}
++	} while (retval == 1);
++	
++	*err = -ENOENT;
++errout:
++	dxtrace(printk("%s not found\n", name));
++	dx_release (frames);
++	return NULL;
++}
++#endif
++
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+@@ -213,8 +938,9 @@ static struct dentry *ext3_lookup(struct
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+-		if (!inode)
++		if (!inode) {
+ 			return ERR_PTR(-EACCES);
++		}
+ 	}
+ 	d_add(dentry, inode);
+ 	return NULL;
+@@ -238,6 +964,301 @@ static inline void ext3_set_de_type(stru
+ 		de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ }
+ 
++#ifdef CONFIG_EXT3_INDEX
++static struct ext3_dir_entry_2 *
++dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
++{
++	unsigned rec_len = 0;
++
++	while (count--) {
++		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		rec_len = EXT3_DIR_REC_LEN(de->name_len);
++		memcpy (to, de, rec_len);
++		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
++		de->inode = 0;
++		map++;
++		to += rec_len;
++	}
++	return (struct ext3_dir_entry_2 *) (to - rec_len);
++}
++
++static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
++{
++	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	unsigned rec_len = 0;
++
++	prev = to = de;
++	while ((char*)de < base + size) {
++		next = (struct ext3_dir_entry_2 *) ((char *) de +
++						    le16_to_cpu(de->rec_len));
++		if (de->inode && de->name_len) {
++			rec_len = EXT3_DIR_REC_LEN(de->name_len);
++			if (de > to)
++				memmove(to, de, rec_len);
++			to->rec_len = rec_len;
++			prev = to;
++			to = (struct ext3_dir_entry_2 *) (((char *) to) + rec_len);
++		}
++		de = next;
++	}
++	return prev;
++}
++
++static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
++			struct buffer_head **bh,struct dx_frame *frame,
++			struct dx_hash_info *hinfo, int *error)
++{
++	unsigned blocksize = dir->i_sb->s_blocksize;
++	unsigned count, continued;
++	struct buffer_head *bh2;
++	u32 newblock;
++	u32 hash2;
++	struct dx_map_entry *map;
++	char *data1 = (*bh)->b_data, *data2;
++	unsigned split;
++	struct ext3_dir_entry_2 *de = NULL, *de2;
++	int	err;
++
++	bh2 = ext3_append (handle, dir, &newblock, error);
++	if (!(bh2)) {
++		brelse(*bh);
++		*bh = NULL;
++		goto errout;
++	}
++
++	BUFFER_TRACE(*bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, *bh);
++	if (err) {
++	journal_error:
++		brelse(*bh);
++		brelse(bh2);
++		*bh = NULL;
++		ext3_std_error(dir->i_sb, err);
++		goto errout;
++	}
++	BUFFER_TRACE(frame->bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, frame->bh);
++	if (err)
++		goto journal_error;
++
++	data2 = bh2->b_data;
++
++	/* create map in the end of data2 block */
++	map = (struct dx_map_entry *) (data2 + blocksize);
++	count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
++			     blocksize, hinfo, map);
++	map -= count;
++	split = count/2; // need to adjust to actual middle
++	dx_sort_map (map, count);
++	hash2 = map[split].hash;
++	continued = hash2 == map[split - 1].hash;
++	dxtrace(printk("Split block %i at %x, %i/%i\n",
++		dx_get_block(frame->at), hash2, split, count-split));
++
++	/* Fancy dance to stay within two buffers */
++	de2 = dx_move_dirents(data1, data2, map + split, count - split);
++	de = dx_pack_dirents(data1,blocksize);
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
++	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++
++	/* Which block gets the new entry? */
++	if (hinfo->hash >= hash2)
++	{
++		swap(*bh, bh2);
++		de = de2;
++	}
++	dx_insert_block (frame, hash2 + continued, newblock);
++	err = ext3_journal_dirty_metadata (handle, bh2);
++	if (err)
++		goto journal_error;
++	err = ext3_journal_dirty_metadata (handle, frame->bh);
++	if (err)
++		goto journal_error;
++	brelse (bh2);
++	dxtrace(dx_show_index ("frame", frame->entries));
++errout:
++	return de;
++}
++#endif
++
++
++/*
++ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
++ * it points to a directory entry which is guaranteed to be large
++ * enough for new directory entry.  If de is NULL, then
++ * add_dirent_to_buf will attempt search the directory block for
++ * space.  It will return -ENOSPC if no space is available, and -EIO
++ * and -EEXIST if directory entry already exists.
++ * 
++ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
++ * all other cases bh is released.
++ */
++static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode, struct ext3_dir_entry_2 *de,
++			     struct buffer_head * bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	unsigned long	offset = 0;
++	unsigned short	reclen;
++	int		nlen, rlen, err;
++	char		*top;
++	
++	reclen = EXT3_DIR_REC_LEN(namelen);
++	if (!de) {
++		de = (struct ext3_dir_entry_2 *)bh->b_data;
++		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
++		while ((char *) de <= top) {
++			if (!ext3_check_dir_entry("ext3_add_entry", dir, de,
++						  bh, offset)) {
++				brelse (bh);
++				return -EIO;
++			}
++			if (ext3_match (namelen, name, de)) {
++				brelse (bh);
++				return -EEXIST;
++			}
++			nlen = EXT3_DIR_REC_LEN(de->name_len);
++			rlen = le16_to_cpu(de->rec_len);
++			if ((de->inode? rlen - nlen: rlen) >= reclen)
++				break;
++			de = (struct ext3_dir_entry_2 *)((char *)de + rlen);
++			offset += rlen;
++		}
++		if ((char *) de > top)
++			return -ENOSPC;
++	}
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err) {
++		ext3_std_error(dir->i_sb, err);
++		brelse(bh);
++		return err;
++	}
++	
++	/* By now the buffer is marked for journaling */
++	nlen = EXT3_DIR_REC_LEN(de->name_len);
++	rlen = le16_to_cpu(de->rec_len);
++	if (de->inode) {
++		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		de1->rec_len = cpu_to_le16(rlen - nlen);
++		de->rec_len = cpu_to_le16(nlen);
++		de = de1;
++	}
++	de->file_type = EXT3_FT_UNKNOWN;
++	if (inode) {
++		de->inode = cpu_to_le32(inode->i_ino);
++		ext3_set_de_type(dir->i_sb, de, inode->i_mode);
++	} else
++		de->inode = 0;
++	de->name_len = namelen;
++	memcpy (de->name, name, namelen);
++	/*
++	 * XXX shouldn't update any times until successful
++	 * completion of syscall, but too many callers depend
++	 * on this.
++	 *
++	 * XXX similarly, too many callers depend on
++	 * ext3_new_inode() setting the times, but error
++	 * recovery deletes the inode, so the worst that can
++	 * happen is that the times are slightly out of date
++	 * and/or different from the directory change time.
++	 */
++	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
++	ext3_update_dx_flag(dir);
++	dir->i_version = ++event;
++	ext3_mark_inode_dirty(handle, dir);
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		ext3_std_error(dir->i_sb, err);
++	brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * This converts a one block unindexed directory to a 3 block indexed
++ * directory, and adds the dentry to the indexed directory.
++ */
++static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
++			    struct inode *inode, struct buffer_head *bh)
++{
++	struct inode	*dir = dentry->d_parent->d_inode;
++	const char	*name = dentry->d_name.name;
++	int		namelen = dentry->d_name.len;
++	struct buffer_head *bh2;
++	struct dx_root	*root;
++	struct dx_frame	frames[2], *frame;
++	struct dx_entry *entries;
++	struct ext3_dir_entry_2	*de, *de2;
++	char		*data1, *top;
++	unsigned	len;
++	int		retval;
++	unsigned	blocksize;
++	struct dx_hash_info hinfo;
++	u32		block;
++		
++	blocksize =  dir->i_sb->s_blocksize;
++	dxtrace(printk("Creating index\n"));
++	retval = ext3_journal_get_write_access(handle, bh);
++	if (retval) {
++		ext3_std_error(dir->i_sb, retval);
++		brelse(bh);
++		return retval;
++	}
++	root = (struct dx_root *) bh->b_data;
++		
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	bh2 = ext3_append (handle, dir, &block, &retval);
++	if (!(bh2)) {
++		brelse(bh);
++		return retval;
++	}
++	data1 = bh2->b_data;
++
++	/* The 0th block becomes the root, move the dirents out */
++	de = (struct ext3_dir_entry_2 *) &root->dotdot;
++	de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
++	len = ((char *) root) + blocksize - (char *) de;
++	memcpy (data1, de, len);
++	de = (struct ext3_dir_entry_2 *) data1;
++	top = data1 + len;
++	while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top)
++		de = de2;
++	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
++	/* Initialize the root; the dot dirents already exist */
++	de = (struct ext3_dir_entry_2 *) (&root->dotdot);
++	de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
++	memset (&root->info, 0, sizeof(root->info));
++	root->info.info_length = sizeof(root->info);
++	root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version;
++	entries = root->entries;
++	dx_set_block (entries, 1);
++	dx_set_count (entries, 1);
++	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
++
++	/* Initialize as for dx_probe */
++	hinfo.hash_version = root->info.hash_version;
++	hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed;
++	ext3fs_dirhash(name, namelen, &hinfo);
++	frame = frames;
++	frame->entries = entries;
++	frame->at = entries;
++	frame->bh = bh;
++	bh = bh2;
++	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	dx_release (frames);
++	if (!(de))
++		return retval;
++
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
++#endif
++
+ /*
+  *	ext3_add_entry()
+  *
+@@ -248,127 +1268,198 @@ static inline void ext3_set_de_type(stru
+  * may not sleep between calling this and putting something into
+  * the entry, as someone else might have used it while you slept.
+  */
+-
+-/*
+- * AKPM: the journalling code here looks wrong on the error paths
+- */
+ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
+ 	struct inode *inode)
+ {
+ 	struct inode *dir = dentry->d_parent->d_inode;
+-	const char *name = dentry->d_name.name;
+-	int namelen = dentry->d_name.len;
+ 	unsigned long offset;
+-	unsigned short rec_len;
+ 	struct buffer_head * bh;
+-	struct ext3_dir_entry_2 * de, * de1;
++	struct ext3_dir_entry_2 *de;
+ 	struct super_block * sb;
+ 	int	retval;
++#ifdef CONFIG_EXT3_INDEX
++	int	dx_fallback=0;
++#endif
++	unsigned blocksize;
++	unsigned nlen, rlen;
++	u32 block, blocks;
+ 
+ 	sb = dir->i_sb;
+-
+-	if (!namelen)
++	blocksize = sb->s_blocksize;
++	if (!dentry->d_name.len)
+ 		return -EINVAL;
+-	bh = ext3_bread (handle, dir, 0, 0, &retval);
++#ifdef CONFIG_EXT3_INDEX
++	if (is_dx(dir)) {
++		retval = ext3_dx_add_entry(handle, dentry, inode);
++		if (!retval || (retval != ERR_BAD_DX_DIR))
++			return retval;
++		EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
++		dx_fallback++;
++		ext3_mark_inode_dirty(handle, dir);
++	}
++#endif
++	blocks = dir->i_size >> sb->s_blocksize_bits;
++	for (block = 0, offset = 0; block < blocks; block++) {
++		bh = ext3_bread(handle, dir, block, 0, &retval);
++		if(!bh)
++			return retval;
++		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++		if (retval != -ENOSPC)
++			return retval;
++
++#ifdef CONFIG_EXT3_INDEX
++		if (blocks == 1 && !dx_fallback &&
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
++			return make_indexed_dir(handle, dentry, inode, bh);
++#endif
++		brelse(bh);
++	}
++	bh = ext3_append(handle, dir, &block, &retval);
+ 	if (!bh)
+ 		return retval;
+-	rec_len = EXT3_DIR_REC_LEN(namelen);
+-	offset = 0;
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+-	while (1) {
+-		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+-			brelse (bh);
+-			bh = NULL;
+-			bh = ext3_bread (handle, dir,
+-				offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval);
+-			if (!bh)
+-				return retval;
+-			if (dir->i_size <= offset) {
+-				if (dir->i_size == 0) {
+-					brelse(bh);
+-					return -ENOENT;
+-				}
++	de->inode = 0;
++	de->rec_len = cpu_to_le16(rlen = blocksize);
++	nlen = 0;
++	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++}
+ 
+-				ext3_debug ("creating next block\n");
++#ifdef CONFIG_EXT3_INDEX
++/*
++ * Returns 0 for success, or a negative error value
++ */
++static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
++			     struct inode *inode)
++{
++	struct dx_frame frames[2], *frame;
++	struct dx_entry *entries, *at;
++	struct dx_hash_info hinfo;
++	struct buffer_head * bh;
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block * sb = dir->i_sb;
++	struct ext3_dir_entry_2 *de;
++	int err;
+ 
+-				BUFFER_TRACE(bh, "get_write_access");
+-				ext3_journal_get_write_access(handle, bh);
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-				de->inode = 0;
+-				de->rec_len = le16_to_cpu(sb->s_blocksize);
+-				dir->u.ext3_i.i_disksize =
+-					dir->i_size = offset + sb->s_blocksize;
+-				dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-				ext3_mark_inode_dirty(handle, dir);
+-			} else {
++	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	if (!frame)
++		return err;
++	entries = frame->entries;
++	at = frame->at;
+ 
+-				ext3_debug ("skipping to next block\n");
++	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++		goto cleanup;
+ 
+-				de = (struct ext3_dir_entry_2 *) bh->b_data;
+-			}
+-		}
+-		if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh,
+-					   offset)) {
+-			brelse (bh);
+-			return -ENOENT;
+-		}
+-		if (ext3_match (namelen, name, de)) {
+-				brelse (bh);
+-				return -EEXIST;
++	BUFFER_TRACE(bh, "get_write_access");
++	err = ext3_journal_get_write_access(handle, bh);
++	if (err)
++		goto journal_error;
++
++	err = add_dirent_to_buf(handle, dentry, inode, 0, bh);
++	if (err != -ENOSPC) {
++		bh = 0;
++		goto cleanup;
++	}
++
++	/* Block full, should compress but for now just split */
++	dxtrace(printk("using %u of %u node entries\n",
++		       dx_get_count(entries), dx_get_limit(entries)));
++	/* Need to split index? */
++	if (dx_get_count(entries) == dx_get_limit(entries)) {
++		u32 newblock;
++		unsigned icount = dx_get_count(entries);
++		int levels = frame - frames;
++		struct dx_entry *entries2;
++		struct dx_node *node2;
++		struct buffer_head *bh2;
++
++		if (levels && (dx_get_count(frames->entries) ==
++			       dx_get_limit(frames->entries))) {
++			ext3_warning(sb, __FUNCTION__,
++				     "Directory index full!\n");
++			err = -ENOSPC;
++			goto cleanup;
+ 		}
+-		if ((le32_to_cpu(de->inode) == 0 &&
+-				le16_to_cpu(de->rec_len) >= rec_len) ||
+-		    (le16_to_cpu(de->rec_len) >=
+-				EXT3_DIR_REC_LEN(de->name_len) + rec_len)) {
+-			BUFFER_TRACE(bh, "get_write_access");
+-			ext3_journal_get_write_access(handle, bh);
+-			/* By now the buffer is marked for journaling */
+-			offset += le16_to_cpu(de->rec_len);
+-			if (le32_to_cpu(de->inode)) {
+-				de1 = (struct ext3_dir_entry_2 *) ((char *) de +
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de1->rec_len =
+-					cpu_to_le16(le16_to_cpu(de->rec_len) -
+-					EXT3_DIR_REC_LEN(de->name_len));
+-				de->rec_len = cpu_to_le16(
+-						EXT3_DIR_REC_LEN(de->name_len));
+-				de = de1;
++		bh2 = ext3_append (handle, dir, &newblock, &err);
++		if (!(bh2))
++			goto cleanup;
++		node2 = (struct dx_node *)(bh2->b_data);
++		entries2 = node2->entries;
++		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
++		node2->fake.inode = 0;
++		BUFFER_TRACE(frame->bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, frame->bh);
++		if (err)
++			goto journal_error;
++		if (levels) {
++			unsigned icount1 = icount/2, icount2 = icount - icount1;
++			unsigned hash2 = dx_get_hash(entries + icount1);
++			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
++				
++			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++			err = ext3_journal_get_write_access(handle,
++							     frames[0].bh);
++			if (err)
++				goto journal_error;
++				
++			memcpy ((char *) entries2, (char *) (entries + icount1),
++				icount2 * sizeof(struct dx_entry));
++			dx_set_count (entries, icount1);
++			dx_set_count (entries2, icount2);
++			dx_set_limit (entries2, dx_node_limit(dir));
++
++			/* Which index block gets the new entry? */
++			if (at - entries >= icount1) {
++				frame->at = at = at - entries - icount1 + entries2;
++				frame->entries = entries = entries2;
++				swap(frame->bh, bh2);
+ 			}
+-			de->file_type = EXT3_FT_UNKNOWN;
+-			if (inode) {
+-				de->inode = cpu_to_le32(inode->i_ino);
+-				ext3_set_de_type(dir->i_sb, de, inode->i_mode);
+-			} else
+-				de->inode = 0;
+-			de->name_len = namelen;
+-			memcpy (de->name, name, namelen);
+-			/*
+-			 * XXX shouldn't update any times until successful
+-			 * completion of syscall, but too many callers depend
+-			 * on this.
+-			 *
+-			 * XXX similarly, too many callers depend on
+-			 * ext3_new_inode() setting the times, but error
+-			 * recovery deletes the inode, so the worst that can
+-			 * happen is that the times are slightly out of date
+-			 * and/or different from the directory change time.
+-			 */
+-			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+-			dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+-			dir->i_version = ++event;
+-			ext3_mark_inode_dirty(handle, dir);
+-			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-			ext3_journal_dirty_metadata(handle, bh);
+-			brelse(bh);
+-			return 0;
++			dx_insert_block (frames + 0, hash2, newblock);
++			dxtrace(dx_show_index ("node", frames[1].entries));
++			dxtrace(dx_show_index ("node",
++			       ((struct dx_node *) bh2->b_data)->entries));
++			err = ext3_journal_dirty_metadata(handle, bh2);
++			if (err)
++				goto journal_error;
++			brelse (bh2);
++		} else {
++			dxtrace(printk("Creating second level index...\n"));
++			memcpy((char *) entries2, (char *) entries,
++			       icount * sizeof(struct dx_entry));
++			dx_set_limit(entries2, dx_node_limit(dir));
++
++			/* Set up root */
++			dx_set_count(entries, 1);
++			dx_set_block(entries + 0, newblock);
++			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++
++			/* Add new access path frame */
++			frame = frames + 1;
++			frame->at = at = at - entries + entries2;
++			frame->entries = entries = entries2;
++			frame->bh = bh2;
++			err = ext3_journal_get_write_access(handle,
++							     frame->bh);
++			if (err)
++				goto journal_error;
+ 		}
+-		offset += le16_to_cpu(de->rec_len);
+-		de = (struct ext3_dir_entry_2 *)
+-			((char *) de + le16_to_cpu(de->rec_len));
++		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	brelse (bh);
+-	return -ENOSPC;
++	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	if (!de)
++		goto cleanup;
++	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	bh = 0;
++	goto cleanup;
++	
++journal_error:
++	ext3_std_error(dir->i_sb, err);
++cleanup:
++	if (bh)
++		brelse(bh);
++	dx_release(frames);
++	return err;
+ }
++#endif
+ 
+ /*
+  * ext3_delete_entry deletes a directory entry by merging it with the
+@@ -452,9 +1543,11 @@ static int ext3_create (struct inode * d
+ 	struct inode * inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -479,9 +1572,11 @@ static int ext3_mknod (struct inode * di
+ 	struct inode *inode;
+ 	int err;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -508,9 +1603,11 @@ static int ext3_mkdir(struct inode * dir
+ 	if (dir->i_nlink >= EXT3_LINK_MAX)
+ 		return -EMLINK;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -522,7 +1619,7 @@ static int ext3_mkdir(struct inode * dir
+ 
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+-	inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize;
++	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+ 	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+@@ -555,21 +1652,19 @@ static int ext3_mkdir(struct inode * dir
+ 		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+-	if (err)
+-		goto out_no_entry;
++	if (err) {
++		inode->i_nlink = 0;
++		ext3_mark_inode_dirty(handle, inode);
++		iput (inode);
++		goto out_stop;
++	}
+ 	dir->i_nlink++;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	d_instantiate(dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	inode->i_nlink = 0;
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ /*
+@@ -656,7 +1751,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	int err = 0, rc;
+ 	
+ 	lock_super(sb);
+-	if (!list_empty(&inode->u.ext3_i.i_orphan))
++	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+ 	/* Orphan handling is only valid for files with data blocks
+@@ -697,7 +1792,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	 * This is safe: on error we're going to ignore the orphan list
+ 	 * anyway on the next recovery. */
+ 	if (!err)
+-		list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan);
++		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
+ 
+ 	jbd_debug(4, "superblock will point to %ld\n", inode->i_ino);
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+@@ -715,25 +1810,26 @@ out_unlock:
+ int ext3_orphan_del(handle_t *handle, struct inode *inode)
+ {
+ 	struct list_head *prev;
++	struct ext3_inode_info *ei = EXT3_I(inode);
+ 	struct ext3_sb_info *sbi;
+ 	ino_t ino_next; 
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 	
+ 	lock_super(inode->i_sb);
+-	if (list_empty(&inode->u.ext3_i.i_orphan)) {
++	if (list_empty(&ei->i_orphan)) {
+ 		unlock_super(inode->i_sb);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+-	prev = inode->u.ext3_i.i_orphan.prev;
++	prev = ei->i_orphan.prev;
+ 	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
+ 
+-	list_del(&inode->u.ext3_i.i_orphan);
+-	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
++	list_del(&ei->i_orphan);
++	INIT_LIST_HEAD(&ei->i_orphan);
+ 
+ 	/* If we're on an error path, we may not have a valid
+ 	 * transaction handle with which to update the orphan list on
+@@ -794,8 +1890,9 @@ static int ext3_rmdir (struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	retval = -ENOENT;
+ 	bh = ext3_find_entry (dentry, &de);
+@@ -833,7 +1930,7 @@ static int ext3_rmdir (struct inode * di
+ 	dir->i_nlink--;
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ 	ext3_mark_inode_dirty(handle, inode);
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 
+ end_rmdir:
+@@ -851,8 +1948,9 @@ static int ext3_unlink(struct inode * di
+ 	handle_t *handle;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -879,7 +1977,7 @@ static int ext3_unlink(struct inode * di
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+-	dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(dir);
+ 	ext3_mark_inode_dirty(handle, dir);
+ 	inode->i_nlink--;
+ 	if (!inode->i_nlink)
+@@ -905,9 +2003,11 @@ static int ext3_symlink (struct inode * 
+ 	if (l > dir->i_sb->s_blocksize)
+ 		return -ENAMETOOLONG;
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -917,7 +2017,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+ 
+-	if (l > sizeof (inode->u.ext3_i.i_data)) {
++	if (l > sizeof (EXT3_I(inode)->i_data)) {
+ 		inode->i_op = &page_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+@@ -926,25 +2026,23 @@ static int ext3_symlink (struct inode * 
+ 		 * i_size in generic_commit_write().
+ 		 */
+ 		err = block_symlink(inode, symname, l);
+-		if (err)
+-			goto out_no_entry;
++		if (err) {
++			ext3_dec_count(handle, inode);
++			ext3_mark_inode_dirty(handle, inode);
++			iput (inode);
++			goto out_stop;
++		}
+ 	} else {
+ 		inode->i_op = &ext3_fast_symlink_inode_operations;
+-		memcpy((char*)&inode->u.ext3_i.i_data,symname,l);
++		memcpy((char*)&EXT3_I(inode)->i_data,symname,l);
+ 		inode->i_size = l-1;
+ 	}
+-	inode->u.ext3_i.i_disksize = inode->i_size;
++	EXT3_I(inode)->i_disksize = inode->i_size;
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ 	ext3_mark_inode_dirty(handle, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
+-
+-out_no_entry:
+-	ext3_dec_count(handle, inode);
+-	ext3_mark_inode_dirty(handle, inode);
+-	iput (inode);
+-	goto out_stop;
+ }
+ 
+ static int ext3_link (struct dentry * old_dentry,
+@@ -957,12 +2055,15 @@ static int ext3_link (struct dentry * ol
+ 	if (S_ISDIR(inode->i_mode))
+ 		return -EPERM;
+ 
+-	if (inode->i_nlink >= EXT3_LINK_MAX)
++	if (inode->i_nlink >= EXT3_LINK_MAX) {
+ 		return -EMLINK;
++	}
+ 
+-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
++					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+@@ -996,9 +2097,11 @@ static int ext3_rename (struct inode * o
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2);
+-	if (IS_ERR(handle))
++	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
++			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
++	if (IS_ERR(handle)) {
+ 		return PTR_ERR(handle);
++	}
+ 
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+@@ -1071,14 +2174,33 @@ static int ext3_rename (struct inode * o
+ 	/*
+ 	 * ok, that's it
+ 	 */
+-	ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	retval = ext3_delete_entry(handle, old_dir, old_de, old_bh);
++	if (retval == -ENOENT) {
++		/*
++		 * old_de could have moved out from under us.
++		 */
++		struct buffer_head *old_bh2;
++		struct ext3_dir_entry_2 *old_de2;
++		
++		old_bh2 = ext3_find_entry(old_dentry, &old_de2);
++		if (old_bh2) {
++			retval = ext3_delete_entry(handle, old_dir,
++						   old_de2, old_bh2);
++			brelse(old_bh2);
++		}
++	}
++	if (retval) {
++		ext3_warning(old_dir->i_sb, "ext3_rename",
++				"Deleting old file (%lu), %d, error=%d",
++				old_dir->i_ino, old_dir->i_nlink, retval);
++	}
+ 
+ 	if (new_inode) {
+ 		new_inode->i_nlink--;
+ 		new_inode->i_ctime = CURRENT_TIME;
+ 	}
+ 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+-	old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++	ext3_update_dx_flag(old_dir);
+ 	if (dir_bh) {
+ 		BUFFER_TRACE(dir_bh, "get_write_access");
+ 		ext3_journal_get_write_access(handle, dir_bh);
+@@ -1090,7 +2212,7 @@ static int ext3_rename (struct inode * o
+ 			new_inode->i_nlink--;
+ 		} else {
+ 			new_dir->i_nlink++;
+-			new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
++			ext3_update_dx_flag(new_dir);
+ 			ext3_mark_inode_dirty(handle, new_dir);
+ 		}
+ 	}
+--- linux-2.4.18-chaos-pdirops/fs/ext3/super.c~ext3-htree	2003-09-23 11:52:24.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/fs/ext3/super.c	2003-09-23 12:11:54.000000000 +0400
+@@ -705,6 +705,7 @@ static int ext3_setup_super(struct super
+ 	es->s_mtime = cpu_to_le32(CURRENT_TIME);
+ 	ext3_update_dynamic_rev(sb);
+ 	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
++
+ 	ext3_commit_super (sb, es, 1);
+ 	if (test_opt (sb, DEBUG))
+ 		printk (KERN_INFO
+@@ -715,6 +716,7 @@ static int ext3_setup_super(struct super
+ 			EXT3_BLOCKS_PER_GROUP(sb),
+ 			EXT3_INODES_PER_GROUP(sb),
+ 			sbi->s_mount_opt);
++
+ 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
+ 				bdevname(sb->s_dev));
+ 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+@@ -889,6 +891,7 @@ static loff_t ext3_max_size(int bits)
+ 	return res;
+ }
+ 
++
+ struct super_block * ext3_read_super (struct super_block * sb, void * data,
+ 				      int silent)
+ {
+@@ -1065,6 +1068,9 @@ struct super_block * ext3_read_super (st
+ 	sbi->s_mount_state = le16_to_cpu(es->s_state);
+ 	sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
+ 	sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
++	for (i=0; i < 4; i++)
++		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
++	sbi->s_def_hash_version = es->s_def_hash_version;
+ 
+ 	if (sbi->s_blocks_per_group > blocksize * 8) {
+ 		printk (KERN_ERR
+@@ -1747,6 +1753,7 @@ static void __exit exit_ext3_fs(void)
+ 	unregister_filesystem(&ext3_fs_type);
+ }
+ 
++EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_fs.h~ext3-htree	2003-07-28 17:52:17.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_fs.h	2003-09-23 12:12:04.000000000 +0400
+@@ -40,6 +40,11 @@
+ #define EXT3FS_VERSION		"2.4-0.9.18"
+ 
+ /*
++ * Always enable hashed directories
++ */
++#define CONFIG_EXT3_INDEX
++
++/*
+  * Debug code
+  */
+ #ifdef EXT3FS_DEBUG
+@@ -437,8 +442,11 @@ struct ext3_super_block {
+ /*E0*/	__u32	s_journal_inum;		/* inode number of journal file */
+ 	__u32	s_journal_dev;		/* device number of journal file */
+ 	__u32	s_last_orphan;		/* start of list of inodes to delete */
+-
+-/*EC*/	__u32	s_reserved[197];	/* Padding to the end of the block */
++	__u32	s_hash_seed[4];		/* HTREE hash seed */
++	__u8	s_def_hash_version;	/* Default hash version to use */
++	__u8	s_reserved_char_pad;
++	__u16	s_reserved_word_pad;
++	__u32	s_reserved[192];	/* Padding to the end of the block */
+ };
+ 
+ #ifdef __KERNEL__
+@@ -575,9 +583,46 @@ struct ext3_dir_entry_2 {
+ #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
+ #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
+ 					 ~EXT3_DIR_ROUND)
++/*
++ * Hash Tree Directory indexing
++ * (c) Daniel Phillips, 2001
++ */
++
++#ifdef CONFIG_EXT3_INDEX
++  #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
++					      EXT3_FEATURE_COMPAT_DIR_INDEX) && \
++		      (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
++#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
++#else
++  #define is_dx(dir) 0
++#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
++#endif
++
++/* Legal values for the dx_root hash_version field: */
++
++#define DX_HASH_LEGACY		0
++#define DX_HASH_HALF_MD4	1
++#define DX_HASH_TEA		2
++
++/* hash info structure used by the directory hash */
++struct dx_hash_info
++{
++	u32		hash;
++	u32		minor_hash;
++	int		hash_version;
++	u32		*seed;
++};
+ 
+ #ifdef __KERNEL__
+ /*
++ * Control parameters used by ext3_htree_next_block
++ */
++#define HASH_NB_ALWAYS		1
++
++
++/*
+  * Describe an inode's exact location on disk and in memory
+  */
+ struct ext3_iloc
+@@ -587,6 +632,27 @@ struct ext3_iloc
+ 	unsigned long block_group;
+ };
+ 
++
++/*
++ * This structure is stuffed into the struct file's private_data field
++ * for directories.  It is where we put information so that we can do
++ * readdir operations in hash tree order.
++ */
++struct dir_private_info {
++	rb_root_t	root;
++	rb_node_t	*curr_node;
++	struct fname	*extra_fname;
++	loff_t		last_pos;
++	__u32		curr_hash;
++	__u32		curr_minor_hash;
++	__u32		next_hash;
++};
++
++/*
++ * Special error return code only used by dx_probe() and its callers.
++ */
++#define ERR_BAD_DX_DIR	-75000
++
+ /*
+  * Function prototypes
+  */
+@@ -614,11 +680,20 @@ extern struct ext3_group_desc * ext3_get
+ 
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
+-				struct ext3_dir_entry_2 *, struct buffer_head *,
+-				unsigned long);
++				struct ext3_dir_entry_2 *,
++				struct buffer_head *, unsigned long);
++extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
++				    __u32 minor_hash,
++				    struct ext3_dir_entry_2 *dirent);
++extern void ext3_htree_free_dir_info(struct dir_private_info *p);
++
+ /* fsync.c */
+ extern int ext3_sync_file (struct file *, struct dentry *, int);
+ 
++/* hash.c */
++extern int ext3fs_dirhash(const char *name, int len, struct
++			  dx_hash_info *hinfo);
++
+ /* ialloc.c */
+ extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+@@ -650,6 +725,8 @@ extern int ext3_ioctl (struct inode *, s
+ /* namei.c */
+ extern int ext3_orphan_add(handle_t *, struct inode *);
+ extern int ext3_orphan_del(handle_t *, struct inode *);
++extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
++				__u32 start_minor_hash, __u32 *next_hash);
+ 
+ /* super.c */
+ extern void ext3_error (struct super_block *, const char *, const char *, ...)
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_fs_sb.h~ext3-htree	2003-07-28 17:52:17.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_fs_sb.h	2003-09-23 12:11:54.000000000 +0400
+@@ -62,6 +62,8 @@ struct ext3_sb_info {
+ 	int s_inode_size;
+ 	int s_first_ino;
+ 	u32 s_next_generation;
++	u32 s_hash_seed[4];
++	int s_def_hash_version;
+ 
+ 	/* Journaling */
+ 	struct inode * s_journal_inode;
+--- linux-2.4.18-chaos-pdirops/include/linux/ext3_jbd.h~ext3-htree	2001-12-21 20:42:03.000000000 +0300
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/ext3_jbd.h	2003-09-23 12:11:54.000000000 +0400
+@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s
+ 
+ #define EXT3_RESERVE_TRANS_BLOCKS	12
+ 
++#define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
++
+ int
+ ext3_mark_iloc_dirty(handle_t *handle, 
+ 		     struct inode *inode,
+--- linux-2.4.18-chaos-pdirops/include/linux/rbtree.h~ext3-htree	2001-11-22 22:46:18.000000000 +0300
++++ linux-2.4.18-chaos-pdirops-alexey/include/linux/rbtree.h	2003-09-23 12:11:54.000000000 +0400
+@@ -120,6 +120,8 @@ rb_root_t;
+ 
+ extern void rb_insert_color(rb_node_t *, rb_root_t *);
+ extern void rb_erase(rb_node_t *, rb_root_t *);
++extern rb_node_t *rb_get_first(rb_root_t *root);
++extern rb_node_t *rb_get_next(rb_node_t *n);
+ 
+ static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
+ {
+--- linux-2.4.18-chaos-pdirops/lib/rbtree.c~ext3-htree	2003-09-23 11:52:34.000000000 +0400
++++ linux-2.4.18-chaos-pdirops-alexey/lib/rbtree.c	2003-09-23 12:11:54.000000000 +0400
+@@ -17,6 +17,8 @@
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+   linux/lib/rbtree.c
++
++  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+ */
+ 
+ #include <linux/rbtree.h>
+@@ -295,3 +297,43 @@ void rb_erase(rb_node_t * node, rb_root_
+ 		__rb_erase_color(child, parent, root);
+ }
+ EXPORT_SYMBOL(rb_erase);
++
++/*
++ * This function returns the first node (in sort order) of the tree.
++ */
++rb_node_t *rb_get_first(rb_root_t *root)
++{
++	rb_node_t	*n;
++
++	n = root->rb_node;
++	if (!n)
++		return 0;
++	while (n->rb_left)
++		n = n->rb_left;
++	return n;
++}
++EXPORT_SYMBOL(rb_get_first);
++
++/*
++ * Given a node, this function will return the next node in the tree.
++ */
++rb_node_t *rb_get_next(rb_node_t *n)
++{
++	rb_node_t	*parent;
++
++	if (n->rb_right) {
++		n = n->rb_right;
++		while (n->rb_left)
++			n = n->rb_left;
++		return n;
++	} else {
++		while ((parent = n->rb_parent)) {
++			if (n == parent->rb_left)
++				return parent;
++			n = parent;
++		}
++		return 0;
++	}
++}
++EXPORT_SYMBOL(rb_get_next);
++
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.18.patch b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.18.patch
new file mode 100644
index 0000000000000000000000000000000000000000..85e12b893f03c4eb5c99d803d3cb7334aadf5527
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.18.patch
@@ -0,0 +1,350 @@
+Index: linux-2.4.18-chaos/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/ialloc.c	2003-10-22 14:23:53.000000000 +0400
++++ linux-2.4.18-chaos/fs/ext3/ialloc.c	2003-10-29 20:42:04.000000000 +0300
+@@ -241,11 +241,16 @@
+ 
+ 	bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
+ 
+-	BUFFER_TRACE(bh, "get_write_access");
+-	fatal = ext3_journal_get_write_access(handle, bh);
++	BUFFER_TRACE(bh, "get_undo_access");
++	fatal = ext3_journal_get_undo_access(handle, bh);
+ 	if (fatal)
+ 		goto error_return;
+ 
++	/* to prevent inode reusing within single transaction -bzzz */
++	BUFFER_TRACE(bh, "clear in b_committed_data");
++	J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data != NULL);
++	ext3_set_bit(bit, bh2jh(bh)->b_committed_data);
++
+ 	/* Ok, now we can actually update the inode bitmaps.. */
+ 	if (!ext3_clear_bit (bit, bh->b_data))
+ 		ext3_error (sb, "ext3_free_inode",
+@@ -319,6 +324,131 @@
+ 	return 0;
+ }
+ 
++static int ext3_test_allocatable(int nr, struct buffer_head *bh)
++{
++	if (ext3_test_bit(nr, bh->b_data))
++		return 0;
++	if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
++		return 1;
++#if 0
++	if (!ext3_test_bit(nr, bh2jh(bh)->b_committed_data))
++		printk("EXT3-fs: inode %d was used\n", nr);
++#endif
++	return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
++}
++
++int ext3_find_group_dir(const struct inode *dir,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	struct super_block *sb = dir->i_sb;
++	struct ext3_super_block *es;
++	struct ext3_group_desc *tmp;
++	int i = 0, j, avefreei;
++
++	es = EXT3_SB(sb)->s_es;
++	avefreei = le32_to_cpu(es->s_free_inodes_count) /
++			EXT3_SB(sb)->s_groups_count;
++	for (j = 0; j < EXT3_SB(sb)->s_groups_count; j++) {
++		struct buffer_head *temp_buffer;
++		tmp = ext3_get_group_desc(sb, j, &temp_buffer);
++		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) &&
++			le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) {
++			if (!*gdp || (le16_to_cpu(tmp->bg_free_blocks_count) >
++				le16_to_cpu((*gdp)->bg_free_blocks_count))) {
++				i = j;
++				*gdp = tmp;
++				*bh = temp_buffer;
++			}
++		}
++	}
++
++	return i;
++}
++
++int ext3_find_group_other(const struct inode *dir,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	struct super_block *sb = dir->i_sb;
++	struct ext3_group_desc *tmp;
++	int i, j;
++
++	/*
++	 * Try to place the inode in its parent directory
++	 */
++	i = EXT3_I(dir)->i_block_group;
++	tmp = ext3_get_group_desc(sb, i, bh);
++	if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
++		*gdp = tmp;
++	else {
++		/*
++		 * Use a quadratic hash to find a group with a
++		 * free inode
++		 */
++		for (j = 1; j < EXT3_SB(sb)->s_groups_count; j <<= 1) {
++			i += j;
++			if (i >= EXT3_SB(sb)->s_groups_count)
++				i -= EXT3_SB(sb)->s_groups_count;
++			tmp = ext3_get_group_desc (sb, i, bh);
++			if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
++				*gdp = tmp;
++				break;
++			}
++		}
++	}
++	if (!*gdp) {
++		/*
++		 * That failed: try linear search for a free inode
++		 */
++		i = EXT3_I(dir)->i_block_group + 1;
++		for (j = 2; j < EXT3_SB(sb)->s_groups_count; j++) {
++			if (++i >= EXT3_SB(sb)->s_groups_count)
++				i = 0;
++			tmp = ext3_get_group_desc (sb, i, bh);
++			if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
++				*gdp = tmp;
++				break;
++			}
++		}
++	}
++
++	return i;
++}
++
++static int ext3_find_group(const struct inode *dir, int mode,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	if (S_ISDIR(mode))
++		return ext3_find_group_dir(dir, gdp, bh);
++	return ext3_find_group_other(dir, gdp, bh);
++}
++
++static int ext3_find_usable_inode(struct super_block *sb,
++					struct buffer_head *bh)
++{
++	int here, maxinodes, next;
++
++	maxinodes = EXT3_INODES_PER_GROUP(sb);
++	here = 0;	
++
++	while (here < maxinodes) {
++		next  = ext3_find_next_zero_bit((unsigned long *) bh->b_data, 
++						 maxinodes, here);
++		if (next >= maxinodes)
++			return -1;
++		if (ext3_test_allocatable(next, bh))
++			return next;
++
++		J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data);
++		here = ext3_find_next_zero_bit
++			((unsigned long *) bh2jh(bh)->b_committed_data, 
++			 maxinodes, next);
++	}
++	return -1;
++}
++
+ /*
+  * There are two policies for allocating an inode.  If the new inode is
+  * a directory, then a forward search is made for a block group with both
+@@ -337,7 +467,7 @@
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+ 	struct buffer_head * bh2;
+-	int i, j, avefreei;
++	int i, j, k;
+ 	struct inode * inode;
+ 	int bitmap_nr;
+ 	struct ext3_inode_info *ei;
+@@ -376,11 +506,12 @@
+ 
+ 		bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
+ 
+-		BUFFER_TRACE(bh, "get_write_access");
+-		err = ext3_journal_get_write_access(handle, bh);
++		BUFFER_TRACE(bh, "get_undo_access");
++		err = ext3_journal_get_undo_access(handle, bh);
+ 		if (err) goto fail;
+ 
+-		if (ext3_set_bit(j, bh->b_data)) {
++		if (!ext3_test_allocatable(j, bh) ||
++				ext3_set_bit(j, bh->b_data)) {
+ 			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
+ 			/* Oh well, we tried. */
+ 			goto repeat;
+@@ -398,119 +529,68 @@
+ 
+ repeat:
+ 	gdp = NULL;
+-	i = 0;
+-
+-	if (S_ISDIR(mode)) {
+-		avefreei = le32_to_cpu(es->s_free_inodes_count) /
+-			sbi->s_groups_count;
+-		if (!gdp) {
+-			for (j = 0; j < sbi->s_groups_count; j++) {
+-				struct buffer_head *temp_buffer;
+-				tmp = ext3_get_group_desc (sb, j, &temp_buffer);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count) &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count) >=
+-							avefreei) {
+-					if (!gdp || (le16_to_cpu(tmp->bg_free_blocks_count) >
+-						le16_to_cpu(gdp->bg_free_blocks_count))) {
+-						i = j;
+-						gdp = tmp;
+-						bh2 = temp_buffer;
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-		/*
+-		 * Try to place the inode in its parent directory
+-		 */
+-		i = EXT3_I(dir)->i_block_group;
+-		tmp = ext3_get_group_desc (sb, i, &bh2);
+-		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
+-			gdp = tmp;
+-		else
+-		{
+-			/*
+-			 * Use a quadratic hash to find a group with a
+-			 * free inode
+-			 */
+-			for (j = 1; j < sbi->s_groups_count; j <<= 1) {
+-				i += j;
+-				if (i >= sbi->s_groups_count)
+-					i -= sbi->s_groups_count;
+-				tmp = ext3_get_group_desc (sb, i, &bh2);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
+-					gdp = tmp;
+-					break;
+-				}
+-			}
+-		}
+-		if (!gdp) {
+-			/*
+-			 * That failed: try linear search for a free inode
+-			 */
+-			i = EXT3_I(dir)->i_block_group + 1;
+-			for (j = 2; j < sbi->s_groups_count; j++) {
+-				if (++i >= sbi->s_groups_count)
+-					i = 0;
+-				tmp = ext3_get_group_desc (sb, i, &bh2);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
+-					gdp = tmp;
+-					break;
+-				}
+-			}
+-		}
+-	}
+ 
++	/* choose group */
++	i = ext3_find_group(dir, mode, &gdp, &bh2);
+ 	err = -ENOSPC;
+ 	if (!gdp)
+ 		goto out;
+-
++	
+ 	err = -EIO;
+-	bitmap_nr = load_inode_bitmap (sb, i);
++	bitmap_nr = load_inode_bitmap(sb, i);
+ 	if (bitmap_nr < 0)
+ 		goto fail;
+-
+ 	bh = sbi->s_inode_bitmap[bitmap_nr];
+ 
+-	if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
+-				      sbi->s_inodes_per_group)) <
+-	    sbi->s_inodes_per_group) {
+-		BUFFER_TRACE(bh, "get_write_access");
+-		err = ext3_journal_get_write_access(handle, bh);
+-		if (err) goto fail;
+-		
+-		if (ext3_set_bit (j, bh->b_data)) {
+-			ext3_error (sb, "ext3_new_inode",
+-				      "bit already set for inode %d", j);
+-			goto repeat;
+-		}
+-		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-		err = ext3_journal_dirty_metadata(handle, bh);
+-		if (err) goto fail;
+-	} else {
+-		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
+-			ext3_error (sb, "ext3_new_inode",
+-				    "Free inodes count corrupted in group %d",
+-				    i);
+-			/* Is it really ENOSPC? */
+-			err = -ENOSPC;
+-			if (sb->s_flags & MS_RDONLY)
+-				goto fail;
+-
+-			BUFFER_TRACE(bh2, "get_write_access");
+-			err = ext3_journal_get_write_access(handle, bh2);
+-			if (err) goto fail;
+-			gdp->bg_free_inodes_count = 0;
+-			BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
+-			err = ext3_journal_dirty_metadata(handle, bh2);
+-			if (err) goto fail;
++	/* try to allocate in selected group */
++	if ((j = ext3_find_usable_inode(sb, bh)) >= 0)
++		goto find_free;
++
++	/* can't allocate: try to allocate in ANY another groups */
++	k = i;
++	err = -EIO;
++	for (i = i + 1; i != k; i++) {
++		if (i >= sbi->s_groups_count)
++			i = 0;
++		tmp = ext3_get_group_desc(sb, i, &bh2);
++		if (le16_to_cpu(tmp->bg_free_inodes_count) == 0)
++			continue;
++
++		bitmap_nr = load_inode_bitmap(sb, i);
++		if (bitmap_nr < 0)
++			goto fail;
++		bh = sbi->s_inode_bitmap[bitmap_nr];
++
++		/* try to allocate in selected group */
++		if ((j = ext3_find_usable_inode(sb, bh)) >= 0) {
++			gdp = tmp;
++			break;
+ 		}
+-		goto repeat;
+ 	}
++	err = -ENOSPC;
++	if (!gdp)
++		goto out;
++
++ find_free:
++	BUFFER_TRACE(bh, "get_undo_access");
++	err = ext3_journal_get_undo_access(handle, bh);
++	if (err)
++		goto fail;
++
++	if (ext3_set_bit(j, bh->b_data)) {
++		ext3_error (sb, "ext3_new_inode",
++				"bit already set for inode %d", j);
++		goto fail; 
++	}
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		goto fail;
++	
+  have_bit_and_group:
++	if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data)
++		J_ASSERT_BH(bh, !ext3_test_bit(j, bh2jh(bh)->b_committed_data));
++
+ 	j += i * EXT3_INODES_PER_GROUP(sb) + 1;
+ 	if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
+ 		ext3_error (sb, "ext3_new_inode",
diff --git a/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.20.patch b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..18c69ffe4f3075dcc8cb48d3483f22551136b9b3
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.20.patch
@@ -0,0 +1,352 @@
+Index: linux-2.4.20/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/ialloc.c	2003-10-25 00:37:13.000000000 +0400
++++ linux-2.4.20/fs/ext3/ialloc.c	2003-10-29 20:33:33.000000000 +0300
+@@ -241,11 +241,16 @@
+ 
+ 	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
+ 
+-	BUFFER_TRACE(bh, "get_write_access");
+-	fatal = ext3_journal_get_write_access(handle, bh);
++	BUFFER_TRACE(bh, "get_undo_access");
++	fatal = ext3_journal_get_undo_access(handle, bh);
+ 	if (fatal)
+ 		goto error_return;
+ 
++	/* to prevent inode reusing within single transaction -bzzz */
++	BUFFER_TRACE(bh, "clear in b_committed_data");
++	J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data != NULL);
++	ext3_set_bit(bit, bh2jh(bh)->b_committed_data);
++
+ 	/* Ok, now we can actually update the inode bitmaps.. */
+ 	if (!ext3_clear_bit (bit, bh->b_data))
+ 		ext3_error (sb, "ext3_free_inode",
+@@ -319,6 +324,131 @@
+ 	return 0;
+ }
+ 
++static int ext3_test_allocatable(int nr, struct buffer_head *bh)
++{
++	if (ext3_test_bit(nr, bh->b_data))
++		return 0;
++	if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
++		return 1;
++#if 0
++	if (!ext3_test_bit(nr, bh2jh(bh)->b_committed_data))
++		printk("EXT3-fs: inode %d was used\n", nr);
++#endif
++	return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
++}
++
++int ext3_find_group_dir(const struct inode *dir,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	struct super_block *sb = dir->i_sb;
++	struct ext3_super_block *es;
++	struct ext3_group_desc *tmp;
++	int i = 0, j, avefreei;
++
++	es = EXT3_SB(sb)->s_es;
++	avefreei = le32_to_cpu(es->s_free_inodes_count) /
++			sb->u.ext3_sb.s_groups_count;
++	for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) {
++		struct buffer_head *temp_buffer;
++		tmp = ext3_get_group_desc(sb, j, &temp_buffer);
++		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) &&
++			le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) {
++			if (!*gdp || (le16_to_cpu(tmp->bg_free_blocks_count) >
++				le16_to_cpu((*gdp)->bg_free_blocks_count))) {
++				i = j;
++				*gdp = tmp;
++				*bh = temp_buffer;
++			}
++		}
++	}
++
++	return i;
++}
++
++int ext3_find_group_other(const struct inode *dir,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	struct super_block *sb = dir->i_sb;
++	struct ext3_group_desc *tmp;
++	int i, j;
++
++	/*
++	 * Try to place the inode in its parent directory
++	 */
++	i = dir->u.ext3_i.i_block_group;
++	tmp = ext3_get_group_desc(sb, i, bh);
++	if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
++		*gdp = tmp;
++	else {
++		/*
++		 * Use a quadratic hash to find a group with a
++		 * free inode
++		 */
++		for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) {
++			i += j;
++			if (i >= sb->u.ext3_sb.s_groups_count)
++				i -= sb->u.ext3_sb.s_groups_count;
++			tmp = ext3_get_group_desc (sb, i, bh);
++			if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
++				*gdp = tmp;
++				break;
++			}
++		}
++	}
++	if (!*gdp) {
++		/*
++		 * That failed: try linear search for a free inode
++		 */
++		i = dir->u.ext3_i.i_block_group + 1;
++		for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) {
++			if (++i >= sb->u.ext3_sb.s_groups_count)
++				i = 0;
++			tmp = ext3_get_group_desc (sb, i, bh);
++			if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
++				*gdp = tmp;
++				break;
++			}
++		}
++	}
++
++	return i;
++}
++
++static int ext3_find_group(const struct inode *dir, int mode,
++				struct ext3_group_desc **gdp,
++				struct buffer_head **bh)
++{
++	if (S_ISDIR(mode))
++		return ext3_find_group_dir(dir, gdp, bh);
++	return ext3_find_group_other(dir, gdp, bh);
++}
++
++static int ext3_find_usable_inode(struct super_block *sb,
++					struct buffer_head *bh)
++{
++	int here, maxinodes, next;
++
++	maxinodes = EXT3_INODES_PER_GROUP(sb);
++	here = 0;	
++
++	while (here < maxinodes) {
++		next  = ext3_find_next_zero_bit((unsigned long *) bh->b_data, 
++						 maxinodes, here);
++		if (next >= maxinodes)
++			return -1;
++		if (ext3_test_allocatable(next, bh))
++			return next;
++
++		J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data);
++		here = ext3_find_next_zero_bit
++			((unsigned long *) bh2jh(bh)->b_committed_data, 
++			 maxinodes, next);
++	}
++	return -1;
++}
++
+ /*
+  * There are two policies for allocating an inode.  If the new inode is
+  * a directory, then a forward search is made for a block group with both
+@@ -336,7 +466,7 @@
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+ 	struct buffer_head * bh2;
+-	int i, j, avefreei;
++	int i, j, k;
+ 	struct inode * inode;
+ 	int bitmap_nr;
+ 	struct ext3_group_desc * gdp;
+@@ -371,11 +501,12 @@
+ 
+ 		bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
+ 
+-		BUFFER_TRACE(bh, "get_write_access");
+-		err = ext3_journal_get_write_access(handle, bh);
++		BUFFER_TRACE(bh, "get_undo_access");
++		err = ext3_journal_get_undo_access(handle, bh);
+ 		if (err) goto fail;
+ 
+-		if (ext3_set_bit(j, bh->b_data)) {
++		if (!ext3_test_allocatable(j, bh) ||
++				ext3_set_bit(j, bh->b_data)) {
+ 			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
+ 			/* Oh well, we tried. */
+ 			goto repeat;
+@@ -393,119 +524,70 @@
+ 
+ repeat:
+ 	gdp = NULL;
+-	i = 0;
+-
+-	if (S_ISDIR(mode)) {
+-		avefreei = le32_to_cpu(es->s_free_inodes_count) /
+-			sb->u.ext3_sb.s_groups_count;
+-		if (!gdp) {
+-			for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) {
+-				struct buffer_head *temp_buffer;
+-				tmp = ext3_get_group_desc (sb, j, &temp_buffer);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count) &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count) >=
+-							avefreei) {
+-					if (!gdp || (le16_to_cpu(tmp->bg_free_blocks_count) >
+-						le16_to_cpu(gdp->bg_free_blocks_count))) {
+-						i = j;
+-						gdp = tmp;
+-						bh2 = temp_buffer;
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-		/*
+-		 * Try to place the inode in its parent directory
+-		 */
+-		i = dir->u.ext3_i.i_block_group;
+-		tmp = ext3_get_group_desc (sb, i, &bh2);
+-		if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
+-			gdp = tmp;
+-		else
+-		{
+-			/*
+-			 * Use a quadratic hash to find a group with a
+-			 * free inode
+-			 */
+-			for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) {
+-				i += j;
+-				if (i >= sb->u.ext3_sb.s_groups_count)
+-					i -= sb->u.ext3_sb.s_groups_count;
+-				tmp = ext3_get_group_desc (sb, i, &bh2);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
+-					gdp = tmp;
+-					break;
+-				}
+-			}
+-		}
+-		if (!gdp) {
+-			/*
+-			 * That failed: try linear search for a free inode
+-			 */
+-			i = dir->u.ext3_i.i_block_group + 1;
+-			for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) {
+-				if (++i >= sb->u.ext3_sb.s_groups_count)
+-					i = 0;
+-				tmp = ext3_get_group_desc (sb, i, &bh2);
+-				if (tmp &&
+-				    le16_to_cpu(tmp->bg_free_inodes_count)) {
+-					gdp = tmp;
+-					break;
+-				}
+-			}
+-		}
+-	}
+ 
++	/* choose group */
++	i = ext3_find_group(dir, mode, &gdp, &bh2);
+ 	err = -ENOSPC;
+ 	if (!gdp)
+ 		goto out;
+-
++	
+ 	err = -EIO;
+-	bitmap_nr = load_inode_bitmap (sb, i);
++	bitmap_nr = load_inode_bitmap(sb, i);
+ 	if (bitmap_nr < 0)
+ 		goto fail;
+-
+ 	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
+ 
+-	if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
+-				      EXT3_INODES_PER_GROUP(sb))) <
+-	    EXT3_INODES_PER_GROUP(sb)) {
+-		BUFFER_TRACE(bh, "get_write_access");
+-		err = ext3_journal_get_write_access(handle, bh);
+-		if (err) goto fail;
+-		
+-		if (ext3_set_bit (j, bh->b_data)) {
+-			ext3_error (sb, "ext3_new_inode",
+-				      "bit already set for inode %d", j);
+-			goto repeat;
+-		}
+-		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-		err = ext3_journal_dirty_metadata(handle, bh);
+-		if (err) goto fail;
+-	} else {
+-		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
+-			ext3_error (sb, "ext3_new_inode",
+-				    "Free inodes count corrupted in group %d",
+-				    i);
+-			/* Is it really ENOSPC? */
+-			err = -ENOSPC;
+-			if (sb->s_flags & MS_RDONLY)
+-				goto fail;
+-
+-			BUFFER_TRACE(bh2, "get_write_access");
+-			err = ext3_journal_get_write_access(handle, bh2);
+-			if (err) goto fail;
+-			gdp->bg_free_inodes_count = 0;
+-			BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
+-			err = ext3_journal_dirty_metadata(handle, bh2);
+-			if (err) goto fail;
++	/* try to allocate in selected group */
++	j = ext3_find_usable_inode(sb, bh);
++	err = -ENOSPC;
++	if (j >= 0)
++		goto found_free;
++
++	/* can't allocate: try to allocate in ANY another groups */
++	k = i;
++	err = -EIO;
++	for (i = i + 1; i != k; i++) {
++		if (i >= sb->u.ext3_sb.s_groups_count)
++			i = 0;
++		tmp = ext3_get_group_desc(sb, i, &bh2);
++		if (le16_to_cpu(tmp->bg_free_inodes_count) == 0)
++			continue;
++
++		bitmap_nr = load_inode_bitmap(sb, i);
++		if (bitmap_nr < 0)
++			goto fail;
++		bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
++
++		/* try to allocate in selected group */
++		if ((j = ext3_find_usable_inode(sb, bh)) >= 0) {
++			gdp = tmp;
++			break;
+ 		}
+-		goto repeat;
+ 	}
++	err = -ENOSPC;
++	if (!gdp)
++		goto out;
++
++ found_free:
++	BUFFER_TRACE(bh, "get_undo_access");
++	err = ext3_journal_get_undo_access(handle, bh);
++	if (err)
++		goto fail;
++
++	if (ext3_set_bit(j, bh->b_data)) {
++		ext3_error (sb, "ext3_new_inode",
++				"bit already set for inode %d", j);
++		goto fail; 
++	}
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		goto fail;
++	
+  have_bit_and_group:
++	if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data)
++		J_ASSERT_BH(bh, !ext3_test_bit(j, bh2jh(bh)->b_committed_data));
++
+ 	j += i * EXT3_INODES_PER_GROUP(sb) + 1;
+ 	if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
+ 		ext3_error (sb, "ext3_new_inode",
diff --git a/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.22.patch b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2bbebbf9d881d5bcfa6a8f0260aaa3851b0d8d51
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.22.patch
@@ -0,0 +1,187 @@
+Index: linux-2.4.22-ac1/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.22-ac1.orig/fs/ext3/ialloc.c	2003-10-22 14:20:03.000000000 +0400
++++ linux-2.4.22-ac1/fs/ext3/ialloc.c	2003-10-29 22:32:28.000000000 +0300
+@@ -242,11 +242,16 @@
+ 
+ 	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
+ 
+-	BUFFER_TRACE(bh, "get_write_access");
+-	fatal = ext3_journal_get_write_access(handle, bh);
++	BUFFER_TRACE(bh, "get_undo_access");
++	fatal = ext3_journal_get_undo_access(handle, bh);
+ 	if (fatal)
+ 		goto error_return;
+ 
++	/* to prevent inode reusing within single transaction -bzzz */
++	BUFFER_TRACE(bh, "clear in b_committed_data");
++	J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data != NULL);
++	ext3_set_bit(bit, bh2jh(bh)->b_committed_data);
++
+ 	/* Ok, now we can actually update the inode bitmaps.. */
+ 	if (!ext3_clear_bit (bit, bh->b_data))
+ 		ext3_error (sb, "ext3_free_inode",
+@@ -320,6 +325,43 @@
+ 	return 0;
+ }
+ 
++static int ext3_test_allocatable(int nr, struct buffer_head *bh)
++{
++	if (ext3_test_bit(nr, bh->b_data))
++		return 0;
++	if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
++		return 1;
++#if 0
++	if (!ext3_test_bit(nr, bh2jh(bh)->b_committed_data))
++		printk("EXT3-fs: inode %d was used\n", nr);
++#endif
++	return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
++}
++
++static int ext3_find_usable_inode(struct super_block *sb,
++					struct buffer_head *bh)
++{
++	int here, maxinodes, next;
++
++	maxinodes = EXT3_INODES_PER_GROUP(sb);
++	here = 0;	
++
++	while (here < maxinodes) {
++		next  = ext3_find_next_zero_bit((unsigned long *) bh->b_data, 
++						 maxinodes, here);
++		if (next >= maxinodes)
++			return -1;
++		if (ext3_test_allocatable(next, bh))
++			return next;
++
++		J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data);
++		here = ext3_find_next_zero_bit
++			((unsigned long *) bh2jh(bh)->b_committed_data, 
++			 maxinodes, next);
++	}
++	return -1;
++}
++
+ /*
+  * There are two policies for allocating an inode.  If the new inode is
+  * a directory, then a forward search is made for a block group with both
+@@ -530,7 +572,7 @@
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+ 	struct buffer_head * bh2;
+-	int group;
++	int group, k;
+ 	ino_t ino;
+ 	struct inode * inode;
+ 	int bitmap_nr;
+@@ -569,7 +611,8 @@
+ 		err = ext3_journal_get_write_access(handle, bh);
+ 		if (err) goto fail;
+ 
+-		if (ext3_set_bit(ino, bh->b_data)) {
++		if (!ext3_test_allocatable(ino, bh) ||
++				ext3_set_bit(ino, bh->b_data)) {
+ 			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
+ 			/* Oh well, we tried. */
+ 			goto repeat;
+@@ -595,52 +638,63 @@
+ 		group = find_group_other(sb, dir);
+   
+ 	err = -ENOSPC;
+-	if (!group == -1)
++	if (group == -1)
+ 		goto out;
+ 
+ 	err = -EIO;
+-	bitmap_nr = load_inode_bitmap (sb, group);
++	bitmap_nr = load_inode_bitmap(sb, group);
+ 	if (bitmap_nr < 0)
+ 		goto fail;
+-
+ 	bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
+-	gdp = ext3_get_group_desc (sb, group, &bh2);
+ 
+-	if ((ino = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
+-				      EXT3_INODES_PER_GROUP(sb))) <
+-	    EXT3_INODES_PER_GROUP(sb)) {
+-		BUFFER_TRACE(bh, "get_write_access");
+-		err = ext3_journal_get_write_access(handle, bh);
+-		if (err) goto fail;
+-		
+-		if (ext3_set_bit (ino, bh->b_data)) {
+-			ext3_error (sb, "ext3_new_inode",
+-				      "bit already set for inode %lu", ino);
+-			goto repeat;
+-		}
+-		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+-		err = ext3_journal_dirty_metadata(handle, bh);
+-		if (err) goto fail;
+-	} else {
+-		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
+-			ext3_error (sb, "ext3_new_inode",
+-				    "Free inodes count corrupted in group %d",
+-				    group);
+-			/* Is it really ENOSPC? */
+-			err = -ENOSPC;
+-			if (sb->s_flags & MS_RDONLY)
+-				goto fail;
+-
+-			BUFFER_TRACE(bh2, "get_write_access");
+-			err = ext3_journal_get_write_access(handle, bh2);
+-			if (err) goto fail;
+-			gdp->bg_free_inodes_count = 0;
+-			BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
+-			err = ext3_journal_dirty_metadata(handle, bh2);
+-			if (err) goto fail;
++	/* try to allocate in selected group */
++	if ((ino = ext3_find_usable_inode(sb, bh)) >= 0)
++		goto find_free;
++
++	/* can't allocate: try to allocate in ANY another groups */
++	k = group;
++	gdp = NULL;
++	err = -EIO;
++	for (group = group + 1; group != k; group++) {
++		struct ext3_group_desc *tmp;
++
++		if (group >= sb->u.ext3_sb.s_groups_count)
++			group = 0;
++		tmp = ext3_get_group_desc(sb, group, &bh2);
++		if (le16_to_cpu(tmp->bg_free_inodes_count) == 0)
++			continue;
++
++		bitmap_nr = load_inode_bitmap(sb, group);
++		if (bitmap_nr < 0)
++			goto fail;
++		bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
++
++		/* try to allocate in selected group */
++		if ((ino = ext3_find_usable_inode(sb, bh)) >= 0) {
++			gdp = tmp;
++			break;
+ 		}
+-		goto repeat;
+ 	}
++	err = -ENOSPC;
++	if (!gdp)
++		goto out;
++
++find_free:
++	BUFFER_TRACE(bh, "get_undo_access");
++	err = ext3_journal_get_undo_access(handle, bh);
++	if (err)
++		goto fail;
++
++	if (ext3_set_bit(ino, bh->b_data)) {
++		ext3_error (sb, "ext3_new_inode",
++				"bit already set for inode %lu",
++				(unsigned long) ino);
++		goto fail; 
++	}
++	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++	err = ext3_journal_dirty_metadata(handle, bh);
++	if (err)
++		goto fail;
+ 
+ have_bit_and_group:
+ 	ino += group * EXT3_INODES_PER_GROUP(sb) + 1;
diff --git a/lustre/kernel_patches/patches/ext3-map_inode_page-2.6.0.patch b/lustre/kernel_patches/patches/ext3-map_inode_page-2.6.0.patch
new file mode 100644
index 0000000000000000000000000000000000000000..675d54ebff2e572a3292af1656d2caabf587d463
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-map_inode_page-2.6.0.patch
@@ -0,0 +1,76 @@
+ fs/ext3/inode.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/super.c |    3 +++
+ 2 files changed, 55 insertions(+)
+
+--- linux-2.6.0-test6/fs/ext3/inode.c~ext3-map_inode_page-2.6.0	2003-10-14 17:03:48.000000000 +0400
++++ linux-2.6.0-test6-alexey/fs/ext3/inode.c	2003-10-14 17:03:49.000000000 +0400
+@@ -3143,3 +3143,55 @@ int ext3_prep_san_write(struct inode *in
+ 		ret = ret2;
+ 	return ret;
+ }
++
++int ext3_map_inode_page(struct inode *inode, struct page *page,
++                        unsigned long *blocks, int *created, int create)
++{
++        unsigned int blocksize, blocks_per_page;
++        unsigned long iblock;
++        struct buffer_head dummy;
++        void *handle;
++        int i, rc = 0, failed = 0, needed_blocks;
++
++        blocksize = inode->i_sb->s_blocksize;
++        blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
++        iblock = page->index * blocks_per_page;
++
++        for (i = 0; i < blocks_per_page; i++, iblock++) {
++                blocks[i] = ext3_bmap(inode->i_mapping, iblock);
++                if (blocks[i] == 0) {
++                        failed++;
++                        created[i] = -1;
++                } else {
++                        created[i] = 0;
++                }
++        }
++
++        if (failed == 0 || create == 0)
++                return 0;
++
++        needed_blocks = ext3_writepage_trans_blocks(inode);
++        handle = ext3_journal_start(inode, needed_blocks);
++        if (IS_ERR(handle))
++                return PTR_ERR(handle);
++
++        iblock = page->index * blocks_per_page;
++        for (i = 0; i < blocks_per_page; i++, iblock++) {
++                if (blocks[i] != 0)
++                        continue;
++
++                rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1, 1);
++                if (rc) {
++                        printk(KERN_INFO "ext3_map_inode_page: error reading "
++                               "block %ld\n", iblock);
++                        goto out;
++                }
++                blocks[i] = dummy.b_blocknr;
++                created[i] = 1;
++        }
++
++ out:
++	ext3_journal_stop(handle);
++        return rc;
++}
++
+--- linux-2.6.0-test6/fs/ext3/super.c~ext3-map_inode_page-2.6.0	2003-10-14 17:03:48.000000000 +0400
++++ linux-2.6.0-test6-alexey/fs/ext3/super.c	2003-10-14 17:09:05.000000000 +0400
+@@ -2043,6 +2043,9 @@ static void __exit exit_ext3_fs(void)
+ int ext3_prep_san_write(struct inode *inode, long *blocks,
+                         int nblocks, loff_t newsize);
+ EXPORT_SYMBOL(ext3_prep_san_write);
++int ext3_map_inode_page(struct inode *inode, struct page *page,
++                        unsigned long *blocks, int *created, int create);
++EXPORT_SYMBOL(ext3_map_inode_page);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-map_inode_page.patch b/lustre/kernel_patches/patches/ext3-map_inode_page.patch
index 80f14de6a79cd9fdd1ce0a67e62e5ff59935f74e..675dc95c589826166e53a202c6178d0afe7cd521 100644
--- a/lustre/kernel_patches/patches/ext3-map_inode_page.patch
+++ b/lustre/kernel_patches/patches/ext3-map_inode_page.patch
@@ -5,25 +5,40 @@
  fs/ext3/inode.c        |   55 +++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 58 insertions(+)
 
---- linux-2.4.20-l18/fs/ext3/inode.c~ext3-map_inode_page	Tue Jul  8 20:07:23 2003
-+++ linux-2.4.20-l18-phil/fs/ext3/inode.c	Wed Jul  9 03:56:41 2003
-@@ -2867,3 +2867,58 @@ int ext3_prep_san_write(struct inode *in
+Index: lum/fs/ext3/inode.c
+===================================================================
+--- lum.orig/fs/ext3/inode.c	Sat Nov 22 16:38:51 2003
++++ lum/fs/ext3/inode.c	Fri Nov 28 00:37:18 2003
+@@ -2979,3 +2979,75 @@
  		ret = ret2;
  	return ret;
  }
 +
++/* copied from fs/buffer.c */
++static void unmap_underlying_metadata(struct buffer_head * bh)
++{
++	struct buffer_head *old_bh;
++
++	old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
++	if (old_bh) {
++		mark_buffer_clean(old_bh);
++		wait_on_buffer(old_bh);
++		clear_bit(BH_Req, &old_bh->b_state);
++		__brelse(old_bh);
++	}
++}
++
 +int ext3_map_inode_page(struct inode *inode, struct page *page,
 +                        unsigned long *blocks, int *created, int create)
 +{
 +        unsigned int blocksize, blocks_per_page;
 +        unsigned long iblock;
-+        struct buffer_head dummy;
 +        void *handle;
 +        int i, rc = 0, failed = 0, needed_blocks;
 +
 +        blocksize = inode->i_sb->s_blocksize;
 +        blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
-+        iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
++        iblock = page->index * blocks_per_page;
 +
 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
 +                blocks[i] = ext3_bmap(inode->i_mapping, iblock);
@@ -38,25 +53,29 @@
 +        if (failed == 0 || create == 0)
 +                return 0;
 +
-+        needed_blocks = ext3_writepage_trans_blocks(inode) * failed;
++        needed_blocks = ext3_writepage_trans_blocks(inode);
 +        lock_kernel();
 +        handle = ext3_journal_start(inode, needed_blocks);
 +        unlock_kernel();
 +        if (IS_ERR(handle))
 +                return PTR_ERR(handle);
 +
-+        iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
++        iblock = page->index * blocks_per_page;
 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
++                struct buffer_head bh;
++
 +                if (blocks[i] != 0)
 +                        continue;
 +
-+                rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1);
++                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
 +                if (rc) {
-+                        printk(KERN_INFO "ext3_map_inode_page: error reading "
-+                               "block %ld\n", iblock);
++                        printk(KERN_INFO "ext3_map_inode_page: error %d "
++                               "allocating block %ld\n", rc, iblock);
 +                        goto out;
 +                }
-+                blocks[i] = dummy.b_blocknr;
++                if (buffer_new(&bh))
++                        unmap_underlying_metadata(&bh);
++                blocks[i] = bh.b_blocknr;
 +                created[i] = 1;
 +        }
 +
@@ -66,8 +85,10 @@
 +	unlock_kernel();
 +        return rc;
 +}
---- linux-2.4.20-l18/fs/ext3/ext3-exports.c~ext3-map_inode_page	Tue Jul  8 20:07:10 2003
-+++ linux-2.4.20-l18-phil/fs/ext3/ext3-exports.c	Tue Jul  8 20:09:02 2003
+Index: lum/fs/ext3/ext3-exports.c
+===================================================================
+--- lum.orig/fs/ext3/ext3-exports.c	Sat Nov 22 16:38:51 2003
++++ lum/fs/ext3/ext3-exports.c	Sat Nov 22 16:38:51 2003
 @@ -9,6 +9,8 @@
  
  int ext3_prep_san_write(struct inode *inode, long *blocks,
@@ -77,7 +98,7 @@
  
  EXPORT_SYMBOL(ext3_force_commit);
  EXPORT_SYMBOL(ext3_bread);
-@@ -18,3 +20,4 @@ EXPORT_SYMBOL(ext3_xattr_get);
+@@ -18,3 +20,4 @@
  EXPORT_SYMBOL(ext3_xattr_list);
  EXPORT_SYMBOL(ext3_xattr_set);
  EXPORT_SYMBOL(ext3_prep_san_write);
diff --git a/lustre/kernel_patches/patches/ext3-map_inode_page_2.4.18.patch b/lustre/kernel_patches/patches/ext3-map_inode_page_2.4.18.patch
index 8386ee30e010f828b5a9d1e53f9dea81ffd6ce98..5c8ba4c44b1f147847191b42e9ec60964dd35f44 100644
--- a/lustre/kernel_patches/patches/ext3-map_inode_page_2.4.18.patch
+++ b/lustre/kernel_patches/patches/ext3-map_inode_page_2.4.18.patch
@@ -5,25 +5,58 @@
  fs/ext3/inode.c        |   55 +++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 58 insertions(+)
 
---- linux-2.4.18-p4smp/fs/ext3/inode.c~ext3-map_inode_page_2.4.18	2003-07-21 22:51:45.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c	2003-07-21 22:51:47.000000000 -0600
-@@ -3003,3 +3003,58 @@ int ext3_prep_san_write(struct inode *in
+Index: linux-2.4.18-p4smp/fs/ext3/ext3-exports.c
+===================================================================
+--- linux-2.4.18-p4smp.orig/fs/ext3/ext3-exports.c	Thu Nov 27 22:18:40 2003
++++ linux-2.4.18-p4smp/fs/ext3/ext3-exports.c	Thu Nov 27 22:18:40 2003
+@@ -9,6 +9,8 @@
+ 
+ int ext3_prep_san_write(struct inode *inode, long *blocks,
+ 	                int nblocks, loff_t newsize);
++int ext3_map_inode_page(struct inode *inode, struct page *page,
++                        unsigned long *block, int *created, int create);
+ 
+ EXPORT_SYMBOL(ext3_force_commit);
+ EXPORT_SYMBOL(ext3_bread);
+@@ -18,3 +20,4 @@
+ EXPORT_SYMBOL(ext3_xattr_list);
+ EXPORT_SYMBOL(ext3_xattr_set);
+ EXPORT_SYMBOL(ext3_prep_san_write);
++EXPORT_SYMBOL(ext3_map_inode_page);
+Index: linux-2.4.18-p4smp/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.18-p4smp.orig/fs/ext3/inode.c	Thu Nov 27 22:18:40 2003
++++ linux-2.4.18-p4smp/fs/ext3/inode.c	Thu Nov 27 22:20:36 2003
+@@ -3004,3 +3004,75 @@
  		ret = ret2;
  	return ret;
  }
 +
++/* copied from fs/buffer.c */
++static void unmap_underlying_metadata(struct buffer_head * bh)
++{
++        struct buffer_head *old_bh;
++
++        old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
++        if (old_bh) {
++                mark_buffer_clean(old_bh);
++                wait_on_buffer(old_bh);
++                clear_bit(BH_Req, &old_bh->b_state);
++                __brelse(old_bh);
++        }
++}
++
 +int ext3_map_inode_page(struct inode *inode, struct page *page,
 +                        unsigned long *blocks, int *created, int create)
 +{
 +        unsigned int blocksize, blocks_per_page;
 +        unsigned long iblock;
-+        struct buffer_head dummy;
 +        void *handle;
 +        int i, rc = 0, failed = 0, needed_blocks;
 +
 +        blocksize = inode->i_sb->s_blocksize;
 +        blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
-+        iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
++        iblock = page->index * blocks_per_page;
 +
 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
 +                blocks[i] = ext3_bmap(inode->i_mapping, iblock);
@@ -38,25 +71,29 @@
 +        if (failed == 0 || create == 0)
 +                return 0;
 +
-+        needed_blocks = ext3_writepage_trans_blocks(inode) * failed;
++        needed_blocks = ext3_writepage_trans_blocks(inode);
 +        lock_kernel();
 +        handle = ext3_journal_start(inode, needed_blocks);
 +        unlock_kernel();
 +        if (IS_ERR(handle))
 +                return PTR_ERR(handle);
 +
-+        iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
++        iblock = page->index * blocks_per_page;
 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
++                struct buffer_head bh;
++
 +                if (blocks[i] != 0)
 +                        continue;
 +
-+                rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1);
++                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
 +                if (rc) {
-+                        printk(KERN_INFO "ext3_map_inode_page: error reading "
-+                               "block %ld\n", iblock);
++                        printk(KERN_INFO "ext3_map_inode_page: error %d "
++                               "allocating block %ld\n", rc, iblock);
 +                        goto out;
 +                }
-+                blocks[i] = dummy.b_blocknr;
++                if (buffer_new(&bh))
++                        unmap_underlying_metadata(&bh);
++                blocks[i] = bh.b_blocknr;
 +                created[i] = 1;
 +        }
 +
@@ -66,21 +103,3 @@
 +	unlock_kernel();
 +        return rc;
 +}
---- linux-2.4.18-p4smp/fs/ext3/ext3-exports.c~ext3-map_inode_page_2.4.18	2003-07-21 22:51:45.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/ext3/ext3-exports.c	2003-07-21 22:51:47.000000000 -0600
-@@ -9,6 +9,8 @@
- 
- int ext3_prep_san_write(struct inode *inode, long *blocks,
- 	                int nblocks, loff_t newsize);
-+int ext3_map_inode_page(struct inode *inode, struct page *page,
-+                        unsigned long *block, int *created, int create);
- 
- EXPORT_SYMBOL(ext3_force_commit);
- EXPORT_SYMBOL(ext3_bread);
-@@ -18,3 +20,4 @@ EXPORT_SYMBOL(ext3_xattr_get);
- EXPORT_SYMBOL(ext3_xattr_list);
- EXPORT_SYMBOL(ext3_xattr_set);
- EXPORT_SYMBOL(ext3_prep_san_write);
-+EXPORT_SYMBOL(ext3_map_inode_page);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-no-write-super-chaos.patch b/lustre/kernel_patches/patches/ext3-no-write-super-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..37a5d7a4a9bf4498edb57a7bf6463a803b587606
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-no-write-super-chaos.patch
@@ -0,0 +1,15 @@
+ fs/ext3/super.c |    1 -
+ 1 files changed, 1 deletion(-)
+
+--- linux-2.4.18-chaos/fs/ext3/super.c~ext3-no-write-super-chaos	2003-08-24 21:34:53.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/ext3/super.c	2003-08-24 21:40:47.000000000 +0400
+@@ -1818,7 +1818,6 @@ void ext3_write_super (struct super_bloc
+ 	if (down_trylock(&sb->s_lock) == 0)
+ 		BUG();
+ 	sb->s_dirt = 0;
+-	log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+ }
+ 
+ static int ext3_sync_fs(struct super_block *sb)
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-no-write-super.patch b/lustre/kernel_patches/patches/ext3-no-write-super.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d2dcdae6893c946a02ee2a8cfd3eaff344bda721
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-no-write-super.patch
@@ -0,0 +1,22 @@
+ 0 files changed
+
+--- linux-2.4.20/fs/ext3/super.c~ext3-no-write-super	2003-08-11 13:20:17.000000000 +0400
++++ linux-2.4.20-alexey/fs/ext3/super.c	2003-08-11 13:31:35.000000000 +0400
+@@ -1849,7 +1849,6 @@ void ext3_write_super (struct super_bloc
+ 	if (down_trylock(&sb->s_lock) == 0)
+ 		BUG();		/* aviro detector */
+ 	sb->s_dirt = 0;
+-	target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+ 
+ 	/*
+ 	 * Tricky --- if we are unmounting, the write really does need
+@@ -1857,6 +1856,7 @@ void ext3_write_super (struct super_bloc
+ 	 * sb->s_root.
+ 	 */
+ 	if (do_sync_supers || !sb->s_root) {
++		target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
+ 		unlock_super(sb);
+ 		log_wait_commit(EXT3_SB(sb)->s_journal, target);
+ 		lock_super(sb);
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-noread-inode.patch b/lustre/kernel_patches/patches/ext3-noread-inode.patch
deleted file mode 100644
index a50d12b0687aadafe4e97e5cd4623478d22f0941..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/ext3-noread-inode.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-
-ext3_get_inode_loc() read inode's block only if:
-  1) this inode has no copy in memory
-  2) inode's block has another valid inode(s)
-
-this optimization allows to avoid needless I/O in two cases:
-1) just allocated inode is first valid in the inode's block
-2) kernel wants to write inode, but buffer in which inode
-   belongs to gets freed by VM
-
-
-
-
-diff -puN fs/ext3/inode.c~ext3-noread-inode fs/ext3/inode.c
---- linux-2.5.73/fs/ext3/inode.c~ext3-noread-inode	Thu Jul 10 12:03:52 2003
-+++ linux-2.5.73-alexey/fs/ext3/inode.c	Thu Jul 10 15:52:59 2003
-@@ -2286,7 +2286,7 @@ out_stop:
-  * inode's underlying buffer_head on success. 
-  */
- 
--int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
-+int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc, int in_mem)
- {
- 	struct buffer_head *bh = 0;
- 	unsigned long block;
-@@ -2328,12 +2328,88 @@ int ext3_get_inode_loc (struct inode *in
- 		EXT3_INODE_SIZE(inode->i_sb);
- 	block = le32_to_cpu(gdp[desc].bg_inode_table) +
- 		(offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
--	if (!(bh = sb_bread(inode->i_sb, block))) {
-+	if (!(bh = sb_getblk(inode->i_sb, block))) {
- 		ext3_error (inode->i_sb, "ext3_get_inode_loc",
- 			    "unable to read inode block - "
- 			    "inode=%lu, block=%lu", inode->i_ino, block);
- 		goto bad_inode;
- 	}
-+	if (!buffer_uptodate(bh)) {
-+		lock_buffer(bh);
-+		if (buffer_uptodate(bh)) {
-+			/* someone has already initialized buffer */
-+			unlock_buffer(bh);
-+			goto has_buffer;
-+		}
-+
-+		/* we can't skip I/O if inode is on a disk only */
-+		if (in_mem) {
-+			struct buffer_head *bitmap_bh; 
-+			struct ext3_group_desc *desc;
-+			int inodes_per_buffer;
-+			int inode_offset, i;
-+			int start;
-+
-+			/*
-+			 * if this inode is only valid in buffer we need not I/O
-+			 */
-+			inodes_per_buffer = bh->b_size /
-+				EXT3_INODE_SIZE(inode->i_sb);
-+			inode_offset = ((inode->i_ino - 1) %
-+					EXT3_INODES_PER_GROUP(inode->i_sb));
-+			start = inode_offset & ~(inodes_per_buffer - 1);
-+
-+			/* check is inode bitmap is in cache? */
-+			desc = ext3_get_group_desc(inode->i_sb, block_group, NULL);
-+			if (!desc)
-+				goto make_io;
-+
-+			bitmap_bh = sb_getblk(inode->i_sb, le32_to_cpu(desc->bg_inode_bitmap));
-+			if (!bitmap_bh)
-+				goto make_io;
-+
-+			/* 
-+			 * if inode bitmap isn't in cache then we may end up by 2 reads
-+			 * instead of 1 read before optimizing. skip it
-+			 */
-+			if (!buffer_uptodate(bitmap_bh)) {
-+				brelse(bitmap_bh);
-+				goto make_io;
-+			}
-+			for (i = start; i < start + inodes_per_buffer; i++) {
-+				if (i == inode_offset)
-+					continue;
-+				if (ext3_test_bit(i, bitmap_bh->b_data))
-+					break;
-+			}
-+			brelse(bitmap_bh);
-+			if (i == start + inodes_per_buffer) {
-+				/* all inodes (but our) are free. so, we skip I/O */
-+				memset(bh->b_data, 0, bh->b_size);
-+				set_buffer_uptodate(bh);
-+				unlock_buffer(bh);
-+				goto has_buffer;
-+			}
-+		}
-+
-+make_io:
-+		/*
-+		 * No, there are another valid inodes in the buffer
-+		 * so, to preserve them we have to read buffer from
-+		 * the disk
-+		 */
-+		get_bh(bh);
-+		bh->b_end_io = end_buffer_io_sync;
-+		submit_bh(READ, bh);
-+		wait_on_buffer(bh);
-+		if (!buffer_uptodate(bh)) {
-+			ext3_error (inode->i_sb, "ext3_get_inode_loc",
-+					"unable to read inode block - "
-+					"inode=%lu, block=%lu", inode->i_ino, block);
-+			goto bad_inode;
-+		}
-+	}
-+  has_buffer:
- 	offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
- 
- 	iloc->bh = bh;
-@@ -2376,7 +2452,7 @@ void ext3_read_inode(struct inode * inod
- endif
- 	if (ext3_iopen_get_inode(inode))
- 		return;
--	if (ext3_get_inode_loc(inode, &iloc))
-+	if (ext3_get_inode_loc(inode, &iloc, 0))
- 		goto bad_inode;
- 	bh = iloc.bh;
- 	raw_inode = iloc.raw_inode;
-@@ -2781,7 +2857,7 @@ ext3_reserve_inode_write(handle_t *handl
- {
- 	int err = 0;
- 	if (handle) {
--		err = ext3_get_inode_loc(inode, iloc);
-+		err = ext3_get_inode_loc(inode, iloc, 1);
- 		if (!err) {
- 			BUFFER_TRACE(iloc->bh, "get_write_access");
- 			err = ext3_journal_get_write_access(handle, iloc->bh);
-@@ -2879,7 +2955,7 @@ ext3_pin_inode(handle_t *handle, struct 
- 
- 	int err = 0;
- 	if (handle) {
--		err = ext3_get_inode_loc(inode, &iloc);
-+		err = ext3_get_inode_loc(inode, &iloc, 1);
- 		if (!err) {
- 			BUFFER_TRACE(iloc.bh, "get_write_access");
- 			err = journal_get_write_access(handle, iloc.bh);
-diff -puN fs/ext3/ialloc.c~ext3-noread-inode fs/ext3/ialloc.c
---- linux-2.5.73/fs/ext3/ialloc.c~ext3-noread-inode	Thu Jul 10 13:05:37 2003
-+++ linux-2.5.73-alexey/fs/ext3/ialloc.c	Thu Jul 10 13:06:12 2003
-@@ -50,7 +50,7 @@
-  *
-  * Return buffer_head of bitmap on success or NULL.
-  */
--static struct buffer_head *
-+struct buffer_head *
- read_inode_bitmap(struct super_block * sb, unsigned long block_group)
- {
- 	struct ext3_group_desc *desc;
-diff -puN include/linux/ext3_fs.h~ext3-noread-inode include/linux/ext3_fs.h
---- linux-2.5.73/include/linux/ext3_fs.h~ext3-noread-inode	Thu Jul 10 13:41:59 2003
-+++ linux-2.5.73-alexey/include/linux/ext3_fs.h	Thu Jul 10 14:40:13 2003
-@@ -717,6 +717,8 @@ extern unsigned long ext3_count_free_ino
- extern unsigned long ext3_count_dirs (struct super_block *);
- extern void ext3_check_inodes_bitmap (struct super_block *);
- extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
-+extern struct buffer_head * read_inode_bitmap(struct super_block *, unsigned long);
-+
- 
- 
- /* inode.c */
-@@ -724,7 +726,7 @@ extern int ext3_forget(handle_t *, int, 
- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
- 
--extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
-+extern int  ext3_get_inode_loc (struct inode *, struct ext3_iloc *, int);
- extern void ext3_read_inode (struct inode *);
- extern void ext3_write_inode (struct inode *, int);
- extern int  ext3_setattr (struct dentry *, struct iattr *);
-
-_
diff --git a/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..932ae843b8a679d7a8c3918c2eee6f5ced32c46d
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-o_direct-1-2.4.18-chaos.patch
@@ -0,0 +1,198 @@
+
+--- linux-2.4.18/fs/ext3/inode.c~ext3-o_direct-1-2.4.18-chaos	Mon Jul 28 14:13:05 2003
++++ linux-2.4.18-alexey/fs/ext3/inode.c	Mon Jul 28 15:50:14 2003
+@@ -27,6 +27,7 @@
+ #include <linux/ext3_jbd.h>
+ #include <linux/jbd.h>
+ #include <linux/locks.h>
++#include <linux/iobuf.h>
+ #include <linux/smp_lock.h>
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+@@ -733,9 +734,9 @@ err_out:
+  * The BKL may not be held on entry here.  Be sure to take it early.
+  */
+ 
+-static int ext3_get_block_handle(handle_t *handle, struct inode *inode, 
+-				 long iblock,
+-				 struct buffer_head *bh_result, int create)
++static int
++ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create, int extend_disksize)
+ {
+ 	int err = -EIO;
+ 	int offsets[4];
+@@ -816,16 +817,18 @@ out:
+ 	if (err)
+ 		goto cleanup;
+ 
+-	new_size = inode->i_size;
+-	/*
+-	 * This is not racy against ext3_truncate's modification of i_disksize
+-	 * because VM/VFS ensures that the file cannot be extended while
+-	 * truncate is in progress.  It is racy between multiple parallel
+-	 * instances of get_block, but we have the BKL.
+-	 */
+-	if (new_size > ei->i_disksize)
+-		ei->i_disksize = new_size;
+-
++	if (extend_disksize) {
++		/*
++		 * This is not racy against ext3_truncate's modification of
++		 * i_disksize because VM/VFS ensures that the file cannot be
++		 * extended while truncate is in progress.  It is racy between
++		 * multiple parallel instances of get_block, but we have BKL.
++		 */
++		struct ext3_inode_info *ei = EXT3_I(inode);
++		new_size = inode->i_size;
++		if (new_size > ei->i_disksize)
++			ei->i_disksize = new_size;
++	}
+ 	bh_result->b_state |= (1UL << BH_New);
+ 	goto got_it;
+ 
+@@ -852,7 +855,38 @@ static int ext3_get_block(struct inode *
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
++	ret = ext3_get_block_handle(handle, inode, iblock,
++				bh_result, create, 1);
++	return ret;
++}
++
++#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
++
++static int
++ext3_direct_io_get_block(struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create)
++{
++	handle_t *handle = journal_current_handle();
++	int ret = 0;
++
++	lock_kernel();
++	if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
++		/*
++		 * Getting low on buffer credits...
++		 */
++		if (!ext3_journal_extend(handle, DIO_CREDITS)) {
++			/*
++			 * Couldn't extend the transaction.  Start a new one
++			 */
++			ret = ext3_journal_restart(handle, DIO_CREDITS);
++		}
++	}
++	if (ret == 0)
++		ret = ext3_get_block_handle(handle, inode, iblock,
++					bh_result, create, 0);
++	if (ret == 0)
++		bh_result->b_size = (1 << inode->i_blkbits);
++	unlock_kernel();
+ 	return ret;
+ }
+ 
+@@ -870,7 +904,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
++	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1380,6 +1414,67 @@ static int ext3_releasepage(struct page 
+ 	return journal_try_to_free_buffers(journal, page, wait);
+ }
+ 
++static int
++ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
++		unsigned long blocknr, int blocksize)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	handle_t *handle = NULL;
++	int ret;
++	int orphan = 0;
++	loff_t offset = blocknr << inode->i_blkbits;	/* ugh */
++	ssize_t count = iobuf->length;			/* ditto */
++
++	if (rw == WRITE) {
++		loff_t final_size = offset + count;
++
++		lock_kernel();
++		handle = ext3_journal_start(inode, DIO_CREDITS);
++		unlock_kernel();
++		if (IS_ERR(handle)) {
++			ret = PTR_ERR(handle);
++			goto out;
++		}
++		if (final_size > inode->i_size) {
++			lock_kernel();
++			ret = ext3_orphan_add(handle, inode);
++			unlock_kernel();
++			if (ret)
++				goto out_stop;
++			orphan = 1;
++			ei->i_disksize = inode->i_size;
++		}
++	}
++
++	ret = generic_direct_IO(rw, inode, iobuf, blocknr,
++				blocksize, ext3_direct_io_get_block);
++
++out_stop:
++	if (handle) {
++		int err;
++
++		lock_kernel();
++		if (orphan) 
++			ext3_orphan_del(handle, inode);
++		if (orphan && ret > 0) {
++			loff_t end = offset + ret;
++			if (end > inode->i_size) {
++				ei->i_disksize = end;
++				inode->i_size = end;
++				err = ext3_mark_inode_dirty(handle, inode);
++				if (!ret) 
++					ret = err;
++			}
++		}
++		err = ext3_journal_stop(handle, inode);
++		if (ret == 0)
++			ret = err;
++		unlock_kernel();
++	}
++out:
++	return ret;
++
++}
+ 
+ struct address_space_operations ext3_aops = {
+ 	readpage:	ext3_readpage,		/* BKL not held.  Don't need */
+@@ -1390,6 +1485,7 @@ struct address_space_operations ext3_aop
+ 	bmap:		ext3_bmap,		/* BKL held */
+ 	flushpage:	ext3_flushpage,		/* BKL not held.  Don't need */
+ 	releasepage:	ext3_releasepage,	/* BKL not held.  Don't need */
++	direct_IO:	ext3_direct_IO,		/* BKL not held.  Don't need */
+ };
+ 
+ /*
+@@ -2987,7 +3083,7 @@ int ext3_prep_san_write(struct inode *in
+ 	/* alloc blocks one by one */
+ 	for (i = 0; i < nblocks; i++) {
+ 		ret = ext3_get_block_handle(handle, inode, blocks[i],
+-						&bh_tmp, 1);
++						&bh_tmp, 1, 1);
+ 		if (ret)
+ 			break;
+ 
+@@ -3047,7 +3143,7 @@ int ext3_map_inode_page(struct inode *in
+                 if (blocks[i] != 0)
+                         continue;
+ 
+-                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
++                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
+                 if (rc) {
+                         printk(KERN_INFO "ext3_map_inode_page: error %d "
+                                "allocating block %ld\n", rc, iblock);
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch b/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1caa2897545139daab53b6f80a568a8f8a2f926e
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-o_direct-1.2.4.20-rh.patch
@@ -0,0 +1,197 @@
+
+Index: linux-2.4.20-rh/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.20-rh.orig/fs/ext3/inode.c	2003-09-04 18:01:41.000000000 +0800
++++ linux-2.4.20-rh/fs/ext3/inode.c	2003-09-04 18:18:54.000000000 +0800
+@@ -27,6 +27,7 @@
+ #include <linux/ext3_jbd.h>
+ #include <linux/jbd.h>
+ #include <linux/locks.h>
++#include <linux/iobuf.h>
+ #include <linux/smp_lock.h>
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+@@ -743,9 +744,9 @@
+  * The BKL may not be held on entry here.  Be sure to take it early.
+  */
+ 
+-static int ext3_get_block_handle(handle_t *handle, struct inode *inode, 
+-				 long iblock,
+-				 struct buffer_head *bh_result, int create)
++static int
++ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create, int extend_disksize)
+ {
+ 	int err = -EIO;
+ 	int offsets[4];
+@@ -825,15 +826,18 @@
+ 	if (err)
+ 		goto cleanup;
+ 
+-	new_size = inode->i_size;
+-	/*
+-	 * This is not racy against ext3_truncate's modification of i_disksize
+-	 * because VM/VFS ensures that the file cannot be extended while
+-	 * truncate is in progress.  It is racy between multiple parallel
+-	 * instances of get_block, but we have the BKL.
+-	 */
+-	if (new_size > inode->u.ext3_i.i_disksize)
+-		inode->u.ext3_i.i_disksize = new_size;
++ 	if (extend_disksize) {
++ 		/*
++ 		 * This is not racy against ext3_truncate's modification of
++ 		 * i_disksize because VM/VFS ensures that the file cannot be
++ 		 * extended while truncate is in progress.  It is racy between
++ 		 * multiple parallel instances of get_block, but we have BKL.
++ 		 */
++ 		struct ext3_inode_info *ei = EXT3_I(inode);
++ 		new_size = inode->i_size;
++ 		if (new_size > ei->i_disksize)
++ 			ei->i_disksize = new_size;
++ 	}
+ 
+ 	bh_result->b_state |= (1UL << BH_New);
+ 	goto got_it;
+@@ -861,7 +865,38 @@
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
++	ret = ext3_get_block_handle(handle, inode, iblock,
++				bh_result, create, 1);
++	return ret;
++}
++
++#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
++
++static int
++ext3_direct_io_get_block(struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create)
++{
++	handle_t *handle = journal_current_handle();
++	int ret = 0;
++
++	lock_kernel();
++	if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
++		/*
++		 * Getting low on buffer credits...
++		 */
++		if (!ext3_journal_extend(handle, DIO_CREDITS)) {
++			/*
++			 * Couldn't extend the transaction.  Start a new one
++			 */
++			ret = ext3_journal_restart(handle, DIO_CREDITS);
++		}
++	}
++	if (ret == 0)
++		ret = ext3_get_block_handle(handle, inode, iblock,
++					bh_result, create, 0);
++	if (ret == 0)
++		bh_result->b_size = (1 << inode->i_blkbits);
++	unlock_kernel();
+ 	return ret;
+ }
+ 
+@@ -879,7 +914,7 @@
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
++	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1387,6 +1422,67 @@
+ 	return journal_try_to_free_buffers(journal, page, wait);
+ }
+ 
++static int
++ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
++		unsigned long blocknr, int blocksize)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	handle_t *handle = NULL;
++	int ret;
++	int orphan = 0;
++	loff_t offset = blocknr << inode->i_blkbits;	/* ugh */
++	ssize_t count = iobuf->length;			/* ditto */
++
++	if (rw == WRITE) {
++		loff_t final_size = offset + count;
++
++		lock_kernel();
++		handle = ext3_journal_start(inode, DIO_CREDITS);
++		unlock_kernel();
++		if (IS_ERR(handle)) {
++			ret = PTR_ERR(handle);
++			goto out;
++		}
++		if (final_size > inode->i_size) {
++			lock_kernel();
++			ret = ext3_orphan_add(handle, inode);
++			unlock_kernel();
++			if (ret)
++				goto out_stop;
++			orphan = 1;
++			ei->i_disksize = inode->i_size;
++		}
++	}
++
++	ret = generic_direct_IO(rw, inode, iobuf, blocknr,
++				blocksize, ext3_direct_io_get_block);
++
++out_stop:
++	if (handle) {
++		int err;
++
++		lock_kernel();
++		if (orphan) 
++			ext3_orphan_del(handle, inode);
++		if (orphan && ret > 0) {
++			loff_t end = offset + ret;
++			if (end > inode->i_size) {
++				ei->i_disksize = end;
++				inode->i_size = end;
++				err = ext3_mark_inode_dirty(handle, inode);
++				if (!ret) 
++					ret = err;
++			}
++		}
++		err = ext3_journal_stop(handle, inode);
++		if (ret == 0)
++			ret = err;
++		unlock_kernel();
++	}
++out:
++	return ret;
++
++}
+ 
+ struct address_space_operations ext3_aops = {
+ 	readpage:	ext3_readpage,		/* BKL not held.  Don't need */
+@@ -1397,6 +1493,7 @@
+ 	bmap:		ext3_bmap,		/* BKL held */
+ 	flushpage:	ext3_flushpage,		/* BKL not held.  Don't need */
+ 	releasepage:	ext3_releasepage,	/* BKL not held.  Don't need */
++	direct_IO:	ext3_direct_IO,		/* BKL not held.  Don't need */
+ };
+ 
+ /*
+@@ -2970,7 +3067,7 @@
+ 	/* alloc blocks one by one */
+ 	for (i = 0; i < nblocks; i++) {
+ 		ret = ext3_get_block_handle(handle, inode, blocks[i],
+-						&bh_tmp, 1);
++						&bh_tmp, 1, 1);
+ 		if (ret)
+ 			break;
+ 
+@@ -3030,7 +3127,7 @@
+                 if (blocks[i] != 0)
+                         continue;
+ 
+-                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
++                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
+                 if (rc) {
+                         printk(KERN_INFO "ext3_map_inode_page: error %d "
+                                "allocating block %ld\n", rc, iblock);
diff --git a/lustre/kernel_patches/patches/ext3-o_direct-1.patch b/lustre/kernel_patches/patches/ext3-o_direct-1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ac716403de1ea6d5ac057855514beee868f33725
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-o_direct-1.patch
@@ -0,0 +1,177 @@
+--- 2.4.20-pre2/fs/ext3/inode.c~ext3-o_direct	Thu Aug 15 01:11:02 2002
++++ 2.4.20-pre2-akpm/fs/ext3/inode.c	Thu Aug 15 01:25:55 2002
+@@ -27,6 +27,7 @@
+ #include <linux/ext3_jbd.h>
+ #include <linux/jbd.h>
+ #include <linux/locks.h>
++#include <linux/iobuf.h>
+ #include <linux/smp_lock.h>
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+@@ -716,9 +717,9 @@ err_out:
+  * The BKL may not be held on entry here.  Be sure to take it early.
+  */
+ 
+-static int ext3_get_block_handle(handle_t *handle, struct inode *inode, 
+-				 long iblock,
+-				 struct buffer_head *bh_result, int create)
++static int
++ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create, int extend_disksize)
+ {
+ 	int err = -EIO;
+ 	int offsets[4];
+@@ -798,16 +799,18 @@ out:
+ 	if (err)
+ 		goto cleanup;
+ 
+-	new_size = inode->i_size;
+-	/*
+-	 * This is not racy against ext3_truncate's modification of i_disksize
+-	 * because VM/VFS ensures that the file cannot be extended while
+-	 * truncate is in progress.  It is racy between multiple parallel
+-	 * instances of get_block, but we have the BKL.
+-	 */
+-	if (new_size > inode->u.ext3_i.i_disksize)
+-		inode->u.ext3_i.i_disksize = new_size;
+-
++	if (extend_disksize) {
++		/*
++		 * This is not racy against ext3_truncate's modification of
++		 * i_disksize because VM/VFS ensures that the file cannot be
++		 * extended while truncate is in progress.  It is racy between
++		 * multiple parallel instances of get_block, but we have BKL.
++		 */
++		struct ext3_inode_info *ei = EXT3_I(inode);
++		new_size = inode->i_size;
++		if (new_size > ei->i_disksize)
++			ei->i_disksize = new_size;
++	}
+ 	bh_result->b_state |= (1UL << BH_New);
+ 	goto got_it;
+ 
+@@ -834,7 +837,38 @@ static int ext3_get_block(struct inode *
+ 		handle = ext3_journal_current_handle();
+ 		J_ASSERT(handle != 0);
+ 	}
+-	ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
++	ret = ext3_get_block_handle(handle, inode, iblock,
++				bh_result, create, 1);
++	return ret;
++}
++
++#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
++
++static int
++ext3_direct_io_get_block(struct inode *inode, long iblock,
++		struct buffer_head *bh_result, int create)
++{
++	handle_t *handle = journal_current_handle();
++	int ret = 0;
++
++	lock_kernel();
++	if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
++		/*
++		 * Getting low on buffer credits...
++		 */
++		if (!ext3_journal_extend(handle, DIO_CREDITS)) {
++			/*
++			 * Couldn't extend the transaction.  Start a new one
++			 */
++			ret = ext3_journal_restart(handle, DIO_CREDITS);
++		}
++	}
++	if (ret == 0)
++		ret = ext3_get_block_handle(handle, inode, iblock,
++					bh_result, create, 0);
++	if (ret == 0)
++		bh_result->b_size = (1 << inode->i_blkbits);
++	unlock_kernel();
+ 	return ret;
+ }
+ 
+@@ -852,7 +886,7 @@ struct buffer_head *ext3_getblk(handle_t
+ 	dummy.b_state = 0;
+ 	dummy.b_blocknr = -1000;
+ 	buffer_trace_init(&dummy.b_history);
+-	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
++	*errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
+ 	if (!*errp && buffer_mapped(&dummy)) {
+ 		struct buffer_head *bh;
+ 		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+@@ -1349,6 +1383,67 @@ static int ext3_releasepage(struct page 
+ 	return journal_try_to_free_buffers(journal, page, wait);
+ }
+ 
++static int
++ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
++		unsigned long blocknr, int blocksize)
++{
++	struct ext3_inode_info *ei = EXT3_I(inode);
++	handle_t *handle = NULL;
++	int ret;
++	int orphan = 0;
++	loff_t offset = blocknr << inode->i_blkbits;	/* ugh */
++	ssize_t count = iobuf->length;			/* ditto */
++
++	if (rw == WRITE) {
++		loff_t final_size = offset + count;
++
++		lock_kernel();
++		handle = ext3_journal_start(inode, DIO_CREDITS);
++		unlock_kernel();
++		if (IS_ERR(handle)) {
++			ret = PTR_ERR(handle);
++			goto out;
++		}
++		if (final_size > inode->i_size) {
++			lock_kernel();
++			ret = ext3_orphan_add(handle, inode);
++			unlock_kernel();
++			if (ret)
++				goto out_stop;
++			orphan = 1;
++			ei->i_disksize = inode->i_size;
++		}
++	}
++
++	ret = generic_direct_IO(rw, inode, iobuf, blocknr,
++				blocksize, ext3_direct_io_get_block);
++
++out_stop:
++	if (handle) {
++		int err;
++
++		lock_kernel();
++		if (orphan) 
++			ext3_orphan_del(handle, inode);
++		if (orphan && ret > 0) {
++			loff_t end = offset + ret;
++			if (end > inode->i_size) {
++				ei->i_disksize = end;
++				inode->i_size = end;
++				err = ext3_mark_inode_dirty(handle, inode);
++				if (!ret) 
++					ret = err;
++			}
++		}
++		err = ext3_journal_stop(handle, inode);
++		if (ret == 0)
++			ret = err;
++		unlock_kernel();
++	}
++out:
++	return ret;
++
++}
+ 
+ struct address_space_operations ext3_aops = {
+ 	readpage:	ext3_readpage,		/* BKL not held.  Don't need */
+@@ -1359,6 +1454,7 @@ struct address_space_operations ext3_aop
+ 	bmap:		ext3_bmap,		/* BKL held */
+ 	flushpage:	ext3_flushpage,		/* BKL not held.  Don't need */
+ 	releasepage:	ext3_releasepage,	/* BKL not held.  Don't need */
++	direct_IO:	ext3_direct_IO,		/* BKL not held.  Don't need */
+ };
+ 
+ /*
diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.19-suse.patch b/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3c6b5e5b8e11eb35ab034c5591685b434e46210e
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.19-suse.patch
@@ -0,0 +1,85 @@
+Index: linux-2.4.19.SuSE/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/namei.c	Sun Nov 16 01:14:50 2003
++++ linux-2.4.19.SuSE/fs/ext3/namei.c	Sun Nov 16 01:18:04 2003
+@@ -1751,8 +1751,8 @@
+ 	struct super_block *sb = inode->i_sb;
+ 	struct ext3_iloc iloc;
+ 	int err = 0, rc;
+-	
+-	lock_super(sb);
++
++	down(&EXT3_SB(sb)->s_orphan_lock);
+ 	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+@@ -1800,7 +1800,7 @@
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+ 			inode->i_ino, NEXT_ORPHAN(inode));
+ out_unlock:
+-	unlock_super(sb);
++	up(&EXT3_SB(sb)->s_orphan_lock);
+ 	ext3_std_error(inode->i_sb, err);
+ 	return err;
+ }
+@@ -1813,20 +1813,19 @@
+ {
+ 	struct list_head *prev;
+ 	struct ext3_inode_info *ei = EXT3_I(inode);
+-	struct ext3_sb_info *sbi;
++	struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb);
+ 	unsigned long ino_next;
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 
+-	lock_super(inode->i_sb);
++	down(&sbi->s_orphan_lock);
+ 	if (list_empty(&ei->i_orphan)) {
+-		unlock_super(inode->i_sb);
++		up(&sbi->s_orphan_lock);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+ 	prev = ei->i_orphan.prev;
+-	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+ 
+@@ -1872,10 +1871,10 @@
+ 	if (err)
+ 		goto out_brelse;
+ 
+-out_err: 
++out_err:
+ 	ext3_std_error(inode->i_sb, err);
+ out:
+-	unlock_super(inode->i_sb);
++	up(&sbi->s_orphan_lock);
+ 	return err;
+ 
+ out_brelse:
+Index: linux-2.4.19.SuSE/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/super.c	Sun Nov 16 00:40:59 2003
++++ linux-2.4.19.SuSE/fs/ext3/super.c	Sun Nov 16 01:18:04 2003
+@@ -1182,6 +1182,7 @@
+ 	 */
+ 	sb->s_op = &ext3_sops;
+ 	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
++	sema_init(&sbi->s_orphan_lock, 1);
+ 
+ 	sb->s_root = 0;
+ 
+Index: linux-2.4.19.SuSE/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/ext3_fs_sb.h	Sat Nov 15 23:58:28 2003
++++ linux-2.4.19.SuSE/include/linux/ext3_fs_sb.h	Sun Nov 16 01:18:41 2003
+@@ -69,6 +69,7 @@
+ 	struct inode * s_journal_inode;
+ 	struct journal_s * s_journal;
+ 	struct list_head s_orphan;
++ 	struct semaphore s_orphan_lock;
+ 	struct block_device *journal_bdev;
+ #ifdef CONFIG_JBD_DEBUG
+ 	struct timer_list turn_ro_timer;	/* For turning read-only (crash simulation) */
diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.22-rh.patch b/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f2d48897ed81fa3534978fad75a4a8bceb2d4702
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.22-rh.patch
@@ -0,0 +1,82 @@
+ fs/ext3/namei.c                 |   15 +++++++--------
+ fs/ext3/namei.c.orig            |   21 +++++++++++++++------
+ fs/ext3/super.c                 |    1 +
+ include/linux/ext3_fs_sb.h      |    1 +
+ include/linux/ext3_fs_sb.h.orig |    2 ++
+ 5 files changed, 26 insertions(+), 14 deletions(-)
+
+--- linux-2.4.22-ac1/fs/ext3/namei.c~ext3-orphan_lock-2.4.22-rh	2003-09-26 00:24:09.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c	2003-09-26 00:26:36.000000000 +0400
+@@ -1748,8 +1748,8 @@ int ext3_orphan_add(handle_t *handle, st
+ 	struct super_block *sb = inode->i_sb;
+ 	struct ext3_iloc iloc;
+ 	int err = 0, rc;
+-	
+-	lock_super(sb);
++
++	down(&EXT3_SB(sb)->s_orphan_lock);
+ 	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+@@ -1797,7 +1797,7 @@ int ext3_orphan_add(handle_t *handle, st
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+ 			inode->i_ino, NEXT_ORPHAN(inode));
+ out_unlock:
+-	unlock_super(sb);
++	up(&EXT3_SB(sb)->s_orphan_lock);
+ 	ext3_std_error(inode->i_sb, err);
+ 	return err;
+ }
+@@ -1810,20 +1810,19 @@ int ext3_orphan_del(handle_t *handle, st
+ {
+ 	struct list_head *prev;
+  	struct ext3_inode_info *ei = EXT3_I(inode);
+-	struct ext3_sb_info *sbi;
++	struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb);
+ 	unsigned long ino_next;
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 
+-	lock_super(inode->i_sb);
++	down(&sbi->s_orphan_lock);
+  	if (list_empty(&ei->i_orphan)) {
+-		unlock_super(inode->i_sb);
++		up(&sbi->s_orphan_lock);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+  	prev = ei->i_orphan.prev;
+-	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+ 
+@@ -1872,7 +1871,7 @@ int ext3_orphan_del(handle_t *handle, st
+ out_err:
+ 	ext3_std_error(inode->i_sb, err);
+ out:
+-	unlock_super(inode->i_sb);
++	up(&sbi->s_orphan_lock);
+ 	return err;
+ 
+ out_brelse:
+--- linux-2.4.22-ac1/fs/ext3/super.c~ext3-orphan_lock-2.4.22-rh	2003-09-26 00:24:09.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/super.c	2003-09-26 00:25:22.000000000 +0400
+@@ -1164,6 +1164,7 @@ struct super_block * ext3_read_super (st
+ 	sb->s_op = &ext3_sops;
+ 	sb->dq_op = &ext3_qops;
+ 	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
++	sema_init(&sbi->s_orphan_lock, 1);
+ 
+ 	sb->s_root = 0;
+ 
+--- linux-2.4.22-ac1/include/linux/ext3_fs_sb.h~ext3-orphan_lock-2.4.22-rh	2003-09-26 00:24:08.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_sb.h	2003-09-26 00:25:22.000000000 +0400
+@@ -72,6 +72,7 @@ struct ext3_sb_info {
+ 	struct inode * s_journal_inode;
+ 	struct journal_s * s_journal;
+ 	struct list_head s_orphan;
++	struct semaphore s_orphan_lock;
+ 	unsigned long s_commit_interval;
+ 	struct block_device *journal_bdev;
+ #ifdef CONFIG_JBD_DEBUG
diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch b/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c3369e6e654fb0bd66e8f1bf0efcc18305930609
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-orphan_lock-suse.patch
@@ -0,0 +1,81 @@
+Index: linux-2.4.21-suse/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/namei.c	2003-10-30 02:17:22.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/namei.c	2003-10-30 02:20:53.000000000 +0300
+@@ -1747,8 +1747,8 @@
+ 	struct super_block *sb = inode->i_sb;
+ 	struct ext3_iloc iloc;
+ 	int err = 0, rc;
+-	
+-	lock_super(sb);
++
++	down(&EXT3_SB(sb)->s_orphan_lock);
+ 	if (!list_empty(&EXT3_I(inode)->i_orphan))
+ 		goto out_unlock;
+ 
+@@ -1796,7 +1796,7 @@
+ 	jbd_debug(4, "orphan inode %ld will point to %d\n",
+ 			inode->i_ino, NEXT_ORPHAN(inode));
+ out_unlock:
+-	unlock_super(sb);
++	up(&EXT3_SB(sb)->s_orphan_lock);
+ 	ext3_std_error(inode->i_sb, err);
+ 	return err;
+ }
+@@ -1808,20 +1808,19 @@
+ int ext3_orphan_del(handle_t *handle, struct inode *inode)
+ {
+ 	struct list_head *prev;
+-	struct ext3_sb_info *sbi;
++	struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb);
+ 	unsigned long ino_next;
+ 	struct ext3_iloc iloc;
+ 	int err = 0;
+ 
+-	lock_super(inode->i_sb);
++	down(&sbi->s_orphan_lock);
+ 	if (list_empty(&inode->u.ext3_i.i_orphan)) {
+-		unlock_super(inode->i_sb);
++		up(&sbi->s_orphan_lock);
+ 		return 0;
+ 	}
+ 
+ 	ino_next = NEXT_ORPHAN(inode);
+ 	prev = inode->u.ext3_i.i_orphan.prev;
+-	sbi = EXT3_SB(inode->i_sb);
+ 
+ 	jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+ 
+@@ -1870,7 +1869,7 @@
+ out_err:
+ 	ext3_std_error(inode->i_sb, err);
+ out:
+-	unlock_super(inode->i_sb);
++	up(&sbi->s_orphan_lock);
+ 	return err;
+ 
+ out_brelse:
+Index: linux-2.4.21-suse/fs/ext3/super.c
+===================================================================
+--- linux-2.4.21-suse.orig/fs/ext3/super.c	2003-10-30 02:17:22.000000000 +0300
++++ linux-2.4.21-suse/fs/ext3/super.c	2003-10-30 02:17:22.000000000 +0300
+@@ -1151,6 +1151,7 @@
+ 	 */
+ 	sb->s_op = &ext3_sops;
+ 	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
++	sema_init(&sbi->s_orphan_lock, 1);
+ 
+ 	sb->s_root = 0;
+ 
+Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h	2003-10-30 02:17:22.000000000 +0300
++++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h	2003-10-30 02:17:22.000000000 +0300
+@@ -69,6 +69,7 @@
+ 	struct inode * s_journal_inode;
+ 	struct journal_s * s_journal;
+ 	struct list_head s_orphan;
++	struct semaphore s_orphan_lock;
+ 	unsigned long s_commit_interval;
+ 	struct block_device *journal_bdev;
+ #ifdef CONFIG_JBD_DEBUG
diff --git a/lustre/kernel_patches/patches/ext3-pdirops-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-pdirops-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f8f514bb1ab6992e1af6854921754e61ca283837
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-pdirops-2.4.18-chaos.patch
@@ -0,0 +1,1238 @@
+ fs/ext3/ialloc.c          |    3 
+ fs/ext3/inode.c           |    3 
+ fs/ext3/namei.c           |  582 +++++++++++++++++++++++++++++++++++++---------
+ fs/ext3/super.c           |   14 +
+ include/linux/ext3_fs.h   |    1 
+ include/linux/ext3_fs_i.h |    6 
+ 6 files changed, 500 insertions(+), 109 deletions(-)
+
+--- linux-2.4.18/fs/ext3/namei.c~ext3-pdirops-2.4.18-chaos	2003-09-01 14:58:06.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/namei.c	2003-09-02 11:46:15.000000000 +0400
+@@ -52,6 +52,9 @@ static struct buffer_head *ext3_append(h
+ {
+ 	struct buffer_head *bh;
+ 
++	/* with parallel dir operations all appends
++	 * have to be serialized -bzzz */
++	down(&EXT3_I(inode)->i_append_sem);
+ 	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
+ 
+ 	if ((bh = ext3_bread(handle, inode, *block, 1, err))) {
+@@ -59,6 +62,8 @@ static struct buffer_head *ext3_append(h
+ 		EXT3_I(inode)->i_disksize = inode->i_size;
+ 		ext3_journal_get_write_access(handle,bh);
+ 	}
++	up(&EXT3_I(inode)->i_append_sem);
++	
+ 	return bh;
+ }
+ 
+@@ -135,6 +140,8 @@ struct dx_frame
+ 	struct buffer_head *bh;
+ 	struct dx_entry *entries;
+ 	struct dx_entry *at;
++	unsigned long leaf;
++	unsigned int curidx;
+ };
+ 
+ struct dx_map_entry
+@@ -143,6 +150,30 @@ struct dx_map_entry
+ 	u32 offs;
+ };
+ 
++/* FIXME: this should be reworked using bb_spin_lock
++ * introduced in -mm tree
++ */
++#define BH_DXLock	25
++
++static inline void dx_lock_bh(struct buffer_head volatile *bh)
++{
++#ifdef CONFIG_SMP
++        while (test_and_set_bit(BH_DXLock, &bh->b_state)) {
++                while (test_bit(BH_DXLock, &bh->b_state))
++                        cpu_relax();
++        }
++#endif
++}
++
++static inline void dx_unlock_bh(struct buffer_head *bh)
++{
++#ifdef CONFIG_SMP
++        smp_mb__before_clear_bit();
++        clear_bit(BH_DXLock, &bh->b_state);
++#endif
++}
++
++
+ #ifdef CONFIG_EXT3_INDEX
+ static inline unsigned dx_get_block (struct dx_entry *entry);
+ static void dx_set_block (struct dx_entry *entry, unsigned value);
+@@ -154,7 +185,7 @@ static void dx_set_count (struct dx_entr
+ static void dx_set_limit (struct dx_entry *entries, unsigned value);
+ static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
+ static unsigned dx_node_limit (struct inode *dir);
+-static struct dx_frame *dx_probe(struct dentry *dentry,
++static struct dx_frame *dx_probe(struct qstr *name,
+ 				 struct inode *dir,
+ 				 struct dx_hash_info *hinfo,
+ 				 struct dx_frame *frame,
+@@ -166,15 +197,18 @@ static void dx_sort_map(struct dx_map_en
+ static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to,
+ 		struct dx_map_entry *offsets, int count);
+ static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size);
+-static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
++static void dx_insert_block (struct inode *, struct dx_frame *, u32, u32, u32);
+ static int ext3_htree_next_block(struct inode *dir, __u32 hash,
+ 				 struct dx_frame *frame,
+ 				 struct dx_frame *frames, int *err,
+ 				 __u32 *start_hash);
+ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
+-		       struct ext3_dir_entry_2 **res_dir, int *err);
++		       struct ext3_dir_entry_2 **res_dir, int *err,
++		       int rwlock, void **lock);
+ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
+ 			     struct inode *inode);
++static inline void *ext3_lock_htree(struct inode *, unsigned long, int);
++static inline void ext3_unlock_htree(struct inode *, void *);
+ 
+ /*
+  * Future: use high four bits of block for coalesce-on-delete flags
+@@ -307,6 +341,94 @@ struct stats dx_show_entries(struct dx_h
+ #endif /* DX_DEBUG */
+ 
+ /*
++ * dx_find_position
++ *
++ * search position of specified hash in index
++ *
++ */
++
++struct dx_entry * dx_find_position(struct dx_entry * entries, u32 hash)
++{
++	struct dx_entry *p, *q, *m;
++	int count;
++
++	count = dx_get_count(entries);
++	p = entries + 1;
++	q = entries + count - 1;
++	while (p <= q)
++	{
++		m = p + (q - p)/2;
++		if (dx_get_hash(m) > hash)
++			q = m - 1;
++		else
++			p = m + 1;
++	}
++	return p - 1;
++}
++
++/*
++ * returns 1 if path is unchanged
++ */
++int dx_check_path(struct dx_frame *frame, u32 hash)
++{
++	struct dx_entry *p;
++	int ret = 1;
++
++	dx_lock_bh(frame->bh);
++	p = dx_find_position(frame->entries, hash);
++	if (frame->leaf != dx_get_block(p))
++		ret = 0;
++	dx_unlock_bh(frame->bh);
++	
++	return ret;
++}
++
++/*
++ * 0 - changed
++ * 1 - hasn't changed
++ */
++static int
++dx_check_full_path(struct dx_frame *frames, struct dx_hash_info *hinfo)
++{
++	struct dx_entry *p;
++	struct dx_frame *frame = frames;
++	u32 leaf;
++
++	/* check first level */
++	dx_lock_bh(frame->bh);
++	p = dx_find_position(frame->entries, hinfo->hash);
++	leaf = dx_get_block(p);
++	dx_unlock_bh(frame->bh);
++	
++	if (leaf != frame->leaf) 
++		return 0;
++	
++	/* is there 2nd level? */
++	frame++;
++	if (frame->bh == NULL)
++		return 1;
++
++	/* check second level */
++	dx_lock_bh(frame->bh);
++
++	/* probably 1st level got changed, check it */
++	if (!dx_check_path(frames, hinfo->hash)) {
++		/* path changed */
++		dx_unlock_bh(frame->bh);
++		return 0;
++	}
++
++	p = dx_find_position(frame->entries, hinfo->hash);
++	leaf = dx_get_block(p);
++	dx_unlock_bh(frame->bh);
++	
++	if (leaf != frame->leaf)
++		return 0;
++
++	return 1;
++}
++
++/*
+  * Probe for a directory leaf block to search.
+  *
+  * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
+@@ -316,19 +438,20 @@ struct stats dx_show_entries(struct dx_h
+  * back to userspace.
+  */
+ static struct dx_frame *
+-dx_probe(struct dentry *dentry, struct inode *dir,
++dx_probe(struct qstr *name, struct inode *dir,
+ 	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
+ {
+-	unsigned count, indirect;
+-	struct dx_entry *at, *entries, *p, *q, *m;
++	unsigned indirect;
++	struct dx_entry *at, *entries;
+ 	struct dx_root *root;
+ 	struct buffer_head *bh;
+ 	struct dx_frame *frame = frame_in;
+ 	u32 hash;
++	unsigned int curidx;
+ 
+ 	frame->bh = NULL;
+-	if (dentry)
+-		dir = dentry->d_parent->d_inode;
++	frame[1].bh = NULL;
++
+ 	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
+ 		goto fail;
+ 	root = (struct dx_root *) bh->b_data;
+@@ -344,8 +467,8 @@ dx_probe(struct dentry *dentry, struct i
+ 	}
+ 	hinfo->hash_version = root->info.hash_version;
+ 	hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed;
+-	if (dentry)
+-		ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
++	if (name)
++		ext3fs_dirhash(name->name, name->len, hinfo);
+ 	hash = hinfo->hash;
+ 
+ 	if (root->info.unused_flags & 1) {
+@@ -357,7 +480,19 @@ dx_probe(struct dentry *dentry, struct i
+ 		goto fail;
+ 	}
+ 
++repeat:
++	curidx = 0;
++	entries = (struct dx_entry *) (((char *)&root->info) +
++				       root->info.info_length);
++	assert(dx_get_limit(entries) == dx_root_limit(dir,
++						      root->info.info_length));
++	dxtrace (printk("Look up %x", hash));
++	dx_lock_bh(bh);
++	/* indirect must be initialized under bh lock because
++	 * 2nd level creation procedure may change it and dx_probe()
++	 * will suggest htree is still single-level -bzzz */
+ 	if ((indirect = root->info.indirect_levels) > 1) {
++		dx_unlock_bh(bh);
+ 		ext3_warning(dir->i_sb, __FUNCTION__,
+ 			     "Unimplemented inode hash depth: %#06x",
+ 			     root->info.indirect_levels);
+@@ -365,56 +500,46 @@ dx_probe(struct dentry *dentry, struct i
+ 		*err = ERR_BAD_DX_DIR;
+ 		goto fail;
+ 	}
+-
+-	entries = (struct dx_entry *) (((char *)&root->info) +
+-				       root->info.info_length);
+-	assert(dx_get_limit(entries) == dx_root_limit(dir,
+-						      root->info.info_length));
+-	dxtrace (printk("Look up %x", hash));
++	
+ 	while (1)
+ 	{
+-		count = dx_get_count(entries);
+-		assert (count && count <= dx_get_limit(entries));
+-		p = entries + 1;
+-		q = entries + count - 1;
+-		while (p <= q)
+-		{
+-			m = p + (q - p)/2;
+-			dxtrace(printk("."));
+-			if (dx_get_hash(m) > hash)
+-				q = m - 1;
+-			else
+-				p = m + 1;
+-		}
+-
+-		if (0) // linear search cross check
+-		{
+-			unsigned n = count - 1;
+-			at = entries;
+-			while (n--)
+-			{
+-				dxtrace(printk(","));
+-				if (dx_get_hash(++at) > hash)
+-				{
+-					at--;
+-					break;
+-				}
+-			}
+-			assert (at == p - 1);
+-		}
+-
+-		at = p - 1;
+-		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
++		at = dx_find_position(entries, hinfo->hash);
++		dxtrace(printk(" %x->%u\n",
++				at == entries? 0: dx_get_hash(at),
++				dx_get_block(at)));
+ 		frame->bh = bh;
+ 		frame->entries = entries;
+ 		frame->at = at;
+-		if (!indirect--) return frame;
+-		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
++		frame->curidx = curidx;
++		frame->leaf = dx_get_block(at);
++		if (!indirect--) {
++			dx_unlock_bh(bh);
++			return frame;
++		}
++		
++		/* step into next htree level */
++		curidx = dx_get_block(at);
++		dx_unlock_bh(bh);
++		if (!(bh = ext3_bread (NULL,dir, frame->leaf, 0, err)))
+ 			goto fail2;
++		
++		dx_lock_bh(bh);
++		/* splitting may change root index block and move
++		 * hash we're looking for into another index block
++		 * so, we have to check this situation and repeat
++		 * from begining if path got changed -bzzz */
++		if (!dx_check_path(frame, hash)) {
++			dx_unlock_bh(bh);
++			bh = frame->bh;
++			indirect++;
++			goto repeat;
++		}
++		
+ 		at = entries = ((struct dx_node *) bh->b_data)->entries;
+ 		assert (dx_get_limit(entries) == dx_node_limit (dir));
+ 		frame++;
+ 	}
++	dx_unlock_bh(bh);
+ fail2:
+ 	while (frame >= frame_in) {
+ 		brelse(frame->bh);
+@@ -428,8 +553,7 @@ static void dx_release (struct dx_frame 
+ {
+ 	if (frames[0].bh == NULL)
+ 		return;
+-
+-	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
++	if (frames[1].bh != NULL)
+ 		brelse(frames[1].bh);
+ 	brelse(frames[0].bh);
+ }
+@@ -471,8 +595,10 @@ static int ext3_htree_next_block(struct 
+ 	 * nodes need to be read.
+ 	 */
+ 	while (1) {
+-		if (++(p->at) < p->entries + dx_get_count(p->entries))
++		if (++(p->at) < p->entries + dx_get_count(p->entries)) {
++			p->leaf = dx_get_block(p->at);
+ 			break;
++		}
+ 		if (p == frames)
+ 			return 0;
+ 		num_frames++;
+@@ -498,13 +624,17 @@ static int ext3_htree_next_block(struct 
+ 	 * block so no check is necessary
+ 	 */
+ 	while (num_frames--) {
+-		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
+-				      0, err)))
++		u32 idx;
++		
++		idx = p->leaf = dx_get_block(p->at);
++		if (!(bh = ext3_bread(NULL, dir, idx, 0, err)))
+ 			return -1; /* Failure */
+ 		p++;
+ 		brelse (p->bh);
+ 		p->bh = bh;
+ 		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
++		p->curidx = idx;
++		p->leaf = dx_get_block(p->at);
+ 	}
+ 	return 1;
+ }
+@@ -544,7 +674,7 @@ int ext3_htree_fill_tree(struct file *di
+ 	dir = dir_file->f_dentry->d_inode;
+ 	hinfo.hash = start_hash;
+ 	hinfo.minor_hash = 0;
+-	frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
++	frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
+ 	if (!frame)
+ 		return err;
+ 
+@@ -626,7 +756,8 @@ static int dx_make_map (struct ext3_dir_
+ 			count++;
+ 		}
+ 		/* XXX: do we need to check rec_len == 0 case? -Chris */
+-		de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
++		de = (struct ext3_dir_entry_2 *)((char*)de +
++				le16_to_cpu(de->rec_len));
+ 	}
+ 	return count;
+ }
+@@ -659,7 +790,8 @@ static void dx_sort_map (struct dx_map_e
+ 	} while(more);
+ }
+ 
+-static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
++static void dx_insert_block(struct inode *dir, struct dx_frame *frame,
++			u32 hash, u32 block, u32 idx)
+ {
+ 	struct dx_entry *entries = frame->entries;
+ 	struct dx_entry *old = frame->at, *new = old + 1;
+@@ -671,6 +803,7 @@ static void dx_insert_block(struct dx_fr
+ 	dx_set_hash(new, hash);
+ 	dx_set_block(new, block);
+ 	dx_set_count(entries, count + 1);
++	
+ }
+ #endif
+ 
+@@ -753,7 +886,8 @@ static int inline search_dirblock(struct
+ 
+ 	
+ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
+-					struct ext3_dir_entry_2 ** res_dir)
++					struct ext3_dir_entry_2 ** res_dir,
++					int rwlock, void **lock)
+ {
+ 	struct super_block * sb;
+ 	struct buffer_head * bh_use[NAMEI_RA_SIZE];
+@@ -769,6 +903,7 @@ static struct buffer_head * ext3_find_en
+ 	int namelen;
+ 	const u8 *name;
+ 	unsigned blocksize;
++	int do_not_use_dx = 0;
+ 
+ 	*res_dir = NULL;
+ 	sb = dir->i_sb;
+@@ -777,9 +912,10 @@ static struct buffer_head * ext3_find_en
+ 	name = dentry->d_name.name;
+ 	if (namelen > EXT3_NAME_LEN)
+ 		return NULL;
++repeat:
+ #ifdef CONFIG_EXT3_INDEX
+ 	if (is_dx(dir)) {
+-		bh = ext3_dx_find_entry(dentry, res_dir, &err);
++		bh = ext3_dx_find_entry(dentry, res_dir, &err, rwlock, lock);
+ 		/*
+ 		 * On success, or if the error was file not found,
+ 		 * return.  Otherwise, fall back to doing a search the
+@@ -788,8 +924,14 @@ static struct buffer_head * ext3_find_en
+ 		if (bh || (err != ERR_BAD_DX_DIR))
+ 			return bh;
+ 		dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
++		do_not_use_dx = 1;
+ 	}
+ #endif
++	*lock = ext3_lock_htree(dir, 0, rwlock);
++	if (is_dx(dir) && !do_not_use_dx) {
++		ext3_unlock_htree(dir, *lock);
++		goto repeat;
++	}
+ 	nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
+ 	start = EXT3_I(dir)->i_dir_start_lookup;
+ 	if (start >= nblocks)
+@@ -861,12 +1003,17 @@ cleanup_and_exit:
+ 	/* Clean up the read-ahead blocks */
+ 	for (; ra_ptr < ra_max; ra_ptr++)
+ 		brelse (bh_use[ra_ptr]);
++	if (!ret) {
++		ext3_unlock_htree(dir, *lock);
++		*lock = NULL;
++	}
+ 	return ret;
+ }
+ 
+ #ifdef CONFIG_EXT3_INDEX
+ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
+-		       struct ext3_dir_entry_2 **res_dir, int *err)
++		       struct ext3_dir_entry_2 **res_dir, int *err,
++		       int rwlock, void **lock)
+ {
+ 	struct super_block * sb;
+ 	struct dx_hash_info	hinfo;
+@@ -881,11 +1028,22 @@ static struct buffer_head * ext3_dx_find
+ 	struct inode *dir = dentry->d_parent->d_inode;
+ 	
+ 	sb = dir->i_sb;
+-	if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err)))
++repeat:
++	if (!(frame = dx_probe (&dentry->d_name, dir, &hinfo, frames, err)))
+ 		return NULL;
++	
++	*lock = ext3_lock_htree(dir, frame->leaf, rwlock);
++	/* while locking leaf we just found may get splitted
++	 * so, we need another leaf. check this */
++	if (!dx_check_full_path(frames, &hinfo)) {
++		ext3_unlock_htree(dir, *lock);
++		dx_release(frames);
++		goto repeat;
++	}
++
+ 	hash = hinfo.hash;
+ 	do {
+-		block = dx_get_block(frame->at);
++		block = frame->leaf;
+ 		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
+ 			goto errout;
+ 		de = (struct ext3_dir_entry_2 *) bh->b_data;
+@@ -919,6 +1077,8 @@ static struct buffer_head * ext3_dx_find
+ 	*err = -ENOENT;
+ errout:
+ 	dxtrace(printk("%s not found\n", name));
++	ext3_unlock_htree(dir, *lock);
++	*lock = NULL;
+ 	dx_release (frames);
+ 	return NULL;
+ }
+@@ -931,6 +1091,7 @@ static struct dentry *ext3_lookup(struct
+ 	struct ext3_dir_entry_2 * de;
+ 	struct buffer_head * bh;
+ 	struct dentry *alternate = NULL;
++	void *lock = NULL;
+ 
+ 	if (dentry->d_name.len > EXT3_NAME_LEN)
+ 		return ERR_PTR(-ENAMETOOLONG);
+@@ -938,10 +1099,11 @@ static struct dentry *ext3_lookup(struct
+ 	if (ext3_check_for_iopen(dir, dentry))
+ 		return NULL;
+ 
+-	bh = ext3_find_entry(dentry, &de);
++	bh = ext3_find_entry(dentry, &de, 0, &lock);
+ 	inode = NULL;
+ 	if (bh) {
+ 		unsigned long ino = le32_to_cpu(de->inode);
++		ext3_unlock_htree(dir, lock);
+ 		brelse (bh);
+ 		inode = iget(dir->i_sb, ino);
+ 
+@@ -984,7 +1146,8 @@ dx_move_dirents(char *from, char *to, st
+ 	unsigned rec_len = 0;
+ 
+ 	while (count--) {
+-		struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs);
++		struct ext3_dir_entry_2 *de =
++			(struct ext3_dir_entry_2 *) (from + map->offs);
+ 		rec_len = EXT3_DIR_REC_LEN(de->name_len);
+ 		memcpy (to, de, rec_len);
+ 		((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
+@@ -997,7 +1160,8 @@ dx_move_dirents(char *from, char *to, st
+ 
+ static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
+ {
+-	struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
++	struct ext3_dir_entry_2 *next, *to, *prev;
++	struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) base;
+ 	unsigned rec_len = 0;
+ 
+ 	prev = to = de;
+@@ -1019,7 +1183,8 @@ static struct ext3_dir_entry_2* dx_pack_
+ 
+ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
+ 			struct buffer_head **bh,struct dx_frame *frame,
+-			struct dx_hash_info *hinfo, int *error)
++			struct dx_hash_info *hinfo, void **target,
++			int *error)
+ {
+ 	unsigned blocksize = dir->i_sb->s_blocksize;
+ 	unsigned count, continued;
+@@ -1066,23 +1231,30 @@ static struct ext3_dir_entry_2 *do_split
+ 	hash2 = map[split].hash;
+ 	continued = hash2 == map[split - 1].hash;
+ 	dxtrace(printk("Split block %i at %x, %i/%i\n",
+-		dx_get_block(frame->at), hash2, split, count-split));
+-
++		frame->leaf, hash2, split, count-split));
++	
+ 	/* Fancy dance to stay within two buffers */
+ 	de2 = dx_move_dirents(data1, data2, map + split, count - split);
+ 	de = dx_pack_dirents(data1,blocksize);
+ 	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
+ 	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
+-	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1));
+-	dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1));
++	dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data1, blocksize, 1));
++	dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data2, blocksize, 1));
+ 
+ 	/* Which block gets the new entry? */
++	*target = NULL;
+ 	if (hinfo->hash >= hash2)
+ 	{
+ 		swap(*bh, bh2);
+ 		de = de2;
+-	}
+-	dx_insert_block (frame, hash2 + continued, newblock);
++
++		/* entry will be stored into new block
++		 * we have to lock it before add_dirent_to_buf */
++		*target = ext3_lock_htree(dir, newblock, 1);
++	}
++	dx_lock_bh(frame->bh);
++	dx_insert_block (dir, frame, hash2 + continued, newblock, frame->curidx);
++	dx_unlock_bh(frame->bh);
+ 	err = ext3_journal_dirty_metadata (handle, bh2);
+ 	if (err)
+ 		goto journal_error;
+@@ -1156,7 +1328,8 @@ static int add_dirent_to_buf(handle_t *h
+ 	nlen = EXT3_DIR_REC_LEN(de->name_len);
+ 	rlen = le16_to_cpu(de->rec_len);
+ 	if (de->inode) {
+-		struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen);
++		struct ext3_dir_entry_2 *de1 =
++			(struct ext3_dir_entry_2 *)((char *)de + nlen);
+ 		de1->rec_len = cpu_to_le16(rlen - nlen);
+ 		de->rec_len = cpu_to_le16(nlen);
+ 		de = de1;
+@@ -1214,7 +1387,8 @@ static int make_indexed_dir(handle_t *ha
+ 	unsigned	blocksize;
+ 	struct dx_hash_info hinfo;
+ 	u32		block;
+-		
++	void		*lock, *new_lock;
++
+ 	blocksize =  dir->i_sb->s_blocksize;
+ 	dxtrace(printk("Creating index\n"));
+ 	retval = ext3_journal_get_write_access(handle, bh);
+@@ -1225,7 +1399,6 @@ static int make_indexed_dir(handle_t *ha
+ 	}
+ 	root = (struct dx_root *) bh->b_data;
+ 		
+-	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
+ 	bh2 = ext3_append (handle, dir, &block, &retval);
+ 	if (!(bh2)) {
+ 		brelse(bh);
+@@ -1233,6 +1406,8 @@ static int make_indexed_dir(handle_t *ha
+ 	}
+ 	data1 = bh2->b_data;
+ 
++	lock = ext3_lock_htree(dir, block, 1);
++
+ 	/* The 0th block becomes the root, move the dirents out */
+ 	de = (struct ext3_dir_entry_2 *) &root->info;
+ 	len = ((char *) root) + blocksize - (char *) de;
+@@ -1261,13 +1436,25 @@ static int make_indexed_dir(handle_t *ha
+ 	frame->entries = entries;
+ 	frame->at = entries;
+ 	frame->bh = bh;
++	frame->curidx = 0;
++	frame->leaf = 0;
++	frame[1].bh = NULL;
+ 	bh = bh2;
+-	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
++	de = do_split(handle,dir, &bh, frame, &hinfo, &new_lock, &retval);
+ 	dx_release (frames);
+ 	if (!(de))
+-		return retval;
++		goto cleanup;
++
++	retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
++cleanup:
++	if (new_lock)
++		ext3_unlock_htree(dir, new_lock);
++	/* we mark directory indexed in order to
++	 * avoid races while htree being created -bzzz */
++	EXT3_I(dir)->i_flags |= EXT3_INDEX_FL;
++	ext3_unlock_htree(dir, lock);
+ 
+-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++	return retval;
+ }
+ #endif
+ 
+@@ -1296,11 +1483,13 @@ static int ext3_add_entry (handle_t *han
+ 	unsigned blocksize;
+ 	unsigned nlen, rlen;
+ 	u32 block, blocks;
++	void *lock;
+ 
+ 	sb = dir->i_sb;
+ 	blocksize = sb->s_blocksize;
+ 	if (!dentry->d_name.len)
+ 		return -EINVAL;
++repeat:
+ #ifdef CONFIG_EXT3_INDEX
+ 	if (is_dx(dir)) {
+ 		retval = ext3_dx_add_entry(handle, dentry, inode);
+@@ -1311,36 +1500,53 @@ static int ext3_add_entry (handle_t *han
+ 		ext3_mark_inode_dirty(handle, dir);
+ 	}
+ #endif
++	lock = ext3_lock_htree(dir, 0, 1);
++	if (is_dx(dir)) {
++		/* we got lock for block 0
++		 * probably previous holder of the lock
++		 * created htree -bzzz */
++		ext3_unlock_htree(dir, lock);
++		goto repeat;
++	}
++	
+ 	blocks = dir->i_size >> sb->s_blocksize_bits;
+ 	for (block = 0, offset = 0; block < blocks; block++) {
+ 		bh = ext3_bread(handle, dir, block, 0, &retval);
+-		if(!bh)
++		if(!bh) {
++			ext3_unlock_htree(dir, lock);
+ 			return retval;
++		}
+ 		retval = add_dirent_to_buf(handle, dentry, inode, 0, bh);
+-		if (retval != -ENOSPC)
++		if (retval != -ENOSPC) {
++			ext3_unlock_htree(dir, lock);
+ 			return retval;
++		}
+ 
+ #ifdef CONFIG_EXT3_INDEX
+ 		if (blocks == 1 && !dx_fallback &&
+-		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
+-			return make_indexed_dir(handle, dentry, inode, bh);
++		    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) {
++			retval = make_indexed_dir(handle, dentry, inode, bh);
++			ext3_unlock_htree(dir, lock);
++			return retval;
++		}
+ #endif
+ 		brelse(bh);
+ 	}
+ 	bh = ext3_append(handle, dir, &block, &retval);
+-	if (!bh)
++	if (!bh) {
++		ext3_unlock_htree(dir, lock);
+ 		return retval;
++	}
+ 	de = (struct ext3_dir_entry_2 *) bh->b_data;
+ 	de->inode = 0;
+ 	de->rec_len = cpu_to_le16(rlen = blocksize);
+ 	nlen = 0;
+-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
++	retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
++	ext3_unlock_htree(dir, lock);
++	return retval;
+ }
+ 
+ #ifdef CONFIG_EXT3_INDEX
+-/*
+- * Returns 0 for success, or a negative error value
+- */
+ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
+ 			     struct inode *inode)
+ {
+@@ -1352,15 +1558,28 @@ static int ext3_dx_add_entry(handle_t *h
+ 	struct super_block * sb = dir->i_sb;
+ 	struct ext3_dir_entry_2 *de;
+ 	int err;
+-
+-	frame = dx_probe(dentry, 0, &hinfo, frames, &err);
++	int curidx;
++	void *idx_lock, *leaf_lock, *newleaf_lock;
++	
++repeat:
++	frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err);
+ 	if (!frame)
+ 		return err;
+-	entries = frame->entries;
+-	at = frame->at;
+ 
+-	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
++	/* we're going to chage leaf, so lock it first */
++	leaf_lock = ext3_lock_htree(dir, frame->leaf, 1);
++
++	/* while locking leaf we just found may get splitted
++	 * so we need to check this */
++	if (!dx_check_full_path(frames, &hinfo)) {
++		ext3_unlock_htree(dir, leaf_lock);
++		dx_release(frames);
++		goto repeat;
++	}
++	if (!(bh = ext3_bread(handle,dir, frame->leaf, 0, &err))) {
++		printk("can't ext3_bread(%d) = %d\n", (int) frame->leaf, err);
+ 		goto cleanup;
++	}
+ 
+ 	BUFFER_TRACE(bh, "get_write_access");
+ 	err = ext3_journal_get_write_access(handle, bh);
+@@ -1373,6 +1592,35 @@ static int ext3_dx_add_entry(handle_t *h
+ 		goto cleanup;
+ 	}
+ 
++	/* our leaf has no enough space. hence, we have to
++	 * split it. so lock index for this leaf first */
++	curidx = frame->curidx;
++	idx_lock = ext3_lock_htree(dir, curidx, 1);
++
++	/* now check did path get changed? */
++	dx_release(frames);
++
++	frame = dx_probe(&dentry->d_name, dentry->d_parent->d_inode,
++			&hinfo, frames, &err);
++	if (!frame) {
++		/* FIXME: error handling here */
++		brelse(bh);
++		ext3_unlock_htree(dir, idx_lock);
++		return err;
++	}
++	
++	if (frame->curidx != curidx) {
++		/* path has been changed. we have to drop old lock
++		 * and repeat */
++		brelse(bh);
++		ext3_unlock_htree(dir, idx_lock);
++		ext3_unlock_htree(dir, leaf_lock);
++		dx_release(frames);
++		goto repeat;
++	}
++	entries = frame->entries;
++	at = frame->at;
++
+ 	/* Block full, should compress but for now just split */
+ 	dxtrace(printk("using %u of %u node entries\n",
+ 		       dx_get_count(entries), dx_get_limit(entries)));
+@@ -1384,7 +1632,8 @@ static int ext3_dx_add_entry(handle_t *h
+ 		struct dx_entry *entries2;
+ 		struct dx_node *node2;
+ 		struct buffer_head *bh2;
+-
++		void *nb_lock;
++		
+ 		if (levels && (dx_get_count(frames->entries) ==
+ 			       dx_get_limit(frames->entries))) {
+ 			ext3_warning(sb, __FUNCTION__,
+@@ -1395,6 +1644,7 @@ static int ext3_dx_add_entry(handle_t *h
+ 		bh2 = ext3_append (handle, dir, &newblock, &err);
+ 		if (!(bh2))
+ 			goto cleanup;
++		nb_lock = ext3_lock_htree(dir, newblock, 1);
+ 		node2 = (struct dx_node *)(bh2->b_data);
+ 		entries2 = node2->entries;
+ 		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
+@@ -1406,27 +1656,73 @@ static int ext3_dx_add_entry(handle_t *h
+ 		if (levels) {
+ 			unsigned icount1 = icount/2, icount2 = icount - icount1;
+ 			unsigned hash2 = dx_get_hash(entries + icount1);
++			void *ri_lock;
++
++			/* we have to protect root htree index against
++			 * another dx_add_entry() which would want to
++			 * split it too -bzzz */
++			ri_lock = ext3_lock_htree(dir, 0, 1);
++
++			/* as root index block blocked we must repeat
++			 * searching for current position of our 2nd index -bzzz */
++			dx_lock_bh(frame->bh);
++			frames->at = dx_find_position(frames->entries, hinfo.hash);
++			dx_unlock_bh(frame->bh);
++			
+ 			dxtrace(printk("Split index %i/%i\n", icount1, icount2));
+-				
+-			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
++	
++			BUFFER_TRACE(frame->bh, "get_write_access");
+ 			err = ext3_journal_get_write_access(handle,
+ 							     frames[0].bh);
+ 			if (err)
+ 				goto journal_error;
+-				
++			
++			/* copy index into new one */
+ 			memcpy ((char *) entries2, (char *) (entries + icount1),
+ 				icount2 * sizeof(struct dx_entry));
+-			dx_set_count (entries, icount1);
+ 			dx_set_count (entries2, icount2);
+ 			dx_set_limit (entries2, dx_node_limit(dir));
+ 
+ 			/* Which index block gets the new entry? */
+ 			if (at - entries >= icount1) {
++				/* unlock index we won't use */
++				ext3_unlock_htree(dir, idx_lock);
++				idx_lock = nb_lock;
+ 				frame->at = at = at - entries - icount1 + entries2;
+-				frame->entries = entries = entries2;
++				frame->entries = entries2;
++				frame->curidx = curidx = newblock;
+ 				swap(frame->bh, bh2);
++			} else {
++				/* we'll use old index,so new one may be freed */
++				ext3_unlock_htree(dir, nb_lock);
+ 			}
+-			dx_insert_block (frames + 0, hash2, newblock);
++		
++			/* NOTE: very subtle piece of code
++			 * competing dx_probe() may find 2nd level index in root
++			 * index, then we insert new index here and set new count
++			 * in that 2nd level index. so, dx_probe() may see 2nd
++			 * level index w/o hash it looks for. the solution is
++			 * to check root index after we locked just founded 2nd
++			 * level index -bzzz */
++			dx_lock_bh(frames[0].bh);
++			dx_insert_block (dir, frames + 0, hash2, newblock, 0);
++			dx_unlock_bh(frames[0].bh);
++			
++			/* now old and new 2nd level index blocks contain
++			 * all pointers, so dx_probe() may find it in the both.
++			 * it's OK -bzzz */
++			
++			dx_lock_bh(frame->bh);
++			dx_set_count(entries, icount1);
++			dx_unlock_bh(frame->bh);
++
++			/* now old 2nd level index block points to first half
++			 * of leafs. it's importand that dx_probe() must
++			 * check root index block for changes under
++			 * dx_lock_bh(frame->bh) -bzzz */
++
++			ext3_unlock_htree(dir, ri_lock);
++		
+ 			dxtrace(dx_show_index ("node", frames[1].entries));
+ 			dxtrace(dx_show_index ("node",
+ 			       ((struct dx_node *) bh2->b_data)->entries));
+@@ -1435,38 +1731,61 @@ static int ext3_dx_add_entry(handle_t *h
+ 				goto journal_error;
+ 			brelse (bh2);
+ 		} else {
++			unsigned long leaf = frame->leaf;
++
+ 			dxtrace(printk("Creating second level index...\n"));
+ 			memcpy((char *) entries2, (char *) entries,
+ 			       icount * sizeof(struct dx_entry));
+ 			dx_set_limit(entries2, dx_node_limit(dir));
+ 
+ 			/* Set up root */
++ 			dx_lock_bh(frames[0].bh);
+ 			dx_set_count(entries, 1);
+ 			dx_set_block(entries + 0, newblock);
+ 			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
++			dx_unlock_bh(frames[0].bh);
+ 
+ 			/* Add new access path frame */
+ 			frame = frames + 1;
+ 			frame->at = at = at - entries + entries2;
+ 			frame->entries = entries = entries2;
+ 			frame->bh = bh2;
++			frame->curidx = newblock;
++			frame->leaf = leaf;
+ 			err = ext3_journal_get_write_access(handle,
+ 							     frame->bh);
+ 			if (err)
+ 				goto journal_error;
++
++			/* first level index was root. it's already initialized */
++			/* we my unlock it now */
++			ext3_unlock_htree(dir, idx_lock);
++
++			/* current index is just created 2nd level index */
++			curidx = newblock;
++			idx_lock = nb_lock;
+ 		}
+ 		ext3_journal_dirty_metadata(handle, frames[0].bh);
+ 	}
+-	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
++	de = do_split(handle, dir, &bh, frame, &hinfo, &newleaf_lock, &err);
+ 	if (!de)
+ 		goto cleanup;
++
++	/* index splitted */
++	ext3_unlock_htree(dir, idx_lock);
++	
+ 	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
++
++	if (newleaf_lock)
++		ext3_unlock_htree(dir, newleaf_lock);
++	
+ 	bh = 0;
+ 	goto cleanup;
+ 	
+ journal_error:
+ 	ext3_std_error(dir->i_sb, err);
+ cleanup:
++	ext3_unlock_htree(dir, leaf_lock);
+ 	if (bh)
+ 		brelse(bh);
+ 	dx_release(frames);
+@@ -1899,6 +2218,7 @@ static int ext3_rmdir (struct inode * di
+ 	struct buffer_head * bh;
+ 	struct ext3_dir_entry_2 * de;
+ 	handle_t *handle;
++	void *lock;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+ 	if (IS_ERR(handle)) {
+@@ -1906,7 +2226,7 @@ static int ext3_rmdir (struct inode * di
+ 	}
+ 
+ 	retval = -ENOENT;
+-	bh = ext3_find_entry (dentry, &de);
++	bh = ext3_find_entry (dentry, &de, 1, &lock);
+ 	if (!bh)
+ 		goto end_rmdir;
+ 
+@@ -1917,14 +2237,19 @@ static int ext3_rmdir (struct inode * di
+ 	DQUOT_INIT(inode);
+ 
+ 	retval = -EIO;
+-	if (le32_to_cpu(de->inode) != inode->i_ino)
++	if (le32_to_cpu(de->inode) != inode->i_ino) {
++		ext3_unlock_htree(dir, lock);
+ 		goto end_rmdir;
++	}
+ 
+ 	retval = -ENOTEMPTY;
+-	if (!empty_dir (inode))
++	if (!empty_dir (inode)) {
++		ext3_unlock_htree(dir, lock);
+ 		goto end_rmdir;
++	}
+ 
+ 	retval = ext3_delete_entry(handle, dir, de, bh);
++	ext3_unlock_htree(dir, lock);
+ 	if (retval)
+ 		goto end_rmdir;
+ 	if (inode->i_nlink != 2)
+@@ -1957,6 +2282,7 @@ static int ext3_unlink(struct inode * di
+ 	struct buffer_head * bh;
+ 	struct ext3_dir_entry_2 * de;
+ 	handle_t *handle;
++	void *lock;
+ 
+ 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+ 	if (IS_ERR(handle)) {
+@@ -1967,7 +2293,7 @@ static int ext3_unlink(struct inode * di
+ 		handle->h_sync = 1;
+ 
+ 	retval = -ENOENT;
+-	bh = ext3_find_entry (dentry, &de);
++	bh = ext3_find_entry (dentry, &de, 1, &lock);
+ 	if (!bh)
+ 		goto end_unlink;
+ 
+@@ -1975,8 +2301,10 @@ static int ext3_unlink(struct inode * di
+ 	DQUOT_INIT(inode);
+ 
+ 	retval = -EIO;
+-	if (le32_to_cpu(de->inode) != inode->i_ino)
++	if (le32_to_cpu(de->inode) != inode->i_ino) {
++		ext3_unlock_htree(dir, lock);
+ 		goto end_unlink;
++	}
+ 	
+ 	if (!inode->i_nlink) {
+ 		ext3_warning (inode->i_sb, "ext3_unlink",
+@@ -1985,6 +2313,7 @@ static int ext3_unlink(struct inode * di
+ 		inode->i_nlink = 1;
+ 	}
+ 	retval = ext3_delete_entry(handle, dir, de, bh);
++	ext3_unlock_htree(dir, lock);
+ 	if (retval)
+ 		goto end_unlink;
+ 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+@@ -2106,6 +2435,7 @@ static int ext3_rename (struct inode * o
+ 	struct buffer_head * old_bh, * new_bh, * dir_bh;
+ 	struct ext3_dir_entry_2 * old_de, * new_de;
+ 	int retval;
++	void *lock1 = NULL, *lock2 = NULL, *lock3 = NULL;
+ 
+ 	old_bh = new_bh = dir_bh = NULL;
+ 
+@@ -2118,7 +2448,10 @@ static int ext3_rename (struct inode * o
+ 	if (IS_SYNC(old_dir) || IS_SYNC(new_dir))
+ 		handle->h_sync = 1;
+ 
+-	old_bh = ext3_find_entry (old_dentry, &old_de);
++	if (old_dentry->d_parent == new_dentry->d_parent)
++		down(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem);
++
++	old_bh = ext3_find_entry (old_dentry, &old_de, 1, &lock1 /* FIXME */);
+ 	/*
+ 	 *  Check for inode number is _not_ due to possible IO errors.
+ 	 *  We might rmdir the source, keep it as pwd of some process
+@@ -2131,7 +2464,7 @@ static int ext3_rename (struct inode * o
+ 		goto end_rename;
+ 
+ 	new_inode = new_dentry->d_inode;
+-	new_bh = ext3_find_entry (new_dentry, &new_de);
++	new_bh = ext3_find_entry (new_dentry, &new_de, 1, &lock2 /* FIXME */);
+ 	if (new_bh) {
+ 		if (!new_inode) {
+ 			brelse (new_bh);
+@@ -2194,7 +2527,7 @@ static int ext3_rename (struct inode * o
+ 		struct buffer_head *old_bh2;
+ 		struct ext3_dir_entry_2 *old_de2;
+ 		
+-		old_bh2 = ext3_find_entry(old_dentry, &old_de2);
++		old_bh2 = ext3_find_entry(old_dentry, &old_de2, 1, &lock3 /* FIXME */);
+ 		if (old_bh2) {
+ 			retval = ext3_delete_entry(handle, old_dir,
+ 						   old_de2, old_bh2);
+@@ -2237,6 +2570,14 @@ static int ext3_rename (struct inode * o
+ 	retval = 0;
+ 
+ end_rename:
++	if (lock1)
++		ext3_unlock_htree(old_dentry->d_parent->d_inode, lock1);
++	if (lock2)
++		ext3_unlock_htree(new_dentry->d_parent->d_inode, lock2);
++	if (lock3)
++		ext3_unlock_htree(old_dentry->d_parent->d_inode, lock3);
++	if (old_dentry->d_parent == new_dentry->d_parent)
++		up(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem);
+ 	brelse (dir_bh);
+ 	brelse (old_bh);
+ 	brelse (new_bh);
+@@ -2245,6 +2586,29 @@ end_rename:
+ }
+ 
+ /*
++ * this locking primitives are used to protect parts
++ * of dir's htree. protection unit is block: leaf or index
++ */
++static inline void *ext3_lock_htree(struct inode *dir,
++					unsigned long value, int rwlock)
++{
++	void *lock;
++	
++	if (!test_opt(dir->i_sb, PDIROPS))
++		return NULL;
++	lock = dynlock_lock(&EXT3_I(dir)->i_htree_lock, value, 1, GFP_KERNEL);
++	return lock;
++}
++
++static inline void ext3_unlock_htree(struct inode *dir,
++					void *lock)
++{
++	if (!test_opt(dir->i_sb, PDIROPS) || !lock)
++		return;
++	dynlock_unlock(&EXT3_I(dir)->i_htree_lock, lock);
++}
++
++/*
+  * directories can handle most operations...
+  */
+ struct inode_operations ext3_dir_inode_operations = {
+--- linux-2.4.18/fs/ext3/super.c~ext3-pdirops-2.4.18-chaos	2003-09-01 16:33:25.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/super.c	2003-09-02 12:46:29.000000000 +0400
+@@ -786,6 +786,8 @@ static int parse_options (char * options
+ 				return 0;
+ 			}
+ 		}
++		else if (!strcmp (this_char, "pdirops"))
++			set_opt (sbi->s_mount_opt, PDIROPS);
+ 		else if (!strcmp (this_char, "grpid") ||
+ 			 !strcmp (this_char, "bsdgroups"))
+ 			set_opt (*mount_options, GRPID);
+@@ -812,6 +814,9 @@ static int parse_options (char * options
+ 			if (want_numeric(value, "sb", sb_block))
+ 				return 0;
+ 		}
++		else if (!strcmp (this_char, "pdirops")) {
++			set_opt (sbi->s_mount_opt, PDIROPS);
++		}
+ #ifdef CONFIG_JBD_DEBUG
+ 		else if (!strcmp (this_char, "ro-after")) {
+ 			unsigned long v;
+@@ -969,6 +974,10 @@ static int ext3_setup_super(struct super
+ 		ext3_check_inodes_bitmap (sb);
+ 	}
+ #endif
++#ifdef S_PDIROPS
++	if (test_opt (sb, PDIROPS))
++		sb->s_flags |= S_PDIROPS;
++#endif
+ 	setup_ro_after(sb);
+ 	return res;
+ }
+@@ -1463,6 +1472,11 @@ struct super_block * ext3_read_super (st
+ 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
+ 		"writeback");
+ 
++	if (test_opt(sb, PDIROPS)) {
++		printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n");
++		sb->s_flags |= S_PDIROPS;
++	}
++		
+ 	return sb;
+ 
+ failed_mount3:
+--- linux-2.4.18/include/linux/ext3_fs.h~ext3-pdirops-2.4.18-chaos	2003-09-01 14:58:06.000000000 +0400
++++ linux-2.4.18-alexey/include/linux/ext3_fs.h	2003-09-02 11:46:15.000000000 +0400
+@@ -310,6 +310,7 @@ struct ext3_inode {
+ /*
+  * Mount flags
+  */
++#define EXT3_MOUNT_PDIROPS		0x800000/* Parallel dir operations */
+ #define EXT3_MOUNT_CHECK		0x0001	/* Do mount-time checks */
+ #define EXT3_MOUNT_GRPID		0x0004	/* Create files with directory's group */
+ #define EXT3_MOUNT_DEBUG		0x0008	/* Some debugging messages */
+--- linux-2.4.18/include/linux/ext3_fs_i.h~ext3-pdirops-2.4.18-chaos	2003-08-29 11:57:30.000000000 +0400
++++ linux-2.4.18-alexey/include/linux/ext3_fs_i.h	2003-09-02 11:46:15.000000000 +0400
+@@ -17,6 +17,7 @@
+ #define _LINUX_EXT3_FS_I
+ 
+ #include <linux/rwsem.h>
++#include <linux/dynlocks.h>
+ 
+ /*
+  * second extended file system inode data in memory
+@@ -73,6 +74,11 @@ struct ext3_inode_info {
+ 	 * by other means, so we have truncate_sem.
+ 	 */
+ 	struct rw_semaphore truncate_sem;
++
++	/* following fields for parallel directory operations -bzzz */
++	struct dynlock i_htree_lock;
++	struct semaphore i_append_sem;
++	struct semaphore i_rename_sem;
+ };
+ 
+ #endif	/* _LINUX_EXT3_FS_I */
+--- linux-2.4.18/fs/ext3/inode.c~ext3-pdirops-2.4.18-chaos	2003-09-01 16:33:25.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/inode.c	2003-09-02 11:46:15.000000000 +0400
+@@ -2454,6 +2454,9 @@ void ext3_read_inode(struct inode * inod
+ 	} else if (S_ISDIR(inode->i_mode)) {
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
++		dynlock_init(&EXT3_I(inode)->i_htree_lock);
++		sema_init(&EXT3_I(inode)->i_rename_sem, 1);
++		sema_init(&EXT3_I(inode)->i_append_sem, 1);
+ 	} else if (S_ISLNK(inode->i_mode)) {
+ 		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+--- linux-2.4.18/fs/ext3/ialloc.c~ext3-pdirops-2.4.18-chaos	2003-09-01 14:58:05.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/ialloc.c	2003-09-02 11:46:15.000000000 +0400
+@@ -601,6 +601,9 @@ repeat:
+ 		return ERR_PTR(-EDQUOT);
+ 	}
+ 	ext3_debug ("allocating inode %lu\n", inode->i_ino);
++	dynlock_init(&EXT3_I(inode)->i_htree_lock);
++	sema_init(&EXT3_I(inode)->i_rename_sem, 1);
++	sema_init(&EXT3_I(inode)->i_append_sem, 1);
+ 	return inode;
+ 
+ fail:
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops.patch b/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops.patch
new file mode 100644
index 0000000000000000000000000000000000000000..72a5156bdada09a20c6c9f7e1e702e91bdfd2caf
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops.patch
@@ -0,0 +1,63 @@
+ fs/ext3/namei.c    |   31 +++++++++++++++++++++++++++++++
+ include/linux/fs.h |    1 +
+ 2 files changed, 32 insertions(+)
+
+--- linux-2.4.18-p4smp1Guser/include/linux/fs.h~ext3-raw-lookup	Thu Sep 25 15:59:59 2003
++++ linux-2.4.18-p4smp1Guser-pschwan/include/linux/fs.h	Thu Sep 25 15:59:59 2003
+@@ -911,6 +911,7 @@ struct inode_operations {
+ 	int (*create) (struct inode *,struct dentry *,int);
+ 	int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *);
++	int (*lookup_raw) (struct inode *, const char *, int, ino_t *);
+ 	struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags);
+ 	int (*link) (struct dentry *,struct inode *,struct dentry *);
+ 	int (*link_raw) (struct nameidata *,struct nameidata *);
+--- linux-2.4.18-p4smp1Guser/fs/ext3/namei.c~ext3-raw-lookup	Thu Sep 25 15:59:59 2003
++++ linux-2.4.18-p4smp1Guser-pschwan/fs/ext3/namei.c	Thu Sep 25 16:16:48 2003
+@@ -1121,6 +1121,36 @@ static struct dentry *ext3_lookup(struct
+ 	return NULL;
+ }
+ 
++static int ext3_lookup_raw(struct inode *dir, const char *name,
++				int len, ino_t *data)
++{
++	struct ext3_dir_entry_2 *de;
++	struct buffer_head *bh;
++	struct dentry parent;
++	struct dentry dentry;
++	void *lock = NULL;
++
++	if (len > EXT3_NAME_LEN)
++		return -ENAMETOOLONG;
++
++	parent.d_inode = dir;
++	dentry.d_parent = &parent;
++	dentry.d_name.name = name;
++	dentry.d_name.len = len;
++
++	bh = ext3_find_entry(&dentry, &de, 0, &lock);
++	if (bh) {
++		unsigned long ino = le32_to_cpu(de->inode);
++		ext3_unlock_htree(dir, lock);
++		brelse (bh);
++		if (data)
++			*data = ino;
++		return 0; /* found name */
++	}
++
++	return -ENOENT;
++}
++
+ #define S_SHIFT 12
+ static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = {
+ 	[S_IFREG >> S_SHIFT]	EXT3_FT_REG_FILE,
+@@ -2623,6 +2653,7 @@ static inline void ext3_unlock_htree(str
+ struct inode_operations ext3_dir_inode_operations = {
+ 	create:		ext3_create,		/* BKL held */
+ 	lookup:		ext3_lookup,		/* BKL held */
++	lookup_raw:	ext3_lookup_raw,	/* BKL held */
+ 	link:		ext3_link,		/* BKL held */
+ 	unlink:		ext3_unlink,		/* BKL held */
+ 	symlink:	ext3_symlink,		/* BKL held */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-raw-lookup.patch b/lustre/kernel_patches/patches/ext3-raw-lookup.patch
new file mode 100644
index 0000000000000000000000000000000000000000..216accc9684f62cd535c99f96dd28c4f275f933b
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-raw-lookup.patch
@@ -0,0 +1,61 @@
+ fs/ext3/namei.c    |   29 +++++++++++++++++++++++++++++
+ include/linux/fs.h |    1 +
+ 2 files changed, 30 insertions(+)
+
+--- linux-2.4.20-vanilla/include/linux/fs.h~ext3-raw-lookup	2003-09-13 17:03:05.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/fs.h	2003-09-15 10:16:38.000000000 +0400
+@@ -865,6 +865,7 @@ struct inode_operations {
+ 	int (*create) (struct inode *,struct dentry *,int);
+ 	int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *);
++	int (*lookup_raw) (struct inode *, const char *, int, ino_t *);
+ 	struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags);
+ 	int (*link) (struct dentry *,struct inode *,struct dentry *);
+ 	int (*link_raw) (struct nameidata *,struct nameidata *);
+--- linux-2.4.20-vanilla/fs/ext3/namei.c~ext3-raw-lookup	2003-09-13 17:03:05.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/ext3/namei.c	2003-09-15 10:18:52.000000000 +0400
+@@ -957,6 +957,34 @@ static struct dentry *ext3_lookup(struct
+ 	return NULL;
+ }
+ 
++static int ext3_lookup_raw(struct inode *dir, const char *name,
++				int len, ino_t *data)
++{
++	struct ext3_dir_entry_2 *de;
++	struct buffer_head *bh;
++	struct dentry parent;
++	struct dentry dentry;
++
++	if (len > EXT3_NAME_LEN)
++		return -ENAMETOOLONG;
++
++	parent.d_inode = dir;
++	dentry.d_parent = &parent;
++	dentry.d_name.name = name;
++	dentry.d_name.len = len;
++
++	bh = ext3_find_entry(&dentry, &de);
++	if (bh) {
++		unsigned long ino = le32_to_cpu(de->inode);
++		brelse (bh);
++		if (data)
++			*data = ino;
++		return 0; /* found name */
++	}
++
++	return -ENOENT;
++}
++
+ #define S_SHIFT 12
+ static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = {
+ 	[S_IFREG >> S_SHIFT]	EXT3_FT_REG_FILE,
+@@ -2247,6 +2275,7 @@ end_rename:
+ struct inode_operations ext3_dir_inode_operations = {
+ 	create:		ext3_create,		/* BKL held */
+ 	lookup:		ext3_lookup,		/* BKL held */
++	lookup_raw:	ext3_lookup_raw,	/* BKL held */
+ 	link:		ext3_link,		/* BKL held */
+ 	unlink:		ext3_unlink,		/* BKL held */
+ 	symlink:	ext3_symlink,		/* BKL held */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.18.patch b/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.18.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4ee1e2c917ff57bcf6453fbad66619f5aa084d5f
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.18.patch
@@ -0,0 +1,180 @@
+ fs/ext3/xattr.c            |   12 +++++-
+ fs/ext3/xattr_trusted.c    |   86 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_xattr.h |    6 +++
+ 3 files changed, 102 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.18-chaos/fs/ext3/xattr.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/xattr.c	2003-10-22 14:23:53.000000000 +0400
++++ linux-2.4.18-chaos/fs/ext3/xattr.c	2003-10-24 01:01:03.000000000 +0400
+@@ -1789,18 +1789,25 @@
+ int __init
+ init_ext3_xattr(void)
+ {
++	int error;
++
+ 	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
+ 		sizeof(struct mb_cache_entry) +
+ 		sizeof(struct mb_cache_entry_index), 1, 61);
+ 	if (!ext3_xattr_cache)
+ 		return -ENOMEM;
+ 
+-	return 0;
++	error = init_ext3_xattr_trusted();
++	if (error)
++		mb_cache_destroy(ext3_xattr_cache);
++
++	return error;
+ }
+ 
+ void
+ exit_ext3_xattr(void)
+ {
++	exit_ext3_xattr_trusted();
+ 	if (ext3_xattr_cache)
+ 		mb_cache_destroy(ext3_xattr_cache);
+ 	ext3_xattr_cache = NULL;
+@@ -1811,12 +1818,13 @@
+ int __init
+ init_ext3_xattr(void)
+ {
+-	return 0;
++	return init_ext3_xattr_trusted();
+ }
+ 
+ void
+ exit_ext3_xattr(void)
+ {
++	exit_ext3_xattr_trusted();
+ }
+ 
+ #endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+Index: linux-2.4.18-chaos/fs/ext3/xattr_trusted.c
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/xattr_trusted.c	2003-10-24 01:01:03.000000000 +0400
++++ linux-2.4.18-chaos/fs/ext3/xattr_trusted.c	2003-10-24 01:01:03.000000000 +0400
+@@ -0,0 +1,86 @@
++/*
++ * linux/fs/ext3/xattr_trusted.c
++ * Handler for trusted extended attributes.
++ *
++ * Copyright (C) 2003 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#define XATTR_TRUSTED_PREFIX "trusted."
++
++static size_t
++ext3_xattr_trusted_list(char *list, struct inode *inode,
++			const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_trusted_get(struct inode *inode, const char *name,
++		       void *buffer, size_t size)
++{
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_trusted_set(struct inode *inode, const char *name,
++		       const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_TRUSTED, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_trusted_handler = {
++	.prefix	= XATTR_TRUSTED_PREFIX,
++	.list	= ext3_xattr_trusted_list,
++	.get	= ext3_xattr_trusted_get,
++	.set	= ext3_xattr_trusted_set,
++};
++
++int __init
++init_ext3_xattr_trusted(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_TRUSTED,
++				   &ext3_xattr_trusted_handler);
++}
++
++void
++exit_ext3_xattr_trusted(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_TRUSTED,
++			      &ext3_xattr_trusted_handler);
++}
+Index: linux-2.4.18-chaos/include/linux/ext3_xattr.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/ext3_xattr.h	2003-10-22 14:23:51.000000000 +0400
++++ linux-2.4.18-chaos/include/linux/ext3_xattr.h	2003-10-24 01:01:03.000000000 +0400
+@@ -19,6 +19,10 @@
+ /* Name indexes */
+ #define EXT3_XATTR_INDEX_MAX			10
+ #define EXT3_XATTR_INDEX_USER			1
++#define EXT3_XATTR_INDEX_TRUSTED		4
++#define EXT3_XATTR_INDEX_LUSTRE			5
++#define EXT3_XATTR_INDEX_SECURITY		6
++  
+ 
+ struct ext3_xattr_header {
+ 	__u32	h_magic;	/* magic number for identification */
+@@ -82,6 +86,9 @@
+ extern int init_ext3_xattr(void) __init;
+ extern void exit_ext3_xattr(void);
+ 
++extern int init_ext3_xattr_trusted(void) __init;
++extern void exit_ext3_xattr_trusted(void);
++
+ # else  /* CONFIG_EXT3_FS_XATTR */
+ #  define ext3_setxattr		NULL
+ #  define ext3_getxattr		NULL
+Index: linux-2.4.18-chaos/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.18-chaos.orig/fs/ext3/Makefile	2003-10-22 14:23:53.000000000 +0400
++++ linux-2.4.18-chaos/fs/ext3/Makefile	2003-10-24 01:02:28.000000000 +0400
+@@ -13,7 +13,7 @@
+ 
+ obj-y    := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+ 		ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o \
+-		extents.o
++		extents.o xattr_trusted.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
diff --git a/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.20.patch b/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0a3bdb8a175ce0effe983fd458f54faee8f4ad7a
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.20.patch
@@ -0,0 +1,180 @@
+ fs/ext3/xattr.c            |   12 +++++-
+ fs/ext3/xattr_trusted.c    |   86 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_xattr.h |    6 +++
+ 3 files changed, 102 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.20/fs/ext3/xattr.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/xattr.c	2003-10-22 02:29:40.000000000 +0400
++++ linux-2.4.20/fs/ext3/xattr.c	2003-10-24 01:03:22.000000000 +0400
+@@ -1771,18 +1771,25 @@
+ int __init
+ init_ext3_xattr(void)
+ {
++	int error;
++
+ 	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
+ 		sizeof(struct mb_cache_entry) +
+ 		sizeof(struct mb_cache_entry_index), 1, 61);
+ 	if (!ext3_xattr_cache)
+ 		return -ENOMEM;
+ 
+-	return 0;
++	error = init_ext3_xattr_trusted();
++	if (error)
++		mb_cache_destroy(ext3_xattr_cache);
++
++	return error;
+ }
+ 
+ void
+ exit_ext3_xattr(void)
+ {
++	exit_ext3_xattr_trusted();
+ 	if (ext3_xattr_cache)
+ 		mb_cache_destroy(ext3_xattr_cache);
+ 	ext3_xattr_cache = NULL;
+@@ -1793,12 +1800,13 @@
+ int __init
+ init_ext3_xattr(void)
+ {
+-	return 0;
++	return init_ext3_xattr_trusted();
+ }
+ 
+ void
+ exit_ext3_xattr(void)
+ {
++	exit_ext3_xattr_trusted();
+ }
+ 
+ #endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+Index: linux-2.4.20/fs/ext3/xattr_trusted.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/xattr_trusted.c	2003-10-24 01:03:22.000000000 +0400
++++ linux-2.4.20/fs/ext3/xattr_trusted.c	2003-10-24 01:03:22.000000000 +0400
+@@ -0,0 +1,86 @@
++/*
++ * linux/fs/ext3/xattr_trusted.c
++ * Handler for trusted extended attributes.
++ *
++ * Copyright (C) 2003 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#define XATTR_TRUSTED_PREFIX "trusted."
++
++static size_t
++ext3_xattr_trusted_list(char *list, struct inode *inode,
++			const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_trusted_get(struct inode *inode, const char *name,
++		       void *buffer, size_t size)
++{
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_trusted_set(struct inode *inode, const char *name,
++		       const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!capable(CAP_SYS_ADMIN))
++		return -EPERM;
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_TRUSTED, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_trusted_handler = {
++	.prefix	= XATTR_TRUSTED_PREFIX,
++	.list	= ext3_xattr_trusted_list,
++	.get	= ext3_xattr_trusted_get,
++	.set	= ext3_xattr_trusted_set,
++};
++
++int __init
++init_ext3_xattr_trusted(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_TRUSTED,
++				   &ext3_xattr_trusted_handler);
++}
++
++void
++exit_ext3_xattr_trusted(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_TRUSTED,
++			      &ext3_xattr_trusted_handler);
++}
+Index: linux-2.4.20/include/linux/ext3_xattr.h
+===================================================================
+--- linux-2.4.20.orig/include/linux/ext3_xattr.h	2003-10-22 02:29:39.000000000 +0400
++++ linux-2.4.20/include/linux/ext3_xattr.h	2003-10-24 01:03:22.000000000 +0400
+@@ -21,6 +21,9 @@
+ #define EXT3_XATTR_INDEX_USER			1
+ #define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
+ #define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++#define EXT3_XATTR_INDEX_TRUSTED		4
++#define EXT3_XATTR_INDEX_LUSTRE			5
++#define EXT3_XATTR_INDEX_SECURITY		6
+ 
+ struct ext3_xattr_header {
+ 	__u32	h_magic;	/* magic number for identification */
+@@ -84,6 +87,9 @@
+ extern int init_ext3_xattr(void) __init;
+ extern void exit_ext3_xattr(void);
+ 
++extern int init_ext3_xattr_trusted(void) __init;
++extern void exit_ext3_xattr_trusted(void);
++
+ # else  /* CONFIG_EXT3_FS_XATTR */
+ #  define ext3_setxattr		NULL
+ #  define ext3_getxattr		NULL
+Index: linux-2.4.20/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/Makefile	2003-10-22 02:29:40.000000000 +0400
++++ linux-2.4.20/fs/ext3/Makefile	2003-10-24 01:03:47.000000000 +0400
+@@ -12,7 +12,8 @@
+ export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+-		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
++		xattr_trusted.o
+ obj-m    := $(O_TARGET)
+ 
+ export-objs += xattr.o
diff --git a/lustre/kernel_patches/patches/ext3-use-after-free-2.4.19-pre1.patch b/lustre/kernel_patches/patches/ext3-use-after-free-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..595db5486144daa07c4992399c5a10e9ff9516cb
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-use-after-free-2.4.19-pre1.patch
@@ -0,0 +1,53 @@
+ ./fs/ext3/namei.c |   11 +++++------
+ 1 files changed, 5 insertions(+), 6 deletions(-)
+
+Index: linux-2.4.19-pre1/./fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/./fs/ext3/namei.c	2003-11-21 01:52:06.000000000 +0300
++++ linux-2.4.19-pre1/./fs/ext3/namei.c	2003-11-21 01:58:15.000000000 +0300
+@@ -1522,8 +1522,11 @@
+ {
+ 	int err = ext3_add_entry(handle, dentry, inode);
+ 	if (!err) {
+-		d_instantiate(dentry, inode);
+-		return 0;
++		err = ext3_mark_inode_dirty(handle, inode);
++		if (err == 0) {
++			d_instantiate(dentry, inode);
++			return 0;
++		}
+ 	}
+ 	ext3_dec_count(handle, inode);
+ 	iput(inode);
+@@ -1559,7 +1562,6 @@
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+-		ext3_mark_inode_dirty(handle, inode);
+ 		err = ext3_add_nondir(handle, dentry, inode);
+ 	}
+ 	ext3_journal_stop(handle, dir);
+@@ -1586,7 +1588,6 @@
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		init_special_inode(inode, mode, rdev);
+-		ext3_mark_inode_dirty(handle, inode);
+ 		err = ext3_add_nondir(handle, dentry, inode);
+ 	}
+ 	ext3_journal_stop(handle, dir);
+@@ -2035,7 +2036,6 @@
+ 		inode->i_size = l-1;
+ 	}
+ 	inode->u.ext3_i.i_disksize = inode->i_size;
+-	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+@@ -2069,7 +2069,6 @@
+ 	ext3_inc_count(handle, inode);
+ 	atomic_inc(&inode->i_count);
+ 
+-	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
diff --git a/lustre/kernel_patches/patches/ext3-use-after-free-suse.patch b/lustre/kernel_patches/patches/ext3-use-after-free-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1dab6d85009ce9f1dbe1e022b87c46cba35d1609
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-use-after-free-suse.patch
@@ -0,0 +1,53 @@
+ ./fs/ext3/namei.c |   11 +++++------
+ 1 files changed, 5 insertions(+), 6 deletions(-)
+
+Index: linux-2.4.19.SuSE/./fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/./fs/ext3/namei.c	Sun Nov 16 01:02:51 2003
++++ linux-2.4.19.SuSE/./fs/ext3/namei.c	Sun Nov 16 01:14:50 2003
+@@ -1523,8 +1523,11 @@
+ {
+ 	int err = ext3_add_entry(handle, dentry, inode);
+ 	if (!err) {
+-		d_instantiate(dentry, inode);
+-		return 0;
++		err = ext3_mark_inode_dirty(handle, inode);
++		if (err == 0) {
++			d_instantiate(dentry, inode);
++			return 0;
++		}
+ 	}
+ 	ext3_dec_count(handle, inode);
+ 	iput(inode);
+@@ -1560,7 +1563,6 @@
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+-		ext3_mark_inode_dirty(handle, inode);
+ 		err = ext3_add_nondir(handle, dentry, inode);
+ 	}
+ 	ext3_journal_stop(handle, dir);
+@@ -1590,7 +1592,6 @@
+ #ifdef CONFIG_EXT3_FS_XATTR
+ 		inode->i_op = &ext3_special_inode_operations;
+ #endif
+-		ext3_mark_inode_dirty(handle, inode);
+ 		err = ext3_add_nondir(handle, dentry, inode);
+ 	}
+ 	ext3_journal_stop(handle, dir);
+@@ -2039,7 +2040,6 @@
+ 		inode->i_size = l-1;
+ 	}
+ 	EXT3_I(inode)->i_disksize = inode->i_size;
+-	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ out_stop:
+ 	ext3_journal_stop(handle, dir);
+@@ -2073,7 +2073,6 @@
+ 	ext3_inc_count(handle, inode);
+ 	atomic_inc(&inode->i_count);
+ 
+-	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_nondir(handle, dentry, inode);
+ 	ext3_journal_stop(handle, dir);
+ 	return err;
diff --git a/lustre/kernel_patches/patches/ext3-wantedi-2.6.patch b/lustre/kernel_patches/patches/ext3-wantedi-2.6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ce897f51ba9d9e27fb44a63781e5dec4db0fc871
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-wantedi-2.6.patch
@@ -0,0 +1,192 @@
+ fs/ext3/ialloc.c        |   35 ++++++++++++++++++++++++++++++++++-
+ fs/ext3/ioctl.c         |   25 +++++++++++++++++++++++++
+ fs/ext3/namei.c         |   21 +++++++++++++++++----
+ include/linux/dcache.h  |    5 +++++
+ include/linux/ext3_fs.h |    5 ++++-
+ 5 files changed, 85 insertions(+), 6 deletions(-)
+
+--- linux-2.6.0-test5/fs/ext3/ialloc.c~ext3-wantedi-2.6	2003-06-24 18:05:25.000000000 +0400
++++ linux-2.6.0-test5-alexey/fs/ext3/ialloc.c	2003-09-28 13:40:23.000000000 +0400
+@@ -420,7 +420,8 @@ static int find_group_other(struct super
+  * For other inodes, search forward from the parent directory's block
+  * group to find a free inode.
+  */
+-struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
++struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode,
++				unsigned long goal)
+ {
+ 	struct super_block *sb;
+ 	struct buffer_head *bitmap_bh = NULL;
+@@ -448,6 +449,38 @@ struct inode *ext3_new_inode(handle_t *h
+ 
+ 	es = EXT3_SB(sb)->s_es;
+ 	sbi = EXT3_SB(sb);
++	if (goal) {
++		group = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
++		ino = (goal - 1) % EXT3_INODES_PER_GROUP(sb);
++		gdp = ext3_get_group_desc(sb, group, &bh2);
++
++		err = -EIO;
++		bitmap_bh = read_inode_bitmap (sb, group);
++		if (!bitmap_bh)
++			goto fail;
++
++		BUFFER_TRACE(bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, bitmap_bh);
++		if (err) goto fail;
++
++		if (ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
++					ino, bitmap_bh->b_data)) {
++			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
++			/* Oh well, we tried. */
++			goto continue_allocation;
++		}
++
++		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++		err = ext3_journal_dirty_metadata(handle, bitmap_bh);
++		if (err) goto fail;
++
++		/* We've shortcircuited the allocation system successfully,
++		 * now finish filling in the inode.
++		 */
++		goto got;
++	}
++
++continue_allocation:
+ 	if (S_ISDIR(mode)) {
+ 		if (test_opt (sb, OLDALLOC))
+ 			group = find_group_dir(sb, dir);
+--- linux-2.6.0-test5/fs/ext3/ioctl.c~ext3-wantedi-2.6	2003-06-24 18:05:25.000000000 +0400
++++ linux-2.6.0-test5-alexey/fs/ext3/ioctl.c	2003-09-28 13:45:54.000000000 +0400
+@@ -24,6 +24,31 @@ int ext3_ioctl (struct inode * inode, st
+ 	ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
+ 
+ 	switch (cmd) {
++	case EXT3_IOC_CREATE_INUM: {
++		char name[32];
++		struct dentry *dchild, *dparent;
++		int rc = 0;
++
++		dparent = list_entry(inode->i_dentry.next, struct dentry,
++				     d_alias);
++		snprintf(name, sizeof name, "%lu", arg);
++		dchild = lookup_one_len(name, dparent, strlen(name));
++		if (dchild->d_inode) {
++			printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n",
++			       dparent->d_name.len, dparent->d_name.name, arg,
++			       dchild->d_inode->i_ino);
++			rc = -EEXIST;
++		} else {
++			dchild->d_fsdata = (void *)arg;
++			rc = vfs_create(inode, dchild, 0644, NULL);
++			if (rc)
++				printk(KERN_ERR "vfs_create: %d\n", rc);
++			else if (dchild->d_inode->i_ino != arg)
++				rc = -EEXIST;
++		}
++		dput(dchild);
++		return rc;
++	}
+ 	case EXT3_IOC_GETFLAGS:
+ 		flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
+ 		return put_user(flags, (int *) arg);
+--- linux-2.6.0-test5/fs/ext3/namei.c~ext3-wantedi-2.6	2003-09-19 18:01:48.000000000 +0400
++++ linux-2.6.0-test5-alexey/fs/ext3/namei.c	2003-09-28 13:40:23.000000000 +0400
+@@ -1617,6 +1617,19 @@ static int ext3_add_nondir(handle_t *han
+ 	return err;
+ }
+ 
++static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
++						int mode, struct dentry *dentry)
++{
++	unsigned long inum = 0;
++
++	if (dentry->d_fsdata != NULL) {
++		struct dentry_params *param =
++			(struct dentry_params *) dentry->d_fsdata;
++		inum = param->p_inum;
++	}
++	return ext3_new_inode(handle, dir, mode, inum);
++}
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1640,7 +1653,7 @@ static int ext3_create (struct inode * d
+ 	if (IS_DIRSYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+@@ -1670,7 +1683,7 @@ static int ext3_mknod (struct inode * di
+ 	if (IS_DIRSYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		init_special_inode(inode, inode->i_mode, rdev);
+@@ -1702,7 +1715,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_DIRSYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -2094,7 +2107,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_DIRSYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+--- linux-2.6.0-test5/include/linux/dcache.h~ext3-wantedi-2.6	2003-09-28 13:40:22.000000000 +0400
++++ linux-2.6.0-test5-alexey/include/linux/dcache.h	2003-09-28 13:40:23.000000000 +0400
+@@ -25,6 +25,11 @@ struct vfsmount;
+ 
+ #define IS_ROOT(x) ((x) == (x)->d_parent)
+ 
++struct dentry_params {
++	unsigned long   p_inum;
++	void            *p_ptr;
++};
++
+ /*
+  * "quick string" -- eases parameter passing, but more importantly
+  * saves "metadata" about the string (ie length and the hash).
+--- linux-2.6.0-test5/include/linux/ext3_fs.h~ext3-wantedi-2.6	2003-09-19 18:01:10.000000000 +0400
++++ linux-2.6.0-test5-alexey/include/linux/ext3_fs.h	2003-09-28 13:40:23.000000000 +0400
+@@ -203,6 +203,7 @@ struct ext3_group_desc
+ #define	EXT3_IOC_SETFLAGS		_IOW('f', 2, long)
+ #define	EXT3_IOC_GETVERSION		_IOR('f', 3, long)
+ #define	EXT3_IOC_SETVERSION		_IOW('f', 4, long)
++/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
+ #define	EXT3_IOC_GETVERSION_OLD		_IOR('v', 1, long)
+ #define	EXT3_IOC_SETVERSION_OLD		_IOW('v', 2, long)
+ #ifdef CONFIG_JBD_DEBUG
+@@ -707,7 +708,8 @@ extern int ext3fs_dirhash(const char *na
+ 			  dx_hash_info *hinfo);
+ 
+ /* ialloc.c */
+-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
++extern struct inode * ext3_new_inode (handle_t *, struct inode *, int,
++				      unsigned long);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+ extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
+ extern unsigned long ext3_count_free_inodes (struct super_block *);
+@@ -792,4 +794,5 @@ extern struct inode_operations ext3_fast
+ 
+ #endif	/* __KERNEL__ */
+ 
++#define EXT3_IOC_CREATE_INUM			_IOW('f', 5, long)
+ #endif	/* _LINUX_EXT3_FS_H */
+
+_
diff --git a/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix.patch b/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix.patch
new file mode 100644
index 0000000000000000000000000000000000000000..05fcf6106a8f9142fa62cbff3651a7bab6e8f936
--- /dev/null
+++ b/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix.patch
@@ -0,0 +1,18 @@
+Index: linux-2.4.20/fs/ext3/xattr.c
+===================================================================
+--- linux-2.4.20.orig/fs/ext3/xattr.c	2003-11-13 17:14:52.000000000 +0300
++++ linux-2.4.20/fs/ext3/xattr.c	2003-11-21 16:43:48.000000000 +0300
+@@ -1293,9 +1293,10 @@
+ 				goto cleanup;
+ 			memcpy(header, HDR(bh), bh->b_size);
+ 			header->h_refcount = cpu_to_le32(1);
+-			offset = (char *)header - bh->b_data;
+-			here = ENTRY((char *)here + offset);
+-			last = ENTRY((char *)last + offset);
++			offset = (char *)here - bh->b_data;
++			here = ENTRY((char *)header + offset);
++			offset = (char *)last - bh->b_data;
++			last = ENTRY((char *)header + offset);
+ 		}
+ 	} else {
+ 		/* Allocate a buffer where we construct the new block. */
diff --git a/lustre/kernel_patches/patches/extN-wantedi-2.4.19-suse.patch b/lustre/kernel_patches/patches/extN-wantedi-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..02cfef1e2bdaf5e0d6185b761d4697dbcf004596
--- /dev/null
+++ b/lustre/kernel_patches/patches/extN-wantedi-2.4.19-suse.patch
@@ -0,0 +1,226 @@
+ fs/ext3/ialloc.c        |   40 ++++++++++++++++++++++++++++++++++++++--
+ fs/ext3/inode.c         |    2 +-
+ fs/ext3/ioctl.c         |   25 +++++++++++++++++++++++++
+ fs/ext3/namei.c         |   21 +++++++++++++++++----
+ include/linux/dcache.h  |    5 +++++
+ include/linux/ext3_fs.h |    5 ++++-
+ 6 files changed, 90 insertions(+), 8 deletions(-)
+
+Index: linux-2.4.19.SuSE/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/namei.c	Sun Nov 16 01:18:04 2003
++++ linux-2.4.19.SuSE/fs/ext3/namei.c	Sun Nov 16 01:23:20 2003
+@@ -1534,6 +1534,19 @@
+ 	return err;
+ }
+ 
++static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
++						int mode, struct dentry *dentry)
++{
++	unsigned long inum = 0;
++
++	if (dentry->d_fsdata != NULL) {
++		struct dentry_params *param =
++			(struct dentry_params *) dentry->d_fsdata;
++		inum = param->p_inum;
++	}
++	return ext3_new_inode(handle, dir, mode, inum);
++}
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1557,7 +1570,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+@@ -1585,7 +1598,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		init_special_inode(inode, inode->i_mode, rdev);
+@@ -1618,7 +1631,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -2013,7 +2026,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+Index: linux-2.4.19.SuSE/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/ialloc.c	Sun Nov 16 01:20:17 2003
++++ linux-2.4.19.SuSE/fs/ext3/ialloc.c	Sun Nov 16 01:24:49 2003
+@@ -330,7 +330,8 @@
+  * For other inodes, search forward from the parent directory's block
+  * group to find a free inode.
+  */
+-struct inode * ext3_new_inode (handle_t *handle, struct inode * dir, int mode)
++struct inode * ext3_new_inode(handle_t *handle, const struct inode * dir,
++			      int mode, unsigned long goal)
+ {
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+@@ -355,7 +356,41 @@
+ 	init_rwsem(&inode->u.ext3_i.truncate_sem);
+ 
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
++
++	if (goal) {
++		i = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
++		j = (goal - 1) % EXT3_INODES_PER_GROUP(sb);
++		gdp = ext3_get_group_desc(sb, i, &bh2);
++
++		bitmap_nr = load_inode_bitmap (sb, i);
++		if (bitmap_nr < 0) {
++			err = bitmap_nr;
++			goto fail;
++		}
++
++		bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
++
++		BUFFER_TRACE(bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, bh);
++		if (err) goto fail;
++
++		if (ext3_set_bit(j, bh->b_data)) {
++			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
++			/* Oh well, we tried. */
++			goto repeat;
++		}
++
++		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++		err = ext3_journal_dirty_metadata(handle, bh);
++		if (err) goto fail;
++
++		/* We've shortcircuited the allocation system successfully,
++		 * now finish filling in the inode.
++		 */
++		goto have_bit_and_group;
++	}
++
+ repeat:
+ 	gdp = NULL;
+ 	i = 0;
+@@ -470,6 +505,7 @@
+ 		}
+ 		goto repeat;
+ 	}
++ have_bit_and_group:
+ 	j += i * EXT3_INODES_PER_GROUP(sb) + 1;
+ 	if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
+ 		ext3_error (sb, "ext3_new_inode",
+Index: linux-2.4.19.SuSE/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/inode.c	Sun Nov 16 01:20:17 2003
++++ linux-2.4.19.SuSE/fs/ext3/inode.c	Sun Nov 16 01:23:20 2003
+@@ -2168,7 +2168,7 @@
+ 	if (IS_ERR(handle))
+ 		goto out_truncate;
+ 
+-	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0);
+ 	if (IS_ERR(new_inode)) {
+ 		ext3_debug("truncate inode %lu directly (no new inodes)\n",
+ 			   old_inode->i_ino);
+Index: linux-2.4.19.SuSE/fs/ext3/ioctl.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/ioctl.c	Fri Nov  9 14:25:04 2001
++++ linux-2.4.19.SuSE/fs/ext3/ioctl.c	Sun Nov 16 01:23:20 2003
+@@ -23,6 +23,31 @@
+ 	ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
+ 
+ 	switch (cmd) {
++	case EXT3_IOC_CREATE_INUM: {
++		char name[32];
++		struct dentry *dchild, *dparent;
++		int rc = 0;
++
++		dparent = list_entry(inode->i_dentry.next, struct dentry,
++				     d_alias);
++		snprintf(name, sizeof name, "%lu", arg);
++		dchild = lookup_one_len(name, dparent, strlen(name));
++		if (dchild->d_inode) {
++			printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n",
++			       dparent->d_name.len, dparent->d_name.name, arg,
++			       dchild->d_inode->i_ino);
++			rc = -EEXIST;
++		} else {
++			dchild->d_fsdata = (void *)arg;
++			rc = vfs_create(inode, dchild, 0644);
++			if (rc)
++				printk(KERN_ERR "vfs_create: %d\n", rc);
++			else if (dchild->d_inode->i_ino != arg)
++				rc = -EEXIST;
++		}
++		dput(dchild);
++		return rc;
++	}
+ 	case EXT3_IOC_GETFLAGS:
+ 		flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
+ 		return put_user(flags, (int *) arg);
+Index: linux-2.4.19.SuSE/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/ext3_fs.h	Sun Nov 16 01:20:17 2003
++++ linux-2.4.19.SuSE/include/linux/ext3_fs.h	Sun Nov 16 01:25:42 2003
+@@ -202,6 +202,7 @@
+ #define	EXT3_IOC_SETFLAGS		_IOW('f', 2, long)
+ #define	EXT3_IOC_GETVERSION		_IOR('f', 3, long)
+ #define	EXT3_IOC_SETVERSION		_IOW('f', 4, long)
++/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
+ #define	EXT3_IOC_GETVERSION_OLD		_IOR('v', 1, long)
+ #define	EXT3_IOC_SETVERSION_OLD		_IOW('v', 2, long)
+ #ifdef CONFIG_JBD_DEBUG
+@@ -674,7 +675,8 @@
+ 			  dx_hash_info *hinfo);
+ 
+ /* ialloc.c */
+-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
++extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int,
++				      unsigned long);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+ extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
+ extern unsigned long ext3_count_free_inodes (struct super_block *);
+@@ -765,4 +767,5 @@
+ 
+ #endif	/* __KERNEL__ */
+ 
++#define EXT3_IOC_CREATE_INUM			_IOW('f', 5, long)
+ #endif	/* _LINUX_EXT3_FS_H */
+Index: linux-2.4.19.SuSE/include/linux/dcache.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/dcache.h	Sat Nov 15 17:35:46 2003
++++ linux-2.4.19.SuSE/include/linux/dcache.h	Sun Nov 16 01:23:20 2003
+@@ -62,6 +62,11 @@
+ 
+ #define IS_ROOT(x) ((x) == (x)->d_parent)
+ 
++struct dentry_params {
++	unsigned long   p_inum;
++	void            *p_ptr;
++};
++
+ /*
+  * "quick string" -- eases parameter passing, but more importantly
+  * saves "metadata" about the string (ie length and the hash).
diff --git a/lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch b/lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5ec4dab994c9b17940903aa52ff5838262a5a55e
--- /dev/null
+++ b/lustre/kernel_patches/patches/extN-wantedi-2.4.22-rh.patch
@@ -0,0 +1,217 @@
+ fs/ext3/ialloc.c        |   41 +++++++++++++++++++++++++++++++++++++++--
+ fs/ext3/inode.c         |    2 +-
+ fs/ext3/ioctl.c         |   25 +++++++++++++++++++++++++
+ fs/ext3/namei.c         |   21 +++++++++++++++++----
+ include/linux/dcache.h  |    5 +++++
+ include/linux/ext3_fs.h |    5 ++++-
+ 6 files changed, 91 insertions(+), 8 deletions(-)
+
+--- linux-2.4.22-ac1/fs/ext3/ialloc.c~extN-wantedi-2.4.22-rh	2003-09-26 00:57:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c	2003-09-26 01:00:17.000000000 +0400
+@@ -524,7 +524,8 @@ static int find_group_other(struct super
+  * group to find a free inode.
+  */
+ struct inode * ext3_new_inode (handle_t *handle,
+-				const struct inode * dir, int mode)
++				const struct inode * dir, int mode,
++				unsigned long goal)
+ {
+ 	struct super_block * sb;
+ 	struct buffer_head * bh;
+@@ -549,7 +550,41 @@ struct inode * ext3_new_inode (handle_t 
+ 	init_rwsem(&inode->u.ext3_i.truncate_sem);
+ 
+ 	lock_super (sb);
+-	es = sb->u.ext3_sb.s_es;
++	es = EXT3_SB(sb)->s_es;
++
++	if (goal) {
++		group = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
++		ino = (goal - 1) % EXT3_INODES_PER_GROUP(sb);
++		gdp = ext3_get_group_desc(sb, group, &bh2);
++
++		bitmap_nr = load_inode_bitmap (sb, group);
++		if (bitmap_nr < 0) {
++			err = bitmap_nr;
++			goto fail;
++		}
++
++		bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
++
++		BUFFER_TRACE(bh, "get_write_access");
++		err = ext3_journal_get_write_access(handle, bh);
++		if (err) goto fail;
++
++		if (ext3_set_bit(ino, bh->b_data)) {
++			printk(KERN_ERR "goal inode %lu unavailable\n", goal);
++			/* Oh well, we tried. */
++			goto repeat;
++		}
++
++		BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
++		err = ext3_journal_dirty_metadata(handle, bh);
++		if (err) goto fail;
++
++		/* We've shortcircuited the allocation system successfully,
++		 * now finish filling in the inode.
++		 */
++		goto have_bit_and_group;
++	}
++
+ repeat:
+ 	if (S_ISDIR(mode)) {
+ 		if (test_opt (sb, OLDALLOC))
+@@ -606,6 +641,8 @@ repeat:
+ 		}
+ 		goto repeat;
+ 	}
++
++have_bit_and_group:
+ 	ino += group * EXT3_INODES_PER_GROUP(sb) + 1;
+ 	if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
+ 		ext3_error (sb, "ext3_new_inode",
+--- linux-2.4.22-ac1/fs/ext3/inode.c~extN-wantedi-2.4.22-rh	2003-09-26 00:57:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c	2003-09-26 00:57:29.000000000 +0400
+@@ -2614,7 +2614,7 @@ void ext3_truncate_thread(struct inode *
+ 	if (IS_ERR(handle))
+ 		goto out_truncate;
+ 
+-	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode);
++	new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0);
+ 	if (IS_ERR(new_inode)) {
+ 		ext3_debug("truncate inode %lu directly (no new inodes)\n",
+ 			   old_inode->i_ino);
+--- linux-2.4.22-ac1/fs/ext3/ioctl.c~extN-wantedi-2.4.22-rh	2003-09-25 14:16:23.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/ioctl.c	2003-09-26 00:57:29.000000000 +0400
+@@ -23,6 +23,31 @@ int ext3_ioctl (struct inode * inode, st
+ 	ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
+ 
+ 	switch (cmd) {
++	case EXT3_IOC_CREATE_INUM: {
++		char name[32];
++		struct dentry *dchild, *dparent;
++		int rc = 0;
++
++		dparent = list_entry(inode->i_dentry.next, struct dentry,
++				     d_alias);
++		snprintf(name, sizeof name, "%lu", arg);
++		dchild = lookup_one_len(name, dparent, strlen(name));
++		if (dchild->d_inode) {
++			printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n",
++			       dparent->d_name.len, dparent->d_name.name, arg,
++			       dchild->d_inode->i_ino);
++			rc = -EEXIST;
++		} else {
++			dchild->d_fsdata = (void *)arg;
++			rc = vfs_create(inode, dchild, 0644);
++			if (rc)
++				printk(KERN_ERR "vfs_create: %d\n", rc);
++			else if (dchild->d_inode->i_ino != arg)
++				rc = -EEXIST;
++		}
++		dput(dchild);
++		return rc;
++	}
+ 	case EXT3_IOC_GETFLAGS:
+ 		flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
+ 		return put_user(flags, (int *) arg);
+--- linux-2.4.22-ac1/fs/ext3/namei.c~extN-wantedi-2.4.22-rh	2003-09-26 00:57:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c	2003-09-26 00:57:29.000000000 +0400
+@@ -1534,6 +1534,19 @@ static int ext3_add_nondir(handle_t *han
+ 	return err;
+ }
+ 
++static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
++						int mode, struct dentry *dentry)
++{
++	unsigned long inum = 0;
++
++	if (dentry->d_fsdata != NULL) {
++		struct dentry_params *param =
++			(struct dentry_params *) dentry->d_fsdata;
++		inum = param->p_inum;
++	}
++	return ext3_new_inode(handle, dir, mode, inum);
++}
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1557,7 +1570,7 @@ static int ext3_create (struct inode * d
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+@@ -1585,7 +1598,7 @@ static int ext3_mknod (struct inode * di
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, mode);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (!IS_ERR(inode)) {
+ 		init_special_inode(inode, mode, rdev);
+@@ -1615,7 +1628,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -2010,7 +2023,7 @@ static int ext3_symlink (struct inode * 
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+--- linux-2.4.22-ac1/include/linux/dcache.h~extN-wantedi-2.4.22-rh	2003-09-26 00:57:27.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/dcache.h	2003-09-26 00:57:29.000000000 +0400
+@@ -63,6 +63,11 @@ static inline void intent_init(struct lo
+ 
+ #define IS_ROOT(x) ((x) == (x)->d_parent)
+ 
++struct dentry_params {
++	unsigned long   p_inum;
++	void            *p_ptr;
++};
++
+ /*
+  * "quick string" -- eases parameter passing, but more importantly
+  * saves "metadata" about the string (ie length and the hash).
+--- linux-2.4.22-ac1/include/linux/ext3_fs.h~extN-wantedi-2.4.22-rh	2003-09-26 00:57:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h	2003-09-26 00:57:29.000000000 +0400
+@@ -203,6 +203,7 @@ struct ext3_group_desc
+ #define	EXT3_IOC_SETFLAGS		_IOW('f', 2, long)
+ #define	EXT3_IOC_GETVERSION		_IOR('f', 3, long)
+ #define	EXT3_IOC_SETVERSION		_IOW('f', 4, long)
++/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */
+ #define	EXT3_IOC_GETVERSION_OLD		_IOR('v', 1, long)
+ #define	EXT3_IOC_SETVERSION_OLD		_IOW('v', 2, long)
+ #ifdef CONFIG_JBD_DEBUG
+@@ -676,7 +677,8 @@ extern int ext3fs_dirhash(const char *na
+ 			  dx_hash_info *hinfo);
+ 
+ /* ialloc.c */
+-extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int);
++extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int,
++				      unsigned long);
+ extern void ext3_free_inode (handle_t *, struct inode *);
+ extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
+ extern unsigned long ext3_count_free_inodes (struct super_block *);
+@@ -769,4 +771,5 @@ extern struct inode_operations ext3_fast
+ 
+ #endif	/* __KERNEL__ */
+ 
++#define EXT3_IOC_CREATE_INUM			_IOW('f', 5, long)
+ #endif	/* _LINUX_EXT3_FS_H */
+
+_
diff --git a/lustre/kernel_patches/patches/extN-wantedi.patch b/lustre/kernel_patches/patches/extN-wantedi.patch
index c5772fbb1ecc808279c40cc759911411b53f8014..359dc63d25e6d6c180ee5f28f714987939c235ac 100644
--- a/lustre/kernel_patches/patches/extN-wantedi.patch
+++ b/lustre/kernel_patches/patches/extN-wantedi.patch
@@ -1,54 +1,72 @@
- fs/ext3/ialloc.c        |   38 ++++++++++++++++++++++++++++++++++++--
+ fs/ext3/ialloc.c        |   40 ++++++++++++++++++++++++++++++++++++++--
+ fs/ext3/inode.c         |    2 +-
  fs/ext3/ioctl.c         |   25 +++++++++++++++++++++++++
- fs/ext3/namei.c         |   12 ++++++++----
+ fs/ext3/namei.c         |   21 +++++++++++++++++----
+ include/linux/dcache.h  |    5 +++++
  include/linux/ext3_fs.h |    5 ++++-
- 4 files changed, 73 insertions(+), 7 deletions(-)
+ 6 files changed, 90 insertions(+), 8 deletions(-)
 
---- linux-2.4.20/fs/ext3/namei.c~extN-wantedi	2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/namei.c	2003-04-08 23:35:55.000000000 -0600
-@@ -1555,7 +1555,8 @@ static int ext3_create (struct inode * d
+--- linux-2.4.18-chaos-uml/fs/ext3/namei.c~extN-wantedi	2003-09-18 12:17:23.000000000 +0400
++++ linux-2.4.18-chaos-uml-alexey/fs/ext3/namei.c	2003-09-18 12:17:26.000000000 +0400
+@@ -1531,6 +1531,19 @@ static int ext3_add_nondir(handle_t *han
+ 	return err;
+ }
+ 
++static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir,
++						int mode, struct dentry *dentry)
++{
++	unsigned long inum = 0;
++
++	if (dentry->d_fsdata != NULL) {
++		struct dentry_params *param =
++			(struct dentry_params *) dentry->d_fsdata;
++		inum = param->p_inum;
++	}
++	return ext3_new_inode(handle, dir, mode, inum);
++}
++
+ /*
+  * By the time this is called, we already have created
+  * the directory cache entry for the new file, but it
+@@ -1554,7 +1567,7 @@ static int ext3_create (struct inode * d
  	if (IS_SYNC(dir))
  		handle->h_sync = 1;
  
 -	inode = ext3_new_inode (handle, dir, mode);
-+	inode = ext3_new_inode (handle, dir, mode,
-+				(unsigned long)dentry->d_fsdata);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
  	err = PTR_ERR(inode);
  	if (!IS_ERR(inode)) {
  		inode->i_op = &ext3_file_inode_operations;
-@@ -1583,7 +1584,8 @@ static int ext3_mknod (struct inode * di
+@@ -1583,7 +1596,7 @@ static int ext3_mknod (struct inode * di
  	if (IS_SYNC(dir))
  		handle->h_sync = 1;
  
 -	inode = ext3_new_inode (handle, dir, mode);
-+	inode = ext3_new_inode (handle, dir, mode,
-+				(unsigned long)dentry->d_fsdata);
++	inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
  	err = PTR_ERR(inode);
  	if (!IS_ERR(inode)) {
  		init_special_inode(inode, mode, rdev);
-@@ -1613,7 +1615,8 @@ static int ext3_mkdir(struct inode * dir
+@@ -1614,7 +1627,7 @@ static int ext3_mkdir(struct inode * dir
  	if (IS_SYNC(dir))
  		handle->h_sync = 1;
  
 -	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
-+	inode = ext3_new_inode (handle, dir, S_IFDIR | mode,
-+				(unsigned long)dentry->d_fsdata);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
  	err = PTR_ERR(inode);
  	if (IS_ERR(inode))
  		goto out_stop;
-@@ -2009,7 +2012,8 @@ static int ext3_symlink (struct inode * 
+@@ -2008,7 +2021,7 @@ static int ext3_symlink (struct inode * 
  	if (IS_SYNC(dir))
  		handle->h_sync = 1;
  
 -	inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
-+	inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO,
-+				(unsigned long)dentry->d_fsdata);
++	inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
  	err = PTR_ERR(inode);
  	if (IS_ERR(inode))
  		goto out_stop;
---- linux-2.4.20/fs/ext3/ialloc.c~extN-wantedi	2003-04-08 23:35:55.000000000 -0600
-+++ linux-2.4.20-braam/fs/ext3/ialloc.c	2003-04-08 23:35:55.000000000 -0600
-@@ -299,7 +299,8 @@ error_return:
+--- linux-2.4.18-chaos-uml/fs/ext3/ialloc.c~extN-wantedi	2003-09-18 12:17:25.000000000 +0400
++++ linux-2.4.18-chaos-uml-alexey/fs/ext3/ialloc.c	2003-09-18 12:17:26.000000000 +0400
+@@ -330,7 +330,8 @@ int ext3_itable_block_used(struct super_
   * group to find a free inode.
   */
  struct inode * ext3_new_inode (handle_t *handle,
@@ -174,11 +192,25 @@
  extern void ext3_free_inode (handle_t *, struct inode *);
  extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
  extern unsigned long ext3_count_free_inodes (struct super_block *);
-@@ -757,4 +759,5 @@ extern struct inode_operations ext3_fast
+@@ -776,4 +778,5 @@ extern struct inode_operations ext3_fast
  
  #endif	/* __KERNEL__ */
  
 +#define EXT3_IOC_CREATE_INUM			_IOW('f', 5, long)
  #endif	/* _LINUX_EXT3_FS_H */
+--- linux-2.4.18-chaos-uml/include/linux/dcache.h~extN-wantedi	2003-09-18 12:17:17.000000000 +0400
++++ linux-2.4.18-chaos-uml-alexey/include/linux/dcache.h	2003-09-18 12:18:47.000000000 +0400
+@@ -62,6 +62,11 @@ static inline void intent_init(struct lo
+ 
+ #define IS_ROOT(x) ((x) == (x)->d_parent)
+ 
++struct dentry_params {
++	unsigned long   p_inum;
++	void            *p_ptr;
++};
++
+ /*
+  * "quick string" -- eases parameter passing, but more importantly
+  * saves "metadata" about the string (ie length and the hash).
 
 _
diff --git a/lustre/kernel_patches/patches/gfp_memalloc-2.4.18-chaos.patch b/lustre/kernel_patches/patches/gfp_memalloc-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a8489e6239ad9559c65683a09c122f3a606d9659
--- /dev/null
+++ b/lustre/kernel_patches/patches/gfp_memalloc-2.4.18-chaos.patch
@@ -0,0 +1,58 @@
+Index: linux-2.4.18-chaos/include/linux/mm.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/mm.h	2003-11-13 17:06:48.000000000 +0300
++++ linux-2.4.18-chaos/include/linux/mm.h	2003-11-17 15:46:32.000000000 +0300
+@@ -677,6 +677,7 @@
+ #define __GFP_IO	0x40	/* Can start low memory physical IO? */
+ #define __GFP_HIGHIO	0x80	/* Can start high mem physical IO? */
+ #define __GFP_FS	0x100	/* Can call down to low-level FS? */
++#define __GFP_MEMALLOC	0x200	/* like PF_MEMALLOC: see __alloc_pages */
+ 
+ #define GFP_NOHIGHIO	(__GFP_HIGH | __GFP_WAIT | __GFP_IO)
+ #define GFP_NOIO	(__GFP_HIGH | __GFP_WAIT)
+@@ -687,6 +688,7 @@
+ #define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
++#define GFP_MEMALLOC	__GFP_MEMALLOC
+ 
+ /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
+    platforms, used as appropriate on others */
+Index: linux-2.4.18-chaos/mm/page_alloc.c
+===================================================================
+--- linux-2.4.18-chaos.orig/mm/page_alloc.c	2003-11-13 17:06:47.000000000 +0300
++++ linux-2.4.18-chaos/mm/page_alloc.c	2003-11-17 15:49:11.000000000 +0300
+@@ -554,7 +554,7 @@
+ 	/*
+ 	 * Oh well, we didn't succeed.
+ 	 */
+-	if (!(current->flags & PF_MEMALLOC)) {
++	if (!(current->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_MEMALLOC)) {
+ 		/*
+ 		 * Are we dealing with a higher order allocation?
+ 		 *
+Index: linux-2.4.18-chaos/include/linux/slab.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/slab.h	2003-07-28 17:52:18.000000000 +0400
++++ linux-2.4.18-chaos/include/linux/slab.h	2003-11-17 15:46:32.000000000 +0300
+@@ -23,6 +23,7 @@
+ #define	SLAB_KERNEL		GFP_KERNEL
+ #define	SLAB_NFS		GFP_NFS
+ #define	SLAB_DMA		GFP_DMA
++#define	SLAB_MEMALLOC		GFP_MEMALLOC
+ 
+ #define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS)
+ #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
+Index: linux-2.4.18-chaos/mm/slab.c
+===================================================================
+--- linux-2.4.18-chaos.orig/mm/slab.c	2003-07-28 17:52:20.000000000 +0400
++++ linux-2.4.18-chaos/mm/slab.c	2003-11-17 15:46:32.000000000 +0300
+@@ -1116,7 +1116,7 @@
+ 	/* Be lazy and only check for valid flags here,
+  	 * keeping it out of the critical path in kmem_cache_alloc().
+ 	 */
+-	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
++	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW|SLAB_MEMALLOC))
+ 		BUG();
+ 	if (flags & SLAB_NO_GROW)
+ 		return 0;
diff --git a/lustre/kernel_patches/patches/gfp_memalloc-2.4.20-rh.patch b/lustre/kernel_patches/patches/gfp_memalloc-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3f37e446822461a212f7681e03fe54395ab998d9
--- /dev/null
+++ b/lustre/kernel_patches/patches/gfp_memalloc-2.4.20-rh.patch
@@ -0,0 +1,59 @@
+Index: linux-2.4.20-rh-20.9/include/linux/mm.h
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/include/linux/mm.h	2003-11-13 17:35:48.000000000 +0300
++++ linux-2.4.20-rh-20.9/include/linux/mm.h	2003-11-17 15:50:22.000000000 +0300
+@@ -713,6 +713,7 @@
+ #define __GFP_IO	0x40	/* Can start low memory physical IO? */
+ #define __GFP_HIGHIO	0x80	/* Can start high mem physical IO? */
+ #define __GFP_FS	0x100	/* Can call down to low-level FS? */
++#define __GFP_MEMALLOC	0x200	/* like PF_MEMALLOC: see __alloc_pages */
+ 
+ #define GFP_NOHIGHIO	(__GFP_HIGH | __GFP_WAIT | __GFP_IO)
+ #define GFP_NOIO	(__GFP_HIGH | __GFP_WAIT)
+@@ -723,6 +724,7 @@
+ #define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
++#define GFP_MEMALLOC	__GFP_MEMALLOC
+ 
+ /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
+    platforms, used as appropriate on others */
+Index: linux-2.4.20-rh-20.9/mm/page_alloc.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/mm/page_alloc.c	2003-11-13 17:20:37.000000000 +0300
++++ linux-2.4.20-rh-20.9/mm/page_alloc.c	2003-11-17 15:51:05.000000000 +0300
+@@ -509,7 +509,8 @@
+ 	/*
+ 	 * Oh well, we didn't succeed.
+ 	 */
+-	if (!(current->flags & (PF_MEMALLOC|PF_MEMDIE))) {
++	if (!(current->flags & (PF_MEMALLOC|PF_MEMDIE)) &&
++		!(gfp_mask & __GFP_MEMALLOC)) {
+ 		/*
+ 		 * Are we dealing with a higher order allocation?
+ 		 *
+Index: linux-2.4.20-rh-20.9/include/linux/slab.h
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/include/linux/slab.h	2003-11-13 17:35:48.000000000 +0300
++++ linux-2.4.20-rh-20.9/include/linux/slab.h	2003-11-17 15:50:22.000000000 +0300
+@@ -23,6 +23,7 @@
+ #define	SLAB_KERNEL		GFP_KERNEL
+ #define	SLAB_NFS		GFP_NFS
+ #define	SLAB_DMA		GFP_DMA
++#define	SLAB_MEMALLOC		GFP_MEMALLOC
+ 
+ #define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS)
+ #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
+Index: linux-2.4.20-rh-20.9/mm/slab.c
+===================================================================
+--- linux-2.4.20-rh-20.9.orig/mm/slab.c	2003-09-13 19:34:24.000000000 +0400
++++ linux-2.4.20-rh-20.9/mm/slab.c	2003-11-17 15:50:22.000000000 +0300
+@@ -1116,7 +1116,7 @@
+ 	/* Be lazy and only check for valid flags here,
+  	 * keeping it out of the critical path in kmem_cache_alloc().
+ 	 */
+-	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
++	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW|SLAB_MEMALLOC))
+ 		BUG();
+ 	if (flags & SLAB_NO_GROW)
+ 		return 0;
diff --git a/lustre/kernel_patches/patches/gfp_memalloc-2.4.22.patch b/lustre/kernel_patches/patches/gfp_memalloc-2.4.22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..015bfc81f1e63a0e623910fc788f15393833d9a8
--- /dev/null
+++ b/lustre/kernel_patches/patches/gfp_memalloc-2.4.22.patch
@@ -0,0 +1,59 @@
+Index: linux-2.4.22-vanilla/include/linux/mm.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/mm.h	2003-11-17 15:26:32.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/mm.h	2003-11-17 15:40:32.000000000 +0300
+@@ -612,6 +612,7 @@
+ #define __GFP_IO	0x40	/* Can start low memory physical IO? */
+ #define __GFP_HIGHIO	0x80	/* Can start high mem physical IO? */
+ #define __GFP_FS	0x100	/* Can call down to low-level FS? */
++#define __GFP_MEMALLOC	0x200	/* like PF_MEMALLOC: see __alloc_pages */
+ 
+ #define GFP_NOHIGHIO	(__GFP_HIGH | __GFP_WAIT | __GFP_IO)
+ #define GFP_NOIO	(__GFP_HIGH | __GFP_WAIT)
+@@ -622,6 +623,7 @@
+ #define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+ #define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
++#define GFP_MEMALLOC	__GFP_MEMALLOC
+ 
+ /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
+    platforms, used as appropriate on others */
+Index: linux-2.4.22-vanilla/mm/page_alloc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/page_alloc.c	2003-11-13 18:19:51.000000000 +0300
++++ linux-2.4.22-vanilla/mm/page_alloc.c	2003-11-17 15:40:32.000000000 +0300
+@@ -377,7 +377,8 @@
+ 	/* here we're in the low on memory slow path */
+ 
+ rebalance:
+-	if (current->flags & (PF_MEMALLOC | PF_MEMDIE)) {
++	if (current->flags & (PF_MEMALLOC | PF_MEMDIE) || 
++			gfp_mask & __GFP_MEMALLOC) {
+ 		zone = zonelist->zones;
+ 		for (;;) {
+ 			zone_t *z = *(zone++);
+Index: linux-2.4.22-vanilla/include/linux/slab.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/slab.h	2003-11-17 14:58:37.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/slab.h	2003-11-17 15:42:13.000000000 +0300
+@@ -23,6 +23,7 @@
+ #define	SLAB_KERNEL		GFP_KERNEL
+ #define	SLAB_NFS		GFP_NFS
+ #define	SLAB_DMA		GFP_DMA
++#define	SLAB_MEMALLOC		GFP_MEMALLOC
+ 
+ #define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS)
+ #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
+Index: linux-2.4.22-vanilla/mm/slab.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/slab.c	2003-11-13 17:39:29.000000000 +0300
++++ linux-2.4.22-vanilla/mm/slab.c	2003-11-17 15:42:13.000000000 +0300
+@@ -1115,7 +1115,7 @@
+ 	/* Be lazy and only check for valid flags here,
+  	 * keeping it out of the critical path in kmem_cache_alloc().
+ 	 */
+-	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
++	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW|SLAB_MEMALLOC))
+ 		BUG();
+ 	if (flags & SLAB_NO_GROW)
+ 		return 0;
diff --git a/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch b/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch
index a54e9ca9014c66dc10a12a4cb3d33d9300e47129..2bfd0b99bfedd8cdbf111cbe22ba7653ce1e49d2 100644
--- a/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch
+++ b/lustre/kernel_patches/patches/htree-ext3-2.4.18.patch
@@ -673,7 +673,7 @@
  /*
   *	ext3_add_entry()
   *
-@@ -255,118 +849,278 @@
+@@ -255,118 +849,279 @@
  	struct inode *inode)
  {
  	struct inode *dir = dentry->d_parent->d_inode;
@@ -1006,7 +1006,8 @@
 +		data1 = bh2->b_data;
 +
 +		/* The 0th block becomes the root, move the dirents out */
-+		de = (ext3_dirent *) &root->info;
++		de = (struct ext3_dir_entry_2 *) &root->dotdot;
++		de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len);
 +		len = ((char *) root) + sb->s_blocksize - (char *) de;
 +		memcpy (data1, de, len);
 +		de = (ext3_dirent *) data1;
diff --git a/lustre/kernel_patches/patches/inode-protection-from-pdflush.patch b/lustre/kernel_patches/patches/inode-protection-from-pdflush.patch
deleted file mode 100644
index abfdc32c50770950f35664d05bae519af8909073..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/inode-protection-from-pdflush.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-
-diff -puN fs/fs-writeback.c~inode-protection-from-pdflush fs/fs-writeback.c
---- linux-2.5.73/fs/fs-writeback.c~inode-protection-from-pdflush	Mon Jul  7 01:10:17 2003
-+++ linux-2.5.73-alexey/fs/fs-writeback.c	Mon Jul  7 01:10:17 2003
-@@ -198,6 +198,11 @@ static void
- __writeback_single_inode(struct inode *inode,
- 			struct writeback_control *wbc)
- {
-+	if (inode->i_flags & I_SKIP_PDFLUSH) {
-+		list_move(&inode->i_list, &inode->i_sb->s_dirty);
-+		return;
-+	}
-+
- 	if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
- 		list_move(&inode->i_list, &inode->i_sb->s_dirty);
- 		return;
-diff -puN include/linux/fs.h~inode-protection-from-pdflush include/linux/fs.h
---- linux-2.5.73/include/linux/fs.h~inode-protection-from-pdflush	Mon Jul  7 01:22:16 2003
-+++ linux-2.5.73-alexey/include/linux/fs.h	Mon Jul  7 01:23:18 2003
-@@ -816,6 +816,7 @@ struct super_operations {
- #define I_FREEING		16
- #define I_CLEAR			32
- #define I_NEW			64
-+#define I_SKIP_PDFLUSH		1024 /* inode will be out of pdflush's scope */
- 
- #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
- 
-
-_
diff --git a/lustre/kernel_patches/patches/invalidate_show-2.4.19-pre1.patch b/lustre/kernel_patches/patches/invalidate_show-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..376558b5691cbbbca8d77635344656ccbb29f866
--- /dev/null
+++ b/lustre/kernel_patches/patches/invalidate_show-2.4.19-pre1.patch
@@ -0,0 +1,121 @@
+
+
+
+ fs/inode.c         |   21 ++++++++++++++-------
+ fs/smbfs/inode.c   |    2 +-
+ fs/super.c         |    4 ++--
+ include/linux/fs.h |    2 +-
+ 4 files changed, 18 insertions(+), 11 deletions(-)
+
+Index: linux-2.4.19-pre1/fs/inode.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/inode.c	2003-11-21 02:39:48.000000000 +0300
++++ linux-2.4.19-pre1/fs/inode.c	2003-11-21 02:39:54.000000000 +0300
+@@ -553,7 +553,8 @@
+ /*
+  * Invalidate all inodes for a device.
+  */
+-static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose)
++static int invalidate_list(struct list_head *head, struct super_block * sb,
++			   struct list_head * dispose, int show)
+ {
+ 	struct list_head *next;
+ 	int busy = 0, count = 0;
+@@ -578,6 +579,11 @@
+ 			count++;
+ 			continue;
+ 		}
++		if (show)
++			printk(KERN_ERR
++			       "inode busy: dev %s:%lu (%p) mode %o count %u\n",
++			       kdevname(sb->s_dev), inode->i_ino, inode,
++			       inode->i_mode, atomic_read(&inode->i_count));
+ 		busy = 1;
+ 	}
+ 	/* only unused inodes may be cached with i_count zero */
+@@ -596,22 +602,23 @@
+ /**
+  *	invalidate_inodes	- discard the inodes on a device
+  *	@sb: superblock
++ *	@show: whether we should display any busy inodes found
+  *
+  *	Discard all of the inodes for a given superblock. If the discard
+  *	fails because there are busy inodes then a non zero value is returned.
+  *	If the discard is successful all the inodes have been discarded.
+  */
+  
+-int invalidate_inodes(struct super_block * sb)
++int invalidate_inodes(struct super_block * sb, int show)
+ {
+ 	int busy;
+ 	LIST_HEAD(throw_away);
+ 
+ 	spin_lock(&inode_lock);
+-	busy = invalidate_list(&inode_in_use, sb, &throw_away);
+-	busy |= invalidate_list(&inode_unused, sb, &throw_away);
+-	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
+-	busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away);
++	busy = invalidate_list(&inode_in_use, sb, &throw_away, show);
++	busy |= invalidate_list(&inode_unused, sb, &throw_away, show);
++	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away, show);
++	busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away, show);
+ 	spin_unlock(&inode_lock);
+ 
+ 	dispose_list(&throw_away);
+@@ -637,7 +644,7 @@
+ 		 * hold).
+ 		 */
+ 		shrink_dcache_sb(sb);
+-		res = invalidate_inodes(sb);
++		res = invalidate_inodes(sb, 0);
+ 		drop_super(sb);
+ 	}
+ 	invalidate_buffers(dev);
+Index: linux-2.4.19-pre1/fs/super.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/super.c	2003-11-21 02:39:48.000000000 +0300
++++ linux-2.4.19-pre1/fs/super.c	2003-11-21 02:40:09.000000000 +0300
+@@ -790,7 +790,7 @@
+ 	fsync_super(sb);
+ 	lock_super(sb);
+ 	sb->s_flags &= ~MS_ACTIVE;
+-	invalidate_inodes(sb);	/* bad name - it should be evict_inodes() */
++	invalidate_inodes(sb, 0);  /* bad name - it should be evict_inodes() */
+ 	if (sop) {
+ 		if (sop->write_super && sb->s_dirt)
+ 			sop->write_super(sb);
+@@ -799,7 +799,7 @@
+ 	}
+ 
+ 	/* Forget any remaining inodes */
+-	if (invalidate_inodes(sb)) {
++	if (invalidate_inodes(sb, 1)) {
+ 		printk("VFS: Busy inodes after unmount. "
+ 			"Self-destruct in 5 seconds.  Have a nice day...\n");
+ 	}
+Index: linux-2.4.19-pre1/include/linux/fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs.h	2003-11-21 02:39:53.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs.h	2003-11-21 02:39:54.000000000 +0300
+@@ -1214,7 +1214,7 @@
+ extern void set_buffer_flushtime(struct buffer_head *);
+ extern void balance_dirty(void);
+ extern int check_disk_change(kdev_t);
+-extern int invalidate_inodes(struct super_block *);
++extern int invalidate_inodes(struct super_block *, int);
+ extern int invalidate_device(kdev_t, int);
+ extern void invalidate_inode_pages(struct inode *);
+ extern void invalidate_inode_pages2(struct address_space *);
+Index: linux-2.4.19-pre1/fs/smbfs/inode.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/smbfs/inode.c	2003-11-21 02:39:48.000000000 +0300
++++ linux-2.4.19-pre1/fs/smbfs/inode.c	2003-11-21 02:39:54.000000000 +0300
+@@ -166,7 +166,7 @@
+ {
+ 	VERBOSE("\n");
+ 	shrink_dcache_sb(SB_of(server));
+-	invalidate_inodes(SB_of(server));
++	invalidate_inodes(SB_of(server), 0);
+ }
+ 
+ /*
diff --git a/lustre/kernel_patches/patches/iod-stock-24-exports-2.4.19-suse.patch b/lustre/kernel_patches/patches/iod-stock-24-exports-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2040fcd9d8e3e7e836ef18bdb0b20e0cd4682e8d
--- /dev/null
+++ b/lustre/kernel_patches/patches/iod-stock-24-exports-2.4.19-suse.patch
@@ -0,0 +1,52 @@
+ fs/Makefile     |    2 +-
+ fs/inode.c      |    4 +++-
+ mm/page_alloc.c |    1 +
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.19.SuSE/fs/inode.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/inode.c	Sat Nov 15 18:02:13 2003
++++ linux-2.4.19.SuSE/fs/inode.c	Sat Nov 15 18:03:04 2003
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+@@ -67,7 +68,8 @@
+  * NOTE! You also have to own the lock if you change
+  * the i_state of an inode while it is in use..
+  */
+-static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++EXPORT_SYMBOL(inode_lock);
+ 
+ /*
+  * Statistics gathering..
+Index: linux-2.4.19.SuSE/fs/Makefile
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/Makefile	Mon Jan 27 05:08:56 2003
++++ linux-2.4.19.SuSE/fs/Makefile	Sat Nov 15 18:03:54 2003
+@@ -7,7 +7,7 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+Index: linux-2.4.19.SuSE/mm/page_alloc.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/mm/page_alloc.c	Mon Jan 27 05:08:55 2003
++++ linux-2.4.19.SuSE/mm/page_alloc.c	Sat Nov 15 18:03:04 2003
+@@ -32,6 +32,7 @@
+ LIST_HEAD(inactive_list);
+ LIST_HEAD(active_list);
+ pg_data_t *pgdat_list;
++EXPORT_SYMBOL(pgdat_list);
+ 
+ /* Used to look up the address of the struct zone encoded in page->zone */
+ zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
diff --git a/lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch b/lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8d8790e7708fa72775f58ff67d001ecd4f44fa6c
--- /dev/null
+++ b/lustre/kernel_patches/patches/iod-stock-exports-2.4.22-rh.patch
@@ -0,0 +1,48 @@
+ fs/Makefile     |    2 +-
+ fs/inode.c      |    4 +++-
+ mm/page_alloc.c |    1 +
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+--- linux-2.4.22-ac1/fs/inode.c~iod-stock-exports-2.4.22-rh	2003-09-25 14:45:32.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/inode.c	2003-09-25 14:49:41.000000000 +0400
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+@@ -68,7 +69,8 @@ static LIST_HEAD(anon_hash_chain); /* fo
+  * NOTE! You also have to own the lock if you change
+  * the i_state of an inode while it is in use..
+  */
+-static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++EXPORT_SYMBOL(inode_lock);
+ 
+ /*
+  * Statistics gathering..
+--- linux-2.4.22-ac1/fs/Makefile~iod-stock-exports-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/Makefile	2003-09-25 14:50:00.000000000 +0400
+@@ -7,7 +7,7 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o
+ mod-subdirs :=	nls xfs
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+--- linux-2.4.22-ac1/mm/page_alloc.c~iod-stock-exports-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/mm/page_alloc.c	2003-09-25 14:49:41.000000000 +0400
+@@ -28,6 +28,7 @@ int nr_inactive_pages;
+ LIST_HEAD(inactive_list);
+ LIST_HEAD(active_list);
+ pg_data_t *pgdat_list;
++EXPORT_SYMBOL(pgdat_list);
+ 
+ /*
+  *
+
+_
diff --git a/lustre/kernel_patches/patches/iod-stock-exports-2.4.22.patch b/lustre/kernel_patches/patches/iod-stock-exports-2.4.22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..47a6ff93ef68807fc9298a430fb7b6500c2c4148
--- /dev/null
+++ b/lustre/kernel_patches/patches/iod-stock-exports-2.4.22.patch
@@ -0,0 +1,52 @@
+ fs/Makefile     |    2 +-
+ fs/inode.c      |    4 +++-
+ mm/page_alloc.c |    1 +
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.22-vanilla/fs/inode.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/inode.c	2003-11-03 23:22:24.000000000 +0300
++++ linux-2.4.22-vanilla/fs/inode.c	2003-11-03 23:25:00.000000000 +0300
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <linux/config.h>
++#include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+@@ -66,7 +67,8 @@
+  * NOTE! You also have to own the lock if you change
+  * the i_state of an inode while it is in use..
+  */
+-static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
++EXPORT_SYMBOL(inode_lock);
+ 
+ /*
+  * Statistics gathering..
+Index: linux-2.4.22-vanilla/fs/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/Makefile	2003-11-03 23:22:11.000000000 +0300
++++ linux-2.4.22-vanilla/fs/Makefile	2003-11-03 23:25:24.000000000 +0300
+@@ -7,7 +7,7 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o inode.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+Index: linux-2.4.22-vanilla/mm/page_alloc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/page_alloc.c	2003-11-03 23:21:29.000000000 +0300
++++ linux-2.4.22-vanilla/mm/page_alloc.c	2003-11-03 23:25:00.000000000 +0300
+@@ -28,6 +28,7 @@
+ LIST_HEAD(inactive_list);
+ LIST_HEAD(active_list);
+ pg_data_t *pgdat_list;
++EXPORT_SYMBOL(pgdat_list);
+ 
+ /*
+  *
diff --git a/lustre/kernel_patches/patches/iopen-2.4.18-2.patch b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c971a83d74c1160f330c847c6a8d68a07759b38d
--- /dev/null
+++ b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch
@@ -0,0 +1,422 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/Makefile                   |    2 
+ fs/ext3/inode.c                    |    4 
+ fs/ext3/iopen.c                    |  259 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   13 +
+ fs/ext3/namei.c                    |   12 +
+ fs/ext3/super.c                    |   11 +
+ include/linux/ext3_fs.h            |    2 
+ 8 files changed, 318 insertions(+), 1 deletion(-)
+
+--- linux-2.4.18-p4smp/Documentation/filesystems/ext2.txt~iopen-2.4.18	2003-07-09 12:17:30.000000000 -0600
++++ linux-2.4.18-p4smp-braam/Documentation/filesystems/ext2.txt	2003-07-09 17:13:02.000000000 -0600
+@@ -35,6 +35,22 @@ resgid=n			The group ID which may use th
+ 
+ sb=n				Use alternate superblock at this location.
+ 
++iopen				Makes an invisible pseudo-directory called 
++				__iopen__ available in the root directory
++				of the filesystem.  Allows open-by-inode-
++				number.  i.e., inode 3145 can be accessed
++				via /mntpt/__iopen__/3145
++
++iopen_nopriv			This option makes the iopen directory be
++				world-readable.  This may be safer since it
++				allows daemons to run as an unprivileged user,
++				however it significantly changes the security
++				model of a Unix filesystem, since previously
++				all files under a mode 700 directory were not
++				generally avilable even if the
++				permissions on the file itself is
++				world-readable.
++
+ grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
+ 
+ 
+--- linux-2.4.18-p4smp/fs/ext3/Makefile~iopen-2.4.18	2003-07-09 17:12:12.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/Makefile	2003-07-09 17:13:15.000000000 -0600
+@@ -11,7 +11,7 @@ O_TARGET := ext3.o
+ 
+ export-objs :=	super.o inode.o xattr.o ext3-exports.o
+ 
+-obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++obj-y    := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+ 		ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
+--- linux-2.4.18-p4smp/fs/ext3/inode.c~iopen-2.4.18	2003-07-09 17:11:19.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c	2003-07-09 17:13:02.000000000 -0600
+@@ -31,6 +31,7 @@
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+ #include <linux/module.h>
++#include "iopen.h"
+ 
+ /*
+  * SEARCH_FROM_ZERO forces each block allocation to search from the start
+@@ -2165,6 +2166,9 @@ void ext3_read_inode(struct inode * inod
+ 	struct buffer_head *bh;
+ 	int block;
+ 	
++	if (ext3_iopen_get_inode(inode))
++		return;
++	
+ 	if(ext3_get_inode_loc(inode, &iloc))
+ 		goto bad_inode;
+ 	bh = iloc.bh;
+--- /dev/null	2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c	2003-07-09 17:13:02.000000000 -0600
+@@ -0,0 +1,259 @@
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ *
++ *
++ * Invariants:
++ *   - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
++ *     for an inode at one time.
++ *   - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
++ *     aliases on an inode at the same time.
++ *
++ * If we have any connected dentry aliases for an inode, use one of those
++ * in iopen_lookup().  Otherwise, we instantiate a single NFSD_DISCONNECTED
++ * dentry for this inode, which thereafter will be found by the dcache
++ * when looking up this inode number in __iopen__, so we don't return here
++ * until it is gone.
++ *
++ * If we get an inode via a regular name lookup, then we "rename" the
++ * NFSD_DISCONNECTED dentry to the proper name and parent.  This ensures
++ * existing users of the disconnected dentry will continue to use the same
++ * dentry as the connected users, and there will never be both kinds of
++ * dentry aliases at one time.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN	32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode;
++	unsigned long ino;
++	struct list_head *lp;
++	struct dentry *alternate;
++	char buf[IOPEN_NAME_LEN];
++	
++	if (dentry->d_name.len >= IOPEN_NAME_LEN)
++		return ERR_PTR(-ENAMETOOLONG);
++
++	memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++	buf[dentry->d_name.len] = 0;
++
++	if (strcmp(buf, ".") == 0)
++		ino = dir->i_ino;
++	else if (strcmp(buf, "..") == 0)
++		ino = EXT3_ROOT_INO;
++	else
++		ino = simple_strtoul(buf, 0, 0);
++
++	if ((ino != EXT3_ROOT_INO &&
++	     //ino != EXT3_ACL_IDX_INO &&
++	     //ino != EXT3_ACL_DATA_INO &&
++	     ino < EXT3_FIRST_INO(dir->i_sb)) ||
++	    ino > le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
++		return ERR_PTR(-ENOENT);
++
++	inode = iget(dir->i_sb, ino);
++	if (!inode)
++		return ERR_PTR(-EACCES);
++	if (is_bad_inode(inode)) {
++		iput(inode);
++		return ERR_PTR(-ENOENT);
++	}
++
++	/* preferrably return a connected dentry */
++	spin_lock(&dcache_lock);
++	list_for_each(lp, &inode->i_dentry) {
++		alternate = list_entry(lp, struct dentry, d_alias);
++		assert(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED));
++	}
++
++	if (!list_empty(&inode->i_dentry)) {
++		alternate = list_entry(inode->i_dentry.next, 
++				       struct dentry, d_alias);
++		dget_locked(alternate);
++		alternate->d_vfs_flags |= DCACHE_REFERENCED;
++		iput(inode);
++		spin_unlock(&dcache_lock);
++		return alternate;
++	}
++	dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
++	spin_unlock(&dcache_lock);
++
++	d_add(dentry, inode);
++	return NULL;
++}
++
++#define do_switch(x,y) do { \
++	__typeof__ (x) __tmp = x; \
++	x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry *dentry, struct dentry *target)
++{
++	const unsigned char *old_name, *new_name;
++
++	memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++	old_name = target->d_name.name;
++	new_name = dentry->d_name.name;
++	if (old_name == target->d_iname)
++		old_name = dentry->d_iname;
++	if (new_name == dentry->d_iname)
++		new_name = target->d_iname;
++	target->d_name.name = new_name;
++	dentry->d_name.name = old_name;
++}
++
++/* This function is spliced into ext3_lookup and does the move of a
++ * disconnected dentry (if it exists) to a connected dentry.
++ */
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++	struct dentry *tmp, *goal = NULL;
++	struct list_head *lp;
++
++	/* preferrably return a connected dentry */
++	spin_lock(&dcache_lock);
++	/* verify this dentry is really new */
++	assert(!de->d_inode);
++	assert(list_empty(&de->d_subdirs));
++	assert(list_empty(&de->d_alias));
++
++
++	list_for_each(lp, &inode->i_dentry) {
++		tmp = list_entry(lp, struct dentry, d_alias);
++		if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
++			assert(tmp->d_alias.next == &inode->i_dentry);
++			assert(tmp->d_alias.prev == &inode->i_dentry);
++			goal = tmp;
++			dget_locked(goal);
++			break;
++		}
++	}
++
++	if (!goal) { 
++		spin_unlock(&dcache_lock);
++		return NULL; 
++	}
++
++	/* Move the goal to the de hash queue - like d_move() */
++	goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
++	list_del(&goal->d_hash);
++	list_add(&goal->d_hash, &de->d_hash);
++
++	list_del(&goal->d_child);
++	list_del(&de->d_child);
++
++	/* Switch the parents and the names.. */
++	switch_names(goal, de);
++	do_switch(goal->d_parent, de->d_parent);
++	do_switch(goal->d_name.len, de->d_name.len);
++	do_switch(goal->d_name.hash, de->d_name.hash);
++
++	/* And add them back to the (new) parent lists */
++	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++	list_add(&de->d_child, &de->d_parent->d_subdirs);
++	spin_unlock(&dcache_lock);
++
++	return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++	lookup:		iopen_lookup,		/* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++	read:		generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++	int	len;
++
++	len = strlen(name);
++	if (dentry->d_name.len != len)
++		return 0;
++	if (strncmp(dentry->d_name.name, name, len))
++		return 0;
++	return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode;
++
++	if (dir->i_ino != EXT3_ROOT_INO ||
++	    !test_opt(dir->i_sb, IOPEN) ||
++	    !match_dentry(dentry, "__iopen__"))
++		return 0;
++
++	inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++	if (!inode) 
++		return 0;
++	d_add(dentry, inode);
++	return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode *inode)
++{
++	if (inode->i_ino != EXT3_BAD_INO)
++		return 0;
++
++	inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++	if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++		inode->i_mode |= 0777;
++	inode->i_uid = 0;
++	inode->i_gid = 0;
++	inode->i_nlink = 1;
++	inode->i_size = 4096;
++	inode->i_atime = CURRENT_TIME;
++	inode->i_ctime = CURRENT_TIME;
++	inode->i_mtime = CURRENT_TIME;
++	inode->u.ext3_i.i_dtime = 0;
++	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size
++					 * (for stat), not the fs block
++					 * size */  
++	inode->i_blocks = 0;
++	inode->i_version = 1;
++	inode->i_generation = 0;
++
++	inode->i_op = &iopen_inode_operations;
++	inode->i_fop = &iopen_file_operations;
++	inode->i_mapping->a_ops = 0;
++
++	return 1;
++}
+--- /dev/null	2003-01-30 03:24:37.000000000 -0700
++++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h	2003-07-09 17:13:02.000000000 -0600
+@@ -0,0 +1,13 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode *inode);
+--- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-2.4.18	2003-07-09 13:32:38.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c	2003-07-09 17:13:02.000000000 -0600
+@@ -34,6 +34,7 @@
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ #include <linux/slab.h>
++#include "iopen.h"
+ 
+ /*
+  * define how far ahead to read directories while searching them.
+@@ -703,16 +704,21 @@ cleanup_and_exit:
+ 	return NULL;
+ }
+ #endif
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
+ 
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+ 	struct ext3_dir_entry_2 * de;
+ 	struct buffer_head * bh;
++	struct dentry *alternate = NULL;
+ 
+ 	if (dentry->d_name.len > EXT3_NAME_LEN)
+ 		return ERR_PTR(-ENAMETOOLONG);
+ 
++	if (ext3_check_for_iopen(dir, dentry))
++		return NULL;
++
+ 	bh = ext3_find_entry(dentry, &de);
+ 	inode = NULL;
+ 	if (bh) {
+@@ -723,6 +729,12 @@ static struct dentry *ext3_lookup(struct
+ 		if (!inode)
+ 			return ERR_PTR(-EACCES);
+ 	}
++
++	if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++		iput(inode);
++		return alternate;
++	}
++
+ 	d_add(dentry, inode);
+ 	return NULL;
+ }
+--- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-2.4.18	2003-07-09 13:32:38.000000000 -0600
++++ linux-2.4.18-p4smp-braam/fs/ext3/super.c	2003-07-09 17:13:02.000000000 -0600
+@@ -831,6 +831,17 @@ static int parse_options (char * options
+ 		         || !strcmp (this_char, "quota")
+ 		         || !strcmp (this_char, "usrquota"))
+ 			/* Don't do anything ;-) */ ;
++		else if (!strcmp (this_char, "iopen")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		} else if (!strcmp (this_char, "noiopen")) {
++			clear_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
++		else if (!strcmp (this_char, "iopen_nopriv")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
+ 		else if (!strcmp (this_char, "journal")) {
+ 			/* @@@ FIXME */
+ 			/* Eventually we will want to be able to create
+--- linux-2.4.18-p4smp/include/linux/ext3_fs.h~iopen-2.4.18	2003-07-09 13:32:38.000000000 -0600
++++ linux-2.4.18-p4smp-braam/include/linux/ext3_fs.h	2003-07-09 17:13:02.000000000 -0600
+@@ -321,6 +321,8 @@ struct ext3_inode {
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_IOPEN		0x8000	/* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV		0x10000	/* Make iopen world-readable */
+ #define EXT3_MOUNT_ASYNCDEL		0x20000	/* Delayed deletion */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+
+_
diff --git a/lustre/kernel_patches/patches/iopen-2.4.18.patch b/lustre/kernel_patches/patches/iopen-2.4.18.patch
index b983b339c40ac796df30b89febce0a7986dd1ff2..7fc40f75afdd30ca97a6e463e61c91ceeb440650 100644
--- a/lustre/kernel_patches/patches/iopen-2.4.18.patch
+++ b/lustre/kernel_patches/patches/iopen-2.4.18.patch
@@ -227,8 +227,7 @@
 +
 +	/* Move the goal to the de hash queue - like d_move() */
 +	goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
-+	list_del(&goal->d_hash);
-+	list_add(&goal->d_hash, &de->d_hash);
++	list_del_init(&goal->d_hash);
 +
 +	list_del(&goal->d_child);
 +	list_del(&de->d_child);
@@ -242,6 +241,7 @@
 +	/* And add them back to the (new) parent lists */
 +	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
 +	list_add(&de->d_child, &de->d_parent->d_subdirs);
++	__d_rehash(goal, 0);
 +	spin_unlock(&dcache_lock);
 +
 +	return goal;
diff --git a/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch b/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ab267bbea7a6e14ab73cfd59c420bee8ba401f9c
--- /dev/null
+++ b/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch
@@ -0,0 +1,437 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/Makefile                   |    2 
+ fs/ext3/inode.c                    |    4 
+ fs/ext3/iopen.c                    |  259 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   13 +
+ fs/ext3/namei.c                    |   13 +
+ fs/ext3/super.c                    |   11 +
+ include/linux/ext3_fs.h            |    2 
+ 8 files changed, 318 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.19.SuSE/Documentation/filesystems/ext2.txt
+===================================================================
+--- linux-2.4.19.SuSE.orig/Documentation/filesystems/ext2.txt	Wed Jul 11 15:44:45 2001
++++ linux-2.4.19.SuSE/Documentation/filesystems/ext2.txt	Sun Nov 16 01:27:31 2003
+@@ -35,6 +35,22 @@
+ 
+ sb=n				Use alternate superblock at this location.
+ 
++iopen				Makes an invisible pseudo-directory called 
++				__iopen__ available in the root directory
++				of the filesystem.  Allows open-by-inode-
++				number.  i.e., inode 3145 can be accessed
++				via /mntpt/__iopen__/3145
++
++iopen_nopriv			This option makes the iopen directory be
++				world-readable.  This may be safer since it
++				allows daemons to run as an unprivileged user,
++				however it significantly changes the security
++				model of a Unix filesystem, since previously
++				all files under a mode 700 directory were not
++				generally avilable even if the
++				permissions on the file itself is
++				world-readable.
++
+ grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
+ 
+ 
+Index: linux-2.4.19.SuSE/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/Makefile	Sun Nov 16 00:40:59 2003
++++ linux-2.4.19.SuSE/fs/ext3/Makefile	Sun Nov 16 01:27:31 2003
+@@ -11,7 +11,7 @@
+ 
+ export-objs := ext3-exports.o
+ 
+-obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+ 		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
+Index: linux-2.4.19.SuSE/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/inode.c	Sun Nov 16 01:26:04 2003
++++ linux-2.4.19.SuSE/fs/ext3/inode.c	Sun Nov 16 01:27:31 2003
+@@ -34,6 +34,7 @@
+ #include <linux/highuid.h>
+ #include <linux/quotaops.h>
+ #include <linux/module.h>
++#include "iopen.h"
+ 
+ /*
+  * SEARCH_FROM_ZERO forces each block allocation to search from the start
+@@ -2350,6 +2351,9 @@
+ 	struct buffer_head *bh;
+ 	int block;
+ 	
++	if (ext3_iopen_get_inode(inode))
++		return;
++	
+ 	if(ext3_get_inode_loc(inode, &iloc))
+ 		goto bad_inode;
+ 	bh = iloc.bh;
+Index: linux-2.4.19.SuSE/fs/ext3/iopen.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/iopen.c	Sun Nov 16 01:27:31 2003
++++ linux-2.4.19.SuSE/fs/ext3/iopen.c	Sun Nov 16 01:27:31 2003
+@@ -0,0 +1,259 @@
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ * 
++ *
++ * Invariants:
++ *   - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias
++ *     for an inode at one time.
++ *   - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry
++ *     aliases on an inode at the same time.
++ *
++ * If we have any connected dentry aliases for an inode, use one of those
++ * in iopen_lookup().  Otherwise, we instantiate a single NFSD_DISCONNECTED
++ * dentry for this inode, which thereafter will be found by the dcache
++ * when looking up this inode number in __iopen__, so we don't return here
++ * until it is gone.
++ *
++ * If we get an inode via a regular name lookup, then we "rename" the
++ * NFSD_DISCONNECTED dentry to the proper name and parent.  This ensures
++ * existing users of the disconnected dentry will continue to use the same
++ * dentry as the connected users, and there will never be both kinds of
++ * dentry aliases at one time.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN	32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode;
++	unsigned long ino;
++	struct list_head *lp;
++	struct dentry *alternate;
++	char buf[IOPEN_NAME_LEN];
++	
++	if (dentry->d_name.len >= IOPEN_NAME_LEN)
++		return ERR_PTR(-ENAMETOOLONG);
++
++	memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++	buf[dentry->d_name.len] = 0;
++
++	if (strcmp(buf, ".") == 0)
++		ino = dir->i_ino;
++	else if (strcmp(buf, "..") == 0)
++		ino = EXT3_ROOT_INO;
++	else
++		ino = simple_strtoul(buf, 0, 0);
++
++	if ((ino != EXT3_ROOT_INO &&
++	     //ino != EXT3_ACL_IDX_INO &&
++	     //ino != EXT3_ACL_DATA_INO &&
++	     ino < EXT3_FIRST_INO(dir->i_sb)) ||
++	    ino > le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
++		return ERR_PTR(-ENOENT);
++
++	inode = iget(dir->i_sb, ino);
++	if (!inode)
++		return ERR_PTR(-EACCES);
++	if (is_bad_inode(inode)) {
++		iput(inode);
++		return ERR_PTR(-ENOENT);
++	}
++
++	/* preferrably return a connected dentry */
++	spin_lock(&dcache_lock);
++	list_for_each(lp, &inode->i_dentry) {
++		alternate = list_entry(lp, struct dentry, d_alias);
++		assert(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED));
++	}
++
++	if (!list_empty(&inode->i_dentry)) {
++		alternate = list_entry(inode->i_dentry.next, 
++				       struct dentry, d_alias);
++		dget_locked(alternate);
++		alternate->d_vfs_flags |= DCACHE_REFERENCED;
++		iput(inode);
++		spin_unlock(&dcache_lock);
++		return alternate;
++	}
++	dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
++	spin_unlock(&dcache_lock);
++
++	d_add(dentry, inode);
++	return NULL;
++}
++
++#define do_switch(x,y) do { \
++	__typeof__ (x) __tmp = x; \
++	x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry *dentry, struct dentry *target)
++{
++	const unsigned char *old_name, *new_name;
++
++	memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++	old_name = target->d_name.name;
++	new_name = dentry->d_name.name;
++	if (old_name == target->d_iname)
++		old_name = dentry->d_iname;
++	if (new_name == dentry->d_iname)
++		new_name = target->d_iname;
++	target->d_name.name = new_name;
++	dentry->d_name.name = old_name;
++}
++
++/* This function is spliced into ext3_lookup and does the move of a
++ * disconnected dentry (if it exists) to a connected dentry.
++ */
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++	struct dentry *tmp, *goal = NULL;
++	struct list_head *lp;
++
++	/* preferrably return a connected dentry */
++	spin_lock(&dcache_lock);
++	/* verify this dentry is really new */
++	assert(!de->d_inode);
++	assert(list_empty(&de->d_subdirs));
++	assert(list_empty(&de->d_alias));
++
++
++	list_for_each(lp, &inode->i_dentry) {
++		tmp = list_entry(lp, struct dentry, d_alias);
++		if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
++			assert(tmp->d_alias.next == &inode->i_dentry);
++			assert(tmp->d_alias.prev == &inode->i_dentry);
++			goal = tmp;
++			dget_locked(goal);
++			break;
++		}
++	}
++
++	if (!goal) { 
++		spin_unlock(&dcache_lock);
++		return NULL; 
++	}
++
++	/* Move the goal to the de hash queue - like d_move() */
++	goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
++	list_del_init(&goal->d_hash);
++
++	list_del(&goal->d_child);
++	list_del(&de->d_child);
++
++	/* Switch the parents and the names.. */
++	switch_names(goal, de);
++	do_switch(goal->d_parent, de->d_parent);
++	do_switch(goal->d_name.len, de->d_name.len);
++	do_switch(goal->d_name.hash, de->d_name.hash);
++
++	/* And add them back to the (new) parent lists */
++	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++	list_add(&de->d_child, &de->d_parent->d_subdirs);
++	__d_rehash(goal, 0);
++	spin_unlock(&dcache_lock);
++
++	return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++	lookup:		iopen_lookup,		/* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++	read:		generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++	int	len;
++
++	len = strlen(name);
++	if (dentry->d_name.len != len)
++		return 0;
++	if (strncmp(dentry->d_name.name, name, len))
++		return 0;
++	return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode;
++
++	if (dir->i_ino != EXT3_ROOT_INO ||
++	    !test_opt(dir->i_sb, IOPEN) ||
++	    !match_dentry(dentry, "__iopen__"))
++		return 0;
++
++	inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++	if (!inode) 
++		return 0;
++	d_add(dentry, inode);
++	return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode *inode)
++{
++	if (inode->i_ino != EXT3_BAD_INO)
++		return 0;
++
++	inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++	if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++		inode->i_mode |= 0777;
++	inode->i_uid = 0;
++	inode->i_gid = 0;
++	inode->i_nlink = 1;
++	inode->i_size = 4096;
++	inode->i_atime = CURRENT_TIME;
++	inode->i_ctime = CURRENT_TIME;
++	inode->i_mtime = CURRENT_TIME;
++	inode->u.ext3_i.i_dtime = 0;
++	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size
++					 * (for stat), not the fs block
++					 * size */  
++	inode->i_blocks = 0;
++	inode->i_version = 1;
++	inode->i_generation = 0;
++
++	inode->i_op = &iopen_inode_operations;
++	inode->i_fop = &iopen_file_operations;
++	inode->i_mapping->a_ops = 0;
++
++	return 1;
++}
+Index: linux-2.4.19.SuSE/fs/ext3/iopen.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/iopen.h	Sun Nov 16 01:27:31 2003
++++ linux-2.4.19.SuSE/fs/ext3/iopen.h	Sun Nov 16 01:27:31 2003
+@@ -0,0 +1,13 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode *inode);
+Index: linux-2.4.19.SuSE/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/namei.c	Sun Nov 16 01:23:20 2003
++++ linux-2.4.19.SuSE/fs/ext3/namei.c	Sun Nov 16 01:27:31 2003
+@@ -36,7 +36,7 @@
+ #include <linux/string.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+-
++#include "iopen.h"
+ 
+ /*
+  * define how far ahead to read directories while searching them.
+@@ -922,16 +922,21 @@
+ 	return NULL;
+ }
+ #endif
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
+ 
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
+ {
+ 	struct inode * inode;
+ 	struct ext3_dir_entry_2 * de;
+ 	struct buffer_head * bh;
++	struct dentry *alternate = NULL;
+ 
+ 	if (dentry->d_name.len > EXT3_NAME_LEN)
+ 		return ERR_PTR(-ENAMETOOLONG);
+ 
++	if (ext3_check_for_iopen(dir, dentry))
++		return NULL;
++
+ 	bh = ext3_find_entry(dentry, &de);
+ 	inode = NULL;
+ 	if (bh) {
+@@ -943,6 +948,12 @@
+ 			return ERR_PTR(-EACCES);
+ 		}
+ 	}
++
++	if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++		iput(inode);
++		return alternate;
++	}
++
+ 	d_add(dentry, inode);
+ 	return NULL;
+ }
+Index: linux-2.4.19.SuSE/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/super.c	Sun Nov 16 01:19:22 2003
++++ linux-2.4.19.SuSE/fs/ext3/super.c	Sun Nov 16 01:27:31 2003
+@@ -864,6 +864,17 @@
+ 		         || !strcmp (this_char, "quota")
+ 		         || !strcmp (this_char, "usrquota"))
+ 			/* Don't do anything ;-) */ ;
++		else if (!strcmp (this_char, "iopen")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		} else if (!strcmp (this_char, "noiopen")) {
++			clear_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
++		else if (!strcmp (this_char, "iopen_nopriv")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
+ 		else if (!strcmp (this_char, "journal")) {
+ 			/* @@@ FIXME */
+ 			/* Eventually we will want to be able to create
+Index: linux-2.4.19.SuSE/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/ext3_fs.h	Sun Nov 16 01:25:42 2003
++++ linux-2.4.19.SuSE/include/linux/ext3_fs.h	Sun Nov 16 01:30:05 2003
+@@ -324,6 +324,8 @@
+ #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ #define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
+ #define EXT3_MOUNT_ASYNCDEL		0x20000 /* Delayed deletion */
++#define EXT3_MOUNT_IOPEN		0x40000	/* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV		0x80000	/* Make iopen world-readable */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
diff --git a/lustre/kernel_patches/patches/iopen-2.4.20.patch b/lustre/kernel_patches/patches/iopen-2.4.20.patch
index ec48814d77f7730167d8dbcbf7432307de8d6418..dcf2fc049d35f6a630a3ee2c50e1efe35ffffb19 100644
--- a/lustre/kernel_patches/patches/iopen-2.4.20.patch
+++ b/lustre/kernel_patches/patches/iopen-2.4.20.patch
@@ -227,8 +227,7 @@
 +
 +	/* Move the goal to the de hash queue - like d_move() */
 +	goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
-+	list_del(&goal->d_hash);
-+	list_add(&goal->d_hash, &de->d_hash);
++	list_del_init(&goal->d_hash);
 +
 +	list_del(&goal->d_child);
 +	list_del(&de->d_child);
@@ -242,6 +241,7 @@
 +	/* And add them back to the (new) parent lists */
 +	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
 +	list_add(&de->d_child, &de->d_parent->d_subdirs);
++	__d_rehash(goal, 0);
 +	spin_unlock(&dcache_lock);
 +
 +	return goal;
diff --git a/lustre/kernel_patches/patches/iopen-2.5.73.patch b/lustre/kernel_patches/patches/iopen-2.5.73.patch
index c9d422372b4d1b6b41424ecfda1703f5b8ff5844..408aa439a1d4173f011ef61fd85bb74e4e1a45cb 100644
--- a/lustre/kernel_patches/patches/iopen-2.5.73.patch
+++ b/lustre/kernel_patches/patches/iopen-2.5.73.patch
@@ -9,7 +9,7 @@
  8 files changed, 300 insertions(+), 1 deletion(-)
 
 --- linux-2.6.0-test1/Documentation/filesystems/ext2.txt~iopen-2.5.73	2003-07-13 21:31:56.000000000 -0600
-+++ linux-2.6.0-test1-braam/Documentation/filesystems/ext2.txt	2003-07-22 01:15:46.000000000 -0600
++++ linux-2.6.0-test1-braam/Documentation/filesystems/ext2.txt	2003-07-22 13:03:47.000000000 -0600
 @@ -35,6 +35,22 @@ resgid=n			The group ID which may use th
  
  sb=n				Use alternate superblock at this location.
@@ -34,7 +34,7 @@
  
  
 --- linux-2.6.0-test1/fs/ext3/Makefile~iopen-2.5.73	2003-07-13 21:30:37.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/ext3/Makefile	2003-07-22 01:15:46.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/Makefile	2003-07-22 13:03:47.000000000 -0600
 @@ -5,7 +5,7 @@
  obj-$(CONFIG_EXT3_FS) += ext3.o
  
@@ -44,8 +44,8 @@
  
  ifeq ($(CONFIG_EXT3_FS_XATTR),y)
  ext3-objs += xattr.o xattr_user.o xattr_trusted.o
---- linux-2.6.0-test1/fs/ext3/inode.c~iopen-2.5.73	2003-07-22 01:15:25.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/ext3/inode.c	2003-07-22 01:16:19.000000000 -0600
+--- linux-2.6.0-test1/fs/ext3/inode.c~iopen-2.5.73	2003-07-22 13:03:47.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/inode.c	2003-07-22 13:03:47.000000000 -0600
 @@ -37,6 +37,7 @@
  #include <linux/mpage.h>
  #include <linux/uio.h>
@@ -64,7 +64,7 @@
  		goto bad_inode;
  	bh = iloc.bh;
 --- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/fs/ext3/iopen.c	2003-07-22 01:15:46.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/iopen.c	2003-07-22 13:07:32.000000000 -0600
 @@ -0,0 +1,239 @@
 +
 +
@@ -96,7 +96,7 @@
 +/*
 + * This implements looking up an inode by number.
 + */
-+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry)
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
 +{
 +	struct inode * inode;
 +	unsigned long ino;
@@ -306,7 +306,7 @@
 +	return 1;
 +}
 --- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/fs/ext3/iopen.h	2003-07-22 01:15:46.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/iopen.h	2003-07-22 13:03:47.000000000 -0600
 @@ -0,0 +1,15 @@
 +/*
 + * iopen.h
@@ -324,7 +324,7 @@
 +
 +
 --- linux-2.6.0-test1/fs/ext3/namei.c~iopen-2.5.73	2003-07-13 21:34:43.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/ext3/namei.c	2003-07-22 01:17:20.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/namei.c	2003-07-22 13:03:47.000000000 -0600
 @@ -37,6 +37,7 @@
  #include <linux/buffer_head.h>
  #include <linux/smp_lock.h>
@@ -368,8 +368,8 @@
  	d_add(dentry, inode);
  	return NULL;
  }
---- linux-2.6.0-test1/fs/ext3/super.c~iopen-2.5.73	2003-07-22 01:15:25.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/ext3/super.c	2003-07-22 01:15:46.000000000 -0600
+--- linux-2.6.0-test1/fs/ext3/super.c~iopen-2.5.73	2003-07-22 13:03:47.000000000 -0600
++++ linux-2.6.0-test1-braam/fs/ext3/super.c	2003-07-22 13:03:47.000000000 -0600
 @@ -755,6 +755,17 @@ static int parse_options (char * options
  		         || !strcmp (this_char, "quota")
  		         || !strcmp (this_char, "usrquota"))
@@ -388,8 +388,8 @@
  		else if (!strcmp (this_char, "journal")) {
  			/* @@@ FIXME */
  			/* Eventually we will want to be able to create
---- linux-2.6.0-test1/include/linux/ext3_fs.h~iopen-2.5.73	2003-07-22 01:14:05.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/ext3_fs.h	2003-07-22 01:15:46.000000000 -0600
+--- linux-2.6.0-test1/include/linux/ext3_fs.h~iopen-2.5.73	2003-07-22 11:04:35.000000000 -0600
++++ linux-2.6.0-test1-braam/include/linux/ext3_fs.h	2003-07-22 13:03:47.000000000 -0600
 @@ -324,6 +324,8 @@ struct ext3_inode {
  #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
  #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
diff --git a/lustre/kernel_patches/patches/iopen-2.6.0-test6.patch b/lustre/kernel_patches/patches/iopen-2.6.0-test6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3c64e1e3a16df1f44e2eb4ca4cf427ca97367174
--- /dev/null
+++ b/lustre/kernel_patches/patches/iopen-2.6.0-test6.patch
@@ -0,0 +1,411 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/inode.c                    |    3 
+ fs/ext3/iopen.c                    |  239 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   15 ++
+ fs/ext3/namei.c                    |   13 ++
+ fs/ext3/super.c                    |   17 ++
+ include/linux/ext3_fs.h            |    2 
+ 7 files changed, 304 insertions(+), 1 deletion(-)
+
+--- linux-2.6.0-test6/Documentation/filesystems/ext2.txt~iopen-2.6.0-test6	2002-11-11 06:28:06.000000000 +0300
++++ linux-2.6.0-test6-alexey/Documentation/filesystems/ext2.txt	2003-10-14 17:03:48.000000000 +0400
+@@ -35,6 +35,22 @@ resgid=n			The group ID which may use th
+ 
+ sb=n				Use alternate superblock at this location.
+ 
++iopen				Makes an invisible pseudo-directory called 
++				__iopen__ available in the root directory
++				of the filesystem.  Allows open-by-inode-
++				number.  i.e., inode 3145 can be accessed
++				via /mntpt/__iopen__/3145
++
++iopen_nopriv			This option makes the iopen directory be
++				world-readable.  This may be safer since it
++				allows daemons to run as an unprivileged user,
++				however it significantly changes the security
++				model of a Unix filesystem, since previously
++				all files under a mode 700 directory were not
++				generally avilable even if the
++				permissions on the file itself is
++				world-readable.
++
+ grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
+ 
+ 
+--- linux-2.6.0-test6/fs/ext3/inode.c~iopen-2.6.0-test6	2003-10-14 17:03:47.000000000 +0400
++++ linux-2.6.0-test6-alexey/fs/ext3/inode.c	2003-10-14 17:03:48.000000000 +0400
+@@ -37,6 +37,7 @@
+ #include <linux/mpage.h>
+ #include <linux/uio.h>
+ #include "xattr.h"
++#include "iopen.h"
+ #include "acl.h"
+ 
+ /*
+@@ -2479,6 +2480,8 @@ void ext3_read_inode(struct inode * inod
+ 	ei->i_acl = EXT3_ACL_NOT_CACHED;
+ 	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+ #endif
++	if (ext3_iopen_get_inode(inode))
++		return;
+ 	if (ext3_get_inode_loc(inode, &iloc, 0))
+ 		goto bad_inode;
+ 	bh = iloc.bh;
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test6-alexey/fs/ext3/iopen.c	2003-10-14 17:03:48.000000000 +0400
+@@ -0,0 +1,239 @@
++
++
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN	32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
++{
++	struct inode * inode;
++	unsigned long ino;
++        struct list_head *lp;
++        struct dentry *alternate;
++	char buf[IOPEN_NAME_LEN];
++	
++	if (dentry->d_name.len >= IOPEN_NAME_LEN)
++		return ERR_PTR(-ENAMETOOLONG);
++
++	memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++	buf[dentry->d_name.len] = 0;
++
++	if (strcmp(buf, ".") == 0)
++		ino = dir->i_ino;
++	else if (strcmp(buf, "..") == 0)
++		ino = EXT3_ROOT_INO;
++	else
++		ino = simple_strtoul(buf, 0, 0);
++
++	if ((ino != EXT3_ROOT_INO &&
++	     //ino != EXT3_ACL_IDX_INO &&
++	     //ino != EXT3_ACL_DATA_INO &&
++	     ino < EXT3_FIRST_INO(dir->i_sb)) ||
++	    ino > le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
++		return ERR_PTR(-ENOENT);
++
++	inode = iget(dir->i_sb, ino);
++	if (!inode)
++		return ERR_PTR(-EACCES);
++	if (is_bad_inode(inode)) {
++		iput(inode);
++		return ERR_PTR(-ENOENT);
++	}
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        list_for_each(lp, &inode->i_dentry) {
++                alternate = list_entry(lp, struct dentry, d_alias);
++                assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
++        }
++
++        if (!list_empty(&inode->i_dentry)) {
++                alternate = list_entry(inode->i_dentry.next, 
++                                       struct dentry, d_alias);
++                dget_locked(alternate);
++                alternate->d_vfs_flags |= DCACHE_REFERENCED;
++                iput(inode);
++                spin_unlock(&dcache_lock);
++                return alternate;
++        }
++        dentry->d_flags |= DCACHE_DISCONNECTED;
++        spin_unlock(&dcache_lock);
++
++	d_add(dentry, inode);
++	return NULL;
++}
++
++#define do_switch(x,y) do { \
++	__typeof__ (x) __tmp = x; \
++	x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry * dentry, struct dentry * target)
++{
++	const unsigned char *old_name, *new_name;
++
++	memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++	old_name = target->d_name.name;
++	new_name = dentry->d_name.name;
++	if (old_name == target->d_iname)
++		old_name = dentry->d_iname;
++	if (new_name == dentry->d_iname)
++		new_name = target->d_iname;
++	target->d_name.name = new_name;
++	dentry->d_name.name = old_name;
++}
++
++
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++        struct dentry *tmp, *goal = NULL;
++        struct list_head *lp;
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        /* verify this dentry is really new */
++        assert(!de->d_inode);
++        assert(list_empty(&de->d_subdirs));
++        assert(list_empty(&de->d_alias));
++
++
++        list_for_each(lp, &inode->i_dentry) {
++                tmp = list_entry(lp, struct dentry, d_alias);
++                if (tmp->d_flags & DCACHE_DISCONNECTED) {
++                        assert(tmp->d_alias.next == &inode->i_dentry);
++                        assert(tmp->d_alias.prev == &inode->i_dentry);
++                        goal = tmp;
++                        dget_locked(goal);
++                        break;
++                }
++        }
++
++        if (!goal) { 
++                spin_unlock(&dcache_lock);
++                return NULL; 
++        }
++
++        /* Move the goal to the de hash queue */
++        goal->d_flags &= ~DCACHE_DISCONNECTED;
++	hlist_add_before(&goal->d_hash, &de->d_hash);
++	hlist_del(&goal->d_hash);
++
++	list_del(&goal->d_child);
++	list_del(&de->d_child);
++
++	/* Switch the parents and the names.. */
++	switch_names(goal, de);
++	do_switch(goal->d_parent, de->d_parent);
++	do_switch(goal->d_name.len, de->d_name.len);
++	do_switch(goal->d_name.hash, de->d_name.hash);
++
++	/* And add them back to the (new) parent lists */
++	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++	list_add(&de->d_child, &de->d_parent->d_subdirs);
++
++        spin_unlock(&dcache_lock);
++        return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++	lookup:		iopen_lookup,		/* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++	read:		generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++	int	len;
++
++	len = strlen(name);
++	if (dentry->d_name.len != len)
++		return 0;
++	if (strncmp(dentry->d_name.name, name, len))
++		return 0;
++	return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry)
++{
++	struct inode * inode;
++
++	if (dir->i_ino != EXT3_ROOT_INO ||
++	    !test_opt(dir->i_sb, IOPEN) ||
++	    !match_dentry(dentry, "__iopen__"))
++		return 0;
++
++	inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++	if (!inode) 
++		return 0;
++	d_add(dentry, inode);
++	return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode * inode)
++{
++	if (inode->i_ino != EXT3_BAD_INO)
++		return 0;
++
++	inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++	if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++		inode->i_mode |= 0777;
++	inode->i_uid = 0;
++	inode->i_gid = 0;
++	inode->i_nlink = 1;
++	inode->i_size = 4096;
++	inode->i_atime = CURRENT_TIME;
++	inode->i_ctime = CURRENT_TIME;
++	inode->i_mtime = CURRENT_TIME;
++	EXT3_I(inode)->i_dtime = 0;
++	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size
++					 * (for stat), not the fs block
++					 * size */  
++	inode->i_blocks = 0;
++	inode->i_version = 1;
++	inode->i_generation = 0;
++
++	inode->i_op = &iopen_inode_operations;
++	inode->i_fop = &iopen_file_operations;
++	inode->i_mapping->a_ops = 0;
++
++	return 1;
++}
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test6-alexey/fs/ext3/iopen.h	2003-10-14 17:03:48.000000000 +0400
+@@ -0,0 +1,15 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode * inode);
++
++
+--- linux-2.6.0-test6/fs/ext3/namei.c~iopen-2.6.0-test6	2003-10-14 17:03:47.000000000 +0400
++++ linux-2.6.0-test6-alexey/fs/ext3/namei.c	2003-10-14 17:03:48.000000000 +0400
+@@ -37,6 +37,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/smp_lock.h>
+ #include "xattr.h"
++#include "iopen.h"
+ #include "acl.h"
+ 
+ /*
+@@ -970,15 +971,21 @@ errout:
+ }
+ #endif
+ 
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
++ 
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct inode * inode;
+ 	struct ext3_dir_entry_2 * de;
+ 	struct buffer_head * bh;
++  	struct dentry *alternate = NULL;
+ 
+ 	if (dentry->d_name.len > EXT3_NAME_LEN)
+ 		return ERR_PTR(-ENAMETOOLONG);
+ 
++ 	if (ext3_check_for_iopen(dir, dentry))
++ 		return NULL;
++
+ 	bh = ext3_find_entry(dentry, &de);
+ 	inode = NULL;
+ 	if (bh) {
+@@ -991,6 +998,12 @@ static struct dentry *ext3_lookup(struct
+ 	}
+ 	if (inode)
+ 		return d_splice_alias(inode, dentry);
++
++	if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++		iput(inode);
++		return alternate;
++	}
++
+ 	d_add(dentry, inode);
+ 	return NULL;
+ }
+--- linux-2.6.0-test6/fs/ext3/super.c~iopen-2.6.0-test6	2003-10-14 17:03:47.000000000 +0400
++++ linux-2.6.0-test6-alexey/fs/ext3/super.c	2003-10-14 17:03:48.000000000 +0400
+@@ -534,7 +534,7 @@ enum {
+ 	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
+ 	Opt_commit, Opt_journal_update, Opt_journal_inum,
+ 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+-	Opt_ignore, Opt_err,
++	Opt_ignore, Opt_err, Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
+ };
+ 
+ static match_table_t tokens = {
+@@ -573,6 +573,9 @@ static match_table_t tokens = {
+ 	{Opt_ignore, "noquota"},
+ 	{Opt_ignore, "quota"},
+ 	{Opt_ignore, "usrquota"},
++	{Opt_iopen,  "iopen"},
++	{Opt_noiopen,  "noiopen"},
++	{Opt_iopen_nopriv,  "iopen_nopriv"},
+ 	{Opt_err, NULL}
+ };
+ 
+@@ -760,6 +763,18 @@ static int parse_options (char * options
+ 		case Opt_abort:
+ 			set_opt(sbi->s_mount_opt, ABORT);
+ 			break;
++		case Opt_iopen:
++ 			set_opt (sbi->s_mount_opt, IOPEN);
++ 			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++			break;
++		case Opt_noiopen:
++			clear_opt (sbi->s_mount_opt, IOPEN);
++ 			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++			break;
++		case Opt_iopen_nopriv:
++ 			set_opt (sbi->s_mount_opt, IOPEN);
++ 			set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++			break;
+ 		case Opt_ignore:
+ 			break;
+ 		default:
+--- linux-2.6.0-test6/include/linux/ext3_fs.h~iopen-2.6.0-test6	2003-10-14 17:03:47.000000000 +0400
++++ linux-2.6.0-test6-alexey/include/linux/ext3_fs.h	2003-10-14 17:03:48.000000000 +0400
+@@ -325,6 +325,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ #define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
++#define EXT3_MOUNT_IOPEN	       0x10000  /* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV	       0x20000  /* Make iopen world-readable */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+
+_
diff --git a/lustre/kernel_patches/patches/iopen-2.6.0.patch b/lustre/kernel_patches/patches/iopen-2.6.0.patch
new file mode 100644
index 0000000000000000000000000000000000000000..af67758d0d7093b8b42fb4fc7264fce8f358ee02
--- /dev/null
+++ b/lustre/kernel_patches/patches/iopen-2.6.0.patch
@@ -0,0 +1,403 @@
+ Documentation/filesystems/ext2.txt |   16 ++
+ fs/ext3/Makefile                   |    2 
+ fs/ext3/inode.c                    |    3 
+ fs/ext3/iopen.c                    |  239 +++++++++++++++++++++++++++++++++++++
+ fs/ext3/iopen.h                    |   15 ++
+ fs/ext3/namei.c                    |   13 ++
+ fs/ext3/super.c                    |   11 +
+ include/linux/ext3_fs.h            |    2 
+ 8 files changed, 300 insertions(+), 1 deletion(-)
+
+--- linux-2.6.0-test1/Documentation/filesystems/ext2.txt~iopen-2.6.0	2002-11-11 06:28:06.000000000 +0300
++++ linux-2.6.0-test1-alexey/Documentation/filesystems/ext2.txt	2003-08-24 13:02:02.000000000 +0400
+@@ -35,6 +35,22 @@ resgid=n			The group ID which may use th
+ 
+ sb=n				Use alternate superblock at this location.
+ 
++iopen				Makes an invisible pseudo-directory called 
++				__iopen__ available in the root directory
++				of the filesystem.  Allows open-by-inode-
++				number.  i.e., inode 3145 can be accessed
++				via /mntpt/__iopen__/3145
++
++iopen_nopriv			This option makes the iopen directory be
++				world-readable.  This may be safer since it
++				allows daemons to run as an unprivileged user,
++				however it significantly changes the security
++				model of a Unix filesystem, since previously
++				all files under a mode 700 directory were not
++				generally avilable even if the
++				permissions on the file itself is
++				world-readable.
++
+ grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
+ 
+ 
+--- linux-2.6.0-test1/fs/ext3/inode.c~iopen-2.6.0	2003-08-24 13:00:36.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/ext3/inode.c	2003-08-24 13:02:02.000000000 +0400
+@@ -37,6 +37,7 @@
+ #include <linux/mpage.h>
+ #include <linux/uio.h>
+ #include "xattr.h"
++#include "iopen.h"
+ #include "acl.h"
+ 
+ /*
+@@ -2477,6 +2478,8 @@ void ext3_read_inode(struct inode * inod
+ 	ei->i_acl = EXT3_ACL_NOT_CACHED;
+ 	ei->i_default_acl = EXT3_ACL_NOT_CACHED;
+ #endif
++	if (ext3_iopen_get_inode(inode))
++		return;
+ 	if (ext3_get_inode_loc(inode, &iloc, 0))
+ 		goto bad_inode;
+ 	bh = iloc.bh;
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test1-alexey/fs/ext3/iopen.c	2003-08-24 13:02:02.000000000 +0400
+@@ -0,0 +1,239 @@
++
++
++/*
++ * linux/fs/ext3/iopen.c
++ *
++ * Special support for open by inode number
++ *
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/smp_lock.h>
++#include "iopen.h"
++
++#ifndef assert
++#define assert(test) J_ASSERT(test)
++#endif
++
++#define IOPEN_NAME_LEN	32
++
++/*
++ * This implements looking up an inode by number.
++ */
++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
++{
++	struct inode * inode;
++	unsigned long ino;
++        struct list_head *lp;
++        struct dentry *alternate;
++	char buf[IOPEN_NAME_LEN];
++	
++	if (dentry->d_name.len >= IOPEN_NAME_LEN)
++		return ERR_PTR(-ENAMETOOLONG);
++
++	memcpy(buf, dentry->d_name.name, dentry->d_name.len);
++	buf[dentry->d_name.len] = 0;
++
++	if (strcmp(buf, ".") == 0)
++		ino = dir->i_ino;
++	else if (strcmp(buf, "..") == 0)
++		ino = EXT3_ROOT_INO;
++	else
++		ino = simple_strtoul(buf, 0, 0);
++
++	if ((ino != EXT3_ROOT_INO &&
++	     //ino != EXT3_ACL_IDX_INO &&
++	     //ino != EXT3_ACL_DATA_INO &&
++	     ino < EXT3_FIRST_INO(dir->i_sb)) ||
++	    ino > le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
++		return ERR_PTR(-ENOENT);
++
++	inode = iget(dir->i_sb, ino);
++	if (!inode)
++		return ERR_PTR(-EACCES);
++	if (is_bad_inode(inode)) {
++		iput(inode);
++		return ERR_PTR(-ENOENT);
++	}
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        list_for_each(lp, &inode->i_dentry) {
++                alternate = list_entry(lp, struct dentry, d_alias);
++                assert(!(alternate->d_flags & DCACHE_DISCONNECTED));
++        }
++
++        if (!list_empty(&inode->i_dentry)) {
++                alternate = list_entry(inode->i_dentry.next, 
++                                       struct dentry, d_alias);
++                dget_locked(alternate);
++                alternate->d_vfs_flags |= DCACHE_REFERENCED;
++                iput(inode);
++                spin_unlock(&dcache_lock);
++                return alternate;
++        }
++        dentry->d_flags |= DCACHE_DISCONNECTED;
++        spin_unlock(&dcache_lock);
++
++	d_add(dentry, inode);
++	return NULL;
++}
++
++#define do_switch(x,y) do { \
++	__typeof__ (x) __tmp = x; \
++	x = y; y = __tmp; } while (0)
++
++static inline void switch_names(struct dentry * dentry, struct dentry * target)
++{
++	const unsigned char *old_name, *new_name;
++
++	memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); 
++	old_name = target->d_name.name;
++	new_name = dentry->d_name.name;
++	if (old_name == target->d_iname)
++		old_name = dentry->d_iname;
++	if (new_name == dentry->d_iname)
++		new_name = target->d_iname;
++	target->d_name.name = new_name;
++	dentry->d_name.name = old_name;
++}
++
++
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode)
++{
++        struct dentry *tmp, *goal = NULL;
++        struct list_head *lp;
++
++        /* preferrably return a connected dentry */
++        spin_lock(&dcache_lock);
++        /* verify this dentry is really new */
++        assert(!de->d_inode);
++        assert(list_empty(&de->d_subdirs));
++        assert(list_empty(&de->d_alias));
++
++
++        list_for_each(lp, &inode->i_dentry) {
++                tmp = list_entry(lp, struct dentry, d_alias);
++                if (tmp->d_flags & DCACHE_DISCONNECTED) {
++                        assert(tmp->d_alias.next == &inode->i_dentry);
++                        assert(tmp->d_alias.prev == &inode->i_dentry);
++                        goal = tmp;
++                        dget_locked(goal);
++                        break;
++                }
++        }
++
++        if (!goal) { 
++                spin_unlock(&dcache_lock);
++                return NULL; 
++        }
++
++        /* Move the goal to the de hash queue */
++        goal->d_flags &= ~DCACHE_DISCONNECTED;
++	hlist_add_before(&goal->d_hash, &de->d_hash);
++	hlist_del(&goal->d_hash);
++
++	list_del(&goal->d_child);
++	list_del(&de->d_child);
++
++	/* Switch the parents and the names.. */
++	switch_names(goal, de);
++	do_switch(goal->d_parent, de->d_parent);
++	do_switch(goal->d_name.len, de->d_name.len);
++	do_switch(goal->d_name.hash, de->d_name.hash);
++
++	/* And add them back to the (new) parent lists */
++	list_add(&goal->d_child, &goal->d_parent->d_subdirs);
++	list_add(&de->d_child, &de->d_parent->d_subdirs);
++
++        spin_unlock(&dcache_lock);
++        return goal;
++}
++
++/*
++ * These are the special structures for the iopen pseudo directory.
++ */
++
++static struct inode_operations iopen_inode_operations = {
++	lookup:		iopen_lookup,		/* BKL held */
++};
++
++static struct file_operations iopen_file_operations = {
++	read:		generic_read_dir,
++};
++
++static int match_dentry(struct dentry *dentry, const char *name)
++{
++	int	len;
++
++	len = strlen(name);
++	if (dentry->d_name.len != len)
++		return 0;
++	if (strncmp(dentry->d_name.name, name, len))
++		return 0;
++	return 1;
++}
++
++/*
++ * This function is spliced into ext3_lookup and returns 1 the file
++ * name is __iopen__ and dentry has been filled in appropriately.
++ */
++int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry)
++{
++	struct inode * inode;
++
++	if (dir->i_ino != EXT3_ROOT_INO ||
++	    !test_opt(dir->i_sb, IOPEN) ||
++	    !match_dentry(dentry, "__iopen__"))
++		return 0;
++
++	inode = iget(dir->i_sb, EXT3_BAD_INO);
++
++	if (!inode) 
++		return 0;
++	d_add(dentry, inode);
++	return 1;
++}
++
++/*
++ * This function is spliced into read_inode; it returns 1 if inode
++ * number is the one for /__iopen__, in which case the inode is filled
++ * in appropriately.  Otherwise, this fuction returns 0.
++ */
++int ext3_iopen_get_inode(struct inode * inode)
++{
++	if (inode->i_ino != EXT3_BAD_INO)
++		return 0;
++
++	inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
++	if (test_opt(inode->i_sb, IOPEN_NOPRIV))
++		inode->i_mode |= 0777;
++	inode->i_uid = 0;
++	inode->i_gid = 0;
++	inode->i_nlink = 1;
++	inode->i_size = 4096;
++	inode->i_atime = CURRENT_TIME;
++	inode->i_ctime = CURRENT_TIME;
++	inode->i_mtime = CURRENT_TIME;
++	EXT3_I(inode)->i_dtime = 0;
++	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size
++					 * (for stat), not the fs block
++					 * size */  
++	inode->i_blocks = 0;
++	inode->i_version = 1;
++	inode->i_generation = 0;
++
++	inode->i_op = &iopen_inode_operations;
++	inode->i_fop = &iopen_file_operations;
++	inode->i_mapping->a_ops = 0;
++
++	return 1;
++}
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test1-alexey/fs/ext3/iopen.h	2003-08-24 13:02:02.000000000 +0400
+@@ -0,0 +1,15 @@
++/*
++ * iopen.h
++ *
++ * Special support for opening files by inode number.
++ * 
++ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu).
++ * 
++ * This file may be redistributed under the terms of the GNU General
++ * Public License.
++ */
++
++extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry);
++extern int ext3_iopen_get_inode(struct inode * inode);
++
++
+--- linux-2.6.0-test1/fs/ext3/Makefile~iopen-2.6.0	2003-08-24 12:58:32.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/ext3/Makefile	2003-08-24 13:02:40.000000000 +0400
+@@ -5,7 +5,7 @@
+ obj-$(CONFIG_EXT3_FS) += ext3.o
+ 
+ ext3-y	:= balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-	   ioctl.o namei.o super.o symlink.o hash.o
++	   iopen.o ioctl.o namei.o super.o symlink.o hash.o
+ 
+ ext3-$(CONFIG_EXT3_FS_XATTR)	 += xattr.o xattr_user.o xattr_trusted.o
+ ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
+--- linux-2.6.0-test1/fs/ext3/namei.c~iopen-2.6.0	2003-07-24 15:52:30.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/ext3/namei.c	2003-08-24 13:02:02.000000000 +0400
+@@ -37,6 +37,7 @@
+ #include <linux/buffer_head.h>
+ #include <linux/smp_lock.h>
+ #include "xattr.h"
++#include "iopen.h"
+ #include "acl.h"
+ 
+ /*
+@@ -970,15 +971,21 @@ errout:
+ }
+ #endif
+ 
++struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode);
++ 
+ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct inode * inode;
+ 	struct ext3_dir_entry_2 * de;
+ 	struct buffer_head * bh;
++  	struct dentry *alternate = NULL;
+ 
+ 	if (dentry->d_name.len > EXT3_NAME_LEN)
+ 		return ERR_PTR(-ENAMETOOLONG);
+ 
++ 	if (ext3_check_for_iopen(dir, dentry))
++ 		return NULL;
++
+ 	bh = ext3_find_entry(dentry, &de);
+ 	inode = NULL;
+ 	if (bh) {
+@@ -991,6 +998,12 @@ static struct dentry *ext3_lookup(struct
+ 	}
+ 	if (inode)
+ 		return d_splice_alias(inode, dentry);
++
++	if (inode && (alternate = iopen_connect_dentry(dentry, inode))) {
++		iput(inode);
++		return alternate;
++	}
++
+ 	d_add(dentry, inode);
+ 	return NULL;
+ }
+--- linux-2.6.0-test1/fs/ext3/super.c~iopen-2.6.0	2003-08-24 13:00:36.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/ext3/super.c	2003-08-24 13:02:02.000000000 +0400
+@@ -755,6 +755,17 @@ static int parse_options (char * options
+ 		         || !strcmp (this_char, "quota")
+ 		         || !strcmp (this_char, "usrquota"))
+ 			/* Don't do anything ;-) */ ;
++		else if (!strcmp (this_char, "iopen")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		} else if (!strcmp (this_char, "noiopen")) {
++			clear_opt (sbi->s_mount_opt, IOPEN);
++			clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
++		else if (!strcmp (this_char, "iopen_nopriv")) {
++			set_opt (sbi->s_mount_opt, IOPEN);
++			set_opt (sbi->s_mount_opt, IOPEN_NOPRIV);
++		}
+ 		else if (!strcmp (this_char, "journal")) {
+ 			/* @@@ FIXME */
+ 			/* Eventually we will want to be able to create
+--- linux-2.6.0-test1/include/linux/ext3_fs.h~iopen-2.6.0	2003-08-24 12:58:57.000000000 +0400
++++ linux-2.6.0-test1-alexey/include/linux/ext3_fs.h	2003-08-24 13:02:02.000000000 +0400
+@@ -324,6 +324,8 @@ struct ext3_inode {
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
+ #define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ #define EXT3_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
++#define EXT3_MOUNT_IOPEN	       0x10000  /* Allow access via iopen */
++#define EXT3_MOUNT_IOPEN_NOPRIV	       0x20000  /* Make iopen world-readable */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+
+_
diff --git a/lustre/kernel_patches/patches/jbd-2.4.18-jcberr.patch b/lustre/kernel_patches/patches/jbd-2.4.18-jcberr.patch
new file mode 100644
index 0000000000000000000000000000000000000000..81b4136377fa648bb1951ba286dba6f23b4611ea
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-2.4.18-jcberr.patch
@@ -0,0 +1,274 @@
+Index: linux-2.4.19.SuSE/include/linux/jbd.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/jbd.h	Sun Nov 16 13:51:03 2003
++++ linux-2.4.19.SuSE/include/linux/jbd.h	Sun Nov 16 15:10:48 2003
+@@ -283,6 +283,13 @@
+ 	return bh->b_private;
+ }
+ 
++#define HAVE_JOURNAL_CALLBACK_STATUS
++struct journal_callback {
++	struct list_head jcb_list;
++	void (*jcb_func)(struct journal_callback *jcb, int error);
++	/* user data goes here */
++};
++
+ struct jbd_revoke_table_s;
+ 
+ /* The handle_t type represents a single atomic update being performed
+@@ -313,6 +320,12 @@
+ 	   operations */
+ 	int			h_err;
+ 
++	/* List of application registered callbacks for this handle.
++	 * The function(s) will be called after the transaction that
++	 * this handle is part of has been committed to disk.
++	 */
++	struct list_head	h_jcb;
++
+ 	/* Flags */
+ 	unsigned int	h_sync:		1;	/* sync-on-close */
+ 	unsigned int	h_jdata:	1;	/* force data journaling */
+@@ -432,6 +445,10 @@
+ 
+ 	/* How many handles used this transaction? */
+ 	int t_handle_count;
++
++	/* List of registered callback functions for this transaction.
++	 * Called when the transaction is committed. */
++	struct list_head	t_jcb;
+ };
+ 
+ 
+@@ -676,6 +693,9 @@
+ extern int	 journal_try_to_free_buffers(journal_t *, struct page *, int);
+ extern int	 journal_stop(handle_t *);
+ extern int	 journal_flush (journal_t *);
++extern void	 journal_callback_set(handle_t *handle,
++				      void (*fn)(struct journal_callback *,int),
++				      struct journal_callback *jcb);
+ 
+ extern void	 journal_lock_updates (journal_t *);
+ extern void	 journal_unlock_updates (journal_t *);
+Index: linux-2.4.19.SuSE/fs/jbd/checkpoint.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/jbd/checkpoint.c	Mon Feb 25 11:38:08 2002
++++ linux-2.4.19.SuSE/fs/jbd/checkpoint.c	Sun Nov 16 15:10:48 2003
+@@ -594,7 +594,8 @@
+ 	J_ASSERT (transaction->t_log_list == NULL);
+ 	J_ASSERT (transaction->t_checkpoint_list == NULL);
+ 	J_ASSERT (transaction->t_updates == 0);
+-	
++	J_ASSERT (list_empty(&transaction->t_jcb));
++
+ 	J_ASSERT (transaction->t_journal->j_committing_transaction !=
+ 					transaction);
+ 	
+Index: linux-2.4.19.SuSE/fs/jbd/commit.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/jbd/commit.c	Mon Jan 27 05:08:04 2003
++++ linux-2.4.19.SuSE/fs/jbd/commit.c	Sun Nov 16 15:13:53 2003
+@@ -485,7 +485,7 @@
+            transaction's t_log_list queue, and metadata buffers are on
+            the t_iobuf_list queue.
+ 
+-	   Wait for the transactions in reverse order.  That way we are
++	   Wait for the buffers in reverse order.  That way we are
+ 	   less likely to be woken up until all IOs have completed, and
+ 	   so we incur less scheduling load.
+ 	*/
+@@ -576,8 +576,10 @@
+ 
+ 	jbd_debug(3, "JBD: commit phase 6\n");
+ 
+-	if (is_journal_aborted(journal))
++	if (is_journal_aborted(journal)) {
++		unlock_journal(journal);
+ 		goto skip_commit;
++	}
+ 
+ 	/* Done it all: now write the commit record.  We should have
+ 	 * cleaned up our previous buffers by now, so if we are in abort
+@@ -587,9 +589,10 @@
+ 	descriptor = journal_get_descriptor_buffer(journal);
+ 	if (!descriptor) {
+ 		__journal_abort_hard(journal);
++		unlock_journal(journal);
+ 		goto skip_commit;
+ 	}
+-	
++
+ 	/* AKPM: buglet - add `i' to tmp! */
+ 	for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
+ 		journal_header_t *tmp =
+@@ -610,14 +614,32 @@
+ 		put_bh(bh);		/* One for getblk() */
+ 		journal_unlock_journal_head(descriptor);
+ 	}
+-	lock_journal(journal);
+ 
+ 	/* End of a transaction!  Finally, we can do checkpoint
+            processing: any buffers committed as a result of this
+            transaction can be removed from any checkpoint list it was on
+            before. */
+ 
+-skip_commit:
++skip_commit: /* The journal should be unlocked by now. */
++
++	/* Call any callbacks that had been registered for handles in this
++	 * transaction.  It is up to the callback to free any allocated
++	 * memory.
++	 */
++	if (!list_empty(&commit_transaction->t_jcb)) {
++		struct list_head *p, *n;
++		int error = is_journal_aborted(journal);
++
++		list_for_each_safe(p, n, &commit_transaction->t_jcb) {
++			struct journal_callback *jcb;
++
++			jcb = list_entry(p, struct journal_callback, jcb_list);
++			list_del(p);
++			jcb->jcb_func(jcb, error);
++		}
++	}
++
++	lock_journal(journal);
+ 
+ 	jbd_debug(3, "JBD: commit phase 7\n");
+ 
+Index: linux-2.4.19.SuSE/fs/jbd/journal.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/jbd/journal.c	Mon Jan 27 05:08:00 2003
++++ linux-2.4.19.SuSE/fs/jbd/journal.c	Sun Nov 16 15:10:48 2003
+@@ -59,6 +59,7 @@
+ #endif
+ EXPORT_SYMBOL(journal_flush);
+ EXPORT_SYMBOL(journal_revoke);
++EXPORT_SYMBOL(journal_callback_set);
+ 
+ EXPORT_SYMBOL(journal_init_dev);
+ EXPORT_SYMBOL(journal_init_inode);
+Index: linux-2.4.19.SuSE/fs/jbd/transaction.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/jbd/transaction.c	Sun Nov 16 01:45:26 2003
++++ linux-2.4.19.SuSE/fs/jbd/transaction.c	Sun Nov 16 15:15:34 2003
+@@ -58,6 +58,7 @@
+ 	transaction->t_state = T_RUNNING;
+ 	transaction->t_tid = journal->j_transaction_sequence++;
+ 	transaction->t_expires = jiffies + bdflush_interval();
++	INIT_LIST_HEAD(&transaction->t_jcb);
+ 
+ 	/* Set up the commit timer for the new transaction. */
+ 	J_ASSERT (!journal->j_commit_timer_active);
+@@ -91,7 +92,14 @@
+ 	transaction_t *transaction;
+ 	int needed;
+ 	int nblocks = handle->h_buffer_credits;
+-	
++
++	if (nblocks > journal->j_max_transaction_buffers) {
++		jbd_debug(1, "JBD: %s wants too many credits (%d > %d)\n",
++			  current->comm, nblocks,
++			  journal->j_max_transaction_buffers);
++		return -ENOSPC;
++	}
++
+ 	jbd_debug(3, "New handle %p going live.\n", handle);
+ 
+ repeat:
+@@ -202,6 +210,20 @@
+ 	return 0;
+ }
+ 
++/* Allocate a new handle.  This should probably be in a slab... */
++static handle_t *new_handle(int nblocks)
++{
++	handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++	if (!handle)
++		return NULL;
++	memset(handle, 0, sizeof (handle_t));
++	handle->h_buffer_credits = nblocks;
++	handle->h_ref = 1;
++	INIT_LIST_HEAD(&handle->h_jcb);
++
++	return handle;
++}
++
+ /*
+  * Obtain a new handle.  
+  *
+@@ -228,14 +250,11 @@
+ 		handle->h_ref++;
+ 		return handle;
+ 	}
+-	
+-	handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++
++	handle = new_handle(nblocks);
+ 	if (!handle)
+ 		return ERR_PTR(-ENOMEM);
+-	memset (handle, 0, sizeof (handle_t));
+ 
+-	handle->h_buffer_credits = nblocks;
+-	handle->h_ref = 1;
+ 	current->journal_info = handle;
+ 
+ 	err = start_this_handle(journal, handle);
+@@ -334,14 +353,11 @@
+ 	
+ 	if (is_journal_aborted(journal))
+ 		return ERR_PTR(-EIO);
+-	
+-	handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++
++	handle = new_handle(nblocks);
+ 	if (!handle)
+ 		return ERR_PTR(-ENOMEM);
+-	memset (handle, 0, sizeof (handle_t));
+ 
+-	handle->h_buffer_credits = nblocks;
+-	handle->h_ref = 1;
+ 	current->journal_info = handle;
+ 
+ 	err = try_start_this_handle(journal, handle);
+@@ -1321,6 +1337,28 @@
+ #endif
+ 
+ /*
++ * Register a callback function for this handle.  The function will be
++ * called when the transaction that this handle is part of has been
++ * committed to disk with the original callback data struct and the
++ * error status of the journal as parameters.  There is no guarantee of
++ * ordering between handles within a single transaction, nor between
++ * callbacks registered on the same handle.
++ *
++ * The caller is responsible for allocating the journal_callback struct.
++ * This is to allow the caller to add as much extra data to the callback
++ * as needed, but reduce the overhead of multiple allocations.  The caller
++ * allocated struct must start with a struct journal_callback at offset 0,
++ * and has the caller-specific data afterwards.
++ */
++void journal_callback_set(handle_t *handle,
++			  void (*func)(struct journal_callback *jcb, int error),
++			  struct journal_callback *jcb)
++{
++	list_add_tail(&jcb->jcb_list, &handle->h_jcb);
++	jcb->jcb_func = func;
++}
++
++/*
+  * All done for a particular handle.
+  *
+  * There is not much action needed here.  We just return any remaining
+@@ -1385,7 +1423,10 @@
+ 			wake_up(&journal->j_wait_transaction_locked);
+ 	}
+ 
+-	/* 
++	/* Move callbacks from the handle to the transaction. */
++	list_splice(&handle->h_jcb, &transaction->t_jcb);
++
++	/*
+ 	 * If the handle is marked SYNC, we need to set another commit
+ 	 * going!  We also want to force a commit if the current
+ 	 * transaction is occupying too much of the log, or if the
diff --git a/lustre/kernel_patches/patches/jbd-2.4.19-pre1-jcberr.patch b/lustre/kernel_patches/patches/jbd-2.4.19-pre1-jcberr.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bbbf613d38093f9f3a1bc36cc56ea2dd61aace04
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-2.4.19-pre1-jcberr.patch
@@ -0,0 +1,274 @@
+Index: linux-2.4.19-pre1/include/linux/jbd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/jbd.h	2003-11-21 03:00:11.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/jbd.h	2003-11-21 03:04:47.000000000 +0300
+@@ -275,6 +275,13 @@
+ 	return bh->b_private;
+ }
+ 
++#define HAVE_JOURNAL_CALLBACK_STATUS
++struct journal_callback {
++	struct list_head jcb_list;
++	void (*jcb_func)(struct journal_callback *jcb, int error);
++	/* user data goes here */
++};
++
+ struct jbd_revoke_table_s;
+ 
+ /* The handle_t type represents a single atomic update being performed
+@@ -305,6 +312,12 @@
+ 	   operations */
+ 	int			h_err;
+ 
++	/* List of application registered callbacks for this handle.
++	 * The function(s) will be called after the transaction that
++	 * this handle is part of has been committed to disk.
++	 */
++	struct list_head	h_jcb;
++
+ 	/* Flags */
+ 	unsigned int	h_sync:		1;	/* sync-on-close */
+ 	unsigned int	h_jdata:	1;	/* force data journaling */
+@@ -424,6 +437,10 @@
+ 
+ 	/* How many handles used this transaction? */
+ 	int t_handle_count;
++
++	/* List of registered callback functions for this transaction.
++	 * Called when the transaction is committed. */
++	struct list_head	t_jcb;
+ };
+ 
+ 
+@@ -672,6 +689,9 @@
+ extern int	 journal_try_to_free_buffers(journal_t *, struct page *, int);
+ extern int	 journal_stop(handle_t *);
+ extern int	 journal_flush (journal_t *);
++extern void	 journal_callback_set(handle_t *handle,
++				      void (*fn)(struct journal_callback *,int),
++				      struct journal_callback *jcb);
+ 
+ extern void	 journal_lock_updates (journal_t *);
+ extern void	 journal_unlock_updates (journal_t *);
+Index: linux-2.4.19-pre1/fs/jbd/checkpoint.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/jbd/checkpoint.c	2003-11-21 02:53:20.000000000 +0300
++++ linux-2.4.19-pre1/fs/jbd/checkpoint.c	2003-11-21 03:04:47.000000000 +0300
+@@ -601,7 +601,8 @@
+ 	J_ASSERT (transaction->t_log_list == NULL);
+ 	J_ASSERT (transaction->t_checkpoint_list == NULL);
+ 	J_ASSERT (transaction->t_updates == 0);
+-	
++	J_ASSERT (list_empty(&transaction->t_jcb));
++
+ 	J_ASSERT (transaction->t_journal->j_committing_transaction !=
+ 					transaction);
+ 	
+Index: linux-2.4.19-pre1/fs/jbd/commit.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/jbd/commit.c	2003-11-21 02:53:20.000000000 +0300
++++ linux-2.4.19-pre1/fs/jbd/commit.c	2003-11-21 03:04:47.000000000 +0300
+@@ -480,7 +480,7 @@
+            transaction's t_log_list queue, and metadata buffers are on
+            the t_iobuf_list queue.
+ 
+-	   Wait for the transactions in reverse order.  That way we are
++	   Wait for the buffers in reverse order.  That way we are
+ 	   less likely to be woken up until all IOs have completed, and
+ 	   so we incur less scheduling load.
+ 	*/
+@@ -571,8 +571,10 @@
+ 
+ 	jbd_debug(3, "JBD: commit phase 6\n");
+ 
+-	if (is_journal_aborted(journal))
++	if (is_journal_aborted(journal)) {
++		unlock_journal(journal);
+ 		goto skip_commit;
++	}
+ 
+ 	/* Done it all: now write the commit record.  We should have
+ 	 * cleaned up our previous buffers by now, so if we are in abort
+@@ -582,9 +584,10 @@
+ 	descriptor = journal_get_descriptor_buffer(journal);
+ 	if (!descriptor) {
+ 		__journal_abort_hard(journal);
++		unlock_journal(journal);
+ 		goto skip_commit;
+ 	}
+-	
++
+ 	/* AKPM: buglet - add `i' to tmp! */
+ 	for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) {
+ 		journal_header_t *tmp =
+@@ -605,14 +608,32 @@
+ 		put_bh(bh);		/* One for getblk() */
+ 		journal_unlock_journal_head(descriptor);
+ 	}
+-	lock_journal(journal);
+ 
+ 	/* End of a transaction!  Finally, we can do checkpoint
+            processing: any buffers committed as a result of this
+            transaction can be removed from any checkpoint list it was on
+            before. */
+ 
+-skip_commit:
++skip_commit: /* The journal should be unlocked by now. */
++
++	/* Call any callbacks that had been registered for handles in this
++	 * transaction.  It is up to the callback to free any allocated
++	 * memory.
++	 */
++	if (!list_empty(&commit_transaction->t_jcb)) {
++		struct list_head *p, *n;
++		int error = is_journal_aborted(journal);
++
++		list_for_each_safe(p, n, &commit_transaction->t_jcb) {
++			struct journal_callback *jcb;
++
++			jcb = list_entry(p, struct journal_callback, jcb_list);
++			list_del(p);
++			jcb->jcb_func(jcb, error);
++		}
++	}
++
++	lock_journal(journal);
+ 
+ 	jbd_debug(3, "JBD: commit phase 7\n");
+ 
+Index: linux-2.4.19-pre1/fs/jbd/journal.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/jbd/journal.c	2003-11-21 02:53:20.000000000 +0300
++++ linux-2.4.19-pre1/fs/jbd/journal.c	2003-11-21 03:04:47.000000000 +0300
+@@ -58,6 +58,7 @@
+ #endif
+ EXPORT_SYMBOL(journal_flush);
+ EXPORT_SYMBOL(journal_revoke);
++EXPORT_SYMBOL(journal_callback_set);
+ 
+ EXPORT_SYMBOL(journal_init_dev);
+ EXPORT_SYMBOL(journal_init_inode);
+Index: linux-2.4.19-pre1/fs/jbd/transaction.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/jbd/transaction.c	2003-11-21 02:53:20.000000000 +0300
++++ linux-2.4.19-pre1/fs/jbd/transaction.c	2003-11-21 03:05:14.000000000 +0300
+@@ -57,6 +57,7 @@
+ 	transaction->t_state = T_RUNNING;
+ 	transaction->t_tid = journal->j_transaction_sequence++;
+ 	transaction->t_expires = jiffies + journal->j_commit_interval;
++	INIT_LIST_HEAD(&transaction->t_jcb);
+ 
+ 	/* Set up the commit timer for the new transaction. */
+ 	J_ASSERT (!journal->j_commit_timer_active);
+@@ -90,7 +91,14 @@
+ 	transaction_t *transaction;
+ 	int needed;
+ 	int nblocks = handle->h_buffer_credits;
+-	
++
++	if (nblocks > journal->j_max_transaction_buffers) {
++		jbd_debug(1, "JBD: %s wants too many credits (%d > %d)\n",
++			  current->comm, nblocks,
++			  journal->j_max_transaction_buffers);
++		return -ENOSPC;
++	}
++
+ 	jbd_debug(3, "New handle %p going live.\n", handle);
+ 
+ repeat:
+@@ -196,6 +204,20 @@
+ 	return 0;
+ }
+ 
++/* Allocate a new handle.  This should probably be in a slab... */
++static handle_t *new_handle(int nblocks)
++{
++	handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++	if (!handle)
++		return NULL;
++	memset(handle, 0, sizeof (handle_t));
++	handle->h_buffer_credits = nblocks;
++	handle->h_ref = 1;
++	INIT_LIST_HEAD(&handle->h_jcb);
++
++	return handle;
++}
++
+ /*
+  * Obtain a new handle.  
+  *
+@@ -222,14 +244,11 @@
+ 		handle->h_ref++;
+ 		return handle;
+ 	}
+-	
+-	handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++
++	handle = new_handle(nblocks);
+ 	if (!handle)
+ 		return ERR_PTR(-ENOMEM);
+-	memset (handle, 0, sizeof (handle_t));
+ 
+-	handle->h_buffer_credits = nblocks;
+-	handle->h_ref = 1;
+ 	current->journal_info = handle;
+ 
+ 	err = start_this_handle(journal, handle);
+@@ -328,14 +347,11 @@
+ 	
+ 	if (is_journal_aborted(journal))
+ 		return ERR_PTR(-EIO);
+-	
+-	handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS);
++
++	handle = new_handle(nblocks);
+ 	if (!handle)
+ 		return ERR_PTR(-ENOMEM);
+-	memset (handle, 0, sizeof (handle_t));
+ 
+-	handle->h_buffer_credits = nblocks;
+-	handle->h_ref = 1;
+ 	current->journal_info = handle;
+ 
+ 	err = try_start_this_handle(journal, handle);
+@@ -1324,6 +1340,28 @@
+ #endif
+ 
+ /*
++ * Register a callback function for this handle.  The function will be
++ * called when the transaction that this handle is part of has been
++ * committed to disk with the original callback data struct and the
++ * error status of the journal as parameters.  There is no guarantee of
++ * ordering between handles within a single transaction, nor between
++ * callbacks registered on the same handle.
++ *
++ * The caller is responsible for allocating the journal_callback struct.
++ * This is to allow the caller to add as much extra data to the callback
++ * as needed, but reduce the overhead of multiple allocations.  The caller
++ * allocated struct must start with a struct journal_callback at offset 0,
++ * and has the caller-specific data afterwards.
++ */
++void journal_callback_set(handle_t *handle,
++			  void (*func)(struct journal_callback *jcb, int error),
++			  struct journal_callback *jcb)
++{
++	list_add_tail(&jcb->jcb_list, &handle->h_jcb);
++	jcb->jcb_func = func;
++}
++
++/*
+  * All done for a particular handle.
+  *
+  * There is not much action needed here.  We just return any remaining
+@@ -1389,7 +1427,10 @@
+ 			wake_up(&journal->j_wait_transaction_locked);
+ 	}
+ 
+-	/* 
++	/* Move callbacks from the handle to the transaction. */
++	list_splice(&handle->h_jcb, &transaction->t_jcb);
++
++	/*
+ 	 * If the handle is marked SYNC, we need to set another commit
+ 	 * going!  We also want to force a commit if the current
+ 	 * transaction is occupying too much of the log, or if the
diff --git a/lustre/kernel_patches/patches/jbd-commit-tricks.patch b/lustre/kernel_patches/patches/jbd-commit-tricks.patch
new file mode 100644
index 0000000000000000000000000000000000000000..467c29f5289ba6c18b8d595a06cb921070cefcea
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-commit-tricks.patch
@@ -0,0 +1,132 @@
+
+--- linux-2.4.18/fs/jbd/checkpoint.c~jbd-commit-tricks	Mon Jul 28 13:52:05 2003
++++ linux-2.4.18-alexey/fs/jbd/checkpoint.c	Mon Jul 28 14:03:59 2003
+@@ -77,19 +77,23 @@ static int __try_to_free_cp_buf(struct j
+  * to wait for a checkpoint to free up some space in the log.
+  */
+ 
+-void log_wait_for_space(journal_t *journal, int nblocks)
++void log_wait_for_space(journal_t *journal)
+ {
++	int nblocks;
++
++	nblocks = jbd_space_needed(journal);
+ 	while (log_space_left(journal) < nblocks) {
+ 		if (journal->j_flags & JFS_ABORT)
+ 			return;
+ 		unlock_journal(journal);
+ 		down(&journal->j_checkpoint_sem);
+ 		lock_journal(journal);
++		nblocks = jbd_space_needed(journal);
+ 		
+ 		/* Test again, another process may have checkpointed
+ 		 * while we were waiting for the checkpoint lock */
+ 		if (log_space_left(journal) < nblocks) {
+-			log_do_checkpoint(journal, nblocks);
++			log_do_checkpoint(journal);
+ 		}
+ 		up(&journal->j_checkpoint_sem);
+ 	}
+@@ -260,8 +264,7 @@ static int __flush_buffer(journal_t *jou
+  * The journal should be locked before calling this function.
+  */
+ 
+-/* @@@ `nblocks' is unused.  Should it be used? */
+-int log_do_checkpoint (journal_t *journal, int nblocks)
++int log_do_checkpoint (journal_t *journal)
+ {
+ 	transaction_t *transaction, *last_transaction, *next_transaction;
+ 	int result;
+@@ -315,6 +318,8 @@ repeat:
+ 			retry = __flush_buffer(journal, jh, bhs, &batch_count,
+ 						&drop_count);
+ 		} while (jh != last_jh && !retry);
++		if (journal->j_checkpoint_transactions != transaction)
++			goto done;
+ 		if (batch_count) {
+ 			__flush_batch(bhs, &batch_count);
+ 			goto repeat;
+@@ -328,6 +333,8 @@ repeat:
+ 		 */
+ 		cleanup_ret = __cleanup_transaction(journal, transaction);
+ 		J_ASSERT(drop_count != 0 || cleanup_ret != 0);
++		if (journal->j_checkpoint_transactions != transaction)
++			goto done;
+ 		goto repeat;	/* __cleanup may have dropped lock */
+ 	} while (transaction != last_transaction);
+ 
+--- linux-2.4.18/fs/jbd/journal.c~jbd-commit-tricks	Mon Jul 28 13:52:05 2003
++++ linux-2.4.18-alexey/fs/jbd/journal.c	Mon Jul 28 14:03:59 2003
+@@ -1115,7 +1115,7 @@ void journal_destroy (journal_t *journal
+ 	/* Force any old transactions to disk */
+ 	lock_journal(journal);
+ 	while (journal->j_checkpoint_transactions != NULL)
+-		log_do_checkpoint(journal, 1);
++		log_do_checkpoint(journal);
+ 
+ 	J_ASSERT(journal->j_running_transaction == NULL);
+ 	J_ASSERT(journal->j_committing_transaction == NULL);
+@@ -1302,7 +1302,7 @@ int journal_flush (journal_t *journal)
+ 	/* ...and flush everything in the log out to disk. */
+ 	lock_journal(journal);
+ 	while (!err && journal->j_checkpoint_transactions != NULL)
+-		err = log_do_checkpoint(journal, journal->j_maxlen);
++		err = log_do_checkpoint(journal);
+ 	cleanup_journal_tail(journal);
+ 
+ 	/* Finally, mark the journal as really needing no recovery.
+--- linux-2.4.18/fs/jbd/transaction.c~jbd-commit-tricks	Mon Jul 28 13:52:05 2003
++++ linux-2.4.18-alexey/fs/jbd/transaction.c	Mon Jul 28 14:03:59 2003
+@@ -182,14 +182,9 @@ repeat_locked:
+ 	 * Also, this test is inconsitent with the matching one in
+ 	 * journal_extend().
+ 	 */
+-	needed = journal->j_max_transaction_buffers;
+-	if (journal->j_committing_transaction) 
+-		needed += journal->j_committing_transaction->
+-					t_outstanding_credits;
+-	
+-	if (log_space_left(journal) < needed) {
++	if (log_space_left(journal) < jbd_space_needed(journal)) {
+ 		jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
+-		log_wait_for_space(journal, needed);
++		log_wait_for_space(journal);
+ 		goto repeat_locked;
+ 	}
+ 
+--- linux-2.4.18/include/linux/jbd.h~jbd-commit-tricks	Mon Jul 28 13:52:17 2003
++++ linux-2.4.18-alexey/include/linux/jbd.h	Mon Jul 28 14:03:59 2003
+@@ -740,9 +740,9 @@ extern void	   journal_brelse_array(stru
+ extern int	log_space_left (journal_t *); /* Called with journal locked */
+ extern tid_t	log_start_commit (journal_t *, transaction_t *);
+ extern void	log_wait_commit (journal_t *, tid_t);
+-extern int	log_do_checkpoint (journal_t *, int);
++extern int	log_do_checkpoint (journal_t *);
+ 
+-extern void	log_wait_for_space(journal_t *, int nblocks);
++extern void	log_wait_for_space(journal_t *);
+ extern void	__journal_drop_transaction(journal_t *, transaction_t *);
+ extern int	cleanup_journal_tail(journal_t *);
+ 
+@@ -815,6 +815,19 @@ static inline int tid_geq(tid_t x, tid_t
+ }
+ 
+ extern int journal_blocks_per_page(struct inode *inode);
++
++/*
++ * Return the minimum number of blocks which must be free in the journal
++ * before a new transaction may be started.  Must be called under j_state_lock.
++ */
++static inline int jbd_space_needed(journal_t *journal)
++{
++	int nblocks = journal->j_max_transaction_buffers;
++	if (journal->j_committing_transaction)
++		nblocks += journal->j_committing_transaction->
++			t_outstanding_credits;
++	return nblocks;
++}
+ 
+ /*
+  * Definitions which augment the buffer_head layer
+
+_
diff --git a/lustre/kernel_patches/patches/jbd-ctx_switch.patch b/lustre/kernel_patches/patches/jbd-ctx_switch.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8d4607f2368fc62f08b55f8738a12c68ee48018e
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-ctx_switch.patch
@@ -0,0 +1,13 @@
+diff -rup linux-2.4.20-uml/fs/jbd/transaction.c linux-2.4.21-rc2/fs/jbd/transaction.c
+--- linux-2.4.20-uml/fs/jbd/transaction.c	Thu Nov 28 16:53:15 2002
++++ linux-2.4.21-rc2/fs/jbd/transaction.c	Fri May 16 11:00:40 2003
+@@ -666,7 +673,8 @@ repeat:
+ 			spin_unlock(&journal_datalist_lock);
+ 			unlock_journal(journal);
+ 			/* commit wakes up all shadow buffers after IO */
+-			sleep_on(&jh2bh(jh)->b_wait);
++			wait_event(jh2bh(jh)->b_wait,
++						jh->b_jlist != BJ_Shadow);
+ 			lock_journal(journal);
+ 			goto repeat;
+ 		}
diff --git a/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice.patch b/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d1be6f02bc4f8a46cc12720bf95982d40e663f52
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice.patch
@@ -0,0 +1,17 @@
+
+--- linux-2.4.18/fs/jbd/commit.c~jbd-dont-account-blocks-twice	Mon Jul 28 13:52:05 2003
++++ linux-2.4.18-alexey/fs/jbd/commit.c	Mon Jul 28 14:03:53 2003
+@@ -407,6 +407,11 @@ sync_datalist_empty:
+ 			continue;
+ 		}
+ 
++		/* start_this_handle() accounts t_outstanding_credits
++		 * to know free space in log, but this counter is changed
++		 * by journal_next_log_block() also. */
++		commit_transaction->t_outstanding_credits--;
++
+ 		/* Bump b_count to prevent truncate from stumbling over
+                    the shadowed buffer!  @@@ This can go if we ever get
+                    rid of the BJ_IO/BJ_Shadow pairing of buffers. */
+
+_
diff --git a/lustre/kernel_patches/patches/jbd-flushtime-2.4.19-suse.patch b/lustre/kernel_patches/patches/jbd-flushtime-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8411137fdd12fa0342b4d8bf160a780ca6a99eda
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-flushtime-2.4.19-suse.patch
@@ -0,0 +1,35 @@
+Index: linux-2.4.19.SuSE/fs/jbd/transaction.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/jbd/transaction.c	Sun Nov 16 01:38:25 2003
++++ linux-2.4.19.SuSE/fs/jbd/transaction.c	Sun Nov 16 01:44:26 2003
+@@ -1094,7 +1094,6 @@
+ 	
+ 	spin_lock(&journal_datalist_lock);
+ 	set_bit(BH_JBDDirty, &bh->b_state);
+-	set_buffer_flushtime(bh);
+ 
+ 	J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ 	
+@@ -1995,6 +1994,13 @@
+ 	spin_unlock(&journal_datalist_lock);
+ }
+ 
++static void jbd_refile_buffer(struct buffer_head *bh)
++{
++	if (buffer_dirty(bh) && (bh->b_list != BUF_DIRTY))
++		set_buffer_flushtime(bh);
++	refile_buffer(bh);
++}
++
+ /* 
+  * Remove a buffer from its current buffer list in preparation for
+  * dropping it from its current transaction entirely.  If the buffer has
+@@ -2022,7 +2028,7 @@
+ 		J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
+ 	} else {
+ 		/* Onto BUF_DIRTY for writeback */
+-		refile_buffer(jh2bh(jh));
++		jbd_refile_buffer(jh2bh(jh));
+ 	}
+ }
+ 
diff --git a/lustre/kernel_patches/patches/jbd-flushtime.patch b/lustre/kernel_patches/patches/jbd-flushtime.patch
new file mode 100644
index 0000000000000000000000000000000000000000..938c14286aed069d431ef7396edccdb7863f77bd
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-flushtime.patch
@@ -0,0 +1,34 @@
+diff -rup linux-2.4.20-uml/fs/jbd/transaction.c linux-2.4.21-rc2/fs/jbd/transaction.c
+--- linux-2.4.20-uml/fs/jbd/transaction.c	Thu Nov 28 16:53:15 2002
++++ linux-2.4.21-rc2/fs/jbd/transaction.c	Fri May 16 11:00:40 2003
+@@ -1109,7 +1142,6 @@ int journal_dirty_metadata (handle_t *ha
+ 	
+ 	spin_lock(&journal_datalist_lock);
+ 	set_bit(BH_JBDDirty, &bh->b_state);
+-	set_buffer_flushtime(bh);
+ 
+ 	J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ 	
+@@ -2035,6 +2093,13 @@ void journal_file_buffer(struct journal_
+ 	spin_unlock(&journal_datalist_lock);
+ }
+ 
++static void jbd_refile_buffer(struct buffer_head *bh)
++{
++	if (buffer_dirty(bh) && (bh->b_list != BUF_DIRTY))
++		set_buffer_flushtime(bh);
++	refile_buffer(bh);
++}
++
+ /* 
+  * Remove a buffer from its current buffer list in preparation for
+  * dropping it from its current transaction entirely.  If the buffer has
+@@ -2055,7 +2120,7 @@ void __journal_refile_buffer(struct jour
+ 		__journal_unfile_buffer(jh);
+ 		jh->b_transaction = NULL;
+ 		/* Onto BUF_DIRTY for writeback */
+-		refile_buffer(jh2bh(jh));
++		jbd_refile_buffer(jh2bh(jh));
+ 		return;
+ 	}
+ 	
diff --git a/lustre/kernel_patches/patches/jbd-get_write_access.patch b/lustre/kernel_patches/patches/jbd-get_write_access.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ea569dc145f476fbf5e99513c42d7059a1ca2f20
--- /dev/null
+++ b/lustre/kernel_patches/patches/jbd-get_write_access.patch
@@ -0,0 +1,56 @@
+diff -rup linux-2.4.20-uml/fs/jbd/transaction.c linux-2.4.21-rc2/fs/jbd/transaction.c
+--- linux-2.4.20-uml/fs/jbd/transaction.c	Thu Nov 28 16:53:15 2002
++++ linux-2.4.21-rc2/fs/jbd/transaction.c	Fri May 16 11:00:40 2003
+@@ -735,7 +743,8 @@ done_locked:
+ 		int offset;
+ 		char *source;
+ 
+-		J_ASSERT_JH(jh, buffer_uptodate(jh2bh(jh)));
++		J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)),
++			    "Possible IO failure.\n");
+ 		page = jh2bh(jh)->b_page;
+ 		offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
+ 		source = kmap(page);
+diff -rup linux-2.4.20-uml/include/linux/jbd.h linux-2.4.21-rc2/include/linux/jbd.h
+--- linux-2.4.20-uml/include/linux/jbd.h	Mon Aug 25 16:16:57 2003
++++ linux-2.4.21-rc2/include/linux/jbd.h	Tue May 13 13:28:29 2003
+@@ -40,6 +40,15 @@
+  */
+ #undef JBD_PARANOID_WRITES
+ 
++/*
++ * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
++ * certain classes of error which can occur due to failed IOs.  Under
++ * normal use we want ext3 to continue after such errors, because
++ * hardware _can_ fail, but for debugging purposes when running tests on
++ * known-good hardware we may want to trap these errors.
++ */
++#undef JBD_PARANOID_IOFAIL
++
+ #ifdef CONFIG_JBD_DEBUG
+ /*
+  * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+@@ -232,6 +272,23 @@ void buffer_assertion_failure(struct buf
+ #define J_ASSERT(assert)	do { } while (0)
+ #endif		/* JBD_ASSERTIONS */
+ 
++#if defined(JBD_PARANOID_IOFAIL)
++#define J_EXPECT(expr, why...)		J_ASSERT(expr)
++#define J_EXPECT_BH(bh, expr, why...)	J_ASSERT_BH(bh, expr)
++#define J_EXPECT_JH(jh, expr, why...)	J_ASSERT_JH(jh, expr)
++#else
++#define __journal_expect(expr, why...)					     \
++	do {								     \
++		if (!(expr)) {						     \
++			printk(KERN_ERR "EXT3-fs unexpected failure: %s;\n", # expr); \
++			printk(KERN_ERR why);				     \
++		}							     \
++	} while (0)
++#define J_EXPECT(expr, why...)		__journal_expect(expr, ## why)
++#define J_EXPECT_BH(bh, expr, why...)	__journal_expect(expr, ## why)
++#define J_EXPECT_JH(jh, expr, why...)	__journal_expect(expr, ## why)
++#endif
++
+ enum jbd_state_bits {
+ 	BH_JWrite
+ 	  = BH_PrivateStart,	/* 1 if being written to log (@@@ DEBUGGING) */
diff --git a/lustre/kernel_patches/patches/kdev-2.4.19-pre1.patch b/lustre/kernel_patches/patches/kdev-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5499df3a8d1adb9c3e784af4f56a1dde37dfe5be
--- /dev/null
+++ b/lustre/kernel_patches/patches/kdev-2.4.19-pre1.patch
@@ -0,0 +1,12 @@
+Index: linux-2.4.19-pre1/include/linux/kdev_t.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/kdev_t.h	2003-11-20 19:01:38.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/kdev_t.h	2003-11-21 04:02:03.000000000 +0300
+@@ -82,6 +82,7 @@
+ #define minor(d) MINOR(d)
+ #define kdev_same(a,b) (a==b)
+ #define kdev_none(d) (!(d))
++#define val_to_kdev(d)  ((kdev_t)(d))
+ 
+ /*
+ As long as device numbers in the outside world have 16 bits only,
diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.4.19-pre1.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..df37f7a81aeb31fea95a65285f13510ccf9bde90
--- /dev/null
+++ b/lustre/kernel_patches/patches/kernel_text_address-2.4.19-pre1.patch
@@ -0,0 +1,58 @@
+Index: linux-2.4.19-pre1/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/i386/kernel/traps.c	2001-09-30 23:26:08.000000000 +0400
++++ linux-2.4.19-pre1/arch/i386/kernel/traps.c	2003-11-21 02:31:28.000000000 +0300
+@@ -961,3 +961,40 @@
+ 	cobalt_init();
+ #endif
+ }
++#ifdef CONFIG_MODULES
++extern struct module *module_list;
++extern struct module kernel_module;
++#endif
++
++int is_kernel_text_address(unsigned long addr)
++{
++       int retval = 0;
++#ifdef CONFIG_MODULES
++       struct module *mod;
++#endif
++       if (addr >= (unsigned long) &_stext &&
++           addr <= (unsigned long) &_etext);
++               return 1;
++
++#ifdef CONFIG_MODULES
++       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
++               /* mod_bound tests for addr being inside the vmalloc'ed
++                * module area. Of course it'd be better to test only
++                * for the .text subset... */
++               if (mod_bound(addr, 0, mod)) {
++                       retval = 1;
++                       break;
++               }
++       }
++#endif
++
++       return retval;
++}
++
++int lookup_symbol(unsigned long address, char *buf, int buflen)
++{
++       return -ENOSYS;
++}
++
++EXPORT_SYMBOL_GPL(is_kernel_text_address);
++EXPORT_SYMBOL_GPL(lookup_symbol);
+Index: linux-2.4.19-pre1/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/i386/kernel/Makefile	2001-11-10 01:21:21.000000000 +0300
++++ linux-2.4.19-pre1/arch/i386/kernel/Makefile	2003-11-21 02:31:46.000000000 +0300
+@@ -14,7 +14,7 @@
+ 
+ O_TARGET := kernel.o
+ 
+-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o
++export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o traps.o
+ 
+ obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+ 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.4.20-rh.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6e78be1c21ea165a4f86b8c0eaa9326c3d3e0524
--- /dev/null
+++ b/lustre/kernel_patches/patches/kernel_text_address-2.4.20-rh.patch
@@ -0,0 +1,68 @@
+Index: linux-2.4.20-20.9/kernel/kksymoops.c
+===================================================================
+--- linux-2.4.20-20.9.orig/kernel/kksymoops.c	2003-08-18 23:16:51.000000000 +0800
++++ linux-2.4.20-20.9/kernel/kksymoops.c	2003-11-06 18:38:12.000000000 +0800
+@@ -80,3 +80,5 @@
+ 	printk("%s\n",modlist);
+ #endif
+ }
++
++EXPORT_SYMBOL(lookup_symbol);
+Index: linux-2.4.20-20.9/kernel/Makefile
+===================================================================
+--- linux-2.4.20-20.9.orig/kernel/Makefile	2003-11-06 18:35:56.000000000 +0800
++++ linux-2.4.20-20.9/kernel/Makefile	2003-11-06 18:42:57.000000000 +0800
+@@ -9,7 +9,7 @@
+ 
+ O_TARGET := kernel.o
+ 
+-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o cpufreq.o profile.o
++export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o cpufreq.o profile.o kksymoops.o
+ 
+ obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o lowlat.o profile.o \
+ 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
+Index: linux-2.4.20-20.9/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.4.20-20.9.orig/arch/i386/kernel/traps.c	2003-11-06 18:35:56.000000000 +0800
++++ linux-2.4.20-20.9/arch/i386/kernel/traps.c	2003-11-06 18:43:26.000000000 +0800
+@@ -1027,9 +1019,39 @@
+ #endif
+ }
+ 
++#ifdef CONFIG_MODULES
++extern struct module *module_list;
++extern struct module kernel_module;
++#endif
++
++int is_kernel_text_address(unsigned long addr)
++{
++       int retval = 0;
++#ifdef CONFIG_MODULES
++       struct module *mod;
++#endif
++       if (addr >= (unsigned long) &_stext &&
++           addr <= (unsigned long) &_etext);
++               return 1;
++
++#ifdef CONFIG_MODULES
++       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
++               /* mod_bound tests for addr being inside the vmalloc'ed
++                * module area. Of course it'd be better to test only
++                * for the .text subset... */
++               if (mod_bound(addr, 0, mod)) {
++                       retval = 1;
++                       break;
++               }
++       }
++#endif
++
++       return retval;
++}
++
+ EXPORT_SYMBOL_GPL(netdump_func);
+ EXPORT_SYMBOL_GPL(netdump_mode);
+ #if CONFIG_X86_LOCAL_APIC
+ EXPORT_SYMBOL_GPL(nmi_watchdog);
+ #endif
+-
++EXPORT_SYMBOL_GPL(is_kernel_text_address);
diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.4.20-vanilla.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.20-vanilla.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1fe56e16c4712ea7adc05f09aced694870732c98
--- /dev/null
+++ b/lustre/kernel_patches/patches/kernel_text_address-2.4.20-vanilla.patch
@@ -0,0 +1,116 @@
+Index: linux-2.4.20-uml/arch/um/kernel/Makefile
+===================================================================
+--- linux-2.4.20-uml.orig/arch/um/kernel/Makefile	2003-11-10 13:42:48.000000000 +0800
++++ linux-2.4.20-uml/arch/um/kernel/Makefile	2003-11-10 13:43:06.000000000 +0800
+@@ -37,7 +37,8 @@
+ export-objs-$(CONFIG_GPROF) += gprof_syms.o
+ export-objs-$(CONFIG_GCOV) += gmon_syms.o
+ 
+-export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
++export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o sysrq.o \
++	$(export-objs-y)
+ 
+ CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
+ 	-I/usr/include -I../include
+Index: linux-2.4.20-uml/arch/um/kernel/sysrq.c
+===================================================================
+--- linux-2.4.20-uml.orig/arch/um/kernel/sysrq.c	2003-11-10 13:42:49.000000000 +0800
++++ linux-2.4.20-uml/arch/um/kernel/sysrq.c	2003-11-10 13:43:06.000000000 +0800
+@@ -86,6 +86,37 @@
+ 	show_trace((unsigned long *)esp);
+ }
+ 
++#ifdef CONFIG_MODULES
++extern struct module *module_list;
++extern struct module kernel_module;
++#endif
++
++int is_kernel_text_address(unsigned long addr)
++{
++	int retval = 0;
++#ifdef CONFIG_MODULES
++	struct module *mod;
++#endif
++	if (addr >= (unsigned long) &_stext &&
++	    addr <= (unsigned long) &_etext)
++		return 1;
++
++#ifdef CONFIG_MODULES
++	for (mod = module_list; mod != &kernel_module; mod = mod->next) {
++		/* mod_bound tests for addr being inside the vmalloc'ed
++		 * module area. Of course it'd be better to test only
++		 * for the .text subset... */
++		if (mod_bound(addr, 0, mod)) {
++			retval = 1;
++			break;
++		}
++	}
++#endif
++	return retval;
++}
++
++EXPORT_SYMBOL(is_kernel_text_address);
++
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+Index: linux-2.4.20-uml/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.4.20-uml.orig/arch/i386/kernel/Makefile	2002-11-29 07:53:09.000000000 +0800
++++ linux-2.4.20-uml/arch/i386/kernel/Makefile	2003-11-10 14:39:28.000000000 +0800
+@@ -14,7 +14,8 @@
+ 
+ O_TARGET := kernel.o
+ 
+-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o
++export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o \
++			traps.o
+ 
+ obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+ 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
+Index: linux-2.4.20-uml/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.4.20-uml.orig/arch/i386/kernel/traps.c	2002-11-29 07:53:09.000000000 +0800
++++ linux-2.4.20-uml/arch/i386/kernel/traps.c	2003-11-10 14:53:53.000000000 +0800
+@@ -1004,3 +1004,41 @@
+ 	cobalt_init();
+ #endif
+ }
++
++#ifdef CONFIG_MODULES
++extern struct module *module_list;
++extern struct module kernel_module;
++#endif
++                                                                                
++int is_kernel_text_address(unsigned long addr)
++{
++       int retval = 0;
++#ifdef CONFIG_MODULES
++       struct module *mod;
++#endif
++       if (addr >= (unsigned long) &_stext &&
++           addr <= (unsigned long) &_etext);
++               return 1;
++                                                                                
++#ifdef CONFIG_MODULES
++       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
++               /* mod_bound tests for addr being inside the vmalloc'ed
++                * module area. Of course it'd be better to test only
++                * for the .text subset... */
++               if (mod_bound(addr, 0, mod)) {
++                       retval = 1;
++                       break;
++               }
++       }
++#endif
++                                                                                
++       return retval;
++}
++
++int lookup_symbol(unsigned long address, char *buf, int buflen)
++{
++	return -ENOSYS;
++}
++
++EXPORT_SYMBOL_GPL(is_kernel_text_address);
++EXPORT_SYMBOL_GPL(lookup_symbol);
diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.4.22-vanilla.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.22-vanilla.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6e9cd932685a7c1c9fbc1f522b556c82b61b4034
--- /dev/null
+++ b/lustre/kernel_patches/patches/kernel_text_address-2.4.22-vanilla.patch
@@ -0,0 +1,59 @@
+Index: linux-2.4.22-vanilla/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/i386/kernel/traps.c	2003-05-16 05:28:59.000000000 +0400
++++ linux-2.4.22-vanilla/arch/i386/kernel/traps.c	2003-11-14 00:35:36.000000000 +0300
+@@ -1004,3 +1004,40 @@
+ 	cobalt_init();
+ #endif
+ }
++#ifdef CONFIG_MODULES
++extern struct module *module_list;
++extern struct module kernel_module;
++#endif
++
++int is_kernel_text_address(unsigned long addr)
++{
++       int retval = 0;
++#ifdef CONFIG_MODULES
++       struct module *mod;
++#endif
++       if (addr >= (unsigned long) &_stext &&
++           addr <= (unsigned long) &_etext);
++               return 1;
++
++#ifdef CONFIG_MODULES
++       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
++               /* mod_bound tests for addr being inside the vmalloc'ed
++                * module area. Of course it'd be better to test only
++                * for the .text subset... */
++               if (mod_bound(addr, 0, mod)) {
++                       retval = 1;
++                       break;
++               }
++       }
++#endif
++
++       return retval;
++}
++
++int lookup_symbol(unsigned long address, char *buf, int buflen)
++{
++       return -ENOSYS;
++}
++
++EXPORT_SYMBOL_GPL(is_kernel_text_address);
++EXPORT_SYMBOL_GPL(lookup_symbol);
+Index: linux-2.4.22-vanilla/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/i386/kernel/Makefile	2003-11-03 23:22:06.000000000 +0300
++++ linux-2.4.22-vanilla/arch/i386/kernel/Makefile	2003-11-14 00:30:28.000000000 +0300
+@@ -14,7 +14,8 @@
+ 
+ O_TARGET := kernel.o
+ 
+-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o setup.o
++export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o \
++			setup.o traps.o
+ 
+ obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+ 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
diff --git a/lustre/kernel_patches/patches/kexec-2.6.0-full.patch b/lustre/kernel_patches/patches/kexec-2.6.0-full.patch
index 7e2ee63c297d17fbf82c013b6838af16ba46941e..d8a1e095067a00f0a31b5f8de971cddfec26ce23 100644
--- a/lustre/kernel_patches/patches/kexec-2.6.0-full.patch
+++ b/lustre/kernel_patches/patches/kexec-2.6.0-full.patch
@@ -1,29 +1,7 @@
- MAINTAINERS                        |   11 
- arch/i386/Kconfig                  |   17 +
- arch/i386/defconfig                |    1 
- arch/i386/kernel/Makefile          |    1 
- arch/i386/kernel/apic.c            |   54 +++
- arch/i386/kernel/dmi_scan.c        |   27 -
- arch/i386/kernel/entry.S           |    1 
- arch/i386/kernel/i8259.c           |   12 
- arch/i386/kernel/io_apic.c         |    2 
- arch/i386/kernel/machine_kexec.c   |  116 ++++++
- arch/i386/kernel/reboot.c          |   44 --
- arch/i386/kernel/relocate_kernel.S |  107 ++++++
- arch/i386/kernel/smp.c             |   24 +
- include/asm-i386/apic.h            |    3 
- include/asm-i386/apicdef.h         |    1 
- include/asm-i386/kexec.h           |   23 +
- include/asm-i386/unistd.h          |    5 
- include/linux/kexec.h              |   54 +++
- include/linux/reboot.h             |    2 
- kernel/Makefile                    |    1 
- kernel/kexec.c                     |  629 +++++++++++++++++++++++++++++++++++++
- kernel/sys.c                       |   23 +
- 22 files changed, 1089 insertions(+), 69 deletions(-)
+ 0 files changed
 
---- linux-2.6.0-test1/MAINTAINERS~kexec-2.6.0-full	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/MAINTAINERS	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/MAINTAINERS~kexec-2.6.0-full	2003-07-23 12:08:43.000000000 +0800
++++ linux-2.6.0-test1-root/MAINTAINERS	2003-07-23 12:08:54.000000000 +0800
 @@ -1095,6 +1095,17 @@ W:	http://nfs.sourceforge.net/
  W:	http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
  S:	Maintained
@@ -42,8 +20,8 @@
  LANMEDIA WAN CARD DRIVER
  P:	Andrew Stanley-Jones
  M:	asj@lanmedia.com
---- linux-2.6.0-test1/arch/i386/Kconfig~kexec-2.6.0-full	2003-07-22 00:52:14.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/Kconfig	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/Kconfig~kexec-2.6.0-full	2003-07-23 12:08:52.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/Kconfig	2003-07-23 12:08:54.000000000 +0800
 @@ -804,6 +804,23 @@ config BOOT_IOREMAP
  	depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA)
  	default y
@@ -68,8 +46,8 @@
  endmenu
  
  
---- linux-2.6.0-test1/arch/i386/defconfig~kexec-2.6.0-full	2003-07-13 21:35:57.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/defconfig	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/defconfig~kexec-2.6.0-full	2003-07-14 11:35:57.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/defconfig	2003-07-23 12:08:54.000000000 +0800
 @@ -72,6 +72,7 @@ CONFIG_SMP=y
  CONFIG_X86_LOCAL_APIC=y
  CONFIG_X86_IO_APIC=y
@@ -78,8 +56,8 @@
  CONFIG_X86_MCE=y
  # CONFIG_X86_MCE_NONFATAL is not set
  CONFIG_X86_MCE_P4THERMAL=y
---- linux-2.6.0-test1/arch/i386/kernel/Makefile~kexec-2.6.0-full	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/Makefile	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/Makefile~kexec-2.6.0-full	2003-07-23 12:08:31.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/Makefile	2003-07-23 12:08:54.000000000 +0800
 @@ -25,6 +25,7 @@ obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoli
  obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
  obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
@@ -88,8 +66,8 @@
  obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend.o suspend_asm.o
  obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
  obj-$(CONFIG_X86_SUMMIT)	+= summit.o
---- linux-2.6.0-test1/arch/i386/kernel/apic.c~kexec-2.6.0-full	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/apic.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/apic.c~kexec-2.6.0-full	2003-07-23 12:08:30.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/apic.c	2003-07-23 12:08:54.000000000 +0800
 @@ -26,6 +26,7 @@
  #include <linux/mc146818rtc.h>
  #include <linux/kernel_stat.h>
@@ -165,8 +143,8 @@
  /*
   * This initializes the IO-APIC and APIC hardware if this is
   * a UP kernel.
---- linux-2.6.0-test1/arch/i386/kernel/dmi_scan.c~kexec-2.6.0-full	2003-07-13 21:32:44.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/dmi_scan.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/dmi_scan.c~kexec-2.6.0-full	2003-07-14 11:32:44.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/dmi_scan.c	2003-07-23 12:08:54.000000000 +0800
 @@ -222,31 +222,6 @@ static __init int set_bios_reboot(struct
  	return 0;
  }
@@ -208,8 +186,8 @@
  			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
  			MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
  			NO_MATCH, NO_MATCH
---- linux-2.6.0-test1/arch/i386/kernel/entry.S~kexec-2.6.0-full	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/entry.S	2003-07-22 00:54:27.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/entry.S~kexec-2.6.0-full	2003-07-23 12:08:30.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/entry.S	2003-07-23 12:08:54.000000000 +0800
 @@ -905,5 +905,6 @@ ENTRY(sys_call_table)
  	.long sys_tgkill	/* 270 */
  	.long sys_utimes
@@ -217,8 +195,8 @@
 +        .long sys_kexec_load
  
  nr_syscalls=(.-sys_call_table)/4
---- linux-2.6.0-test1/arch/i386/kernel/i8259.c~kexec-2.6.0-full	2003-07-13 21:38:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/i8259.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/i8259.c~kexec-2.6.0-full	2003-07-14 11:38:03.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/i8259.c	2003-07-23 12:08:54.000000000 +0800
 @@ -244,9 +244,21 @@ static int i8259A_resume(struct sys_devi
  	return 0;
  }
@@ -241,8 +219,8 @@
  };
  
  static struct sys_device device_i8259A = {
---- linux-2.6.0-test1/arch/i386/kernel/io_apic.c~kexec-2.6.0-full	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/io_apic.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/io_apic.c~kexec-2.6.0-full	2003-07-23 12:08:30.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/io_apic.c	2003-07-23 12:08:54.000000000 +0800
 @@ -1601,8 +1601,6 @@ void disable_IO_APIC(void)
  	 * Clear the IO-APIC before rebooting:
  	 */
@@ -252,8 +230,8 @@
  }
  
  /*
---- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/machine_kexec.c	2003-07-22 00:54:04.000000000 -0600
+--- /dev/null	2002-08-31 07:31:37.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/machine_kexec.c	2003-07-23 12:08:54.000000000 +0800
 @@ -0,0 +1,116 @@
 +#include <linux/config.h>
 +#include <linux/mm.h>
@@ -371,8 +349,8 @@
 +	rnk = (relocate_new_kernel_t) reboot_code_buffer;
 +	(*rnk)(indirection_page, reboot_code_buffer, image->start);
 +}
---- linux-2.6.0-test1/arch/i386/kernel/reboot.c~kexec-2.6.0-full	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/reboot.c	2003-07-22 00:55:22.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/reboot.c~kexec-2.6.0-full	2003-07-23 12:08:31.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/reboot.c	2003-07-23 12:08:54.000000000 +0800
 @@ -8,6 +8,7 @@
  #include <linux/interrupt.h>
  #include <linux/mc146818rtc.h>
@@ -456,8 +434,8 @@
  	if (pm_power_off)
  		pm_power_off();
  }
---- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/relocate_kernel.S	2003-07-22 00:54:04.000000000 -0600
+--- /dev/null	2002-08-31 07:31:37.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/relocate_kernel.S	2003-07-23 12:08:54.000000000 +0800
 @@ -0,0 +1,107 @@
 +#include <linux/config.h>
 +#include <linux/linkage.h>
@@ -566,15 +544,15 @@
 +	.globl relocate_new_kernel_size
 +relocate_new_kernel_size:	
 +	.long relocate_new_kernel_end - relocate_new_kernel
---- linux-2.6.0-test1/arch/i386/kernel/smp.c~kexec-2.6.0-full	2003-07-22 00:52:14.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/smp.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/arch/i386/kernel/smp.c~kexec-2.6.0-full	2003-07-23 12:08:52.000000000 +0800
++++ linux-2.6.0-test1-root/arch/i386/kernel/smp.c	2003-07-23 12:53:45.000000000 +0800
 @@ -587,6 +587,30 @@ void stop_this_cpu (void * dummy)
  
  void smp_send_stop(void)
  {
 + 	extern int reboot_cpu;
 +	int reboot_cpu_id;
-+
++	
 + 	/* The boot cpu is always logical cpu 0 */
 +	reboot_cpu_id = 0;
 +
@@ -591,7 +569,7 @@
 +	}
 +
 +	/* Make certain I only run on the appropriate processor */
-+	set_cpus_allowed(current, 1 << reboot_cpu_id);
++	set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
 +
 +	/* O.k. Now that I'm on the appropriate processor stop
 +	 * all of the others.
@@ -599,8 +577,8 @@
  	smp_call_function(stop_this_cpu, NULL, 1, 0);
  
  	local_irq_disable();
---- linux-2.6.0-test1/include/asm-i386/apic.h~kexec-2.6.0-full	2003-07-13 21:38:53.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/apic.h	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/include/asm-i386/apic.h~kexec-2.6.0-full	2003-07-14 11:38:53.000000000 +0800
++++ linux-2.6.0-test1-root/include/asm-i386/apic.h	2003-07-23 12:08:54.000000000 +0800
 @@ -97,6 +97,9 @@ extern unsigned int nmi_watchdog;
  #define NMI_LOCAL_APIC	2
  #define NMI_INVALID	3
@@ -611,8 +589,8 @@
  #endif /* CONFIG_X86_LOCAL_APIC */
  
  #endif /* __ASM_APIC_H */
---- linux-2.6.0-test1/include/asm-i386/apicdef.h~kexec-2.6.0-full	2003-07-13 21:34:40.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/apicdef.h	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/include/asm-i386/apicdef.h~kexec-2.6.0-full	2003-07-14 11:34:40.000000000 +0800
++++ linux-2.6.0-test1-root/include/asm-i386/apicdef.h	2003-07-23 12:08:54.000000000 +0800
 @@ -86,6 +86,7 @@
  #define			APIC_LVT_REMOTE_IRR		(1<<14)
  #define			APIC_INPUT_POLARITY		(1<<13)
@@ -621,8 +599,8 @@
  #define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
  #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
  #define				APIC_MODE_FIXED		0x0
---- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/include/asm-i386/kexec.h	2003-07-22 00:54:04.000000000 -0600
+--- /dev/null	2002-08-31 07:31:37.000000000 +0800
++++ linux-2.6.0-test1-root/include/asm-i386/kexec.h	2003-07-23 12:08:54.000000000 +0800
 @@ -0,0 +1,23 @@
 +#ifndef _I386_KEXEC_H
 +#define _I386_KEXEC_H
@@ -647,8 +625,8 @@
 +#define KEXEC_REBOOT_CODE_SIZE	4096
 +
 +#endif /* _I386_KEXEC_H */
---- linux-2.6.0-test1/include/asm-i386/unistd.h~kexec-2.6.0-full	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/unistd.h	2003-07-22 00:55:57.000000000 -0600
+--- linux-2.6.0-test1/include/asm-i386/unistd.h~kexec-2.6.0-full	2003-07-23 12:08:42.000000000 +0800
++++ linux-2.6.0-test1-root/include/asm-i386/unistd.h	2003-07-23 12:08:54.000000000 +0800
 @@ -278,8 +278,9 @@
  #define __NR_tgkill		270
  #define __NR_utimes		271
@@ -661,8 +639,8 @@
  
  /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
  
---- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/include/linux/kexec.h	2003-07-22 00:54:04.000000000 -0600
+--- /dev/null	2002-08-31 07:31:37.000000000 +0800
++++ linux-2.6.0-test1-root/include/linux/kexec.h	2003-07-23 12:08:54.000000000 +0800
 @@ -0,0 +1,54 @@
 +#ifndef LINUX_KEXEC_H
 +#define LINUX_KEXEC_H
@@ -718,8 +696,8 @@
 +#endif
 +#endif /* LINUX_KEXEC_H */
 +
---- linux-2.6.0-test1/include/linux/reboot.h~kexec-2.6.0-full	2003-07-13 21:39:35.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/reboot.h	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/include/linux/reboot.h~kexec-2.6.0-full	2003-07-14 11:39:35.000000000 +0800
++++ linux-2.6.0-test1-root/include/linux/reboot.h	2003-07-23 12:08:54.000000000 +0800
 @@ -22,6 +22,7 @@
   * POWER_OFF   Stop OS and remove all power from system, if possible.
   * RESTART2    Restart system using given command string.
@@ -736,8 +714,8 @@
  
  
  #ifdef __KERNEL__
---- linux-2.6.0-test1/kernel/Makefile~kexec-2.6.0-full	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/Makefile	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/kernel/Makefile~kexec-2.6.0-full	2003-07-23 12:08:43.000000000 +0800
++++ linux-2.6.0-test1-root/kernel/Makefile	2003-07-23 12:08:54.000000000 +0800
 @@ -19,6 +19,7 @@ obj-$(CONFIG_PM) += pm.o
  obj-$(CONFIG_CPU_FREQ) += cpufreq.o
  obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
@@ -746,8 +724,8 @@
  obj-$(CONFIG_COMPAT) += compat.o
  
  ifneq ($(CONFIG_IA64),y)
---- /dev/null	2003-01-30 03:24:37.000000000 -0700
-+++ linux-2.6.0-test1-braam/kernel/kexec.c	2003-07-22 00:54:04.000000000 -0600
+--- /dev/null	2002-08-31 07:31:37.000000000 +0800
++++ linux-2.6.0-test1-root/kernel/kexec.c	2003-07-23 12:08:54.000000000 +0800
 @@ -0,0 +1,629 @@
 +#include <linux/mm.h>
 +#include <linux/file.h>
@@ -1378,8 +1356,8 @@
 +	kimage_free(image);
 +	return result;
 +}
---- linux-2.6.0-test1/kernel/sys.c~kexec-2.6.0-full	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/sys.c	2003-07-22 00:54:04.000000000 -0600
+--- linux-2.6.0-test1/kernel/sys.c~kexec-2.6.0-full	2003-07-23 12:08:43.000000000 +0800
++++ linux-2.6.0-test1-root/kernel/sys.c	2003-07-23 12:08:54.000000000 +0800
 @@ -17,6 +17,7 @@
  #include <linux/init.h>
  #include <linux/highuid.h>
diff --git a/lustre/kernel_patches/patches/kexec-2.5.73-full.patch b/lustre/kernel_patches/patches/kexec-2.6.0-test6-full.patch
similarity index 80%
rename from lustre/kernel_patches/patches/kexec-2.5.73-full.patch
rename to lustre/kernel_patches/patches/kexec-2.6.0-test6-full.patch
index 3f45a0678cd9de2b5cd9d7c75281e969edd33b0a..ea09f122d43a99dd47e639955bce7f3992773202 100644
--- a/lustre/kernel_patches/patches/kexec-2.5.73-full.patch
+++ b/lustre/kernel_patches/patches/kexec-2.6.0-test6-full.patch
@@ -1,51 +1,10 @@
-# This is a BitKeeper generated patch for the following project:
-# Project Name: Linux kernel tree
-# This patch format is intended for GNU patch command version 2.5 or higher.
-# This patch includes the following deltas:
-#	           ChangeSet	1.1376  -> 1.1380 
-#	arch/i386/kernel/smp.c	1.32    -> 1.33   
-#	        kernel/sys.c	1.47    -> 1.48   
-#	   arch/i386/Kconfig	1.62    -> 1.63   
-#	arch/i386/kernel/Makefile	1.44    -> 1.45   
-#	     kernel/Makefile	1.28    -> 1.29   
-#	arch/i386/kernel/entry.S	1.64    -> 1.65   
-#	arch/i386/kernel/reboot.c	1.8     -> 1.9    
-#	arch/i386/kernel/io_apic.c	1.71    -> 1.72   
-#	arch/i386/kernel/dmi_scan.c	1.36    -> 1.37   
-#	            fs/aio.c	1.32    -> 1.33   
-#	include/asm-i386/apicdef.h	1.8     -> 1.9    
-#	         MAINTAINERS	1.149   -> 1.150  
-#	include/asm-i386/unistd.h	1.26    -> 1.27   
-#	 arch/i386/defconfig	1.96    -> 1.97   
-#	arch/i386/kernel/i8259.c	1.25    -> 1.26   
-#	include/asm-i386/apic.h	1.13    -> 1.14   
-#	arch/i386/kernel/apic.c	1.42    -> 1.43   
-#	include/linux/reboot.h	1.4     -> 1.5    
-#	               (new)	        -> 1.1     include/linux/kexec.h
-#	               (new)	        -> 1.1     include/asm-i386/kexec.h
-#	               (new)	        -> 1.1     kernel/kexec.c 
-#	               (new)	        -> 1.1     arch/i386/kernel/relocate_kernel.S
-#	               (new)	        -> 1.1     arch/i386/kernel/machine_kexec.c
-#
-# The following is the BitKeeper ChangeSet Log
-# --------------------------------------------
-# 03/06/23	andyp@andyp.pdx.osdl.net	1.1377
-# kexec2-2.5.73-common.patch
-# --------------------------------------------
-# 03/06/23	andyp@andyp.pdx.osdl.net	1.1378
-# kexec2-2.5.73-x86.patch
-# --------------------------------------------
-# 03/06/23	andyp@andyp.pdx.osdl.net	1.1379
-# kexec2-2.5.73-syscall.patch
-# --------------------------------------------
-# 03/06/23	andyp@andyp.pdx.osdl.net	1.1380
-# kexec2-2.5.73-defconfig.patch
-# --------------------------------------------
-#
-diff -Nru a/MAINTAINERS b/MAINTAINERS
---- a/MAINTAINERS	Mon Jun 23 12:22:26 2003
-+++ b/MAINTAINERS	Mon Jun 23 12:22:26 2003
-@@ -1067,6 +1067,17 @@
+ 0 files changed
+
+Index: linux-2.6.0-test6/MAINTAINERS
+===================================================================
+--- linux-2.6.0-test6.orig/MAINTAINERS	2003-10-07 16:08:42.000000000 +0800
++++ linux-2.6.0-test6/MAINTAINERS	2003-10-07 16:09:00.000000000 +0800
+@@ -1174,6 +1174,17 @@
  W:	http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
  S:	Maintained
  
@@ -63,11 +22,12 @@ diff -Nru a/MAINTAINERS b/MAINTAINERS
  LANMEDIA WAN CARD DRIVER
  P:	Andrew Stanley-Jones
  M:	asj@lanmedia.com
-diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
---- a/arch/i386/Kconfig	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/Kconfig	Mon Jun 23 12:22:26 2003
-@@ -794,6 +794,23 @@
- 	depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA)
+Index: linux-2.6.0-test6/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/Kconfig	2003-10-07 16:08:59.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/Kconfig	2003-10-07 16:09:00.000000000 +0800
+@@ -845,6 +845,23 @@
+ # depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA)) || X86_GENERICARCH
  	default y
  
 +config KEXEC
@@ -90,31 +50,34 @@ diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
  endmenu
  
  
-diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig
---- a/arch/i386/defconfig	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/defconfig	Mon Jun 23 12:22:26 2003
-@@ -72,6 +72,7 @@
+Index: linux-2.6.0-test6/arch/i386/defconfig
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/defconfig	2003-10-07 15:47:25.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/defconfig	2003-10-07 16:09:00.000000000 +0800
+@@ -82,6 +82,7 @@
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=8
++CONFIG_KEXEC=y
+ CONFIG_PREEMPT=y
  CONFIG_X86_LOCAL_APIC=y
  CONFIG_X86_IO_APIC=y
- CONFIG_NR_CPUS=32
-+CONFIG_KEXEC=y
- CONFIG_X86_MCE=y
- # CONFIG_X86_MCE_NONFATAL is not set
- CONFIG_X86_MCE_P4THERMAL=y
-diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
---- a/arch/i386/kernel/Makefile	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/Makefile	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/Makefile	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/Makefile	2003-10-07 16:09:00.000000000 +0800
 @@ -24,6 +24,7 @@
  obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
  obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
  obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 +obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
- obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend.o suspend_asm.o
  obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
  obj-$(CONFIG_X86_SUMMIT)	+= summit.o
-diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
---- a/arch/i386/kernel/apic.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/apic.c	Mon Jun 23 12:22:26 2003
+ obj-$(CONFIG_EDD)             	+= edd.o
+Index: linux-2.6.0-test6/arch/i386/kernel/apic.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/apic.c	2003-10-07 15:47:25.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/apic.c	2003-10-07 16:09:01.000000000 +0800
 @@ -26,6 +26,7 @@
  #include <linux/mc146818rtc.h>
  #include <linux/kernel_stat.h>
@@ -123,7 +86,7 @@ diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
  
  #include <asm/atomic.h>
  #include <asm/smp.h>
-@@ -175,6 +176,39 @@
+@@ -183,6 +184,39 @@
  		outb(0x70, 0x22);
  		outb(0x00, 0x23);
  	}
@@ -163,12 +126,10 @@ diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
  }
  
  void disable_local_APIC(void)
-@@ -1113,6 +1147,26 @@
- 	printk (KERN_INFO "APIC error on CPU%d: %02lx(%02lx)\n",
- 	        smp_processor_id(), v , v1);
+@@ -1147,6 +1181,26 @@
  	irq_exit();
-+}
-+
+ }
+ 
 +void stop_apics(void)
 +{
 +	/* By resetting the APIC's we disable the nmi watchdog */
@@ -187,12 +148,15 @@ diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
 +	}
 +#endif
 +	disconnect_bsp_APIC();
- }
- 
++}
++
  /*
-diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
---- a/arch/i386/kernel/dmi_scan.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/dmi_scan.c	Mon Jun 23 12:22:26 2003
+  * This initializes the IO-APIC and APIC hardware if this is
+  * a UP kernel.
+Index: linux-2.6.0-test6/arch/i386/kernel/dmi_scan.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/dmi_scan.c	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/dmi_scan.c	2003-10-07 16:09:01.000000000 +0800
 @@ -222,31 +222,6 @@
  	return 0;
  }
@@ -225,7 +189,7 @@ diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
  
  /*
   * Some bioses have a broken protected mode poweroff and need to use realmode
-@@ -527,7 +502,7 @@
+@@ -581,7 +556,7 @@
  			MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
  			MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
  			} },
@@ -234,19 +198,22 @@ diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
  			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
  			MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
  			NO_MATCH, NO_MATCH
-diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
---- a/arch/i386/kernel/entry.S	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/entry.S	Mon Jun 23 12:22:26 2003
-@@ -876,5 +876,6 @@
-  	.long sys_clock_nanosleep
- 	.long sys_statfs64
- 	.long sys_fstatfs64	
-+	.long sys_kexec_load		/* 270 */
-  
+Index: linux-2.6.0-test6/arch/i386/kernel/entry.S
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/entry.S	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/entry.S	2003-10-07 16:09:01.000000000 +0800
+@@ -1046,6 +1046,7 @@
+ 	.long sys_utimes
+  	.long sys_fadvise64_64
+ 	.long sys_ni_syscall	/* sys_vserver */
++        .long sys_kexec_load
+ 
  nr_syscalls=(.-sys_call_table)/4
-diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
---- a/arch/i386/kernel/i8259.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/i8259.c	Mon Jun 23 12:22:26 2003
+ 
+Index: linux-2.6.0-test6/arch/i386/kernel/i8259.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/i8259.c	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/i8259.c	2003-10-07 16:09:01.000000000 +0800
 @@ -244,9 +244,21 @@
  	return 0;
  }
@@ -269,10 +236,11 @@ diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
  };
  
  static struct sys_device device_i8259A = {
-diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
---- a/arch/i386/kernel/io_apic.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/io_apic.c	Mon Jun 23 12:22:26 2003
-@@ -1562,8 +1562,6 @@
+Index: linux-2.6.0-test6/arch/i386/kernel/io_apic.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/io_apic.c	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/io_apic.c	2003-10-07 16:09:01.000000000 +0800
+@@ -1629,8 +1629,6 @@
  	 * Clear the IO-APIC before rebooting:
  	 */
  	clear_IO_APIC();
@@ -281,9 +249,10 @@ diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
  }
  
  /*
-diff -Nru a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
---- /dev/null	Wed Dec 31 16:00:00 1969
-+++ b/arch/i386/kernel/machine_kexec.c	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/machine_kexec.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/machine_kexec.c	2003-10-07 16:09:00.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/machine_kexec.c	2003-10-07 16:09:01.000000000 +0800
 @@ -0,0 +1,116 @@
 +#include <linux/config.h>
 +#include <linux/mm.h>
@@ -401,18 +370,11 @@ diff -Nru a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
 +	rnk = (relocate_new_kernel_t) reboot_code_buffer;
 +	(*rnk)(indirection_page, reboot_code_buffer, image->start);
 +}
-diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
---- a/arch/i386/kernel/reboot.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/reboot.c	Mon Jun 23 12:22:26 2003
-@@ -8,6 +8,7 @@
- #include <linux/interrupt.h>
- #include <linux/mc146818rtc.h>
- #include <asm/uaccess.h>
-+#include <asm/apic.h>
- #include "mach_reboot.h"
- 
- /*
-@@ -20,8 +21,7 @@
+Index: linux-2.6.0-test6/arch/i386/kernel/reboot.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/reboot.c	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/reboot.c	2003-10-07 16:09:01.000000000 +0800
+@@ -21,8 +21,7 @@
  int reboot_thru_bios;
  
  #ifdef CONFIG_SMP
@@ -422,7 +384,7 @@ diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
  /* shamelessly grabbed from lib/vsprintf.c for readability */
  #define is_digit(c)	((c) >= '0' && (c) <= '9')
  #endif
-@@ -43,7 +43,6 @@
+@@ -44,7 +43,6 @@
  			break;
  #ifdef CONFIG_SMP
  		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
@@ -430,7 +392,7 @@ diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
  			if (is_digit(*(str+1))) {
  				reboot_cpu = (int) (*(str+1) - '0');
  				if (is_digit(*(str+2))) 
-@@ -215,42 +214,7 @@
+@@ -217,51 +215,7 @@
  
  void machine_restart(char * __unused)
  {
@@ -445,7 +407,7 @@ diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
 -		   if its not, default to the BSP */
 -		if ((reboot_cpu == -1) ||  
 -		      (reboot_cpu > (NR_CPUS -1))  || 
--		      !(phys_cpu_present_map & (1<<cpuid))) 
+-		      !physid_isset(cpuid, phys_cpu_present_map))
 -			reboot_cpu = boot_cpu_physical_apicid;
 -
 -		reboot_smp = 0;  /* use this as a flag to only go through this once*/
@@ -468,28 +430,40 @@ diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
 -	 * other OSs see a clean IRQ state.
 -	 */
 -	smp_send_stop();
+-#elif defined(CONFIG_X86_LOCAL_APIC)
+-	if (cpu_has_apic) {
+-		local_irq_disable();
+-		disable_local_APIC();
+-		local_irq_enable();
+-	}
+-#endif
+-#ifdef CONFIG_X86_IO_APIC
 -	disable_IO_APIC();
 -#endif
-+	stop_apics();
- 
- 	if(!reboot_thru_bios) {
- 		/* rebooting needs to touch the page at absolute addr 0 */
-@@ -268,10 +232,12 @@
+-
++        stop_apics();
+ 	if (!reboot_thru_bios) {
+ 		if (efi_enabled) {
+ 			efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, 0);
+@@ -284,11 +238,13 @@
+ }
  
  void machine_halt(void)
- {
-+	stop_apics();
+-{
++{ 
++ 	stop_apics();
  }
  
  void machine_power_off(void)
  {
-+	stop_apics();
++ 	stop_apics();
+ 	if (efi_enabled)
+ 		efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, 0);
  	if (pm_power_off)
- 		pm_power_off();
- }
-diff -Nru a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S
---- /dev/null	Wed Dec 31 16:00:00 1969
-+++ b/arch/i386/kernel/relocate_kernel.S	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/relocate_kernel.S
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/relocate_kernel.S	2003-10-07 16:09:00.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/relocate_kernel.S	2003-10-07 16:09:01.000000000 +0800
 @@ -0,0 +1,107 @@
 +#include <linux/config.h>
 +#include <linux/linkage.h>
@@ -598,16 +572,17 @@ diff -Nru a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kerne
 +	.globl relocate_new_kernel_size
 +relocate_new_kernel_size:	
 +	.long relocate_new_kernel_end - relocate_new_kernel
-diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
---- a/arch/i386/kernel/smp.c	Mon Jun 23 12:22:26 2003
-+++ b/arch/i386/kernel/smp.c	Mon Jun 23 12:22:26 2003
-@@ -547,6 +547,30 @@
+Index: linux-2.6.0-test6/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/smp.c	2003-10-07 16:08:59.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/smp.c	2003-10-07 16:09:01.000000000 +0800
+@@ -577,6 +577,30 @@
  
  void smp_send_stop(void)
  {
 + 	extern int reboot_cpu;
 +	int reboot_cpu_id;
-+
++	
 + 	/* The boot cpu is always logical cpu 0 */
 +	reboot_cpu_id = 0;
 +
@@ -624,7 +599,7 @@ diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
 +	}
 +
 +	/* Make certain I only run on the appropriate processor */
-+	set_cpus_allowed(current, 1 << reboot_cpu_id);
++	set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
 +
 +	/* O.k. Now that I'm on the appropriate processor stop
 +	 * all of the others.
@@ -632,22 +607,11 @@ diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
  	smp_call_function(stop_this_cpu, NULL, 1, 0);
  
  	local_irq_disable();
-diff -Nru a/fs/aio.c b/fs/aio.c
---- a/fs/aio.c	Mon Jun 23 12:22:26 2003
-+++ b/fs/aio.c	Mon Jun 23 12:22:26 2003
-@@ -536,7 +536,7 @@
- 	return ioctx;
- }
- 
--static void use_mm(struct mm_struct *mm)
-+void use_mm(struct mm_struct *mm)
- {
- 	struct mm_struct *active_mm = current->active_mm;
- 	atomic_inc(&mm->mm_count);
-diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h
---- a/include/asm-i386/apic.h	Mon Jun 23 12:22:26 2003
-+++ b/include/asm-i386/apic.h	Mon Jun 23 12:22:26 2003
-@@ -97,6 +97,9 @@
+Index: linux-2.6.0-test6/include/asm-i386/apic.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/apic.h	2003-10-07 15:47:25.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/apic.h	2003-10-07 16:09:01.000000000 +0800
+@@ -99,6 +99,9 @@
  #define NMI_LOCAL_APIC	2
  #define NMI_INVALID	3
  
@@ -657,9 +621,10 @@ diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h
  #endif /* CONFIG_X86_LOCAL_APIC */
  
  #endif /* __ASM_APIC_H */
-diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
---- a/include/asm-i386/apicdef.h	Mon Jun 23 12:22:26 2003
-+++ b/include/asm-i386/apicdef.h	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/include/asm-i386/apicdef.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/apicdef.h	2003-10-07 15:47:25.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/apicdef.h	2003-10-07 16:09:01.000000000 +0800
 @@ -86,6 +86,7 @@
  #define			APIC_LVT_REMOTE_IRR		(1<<14)
  #define			APIC_INPUT_POLARITY		(1<<13)
@@ -668,9 +633,10 @@ diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
  #define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
  #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
  #define				APIC_MODE_FIXED		0x0
-diff -Nru a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
---- /dev/null	Wed Dec 31 16:00:00 1969
-+++ b/include/asm-i386/kexec.h	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/include/asm-i386/kexec.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/kexec.h	2003-10-07 16:09:00.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/kexec.h	2003-10-07 16:09:01.000000000 +0800
 @@ -0,0 +1,23 @@
 +#ifndef _I386_KEXEC_H
 +#define _I386_KEXEC_H
@@ -695,23 +661,26 @@ diff -Nru a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
 +#define KEXEC_REBOOT_CODE_SIZE	4096
 +
 +#endif /* _I386_KEXEC_H */
-diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
---- a/include/asm-i386/unistd.h	Mon Jun 23 12:22:26 2003
-+++ b/include/asm-i386/unistd.h	Mon Jun 23 12:22:26 2003
-@@ -275,8 +275,9 @@
- #define __NR_clock_nanosleep	(__NR_timer_create+8)
- #define __NR_statfs64		268
- #define __NR_fstatfs64		269
-+#define __NR_sys_kexec_load	270
- 
--#define NR_syscalls 270
-+#define NR_syscalls 271
+Index: linux-2.6.0-test6/include/asm-i386/unistd.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/unistd.h	2003-10-07 16:08:41.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/unistd.h	2003-10-07 16:09:01.000000000 +0800
+@@ -279,8 +279,9 @@
+ #define __NR_utimes		271
+ #define __NR_fadvise64_64	272
+ #define __NR_vserver		273
+-
+-#define NR_syscalls 274
++#define __NR_sys_kexec_load	274
++    
++#define NR_syscalls 275
  
  /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
  
-diff -Nru a/include/linux/kexec.h b/include/linux/kexec.h
---- /dev/null	Wed Dec 31 16:00:00 1969
-+++ b/include/linux/kexec.h	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/include/linux/kexec.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/kexec.h	2003-10-07 16:09:00.000000000 +0800
++++ linux-2.6.0-test6/include/linux/kexec.h	2003-10-07 16:09:01.000000000 +0800
 @@ -0,0 +1,54 @@
 +#ifndef LINUX_KEXEC_H
 +#define LINUX_KEXEC_H
@@ -767,13 +736,14 @@ diff -Nru a/include/linux/kexec.h b/include/linux/kexec.h
 +#endif
 +#endif /* LINUX_KEXEC_H */
 +
-diff -Nru a/include/linux/reboot.h b/include/linux/reboot.h
---- a/include/linux/reboot.h	Mon Jun 23 12:22:26 2003
-+++ b/include/linux/reboot.h	Mon Jun 23 12:22:26 2003
+Index: linux-2.6.0-test6/include/linux/reboot.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/reboot.h	2003-10-07 15:47:25.000000000 +0800
++++ linux-2.6.0-test6/include/linux/reboot.h	2003-10-07 16:09:01.000000000 +0800
 @@ -22,6 +22,7 @@
   * POWER_OFF   Stop OS and remove all power from system, if possible.
   * RESTART2    Restart system using given command string.
-  * SW_SUSPEND  Suspend system using Software Suspend if compiled in
+  * SW_SUSPEND  Suspend system using software suspend if compiled in.
 + * KEXEC       Restart the system using a different kernel.
   */
  
@@ -786,20 +756,22 @@ diff -Nru a/include/linux/reboot.h b/include/linux/reboot.h
  
  
  #ifdef __KERNEL__
-diff -Nru a/kernel/Makefile b/kernel/Makefile
---- a/kernel/Makefile	Mon Jun 23 12:22:26 2003
-+++ b/kernel/Makefile	Mon Jun 23 12:22:26 2003
-@@ -18,6 +18,7 @@
- obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+Index: linux-2.6.0-test6/kernel/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/Makefile	2003-10-07 16:08:42.000000000 +0800
++++ linux-2.6.0-test6/kernel/Makefile	2003-10-07 16:09:01.000000000 +0800
+@@ -17,6 +17,7 @@
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+ obj-$(CONFIG_PM) += power/
  obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
- obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
 +obj-$(CONFIG_KEXEC) += kexec.o
  obj-$(CONFIG_COMPAT) += compat.o
- 
- ifneq ($(CONFIG_IA64),y)
-diff -Nru a/kernel/kexec.c b/kernel/kexec.c
---- /dev/null	Wed Dec 31 16:00:00 1969
-+++ b/kernel/kexec.c	Mon Jun 23 12:22:26 2003
+ obj-$(CONFIG_IKCONFIG) += configs.o
+ obj-$(CONFIG_IKCONFIG_PROC) += configs.o
+Index: linux-2.6.0-test6/kernel/kexec.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/kexec.c	2003-10-07 16:09:00.000000000 +0800
++++ linux-2.6.0-test6/kernel/kexec.c	2003-10-07 16:09:01.000000000 +0800
 @@ -0,0 +1,629 @@
 +#include <linux/mm.h>
 +#include <linux/file.h>
@@ -1430,10 +1402,11 @@ diff -Nru a/kernel/kexec.c b/kernel/kexec.c
 +	kimage_free(image);
 +	return result;
 +}
-diff -Nru a/kernel/sys.c b/kernel/sys.c
---- a/kernel/sys.c	Mon Jun 23 12:22:26 2003
-+++ b/kernel/sys.c	Mon Jun 23 12:22:26 2003
-@@ -16,6 +16,7 @@
+Index: linux-2.6.0-test6/kernel/sys.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/sys.c	2003-10-07 16:08:42.000000000 +0800
++++ linux-2.6.0-test6/kernel/sys.c	2003-10-09 18:38:57.000000000 +0800
+@@ -17,6 +17,7 @@
  #include <linux/init.h>
  #include <linux/highuid.h>
  #include <linux/fs.h>
@@ -1441,7 +1414,23 @@ diff -Nru a/kernel/sys.c b/kernel/sys.c
  #include <linux/workqueue.h>
  #include <linux/device.h>
  #include <linux/times.h>
-@@ -207,6 +208,7 @@
+@@ -94,6 +95,7 @@
+ int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
+ {
+ 	write_lock(&notifier_lock);
++	printk(KERN_EMERG"add noitifier nb %p \n", n);
+ 	while(*list)
+ 	{
+ 		if(n->priority > (*list)->priority)
+@@ -156,6 +158,7 @@
+ 
+ 	while(nb)
+ 	{
++		printk("nb %p notifier_call %p \n", nb, nb->notifier_call);
+ 		ret=nb->notifier_call(nb,val,v);
+ 		if(ret&NOTIFY_STOP_MASK)
+ 		{
+@@ -208,6 +211,7 @@
  cond_syscall(sys_lookup_dcookie)
  cond_syscall(sys_swapon)
  cond_syscall(sys_swapoff)
@@ -1449,7 +1438,7 @@ diff -Nru a/kernel/sys.c b/kernel/sys.c
  cond_syscall(sys_init_module)
  cond_syscall(sys_delete_module)
  cond_syscall(sys_socketpair)
-@@ -450,6 +452,27 @@
+@@ -454,6 +458,27 @@
  		machine_restart(buffer);
  		break;
  
@@ -1477,3 +1466,16 @@ diff -Nru a/kernel/sys.c b/kernel/sys.c
  #ifdef CONFIG_SOFTWARE_SUSPEND
  	case LINUX_REBOOT_CMD_SW_SUSPEND:
  		if (!software_suspend_enabled) {
+Index: linux-2.6.0-test6/fs/aio.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/aio.c	2003-10-07 16:08:40.000000000 +0800
++++ linux-2.6.0-test6/fs/aio.c	2003-10-07 16:09:01.000000000 +0800
+@@ -560,7 +560,7 @@
+  * 	(Note: this routine is intended to be called only
+  * 	from a kernel thread context)
+  */
+-static void use_mm(struct mm_struct *mm)
++void use_mm(struct mm_struct *mm)
+ {
+ 	struct mm_struct *active_mm;
+ 	struct task_struct *tsk = current;
diff --git a/lustre/kernel_patches/patches/kgdb-ga-2.5.73.patch b/lustre/kernel_patches/patches/kgdb-ga-2.5.73.patch
deleted file mode 100644
index b3e0bbe45fa5599da93f05e98195da375c5aeb08..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/kgdb-ga-2.5.73.patch
+++ /dev/null
@@ -1,5046 +0,0 @@
-
-
-This kgdb will get called and will trap almost any kernel
-fault WITHOUT BEING ARMED.
-
-It is entered at boot time via "kgdb" in the boot string,
-not "gdb".  This entry occurs when the first setup on the
-boot string is called, not sometime later.  You will not
-find a "waiting for gdb" on your console, as the console has
-not yet been enabled at this time.  (Note, this early stuff
-is a bit fragile as the full trap table has yet to be
-loaded, something I might address, sometime...  So don't try
-to look at memory that can not be reached, for example. 
-Once the full trap table is loaded this restriction goes
-away.)
-
-If you hard code it, you can put a breakpoint() as the FIRST
-LINE OF C CODE.
-
-It does NOT use the serial driver, but if the serial driver
-is loaded, it tells it to release the port to avoid
-conflict.  
-
-The threads stuff is not configurable, does not require
-redirection of schedule() calls and does back track to the
-first non schedule() caller on the info threads command.  If
-you switch to the thread, however, it will show it in the
-switch code (as it should).
-
-It is MUCH more aggressive and paranoid about grabbing the
-other cpus on entry.  It issues a "send_nmi_all_but_self()"
-rather than depending on them to interrupt or hit an NMI
-sometime in the distant future.  If a cpu does not come to
-the party, it will continue without it so all is not lost.
-
-It does not have anything to do with IOCTL calls, but does
-do the control-C thing.
-
-There is a LOT of info in the patch which ends up in
-.../Documentation/i386/kgdb/*
-
-There is a nifty little thing call kgdb_ts() (kgdb time
-stamp) which is a function you can code calls to which puts
-some useful stuff in a circular buffer which can be examined
-with the supplied gdb macros.
-
-It also allows you do to do "p foobar(...)"  i.e. to call a
-function from gdb, just like gdb allows in program
-debugging.
-
-In an SMP system, you can choose to "hold" any given set of
-cpus.  It also defaults to holding other cpus on single step
-(this can be overridden).
-
-This said, you can imagine my consternation when I found it
-"lost it" on continues on 2.5.  I found and fixed this this
-early pm, a hold cpu on exit goof on my part.
-
-Oh, and a final point, the configure options are more
-extensive (the serial port is set up here, for example, (can
-not wait for a command line to do this)).  There is one to
-do system call exit tests.  This is VERY new and causes the
-kernel to hit a hard "int 3" if a system call attempts to
-exit with preempt count other than zero.  This is a fault,
-of course, but the current 2.5 is full of them so I don't
-recommend turning this on.
-
-
-
-
- Documentation/i386/kgdb/andthen         |  100 +
- Documentation/i386/kgdb/debug-nmi.txt   |   37 
- Documentation/i386/kgdb/gdb-globals.txt |   71 +
- Documentation/i386/kgdb/gdbinit         |   14 
- Documentation/i386/kgdb/gdbinit-modules |  146 ++
- Documentation/i386/kgdb/gdbinit.hw      |  117 +
- Documentation/i386/kgdb/kgdb.txt        |  715 ++++++++++
- Documentation/i386/kgdb/loadmodule.sh   |   78 +
- MAINTAINERS                             |    6 
- arch/i386/Kconfig                       |  180 ++
- arch/i386/Makefile                      |    3 
- arch/i386/kernel/Makefile               |    1 
- arch/i386/kernel/entry.S                |   28 
- arch/i386/kernel/kgdb_stub.c            | 2214 ++++++++++++++++++++++++++++++++
- arch/i386/kernel/nmi.c                  |   25 
- arch/i386/kernel/smp.c                  |   12 
- arch/i386/kernel/traps.c                |   86 +
- arch/i386/lib/Makefile                  |    1 
- arch/i386/lib/kgdb_serial.c             |  485 +++++++
- arch/i386/mm/fault.c                    |    6 
- drivers/char/keyboard.c                 |    3 
- drivers/char/sysrq.c                    |   15 
- drivers/serial/8250.c                   |   42 
- include/asm-i386/bugs.h                 |   21 
- include/asm-i386/kgdb.h                 |   59 
- include/asm-i386/kgdb_local.h           |  102 +
- include/linux/config.h                  |    3 
- kernel/sched.c                          |    7 
- 28 files changed, 4565 insertions(+), 12 deletions(-)
-
-diff -puN arch/i386/Kconfig~kgdb-ga arch/i386/Kconfig
---- 25/arch/i386/Kconfig~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/Kconfig	2003-06-25 23:14:17.000000000 -0700
-@@ -1419,14 +1419,194 @@ config DEBUG_SPINLOCK_SLEEP
- 	  If you say Y here, various routines which may sleep will become very
- 	  noisy if they are called with a spinlock held.	
- 
-+config KGDB
-+	bool "Include kgdb kernel debugger"
-+	depends on DEBUG_KERNEL
-+	help  
-+	  If you say Y here, the system will be compiled with the debug
-+	  option (-g) and a debugging stub will be included in the
-+	  kernel.  This stub communicates with gdb on another (host)
-+	  computer via a serial port.  The host computer should have
-+	  access to the kernel binary file (vmlinux) and a serial port
-+	  that is connected to the target machine.  Gdb can be made to
-+	  configure the serial port or you can use stty and setserial to
-+	  do this. See the 'target' command in gdb. This option also
-+	  configures in the ability to request a breakpoint early in the
-+	  boot process.  To request the breakpoint just include 'kgdb'
-+	  as a boot option when booting the target machine.  The system
-+	  will then break as soon as it looks at the boot options.  This
-+	  option also installs a breakpoint in panic and sends any
-+	  kernel faults to the debugger. For more information see the
-+	  Documentation/i386/kgdb.txt file.
-+
-+choice
-+	depends on KGDB
-+    	prompt "Debug serial port BAUD" 
-+	default KGDB_115200BAUD
-+	help  
-+	  Gdb and the kernel stub need to agree on the baud rate to be
-+	  used.  Some systems (x86 family at this writing) allow this to
-+	  be configured.
-+
-+config KGDB_9600BAUD
-+	bool "9600"
-+
-+config KGDB_19200BAUD
-+	bool "19200"
-+
-+config KGDB_38400BAUD
-+	bool "38400"
-+
-+config KGDB_57600BAUD
-+	bool "57600"
-+
-+config KGDB_115200BAUD
-+	bool "115200"
-+endchoice
-+
-+config KGDB_PORT
-+	hex "hex I/O port address of the debug serial port"
-+	depends on KGDB
-+	default  3f8
-+	help  
-+	  Some systems (x86 family at this writing) allow the port
-+	  address to be configured.  The number entered is assumed to be
-+	  hex, don't put 0x in front of it.  The standard address are:
-+	  COM1 3f8 , irq 4 and COM2 2f8 irq 3.  Setserial /dev/ttySx
-+	  will tell you what you have.  It is good to test the serial
-+	  connection with a live system before trying to debug.
-+
-+config KGDB_IRQ
-+	int "IRQ of the debug serial port"
-+	depends on KGDB
-+	default 4
-+	help  
-+	  This is the irq for the debug port.  If everything is working
-+	  correctly and the kernel has interrupts on a control C to the
-+	  port should cause a break into the kernel debug stub.
-+
-+config DEBUG_INFO
-+	bool
-+	default y
-+
-+config KGDB_MORE
-+	bool "Add any additional compile options"
-+	depends on KGDB
-+	default n
-+	help  
-+	  Saying yes here turns on the ability to enter additional
-+	  compile options.
-+
-+
-+config KGDB_OPTIONS
-+	depends on KGDB_MORE
-+	string "Additional compile arguments"
-+	default "-O1"
-+	help  
-+	  This option allows you enter additional compile options for
-+	  the whole kernel compile.  Each platform will have a default
-+	  that seems right for it.  For example on PPC "-ggdb -O1", and
-+	  for i386 "-O1".  Note that by configuring KGDB "-g" is already
-+	  turned on.  In addition, on i386 platforms
-+	  "-fomit-frame-pointer" is deleted from the standard compile
-+	  options.
-+
-+config NO_KGDB_CPUS
-+	int "Number of CPUs"
-+	depends on KGDB && SMP
-+	default NR_CPUS
-+	help
-+	  
-+	  This option sets the number of cpus for kgdb ONLY.  It is used
-+	  to prune some internal structures so they look "nice" when
-+	  displayed with gdb.  This is to overcome possibly larger
-+	  numbers that may have been entered above.  Enter the real
-+	  number to get nice clean kgdb_info displays.
-+
-+config KGDB_TS
-+	bool "Enable kgdb time stamp macros?"
-+	depends on KGDB
-+	default n
-+	help	  
-+	  Kgdb event macros allow you to instrument your code with calls
-+	  to the kgdb event recording function.  The event log may be
-+	  examined with gdb at a break point.  Turning on this
-+	  capability also allows you to choose how many events to
-+	  keep. Kgdb always keeps the lastest events.
-+
-+choice 
-+	depends on KGDB_TS
-+	prompt "Max number of time stamps to save?"
-+	default KGDB_TS_128
-+
-+config KGDB_TS_64
-+	bool "64"
-+
-+config KGDB_TS_128
-+	bool "128"
-+
-+config KGDB_TS_256
-+	bool "256"
-+
-+config KGDB_TS_512
-+	bool "512"
-+
-+config KGDB_TS_1024
-+	bool "1024"
-+
-+endchoice
-+
-+config STACK_OVERFLOW_TEST
-+	bool "Turn on kernel stack overflow testing?"
-+	depends on KGDB
-+	default n
-+	help  
-+	  This option enables code in the front line interrupt handlers
-+	  to check for kernel stack overflow on interrupts and system
-+	  calls.  This is part of the kgdb code on x86 systems.
-+
-+config KGDB_CONSOLE
-+	bool "Enable serial console thru kgdb port"
-+	depends on KGDB
-+	default n
-+	help
-+	  This option enables the command line "console=kgdb" option.
-+	  When the system is booted with this option in the command line
-+	  all kernel printk output is sent to gdb (as well as to other
-+	  consoles).  For this to work gdb must be connected.  For this
-+	  reason, this command line option will generate a breakpoint if
-+	  gdb has not yet connected.  After the gdb continue command is
-+	  given all pent up console output will be printed by gdb on the
-+	  host machine.  Neither this option, nor KGDB require the
-+	  serial driver to be configured.
-+
-+config KGDB_SYSRQ
-+	bool "Turn on SysRq 'G' command to do a break?"
-+	depends on KGDB
-+	default y
-+	help
-+	  This option includes an option in the SysRq code that allows
-+	  you to enter SysRq G which generates a breakpoint to the KGDB
-+	  stub.  This will work if the keyboard is alive and can
-+	  interrupt the system.  Because of constraints on when the
-+	  serial port interrupt can be enabled, this code may allow you
-+	  to interrupt the system before the serial port control C is
-+	  available.  Just say yes here.
-+
- config FRAME_POINTER
- 	bool "Compile the kernel with frame pointers"
-+	default KGDB
- 	help
- 	  If you say Y here the resulting kernel image will be slightly larger
- 	  and slower, but it will give very useful debugging information.
- 	  If you don't debug the kernel, you can say N, but we may not be able
- 	  to solve problems without frame pointers.
- 
-+config MAGIC_SYSRQ
-+	bool
-+	depends on KGDB_SYSRQ
-+	default y
-+
- config X86_EXTRA_IRQS
- 	bool
- 	depends on X86_LOCAL_APIC || X86_VOYAGER
-diff -puN arch/i386/kernel/entry.S~kgdb-ga arch/i386/kernel/entry.S
---- 25/arch/i386/kernel/entry.S~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/entry.S	2003-06-25 23:14:17.000000000 -0700
-@@ -48,6 +48,18 @@
- #include <asm/smp.h>
- #include <asm/page.h>
- #include "irq_vectors.h"
-+        /* We do not recover from a stack overflow, but at least
-+         * we know it happened and should be able to track it down.
-+         */
-+#ifdef CONFIG_STACK_OVERFLOW_TEST
-+#define STACK_OVERFLOW_TEST \
-+        testl $7680,%esp;    \
-+        jnz   10f;            \
-+        call  stack_overflow; \
-+10:
-+#else
-+#define STACK_OVERFLOW_TEST
-+#endif
- 
- EBX		= 0x00
- ECX		= 0x04
-@@ -98,7 +110,8 @@ TSS_ESP0_OFFSET = (4 - 0x200)
- 	pushl %ebx; \
- 	movl $(__USER_DS), %edx; \
- 	movl %edx, %ds; \
--	movl %edx, %es;
-+	movl %edx, %es; \
-+        STACK_OVERFLOW_TEST
- 
- #define RESTORE_INT_REGS \
- 	popl %ebx;	\
-@@ -298,6 +311,19 @@ syscall_exit:
- 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
- 	jne syscall_exit_work
- restore_all:
-+#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-+	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
-+	movb CS(%esp), %al
-+	testl $(VM_MASK | 3), %eax
-+	jz resume_kernelX		# returning to kernel or vm86-space
-+
-+	cmpl $0,TI_PRE_COUNT(%ebx)	# non-zero preempt_count ?
-+	jz resume_kernelX
-+        
-+        int $3
-+        
-+resume_kernelX:
-+#endif
- 	RESTORE_ALL
- 
- 	# perform work that needs to be done immediately before resumption
-diff -puN /dev/null arch/i386/kernel/kgdb_stub.c
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/kgdb_stub.c	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,2214 @@
-+/*
-+ *
-+ * This program 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, or (at your option) any
-+ * later version.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
-+ * General Public License for more details.
-+ *
-+ */
-+
-+/*
-+ * Copyright (c) 2000 VERITAS Software Corporation.
-+ * 
-+ */
-+/****************************************************************************
-+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
-+ *
-+ *  Module name: remcom.c $
-+ *  Revision: 1.34 $
-+ *  Date: 91/03/09 12:29:49 $
-+ *  Contributor:     Lake Stevens Instrument Division$
-+ *
-+ *  Description:     low level support for gdb debugger. $
-+ *
-+ *  Considerations:  only works on target hardware $
-+ *
-+ *  Written by:	     Glenn Engel $
-+ *  Updated by:	     David Grothe <dave@gcom.com>
-+ *  ModuleState:     Experimental $
-+ *
-+ *  NOTES:	     See Below $
-+ *
-+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
-+ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
-+ *
-+ *  Changes to allow auto initilization.  All that is needed is that it
-+ *  be linked with the kernel and a break point (int 3) be executed.
-+ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
-+ *  this. It should also be possible, once the interrupt system is up, to
-+ *  call putDebugChar("+").  Once this is done, the remote debugger should
-+ *  get our attention by sending a ^C in a packet. George Anzinger 
-+ *  <george@mvista.com>
-+ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
-+ *  Added thread support, support for multiple processors,
-+ *	support for ia-32(x86) hardware debugging.
-+ *	Amit S. Kale ( akale@veritas.com )
-+ *
-+ *
-+ *  To enable debugger support, two things need to happen.  One, a
-+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
-+ *  or error conditions to be properly intercepted and reported to gdb.
-+ *  Two, a breakpoint needs to be generated to begin communication.  This
-+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
-+ *  simulates a breakpoint by executing an int 3.
-+ *
-+ *************
-+ *
-+ *    The following gdb commands are supported:
-+ *
-+ * command	    function				   Return value
-+ *
-+ *    g		    return the value of the CPU registers  hex data or ENN
-+ *    G		    set the value of the CPU registers	   OK or ENN
-+ *
-+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA	   hex data or ENN
-+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA	   OK or ENN
-+ *
-+ *    c		    Resume at current address		   SNN	 ( signal NN)
-+ *    cAA..AA	    Continue at address AA..AA		   SNN
-+ *
-+ *    s		    Step one instruction		   SNN
-+ *    sAA..AA	    Step one instruction from AA..AA	   SNN
-+ *
-+ *    k		    kill
-+ *
-+ *    ?		    What was the last sigval ?		   SNN	 (signal NN)
-+ *
-+ * All commands and responses are sent with a packet which includes a
-+ * checksum.  A packet consists of
-+ *
-+ * $<packet info>#<checksum>.
-+ *
-+ * where
-+ * <packet info> :: <characters representing the command or response>
-+ * <checksum>	 :: < two hex digits computed as modulo 256 sum of <packetinfo>>
-+ *
-+ * When a packet is received, it is first acknowledged with either '+' or '-'.
-+ * '+' indicates a successful transfer.	 '-' indicates a failed transfer.
-+ *
-+ * Example:
-+ *
-+ * Host:		  Reply:
-+ * $m0,10#2a		   +$00010203040506070809101112131415#42
-+ *
-+ ****************************************************************************/
-+#define KGDB_VERSION "<20030530.0126.22>"
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <asm/string.h>		/* for strcpy */
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <asm/vm86.h>
-+#include <asm/system.h>
-+#include <asm/ptrace.h>		/* for linux pt_regs struct */
-+#include <asm/kgdb_local.h>
-+#include <linux/list.h>
-+#include <asm/atomic.h>
-+#include <asm/processor.h>
-+#include <linux/irq.h>
-+#include <asm/desc.h>
-+
-+/************************************************************************
-+ *
-+ * external low-level support routines
-+ */
-+typedef void (*Function) (void);	/* pointer to a function */
-+
-+/* Thread reference */
-+typedef unsigned char threadref[8];
-+
-+extern void putDebugChar(int);	/* write a single character	 */
-+extern int getDebugChar(void);	/* read and return a single char */
-+
-+/************************************************************************/
-+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-+/* at least NUMREGBYTES*2 are needed for register packets */
-+/* Longer buffer is needed to list all threads */
-+#define BUFMAX 1024
-+
-+char *kgdb_version = KGDB_VERSION;
-+
-+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
-+int debug_regs = 0;		/* set to non-zero to print registers */
-+
-+/* filled in by an external module */
-+char *gdb_module_offsets;
-+
-+static const char hexchars[] = "0123456789abcdef";
-+
-+/* Number of bytes of registers.  */
-+#define NUMREGBYTES 64
-+/*
-+ * Note that this register image is in a different order than
-+ * the register image that Linux produces at interrupt time.
-+ *
-+ * Linux's register image is defined by struct pt_regs in ptrace.h.
-+ * Just why GDB uses a different order is a historical mystery.
-+ */
-+enum regnames { _EAX,		/* 0 */
-+	_ECX,			/* 1 */
-+	_EDX,			/* 2 */
-+	_EBX,			/* 3 */
-+	_ESP,			/* 4 */
-+	_EBP,			/* 5 */
-+	_ESI,			/* 6 */
-+	_EDI,			/* 7 */
-+	_PC /* 8 also known as eip */ ,
-+	_PS /* 9 also known as eflags */ ,
-+	_CS,			/* 10 */
-+	_SS,			/* 11 */
-+	_DS,			/* 12 */
-+	_ES,			/* 13 */
-+	_FS,			/* 14 */
-+	_GS			/* 15 */
-+};
-+
-+/***************************  ASSEMBLY CODE MACROS *************************/
-+/*
-+ * Put the error code here just in case the user cares.	
-+ * Likewise, the vector number here (since GDB only gets the signal
-+ * number through the usual means, and that's not very specific). 
-+ * The called_from is the return address so he can tell how we entered kgdb.
-+ * This will allow him to seperate out the various possible entries. 
-+ */
-+#define REMOTE_DEBUG 0		/* set != to turn on printing (also available in info) */
-+
-+#define PID_MAX PID_MAX_DEFAULT
-+
-+#ifdef CONFIG_SMP
-+void smp_send_nmi_allbutself(void);
-+#define IF_SMP(x) x
-+#undef MAX_NO_CPUS
-+#ifndef CONFIG_NO_KGDB_CPUS
-+#define CONFIG_NO_KGDB_CPUS 2
-+#endif
-+#if CONFIG_NO_KGDB_CPUS > NR_CPUS
-+#define MAX_NO_CPUS NR_CPUS
-+#else
-+#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
-+#endif
-+#define hold_init hold_on_sstep: 1,
-+#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
-+#define NUM_CPUS num_online_cpus()
-+extern volatile unsigned long cpu_callout_map;
-+#else
-+#define IF_SMP(x)
-+#define hold_init
-+#undef MAX_NO_CPUS
-+#define MAX_NO_CPUS 1
-+#define NUM_CPUS 1
-+#endif
-+#define NOCPU (struct task_struct *)0xbad1fbad
-+/* *INDENT-OFF*	 */
-+struct kgdb_info {
-+	int used_malloc;
-+	void *called_from;
-+	long long entry_tsc;
-+	int errcode;
-+	int vector;
-+	int print_debug_info;
-+#ifdef CONFIG_SMP
-+	int hold_on_sstep;
-+	struct {
-+		volatile struct task_struct *task;
-+		int pid;
-+		int hold;
-+		struct pt_regs *regs;
-+	} cpus_waiting[MAX_NO_CPUS];
-+#endif
-+} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
-+
-+/* *INDENT-ON*	*/
-+
-+#define used_m kgdb_info.used_malloc
-+/*
-+ * This is little area we set aside to contain the stack we 
-+ * need to build to allow gdb to call functions.  We use one
-+ * per cpu to avoid locking issues.  We will do all this work
-+ * with interrupts off so that should take care of the protection
-+ * issues.
-+ */
-+#define LOOKASIDE_SIZE 200	/* should be more than enough */
-+#define MALLOC_MAX   200	/* Max malloc size */
-+struct {
-+	unsigned int esp;
-+	int array[LOOKASIDE_SIZE];
-+} fn_call_lookaside[MAX_NO_CPUS];
-+
-+static int trap_cpu;
-+static unsigned int OLD_esp;
-+
-+#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
-+#define IF_BIT 0x200
-+#define TF_BIT 0x100
-+
-+#define MALLOC_ROUND 8-1
-+
-+static char malloc_array[MALLOC_MAX];
-+IF_SMP(static void to_gdb(const char *mess));
-+void *
-+malloc(int size)
-+{
-+
-+	if (size <= (MALLOC_MAX - used_m)) {
-+		int old_used = used_m;
-+		used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
-+		return &malloc_array[old_used];
-+	} else {
-+		return NULL;
-+	}
-+}
-+
-+/*
-+ * Gdb calls functions by pushing agruments, including a return address 
-+ * on the stack and the adjusting EIP to point to the function.	 The 
-+ * whole assumption in GDB is that we are on a different stack than the
-+ * one the "user" i.e. code that hit the break point, is on.  This, of
-+ * course is not true in the kernel.  Thus various dodges are needed to
-+ * do the call without directly messing with EIP (which we can not change
-+ * as it is just a location and not a register.	 To adjust it would then
-+ * require that we move every thing below EIP up or down as needed.  This
-+ * will not work as we may well have stack relative pointer on the stack
-+ * (such as the pointer to regs, for example).
-+
-+ * So here is what we do:
-+ * We detect gdb attempting to store into the stack area and instead, store
-+ * into the fn_call_lookaside.array at the same relative location as if it 
-+ * were the area ESP pointed at.  We also trap ESP modifications
-+ * and uses these to adjust fn_call_lookaside.esp.  On entry 
-+ * fn_call_lookaside.esp will be set to point at the last entry in
-+ * fn_call_lookaside.array.  This allows us to check if it has changed, and 
-+ * if so, on exit, we add the registers we will use to do the move and a
-+ * trap/ interrupt return exit sequence.  We then adjust the eflags in the
-+ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
-+ * kill the interrupt bit, AND we change EIP to point at our set up stub.
-+ * As part of the register set up we preset the registers to point at the
-+ * begining and end of the fn_call_lookaside.array, so all the stub needs to
-+ * do is move words from the array to the stack until ESP= the desired value
-+ * then do the rti.  This will then transfer to the desired function with 
-+ * all the correct registers.  Nifty huh?
-+ */
-+extern asmlinkage void fn_call_stub(void);
-+extern asmlinkage void fn_rtn_stub(void);
-+/*					   *INDENT-OFF*	 */
-+__asm__("fn_rtn_stub:\n\t"
-+	"movl %eax,%esp\n\t"
-+	"fn_call_stub:\n\t"
-+	"1:\n\t"
-+	"addl $-4,%ebx\n\t"
-+	"movl (%ebx), %eax\n\t"
-+	"pushl %eax\n\t"
-+	"cmpl %esp,%ecx\n\t"
-+	"jne  1b\n\t"
-+	"popl %eax\n\t" 
-+	"popl %ebx\n\t" 
-+	"popl %ecx\n\t" 
-+	"iret \n\t");
-+/*					     *INDENT-ON*  */
-+#define gdb_i386vector	kgdb_info.vector
-+#define gdb_i386errcode kgdb_info.errcode
-+#define waiting_cpus	kgdb_info.cpus_waiting
-+#define remote_debug	kgdb_info.print_debug_info
-+#define hold_cpu(cpu)	kgdb_info.cpus_waiting[cpu].hold
-+/* gdb locks */
-+
-+#ifdef CONFIG_SMP
-+static int in_kgdb_called;
-+static spinlock_t waitlocks[MAX_NO_CPUS] =
-+    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
-+/*
-+ * The following array has the thread pointer of each of the "other"
-+ * cpus.  We make it global so it can be seen by gdb.
-+ */
-+volatile int in_kgdb_entry_log[MAX_NO_CPUS];
-+volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
-+/*
-+static spinlock_t continuelocks[MAX_NO_CPUS];
-+*/
-+spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
-+/* waiters on our spinlock plus us */
-+static atomic_t spinlock_waiters = ATOMIC_INIT(1);
-+static int spinlock_count = 0;
-+static int spinlock_cpu = 0;
-+/*
-+ * Note we use nested spin locks to account for the case where a break
-+ * point is encountered when calling a function by user direction from
-+ * kgdb. Also there is the memory exception recursion to account for.
-+ * Well, yes, but this lets other cpus thru too.  Lets add a
-+ * cpu id to the lock.
-+ */
-+#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
-+			      spinlock_cpu != smp_processor_id()){\
-+				      atomic_inc(&spinlock_waiters); \
-+				      while (! spin_trylock(x)) {\
-+					    in_kgdb(&regs);\
-+				      }\
-+				      atomic_dec(&spinlock_waiters); \
-+				      spinlock_count = 1; \
-+				      spinlock_cpu = smp_processor_id(); \
-+			  }else{  \
-+				      spinlock_count++; \
-+			  }
-+#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
-+extern volatile unsigned long cpu_callout_map;
-+#else
-+unsigned kgdb_spinlock = 0;
-+#define KGDB_SPIN_LOCK(x) --*x
-+#define KGDB_SPIN_UNLOCK(x) ++*x
-+#endif
-+
-+int
-+hex(char ch)
-+{
-+	if ((ch >= 'a') && (ch <= 'f'))
-+		return (ch - 'a' + 10);
-+	if ((ch >= '0') && (ch <= '9'))
-+		return (ch - '0');
-+	if ((ch >= 'A') && (ch <= 'F'))
-+		return (ch - 'A' + 10);
-+	return (-1);
-+}
-+
-+/* scan for the sequence $<data>#<checksum>	*/
-+void
-+getpacket(char *buffer)
-+{
-+	unsigned char checksum;
-+	unsigned char xmitcsum;
-+	int i;
-+	int count;
-+	char ch;
-+
-+	do {
-+		/* wait around for the start character, ignore all other characters */
-+		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
-+		checksum = 0;
-+		xmitcsum = -1;
-+
-+		count = 0;
-+
-+		/* now, read until a # or end of buffer is found */
-+		while (count < BUFMAX) {
-+			ch = getDebugChar() & 0x7f;
-+			if (ch == '#')
-+				break;
-+			checksum = checksum + ch;
-+			buffer[count] = ch;
-+			count = count + 1;
-+		}
-+		buffer[count] = 0;
-+
-+		if (ch == '#') {
-+			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
-+			xmitcsum += hex(getDebugChar() & 0x7f);
-+			if ((remote_debug) && (checksum != xmitcsum)) {
-+				printk
-+				    ("bad checksum.	My count = 0x%x, sent=0x%x. buf=%s\n",
-+				     checksum, xmitcsum, buffer);
-+			}
-+
-+			if (checksum != xmitcsum)
-+				putDebugChar('-');	/* failed checksum */
-+			else {
-+				putDebugChar('+');	/* successful transfer */
-+				/* if a sequence char is present, reply the sequence ID */
-+				if (buffer[2] == ':') {
-+					putDebugChar(buffer[0]);
-+					putDebugChar(buffer[1]);
-+					/* remove sequence chars from buffer */
-+					count = strlen(buffer);
-+					for (i = 3; i <= count; i++)
-+						buffer[i - 3] = buffer[i];
-+				}
-+			}
-+		}
-+	} while (checksum != xmitcsum);
-+
-+	if (remote_debug)
-+		printk("R:%s\n", buffer);
-+}
-+
-+/* send the packet in buffer.  */
-+
-+void
-+putpacket(char *buffer)
-+{
-+	unsigned char checksum;
-+	int count;
-+	char ch;
-+
-+	/*  $<packet info>#<checksum>. */
-+	do {
-+		if (remote_debug)
-+			printk("T:%s\n", buffer);
-+		putDebugChar('$');
-+		checksum = 0;
-+		count = 0;
-+
-+		while ((ch = buffer[count])) {
-+			putDebugChar(ch);
-+			checksum += ch;
-+			count += 1;
-+		}
-+
-+		putDebugChar('#');
-+		putDebugChar(hexchars[checksum >> 4]);
-+		putDebugChar(hexchars[checksum % 16]);
-+
-+	} while ((getDebugChar() & 0x7f) != '+');
-+
-+}
-+
-+static char remcomInBuffer[BUFMAX];
-+static char remcomOutBuffer[BUFMAX];
-+static short error;
-+
-+void
-+debug_error(char *format, char *parm)
-+{
-+	if (remote_debug)
-+		printk(format, parm);
-+}
-+
-+static void
-+print_regs(struct pt_regs *regs)
-+{
-+	printk("EAX=%08lx ", regs->eax);
-+	printk("EBX=%08lx ", regs->ebx);
-+	printk("ECX=%08lx ", regs->ecx);
-+	printk("EDX=%08lx ", regs->edx);
-+	printk("\n");
-+	printk("ESI=%08lx ", regs->esi);
-+	printk("EDI=%08lx ", regs->edi);
-+	printk("EBP=%08lx ", regs->ebp);
-+	printk("ESP=%08lx ", (long) &regs->esp);
-+	printk("\n");
-+	printk(" DS=%08x ", regs->xds);
-+	printk(" ES=%08x ", regs->xes);
-+	printk(" SS=%08x ", __KERNEL_DS);
-+	printk(" FL=%08lx ", regs->eflags);
-+	printk("\n");
-+	printk(" CS=%08x ", regs->xcs);
-+	printk(" IP=%08lx ", regs->eip);
-+#if 0
-+	printk(" FS=%08x ", regs->fs);
-+	printk(" GS=%08x ", regs->gs);
-+#endif
-+	printk("\n");
-+
-+}				/* print_regs */
-+
-+#define NEW_esp fn_call_lookaside[trap_cpu].esp
-+
-+static void
-+regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
-+{
-+	gdb_regs[_EAX] = regs->eax;
-+	gdb_regs[_EBX] = regs->ebx;
-+	gdb_regs[_ECX] = regs->ecx;
-+	gdb_regs[_EDX] = regs->edx;
-+	gdb_regs[_ESI] = regs->esi;
-+	gdb_regs[_EDI] = regs->edi;
-+	gdb_regs[_EBP] = regs->ebp;
-+	gdb_regs[_DS] = regs->xds;
-+	gdb_regs[_ES] = regs->xes;
-+	gdb_regs[_PS] = regs->eflags;
-+	gdb_regs[_CS] = regs->xcs;
-+	gdb_regs[_PC] = regs->eip;
-+	/* Note, as we are a debugging the kernel, we will always 
-+	 * trap in kernel code, this means no priviledge change,
-+	 * and so the pt_regs structure is not completely valid.  In a non
-+	 * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
-+	 * SS and ESP are not stacked, this means that the last 2 elements of
-+	 * pt_regs is not valid (they would normally refer to the user stack)
-+	 * also, using regs+1 is no good because you end up will a value that is 
-+	 * 2 longs (8) too high.  This used to cause stepping over functions
-+	 * to fail, so my fix is to use the address of regs->esp, which 
-+	 * should point at the end of the stack frame.	Note I have ignored
-+	 * completely exceptions that cause an error code to be stacked, such
-+	 * as double fault.  Stuart Hughes, Zentropix.
-+	 * original code: gdb_regs[_ESP] =  (int) (regs + 1) ; 
-+
-+	 * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
-+	 */
-+	gdb_regs[_ESP] = NEW_esp;
-+	gdb_regs[_SS] = __KERNEL_DS;
-+	gdb_regs[_FS] = 0xFFFF;
-+	gdb_regs[_GS] = 0xFFFF;
-+}				/* regs_to_gdb_regs */
-+
-+static void
-+gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
-+{
-+	regs->eax = gdb_regs[_EAX];
-+	regs->ebx = gdb_regs[_EBX];
-+	regs->ecx = gdb_regs[_ECX];
-+	regs->edx = gdb_regs[_EDX];
-+	regs->esi = gdb_regs[_ESI];
-+	regs->edi = gdb_regs[_EDI];
-+	regs->ebp = gdb_regs[_EBP];
-+	regs->xds = gdb_regs[_DS];
-+	regs->xes = gdb_regs[_ES];
-+	regs->eflags = gdb_regs[_PS];
-+	regs->xcs = gdb_regs[_CS];
-+	regs->eip = gdb_regs[_PC];
-+	NEW_esp = gdb_regs[_ESP];	/* keep the value */
-+#if 0				/* can't change these */
-+	regs->esp = gdb_regs[_ESP];
-+	regs->xss = gdb_regs[_SS];
-+	regs->fs = gdb_regs[_FS];
-+	regs->gs = gdb_regs[_GS];
-+#endif
-+
-+}				/* gdb_regs_to_regs */
-+extern void scheduling_functions_start_here(void);
-+extern void scheduling_functions_end_here(void);
-+#define first_sched	((unsigned long) scheduling_functions_start_here)
-+#define last_sched	((unsigned long) scheduling_functions_end_here)
-+
-+int thread_list = 0;
-+
-+void
-+get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
-+{
-+	unsigned long stack_page;
-+	int count = 0;
-+	IF_SMP(int i);
-+	if (!p || p == current) {
-+		regs_to_gdb_regs(gdb_regs, regs);
-+		return;
-+	}
-+#ifdef CONFIG_SMP
-+	for (i = 0; i < MAX_NO_CPUS; i++) {
-+		if (p == kgdb_info.cpus_waiting[i].task) {
-+			regs_to_gdb_regs(gdb_regs,
-+					 kgdb_info.cpus_waiting[i].regs);
-+			gdb_regs[_ESP] =
-+			    (int) &kgdb_info.cpus_waiting[i].regs->esp;
-+
-+			return;
-+		}
-+	}
-+#endif
-+	memset(gdb_regs, 0, NUMREGBYTES);
-+	gdb_regs[_ESP] = p->thread.esp;
-+	gdb_regs[_PC] = p->thread.eip;
-+	gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
-+	gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
-+	gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
-+
-+/*
-+ * This code is to give a more informative notion of where a process 
-+ * is waiting.	It is used only when the user asks for a thread info
-+ * list.  If he then switches to the thread, s/he will find the task
-+ * is in schedule, but a back trace should show the same info we come
-+ * up with.  This code was shamelessly purloined from process.c.  It was
-+ * then enhanced to provide more registers than simply the program 
-+ * counter.
-+ */
-+
-+	if (!thread_list) {
-+		return;
-+	}
-+
-+	if (p->state == TASK_RUNNING)
-+		return;
-+	stack_page = (unsigned long) p->thread_info;
-+	if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
-+		return;
-+	/* include/asm-i386/system.h:switch_to() pushes ebp last. */
-+	do {
-+		if (gdb_regs[_EBP] < stack_page ||
-+		    gdb_regs[_EBP] > 8184 + stack_page)
-+			return;
-+		gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
-+		gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
-+		gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
-+		if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
-+			return;
-+	} while (count++ < 16);
-+	return;
-+}
-+
-+/* Indicate to caller of mem2hex or hex2mem that there has been an
-+   error.  */
-+static volatile int mem_err = 0;
-+static volatile int mem_err_expected = 0;
-+static volatile int mem_err_cnt = 0;
-+static int garbage_loc = -1;
-+
-+int
-+get_char(char *addr)
-+{
-+	return *addr;
-+}
-+
-+void
-+set_char(char *addr, int val, int may_fault)
-+{
-+	/*
-+	 * This code traps references to the area mapped to the kernel
-+	 * stack as given by the regs and, instead, stores to the
-+	 * fn_call_lookaside[cpu].array
-+	 */
-+	if (may_fault &&
-+	    (unsigned int) addr < OLD_esp &&
-+	    ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
-+		addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
-+	}
-+	*addr = val;
-+}
-+
-+/* convert the memory pointed to by mem into hex, placing result in buf */
-+/* return a pointer to the last char put in buf (null) */
-+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
-+   a fault; if zero treat a fault like any other fault in the stub.  */
-+char *
-+mem2hex(char *mem, char *buf, int count, int may_fault)
-+{
-+	int i;
-+	unsigned char ch;
-+
-+	if (may_fault) {
-+		mem_err_expected = 1;
-+		mem_err = 0;
-+	}
-+	for (i = 0; i < count; i++) {
-+		/* printk("%lx = ", mem) ; */
-+
-+		ch = get_char(mem++);
-+
-+		/* printk("%02x\n", ch & 0xFF) ; */
-+		if (may_fault && mem_err) {
-+			if (remote_debug)
-+				printk("Mem fault fetching from addr %lx\n",
-+				       (long) (mem - 1));
-+			*buf = 0;	/* truncate buffer */
-+			return (buf);
-+		}
-+		*buf++ = hexchars[ch >> 4];
-+		*buf++ = hexchars[ch % 16];
-+	}
-+	*buf = 0;
-+	if (may_fault)
-+		mem_err_expected = 0;
-+	return (buf);
-+}
-+
-+/* convert the hex array pointed to by buf into binary to be placed in mem */
-+/* return a pointer to the character AFTER the last byte written */
-+/* NOTE: We use the may fault flag to also indicate if the write is to
-+ * the registers (0) or "other" memory (!=0) 
-+ */
-+char *
-+hex2mem(char *buf, char *mem, int count, int may_fault)
-+{
-+	int i;
-+	unsigned char ch;
-+
-+	if (may_fault) {
-+		mem_err_expected = 1;
-+		mem_err = 0;
-+	}
-+	for (i = 0; i < count; i++) {
-+		ch = hex(*buf++) << 4;
-+		ch = ch + hex(*buf++);
-+		set_char(mem++, ch, may_fault);
-+
-+		if (may_fault && mem_err) {
-+			if (remote_debug)
-+				printk("Mem fault storing to addr %lx\n",
-+				       (long) (mem - 1));
-+			return (mem);
-+		}
-+	}
-+	if (may_fault)
-+		mem_err_expected = 0;
-+	return (mem);
-+}
-+
-+/**********************************************/
-+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-+/* RETURN NUMBER OF CHARS PROCESSED	      */
-+/**********************************************/
-+int
-+hexToInt(char **ptr, int *intValue)
-+{
-+	int numChars = 0;
-+	int hexValue;
-+
-+	*intValue = 0;
-+
-+	while (**ptr) {
-+		hexValue = hex(**ptr);
-+		if (hexValue >= 0) {
-+			*intValue = (*intValue << 4) | hexValue;
-+			numChars++;
-+		} else
-+			break;
-+
-+		(*ptr)++;
-+	}
-+
-+	return (numChars);
-+}
-+
-+#define stubhex(h) hex(h)
-+
-+static int
-+stub_unpack_int(char *buff, int fieldlength)
-+{
-+	int nibble;
-+	int retval = 0;
-+
-+	while (fieldlength) {
-+		nibble = stubhex(*buff++);
-+		retval |= nibble;
-+		fieldlength--;
-+		if (fieldlength)
-+			retval = retval << 4;
-+	}
-+	return retval;
-+}
-+
-+static char *
-+pack_hex_byte(char *pkt, int byte)
-+{
-+	*pkt++ = hexchars[(byte >> 4) & 0xf];
-+	*pkt++ = hexchars[(byte & 0xf)];
-+	return pkt;
-+}
-+
-+#define BUF_THREAD_ID_SIZE 16
-+
-+static char *
-+pack_threadid(char *pkt, threadref * id)
-+{
-+	char *limit;
-+	unsigned char *altid;
-+
-+	altid = (unsigned char *) id;
-+	limit = pkt + BUF_THREAD_ID_SIZE;
-+	while (pkt < limit)
-+		pkt = pack_hex_byte(pkt, *altid++);
-+	return pkt;
-+}
-+
-+static char *
-+unpack_byte(char *buf, int *value)
-+{
-+	*value = stub_unpack_int(buf, 2);
-+	return buf + 2;
-+}
-+
-+static char *
-+unpack_threadid(char *inbuf, threadref * id)
-+{
-+	char *altref;
-+	char *limit = inbuf + BUF_THREAD_ID_SIZE;
-+	int x, y;
-+
-+	altref = (char *) id;
-+
-+	while (inbuf < limit) {
-+		x = stubhex(*inbuf++);
-+		y = stubhex(*inbuf++);
-+		*altref++ = (x << 4) | y;
-+	}
-+	return inbuf;
-+}
-+
-+void
-+int_to_threadref(threadref * id, int value)
-+{
-+	unsigned char *scan;
-+
-+	scan = (unsigned char *) id;
-+	{
-+		int i = 4;
-+		while (i--)
-+			*scan++ = 0;
-+	}
-+	*scan++ = (value >> 24) & 0xff;
-+	*scan++ = (value >> 16) & 0xff;
-+	*scan++ = (value >> 8) & 0xff;
-+	*scan++ = (value & 0xff);
-+}
-+
-+static int
-+threadref_to_int(threadref * ref)
-+{
-+	int i, value = 0;
-+	unsigned char *scan;
-+
-+	scan = (char *) ref;
-+	scan += 4;
-+	i = 4;
-+	while (i-- > 0)
-+		value = (value << 8) | ((*scan++) & 0xff);
-+	return value;
-+}
-+
-+#if 1				/* this is a hold over from 2.4 where O(1) was "sometimes" */
-+extern struct task_struct *kgdb_get_idle(int cpu);
-+#define idle_task(cpu) kgdb_get_idle(cpu)
-+#else
-+#define idle_task(cpu) init_tasks[cpu]
-+#endif
-+
-+struct task_struct *
-+getthread(int pid)
-+{
-+	struct task_struct *thread;
-+	if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
-+
-+		return idle_task(pid - PID_MAX);
-+	} else {
-+		/*
-+		 * find_task_by_pid is relatively safe all the time
-+		 * Other pid functions require lock downs which imply
-+		 * that we may be interrupting them (as we get here
-+		 * in the middle of most any lock down)
-+		 */
-+		thread = find_task_by_pid(pid);
-+		if (thread) {
-+			return thread;
-+		}
-+	}
-+	return NULL;
-+}
-+/* *INDENT-OFF*	 */
-+struct hw_breakpoint {
-+	unsigned enabled;
-+	unsigned type;
-+	unsigned len;
-+	unsigned addr;
-+} breakinfo[4] = { {enabled:0}, 
-+		   {enabled:0}, 
-+		   {enabled:0}, 
-+		   {enabled:0}};
-+/* *INDENT-ON*	*/
-+unsigned hw_breakpoint_status;
-+void
-+correct_hw_break(void)
-+{
-+	int breakno;
-+	int correctit;
-+	int breakbit;
-+	unsigned dr7;
-+
-+	asm volatile ("movl %%db7, %0\n":"=r" (dr7)
-+		      :);
-+	/* *INDENT-OFF*	 */
-+	do {
-+		unsigned addr0, addr1, addr2, addr3;
-+		asm volatile ("movl %%db0, %0\n"
-+			      "movl %%db1, %1\n"
-+			      "movl %%db2, %2\n"
-+			      "movl %%db3, %3\n"
-+			      :"=r" (addr0), "=r"(addr1),
-+			      "=r"(addr2), "=r"(addr3)
-+			      :);
-+	} while (0);
-+	/* *INDENT-ON*	*/
-+	correctit = 0;
-+	for (breakno = 0; breakno < 3; breakno++) {
-+		breakbit = 2 << (breakno << 1);
-+		if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
-+			correctit = 1;
-+			dr7 |= breakbit;
-+			dr7 &= ~(0xf0000 << (breakno << 2));
-+			dr7 |= (((breakinfo[breakno].len << 2) |
-+				 breakinfo[breakno].type) << 16) <<
-+			    (breakno << 2);
-+			switch (breakno) {
-+			case 0:
-+				asm volatile ("movl %0, %%dr0\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 1:
-+				asm volatile ("movl %0, %%dr1\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 2:
-+				asm volatile ("movl %0, %%dr2\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+
-+			case 3:
-+				asm volatile ("movl %0, %%dr3\n"::"r"
-+					      (breakinfo[breakno].addr));
-+				break;
-+			}
-+		} else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
-+			correctit = 1;
-+			dr7 &= ~breakbit;
-+			dr7 &= ~(0xf0000 << (breakno << 2));
-+		}
-+	}
-+	if (correctit) {
-+		asm volatile ("movl %0, %%db7\n"::"r" (dr7));
-+	}
-+}
-+
-+int
-+remove_hw_break(unsigned breakno)
-+{
-+	if (!breakinfo[breakno].enabled) {
-+		return -1;
-+	}
-+	breakinfo[breakno].enabled = 0;
-+	return 0;
-+}
-+
-+int
-+set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
-+{
-+	if (breakinfo[breakno].enabled) {
-+		return -1;
-+	}
-+	breakinfo[breakno].enabled = 1;
-+	breakinfo[breakno].type = type;
-+	breakinfo[breakno].len = len;
-+	breakinfo[breakno].addr = addr;
-+	return 0;
-+}
-+
-+#ifdef CONFIG_SMP
-+static int in_kgdb_console = 0;
-+
-+int
-+in_kgdb(struct pt_regs *regs)
-+{
-+	unsigned flags;
-+	int cpu = smp_processor_id();
-+	in_kgdb_called = 1;
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		if (in_kgdb_here_log[cpu] ||	/* we are holding this cpu */
-+		    in_kgdb_console) {	/* or we are doing slow i/o */
-+			return 1;
-+		}
-+		return 0;
-+	}
-+
-+	/* As I see it the only reason not to let all cpus spin on
-+	 * the same spin_lock is to allow selected ones to proceed.
-+	 * This would be a good thing, so we leave it this way.
-+	 * Maybe someday....  Done !
-+
-+	 * in_kgdb() is called from an NMI so we don't pretend
-+	 * to have any resources, like printk() for example.  
-+	 */
-+
-+	kgdb_local_irq_save(flags);	/* only local here, to avoid hanging */
-+	/*
-+	 * log arival of this cpu
-+	 * The NMI keeps on ticking.  Protect against recurring more
-+	 * than once, and ignor the cpu that has the kgdb lock
-+	 */
-+	in_kgdb_entry_log[cpu]++;
-+	in_kgdb_here_log[cpu] = regs;
-+	if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
-+		goto exit_in_kgdb;
-+	}
-+	/*
-+	 * For protection of the initilization of the spin locks by kgdb
-+	 * it locks the kgdb spinlock before it gets the wait locks set
-+	 * up.	We wait here for the wait lock to be taken.  If the
-+	 * kgdb lock goes away first??	Well, it could be a slow exit
-+	 * sequence where the wait lock is removed prior to the kgdb lock
-+	 * so if kgdb gets unlocked, we just exit.
-+	 */
-+	while (spin_is_locked(&kgdb_spinlock) &&
-+	       !spin_is_locked(waitlocks + cpu)) ;
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		goto exit_in_kgdb;
-+	}
-+	waiting_cpus[cpu].task = current;
-+	waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
-+	waiting_cpus[cpu].regs = regs;
-+
-+	spin_unlock_wait(waitlocks + cpu);
-+	/*
-+	 * log departure of this cpu
-+	 */
-+	waiting_cpus[cpu].task = 0;
-+	waiting_cpus[cpu].pid = 0;
-+	waiting_cpus[cpu].regs = 0;
-+	correct_hw_break();
-+      exit_in_kgdb:
-+	in_kgdb_here_log[cpu] = 0;
-+	kgdb_local_irq_restore(flags);
-+	return 1;
-+	/*
-+	   spin_unlock(continuelocks + smp_processor_id());
-+	 */
-+}
-+
-+void
-+smp__in_kgdb(struct pt_regs regs)
-+{
-+	ack_APIC_irq();
-+	in_kgdb(&regs);
-+}
-+#else
-+int
-+in_kgdb(struct pt_regs *regs)
-+{
-+	return (kgdb_spinlock);
-+}
-+#endif
-+
-+void
-+printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
-+{
-+	unsigned dr6;
-+	int i;
-+	switch (exceptionNo) {
-+	case 1:		/* debug exception */
-+		break;
-+	case 3:		/* breakpoint */
-+		sprintf(buffer, "Software breakpoint");
-+		return;
-+	default:
-+		sprintf(buffer, "Details not available");
-+		return;
-+	}
-+	asm volatile ("movl %%db6, %0\n":"=r" (dr6)
-+		      :);
-+	if (dr6 & 0x4000) {
-+		sprintf(buffer, "Single step");
-+		return;
-+	}
-+	for (i = 0; i < 4; ++i) {
-+		if (dr6 & (1 << i)) {
-+			sprintf(buffer, "Hardware breakpoint %d", i);
-+			return;
-+		}
-+	}
-+	sprintf(buffer, "Unknown trap");
-+	return;
-+}
-+
-+/*
-+ * This function does all command procesing for interfacing to gdb.
-+ *
-+ * NOTE:  The INT nn instruction leaves the state of the interrupt
-+ *	  enable flag UNCHANGED.  That means that when this routine
-+ *	  is entered via a breakpoint (INT 3) instruction from code
-+ *	  that has interrupts enabled, then interrupts will STILL BE
-+ *	  enabled when this routine is entered.	 The first thing that
-+ *	  we do here is disable interrupts so as to prevent recursive
-+ *	  entries and bothersome serial interrupts while we are
-+ *	  trying to run the serial port in polled mode.
-+ *
-+ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
-+ * it is always necessary to do a restore_flags before returning
-+ * so as to let go of that lock.
-+ */
-+int
-+kgdb_handle_exception(int exceptionVector,
-+		      int signo, int err_code, struct pt_regs *linux_regs)
-+{
-+	struct task_struct *usethread = NULL;
-+	struct task_struct *thread_list_start = 0, *thread = NULL;
-+	int addr, length;
-+	int breakno, breaktype;
-+	char *ptr;
-+	int newPC;
-+	threadref thref;
-+	int threadid;
-+	int thread_min = PID_MAX + MAX_NO_CPUS;
-+	int maxthreads;
-+	int nothreads;
-+	unsigned long flags;
-+	int gdb_regs[NUMREGBYTES / 4];
-+	int dr6;
-+	IF_SMP(int entry_state = 0);	/* 0, ok, 1, no nmi, 2 sync failed */
-+#define NO_NMI 1
-+#define NO_SYNC 2
-+#define	regs	(*linux_regs)
-+#define NUMREGS NUMREGBYTES/4
-+	/*
-+	 * If the entry is not from the kernel then return to the Linux
-+	 * trap handler and let it process the interrupt normally.
-+	 */
-+	if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
-+		printk("ignoring non-kernel exception\n");
-+		print_regs(&regs);
-+		return (0);
-+	}
-+
-+	kgdb_local_irq_save(flags);
-+
-+	/* Get kgdb spinlock */
-+
-+	KGDB_SPIN_LOCK(&kgdb_spinlock);
-+	rdtscll(kgdb_info.entry_tsc);
-+	/*
-+	 * We depend on this spinlock and the NMI watch dog to control the 
-+	 * other cpus.	They will arrive at "in_kgdb()" as a result of the
-+	 * NMI and will wait there for the following spin locks to be 
-+	 * released.
-+	 */
-+#ifdef CONFIG_SMP
-+
-+	if (cpu_callout_map & ~MAX_CPU_MASK) {
-+		printk("kgdb : too many cpus, possibly not mapped"
-+		       " in contiguous space, change MAX_NO_CPUS"
-+		       " in kgdb_stub and make new kernel.\n"
-+		       " cpu_callout_map is %lx\n", cpu_callout_map);
-+		goto exit_just_unlock;
-+	}
-+
-+	if (spinlock_count == 1) {
-+		int time, end_time, dum;
-+		int i;
-+		int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
-+		};
-+		if (remote_debug) {
-+			printk("kgdb : cpu %d entry, syncing others\n",
-+			       smp_processor_id());
-+		}
-+		for (i = 0; i < MAX_NO_CPUS; i++) {
-+			/*
-+			 * Use trylock as we may already hold the lock if
-+			 * we are holding the cpu.  Net result is all
-+			 * locked.
-+			 */
-+			spin_trylock(&waitlocks[i]);
-+		}
-+		for (i = 0; i < MAX_NO_CPUS; i++)
-+			cpu_logged_in[i] = 0;
-+		/*
-+		 * Wait for their arrival.  We know the watch dog is active if 
-+		 * in_kgdb() has ever been called, as it is always called on a 
-+		 * watchdog tick.
-+		 */
-+		rdtsc(dum, time);
-+		end_time = time + 2;	/* Note: we use the High order bits! */
-+		i = 1;
-+		if (num_online_cpus() > 1) {
-+			int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
-+			smp_send_nmi_allbutself();
-+			while (i < num_online_cpus() && time != end_time) {
-+				int j;
-+				for (j = 0; j < MAX_NO_CPUS; j++) {
-+					if (waiting_cpus[j].task &&
-+					    !cpu_logged_in[j]) {
-+						i++;
-+						cpu_logged_in[j] = 1;
-+						if (remote_debug) {
-+							printk
-+							    ("kgdb : cpu %d arrived at kgdb\n",
-+							     j);
-+						}
-+						break;
-+					} else if (!waiting_cpus[j].task &&
-+						   !cpu_online(j)) {
-+						waiting_cpus[j].task = NOCPU;
-+						cpu_logged_in[j] = 1;
-+						waiting_cpus[j].hold = 1;
-+						break;
-+					}
-+					if (!waiting_cpus[j].task &&
-+					    in_kgdb_here_log[j]) {
-+
-+						int wait = 100000;
-+						while (wait--) ;
-+						if (!waiting_cpus[j].task &&
-+						    in_kgdb_here_log[j]) {
-+							printk
-+							    ("kgdb : cpu %d stall"
-+							     " in in_kgdb\n",
-+							     j);
-+							i++;
-+							cpu_logged_in[j] = 1;
-+							waiting_cpus[j].task =
-+							    (struct task_struct
-+							     *) 1;
-+						}
-+					}
-+				}
-+
-+				if (in_kgdb_entry_log[smp_processor_id()] >
-+				    (me_in_kgdb + 10)) {
-+					break;
-+				}
-+
-+				rdtsc(dum, time);
-+			}
-+			if (i < num_online_cpus()) {
-+				printk
-+				    ("kgdb : time out, proceeding without sync\n");
-+#if 0
-+				printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
-+				       waiting_cpus[0].task != 0,
-+				       waiting_cpus[1].task != 0);
-+				printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
-+				       cpu_logged_in[0], cpu_logged_in[1]);
-+				printk
-+				    ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
-+				     in_kgdb_here_log[0] != 0,
-+				     in_kgdb_here_log[1] != 0);
-+#endif
-+				entry_state = NO_SYNC;
-+			} else {
-+#if 0
-+				int ent =
-+				    in_kgdb_entry_log[smp_processor_id()] -
-+				    me_in_kgdb;
-+				printk("kgdb : sync after %d entries\n", ent);
-+#endif
-+			}
-+		} else {
-+			if (remote_debug) {
-+				printk
-+				    ("kgdb : %d cpus, but watchdog not active\n"
-+				     "proceeding without locking down other cpus\n",
-+				     num_online_cpus());
-+				entry_state = NO_NMI;
-+			}
-+		}
-+	}
-+#endif
-+
-+	if (remote_debug) {
-+		unsigned long *lp = (unsigned long *) &linux_regs;
-+
-+		printk("handle_exception(exceptionVector=%d, "
-+		       "signo=%d, err_code=%d, linux_regs=%p)\n",
-+		       exceptionVector, signo, err_code, linux_regs);
-+		if (debug_regs) {
-+			print_regs(&regs);
-+			printk("Stk: %8lx %8lx %8lx %8lx"
-+			       "  %8lx %8lx %8lx %8lx\n",
-+			       lp[0], lp[1], lp[2], lp[3],
-+			       lp[4], lp[5], lp[6], lp[7]);
-+			printk("     %8lx %8lx %8lx %8lx"
-+			       "  %8lx %8lx %8lx %8lx\n",
-+			       lp[8], lp[9], lp[10], lp[11],
-+			       lp[12], lp[13], lp[14], lp[15]);
-+			printk("     %8lx %8lx %8lx %8lx  "
-+			       "%8lx %8lx %8lx %8lx\n",
-+			       lp[16], lp[17], lp[18], lp[19],
-+			       lp[20], lp[21], lp[22], lp[23]);
-+			printk("     %8lx %8lx %8lx %8lx  "
-+			       "%8lx %8lx %8lx %8lx\n",
-+			       lp[24], lp[25], lp[26], lp[27],
-+			       lp[28], lp[29], lp[30], lp[31]);
-+		}
-+	}
-+
-+	/* Disable hardware debugging while we are in kgdb */
-+	/* Get the debug register status register */
-+/*				       *INDENT-OFF*  */
-+      __asm__("movl %0,%%db7"
-+	      :	/* no output */
-+	      :"r"(0));
-+
-+	asm volatile ("movl %%db6, %0\n"
-+		      :"=r" (hw_breakpoint_status)
-+		      :);
-+
-+/*				       *INDENT-ON*  */
-+	switch (exceptionVector) {
-+	case 0:		/* divide error */
-+	case 1:		/* debug exception */
-+	case 2:		/* NMI */
-+	case 3:		/* breakpoint */
-+	case 4:		/* overflow */
-+	case 5:		/* bounds check */
-+	case 6:		/* invalid opcode */
-+	case 7:		/* device not available */
-+	case 8:		/* double fault (errcode) */
-+	case 10:		/* invalid TSS (errcode) */
-+	case 12:		/* stack fault (errcode) */
-+	case 16:		/* floating point error */
-+	case 17:		/* alignment check (errcode) */
-+	default:		/* any undocumented */
-+		break;
-+	case 11:		/* segment not present (errcode) */
-+	case 13:		/* general protection (errcode) */
-+	case 14:		/* page fault (special errcode) */
-+	case 19:		/* cache flush denied */
-+		if (mem_err_expected) {
-+			/*
-+			 * This fault occured because of the
-+			 * get_char or set_char routines.  These
-+			 * two routines use either eax of edx to
-+			 * indirectly reference the location in
-+			 * memory that they are working with.
-+			 * For a page fault, when we return the
-+			 * instruction will be retried, so we
-+			 * have to make sure that these
-+			 * registers point to valid memory. 
-+			 */
-+			mem_err = 1;	/* set mem error flag */
-+			mem_err_expected = 0;
-+			mem_err_cnt++;	/* helps in debugging */
-+			/* make valid address */
-+			regs.eax = (long) &garbage_loc;
-+			/* make valid address */
-+			regs.edx = (long) &garbage_loc;
-+			if (remote_debug)
-+				printk("Return after memory error: "
-+				       "mem_err_cnt=%d\n", mem_err_cnt);
-+			if (debug_regs)
-+				print_regs(&regs);
-+			goto exit_kgdb;
-+		}
-+		break;
-+	}
-+	if (remote_debug)
-+		printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
-+
-+	gdb_i386vector = exceptionVector;
-+	gdb_i386errcode = err_code;
-+	kgdb_info.called_from = __builtin_return_address(0);
-+#ifdef CONFIG_SMP
-+	/*
-+	 * OK, we can now communicate, lets tell gdb about the sync.
-+	 * but only if we had a problem.
-+	 */
-+	switch (entry_state) {
-+	case NO_NMI:
-+		to_gdb("NMI not active, other cpus not stopped\n");
-+		break;
-+	case NO_SYNC:
-+		to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
-+	default:;
-+	}
-+
-+#endif
-+/*
-+ * Set up the gdb function call area.
-+ */
-+	trap_cpu = smp_processor_id();
-+	OLD_esp = NEW_esp = (int) (&linux_regs->esp);
-+
-+      IF_SMP(once_again:)
-+	    /* reply to host that an exception has occurred */
-+	    remcomOutBuffer[0] = 'S';
-+	remcomOutBuffer[1] = hexchars[signo >> 4];
-+	remcomOutBuffer[2] = hexchars[signo % 16];
-+	remcomOutBuffer[3] = 0;
-+
-+	putpacket(remcomOutBuffer);
-+
-+	while (1 == 1) {
-+		error = 0;
-+		remcomOutBuffer[0] = 0;
-+		getpacket(remcomInBuffer);
-+		switch (remcomInBuffer[0]) {
-+		case '?':
-+			remcomOutBuffer[0] = 'S';
-+			remcomOutBuffer[1] = hexchars[signo >> 4];
-+			remcomOutBuffer[2] = hexchars[signo % 16];
-+			remcomOutBuffer[3] = 0;
-+			break;
-+		case 'd':
-+			remote_debug = !(remote_debug);	/* toggle debug flag */
-+			printk("Remote debug %s\n",
-+			       remote_debug ? "on" : "off");
-+			break;
-+		case 'g':	/* return the value of the CPU registers */
-+			get_gdb_regs(usethread, &regs, gdb_regs);
-+			mem2hex((char *) gdb_regs,
-+				remcomOutBuffer, NUMREGBYTES, 0);
-+			break;
-+		case 'G':	/* set the value of the CPU registers - return OK */
-+			hex2mem(&remcomInBuffer[1],
-+				(char *) gdb_regs, NUMREGBYTES, 0);
-+			if (!usethread || usethread == current) {
-+				gdb_regs_to_regs(gdb_regs, &regs);
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "E00");
-+			}
-+			break;
-+
-+		case 'P':{	/* set the value of a single CPU register - 
-+				   return OK */
-+				/*
-+				 * For some reason, gdb wants to talk about psudo
-+				 * registers (greater than 15).	 These may have
-+				 * meaning for ptrace, but for us it is safe to
-+				 * ignor them.	We do this by dumping them into
-+				 * _GS which we also ignor, but do have memory for.
-+				 */
-+				int regno;
-+
-+				ptr = &remcomInBuffer[1];
-+				regs_to_gdb_regs(gdb_regs, &regs);
-+				if ((!usethread || usethread == current) &&
-+				    hexToInt(&ptr, &regno) &&
-+				    *ptr++ == '=' && (regno >= 0)) {
-+					regno =
-+					    (regno >= NUMREGS ? _GS : regno);
-+					hex2mem(ptr, (char *) &gdb_regs[regno],
-+						4, 0);
-+					gdb_regs_to_regs(gdb_regs, &regs);
-+					strcpy(remcomOutBuffer, "OK");
-+					break;
-+				}
-+				strcpy(remcomOutBuffer, "E01");
-+				break;
-+			}
-+
-+			/* mAA..AA,LLLL	 Read LLLL bytes at address AA..AA */
-+		case 'm':
-+			/* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr) &&
-+			    (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
-+				ptr = 0;
-+				/*
-+				 * hex doubles the byte count
-+				 */
-+				if (length > (BUFMAX / 2))
-+					length = BUFMAX / 2;
-+				mem2hex((char *) addr,
-+					remcomOutBuffer, length, 1);
-+				if (mem_err) {
-+					strcpy(remcomOutBuffer, "E03");
-+					debug_error("memory fault\n", NULL);
-+				}
-+			}
-+
-+			if (ptr) {
-+				strcpy(remcomOutBuffer, "E01");
-+				debug_error
-+				    ("malformed read memory command: %s\n",
-+				     remcomInBuffer);
-+			}
-+			break;
-+
-+			/* MAA..AA,LLLL: 
-+			   Write LLLL bytes at address AA.AA return OK */
-+		case 'M':
-+			/* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr) &&
-+			    (*(ptr++) == ',') &&
-+			    (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
-+				hex2mem(ptr, (char *) addr, length, 1);
-+
-+				if (mem_err) {
-+					strcpy(remcomOutBuffer, "E03");
-+					debug_error("memory fault\n", NULL);
-+				} else {
-+					strcpy(remcomOutBuffer, "OK");
-+				}
-+
-+				ptr = 0;
-+			}
-+			if (ptr) {
-+				strcpy(remcomOutBuffer, "E02");
-+				debug_error
-+				    ("malformed write memory command: %s\n",
-+				     remcomInBuffer);
-+			}
-+			break;
-+
-+			/* cAA..AA  Continue at address AA..AA(optional) */
-+			/* sAA..AA  Step one instruction from AA..AA(optional) */
-+			/* D	    detach, reply OK and then continue */
-+		case 'c':
-+		case 's':
-+		case 'D':
-+
-+			/* try to read optional parameter, 
-+			   pc unchanged if no parm */
-+			ptr = &remcomInBuffer[1];
-+			if (hexToInt(&ptr, &addr)) {
-+				if (remote_debug)
-+					printk("Changing EIP to 0x%x\n", addr);
-+
-+				regs.eip = addr;
-+			}
-+
-+			newPC = regs.eip;
-+
-+			/* clear the trace bit */
-+			regs.eflags &= 0xfffffeff;
-+
-+			/* set the trace bit if we're stepping */
-+			if (remcomInBuffer[0] == 's')
-+				regs.eflags |= 0x100;
-+
-+			/* detach is a friendly version of continue. Note that
-+			   debugging is still enabled (e.g hit control C)
-+			   until the process that issued an ioctl TIOCGDB
-+			   terminates
-+			 */
-+			if (remcomInBuffer[0] == 'D') {
-+				strcpy(remcomOutBuffer, "OK");
-+				putpacket(remcomOutBuffer);
-+			}
-+
-+			if (remote_debug) {
-+				printk("Resuming execution\n");
-+				print_regs(&regs);
-+			}
-+			asm volatile ("movl %%db6, %0\n":"=r" (dr6)
-+				      :);
-+			if (!(dr6 & 0x4000)) {
-+				for (breakno = 0; breakno < 4; ++breakno) {
-+					if (dr6 & (1 << breakno) &&
-+					    (breakinfo[breakno].type == 0)) {
-+						/* Set restore flag */
-+						regs.eflags |= 0x10000;
-+						break;
-+					}
-+				}
-+			}
-+			correct_hw_break();
-+			asm volatile ("movl %0, %%db6\n"::"r" (0));
-+			goto exit_kgdb;
-+
-+			/* kill the program */
-+		case 'k':	/* do nothing */
-+			break;
-+
-+			/* query */
-+		case 'q':
-+			switch (remcomInBuffer[1]) {
-+			case 'L':
-+				/* List threads */
-+				thread_list = 2;
-+				thread_list_start = (usethread ? : current);
-+				unpack_byte(remcomInBuffer + 3, &maxthreads);
-+				unpack_threadid(remcomInBuffer + 5, &thref);
-+				do {
-+					int buf_thread_limit =
-+					    (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
-+					if (maxthreads > buf_thread_limit) {
-+						maxthreads = buf_thread_limit;
-+					}
-+				} while (0);
-+				remcomOutBuffer[0] = 'q';
-+				remcomOutBuffer[1] = 'M';
-+				remcomOutBuffer[4] = '0';
-+				pack_threadid(remcomOutBuffer + 5, &thref);
-+
-+				threadid = threadref_to_int(&thref);
-+				for (nothreads = 0;
-+				     nothreads < maxthreads &&
-+				     threadid < PID_MAX + MAX_NO_CPUS;
-+				     threadid++) {
-+					thread = getthread(threadid);
-+					if (thread) {
-+						int_to_threadref(&thref,
-+								 threadid);
-+						pack_threadid(remcomOutBuffer +
-+							      21 +
-+							      nothreads * 16,
-+							      &thref);
-+						nothreads++;
-+						if (thread_min > threadid)
-+							thread_min = threadid;
-+					}
-+				}
-+
-+				if (threadid == PID_MAX + MAX_NO_CPUS) {
-+					remcomOutBuffer[4] = '1';
-+				}
-+				pack_hex_byte(remcomOutBuffer + 2, nothreads);
-+				remcomOutBuffer[21 + nothreads * 16] = '\0';
-+				break;
-+
-+			case 'C':
-+				/* Current thread id */
-+				remcomOutBuffer[0] = 'Q';
-+				remcomOutBuffer[1] = 'C';
-+				threadid = current->pid;
-+				if (!threadid) {
-+					/*
-+					 * idle thread
-+					 */
-+					for (threadid = PID_MAX;
-+					     threadid < PID_MAX + MAX_NO_CPUS;
-+					     threadid++) {
-+						if (current ==
-+						    idle_task(threadid -
-+							      PID_MAX))
-+							break;
-+					}
-+				}
-+				int_to_threadref(&thref, threadid);
-+				pack_threadid(remcomOutBuffer + 2, &thref);
-+				remcomOutBuffer[18] = '\0';
-+				break;
-+
-+			case 'E':
-+				/* Print exception info */
-+				printexceptioninfo(exceptionVector,
-+						   err_code, remcomOutBuffer);
-+				break;
-+			}
-+			break;
-+
-+			/* task related */
-+		case 'H':
-+			switch (remcomInBuffer[1]) {
-+			case 'g':
-+				ptr = &remcomInBuffer[2];
-+				hexToInt(&ptr, &threadid);
-+				thread = getthread(threadid);
-+				if (!thread) {
-+					remcomOutBuffer[0] = 'E';
-+					remcomOutBuffer[1] = '\0';
-+					break;
-+				}
-+				/*
-+				 * Just in case I forget what this is all about,
-+				 * the "thread info" command to gdb causes it
-+				 * to ask for a thread list.  It then switches
-+				 * to each thread and asks for the registers.
-+				 * For this (and only this) usage, we want to
-+				 * fudge the registers of tasks not on the run
-+				 * list (i.e. waiting) to show the routine that
-+				 * called schedule. Also, gdb, is a minimalist
-+				 * in that if the current thread is the last
-+				 * it will not re-read the info when done.
-+				 * This means that in this case we must show
-+				 * the real registers. So here is how we do it:
-+				 * Each entry we keep track of the min
-+				 * thread in the list (the last that gdb will)
-+				 * get info for.  We also keep track of the
-+				 * starting thread.
-+				 * "thread_list" is cleared when switching back
-+				 * to the min thread if it is was current, or
-+				 * if it was not current, thread_list is set 
-+				 * to 1.  When the switch to current comes,
-+				 * if thread_list is 1, clear it, else do 
-+				 * nothing.
-+				 */
-+				usethread = thread;
-+				if ((thread_list == 1) &&
-+				    (thread == thread_list_start)) {
-+					thread_list = 0;
-+				}
-+				if (thread_list && (threadid == thread_min)) {
-+					if (thread == thread_list_start) {
-+						thread_list = 0;
-+					} else {
-+						thread_list = 1;
-+					}
-+				}
-+				/* follow through */
-+			case 'c':
-+				remcomOutBuffer[0] = 'O';
-+				remcomOutBuffer[1] = 'K';
-+				remcomOutBuffer[2] = '\0';
-+				break;
-+			}
-+			break;
-+
-+			/* Query thread status */
-+		case 'T':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &threadid);
-+			thread = getthread(threadid);
-+			if (thread) {
-+				remcomOutBuffer[0] = 'O';
-+				remcomOutBuffer[1] = 'K';
-+				remcomOutBuffer[2] = '\0';
-+				if (thread_min > threadid)
-+					thread_min = threadid;
-+			} else {
-+				remcomOutBuffer[0] = 'E';
-+				remcomOutBuffer[1] = '\0';
-+			}
-+			break;
-+
-+		case 'Y':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &breakno);
-+			ptr++;
-+			hexToInt(&ptr, &breaktype);
-+			ptr++;
-+			hexToInt(&ptr, &length);
-+			ptr++;
-+			hexToInt(&ptr, &addr);
-+			if (set_hw_break(breakno & 0x3,
-+					 breaktype & 0x3,
-+					 length & 0x3, addr) == 0) {
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "ERROR");
-+			}
-+			break;
-+
-+			/* Remove hardware breakpoint */
-+		case 'y':
-+			ptr = &remcomInBuffer[1];
-+			hexToInt(&ptr, &breakno);
-+			if (remove_hw_break(breakno & 0x3) == 0) {
-+				strcpy(remcomOutBuffer, "OK");
-+			} else {
-+				strcpy(remcomOutBuffer, "ERROR");
-+			}
-+			break;
-+
-+		case 'r':	/* reboot */
-+			strcpy(remcomOutBuffer, "OK");
-+			putpacket(remcomOutBuffer);
-+			/*to_gdb("Rebooting\n"); */
-+			/* triplefault	 no return from here */
-+			{
-+				static long no_idt[2];
-+				__asm__ __volatile__("lidt %0"::"m"(no_idt));
-+				BREAKPOINT;
-+			}
-+
-+		}		/* switch */
-+
-+		/* reply to the request */
-+		putpacket(remcomOutBuffer);
-+	}			/* while(1==1) */
-+	/*
-+	 *  reached by goto only.
-+	 */
-+      exit_kgdb:
-+	/*
-+	 * Here is where we set up to trap a gdb function call.	 NEW_esp
-+	 * will be changed if we are trying to do this.	 We handle both
-+	 * adding and subtracting, thus allowing gdb to put grung on 
-+	 * the stack which it removes later.
-+	 */
-+	if (NEW_esp != OLD_esp) {
-+		int *ptr = END_OF_LOOKASIDE;
-+		if (NEW_esp < OLD_esp)
-+			ptr -= (OLD_esp - NEW_esp) / sizeof (int);
-+		*--ptr = linux_regs->eflags;
-+		*--ptr = linux_regs->xcs;
-+		*--ptr = linux_regs->eip;
-+		*--ptr = linux_regs->ecx;
-+		*--ptr = linux_regs->ebx;
-+		*--ptr = linux_regs->eax;
-+		linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
-+		linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
-+		if (NEW_esp < OLD_esp) {
-+			linux_regs->eip = (unsigned int) fn_call_stub;
-+		} else {
-+			linux_regs->eip = (unsigned int) fn_rtn_stub;
-+			linux_regs->eax = NEW_esp;
-+		}
-+		linux_regs->eflags &= ~(IF_BIT | TF_BIT);
-+	}
-+#ifdef CONFIG_SMP
-+	/*
-+	 * Release gdb wait locks 
-+	 * Sanity check time.  Must have at least one cpu to run.  Also single
-+	 * step must not be done if the current cpu is on hold.
-+	 */
-+	if (spinlock_count == 1) {
-+		int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
-+		int cpu_avail = 0;
-+		int i;
-+
-+		for (i = 0; i < MAX_NO_CPUS; i++) {
-+			if (!cpu_online(i))
-+				break;
-+			if (!hold_cpu(i)) {
-+				cpu_avail = 1;
-+			}
-+		}
-+		/*
-+		 * Early in the bring up there will be NO cpus on line...
-+		 */
-+		if (!cpu_avail && cpu_online_map) {
-+			to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
-+			goto once_again;
-+		}
-+		if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
-+			to_gdb
-+			    ("Current cpu must be unblocked to single step\n");
-+			goto once_again;
-+		}
-+		if (!(ss_hold)) {
-+			int i;
-+			for (i = 0; i < MAX_NO_CPUS; i++) {
-+				if (!hold_cpu(i)) {
-+					spin_unlock(&waitlocks[i]);
-+				}
-+			}
-+		} else {
-+			spin_unlock(&waitlocks[smp_processor_id()]);
-+		}
-+		/* Release kgdb spinlock */
-+		KGDB_SPIN_UNLOCK(&kgdb_spinlock);
-+		/*
-+		 * If this cpu is on hold, this is where we
-+		 * do it.  Note, the NMI will pull us out of here,
-+		 * but will return as the above lock is not held.
-+		 * We will stay here till another cpu releases the lock for us.
-+		 */
-+		spin_unlock_wait(waitlocks + smp_processor_id());
-+		kgdb_local_irq_restore(flags);
-+		return (0);
-+	}
-+      exit_just_unlock:
-+#endif
-+	/* Release kgdb spinlock */
-+	KGDB_SPIN_UNLOCK(&kgdb_spinlock);
-+	kgdb_local_irq_restore(flags);
-+	return (0);
-+}
-+
-+/* this function is used to set up exception handlers for tracing and
-+ * breakpoints. 
-+ * This function is not needed as the above line does all that is needed.
-+ * We leave it for backward compatitability...
-+ */
-+void
-+set_debug_traps(void)
-+{
-+	/*
-+	 * linux_debug_hook is defined in traps.c.  We store a pointer
-+	 * to our own exception handler into it.
-+
-+	 * But really folks, every hear of labeled common, an old Fortran
-+	 * concept.  Lots of folks can reference it and it is define if 
-+	 * anyone does.	 Only one can initialize it at link time.  We do 
-+	 * this with the hook.	See the statement above.  No need for any
-+	 * executable code and it is ready as soon as the kernel is
-+	 * loaded.  Very desirable in kernel debugging.
-+
-+	 linux_debug_hook = handle_exception ;
-+	 */
-+
-+	/* In case GDB is started before us, ack any packets (presumably
-+	   "$?#xx") sitting there. 
-+	   putDebugChar ('+');
-+
-+	   initialized = 1;
-+	 */
-+}
-+
-+/* This function will generate a breakpoint exception.	It is used at the
-+   beginning of a program to sync up with a debugger and can be used
-+   otherwise as a quick means to stop program execution and "break" into
-+   the debugger. */
-+/* But really, just use the BREAKPOINT macro.  We will handle the int stuff
-+ */
-+
-+#ifdef later
-+/*
-+ * possibly we should not go thru the traps.c code at all?  Someday.
-+ */
-+void
-+do_kgdb_int3(struct pt_regs *regs, long error_code)
-+{
-+	kgdb_handle_exception(3, 5, error_code, regs);
-+	return;
-+}
-+#endif
-+#undef regs
-+#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-+asmlinkage void
-+bad_sys_call_exit(int stuff)
-+{
-+	struct pt_regs *regs = (struct pt_regs *) &stuff;
-+	printk("Sys call %d return with %x preempt_count\n",
-+	       (int) regs->orig_eax, preempt_count());
-+}
-+#endif
-+#ifdef CONFIG_STACK_OVERFLOW_TEST
-+#include <asm/kgdb.h>
-+asmlinkage void
-+stack_overflow(void)
-+{
-+#ifdef BREAKPOINT
-+	BREAKPOINT;
-+#else
-+	printk("Kernel stack overflow, looping forever\n");
-+#endif
-+	while (1) {
-+	}
-+}
-+#endif
-+
-+#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
-+char gdbconbuf[BUFMAX];
-+
-+static void
-+kgdb_gdb_message(const char *s, unsigned count)
-+{
-+	int i;
-+	int wcount;
-+	char *bufptr;
-+	/*
-+	 * This takes care of NMI while spining out chars to gdb
-+	 */
-+	IF_SMP(in_kgdb_console = 1);
-+	gdbconbuf[0] = 'O';
-+	bufptr = gdbconbuf + 1;
-+	while (count > 0) {
-+		if ((count << 1) > (BUFMAX - 2)) {
-+			wcount = (BUFMAX - 2) >> 1;
-+		} else {
-+			wcount = count;
-+		}
-+		count -= wcount;
-+		for (i = 0; i < wcount; i++) {
-+			bufptr = pack_hex_byte(bufptr, s[i]);
-+		}
-+		*bufptr = '\0';
-+		s += wcount;
-+
-+		putpacket(gdbconbuf);
-+
-+	}
-+	IF_SMP(in_kgdb_console = 0);
-+}
-+#endif
-+#ifdef CONFIG_SMP
-+static void
-+to_gdb(const char *s)
-+{
-+	int count = 0;
-+	while (s[count] && (count++ < BUFMAX)) ;
-+	kgdb_gdb_message(s, count);
-+}
-+#endif
-+#ifdef CONFIG_KGDB_CONSOLE
-+#include <linux/console.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+void
-+kgdb_console_write(struct console *co, const char *s, unsigned count)
-+{
-+
-+	if (gdb_i386vector == -1) {
-+		/*
-+		 * We have not yet talked to gdb.  What to do...
-+		 * lets break, on continue we can do the write.
-+		 * But first tell him whats up. Uh, well no can do,
-+		 * as this IS the console.  Oh well...
-+		 * We do need to wait or the messages will be lost.
-+		 * Other option would be to tell the above code to
-+		 * ignore this breakpoint and do an auto return, 
-+		 * but that might confuse gdb.	Also this happens 
-+		 * early enough in boot up that we don't have the traps
-+		 * set up yet, so...
-+		 */
-+		breakpoint();
-+	}
-+	kgdb_gdb_message(s, count);
-+}
-+
-+/*
-+ * ------------------------------------------------------------
-+ * Serial KGDB driver 
-+ * ------------------------------------------------------------
-+ */
-+
-+static struct console kgdbcons = {
-+	name:"kgdb",
-+	write:kgdb_console_write,
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+	device:kgdb_console_device,
-+#endif
-+	flags:CON_PRINTBUFFER | CON_ENABLED,
-+	index:-1,
-+};
-+
-+/*
-+ * The trick here is that this file gets linked before printk.o
-+ * That means we get to peer at the console info in the command
-+ * line before it does.	 If we are up, we register, otherwise,
-+ * do nothing.	By returning 0, we allow printk to look also.
-+ */
-+static int kgdb_console_enabled;
-+
-+int __init
-+kgdb_console_init(char *str)
-+{
-+	if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
-+		register_console(&kgdbcons);
-+		kgdb_console_enabled = 1;
-+	}
-+	return 0;		/* let others look at the string */
-+}
-+
-+__setup("console=", kgdb_console_init);
-+
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+static kdev_t kgdb_console_device(struct console *c);
-+/* This stuff sort of works, but it knocks out telnet devices  
-+ * we are leaving it here in case we (or you) find time to figure it out
-+ * better..
-+ */
-+
-+/*
-+ * We need a real char device as well for when the console is opened for user
-+ * space activities.
-+ */
-+
-+static int
-+kgdb_consdev_open(struct inode *inode, struct file *file)
-+{
-+	return 0;
-+}
-+
-+static ssize_t
-+kgdb_consdev_write(struct file *file, const char *buf,
-+		   size_t count, loff_t * ppos)
-+{
-+	int size, ret = 0;
-+	static char kbuf[128];
-+	static DECLARE_MUTEX(sem);
-+
-+	/* We are not reentrant... */
-+	if (down_interruptible(&sem))
-+		return -ERESTARTSYS;
-+
-+	while (count > 0) {
-+		/* need to copy the data from user space */
-+		size = count;
-+		if (size > sizeof (kbuf))
-+			size = sizeof (kbuf);
-+		if (copy_from_user(kbuf, buf, size)) {
-+			ret = -EFAULT;
-+			break;;
-+		}
-+		kgdb_console_write(&kgdbcons, kbuf, size);
-+		count -= size;
-+		ret += size;
-+		buf += size;
-+	}
-+
-+	up(&sem);
-+
-+	return ret;
-+}
-+
-+struct file_operations kgdb_consdev_fops = {
-+	open:kgdb_consdev_open,
-+	write:kgdb_consdev_write
-+};
-+static kdev_t
-+kgdb_console_device(struct console *c)
-+{
-+	return MKDEV(TTYAUX_MAJOR, 1);
-+}
-+
-+/*
-+ * This routine gets called from the serial stub in the i386/lib 
-+ * This is so it is done late in bring up (just before the console open).
-+ */
-+void
-+kgdb_console_finit(void)
-+{
-+	if (kgdb_console_enabled) {
-+		char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
-+		char *cp = cptr;
-+		while (*cptr && *cptr != '(')
-+			cptr++;
-+		*cptr = 0;
-+		unregister_chrdev(TTYAUX_MAJOR, cp);
-+		register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
-+	}
-+}
-+#endif
-+#endif
-+#ifdef CONFIG_KGDB_TS
-+#include <asm/msr.h>		/* time stamp code */
-+#include <asm/hardirq.h>	/* in_interrupt */
-+#ifdef CONFIG_KGDB_TS_64
-+#define DATA_POINTS 64
-+#endif
-+#ifdef CONFIG_KGDB_TS_128
-+#define DATA_POINTS 128
-+#endif
-+#ifdef CONFIG_KGDB_TS_256
-+#define DATA_POINTS 256
-+#endif
-+#ifdef CONFIG_KGDB_TS_512
-+#define DATA_POINTS 512
-+#endif
-+#ifdef CONFIG_KGDB_TS_1024
-+#define DATA_POINTS 1024
-+#endif
-+#ifndef DATA_POINTS
-+#define DATA_POINTS 128		/* must be a power of two */
-+#endif
-+#define INDEX_MASK (DATA_POINTS - 1)
-+#if (INDEX_MASK & DATA_POINTS)
-+#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
-+#endif
-+struct kgdb_and_then_struct {
-+#ifdef CONFIG_SMP
-+	int on_cpu;
-+#endif
-+	struct task_struct *task;
-+	long long at_time;
-+	int from_ln;
-+	char *in_src;
-+	void *from;
-+	int *with_shpf;
-+	int data0;
-+	int data1;
-+};
-+struct kgdb_and_then_struct2 {
-+#ifdef CONFIG_SMP
-+	int on_cpu;
-+#endif
-+	struct task_struct *task;
-+	long long at_time;
-+	int from_ln;
-+	char *in_src;
-+	void *from;
-+	int *with_shpf;
-+	struct task_struct *t1;
-+	struct task_struct *t2;
-+};
-+struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
-+
-+struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
-+int kgdb_and_then_count;
-+
-+void
-+kgdb_tstamp(int line, char *source, int data0, int data1)
-+{
-+	static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
-+	int flags;
-+	kgdb_local_irq_save(flags);
-+	spin_lock(&ts_spin);
-+	rdtscll(kgdb_and_then->at_time);
-+#ifdef CONFIG_SMP
-+	kgdb_and_then->on_cpu = smp_processor_id();
-+#endif
-+	kgdb_and_then->task = current;
-+	kgdb_and_then->from_ln = line;
-+	kgdb_and_then->in_src = source;
-+	kgdb_and_then->from = __builtin_return_address(0);
-+	kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
-+					    (preempt_count() << 8));
-+	kgdb_and_then->data0 = data0;
-+	kgdb_and_then->data1 = data1;
-+	kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
-+	spin_unlock(&ts_spin);
-+	kgdb_local_irq_restore(flags);
-+#ifdef CONFIG_PREEMPT
-+
-+#endif
-+	return;
-+}
-+#endif
-+typedef int gdb_debug_hook(int exceptionVector,
-+			   int signo, int err_code, struct pt_regs *linux_regs);
-+gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;	/* histerical reasons... */
-diff -puN arch/i386/kernel/Makefile~kgdb-ga arch/i386/kernel/Makefile
---- 25/arch/i386/kernel/Makefile~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/Makefile	2003-06-25 23:14:17.000000000 -0700
-@@ -14,6 +14,7 @@ obj-y				+= timers/
- obj-$(CONFIG_ACPI)		+= acpi/
- obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
- obj-$(CONFIG_MCA)		+= mca.o
-+obj-$(CONFIG_KGDB)		+= kgdb_stub.o 
- obj-$(CONFIG_X86_MSR)		+= msr.o
- obj-$(CONFIG_X86_CPUID)		+= cpuid.o
- obj-$(CONFIG_MICROCODE)		+= microcode.o
-diff -puN arch/i386/kernel/nmi.c~kgdb-ga arch/i386/kernel/nmi.c
---- 25/arch/i386/kernel/nmi.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/nmi.c	2003-06-25 23:14:17.000000000 -0700
-@@ -31,7 +31,17 @@
- #include <asm/mpspec.h>
- #include <asm/nmi.h>
- 
-+#ifdef CONFIG_KGDB
-+#include <asm/kgdb.h>
-+#ifdef CONFIG_SMP
-+unsigned int nmi_watchdog = NMI_IO_APIC;
-+#else
-+unsigned int nmi_watchdog = NMI_LOCAL_APIC;
-+#endif
-+#else
- unsigned int nmi_watchdog = NMI_NONE;
-+#endif
-+
- static unsigned int nmi_hz = HZ;
- unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
- extern void show_registers(struct pt_regs *regs);
-@@ -398,6 +408,9 @@ void touch_nmi_watchdog (void)
- 	for (i = 0; i < NR_CPUS; i++)
- 		alert_counter[i] = 0;
- }
-+#ifdef CONFIG_KGDB
-+int tune_watchdog = 5*HZ;
-+#endif
- 
- void nmi_watchdog_tick (struct pt_regs * regs)
- {
-@@ -411,12 +424,24 @@ void nmi_watchdog_tick (struct pt_regs *
- 
- 	sum = irq_stat[cpu].apic_timer_irqs;
- 
-+#ifdef CONFIG_KGDB
-+ 	if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
-+  
-+#else
- 	if (last_irq_sums[cpu] == sum) {
-+#endif
- 		/*
- 		 * Ayiee, looks like this CPU is stuck ...
- 		 * wait a few IRQs (5 seconds) before doing the oops ...
- 		 */
- 		alert_counter[cpu]++;
-+#ifdef CONFIG_KGDB
-+                if (alert_counter[cpu] == tune_watchdog) {                      
-+                        kgdb_handle_exception(2, SIGPWR, 0, regs);
-+                        last_irq_sums[cpu] = sum;
-+                        alert_counter[cpu] = 0;
-+                }
-+#endif
- 		if (alert_counter[cpu] == 5*nmi_hz) {
- 			spin_lock(&nmi_print_lock);
- 			/*
-diff -puN arch/i386/kernel/smp.c~kgdb-ga arch/i386/kernel/smp.c
---- 25/arch/i386/kernel/smp.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/smp.c	2003-06-25 23:14:17.000000000 -0700
-@@ -459,7 +459,17 @@ void smp_send_reschedule(int cpu)
- {
- 	send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
- }
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * By using the NMI code instead of a vector we just sneak thru the 
-+ * word generator coming out with just what we want.  AND it does
-+ * not matter if clustered_apic_mode is set or not.
-+ */
-+void smp_send_nmi_allbutself(void)
-+{
-+	send_IPI_allbutself(APIC_DM_NMI);
-+}
-+#endif
- /*
-  * Structure and data for smp_call_function(). This is designed to minimise
-  * static memory requirements. It also looks cleaner.
-diff -puN arch/i386/kernel/traps.c~kgdb-ga arch/i386/kernel/traps.c
---- 25/arch/i386/kernel/traps.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/kernel/traps.c	2003-06-25 23:14:17.000000000 -0700
-@@ -90,6 +90,42 @@ asmlinkage void alignment_check(void);
- asmlinkage void spurious_interrupt_bug(void);
- asmlinkage void machine_check(void);
- 
-+#ifdef CONFIG_KGDB
-+extern void sysenter_entry(void);
-+#include <asm/kgdb.h>
-+#include <linux/init.h>
-+extern void int3(void);
-+extern void debug(void);
-+void set_intr_gate(unsigned int n, void *addr);
-+static void set_intr_usr_gate(unsigned int n, void *addr);
-+/*
-+ * Should be able to call this breakpoint() very early in
-+ * bring up.  Just hard code the call where needed.
-+ * The breakpoint() code is here because set_?_gate() functions
-+ * are local (static) to trap.c.  They need be done only once,
-+ * but it does not hurt to do them over.
-+ */
-+void breakpoint(void)
-+{
-+        set_intr_usr_gate(3,&int3); /* disable ints on trap */
-+	set_intr_gate(1,&debug);
-+	set_intr_gate(14,&page_fault);
-+       
-+        BREAKPOINT;
-+}
-+#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)		\
-+    {									\
-+	if (!user_mode(regs)  ) \
-+	{								\
-+		kgdb_handle_exception(trapnr, signr, error_code, regs);	\
-+		after;							\
-+	} else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
-+    }
-+#else
-+#define	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)	
-+#endif
-+
-+
- static int kstack_depth_to_print = 24;
- 
- void show_trace(struct task_struct *task, unsigned long * stack)
-@@ -258,6 +294,15 @@ void die(const char * str, struct pt_reg
- 	bust_spinlocks(1);
- 	handle_BUG(regs);
- 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-+#ifdef CONFIG_KGDB
-+	/* This is about the only place we want to go to kgdb even if in 
-+	 * user mode.  But we must go in via a trap so within kgdb we will
-+	 * always be in kernel mode.
-+	 */
-+	if (user_mode(regs))
-+		BREAKPOINT;
-+#endif
-+ 	CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
- 	show_registers(regs);
- 	bust_spinlocks(0);
- 	spin_unlock_irq(&die_lock);
-@@ -327,6 +372,7 @@ static inline void do_trap(int trapnr, i
- #define DO_ERROR(trapnr, signr, str, name) \
- asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
- { \
-+	CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
- 	do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
- }
- 
-@@ -344,7 +390,9 @@ asmlinkage void do_##name(struct pt_regs
- #define DO_VM86_ERROR(trapnr, signr, str, name) \
- asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
- { \
-+	CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
- 	do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
-+	return; \
- }
- 
- #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-@@ -387,8 +435,10 @@ gp_in_vm86:
- 	return;
- 
- gp_in_kernel:
--	if (!fixup_exception(regs))
-+	if (!fixup_exception(regs)){
-+ 		CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
- 		die("general protection fault", regs, error_code);
-+	}
- }
- 
- static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
-@@ -550,8 +600,18 @@ asmlinkage void do_debug(struct pt_regs 
- 		 * allowing programs to debug themselves without the ptrace()
- 		 * interface.
- 		 */
--		if ((regs->xcs & 3) == 0)
-+#ifdef CONFIG_KGDB
-+		/*
-+		 * I think this is the only "real" case of a TF in the kernel
-+		 * that really belongs to user space.  Others are
-+		 * "Ours all ours!"
-+		 */
-+		if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
- 			goto clear_TF_reenable;
-+#else
-+		if ((regs->xcs & 3) == 0)	
-+			goto clear_TF_reenable;
-+#endif
- 		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
- 			goto clear_TF;
- 	}
-@@ -563,6 +623,17 @@ asmlinkage void do_debug(struct pt_regs 
- 	info.si_errno = 0;
- 	info.si_code = TRAP_BRKPT;
- 	
-+#ifdef CONFIG_KGDB
-+        /*
-+	 * If this is a kernel mode trap, we need to reset db7 to allow us
-+	 * to continue sanely ALSO skip the signal delivery 
-+         */
-+	if ((regs->xcs & 3) == 0)
-+		goto clear_dr7;
-+
-+        /* if not kernel, allow ints but only if they were on */ 
-+       if ( regs->eflags & 0x200) local_irq_enable(); 
-+#endif
- 	/* If this is a kernel mode trap, save the user PC on entry to 
- 	 * the kernel, that's what the debugger can make sense of.
- 	 */
-@@ -577,6 +648,7 @@ clear_dr7:
- 	__asm__("movl %0,%%db7"
- 		: /* no output */
- 		: "r" (0));
-+	CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
- 	return;
- 
- debug_vm86:
-@@ -823,6 +895,12 @@ static void __init set_call_gate(void *a
- {
- 	_set_gate(a,12,3,addr,__KERNEL_CS);
- }
-+#ifdef CONFIG_KGDB
-+void set_intr_usr_gate(unsigned int n, void *addr)
-+{
-+	_set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
-+}
-+#endif
- 
- static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
- {
-@@ -849,7 +927,11 @@ void __init trap_init(void)
- 	set_trap_gate(0,&divide_error);
- 	set_intr_gate(1,&debug);
- 	set_intr_gate(2,&nmi);
-+#ifndef CONFIG_KGDB
- 	set_system_gate(3,&int3);	/* int3-5 can be called from all */
-+#else
-+	set_intr_usr_gate(3,&int3);	/* int3-5 can be called from all */
-+#endif
- 	set_system_gate(4,&overflow);
- 	set_system_gate(5,&bounds);
- 	set_trap_gate(6,&invalid_op);
-diff -puN /dev/null arch/i386/lib/kgdb_serial.c
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/arch/i386/lib/kgdb_serial.c	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,485 @@
-+/*
-+ * Serial interface GDB stub
-+ *
-+ * Written (hacked together) by David Grothe (dave@gcom.com)
-+ * Modified to allow invokation early in boot see also
-+ * kgdb.h for instructions by George Anzinger(george@mvista.com)
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <linux/config.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/highmem.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/segment.h>
-+#include <asm/bitops.h>
-+#include <asm/system.h>
-+#include <asm/kgdb_local.h>
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+extern void kgdb_console_finit(void);
-+#endif
-+#define PRNT_off
-+#define TEST_EXISTANCE
-+#ifdef PRNT
-+#define dbprintk(s) printk s
-+#else
-+#define dbprintk(s)
-+#endif
-+#define TEST_INTERRUPT_off
-+#ifdef TEST_INTERRUPT
-+#define intprintk(s) printk s
-+#else
-+#define intprintk(s)
-+#endif
-+
-+#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
-+
-+#define	GDB_BUF_SIZE	512	/* power of 2, please */
-+
-+static char gdb_buf[GDB_BUF_SIZE];
-+static int gdb_buf_in_inx;
-+static atomic_t gdb_buf_in_cnt;
-+static int gdb_buf_out_inx;
-+
-+struct async_struct *gdb_async_info;
-+static int gdb_async_irq;
-+
-+#define outb_px(a,b) outb_p(b,a)
-+
-+static void program_uart(struct async_struct *info);
-+static void write_char(struct async_struct *info, int chr);
-+/*
-+ * Get a byte from the hardware data buffer and return it
-+ */
-+static int
-+read_data_bfr(struct async_struct *info)
-+{
-+	char it = inb_p(info->port + UART_LSR);
-+
-+	if (it & UART_LSR_DR)
-+		return (inb_p(info->port + UART_RX));
-+	/*
-+	 * If we have a framing error assume somebody messed with
-+	 * our uart.  Reprogram it and send '-' both ways...
-+	 */
-+	if (it & 0xc) {
-+		program_uart(info);
-+		write_char(info, '-');
-+		return ('-');
-+	}
-+	return (-1);
-+
-+}				/* read_data_bfr */
-+
-+/*
-+ * Get a char if available, return -1 if nothing available.
-+ * Empty the receive buffer first, then look at the interface hardware.
-+
-+ * Locking here is a bit of a problem.	We MUST not lock out communication
-+ * if we are trying to talk to gdb about a kgdb entry.	ON the other hand
-+ * we can loose chars in the console pass thru if we don't lock.  It is also
-+ * possible that we could hold the lock or be waiting for it when kgdb
-+ * NEEDS to talk.  Since kgdb locks down the world, it does not need locks.
-+ * We do, of course have possible issues with interrupting a uart operation,
-+ * but we will just depend on the uart status to help keep that straight.
-+
-+ */
-+static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
-+#ifdef CONFIG_SMP
-+extern spinlock_t kgdb_spinlock;
-+#endif
-+
-+static int
-+read_char(struct async_struct *info)
-+{
-+	int chr;
-+	unsigned long flags;
-+	local_irq_save(flags);
-+#ifdef CONFIG_SMP
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		spin_lock(&uart_interrupt_lock);
-+	}
-+#endif
-+	if (atomic_read(&gdb_buf_in_cnt) != 0) {	/* intr routine has q'd chars */
-+		chr = gdb_buf[gdb_buf_out_inx++];
-+		gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
-+		atomic_dec(&gdb_buf_in_cnt);
-+	} else {
-+		chr = read_data_bfr(info);
-+	}
-+#ifdef CONFIG_SMP
-+	if (!spin_is_locked(&kgdb_spinlock)) {
-+		spin_unlock(&uart_interrupt_lock);
-+	}
-+#endif
-+	local_irq_restore(flags);
-+	return (chr);
-+}
-+
-+/*
-+ * Wait until the interface can accept a char, then write it.
-+ */
-+static void
-+write_char(struct async_struct *info, int chr)
-+{
-+	while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
-+
-+	outb_p(chr, info->port + UART_TX);
-+
-+}				/* write_char */
-+
-+/*
-+ * Mostly we don't need a spinlock, but since the console goes
-+ * thru here with interrutps on, well, we need to catch those
-+ * chars.
-+ */
-+/*
-+ * This is the receiver interrupt routine for the GDB stub.
-+ * It will receive a limited number of characters of input
-+ * from the gdb  host machine and save them up in a buffer.
-+ *
-+ * When the gdb stub routine getDebugChar() is called it
-+ * draws characters out of the buffer until it is empty and
-+ * then reads directly from the serial port.
-+ *
-+ * We do not attempt to write chars from the interrupt routine
-+ * since the stubs do all of that via putDebugChar() which
-+ * writes one byte after waiting for the interface to become
-+ * ready.
-+ *
-+ * The debug stubs like to run with interrupts disabled since,
-+ * after all, they run as a consequence of a breakpoint in
-+ * the kernel.
-+ *
-+ * Perhaps someone who knows more about the tty driver than I
-+ * care to learn can make this work for any low level serial
-+ * driver.
-+ */
-+static irqreturn_t
-+gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+	struct async_struct *info;
-+	unsigned long flags;
-+
-+	info = gdb_async_info;
-+	if (!info || !info->tty || irq != gdb_async_irq)
-+		return IRQ_NONE;
-+
-+	local_irq_save(flags);
-+	spin_lock(&uart_interrupt_lock);
-+	do {
-+		int chr = read_data_bfr(info);
-+		intprintk(("Debug char on int: %x hex\n", chr));
-+		if (chr < 0)
-+			continue;
-+
-+		if (chr == 3) {	/* Ctrl-C means remote interrupt */
-+			BREAKPOINT;
-+			continue;
-+		}
-+
-+		if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
-+			/* buffer overflow tosses early char */
-+			read_char(info);
-+		}
-+		gdb_buf[gdb_buf_in_inx++] = chr;
-+		gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
-+	} while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
-+	spin_unlock(&uart_interrupt_lock);
-+	local_irq_restore(flags);
-+	return IRQ_HANDLED;
-+}				/* gdb_interrupt */
-+
-+/*
-+ * Just a NULL routine for testing.
-+ */
-+void
-+gdb_null(void)
-+{
-+}				/* gdb_null */
-+
-+/* These structure are filled in with values defined in asm/kgdb_local.h
-+ */
-+static struct serial_state state = SB_STATE;
-+static struct async_struct local_info = SB_INFO;
-+static int ok_to_enable_ints = 0;
-+static void kgdb_enable_ints_now(void);
-+
-+extern char *kgdb_version;
-+/*
-+ * Hook an IRQ for KGDB.
-+ *
-+ * This routine is called from putDebugChar, below.
-+ */
-+static int ints_disabled = 1;
-+int
-+gdb_hook_interrupt(struct async_struct *info, int verb)
-+{
-+	struct serial_state *state = info->state;
-+	unsigned long flags;
-+	int port;
-+#ifdef TEST_EXISTANCE
-+	int scratch, scratch2;
-+#endif
-+
-+	/* The above fails if memory managment is not set up yet. 
-+	 * Rather than fail the set up, just keep track of the fact
-+	 * and pick up the interrupt thing later.
-+	 */
-+	gdb_async_info = info;
-+	port = gdb_async_info->port;
-+	gdb_async_irq = state->irq;
-+	if (verb) {
-+		printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
-+		       kgdb_version,
-+		       port,
-+		       gdb_async_irq, gdb_async_info->state->custom_divisor);
-+	}
-+	local_irq_save(flags);
-+#ifdef TEST_EXISTANCE
-+	/* Existance test */
-+	/* Should not need all this, but just in case.... */
-+
-+	scratch = inb_p(port + UART_IER);
-+	outb_px(port + UART_IER, 0);
-+	outb_px(0xff, 0x080);
-+	scratch2 = inb_p(port + UART_IER);
-+	outb_px(port + UART_IER, scratch);
-+	if (scratch2) {
-+		printk
-+		    ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
-+		local_irq_restore(flags);
-+		return 1;	/* We failed; there's nothing here */
-+	}
-+	scratch2 = inb_p(port + UART_LCR);
-+	outb_px(port + UART_LCR, 0xBF);	/* set up for StarTech test */
-+	outb_px(port + UART_EFR, 0);	/* EFR is the same as FCR */
-+	outb_px(port + UART_LCR, 0);
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
-+	scratch = inb_p(port + UART_IIR) >> 6;
-+	if (scratch == 1) {
-+		printk("gdb_hook_interrupt: Undefined UART type!"
-+		       "  Not a UART! \n");
-+		local_irq_restore(flags);
-+		return 1;
-+	} else {
-+		dbprintk(("gdb_hook_interrupt: UART type "
-+			  "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
-+	}
-+	scratch = inb_p(port + UART_MCR);
-+	outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
-+	outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
-+	scratch2 = inb_p(port + UART_MSR) & 0xF0;
-+	outb_px(port + UART_MCR, scratch);
-+	if (scratch2 != 0x90) {
-+		printk("gdb_hook_interrupt: "
-+		       "Loop back test failed! Not a UART!\n");
-+		local_irq_restore(flags);
-+		return scratch2 + 1000;	/* force 0 to fail */
-+	}
-+#endif				/* test existance */
-+	program_uart(info);
-+	local_irq_restore(flags);
-+
-+	return (0);
-+
-+}				/* gdb_hook_interrupt */
-+
-+static void
-+program_uart(struct async_struct *info)
-+{
-+	int port = info->port;
-+
-+	(void) inb_p(port + UART_RX);
-+	outb_px(port + UART_IER, 0);
-+
-+	(void) inb_p(port + UART_RX);	/* serial driver comments say */
-+	(void) inb_p(port + UART_IIR);	/* this clears the interrupt regs */
-+	(void) inb_p(port + UART_MSR);
-+	outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
-+	outb_px(port + UART_DLL, info->state->custom_divisor & 0xff);	/* LS */
-+	outb_px(port + UART_DLM, info->state->custom_divisor >> 8);	/* MS  */
-+	outb_px(port + UART_MCR, info->MCR);
-+
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);	/* set fcr */
-+	outb_px(port + UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-+	outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1);	/* set fcr */
-+	if (!ints_disabled) {
-+		intprintk(("KGDB: Sending %d to port %x offset %d\n",
-+			   gdb_async_info->IER,
-+			   (int) gdb_async_info->port, UART_IER));
-+		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
-+	}
-+	return;
-+}
-+
-+/*
-+ * getDebugChar
-+ *
-+ * This is a GDB stub routine.	It waits for a character from the
-+ * serial interface and then returns it.  If there is no serial
-+ * interface connection then it returns a bogus value which will
-+ * almost certainly cause the system to hang.  In the 
-+ */
-+int kgdb_in_isr = 0;
-+int kgdb_in_lsr = 0;
-+extern spinlock_t kgdb_spinlock;
-+
-+/* Caller takes needed protections */
-+
-+int
-+getDebugChar(void)
-+{
-+	volatile int chr, dum, time, end_time;
-+
-+	dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
-+
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 0);
-+	}
-+	/* 
-+	 * This trick says if we wait a very long time and get
-+	 * no char, return the -1 and let the upper level deal
-+	 * with it.
-+	 */
-+	rdtsc(dum, time);
-+	end_time = time + 2;
-+	while (((chr = read_char(gdb_async_info)) == -1) &&
-+	       (end_time - time) > 0) {
-+		rdtsc(dum, time);
-+	};
-+	/*
-+	 * This covers our butts if some other code messes with
-+	 * our uart, hay, it happens :o)
-+	 */
-+	if (chr == -1)
-+		program_uart(gdb_async_info);
-+
-+	dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
-+	return (chr);
-+
-+}				/* getDebugChar */
-+
-+static int count = 3;
-+static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
-+
-+static int __init
-+kgdb_enable_ints(void)
-+{
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 1);
-+	}
-+	ok_to_enable_ints = 1;
-+	kgdb_enable_ints_now();
-+#ifdef CONFIG_KGDB_USER_CONSOLE
-+	kgdb_console_finit();
-+#endif
-+	return 0;
-+}
-+
-+#ifdef CONFIG_SERIAL_8250
-+void shutdown_for_kgdb(struct async_struct *gdb_async_info);
-+#endif
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+static inline int kgdb_mem_init_done(void)
-+{
-+	return highmem_start_page != NULL;
-+}
-+#else
-+static inline int kgdb_mem_init_done(void)
-+{
-+	return max_mapnr != 0;
-+}
-+#endif
-+
-+static void
-+kgdb_enable_ints_now(void)
-+{
-+	if (!spin_trylock(&one_at_atime))
-+		return;
-+	if (!ints_disabled)
-+		goto exit;
-+	if (kgdb_mem_init_done() &&
-+			ints_disabled) {	/* don't try till mem init */
-+#ifdef CONFIG_SERIAL_8250
-+		/*
-+		 * The ifdef here allows the system to be configured
-+		 * without the serial driver.
-+		 * Don't make it a module, however, it will steal the port
-+		 */
-+		shutdown_for_kgdb(gdb_async_info);
-+#endif
-+		ints_disabled = request_irq(gdb_async_info->state->irq,
-+					    gdb_interrupt,
-+					    IRQ_T(gdb_async_info),
-+					    "KGDB-stub", NULL);
-+		intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
-+	}
-+	if (!ints_disabled) {
-+		intprintk(("KGDB: Sending %d to port %x offset %d\n",
-+			   gdb_async_info->IER,
-+			   (int) gdb_async_info->port, UART_IER));
-+		outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
-+	}
-+      exit:
-+	spin_unlock(&one_at_atime);
-+}
-+
-+/*
-+ * putDebugChar
-+ *
-+ * This is a GDB stub routine.	It waits until the interface is ready
-+ * to transmit a char and then sends it.  If there is no serial
-+ * interface connection then it simply returns to its caller, having
-+ * pretended to send the char.	Caller takes needed protections.
-+ */
-+void
-+putDebugChar(int chr)
-+{
-+	dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
-+		  gdb_async_info->port,
-+		  chr,
-+		  chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
-+
-+	if (gdb_async_info == NULL) {
-+		gdb_hook_interrupt(&local_info, 0);
-+	}
-+
-+	write_char(gdb_async_info, chr);	/* this routine will wait */
-+	count = (chr == '#') ? 0 : count + 1;
-+	if ((count == 2)) {	/* try to enable after */
-+		if (ints_disabled & ok_to_enable_ints)
-+			kgdb_enable_ints_now();	/* try to enable after */
-+
-+		/* We do this a lot because, well we really want to get these
-+		 * interrupts.	The serial driver will clear these bits when it
-+		 * initializes the chip.  Every thing else it does is ok, 
-+		 * but this.
-+		 */
-+		if (!ints_disabled) {
-+			outb_px(gdb_async_info->port + UART_IER,
-+				gdb_async_info->IER);
-+		}
-+	}
-+
-+}				/* putDebugChar */
-+
-+module_init(kgdb_enable_ints);
-diff -puN arch/i386/lib/Makefile~kgdb-ga arch/i386/lib/Makefile
---- 25/arch/i386/lib/Makefile~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/lib/Makefile	2003-06-25 23:14:17.000000000 -0700
-@@ -9,4 +9,5 @@ lib-y = checksum.o delay.o \
- 
- lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
- lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
-+lib-$(CONFIG_KGDB) += kgdb_serial.o
- lib-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
-diff -puN arch/i386/Makefile~kgdb-ga arch/i386/Makefile
---- 25/arch/i386/Makefile~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/Makefile	2003-06-25 23:14:17.000000000 -0700
-@@ -85,6 +85,9 @@ mcore-$(CONFIG_X86_ES7000)	:= mach-es700
- # default subarch .h files
- mflags-y += -Iinclude/asm-i386/mach-default
- 
-+mflags-$(CONFIG_KGDB) += -g
-+mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
-+
- head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
- 
- libs-y 					+= arch/i386/lib/
-diff -puN arch/i386/mm/fault.c~kgdb-ga arch/i386/mm/fault.c
---- 25/arch/i386/mm/fault.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/arch/i386/mm/fault.c	2003-06-25 23:14:17.000000000 -0700
-@@ -236,6 +236,12 @@ no_context:
-  * Oops. The kernel tried to access some bad page. We'll have to
-  * terminate things with extreme prejudice.
-  */
-+#ifdef CONFIG_KGDB
-+        if (!user_mode(regs)){
-+                kgdb_handle_exception(14,SIGBUS, error_code, regs);
-+                return;
-+        }
-+#endif
- 
- 	bust_spinlocks(1);
- 
-diff -puN /dev/null Documentation/i386/kgdb/andthen
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/andthen	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,100 @@
-+
-+define	set_andthen
-+	set var $thp=0
-+	set var $thp=(struct kgdb_and_then_struct *)&kgdb_data[0]
-+	set var $at_size = (sizeof kgdb_data)/(sizeof *$thp)
-+	set var $at_oc=kgdb_and_then_count
-+	set var $at_cc=$at_oc
-+end
-+
-+define andthen_next
-+	set var $at_cc=$arg0
-+end
-+
-+define andthen
-+	andthen_set_edge
-+	if ($at_cc >= $at_oc)
-+		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
-+	else
-+		printf "%d: ",$at_cc
-+		output *($thp+($at_cc++ % $at_size ))
-+		printf "\n"
-+	end
-+end
-+define andthen_set_edge
-+	set var $at_oc=kgdb_and_then_count
-+	set var $at_low = $at_oc - $at_size
-+	if ($at_low < 0 )
-+		set var $at_low = 0
-+	end
-+	if (( $at_cc > $at_oc) || ($at_cc < $at_low))
-+		printf "Count outside of window, setting count to "
-+		if ($at_cc >= $at_oc)
-+			set var $at_cc = $at_oc
-+		else
-+			set var $at_cc = $at_low
-+		end
-+		printf "%d\n",$at_cc
-+	end
-+end
-+
-+define beforethat
-+	andthen_set_edge
-+	if ($at_cc <= $at_low)
-+		printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
-+	else
-+		printf "%d: ",$at_cc-1
-+		output *($thp+(--$at_cc % $at_size ))
-+		printf "\n"
-+	end
-+end
-+
-+document andthen_next
-+	andthen_next <count>
-+	.	sets the number of the event to display next. If this event
-+	.	is not in the event pool, either andthen or beforethat will
-+	.	correct it to the nearest event pool edge.  The event pool
-+	.	ends at the last event recorded and begins <number of events>
-+	.	prior to that.  If beforethat is used next, it will display
-+	.	event <count> -1.
-+.
-+	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+	
-+			
-+document andthen
-+	andthen 
-+.	displays the next event in the list.  <set_andthen> sets up to display
-+.	the oldest saved event first. 
-+.	<count> (optional) count of the event to display.
-+.	note the number of events saved is specified at configure time.
-+.	if events are saved between calls to andthen the index will change
-+.	but the displayed event will be the next one (unless the event buffer
-+.	is overrun).
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+
-+document set_andthen
-+	set_andthen
-+.	sets up to use the <andthen> and <beforethat> commands. 
-+.		if you have defined your own struct, use the above and
-+.		then enter the following:
-+.		p $thp=(struct kgdb_and_then_structX *)&kgdb_data[0]
-+.		where <kgdb_and_then_structX> is the name of your structure.
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-+
-+document beforethat
-+	beforethat 
-+.	displays the next prior event in the list. <set_andthen> sets up to
-+.	display the last occuring event first.
-+.
-+.	note the number of events saved is specified at configure time.
-+.	if events are saved between calls to beforethat the index will change
-+.	but the displayed event will be the next one (unless the event buffer
-+.	is overrun).
-+.
-+.	andthen commands are: set_andthen, andthen_next, andthen and beforethat
-+end
-diff -puN /dev/null Documentation/i386/kgdb/debug-nmi.txt
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/debug-nmi.txt	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,37 @@
-+Subject: Debugging with NMI
-+Date: Mon, 12 Jul 1999 11:28:31 -0500
-+From: David Grothe <dave@gcom.com>
-+Organization: Gcom, Inc
-+To: David Grothe <dave@gcom.com>
-+
-+Kernel hackers:
-+
-+Maybe this is old hat, but it is new to me --
-+
-+On an ISA bus machine, if you short out the A1 and B1 pins of an ISA
-+slot you will generate an NMI to the CPU.  This interrupts even a
-+machine that is hung in a loop with interrupts disabled.  Used in
-+conjunction with kgdb <
-+ftp://ftp.gcom.com/pub/linux/src/kgdb-2.3.35/kgdb-2.3.35.tgz > you can
-+gain debugger control of a machine that is hung in the kernel!  Even
-+without kgdb the kernel will print a stack trace so you can find out
-+where it was hung.
-+
-+The A1/B1 pins are directly opposite one another and the farthest pins
-+towards the bracket end of the ISA bus socket.  You can stick a paper
-+clip or multi-meter probe between them to short them out.
-+
-+I had a spare ISA bus to PC104 bus adapter around.  The PC104 end of the
-+board consists of two rows of wire wrap pins.  So I wired a push button
-+between the A1/B1 pins and now have an ISA board that I can stick into
-+any ISA bus slot for debugger entry.
-+
-+Microsoft has a circuit diagram of a PCI card at
-+http://www.microsoft.com/hwdev/DEBUGGING/DMPSW.HTM.  If you want to
-+build one you will have to mail them and ask for the PAL equations.
-+Nobody makes one comercially.
-+
-+[THIS TIP COMES WITH NO WARRANTY WHATSOEVER.  It works for me, but if
-+your machine catches fire, it is your problem, not mine.]
-+
-+-- Dave (the kgdb guy)
-diff -puN /dev/null Documentation/i386/kgdb/gdb-globals.txt
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/gdb-globals.txt	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,71 @@
-+Sender: akale@veritas.com
-+Date: Fri, 23 Jun 2000 19:26:35 +0530
-+From: "Amit S. Kale" <akale@veritas.com>
-+Organization: Veritas Software (India)
-+To: Dave Grothe <dave@gcom.com>, linux-kernel@vger.rutgers.edu
-+CC: David Milburn <dmilburn@wirespeed.com>,
-+        "Edouard G. Parmelan" <Edouard.Parmelan@quadratec.fr>,
-+        ezannoni@cygnus.com, Keith Owens <kaos@ocs.com.au>
-+Subject: Re: Module debugging using kgdb
-+
-+Dave Grothe wrote:
-+> 
-+> Amit:
-+> 
-+> There is a 2.4.0 version of kgdb on our ftp site:
-+> ftp://ftp.gcom.com/pub/linux/src/kgdb.  I mirrored your version of gdb
-+> and loadmodule.sh there.
-+> 
-+> Have a look at the README file and see if I go it right.  If not, send
-+> me some corrections and I will update it.
-+> 
-+> Does your version of gdb solve the global variable problem?
-+
-+Yes. 
-+Thanks to Elena Zanoni, gdb (developement version) can now calculate 
-+correctly addresses  of dynamically loaded object files. I have not been 
-+following gdb developement for sometime and am not sure when symbol
-+address calculation fix is going to appear in a gdb stable version.
-+
-+Elena, any idea when the fix will make it to a prebuilt gdb from a
-+redhat release?
-+
-+For the time being I have built a gdb developement version. It can be
-+used for module debugging with loadmodule.sh script.
-+
-+The problem with calculating of module addresses with previous versions
-+of gdb was as follows:
-+gdb did not use base address of a section while calculating address of
-+a symbol in the section in an object file loaded via 'add-symbol-file'. 
-+It used address of .text segment instead. Due to this addresses of
-+symbols in .data, .bss etc. (e.g. global variables) were calculated incorrectly.
-+
-+Above mentioned fix allow gdb to use base address of a segment while
-+calculating address of a symbol in it. It adds a parameter '-s' to
-+'add-symbol-file' command for specifying base address of a segment.
-+
-+loadmodule.sh script works as follows.
-+
-+1. Copy a module file to target machine.
-+2. Load the module on the target machine using insmod with -m parameter.
-+insmod produces a module load map which contains base addresses of all
-+sections in the module and addresses of symbols in the module file.
-+3. Find all sections and their base addresses in the module from 
-+the module map.
-+4. Generate a script that loads the module file. The script uses
-+'add-symbol-file' and specifies address of text segment followed by
-+addresses of all segments in the module.
-+
-+Here is an example gdb script produced by loadmodule.sh script.
-+
-+add-symbol-file foo 0xd082c060 -s .text.lock 0xd08cbfb5 
-+-s .fixup 0xd08cfbdf -s .rodata 0xd08cfde0 -s __ex_table 0xd08e3b38 
-+-s .data 0xd08e3d00 -s .bss 0xd08ec8c0 -s __ksymtab 0xd08ee838
-+
-+With this command gdb can calculate addresses of symbols in ANY segment
-+in a module file.
-+
-+Regards.
-+-- 
-+Amit Kale
-+Veritas Software ( http://www.veritas.com )
-diff -puN /dev/null Documentation/i386/kgdb/gdbinit
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/gdbinit	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,14 @@
-+shell echo -e "\003" >/dev/ttyS0
-+set remotebaud 38400
-+target remote /dev/ttyS0
-+define si
-+stepi
-+printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
-+printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
-+x/i $eip
-+end
-+define ni
-+nexti
-+printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
-+printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
-+x/i $eip
-diff -puN /dev/null Documentation/i386/kgdb/gdbinit.hw
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/gdbinit.hw	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,117 @@
-+
-+#Using ia-32 hardware breakpoints.
-+#
-+#4 hardware breakpoints are available in ia-32 processors. These breakpoints
-+#do not need code modification. They are set using debug registers.
-+#
-+#Each hardware breakpoint can be of one of the
-+#three types: execution, write, access.
-+#1. An Execution breakpoint is triggered when code at the breakpoint address is
-+#executed.
-+#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
-+#at the breakpoint address is written.
-+#3. An access breakpoint is triggered when memory location at the breakpoint
-+#address is either read or written.
-+#
-+#As hardware breakpoints are available in limited number, use software
-+#breakpoints ( br command in gdb ) instead of execution hardware breakpoints.
-+#
-+#Length of an access or a write breakpoint defines length of the datatype to
-+#be watched. Length is 1 for char, 2 short , 3 int.
-+#
-+#For placing execution, write and access breakpoints, use commands
-+#hwebrk, hwwbrk, hwabrk
-+#To remove a breakpoint use hwrmbrk command.
-+#
-+#These commands take following types of arguments. For arguments associated
-+#with each command, use help command.
-+#1. breakpointno: 0 to 3
-+#2. length: 1 to 3
-+#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
-+#
-+#Use the command exinfo to find which hardware breakpoint occured.
-+
-+#hwebrk breakpointno address
-+define hwebrk
-+	maintenance packet Y$arg0,0,0,$arg1
-+end
-+document hwebrk
-+	hwebrk <breakpointno> <address>
-+	Places a hardware execution breakpoint
-+	<breakpointno> = 0 - 3
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwwbrk breakpointno length address
-+define hwwbrk
-+	maintenance packet Y$arg0,1,$arg1,$arg2
-+end
-+document hwwbrk
-+	hwwbrk <breakpointno> <length> <address>
-+	Places a hardware write breakpoint
-+	<breakpointno> = 0 - 3
-+	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwabrk breakpointno length address
-+define hwabrk
-+	maintenance packet Y$arg0,1,$arg1,$arg2
-+end
-+document hwabrk
-+	hwabrk <breakpointno> <length> <address>
-+	Places a hardware access breakpoint
-+	<breakpointno> = 0 - 3
-+	<length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
-+	<address> = Hex digits without leading "0x".
-+end
-+
-+#hwrmbrk breakpointno
-+define hwrmbrk
-+	maintenance packet y$arg0
-+end
-+document hwrmbrk
-+	hwrmbrk <breakpointno>
-+	<breakpointno> = 0 - 3
-+	Removes a hardware breakpoint
-+end
-+
-+define reboot
-+        maintenance packet r
-+end
-+#exinfo 
-+define exinfo
-+	maintenance packet qE
-+end
-+document exinfo
-+	exinfo 
-+	Gives information about a breakpoint.
-+end
-+define get_th
-+	p $th=(struct thread_info *)((int)$esp & ~8191)
-+end
-+document get_th
-+	get_tu
-+	Gets and prints the current thread_info pointer, Defines th to be it.
-+end
-+define get_cu
-+	p $cu=(struct thread_info *)((int)$esp & ~8191)->task
-+end
-+document get_cu
-+	get_cu
-+	Gets and print the "current" value.  Defines $cu to be it.
-+end
-+define int_off
-+	set var $flags=$eflags
-+	set $eflags=$eflags&~0x200
-+	end
-+define int_on
-+	set var $eflags|=$flags&0x200
-+	end
-+document int_off
-+	saves the current interrupt state and clears the processor interrupt 
-+	flag.  Use int_on to restore the saved flag.
-+end
-+document int_on
-+	Restores the interrupt flag saved by int_off.
-+end
-diff -puN /dev/null Documentation/i386/kgdb/gdbinit-modules
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/gdbinit-modules	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,146 @@
-+#
-+# Usefull GDB user-command to debug Linux Kernel Modules with gdbstub.
-+#
-+# This don't work for Linux-2.0 or older.
-+#
-+# Author Edouard G. Parmelan <Edouard.Parmelan@quadratec.fr>
-+#
-+#
-+# Fri Apr 30 20:33:29 CEST 1999
-+#   First public release.
-+#
-+#   Major cleanup after experiment Linux-2.0 kernel without success.
-+#   Symbols of a module are not in the correct order, I can't explain
-+#   why :(
-+#
-+# Fri Mar 19 15:41:40 CET 1999
-+#   Initial version.
-+#
-+# Thu Jan  6 16:29:03 CST 2000
-+#   A little fixing by Dave Grothe <dave@gcom.com>
-+#
-+# Mon Jun 19 09:33:13 CDT 2000
-+#   Alignment changes from Edouard Parmelan
-+#
-+# The basic idea is to find where insmod load the module and inform
-+# GDB to load the symbol table of the module with the GDB command 
-+# ``add-symbol-file <object> <address>''.
-+#
-+# The Linux kernel holds the list of all loaded modules in module_list,
-+# this list end with &kernel_module (exactly with module->next == NULL,
-+# but the last module is not a real module).
-+#
-+# Insmod allocates the struct module before the object file.  Since
-+# Linux-2.1, this structure contain his size.  The real address of
-+# the object file is then (char*)module + module->size_of_struct.
-+#
-+# You can use three user functions ``mod-list'', ``mod-print-symbols''
-+# and ``add-module-symbols''.
-+#
-+# mod-list list all loaded modules with the format:
-+#    <module-address> <module-name>
-+#
-+# As soon as you have found the address of your module, you can
-+# print its exported symbols (mod-print-symbols) or inform GDB to add
-+# symbols from your module file (mod-add-symbols).
-+#
-+# The argument that you give to mod-print-symbols or mod-add-symbols
-+# is the <module-address> from the mod-list command.
-+#
-+# When using the mod-add-symbols command you must also give the full
-+# pathname of the modules object code file.
-+#
-+# The command mod-add-lis is an example of how to make this easier.
-+# You can edit this macro to contain the path name of your own
-+# favorite module and then use it as a shorthand to load it.  You
-+# still need the module-address, however.
-+#
-+# The internal function ``mod-validate'' set the GDB variable $mod
-+# as a ``struct module*'' if the kernel known the module otherwise
-+# $mod is set to NULL.  This ensure to not add symbols for a wrong
-+# address.
-+# 
-+# Have a nice hacking day !
-+#
-+#
-+define mod-list
-+    set $mod = (struct module*)module_list
-+    # the last module is the kernel, ignore it
-+    while $mod != &kernel_module
-+    	printf "%p\t%s\n", (long)$mod, ($mod)->name
-+	set $mod = $mod->next
-+    end
-+end
-+document mod-list
-+List all modules in the form: <module-address> <module-name>
-+Use the <module-address> as the argument for the other
-+mod-commands: mod-print-symbols, mod-add-symbols.
-+end
-+
-+define mod-validate
-+    set $mod = (struct module*)module_list
-+    while ($mod != $arg0) && ($mod != &kernel_module)
-+    	set $mod = $mod->next
-+    end
-+    if $mod == &kernel_module
-+	set $mod = 0
-+    	printf "%p is not a module\n", $arg0
-+    end
-+end
-+document mod-validate
-+mod-validate <module-address>
-+Internal user-command used to validate the module parameter.
-+If <module> is a real loaded module, set $mod to it otherwise set $mod to 0.
-+end
-+
-+
-+define mod-print-symbols
-+    mod-validate $arg0
-+    if $mod != 0
-+	set $i = 0
-+	while $i < $mod->nsyms
-+	    set $sym = $mod->syms[$i]
-+	    printf "%p\t%s\n", $sym->value, $sym->name
-+	    set $i = $i + 1
-+	end
-+    end
-+end
-+document mod-print-symbols
-+mod-print-symbols <module-address>
-+Print all exported symbols of the module.  see mod-list
-+end
-+
-+
-+define mod-add-symbols-align
-+    mod-validate $arg0
-+    if $mod != 0
-+	set $mod_base = ($mod->size_of_struct + (long)$mod)
-+	if ($arg2 != 0) && (($mod_base & ($arg2 - 1)) != 0)
-+	    set $mod_base = ($mod_base | ($arg2 - 1)) + 1
-+	end
-+	add-symbol-file $arg1 $mod_base
-+    end
-+end
-+document mod-add-symbols-align
-+mod-add-symbols-align <module-address> <object file path name> <align>
-+Load the symbols table of the module from the object file where
-+first section aligment is <align>.
-+To retreive alignment, use `objdump -h <object file path name>'.
-+end
-+
-+define mod-add-symbols
-+    mod-add-symbols-align $arg0 $arg1 sizeof(long)
-+end
-+document mod-add-symbols
-+mod-add-symbols <module-address> <object file path name>
-+Load the symbols table of the module from the object file.
-+Default alignment is 4.  See mod-add-symbols-align.
-+end
-+
-+define mod-add-lis
-+    mod-add-symbols-align $arg0 /usr/src/LiS/streams.o 16
-+end
-+document mod-add-lis
-+mod-add-lis <module-address>
-+Does mod-add-symbols <module-address> /usr/src/LiS/streams.o
-+end
-diff -puN /dev/null Documentation/i386/kgdb/kgdb.txt
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/kgdb.txt	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,715 @@
-+Last edit: <20030506.1615.42>
-+This file has information specific to the i386 kgdb option.  Other
-+platforms with the kgdb option may behave in a similar fashion.
-+
-+New features: 
-+============
-+20030505.1827.27
-+We are starting to align with the sourceforge version, at least in 
-+commands.  To this end, the boot command sting to start kgdb at
-+boot time has been changed from "kgdb" to "gdb".
-+
-+Andrew Morton sent a couple of patchs which are now included as follows:
-+1.) We now return a flag to the interrupt handler.
-+2.) We no longer use smp_num_cpus (a conflict with the lock meter).
-+3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
-+    sure high-mem is set up before we attempt to register our interrupt
-+    handler.
-+We now include asm/kgdb.h from config.h so you will most likely never
-+have to include it.  It also 'NULLS' the kgdb macros you might have in
-+your code when CONFIG_KGDB is not defined.  This allows you to just
-+turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
-+This include is conditioned on the machine being an x86 so as to not
-+mess with other archs.
-+
-+20020801.1129.03
-+This is currently the version for the 2.4.18 (and beyond?) kernel.
-+
-+We have several new "features" beginning with this version:
-+ 
-+1.) Kgdb now syncs the "other" cpus with a cross cpu NMI.  No more
-+    waiting and it will pull that guy out of an irq off spin lock :)
-+
-+2.) We doctored up the code that tells where a task is waiting and
-+    included it so that the "info thread" command will show a bit more
-+    than "schedule()".  Try it...
-+
-+3.) Added the ability to call a function from gdb.  All the standard gdb
-+    issues apply, i.e. if you hit a break point in the function you are
-+    not allowed to call another (gdb limitation, not kgdb).  T0 help
-+    this capability we added a memory allocation function.  Gdb does not
-+    return this memory (it is used for stings you pass to that function
-+    you are calling from gdb) so we fixed up a way to allow you to
-+    manually return the memory (see below).
-+
-+4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
-+    interrupt flag to now also include the preemption count and the
-+    "in_interrupt" info.  The flag is now called "with_pif" to indicate
-+    the order, preempt_count, in_interrupt, flag.  The preempt_count is
-+    shifted left by 4 bits so you can read the count in hex by dropping
-+    the low order digit.  In_interrupt is in bit 1, and the flag is in
-+    bit 0.
-+
-+5.) The command: "p kgdb_info" is now expanded and prints something
-+    like:
-+(gdb) p kgdb_info
-+$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259, 
-+  errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1, 
-+  cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0, 
-+      regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
-+    
-+    Things to note here: a.) used_malloc is the amount of memory that
-+    has been malloc'ed to do calls from gdb.  You can reclaim this
-+    memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
-+    cpus_waiting is now "sized" by the number of cpus you enter at
-+    configure time in the kgdb configure section.  This is NOT used any
-+    where else in the system, but it is "nice" here.  c.)  The tasks
-+    "pid" is now in the structure.  This is the pid you will need to use
-+    to decode to the thread id to get gdb to look at that thread.
-+    Remember that the "info thread" command prints a list of threads
-+    where in it numbers each thread with its reference number followed
-+    by the threads pid.  Note that the per cpu idle threads actually
-+    have pids of 0 (yes there is more than one pid 0 in an SMP system).
-+    To avoid confusion, kgdb numbers these threads with numbers beyond
-+    the MAX_PID.  That is why you see 32768 above.
-+
-+6.) A subtle change, we now provide the complete register set for tasks
-+    that are active on the other cpus.  This allows better trace back on
-+    those tasks.
-+
-+    And, lets mention what we could not fix.  Back-trace from all but the
-+    thread that we trapped will, most likely, have a bogus entry in it.
-+    The problem is that gdb does not recognize the entry code for
-+    functions that use "current" near (at all?) the entry.  The compiler
-+    is putting the "current" decode as the first two instructions of the
-+    function where gdb expects to find %ebp changing code.  Back trace
-+    also has trouble with interrupt frames.  I am talking with Daniel
-+    Jacobowitz about some way to fix this, but don't hold your breath.
-+
-+20011220.0050.35
-+Major enhancement with this version is the ability to hold one or more
-+cpus in an SMP system while allowing the others to continue.  Also, by
-+default only the current cpu is enabled on single step commands (please
-+note that gdb issues single step commands at times other than when you
-+use the si command).
-+ 
-+Another change is to collect some useful information in
-+a global structure called "kgdb_info".  You should be able to just:
-+
-+p kgdb_info
-+
-+although I have seen cases where the first time this is done gdb just
-+prints the first member but prints the whole structure if you then enter
-+CR (carriage return or enter).  This also works:
-+
-+p *&kgdb_info
-+
-+Here is a sample:
-+(gdb) p kgdb_info
-+$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0, 
-+  vector = 3, print_debug_info = 0}
-+
-+"Called_from" is the return address from the current entry into kgdb.  
-+Sometimes it is useful to know why you are in kgdb, for example, was 
-+it an NMI or a real break point?  The simple way to interrogate this 
-+return address is:
-+
-+l *0xc010732c
-+
-+which will print the surrounding few lines of source code.
-+
-+"Entry_tsc" is the cpu TSC on entry to kgdb (useful to compare to the
-+kgdb_ts entries).
-+
-+"errcode" and "vector" are other entry parameters which may be helpful on
-+some traps.
-+
-+"print_debug_info" is the internal debugging kgdb print enable flag.  Yes,
-+you can modify it.
-+
-+In SMP systems kgdb_info also includes the "cpus_waiting" structure and
-+"hold_on_step": 
-+
-+(gdb) p kgdb_info
-+$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0, 
-+  vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
-+      task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0, 
-+      regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-+      hold = 0, regs = 0x0}}}
-+
-+"Cpus_waiting" has an entry for each cpu other than the current one that 
-+has been stopped.  Each entry contains the task_struct address for that
-+cpu, the address of the regs for that task and a hold flag.  All these
-+have the proper typing so that, for example:
-+
-+p *kgdb_info.cpus_waiting[1].regs
-+
-+will print the registers for cpu 1.
-+
-+"Hold_on_sstep" is a new feature with this version and comes up set or
-+true.  What is means is that whenever kgdb is asked to single step all
-+other cpus are held (i.e. not allowed to execute).  The flag applies to
-+all but the current cpu and, again, can be changed:
-+
-+p kgdb_info.hold_on_sstep=0
-+
-+restores the old behavior of letting all cpus run during single stepping.
-+
-+Likewise, each cpu has a "hold" flag, which if set, locks that cpu out
-+of execution.  Note that this has some risk in cases where the cpus need
-+to communicate with each other.  If kgdb finds no cpu available on exit,
-+it will push a message thru gdb and stay in kgdb.  Note that it is legal
-+to hold the current cpu as long as at least one cpu can execute.
-+
-+20010621.1117.09
-+This version implements an event queue.  Events are signaled by calling
-+a function in the kgdb stub and may be examined from gdb.  See EVENTS 
-+below for details.  This version also tighten up the interrupt and SMP
-+handling to not allow interrupts on the way to kgdb from a breakpoint 
-+trap.  It is fine to allow these interrupts for user code, but not
-+system debugging.
-+
-+Version
-+=======
-+
-+This version of the kgdb package was developed and tested on
-+kernel version 2.4.16.  It will not install on any earlier kernels.  
-+It is possible that it will continue to work on later versions
-+of 2.4 and then versions of 2.5 (I hope).
-+
-+
-+Debugging Setup
-+===============
-+
-+Designate one machine as the "development" machine.  This is the
-+machine on which you run your compiles and which has your source
-+code for the kernel.  Designate a second machine as the "target"
-+machine.  This is the machine that will run your experimental
-+kernel.
-+
-+The two machines will be connected together via a serial line out
-+one or the other of the COM ports of the PC.  You will need a modem
-+eliminator and the appropriate cables.
-+
-+Decide on which tty port you want the machines to communicate, then
-+cable them up back-to-back using the null modem.  COM1 is /dev/ttyS0 and
-+COM2 is /dev/ttyS1. You should test this connection with the two
-+machines prior to trying to debug a kernel.  Once you have it working,
-+on the TARGET machine, enter:
-+
-+setserial /dev/ttyS0 (or what ever tty you are using)
-+
-+and record the port and the irq addresses. 
-+
-+On the DEVELOPMENT machine you need to apply the patch for the kgdb
-+hooks.  You have probably already done that if you are reading this
-+file.
-+
-+On your DEVELOPMENT machine, go to your kernel source directory and do
-+"make Xconfig" where X is one of "x", "menu", or "".  If you are
-+configuring in the standard serial driver, it must not be a module.
-+Either yes or no is ok, but making the serial driver a module means it
-+will initialize after kgdb has set up the UART interrupt code and may
-+cause a failure of the control C option discussed below.  The configure
-+question for the serial driver is under the "Character devices" heading
-+and is:
-+
-+"Standard/generic (8250/16550 and compatible UARTs) serial support"
-+
-+Go down to the kernel debugging menu item and open it up.  Enable the
-+kernel kgdb stub code by selecting that item.  You can also choose to
-+turn on the "-ggdb -O1" compile options.  The -ggdb causes the compiler
-+to put more debug info (like local symbols) in the object file.  On the
-+i386 -g and -ggdb are the same so this option just reduces to "O1".  The
-+-O1 reduces the optimization level.  This may be helpful in some cases,
-+be aware, however, that this may also mask the problem you are looking
-+for.
-+
-+The baud rate.  Default is 115200.  What ever you choose be sure that
-+the host machine is set to the same speed.  I recommend the default.
-+
-+The port.  This is the I/O address of the serial UART that you should
-+have gotten using setserial as described above.  The standard com1 port
-+(3f8) using irq 4 is default .  Com2 is 2f8 which by convention uses irq
-+3.
-+
-+The port irq (see above).
-+
-+Stack overflow test.  This option makes a minor change in the trap,
-+system call and interrupt code to detect stack overflow and transfer
-+control to kgdb if it happens.  (Some platforms have this in the base
-+line code, but the i386 does not.)
-+
-+You can also configure the system to recognize the boot option
-+"console=kgdb" which if given will cause all console output during
-+booting to be put thru gdb as well as other consoles.  This option
-+requires that gdb and kgdb be connected prior to sending console output
-+so, if they are not, a breakpoint is executed to force the connection.
-+This will happen before any kernel output (it is going thru gdb, right),
-+and will stall the boot until the connection is made.
-+
-+You can also configure in a patch to SysRq to enable the kGdb SysRq.
-+This request generates a breakpoint.  Since the serial port irq line is
-+set up after any serial drivers, it is possible that this command will
-+work when the control C will not.
-+
-+Save and exit the Xconfig program.  Then do "make clean" , "make dep"
-+and "make bzImage" (or whatever target you want to make).  This gets the
-+kernel compiled with the "-g" option set -- necessary for debugging.
-+
-+You have just built the kernel on your DEVELOPMENT machine that you
-+intend to run on your TARGET machine.
-+
-+To install this new kernel, use the following installation procedure.
-+Remember, you are on the DEVELOPMENT machine patching the kernel source
-+for the kernel that you intend to run on the TARGET machine.
-+
-+Copy this kernel to your target machine using your usual procedures.  I
-+usually arrange to copy development:
-+/usr/src/linux/arch/i386/boot/bzImage to /vmlinuz on the TARGET machine
-+via a LAN based NFS access.  That is, I run the cp command on the target
-+and copy from the development machine via the LAN.  Run Lilo (see "man
-+lilo" for details on how to set this up) on the new kernel on the target
-+machine so that it will boot!  Then boot the kernel on the target
-+machine.
-+
-+On the DEVELOPMENT machine, create a file called .gdbinit in the
-+directory /usr/src/linux.  An example .gdbinit file looks like this:
-+
-+shell echo -e "\003" >/dev/ttyS0
-+set remotebaud 38400 (or what ever speed you have chosen)
-+target remote /dev/ttyS0
-+
-+
-+Change the "echo" and "target" definition so that it specifies the tty
-+port that you intend to use.  Change the "remotebaud" definition to
-+match the data rate that you are going to use for the com line.
-+
-+You are now ready to try it out.
-+
-+Boot your target machine with "kgdb" in the boot command i.e. something
-+like:
-+
-+lilo> test kgdb
-+
-+or if you also want console output thru gdb:
-+
-+lilo> test kgdb console=kgdb
-+
-+You should see the lilo message saying it has loaded the kernel and then
-+all output stops.  The kgdb stub is trying to connect with gdb.  Start
-+gdb something like this:
-+
-+
-+On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux".
-+When gdb gets the symbols loaded it will read your .gdbinit file and, if
-+everything is working correctly, you should see gdb print out a few
-+lines indicating that a breakpoint has been taken.  It will actually
-+show a line of code in the target kernel inside the kgdb activation
-+code.
-+
-+The gdb interaction should look something like this:
-+
-+    linux-dev:/usr/src/linux# gdb vmlinux
-+    GDB is free software and you are welcome to distribute copies of it
-+     under certain conditions; type "show copying" to see the conditions.
-+    There is absolutely no warranty for GDB; type "show warranty" for details.
-+    GDB 4.15.1 (i486-slackware-linux), 
-+    Copyright 1995 Free Software Foundation, Inc...
-+    breakpoint () at i386-stub.c:750
-+    750     }
-+    (gdb) 
-+
-+You can now use whatever gdb commands you like to set breakpoints.
-+Enter "continue" to start your target machine executing again.  At this
-+point the target system will run at full speed until it encounters
-+your breakpoint or gets a segment violation in the kernel, or whatever.
-+
-+If you have the kgdb console enabled when you continue, gdb will print
-+out all the console messages.
-+
-+The above example caused a breakpoint relatively early in the boot
-+process.  For the i386 kgdb it is possible to code a break instruction
-+as the first C-language point in init/main.c, i.e. as the first instruction
-+in start_kernel().  This could be done as follows:
-+
-+#include <asm/kgdb.h>
-+	 breakpoint();
-+
-+This breakpoint() is really a function that sets up the breakpoint and
-+single-step hardware trap cells and then executes a breakpoint.  Any
-+early hard coded breakpoint will need to use this function.  Once the
-+trap cells are set up they need not be set again, but doing it again
-+does not hurt anything, so you don't need to be concerned about which
-+breakpoint is hit first.  Once the trap cells are set up (and the kernel
-+sets them up in due course even if breakpoint() is never called) the
-+macro:
-+
-+BREAKPOINT;
-+
-+will generate an inline breakpoint.  This may be more useful as it stops
-+the processor at the instruction instead of in a function a step removed
-+from the location of interest.  In either case <asm/kgdb.h> must be
-+included to define both breakpoint() and BREAKPOINT.
-+
-+Triggering kgdbstub at other times
-+==================================
-+
-+Often you don't need to enter the debugger until much later in the boot
-+or even after the machine has been running for some time.  Once the
-+kernel is booted and interrupts are on, you can force the system to
-+enter the debugger by sending a control C to the debug port. This is
-+what the first line of the recommended .gdbinit file does.  This allows
-+you to start gdb any time after the system is up as well as when the
-+system is already at a break point.  (In the case where the system is
-+already at a break point the control C is not needed, however, it will
-+be ignored by the target so no harm is done.  Also note the the echo
-+command assumes that the port speed is already set.  This will be true
-+once gdb has connected, but it is best to set the port speed before you
-+run gdb.)
-+
-+Another simple way to do this is to put the following file in you ~/bin
-+directory:
-+
-+#!/bin/bash
-+echo  -e "\003"  > /dev/ttyS0 
-+
-+Here, the ttyS0 should be replaced with what ever port you are using.
-+The "\003" is control-C.  Once you are connected with gdb, you can enter
-+control-C at the command prompt.
-+
-+An alternative way to get control to the debugger is to enable the kGdb
-+SysRq command.  Then you would enter Alt-SysRq-g (all three keys at the
-+same time, but push them down in the order given).  To refresh your
-+memory of the available SysRq commands try Alt-SysRq-=.  Actually any
-+undefined command could replace the "=", but I like to KNOW that what I
-+am pushing will never be defined.
-+ 
-+Debugging hints
-+===============
-+
-+You can break into the target machine at any time from the development
-+machine by typing ^C (see above paragraph).  If the target machine has
-+interrupts enabled this will stop it in the kernel and enter the
-+debugger.
-+
-+There is unfortunately no way of breaking into the kernel if it is
-+in a loop with interrupts disabled, so if this happens to you then
-+you need to place exploratory breakpoints or printk's into the kernel
-+to find out where it is looping.  The exploratory breakpoints can be
-+entered either thru gdb or hard coded into the source.  This is very
-+handy if you do something like:
-+
-+if (<it hurts>) BREAKPOINT;
-+
-+
-+There is a copy of an e-mail in the Documentation/i386/kgdb/ directory
-+(debug-nmi.txt) which describes how to create an NMI on an ISA bus
-+machine using a paper clip.  I have a sophisticated version of this made
-+by wiring a push button switch into a PC104/ISA bus adapter card.  The
-+adapter card nicely furnishes wire wrap pins for all the ISA bus
-+signals.
-+
-+When you are done debugging the kernel on the target machine it is a
-+good idea to leave it in a running state.  This makes reboots faster,
-+bypassing the fsck.  So do a gdb "continue" as the last gdb command if
-+this is possible.  To terminate gdb itself on the development machine
-+and leave the target machine running, first clear all breakpoints and
-+continue, then type ^Z to suspend gdb and then kill it with "kill %1" or
-+something similar.
-+
-+If gdbstub Does Not Work
-+========================
-+
-+If it doesn't work, you will have to troubleshoot it.  Do the easy
-+things first like double checking your cabling and data rates.  You
-+might try some non-kernel based programs to see if the back-to-back
-+connection works properly.  Just something simple like cat /etc/hosts
-+>/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
-+if you can send data from one machine to the other.  Make sure it works
-+in both directions.  There is no point in tearing out your hair in the
-+kernel if the line doesn't work.
-+
-+All of the real action takes place in the file
-+/usr/src/linux/arch/i386/kernel/kgdb_stub.c.  That is the code on the target
-+machine that interacts with gdb on the development machine.  In gdb you can
-+turn on a debug switch with the following command:
-+
-+	set remotedebug
-+
-+This will print out the protocol messages that gdb is exchanging with
-+the target machine.
-+
-+Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c This is
-+the code that talks to the serial port on the target side.  There might
-+be a problem there.  In particular there is a section of this code that
-+tests the UART which will tell you what UART you have if you define
-+"PRNT" (just remove "_off" from the #define PRNT_off).  To view this
-+report you will need to boot the system without any beakpoints.  This
-+allows the kernel to run to the point where it calls kgdb to set up
-+interrupts.  At this time kgdb will test the UART and print out the type
-+it finds.  (You need to wait so that the printks are actually being
-+printed.  Early in the boot they are cached, waiting for the console to
-+be enabled.  Also, if kgdb is entered thru a breakpoint it is possible
-+to cause a dead lock by calling printk when the console is locked.  The
-+stub, thus avoids doing printks from break points especially in the
-+serial code.)  At this time, if the UART fails to do the expected thing,
-+kgdb will print out (using printk) information on what failed.  (These
-+messages will be buried in all the other boot up messages.  Look for
-+lines that start with "gdb_hook_interrupt:".  You may want to use dmesg
-+once the system is up to view the log.  If this fails or if you still
-+don't connect, review your answers for the port address.  Use:
-+
-+setserial /dev/ttyS0 
-+
-+to get the current port and irq information.  This command will also
-+tell you what the system found for the UART type. The stub recognizes
-+the following UART types:
-+
-+16450, 16550, and 16550A
-+
-+If you are really desperate you can use printk debugging in the
-+kgdbstub code in the target kernel until you get it working.  In particular,
-+there is a global variable in /usr/src/linux/arch/i386/kernel/kgdb_stub.c
-+named "remote_debug".  Compile your kernel with this set to 1, rather
-+than 0 and the debug stub will print out lots of stuff as it does
-+what it does.  Likewise there are debug printks in the kgdb_serial.c
-+code that can be turned on with simple changes in the macro defines.
-+
-+
-+Debugging Loadable Modules
-+==========================
-+
-+This technique comes courtesy of Edouard Parmelan
-+<Edouard.Parmelan@quadratec.fr>
-+
-+When you run gdb, enter the command
-+
-+source gdbinit-modules
-+
-+This will read in a file of gdb macros that was installed in your
-+kernel source directory when kgdb was installed.  This file implements
-+the following commands:
-+
-+mod-list
-+    Lists the loaded modules in the form <module-address> <module-name>
-+
-+mod-print-symbols <module-address>
-+    Prints all the symbols in the indicated module.
-+
-+mod-add-symbols <module-address> <object-file-path-name>
-+    Loads the symbols from the object file and associates them
-+    with the indicated module.
-+
-+After you have loaded the module that you want to debug, use the command
-+mod-list to find the <module-address> of your module.  Then use that
-+address in the mod-add-symbols command to load your module's symbols.
-+From that point onward you can debug your module as if it were a part
-+of the kernel.
-+
-+The file gdbinit-modules also contains a command named mod-add-lis as
-+an example of how to construct a command of your own to load your
-+favorite module.  The idea is to "can" the pathname of the module
-+in the command so you don't have to type so much.
-+
-+Threads
-+=======
-+
-+Each process in a target machine is seen as a gdb thread. gdb thread
-+related commands (info threads, thread n) can be used.
-+
-+ia-32 hardware breakpoints
-+==========================
-+
-+kgdb stub contains support for hardware breakpoints using debugging features
-+of ia-32(x86) processors. These breakpoints do not need code modification.
-+They use debugging registers. 4 hardware breakpoints are available in ia-32
-+processors.
-+
-+Each hardware breakpoint can be of one of the following three types.
-+
-+1. Execution breakpoint - An Execution breakpoint is triggered when code
-+	at the breakpoint address is executed.
-+
-+	As limited number of hardware breakpoints are available, it is
-+	advisable to use software breakpoints ( break command ) instead
-+	of execution hardware breakpoints, unless modification of code
-+	is to be avoided.
-+
-+2. Write breakpoint - A write breakpoint is triggered when memory
-+	location at the breakpoint address is written.
-+
-+	A write or can be placed for data of variable length. Length of
-+	a write breakpoint indicates length of the datatype to be
-+	watched. Length is 1 for 1 byte data , 2 for 2 byte data, 3 for
-+	4 byte data.
-+
-+3. Access breakpoint - An access breakpoint is triggered when memory
-+	location at the breakpoint address is either read or written.
-+
-+	Access breakpoints also have lengths similar to write breakpoints.
-+
-+IO breakpoints in ia-32 are not supported.
-+
-+Since gdb stub at present does not use the protocol used by gdb for hardware
-+breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros
-+for hardware breakpoints are described below.
-+
-+hwebrk	- Places an execution breakpoint
-+	hwebrk breakpointno address
-+hwwbrk	- Places a write breakpoint
-+	hwwbrk breakpointno length address
-+hwabrk	- Places an access breakpoint
-+	hwabrk breakpointno length address
-+hwrmbrk	- Removes a breakpoint
-+	hwrmbrk breakpointno
-+exinfo	- Tells whether a software or hardware breakpoint has occurred.
-+	Prints number of the hardware breakpoint if a hardware breakpoint has
-+	occurred.
-+
-+Arguments required by these commands are as follows
-+breakpointno	- 0 to 3
-+length		- 1 to 3
-+address		- Memory location in hex digits ( without 0x ) e.g c015e9bc
-+
-+SMP support
-+==========
-+
-+When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb
-+client, all the processors are forced to enter the debugger. Current
-+thread corresponds to the thread running on the processor where
-+breakpoint occurred.  Threads running on other processor(s) appear
-+similar to other non running threads in the 'info threads' output.  With
-+in the kgdb stub there is a structure "waiting_cpus" in which kgdb
-+records the values of "current" and "regs" for each cpu other than the
-+one that hit the breakpoint.  "current" is a pointer to the task
-+structure for the task that cpu is running, while "regs" points to the
-+saved registers for the task.  This structure can be examined with the
-+gdb "p" command.
-+
-+ia-32 hardware debugging registers on all processors are set to same
-+values.  Hence any hardware breakpoints may occur on any processor.
-+
-+gdb troubleshooting
-+===================
-+
-+1. gdb hangs
-+Kill it. restart gdb. Connect to target machine.
-+
-+2. gdb cannot connect to target machine (after killing a gdb and
-+restarting another) If the target machine was not inside debugger when
-+you killed gdb, gdb cannot connect because the target machine won't
-+respond.  In this case echo "Ctrl+C"(ASCII 3) in the serial line.
-+e.g. echo -e "\003" > /dev/ttyS1 This forces that target machine into
-+debugger after which you can connect.
-+
-+3. gdb cannot connect even after echoing Ctrl+C into serial line
-+Try changing serial line settings min to 1 and time to 0
-+e.g. stty min 1 time 0 < /dev/ttyS1
-+Try echoing again
-+
-+check serial line speed and set it to correct value if required
-+e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
-+
-+EVENTS
-+======
-+
-+Ever want to know the order of things happening?  Which cpu did what and
-+when?  How did the spinlock get the way it is?  Then events are for
-+you.  Events are defined by calls to an event collection interface and
-+saved for later examination.  In this case, kgdb events are saved by a
-+very fast bit of code in kgdb which is fully SMP and interrupt protected
-+and they are examined by using gdb to display them.  Kgdb keeps only
-+the last N events, where N must be a power of two and is defined at
-+configure time.
-+
-+
-+Events are signaled to kgdb by calling:
-+
-+kgdb_ts(data0,data1)
-+
-+For each call kgdb records each call in an array along with other info.
-+Here is the array def:
-+
-+struct kgdb_and_then_struct {
-+#ifdef CONFIG_SMP
-+	int	on_cpu;
-+#endif
-+	long long at_time;
-+	int  	from_ln;
-+	char	* in_src;
-+	void	*from;
-+        int     with_if;
-+	int	data0;
-+	int	data1;
-+};
-+
-+For SMP machines the cpu is recorded, for all machines the TSC is
-+recorded (gets a time stamp) as well as the line number and source file
-+the call was made from.  The address of the (from), the "if" (interrupt
-+flag) and the two data items are also recorded.  The macro kgdb_ts casts
-+the types to int, so you can put any 32-bit values here.  There is a
-+configure option to select the number of events you want to keep.  A
-+nice number might be 128, but you can keep up to 1024 if you want.  The
-+number must be a power of two.  An "andthen" macro library is provided
-+for gdb to help you look at these events.  It is also possible to define
-+a different structure for the event storage and cast the data to this
-+structure.  For example the following structure is defined in kgdb:
-+
-+struct kgdb_and_then_struct2 {
-+#ifdef CONFIG_SMP
-+	int	on_cpu;
-+#endif
-+	long long at_time;
-+	int  	from_ln;
-+	char	* in_src;
-+	void	*from;
-+        int     with_if;
-+	struct task_struct *t1;
-+	struct task_struct *t2;
-+};
-+
-+If you use this for display, the data elements will be displayed as
-+pointers to task_struct entries.  You may want to define your own
-+structure to use in casting.  You should only change the last two items
-+and you must keep the structure size the same.  Kgdb will handle these
-+as 32-bit ints, but within that constraint you can define a structure to
-+cast to any 32-bit quantity.  This need only be available to gdb and is
-+only used for casting in the display code.
-+
-+Final Items
-+===========
-+
-+I picked up this code from Amit S. Kale and enhanced it.
-+
-+If you make some really cool modification to this stuff, or if you 
-+fix a bug, please let me know.
-+
-+George Anzinger
-+<george@mvista.com>
-+
-+Amit S. Kale
-+<akale@veritas.com>
-+
-+(First kgdb by David Grothe <dave@gcom.com>)
-+
-+(modified by Tigran Aivazian <tigran@sco.com>)
-+    Putting gdbstub into the kernel config menu.
-+
-+(modified by Scott Foehner <sfoehner@engr.sgi.com>)
-+    Hooks for entering gdbstub at boot time.
-+
-+(modified by Amit S. Kale <akale@veritas.com>)
-+    Threads, ia-32 hw debugging, mp support, console support,
-+    nmi watchdog handling.
-+
-+(modified by George Anzinger <george@mvista.com>)
-+    Extended threads to include the idle threads.
-+    Enhancements to allow breakpoint() at first C code.
-+    Use of module_init() and __setup() to automate the configure.
-+    Enhanced the cpu "collection" code to work in early bring up.
-+    Added ability to call functions from gdb
-+    Print info thread stuff without going back to schedule()
-+    Now collect the "other" cpus with a IPI/ NMI.
-\ No newline at end of file
-diff -puN /dev/null Documentation/i386/kgdb/loadmodule.sh
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/loadmodule.sh	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,78 @@
-+#/bin/sh
-+# This script loads a module on a target machine and generates a gdb script.
-+# source generated gdb script to load the module file at appropriate addresses
-+# in gdb.
-+#
-+# Usage: 
-+# Loading the module on target machine and generating gdb script)
-+#	[foo]$ loadmodule.sh <modulename>
-+#
-+# Loading the module file into gdb
-+#	(gdb) source <gdbscriptpath>
-+#
-+# Modify following variables according to your setup. 
-+#	TESTMACHINE - Name of the target machine
-+#	GDBSCRIPTS - The directory where a gdb script will be generated
-+#
-+# Author: Amit S. Kale (akale@veritas.com).
-+#
-+# If you run into problems, please check files pointed to by following
-+# variables.
-+#	ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
-+#	MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
-+#	GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
-+
-+TESTMACHINE=foo
-+GDBSCRIPTS=/home/bar
-+
-+if [ $# -lt 1 ] ; then {
-+	echo Usage: $0 modulefile
-+	exit
-+} ; fi
-+
-+MODULEFILE=$1
-+MODULEFILEBASENAME=`basename $1`
-+
-+if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
-+	MODULEFILE=`pwd`/$MODULEFILE
-+} fi
-+
-+ERRFILE=/tmp/$MODULEFILEBASENAME.errs
-+MAPFILE=/tmp/$MODULEFILEBASENAME.map
-+GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
-+
-+function findaddr() {
-+	local ADDR=0x$(echo "$SEGMENTS" | \
-+		grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
-+		sed 's/[ ]*[^ ]*$//')
-+	echo $ADDR
-+}
-+
-+function checkerrs() {
-+	if [ "`cat $ERRFILE`" != "" ] ; then {
-+		cat $ERRFILE
-+		exit
-+	} fi
-+}
-+
-+#load the module
-+echo Copying $MODULEFILE to $TESTMACHINE
-+rcp $MODULEFILE root@${TESTMACHINE}:
-+
-+echo Loading module $MODULEFILE
-+rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
-+	> $MAPFILE 2> $ERRFILE
-+checkerrs
-+
-+SEGMENTS=`head -n 11 $MAPFILE | tail -n 10`
-+TEXTADDR=$(findaddr "\\.text[^.]")
-+LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
-+SEGADDRS=`echo "$SEGMENTS" | awk '//{
-+	if ($1 != ".text" && $1 != ".this" &&
-+	    $1 != ".kstrtab" && $1 != ".kmodtab") {
-+		print " -s " $1 " 0x" $3 " "
-+	}
-+}'`
-+LOADSTRING="$LOADSTRING $SEGADDRS"
-+echo Generating script $GDBSCRIPT
-+echo $LOADSTRING > $GDBSCRIPT
-diff -puN drivers/char/keyboard.c~kgdb-ga drivers/char/keyboard.c
---- 25/drivers/char/keyboard.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/drivers/char/keyboard.c	2003-06-25 23:14:17.000000000 -0700
-@@ -1055,6 +1055,9 @@ void kbd_keycode(unsigned int keycode, i
- 	}
- 	if (sysrq_down && down && !rep) {
- 		handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
-+#ifdef CONFIG_KGDB_SYSRQ
-+                sysrq_down = 0;        /* in case we miss the "up" event */
-+#endif
- 		return;
- 	}
- #endif
-diff -puN drivers/char/sysrq.c~kgdb-ga drivers/char/sysrq.c
---- 25/drivers/char/sysrq.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/drivers/char/sysrq.c	2003-06-25 23:14:17.000000000 -0700
-@@ -35,6 +35,19 @@
- #include <linux/spinlock.h>
- 
- #include <asm/ptrace.h>
-+#ifdef CONFIG_KGDB_SYSRQ
-+
-+#define  GDB_OP &kgdb_op
-+static struct sysrq_key_op kgdb_op={
-+	handler:	(void*)breakpoint,
-+	help_msg:	"kGdb ",
-+	action_msg:	"Debug breakpoint\n",
-+};
-+
-+#else
-+#define  GDB_OP NULL
-+#endif
-+
- 
- extern void reset_vc(unsigned int);
- extern struct list_head super_blocks;
-@@ -240,7 +253,7 @@ static struct sysrq_key_op *sysrq_key_ta
- /* d */	NULL,
- /* e */	&sysrq_term_op,
- /* f */	NULL,
--/* g */	NULL,
-+/* g */	GDB_OP,
- /* h */	NULL,
- /* i */	&sysrq_kill_op,
- /* j */	NULL,
-diff -puN drivers/serial/8250.c~kgdb-ga drivers/serial/8250.c
---- 25/drivers/serial/8250.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/drivers/serial/8250.c	2003-06-25 23:14:17.000000000 -0700
-@@ -823,7 +823,7 @@ receive_chars(struct uart_8250_port *up,
- 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
- 			tty->flip.work.func((void *)tty);
- 			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
--				return; // if TTY_DONT_FLIP is set
-+				return;	/* if TTY_DONT_FLIP is set */
- 		}
- 		ch = serial_inp(up, UART_RX);
- 		*tty->flip.char_buf_ptr = ch;
-@@ -1183,13 +1183,20 @@ static void serial8250_break_ctl(struct 
- 	serial_out(up, UART_LCR, up->lcr);
- 	spin_unlock_irqrestore(&up->port.lock, flags);
- }
-+#ifdef CONFIG_KGDB
-+static int kgdb_irq = -1;
-+#endif
- 
- static int serial8250_startup(struct uart_port *port)
- {
- 	struct uart_8250_port *up = (struct uart_8250_port *)port;
- 	unsigned long flags;
- 	int retval;
--
-+#ifdef CONFIG_KGDB
-+	if ( up->port.irq == kgdb_irq){
-+		return -EBUSY;
-+	}
-+#endif
- 	if (up->port.type == PORT_16C950) {
- 		/* Wake up and initialize UART */
- 		up->acr = 0;
-@@ -1853,6 +1860,11 @@ static void __init serial8250_register_p
- 	for (i = 0; i < UART_NR; i++) {
- 		struct uart_8250_port *up = &serial8250_ports[i];
- 
-+#ifdef CONFIG_KGDB
-+		if(up->port.irq == kgdb_irq){
-+			up->port.iobase = up->port.mapbase = 0;
-+		}
-+#endif
- 		up->port.line = i;
- 		up->port.ops = &serial8250_pops;
- 		init_timer(&up->timer);
-@@ -2116,7 +2128,31 @@ void serial8250_resume_port(int line, u3
- {
- 	uart_resume_port(&serial8250_reg, &serial8250_ports[line].port, level);
- }
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * Find all the ports using the given irq and shut them down.
-+ * Result should be that the irq will be released.
-+ */
-+void shutdown_for_kgdb(struct async_struct * info)
-+{
-+        int irq = info->state->irq;
-+        struct uart_8250_port *up;
-+	int ttyS;
-+
-+	kgdb_irq = irq;			/* save for later init */
-+	for (ttyS = 0; ttyS < UART_NR; ttyS++){
-+		up =  &serial8250_ports[ttyS];
-+		if( up->port.irq == irq && (irq_lists + irq)->head){
-+#ifdef CONFIG_DEBUG_SPINLOCK   /* ugly business... */
-+			if(up->port.lock.magic != SPINLOCK_MAGIC){
-+				spin_lock_init(&up->port.lock);
-+			}
-+#endif
-+			serial8250_shutdown(&up->port);
-+		}
-+        }
-+}
-+#endif
- static int __init serial8250_init(void)
- {
- 	int ret, i;
-diff -puN include/asm-i386/bugs.h~kgdb-ga include/asm-i386/bugs.h
---- 25/include/asm-i386/bugs.h~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/include/asm-i386/bugs.h	2003-06-25 23:14:17.000000000 -0700
-@@ -1,11 +1,11 @@
- /*
-  *  include/asm-i386/bugs.h
-  *
-- *  Copyright (C) 1994  Linus Torvalds
-+ *  Copyright (C) 1994	Linus Torvalds
-  *
-  *  Cyrix stuff, June 1998 by:
-  *	- Rafael R. Reilova (moved everything from head.S),
-- *        <rreilova@ececs.uc.edu>
-+ *	  <rreilova@ececs.uc.edu>
-  *	- Channing Corn (tests & fixes),
-  *	- Andrew D. Balsa (code cleanup).
-  *
-@@ -25,7 +25,20 @@
- #include <asm/processor.h>
- #include <asm/i387.h>
- #include <asm/msr.h>
--
-+#ifdef CONFIG_KGDB
-+/*
-+ * Provied the command line "gdb" initial break
-+ */
-+int __init kgdb_initial_break(char * str)
-+{
-+	if (*str == '\0'){
-+		breakpoint();
-+		return 1;
-+	}
-+	return 0;
-+}
-+__setup("gdb",kgdb_initial_break);
-+#endif
- static int __init no_halt(char *s)
- {
- 	boot_cpu_data.hlt_works_ok = 0;
-@@ -140,7 +153,7 @@ static void __init check_popad(void)
- 	  : "ecx", "edi" );
- 	/* If this fails, it means that any user program may lock the CPU hard. Too bad. */
- 	if (res != 12345678) printk( "Buggy.\n" );
--		        else printk( "OK.\n" );
-+			else printk( "OK.\n" );
- #endif
- }
- 
-diff -puN /dev/null include/asm-i386/kgdb.h
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/include/asm-i386/kgdb.h	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,59 @@
-+#ifndef __KGDB
-+#define __KGDB
-+
-+/*
-+ * This file should not include ANY others.  This makes it usable
-+ * most anywhere without the fear of include order or inclusion.
-+ * Make it so!
-+ *
-+ * This file may be included all the time.  It is only active if 
-+ * CONFIG_KGDB is defined, otherwise it stubs out all the macros
-+ * and entry points.
-+ */
-+#if defined(CONFIG_KGDB) && !defined(__ASSEMBLY__)
-+
-+extern void breakpoint(void);
-+#define INIT_KGDB_INTS kgdb_enable_ints()
-+
-+#ifndef BREAKPOINT
-+#define BREAKPOINT   asm("   int $3")
-+#endif
-+/*
-+ * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
-+ * pointer to its routine and it will be entered as the first thing
-+ * when a trap occurs.
-+ *
-+ * Return values are, at present, undefined.
-+ *
-+ * The debug hook routine does not necessarily return to its caller.
-+ * It has the register image and thus may choose to resume execution
-+ * anywhere it pleases. 
-+ */
-+struct pt_regs;
-+
-+extern int kgdb_handle_exception(int trapno,
-+				 int signo, int err_code, struct pt_regs *regs);
-+extern int in_kgdb(struct pt_regs *regs);
-+
-+#ifdef CONFIG_KGDB_TS
-+void kgdb_tstamp(int line, char *source, int data0, int data1);
-+/*
-+ * This is the time stamp function.  The macro adds the source info and
-+ * does a cast on the data to allow most any 32-bit value.
-+ */
-+
-+#define kgdb_ts(data0,data1) kgdb_tstamp(__LINE__,__FILE__,(int)data0,(int)data1)
-+#else
-+#define kgdb_ts(data0,data1)
-+#endif
-+#else				/* CONFIG_KGDB  && ! __ASSEMBLY__ ,stubs follow... */
-+#ifndef BREAKPOINT
-+#define BREAKPOINT
-+#endif
-+#define kgdb_ts(data0,data1)
-+#define in_kgdb
-+#define kgdb_handle_exception
-+#define breakpoint
-+#define INIT_KGDB_INTS
-+#endif
-+#endif				/* __KGDB */
-diff -puN /dev/null include/asm-i386/kgdb_local.h
---- /dev/null	2002-08-30 16:31:37.000000000 -0700
-+++ 25-akpm/include/asm-i386/kgdb_local.h	2003-06-25 23:14:17.000000000 -0700
-@@ -0,0 +1,102 @@
-+#ifndef __KGDB_LOCAL
-+#define ___KGDB_LOCAL
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/serial.h>
-+#include <linux/serialP.h>
-+#include <linux/spinlock.h>
-+#include <asm/processor.h>
-+#include <asm/msr.h>
-+#include <asm/kgdb.h>
-+
-+#define PORT 0x3f8
-+#ifdef CONFIG_KGDB_PORT
-+#undef PORT
-+#define PORT CONFIG_KGDB_PORT
-+#endif
-+#define IRQ 4
-+#ifdef CONFIG_KGDB_IRQ
-+#undef IRQ
-+#define IRQ CONFIG_KGDB_IRQ
-+#endif
-+#define SB_CLOCK 1843200
-+#define SB_BASE (SB_CLOCK/16)
-+#define SB_BAUD9600 SB_BASE/9600
-+#define SB_BAUD192  SB_BASE/19200
-+#define SB_BAUD384  SB_BASE/38400
-+#define SB_BAUD576  SB_BASE/57600
-+#define SB_BAUD1152 SB_BASE/115200
-+#ifdef CONFIG_KGDB_9600BAUD
-+#define SB_BAUD SB_BAUD9600
-+#endif
-+#ifdef CONFIG_KGDB_19200BAUD
-+#define SB_BAUD SB_BAUD192
-+#endif
-+#ifdef CONFIG_KGDB_38400BAUD
-+#define SB_BAUD SB_BAUD384
-+#endif
-+#ifdef CONFIG_KGDB_57600BAUD
-+#define SB_BAUD SB_BAUD576
-+#endif
-+#ifdef CONFIG_KGDB_115200BAUD
-+#define SB_BAUD SB_BAUD1152
-+#endif
-+#ifndef SB_BAUD
-+#define SB_BAUD SB_BAUD1152	/* Start with this if not given */
-+#endif
-+
-+#ifndef CONFIG_X86_TSC
-+#undef rdtsc
-+#define rdtsc(a,b) if (a++ > 10000){a = 0; b++;}
-+#undef rdtscll
-+#define rdtscll(s) s++
-+#endif
-+
-+#ifdef _raw_read_unlock		/* must use a name that is "define"ed, not an inline */
-+#undef spin_lock
-+#undef spin_trylock
-+#undef spin_unlock
-+#define spin_lock	 _raw_spin_lock
-+#define spin_trylock	 _raw_spin_trylock
-+#define spin_unlock	 _raw_spin_unlock
-+#else
-+#endif
-+#undef spin_unlock_wait
-+#define spin_unlock_wait(x)  do { cpu_relax(); barrier();} \
-+                                     while(spin_is_locked(x))
-+
-+#define SB_IER 1
-+#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
-+
-+#define FLAGS 0
-+#define SB_STATE { \
-+     magic: SSTATE_MAGIC, \
-+     baud_base: SB_BASE,  \
-+     port:      PORT,     \
-+     irq:       IRQ,      \
-+     flags:     FLAGS,    \
-+     custom_divisor:SB_BAUD}
-+#define SB_INFO  { \
-+      magic: SERIAL_MAGIC, \
-+      port:  PORT,0,FLAGS, \
-+      state: &state,       \
-+      tty:   (struct tty_struct *)&state, \
-+      IER:   SB_IER,       \
-+      MCR:   SB_MCR}
-+extern void putDebugChar(int);
-+/* RTAI support needs us to really stop/start interrupts */
-+
-+#define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
-+#define kgdb_cli() __asm__ __volatile__("cli": : :"memory")
-+#define kgdb_local_save_flags(x) __asm__ __volatile__(\
-+                                   "pushfl ; popl %0":"=g" (x): /* no input */)
-+#define kgdb_local_irq_restore(x) __asm__ __volatile__(\
-+                                   "pushl %0 ; popfl": \
-+                                     /* no output */ :"g" (x):"memory", "cc")
-+#define kgdb_local_irq_save(x) kgdb_local_save_flags(x); kgdb_cli()
-+
-+#ifdef CONFIG_SERIAL
-+extern void shutdown_for_kgdb(struct async_struct *info);
-+#endif
-+#define INIT_KDEBUG putDebugChar("+");
-+#endif				/* __KGDB_LOCAL */
-diff -puN include/linux/config.h~kgdb-ga include/linux/config.h
---- 25/include/linux/config.h~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/include/linux/config.h	2003-06-25 23:14:17.000000000 -0700
-@@ -2,5 +2,8 @@
- #define _LINUX_CONFIG_H
- 
- #include <linux/autoconf.h>
-+#ifdef CONFIG_X86
-+#include <asm/kgdb.h>
-+#endif
- 
- #endif
-diff -puN kernel/sched.c~kgdb-ga kernel/sched.c
---- 25/kernel/sched.c~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/kernel/sched.c	2003-06-25 23:14:17.000000000 -0700
-@@ -1604,6 +1604,13 @@ out_unlock:
- 	task_rq_unlock(rq, &flags);
- }
- 
-+#if defined( CONFIG_KGDB) 
-+struct task_struct * kgdb_get_idle(int this_cpu)
-+{
-+        return runqueues[this_cpu].idle;
-+}
-+#endif
-+
- #ifndef __alpha__
- 
- /*
-diff -puN MAINTAINERS~kgdb-ga MAINTAINERS
---- 25/MAINTAINERS~kgdb-ga	2003-06-25 23:14:17.000000000 -0700
-+++ 25-akpm/MAINTAINERS	2003-06-25 23:14:17.000000000 -0700
-@@ -1059,6 +1059,12 @@ L:	kbuild-devel@lists.sourceforge.net
- W:	http://kbuild.sourceforge.net
- S:	Maintained 
- 
-+KGDB FOR I386 PLATFORM
-+P:	George Anzinger
-+M:	george@mvista.com
-+L:	linux-net@vger.kernel.org
-+S:	Supported
-+
- KERNEL NFSD
- P:	Neil Brown
- M:	neilb@cse.unsw.edu.au
-
-_
diff --git a/lustre/kernel_patches/patches/kgdb-ga-docco-fixes-2.5.73.patch b/lustre/kernel_patches/patches/kgdb-ga-docco-fixes-2.5.73.patch
deleted file mode 100644
index 47d451c51d70d62f2afff3ae4e24dc7f324945c9..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/kgdb-ga-docco-fixes-2.5.73.patch
+++ /dev/null
@@ -1,347 +0,0 @@
-
-From: "Randy.Dunlap" <rddunlap@osdl.org>
-
-Just some readability fixes.
-
-
-
- Documentation/i386/kgdb/kgdb.txt |  135 +++++++++++++++++++--------------------
- 1 files changed, 68 insertions(+), 67 deletions(-)
-
-diff -puN Documentation/i386/kgdb/kgdb.txt~kgdb-gs-docco-fixes Documentation/i386/kgdb/kgdb.txt
---- 25/Documentation/i386/kgdb/kgdb.txt~kgdb-gs-docco-fixes	2003-06-26 17:32:25.000000000 -0700
-+++ 25-akpm/Documentation/i386/kgdb/kgdb.txt	2003-06-26 17:32:25.000000000 -0700
-@@ -6,10 +6,10 @@ New features: 
- ============
- 20030505.1827.27
- We are starting to align with the sourceforge version, at least in 
--commands.  To this end, the boot command sting to start kgdb at
-+commands.  To this end, the boot command string to start kgdb at
- boot time has been changed from "kgdb" to "gdb".
- 
--Andrew Morton sent a couple of patchs which are now included as follows:
-+Andrew Morton sent a couple of patches which are now included as follows:
- 1.) We now return a flag to the interrupt handler.
- 2.) We no longer use smp_num_cpus (a conflict with the lock meter).
- 3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
-@@ -27,18 +27,18 @@ This is currently the version for the 2.
- 
- We have several new "features" beginning with this version:
-  
--1.) Kgdb now syncs the "other" cpus with a cross cpu NMI.  No more
--    waiting and it will pull that guy out of an irq off spin lock :)
-+1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI.  No more
-+    waiting and it will pull that guy out of an IRQ off spin lock :)
- 
- 2.) We doctored up the code that tells where a task is waiting and
-     included it so that the "info thread" command will show a bit more
-     than "schedule()".  Try it...
- 
- 3.) Added the ability to call a function from gdb.  All the standard gdb
--    issues apply, i.e. if you hit a break point in the function you are
--    not allowed to call another (gdb limitation, not kgdb).  T0 help
-+    issues apply, i.e. if you hit a breakpoint in the function, you are
-+    not allowed to call another (gdb limitation, not kgdb).  To help
-     this capability we added a memory allocation function.  Gdb does not
--    return this memory (it is used for stings you pass to that function
-+    return this memory (it is used for strings that you pass to that function
-     you are calling from gdb) so we fixed up a way to allow you to
-     manually return the memory (see below).
- 
-@@ -61,23 +61,23 @@ $2 = {used_malloc = 0, called_from = 0xc
-     Things to note here: a.) used_malloc is the amount of memory that
-     has been malloc'ed to do calls from gdb.  You can reclaim this
-     memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
--    cpus_waiting is now "sized" by the number of cpus you enter at
--    configure time in the kgdb configure section.  This is NOT used any
--    where else in the system, but it is "nice" here.  c.)  The tasks
-+    cpus_waiting is now "sized" by the number of CPUs you enter at
-+    configure time in the kgdb configure section.  This is NOT used
-+    anywhere else in the system, but it is "nice" here.  c.)  The task's
-     "pid" is now in the structure.  This is the pid you will need to use
-     to decode to the thread id to get gdb to look at that thread.
-     Remember that the "info thread" command prints a list of threads
--    where in it numbers each thread with its reference number followed
--    by the threads pid.  Note that the per cpu idle threads actually
--    have pids of 0 (yes there is more than one pid 0 in an SMP system).
-+    wherein it numbers each thread with its reference number followed
-+    by the thread's pid.  Note that the per-CPU idle threads actually
-+    have pids of 0 (yes, there is more than one pid 0 in an SMP system).
-     To avoid confusion, kgdb numbers these threads with numbers beyond
--    the MAX_PID.  That is why you see 32768 above.
-+    the MAX_PID.  That is why you see 32768 and above.
- 
- 6.) A subtle change, we now provide the complete register set for tasks
--    that are active on the other cpus.  This allows better trace back on
-+    that are active on the other CPUs.  This allows better trace back on
-     those tasks.
- 
--    And, lets mention what we could not fix.  Back-trace from all but the
-+    And, let's mention what we could not fix.  Back-trace from all but the
-     thread that we trapped will, most likely, have a bogus entry in it.
-     The problem is that gdb does not recognize the entry code for
-     functions that use "current" near (at all?) the entry.  The compiler
-@@ -88,9 +88,9 @@ $2 = {used_malloc = 0, called_from = 0xc
- 
- 20011220.0050.35
- Major enhancement with this version is the ability to hold one or more
--cpus in an SMP system while allowing the others to continue.  Also, by
--default only the current cpu is enabled on single step commands (please
--note that gdb issues single step commands at times other than when you
-+CPUs in an SMP system while allowing the others to continue.  Also, by
-+default only the current CPU is enabled on single-step commands (please
-+note that gdb issues single-step commands at times other than when you
- use the si command).
-  
- Another change is to collect some useful information in
-@@ -111,14 +111,14 @@ $4 = {called_from = 0xc010732c, entry_ts
- 
- "Called_from" is the return address from the current entry into kgdb.  
- Sometimes it is useful to know why you are in kgdb, for example, was 
--it an NMI or a real break point?  The simple way to interrogate this 
-+it an NMI or a real breakpoint?  The simple way to interrogate this
- return address is:
- 
- l *0xc010732c
- 
- which will print the surrounding few lines of source code.
- 
--"Entry_tsc" is the cpu TSC on entry to kgdb (useful to compare to the
-+"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
- kgdb_ts entries).
- 
- "errcode" and "vector" are other entry parameters which may be helpful on
-@@ -139,34 +139,34 @@ $7 = {called_from = 0xc0112739, entry_ts
-       hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0, 
-       hold = 0, regs = 0x0}}}
- 
--"Cpus_waiting" has an entry for each cpu other than the current one that 
-+"Cpus_waiting" has an entry for each CPU other than the current one that
- has been stopped.  Each entry contains the task_struct address for that
--cpu, the address of the regs for that task and a hold flag.  All these
-+CPU, the address of the regs for that task and a hold flag.  All these
- have the proper typing so that, for example:
- 
- p *kgdb_info.cpus_waiting[1].regs
- 
--will print the registers for cpu 1.
-+will print the registers for CPU 1.
- 
- "Hold_on_sstep" is a new feature with this version and comes up set or
--true.  What is means is that whenever kgdb is asked to single step all
--other cpus are held (i.e. not allowed to execute).  The flag applies to
--all but the current cpu and, again, can be changed:
-+true.  What this means is that whenever kgdb is asked to single-step all
-+other CPUs are held (i.e. not allowed to execute).  The flag applies to
-+all but the current CPU and, again, can be changed:
- 
- p kgdb_info.hold_on_sstep=0
- 
--restores the old behavior of letting all cpus run during single stepping.
-+restores the old behavior of letting all CPUs run during single-stepping.
- 
--Likewise, each cpu has a "hold" flag, which if set, locks that cpu out
--of execution.  Note that this has some risk in cases where the cpus need
--to communicate with each other.  If kgdb finds no cpu available on exit,
-+Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
-+of execution.  Note that this has some risk in cases where the CPUs need
-+to communicate with each other.  If kgdb finds no CPU available on exit,
- it will push a message thru gdb and stay in kgdb.  Note that it is legal
--to hold the current cpu as long as at least one cpu can execute.
-+to hold the current CPU as long as at least one CPU can execute.
- 
- 20010621.1117.09
- This version implements an event queue.  Events are signaled by calling
- a function in the kgdb stub and may be examined from gdb.  See EVENTS 
--below for details.  This version also tighten up the interrupt and SMP
-+below for details.  This version also tightens up the interrupt and SMP
- handling to not allow interrupts on the way to kgdb from a breakpoint 
- trap.  It is fine to allow these interrupts for user code, but not
- system debugging.
-@@ -190,18 +190,18 @@ machine.  This is the machine that will 
- kernel.
- 
- The two machines will be connected together via a serial line out
--one or the other of the COM ports of the PC.  You will need a modem
--eliminator and the appropriate cables.
-+one or the other of the COM ports of the PC.  You will need the
-+appropriate modem eliminator (null modem) cable(s) for this.
- 
- Decide on which tty port you want the machines to communicate, then
--cable them up back-to-back using the null modem.  COM1 is /dev/ttyS0 and
--COM2 is /dev/ttyS1. You should test this connection with the two
--machines prior to trying to debug a kernel.  Once you have it working,
--on the TARGET machine, enter:
-+connect them up back-to-back using the null modem cable.  COM1 is
-+/dev/ttyS0 and COM2 is /dev/ttyS1. You should test this connection
-+with the two machines prior to trying to debug a kernel.  Once you
-+have it working, on the TARGET machine, enter:
- 
- setserial /dev/ttyS0 (or what ever tty you are using)
- 
--and record the port and the irq addresses. 
-+and record the port address and the IRQ number.
- 
- On the DEVELOPMENT machine you need to apply the patch for the kgdb
- hooks.  You have probably already done that if you are reading this
-@@ -212,7 +212,7 @@ On your DEVELOPMENT machine, go to your 
- configuring in the standard serial driver, it must not be a module.
- Either yes or no is ok, but making the serial driver a module means it
- will initialize after kgdb has set up the UART interrupt code and may
--cause a failure of the control C option discussed below.  The configure
-+cause a failure of the control-C option discussed below.  The configure
- question for the serial driver is under the "Character devices" heading
- and is:
- 
-@@ -231,16 +231,16 @@ The baud rate.  Default is 115200.  What
- the host machine is set to the same speed.  I recommend the default.
- 
- The port.  This is the I/O address of the serial UART that you should
--have gotten using setserial as described above.  The standard com1 port
--(3f8) using irq 4 is default .  Com2 is 2f8 which by convention uses irq
-+have gotten using setserial as described above.  The standard COM1 port
-+(3f8) using IRQ 4 is default.  COM2 is 2f8 which by convention uses IRQ
- 3.
- 
--The port irq (see above).
-+The port IRQ (see above).
- 
- Stack overflow test.  This option makes a minor change in the trap,
- system call and interrupt code to detect stack overflow and transfer
--control to kgdb if it happens.  (Some platforms have this in the base
--line code, but the i386 does not.)
-+control to kgdb if it happens.  (Some platforms have this in the
-+baseline code, but the i386 does not.)
- 
- You can also configure the system to recognize the boot option
- "console=kgdb" which if given will cause all console output during
-@@ -251,9 +251,9 @@ This will happen before any kernel outpu
- and will stall the boot until the connection is made.
- 
- You can also configure in a patch to SysRq to enable the kGdb SysRq.
--This request generates a breakpoint.  Since the serial port irq line is
-+This request generates a breakpoint.  Since the serial port IRQ line is
- set up after any serial drivers, it is possible that this command will
--work when the control C will not.
-+work when the control-C will not.
- 
- Save and exit the Xconfig program.  Then do "make clean" , "make dep"
- and "make bzImage" (or whatever target you want to make).  This gets the
-@@ -360,11 +360,11 @@ Triggering kgdbstub at other times
- Often you don't need to enter the debugger until much later in the boot
- or even after the machine has been running for some time.  Once the
- kernel is booted and interrupts are on, you can force the system to
--enter the debugger by sending a control C to the debug port. This is
-+enter the debugger by sending a control-C to the debug port. This is
- what the first line of the recommended .gdbinit file does.  This allows
- you to start gdb any time after the system is up as well as when the
--system is already at a break point.  (In the case where the system is
--already at a break point the control C is not needed, however, it will
-+system is already at a breakpoint.  (In the case where the system is
-+already at a breakpoint the control-C is not needed, however, it will
- be ignored by the target so no harm is done.  Also note the the echo
- command assumes that the port speed is already set.  This will be true
- once gdb has connected, but it is best to set the port speed before you
-@@ -442,7 +442,7 @@ turn on a debug switch with the followin
- This will print out the protocol messages that gdb is exchanging with
- the target machine.
- 
--Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c This is
-+Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c. This is
- the code that talks to the serial port on the target side.  There might
- be a problem there.  In particular there is a section of this code that
- tests the UART which will tell you what UART you have if you define
-@@ -454,7 +454,7 @@ it finds.  (You need to wait so that the
- printed.  Early in the boot they are cached, waiting for the console to
- be enabled.  Also, if kgdb is entered thru a breakpoint it is possible
- to cause a dead lock by calling printk when the console is locked.  The
--stub, thus avoids doing printks from break points especially in the
-+stub thus avoids doing printks from breakpoints, especially in the
- serial code.)  At this time, if the UART fails to do the expected thing,
- kgdb will print out (using printk) information on what failed.  (These
- messages will be buried in all the other boot up messages.  Look for
-@@ -464,7 +464,7 @@ don't connect, review your answers for t
- 
- setserial /dev/ttyS0 
- 
--to get the current port and irq information.  This command will also
-+to get the current port and IRQ information.  This command will also
- tell you what the system found for the UART type. The stub recognizes
- the following UART types:
- 
-@@ -581,11 +581,11 @@ When a breakpoint occurs or user issues 
- client, all the processors are forced to enter the debugger. Current
- thread corresponds to the thread running on the processor where
- breakpoint occurred.  Threads running on other processor(s) appear
--similar to other non running threads in the 'info threads' output.  With
--in the kgdb stub there is a structure "waiting_cpus" in which kgdb
--records the values of "current" and "regs" for each cpu other than the
-+similar to other non-running threads in the 'info threads' output.
-+Within the kgdb stub there is a structure "waiting_cpus" in which kgdb
-+records the values of "current" and "regs" for each CPU other than the
- one that hit the breakpoint.  "current" is a pointer to the task
--structure for the task that cpu is running, while "regs" points to the
-+structure for the task that CPU is running, while "regs" points to the
- saved registers for the task.  This structure can be examined with the
- gdb "p" command.
- 
-@@ -601,22 +601,23 @@ Kill it. restart gdb. Connect to target 
- 2. gdb cannot connect to target machine (after killing a gdb and
- restarting another) If the target machine was not inside debugger when
- you killed gdb, gdb cannot connect because the target machine won't
--respond.  In this case echo "Ctrl+C"(ASCII 3) in the serial line.
--e.g. echo -e "\003" > /dev/ttyS1 This forces that target machine into
--debugger after which you can connect.
-+respond.  In this case echo "Ctrl+C"(ASCII 3) to the serial line.
-+e.g. echo -e "\003" > /dev/ttyS1
-+This forces that target machine into the debugger, after which you
-+can connect.
- 
- 3. gdb cannot connect even after echoing Ctrl+C into serial line
- Try changing serial line settings min to 1 and time to 0
- e.g. stty min 1 time 0 < /dev/ttyS1
- Try echoing again
- 
--check serial line speed and set it to correct value if required
-+Check serial line speed and set it to correct value if required
- e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
- 
- EVENTS
- ======
- 
--Ever want to know the order of things happening?  Which cpu did what and
-+Ever want to know the order of things happening?  Which CPU did what and
- when?  How did the spinlock get the way it is?  Then events are for
- you.  Events are defined by calls to an event collection interface and
- saved for later examination.  In this case, kgdb events are saved by a
-@@ -631,7 +632,7 @@ Events are signaled to kgdb by calling:
- kgdb_ts(data0,data1)
- 
- For each call kgdb records each call in an array along with other info.
--Here is the array def:
-+Here is the array definition:
- 
- struct kgdb_and_then_struct {
- #ifdef CONFIG_SMP
-@@ -646,7 +647,7 @@ struct kgdb_and_then_struct {
- 	int	data1;
- };
- 
--For SMP machines the cpu is recorded, for all machines the TSC is
-+For SMP machines the CPU is recorded, for all machines the TSC is
- recorded (gets a time stamp) as well as the line number and source file
- the call was made from.  The address of the (from), the "if" (interrupt
- flag) and the two data items are also recorded.  The macro kgdb_ts casts
-@@ -709,7 +710,7 @@ Amit S. Kale
-     Extended threads to include the idle threads.
-     Enhancements to allow breakpoint() at first C code.
-     Use of module_init() and __setup() to automate the configure.
--    Enhanced the cpu "collection" code to work in early bring up.
-+    Enhanced the cpu "collection" code to work in early bring-up.
-     Added ability to call functions from gdb
-     Print info thread stuff without going back to schedule()
--    Now collect the "other" cpus with a IPI/ NMI.
-\ No newline at end of file
-+    Now collect the "other" cpus with an IPI/ NMI.
-
-_
diff --git a/lustre/kernel_patches/patches/kgdb-over-netpoll.patch b/lustre/kernel_patches/patches/kgdb-over-netpoll.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2f7548a0d73b7bc82a053f456073498c41a935d6
--- /dev/null
+++ b/lustre/kernel_patches/patches/kgdb-over-netpoll.patch
@@ -0,0 +1,1072 @@
+ l-mpm/Documentation/i386/kgdb/kgdbeth.txt |   88 +----
+ l-mpm/arch/i386/kernel/irq.c              |   10 
+ l-mpm/arch/i386/kernel/kgdb_stub.c        |  107 +-----
+ l-mpm/arch/i386/lib/kgdb_serial.c         |    2 
+ l-mpm/drivers/net/Makefile                |    5 
+ l-mpm/drivers/net/kgdb_eth.c              |  464 ++++--------------------------
+ l-mpm/include/asm-i386/kgdb.h                  |   11 
+ l-mpm/net/core/dev.c                      |    4 
+ 8 files changed, 129 insertions(+), 562 deletions(-)
+
+Index: linux-2.6.0-test6/drivers/net/kgdb_eth.c
+===================================================================
+--- linux-2.6.0-test6.orig/drivers/net/kgdb_eth.c	2003-10-12 13:12:22.000000000 +0800
++++ linux-2.6.0-test6/drivers/net/kgdb_eth.c	2003-10-12 13:12:25.000000000 +0800
+@@ -7,36 +7,26 @@
+  *
+  * Twiddled for 2.6 by Robert Walsh <rjwalsh@durables.org>
+  * and wangdi <wangdi@clusterfs.com>.
++ *
++ * Refactored for netpoll API by Matt Mackall <mpm@selenic.com>
++ *
+  */
+ 
+-#include <linux/module.h>
+-#include <linux/errno.h>
+-#include <linux/signal.h>
+ #include <linux/sched.h>
+-#include <linux/timer.h>
+ #include <linux/interrupt.h>
+ #include <linux/config.h>
+-#include <linux/major.h>
+ #include <linux/string.h>
+-#include <linux/fcntl.h>
+-#include <linux/termios.h>
+-#include <asm/kgdb.h>
+-#include <linux/if_ether.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/delay.h>
+-#include <net/tcp.h>
+-#include <net/udp.h>
++#include <linux/netpoll.h>
+ 
+ #include <asm/system.h>
++#include <asm/kgdb.h>
+ #include <asm/io.h>
+-#include <asm/segment.h>
+ #include <asm/bitops.h>
+ #include <asm/system.h>
+ #include <asm/irq.h>
+ #include <asm/atomic.h>
+ 
++
+ #define	GDB_BUF_SIZE	512		/* power of 2, please */
+ 
+ static char	kgdb_buf[GDB_BUF_SIZE] ;
+@@ -44,26 +34,28 @@
+ static atomic_t	kgdb_buf_in_cnt ;
+ static int	kgdb_buf_out_inx ;
+ 
++#define ETH_QUEUE_SIZE 256
++static char eth_queue[ETH_QUEUE_SIZE];
++static int outgoing_queue;
++
+ extern void	set_debug_traps(void) ;		/* GDB routine */
+ extern void	breakpoint(void);
+ 
+-unsigned int	kgdb_remoteip = 0;
+-unsigned short	kgdb_listenport = 6443;
+-unsigned short	kgdb_sendport= 6442;
+-int		kgdb_eth = -1; /* Default tty mode */
+-unsigned char	kgdb_remotemac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+-unsigned char	kgdb_localmac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+-volatile int	kgdb_eth_is_initializing = 0;
+-int		kgdb_eth_need_breakpoint[NR_CPUS];
++int kgdboe = 0; /* Default tty mode */
++int kgdb_eth_need_breakpoint[NR_CPUS];
+ 
+-struct net_device *kgdb_netdevice = NULL;
++static void rx_hook(struct netpoll *np, int port, char *msg, int len);
+ 
+-/*
+- * Get a char if available, return -1 if nothing available.
+- * Empty the receive buffer first, then look at the interface hardware.
+- */
+-static int
+-read_char(void)
++static struct netpoll np = {
++	.name = "kgdboe",
++	.dev_name = "eth0",
++	.rx_hook = rx_hook,
++	.local_port = 6443,
++	.remote_port = 6442,
++	.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
++};
++
++static int read_char(void)
+ {
+ 	/* intr routine has queued chars */
+ 	if (atomic_read(&kgdb_buf_in_cnt) != 0)
+@@ -79,287 +71,32 @@
+ 	return -1; /* no data */
+ }
+ 
+-/*
+- * Wait until the interface can accept a char, then write it.
+- */
+-static void
+-write_buffer(char *buf, int len)
++static void write_buffer(char *buf, int len)
+ {
+-	int			total_len, eth_len, ip_len, udp_len;
+-	struct in_device	*in_dev;
+-	struct sk_buff		*skb;
+-	struct udphdr		*udph;
+-	struct iphdr		*iph;
+-	struct ethhdr		*eth;
+-
+-	if (!(in_dev = (struct in_device *) kgdb_netdevice->ip_ptr)) {
+-		panic("No in_device available for interface!\n");
+-	}
+-
+-	if (!(in_dev->ifa_list)) {
+-		panic("No interface address set for interface!\n");
+-	}
+-
+-	udp_len = len + sizeof(struct udphdr);
+-	ip_len = eth_len = udp_len + sizeof(struct iphdr);
+-	total_len = eth_len + ETH_HLEN;
+-
+-	if (!(skb = alloc_skb(total_len, GFP_ATOMIC))) {
++	if (!np.dev)
+ 		return;
+-	}
+-
+-	atomic_set(&skb->users, 1);
+-	skb_reserve(skb, total_len - len);
+-
+-	memcpy(skb->data, (unsigned char *) buf, len);
+-	skb->len += len;
+-
+-	udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
+-	udph->source = htons(kgdb_listenport);
+-	udph->dest   = htons(kgdb_sendport);
+-	udph->len    = htons(udp_len);
+-	udph->check  = 0;
+-
+-	iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
+-	iph->version  = 4;
+-	iph->ihl      = 5;
+-	iph->tos      = 0;
+-	iph->tot_len  = htons(ip_len);
+-	iph->id       = 0;
+-	iph->frag_off = 0;
+-	iph->ttl      = 64;
+-	iph->protocol = IPPROTO_UDP;
+-	iph->check    = 0;
+-	iph->saddr    = in_dev->ifa_list->ifa_address;
+-	iph->daddr    = kgdb_remoteip;
+-	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
+-
+-	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
+-	eth->h_proto = htons(ETH_P_IP);
+-	memcpy(eth->h_source, kgdb_localmac, kgdb_netdevice->addr_len);
+-	memcpy(eth->h_dest, kgdb_remotemac, kgdb_netdevice->addr_len);
+-
+-repeat:
+-	spin_lock(&kgdb_netdevice->xmit_lock);
+-	kgdb_netdevice->xmit_lock_owner = smp_processor_id();
+-
+-	if (netif_queue_stopped(kgdb_netdevice)) {
+-		kgdb_netdevice->xmit_lock_owner = -1;
+-		spin_unlock(&kgdb_netdevice->xmit_lock);
+-
+-		kgdb_netdevice->poll_controller(kgdb_netdevice);
+-		goto repeat;
+-	}
+-
+-	kgdb_netdevice->hard_start_xmit(skb, kgdb_netdevice);
+-	kgdb_netdevice->xmit_lock_owner = -1;
+-	spin_unlock(&kgdb_netdevice->xmit_lock);
++	netpoll_send_udp(&np, buf, len);
+ }
+ 
+ /*
+- * In the interrupt state the target machine will not respond to any
+- * arp requests, so handle them here.
+- */
+-
+-static struct sk_buff *send_skb = NULL;
+-
+-void
+-kgdb_eth_reply_arp(void)
+-{
+-	if (send_skb) {
+-		spin_lock(&kgdb_netdevice->xmit_lock);
+-		kgdb_netdevice->xmit_lock_owner = smp_processor_id();
+-	    	kgdb_netdevice->hard_start_xmit(send_skb, kgdb_netdevice);
+-	    	kgdb_netdevice->xmit_lock_owner = -1;
+-	    	spin_unlock(&kgdb_netdevice->xmit_lock);
+-		send_skb = NULL;
+-	}
+-}
+-
+-static int
+-make_arp_request(struct sk_buff *skb)
+-{
+-	struct arphdr *arp;
+-	unsigned char *arp_ptr;
+-	int type = ARPOP_REPLY;
+-	int ptype = ETH_P_ARP;
+-	u32 sip, tip;
+-	unsigned char *sha, *tha;
+-	struct in_device *in_dev = (struct in_device *) kgdb_netdevice->ip_ptr;
+-
+-	/* No arp on this interface */
+-
+-	if (kgdb_netdevice->flags & IFF_NOARP) {
+-		return 0;
+-	}
+-
+-	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
+-				 (2 * kgdb_netdevice->addr_len) +
+-				 (2 * sizeof(u32))))) {
+-		return 0;
+-	}
+-
+-	skb->h.raw = skb->nh.raw = skb->data;
+-	arp = skb->nh.arph;
+-
+-	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
+-	     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
+-	    arp->ar_pro != htons(ETH_P_IP)) {
+-		return 0;
+-	}
+-
+-	/* Understand only these message types */
+-
+-	if (arp->ar_op != htons(ARPOP_REQUEST)) {
+-		return 0;
+-	}
+-
+-	/* Extract fields */
+-
+-	arp_ptr= (unsigned char *)(arp+1);
+-	sha = arp_ptr;
+-	arp_ptr += kgdb_netdevice->addr_len;
+-	memcpy(&sip, arp_ptr, 4);
+-	arp_ptr += 4;
+-	tha = arp_ptr;
+-	arp_ptr += kgdb_netdevice->addr_len;
+-	memcpy(&tip, arp_ptr, 4);
+-
+-	if (tip != in_dev->ifa_list->ifa_address) {
+-		return 0;
+-	}
+-
+-	if (kgdb_remoteip != sip) {
+-		return 0;
+-	}
+-
+-	/*
+-	 * Check for bad requests for 127.x.x.x and requests for multicast
+-	 * addresses.  If this is one such, delete it.
+-	 */
+-
+-	if (LOOPBACK(tip) || MULTICAST(tip)) {
+-		return 0;
+-	}
+-
+-	/* reply to the ARP request */
+-
+-	send_skb = alloc_skb(sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4) + LL_RESERVED_SPACE(kgdb_netdevice), GFP_ATOMIC);
+-
+-	if (send_skb == NULL) {
+-		return 0;
+-	}
+-
+-	skb_reserve(send_skb, LL_RESERVED_SPACE(kgdb_netdevice));
+-	send_skb->nh.raw = send_skb->data;
+-	arp = (struct arphdr *) skb_put(send_skb, sizeof(struct arphdr) + 2 * (kgdb_netdevice->addr_len + 4));
+-	send_skb->dev = kgdb_netdevice;
+-	send_skb->protocol = htons(ETH_P_ARP);
+-
+-	/* Fill the device header for the ARP frame */
+-
+-	if (kgdb_netdevice->hard_header &&
+-	    kgdb_netdevice->hard_header(send_skb, kgdb_netdevice, ptype,
+-				       kgdb_remotemac, kgdb_localmac,
+-				       send_skb->len) < 0) {
+-		kfree_skb(send_skb);
+-		return 0;
+-	}
+-
+-	/*
+-	 * Fill out the arp protocol part.
+-	 *
+-	 * we only support ethernet device type,
+-	 * which (according to RFC 1390) should always equal 1 (Ethernet).
+-	 */
+-
+-	arp->ar_hrd = htons(kgdb_netdevice->type);
+-	arp->ar_pro = htons(ETH_P_IP);
+-
+-	arp->ar_hln = kgdb_netdevice->addr_len;
+-	arp->ar_pln = 4;
+-	arp->ar_op = htons(type);
+-
+-	arp_ptr=(unsigned char *)(arp + 1);
+-
+-	memcpy(arp_ptr, kgdb_netdevice->dev_addr, kgdb_netdevice->addr_len);
+-	arp_ptr += kgdb_netdevice->addr_len;
+-	memcpy(arp_ptr, &tip, 4);
+-	arp_ptr += 4;
+-	memcpy(arp_ptr, kgdb_localmac, kgdb_netdevice->addr_len);
+-	arp_ptr += kgdb_netdevice->addr_len;
+-	memcpy(arp_ptr, &sip, 4);
+-	return 0;
+-}
+-
+-
+-/*
+  * Accept an skbuff from net_device layer and add the payload onto
+  * kgdb buffer
+- *
+- * When the kgdb stub routine getDebugChar() is called it draws characters
+- * out of the buffer until it is empty and then reads directly from the
+- * serial port.
+- *
+- * We do not attempt to write chars from the interrupt routine since
+- * the stubs do all of that via putDebugChar() which writes one byte
+- * after waiting for the interface to become ready.
+- *
+- * The debug stubs like to run with interrupts disabled since, after all,
+- * they run as a consequence of a breakpoint in the kernel.
+- *
+- * NOTE: Return value of 1 means it was for us and is an indication to
+- * the calling driver to destroy the sk_buff and not send it up the stack.
+  */
+-int
+-kgdb_net_interrupt(struct sk_buff *skb)
++static void rx_hook(struct netpoll *np, int port, char *msg, int len)
+ {
+-	unsigned char	chr;
+-	struct iphdr	*iph = (struct iphdr*)skb->data;
+-	struct udphdr	*udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
+-	unsigned char	*data = (unsigned char *) udph + sizeof(struct udphdr);
+-	int		len;
+-	int		i;
+-
+-	if ((kgdb_eth != -1) && (!kgdb_netdevice) &&
+-	    (iph->protocol == IPPROTO_UDP) &&
+-	    (be16_to_cpu(udph->dest) == kgdb_listenport)) {
+-		kgdb_sendport = be16_to_cpu(udph->source);
+-
+-		while (kgdb_eth_is_initializing)
+-			;
+-		if (!kgdb_netdevice)
+-			kgdb_eth_hook();
+-		if (!kgdb_netdevice) {
+-			/* Lets not even try again. */
+-			kgdb_eth = -1;
+-			return 0;
+-		}
+-	}
+-	if (!kgdb_netdevice) {
+-		return 0;
+-	}
+-	if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb) {
+-		make_arp_request(skb);
+-		return 0;
+-	}
+-	if (iph->protocol != IPPROTO_UDP) {
+-		return 0;
+-	}
++	int i, chr;
+ 
+-	if (be16_to_cpu(udph->dest) != kgdb_listenport) {
+-		return 0;
+-	}
++	np->remote_port = port;
+ 
+-	len = (be16_to_cpu(iph->tot_len) -
+-	       (sizeof(struct udphdr) + sizeof(struct iphdr)));
++	/* Is this gdb trying to attach? */
++	if (!netpoll_trap() && len == 8 && !strncmp(msg, "$Hc-1#09", 8))
++		kgdb_schedule_breakpoint();
+ 
+ 	for (i = 0; i < len; i++) {
+-		chr = data[i];
+-		if (chr == 3) {
+-			kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
+-			continue;
+-		}
++		chr = msg[i];
++		if (chr == 3)
++			kgdb_schedule_breakpoint();
++
+ 		if (atomic_read(&kgdb_buf_in_cnt) >= GDB_BUF_SIZE) {
+ 			/* buffer overflow, clear it */
+ 			kgdb_buf_in_inx = 0;
+@@ -371,112 +108,54 @@
+ 		kgdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
+ 		atomic_inc(&kgdb_buf_in_cnt);
+ 	}
+-
+-	if (!kgdb_netdevice->kgdb_is_trapped) {
+-		/*
+-		 * If a new gdb instance is trying to attach, we need to
+-		 * break here.
+-		 */
+-		if (!strncmp(data, "$Hc-1#09", 8))
+-			kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
+-	}
+-	return 1;
+ }
+-EXPORT_SYMBOL(kgdb_net_interrupt);
+ 
+-int
+-kgdb_eth_hook(void)
++static int option_setup(char *opt)
+ {
+-	char kgdb_netdev[16];
+-	extern void kgdb_respond_ok(void);
+-
+-	if (kgdb_remotemac[0] == 0xff) {
+-		panic("ERROR! 'gdbeth_remotemac' option not set!\n");
+-	}
+-	if (kgdb_localmac[0] == 0xff) {
+-		panic("ERROR! 'gdbeth_localmac' option not set!\n");
+-	}
+-	if (kgdb_remoteip == 0) {
+-		panic("ERROR! 'gdbeth_remoteip' option not set!\n");
+-	}
++	return netpoll_parse_options(&np, opt);
++}
+ 
+-	sprintf(kgdb_netdev,"eth%d",kgdb_eth);
++__setup("kgdboe=", option_setup);
+ 
++static int init_kgdboe(void)
++{
+ #ifdef CONFIG_SMP
+ 	if (num_online_cpus() > CONFIG_NO_KGDB_CPUS) {
+ 		printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
+ 		return -1;
+ 	}
+ #endif
+-	for (kgdb_netdevice = dev_base;
+-		kgdb_netdevice != NULL;
+-		kgdb_netdevice = kgdb_netdevice->next) {
+-		if (strncmp(kgdb_netdevice->name, kgdb_netdev, IFNAMSIZ) == 0) {
+-			break;
+-		}
+-	}
+-	if (!kgdb_netdevice) {
+-		printk("KGDB NET : Unable to find interface %s\n",kgdb_netdev);
+-		return -ENODEV;
+-	}
+ 
+-	/*
+-	 * Call GDB routine to setup the exception vectors for the debugger
+-	 */
+ 	set_debug_traps();
+ 
+-	/*
+-	 * Call the breakpoint() routine in GDB to start the debugging
+-	 * session.
+-	 */
+-	kgdb_eth_is_initializing = 1;
+-	kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
++	if(!np.remote_ip || netpoll_setup(&np))
++		return 1;
++
++	kgdboe = 1;
++
++	printk(KERN_INFO "kgdb: debugging over ethernet enabled\n");
++
+ 	return 0;
+ }
+ 
+-/*
+- * getDebugChar
+- *
+- * This is a GDB stub routine.  It waits for a character from the
+- * serial interface and then returns it.  If there is no serial
+- * interface connection then it returns a bogus value which will
+- * almost certainly cause the system to hang.
+- */
+-int
+-eth_getDebugChar(void)
++int eth_getDebugChar(void)
+ {
+-	volatile int	chr;
++	int chr;
+ 
+-	while ((chr = read_char()) < 0) {
+-		if (send_skb) {
+-			kgdb_eth_reply_arp();
+-		}
+-		if (kgdb_netdevice->poll_controller) {
+-			kgdb_netdevice->poll_controller(kgdb_netdevice);
+-		} else {
+-			printk("KGDB NET: Error - Device %s is not supported!\n", kgdb_netdevice->name);
+-			panic("Please add support for kgdb net to this driver");
+-		}
+-	}
++	while ((chr = read_char()) < 0)
++		netpoll_poll(&np);
+ 	return chr;
+ }
+ 
+-#define ETH_QUEUE_SIZE 256
+-static char eth_queue[ETH_QUEUE_SIZE];
+-static int outgoing_queue;
+-
+-void
+-eth_flushDebugChar(void)
++void eth_flushDebugChar(void)
+ {
+ 	if(outgoing_queue) {
+ 		write_buffer(eth_queue, outgoing_queue);
+-
+ 		outgoing_queue = 0;
+ 	}
+ }
+ 
+-static void
+-put_char_on_queue(int chr)
++static void put_char_on_queue(int chr)
+ {
+ 	eth_queue[outgoing_queue++] = chr;
+ 	if(outgoing_queue == ETH_QUEUE_SIZE)
+@@ -485,33 +164,26 @@
+ 	}
+ }
+ 
+-/*
+- * eth_putDebugChar
+- *
+- * This is a GDB stub routine.  It waits until the interface is ready
+- * to transmit a char and then sends it.
+- */
+-void
+-eth_putDebugChar(int chr)
++void eth_putDebugChar(int chr)
+ {
+ 	put_char_on_queue(chr); /* this routine will wait */
+ }
+ 
+-void
+-kgdb_eth_set_trapmode(int mode)
++void kgdb_schedule_breakpoint(void)
+ {
+-	if (!kgdb_netdevice) {
+-		return;
+-	}
+-	kgdb_netdevice->kgdb_is_trapped = mode;
++	kgdb_eth_need_breakpoint[smp_processor_id()] = 1;
+ }
+ 
+-int
+-kgdb_eth_is_trapped()
++void kgdb_process_breakpoint(void)
+ {
+-	if (!kgdb_netdevice) {
+-		return 0;
++	/*
++	 * Handle a breakpoint queued from inside network driver code
++         * to avoid reentrancy issues
++	 */
++	if (kgdb_eth_need_breakpoint[smp_processor_id()]) {
++		kgdb_eth_need_breakpoint[smp_processor_id()] = 0;
++		BREAKPOINT;
+ 	}
+-	return kgdb_netdevice->kgdb_is_trapped;
+ }
+-EXPORT_SYMBOL(kgdb_eth_is_trapped);
++
++module_init(init_kgdboe);
+Index: linux-2.6.0-test6/arch/i386/kernel/kgdb_stub.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/kgdb_stub.c	2003-10-12 13:12:22.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/kgdb_stub.c	2003-10-12 18:57:21.625083056 +0800
+@@ -120,6 +120,7 @@
+ #include <asm/desc.h>
+ #include <linux/inet.h>
+ #include <linux/kallsyms.h>
++#include <linux/netpoll.h>
+ 
+ /************************************************************************
+  *
+@@ -136,10 +137,6 @@
+ extern int eth_putDebugChar(int);     /* write a single character      */
+ extern int eth_getDebugChar(void);    /* read and return a single char */
+ extern void eth_flushDebugChar(void); /* flush pending characters      */
+-extern void kgdb_eth_set_trapmode(int);
+-extern void kgdb_eth_reply_arp(void);   /*send arp request */
+-extern volatile int kgdb_eth_is_initializing;
+-
+ 
+ /************************************************************************/
+ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+@@ -281,13 +278,13 @@
+ 
+ /*
+  * I/O dispatch functions...
+- * Based upon kgdb_eth, either call the ethernet
++ * Based upon kgdboe, either call the ethernet
+  * handler or the serial one..
+  */
+ void
+ putDebugChar(int c)
+ {
+-	if (kgdb_eth == -1) {
++	if (!kgdboe) {
+ 		tty_putDebugChar(c);
+ 	} else {
+ 		eth_putDebugChar(c);
+@@ -297,7 +294,7 @@
+ int
+ getDebugChar(void)
+ {
+-	if (kgdb_eth == -1) {
++	if (!kgdboe) {
+ 		return tty_getDebugChar();
+ 	} else {
+ 		return eth_getDebugChar();
+@@ -307,7 +304,7 @@
+ void
+ flushDebugChar(void)
+ {
+-	if (kgdb_eth == -1) {
++	if (!kgdboe) {
+ 		tty_flushDebugChar();
+ 	} else {
+ 		eth_flushDebugChar();
+@@ -494,66 +491,24 @@
+ 
+ 	/*  $<packet info>#<checksum>. */
+ 
+-	if (kgdb_eth == -1) {
+-		do {
+-			if (remote_debug)
+-				printk("T:%s\n", buffer);
+-			putDebugChar('$');
+-			checksum = 0;
+-			count = 0;
+-
+-			while ((ch = buffer[count])) {
+-				putDebugChar(ch);
+-				checksum += ch;
+-				count += 1;
+-			}
+-
+-			putDebugChar('#');
+-			putDebugChar(hexchars[checksum >> 4]);
+-			putDebugChar(hexchars[checksum % 16]);
+-			flushDebugChar();
+-
+-		} while ((getDebugChar() & 0x7f) != '+');
+-	} else {
+-		/*
+-		 * For udp, we can not transfer too much bytes once.
+-		 * We only transfer MAX_SEND_COUNT size bytes each time
+-		 */
+-
+-#define MAX_SEND_COUNT 30
+-
+-		int send_count = 0, i = 0;
+-		char send_buf[MAX_SEND_COUNT];
++	do {
++		if (remote_debug)
++			printk("T:%s\n", buffer);
++		putDebugChar('$');
++		checksum = 0;
++		count = 0;
++		while ((ch = buffer[count])) {
++			putDebugChar(ch);
++			checksum += ch;
++			count += 1;
++		}
++		
++		putDebugChar('#');
++		putDebugChar(hexchars[checksum >> 4]);
++		putDebugChar(hexchars[checksum % 16]);
++		flushDebugChar();
+ 
+-		do {
+-			if (remote_debug)
+-				printk("T:%s\n", buffer);
+-			putDebugChar('$');
+-			checksum = 0;
+-			count = 0;
+-			send_count = 0;
+-			while ((ch = buffer[count])) {
+-				if (send_count >= MAX_SEND_COUNT) {
+-					for(i = 0; i < MAX_SEND_COUNT; i++) {
+-						putDebugChar(send_buf[i]);
+-					}
+-					flushDebugChar();
+-					send_count = 0;
+-				} else {
+-					send_buf[send_count] = ch;
+-					checksum += ch;
+-					count ++;
+-					send_count++;
+-				}
+-			}
+-			for(i = 0; i < send_count; i++)
+-				putDebugChar(send_buf[i]);
+-			putDebugChar('#');
+-			putDebugChar(hexchars[checksum >> 4]);
+-			putDebugChar(hexchars[checksum % 16]);
+-			flushDebugChar();
+-		} while ((getDebugChar() & 0x7f) != '+');
+-	}
++	} while ((getDebugChar() & 0x7f) != '+');
+ }
+ 
+ static char remcomInBuffer[BUFMAX];
+@@ -1142,9 +1097,9 @@
+ 	 */
+ 	in_kgdb_entry_log[cpu]++;
+ 	in_kgdb_here_log[cpu] = regs;
+-	if (cpu == spinlock_cpu || waiting_cpus[cpu].task) {
++	if (cpu == spinlock_cpu || waiting_cpus[cpu].task)
+ 		goto exit_in_kgdb;
+-	}
++
+ 	/*
+ 	 * For protection of the initilization of the spin locks by kgdb
+ 	 * it locks the kgdb spinlock before it gets the wait locks set
+@@ -1153,16 +1108,18 @@
+ 	 * sequence where the wait lock is removed prior to the kgdb lock
+ 	 * so if kgdb gets unlocked, we just exit.
+ 	 */
++
+ 	while (spin_is_locked(&kgdb_spinlock) &&
+ 	       !spin_is_locked(waitlocks + cpu)) ;
+-	if (!spin_is_locked(&kgdb_spinlock)) {
++	if (!spin_is_locked(&kgdb_spinlock))
+ 		goto exit_in_kgdb;
+-	}
++
+ 	waiting_cpus[cpu].task = current;
+ 	waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
+ 	waiting_cpus[cpu].regs = regs;
+ 
+ 	spin_unlock_wait(waitlocks + cpu);
++
+ 	/*
+ 	 * log departure of this cpu
+ 	 */
+@@ -1281,9 +1238,8 @@
+ 
+ 	__asm__("movl %%cr2,%0":"=r" (address));
+ 
+-	if (kgdb_eth != -1) {
+-		kgdb_eth_set_trapmode(1);
+-	}
++	if (kgdboe)
++		netpoll_set_trap(1);
+ 
+ 	kgdb_local_irq_save(flags);
+ 
+@@ -1338,10 +1294,12 @@
+ 		if (num_online_cpus() > 1) {
+ 			int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
+ 			smp_send_nmi_allbutself();
++
+ 			while (i < num_online_cpus() && time != end_time) {
+ 				int j;
+ 				for (j = 0; j < MAX_NO_CPUS; j++) {
+ 					if (waiting_cpus[j].task &&
++					    waiting_cpus[j].task != NOCPU &&
+ 					    !cpu_logged_in[j]) {
+ 						i++;
+ 						cpu_logged_in[j] = 1;
+@@ -1526,13 +1484,8 @@
+ 	remcomOutBuffer[2] = hexchars[signo % 16];
+ 	remcomOutBuffer[3] = 0;
+ 
+-	if (kgdb_eth_is_initializing) {
+-		kgdb_eth_is_initializing = 0;
+-	} else {
+-		putpacket(remcomOutBuffer);
+-	}
++	putpacket(remcomOutBuffer);
+ 
+-	kgdb_eth_reply_arp();
+ 	while (1 == 1) {
+ 		error = 0;
+ 		remcomOutBuffer[0] = 0;
+@@ -1689,10 +1642,6 @@
+ 
+ 			newPC = regs.eip;
+ 
+-			if (kgdb_eth != -1) {
+-				kgdb_eth_set_trapmode(0);
+-			}
+-
+ 			/* clear the trace bit */
+ 			regs.eflags &= 0xfffffeff;
+ 
+@@ -1724,6 +1673,10 @@
+ 					}
+ 				}
+ 			}
++
++			if (kgdboe)
++				netpoll_set_trap(0);
++
+ 			correct_hw_break();
+ 			asm volatile ("movl %0, %%db6\n"::"r" (0));
+ 			goto exit_kgdb;
+@@ -2430,63 +2383,3 @@
+ 			   int signo, int err_code, struct pt_regs *linux_regs);
+ gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;	/* histerical reasons... */
+ 
+-static int __init kgdb_opt_kgdbeth(char *str)
+-{
+-	kgdb_eth = simple_strtoul(str, NULL, 10);
+-	return 1;
+-}
+-
+-static int __init kgdb_opt_kgdbeth_remoteip(char *str)
+-{
+-	kgdb_remoteip = in_aton(str);
+-	return 1;
+-}
+-
+-static int __init kgdb_opt_kgdbeth_listenport(char *str)
+-{
+-	kgdb_listenport = simple_strtoul(str, NULL, 10);
+-	kgdb_sendport = kgdb_listenport - 1;
+-	return 1;
+-}
+-
+-static int __init parse_hw_addr(char *str, unsigned char *addr)
+-{
+-	int  i;
+-	char *p;
+-
+-	p = str;
+-	i = 0;
+-	while(1)
+-	{
+-		unsigned int c;
+-
+-		sscanf(p, "%x:", &c);
+-		addr[i++] = c;
+-		while((*p != 0) && (*p != ':')) {
+-			p++;
+-		}
+-		if (*p == 0) {
+-			break;
+-		}
+-		p++;
+-	}
+-
+-	return 1;
+-}
+-
+-static int __init kgdb_opt_kgdbeth_remotemac(char *str)
+-{
+-	return parse_hw_addr(str, kgdb_remotemac);
+-}
+-static int __init kgdb_opt_kgdbeth_localmac(char *str)
+-{
+-	return parse_hw_addr(str, kgdb_localmac);
+-}
+-
+-
+-__setup("gdbeth=", kgdb_opt_kgdbeth);
+-__setup("gdbeth_remoteip=", kgdb_opt_kgdbeth_remoteip);
+-__setup("gdbeth_listenport=", kgdb_opt_kgdbeth_listenport);
+-__setup("gdbeth_remotemac=", kgdb_opt_kgdbeth_remotemac);
+-__setup("gdbeth_localmac=", kgdb_opt_kgdbeth_localmac);
+-
+Index: linux-2.6.0-test6/arch/i386/lib/kgdb_serial.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/lib/kgdb_serial.c	2003-10-12 13:12:22.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/lib/kgdb_serial.c	2003-10-12 13:12:25.000000000 +0800
+@@ -386,7 +386,7 @@
+ static int __init
+ kgdb_enable_ints(void)
+ {
+-	if (kgdb_eth != -1) {
++	if (kgdboe) {
+ 		return 0;
+ 	}
+ 	if (gdb_async_info == NULL) {
+Index: linux-2.6.0-test6/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/drivers/net/Makefile	2003-10-12 13:12:22.000000000 +0800
++++ linux-2.6.0-test6/drivers/net/Makefile	2003-10-12 13:12:25.000000000 +0800
+@@ -32,8 +32,6 @@
+ 
+ obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
+ 
+-obj-$(CONFIG_KGDB) += kgdb_eth.o
+-
+ obj-$(CONFIG_DGRS) += dgrs.o
+ obj-$(CONFIG_RCPCI) += rcpci.o
+ obj-$(CONFIG_VORTEX) += 3c59x.o
+@@ -109,6 +107,8 @@
+ ifeq ($(CONFIG_SLIP_COMPRESSED),y)
+   obj-$(CONFIG_SLIP) += slhc.o
+ endif
++# Must come after all NICs it might use
++obj-$(CONFIG_KGDB) += kgdb_eth.o
+ 
+ obj-$(CONFIG_DUMMY) += dummy.o
+ obj-$(CONFIG_DE600) += de600.o
+Index: linux-2.6.0-test6/include/asm-i386/kgdb.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/kgdb.h	2003-10-12 13:12:23.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/kgdb.h	2003-10-12 13:12:25.000000000 +0800
+@@ -21,17 +21,13 @@
+ 
+ struct sk_buff;
+ 
+-extern int kgdb_eth;
+-extern unsigned kgdb_remoteip;
+-extern unsigned short kgdb_listenport;
+-extern unsigned short kgdb_sendport;
+-extern unsigned char kgdb_remotemac[6];
+-extern unsigned char kgdb_localmac[6];
+ extern int kgdb_eth_need_breakpoint[];
++extern int kgdboe;
++extern void kgdb_schedule_breakpoint(void);
++extern void kgdb_process_breakpoint(void);
+ 
+ extern int kgdb_tty_hook(void);
+ extern int kgdb_eth_hook(void);
+-extern int gdb_net_interrupt(struct sk_buff *skb);
+ 
+ /*
+  * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
+Index: linux-2.6.0-test6/Documentation/i386/kgdb/kgdbeth.txt
+===================================================================
+--- linux-2.6.0-test6.orig/Documentation/i386/kgdb/kgdbeth.txt	2003-10-12 13:12:22.000000000 +0800
++++ linux-2.6.0-test6/Documentation/i386/kgdb/kgdbeth.txt	2003-10-12 13:12:25.000000000 +0800
+@@ -6,16 +6,20 @@
+ 
+ Robert Walsh <rjwalsh@durables.org>  (2.6 port)
+ wangdi <wangdi@clusterfs.com>        (2.6 port)
++Matt Mackall <mpm@selenic.com>       (netpoll api)
+ San Mehat                            (original 2.4 code)
+ 
+ 
+ Introduction
+ ------------
+ 
+-KGDB supports debugging over ethernet.  Only a limited set of ethernet
+-devices are supported right now, but adding support for new devices
+-should not be too complicated.  See "New Devices" below for details.
+-
++KGDB supports debugging over ethernet (kgdboe) via polling of a given
++network interface. Most cards should be supported automatically.
++Debugging facilities are available as soon as the network driver and
++kgdboe have initialized. Unfortunately, this is too late in the boot
++process for debugging some issues, but works quite well for many
++others. This should not interfere with normal network usage and
++doesn't require a dedicated NIC.
+ 
+ Terminology
+ -----------
+@@ -29,33 +33,25 @@
+ Usage
+ -----
+ 
+-You need to use the following command-line options on the TARGET kernel:
+-
+-  gdbeth=DEVICENUM
+-  gdbeth_remoteip=HOSTIPADDR
+-  gdbeth_remotemac=REMOTEMAC
+-  gdbeth_localmac=LOCALMAC
+-
+-kgdbeth=DEVICENUM sets the ethernet device number to listen on for
+-debugging packets.  e.g. kgdbeth=0 listens on eth0.
+-
+-kgdbeth_remoteip=HOSTIPADDR sets the IP address of the HOST machine.
+-Only packets originating from this IP address will be accepted by the
+-debugger.  e.g. kgdbeth_remoteip=192.168.2.2
++You need to use the following command-line option on the TARGET kernel:
+ 
+-kgdbeth_remotemac=REMOTEMAC sets the ethernet address of the HOST machine.
+-e.g. kgdbeth_remotemac=00:07:70:12:4E:F5
++  kgdboe=[tgt-port]@<tgt-ip>/[dev],[host-port]@<host-ip>/[host-macaddr]
+ 
+-kgdbeth_localmac=LOCALMAC sets the ethernet address of the TARGET machine.
+-e.g. kgdbeth_localmac=00:10:9F:18:21:3C
++    where
++        tgt-port      source for UDP packets (defaults to 6443)
++        tgt-ip        source IP to use (interface address)
++        dev           network interface (eth0)
++        host-port     HOST UDP port (6442) (not really used)
++        host-ip       IP address for HOST machine
++        host-macaddr  ethernet MAC address for HOST (ff:ff:ff:ff:ff:ff)
+ 
+-You can also set the following command-line option on the TARGET kernel:
++  examples:
+ 
+-  kgdbeth_listenport=PORT
++    kgdboe=7000@192.168.0.1/wlan0,7001@192.168.0.2/00:05:3C:04:47:5D
++    kgdboe=@192.168.0.1/,@192.168.0.2/
+ 
+-kgdbeth_listenport sets the UDP port to listen on for gdb debugging
+-packets.  The default value is "6443".  e.g. kgdbeth_listenport=7654
+-causes the kernel to listen on UDP port 7654 for debugging packets.
++Only packets originating from the configured HOST IP address will be
++accepted by the debugger.
+ 
+ On the HOST side, run gdb as normal and use a remote UDP host as the
+ target:
+@@ -72,47 +68,16 @@
+ 
+ You can now continue as if you were debugging over a serial line.
+ 
+-Observations
+-------------
+-
+-I've used this with NFS and various other network applications (ssh,
+-etc.) and it's doesn't appear to interfere with their operation in
+-any way.  It doesn't seem to effect the NIC it uses - i.e. you don't
+-need a dedicated NIC for this.
+-
+ Limitations
+ -----------
+ 
+-In the inital release of this code you _must_ break into the system with the
+-debugger by hand, early after boot, as described above.
+-
+-Otherwise, the first time the kernel tries to enter the debugger (say, via an
+-oops or a BUG), the kgdb stub will doublefault and die because things aren't
+-fully set up yet.
+-
+-Supported devices
+------------------
+-
+-Right now, the following drivers are supported:
+-
+-  e100 driver (drivers/net/e100/*)
+-  3c59x driver (drivers/net/3c59x.c)
+-
+-
+-New devices
+------------
+-
+-Supporting a new device is straightforward.  Just add a "poll" routine to
+-the driver and hook it into the poll_controller field in the netdevice
+-structure.  For an example, look in drivers/net/3c59x.c and search
+-for CONFIG_KGDB (two places.)
+-
+-The poll routine is usually quite simple - it's usually enough to just
+-disable interrupts, call the device's interrupt routine and re-enable
+-interrupts again.
+-
++The current release of this code is exclusive of using kgdb on a
++serial interface, so you must boot without the kgdboe option to use
++serial debugging. Trying to debug the network driver while using it
++will prove interesting.
+ 
+ Bug reports
+ -----------
+ 
+-Send bug reports to Robert Walsh <rjwalsh@durables.org>.
++Send bug reports to Robert Walsh <rjwalsh@durables.org> Matt
++Mackall <mpm@selenic.com> and wangdi <wangdi@clusterfs.com>.
diff --git a/lustre/kernel_patches/patches/kgdb-use-ggdb-2.5.73.patch b/lustre/kernel_patches/patches/kgdb-use-ggdb-2.5.73.patch
deleted file mode 100644
index da07bd96cb5a7bcb1e42749227b14895453dfda1..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/kgdb-use-ggdb-2.5.73.patch
+++ /dev/null
@@ -1,17 +0,0 @@
- arch/i386/Makefile |    2 +-
- 1 files changed, 1 insertion(+), 1 deletion(-)
-
-diff -puN arch/i386/Makefile~kgdb-use-ggdb arch/i386/Makefile
---- 25/arch/i386/Makefile~kgdb-use-ggdb	2003-06-14 22:54:41.000000000 -0700
-+++ 25-akpm/arch/i386/Makefile	2003-06-14 22:54:41.000000000 -0700
-@@ -85,7 +85,7 @@ mcore-$(CONFIG_X86_ES7000)	:= mach-es700
- # default subarch .h files
- mflags-y += -Iinclude/asm-i386/mach-default
- 
--mflags-$(CONFIG_KGDB) += -g
-+mflags-$(CONFIG_KGDB) += -ggdb
- mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
- 
- head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
-
-_
diff --git a/lustre/kernel_patches/patches/kgdb_eth.patch b/lustre/kernel_patches/patches/kgdb_eth.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5c8eaa206e4c20b9fcced55817d506431182b186
--- /dev/null
+++ b/lustre/kernel_patches/patches/kgdb_eth.patch
@@ -0,0 +1,1185 @@
+Index: linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c
+===================================================================
+--- linux-2.6.0-test1.orig/arch/i386/kernel/kgdb_stub.c	2003-09-02 14:16:10.000000000 +0800
++++ linux-2.6.0-test1/arch/i386/kernel/kgdb_stub.c	2003-09-02 14:32:02.000000000 +0800
+@@ -30,6 +30,7 @@
+  *
+  *  Written by:	     Glenn Engel $
+  *  Updated by:	     David Grothe <dave@gcom.com>
++ *  Updated by:	     Robert Walsh <rjwalsh@durables.org>
+  *  ModuleState:     Experimental $
+  *
+  *  NOTES:	     See Below $
+@@ -112,6 +113,7 @@
+ #include <asm/processor.h>
+ #include <linux/irq.h>
+ #include <asm/desc.h>
++#include <linux/inet.h>
+ 
+ /************************************************************************
+  *
+@@ -122,8 +124,16 @@
+ /* Thread reference */
+ typedef unsigned char threadref[8];
+ 
+-extern void putDebugChar(int);	/* write a single character	 */
+-extern int getDebugChar(void);	/* read and return a single char */
++extern int tty_putDebugChar(int);     /* write a single character      */
++extern int tty_getDebugChar(void);    /* read and return a single char */
++extern void tty_flushDebugChar(void); /* flush pending characters      */
++extern int eth_putDebugChar(int);     /* write a single character      */
++extern int eth_getDebugChar(void);    /* read and return a single char */
++extern void eth_flushDebugChar(void); /* flush pending characters      */
++extern void gdb_eth_set_trapmode(int);
++extern void gdb_eth_reply_arp(void);   /*send arp request */
++extern int gdb_eth_is_initializing;
++
+ 
+ /************************************************************************/
+ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+@@ -264,6 +274,35 @@
+ }
+ 
+ /*
++ * I/O dispatch functions...
++ * Based upon gdb_eth, either call the ethernet
++ * handler or the serial one..
++ */
++void putDebugChar(int c)
++{
++  if (gdb_eth == -1)
++	tty_putDebugChar(c);
++  else
++	eth_putDebugChar(c);
++}
++
++int getDebugChar(void)
++{
++  if (gdb_eth == -1)
++	return tty_getDebugChar();
++  else
++	return eth_getDebugChar();
++}
++
++void flushDebugChar(void)
++{
++    if (gdb_eth == -1)
++	tty_flushDebugChar();
++    else
++	eth_flushDebugChar();
++}
++
++/*
+  * Gdb calls functions by pushing agruments, including a return address 
+  * on the stack and the adjusting EIP to point to the function.	 The 
+  * whole assumption in GDB is that we are on a different stack than the
+@@ -389,7 +428,6 @@
+ 		xmitcsum = -1;
+ 
+ 		count = 0;
+-
+ 		/* now, read until a # or end of buffer is found */
+ 		while (count < BUFMAX) {
+ 			ch = getDebugChar() & 0x7f;
+@@ -429,6 +467,7 @@
+ 
+ 	if (remote_debug)
+ 		printk("R:%s\n", buffer);
++	flushDebugChar();
+ }
+ 
+ /* send the packet in buffer.  */
+@@ -441,25 +480,64 @@
+ 	char ch;
+ 
+ 	/*  $<packet info>#<checksum>. */
+-	do {
+-		if (remote_debug)
+-			printk("T:%s\n", buffer);
+-		putDebugChar('$');
+-		checksum = 0;
+-		count = 0;
+-
+-		while ((ch = buffer[count])) {
+-			putDebugChar(ch);
+-			checksum += ch;
+-			count += 1;
+-		}
+ 
+-		putDebugChar('#');
+-		putDebugChar(hexchars[checksum >> 4]);
+-		putDebugChar(hexchars[checksum % 16]);
+-
+-	} while ((getDebugChar() & 0x7f) != '+');
++	if (gdb_eth == -1){
++		do {
++			if (remote_debug)
++				printk("T:%s\n", buffer);
++			putDebugChar('$');
++			checksum = 0;
++			count = 0;
++
++			while ((ch = buffer[count])) {
++				putDebugChar(ch);
++				checksum += ch;
++				count += 1;
++			}
++			
++			putDebugChar('#');
++			putDebugChar(hexchars[checksum >> 4]);
++			putDebugChar(hexchars[checksum % 16]);
++			flushDebugChar();
++
++		} while ((getDebugChar() & 0x7f) != '+');
++	}else{
++	
++		/*for udp, we can not transfer too much bytes once */
++		/*we only transfer MAX_SEND_COUNT size byts each time */
++#define MAX_SEND_COUNT 30	
++		int send_count=0, i=0;
++		char send_buf[30];
+ 
++		do {
++			if (remote_debug)
++				printk("T:%s\n", buffer);
++			putDebugChar('$');
++			checksum = 0;
++			count = 0;
++			send_count = 0;	
++			while ((ch = buffer[count])) {
++				if (send_count >= MAX_SEND_COUNT){
++					for(i=0; i < MAX_SEND_COUNT; i++){
++						putDebugChar(send_buf[i]);
++					}		
++					flushDebugChar();
++					send_count = 0;
++				}else{
++					send_buf[send_count] = ch;
++					checksum += ch;
++					count ++;
++					send_count++;
++				}
++			}
++			for(i=0; i < send_count; i++)
++				putDebugChar(send_buf[i]);
++			putDebugChar('#');
++			putDebugChar(hexchars[checksum >> 4]);
++			putDebugChar(hexchars[checksum % 16]);
++			flushDebugChar();
++		} while ((getDebugChar() & 0x7f) != '+');
++	}
+ }
+ 
+ static char remcomInBuffer[BUFMAX];
+@@ -1143,6 +1221,13 @@
+ 		print_regs(&regs);
+ 		return (0);
+ 	}
++	/*
++	 * If we're using eth mode, set the 'mode' in the netdevice.
++	 */
++
++	if(gdb_eth != -1) {
++		gdb_eth_set_trapmode(1);
++	}
+ 
+ 	kgdb_local_irq_save(flags);
+ 
+@@ -1156,8 +1241,8 @@
+ 	 * NMI and will wait there for the following spin locks to be 
+ 	 * released.
+ 	 */
++	
+ #ifdef CONFIG_SMP
+-
+ #if 0
+ 	if (cpu_callout_map & ~MAX_CPU_MASK) {
+ 		printk("kgdb : too many cpus, possibly not mapped"
+@@ -1372,6 +1457,7 @@
+ 	gdb_i386vector = exceptionVector;
+ 	gdb_i386errcode = err_code;
+ 	kgdb_info.called_from = __builtin_return_address(0);
++
+ #ifdef CONFIG_SMP
+ 	/*
+ 	 * OK, we can now communicate, lets tell gdb about the sync.
+@@ -1400,8 +1486,13 @@
+ 	remcomOutBuffer[2] = hexchars[signo % 16];
+ 	remcomOutBuffer[3] = 0;
+ 
+-	putpacket(remcomOutBuffer);
++	if (gdb_eth_is_initializing) {
++		gdb_eth_is_initializing = 0;
++	} else {
++		putpacket(remcomOutBuffer);
++	}
+ 
++	gdb_eth_reply_arp();
+ 	while (1 == 1) {
+ 		error = 0;
+ 		remcomOutBuffer[0] = 0;
+@@ -1419,7 +1510,9 @@
+ 			       remote_debug ? "on" : "off");
+ 			break;
+ 		case 'g':	/* return the value of the CPU registers */
++			
+ 			get_gdb_regs(usethread, &regs, gdb_regs);
++			
+ 			mem2hex((char *) gdb_regs,
+ 				remcomOutBuffer, NUMREGBYTES, 0);
+ 			break;
+@@ -1536,6 +1629,10 @@
+ 
+ 			newPC = regs.eip;
+ 
++			if (gdb_eth != -1) {
++				gdb_eth_set_trapmode(0);
++			}
++
+ 			/* clear the trace bit */
+ 			regs.eflags &= 0xfffffeff;
+ 
+@@ -1856,9 +1953,7 @@
+ 		kgdb_local_irq_restore(flags);
+ 		return (0);
+ 	}
+-#if 0
+-exit_just_unlock:
+-#endif
++      exit_just_unlock:
+ #endif
+ 	/* Release kgdb spinlock */
+ 	KGDB_SPIN_UNLOCK(&kgdb_spinlock);
+@@ -2213,3 +2308,72 @@
+ typedef int gdb_debug_hook(int exceptionVector,
+ 			   int signo, int err_code, struct pt_regs *linux_regs);
+ gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;	/* histerical reasons... */
++
++static int __init kgdb_opt_gdbeth(char *str)
++{
++	gdb_eth = simple_strtoul(str,NULL,10);
++	return 1;
++}
++
++static int __init kgdb_opt_gdbeth_remote(char *str)
++{
++	gdb_ethremote = in_aton(str);
++	return 1;
++}
++
++static int __init kgdb_opt_gdbeth_listen(char *str)
++{
++	gdb_listenport = simple_strtoul(str,NULL,10);
++	return 1;
++}
++
++static int __init kgdb_opt_gdbeth_hwaddr(char *str)
++{
++	int  i;
++	char *p;
++
++	p = str;
++	i = 0;
++	while(1)
++	{
++		unsigned int c;
++		sscanf(p, "%x:", &c);
++		gdb_sendhwaddr[i++] = c;
++		while((*p != 0) && (*p != ':'))
++			p++;
++		if (*p == 0)
++			break;
++		p++;
++	}
++
++	return 1;
++}
++static int __init kgdb_opt_gdbeth_rchwaddr(char *str)
++{
++	int  i;
++	char *p;
++
++	p = str;
++	i = 0;
++	while(1)
++	{
++		unsigned int c;
++		sscanf(p, "%x:", &c);
++		gdb_receivehwaddr[i++] = c;
++		while((*p != 0) && (*p != ':'))
++			p++;
++		if (*p == 0)
++			break;
++		p++;
++	}
++
++	return 1;
++}
++
++
++__setup("gdbeth=", kgdb_opt_gdbeth);
++__setup("gdbeth_remote=", kgdb_opt_gdbeth_remote);
++__setup("gdbeth_listenport=", kgdb_opt_gdbeth_listen);
++__setup("gdbeth_sendhwaddr=", kgdb_opt_gdbeth_hwaddr);
++__setup("gdbeth_receivehwaddr=", kgdb_opt_gdbeth_rchwaddr);
++
+Index: linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c
+===================================================================
+--- linux-2.6.0-test1.orig/arch/i386/lib/kgdb_serial.c	2003-09-02 14:16:11.000000000 +0800
++++ linux-2.6.0-test1/arch/i386/lib/kgdb_serial.c	2003-09-02 14:32:02.000000000 +0800
+@@ -155,12 +155,12 @@
+  * It will receive a limited number of characters of input
+  * from the gdb  host machine and save them up in a buffer.
+  *
+- * When the gdb stub routine getDebugChar() is called it
++ * When the gdb stub routine tty_getDebugChar() is called it
+  * draws characters out of the buffer until it is empty and
+  * then reads directly from the serial port.
+  *
+  * We do not attempt to write chars from the interrupt routine
+- * since the stubs do all of that via putDebugChar() which
++ * since the stubs do all of that via tty_putDebugChar() which
+  * writes one byte after waiting for the interface to become
+  * ready.
+  *
+@@ -226,7 +226,7 @@
+ /*
+  * Hook an IRQ for KGDB.
+  *
+- * This routine is called from putDebugChar, below.
++ * This routine is called from tty_putDebugChar, below.
+  */
+ static int ints_disabled = 1;
+ int
+@@ -331,7 +331,7 @@
+ }
+ 
+ /*
+- * getDebugChar
++ * tty_getDebugChar
+  *
+  * This is a GDB stub routine.	It waits for a character from the
+  * serial interface and then returns it.  If there is no serial
+@@ -345,11 +345,11 @@
+ /* Caller takes needed protections */
+ 
+ int
+-getDebugChar(void)
++tty_getDebugChar(void)
+ {
+ 	volatile int chr, dum, time, end_time;
+ 
+-	dbprintk(("getDebugChar(port %x): ", gdb_async_info->port));
++	dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
+ 
+ 	if (gdb_async_info == NULL) {
+ 		gdb_hook_interrupt(&local_info, 0);
+@@ -375,7 +375,7 @@
+ 	dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
+ 	return (chr);
+ 
+-}				/* getDebugChar */
++}				/* tty_getDebugChar */
+ 
+ static int count = 3;
+ static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
+@@ -383,6 +383,9 @@
+ static int __init
+ kgdb_enable_ints(void)
+ {
++	if (gdb_eth != -1) {
++		return 0;
++	}
+ 	if (gdb_async_info == NULL) {
+ 		gdb_hook_interrupt(&local_info, 1);
+ 	}
+@@ -444,7 +447,7 @@
+ }
+ 
+ /*
+- * putDebugChar
++ * tty_putDebugChar
+  *
+  * This is a GDB stub routine.	It waits until the interface is ready
+  * to transmit a char and then sends it.  If there is no serial
+@@ -452,9 +455,9 @@
+  * pretended to send the char.	Caller takes needed protections.
+  */
+ void
+-putDebugChar(int chr)
++tty_putDebugChar(int chr)
+ {
+-	dbprintk(("putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
++	dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
+ 		  gdb_async_info->port,
+ 		  chr,
+ 		  chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
+@@ -480,6 +483,14 @@
+ 		}
+ 	}
+ 
+-}				/* putDebugChar */
++}				/* tty_putDebugChar */
++
++/*
++ * This does nothing for the serial port, since it doesn't buffer.
++ */
++
++void tty_flushDebugChar(void)
++{
++}
+ 
+ module_init(kgdb_enable_ints);
+Index: linux-2.6.0-test1/include/linux/netdevice.h
+===================================================================
+--- linux-2.6.0-test1.orig/include/linux/netdevice.h	2003-09-02 14:29:27.000000000 +0800
++++ linux-2.6.0-test1/include/linux/netdevice.h	2003-09-02 14:32:02.000000000 +0800
+@@ -469,6 +469,11 @@
+ 
+ 	/* statistics sub-directory */
+ 	struct kobject		stats_kobj;
++
++#ifdef CONFIG_KGDB
++	int			kgdb_is_trapped;
++	void			(*kgdb_net_poll_rx)(struct net_device *);
++#endif
+ };
+ 
+ #define SET_MODULE_OWNER(dev) do { } while (0)
+@@ -524,6 +529,11 @@
+ extern struct net_device	*dev_get_by_index(int ifindex);
+ extern struct net_device	*__dev_get_by_index(int ifindex);
+ extern int		dev_restart(struct net_device *dev);
++#ifdef CONFIG_KGDB
++int		gdb_eth_is_trapped(void);
++int		gdb_net_interrupt(struct sk_buff *skb);
++void		gdb_send_arp_request(void);
++#endif
+ 
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+ extern int		register_gifconf(unsigned int family, gifconf_func_t * gifconf);
+@@ -582,12 +592,20 @@
+ 
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++	if (gdb_eth_is_trapped())
++		return;
++#endif
+ 	if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+ 		__netif_schedule(dev);
+ }
+ 
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_KGDB
++	if (gdb_eth_is_trapped())
++		return;
++#endif
+ 	set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+ 
+Index: linux-2.6.0-test1/include/asm-i386/kgdb.h
+===================================================================
+--- linux-2.6.0-test1.orig/include/asm-i386/kgdb.h	2003-09-02 14:16:20.000000000 +0800
++++ linux-2.6.0-test1/include/asm-i386/kgdb.h	2003-09-02 14:32:03.000000000 +0800
+@@ -18,6 +18,16 @@
+ #ifndef BREAKPOINT
+ #define BREAKPOINT   asm("   int $3")
+ #endif
++
++extern int gdb_eth;
++extern unsigned gdb_ethremote;
++extern unsigned short gdb_listenport;
++extern unsigned char gdb_sendhwaddr[6];
++extern unsigned char gdb_receivehwaddr[6];
++
++extern int gdb_tty_hook(void);
++extern int gdb_eth_hook(void);
++
+ /*
+  * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
+  * pointer to its routine and it will be entered as the first thing
+@@ -34,6 +44,7 @@
+ extern int kgdb_handle_exception(int trapno,
+ 				 int signo, int err_code, struct pt_regs *regs);
+ extern int in_kgdb(struct pt_regs *regs);
++extern void kgdb_null(void);
+ 
+ #ifdef CONFIG_KGDB_TS
+ void kgdb_tstamp(int line, char *source, int data0, int data1);
+Index: linux-2.6.0-test1/drivers/net/e100/e100_main.c
+===================================================================
+--- linux-2.6.0-test1.orig/drivers/net/e100/e100_main.c	2003-09-02 14:29:27.000000000 +0800
++++ linux-2.6.0-test1/drivers/net/e100/e100_main.c	2003-09-02 14:32:03.000000000 +0800
+@@ -567,6 +567,15 @@
+ }
+ #endif
+ 
++#ifdef CONFIG_KGDB
++static void e100_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	e100intr(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++#endif
++
+ static int __devinit
+ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+ {
+@@ -662,7 +671,9 @@
+ 	dev->set_multicast_list = &e100_set_multi;
+ 	dev->set_mac_address = &e100_set_mac;
+ 	dev->do_ioctl = &e100_ioctl;
+-
++#ifdef CONFIG_KGDB
++	dev->kgdb_net_poll_rx = e100_rx_poll;
++#endif
+ 	if (bdp->flags & USE_IPCB)
+ 	dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+ 			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+Index: linux-2.6.0-test1/drivers/net/3c59x.c
+===================================================================
+--- linux-2.6.0-test1.orig/drivers/net/3c59x.c	2003-09-02 14:29:27.000000000 +0800
++++ linux-2.6.0-test1/drivers/net/3c59x.c	2003-09-02 14:32:03.000000000 +0800
+@@ -1063,6 +1063,22 @@
+ 	return rc;
+ }
+ 
++#ifdef CONFIG_KGDB
++static void vortex_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	vortex_interrupt(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++
++static void boomerang_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	boomerang_interrupt(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}
++#endif
++
+ /*
+  * Start up the PCI/EISA device which is described by *gendev.
+  * Return 0 on success.
+@@ -1449,6 +1465,14 @@
+ 	dev->set_multicast_list = set_rx_mode;
+ 	dev->tx_timeout = vortex_tx_timeout;
+ 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
++#ifdef CONFIG_KGDB
++ 	if (vp->full_bus_master_tx) {
++ 		dev->kgdb_net_poll_rx = boomerang_rx_poll;
++ 	} else {
++ 		dev->kgdb_net_poll_rx = vortex_rx_poll;
++ 	}
++#endif
++
+ #ifdef HAVE_POLL_CONTROLLER
+ 	dev->poll_controller = &vorboom_poll;
+ #endif
+Index: linux-2.6.0-test1/drivers/net/Makefile
+===================================================================
+--- linux-2.6.0-test1.orig/drivers/net/Makefile	2003-07-14 11:32:32.000000000 +0800
++++ linux-2.6.0-test1/drivers/net/Makefile	2003-09-02 14:32:03.000000000 +0800
+@@ -32,6 +32,8 @@
+ 
+ obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
+ 
++obj-$(CONFIG_KGDB) += kgdb_eth.o
++
+ obj-$(CONFIG_DGRS) += dgrs.o
+ obj-$(CONFIG_RCPCI) += rcpci.o
+ obj-$(CONFIG_VORTEX) += 3c59x.o
+Index: linux-2.6.0-test1/drivers/net/kgdb_eth.c
+===================================================================
+--- linux-2.6.0-test1.orig/drivers/net/kgdb_eth.c	2003-09-02 14:32:02.000000000 +0800
++++ linux-2.6.0-test1/drivers/net/kgdb_eth.c	2003-09-02 21:41:42.000000000 +0800
+@@ -0,0 +1,547 @@
++/*
++ * Network interface GDB stub
++ *
++ * Written by San Mehat (nettwerk@biodome.org)
++ * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
++ * and Scott Foehner (sfoehner@engr.sgi.com)
++ *
++ * Twiddled for 2.5 by Robert Walsh (rjwalsh@durables.org)
++ *
++ */
++ 
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/termios.h>
++#include <linux/workqueue.h>
++#include <asm/kgdb.h>
++#include <linux/if_ether.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/delay.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/atomic.h>
++
++#undef	PRNT				/* define for debug printing */
++
++#define	GDB_BUF_SIZE	512		/* power of 2, please */
++
++static char	gdb_buf[GDB_BUF_SIZE] ;
++static int	gdb_buf_in_inx ;
++static atomic_t	gdb_buf_in_cnt ;
++static int	gdb_buf_out_inx ;
++
++extern void	set_debug_traps(void) ;		/* GDB routine */
++extern void     breakpoint(void);
++
++unsigned int    gdb_ethremote = 0;
++unsigned short  gdb_listenport = 6443;
++unsigned short  gdb_sendport= 6442;
++int             gdb_eth = -1; /* Default tty mode */
++unsigned char   gdb_sendhwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++unsigned char   gdb_receivehwaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
++int             gdb_eth_is_initializing = 0;
++int 		gdb_eth_debug = 0;
++
++struct net_device *gdb_netdevice = NULL;
++
++//static int      initialized = -1;
++//static struct work_struct irq_bp;
++
++static void bpwork_func(void *p)
++{
++    udelay(500);
++    BREAKPOINT;
++}
++
++static struct workqueue_struct *irq_bp;
++DECLARE_WORK(bpwork, bpwork_func, NULL);
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++ */
++static int read_char(void)
++{
++    
++    if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */
++    {
++	int chr ;
++
++	chr = gdb_buf[gdb_buf_out_inx++] ;
++	gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
++	atomic_dec(&gdb_buf_in_cnt) ;
++	return chr;
++    }
++    return -1; // no data
++} /* read_char */
++
++//static unsigned char daddr[6] = {0x00,0x06,0x25,0xA9,0x9F,0x6A};
++//static unsigned char daddr[6] = {0x00,0x50,0xFC,0xB8,0x22,0x03};
++//static unsigned char daddr[6] = {0x00,0x08,0x74,0x96,0x6D,0x9B};
++//static unsigned char daddr[6] = {0x00,0x07,0xE9,0xD4,0xBE,0x85};
++//static unsigned char daddr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void write_buffer(char *buf, int len)
++{
++    int              total_len, eth_len, ip_len, udp_len;
++    struct in_device *in_dev;
++    struct sk_buff   *skb;
++    struct udphdr    *udph;
++    struct iphdr     *iph;
++    struct ethhdr    *eth;
++
++    if (!(in_dev = (struct in_device *) gdb_netdevice->ip_ptr)) 
++	panic("No in_device available for interface!\n");
++    if (!(in_dev->ifa_list))
++	panic("No interface address set for interface!\n");
++    udp_len = len + sizeof(struct udphdr);
++    ip_len = eth_len = udp_len + sizeof(struct iphdr);
++    total_len = eth_len + ETH_HLEN;
++
++    if (!(skb = alloc_skb(total_len, GFP_ATOMIC)))
++	return;
++
++    atomic_set(&skb->users, 1);
++    skb_reserve(skb, total_len - 1);
++
++    memcpy(skb->data , (unsigned char *) buf, len);
++    skb->len += len;
++
++    udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
++    udph->source = htons(gdb_listenport);
++    udph->dest   = htons(gdb_sendport);
++    udph->len    = htons(udp_len);
++    udph->check  = 0;
++  
++    iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
++    iph->version = 4;
++    iph->ihl     = 5;
++    iph->tos     = 0;
++    iph->tot_len = htons(ip_len);
++    iph->id      = 0;
++    iph->frag_off= 0;
++    iph->ttl     = 64;
++    iph->protocol= IPPROTO_UDP;
++    iph->check   = 0;
++    iph->saddr   = in_dev->ifa_list->ifa_address;
++    iph->daddr   = gdb_ethremote;
++    iph->check   = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++    eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
++    eth->h_proto = htons(ETH_P_IP);
++    memcpy(eth->h_source, gdb_sendhwaddr, gdb_netdevice->addr_len);
++//    memcpy(eth->h_dest, daddr, gdb_netdevice->addr_len);
++    memcpy(eth->h_dest, gdb_receivehwaddr, gdb_netdevice->addr_len);
++
++#if 0 
++repeat_poll:
++#endif
++    spin_lock(&gdb_netdevice->xmit_lock);
++    gdb_netdevice->xmit_lock_owner = smp_processor_id();
++#if 0 
++    if (netif_queue_stopped(gdb_netdevice))
++    {
++	gdb_netdevice->xmit_lock_owner = -1;
++	spin_unlock(&gdb_netdevice->xmit_lock);
++	gdb_netdevice->poll_controller(gdb_netdevice);
++	zap_completion_queue();
++	goto repeat_poll;
++    }
++#endif
++    gdb_netdevice->hard_start_xmit(skb, gdb_netdevice);
++    gdb_netdevice->xmit_lock_owner = -1;
++    spin_unlock(&gdb_netdevice->xmit_lock);
++
++   // kfree_skb(skb);
++} /* write_char */
++/* in interrupt state the target machine will not response the arp request */ 
++
++static struct sk_buff *send_skb = NULL;
++void gdb_eth_reply_arp(void)
++{
++	if (send_skb){
++#if 0 
++repeat_poll:
++#endif
++    		spin_lock(&gdb_netdevice->xmit_lock);
++    		gdb_netdevice->xmit_lock_owner = smp_processor_id();
++#if 0 
++		if (netif_queue_stopped(gdb_netdevice)){
++			gdb_netdevice->xmit_lock_owner = -1;
++			spin_unlock(&gdb_netdevice->xmit_lock);
++			gdb_netdevice->poll_controller(gdb_netdevice);
++			zap_completion_queue();
++			goto repeat_poll;
++	        }
++#endif
++	    	gdb_netdevice->hard_start_xmit(send_skb, gdb_netdevice);
++	    	gdb_netdevice->xmit_lock_owner = -1;
++	    	spin_unlock(&gdb_netdevice->xmit_lock);
++		send_skb = NULL;	
++	
++	}
++}
++static int make_arp_request( struct sk_buff *skb)
++{
++	struct arphdr *arp;
++	unsigned char *arp_ptr;
++	int type = ARPOP_REPLY;
++	int ptype = ETH_P_ARP;
++	u32 sip, tip;
++	unsigned char *sha, *tha;
++    	struct in_device *in_dev = (struct in_device *) gdb_netdevice->ip_ptr; 
++	/*
++	 *	No arp on this interface.
++	 */
++	if (gdb_netdevice->flags &IFF_NOARP)
++		return 0;
++	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++				 (2 * gdb_netdevice->addr_len) +
++				 (2 * sizeof(u32)))))
++		return 0;
++	
++	skb->h.raw = skb->nh.raw = skb->data;
++	arp = skb->nh.arph;
++
++	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
++	     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
++	    arp->ar_pro != htons(ETH_P_IP))
++		return 0;
++
++/* Understand only these message types */
++
++	if (arp->ar_op != htons(ARPOP_REQUEST))
++		return 0;
++/*
++ *	Extract fields
++ */
++	arp_ptr= (unsigned char *)(arp+1);
++	sha	= arp_ptr;
++	arp_ptr += gdb_netdevice->addr_len;
++	memcpy(&sip, arp_ptr, 4);
++	arp_ptr += 4;
++	tha	= arp_ptr;
++	arp_ptr += gdb_netdevice->addr_len;
++	memcpy(&tip, arp_ptr, 4);
++	if (tip != in_dev->ifa_list->ifa_address){
++		return 0;
++	} 
++	if (gdb_ethremote != sip){
++		return 0;	
++	}
++/* 
++ *	Check for bad requests for 127.x.x.x and requests for multicast
++ *	addresses.  If this is one such, delete it.
++ */
++	
++	if (LOOPBACK(tip) || MULTICAST(tip))
++		return 0;
++
++/*
++ *      reply the arp request
++ */	
++	send_skb = alloc_skb(sizeof(struct arphdr)+ 2*(gdb_netdevice->addr_len+4)
++				+ LL_RESERVED_SPACE(gdb_netdevice), GFP_ATOMIC);
++	if (send_skb == NULL)
++		return 0;
++
++	skb_reserve(send_skb, LL_RESERVED_SPACE(gdb_netdevice));
++	send_skb->nh.raw = send_skb->data;
++	arp = (struct arphdr *) skb_put(send_skb,sizeof(struct arphdr) + 2*(gdb_netdevice->addr_len+4));
++	send_skb->dev = gdb_netdevice;
++	send_skb->protocol = htons(ETH_P_ARP);
++	
++	/*
++	 *	Fill the device header for the ARP frame
++	 */
++	if (gdb_netdevice->hard_header &&
++	    gdb_netdevice->hard_header(send_skb,  gdb_netdevice,  ptype, gdb_receivehwaddr, gdb_sendhwaddr, send_skb->len) < 0){
++		kfree_skb(send_skb);
++		return 0;
++	}
++	/*
++	 * Fill out the arp protocol part.
++	 *
++	 * we only support ethernet device type, 
++	 * which (according to RFC 1390) should always equal 1 (Ethernet).
++	 */
++	arp->ar_hrd = htons(gdb_netdevice->type);
++	arp->ar_pro = htons(ETH_P_IP);
++
++	arp->ar_hln = gdb_netdevice->addr_len;
++	arp->ar_pln = 4;
++	arp->ar_op = htons(type);
++
++	arp_ptr=(unsigned char *)(arp+1);
++
++	memcpy(arp_ptr, gdb_netdevice->dev_addr, gdb_netdevice->addr_len); 
++	arp_ptr += gdb_netdevice->addr_len;
++	memcpy(arp_ptr, &tip, 4);
++	arp_ptr += 4;
++        memcpy(arp_ptr, gdb_sendhwaddr, gdb_netdevice->addr_len);
++	arp_ptr+=gdb_netdevice->addr_len;
++	memcpy(arp_ptr, &sip, 4);
++	return 0;
++}
++/*
++ * Accept an skbuff from net_device layer and 
++ * add the payload onto gdb buffer
++ *
++ * When the gdb stub routine getDebugChar() is called it
++ * draws characters out of the buffer until it is empty and
++ * then reads directly from the serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine
++ * since the stubs do all of that via putDebugChar() which
++ * writes one byte after waiting for the interface to become
++ * ready.
++ *
++ * The debug stubs like to run with interrupts disabled since,
++ * after all, they run as a consequence of a breakpoint in
++ * the kernel.
++ *
++ * NOTE: Return value of 1 means it was for us and is an
++ * indication to the calling driver to destroy the sk_buff
++ * and not send it up the stack
++ */
++
++int gdb_net_interrupt(struct sk_buff *skb)
++{
++    unsigned char  chr;
++    struct iphdr   *iph = (struct iphdr*)skb->data;
++    struct udphdr  *udph= (struct udphdr*)(skb->data+(iph->ihl<<2));
++    unsigned char  *data = (unsigned char *) udph + sizeof(struct udphdr);
++    int            len;
++    int            i;
++
++    if ((gdb_eth != -1) && (!gdb_netdevice) &&
++	(iph->protocol == IPPROTO_UDP) &&
++	(be16_to_cpu(udph->dest) == gdb_listenport)) {
++	gdb_sendport = be16_to_cpu(udph->source);
++	
++        while(gdb_eth_is_initializing);
++	if(!gdb_netdevice)
++	    gdb_eth_hook();
++	if (!gdb_netdevice) {
++	    /* Lets not even try again. */
++	    gdb_eth = -1;
++	    return 0;
++	}
++    }
++    if (!gdb_netdevice) {
++	return 0;
++    }
++    if (skb->protocol == __constant_htons(ETH_P_ARP) && !send_skb){
++	make_arp_request(skb);
++	return 0;
++    }
++    if (iph->protocol != IPPROTO_UDP)
++	return 0;
++
++    if (be16_to_cpu(udph->dest) != gdb_listenport)
++	return 0;
++
++    len = be16_to_cpu(iph->tot_len) - (sizeof(struct udphdr) +
++				       sizeof(struct iphdr));
++    for (i = 0; i < len; i++)
++    {
++	chr = *data++;
++	if (chr == 3)
++	{
++	    queue_work(irq_bp, &bpwork);
++//	    flush_workqueue(irq_bp);
++	    continue;
++/*
++	    if (!in_interrupt())
++	    {
++		breakpoint();
++	    }
++	    else
++	    {
++	        schedule_work(&irq_bp); // XXX: is this really necessary??
++	    }
++	    continue;
++*/
++	}
++	if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE)
++	{				/* buffer overflow, clear it */
++	    gdb_buf_in_inx = 0 ;
++	    atomic_set(&gdb_buf_in_cnt, 0) ;
++	    gdb_buf_out_inx = 0 ;
++	    break ;
++	}
++	gdb_buf[gdb_buf_in_inx++] = chr ;
++	gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ;
++	atomic_inc(&gdb_buf_in_cnt) ;
++    }
++
++    return 1;
++} /* gdb_interrupt */
++
++
++int gdb_eth_hook(void)
++{
++    char gdb_netdev[16];
++    extern void kgdb_respond_ok(void);
++
++    if (gdb_sendhwaddr[0] == 0xff)
++	panic("ERROR! 'gdbeth_sendhwaddr' option not set!\n");
++    if (gdb_receivehwaddr[0] == 0xff)
++	panic("ERROR! 'gdbeth_receivehwaddr' option not set!\n");
++    if (gdb_ethremote == 0)
++	panic("ERROR! 'gdbeth_remote' option not set!\n");
++
++    sprintf(gdb_netdev,"eth%d",gdb_eth);
++
++#ifdef CONFIG_SMP
++    if (num_online_cpus() > CONFIG_NO_KGDB_CPUS){ 
++	printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
++	return -1;
++    }
++#endif
++    for (gdb_netdevice = dev_base;
++	 gdb_netdevice != NULL; 
++	 gdb_netdevice = gdb_netdevice->next){
++	if (strncmp(gdb_netdevice->name, gdb_netdev, IFNAMSIZ) == 0)
++	    break;
++    }
++    if (!gdb_netdevice){
++	printk("KGDB NET : Unable to find interface %s\n",gdb_netdev);
++	return -ENODEV;
++    }
++
++    /*
++     * Call GDB routine to setup the exception vectors for the debugger
++     */
++    set_debug_traps() ;
++
++    /*
++     * Call the breakpoint() routine in GDB to start the debugging
++     * session.
++     */
++     if (gdb_eth_debug){
++	    printk(KERN_INFO "Waiting for remote gdb connection from %x on local port %d\n",
++		   gdb_ethremote, gdb_listenport);
++	    printk(KERN_INFO "We are sending on port %d to %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
++		   gdb_sendport,
++		   gdb_sendhwaddr[0],
++		   gdb_sendhwaddr[1],
++		   gdb_sendhwaddr[2],
++		   gdb_sendhwaddr[3],
++		   gdb_sendhwaddr[4],
++		   gdb_sendhwaddr[5]);
++	    printk("Connected.\n");
++    }
++    gdb_eth_is_initializing = 1;
++    queue_work(irq_bp, &bpwork);
++    return 0;
++} /* gdb_hook_interrupt2 */
++
++/*
++ * getDebugChar
++ *
++ * This is a GDB stub routine.  It waits for a character from the
++ * serial interface and then returns it.  If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.
++ */
++int eth_getDebugChar(void)
++{
++    volatile int	chr ;
++
++    while((chr = read_char()) < 0)
++    {
++	if (send_skb){
++		gdb_eth_reply_arp();	
++        }
++	if (gdb_netdevice->kgdb_net_poll_rx)
++	    gdb_netdevice->kgdb_net_poll_rx(gdb_netdevice);
++	else
++        {
++	    printk("KGDB NET: Error - Device %s is not supported!\n",
++		   gdb_netdevice->name);
++	    panic("Please add support for kgdb net to this driver");
++        }
++    }
++    return chr;
++
++} /* eth_getDebugChar */
++
++#define ETH_QUEUE_SIZE 256
++static char eth_queue[ETH_QUEUE_SIZE];
++static int outgoing_queue;
++
++void eth_flushDebugChar(void)
++{
++    if(outgoing_queue) {
++	write_buffer(eth_queue, outgoing_queue);
++
++	outgoing_queue = 0;
++    }
++}
++
++static void put_char_on_queue(int chr)
++{
++    eth_queue[outgoing_queue++] = chr;
++    if(outgoing_queue == ETH_QUEUE_SIZE)
++    {
++	eth_flushDebugChar();
++    }
++}
++
++/*
++ * eth_putDebugChar
++ *
++ * This is a GDB stub routine.  It waits until the interface is ready
++ * to transmit a char and then sends it.
++ */
++void eth_putDebugChar(int chr)
++{
++    if (gdb_eth_debug)
++    	printk(KERN_INFO "eth_putDebugChar: chr=%02x '%c'\n", chr,
++	   	chr > ' ' && chr < 0x7F ? chr : ' ') ;
++    put_char_on_queue(chr) ;	/* this routine will wait */
++} /* putDebugChar */
++
++void gdb_eth_set_trapmode(int mode)
++{
++    if (!gdb_netdevice)
++	return;
++    gdb_netdevice->kgdb_is_trapped = mode;
++}
++
++int gdb_eth_is_trapped()
++{
++    if (!gdb_netdevice)
++	return 0;
++    return gdb_netdevice->kgdb_is_trapped;
++}
++
++static int __init
++kgdb_eth_init(void)
++{
++    irq_bp = create_workqueue("kgdb");
++    return 0;
++}
++
++module_init(kgdb_eth_init);
+Index: linux-2.6.0-test1/net/core/dev.c
+===================================================================
+--- linux-2.6.0-test1.orig/net/core/dev.c	2003-09-02 14:29:27.000000000 +0800
++++ linux-2.6.0-test1/net/core/dev.c	2003-09-02 14:32:03.000000000 +0800
+@@ -188,7 +188,9 @@
+ extern int netdev_sysfs_init(void);
+ extern int netdev_register_sysfs(struct net_device *);
+ extern void netdev_unregister_sysfs(struct net_device *);
+-
++#ifdef CONFIG_KGDB
++extern int gdb_net_interrupt(struct sk_buff *skb);
++#endif
+ 
+ /*******************************************************************************
+ 
+@@ -1349,6 +1351,21 @@
+ 	struct softnet_data *queue;
+ 	unsigned long flags;
+ 
++#ifdef CONFIG_KGDB
++	/* See if kgdb_eth wants this packet */
++	if (!gdb_net_interrupt(skb)) {
++		/* No.. if we're 'trapped' then junk it */
++		if (gdb_eth_is_trapped()) {
++			kfree_skb(skb);
++			return NET_RX_DROP;
++		}
++	} else {
++		/* kgdb_eth ate the packet... drop it silently */
++		kfree_skb(skb);
++		return NET_RX_DROP;
++	}
++#endif
++
+ 
+ 	/*
+ 	 * The code is rearranged so that the path is the most
diff --git a/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch b/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch
index 04b49ea029de472fe464b98bc02f776f5ebd662c..aa5cfbba49a81fa4d7ae310c6775c4bbb04f9ad1 100644
--- a/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch
+++ b/lustre/kernel_patches/patches/kmem_cache_validate_hp.patch
@@ -108,11 +108,11 @@
  unsigned long highstart_pfn, highend_pfn;
  static unsigned long totalram_pages;
  static unsigned long totalhigh_pages;
-+                                                                                                                                             
++
 +struct page *check_get_page(unsigned long kaddr)
 +{
 +#warning FIXME: Lustre team, is this solid?
-+       return virt_to_page(kaddr);
++	return virt_to_page(kaddr);
 +}
  
  int do_check_pgt_cache(int low, int high)
diff --git a/lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26-2.patch b/lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26-2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c7d06a82497850f11d27d98f95df77bd31ba9fdc
--- /dev/null
+++ b/lustre/kernel_patches/patches/linux-2.4.18ea-0.8.26-2.patch
@@ -0,0 +1,1775 @@
+ fs/ext3/Makefile           |    4 
+ fs/ext3/ext3-exports.c     |   13 
+ fs/ext3/ialloc.c           |    2 
+ fs/ext3/inode.c            |   29 -
+ fs/ext3/namei.c            |    8 
+ fs/ext3/super.c            |   23 
+ fs/ext3/xattr.c            | 1242 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ext3_fs.h    |   46 -
+ include/linux/ext3_jbd.h   |    8 
+ include/linux/ext3_xattr.h |  155 +++++
+ include/linux/xattr.h      |   15 
+ 11 files changed, 1494 insertions(+), 51 deletions(-)
+
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/fs/ext3/ext3-exports.c	2003-09-01 14:55:39.000000000 +0400
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
+--- linux-2.4.18/fs/ext3/ialloc.c~linux-2.4.18ea-0.8.26-2	2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/ialloc.c	2003-09-01 14:55:39.000000000 +0400
+@@ -17,6 +17,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+ #include <linux/locks.h>
+@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
+ 	 * as writing the quota to disk may need the lock as well.
+ 	 */
+ 	DQUOT_INIT(inode);
++	ext3_xattr_drop_inode(handle, inode);
+ 	DQUOT_FREE_INODE(inode);
+ 	DQUOT_DROP(inode);
+ 
+--- linux-2.4.18/fs/ext3/inode.c~linux-2.4.18ea-0.8.26-2	2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/inode.c	2003-09-01 14:55:39.000000000 +0400
+@@ -39,6 +39,18 @@
+  */
+ #undef SEARCH_FROM_ZERO
+ 
++/*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext3_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = EXT3_I(inode)->i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
+ /* The ext3 forget function must perform a revoke if we are freeing data
+  * which has been journaled.  Metadata (eg. indirect blocks) must be
+  * revoked in all cases. 
+@@ -48,7 +60,7 @@
+  * still needs to be revoked.
+  */
+ 
+-static int ext3_forget(handle_t *handle, int is_metadata,
++int ext3_forget(handle_t *handle, int is_metadata,
+ 		       struct inode *inode, struct buffer_head *bh,
+ 		       int blocknr)
+ {
+@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
+ {
+ 	handle_t *handle;
+ 	
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 
+ 	lock_kernel();
+@@ -1877,6 +1887,8 @@ void ext3_truncate(struct inode * inode)
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext3_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -2038,8 +2050,6 @@ int ext3_get_inode_loc (struct inode *in
+ 	struct ext3_group_desc * gdp;
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+-		inode->i_ino != EXT3_ACL_IDX_INO &&
+-		inode->i_ino != EXT3_ACL_DATA_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+ 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+ 		inode->i_ino > le32_to_cpu(
+@@ -2166,10 +2176,7 @@ void ext3_read_inode(struct inode * inod
+ 
+ 	brelse (iloc.bh);
+ 
+-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+@@ -2177,7 +2184,7 @@ void ext3_read_inode(struct inode * inod
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		else {
+ 			inode->i_op = &page_symlink_inode_operations;
+--- linux-2.4.18/fs/ext3/Makefile~linux-2.4.18ea-0.8.26-2	2003-08-29 16:53:17.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/Makefile	2003-09-01 14:55:50.000000000 +0400
+@@ -9,10 +9,10 @@
+ 
+ O_TARGET := ext3.o
+ 
+-export-objs :=	super.o inode.o
++export-objs :=	ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o hash.o
++		ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.18/fs/ext3/namei.c~linux-2.4.18ea-0.8.26-2	2003-09-01 11:50:59.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/namei.c	2003-09-01 14:55:39.000000000 +0400
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/fcntl.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+@@ -1524,6 +1525,7 @@ static int ext3_add_nondir(handle_t *han
+ 		d_instantiate(dentry, inode);
+ 		return 0;
+ 	}
++	ext3_xattr_drop_inode(handle, inode);
+ 	ext3_dec_count(handle, inode);
+ 	iput(inode);
+ 	return err;
+@@ -1612,7 +1614,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR);
++	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1620,7 +1622,6 @@ static int ext3_mkdir(struct inode * dir
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+ 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+-	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+ 		inode->i_nlink--; /* is this nlink == 0? */
+@@ -1647,9 +1648,6 @@ static int ext3_mkdir(struct inode * dir
+ 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
+ 	ext3_journal_dirty_metadata(handle, dir_block);
+ 	brelse (dir_block);
+-	inode->i_mode = S_IFDIR | mode;
+-	if (dir->i_mode & S_ISGID)
+-		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+ 	if (err) {
+--- linux-2.4.18/fs/ext3/super.c~linux-2.4.18ea-0.8.26-2	2003-08-29 16:53:17.000000000 +0400
++++ linux-2.4.18-alexey/fs/ext3/super.c	2003-09-01 14:55:39.000000000 +0400
+@@ -24,6 +24,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -406,6 +407,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
+@@ -1743,18 +1745,27 @@ int ext3_statfs (struct super_block * sb
+ 
+ static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super);
+ 
+-static int __init init_ext3_fs(void)
++static void exit_ext3_fs(void)
+ {
+-        return register_filesystem(&ext3_fs_type);
++	unregister_filesystem(&ext3_fs_type);
++	exit_ext3_xattr_user();
++	exit_ext3_xattr();
+ }
+ 
+-static void __exit exit_ext3_fs(void)
++static int __init init_ext3_fs(void)
+ {
+-	unregister_filesystem(&ext3_fs_type);
++	int error = init_ext3_xattr();
++	if (!error)
++		error = init_ext3_xattr_user();
++	if (!error)
++		error = register_filesystem(&ext3_fs_type);
++	if (!error)
++		return 0;
++
++	exit_ext3_fs();
++	return error;
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/fs/ext3/xattr.c	2003-09-01 14:55:39.000000000 +0400
+@@ -0,0 +1,1242 @@
++/*
++ * linux/fs/ext3/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   ¦ entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT3_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++#include <linux/mbcache.h>
++#endif
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++#include <linux/module.h>
++
++/* These symbols may be needed by a module. */
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT3_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
++			   struct ext3_xattr_header *);
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++static int ext3_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext3_xattr_cache_find(struct inode *,
++						 struct ext3_xattr_header *);
++static void ext3_xattr_cache_remove(struct buffer_head *);
++static void ext3_xattr_rehash(struct ext3_xattr_header *,
++			      struct ext3_xattr_entry *);
++
++static struct mb_cache *ext3_xattr_cache;
++
++#else
++# define ext3_xattr_cache_insert(bh) 0
++# define ext3_xattr_cache_find(inode, header) NULL
++# define ext3_xattr_cache_remove(bh) do {} while(0)
++# define ext3_xattr_rehash(header, entry) do {} while(0)
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext3_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext3_xattr_sem);
++
++static inline void
++ext3_xattr_lock(void)
++{
++	down(&ext3_xattr_sem);
++}
++
++static inline void
++ext3_xattr_unlock(void)
++{
++	up(&ext3_xattr_sem);
++}
++
++static inline int
++ext3_xattr_new_block(handle_t *handle, struct inode *inode,
++		     int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
++		EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext3_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext3_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext3_xattr_free_block(handle_t *handle, struct inode * inode,
++		      unsigned long block)
++{
++	ext3_free_blocks(handle, inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext3_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext3_xattr_free_block(handle, inode, block) \
++	ext3_free_blocks(handle, inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
++rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		if (!ext3_xattr_handlers[name_index-1]) {
++			ext3_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext3_handler_lock);
++	}
++	return error;
++}
++
++void
++ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		ext3_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext3_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static inline struct ext3_xattr_handler *
++ext3_xattr_resolve_name(const char **name)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext3_handler_lock);
++	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
++		if (ext3_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext3_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext3_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext3_handler_lock);
++	return handler;
++}
++
++static inline struct ext3_xattr_handler *
++ext3_xattr_handler(int name_index)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		read_lock(&ext3_handler_lock);
++		handler = ext3_xattr_handlers[name_index-1];
++		read_unlock(&ext3_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext3_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_setxattr(struct dentry *dentry, const char *name,
++	      void *value, size_t size, int flags)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext3_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT3_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT3_I(inode)->i_file_acl)
++		return 0;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler) {
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len) + 1;
++		}
++	}
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler) {
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++			*buf++ = '\0';
++		}
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext3_xattr_update_super_block(handle_t *handle,
++					  struct super_block *sb)
++{
++	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT3_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext3_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_header *header = NULL;
++	struct ext3_xattr_entry *here, *last;
++	unsigned int name_len;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	ext3_xattr_lock();
++
++	if (EXT3_I(inode)->i_file_acl) {
++		/* The inode already has an extended attribute block. */
++		int block = EXT3_I(inode)->i_file_acl;
++
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext3_error(sb, "ext3_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT3_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT3_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT3_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext3_xattr_cache_remove(bh);
++			error = ext3_journal_get_write_access(handle, bh);
++			if (error)
++				goto cleanup;
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT3_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT3_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT3_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext3_xattr_set2(handle, inode, bh,NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT3_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT3_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT3_XATTR_PAD, 0,
++			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext3_xattr_rehash(header, here);
++
++	error = ext3_xattr_set2(handle, inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	ext3_xattr_unlock();
++
++	return error;
++}
++
++/*
++ * Second half of ext3_xattr_set(): Update the file system.
++ */
++static int
++ext3_xattr_set2(handle_t *handle, struct inode *inode,
++		struct buffer_head *old_bh, struct ext3_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext3_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext3_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			error = ext3_journal_get_write_access(handle, new_bh);
++			if (error)
++				goto cleanup;
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			(void)ext3_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT3_I(inode)->i_file_acl != 0;
++			int block = ext3_xattr_new_block(handle, inode,
++							 &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++getblk_failed:			ext3_xattr_free_block(handle, inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			error = ext3_journal_get_create_access(handle, new_bh);
++			if (error) {
++				unlock_buffer(new_bh);
++				goto getblk_failed;
++			}
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			(void)ext3_xattr_cache_insert(new_bh);
++			ext3_xattr_update_super_block(handle, sb);
++		}
++		error = ext3_journal_dirty_metadata(handle, new_bh);
++		if (error)
++			goto cleanup;
++	}
++
++	/* Update the inode. */
++	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		error = ext3_journal_get_write_access(handle, old_bh);
++		if (error)
++			goto cleanup;
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
++
++			/* ext3_forget() calls bforget() for us, but we
++			   let our caller release old_bh, so we need to
++			   duplicate the handle before. */
++			get_bh(old_bh);
++			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext3_xattr_quota_free(inode);
++			ext3_journal_dirty_metadata(handle, old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_drop_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext3_xattr_drop_inode(handle_t *handle, struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT3_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	ext3_xattr_lock();
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext3_error(inode->i_sb, "ext3_xattr_drop_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext3_error(inode->i_sb, "ext3_xattr_drop_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ext3_journal_get_write_access(handle, bh);
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext3_xattr_cache_remove(bh);
++		ext3_xattr_free_block(handle, inode, block);
++		ext3_forget(handle, 1, inode, bh, block);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		ext3_journal_dirty_metadata(handle, bh);
++		if (IS_SYNC(inode))
++			handle->h_sync = 1;
++		ext3_xattr_quota_free(inode);
++	}
++	EXT3_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	ext3_xattr_unlock();
++}
++
++/*
++ * ext3_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext3_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++	mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++/*
++ * ext3_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext3_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext3_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext3_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext3_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext3_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext3_xattr_cmp(struct ext3_xattr_header *header1,
++	       struct ext3_xattr_header *header2)
++{
++	struct ext3_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT3_XATTR_NEXT(entry1);
++		entry2 = EXT3_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext3_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT3_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT3_XATTR_REFCOUNT_MAX);
++		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext3_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext3_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
++					 struct ext3_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext3_xattr_rehash(struct ext3_xattr_header *header,
++			      struct ext3_xattr_entry *entry)
++{
++	struct ext3_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext3_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT3_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext3_xattr(void)
++{
++	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext3_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++	if (ext3_xattr_cache)
++		mb_cache_destroy(ext3_xattr_cache);
++	ext3_xattr_cache = NULL;
++}
++
++#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
++
++int __init
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+--- linux-2.4.18/include/linux/ext3_fs.h~linux-2.4.18ea-0.8.26-2	2003-09-01 11:51:00.000000000 +0400
++++ linux-2.4.18-alexey/include/linux/ext3_fs.h	2003-09-01 14:55:39.000000000 +0400
+@@ -63,8 +63,6 @@
+  */
+ #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT3_ROOT_INO		 2	/* Root inode */
+-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
+@@ -94,7 +92,6 @@
+ #else
+ # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
+ #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -129,28 +126,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext3_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext3_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext3_group_desc
+@@ -521,7 +496,7 @@ struct ext3_super_block {
+ #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+ 
+-#define EXT3_FEATURE_COMPAT_SUPP	0
++#define EXT3_FEATURE_COMPAT_SUPP	EXT3_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
+ 					 EXT3_FEATURE_INCOMPAT_RECOVER)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+@@ -623,6 +598,24 @@ struct dx_hash_info
+ #define HASH_NB_ALWAYS		1
+ 
+ 
++/* Defined for extended attributes */
++#define CONFIG_EXT3_FS_XATTR y
++#ifndef ENOATTR
++#define ENOATTR ENODATA		/* No such attribute */
++#endif
++#ifndef ENOTSUP
++#define ENOTSUP EOPNOTSUPP	/* Operation not supported */
++#endif
++#ifndef XATTR_NAME_MAX
++#define XATTR_NAME_MAX   255	/* # chars in an extended attribute name */
++#define XATTR_SIZE_MAX 65536	/* size of an extended attribute value (64k) */
++#define XATTR_LIST_MAX 65536	/* size of extended attribute namelist (64k) */
++#endif
++#ifndef XATTR_CREATE
++#define XATTR_CREATE	1	/* set value, fail if attr already exists */
++#define XATTR_REPLACE	2	/* set value, fail if attr does not exist */
++#endif
++
+ /*
+  * Describe an inode's exact location on disk and in memory
+  */
+@@ -704,6 +697,7 @@ extern void ext3_check_inodes_bitmap (st
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
+ 
+ /* inode.c */
++extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+ 
+--- linux-2.4.18/include/linux/ext3_jbd.h~linux-2.4.18ea-0.8.26-2	2003-08-29 16:53:17.000000000 +0400
++++ linux-2.4.18-alexey/include/linux/ext3_jbd.h	2003-09-01 14:55:39.000000000 +0400
+@@ -30,13 +30,19 @@
+ 
+ #define EXT3_SINGLEDATA_TRANS_BLOCKS	8
+ 
++/* Extended attributes may touch two data buffers, two bitmap buffers,
++ * and two group and summaries. */
++
++#define EXT3_XATTR_TRANS_BLOCKS		8
++
+ /* Define the minimum size for a transaction which modifies data.  This
+  * needs to take into account the fact that we may end up modifying two
+  * quota files too (one for the group, one for the user quota).  The
+  * superblock only gets updated once, of course, so don't bother
+  * counting that again for the quota updates. */
+ 
+-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
++#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
++					 EXT3_XATTR_TRANS_BLOCKS - 2)
+ 
+ extern int ext3_writepage_trans_blocks(struct inode *inode);
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/include/linux/ext3_xattr.h	2003-09-01 14:55:39.000000000 +0400
+@@ -0,0 +1,155 @@
++/*
++  File: linux/ext3_xattr.h
++
++  On-disk format of extended attributes for the ext3 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT3_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT3_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT3_XATTR_INDEX_MAX			10
++#define EXT3_XATTR_INDEX_USER			1
++
++struct ext3_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext3_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT3_XATTR_PAD_BITS		2
++#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
++#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
++#define EXT3_XATTR_LEN(name_len) \
++	(((name_len) + EXT3_XATTR_ROUND + \
++	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
++#define EXT3_XATTR_NEXT(entry) \
++	( (struct ext3_xattr_entry *)( \
++	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
++#define EXT3_XATTR_SIZE(size) \
++	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT3_FS_XATTR
++
++struct ext3_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
++extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
++
++extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int);
++extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
++extern int ext3_removexattr(struct dentry *, const char *);
++
++extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext3_xattr_list(struct inode *, char *, size_t);
++extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, void *, size_t, int);
++
++extern void ext3_xattr_drop_inode(handle_t *, struct inode *);
++extern void ext3_xattr_put_super(struct super_block *);
++
++extern int init_ext3_xattr(void) __init;
++extern void exit_ext3_xattr(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR */
++#  define ext3_setxattr		NULL
++#  define ext3_getxattr		NULL
++#  define ext3_listxattr	NULL
++#  define ext3_removexattr	NULL
++
++static inline int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext3_xattr_drop_inode(handle_t *handle, struct inode *inode)
++{
++}
++
++static inline void
++ext3_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT3_FS_XATTR */
++
++# ifdef CONFIG_EXT3_FS_XATTR_USER
++
++extern int init_ext3_xattr_user(void) __init;
++extern void exit_ext3_xattr_user(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR_USER */
++
++static inline int
++init_ext3_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr_user(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.18-alexey/include/linux/xattr.h	2003-09-01 14:55:39.000000000 +0400
+@@ -0,0 +1,15 @@
++/*
++  File: linux/xattr.h
++
++  Extended attributes handling.
++
++  Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
++  Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
++*/
++#ifndef _LINUX_XATTR_H
++#define _LINUX_XATTR_H
++
++#define XATTR_CREATE	1	/* set value, fail if attr already exists */
++#define XATTR_REPLACE	2	/* set value, fail if attr does not exist */
++
++#endif	/* _LINUX_XATTR_H */
+
+_
diff --git a/lustre/kernel_patches/patches/linux-2.4.19-pre1-xattr-0.8.54.patch b/lustre/kernel_patches/patches/linux-2.4.19-pre1-xattr-0.8.54.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d5d003087cb3a0aad6471bf40f1ccc42415b6397
--- /dev/null
+++ b/lustre/kernel_patches/patches/linux-2.4.19-pre1-xattr-0.8.54.patch
@@ -0,0 +1,6038 @@
+ Documentation/Configure.help  |   66 ++
+ arch/alpha/defconfig          |    7 
+ arch/alpha/kernel/entry.S     |   12 
+ arch/arm/defconfig            |    7 
+ arch/arm/kernel/calls.S       |   24 
+ arch/i386/defconfig           |    7 
+ arch/ia64/defconfig           |    7 
+ arch/ia64/kernel/entry.S      |   24 
+ arch/m68k/defconfig           |    7 
+ arch/mips/defconfig           |    7 
+ arch/mips64/defconfig         |    7 
+ arch/ppc/defconfig            |   14 
+ arch/ppc64/kernel/misc.S      |    2 
+ arch/s390/defconfig           |    7 
+ arch/s390/kernel/entry.S      |   24 
+ arch/s390x/defconfig          |    7 
+ arch/s390x/kernel/entry.S     |   24 
+ arch/s390x/kernel/wrapper32.S |   92 +++
+ arch/sparc/defconfig          |    7 
+ arch/sparc/kernel/systbls.S   |   10 
+ arch/sparc64/defconfig        |    7 
+ arch/sparc64/kernel/systbls.S |   20 
+ fs/Config.in                  |   14 
+ fs/Makefile                   |    3 
+ fs/ext2/Makefile              |    4 
+ fs/ext2/file.c                |    5 
+ fs/ext2/ialloc.c              |    2 
+ fs/ext2/inode.c               |   34 -
+ fs/ext2/namei.c               |   14 
+ fs/ext2/super.c               |   29 
+ fs/ext2/symlink.c             |   14 
+ fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
+ fs/ext2/xattr_user.c          |  103 +++
+ fs/ext3/Makefile              |   10 
+ fs/ext3/file.c                |    5 
+ fs/ext3/ialloc.c              |    2 
+ fs/ext3/inode.c               |   35 -
+ fs/ext3/namei.c               |   21 
+ fs/ext3/super.c               |   36 +
+ fs/ext3/symlink.c             |   14 
+ fs/ext3/xattr.c               | 1225 ++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/xattr_user.c          |  111 +++
+ fs/jfs/jfs_xattr.h            |    6 
+ fs/jfs/xattr.c                |    6 
+ fs/mbcache.c                  |  648 ++++++++++++++++++++++
+ include/asm-arm/unistd.h      |    2 
+ include/asm-ia64/unistd.h     |   13 
+ include/asm-ppc64/unistd.h    |    2 
+ include/asm-s390/unistd.h     |   15 
+ include/asm-s390x/unistd.h    |   15 
+ include/asm-sparc/unistd.h    |   24 
+ include/asm-sparc64/unistd.h  |   24 
+ include/linux/cache_def.h     |   15 
+ include/linux/errno.h         |    4 
+ include/linux/ext2_fs.h       |   31 -
+ include/linux/ext2_xattr.h    |  157 +++++
+ include/linux/ext3_fs.h       |   31 -
+ include/linux/ext3_jbd.h      |    8 
+ include/linux/ext3_xattr.h    |  157 +++++
+ include/linux/fs.h            |    2 
+ include/linux/mbcache.h       |   69 ++
+ kernel/ksyms.c                |    4 
+ mm/vmscan.c                   |   35 +
+ fs/ext3/ext3-exports.c        |   14 +  
+ 64 files changed, 4355 insertions(+), 195 deletions(-)
+
+Index: linux-2.4.19-pre1/Documentation/Configure.help
+===================================================================
+--- linux-2.4.19-pre1.orig/Documentation/Configure.help	2003-11-20 19:01:44.000000000 +0300
++++ linux-2.4.19-pre1/Documentation/Configure.help	2003-11-21 03:51:05.000000000 +0300
+@@ -14035,6 +14035,39 @@
+   be compiled as a module, and so this could be dangerous.  Most
+   everyone wants to say Y here.
+ 
++Ext2 extended attributes
++CONFIG_EXT2_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 extended attribute block sharing
++CONFIG_EXT2_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext2 extended user attributes
++CONFIG_EXT2_FS_XATTR_USER
++  This option enables extended user attributes on ext2. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 trusted extended attributes
++CONFIG_EXT2_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext2 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Ext3 journalling file system support (EXPERIMENTAL)
+ CONFIG_EXT3_FS
+   This is the journalling version of the Second extended file system
+@@ -14067,6 +14100,39 @@
+   of your root partition (the one containing the directory /) cannot
+   be compiled as a module, and so this may be dangerous.
+ 
++Ext3 extended attributes
++CONFIG_EXT3_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 extended attribute block sharing
++CONFIG_EXT3_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext3 extended user attributes
++CONFIG_EXT3_FS_XATTR_USER
++  This option enables extended user attributes on ext3. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 trusted extended attributes
++CONFIG_EXT3_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext3 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
+ CONFIG_JBD
+   This is a generic journalling layer for block devices.  It is
+Index: linux-2.4.19-pre1/arch/alpha/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/alpha/defconfig	2001-11-20 02:19:42.000000000 +0300
++++ linux-2.4.19-pre1/arch/alpha/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ALPHA=y
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+Index: linux-2.4.19-pre1/arch/alpha/kernel/entry.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/alpha/kernel/entry.S	2001-11-10 00:45:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/alpha/kernel/entry.S	2003-11-21 03:51:05.000000000 +0300
+@@ -1148,3 +1148,16 @@
+ 	.quad sys_gettid
+ 	.quad sys_readahead
+ 	.quad sys_ni_syscall			/* 380, sys_security */
++	.quad sys_ni_syscall			/* 381, sys_tkill */
++	.quad sys_setxattr
++	.quad sys_lsetxattr
++	.quad sys_fsetxattr
++	.quad sys_getxattr			/* 385 */
++	.quad sys_lgetxattr
++	.quad sys_fgetxattr
++	.quad sys_listxattr
++	.quad sys_llistxattr
++	.quad sys_flistxattr			/* 390 */
++	.quad sys_removexattr
++	.quad sys_lremovexattr
++	.quad sys_fremovexattr
+Index: linux-2.4.19-pre1/arch/arm/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/arm/defconfig	2001-05-20 04:43:05.000000000 +0400
++++ linux-2.4.19-pre1/arch/arm/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ARM=y
+ # CONFIG_EISA is not set
+ # CONFIG_SBUS is not set
+Index: linux-2.4.19-pre1/arch/arm/kernel/calls.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/arm/kernel/calls.S	2001-10-08 21:39:18.000000000 +0400
++++ linux-2.4.19-pre1/arch/arm/kernel/calls.S	2003-11-21 03:51:05.000000000 +0300
+@@ -236,6 +236,22 @@
+ 		.long	SYMBOL_NAME(sys_mincore)
+ /* 220 */	.long	SYMBOL_NAME(sys_madvise)
+ 		.long	SYMBOL_NAME(sys_fcntl64)
++ 		.long	SYMBOL_NAME(sys_ni_syscall) /* TUX */
++ 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
++ 		.long	SYMBOL_NAME(sys_gettid)
++ /* 225 */	.long	SYMBOL_NAME(sys_readahead)
++		.long	SYMBOL_NAME(sys_setxattr)
++		.long	SYMBOL_NAME(sys_lsetxattr)
++		.long	SYMBOL_NAME(sys_fsetxattr)
++		.long	SYMBOL_NAME(sys_getxattr)
++/* 230 */	.long	SYMBOL_NAME(sys_lgetxattr)
++		.long	SYMBOL_NAME(sys_fgetxattr)
++		.long	SYMBOL_NAME(sys_listxattr)
++		.long	SYMBOL_NAME(sys_llistxattr)
++		.long	SYMBOL_NAME(sys_flistxattr)
++/* 235 */	.long	SYMBOL_NAME(sys_removexattr)
++		.long	SYMBOL_NAME(sys_lremovexattr)
++		.long	SYMBOL_NAME(sys_fremovexattr)
+ __syscall_end:
+ 
+ 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
+Index: linux-2.4.19-pre1/arch/i386/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/i386/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/i386/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+Index: linux-2.4.19-pre1/arch/ia64/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/ia64/defconfig	2001-11-10 01:26:17.000000000 +0300
++++ linux-2.4.19-pre1/arch/ia64/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+Index: linux-2.4.19-pre1/arch/ia64/kernel/entry.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/ia64/kernel/entry.S	2001-11-10 01:26:17.000000000 +0300
++++ linux-2.4.19-pre1/arch/ia64/kernel/entry.S	2003-11-21 03:51:05.000000000 +0300
+@@ -1130,18 +1130,18 @@
+ 	data8 sys_getdents64
+ 	data8 sys_getunwind			// 1215
+ 	data8 sys_readahead
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall			// 1220
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall			// 1225
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
+-	data8 ia64_ni_syscall
++	data8 sys_setxattr
++	data8 sys_lsetxattr
++	data8 sys_fsetxattr
++	data8 sys_getxattr			// 1220
++	data8 sys_lgetxattr
++	data8 sys_fgetxattr
++	data8 sys_listxattr
++	data8 sys_llistxattr
++	data8 sys_flistxattr			// 1225
++	data8 sys_removexattr
++	data8 sys_lremovexattr
++	data8 sys_fremovexattr
+ 	data8 ia64_ni_syscall
+ 	data8 ia64_ni_syscall			// 1230
+ 	data8 ia64_ni_syscall
+Index: linux-2.4.19-pre1/arch/m68k/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/m68k/defconfig	2000-06-19 23:56:08.000000000 +0400
++++ linux-2.4.19-pre1/arch/m68k/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ 
+ #
+Index: linux-2.4.19-pre1/arch/mips/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/mips/defconfig	2001-09-09 21:43:02.000000000 +0400
++++ linux-2.4.19-pre1/arch/mips/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ # CONFIG_SMP is not set
+ 
+Index: linux-2.4.19-pre1/arch/mips64/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/mips64/defconfig	2001-09-09 21:43:02.000000000 +0400
++++ linux-2.4.19-pre1/arch/mips64/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+Index: linux-2.4.19-pre1/arch/ppc/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/ppc/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/ppc/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,20 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+Index: linux-2.4.19-pre1/arch/s390/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/s390/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/s390/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+Index: linux-2.4.19-pre1/arch/s390/kernel/entry.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/s390/kernel/entry.S	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/s390/kernel/entry.S	2003-11-21 03:51:05.000000000 +0300
+@@ -599,8 +599,19 @@
+         .long  sys_fcntl64 
+ 	.long  sys_ni_syscall		 /* 222 - reserved for posix_acl */
+ 	.long  sys_ni_syscall		 /* 223 - reserved for posix_acl */
+-	.long  sys_ni_syscall		 /* 224 - reserved for posix_acl */
+-	.rept  255-224
++	.long  sys_setxattr
++	.long  sys_lsetxattr		/* 225 */
++	.long  sys_fsetxattr
++	.long  sys_getxattr
++	.long  sys_lgetxattr
++	.long  sys_fgetxattr
++	.long  sys_listxattr		/* 230 */
++	.long  sys_llistxattr
++	.long  sys_flistxattr
++	.long  sys_removexattr
++	.long  sys_lremovexattr
++	.long  sys_fremovexattr		/* 235 */
++	.rept  255-235
+ 	.long  sys_ni_syscall
+ 	.endr
+ 
+Index: linux-2.4.19-pre1/arch/s390x/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/s390x/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/s390x/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+Index: linux-2.4.19-pre1/arch/s390x/kernel/entry.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/s390x/kernel/entry.S	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/s390x/kernel/entry.S	2003-11-21 03:51:05.000000000 +0300
+@@ -632,8 +632,19 @@
+ 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
+-        .rept  255-224
++	.long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
++	.long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)	/* 225 */
++	.long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
++	.long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
++	.long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
++	.long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
++	.long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)	/* 230 */
++	.long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
++	.long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
++	.long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
++	.long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
++	.long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
++        .rept  255-235
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+ 	.endr
+ 
+Index: linux-2.4.19-pre1/arch/s390x/kernel/wrapper32.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/s390x/kernel/wrapper32.S	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/s390x/kernel/wrapper32.S	2003-11-21 03:51:05.000000000 +0300
+@@ -1091,3 +1091,95 @@
+ 	llgtr	%r3,%r3			# struct stat64 *
+ 	llgfr	%r4,%r4			# long
+ 	jg	sys32_fstat64		# branch to system call
++
++	.globl	sys32_setxattr_wrapper
++sys32_setxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_setxattr
++
++	.globl	sys32_lsetxattr_wrapper
++sys32_lsetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_lsetxattr
++
++	.globl	sys32_fsetxattr_wrapper
++sys32_fsetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_fsetxattr
++
++	.globl	sys32_getxattr_wrapper
++sys32_getxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_getxattr
++
++	.globl	sys32_lgetxattr_wrapper
++sys32_lgetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_lgetxattr
++
++	.globl	sys32_fgetxattr_wrapper
++sys32_fgetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_fgetxattr
++
++	.globl	sys32_listxattr_wrapper
++sys32_listxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_listxattr
++
++	.globl	sys32_llistxattr_wrapper
++sys32_llistxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_llistxattr
++
++	.globl	sys32_flistxattr_wrapper
++sys32_flistxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_flistxattr
++
++	.globl	sys32_removexattr_wrapper
++sys32_removexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_removexattr
++
++	.globl	sys32_lremovexattr_wrapper
++sys32_lremovexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_lremovexattr
++
++	.globl	sys32_fremovexattr_wrapper
++sys32_fremovexattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	jg	sys_fremovexattr
++
++
+Index: linux-2.4.19-pre1/arch/sparc/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/sparc/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/sparc/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ CONFIG_HIGHMEM=y
+ 
+Index: linux-2.4.19-pre1/arch/sparc/kernel/systbls.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/sparc/kernel/systbls.S	2001-10-21 21:36:54.000000000 +0400
++++ linux-2.4.19-pre1/arch/sparc/kernel/systbls.S	2003-11-21 03:51:05.000000000 +0300
+@@ -51,11 +51,11 @@
+ /*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
+ /*155*/	.long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+ /*160*/	.long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
+-/*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
+-/*170*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
+-/*175*/	.long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+-/*180*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
+-/*185*/	.long sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname
++/*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
++/*170*/	.long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
++/*175*/	.long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
++/*180*/	.long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
++/*185*/	.long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
+ /*190*/	.long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ /*195*/	.long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
+ /*200*/	.long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
+Index: linux-2.4.19-pre1/arch/sparc64/defconfig
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/sparc64/defconfig	2003-11-20 19:01:35.000000000 +0300
++++ linux-2.4.19-pre1/arch/sparc64/defconfig	2003-11-21 03:51:05.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+Index: linux-2.4.19-pre1/arch/sparc64/kernel/systbls.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/sparc64/kernel/systbls.S	2001-10-21 21:36:54.000000000 +0400
++++ linux-2.4.19-pre1/arch/sparc64/kernel/systbls.S	2003-11-21 03:51:05.000000000 +0300
+@@ -52,11 +52,11 @@
+ /*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
+ 	.word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
+ /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
+-	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
+-/*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
+-	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+-/*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
+-	.word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
++	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
++/*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
++	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
++/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
++	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
+ /*190*/	.word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
+ /*200*/	.word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
+@@ -111,11 +111,11 @@
+ /*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
+ 	.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+ /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
+-	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
+-/*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
+-	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+-/*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
+-	.word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
++	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
++/*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
++	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
++/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
++	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
+ /*190*/	.word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
+ /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
+Index: linux-2.4.19-pre1/fs/Config.in
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/Config.in	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/Config.in	2003-11-21 03:51:05.000000000 +0300
+@@ -22,6 +22,11 @@
+ dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
+ 
+ tristate 'Ext3 journalling file system support (EXPERIMENTAL)' CONFIG_EXT3_FS
++dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
++dep_bool '    Ext3 extended attribute block sharing' \
++    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
++dep_bool '    Ext3 extended user attributes' \
++    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
+ # CONFIG_JBD could be its own option (even modular), but until there are
+ # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
+ # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
+@@ -77,6 +82,11 @@
+ tristate 'ROM file system support' CONFIG_ROMFS_FS
+ 
+ tristate 'Second extended fs support' CONFIG_EXT2_FS
++dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
++dep_bool '    Ext2 extended attribute block sharing' \
++    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
++dep_bool '    Ext2 extended user attributes' \
++    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
+ 
+ tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
+ 
+@@ -156,6 +166,10 @@
+   fi
+ fi
+ 
++# Meta block cache for Extended Attributes (ext2/ext3)
++#tristate 'Meta block cache' CONFIG_FS_MBCACHE
++define_tristate CONFIG_FS_MBCACHE y 
++
+ mainmenu_option next_comment
+ comment 'Partition Types'
+ source fs/partitions/Config.in
+Index: linux-2.4.19-pre1/fs/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/Makefile	2003-11-21 03:51:01.000000000 +0300
++++ linux-2.4.19-pre1/fs/Makefile	2003-11-21 03:51:05.000000000 +0300
+@@ -14,7 +14,7 @@
+ 		super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
+ 		fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
+ 		dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
+-		filesystems.o namespace.o seq_file.o
++		filesystems.o namespace.o seq_file.o xattr.o
+ 
+ ifeq ($(CONFIG_QUOTA),y)
+ obj-y += dquot.o
+@@ -78,6 +78,9 @@
+ 
+ obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+ 
++export-objs += mbcache.o
++obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
++
+ # persistent filesystems
+ obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+ 
+Index: linux-2.4.19-pre1/fs/ext2/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/Makefile	2001-10-11 19:05:18.000000000 +0400
++++ linux-2.4.19-pre1/fs/ext2/Makefile	2003-11-21 03:51:05.000000000 +0300
+@@ -13,4 +13,8 @@
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.19-pre1/fs/ext2/file.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/file.c	2001-10-11 19:05:18.000000000 +0400
++++ linux-2.4.19-pre1/fs/ext2/file.c	2003-11-21 03:51:05.000000000 +0300
+@@ -20,6 +20,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/sched.h>
+ 
+ /*
+@@ -51,4 +52,8 @@
+ 
+ struct inode_operations ext2_file_inode_operations = {
+ 	truncate:	ext2_truncate,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.19-pre1/fs/ext2/ialloc.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/ialloc.c	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext2/ialloc.c	2003-11-21 03:51:05.000000000 +0300
+@@ -15,6 +15,7 @@
+ #include <linux/config.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ 
+@@ -167,6 +168,7 @@
+ 	 */
+ 	if (!is_bad_inode(inode)) {
+ 		/* Quota is already initialized in iput() */
++		ext2_xattr_delete_inode(inode);
+ 	    	DQUOT_FREE_INODE(inode);
+ 		DQUOT_DROP(inode);
+ 	}
+Index: linux-2.4.19-pre1/fs/ext2/inode.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/inode.c	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext2/inode.c	2003-11-21 03:51:05.000000000 +0300
+@@ -39,6 +39,18 @@
+ static int ext2_update_inode(struct inode * inode, int do_sync);
+ 
+ /*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext2_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext2_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
++/*
+  * Called at each iput()
+  */
+ void ext2_put_inode (struct inode * inode)
+@@ -53,9 +65,7 @@
+ {
+ 	lock_kernel();
+ 
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
+ 	mark_inode_dirty(inode);
+@@ -800,6 +810,8 @@
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext2_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -889,8 +901,7 @@
+ 	unsigned long offset;
+ 	struct ext2_group_desc * gdp;
+ 
+-	if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
+-	     inode->i_ino != EXT2_ACL_DATA_INO &&
++	if ((inode->i_ino != EXT2_ROOT_INO &&
+ 	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
+ 	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
+ 		ext2_error (inode->i_sb, "ext2_read_inode",
+@@ -975,10 +986,7 @@
+ 	for (block = 0; block < EXT2_N_BLOCKS; block++)
+ 		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
+ 
+-	if (inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext2_file_inode_operations;
+ 		inode->i_fop = &ext2_file_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+@@ -987,15 +995,17 @@
+ 		inode->i_fop = &ext2_dir_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext2_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext2_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext2_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext2_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext2_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(raw_inode->i_block[0]));
++	}
+ 	brelse (bh);
+ 	inode->i_attr_flags = 0;
+ 	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
+Index: linux-2.4.19-pre1/fs/ext2/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/namei.c	2001-10-04 09:57:36.000000000 +0400
++++ linux-2.4.19-pre1/fs/ext2/namei.c	2003-11-21 03:51:05.000000000 +0300
+@@ -31,6 +31,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/pagemap.h>
+ 
+ /*
+@@ -136,7 +137,7 @@
+ 
+ 	if (l > sizeof (inode->u.ext2_i.i_data)) {
+ 		/* slow symlink */
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext2_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 		err = block_symlink(inode, symname, l);
+ 		if (err)
+@@ -345,4 +346,15 @@
+ 	rmdir:		ext2_rmdir,
+ 	mknod:		ext2_mknod,
+ 	rename:		ext2_rename,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
++struct inode_operations ext2_special_inode_operations = {
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.19-pre1/fs/ext2/super.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/super.c	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext2/super.c	2003-11-21 03:51:05.000000000 +0300
+@@ -21,6 +21,7 @@
+ #include <linux/string.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -125,6 +126,7 @@
+ 	int db_count;
+ 	int i;
+ 
++	ext2_xattr_put_super(sb);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+ 
+@@ -175,6 +177,13 @@
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -424,6 +433,9 @@
+ 	    blocksize = BLOCK_SIZE;
+ 
+ 	sb->u.ext2_sb.s_mount_opt = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++	/* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
++#endif
+ 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
+ 	    &sb->u.ext2_sb.s_mount_opt)) {
+ 		return NULL;
+@@ -810,12 +822,27 @@
+ 
+ static int __init init_ext2_fs(void)
+ {
+-        return register_filesystem(&ext2_fs_type);
++	int error = init_ext2_xattr();
++	if (error)
++		return error;
++	error = init_ext2_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext2_fs_type);
++	if (!error)
++		return 0;
++
++	exit_ext2_xattr_user();
++fail:
++	exit_ext2_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext2_fs(void)
+ {
+ 	unregister_filesystem(&ext2_fs_type);
++	exit_ext2_xattr_user();
++	exit_ext2_xattr();
+ }
+ 
+ EXPORT_NO_SYMBOLS;
+Index: linux-2.4.19-pre1/fs/ext2/symlink.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/symlink.c	2000-09-28 00:41:33.000000000 +0400
++++ linux-2.4.19-pre1/fs/ext2/symlink.c	2003-11-21 03:51:05.000000000 +0300
+@@ -19,6 +19,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ 
+ static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -32,7 +33,20 @@
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext2_symlink_inode_operations = {
++	readlink:	page_readlink,
++	follow_link:	page_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
+ struct inode_operations ext2_fast_symlink_inode_operations = {
+ 	readlink:	ext2_readlink,
+ 	follow_link:	ext2_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.19-pre1/fs/ext2/xattr.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/xattr.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext2/xattr.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,1212 @@
++/*
++ * linux/fs/ext2/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT2_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++/* These symbols may be needed by a module. */
++EXPORT_SYMBOL(ext2_xattr_register);
++EXPORT_SYMBOL(ext2_xattr_unregister);
++EXPORT_SYMBOL(ext2_xattr_get);
++EXPORT_SYMBOL(ext2_xattr_list);
++EXPORT_SYMBOL(ext2_xattr_set);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT2_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext2_xattr_set2(struct inode *, struct buffer_head *,
++			   struct ext2_xattr_header *);
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++static int ext2_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext2_xattr_cache_find(struct inode *,
++						 struct ext2_xattr_header *);
++static void ext2_xattr_cache_remove(struct buffer_head *);
++static void ext2_xattr_rehash(struct ext2_xattr_header *,
++			      struct ext2_xattr_entry *);
++
++static struct mb_cache *ext2_xattr_cache;
++
++#else
++# define ext2_xattr_cache_insert(bh) 0
++# define ext2_xattr_cache_find(inode, header) NULL
++# define ext2_xattr_cache_remove(bh) while(0) {}
++# define ext2_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext2_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext2_xattr_sem);
++
++static inline int
++ext2_xattr_new_block(struct inode *inode, int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
++		EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext2_new_block(inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext2_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext2_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext2_xattr_free_block(struct inode * inode, unsigned long block)
++{
++	ext2_free_blocks(inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext2_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext2_xattr_free_block(inode, block) \
++	ext2_free_blocks(inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
++rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		if (!ext2_xattr_handlers[name_index-1]) {
++			ext2_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext2_handler_lock);
++	}
++	return error;
++}
++
++void
++ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		ext2_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext2_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static struct ext2_xattr_handler *
++ext2_xattr_resolve_name(const char **name)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext2_handler_lock);
++	for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
++		if (ext2_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext2_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext2_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext2_handler_lock);
++	return handler;
++}
++
++static inline struct ext2_xattr_handler *
++ext2_xattr_handler(int name_index)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		read_lock(&ext2_handler_lock);
++		handler = ext2_xattr_handlers[name_index-1];
++		read_unlock(&ext2_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext2_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext2_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT2_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT2_I(inode)->i_file_acl)
++		return 0;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext2_xattr_update_super_block(struct super_block *sb)
++{
++	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT2_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext2_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_header *header = NULL;
++	struct ext2_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT2_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext2_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext2_error(sb, "ext2_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext2_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT2_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT2_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT2_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext2_xattr_cache_remove(bh);
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT2_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT2_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT2_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext2_xattr_set2(inode, bh, NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT2_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT2_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT2_XATTR_PAD, 0,
++			       EXT2_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext2_xattr_rehash(header, here);
++
++	error = ext2_xattr_set2(inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext2_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext2_xattr_set(): Update the file system.
++ */
++static int
++ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
++		struct ext2_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext2_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext2_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext2_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT2_I(inode)->i_file_acl != 0;
++			int block = ext2_xattr_new_block(inode, &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++				ext2_xattr_free_block(inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext2_xattr_cache_insert(new_bh);
++			
++			ext2_xattr_update_super_block(sb);
++		}
++		mark_buffer_dirty(new_bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &new_bh);
++			wait_on_buffer(new_bh); 
++			error = -EIO;
++			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
++				goto cleanup;
++		}
++	}
++
++	/* Update the inode. */
++	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	if (IS_SYNC(inode)) {
++		error = ext2_sync_inode (inode);
++		if (error)
++			goto cleanup;
++	} else
++		mark_inode_dirty(inode);
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext2_xattr_free_block(inode, old_bh->b_blocknr);
++			mark_buffer_clean(old_bh);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext2_xattr_quota_free(inode);
++			mark_buffer_dirty(old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT2_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext2_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext2_xattr_cache_remove(bh);
++		ext2_xattr_free_block(inode, block);
++		bforget(bh);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		mark_buffer_dirty(bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &bh);
++			wait_on_buffer(bh);
++		}
++		ext2_xattr_quota_free(inode);
++	}
++	EXT2_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext2_xattr_sem);
++}
++
++/*
++ * ext2_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext2_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++	mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++/*
++ * ext2_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext2_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext2_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext2_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext2_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext2_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext2_xattr_cmp(struct ext2_xattr_header *header1,
++	       struct ext2_xattr_header *header2)
++{
++	struct ext2_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT2_XATTR_NEXT(entry1);
++		entry2 = EXT2_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext2_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT2_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT2_XATTR_REFCOUNT_MAX);
++		} else if (!ext2_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext2_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext2_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
++					 struct ext2_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext2_xattr_rehash(struct ext2_xattr_header *header,
++			      struct ext2_xattr_entry *entry)
++{
++	struct ext2_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext2_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT2_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext2_xattr(void)
++{
++	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext2_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++	mb_cache_destroy(ext2_xattr_cache);
++}
++
++#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
++
++int __init
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
+Index: linux-2.4.19-pre1/fs/ext2/xattr_user.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext2/xattr_user.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext2/xattr_user.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,103 @@
++/*
++ * linux/fs/ext2/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++# include <linux/ext2_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext2_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext2_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext2_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
++			      value, size, flags);
++}
++
++struct ext2_xattr_handler ext2_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext2_xattr_user_list,
++	get:	ext2_xattr_user_get,
++	set:	ext2_xattr_user_set,
++};
++
++int __init
++init_ext2_xattr_user(void)
++{
++	return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
++				   &ext2_xattr_user_handler);
++}
++
++void
++exit_ext2_xattr_user(void)
++{
++	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
++			      &ext2_xattr_user_handler);
++}
+Index: linux-2.4.19-pre1/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/Makefile	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/Makefile	2003-11-21 03:51:05.000000000 +0300
+@@ -1,5 +1,5 @@
+ #
+-# Makefile for the linux ext2-filesystem routines.
++# Makefile for the linux ext3-filesystem routines.
+ #
+ # Note! Dependencies are done automagically by 'make dep', which also
+ # removes any old dependencies. DON'T put your own dependencies here
+@@ -9,10 +9,14 @@
+ 
+ O_TARGET := ext3.o
+ 
+-export-objs :=	super.o inode.o
++export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o hash.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.19-pre1/fs/ext3/file.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/file.c	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/file.c	2003-11-21 03:51:05.000000000 +0300
+@@ -23,6 +23,7 @@
+ #include <linux/locks.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/smp_lock.h>
+ 
+@@ -93,5 +94,9 @@
+ struct inode_operations ext3_file_inode_operations = {
+ 	truncate:	ext3_truncate,		/* BKL held */
+ 	setattr:	ext3_setattr,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+ 
+Index: linux-2.4.19-pre1/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/ialloc.c	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/ialloc.c	2003-11-21 03:51:05.000000000 +0300
+@@ -17,6 +17,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+ #include <linux/locks.h>
+@@ -216,6 +217,7 @@
+ 	 * as writing the quota to disk may need the lock as well.
+ 	 */
+ 	DQUOT_INIT(inode);
++	ext3_xattr_delete_inode(handle, inode);
+ 	DQUOT_FREE_INODE(inode);
+ 	DQUOT_DROP(inode);
+ 
+Index: linux-2.4.19-pre1/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/inode.c	2003-11-20 19:01:36.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/inode.c	2003-11-21 03:51:05.000000000 +0300
+@@ -39,6 +39,18 @@
+  */
+ #undef SEARCH_FROM_ZERO
+ 
++/*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext3_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext3_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
+ /* The ext3 forget function must perform a revoke if we are freeing data
+  * which has been journaled.  Metadata (eg. indirect blocks) must be
+  * revoked in all cases. 
+@@ -48,7 +60,7 @@
+  * still needs to be revoked.
+  */
+ 
+-static int ext3_forget(handle_t *handle, int is_metadata,
++int ext3_forget(handle_t *handle, int is_metadata,
+ 		       struct inode *inode, struct buffer_head *bh,
+ 		       int blocknr)
+ {
+@@ -164,9 +176,7 @@
+ {
+ 	handle_t *handle;
+ 	
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 
+ 	lock_kernel();
+@@ -1845,6 +1855,8 @@
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext3_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -1992,8 +2004,6 @@
+ 	struct ext3_group_desc * gdp;
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+-		inode->i_ino != EXT3_ACL_IDX_INO &&
+-		inode->i_ino != EXT3_ACL_DATA_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+ 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+ 		inode->i_ino > le32_to_cpu(
+@@ -2120,10 +2130,7 @@
+ 
+ 	brelse (iloc.bh);
+ 
+-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+@@ -2131,15 +2138,17 @@
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext3_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext3_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext3_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
++	}
+ 	/* inode->i_attr_flags = 0;				unused */
+ 	if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) {
+ 		/* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */
+Index: linux-2.4.19-pre1/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/namei.c	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/namei.c	2003-11-21 03:51:05.000000000 +0300
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/fcntl.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+@@ -1612,7 +1613,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR);
++	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1620,7 +1621,6 @@
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+ 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+-	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+ 		inode->i_nlink--; /* is this nlink == 0? */
+@@ -1647,9 +1647,6 @@
+ 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
+ 	ext3_journal_dirty_metadata(handle, dir_block);
+ 	brelse (dir_block);
+-	inode->i_mode = S_IFDIR | mode;
+-	if (dir->i_mode & S_ISGID)
+-		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+ 	if (err) {
+@@ -2018,7 +2015,7 @@
+ 		goto out_stop;
+ 
+ 	if (l > sizeof (EXT3_I(inode)->i_data)) {
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext3_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+ 		 * block_symlink() calls back into ext3_prepare/commit_write.
+@@ -2245,4 +2242,16 @@
+ 	rmdir:		ext3_rmdir,		/* BKL held */
+ 	mknod:		ext3_mknod,		/* BKL held */
+ 	rename:		ext3_rename,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
++
++struct inode_operations ext3_special_inode_operations = {
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+Index: linux-2.4.19-pre1/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/super.c	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/super.c	2003-11-21 03:51:05.000000000 +0300
+@@ -24,6 +24,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -404,6 +405,7 @@
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
+@@ -499,6 +501,7 @@
+ 			  int is_remount)
+ {
+ 	unsigned long *mount_options = &sbi->s_mount_opt;
++	
+ 	uid_t *resuid = &sbi->s_resuid;
+ 	gid_t *resgid = &sbi->s_resgid;
+ 	char * this_char;
+@@ -511,6 +514,13 @@
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -924,6 +934,12 @@
+ 	sbi->s_mount_opt = 0;
+ 	sbi->s_resuid = EXT3_DEF_RESUID;
+ 	sbi->s_resgid = EXT3_DEF_RESGID;
++
++	/* Default extended attribute flags */
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++	/* set_opt(sbi->s_mount_opt, XATTR_USER); */
++#endif
++
+ 	if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
+ 		sb->s_dev = 0;
+ 		goto out_fail;
+@@ -1742,17 +1758,29 @@
+ 
+ static int __init init_ext3_fs(void)
+ {
+-        return register_filesystem(&ext3_fs_type);
++	int error = init_ext3_xattr();
++	if (error)
++		return error;
++	error = init_ext3_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext3_fs_type);
++	if (!error)
++		return 0;
++	
++	exit_ext3_xattr_user();
++fail:
++	exit_ext3_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext3_fs(void)
+ {
+ 	unregister_filesystem(&ext3_fs_type);
++	exit_ext3_xattr_user();
++	exit_ext3_xattr();
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+-
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+ MODULE_LICENSE("GPL");
+Index: linux-2.4.19-pre1/fs/ext3/symlink.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/symlink.c	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/symlink.c	2003-11-21 03:51:05.000000000 +0300
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ 
+ static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -33,7 +34,20 @@
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext3_symlink_inode_operations = {
++	readlink:	page_readlink,		/* BKL not held.  Don't need */
++	follow_link:	page_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+ 	readlink:	ext3_readlink,		/* BKL not held.  Don't need */
+ 	follow_link:	ext3_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+Index: linux-2.4.19-pre1/fs/ext3/xattr.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/xattr.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/xattr.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,1225 @@
++/*
++ * linux/fs/ext3/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT3_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++#define EXT3_EA_USER "user."
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT3_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
++			   struct ext3_xattr_header *);
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++static int ext3_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext3_xattr_cache_find(struct inode *,
++						 struct ext3_xattr_header *);
++static void ext3_xattr_cache_remove(struct buffer_head *);
++static void ext3_xattr_rehash(struct ext3_xattr_header *,
++			      struct ext3_xattr_entry *);
++
++static struct mb_cache *ext3_xattr_cache;
++
++#else
++# define ext3_xattr_cache_insert(bh) 0
++# define ext3_xattr_cache_find(inode, header) NULL
++# define ext3_xattr_cache_remove(bh) while(0) {}
++# define ext3_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext3_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext3_xattr_sem);
++
++static inline int
++ext3_xattr_new_block(handle_t *handle, struct inode *inode,
++		     int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
++		EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext3_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext3_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext3_xattr_free_block(handle_t *handle, struct inode * inode,
++		      unsigned long block)
++{
++	ext3_free_blocks(handle, inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext3_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext3_xattr_free_block(handle, inode, block) \
++	ext3_free_blocks(handle, inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
++rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		if (!ext3_xattr_handlers[name_index-1]) {
++			ext3_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext3_handler_lock);
++	}
++	return error;
++}
++
++void
++ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		ext3_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext3_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static inline struct ext3_xattr_handler *
++ext3_xattr_resolve_name(const char **name)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext3_handler_lock);
++	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
++		if (ext3_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext3_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext3_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext3_handler_lock);
++	return handler;
++}
++
++static inline struct ext3_xattr_handler *
++ext3_xattr_handler(int name_index)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		read_lock(&ext3_handler_lock);
++		handler = ext3_xattr_handlers[name_index-1];
++		read_unlock(&ext3_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext3_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext3_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT3_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT3_I(inode)->i_file_acl)
++		return 0;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext3_xattr_update_super_block(handle_t *handle,
++					  struct super_block *sb)
++{
++	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT3_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext3_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_header *header = NULL;
++	struct ext3_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT3_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext3_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext3_error(sb, "ext3_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT3_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT3_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT3_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext3_xattr_cache_remove(bh);
++			error = ext3_journal_get_write_access(handle, bh);
++			if (error)
++				goto cleanup;
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT3_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT3_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT3_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext3_xattr_set2(handle, inode, bh,NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT3_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT3_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT3_XATTR_PAD, 0,
++			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext3_xattr_rehash(header, here);
++
++	error = ext3_xattr_set2(handle, inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext3_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext3_xattr_set(): Update the file system.
++ */
++static int
++ext3_xattr_set2(handle_t *handle, struct inode *inode,
++		struct buffer_head *old_bh, struct ext3_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext3_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext3_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			error = ext3_journal_get_write_access(handle, new_bh);
++			if (error)
++				goto cleanup;
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext3_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT3_I(inode)->i_file_acl != 0;
++			int block = ext3_xattr_new_block(handle, inode,
++							 &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++getblk_failed:			ext3_xattr_free_block(handle, inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			error = ext3_journal_get_create_access(handle, new_bh);
++			if (error) {
++				unlock_buffer(new_bh);
++				goto getblk_failed;
++			}
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext3_xattr_cache_insert(new_bh);
++			
++			ext3_xattr_update_super_block(handle, sb);
++		}
++		error = ext3_journal_dirty_metadata(handle, new_bh);
++		if (error)
++			goto cleanup;
++	}
++
++	/* Update the inode. */
++	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		error = ext3_journal_get_write_access(handle, old_bh);
++		if (error)
++			goto cleanup;
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
++
++			/* ext3_forget() calls bforget() for us, but we
++			   let our caller release old_bh, so we need to
++			   duplicate the handle before. */
++			get_bh(old_bh);
++			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext3_xattr_quota_free(inode);
++			ext3_journal_dirty_metadata(handle, old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT3_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext3_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ext3_journal_get_write_access(handle, bh);
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext3_xattr_cache_remove(bh);
++		ext3_xattr_free_block(handle, inode, block);
++		ext3_forget(handle, 1, inode, bh, block);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		ext3_journal_dirty_metadata(handle, bh);
++		if (IS_SYNC(inode))
++			handle->h_sync = 1;
++		ext3_xattr_quota_free(inode);
++	}
++	EXT3_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext3_xattr_sem);
++}
++
++/*
++ * ext3_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext3_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++	mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++/*
++ * ext3_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext3_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext3_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext3_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext3_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext3_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext3_xattr_cmp(struct ext3_xattr_header *header1,
++	       struct ext3_xattr_header *header2)
++{
++	struct ext3_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT3_XATTR_NEXT(entry1);
++		entry2 = EXT3_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext3_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT3_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT3_XATTR_REFCOUNT_MAX);
++		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext3_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext3_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
++					 struct ext3_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext3_xattr_rehash(struct ext3_xattr_header *header,
++			      struct ext3_xattr_entry *entry)
++{
++	struct ext3_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext3_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT3_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext3_xattr(void)
++{
++	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext3_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++	if (ext3_xattr_cache)
++		mb_cache_destroy(ext3_xattr_cache);
++	ext3_xattr_cache = NULL;
++}
++
++#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
++
++int __init
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+Index: linux-2.4.19-pre1/fs/ext3/xattr_user.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/xattr_user.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/xattr_user.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,111 @@
++/*
++ * linux/fs/ext3/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++# include <linux/ext3_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext3_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext3_xattr_user_list,
++	get:	ext3_xattr_user_get,
++	set:	ext3_xattr_user_set,
++};
++
++int __init
++init_ext3_xattr_user(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
++				   &ext3_xattr_user_handler);
++}
++
++void
++exit_ext3_xattr_user(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
++			      &ext3_xattr_user_handler);
++}
+Index: linux-2.4.19-pre1/fs/mbcache.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/mbcache.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/mbcache.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,648 @@
++/*
++ * linux/fs/mbcache.c
++ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++/*
++ * Filesystem Meta Information Block Cache (mbcache)
++ *
++ * The mbcache caches blocks of block devices that need to be located
++ * by their device/block number, as well as by other criteria (such
++ * as the block's contents).
++ *
++ * There can only be one cache entry in a cache per device and block number.
++ * Additional indexes need not be unique in this sense. The number of
++ * additional indexes (=other criteria) can be hardwired at compile time
++ * or specified at cache create time.
++ *
++ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
++ * in the cache. A valid entry is in the main hash tables of the cache,
++ * and may also be in the lru list. An invalid entry is not in any hashes
++ * or lists.
++ *
++ * A valid cache entry is only in the lru list if no handles refer to it.
++ * Invalid cache entries will be freed when the last handle to the cache
++ * entry is released. Entries that cannot be freed immediately are put
++ * back on the lru list.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/cache_def.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/mbcache.h>
++
++
++#ifdef MB_CACHE_DEBUG
++# define mb_debug(f...) do { \
++		printk(KERN_DEBUG f); \
++		printk("\n"); \
++	} while (0)
++#define mb_assert(c) do { if (!(c)) \
++		printk(KERN_ERR "assertion " #c " failed\n"); \
++	} while(0)
++#else
++# define mb_debug(f...) do { } while(0)
++# define mb_assert(c) do { } while(0)
++#endif
++#define mb_error(f...) do { \
++		printk(KERN_ERR f); \
++		printk("\n"); \
++	} while(0)
++		
++MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
++MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++MODULE_LICENSE("GPL");
++#endif
++
++EXPORT_SYMBOL(mb_cache_create);
++EXPORT_SYMBOL(mb_cache_shrink);
++EXPORT_SYMBOL(mb_cache_destroy);
++EXPORT_SYMBOL(mb_cache_entry_alloc);
++EXPORT_SYMBOL(mb_cache_entry_insert);
++EXPORT_SYMBOL(mb_cache_entry_release);
++EXPORT_SYMBOL(mb_cache_entry_takeout);
++EXPORT_SYMBOL(mb_cache_entry_free);
++EXPORT_SYMBOL(mb_cache_entry_dup);
++EXPORT_SYMBOL(mb_cache_entry_get);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++EXPORT_SYMBOL(mb_cache_entry_find_first);
++EXPORT_SYMBOL(mb_cache_entry_find_next);
++#endif
++
++
++/*
++ * Global data: list of all mbcache's, lru list, and a spinlock for
++ * accessing cache data structures on SMP machines. The lru list is
++ * global across all mbcaches.
++ */
++
++static LIST_HEAD(mb_cache_list);
++static LIST_HEAD(mb_cache_lru_list);
++static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
++
++static inline int
++mb_cache_indexes(struct mb_cache *cache)
++{
++#ifdef MB_CACHE_INDEXES_COUNT
++	return MB_CACHE_INDEXES_COUNT;
++#else
++	return cache->c_indexes_count;
++#endif
++}
++
++/*
++ * What the mbcache registers as to get shrunk dynamically.
++ */
++
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
++
++static struct cache_definition mb_cache_definition = {
++	"mb_cache",
++	mb_cache_memory_pressure
++};
++
++
++static inline int
++__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
++{
++	return !list_empty(&ce->e_block_list);
++}
++
++
++static inline void
++__mb_cache_entry_unhash(struct mb_cache_entry *ce)
++{
++	int n;
++
++	if (__mb_cache_entry_is_hashed(ce)) {
++		list_del_init(&ce->e_block_list);
++		for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
++			list_del(&ce->e_indexes[n].o_list);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
++{
++	struct mb_cache *cache = ce->e_cache;
++
++	mb_assert(atomic_read(&ce->e_used) == 0);
++	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
++		/* free failed -- put back on the lru list
++		   for freeing later. */
++		spin_lock(&mb_cache_spinlock);
++		list_add(&ce->e_lru_list, &mb_cache_lru_list);
++		spin_unlock(&mb_cache_spinlock);
++	} else {
++		kmem_cache_free(cache->c_entry_cache, ce);
++		atomic_dec(&cache->c_entry_count);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
++{
++	if (atomic_dec_and_test(&ce->e_used)) {
++		if (__mb_cache_entry_is_hashed(ce))
++			list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
++		else {
++			spin_unlock(&mb_cache_spinlock);
++			__mb_cache_entry_forget(ce, GFP_KERNEL);
++			return;
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_memory_pressure()  memory pressure callback
++ *
++ * This function is called by the kernel memory management when memory
++ * gets low.
++ *
++ * @priority: Amount by which to shrink the cache (0 = highes priority)
++ * @gfp_mask: (ignored)
++ */
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int count = 0;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &mb_cache_list) {
++		struct mb_cache *cache =
++			list_entry(l, struct mb_cache, c_cache_list);
++		mb_debug("cache %s (%d)", cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++		count += atomic_read(&cache->c_entry_count);
++	}
++	mb_debug("trying to free %d of %d entries",
++		  count / (priority ? priority : 1), count);
++	if (priority)
++		count /= priority;
++	while (count-- && !list_empty(&mb_cache_lru_list)) {
++		struct mb_cache_entry *ce =
++			list_entry(mb_cache_lru_list.next,
++				   struct mb_cache_entry, e_lru_list);
++		list_del(&ce->e_lru_list);
++		__mb_cache_entry_unhash(ce);
++		list_add_tail(&ce->e_lru_list, &free_list);
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), gfp_mask);
++	}
++}
++
++
++/*
++ * mb_cache_create()  create a new cache
++ *
++ * All entries in one cache are equal size. Cache entries may be from
++ * multiple devices. If this is the first mbcache created, registers
++ * the cache with kernel memory management. Returns NULL if no more
++ * memory was available.
++ *
++ * @name: name of the cache (informal)
++ * @cache_op: contains the callback called when freeing a cache entry
++ * @entry_size: The size of a cache entry, including
++ *              struct mb_cache_entry
++ * @indexes_count: number of additional indexes in the cache. Must equal
++ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
++ *                 hardwired.
++ * @bucket_count: number of hash buckets
++ */
++struct mb_cache *
++mb_cache_create(const char *name, struct mb_cache_op *cache_op,
++		size_t entry_size, int indexes_count, int bucket_count)
++{
++	int m=0, n;
++	struct mb_cache *cache = NULL;
++
++	if(entry_size < sizeof(struct mb_cache_entry) +
++	   indexes_count * sizeof(struct mb_cache_entry_index))
++		return NULL;
++
++	MOD_INC_USE_COUNT;
++	cache = kmalloc(sizeof(struct mb_cache) +
++	                indexes_count * sizeof(struct list_head), GFP_KERNEL);
++	if (!cache)
++		goto fail;
++	cache->c_name = name;
++	cache->c_op.free = NULL;
++	if (cache_op)
++		cache->c_op.free = cache_op->free;
++	atomic_set(&cache->c_entry_count, 0);
++	cache->c_bucket_count = bucket_count;
++#ifdef MB_CACHE_INDEXES_COUNT
++	mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
++#else
++	cache->c_indexes_count = indexes_count;
++#endif
++	cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
++	                              GFP_KERNEL);
++	if (!cache->c_block_hash)
++		goto fail;
++	for (n=0; n<bucket_count; n++)
++		INIT_LIST_HEAD(&cache->c_block_hash[n]);
++	for (m=0; m<indexes_count; m++) {
++		cache->c_indexes_hash[m] = kmalloc(bucket_count *
++		                                 sizeof(struct list_head),
++		                                 GFP_KERNEL);
++		if (!cache->c_indexes_hash[m])
++			goto fail;
++		for (n=0; n<bucket_count; n++)
++			INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
++	}
++	cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
++		0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
++	if (!cache->c_entry_cache)
++		goto fail;
++
++	spin_lock(&mb_cache_spinlock);
++	list_add(&cache->c_cache_list, &mb_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	return cache;
++
++fail:
++	if (cache) {
++		while (--m >= 0)
++			kfree(cache->c_indexes_hash[m]);
++		if (cache->c_block_hash)
++			kfree(cache->c_block_hash);
++		kfree(cache);
++	}
++	MOD_DEC_USE_COUNT;
++	return NULL;
++}
++
++
++/*
++ * mb_cache_shrink()
++ *
++ * Removes all cache entires of a device from the cache. All cache entries
++ * currently in use cannot be freed, and thus remain in the cache.
++ *
++ * @cache: which cache to shrink
++ * @dev: which device's cache entries to shrink
++ */
++void
++mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_dev == dev) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++}
++
++
++/*
++ * mb_cache_destroy()
++ *
++ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
++ * and then destroys it. If this was the last mbcache, un-registers the
++ * mbcache from kernel memory management.
++ */
++void
++mb_cache_destroy(struct mb_cache *cache)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_cache == cache) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	list_del(&cache->c_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++
++	if (atomic_read(&cache->c_entry_count) > 0) {
++		mb_error("cache %s: %d orphaned entries",
++			  cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++	}
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
++	/* We don't have kmem_cache_destroy() in 2.2.x */
++	kmem_cache_shrink(cache->c_entry_cache);
++#else
++	kmem_cache_destroy(cache->c_entry_cache);
++#endif
++	for (n=0; n < mb_cache_indexes(cache); n++)
++		kfree(cache->c_indexes_hash[n]);
++	kfree(cache->c_block_hash);
++	kfree(cache);
++
++	MOD_DEC_USE_COUNT;
++}
++
++
++/*
++ * mb_cache_entry_alloc()
++ *
++ * Allocates a new cache entry. The new entry will not be valid initially,
++ * and thus cannot be looked up yet. It should be filled with data, and
++ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
++ * if no more memory was available.
++ */
++struct mb_cache_entry *
++mb_cache_entry_alloc(struct mb_cache *cache)
++{
++	struct mb_cache_entry *ce;
++
++	atomic_inc(&cache->c_entry_count);
++	ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
++	if (ce) {
++		INIT_LIST_HEAD(&ce->e_lru_list);
++		INIT_LIST_HEAD(&ce->e_block_list);
++		ce->e_cache = cache;
++		atomic_set(&ce->e_used, 1);
++	}
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_insert()
++ *
++ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
++ * the cache. After this, the cache entry can be looked up, but is not yet
++ * in the lru list as the caller still holds a handle to it. Returns 0 on
++ * success, or -EBUSY if a cache entry for that device + inode exists
++ * already (this may happen after a failed lookup, if another process has
++ * inserted the same cache entry in the meantime).
++ *
++ * @dev: device the cache entry belongs to
++ * @block: block number
++ * @keys: array of additional keys. There must be indexes_count entries
++ *        in the array (as specified when creating the cache).
++ */
++int
++mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
++		      unsigned long block, unsigned int keys[])
++{
++	struct mb_cache *cache = ce->e_cache;
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	int error = -EBUSY, n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block)
++			goto out;
++	}
++	__mb_cache_entry_unhash(ce);
++	ce->e_dev = dev;
++	ce->e_block = block;
++	list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
++	for (n=0; n<mb_cache_indexes(cache); n++) {
++		ce->e_indexes[n].o_key = keys[n];
++		bucket = keys[n] % cache->c_bucket_count;
++		list_add(&ce->e_indexes[n].o_list,
++		         &cache->c_indexes_hash[n][bucket]);
++	}
++out:
++	spin_unlock(&mb_cache_spinlock);
++	return error;
++}
++
++
++/*
++ * mb_cache_entry_release()
++ *
++ * Release a handle to a cache entry. When the last handle to a cache entry
++ * is released it is either freed (if it is invalid) or otherwise inserted
++ * in to the lru list.
++ */
++void
++mb_cache_entry_release(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_takeout()
++ *
++ * Take a cache entry out of the cache, making it invalid. The entry can later
++ * be re-inserted using mb_cache_entry_insert(), or released using
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_takeout(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_entry_free()
++ *
++ * This is equivalent to the sequence mb_cache_entry_takeout() --
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_free(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_dup()
++ *
++ * Duplicate a handle to a cache entry (does not duplicate the cache entry
++ * itself). After the call, both the old and the new handle must be released.
++ */
++struct mb_cache_entry *
++mb_cache_entry_dup(struct mb_cache_entry *ce)
++{
++	atomic_inc(&ce->e_used);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_get()
++ *
++ * Get a cache entry  by device / block number. (There can only be one entry
++ * in the cache per device and block.) Returns NULL if no such cache entry
++ * exists.
++ */
++struct mb_cache_entry *
++mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
++{
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		ce = list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			goto cleanup;
++		}
++	}
++	ce = NULL;
++
++cleanup:
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++
++static struct mb_cache_entry *
++__mb_cache_entry_find(struct list_head *l, struct list_head *head,
++		      int index, kdev_t dev, unsigned int key)
++{
++	while (l != head) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry,
++			           e_indexes[index].o_list);
++		if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			return ce;
++		}
++		l = l->next;
++	}
++	return NULL;
++}
++
++
++/*
++ * mb_cache_entry_find_first()
++ *
++ * Find the first cache entry on a given device with a certain key in
++ * an additional index. Additonal matches can be found with
++ * mb_cache_entry_find_next(). Returns NULL if no match was found.
++ *
++ * @cache: the cache to search
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
++			  unsigned int key)
++{
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = cache->c_indexes_hash[index][bucket].next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_find_next()
++ *
++ * Find the next cache entry on a given device with a certain key in an
++ * additional index. Returns NULL if no match could be found. The previous
++ * entry is atomatically released, so that mb_cache_entry_find_next() can
++ * be called like this:
++ *
++ * entry = mb_cache_entry_find_first();
++ * while (entry) {
++ * 	...
++ *	entry = mb_cache_entry_find_next(entry, ...);
++ * }
++ *
++ * @prev: The previous match
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
++			 unsigned int key)
++{
++	struct mb_cache *cache = prev->e_cache;
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = prev->e_indexes[index].o_list.next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	__mb_cache_entry_release_unlock(prev);
++	return ce;
++}
++
++#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
++
++static int __init init_mbcache(void)
++{
++	register_cache(&mb_cache_definition);
++	return 0;
++}
++
++static void __exit exit_mbcache(void)
++{
++	unregister_cache(&mb_cache_definition);
++}
++
++module_init(init_mbcache)
++module_exit(exit_mbcache)
++
+Index: linux-2.4.19-pre1/include/asm-arm/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-arm/unistd.h	2001-08-12 22:14:00.000000000 +0400
++++ linux-2.4.19-pre1/include/asm-arm/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -240,6 +240,18 @@
+ #define __NR_mincore			(__NR_SYSCALL_BASE+219)
+ #define __NR_madvise			(__NR_SYSCALL_BASE+220)
+ #define __NR_fcntl64			(__NR_SYSCALL_BASE+221)
++#define __NR_setxattr			(__NR_SYSCALL_BASE+226)
++#define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
++#define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
++#define __NR_getxattr			(__NR_SYSCALL_BASE+229)
++#define __NR_lgetxattr			(__NR_SYSCALL_BASE+230)
++#define __NR_fgetxattr			(__NR_SYSCALL_BASE+231)
++#define __NR_listxattr			(__NR_SYSCALL_BASE+232)
++#define __NR_llistxattr			(__NR_SYSCALL_BASE+233)
++#define __NR_flistxattr			(__NR_SYSCALL_BASE+234)
++#define __NR_removexattr		(__NR_SYSCALL_BASE+235)
++#define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
++#define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
+ 
+ /*
+  * The following SWIs are ARM private.
+Index: linux-2.4.19-pre1/include/asm-ia64/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-ia64/unistd.h	2001-11-10 01:26:17.000000000 +0300
++++ linux-2.4.19-pre1/include/asm-ia64/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -206,6 +206,18 @@
+ #define __NR_getdents64			1214
+ #define __NR_getunwind			1215
+ #define __NR_readahead			1216
++#define __NR_setxattr			1217
++#define __NR_lsetxattr			1218
++#define __NR_fsetxattr			1219
++#define __NR_getxattr			1220
++#define __NR_lgetxattr			1221
++#define __NR_fgetxattr			1222
++#define __NR_listxattr			1223
++#define __NR_llistxattr			1224
++#define __NR_flistxattr			1225
++#define __NR_removexattr		1226
++#define __NR_lremovexattr		1227
++#define __NR_fremovexattr		1228
+ 
+ #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
+ 
+Index: linux-2.4.19-pre1/include/asm-s390/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-s390/unistd.h	2001-10-11 20:43:38.000000000 +0400
++++ linux-2.4.19-pre1/include/asm-s390/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -211,6 +211,18 @@
+ #define __NR_mincore            218
+ #define __NR_madvise            219
+ #define __NR_getdents64		220
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ 
+ 
+ /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
+Index: linux-2.4.19-pre1/include/asm-s390x/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-s390x/unistd.h	2001-10-11 20:43:38.000000000 +0400
++++ linux-2.4.19-pre1/include/asm-s390x/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -181,6 +181,18 @@
+ #define __NR_mincore            218
+ #define __NR_madvise            219
+ #define __NR_getdents64         220
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ 
+ 
+ /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
+Index: linux-2.4.19-pre1/include/asm-sparc/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-sparc/unistd.h	2001-10-21 21:36:54.000000000 +0400
++++ linux-2.4.19-pre1/include/asm-sparc/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -184,24 +184,24 @@
+ /* #define __NR_exportfs        166    SunOS Specific                              */
+ #define __NR_mount              167 /* Common                                      */
+ #define __NR_ustat              168 /* Common                                      */
+-/* #define __NR_semsys          169    SunOS Specific                              */
+-/* #define __NR_msgsys          170    SunOS Specific                              */
+-/* #define __NR_shmsys          171    SunOS Specific                              */
+-/* #define __NR_auditsys        172    SunOS Specific                              */
+-/* #define __NR_rfssys          173    SunOS Specific                              */
++#define __NR_setxattr           169 /* SunOS: semsys                               */
++#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
++#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
++#define __NR_getxattr           172 /* SunOS: auditsys                             */
++#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
+ #define __NR_getdents           174 /* Common                                      */
+ #define __NR_setsid             175 /* Common                                      */
+ #define __NR_fchdir             176 /* Common                                      */
+-/* #define __NR_fchroot         177    SunOS Specific                              */
+-/* #define __NR_vpixsys         178    SunOS Specific                              */
+-/* #define __NR_aioread         179    SunOS Specific                              */
+-/* #define __NR_aiowrite        180    SunOS Specific                              */
+-/* #define __NR_aiowait         181    SunOS Specific                              */
+-/* #define __NR_aiocancel       182    SunOS Specific                              */
++#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
++#define __NR_listxattr          178 /* SunOS: vpixsys                              */
++#define __NR_llistxattr         179 /* SunOS: aioread                              */
++#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
++#define __NR_removexattr        181 /* SunOS: aiowait                              */
++#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
+ #define __NR_sigpending         183 /* Common                                      */
+ #define __NR_query_module	184 /* Linux Specific				   */
+ #define __NR_setpgid            185 /* Common                                      */
+-/* #define __NR_pathconf        186    SunOS Specific                              */
++#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
+ /* #define __NR_fpathconf       187    SunOS Specific                              */
+ /* #define __NR_sysconf         188    SunOS Specific                              */
+ #define __NR_uname              189 /* Linux Specific                              */
+Index: linux-2.4.19-pre1/include/asm-sparc64/unistd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/asm-sparc64/unistd.h	2001-10-21 21:36:54.000000000 +0400
++++ linux-2.4.19-pre1/include/asm-sparc64/unistd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -184,24 +184,24 @@
+ /* #define __NR_exportfs        166    SunOS Specific                              */
+ #define __NR_mount              167 /* Common                                      */
+ #define __NR_ustat              168 /* Common                                      */
+-/* #define __NR_semsys          169    SunOS Specific                              */
+-/* #define __NR_msgsys          170    SunOS Specific                              */
+-/* #define __NR_shmsys          171    SunOS Specific                              */
+-/* #define __NR_auditsys        172    SunOS Specific                              */
+-/* #define __NR_rfssys          173    SunOS Specific                              */
++#define __NR_setxattr           169 /* SunOS: semsys                               */
++#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
++#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
++#define __NR_getxattr           172 /* SunOS: auditsys                             */
++#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
+ #define __NR_getdents           174 /* Common                                      */
+ #define __NR_setsid             175 /* Common                                      */
+ #define __NR_fchdir             176 /* Common                                      */
+-/* #define __NR_fchroot         177    SunOS Specific                              */
+-/* #define __NR_vpixsys         178    SunOS Specific                              */
+-/* #define __NR_aioread         179    SunOS Specific                              */
+-/* #define __NR_aiowrite        180    SunOS Specific                              */
+-/* #define __NR_aiowait         181    SunOS Specific                              */
+-/* #define __NR_aiocancel       182    SunOS Specific                              */
++#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
++#define __NR_listxattr          178 /* SunOS: vpixsys                              */
++#define __NR_llistxattr         179 /* SunOS: aioread                              */
++#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
++#define __NR_removexattr        181 /* SunOS: aiowait                              */
++#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
+ #define __NR_sigpending         183 /* Common                                      */
+ #define __NR_query_module	184 /* Linux Specific				   */
+ #define __NR_setpgid            185 /* Common                                      */
+-/* #define __NR_pathconf        186    SunOS Specific                              */
++#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
+ /* #define __NR_fpathconf       187    SunOS Specific                              */
+ /* #define __NR_sysconf         188    SunOS Specific                              */
+ #define __NR_uname              189 /* Linux Specific                              */
+Index: linux-2.4.19-pre1/include/linux/cache_def.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/cache_def.h	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/cache_def.h	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,15 @@
++/*
++ * linux/cache_def.h
++ * Handling of caches defined in drivers, filesystems, ...
++ *
++ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++struct cache_definition {
++	const char *name;
++	void (*shrink)(int, unsigned int);
++	struct list_head link;
++};
++
++extern void register_cache(struct cache_definition *);
++extern void unregister_cache(struct cache_definition *);
+Index: linux-2.4.19-pre1/include/linux/errno.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/errno.h	2001-02-10 01:46:13.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/errno.h	2003-11-21 03:51:05.000000000 +0300
+@@ -23,4 +23,8 @@
+ 
+ #endif
+ 
++/* Defined for extended attributes */
++#define ENOATTR ENODATA		/* No such attribute */
++#define ENOTSUP EOPNOTSUPP	/* Operation not supported */
++
+ #endif
+Index: linux-2.4.19-pre1/include/linux/ext2_fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext2_fs.h	2001-11-22 22:46:52.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext2_fs.h	2003-11-21 03:51:05.000000000 +0300
+@@ -57,8 +57,6 @@
+  */
+ #define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT2_ROOT_INO		 2	/* Root inode */
+-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ 
+@@ -86,7 +84,6 @@
+ #else
+ # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+ #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -121,28 +118,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext2_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext2_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext2_group_desc
+@@ -314,6 +289,7 @@
+ #define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+ #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+ #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
++#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+ #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+@@ -397,6 +373,7 @@
+ 
+ #ifdef __KERNEL__
+ #define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
++#define EXT2_I(inode)	(&((inode)->u.ext2_i))
+ #else
+ /* Assume that user mode programs are passing in an ext2fs superblock, not
+  * a kernel struct super_block.  This will allow us to call the feature-test
+@@ -466,7 +443,7 @@
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008
+ #define EXT2_FEATURE_INCOMPAT_ANY		0xffffffff
+ 
+-#define EXT2_FEATURE_COMPAT_SUPP	0
++#define EXT2_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+ #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+@@ -623,8 +600,10 @@
+ 
+ /* namei.c */
+ extern struct inode_operations ext2_dir_inode_operations;
++extern struct inode_operations ext2_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext2_symlink_inode_operations;
+ extern struct inode_operations ext2_fast_symlink_inode_operations;
+ 
+ #endif	/* __KERNEL__ */
+Index: linux-2.4.19-pre1/include/linux/ext2_xattr.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext2_xattr.h	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext2_xattr.h	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext2_xattr.h
++
++  On-disk format of extended attributes for the ext2 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT2_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT2_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT2_XATTR_INDEX_MAX			10
++#define EXT2_XATTR_INDEX_USER			1
++#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext2_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext2_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT2_XATTR_PAD_BITS		2
++#define EXT2_XATTR_PAD		(1<<EXT2_XATTR_PAD_BITS)
++#define EXT2_XATTR_ROUND		(EXT2_XATTR_PAD-1)
++#define EXT2_XATTR_LEN(name_len) \
++	(((name_len) + EXT2_XATTR_ROUND + \
++	sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
++#define EXT2_XATTR_NEXT(entry) \
++	( (struct ext2_xattr_entry *)( \
++	  (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
++#define EXT2_XATTR_SIZE(size) \
++	(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT2_FS_XATTR
++
++struct ext2_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
++extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
++
++extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
++extern int ext2_removexattr(struct dentry *, const char *);
++
++extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext2_xattr_list(struct inode *, char *, size_t);
++extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext2_xattr_delete_inode(struct inode *);
++extern void ext2_xattr_put_super(struct super_block *);
++
++extern int init_ext2_xattr(void) __init;
++extern void exit_ext2_xattr(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR */
++#  define ext2_setxattr		NULL
++#  define ext2_getxattr		NULL
++#  define ext2_listxattr	NULL
++#  define ext2_removexattr	NULL
++
++static inline int
++ext2_xattr_get(struct inode *inode, int name_index,
++	       const char *name, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++}
++
++static inline void
++ext2_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR */
++
++# ifdef CONFIG_EXT2_FS_XATTR_USER
++
++extern int init_ext2_xattr_user(void) __init;
++extern void exit_ext2_xattr_user(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR_USER */
++
++static inline int
++init_ext2_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr_user(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+Index: linux-2.4.19-pre1/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_fs.h	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_fs.h	2003-11-21 03:51:05.000000000 +0300
+@@ -63,8 +63,6 @@
+  */
+ #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT3_ROOT_INO		 2	/* Root inode */
+-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
+@@ -94,7 +92,6 @@
+ #else
+ # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
+ #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -129,28 +126,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext3_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext3_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext3_group_desc
+@@ -344,6 +319,7 @@
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -520,7 +496,7 @@
+ #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+ 
+-#define EXT3_FEATURE_COMPAT_SUPP	0
++#define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
+ 					 EXT3_FEATURE_INCOMPAT_RECOVER)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+@@ -703,6 +679,7 @@
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
+ 
+ /* inode.c */
++extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+ 
+@@ -771,8 +748,10 @@
+ 
+ /* namei.c */
+ extern struct inode_operations ext3_dir_inode_operations;
++extern struct inode_operations ext3_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext3_symlink_inode_operations;
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
+ 
+Index: linux-2.4.19-pre1/include/linux/ext3_jbd.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_jbd.h	2003-11-21 03:51:02.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_jbd.h	2003-11-21 03:51:05.000000000 +0300
+@@ -30,13 +30,19 @@
+ 
+ #define EXT3_SINGLEDATA_TRANS_BLOCKS	8
+ 
++/* Extended attributes may touch two data buffers, two bitmap buffers,
++ * and two group and summaries. */
++
++#define EXT3_XATTR_TRANS_BLOCKS		8
++
+ /* Define the minimum size for a transaction which modifies data.  This
+  * needs to take into account the fact that we may end up modifying two
+  * quota files too (one for the group, one for the user quota).  The
+  * superblock only gets updated once, of course, so don't bother
+  * counting that again for the quota updates. */
+ 
+-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
++#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
++					 EXT3_XATTR_TRANS_BLOCKS - 2)
+ 
+ extern int ext3_writepage_trans_blocks(struct inode *inode);
+ 
+Index: linux-2.4.19-pre1/include/linux/ext3_xattr.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/ext3_xattr.h	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/ext3_xattr.h	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext3_xattr.h
++
++  On-disk format of extended attributes for the ext3 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT3_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT3_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT3_XATTR_INDEX_MAX			10
++#define EXT3_XATTR_INDEX_USER			1
++#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext3_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext3_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT3_XATTR_PAD_BITS		2
++#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
++#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
++#define EXT3_XATTR_LEN(name_len) \
++	(((name_len) + EXT3_XATTR_ROUND + \
++	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
++#define EXT3_XATTR_NEXT(entry) \
++	( (struct ext3_xattr_entry *)( \
++	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
++#define EXT3_XATTR_SIZE(size) \
++	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT3_FS_XATTR
++
++struct ext3_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
++extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
++
++extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
++extern int ext3_removexattr(struct dentry *, const char *);
++
++extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext3_xattr_list(struct inode *, char *, size_t);
++extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
++extern void ext3_xattr_put_super(struct super_block *);
++
++extern int init_ext3_xattr(void) __init;
++extern void exit_ext3_xattr(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR */
++#  define ext3_setxattr		NULL
++#  define ext3_getxattr		NULL
++#  define ext3_listxattr	NULL
++#  define ext3_removexattr	NULL
++
++static inline int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++}
++
++static inline void
++ext3_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT3_FS_XATTR */
++
++# ifdef CONFIG_EXT3_FS_XATTR_USER
++
++extern int init_ext3_xattr_user(void) __init;
++extern void exit_ext3_xattr_user(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR_USER */
++
++static inline int
++init_ext3_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr_user(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+Index: linux-2.4.19-pre1/include/linux/fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs.h	2003-11-21 03:51:00.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs.h	2003-11-21 03:51:05.000000000 +0300
+@@ -872,6 +872,10 @@
+ 	int (*setattr) (struct dentry *, struct iattr *);
+ 	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
++	int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
++	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
++	ssize_t (*listxattr) (struct dentry *, char *, size_t);
++	int (*removexattr) (struct dentry *, const char *);
+ };
+ 
+ struct seq_file;
+Index: linux-2.4.19-pre1/include/linux/mbcache.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/mbcache.h	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/mbcache.h	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,69 @@
++/*
++  File: linux/mbcache.h
++
++  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++/* Hardwire the number of additional indexes */
++#define MB_CACHE_INDEXES_COUNT 1
++
++struct mb_cache_entry;
++
++struct mb_cache_op {
++	int (*free)(struct mb_cache_entry *, int);
++};
++
++struct mb_cache {
++	struct list_head		c_cache_list;
++	const char			*c_name;
++	struct mb_cache_op		c_op;
++	atomic_t			c_entry_count;
++	int				c_bucket_count;
++#ifndef MB_CACHE_INDEXES_COUNT
++	int				c_indexes_count;
++#endif
++	kmem_cache_t			*c_entry_cache;
++	struct list_head		*c_block_hash;
++	struct list_head		*c_indexes_hash[0];
++};
++
++struct mb_cache_entry_index {
++	struct list_head		o_list;
++	unsigned int			o_key;
++};
++
++struct mb_cache_entry {
++	struct list_head		e_lru_list;
++	struct mb_cache			*e_cache;
++	atomic_t			e_used;
++	kdev_t				e_dev;
++	unsigned long			e_block;
++	struct list_head		e_block_list;
++	struct mb_cache_entry_index	e_indexes[0];
++};
++
++/* Functions on caches */
++
++struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
++				  int, int);
++void mb_cache_shrink(struct mb_cache *, kdev_t);
++void mb_cache_destroy(struct mb_cache *);
++
++/* Functions on cache entries */
++
++struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
++int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
++			  unsigned int[]);
++void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
++void mb_cache_entry_release(struct mb_cache_entry *);
++void mb_cache_entry_takeout(struct mb_cache_entry *);
++void mb_cache_entry_free(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
++					  unsigned long);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
++						 kdev_t, unsigned int);
++struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
++						kdev_t, unsigned int);
++#endif
+Index: linux-2.4.19-pre1/kernel/ksyms.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/ksyms.c	2003-11-21 03:50:59.000000000 +0300
++++ linux-2.4.19-pre1/kernel/ksyms.c	2003-11-21 03:51:05.000000000 +0300
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/slab.h>
++#include <linux/cache_def.h>
+ #include <linux/module.h>
+ #include <linux/blkdev.h>
+ #include <linux/cdrom.h>
+@@ -88,6 +89,7 @@
+ EXPORT_SYMBOL(exit_files);
+ EXPORT_SYMBOL(exit_fs);
+ EXPORT_SYMBOL(exit_sighand);
++EXPORT_SYMBOL(copy_fs_struct);
+ 
+ /* internal kernel memory management */
+ EXPORT_SYMBOL(_alloc_pages);
+@@ -104,6 +106,8 @@
+ EXPORT_SYMBOL(kmem_cache_shrink);
+ EXPORT_SYMBOL(kmem_cache_alloc);
+ EXPORT_SYMBOL(kmem_cache_free);
++EXPORT_SYMBOL(register_cache);
++EXPORT_SYMBOL(unregister_cache);
+ EXPORT_SYMBOL(kmalloc);
+ EXPORT_SYMBOL(kfree);
+ EXPORT_SYMBOL(vfree);
+Index: linux-2.4.19-pre1/mm/vmscan.c
+===================================================================
+--- linux-2.4.19-pre1.orig/mm/vmscan.c	2003-11-20 19:01:38.000000000 +0300
++++ linux-2.4.19-pre1/mm/vmscan.c	2003-11-21 03:51:05.000000000 +0300
+@@ -15,6 +15,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/swap.h>
+ #include <linux/swapctl.h>
++#include <linux/cache_def.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pagemap.h>
+ #include <linux/init.h>
+@@ -32,6 +33,39 @@
+  */
+ #define DEF_PRIORITY (6)
+ 
++static DECLARE_MUTEX(other_caches_sem);
++static LIST_HEAD(cache_definitions);
++
++void register_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_add(&cache->link, &cache_definitions);
++	up(&other_caches_sem);
++}
++
++void unregister_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_del(&cache->link);
++	up(&other_caches_sem);
++}
++
++static void shrink_other_caches(unsigned int priority, int gfp_mask)
++{
++	struct list_head *p;
++
++	if (down_trylock(&other_caches_sem))
++		return;
++
++	list_for_each_prev(p, &cache_definitions) {
++		struct cache_definition *cache =
++			list_entry(p, struct cache_definition, link);
++
++		cache->shrink(priority, gfp_mask);
++	}
++	up(&other_caches_sem);
++}
++
+ /*
+  * The swap-out function returns 1 if it successfully
+  * scanned all the pages it was asked to (`count').
+@@ -578,6 +612,7 @@
+ 
+ 	shrink_dcache_memory(priority, gfp_mask);
+ 	shrink_icache_memory(priority, gfp_mask);
++	shrink_other_caches(priority, gfp_mask);
+ #ifdef CONFIG_QUOTA
+ 	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+ #endif
+Index: linux-2.4.19-pre1/fs/ext3/ext3-exports.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/ext3/ext3-exports.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/ext3/ext3-exports.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
+Index: linux-2.4.19-pre1/include/linux/xattr.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/xattr.h	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/xattr.h	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,15 @@
++/*
++  File: linux/xattr.h
++
++  Extended attributes handling.
++
++  Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
++  Copyright (c) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
++*/
++#ifndef _LINUX_XATTR_H
++#define _LINUX_XATTR_H
++
++#define XATTR_CREATE	0x1	/* set the value, fail if attr already exists */
++#define XATTR_REPLACE	0x2	/* set the value, fail if attr does not exist */
++
++#endif	/* _LINUX_XATTR_H */
+Index: linux-2.4.19-pre1/arch/i386/kernel/entry.S
+===================================================================
+--- linux-2.4.19-pre1.orig/arch/i386/kernel/entry.S	2003-11-21 03:38:55.000000000 +0300
++++ linux-2.4.19-pre1/arch/i386/kernel/entry.S	2003-11-21 03:51:05.000000000 +0300
+@@ -622,18 +622,18 @@
+ 	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
+ 	.long SYMBOL_NAME(sys_gettid)
+ 	.long SYMBOL_NAME(sys_readahead)	/* 225 */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for setxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lsetxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fsetxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for getxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* 230 reserved for lgetxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fgetxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for listxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for llistxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for flistxattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* 235 reserved for removexattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lremovexattr */
+-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fremovexattr */
++	.long SYMBOL_NAME(sys_setxattr)
++	.long SYMBOL_NAME(sys_lsetxattr)
++	.long SYMBOL_NAME(sys_fsetxattr)
++	.long SYMBOL_NAME(sys_getxattr)
++	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
++	.long SYMBOL_NAME(sys_fgetxattr)
++	.long SYMBOL_NAME(sys_listxattr)
++	.long SYMBOL_NAME(sys_llistxattr)
++	.long SYMBOL_NAME(sys_flistxattr)
++	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
++	.long SYMBOL_NAME(sys_lremovexattr)
++	.long SYMBOL_NAME(sys_fremovexattr)
+ 
+ 	.rept NR_syscalls-(.-sys_call_table)/4
+ 		.long SYMBOL_NAME(sys_ni_syscall)
+Index: linux-2.4.19-pre1/fs/xattr.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/xattr.c	2003-11-21 03:51:05.000000000 +0300
++++ linux-2.4.19-pre1/fs/xattr.c	2003-11-21 03:51:05.000000000 +0300
+@@ -0,0 +1,355 @@
++/*
++  File: fs/xattr.c
++
++  Extended attribute handling.
++
++  Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
++  Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
++ */
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/smp_lock.h>
++#include <linux/file.h>
++#include <linux/xattr.h>
++#include <asm/uaccess.h>
++
++/*
++ * Extended attribute memory allocation wrappers, originally
++ * based on the Intermezzo PRESTO_ALLOC/PRESTO_FREE macros.
++ * The vmalloc use here is very uncommon - extended attributes
++ * are supposed to be small chunks of metadata, and it is quite
++ * unusual to have very many extended attributes, so lists tend
++ * to be quite short as well.  The 64K upper limit is derived
++ * from the extended attribute size limit used by XFS.
++ * Intentionally allow zero @size for value/list size requests.
++ */
++static void *
++xattr_alloc(size_t size, size_t limit)
++{
++	void *ptr;
++
++	if (size > limit)
++		return ERR_PTR(-E2BIG);
++
++	if (!size)	/* size request, no buffer is needed */
++		return NULL;
++	else if (size <= PAGE_SIZE)
++		ptr = kmalloc((unsigned long) size, GFP_KERNEL);
++	else
++		ptr = vmalloc((unsigned long) size);
++	if (!ptr)
++		return ERR_PTR(-ENOMEM);
++	return ptr;
++}
++
++static void
++xattr_free(void *ptr, size_t size)
++{
++	if (!size)	/* size request, no buffer was needed */
++		return;
++	else if (size <= PAGE_SIZE)
++		kfree(ptr);
++	else
++		vfree(ptr);
++}
++
++/*
++ * Extended attribute SET operations
++ */
++static long
++setxattr(struct dentry *d, char *name, void *value, size_t size, int flags)
++{
++	int error;
++	void *kvalue;
++	char kname[XATTR_NAME_MAX + 1];
++
++	if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
++		return -EINVAL;
++
++	error = strncpy_from_user(kname, name, sizeof(kname));
++	if (error == 0 || error == sizeof(kname))
++		error = -ERANGE;
++	if (error < 0)
++		return error;
++
++	kvalue = xattr_alloc(size, XATTR_SIZE_MAX);
++	if (IS_ERR(kvalue))
++		return PTR_ERR(kvalue);
++
++	if (size > 0 && copy_from_user(kvalue, value, size)) {
++		xattr_free(kvalue, size);
++		return -EFAULT;
++	}
++
++	error = -EOPNOTSUPP;
++	if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
++		down(&d->d_inode->i_sem);
++		lock_kernel();
++		error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
++		unlock_kernel();
++		up(&d->d_inode->i_sem);
++	}
++
++	xattr_free(kvalue, size);
++	return error;
++}
++
++asmlinkage long
++sys_setxattr(char *path, char *name, void *value, size_t size, int flags)
++{
++	struct nameidata nd;
++	int error;
++
++	error = user_path_walk(path, &nd);
++	if (error)
++		return error;
++	error = setxattr(nd.dentry, name, value, size, flags);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage long
++sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags)
++{
++	struct nameidata nd;
++	int error;
++
++	error = user_path_walk_link(path, &nd);
++	if (error)
++		return error;
++	error = setxattr(nd.dentry, name, value, size, flags);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage long
++sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags)
++{
++	struct file *f;
++	int error = -EBADF;
++
++	f = fget(fd);
++	if (!f)
++		return error;
++	error = setxattr(f->f_dentry, name, value, size, flags);
++	fput(f);
++	return error;
++}
++
++/*
++ * Extended attribute GET operations
++ */
++static ssize_t
++getxattr(struct dentry *d, char *name, void *value, size_t size)
++{
++	ssize_t error;
++	void *kvalue;
++	char kname[XATTR_NAME_MAX + 1];
++
++	error = strncpy_from_user(kname, name, sizeof(kname));
++	if (error == 0 || error == sizeof(kname))
++		error = -ERANGE;
++	if (error < 0)
++		return error;
++
++	kvalue = xattr_alloc(size, XATTR_SIZE_MAX);
++	if (IS_ERR(kvalue))
++		return PTR_ERR(kvalue);
++
++	error = -EOPNOTSUPP;
++	if (d->d_inode->i_op && d->d_inode->i_op->getxattr) {
++		down(&d->d_inode->i_sem);
++		lock_kernel();
++		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
++		unlock_kernel();
++		up(&d->d_inode->i_sem);
++	}
++
++	if (kvalue && error > 0)
++		if (copy_to_user(value, kvalue, error))
++			error = -EFAULT;
++	xattr_free(kvalue, size);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_getxattr(char *path, char *name, void *value, size_t size)
++{
++	struct nameidata nd;
++	ssize_t error;
++
++	error = user_path_walk(path, &nd);
++	if (error)
++		return error;
++	error = getxattr(nd.dentry, name, value, size);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_lgetxattr(char *path, char *name, void *value, size_t size)
++{
++	struct nameidata nd;
++	ssize_t error;
++
++	error = user_path_walk_link(path, &nd);
++	if (error)
++		return error;
++	error = getxattr(nd.dentry, name, value, size);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_fgetxattr(int fd, char *name, void *value, size_t size)
++{
++	struct file *f;
++	ssize_t error = -EBADF;
++
++	f = fget(fd);
++	if (!f)
++		return error;
++	error = getxattr(f->f_dentry, name, value, size);
++	fput(f);
++	return error;
++}
++
++/*
++ * Extended attribute LIST operations
++ */
++static ssize_t
++listxattr(struct dentry *d, char *list, size_t size)
++{
++	ssize_t error;
++	char *klist;
++
++	klist = (char *)xattr_alloc(size, XATTR_LIST_MAX);
++	if (IS_ERR(klist))
++		return PTR_ERR(klist);
++
++	error = -EOPNOTSUPP;
++	if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
++		down(&d->d_inode->i_sem);
++		lock_kernel();
++		error = d->d_inode->i_op->listxattr(d, klist, size);
++		unlock_kernel();
++		up(&d->d_inode->i_sem);
++	}
++
++	if (klist && error > 0)
++		if (copy_to_user(list, klist, error))
++			error = -EFAULT;
++	xattr_free(klist, size);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_listxattr(char *path, char *list, size_t size)
++{
++	struct nameidata nd;
++	ssize_t error;
++
++	error = user_path_walk(path, &nd);
++	if (error)
++		return error;
++	error = listxattr(nd.dentry, list, size);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_llistxattr(char *path, char *list, size_t size)
++{
++	struct nameidata nd;
++	ssize_t error;
++
++	error = user_path_walk_link(path, &nd);
++	if (error)
++		return error;
++	error = listxattr(nd.dentry, list, size);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage ssize_t
++sys_flistxattr(int fd, char *list, size_t size)
++{
++	struct file *f;
++	ssize_t error = -EBADF;
++
++	f = fget(fd);
++	if (!f)
++		return error;
++	error = listxattr(f->f_dentry, list, size);
++	fput(f);
++	return error;
++}
++
++/*
++ * Extended attribute REMOVE operations
++ */
++static long
++removexattr(struct dentry *d, char *name)
++{
++	int error;
++	char kname[XATTR_NAME_MAX + 1];
++
++	error = strncpy_from_user(kname, name, sizeof(kname));
++	if (error == 0 || error == sizeof(kname))
++		error = -ERANGE;
++	if (error < 0)
++		return error;
++
++	error = -EOPNOTSUPP;
++	if (d->d_inode->i_op && d->d_inode->i_op->removexattr) {
++		down(&d->d_inode->i_sem);
++		lock_kernel();
++		error = d->d_inode->i_op->removexattr(d, kname);
++		unlock_kernel();
++		up(&d->d_inode->i_sem);
++	}
++	return error;
++}
++
++asmlinkage long
++sys_removexattr(char *path, char *name)
++{
++	struct nameidata nd;
++	int error;
++
++	error = user_path_walk(path, &nd);
++	if (error)
++		return error;
++	error = removexattr(nd.dentry, name);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage long
++sys_lremovexattr(char *path, char *name)
++{
++	struct nameidata nd;
++	int error;
++
++	error = user_path_walk_link(path, &nd);
++	if (error)
++		return error;
++	error = removexattr(nd.dentry, name);
++	path_release(&nd);
++	return error;
++}
++
++asmlinkage long
++sys_fremovexattr(int fd, char *name)
++{
++	struct file *f;
++	int error = -EBADF;
++
++	f = fget(fd);
++	if (!f)
++		return error;
++	error = removexattr(f->f_dentry, name);
++	fput(f);
++	return error;
++}
+Index: linux-2.4.19-pre1/include/linux/kernel.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/kernel.h	2003-11-21 02:25:34.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/kernel.h	2003-11-21 03:51:05.000000000 +0300
+@@ -11,6 +11,7 @@
+ #include <linux/linkage.h>
+ #include <linux/stddef.h>
+ #include <linux/types.h>
++#include <linux/compiler.h>
+ 
+ /* Optimization barrier */
+ /* The "volatile" is due to gcc bugs */
diff --git a/lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-suse.patch b/lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..26d3af93664cffee58f0f43204cffd1fbd72d2af
--- /dev/null
+++ b/lustre/kernel_patches/patches/linux-2.4.19-xattr-0.8.54-suse.patch
@@ -0,0 +1,47 @@
+ ext2/super.c        |    3 +--
+ ext3/ext3-exports.c |   13 +++++++++++++
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+Index: linux-2.4.19.SuSE/fs/ext2/super.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext2/super.c	Mon Jan 27 05:08:00 2003
++++ linux-2.4.19.SuSE/fs/ext2/super.c	Sun Nov 16 00:40:59 2003
+@@ -70,6 +70,7 @@
+ {
+ 	va_list args;
+ 
++	ext2_xattr_put_super(sb);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
+ 		sb->u.ext2_sb.s_es->s_state =
+Index: linux-2.4.19.SuSE/fs/ext3/super.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/super.c	Mon Jan 27 05:08:00 2003
++++ linux-2.4.19.SuSE/fs/ext3/super.c	Sun Nov 16 00:40:59 2003
+@@ -1822,8 +1828,6 @@
+ 	exit_ext3_xattr();
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+ 
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+Index: linux-2.4.19.SuSE/fs/ext3/ext3-exports.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/ext3/ext3-exports.c	Sun Nov 16 00:40:58 2003
++++ linux-2.4.19.SuSE/fs/ext3/ext3-exports.c	Sun Nov 16 00:40:59 2003
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch
index 6d8eac662275fe3c9abf38ef88a578fe559ebe73..8c4da0b2925f5ee201a7be6005423215e146bee6 100644
--- a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch
+++ b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-chaos.patch
@@ -2248,7 +2248,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
 +			      value, size, flags);
 +}
@@ -3921,7 +3921,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 +	if (IS_ERR(handle))
 +		return PTR_ERR(handle);
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch
index f0f92e5cbb897e1ce1437aaa80b803dff91d42bf..ad36c0f031860f070ce04552961dd58341363e9b 100644
--- a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch
+++ b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54-hp.patch
@@ -1,24 +1,5 @@
  Documentation/Configure.help  |   66 ++
- arch/alpha/defconfig          |    7 
- arch/alpha/kernel/entry.S     |   12 
- arch/arm/defconfig            |    7 
- arch/arm/kernel/calls.S       |   24 
- arch/i386/defconfig           |    7 
  arch/ia64/defconfig           |    7 
- arch/m68k/defconfig           |    7 
- arch/mips/defconfig           |    7 
- arch/mips64/defconfig         |    7 
- arch/ppc/defconfig            |   14 
- arch/ppc64/kernel/misc.S      |    2 
- arch/s390/defconfig           |    7 
- arch/s390/kernel/entry.S      |   24 
- arch/s390x/defconfig          |    7 
- arch/s390x/kernel/entry.S     |   24 
- arch/s390x/kernel/wrapper32.S |   92 +++
- arch/sparc/defconfig          |    7 
- arch/sparc/kernel/systbls.S   |   10 
- arch/sparc64/defconfig        |    7 
- arch/sparc64/kernel/systbls.S |   20 
  fs/Config.in                  |   14 
  fs/Makefile                   |    3 
  fs/ext2/Makefile              |    4 
@@ -43,12 +24,6 @@
  fs/jfs/jfs_xattr.h            |    6 
  fs/jfs/xattr.c                |    6 
  fs/mbcache.c                  |  648 ++++++++++++++++++++++
- include/asm-arm/unistd.h      |    2 
- include/asm-ppc64/unistd.h    |    2 
- include/asm-s390/unistd.h     |   15 
- include/asm-s390x/unistd.h    |   15 
- include/asm-sparc/unistd.h    |   24 
- include/asm-sparc64/unistd.h  |   24 
  include/linux/cache_def.h     |   15 
  include/linux/errno.h         |    4 
  include/linux/ext2_fs.h       |   31 -
@@ -144,108 +119,6 @@
  Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
  CONFIG_JBD
    This is a generic journalling layer for block devices.  It is
---- linux/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/alpha/defconfig	Fri May 16 08:43:00 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ALPHA=y
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
---- linux/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:42 2002
-+++ linux-mmonroe/arch/alpha/kernel/entry.S	Fri May 16 08:43:00 2003
-@@ -1154,6 +1154,18 @@ sys_call_table:
- 	.quad sys_readahead
- 	.quad sys_ni_syscall			/* 380, sys_security */
- 	.quad sys_tkill
-+	.quad sys_setxattr
-+	.quad sys_lsetxattr
-+	.quad sys_fsetxattr
-+	.quad sys_getxattr			/* 385 */
-+	.quad sys_lgetxattr
-+	.quad sys_fgetxattr
-+	.quad sys_listxattr
-+	.quad sys_llistxattr
-+	.quad sys_flistxattr			/* 390 */
-+	.quad sys_removexattr
-+	.quad sys_lremovexattr
-+	.quad sys_fremovexattr
- 
- /* Remember to update everything, kids.  */
- .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
---- linux/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/arm/defconfig	Fri May 16 08:43:00 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_ARM=y
- # CONFIG_EISA is not set
- # CONFIG_SBUS is not set
---- linux/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:42 2002
-+++ linux-mmonroe/arch/arm/kernel/calls.S	Fri May 16 08:43:00 2003
-@@ -240,18 +240,18 @@ __syscall_start:
- 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
- 		.long	SYMBOL_NAME(sys_gettid)
- /* 225 */	.long	SYMBOL_NAME(sys_readahead)
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
--/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
--/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
--		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
-+		.long	SYMBOL_NAME(sys_setxattr)
-+		.long	SYMBOL_NAME(sys_lsetxattr)
-+		.long	SYMBOL_NAME(sys_fsetxattr)
-+		.long	SYMBOL_NAME(sys_getxattr)
-+/* 230 */	.long	SYMBOL_NAME(sys_lgetxattr)
-+		.long	SYMBOL_NAME(sys_fgetxattr)
-+		.long	SYMBOL_NAME(sys_listxattr)
-+		.long	SYMBOL_NAME(sys_llistxattr)
-+		.long	SYMBOL_NAME(sys_flistxattr)
-+/* 235 */	.long	SYMBOL_NAME(sys_removexattr)
-+		.long	SYMBOL_NAME(sys_lremovexattr)
-+		.long	SYMBOL_NAME(sys_fremovexattr)
- 		.long	SYMBOL_NAME(sys_tkill)
- 		/*
- 		 * Please check 2.5 _before_ adding calls here,
---- linux/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/i386/defconfig	Fri May 16 08:43:00 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_X86=y
- CONFIG_ISA=y
- # CONFIG_SBUS is not set
 --- linux/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
 +++ linux-mmonroe/arch/ia64/defconfig	Fri May 16 08:43:00 2003
 @@ -1,6 +1,13 @@
@@ -262,378 +135,6 @@
  
  #
  # Code maturity level options
---- linux/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/m68k/defconfig	Fri May 16 08:43:00 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- 
- #
---- linux/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/mips/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- CONFIG_MIPS32=y
- # CONFIG_MIPS64 is not set
---- linux/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/mips64/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_MIPS=y
- # CONFIG_MIPS32 is not set
- CONFIG_MIPS64=y
---- linux/arch/ppc/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/ppc/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,20 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_UID16 is not set
- # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
- CONFIG_RWSEM_XCHGADD_ALGORITHM=y
---- linux/arch/ppc64/kernel/misc.S~linux-2.4.20-xattr-0.8.54-hp	Thu Nov 28 15:53:11 2002
-+++ linux-mmonroe/arch/ppc64/kernel/misc.S	Fri May 16 08:43:01 2003
-@@ -731,6 +731,7 @@ _GLOBAL(sys_call_table32)
- 	.llong .sys_gettid		/* 207 */
- #if 0 /* Reserved syscalls */
- 	.llong .sys_tkill		/* 208 */
-+#endif
- 	.llong .sys_setxattr
- 	.llong .sys_lsetxattr	/* 210 */
- 	.llong .sys_fsetxattr
-@@ -743,6 +744,7 @@ _GLOBAL(sys_call_table32)
- 	.llong .sys_removexattr
- 	.llong .sys_lremovexattr
- 	.llong .sys_fremovexattr	/* 220 */
-+#if 0 /* Reserved syscalls */
- 	.llong .sys_futex
- #endif
- 	.llong .sys_perfmonctl   /* Put this here for now ... */
---- linux/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/s390/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp	Thu Nov 28 15:53:11 2002
-+++ linux-mmonroe/arch/s390/kernel/entry.S	Fri May 16 08:43:01 2003
-@@ -558,18 +558,18 @@ sys_call_table:
-         .long  sys_fcntl64 
- 	.long  sys_ni_syscall
- 	.long  sys_ni_syscall
--	.long  sys_ni_syscall		 /* 224 - reserved for setxattr  */
--	.long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
--	.long  sys_ni_syscall		 /* 226 - reserved for fsetxattr */
--	.long  sys_ni_syscall		 /* 227 - reserved for getxattr  */
--	.long  sys_ni_syscall		 /* 228 - reserved for lgetxattr */
--	.long  sys_ni_syscall		 /* 229 - reserved for fgetxattr */
--	.long  sys_ni_syscall		 /* 230 - reserved for listxattr */
--	.long  sys_ni_syscall		 /* 231 - reserved for llistxattr */
--	.long  sys_ni_syscall		 /* 232 - reserved for flistxattr */
--	.long  sys_ni_syscall		 /* 233 - reserved for removexattr */
--	.long  sys_ni_syscall		 /* 234 - reserved for lremovexattr */
--	.long  sys_ni_syscall		 /* 235 - reserved for fremovexattr */
-+	.long  sys_setxattr
-+	.long  sys_lsetxattr		/* 225 */
-+	.long  sys_fsetxattr
-+	.long  sys_getxattr
-+	.long  sys_lgetxattr
-+	.long  sys_fgetxattr
-+	.long  sys_listxattr		/* 230 */
-+	.long  sys_llistxattr
-+	.long  sys_flistxattr
-+	.long  sys_removexattr
-+	.long  sys_lremovexattr
-+	.long  sys_fremovexattr		/* 235 */
- 	.long  sys_gettid
- 	.long  sys_tkill
- 	.rept  255-237
---- linux/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/s390x/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- # CONFIG_ISA is not set
- # CONFIG_EISA is not set
- # CONFIG_MCA is not set
---- linux/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54-hp	Thu Nov 28 15:53:11 2002
-+++ linux-mmonroe/arch/s390x/kernel/entry.S	Fri May 16 08:43:01 2003
-@@ -591,18 +591,18 @@ sys_call_table:
- 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
- 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
- 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
--	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
-+	.long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
-+	.long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)	/* 225 */
-+	.long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
-+	.long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
-+	.long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
-+	.long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
-+	.long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)	/* 230 */
-+	.long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
-+	.long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
-+	.long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
-+	.long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
-+	.long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
- 	.long  SYSCALL(sys_gettid,sys_gettid)
- 	.long  SYSCALL(sys_tkill,sys_tkill)
- 	.rept  255-237
---- linux/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54-hp	Mon Feb 25 11:37:56 2002
-+++ linux-mmonroe/arch/s390x/kernel/wrapper32.S	Fri May 16 08:43:01 2003
-@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
- 	llgtr	%r3,%r3			# struct stat64 *
- 	llgfr	%r4,%r4			# long
- 	jg	sys32_fstat64		# branch to system call
-+
-+	.globl	sys32_setxattr_wrapper
-+sys32_setxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	lgfr	%r6,%r6			# int
-+	jg	sys_setxattr
-+
-+	.globl	sys32_lsetxattr_wrapper
-+sys32_lsetxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	lgfr	%r6,%r6			# int
-+	jg	sys_lsetxattr
-+
-+	.globl	sys32_fsetxattr_wrapper
-+sys32_fsetxattr_wrapper:
-+	lgfr	%r2,%r2			# int
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	lgfr	%r6,%r6			# int
-+	jg	sys_fsetxattr
-+
-+	.globl	sys32_getxattr_wrapper
-+sys32_getxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	jg	sys_getxattr
-+
-+	.globl	sys32_lgetxattr_wrapper
-+sys32_lgetxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	jg	sys_lgetxattr
-+
-+	.globl	sys32_fgetxattr_wrapper
-+sys32_fgetxattr_wrapper:
-+	lgfr	%r2,%r2			# int
-+	llgtr	%r3,%r3			# char *
-+	llgtr	%r4,%r4			# void *
-+	llgfr	%r5,%r5			# size_t
-+	jg	sys_fgetxattr
-+
-+	.globl	sys32_listxattr_wrapper
-+sys32_listxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgfr	%r4,%r4			# size_t
-+	jg	sys_listxattr
-+
-+	.globl	sys32_llistxattr_wrapper
-+sys32_llistxattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	llgfr	%r4,%r4			# size_t
-+	jg	sys_llistxattr
-+
-+	.globl	sys32_flistxattr_wrapper
-+sys32_flistxattr_wrapper:
-+	lgfr	%r2,%r2			# int
-+	llgtr	%r3,%r3			# char *
-+	llgfr	%r4,%r4			# size_t
-+	jg	sys_flistxattr
-+
-+	.globl	sys32_removexattr_wrapper
-+sys32_removexattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	jg	sys_removexattr
-+
-+	.globl	sys32_lremovexattr_wrapper
-+sys32_lremovexattr_wrapper:
-+	llgtr	%r2,%r2			# char *
-+	llgtr	%r3,%r3			# char *
-+	jg	sys_lremovexattr
-+
-+	.globl	sys32_fremovexattr_wrapper
-+sys32_fremovexattr_wrapper:
-+	lgfr	%r2,%r2			# int
-+	llgtr	%r3,%r3			# char *
-+	jg	sys_fremovexattr
-+
-+
---- linux/arch/sparc/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/sparc/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- CONFIG_UID16=y
- CONFIG_HIGHMEM=y
- 
---- linux/arch/sparc/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:43 2002
-+++ linux-mmonroe/arch/sparc/kernel/systbls.S	Fri May 16 08:43:01 2003
-@@ -51,11 +51,11 @@ sys_call_table:
- /*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- /*155*/	.long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/	.long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--/*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--/*175*/	.long sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
--/*185*/	.long sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sys_newuname
-+/*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/	.long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+/*175*/	.long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/	.long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-+/*185*/	.long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
- /*190*/	.long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- /*195*/	.long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
- /*200*/	.long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
---- linux/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/sparc64/defconfig	Fri May 16 08:43:01 2003
-@@ -1,6 +1,13 @@
- #
- # Automatically generated make config: don't edit
- #
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT3_FS_XATTR_SHARING is not set
-+# CONFIG_EXT3_FS_XATTR_USER is not set
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XATTR_SHARING is not set
-+# CONFIG_EXT2_FS_XATTR_USER is not set
-+# CONFIG_FS_MBCACHE is not set
- 
- #
- # Code maturity level options
---- linux/arch/sparc64/kernel/systbls.S~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
-+++ linux-mmonroe/arch/sparc64/kernel/systbls.S	Fri May 16 08:43:01 2003
-@@ -52,11 +52,11 @@ sys_call_table32:
- /*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- 	.word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
- /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
--	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
--/*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
--	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
--	.word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
-+/*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
-+	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-+	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/	.word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
- /*200*/	.word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-@@ -111,11 +111,11 @@ sys_call_table:
- /*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- 	.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
- /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
--	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
--/*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
--	.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
--/*180*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
--	.word sys_setpgid, sys_nis_syscall, sys_tkill, sys_nis_syscall, sparc64_newuname
-+	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_setxattr
-+/*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
-+	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-+/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-+	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
- /*190*/	.word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
- /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 --- linux/fs/Config.in~linux-2.4.20-xattr-0.8.54-hp	Fri May 16 08:39:14 2003
 +++ linux-mmonroe/fs/Config.in	Fri May 16 08:43:01 2003
 @@ -35,6 +35,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
@@ -2248,7 +1749,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
 +			      value, size, flags);
 +}
@@ -3920,7 +3421,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 +	if (IS_ERR(handle))
 +		return PTR_ERR(handle);
@@ -4662,168 +4163,6 @@
 +module_init(init_mbcache)
 +module_exit(exit_mbcache)
 +
---- linux/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-arm/unistd.h	Fri May 16 08:43:01 2003
-@@ -244,7 +244,6 @@
- #define __NR_security			(__NR_SYSCALL_BASE+223)
- #define __NR_gettid			(__NR_SYSCALL_BASE+224)
- #define __NR_readahead			(__NR_SYSCALL_BASE+225)
--#if 0 /* allocated in 2.5 */
- #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
- #define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
- #define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
-@@ -257,7 +256,6 @@
- #define __NR_removexattr		(__NR_SYSCALL_BASE+235)
- #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
- #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
--#endif
- #define __NR_tkill			(__NR_SYSCALL_BASE+238)
- /*
-  * Please check 2.5 _before_ adding calls here,
---- linux/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-ppc64/unistd.h	Fri May 16 08:43:01 2003
-@@ -218,6 +218,7 @@
- #define __NR_gettid		207
- #if 0 /* Reserved syscalls */
- #define __NR_tkill		208
-+#endif
- #define __NR_setxattr		209
- #define __NR_lsetxattr		210
- #define __NR_fsetxattr		211
-@@ -230,6 +231,7 @@
- #define __NR_removexattr	218
- #define __NR_lremovexattr	219
- #define __NR_fremovexattr	220
-+#if 0 /* Reserved syscalls */
- #define __NR_futex		221
- #endif
- 
---- linux/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-s390/unistd.h	Fri May 16 08:43:01 2003
-@@ -212,9 +212,18 @@
- #define __NR_madvise            219
- #define __NR_getdents64		220
- #define __NR_fcntl64		221
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr		224
-+#define __NR_lsetxattr		225
-+#define __NR_fsetxattr		226
-+#define __NR_getxattr		227
-+#define __NR_lgetxattr		228
-+#define __NR_fgetxattr		229
-+#define __NR_listxattr		230
-+#define __NR_llistxattr		231
-+#define __NR_flistxattr		232
-+#define __NR_removexattr	233
-+#define __NR_lremovexattr	234
-+#define __NR_fremovexattr	235
- #define __NR_gettid		236
- #define __NR_tkill		237
- 
---- linux/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-s390x/unistd.h	Fri May 16 08:43:01 2003
-@@ -180,9 +180,18 @@
- #define __NR_pivot_root         217
- #define __NR_mincore            218
- #define __NR_madvise            219
--/*
-- * Numbers 224-235 are reserved for posix acl
-- */
-+#define __NR_setxattr		224
-+#define __NR_lsetxattr		225
-+#define __NR_fsetxattr		226
-+#define __NR_getxattr		227
-+#define __NR_lgetxattr		228
-+#define __NR_fgetxattr		229
-+#define __NR_listxattr		230
-+#define __NR_llistxattr		231
-+#define __NR_flistxattr		232
-+#define __NR_removexattr	233
-+#define __NR_lremovexattr	234
-+#define __NR_fremovexattr	235
- #define __NR_gettid		236
- #define __NR_tkill		237
- 
---- linux/include/asm-sparc/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-sparc/unistd.h	Fri May 16 08:43:01 2003
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module	184 /* Linux Specific				   */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
---- linux/include/asm-sparc64/unistd.h~linux-2.4.20-xattr-0.8.54-hp	Fri Aug  2 17:39:45 2002
-+++ linux-mmonroe/include/asm-sparc64/unistd.h	Fri May 16 08:43:01 2003
-@@ -184,24 +184,24 @@
- /* #define __NR_exportfs        166    SunOS Specific                              */
- #define __NR_mount              167 /* Common                                      */
- #define __NR_ustat              168 /* Common                                      */
--/* #define __NR_semsys          169    SunOS Specific                              */
--/* #define __NR_msgsys          170    SunOS Specific                              */
--/* #define __NR_shmsys          171    SunOS Specific                              */
--/* #define __NR_auditsys        172    SunOS Specific                              */
--/* #define __NR_rfssys          173    SunOS Specific                              */
-+#define __NR_setxattr           169 /* SunOS: semsys                               */
-+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-+#define __NR_getxattr           172 /* SunOS: auditsys                             */
-+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
- #define __NR_getdents           174 /* Common                                      */
- #define __NR_setsid             175 /* Common                                      */
- #define __NR_fchdir             176 /* Common                                      */
--/* #define __NR_fchroot         177    SunOS Specific                              */
--/* #define __NR_vpixsys         178    SunOS Specific                              */
--/* #define __NR_aioread         179    SunOS Specific                              */
--/* #define __NR_aiowrite        180    SunOS Specific                              */
--/* #define __NR_aiowait         181    SunOS Specific                              */
--/* #define __NR_aiocancel       182    SunOS Specific                              */
-+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-+#define __NR_llistxattr         179 /* SunOS: aioread                              */
-+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-+#define __NR_removexattr        181 /* SunOS: aiowait                              */
-+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
- #define __NR_sigpending         183 /* Common                                      */
- #define __NR_query_module	184 /* Linux Specific				   */
- #define __NR_setpgid            185 /* Common                                      */
--/* #define __NR_pathconf        186    SunOS Specific                              */
-+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
- #define __NR_tkill              187 /* SunOS: fpathconf                            */
- /* #define __NR_sysconf         188    SunOS Specific                              */
- #define __NR_uname              189 /* Linux Specific                              */
 --- /dev/null	Mon May 20 21:11:23 2002
 +++ linux-mmonroe/include/linux/cache_def.h	Fri May 16 08:43:01 2003
 @@ -0,0 +1,15 @@
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch
index 1489989433ae1785f9545899732bb80c06be69c5..152e89a3fa1e1f1accddd0123edbd0c17142dffc 100644
--- a/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch
+++ b/lustre/kernel_patches/patches/linux-2.4.20-xattr-0.8.54.patch
@@ -2283,7 +2283,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
 +			      value, size, flags);
 +}
@@ -3956,7 +3956,7 @@
 +#endif
 +	if (error)
 +		return error;
-+  
++
 +	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 +	if (IS_ERR(handle))
 +		return PTR_ERR(handle);
diff --git a/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch b/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9318fc1c967baf34521c7ebeed9dbb8c06893213
--- /dev/null
+++ b/lustre/kernel_patches/patches/linux-2.4.21-xattr-0.8.54-suse.patch
@@ -0,0 +1,5349 @@
+ Documentation/Configure.help  |   66 ++
+ arch/alpha/defconfig          |    7 
+ arch/alpha/kernel/entry.S     |   12 
+ arch/arm/defconfig            |    7 
+ arch/arm/kernel/calls.S       |   24 
+ arch/i386/defconfig           |    7 
+ arch/ia64/defconfig           |    7 
+ arch/ia64/kernel/entry.S      |   24 
+ arch/m68k/defconfig           |    7 
+ arch/mips/defconfig           |    7 
+ arch/mips64/defconfig         |    7 
+ arch/ppc/defconfig            |   14 
+ arch/ppc64/kernel/misc.S      |    2 
+ arch/s390/defconfig           |    7 
+ arch/s390/kernel/entry.S      |   24 
+ arch/s390x/defconfig          |    7 
+ arch/s390x/kernel/entry.S     |   24 
+ arch/s390x/kernel/wrapper32.S |   92 +++
+ arch/sparc/defconfig          |    7 
+ arch/sparc/kernel/systbls.S   |   10 
+ arch/sparc64/defconfig        |    7 
+ arch/sparc64/kernel/systbls.S |   20 
+ fs/Config.in                  |   14 
+ fs/Makefile                   |    3 
+ fs/ext2/Makefile              |    4 
+ fs/ext2/file.c                |    5 
+ fs/ext2/ialloc.c              |    2 
+ fs/ext2/inode.c               |   34 -
+ fs/ext2/namei.c               |   14 
+ fs/ext2/super.c               |   29 
+ fs/ext2/symlink.c             |   14 
+ fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
+ fs/ext2/xattr_user.c          |  103 +++
+ fs/ext3/Makefile              |   10 
+ fs/ext3/file.c                |    5 
+ fs/ext3/ialloc.c              |    2 
+ fs/ext3/inode.c               |   35 -
+ fs/ext3/namei.c               |   21 
+ fs/ext3/super.c               |   36 +
+ fs/ext3/symlink.c             |   14 
+ fs/ext3/xattr.c               | 1225 ++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/xattr_user.c          |  111 +++
+ fs/jfs/jfs_xattr.h            |    6 
+ fs/jfs/xattr.c                |    6 
+ fs/mbcache.c                  |  648 ++++++++++++++++++++++
+ include/asm-arm/unistd.h      |    2 
+ include/asm-ia64/unistd.h     |   13 
+ include/asm-ppc64/unistd.h    |    2 
+ include/asm-s390/unistd.h     |   15 
+ include/asm-s390x/unistd.h    |   15 
+ include/asm-sparc/unistd.h    |   24 
+ include/asm-sparc64/unistd.h  |   24 
+ include/linux/cache_def.h     |   15 
+ include/linux/errno.h         |    4 
+ include/linux/ext2_fs.h       |   31 -
+ include/linux/ext2_xattr.h    |  157 +++++
+ include/linux/ext3_fs.h       |   31 -
+ include/linux/ext3_jbd.h      |    8 
+ include/linux/ext3_xattr.h    |  157 +++++
+ include/linux/fs.h            |    2 
+ include/linux/mbcache.h       |   69 ++
+ kernel/ksyms.c                |    4 
+ mm/vmscan.c                   |   35 +
+ fs/ext3/ext3-exports.c        |   14 +  
+ 64 files changed, 4355 insertions(+), 195 deletions(-)
+
+--- linux-2.4.20/Documentation/Configure.help~linux-2.4.20-xattr-0.8.54	2003-05-05 17:43:06.000000000 +0800
++++ linux-2.4.20-root/Documentation/Configure.help	2003-05-07 18:08:03.000000000 +0800
+@@ -15242,6 +15242,39 @@ CONFIG_EXT2_FS
+   be compiled as a module, and so this could be dangerous.  Most
+   everyone wants to say Y here.
+ 
++Ext2 extended attributes
++CONFIG_EXT2_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 extended attribute block sharing
++CONFIG_EXT2_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext2 extended user attributes
++CONFIG_EXT2_FS_XATTR_USER
++  This option enables extended user attributes on ext2. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 trusted extended attributes
++CONFIG_EXT2_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext2 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Ext3 journalling file system support (EXPERIMENTAL)
+ CONFIG_EXT3_FS
+   This is the journalling version of the Second extended file system
+@@ -15274,6 +15307,39 @@ CONFIG_EXT3_FS
+   of your root partition (the one containing the directory /) cannot
+   be compiled as a module, and so this may be dangerous.
+ 
++Ext3 extended attributes
++CONFIG_EXT3_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 extended attribute block sharing
++CONFIG_EXT3_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext3 extended user attributes
++CONFIG_EXT3_FS_XATTR_USER
++  This option enables extended user attributes on ext3. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 trusted extended attributes
++CONFIG_EXT3_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext3 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
+ CONFIG_JBD
+   This is a generic journalling layer for block devices.  It is
+--- linux-2.4.20/arch/alpha/defconfig~linux-2.4.20-xattr-0.8.54	2001-11-20 07:19:42.000000000 +0800
++++ linux-2.4.20-root/arch/alpha/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ALPHA=y
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+--- linux-2.4.20/arch/alpha/kernel/entry.S~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:42.000000000 +0800
++++ linux-2.4.20-root/arch/alpha/kernel/entry.S	2003-05-07 18:08:03.000000000 +0800
+@@ -1154,6 +1154,18 @@ sys_call_table:
+ 	.quad sys_readahead
+ 	.quad sys_ni_syscall			/* 380, sys_security */
+ 	.quad sys_tkill
++	.quad sys_setxattr
++	.quad sys_lsetxattr
++	.quad sys_fsetxattr
++	.quad sys_getxattr			/* 385 */
++	.quad sys_lgetxattr
++	.quad sys_fgetxattr
++	.quad sys_listxattr
++	.quad sys_llistxattr
++	.quad sys_flistxattr			/* 390 */
++	.quad sys_removexattr
++	.quad sys_lremovexattr
++	.quad sys_fremovexattr
+ 
+ /* Remember to update everything, kids.  */
+ .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
+--- linux-2.4.20/arch/arm/defconfig~linux-2.4.20-xattr-0.8.54	2001-05-20 08:43:05.000000000 +0800
++++ linux-2.4.20-root/arch/arm/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ARM=y
+ # CONFIG_EISA is not set
+ # CONFIG_SBUS is not set
+--- linux-2.4.20/arch/arm/kernel/calls.S~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:42.000000000 +0800
++++ linux-2.4.20-root/arch/arm/kernel/calls.S	2003-05-07 18:08:03.000000000 +0800
+@@ -240,18 +240,18 @@ __syscall_start:
+ 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
+ 		.long	SYMBOL_NAME(sys_gettid)
+ /* 225 */	.long	SYMBOL_NAME(sys_readahead)
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
+-/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
+-/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
++		.long	SYMBOL_NAME(sys_setxattr)
++		.long	SYMBOL_NAME(sys_lsetxattr)
++		.long	SYMBOL_NAME(sys_fsetxattr)
++		.long	SYMBOL_NAME(sys_getxattr)
++/* 230 */	.long	SYMBOL_NAME(sys_lgetxattr)
++		.long	SYMBOL_NAME(sys_fgetxattr)
++		.long	SYMBOL_NAME(sys_listxattr)
++		.long	SYMBOL_NAME(sys_llistxattr)
++		.long	SYMBOL_NAME(sys_flistxattr)
++/* 235 */	.long	SYMBOL_NAME(sys_removexattr)
++		.long	SYMBOL_NAME(sys_lremovexattr)
++		.long	SYMBOL_NAME(sys_fremovexattr)
+ 		.long	SYMBOL_NAME(sys_tkill)
+ 		/*
+ 		 * Please check 2.5 _before_ adding calls here,
+--- linux-2.4.20/arch/i386/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:09.000000000 +0800
++++ linux-2.4.20-root/arch/i386/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+--- linux-2.4.20/arch/ia64/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:09.000000000 +0800
++++ linux-2.4.20-root/arch/ia64/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+--- linux-2.4.20/arch/m68k/defconfig~linux-2.4.20-xattr-0.8.54	2000-06-20 03:56:08.000000000 +0800
++++ linux-2.4.20-root/arch/m68k/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ 
+ #
+--- linux-2.4.20/arch/mips/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:10.000000000 +0800
++++ linux-2.4.20-root/arch/mips/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ CONFIG_MIPS32=y
+ # CONFIG_MIPS64 is not set
+--- linux-2.4.20/arch/mips64/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:10.000000000 +0800
++++ linux-2.4.20-root/arch/mips64/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ # CONFIG_MIPS32 is not set
+ CONFIG_MIPS64=y
+--- linux-2.4.20/arch/s390/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:11.000000000 +0800
++++ linux-2.4.20-root/arch/s390/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+--- linux-2.4.20/arch/s390/kernel/entry.S~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:11.000000000 +0800
++++ linux-2.4.20-root/arch/s390/kernel/entry.S	2003-05-07 18:08:03.000000000 +0800
+@@ -558,18 +558,18 @@ sys_call_table:
+         .long  sys_fcntl64 
+ 	.long  sys_ni_syscall
+ 	.long  sys_ni_syscall
+-	.long  sys_ni_syscall		 /* 224 - reserved for setxattr  */
+-	.long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
+-	.long  sys_ni_syscall		 /* 226 - reserved for fsetxattr */
+-	.long  sys_ni_syscall		 /* 227 - reserved for getxattr  */
+-	.long  sys_ni_syscall		 /* 228 - reserved for lgetxattr */
+-	.long  sys_ni_syscall		 /* 229 - reserved for fgetxattr */
+-	.long  sys_ni_syscall		 /* 230 - reserved for listxattr */
+-	.long  sys_ni_syscall		 /* 231 - reserved for llistxattr */
+-	.long  sys_ni_syscall		 /* 232 - reserved for flistxattr */
+-	.long  sys_ni_syscall		 /* 233 - reserved for removexattr */
+-	.long  sys_ni_syscall		 /* 234 - reserved for lremovexattr */
+-	.long  sys_ni_syscall		 /* 235 - reserved for fremovexattr */
++	.long  sys_setxattr
++	.long  sys_lsetxattr		/* 225 */
++	.long  sys_fsetxattr
++	.long  sys_getxattr
++	.long  sys_lgetxattr
++	.long  sys_fgetxattr
++	.long  sys_listxattr		/* 230 */
++	.long  sys_llistxattr
++	.long  sys_flistxattr
++	.long  sys_removexattr
++	.long  sys_lremovexattr
++	.long  sys_fremovexattr		/* 235 */
+ 	.long  sys_gettid
+ 	.long  sys_tkill
+ 	.rept  255-237
+--- linux-2.4.20/arch/s390x/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:11.000000000 +0800
++++ linux-2.4.20-root/arch/s390x/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+--- linux-2.4.20/arch/s390x/kernel/entry.S~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:11.000000000 +0800
++++ linux-2.4.20-root/arch/s390x/kernel/entry.S	2003-05-07 18:08:03.000000000 +0800
+@@ -591,18 +591,18 @@ sys_call_table:
+ 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
++	.long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
++	.long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)	/* 225 */
++	.long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
++	.long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
++	.long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
++	.long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
++	.long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)	/* 230 */
++	.long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
++	.long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
++	.long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
++	.long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
++	.long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
+ 	.long  SYSCALL(sys_gettid,sys_gettid)
+ 	.long  SYSCALL(sys_tkill,sys_tkill)
+ 	.rept  255-237
+--- linux-2.4.20/arch/s390x/kernel/wrapper32.S~linux-2.4.20-xattr-0.8.54	2002-02-26 03:37:56.000000000 +0800
++++ linux-2.4.20-root/arch/s390x/kernel/wrapper32.S	2003-05-07 18:08:03.000000000 +0800
+@@ -1091,3 +1091,95 @@ sys32_fstat64_wrapper:
+ 	llgtr	%r3,%r3			# struct stat64 *
+ 	llgfr	%r4,%r4			# long
+ 	jg	sys32_fstat64		# branch to system call
++
++	.globl	sys32_setxattr_wrapper
++sys32_setxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_setxattr
++
++	.globl	sys32_lsetxattr_wrapper
++sys32_lsetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_lsetxattr
++
++	.globl	sys32_fsetxattr_wrapper
++sys32_fsetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_fsetxattr
++
++	.globl	sys32_getxattr_wrapper
++sys32_getxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_getxattr
++
++	.globl	sys32_lgetxattr_wrapper
++sys32_lgetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_lgetxattr
++
++	.globl	sys32_fgetxattr_wrapper
++sys32_fgetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_fgetxattr
++
++	.globl	sys32_listxattr_wrapper
++sys32_listxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_listxattr
++
++	.globl	sys32_llistxattr_wrapper
++sys32_llistxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_llistxattr
++
++	.globl	sys32_flistxattr_wrapper
++sys32_flistxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_flistxattr
++
++	.globl	sys32_removexattr_wrapper
++sys32_removexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_removexattr
++
++	.globl	sys32_lremovexattr_wrapper
++sys32_lremovexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_lremovexattr
++
++	.globl	sys32_fremovexattr_wrapper
++sys32_fremovexattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	jg	sys_fremovexattr
++
++
+--- linux-2.4.20/arch/sparc64/defconfig~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:12.000000000 +0800
++++ linux-2.4.20-root/arch/sparc64/defconfig	2003-05-07 18:08:03.000000000 +0800
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+--- linux-2.4.20/fs/Config.in~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/Config.in	2003-05-07 18:08:03.000000000 +0800
+@@ -25,6 +25,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
+ dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
+ 
+ tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
++dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
++dep_bool '    Ext3 extended attribute block sharing' \
++    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
++dep_bool '    Ext3 extended user attributes' \
++    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
+ # CONFIG_JBD could be its own option (even modular), but until there are
+ # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
+ # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
+@@ -84,6 +89,11 @@ dep_mbool '  QNX4FS write support (DANGE
+ tristate 'ROM file system support' CONFIG_ROMFS_FS
+ 
+ tristate 'Second extended fs support' CONFIG_EXT2_FS
++dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
++dep_bool '    Ext2 extended attribute block sharing' \
++    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
++dep_bool '    Ext2 extended user attributes' \
++    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
+ 
+ tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
+ 
+@@ -155,6 +165,10 @@ else
+    define_tristate CONFIG_ZISOFS_FS n
+ fi
+ 
++# Meta block cache for Extended Attributes (ext2/ext3)
++#tristate 'Meta block cache' CONFIG_FS_MBCACHE
++define_tristate CONFIG_FS_MBCACHE y 
++
+ mainmenu_option next_comment
+ comment 'Partition Types'
+ source fs/partitions/Config.in
+--- linux-2.4.20/fs/Makefile~linux-2.4.20-xattr-0.8.54	2003-05-05 19:00:58.000000000 +0800
++++ linux-2.4.20-root/fs/Makefile	2003-05-07 18:08:03.000000000 +0800
+@@ -79,6 +79,9 @@ obj-y				+= binfmt_script.o
+ 
+ obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+ 
++export-objs += mbcache.o
++obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
++
+ # persistent filesystems
+ obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+ 
+--- linux-2.4.20/fs/ext2/Makefile~linux-2.4.20-xattr-0.8.54	2001-10-11 23:05:18.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/Makefile	2003-05-07 18:08:03.000000000 +0800
+@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.20/fs/ext2/file.c~linux-2.4.20-xattr-0.8.54	2001-10-11 23:05:18.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/file.c	2003-05-07 18:08:03.000000000 +0800
+@@ -20,6 +20,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/sched.h>
+ 
+ /*
+@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
+ 
+ struct inode_operations ext2_file_inode_operations = {
+ 	truncate:	ext2_truncate,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- linux-2.4.20/fs/ext2/ialloc.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/ialloc.c	2003-05-07 18:08:03.000000000 +0800
+@@ -15,6 +15,7 @@
+ #include <linux/config.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ 
+@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
+ 	 */
+ 	if (!is_bad_inode(inode)) {
+ 		/* Quota is already initialized in iput() */
++		ext2_xattr_delete_inode(inode);
+ 	    	DQUOT_FREE_INODE(inode);
+ 		DQUOT_DROP(inode);
+ 	}
+--- linux-2.4.20/fs/ext2/inode.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/inode.c	2003-05-07 18:08:03.000000000 +0800
+@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
+ static int ext2_update_inode(struct inode * inode, int do_sync);
+ 
+ /*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext2_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext2_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
++/*
+  * Called at each iput()
+  */
+ void ext2_put_inode (struct inode * inode)
+@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
+ {
+ 	lock_kernel();
+ 
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
+ 	mark_inode_dirty(inode);
+@@ -801,6 +811,8 @@ void ext2_truncate (struct inode * inode
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext2_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -888,8 +900,7 @@ void ext2_read_inode (struct inode * ino
+ 	unsigned long offset;
+ 	struct ext2_group_desc * gdp;
+ 
+-	if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
+-	     inode->i_ino != EXT2_ACL_DATA_INO &&
++	if ((inode->i_ino != EXT2_ROOT_INO &&
+ 	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
+ 	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
+ 		ext2_error (inode->i_sb, "ext2_read_inode",
+@@ -974,10 +985,7 @@ void ext2_read_inode (struct inode * ino
+ 	for (block = 0; block < EXT2_N_BLOCKS; block++)
+ 		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
+ 
+-	if (inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext2_file_inode_operations;
+ 		inode->i_fop = &ext2_file_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+@@ -986,15 +994,17 @@ void ext2_read_inode (struct inode * ino
+ 		inode->i_fop = &ext2_dir_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext2_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext2_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext2_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext2_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext2_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(raw_inode->i_block[0]));
++	}
+ 	brelse (bh);
+ 	inode->i_attr_flags = 0;
+ 	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
+--- linux-2.4.20/fs/ext2/namei.c~linux-2.4.20-xattr-0.8.54	2001-10-04 13:57:36.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/namei.c	2003-05-07 18:08:03.000000000 +0800
+@@ -31,6 +31,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/pagemap.h>
+ 
+ /*
+@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
+ 
+ 	if (l > sizeof (inode->u.ext2_i.i_data)) {
+ 		/* slow symlink */
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext2_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 		err = block_symlink(inode, symname, l);
+ 		if (err)
+@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
+ 	rmdir:		ext2_rmdir,
+ 	mknod:		ext2_mknod,
+ 	rename:		ext2_rename,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
++struct inode_operations ext2_special_inode_operations = {
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- linux-2.4.20/fs/ext2/super.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/super.c	2003-05-07 18:08:03.000000000 +0800
+@@ -21,6 +21,7 @@
+ #include <linux/string.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
+ 	int db_count;
+ 	int i;
+ 
++	ext2_xattr_put_super(sb);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+ 
+@@ -175,6 +177,13 @@ static int parse_options (char * options
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
+ 	    blocksize = BLOCK_SIZE;
+ 
+ 	sb->u.ext2_sb.s_mount_opt = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++	/* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
++#endif
+ 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
+ 	    &sb->u.ext2_sb.s_mount_opt)) {
+ 		return NULL;
+@@ -813,12 +825,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
+ 
+ static int __init init_ext2_fs(void)
+ {
+-        return register_filesystem(&ext2_fs_type);
++	int error = init_ext2_xattr();
++	if (error)
++		return error;
++	error = init_ext2_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext2_fs_type);
++	if (!error)
++		return 0;
++
++	exit_ext2_xattr_user();
++fail:
++	exit_ext2_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext2_fs(void)
+ {
+ 	unregister_filesystem(&ext2_fs_type);
++	exit_ext2_xattr_user();
++	exit_ext2_xattr();
+ }
+ 
+ EXPORT_NO_SYMBOLS;
+--- linux-2.4.20/fs/ext2/symlink.c~linux-2.4.20-xattr-0.8.54	2000-09-28 04:41:33.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/symlink.c	2003-05-07 18:08:03.000000000 +0800
+@@ -19,6 +19,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ 
+ static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext2_symlink_inode_operations = {
++	readlink:	page_readlink,
++	follow_link:	page_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
+ struct inode_operations ext2_fast_symlink_inode_operations = {
+ 	readlink:	ext2_readlink,
+ 	follow_link:	ext2_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/xattr.c	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,1212 @@
++/*
++ * linux/fs/ext2/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT2_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++/* These symbols may be needed by a module. */
++EXPORT_SYMBOL(ext2_xattr_register);
++EXPORT_SYMBOL(ext2_xattr_unregister);
++EXPORT_SYMBOL(ext2_xattr_get);
++EXPORT_SYMBOL(ext2_xattr_list);
++EXPORT_SYMBOL(ext2_xattr_set);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT2_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext2_xattr_set2(struct inode *, struct buffer_head *,
++			   struct ext2_xattr_header *);
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++static int ext2_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext2_xattr_cache_find(struct inode *,
++						 struct ext2_xattr_header *);
++static void ext2_xattr_cache_remove(struct buffer_head *);
++static void ext2_xattr_rehash(struct ext2_xattr_header *,
++			      struct ext2_xattr_entry *);
++
++static struct mb_cache *ext2_xattr_cache;
++
++#else
++# define ext2_xattr_cache_insert(bh) 0
++# define ext2_xattr_cache_find(inode, header) NULL
++# define ext2_xattr_cache_remove(bh) while(0) {}
++# define ext2_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext2_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext2_xattr_sem);
++
++static inline int
++ext2_xattr_new_block(struct inode *inode, int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
++		EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext2_new_block(inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext2_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext2_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext2_xattr_free_block(struct inode * inode, unsigned long block)
++{
++	ext2_free_blocks(inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext2_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext2_xattr_free_block(inode, block) \
++	ext2_free_blocks(inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
++rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		if (!ext2_xattr_handlers[name_index-1]) {
++			ext2_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext2_handler_lock);
++	}
++	return error;
++}
++
++void
++ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		ext2_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext2_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static struct ext2_xattr_handler *
++ext2_xattr_resolve_name(const char **name)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext2_handler_lock);
++	for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
++		if (ext2_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext2_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext2_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext2_handler_lock);
++	return handler;
++}
++
++static inline struct ext2_xattr_handler *
++ext2_xattr_handler(int name_index)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		read_lock(&ext2_handler_lock);
++		handler = ext2_xattr_handlers[name_index-1];
++		read_unlock(&ext2_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext2_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext2_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT2_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT2_I(inode)->i_file_acl)
++		return 0;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext2_xattr_update_super_block(struct super_block *sb)
++{
++	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT2_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext2_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_header *header = NULL;
++	struct ext2_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT2_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext2_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext2_error(sb, "ext2_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext2_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT2_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT2_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT2_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext2_xattr_cache_remove(bh);
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT2_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT2_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT2_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext2_xattr_set2(inode, bh, NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT2_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT2_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT2_XATTR_PAD, 0,
++			       EXT2_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext2_xattr_rehash(header, here);
++
++	error = ext2_xattr_set2(inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext2_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext2_xattr_set(): Update the file system.
++ */
++static int
++ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
++		struct ext2_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext2_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext2_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext2_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT2_I(inode)->i_file_acl != 0;
++			int block = ext2_xattr_new_block(inode, &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++				ext2_xattr_free_block(inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext2_xattr_cache_insert(new_bh);
++			
++			ext2_xattr_update_super_block(sb);
++		}
++		mark_buffer_dirty(new_bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &new_bh);
++			wait_on_buffer(new_bh); 
++			error = -EIO;
++			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
++				goto cleanup;
++		}
++	}
++
++	/* Update the inode. */
++	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	if (IS_SYNC(inode)) {
++		error = ext2_sync_inode (inode);
++		if (error)
++			goto cleanup;
++	} else
++		mark_inode_dirty(inode);
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext2_xattr_free_block(inode, old_bh->b_blocknr);
++			mark_buffer_clean(old_bh);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext2_xattr_quota_free(inode);
++			mark_buffer_dirty(old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT2_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext2_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext2_xattr_cache_remove(bh);
++		ext2_xattr_free_block(inode, block);
++		bforget(bh);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		mark_buffer_dirty(bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &bh);
++			wait_on_buffer(bh);
++		}
++		ext2_xattr_quota_free(inode);
++	}
++	EXT2_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext2_xattr_sem);
++}
++
++/*
++ * ext2_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext2_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++	mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++/*
++ * ext2_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext2_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext2_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext2_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext2_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext2_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext2_xattr_cmp(struct ext2_xattr_header *header1,
++	       struct ext2_xattr_header *header2)
++{
++	struct ext2_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT2_XATTR_NEXT(entry1);
++		entry2 = EXT2_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext2_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT2_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT2_XATTR_REFCOUNT_MAX);
++		} else if (!ext2_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext2_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext2_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
++					 struct ext2_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext2_xattr_rehash(struct ext2_xattr_header *header,
++			      struct ext2_xattr_entry *entry)
++{
++	struct ext2_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext2_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT2_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext2_xattr(void)
++{
++	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext2_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++	mb_cache_destroy(ext2_xattr_cache);
++}
++
++#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
++
++int __init
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/fs/ext2/xattr_user.c	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,103 @@
++/*
++ * linux/fs/ext2/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++# include <linux/ext2_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext2_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext2_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext2_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
++			      value, size, flags);
++}
++
++struct ext2_xattr_handler ext2_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext2_xattr_user_list,
++	get:	ext2_xattr_user_get,
++	set:	ext2_xattr_user_set,
++};
++
++int __init
++init_ext2_xattr_user(void)
++{
++	return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
++				   &ext2_xattr_user_handler);
++}
++
++void
++exit_ext2_xattr_user(void)
++{
++	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
++			      &ext2_xattr_user_handler);
++}
+--- linux-2.4.20/fs/ext3/Makefile~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:02.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/Makefile	2003-05-07 18:10:33.000000000 +0800
+@@ -1,5 +1,5 @@
+ #
+-# Makefile for the linux ext2-filesystem routines.
++# Makefile for the linux ext3-filesystem routines.
+ #
+ # Note! Dependencies are done automagically by 'make dep', which also
+ # removes any old dependencies. DON'T put your own dependencies here
+@@ -9,10 +9,14 @@
+ 
+ O_TARGET := ext3.o
+ 
+-export-objs :=	super.o inode.o
++export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o hash.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.20/fs/ext3/file.c~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:02.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/file.c	2003-05-07 18:08:03.000000000 +0800
+@@ -23,6 +23,7 @@
+ #include <linux/locks.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/smp_lock.h>
+ 
+@@ -126,5 +127,9 @@ struct file_operations ext3_file_operati
+ struct inode_operations ext3_file_inode_operations = {
+ 	truncate:	ext3_truncate,		/* BKL held */
+ 	setattr:	ext3_setattr,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+ 
+--- linux-2.4.20/fs/ext3/ialloc.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/ialloc.c	2003-05-07 18:08:03.000000000 +0800
+@@ -17,6 +17,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+ #include <linux/locks.h>
+@@ -216,6 +217,7 @@ void ext3_free_inode (handle_t *handle, 
+ 	 * as writing the quota to disk may need the lock as well.
+ 	 */
+ 	DQUOT_INIT(inode);
++	ext3_xattr_delete_inode(handle, inode);
+ 	DQUOT_FREE_INODE(inode);
+ 	DQUOT_DROP(inode);
+ 
+--- linux-2.4.20/fs/ext3/inode.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/inode.c	2003-05-07 18:08:03.000000000 +0800
+@@ -39,6 +39,18 @@
+  */
+ #undef SEARCH_FROM_ZERO
+ 
++/*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext3_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext3_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
+ /* The ext3 forget function must perform a revoke if we are freeing data
+  * which has been journaled.  Metadata (eg. indirect blocks) must be
+  * revoked in all cases. 
+@@ -48,7 +60,7 @@
+  * still needs to be revoked.
+  */
+ 
+-static int ext3_forget(handle_t *handle, int is_metadata,
++int ext3_forget(handle_t *handle, int is_metadata,
+ 		       struct inode *inode, struct buffer_head *bh,
+ 		       int blocknr)
+ {
+@@ -164,9 +176,7 @@ void ext3_delete_inode (struct inode * i
+ {
+ 	handle_t *handle;
+ 	
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 
+ 	lock_kernel();
+@@ -1855,6 +1865,8 @@ void ext3_truncate(struct inode * inode)
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext3_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -2002,8 +2014,6 @@ int ext3_get_inode_loc (struct inode *in
+ 	struct ext3_group_desc * gdp;
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+-		inode->i_ino != EXT3_ACL_IDX_INO &&
+-		inode->i_ino != EXT3_ACL_DATA_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+ 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+ 		inode->i_ino > le32_to_cpu(
+@@ -2130,10 +2140,7 @@ void ext3_read_inode(struct inode * inod
+ 
+ 	brelse (iloc.bh);
+ 
+-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+@@ -2141,15 +2148,17 @@ void ext3_read_inode(struct inode * inod
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext3_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext3_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext3_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
++	}
+ 	ext3_set_inode_flags(inode);
+ 	return;
+ 	
+--- linux-2.4.20/fs/ext3/namei.c~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:05.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/namei.c	2003-05-07 18:08:03.000000000 +0800
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/fcntl.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+@@ -1611,7 +1612,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR);
++	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1619,7 +1620,6 @@ static int ext3_mkdir(struct inode * dir
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+ 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+-	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+ 		inode->i_nlink--; /* is this nlink == 0? */
+@@ -1646,9 +1646,6 @@ static int ext3_mkdir(struct inode * dir
+ 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
+ 	ext3_journal_dirty_metadata(handle, dir_block);
+ 	brelse (dir_block);
+-	inode->i_mode = S_IFDIR | mode;
+-	if (dir->i_mode & S_ISGID)
+-		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+ 	if (err) {
+@@ -2017,7 +2014,7 @@ static int ext3_symlink (struct inode * 
+ 		goto out_stop;
+ 
+ 	if (l > sizeof (EXT3_I(inode)->i_data)) {
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext3_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+ 		 * block_symlink() calls back into ext3_prepare/commit_write.
+@@ -2244,4 +2241,16 @@ struct inode_operations ext3_dir_inode_o
+ 	rmdir:		ext3_rmdir,		/* BKL held */
+ 	mknod:		ext3_mknod,		/* BKL held */
+ 	rename:		ext3_rename,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
++
++struct inode_operations ext3_special_inode_operations = {
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+--- linux-2.4.20/fs/ext3/super.c~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:02.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/super.c	2003-05-07 18:08:39.000000000 +0800
+@@ -24,6 +24,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -404,6 +405,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
+@@ -499,6 +501,7 @@ static int parse_options (char * options
+ 			  int is_remount)
+ {
+ 	unsigned long *mount_options = &sbi->s_mount_opt;
++	
+ 	uid_t *resuid = &sbi->s_resuid;
+ 	gid_t *resgid = &sbi->s_resgid;
+ 	char * this_char;
+@@ -511,6 +514,13 @@ static int parse_options (char * options
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -928,6 +938,12 @@ struct super_block * ext3_read_super (st
+ 	sbi->s_mount_opt = 0;
+ 	sbi->s_resuid = EXT3_DEF_RESUID;
+ 	sbi->s_resgid = EXT3_DEF_RESGID;
++
++	/* Default extended attribute flags */
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++	/* set_opt(sbi->s_mount_opt, XATTR_USER); */
++#endif
++
+ 	if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
+ 		sb->s_dev = 0;
+ 		goto out_fail;
+@@ -1767,17 +1783,29 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
+ 
+ static int __init init_ext3_fs(void)
+ {
+-        return register_filesystem(&ext3_fs_type);
++	int error = init_ext3_xattr();
++	if (error)
++		return error;
++	error = init_ext3_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext3_fs_type);
++	if (!error)
++		return 0;
++	
++	exit_ext3_xattr_user();
++fail:
++	exit_ext3_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext3_fs(void)
+ {
+ 	unregister_filesystem(&ext3_fs_type);
++	exit_ext3_xattr_user();
++	exit_ext3_xattr();
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+-
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+ MODULE_LICENSE("GPL");
+--- linux-2.4.20/fs/ext3/symlink.c~linux-2.4.20-xattr-0.8.54	2001-11-10 06:25:04.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/symlink.c	2003-05-07 18:08:03.000000000 +0800
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ 
+ static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext3_symlink_inode_operations = {
++	readlink:	page_readlink,		/* BKL not held.  Don't need */
++	follow_link:	page_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+ 	readlink:	ext3_readlink,		/* BKL not held.  Don't need */
+ 	follow_link:	ext3_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/xattr.c	2003-05-07 18:09:23.000000000 +0800
+@@ -0,0 +1,1225 @@
++/*
++ * linux/fs/ext3/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT3_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++#define EXT3_EA_USER "user."
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT3_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
++			   struct ext3_xattr_header *);
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++static int ext3_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext3_xattr_cache_find(struct inode *,
++						 struct ext3_xattr_header *);
++static void ext3_xattr_cache_remove(struct buffer_head *);
++static void ext3_xattr_rehash(struct ext3_xattr_header *,
++			      struct ext3_xattr_entry *);
++
++static struct mb_cache *ext3_xattr_cache;
++
++#else
++# define ext3_xattr_cache_insert(bh) 0
++# define ext3_xattr_cache_find(inode, header) NULL
++# define ext3_xattr_cache_remove(bh) while(0) {}
++# define ext3_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext3_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext3_xattr_sem);
++
++static inline int
++ext3_xattr_new_block(handle_t *handle, struct inode *inode,
++		     int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
++		EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext3_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext3_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext3_xattr_free_block(handle_t *handle, struct inode * inode,
++		      unsigned long block)
++{
++	ext3_free_blocks(handle, inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext3_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext3_xattr_free_block(handle, inode, block) \
++	ext3_free_blocks(handle, inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
++rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		if (!ext3_xattr_handlers[name_index-1]) {
++			ext3_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext3_handler_lock);
++	}
++	return error;
++}
++
++void
++ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		ext3_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext3_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static inline struct ext3_xattr_handler *
++ext3_xattr_resolve_name(const char **name)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext3_handler_lock);
++	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
++		if (ext3_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext3_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext3_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext3_handler_lock);
++	return handler;
++}
++
++static inline struct ext3_xattr_handler *
++ext3_xattr_handler(int name_index)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		read_lock(&ext3_handler_lock);
++		handler = ext3_xattr_handlers[name_index-1];
++		read_unlock(&ext3_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext3_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext3_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT3_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT3_I(inode)->i_file_acl)
++		return 0;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext3_xattr_update_super_block(handle_t *handle,
++					  struct super_block *sb)
++{
++	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT3_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext3_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_header *header = NULL;
++	struct ext3_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT3_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext3_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext3_error(sb, "ext3_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT3_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT3_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT3_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext3_xattr_cache_remove(bh);
++			error = ext3_journal_get_write_access(handle, bh);
++			if (error)
++				goto cleanup;
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT3_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT3_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT3_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext3_xattr_set2(handle, inode, bh,NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT3_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT3_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT3_XATTR_PAD, 0,
++			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext3_xattr_rehash(header, here);
++
++	error = ext3_xattr_set2(handle, inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext3_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext3_xattr_set(): Update the file system.
++ */
++static int
++ext3_xattr_set2(handle_t *handle, struct inode *inode,
++		struct buffer_head *old_bh, struct ext3_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext3_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext3_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			error = ext3_journal_get_write_access(handle, new_bh);
++			if (error)
++				goto cleanup;
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext3_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT3_I(inode)->i_file_acl != 0;
++			int block = ext3_xattr_new_block(handle, inode,
++							 &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++getblk_failed:			ext3_xattr_free_block(handle, inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			error = ext3_journal_get_create_access(handle, new_bh);
++			if (error) {
++				unlock_buffer(new_bh);
++				goto getblk_failed;
++			}
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext3_xattr_cache_insert(new_bh);
++			
++			ext3_xattr_update_super_block(handle, sb);
++		}
++		error = ext3_journal_dirty_metadata(handle, new_bh);
++		if (error)
++			goto cleanup;
++	}
++
++	/* Update the inode. */
++	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		error = ext3_journal_get_write_access(handle, old_bh);
++		if (error)
++			goto cleanup;
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
++
++			/* ext3_forget() calls bforget() for us, but we
++			   let our caller release old_bh, so we need to
++			   duplicate the handle before. */
++			get_bh(old_bh);
++			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext3_xattr_quota_free(inode);
++			ext3_journal_dirty_metadata(handle, old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT3_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext3_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ext3_journal_get_write_access(handle, bh);
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext3_xattr_cache_remove(bh);
++		ext3_xattr_free_block(handle, inode, block);
++		ext3_forget(handle, 1, inode, bh, block);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		ext3_journal_dirty_metadata(handle, bh);
++		if (IS_SYNC(inode))
++			handle->h_sync = 1;
++		ext3_xattr_quota_free(inode);
++	}
++	EXT3_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext3_xattr_sem);
++}
++
++/*
++ * ext3_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext3_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++	mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++/*
++ * ext3_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext3_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext3_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext3_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext3_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext3_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext3_xattr_cmp(struct ext3_xattr_header *header1,
++	       struct ext3_xattr_header *header2)
++{
++	struct ext3_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT3_XATTR_NEXT(entry1);
++		entry2 = EXT3_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext3_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT3_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT3_XATTR_REFCOUNT_MAX);
++		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext3_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext3_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
++					 struct ext3_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext3_xattr_rehash(struct ext3_xattr_header *header,
++			      struct ext3_xattr_entry *entry)
++{
++	struct ext3_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext3_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT3_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext3_xattr(void)
++{
++	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext3_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++	if (ext3_xattr_cache)
++		mb_cache_destroy(ext3_xattr_cache);
++	ext3_xattr_cache = NULL;
++}
++
++#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
++
++int __init
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/fs/ext3/xattr_user.c	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,111 @@
++/*
++ * linux/fs/ext3/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++# include <linux/ext3_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext3_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext3_xattr_user_list,
++	get:	ext3_xattr_user_get,
++	set:	ext3_xattr_user_set,
++};
++
++int __init
++init_ext3_xattr_user(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
++				   &ext3_xattr_user_handler);
++}
++
++void
++exit_ext3_xattr_user(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
++			      &ext3_xattr_user_handler);
++}
+--- linux-2.4.20/fs/jfs/jfs_xattr.h~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/jfs/jfs_xattr.h	2003-05-07 18:08:03.000000000 +0800
+@@ -52,8 +52,10 @@ struct jfs_ea_list {
+ #define	END_EALIST(ealist) \
+ 	((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
+ 
+-extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
+-extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
++extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
++			  int);
++extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
++			int);
+ extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
+ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
+ extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
+--- linux-2.4.20/fs/jfs/xattr.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/fs/jfs/xattr.c	2003-05-07 18:08:03.000000000 +0800
+@@ -641,7 +641,7 @@ static int ea_put(struct inode *inode, s
+ }
+ 
+ static int can_set_xattr(struct inode *inode, const char *name,
+-			 void *value, size_t value_len)
++			 const void *value, size_t value_len)
+ {
+ 	if (IS_RDONLY(inode))
+ 		return -EROFS;
+@@ -660,7 +660,7 @@ static int can_set_xattr(struct inode *i
+ 	return permission(inode, MAY_WRITE);
+ }
+ 
+-int __jfs_setxattr(struct inode *inode, const char *name, void *value,
++int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
+ 		   size_t value_len, int flags)
+ {
+ 	struct jfs_ea_list *ealist;
+@@ -799,7 +799,7 @@ int __jfs_setxattr(struct inode *inode, 
+ 	return rc;
+ }
+ 
+-int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
++int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+ 		 size_t value_len, int flags)
+ {
+ 	if (value == NULL) {	/* empty EA, do not remove */
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/fs/mbcache.c	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,648 @@
++/*
++ * linux/fs/mbcache.c
++ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++/*
++ * Filesystem Meta Information Block Cache (mbcache)
++ *
++ * The mbcache caches blocks of block devices that need to be located
++ * by their device/block number, as well as by other criteria (such
++ * as the block's contents).
++ *
++ * There can only be one cache entry in a cache per device and block number.
++ * Additional indexes need not be unique in this sense. The number of
++ * additional indexes (=other criteria) can be hardwired at compile time
++ * or specified at cache create time.
++ *
++ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
++ * in the cache. A valid entry is in the main hash tables of the cache,
++ * and may also be in the lru list. An invalid entry is not in any hashes
++ * or lists.
++ *
++ * A valid cache entry is only in the lru list if no handles refer to it.
++ * Invalid cache entries will be freed when the last handle to the cache
++ * entry is released. Entries that cannot be freed immediately are put
++ * back on the lru list.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/cache_def.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/mbcache.h>
++
++
++#ifdef MB_CACHE_DEBUG
++# define mb_debug(f...) do { \
++		printk(KERN_DEBUG f); \
++		printk("\n"); \
++	} while (0)
++#define mb_assert(c) do { if (!(c)) \
++		printk(KERN_ERR "assertion " #c " failed\n"); \
++	} while(0)
++#else
++# define mb_debug(f...) do { } while(0)
++# define mb_assert(c) do { } while(0)
++#endif
++#define mb_error(f...) do { \
++		printk(KERN_ERR f); \
++		printk("\n"); \
++	} while(0)
++		
++MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
++MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++MODULE_LICENSE("GPL");
++#endif
++
++EXPORT_SYMBOL(mb_cache_create);
++EXPORT_SYMBOL(mb_cache_shrink);
++EXPORT_SYMBOL(mb_cache_destroy);
++EXPORT_SYMBOL(mb_cache_entry_alloc);
++EXPORT_SYMBOL(mb_cache_entry_insert);
++EXPORT_SYMBOL(mb_cache_entry_release);
++EXPORT_SYMBOL(mb_cache_entry_takeout);
++EXPORT_SYMBOL(mb_cache_entry_free);
++EXPORT_SYMBOL(mb_cache_entry_dup);
++EXPORT_SYMBOL(mb_cache_entry_get);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++EXPORT_SYMBOL(mb_cache_entry_find_first);
++EXPORT_SYMBOL(mb_cache_entry_find_next);
++#endif
++
++
++/*
++ * Global data: list of all mbcache's, lru list, and a spinlock for
++ * accessing cache data structures on SMP machines. The lru list is
++ * global across all mbcaches.
++ */
++
++static LIST_HEAD(mb_cache_list);
++static LIST_HEAD(mb_cache_lru_list);
++static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
++
++static inline int
++mb_cache_indexes(struct mb_cache *cache)
++{
++#ifdef MB_CACHE_INDEXES_COUNT
++	return MB_CACHE_INDEXES_COUNT;
++#else
++	return cache->c_indexes_count;
++#endif
++}
++
++/*
++ * What the mbcache registers as to get shrunk dynamically.
++ */
++
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
++
++static struct cache_definition mb_cache_definition = {
++	"mb_cache",
++	mb_cache_memory_pressure
++};
++
++
++static inline int
++__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
++{
++	return !list_empty(&ce->e_block_list);
++}
++
++
++static inline void
++__mb_cache_entry_unhash(struct mb_cache_entry *ce)
++{
++	int n;
++
++	if (__mb_cache_entry_is_hashed(ce)) {
++		list_del_init(&ce->e_block_list);
++		for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
++			list_del(&ce->e_indexes[n].o_list);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
++{
++	struct mb_cache *cache = ce->e_cache;
++
++	mb_assert(atomic_read(&ce->e_used) == 0);
++	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
++		/* free failed -- put back on the lru list
++		   for freeing later. */
++		spin_lock(&mb_cache_spinlock);
++		list_add(&ce->e_lru_list, &mb_cache_lru_list);
++		spin_unlock(&mb_cache_spinlock);
++	} else {
++		kmem_cache_free(cache->c_entry_cache, ce);
++		atomic_dec(&cache->c_entry_count);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
++{
++	if (atomic_dec_and_test(&ce->e_used)) {
++		if (__mb_cache_entry_is_hashed(ce))
++			list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
++		else {
++			spin_unlock(&mb_cache_spinlock);
++			__mb_cache_entry_forget(ce, GFP_KERNEL);
++			return;
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_memory_pressure()  memory pressure callback
++ *
++ * This function is called by the kernel memory management when memory
++ * gets low.
++ *
++ * @priority: Amount by which to shrink the cache (0 = highes priority)
++ * @gfp_mask: (ignored)
++ */
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int count = 0;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &mb_cache_list) {
++		struct mb_cache *cache =
++			list_entry(l, struct mb_cache, c_cache_list);
++		mb_debug("cache %s (%d)", cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++		count += atomic_read(&cache->c_entry_count);
++	}
++	mb_debug("trying to free %d of %d entries",
++		  count / (priority ? priority : 1), count);
++	if (priority)
++		count /= priority;
++	while (count-- && !list_empty(&mb_cache_lru_list)) {
++		struct mb_cache_entry *ce =
++			list_entry(mb_cache_lru_list.next,
++				   struct mb_cache_entry, e_lru_list);
++		list_del(&ce->e_lru_list);
++		__mb_cache_entry_unhash(ce);
++		list_add_tail(&ce->e_lru_list, &free_list);
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), gfp_mask);
++	}
++}
++
++
++/*
++ * mb_cache_create()  create a new cache
++ *
++ * All entries in one cache are equal size. Cache entries may be from
++ * multiple devices. If this is the first mbcache created, registers
++ * the cache with kernel memory management. Returns NULL if no more
++ * memory was available.
++ *
++ * @name: name of the cache (informal)
++ * @cache_op: contains the callback called when freeing a cache entry
++ * @entry_size: The size of a cache entry, including
++ *              struct mb_cache_entry
++ * @indexes_count: number of additional indexes in the cache. Must equal
++ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
++ *                 hardwired.
++ * @bucket_count: number of hash buckets
++ */
++struct mb_cache *
++mb_cache_create(const char *name, struct mb_cache_op *cache_op,
++		size_t entry_size, int indexes_count, int bucket_count)
++{
++	int m=0, n;
++	struct mb_cache *cache = NULL;
++
++	if(entry_size < sizeof(struct mb_cache_entry) +
++	   indexes_count * sizeof(struct mb_cache_entry_index))
++		return NULL;
++
++	MOD_INC_USE_COUNT;
++	cache = kmalloc(sizeof(struct mb_cache) +
++	                indexes_count * sizeof(struct list_head), GFP_KERNEL);
++	if (!cache)
++		goto fail;
++	cache->c_name = name;
++	cache->c_op.free = NULL;
++	if (cache_op)
++		cache->c_op.free = cache_op->free;
++	atomic_set(&cache->c_entry_count, 0);
++	cache->c_bucket_count = bucket_count;
++#ifdef MB_CACHE_INDEXES_COUNT
++	mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
++#else
++	cache->c_indexes_count = indexes_count;
++#endif
++	cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
++	                              GFP_KERNEL);
++	if (!cache->c_block_hash)
++		goto fail;
++	for (n=0; n<bucket_count; n++)
++		INIT_LIST_HEAD(&cache->c_block_hash[n]);
++	for (m=0; m<indexes_count; m++) {
++		cache->c_indexes_hash[m] = kmalloc(bucket_count *
++		                                 sizeof(struct list_head),
++		                                 GFP_KERNEL);
++		if (!cache->c_indexes_hash[m])
++			goto fail;
++		for (n=0; n<bucket_count; n++)
++			INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
++	}
++	cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
++		0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
++	if (!cache->c_entry_cache)
++		goto fail;
++
++	spin_lock(&mb_cache_spinlock);
++	list_add(&cache->c_cache_list, &mb_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	return cache;
++
++fail:
++	if (cache) {
++		while (--m >= 0)
++			kfree(cache->c_indexes_hash[m]);
++		if (cache->c_block_hash)
++			kfree(cache->c_block_hash);
++		kfree(cache);
++	}
++	MOD_DEC_USE_COUNT;
++	return NULL;
++}
++
++
++/*
++ * mb_cache_shrink()
++ *
++ * Removes all cache entires of a device from the cache. All cache entries
++ * currently in use cannot be freed, and thus remain in the cache.
++ *
++ * @cache: which cache to shrink
++ * @dev: which device's cache entries to shrink
++ */
++void
++mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_dev == dev) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++}
++
++
++/*
++ * mb_cache_destroy()
++ *
++ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
++ * and then destroys it. If this was the last mbcache, un-registers the
++ * mbcache from kernel memory management.
++ */
++void
++mb_cache_destroy(struct mb_cache *cache)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_cache == cache) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	list_del(&cache->c_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++
++	if (atomic_read(&cache->c_entry_count) > 0) {
++		mb_error("cache %s: %d orphaned entries",
++			  cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++	}
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
++	/* We don't have kmem_cache_destroy() in 2.2.x */
++	kmem_cache_shrink(cache->c_entry_cache);
++#else
++	kmem_cache_destroy(cache->c_entry_cache);
++#endif
++	for (n=0; n < mb_cache_indexes(cache); n++)
++		kfree(cache->c_indexes_hash[n]);
++	kfree(cache->c_block_hash);
++	kfree(cache);
++
++	MOD_DEC_USE_COUNT;
++}
++
++
++/*
++ * mb_cache_entry_alloc()
++ *
++ * Allocates a new cache entry. The new entry will not be valid initially,
++ * and thus cannot be looked up yet. It should be filled with data, and
++ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
++ * if no more memory was available.
++ */
++struct mb_cache_entry *
++mb_cache_entry_alloc(struct mb_cache *cache)
++{
++	struct mb_cache_entry *ce;
++
++	atomic_inc(&cache->c_entry_count);
++	ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
++	if (ce) {
++		INIT_LIST_HEAD(&ce->e_lru_list);
++		INIT_LIST_HEAD(&ce->e_block_list);
++		ce->e_cache = cache;
++		atomic_set(&ce->e_used, 1);
++	}
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_insert()
++ *
++ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
++ * the cache. After this, the cache entry can be looked up, but is not yet
++ * in the lru list as the caller still holds a handle to it. Returns 0 on
++ * success, or -EBUSY if a cache entry for that device + inode exists
++ * already (this may happen after a failed lookup, if another process has
++ * inserted the same cache entry in the meantime).
++ *
++ * @dev: device the cache entry belongs to
++ * @block: block number
++ * @keys: array of additional keys. There must be indexes_count entries
++ *        in the array (as specified when creating the cache).
++ */
++int
++mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
++		      unsigned long block, unsigned int keys[])
++{
++	struct mb_cache *cache = ce->e_cache;
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	int error = -EBUSY, n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block)
++			goto out;
++	}
++	__mb_cache_entry_unhash(ce);
++	ce->e_dev = dev;
++	ce->e_block = block;
++	list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
++	for (n=0; n<mb_cache_indexes(cache); n++) {
++		ce->e_indexes[n].o_key = keys[n];
++		bucket = keys[n] % cache->c_bucket_count;
++		list_add(&ce->e_indexes[n].o_list,
++		         &cache->c_indexes_hash[n][bucket]);
++	}
++out:
++	spin_unlock(&mb_cache_spinlock);
++	return error;
++}
++
++
++/*
++ * mb_cache_entry_release()
++ *
++ * Release a handle to a cache entry. When the last handle to a cache entry
++ * is released it is either freed (if it is invalid) or otherwise inserted
++ * in to the lru list.
++ */
++void
++mb_cache_entry_release(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_takeout()
++ *
++ * Take a cache entry out of the cache, making it invalid. The entry can later
++ * be re-inserted using mb_cache_entry_insert(), or released using
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_takeout(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_entry_free()
++ *
++ * This is equivalent to the sequence mb_cache_entry_takeout() --
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_free(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_dup()
++ *
++ * Duplicate a handle to a cache entry (does not duplicate the cache entry
++ * itself). After the call, both the old and the new handle must be released.
++ */
++struct mb_cache_entry *
++mb_cache_entry_dup(struct mb_cache_entry *ce)
++{
++	atomic_inc(&ce->e_used);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_get()
++ *
++ * Get a cache entry  by device / block number. (There can only be one entry
++ * in the cache per device and block.) Returns NULL if no such cache entry
++ * exists.
++ */
++struct mb_cache_entry *
++mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
++{
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		ce = list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			goto cleanup;
++		}
++	}
++	ce = NULL;
++
++cleanup:
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++
++static struct mb_cache_entry *
++__mb_cache_entry_find(struct list_head *l, struct list_head *head,
++		      int index, kdev_t dev, unsigned int key)
++{
++	while (l != head) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry,
++			           e_indexes[index].o_list);
++		if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			return ce;
++		}
++		l = l->next;
++	}
++	return NULL;
++}
++
++
++/*
++ * mb_cache_entry_find_first()
++ *
++ * Find the first cache entry on a given device with a certain key in
++ * an additional index. Additonal matches can be found with
++ * mb_cache_entry_find_next(). Returns NULL if no match was found.
++ *
++ * @cache: the cache to search
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
++			  unsigned int key)
++{
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = cache->c_indexes_hash[index][bucket].next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_find_next()
++ *
++ * Find the next cache entry on a given device with a certain key in an
++ * additional index. Returns NULL if no match could be found. The previous
++ * entry is atomatically released, so that mb_cache_entry_find_next() can
++ * be called like this:
++ *
++ * entry = mb_cache_entry_find_first();
++ * while (entry) {
++ * 	...
++ *	entry = mb_cache_entry_find_next(entry, ...);
++ * }
++ *
++ * @prev: The previous match
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
++			 unsigned int key)
++{
++	struct mb_cache *cache = prev->e_cache;
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = prev->e_indexes[index].o_list.next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	__mb_cache_entry_release_unlock(prev);
++	return ce;
++}
++
++#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
++
++static int __init init_mbcache(void)
++{
++	register_cache(&mb_cache_definition);
++	return 0;
++}
++
++static void __exit exit_mbcache(void)
++{
++	unregister_cache(&mb_cache_definition);
++}
++
++module_init(init_mbcache)
++module_exit(exit_mbcache)
++
+--- linux-2.4.20/include/asm-arm/unistd.h~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:45.000000000 +0800
++++ linux-2.4.20-root/include/asm-arm/unistd.h	2003-05-07 18:08:03.000000000 +0800
+@@ -244,7 +244,6 @@
+ #define __NR_security			(__NR_SYSCALL_BASE+223)
+ #define __NR_gettid			(__NR_SYSCALL_BASE+224)
+ #define __NR_readahead			(__NR_SYSCALL_BASE+225)
+-#if 0 /* allocated in 2.5 */
+ #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
+ #define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
+ #define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
+@@ -257,7 +256,6 @@
+ #define __NR_removexattr		(__NR_SYSCALL_BASE+235)
+ #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
+ #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
+-#endif
+ #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+ /*
+  * Please check 2.5 _before_ adding calls here,
+--- linux-2.4.20/include/asm-ppc64/unistd.h~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:45.000000000 +0800
++++ linux-2.4.20-root/include/asm-ppc64/unistd.h	2003-05-07 18:08:03.000000000 +0800
+@@ -218,6 +218,7 @@
+ #define __NR_gettid		207
+ #if 0 /* Reserved syscalls */
+ #define __NR_tkill		208
++#endif
+ #define __NR_setxattr		209
+ #define __NR_lsetxattr		210
+ #define __NR_fsetxattr		211
+@@ -230,6 +231,7 @@
+ #define __NR_removexattr	218
+ #define __NR_lremovexattr	219
+ #define __NR_fremovexattr	220
++#if 0 /* Reserved syscalls */
+ #define __NR_futex		221
+ #endif
+ 
+--- linux-2.4.20/include/asm-s390/unistd.h~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:45.000000000 +0800
++++ linux-2.4.20-root/include/asm-s390/unistd.h	2003-05-07 18:08:03.000000000 +0800
+@@ -212,9 +212,18 @@
+ #define __NR_getdents64		220
+ #define __NR_fcntl64		221
+ #define __NR_readahead		222
+-/*
+- * Numbers 224-235 are reserved for posix acl
+- */
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ #define __NR_gettid		236
+ #define __NR_tkill		237
+ 
+--- linux-2.4.20/include/asm-s390x/unistd.h~linux-2.4.20-xattr-0.8.54	2002-08-03 08:39:45.000000000 +0800
++++ linux-2.4.20-root/include/asm-s390x/unistd.h	2003-05-07 18:08:03.000000000 +0800
+@@ -180,9 +180,18 @@
+ #define __NR_mincore            218
+ #define __NR_madvise            219
+ #define __NR_readahead		222
+-/*
+- * Numbers 224-235 are reserved for posix acl
+- */
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ #define __NR_gettid		236
+ #define __NR_tkill		237
+ 
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/include/linux/cache_def.h	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,15 @@
++/*
++ * linux/cache_def.h
++ * Handling of caches defined in drivers, filesystems, ...
++ *
++ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++struct cache_definition {
++	const char *name;
++	void (*shrink)(int, unsigned int);
++	struct list_head link;
++};
++
++extern void register_cache(struct cache_definition *);
++extern void unregister_cache(struct cache_definition *);
+--- linux-2.4.20/include/linux/errno.h~linux-2.4.20-xattr-0.8.54	2003-04-14 16:39:03.000000000 +0800
++++ linux-2.4.20-root/include/linux/errno.h	2003-05-07 18:08:03.000000000 +0800
+@@ -23,4 +23,8 @@
+ 
+ #endif
+ 
++/* Defined for extended attributes */
++#define ENOATTR ENODATA		/* No such attribute */
++#define ENOTSUP EOPNOTSUPP	/* Operation not supported */
++
+ #endif
+--- linux-2.4.20/include/linux/ext2_fs.h~linux-2.4.20-xattr-0.8.54	2003-04-14 16:39:08.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext2_fs.h	2003-05-07 18:08:03.000000000 +0800
+@@ -57,8 +57,6 @@
+  */
+ #define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT2_ROOT_INO		 2	/* Root inode */
+-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ 
+@@ -86,7 +84,6 @@
+ #else
+ # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+ #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -121,28 +118,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext2_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext2_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext2_group_desc
+@@ -314,6 +289,7 @@ struct ext2_inode {
+ #define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+ #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+ #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
++#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+ #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+@@ -397,6 +373,7 @@ struct ext2_super_block {
+ 
+ #ifdef __KERNEL__
+ #define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
++#define EXT2_I(inode)	(&((inode)->u.ext2_i))
+ #else
+ /* Assume that user mode programs are passing in an ext2fs superblock, not
+  * a kernel struct super_block.  This will allow us to call the feature-test
+@@ -466,7 +443,7 @@ struct ext2_super_block {
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008
+ #define EXT2_FEATURE_INCOMPAT_ANY		0xffffffff
+ 
+-#define EXT2_FEATURE_COMPAT_SUPP	0
++#define EXT2_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+ #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+@@ -623,8 +600,10 @@ extern struct address_space_operations e
+ 
+ /* namei.c */
+ extern struct inode_operations ext2_dir_inode_operations;
++extern struct inode_operations ext2_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext2_symlink_inode_operations;
+ extern struct inode_operations ext2_fast_symlink_inode_operations;
+ 
+ #endif	/* __KERNEL__ */
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext2_xattr.h	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext2_xattr.h
++
++  On-disk format of extended attributes for the ext2 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT2_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT2_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT2_XATTR_INDEX_MAX			10
++#define EXT2_XATTR_INDEX_USER			1
++#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext2_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext2_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT2_XATTR_PAD_BITS		2
++#define EXT2_XATTR_PAD		(1<<EXT2_XATTR_PAD_BITS)
++#define EXT2_XATTR_ROUND		(EXT2_XATTR_PAD-1)
++#define EXT2_XATTR_LEN(name_len) \
++	(((name_len) + EXT2_XATTR_ROUND + \
++	sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
++#define EXT2_XATTR_NEXT(entry) \
++	( (struct ext2_xattr_entry *)( \
++	  (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
++#define EXT2_XATTR_SIZE(size) \
++	(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT2_FS_XATTR
++
++struct ext2_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
++extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
++
++extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
++extern int ext2_removexattr(struct dentry *, const char *);
++
++extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext2_xattr_list(struct inode *, char *, size_t);
++extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext2_xattr_delete_inode(struct inode *);
++extern void ext2_xattr_put_super(struct super_block *);
++
++extern int init_ext2_xattr(void) __init;
++extern void exit_ext2_xattr(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR */
++#  define ext2_setxattr		NULL
++#  define ext2_getxattr		NULL
++#  define ext2_listxattr	NULL
++#  define ext2_removexattr	NULL
++
++static inline int
++ext2_xattr_get(struct inode *inode, int name_index,
++	       const char *name, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++}
++
++static inline void
++ext2_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR */
++
++# ifdef CONFIG_EXT2_FS_XATTR_USER
++
++extern int init_ext2_xattr_user(void) __init;
++extern void exit_ext2_xattr_user(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR_USER */
++
++static inline int
++init_ext2_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr_user(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+--- linux-2.4.20/include/linux/ext3_fs.h~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:04.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext3_fs.h	2003-05-07 18:08:03.000000000 +0800
+@@ -63,8 +63,6 @@
+  */
+ #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT3_ROOT_INO		 2	/* Root inode */
+-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
+@@ -94,7 +92,6 @@
+ #else
+ # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
+ #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -129,28 +126,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext3_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext3_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext3_group_desc
+@@ -344,6 +319,7 @@ struct ext3_inode {
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -520,7 +496,7 @@ struct ext3_super_block {
+ #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+ 
+-#define EXT3_FEATURE_COMPAT_SUPP	0
++#define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
+ 					 EXT3_FEATURE_INCOMPAT_RECOVER)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+@@ -703,6 +679,7 @@ extern void ext3_check_inodes_bitmap (st
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
+ 
+ /* inode.c */
++extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+ 
+@@ -771,8 +748,10 @@ extern struct address_space_operations e
+ 
+ /* namei.c */
+ extern struct inode_operations ext3_dir_inode_operations;
++extern struct inode_operations ext3_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext3_symlink_inode_operations;
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
+ 
+--- linux-2.4.20/include/linux/ext3_jbd.h~linux-2.4.20-xattr-0.8.54	2003-05-05 19:01:02.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext3_jbd.h	2003-05-07 18:08:03.000000000 +0800
+@@ -30,13 +30,19 @@
+ 
+ #define EXT3_SINGLEDATA_TRANS_BLOCKS	8
+ 
++/* Extended attributes may touch two data buffers, two bitmap buffers,
++ * and two group and summaries. */
++
++#define EXT3_XATTR_TRANS_BLOCKS		8
++
+ /* Define the minimum size for a transaction which modifies data.  This
+  * needs to take into account the fact that we may end up modifying two
+  * quota files too (one for the group, one for the user quota).  The
+  * superblock only gets updated once, of course, so don't bother
+  * counting that again for the quota updates. */
+ 
+-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
++#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
++					 EXT3_XATTR_TRANS_BLOCKS - 2)
+ 
+ extern int ext3_writepage_trans_blocks(struct inode *inode);
+ 
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/include/linux/ext3_xattr.h	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext3_xattr.h
++
++  On-disk format of extended attributes for the ext3 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT3_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT3_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT3_XATTR_INDEX_MAX			10
++#define EXT3_XATTR_INDEX_USER			1
++#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext3_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext3_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT3_XATTR_PAD_BITS		2
++#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
++#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
++#define EXT3_XATTR_LEN(name_len) \
++	(((name_len) + EXT3_XATTR_ROUND + \
++	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
++#define EXT3_XATTR_NEXT(entry) \
++	( (struct ext3_xattr_entry *)( \
++	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
++#define EXT3_XATTR_SIZE(size) \
++	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT3_FS_XATTR
++
++struct ext3_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
++extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
++
++extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
++extern int ext3_removexattr(struct dentry *, const char *);
++
++extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext3_xattr_list(struct inode *, char *, size_t);
++extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
++extern void ext3_xattr_put_super(struct super_block *);
++
++extern int init_ext3_xattr(void) __init;
++extern void exit_ext3_xattr(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR */
++#  define ext3_setxattr		NULL
++#  define ext3_getxattr		NULL
++#  define ext3_listxattr	NULL
++#  define ext3_removexattr	NULL
++
++static inline int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++}
++
++static inline void
++ext3_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT3_FS_XATTR */
++
++# ifdef CONFIG_EXT3_FS_XATTR_USER
++
++extern int init_ext3_xattr_user(void) __init;
++extern void exit_ext3_xattr_user(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR_USER */
++
++static inline int
++init_ext3_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr_user(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+--- linux-2.4.20/include/linux/fs.h~linux-2.4.20-xattr-0.8.54	2003-05-05 19:00:55.000000000 +0800
++++ linux-2.4.20-root/include/linux/fs.h	2003-05-07 18:08:03.000000000 +0800
+@@ -888,7 +888,7 @@ struct inode_operations {
+ 	int (*setattr) (struct dentry *, struct iattr *);
+ 	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
+-	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
++	int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
+ 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+ 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+ 	int (*removexattr) (struct dentry *, const char *);
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-2.4.20-root/include/linux/mbcache.h	2003-05-07 18:08:03.000000000 +0800
+@@ -0,0 +1,69 @@
++/*
++  File: linux/mbcache.h
++
++  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++/* Hardwire the number of additional indexes */
++#define MB_CACHE_INDEXES_COUNT 1
++
++struct mb_cache_entry;
++
++struct mb_cache_op {
++	int (*free)(struct mb_cache_entry *, int);
++};
++
++struct mb_cache {
++	struct list_head		c_cache_list;
++	const char			*c_name;
++	struct mb_cache_op		c_op;
++	atomic_t			c_entry_count;
++	int				c_bucket_count;
++#ifndef MB_CACHE_INDEXES_COUNT
++	int				c_indexes_count;
++#endif
++	kmem_cache_t			*c_entry_cache;
++	struct list_head		*c_block_hash;
++	struct list_head		*c_indexes_hash[0];
++};
++
++struct mb_cache_entry_index {
++	struct list_head		o_list;
++	unsigned int			o_key;
++};
++
++struct mb_cache_entry {
++	struct list_head		e_lru_list;
++	struct mb_cache			*e_cache;
++	atomic_t			e_used;
++	kdev_t				e_dev;
++	unsigned long			e_block;
++	struct list_head		e_block_list;
++	struct mb_cache_entry_index	e_indexes[0];
++};
++
++/* Functions on caches */
++
++struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
++				  int, int);
++void mb_cache_shrink(struct mb_cache *, kdev_t);
++void mb_cache_destroy(struct mb_cache *);
++
++/* Functions on cache entries */
++
++struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
++int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
++			  unsigned int[]);
++void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
++void mb_cache_entry_release(struct mb_cache_entry *);
++void mb_cache_entry_takeout(struct mb_cache_entry *);
++void mb_cache_entry_free(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
++					  unsigned long);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
++						 kdev_t, unsigned int);
++struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
++						kdev_t, unsigned int);
++#endif
+--- linux-2.4.20/kernel/ksyms.c~linux-2.4.20-xattr-0.8.54	2003-05-05 17:43:15.000000000 +0800
++++ linux-2.4.20-root/kernel/ksyms.c	2003-05-07 18:08:03.000000000 +0800
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/slab.h>
++#include <linux/cache_def.h>
+ #include <linux/module.h>
+ #include <linux/blkdev.h>
+ #include <linux/cdrom.h>
+@@ -89,6 +90,7 @@ EXPORT_SYMBOL(exit_mm);
+ EXPORT_SYMBOL(exit_files);
+ EXPORT_SYMBOL(exit_fs);
+ EXPORT_SYMBOL(exit_sighand);
++EXPORT_SYMBOL(copy_fs_struct);
+ 
+ /* internal kernel memory management */
+ EXPORT_SYMBOL(_alloc_pages);
+@@ -107,6 +109,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
+ EXPORT_SYMBOL(kmem_cache_alloc);
+ EXPORT_SYMBOL(kmem_cache_free);
+ EXPORT_SYMBOL(kmem_cache_size);
++EXPORT_SYMBOL(register_cache);
++EXPORT_SYMBOL(unregister_cache);
+ EXPORT_SYMBOL(kmalloc);
+ EXPORT_SYMBOL(kfree);
+ EXPORT_SYMBOL(vfree);
+--- linux-2.4.20/mm/vmscan.c~linux-2.4.20-xattr-0.8.54	2002-11-29 07:53:15.000000000 +0800
++++ linux-2.4.20-root/mm/vmscan.c	2003-05-07 18:08:03.000000000 +0800
+@@ -18,6 +18,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/swap.h>
+ #include <linux/swapctl.h>
++#include <linux/cache_def.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pagemap.h>
+ #include <linux/init.h>
+@@ -34,6 +35,39 @@
+  */
+ #define DEF_PRIORITY (6)
+ 
++static DECLARE_MUTEX(other_caches_sem);
++static LIST_HEAD(cache_definitions);
++
++void register_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_add(&cache->link, &cache_definitions);
++	up(&other_caches_sem);
++}
++
++void unregister_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_del(&cache->link);
++	up(&other_caches_sem);
++}
++
++static void shrink_other_caches(unsigned int priority, int gfp_mask)
++{
++	struct list_head *p;
++
++	if (down_trylock(&other_caches_sem))
++		return;
++
++	list_for_each_prev(p, &cache_definitions) {
++		struct cache_definition *cache =
++			list_entry(p, struct cache_definition, link);
++
++		cache->shrink(priority, gfp_mask);
++	}
++	up(&other_caches_sem);
++}
++
+ /*
+  * The swap-out function returns 1 if it successfully
+  * scanned all the pages it was asked to (`count').
+@@ -577,6 +611,7 @@ static int shrink_caches(zone_t * classz
+ 
+ 	shrink_dcache_memory(priority, gfp_mask);
+ 	shrink_icache_memory(priority, gfp_mask);
++	shrink_other_caches(priority, gfp_mask);
+ #ifdef CONFIG_QUOTA
+ 	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+ #endif
+--- /dev/null	2003-01-30 18:24:37.000000000 +0800
++++ linux-root/fs/ext3/ext3-exports.c	2003-05-05 18:19:11.000000000 +0800
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
+
+_
diff --git a/lustre/kernel_patches/patches/linux-2.4.22-xattr-0.8.54.patch b/lustre/kernel_patches/patches/linux-2.4.22-xattr-0.8.54.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c5abbf3a1f784db5947c1600d44486261eede9ea
--- /dev/null
+++ b/lustre/kernel_patches/patches/linux-2.4.22-xattr-0.8.54.patch
@@ -0,0 +1,5460 @@
+ Documentation/Configure.help  |   66 ++
+ arch/alpha/defconfig          |    7 
+ arch/alpha/kernel/entry.S     |   12 
+ arch/arm/defconfig            |    7 
+ arch/arm/kernel/calls.S       |   24 
+ arch/i386/defconfig           |    7 
+ arch/ia64/defconfig           |    7 
+ arch/ia64/kernel/entry.S      |   24 
+ arch/m68k/defconfig           |    7 
+ arch/mips/defconfig           |    7 
+ arch/mips64/defconfig         |    7 
+ arch/ppc/defconfig            |   14 
+ arch/ppc64/kernel/misc.S      |    2 
+ arch/s390/defconfig           |    7 
+ arch/s390/kernel/entry.S      |   24 
+ arch/s390x/defconfig          |    7 
+ arch/s390x/kernel/entry.S     |   24 
+ arch/s390x/kernel/wrapper32.S |   92 +++
+ arch/sparc/defconfig          |    7 
+ arch/sparc/kernel/systbls.S   |   10 
+ arch/sparc64/defconfig        |    7 
+ arch/sparc64/kernel/systbls.S |   20 
+ fs/Config.in                  |   14 
+ fs/Makefile                   |    3 
+ fs/ext2/Makefile              |    4 
+ fs/ext2/file.c                |    5 
+ fs/ext2/ialloc.c              |    2 
+ fs/ext2/inode.c               |   34 -
+ fs/ext2/namei.c               |   14 
+ fs/ext2/super.c               |   29 
+ fs/ext2/symlink.c             |   14 
+ fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
+ fs/ext2/xattr_user.c          |  103 +++
+ fs/ext3/Makefile              |   10 
+ fs/ext3/file.c                |    5 
+ fs/ext3/ialloc.c              |    2 
+ fs/ext3/inode.c               |   35 -
+ fs/ext3/namei.c               |   21 
+ fs/ext3/super.c               |   36 +
+ fs/ext3/symlink.c             |   14 
+ fs/ext3/xattr.c               | 1225 ++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/xattr_user.c          |  111 +++
+ fs/jfs/jfs_xattr.h            |    6 
+ fs/jfs/xattr.c                |    6 
+ fs/mbcache.c                  |  648 ++++++++++++++++++++++
+ include/asm-arm/unistd.h      |    2 
+ include/asm-ia64/unistd.h     |   13 
+ include/asm-ppc64/unistd.h    |    2 
+ include/asm-s390/unistd.h     |   15 
+ include/asm-s390x/unistd.h    |   15 
+ include/asm-sparc/unistd.h    |   24 
+ include/asm-sparc64/unistd.h  |   24 
+ include/linux/cache_def.h     |   15 
+ include/linux/errno.h         |    4 
+ include/linux/ext2_fs.h       |   31 -
+ include/linux/ext2_xattr.h    |  157 +++++
+ include/linux/ext3_fs.h       |   31 -
+ include/linux/ext3_jbd.h      |    8 
+ include/linux/ext3_xattr.h    |  157 +++++
+ include/linux/fs.h            |    2 
+ include/linux/mbcache.h       |   69 ++
+ kernel/ksyms.c                |    4 
+ mm/vmscan.c                   |   35 +
+ fs/ext3/ext3-exports.c        |   14 +  
+ 64 files changed, 4355 insertions(+), 195 deletions(-)
+
+Index: linux-2.4.22-vanilla/Documentation/Configure.help
+===================================================================
+--- linux-2.4.22-vanilla.orig/Documentation/Configure.help	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/Documentation/Configure.help	2003-11-03 23:41:29.000000000 +0300
+@@ -15613,6 +15613,39 @@
+   be compiled as a module, and so this could be dangerous.  Most
+   everyone wants to say Y here.
+ 
++Ext2 extended attributes
++CONFIG_EXT2_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 extended attribute block sharing
++CONFIG_EXT2_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext2 extended user attributes
++CONFIG_EXT2_FS_XATTR_USER
++  This option enables extended user attributes on ext2. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 trusted extended attributes
++CONFIG_EXT2_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext2 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Ext3 journalling file system support (EXPERIMENTAL)
+ CONFIG_EXT3_FS
+   This is the journalling version of the Second extended file system
+@@ -15645,6 +15678,39 @@
+   of your root partition (the one containing the directory /) cannot
+   be compiled as a module, and so this may be dangerous.
+ 
++Ext3 extended attributes
++CONFIG_EXT3_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 extended attribute block sharing
++CONFIG_EXT3_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext3 extended user attributes
++CONFIG_EXT3_FS_XATTR_USER
++  This option enables extended user attributes on ext3. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 trusted extended attributes
++CONFIG_EXT3_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext3 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
+ CONFIG_JBD
+   This is a generic journalling layer for block devices.  It is
+Index: linux-2.4.22-vanilla/arch/alpha/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/alpha/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/alpha/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ALPHA=y
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+Index: linux-2.4.22-vanilla/arch/alpha/kernel/entry.S
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/alpha/kernel/entry.S	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/alpha/kernel/entry.S	2003-11-03 23:41:29.000000000 +0300
+@@ -1154,6 +1154,18 @@
+ 	.quad sys_readahead
+ 	.quad sys_ni_syscall			/* 380, sys_security */
+ 	.quad sys_tkill
++	.quad sys_setxattr
++	.quad sys_lsetxattr
++	.quad sys_fsetxattr
++	.quad sys_getxattr			/* 385 */
++	.quad sys_lgetxattr
++	.quad sys_fgetxattr
++	.quad sys_listxattr
++	.quad sys_llistxattr
++	.quad sys_flistxattr			/* 390 */
++	.quad sys_removexattr
++	.quad sys_lremovexattr
++	.quad sys_fremovexattr
+ 
+ /* Remember to update everything, kids.  */
+ .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
+Index: linux-2.4.22-vanilla/arch/arm/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/arm/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/arm/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ARM=y
+ # CONFIG_EISA is not set
+ # CONFIG_SBUS is not set
+Index: linux-2.4.22-vanilla/arch/arm/kernel/calls.S
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/arm/kernel/calls.S	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/arm/kernel/calls.S	2003-11-03 23:41:29.000000000 +0300
+@@ -240,18 +240,18 @@
+ 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
+ 		.long	SYMBOL_NAME(sys_gettid)
+ /* 225 */	.long	SYMBOL_NAME(sys_readahead)
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* setxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* getxattr */
+-/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* listxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* llistxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* flistxattr */
+-/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* removexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */
++		.long	SYMBOL_NAME(sys_setxattr)
++		.long	SYMBOL_NAME(sys_lsetxattr)
++		.long	SYMBOL_NAME(sys_fsetxattr)
++		.long	SYMBOL_NAME(sys_getxattr)
++/* 230 */	.long	SYMBOL_NAME(sys_lgetxattr)
++		.long	SYMBOL_NAME(sys_fgetxattr)
++		.long	SYMBOL_NAME(sys_listxattr)
++		.long	SYMBOL_NAME(sys_llistxattr)
++		.long	SYMBOL_NAME(sys_flistxattr)
++/* 235 */	.long	SYMBOL_NAME(sys_removexattr)
++		.long	SYMBOL_NAME(sys_lremovexattr)
++		.long	SYMBOL_NAME(sys_fremovexattr)
+ 		.long	SYMBOL_NAME(sys_tkill)
+ 		.long	SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */
+ /* 240 */	.long	SYMBOL_NAME(sys_ni_syscall) /* futex */
+Index: linux-2.4.22-vanilla/arch/i386/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/i386/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/i386/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+Index: linux-2.4.22-vanilla/arch/ia64/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/ia64/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/ia64/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+Index: linux-2.4.22-vanilla/arch/m68k/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/m68k/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/m68k/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ 
+ #
+Index: linux-2.4.22-vanilla/arch/mips/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/mips/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/mips/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ CONFIG_MIPS32=y
+ # CONFIG_MIPS64 is not set
+Index: linux-2.4.22-vanilla/arch/mips64/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/mips64/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/mips64/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ # CONFIG_MIPS32 is not set
+ CONFIG_MIPS64=y
+Index: linux-2.4.22-vanilla/arch/s390/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/s390/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/s390/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+Index: linux-2.4.22-vanilla/arch/s390/kernel/entry.S
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/s390/kernel/entry.S	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/s390/kernel/entry.S	2003-11-03 23:41:29.000000000 +0300
+@@ -558,18 +558,18 @@
+         .long  sys_fcntl64 
+ 	.long  sys_readahead
+ 	.long  sys_ni_syscall
+-	.long  sys_ni_syscall		 /* 224 - reserved for setxattr  */
+-	.long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
+-	.long  sys_ni_syscall		 /* 226 - reserved for fsetxattr */
+-	.long  sys_ni_syscall		 /* 227 - reserved for getxattr  */
+-	.long  sys_ni_syscall		 /* 228 - reserved for lgetxattr */
+-	.long  sys_ni_syscall		 /* 229 - reserved for fgetxattr */
+-	.long  sys_ni_syscall		 /* 230 - reserved for listxattr */
+-	.long  sys_ni_syscall		 /* 231 - reserved for llistxattr */
+-	.long  sys_ni_syscall		 /* 232 - reserved for flistxattr */
+-	.long  sys_ni_syscall		 /* 233 - reserved for removexattr */
+-	.long  sys_ni_syscall		 /* 234 - reserved for lremovexattr */
+-	.long  sys_ni_syscall		 /* 235 - reserved for fremovexattr */
++	.long  sys_setxattr
++	.long  sys_lsetxattr		/* 225 */
++	.long  sys_fsetxattr
++	.long  sys_getxattr
++	.long  sys_lgetxattr
++	.long  sys_fgetxattr
++	.long  sys_listxattr		/* 230 */
++	.long  sys_llistxattr
++	.long  sys_flistxattr
++	.long  sys_removexattr
++	.long  sys_lremovexattr
++	.long  sys_fremovexattr		/* 235 */
+ 	.long  sys_gettid
+ 	.long  sys_tkill
+ 	.rept  255-237
+Index: linux-2.4.22-vanilla/arch/s390x/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/s390x/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/s390x/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+Index: linux-2.4.22-vanilla/arch/s390x/kernel/entry.S
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/s390x/kernel/entry.S	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/s390x/kernel/entry.S	2003-11-03 23:41:29.000000000 +0300
+@@ -591,18 +591,18 @@
+ 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
+ 	.long  SYSCALL(sys_readahead,sys32_readahead)
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
++	.long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
++	.long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)	/* 225 */
++	.long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
++	.long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
++	.long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
++	.long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
++	.long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)	/* 230 */
++	.long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
++	.long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
++	.long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
++	.long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
++	.long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
+ 	.long  SYSCALL(sys_gettid,sys_gettid)
+ 	.long  SYSCALL(sys_tkill,sys_tkill)
+ 	.rept  255-237
+Index: linux-2.4.22-vanilla/arch/s390x/kernel/wrapper32.S
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/s390x/kernel/wrapper32.S	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/s390x/kernel/wrapper32.S	2003-11-03 23:41:29.000000000 +0300
+@@ -1098,6 +1098,98 @@
+ 	llgfr	%r4,%r4			# long
+ 	jg	sys32_fstat64		# branch to system call
+ 
++	.globl	sys32_setxattr_wrapper
++sys32_setxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_setxattr
++
++	.globl	sys32_lsetxattr_wrapper
++sys32_lsetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_lsetxattr
++
++	.globl	sys32_fsetxattr_wrapper
++sys32_fsetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_fsetxattr
++
++	.globl	sys32_getxattr_wrapper
++sys32_getxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_getxattr
++
++	.globl	sys32_lgetxattr_wrapper
++sys32_lgetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_lgetxattr
++
++	.globl	sys32_fgetxattr_wrapper
++sys32_fgetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_fgetxattr
++
++	.globl	sys32_listxattr_wrapper
++sys32_listxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_listxattr
++
++	.globl	sys32_llistxattr_wrapper
++sys32_llistxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_llistxattr
++
++	.globl	sys32_flistxattr_wrapper
++sys32_flistxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_flistxattr
++
++	.globl	sys32_removexattr_wrapper
++sys32_removexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_removexattr
++
++	.globl	sys32_lremovexattr_wrapper
++sys32_lremovexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_lremovexattr
++
++	.globl	sys32_fremovexattr_wrapper
++sys32_fremovexattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	jg	sys_fremovexattr
++
++
++
+ 	.globl	sys32_stime_wrapper
+ sys32_stime_wrapper:
+ 	llgtr	%r2,%r2			# int *
+Index: linux-2.4.22-vanilla/arch/sparc64/defconfig
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/sparc64/defconfig	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/arch/sparc64/defconfig	2003-11-03 23:41:29.000000000 +0300
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+Index: linux-2.4.22-vanilla/fs/Config.in
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/Config.in	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/Config.in	2003-11-03 23:41:29.000000000 +0300
+@@ -29,6 +29,11 @@
+ dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
+ 
+ tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
++dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
++dep_bool '    Ext3 extended attribute block sharing' \
++    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
++dep_bool '    Ext3 extended user attributes' \
++    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
+ # CONFIG_JBD could be its own option (even modular), but until there are
+ # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
+ # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
+@@ -88,6 +93,11 @@
+ tristate 'ROM file system support' CONFIG_ROMFS_FS
+ 
+ tristate 'Second extended fs support' CONFIG_EXT2_FS
++dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
++dep_bool '    Ext2 extended attribute block sharing' \
++    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
++dep_bool '    Ext2 extended user attributes' \
++    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
+ 
+ tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
+ 
+@@ -160,6 +170,10 @@
+    define_tristate CONFIG_ZISOFS_FS n
+ fi
+ 
++# Meta block cache for Extended Attributes (ext2/ext3)
++#tristate 'Meta block cache' CONFIG_FS_MBCACHE
++define_tristate CONFIG_FS_MBCACHE y 
++
+ mainmenu_option next_comment
+ comment 'Partition Types'
+ source fs/partitions/Config.in
+Index: linux-2.4.22-vanilla/fs/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/Makefile	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/Makefile	2003-11-03 23:41:29.000000000 +0300
+@@ -77,6 +77,9 @@
+ 
+ obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+ 
++export-objs += mbcache.o
++obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
++
+ # persistent filesystems
+ obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+ 
+Index: linux-2.4.22-vanilla/fs/ext2/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/Makefile	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/Makefile	2003-11-03 23:41:29.000000000 +0300
+@@ -13,4 +13,8 @@
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.22-vanilla/fs/ext2/file.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/file.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/file.c	2003-11-03 23:41:29.000000000 +0300
+@@ -20,6 +20,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/sched.h>
+ 
+ /*
+@@ -51,4 +52,8 @@
+ 
+ struct inode_operations ext2_file_inode_operations = {
+ 	truncate:	ext2_truncate,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.22-vanilla/fs/ext2/ialloc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/ialloc.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/ialloc.c	2003-11-03 23:41:29.000000000 +0300
+@@ -15,6 +15,7 @@
+ #include <linux/config.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ 
+@@ -167,6 +168,7 @@
+ 	 */
+ 	if (!is_bad_inode(inode)) {
+ 		/* Quota is already initialized in iput() */
++		ext2_xattr_delete_inode(inode);
+ 	    	DQUOT_FREE_INODE(inode);
+ 		DQUOT_DROP(inode);
+ 	}
+Index: linux-2.4.22-vanilla/fs/ext2/inode.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/inode.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/inode.c	2003-11-03 23:41:29.000000000 +0300
+@@ -39,6 +39,18 @@
+ static int ext2_update_inode(struct inode * inode, int do_sync);
+ 
+ /*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext2_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext2_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
++/*
+  * Called at each iput()
+  */
+ void ext2_put_inode (struct inode * inode)
+@@ -53,9 +65,7 @@
+ {
+ 	lock_kernel();
+ 
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
+ 	mark_inode_dirty(inode);
+@@ -801,6 +811,8 @@
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext2_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -903,8 +915,7 @@
+ 	unsigned long offset;
+ 	struct ext2_group_desc * gdp;
+ 
+-	if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
+-	     inode->i_ino != EXT2_ACL_DATA_INO &&
++	if ((inode->i_ino != EXT2_ROOT_INO &&
+ 	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
+ 	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
+ 		ext2_error (inode->i_sb, "ext2_read_inode",
+@@ -989,10 +1000,7 @@
+ 	for (block = 0; block < EXT2_N_BLOCKS; block++)
+ 		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
+ 
+-	if (inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext2_file_inode_operations;
+ 		inode->i_fop = &ext2_file_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+@@ -1001,15 +1009,17 @@
+ 		inode->i_fop = &ext2_dir_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext2_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext2_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext2_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext2_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext2_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(raw_inode->i_block[0]));
++	}
+ 	brelse (bh);
+ 	inode->i_attr_flags = 0;
+ 	ext2_set_inode_flags(inode);
+Index: linux-2.4.22-vanilla/fs/ext2/namei.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/namei.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/namei.c	2003-11-03 23:41:29.000000000 +0300
+@@ -31,6 +31,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/pagemap.h>
+ 
+ /*
+@@ -136,7 +137,7 @@
+ 
+ 	if (l > sizeof (inode->u.ext2_i.i_data)) {
+ 		/* slow symlink */
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext2_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 		err = block_symlink(inode, symname, l);
+ 		if (err)
+@@ -345,4 +346,15 @@
+ 	rmdir:		ext2_rmdir,
+ 	mknod:		ext2_mknod,
+ 	rename:		ext2_rename,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
++struct inode_operations ext2_special_inode_operations = {
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.22-vanilla/fs/ext2/super.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/super.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/super.c	2003-11-03 23:41:29.000000000 +0300
+@@ -21,6 +21,7 @@
+ #include <linux/string.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -125,6 +126,7 @@
+ 	int db_count;
+ 	int i;
+ 
++	ext2_xattr_put_super(sb);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+ 
+@@ -175,6 +177,13 @@
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -424,6 +433,9 @@
+ 	    blocksize = BLOCK_SIZE;
+ 
+ 	sb->u.ext2_sb.s_mount_opt = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++	/* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
++#endif
+ 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
+ 	    &sb->u.ext2_sb.s_mount_opt)) {
+ 		return NULL;
+@@ -813,12 +825,27 @@
+ 
+ static int __init init_ext2_fs(void)
+ {
+-        return register_filesystem(&ext2_fs_type);
++	int error = init_ext2_xattr();
++	if (error)
++		return error;
++	error = init_ext2_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext2_fs_type);
++	if (!error)
++		return 0;
++
++	exit_ext2_xattr_user();
++fail:
++	exit_ext2_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext2_fs(void)
+ {
+ 	unregister_filesystem(&ext2_fs_type);
++	exit_ext2_xattr_user();
++	exit_ext2_xattr();
+ }
+ 
+ EXPORT_NO_SYMBOLS;
+Index: linux-2.4.22-vanilla/fs/ext2/symlink.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/symlink.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/symlink.c	2003-11-03 23:41:29.000000000 +0300
+@@ -19,6 +19,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ 
+ static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -32,7 +33,20 @@
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext2_symlink_inode_operations = {
++	readlink:	page_readlink,
++	follow_link:	page_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
+ struct inode_operations ext2_fast_symlink_inode_operations = {
+ 	readlink:	ext2_readlink,
+ 	follow_link:	ext2_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+Index: linux-2.4.22-vanilla/fs/ext2/xattr.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/xattr.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/xattr.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,1212 @@
++/*
++ * linux/fs/ext2/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT2_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++/* These symbols may be needed by a module. */
++EXPORT_SYMBOL(ext2_xattr_register);
++EXPORT_SYMBOL(ext2_xattr_unregister);
++EXPORT_SYMBOL(ext2_xattr_get);
++EXPORT_SYMBOL(ext2_xattr_list);
++EXPORT_SYMBOL(ext2_xattr_set);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT2_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext2_xattr_set2(struct inode *, struct buffer_head *,
++			   struct ext2_xattr_header *);
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++static int ext2_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext2_xattr_cache_find(struct inode *,
++						 struct ext2_xattr_header *);
++static void ext2_xattr_cache_remove(struct buffer_head *);
++static void ext2_xattr_rehash(struct ext2_xattr_header *,
++			      struct ext2_xattr_entry *);
++
++static struct mb_cache *ext2_xattr_cache;
++
++#else
++# define ext2_xattr_cache_insert(bh) 0
++# define ext2_xattr_cache_find(inode, header) NULL
++# define ext2_xattr_cache_remove(bh) while(0) {}
++# define ext2_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext2_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext2_xattr_sem);
++
++static inline int
++ext2_xattr_new_block(struct inode *inode, int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
++		EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext2_new_block(inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext2_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext2_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext2_xattr_free_block(struct inode * inode, unsigned long block)
++{
++	ext2_free_blocks(inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext2_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext2_xattr_free_block(inode, block) \
++	ext2_free_blocks(inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
++rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		if (!ext2_xattr_handlers[name_index-1]) {
++			ext2_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext2_handler_lock);
++	}
++	return error;
++}
++
++void
++ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		ext2_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext2_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static struct ext2_xattr_handler *
++ext2_xattr_resolve_name(const char **name)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext2_handler_lock);
++	for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
++		if (ext2_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext2_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext2_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext2_handler_lock);
++	return handler;
++}
++
++static inline struct ext2_xattr_handler *
++ext2_xattr_handler(int name_index)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		read_lock(&ext2_handler_lock);
++		handler = ext2_xattr_handlers[name_index-1];
++		read_unlock(&ext2_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext2_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext2_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT2_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT2_I(inode)->i_file_acl)
++		return 0;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext2_xattr_update_super_block(struct super_block *sb)
++{
++	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT2_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext2_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_header *header = NULL;
++	struct ext2_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT2_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext2_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext2_error(sb, "ext2_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext2_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT2_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT2_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT2_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext2_xattr_cache_remove(bh);
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT2_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT2_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT2_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext2_xattr_set2(inode, bh, NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT2_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT2_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT2_XATTR_PAD, 0,
++			       EXT2_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext2_xattr_rehash(header, here);
++
++	error = ext2_xattr_set2(inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext2_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext2_xattr_set(): Update the file system.
++ */
++static int
++ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
++		struct ext2_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext2_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext2_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext2_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT2_I(inode)->i_file_acl != 0;
++			int block = ext2_xattr_new_block(inode, &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++				ext2_xattr_free_block(inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext2_xattr_cache_insert(new_bh);
++			
++			ext2_xattr_update_super_block(sb);
++		}
++		mark_buffer_dirty(new_bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &new_bh);
++			wait_on_buffer(new_bh); 
++			error = -EIO;
++			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
++				goto cleanup;
++		}
++	}
++
++	/* Update the inode. */
++	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	if (IS_SYNC(inode)) {
++		error = ext2_sync_inode (inode);
++		if (error)
++			goto cleanup;
++	} else
++		mark_inode_dirty(inode);
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext2_xattr_free_block(inode, old_bh->b_blocknr);
++			mark_buffer_clean(old_bh);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext2_xattr_quota_free(inode);
++			mark_buffer_dirty(old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT2_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext2_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext2_xattr_cache_remove(bh);
++		ext2_xattr_free_block(inode, block);
++		bforget(bh);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		mark_buffer_dirty(bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &bh);
++			wait_on_buffer(bh);
++		}
++		ext2_xattr_quota_free(inode);
++	}
++	EXT2_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext2_xattr_sem);
++}
++
++/*
++ * ext2_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext2_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++	mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++/*
++ * ext2_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext2_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext2_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext2_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext2_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext2_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext2_xattr_cmp(struct ext2_xattr_header *header1,
++	       struct ext2_xattr_header *header2)
++{
++	struct ext2_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT2_XATTR_NEXT(entry1);
++		entry2 = EXT2_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext2_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT2_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT2_XATTR_REFCOUNT_MAX);
++		} else if (!ext2_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext2_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext2_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
++					 struct ext2_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext2_xattr_rehash(struct ext2_xattr_header *header,
++			      struct ext2_xattr_entry *entry)
++{
++	struct ext2_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext2_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT2_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext2_xattr(void)
++{
++	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext2_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++	mb_cache_destroy(ext2_xattr_cache);
++}
++
++#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
++
++int __init
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
+Index: linux-2.4.22-vanilla/fs/ext2/xattr_user.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext2/xattr_user.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext2/xattr_user.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,103 @@
++/*
++ * linux/fs/ext2/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++# include <linux/ext2_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext2_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext2_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext2_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
++			      value, size, flags);
++}
++
++struct ext2_xattr_handler ext2_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext2_xattr_user_list,
++	get:	ext2_xattr_user_get,
++	set:	ext2_xattr_user_set,
++};
++
++int __init
++init_ext2_xattr_user(void)
++{
++	return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
++				   &ext2_xattr_user_handler);
++}
++
++void
++exit_ext2_xattr_user(void)
++{
++	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
++			      &ext2_xattr_user_handler);
++}
+Index: linux-2.4.22-vanilla/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/Makefile	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/Makefile	2003-11-03 23:41:29.000000000 +0300
+@@ -1,5 +1,5 @@
+ #
+-# Makefile for the linux ext2-filesystem routines.
++# Makefile for the linux ext3-filesystem routines.
+ #
+ # Note! Dependencies are done automagically by 'make dep', which also
+ # removes any old dependencies. DON'T put your own dependencies here
+@@ -9,10 +9,14 @@
+ 
+ O_TARGET := ext3.o
+ 
+-export-objs :=	super.o inode.o
++export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o hash.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+Index: linux-2.4.22-vanilla/fs/ext3/file.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/file.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/file.c	2003-11-03 23:41:29.000000000 +0300
+@@ -23,6 +23,7 @@
+ #include <linux/locks.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/smp_lock.h>
+ 
+@@ -127,5 +128,9 @@
+ struct inode_operations ext3_file_inode_operations = {
+ 	truncate:	ext3_truncate,		/* BKL held */
+ 	setattr:	ext3_setattr,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+ 
+Index: linux-2.4.22-vanilla/fs/ext3/ialloc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/ialloc.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/ialloc.c	2003-11-03 23:41:29.000000000 +0300
+@@ -17,6 +17,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+ #include <linux/locks.h>
+@@ -216,6 +217,7 @@
+ 	 * as writing the quota to disk may need the lock as well.
+ 	 */
+ 	DQUOT_INIT(inode);
++	ext3_xattr_delete_inode(handle, inode);
+ 	DQUOT_FREE_INODE(inode);
+ 	DQUOT_DROP(inode);
+ 
+Index: linux-2.4.22-vanilla/fs/ext3/inode.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/inode.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/inode.c	2003-11-03 23:41:29.000000000 +0300
+@@ -39,6 +39,18 @@
+  */
+ #undef SEARCH_FROM_ZERO
+ 
++/*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext3_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext3_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
+ /* The ext3 forget function must perform a revoke if we are freeing data
+  * which has been journaled.  Metadata (eg. indirect blocks) must be
+  * revoked in all cases. 
+@@ -48,7 +60,7 @@
+  * still needs to be revoked.
+  */
+ 
+-static int ext3_forget(handle_t *handle, int is_metadata,
++int ext3_forget(handle_t *handle, int is_metadata,
+ 		       struct inode *inode, struct buffer_head *bh,
+ 		       int blocknr)
+ {
+@@ -179,9 +191,7 @@
+ {
+ 	handle_t *handle;
+ 	
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 
+ 	lock_kernel();
+@@ -1870,6 +1880,8 @@
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext3_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -2017,8 +2029,6 @@
+ 	struct ext3_group_desc * gdp;
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+-		inode->i_ino != EXT3_ACL_IDX_INO &&
+-		inode->i_ino != EXT3_ACL_DATA_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+ 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+ 		inode->i_ino > le32_to_cpu(
+@@ -2159,10 +2169,7 @@
+ 		inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
+ 	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
+ 
+-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+@@ -2170,15 +2177,17 @@
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext3_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext3_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext3_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
++	}
+ 	brelse(iloc.bh);
+ 	ext3_set_inode_flags(inode);
+ 	return;
+Index: linux-2.4.22-vanilla/fs/ext3/namei.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/namei.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/namei.c	2003-11-03 23:41:29.000000000 +0300
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/fcntl.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+@@ -1613,7 +1614,7 @@
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR);
++	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1621,7 +1622,6 @@
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+ 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+-	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+ 		inode->i_nlink--; /* is this nlink == 0? */
+@@ -1648,9 +1648,6 @@
+ 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
+ 	ext3_journal_dirty_metadata(handle, dir_block);
+ 	brelse (dir_block);
+-	inode->i_mode = S_IFDIR | mode;
+-	if (dir->i_mode & S_ISGID)
+-		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+ 	if (err) {
+@@ -2019,7 +2016,7 @@
+ 		goto out_stop;
+ 
+ 	if (l > sizeof (EXT3_I(inode)->i_data)) {
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext3_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+ 		 * block_symlink() calls back into ext3_prepare/commit_write.
+@@ -2244,4 +2241,16 @@
+ 	rmdir:		ext3_rmdir,		/* BKL held */
+ 	mknod:		ext3_mknod,		/* BKL held */
+ 	rename:		ext3_rename,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
++
++struct inode_operations ext3_special_inode_operations = {
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+Index: linux-2.4.22-vanilla/fs/ext3/super.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/super.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/super.c	2003-11-03 23:41:29.000000000 +0300
+@@ -24,6 +24,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -406,6 +407,7 @@
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
+@@ -505,6 +507,7 @@
+ 			  int is_remount)
+ {
+ 	unsigned long *mount_options = &sbi->s_mount_opt;
++	
+ 	uid_t *resuid = &sbi->s_resuid;
+ 	gid_t *resgid = &sbi->s_resgid;
+ 	char * this_char;
+@@ -517,6 +520,13 @@
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -934,6 +944,12 @@
+ 	sbi->s_mount_opt = 0;
+ 	sbi->s_resuid = EXT3_DEF_RESUID;
+ 	sbi->s_resgid = EXT3_DEF_RESGID;
++
++	/* Default extended attribute flags */
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++	/* set_opt(sbi->s_mount_opt, XATTR_USER); */
++#endif
++
+ 	if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
+ 		sb->s_dev = 0;
+ 		goto out_fail;
+@@ -1827,17 +1843,29 @@
+ 	old_sync_dquot = ext3_qops.sync_dquot;
+ 	ext3_qops.sync_dquot = ext3_sync_dquot;
+ #endif
+-        return register_filesystem(&ext3_fs_type);
++	int error = init_ext3_xattr();
++	if (error)
++		return error;
++	error = init_ext3_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext3_fs_type);
++	if (!error)
++		return 0;
++	
++	exit_ext3_xattr_user();
++fail:
++	exit_ext3_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext3_fs(void)
+ {
+ 	unregister_filesystem(&ext3_fs_type);
++	exit_ext3_xattr_user();
++	exit_ext3_xattr();
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+-
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+ MODULE_LICENSE("GPL");
+Index: linux-2.4.22-vanilla/fs/ext3/symlink.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/symlink.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/symlink.c	2003-11-03 23:41:29.000000000 +0300
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ 
+ static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -33,7 +34,20 @@
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext3_symlink_inode_operations = {
++	readlink:	page_readlink,		/* BKL not held.  Don't need */
++	follow_link:	page_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+ 	readlink:	ext3_readlink,		/* BKL not held.  Don't need */
+ 	follow_link:	ext3_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+Index: linux-2.4.22-vanilla/fs/ext3/xattr.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/xattr.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/xattr.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,1225 @@
++/*
++ * linux/fs/ext3/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT3_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++#define EXT3_EA_USER "user."
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT3_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
++			   struct ext3_xattr_header *);
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++static int ext3_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext3_xattr_cache_find(struct inode *,
++						 struct ext3_xattr_header *);
++static void ext3_xattr_cache_remove(struct buffer_head *);
++static void ext3_xattr_rehash(struct ext3_xattr_header *,
++			      struct ext3_xattr_entry *);
++
++static struct mb_cache *ext3_xattr_cache;
++
++#else
++# define ext3_xattr_cache_insert(bh) 0
++# define ext3_xattr_cache_find(inode, header) NULL
++# define ext3_xattr_cache_remove(bh) while(0) {}
++# define ext3_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext3_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext3_xattr_sem);
++
++static inline int
++ext3_xattr_new_block(handle_t *handle, struct inode *inode,
++		     int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
++		EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext3_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext3_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext3_xattr_free_block(handle_t *handle, struct inode * inode,
++		      unsigned long block)
++{
++	ext3_free_blocks(handle, inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext3_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext3_xattr_free_block(handle, inode, block) \
++	ext3_free_blocks(handle, inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
++rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		if (!ext3_xattr_handlers[name_index-1]) {
++			ext3_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext3_handler_lock);
++	}
++	return error;
++}
++
++void
++ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		ext3_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext3_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static inline struct ext3_xattr_handler *
++ext3_xattr_resolve_name(const char **name)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext3_handler_lock);
++	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
++		if (ext3_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext3_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext3_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext3_handler_lock);
++	return handler;
++}
++
++static inline struct ext3_xattr_handler *
++ext3_xattr_handler(int name_index)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		read_lock(&ext3_handler_lock);
++		handler = ext3_xattr_handlers[name_index-1];
++		read_unlock(&ext3_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext3_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext3_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT3_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT3_I(inode)->i_file_acl)
++		return 0;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext3_xattr_update_super_block(handle_t *handle,
++					  struct super_block *sb)
++{
++	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT3_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext3_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_header *header = NULL;
++	struct ext3_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT3_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext3_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext3_error(sb, "ext3_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT3_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT3_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT3_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext3_xattr_cache_remove(bh);
++			error = ext3_journal_get_write_access(handle, bh);
++			if (error)
++				goto cleanup;
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT3_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT3_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT3_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext3_xattr_set2(handle, inode, bh,NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT3_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT3_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT3_XATTR_PAD, 0,
++			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext3_xattr_rehash(header, here);
++
++	error = ext3_xattr_set2(handle, inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext3_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext3_xattr_set(): Update the file system.
++ */
++static int
++ext3_xattr_set2(handle_t *handle, struct inode *inode,
++		struct buffer_head *old_bh, struct ext3_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext3_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext3_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			error = ext3_journal_get_write_access(handle, new_bh);
++			if (error)
++				goto cleanup;
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext3_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT3_I(inode)->i_file_acl != 0;
++			int block = ext3_xattr_new_block(handle, inode,
++							 &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++getblk_failed:			ext3_xattr_free_block(handle, inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			error = ext3_journal_get_create_access(handle, new_bh);
++			if (error) {
++				unlock_buffer(new_bh);
++				goto getblk_failed;
++			}
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext3_xattr_cache_insert(new_bh);
++			
++			ext3_xattr_update_super_block(handle, sb);
++		}
++		error = ext3_journal_dirty_metadata(handle, new_bh);
++		if (error)
++			goto cleanup;
++	}
++
++	/* Update the inode. */
++	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		error = ext3_journal_get_write_access(handle, old_bh);
++		if (error)
++			goto cleanup;
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
++
++			/* ext3_forget() calls bforget() for us, but we
++			   let our caller release old_bh, so we need to
++			   duplicate the handle before. */
++			get_bh(old_bh);
++			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext3_xattr_quota_free(inode);
++			ext3_journal_dirty_metadata(handle, old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT3_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext3_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ext3_journal_get_write_access(handle, bh);
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext3_xattr_cache_remove(bh);
++		ext3_xattr_free_block(handle, inode, block);
++		ext3_forget(handle, 1, inode, bh, block);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		ext3_journal_dirty_metadata(handle, bh);
++		if (IS_SYNC(inode))
++			handle->h_sync = 1;
++		ext3_xattr_quota_free(inode);
++	}
++	EXT3_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext3_xattr_sem);
++}
++
++/*
++ * ext3_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext3_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++	mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++/*
++ * ext3_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext3_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext3_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext3_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext3_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext3_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext3_xattr_cmp(struct ext3_xattr_header *header1,
++	       struct ext3_xattr_header *header2)
++{
++	struct ext3_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT3_XATTR_NEXT(entry1);
++		entry2 = EXT3_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext3_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT3_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT3_XATTR_REFCOUNT_MAX);
++		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext3_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext3_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
++					 struct ext3_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext3_xattr_rehash(struct ext3_xattr_header *header,
++			      struct ext3_xattr_entry *entry)
++{
++	struct ext3_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext3_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT3_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext3_xattr(void)
++{
++	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext3_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++	if (ext3_xattr_cache)
++		mb_cache_destroy(ext3_xattr_cache);
++	ext3_xattr_cache = NULL;
++}
++
++#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
++
++int __init
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+Index: linux-2.4.22-vanilla/fs/ext3/xattr_user.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/xattr_user.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/xattr_user.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,111 @@
++/*
++ * linux/fs/ext3/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++# include <linux/ext3_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext3_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext3_xattr_user_list,
++	get:	ext3_xattr_user_get,
++	set:	ext3_xattr_user_set,
++};
++
++int __init
++init_ext3_xattr_user(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
++				   &ext3_xattr_user_handler);
++}
++
++void
++exit_ext3_xattr_user(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
++			      &ext3_xattr_user_handler);
++}
+Index: linux-2.4.22-vanilla/fs/jfs/jfs_xattr.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/jfs/jfs_xattr.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/jfs/jfs_xattr.h	2003-11-03 23:41:29.000000000 +0300
+@@ -52,8 +52,10 @@
+ #define	END_EALIST(ealist) \
+ 	((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
+ 
+-extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
+-extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
++extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
++			  int);
++extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
++			int);
+ extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
+ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
+ extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
+Index: linux-2.4.22-vanilla/fs/jfs/xattr.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/jfs/xattr.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/fs/jfs/xattr.c	2003-11-03 23:41:29.000000000 +0300
+@@ -641,7 +641,7 @@
+ }
+ 
+ static int can_set_xattr(struct inode *inode, const char *name,
+-			 void *value, size_t value_len)
++			 const void *value, size_t value_len)
+ {
+ 	if (IS_RDONLY(inode))
+ 		return -EROFS;
+@@ -660,7 +660,7 @@
+ 	return permission(inode, MAY_WRITE);
+ }
+ 
+-int __jfs_setxattr(struct inode *inode, const char *name, void *value,
++int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
+ 		   size_t value_len, int flags)
+ {
+ 	struct jfs_ea_list *ealist;
+@@ -799,7 +799,7 @@
+ 	return rc;
+ }
+ 
+-int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
++int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+ 		 size_t value_len, int flags)
+ {
+ 	if (value == NULL) {	/* empty EA, do not remove */
+Index: linux-2.4.22-vanilla/fs/mbcache.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/mbcache.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/mbcache.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,648 @@
++/*
++ * linux/fs/mbcache.c
++ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++/*
++ * Filesystem Meta Information Block Cache (mbcache)
++ *
++ * The mbcache caches blocks of block devices that need to be located
++ * by their device/block number, as well as by other criteria (such
++ * as the block's contents).
++ *
++ * There can only be one cache entry in a cache per device and block number.
++ * Additional indexes need not be unique in this sense. The number of
++ * additional indexes (=other criteria) can be hardwired at compile time
++ * or specified at cache create time.
++ *
++ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
++ * in the cache. A valid entry is in the main hash tables of the cache,
++ * and may also be in the lru list. An invalid entry is not in any hashes
++ * or lists.
++ *
++ * A valid cache entry is only in the lru list if no handles refer to it.
++ * Invalid cache entries will be freed when the last handle to the cache
++ * entry is released. Entries that cannot be freed immediately are put
++ * back on the lru list.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/cache_def.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/mbcache.h>
++
++
++#ifdef MB_CACHE_DEBUG
++# define mb_debug(f...) do { \
++		printk(KERN_DEBUG f); \
++		printk("\n"); \
++	} while (0)
++#define mb_assert(c) do { if (!(c)) \
++		printk(KERN_ERR "assertion " #c " failed\n"); \
++	} while(0)
++#else
++# define mb_debug(f...) do { } while(0)
++# define mb_assert(c) do { } while(0)
++#endif
++#define mb_error(f...) do { \
++		printk(KERN_ERR f); \
++		printk("\n"); \
++	} while(0)
++		
++MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
++MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++MODULE_LICENSE("GPL");
++#endif
++
++EXPORT_SYMBOL(mb_cache_create);
++EXPORT_SYMBOL(mb_cache_shrink);
++EXPORT_SYMBOL(mb_cache_destroy);
++EXPORT_SYMBOL(mb_cache_entry_alloc);
++EXPORT_SYMBOL(mb_cache_entry_insert);
++EXPORT_SYMBOL(mb_cache_entry_release);
++EXPORT_SYMBOL(mb_cache_entry_takeout);
++EXPORT_SYMBOL(mb_cache_entry_free);
++EXPORT_SYMBOL(mb_cache_entry_dup);
++EXPORT_SYMBOL(mb_cache_entry_get);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++EXPORT_SYMBOL(mb_cache_entry_find_first);
++EXPORT_SYMBOL(mb_cache_entry_find_next);
++#endif
++
++
++/*
++ * Global data: list of all mbcache's, lru list, and a spinlock for
++ * accessing cache data structures on SMP machines. The lru list is
++ * global across all mbcaches.
++ */
++
++static LIST_HEAD(mb_cache_list);
++static LIST_HEAD(mb_cache_lru_list);
++static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
++
++static inline int
++mb_cache_indexes(struct mb_cache *cache)
++{
++#ifdef MB_CACHE_INDEXES_COUNT
++	return MB_CACHE_INDEXES_COUNT;
++#else
++	return cache->c_indexes_count;
++#endif
++}
++
++/*
++ * What the mbcache registers as to get shrunk dynamically.
++ */
++
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
++
++static struct cache_definition mb_cache_definition = {
++	"mb_cache",
++	mb_cache_memory_pressure
++};
++
++
++static inline int
++__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
++{
++	return !list_empty(&ce->e_block_list);
++}
++
++
++static inline void
++__mb_cache_entry_unhash(struct mb_cache_entry *ce)
++{
++	int n;
++
++	if (__mb_cache_entry_is_hashed(ce)) {
++		list_del_init(&ce->e_block_list);
++		for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
++			list_del(&ce->e_indexes[n].o_list);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
++{
++	struct mb_cache *cache = ce->e_cache;
++
++	mb_assert(atomic_read(&ce->e_used) == 0);
++	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
++		/* free failed -- put back on the lru list
++		   for freeing later. */
++		spin_lock(&mb_cache_spinlock);
++		list_add(&ce->e_lru_list, &mb_cache_lru_list);
++		spin_unlock(&mb_cache_spinlock);
++	} else {
++		kmem_cache_free(cache->c_entry_cache, ce);
++		atomic_dec(&cache->c_entry_count);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
++{
++	if (atomic_dec_and_test(&ce->e_used)) {
++		if (__mb_cache_entry_is_hashed(ce))
++			list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
++		else {
++			spin_unlock(&mb_cache_spinlock);
++			__mb_cache_entry_forget(ce, GFP_KERNEL);
++			return;
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_memory_pressure()  memory pressure callback
++ *
++ * This function is called by the kernel memory management when memory
++ * gets low.
++ *
++ * @priority: Amount by which to shrink the cache (0 = highes priority)
++ * @gfp_mask: (ignored)
++ */
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int count = 0;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &mb_cache_list) {
++		struct mb_cache *cache =
++			list_entry(l, struct mb_cache, c_cache_list);
++		mb_debug("cache %s (%d)", cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++		count += atomic_read(&cache->c_entry_count);
++	}
++	mb_debug("trying to free %d of %d entries",
++		  count / (priority ? priority : 1), count);
++	if (priority)
++		count /= priority;
++	while (count-- && !list_empty(&mb_cache_lru_list)) {
++		struct mb_cache_entry *ce =
++			list_entry(mb_cache_lru_list.next,
++				   struct mb_cache_entry, e_lru_list);
++		list_del(&ce->e_lru_list);
++		__mb_cache_entry_unhash(ce);
++		list_add_tail(&ce->e_lru_list, &free_list);
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), gfp_mask);
++	}
++}
++
++
++/*
++ * mb_cache_create()  create a new cache
++ *
++ * All entries in one cache are equal size. Cache entries may be from
++ * multiple devices. If this is the first mbcache created, registers
++ * the cache with kernel memory management. Returns NULL if no more
++ * memory was available.
++ *
++ * @name: name of the cache (informal)
++ * @cache_op: contains the callback called when freeing a cache entry
++ * @entry_size: The size of a cache entry, including
++ *              struct mb_cache_entry
++ * @indexes_count: number of additional indexes in the cache. Must equal
++ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
++ *                 hardwired.
++ * @bucket_count: number of hash buckets
++ */
++struct mb_cache *
++mb_cache_create(const char *name, struct mb_cache_op *cache_op,
++		size_t entry_size, int indexes_count, int bucket_count)
++{
++	int m=0, n;
++	struct mb_cache *cache = NULL;
++
++	if(entry_size < sizeof(struct mb_cache_entry) +
++	   indexes_count * sizeof(struct mb_cache_entry_index))
++		return NULL;
++
++	MOD_INC_USE_COUNT;
++	cache = kmalloc(sizeof(struct mb_cache) +
++	                indexes_count * sizeof(struct list_head), GFP_KERNEL);
++	if (!cache)
++		goto fail;
++	cache->c_name = name;
++	cache->c_op.free = NULL;
++	if (cache_op)
++		cache->c_op.free = cache_op->free;
++	atomic_set(&cache->c_entry_count, 0);
++	cache->c_bucket_count = bucket_count;
++#ifdef MB_CACHE_INDEXES_COUNT
++	mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
++#else
++	cache->c_indexes_count = indexes_count;
++#endif
++	cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
++	                              GFP_KERNEL);
++	if (!cache->c_block_hash)
++		goto fail;
++	for (n=0; n<bucket_count; n++)
++		INIT_LIST_HEAD(&cache->c_block_hash[n]);
++	for (m=0; m<indexes_count; m++) {
++		cache->c_indexes_hash[m] = kmalloc(bucket_count *
++		                                 sizeof(struct list_head),
++		                                 GFP_KERNEL);
++		if (!cache->c_indexes_hash[m])
++			goto fail;
++		for (n=0; n<bucket_count; n++)
++			INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
++	}
++	cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
++		0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
++	if (!cache->c_entry_cache)
++		goto fail;
++
++	spin_lock(&mb_cache_spinlock);
++	list_add(&cache->c_cache_list, &mb_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	return cache;
++
++fail:
++	if (cache) {
++		while (--m >= 0)
++			kfree(cache->c_indexes_hash[m]);
++		if (cache->c_block_hash)
++			kfree(cache->c_block_hash);
++		kfree(cache);
++	}
++	MOD_DEC_USE_COUNT;
++	return NULL;
++}
++
++
++/*
++ * mb_cache_shrink()
++ *
++ * Removes all cache entires of a device from the cache. All cache entries
++ * currently in use cannot be freed, and thus remain in the cache.
++ *
++ * @cache: which cache to shrink
++ * @dev: which device's cache entries to shrink
++ */
++void
++mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_dev == dev) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++}
++
++
++/*
++ * mb_cache_destroy()
++ *
++ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
++ * and then destroys it. If this was the last mbcache, un-registers the
++ * mbcache from kernel memory management.
++ */
++void
++mb_cache_destroy(struct mb_cache *cache)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_cache == cache) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	list_del(&cache->c_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++
++	if (atomic_read(&cache->c_entry_count) > 0) {
++		mb_error("cache %s: %d orphaned entries",
++			  cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++	}
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
++	/* We don't have kmem_cache_destroy() in 2.2.x */
++	kmem_cache_shrink(cache->c_entry_cache);
++#else
++	kmem_cache_destroy(cache->c_entry_cache);
++#endif
++	for (n=0; n < mb_cache_indexes(cache); n++)
++		kfree(cache->c_indexes_hash[n]);
++	kfree(cache->c_block_hash);
++	kfree(cache);
++
++	MOD_DEC_USE_COUNT;
++}
++
++
++/*
++ * mb_cache_entry_alloc()
++ *
++ * Allocates a new cache entry. The new entry will not be valid initially,
++ * and thus cannot be looked up yet. It should be filled with data, and
++ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
++ * if no more memory was available.
++ */
++struct mb_cache_entry *
++mb_cache_entry_alloc(struct mb_cache *cache)
++{
++	struct mb_cache_entry *ce;
++
++	atomic_inc(&cache->c_entry_count);
++	ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
++	if (ce) {
++		INIT_LIST_HEAD(&ce->e_lru_list);
++		INIT_LIST_HEAD(&ce->e_block_list);
++		ce->e_cache = cache;
++		atomic_set(&ce->e_used, 1);
++	}
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_insert()
++ *
++ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
++ * the cache. After this, the cache entry can be looked up, but is not yet
++ * in the lru list as the caller still holds a handle to it. Returns 0 on
++ * success, or -EBUSY if a cache entry for that device + inode exists
++ * already (this may happen after a failed lookup, if another process has
++ * inserted the same cache entry in the meantime).
++ *
++ * @dev: device the cache entry belongs to
++ * @block: block number
++ * @keys: array of additional keys. There must be indexes_count entries
++ *        in the array (as specified when creating the cache).
++ */
++int
++mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
++		      unsigned long block, unsigned int keys[])
++{
++	struct mb_cache *cache = ce->e_cache;
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	int error = -EBUSY, n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block)
++			goto out;
++	}
++	__mb_cache_entry_unhash(ce);
++	ce->e_dev = dev;
++	ce->e_block = block;
++	list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
++	for (n=0; n<mb_cache_indexes(cache); n++) {
++		ce->e_indexes[n].o_key = keys[n];
++		bucket = keys[n] % cache->c_bucket_count;
++		list_add(&ce->e_indexes[n].o_list,
++		         &cache->c_indexes_hash[n][bucket]);
++	}
++out:
++	spin_unlock(&mb_cache_spinlock);
++	return error;
++}
++
++
++/*
++ * mb_cache_entry_release()
++ *
++ * Release a handle to a cache entry. When the last handle to a cache entry
++ * is released it is either freed (if it is invalid) or otherwise inserted
++ * in to the lru list.
++ */
++void
++mb_cache_entry_release(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_takeout()
++ *
++ * Take a cache entry out of the cache, making it invalid. The entry can later
++ * be re-inserted using mb_cache_entry_insert(), or released using
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_takeout(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_entry_free()
++ *
++ * This is equivalent to the sequence mb_cache_entry_takeout() --
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_free(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_dup()
++ *
++ * Duplicate a handle to a cache entry (does not duplicate the cache entry
++ * itself). After the call, both the old and the new handle must be released.
++ */
++struct mb_cache_entry *
++mb_cache_entry_dup(struct mb_cache_entry *ce)
++{
++	atomic_inc(&ce->e_used);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_get()
++ *
++ * Get a cache entry  by device / block number. (There can only be one entry
++ * in the cache per device and block.) Returns NULL if no such cache entry
++ * exists.
++ */
++struct mb_cache_entry *
++mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
++{
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		ce = list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			goto cleanup;
++		}
++	}
++	ce = NULL;
++
++cleanup:
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++
++static struct mb_cache_entry *
++__mb_cache_entry_find(struct list_head *l, struct list_head *head,
++		      int index, kdev_t dev, unsigned int key)
++{
++	while (l != head) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry,
++			           e_indexes[index].o_list);
++		if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			return ce;
++		}
++		l = l->next;
++	}
++	return NULL;
++}
++
++
++/*
++ * mb_cache_entry_find_first()
++ *
++ * Find the first cache entry on a given device with a certain key in
++ * an additional index. Additonal matches can be found with
++ * mb_cache_entry_find_next(). Returns NULL if no match was found.
++ *
++ * @cache: the cache to search
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
++			  unsigned int key)
++{
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = cache->c_indexes_hash[index][bucket].next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_find_next()
++ *
++ * Find the next cache entry on a given device with a certain key in an
++ * additional index. Returns NULL if no match could be found. The previous
++ * entry is atomatically released, so that mb_cache_entry_find_next() can
++ * be called like this:
++ *
++ * entry = mb_cache_entry_find_first();
++ * while (entry) {
++ * 	...
++ *	entry = mb_cache_entry_find_next(entry, ...);
++ * }
++ *
++ * @prev: The previous match
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
++			 unsigned int key)
++{
++	struct mb_cache *cache = prev->e_cache;
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = prev->e_indexes[index].o_list.next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	__mb_cache_entry_release_unlock(prev);
++	return ce;
++}
++
++#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
++
++static int __init init_mbcache(void)
++{
++	register_cache(&mb_cache_definition);
++	return 0;
++}
++
++static void __exit exit_mbcache(void)
++{
++	unregister_cache(&mb_cache_definition);
++}
++
++module_init(init_mbcache)
++module_exit(exit_mbcache)
++
+Index: linux-2.4.22-vanilla/include/asm-arm/unistd.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-arm/unistd.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-arm/unistd.h	2003-11-03 23:41:29.000000000 +0300
+@@ -250,7 +250,6 @@
+ #define __NR_security			(__NR_SYSCALL_BASE+223)
+ #define __NR_gettid			(__NR_SYSCALL_BASE+224)
+ #define __NR_readahead			(__NR_SYSCALL_BASE+225)
+-#if 0 /* allocated in 2.5 */
+ #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
+ #define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
+ #define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
+@@ -263,7 +262,6 @@
+ #define __NR_removexattr		(__NR_SYSCALL_BASE+235)
+ #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
+ #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
+-#endif
+ #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+ #if 0 /* allocated in 2.5 */
+ #define __NR_sendfile64                 (__NR_SYSCALL_BASE+239)
+Index: linux-2.4.22-vanilla/include/asm-ppc64/unistd.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-ppc64/unistd.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-ppc64/unistd.h	2003-11-03 23:41:29.000000000 +0300
+@@ -218,6 +218,7 @@
+ #define __NR_mincore		206
+ #define __NR_gettid		207
+ #define __NR_tkill		208
++#endif
+ #define __NR_setxattr		209
+ #define __NR_lsetxattr		210
+ #define __NR_fsetxattr		211
+@@ -230,6 +231,7 @@
+ #define __NR_removexattr	218
+ #define __NR_lremovexattr	219
+ #define __NR_fremovexattr	220
++#if 0 /* Reserved syscalls */
+ #define __NR_futex		221
+ #define __NR_sched_setaffinity	222     
+ #define __NR_sched_getaffinity	223
+Index: linux-2.4.22-vanilla/include/asm-s390/unistd.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-s390/unistd.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-s390/unistd.h	2003-11-03 23:41:29.000000000 +0300
+@@ -213,9 +213,18 @@
+ #define __NR_getdents64		220
+ #define __NR_fcntl64		221
+ #define __NR_readahead		222
+-/*
+- * Numbers 224-235 are reserved for posix acl
+- */
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ #define __NR_gettid		236
+ #define __NR_tkill		237
+ 
+Index: linux-2.4.22-vanilla/include/asm-s390x/unistd.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-s390x/unistd.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-s390x/unistd.h	2003-11-03 23:41:29.000000000 +0300
+@@ -181,9 +181,18 @@
+ #define __NR_mincore            218
+ #define __NR_madvise            219
+ #define __NR_readahead		222
+-/*
+- * Numbers 224-235 are reserved for posix acl
+- */
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
+ #define __NR_gettid		236
+ #define __NR_tkill		237
+ 
+Index: linux-2.4.22-vanilla/include/linux/cache_def.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/cache_def.h	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/cache_def.h	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,15 @@
++/*
++ * linux/cache_def.h
++ * Handling of caches defined in drivers, filesystems, ...
++ *
++ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++struct cache_definition {
++	const char *name;
++	void (*shrink)(int, unsigned int);
++	struct list_head link;
++};
++
++extern void register_cache(struct cache_definition *);
++extern void unregister_cache(struct cache_definition *);
+Index: linux-2.4.22-vanilla/include/linux/errno.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/errno.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/errno.h	2003-11-03 23:41:29.000000000 +0300
+@@ -23,4 +23,8 @@
+ 
+ #endif
+ 
++/* Defined for extended attributes */
++#define ENOATTR ENODATA		/* No such attribute */
++#define ENOTSUP EOPNOTSUPP	/* Operation not supported */
++
+ #endif
+Index: linux-2.4.22-vanilla/include/linux/ext2_fs.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/ext2_fs.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/ext2_fs.h	2003-11-03 23:41:29.000000000 +0300
+@@ -57,8 +57,6 @@
+  */
+ #define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT2_ROOT_INO		 2	/* Root inode */
+-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ 
+@@ -86,7 +84,6 @@
+ #else
+ # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+ #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -121,28 +118,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext2_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext2_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext2_group_desc
+@@ -314,6 +289,7 @@
+ #define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+ #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+ #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
++#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+ #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+@@ -397,6 +373,7 @@
+ 
+ #ifdef __KERNEL__
+ #define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
++#define EXT2_I(inode)	(&((inode)->u.ext2_i))
+ #else
+ /* Assume that user mode programs are passing in an ext2fs superblock, not
+  * a kernel struct super_block.  This will allow us to call the feature-test
+@@ -466,7 +443,7 @@
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008
+ #define EXT2_FEATURE_INCOMPAT_ANY		0xffffffff
+ 
+-#define EXT2_FEATURE_COMPAT_SUPP	0
++#define EXT2_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+ #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+@@ -624,8 +601,10 @@
+ 
+ /* namei.c */
+ extern struct inode_operations ext2_dir_inode_operations;
++extern struct inode_operations ext2_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext2_symlink_inode_operations;
+ extern struct inode_operations ext2_fast_symlink_inode_operations;
+ 
+ #endif	/* __KERNEL__ */
+Index: linux-2.4.22-vanilla/include/linux/ext2_xattr.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/ext2_xattr.h	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/ext2_xattr.h	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext2_xattr.h
++
++  On-disk format of extended attributes for the ext2 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT2_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT2_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT2_XATTR_INDEX_MAX			10
++#define EXT2_XATTR_INDEX_USER			1
++#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext2_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext2_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT2_XATTR_PAD_BITS		2
++#define EXT2_XATTR_PAD		(1<<EXT2_XATTR_PAD_BITS)
++#define EXT2_XATTR_ROUND		(EXT2_XATTR_PAD-1)
++#define EXT2_XATTR_LEN(name_len) \
++	(((name_len) + EXT2_XATTR_ROUND + \
++	sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
++#define EXT2_XATTR_NEXT(entry) \
++	( (struct ext2_xattr_entry *)( \
++	  (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
++#define EXT2_XATTR_SIZE(size) \
++	(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT2_FS_XATTR
++
++struct ext2_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
++extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
++
++extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
++extern int ext2_removexattr(struct dentry *, const char *);
++
++extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext2_xattr_list(struct inode *, char *, size_t);
++extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext2_xattr_delete_inode(struct inode *);
++extern void ext2_xattr_put_super(struct super_block *);
++
++extern int init_ext2_xattr(void) __init;
++extern void exit_ext2_xattr(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR */
++#  define ext2_setxattr		NULL
++#  define ext2_getxattr		NULL
++#  define ext2_listxattr	NULL
++#  define ext2_removexattr	NULL
++
++static inline int
++ext2_xattr_get(struct inode *inode, int name_index,
++	       const char *name, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++}
++
++static inline void
++ext2_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR */
++
++# ifdef CONFIG_EXT2_FS_XATTR_USER
++
++extern int init_ext2_xattr_user(void) __init;
++extern void exit_ext2_xattr_user(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR_USER */
++
++static inline int
++init_ext2_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr_user(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+Index: linux-2.4.22-vanilla/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/ext3_fs.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/ext3_fs.h	2003-11-03 23:41:29.000000000 +0300
+@@ -63,8 +63,6 @@
+  */
+ #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT3_ROOT_INO		 2	/* Root inode */
+-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
+@@ -94,7 +92,6 @@
+ #else
+ # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
+ #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -129,28 +126,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext3_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext3_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext3_group_desc
+@@ -344,6 +319,7 @@
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -521,7 +497,7 @@
+ #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+ 
+-#define EXT3_FEATURE_COMPAT_SUPP	0
++#define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
+ 					 EXT3_FEATURE_INCOMPAT_RECOVER)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+@@ -704,6 +680,7 @@
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
+ 
+ /* inode.c */
++extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+ 
+@@ -773,8 +750,10 @@
+ 
+ /* namei.c */
+ extern struct inode_operations ext3_dir_inode_operations;
++extern struct inode_operations ext3_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext3_symlink_inode_operations;
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
+ 
+Index: linux-2.4.22-vanilla/include/linux/ext3_jbd.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/ext3_jbd.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/ext3_jbd.h	2003-11-03 23:41:29.000000000 +0300
+@@ -30,13 +30,19 @@
+ 
+ #define EXT3_SINGLEDATA_TRANS_BLOCKS	8U
+ 
++/* Extended attributes may touch two data buffers, two bitmap buffers,
++ * and two group and summaries. */
++
++#define EXT3_XATTR_TRANS_BLOCKS		8
++
+ /* Define the minimum size for a transaction which modifies data.  This
+  * needs to take into account the fact that we may end up modifying two
+  * quota files too (one for the group, one for the user quota).  The
+  * superblock only gets updated once, of course, so don't bother
+  * counting that again for the quota updates. */
+ 
+-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
++#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
++					 EXT3_XATTR_TRANS_BLOCKS - 2)
+ 
+ extern int ext3_writepage_trans_blocks(struct inode *inode);
+ 
+Index: linux-2.4.22-vanilla/include/linux/ext3_xattr.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/ext3_xattr.h	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/ext3_xattr.h	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext3_xattr.h
++
++  On-disk format of extended attributes for the ext3 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT3_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT3_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT3_XATTR_INDEX_MAX			10
++#define EXT3_XATTR_INDEX_USER			1
++#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext3_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext3_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT3_XATTR_PAD_BITS		2
++#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
++#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
++#define EXT3_XATTR_LEN(name_len) \
++	(((name_len) + EXT3_XATTR_ROUND + \
++	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
++#define EXT3_XATTR_NEXT(entry) \
++	( (struct ext3_xattr_entry *)( \
++	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
++#define EXT3_XATTR_SIZE(size) \
++	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT3_FS_XATTR
++
++struct ext3_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
++extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
++
++extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
++extern int ext3_removexattr(struct dentry *, const char *);
++
++extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext3_xattr_list(struct inode *, char *, size_t);
++extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
++extern void ext3_xattr_put_super(struct super_block *);
++
++extern int init_ext3_xattr(void) __init;
++extern void exit_ext3_xattr(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR */
++#  define ext3_setxattr		NULL
++#  define ext3_getxattr		NULL
++#  define ext3_listxattr	NULL
++#  define ext3_removexattr	NULL
++
++static inline int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++}
++
++static inline void
++ext3_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT3_FS_XATTR */
++
++# ifdef CONFIG_EXT3_FS_XATTR_USER
++
++extern int init_ext3_xattr_user(void) __init;
++extern void exit_ext3_xattr_user(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR_USER */
++
++static inline int
++init_ext3_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr_user(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+Index: linux-2.4.22-vanilla/include/linux/fs.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/fs.h	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/fs.h	2003-11-03 23:41:29.000000000 +0300
+@@ -913,7 +913,7 @@
+ 	int (*setattr) (struct dentry *, struct iattr *);
+ 	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
+-	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
++	int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
+ 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+ 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+ 	int (*removexattr) (struct dentry *, const char *);
+Index: linux-2.4.22-vanilla/include/linux/mbcache.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/mbcache.h	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/mbcache.h	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,69 @@
++/*
++  File: linux/mbcache.h
++
++  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++/* Hardwire the number of additional indexes */
++#define MB_CACHE_INDEXES_COUNT 1
++
++struct mb_cache_entry;
++
++struct mb_cache_op {
++	int (*free)(struct mb_cache_entry *, int);
++};
++
++struct mb_cache {
++	struct list_head		c_cache_list;
++	const char			*c_name;
++	struct mb_cache_op		c_op;
++	atomic_t			c_entry_count;
++	int				c_bucket_count;
++#ifndef MB_CACHE_INDEXES_COUNT
++	int				c_indexes_count;
++#endif
++	kmem_cache_t			*c_entry_cache;
++	struct list_head		*c_block_hash;
++	struct list_head		*c_indexes_hash[0];
++};
++
++struct mb_cache_entry_index {
++	struct list_head		o_list;
++	unsigned int			o_key;
++};
++
++struct mb_cache_entry {
++	struct list_head		e_lru_list;
++	struct mb_cache			*e_cache;
++	atomic_t			e_used;
++	kdev_t				e_dev;
++	unsigned long			e_block;
++	struct list_head		e_block_list;
++	struct mb_cache_entry_index	e_indexes[0];
++};
++
++/* Functions on caches */
++
++struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
++				  int, int);
++void mb_cache_shrink(struct mb_cache *, kdev_t);
++void mb_cache_destroy(struct mb_cache *);
++
++/* Functions on cache entries */
++
++struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
++int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
++			  unsigned int[]);
++void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
++void mb_cache_entry_release(struct mb_cache_entry *);
++void mb_cache_entry_takeout(struct mb_cache_entry *);
++void mb_cache_entry_free(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
++					  unsigned long);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
++						 kdev_t, unsigned int);
++struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
++						kdev_t, unsigned int);
++#endif
+Index: linux-2.4.22-vanilla/kernel/ksyms.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/kernel/ksyms.c	2003-11-03 23:41:26.000000000 +0300
++++ linux-2.4.22-vanilla/kernel/ksyms.c	2003-11-03 23:41:29.000000000 +0300
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/slab.h>
++#include <linux/cache_def.h>
+ #include <linux/module.h>
+ #include <linux/blkdev.h>
+ #include <linux/cdrom.h>
+@@ -91,6 +92,7 @@
+ EXPORT_SYMBOL(exit_files);
+ EXPORT_SYMBOL(exit_fs);
+ EXPORT_SYMBOL(exit_sighand);
++EXPORT_SYMBOL(copy_fs_struct);
+ 
+ /* internal kernel memory management */
+ EXPORT_SYMBOL(_alloc_pages);
+@@ -109,6 +111,8 @@
+ EXPORT_SYMBOL(kmem_cache_alloc);
+ EXPORT_SYMBOL(kmem_cache_free);
+ EXPORT_SYMBOL(kmem_cache_size);
++EXPORT_SYMBOL(register_cache);
++EXPORT_SYMBOL(unregister_cache);
+ EXPORT_SYMBOL(kmalloc);
+ EXPORT_SYMBOL(kfree);
+ EXPORT_SYMBOL(vfree);
+Index: linux-2.4.22-vanilla/mm/vmscan.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/vmscan.c	2003-11-03 23:41:27.000000000 +0300
++++ linux-2.4.22-vanilla/mm/vmscan.c	2003-11-03 23:41:29.000000000 +0300
+@@ -18,6 +18,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/swap.h>
+ #include <linux/swapctl.h>
++#include <linux/cache_def.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pagemap.h>
+ #include <linux/init.h>
+@@ -34,6 +35,39 @@
+  */
+ #define DEF_PRIORITY (6)
+ 
++static DECLARE_MUTEX(other_caches_sem);
++static LIST_HEAD(cache_definitions);
++
++void register_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_add(&cache->link, &cache_definitions);
++	up(&other_caches_sem);
++}
++
++void unregister_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_del(&cache->link);
++	up(&other_caches_sem);
++}
++
++static void shrink_other_caches(unsigned int priority, int gfp_mask)
++{
++	struct list_head *p;
++
++	if (down_trylock(&other_caches_sem))
++		return;
++
++	list_for_each_prev(p, &cache_definitions) {
++		struct cache_definition *cache =
++			list_entry(p, struct cache_definition, link);
++
++		cache->shrink(priority, gfp_mask);
++	}
++	up(&other_caches_sem);
++}
++
+ /*
+  * The swap-out function returns 1 if it successfully
+  * scanned all the pages it was asked to (`count').
+@@ -577,6 +611,7 @@
+ 
+ 	shrink_dcache_memory(priority, gfp_mask);
+ 	shrink_icache_memory(priority, gfp_mask);
++	shrink_other_caches(priority, gfp_mask);
+ #ifdef CONFIG_QUOTA
+ 	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+ #endif
+Index: linux-2.4.22-vanilla/fs/ext3/ext3-exports.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/ext3/ext3-exports.c	2003-11-03 23:41:29.000000000 +0300
++++ linux-2.4.22-vanilla/fs/ext3/ext3-exports.c	2003-11-03 23:41:29.000000000 +0300
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
diff --git a/lustre/kernel_patches/patches/listman-2.4.18.patch b/lustre/kernel_patches/patches/listman-2.4.18.patch
new file mode 100644
index 0000000000000000000000000000000000000000..37535c0963534204b8ae91c93608740836c8c4f8
--- /dev/null
+++ b/lustre/kernel_patches/patches/listman-2.4.18.patch
@@ -0,0 +1,21 @@
+Index: linux-2.4.18-chaos/include/linux/list.h
+===================================================================
+--- linux-2.4.18-chaos.orig/include/linux/list.h	2003-10-22 13:43:39.000000000 +0400
++++ linux-2.4.18-chaos/include/linux/list.h	2003-10-22 13:44:17.000000000 +0400
+@@ -173,6 +173,16 @@
+ 	for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
+         	pos = pos->prev, prefetch(pos->prev))
+         	
++/* 2.5 uses hlists for some things, like the d_hash.  we'll treat them
++ * as 2.5 and let macros drop back.. */
++#define hlist_entry                     list_entry
++#define hlist_head                      list_head
++#define hlist_node                      list_head
++#define HLIST_HEAD                      LIST_HEAD
++#define INIT_HLIST_HEAD                 INIT_LIST_HEAD
++#define hlist_del_init                  list_del_init
++#define hlist_add_head                  list_add
++#define hlist_for_each_safe             list_for_each_safe
+ 
+ #endif /* __KERNEL__ || _LVM_H_INCLUDE */
+ 
diff --git a/lustre/kernel_patches/patches/listman-2.4.20.patch b/lustre/kernel_patches/patches/listman-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1e4508b723cf4846a4f7b37257a13884ffc7f5ca
--- /dev/null
+++ b/lustre/kernel_patches/patches/listman-2.4.20.patch
@@ -0,0 +1,22 @@
+Index: linux-2.4.20/include/linux/list.h
+===================================================================
+--- linux-2.4.20.orig/include/linux/list.h	2003-10-17 23:56:26.000000000 +0400
++++ linux-2.4.20/include/linux/list.h	2003-10-22 14:02:22.000000000 +0400
+@@ -227,6 +227,17 @@
+ 	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
+ 		     prefetch(pos->member.next))
+ 
++/* 2.5 uses hlists for some things, like the d_hash.  we'll treat them
++ * as 2.5 and let macros drop back.. */
++#define hlist_entry                     list_entry
++#define hlist_head                      list_head
++#define hlist_node                      list_head
++#define HLIST_HEAD                      LIST_HEAD
++#define INIT_HLIST_HEAD                 INIT_LIST_HEAD
++#define hlist_del_init                  list_del_init
++#define hlist_add_head                  list_add
++#define hlist_for_each_safe             list_for_each_safe
++
+ #endif /* __KERNEL__ || _LVM_H_INCLUDE */
+ 
+ #endif
diff --git a/lustre/kernel_patches/patches/lkcd-cvs-2.5.69.patch b/lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test6.patch
similarity index 96%
rename from lustre/kernel_patches/patches/lkcd-cvs-2.5.69.patch
rename to lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test6.patch
index ee9490955d32b5766a3111c9e8dad8377b424ced..d9f714547162897379d91cb91eba75ed45d6fc96 100644
--- a/lustre/kernel_patches/patches/lkcd-cvs-2.5.69.patch
+++ b/lustre/kernel_patches/patches/lkcd-cvs-2.6.0-test6.patch
@@ -1,5 +1,9 @@
---- linux-2.5.69/drivers/dump/Makefile.lkcdbase	Mon Jun  2 17:29:39 2003
-+++ linux-2.5.69/drivers/dump/Makefile	Fri Apr 25 00:24:15 2003
+ 0 files changed
+
+Index: linux-2.6.0-test5/drivers/dump/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/Makefile	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/Makefile	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,14 @@
 +#
 +# Makefile for the dump device drivers.
@@ -15,8 +19,10 @@
 +obj-$(CONFIG_CRASH_DUMP_NETDEV)	+= dump_netdev.o
 +obj-$(CONFIG_CRASH_DUMP_COMPRESS_RLE)	+= dump_rle.o
 +obj-$(CONFIG_CRASH_DUMP_COMPRESS_GZIP)	+= dump_gzip.o
---- linux-2.5.69/drivers/dump/dump_blockdev.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_blockdev.c	Sun May 18 22:30:52 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_blockdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_blockdev.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_blockdev.c	2003-09-26 14:29:10.000000000 +0800
 @@ -0,0 +1,461 @@
 +/*
 + * Implements the dump driver interface for saving a dump to 
@@ -218,7 +224,7 @@
 +	}
 +
 +	/* assign the new dump dev structure */
-+	dump_bdev->kdev_id = to_kdev_t((dev_t)arg);
++	dump_bdev->kdev_id = new_decode_dev((dev_t)arg);
 +	dump_bdev->bdev = bdev;
 +
 +	/* make a note of the limit */
@@ -237,8 +243,8 @@
 +	}
 +
 +	printk("Block device (%d,%d) successfully configured for dumping\n",
-+	       major(dump_bdev->kdev_id),
-+	       minor(dump_bdev->kdev_id));
++	       MAJOR(dump_bdev->kdev_id),
++	       MINOR(dump_bdev->kdev_id));
 +
 +
 +	/* after opening the block device, return */
@@ -309,7 +315,7 @@
 +	__dump_irq_enable();
 +
 +	printk("Dumping to block device (%d,%d) on CPU %d ...\n",
-+	       major(dump_bdev->kdev_id), minor(dump_bdev->kdev_id),
++	       MAJOR(dump_bdev->kdev_id), MINOR(dump_bdev->kdev_id),
 +	       smp_processor_id());
 +	
 +	return 0;
@@ -479,8 +485,10 @@
 +
 +module_init(dump_blockdev_init);
 +module_exit(dump_blockdev_cleanup);
---- linux-2.5.69/drivers/dump/dump_execute.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_execute.c	Fri Feb  7 06:47:58 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_execute.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_execute.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_execute.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,126 @@
 +/*
 + * The file has the common/generic dump execution code 
@@ -608,8 +616,10 @@
 +
 +	return ret;
 +}
---- linux-2.5.69/drivers/dump/dump_filters.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_filters.c	Mon Feb  3 05:06:28 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_filters.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_filters.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_filters.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,143 @@
 +/*
 + * Default filters to select data to dump for various passes.
@@ -754,9 +764,11 @@
 +	{ .name = "", .selector = NULL, .level_mask = 0}
 +};
 +
---- linux-2.5.69/drivers/dump/dump_fmt.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_fmt.c	Fri Feb  7 06:47:58 2003
-@@ -0,0 +1,395 @@
+Index: linux-2.6.0-test5/drivers/dump/dump_fmt.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_fmt.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_fmt.c	2003-09-26 14:26:34.000000000 +0800
+@@ -0,0 +1,399 @@
 +/*
 + * Implements the routines which handle the format specific
 + * aspects of dump for the default dump format.
@@ -852,6 +864,8 @@
 +static int lcrash_init_dump_header(const char *panic_str)
 +{
 +	struct timeval dh_time;
++	struct sysinfo info;
++
 +	/* make sure the dump header isn't TOO big */
 +	if ((sizeof(struct __dump_header) +
 +		sizeof(struct __dump_header_asm)) > DUMP_BUFFER_SIZE) {
@@ -870,6 +884,8 @@
 +	dump_header.dh_memory_start = PAGE_OFFSET;
 +	dump_header.dh_memory_end = DUMP_MAGIC_NUMBER;
 +	dump_header.dh_header_size = sizeof(struct __dump_header);
++	si_meminfo(&info);
++	dump_header.dh_memory_size = (u64)info.totalram;
 +	dump_header.dh_page_size = PAGE_SIZE;
 +	dump_header.dh_dump_level = dump_config.level;
 +	dump_header.dh_current_task = (unsigned long) current;
@@ -877,7 +893,7 @@
 +		compress_type;
 +	dump_header.dh_dump_flags = dump_config.flags;
 +	dump_header.dh_dump_device = dump_config.dumper->dev->device_id; 
-+
++	
 +#if DUMP_DEBUG >= 6
 +	dump_header.dh_num_bytes = 0;
 +#endif
@@ -1152,8 +1168,10 @@
 +	.ops	= &dump_fmt_lcrash_ops
 +};
 +
---- linux-2.5.69/drivers/dump/dump_gzip.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_gzip.c	Fri Dec 13 00:51:31 2002
+Index: linux-2.6.0-test5/drivers/dump/dump_gzip.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_gzip.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_gzip.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,118 @@
 +/*
 + * GZIP Compression functions for kernel crash dumps.
@@ -1273,8 +1291,10 @@
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
 +MODULE_DESCRIPTION("Gzip compression module for crash dump driver");
---- linux-2.5.69/drivers/dump/dump_i386.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_i386.c	Wed Mar  5 02:49:22 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_i386.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_i386.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_i386.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,329 @@
 +/*
 + * Architecture specific (i386) functions for Linux crash dumps.
@@ -1370,13 +1390,13 @@
 +
 +
 +#ifdef CONFIG_SMP
-+extern unsigned long irq_affinity[];
++extern cpumask_t irq_affinity[];
 +extern irq_desc_t irq_desc[];
 +extern void dump_send_ipi(void);
 +
 +static int dump_expect_ipi[NR_CPUS];
 +static atomic_t waiting_for_dump_ipi;
-+static unsigned long saved_affinity[NR_IRQS];
++static cpumask_t saved_affinity[NR_IRQS];
 +
 +extern void stop_this_cpu(void *); /* exported by i386 kernel */
 +
@@ -1458,11 +1478,11 @@
 +	int i;
 +	int cpu = smp_processor_id();
 +
-+	memcpy(saved_affinity, irq_affinity, NR_IRQS * sizeof(unsigned long));
++	memcpy(saved_affinity, irq_affinity, NR_IRQS * sizeof(cpumask_t));
 +	for (i = 0; i < NR_IRQS; i++) {
 +		if (irq_desc[i].handler == NULL)
 +			continue;
-+		irq_affinity[i] = 1UL << cpu;
++		irq_affinity[i] = cpumask_of_cpu(cpu);
 +		if (irq_desc[i].handler->set_affinity != NULL)
 +			irq_desc[i].handler->set_affinity(i, irq_affinity[i]);
 +	}
@@ -1605,8 +1625,10 @@
 +	return pfn_is_ram(index);
 +}
 +
---- linux-2.5.69/drivers/dump/dump_memdev.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_memdev.c	Tue Mar 25 21:34:35 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_memdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_memdev.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_memdev.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,640 @@
 +/*
 + * Implements the dump driver interface for saving a dump in available
@@ -2248,9 +2270,11 @@
 +/* may be overwritten if a previous dump exists */
 +struct dump_memdev *dump_memdev = &default_dump_memdev;
 +
---- linux-2.5.69/drivers/dump/dump_netdev.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_netdev.c	Tue May 20 03:04:07 2003
-@@ -0,0 +1,863 @@
+Index: linux-2.6.0-test5/drivers/dump/dump_netdev.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_netdev.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_netdev.c	2003-09-26 14:26:34.000000000 +0800
+@@ -0,0 +1,880 @@
 +/*
 + * Implements the dump driver interface for saving a dump via network
 + * interface. 
@@ -2366,8 +2390,11 @@
 +	int count;
 +	unsigned long flags;
 +	int cpu = smp_processor_id();
++	struct softnet_data *softnet_data;
++       	
 +
-+        count=0;
++	softnet_data = &__get_cpu_var(softnet_data);
++	count=0;
 +	if (softnet_data[cpu].completion_queue) {
 +		struct sk_buff *clist;
 +	
@@ -2645,6 +2672,13 @@
 +                dump_send_skb(dev, buff + offset, 1024, &reply);
 +	}
 +}
++static void dump_do_sysrq(int key)
++{
++        struct pt_regs regs;
++        
++	get_current_regs(&regs);
++	handle_sysrq(key, &regs, NULL, NULL);
++}
 +
 +/*
 + * This function waits for the client to acknowledge the receipt
@@ -2822,7 +2856,14 @@
 +			dump_send_skb(dump_ndev, (char *)&dump_magic,
 +					sizeof(dump_magic), &reply);
 +			break;
-+
++                case COMM_SYSRQ:
++			dump_do_sysrq(req.from);
++			reply.code = REPLY_SYSRQ;
++			reply.nr = req.nr;
++			reply.info = req.from;
++			sprintf(tmp, "SYSRQ command %d \n", req.from);
++			dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
++			break;
 +		default:
 +			reply.code = REPLY_ERROR;
 +			reply.nr = req.nr;
@@ -3114,8 +3155,10 @@
 +
 +module_init(dump_netdev_init);
 +module_exit(dump_netdev_cleanup);
---- linux-2.5.69/drivers/dump/dump_overlay.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_overlay.c	Fri Feb  7 06:47:58 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_overlay.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_overlay.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_overlay.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,848 @@
 +/*
 + * Two-stage soft-boot based dump scheme methods (memory overlay
@@ -3965,8 +4008,10 @@
 +	.dev		= NULL,
 +};		
 +
---- linux-2.5.69/drivers/dump/dump_rle.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_rle.c	Fri Dec 13 00:51:31 2002
+Index: linux-2.6.0-test5/drivers/dump/dump_rle.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_rle.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_rle.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,175 @@
 +/*
 + * RLE Compression functions for kernel crash dumps.
@@ -4143,8 +4188,10 @@
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");
 +MODULE_DESCRIPTION("RLE compression module for crash dump driver");
---- linux-2.5.69/drivers/dump/dump_scheme.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_scheme.c	Fri Apr 25 00:24:15 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_scheme.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_scheme.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_scheme.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,357 @@
 +/* 
 + * Default single stage dump scheme methods
@@ -4503,8 +4550,10 @@
 +	.dev		= NULL,
 +};		
 +
---- linux-2.5.69/drivers/dump/dump_setup.c.lkcdbase	Mon Jun  2 17:29:49 2003
-+++ linux-2.5.69/drivers/dump/dump_setup.c	Tue Apr 29 03:37:19 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_setup.c
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_setup.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_setup.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,803 @@
 +/*
 + * Standard kernel function entry points for Linux crash dumps.
@@ -5309,8 +5358,10 @@
 +
 +module_init(dump_init);
 +module_exit(dump_cleanup);
---- linux-2.5.69/include/linux/dumpdev.h.lkcdbase	Mon Jun  2 17:28:52 2003
-+++ linux-2.5.69/include/linux/dumpdev.h	Mon Jun  2 17:31:01 2003
+Index: linux-2.6.0-test5/include/linux/dumpdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dumpdev.h	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/include/linux/dumpdev.h	2003-09-26 14:27:08.000000000 +0800
 @@ -0,0 +1,161 @@
 +/*
 + * Generic dump device interfaces for flexible system dump 
@@ -5371,7 +5422,7 @@
 +/* block */
 +struct dump_blockdev {
 +	struct dump_dev ddev;
-+	kdev_t kdev_id;
++	dev_t kdev_id;
 +	struct block_device *bdev;
 +	struct bio *bio;
 +	loff_t start_offset;
@@ -5473,8 +5524,10 @@
 +extern void dump_unregister_device(struct dump_dev *);
 +
 +#endif /*  _LINUX_DUMPDEV_H */
---- linux-2.5.69/include/linux/dump.h.lkcdbase	Mon Jun  2 17:28:56 2003
-+++ linux-2.5.69/include/linux/dump.h	Mon Jun  2 17:31:01 2003
+Index: linux-2.6.0-test5/include/linux/dump.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dump.h	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/include/linux/dump.h	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,376 @@
 +/*
 + * Kernel header file for Linux crash dumps.
@@ -5852,9 +5905,11 @@
 +#endif	/* !CONFIG_CRASH_DUMP */
 +
 +#endif /* _DUMP_H */
---- linux-2.5.69/include/linux/dump_netdev.h.lkcdbase	Mon Jun  2 17:29:01 2003
-+++ linux-2.5.69/include/linux/dump_netdev.h	Mon Jun  2 17:31:01 2003
-@@ -0,0 +1,80 @@
+Index: linux-2.6.0-test5/include/linux/dump_netdev.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/linux/dump_netdev.h	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/include/linux/dump_netdev.h	2003-09-26 14:26:34.000000000 +0800
+@@ -0,0 +1,82 @@
 +/*
 + *  linux/drivers/net/netconsole.h
 + *
@@ -5900,6 +5955,7 @@
 +	COMM_GET_REGS = 8,
 +	COMM_GET_MAGIC = 9,
 +	COMM_START_WRITE_NETDUMP_ACK = 10,
++	COMM_SYSRQ = 11,
 +};
 +
 +typedef struct netdump_req_s {
@@ -5924,6 +5980,7 @@
 +	REPLY_REGS = 10,
 +	REPLY_MAGIC = 11,
 +	REPLY_START_WRITE_NETDUMP = 12,
++	REPLY_SYSRQ = 13,
 +};
 +
 +typedef struct netdump_reply_s {
@@ -5935,8 +5992,10 @@
 +#define HEADER_LEN (1 + sizeof(reply_t))
 +
 +
---- linux-2.5.69/include/asm-i386/dump.h.lkcdbase	Mon Jun  2 17:28:47 2003
-+++ linux-2.5.69/include/asm-i386/dump.h	Mon Jun  2 17:31:10 2003
+Index: linux-2.6.0-test5/include/asm-i386/dump.h
+===================================================================
+--- linux-2.6.0-test5.orig/include/asm-i386/dump.h	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/include/asm-i386/dump.h	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,93 @@
 +/*
 + * Kernel header file for Linux crash dumps.
@@ -6003,7 +6062,7 @@
 +extern struct __dump_header_asm dump_header_asm;
 +
 +#ifdef CONFIG_SMP
-+extern unsigned long irq_affinity[];
++extern cpumask_t irq_affinity[];
 +extern int (*dump_ipi_function_ptr)(struct pt_regs *);
 +extern void dump_send_ipi(void);
 +#else
@@ -6031,8 +6090,10 @@
 +#endif /* __KERNEL__ */
 +
 +#endif /* _ASM_DUMP_H */
---- linux-2.5.69/init/kerntypes.c.lkcdbase	Mon Jun  2 17:29:10 2003
-+++ linux-2.5.69/init/kerntypes.c	Mon Jun  2 17:29:06 2003
+Index: linux-2.6.0-test5/init/kerntypes.c
+===================================================================
+--- linux-2.6.0-test5.orig/init/kerntypes.c	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/init/kerntypes.c	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,31 @@
 +/*
 + * kerntypes.c
@@ -6065,8 +6126,10 @@
 +kerntypes_dummy(void)
 +{
 +}
---- linux-2.5.69/drivers/dump/dump_methods.h.lkcdbase	Mon Jun  2 17:56:12 2003
-+++ linux-2.5.69/drivers/dump/dump_methods.h	Mon Jun  2 17:55:51 2003
+Index: linux-2.6.0-test5/drivers/dump/dump_methods.h
+===================================================================
+--- linux-2.6.0-test5.orig/drivers/dump/dump_methods.h	2003-09-26 14:26:34.000000000 +0800
++++ linux-2.6.0-test5/drivers/dump/dump_methods.h	2003-09-26 14:26:34.000000000 +0800
 @@ -0,0 +1,348 @@
 +/*
 + * Generic interfaces for flexible system dump 
@@ -6416,3 +6479,18 @@
 +
 +
 +#endif /*  _LINUX_DUMP_METHODS_H */
+Index: linux-2.6.0-test5/Makefile
+===================================================================
+--- linux-2.6.0-test5.orig/Makefile	2003-09-26 14:26:29.000000000 +0800
++++ linux-2.6.0-test5/Makefile	2003-09-26 14:26:34.000000000 +0800
+@@ -289,6 +289,10 @@
+ 
+ export MODVERDIR := .tmp_versions
+ 
++ifeq ($(CONFIG_CRASH_DUMP),)
++      CFLAGS += -g
++endif
++
+ # The temporary file to save gcc -MD generated dependencies must not
+ # contain a comma
+ comma := ,
diff --git a/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test1.patch b/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test1.patch
deleted file mode 100644
index 6b09ba1d9edd50c529dcb108d650bb9906431277..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test1.patch
+++ /dev/null
@@ -1,588 +0,0 @@
- arch/i386/Kconfig                           |   50 ++++++++++++++++++++++++++++
- arch/i386/boot/Makefile                     |    1 
- arch/i386/kernel/i386_ksyms.c               |   19 ++++++++++
- arch/i386/kernel/nmi.c                      |    2 +
- arch/i386/kernel/setup.c                    |    6 +++
- arch/i386/kernel/smp.c                      |   16 +++++++-
- arch/i386/kernel/traps.c                    |    2 +
- arch/i386/mm/init.c                         |    6 +++
- arch/s390/boot/Makefile                     |    2 -
- arch/s390/boot/install.sh                   |   24 +++++++++----
- drivers/Makefile                            |    1 
- include/asm-i386/kmap_types.h               |    5 +-
- include/asm-i386/mach-default/irq_vectors.h |    1 
- include/asm-i386/smp.h                      |    1 
- include/linux/major.h                       |    2 +
- init/Makefile                               |    4 ++
- init/main.c                                 |   10 +++++
- init/version.c                              |    4 ++
- kernel/ksyms.c                              |    8 ++++
- kernel/panic.c                              |   17 +++++++++
- kernel/sched.c                              |   22 ++++++++++++
- lib/Kconfig                                 |   10 +++--
- mm/page_alloc.c                             |    3 +
- scripts/mkcompile_h                         |    4 +-
- 24 files changed, 202 insertions(+), 18 deletions(-)
-
---- linux-2.6.0-test1/drivers/Makefile~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:37:15.000000000 -0600
-+++ linux-2.6.0-test1-braam/drivers/Makefile	2003-07-22 00:52:14.000000000 -0600
-@@ -49,3 +49,4 @@ obj-$(CONFIG_ISDN_BOOL)		+= isdn/
- obj-$(CONFIG_MCA)		+= mca/
- obj-$(CONFIG_EISA)		+= eisa/
- obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
-+obj-$(CONFIG_CRASH_DUMP)	+= dump/
---- linux-2.6.0-test1/include/linux/major.h~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:31:58.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/major.h	2003-07-22 00:52:14.000000000 -0600
-@@ -157,6 +157,8 @@
- 
- #define OSST_MAJOR		206	/* OnStream-SCx0 SCSI tape */
- 
-+#define CRASH_DUMP_MAJOR	221	/* crash dump interface */
-+
- #define IBM_TTY3270_MAJOR	227
- #define IBM_FS3270_MAJOR	228
- 
---- linux-2.6.0-test1/include/asm-i386/mach-default/irq_vectors.h~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:31:59.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/mach-default/irq_vectors.h	2003-07-22 00:52:14.000000000 -0600
-@@ -48,6 +48,7 @@
- #define INVALIDATE_TLB_VECTOR	0xfd
- #define RESCHEDULE_VECTOR	0xfc
- #define CALL_FUNCTION_VECTOR	0xfb
-+#define DUMP_VECTOR		0xfa
- 
- #define THERMAL_APIC_VECTOR	0xf0
- /*
---- linux-2.6.0-test1/include/asm-i386/kmap_types.h~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/kmap_types.h	2003-07-22 00:53:23.000000000 -0600
-@@ -1,4 +1,4 @@
--#ifndef _ASM_KMAP_TYPES_H
-+22#ifndef _ASM_KMAP_TYPES_H
- #define _ASM_KMAP_TYPES_H
- 
- #include <linux/config.h>
-@@ -26,7 +26,8 @@ D(12)	KM_IRQ0,
- D(13)	KM_IRQ1,
- D(14)	KM_SOFTIRQ0,
- D(15)	KM_SOFTIRQ1,
--D(16)	KM_TYPE_NR
-+D(16)	KM_DUMP
-+D(17)	KM_TYPE_NR
- };
- 
- #undef D
---- linux-2.6.0-test1/include/asm-i386/smp.h~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/asm-i386/smp.h	2003-07-22 00:52:14.000000000 -0600
-@@ -38,6 +38,7 @@ extern int smp_num_siblings;
- extern int cpu_sibling_map[];
- 
- extern void smp_flush_tlb(void);
-+extern void dump_send_ipi(void);
- extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
- extern void smp_send_reschedule(int cpu);
- extern void smp_invalidate_rcv(void);		/* Process an NMI */
---- linux-2.6.0-test1/arch/i386/kernel/i386_ksyms.c~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:39:21.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/i386_ksyms.c	2003-07-22 00:52:14.000000000 -0600
-@@ -16,6 +16,7 @@
- #include <linux/tty.h>
- #include <linux/highmem.h>
- #include <linux/time.h>
-+#include <linux/nmi.h>
- 
- #include <asm/semaphore.h>
- #include <asm/processor.h>
-@@ -33,6 +34,7 @@
- #include <asm/tlbflush.h>
- #include <asm/nmi.h>
- #include <asm/edd.h>
-+#include <asm/e820.h>
- 
- extern void dump_thread(struct pt_regs *, struct user *);
- extern spinlock_t rtc_lock;
-@@ -209,3 +211,20 @@ EXPORT_SYMBOL(kmap_atomic_to_page);
- EXPORT_SYMBOL(edd);
- EXPORT_SYMBOL(eddnr);
- #endif
-+
-+#ifdef CONFIG_CRASH_DUMP_MODULE
-+#ifdef CONFIG_SMP
-+extern irq_desc_t irq_desc[NR_IRQS];
-+extern unsigned long irq_affinity[NR_IRQS];
-+extern void stop_this_cpu(void *);
-+EXPORT_SYMBOL(irq_desc);
-+EXPORT_SYMBOL(irq_affinity);
-+EXPORT_SYMBOL(stop_this_cpu);
-+EXPORT_SYMBOL(dump_send_ipi);
-+#endif
-+extern int pfn_is_ram(unsigned long);
-+EXPORT_SYMBOL(pfn_is_ram);
-+#ifdef ARCH_HAS_NMI_WATCHDOG
-+EXPORT_SYMBOL(touch_nmi_watchdog);
-+#endif
-+#endif
---- linux-2.6.0-test1/arch/i386/kernel/nmi.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/nmi.c	2003-07-22 00:52:14.000000000 -0600
-@@ -24,6 +24,7 @@
- #include <linux/kernel_stat.h>
- #include <linux/module.h>
- #include <linux/nmi.h>
-+#include <linux/dump.h>
- #include <linux/sysdev.h>
- 
- #include <asm/smp.h>
-@@ -449,6 +450,7 @@ void nmi_watchdog_tick (struct pt_regs *
- 			bust_spinlocks(1);
- 			printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip);
- 			show_registers(regs);
-+			dump("NMI Watchdog detected LOCKUP", regs);
- 			printk("console shuts up ...\n");
- 			console_silent();
- 			spin_unlock(&nmi_print_lock);
---- linux-2.6.0-test1/arch/i386/kernel/setup.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/setup.c	2003-07-22 00:52:14.000000000 -0600
-@@ -439,6 +439,7 @@ static void __init setup_memory_region(v
- 	print_memory_map(who);
- } /* setup_memory_region */
- 
-+unsigned long crashdump_addr = 0xdeadbeef;
- 
- static void __init parse_cmdline_early (char ** cmdline_p)
- {
-@@ -532,6 +533,9 @@ static void __init parse_cmdline_early (
- 		if (c == ' ' && !memcmp(from, "highmem=", 8))
- 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
- 	
-+		if (c == ' ' && !memcmp(from, "crashdump=", 10))
-+			crashdump_addr = memparse(from+10, &from); 
-+			
- 		c = *(from++);
- 		if (!c)
- 			break;
-@@ -914,6 +918,8 @@ static int __init noreplacement_setup(ch
- 
- __setup("noreplacement", noreplacement_setup); 
- 
-+extern void crashdump_reserve(void);
-+
- void __init setup_arch(char **cmdline_p)
- {
- 	unsigned long max_low_pfn;
---- linux-2.6.0-test1/arch/i386/kernel/smp.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/smp.c	2003-07-22 00:52:14.000000000 -0600
-@@ -19,6 +19,7 @@
- #include <linux/mc146818rtc.h>
- #include <linux/cache.h>
- #include <linux/interrupt.h>
-+#include <linux/dump.h>
- 
- #include <asm/mtrr.h>
- #include <asm/pgalloc.h>
-@@ -144,6 +145,13 @@ inline void __send_IPI_shortcut(unsigned
- 	 */
- 	cfg = __prepare_ICR(shortcut, vector);
- 
-+	if (vector == DUMP_VECTOR) {
-+		/*
-+		 * Setup DUMP IPI to be delivered as an NMI
-+		 */
-+		cfg = (cfg&~APIC_VECTOR_MASK)|APIC_DM_NMI;
-+	}
-+
- 	/*
- 	 * Send the IPI. The write to APIC_ICR fires this off.
- 	 */
-@@ -467,6 +475,11 @@ void flush_tlb_all(void)
- 	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
- }
- 
-+void dump_send_ipi(void)
-+{
-+	send_IPI_allbutself(DUMP_VECTOR);
-+}
-+
- /*
-  * this function sends a 'reschedule' IPI to another CPU.
-  * it goes straight through and wastes no time serializing
-@@ -555,7 +568,7 @@ int smp_call_function (void (*func) (voi
- 	return 0;
- }
- 
--static void stop_this_cpu (void * dummy)
-+void stop_this_cpu (void * dummy)
- {
- 	/*
- 	 * Remove this CPU:
-@@ -616,4 +629,3 @@ asmlinkage void smp_call_function_interr
- 		atomic_inc(&call_data->finished);
- 	}
- }
--
---- linux-2.6.0-test1/arch/i386/kernel/traps.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/kernel/traps.c	2003-07-22 00:52:14.000000000 -0600
-@@ -25,6 +25,7 @@
- #include <linux/highmem.h>
- #include <linux/kallsyms.h>
- #include <linux/ptrace.h>
-+#include <linux/dump.h>
- 
- #ifdef CONFIG_EISA
- #include <linux/ioport.h>
-@@ -322,6 +323,7 @@ void die(const char * str, struct pt_reg
- #endif
-  	CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
- 	show_registers(regs);
-+	dump((char *)str, regs);
- 	bust_spinlocks(0);
- 	spin_unlock_irq(&die_lock);
- 	if (in_interrupt())
---- linux-2.6.0-test1/arch/i386/mm/init.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/mm/init.c	2003-07-22 00:52:14.000000000 -0600
-@@ -186,6 +186,12 @@ static inline int page_is_ram(unsigned l
- 	return 0;
- }
- 
-+/* To enable modules to check if a page is in RAM */
-+int pfn_is_ram(unsigned long pfn)
-+{
-+	return (page_is_ram(pfn));
-+}
-+
- #ifdef CONFIG_HIGHMEM
- pte_t *kmap_pte;
- pgprot_t kmap_prot;
---- linux-2.6.0-test1/arch/i386/boot/Makefile~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:33:11.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/boot/Makefile	2003-07-22 00:52:14.000000000 -0600
-@@ -101,3 +101,4 @@ zlilo: $(BOOTIMAGE)
- 
- install: $(BOOTIMAGE)
- 	sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
-+	if [ -f init/kerntypes.o ]; then cp init/kerntypes.o $(INSTALL_PATH)/Kerntypes; fi
---- linux-2.6.0-test1/arch/i386/Kconfig~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/i386/Kconfig	2003-07-22 00:52:14.000000000 -0600
-@@ -1297,6 +1297,56 @@ source "arch/i386/oprofile/Kconfig"
- 
- menu "Kernel hacking"
- 
-+config CRASH_DUMP
-+	tristate "Crash dump support (EXPERIMENTAL)"
-+	depends on EXPERIMENTAL
-+	default n
-+	---help---
-+	  Say Y here to enable saving an image of system memory when a panic
-+	  or other error occurs. Dumps can also be forced with the SysRq+d
-+	  key if MAGIC_SYSRQ is enabled.
-+
-+config CRASH_DUMP_BLOCKDEV
-+	tristate "Crash dump block device driver"
-+	depends on CRASH_DUMP
-+	help
-+	  Say Y to allow saving crash dumps directly to a disk device.
-+
-+config CRASH_DUMP_NETDEV
-+	tristate "Crash dump network device driver"
-+	depends on CRASH_DUMP
-+	help
-+	  Say Y to allow saving crash dumps over a network device.
-+
-+config CRASH_DUMP_MEMDEV
-+	bool "Crash dump staged memory driver"
-+	depends on CRASH_DUMP
-+	help
-+	  Say Y to allow intermediate saving crash dumps in spare 
-+	  memory pages which would then be written out to disk
-+	  later.
-+
-+config CRASH_DUMP_SOFTBOOT
-+	bool "Save crash dump across a soft reboot"
-+	depends on CRASH_DUMP_MEMDEV
-+	help
-+	  Say Y to allow a crash dump to be preserved in memory
-+	  pages across a soft reboot and written out to disk
-+	  thereafter. For this to work, CRASH_DUMP must be 
-+	  configured as part of the kernel (not as a module).
-+
-+config CRASH_DUMP_COMPRESS_RLE
-+	tristate "Crash dump RLE compression"
-+	depends on CRASH_DUMP
-+	help
-+	  Say Y to allow saving dumps with Run Length Encoding compression.
-+
-+config CRASH_DUMP_COMPRESS_GZIP
-+	tristate "Crash dump GZIP compression"
-+	depends on CRASH_DUMP
-+	help
-+	  Say Y to allow saving dumps with Gnu Zip compression.
-+
- config DEBUG_KERNEL
- 	bool "Kernel debugging"
- 	help
---- linux-2.6.0-test1/arch/s390/boot/Makefile~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:39:33.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/s390/boot/Makefile	2003-07-22 00:52:14.000000000 -0600
-@@ -16,4 +16,4 @@ $(obj)/image: vmlinux FORCE
- 
- install: $(CONFIGURE) $(obj)/image
- 	sh -x $(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
--	      System.map Kerntypes "$(INSTALL_PATH)"
-+	      System.map init/kerntypes.o "$(INSTALL_PATH)"
---- linux-2.6.0-test1/arch/s390/boot/install.sh~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:35:17.000000000 -0600
-+++ linux-2.6.0-test1-braam/arch/s390/boot/install.sh	2003-07-22 00:52:14.000000000 -0600
-@@ -16,7 +16,8 @@
- #   $1 - kernel version
- #   $2 - kernel image file
- #   $3 - kernel map file
--#   $4 - default install path (blank if root directory)
-+#   $4 - kernel type file
-+#   $5 - default install path (blank if root directory)
- #
- 
- # User may have a custom install script
-@@ -26,13 +27,22 @@ if [ -x /sbin/installkernel ]; then exec
- 
- # Default install - same as make zlilo
- 
--if [ -f $4/vmlinuz ]; then
--	mv $4/vmlinuz $4/vmlinuz.old
-+if [ -f $5/vmlinuz ]; then
-+	mv $5/vmlinuz $5/vmlinuz.old
- fi
- 
--if [ -f $4/System.map ]; then
--	mv $4/System.map $4/System.old
-+if [ -f $5/System.map ]; then
-+	mv $5/System.map $5/System.old
- fi
- 
--cat $2 > $4/vmlinuz
--cp $3 $4/System.map
-+if [ -f $5/Kerntypes ]; then
-+	mv $5/Kerntypes $5/Kerntypes.old
-+fi
-+
-+cat $2 > $5/vmlinuz
-+cp $3 $5/System.map
-+
-+# copy the kernel type file if it exists
-+if [ -f $4 ]; then
-+	cp $4 $5/Kerntypes
-+fi
---- linux-2.6.0-test1/scripts/mkcompile_h~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:39:36.000000000 -0600
-+++ linux-2.6.0-test1-braam/scripts/mkcompile_h	2003-07-22 00:52:14.000000000 -0600
-@@ -33,7 +33,7 @@ UTS_VERSION="$UTS_VERSION `LANG=C date`"
- 
- UTS_LEN=64
- UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
--
-+LINUX_COMPILE_VERSION_ID="__linux_compile_version_id__`hostname | tr -c '[0-9A-Za-z\n]' '__'`_`LANG=C date | tr -c '[0-9A-Za-z\n]' '_'`"
- # Generate a temporary compile.h
- 
- ( echo /\* This file is auto generated, version $VERSION \*/
-@@ -55,6 +55,8 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}
-   fi
- 
-   echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -1`\"
-+  echo \#define LINUX_COMPILE_VERSION_ID $LINUX_COMPILE_VERSION_ID
-+  echo \#define LINUX_COMPILE_VERSION_ID_TYPE typedef char* "$LINUX_COMPILE_VERSION_ID""_t"
- ) > .tmpcompile
- 
- # Only replace the real compile.h if the new one is different,
---- linux-2.6.0-test1/kernel/ksyms.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/ksyms.c	2003-07-22 00:52:14.000000000 -0600
-@@ -60,6 +60,8 @@
- #include <linux/backing-dev.h>
- #include <linux/percpu_counter.h>
- #include <asm/checksum.h>
-+#include <linux/dump.h>
-+#include <linux/bootmem.h>
- 
- #if defined(CONFIG_PROC_FS)
- #include <linux/proc_fs.h>
-@@ -627,3 +629,9 @@ EXPORT_SYMBOL(ptrace_notify);
- EXPORT_SYMBOL(console_printk);
- 
- EXPORT_SYMBOL(current_kernel_time);
-+
-+#ifdef CONFIG_CRASH_DUMP_MODULE
-+EXPORT_SYMBOL(min_low_pfn);
-+EXPORT_SYMBOL(dump_oncpu);
-+EXPORT_SYMBOL(dump_function_ptr);
-+#endif
---- linux-2.6.0-test1/kernel/panic.c~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:38:38.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/panic.c	2003-07-22 00:52:14.000000000 -0600
-@@ -16,12 +16,16 @@
- #include <linux/init.h>
- #include <linux/sysrq.h>
- #include <linux/interrupt.h>
-+#ifdef CONFIG_KEXEC
-+#include <linux/kexec.h>
-+#endif
- 
- asmlinkage void sys_sync(void);	/* it's really int */
- 
- int panic_timeout;
- int panic_on_oops;
- int tainted;
-+void (*dump_function_ptr)(const char *, const struct pt_regs *) = 0;
- 
- struct notifier_block *panic_notifier_list;
- 
-@@ -54,6 +58,7 @@ NORET_TYPE void panic(const char * fmt, 
- 	va_start(args, fmt);
- 	vsnprintf(buf, sizeof(buf), fmt, args);
- 	va_end(args);
-+
- 	printk(KERN_EMERG "Kernel panic: %s\n",buf);
- 	if (in_interrupt())
- 		printk(KERN_EMERG "In interrupt handler - not syncing\n");
-@@ -76,6 +81,18 @@ NORET_TYPE void panic(const char * fmt, 
- 		 * We can't use the "normal" timers since we just panicked..
- 	 	 */
- 		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
-+#ifdef CONFIG_KEXEC
-+{
-+		struct kimage *image;
-+		image = xchg(&kexec_image, 0);
-+		if (image) {
-+			printk(KERN_EMERG "by starting a new kernel ..\n");
-+			mdelay(panic_timeout*1000);
-+			machine_kexec(image);
-+		}
-+}
-+#endif
-+
- 		mdelay(panic_timeout*1000);
- 		/*
- 		 *	Should we run the reboot notifier. For the moment Im
---- linux-2.6.0-test1/kernel/sched.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/sched.c	2003-07-22 00:52:14.000000000 -0600
-@@ -41,6 +41,9 @@
- #define cpu_to_node_mask(cpu) (cpu_online_map)
- #endif
- 
-+/* used to soft spin in sched while dump is in progress */
-+int dump_oncpu;
-+
- /*
-  * Convert user-nice values [ -20 ... 0 ... 19 ]
-  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
-@@ -1335,6 +1338,15 @@ asmlinkage void schedule(void)
- 	struct list_head *queue;
- 	int idx;
- 
-+ 	/*
-+	 * If crash dump is in progress, this other cpu's
-+	 * need to wait until it completes.
-+	 * NB: this code is optimized away for kernels without
-+	 * dumping enabled.
-+	 */
-+	if (unlikely(dump_oncpu))
-+		goto dump_scheduling_disabled;
-+
- 	/*
- 	 * Test if we are atomic.  Since do_exit() needs to call into
- 	 * schedule() atomically, we ignore that path for now.
-@@ -1422,6 +1434,16 @@ switch_tasks:
- 	preempt_enable_no_resched();
- 	if (test_thread_flag(TIF_NEED_RESCHED))
- 		goto need_resched;
-+
-+	return;
-+
-+ dump_scheduling_disabled:
-+	/* allow scheduling only if this is the dumping cpu */
-+	if (dump_oncpu != smp_processor_id()+1) {
-+		while (dump_oncpu)
-+			cpu_relax();
-+	}
-+	return;
- }
- 
- #ifdef CONFIG_PREEMPT
---- linux-2.6.0-test1/lib/Kconfig~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:34:43.000000000 -0600
-+++ linux-2.6.0-test1-braam/lib/Kconfig	2003-07-22 00:52:14.000000000 -0600
-@@ -17,14 +17,16 @@ config CRC32
- #
- config ZLIB_INFLATE
- 	tristate
--	default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y
--	default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m
-+	default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y || CRASH_DUMP_COMPRESS_GZIP=y
-+	default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m || CRASH_DUMP_COMPRESS_GZIP=m
- 
- config ZLIB_DEFLATE
- 	tristate
- 	default m if PPP_DEFLATE!=y && JFFS2_FS!=y && CRYPTO_DEFLATE!=y && \
--		(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m)
--	default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y
-+		(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m \
-+			|| CRASH_DUMP_COMPRESS_GZIP=m )
-+	default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y \
-+		|| CRASH_DUMP_COMPRESS_GZIP=y
- 
- endmenu
- 
---- linux-2.6.0-test1/mm/page_alloc.c~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:30:01.000000000 -0600
-+++ linux-2.6.0-test1-braam/mm/page_alloc.c	2003-07-22 00:52:14.000000000 -0600
-@@ -89,7 +89,8 @@ static void bad_page(const char *functio
- 	page->mapping = NULL;
- }
- 
--#ifndef CONFIG_HUGETLB_PAGE
-+#if !defined(CONFIG_HUGETLB_PAGE) && !defined(CONFIG_CRASH_DUMP) \
-+	&& !defined(CONFIG_CRASH_DUMP_MODULE)
- #define prep_compound_page(page, order) do { } while (0)
- #define destroy_compound_page(page, order) do { } while (0)
- #else
---- linux-2.6.0-test1/init/Makefile~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:33:12.000000000 -0600
-+++ linux-2.6.0-test1-braam/init/Makefile	2003-07-22 00:52:14.000000000 -0600
-@@ -9,6 +9,9 @@ mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mount
- mounts-$(CONFIG_BLK_DEV_INITRD)	+= do_mounts_initrd.o
- mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
- 
-+extra-$(CONFIG_CRASH_DUMP)	+= kerntypes.o
-+CFLAGS_kerntypes.o		:= -gstabs
-+
- # files to be removed upon make clean
- clean-files := ../include/linux/compile.h
- 
-@@ -24,3 +27,4 @@ $(obj)/version.o: include/linux/compile.
- include/linux/compile.h: FORCE
- 	@echo '  CHK     $@'
- 	@sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
-+
---- linux-2.6.0-test1/init/main.c~lkcd-kernel-changes-2.6.0-test1	2003-07-22 00:46:07.000000000 -0600
-+++ linux-2.6.0-test1-braam/init/main.c	2003-07-22 00:52:14.000000000 -0600
-@@ -100,6 +100,16 @@ extern void ipc_init(void);
- int system_running = 0;
- 
- /*
-+ * The kernel_magic value represents the address of _end, which allows
-+ * namelist tools to "match" each other respectively.  That way a tool
-+ * that looks at /dev/mem can verify that it is using the right System.map
-+ * file -- if kernel_magic doesn't equal the namelist value of _end,
-+ * something's wrong.
-+ */
-+extern unsigned long _end;
-+unsigned long *kernel_magic = &_end;
-+
-+/*
-  * Boot command-line arguments
-  */
- #define MAX_INIT_ARGS 8
---- linux-2.6.0-test1/init/version.c~lkcd-kernel-changes-2.6.0-test1	2003-07-13 21:34:03.000000000 -0600
-+++ linux-2.6.0-test1-braam/init/version.c	2003-07-22 00:52:14.000000000 -0600
-@@ -10,6 +10,7 @@
- #include <linux/uts.h>
- #include <linux/utsname.h>
- #include <linux/version.h>
-+#include <linux/stringify.h>
- 
- #define version(a) Version_ ## a
- #define version_string(a) version(a)
-@@ -28,3 +29,6 @@ struct new_utsname system_utsname = {
- const char *linux_banner = 
- 	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
- 	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
-+
-+const char *LINUX_COMPILE_VERSION_ID = __stringify(LINUX_COMPILE_VERSION_ID);
-+LINUX_COMPILE_VERSION_ID_TYPE;
-
-_
diff --git a/lustre/kernel_patches/patches/lkcd-kernel-changes-2.5.73.patch b/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test6.patch
similarity index 52%
rename from lustre/kernel_patches/patches/lkcd-kernel-changes-2.5.73.patch
rename to lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test6.patch
index ebe09e893c27688f0e1defe159a168e8995b3d75..fa429d517b731aa0c92729a4fa3117dac714040d 100644
--- a/lustre/kernel_patches/patches/lkcd-kernel-changes-2.5.73.patch
+++ b/lustre/kernel_patches/patches/lkcd-kernel-changes-2.6.0-test6.patch
@@ -1,42 +1,30 @@
+ 0 files changed
 
-
-
- arch/i386/Kconfig                           |   50 ++++++++++++++++++++++++++++
- arch/i386/boot/Makefile                     |    1 
- arch/i386/kernel/i386_ksyms.c               |   19 ++++++++++
- arch/i386/kernel/nmi.c                      |    2 +
- arch/i386/kernel/setup.c                    |   10 +++++
- arch/i386/kernel/smp.c                      |   16 +++++++-
- arch/i386/kernel/traps.c                    |    2 +
- arch/i386/mm/init.c                         |    6 +++
- arch/s390/boot/Makefile                     |    2 -
- arch/s390/boot/install.sh                   |   24 +++++++++----
- drivers/Makefile                            |    1 
- include/asm-i386/kmap_types.h               |    3 +
- include/asm-i386/mach-default/irq_vectors.h |    1 
- include/asm-i386/smp.h                      |    1 
- include/linux/major.h                       |    2 +
- include/linux/sysctl.h                      |    2 +
- init/Makefile                               |    4 ++
- init/main.c                                 |   10 +++++
- init/version.c                              |    4 ++
- kernel/ksyms.c                              |    8 ++++
- kernel/panic.c                              |   17 +++++++++
- kernel/sched.c                              |   22 ++++++++++++
- lib/Kconfig                                 |   10 +++--
- mm/page_alloc.c                             |    3 +
- scripts/mkcompile_h                         |    4 +-
- 25 files changed, 207 insertions(+), 17 deletions(-)
-
---- linux-2.5.73/drivers/Makefile~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:08 2003
-+++ linux-2.5.73-n9560/drivers/Makefile	Mon Jun 30 14:56:26 2003
-@@ -50,3 +50,4 @@ obj-$(CONFIG_ISDN_BOOL)		+= isdn/
+Index: linux-2.6.0-test6/drivers/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/drivers/Makefile	2003-09-28 08:50:41.000000000 +0800
++++ linux-2.6.0-test6/drivers/Makefile	2003-10-09 20:57:41.884807280 +0800
+@@ -49,3 +49,4 @@
  obj-$(CONFIG_MCA)		+= mca/
  obj-$(CONFIG_EISA)		+= eisa/
  obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 +obj-$(CONFIG_CRASH_DUMP)	+= dump/
---- linux-2.5.73/include/linux/major.h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:37 2003
-+++ linux-2.5.73-n9560/include/linux/major.h	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/include/linux/sysctl.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/sysctl.h	2003-10-09 20:52:02.839350024 +0800
++++ linux-2.6.0-test6/include/linux/sysctl.h	2003-10-09 20:57:41.885807128 +0800
+@@ -127,6 +127,7 @@
+ 	KERN_PANIC_ON_OOPS=57,  /* int: whether we will panic on an oops */
+ 	KERN_HPPA_PWRSW=58,	/* int: hppa soft-power enable */
+ 	KERN_HPPA_UNALIGNED=59,	/* int: hppa unaligned-trap enable */
++	KERN_DUMP=60,           /* directory: dump parameters */
+ };
+ 
+ 
+Index: linux-2.6.0-test6/include/linux/major.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/major.h	2003-09-28 08:50:13.000000000 +0800
++++ linux-2.6.0-test6/include/linux/major.h	2003-10-09 20:57:41.885807128 +0800
 @@ -157,6 +157,8 @@
  
  #define OSST_MAJOR		206	/* OnStream-SCx0 SCSI tape */
@@ -46,19 +34,10 @@
  #define IBM_TTY3270_MAJOR	227
  #define IBM_FS3270_MAJOR	228
  
---- linux-2.5.73/include/linux/sysctl.h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:55 2003
-+++ linux-2.5.73-n9560/include/linux/sysctl.h	Mon Jun 30 14:56:26 2003
-@@ -130,6 +130,8 @@ enum
- 	KERN_PIDMAX=55,		/* int: PID # limit */
-   	KERN_CORE_PATTERN=56,	/* string: pattern for core-file names */
- 	KERN_PANIC_ON_OOPS=57,  /* int: whether we will panic on an oops */
-+
-+	KERN_DUMP=60,		/* directory: dump parameters */
- };
- 
- 
---- linux-2.5.73/include/asm-i386/mach-default/irq_vectors.h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:38 2003
-+++ linux-2.5.73-n9560/include/asm-i386/mach-default/irq_vectors.h	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/include/asm-i386/mach-default/irq_vectors.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/mach-default/irq_vectors.h	2003-10-09 20:52:02.764361424 +0800
++++ linux-2.6.0-test6/include/asm-i386/mach-default/irq_vectors.h	2003-10-09 20:57:41.885807128 +0800
 @@ -48,6 +48,7 @@
  #define INVALIDATE_TLB_VECTOR	0xfd
  #define RESCHEDULE_VECTOR	0xfc
@@ -67,21 +46,24 @@
  
  #define THERMAL_APIC_VECTOR	0xf0
  /*
---- linux-2.5.73/include/asm-i386/kmap_types.h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:01 2003
-+++ linux-2.5.73-n9560/include/asm-i386/kmap_types.h	Mon Jun 30 14:56:26 2003
-@@ -24,7 +24,8 @@ D(10)	KM_IRQ0,
- D(11)	KM_IRQ1,
- D(12)	KM_SOFTIRQ0,
- D(13)	KM_SOFTIRQ1,
--D(14)	KM_TYPE_NR
-+D(14)	KM_TYPE_NR,
-+D(15)	KM_DUMP
+Index: linux-2.6.0-test6/include/asm-i386/kmap_types.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/kmap_types.h	2003-10-09 20:52:02.764361424 +0800
++++ linux-2.6.0-test6/include/asm-i386/kmap_types.h	2003-10-09 20:57:41.886806976 +0800
+@@ -33,6 +33,7 @@
+ 	 * Add new entries in pairs:
+ 	 * the 4G/4G virtual stack must be 8K aligned on each cpu.
+ 	 */
+-	KM_TYPE_NR
++	KM_DUMP,
++	KM_TYPE_NR,
  };
- 
- #undef D
---- linux-2.5.73/include/asm-i386/smp.h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:56 2003
-+++ linux-2.5.73-n9560/include/asm-i386/smp.h	Mon Jun 30 14:56:26 2003
-@@ -39,6 +39,7 @@ extern int smp_num_siblings;
+ #endif
+Index: linux-2.6.0-test6/include/asm-i386/smp.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/smp.h	2003-09-28 08:50:29.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/smp.h	2003-10-09 20:57:41.886806976 +0800
+@@ -37,6 +37,7 @@
  extern int cpu_sibling_map[];
  
  extern void smp_flush_tlb(void);
@@ -89,8 +71,10 @@
  extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
  extern void smp_send_reschedule(int cpu);
  extern void smp_invalidate_rcv(void);		/* Process an NMI */
---- linux-2.5.73/arch/i386/kernel/i386_ksyms.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:35 2003
-+++ linux-2.5.73-n9560/arch/i386/kernel/i386_ksyms.c	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/i386_ksyms.c	2003-10-09 20:56:19.104391816 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/i386_ksyms.c	2003-10-09 20:58:33.601945080 +0800
 @@ -16,6 +16,7 @@
  #include <linux/tty.h>
  #include <linux/highmem.h>
@@ -99,17 +83,17 @@
  
  #include <asm/semaphore.h>
  #include <asm/processor.h>
-@@ -33,6 +34,7 @@
- #include <asm/tlbflush.h>
+@@ -34,6 +35,7 @@
  #include <asm/nmi.h>
  #include <asm/edd.h>
+ #include <asm/ist.h>
 +#include <asm/e820.h>
- 
+ #include <asm/netconsole.h>
  extern void dump_thread(struct pt_regs *, struct user *);
  extern spinlock_t rtc_lock;
-@@ -208,3 +210,20 @@ EXPORT_SYMBOL(kmap_atomic_to_page);
- EXPORT_SYMBOL(edd);
- EXPORT_SYMBOL(eddnr);
+@@ -220,3 +222,20 @@
+ #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
+ EXPORT_SYMBOL(ist_info);
  #endif
 +
 +#ifdef CONFIG_CRASH_DUMP_MODULE
@@ -128,8 +112,10 @@
 +EXPORT_SYMBOL(touch_nmi_watchdog);
 +#endif
 +#endif
---- linux-2.5.73/arch/i386/kernel/nmi.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:55 2003
-+++ linux-2.5.73-n9560/arch/i386/kernel/nmi.c	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/nmi.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/nmi.c	2003-10-09 20:52:02.026473600 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/nmi.c	2003-10-09 20:57:41.887806824 +0800
 @@ -24,6 +24,7 @@
  #include <linux/kernel_stat.h>
  #include <linux/module.h>
@@ -138,7 +124,7 @@
  #include <linux/sysdev.h>
  
  #include <asm/smp.h>
-@@ -426,6 +427,7 @@ void nmi_watchdog_tick (struct pt_regs *
+@@ -460,6 +461,7 @@
  			bust_spinlocks(1);
  			printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip);
  			show_registers(regs);
@@ -146,9 +132,11 @@
  			printk("console shuts up ...\n");
  			console_silent();
  			spin_unlock(&nmi_print_lock);
---- linux-2.5.73/arch/i386/kernel/setup.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:44 2003
-+++ linux-2.5.73-n9560/arch/i386/kernel/setup.c	Mon Jun 30 14:56:26 2003
-@@ -438,6 +438,7 @@ static void __init setup_memory_region(v
+Index: linux-2.6.0-test6/arch/i386/kernel/setup.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/setup.c	2003-10-09 20:52:02.028473296 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/setup.c	2003-10-09 20:57:41.888806672 +0800
+@@ -471,6 +471,7 @@
  	print_memory_map(who);
  } /* setup_memory_region */
  
@@ -156,7 +144,7 @@
  
  static void __init parse_cmdline_early (char ** cmdline_p)
  {
-@@ -531,6 +532,9 @@ static void __init parse_cmdline_early (
+@@ -588,6 +589,9 @@
  		if (c == ' ' && !memcmp(from, "highmem=", 8))
  			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
  	
@@ -166,28 +154,19 @@
  		c = *(from++);
  		if (!c)
  			break;
-@@ -913,6 +917,8 @@ static int __init noreplacement_setup(ch
+@@ -1030,6 +1034,8 @@
  
  __setup("noreplacement", noreplacement_setup); 
  
 +extern void crashdump_reserve(void);
-+
- void __init setup_arch(char **cmdline_p)
- {
- 	unsigned long max_low_pfn;
-@@ -977,6 +983,10 @@ void __init setup_arch(char **cmdline_p)
- 	generic_apic_probe(*cmdline_p);
- #endif	
- 
-+#ifdef CONFIG_CRASH_DUMP_SOFTBOOT
-+	crashdump_reserve(); /* Preserve crash dump state from prev boot */
-+#endif
-+
- #ifdef CONFIG_ACPI_BOOT
- 	/*
- 	 * Parse the ACPI tables for possible boot-time SMP configuration.
---- linux-2.5.73/arch/i386/kernel/smp.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:32 2003
-+++ linux-2.5.73-n9560/arch/i386/kernel/smp.c	Mon Jun 30 16:01:58 2003
++ 
+ /*
+  * Determine if we were loaded by an EFI loader.  If so, then we have also been
+  * passed the efi memmap, systab, etc., so we should use these data structures
+Index: linux-2.6.0-test6/arch/i386/kernel/smp.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/smp.c	2003-10-09 20:52:02.031472840 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/smp.c	2003-10-09 20:57:41.889806520 +0800
 @@ -19,6 +19,7 @@
  #include <linux/mc146818rtc.h>
  #include <linux/cache.h>
@@ -196,7 +175,7 @@
  
  #include <asm/mtrr.h>
  #include <asm/pgalloc.h>
-@@ -144,6 +145,13 @@ inline void __send_IPI_shortcut(unsigned
+@@ -144,6 +145,13 @@
  	 */
  	cfg = __prepare_ICR(shortcut, vector);
  
@@ -210,8 +189,8 @@
  	/*
  	 * Send the IPI. The write to APIC_ICR fires this off.
  	 */
-@@ -450,6 +458,11 @@ void flush_tlb_all(void)
- 	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+@@ -477,6 +485,11 @@
+ 	send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
  }
  
 +void dump_send_ipi(void)
@@ -220,9 +199,9 @@
 +}
 +
  /*
-  * this function sends a 'reschedule' IPI to another CPU.
-  * it goes straight through and wastes no time serializing
-@@ -528,7 +541,7 @@ int smp_call_function (void (*func) (voi
+  * Structure and data for smp_call_function(). This is designed to minimise
+  * static memory requirements. It also looks cleaner.
+@@ -545,7 +558,7 @@
  	return 0;
  }
  
@@ -231,13 +210,15 @@
  {
  	/*
  	 * Remove this CPU:
-@@ -589,4 +602,3 @@ asmlinkage void smp_call_function_interr
+@@ -606,4 +619,3 @@
  		atomic_inc(&call_data->finished);
  	}
  }
 -
---- linux-2.5.73/arch/i386/kernel/traps.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:35 2003
-+++ linux-2.5.73-n9560/arch/i386/kernel/traps.c	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/arch/i386/kernel/traps.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/traps.c	2003-10-09 20:52:02.033472536 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/traps.c	2003-10-09 20:57:41.889806520 +0800
 @@ -25,6 +25,7 @@
  #include <linux/highmem.h>
  #include <linux/kallsyms.h>
@@ -246,18 +227,20 @@
  
  #ifdef CONFIG_EISA
  #include <linux/ioport.h>
-@@ -258,6 +259,7 @@ void die(const char * str, struct pt_reg
- 	handle_BUG(regs);
- 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+@@ -322,6 +323,7 @@
+ #endif
+  	CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
  	show_registers(regs);
 +	dump((char *)str, regs);
  	bust_spinlocks(0);
  	spin_unlock_irq(&die_lock);
  	if (in_interrupt())
---- linux-2.5.73/arch/i386/mm/init.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:06 2003
-+++ linux-2.5.73-n9560/arch/i386/mm/init.c	Mon Jun 30 14:56:26 2003
-@@ -189,6 +189,12 @@ static inline int page_is_ram(unsigned l
- 	return 0;
+Index: linux-2.6.0-test6/arch/i386/mm/init.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/mm/init.c	2003-10-09 20:52:02.041471320 +0800
++++ linux-2.6.0-test6/arch/i386/mm/init.c	2003-10-09 20:57:41.890806368 +0800
+@@ -115,6 +115,12 @@
+ 		SetPageReserved(page);
  }
  
 +/* To enable modules to check if a page is in RAM */
@@ -267,18 +250,22 @@
 +}
 +
  #ifdef CONFIG_HIGHMEM
- pte_t *kmap_pte;
- pgprot_t kmap_prot;
---- linux-2.5.73/arch/i386/boot/Makefile~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:42 2003
-+++ linux-2.5.73-n9560/arch/i386/boot/Makefile	Mon Jun 30 14:56:26 2003
-@@ -101,3 +101,4 @@ zlilo: $(BOOTIMAGE)
+ 
+ #ifndef CONFIG_DISCONTIGMEM
+Index: linux-2.6.0-test6/arch/i386/boot/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/boot/Makefile	2003-09-28 08:50:16.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/boot/Makefile	2003-10-09 20:57:41.890806368 +0800
+@@ -100,3 +100,4 @@
  
  install: $(BOOTIMAGE)
- 	sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+ 	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
 +	if [ -f init/kerntypes.o ]; then cp init/kerntypes.o $(INSTALL_PATH)/Kerntypes; fi
---- linux-2.5.73/arch/i386/Kconfig~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:34 2003
-+++ linux-2.5.73-n9560/arch/i386/Kconfig	Mon Jun 30 14:56:26 2003
-@@ -1347,6 +1347,56 @@ source "arch/i386/oprofile/Kconfig"
+Index: linux-2.6.0-test6/arch/i386/Kconfig
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/Kconfig	2003-10-09 20:52:01.999477704 +0800
++++ linux-2.6.0-test6/arch/i386/Kconfig	2003-10-09 20:57:41.891806216 +0800
+@@ -1239,6 +1239,56 @@
  
  menu "Kernel hacking"
  
@@ -335,16 +322,20 @@
  config DEBUG_KERNEL
  	bool "Kernel debugging"
  	help
---- linux-2.5.73/arch/s390/boot/Makefile~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:36 2003
-+++ linux-2.5.73-n9560/arch/s390/boot/Makefile	Mon Jun 30 14:56:26 2003
-@@ -16,4 +16,4 @@ $(obj)/image: vmlinux FORCE
+Index: linux-2.6.0-test6/arch/s390/boot/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/arch/s390/boot/Makefile	2003-09-28 08:51:21.000000000 +0800
++++ linux-2.6.0-test6/arch/s390/boot/Makefile	2003-10-09 20:57:41.892806064 +0800
+@@ -15,4 +15,4 @@
  
  install: $(CONFIGURE) $(obj)/image
  	sh -x $(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
 -	      System.map Kerntypes "$(INSTALL_PATH)"
 +	      System.map init/kerntypes.o "$(INSTALL_PATH)"
---- linux-2.5.73/arch/s390/boot/install.sh~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:57 2003
-+++ linux-2.5.73-n9560/arch/s390/boot/install.sh	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/arch/s390/boot/install.sh
+===================================================================
+--- linux-2.6.0-test6.orig/arch/s390/boot/install.sh	2003-09-28 08:50:30.000000000 +0800
++++ linux-2.6.0-test6/arch/s390/boot/install.sh	2003-10-09 20:57:41.892806064 +0800
 @@ -16,7 +16,8 @@
  #   $1 - kernel version
  #   $2 - kernel image file
@@ -355,7 +346,7 @@
  #
  
  # User may have a custom install script
-@@ -26,13 +27,22 @@ if [ -x /sbin/installkernel ]; then exec
+@@ -26,13 +27,22 @@
  
  # Default install - same as make zlilo
  
@@ -384,9 +375,11 @@
 +if [ -f $4 ]; then
 +	cp $4 $5/Kerntypes
 +fi
---- linux-2.5.73/scripts/mkcompile_h~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:36 2003
-+++ linux-2.5.73-n9560/scripts/mkcompile_h	Mon Jun 30 14:56:26 2003
-@@ -33,7 +33,7 @@ UTS_VERSION="$UTS_VERSION `LANG=C date`"
+Index: linux-2.6.0-test6/scripts/mkcompile_h
+===================================================================
+--- linux-2.6.0-test6.orig/scripts/mkcompile_h	2003-09-28 08:51:28.000000000 +0800
++++ linux-2.6.0-test6/scripts/mkcompile_h	2003-10-09 20:57:41.892806064 +0800
+@@ -33,7 +33,7 @@
  
  UTS_LEN=64
  UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
@@ -395,18 +388,20 @@
  # Generate a temporary compile.h
  
  ( echo /\* This file is auto generated, version $VERSION \*/
-@@ -55,6 +55,8 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}
+@@ -55,6 +55,8 @@
    fi
  
-   echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -1`\"
+   echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
 +  echo \#define LINUX_COMPILE_VERSION_ID $LINUX_COMPILE_VERSION_ID
 +  echo \#define LINUX_COMPILE_VERSION_ID_TYPE typedef char* "$LINUX_COMPILE_VERSION_ID""_t"
  ) > .tmpcompile
  
  # Only replace the real compile.h if the new one is different,
---- linux-2.5.73/kernel/ksyms.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:30 2003
-+++ linux-2.5.73-n9560/kernel/ksyms.c	Mon Jun 30 14:56:26 2003
-@@ -59,6 +59,8 @@
+Index: linux-2.6.0-test6/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/ksyms.c	2003-10-09 20:52:02.855347592 +0800
++++ linux-2.6.0-test6/kernel/ksyms.c	2003-10-09 20:57:41.893805912 +0800
+@@ -58,6 +58,8 @@
  #include <linux/backing-dev.h>
  #include <linux/percpu_counter.h>
  #include <asm/checksum.h>
@@ -415,7 +410,7 @@
  
  #if defined(CONFIG_PROC_FS)
  #include <linux/proc_fs.h>
-@@ -606,3 +608,9 @@ EXPORT_SYMBOL(ptrace_notify);
+@@ -378,3 +380,9 @@
  EXPORT_SYMBOL(console_printk);
  
  EXPORT_SYMBOL(current_kernel_time);
@@ -425,16 +420,18 @@
 +EXPORT_SYMBOL(dump_oncpu);
 +EXPORT_SYMBOL(dump_function_ptr);
 +#endif
---- linux-2.5.73/kernel/panic.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:18 2003
-+++ linux-2.5.73-n9560/kernel/panic.c	Mon Jun 30 14:56:26 2003
-@@ -16,12 +16,16 @@
- #include <linux/init.h>
- #include <linux/sysrq.h>
+Index: linux-2.6.0-test6/kernel/panic.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/panic.c	2003-09-28 08:51:05.000000000 +0800
++++ linux-2.6.0-test6/kernel/panic.c	2003-10-09 20:57:41.893805912 +0800
+@@ -18,11 +18,16 @@
  #include <linux/interrupt.h>
+ #include <linux/nmi.h>
+ 
 +#ifdef CONFIG_KEXEC
 +#include <linux/kexec.h>
 +#endif
- 
++
  asmlinkage void sys_sync(void);	/* it's really int */
  
  int panic_timeout;
@@ -444,7 +441,7 @@
  
  struct notifier_block *panic_notifier_list;
  
-@@ -54,6 +58,7 @@ NORET_TYPE void panic(const char * fmt, 
+@@ -55,6 +60,7 @@
  	va_start(args, fmt);
  	vsnprintf(buf, sizeof(buf), fmt, args);
  	va_end(args);
@@ -452,28 +449,31 @@
  	printk(KERN_EMERG "Kernel panic: %s\n",buf);
  	if (in_interrupt())
  		printk(KERN_EMERG "In interrupt handler - not syncing\n");
-@@ -76,6 +81,18 @@ NORET_TYPE void panic(const char * fmt, 
+@@ -78,6 +84,19 @@
  		 * We can't use the "normal" timers since we just panicked..
  	 	 */
  		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
 +#ifdef CONFIG_KEXEC
-+{
-+		struct kimage *image;
-+		image = xchg(&kexec_image, 0);
-+		if (image) {
-+			printk(KERN_EMERG "by starting a new kernel ..\n");
-+			mdelay(panic_timeout*1000);
-+			machine_kexec(image);
++		{
++ 			struct kimage *image;
++ 			image = xchg(&kexec_image, 0);
++ 			if (image) {
++ 				printk(KERN_EMERG "by starting a new kernel ..\n");
++ 				mdelay(panic_timeout*1000);
++ 				machine_kexec(image);
++ 			}
 +		}
-+}
 +#endif
++ 
 +
- 		mdelay(panic_timeout*1000);
- 		/*
- 		 *	Should we run the reboot notifier. For the moment Im
---- linux-2.5.73/kernel/sched.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:33:08 2003
-+++ linux-2.5.73-n9560/kernel/sched.c	Mon Jun 30 14:56:26 2003
-@@ -40,6 +40,9 @@
+ 		for (i = 0; i < panic_timeout; i++) {
+ 			touch_nmi_watchdog();
+ 			mdelay(1000);
+Index: linux-2.6.0-test6/kernel/sched.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/sched.c	2003-10-09 20:52:02.864346224 +0800
++++ linux-2.6.0-test6/kernel/sched.c	2003-10-09 20:57:41.895805608 +0800
+@@ -44,6 +44,9 @@
  #define cpu_to_node_mask(cpu) (cpu_online_map)
  #endif
  
@@ -483,8 +483,8 @@
  /*
   * Convert user-nice values [ -20 ... 0 ... 19 ]
   * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
-@@ -1249,6 +1252,15 @@ asmlinkage void schedule(void)
- 	struct list_head *queue;
+@@ -1463,6 +1466,15 @@
+ 	unsigned long run_time;
  	int idx;
  
 + 	/*
@@ -499,7 +499,7 @@
  	/*
  	 * Test if we are atomic.  Since do_exit() needs to call into
  	 * schedule() atomically, we ignore that path for now.
-@@ -1336,6 +1348,16 @@ switch_tasks:
+@@ -1586,6 +1598,16 @@
  	preempt_enable_no_resched();
  	if (test_thread_flag(TIF_NEED_RESCHED))
  		goto need_resched;
@@ -515,33 +515,36 @@
 +	return;
  }
  
- #ifdef CONFIG_PREEMPT
---- linux-2.5.73/lib/Kconfig~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:56 2003
-+++ linux-2.5.73-n9560/lib/Kconfig	Mon Jun 30 14:56:26 2003
-@@ -17,14 +17,16 @@ config CRC32
+ EXPORT_SYMBOL(schedule);
+Index: linux-2.6.0-test6/lib/Kconfig
+===================================================================
+--- linux-2.6.0-test6.orig/lib/Kconfig	2003-09-28 08:50:29.000000000 +0800
++++ linux-2.6.0-test6/lib/Kconfig	2003-10-09 20:57:41.895805608 +0800
+@@ -16,10 +16,17 @@
+ # compression support is select'ed if needed
  #
  config ZLIB_INFLATE
- 	tristate
--	default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y
--	default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m
-+	default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y || CRASH_DUMP_COMPRESS_GZIP=y
-+	default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m || CRASH_DUMP_COMPRESS_GZIP=m
+-	tristate
++  	tristate
++ 	default y if CRAMFS=y || PPP_DEFLATE=y || JFFS2_FS=y || ZISOFS_FS=y || BINFMT_ZFLAT=y || CRYPTO_DEFLATE=y || CRASH_DUMP_COMPRESS_GZIP=y
++ 	default m if CRAMFS=m || PPP_DEFLATE=m || JFFS2_FS=m || ZISOFS_FS=m || BINFMT_ZFLAT=m || CRYPTO_DEFLATE=m || CRASH_DUMP_COMPRESS_GZIP=m
  
  config ZLIB_DEFLATE
  	tristate
- 	default m if PPP_DEFLATE!=y && JFFS2_FS!=y && CRYPTO_DEFLATE!=y && \
--		(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m)
--	default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y
-+		(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m \
-+			|| CRASH_DUMP_COMPRESS_GZIP=m )
-+	default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y \
-+		|| CRASH_DUMP_COMPRESS_GZIP=y
- 
+-
++  	default m if PPP_DEFLATE!=y && JFFS2_FS!=y && CRYPTO_DEFLATE!=y && \
++ 		(PPP_DEFLATE=m || JFFS2_FS=m || CRYPTO_DEFLATE=m \
++ 			|| CRASH_DUMP_COMPRESS_GZIP=m )
++ 	default y if PPP_DEFLATE=y || JFFS2_FS=y || CRYPTO_DEFLATE=y \
++ 		|| CRASH_DUMP_COMPRESS_GZIP=y
++ 
  endmenu
  
---- linux-2.5.73/mm/page_alloc.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:32 2003
-+++ linux-2.5.73-n9560/mm/page_alloc.c	Mon Jun 30 14:56:26 2003
-@@ -84,7 +84,8 @@ static void bad_page(const char *functio
+Index: linux-2.6.0-test6/mm/page_alloc.c
+===================================================================
+--- linux-2.6.0-test6.orig/mm/page_alloc.c	2003-10-09 20:52:02.881343640 +0800
++++ linux-2.6.0-test6/mm/page_alloc.c	2003-10-09 20:57:41.897805304 +0800
+@@ -89,7 +89,8 @@
  	page->mapping = NULL;
  }
  
@@ -551,9 +554,11 @@
  #define prep_compound_page(page, order) do { } while (0)
  #define destroy_compound_page(page, order) do { } while (0)
  #else
---- linux-2.5.73/init/Makefile~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:42 2003
-+++ linux-2.5.73-n9560/init/Makefile	Mon Jun 30 14:56:26 2003
-@@ -9,6 +9,9 @@ mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mount
+Index: linux-2.6.0-test6/init/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/init/Makefile	2003-09-28 08:50:17.000000000 +0800
++++ linux-2.6.0-test6/init/Makefile	2003-10-09 20:57:41.897805304 +0800
+@@ -9,6 +9,9 @@
  mounts-$(CONFIG_BLK_DEV_INITRD)	+= do_mounts_initrd.o
  mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
  
@@ -563,14 +568,16 @@
  # files to be removed upon make clean
  clean-files := ../include/linux/compile.h
  
-@@ -24,3 +27,4 @@ $(obj)/version.o: include/linux/compile.
+@@ -24,3 +27,4 @@
  include/linux/compile.h: FORCE
  	@echo '  CHK     $@'
  	@sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
 +
---- linux-2.5.73/init/main.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:35 2003
-+++ linux-2.5.73-n9560/init/main.c	Mon Jun 30 14:56:26 2003
-@@ -101,6 +101,16 @@ extern void ipc_init(void);
+Index: linux-2.6.0-test6/init/main.c
+===================================================================
+--- linux-2.6.0-test6.orig/init/main.c	2003-10-09 20:52:02.850348352 +0800
++++ linux-2.6.0-test6/init/main.c	2003-10-09 20:57:41.897805304 +0800
+@@ -97,6 +97,16 @@
  int system_running = 0;
  
  /*
@@ -587,8 +594,10 @@
   * Boot command-line arguments
   */
  #define MAX_INIT_ARGS 8
---- linux-2.5.73/init/version.c~lkcd-kernel-changes-2.5.73	Sun Jun 22 11:32:45 2003
-+++ linux-2.5.73-n9560/init/version.c	Mon Jun 30 14:56:26 2003
+Index: linux-2.6.0-test6/init/version.c
+===================================================================
+--- linux-2.6.0-test6.orig/init/version.c	2003-09-28 08:50:20.000000000 +0800
++++ linux-2.6.0-test6/init/version.c	2003-10-09 20:57:41.898805152 +0800
 @@ -10,6 +10,7 @@
  #include <linux/uts.h>
  #include <linux/utsname.h>
@@ -597,12 +606,10 @@
  
  #define version(a) Version_ ## a
  #define version_string(a) version(a)
-@@ -24,3 +25,6 @@ struct new_utsname system_utsname = {
+@@ -28,3 +29,6 @@
  const char *linux_banner = 
  	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
  	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
 +
 +const char *LINUX_COMPILE_VERSION_ID = __stringify(LINUX_COMPILE_VERSION_ID);
 +LINUX_COMPILE_VERSION_ID_TYPE;
-
-_
diff --git a/lustre/kernel_patches/patches/lustre_version.patch b/lustre/kernel_patches/patches/lustre_version.patch
index 7a47d62904860398dc921b5ed02f12af06badf9c..86f514bb8b10f0fb6a145ed2a9debfd14dc5bf69 100644
--- a/lustre/kernel_patches/patches/lustre_version.patch
+++ b/lustre/kernel_patches/patches/lustre_version.patch
@@ -7,6 +7,6 @@
 --- /dev/null	Fri Aug 30 17:31:37 2002
 +++ linux-2.4.18-18.8.0-l12-braam/include/linux/lustre_version.h	Thu Feb 13 07:58:33 2003
 @@ -0,0 +1 @@
-+#define LUSTRE_KERNEL_VERSION 23
++#define LUSTRE_KERNEL_VERSION 32
 
 _
diff --git a/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch b/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c5f1ed03082fbed38bf2f7eb830a21edb8943a2a
--- /dev/null
+++ b/lustre/kernel_patches/patches/netconsole-2.4.20-rh.patch
@@ -0,0 +1,469 @@
+Index: linux-2.4.20-rh/drivers/net/netconsole.c
+===================================================================
+--- linux-2.4.20-rh.orig/drivers/net/netconsole.c	2003-07-22 16:02:23.000000000 +0800
++++ linux-2.4.20-rh/drivers/net/netconsole.c	2003-11-11 07:42:33.000000000 +0800
+@@ -12,6 +12,8 @@
+  *
+  * 2001-09-17    started by Ingo Molnar.
+  * 2002-03-14    simultaneous syslog packet option by Michael K. Johnson
++ * 2003-10-30    Add sysrq command processing by Wangdi <wangdi@clusterfs.com>
++ * 
+  */
+ 
+ /****************************************************************
+@@ -51,6 +53,7 @@
+ #include <linux/tty_driver.h>
+ #include <linux/etherdevice.h>
+ #include <linux/elf.h>
++#include "netconsole.h"
+ 
+ static struct net_device *netconsole_dev;
+ static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port;
+@@ -62,12 +65,11 @@
+ static unsigned int mhz = 500, idle_timeout;
+ static unsigned long long mhz_cycles, jiffy_cycles;
+ 
+-#include "netconsole.h"
+ 
+ #define MAX_UDP_CHUNK 1460
+ #define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
+ 
+-#define DEBUG 0
++#define DEBUG 0 
+ #if DEBUG
+ # define Dprintk(x...) printk(KERN_INFO x)
+ #else
+@@ -187,6 +189,22 @@
+ 		}
+ 	}
+ }
++void (*irqfunc)(int, void *, struct pt_regs *);
++
++static void netdump_poll(struct net_device *dev)
++{
++	int budget = 1;
++
++	disable_irq(dev->irq);
++	
++	irqfunc(dev->irq, dev, 0);
++	
++	if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state))
++	        dev->poll(dev, &budget);
++
++	enable_irq(dev->irq);
++
++}
+ 
+ static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve)
+ {
+@@ -209,7 +227,7 @@
+ 				once = 0;
+ 			}
+ 			Dprintk("alloc skb: polling controller ...\n");
+-			dev->poll_controller(dev);
++			netdump_poll(dev);
+ 			goto repeat;
+ 		}
+ 	}
+@@ -231,7 +249,7 @@
+ 		spin_unlock(&dev->xmit_lock);
+ 
+ 		Dprintk("xmit skb: polling controller ...\n");
+-		dev->poll_controller(dev);
++		netdump_poll(dev);
+ 		zap_completion_queue();
+ 		goto repeat_poll;
+ 	}
+@@ -426,18 +444,79 @@
+ static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+ static unsigned int log_offset;
+ 
++static int thread_stopped = 0;
++/*Interrupt function for netdump */
++static int sysrq_mode = 0;
++static int stop_sysrq_thread = 0;
++#define Set_Sysrq_mode()       (sysrq_mode = 1)
++#define Clear_Sysrq_mode()     (sysrq_mode = 0)
++static char send_cache[MAX_PRINT_CHUNK];
++static unsigned int send_cache_pos = 0;
++wait_queue_head_t sysrq_thread_queue;
++wait_queue_head_t sysrq_thread_waiter_queue;
++
++#define SEND_MSG_BUFFER(buf, len) 			\
++do							\
++{							\
++	reply_t reply; 					\
++	unsigned int flags; 				\
++	__save_flags(flags); 				\
++	__cli(); 					\
++	reply.code = REPLY_LOG;				\
++	reply.nr = 0; 					\
++	reply.info = 0; 				\
++	spin_lock(&sequence_lock);			\
++	send_netlog_skb(dev, buf, len, &reply);	\
++	spin_unlock(&sequence_lock);			\
++	__restore_flags(flags);				\
++}while(0);
++
++void netconsole_do_sysrq(req_t *req)
++{
++        struct pt_regs regs;
++	struct net_device *dev = netconsole_dev;
++
++	if (!dev)
++		return;
++	Set_Sysrq_mode();
++	get_current_regs(&regs);
++	handle_sysrq((int)req->from, &regs, NULL);
++	
++	if (send_cache_pos != 0){
++		SEND_MSG_BUFFER(send_cache, send_cache_pos);
++		memset(send_cache, 0, MAX_PRINT_CHUNK);
++		send_cache_pos = 0;
++	} 
++
++	Clear_Sysrq_mode();
++}
+ static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len)
+ {
+ 	int len, left, i;
+ 	struct net_device *dev;
+ 	const char *msg = msg0;
+ 	reply_t reply;
+-
++	
+ 	dev = netconsole_dev;
+ 	if (!dev || netdump_mode)
+ 		return;
+-
+-	if (dev->poll_controller && netif_running(dev)) {
++	if (sysrq_mode){
++		unsigned long total_len = send_cache_pos + msg_len;
++		unsigned long left_len = msg_len;
++		while (total_len >=  MAX_PRINT_CHUNK){
++			unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos; 
++			memcpy(send_cache + send_cache_pos, msg, send_len);
++			SEND_MSG_BUFFER(send_cache, MAX_PRINT_CHUNK);
++			send_cache_pos = 0;
++			total_len -= MAX_PRINT_CHUNK;
++			left_len -= send_len; 
++		}
++		if (left_len > 0){
++			memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len);
++			send_cache_pos += left_len;
++		}
++		return; 
++	}else if (netif_running(dev)) {
+ 		unsigned long flags;
+ 
+ 		__save_flags(flags);
+@@ -567,8 +646,6 @@
+ 	req_t *req;
+ 	struct net_device *dev;
+ 
+-	if (!netdump_mode)
+-		return NET_RX_SUCCESS;
+ #if DEBUG
+ 	{
+ 		static int packet_count;
+@@ -722,8 +799,16 @@
+ 	Dprintk("... netdump from:    %08x.\n", req->from);
+ 	Dprintk("... netdump to:      %08x.\n", req->to);
+ 
+-	add_new_req(req);
++	if (netdump_mode) 
++		add_new_req(req);
++	else if (req->command == COMM_SYSRQ){
++		add_new_req(req);
++		wake_up(&sysrq_thread_queue);	
++		return NET_RX_DROP;
++	}
+ out:
++	if (!netdump_mode)
++		return NET_RX_SUCCESS;
+ 	return NET_RX_DROP;
+ }
+ 
+@@ -763,6 +848,7 @@
+ 	kunmap_atomic(kaddr, KM_NETDUMP);
+ }
+ 
++
+ /*
+  * This function waits for the client to acknowledge the receipt
+  * of the netdump startup reply, with the possibility of packets
+@@ -792,7 +878,7 @@
+ 		// wait 1 sec.
+ 		udelay(100);
+ 		Dprintk("handshake: polling controller ...\n");
+-		dev->poll_controller(dev);
++		netdump_poll(dev);		
+ 		zap_completion_queue();
+ 		req = get_new_req();
+ 		if (req)
+@@ -904,7 +990,7 @@
+ 	while (netdump_mode) {
+ 		__cli();
+ 		Dprintk("main netdump loop: polling controller ...\n");
+-		dev->poll_controller(dev);
++		netdump_poll(dev);
+ 		zap_completion_queue();
+ #if !CLI
+ 		__sti();
+@@ -1009,6 +1095,32 @@
+ 	printk("NETDUMP END!\n");
+ 	__restore_flags(flags);
+ }
++static int netconsole_sysrq_schedule(void *arg) 
++{
++	struct task_struct *tsk = current;
++
++	sprintf(tsk->comm, "sysrq_schedule");
++	sigfillset(&tsk->blocked);
++
++	/* main loop */
++	thread_stopped = 0;	
++	for (;;) {
++		wait_event_interruptible(sysrq_thread_queue,
++					 !list_empty(&request_list) || stop_sysrq_thread);
++		while (!list_empty(&request_list)) {
++			req_t *req = get_new_req();
++			if (req->command == COMM_SYSRQ)
++				netconsole_do_sysrq(req);	
++		}
++		if (stop_sysrq_thread)
++			break;
++		wake_up(&sysrq_thread_waiter_queue);
++	}
++	thread_stopped = 1;	
++	wake_up(&sysrq_thread_waiter_queue);
++	return 0;
++}
++
+ 
+ static char *dev;
+ static int netdump_target_eth_byte0 = 255;
+@@ -1087,11 +1199,12 @@
+ 
+ static struct console netconsole =
+ 	 { flags: CON_ENABLED, write: write_netconsole_msg };
+-
+ static int init_netconsole(void)
+ {
+ 	struct net_device *ndev = NULL;
+ 	struct in_device *in_dev;
++ 	struct irqaction *action;
++	int rc = 0;
+ 
+ 	printk(KERN_INFO "netlog: using network device <%s>\n", dev);
+ 	// this will be valid once the device goes up.
+@@ -1101,10 +1214,6 @@
+ 		printk(KERN_ERR "netlog: network device %s does not exist, aborting.\n", dev);
+ 		return -1;
+ 	}
+-	if (!ndev->poll_controller) {
+-		printk(KERN_ERR "netlog: %s's network driver does not implement netlogging yet, aborting.\n", dev);
+-		return -1;
+-	}
+ 	in_dev = in_dev_get(ndev);
+ 	if (!in_dev) {
+ 		printk(KERN_ERR "netlog: network device %s is not an IP protocol device, aborting.\n", dev);
+@@ -1137,8 +1246,6 @@
+ 	if (!netdump_target_ip && !netlog_target_ip && !syslog_target_ip) {
+ 		printk(KERN_ERR "netlog: target_ip parameter not specified, aborting.\n");
+ 		return -1;
+-	}
+-	if (netdump_target_ip) {
+ #define IP(x) ((unsigned char *)&netdump_target_ip)[x]
+ 		printk(KERN_INFO "netlog: using netdump target IP %u.%u.%u.%u\n",
+ 			IP(3), IP(2), IP(1), IP(0));
+@@ -1214,12 +1321,27 @@
+ 
+ 	mhz_cycles = (unsigned long long)mhz * 1000000ULL;
+ 	jiffy_cycles = (unsigned long long)mhz * (1000000/HZ);
+-
+-	INIT_LIST_HEAD(&request_list);
+-
++	
+ 	ndev->rx_hook = netconsole_rx_hook;
+ 	netdump_func = netconsole_netdump;
+ 	netconsole_dev = ndev;
++	/* find irq function of the ndev*/
++	action=find_irq_action(ndev->irq, ndev);
++        if (!action) {
++		printk(KERN_ERR "couldn't find irq handler for <%s>", dev);
++		return -1;
++	}
++	irqfunc = action->handler;
++
++	stop_sysrq_thread = 0;
++	INIT_LIST_HEAD(&request_list);
++	init_waitqueue_head(&sysrq_thread_queue);
++	init_waitqueue_head(&sysrq_thread_waiter_queue);
++	if ((rc = kernel_thread(netconsole_sysrq_schedule, NULL, 0)) < 0 ){
++              printk(KERN_ERR "Can not start netconsole sysrq thread: rc %d\n", rc); 
++	      return -1; 
++	}
++
+ #define STARTUP_MSG "[...network console startup...]\n"
+ 	write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
+ 
+@@ -1230,7 +1352,11 @@
+ 
+ static void cleanup_netconsole(void)
+ {
+-	printk(KERN_INFO "netlog: network logging shut down.\n");
++	stop_sysrq_thread = 1;
++	
++	wake_up(&sysrq_thread_queue);
++	wait_event(sysrq_thread_waiter_queue, thread_stopped); 
++	printk(KERN_INFO"netlog: network logging shut down.\n");
+ 	unregister_console(&netconsole);
+ 
+ #define SHUTDOWN_MSG "[...network console shutdown...]\n"
+Index: linux-2.4.20-rh/drivers/net/netconsole.h
+===================================================================
+--- linux-2.4.20-rh.orig/drivers/net/netconsole.h	2003-07-22 16:02:23.000000000 +0800
++++ linux-2.4.20-rh/drivers/net/netconsole.h	2003-10-30 01:48:45.000000000 +0800
+@@ -29,7 +29,7 @@
+  *
+  ****************************************************************/
+ 
+-#define NETCONSOLE_VERSION 0x04
++#define NETCONSOLE_VERSION 0x03
+ 
+ enum netdump_commands {
+ 	COMM_NONE = 0,
+@@ -42,6 +42,8 @@
+ 	COMM_START_NETDUMP_ACK = 7,
+ 	COMM_GET_REGS = 8,
+ 	COMM_SHOW_STATE = 9,
++  	COMM_START_WRITE_NETDUMP_ACK = 10,
++        COMM_SYSRQ = 11,
+ };
+ 
+ #define NETDUMP_REQ_SIZE (8+4*4)
+@@ -69,6 +71,7 @@
+ 	REPLY_REGS = 10,
+ 	REPLY_MAGIC = 11,
+ 	REPLY_SHOW_STATE = 12,
++	REPLY_SYSRQ = 13,
+ };
+ 
+ typedef struct netdump_reply_s {
+@@ -78,4 +81,22 @@
+ } reply_t;
+ 
+ #define HEADER_LEN (1 + sizeof(reply_t))
+-
++/* for netconsole */
++static inline void get_current_regs(struct pt_regs *regs)
++{
++       __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
++       __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
++       __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
++       __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
++       __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
++       __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
++       __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
++       __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
++       __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
++       __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
++       __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
++       __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
++       __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
++       regs->eip = (unsigned long)current_text_addr();
++}
++		
+Index: linux-2.4.20-rh/arch/i386/kernel/irq.c
+===================================================================
+--- linux-2.4.20-rh.orig/arch/i386/kernel/irq.c	2003-10-30 08:29:38.000000000 +0800
++++ linux-2.4.20-rh/arch/i386/kernel/irq.c	2003-10-30 08:30:13.000000000 +0800
+@@ -1043,7 +1043,20 @@
+ 	register_irq_proc(irq);
+ 	return 0;
+ }
++struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
++{
++	struct irqaction *a, *r=0;
+ 
++	spin_lock_irq(&irq_desc[irq].lock);
++	for(a=irq_desc[irq].action; a; a=a->next) {
++		if(a->dev_id == dev_id) {
++			r=a;
++			break;
++		}
++	}
++	spin_unlock_irq(&irq_desc[irq].lock);
++	return r;
++}
+ 
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+Index: linux-2.4.20-rh/net/core/dev.c
+===================================================================
+--- linux-2.4.20-rh.orig/net/core/dev.c	2003-10-29 01:40:26.000000000 +0800
++++ linux-2.4.20-rh/net/core/dev.c	2003-10-30 01:48:45.000000000 +0800
+@@ -1475,6 +1475,16 @@
+ 
+ 	skb_bond(skb);
+ 
++	if (unlikely(skb->dev->rx_hook != NULL)) {
++		int ret;
++
++		ret = skb->dev->rx_hook(skb);
++		if (ret == NET_RX_DROP){
++			kfree_skb(skb);
++			return ret;
++		}
++        }
++
+ 	netdev_rx_stat[smp_processor_id()].total++;
+ 
+ #ifdef CONFIG_NET_FASTROUTE
+Index: linux-2.4.20-rh/include/asm-i386/irq.h
+===================================================================
+--- linux-2.4.20-rh.orig/include/asm-i386/irq.h	2003-10-28 16:18:18.000000000 +0800
++++ linux-2.4.20-rh/include/asm-i386/irq.h	2003-10-30 10:24:49.000000000 +0800
+@@ -38,7 +38,7 @@
+ extern void disable_irq_nosync(unsigned int);
+ extern void enable_irq(unsigned int);
+ extern void release_x86_irqs(struct task_struct *);
+-
++extern struct irqaction *find_irq_action(unsigned int irq, void *dev_id);
+ #ifdef CONFIG_X86_LOCAL_APIC
+ #define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
+ #endif
+Index: linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c
+===================================================================
+--- linux-2.4.20-rh.orig/arch/i386/kernel/i386_ksyms.c	2003-10-28 19:44:57.000000000 +0800
++++ linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c	2003-10-30 11:14:55.000000000 +0800
+@@ -68,6 +68,7 @@
+ EXPORT_SYMBOL(iounmap);
+ EXPORT_SYMBOL(enable_irq);
+ EXPORT_SYMBOL(disable_irq);
++EXPORT_SYMBOL(find_irq_action);
+ EXPORT_SYMBOL(disable_irq_nosync);
+ EXPORT_SYMBOL(probe_irq_mask);
+ EXPORT_SYMBOL(kernel_thread);
+@@ -199,7 +200,6 @@
+ EXPORT_SYMBOL(edd);
+ EXPORT_SYMBOL(eddnr);
+ #endif
+-
+ EXPORT_SYMBOL_GPL(show_mem);
+ EXPORT_SYMBOL_GPL(show_state);
+ EXPORT_SYMBOL_GPL(show_regs);
+Index: linux-2.4.20-rh/kernel/panic.c
+===================================================================
+--- linux-2.4.20-rh.orig/kernel/panic.c	2003-10-31 07:25:19.000000000 +0800
++++ linux-2.4.20-rh/kernel/panic.c	2003-10-31 07:25:59.000000000 +0800
+@@ -219,8 +219,6 @@
+ 	}
+ #endif
+ 
+-	if (netdump_func)
+-		BUG();
+ 	if (in_interrupt())
+ 		printk(KERN_EMERG "In interrupt handler - not syncing\n");
+ 	else if (!current->pid)
diff --git a/lustre/kernel_patches/patches/netconsole-over-netpoll.patch b/lustre/kernel_patches/patches/netconsole-over-netpoll.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c715c8427b05d450f502c543240e56f7c7e73419
--- /dev/null
+++ b/lustre/kernel_patches/patches/netconsole-over-netpoll.patch
@@ -0,0 +1,416 @@
+ Documentation/networking/netconsole.txt |   57 ++++++++
+ arch/i386/kernel/i386_ksyms.c           |    8 +
+ arch/i386/kernel/irq.c                  |   12 +
+ drivers/net/Kconfig                     |    7 +
+ drivers/net/Makefile                    |    1 
+ drivers/net/netconsole.c                |  217 ++++++++++++++++++++++++++++++++
+ include/asm-i386/netconsole.h           |    6 
+ net/Kconfig                             |    2 
+ net/core/dev.c                          |    3 
+ 9 files changed, 311 insertions(+), 2 deletions(-)
+
+--- linux-2.6.0-test6/arch/i386/kernel/i386_ksyms.c~netconsole-over-netpoll	2003-10-14 17:44:04.000000000 +0400
++++ linux-2.6.0-test6-alexey/arch/i386/kernel/i386_ksyms.c	2003-10-14 17:45:08.000000000 +0400
+@@ -34,7 +34,7 @@
+ #include <asm/nmi.h>
+ #include <asm/edd.h>
+ #include <asm/ist.h>
+-
++#include <asm/netconsole.h>
+ extern void dump_thread(struct pt_regs *, struct user *);
+ extern spinlock_t rtc_lock;
+ 
+@@ -211,6 +211,12 @@ EXPORT_SYMBOL(edd);
+ EXPORT_SYMBOL(eddnr);
+ #endif
+ 
++#ifdef CONFIG_NETCONSOLE
++EXPORT_SYMBOL(netconsole_sysrq_req);
++EXPORT_SYMBOL(netconsole_do_sysrq);
++EXPORT_SYMBOL(netif_in_poll);
++#endif
++
+ #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
+ EXPORT_SYMBOL(ist_info);
+ #endif
+--- linux-2.6.0-test6/arch/i386/kernel/irq.c~netconsole-over-netpoll	2003-10-14 17:45:03.000000000 +0400
++++ linux-2.6.0-test6-alexey/arch/i386/kernel/irq.c	2003-10-14 17:45:08.000000000 +0400
+@@ -45,6 +45,7 @@
+ #include <asm/desc.h>
+ #include <asm/irq.h>
+ #include <asm/kgdb.h>
++#include <asm/netconsole.h>
+ 
+ /*
+  * Linux has a controller-independent x86 interrupt architecture.
+@@ -510,6 +511,17 @@ out:
+ 		BREAKPOINT;
+ 	}
+ #endif
++#ifdef CONFIG_NETCONSOLE
++	/*
++	 * We need to do this after clearing out of all the interrupt
++	 * machinery because kgdb will reenter the NIC driver and the IRQ
++	 * system.  synchronize_irq() (at least) will deadlock.
++	 */
++	if (netconsole_sysrq_req && !netif_in_poll) {
++		netconsole_sysrq_req = 0;
++		HANDLE_NETCONSOLE;
++	}
++#endif
+ 	return 1;
+ }
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test6-alexey/Documentation/networking/netconsole.txt	2003-10-14 17:45:08.000000000 +0400
+@@ -0,0 +1,57 @@
++
++started by Ingo Molnar <mingo@redhat.com>, 2001.09.17
++2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003
++
++Please send bug reports to Matt Mackall <mpm@selenic.com>
++
++This module logs kernel printk messages over UDP allowing debugging of
++problem where disk logging fails and serial consoles are impractical.
++
++It can be used either built-in or as a module. As a built-in,
++netconsole initializes immediately after NIC cards and will bring up
++the specified interface as soon as possible. While this doesn't allow
++capture of early kernel panics, it does capture most of the boot
++process.
++
++It takes a string configuration parameter "netconsole" in the
++following format:
++
++ netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
++
++   where
++        src-port      source for UDP packets (defaults to 6666)
++        src-ip        source IP to use (interface address)
++        dev           network interface (eth0)
++        tgt-port      port for logging agent (514)
++        tgt-ip        IP address for logging agent
++        tgt-macaddr   ethernet MAC address for logging agent (broadcast)
++
++Examples:
++
++ linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
++
++  or
++
++ insmod netconsole netconsole=@/,@10.0.0.2/
++
++Built-in netconsole starts immediately after the TCP stack is
++initialized and attempts to bring up the supplied dev at the supplied
++address.
++
++The remote host can run either 'netcat -u -l -p <port>' or syslogd.
++
++WARNING: the default target ethernet setting uses the broadcast
++ethernet address to send packets, which can cause increased load on
++other systems on the same ethernet segment.
++
++NOTE: the network device (eth1 in the above case) can run any kind
++of other network traffic, netconsole is not intrusive. Netconsole
++might cause slight delays in other traffic if the volume of kernel
++messages is high, but should have no other impact.
++
++Netconsole was designed to be as instantaneous as possible, to
++enable the logging of even the most critical kernel bugs. It works
++from IRQ contexts as well, and does not enable interrupts while
++sending packets. Due to these unique needs, configuration can not
++be more automatic, and some fundamental limitations will remain:
++only IP networks, UDP packets and ethernet devices are supported.
+--- linux-2.6.0-test6/drivers/net/Kconfig~netconsole-over-netpoll	2003-10-14 17:44:05.000000000 +0400
++++ linux-2.6.0-test6-alexey/drivers/net/Kconfig	2003-10-14 17:45:08.000000000 +0400
+@@ -2444,6 +2444,13 @@ config SHAPER
+ config NET_POLL_CONTROLLER
+ 	def_bool KGDB
+ 
++config NETCONSOLE
++	tristate "Network console logging support"
++	depends on NETDEVICES
++	---help---
++	If you want to log kernel messages over the network, enable this.
++	See Documentation/networking/netconsole.txt for details.
++
+ source "drivers/net/wan/Kconfig"
+ 
+ source "drivers/net/pcmcia/Kconfig"
+--- linux-2.6.0-test6/drivers/net/Makefile~netconsole-over-netpoll	2003-10-14 17:45:04.000000000 +0400
++++ linux-2.6.0-test6-alexey/drivers/net/Makefile	2003-10-14 17:45:08.000000000 +0400
+@@ -109,6 +109,7 @@ ifeq ($(CONFIG_SLIP_COMPRESSED),y)
+ endif
+ # Must come after all NICs it might use
+ obj-$(CONFIG_KGDB) += kgdb_eth.o
++obj-$(CONFIG_NETCONSOLE) += netconsole.o
+ 
+ obj-$(CONFIG_DUMMY) += dummy.o
+ obj-$(CONFIG_DE600) += de600.o
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test6-alexey/drivers/net/netconsole.c	2003-10-14 17:45:56.000000000 +0400
+@@ -0,0 +1,217 @@
++/*
++ *  linux/drivers/net/netconsole.c
++ *
++ *  Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
++ *
++ *  This file contains the implementation of an IRQ-safe, crash-safe
++ *  kernel console implementation that outputs kernel messages to the
++ *  network.
++ *
++ * Modification history:
++ *
++ * 2001-09-17    started by Ingo Molnar.
++ * 2003-08-11    2.6 port by Matt Mackall
++ *               simplified options
++ *               generic card hooks
++ *               works non-modular
++ * 2003-09-07    rewritten with netpoll api
++ * 2003-09-27    updated by wangdi <wangdi@clusterfs.com>
++ */
++
++/****************************************************************
++ *      This program 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, or (at your option)
++ *      any later version.
++ *
++ *      This program is distributed in the hope that it will be useful,
++ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *      GNU General Public License for more details.
++ *
++ *      You should have received a copy of the GNU General Public License
++ *      along with this program; if not, write to the Free Software
++ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ ****************************************************************/
++
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/console.h>
++#include <linux/tty_driver.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/string.h>
++#include <linux/sysrq.h>
++#include <linux/smp.h>
++#include <linux/netpoll.h>
++#include <linux/dump.h>
++#include <linux/dump_netdev.h>
++#include <asm/unaligned.h>
++#include <asm/dump.h>
++#include <asm/netconsole.h>
++
++MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
++MODULE_DESCRIPTION("Console driver for network interfaces");
++MODULE_LICENSE("GPL");
++
++static char config[256];
++module_param_string(netconsole, config, 256, 0);
++MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
++
++static void rx_hook(struct netpoll *np, int port, char *msg, int len);
++
++static int sysrq_mode = 0;
++
++static req_t req;
++unsigned int netconsole_sysrq_req = 0;
++unsigned int netif_in_poll = 0;
++static unsigned int handle_sysrq_progress = 0;
++#define Set_Sysrq_mode() 	(sysrq_mode = 1)
++#define Clear_Sysrq_mode() 	(sysrq_mode = 0)
++
++static struct netpoll np = {
++	.name = "netconsole",
++	.dev_name = "eth0",
++	.rx_hook = rx_hook,
++	.local_port = 6666,
++	.remote_port = 6666,
++	.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
++};
++
++#define MAX_PRINT_CHUNK 1000
++#define MAX_SEND_BUFFER_LEN (MAX_PRINT_CHUNK + 200)
++
++static char send_buf[MAX_SEND_BUFFER_LEN];
++static char send_cache[MAX_PRINT_CHUNK];
++static unsigned int send_cache_pos = 0;
++
++static void send_msg_buffer(struct netpoll *np, const char *msg, int len)
++{
++  	reply_t reply;
++ 
++	send_buf[0] = NETCONSOLE_VERSION;
++        reply.code = REPLY_LOG;
++        reply.nr = 0;
++        reply.info = 0;
++
++        put_unaligned(htonl(reply.nr), (u32 *) (send_buf + 1));
++        put_unaligned(htonl(reply.code), (u32 *) (send_buf + 5));
++        put_unaligned(htonl(reply.info), (u32 *) (send_buf+ 9));
++
++	memcpy(send_buf + 1 + sizeof(reply_t), msg, len);
++	netpoll_send_udp(np, send_buf, len + 1 + sizeof(reply_t));
++	return;
++}
++static void write_msg(struct console *con, const char *msg, unsigned int len)
++{
++	unsigned long total_len = send_cache_pos + len;
++	unsigned long left_len = len;
++	unsigned long flags;
++
++	if (!sysrq_mode)
++		return;
++	if (!np.dev)
++		return;
++	while (total_len >=  MAX_PRINT_CHUNK){
++		unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos; 
++		memcpy(send_cache + send_cache_pos, msg, send_len);
++		local_irq_save(flags);
++#if 0
++		for(left = send_len; left; ) {
++			frag = min(left, MAX_PRINT_CHUNK);
++			send_msg_buffer(&np, send_buffer, frag);
++			msg += frag;
++			left -= frag;
++		}
++#endif
++		send_msg_buffer(&np, send_cache, MAX_PRINT_CHUNK);
++		send_cache_pos = 0;
++		local_irq_restore(flags);
++		total_len -= MAX_PRINT_CHUNK;
++		left_len -= send_len; 
++	}
++	if (left_len > 0){
++		memcpy(send_cache + send_cache_pos, msg + (len -left_len), left_len);
++		send_cache_pos += left_len;
++	}
++}
++void netconsole_do_sysrq()
++{
++        struct pt_regs regs;
++	unsigned long flags;	
++	
++	handle_sysrq_progress = 1; 
++	Set_Sysrq_mode();
++	get_current_regs(&regs);
++	handle_sysrq((int)req.from, &regs, NULL);
++	
++	if (send_cache_pos != 0){
++		local_irq_save(flags);
++		send_msg_buffer(&np, send_cache, send_cache_pos);
++		send_cache_pos = 0;
++		local_irq_restore(flags);
++	} 
++
++	handle_sysrq_progress = 0;
++	Clear_Sysrq_mode();
++}
++static void rx_hook(struct netpoll *np, int port, char *msg, int len)
++{
++	/* add sysrq support */
++	req_t *__req;
++
++	if (handle_sysrq_progress)
++		goto out;	
++	__req = (req_t *)(msg);
++	if(len < (sizeof(req_t)))
++		goto out;
++
++	if ((ntohl(__req->command) != COMM_SYSRQ)) 
++		goto out;
++	/*FIXME should check magic, but did not have good ways*/
++
++	req.magic = ntohl(__req->magic);
++	req.command = ntohl(__req->command);
++	req.from = ntohl(__req->from);
++	req.to = ntohl(__req->to);
++	req.nr = ntohl(__req->nr);
++	netconsole_sysrq_req = 1;	
++out:
++	return ;
++}
++
++static struct console netconsole = {
++	.flags = CON_ENABLED | CON_PRINTBUFFER,
++	.write = write_msg
++};
++
++static int option_setup(char *opt)
++{
++	return netpoll_parse_options(&np, opt);
++}
++
++__setup("netconsole=", option_setup);
++
++static int init_netconsole(void)
++{
++	if(strlen(config) && option_setup(config))
++		return 1;
++
++	if(!np.remote_ip || netpoll_setup(&np))
++		return 1;
++	register_console(&netconsole);
++	printk(KERN_INFO "netconsole: network logging started\n");
++	return 0;
++}
++
++static void cleanup_netconsole(void)
++{
++	unregister_console(&netconsole);
++	netpoll_cleanup(&np);
++}
++
++module_init(init_netconsole);
++module_exit(cleanup_netconsole);
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.6.0-test6-alexey/include/asm-i386/netconsole.h	2003-10-14 17:45:08.000000000 +0400
+@@ -0,0 +1,6 @@
++extern unsigned int netconsole_sysrq_req;
++extern void netconsole_do_sysrq(void);
++extern unsigned int netif_in_poll;
++#ifndef HANDLE_NETCONSOLE
++#define HANDLE_NETCONSOLE netconsole_do_sysrq()
++#endif
+--- linux-2.6.0-test6/net/core/dev.c~netconsole-over-netpoll	2003-10-14 17:45:03.000000000 +0400
++++ linux-2.6.0-test6-alexey/net/core/dev.c	2003-10-14 17:45:08.000000000 +0400
+@@ -109,6 +109,7 @@
+ #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
+ #include <net/iw_handler.h>
+ #endif	/* CONFIG_NET_RADIO */
++#include <asm/netconsole.h>
+ #include <asm/current.h>
+ 
+ #ifdef CONFIG_KGDB
+@@ -1687,6 +1688,7 @@ static void net_rx_action(struct softirq
+ 	preempt_disable();
+ 	local_irq_disable();
+ 
++	netif_in_poll = 1;
+ 	while (!list_empty(&queue->poll_list)) {
+ 		struct net_device *dev;
+ 
+@@ -1711,6 +1713,7 @@ static void net_rx_action(struct softirq
+ 			local_irq_disable();
+ 		}
+ 	}
++	netif_in_poll = 0;
+ out:
+ 	local_irq_enable();
+ 	preempt_enable();
+--- linux-2.6.0-test6/net/Kconfig~netconsole-over-netpoll	2003-10-14 17:45:03.000000000 +0400
++++ linux-2.6.0-test6-alexey/net/Kconfig	2003-10-14 17:45:08.000000000 +0400
+@@ -671,6 +671,6 @@ source "net/irda/Kconfig"
+ source "net/bluetooth/Kconfig"
+ 
+ config NETPOLL
+-	def_bool KGDB
++	def_bool KGDB || NETCONSOLE
+ 
+ endmenu
+
+_
diff --git a/lustre/kernel_patches/patches/netpoll-core.patch b/lustre/kernel_patches/patches/netpoll-core.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bd554248ac7e348baecd35a0caba6d12e3a01270
--- /dev/null
+++ b/lustre/kernel_patches/patches/netpoll-core.patch
@@ -0,0 +1,854 @@
+ l-mpm/arch/i386/kernel/irq.c    |   15 
+ l-mpm/include/asm-i386/irq.h         |    1 
+ l-mpm/include/linux/netdevice.h |   22 -
+ l-mpm/include/linux/netpoll.h   |   37 ++
+ l-mpm/net/Kconfig               |    3 
+ l-mpm/net/core/Makefile         |    1 
+ l-mpm/net/core/dev.c            |   22 -
+ l-mpm/net/core/netpoll.c        |  632 ++++++++++++++++++++++++++++++++++++++++
+ 8 files changed, 707 insertions(+), 26 deletions(-)
+
+Index: linux-2.6.0-test6/net/core/netpoll.c
+===================================================================
+--- linux-2.6.0-test6.orig/net/core/netpoll.c	2003-10-07 16:08:51.000000000 +0800
++++ linux-2.6.0-test6/net/core/netpoll.c	2003-10-09 20:40:07.769057232 +0800
+@@ -0,0 +1,633 @@
++/*
++ * Common framework for low-level network console, dump, and debugger code
++ *
++ * Sep 8 2003  Matt Mackall <mpm@selenic.com>
++ */
++
++#include <linux/smp_lock.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/string.h>
++#include <linux/inetdevice.h>
++#include <linux/inet.h>
++#include <linux/interrupt.h>
++#include <linux/netpoll.h>
++#include <linux/sched.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++
++/*
++ * We maintain a small pool of fully-sized skbs, to make sure the
++ * message gets out even in extreme OOM situations.
++ */
++
++#define MAX_SKBS 32
++#define MAX_UDP_CHUNK 1460
++
++static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED;
++static int nr_skbs;
++static struct sk_buff *skbs;
++
++static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED;
++static LIST_HEAD(rx_list);
++
++static int trapped;
++
++#define MAX_SKB_SIZE \
++		(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
++				sizeof(struct iphdr) + sizeof(struct ethhdr))
++
++static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
++			     unsigned short ulen, u32 saddr, u32 daddr)
++{
++	if (uh->check == 0)
++		return 0;
++
++	if (skb->ip_summed == CHECKSUM_HW)
++		return csum_tcpudp_magic(
++			saddr, daddr, ulen, IPPROTO_UDP, skb->csum);
++
++	skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
++
++	return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
++}
++
++void netpoll_poll(struct netpoll *np)
++{
++	int budget = 1;
++
++	if(!np || !np->dev || !(np->dev->flags & IFF_UP))
++		return;
++
++	disable_irq(np->dev->irq);
++
++	/* Process pending work on NIC */
++	np->irqfunc(np->dev->irq, np->dev, 0);
++
++	/* If scheduling is stopped, tickle NAPI bits */
++	if(trapped && np->dev->poll &&
++	   test_bit(__LINK_STATE_RX_SCHED, &np->dev->state))
++		np->dev->poll(np->dev, &budget);
++
++	enable_irq(np->dev->irq);
++}
++
++static void refill_skbs(void)
++{
++	struct sk_buff *skb;
++	unsigned long flags;
++
++	spin_lock_irqsave(&skb_list_lock, flags);
++	while (nr_skbs < MAX_SKBS) {
++		skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
++		if (!skb)
++			break;
++
++		skb->next = skbs;
++		skbs = skb;
++		nr_skbs++;
++	}
++	spin_unlock_irqrestore(&skb_list_lock, flags);
++}
++
++static void zap_completion_queue(void)
++{
++	unsigned long flags;
++	struct softnet_data *sd = &get_cpu_var(softnet_data);
++
++	if (sd->completion_queue) {
++		struct sk_buff *clist;
++
++		local_irq_save(flags);
++		clist = sd->completion_queue;
++		sd->completion_queue = NULL;
++		local_irq_restore(flags);
++
++		while (clist != NULL) {
++			struct sk_buff *skb = clist;
++			clist = clist->next;
++			__kfree_skb(skb);
++		}
++	}
++
++	put_cpu_var(softnet_data);
++}
++
++static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve)
++{
++	int once = 1, count = 0;
++	unsigned long flags;
++	struct sk_buff *skb = NULL;
++
++repeat:
++	zap_completion_queue();
++	if (nr_skbs < MAX_SKBS)
++		refill_skbs();
++
++	skb = alloc_skb(len, GFP_ATOMIC);
++
++	if (!skb) {
++		spin_lock_irqsave(&skb_list_lock, flags);
++		skb = skbs;
++		if (skb)
++			skbs = skb->next;
++		skb->next = NULL;
++		nr_skbs--;
++		spin_unlock_irqrestore(&skb_list_lock, flags);
++	}
++
++	if(!skb) {
++		count++;
++		if (once && (count == 1000000)) {
++			printk("out of netpoll skbs!\n");
++			once = 0;
++		}
++		netpoll_poll(np);
++		goto repeat;
++	}
++
++	atomic_set(&skb->users, 1);
++	skb_reserve(skb, reserve);
++	return skb;
++}
++
++void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
++{
++	int status;
++
++repeat:
++	if(!np || !np->dev || !(np->dev->flags & IFF_UP)) {
++		__kfree_skb(skb);
++		return;
++	}
++
++	spin_lock(&np->dev->xmit_lock);
++	np->dev->xmit_lock_owner = smp_processor_id();
++
++	if (netif_queue_stopped(np->dev)) {
++		np->dev->xmit_lock_owner = -1;
++		spin_unlock(&np->dev->xmit_lock);
++
++		netpoll_poll(np);
++		zap_completion_queue();
++		goto repeat;
++	}
++
++	status = np->dev->hard_start_xmit(skb, np->dev);
++	np->dev->xmit_lock_owner = -1;
++	spin_unlock(&np->dev->xmit_lock);
++
++	/* transmit busy */
++	if(status)
++		goto repeat;
++}
++
++void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
++{
++	int total_len, eth_len, ip_len, udp_len;
++	struct sk_buff *skb;
++	struct udphdr *udph;
++	struct iphdr *iph;
++	struct ethhdr *eth;
++
++	udp_len = len + sizeof(*udph);
++	ip_len = eth_len = udp_len + sizeof(*iph);
++	total_len = eth_len + ETH_HLEN;
++
++	skb = find_skb(np, total_len, total_len - len);
++	if (!skb)
++		return;
++
++	memcpy(skb->data, msg, len);
++	skb->len += len;
++
++	udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
++	udph->source = htons(np->local_port);
++	udph->dest = htons(np->remote_port);
++	udph->len = htons(udp_len);
++	udph->check = 0;
++
++	iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
++
++	iph->version  = 4;
++	iph->ihl      = 5;
++	iph->tos      = 0;
++	iph->tot_len  = htons(ip_len);
++	iph->id       = 0;
++	iph->frag_off = 0;
++	iph->ttl      = 64;
++	iph->protocol = IPPROTO_UDP;
++	iph->check    = 0;
++	iph->saddr    = htonl(np->local_ip);
++	iph->daddr    = htonl(np->remote_ip);
++	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
++
++	eth->h_proto = htons(ETH_P_IP);
++	memcpy(eth->h_source, np->local_mac, 6);
++	memcpy(eth->h_dest, np->remote_mac, 6);
++
++	netpoll_send_skb(np, skb);
++}
++
++static void arp_reply(struct sk_buff *skb)
++{
++	struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr;
++	struct arphdr *arp;
++	unsigned char *arp_ptr, *sha, *tha;
++	int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
++	u32 sip, tip;
++	struct sk_buff *send_skb;
++	unsigned long flags;
++	struct list_head *p;
++	struct netpoll *np = 0;
++
++	spin_lock_irqsave(&rx_list_lock, flags);
++	list_for_each(p, &rx_list) {
++		np = list_entry(p, struct netpoll, rx_list);
++		if ( np->dev == skb->dev )
++			break;
++		np = 0;
++	}
++	spin_unlock_irqrestore(&rx_list_lock, flags);
++
++	if (!np) return;
++
++	/* No arp on this interface */
++	if (!in_dev || skb->dev->flags & IFF_NOARP)
++		return;
++
++	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++				 (2 * skb->dev->addr_len) +
++				 (2 * sizeof(u32)))))
++		return;
++
++	skb->h.raw = skb->nh.raw = skb->data;
++	arp = skb->nh.arph;
++
++	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
++	     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
++	    arp->ar_pro != htons(ETH_P_IP) ||
++	    arp->ar_op != htons(ARPOP_REQUEST))
++		return;
++
++	arp_ptr= (unsigned char *)(arp+1);
++	sha = arp_ptr;
++	arp_ptr += skb->dev->addr_len;
++	memcpy(&sip, arp_ptr, 4);
++	arp_ptr += 4;
++	tha = arp_ptr;
++	arp_ptr += skb->dev->addr_len;
++	memcpy(&tip, arp_ptr, 4);
++
++	/* Should we ignore arp? */
++	if (tip != in_dev->ifa_list->ifa_address ||
++	    LOOPBACK(tip) || MULTICAST(tip))
++		return;
++
++
++	size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
++	send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
++			    LL_RESERVED_SPACE(np->dev));
++
++	if (!send_skb)
++		return;
++
++	send_skb->nh.raw = send_skb->data;
++	arp = (struct arphdr *) skb_put(send_skb, size);
++	send_skb->dev = skb->dev;
++	send_skb->protocol = htons(ETH_P_ARP);
++
++	/* Fill the device header for the ARP frame */
++
++	if (np->dev->hard_header &&
++	    np->dev->hard_header(send_skb, skb->dev, ptype,
++				       np->remote_mac, np->local_mac,
++				       send_skb->len) < 0) {
++		kfree_skb(send_skb);
++		return;
++	}
++
++	/*
++	 * Fill out the arp protocol part.
++	 *
++	 * we only support ethernet device type,
++	 * which (according to RFC 1390) should always equal 1 (Ethernet).
++	 */
++
++	arp->ar_hrd = htons(np->dev->type);
++	arp->ar_pro = htons(ETH_P_IP);
++	arp->ar_hln = np->dev->addr_len;
++	arp->ar_pln = 4;
++	arp->ar_op = htons(type);
++
++	arp_ptr=(unsigned char *)(arp + 1);
++	memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len);
++	arp_ptr += np->dev->addr_len;
++	memcpy(arp_ptr, &tip, 4);
++	arp_ptr += 4;
++	memcpy(arp_ptr, np->local_mac, np->dev->addr_len);
++	arp_ptr += np->dev->addr_len;
++	memcpy(arp_ptr, &sip, 4);
++
++	netpoll_send_skb(np, send_skb);
++}
++
++static int rx_hook(struct sk_buff *skb)
++{
++	int proto, len, ulen;
++	struct iphdr *iph;
++	struct udphdr *uh;
++	struct netpoll *np;
++	struct list_head *p;
++	unsigned long flags;
++	int rx_hook_called = 0;
++
++	if (skb->dev->type != ARPHRD_ETHER)
++		goto out;
++
++	/* check if netpoll clients need ARP */
++	if (skb->protocol == __constant_htons(ETH_P_ARP) && trapped) {
++		arp_reply(skb);
++		return 1;
++	}
++
++	proto = ntohs(skb->mac.ethernet->h_proto);
++	if (proto != ETH_P_IP)
++		goto out;
++	if (skb->pkt_type == PACKET_OTHERHOST)
++		goto out;
++	if (skb_shared(skb))
++		goto out;
++
++	iph = (struct iphdr *)skb->data;
++	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
++		goto out;
++	if (iph->ihl < 5 || iph->version != 4)
++		goto out;
++	if (!pskb_may_pull(skb, iph->ihl*4))
++		goto out;
++	if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
++		goto out;
++
++	len = ntohs(iph->tot_len);
++	if (skb->len < len || len < iph->ihl*4)
++		goto out;
++
++	if (iph->protocol != IPPROTO_UDP)
++		goto out;
++
++	len -= iph->ihl*4;
++	uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
++	ulen = ntohs(uh->len);
++
++	if (ulen != len)
++		goto out;
++	if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)
++		goto out;
++
++	spin_lock_irqsave(&rx_list_lock, flags);
++	list_for_each(p, &rx_list) {
++		np = list_entry(p, struct netpoll, rx_list);
++		if (np->dev && np->dev != skb->dev)
++			continue;
++		if (np->local_ip && np->local_ip != ntohl(iph->daddr))
++			continue;
++		if (np->remote_ip && np->remote_ip != ntohl(iph->saddr))
++			continue;
++		if (np->local_port && np->local_port != ntohs(uh->dest))
++			continue;
++
++		if (np->rx_hook){
++			np->rx_hook(np, ntohs(uh->source),
++				    (char *)(uh+1), ulen-sizeof(uh)-4);
++			rx_hook_called = 1;
++		}
++	}
++	spin_unlock_irqrestore(&rx_list_lock, flags);
++	
++	if (rx_hook_called)
++		return 1;
++out:
++	return trapped;
++}
++
++int netpoll_parse_options(struct netpoll *np, char *opt)
++{
++	char *cur=opt, *delim;
++
++	if(*cur != '@') {
++		if ((delim = strchr(cur, '@')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->local_port=simple_strtol(cur, 0, 10);
++		cur=delim;
++	}
++	cur++;
++	printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);
++
++	if(*cur != '/') {
++		if ((delim = strchr(cur, '/')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->local_ip=ntohl(in_aton(cur));
++		cur=delim;
++
++		printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
++		       np->name, HIPQUAD(np->local_ip));
++	}
++	cur++;
++
++	if ( *cur != ',') {
++		/* parse out dev name */
++		if ((delim = strchr(cur, ',')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		strlcpy(np->dev_name, cur, sizeof(np->dev_name));
++		cur=delim;
++	}
++	cur++;
++
++	printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);
++
++	if ( *cur != '@' ) {
++		/* dst port */
++		if ((delim = strchr(cur, '@')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_port=simple_strtol(cur, 0, 10);
++		cur=delim;
++	}
++	cur++;
++	printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);
++
++	/* dst ip */
++	if ((delim = strchr(cur, '/')) == NULL)
++		goto parse_failed;
++	*delim=0;
++	np->remote_ip=ntohl(in_aton(cur));
++	cur=delim+1;
++
++	printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
++		       np->name, HIPQUAD(np->remote_ip));
++
++	if( *cur != 0 )
++	{
++		/* MAC address */
++		if ((delim = strchr(cur, ':')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_mac[0]=simple_strtol(cur, 0, 16);
++		cur=delim+1;
++		if ((delim = strchr(cur, ':')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_mac[1]=simple_strtol(cur, 0, 16);
++		cur=delim+1;
++		if ((delim = strchr(cur, ':')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_mac[2]=simple_strtol(cur, 0, 16);
++		cur=delim+1;
++		if ((delim = strchr(cur, ':')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_mac[3]=simple_strtol(cur, 0, 16);
++		cur=delim+1;
++		if ((delim = strchr(cur, ':')) == NULL)
++			goto parse_failed;
++		*delim=0;
++		np->remote_mac[4]=simple_strtol(cur, 0, 16);
++		cur=delim+1;
++		np->remote_mac[5]=simple_strtol(cur, 0, 16);
++	}
++
++	printk(KERN_INFO "%s: remote ethernet address "
++	       "%02x:%02x:%02x:%02x:%02x:%02x\n",
++	       np->name,
++	       np->remote_mac[0],
++	       np->remote_mac[1],
++	       np->remote_mac[2],
++	       np->remote_mac[3],
++	       np->remote_mac[4],
++	       np->remote_mac[5]);
++
++	return 0;
++
++ parse_failed:
++	printk(KERN_INFO "%s: couldn't parse config at %s!\n",
++	       np->name, cur);
++	return -1;
++}
++
++int netpoll_setup(struct netpoll *np)
++{
++	struct net_device *ndev = NULL;
++	struct in_device *in_dev;
++	struct irqaction *a;
++
++	if (np->dev_name)
++		ndev = dev_get_by_name(np->dev_name);
++	if (!ndev) {
++		printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
++		       np->name, np->dev_name);
++		return -1;
++	}
++
++	if (!(ndev->flags & IFF_UP)) {
++		unsigned short oflags;
++		unsigned long jiff;
++
++		printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
++		       np->name, np->dev_name);
++
++		oflags = ndev->flags;
++
++		rtnl_shlock();
++		if (dev_change_flags(ndev, oflags | IFF_UP) < 0) {
++			printk(KERN_ERR "%s: failed to open %s\n",
++			       np->name, np->dev_name);
++			rtnl_shunlock();
++			return -1;
++		}
++		rtnl_shunlock();
++
++		jiff = jiffies + 6*HZ;
++		while(!netif_carrier_ok(ndev)) {
++			if (!time_before(jiffies, jiff)) {
++				printk(KERN_NOTICE
++				       "%s: timeout waiting for carrier\n",
++				       np->name);
++				break;
++			}
++			cond_resched();
++		}
++
++	}
++
++	if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)
++		memcpy(np->local_mac, ndev->dev_addr, 6);
++
++	if (!np->local_ip)
++	{
++		in_dev = in_dev_get(ndev);
++
++		if (!in_dev) {
++			printk(KERN_ERR "%s: no IP address for %s, aborting\n",
++			       np->name, np->dev_name);
++			return -1;
++		}
++
++		np->local_ip = ntohl(in_dev->ifa_list->ifa_local);
++		in_dev_put(in_dev);
++		printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
++		       np->name, HIPQUAD(np->local_ip));
++	}
++
++	a=find_irq_action(ndev->irq, ndev);
++	if (!a) {
++		printk(KERN_ERR "%s: couldn't find irq handler for %s, "
++		       "aborting\n", np->name, np->dev_name);
++		return -1;
++	}
++
++	np->irqfunc = a->handler;
++	np->dev = ndev;
++
++	if(np->rx_hook) {
++		unsigned long flags;
++
++		np->dev->rx_hook = rx_hook;
++
++		spin_lock_irqsave(&rx_list_lock, flags);
++		list_add(&np->rx_list, &rx_list);
++		spin_unlock_irqrestore(&rx_list_lock, flags);
++	}
++
++	return 0;
++}
++
++void netpoll_cleanup(struct netpoll *np)
++{
++	if(np->rx_hook) {
++		unsigned long flags;
++
++		spin_lock_irqsave(&rx_list_lock, flags);
++		list_del(&np->rx_list);
++		np->dev->rx_hook = 0;
++		spin_unlock_irqrestore(&rx_list_lock, flags);
++	}
++
++	np->dev = 0;
++}
++
++int netpoll_trap()
++{
++	return trapped;
++}
++
++void netpoll_set_trap(int trap)
++{
++	trapped = trap;
++}
+Index: linux-2.6.0-test6/include/linux/netpoll.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/netpoll.h	2003-10-07 16:08:51.000000000 +0800
++++ linux-2.6.0-test6/include/linux/netpoll.h	2003-10-07 16:08:51.000000000 +0800
+@@ -0,0 +1,37 @@
++/*
++ * Common code for low-level network console, dump, and debugger code
++ *
++ * Derived from netconsole, kgdb-over-ethernet, and netdump patches
++ */
++
++#ifndef _LINUX_NETPOLL_H
++#define _LINUX_NETPOLL_H
++
++#include <linux/netdevice.h>
++#include <linux/irq.h>
++#include <linux/list.h>
++
++struct netpoll;
++
++struct netpoll {
++	struct net_device *dev;
++	char dev_name[16], *name;
++	irqreturn_t (*irqfunc)(int, void *, struct pt_regs *);
++	void (*rx_hook)(struct netpoll *, int, char *, int);
++	u32 local_ip, remote_ip;
++	u16 local_port, remote_port;
++	unsigned char local_mac[6], remote_mac[6];
++	struct list_head rx_list;
++};
++
++void netpoll_poll(struct netpoll *np);
++void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
++void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
++int netpoll_parse_options(struct netpoll *np, char *opt);
++int netpoll_setup(struct netpoll *np);
++int netpoll_trap(void);
++void netpoll_set_trap(int trap);
++void netpoll_cleanup(struct netpoll *np);
++
++
++#endif
+Index: linux-2.6.0-test6/net/core/Makefile
+===================================================================
+--- linux-2.6.0-test6.orig/net/core/Makefile	2003-09-28 08:51:03.000000000 +0800
++++ linux-2.6.0-test6/net/core/Makefile	2003-10-07 16:08:51.000000000 +0800
+@@ -13,3 +13,4 @@
+ obj-$(CONFIG_NET_DIVERT) += dv.o
+ obj-$(CONFIG_NET_PKTGEN) += pktgen.o
+ obj-$(CONFIG_NET_RADIO) += wireless.o
++obj-$(CONFIG_NETPOLL) += netpoll.o
+Index: linux-2.6.0-test6/net/Kconfig
+===================================================================
+--- linux-2.6.0-test6.orig/net/Kconfig	2003-09-28 08:50:07.000000000 +0800
++++ linux-2.6.0-test6/net/Kconfig	2003-10-09 20:36:23.429162080 +0800
+@@ -670,4 +670,7 @@
+ 
+ source "net/bluetooth/Kconfig"
+ 
++config NETPOLL
++	def_bool KGDB
++
+ endmenu
+Index: linux-2.6.0-test6/include/linux/netdevice.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/netdevice.h	2003-10-07 16:08:42.000000000 +0800
++++ linux-2.6.0-test6/include/linux/netdevice.h	2003-10-07 16:08:51.000000000 +0800
+@@ -452,13 +452,13 @@
+ 						     unsigned char *haddr);
+ 	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
+ 	int			(*accept_fastpath)(struct net_device *, struct dst_entry*);
++#ifdef CONFIG_NETPOLL
++	int			(*rx_hook)(struct sk_buff *skb);
++#endif
+ 
+ 	/* bridge stuff */
+ 	struct net_bridge_port	*br_port;
+ 
+-#ifdef CONFIG_KGDB
+-	int			kgdb_is_trapped;
+-#endif
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ 	void			(*poll_controller)(struct net_device *);
+ #endif
+@@ -537,10 +537,8 @@
+ extern struct net_device	*dev_get_by_index(int ifindex);
+ extern struct net_device	*__dev_get_by_index(int ifindex);
+ extern int		dev_restart(struct net_device *dev);
+-#ifdef CONFIG_KGDB
+-extern int		kgdb_eth_is_trapped(void);
+-extern int		kgdb_net_interrupt(struct sk_buff *skb);
+-extern void		kgdb_send_arp_request(void);
++#ifdef CONFIG_NETPOLL
++extern int		netpoll_trap(void);
+ #endif
+ 
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+@@ -600,10 +598,9 @@
+ 
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
+-#ifdef CONFIG_KGDB
+-	if (kgdb_eth_is_trapped()) {
++#ifdef CONFIG_NETPOLL
++	if (netpoll_trap())
+ 		return;
+-	}
+ #endif
+ 	if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+ 		__netif_schedule(dev);
+@@ -611,10 +608,9 @@
+ 
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
+-#ifdef CONFIG_KGDB
+-	if (kgdb_eth_is_trapped()) {
++#ifdef CONFIG_NETPOLL
++	if (netpoll_trap())
+ 		return;
+-	}
+ #endif
+ 	set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+Index: linux-2.6.0-test6/net/core/dev.c
+===================================================================
+--- linux-2.6.0-test6.orig/net/core/dev.c	2003-10-07 16:08:42.000000000 +0800
++++ linux-2.6.0-test6/net/core/dev.c	2003-10-09 20:36:23.436161016 +0800
+@@ -1352,16 +1352,8 @@
+ 	struct softnet_data *queue;
+ 	unsigned long flags;
+ 
+-#ifdef CONFIG_KGDB
+-	/* See if kgdb_eth wants this packet */
+-	if (!kgdb_net_interrupt(skb)) {
+-		/* No.. if we're 'trapped' then junk it */
+-		if (kgdb_eth_is_trapped()) {
+-			kfree_skb(skb);
+-			return NET_RX_DROP;
+-		}
+-	} else {
+-		/* kgdb_eth ate the packet... drop it silently */
++#ifdef CONFIG_NETPOLL
++	if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
+ 		kfree_skb(skb);
+ 		return NET_RX_DROP;
+ 	}
+@@ -1556,6 +1548,13 @@
+ 	int ret = NET_RX_DROP;
+ 	unsigned short type = skb->protocol;
+ 
++#ifdef CONFIG_NETPOLL
++	if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
++		kfree_skb(skb);
++		return NET_RX_DROP;
++	}
++#endif
++
+ 	if (!skb->stamp.tv_sec)
+ 		do_gettimeofday(&skb->stamp);
+ 
+Index: linux-2.6.0-test6/include/asm-i386/irq.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/asm-i386/irq.h	2003-09-28 08:50:36.000000000 +0800
++++ linux-2.6.0-test6/include/asm-i386/irq.h	2003-10-07 16:08:51.000000000 +0800
+@@ -24,6 +24,7 @@
+ extern void disable_irq_nosync(unsigned int);
+ extern void enable_irq(unsigned int);
+ extern void release_x86_irqs(struct task_struct *);
++struct irqaction *find_irq_action(unsigned int irq, void *dev_id);
+ 
+ #ifdef CONFIG_X86_LOCAL_APIC
+ #define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
+Index: linux-2.6.0-test6/arch/i386/kernel/irq.c
+===================================================================
+--- linux-2.6.0-test6.orig/arch/i386/kernel/irq.c	2003-10-07 16:08:34.000000000 +0800
++++ linux-2.6.0-test6/arch/i386/kernel/irq.c	2003-10-09 20:36:23.433161472 +0800
+@@ -396,7 +396,6 @@
+ 	}
+ 	spin_unlock_irqrestore(&desc->lock, flags);
+ }
+-
+ /*
+  * do_IRQ handles all normal device IRQ's (the special
+  * SMP cross-CPU interrupts have their own specific
+@@ -896,6 +895,21 @@
+ 	return 0;
+ }
+ 
++struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
++{
++	struct irqaction *a, *r=0;
++
++	spin_lock_irq(&irq_desc[irq].lock);
++	for(a=irq_desc[irq].action; a; a=a->next) {
++		if(a->dev_id == dev_id) {
++			r=a;
++			break;
++		}
++	}
++	spin_unlock_irq(&irq_desc[irq].lock);
++	return r;
++}
++
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+ 
diff --git a/lustre/kernel_patches/patches/netpoll-pcnet32.patch b/lustre/kernel_patches/patches/netpoll-pcnet32.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f0ad313255a9415d551c130abc5d829d79fee066
--- /dev/null
+++ b/lustre/kernel_patches/patches/netpoll-pcnet32.patch
@@ -0,0 +1,45 @@
+ drivers/net/pcnet32.c |   16 ++++++++++++++++
+ 1 files changed, 16 insertions(+)
+
+diff -puN drivers/net/pcnet32.c~kgdbeth-pcnet32-support drivers/net/pcnet32.c
+--- linux-2.6.0-test6-mm/drivers/net/pcnet32.c~kgdbeth-pcnet32-support	2003-10-06 00:45:54.000000000 +0400
++++ linux-2.6.0-test6-mm-alexey/drivers/net/pcnet32.c	2003-10-06 00:54:55.000000000 +0400
+@@ -331,6 +331,9 @@ static int  pcnet32_init_ring(struct net
+ static int  pcnet32_start_xmit(struct sk_buff *, struct net_device *);
+ static int  pcnet32_rx(struct net_device *);
+ static void pcnet32_tx_timeout (struct net_device *dev);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void pcnet32_rx_poll(struct net_device *);
++#endif
+ static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *);
+ static int  pcnet32_close(struct net_device *);
+ static struct net_device_stats *pcnet32_get_stats(struct net_device *);
+@@ -806,6 +809,10 @@ pcnet32_probe1(unsigned long ioaddr, uns
+     dev->tx_timeout = pcnet32_tx_timeout;
+     dev->watchdog_timeo = (5*HZ);
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++    dev->poll_controller = pcnet32_rx_poll;
++#endif
++
+     lp->next = pcnet32_dev;
+     pcnet32_dev = dev;
+ 
+@@ -1152,6 +1159,15 @@ pcnet32_start_xmit(struct sk_buff *skb, 
+     return 0;
+ }
+ 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void pcnet32_rx_poll(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	pcnet32_interrupt(dev->irq, (void *)dev, 0);
++	enable_irq(dev->irq);
++}       
++#endif
++
+ /* The PCNET32 interrupt handler. */
+ static irqreturn_t
+ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+
+_
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.18.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.18.patch
new file mode 100644
index 0000000000000000000000000000000000000000..51f581e36ddffc0da15c3680b5650800eb4bff14
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.18.patch
@@ -0,0 +1,741 @@
+ fs/Makefile        |    3 
+ fs/file_table.c    |   11 ++
+ fs/inode.c         |   23 ++++-
+ fs/namei.c         |   12 ++
+ fs/nfsd/export.c   |    5 +
+ fs/nfsd/nfsfh.c    |   65 +++++++++++++-
+ fs/nfsd/vfs.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/fs.h |   10 ++
+ kernel/ksyms.c     |    2 
+ 9 files changed, 337 insertions(+), 34 deletions(-)
+
+--- linux-2.4.18-chaos/fs/file_table.c~nfs_export_kernel-2.4.18	2003-07-28 17:52:04.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/file_table.c	2003-10-08 01:10:58.000000000 +0400
+@@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+--- linux-2.4.18-chaos/fs/inode.c~nfs_export_kernel-2.4.18	2003-10-08 00:58:35.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/inode.c	2003-10-08 01:10:58.000000000 +0400
+@@ -987,9 +987,10 @@ struct inode *igrab(struct inode *inode)
+ }
+ 
+ 
+-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
++                                  struct list_head *head,
++                                  find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -1002,6 +1003,24 @@ struct inode *iget4(struct super_block *
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+--- linux-2.4.18-chaos/fs/Makefile~nfs_export_kernel-2.4.18	2003-10-08 00:58:35.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/Makefile	2003-10-08 01:10:58.000000000 +0400
+@@ -9,7 +9,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o namei.o \
++		file_table.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+--- linux-2.4.18-chaos/fs/namei.c~nfs_export_kernel-2.4.18	2003-10-08 00:58:34.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/namei.c	2003-10-08 01:10:58.000000000 +0400
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -914,7 +916,8 @@ struct dentry * lookup_hash(struct qstr 
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -934,11 +937,16 @@ struct dentry * lookup_one_len(const cha
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+--- linux-2.4.18-chaos/fs/nfsd/export.c~nfs_export_kernel-2.4.18	2003-07-28 17:52:06.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/nfsd/export.c	2003-10-08 01:10:58.000000000 +0400
+@@ -250,6 +250,11 @@ exp_export(struct nfsctl_export *nxp)
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+--- linux-2.4.18-chaos/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.18	2003-07-28 17:52:06.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/nfsd/nfsfh.c	2003-10-08 01:10:58.000000000 +0400
+@@ -37,6 +37,15 @@ struct nfsd_getdents_callback {
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -76,6 +85,8 @@ static int nfsd_get_name(struct dentry *
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -86,9 +97,37 @@ static int nfsd_get_name(struct dentry *
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -114,9 +153,13 @@ static int nfsd_get_name(struct dentry *
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -275,7 +318,7 @@ struct dentry *nfsd_findparent(struct de
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -307,6 +350,8 @@ struct dentry *nfsd_findparent(struct de
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -465,6 +510,8 @@ find_fh_dentry(struct super_block *sb, _
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -667,6 +714,11 @@ fh_verify(struct svc_rqst *rqstp, struct
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -905,8 +957,9 @@ out_negative:
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+--- linux-2.4.18-chaos/fs/nfsd/vfs.c~nfs_export_kernel-2.4.18	2003-07-28 17:52:06.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/nfsd/vfs.c	2003-10-08 01:11:59.000000000 +0400
+@@ -77,6 +77,128 @@ struct raparms {
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -300,7 +422,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -427,6 +552,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -473,6 +599,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -487,7 +621,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -824,7 +962,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -840,20 +978,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -874,10 +1036,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -890,16 +1054,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -968,7 +1135,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1019,6 +1192,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1125,7 +1300,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1139,12 +1314,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1154,7 +1335,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++				else
++					err = notify_change(dnew, iap);
+ 				if (!err && EX_ISSYNC(fhp->fh_export))
+ 					write_inode_now(dentry->d_inode, 1);
+ 		       }
+@@ -1212,7 +1396,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1298,7 +1485,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	unlock_kernel();
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+@@ -1320,7 +1510,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1366,9 +1556,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+--- linux-2.4.18-chaos/include/linux/fs.h~nfs_export_kernel-2.4.18	2003-10-08 01:09:51.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/fs.h	2003-10-08 01:10:58.000000000 +0400
+@@ -93,6 +93,9 @@ extern int leases_enable, dir_notify_ena
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1147,6 +1150,9 @@ extern struct file *filp_open(const char
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1423,6 +1429,8 @@ extern void path_release(struct nameidat
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1437,6 +1445,8 @@ extern ino_t iunique(struct super_block 
+ 
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+ 	return iget4(sb, ino, NULL, NULL);
+--- linux-2.4.18-chaos/kernel/ksyms.c~nfs_export_kernel-2.4.18	2003-10-08 00:58:34.000000000 +0400
++++ linux-2.4.18-chaos-alexey/kernel/ksyms.c	2003-10-08 01:10:58.000000000 +0400
+@@ -156,6 +156,7 @@ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+ EXPORT_SYMBOL(force_delete);
+@@ -167,6 +168,7 @@ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(sys_read);
+
+_
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.19-pre1.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7278b238b6366654e558116d25d6511043161c5a
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.19-pre1.patch
@@ -0,0 +1,757 @@
+ fs/Makefile        |    3 
+ fs/file_table.c    |   11 ++
+ fs/inode.c         |   23 ++++-
+ fs/namei.c         |   12 ++
+ fs/nfsd/export.c   |    5 +
+ fs/nfsd/nfsfh.c    |   65 +++++++++++++-
+ fs/nfsd/vfs.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/fs.h |   10 ++
+ kernel/ksyms.c     |    2 
+ 9 files changed, 337 insertions(+), 34 deletions(-)
+
+Index: linux-2.4.19-pre1/fs/file_table.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/file_table.c	2001-09-18 00:16:30.000000000 +0400
++++ linux-2.4.19-pre1/fs/file_table.c	2003-11-21 02:02:35.000000000 +0300
+@@ -82,7 +82,8 @@
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+Index: linux-2.4.19-pre1/fs/inode.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/inode.c	2003-11-20 19:24:08.000000000 +0300
++++ linux-2.4.19-pre1/fs/inode.c	2003-11-21 02:02:35.000000000 +0300
+@@ -971,9 +971,10 @@
+ }
+ 
+ 
+-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
++                                  struct list_head *head,
++                                  find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -986,6 +987,24 @@
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+Index: linux-2.4.19-pre1/fs/Makefile
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/Makefile	2003-11-21 01:51:50.000000000 +0300
++++ linux-2.4.19-pre1/fs/Makefile	2003-11-21 02:02:35.000000000 +0300
+@@ -7,7 +7,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o namei.o \
++		file_table.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+Index: linux-2.4.19-pre1/fs/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/namei.c	2003-11-20 19:16:40.000000000 +0300
++++ linux-2.4.19-pre1/fs/namei.c	2003-11-21 02:02:35.000000000 +0300
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -878,7 +880,8 @@
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -898,11 +901,16 @@
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+Index: linux-2.4.19-pre1/fs/nfsd/export.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/nfsd/export.c	2001-10-04 09:57:36.000000000 +0400
++++ linux-2.4.19-pre1/fs/nfsd/export.c	2003-11-21 02:13:10.000000000 +0300
+@@ -196,6 +196,11 @@
+ 		goto out_unlock;
+ 
+ 	inode = nd.dentry->d_inode;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 	if (inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
+ 		printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
+Index: linux-2.4.19-pre1/fs/nfsd/nfsfh.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/nfsd/nfsfh.c	2001-10-04 09:59:22.000000000 +0400
++++ linux-2.4.19-pre1/fs/nfsd/nfsfh.c	2003-11-21 02:14:53.000000000 +0300
+@@ -36,6 +36,15 @@
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -273,7 +316,7 @@
+ 	/* I'm going to assume that if the returned dentry is different, then
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+ 		/* File system cannot find ".." ... sad but possible */
+@@ -304,6 +347,8 @@
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -461,6 +506,8 @@
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -650,6 +697,11 @@
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -880,8 +932,9 @@
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+Index: linux-2.4.19-pre1/fs/nfsd/vfs.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/nfsd/vfs.c	2001-12-21 20:41:55.000000000 +0300
++++ linux-2.4.19-pre1/fs/nfsd/vfs.c	2003-11-21 02:15:47.000000000 +0300
+@@ -77,6 +77,128 @@
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -303,7 +425,10 @@
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -430,6 +555,7 @@
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -476,6 +602,14 @@
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -490,7 +624,11 @@
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -812,7 +950,7 @@
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -828,20 +966,44 @@
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -862,10 +1024,12 @@
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -878,16 +1042,19 @@
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -956,7 +1123,13 @@
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1007,6 +1180,8 @@
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1113,7 +1288,7 @@
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1127,12 +1302,18 @@
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1142,7 +1323,10 @@
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++				else
++					err = notify_change(dnew, iap);
+ 				if (!err && EX_ISSYNC(fhp->fh_export))
+ 					write_inode_now(dentry->d_inode, 1);
+ 		       }
+@@ -1200,7 +1384,10 @@
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1285,7 +1472,10 @@
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1306,7 +1496,7 @@
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1352,9 +1542,15 @@
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+Index: linux-2.4.19-pre1/include/linux/fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs.h	2003-11-21 02:00:20.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs.h	2003-11-21 02:02:36.000000000 +0300
+@@ -93,6 +93,9 @@
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1081,6 +1084,9 @@
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1342,6 +1348,8 @@
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1355,6 +1363,8 @@
+ 
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+ 	return iget4(sb, ino, NULL, NULL);
+Index: linux-2.4.19-pre1/kernel/ksyms.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/ksyms.c	2003-11-21 01:51:50.000000000 +0300
++++ linux-2.4.19-pre1/kernel/ksyms.c	2003-11-21 02:02:36.000000000 +0300
+@@ -140,6 +140,7 @@
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(force_delete);
+ EXPORT_SYMBOL(follow_up);
+@@ -150,6 +151,7 @@
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-hp.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-hp.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ea4734ee3d430e14293a3fccf8c014fe3c67915e
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-hp.patch
@@ -0,0 +1,741 @@
+ fs/Makefile        |    3 
+ fs/file_table.c    |   11 ++
+ fs/inode.c         |   23 ++++-
+ fs/namei.c         |   12 ++
+ fs/nfsd/export.c   |    5 +
+ fs/nfsd/nfsfh.c    |   65 +++++++++++++-
+ fs/nfsd/vfs.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/fs.h |   10 ++
+ kernel/ksyms.c     |    2 
+ 9 files changed, 337 insertions(+), 34 deletions(-)
+
+--- linux-2.4.20-hp4-pnnl13/fs/file_table.c~nfs_export_kernel-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/file_table.c	2003-10-08 10:54:08.000000000 +0400
+@@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+--- linux-2.4.20-hp4-pnnl13/fs/inode.c~nfs_export_kernel-2.4.20-hp	2003-09-14 17:34:20.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/inode.c	2003-10-08 11:38:11.000000000 +0400
+@@ -964,9 +964,10 @@ struct inode *igrab(struct inode *inode)
+ 	return inode;
+ }
+ 
+-struct inode *iget4_locked(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++struct inode *ifind(struct super_block *sb, unsigned long ino,
++				struct list_head *head,
++				find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -979,6 +980,24 @@ struct inode *iget4_locked(struct super_
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4_locked(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+--- linux-2.4.20-hp4-pnnl13/fs/Makefile~nfs_export_kernel-2.4.20-hp	2003-09-14 17:34:22.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/Makefile	2003-10-08 10:54:37.000000000 +0400
+@@ -7,7 +7,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o inode.o \
++		namei.o file_table.o
+ mod-subdirs :=	nls xfs
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+--- linux-2.4.20-hp4-pnnl13/fs/namei.c~nfs_export_kernel-2.4.20-hp	2003-09-14 17:34:20.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/namei.c	2003-10-08 10:54:08.000000000 +0400
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -917,7 +919,8 @@ struct dentry * lookup_hash(struct qstr 
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -937,11 +940,16 @@ struct dentry * lookup_one_len(const cha
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+--- linux-2.4.20-hp4-pnnl13/fs/nfsd/export.c~nfs_export_kernel-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/nfsd/export.c	2003-10-08 10:54:08.000000000 +0400
+@@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp)
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+--- linux-2.4.20-hp4-pnnl13/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/nfsd/nfsfh.c	2003-10-08 10:54:08.000000000 +0400
+@@ -36,6 +36,15 @@ struct nfsd_getdents_callback {
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry *
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry *
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@ static int nfsd_get_name(struct dentry *
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -662,6 +709,11 @@ fh_verify(struct svc_rqst *rqstp, struct
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -900,8 +952,9 @@ out_negative:
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+--- linux-2.4.20-hp4-pnnl13/fs/nfsd/vfs.c~nfs_export_kernel-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/nfsd/vfs.c	2003-10-08 10:54:08.000000000 +0400
+@@ -77,6 +77,128 @@ struct raparms {
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -300,7 +422,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -427,6 +552,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -473,6 +599,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -487,7 +621,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -818,7 +956,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -834,20 +972,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -868,10 +1030,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -884,16 +1048,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -962,7 +1129,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1013,6 +1186,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1119,7 +1294,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1133,12 +1308,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++				else
++					err = notify_change(dnew, iap);
+ 				if (!err && EX_ISSYNC(fhp->fh_export))
+ 					write_inode_now(dentry->d_inode, 1);
+ 		       }
+@@ -1206,7 +1390,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1291,7 +1478,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1312,7 +1502,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1358,9 +1548,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+--- linux-2.4.20-hp4-pnnl13/include/linux/fs.h~nfs_export_kernel-2.4.20-hp	2003-09-14 17:34:24.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/include/linux/fs.h	2003-10-08 11:39:07.000000000 +0400
+@@ -93,6 +93,9 @@ extern int leases_enable, dir_notify_ena
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1116,6 +1119,9 @@ extern int open_namei_it(const char *fil
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1386,6 +1392,8 @@ extern void path_release(struct nameidat
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1403,6 +1411,8 @@ typedef int (*find_inode_t)(struct inode
+ 
+ extern struct inode * iget4_locked(struct super_block *, unsigned long,
+ 				   find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ 
+ static inline struct inode *iget4(struct super_block *sb, unsigned long ino,
+ 				  find_inode_t find_actor, void *opaque)
+--- linux-2.4.20-hp4-pnnl13/kernel/ksyms.c~nfs_export_kernel-2.4.20-hp	2003-09-14 17:34:22.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/kernel/ksyms.c	2003-10-08 11:39:42.000000000 +0400
+@@ -169,6 +169,7 @@ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4_locked);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(unlock_new_inode);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+@@ -181,6 +182,7 @@ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
+
+_
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8ae5b785c6cab1f1700884499d7baa5c7c3158bb
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20-rh.patch
@@ -0,0 +1,741 @@
+ fs/Makefile        |    3 
+ fs/file_table.c    |   11 ++
+ fs/inode.c         |   23 ++++-
+ fs/namei.c         |   12 ++
+ fs/nfsd/export.c   |    5 +
+ fs/nfsd/nfsfh.c    |   65 +++++++++++++-
+ fs/nfsd/vfs.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/fs.h |   10 ++
+ kernel/ksyms.c     |    2 
+ 9 files changed, 337 insertions(+), 34 deletions(-)
+
+--- linux-2.4.20-rh-20.9/fs/file_table.c~nfs_export_kernel-2.4.20-rh	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-rh-20.9-alexey/fs/file_table.c	2003-10-08 10:48:38.000000000 +0400
+@@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+--- linux-2.4.20-rh-20.9/fs/inode.c~nfs_export_kernel-2.4.20-rh	2003-09-14 17:35:22.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/inode.c	2003-10-08 10:48:38.000000000 +0400
+@@ -1063,9 +1063,10 @@ struct inode *igrab(struct inode *inode)
+ }
+ 
+ 
+-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
++                                  struct list_head *head,
++                                  find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -1078,6 +1079,24 @@ struct inode *iget4(struct super_block *
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+--- linux-2.4.20-rh-20.9/fs/Makefile~nfs_export_kernel-2.4.20-rh	2003-09-14 17:35:20.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/Makefile	2003-10-08 10:49:33.000000000 +0400
+@@ -9,7 +9,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o \
++		namei.o file_table.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+--- linux-2.4.20-rh-20.9/fs/namei.c~nfs_export_kernel-2.4.20-rh	2003-09-14 17:35:22.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/namei.c	2003-10-08 10:48:38.000000000 +0400
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ static void *lock_dir(struct inode *dir, struct qstr *name)
+ {
+@@ -959,7 +961,8 @@ struct dentry * lookup_hash(struct qstr 
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -979,11 +982,16 @@ struct dentry * lookup_one_len(const cha
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+--- linux-2.4.20-rh-20.9/fs/nfsd/export.c~nfs_export_kernel-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/export.c	2003-10-08 10:48:38.000000000 +0400
+@@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp)
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+--- linux-2.4.20-rh-20.9/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.20-rh	2003-09-13 19:34:15.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/nfsfh.c	2003-10-08 10:48:38.000000000 +0400
+@@ -36,6 +36,15 @@ struct nfsd_getdents_callback {
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry *
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry *
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@ static int nfsd_get_name(struct dentry *
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -669,6 +716,11 @@ fh_verify(struct svc_rqst *rqstp, struct
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -912,8 +964,9 @@ out_negative:
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+--- linux-2.4.20-rh-20.9/fs/nfsd/vfs.c~nfs_export_kernel-2.4.20-rh	2003-09-13 19:34:15.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/nfsd/vfs.c	2003-10-08 10:48:38.000000000 +0400
+@@ -77,6 +77,128 @@ struct raparms {
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -302,7 +424,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -429,6 +554,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -475,6 +601,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -489,7 +623,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -820,7 +958,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -836,20 +974,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -870,10 +1032,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -886,16 +1050,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -964,7 +1131,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1015,6 +1188,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1121,7 +1296,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1135,12 +1310,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1150,7 +1331,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++				else
++					err = notify_change(dnew, iap);
+ 				if (!err && EX_ISSYNC(fhp->fh_export))
+ 					write_inode_now(dentry->d_inode, 1);
+ 		       }
+@@ -1208,7 +1392,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1293,7 +1480,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1314,7 +1504,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1360,9 +1550,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+--- linux-2.4.20-rh-20.9/include/linux/fs.h~nfs_export_kernel-2.4.20-rh	2003-09-14 17:35:22.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/include/linux/fs.h	2003-10-08 10:48:38.000000000 +0400
+@@ -94,6 +94,9 @@ extern int leases_enable, dir_notify_ena
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1124,6 +1127,9 @@ extern int open_namei_it(const char *fil
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1423,6 +1429,8 @@ extern void path_release(struct nameidat
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1439,6 +1447,8 @@ extern ino_t iunique(struct super_block 
+ 
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+ 	return iget4(sb, ino, NULL, NULL);
+--- linux-2.4.20-rh-20.9/kernel/ksyms.c~nfs_export_kernel-2.4.20-rh	2003-09-14 17:35:20.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/kernel/ksyms.c	2003-10-08 10:48:38.000000000 +0400
+@@ -164,6 +164,7 @@ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+ EXPORT_SYMBOL(force_delete);
+@@ -175,6 +176,7 @@ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(sys_read);
+
+_
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bb7e3787dd41b0c73812363b36b8e339333f4037
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.20.patch
@@ -0,0 +1,737 @@
+diff -uprN linux/fs/Makefile linux-2.4.20/fs/Makefile
+--- linux/fs/Makefile	Sun Oct  5 21:52:51 2003
++++ linux-2.4.20/fs/Makefile	Sun Oct  5 21:47:45 2003
+@@ -7,7 +7,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o inode.o namei.o \
++		file_table.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+diff -uprN linux/fs/file_table.c linux-2.4.20/fs/file_table.c
+--- linux/fs/file_table.c	Fri Nov 29 05:23:15 2002
++++ linux-2.4.20/fs/file_table.c	Sun Oct  5 21:47:45 2003
+@@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+diff -uprN linux/fs/inode.c linux-2.4.20/fs/inode.c
+--- linux/fs/inode.c	Sun Oct  5 21:52:49 2003
++++ linux-2.4.20/fs/inode.c	Sun Oct  5 21:47:45 2003
+@@ -970,9 +970,10 @@ struct inode *igrab(struct inode *inode)
+ }
+ 
+ 
+-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
++                                  struct list_head *head,
++                                  find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -985,6 +986,24 @@ struct inode *iget4(struct super_block *
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+diff -uprN linux/fs/namei.c linux-2.4.20/fs/namei.c
+--- linux/fs/namei.c	Sun Oct  5 21:52:48 2003
++++ linux-2.4.20/fs/namei.c	Sun Oct  5 21:47:45 2003
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -900,7 +902,8 @@ struct dentry * lookup_hash(struct qstr 
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -920,11 +923,16 @@ struct dentry * lookup_one_len(const cha
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+diff -uprN linux/fs/nfsd/export.c linux-2.4.20/fs/nfsd/export.c
+--- linux/fs/nfsd/export.c	Fri Nov 29 05:23:15 2002
++++ linux-2.4.20/fs/nfsd/export.c	Sun Oct  5 22:25:20 2003
+@@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp)
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+diff -uprN linux/fs/nfsd/nfsfh.c linux-2.4.20/fs/nfsd/nfsfh.c
+--- linux/fs/nfsd/nfsfh.c	Fri Nov 29 05:23:15 2002
++++ linux-2.4.20/fs/nfsd/nfsfh.c	Sun Oct  5 21:47:45 2003
+@@ -36,6 +36,15 @@ struct nfsd_getdents_callback {
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry *
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry *
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@ static int nfsd_get_name(struct dentry *
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -662,6 +709,11 @@ fh_verify(struct svc_rqst *rqstp, struct
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -900,8 +952,9 @@ out_negative:
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+diff -uprN linux/fs/nfsd/vfs.c linux-2.4.20/fs/nfsd/vfs.c
+--- linux/fs/nfsd/vfs.c	Fri Nov 29 05:23:15 2002
++++ linux-2.4.20/fs/nfsd/vfs.c	Sun Oct  5 21:47:45 2003
+@@ -77,6 +77,128 @@ struct raparms {
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -300,7 +422,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -427,6 +552,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -473,6 +599,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -487,7 +621,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -818,7 +956,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -834,20 +972,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -868,10 +1030,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -884,16 +1048,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -962,7 +1129,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1013,6 +1186,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1119,7 +1294,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1133,12 +1308,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++				else
++					err = notify_change(dnew, iap);
+ 				if (!err && EX_ISSYNC(fhp->fh_export))
+ 					write_inode_now(dentry->d_inode, 1);
+ 		       }
+@@ -1206,7 +1390,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1291,7 +1478,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1312,7 +1502,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1358,9 +1548,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+diff -uprN linux/include/linux/fs.h linux-2.4.20/include/linux/fs.h
+--- linux/include/linux/fs.h	Sun Oct  5 21:52:56 2003
++++ linux-2.4.20/include/linux/fs.h	Sun Oct  5 22:25:20 2003
+@@ -93,6 +93,9 @@ extern int leases_enable, dir_notify_ena
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1099,6 +1102,9 @@ extern int open_namei_it(const char *fil
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1369,6 +1375,8 @@ extern void path_release(struct nameidat
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1382,6 +1390,8 @@ extern ino_t iunique(struct super_block 
+ 
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+ 	return iget4(sb, ino, NULL, NULL);
+diff -uprN linux/kernel/ksyms.c linux-2.4.20/kernel/ksyms.c
+--- linux/kernel/ksyms.c	Sun Oct  5 21:52:51 2003
++++ linux-2.4.20/kernel/ksyms.c	Sun Oct  5 22:25:20 2003
+@@ -146,6 +146,7 @@ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(force_delete);
+ EXPORT_SYMBOL(follow_up);
+@@ -156,6 +157,7 @@ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..40285b81b956f65285821c45300467a63d4e29ca
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22-rh.patch
@@ -0,0 +1,730 @@
+ fs/Makefile        |    3 
+ fs/file_table.c    |   11 ++
+ fs/inode.c         |   23 ++++-
+ fs/namei.c         |   12 ++
+ fs/nfsd/export.c   |    5 +
+ fs/nfsd/nfsfh.c    |   65 +++++++++++++-
+ fs/nfsd/vfs.c      |  235 ++++++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/fs.h |   11 ++
+ kernel/ksyms.c     |    2 
+ 9 files changed, 333 insertions(+), 34 deletions(-)
+
+--- linux-2.4.22-ac1/fs/file_table.c~nfs_export_kernel-2.4.22-rh	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/file_table.c	2003-10-08 13:41:27.000000000 +0400
+@@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+--- linux-2.4.22-ac1/fs/inode.c~nfs_export_kernel-2.4.22-rh	2003-09-26 00:57:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/inode.c	2003-10-08 13:43:31.000000000 +0400
+@@ -998,9 +998,10 @@ struct inode *igrab(struct inode *inode)
+ 	return inode;
+ }
+ 
+-struct inode *iget4_locked(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++struct inode *ifind(struct super_block *sb, unsigned long ino,
++			struct list_head *head,
++			find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -1013,6 +1014,24 @@ struct inode *iget4_locked(struct super_
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4_locked(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+--- linux-2.4.22-ac1/fs/Makefile~nfs_export_kernel-2.4.22-rh	2003-09-26 00:57:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/Makefile	2003-10-08 13:41:55.000000000 +0400
+@@ -7,7 +7,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o dcookies.o inode.o \
++		namei.o file_table.o
+ mod-subdirs :=	nls xfs
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+--- linux-2.4.22-ac1/fs/namei.c~nfs_export_kernel-2.4.22-rh	2003-09-26 00:57:27.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/namei.c	2003-10-08 13:41:27.000000000 +0400
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -903,7 +905,8 @@ struct dentry * lookup_hash(struct qstr 
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -923,11 +926,16 @@ struct dentry * lookup_one_len(const cha
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+--- linux-2.4.22-ac1/fs/nfsd/export.c~nfs_export_kernel-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/nfsd/export.c	2003-10-08 13:41:27.000000000 +0400
+@@ -223,6 +223,11 @@ exp_export(struct nfsctl_export *nxp)
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+--- linux-2.4.22-ac1/fs/nfsd/nfsfh.c~nfs_export_kernel-2.4.22-rh	2003-08-25 15:44:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/nfsd/nfsfh.c	2003-10-08 13:41:27.000000000 +0400
+@@ -36,6 +36,15 @@ struct nfsd_getdents_callback {
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry *
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry *
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@ static int nfsd_get_name(struct dentry *
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -669,6 +716,11 @@ fh_verify(struct svc_rqst *rqstp, struct
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -902,8 +954,9 @@ out_negative:
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+--- linux-2.4.22-ac1/fs/nfsd/vfs.c~nfs_export_kernel-2.4.22-rh	2003-08-25 15:44:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/nfsd/vfs.c	2003-10-08 13:41:27.000000000 +0400
+@@ -77,6 +77,128 @@ struct raparms {
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -302,7 +424,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -429,6 +554,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -475,6 +601,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -489,7 +623,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -820,7 +958,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -836,20 +974,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -870,10 +1032,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -886,16 +1050,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -964,7 +1131,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1015,6 +1188,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1121,7 +1296,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1135,12 +1310,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1210,7 +1391,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1295,7 +1479,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1316,7 +1503,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1362,9 +1549,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+--- linux-2.4.22-ac1/include/linux/fs.h~nfs_export_kernel-2.4.22-rh	2003-09-26 01:00:26.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/fs.h	2003-10-08 13:44:53.000000000 +0400
+@@ -93,6 +93,9 @@ extern int leases_enable, dir_notify_ena
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID  64 /* Use file system specific fsid for
++			    * exporting non device filesystems.
++			    */
+ #define FS_ALWAYS_REVAL	16384	/* Always revalidate dentries returned by
+ 				   link_path_walk */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+@@ -1121,6 +1124,9 @@ extern int open_namei_it(const char *fil
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1420,6 +1426,8 @@ extern void path_release(struct nameidat
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1439,7 +1447,8 @@ typedef int (*find_inode_t)(struct inode
+ 
+ extern struct inode * iget4_locked(struct super_block *, unsigned long,
+ 				   find_inode_t, void *);
+-
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget4(struct super_block *sb, unsigned long ino,
+ 				  find_inode_t find_actor, void *opaque)
+ {
+--- linux-2.4.22-ac1/kernel/ksyms.c~nfs_export_kernel-2.4.22-rh	2003-09-26 00:57:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/kernel/ksyms.c	2003-10-08 13:45:20.000000000 +0400
+@@ -165,6 +165,7 @@ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4_locked);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(unlock_new_inode);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+@@ -178,6 +179,7 @@ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
+
+_
diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3ca1abcca4cecd06ed14ff10cb0f153984d04654
--- /dev/null
+++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.22.patch
@@ -0,0 +1,746 @@
+Index: linux-2.4.22-vanilla/fs/Makefile
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/Makefile	2003-11-03 23:41:40.000000000 +0300
++++ linux-2.4.22-vanilla/fs/Makefile	2003-11-03 23:45:07.000000000 +0300
+@@ -7,7 +7,8 @@
+ 
+ O_TARGET := fs.o
+ 
+-export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o inode.o
++export-objs :=	filesystems.o open.o dcache.o buffer.o dquot.o inode.o \
++		namei.o file_table.o
+ mod-subdirs :=	nls
+ 
+ obj-y :=	open.o read_write.o devices.o file_table.o buffer.o \
+Index: linux-2.4.22-vanilla/fs/file_table.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/file_table.c	2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.22-vanilla/fs/file_table.c	2003-11-03 23:44:38.000000000 +0300
+@@ -82,7 +82,8 @@
+  * and call the open function (if any).  The caller must verify that
+  * inode->i_fop is not NULL.
+  */
+-int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
++                         struct lookup_intent *it)
+ {
+ 	memset(filp, 0, sizeof(*filp));
+ 	filp->f_mode   = mode;
+@@ -90,12 +91,20 @@
+ 	filp->f_dentry = dentry;
+ 	filp->f_uid    = current->fsuid;
+ 	filp->f_gid    = current->fsgid;
++	if (it)
++		filp->f_it = it;
+ 	filp->f_op     = dentry->d_inode->i_fop;
+ 	if (filp->f_op->open)
+ 		return filp->f_op->open(dentry->d_inode, filp);
+ 	else
+ 		return 0;
+ }
++EXPORT_SYMBOL(init_private_file_it);
++
++int init_private_file(struct file *filp, struct dentry *dentry, int mode)
++{
++	return init_private_file_it(filp, dentry, mode, NULL);
++}
+ 
+ void fput(struct file * file)
+ {
+Index: linux-2.4.22-vanilla/fs/inode.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/inode.c	2003-11-03 23:25:33.000000000 +0300
++++ linux-2.4.22-vanilla/fs/inode.c	2003-11-03 23:44:38.000000000 +0300
+@@ -970,9 +970,10 @@
+ }
+ 
+ 
+-struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
++static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
++                                  struct list_head *head,
++                                  find_inode_t find_actor, void *opaque)
+ {
+-	struct list_head * head = inode_hashtable + hash(sb,ino);
+ 	struct inode * inode;
+ 
+ 	spin_lock(&inode_lock);
+@@ -985,6 +986,24 @@
+ 	}
+ 	spin_unlock(&inode_lock);
+ 
++	return NULL;
++}
++
++struct inode *ilookup4(struct super_block *sb, unsigned long ino,
++                       find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	return ifind(sb, ino, head, find_actor, opaque);
++}
++
++struct inode *iget4(struct super_block *sb, unsigned long ino,
++                    find_inode_t find_actor, void *opaque)
++{
++	struct list_head * head = inode_hashtable + hash(sb,ino);
++	struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
++	if (inode)
++		return inode;
++
+ 	/*
+ 	 * get_new_inode() will do the right thing, re-trying the search
+ 	 * in case it had to block at any point.
+Index: linux-2.4.22-vanilla/fs/namei.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/namei.c	2003-11-03 23:22:22.000000000 +0300
++++ linux-2.4.22-vanilla/fs/namei.c	2003-11-03 23:44:38.000000000 +0300
+@@ -22,6 +22,7 @@
+ #include <linux/dnotify.h>
+ #include <linux/smp_lock.h>
+ #include <linux/personality.h>
++#include <linux/module.h>
+ 
+ #include <asm/namei.h>
+ #include <asm/uaccess.h>
+@@ -100,6 +101,7 @@
+ 		it->it_op_release(it);
+ 
+ }
++EXPORT_SYMBOL(intent_release);
+ 
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+@@ -902,7 +904,8 @@
+ 
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
++                                  int len, struct lookup_intent *it)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -922,11 +925,16 @@
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash_it(&this, base, NULL);
++	return lookup_hash_it(&this, base, it);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+Index: linux-2.4.22-vanilla/fs/nfsd/export.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/nfsd/export.c	2003-11-03 23:22:11.000000000 +0300
++++ linux-2.4.22-vanilla/fs/nfsd/export.c	2003-11-03 23:44:38.000000000 +0300
+@@ -223,6 +223,11 @@
+ 	inode = nd.dentry->d_inode;
+ 	dev = inode->i_dev;
+ 	ino = inode->i_ino;
++	if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
++	    !(nxp->ex_flags & NFSEXP_FSID)) {
++	    nxp->ex_dev = inode->i_sb->s_dev;
++	    nxp->ex_flags |= NFSEXP_FSID;
++	}
+ 	err = -EINVAL;
+ 
+ 	exp = exp_get(clp, dev, ino);
+Index: linux-2.4.22-vanilla/fs/nfsd/nfsfh.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/nfsd/nfsfh.c	2003-11-03 23:22:11.000000000 +0300
++++ linux-2.4.22-vanilla/fs/nfsd/nfsfh.c	2003-11-03 23:44:38.000000000 +0300
+@@ -36,6 +36,15 @@
+ 	int sequence;		/* sequence counter */
+ };
+ 
++static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
++{
++	if (inode->i_op->lookup_it)
++	    return inode->i_op->lookup_it(inode, dentry, NULL, 0);
++	else
++	    return inode->i_op->lookup(inode, dentry);
++		
++}
++
+ /*
+  * A rather strange filldir function to capture
+  * the name matching the specified inode number.
+@@ -75,6 +84,8 @@
+ 	int error;
+ 	struct file file;
+ 	struct nfsd_getdents_callback buffer;
++	struct lookup_intent it;
++	struct file *filp = NULL;
+ 
+ 	error = -ENOTDIR;
+ 	if (!dir || !S_ISDIR(dir->i_mode))
+@@ -85,9 +96,37 @@
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	error = init_private_file(&file, dentry, FMODE_READ);
+-	if (error)
++	if (dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
++		    (dentry->d_parent == dentry) ) {
++			it.it_op_release = NULL;
++			/* 
++			 * XXX Temporary Hack: Simulating init_private_file without
++			 * f_op->open for disconnected dentry Since we don't have actual
++			 * dentry->d_name to revalidate in revalidate_it()
++			 */
++			filp = &file;
++			memset(filp, 0, sizeof(*filp));
++			filp->f_mode   = FMODE_READ;
++			atomic_set(&filp->f_count, 1);
++			filp->f_dentry = dentry;
++			filp->f_uid = current->fsuid;
++			filp->f_gid = current->fsgid;
++			filp->f_op = dentry->d_inode->i_fop;
++			error = 0;
++		} else {
++			intent_init(&it, IT_OPEN, 0);
++			error = revalidate_it(dentry, &it);
++			if (error)
++				goto out;
++			error = init_private_file_it(&file, dentry, FMODE_READ, &it);
++		}
++	} else {
++		error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
++	}
++	if (error) 
+ 		goto out;
++
+ 	error = -EINVAL;
+ 	if (!file.f_op->readdir)
+ 		goto out_close;
+@@ -113,9 +152,13 @@
+ 	}
+ 
+ out_close:
+-	if (file.f_op->release)
++	if (file.f_op->release && !filp)
+ 		file.f_op->release(dir, &file);
+ out:
++	if (dentry->d_op &&
++	    dentry->d_op->d_revalidate_it &&
++	    it.it_op_release && !filp)
++		intent_release(&it);
+ 	return error;
+ }
+ 
+@@ -274,7 +317,7 @@
+ 	 * it is well connected.  But nobody returns different dentrys do they?
+ 	 */
+ 	down(&child->d_inode->i_sem);
+-	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++	pdentry = lookup_it(child->d_inode, tdentry);
+ 	up(&child->d_inode->i_sem);
+ 	d_drop(tdentry); /* we never want ".." hashed */
+ 	if (!pdentry && tdentry->d_inode == NULL) {
+@@ -306,6 +349,8 @@
+ 				igrab(tdentry->d_inode);
+ 				pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ 			}
++			if (child->d_op && child->d_op->d_revalidate_it)
++				pdentry->d_op = child->d_op;
+ 		}
+ 		if (pdentry == NULL)
+ 			pdentry = ERR_PTR(-ENOMEM);
+@@ -463,6 +508,8 @@
+ 		struct dentry *pdentry;
+ 		struct inode *parent;
+ 
++		if (result->d_op && result->d_op->d_revalidate_it)
++			dentry->d_op = result->d_op;
+ 		pdentry = nfsd_findparent(dentry);
+ 		err = PTR_ERR(pdentry);
+ 		if (IS_ERR(pdentry))
+@@ -669,6 +716,11 @@
+ 
+ 	inode = dentry->d_inode;
+ 
++	/* cache coherency for non-device filesystems */
++	if (inode->i_op && inode->i_op->revalidate_it) {
++	    inode->i_op->revalidate_it(dentry, NULL);
++	}
++
+ 	/* Type check. The correct error return for type mismatches
+ 	 * does not seem to be generally agreed upon. SunOS seems to
+ 	 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
+@@ -902,8 +954,9 @@
+ 		dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ out_uptodate:
+-	printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
+-		dentry->d_parent->d_name.name, dentry->d_name.name);
++	if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
++		printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++			dentry->d_parent->d_name.name, dentry->d_name.name);
+ 	goto out;
+ }
+ 
+Index: linux-2.4.22-vanilla/fs/nfsd/vfs.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/nfsd/vfs.c	2003-11-03 23:22:11.000000000 +0300
++++ linux-2.4.22-vanilla/fs/nfsd/vfs.c	2003-11-03 23:47:41.000000000 +0300
+@@ -77,6 +77,128 @@
+ static struct raparms *		raparml;
+ static struct raparms *		raparm_cache;
+ 
++static int link_raw(struct dentry *dold, struct dentry *ddir,
++                    struct dentry *dnew)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = dold };
++	struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->link_raw(&old_nd, &nd);
++	d_instantiate(dnew, dold->d_inode);
++	if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
++		dold->d_inode->i_op->revalidate_it(dnew, NULL);
++
++	return err;
++}
++
++static int unlink_raw(struct dentry *dentry, char *fname, int flen,
++                      struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->unlink_raw(&nd);
++	if (!err)
++		d_delete(rdentry);
++
++	return err;
++}
++
++static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
++                     struct dentry *rdentry)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->rmdir_raw(&nd);
++	if(!err) {
++		rdentry->d_inode->i_flags |= S_DEAD;
++		d_delete(rdentry);
++	}
++
++	return err;
++}
++
++static int symlink_raw(struct dentry *dentry,  char *fname, int flen,
++                       char *path)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->symlink_raw(&nd, path);
++
++	return err;
++}
++
++static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mkdir_raw(&nd, mode);
++
++	return err;
++}
++
++static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
++                     dev_t dev)
++{
++	int err;
++        struct qstr last = { .name = fname, .len = flen };
++	struct nameidata nd = { .dentry = dentry, .last = last };
++	struct inode_operations *op = nd.dentry->d_inode->i_op;
++	err = op->mknod_raw(&nd, mode, dev);
++
++	return err;
++}	
++
++static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
++                      struct dentry *odentry, struct dentry *ndentry)
++{
++	int err;
++
++	struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
++	struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
++	struct inode_operations *op = old_nd.dentry->d_inode->i_op;
++	err = op->rename_raw(&old_nd, &new_nd);
++	d_move(odentry, ndentry);
++
++	return err;
++}
++
++static int setattr_raw(struct inode *inode, struct iattr *iap)
++{
++	int err;
++
++	iap->ia_valid |= ATTR_RAW;
++	err = inode->i_op->setattr_raw(inode, iap);
++
++	return err;
++}
++
++int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
++{
++	int err = 0;
++
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
++			!d_invalidate(dentry)) {
++			dput(dentry);
++			err = -EINVAL;
++			dentry = NULL;
++			return err;
++		}
++	}
++
++	return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -302,7 +424,10 @@
+ 	}
+ 	err = nfserr_notsync;
+ 	if (!check_guard || guardtime == inode->i_ctime) {
+-		err = notify_change(dentry, iap);
++		if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
++			err = setattr_raw(dentry->d_inode, iap);
++		else
++			err = notify_change(dentry, iap);
+ 		err = nfserrno(err);
+ 	}
+ 	if (size_change) {
+@@ -429,6 +554,7 @@
+ {
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
++	struct lookup_intent it;
+ 	int		err;
+ 
+ 	/* If we get here, then the client has already done an "open", and (hopefully)
+@@ -475,6 +601,14 @@
+ 		filp->f_mode  = FMODE_READ;
+ 	}
+ 
++	intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
++
++	err = revalidate_it(dentry, &it);
++	if (err)
++		goto out_nfserr;
++	
++	filp->f_it = &it;
++	
+ 	err = 0;
+ 	if (filp->f_op && filp->f_op->open) {
+ 		err = filp->f_op->open(inode, filp);
+@@ -489,7 +623,11 @@
+ 			atomic_dec(&filp->f_count);
+ 		}
+ 	}
++
+ out_nfserr:
++	if (it.it_op_release)
++		intent_release(&it);
++
+ 	if (err)
+ 		err = nfserrno(err);
+ out:
+@@ -820,7 +958,7 @@
+ {
+ 	struct dentry	*dentry, *dchild;
+ 	struct inode	*dirp;
+-	int		err;
++	int		err, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_perm;
+ 	if (!flen)
+@@ -836,20 +974,44 @@
+ 	dentry = fhp->fh_dentry;
+ 	dirp = dentry->d_inode;
+ 
++	switch (type) {
++			case S_IFDIR:
++				if (dirp->i_op->mkdir_raw)
++		            error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
++				break;
++			case S_IFCHR:
++			case S_IFBLK:
++			case S_IFIFO:
++			case S_IFSOCK:
++			case S_IFREG:
++			    if (dirp->i_op->mknod_raw) {
++					if (type == S_IFREG)
++						rdev = 0;
++					error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
++				}
++				break;
++				default:
++	                printk("nfsd: bad file type %o in nfsd_create\n", type);
++	}
++
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	/*
+ 	 * Check whether the response file handle has been verified yet.
+ 	 * If it has, the parent directory should already be locked.
+ 	 */
+-	if (!resfhp->fh_dentry) {
+-		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
+-		fh_lock(fhp);
++	if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
++		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
++		   and nfsd_proc_create in case of lustre
++		*/
++		if (!resfhp->fh_dentry)
++			fh_lock(fhp);
+ 		dchild = lookup_one_len(fname, dentry, flen);
+ 		err = PTR_ERR(dchild);
+ 		if (IS_ERR(dchild))
+ 			goto out_nfserr;
++		resfhp->fh_dentry = NULL;
+ 		err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+ 		if (err)
+ 			goto out;
+@@ -870,10 +1032,12 @@
+ 	 * Make sure the child dentry is still negative ...
+ 	 */
+ 	err = nfserr_exist;
+-	if (dchild->d_inode) {
+-		dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-			dentry->d_name.name, dchild->d_name.name);
+-		goto out; 
++	if ( error == -EOPNOTSUPP) {
++		if (dchild->d_inode) {
++			dprintk("nfsd_create: dentry %s/%s not negative!\n",
++				dentry->d_name.name, dchild->d_name.name);
++			goto out; 
++		}
+ 	}
+ 
+ 	if (!(iap->ia_valid & ATTR_MODE))
+@@ -886,16 +1050,19 @@
+ 	err = nfserr_perm;
+ 	switch (type) {
+ 	case S_IFREG:
+-		err = vfs_create(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_create(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFDIR:
+-		err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++		if (error == -EOPNOTSUPP)
++			err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ 		break;
+ 	case S_IFCHR:
+ 	case S_IFBLK:
+ 	case S_IFIFO:
+ 	case S_IFSOCK:
+-		err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++		if (error == -EOPNOTSUPP)	
++			err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ 		break;
+ 	default:
+ 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
+@@ -964,7 +1131,13 @@
+ 	/* Get all the sanity checks out of the way before
+ 	 * we lock the parent. */
+ 	err = nfserr_notdir;
+-	if(!dirp->i_op || !dirp->i_op->lookup)
++	if (dirp->i_op->mknod_raw) {
++		err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
++		if (err && err != -EOPNOTSUPP)
++			goto out;
++	}
++
++	if(!dirp->i_op ||  !(dirp->i_op->lookup || dirp->i_op->lookup_it))
+ 		goto out;
+ 	fh_lock(fhp);
+ 
+@@ -1015,6 +1188,8 @@
+ 		case NFS3_CREATE_GUARDED:
+ 			err = nfserr_exist;
+ 		}
++		if(dirp->i_op->mknod_raw)
++			err = 0;
+ 		goto out;
+ 	}
+ 
+@@ -1121,7 +1296,7 @@
+ 				struct iattr *iap)
+ {
+ 	struct dentry	*dentry, *dnew;
+-	int		err, cerr;
++	int		err, cerr, error = -EOPNOTSUPP;
+ 
+ 	err = nfserr_noent;
+ 	if (!flen || !plen)
+@@ -1135,12 +1310,18 @@
+ 		goto out;
+ 	fh_lock(fhp);
+ 	dentry = fhp->fh_dentry;
++	
++	if (dentry->d_inode->i_op->symlink_raw)
++		error = symlink_raw(dentry, fname, flen, path);
++
+ 	dnew = lookup_one_len(fname, dentry, flen);
+ 	err = PTR_ERR(dnew);
+ 	if (IS_ERR(dnew))
+ 		goto out_nfserr;
+ 
+-	err = vfs_symlink(dentry->d_inode, dnew, path);
++	err = error;
++	if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
++		err = vfs_symlink(dentry->d_inode, dnew, path);
+ 	if (!err) {
+ 		if (EX_ISSYNC(fhp->fh_export))
+ 			nfsd_sync_dir(dentry);
+@@ -1150,7 +1331,10 @@
+ 				iap->ia_valid |= ATTR_CTIME;
+ 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ 					| S_IFLNK;
+-				err = notify_change(dnew, iap);
++				if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
++					err = setattr_raw(dnew->d_inode, iap);
++ 				else
++					err = notify_change(dnew, iap);
+ 				if (err)
+ 					err = nfserrno(err);
+ 				else if (EX_ISSYNC(fhp->fh_export))
+@@ -1210,7 +1394,10 @@
+ 	dold = tfhp->fh_dentry;
+ 	dest = dold->d_inode;
+ 
+-	err = vfs_link(dold, dirp, dnew);
++	if (dirp->i_op->link_raw)
++		err = link_raw(dold, ddir, dnew);
++	else
++		err = vfs_link(dold, dirp, dnew);
+ 	if (!err) {
+ 		if (EX_ISSYNC(ffhp->fh_export)) {
+ 			nfsd_sync_dir(ddir);
+@@ -1295,7 +1482,10 @@
+ 			err = nfserr_perm;
+ 	} else
+ #endif
+-	err = vfs_rename(fdir, odentry, tdir, ndentry);
++	if(fdir->i_op->rename_raw)
++		err = rename_raw(fdentry, tdentry, odentry, ndentry);
++	else
++		err = vfs_rename(fdir, odentry, tdir, ndentry);
+ 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
+ 		nfsd_sync_dir(tdentry);
+ 		nfsd_sync_dir(fdentry);
+@@ -1316,7 +1506,7 @@
+ 	fill_post_wcc(tfhp);
+ 	double_up(&tdir->i_sem, &fdir->i_sem);
+ 	ffhp->fh_locked = tfhp->fh_locked = 0;
+-	
++
+ out:
+ 	return err;
+ }
+@@ -1362,9 +1552,15 @@
+ 			err = nfserr_perm;
+ 		} else
+ #endif
+-		err = vfs_unlink(dirp, rdentry);
++		if (dirp->i_op->unlink_raw)
++			err = unlink_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_unlink(dirp, rdentry);
+ 	} else { /* It's RMDIR */
+-		err = vfs_rmdir(dirp, rdentry);
++		if (dirp->i_op->rmdir_raw)
++			err = rmdir_raw(dentry, fname, flen, rdentry);
++		else
++			err = vfs_rmdir(dirp, rdentry);
+ 	}
+ 
+ 	dput(rdentry);
+Index: linux-2.4.22-vanilla/include/linux/fs.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/fs.h	2003-11-03 23:41:40.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/fs.h	2003-11-03 23:44:38.000000000 +0300
+@@ -93,6 +93,9 @@
+ #define FS_SINGLE	8 /* Filesystem that can have only one superblock */
+ #define FS_NOMOUNT	16 /* Never mount from userland */
+ #define FS_LITTER	32 /* Keeps the tree in dcache */
++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
++			   * exporting non device filesystems.
++			   */
+ #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
+ 				  * as nfs_rename() will be cleaned up
+ 				  */
+@@ -1115,6 +1118,9 @@
+ 			 struct nameidata *nd, struct lookup_intent *it);
+ extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
+ 			    int flags, struct lookup_intent *it);
++extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
++extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
++                                struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1411,6 +1417,8 @@
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
++                                         struct lookup_intent *);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+@@ -1425,6 +1433,8 @@
+ 
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
++extern struct inode * ilookup4(struct super_block *, unsigned long,
++                               find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+ 	return iget4(sb, ino, NULL, NULL);
+Index: linux-2.4.22-vanilla/kernel/ksyms.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/kernel/ksyms.c	2003-11-03 23:41:40.000000000 +0300
++++ linux-2.4.22-vanilla/kernel/ksyms.c	2003-11-03 23:44:38.000000000 +0300
+@@ -149,6 +149,7 @@
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
+ EXPORT_SYMBOL(iget4);
++EXPORT_SYMBOL(ilookup4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+ EXPORT_SYMBOL(force_delete);
+@@ -160,6 +161,7 @@
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);
+ EXPORT_SYMBOL(dcache_lock);
diff --git a/lustre/kernel_patches/patches/removepage-2.4.19-suse.patch b/lustre/kernel_patches/patches/removepage-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4602f9668492e8cf6f95d4b9dc032164e3a4b67b
--- /dev/null
+++ b/lustre/kernel_patches/patches/removepage-2.4.19-suse.patch
@@ -0,0 +1,30 @@
+ include/linux/fs.h |    1 +
+ mm/filemap.c       |    3 +++
+ 2 files changed, 4 insertions(+)
+
+Index: linux-2.4.19.SuSE/include/linux/fs.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/fs.h	Sun Nov 16 00:40:59 2003
++++ linux-2.4.19.SuSE/include/linux/fs.h	Sun Nov 16 01:38:06 2003
+@@ -428,6 +428,7 @@
+ 	int (*releasepage) (struct page *, int);
+ #define KERNEL_HAS_O_DIRECT /* this is for modules out of the kernel */
+ 	int (*direct_IO)(int, struct file *, struct kiobuf *, unsigned long, int);
++	void (*removepage)(struct page *); /* called when page gets removed from the inode */
+ };
+ 
+ struct address_space {
+Index: linux-2.4.19.SuSE/mm/filemap.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/mm/filemap.c	Sat Nov 15 18:02:15 2003
++++ linux-2.4.19.SuSE/mm/filemap.c	Sun Nov 16 01:37:11 2003
+@@ -97,6 +97,9 @@
+ {
+ 	struct address_space * mapping = page->mapping;
+ 
++	if (mapping->a_ops->removepage)
++		mapping->a_ops->removepage(page);
++	
+ 	mapping->nrpages--;
+ 	list_del(&page->list);
+ 	page->mapping = NULL;
diff --git a/lustre/kernel_patches/patches/removepage-2.4.20.patch b/lustre/kernel_patches/patches/removepage-2.4.20.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cc721e116c9c6373ef0a730d7446c57b4d04bd26
--- /dev/null
+++ b/lustre/kernel_patches/patches/removepage-2.4.20.patch
@@ -0,0 +1,28 @@
+ include/linux/fs.h |    1 +
+ mm/filemap.c       |    3 +++
+ 2 files changed, 4 insertions(+)
+
+--- linux-2.4.20-b_llpmd-l24/include/linux/fs.h~removepage-2.4.20	2003-09-05 11:45:42.000000000 -0700
++++ linux-2.4.20-b_llpmd-l24-zab/include/linux/fs.h	2003-09-05 11:46:25.000000000 -0700
+@@ -402,6 +402,7 @@ struct address_space_operations {
+ 	int (*releasepage) (struct page *, int);
+ #define KERNEL_HAS_O_DIRECT /* this is for modules out of the kernel */
+ 	int (*direct_IO)(int, struct inode *, struct kiobuf *, unsigned long, int);
++	void (*removepage)(struct page *); /* called when page gets removed from the inode */
+ };
+ 
+ struct address_space {
+--- linux-2.4.20-b_llpmd-l24/mm/filemap.c~removepage-2.4.20	2003-09-05 11:45:42.000000000 -0700
++++ linux-2.4.20-b_llpmd-l24-zab/mm/filemap.c	2003-09-05 11:46:25.000000000 -0700
+@@ -95,6 +95,9 @@ static inline void remove_page_from_inod
+ {
+ 	struct address_space * mapping = page->mapping;
+ 
++	if (mapping->a_ops->removepage)
++		mapping->a_ops->removepage(page);
++	
+ 	mapping->nrpages--;
+ 	list_del(&page->list);
+ 	page->mapping = NULL;
+
+_
diff --git a/lustre/kernel_patches/patches/removepage-2.6.0.patch b/lustre/kernel_patches/patches/removepage-2.6.0.patch
new file mode 100644
index 0000000000000000000000000000000000000000..268ca9779597bf5cbcbf5a6e7ea62e4fc3a866e3
--- /dev/null
+++ b/lustre/kernel_patches/patches/removepage-2.6.0.patch
@@ -0,0 +1,28 @@
+ include/linux/fs.h |    1 +
+ mm/filemap.c       |    3 +++
+ 2 files changed, 4 insertions(+)
+
+--- linux-2.6.0-test3-l25/include/linux/fs.h~removepage-2.6.0	2003-09-05 15:31:52.000000000 -0700
++++ linux-2.6.0-test3-l25-zab/include/linux/fs.h	2003-09-08 10:47:30.000000000 -0700
+@@ -311,6 +311,7 @@ struct address_space_operations {
+ 	int (*releasepage) (struct page *, int);
+ 	int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
+ 			loff_t offset, unsigned long nr_segs);
++	void (*removepage)(struct page *); /* called when page gets removed from the inode */
+ };
+ 
+ struct backing_dev_info;
+--- linux-2.6.0-test3-l25/mm/filemap.c~removepage-2.6.0	2003-08-08 21:34:39.000000000 -0700
++++ linux-2.6.0-test3-l25-zab/mm/filemap.c	2003-09-08 10:48:10.000000000 -0700
+@@ -81,6 +81,9 @@ void __remove_from_page_cache(struct pag
+ {
+ 	struct address_space *mapping = page->mapping;
+ 
++	if (mapping->a_ops->removepage)
++		mapping->a_ops->removepage(page);
++
+ 	radix_tree_delete(&mapping->page_tree, page->index);
+ 	list_del(&page->list);
+ 	page->mapping = NULL;
+
+_
diff --git a/lustre/kernel_patches/patches/resched-2.4.19-pre1.patch b/lustre/kernel_patches/patches/resched-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..567e1e8c855b5057d985f98038331d7137e7c454
--- /dev/null
+++ b/lustre/kernel_patches/patches/resched-2.4.19-pre1.patch
@@ -0,0 +1,16 @@
+Index: linux-2.4.19-pre1/include/linux/sched.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/sched.h	2003-11-21 04:05:05.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/sched.h	2003-11-21 04:10:29.000000000 +0300
+@@ -927,6 +927,11 @@
+ 	return res;
+ }
+ 
++static inline int need_resched(void)
++{
++	        return (unlikely(current->need_resched));
++}
++
+ #endif /* __KERNEL__ */
+ 
+ #endif
diff --git a/lustre/kernel_patches/patches/seq-private-2.4.19-pre1.patch b/lustre/kernel_patches/patches/seq-private-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..241bf3639fa22db3a54ff646f45325311d13a112
--- /dev/null
+++ b/lustre/kernel_patches/patches/seq-private-2.4.19-pre1.patch
@@ -0,0 +1,12 @@
+Index: linux-2.4.19-pre1/include/linux/seq_file.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/seq_file.h	2001-11-11 22:23:14.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/seq_file.h	2003-11-21 03:09:39.000000000 +0300
+@@ -12,6 +12,7 @@
+ 	loff_t index;
+ 	struct semaphore sem;
+ 	struct seq_operations *op;
++	void *private;
+ };
+ 
+ struct seq_operations {
diff --git a/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.22.patch b/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.22.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ab5afe808bcb4af3240140d58847d8f3edc61954
--- /dev/null
+++ b/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.22.patch
@@ -0,0 +1,717 @@
+%patch
+Index: linux-2.4.22-vanilla/mm/slab.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/slab.c	2003-11-17 15:42:13.000000000 +0300
++++ linux-2.4.22-vanilla/mm/slab.c	2003-11-18 01:15:35.000000000 +0300
+@@ -97,6 +97,8 @@
+ #define	FORCED_DEBUG	0
+ #endif
+ 
++#include	<linux/vmalloc.h>
++
+ /*
+  * Parameters for kmem_cache_reap
+  */
+@@ -825,6 +827,12 @@
+ 	return cachep;
+ }
+ 
++#ifdef CONFIG_DEBUG_UAF
++void * uaf_alloc(kmem_cache_t *, int gfp_mask);
++int uaf_cache_free(kmem_cache_t *, void *addr);
++int uaf_free(void *addr);
++struct page *uaf_vaddr_to_page(void *obj);
++#endif
+ 
+ #if DEBUG
+ /*
+@@ -1340,6 +1348,20 @@
+ 	unsigned long save_flags;
+ 	void* objp;
+ 
++#ifdef CONFIG_DEBUG_UAF
++	/* try to use uaf-allocator first */
++	objp = uaf_alloc(cachep, flags);
++	if (objp) {
++		if (cachep->ctor) {
++			unsigned long ctor_flags;
++			ctor_flags = SLAB_CTOR_CONSTRUCTOR;
++			if (!(flags & __GFP_WAIT))
++				ctor_flags |= SLAB_CTOR_ATOMIC;
++			cachep->ctor(objp, cachep, ctor_flags);
++		}
++		return objp;
++	}
++#endif
+ 	kmem_cache_alloc_head(cachep, flags);
+ try_again:
+ 	local_irq_save(save_flags);
+@@ -1576,6 +1598,10 @@
+ void kmem_cache_free (kmem_cache_t *cachep, void *objp)
+ {
+ 	unsigned long flags;
++#ifdef CONFIG_DEBUG_UAF
++	if (uaf_cache_free(cachep, objp))
++		return;
++#endif
+ #if DEBUG
+ 	CHECK_PAGE(virt_to_page(objp));
+ 	if (cachep != GET_PAGE_CACHE(virt_to_page(objp)))
+@@ -1601,6 +1627,10 @@
+ 
+ 	if (!objp)
+ 		return;
++#ifdef CONFIG_DEBUG_UAF
++	if (uaf_free((void *) objp))
++		return;
++#endif
+ 	local_irq_save(flags);
+ 	CHECK_PAGE(virt_to_page(objp));
+ 	c = GET_PAGE_CACHE(virt_to_page(objp));
+@@ -2075,3 +2105,460 @@
+ #endif
+ }
+ #endif
++
++
++
++#ifdef CONFIG_DEBUG_UAF
++
++#define MAX_UAF_OBJ_SIZE	8	/* in pages */
++#define UAF_ASSERT(xxx)		if (!(xxx)) BUG();
++#define UAF_DEBUG__
++#ifdef UAF_DEBUG
++#define uaf_printk(fmt,a...)	printk(fmt, ##a)
++#else
++#define uaf_printk(a,...)	
++#endif
++
++struct uaf_stats {
++	atomic_t uaf_allocated;
++	atomic_t uaf_allocations;
++	atomic_t uaf_failed;
++};
++
++static int uaf_max = 32768;
++static void *uaf_bitmap = NULL;
++static spinlock_t uaf_lock;
++static int uaf_last_found = 0;
++static int uaf_used = 0;
++static struct vm_struct *uaf_area = NULL;
++static struct uaf_stats uaf_stats[MAX_UAF_OBJ_SIZE + 1];
++
++static int __init uaf_setup(char *str)
++{
++        uaf_max = simple_strtoul(str, NULL, 0);
++        return 1;
++}
++
++__setup("uaf=", uaf_setup);
++
++
++void uaf_init(void)
++{
++	int size;
++
++	printk("UAF: total vmalloc-space - %lu\n",
++			VMALLOC_END - VMALLOC_START);
++
++	uaf_area = get_vm_area(PAGE_SIZE * uaf_max, VM_ALLOC);
++	if (!uaf_area) {
++		printk(KERN_ALERT "UAF: can't reserve %lu bytes in KVA\n",
++				PAGE_SIZE * uaf_max);
++		return;
++	}
++	
++	printk("UAF: reserved %lu bytes in KVA at 0x%p\n",
++			PAGE_SIZE * uaf_max, uaf_area->addr);
++
++	/* how many bytes we need to track space usage? */
++	size = uaf_max / 8 + 8;
++
++	uaf_bitmap = vmalloc(size);
++	if (!uaf_bitmap) {
++		printk(KERN_ALERT
++			"UAF: can't allocate %d bytes for bitmap\n", size);
++		return;
++	}
++	memset(uaf_bitmap, 0, size);
++	spin_lock_init(&uaf_lock);
++	memset(uaf_stats, 0, sizeof(uaf_stats));
++
++	printk("UAF: allocated %d for bitmap\n", size);
++}
++
++static int uaf_find(int len)
++{
++	int new_last_found = -1;
++	int loop = 0;
++	int i, j;
++
++	j = uaf_last_found;
++
++	do {
++		i = find_next_zero_bit(uaf_bitmap, uaf_max, j);
++		if (i >= uaf_max) {
++			/* repeat from 0 */
++			if (++loop > 1) {
++				/* this is 2nd loop and it's useless */
++				return -1;
++			}
++
++			i = find_next_zero_bit(uaf_bitmap, uaf_max, 0);
++			if (i >= uaf_max)
++				return -1;
++
++			/* save found num for subsequent searches */
++			if (new_last_found == -1)
++				new_last_found = uaf_last_found = i;
++			UAF_ASSERT(new_last_found < uaf_max);
++		}
++
++		/*
++		 * OK. found first zero bit.
++		 * now, try to find requested cont. zero-space
++		 */
++
++		/* FIXME: implmement multipage allocation! */
++		break;
++
++		/*
++		j = find_next_bit(uaf_bitmap, uaf_max, i);
++		if (++loop2 > 10000) {
++			printk("ALERT: loop2=%d\n", loop2);
++			return -1;
++		}
++		*/
++	} while (j - i < len);
++
++	/* found! */
++	if (new_last_found == -1)
++		uaf_last_found = i + 1;
++	if (uaf_last_found >= uaf_max)
++		uaf_last_found = 0;
++	return i;
++}
++
++extern int __vmalloc_area_pages (unsigned long address, unsigned long size,
++					int gfp_mask, pgprot_t prot,
++					struct page ***pages);
++void * uaf_alloc(kmem_cache_t *cachep, int gfp_mask)
++{
++	struct page *ptrs[MAX_UAF_OBJ_SIZE];
++	int size = cachep->objsize;
++	struct page **pages;
++	unsigned long flags;
++	unsigned long addr;
++	int i, j, err = -2000;
++
++	if (uaf_bitmap == NULL)
++		return NULL;
++
++	if (!(cachep->flags & SLAB_USE_UAF))
++		return NULL;
++
++	pages = (struct page **) ptrs;
++	size = (size + (PAGE_SIZE - 1)) / PAGE_SIZE;
++	/* FIXME: implement multipage allocation! */
++	if (size > 1)
++		return NULL;
++	if (size > MAX_UAF_OBJ_SIZE) {
++		printk(KERN_ALERT "size is too big: %d\n", size);
++		return NULL;
++	}
++
++	if (uaf_used == uaf_max) {
++		uaf_printk("UAF: space exhausted!\n");
++		atomic_inc(&uaf_stats[size].uaf_failed);
++		return NULL;
++	}
++
++
++	spin_lock_irqsave(&uaf_lock, flags);
++	i = uaf_find(size);
++	if (i < 0) {
++		spin_unlock_irqrestore(&uaf_lock, flags);
++		atomic_inc(&uaf_stats[size].uaf_failed);
++		return NULL;
++	}
++	for (j = 0; j < size; j++) {
++		UAF_ASSERT(!test_bit(i + j, uaf_bitmap));
++		set_bit(i + j, uaf_bitmap);
++		uaf_used++;
++	}
++	spin_unlock_irqrestore(&uaf_lock, flags);
++
++	addr = ((unsigned long) uaf_area->addr) + (PAGE_SIZE * i);
++	uaf_printk("UAF: found %d/%d, base 0x%p, map at 0x%lx: ", i,
++			size, uaf_area->addr, addr);
++
++	/* OK. we've found free space, let's allocate pages */
++	memset(pages, 0, sizeof(struct page *) * MAX_UAF_OBJ_SIZE);
++	for (j = 0; j < size; j++) {
++		pages[j] = alloc_page(gfp_mask);
++		if (pages[j] == NULL)
++			goto nomem;
++		uaf_printk("0x%p ", pages[j]);
++	}
++
++	/* time to map just allocated pages */
++	err = __vmalloc_area_pages(addr, PAGE_SIZE * size, gfp_mask,
++					PAGE_KERNEL, &pages);
++	pages = (struct page **) ptrs;
++	if (err == 0) {
++		/* put slab cache pointer in first page */
++		ptrs[0]->list.next = (void *) cachep;
++		uaf_printk(" -> 0x%lx\n", addr);
++		atomic_inc(&uaf_stats[size].uaf_allocated);
++		atomic_inc(&uaf_stats[size].uaf_allocations);
++		if (!in_interrupt() && !in_softirq())
++			flush_tlb_all();
++		else
++			local_flush_tlb();
++		//printk("UAF: found %d/%d, base 0x%p, map at 0x%lx\n",
++		//		i, cachep->objsize, uaf_area->addr, addr);
++		return (void *) addr;
++	}
++
++nomem:
++	printk(KERN_ALERT "can't map pages: %d\n", err);
++	for (j = 0; j < size; j++)
++		if (pages[j])
++			__free_page(pages[j]);
++
++	/* can't find free pages */
++	spin_lock_irqsave(&uaf_lock, flags);
++	for (j = 0; j < size; j++) {
++		clear_bit(i + j, uaf_bitmap);
++		uaf_used--;
++	}
++	spin_unlock_irqrestore(&uaf_lock, flags);
++	atomic_inc(&uaf_stats[size].uaf_failed);
++
++	return NULL;
++}
++
++extern void free_area_pmd(pgd_t *dir, unsigned long address,
++				  unsigned long size);
++static void uaf_unmap(unsigned long address, unsigned long size)
++{
++	unsigned long end = (address + size);
++	pgd_t *dir;
++
++	dir = pgd_offset_k(address);
++	flush_cache_all();
++	do {
++		free_area_pmd(dir, address, end - address);
++		address = (address + PGDIR_SIZE) & PGDIR_MASK;
++		dir++;
++	} while (address && (address < end));
++
++	/*
++	 * we must not call smp_call_function() with interrtups disabled
++	 * otherwise we can get into deadlock
++	 */
++	if (!in_interrupt() && !in_softirq())
++		flush_tlb_all();
++	else
++		local_flush_tlb();
++}
++
++/*
++ * returns 1 if free was successfull
++ */
++int uaf_cache_free(kmem_cache_t *cachep, void *addr)
++{
++	struct page *pages[MAX_UAF_OBJ_SIZE];
++	int size = cachep->objsize;
++	unsigned long flags;
++	int i, j;
++
++	uaf_printk("UAF: to free 0x%p/%d\n", addr, size);
++
++	size = (size + (PAGE_SIZE - 1)) / PAGE_SIZE;
++	if (size > MAX_UAF_OBJ_SIZE)
++		return 0;
++
++	if (uaf_bitmap == NULL)
++		return 0;
++
++	/* first, check is address is in UAF space */
++	if ((unsigned) addr < (unsigned) uaf_area->addr ||
++		(unsigned) addr >= (unsigned) uaf_area->addr + uaf_area->size)
++		return 0;
++
++	UAF_ASSERT(((unsigned long) addr & ~PAGE_MASK) == 0UL);
++	
++	/* calculate placement in bitmap */
++	i = (unsigned) addr - (unsigned) uaf_area->addr;
++	UAF_ASSERT(i >= 0);
++	i = i / PAGE_SIZE;
++
++	/* collect all the pages */
++	uaf_printk("free/unmap %d pages: ", size);
++	/* NOTE: we need not page_table_lock here. bits in bitmap
++	 * protect those pte's from to be reused */
++	for (j = 0; j < size; j++) {
++		unsigned long address;
++		address = ((unsigned long) addr) + (PAGE_SIZE * j);
++		pages[j] = vmalloc_to_page((void *) address);
++		uaf_printk("0x%lx->0x%p ", address, pages[j]);
++	}
++	uaf_printk("\n");
++
++	uaf_unmap((unsigned long) addr, PAGE_SIZE * size);
++	/* free all the pages */
++	for (j = 0; j < size; j++)
++		__free_page(pages[j]);
++
++	spin_lock_irqsave(&uaf_lock, flags);
++	for (j = 0; j < size; j++) {
++		/* now check is correspondend bit set */
++		UAF_ASSERT(i+j >= 0 && i+j < uaf_max);
++		UAF_ASSERT(test_bit(i+j, uaf_bitmap));
++		
++		/* now free space in UAF */
++		clear_bit(i+j, uaf_bitmap);
++		uaf_used--;
++	}
++	spin_unlock_irqrestore(&uaf_lock, flags);
++
++	atomic_dec(&uaf_stats[size].uaf_allocated);
++	
++	uaf_printk("UAF: freed %d/%d at 0x%p\n", i, size, addr);
++	//printk("UAF: freed %d/%d at 0x%p\n", i, size, addr);
++
++	return 1;
++}
++
++struct page *uaf_vaddr_to_page(void *obj)
++{
++	if (uaf_bitmap == NULL)
++		return NULL;
++
++	/* first, check is address is in UAF space */
++	if ((unsigned) obj < (unsigned) uaf_area->addr ||
++		(unsigned) obj >= (unsigned) uaf_area->addr + uaf_area->size)
++		return NULL;
++	
++	return vmalloc_to_page(obj);
++}
++
++int uaf_free(void *obj)
++{
++	struct page *page = uaf_vaddr_to_page((void *) obj);
++	kmem_cache_t *c;
++
++	if (!page)
++		return 0;
++
++	c = GET_PAGE_CACHE(page);
++	return uaf_cache_free(c, (void *) obj);
++}
++
++int uaf_is_allocated(void *obj)
++{
++	unsigned long addr = (unsigned long) obj;
++	int i;
++
++	if (uaf_bitmap == NULL)
++		return 0;
++
++	addr &= PAGE_MASK;
++	/* first, check is address is in UAF space */
++	if (addr < (unsigned long) uaf_area->addr ||
++			addr >= (unsigned long) uaf_area->addr + uaf_area->size)
++		return 0;
++
++	/* calculate placement in bitmap */
++	i = (unsigned) addr - (unsigned) uaf_area->addr;
++	i = i / PAGE_SIZE;
++	return test_bit(i, uaf_bitmap);
++}
++
++static void *uaf_s_start(struct seq_file *m, loff_t *pos)
++{
++	loff_t n = *pos;
++
++	if (!n)
++		seq_printf(m, "size(pgs) allocated failed allocations. "
++				"%d reserved, %d in use, %d last\n",
++				uaf_max, uaf_used, uaf_last_found);
++	else if (n > MAX_UAF_OBJ_SIZE)
++		return NULL;
++
++	*pos = 1;
++	return (void *) 1;
++}
++
++static void *uaf_s_next(struct seq_file *m, void *p, loff_t *pos)
++{
++	unsigned long n = *pos;
++	++*pos;
++	if (n + 1 > MAX_UAF_OBJ_SIZE)
++		return NULL;
++	return (void *) (n + 1);
++}
++
++static void uaf_s_stop(struct seq_file *m, void *p)
++{
++}
++
++static int uaf_s_show(struct seq_file *m, void *p)
++{
++	int n = (int) p;
++
++	if (n > MAX_UAF_OBJ_SIZE)
++		return 0;
++	seq_printf(m, "%d  %d  %d %d\n", n, 
++			atomic_read(&uaf_stats[n].uaf_allocated),
++			atomic_read(&uaf_stats[n].uaf_failed),
++			atomic_read(&uaf_stats[n].uaf_allocations));
++	return 0;
++}
++
++struct seq_operations uafinfo_op = {
++	.start	= uaf_s_start,
++	.next	= uaf_s_next,
++	.stop	= uaf_s_stop,
++	.show	= uaf_s_show,
++};
++
++ssize_t uafinfo_write(struct file *file, const char *buffer,
++				size_t count, loff_t *ppos)
++{
++	char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
++	char *key, *name;
++	int res;
++	struct list_head *p;
++	
++	if (count > MAX_SLABINFO_WRITE)
++		return -EINVAL;
++	if (copy_from_user(&kbuf, buffer, count))
++		return -EFAULT;
++	kbuf[MAX_SLABINFO_WRITE] = '\0'; 
++
++	tmp = kbuf;
++	key = strsep(&tmp, " \t\n");
++	if (!key)
++		return -EINVAL;
++	if (!strcmp(key, "on"))
++		res = 1;
++	else if (!strcmp(key, "off"))
++		res = 0;
++	else
++		return -EINVAL;
++
++	name = strsep(&tmp, " \t\n");
++	if (!name)
++		return -EINVAL;
++
++	/* Find the cache in the chain of caches. */
++	down(&cache_chain_sem);
++	list_for_each(p,&cache_chain) {
++		kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
++
++		if (!strcmp(cachep->name, name)) {
++			if (res) {
++				printk("UAF: use on %s\n", cachep->name);
++				cachep->flags |= SLAB_USE_UAF;
++			} else {
++				printk("UAF: dont use on %s\n", cachep->name);
++				cachep->flags &= ~SLAB_USE_UAF;
++			}
++			break;
++		}
++	}
++	up(&cache_chain_sem);
++	return count;
++}
++#endif
++
+Index: linux-2.4.22-vanilla/init/main.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/init/main.c	2003-11-03 23:22:13.000000000 +0300
++++ linux-2.4.22-vanilla/init/main.c	2003-11-18 01:06:45.000000000 +0300
+@@ -436,6 +436,9 @@
+ 	 *	make syscalls (and thus be locked).
+ 	 */
+ 	smp_init();
++#ifdef CONFIG_DEBUG_UAF
++	uaf_init();
++#endif
+ 	rest_init();
+ }
+ 
+Index: linux-2.4.22-vanilla/fs/proc/proc_misc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/fs/proc/proc_misc.c	2003-11-03 23:22:11.000000000 +0300
++++ linux-2.4.22-vanilla/fs/proc/proc_misc.c	2003-11-18 01:06:45.000000000 +0300
+@@ -301,6 +301,22 @@
+ 	release:	seq_release,
+ };
+ 
++#ifdef CONFIG_DEBUG_UAF
++extern struct seq_operations uafinfo_op;
++extern ssize_t uafinfo_write(struct file *, const char *, size_t, loff_t *);
++static int uafinfo_open(struct inode *inode, struct file *file)
++{
++	return seq_open(file, &uafinfo_op);
++}
++static struct file_operations proc_uafinfo_operations = {
++	.open		= uafinfo_open,
++	.read		= seq_read,
++	.write		= uafinfo_write,
++	.llseek		= seq_lseek,
++	.release	= seq_release,
++};
++#endif
++
+ static int kstat_read_proc(char *page, char **start, off_t off,
+ 				 int count, int *eof, void *data)
+ {
+@@ -616,6 +632,9 @@
+ 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+ 	create_seq_entry("partitions", 0, &proc_partitions_operations);
+ 	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
++#ifdef CONFIG_DEBUG_UAF
++	create_seq_entry("uafinfo",S_IWUSR|S_IRUGO,&proc_uafinfo_operations);
++#endif
+ #ifdef CONFIG_MODULES
+ 	create_seq_entry("ksyms", 0, &proc_ksyms_operations);
+ #endif
+Index: linux-2.4.22-vanilla/include/linux/slab.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/linux/slab.h	2003-11-17 15:42:13.000000000 +0300
++++ linux-2.4.22-vanilla/include/linux/slab.h	2003-11-18 02:14:40.000000000 +0300
+@@ -40,6 +40,7 @@
+ #define	SLAB_HWCACHE_ALIGN	0x00002000UL	/* align objs on a h/w cache lines */
+ #define SLAB_CACHE_DMA		0x00004000UL	/* use GFP_DMA memory */
+ #define SLAB_MUST_HWCACHE_ALIGN	0x00008000UL	/* force alignment */
++#define SLAB_USE_UAF		0x00040000UL	/* use UAF allocator */
+ 
+ /* flags passed to a constructor func */
+ #define	SLAB_CTOR_CONSTRUCTOR	0x001UL		/* if not set, then deconstructor */
+Index: linux-2.4.22-vanilla/arch/i386/config.in
+===================================================================
+--- linux-2.4.22-vanilla.orig/arch/i386/config.in	2003-11-03 23:22:06.000000000 +0300
++++ linux-2.4.22-vanilla/arch/i386/config.in	2003-11-18 01:06:45.000000000 +0300
+@@ -470,6 +470,9 @@
+    bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
+    bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
+    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
++   if [ "$CONFIG_DEBUG_SLAB" != "n" ]; then
++      bool '  Debug memory allocations (use-after-free via vmalloced space)' CONFIG_DEBUG_UAF
++   fi
+    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
+    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
+    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+Index: linux-2.4.22-vanilla/mm/vmalloc.c
+===================================================================
+--- linux-2.4.22-vanilla.orig/mm/vmalloc.c	2003-11-03 23:22:13.000000000 +0300
++++ linux-2.4.22-vanilla/mm/vmalloc.c	2003-11-18 01:06:45.000000000 +0300
+@@ -53,7 +53,7 @@
+ 	} while (address < end);
+ }
+ 
+-static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size)
++void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size)
+ {
+ 	pmd_t * pmd;
+ 	unsigned long end;
+@@ -152,7 +152,7 @@
+ 	return 0;
+ }
+ 
+-static inline int __vmalloc_area_pages (unsigned long address,
++int __vmalloc_area_pages (unsigned long address,
+ 					unsigned long size,
+ 					int gfp_mask,
+ 					pgprot_t prot,
+Index: linux-2.4.22-vanilla/include/asm-i386/io.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-i386/io.h	2003-11-17 14:58:37.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-i386/io.h	2003-11-18 02:26:42.000000000 +0300
+@@ -75,6 +75,16 @@
+  
+ static inline unsigned long virt_to_phys(volatile void * address)
+ {
++#ifdef CONFIG_DEBUG_UAF
++	unsigned long addr = (unsigned long) address;
++	if (vmlist && addr >= VMALLOC_START && addr < VMALLOC_END) {
++		struct page *page = vmalloc_to_page((void *) address);
++		if (page) {
++			unsigned long offset = addr & ~PAGE_MASK;
++			address = page_address(page) + offset;
++		}
++	}
++#endif
+ 	return __pa(address);
+ }
+ 
+Index: linux-2.4.22-vanilla/include/asm-i386/page.h
+===================================================================
+--- linux-2.4.22-vanilla.orig/include/asm-i386/page.h	2003-11-03 23:51:46.000000000 +0300
++++ linux-2.4.22-vanilla/include/asm-i386/page.h	2003-11-18 02:14:38.000000000 +0300
+@@ -129,9 +129,49 @@
+ #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
+ #define __MAXMEM		(-__PAGE_OFFSET-__VMALLOC_RESERVE)
+ #define MAXMEM			((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
++
++#ifndef CONFIG_DEBUG_UAF
+ #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+ #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+ #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
++#else
++#define __pa(x)		({							\
++				unsigned long __pn, __fr;			\
++				__pn = (unsigned long)(x)-PAGE_OFFSET;		\
++				__fr = __pn >> PAGE_SHIFT;			\
++				if (jiffies > HZ*3 && __fr >= max_mapnr) {	\
++					printk("invalid arg __pa(0x%x)"		\
++						" at %s:%d\n", (unsigned) (x),	\
++						__FILE__, __LINE__);		\
++					dump_stack();				\
++				}						\
++				__pn;						\
++			})
++
++#define __va(x)		({							\
++				unsigned long __pn;				\
++				__pn = (unsigned long) (x) >> PAGE_SHIFT;	\
++				if (jiffies > HZ*3 && __pn >= max_mapnr) {	\
++					printk("invalid arg __va(0x%x)"		\
++						" at %s:%d\n", (unsigned) (x),	\
++						__FILE__, __LINE__);		\
++					dump_stack();				\
++				}						\
++				((void *)((unsigned long)(x) + PAGE_OFFSET));	\
++			})
++
++#define virt_to_page(ka) ({							\
++				struct page *_p;				\
++				if ((unsigned long)(ka) >= VMALLOC_START) {	\
++					_p = vmalloc_to_page((void *)(ka));	\
++					BUG_ON(!_p);				\
++				} else 						\
++					_p = mem_map+(__pa(ka) >> PAGE_SHIFT);	\
++				(_p);						\
++			})
++#endif
++
++
+ #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+ 
+ #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+
+%diffstat
+ arch/i386/config.in     |    3 
+ fs/proc/proc_misc.c     |   19 +
+ include/asm-i386/io.h   |   10 
+ include/asm-i386/page.h |   40 +++
+ include/linux/slab.h    |    1 
+ init/main.c             |    3 
+ mm/slab.c               |  487 ++++++++++++++++++++++++++++++++++++++++++++++++
+ mm/vmalloc.c            |    4 
+ 8 files changed, 565 insertions(+), 2 deletions(-)
+
diff --git a/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch b/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..08ca1b256e8a523ca647f0674c4c0afc9ed93371
--- /dev/null
+++ b/lustre/kernel_patches/patches/socket-exports-2.4.22-rh.patch
@@ -0,0 +1,41 @@
+ include/linux/socket.h |    4 ++++
+ net/netsyms.c          |    1 +
+ net/socket.c           |    2 +-
+ 3 files changed, 6 insertions(+), 1 deletion(-)
+
+--- linux-2.4.22-ac1/include/linux/socket.h~socket-exports-2.4.22-rh	2003-06-13 18:51:39.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/socket.h	2003-09-26 00:49:43.000000000 +0400
+@@ -275,6 +275,10 @@ extern void memcpy_tokerneliovec(struct 
+ extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen);
+ extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
+ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
++struct socket;
++extern int sock_map_fd(struct socket *sock);
++extern struct socket *sockfd_lookup(int fd, int *err);
++
+ #endif
+ #endif /* not kernel and not glibc */
+ #endif /* _LINUX_SOCKET_H */
+--- linux-2.4.22-ac1/net/netsyms.c~socket-exports-2.4.22-rh	2003-09-26 00:49:19.000000000 +0400
++++ linux-2.4.22-ac1-alexey/net/netsyms.c	2003-09-26 00:50:20.000000000 +0400
+@@ -163,6 +163,7 @@ EXPORT_SYMBOL(put_cmsg);
+ EXPORT_SYMBOL(sock_kmalloc);
+ EXPORT_SYMBOL(sock_kfree_s);
+ EXPORT_SYMBOL(sockfd_lookup);
++EXPORT_SYMBOL(sock_map_fd);
+ 
+ #ifdef CONFIG_FILTER
+ EXPORT_SYMBOL(sk_run_filter);
+--- linux-2.4.22-ac1/net/socket.c~socket-exports-2.4.22-rh	2003-08-25 15:44:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/net/socket.c	2003-09-26 00:49:43.000000000 +0400
+@@ -325,7 +325,7 @@ static struct dentry_operations sockfs_d
+  *	but we take care of internal coherence yet.
+  */
+ 
+-static int sock_map_fd(struct socket *sock)
++int sock_map_fd(struct socket *sock)
+ {
+ 	int fd;
+ 	struct qstr this;
+
+_
diff --git a/lustre/kernel_patches/patches/tcp-zero-copy-2.4.22-rh.patch b/lustre/kernel_patches/patches/tcp-zero-copy-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..65baef519ba5ba68600f2502584e3a8e7e180f08
--- /dev/null
+++ b/lustre/kernel_patches/patches/tcp-zero-copy-2.4.22-rh.patch
@@ -0,0 +1,459 @@
+ include/linux/skbuff.h |   30 +++++
+ include/net/tcp.h      |    5 
+ net/core/skbuff.c      |   25 ++++
+ net/ipv4/tcp.c         |  252 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ net/netsyms.c          |    2 
+ 5 files changed, 311 insertions(+), 3 deletions(-)
+
+--- linux-2.4.22-ac1/include/linux/skbuff.h~tcp-zero-copy-2.4.22-rh	2003-08-25 15:44:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/skbuff.h	2003-09-26 00:38:48.000000000 +0400
+@@ -116,6 +116,30 @@ struct skb_frag_struct
+ 	__u16 size;
+ };
+ 
++/* Support for callback when skb data has been released */
++typedef struct zccd				/* Zero Copy Callback Descriptor */
++{						/* (embed as first member of custom struct) */
++	atomic_t	zccd_count;		/* reference count */
++	void           (*zccd_destructor)(struct zccd *); /* callback when refcount reaches zero */
++} zccd_t;
++
++static inline void zccd_init (zccd_t *d, void (*callback)(zccd_t *))
++{
++	atomic_set (&d->zccd_count, 1);
++	d->zccd_destructor = callback;
++}
++
++static inline void zccd_get (zccd_t *d)		/* take a reference */
++{
++	atomic_inc (&d->zccd_count);
++}
++
++static inline void zccd_put (zccd_t *d)		/* release a reference */
++{
++	if (atomic_dec_and_test (&d->zccd_count))
++		(d->zccd_destructor)(d);
++}
++
+ /* This data is invariant across clones and lives at
+  * the end of the header data, ie. at skb->end.
+  */
+@@ -123,6 +147,12 @@ struct skb_shared_info {
+ 	atomic_t	dataref;
+ 	unsigned int	nr_frags;
+ 	struct sk_buff	*frag_list;
++	zccd_t          *zccd;			/* zero copy descriptor */
++	zccd_t		*zccd2;			/* 2nd zero copy descriptor */
++	/* NB we expect zero-copy data to be at least 1 packet, so
++	 * having 2 zccds means we don't unneccessarily split the packet
++	 * where consecutive zero-copy sends abutt.
++	 */
+ 	skb_frag_t	frags[MAX_SKB_FRAGS];
+ };
+ 
+--- linux-2.4.22-ac1/include/net/tcp.h~tcp-zero-copy-2.4.22-rh	2003-08-25 15:44:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/net/tcp.h	2003-09-26 00:38:48.000000000 +0400
+@@ -643,6 +643,8 @@ extern int		    	tcp_v4_tw_remember_stam
+ 
+ extern int			tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size);
+ extern ssize_t			tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
++extern ssize_t			tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size,
++						  int flags, zccd_t *zccd);
+ 
+ extern int			tcp_ioctl(struct sock *sk, 
+ 					  int cmd, 
+@@ -737,6 +739,9 @@ extern int			tcp_recvmsg(struct sock *sk
+ 					    struct msghdr *msg,
+ 					    int len, int nonblock, 
+ 					    int flags, int *addr_len);
++extern int			tcp_recvpackets(struct sock *sk,
++						struct sk_buff_head *packets,
++						int len, int nonblock);
+ 
+ extern int			tcp_listen_start(struct sock *sk);
+ 
+--- linux-2.4.22-ac1/net/core/skbuff.c~tcp-zero-copy-2.4.22-rh	2003-08-25 15:44:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/net/core/skbuff.c	2003-09-26 00:38:48.000000000 +0400
+@@ -208,6 +208,8 @@ struct sk_buff *alloc_skb(unsigned int s
+ 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
+ 	skb_shinfo(skb)->nr_frags = 0;
+ 	skb_shinfo(skb)->frag_list = NULL;
++	skb_shinfo(skb)->zccd = NULL;		/* skbuffs kick off with NO user zero copy descriptors */
++	skb_shinfo(skb)->zccd2 = NULL;
+ 	return skb;
+ 
+ nodata:
+@@ -277,6 +279,10 @@ static void skb_release_data(struct sk_b
+ {
+ 	if (!skb->cloned ||
+ 	    atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) {
++		if (skb_shinfo(skb)->zccd != NULL) /* zero copy callback descriptor? */
++			zccd_put (skb_shinfo(skb)->zccd); /* release hold */
++		if (skb_shinfo(skb)->zccd2 != NULL) /* 2nd zero copy callback descriptor? */
++			zccd_put (skb_shinfo(skb)->zccd2); /* release hold */
+ 		if (skb_shinfo(skb)->nr_frags) {
+ 			int i;
+ 			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+@@ -535,6 +541,8 @@ int skb_linearize(struct sk_buff *skb, i
+ 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
+ 	skb_shinfo(skb)->nr_frags = 0;
+ 	skb_shinfo(skb)->frag_list = NULL;
++	skb_shinfo(skb)->zccd = NULL;		/* copied data => no user zero copy descriptor */
++	skb_shinfo(skb)->zccd2 = NULL;
+ 
+ 	/* We are no longer a clone, even if we were. */
+ 	skb->cloned = 0;
+@@ -581,6 +589,14 @@ struct sk_buff *pskb_copy(struct sk_buff
+ 	n->data_len = skb->data_len;
+ 	n->len = skb->len;
+ 
++	if (skb_shinfo(skb)->zccd != NULL)	/* user zero copy descriptor? */
++		zccd_get (skb_shinfo(skb)->zccd); /* 1 more ref (pages are shared) */
++	skb_shinfo(n)->zccd = skb_shinfo(skb)->zccd;
++
++	if (skb_shinfo(skb)->zccd2 != NULL)	/* 2nd user zero copy descriptor? */
++		zccd_get (skb_shinfo(skb)->zccd2); /* 1 more ref (pages are shared) */
++	skb_shinfo(n)->zccd2 = skb_shinfo(skb)->zccd2;
++
+ 	if (skb_shinfo(skb)->nr_frags) {
+ 		int i;
+ 
+@@ -623,6 +639,8 @@ int pskb_expand_head(struct sk_buff *skb
+ 	u8 *data;
+ 	int size = nhead + (skb->end - skb->head) + ntail;
+ 	long off;
++	zccd_t *zccd = skb_shinfo(skb)->zccd;	/* stash user zero copy descriptor */
++	zccd_t *zccd2 = skb_shinfo(skb)->zccd2;	/* stash 2nd user zero copy descriptor */
+ 
+ 	if (skb_shared(skb))
+ 		BUG();
+@@ -644,6 +662,11 @@ int pskb_expand_head(struct sk_buff *skb
+ 	if (skb_shinfo(skb)->frag_list)
+ 		skb_clone_fraglist(skb);
+ 
++	if (zccd != NULL)			/* user zero copy descriptor? */
++		zccd_get (zccd);		/* extra ref (pages are shared) */
++	if (zccd2 != NULL)			/* 2nd user zero copy descriptor? */
++		zccd_get (zccd2);		/* extra ref (pages are shared) */
++
+ 	skb_release_data(skb);
+ 
+ 	off = (data+nhead) - skb->head;
+@@ -658,6 +681,8 @@ int pskb_expand_head(struct sk_buff *skb
+ 	skb->nh.raw += off;
+ 	skb->cloned = 0;
+ 	atomic_set(&skb_shinfo(skb)->dataref, 1);
++	skb_shinfo(skb)->zccd = zccd;
++	skb_shinfo(skb)->zccd2 = zccd2;
+ 	return 0;
+ 
+ nodata:
+--- linux-2.4.22-ac1/net/ipv4/tcp.c~tcp-zero-copy-2.4.22-rh	2003-08-25 15:44:44.000000000 +0400
++++ linux-2.4.22-ac1-alexey/net/ipv4/tcp.c	2003-09-26 00:38:48.000000000 +0400
+@@ -747,7 +747,7 @@ do_interrupted:
+ 	goto out;
+ }
+ 
+-ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags);
++ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd);
+ 
+ static inline int
+ can_coalesce(struct sk_buff *skb, int i, struct page *page, int off)
+@@ -826,7 +826,8 @@ static int tcp_error(struct sock *sk, in
+ 	return err;
+ }
+ 
+-ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags)
++/* Extra parameter: user zero copy descriptor (or NULL if not doing that) */
++ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd)
+ {
+ 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ 	int mss_now;
+@@ -874,6 +875,17 @@ new_segment:
+ 			copy = size;
+ 
+ 		i = skb_shinfo(skb)->nr_frags;
++
++		if (zccd != NULL &&		/* this is a zcc I/O */
++		    skb_shinfo(skb)->zccd != NULL && /* skb is part of a zcc I/O */
++		    skb_shinfo(skb)->zccd2 != NULL &&
++		    skb_shinfo(skb)->zccd != zccd && /* not the same one */
++		    skb_shinfo(skb)->zccd2 != zccd)
++		{
++			tcp_mark_push (tp, skb);
++			goto new_segment;
++		}
++
+ 		if (can_coalesce(skb, i, page, offset)) {
+ 			skb_shinfo(skb)->frags[i-1].size += copy;
+ 		} else if (i < MAX_SKB_FRAGS) {
+@@ -884,6 +896,20 @@ new_segment:
+ 			goto new_segment;
+ 		}
+ 
++		if (zccd != NULL &&	/* this is a zcc I/O */
++		    skb_shinfo(skb)->zccd != zccd && /* not already referencing this zccd */
++		    skb_shinfo(skb)->zccd2 != zccd)
++		{
++			zccd_get (zccd);	/* bump ref count */
++
++			BUG_TRAP (skb_shinfo(skb)->zccd2 == NULL);
++
++			if (skb_shinfo(skb)->zccd == NULL) /* reference this zccd */
++				skb_shinfo(skb)->zccd = zccd;
++			else
++				skb_shinfo(skb)->zccd2 = zccd;
++		}
++
+ 		skb->len += copy;
+ 		skb->data_len += copy;
+ 		skb->ip_summed = CHECKSUM_HW;
+@@ -947,7 +973,31 @@ ssize_t tcp_sendpage(struct socket *sock
+ 
+ 	lock_sock(sk);
+ 	TCP_CHECK_TIMER(sk);
+-	res = do_tcp_sendpages(sk, &page, offset, size, flags);
++	res = do_tcp_sendpages(sk, &page, offset, size, flags, NULL);
++	TCP_CHECK_TIMER(sk);
++	release_sock(sk);
++	return res;
++}
++
++ssize_t tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size,
++			  int flags, zccd_t *zccd)
++{
++	ssize_t res;
++	struct sock *sk = sock->sk;
++
++#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
++
++	if (!(sk->route_caps & NETIF_F_SG) || 	/* caller shouldn't waste her time */
++	    !(sk->route_caps & TCP_ZC_CSUM_FLAGS)) /* on double mapping */
++		BUG ();
++
++#undef TCP_ZC_CSUM_FLAGS
++
++	lock_sock(sk);
++	TCP_CHECK_TIMER(sk);
++
++	res = do_tcp_sendpages(sk, &page, offset, size, flags, zccd);
++
+ 	TCP_CHECK_TIMER(sk);
+ 	release_sock(sk);
+ 	return res;
+@@ -1771,6 +1821,202 @@ recv_urg:
+ 	goto out;
+ }
+ 
++int tcp_recvpackets (struct sock *sk, struct sk_buff_head *packets,
++		     int len, int nonblock)
++{
++	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
++	int copied;
++	long timeo;
++
++	BUG_TRAP (len > 0);
++	/*BUG_TRAP ((flags & (MSG_OOB | MSG_PEEK | MSG_TRUNC)) == 0);*/
++
++	lock_sock(sk);
++
++	TCP_CHECK_TIMER(sk);
++
++	copied = -ENOTCONN;
++	if (sk->state == TCP_LISTEN)
++		goto out;
++
++	copied = 0;
++	timeo = sock_rcvtimeo(sk, nonblock);
++
++	do {
++		struct sk_buff * skb;
++		u32 offset;
++		unsigned long used;
++		int exhausted;
++		int eaten;
++
++		/* Are we at urgent data? Stop if we have read anything. */
++		if (copied && tp->urg_data && tp->urg_seq == tp->copied_seq)
++			break;
++
++		/* We need to check signals first, to get correct SIGURG
++		 * handling. FIXME: Need to check this doesnt impact 1003.1g
++		 * and move it down to the bottom of the loop
++		 */
++		if (signal_pending(current)) {
++			if (copied)
++				break;
++			copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
++			break;
++		}
++
++		/* Next get a buffer. */
++
++		skb = skb_peek(&sk->receive_queue);
++
++		if (skb == NULL)		/* nothing ready */
++		{
++			if (copied) {
++				if (sk->err ||
++				    sk->state == TCP_CLOSE ||
++				    (sk->shutdown & RCV_SHUTDOWN) ||
++				    !timeo ||
++				    (0))
++					break;
++			} else {
++				if (sk->done)
++					break;
++
++				if (sk->err) {
++					copied = sock_error(sk);
++					break;
++				}
++
++				if (sk->shutdown & RCV_SHUTDOWN)
++					break;
++
++				if (sk->state == TCP_CLOSE) {
++					if (!sk->done) {
++						/* This occurs when user tries to read
++						 * from never connected socket.
++						 */
++						copied = -ENOTCONN;
++						break;
++					}
++					break;
++				}
++
++				if (!timeo) {
++					copied = -EAGAIN;
++					break;
++				}
++			}
++
++			cleanup_rbuf(sk, copied);
++			timeo = tcp_data_wait(sk, timeo);
++			continue;
++		}
++
++		BUG_TRAP (atomic_read (&skb->users) == 1);
++
++		exhausted = eaten = 0;
++
++		offset = tp->copied_seq - TCP_SKB_CB(skb)->seq;
++		if (skb->h.th->syn)
++			offset--;
++
++		used = skb->len - offset;
++
++		if (tp->urg_data) {
++			u32 urg_offset = tp->urg_seq - tp->copied_seq;
++			if (urg_offset < used) {
++				if (!urg_offset) { /* at urgent date */
++					if (!sk->urginline) {
++						tp->copied_seq++; /* discard the single byte of urgent data */
++						offset++;
++						used--;
++					}
++				} else		/* truncate read */
++					used = urg_offset;
++			}
++		}
++
++		BUG_TRAP (used >= 0);
++		if (len < used)
++			used = len;
++
++		if (used == 0)
++			exhausted = 1;
++		else
++		{
++			if (skb_is_nonlinear (skb))
++			{
++				int   rc = skb_linearize (skb, GFP_KERNEL);
++
++				printk ("tcp_recvpackets(): linearising: %d\n", rc);
++
++				if (rc)
++				{
++					if (!copied)
++						copied = rc;
++					break;
++				}
++			}
++
++			if ((offset + used) == skb->len) /* consuming the whole packet */
++			{
++				__skb_unlink (skb, &sk->receive_queue);
++				dst_release (skb->dst);
++				skb_orphan (skb);
++				__skb_pull (skb, offset);
++				__skb_queue_tail (packets, skb);
++				exhausted = eaten = 1;
++			}
++			else			/* consuming only part of the packet */
++			{
++				struct sk_buff *skb2 = skb_clone (skb, GFP_KERNEL);
++
++				if (skb2 == NULL)
++				{
++					if (!copied)
++						copied = -ENOMEM;
++					break;
++				}
++
++				dst_release (skb2->dst);
++				__skb_pull (skb2, offset);
++				__skb_trim (skb2, used);
++				__skb_queue_tail (packets, skb2);
++			}
++
++			tp->copied_seq += used;
++			copied += used;
++			len -= used;
++		}
++
++		if (tp->urg_data && after(tp->copied_seq,tp->urg_seq)) {
++			tp->urg_data = 0;
++			tcp_fast_path_check(sk, tp);
++		}
++
++		if (!exhausted)
++			continue;
++
++		if (skb->h.th->fin)
++		{
++			tp->copied_seq++;
++			if (!eaten)
++				tcp_eat_skb (sk, skb);
++			break;
++		}
++
++		if (!eaten)
++			tcp_eat_skb (sk, skb);
++
++	} while (len > 0);
++
++ out:
++	/* Clean up data we have read: This will do ACK frames. */
++	cleanup_rbuf(sk, copied);
++	TCP_CHECK_TIMER(sk);
++	release_sock(sk);
++	return copied;
++}
++
+ /*
+  *	State processing on a close. This implements the state shift for
+  *	sending our FIN frame. Note that we only send a FIN for some
+--- linux-2.4.22-ac1/net/netsyms.c~tcp-zero-copy-2.4.22-rh	2003-09-25 14:16:26.000000000 +0400
++++ linux-2.4.22-ac1-alexey/net/netsyms.c	2003-09-26 00:39:16.000000000 +0400
+@@ -396,6 +396,8 @@ EXPORT_SYMBOL(sysctl_tcp_wmem);
+ EXPORT_SYMBOL(sysctl_tcp_ecn);
+ EXPORT_SYMBOL(tcp_cwnd_application_limited);
+ EXPORT_SYMBOL(tcp_sendpage);
++EXPORT_SYMBOL(tcp_sendpage_zccd);
++EXPORT_SYMBOL(tcp_recvpackets);
+ EXPORT_SYMBOL(sysctl_tcp_low_latency);
+ 
+ EXPORT_SYMBOL(tcp_write_xmit);
+
+_
diff --git a/lustre/kernel_patches/patches/uml-2.4.20-do_mmap_pgoff-fix.patch b/lustre/kernel_patches/patches/uml-2.4.20-do_mmap_pgoff-fix.patch
new file mode 100644
index 0000000000000000000000000000000000000000..844d7354fa4485f446e73919ad3eaebaa408cb0e
--- /dev/null
+++ b/lustre/kernel_patches/patches/uml-2.4.20-do_mmap_pgoff-fix.patch
@@ -0,0 +1,16 @@
+ arch/i386/kernel/sys_i386.c |    2 +-
+ 1 files changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.4.20-vanilla/arch/i386/kernel/sys_i386.c~uml-2.4.20-do_mmap_pgoff-fix	2001-03-19 23:35:09.000000000 +0300
++++ linux-2.4.20-vanilla-alexey/arch/i386/kernel/sys_i386.c	2003-09-15 10:26:19.000000000 +0400
+@@ -56,7 +56,7 @@ static inline long do_mmap2(
+ 	}
+ 
+ 	down_write(&current->mm->mmap_sem);
+-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
++	error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff);
+ 	up_write(&current->mm->mmap_sem);
+ 
+ 	if (file)
+
+_
diff --git a/lustre/kernel_patches/patches/uml-2.4.20-fixes-1.patch b/lustre/kernel_patches/patches/uml-2.4.20-fixes-1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6f4c8e3a49d227034c91e54c6bdae33d1373939d
--- /dev/null
+++ b/lustre/kernel_patches/patches/uml-2.4.20-fixes-1.patch
@@ -0,0 +1,215 @@
+ arch/um/kernel/process.c           |    2 +-
+ arch/um/kernel/skas/process.c      |   26 +++++++++++++-------------
+ arch/um/kernel/skas/syscall_kern.c |    3 ++-
+ arch/um/kernel/trap_user.c         |    2 +-
+ arch/um/kernel/tt/syscall_kern.c   |    3 ++-
+ arch/um/kernel/tt/uaccess_user.c   |    2 +-
+ arch/um/kernel/uaccess_user.c      |    2 +-
+ arch/um/link.ld.in                 |    1 -
+ 8 files changed, 21 insertions(+), 20 deletions(-)
+
+Index: linux-2.4.20/arch/um/link.ld.in
+===================================================================
+--- linux-2.4.20.orig/arch/um/link.ld.in	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/link.ld.in	2003-10-25 00:36:02.000000000 +0400
+@@ -6,7 +6,6 @@
+ {
+   . = START() + SIZEOF_HEADERS;
+ 
+-  . = ALIGN(4096);
+   __binary_start = .;
+ ifdef(`MODE_TT', `
+   .thread_private : {
+Index: linux-2.4.20/arch/um/kernel/process.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/process.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/process.c	2003-10-25 00:36:02.000000000 +0400
+@@ -232,7 +232,7 @@
+ 	int n;
+ 
+ 	*jmp_ptr = &buf;
+-	n = setjmp(buf);
++	n = sigsetjmp(buf, 1);
+ 	if(n != 0)
+ 		return(n);
+ 	(*fn)(arg);
+Index: linux-2.4.20/arch/um/kernel/skas/process.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/skas/process.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/skas/process.c	2003-10-25 00:36:02.000000000 +0400
+@@ -59,11 +59,11 @@
+ 	int err, syscall_nr, status;
+ 
+ 	syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
++	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 	if(syscall_nr < 1){
+ 		relay_signal(SIGTRAP, regs);
+ 		return;
+ 	}
+-	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 
+ 	err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
+ 	if(err < 0)
+@@ -189,7 +189,7 @@
+ 	*switch_buf_ptr = &switch_buf;
+ 	*fork_buf_ptr = &fork_buf;
+ 
+-	if(setjmp(fork_buf) == 0)
++	if(sigsetjmp(fork_buf, 1) == 0)
+ 		new_thread_proc(stack, handler);
+ 
+ 	remove_sigstack();
+@@ -201,8 +201,8 @@
+ 
+ 	*switch_buf = &buf;
+ 	fork_buf = fb;
+-	if(setjmp(buf) == 0)
+-		longjmp(*fork_buf, 1);
++	if(sigsetjmp(buf, 1) == 0)
++		siglongjmp(*fork_buf, 1);
+ }
+ 
+ static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
+@@ -260,8 +260,8 @@
+ 	jmp_buf my_buf, **me_ptr = me, *next_buf = next;
+ 	
+ 	*me_ptr = &my_buf;
+-	if(setjmp(my_buf) == 0)
+-		longjmp(*next_buf, 1);
++	if(sigsetjmp(my_buf, 1) == 0)
++		siglongjmp(*next_buf, 1);
+ }
+ 
+ static jmp_buf initial_jmpbuf;
+@@ -277,14 +277,14 @@
+ 	int n;
+ 
+ 	*fork_buf_ptr = &initial_jmpbuf;
+-	n = setjmp(initial_jmpbuf);
++	n = sigsetjmp(initial_jmpbuf, 1);
+ 	if(n == 0)
+ 		new_thread_proc((void *) stack, new_thread_handler);
+ 	else if(n == 1)
+ 		remove_sigstack();
+ 	else if(n == 2){
+ 		(*cb_proc)(cb_arg);
+-		longjmp(*cb_back, 1);
++		siglongjmp(*cb_back, 1);
+ 	}
+ 	else if(n == 3){
+ 		kmalloc_ok = 0;
+@@ -294,7 +294,7 @@
+ 		kmalloc_ok = 0;
+ 		return(1);
+ 	}
+-	longjmp(**switch_buf, 1);
++	siglongjmp(**switch_buf, 1);
+ }
+ 
+ void remove_sigstack(void)
+@@ -316,8 +316,8 @@
+ 	cb_back = &here;
+ 
+ 	block_signals();
+-	if(setjmp(here) == 0)
+-		longjmp(initial_jmpbuf, 2);
++	if(sigsetjmp(here, 1) == 0)
++		siglongjmp(initial_jmpbuf, 2);
+ 	unblock_signals();
+ 
+ 	cb_proc = NULL;
+@@ -328,13 +328,13 @@
+ void halt_skas(void)
+ {
+ 	block_signals();
+-	longjmp(initial_jmpbuf, 3);
++	siglongjmp(initial_jmpbuf, 3);
+ }
+ 
+ void reboot_skas(void)
+ {
+ 	block_signals();
+-	longjmp(initial_jmpbuf, 4);
++	siglongjmp(initial_jmpbuf, 4);
+ }
+ 
+ int new_mm(int from)
+Index: linux-2.4.20/arch/um/kernel/skas/syscall_kern.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/skas/syscall_kern.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/skas/syscall_kern.c	2003-10-25 00:36:02.000000000 +0400
+@@ -23,7 +23,8 @@
+ 	nsyscalls++;
+ 	syscall = UPT_SYSCALL_NR(&regs->regs);
+ 
+-	if((syscall >= NR_syscalls) || (syscall < 0))
++	if((syscall >= NR_syscalls) || (syscall < 0) || 
++	   (sys_call_table[syscall] == NULL))
+ 		res = -ENOSYS;
+ 	else res = EXECUTE_SYSCALL(syscall, regs);
+ 
+Index: linux-2.4.20/arch/um/kernel/trap_user.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/trap_user.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/trap_user.c	2003-10-25 00:36:02.000000000 +0400
+@@ -125,7 +125,7 @@
+ {
+ 	jmp_buf *buf = b;
+ 
+-	longjmp(*buf, val);
++	siglongjmp(*buf, val);
+ }
+ 
+ /*
+Index: linux-2.4.20/arch/um/kernel/tt/syscall_kern.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/tt/syscall_kern.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/tt/syscall_kern.c	2003-10-25 00:36:02.000000000 +0400
+@@ -113,7 +113,8 @@
+ 	nsyscalls++;
+ 	syscall = UPT_SYSCALL_NR(&regs->regs);
+ 
+-	if((syscall >= NR_syscalls) || (syscall < 0))
++	if((syscall >= NR_syscalls) || (syscall < 0) || 
++	   (sys_call_table[syscall] == NULL))
+ 		res = -ENOSYS;
+ 	else if(honeypot && check_bogosity(regs))
+ 		res = -EFAULT;
+Index: linux-2.4.20/arch/um/kernel/tt/uaccess_user.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/tt/uaccess_user.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/tt/uaccess_user.c	2003-10-25 00:36:02.000000000 +0400
+@@ -75,7 +75,7 @@
+ 	jmp_buf jbuf;
+ 
+ 	*fault_catcher = &jbuf;
+-	if(setjmp(jbuf) == 0){
++	if(sigsetjmp(jbuf, 1) == 0){
+ 		ret = strlen(str) + 1;
+ 	} 
+ 	else {
+Index: linux-2.4.20/arch/um/kernel/uaccess_user.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/uaccess_user.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/uaccess_user.c	2003-10-25 00:36:02.000000000 +0400
+@@ -20,7 +20,7 @@
+ 
+ 	jmp_buf jbuf;
+ 	*fault_catcher = &jbuf;
+-	if(setjmp(jbuf) == 0){
++	if(sigsetjmp(jbuf, 1) == 0){
+ 		(*op)(to, from, n);
+ 		ret = 0;
+ 		*faulted_out = 0;
+Index: linux-2.4.20/arch/um/kernel/tt/ptproxy/sysdep.c
+===================================================================
+--- linux-2.4.20.orig/arch/um/kernel/tt/ptproxy/sysdep.c	2003-10-25 00:35:59.000000000 +0400
++++ linux-2.4.20/arch/um/kernel/tt/ptproxy/sysdep.c	2003-10-25 00:36:23.000000000 +0400
+@@ -9,6 +9,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include <signal.h>
++#include <errno.h>
+ #include <sys/types.h>
+ #include <sys/ptrace.h>
+ #include <asm/ptrace.h>
diff --git a/lustre/kernel_patches/patches/uml-2.6.0-fix.patch b/lustre/kernel_patches/patches/uml-2.6.0-fix.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2910f977b8aa2fba7a646b137032c9ffdf4a3c64
--- /dev/null
+++ b/lustre/kernel_patches/patches/uml-2.6.0-fix.patch
@@ -0,0 +1,19 @@
+ include/asm-um/unistd.h |    2 ++
+ 1 files changed, 2 insertions(+)
+
+diff -puN include/asm-um/unistd.h~uml-2.6.0-fix include/asm-um/unistd.h
+--- linux-2.6.0-test3/include/asm-um/unistd.h~uml-2.6.0-fix	2003-09-04 18:39:45.000000000 +0400
++++ linux-2.6.0-test3-alexey/include/asm-um/unistd.h	2003-09-04 18:39:59.000000000 +0400
+@@ -6,8 +6,10 @@
+ #ifndef _UM_UNISTD_H_
+ #define _UM_UNISTD_H_
+ 
++#ifdef __KERNEL__
+ #include "linux/resource.h"
+ #include "asm/uaccess.h"
++#endif
+ 
+ extern long sys_open(const char *filename, int flags, int mode);
+ extern long sys_dup(unsigned int fildes);
+
+_
diff --git a/lustre/kernel_patches/patches/uml-patch-2.6.0-test5.patch b/lustre/kernel_patches/patches/uml-patch-2.6.0-test5.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1c4ec8dc309da0d6d81d107637780b0ee44f68ea
--- /dev/null
+++ b/lustre/kernel_patches/patches/uml-patch-2.6.0-test5.patch
@@ -0,0 +1,9304 @@
+diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
+--- a/arch/um/Kconfig	Tue Sep  9 16:43:10 2003
++++ b/arch/um/Kconfig	Tue Sep  9 16:48:54 2003
+@@ -61,6 +61,20 @@
+ 
+ config NET
+ 	bool "Networking support"
++	help
++	Unless you really know what you are doing, you should say Y here.
++	The reason is that some programs need kernel networking support even
++	when running on a stand-alone machine that isn't connected to any
++	other computer. If you are upgrading from an older kernel, you
++	should consider updating your networking tools too because changes
++	in the kernel and the tools often go hand in hand. The tools are
++	contained in the package net-tools, the location and version number
++	of which are given in Documentation/Changes.
++
++	For a general introduction to Linux networking, it is highly
++	recommended to read the NET-HOWTO, available from
++	<http://www.tldp.org/docs.html#howto>.
++
+ 
+ source "fs/Kconfig.binfmt"
+ 
+@@ -85,6 +99,19 @@
+         If you'd like to be able to work with files stored on the host, 
+         say Y or M here; otherwise say N.
+ 
++config HPPFS
++	tristate "HoneyPot ProcFS"
++	help
++	hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 
++	entries to be overridden, removed, or fabricated from the host.
++	Its purpose is to allow a UML to appear to be a physical machine
++	by removing or changing anything in /proc which gives away the
++	identity of a UML.
++
++	See http://user-mode-linux.sf.net/hppfs.html for more information.
++
++	You only need this if you are setting up a UML honeypot.  Otherwise,
++	it is safe to say 'N' here.
+ 
+ config MCONSOLE
+ 	bool "Management console"
+@@ -105,6 +132,16 @@
+ config MAGIC_SYSRQ
+ 	bool "Magic SysRq key"
+ 	depends on MCONSOLE
++	help
++	If you say Y here, you will have some control over the system even
++	if the system crashes for example during kernel debugging (e.g., you
++	will be able to flush the buffer cache to disk, reboot the system
++	immediately or dump some status information). This is accomplished
++	by pressing various keys while holding SysRq (Alt+PrintScreen). It
++	also works on a serial console (on PC hardware at least), if you
++	send a BREAK and then within 5 seconds a command keypress. The
++	keys are documented in Documentation/sysrq.txt. Don't say Y
++	unless you really know what this hack does.
+ 
+ config HOST_2G_2G
+ 	bool "2G/2G host address space split"
+@@ -159,6 +196,9 @@
+ config HIGHMEM
+ 	bool "Highmem support"
+ 
++config PROC_MM
++	bool "/proc/mm support"
++
+ config KERNEL_STACK_ORDER
+ 	int "Kernel stack size order"
+ 	default 2
+@@ -239,6 +279,10 @@
+ config PT_PROXY
+ 	bool "Enable ptrace proxy"
+ 	depends on XTERM_CHAN && DEBUG_INFO
++	help
++	This option enables a debugging interface which allows gdb to debug
++	the kernel without needing to actually attach to kernel threads.
++	If you want to do kernel debugging, say Y here; otherwise say N.
+ 
+ config GPROF
+ 	bool "Enable gprof support"
+diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
+--- a/arch/um/Kconfig_block	Tue Sep  9 16:44:02 2003
++++ b/arch/um/Kconfig_block	Tue Sep  9 16:49:30 2003
+@@ -29,6 +29,20 @@
+         wise choice too.  In all other cases (for example, if you're just
+         playing around with User-Mode Linux) you can choose N.
+ 
++# Turn this back on when the driver actually works
++#
++#config BLK_DEV_COW
++#	tristate "COW block device"
++#	help
++#	This is a layered driver which sits above two other block devices.
++#	One is read-only, and the other is a read-write layer which stores
++#	all changes.  This provides the illusion that the read-only layer
++#	can be mounted read-write and changed.
++
++config BLK_DEV_COW_COMMON
++	bool
++	default BLK_DEV_COW || BLK_DEV_UBD
++
+ config BLK_DEV_LOOP
+ 	tristate "Loopback device support"
+ 
+diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
+--- a/arch/um/Kconfig_net	Tue Sep  9 16:43:43 2003
++++ b/arch/um/Kconfig_net	Tue Sep  9 16:49:20 2003
+@@ -1,5 +1,5 @@
+ 
+-menu "Network Devices"
++menu "UML Network Devices"
+ 	depends on NET
+ 
+ # UML virtual driver
+@@ -176,73 +176,5 @@
+ 	
+         Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
+ 
+-
+-# Below are hardware-independent drivers mirrored from
+-# drivers/net/Config.in. It would be nice if Linux
+-# had HW independent drivers separated from the other
+-# but it does not. Until then each non-ISA/PCI arch
+-# needs to provide it's own menu of network drivers
+-config DUMMY
+-	tristate "Dummy net driver support"
+-
+-config BONDING
+-	tristate "Bonding driver support"
+-
+-config EQUALIZER
+-	tristate "EQL (serial line load balancing) support"
+-
+-config TUN
+-	tristate "Universal TUN/TAP device driver support"
+-
+-config ETHERTAP
+-	tristate "Ethertap network tap (OBSOLETE)"
+-	depends on EXPERIMENTAL && NETLINK
+-
+-config PPP
+-	tristate "PPP (point-to-point protocol) support"
+-
+-config PPP_MULTILINK
+-	bool "PPP multilink support (EXPERIMENTAL)"
+-	depends on PPP && EXPERIMENTAL
+-
+-config PPP_FILTER
+-	bool "PPP filtering"
+-	depends on PPP && FILTER
+-
+-config PPP_ASYNC
+-	tristate "PPP support for async serial ports"
+-	depends on PPP
+-
+-config PPP_SYNC_TTY
+-	tristate "PPP support for sync tty ports"
+-	depends on PPP
+-
+-config PPP_DEFLATE
+-	tristate "PPP Deflate compression"
+-	depends on PPP
+-
+-config PPP_BSDCOMP
+-	tristate "PPP BSD-Compress compression"
+-	depends on PPP
+-
+-config PPPOE
+-	tristate "PPP over Ethernet (EXPERIMENTAL)"
+-	depends on PPP && EXPERIMENTAL
+-
+-config SLIP
+-	tristate "SLIP (serial line) support"
+-
+-config SLIP_COMPRESSED
+-	bool "CSLIP compressed headers"
+-	depends on SLIP=y
+-
+-config SLIP_SMART
+-	bool "Keepalive and linefill"
+-	depends on SLIP=y
+-
+-config SLIP_MODE_SLIP6
+-	bool "Six bit SLIP encapsulation"
+-	depends on SLIP=y
+-
+ endmenu
+ 
+diff -Naur a/arch/um/Makefile b/arch/um/Makefile
+--- a/arch/um/Makefile	Tue Sep  9 16:43:50 2003
++++ b/arch/um/Makefile	Tue Sep  9 16:49:24 2003
+@@ -24,15 +24,17 @@
+ # Have to precede the include because the included Makefiles reference them.
+ SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
+ 	include/asm-um/sigcontext.h include/asm-um/processor.h \
+-	include/asm-um/ptrace.h include/asm-um/arch-signal.h
++	include/asm-um/ptrace.h include/asm-um/arch-signal.h \
++	include/asm-um/module.h
+ 
+ ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
+ 	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
+ 
+ GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
+ 
+-include $(ARCH_DIR)/Makefile-$(SUBARCH)
+-include $(ARCH_DIR)/Makefile-os-$(OS)
++.PHONY: sys_prepare
++sys_prepare:
++	@:
+ 
+ MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
+ MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+@@ -41,6 +43,9 @@
+   include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
+ endif
+ 
++include $(ARCH_DIR)/Makefile-$(SUBARCH)
++include $(ARCH_DIR)/Makefile-os-$(OS)
++
+ EXTRAVERSION := $(EXTRAVERSION)-1um
+ 
+ ARCH_INCLUDE = -I$(ARCH_DIR)/include
+@@ -52,14 +57,14 @@
+ 
+ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+ 	-D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
+-	$(MODE_INCLUDE)
++	-Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
+ 
+ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+ 
+ SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
+ 
+ ifeq ($(CONFIG_MODE_SKAS), y)
+-$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+ endif
+ 
+ include/linux/version.h: arch/$(ARCH)/Makefile
+@@ -98,17 +103,17 @@
+ CONFIG_KERNEL_STACK_ORDER ?= 2
+ STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
+ 
+-AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
++AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
+ 	-DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
+ 	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+-	-DKERNEL_STACK_SIZE=$(STACK_SIZE)
++	-DKERNEL_STACK_SIZE=$(STACK_SIZE))
+ 
+-AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
++export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
+ 
+ LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
+ 
+-$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
+-	$(call if_changed_dep,as_s_S)
++#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
++#	$(call if_changed_dep,as_s_S)
+ 
+ linux: vmlinux $(LD_SCRIPT-y)
+ 	$(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
+@@ -116,6 +121,7 @@
+ 
+ USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+ USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
++USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
+ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+ 	$(MODE_INCLUDE)
+ 
+@@ -123,9 +129,10 @@
+ USER_CFLAGS += -D_GNU_SOURCE
+ 
+ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
+-	$(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
++	$(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
++	$(GEN_HEADERS)
+ 
+-$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
++$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
+ 	$(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+ 
+ archmrproper:
+@@ -161,19 +168,23 @@
+ $(ARCH_DIR)/os:
+ 	cd $(ARCH_DIR) && ln -sf os-$(OS) os
+ 
+-$(ARCH_DIR)/include/uml-config.h :
++$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
+ 	sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
+ 
++filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
++
+ $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
+-	$< > $@
++	$(call filechk,$@)
++
++filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
+ 
+ $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
+-	$< > $@
++	$(call filechk,$@)
+ 
+-$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
+-	$(ARCH_DIR)/util FORCE ;
++$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
++	sys_prepare FORCE ;
+ 
+ $(ARCH_DIR)/util: FORCE
+-	@$(call descend,$@,)
++	$(MAKE) -f scripts/Makefile.build obj=$@
+ 
+-export SUBARCH USER_CFLAGS OS
++export SUBARCH USER_CFLAGS OS 
+diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
+--- a/arch/um/Makefile-i386	Tue Sep  9 16:45:38 2003
++++ b/arch/um/Makefile-i386	Tue Sep  9 16:50:11 2003
+@@ -16,22 +16,28 @@
+ 
+ SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+ 
++sys_prepare: $(SYS_DIR)/sc.h
++
+ prepare: $(SYS_HEADERS)
+ 
++filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
++
+ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
+-	$< > $@
++	$(call filechk,$@)
++
++filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
+ 
+ $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
+-	$< > $@
++	$(call filechk,$@)
+ 
+-$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
+-	@$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
++	+@$(call descend,$(SYS_UTIL_DIR),$@)
+ 
+-$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
+-	@$(call descend,$(SYS_UTIL_DIR),$@)
++$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
++	+@$(call descend,$(SYS_UTIL_DIR),$@)
+ 
+ $(SYS_UTIL_DIR): include/asm FORCE
+-	@$(call descend,$@,)
++	+@$(call descend,$@,)
+ 
+ sysclean :
+ 	rm -f $(SYS_HEADERS)
+diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
+--- a/arch/um/Makefile-skas	Tue Sep  9 16:43:05 2003
++++ b/arch/um/Makefile-skas	Tue Sep  9 16:48:52 2003
+@@ -14,7 +14,7 @@
+ LINK_SKAS = -Wl,-rpath,/lib 
+ LD_SCRIPT_SKAS = dyn.lds.s
+ 
+-GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
++GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
+ 
+-$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
+-	$(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
++$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
++	$(call descend,$(ARCH_DIR)/kernel/skas,$@)
+diff -Naur a/arch/um/config.release b/arch/um/config.release
+--- a/arch/um/config.release	Tue Sep  9 16:46:07 2003
++++ b/arch/um/config.release	Tue Sep  9 16:51:08 2003
+@@ -228,7 +228,6 @@
+ CONFIG_EXT2_FS=y
+ CONFIG_SYSV_FS=m
+ CONFIG_UDF_FS=m
+-# CONFIG_UDF_RW is not set
+ CONFIG_UFS_FS=m
+ # CONFIG_UFS_FS_WRITE is not set
+ 
+diff -Naur a/arch/um/defconfig b/arch/um/defconfig
+--- a/arch/um/defconfig	Tue Sep  9 16:43:55 2003
++++ b/arch/um/defconfig	Tue Sep  9 16:49:28 2003
+@@ -3,29 +3,19 @@
+ #
+ CONFIG_USERMODE=y
+ CONFIG_MMU=y
+-CONFIG_SWAP=y
+ CONFIG_UID16=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+-CONFIG_CONFIG_LOG_BUF_SHIFT=14
+-
+-#
+-# Code maturity level options
+-#
+-CONFIG_EXPERIMENTAL=y
+ 
+ #
+-# General Setup
++# UML-specific options
+ #
+ CONFIG_MODE_TT=y
+ CONFIG_MODE_SKAS=y
+ CONFIG_NET=y
+-CONFIG_SYSVIPC=y
+-CONFIG_BSD_PROCESS_ACCT=y
+-CONFIG_SYSCTL=y
+-CONFIG_BINFMT_AOUT=y
+ CONFIG_BINFMT_ELF=y
+ CONFIG_BINFMT_MISC=y
+ CONFIG_HOSTFS=y
++CONFIG_HPPFS=y
+ CONFIG_MCONSOLE=y
+ CONFIG_MAGIC_SYSRQ=y
+ # CONFIG_HOST_2G_2G is not set
+@@ -38,10 +28,38 @@
+ CONFIG_KERNEL_STACK_ORDER=2
+ 
+ #
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_STANDALONE=y
++CONFIG_BROKEN_ON_SMP=y
++
++#
++# General setup
++#
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_SYSCTL=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_IKCONFIG is not set
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++
++#
+ # Loadable module support
+ #
+-CONFIG_MODULES=y
+-# CONFIG_KMOD is not set
++# CONFIG_MODULES is not set
++
++#
++# Generic Driver Options
++#
+ 
+ #
+ # Character Devices
+@@ -69,6 +87,7 @@
+ #
+ CONFIG_BLK_DEV_UBD=y
+ # CONFIG_BLK_DEV_UBD_SYNC is not set
++CONFIG_BLK_DEV_COW_COMMON=y
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_NBD=y
+ CONFIG_BLK_DEV_RAM=y
+@@ -78,7 +97,7 @@
+ CONFIG_NETDEVICES=y
+ 
+ #
+-# Network Devices
++# UML Network Devices
+ #
+ CONFIG_UML_NET=y
+ CONFIG_UML_NET_ETHERTAP=y
+@@ -88,22 +107,6 @@
+ CONFIG_UML_NET_MCAST=y
+ # CONFIG_UML_NET_PCAP is not set
+ CONFIG_UML_NET_SLIRP=y
+-CONFIG_DUMMY=y
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-CONFIG_TUN=y
+-# CONFIG_ETHERTAP is not set
+-CONFIG_PPP=y
+-# CONFIG_PPP_MULTILINK is not set
+-# CONFIG_PPP_ASYNC is not set
+-# CONFIG_PPP_SYNC_TTY is not set
+-# CONFIG_PPP_DEFLATE is not set
+-# CONFIG_PPP_BSDCOMP is not set
+-# CONFIG_PPPOE is not set
+-CONFIG_SLIP=y
+-# CONFIG_SLIP_COMPRESSED is not set
+-# CONFIG_SLIP_SMART is not set
+-# CONFIG_SLIP_MODE_SLIP6 is not set
+ 
+ #
+ # Networking support
+@@ -115,8 +118,6 @@
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+ # CONFIG_NETLINK_DEV is not set
+-# CONFIG_NETFILTER is not set
+-# CONFIG_FILTER is not set
+ CONFIG_UNIX=y
+ # CONFIG_NET_KEY is not set
+ CONFIG_INET=y
+@@ -130,8 +131,11 @@
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_INET_AH is not set
+ # CONFIG_INET_ESP is not set
+-# CONFIG_XFRM_USER is not set
++# CONFIG_INET_IPCOMP is not set
+ # CONFIG_IPV6 is not set
++# CONFIG_DECNET is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NETFILTER is not set
+ 
+ #
+ # SCTP Configuration (EXPERIMENTAL)
+@@ -141,8 +145,6 @@
+ # CONFIG_ATM is not set
+ # CONFIG_VLAN_8021Q is not set
+ # CONFIG_LLC is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_NET_DIVERT is not set
+@@ -160,6 +162,10 @@
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=y
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+@@ -171,6 +177,22 @@
+ #
+ 
+ #
++# Ethernet (10000 Mbit)
++#
++CONFIG_PPP=y
++# CONFIG_PPP_MULTILINK is not set
++# CONFIG_PPP_FILTER is not set
++# CONFIG_PPP_ASYNC is not set
++# CONFIG_PPP_SYNC_TTY is not set
++# CONFIG_PPP_DEFLATE is not set
++# CONFIG_PPP_BSDCOMP is not set
++# CONFIG_PPPOE is not set
++CONFIG_SLIP=y
++# CONFIG_SLIP_COMPRESSED is not set
++# CONFIG_SLIP_SMART is not set
++# CONFIG_SLIP_MODE_SLIP6 is not set
++
++#
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
+@@ -188,66 +210,82 @@
+ #
+ # File systems
+ #
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_JBD is not set
++CONFIG_REISERFS_FS=y
++# CONFIG_REISERFS_CHECK is not set
++# CONFIG_REISERFS_PROC_INFO is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++CONFIG_MINIX_FS=y
++# CONFIG_ROMFS_FS is not set
+ CONFIG_QUOTA=y
+ # CONFIG_QFMT_V1 is not set
+ # CONFIG_QFMT_V2 is not set
+ CONFIG_QUOTACTL=y
+-CONFIG_AUTOFS_FS=m
+-CONFIG_AUTOFS4_FS=m
+-CONFIG_REISERFS_FS=m
+-# CONFIG_REISERFS_CHECK is not set
+-# CONFIG_REISERFS_PROC_INFO is not set
++CONFIG_AUTOFS_FS=y
++CONFIG_AUTOFS4_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_DEVFS_FS=y
++CONFIG_DEVFS_MOUNT=y
++# CONFIG_DEVFS_DEBUG is not set
++CONFIG_DEVPTS_FS=y
++# CONFIG_DEVPTS_FS_XATTR is not set
++# CONFIG_TMPFS is not set
++CONFIG_RAMFS=y
++
++#
++# Miscellaneous filesystems
++#
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+-# CONFIG_EXT3_FS is not set
+-# CONFIG_JBD is not set
+-CONFIG_FAT_FS=m
+-CONFIG_MSDOS_FS=m
+-CONFIG_VFAT_FS=m
+ # CONFIG_EFS_FS is not set
+ CONFIG_JFFS_FS=y
+ CONFIG_JFFS_FS_VERBOSE=0
+-CONFIG_JFFS_PROC_FS=y
+ # CONFIG_JFFS2_FS is not set
+ # CONFIG_CRAMFS is not set
+-# CONFIG_TMPFS is not set
+-CONFIG_RAMFS=y
+-CONFIG_ISO9660_FS=m
+-# CONFIG_JOLIET is not set
+-# CONFIG_ZISOFS is not set
+-# CONFIG_JFS_FS is not set
+-CONFIG_MINIX_FS=m
+ # CONFIG_VXFS_FS is not set
+-# CONFIG_NTFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+-CONFIG_PROC_FS=y
+-CONFIG_DEVFS_FS=y
+-CONFIG_DEVFS_MOUNT=y
+-# CONFIG_DEVFS_DEBUG is not set
+-CONFIG_DEVPTS_FS=y
+ # CONFIG_QNX4FS_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
+ # CONFIG_SYSV_FS is not set
+-# CONFIG_UDF_FS is not set
+ # CONFIG_UFS_FS is not set
+-# CONFIG_XFS_FS is not set
+ 
+ #
+ # Network File Systems
+ #
+-# CONFIG_CODA_FS is not set
+-# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_NFS_FS is not set
+ # CONFIG_NFSD is not set
+ # CONFIG_EXPORTFS is not set
+-# CONFIG_CIFS is not set
+ # CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_INTERMEZZO_FS is not set
+ # CONFIG_AFS_FS is not set
+ 
+ #
+@@ -317,28 +355,7 @@
+ #
+ # SCSI support
+ #
+-CONFIG_SCSI=y
+-CONFIG_GENERIC_ISA_DMA=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-CONFIG_SD_EXTRA_DEVS=40
+-CONFIG_CHR_DEV_ST=y
+-CONFIG_BLK_DEV_SR=y
+-CONFIG_BLK_DEV_SR_VENDOR=y
+-CONFIG_SR_EXTRA_DEVS=2
+-CONFIG_CHR_DEV_SG=y
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-CONFIG_SCSI_DEBUG_QUEUES=y
+-CONFIG_SCSI_MULTI_LUN=y
+-CONFIG_SCSI_CONSTANTS=y
+-CONFIG_SCSI_LOGGING=y
+-CONFIG_SCSI_DEBUG=y
++# CONFIG_SCSI is not set
+ 
+ #
+ # Multi-device support (RAID and LVM)
+@@ -360,6 +377,7 @@
+ CONFIG_MTD_BLOCK=y
+ # CONFIG_FTL is not set
+ # CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
+ 
+ #
+ # RAM/ROM/Flash chip drivers
+@@ -374,20 +392,21 @@
+ #
+ # Mapping drivers for chip access
+ #
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+ 
+ #
+ # Self-contained MTD device drivers
+ #
+ # CONFIG_MTD_SLRAM is not set
+ # CONFIG_MTD_MTDRAM is not set
+-CONFIG_MTD_BLKMTD=m
++CONFIG_MTD_BLKMTD=y
+ 
+ #
+ # Disk-On-Chip Device Drivers
+ #
+-# CONFIG_MTD_DOC1000 is not set
+ # CONFIG_MTD_DOC2000 is not set
+ # CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
+ 
+ #
+ # NAND Flash Device Drivers
+diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
+--- a/arch/um/drivers/Makefile	Tue Sep  9 16:43:32 2003
++++ b/arch/um/drivers/Makefile	Tue Sep  9 16:49:19 2003
+@@ -1,5 +1,5 @@
+ # 
+-# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
++# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
+ # Licensed under the GPL
+ #
+ 
+@@ -39,6 +39,8 @@
+ obj-$(CONFIG_TTY_CHAN) += tty.o 
+ obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
+ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
++obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
++obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
+ 
+ obj-y += stdio_console.o $(CHAN_OBJS)
+ 
+@@ -46,7 +48,7 @@
+ 
+ USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
+ 	null.o pty.o tty.o xterm.o
+-USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
++USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+ 
+ $(USER_OBJS) : %.o: %.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+diff -Naur a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
+--- a/arch/um/drivers/chan_kern.c	Tue Sep  9 16:46:09 2003
++++ b/arch/um/drivers/chan_kern.c	Tue Sep  9 16:51:12 2003
+@@ -8,6 +8,7 @@
+ #include <linux/list.h>
+ #include <linux/slab.h>
+ #include <linux/tty.h>
++#include <linux/string.h>
+ #include <linux/tty_flip.h>
+ #include <asm/irq.h>
+ #include "chan_kern.h"
+diff -Naur a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
+--- a/arch/um/drivers/chan_user.c	Tue Sep  9 16:41:10 2003
++++ b/arch/um/drivers/chan_user.c	Tue Sep  9 16:47:22 2003
+@@ -188,8 +188,8 @@
+ 	if(!isatty(fd)) return;
+ 
+ 	pid = tcgetpgrp(fd);
+-	if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
+-	   (pid == -1)){
++	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
++			     device_data) && (pid == -1)){
+ 		thread = winch_tramp(fd, device_data, &thread_fd);
+ 		if(fd != -1){
+ 			register_winch_irq(thread_fd, fd, thread, device_data);
+diff -Naur a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
+--- a/arch/um/drivers/cow.h	Wed Dec 31 19:00:00 1969
++++ b/arch/um/drivers/cow.h	Tue Sep  9 16:47:42 2003
+@@ -0,0 +1,40 @@
++#ifndef __COW_H__
++#define __COW_H__
++
++#include <asm/types.h>
++
++#if __BYTE_ORDER == __BIG_ENDIAN
++# define ntohll(x) (x)
++# define htonll(x) (x)
++#elif __BYTE_ORDER == __LITTLE_ENDIAN
++# define ntohll(x)  bswap_64(x)
++# define htonll(x)  bswap_64(x)
++#else
++#error "__BYTE_ORDER not defined"
++#endif
++
++extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
++			 int sectorsize, int *bitmap_offset_out, 
++			 unsigned long *bitmap_len_out, int *data_offset_out);
++
++extern int file_reader(__u64 offset, char *buf, int len, void *arg);
++extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
++			   void *arg, __u32 *magic_out, 
++			   char **backing_file_out, time_t *mtime_out, 
++			   __u64 *size_out, int *sectorsize_out, 
++			   int *bitmap_offset_out);
++
++extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
++			    int sectorsize, long long *size);
++
++extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
++		      unsigned long *bitmap_len_out, int *data_offset_out);
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c
+--- a/arch/um/drivers/cow_kern.c	Wed Dec 31 19:00:00 1969
++++ b/arch/um/drivers/cow_kern.c	Tue Sep  9 16:51:12 2003
+@@ -0,0 +1,628 @@
++#define COW_MAJOR 60
++#define MAJOR_NR COW_MAJOR
++
++#include <linux/stddef.h>
++#include <linux/kernel.h>
++#include <linux/ctype.h>
++#include <linux/stat.h>
++#include <linux/vmalloc.h>
++#include <linux/blkdev.h>
++#include <linux/blk.h>
++#include <linux/fs.h>
++#include <linux/genhd.h>
++#include <linux/devfs_fs.h>
++#include <asm/uaccess.h>
++#include "2_5compat.h"
++#include "cow.h"
++#include "ubd_user.h"
++
++#define COW_SHIFT 4
++
++struct cow {
++	int count;
++	char *cow_path;
++	dev_t cow_dev;
++	struct block_device *cow_bdev;
++	char *backing_path;
++	dev_t backing_dev;
++	struct block_device *backing_bdev;
++	int sectorsize;
++	unsigned long *bitmap;
++	unsigned long bitmap_len;
++	int bitmap_offset;
++	int data_offset;
++	devfs_handle_t devfs;
++	struct semaphore sem;
++	struct semaphore io_sem;
++	atomic_t working;
++	spinlock_t io_lock;
++	struct buffer_head *bh;
++	struct buffer_head *bhtail;
++	void *end_io;
++};
++
++#define DEFAULT_COW { \
++	.count			= 0, \
++	.cow_path		= NULL, \
++	.cow_dev		= 0, \
++	.backing_path		= NULL, \
++	.backing_dev		= 0, \
++        .bitmap			= NULL, \
++	.bitmap_len		= 0, \
++	.bitmap_offset		= 0, \
++        .data_offset		= 0, \
++	.devfs			= NULL, \
++	.working		= ATOMIC_INIT(0), \
++	.io_lock		= SPIN_LOCK_UNLOCKED, \
++}
++
++#define MAX_DEV (8)
++#define MAX_MINOR (MAX_DEV << COW_SHIFT)
++
++struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
++
++/* Not modified by this driver */
++static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
++static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
++
++/* Protected by cow_lock */
++static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
++
++static struct hd_struct	cow_part[MAX_MINOR] =
++	{ [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
++
++/* Protected by io_request_lock */
++static request_queue_t *cow_queue;
++
++static int cow_open(struct inode *inode, struct file *filp);
++static int cow_release(struct inode * inode, struct file * file);
++static int cow_ioctl(struct inode * inode, struct file * file,
++		     unsigned int cmd, unsigned long arg);
++static int cow_revalidate(kdev_t rdev);
++
++static struct block_device_operations cow_blops = {
++       .open		= cow_open,
++       .release	= cow_release,
++       .ioctl		= cow_ioctl,
++       .revalidate	= cow_revalidate,
++};
++
++/* Initialized in an initcall, and unchanged thereafter */
++devfs_handle_t cow_dir_handle;
++
++#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
++{ \
++	.major 		= maj, \
++	.major_name  	= name, \
++	.minor_shift 	= shift, \
++	.max_p  	= 1 << shift, \
++	.part  		= parts, \
++	.sizes  	= bsizes, \
++	.nr_real  	= max, \
++	.real_devices  	= NULL, \
++	.next  		= NULL, \
++	.fops  		= blops, \
++	.de_arr  	= NULL, \
++	.flags  	= 0 \
++}
++
++static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
++
++static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
++						 COW_SHIFT, sizes, MAX_DEV, 
++						 &cow_blops);
++
++static int cow_add(int n)
++{
++	struct cow *dev = &cow_dev[n];
++	char name[sizeof("nnnnnn\0")];
++	int err = -ENODEV;
++
++	if(dev->cow_path == NULL)
++		goto out;
++
++	sprintf(name, "%d", n);
++	dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
++				    MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
++				    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
++				    &cow_blops, NULL);
++
++	init_MUTEX_LOCKED(&dev->sem);
++	init_MUTEX(&dev->io_sem);
++
++	return(0);
++
++out:
++	return(err);
++}
++
++/*
++* Add buffer_head to back of pending list
++*/
++static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&cow->io_lock, flags);
++	if(cow->bhtail != NULL){
++		cow->bhtail->b_reqnext = bh;
++		cow->bhtail = bh;
++	}
++	else {
++		cow->bh = bh;
++		cow->bhtail = bh;
++	}
++	spin_unlock_irqrestore(&cow->io_lock, flags);
++}
++
++/*
++* Grab first pending buffer
++*/
++static struct buffer_head *cow_get_bh(struct cow *cow)
++{
++	struct buffer_head *bh;
++
++	spin_lock_irq(&cow->io_lock);
++	bh = cow->bh;
++	if(bh != NULL){
++		if(bh == cow->bhtail)
++			cow->bhtail = NULL;
++		cow->bh = bh->b_reqnext;
++		bh->b_reqnext = NULL;
++	}
++	spin_unlock_irq(&cow->io_lock);
++
++	return(bh);
++}
++
++static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
++			  struct buffer_head **cow_bh, int ncow_bh)
++{
++	int i;
++
++	if(ncow_bh > 0)
++		ll_rw_block(WRITE, ncow_bh, cow_bh);
++
++	for(i = 0; i < ncow_bh ; i++){
++		wait_on_buffer(cow_bh[i]);
++		brelse(cow_bh[i]);
++	}
++
++	ll_rw_block(WRITE, 1, &bh);
++	brelse(bh);
++}
++
++static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
++{
++	struct buffer_head *bh;
++
++	sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
++	bh = getblk(dev->cow_dev, sector, dev->sectorsize);
++	memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
++	       dev->sectorsize);
++	return(bh);
++}
++
++/* Copied from loop.c, needed to avoid deadlocking in make_request. */
++
++static int cow_thread(void *data)
++{
++	struct cow *dev = data;
++	struct buffer_head *bh;
++
++	daemonize();
++	exit_files(current);
++
++	sprintf(current->comm, "cow%d", dev - cow_dev);
++
++	spin_lock_irq(&current->sigmask_lock);
++	sigfillset(&current->blocked);
++	flush_signals(current);
++	spin_unlock_irq(&current->sigmask_lock);
++
++	atomic_inc(&dev->working);
++
++	current->policy = SCHED_OTHER;
++	current->nice = -20;
++
++	current->flags |= PF_NOIO;
++
++	/*
++	 * up sem, we are running
++	 */
++	up(&dev->sem);
++
++	for(;;){
++		int start, len, nbh, i, update_bitmap = 0;
++		struct buffer_head *cow_bh[2];
++
++		down_interruptible(&dev->io_sem);
++		/*
++		 * could be upped because of tear-down, not because of
++		 * pending work
++		 */
++		if(!atomic_read(&dev->working))
++			break;
++
++		bh = cow_get_bh(dev);
++		if(bh == NULL){
++			printk(KERN_ERR "cow: missing bh\n");
++			continue;
++		}
++
++		start = bh->b_blocknr * bh->b_size / dev->sectorsize;
++		len = bh->b_size / dev->sectorsize;
++		for(i = 0; i < len ; i++){
++			if(ubd_test_bit(start +ni, 
++					(unsigned char *) dev->bitmap))
++				continue;
++
++			update_bitmap = 1;
++			ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
++		}
++
++		cow_bh[0] = NULL;
++		cow_bh[1] = NULL;
++		nbh = 0;
++		if(update_bitmap){
++			cow_bh[0] = cow_new_bh(dev, start);
++			nbh++;
++			if(start / dev->sectorsize != 
++			   (start + len) / dev->sectorsize){
++				cow_bh[1] = cow_new_bh(dev, start + len);
++				nbh++;
++			}
++		}
++		
++		bh->b_dev = dev->cow_dev;
++		bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++		cow_handle_bh(dev, bh, cow_bh, nbh);
++
++		/*
++		 * upped both for pending work and tear-down, lo_pending
++		 * will hit zero then
++		 */
++		if(atomic_dec_and_test(&dev->working))
++			break;
++	}
++
++	up(&dev->sem);
++	return(0);
++}
++
++static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
++{
++	struct cow *dev;
++	int n, minor;
++
++	minor = MINOR(bh->b_rdev);
++	n = minor >> COW_SHIFT;
++	dev = &cow_dev[n];
++
++	dev->end_io = NULL;
++	if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
++		bh->b_rdev = dev->cow_dev;
++		bh->b_rsector += dev->data_offset / dev->sectorsize;
++	}
++	else if(rw == WRITE){
++		bh->b_dev = dev->cow_dev;
++		bh->b_blocknr += dev->data_offset / dev->sectorsize;
++
++		cow_add_bh(dev, bh);
++		up(&dev->io_sem);
++		return(0);
++	}
++	else {
++		bh->b_rdev = dev->backing_dev;
++	}
++
++	return(1);
++}
++
++int cow_init(void)
++{
++	int i;
++
++	cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
++	if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
++		printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
++		return -1;
++	}
++	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
++	blksize_size[MAJOR_NR] = blk_sizes;
++	blk_size[MAJOR_NR] = sizes;
++	INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
++
++	cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
++	blk_init_queue(cow_queue, NULL);
++	INIT_ELV(cow_queue, &cow_queue->elevator);
++	blk_queue_make_request(cow_queue, cow_make_request);
++
++       add_gendisk(&cow_gendisk);
++
++	for(i=0;i<MAX_DEV;i++) 
++		cow_add(i);
++
++	return(0);
++}
++
++__initcall(cow_init);
++
++static int reader(__u64 start, char *buf, int count, void *arg)
++{
++	dev_t dev = *((dev_t *) arg);
++	struct buffer_head *bh;
++	__u64 block;
++	int cur, offset, left, n, blocksize = get_hardsect_size(dev);
++
++	if(blocksize == 0)
++		panic("Zero blocksize");
++
++	block = start / blocksize;
++	offset = start % blocksize;
++	left = count;
++	cur = 0;
++	while(left > 0){
++		n = (left > blocksize) ? blocksize : left;
++
++		bh = bread(dev, block, (n < 512) ? 512 : n);
++		if(bh == NULL)
++			return(-EIO);
++
++		n -= offset;
++		memcpy(&buf[cur], bh->b_data + offset, n);
++		block++;
++		left -= n;
++		cur += n;
++		offset = 0;
++		brelse(bh);
++	}
++
++	return(count);
++}
++
++static int cow_open(struct inode *inode, struct file *filp)
++{
++	int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
++			 unsigned long);
++	mm_segment_t fs;
++	struct cow *dev;
++	__u64 size;
++	__u32 magic;
++	time_t mtime;
++	char *backing_file;
++	int n, offset, err = 0;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++	offset = n << COW_SHIFT;
++
++	spin_lock(&cow_lock);
++
++	if(dev->count == 0){
++		dev->cow_dev = name_to_kdev_t(dev->cow_path);
++		if(dev->cow_dev == 0){
++			printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++			       "failed\n", dev->cow_path);
++			err = -ENODEV;
++		}
++
++		dev->backing_dev = name_to_kdev_t(dev->backing_path);
++		if(dev->backing_dev == 0){
++			printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
++			       "failed\n", dev->backing_path);
++			err = -ENODEV;
++		}
++
++		if(err) 
++			goto out;
++
++		dev->cow_bdev = bdget(dev->cow_dev);
++		if(dev->cow_bdev == NULL){
++			printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
++			       dev->cow_path);
++			err = -ENOMEM;
++		}
++		dev->backing_bdev = bdget(dev->backing_dev);
++		if(dev->backing_bdev == NULL){
++			printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
++			       dev->backing_path);
++			err = -ENOMEM;
++		}
++
++		if(err) 
++			goto out;
++
++		err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
++				 BDEV_RAW);
++		if(err){
++			printk("cow_open - blkdev_get of COW device failed, "
++			       "error = %d\n", err);
++			goto out;
++		}
++		
++		err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
++		if(err){
++			printk("cow_open - blkdev_get of backing device "
++			       "failed, error = %d\n", err);
++			goto out;
++		}
++		
++		err = read_cow_header(reader, &dev->cow_dev, &magic, 
++				      &backing_file, &mtime, &size,
++				      &dev->sectorsize, &dev->bitmap_offset);
++		if(err){
++			printk(KERN_ERR "cow_open - read_cow_header failed, "
++			       "err = %d\n", err);
++			goto out;
++		}
++
++		cow_sizes(size, dev->sectorsize, dev->bitmap_offset, 
++			  &dev->bitmap_len, &dev->data_offset);
++		dev->bitmap = (void *) vmalloc(dev->bitmap_len);
++		if(dev->bitmap == NULL){
++			err = -ENOMEM;
++			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++			goto out;
++		}
++		flush_tlb_kernel_vm();
++		
++		err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
++			     dev->bitmap_len, &dev->cow_dev);
++		if(err < 0){
++			printk(KERN_ERR "Failed to read COW bitmap\n");
++			vfree(dev->bitmap);
++			goto out;
++		}
++
++		dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++		fs = get_fs();
++		set_fs(KERNEL_DS);
++		err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
++				   (unsigned long) &sizes[offset]);
++		set_fs(fs);
++		if(err){
++			printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
++			       "error = %d\n", err);
++			goto out;
++		}
++
++		kernel_thread(cow_thread, dev, 
++			      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++		down(&dev->sem);
++	}
++	dev->count++;
++out:
++	spin_unlock(&cow_lock);
++	return(err);
++}
++
++static int cow_release(struct inode * inode, struct file * file)
++{
++	struct cow *dev;
++	int n, err;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++
++	spin_lock(&cow_lock);
++
++	if(--dev->count > 0)
++		goto out;
++
++	err = blkdev_put(dev->cow_bdev, BDEV_RAW);
++	if(err)
++		printk("cow_release - blkdev_put of cow device failed, "
++		       "error = %d\n", err);
++	bdput(dev->cow_bdev);
++	dev->cow_bdev = 0;
++
++	err = blkdev_put(dev->backing_bdev, BDEV_RAW);
++	if(err)
++		printk("cow_release - blkdev_put of backing device failed, "
++		       "error = %d\n", err);
++	bdput(dev->backing_bdev);
++	dev->backing_bdev = 0;
++
++out:
++	spin_unlock(&cow_lock);
++	return(0);
++}
++
++static int cow_ioctl(struct inode * inode, struct file * file,
++		     unsigned int cmd, unsigned long arg)
++{
++	struct cow *dev;
++	int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
++			 unsigned long);
++	int n;
++
++	n = DEVICE_NR(inode->i_rdev);
++	if(n >= MAX_DEV)
++		return(-ENODEV);
++	dev = &cow_dev[n];
++
++	dev_ioctl = dev->backing_bdev->bd_op->ioctl;
++	return((*dev_ioctl)(inode, file, cmd, arg));
++}
++
++static int cow_revalidate(kdev_t rdev)
++{
++	printk(KERN_ERR "Need to implement cow_revalidate\n");
++	return(0);
++}
++
++static int parse_unit(char **ptr)
++{
++	char *str = *ptr, *end;
++	int n = -1;
++
++	if(isdigit(*str)) {
++		n = simple_strtoul(str, &end, 0);
++		if(end == str)
++			return(-1);
++		*ptr = end;
++	}
++	else if (('a' <= *str) && (*str <= 'h')) {
++		n = *str - 'a';
++		str++;
++		*ptr = str;
++	}
++	return(n);
++}
++
++static int cow_setup(char *str)
++{
++	struct cow *dev;
++	char *cow_name, *backing_name;
++	int unit;
++
++	unit = parse_unit(&str);
++	if(unit < 0){
++		printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
++		return(1);
++	}
++
++	if(*str != '='){
++		printk(KERN_ERR "cow_setup - Missing '=' after unit "
++		       "number\n");
++		return(1);
++	}
++	str++;
++
++	cow_name = str;
++	backing_name = strchr(str, ',');
++	if(backing_name == NULL){
++		printk(KERN_ERR "cow_setup - missing backing device name\n");
++		return(0);
++	}
++	*backing_name = '\0';
++	backing_name++;
++
++	spin_lock(&cow_lock);
++
++	dev = &cow_dev[unit];
++	dev->cow_path = cow_name;
++	dev->backing_path = backing_name;
++	
++	spin_unlock(&cow_lock);
++	return(0);
++}
++
++__setup("cow", cow_setup);
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
+--- a/arch/um/drivers/cow_sys.h	Wed Dec 31 19:00:00 1969
++++ b/arch/um/drivers/cow_sys.h	Tue Sep  9 16:49:10 2003
+@@ -0,0 +1,48 @@
++#ifndef __COW_SYS_H__
++#define __COW_SYS_H__
++
++#include "kern_util.h"
++#include "user_util.h"
++#include "os.h"
++#include "user.h"
++
++static inline void *cow_malloc(int size)
++{
++	return(um_kmalloc(size));
++}
++
++static inline void cow_free(void *ptr)
++{
++	kfree(ptr);
++}
++
++#define cow_printf printk
++
++static inline char *cow_strdup(char *str)
++{
++	return(uml_strdup(str));
++}
++
++static inline int cow_seek_file(int fd, __u64 offset)
++{
++	return(os_seek_file(fd, offset));
++}
++
++static inline int cow_file_size(char *file, __u64 *size_out)
++{
++	return(os_file_size(file, size_out));
++}
++
++static inline int cow_write_file(int fd, char *buf, int size)
++{
++	return(os_write_file(fd, buf, size));
++}
++
++#endif
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
+--- a/arch/um/drivers/cow_user.c	Wed Dec 31 19:00:00 1969
++++ b/arch/um/drivers/cow_user.c	Tue Sep  9 16:49:06 2003
+@@ -0,0 +1,296 @@
++#include <stddef.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <byteswap.h>
++#include <sys/stat.h>
++#include <sys/time.h>
++#include <sys/param.h>
++#include <netinet/in.h>
++
++#include "cow.h"
++#include "cow_sys.h"
++
++#define PATH_LEN_V1 256
++
++struct cow_header_v1 {
++	int magic;
++	int version;
++	char backing_file[PATH_LEN_V1];
++	time_t mtime;
++	__u64 size;
++	int sectorsize;
++};
++
++#define PATH_LEN_V2 MAXPATHLEN
++
++struct cow_header_v2 {
++	unsigned long magic;
++	unsigned long version;
++	char backing_file[PATH_LEN_V2];
++	time_t mtime;
++	__u64 size;
++	int sectorsize;
++};
++
++union cow_header {
++	struct cow_header_v1 v1;
++	struct cow_header_v2 v2;
++};
++
++#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
++#define COW_VERSION 2
++
++void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
++	       unsigned long *bitmap_len_out, int *data_offset_out)
++{
++	*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
++
++	*data_offset_out = bitmap_offset + *bitmap_len_out;
++	*data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
++	*data_offset_out *= sectorsize;
++}
++
++static int absolutize(char *to, int size, char *from)
++{
++	char save_cwd[256], *slash;
++	int remaining;
++
++	if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
++		cow_printf("absolutize : unable to get cwd - errno = %d\n", 
++			   errno);
++		return(-1);
++	}
++	slash = strrchr(from, '/');
++	if(slash != NULL){
++		*slash = '\0';
++		if(chdir(from)){
++			*slash = '/';
++			cow_printf("absolutize : Can't cd to '%s' - " 
++				   "errno = %d\n", from, errno);
++			return(-1);
++		}
++		*slash = '/';
++		if(getcwd(to, size) == NULL){
++			cow_printf("absolutize : unable to get cwd of '%s' - "
++			       "errno = %d\n", from, errno);
++			return(-1);
++		}
++		remaining = size - strlen(to);
++		if(strlen(slash) + 1 > remaining){
++			cow_printf("absolutize : unable to fit '%s' into %d "
++			       "chars\n", from, size);
++			return(-1);
++		}
++		strcat(to, slash);
++	}
++	else {
++		if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
++			cow_printf("absolutize : unable to fit '%s' into %d "
++			       "chars\n", from, size);
++			return(-1);
++		}
++		strcpy(to, save_cwd);
++		strcat(to, "/");
++		strcat(to, from);
++	}
++	chdir(save_cwd);
++	return(0);
++}
++
++int write_cow_header(char *cow_file, int fd, char *backing_file, 
++		     int sectorsize, long long *size)
++{
++	struct cow_header_v2 *header;
++	struct stat64 buf;
++	int err;
++
++	err = cow_seek_file(fd, 0);
++	if(err != 0){
++		cow_printf("write_cow_header - lseek failed, errno = %d\n", 
++			   errno);
++		return(-errno);
++	}
++
++	err = -ENOMEM;
++	header = cow_malloc(sizeof(*header));
++	if(header == NULL){
++		cow_printf("Failed to allocate COW V2 header\n");
++		goto out;
++	}
++	header->magic = htonl(COW_MAGIC);
++	header->version = htonl(COW_VERSION);
++
++	err = -EINVAL;
++	if(strlen(backing_file) > sizeof(header->backing_file) - 1){
++		cow_printf("Backing file name \"%s\" is too long - names are "
++			   "limited to %d characters\n", backing_file, 
++			   sizeof(header->backing_file) - 1);
++		goto out_free;
++	}
++
++	if(absolutize(header->backing_file, sizeof(header->backing_file), 
++		      backing_file))
++		goto out_free;
++
++	err = stat64(header->backing_file, &buf);
++	if(err < 0){
++		cow_printf("Stat of backing file '%s' failed, errno = %d\n",
++			   header->backing_file, errno);
++		err = -errno;
++		goto out_free;
++	}
++
++	err = cow_file_size(header->backing_file, size);
++	if(err){
++		cow_printf("Couldn't get size of backing file '%s', "
++			   "errno = %d\n", header->backing_file, -*size);
++		goto out_free;
++	}
++
++	header->mtime = htonl(buf.st_mtime);
++	header->size = htonll(*size);
++	header->sectorsize = htonl(sectorsize);
++
++	err = write(fd, header, sizeof(*header));
++	if(err != sizeof(*header)){
++		cow_printf("Write of header to new COW file '%s' failed, "
++			   "errno = %d\n", cow_file, errno);
++		goto out_free;
++	}
++	err = 0;
++ out_free:
++	cow_free(header);
++ out:
++	return(err);
++}
++
++int file_reader(__u64 offset, char *buf, int len, void *arg)
++{
++	int fd = *((int *) arg);
++
++	return(pread(fd, buf, len, offset));
++}
++
++int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
++		    __u32 *magic_out, char **backing_file_out, 
++		    time_t *mtime_out, __u64 *size_out, 
++		    int *sectorsize_out, int *bitmap_offset_out)
++{
++	union cow_header *header;
++	char *file;
++	int err, n;
++	unsigned long version, magic;
++
++	header = cow_malloc(sizeof(*header));
++	if(header == NULL){
++	        cow_printf("read_cow_header - Failed to allocate header\n");
++		return(-ENOMEM);
++	}
++	err = -EINVAL;
++	n = (*reader)(0, (char *) header, sizeof(*header), arg);
++	if(n < offsetof(typeof(header->v1), backing_file)){
++		cow_printf("read_cow_header - short header\n");
++		goto out;
++	}
++
++	magic = header->v1.magic;
++	if(magic == COW_MAGIC) {
++		version = header->v1.version;
++	}
++	else if(magic == ntohl(COW_MAGIC)){
++		version = ntohl(header->v1.version);
++	}
++	/* No error printed because the non-COW case comes through here */
++	else goto out;
++
++	*magic_out = COW_MAGIC;
++
++	if(version == 1){
++		if(n < sizeof(header->v1)){
++			cow_printf("read_cow_header - failed to read V1 "
++				   "header\n");
++			goto out;
++		}
++		*mtime_out = header->v1.mtime;
++		*size_out = header->v1.size;
++		*sectorsize_out = header->v1.sectorsize;
++		*bitmap_offset_out = sizeof(header->v1);
++		file = header->v1.backing_file;
++	}
++	else if(version == 2){
++		if(n < sizeof(header->v2)){
++			cow_printf("read_cow_header - failed to read V2 "
++				   "header\n");
++			goto out;
++		}
++		*mtime_out = ntohl(header->v2.mtime);
++		*size_out = ntohll(header->v2.size);
++		*sectorsize_out = ntohl(header->v2.sectorsize);
++		*bitmap_offset_out = sizeof(header->v2);
++		file = header->v2.backing_file;
++	}
++	else {
++		cow_printf("read_cow_header - invalid COW version\n");
++		goto out;
++	}
++	err = -ENOMEM;
++	*backing_file_out = cow_strdup(file);
++	if(*backing_file_out == NULL){
++		cow_printf("read_cow_header - failed to allocate backing "
++			   "file\n");
++		goto out;
++	}
++	err = 0;
++ out:
++	cow_free(header);
++	return(err);
++}
++
++int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
++		  int *bitmap_offset_out, unsigned long *bitmap_len_out, 
++		  int *data_offset_out)
++{
++	__u64 size, offset;
++	char zero = 0;
++	int err;
++
++	err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
++	if(err) 
++		goto out;
++	
++	cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
++		  bitmap_len_out, data_offset_out);
++	*bitmap_offset_out = sizeof(struct cow_header_v2);
++
++	offset = *data_offset_out + size - sizeof(zero);
++	err = cow_seek_file(fd, offset);
++	if(err != 0){
++		cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
++		goto out;
++	}
++
++	/* does not really matter how much we write it is just to set EOF 
++	 * this also sets the entire COW bitmap
++	 * to zero without having to allocate it 
++	 */
++	err = cow_write_file(fd, &zero, sizeof(zero));
++	if(err != sizeof(zero)){
++		err = -EINVAL;
++		cow_printf("Write of bitmap to new COW file '%s' failed, "
++			   "errno = %d\n", cow_file, errno);
++		goto out;
++	}
++
++	return(0);
++
++ out:
++	return(err);
++}
++
++/*
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
+--- a/arch/um/drivers/hostaudio_kern.c	Tue Sep  9 16:46:07 2003
++++ b/arch/um/drivers/hostaudio_kern.c	Tue Sep  9 16:51:08 2003
+@@ -11,6 +11,7 @@
+ #include "linux/fs.h"
+ #include "linux/sound.h"
+ #include "linux/soundcard.h"
++#include "asm/uaccess.h"
+ #include "kern_util.h"
+ #include "init.h"
+ #include "hostaudio.h"
+@@ -22,7 +23,7 @@
+ #ifndef MODULE
+ static int set_dsp(char *name, int *add)
+ {
+-	dsp = uml_strdup(name);
++	dsp = name;
+ 	return(0);
+ }
+ 
+@@ -34,7 +35,7 @@
+ 
+ static int set_mixer(char *name, int *add)
+ {
+-	mixer = uml_strdup(name);
++	mixer = name;
+ 	return(0);
+ }
+ 
+@@ -51,23 +52,55 @@
+ 			      loff_t *ppos)
+ {
+         struct hostaudio_state *state = file->private_data;
++	void *kbuf;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: read called, count = %d\n", count);
+ #endif
+ 
+-        return(hostaudio_read_user(state, buffer, count, ppos));
++	kbuf = kmalloc(count, GFP_KERNEL);
++	if(kbuf == NULL)
++		return(-ENOMEM);
++
++        err = hostaudio_read_user(state, kbuf, count, ppos);
++	if(err < 0)
++		goto out;
++
++	if(copy_to_user(buffer, kbuf, err))
++		err = -EFAULT;
++
++ out:
++	kfree(kbuf);
++	return(err);
+ }
+ 
+ static ssize_t hostaudio_write(struct file *file, const char *buffer, 
+ 			       size_t count, loff_t *ppos)
+ {
+         struct hostaudio_state *state = file->private_data;
++	void *kbuf;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: write called, count = %d\n", count);
+ #endif
+-        return(hostaudio_write_user(state, buffer, count, ppos));
++
++	kbuf = kmalloc(count, GFP_KERNEL);
++	if(kbuf == NULL)
++		return(-ENOMEM);
++
++	err = -EFAULT;
++	if(copy_from_user(kbuf, buffer, count))
++		goto out;
++
++        err = hostaudio_write_user(state, kbuf, count, ppos);
++	if(err < 0)
++		goto out;
++
++ out:
++	kfree(kbuf);
++	return(err);
+ }
+ 
+ static unsigned int hostaudio_poll(struct file *file, 
+@@ -86,12 +119,43 @@
+ 			   unsigned int cmd, unsigned long arg)
+ {
+         struct hostaudio_state *state = file->private_data;
++	unsigned long data = 0;
++	int err;
+ 
+ #ifdef DEBUG
+         printk("hostaudio: ioctl called, cmd = %u\n", cmd);
+ #endif
++	switch(cmd){
++	case SNDCTL_DSP_SPEED:
++	case SNDCTL_DSP_STEREO:
++	case SNDCTL_DSP_GETBLKSIZE:
++	case SNDCTL_DSP_CHANNELS:
++	case SNDCTL_DSP_SUBDIVIDE:
++	case SNDCTL_DSP_SETFRAGMENT:
++		if(get_user(data, (int *) arg))
++			return(-EFAULT);
++		break;
++	default:
++		break;
++	}
++
++        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
++
++	switch(cmd){
++	case SNDCTL_DSP_SPEED:
++	case SNDCTL_DSP_STEREO:
++	case SNDCTL_DSP_GETBLKSIZE:
++	case SNDCTL_DSP_CHANNELS:
++	case SNDCTL_DSP_SUBDIVIDE:
++	case SNDCTL_DSP_SETFRAGMENT:
++		if(put_user(data, (int *) arg))
++			return(-EFAULT);
++		break;
++	default:
++		break;
++	}
+ 
+-        return(hostaudio_ioctl_user(state, cmd, arg));
++	return(err);
+ }
+ 
+ static int hostaudio_open(struct inode *inode, struct file *file)
+@@ -225,7 +289,8 @@
+ 
+ static int __init hostaudio_init_module(void)
+ {
+-        printk(KERN_INFO "UML Audio Relay\n");
++        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
++	       dsp, mixer);
+ 
+ 	module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
+         if(module_data.dev_audio < 0){
+diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
+--- a/arch/um/drivers/line.c	Tue Sep  9 16:45:58 2003
++++ b/arch/um/drivers/line.c	Tue Sep  9 16:50:27 2003
+@@ -6,8 +6,8 @@
+ #include "linux/sched.h"
+ #include "linux/slab.h"
+ #include "linux/list.h"
++#include "linux/interrupt.h"
+ #include "linux/devfs_fs_kernel.h"
+-#include "asm/irq.h"
+ #include "asm/uaccess.h"
+ #include "chan_kern.h"
+ #include "irq_user.h"
+@@ -16,16 +16,18 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "os.h"
++#include "irq_kern.h"
+ 
+ #define LINE_BUFSIZE 4096
+ 
+-void line_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct line *dev = data;
+ 
+ 	if(dev->count > 0) 
+ 		chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
+ 			       dev);
++	return IRQ_HANDLED;
+ }
+ 
+ void line_timer_cb(void *arg)
+@@ -136,20 +138,22 @@
+ 	return(len);
+ }
+ 
+-void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct line *dev = data;
+ 	struct tty_struct *tty = dev->tty;
+ 	int err;
+ 
+ 	err = flush_buffer(dev);
+-	if(err == 0) return;
++	if(err == 0) 
++		return(IRQ_NONE);
+ 	else if(err < 0){
+ 		dev->head = dev->buffer;
+ 		dev->tail = dev->buffer;
+ 	}
+ 
+-	if(tty == NULL) return;
++	if(tty == NULL) 
++		return(IRQ_NONE);
+ 
+ 	if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
+ 	   (tty->ldisc.write_wakeup != NULL))
+@@ -161,9 +165,9 @@
+ 	 * writes.
+ 	 */
+ 
+-	if (waitqueue_active(&tty->write_wait))
++	if(waitqueue_active(&tty->write_wait))
+ 		wake_up_interruptible(&tty->write_wait);
+-
++	return(IRQ_HANDLED);
+ }
+ 
+ int line_write_room(struct tty_struct *tty)
+@@ -369,7 +373,7 @@
+ 
+ 	dev = simple_strtoul(name, &end, 0);
+ 	if((*end != '\0') || (end == name)){
+-		*error_out = "line_setup failed to parse device number";
++		*error_out = "line_get_config failed to parse device number";
+ 		return(0);
+ 	}
+ 
+@@ -379,15 +383,15 @@
+ 	}
+ 
+ 	line = &lines[dev];
++
+ 	down(&line->sem);
+-	
+ 	if(!line->valid)
+ 		CONFIG_CHUNK(str, size, n, "none", 1);
+ 	else if(line->count == 0)
+ 		CONFIG_CHUNK(str, size, n, line->init_str, 1);
+ 	else n = chan_config_string(&line->chan_list, str, size, error_out);
+-
+ 	up(&line->sem);
++
+ 	return(n);
+ }
+ 
+@@ -412,7 +416,8 @@
+ 		return NULL;
+ 
+ 	driver->driver_name = line_driver->name;
+-	driver->name = line_driver->devfs_name;
++	driver->name = line_driver->device_name;
++	driver->devfs_name = line_driver->devfs_name;
+ 	driver->major = line_driver->major;
+ 	driver->minor_start = line_driver->minor_start;
+ 	driver->type = line_driver->type;
+@@ -432,7 +437,7 @@
+ 
+ 	for(i = 0; i < nlines; i++){
+ 		if(!lines[i].valid) 
+-			tty_unregister_devfs(driver, i);
++			tty_unregister_device(driver, i);
+ 	}
+ 
+ 	mconsole_register_dev(&line_driver->mc);
+@@ -465,24 +470,25 @@
+ 	struct line *line;
+ };
+ 
+-void winch_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	struct winch *winch = data;
+ 	struct tty_struct *tty;
+ 	int err;
+ 	char c;
+ 
+-	err = generic_read(winch->fd, &c, NULL);
+-	if(err < 0){
+-		if(err != -EAGAIN){
+-			printk("winch_interrupt : read failed, errno = %d\n", 
+-			       -err);
+-			printk("fd %d is losing SIGWINCH support\n", 
+-			       winch->tty_fd);
+-			free_irq(irq, data);
+-			return;
++	if(winch->fd != -1){
++		err = generic_read(winch->fd, &c, NULL);
++		if(err < 0){
++			if(err != -EAGAIN){
++				printk("winch_interrupt : read failed, "
++				       "errno = %d\n", -err);
++				printk("fd %d is losing SIGWINCH support\n", 
++				       winch->tty_fd);
++				return(IRQ_HANDLED);
++			}
++			goto out;
+ 		}
+-		goto out;
+ 	}
+ 	tty = winch->line->tty;
+ 	if(tty != NULL){
+@@ -492,7 +498,9 @@
+ 		kill_pg(tty->pgrp, SIGWINCH, 1);
+ 	}
+  out:
+-	reactivate_fd(winch->fd, WINCH_IRQ);
++	if(winch->fd != -1)
++		reactivate_fd(winch->fd, WINCH_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ DECLARE_MUTEX(winch_handler_sem);
+@@ -529,7 +537,10 @@
+ 
+ 	list_for_each(ele, &winch_handlers){
+ 		winch = list_entry(ele, struct winch, list);
+-		close(winch->fd);
++		if(winch->fd != -1){
++			deactivate_fd(winch->fd, WINCH_IRQ);
++			close(winch->fd);
++		}
+ 		if(winch->pid != -1) 
+ 			os_kill_process(winch->pid, 1);
+ 	}
+diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
+--- a/arch/um/drivers/mconsole_kern.c	Tue Sep  9 16:41:12 2003
++++ b/arch/um/drivers/mconsole_kern.c	Tue Sep  9 16:47:22 2003
+@@ -27,6 +27,7 @@
+ #include "init.h"
+ #include "os.h"
+ #include "umid.h"
++#include "irq_kern.h"
+ 
+ static int do_unlink_socket(struct notifier_block *notifier, 
+ 			    unsigned long what, void *data)
+@@ -67,7 +68,7 @@
+ 
+ DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
+ 
+-void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	int fd;
+ 	struct mconsole_entry *new;
+@@ -88,6 +89,7 @@
+ 	}
+ 	if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
+ 	reactivate_fd(fd, MCONSOLE_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ void mconsole_version(struct mc_request *req)
+@@ -100,20 +102,34 @@
+ 	mconsole_reply(req, version, 0, 0);
+ }
+ 
++void mconsole_log(struct mc_request *req)
++{
++	int len;
++	char *ptr = req->request.data;
++	
++	ptr += strlen("log");
++	while(isspace(*ptr)) ptr++;
++
++	len = ptr - req->request.data;
++	printk("%.*s", len, ptr);
++	mconsole_reply(req, "", 0, 0);
++}
++
+ #define UML_MCONSOLE_HELPTEXT \
+-"Commands:
+-    version - Get kernel version
+-    help - Print this message
+-    halt - Halt UML
+-    reboot - Reboot UML
+-    config <dev>=<config> - Add a new device to UML; 
+-	same syntax as command line
+-    config <dev> - Query the configuration of a device
+-    remove <dev> - Remove a device from UML
+-    sysrq <letter> - Performs the SysRq action controlled by the letter
+-    cad - invoke the Ctl-Alt-Del handler
+-    stop - pause the UML; it will do nothing until it receives a 'go'
+-    go - continue the UML after a 'stop'
++"Commands: \n\
++    version - Get kernel version \n\
++    help - Print this message \n\
++    halt - Halt UML \n\
++    reboot - Reboot UML \n\
++    config <dev>=<config> - Add a new device to UML;  \n\
++	same syntax as command line \n\
++    config <dev> - Query the configuration of a device \n\
++    remove <dev> - Remove a device from UML \n\
++    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
++    cad - invoke the Ctl-Alt-Del handler \n\
++    stop - pause the UML; it will do nothing until it receives a 'go' \n\
++    go - continue the UML after a 'stop' \n\
++    log <string> - make UML enter <string> into the kernel log\n\
+ "
+ 
+ void mconsole_help(struct mc_request *req)
+@@ -302,7 +318,7 @@
+ 	if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
+ 	snprintf(mconsole_socket_name, sizeof(file), "%s", file);
+ 
+-	sock = create_unix_socket(file, sizeof(file));
++	sock = create_unix_socket(file, sizeof(file), 1);
+ 	if (sock < 0){
+ 		printk("Failed to initialize management console\n");
+ 		return(1);
+diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
+--- a/arch/um/drivers/mconsole_user.c	Tue Sep  9 16:41:40 2003
++++ b/arch/um/drivers/mconsole_user.c	Tue Sep  9 16:47:42 2003
+@@ -28,6 +28,7 @@
+ 	{ "cad", mconsole_cad, 1 },
+ 	{ "stop", mconsole_stop, 0 },
+ 	{ "go", mconsole_go, 1 },
++	{ "log", mconsole_log, 1 },
+ };
+ 
+ /* Initialized in mconsole_init, which is an initcall */
+@@ -139,6 +140,7 @@
+ 		memcpy(reply.data, str, len);
+ 		reply.data[len] = '\0';
+ 		total -= len;
++ 		str += len;
+ 		reply.len = len + 1;
+ 
+ 		len = sizeof(reply) + reply.len - sizeof(reply.data);
+diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
+--- a/arch/um/drivers/mmapper_kern.c	Tue Sep  9 16:41:34 2003
++++ b/arch/um/drivers/mmapper_kern.c	Tue Sep  9 16:47:40 2003
+@@ -120,7 +120,10 @@
+ 	printk(KERN_INFO "Mapper v0.1\n");
+ 
+ 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
+-	if(mmapper_size == 0) return(0);
++	if(mmapper_size == 0){
++		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
++		return(0);
++	}
+ 
+ 	p_buf = __pa(v_buf);
+ 
+diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
+--- a/arch/um/drivers/net_kern.c	Tue Sep  9 16:43:06 2003
++++ b/arch/um/drivers/net_kern.c	Tue Sep  9 16:48:52 2003
+@@ -26,6 +26,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(opened);
+@@ -61,14 +62,14 @@
+ 	return pkt_len;
+ }
+ 
+-void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct net_device *dev = dev_id;
+ 	struct uml_net_private *lp = dev->priv;
+ 	int err;
+ 
+ 	if(!netif_running(dev))
+-		return;
++		return(IRQ_NONE);
+ 
+ 	spin_lock(&lp->lock);
+ 	while((err = uml_net_rx(dev)) > 0) ;
+@@ -83,6 +84,7 @@
+ 
+  out:
+ 	spin_unlock(&lp->lock);
++	return(IRQ_HANDLED);
+ }
+ 
+ static int uml_net_open(struct net_device *dev)
+@@ -252,37 +254,6 @@
+ #endif
+ }
+ 
+-/*
+- * default do nothing hard header packet routines for struct net_device init.
+- * real ethernet transports will overwrite with real routines.
+- */
+-static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
+-                 unsigned short type, void *daddr, void *saddr, unsigned len)
+-{
+-	return(0); /* no change */
+-}
+-
+-static int uml_net_rebuild_header(struct sk_buff *skb)
+-{
+-	return(0); /* ignore */ 
+-}
+-
+-static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+-{
+-	return(-1); /* fail */
+-}
+-
+-static void uml_net_header_cache_update(struct hh_cache *hh,
+-                 struct net_device *dev, unsigned char * haddr)
+-{
+-	/* ignore */
+-}
+-
+-static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
+-{
+-	return(0); /* nothing */
+-}
+-
+ static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
+ static struct list_head devices = LIST_HEAD_INIT(devices);
+ 
+@@ -292,7 +263,7 @@
+ 	struct uml_net *device;
+ 	struct net_device *dev;
+ 	struct uml_net_private *lp;
+-	int err, size;
++	int save, err, size;
+ 
+ 	size = transport->private_size + sizeof(struct uml_net_private) + 
+ 		sizeof(((struct uml_net_private *) 0)->user);
+@@ -334,12 +305,6 @@
+ 	snprintf(dev->name, sizeof(dev->name), "eth%d", n);
+ 	device->dev = dev;
+ 
+-        dev->hard_header = uml_net_hard_header;
+-        dev->rebuild_header = uml_net_rebuild_header;
+-        dev->hard_header_cache = uml_net_header_cache;
+-        dev->header_cache_update= uml_net_header_cache_update;
+-        dev->hard_header_parse = uml_net_header_parse;
+-
+ 	(*transport->kern->init)(dev, init);
+ 
+ 	dev->mtu = transport->user->max_packet;
+@@ -362,21 +327,29 @@
+ 		return 1;
+ 	lp = dev->priv;
+ 
+-	INIT_LIST_HEAD(&lp->list);
+-	spin_lock_init(&lp->lock);
+-	lp->dev = dev;
+-	lp->fd = -1;
+-	lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
+-	lp->have_mac = device->have_mac;
+-	lp->protocol = transport->kern->protocol;
+-	lp->open = transport->user->open;
+-	lp->close = transport->user->close;
+-	lp->remove = transport->user->remove;
+-	lp->read = transport->kern->read;
+-	lp->write = transport->kern->write;
+-	lp->add_address = transport->user->add_address;
+-	lp->delete_address = transport->user->delete_address;
+-	lp->set_mtu = transport->user->set_mtu;
++	/* lp.user is the first four bytes of the transport data, which
++	 * has already been initialized.  This structure assignment will
++	 * overwrite that, so we make sure that .user gets overwritten with
++	 * what it already has.
++	 */
++	save = lp->user[0];
++	*lp = ((struct uml_net_private) 
++		{ .list  		= LIST_HEAD_INIT(lp->list),
++		  .lock 		= SPIN_LOCK_UNLOCKED,
++		  .dev 			= dev,
++		  .fd 			= -1,
++		  .mac 			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
++		  .have_mac 		= device->have_mac,
++		  .protocol 		= transport->kern->protocol,
++		  .open 		= transport->user->open,
++		  .close 		= transport->user->close,
++		  .remove 		= transport->user->remove,
++		  .read 		= transport->kern->read,
++		  .write 		= transport->kern->write,
++		  .add_address 		= transport->user->add_address,
++		  .delete_address  	= transport->user->delete_address,
++		  .set_mtu 		= transport->user->set_mtu,
++		  .user  		= { save } });
+ 
+ 	init_timer(&lp->tl);
+ 	lp->tl.function = uml_net_user_timer_expire;
+@@ -609,7 +582,8 @@
+ 	unregister_netdev(dev);
+ 
+ 	list_del(&device->list);
+-	free_netdev(device);
++	kfree(device);
++	free_netdev(dev);
+ 	return(0);
+ }
+ 
+diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
+--- a/arch/um/drivers/port_kern.c	Tue Sep  9 16:41:19 2003
++++ b/arch/um/drivers/port_kern.c	Tue Sep  9 16:47:28 2003
+@@ -6,6 +6,7 @@
+ #include "linux/list.h"
+ #include "linux/sched.h"
+ #include "linux/slab.h"
++#include "linux/interrupt.h"
+ #include "linux/irq.h"
+ #include "linux/spinlock.h"
+ #include "linux/errno.h"
+@@ -14,6 +15,7 @@
+ #include "kern_util.h"
+ #include "kern.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "port.h"
+ #include "init.h"
+ #include "os.h"
+@@ -44,7 +46,7 @@
+ 	struct port_list *port;
+ };
+ 
+-static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct connection *conn = data;
+ 	int fd;
+@@ -52,7 +54,7 @@
+  	fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
+ 	if(fd < 0){
+ 		if(fd == -EAGAIN)
+-			return;
++			return(IRQ_NONE);
+ 
+ 		printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
+ 		       -fd);
+@@ -65,6 +67,7 @@
+ 	list_add(&conn->list, &conn->port->connections);
+ 
+ 	up(&conn->port->sem);
++	return(IRQ_HANDLED);
+ }
+ 
+ static int port_accept(struct port_list *port)
+@@ -138,12 +141,13 @@
+ 
+ DECLARE_WORK(port_work, port_work_proc, NULL);
+ 
+-static void port_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct port_list *port = data;
+ 
+ 	port->has_connection = 1;
+ 	schedule_work(&port_work);
++	return(IRQ_HANDLED);
+ } 
+ 
+ void *port_data(int port_num)
+diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
+--- a/arch/um/drivers/ssl.c	Tue Sep  9 16:43:21 2003
++++ b/arch/um/drivers/ssl.c	Tue Sep  9 16:48:57 2003
+@@ -53,8 +53,9 @@
+ 
+ static struct line_driver driver = {
+ 	.name 			= "UML serial line",
+-	.devfs_name 		= "tts/%d",
+-	.major 			= TTYAUX_MAJOR,
++	.device_name 		= "ttS",
++	.devfs_name 		= "tts/",
++	.major 			= TTY_MAJOR,
+ 	.minor_start 		= 64,
+ 	.type 		 	= TTY_DRIVER_TYPE_SERIAL,
+ 	.subtype 	 	= 0,
+diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
+--- a/arch/um/drivers/stdio_console.c	Tue Sep  9 16:41:51 2003
++++ b/arch/um/drivers/stdio_console.c	Tue Sep  9 16:47:57 2003
+@@ -83,7 +83,8 @@
+ 
+ static struct line_driver driver = {
+ 	.name 			= "UML console",
+-	.devfs_name 		= "vc/%d",
++	.device_name 		= "tty",
++	.devfs_name 		= "vc/",
+ 	.major 			= TTY_MAJOR,
+ 	.minor_start 		= 0,
+ 	.type 		 	= TTY_DRIVER_TYPE_CONSOLE,
+@@ -159,6 +160,15 @@
+ 
+ static int con_init_done = 0;
+ 
++static struct tty_operations console_ops = {
++	.open 	 		= con_open,
++	.close 	 		= con_close,
++	.write 	 		= con_write,
++	.chars_in_buffer 	= chars_in_buffer,
++	.set_termios 		= set_termios,
++	.write_room		= line_write_room,
++};
++
+ int stdio_init(void)
+ {
+ 	char *new_title;
+@@ -166,7 +176,8 @@
+ 	printk(KERN_INFO "Initializing stdio console driver\n");
+ 
+ 	console_driver = line_register_devfs(&console_lines, &driver,
+-				&console_ops, vts, sizeof(vts)/sizeof(vts[0]));
++					     &console_ops, vts,
++					     sizeof(vts)/sizeof(vts[0]));
+ 
+ 	lines_init(vts, sizeof(vts)/sizeof(vts[0]));
+ 
+@@ -188,15 +199,6 @@
+ 	if(con_init_done) up(&vts[console->index].sem);
+ }
+ 
+-static struct tty_operations console_ops = {
+-	.open 	 		= con_open,
+-	.close 	 		= con_close,
+-	.write 	 		= con_write,
+-	.chars_in_buffer 	= chars_in_buffer,
+-	.set_termios 		= set_termios,
+-	.write_room		= line_write_room,
+-};
+-
+ static struct tty_driver *console_device(struct console *c, int *index)
+ {
+ 	*index = c->index;
+@@ -212,12 +214,14 @@
+ 					       console_device, console_setup,
+ 					       CON_PRINTBUFFER);
+ 
+-static void __init stdio_console_init(void)
++static int __init stdio_console_init(void)
+ {
+ 	INIT_LIST_HEAD(&vts[0].chan_list);
+ 	list_add(&init_console_chan.list, &vts[0].chan_list);
+ 	register_console(&stdiocons);
++	return(0);
+ }
++
+ console_initcall(stdio_console_init);
+ 
+ static int console_chan_setup(char *str)
+diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
+--- a/arch/um/drivers/ubd_kern.c	Tue Sep  9 16:43:08 2003
++++ b/arch/um/drivers/ubd_kern.c	Tue Sep  9 16:48:54 2003
+@@ -8,6 +8,13 @@
+  * old style ubd by setting UBD_SHIFT to 0
+  * 2002-09-27...2002-10-18 massive tinkering for 2.5
+  * partitions have changed in 2.5
++ * 2003-01-29 more tinkering for 2.5.59-1
++ * This should now address the sysfs problems and has
++ * the symlink for devfs to allow for booting with
++ * the common /dev/ubd/discX/... names rather than
++ * only /dev/ubdN/discN this version also has lots of
++ * clean ups preparing for ubd-many.
++ * James McMechan
+  */
+ 
+ #define MAJOR_NR UBD_MAJOR
+@@ -40,6 +47,7 @@
+ #include "mconsole_kern.h"
+ #include "init.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "ubd_user.h"
+ #include "2_5compat.h"
+ #include "os.h"
+@@ -67,7 +75,7 @@
+ static request_queue_t *ubd_queue;
+ 
+ /* Protected by ubd_lock */
+-static int fake_major = 0;
++static int fake_major = MAJOR_NR;
+ 
+ static struct gendisk *ubd_gendisk[MAX_DEV];
+ static struct gendisk *fake_gendisk[MAX_DEV];
+@@ -96,12 +104,12 @@
+ 
+ struct ubd {
+ 	char *file;
+-	int is_dir;
+ 	int count;
+ 	int fd;
+ 	__u64 size;
+ 	struct openflags boot_openflags;
+ 	struct openflags openflags;
++	int no_cow;
+ 	struct cow cow;
+ };
+ 
+@@ -115,12 +123,12 @@
+ 
+ #define DEFAULT_UBD { \
+ 	.file = 		NULL, \
+-	.is_dir =		0, \
+ 	.count =		0, \
+ 	.fd =			-1, \
+ 	.size =			-1, \
+ 	.boot_openflags =	OPEN_FLAGS, \
+ 	.openflags =		OPEN_FLAGS, \
++        .no_cow =               0, \
+         .cow =			DEFAULT_COW, \
+ }
+ 
+@@ -128,8 +136,10 @@
+ 
+ static int ubd0_init(void)
+ {
+-	if(ubd_dev[0].file == NULL)
+-		ubd_dev[0].file = "root_fs";
++	struct ubd *dev = &ubd_dev[0];
++
++	if(dev->file == NULL)
++		dev->file = "root_fs";
+ 	return(0);
+ }
+ 
+@@ -196,19 +206,39 @@
+ "    Create ide0 entries that map onto ubd devices.\n\n"
+ );
+ 
++static int parse_unit(char **ptr)
++{
++	char *str = *ptr, *end;
++	int n = -1;
++
++	if(isdigit(*str)) {
++		n = simple_strtoul(str, &end, 0);
++		if(end == str)
++			return(-1);
++		*ptr = end;
++	}
++	else if (('a' <= *str) && (*str <= 'h')) {
++		n = *str - 'a';
++		str++;
++		*ptr = str;
++	}
++	return(n);
++}
++
+ static int ubd_setup_common(char *str, int *index_out)
+ {
++	struct ubd *dev;
+ 	struct openflags flags = global_openflags;
+ 	char *backing_file;
+ 	int n, err;
+ 
+ 	if(index_out) *index_out = -1;
+-	n = *str++;
++	n = *str;
+ 	if(n == '='){
+-		static int fake_major_allowed = 1;
+ 		char *end;
+ 		int major;
+ 
++		str++;
+ 		if(!strcmp(str, "sync")){
+ 			global_openflags.s = 1;
+ 			return(0);
+@@ -220,20 +250,14 @@
+ 			return(1);
+ 		}
+ 
+-		if(!fake_major_allowed){
+-			printk(KERN_ERR "Can't assign a fake major twice\n");
+-			return(1);
+-		}
+-
+ 		err = 1;
+  		spin_lock(&ubd_lock);
+- 		if(!fake_major_allowed){
++ 		if(fake_major != MAJOR_NR){
+  			printk(KERN_ERR "Can't assign a fake major twice\n");
+  			goto out1;
+  		}
+  
+  		fake_major = major;
+-		fake_major_allowed = 0;
+ 
+ 		printk(KERN_INFO "Setting extra ubd major number to %d\n",
+ 		       major);
+@@ -243,25 +267,23 @@
+ 		return(err);
+ 	}
+ 
+-	if(n < '0'){
+-		printk(KERN_ERR "ubd_setup : index out of range\n"); }
+-
+-	if((n >= '0') && (n <= '9')) n -= '0';
+-	else if((n >= 'a') && (n <= 'z')) n -= 'a';
+-	else {
+-		printk(KERN_ERR "ubd_setup : device syntax invalid\n");
++	n = parse_unit(&str);
++	if(n < 0){
++		printk(KERN_ERR "ubd_setup : couldn't parse unit number "
++		       "'%s'\n", str);
+ 		return(1);
+ 	}
+ 	if(n >= MAX_DEV){
+-		printk(KERN_ERR "ubd_setup : index out of range "
+-		       "(%d devices)\n", MAX_DEV);	
++		printk(KERN_ERR "ubd_setup : index %d out of range "
++		       "(%d devices)\n", n, MAX_DEV);
+ 		return(1);
+ 	}
+ 
+ 	err = 1;
+ 	spin_lock(&ubd_lock);
+ 
+-	if(ubd_dev[n].file != NULL){
++	dev = &ubd_dev[n];
++	if(dev->file != NULL){
+ 		printk(KERN_ERR "ubd_setup : device already configured\n");
+ 		goto out2;
+ 	}
+@@ -276,6 +298,11 @@
+ 		flags.s = 1;
+ 		str++;
+ 	}
++	if (*str == 'd'){
++		dev->no_cow = 1;
++		str++;
++	}
++
+ 	if(*str++ != '='){
+ 		printk(KERN_ERR "ubd_setup : Expected '='\n");
+ 		goto out2;
+@@ -284,14 +311,17 @@
+ 	err = 0;
+ 	backing_file = strchr(str, ',');
+ 	if(backing_file){
+-		*backing_file = '\0';
+-		backing_file++;
++		if(dev->no_cow)
++			printk(KERN_ERR "Can't specify both 'd' and a "
++			       "cow file\n");
++		else {
++			*backing_file = '\0';
++			backing_file++;
++		}
+ 	}
+-	ubd_dev[n].file = str;
+-	if(ubd_is_dir(ubd_dev[n].file))
+-		ubd_dev[n].is_dir = 1;
+-	ubd_dev[n].cow.file = backing_file;
+-	ubd_dev[n].boot_openflags = flags;
++	dev->file = str;
++	dev->cow.file = backing_file;
++	dev->boot_openflags = flags;
+  out2:
+ 	spin_unlock(&ubd_lock);
+ 	return(err);
+@@ -321,8 +351,7 @@
+ static int fakehd_set = 0;
+ static int fakehd(char *str)
+ {
+-	printk(KERN_INFO 
+-	       "fakehd : Changing ubd name to \"hd\".\n");
++	printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
+ 	fakehd_set = 1;
+ 	return 1;
+ }
+@@ -391,9 +420,10 @@
+ 	do_ubd_request(ubd_queue);
+ }
+ 
+-static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
++static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
+ {
+ 	ubd_handler();
++	return(IRQ_HANDLED);
+ }
+ 
+ /* Only changed by ubd_init, which is an initcall. */
+@@ -429,16 +459,18 @@
+ static int ubd_open_dev(struct ubd *dev)
+ {
+ 	struct openflags flags;
+-	int err, n, create_cow, *create_ptr;
++	char **back_ptr;
++	int err, create_cow, *create_ptr;
+ 
++	dev->openflags = dev->boot_openflags;
+ 	create_cow = 0;
+ 	create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
+-	dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
++	back_ptr = dev->no_cow ? NULL : &dev->cow.file;
++	dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
+ 				&dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
+ 				&dev->cow.data_offset, create_ptr);
+ 
+ 	if((dev->fd == -ENOENT) && create_cow){
+-		n = dev - ubd_dev;
+ 		dev->fd = create_cow_file(dev->file, dev->cow.file, 
+ 					  dev->openflags, 1 << 9,
+ 					  &dev->cow.bitmap_offset, 
+@@ -455,7 +487,10 @@
+ 	if(dev->cow.file != NULL){
+ 		err = -ENOMEM;
+ 		dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
+-		if(dev->cow.bitmap == NULL) goto error;
++		if(dev->cow.bitmap == NULL){
++			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
++			goto error;
++		}
+ 		flush_tlb_kernel_vm();
+ 
+ 		err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
+@@ -481,17 +516,31 @@
+ 			
+ {
+ 	struct gendisk *disk;
++	char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
++	int err;
+ 
+ 	disk = alloc_disk(1 << UBD_SHIFT);
+-	if (!disk)
+-		return -ENOMEM;
++	if(disk == NULL)
++		return(-ENOMEM);
+ 
+ 	disk->major = major;
+ 	disk->first_minor = unit << UBD_SHIFT;
+ 	disk->fops = &ubd_blops;
+ 	set_capacity(disk, size / 512);
+-	sprintf(disk->disk_name, "ubd");
+-	sprintf(disk->devfs_name, "ubd/disc%d", unit);
++	if(major == MAJOR_NR){
++		sprintf(disk->disk_name, "ubd%d", unit);
++		sprintf(disk->devfs_name, "ubd/disc%d", unit);
++		sprintf(from, "ubd/%d", unit);
++		sprintf(to, "disc%d/disc", unit);
++		err = devfs_mk_symlink(from, to);
++		if(err)
++			printk("ubd_new_disk failed to make link from %s to "
++			       "%s, error = %d\n", from, to, err);
++	}
++	else {
++		sprintf(disk->disk_name, "ubd_fake%d", unit);
++		sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
++	}
+ 
+ 	disk->private_data = &ubd_dev[unit];
+ 	disk->queue = ubd_queue;
+@@ -506,10 +555,7 @@
+ 	struct ubd *dev = &ubd_dev[n];
+ 	int err;
+ 
+-	if(dev->is_dir)
+-		return(-EISDIR);
+-
+-	if (!dev->file)
++	if(dev->file == NULL)
+ 		return(-ENODEV);
+ 
+ 	if (ubd_open_dev(dev))
+@@ -523,7 +569,7 @@
+ 	if(err) 
+ 		return(err);
+  
+-	if(fake_major)
++	if(fake_major != MAJOR_NR)
+ 		ubd_new_disk(fake_major, dev->size, n, 
+ 			     &fake_gendisk[n]);
+ 
+@@ -561,42 +607,42 @@
+ 	return(err);
+ }
+ 
+-static int ubd_get_config(char *dev, char *str, int size, char **error_out)
++static int ubd_get_config(char *name, char *str, int size, char **error_out)
+ {
+-	struct ubd *ubd;
++	struct ubd *dev;
+ 	char *end;
+-	int major, n = 0;
++	int n, len = 0;
+ 
+-	major = simple_strtoul(dev, &end, 0);
+-	if((*end != '\0') || (end == dev)){
+-		*error_out = "ubd_get_config : didn't parse major number";
++	n = simple_strtoul(name, &end, 0);
++	if((*end != '\0') || (end == name)){
++		*error_out = "ubd_get_config : didn't parse device number";
+ 		return(-1);
+ 	}
+ 
+-	if((major >= MAX_DEV) || (major < 0)){
+-		*error_out = "ubd_get_config : major number out of range";
++	if((n >= MAX_DEV) || (n < 0)){
++		*error_out = "ubd_get_config : device number out of range";
+ 		return(-1);
+ 	}
+ 
+-	ubd = &ubd_dev[major];
++	dev = &ubd_dev[n];
+ 	spin_lock(&ubd_lock);
+ 
+-	if(ubd->file == NULL){
+-		CONFIG_CHUNK(str, size, n, "", 1);
++	if(dev->file == NULL){
++		CONFIG_CHUNK(str, size, len, "", 1);
+ 		goto out;
+ 	}
+ 
+-	CONFIG_CHUNK(str, size, n, ubd->file, 0);
++	CONFIG_CHUNK(str, size, len, dev->file, 0);
+ 
+-	if(ubd->cow.file != NULL){
+-		CONFIG_CHUNK(str, size, n, ",", 0);
+-		CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
++	if(dev->cow.file != NULL){
++		CONFIG_CHUNK(str, size, len, ",", 0);
++		CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+ 	}
+-	else CONFIG_CHUNK(str, size, n, "", 1);
++	else CONFIG_CHUNK(str, size, len, "", 1);
+ 
+  out:
+ 	spin_unlock(&ubd_lock);
+-	return(n);
++	return(len);
+ }
+ 
+ static int ubd_remove(char *str)
+@@ -604,11 +650,9 @@
+ 	struct ubd *dev;
+ 	int n, err = -ENODEV;
+ 
+-	if(!isdigit(*str))
+-		return(err);	/* it should be a number 0-7/a-h */
++	n = parse_unit(&str);
+ 
+-	n = *str - '0';
+-	if(n >= MAX_DEV) 
++	if((n < 0) || (n >= MAX_DEV))
+ 		return(err);
+ 
+ 	dev = &ubd_dev[n];
+@@ -669,7 +713,7 @@
+ 		
+ 	elevator_init(ubd_queue, &elevator_noop);
+ 
+-	if (fake_major != 0) {
++	if (fake_major != MAJOR_NR) {
+ 		char name[sizeof("ubd_nnn\0")];
+ 
+ 		snprintf(name, sizeof(name), "ubd_%d", fake_major);
+@@ -714,15 +758,9 @@
+ {
+ 	struct gendisk *disk = inode->i_bdev->bd_disk;
+ 	struct ubd *dev = disk->private_data;
+-	int err = -EISDIR;
+-
+-	if(dev->is_dir == 1)
+-		goto out;
++	int err = 0;
+ 
+-	err = 0;
+ 	if(dev->count == 0){
+-		dev->openflags = dev->boot_openflags;
+-
+ 		err = ubd_open_dev(dev);
+ 		if(err){
+ 			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
+@@ -796,15 +834,6 @@
+ 
+ 	if(req->rq_status == RQ_INACTIVE) return(1);
+ 
+-	if(dev->is_dir){
+-		strcpy(req->buffer, "HOSTFS:");
+-		strcat(req->buffer, dev->file);
+- 		spin_lock(&ubd_io_lock);
+-		end_request(req, 1);
+- 		spin_unlock(&ubd_io_lock);
+-		return(1);
+-	}
+-
+ 	if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+ 		printk("Write attempted on readonly ubd device %s\n", 
+ 		       disk->disk_name);
+diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
+--- a/arch/um/drivers/ubd_user.c	Tue Sep  9 16:41:52 2003
++++ b/arch/um/drivers/ubd_user.c	Tue Sep  9 16:47:57 2003
+@@ -24,142 +24,24 @@
+ #include "user.h"
+ #include "ubd_user.h"
+ #include "os.h"
++#include "cow.h"
+ 
+ #include <endian.h>
+ #include <byteswap.h>
+-#if __BYTE_ORDER == __BIG_ENDIAN
+-# define ntohll(x) (x)
+-# define htonll(x) (x)
+-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+-# define ntohll(x)  bswap_64(x)
+-# define htonll(x)  bswap_64(x)
+-#else
+-#error "__BYTE_ORDER not defined"
+-#endif
+-
+-#define PATH_LEN_V1 256
+-
+-struct cow_header_v1 {
+-	int magic;
+-	int version;
+-	char backing_file[PATH_LEN_V1];
+-	time_t mtime;
+-	__u64 size;
+-	int sectorsize;
+-};
+-
+-#define PATH_LEN_V2 MAXPATHLEN
+-
+-struct cow_header_v2 {
+-	unsigned long magic;
+-	unsigned long version;
+-	char backing_file[PATH_LEN_V2];
+-	time_t mtime;
+-	__u64 size;
+-	int sectorsize;
+-};
+-
+-union cow_header {
+-	struct cow_header_v1 v1;
+-	struct cow_header_v2 v2;
+-};
+-
+-#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
+-#define COW_VERSION 2
+-
+-static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
+-		  unsigned long *bitmap_len_out, int *data_offset_out)
+-{
+-	*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
+-
+-	*data_offset_out = bitmap_offset + *bitmap_len_out;
+-	*data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
+-	*data_offset_out *= sectorsize;
+-}
+-
+-static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
+-			   time_t *mtime_out, __u64 *size_out, 
+-			   int *sectorsize_out, int *bitmap_offset_out)
+-{
+-	union cow_header *header;
+-	char *file;
+-	int err, n;
+-	unsigned long version, magic;
+-
+-	header = um_kmalloc(sizeof(*header));
+-	if(header == NULL){
+-		printk("read_cow_header - Failed to allocate header\n");
+-		return(-ENOMEM);
+-	}
+-	err = -EINVAL;
+-	n = read(fd, header, sizeof(*header));
+-	if(n < offsetof(typeof(header->v1), backing_file)){
+-		printk("read_cow_header - short header\n");
+-		goto out;
+-	}
+-
+-	magic = header->v1.magic;
+-	if(magic == COW_MAGIC) {
+-		version = header->v1.version;
+-	}
+-	else if(magic == ntohl(COW_MAGIC)){
+-		version = ntohl(header->v1.version);
+-	}
+-	else goto out;
+-
+-	*magic_out = COW_MAGIC;
+-
+-	if(version == 1){
+-		if(n < sizeof(header->v1)){
+-			printk("read_cow_header - failed to read V1 header\n");
+-			goto out;
+-		}
+-		*mtime_out = header->v1.mtime;
+-		*size_out = header->v1.size;
+-		*sectorsize_out = header->v1.sectorsize;
+-		*bitmap_offset_out = sizeof(header->v1);
+-		file = header->v1.backing_file;
+-	}
+-	else if(version == 2){
+-		if(n < sizeof(header->v2)){
+-			printk("read_cow_header - failed to read V2 header\n");
+-			goto out;
+-		}
+-		*mtime_out = ntohl(header->v2.mtime);
+-		*size_out = ntohll(header->v2.size);
+-		*sectorsize_out = ntohl(header->v2.sectorsize);
+-		*bitmap_offset_out = sizeof(header->v2);
+-		file = header->v2.backing_file;
+-	}
+-	else {
+-		printk("read_cow_header - invalid COW version\n");
+-		goto out;
+-	}
+-	err = -ENOMEM;
+-	*backing_file_out = uml_strdup(file);
+-	if(*backing_file_out == NULL){
+-		printk("read_cow_header - failed to allocate backing file\n");
+-		goto out;
+-	}
+-	err = 0;
+- out:
+-	kfree(header);
+-	return(err);
+-}
+ 
+ static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+ {
+-	struct stat buf1, buf2;
++	struct stat64 buf1, buf2;
+ 
+ 	if(from_cmdline == NULL) return(1);
+ 	if(!strcmp(from_cmdline, from_cow)) return(1);
+ 
+-	if(stat(from_cmdline, &buf1) < 0){
++	if(stat64(from_cmdline, &buf1) < 0){
+ 		printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
+ 		       errno);
+ 		return(1);
+ 	}
+-	if(stat(from_cow, &buf2) < 0){
++	if(stat64(from_cow, &buf2) < 0){
+ 		printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
+ 		return(1);
+ 	}
+@@ -215,118 +97,6 @@
+ 	return(0);
+ }
+ 
+-static int absolutize(char *to, int size, char *from)
+-{
+-	char save_cwd[256], *slash;
+-	int remaining;
+-
+-	if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+-		printk("absolutize : unable to get cwd - errno = %d\n", errno);
+-		return(-1);
+-	}
+-	slash = strrchr(from, '/');
+-	if(slash != NULL){
+-		*slash = '\0';
+-		if(chdir(from)){
+-			*slash = '/';
+-			printk("absolutize : Can't cd to '%s' - errno = %d\n",
+-			       from, errno);
+-			return(-1);
+-		}
+-		*slash = '/';
+-		if(getcwd(to, size) == NULL){
+-			printk("absolutize : unable to get cwd of '%s' - "
+-			       "errno = %d\n", from, errno);
+-			return(-1);
+-		}
+-		remaining = size - strlen(to);
+-		if(strlen(slash) + 1 > remaining){
+-			printk("absolutize : unable to fit '%s' into %d "
+-			       "chars\n", from, size);
+-			return(-1);
+-		}
+-		strcat(to, slash);
+-	}
+-	else {
+-		if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+-			printk("absolutize : unable to fit '%s' into %d "
+-			       "chars\n", from, size);
+-			return(-1);
+-		}
+-		strcpy(to, save_cwd);
+-		strcat(to, "/");
+-		strcat(to, from);
+-	}
+-	chdir(save_cwd);
+-	return(0);
+-}
+-
+-static int write_cow_header(char *cow_file, int fd, char *backing_file, 
+-			    int sectorsize, long long *size)
+-{
+-        struct cow_header_v2 *header;
+-	struct stat64 buf;
+-	int err;
+-
+-	err = os_seek_file(fd, 0);
+-	if(err != 0){
+-		printk("write_cow_header - lseek failed, errno = %d\n", errno);
+-		return(-errno);
+-	}
+-
+-	err = -ENOMEM;
+-	header = um_kmalloc(sizeof(*header));
+-	if(header == NULL){
+-		printk("Failed to allocate COW V2 header\n");
+-		goto out;
+-	}
+-	header->magic = htonl(COW_MAGIC);
+-	header->version = htonl(COW_VERSION);
+-
+-	err = -EINVAL;
+-	if(strlen(backing_file) > sizeof(header->backing_file) - 1){
+-		printk("Backing file name \"%s\" is too long - names are "
+-		       "limited to %d characters\n", backing_file, 
+-		       sizeof(header->backing_file) - 1);
+-		goto out_free;
+-	}
+-
+-	if(absolutize(header->backing_file, sizeof(header->backing_file), 
+-		      backing_file))
+-		goto out_free;
+-
+-	err = stat64(header->backing_file, &buf);
+-	if(err < 0){
+-		printk("Stat of backing file '%s' failed, errno = %d\n",
+-		       header->backing_file, errno);
+-		err = -errno;
+-		goto out_free;
+-	}
+-
+-	err = os_file_size(header->backing_file, size);
+-	if(err){
+-		printk("Couldn't get size of backing file '%s', errno = %d\n",
+-		       header->backing_file, -*size);
+-		goto out_free;
+-	}
+-
+-	header->mtime = htonl(buf.st_mtime);
+-	header->size = htonll(*size);
+-	header->sectorsize = htonl(sectorsize);
+-
+-	err = write(fd, header, sizeof(*header));
+-	if(err != sizeof(*header)){
+-		printk("Write of header to new COW file '%s' failed, "
+-		       "errno = %d\n", cow_file, errno);
+-		goto out_free;
+-	}
+-	err = 0;
+- out_free:
+-	kfree(header);
+- out:
+-	return(err);
+-}
+-
+ int open_ubd_file(char *file, struct openflags *openflags, 
+ 		  char **backing_file_out, int *bitmap_offset_out, 
+ 		  unsigned long *bitmap_len_out, int *data_offset_out, 
+@@ -346,10 +116,17 @@
+                 if((fd = os_open_file(file, *openflags, mode)) < 0) 
+ 			return(fd);
+         }
++
++	err = os_lock_file(fd, openflags->w);
++	if(err){
++		printk("Failed to lock '%s', errno = %d\n", file, -err);
++		goto error;
++	}
++	
+ 	if(backing_file_out == NULL) return(fd);
+ 
+-	err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
+-			      &sectorsize, bitmap_offset_out);
++	err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime, 
++			      &size, &sectorsize, bitmap_offset_out);
+ 	if(err && (*backing_file_out != NULL)){
+ 		printk("Failed to read COW header from COW file \"%s\", "
+ 		       "errno = %d\n", file, err);
+@@ -376,12 +153,12 @@
+ 		if(err) goto error;
+ 	}
+ 
+-	sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
+-	      data_offset_out);
++	cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
++		  data_offset_out);
+ 
+         return(fd);
+  error:
+-	close(fd);
++	os_close_file(fd);
+ 	return(err);
+ }
+ 
+@@ -389,10 +166,7 @@
+ 		    int sectorsize, int *bitmap_offset_out, 
+ 		    unsigned long *bitmap_len_out, int *data_offset_out)
+ {
+-	__u64 blocks;
+-	long zero;
+-	int err, fd, i;
+-	long long size;
++	int err, fd;
+ 
+ 	flags.c = 1;
+ 	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+@@ -403,29 +177,12 @@
+ 		goto out;
+ 	}
+ 
+-	err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
+-	if(err) goto out_close;
+-
+-	blocks = (size + sectorsize - 1) / sectorsize;
+-	blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
+-	zero = 0;
+-	for(i = 0; i < blocks; i++){
+-		err = write(fd, &zero, sizeof(zero));
+-		if(err != sizeof(zero)){
+-			printk("Write of bitmap to new COW file '%s' failed, "
+-			       "errno = %d\n", cow_file, errno);
+-			goto out_close;
+-		}
+-	}
+-
+-	sizes(size, sectorsize, sizeof(struct cow_header_v2), 
+-	      bitmap_len_out, data_offset_out);
+-	*bitmap_offset_out = sizeof(struct cow_header_v2);
+-
+-	return(fd);
+-
+- out_close:
+-	close(fd);
++	err = init_cow_file(fd, cow_file, backing_file, sectorsize, 
++			    bitmap_offset_out, bitmap_len_out, 
++			    data_offset_out);
++	if(!err)
++		return(fd);
++	os_close_file(fd);
+  out:
+ 	return(err);
+ }
+@@ -448,14 +205,6 @@
+ 	else return(n);
+ }
+ 
+-int ubd_is_dir(char *file)
+-{
+-	struct stat64 buf;
+-
+-	if(stat64(file, &buf) < 0) return(0);
+-	return(S_ISDIR(buf.st_mode));
+-}
+-
+ void do_io(struct io_thread_req *req)
+ {
+ 	char *buf;
+diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
+--- a/arch/um/drivers/xterm.c	Tue Sep  9 16:41:17 2003
++++ b/arch/um/drivers/xterm.c	Tue Sep  9 16:47:27 2003
+@@ -108,7 +108,7 @@
+ 	}
+ 	close(fd);
+ 
+-	fd = create_unix_socket(file, sizeof(file));
++	fd = create_unix_socket(file, sizeof(file), 1);
+ 	if(fd < 0){
+ 		printk("xterm_open : create_unix_socket failed, errno = %d\n", 
+ 		       -fd);
+diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
+--- a/arch/um/drivers/xterm_kern.c	Tue Sep  9 16:45:16 2003
++++ b/arch/um/drivers/xterm_kern.c	Tue Sep  9 16:50:00 2003
+@@ -5,9 +5,12 @@
+ 
+ #include "linux/errno.h"
+ #include "linux/slab.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "asm/irq.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ #include "kern_util.h"
+ #include "os.h"
+ #include "xterm.h"
+@@ -19,17 +22,18 @@
+ 	int new_fd;
+ };
+ 
+-static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
++static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
+ {
+ 	struct xterm_wait *xterm = data;
+ 	int fd;
+ 
+ 	fd = os_rcv_fd(xterm->fd, &xterm->pid);
+ 	if(fd == -EAGAIN)
+-		return;
++		return(IRQ_NONE);
+ 
+ 	xterm->new_fd = fd;
+ 	up(&xterm->sem);
++	return(IRQ_HANDLED);
+ }
+ 
+ int xterm_fd(int socket, int *pid_out)
+diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
+--- a/arch/um/dyn.lds.S	Tue Sep  9 16:43:23 2003
++++ b/arch/um/dyn.lds.S	Tue Sep  9 16:49:04 2003
+@@ -15,7 +15,11 @@
+   . = ALIGN(4096);		/* Init code and data */
+   _stext = .;
+   __init_begin = .;
+-  .text.init : { *(.text.init) }
++  .init.text : { 
++	_sinittext = .;
++	*(.init.text)
++	_einittext = .;
++  }
+ 
+   . = ALIGN(4096);
+ 
+@@ -67,7 +71,7 @@
+ 
+   #include "asm/common.lds.S"
+ 
+-  .data.init : { *(.data.init) }
++  init.data : { *(.init.data) }
+ 
+   /* Ensure the __preinit_array_start label is properly aligned.  We
+      could instead move the label definition inside the section, but
+diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
+--- a/arch/um/include/irq_kern.h	Wed Dec 31 19:00:00 1969
++++ b/arch/um/include/irq_kern.h	Tue Sep  9 16:48:56 2003
+@@ -0,0 +1,28 @@
++/* 
++ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#ifndef __IRQ_KERN_H__
++#define __IRQ_KERN_H__
++
++#include "linux/interrupt.h"
++
++extern int um_request_irq(unsigned int irq, int fd, int type,
++			  irqreturn_t (*handler)(int, void *, 
++						 struct pt_regs *),
++			  unsigned long irqflags,  const char * devname,
++			  void *dev_id);
++
++#endif
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
+--- a/arch/um/include/kern_util.h	Tue Sep  9 16:42:24 2003
++++ b/arch/um/include/kern_util.h	Tue Sep  9 16:48:18 2003
+@@ -63,10 +63,9 @@
+ extern void *syscall_sp(void *t);
+ extern void syscall_trace(void);
+ extern int hz(void);
+-extern void idle_timer(void);
++extern void uml_idle_timer(void);
+ extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
+ extern int external_pid(void *t);
+-extern int pid_to_processor_id(int pid);
+ extern void boot_timer_handler(int sig);
+ extern void interrupt_end(void);
+ extern void initial_thread_cb(void (*proc)(void *), void *arg);
+@@ -90,9 +89,7 @@
+ extern char *uml_strdup(char *string);
+ extern void unprotect_kernel_mem(void);
+ extern void protect_kernel_mem(void);
+-extern void set_kmem_end(unsigned long);
+ extern void uml_cleanup(void);
+-extern int pid_to_processor_id(int pid);
+ extern void set_current(void *t);
+ extern void lock_signalled_task(void *t);
+ extern void IPI_handler(int cpu);
+@@ -101,7 +98,9 @@
+ extern int clear_user_proc(void *buf, int size);
+ extern int copy_to_user_proc(void *to, void *from, int size);
+ extern int copy_from_user_proc(void *to, void *from, int size);
++extern int strlen_user_proc(char *str);
+ extern void bus_handler(int sig, union uml_pt_regs *regs);
++extern void winch(int sig, union uml_pt_regs *regs);
+ extern long execute_syscall(void *r);
+ extern int smp_sigio_handler(void);
+ extern void *get_current(void);
+diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
+--- a/arch/um/include/line.h	Tue Sep  9 16:45:29 2003
++++ b/arch/um/include/line.h	Tue Sep  9 16:50:05 2003
+@@ -9,12 +9,14 @@
+ #include "linux/list.h"
+ #include "linux/workqueue.h"
+ #include "linux/tty.h"
++#include "linux/interrupt.h"
+ #include "asm/semaphore.h"
+ #include "chan_user.h"
+ #include "mconsole_kern.h"
+ 
+ struct line_driver {
+ 	char *name;
++	char *device_name;
+ 	char *devfs_name;
+ 	short major;
+ 	short minor_start;
+@@ -67,8 +69,9 @@
+ 
+ #define LINES_INIT(n) {  num :		n }
+ 
+-extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
+-extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused);
++extern irqreturn_t line_write_interrupt(int irq, void *data, 
++					struct pt_regs *unused);
+ extern void line_close(struct line *lines, struct tty_struct *tty);
+ extern int line_open(struct line *lines, struct tty_struct *tty, 
+ 		     struct chan_opts *opts);
+diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
+--- a/arch/um/include/mconsole.h	Tue Sep  9 16:42:56 2003
++++ b/arch/um/include/mconsole.h	Tue Sep  9 16:48:27 2003
+@@ -77,6 +77,7 @@
+ extern void mconsole_cad(struct mc_request *req);
+ extern void mconsole_stop(struct mc_request *req);
+ extern void mconsole_go(struct mc_request *req);
++extern void mconsole_log(struct mc_request *req);
+ 
+ extern int mconsole_get_request(int fd, struct mc_request *req);
+ extern int mconsole_notify(char *sock_name, int type, const void *data, 
+diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
+--- a/arch/um/include/mem.h	Tue Sep  9 16:46:13 2003
++++ b/arch/um/include/mem.h	Tue Sep  9 16:51:14 2003
+@@ -13,7 +13,6 @@
+ };
+ 
+ extern void set_usable_vm(unsigned long start, unsigned long end);
+-extern void set_kmem_end(unsigned long new);
+ 
+ #endif
+ 
+diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
+--- a/arch/um/include/mem_user.h	Tue Sep  9 16:43:56 2003
++++ b/arch/um/include/mem_user.h	Tue Sep  9 16:49:29 2003
+@@ -51,9 +51,6 @@
+ 
+ extern int init_mem_user(void);
+ extern int create_mem_file(unsigned long len);
+-extern void setup_range(int fd, char *driver, unsigned long start,
+-			unsigned long pfn, unsigned long total, int need_vm, 
+-			struct mem_region *region, void *reserved);
+ extern void setup_memory(void *entry);
+ extern unsigned long find_iomem(char *driver, unsigned long *len_out);
+ extern int init_maps(struct mem_region *region);
+diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
+--- a/arch/um/include/os.h	Tue Sep  9 16:41:47 2003
++++ b/arch/um/include/os.h	Tue Sep  9 16:47:55 2003
+@@ -103,10 +103,11 @@
+ extern int os_shutdown_socket(int fd, int r, int w);
+ extern void os_close_file(int fd);
+ extern int os_rcv_fd(int fd, int *helper_pid_out);
+-extern int create_unix_socket(char *file, int len);
++extern int create_unix_socket(char *file, int len, int close_on_exec);
+ extern int os_connect_socket(char *name);
+ extern int os_file_type(char *file);
+ extern int os_file_mode(char *file, struct openflags *mode_out);
++extern int os_lock_file(int fd, int excl);
+ 
+ extern unsigned long os_process_pc(int pid);
+ extern int os_process_parent(int pid);
+@@ -120,6 +121,7 @@
+ extern int os_protect_memory(void *addr, unsigned long len, 
+ 			     int r, int w, int x);
+ extern int os_unmap_memory(void *addr, int len);
++extern void os_flush_stdout(void);
+ 
+ #endif
+ 
+diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
+--- a/arch/um/include/sysdep-i386/sigcontext.h	Tue Sep  9 16:45:13 2003
++++ b/arch/um/include/sysdep-i386/sigcontext.h	Tue Sep  9 16:49:58 2003
+@@ -28,8 +28,8 @@
+  */
+ #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
+ 
+-/* These are General Protection and Page Fault */
+-#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
++/* This is Page Fault */
++#define SEGV_IS_FIXABLE(trap) (trap == 14)
+ 
+ #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
+ 
+diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
+--- a/arch/um/include/ubd_user.h	Tue Sep  9 16:43:28 2003
++++ b/arch/um/include/ubd_user.h	Tue Sep  9 16:49:08 2003
+@@ -39,7 +39,6 @@
+ extern int write_ubd_fs(int fd, char *buffer, int len);
+ extern int start_io_thread(unsigned long sp, int *fds_out);
+ extern void do_io(struct io_thread_req *req);
+-extern int ubd_is_dir(char *file);
+ 
+ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
+ {
+diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
+--- a/arch/um/include/user.h	Tue Sep  9 16:41:16 2003
++++ b/arch/um/include/user.h	Tue Sep  9 16:47:26 2003
+@@ -14,7 +14,7 @@
+ extern void kfree(void *ptr);
+ extern int in_aton(char *str);
+ extern int open_gdb_chan(void);
+-
++extern int strlcpy(char *, const char *, int);
+ #endif
+ 
+ /*
+diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
+--- a/arch/um/include/user_util.h	Tue Sep  9 16:41:34 2003
++++ b/arch/um/include/user_util.h	Tue Sep  9 16:47:39 2003
+@@ -59,7 +59,6 @@
+ extern void *add_signal_handler(int sig, void (*handler)(int));
+ extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
+ 			    int clone_flags, int (*tramp)(void *));
+-extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
+ extern int linux_main(int argc, char **argv);
+ extern void set_cmdline(char *cmd);
+ extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
+@@ -90,7 +89,8 @@
+ extern int arch_fixup(unsigned long address, void *sc_ptr);
+ extern void forward_pending_sigio(int target);
+ extern int can_do_skas(void);
+- 
++extern void arch_init_thread(void);
++
+ #endif
+ 
+ /*
+diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
+--- a/arch/um/kernel/Makefile	Tue Sep  9 16:44:02 2003
++++ b/arch/um/kernel/Makefile	Tue Sep  9 16:49:30 2003
+@@ -21,6 +21,8 @@
+ obj-$(CONFIG_MODE_TT) += tt/
+ obj-$(CONFIG_MODE_SKAS) += skas/
+ 
++clean-files	:= config.c
++
+ user-objs-$(CONFIG_TTY_LOG) += tty_log.o
+ 
+ USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
+@@ -45,17 +47,13 @@
+ $(obj)/frame.o: $(src)/frame.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
+ 
+-QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
++QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
+ 
+ $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
+ 	$(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
+ 
+ $(obj)/config.o : $(obj)/config.c
+ 
+-clean:
+-	rm -f config.c
+-	for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
+-
+ modules:
+ 
+ fastdep:
+diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
+--- a/arch/um/kernel/config.c.in	Tue Sep  9 16:45:16 2003
++++ b/arch/um/kernel/config.c.in	Tue Sep  9 16:50:00 2003
+@@ -7,9 +7,7 @@
+ #include <stdlib.h>
+ #include "init.h"
+ 
+-static __initdata char *config = "
+-CONFIG
+-";
++static __initdata char *config = "CONFIG";
+ 
+ static int __init print_config(char *line, int *add)
+ {
+diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
+--- a/arch/um/kernel/exec_kern.c	Tue Sep  9 16:41:55 2003
++++ b/arch/um/kernel/exec_kern.c	Tue Sep  9 16:48:00 2003
+@@ -32,10 +32,15 @@
+ 	CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
+ }
+ 
++extern void log_exec(char **argv, void *tty);
++
+ static int execve1(char *file, char **argv, char **env)
+ {
+         int error;
+ 
++#ifdef CONFIG_TTY_LOG
++	log_exec(argv, current->tty);
++#endif
+         error = do_execve(file, argv, env, &current->thread.regs);
+         if (error == 0){
+                 current->ptrace &= ~PT_DTRACE;
+diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
+--- a/arch/um/kernel/init_task.c	Tue Sep  9 16:46:17 2003
++++ b/arch/um/kernel/init_task.c	Tue Sep  9 16:51:23 2003
+@@ -17,6 +17,7 @@
+ struct mm_struct init_mm = INIT_MM(init_mm);
+ static struct files_struct init_files = INIT_FILES;
+ static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+ 
+ /*
+  * Initial task structure.
+@@ -38,26 +39,12 @@
+ __attribute__((__section__(".data.init_task"))) = 
+ { INIT_THREAD_INFO(init_task) };
+ 
+-struct task_struct *alloc_task_struct(void)
+-{
+-	return((struct task_struct *) 
+-	       __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
+-}
+-
+ void unprotect_stack(unsigned long stack)
+ {
+ 	protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
+ 		       1, 1, 0, 1);
+ }
+ 
+-void free_task_struct(struct task_struct *task)
+-{
+-	/* free_pages decrements the page counter and only actually frees
+-	 * the pages if they are now not accessed by anything.
+-	 */
+-	free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
+-}
+-
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
+--- a/arch/um/kernel/irq.c	Tue Sep  9 16:45:47 2003
++++ b/arch/um/kernel/irq.c	Tue Sep  9 16:50:14 2003
+@@ -28,6 +28,7 @@
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ static void register_irq_proc (unsigned int irq);
+ 
+@@ -82,65 +83,52 @@
+ 	end_none
+ };
+ 
+-/* Not changed */
+-volatile unsigned long irq_err_count;
+-
+ /*
+  * Generic, controller-independent functions:
+  */
+ 
+-int get_irq_list(char *buf)
++int show_interrupts(struct seq_file *p, void *v)
+ {
+ 	int i, j;
+-	unsigned long flags;
+ 	struct irqaction * action;
+-	char *p = buf;
++	unsigned long flags;
+ 
+-	p += sprintf(p, "           ");
+-	for (j=0; j<num_online_cpus(); j++)
+-		p += sprintf(p, "CPU%d       ",j);
+-	*p++ = '\n';
++	seq_printf(p, "           ");
++	for (j=0; j<NR_CPUS; j++)
++		if (cpu_online(j))
++			seq_printf(p, "CPU%d       ",j);
++	seq_putc(p, '\n');
+ 
+ 	for (i = 0 ; i < NR_IRQS ; i++) {
+ 		spin_lock_irqsave(&irq_desc[i].lock, flags);
+ 		action = irq_desc[i].action;
+ 		if (!action) 
+-			goto end;
+-		p += sprintf(p, "%3d: ",i);
++			goto skip;
++		seq_printf(p, "%3d: ",i);
+ #ifndef CONFIG_SMP
+-		p += sprintf(p, "%10u ", kstat_irqs(i));
++		seq_printf(p, "%10u ", kstat_irqs(i));
+ #else
+-		for (j = 0; j < num_online_cpus(); j++)
+-			p += sprintf(p, "%10u ",
+-				kstat_cpu(cpu_logical_map(j)).irqs[i]);
++		for (j = 0; j < NR_CPUS; j++)
++			if (cpu_online(j))
++				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ #endif
+-		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+-		p += sprintf(p, "  %s", action->name);
++		seq_printf(p, " %14s", irq_desc[i].handler->typename);
++		seq_printf(p, "  %s", action->name);
+ 
+ 		for (action=action->next; action; action = action->next)
+-			p += sprintf(p, ", %s", action->name);
+-		*p++ = '\n';
+-	end:
++			seq_printf(p, ", %s", action->name);
++
++		seq_putc(p, '\n');
++skip:
+ 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ 	}
+-	p += sprintf(p, "\n");
+-#ifdef notdef
+-#ifdef CONFIG_SMP
+-	p += sprintf(p, "LOC: ");
+-	for (j = 0; j < num_online_cpus(); j++)
+-		p += sprintf(p, "%10u ",
+-			apic_timer_irqs[cpu_logical_map(j)]);
+-	p += sprintf(p, "\n");
+-#endif
+-#endif
+-	p += sprintf(p, "ERR: %10lu\n", irq_err_count);
+-	return p - buf;
+-}
++	seq_printf(p, "NMI: ");
++	for (j = 0; j < NR_CPUS; j++)
++		if (cpu_online(j))
++			seq_printf(p, "%10u ", nmi_count(j));
++	seq_putc(p, '\n');
+ 
+-
+-int show_interrupts(struct seq_file *p, void *v)
+-{
+-	return(0);
++	return 0;
+ }
+ 
+ /*
+@@ -281,13 +269,12 @@
+ 	 * 0 return value means that this irq is already being
+ 	 * handled by some other CPU. (or is disabled)
+ 	 */
+-	int cpu = smp_processor_id();
+ 	irq_desc_t *desc = irq_desc + irq;
+ 	struct irqaction * action;
+ 	unsigned int status;
+ 
+ 	irq_enter();
+-	kstat_cpu(cpu).irqs[irq]++;
++	kstat_this_cpu.irqs[irq]++;
+ 	spin_lock(&desc->lock);
+ 	desc->handler->ack(irq);
+ 	/*
+@@ -384,7 +371,7 @@
+  */
+  
+ int request_irq(unsigned int irq,
+-		void (*handler)(int, void *, struct pt_regs *),
++		irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ 		unsigned long irqflags, 
+ 		const char * devname,
+ 		void *dev_id)
+@@ -430,15 +417,19 @@
+ }
+ 
+ int um_request_irq(unsigned int irq, int fd, int type,
+-		   void (*handler)(int, void *, struct pt_regs *),
++		   irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ 		   unsigned long irqflags, const char * devname,
+ 		   void *dev_id)
+ {
+-	int retval;
++	int err;
+ 
+-	retval = request_irq(irq, handler, irqflags, devname, dev_id);
+-	if(retval) return(retval);
+-	return(activate_fd(irq, fd, type, dev_id));
++	err = request_irq(irq, handler, irqflags, devname, dev_id);
++	if(err) 
++		return(err);
++
++	if(fd != -1)
++		err = activate_fd(irq, fd, type, dev_id);
++	return(err);
+ }
+ 
+ /* this was setup_x86_irq but it seems pretty generic */
+@@ -654,7 +645,7 @@
+ 		return -EINVAL;
+ 	tmp = *mask;
+ 	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-		int j = sprintf(page, "%04hx", cpus_coerce(tmp));
++		int j = sprintf(page, "%04hx", (short) cpus_coerce(tmp));
+ 		len += j;
+ 		page += j;
+ 		cpus_shift_right(tmp, tmp, 16);
+diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
+--- a/arch/um/kernel/mem.c	Tue Sep  9 16:42:54 2003
++++ b/arch/um/kernel/mem.c	Tue Sep  9 16:48:27 2003
+@@ -119,11 +119,6 @@
+ 	return(kmem_top);
+ }
+ 
+-void set_kmem_end(unsigned long new)
+-{
+-	kmem_top = new;
+-}
+-
+ #ifdef CONFIG_HIGHMEM
+ /* Changed during early boot */
+ pte_t *kmap_pte;
+@@ -218,7 +213,7 @@
+ 		if(regions[i] == NULL) break;		
+ 	}
+ 	if(i == NREGIONS){
+-		printk("setup_range : no free regions\n");
++		printk("setup_one_range : no free regions\n");
+ 		i = -1;
+ 		goto out;
+ 	}
+@@ -227,7 +222,9 @@
+ 		fd = create_mem_file(len);
+ 
+ 	if(region == NULL){
+-		region = alloc_bootmem_low_pages(sizeof(*region));
++		if(kmalloc_ok)
++			region = kmalloc(sizeof(*region), GFP_KERNEL);
++		else region = alloc_bootmem_low_pages(sizeof(*region));
+ 		if(region == NULL)
+ 			panic("Failed to allocating mem_region");
+ 	}
+@@ -528,9 +525,9 @@
+ 	return(NREGIONS);
+ }
+ 
+-void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
+-		 unsigned long len, int need_vm, struct mem_region *region, 
+-		 void *reserved)
++static void setup_range(int fd, char *driver, unsigned long start, 
++			unsigned long pfn, unsigned long len, int need_vm, 
++			struct mem_region *region, void *reserved)
+ {
+ 	int i, cur;
+ 
+diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
+--- a/arch/um/kernel/mem_user.c	Tue Sep  9 16:43:27 2003
++++ b/arch/um/kernel/mem_user.c	Tue Sep  9 16:49:07 2003
+@@ -111,6 +111,11 @@
+ 		offset = 0;
+ 	}
+ 
++	if(offset >= region->len){
++		printf("%ld bytes of physical memory is insufficient\n",
++		       region->len);
++		exit(1);
++	}
+ 	loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
+ 		   MAP_SHARED | MAP_FIXED, region->fd, offset);
+ 	if(loc != start){
+@@ -122,26 +127,26 @@
+ 
+ static int __init parse_iomem(char *str, int *add)
+ {
+-	struct stat buf;
++	struct stat64 buf;
+ 	char *file, *driver;
+ 	int fd;
+ 
+ 	driver = str;
+ 	file = strchr(str,',');
+ 	if(file == NULL){
+-		printk("parse_iomem : failed to parse iomem\n");
++		printf("parse_iomem : failed to parse iomem\n");
+ 		return(1);
+ 	}
+ 	*file = '\0';
+ 	file++;
+ 	fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
+ 	if(fd < 0){
+-		printk("parse_iomem - Couldn't open io file, errno = %d\n", 
++		printf("parse_iomem - Couldn't open io file, errno = %d\n", 
+ 		       errno);
+ 		return(1);
+ 	}
+-	if(fstat(fd, &buf) < 0) {
+-		printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
++	if(fstat64(fd, &buf) < 0) {
++		printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
+ 		return(1);
+ 	}
+ 	add_iomem(driver, fd, buf.st_size);
+diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
+--- a/arch/um/kernel/process.c	Tue Sep  9 16:45:56 2003
++++ b/arch/um/kernel/process.c	Tue Sep  9 16:50:22 2003
+@@ -72,7 +72,6 @@
+ 		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ 	set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
+ 		    SA_NOMASK | flags, -1);
+-	(void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
+ 	signal(SIGHUP, SIG_IGN);
+ 
+ 	init_irq_signals(altstack);
+@@ -127,7 +126,8 @@
+ 	if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
+ 			  errno);
+ 	if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
+-		panic("outer trampoline didn't exit with SIGKILL");
++		panic("outer trampoline didn't exit with SIGKILL, "
++		      "status = %d", status);
+ 
+ 	return(arg.pid);
+ }
+diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
+--- a/arch/um/kernel/process_kern.c	Tue Sep  9 16:43:24 2003
++++ b/arch/um/kernel/process_kern.c	Tue Sep  9 16:49:06 2003
+@@ -52,17 +52,12 @@
+ 
+ struct task_struct *get_task(int pid, int require)
+ {
+-        struct task_struct *task, *ret;
++        struct task_struct *ret;
+ 
+-        ret = NULL;
+         read_lock(&tasklist_lock);
+-        for_each_process(task){
+-                if(task->pid == pid){
+-                        ret = task;
+-                        break;
+-                }
+-        }
++	ret = find_task_by_pid(pid);
+         read_unlock(&tasklist_lock);
++
+         if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
+         return(ret);
+ }
+@@ -103,13 +98,14 @@
+ 
+ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ {
+-	struct task_struct *p;
++	int pid;
+ 
+ 	current->thread.request.u.thread.proc = fn;
+ 	current->thread.request.u.thread.arg = arg;
+-	p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
+-	if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
+-	return(p->pid);
++	pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
++	if(pid < 0)
++		panic("do_fork failed in kernel_thread, errno = %d", pid);
++	return(pid);
+ }
+ 
+ void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
+@@ -129,7 +125,7 @@
+ 		{ external_pid(task), task });
+ }
+ 
+-void *switch_to(void *prev, void *next, void *last)
++void *_switch_to(void *prev, void *next, void *last)
+ {
+ 	return(CHOOSE_MODE(switch_to_tt(prev, next), 
+ 			   switch_to_skas(prev, next)));
+@@ -149,7 +145,7 @@
+ void exit_thread(void)
+ {
+ 	CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
+-	unprotect_stack((unsigned long) current->thread_info);
++	unprotect_stack((unsigned long) current_thread);
+ }
+  
+ void *get_current(void)
+@@ -157,6 +153,10 @@
+ 	return(current);
+ }
+ 
++void prepare_to_copy(struct task_struct *tsk)
++{
++}
++
+ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ 		unsigned long stack_top, struct task_struct * p, 
+ 		struct pt_regs *regs)
+@@ -190,7 +190,7 @@
+ 
+ void default_idle(void)
+ {
+-	idle_timer();
++	uml_idle_timer();
+ 
+ 	atomic_inc(&init_mm.mm_count);
+ 	current->mm = &init_mm;
+@@ -363,10 +363,15 @@
+ 	return(clear_user(buf, size));
+ }
+ 
++int strlen_user_proc(char *str)
++{
++	return(strlen_user(str));
++}
++
+ int smp_sigio_handler(void)
+ {
+ #ifdef CONFIG_SMP
+-	int cpu = current->thread_info->cpu;
++	int cpu = current_thread->cpu;
+ 	IPI_handler(cpu);
+ 	if(cpu != 0)
+ 		return(1);
+@@ -381,7 +386,7 @@
+ 
+ int cpu(void)
+ {
+-	return(current->thread_info->cpu);
++	return(current_thread->cpu);
+ }
+ 
+ /*
+diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
+--- a/arch/um/kernel/ptrace.c	Tue Sep  9 16:41:35 2003
++++ b/arch/um/kernel/ptrace.c	Tue Sep  9 16:47:40 2003
+@@ -311,11 +311,8 @@
+ 
+ 	/* the 0x80 provides a way for the tracing parent to distinguish
+ 	   between a syscall stop and SIGTRAP delivery */
+- 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+- 					? 0x80 : 0);
+-	current->state = TASK_STOPPED;
+-	notify_parent(current, SIGCHLD);
+-	schedule();
++	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
++				 ? 0x80 : 0));
+ 
+ 	/*
+ 	 * this isn't the same as continuing with a signal, but it will do
+diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
+--- a/arch/um/kernel/sigio_kern.c	Tue Sep  9 16:41:54 2003
++++ b/arch/um/kernel/sigio_kern.c	Tue Sep  9 16:47:58 2003
+@@ -6,18 +6,21 @@
+ #include "linux/kernel.h"
+ #include "linux/list.h"
+ #include "linux/slab.h"
+-#include "asm/irq.h"
++#include "linux/signal.h"
++#include "linux/interrupt.h"
+ #include "init.h"
+ #include "sigio.h"
+ #include "irq_user.h"
++#include "irq_kern.h"
+ 
+ /* Protected by sigio_lock() called from write_sigio_workaround */
+ static int sigio_irq_fd = -1;
+ 
+-void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
++irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+ {
+ 	read_sigio_fd(sigio_irq_fd);
+ 	reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
++	return(IRQ_HANDLED);
+ }
+ 
+ int write_sigio_irq(int fd)
+diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
+--- a/arch/um/kernel/signal_kern.c	Tue Sep  9 16:43:31 2003
++++ b/arch/um/kernel/signal_kern.c	Tue Sep  9 16:49:19 2003
+@@ -36,7 +36,7 @@
+ 	if(sig == SIGSEGV){
+ 		struct k_sigaction *ka;
+ 
+-		ka = &current->sig->action[SIGSEGV - 1];
++		ka = &current->sighand->action[SIGSEGV - 1];
+ 		ka->sa.sa_handler = SIG_DFL;
+ 	}
+ 	force_sig(SIGSEGV, current);
+@@ -142,7 +142,7 @@
+ 		return(0);
+ 
+ 	/* Whee!  Actually deliver the signal.  */
+-	ka = &current->sig->action[sig -1 ];
++	ka = &current->sighand->action[sig -1 ];
+ 	err = handle_signal(regs, sig, ka, &info, oldset, error);
+ 	if(!err) return(1);
+ 
+@@ -201,7 +201,7 @@
+ 	}
+ }
+ 
+-int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
++int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+ {
+ 	sigset_t saveset, newset;
+ 
+@@ -227,6 +227,42 @@
+ 	}
+ }
+ 
++int sys_sigaction(int sig, const struct old_sigaction __user *act,
++			 struct old_sigaction __user *oact)
++{
++	struct k_sigaction new_ka, old_ka;
++	int ret;
++
++	if (act) {
++		old_sigset_t mask;
++		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
++		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
++		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
++			return -EFAULT;
++		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
++		__get_user(mask, &act->sa_mask);
++		siginitset(&new_ka.sa.sa_mask, mask);
++	}
++
++	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++
++	if (!ret && oact) {
++		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
++		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
++		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
++			return -EFAULT;
++		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
++	}
++
++	return ret;
++}
++
++int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
++{
++	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
++}
++
+ static int copy_sc_from_user(struct pt_regs *to, void *from, 
+ 			     struct arch_frame_data *arch)
+ {
+@@ -239,8 +275,8 @@
+ 
+ int sys_sigreturn(struct pt_regs regs)
+ {
+-	void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
+-	void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
++	void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
++	void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
+ 	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
+ 
+ 	spin_lock_irq(&current->sighand->siglock);
+@@ -257,7 +293,8 @@
+ 
+ int sys_rt_sigreturn(struct pt_regs regs)
+ {
+-	struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
++	unsigned long sp = PT_REGS_SP(&current->thread.regs);
++	struct ucontext __user *uc = sp_to_uc(sp);
+ 	void *fp;
+ 	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
+ 
+diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
+--- a/arch/um/kernel/skas/Makefile	Tue Sep  9 16:42:00 2003
++++ b/arch/um/kernel/skas/Makefile	Tue Sep  9 16:48:10 2003
+@@ -7,18 +7,22 @@
+ 	process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
+ 	sys-$(SUBARCH)/
+ 
++host-progs	:= util/mk_ptregs
++clean-files	:= include/skas_ptregs.h
++
+ USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+ 
+-include/skas_ptregs.h : util/mk_ptregs
+-	util/mk_ptregs > $@
+-
+-util/mk_ptregs :
+-	$(MAKE) -C util
++$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
++	@echo -n '  Generating $@'
++	@$< > $@.tmp
++	@if [ -r $@ ] && cmp -s $@ $@.tmp; then \
++		echo ' (unchanged)'; \
++		rm -f $@.tmp; \
++	else \
++		echo ' (updated)'; \
++		mv -f $@.tmp $@; \
++	fi
+ 
+ $(USER_OBJS) : %.o: %.c
+ 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+-
+-clean :
+-	$(MAKE) -C util clean
+-	$(RM) -f include/skas_ptregs.h
+diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
+--- a/arch/um/kernel/skas/include/mode.h	Tue Sep  9 16:43:28 2003
++++ b/arch/um/kernel/skas/include/mode.h	Tue Sep  9 16:49:08 2003
+@@ -20,6 +20,7 @@
+ extern void halt_skas(void);
+ extern void reboot_skas(void);
+ extern void kill_off_processes_skas(void);
++extern int is_skas_winch(int pid, int fd, void *data);
+ 
+ #endif
+ 
+diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
+--- a/arch/um/kernel/skas/include/uaccess.h	Tue Sep  9 16:42:57 2003
++++ b/arch/um/kernel/skas/include/uaccess.h	Tue Sep  9 16:48:51 2003
+@@ -19,7 +19,7 @@
+ #define access_ok_skas(type, addr, size) \
+ 	((segment_eq(get_fs(), KERNEL_DS)) || \
+ 	 (((unsigned long) (addr) < TASK_SIZE) && \
+-	  ((unsigned long) (addr) + (size) < TASK_SIZE)))
++	  ((unsigned long) (addr) + (size) <= TASK_SIZE)))
+ 
+ static inline int verify_area_skas(int type, const void * addr, 
+ 				   unsigned long size)
+diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
+--- a/arch/um/kernel/skas/process.c	Tue Sep  9 16:46:01 2003
++++ b/arch/um/kernel/skas/process.c	Tue Sep  9 16:51:06 2003
+@@ -4,6 +4,7 @@
+  */
+ 
+ #include <stdlib.h>
++#include <unistd.h>
+ #include <errno.h>
+ #include <signal.h>
+ #include <setjmp.h>
+@@ -24,6 +25,16 @@
+ #include "os.h"
+ #include "proc_mm.h"
+ #include "skas_ptrace.h"
++#include "chan_user.h"
++
++int is_skas_winch(int pid, int fd, void *data)
++{
++	if(pid != getpid())
++		return(0);
++
++	register_winch_irq(-1, fd, -1, data);
++	return(1);
++}
+ 
+ unsigned long exec_regs[FRAME_SIZE];
+ unsigned long exec_fp_regs[HOST_FP_SIZE];
+@@ -48,11 +59,11 @@
+ 	int err, syscall_nr, status;
+ 
+ 	syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
++	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 	if(syscall_nr < 1){
+ 		relay_signal(SIGTRAP, regs);
+ 		return;
+ 	}
+-	UPT_SYSCALL_NR(regs) = syscall_nr;
+ 
+ 	err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
+ 	if(err < 0)
+@@ -72,8 +83,6 @@
+ 	handle_syscall(regs);
+ }
+ 
+-int userspace_pid;
+-
+ static int userspace_tramp(void *arg)
+ {
+ 	init_new_thread_signals(0);
+@@ -83,6 +92,8 @@
+ 	return(0);
+ }
+ 
++int userspace_pid;
++
+ void start_userspace(void)
+ {
+ 	void *stack;
+@@ -149,6 +160,7 @@
+ 			case SIGILL:
+ 			case SIGBUS:
+ 			case SIGFPE:
++			case SIGWINCH:
+ 				user_signal(WSTOPSIG(status), regs);
+ 				break;
+ 			default:
+@@ -328,7 +340,8 @@
+ int new_mm(int from)
+ {
+ 	struct proc_mm_op copy;
+-	int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
++	int n, fd = os_open_file("/proc/mm", 
++				 of_cloexec(of_write(OPENFLAGS())), 0);
+ 
+ 	if(fd < 0)
+ 		return(-errno);
+@@ -342,6 +355,7 @@
+ 			printk("new_mm : /proc/mm copy_segments failed, "
+ 			       "errno = %d\n", errno);
+ 	}
++
+ 	return(fd);
+ }
+ 
+diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
+--- a/arch/um/kernel/skas/process_kern.c	Tue Sep  9 16:41:52 2003
++++ b/arch/um/kernel/skas/process_kern.c	Tue Sep  9 16:47:57 2003
+@@ -61,9 +61,8 @@
+ 	thread_wait(&current->thread.mode.skas.switch_buf, 
+ 		    current->thread.mode.skas.fork_buf);
+ 
+-#ifdef CONFIG_SMP
+-	schedule_tail(NULL);
+-#endif
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
+ 	current->thread.prev_sched = NULL;
+ 
+ 	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
+@@ -93,9 +92,8 @@
+ 		    current->thread.mode.skas.fork_buf);
+   	
+ 	force_flush_all();
+-#ifdef CONFIG_SMP
+-	schedule_tail(current->thread.prev_sched);
+-#endif
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
+ 	current->thread.prev_sched = NULL;
+ 	unblock_signals();
+ 
+@@ -136,7 +134,7 @@
+ 
+ void init_idle_skas(void)
+ {
+-	cpu_tasks[current->thread_info->cpu].pid = os_getpid();
++	cpu_tasks[current_thread->cpu].pid = os_getpid();
+ 	default_idle();
+ }
+ 
+@@ -164,7 +162,7 @@
+ 	capture_signal_stack();
+ 
+ 	init_new_thread_signals(1);
+-	idle_timer();
++	uml_idle_timer();
+ 
+ 	init_task.thread.request.u.thread.proc = start_kernel_proc;
+ 	init_task.thread.request.u.thread.arg = NULL;
+diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
+--- a/arch/um/kernel/skas/util/mk_ptregs.c	Tue Sep  9 16:42:54 2003
++++ b/arch/um/kernel/skas/util/mk_ptregs.c	Tue Sep  9 16:48:27 2003
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+ 
+diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
+--- a/arch/um/kernel/smp.c	Tue Sep  9 16:41:48 2003
++++ b/arch/um/kernel/smp.c	Tue Sep  9 16:47:56 2003
+@@ -22,7 +22,7 @@
+ #include "os.h"
+ 
+ /* CPU online map, set by smp_boot_cpus */
+-unsigned long cpu_online_map = cpumask_of_cpu(0);
++unsigned long cpu_online_map = CPU_MASK_NONE;
+ 
+ /* Per CPU bogomips and other parameters
+  * The only piece used here is the ipi pipe, which is set before SMP is
+@@ -97,15 +97,15 @@
+ 
+ 	printk(KERN_INFO "Stopping all CPUs...");
+ 	for(i = 0; i < num_online_cpus(); i++){
+-		if(i == current->thread_info->cpu)
++		if(i == current_thread->cpu)
+ 			continue;
+ 		write(cpu_data[i].ipi_pipe[1], "S", 1);
+ 	}
+ 	printk("done\n");
+ }
+ 
+-static cpumask_t smp_commenced_mask;
+-static cpumask_t smp_callin_map = CPU_MASK_NONE;
++static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
++static cpumask_t cpu_callin_map = CPU_MASK_NONE;
+ 
+ static int idle_proc(void *cpup)
+ {
+@@ -120,12 +120,12 @@
+ 		     current->thread.mode.tt.extern_pid);
+  
+ 	wmb();
+-	if (cpu_test_and_set(cpu, &smp_callin_map)) {
++	if (cpu_test_and_set(cpu, cpu_callin_map)) {
+ 		printk("huh, CPU#%d already present??\n", cpu);
+ 		BUG();
+ 	}
+ 
+-	while (!cpu_isset(cpu, &smp_commenced_mask))
++	while (!cpu_isset(cpu, smp_commenced_mask))
+ 		cpu_relax();
+ 
+ 	cpu_set(cpu, cpu_online_map);
+@@ -140,8 +140,11 @@
+ 
+         current->thread.request.u.thread.proc = idle_proc;
+         current->thread.request.u.thread.arg = (void *) cpu;
+-	new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
+-	if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
++	new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
++				NULL);
++	if(IS_ERR(new_task)) 
++		panic("copy_process failed in idle_thread, error = %ld",
++		      PTR_ERR(new_task));
+ 
+ 	cpu_tasks[cpu] = ((struct cpu_task) 
+ 		          { .pid = 	new_task->thread.mode.tt.extern_pid,
+@@ -150,6 +153,7 @@
+ 	CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
+ 			  sizeof(c)),
+ 		    ({ panic("skas mode doesn't support SMP"); }));
++	wake_up_forked_process(new_task);
+ 	return(new_task);
+ }
+ 
+@@ -157,15 +161,16 @@
+ {
+ 	struct task_struct *idle;
+ 	unsigned long waittime;
+-	int err, cpu;
++	int err, cpu, me = smp_processor_id();
+ 
+-	cpu_set(0, cpu_online_map);
+-	cpu_set(0, smp_callin_map);
++	cpu_clear(me, cpu_online_map);
++	cpu_set(me, cpu_online_map);
++	cpu_set(me, cpu_callin_map);
+ 
+-	err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
++	err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
+ 	if(err)	panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
+ 
+-	activate_ipi(cpu_data[0].ipi_pipe[0], 
++	activate_ipi(cpu_data[me].ipi_pipe[0], 
+ 		     current->thread.mode.tt.extern_pid);
+ 
+ 	for(cpu = 1; cpu < ncpus; cpu++){
+@@ -177,10 +182,10 @@
+ 		unhash_process(idle);
+ 
+ 		waittime = 200000000;
+-		while (waittime-- && !cpu_isset(cpu, smp_callin_map))
++		while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
+ 			cpu_relax();
+ 
+-		if (cpu_isset(cpu, smp_callin_map))
++		if (cpu_isset(cpu, cpu_callin_map))
+ 			printk("done\n");
+ 		else printk("failed\n");
+ 	}
+@@ -270,7 +275,7 @@
+ 	info = _info;
+ 
+ 	for (i=0;i<NR_CPUS;i++)
+-		if((i != current->thread_info->cpu) && 
++		if((i != current_thread->cpu) && 
+ 		   cpu_isset(i, cpu_online_map))
+ 			write(cpu_data[i].ipi_pipe[1], "C", 1);
+ 
+diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
+--- a/arch/um/kernel/sys_call_table.c	Tue Sep  9 16:45:55 2003
++++ b/arch/um/kernel/sys_call_table.c	Tue Sep  9 16:50:22 2003
+@@ -219,15 +219,30 @@
+ extern syscall_handler_t sys_gettid;
+ extern syscall_handler_t sys_readahead;
+ extern syscall_handler_t sys_tkill;
++extern syscall_handler_t sys_setxattr;
++extern syscall_handler_t sys_lsetxattr;
++extern syscall_handler_t sys_fsetxattr;
++extern syscall_handler_t sys_getxattr;
++extern syscall_handler_t sys_lgetxattr;
++extern syscall_handler_t sys_fgetxattr;
++extern syscall_handler_t sys_listxattr;
++extern syscall_handler_t sys_llistxattr;
++extern syscall_handler_t sys_flistxattr;
++extern syscall_handler_t sys_removexattr;
++extern syscall_handler_t sys_lremovexattr;
++extern syscall_handler_t sys_fremovexattr;
+ extern syscall_handler_t sys_sendfile64;
+ extern syscall_handler_t sys_futex;
+ extern syscall_handler_t sys_sched_setaffinity;
+ extern syscall_handler_t sys_sched_getaffinity;
++extern syscall_handler_t sys_set_thread_area;
++extern syscall_handler_t sys_get_thread_area;
+ extern syscall_handler_t sys_io_setup;
+ extern syscall_handler_t sys_io_destroy;
+ extern syscall_handler_t sys_io_getevents;
+ extern syscall_handler_t sys_io_submit;
+ extern syscall_handler_t sys_io_cancel;
++extern syscall_handler_t sys_fadvise64;
+ extern syscall_handler_t sys_exit_group;
+ extern syscall_handler_t sys_lookup_dcookie;
+ extern syscall_handler_t sys_epoll_create;
+@@ -235,6 +250,20 @@
+ extern syscall_handler_t sys_epoll_wait;
+ extern syscall_handler_t sys_remap_file_pages;
+ extern syscall_handler_t sys_set_tid_address;
++extern syscall_handler_t sys_timer_create;
++extern syscall_handler_t sys_timer_settime;
++extern syscall_handler_t sys_timer_gettime;
++extern syscall_handler_t sys_timer_getoverrun;
++extern syscall_handler_t sys_timer_delete;
++extern syscall_handler_t sys_clock_settime;
++extern syscall_handler_t sys_clock_gettime;
++extern syscall_handler_t sys_clock_getres;
++extern syscall_handler_t sys_clock_nanosleep;
++extern syscall_handler_t sys_statfs64;
++extern syscall_handler_t sys_fstatfs64;
++extern syscall_handler_t sys_tgkill;
++extern syscall_handler_t sys_utimes;
++extern syscall_handler_t sys_fadvise64_64;
+ 
+ #ifdef CONFIG_NFSD
+ #define NFSSERVCTL sys_nfsservctl
+@@ -246,7 +275,7 @@
+ extern syscall_handler_t um_time;
+ extern syscall_handler_t um_stime;
+ 
+-#define LAST_GENERIC_SYSCALL __NR_set_tid_address
++#define LAST_GENERIC_SYSCALL __NR_fadvise64_64
+ 
+ #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
+ #define LAST_SYSCALL LAST_GENERIC_SYSCALL
+@@ -455,32 +484,37 @@
+ 	[ __NR_stat64 ] = sys_stat64,
+ 	[ __NR_lstat64 ] = sys_lstat64,
+ 	[ __NR_fstat64 ] = sys_fstat64,
+-	[ __NR_fcntl64 ] = sys_fcntl64,
+ 	[ __NR_getdents64 ] = sys_getdents64,
++	[ __NR_fcntl64 ] = sys_fcntl64,
++	[ 223 ] = sys_ni_syscall,
+ 	[ __NR_gettid ] = sys_gettid,
+ 	[ __NR_readahead ] = sys_readahead,
+-	[ __NR_setxattr ] = sys_ni_syscall,
+-	[ __NR_lsetxattr ] = sys_ni_syscall,
+-	[ __NR_fsetxattr ] = sys_ni_syscall,
+-	[ __NR_getxattr ] = sys_ni_syscall,
+-	[ __NR_lgetxattr ] = sys_ni_syscall,
+-	[ __NR_fgetxattr ] = sys_ni_syscall,
+-	[ __NR_listxattr ] = sys_ni_syscall,
+-	[ __NR_llistxattr ] = sys_ni_syscall,
+-	[ __NR_flistxattr ] = sys_ni_syscall,
+-	[ __NR_removexattr ] = sys_ni_syscall,
+-	[ __NR_lremovexattr ] = sys_ni_syscall,
+-	[ __NR_fremovexattr ] = sys_ni_syscall,
++	[ __NR_setxattr ] = sys_setxattr,
++	[ __NR_lsetxattr ] = sys_lsetxattr,
++	[ __NR_fsetxattr ] = sys_fsetxattr,
++	[ __NR_getxattr ] = sys_getxattr,
++	[ __NR_lgetxattr ] = sys_lgetxattr,
++	[ __NR_fgetxattr ] = sys_fgetxattr,
++	[ __NR_listxattr ] = sys_listxattr,
++	[ __NR_llistxattr ] = sys_llistxattr,
++	[ __NR_flistxattr ] = sys_flistxattr,
++	[ __NR_removexattr ] = sys_removexattr,
++	[ __NR_lremovexattr ] = sys_lremovexattr,
++	[ __NR_fremovexattr ] = sys_fremovexattr,
+ 	[ __NR_tkill ] = sys_tkill,
+ 	[ __NR_sendfile64 ] = sys_sendfile64,
+ 	[ __NR_futex ] = sys_futex,
+ 	[ __NR_sched_setaffinity ] = sys_sched_setaffinity,
+ 	[ __NR_sched_getaffinity ] = sys_sched_getaffinity,
++	[ __NR_set_thread_area ] = sys_ni_syscall,
++	[ __NR_get_thread_area ] = sys_ni_syscall,
+ 	[ __NR_io_setup ] = sys_io_setup,
+ 	[ __NR_io_destroy ] = sys_io_destroy,
+ 	[ __NR_io_getevents ] = sys_io_getevents,
+ 	[ __NR_io_submit ] = sys_io_submit,
+ 	[ __NR_io_cancel ] = sys_io_cancel,
++	[ __NR_fadvise64 ] = sys_fadvise64,
++	[ 251 ] = sys_ni_syscall,
+ 	[ __NR_exit_group ] = sys_exit_group,
+ 	[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
+ 	[ __NR_epoll_create ] = sys_epoll_create,
+@@ -488,6 +522,20 @@
+ 	[ __NR_epoll_wait ] = sys_epoll_wait,
+         [ __NR_remap_file_pages ] = sys_remap_file_pages,
+         [ __NR_set_tid_address ] = sys_set_tid_address,
++	[ __NR_timer_create ] = sys_timer_create,
++	[ __NR_timer_settime ] = sys_timer_settime,
++	[ __NR_timer_gettime ] = sys_timer_gettime,
++	[ __NR_timer_getoverrun ] = sys_timer_getoverrun,
++	[ __NR_timer_delete ] = sys_timer_delete,
++	[ __NR_clock_settime ] = sys_clock_settime,
++	[ __NR_clock_gettime ] = sys_clock_gettime,
++	[ __NR_clock_getres ] = sys_clock_getres,
++	[ __NR_clock_nanosleep ] = sys_clock_nanosleep,
++	[ __NR_statfs64 ] = sys_statfs64,
++	[ __NR_fstatfs64 ] = sys_fstatfs64,
++	[ __NR_tgkill ] = sys_tgkill,
++	[ __NR_utimes ] = sys_utimes,
++	[ __NR_fadvise64_64 ] = sys_fadvise64_64,
+ 
+ 	ARCH_SYSCALLS
+ 	[ LAST_SYSCALL + 1 ... NR_syscalls ] = 
+diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
+--- a/arch/um/kernel/syscall_kern.c	Tue Sep  9 16:45:13 2003
++++ b/arch/um/kernel/syscall_kern.c	Tue Sep  9 16:49:58 2003
+@@ -35,39 +35,40 @@
+ 
+ long sys_fork(void)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
++        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+-long sys_clone(unsigned long clone_flags, unsigned long newsp)
++long sys_clone(unsigned long clone_flags, unsigned long newsp, 
++	       int *parent_tid, int *child_tid)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-	p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
++	ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+ long sys_vfork(void)
+ {
+-	struct task_struct *p;
++	long ret;
+ 
+ 	current->thread.forking = 1;
+-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
++	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
++		      NULL);
+ 	current->thread.forking = 0;
+-	return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
++	return(ret);
+ }
+ 
+ /* common code for old and new mmaps */
+-static inline long do_mmap2(
+-	unsigned long addr, unsigned long len,
+-	unsigned long prot, unsigned long flags,
+-	unsigned long fd, unsigned long pgoff)
++long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
++	      unsigned long prot, unsigned long flags, unsigned long fd,
++	      unsigned long pgoff)
+ {
+ 	int error = -EBADF;
+ 	struct file * file = NULL;
+@@ -79,9 +80,9 @@
+ 			goto out;
+ 	}
+ 
+-	down_write(&current->mm->mmap_sem);
+-	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+-	up_write(&current->mm->mmap_sem);
++	down_write(&mm->mmap_sem);
++	error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
++	up_write(&mm->mmap_sem);
+ 
+ 	if (file)
+ 		fput(file);
+@@ -93,7 +94,7 @@
+ 	       unsigned long prot, unsigned long flags,
+ 	       unsigned long fd, unsigned long pgoff)
+ {
+-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
++	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
+ }
+ 
+ /*
+@@ -120,7 +121,8 @@
+ 	if (offset & ~PAGE_MASK)
+ 		goto out;
+ 
+-	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
++	err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
++		       offset >> PAGE_SHIFT);
+  out:
+ 	return err;
+ }
+@@ -141,37 +143,6 @@
+         return error;
+ }
+ 
+-int sys_sigaction(int sig, const struct old_sigaction *act,
+-			 struct old_sigaction *oact)
+-{
+-	struct k_sigaction new_ka, old_ka;
+-	int ret;
+-
+-	if (act) {
+-		old_sigset_t mask;
+-		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+-			return -EFAULT;
+-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+-		__get_user(mask, &act->sa_mask);
+-		siginitset(&new_ka.sa.sa_mask, mask);
+-	}
+-
+-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+-
+-	if (!ret && oact) {
+-		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+-			return -EFAULT;
+-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+-	}
+-
+-	return ret;
+-}
+-
+ /*
+  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+  *
+@@ -253,7 +224,7 @@
+ 		return sys_shmctl (first, second,
+ 				   (struct shmid_ds *) ptr);
+ 	default:
+-		return -EINVAL;
++		return -ENOSYS;
+ 	}
+ }
+ 
+@@ -302,11 +273,6 @@
+ 	return error;
+ }
+ 
+-int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+-{
+-	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
+-}
+-
+ long execute_syscall(void *r)
+ {
+ 	return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
+diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
+--- a/arch/um/kernel/sysrq.c	Tue Sep  9 16:42:22 2003
++++ b/arch/um/kernel/sysrq.c	Tue Sep  9 16:48:13 2003
+@@ -53,6 +53,14 @@
+ 	show_trace((unsigned long *)esp);
+ }
+ 
++void show_stack(struct task_struct *task, unsigned long *sp)
++{
++	if(task)
++		show_trace_task(task);
++	else
++		show_trace(sp);
++}
++
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
+--- a/arch/um/kernel/time.c	Tue Sep  9 16:41:45 2003
++++ b/arch/um/kernel/time.c	Tue Sep  9 16:47:55 2003
+@@ -15,12 +15,16 @@
+ #include "process.h"
+ #include "signal_user.h"
+ #include "time_user.h"
++#include "kern_constants.h"
+ 
+ extern struct timeval xtime;
+ 
++struct timeval local_offset = { 0, 0 };
++
+ void timer(void)
+ {
+ 	gettimeofday(&xtime, NULL);
++	timeradd(&xtime, &local_offset, &xtime);
+ }
+ 
+ void set_interval(int timer_type)
+@@ -65,7 +69,7 @@
+ 		       errno);
+ }
+ 
+-void idle_timer(void)
++void uml_idle_timer(void)
+ {
+ 	if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
+ 		panic("Couldn't unset SIGVTALRM handler");
+@@ -82,8 +86,6 @@
+ 	set_interval(ITIMER_VIRTUAL);
+ }
+ 
+-struct timeval local_offset = { 0, 0 };
+-
+ void do_gettimeofday(struct timeval *tv)
+ {
+ 	unsigned long flags;
+@@ -100,7 +102,7 @@
+ 	unsigned long flags;
+ 	struct timeval tv_in;
+ 
+-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
++	if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
+ 		return -EINVAL;
+ 
+ 	tv_in.tv_sec = tv->tv_sec;
+@@ -110,6 +112,8 @@
+ 	gettimeofday(&now, NULL);
+ 	timersub(&tv_in, &now, &local_offset);
+ 	time_unlock(flags);
++
++	return(0);
+ }
+ 
+ void idle_sleep(int secs)
+diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
+--- a/arch/um/kernel/time_kern.c	Tue Sep  9 16:43:50 2003
++++ b/arch/um/kernel/time_kern.c	Tue Sep  9 16:49:26 2003
+@@ -38,7 +38,7 @@
+ 
+ void timer_irq(union uml_pt_regs *regs)
+ {
+-	int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
++	int cpu = current_thread->cpu, ticks = missed_ticks[cpu];
+ 
+         if(!timer_irq_inited) return;
+ 	missed_ticks[cpu] = 0;
+@@ -55,12 +55,13 @@
+ 	do_timer(&regs);
+ }
+ 
+-void um_timer(int irq, void *dev, struct pt_regs *regs)
++irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
+ {
+ 	do_timer(regs);
+-	write_seqlock(&xtime_lock);
++	write_seqlock_irq(&xtime_lock);
+ 	timer();
+-	write_sequnlock(&xtime_lock);
++	write_sequnlock_irq(&xtime_lock);
++	return(IRQ_HANDLED);
+ }
+ 
+ long um_time(int * tloc)
+@@ -78,12 +79,12 @@
+ long um_stime(int * tptr)
+ {
+ 	int value;
+-	struct timeval new;
++	struct timespec new;
+ 
+ 	if (get_user(value, tptr))
+                 return -EFAULT;
+ 	new.tv_sec = value;
+-	new.tv_usec = 0;
++	new.tv_nsec = 0;
+ 	do_settimeofday(&new);
+ 	return 0;
+ }
+@@ -122,9 +123,11 @@
+ void timer_handler(int sig, union uml_pt_regs *regs)
+ {
+ #ifdef CONFIG_SMP
++	local_irq_disable();
+ 	update_process_times(user_context(UPT_SP(regs)));
++	local_irq_enable();
+ #endif
+-	if(current->thread_info->cpu == 0)
++	if(current_thread->cpu == 0)
+ 		timer_irq(regs);
+ }
+ 
+diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
+--- a/arch/um/kernel/trap_kern.c	Tue Sep  9 16:41:19 2003
++++ b/arch/um/kernel/trap_kern.c	Tue Sep  9 16:47:27 2003
+@@ -16,6 +16,7 @@
+ #include "asm/tlbflush.h"
+ #include "asm/a.out.h"
+ #include "asm/current.h"
++#include "asm/irq.h"
+ #include "user_util.h"
+ #include "kern_util.h"
+ #include "kern.h"
+@@ -51,7 +52,7 @@
+ 	if(is_write && !(vma->vm_flags & VM_WRITE)) 
+ 		goto out;
+ 	page = address & PAGE_MASK;
+-	if(page == (unsigned long) current->thread_info + PAGE_SIZE)
++	if(page == (unsigned long) current_thread + PAGE_SIZE)
+ 		panic("Kernel stack overflow");
+ 	pgd = pgd_offset(mm, page);
+ 	pmd = pmd_offset(pgd, page);
+@@ -180,6 +181,11 @@
+ 	else relay_signal(sig, regs);
+ }
+ 
++void winch(int sig, union uml_pt_regs *regs)
++{
++	do_IRQ(WINCH_IRQ, regs);
++}
++
+ void trap_init(void)
+ {
+ }
+diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
+--- a/arch/um/kernel/trap_user.c	Tue Sep  9 16:43:06 2003
++++ b/arch/um/kernel/trap_user.c	Tue Sep  9 16:48:52 2003
+@@ -82,6 +82,8 @@
+ 		     .is_irq 		= 0 },
+ 	[ SIGILL ] { .handler 		= relay_signal,
+ 		     .is_irq 		= 0 },
++	[ SIGWINCH ] { .handler		= winch,
++		       .is_irq		= 1 },
+ 	[ SIGBUS ] { .handler 		= bus_handler,
+ 		     .is_irq 		= 0 },
+ 	[ SIGSEGV] { .handler 		= segv_handler,
+diff -Naur a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
+--- a/arch/um/kernel/tt/exec_kern.c	Tue Sep  9 16:41:43 2003
++++ b/arch/um/kernel/tt/exec_kern.c	Tue Sep  9 16:47:53 2003
+@@ -47,17 +47,17 @@
+ 		do_exit(SIGKILL);
+ 	}
+ 
+-	if(current->thread_info->cpu == 0)
++	if(current_thread->cpu == 0)
+ 		forward_interrupts(new_pid);
+ 	current->thread.request.op = OP_EXEC;
+ 	current->thread.request.u.exec.pid = new_pid;
+-	unprotect_stack((unsigned long) current->thread_info);
++	unprotect_stack((unsigned long) current_thread);
+ 	os_usr1_process(os_getpid());
+ 
+ 	enable_timer();
+ 	free_page(stack);
+ 	protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
+-	task_protections((unsigned long) current->thread_info);
++	task_protections((unsigned long) current_thread);
+ 	force_flush_all();
+ 	unblock_signals();
+ }
+diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
+--- a/arch/um/kernel/tt/include/uaccess.h	Tue Sep  9 16:43:54 2003
++++ b/arch/um/kernel/tt/include/uaccess.h	Tue Sep  9 16:49:28 2003
+@@ -46,18 +46,20 @@
+ 
+ static inline int copy_from_user_tt(void *to, const void *from, int n)
+ {
+-	return(access_ok_tt(VERIFY_READ, from, n) ?
+-	       __do_copy_from_user(to, from, n, 
+-				   &current->thread.fault_addr,
+-				   &current->thread.fault_catcher) : n);
++	if(!access_ok_tt(VERIFY_READ, from, n)) 
++		return(n);
++
++	return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
++				   &current->thread.fault_catcher));
+ }
+ 
+ static inline int copy_to_user_tt(void *to, const void *from, int n)
+ {
+-	return(access_ok_tt(VERIFY_WRITE, to, n) ?
+-	       __do_copy_to_user(to, from, n, 
+-				   &current->thread.fault_addr,
+-				   &current->thread.fault_catcher) : n);
++	if(!access_ok_tt(VERIFY_WRITE, to, n))
++		return(n);
++		
++	return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
++				 &current->thread.fault_catcher));
+ }
+ 
+ extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
+@@ -67,7 +69,9 @@
+ {
+ 	int n;
+ 
+-	if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
++	if(!access_ok_tt(VERIFY_READ, src, 1)) 
++		return(-EFAULT);
++
+ 	n = __do_strncpy_from_user(dst, src, count, 
+ 				   &current->thread.fault_addr,
+ 				   &current->thread.fault_catcher);
+@@ -87,10 +91,11 @@
+ 
+ static inline int clear_user_tt(void *mem, int len)
+ {
+-	return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
+-	       __do_clear_user(mem, len, 
+-			       &current->thread.fault_addr,
+-			       &current->thread.fault_catcher) : len);
++	if(!access_ok_tt(VERIFY_WRITE, mem, len))
++		return(len);
++
++	return(__do_clear_user(mem, len, &current->thread.fault_addr,
++			       &current->thread.fault_catcher));
+ }
+ 
+ extern int __do_strnlen_user(const char *str, unsigned long n,
+diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
+--- a/arch/um/kernel/tt/process_kern.c	Tue Sep  9 16:45:54 2003
++++ b/arch/um/kernel/tt/process_kern.c	Tue Sep  9 16:50:21 2003
+@@ -104,7 +104,10 @@
+ 
+ void release_thread_tt(struct task_struct *task)
+ {
+-	os_kill_process(task->thread.mode.tt.extern_pid, 0);
++	int pid = task->thread.mode.tt.extern_pid;
++
++	if(os_getpid() != pid)
++		os_kill_process(pid, 0);
+ }
+ 
+ void exit_thread_tt(void)
+@@ -125,27 +128,27 @@
+ 	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
+ 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+ 
+-	block_signals();
++	force_flush_all();
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
++	current->thread.prev_sched = NULL;
++
+ 	init_new_thread_signals(1);
+-#ifdef CONFIG_SMP
+-	schedule_tail(current->thread.prev_sched);
+-#endif
+ 	enable_timer();
+ 	free_page(current->thread.temp_stack);
+ 	set_cmdline("(kernel thread)");
+-	force_flush_all();
+ 
+-	current->thread.prev_sched = NULL;
+ 	change_sig(SIGUSR1, 1);
+ 	change_sig(SIGVTALRM, 1);
+ 	change_sig(SIGPROF, 1);
+-	unblock_signals();
++	local_irq_enable();
+ 	if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
+ 		do_exit(0);
+ }
+ 
+ static int new_thread_proc(void *stack)
+ {
++	local_irq_disable();
+ 	init_new_thread_stack(stack, new_thread_handler);
+ 	os_usr1_process(os_getpid());
+ 	return(0);
+@@ -165,35 +168,32 @@
+  	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
+ 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
+ 
+-#ifdef CONFIG_SMP	
+-	schedule_tail(NULL);
+-#endif
++	force_flush_all();
++	if(current->thread.prev_sched != NULL)
++		schedule_tail(current->thread.prev_sched);
++	current->thread.prev_sched = NULL;
++
+ 	enable_timer();
+ 	change_sig(SIGVTALRM, 1);
+ 	local_irq_enable();
+-	force_flush_all();
+ 	if(current->mm != current->parent->mm)
+ 		protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
+ 			       1, 0, 1);
+-	task_protections((unsigned long) current->thread_info);
+-
+-	current->thread.prev_sched = NULL;
++	task_protections((unsigned long) current_thread);
+ 
+ 	free_page(current->thread.temp_stack);
++	local_irq_disable();
+ 	change_sig(SIGUSR1, 0);
+ 	set_user_mode(current);
+ }
+ 
+-static int sigusr1 = SIGUSR1;
+-
+ int fork_tramp(void *stack)
+ {
+-	int sig = sigusr1;
+-
+ 	local_irq_disable();
++	arch_init_thread();
+ 	init_new_thread_stack(stack, finish_fork_handler);
+ 
+-	kill(os_getpid(), sig);
++	os_usr1_process(os_getpid());
+ 	return(0);
+ }
+ 
+@@ -377,8 +377,8 @@
+ 
+ 	pages = (1 << CONFIG_KERNEL_STACK_ORDER);
+ 
+-	start = (unsigned long) current->thread_info + PAGE_SIZE;
+-	end = (unsigned long) current + PAGE_SIZE * pages;
++	start = (unsigned long) current_thread + PAGE_SIZE;
++	end = (unsigned long) current_thread + PAGE_SIZE * pages;
+ 	protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
+ 	protect_memory(end, high_physmem - end, 1, w, 1, 1);
+ 
+diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
+--- a/arch/um/kernel/tt/ptproxy/proxy.c	Tue Sep  9 16:43:48 2003
++++ b/arch/um/kernel/tt/ptproxy/proxy.c	Tue Sep  9 16:49:22 2003
+@@ -293,10 +293,10 @@
+ }
+ 
+ char gdb_init_string[] = 
+-"att 1
+-b panic
+-b stop
+-handle SIGWINCH nostop noprint pass
++"att 1 \n\
++b panic \n\
++b stop \n\
++handle SIGWINCH nostop noprint pass \n\
+ ";
+ 
+ int start_debugger(char *prog, int startup, int stop, int *fd_out)
+diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
+--- a/arch/um/kernel/tt/tracer.c	Tue Sep  9 16:41:14 2003
++++ b/arch/um/kernel/tt/tracer.c	Tue Sep  9 16:47:25 2003
+@@ -39,7 +39,7 @@
+ 		return(0);
+ 
+ 	register_winch_irq(tracer_winch[0], fd, -1, data);
+-	return(0);
++	return(1);
+ }
+ 
+ static void tracer_winch_handler(int sig)
+@@ -401,7 +401,7 @@
+ 		
+ 		if(!strcmp(line, "go"))	debug_stop = 0;
+ 		else if(!strcmp(line, "parent")) debug_parent = 1;
+-		else printk("Unknown debug option : '%s'\n", line);
++		else printf("Unknown debug option : '%s'\n", line);
+ 
+ 		line = next;
+ 	}
+diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
+--- a/arch/um/kernel/tt/uaccess_user.c	Tue Sep  9 16:42:02 2003
++++ b/arch/um/kernel/tt/uaccess_user.c	Tue Sep  9 16:48:11 2003
+@@ -8,15 +8,20 @@
+ #include <string.h>
+ #include "user_util.h"
+ #include "uml_uaccess.h"
++#include "task.h"
++#include "kern_util.h"
+ 
+ int __do_copy_from_user(void *to, const void *from, int n,
+ 			void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+ 			       __do_copy, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(0);
+ 	else return(n - (fault - (unsigned long) from));
+ }
+@@ -29,11 +34,14 @@
+ int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
+ 			   void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
+ 			       __do_strncpy, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(strlen(dst));
+ 	else return(-1);
+ }
+@@ -46,11 +54,14 @@
+ int __do_clear_user(void *mem, unsigned long len,
+ 		    void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	unsigned long fault;
+ 	int faulted;
+ 
+ 	fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
+ 			       __do_clear, &faulted);
++	TASK_REGS(get_current())->tt = save;
++
+ 	if(!faulted) return(0);
+ 	else return(len - (fault - (unsigned long) mem));
+ }
+@@ -58,6 +69,7 @@
+ int __do_strnlen_user(const char *str, unsigned long n,
+ 		      void **fault_addr, void **fault_catcher)
+ {
++	struct tt_regs save = TASK_REGS(get_current())->tt;
+ 	int ret;
+ 	unsigned long *faddrp = (unsigned long *)fault_addr;
+ 	jmp_buf jbuf;
+@@ -71,6 +83,8 @@
+ 	}
+ 	*fault_addr = NULL;
+ 	*fault_catcher = NULL;
++
++	TASK_REGS(get_current())->tt = save;
+ 	return ret;
+ }
+ 
+diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
+--- a/arch/um/kernel/tty_log.c	Tue Sep  9 16:43:49 2003
++++ b/arch/um/kernel/tty_log.c	Tue Sep  9 16:49:22 2003
+@@ -13,6 +13,7 @@
+ #include <sys/time.h>
+ #include "init.h"
+ #include "user.h"
++#include "kern_util.h"
+ #include "os.h"
+ 
+ #define TTY_LOG_DIR "./"
+@@ -24,29 +25,40 @@
+ #define TTY_LOG_OPEN 1
+ #define TTY_LOG_CLOSE 2
+ #define TTY_LOG_WRITE 3
++#define TTY_LOG_EXEC 4
++
++#define TTY_READ 1
++#define TTY_WRITE 2
+ 
+ struct tty_log_buf {
+ 	int what;
+ 	unsigned long tty;
+ 	int len;
++	int direction;
++	unsigned long sec;
++	unsigned long usec;
+ };
+ 
+-int open_tty_log(void *tty)
++int open_tty_log(void *tty, void *current_tty)
+ {
+ 	struct timeval tv;
+ 	struct tty_log_buf data;
+ 	char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
+ 	int fd;
+ 
++	gettimeofday(&tv, NULL);
+ 	if(tty_log_fd != -1){
+-		data = ((struct tty_log_buf) { what :	TTY_LOG_OPEN,
+-					       tty : (unsigned long) tty,
+-					       len : 0 });
++		data = ((struct tty_log_buf) { .what 	= TTY_LOG_OPEN,
++					       .tty  = (unsigned long) tty,
++					       .len  = sizeof(current_tty),
++					       .direction = 0,
++					       .sec = tv.tv_sec,
++					       .usec = tv.tv_usec } );
+ 		write(tty_log_fd, &data, sizeof(data));
++		write(tty_log_fd, &current_tty, data.len);
+ 		return(tty_log_fd);
+ 	}
+ 
+-	gettimeofday(&tv, NULL);
+ 	sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
+  		(unsigned int) tv.tv_usec);
+ 
+@@ -62,30 +74,114 @@
+ void close_tty_log(int fd, void *tty)
+ {
+ 	struct tty_log_buf data;
++	struct timeval tv;
+ 
+ 	if(tty_log_fd != -1){
+-		data = ((struct tty_log_buf) { what :	TTY_LOG_CLOSE,
+-					       tty : (unsigned long) tty,
+-					       len : 0 });
++		gettimeofday(&tv, NULL);
++		data = ((struct tty_log_buf) { .what 	= TTY_LOG_CLOSE,
++					       .tty  = (unsigned long) tty,
++					       .len  = 0,
++					       .direction = 0,
++					       .sec = tv.tv_sec,
++					       .usec = tv.tv_usec } );
+ 		write(tty_log_fd, &data, sizeof(data));
+ 		return;
+ 	}
+ 	close(fd);
+ }
+ 
+-int write_tty_log(int fd, char *buf, int len, void *tty)
++static int log_chunk(int fd, const char *buf, int len)
+ {
++	int total = 0, try, missed, n;
++	char chunk[64];
++
++	while(len > 0){
++		try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
++		missed = copy_from_user_proc(chunk, (char *) buf, try);
++		try -= missed;
++		n = write(fd, chunk, try);
++		if(n != try)
++			return(-errno);
++		if(missed != 0)
++			return(-EFAULT);
++
++		len -= try;
++		total += try;
++		buf += try;
++	}
++
++	return(total);
++}
++
++int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
++{
++	struct timeval tv;
+ 	struct tty_log_buf data;
++	int direction;
+ 
+ 	if(fd == tty_log_fd){
+-		data = ((struct tty_log_buf) { what :	TTY_LOG_WRITE,
+-					       tty : (unsigned long) tty,
+-					       len : len });
++		gettimeofday(&tv, NULL);
++		direction = is_read ? TTY_READ : TTY_WRITE;
++		data = ((struct tty_log_buf) { .what 	= TTY_LOG_WRITE,
++					       .tty  = (unsigned long) tty,
++					       .len  = len,
++					       .direction = direction,
++					       .sec = tv.tv_sec,
++					       .usec = tv.tv_usec } );
+ 		write(tty_log_fd, &data, sizeof(data));
+ 	}
+-	return(write(fd, buf, len));
++
++	return(log_chunk(fd, buf, len));
+ }
+ 
++void log_exec(char **argv, void *tty)
++{
++	struct timeval tv;
++	struct tty_log_buf data;
++	char **ptr,*arg;
++	int len;
++	
++	if(tty_log_fd == -1) return;
++
++	gettimeofday(&tv, NULL);
++
++	len = 0;
++	for(ptr = argv; ; ptr++){
++		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
++			return;
++		if(arg == NULL) break;
++		len += strlen_user_proc(arg);
++	}
++
++	data = ((struct tty_log_buf) { .what 	= TTY_LOG_EXEC,
++				       .tty  = (unsigned long) tty,
++				       .len  = len,
++				       .direction = 0,
++				       .sec = tv.tv_sec,
++				       .usec = tv.tv_usec } );
++	write(tty_log_fd, &data, sizeof(data));
++
++	for(ptr = argv; ; ptr++){
++		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
++			return;
++		if(arg == NULL) break;
++		log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
++	}
++}
++
++extern void register_tty_logger(int (*opener)(void *, void *),
++				int (*writer)(int, const char *, int, 
++					      void *, int),
++				void (*closer)(int, void *));
++
++static int register_logger(void)
++{
++	register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
++	return(0);
++}
++
++__uml_initcall(register_logger);
++
+ static int __init set_tty_log_dir(char *name, int *add)
+ {
+ 	tty_log_dir = name;
+@@ -104,7 +200,7 @@
+ 
+ 	tty_log_fd = strtoul(name, &end, 0);
+ 	if((*end != '\0') || (end == name)){
+-		printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
++		printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
+ 		tty_log_fd = -1;
+ 	}
+ 	return 0;
+diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
+--- a/arch/um/kernel/um_arch.c	Tue Sep  9 16:45:38 2003
++++ b/arch/um/kernel/um_arch.c	Tue Sep  9 16:50:11 2003
+@@ -38,13 +38,18 @@
+ #include "mode_kern.h"
+ #include "mode.h"
+ 
+-#define DEFAULT_COMMAND_LINE "root=6200"
++#define DEFAULT_COMMAND_LINE "root=ubd0"
+ 
+ struct cpuinfo_um boot_cpu_data = { 
+ 	.loops_per_jiffy	= 0,
+ 	.ipi_pipe		= { -1, -1 }
+ };
+ 
++/* Placeholder to make UML link until the vsyscall stuff is actually 
++ * implemented
++ */
++void *__kernel_vsyscall;
++
+ unsigned long thread_saved_pc(struct task_struct *task)
+ {
+ 	return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
+@@ -61,10 +66,14 @@
+ 		return 0;
+ #endif
+ 
+-	seq_printf(m, "bogomips\t: %lu.%02lu\n",
++	seq_printf(m, "processor\t: %d\n", index);
++	seq_printf(m, "vendor_id\t: User Mode Linux\n");
++	seq_printf(m, "model name\t: UML\n");
++	seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
++	seq_printf(m, "host\t\t: %s\n", host_info);
++	seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+ 		   loops_per_jiffy/(500000/HZ),
+ 		   (loops_per_jiffy/(5000/HZ)) % 100);
+-	seq_printf(m, "host\t\t: %s\n", host_info);
+ 
+ 	return(0);
+ }
+@@ -134,12 +143,12 @@
+ 	if(umid != NULL){
+ 		snprintf(argv1_begin, 
+ 			 (argv1_end - argv1_begin) * sizeof(*ptr), 
+-			 "(%s)", umid);
++			 "(%s) ", umid);
+ 		ptr = &argv1_begin[strlen(argv1_begin)];
+ 	}
+ 	else ptr = argv1_begin;
+ 
+-	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
++	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
+ 	memset(argv1_begin + strlen(argv1_begin), '\0', 
+ 	       argv1_end - argv1_begin - strlen(argv1_begin));
+ #endif
+@@ -179,7 +188,7 @@
+ static int __init uml_ncpus_setup(char *line, int *add)
+ {
+        if (!sscanf(line, "%d", &ncpus)) {
+-               printk("Couldn't parse [%s]\n", line);
++               printf("Couldn't parse [%s]\n", line);
+                return -1;
+        }
+ 
+@@ -210,7 +219,7 @@
+ 
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+-	printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
++	printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
+ 	return(0);
+ }
+ 
+@@ -221,7 +230,7 @@
+ 
+ static int __init mode_tt_setup(char *line, int *add)
+ {
+-	printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
++	printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
+ 	return(0);
+ }
+ 
+@@ -369,6 +378,7 @@
+ 		2 * PAGE_SIZE;
+ 
+ 	task_protections((unsigned long) &init_thread_info);
++	os_flush_stdout();
+ 
+ 	return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
+ }
+diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
+--- a/arch/um/kernel/umid.c	Tue Sep  9 16:46:00 2003
++++ b/arch/um/kernel/umid.c	Tue Sep  9 16:51:03 2003
+@@ -33,18 +33,19 @@
+ static int umid_is_random = 1;
+ static int umid_inited = 0;
+ 
+-static int make_umid(void);
++static int make_umid(int (*printer)(const char *fmt, ...));
+ 
+-static int __init set_umid(char *name, int is_random)
++static int __init set_umid(char *name, int is_random, 
++			   int (*printer)(const char *fmt, ...))
+ {
+ 	if(umid_inited){
+-		printk("Unique machine name can't be set twice\n");
++		(*printer)("Unique machine name can't be set twice\n");
+ 		return(-1);
+ 	}
+ 
+ 	if(strlen(name) > UMID_LEN - 1)
+-		printk("Unique machine name is being truncated to %s "
+-		       "characters\n", UMID_LEN);
++		(*printer)("Unique machine name is being truncated to %s "
++			   "characters\n", UMID_LEN);
+ 	strlcpy(umid, name, sizeof(umid));
+ 
+ 	umid_is_random = is_random;
+@@ -54,7 +55,7 @@
+ 
+ static int __init set_umid_arg(char *name, int *add)
+ {
+-	return(set_umid(name, 0));
++	return(set_umid(name, 0, printf));
+ }
+ 
+ __uml_setup("umid=", set_umid_arg,
+@@ -67,7 +68,7 @@
+ {
+ 	int n;
+ 
+-	if(!umid_inited && make_umid()) return(-1);
++	if(!umid_inited && make_umid(printk)) return(-1);
+ 
+ 	n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
+ 	if(n > len){
+@@ -92,14 +93,14 @@
+ 	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
+ 			  0644);
+ 	if(fd < 0){
+-		printk("Open of machine pid file \"%s\" failed - "
++		printf("Open of machine pid file \"%s\" failed - "
+ 		       "errno = %d\n", file, -fd);
+ 		return 0;
+ 	}
+ 
+ 	sprintf(pid, "%d\n", os_getpid());
+ 	if(write(fd, pid, strlen(pid)) != strlen(pid))
+-		printk("Write of pid file failed - errno = %d\n", errno);
++		printf("Write of pid file failed - errno = %d\n", errno);
+ 	close(fd);
+ 	return 0;
+ }
+@@ -197,7 +198,7 @@
+ 	if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
+ 		uml_dir = malloc(strlen(name) + 1);
+ 		if(uml_dir == NULL){
+-			printk("Failed to malloc uml_dir - error = %d\n",
++			printf("Failed to malloc uml_dir - error = %d\n",
+ 			       errno);
+ 			uml_dir = name;
+ 			return(0);
+@@ -217,7 +218,7 @@
+ 		char *home = getenv("HOME");
+ 
+ 		if(home == NULL){
+-			printk("make_uml_dir : no value in environment for "
++			printf("make_uml_dir : no value in environment for "
+ 			       "$HOME\n");
+ 			exit(1);
+ 		}
+@@ -239,25 +240,25 @@
+ 	strcpy(uml_dir, dir);
+ 	
+ 	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
+-	        printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
++	        printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
+ 		return(-1);
+ 	}
+ 	return 0;
+ }
+ 
+-static int __init make_umid(void)
++static int __init make_umid(int (*printer)(const char *fmt, ...))
+ {
+ 	int fd, err;
+ 	char tmp[strlen(uml_dir) + UMID_LEN + 1];
+ 
+ 	strlcpy(tmp, uml_dir, sizeof(tmp));
+ 
+-	if(*umid == 0){
++	if(!umid_inited){
+ 		strcat(tmp, "XXXXXX");
+ 		fd = mkstemp(tmp);
+ 		if(fd < 0){
+-			printk("make_umid - mkstemp failed, errno = %d\n",
+-			       errno);
++			(*printer)("make_umid - mkstemp failed, errno = %d\n",
++				   errno);
+ 			return(1);
+ 		}
+ 
+@@ -267,7 +268,7 @@
+ 		 * for directories.
+ 		 */
+ 		unlink(tmp);
+-		set_umid(&tmp[strlen(uml_dir)], 1);
++		set_umid(&tmp[strlen(uml_dir)], 1, printer);
+ 	}
+ 	
+ 	sprintf(tmp, "%s%s", uml_dir, umid);
+@@ -275,14 +276,14 @@
+ 	if((err = mkdir(tmp, 0777)) < 0){
+ 		if(errno == EEXIST){
+ 			if(not_dead_yet(tmp)){
+-				printk("umid '%s' is in use\n", umid);
++				(*printer)("umid '%s' is in use\n", umid);
+ 				return(-1);
+ 			}
+ 			err = mkdir(tmp, 0777);
+ 		}
+ 	}
+ 	if(err < 0){
+-		printk("Failed to create %s - errno = %d\n", umid, errno);
++		(*printer)("Failed to create %s - errno = %d\n", umid, errno);
+ 		return(-1);
+ 	}
+ 
+@@ -295,7 +296,13 @@
+ );
+ 
+ __uml_postsetup(make_uml_dir);
+-__uml_postsetup(make_umid);
++
++static int __init make_umid_setup(void)
++{
++	return(make_umid(printf));
++}
++
++__uml_postsetup(make_umid_setup);
+ __uml_postsetup(create_pid_file);
+ 
+ /*
+diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
+--- a/arch/um/kernel/user_util.c	Tue Sep  9 16:41:41 2003
++++ b/arch/um/kernel/user_util.c	Tue Sep  9 16:47:43 2003
+@@ -119,17 +119,6 @@
+ 	}
+ }
+ 
+-int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
+-{
+-	int pid;
+-
+-	pid = clone(fn, sp, flags, arg);
+- 	if(pid < 0) return(-1);
+-	wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
+-	ptrace(PTRACE_CONT, pid, 0, 0);
+-	return(pid);
+-}
+-
+ int raw(int fd, int complain)
+ {
+ 	struct termios tt;
+diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
+--- a/arch/um/os-Linux/drivers/tuntap_user.c	Tue Sep  9 16:46:16 2003
++++ b/arch/um/os-Linux/drivers/tuntap_user.c	Tue Sep  9 16:51:17 2003
+@@ -142,7 +142,7 @@
+ 			return(-errno);
+ 		}
+ 		memset(&ifr, 0, sizeof(ifr));
+-		ifr.ifr_flags = IFF_TAP;
++		ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 		strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
+ 		if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ 			printk("TUNSETIFF failed, errno = %d", errno);
+diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
+--- a/arch/um/os-Linux/file.c	Tue Sep  9 16:46:10 2003
++++ b/arch/um/os-Linux/file.c	Tue Sep  9 16:51:13 2003
+@@ -315,7 +315,7 @@
+ 	return(new);
+ }
+ 
+-int create_unix_socket(char *file, int len)
++int create_unix_socket(char *file, int len, int close_on_exec)
+ {
+ 	struct sockaddr_un addr;
+ 	int sock, err;
+@@ -327,6 +327,10 @@
+ 		return(-errno);
+ 	}
+ 
++	if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
++		printk("create_unix_socket : Setting FD_CLOEXEC failed, "
++		       "errno = %d", errno);
++
+ 	addr.sun_family = AF_UNIX;
+ 
+ 	/* XXX Be more careful about overflow */
+@@ -342,6 +346,37 @@
+ 	return(sock);
+ }
+ 
++void os_flush_stdout(void)
++{
++	fflush(stdout);
++}
++
++int os_lock_file(int fd, int excl)
++{
++	int type = excl ? F_WRLCK : F_RDLCK;
++	struct flock lock = ((struct flock) { .l_type	= type,
++					      .l_whence	= SEEK_SET,
++					      .l_start	= 0,
++					      .l_len	= 0 } );
++	int err, save;
++
++	err = fcntl(fd, F_SETLK, &lock);
++	if(!err)
++		goto out;
++
++	save = -errno;
++	err = fcntl(fd, F_GETLK, &lock);
++	if(err){
++		err = -errno;
++		goto out;
++	}
++	
++	printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
++	err = save;
++ out:
++	return(err);
++}
++
+ /*
+  * Overrides for Emacs so that we follow Linus's tabbing style.
+  * Emacs will notice this stuff at the end of the file and automatically
+diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
+--- a/arch/um/sys-i386/Makefile	Tue Sep  9 16:41:38 2003
++++ b/arch/um/sys-i386/Makefile	Tue Sep  9 16:47:42 2003
+@@ -1,7 +1,8 @@
+-obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
+-	ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
++obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
++	ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
+ 
+ obj-$(CONFIG_HIGHMEM) += highmem.o
++obj-$(CONFIG_MODULES) += module.o
+ 
+ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
+ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+@@ -9,6 +10,8 @@
+ SYMLINKS = semaphore.c highmem.c module.c
+ SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
+ 
++clean-files := $(SYMLINKS)
++
+ semaphore.c-dir = kernel
+ highmem.c-dir = mm
+ module.c-dir = kernel
+@@ -24,8 +27,7 @@
+ $(SYMLINKS): 
+ 	$(call make_link,$@)
+ 
+-clean:
+-	$(MAKE) -C util clean
++subdir- := util
+ 
+ fastdep:
+ 
+diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
+--- a/arch/um/sys-i386/bugs.c	Tue Sep  9 16:45:37 2003
++++ b/arch/um/sys-i386/bugs.c	Tue Sep  9 16:50:09 2003
+@@ -8,6 +8,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <sys/signal.h>
++#include <asm/ldt.h>
+ #include "kern_util.h"
+ #include "user.h"
+ #include "sysdep/ptrace.h"
+@@ -16,8 +17,8 @@
+ #define MAXTOKEN 64
+ 
+ /* Set during early boot */
+-int cpu_has_cmov = 1;
+-int cpu_has_xmm = 0;
++int host_has_cmov = 1;
++int host_has_xmm = 0;
+ 
+ static char token(int fd, char *buf, int len, char stop)
+ {
+@@ -104,6 +105,25 @@
+ 	return(1);
+ }
+ 
++static void disable_lcall(void)
++{
++	struct modify_ldt_ldt_s ldt;
++	int err;
++
++	bzero(&ldt, sizeof(ldt));
++	ldt.entry_number = 7;
++	ldt.base_addr = 0;
++	ldt.limit = 0;
++	err = modify_ldt(1, &ldt, sizeof(ldt));
++	if(err)
++		printk("Failed to disable lcall7 - errno = %d\n", errno);
++}
++
++void arch_init_thread(void)
++{
++	disable_lcall();
++}
++
+ void arch_check_bugs(void)
+ {
+ 	int have_it;
+@@ -113,8 +133,8 @@
+ 		       "checks\n");
+ 		return;
+ 	}
+-	if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
+-	if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
++	if(check_cpu_feature("cmov", &have_it)) host_has_cmov = have_it;
++	if(check_cpu_feature("xmm", &have_it)) host_has_xmm = have_it;
+ }
+ 
+ int arch_handle_signal(int sig, union uml_pt_regs *regs)
+@@ -130,18 +150,18 @@
+ 	if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
+ 		return(0);
+ 
+-	if(cpu_has_cmov == 0)
++	if(host_has_cmov == 0)
+ 		panic("SIGILL caused by cmov, which this processor doesn't "
+ 		      "implement, boot a filesystem compiled for older "
+ 		      "processors");
+-	else if(cpu_has_cmov == 1)
++	else if(host_has_cmov == 1)
+ 		panic("SIGILL caused by cmov, which this processor claims to "
+ 		      "implement");
+-	else if(cpu_has_cmov == -1)
++	else if(host_has_cmov == -1)
+ 		panic("SIGILL caused by cmov, couldn't tell if this processor "
+ 		      "implements it, boot a filesystem compiled for older "
+ 		      "processors");
+-	else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
++	else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
+ 	return(0);
+ }
+ 
+diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
+--- a/arch/um/uml.lds.S	Tue Sep  9 16:43:03 2003
++++ b/arch/um/uml.lds.S	Tue Sep  9 16:48:52 2003
+@@ -26,7 +26,11 @@
+   . = ALIGN(4096);		/* Init code and data */
+   _stext = .;
+   __init_begin = .;
+-  .text.init : { *(.text.init) }
++  .init.text : { 
++	_sinittext = .;
++	*(.init.text)
++	_einittext = .;
++  }
+   . = ALIGN(4096);
+   .text      :
+   {
+@@ -38,7 +42,7 @@
+ 
+   #include "asm/common.lds.S"
+ 
+-  .data.init : { *(.data.init) }
++  init.data : { *(init.data) }
+   .data    :
+   {
+     . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
+diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
+--- a/arch/um/util/mk_constants_kern.c	Tue Sep  9 16:41:24 2003
++++ b/arch/um/util/mk_constants_kern.c	Tue Sep  9 16:47:30 2003
+@@ -1,5 +1,6 @@
+ #include "linux/kernel.h"
+ #include "linux/stringify.h"
++#include "linux/time.h"
+ #include "asm/page.h"
+ 
+ extern void print_head(void);
+@@ -11,6 +12,7 @@
+ {
+   print_head();
+   print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
++
+   print_constant_str("UM_KERN_EMERG", KERN_EMERG);
+   print_constant_str("UM_KERN_ALERT", KERN_ALERT);
+   print_constant_str("UM_KERN_CRIT", KERN_CRIT);
+@@ -19,6 +21,8 @@
+   print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
+   print_constant_str("UM_KERN_INFO", KERN_INFO);
+   print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
++
++  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
+   print_tail();
+   return(0);
+ }
+diff -Naur a/fs/Makefile b/fs/Makefile
+--- a/fs/Makefile	Tue Sep  9 16:43:32 2003
++++ b/fs/Makefile	Tue Sep  9 16:49:19 2003
+@@ -91,3 +91,5 @@
+ obj-$(CONFIG_XFS_FS)		+= xfs/
+ obj-$(CONFIG_AFS_FS)		+= afs/
+ obj-$(CONFIG_BEFS_FS)		+= befs/
++obj-$(CONFIG_HOSTFS)		+= hostfs/
++obj-$(CONFIG_HPPFS)		+= hppfs/
+diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
+--- a/fs/hostfs/Makefile	Wed Dec 31 19:00:00 1969
++++ b/fs/hostfs/Makefile	Tue Sep  9 16:47:22 2003
+@@ -0,0 +1,36 @@
++# 
++# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
++# Licensed under the GPL
++#
++
++# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
++# to __st_ino.  It stayed in the same place, so as long as the correct name
++# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
++
++STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
++				echo __)st_ino
++
++hostfs-objs := hostfs_kern.o hostfs_user.o
++
++obj-y = 
++obj-$(CONFIG_HOSTFS) += hostfs.o
++
++SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
++
++USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
++USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
++
++USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
++
++$(USER_OBJS) : %.o: %.c
++	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
++
++clean:
++
++modules:
++
++fastdep:
++
++dep:
++
++archmrproper: clean
+diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
+--- a/fs/hostfs/hostfs.h	Wed Dec 31 19:00:00 1969
++++ b/fs/hostfs/hostfs.h	Tue Sep  9 16:47:21 2003
+@@ -0,0 +1,79 @@
++#ifndef __UM_FS_HOSTFS
++#define __UM_FS_HOSTFS
++
++#include "os.h"
++
++/* These are exactly the same definitions as in fs.h, but the names are 
++ * changed so that this file can be included in both kernel and user files.
++ */
++
++#define HOSTFS_ATTR_MODE	1
++#define HOSTFS_ATTR_UID 	2
++#define HOSTFS_ATTR_GID 	4
++#define HOSTFS_ATTR_SIZE	8
++#define HOSTFS_ATTR_ATIME	16
++#define HOSTFS_ATTR_MTIME	32
++#define HOSTFS_ATTR_CTIME	64
++#define HOSTFS_ATTR_ATIME_SET	128
++#define HOSTFS_ATTR_MTIME_SET	256
++#define HOSTFS_ATTR_FORCE	512	/* Not a change, but a change it */
++#define HOSTFS_ATTR_ATTR_FLAG	1024
++
++struct hostfs_iattr {
++	unsigned int	ia_valid;
++	mode_t		ia_mode;
++	uid_t		ia_uid;
++	gid_t		ia_gid;
++	loff_t		ia_size;
++	struct timespec	ia_atime;
++	struct timespec	ia_mtime;
++	struct timespec	ia_ctime;
++	unsigned int	ia_attr_flags;
++};
++
++extern int stat_file(const char *path, unsigned long long *inode_out, 
++		     int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
++		     unsigned long long *size_out, struct timespec *atime_out, 
++		     struct timespec *mtime_out, struct timespec *ctime_out, 
++		     int *blksize_out, unsigned long long *blocks_out);
++extern int access_file(char *path, int r, int w, int x);
++extern int open_file(char *path, int r, int w, int append);
++extern int file_type(const char *path, int *rdev);
++extern void *open_dir(char *path, int *err_out);
++extern char *read_dir(void *stream, unsigned long long *pos, 
++		      unsigned long long *ino_out, int *len_out);
++extern void close_file(void *stream);
++extern void close_dir(void *stream);
++extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
++extern int write_file(int fd, unsigned long long *offset, const char *buf,
++		      int len);
++extern int lseek_file(int fd, long long offset, int whence);
++extern int file_create(char *name, int ur, int uw, int ux, int gr, 
++		       int gw, int gx, int or, int ow, int ox);
++extern int set_attr(const char *file, struct hostfs_iattr *attrs);
++extern int make_symlink(const char *from, const char *to);
++extern int unlink_file(const char *file);
++extern int do_mkdir(const char *file, int mode);
++extern int do_rmdir(const char *file);
++extern int do_mknod(const char *file, int mode, int dev);
++extern int link_file(const char *from, const char *to);
++extern int do_readlink(char *file, char *buf, int size);
++extern int rename_file(char *from, char *to);
++extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
++		     long long *bfree_out, long long *bavail_out, 
++		     long long *files_out, long long *ffree_out, 
++		     void *fsid_out, int fsid_size, long *namelen_out, 
++		     long *spare_out);
++
++#endif
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
+--- a/fs/hostfs/hostfs_kern.c	Wed Dec 31 19:00:00 1969
++++ b/fs/hostfs/hostfs_kern.c	Tue Sep  9 16:47:25 2003
+@@ -0,0 +1,1008 @@
++/* 
++ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ *
++ * Ported the filesystem routines to 2.5.
++ * 2003-02-10 Petr Baudis <pasky@ucw.cz>
++ */
++
++#include <linux/stddef.h>
++#include <linux/fs.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/blkdev.h>
++#include <linux/list.h>
++#include <linux/buffer_head.h>
++#include <linux/root_dev.h>
++#include <linux/statfs.h>
++#include <asm/uaccess.h>
++#include "hostfs.h"
++#include "kern_util.h"
++#include "kern.h"
++#include "user_util.h"
++#include "2_5compat.h"
++#include "init.h"
++
++struct hostfs_inode_info {
++	char *host_filename;
++	int fd;
++	int mode;
++	struct inode vfs_inode;
++};
++
++static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
++{
++	return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
++}
++
++#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
++
++int hostfs_d_delete(struct dentry *dentry)
++{
++	return(1);
++}
++
++struct dentry_operations hostfs_dentry_ops = {
++	.d_delete		= hostfs_d_delete,
++};
++
++/* Changed in hostfs_args before the kernel starts running */
++static char *root_ino = "/";
++static int append = 0;
++
++#define HOSTFS_SUPER_MAGIC 0x00c0ffee
++
++static struct inode_operations hostfs_iops;
++static struct inode_operations hostfs_dir_iops;
++static struct address_space_operations hostfs_link_aops;
++
++static int __init hostfs_args(char *options, int *add)
++{
++	char *ptr;
++
++	ptr = strchr(options, ',');
++	if(ptr != NULL)
++		*ptr++ = '\0';
++	if(*options != '\0')
++		root_ino = options;
++
++	options = ptr;
++	while(options){
++		ptr = strchr(options, ',');
++		if(ptr != NULL)
++			*ptr++ = '\0';
++		if(*options != '\0'){
++			if(!strcmp(options, "append"))
++				append = 1;
++			else printf("hostfs_args - unsupported option - %s\n",
++				    options);
++		}
++		options = ptr;
++	}
++	return(0);
++}
++
++__uml_setup("hostfs=", hostfs_args,
++"hostfs=<root dir>,<flags>,...\n"
++"    This is used to set hostfs parameters.  The root directory argument\n"
++"    is used to confine all hostfs mounts to within the specified directory\n"
++"    tree on the host.  If this isn't specified, then a user inside UML can\n"
++"    mount anything on the host that's accessible to the user that's running\n"
++"    it.\n"
++"    The only flag currently supported is 'append', which specifies that all\n"
++"    files opened by hostfs will be opened in append mode.\n\n"
++);
++
++static char *dentry_name(struct dentry *dentry, int extra)
++{
++	struct dentry *parent;
++	char *root, *name;
++	int len;
++
++	len = 0;
++	parent = dentry;
++	while(parent->d_parent != parent){
++		len += parent->d_name.len + 1;
++		parent = parent->d_parent;
++	}
++	
++	root = HOSTFS_I(parent->d_inode)->host_filename;
++	len += strlen(root);
++	name = kmalloc(len + extra + 1, GFP_KERNEL);
++	if(name == NULL) return(NULL);
++
++	name[len] = '\0';
++	parent = dentry;
++	while(parent->d_parent != parent){
++		len -= parent->d_name.len + 1;
++		name[len] = '/';
++		strncpy(&name[len + 1], parent->d_name.name, 
++			parent->d_name.len);
++		parent = parent->d_parent;
++	}
++	strncpy(name, root, strlen(root));
++	return(name);
++}
++
++static char *inode_name(struct inode *ino, int extra)
++{
++	struct dentry *dentry;
++
++	dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
++	return(dentry_name(dentry, extra));
++}
++
++static int read_name(struct inode *ino, char *name)
++{
++	/* The non-int inode fields are copied into ints by stat_file and
++	 * then copied into the inode because passing the actual pointers
++	 * in and having them treated as int * breaks on big-endian machines
++	 */
++	int err;
++	int i_mode, i_nlink, i_blksize;
++	unsigned long long i_size;
++	unsigned long long i_ino;
++	unsigned long long i_blocks;
++
++	err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
++			&ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
++			&ino->i_ctime, &i_blksize, &i_blocks);
++	if(err) 
++		return(err);
++
++	ino->i_ino = i_ino;
++	ino->i_mode = i_mode;
++	ino->i_nlink = i_nlink;
++	ino->i_size = i_size;
++	ino->i_blksize = i_blksize;
++	ino->i_blocks = i_blocks;
++	if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
++		ino->i_uid = 0;
++	return(0);
++}
++
++static char *follow_link(char *link)
++{
++	int len, n;
++	char *name, *resolved, *end;
++
++	len = 64;
++	while(1){
++		n = -ENOMEM;
++		name = kmalloc(len, GFP_KERNEL);
++		if(name == NULL)
++			goto out;
++
++		n = do_readlink(link, name, len);
++		if(n < len)
++			break;
++		len *= 2;
++		kfree(name);
++	}
++	if(n < 0)
++		goto out_free;
++
++	if(*name == '/')
++		return(name);
++
++	end = strrchr(link, '/');
++	if(end == NULL)
++		return(name);
++
++	*(end + 1) = '\0';
++	len = strlen(link) + strlen(name) + 1;
++
++	resolved = kmalloc(len, GFP_KERNEL);
++	if(resolved == NULL){
++		n = -ENOMEM;
++		goto out_free;
++	}
++
++	sprintf(resolved, "%s%s", link, name);
++	kfree(name);
++	kfree(link);
++	return(resolved);
++
++ out_free:
++	kfree(name);
++ out:
++	return(ERR_PTR(n));
++}
++
++static int read_inode(struct inode *ino)
++{
++	char *name;
++	int err = 0;
++
++	/* Unfortunately, we are called from iget() when we don't have a dentry
++	 * allocated yet.
++	 */
++	if(list_empty(&ino->i_dentry))
++		goto out;
++ 
++	err = -ENOMEM;
++	name = inode_name(ino, 0);
++	if(name == NULL) 
++		goto out;
++
++	if(file_type(name, NULL) == OS_TYPE_SYMLINK){
++		name = follow_link(name);
++		if(IS_ERR(name)){
++			err = PTR_ERR(name);
++			goto out;
++		}
++	}
++	
++	err = read_name(ino, name);
++	kfree(name);
++ out:
++	return(err);
++}
++
++int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
++{
++	/* do_statfs uses struct statfs64 internally, but the linux kernel
++	 * struct statfs still has 32-bit versions for most of these fields,
++	 * so we convert them here
++	 */
++	int err;
++	long long f_blocks;
++	long long f_bfree;
++	long long f_bavail;
++	long long f_files;
++	long long f_ffree;
++
++	err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
++			&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
++			&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
++			&sf->f_namelen, sf->f_spare);
++	if(err) return(err);
++	sf->f_blocks = f_blocks;
++	sf->f_bfree = f_bfree;
++	sf->f_bavail = f_bavail;
++	sf->f_files = f_files;
++	sf->f_ffree = f_ffree;
++	sf->f_type = HOSTFS_SUPER_MAGIC;
++	return(0);
++}
++
++static struct inode *hostfs_alloc_inode(struct super_block *sb)
++{
++	struct hostfs_inode_info *hi;
++
++	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
++	if(hi == NULL) 
++		return(NULL);
++
++	*hi = ((struct hostfs_inode_info) { .host_filename	= NULL,
++					    .fd			= -1,
++					    .mode		= 0 });
++	inode_init_once(&hi->vfs_inode);
++	return(&hi->vfs_inode);
++}
++
++static void hostfs_destroy_inode(struct inode *inode)
++{
++	if(HOSTFS_I(inode)->host_filename) 
++		kfree(HOSTFS_I(inode)->host_filename);
++
++	if(HOSTFS_I(inode)->fd != -1) 
++		close_file(&HOSTFS_I(inode)->fd);
++
++	kfree(HOSTFS_I(inode));
++}
++
++static void hostfs_read_inode(struct inode *inode)
++{
++	read_inode(inode);
++}
++
++static struct super_operations hostfs_sbops = { 
++	.alloc_inode	= hostfs_alloc_inode,
++	.destroy_inode	= hostfs_destroy_inode,
++	.read_inode	= hostfs_read_inode,
++	.statfs		= hostfs_statfs,
++};
++
++int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
++{
++	void *dir;
++	char *name;
++	unsigned long long next, ino;
++	int error, len;
++
++	name = dentry_name(file->f_dentry, 0);
++	if(name == NULL) return(-ENOMEM);
++	dir = open_dir(name, &error);
++	kfree(name);
++	if(dir == NULL) return(-error);
++	next = file->f_pos;
++	while((name = read_dir(dir, &next, &ino, &len)) != NULL){
++		error = (*filldir)(ent, name, len, file->f_pos, 
++				   ino, DT_UNKNOWN);
++		if(error) break;
++		file->f_pos = next;
++	}
++	close_dir(dir);
++	return(0);
++}
++
++int hostfs_file_open(struct inode *ino, struct file *file)
++{
++	char *name;
++	int mode = 0, r = 0, w = 0, fd;
++
++	mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
++	if((mode & HOSTFS_I(ino)->mode) == mode)
++		return(0);
++
++	/* The file may already have been opened, but with the wrong access,
++	 * so this resets things and reopens the file with the new access.
++	 */
++	if(HOSTFS_I(ino)->fd != -1){
++		close_file(&HOSTFS_I(ino)->fd);
++		HOSTFS_I(ino)->fd = -1;
++	}
++
++	HOSTFS_I(ino)->mode |= mode;
++	if(HOSTFS_I(ino)->mode & FMODE_READ) 
++		r = 1;
++	if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
++		w = 1;
++	if(w) 
++		r = 1;
++
++	name = dentry_name(file->f_dentry, 0);
++	if(name == NULL) 
++		return(-ENOMEM);
++
++	fd = open_file(name, r, w, append);
++	kfree(name);
++	if(fd < 0) return(fd);
++	FILE_HOSTFS_I(file)->fd = fd;
++
++	return(0);
++}
++
++int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
++{
++	return(0);
++}
++
++static struct file_operations hostfs_file_fops = {
++	.llseek		= generic_file_llseek,
++	.read		= generic_file_read,
++	.write		= generic_file_write,
++	.mmap		= generic_file_mmap,
++	.open		= hostfs_file_open,
++	.release	= NULL,
++	.fsync		= hostfs_fsync,
++};
++
++static struct file_operations hostfs_dir_fops = {
++	.readdir	= hostfs_readdir,
++	.read		= generic_read_dir,
++};
++
++int hostfs_writepage(struct page *page, struct writeback_control *wbc)
++{
++	struct address_space *mapping = page->mapping;
++	struct inode *inode = mapping->host;
++	char *buffer;
++	unsigned long long base;
++	int count = PAGE_CACHE_SIZE;
++	int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
++	int err;
++
++	if (page->index >= end_index)
++		count = inode->i_size & (PAGE_CACHE_SIZE-1);
++
++	buffer = kmap(page);
++	base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
++
++	err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
++	if(err != count){
++		ClearPageUptodate(page);
++		goto out;
++	}
++
++	if (base > inode->i_size)
++		inode->i_size = base;
++
++	if (PageError(page))
++		ClearPageError(page);	
++	err = 0;
++
++ out:	
++	kunmap(page);
++
++	unlock_page(page);
++	return err; 
++}
++
++int hostfs_readpage(struct file *file, struct page *page)
++{
++	char *buffer;
++	long long start;
++	int err = 0;
++
++	start = (long long) page->index << PAGE_CACHE_SHIFT;
++	buffer = kmap(page);
++	err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
++			PAGE_CACHE_SIZE);
++	if(err < 0) goto out;
++
++	memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
++
++	flush_dcache_page(page);
++	SetPageUptodate(page);
++	if (PageError(page)) ClearPageError(page);
++	err = 0;
++ out:
++	kunmap(page);
++	unlock_page(page);
++	return(err);
++}
++
++int hostfs_prepare_write(struct file *file, struct page *page, 
++			 unsigned int from, unsigned int to)
++{
++	char *buffer;
++	long long start, tmp;
++	int err;
++
++	start = (long long) page->index << PAGE_CACHE_SHIFT;
++	buffer = kmap(page);
++	if(from != 0){
++		tmp = start;
++		err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
++				from);
++		if(err < 0) goto out;
++	}
++	if(to != PAGE_CACHE_SIZE){
++		start += to;
++		err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
++				PAGE_CACHE_SIZE - to);
++		if(err < 0) goto out;		
++	}
++	err = 0;
++ out:
++	kunmap(page);
++	return(err);
++}
++
++int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
++		 unsigned to)
++{
++	struct address_space *mapping = page->mapping;
++	struct inode *inode = mapping->host;
++	char *buffer;
++	long long start;
++	int err = 0;
++
++	start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
++	buffer = kmap(page);
++	err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
++			 to - from);
++	if(err > 0) err = 0;
++	if(!err && (start > inode->i_size))
++		inode->i_size = start;
++
++	kunmap(page);
++	return(err);
++}
++
++static struct address_space_operations hostfs_aops = {
++	.writepage 	= hostfs_writepage,
++	.readpage	= hostfs_readpage,
++/* 	.set_page_dirty = __set_page_dirty_nobuffers, */
++	.prepare_write	= hostfs_prepare_write,
++	.commit_write	= hostfs_commit_write
++};
++
++static int init_inode(struct inode *inode, struct dentry *dentry)
++{
++	char *name;
++	int type, err = -ENOMEM, rdev;
++
++	if(dentry){
++		name = dentry_name(dentry, 0);
++		if(name == NULL)
++			goto out;
++		type = file_type(name, &rdev);
++		kfree(name);
++	}
++	else type = OS_TYPE_DIR;
++
++	err = 0;
++	if(type == OS_TYPE_SYMLINK)
++		inode->i_op = &page_symlink_inode_operations;
++	else if(type == OS_TYPE_DIR)
++		inode->i_op = &hostfs_dir_iops;
++	else inode->i_op = &hostfs_iops;
++
++	if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
++	else inode->i_fop = &hostfs_file_fops;
++
++	if(type == OS_TYPE_SYMLINK) 
++		inode->i_mapping->a_ops = &hostfs_link_aops;
++	else inode->i_mapping->a_ops = &hostfs_aops;
++
++	switch (type) {
++	case OS_TYPE_CHARDEV:
++		init_special_inode(inode, S_IFCHR, rdev);
++		break;
++	case OS_TYPE_BLOCKDEV:
++		init_special_inode(inode, S_IFBLK, rdev);
++		break;
++	case OS_TYPE_FIFO:
++		init_special_inode(inode, S_IFIFO, 0);
++		break;
++	case OS_TYPE_SOCK:
++		init_special_inode(inode, S_IFSOCK, 0);
++		break;
++	}
++ out:
++	return(err);
++}
++
++int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
++                 struct nameidata *nd)
++{
++	struct inode *inode;
++	char *name;
++	int error, fd;
++
++	error = -ENOMEM;
++	inode = iget(dir->i_sb, 0);
++	if(inode == NULL) goto out;
++
++	error = init_inode(inode, dentry);
++	if(error) 
++		goto out_put;
++	
++	error = -ENOMEM;
++	name = dentry_name(dentry, 0);
++	if(name == NULL)
++		goto out_put;
++
++	fd = file_create(name, 
++			 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
++			 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
++			 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
++	if(fd < 0) 
++		error = fd;
++	else error = read_name(inode, name);
++
++	kfree(name);
++	if(error)
++		goto out_put;
++
++	HOSTFS_I(inode)->fd = fd;
++	HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
++	d_instantiate(dentry, inode);
++	return(0);
++
++ out_put:
++	iput(inode);
++ out:
++	return(error);
++}
++
++struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
++                            struct nameidata *nd)
++{
++	struct inode *inode;
++	char *name;
++	int err;
++
++	err = -ENOMEM;
++	inode = iget(ino->i_sb, 0);
++	if(inode == NULL) 
++		goto out;
++ 
++	err = init_inode(inode, dentry);
++	if(err) 
++		goto out_put;
++
++	err = -ENOMEM;
++	name = dentry_name(dentry, 0);
++	if(name == NULL)
++		goto out_put;
++
++	err = read_name(inode, name);
++	kfree(name);
++	if(err == -ENOENT){
++		iput(inode);
++		inode = NULL;
++	}
++	else if(err)
++		goto out_put;
++
++	d_add(dentry, inode);
++	dentry->d_op = &hostfs_dentry_ops;
++	return(NULL);
++
++ out_put:
++	iput(inode);
++ out:
++	return(ERR_PTR(err));
++}
++
++static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
++{
++        char *file;
++	int len;
++
++	file = inode_name(ino, dentry->d_name.len + 1);
++	if(file == NULL) return(NULL);
++        strcat(file, "/");
++	len = strlen(file);
++        strncat(file, dentry->d_name.name, dentry->d_name.len);
++	file[len + dentry->d_name.len] = '\0';
++        return(file);
++}
++
++int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
++{
++        char *from_name, *to_name;
++        int err;
++
++        if((from_name = inode_dentry_name(ino, from)) == NULL) 
++                return(-ENOMEM);
++        to_name = dentry_name(to, 0);
++	if(to_name == NULL){
++		kfree(from_name);
++		return(-ENOMEM);
++	}
++        err = link_file(to_name, from_name);
++        kfree(from_name);
++        kfree(to_name);
++        return(err);
++}
++
++int hostfs_unlink(struct inode *ino, struct dentry *dentry)
++{
++	char *file;
++	int err;
++
++	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
++	if(append)
++		return(-EPERM);
++
++	err = unlink_file(file);
++	kfree(file);
++	return(err);
++}
++
++int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
++{
++	char *file;
++	int err;
++
++	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
++	err = make_symlink(file, to);
++	kfree(file);
++	return(err);
++}
++
++int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
++{
++	char *file;
++	int err;
++
++	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
++	err = do_mkdir(file, mode);
++	kfree(file);
++	return(err);
++}
++
++int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
++{
++	char *file;
++	int err;
++
++	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
++	err = do_rmdir(file);
++	kfree(file);
++	return(err);
++}
++
++int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
++{
++	struct inode *inode;
++	char *name;
++	int err = -ENOMEM;
++ 
++	inode = iget(dir->i_sb, 0);
++	if(inode == NULL) 
++		goto out;
++
++	err = init_inode(inode, dentry);
++	if(err) 
++		goto out_put;
++
++	err = -ENOMEM;
++	name = dentry_name(dentry, 0);
++	if(name == NULL)
++		goto out_put;
++
++	init_special_inode(inode, mode, dev);
++	err = do_mknod(name, mode, dev);
++	if(err)
++		goto out_free;
++
++	err = read_name(inode, name);
++	kfree(name);
++	if(err)
++		goto out_put;
++
++	d_instantiate(dentry, inode);
++	return(0);
++
++ out_free:
++	kfree(name);
++ out_put:
++	iput(inode);
++ out:
++	return(err);
++}
++
++int hostfs_rename(struct inode *from_ino, struct dentry *from,
++		  struct inode *to_ino, struct dentry *to)
++{
++	char *from_name, *to_name;
++	int err;
++
++	if((from_name = inode_dentry_name(from_ino, from)) == NULL)
++		return(-ENOMEM);
++	if((to_name = inode_dentry_name(to_ino, to)) == NULL){
++		kfree(from_name);
++		return(-ENOMEM);
++	}
++	err = rename_file(from_name, to_name);
++	kfree(from_name);
++	kfree(to_name);
++	return(err);
++}
++
++void hostfs_truncate(struct inode *ino)
++{
++	not_implemented();
++}
++
++int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
++{
++	char *name;
++	int r = 0, w = 0, x = 0, err;
++
++	if(desired & MAY_READ) r = 1;
++	if(desired & MAY_WRITE) w = 1;
++	if(desired & MAY_EXEC) x = 1;
++	name = inode_name(ino, 0);
++	if(name == NULL) return(-ENOMEM);
++	err = access_file(name, r, w, x);
++	kfree(name);
++	if(!err) err = vfs_permission(ino, desired);
++	return(err);
++}
++
++int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
++{
++	struct hostfs_iattr attrs;
++	char *name;
++	int err;
++	
++	if(append) 
++		attr->ia_valid &= ~ATTR_SIZE;
++
++	attrs.ia_valid = 0;
++	if(attr->ia_valid & ATTR_MODE){
++		attrs.ia_valid |= HOSTFS_ATTR_MODE;
++		attrs.ia_mode = attr->ia_mode;
++	}
++	if(attr->ia_valid & ATTR_UID){
++		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
++		   (attr->ia_uid == 0))
++			attr->ia_uid = getuid();
++		attrs.ia_valid |= HOSTFS_ATTR_UID;
++		attrs.ia_uid = attr->ia_uid;
++	}
++	if(attr->ia_valid & ATTR_GID){
++		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
++		   (attr->ia_gid == 0))
++			attr->ia_gid = getuid();
++		attrs.ia_valid |= HOSTFS_ATTR_GID;
++		attrs.ia_gid = attr->ia_gid;
++	}
++	if(attr->ia_valid & ATTR_SIZE){
++		attrs.ia_valid |= HOSTFS_ATTR_SIZE;
++		attrs.ia_size = attr->ia_size;
++	}
++	if(attr->ia_valid & ATTR_ATIME){
++		attrs.ia_valid |= HOSTFS_ATTR_ATIME;
++		attrs.ia_atime = attr->ia_atime;
++	}
++	if(attr->ia_valid & ATTR_MTIME){
++		attrs.ia_valid |= HOSTFS_ATTR_MTIME;
++		attrs.ia_mtime = attr->ia_mtime;
++	}
++	if(attr->ia_valid & ATTR_CTIME){
++		attrs.ia_valid |= HOSTFS_ATTR_CTIME;
++		attrs.ia_ctime = attr->ia_ctime;
++	}
++	if(attr->ia_valid & ATTR_ATIME_SET){
++		attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
++	}
++	if(attr->ia_valid & ATTR_MTIME_SET){
++		attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
++	}
++	name = dentry_name(dentry, 0);
++	if(name == NULL) return(-ENOMEM);
++	err = set_attr(name, &attrs);
++	kfree(name);
++	if(err)
++		return(err);
++
++	return(inode_setattr(dentry->d_inode, attr));
++}
++
++int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
++	   struct kstat *stat)
++{
++	generic_fillattr(dentry->d_inode, stat);
++	return(0);
++}
++
++static struct inode_operations hostfs_iops = {
++	.create		= hostfs_create,
++	.link		= hostfs_link,
++	.unlink		= hostfs_unlink,
++	.symlink	= hostfs_symlink,
++	.mkdir		= hostfs_mkdir,
++	.rmdir		= hostfs_rmdir,
++	.mknod		= hostfs_mknod,
++	.rename		= hostfs_rename,
++	.truncate	= hostfs_truncate,
++	.permission	= hostfs_permission,
++	.setattr	= hostfs_setattr,
++	.getattr	= hostfs_getattr,
++};
++
++static struct inode_operations hostfs_dir_iops = {
++	.create		= hostfs_create,
++	.lookup		= hostfs_lookup,
++	.link		= hostfs_link,
++	.unlink		= hostfs_unlink,
++	.symlink	= hostfs_symlink,
++	.mkdir		= hostfs_mkdir,
++	.rmdir		= hostfs_rmdir,
++	.mknod		= hostfs_mknod,
++	.rename		= hostfs_rename,
++	.truncate	= hostfs_truncate,
++	.permission	= hostfs_permission,
++	.setattr	= hostfs_setattr,
++	.getattr	= hostfs_getattr,
++};
++
++int hostfs_link_readpage(struct file *file, struct page *page)
++{
++	char *buffer, *name;
++	long long start;
++	int err;
++
++	start = page->index << PAGE_CACHE_SHIFT;
++	buffer = kmap(page);
++	name = inode_name(page->mapping->host, 0);
++	if(name == NULL) return(-ENOMEM);
++	err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
++	kfree(name);
++	if(err == PAGE_CACHE_SIZE)
++		err = -E2BIG;
++	else if(err > 0){
++		flush_dcache_page(page);
++		SetPageUptodate(page);
++		if (PageError(page)) ClearPageError(page);
++		err = 0;
++	}
++	kunmap(page);
++	unlock_page(page);
++	return(err);
++}
++
++static struct address_space_operations hostfs_link_aops = {
++	.readpage	= hostfs_link_readpage,
++};
++
++static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
++{
++	struct inode *root_inode;
++	char *name, *data = d;
++	int err;
++
++	sb->s_blocksize = 1024;
++	sb->s_blocksize_bits = 10;
++	sb->s_magic = HOSTFS_SUPER_MAGIC;
++	sb->s_op = &hostfs_sbops;
++
++	if((data == NULL) || (*data == '\0')) 
++		data = root_ino;
++
++	err = -ENOMEM;
++	name = kmalloc(strlen(data) + 1, GFP_KERNEL);
++	if(name == NULL) 
++		goto out;
++
++	strcpy(name, data);
++
++	root_inode = iget(sb, 0);
++	if(root_inode == NULL)
++		goto out_free;
++
++	err = init_inode(root_inode, NULL);
++	if(err)
++		goto out_put;
++
++	HOSTFS_I(root_inode)->host_filename = name;
++
++	err = -ENOMEM;
++	sb->s_root = d_alloc_root(root_inode);
++	if(sb->s_root == NULL)
++		goto out_put;
++
++	err = read_inode(root_inode);
++	if(err)
++		goto out_put;
++
++	return(0);
++
++ out_put:
++	iput(root_inode);
++ out_free:
++	kfree(name);
++ out:
++	return(err);
++}
++
++static struct super_block *hostfs_read_sb(struct file_system_type *type,
++					     int flags, const char *dev_name,
++					     void *data)
++{
++	return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
++}
++
++static struct file_system_type hostfs_type = {
++	.owner 		= THIS_MODULE,
++	.name 		= "hostfs",
++	.get_sb 	= hostfs_read_sb,
++	.kill_sb	= kill_anon_super,
++	.fs_flags 	= 0,
++};
++
++static int __init init_hostfs(void)
++{
++	return(register_filesystem(&hostfs_type));
++}
++
++static void __exit exit_hostfs(void)
++{
++	unregister_filesystem(&hostfs_type);
++}
++
++module_init(init_hostfs)
++module_exit(exit_hostfs)
++MODULE_LICENSE("GPL");
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
+--- a/fs/hostfs/hostfs_user.c	Wed Dec 31 19:00:00 1969
++++ b/fs/hostfs/hostfs_user.c	Tue Sep  9 16:47:43 2003
+@@ -0,0 +1,361 @@
++/* 
++ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#include <unistd.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <dirent.h>
++#include <errno.h>
++#include <utime.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/time.h>
++#include <sys/vfs.h>
++#include "hostfs.h"
++#include "kern_util.h"
++#include "user.h"
++
++int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
++	      int *nlink_out, int *uid_out, int *gid_out, 
++	      unsigned long long *size_out, struct timespec *atime_out,
++	      struct timespec *mtime_out, struct timespec *ctime_out,
++	      int *blksize_out, unsigned long long *blocks_out)
++{
++	struct stat64 buf;
++
++	if(lstat64(path, &buf) < 0) 
++		return(-errno);
++
++	/* See the Makefile for why STAT64_INO_FIELD is passed in
++	 * by the build
++	 */
++	if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
++	if(mode_out != NULL) *mode_out = buf.st_mode;
++	if(nlink_out != NULL) *nlink_out = buf.st_nlink;
++	if(uid_out != NULL) *uid_out = buf.st_uid;
++	if(gid_out != NULL) *gid_out = buf.st_gid;
++	if(size_out != NULL) *size_out = buf.st_size;
++	if(atime_out != NULL) {
++		atime_out->tv_sec = buf.st_atime;
++		atime_out->tv_nsec = 0;
++	}
++	if(mtime_out != NULL) {
++		mtime_out->tv_sec = buf.st_mtime;
++		mtime_out->tv_nsec = 0;
++	}
++	if(ctime_out != NULL) {
++		ctime_out->tv_sec = buf.st_ctime;
++		ctime_out->tv_nsec = 0;
++	}
++	if(blksize_out != NULL) *blksize_out = buf.st_blksize;
++	if(blocks_out != NULL) *blocks_out = buf.st_blocks;
++	return(0);
++}
++
++int file_type(const char *path, int *rdev)
++{
++ 	struct stat64 buf;
++
++	if(lstat64(path, &buf) < 0) 
++		return(-errno);
++	if(rdev != NULL) 
++		*rdev = buf.st_rdev;
++
++	if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
++	else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
++	else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
++	else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
++	else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
++	else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
++	else return(OS_TYPE_FILE);
++}
++
++int access_file(char *path, int r, int w, int x)
++{
++	int mode = 0;
++
++	if(r) mode = R_OK;
++	if(w) mode |= W_OK;
++	if(x) mode |= X_OK;
++	if(access(path, mode) != 0) return(-errno);
++	else return(0);
++}
++
++int open_file(char *path, int r, int w, int append)
++{
++	int mode = 0, fd;
++
++	if(r && !w) 
++		mode = O_RDONLY;
++	else if(!r && w) 
++		mode = O_WRONLY;
++	else if(r && w) 
++		mode = O_RDWR;
++	else panic("Impossible mode in open_file");
++
++	if(append)
++		mode |= O_APPEND;
++	fd = open64(path, mode);
++	if(fd < 0) return(-errno);
++	else return(fd);
++}
++
++void *open_dir(char *path, int *err_out)
++{
++	DIR *dir;
++
++	dir = opendir(path);
++	*err_out = errno;
++	if(dir == NULL) return(NULL);
++	return(dir);
++}
++
++char *read_dir(void *stream, unsigned long long *pos, 
++	       unsigned long long *ino_out, int *len_out)
++{
++	DIR *dir = stream;
++	struct dirent *ent;
++
++	seekdir(dir, *pos);
++	ent = readdir(dir);
++	if(ent == NULL) return(NULL);
++	*len_out = strlen(ent->d_name);
++	*ino_out = ent->d_ino;
++	*pos = telldir(dir);
++	return(ent->d_name);
++}
++
++int read_file(int fd, unsigned long long *offset, char *buf, int len)
++{
++	int n;
++
++	n = pread64(fd, buf, len, *offset);
++	if(n < 0) return(-errno);
++	*offset += n;
++	return(n);
++}
++
++int write_file(int fd, unsigned long long *offset, const char *buf, int len)
++{
++	int n;
++
++	n = pwrite64(fd, buf, len, *offset);
++	if(n < 0) return(-errno);
++	*offset += n;
++	return(n);
++}
++
++int lseek_file(int fd, long long offset, int whence)
++{
++	int ret;
++
++	ret = lseek64(fd, offset, whence);
++	if(ret < 0) return(-errno);
++	return(0);
++}
++
++void close_file(void *stream)
++{
++	close(*((int *) stream));
++}
++
++void close_dir(void *stream)
++{
++	closedir(stream);
++}
++
++int file_create(char *name, int ur, int uw, int ux, int gr, 
++		int gw, int gx, int or, int ow, int ox)
++{
++	int mode, fd;
++
++	mode = 0;
++	mode |= ur ? S_IRUSR : 0;
++	mode |= uw ? S_IWUSR : 0;
++	mode |= ux ? S_IXUSR : 0;
++	mode |= gr ? S_IRGRP : 0;
++	mode |= gw ? S_IWGRP : 0;
++	mode |= gx ? S_IXGRP : 0;
++	mode |= or ? S_IROTH : 0;
++	mode |= ow ? S_IWOTH : 0;
++	mode |= ox ? S_IXOTH : 0;
++	fd = open64(name, O_CREAT | O_RDWR, mode);
++	if(fd < 0) 
++		return(-errno);
++	return(fd);
++}
++
++int set_attr(const char *file, struct hostfs_iattr *attrs)
++{
++	struct utimbuf buf;
++	int err, ma;
++
++	if(attrs->ia_valid & HOSTFS_ATTR_MODE){
++		if(chmod(file, attrs->ia_mode) != 0) return(-errno);
++	}
++	if(attrs->ia_valid & HOSTFS_ATTR_UID){
++		if(chown(file, attrs->ia_uid, -1)) return(-errno);
++	}
++	if(attrs->ia_valid & HOSTFS_ATTR_GID){
++		if(chown(file, -1, attrs->ia_gid)) return(-errno);
++	}
++	if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
++		if(truncate(file, attrs->ia_size)) return(-errno);
++	}
++	ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
++	if((attrs->ia_valid & ma) == ma){
++		buf.actime = attrs->ia_atime.tv_sec;
++		buf.modtime = attrs->ia_mtime.tv_sec;
++		if(utime(file, &buf) != 0) return(-errno);
++	}
++	else {
++		struct timespec ts;
++
++		if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
++			err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
++					NULL, NULL, &ts, NULL, NULL, NULL);
++			if(err != 0) 
++				return(err);
++			buf.actime = attrs->ia_atime.tv_sec;
++			buf.modtime = ts.tv_sec;
++			if(utime(file, &buf) != 0) 
++				return(-errno);
++		}
++		if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
++			err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
++					NULL, &ts, NULL, NULL, NULL, NULL);
++			if(err != 0) 
++				return(err);
++			buf.actime = ts.tv_sec;
++			buf.modtime = attrs->ia_mtime.tv_sec;
++			if(utime(file, &buf) != 0) 
++				return(-errno);
++		}
++	}
++	if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
++	if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
++		err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
++				&attrs->ia_atime, &attrs->ia_mtime, NULL, 
++				NULL, NULL);
++		if(err != 0) return(err);
++	}
++	return(0);
++}
++
++int make_symlink(const char *from, const char *to)
++{
++	int err;
++
++	err = symlink(to, from);
++	if(err) return(-errno);
++	return(0);
++}
++
++int unlink_file(const char *file)
++{
++	int err;
++
++	err = unlink(file);
++	if(err) return(-errno);
++	return(0);
++}
++
++int do_mkdir(const char *file, int mode)
++{
++	int err;
++
++	err = mkdir(file, mode);
++	if(err) return(-errno);
++	return(0);
++}
++
++int do_rmdir(const char *file)
++{
++	int err;
++
++	err = rmdir(file);
++	if(err) return(-errno);
++	return(0);
++}
++
++int do_mknod(const char *file, int mode, int dev)
++{
++	int err;
++
++	err = mknod(file, mode, dev);
++	if(err) return(-errno);
++	return(0);
++}
++
++int link_file(const char *to, const char *from)
++{
++	int err;
++
++	err = link(to, from);
++	if(err) return(-errno);
++	return(0);
++}
++
++int do_readlink(char *file, char *buf, int size)
++{
++	int n;
++
++	n = readlink(file, buf, size);
++	if(n < 0) 
++		return(-errno);
++	if(n < size) 
++		buf[n] = '\0';
++	return(n);
++}
++
++int rename_file(char *from, char *to)
++{
++	int err;
++
++	err = rename(from, to);
++	if(err < 0) return(-errno);
++	return(0);	
++}
++
++int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
++	      long long *bfree_out, long long *bavail_out, 
++	      long long *files_out, long long *ffree_out,
++	      void *fsid_out, int fsid_size, long *namelen_out, 
++	      long *spare_out)
++{
++	struct statfs64 buf;
++	int err;
++
++	err = statfs64(root, &buf);
++	if(err < 0) return(-errno);
++	*bsize_out = buf.f_bsize;
++	*blocks_out = buf.f_blocks;
++	*bfree_out = buf.f_bfree;
++	*bavail_out = buf.f_bavail;
++	*files_out = buf.f_files;
++	*ffree_out = buf.f_ffree;
++	memcpy(fsid_out, &buf.f_fsid, 
++	       sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
++	       sizeof(buf.f_fsid));
++	*namelen_out = buf.f_namelen;
++	spare_out[0] = buf.f_spare[0];
++	spare_out[1] = buf.f_spare[1];
++	spare_out[2] = buf.f_spare[2];
++	spare_out[3] = buf.f_spare[3];
++	spare_out[4] = buf.f_spare[4];
++	spare_out[5] = buf.f_spare[5];
++	return(0);
++}
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
+--- a/fs/hppfs/Makefile	Wed Dec 31 19:00:00 1969
++++ b/fs/hppfs/Makefile	Tue Sep  9 16:49:04 2003
+@@ -0,0 +1,19 @@
++# 
++# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
++# Licensed under the GPL
++#
++
++hppfs-objs := hppfs_kern.o
++
++obj-y = 
++obj-$(CONFIG_HPPFS) += hppfs.o
++
++clean:
++
++modules:
++
++fastdep:
++
++dep:
++
++archmrproper: clean
+diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
+--- a/fs/hppfs/hppfs_kern.c	Wed Dec 31 19:00:00 1969
++++ b/fs/hppfs/hppfs_kern.c	Tue Sep  9 16:48:52 2003
+@@ -0,0 +1,811 @@
++/* 
++ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/kernel.h>
++#include <linux/ctype.h>
++#include <linux/dcache.h>
++#include <linux/statfs.h>
++#include <asm/uaccess.h>
++#include <asm/fcntl.h>
++#include "os.h"
++
++static int init_inode(struct inode *inode, struct dentry *dentry);
++
++struct hppfs_data {
++	struct list_head list;
++	char contents[PAGE_SIZE - sizeof(struct list_head)];
++};
++
++struct hppfs_private {
++	struct file proc_file;
++	int host_fd;
++	loff_t len;
++	struct hppfs_data *contents;
++};
++
++struct hppfs_inode_info {
++        struct dentry *proc_dentry;
++	struct inode vfs_inode;
++};
++
++static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
++{
++	return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
++}
++
++#define HPPFS_SUPER_MAGIC 0xb00000ee
++
++static struct super_operations hppfs_sbops;
++
++static int is_pid(struct dentry *dentry)
++{
++	struct super_block *sb;
++	int i;
++
++	sb = dentry->d_sb;
++	if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
++		return(0);
++
++	for(i = 0; i < dentry->d_name.len; i++){
++		if(!isdigit(dentry->d_name.name[i]))
++			return(0);
++	}
++	return(1);
++}
++
++static char *dentry_name(struct dentry *dentry, int extra)
++{
++	struct dentry *parent;
++	char *root, *name;
++	const char *seg_name;
++	int len, seg_len;
++
++	len = 0;
++	parent = dentry;
++	while(parent->d_parent != parent){
++		if(is_pid(parent))
++			len += strlen("pid") + 1;
++		else len += parent->d_name.len + 1;
++		parent = parent->d_parent;
++	}
++	
++	root = "proc";
++	len += strlen(root);
++	name = kmalloc(len + extra + 1, GFP_KERNEL);
++	if(name == NULL) return(NULL);
++
++	name[len] = '\0';
++	parent = dentry;
++	while(parent->d_parent != parent){
++		if(is_pid(parent)){
++			seg_name = "pid";
++			seg_len = strlen("pid");
++		}
++		else {
++			seg_name = parent->d_name.name;
++			seg_len = parent->d_name.len;
++		}
++
++		len -= seg_len + 1;
++		name[len] = '/';
++		strncpy(&name[len + 1], seg_name, seg_len);
++		parent = parent->d_parent;
++	}
++	strncpy(name, root, strlen(root));
++	return(name);
++}
++
++struct dentry_operations hppfs_dentry_ops = {
++};
++
++static int file_removed(struct dentry *dentry, const char *file)
++{
++	char *host_file;
++	int extra, fd;
++
++	extra = 0;
++	if(file != NULL) extra += strlen(file) + 1;
++
++	host_file = dentry_name(dentry, extra + strlen("/remove"));
++	if(host_file == NULL){
++		printk("file_removed : allocation failed\n");
++		return(-ENOMEM);
++	}
++
++	if(file != NULL){
++		strcat(host_file, "/");
++		strcat(host_file, file);
++	}
++	strcat(host_file, "/remove");
++
++	fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
++	kfree(host_file);
++	if(fd > 0){
++		os_close_file(fd);
++		return(1);
++	}
++	return(0);
++}
++
++static void hppfs_read_inode(struct inode *ino)
++{
++	struct inode *proc_ino;
++
++	if(HPPFS_I(ino)->proc_dentry == NULL)
++		return;
++
++	proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
++	ino->i_uid = proc_ino->i_uid;
++	ino->i_gid = proc_ino->i_gid;
++	ino->i_atime = proc_ino->i_atime;
++	ino->i_mtime = proc_ino->i_mtime;
++	ino->i_ctime = proc_ino->i_ctime;
++	ino->i_ino = proc_ino->i_ino;
++	ino->i_mode = proc_ino->i_mode;
++	ino->i_nlink = proc_ino->i_nlink;
++	ino->i_size = proc_ino->i_size;
++	ino->i_blksize = proc_ino->i_blksize;
++	ino->i_blocks = proc_ino->i_blocks;
++}
++
++static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
++                                  struct nameidata *nd)
++{
++	struct dentry *proc_dentry, *new, *parent;
++	struct inode *inode;
++	int err, deleted;
++
++	deleted = file_removed(dentry, NULL);
++	if(deleted < 0)
++		return(ERR_PTR(deleted));
++	else if(deleted)
++		return(ERR_PTR(-ENOENT));
++
++	err = -ENOMEM;
++	parent = HPPFS_I(ino)->proc_dentry;
++	down(&parent->d_inode->i_sem);
++	proc_dentry = d_lookup(parent, &dentry->d_name);
++	if(proc_dentry == NULL){
++		proc_dentry = d_alloc(parent, &dentry->d_name);
++		if(proc_dentry == NULL){
++			up(&parent->d_inode->i_sem);
++			goto out;
++		}
++		new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
++						       proc_dentry, NULL);
++		if(new){
++			dput(proc_dentry);
++			proc_dentry = new;
++		}
++	}
++	up(&parent->d_inode->i_sem);
++
++	if(IS_ERR(proc_dentry))
++		return(proc_dentry);
++
++	inode = iget(ino->i_sb, 0);
++	if(inode == NULL) 
++		goto out_dput;
++
++	err = init_inode(inode, proc_dentry);
++	if(err) 
++		goto out_put;
++	
++	hppfs_read_inode(inode);
++
++ 	d_add(dentry, inode);
++	dentry->d_op = &hppfs_dentry_ops;
++	return(NULL);
++
++ out_put:
++	iput(inode);
++ out_dput:
++	dput(proc_dentry);
++ out:
++	return(ERR_PTR(err));
++}
++
++static struct inode_operations hppfs_file_iops = {
++};
++
++static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
++			 loff_t *ppos, int is_user)
++{
++	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
++	ssize_t n;
++
++	read = file->f_dentry->d_inode->i_fop->read;
++
++	if(!is_user)
++		set_fs(KERNEL_DS);
++		
++	n = (*read)(file, buf, count, &file->f_pos);
++
++	if(!is_user)
++		set_fs(USER_DS);
++
++	if(ppos) *ppos = file->f_pos;
++	return(n);
++}
++
++static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
++{
++	ssize_t n;
++	int cur, err;
++	char *new_buf;
++
++	n = -ENOMEM;
++	new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
++	if(new_buf == NULL){
++		printk("hppfs_read_file : kmalloc failed\n");
++		goto out;
++	}
++	n = 0;
++	while(count > 0){
++		cur = min_t(ssize_t, count, PAGE_SIZE);
++		err = os_read_file(fd, new_buf, cur);
++		if(err < 0){
++			printk("hppfs_read : read failed, errno = %d\n",
++			       count);
++			n = err;
++			goto out_free;
++		}
++		else if(err == 0)
++			break;
++
++		if(copy_to_user(buf, new_buf, err)){
++			n = -EFAULT;
++			goto out_free;
++		}
++		n += err;
++		count -= err;
++	}
++ out_free:
++	kfree(new_buf);
++ out:
++	return(n);
++}
++
++static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
++			  loff_t *ppos)
++{
++	struct hppfs_private *hppfs = file->private_data;
++	struct hppfs_data *data;
++	loff_t off;
++	int err;
++
++	if(hppfs->contents != NULL){
++		if(*ppos >= hppfs->len) return(0);
++
++		data = hppfs->contents;
++		off = *ppos;
++		while(off >= sizeof(data->contents)){
++			data = list_entry(data->list.next, struct hppfs_data,
++					  list);
++			off -= sizeof(data->contents);
++		}
++
++		if(off + count > hppfs->len)
++			count = hppfs->len - off;
++		copy_to_user(buf, &data->contents[off], count);
++		*ppos += count;
++	}
++	else if(hppfs->host_fd != -1){
++		err = os_seek_file(hppfs->host_fd, *ppos);
++		if(err){
++			printk("hppfs_read : seek failed, errno = %d\n", err);
++			return(err);
++		}
++		count = hppfs_read_file(hppfs->host_fd, buf, count);
++		if(count > 0)
++			*ppos += count;
++	}
++	else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
++
++	return(count);
++}
++
++static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
++			   loff_t *ppos)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = &data->proc_file;
++	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
++	int err;
++
++	write = proc_file->f_dentry->d_inode->i_fop->write;
++
++	proc_file->f_pos = file->f_pos;
++	err = (*write)(proc_file, buf, len, &proc_file->f_pos);
++	file->f_pos = proc_file->f_pos;
++
++	return(err);
++}
++
++static int open_host_sock(char *host_file, int *filter_out)
++{
++	char *end;
++	int fd;
++
++	end = &host_file[strlen(host_file)];
++	strcpy(end, "/rw");
++	*filter_out = 1;
++	fd = os_connect_socket(host_file);
++	if(fd > 0)
++		return(fd);
++
++	strcpy(end, "/r");
++	*filter_out = 0;
++	fd = os_connect_socket(host_file);
++	return(fd);
++}
++
++static void free_contents(struct hppfs_data *head)
++{
++	struct hppfs_data *data;
++	struct list_head *ele, *next;
++
++	if(head == NULL) return;
++
++	list_for_each_safe(ele, next, &head->list){
++		data = list_entry(ele, struct hppfs_data, list);
++		kfree(data);
++	}
++	kfree(head);
++}
++
++static struct hppfs_data *hppfs_get_data(int fd, int filter, 
++					 struct file *proc_file, 
++					 struct file *hppfs_file, 
++					 loff_t *size_out)
++{
++	struct hppfs_data *data, *new, *head;
++	int n, err;
++
++	err = -ENOMEM;
++	data = kmalloc(sizeof(*data), GFP_KERNEL);
++	if(data == NULL){
++		printk("hppfs_get_data : head allocation failed\n");
++		goto failed;
++	}
++
++	INIT_LIST_HEAD(&data->list);
++
++	head = data;
++	*size_out = 0;
++
++	if(filter){
++		while((n = read_proc(proc_file, data->contents,
++				     sizeof(data->contents), NULL, 0)) > 0)
++			os_write_file(fd, data->contents, n);
++		err = os_shutdown_socket(fd, 0, 1);
++		if(err){
++			printk("hppfs_get_data : failed to shut down "
++			       "socket\n");
++			goto failed_free;
++		}
++	}
++	while(1){
++		n = os_read_file(fd, data->contents, sizeof(data->contents));
++		if(n < 0){
++			err = n;
++			printk("hppfs_get_data : read failed, errno = %d\n",
++			       err);
++			goto failed_free;
++		}
++		else if(n == 0)
++			break;
++
++		*size_out += n;
++
++		if(n < sizeof(data->contents))
++			break;
++
++		new = kmalloc(sizeof(*data), GFP_KERNEL);
++		if(new == 0){
++			printk("hppfs_get_data : data allocation failed\n");
++			err = -ENOMEM;
++			goto failed_free;
++		}
++	
++		INIT_LIST_HEAD(&new->list);
++		list_add(&new->list, &data->list);
++		data = new;
++	}
++	return(head);
++
++ failed_free:
++	free_contents(head);
++ failed:		
++	return(ERR_PTR(err));
++}
++
++static struct hppfs_private *hppfs_data(void)
++{
++	struct hppfs_private *data;
++
++	data = kmalloc(sizeof(*data), GFP_KERNEL);
++	if(data == NULL)
++		return(data);
++
++	*data = ((struct hppfs_private ) { .host_fd  		= -1,
++					   .len  		= -1,
++					   .contents 		= NULL } );
++	return(data);
++}
++
++static int file_mode(int fmode)
++{
++	if(fmode == (FMODE_READ | FMODE_WRITE))
++		return(O_RDWR);
++	if(fmode == FMODE_READ)
++		return(O_RDONLY);
++	if(fmode == FMODE_WRITE)
++		return(O_WRONLY);
++	return(0);
++}
++
++static int hppfs_open(struct inode *inode, struct file *file)
++{
++	struct hppfs_private *data;
++	struct dentry *proc_dentry;
++	char *host_file;
++	int err, fd, type, filter;
++
++	err = -ENOMEM;
++	data = hppfs_data();
++	if(data == NULL)
++		goto out;
++
++	host_file = dentry_name(file->f_dentry, strlen("/rw"));
++	if(host_file == NULL)
++		goto out_free2;
++
++	proc_dentry = HPPFS_I(inode)->proc_dentry;
++
++	/* XXX This isn't closed anywhere */
++	err = open_private_file(&data->proc_file, proc_dentry, 
++				file_mode(file->f_mode));
++	if(err)
++		goto out_free1;
++
++	type = os_file_type(host_file);
++	if(type == OS_TYPE_FILE){
++		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
++		if(fd >= 0) 
++			data->host_fd = fd;
++		else printk("hppfs_open : failed to open '%s', errno = %d\n",
++			    host_file, -fd);
++
++		data->contents = NULL;
++	}
++	else if(type == OS_TYPE_DIR){
++		fd = open_host_sock(host_file, &filter);
++		if(fd > 0){
++			data->contents = hppfs_get_data(fd, filter, 
++							&data->proc_file, 
++							file, &data->len);
++			if(!IS_ERR(data->contents))
++				data->host_fd = fd;
++		}
++		else printk("hppfs_open : failed to open a socket in "
++			    "'%s', errno = %d\n", host_file, -fd);
++	}
++	kfree(host_file);
++
++	file->private_data = data;
++	return(0);
++
++ out_free1:
++	kfree(host_file);
++ out_free2:
++	free_contents(data->contents);
++	kfree(data);
++ out:
++	return(err);
++}
++
++static int hppfs_dir_open(struct inode *inode, struct file *file)
++{
++	struct hppfs_private *data;
++	struct dentry *proc_dentry;
++	int err;
++
++	err = -ENOMEM;
++	data = hppfs_data();
++	if(data == NULL)
++		goto out;
++
++	proc_dentry = HPPFS_I(inode)->proc_dentry;
++	err = open_private_file(&data->proc_file, proc_dentry, 
++				file_mode(file->f_mode));
++	if(err)
++		goto out_free;
++
++	file->private_data = data;
++	return(0);
++
++ out_free:
++	kfree(data);
++ out:
++	return(err);
++}
++
++static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = &data->proc_file;
++	loff_t (*llseek)(struct file *, loff_t, int);
++	loff_t ret;
++
++	llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
++	if(llseek != NULL){
++		ret = (*llseek)(proc_file, off, where);
++		if(ret < 0)
++			return(ret);
++	}
++
++	return(default_llseek(file, off, where));
++}
++
++static struct file_operations hppfs_file_fops = {
++	.owner		= NULL,
++	.llseek		= hppfs_llseek,
++	.read		= hppfs_read,
++	.write		= hppfs_write,
++	.open		= hppfs_open,
++};
++
++struct hppfs_dirent {
++	void *vfs_dirent;
++	filldir_t filldir;
++	struct dentry *dentry;
++};
++
++static int hppfs_filldir(void *d, const char *name, int size, 
++			 loff_t offset, ino_t inode, unsigned int type)
++{
++	struct hppfs_dirent *dirent = d;
++
++	if(file_removed(dirent->dentry, name))
++		return(0);
++
++	return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
++				  inode, type));
++}
++
++static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = &data->proc_file;
++	int (*readdir)(struct file *, void *, filldir_t);
++	struct hppfs_dirent dirent = ((struct hppfs_dirent)
++		                      { .vfs_dirent  	= ent,
++					.filldir 	= filldir,
++					.dentry  	= file->f_dentry } );
++	int err;
++
++	readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
++
++	proc_file->f_pos = file->f_pos;
++	err = (*readdir)(proc_file, &dirent, hppfs_filldir);
++	file->f_pos = proc_file->f_pos;
++
++	return(err);
++}
++
++static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
++{
++	return(0);
++}
++
++static struct file_operations hppfs_dir_fops = {
++	.owner		= NULL,
++	.readdir	= hppfs_readdir,
++	.open		= hppfs_dir_open,
++	.fsync		= hppfs_fsync,
++};
++
++static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
++{
++	sf->f_blocks = 0;
++	sf->f_bfree = 0;
++	sf->f_bavail = 0;
++	sf->f_files = 0;
++	sf->f_ffree = 0;
++	sf->f_type = HPPFS_SUPER_MAGIC;
++	return(0);
++}
++
++static struct inode *hppfs_alloc_inode(struct super_block *sb)
++{
++	struct hppfs_inode_info *hi;
++
++	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
++	if(hi == NULL) 
++		return(NULL);
++
++	*hi = ((struct hppfs_inode_info) { .proc_dentry	= NULL });
++	inode_init_once(&hi->vfs_inode);
++	return(&hi->vfs_inode);
++}
++
++void hppfs_delete_inode(struct inode *ino)
++{
++	clear_inode(ino);
++}
++
++static void hppfs_destroy_inode(struct inode *inode)
++{
++	kfree(HPPFS_I(inode));
++}
++
++static struct super_operations hppfs_sbops = { 
++	.alloc_inode	= hppfs_alloc_inode,
++	.destroy_inode	= hppfs_destroy_inode,
++	.read_inode	= hppfs_read_inode,
++	.delete_inode	= hppfs_delete_inode,
++	.statfs		= hppfs_statfs,
++};
++
++static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
++{
++	struct file proc_file;
++	struct dentry *proc_dentry;
++	int (*readlink)(struct dentry *, char *, int);
++	int err, n;
++
++	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
++	err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
++	if(err) 
++		return(err);
++
++	readlink = proc_dentry->d_inode->i_op->readlink;
++	n = (*readlink)(proc_dentry, buffer, buflen);
++
++	close_private_file(&proc_file);
++	
++	return(n);
++}
++
++static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++	struct file proc_file;
++	struct dentry *proc_dentry;
++	int (*follow_link)(struct dentry *, struct nameidata *);
++	int err, n;
++
++	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
++	err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
++	if(err) 
++		return(err);
++
++	follow_link = proc_dentry->d_inode->i_op->follow_link;
++	n = (*follow_link)(proc_dentry, nd);
++
++	close_private_file(&proc_file);
++	
++	return(n);
++}
++
++static struct inode_operations hppfs_dir_iops = {
++	.lookup		= hppfs_lookup,
++};
++
++static struct inode_operations hppfs_link_iops = {
++	.readlink	= hppfs_readlink,
++	.follow_link	= hppfs_follow_link,
++};
++
++static int init_inode(struct inode *inode, struct dentry *dentry)
++{
++	if(S_ISDIR(dentry->d_inode->i_mode)){
++		inode->i_op = &hppfs_dir_iops;
++		inode->i_fop = &hppfs_dir_fops;
++	}
++	else if(S_ISLNK(dentry->d_inode->i_mode)){
++		inode->i_op = &hppfs_link_iops;
++		inode->i_fop = &hppfs_file_fops;
++	}
++	else {
++		inode->i_op = &hppfs_file_iops;
++		inode->i_fop = &hppfs_file_fops;
++	}
++
++	HPPFS_I(inode)->proc_dentry = dentry;
++
++	return(0);
++}
++
++static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
++{
++	struct inode *root_inode;
++	struct file_system_type *procfs;
++	struct super_block *proc_sb;
++	int err;
++
++	err = -ENOENT;
++	procfs = get_fs_type("proc");
++	if(procfs == NULL) 
++		goto out;
++
++	if(list_empty(&procfs->fs_supers))
++		goto out;
++
++	proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
++			     s_instances);
++	
++	sb->s_blocksize = 1024;
++	sb->s_blocksize_bits = 10;
++	sb->s_magic = HPPFS_SUPER_MAGIC;
++	sb->s_op = &hppfs_sbops;
++
++	root_inode = iget(sb, 0);
++	if(root_inode == NULL)
++		goto out;
++
++	err = init_inode(root_inode, proc_sb->s_root);
++	if(err)
++		goto out_put;
++
++	err = -ENOMEM;
++	sb->s_root = d_alloc_root(root_inode);
++	if(sb->s_root == NULL)
++		goto out_put;
++
++	hppfs_read_inode(root_inode);
++
++	return(0);
++
++ out_put:
++	iput(root_inode);
++ out:
++	return(err);
++}
++
++static struct super_block *hppfs_read_super(struct file_system_type *type,
++					     int flags, const char *dev_name,
++					     void *data)
++{
++	return(get_sb_nodev(type, flags, data, hppfs_fill_super));
++}
++
++static struct file_system_type hppfs_type = {
++	.owner 		= THIS_MODULE,
++	.name 		= "hppfs",
++	.get_sb 	= hppfs_read_super,
++	.kill_sb	= kill_anon_super,
++	.fs_flags 	= 0,
++};
++
++static int __init init_hppfs(void)
++{
++	return(register_filesystem(&hppfs_type));
++}
++
++static void __exit exit_hppfs(void)
++{
++	unregister_filesystem(&hppfs_type);
++}
++
++module_init(init_hppfs)
++module_exit(exit_hppfs)
++MODULE_LICENSE("GPL");
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
+--- a/include/asm-um/archparam-i386.h	Tue Sep  9 16:45:45 2003
++++ b/include/asm-um/archparam-i386.h	Tue Sep  9 16:50:12 2003
+@@ -56,6 +56,65 @@
+ 	pr_reg[16] = PT_REGS_SS(regs);		\
+ } while(0);
+ 
++#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
++#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
++#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
++extern void *__kernel_vsyscall;
++
++/*
++ * Architecture-neutral AT_ values in 0-17, leave some room
++ * for more of them, start the x86-specific ones at 32.
++ */
++#define AT_SYSINFO		32
++#define AT_SYSINFO_EHDR		33
++
++#define ARCH_DLINFO						\
++do {								\
++		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
++		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
++} while (0)
++
++/*
++ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
++ * extra segments containing the vsyscall DSO contents.  Dumping its
++ * contents makes post-mortem fully interpretable later without matching up
++ * the same kernel and hardware config to see what PC values meant.
++ * Dumping its extra ELF program headers includes all the other information
++ * a debugger needs to easily find how the vsyscall DSO was being used.
++ */
++#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
++#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
++do {									      \
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (VSYSCALL_BASE		      \
++					   + VSYSCALL_EHDR->e_phoff);	      \
++	int i;								      \
++	Elf32_Off ofs = 0;						      \
++	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
++		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
++		if (phdr.p_type == PT_LOAD) {				      \
++			ofs = phdr.p_offset = offset;			      \
++			offset += phdr.p_filesz;			      \
++		}							      \
++		else							      \
++			phdr.p_offset += ofs;				      \
++		phdr.p_paddr = 0; /* match other core phdrs */		      \
++		DUMP_WRITE(&phdr, sizeof(phdr));			      \
++	}								      \
++} while (0)
++#define ELF_CORE_WRITE_EXTRA_DATA					      \
++do {									      \
++	const struct elf_phdr *const vsyscall_phdrs =			      \
++		(const struct elf_phdr *) (VSYSCALL_BASE		      \
++					   + VSYSCALL_EHDR->e_phoff);	      \
++	int i;								      \
++	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
++		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
++			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
++				   vsyscall_phdrs[i].p_filesz);		      \
++	}								      \
++} while (0)
++
+ /********* Bits for asm-um/delay.h **********/
+ 
+ typedef unsigned long um_udelay_t;
+diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
+--- a/include/asm-um/common.lds.S	Tue Sep  9 16:41:45 2003
++++ b/include/asm-um/common.lds.S	Tue Sep  9 16:47:55 2003
+@@ -1,3 +1,5 @@
++#include <asm-generic/vmlinux.lds.h>
++
+   .fini      : { *(.fini)    } =0x9090
+   _etext = .;
+   PROVIDE (etext = .);
+@@ -67,6 +69,10 @@
+   }
+   __initcall_end = .;
+ 
++  __con_initcall_start = .;
++  .con_initcall.init : { *(.con_initcall.init) }
++  __con_initcall_end = .;
++
+   __uml_initcall_start = .;
+   .uml.initcall.init : { *(.uml.initcall.init) }
+   __uml_initcall_end = .;
+@@ -80,7 +86,33 @@
+   .uml.exitcall : { *(.uml.exitcall.exit) }
+   __uml_exitcall_end = .;
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(4);
++  __alt_instructions = .;
++  .altinstructions : { *(.altinstructions) } 
++  __alt_instructions_end = .; 
++  .altinstr_replacement : { *(.altinstr_replacement) } 
++  /* .exit.text is discard at runtime, not link time, to deal with references
++     from .altinstructions and .eh_frame */
++  .exit.text : { *(.exit.text) }
++  .exit.data : { *(.exit.data) }
++ 
++  __preinit_array_start = .;
++  .preinit_array : { *(.preinit_array) }
++  __preinit_array_end = .;
++  __init_array_start = .;
++  .init_array : { *(.init_array) }
++  __init_array_end = .;
++  __fini_array_start = .;
++  .fini_array : { *(.fini_array) }
++  __fini_array_end = .;
++
++   . = ALIGN(4096);
+   __initramfs_start = .;
+   .init.ramfs : { *(.init.ramfs) }
+   __initramfs_end = .;
++
++  /* Sections to be discarded */
++  /DISCARD/ : {
++ 	*(.exitcall.exit)
++  }
++ 
+diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
+--- a/include/asm-um/cpufeature.h	Wed Dec 31 19:00:00 1969
++++ b/include/asm-um/cpufeature.h	Tue Sep  9 16:47:22 2003
+@@ -0,0 +1,6 @@
++#ifndef __UM_CPUFEATURE_H
++#define __UM_CPUFEATURE_H
++
++#include "asm/arch/cpufeature.h"
++
++#endif
+diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
+--- a/include/asm-um/current.h	Tue Sep  9 16:41:22 2003
++++ b/include/asm-um/current.h	Tue Sep  9 16:47:29 2003
+@@ -16,8 +16,10 @@
+ #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
+ 			        (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
+ 
+-#define current ({ int dummy; \
+-                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
++#define current_thread \
++	({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
++
++#define current (current_thread->task)
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
+--- a/include/asm-um/fixmap.h	Tue Sep  9 16:46:00 2003
++++ b/include/asm-um/fixmap.h	Tue Sep  9 16:51:02 2003
+@@ -34,6 +34,7 @@
+ 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+ 	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ #endif
++	FIX_VSYSCALL,
+ 	__end_of_fixed_addresses
+ };
+ 
+@@ -63,6 +64,13 @@
+ #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+ #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+ 
++/*
++ * This is the range that is readable by user mode, and things
++ * acting like user mode such as get_user_pages.
++ */
++#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
++#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
++
+ extern void __this_fixmap_does_not_exist(void);
+ 
+ /*
+diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
+--- a/include/asm-um/irq.h	Tue Sep  9 16:46:09 2003
++++ b/include/asm-um/irq.h	Tue Sep  9 16:51:12 2003
+@@ -1,15 +1,6 @@
+ #ifndef __UM_IRQ_H
+ #define __UM_IRQ_H
+ 
+-/* The i386 irq.h has a struct task_struct in a prototype without including
+- * sched.h.  This forward declaration kills the resulting warning.
+- */
+-struct task_struct;
+-
+-#include "asm/ptrace.h"
+-
+-#undef NR_IRQS
+-
+ #define TIMER_IRQ		0
+ #define UMN_IRQ			1
+ #define CONSOLE_IRQ		2
+@@ -28,8 +19,4 @@
+ #define LAST_IRQ XTERM_IRQ
+ #define NR_IRQS (LAST_IRQ + 1)
+ 
+-extern int um_request_irq(unsigned int irq, int fd, int type,
+-			  void (*handler)(int, void *, struct pt_regs *),
+-			  unsigned long irqflags,  const char * devname,
+-			  void *dev_id);
+ #endif
+diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
+--- a/include/asm-um/local.h	Wed Dec 31 19:00:00 1969
++++ b/include/asm-um/local.h	Tue Sep  9 16:49:26 2003
+@@ -0,0 +1,6 @@
++#ifndef __UM_LOCAL_H
++#define __UM_LOCAL_H
++
++#include "asm/arch/local.h"
++
++#endif
+diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
+--- a/include/asm-um/module-generic.h	Wed Dec 31 19:00:00 1969
++++ b/include/asm-um/module-generic.h	Tue Sep  9 16:49:17 2003
+@@ -0,0 +1,6 @@
++#ifndef __UM_MODULE_GENERIC_H
++#define __UM_MODULE_GENERIC_H
++
++#include "asm/arch/module.h"
++
++#endif
+diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
+--- a/include/asm-um/module-i386.h	Wed Dec 31 19:00:00 1969
++++ b/include/asm-um/module-i386.h	Tue Sep  9 16:49:10 2003
+@@ -0,0 +1,13 @@
++#ifndef __UM_MODULE_I386_H
++#define __UM_MODULE_I386_H
++
++/* UML is simple */
++struct mod_arch_specific
++{
++};
++
++#define Elf_Shdr Elf32_Shdr
++#define Elf_Sym Elf32_Sym
++#define Elf_Ehdr Elf32_Ehdr
++
++#endif
+diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
+--- a/include/asm-um/page.h	Tue Sep  9 16:43:32 2003
++++ b/include/asm-um/page.h	Tue Sep  9 16:49:19 2003
+@@ -4,7 +4,6 @@
+ struct page;
+ 
+ #include "asm/arch/page.h"
+-#include "asm/bug.h"
+ 
+ #undef __pa
+ #undef __va
+diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
+--- a/include/asm-um/pgtable.h	Tue Sep  9 16:46:25 2003
++++ b/include/asm-um/pgtable.h	Tue Sep  9 16:51:24 2003
+@@ -79,12 +79,13 @@
+ 
+ #define _PAGE_PRESENT	0x001
+ #define _PAGE_NEWPAGE	0x002
+-#define _PAGE_PROTNONE	0x004	/* If not present */
+-#define _PAGE_RW	0x008
+-#define _PAGE_USER	0x010
+-#define _PAGE_ACCESSED	0x020
+-#define _PAGE_DIRTY	0x040
+-#define _PAGE_NEWPROT   0x080
++#define _PAGE_NEWPROT   0x004
++#define _PAGE_FILE	0x008   /* set:pagecache unset:swap */
++#define _PAGE_PROTNONE	0x010	/* If not present */
++#define _PAGE_RW	0x020
++#define _PAGE_USER	0x040
++#define _PAGE_ACCESSED	0x080
++#define _PAGE_DIRTY	0x100
+ 
+ #define REGION_MASK	0xf0000000
+ #define REGION_SHIFT	28
+@@ -203,6 +204,16 @@
+ #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
+ #define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
+ 
++/*
++ * Bits 0 through 3 are taken
++ */
++#define PTE_FILE_MAX_BITS	28
++
++#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
++
++#define pgoff_to_pte(off) \
++	((pte_t) { ((off) << 4) + _PAGE_FILE })
++
+ static inline pte_t pte_mknewprot(pte_t pte)
+ {
+  	pte_val(pte) |= _PAGE_NEWPROT;
+@@ -236,6 +247,12 @@
+  * The following only work if pte_present() is true.
+  * Undefined behaviour if not..
+  */
++static inline int pte_user(pte_t pte)
++{ 
++	return((pte_val(pte) & _PAGE_USER) && 
++	       !(pte_val(pte) & _PAGE_PROTNONE));
++}
++
+ static inline int pte_read(pte_t pte)
+ { 
+ 	return((pte_val(pte) & _PAGE_USER) && 
+@@ -253,6 +270,14 @@
+ 	       !(pte_val(pte) & _PAGE_PROTNONE));
+ }
+ 
++/*
++ * The following only works if pte_present() is not true.
++ */
++static inline int pte_file(pte_t pte)
++{ 
++	return (pte).pte_low & _PAGE_FILE; 
++}
++
+ static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_DIRTY; }
+ static inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
+ static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
+@@ -355,14 +380,26 @@
+ #define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
+ 		       ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
+ 
+-/* to find an entry in a page-table-directory. */
++/*
++ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
++ *
++ * this macro returns the index of the entry in the pgd page which would
++ * control the given virtual address
++ */
+ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ 
+-/* to find an entry in a page-table-directory */
++/*
++ * pgd_offset() returns a (pgd_t *)
++ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
++ */
+ #define pgd_offset(mm, address) \
+ ((mm)->pgd + ((address) >> PGDIR_SHIFT))
+ 
+-/* to find an entry in a kernel page-table-directory */
++
++/*
++ * a shortcut which implies the use of the kernel's pgd, instead
++ * of a process's
++ */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
+ 
+ #define pmd_index(address) \
+@@ -374,7 +411,12 @@
+ 	return (pmd_t *) dir;
+ }
+ 
+-/* Find an entry in the third-level page table.. */ 
++/*
++ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
++ *
++ * this macro returns the index of the entry in the pte page which would
++ * control the given virtual address
++ */
+ #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ #define pte_offset_kernel(dir, address) \
+ 	((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
+@@ -400,11 +442,11 @@
+ #define update_mmu_cache(vma,address,pte) do ; while (0)
+ 
+ /* Encode and de-code a swap entry */
+-#define __swp_type(x)			(((x).val >> 3) & 0x7f)
+-#define __swp_offset(x)			((x).val >> 10)
++#define __swp_type(x)			(((x).val >> 4) & 0x3f)
++#define __swp_offset(x)			((x).val >> 11)
+ 
+ #define __swp_entry(type, offset) \
+-	((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
++	((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
+ #define __pte_to_swp_entry(pte) \
+ 	((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+ #define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
+--- a/include/asm-um/processor-generic.h	Tue Sep  9 16:41:42 2003
++++ b/include/asm-um/processor-generic.h	Tue Sep  9 16:47:43 2003
+@@ -11,9 +11,7 @@
+ struct task_struct;
+ 
+ #include "linux/config.h"
+-#include "linux/signal.h"
+ #include "asm/ptrace.h"
+-#include "asm/siginfo.h"
+ #include "choose-mode.h"
+ 
+ struct mm_struct;
+@@ -101,14 +99,19 @@
+ } mm_segment_t;
+ 
+ extern struct task_struct *alloc_task_struct(void);
+-extern void free_task_struct(struct task_struct *task);
+ 
+ extern void release_thread(struct task_struct *);
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+ extern void dump_thread(struct pt_regs *regs, struct user *u);
++extern void prepare_to_copy(struct task_struct *tsk);
+ 
+ extern unsigned long thread_saved_pc(struct task_struct *t);
+ 
++static inline void mm_copy_segments(struct mm_struct *from_mm, 
++				    struct mm_struct *new_mm)
++{
++}
++
+ #define init_stack	(init_thread_union.stack)
+ 
+ /*
+diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
+--- a/include/asm-um/processor-i386.h	Tue Sep  9 16:41:17 2003
++++ b/include/asm-um/processor-i386.h	Tue Sep  9 16:47:27 2003
+@@ -6,8 +6,8 @@
+ #ifndef __UM_PROCESSOR_I386_H
+ #define __UM_PROCESSOR_I386_H
+ 
+-extern int cpu_has_xmm;
+-extern int cpu_has_cmov;
++extern int host_has_xmm;
++extern int host_has_cmov;
+ 
+ struct arch_thread {
+ 	unsigned long debugregs[8];
+diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
+--- a/include/asm-um/sections.h	Wed Dec 31 19:00:00 1969
++++ b/include/asm-um/sections.h	Tue Sep  9 16:49:28 2003
+@@ -0,0 +1,7 @@
++#ifndef _UM_SECTIONS_H
++#define _UM_SECTIONS_H
++
++/* nothing to see, move along */
++#include <asm-generic/sections.h>
++
++#endif
+diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
+--- a/include/asm-um/smp.h	Tue Sep  9 16:41:04 2003
++++ b/include/asm-um/smp.h	Tue Sep  9 16:47:18 2003
+@@ -10,7 +10,7 @@
+ 
+ extern cpumask_t cpu_online_map;
+ 
+-#define smp_processor_id() (current->thread_info->cpu)
++#define smp_processor_id() (current_thread->cpu)
+ #define cpu_logical_map(n) (n)
+ #define cpu_number_map(n) (n)
+ #define PROC_CHANGE_PENALTY	15 /* Pick a number, any number */
+diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
+--- a/include/asm-um/system-generic.h	Tue Sep  9 16:46:13 2003
++++ b/include/asm-um/system-generic.h	Tue Sep  9 16:51:14 2003
+@@ -23,8 +23,10 @@
+ extern void block_signals(void);
+ extern void unblock_signals(void);
+ 
+-#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
+-#define local_irq_restore(flags) do { set_signals(flags); } while(0)
++#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
++				     (flags) = get_signals(); } while(0)
++#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
++				      set_signals(flags); } while(0)
+ 
+ #define local_irq_save(flags) do { local_save_flags(flags); \
+                                    local_irq_disable(); } while(0)
+@@ -39,4 +41,7 @@
+         (flags == 0);                   \
+ })
+ 
++extern void *_switch_to(void *prev, void *next, void *last);
++#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
++
+ #endif
+diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
+--- a/include/asm-um/thread_info.h	Tue Sep  9 16:42:02 2003
++++ b/include/asm-um/thread_info.h	Tue Sep  9 16:48:12 2003
+@@ -9,6 +9,7 @@
+ #ifndef __ASSEMBLY__
+ 
+ #include <asm/processor.h>
++#include <asm/types.h>
+ 
+ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
+@@ -43,15 +44,18 @@
+ static inline struct thread_info *current_thread_info(void)
+ {
+ 	struct thread_info *ti;
+-	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
++	unsigned long mask = PAGE_SIZE * 
++		(1 << CONFIG_KERNEL_STACK_ORDER) - 1;
++	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
+ 	return ti;
+ }
+ 
+ /* thread information allocation */
+-#define THREAD_SIZE (4*PAGE_SIZE)
+-#define alloc_thread_info(tsk) ((struct thread_info *) \
+-	__get_free_pages(GFP_KERNEL,2))
+-#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
++#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
++#define alloc_thread_info(tsk) \
++	((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
++#define free_thread_info(ti) kfree(ti)
++	
+ #define get_thread_info(ti) get_task_struct((ti)->task)
+ #define put_thread_info(ti) put_task_struct((ti)->task)
+ 
+@@ -65,11 +69,13 @@
+ #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
+ 					 * TIF_NEED_RESCHED 
+ 					 */
++#define TIF_RESTART_BLOCK 	4
+ 
+ #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+ #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+ #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
++#define _TIF_RESTART_BLOCK	(1 << TIF_RESTART_BLOCK)
+ 
+ #endif
+ 
+diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
+--- a/include/asm-um/timex.h	Tue Sep  9 16:43:51 2003
++++ b/include/asm-um/timex.h	Tue Sep  9 16:49:27 2003
+@@ -1,8 +1,6 @@
+ #ifndef __UM_TIMEX_H
+ #define __UM_TIMEX_H
+ 
+-#include "linux/time.h"
+-
+ typedef unsigned long cycles_t;
+ 
+ #define cacheflush_time (0)
+diff -Naur a/include/linux/mm.h b/include/linux/mm.h
+--- a/include/linux/mm.h	Tue Sep  9 16:41:15 2003
++++ b/include/linux/mm.h	Tue Sep  9 16:47:26 2003
+@@ -487,6 +487,9 @@
+ 	return __set_page_dirty_buffers(page);
+ }
+ 
++extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
++			size_t len, unsigned long prot);
++
+ /*
+  * On a two-level page table, this ends up being trivial. Thus the
+  * inlining and the symmetry break with pte_alloc_map() that does all
+@@ -517,9 +520,10 @@
+ 
+ extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ 
+-extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+-	unsigned long len, unsigned long prot,
+-	unsigned long flag, unsigned long pgoff);
++extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
++				   unsigned long addr, unsigned long len,
++				   unsigned long prot, unsigned long flag,
++				   unsigned long pgoff);
+ 
+ static inline unsigned long do_mmap(struct file *file, unsigned long addr,
+ 	unsigned long len, unsigned long prot,
+@@ -529,7 +533,8 @@
+ 	if ((offset + PAGE_ALIGN(len)) < offset)
+ 		goto out;
+ 	if (!(offset & ~PAGE_MASK))
+-		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
++		ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
++				    offset >> PAGE_SHIFT);
+ out:
+ 	return ret;
+ }
+diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
+--- a/include/linux/proc_mm.h	Wed Dec 31 19:00:00 1969
++++ b/include/linux/proc_mm.h	Tue Sep  9 16:47:15 2003
+@@ -0,0 +1,48 @@
++/* 
++ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#ifndef __PROC_MM_H
++#define __PROC_MM_H
++
++#include "linux/sched.h"
++
++#define MM_MMAP 54
++#define MM_MUNMAP 55
++#define MM_MPROTECT 56
++#define MM_COPY_SEGMENTS 57
++
++struct mm_mmap {
++	unsigned long addr;
++	unsigned long len;
++	unsigned long prot;
++	unsigned long flags;
++	unsigned long fd;
++	unsigned long offset;
++};
++
++struct mm_munmap {
++	unsigned long addr;
++	unsigned long len;	
++};
++
++struct mm_mprotect {
++	unsigned long addr;
++	unsigned long len;
++        unsigned int prot;
++};
++
++struct proc_mm_op {
++	int op;
++	union {
++		struct mm_mmap mmap;
++		struct mm_munmap munmap;
++	        struct mm_mprotect mprotect;
++		int copy_segments;
++	} u;
++};
++
++extern struct mm_struct *proc_mm_get_mm(int fd);
++
++#endif
+diff -Naur a/mm/Makefile b/mm/Makefile
+--- a/mm/Makefile	Tue Sep  9 16:43:50 2003
++++ b/mm/Makefile	Tue Sep  9 16:49:26 2003
+@@ -12,3 +12,5 @@
+ 			   slab.o swap.o truncate.o vmscan.o $(mmu-y)
+ 
+ obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
++obj-$(CONFIG_PROC_MM)	+= proc_mm.o
++
+diff -Naur a/mm/memory.c b/mm/memory.c
+--- a/mm/memory.c	Tue Sep  9 16:43:03 2003
++++ b/mm/memory.c	Tue Sep  9 16:48:52 2003
+@@ -44,6 +44,7 @@
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+ #include <linux/rmap-locking.h>
++#include <linux/init.h>
+ #include <linux/module.h>
+ 
+ #include <asm/pgalloc.h>
+@@ -673,6 +674,24 @@
+ }
+ 
+ 
++static struct vm_area_struct fixmap_vma = {
++	/* Catch users - if there are any valid
++	   ones, we can make this be "&init_mm" or
++	   something.  */
++	.vm_mm = NULL,
++	.vm_page_prot = PAGE_READONLY,
++	.vm_flags = VM_READ | VM_EXEC,
++};
++
++static int init_fixmap_vma(void)
++{
++	fixmap_vma.vm_start = FIXADDR_START;
++	fixmap_vma.vm_end = FIXADDR_TOP;
++	return(0);
++}
++
++__initcall(init_fixmap_vma);
++
+ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ 		unsigned long start, int len, int write, int force,
+ 		struct page **pages, struct vm_area_struct **vmas)
+@@ -693,19 +712,8 @@
+ 
+ 		vma = find_extend_vma(mm, start);
+ 
+-#ifdef FIXADDR_USER_START
+-		if (!vma &&
+-		    start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
+-			static struct vm_area_struct fixmap_vma = {
+-				/* Catch users - if there are any valid
+-				   ones, we can make this be "&init_mm" or
+-				   something.  */
+-				.vm_mm = NULL,
+-				.vm_start = FIXADDR_USER_START,
+-				.vm_end = FIXADDR_USER_END,
+-				.vm_page_prot = PAGE_READONLY,
+-				.vm_flags = VM_READ | VM_EXEC,
+-			};
++#ifdef FIXADDR_START
++		if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
+ 			unsigned long pg = start & PAGE_MASK;
+ 			pgd_t *pgd;
+ 			pmd_t *pmd;
+diff -Naur a/mm/mmap.c b/mm/mmap.c
+--- a/mm/mmap.c	Tue Sep  9 16:43:49 2003
++++ b/mm/mmap.c	Tue Sep  9 16:49:24 2003
+@@ -434,11 +434,11 @@
+  * The caller must hold down_write(current->mm->mmap_sem).
+  */
+ 
+-unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
+-			unsigned long len, unsigned long prot,
+-			unsigned long flags, unsigned long pgoff)
++unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
++			    unsigned long addr, unsigned long len,
++			    unsigned long prot, unsigned long flags,
++			    unsigned long pgoff)
+ {
+-	struct mm_struct * mm = current->mm;
+ 	struct vm_area_struct * vma, * prev;
+ 	struct inode *inode;
+ 	unsigned int vm_flags;
+diff -Naur a/mm/mprotect.c b/mm/mprotect.c
+--- a/mm/mprotect.c	Tue Sep  9 16:42:54 2003
++++ b/mm/mprotect.c	Tue Sep  9 16:48:27 2003
+@@ -222,7 +222,8 @@
+ }
+ 
+ asmlinkage long
+-sys_mprotect(unsigned long start, size_t len, unsigned long prot)
++do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
++	     unsigned long prot)
+ {
+ 	unsigned long vm_flags, nstart, end, tmp;
+ 	struct vm_area_struct * vma, * next, * prev;
+@@ -241,9 +242,9 @@
+ 
+ 	vm_flags = calc_vm_prot_bits(prot);
+ 
+-	down_write(&current->mm->mmap_sem);
++	down_write(&mm->mmap_sem);
+ 
+-	vma = find_vma_prev(current->mm, start, &prev);
++	vma = find_vma_prev(mm, start, &prev);
+ 	error = -ENOMEM;
+ 	if (!vma || vma->vm_start > start)
+ 		goto out;
+@@ -304,6 +305,11 @@
+ 		prev->vm_mm->map_count--;
+ 	}
+ out:
+-	up_write(&current->mm->mmap_sem);
++	up_write(&mm->mmap_sem);
+ 	return error;
+ }
++
++asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
++{
++        return(do_mprotect(current->mm, start, len, prot));
++}
+diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
+--- a/mm/proc_mm.c	Wed Dec 31 19:00:00 1969
++++ b/mm/proc_mm.c	Tue Sep  9 16:48:51 2003
+@@ -0,0 +1,174 @@
++/* 
++ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
++ * Licensed under the GPL
++ */
++
++#include "linux/mm.h"
++#include "linux/init.h"
++#include "linux/proc_fs.h"
++#include "linux/proc_mm.h"
++#include "linux/file.h"
++#include "asm/uaccess.h"
++#include "asm/mmu_context.h"
++
++static struct file_operations proc_mm_fops;
++
++struct mm_struct *proc_mm_get_mm(int fd)
++{
++	struct mm_struct *ret = ERR_PTR(-EBADF);
++	struct file *file;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	ret = ERR_PTR(-EINVAL);
++	if(file->f_op != &proc_mm_fops)
++		goto out_fput;
++
++	ret = file->private_data;
++ out_fput:
++	fput(file);
++ out:
++	return(ret);
++}
++
++extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
++		     unsigned long len, unsigned long prot, 
++		     unsigned long flags, unsigned long fd,
++		     unsigned long pgoff);
++
++static ssize_t write_proc_mm(struct file *file, const char *buffer,
++			     size_t count, loff_t *ppos)
++{
++	struct mm_struct *mm = file->private_data;
++	struct proc_mm_op req;
++	int n, ret;
++
++	if(count > sizeof(req))
++		return(-EINVAL);
++
++	n = copy_from_user(&req, buffer, count);
++	if(n != 0)
++		return(-EFAULT);
++
++	ret = count;
++	switch(req.op){
++	case MM_MMAP: {
++		struct mm_mmap *map = &req.u.mmap;
++
++		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
++			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
++		if((ret & ~PAGE_MASK) == 0)
++			ret = count;
++	
++		break;
++	}
++	case MM_MUNMAP: {
++		struct mm_munmap *unmap = &req.u.munmap;
++
++		down_write(&mm->mmap_sem);
++		ret = do_munmap(mm, unmap->addr, unmap->len);
++		up_write(&mm->mmap_sem);
++
++		if(ret == 0)
++			ret = count;
++		break;
++	}
++	case MM_MPROTECT: {
++		struct mm_mprotect *protect = &req.u.mprotect;
++
++		ret = do_mprotect(mm, protect->addr, protect->len, 
++				  protect->prot);
++		if(ret == 0)
++			ret = count;
++		break;
++	}
++
++	case MM_COPY_SEGMENTS: {
++		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
++
++		if(IS_ERR(from)){
++			ret = PTR_ERR(from);
++			break;
++		}
++
++		mm_copy_segments(from, mm);
++		break;
++	}
++	default:
++		ret = -EINVAL;
++		break;
++	}
++
++	return(ret);
++}
++
++static int open_proc_mm(struct inode *inode, struct file *file)
++{
++	struct mm_struct *mm = mm_alloc();
++	int ret;
++
++	ret = -ENOMEM;
++	if(mm == NULL)
++		goto out_mem;
++
++	ret = init_new_context(current, mm);
++	if(ret)
++		goto out_free;
++
++	spin_lock(&mmlist_lock);
++	list_add(&mm->mmlist, &current->mm->mmlist);
++	mmlist_nr++;
++	spin_unlock(&mmlist_lock);
++
++	file->private_data = mm;
++
++	return(0);
++
++ out_free:
++	mmput(mm);
++ out_mem:
++	return(ret);
++}
++
++static int release_proc_mm(struct inode *inode, struct file *file)
++{
++	struct mm_struct *mm = file->private_data;
++
++	mmput(mm);
++	return(0);
++}
++
++static struct file_operations proc_mm_fops = {
++	.open		= open_proc_mm,
++	.release	= release_proc_mm,
++	.write		= write_proc_mm,
++};
++
++static int make_proc_mm(void)
++{
++	struct proc_dir_entry *ent;
++
++	ent = create_proc_entry("mm", 0222, &proc_root);
++	if(ent == NULL){
++		printk("make_proc_mm : Failed to register /proc/mm\n");
++		return(0);
++	}
++	ent->proc_fops = &proc_mm_fops;
++
++	return(0);
++}
++
++__initcall(make_proc_mm);
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
diff --git a/lustre/kernel_patches/patches/vfs-pdirops-2.4.18-chaos.patch b/lustre/kernel_patches/patches/vfs-pdirops-2.4.18-chaos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0f3070b68011fcf09b574c285aa041e006b7ced1
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs-pdirops-2.4.18-chaos.patch
@@ -0,0 +1,265 @@
+ fs/inode.c         |    1 
+ fs/namei.c         |   65 +++++++++++++++++++++++++++++++++++++++--------------
+ include/linux/fs.h |   11 ++++----
+ 3 files changed, 54 insertions(+), 23 deletions(-)
+
+--- linux-2.4.18-chaos/fs/namei.c~vfs-pdirops-2.4.18-chaos	2003-09-16 23:33:47.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/namei.c	2003-09-17 00:18:45.000000000 +0400
+@@ -101,6 +101,36 @@ void intent_release(struct lookup_intent
+ 
+ }
+ 
++static void *lock_dir(struct inode *dir, struct qstr *name)
++{
++	unsigned long hash;
++	
++	if (!IS_PDIROPS(dir)) {
++		down(&dir->i_sem);
++		return 0;
++	}
++
++	/* OK. fs understands parallel directory operations.
++	 * so, we try to acquire lock for hash of requested
++	 * filename in order to prevent any operations with
++	 * same name in same time -bzzz */
++
++	/* calculate name hash */
++	hash = full_name_hash(name->name, name->len);
++
++	/* lock this hash */
++	return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC);
++}
++
++static void unlock_dir(struct inode *dir, void *lock)
++{
++	if (!IS_PDIROPS(dir)) {
++		up(&dir->i_sem);
++		return;
++	}
++	dynlock_unlock(&dir->i_dcache_lock, lock);
++}
++
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+  * kernel data space before using them..
+@@ -303,10 +333,11 @@ static struct dentry *real_lookup(struct
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
+         int counter = 0;
++ 	void *lock;
+ 
+ again:
++ 	lock = lock_dir(dir, name);
+         counter++;
+-	down(&dir->i_sem);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+ 	 * while we waited for the directory semaphore..
+@@ -330,7 +361,7 @@ again:
+ 			else
+ 				result = dentry;
+ 		}
+-		up(&dir->i_sem);
++		unlock_dir(dir, lock);
+ 		return result;
+ 	}
+ 
+@@ -338,7 +369,7 @@ again:
+ 	 * Uhhuh! Nasty case: the cache was re-populated while
+ 	 * we waited on the semaphore. Need to revalidate.
+ 	 */
+-	up(&dir->i_sem);
++	unlock_dir(dir, lock);
+ 	if (result->d_op && result->d_op->d_revalidate) {
+ 		if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
+ 			dput(result);
+@@ -1240,13 +1271,13 @@ struct file *filp_open(const char * path
+ 		goto exit;
+ 
+ 	dir = nd.dentry;
+-	down(&dir->d_inode->i_sem);
++	nd.lock = lock_dir(dir->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
+ 
+ do_last:
+ 	error = PTR_ERR(dentry);
+ 	if (IS_ERR(dentry)) {
+-		up(&dir->d_inode->i_sem);
++		unlock_dir(dir->d_inode, nd.lock);
+ 		goto exit;
+ 	}
+ 
+@@ -1255,7 +1286,7 @@ do_last:
+ 	if (!dentry->d_inode) {
+ 		error = vfs_create_it(dir->d_inode, dentry,
+ 				   mode & ~current->fs->umask, &it);
+-		up(&dir->d_inode->i_sem);
++		unlock_dir(dir->d_inode, nd.lock);
+ 		dput(nd.dentry);
+ 		nd.dentry = dentry;
+ 		if (error)
+@@ -1270,7 +1301,7 @@ do_last:
+ 	/*
+ 	 * It already exists.
+ 	 */
+-	up(&dir->d_inode->i_sem);
++	unlock_dir(dir->d_inode, nd.lock);
+ 
+ 	error = -EEXIST;
+ 	if (flag & O_EXCL)
+@@ -1350,7 +1381,7 @@ do_link:
+ 		goto exit;
+ 	}
+ 	dir = nd.dentry;
+-	down(&dir->d_inode->i_sem);
++	nd.lock = lock_dir(dir->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
+ 	putname(nd.last.name);
+ 	goto do_last;
+@@ -1363,7 +1394,7 @@ static struct dentry *lookup_create(stru
+ {
+ 	struct dentry *dentry;
+ 
+-	down(&nd->dentry->d_inode->i_sem);
++	nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
+ 	dentry = ERR_PTR(-EEXIST);
+ 	if (nd->last_type != LAST_NORM)
+ 		goto fail;
+@@ -1452,7 +1483,7 @@ asmlinkage long sys_mknod(const char * f
+ 		}
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ out2:
+ 	path_release(&nd);
+ out:
+@@ -1515,7 +1546,7 @@ asmlinkage long sys_mkdir(const char * p
+ 					  mode & ~current->fs->umask);
+ 			dput(dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ out2:
+ 		path_release(&nd);
+ out:
+@@ -1625,14 +1656,14 @@ asmlinkage long sys_rmdir(const char * p
+ 		if (error != -EOPNOTSUPP)
+ 			goto exit1;
+ 	}
+-	down(&nd.dentry->d_inode->i_sem);
++	nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ exit1:
+ 	path_release(&nd);
+ exit:
+@@ -1691,7 +1722,7 @@ asmlinkage long sys_unlink(const char * 
+ 		if (error != -EOPNOTSUPP)
+ 			goto exit1;
+ 	}
+-	down(&nd.dentry->d_inode->i_sem);
++	nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+@@ -1702,7 +1733,7 @@ asmlinkage long sys_unlink(const char * 
+ 	exit2:
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ exit1:
+ 	path_release(&nd);
+ exit:
+@@ -1772,7 +1803,7 @@ asmlinkage long sys_symlink(const char *
+ 			error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+ 			dput(dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ 	out2:
+ 		path_release(&nd);
+ 	out:
+@@ -1864,7 +1895,7 @@ asmlinkage long sys_link(const char * ol
+ 			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+ 			dput(new_dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ out_release:
+ 		path_release(&nd);
+ out:
+--- linux-2.4.18-chaos/include/linux/fs.h~vfs-pdirops-2.4.18-chaos	2003-09-16 23:33:47.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/fs.h	2003-09-17 00:16:08.000000000 +0400
+@@ -21,6 +21,7 @@
+ #include <linux/cache.h>
+ #include <linux/stddef.h>
+ #include <linux/string.h>
++#include <linux/dynlocks.h>
+ 
+ #include <asm/atomic.h>
+ #include <asm/bitops.h>
+@@ -136,6 +137,7 @@ extern int leases_enable, dir_notify_ena
+ #define S_IMMUTABLE	16	/* Immutable file */
+ #define S_DEAD		32	/* removed, but still open directory */
+ #define S_NOQUOTA	64	/* Inode is not counted to quota */
++#define S_PDIROPS	256	/* Parallel directory operations */
+ 
+ /*
+  * Note that nosuid etc flags are inode-specific: setting some file-system
+@@ -162,6 +164,7 @@ extern int leases_enable, dir_notify_ena
+ #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
+ #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
+ #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
++#define IS_PDIROPS(inode)	__IS_FLG(inode, S_PDIROPS)
+ 
+ #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
+ 
+@@ -491,6 +494,7 @@ struct inode {
+ 	atomic_t		i_writecount;
+ 	unsigned int		i_attr_flags;
+ 	__u32			i_generation;
++	struct dynlock		i_dcache_lock;	/* for parallel directory ops */
+ 	union {
+ 		struct minix_inode_info		minix_i;
+ 		struct ext2_inode_info		ext2_i;
+@@ -714,6 +718,7 @@ struct nameidata {
+ 	unsigned int flags;
+ 	int last_type;
+ 	struct lookup_intent *intent;
++	void *lock;
+ };
+ 
+ #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
+@@ -1611,12 +1616,6 @@ static inline struct dentry *get_parent(
+ 	return dget(dentry->d_parent);
+ }
+ 
+-static inline void unlock_dir(struct dentry *dir)
+-{
+-	up(&dir->d_inode->i_sem);
+-	dput(dir);
+-}
+-
+ /*
+  * Whee.. Deadlock country. Happily there are only two VFS
+  * operations that does this..
+--- linux-2.4.18-chaos/fs/inode.c~vfs-pdirops-2.4.18-chaos	2003-09-16 23:33:48.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/inode.c	2003-09-16 23:47:45.000000000 +0400
+@@ -119,6 +119,7 @@ static struct inode *alloc_inode(struct 
+ 		mapping->host = inode;
+ 		mapping->gfp_mask = GFP_HIGHUSER;
+ 		inode->i_mapping = mapping;
++		dynlock_init(&inode->i_dcache_lock);
+ 	}
+ 	return inode;
+ }
+
+_
diff --git a/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch b/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6ab7a21bdec21404365b0d5e93817a6d52ce0eb7
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs-pdirops-2.4.20-rh.patch
@@ -0,0 +1,269 @@
+ fs/inode.c         |    1 
+ fs/namei.c         |   66 ++++++++++++++++++++++++++++++++++++++---------------
+ include/linux/fs.h |   11 ++++----
+ 3 files changed, 54 insertions(+), 24 deletions(-)
+
+Index: linux-2.4.20-rh/fs/namei.c
+===================================================================
+--- linux-2.4.20-rh.orig/fs/namei.c	2003-09-04 20:58:33.000000000 +0800
++++ linux-2.4.20-rh/fs/namei.c	2003-09-04 21:21:20.000000000 +0800
+@@ -101,6 +101,36 @@
+ 
+ }
+ 
++static void *lock_dir(struct inode *dir, struct qstr *name)
++{
++	unsigned long hash;
++	
++	if (!IS_PDIROPS(dir)) {
++		down(&dir->i_sem);
++		return 0;
++	}
++
++	/* OK. fs understands parallel directory operations.
++	 * so, we try to acquire lock for hash of requested
++	 * filename in order to prevent any operations with
++	 * same name in same time -bzzz */
++
++	/* calculate name hash */
++	hash = full_name_hash(name->name, name->len);
++
++	/* lock this hash */
++	return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC);
++}
++
++static void unlock_dir(struct inode *dir, void *lock)
++{
++	if (!IS_PDIROPS(dir)) {
++		up(&dir->i_sem);
++		return;
++	}
++	dynlock_unlock(&dir->i_dcache_lock, lock);
++}
++
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+  * kernel data space before using them..
+@@ -303,10 +333,11 @@
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
+ 	int counter = 0;
++	void *lock;
+ 
+ again:
+ 	counter++;
+-	down(&dir->i_sem);
++	lock = lock_dir(dir, name);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+ 	 * while we waited for the directory semaphore..
+@@ -329,7 +359,7 @@
+ 			else
+ 				result = dentry;
+ 		}
+-		up(&dir->i_sem);
++		unlock_dir(dir, lock);
+ 		return result;
+ 	}
+ 
+@@ -337,7 +367,7 @@
+ 	 * Uhhuh! Nasty case: the cache was re-populated while
+ 	 * we waited on the semaphore. Need to revalidate.
+ 	 */
+-	up(&dir->i_sem);
++	unlock_dir(dir, lock);
+ 	if (result->d_op && result->d_op->d_revalidate) {
+ 		if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
+ 			dput(result);
+@@ -1180,13 +1210,13 @@
+ 		goto exit;
+ 
+ 	dir = nd->dentry;
+-	down(&dir->d_inode->i_sem);
++	nd->lock = lock_dir(dir->d_inode, &nd->last);
+ 	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 
+ do_last:
+ 	error = PTR_ERR(dentry);
+ 	if (IS_ERR(dentry)) {
+-		up(&dir->d_inode->i_sem);
++		unlock_dir(dir->d_inode, nd->lock);
+ 		goto exit;
+ 	}
+ 
+@@ -1195,7 +1225,7 @@
+ 	if (!dentry->d_inode) {
+ 		error = vfs_create_it(dir->d_inode, dentry,
+ 				   mode & ~current->fs->umask, it);
+-		up(&dir->d_inode->i_sem);
++		unlock_dir(dir->d_inode, nd->lock);		
+ 		dput(nd->dentry);
+ 		nd->dentry = dentry;
+ 		if (error)
+@@ -1209,7 +1239,7 @@
+ 	/*
+ 	 * It already exists.
+ 	 */
+-	up(&dir->d_inode->i_sem);
++	unlock_dir(dir->d_inode, nd->lock);
+ 
+ 	error = -EEXIST;
+ 	if (flag & O_EXCL)
+@@ -1362,7 +1392,7 @@
+ 		goto exit;
+ 	}
+ 	dir = nd->dentry;
+-	down(&dir->d_inode->i_sem);
++	nd->lock = lock_dir(dir->d_inode, &nd->last);
+ 	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 	putname(nd->last.name);
+ 	goto do_last;
+@@ -1380,7 +1410,7 @@
+ {
+ 	struct dentry *dentry;
+ 
+-	down(&nd->dentry->d_inode->i_sem);
++	nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
+ 	dentry = ERR_PTR(-EEXIST);
+ 	if (nd->last_type != LAST_NORM)
+ 		goto fail;
+@@ -1469,7 +1499,7 @@
+ 		}
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ out2:
+ 	path_release(&nd);
+ out:
+@@ -1532,7 +1562,7 @@
+ 					  mode & ~current->fs->umask);
+ 			dput(dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ out2:
+ 		path_release(&nd);
+ out:
+@@ -1642,14 +1672,14 @@
+ 		if (error != -EOPNOTSUPP)
+ 			goto exit1;
+ 	}
+-	down(&nd.dentry->d_inode->i_sem);
++	nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ exit1:
+ 	path_release(&nd);
+ exit:
+@@ -1708,7 +1738,7 @@
+ 		if (error != -EOPNOTSUPP)
+ 			goto exit1;
+ 	}
+-	down(&nd.dentry->d_inode->i_sem);
++	nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
+ 	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+@@ -1719,7 +1749,7 @@
+ 	exit2:
+ 		dput(dentry);
+ 	}
+-	up(&nd.dentry->d_inode->i_sem);
++	unlock_dir(nd.dentry->d_inode, nd.lock);
+ exit1:
+ 	path_release(&nd);
+ exit:
+@@ -1789,7 +1819,7 @@
+ 			error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+ 			dput(dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ 	out2:
+ 		path_release(&nd);
+ 	out:
+@@ -1881,7 +1911,7 @@
+ 			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+ 			dput(new_dentry);
+ 		}
+-		up(&nd.dentry->d_inode->i_sem);
++		unlock_dir(nd.dentry->d_inode, nd.lock);
+ out_release:
+ 		path_release(&nd);
+ out:
+Index: linux-2.4.20-rh/include/linux/fs.h
+===================================================================
+--- linux-2.4.20-rh.orig/include/linux/fs.h	2003-09-04 20:59:14.000000000 +0800
++++ linux-2.4.20-rh/include/linux/fs.h	2003-09-04 21:03:46.000000000 +0800
+@@ -21,6 +21,7 @@
+ #include <linux/cache.h>
+ #include <linux/stddef.h>
+ #include <linux/string.h>
++#include <linux/dynlocks.h>
+ 
+ #include <asm/atomic.h>
+ #include <asm/bitops.h>
+@@ -136,6 +137,7 @@
+ #define S_IMMUTABLE	16	/* Immutable file */
+ #define S_DEAD		32	/* removed, but still open directory */
+ #define S_NOQUOTA	64	/* Inode is not counted to quota */
++#define S_PDIROPS	256	/* Parallel directory operations */
+ 
+ /*
+  * Note that nosuid etc flags are inode-specific: setting some file-system
+@@ -162,6 +164,7 @@
+ #define IS_IMMUTABLE(inode)	((inode)->i_flags & S_IMMUTABLE)
+ #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
+ #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
++#define IS_PDIROPS(inode)	__IS_FLG(inode, S_PDIROPS)
+ 
+ #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
+ 
+@@ -489,6 +492,7 @@
+ 	atomic_t		i_writecount;
+ 	unsigned int		i_attr_flags;
+ 	__u32			i_generation;
++	struct dynlock		i_dcache_lock;	/* for parallel directory ops */
+ 	union {
+ 		struct minix_inode_info		minix_i;
+ 		struct ext2_inode_info		ext2_i;
+@@ -708,6 +712,7 @@
+ 	unsigned int flags;
+ 	int last_type;
+ 	struct lookup_intent *intent;
++	void *lock;
+ };
+ 
+ /*
+@@ -1621,12 +1626,6 @@
+ 	return dget(dentry->d_parent);
+ }
+ 
+-static inline void unlock_dir(struct dentry *dir)
+-{
+-	up(&dir->d_inode->i_sem);
+-	dput(dir);
+-}
+-
+ /*
+  * Whee.. Deadlock country. Happily there are only two VFS
+  * operations that does this..
+Index: linux-2.4.20-rh/fs/inode.c
+===================================================================
+--- linux-2.4.20-rh.orig/fs/inode.c	2003-09-04 20:58:35.000000000 +0800
++++ linux-2.4.20-rh/fs/inode.c	2003-09-04 21:03:46.000000000 +0800
+@@ -121,6 +121,7 @@
+ 		mapping->host = inode;
+ 		mapping->gfp_mask = GFP_HIGHUSER;
+ 		inode->i_mapping = mapping;
++		dynlock_init(&inode->i_dcache_lock);
+ 	}
+ 	return inode;
+ }
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch
index d68a35161f18c139160a4691fb796f3db70a152b..7f16189f7b721505a5b5430a6fa53877afe99945 100644
--- a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch
@@ -1,31 +1,31 @@
  fs/dcache.c            |   19 ++
- fs/exec.c              |   15 +-
- fs/namei.c             |  355 +++++++++++++++++++++++++++++++++++++++++--------
- fs/namespace.c         |   30 +++-
- fs/open.c              |  122 ++++++++++++++--
- fs/proc/base.c         |    3 
- fs/stat.c              |   27 ++-
- include/linux/dcache.h |   54 +++++++
- include/linux/fs.h     |   31 ++++
+ fs/exec.c              |   18 +-
+ fs/namei.c             |  328 +++++++++++++++++++++++++++++++++++++++++--------
+ fs/namespace.c         |   28 +++-
+ fs/open.c              |  167 ++++++++++++++++++------
+ fs/stat.c              |   29 ++--
+ include/linux/dcache.h |   60 ++++++++
+ include/linux/fs.h     |   34 ++++-
  kernel/exit.c          |    3 
  kernel/fork.c          |    3 
  kernel/ksyms.c         |    1 
- 12 files changed, 564 insertions(+), 99 deletions(-)
+ 11 files changed, 564 insertions(+), 126 deletions(-)
 
---- linux-2.4.18-p4smp/fs/exec.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:17:30.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/exec.c	2003-07-09 13:20:37.000000000 -0600
-@@ -117,8 +117,9 @@ asmlinkage long sys_uselib(const char * 
+--- linux-2.4.18-chaos/fs/exec.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/exec.c	2003-09-14 17:25:41.000000000 +0400
+@@ -117,8 +117,10 @@ asmlinkage long sys_uselib(const char * 
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++	                                     .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	error = user_path_walk(library, &nd);
 +	error = user_path_walk_it(library, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -130,7 +131,8 @@ asmlinkage long sys_uselib(const char * 
+@@ -130,7 +132,8 @@ asmlinkage long sys_uselib(const char * 
  	if (error)
  		goto exit;
  
@@ -35,18 +35,19 @@
  	error = PTR_ERR(file);
  	if (IS_ERR(file))
  		goto out;
-@@ -359,8 +361,9 @@ struct file *open_exec(const char *name)
+@@ -359,8 +362,9 @@ struct file *open_exec(const char *name)
  	struct inode *inode;
  	struct file *file;
  	int err = 0;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
- 
+-
 -	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
++	struct lookup_intent it = { .it_op = IT_OPEN,
++	                                     .it_flags = FMODE_READ|FMODE_EXEC };
 +	err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
  	file = ERR_PTR(err);
  	if (!err) {
  		inode = nd.dentry->d_inode;
-@@ -372,7 +375,8 @@ struct file *open_exec(const char *name)
+@@ -372,7 +376,8 @@ struct file *open_exec(const char *name)
  				err = -EACCES;
  			file = ERR_PTR(err);
  			if (!err) {
@@ -56,7 +57,7 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
-@@ -384,6 +388,7 @@ out:
+@@ -384,6 +389,7 @@ out:
  				return file;
  			}
  		}
@@ -64,7 +65,7 @@
  		path_release(&nd);
  	}
  	goto out;
-@@ -1104,7 +1109,7 @@ int do_coredump(long signr, struct pt_re
+@@ -1104,7 +1110,7 @@ int do_coredump(long signr, struct pt_re
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
@@ -73,8 +74,8 @@
  		goto close_fail;
  
  	retval = binfmt->core_dump(signr, regs, file);
---- linux-2.4.18-p4smp/fs/dcache.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:17:30.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/dcache.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/fs/dcache.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:03.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/dcache.c	2003-09-14 17:25:41.000000000 +0400
 @@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
  		spin_unlock(&dcache_lock);
  		return 0;
@@ -112,8 +113,8 @@
  }
  
  #define do_switch(x,y) do { \
---- linux-2.4.18-p4smp/fs/namespace.c~vfs_intent-2.4.18-18-chaos65	2002-06-25 22:16:14.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/namespace.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/fs/namespace.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:05.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/namespace.c	2003-09-14 17:25:41.000000000 +0400
 @@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
  {
  	old_nd->dentry = mnt->mnt_mountpoint;
@@ -158,16 +159,14 @@
  	path_release(&old_nd);
  	return err;
  }
-@@ -698,7 +704,8 @@ long do_mount(char * dev_name, char * di
+@@ -698,6 +704,7 @@ long do_mount(char * dev_name, char * di
  		  unsigned long flags, void *data_page)
  {
  	struct nameidata nd;
--	int retval = 0;
 +	struct lookup_intent it = { .it_op = IT_GETATTR };
-+	int retval = 0;
+ 	int retval = 0;
  	int mnt_flags = 0;
  
- 	/* Discard magic */
 @@ -722,10 +729,11 @@ long do_mount(char * dev_name, char * di
  	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
  
@@ -229,8 +228,8 @@
  	path_release(&new_nd);
  out0:
  	unlock_kernel();
---- linux-2.4.18-p4smp/fs/namei.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:17:30.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/namei.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/fs/namei.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:05.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/namei.c	2003-09-14 17:25:41.000000000 +0400
 @@ -94,6 +94,13 @@
   * XEmacs seems to be relying on it...
   */
@@ -266,7 +265,7 @@
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
  			dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
   * make sure that nobody added the entry to the dcache in the meantime..
   * SMP-safe
   */
@@ -276,13 +275,14 @@
  {
  	struct dentry * result;
  	struct inode *dir = parent->d_inode;
++        int counter = 0;
  
 +again:
-+
++        counter++;
  	down(&dir->i_sem);
  	/*
  	 * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
  		result = ERR_PTR(-ENOMEM);
  		if (dentry) {
  			lock_kernel();
@@ -292,7 +292,7 @@
  			result = dir->i_op->lookup(dir, dentry);
  			unlock_kernel();
  			if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
  			dput(result);
  			result = ERR_PTR(-ENOENT);
  		}
@@ -300,12 +300,15 @@
 +		if (!result->d_op->d_revalidate_it(result, flags, it) &&
 +		    !d_invalidate(result)) {
 +			dput(result);
-+			goto again;
++                        if (counter > 10)
++                                result = ERR_PTR(-ESTALE);
++                        if (!IS_ERR(result))
++                                goto again;
 +		}
  	}
  	return result;
  }
-@@ -334,7 +362,8 @@ int max_recursive_link = 5;
+@@ -334,7 +366,8 @@ int max_recursive_link = 5;
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups. 
   */
@@ -315,22 +318,12 @@
  {
  	int err;
  	if (current->link_count >= max_recursive_link)
-@@ -348,10 +377,21 @@ static inline int do_follow_link(struct 
+@@ -348,10 +381,12 @@ static inline int do_follow_link(struct 
  	current->link_count++;
  	current->total_link_count++;
  	UPDATE_ATIME(dentry->d_inode);
--	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	nd->it = it;
-+	if (dentry->d_inode->i_op->follow_link2)
-+		err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
-+	else
-+		err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
-+		intent_release(it);
-+		path_release(nd);
-+		err = -ENOLINK;
-+	}
++	nd->intent = it;
+ 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
  	current->link_count--;
  	return err;
  loop:
@@ -338,7 +331,7 @@
  	path_release(nd);
  	return -ELOOP;
  }
-@@ -381,15 +421,26 @@ int follow_up(struct vfsmount **mnt, str
+@@ -381,7 +416,8 @@ int follow_up(struct vfsmount **mnt, str
  	return __follow_up(mnt, dentry);
  }
  
@@ -348,25 +341,7 @@
  {
  	struct vfsmount *mounted;
  
- 	spin_lock(&dcache_lock);
- 	mounted = lookup_mnt(*mnt, *dentry);
- 	if (mounted) {
-+		int opc = 0, mode = 0;
- 		*mnt = mntget(mounted);
- 		spin_unlock(&dcache_lock);
-+		if (it) {
-+			opc = it->it_op;
-+			mode = it->it_mode;
-+		}
-+		intent_release(it);
-+		if (it) {
-+			it->it_op = opc;
-+			it->it_mode = mode;
-+		}
- 		dput(*dentry);
- 		mntput(mounted->mnt_parent);
- 		*dentry = dget(mounted->mnt_root);
-@@ -401,7 +452,7 @@ static inline int __follow_down(struct v
+@@ -401,7 +437,7 @@ static inline int __follow_down(struct v
  
  int follow_down(struct vfsmount **mnt, struct dentry **dentry)
  {
@@ -375,7 +350,7 @@
  }
   
  static inline void follow_dotdot(struct nameidata *nd)
-@@ -437,7 +488,7 @@ static inline void follow_dotdot(struct 
+@@ -437,7 +473,7 @@ static inline void follow_dotdot(struct 
  		mntput(nd->mnt);
  		nd->mnt = parent;
  	}
@@ -384,7 +359,7 @@
  		;
  }
  
-@@ -449,7 +500,8 @@ static inline void follow_dotdot(struct 
+@@ -449,7 +485,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
   */
@@ -394,7 +369,7 @@
  {
  	struct dentry *dentry;
  	struct inode *inode;
-@@ -526,18 +578,18 @@ int link_path_walk(const char * name, st
+@@ -526,18 +563,18 @@ int link_path_walk(const char * name, st
  				break;
  		}
  		/* This does the actual lookups.. */
@@ -416,7 +391,7 @@
  			;
  
  		err = -ENOENT;
-@@ -548,8 +600,8 @@ int link_path_walk(const char * name, st
+@@ -548,8 +585,8 @@ int link_path_walk(const char * name, st
  		if (!inode->i_op)
  			goto out_dput;
  
@@ -427,7 +402,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -565,7 +617,7 @@ int link_path_walk(const char * name, st
+@@ -565,7 +602,7 @@ int link_path_walk(const char * name, st
  			nd->dentry = dentry;
  		}
  		err = -ENOTDIR; 
@@ -436,7 +411,7 @@
  			break;
  		continue;
  		/* here ends the main loop */
-@@ -592,22 +644,23 @@ last_component:
+@@ -592,22 +629,23 @@ last_component:
  			if (err < 0)
  				break;
  		}
@@ -465,7 +440,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -621,7 +674,8 @@ last_component:
+@@ -621,7 +659,8 @@ last_component:
  			goto no_inode;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
@@ -475,12 +450,11 @@
  				break;
  		}
  		goto return_base;
-@@ -645,7 +699,24 @@ return_reval:
+@@ -645,7 +684,26 @@ return_reval:
  		 * Check the cached dentry for staleness.
  		 */
  		dentry = nd->dentry;
 -		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-+	revalidate_again:
 +		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
 +			err = -ESTALE;
 +			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
@@ -493,15 +467,18 @@
 +						  &dentry->d_name, 0, NULL);
 +				d_invalidate(dentry);
 +				dput(dentry);
-+				dentry = new;
-+				goto revalidate_again;
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
 +			}
 +		}
 +		else if (dentry && dentry->d_op && dentry->d_op->d_revalidate){
  			err = -ESTALE;
  			if (!dentry->d_op->d_revalidate(dentry, 0)) {
  				d_invalidate(dentry);
-@@ -658,15 +729,28 @@ out_dput:
+@@ -658,15 +716,28 @@ out_dput:
  		dput(dentry);
  		break;
  	}
@@ -531,7 +508,7 @@
  }
  
  /* SMP-safe */
-@@ -751,6 +835,17 @@ walk_init_root(const char *name, struct 
+@@ -751,6 +822,17 @@ walk_init_root(const char *name, struct 
  }
  
  /* SMP-safe */
@@ -549,15 +526,15 @@
  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
  {
  	int error = 0;
-@@ -765,6 +860,7 @@ int path_init(const char *name, unsigned
+@@ -765,6 +847,7 @@ int path_init(const char *name, unsigned
  {
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
-+	nd->it = NULL;
++	nd->intent = NULL;
  	if (*name=='/')
  		return walk_init_root(name,nd);
  	read_lock(&current->fs->lock);
-@@ -779,7 +875,8 @@ int path_init(const char *name, unsigned
+@@ -779,7 +862,8 @@ int path_init(const char *name, unsigned
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -567,7 +544,7 @@
  {
  	struct dentry * dentry;
  	struct inode *inode;
-@@ -802,13 +899,16 @@ struct dentry * lookup_hash(struct qstr 
+@@ -802,13 +886,16 @@ struct dentry * lookup_hash(struct qstr 
  			goto out;
  	}
  
@@ -585,7 +562,7 @@
  		dentry = inode->i_op->lookup(inode, new);
  		unlock_kernel();
  		if (!dentry)
-@@ -820,6 +920,12 @@ out:
+@@ -820,6 +907,12 @@ out:
  	return dentry;
  }
  
@@ -598,7 +575,7 @@
  /* SMP-safe */
  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
  {
-@@ -841,7 +947,7 @@ struct dentry * lookup_one_len(const cha
+@@ -841,7 +934,7 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -607,7 +584,7 @@
  access:
  	return ERR_PTR(-EACCES);
  }
-@@ -872,6 +978,23 @@ int __user_walk(const char *name, unsign
+@@ -872,6 +965,23 @@ int __user_walk(const char *name, unsign
  	return err;
  }
  
@@ -631,7 +608,7 @@
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -969,6 +1092,37 @@ static inline int lookup_flags(unsigned 
+@@ -969,6 +1079,37 @@ static inline int lookup_flags(unsigned 
  	return retval;
  }
  
@@ -669,24 +646,14 @@
  int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
  {
  	int error;
-@@ -987,7 +1141,7 @@ int vfs_create(struct inode *dir, struct
- 
- 	DQUOT_INIT(dir);
- 	lock_kernel();
--	error = dir->i_op->create(dir, dentry, mode);
-+	error = dir->i_op->create(dir, dentry, mode);
- 	unlock_kernel();
- exit_lock:
- 	up(&dir->i_zombie);
-@@ -1045,14 +1199,17 @@ int may_open(struct nameidata *nd, int a
+@@ -1045,14 +1186,17 @@ int may_open(struct nameidata *nd, int a
          return get_lease(inode, flag);
  }
  
--struct file *filp_open(const char * pathname, int open_flags, int mode)
 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
 +				   int flags, struct lookup_intent *it);
 +
-+struct file *filp_open(const char * pathname, int open_flags, int mode)
+ struct file *filp_open(const char * pathname, int open_flags, int mode)
  {
  	int acc_mode, error = 0;
 -	struct inode *inode;
@@ -694,11 +661,18 @@
  	struct dentry *dir;
  	int flag = open_flags;
  	struct nameidata nd;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = open_flags };
++	struct lookup_intent it = { .it_op = IT_OPEN};
  	int count = 0;
  	
  	if (!capable(CAP_SYS_ADMIN))
-@@ -1069,7 +1226,7 @@ struct file *filp_open(const char * path
+@@ -1063,13 +1207,14 @@ struct file *filp_open(const char * path
+ 	if (flag & O_TRUNC)
+ 		flag |= 2;
+ 
++	it.it_flags = flag;
+ 	acc_mode = ACC_MODE(flag);
+ 
+ 	/*
  	 * The simplest case - just a plain lookup.
  	 */
  	if (!(flag & O_CREAT)) {
@@ -707,16 +681,16 @@
  		if (error)
  			return ERR_PTR(error);
  		dentry = nd.dentry;
-@@ -1079,6 +1236,8 @@ struct file *filp_open(const char * path
+@@ -1079,6 +1224,8 @@ struct file *filp_open(const char * path
  	/*
  	 * Create - we need to know the parent.
  	 */
-+	it.it_mode = mode;
++	it.it_create_mode = mode;
 +	it.it_op |= IT_CREAT;
  	error = path_lookup(pathname, LOOKUP_PARENT, &nd);
  	if (error)
  		return ERR_PTR(error);
-@@ -1094,7 +1253,7 @@ struct file *filp_open(const char * path
+@@ -1094,7 +1241,7 @@ struct file *filp_open(const char * path
  
  	dir = nd.dentry;
  	down(&dir->d_inode->i_sem);
@@ -725,11 +699,11 @@
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1103,10 +1262,11 @@ do_last:
+@@ -1103,10 +1250,11 @@ do_last:
  		goto exit;
  	}
  
-+	it.it_mode = mode;
++	it.it_create_mode = mode;
  	/* Negative dentry, just create the file */
  	if (!dentry->d_inode) {
 -		error = vfs_create(dir->d_inode, dentry,
@@ -739,7 +713,7 @@
  		up(&dir->d_inode->i_sem);
  		dput(nd.dentry);
  		nd.dentry = dentry;
-@@ -1132,12 +1292,12 @@ do_last:
+@@ -1132,12 +1280,12 @@ do_last:
  		error = -ELOOP;
  		if (flag & O_NOFOLLOW)
  			goto exit_dput;
@@ -754,7 +728,7 @@
  		goto do_link;
  
  	dput(nd.dentry);
-@@ -1152,11 +1312,13 @@ ok:
+@@ -1152,11 +1300,13 @@ ok:
  	if (!S_ISREG(nd.dentry->d_inode->i_mode))
  		open_flags &= ~O_TRUNC;
  
@@ -769,20 +743,14 @@
  	path_release(&nd);
  	return ERR_PTR(error);
  
-@@ -1175,10 +1337,19 @@ do_link:
+@@ -1175,10 +1325,14 @@ do_link:
  	 * are done. Procfs-like symlinks just set LAST_BIND.
  	 */
  	UPDATE_ATIME(dentry->d_inode);
--	error = dentry->d_inode->i_op->follow_link(dentry, &nd);
-+	nd.it = &it;
-+	error = dentry->d_inode->i_op->follow_link(dentry, &nd);
++	nd.intent = &it;
+ 	error = dentry->d_inode->i_op->follow_link(dentry, &nd);
 +	if (error) {
 +		intent_release(&it);
-+	} else if (!(it.it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
-+		intent_release(&it);
-+		path_release(&nd);
-+		error = -ENOLINK;
 +	}
  	dput(dentry);
  	if (error)
@@ -791,7 +759,7 @@
  	if (nd.last_type == LAST_BIND) {
  		dentry = nd.dentry;
  		goto ok;
-@@ -1197,13 +1368,15 @@ do_link:
+@@ -1197,13 +1351,15 @@ do_link:
  	}
  	dir = nd.dentry;
  	down(&dir->d_inode->i_sem);
@@ -809,7 +777,7 @@
  {
  	struct dentry *dentry;
  
-@@ -1211,7 +1384,7 @@ static struct dentry *lookup_create(stru
+@@ -1211,7 +1367,7 @@ static struct dentry *lookup_create(stru
  	dentry = ERR_PTR(-EEXIST);
  	if (nd->last_type != LAST_NORM)
  		goto fail;
@@ -818,7 +786,7 @@
  	if (IS_ERR(dentry))
  		goto fail;
  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1267,7 +1440,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1267,7 +1423,16 @@ asmlinkage long sys_mknod(const char * f
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -836,7 +804,7 @@
  	error = PTR_ERR(dentry);
  
  	mode &= ~current->fs->umask;
-@@ -1288,6 +1470,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1288,6 +1453,7 @@ asmlinkage long sys_mknod(const char * f
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -844,23 +812,23 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1335,7 +1518,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1335,7 +1501,14 @@ asmlinkage long sys_mkdir(const char * p
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
 -		dentry = lookup_create(&nd, 1);
-+ 		if (nd.dentry->d_inode->i_op->mkdir_raw) {
-+ 			struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 			error = op->mkdir_raw(&nd, mode);
-+ 			/* the file system wants to use normal vfs path now */
-+ 			if (error != -EOPNOTSUPP)
-+ 				goto out2;
-+ 		}
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
 +		dentry = lookup_create(&nd, 1, NULL);
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
  			error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1343,6 +1533,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1343,6 +1516,7 @@ asmlinkage long sys_mkdir(const char * p
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -868,42 +836,42 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1443,8 +1634,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1443,8 +1617,16 @@ asmlinkage long sys_rmdir(const char * p
  			error = -EBUSY;
  			goto exit1;
  	}
-+ 	if (nd.dentry->d_inode->i_op->rmdir_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
 +
-+ 		error = op->rmdir_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1502,8 +1701,15 @@ asmlinkage long sys_unlink(const char * 
+@@ -1502,8 +1684,15 @@ asmlinkage long sys_unlink(const char * 
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
-+ 	if (nd.dentry->d_inode->i_op->unlink_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 		error = op->unlink_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
-@@ -1570,15 +1776,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1570,15 +1759,23 @@ asmlinkage long sys_symlink(const char *
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -929,7 +897,7 @@
  		putname(to);
  	}
  	putname(from);
-@@ -1654,7 +1868,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1654,7 +1851,14 @@ asmlinkage long sys_link(const char * ol
  		error = -EXDEV;
  		if (old_nd.mnt != nd.mnt)
  			goto out_release;
@@ -945,7 +913,7 @@
  		error = PTR_ERR(new_dentry);
  		if (!IS_ERR(new_dentry)) {
  			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1698,7 +1919,7 @@ exit:
+@@ -1698,7 +1902,7 @@ exit:
   *	   locking].
   */
  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -954,7 +922,7 @@
  {
  	int error;
  	struct inode *target;
-@@ -1777,7 +1998,7 @@ out_unlock:
+@@ -1777,7 +1981,7 @@ out_unlock:
  }
  
  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
@@ -963,18 +931,18 @@
  {
  	int error;
  
-@@ -1865,9 +2086,18 @@ static inline int do_rename(const char *
+@@ -1865,9 +2069,18 @@ static inline int do_rename(const char *
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
  
-+ 	if (old_dir->d_inode->i_op->rename_raw) {
++	if (old_dir->d_inode->i_op->rename_raw) {
 +		lock_kernel();
-+ 		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
 +		unlock_kernel();
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit2;
-+ 	}
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
 +
  	double_lock(new_dir, old_dir);
  
@@ -983,7 +951,7 @@
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
-@@ -1883,16 +2113,16 @@ static inline int do_rename(const char *
+@@ -1883,16 +2096,16 @@ static inline int do_rename(const char *
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
@@ -1002,7 +970,7 @@
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
-@@ -1943,12 +2173,19 @@ out:
+@@ -1943,12 +2156,17 @@ out:
  }
  
  static inline int
@@ -1015,15 +983,13 @@
  	if (IS_ERR(link))
  		goto fail;
 +	if (it == NULL)
-+		it = nd->it;
-+	else if (it != nd->it)
-+		printk("it != nd->it: tell phil@clusterfs.com\n");
-+	if (it != NULL)
-+		it->it_int_flags |= IT_FL_FOLLOWED;
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
  
  	if (*link == '/') {
  		path_release(nd);
-@@ -1956,7 +2193,7 @@ __vfs_follow_link(struct nameidata *nd, 
+@@ -1956,7 +2174,7 @@ __vfs_follow_link(struct nameidata *nd, 
  			/* weird __emul_prefix() stuff did it */
  			goto out;
  	}
@@ -1032,7 +998,7 @@
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
  		return res;
-@@ -1978,7 +2215,13 @@ fail:
+@@ -1978,7 +2196,13 @@ fail:
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
@@ -1047,7 +1013,7 @@
  }
  
  /* get the link contents into pagecache */
-@@ -2020,7 +2263,7 @@ int page_follow_link(struct dentry *dent
+@@ -2020,7 +2244,7 @@ int page_follow_link(struct dentry *dent
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
@@ -1056,8 +1022,8 @@
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
---- linux-2.4.18-p4smp/fs/open.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:17:30.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/open.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/fs/open.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:06.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/open.c	2003-09-14 17:25:41.000000000 +0400
 @@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
@@ -1094,7 +1060,7 @@
  	up(&inode->i_sem);
  	return error;
  }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
+@@ -118,12 +127,13 @@ static inline long do_sys_truncate(const
  	struct nameidata nd;
  	struct inode * inode;
  	int error;
@@ -1109,7 +1075,7 @@
  	if (error)
  		goto out;
  	inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
+@@ -163,11 +173,13 @@ static inline long do_sys_truncate(const
  	error = locks_verify_truncate(inode, NULL, length);
  	if (!error) {
  		DQUOT_INIT(inode);
@@ -1124,7 +1090,7 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
+@@ -215,7 +227,7 @@ static inline long do_sys_ftruncate(unsi
  
  	error = locks_verify_truncate(inode, file, length);
  	if (!error)
@@ -1133,7 +1099,7 @@
  out_putf:
  	fput(file);
  out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
+@@ -260,11 +272,13 @@ asmlinkage long sys_utime(char * filenam
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1148,7 +1114,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -279,11 +294,25 @@ asmlinkage long sys_utime(char * filenam
+@@ -279,11 +293,25 @@ asmlinkage long sys_utime(char * filenam
  			goto dput_and_out;
  
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1175,7 +1141,7 @@
  	error = notify_change(nd.dentry, &newattrs);
  dput_and_out:
  	path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
+@@ -304,12 +332,14 @@ asmlinkage long sys_utimes(char * filena
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1191,7 +1157,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
+@@ -324,7 +354,20 @@ asmlinkage long sys_utimes(char * filena
  		newattrs.ia_atime = times[0].tv_sec;
  		newattrs.ia_mtime = times[1].tv_sec;
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1213,7 +1179,7 @@
  		if (current->fsuid != inode->i_uid &&
  		    (error = permission(inode,MAY_WRITE)) != 0)
  			goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
+@@ -347,6 +390,7 @@ asmlinkage long sys_access(const char * 
  	int old_fsuid, old_fsgid;
  	kernel_cap_t old_cap;
  	int res;
@@ -1221,7 +1187,7 @@
  
  	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
  		return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
+@@ -364,13 +408,14 @@ asmlinkage long sys_access(const char * 
  	else
  		current->cap_effective = current->cap_permitted;
  
@@ -1237,7 +1203,7 @@
  		path_release(&nd);
  	}
  
-@@ -385,8 +435,11 @@ asmlinkage long sys_chdir(const char * f
+@@ -385,8 +430,11 @@ asmlinkage long sys_chdir(const char * f
  {
  	int error;
  	struct nameidata nd;
@@ -1250,7 +1216,7 @@
  	if (error)
  		goto out;
  
-@@ -397,6 +450,7 @@ asmlinkage long sys_chdir(const char * f
+@@ -397,6 +445,7 @@ asmlinkage long sys_chdir(const char * f
  	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
  
  dput_and_out:
@@ -1258,7 +1224,7 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -436,9 +490,10 @@ asmlinkage long sys_chroot(const char * 
+@@ -436,9 +485,10 @@ asmlinkage long sys_chroot(const char * 
  {
  	int error;
  	struct nameidata nd;
@@ -1271,7 +1237,7 @@
  	if (error)
  		goto out;
  
-@@ -454,6 +509,7 @@ asmlinkage long sys_chroot(const char * 
+@@ -454,39 +504,56 @@ asmlinkage long sys_chroot(const char * 
  	set_fs_altroot();
  	error = 0;
  dput_and_out:
@@ -1279,26 +1245,102 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
  
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
 +	if (inode->i_op->setattr_raw) {
-+		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
 +		newattrs.ia_mode = mode;
 +		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 +		newattrs.ia_valid |= ATTR_RAW;
-+		error = op->setattr_raw(inode, &newattrs);
++		err = inode->i_op->setattr_raw(inode, &newattrs);
 +		/* the file system wants to use normal vfs path now */
-+		if (error != -EOPNOTSUPP)
-+			goto dput_and_out;
++		if (err != -EOPNOTSUPP)
++			goto out;
 +	}
-+
- 	error = -EPERM;
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -538,6 +606,20 @@ static int chown_common(struct dentry * 
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -495,30 +562,14 @@ out:
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
+-
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
++	error = chmod_common(nd.dentry, mode);
+ 
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -538,6 +589,20 @@ static int chown_common(struct dentry * 
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto out;
@@ -1319,7 +1361,7 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
-@@ -628,7 +710,8 @@ extern ssize_t do_readahead(struct file 
+@@ -628,7 +693,8 @@ extern ssize_t do_readahead(struct file 
  /* for files over a certains size it doesn't pay to do readahead on open */
  #define READAHEAD_CUTOFF 48000
  
@@ -1329,7 +1371,7 @@
  {
  	struct file * f;
  	struct inode *inode;
-@@ -649,7 +732,7 @@ struct file *dentry_open(struct dentry *
+@@ -649,7 +715,7 @@ struct file *dentry_open(struct dentry *
  		error = locks_verify_locked(inode);
  		if (!error) {
  			DQUOT_INIT(inode);
@@ -1338,7 +1380,7 @@
  		}
  		if (error || !(f->f_mode & FMODE_WRITE))
  			put_write_access(inode);
-@@ -679,7 +762,9 @@ struct file *dentry_open(struct dentry *
+@@ -679,7 +745,9 @@ struct file *dentry_open(struct dentry *
  	}
  
  	if (f->f_op && f->f_op->open) {
@@ -1348,7 +1390,7 @@
  		if (error)
  			goto cleanup_all;
  	}
-@@ -693,6 +778,7 @@ struct file *dentry_open(struct dentry *
+@@ -693,6 +761,7 @@ struct file *dentry_open(struct dentry *
  		do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
  	
  
@@ -1356,7 +1398,7 @@
  	return f;
  
  cleanup_all:
-@@ -707,11 +793,17 @@ cleanup_all:
+@@ -707,11 +776,17 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
@@ -1374,9 +1416,9 @@
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux-2.4.18-p4smp/fs/stat.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:17:30.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/stat.c	2003-07-09 13:20:37.000000000 -0600
-@@ -17,21 +17,24 @@
+--- linux-2.4.18-chaos/fs/stat.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:06.000000000 +0400
++++ linux-2.4.18-chaos-alexey/fs/stat.c	2003-09-14 17:30:21.000000000 +0400
+@@ -17,21 +17,26 @@
   * Revalidate the inode. This is required for proper NFS attribute caching.
   */
  static __inline__ int
@@ -1385,6 +1427,8 @@
  {
  	struct inode * inode = dentry->d_inode;
 -	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
 +	if (inode->i_op && inode->i_op->revalidate_it)
 +		return inode->i_op->revalidate_it(dentry, it);
 +	else if (inode->i_op && inode->i_op->revalidate)
@@ -1405,7 +1449,7 @@
  	if (res)
  		return res;
  
-@@ -104,10 +107,12 @@ int vfs_stat(char *name, struct kstat *s
+@@ -104,10 +109,12 @@ int vfs_stat(char *name, struct kstat *s
  {
  	struct nameidata nd;
  	int error;
@@ -1420,7 +1464,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -117,10 +122,12 @@ int vfs_lstat(char *name, struct kstat *
+@@ -117,10 +124,12 @@ int vfs_lstat(char *name, struct kstat *
  {
  	struct nameidata nd;
  	int error;
@@ -1435,7 +1479,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -132,7 +139,7 @@ int vfs_fstat(unsigned int fd, struct ks
+@@ -132,7 +141,7 @@ int vfs_fstat(unsigned int fd, struct ks
  	int error = -EBADF;
  
  	if (f) {
@@ -1444,7 +1488,7 @@
  		fput(f);
  	}
  	return error;
-@@ -279,7 +286,7 @@ asmlinkage long sys_readlink(const char 
+@@ -279,7 +288,7 @@ asmlinkage long sys_readlink(const char 
  
  		error = -EINVAL;
  		if (inode->i_op && inode->i_op->readlink &&
@@ -1453,23 +1497,11 @@
  			UPDATE_ATIME(inode);
  			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
  		}
---- linux-2.4.18-p4smp/fs/proc/base.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 12:20:46.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/proc/base.c	2003-07-09 13:20:37.000000000 -0600
-@@ -465,6 +465,9 @@ static int proc_pid_follow_link(struct d
+--- linux-2.4.18-chaos/include/linux/dcache.h~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:16.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/dcache.h	2003-09-14 17:25:41.000000000 +0400
+@@ -5,6 +5,51 @@
  
- 	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
- 	nd->last_type = LAST_BIND;
-+
-+	if (nd->it != NULL)
-+		nd->it->it_int_flags |= IT_FL_FOLLOWED;
- out:
- 	return error;
- }
---- linux-2.4.18-p4smp/include/linux/dcache.h~vfs_intent-2.4.18-18-chaos65	2003-07-09 13:15:23.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/include/linux/dcache.h	2003-07-09 13:32:08.000000000 -0600
-@@ -6,6 +6,45 @@
  #include <asm/atomic.h>
- #include <linux/gdb.h>
  #include <linux/mount.h>
 +#include <linux/string.h>
 +
@@ -1488,18 +1520,24 @@
 +
 +#define INTENT_MAGIC 0x19620323
 +
-+struct lookup_intent {
-+	int it_op;
-+	void (*it_op_release)(struct lookup_intent *);
-+	int it_magic;
-+	int it_mode;
-+	int it_flags;
-+	int it_disposition;
-+	int it_status;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
 +	int it_int_flags;
-+	__u64 it_lock_handle[2];
-+	int it_lock_mode;
-+	void *it_data;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op, int flags)
@@ -1513,7 +1551,7 @@
  
  /*
   * linux/include/linux/dcache.h
-@@ -92,8 +131,22 @@ struct dentry_operations {
+@@ -91,8 +136,22 @@ struct dentry_operations {
  	int (*d_delete)(struct dentry *);
  	void (*d_release)(struct dentry *);
  	void (*d_iput)(struct dentry *, struct inode *);
@@ -1536,7 +1574,7 @@
  /* the dentry parameter passed to d_hash and d_compare is the parent
   * directory of the entries to be compared. It is used in case these
   * functions need any directory specific information for determining
-@@ -125,6 +178,7 @@ d_iput:		no		no		yes
+@@ -124,6 +183,7 @@ d_iput:		no		no		yes
  					 * s_nfsd_free_path semaphore will be down
  					 */
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
@@ -1544,9 +1582,17 @@
  
  extern spinlock_t dcache_lock;
  
---- linux-2.4.18-p4smp/include/linux/fs.h~vfs_intent-2.4.18-18-chaos65	2003-07-08 14:41:47.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/include/linux/fs.h	2003-07-08 14:45:17.000000000 -0600
-@@ -339,6 +339,9 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.18-chaos/include/linux/fs.h~vfs_intent-2.4.18-18-chaos65	2003-09-14 17:24:21.000000000 +0400
++++ linux-2.4.18-chaos-alexey/include/linux/fs.h	2003-09-14 17:25:41.000000000 +0400
+@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -339,6 +340,9 @@ extern void set_bh_page(struct buffer_he
  #define ATTR_MTIME_SET	256
  #define ATTR_FORCE	512	/* Not a change, but a change it */
  #define ATTR_ATTR_FLAG	1024
@@ -1556,7 +1602,15 @@
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -578,6 +580,7 @@ struct file {
+@@ -474,6 +478,7 @@ struct inode {
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -578,6 +583,7 @@ struct file {
  
  	/* needed for tty driver, and maybe others */
  	void			*private_data;
@@ -1564,15 +1618,15 @@
  
  	/* preallocated helper kiobuf to speedup O_DIRECT */
  	struct kiobuf		*f_iobuf;
-@@ -707,6 +710,7 @@ struct nameidata {
+@@ -707,6 +713,7 @@ struct nameidata {
  	struct qstr last;
  	unsigned int flags;
  	int last_type;
-+	struct lookup_intent *it;
++	struct lookup_intent *intent;
  };
  
  #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
-@@ -840,7 +844,8 @@ extern int vfs_symlink(struct inode *, s
+@@ -840,7 +847,8 @@ extern int vfs_symlink(struct inode *, s
  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
  extern int vfs_rmdir(struct inode *, struct dentry *);
  extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1582,7 +1636,7 @@
  
  /*
   * File types
-@@ -900,21 +905,34 @@ struct file_operations {
+@@ -900,21 +908,34 @@ struct file_operations {
  
  struct inode_operations {
  	int (*create) (struct inode *,struct dentry *,int);
@@ -1613,11 +1667,11 @@
  	int (*revalidate) (struct dentry *);
 +	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
  	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
  	int (*getattr) (struct dentry *, struct iattr *);
  };
  
-@@ -1119,10 +1137,12 @@ static inline int get_lease(struct inode
+@@ -1119,10 +1140,12 @@ static inline int get_lease(struct inode
  
  asmlinkage long sys_open(const char *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
@@ -1631,7 +1685,7 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char *);
  
-@@ -1388,9 +1408,12 @@ typedef int (*read_actor_t)(read_descrip
+@@ -1388,9 +1411,12 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
@@ -1644,7 +1698,7 @@
  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
  extern void path_release(struct nameidata *);
  extern int follow_down(struct vfsmount **, struct dentry **);
-@@ -1399,6 +1422,8 @@ extern struct dentry * lookup_one_len(co
+@@ -1399,6 +1425,8 @@ extern struct dentry * lookup_one_len(co
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
  #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
@@ -1653,7 +1707,7 @@
  
  extern void inode_init_once(struct inode *);
  extern void iput(struct inode *);
-@@ -1499,6 +1524,8 @@ extern struct file_operations generic_ro
+@@ -1499,6 +1527,8 @@ extern struct file_operations generic_ro
  
  extern int vfs_readlink(struct dentry *, char *, int, const char *);
  extern int vfs_follow_link(struct nameidata *, const char *);
@@ -1662,8 +1716,8 @@
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.18-p4smp/kernel/fork.c~vfs_intent-2.4.18-18-chaos65	2003-03-24 11:22:37.000000000 -0700
-+++ linux-2.4.18-p4smp-braam/kernel/fork.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/kernel/fork.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:20.000000000 +0400
++++ linux-2.4.18-chaos-alexey/kernel/fork.c	2003-09-14 17:25:41.000000000 +0400
 @@ -399,10 +399,13 @@ static inline struct fs_struct *__copy_f
  		fs->umask = old->umask;
  		read_lock(&old->lock);
@@ -1678,8 +1732,8 @@
  			fs->altrootmnt = mntget(old->altrootmnt);
  			fs->altroot = dget(old->altroot);
  		} else {
---- linux-2.4.18-p4smp/kernel/exit.c~vfs_intent-2.4.18-18-chaos65	2002-10-29 12:27:38.000000000 -0700
-+++ linux-2.4.18-p4smp-braam/kernel/exit.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/kernel/exit.c~vfs_intent-2.4.18-18-chaos65	2003-07-28 17:52:20.000000000 +0400
++++ linux-2.4.18-chaos-alexey/kernel/exit.c	2003-09-14 17:25:41.000000000 +0400
 @@ -303,11 +303,14 @@ static inline void __put_fs_struct(struc
  {
  	/* No need to hold fs->lock if we are killing it */
@@ -1695,8 +1749,8 @@
  			dput(fs->altroot);
  			mntput(fs->altrootmnt);
  		}
---- linux-2.4.18-p4smp/kernel/ksyms.c~vfs_intent-2.4.18-18-chaos65	2003-07-09 13:20:35.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/kernel/ksyms.c	2003-07-09 13:20:37.000000000 -0600
+--- linux-2.4.18-chaos/kernel/ksyms.c~vfs_intent-2.4.18-18-chaos65	2003-09-14 17:24:22.000000000 +0400
++++ linux-2.4.18-chaos-alexey/kernel/ksyms.c	2003-09-14 17:25:41.000000000 +0400
 @@ -294,6 +294,7 @@ EXPORT_SYMBOL(read_cache_page);
  EXPORT_SYMBOL(set_page_dirty);
  EXPORT_SYMBOL(vfs_readlink);
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch
new file mode 100644
index 0000000000000000000000000000000000000000..43abf92c185c3a6ec762b806523aeeb48c107da6
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch
@@ -0,0 +1,1855 @@
+ fs/dcache.c               |   19 ++
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  295 +++++++++++++++++++++++++++++++++++++++-------
+ fs/namespace.c            |   28 +++-
+ fs/open.c                 |  172 +++++++++++++++++++-------
+ fs/stat.c                 |   52 +++++---
+ include/linux/dcache.h    |   60 +++++++++
+ include/linux/fs.h        |   32 ++++
+ include/linux/fs_struct.h |    4 
+ kernel/exit.c             |    3 
+ kernel/fork.c             |    3 
+ kernel/ksyms.c            |    1 
+ 12 files changed, 558 insertions(+), 128 deletions(-)
+
+Index: linux-2.4.19-pre1/fs/exec.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/exec.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/exec.c	2003-11-21 02:51:38.000000000 +0300
+@@ -107,8 +107,10 @@
+ 	struct file * file;
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
+ 
+-	error = user_path_walk(library, &nd);
++	error = user_path_walk_it(library, &nd, &it);
+ 	if (error)
+ 		goto out;
+ 
+@@ -120,7 +122,8 @@
+ 	if (error)
+ 		goto exit;
+ 
+-	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++	file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++	intent_release(&it);
+ 	error = PTR_ERR(file);
+ 	if (IS_ERR(file))
+ 		goto out;
+@@ -342,9 +345,11 @@
+ 	struct inode *inode;
+ 	struct file *file;
+ 	int err = 0;
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
+ 
+ 	if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+-		err = path_walk(name, &nd);
++		err = path_walk_it(name, &nd, &it);
+ 	file = ERR_PTR(err);
+ 	if (!err) {
+ 		inode = nd.dentry->d_inode;
+@@ -356,7 +361,8 @@
+ 				err = -EACCES;
+ 			file = ERR_PTR(err);
+ 			if (!err) {
+-				file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++				file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++				intent_release(&it);
+ 				if (!IS_ERR(file)) {
+ 					err = deny_write_access(file);
+ 					if (err) {
+@@ -368,6 +374,7 @@
+ 				return file;
+ 			}
+ 		}
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	goto out;
+@@ -970,7 +977,7 @@
+ 		goto close_fail;
+ 	if (!file->f_op->write)
+ 		goto close_fail;
+-	if (do_truncate(file->f_dentry, 0) != 0)
++	if (do_truncate(file->f_dentry, 0, 0) != 0)
+ 		goto close_fail;
+ 
+ 	retval = binfmt->core_dump(signr, regs, file);
+Index: linux-2.4.19-pre1/fs/dcache.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/dcache.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/dcache.c	2003-11-21 02:51:38.000000000 +0300
+@@ -181,6 +181,13 @@
+ 		spin_unlock(&dcache_lock);
+ 		return 0;
+ 	}
++
++	/* network invalidation by Lustre */
++	if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
++		spin_unlock(&dcache_lock);
++		return 0;
++	}
++
+ 	/*
+ 	 * Check whether to do a partial shrink_dcache
+ 	 * to get rid of unused child entries.
+@@ -831,13 +838,19 @@
+  * Adds a dentry to the hash according to its name.
+  */
+  
+-void d_rehash(struct dentry * entry)
++void __d_rehash(struct dentry * entry, int lock)
+ {
+ 	struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+ 	if (!list_empty(&entry->d_hash)) BUG();
+-	spin_lock(&dcache_lock);
++	if (lock) spin_lock(&dcache_lock);
+ 	list_add(&entry->d_hash, list);
+-	spin_unlock(&dcache_lock);
++	if (lock) spin_unlock(&dcache_lock);
++}
++EXPORT_SYMBOL(__d_rehash);
++
++void d_rehash(struct dentry * entry)
++{
++	__d_rehash(entry, 1);
+ }
+ 
+ #define do_switch(x,y) do { \
+Index: linux-2.4.19-pre1/fs/namespace.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/namespace.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/namespace.c	2003-11-21 02:51:38.000000000 +0300
+@@ -107,6 +107,7 @@
+ {
+ 	old_nd->dentry = mnt->mnt_mountpoint;
+ 	old_nd->mnt = mnt->mnt_parent;
++	UNPIN(old_nd->dentry, old_nd->mnt, 1);
+ 	mnt->mnt_parent = mnt;
+ 	mnt->mnt_mountpoint = mnt->mnt_root;
+ 	list_del_init(&mnt->mnt_child);
+@@ -118,6 +119,7 @@
+ {
+ 	mnt->mnt_parent = mntget(nd->mnt);
+ 	mnt->mnt_mountpoint = dget(nd->dentry);
++	PIN(nd->dentry, nd->mnt, 1);
+ 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+ 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+ 	nd->dentry->d_mounted++;
+@@ -500,15 +502,18 @@
+ {
+ 	struct nameidata old_nd;
+ 	struct vfsmount *mnt = NULL;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int err = mount_is_safe(nd);
+ 	if (err)
+ 		return err;
+ 	if (!old_name || !*old_name)
+ 		return -EINVAL;
+ 	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+-		err = path_walk(old_name, &old_nd);
+-	if (err)
++		err = path_walk_it(old_name, &old_nd, &it);
++	if (err) {
++		intent_release(&it);
+ 		return err;
++	}
+ 
+ 	down(&mount_sem);
+ 	err = -EINVAL;
+@@ -531,6 +536,7 @@
+ 	}
+ 
+ 	up(&mount_sem);
++	intent_release(&it);
+ 	path_release(&old_nd);
+ 	return err;
+ }
+@@ -706,6 +712,7 @@
+ 		  unsigned long flags, void *data_page)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int retval = 0;
+ 	int mnt_flags = 0;
+ 
+@@ -731,9 +738,11 @@
+ 
+ 	/* ... and get the mountpoint */
+ 	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+-		retval = path_walk(dir_name, &nd);
+-	if (retval)
++		retval = path_walk_it(dir_name, &nd, &it);
++	if (retval) {
++		intent_release(&it);
+ 		return retval;
++	}
+ 
+ 	if (flags & MS_REMOUNT)
+ 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+@@ -745,6 +754,8 @@
+ 	else
+ 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+ 				      dev_name, data_page);
++
++	intent_release(&it);
+ 	path_release(&nd);
+ 	return retval;
+ }
+@@ -830,6 +841,8 @@
+ {
+ 	struct vfsmount *tmp;
+ 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
++	struct lookup_intent new_it = { .it_op = IT_GETATTR };
++	struct lookup_intent old_it = { .it_op = IT_GETATTR };
+ 	char *name;
+ 	int error;
+ 
+@@ -844,7 +857,7 @@
+ 		goto out0;
+ 	error = 0;
+ 	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
+-		error = path_walk(name, &new_nd);
++		error = path_walk_it(name, &new_nd, &new_it);
+ 	putname(name);
+ 	if (error)
+ 		goto out0;
+@@ -858,7 +871,7 @@
+ 		goto out1;
+ 	error = 0;
+ 	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
+-		error = path_walk(name, &old_nd);
++		error = path_walk_it(name, &old_nd, &old_it);
+ 	putname(name);
+ 	if (error)
+ 		goto out1;
+@@ -914,8 +927,10 @@
+ 	up(&old_nd.dentry->d_inode->i_zombie);
+ 	up(&mount_sem);
+ 	path_release(&user_nd);
++	intent_release(&old_it);
+ 	path_release(&old_nd);
+ out1:
++	intent_release(&new_it);
+ 	path_release(&new_nd);
+ out0:
+ 	unlock_kernel();
+Index: linux-2.4.19-pre1/fs/namei.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/namei.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/namei.c	2003-11-21 02:52:01.000000000 +0300
+@@ -94,6 +94,13 @@
+  * XEmacs seems to be relying on it...
+  */
+ 
++void intent_release(struct lookup_intent *it)
++{
++	if (it && it->it_op_release)
++		it->it_op_release(it);
++
++}
++
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+  * kernel data space before using them..
+@@ -260,10 +267,19 @@
+  * Internal lookup() using the new generic dcache.
+  * SMP-safe
+  */
+-static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
++static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
++				    int flags, struct lookup_intent *it)
+ {
+ 	struct dentry * dentry = d_lookup(parent, name);
+ 
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, flags, it) &&
++		    !d_invalidate(dentry)) {
++			dput(dentry);
++			dentry = NULL;
++		}
++		return dentry;
++	} else
+ 	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
+ 		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
+ 			dput(dentry);
+@@ -281,11 +297,15 @@
+  * make sure that nobody added the entry to the dcache in the meantime..
+  * SMP-safe
+  */
+-static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
++static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
++				  int flags, struct lookup_intent *it)
+ {
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
++	int counter = 0;
+ 
++again:
++	counter++;
+ 	down(&dir->i_sem);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+@@ -300,6 +320,9 @@
+ 		result = ERR_PTR(-ENOMEM);
+ 		if (dentry) {
+ 			lock_kernel();
++			if (dir->i_op->lookup_it)
++				result = dir->i_op->lookup_it(dir, dentry, it, flags);
++			else
+ 			result = dir->i_op->lookup(dir, dentry);
+ 			unlock_kernel();
+ 			if (result)
+@@ -321,6 +344,15 @@
+ 			dput(result);
+ 			result = ERR_PTR(-ENOENT);
+ 		}
++	} else if (result->d_op && result->d_op->d_revalidate_it) {
++		if (!result->d_op->d_revalidate_it(result, flags, it) &&
++		    !d_invalidate(result)) {
++			dput(result);
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
++		}
+ 	}
+ 	return result;
+ }
+@@ -332,7 +364,8 @@
+  * Without that kind of total limit, nasty chains of consecutive
+  * symlinks can cause almost arbitrarily long lookups. 
+  */
+-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
++static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
++				 struct lookup_intent *it)
+ {
+ 	int err;
+ 	if (current->link_count >= 5)
+@@ -346,10 +379,12 @@
+ 	current->link_count++;
+ 	current->total_link_count++;
+ 	UPDATE_ATIME(dentry->d_inode);
++	nd->intent = it;
+ 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
+ 	current->link_count--;
+ 	return err;
+ loop:
++	intent_release(it);
+ 	path_release(nd);
+ 	return -ELOOP;
+ }
+@@ -445,7 +480,8 @@
+  *
+  * We expect 'base' to be positive and a directory.
+  */
+-int link_path_walk(const char * name, struct nameidata *nd)
++int link_path_walk_it(const char *name, struct nameidata *nd,
++		      struct lookup_intent *it)
+ {
+ 	struct dentry *dentry;
+ 	struct inode *inode;
+@@ -455,7 +491,7 @@
+ 	while (*name=='/')
+ 		name++;
+ 	if (!*name)
+-		goto return_base;
++		goto return_reval;
+ 
+ 	inode = nd->dentry->d_inode;
+ 	if (current->link_count)
+@@ -518,9 +554,10 @@
+ 				break;
+ 		}
+ 		/* This does the actual lookups.. */
+-		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
++		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
+ 		if (!dentry) {
+-			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
++			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE,
++						NULL);
+ 			err = PTR_ERR(dentry);
+ 			if (IS_ERR(dentry))
+ 				break;
+@@ -538,7 +575,7 @@
+ 			goto out_dput;
+ 
+ 		if (inode->i_op->follow_link) {
+-			err = do_follow_link(dentry, nd);
++			err = do_follow_link(dentry, nd, NULL);
+ 			dput(dentry);
+ 			if (err)
+ 				goto return_err;
+@@ -554,7 +591,7 @@
+ 			nd->dentry = dentry;
+ 		}
+ 		err = -ENOTDIR; 
+-		if (!inode->i_op->lookup)
++		if (!inode->i_op->lookup && !inode->i_op->lookup_it)
+ 			break;
+ 		continue;
+ 		/* here ends the main loop */
+@@ -574,16 +611,16 @@
+ 				inode = nd->dentry->d_inode;
+ 				/* fallthrough */
+ 			case 1:
+-				goto return_base;
++				goto return_reval;
+ 		}
+ 		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
+ 			err = nd->dentry->d_op->d_hash(nd->dentry, &this);
+ 			if (err < 0)
+ 				break;
+ 		}
+-		dentry = cached_lookup(nd->dentry, &this, 0);
++		dentry = cached_lookup(nd->dentry, &this, 0, it);
+ 		if (!dentry) {
+-			dentry = real_lookup(nd->dentry, &this, 0);
++			dentry = real_lookup(nd->dentry, &this, 0, it);
+ 			err = PTR_ERR(dentry);
+ 			if (IS_ERR(dentry))
+ 				break;
+@@ -593,7 +630,7 @@
+ 		inode = dentry->d_inode;
+ 		if ((lookup_flags & LOOKUP_FOLLOW)
+ 		    && inode && inode->i_op && inode->i_op->follow_link) {
+-			err = do_follow_link(dentry, nd);
++			err = do_follow_link(dentry, nd, it);
+ 			dput(dentry);
+ 			if (err)
+ 				goto return_err;
+@@ -607,7 +644,8 @@
+ 			goto no_inode;
+ 		if (lookup_flags & LOOKUP_DIRECTORY) {
+ 			err = -ENOTDIR; 
+-			if (!inode->i_op || !inode->i_op->lookup)
++			if (!inode->i_op ||
++			    (!inode->i_op->lookup && !inode->i_op->lookup_it))
+ 				break;
+ 		}
+ 		goto return_base;
+@@ -625,21 +663,66 @@
+ 			nd->last_type = LAST_DOT;
+ 		else if (this.len == 2 && this.name[1] == '.')
+ 			nd->last_type = LAST_DOTDOT;
++return_reval:
++		/*
++		 * We bypassed the ordinary revalidation routines.
++		 * Check the cached dentry for staleness.
++		 */
++		dentry = nd->dentry;
++		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++			err = -ESTALE;
++			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
++				struct dentry *new;
++				err = permission(dentry->d_parent->d_inode,
++						 MAY_EXEC);
++				if (err)
++					break;
++				new = real_lookup(dentry->d_parent,
++						  &dentry->d_name, 0, NULL);
++				d_invalidate(dentry);
++				dput(dentry);
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
++			}
++		} else
++		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
++			err = -ESTALE;
++			if (!dentry->d_op->d_revalidate(dentry, 0)) {
++				d_invalidate(dentry);
++				break;
++			}
++		}
+ return_base:
+ 		return 0;
+ out_dput:
+ 		dput(dentry);
+ 		break;
+ 	}
++	if (err)
++		intent_release(it);
+ 	path_release(nd);
+ return_err:
+ 	return err;
+ }
+ 
++int link_path_walk(const char * name, struct nameidata *nd)
++{
++	return link_path_walk_it(name, nd, NULL);
++}
++
++int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
++{
++	current->total_link_count = 0;
++	return link_path_walk_it(name, nd, it);
++}
++
+ int path_walk(const char * name, struct nameidata *nd)
+ {
+ 	current->total_link_count = 0;
+-	return link_path_walk(name, nd);
++	return link_path_walk_it(name, nd, NULL);
+ }
+ 
+ /* SMP-safe */
+@@ -728,6 +811,7 @@
+ {
+ 	nd->last_type = LAST_ROOT; /* if there are only slashes... */
+ 	nd->flags = flags;
++	nd->intent = NULL;
+ 	if (*name=='/')
+ 		return walk_init_root(name,nd);
+ 	read_lock(&current->fs->lock);
+@@ -742,7 +826,8 @@
+  * needs parent already locked. Doesn't follow mounts.
+  * SMP-safe.
+  */
+-struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
++struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
++			       struct lookup_intent *it)
+ {
+ 	struct dentry * dentry;
+ 	struct inode *inode;
+@@ -765,13 +850,16 @@
+ 			goto out;
+ 	}
+ 
+-	dentry = cached_lookup(base, name, 0);
++	dentry = cached_lookup(base, name, 0, it);
+ 	if (!dentry) {
+ 		struct dentry *new = d_alloc(base, name);
+ 		dentry = ERR_PTR(-ENOMEM);
+ 		if (!new)
+ 			goto out;
+ 		lock_kernel();
++		if (inode->i_op->lookup_it)
++			dentry = inode->i_op->lookup_it(inode, new, it, 0);
++		else
+ 		dentry = inode->i_op->lookup(inode, new);
+ 		unlock_kernel();
+ 		if (!dentry)
+@@ -783,6 +871,12 @@
+ 	return dentry;
+ }
+ 
++struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
++{
++	return lookup_hash_it(name, base, NULL);
++}
++
++
+ /* SMP-safe */
+ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
+ {
+@@ -804,7 +898,7 @@
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash(&this, base);
++	return lookup_hash_it(&this, base, NULL);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+@@ -836,6 +930,23 @@
+ 	return err;
+ }
+ 
++int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
++		   struct lookup_intent *it)
++{
++	char *tmp;
++	int err;
++
++	tmp = getname(name);
++	err = PTR_ERR(tmp);
++	if (!IS_ERR(tmp)) {
++		err = 0;
++		if (path_init(tmp, flags, nd))
++			err = path_walk_it(tmp, nd, it);
++		putname(tmp);
++	}
++	return err;
++}
++
+ /*
+  * It's inline, so penalty for filesystems that don't use sticky bit is
+  * minimal.
+@@ -929,7 +1040,8 @@
+ 	return retval;
+ }
+ 
+-int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
++static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode,
++			 struct lookup_intent *it)
+ {
+ 	int error;
+ 
+@@ -942,12 +1054,15 @@
+ 		goto exit_lock;
+ 
+ 	error = -EACCES;	/* shouldn't it be ENOSYS? */
+-	if (!dir->i_op || !dir->i_op->create)
++	if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it))
+ 		goto exit_lock;
+ 
+ 	DQUOT_INIT(dir);
+ 	lock_kernel();
+-	error = dir->i_op->create(dir, dentry, mode);
++	if (dir->i_op->create_it)
++		error = dir->i_op->create_it(dir, dentry, mode, it);
++	else
++		error = dir->i_op->create(dir, dentry, mode);
+ 	unlock_kernel();
+ exit_lock:
+ 	up(&dir->i_zombie);
+@@ -956,6 +1071,11 @@
+ 	return error;
+ }
+ 
++int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
++{
++	return vfs_create_it(dir, dentry, mode, NULL);
++}
++
+ /*
+  *	open_namei()
+  *
+@@ -970,7 +1090,8 @@
+  * for symlinks (where the permissions are checked later).
+  * SMP-safe
+  */
+-int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
++int open_namei_it(const char *pathname, int flag, int mode,
++		  struct nameidata *nd, struct lookup_intent *it)
+ {
+ 	int acc_mode, error = 0;
+ 	struct inode *inode;
+@@ -980,12 +1101,14 @@
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
+ 	/*
+ 	 * The simplest case - just a plain lookup.
+ 	 */
+ 	if (!(flag & O_CREAT)) {
+ 		if (path_init(pathname, lookup_flags(flag), nd))
+-			error = path_walk(pathname, nd);
++			error = path_walk_it(pathname, nd, it);
+ 		if (error)
+ 			return error;
+ 		dentry = nd->dentry;
+@@ -995,6 +1118,10 @@
+ 	/*
+ 	 * Create - we need to know the parent.
+ 	 */
++	if (it) {
++		it->it_create_mode = mode;
++		it->it_op |= IT_CREAT;
++	}
+ 	if (path_init(pathname, LOOKUP_PARENT, nd))
+ 		error = path_walk(pathname, nd);
+ 	if (error)
+@@ -1011,7 +1138,7 @@
+ 
+ 	dir = nd->dentry;
+ 	down(&dir->d_inode->i_sem);
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 
+ do_last:
+ 	error = PTR_ERR(dentry);
+@@ -1020,10 +1147,11 @@
+ 		goto exit;
+ 	}
+ 
++	it->it_create_mode = mode;
+ 	/* Negative dentry, just create the file */
+ 	if (!dentry->d_inode) {
+-		error = vfs_create(dir->d_inode, dentry,
+-				   mode & ~current->fs->umask);
++		error = vfs_create_it(dir->d_inode, dentry,
++				      mode & ~current->fs->umask, it);
+ 		up(&dir->d_inode->i_sem);
+ 		dput(nd->dentry);
+ 		nd->dentry = dentry;
+@@ -1127,7 +1255,7 @@
+ 		if (!error) {
+ 			DQUOT_INIT(inode);
+ 			
+-			error = do_truncate(dentry, 0);
++			error = do_truncate(dentry, 0, 1);
+ 		}
+ 		put_write_access(inode);
+ 		if (error)
+@@ -1139,8 +1267,10 @@
+ 	return 0;
+ 
+ exit_dput:
++	intent_release(it);
+ 	dput(dentry);
+ exit:
++	intent_release(it);
+ 	path_release(nd);
+ 	return error;
+ 
+@@ -1159,7 +1289,10 @@
+ 	 * are done. Procfs-like symlinks just set LAST_BIND.
+ 	 */
+ 	UPDATE_ATIME(dentry->d_inode);
++	nd->intent = it;
+ 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
++	if (error)
++		intent_release(it);
+ 	dput(dentry);
+ 	if (error)
+ 		return error;
+@@ -1181,13 +1314,20 @@
+ 	}
+ 	dir = nd->dentry;
+ 	down(&dir->d_inode->i_sem);
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 	putname(nd->last.name);
+ 	goto do_last;
+ }
+ 
++int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
++{
++	return open_namei_it(pathname, flag, mode, nd, NULL);
++}
++
++
+ /* SMP-safe */
+-static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
++static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
++				    struct lookup_intent *it)
+ {
+ 	struct dentry *dentry;
+ 
+@@ -1195,7 +1335,7 @@
+ 	dentry = ERR_PTR(-EEXIST);
+ 	if (nd->last_type != LAST_NORM)
+ 		goto fail;
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 	if (IS_ERR(dentry))
+ 		goto fail;
+ 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
+@@ -1252,7 +1392,16 @@
+ 		error = path_walk(tmp, &nd);
+ 	if (error)
+ 		goto out;
+-	dentry = lookup_create(&nd, 0);
++
++	if (nd.dentry->d_inode->i_op->mknod_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->mknod_raw(&nd, mode, dev);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto out2;
++	}
++
++	dentry = lookup_create(&nd, 0, NULL);
+ 	error = PTR_ERR(dentry);
+ 
+ 	mode &= ~current->fs->umask;
+@@ -1273,6 +1422,7 @@
+ 		dput(dentry);
+ 	}
+ 	up(&nd.dentry->d_inode->i_sem);
++out2:
+ 	path_release(&nd);
+ out:
+ 	putname(tmp);
+@@ -1321,7 +1471,14 @@
+ 			error = path_walk(tmp, &nd);
+ 		if (error)
+ 			goto out;
+-		dentry = lookup_create(&nd, 1);
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
++		dentry = lookup_create(&nd, 1, NULL);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+ 			error = vfs_mkdir(nd.dentry->d_inode, dentry,
+@@ -1329,6 +1486,7 @@
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++out2:
+ 		path_release(&nd);
+ out:
+ 		putname(tmp);
+@@ -1428,8 +1586,16 @@
+ 			error = -EBUSY;
+ 			goto exit1;
+ 	}
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
+ 	down(&nd.dentry->d_inode->i_sem);
+-	dentry = lookup_hash(&nd.last, nd.dentry);
++	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+@@ -1488,8 +1654,15 @@
+ 	error = -EISDIR;
+ 	if (nd.last_type != LAST_NORM)
+ 		goto exit1;
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
+ 	down(&nd.dentry->d_inode->i_sem);
+-	dentry = lookup_hash(&nd.last, nd.dentry);
++	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		/* Why not before? Because we want correct error value */
+@@ -1557,15 +1730,23 @@
+ 			error = path_walk(to, &nd);
+ 		if (error)
+ 			goto out;
+-		dentry = lookup_create(&nd, 0);
++		if (nd.dentry->d_inode->i_op->symlink_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->symlink_raw(&nd, from);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
++		dentry = lookup_create(&nd, 0, NULL);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+ 			error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++	out2:
+ 		path_release(&nd);
+-out:
++	out:
+ 		putname(to);
+ 	}
+ 	putname(from);
+@@ -1648,7 +1829,14 @@
+ 		error = -EXDEV;
+ 		if (old_nd.mnt != nd.mnt)
+ 			goto out_release;
+-		new_dentry = lookup_create(&nd, 0);
++		if (nd.dentry->d_inode->i_op->link_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->link_raw(&old_nd, &nd);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out_release;
++		}
++		new_dentry = lookup_create(&nd, 0, NULL);
+ 		error = PTR_ERR(new_dentry);
+ 		if (!IS_ERR(new_dentry)) {
+ 			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+@@ -1694,7 +1882,7 @@
+  *	   locking].
+  */
+ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++		   struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	int error;
+ 	struct inode *target;
+@@ -1775,7 +1963,7 @@
+ }
+ 
+ int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++		     struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	int error;
+ 
+@@ -1866,9 +2054,18 @@
+ 	if (newnd.last_type != LAST_NORM)
+ 		goto exit2;
+ 
++	if (old_dir->d_inode->i_op->rename_raw) {
++		lock_kernel();
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		unlock_kernel();
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
++
+ 	double_lock(new_dir, old_dir);
+ 
+-	old_dentry = lookup_hash(&oldnd.last, old_dir);
++	old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
+ 	error = PTR_ERR(old_dentry);
+ 	if (IS_ERR(old_dentry))
+ 		goto exit3;
+@@ -1884,16 +2081,16 @@
+ 		if (newnd.last.name[newnd.last.len])
+ 			goto exit4;
+ 	}
+-	new_dentry = lookup_hash(&newnd.last, new_dir);
++	new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
+ 	error = PTR_ERR(new_dentry);
+ 	if (IS_ERR(new_dentry))
+ 		goto exit4;
+ 
++
+ 	lock_kernel();
+ 	error = vfs_rename(old_dir->d_inode, old_dentry,
+ 				   new_dir->d_inode, new_dentry);
+ 	unlock_kernel();
+-
+ 	dput(new_dentry);
+ exit4:
+ 	dput(old_dentry);
+@@ -1944,20 +2141,26 @@
+ }
+ 
+ static inline int
+-__vfs_follow_link(struct nameidata *nd, const char *link)
++__vfs_follow_link(struct nameidata *nd, const char *link,
++		  struct lookup_intent *it)
+ {
+ 	int res = 0;
+ 	char *name;
+ 	if (IS_ERR(link))
+ 		goto fail;
+ 
++	if (it == NULL)
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
++
+ 	if (*link == '/') {
+ 		path_release(nd);
+ 		if (!walk_init_root(link, nd))
+ 			/* weird __emul_prefix() stuff did it */
+ 			goto out;
+ 	}
+-	res = link_path_walk(link, nd);
++	res = link_path_walk_it(link, nd, it);
+ out:
+ 	if (current->link_count || res || nd->last_type!=LAST_NORM)
+ 		return res;
+@@ -1979,7 +2182,13 @@
+ 
+ int vfs_follow_link(struct nameidata *nd, const char *link)
+ {
+-	return __vfs_follow_link(nd, link);
++	return __vfs_follow_link(nd, link, NULL);
++}
++
++int vfs_follow_link_it(struct nameidata *nd, const char *link,
++		       struct lookup_intent *it)
++{
++	return __vfs_follow_link(nd, link, it);
+ }
+ 
+ /* get the link contents into pagecache */
+@@ -2021,7 +2230,7 @@
+ {
+ 	struct page *page = NULL;
+ 	char *s = page_getlink(dentry, &page);
+-	int res = __vfs_follow_link(nd, s);
++	int res = __vfs_follow_link(nd, s, NULL);
+ 	if (page) {
+ 		kunmap(page);
+ 		page_cache_release(page);
+Index: linux-2.4.19-pre1/fs/open.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/open.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/open.c	2003-11-21 02:51:38.000000000 +0300
+@@ -19,6 +19,8 @@
+ #include <asm/uaccess.h>
+ 
+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
++extern int path_walk_it(const char *name, struct nameidata *nd,
++			struct lookup_intent *it);
+ 
+ int vfs_statfs(struct super_block *sb, struct statfs *buf)
+ {
+@@ -71,9 +73,10 @@
+ 	return error;
+ }
+ 
+-int do_truncate(struct dentry *dentry, loff_t length)
++int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
+ {
+ 	struct inode *inode = dentry->d_inode;
++	struct inode_operations *op = dentry->d_inode->i_op;
+ 	int error;
+ 	struct iattr newattrs;
+ 
+@@ -84,7 +87,13 @@
+ 	down(&inode->i_sem);
+ 	newattrs.ia_size = length;
+ 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+-	error = notify_change(dentry, &newattrs);
++	if (called_from_open)
++		newattrs.ia_valid |= ATTR_FROM_OPEN;
++	if (op->setattr_raw) {
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++	} else
++		error = notify_change(dentry, &newattrs);
+ 	up(&inode->i_sem);
+ 	return error;
+ }
+@@ -94,12 +103,13 @@
+ 	struct nameidata nd;
+ 	struct inode * inode;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	error = -EINVAL;
+ 	if (length < 0)	/* sorry, but loff_t says... */
+ 		goto out;
+ 
+-	error = user_path_walk(path, &nd);
++	error = user_path_walk_it(path, &nd, &it);
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+@@ -139,11 +149,13 @@
+ 	error = locks_verify_truncate(inode, NULL, length);
+ 	if (!error) {
+ 		DQUOT_INIT(inode);
+-		error = do_truncate(nd.dentry, length);
++		intent_release(&it);
++		error = do_truncate(nd.dentry, length, 0);
+ 	}
+ 	put_write_access(inode);
+ 
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -191,7 +203,7 @@
+ 
+ 	error = locks_verify_truncate(inode, file, length);
+ 	if (!error)
+-		error = do_truncate(dentry, length);
++		error = do_truncate(dentry, length, 0);
+ out_putf:
+ 	fput(file);
+ out:
+@@ -236,11 +248,13 @@
+ 	struct inode * inode;
+ 	struct iattr newattrs;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, NULL);
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+ 
++	/* this is safe without a Lustre lock because it only depends
++	   on the super block */
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+@@ -255,11 +269,25 @@
+ 			goto dput_and_out;
+ 
+ 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-	} else {
++	}
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	}
++
++	error = -EPERM;
++	if (!times) {
+ 		if (current->fsuid != inode->i_uid &&
+ 		    (error = permission(inode,MAY_WRITE)) != 0)
+ 			goto dput_and_out;
+ 	}
++
+ 	error = notify_change(nd.dentry, &newattrs);
+ dput_and_out:
+ 	path_release(&nd);
+@@ -280,12 +308,14 @@
+ 	struct inode * inode;
+ 	struct iattr newattrs;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, NULL);
+ 
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+ 
++	/* this is safe without a Lustre lock because it only depends
++	   on the super block */
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+@@ -300,7 +330,20 @@
+ 		newattrs.ia_atime = times[0].tv_sec;
+ 		newattrs.ia_mtime = times[1].tv_sec;
+ 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-	} else {
++	}
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	}
++
++	error = -EPERM;
++	if (!utimes) {
+ 		if ((error = permission(inode,MAY_WRITE)) != 0)
+ 			goto dput_and_out;
+ 	}
+@@ -322,6 +365,7 @@
+ 	int old_fsuid, old_fsgid;
+ 	kernel_cap_t old_cap;
+ 	int res;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
+ 		return -EINVAL;
+@@ -339,13 +383,14 @@
+ 	else
+ 		current->cap_effective = current->cap_permitted;
+ 
+-	res = user_path_walk(filename, &nd);
++	res = user_path_walk_it(filename, &nd, &it);
+ 	if (!res) {
+ 		res = permission(nd.dentry->d_inode, mode);
+ 		/* SuS v2 requires we report a read only fs too */
+ 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+ 		   && !special_file(nd.dentry->d_inode->i_mode))
+ 			res = -EROFS;
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 
+@@ -361,6 +406,7 @@
+ 	int error;
+ 	struct nameidata nd;
+ 	char *name;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	name = getname(filename);
+ 	error = PTR_ERR(name);
+@@ -369,7 +415,7 @@
+ 
+ 	error = 0;
+ 	if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
+-		error = path_walk(name, &nd);
++		error = path_walk_it(name, &nd, &it);
+ 	putname(name);
+ 	if (error)
+ 		goto out;
+@@ -381,6 +427,7 @@
+ 	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+ 
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -421,6 +468,7 @@
+ 	int error;
+ 	struct nameidata nd;
+ 	char *name;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	name = getname(filename);
+ 	error = PTR_ERR(name);
+@@ -429,7 +477,7 @@
+ 
+ 	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
+ 		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
+-	error = path_walk(name, &nd);	
++	error = path_walk_it(name, &nd, &it);
+ 	putname(name);
+ 	if (error)
+ 		goto out;
+@@ -446,39 +494,56 @@
+ 	set_fs_altroot();
+ 	error = 0;
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
+ 
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
++	if (inode->i_op->setattr_raw) {
++		newattrs.ia_mode = mode;
++		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
++		newattrs.ia_valid |= ATTR_RAW;
++		err = inode->i_op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (err != -EOPNOTSUPP)
++			goto out;
++	}
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -487,30 +552,14 @@
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
++	error = chmod_common(nd.dentry, mode);
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
+-
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -530,6 +579,20 @@
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto out;
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = dentry->d_inode->i_op;
++
++		newattrs.ia_uid = user;
++		newattrs.ia_gid = group;
++		newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			return error;
++	}
++
+ 	error = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ 		goto out;
+@@ -634,6 +697,7 @@
+ {
+ 	int namei_flags, error;
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_OPEN };
+ 
+ 	namei_flags = flags;
+ 	if ((namei_flags+1) & O_ACCMODE)
+@@ -641,14 +705,15 @@
+ 	if (namei_flags & O_TRUNC)
+ 		namei_flags |= 2;
+ 
+-	error = open_namei(filename, namei_flags, mode, &nd);
+-	if (!error)
+-		return dentry_open(nd.dentry, nd.mnt, flags);
++	error = open_namei_it(filename, namei_flags, mode, &nd, &it);
++	if (error)
++		return ERR_PTR(error);
+ 
+-	return ERR_PTR(error);
++	return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
+ }
+ 
+-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
++			    int flags, struct lookup_intent *it)
+ {
+ 	struct file * f;
+ 	struct inode *inode;
+@@ -685,12 +750,15 @@
+ 	}
+ 
+ 	if (f->f_op && f->f_op->open) {
++		f->f_it = it;
+ 		error = f->f_op->open(inode,f);
++		f->f_it = NULL;
+ 		if (error)
+ 			goto cleanup_all;
+ 	}
+ 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ 
++	intent_release(it);
+ 	return f;
+ 
+ cleanup_all:
+@@ -705,11 +773,17 @@
+ cleanup_file:
+ 	put_filp(f);
+ cleanup_dentry:
++	intent_release(it);
+ 	dput(dentry);
+ 	mntput(mnt);
+ 	return ERR_PTR(error);
+ }
+ 
++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++{
++	return dentry_open_it(dentry, mnt, flags, NULL);
++}
++
+ /*
+  * Find an empty file descriptor entry, and mark it busy.
+  */
+Index: linux-2.4.19-pre1/fs/stat.c
+===================================================================
+--- linux-2.4.19-pre1.orig/fs/stat.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/fs/stat.c	2003-11-21 02:51:38.000000000 +0300
+@@ -17,10 +17,14 @@
+  * Revalidate the inode. This is required for proper NFS attribute caching.
+  */
+ static __inline__ int
+-do_revalidate(struct dentry *dentry)
++do_revalidate(struct dentry *dentry, struct lookup_intent *it)
+ {
+ 	struct inode * inode = dentry->d_inode;
+-	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
++	if (inode->i_op && inode->i_op->revalidate_it)
++		return inode->i_op->revalidate_it(dentry, it);
++	else if (inode->i_op && inode->i_op->revalidate)
+ 		return inode->i_op->revalidate(dentry);
+ 	return 0;
+ }
+@@ -135,13 +139,15 @@
+ asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -151,13 +157,15 @@
+ asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -172,13 +180,15 @@
+ asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -189,13 +199,15 @@
+ asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -216,7 +228,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_old_stat(dentry->d_inode, statbuf);
+ 		fput(f);
+@@ -235,7 +247,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat(dentry->d_inode, statbuf);
+ 		fput(f);
+@@ -257,7 +269,7 @@
+ 
+ 		error = -EINVAL;
+ 		if (inode->i_op && inode->i_op->readlink &&
+-		    !(error = do_revalidate(nd.dentry))) {
++		    !(error = do_revalidate(nd.dentry, NULL))) {
+ 			UPDATE_ATIME(inode);
+ 			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
+ 		}
+@@ -333,12 +345,14 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -348,12 +362,14 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -368,7 +384,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat64(dentry->d_inode, statbuf);
+ 		fput(f);
+Index: linux-2.4.19-pre1/include/linux/dcache.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/dcache.h	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/dcache.h	2003-11-21 02:51:38.000000000 +0300
+@@ -5,6 +5,51 @@
+ 
+ #include <asm/atomic.h>
+ #include <linux/mount.h>
++#include <linux/string.h>
++
++#define IT_OPEN     0x0001
++#define IT_CREAT    0x0002
++#define IT_READDIR  0x0004
++#define IT_GETATTR  0x0008
++#define IT_LOOKUP   0x0010
++#define IT_UNLINK   0x0020
++#define IT_GETXATTR 0x0040
++#define IT_EXEC     0x0080
++#define IT_PIN      0x0100
++
++#define IT_FL_LOCKED   0x0001
++#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */
++
++#define INTENT_MAGIC 0x19620323
++
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
++	int it_int_flags;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
++};
++
++static inline void intent_init(struct lookup_intent *it, int op, int flags)
++{
++	memset(it, 0, sizeof(*it));
++	it->it_magic = INTENT_MAGIC;
++	it->it_op = op;
++	it->it_flags = flags;
++}
++
+ 
+ /*
+  * linux/include/linux/dcache.h
+@@ -90,8 +135,22 @@
+ 	int (*d_delete)(struct dentry *);
+ 	void (*d_release)(struct dentry *);
+ 	void (*d_iput)(struct dentry *, struct inode *);
++	int (*d_revalidate_it)(struct dentry *, int, struct lookup_intent *);
++	void (*d_pin)(struct dentry *, struct vfsmount * , int);
++	void (*d_unpin)(struct dentry *, struct vfsmount *, int);
+ };
+ 
++#define PIN(de,mnt,flag)  if (de->d_op && de->d_op->d_pin) \
++				de->d_op->d_pin(de, mnt, flag);
++#define UNPIN(de,mnt,flag)  if (de->d_op && de->d_op->d_unpin) \
++				de->d_op->d_unpin(de, mnt, flag);
++
++
++/* defined in fs/namei.c */
++extern void intent_release(struct lookup_intent *it);
++/* defined in fs/dcache.c */
++extern void __d_rehash(struct dentry * entry, int lock);
++
+ /* the dentry parameter passed to d_hash and d_compare is the parent
+  * directory of the entries to be compared. It is used in case these
+  * functions need any directory specific information for determining
+@@ -123,6 +182,7 @@
+ 					 * s_nfsd_free_path semaphore will be down
+ 					 */
+ #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
++#define DCACHE_LUSTRE_INVALID	0x0010  /* Lustre invalidated */
+ 
+ extern spinlock_t dcache_lock;
+ 
+Index: linux-2.4.19-pre1/include/linux/fs.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs.h	2003-11-21 02:51:37.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs.h	2003-11-21 02:51:38.000000000 +0300
+@@ -73,6 +73,7 @@
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -332,6 +333,9 @@
+ #define ATTR_MTIME_SET	256
+ #define ATTR_FORCE	512	/* Not a change, but a change it */
+ #define ATTR_ATTR_FLAG	1024
++#define ATTR_RAW	0x0800	/* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN	0x1000	/* called from open path, ie O_TRUNC */
++#define ATTR_CTIME_SET 0x2000
+ 
+ /*
+  * This is the Inode Attributes structure, used for notify_change().  It
+@@ -465,6 +469,7 @@
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -534,6 +539,7 @@
+ 
+ 	/* needed for tty driver, and maybe others */
+ 	void			*private_data;
++	struct lookup_intent    *f_it;
+ 
+ 	/* preallocated helper kiobuf to speedup O_DIRECT */
+ 	struct kiobuf		*f_iobuf;
+@@ -644,6 +650,7 @@
+ 	struct qstr last;
+ 	unsigned int flags;
+ 	int last_type;
++	struct lookup_intent *intent;
+ };
+ 
+ #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
+@@ -777,7 +784,8 @@
+ extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
+ extern int vfs_rmdir(struct inode *, struct dentry *);
+ extern int vfs_unlink(struct inode *, struct dentry *);
+-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
++int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++	       struct inode *new_dir, struct dentry *new_dentry);
+ 
+ /*
+  * File types
+@@ -837,21 +845,32 @@
+ 
+ struct inode_operations {
+ 	int (*create) (struct inode *,struct dentry *,int);
++	int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *);
++	struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags);
+ 	int (*link) (struct dentry *,struct inode *,struct dentry *);
++	int (*link_raw) (struct nameidata *,struct nameidata *);
+ 	int (*unlink) (struct inode *,struct dentry *);
++	int (*unlink_raw) (struct nameidata *);
+ 	int (*symlink) (struct inode *,struct dentry *,const char *);
++	int (*symlink_raw) (struct nameidata *,const char *);
+ 	int (*mkdir) (struct inode *,struct dentry *,int);
++	int (*mkdir_raw) (struct nameidata *,int);
+ 	int (*rmdir) (struct inode *,struct dentry *);
++	int (*rmdir_raw) (struct nameidata *);
+ 	int (*mknod) (struct inode *,struct dentry *,int,int);
++	int (*mknod_raw) (struct nameidata *,int,dev_t);
+ 	int (*rename) (struct inode *, struct dentry *,
+ 			struct inode *, struct dentry *);
++	int (*rename_raw) (struct nameidata *, struct nameidata *);
+ 	int (*readlink) (struct dentry *, char *,int);
+ 	int (*follow_link) (struct dentry *, struct nameidata *);
+ 	void (*truncate) (struct inode *);
+ 	int (*permission) (struct inode *, int);
+ 	int (*revalidate) (struct dentry *);
++	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
+ 	int (*setattr) (struct dentry *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
+ };
+ 
+@@ -1049,10 +1068,14 @@
+ 
+ asmlinkage long sys_open(const char *, int, int);
+ asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
+-extern int do_truncate(struct dentry *, loff_t start);
++extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
+ 
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
++extern int open_namei_it(const char *filename, int namei_flags, int mode,
++			 struct nameidata *nd, struct lookup_intent *it);
++extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
++			    int flags, struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1306,6 +1329,7 @@
+ extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
+ 
+ extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
++extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
+ extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
+ extern int FASTCALL(path_walk(const char *, struct nameidata *));
+ extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
+@@ -1316,6 +1340,8 @@
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
++#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
++#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
+ 
+ extern void iput(struct inode *);
+ extern void force_delete(struct inode *);
+@@ -1423,6 +1449,8 @@
+ 
+ extern int vfs_readlink(struct dentry *, char *, int, const char *);
+ extern int vfs_follow_link(struct nameidata *, const char *);
++extern int vfs_follow_link_it(struct nameidata *, const char *,
++			      struct lookup_intent *it);
+ extern int page_readlink(struct dentry *, char *, int);
+ extern int page_follow_link(struct dentry *, struct nameidata *);
+ extern struct inode_operations page_symlink_inode_operations;
+Index: linux-2.4.19-pre1/include/linux/fs_struct.h
+===================================================================
+--- linux-2.4.19-pre1.orig/include/linux/fs_struct.h	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/include/linux/fs_struct.h	2003-11-21 02:51:38.000000000 +0300
+@@ -34,10 +34,12 @@
+ 	write_lock(&fs->lock);
+ 	old_root = fs->root;
+ 	old_rootmnt = fs->rootmnt;
++	PIN(dentry, mnt, 1);
+ 	fs->rootmnt = mntget(mnt);
+ 	fs->root = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_root) {
++		UNPIN(old_root, old_rootmnt, 1);
+ 		dput(old_root);
+ 		mntput(old_rootmnt);
+ 	}
+@@ -57,10 +59,12 @@
+ 	write_lock(&fs->lock);
+ 	old_pwd = fs->pwd;
+ 	old_pwdmnt = fs->pwdmnt;
++	PIN(dentry, mnt, 0);
+ 	fs->pwdmnt = mntget(mnt);
+ 	fs->pwd = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_pwd) {
++		UNPIN(old_pwd, old_pwdmnt, 0);
+ 		dput(old_pwd);
+ 		mntput(old_pwdmnt);
+ 	}
+Index: linux-2.4.19-pre1/kernel/ksyms.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/ksyms.c	2003-11-21 02:51:37.000000000 +0300
++++ linux-2.4.19-pre1/kernel/ksyms.c	2003-11-21 02:51:38.000000000 +0300
+@@ -260,6 +260,7 @@
+ EXPORT_SYMBOL(set_page_dirty);
+ EXPORT_SYMBOL(vfs_readlink);
+ EXPORT_SYMBOL(vfs_follow_link);
++EXPORT_SYMBOL(vfs_follow_link_it);
+ EXPORT_SYMBOL(page_readlink);
+ EXPORT_SYMBOL(page_follow_link);
+ EXPORT_SYMBOL(page_symlink_inode_operations);
+Index: linux-2.4.19-pre1/kernel/fork.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/fork.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/kernel/fork.c	2003-11-21 02:51:38.000000000 +0300
+@@ -372,10 +372,13 @@
+ 		fs->umask = old->umask;
+ 		read_lock(&old->lock);
+ 		fs->rootmnt = mntget(old->rootmnt);
++		PIN(old->pwd, old->pwdmnt, 0);
++		PIN(old->root, old->rootmnt, 1);
+ 		fs->root = dget(old->root);
+ 		fs->pwdmnt = mntget(old->pwdmnt);
+ 		fs->pwd = dget(old->pwd);
+ 		if (old->altroot) {
++			PIN(old->altroot, old->altrootmnt, 1);
+ 			fs->altrootmnt = mntget(old->altrootmnt);
+ 			fs->altroot = dget(old->altroot);
+ 		} else {
+Index: linux-2.4.19-pre1/kernel/exit.c
+===================================================================
+--- linux-2.4.19-pre1.orig/kernel/exit.c	2003-11-21 02:41:00.000000000 +0300
++++ linux-2.4.19-pre1/kernel/exit.c	2003-11-21 02:51:38.000000000 +0300
+@@ -245,11 +245,14 @@
+ {
+ 	/* No need to hold fs->lock if we are killing it */
+ 	if (atomic_dec_and_test(&fs->count)) {
++		UNPIN(fs->pwd, fs->pwdmnt, 0);
++		UNPIN(fs->root, fs->rootmnt, 1);
+ 		dput(fs->root);
+ 		mntput(fs->rootmnt);
+ 		dput(fs->pwd);
+ 		mntput(fs->pwdmnt);
+ 		if (fs->altroot) {
++			UNPIN(fs->altroot, fs->altrootmnt, 1);
+ 			dput(fs->altroot);
+ 			mntput(fs->altrootmnt);
+ 		}
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4e37bb8b9c9c20b982ec41d4cf31214754799269
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch
@@ -0,0 +1,1835 @@
+ fs/dcache.c               |   19 ++
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  295 +++++++++++++++++++++++++++++++++++++++-------
+ fs/namespace.c            |   28 +++-
+ fs/open.c                 |  172 +++++++++++++++++++-------
+ fs/stat.c                 |   52 +++++---
+ include/linux/dcache.h    |   60 +++++++++
+ include/linux/fs.h        |   32 ++++
+ include/linux/fs_struct.h |    4 
+ kernel/exit.c             |    3 
+ kernel/fork.c             |    3 
+ kernel/ksyms.c            |    1 
+ 12 files changed, 558 insertions(+), 128 deletions(-)
+
+Index: linux-2.4.19.SuSE/fs/exec.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/exec.c	Mon Jan 27 05:08:35 2003
++++ linux-2.4.19.SuSE/fs/exec.c	Sat Nov 15 17:34:06 2003
+@@ -107,8 +107,10 @@
+ 	struct file * file;
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
+ 
+-	error = user_path_walk(library, &nd);
++	error = user_path_walk_it(library, &nd, &it);
+ 	if (error)
+ 		goto out;
+ 
+@@ -120,7 +122,8 @@
+ 	if (error)
+ 		goto exit;
+ 
+-	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++	file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++	intent_release(&it);
+ 	error = PTR_ERR(file);
+ 	if (IS_ERR(file))
+ 		goto out;
+@@ -346,9 +349,11 @@
+ 	struct inode *inode;
+ 	struct file *file;
+ 	int err = 0;
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
+ 
+ 	if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+-		err = path_walk(name, &nd);
++		err = path_walk_it(name, &nd, &it);
+ 	file = ERR_PTR(err);
+ 	if (!err) {
+ 		inode = nd.dentry->d_inode;
+@@ -360,7 +365,8 @@
+ 				err = -EACCES;
+ 			file = ERR_PTR(err);
+ 			if (!err) {
+-				file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++				file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++				intent_release(&it);
+ 				if (!IS_ERR(file)) {
+ 					err = deny_write_access(file);
+ 					if (err) {
+@@ -372,6 +378,7 @@
+ 				return file;
+ 			}
+ 		}
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	goto out;
+@@ -981,7 +988,7 @@
+ 		goto close_fail;
+ 	if (!file->f_op->write)
+ 		goto close_fail;
+-	if (do_truncate(file->f_dentry, 0) != 0)
++	if (do_truncate(file->f_dentry, 0, 0) != 0)
+ 		goto close_fail;
+ 
+ 	retval = binfmt->core_dump(signr, regs, file);
+Index: linux-2.4.19.SuSE/fs/dcache.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/dcache.c	Mon Jan 27 05:08:04 2003
++++ linux-2.4.19.SuSE/fs/dcache.c	Sat Nov 15 17:29:03 2003
+@@ -186,6 +186,13 @@
+ 		spin_unlock(&dcache_lock);
+ 		return 0;
+ 	}
++
++	/* network invalidation by Lustre */
++	if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
++		spin_unlock(&dcache_lock);
++		return 0;
++	}
++
+ 	/*
+ 	 * Check whether to do a partial shrink_dcache
+ 	 * to get rid of unused child entries.
+@@ -838,13 +845,19 @@
+  * Adds a dentry to the hash according to its name.
+  */
+  
+-void d_rehash(struct dentry * entry)
++void __d_rehash(struct dentry * entry, int lock)
+ {
+ 	struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+ 	if (!list_empty(&entry->d_hash)) BUG();
+-	spin_lock(&dcache_lock);
++	if (lock) spin_lock(&dcache_lock);
+ 	list_add(&entry->d_hash, list);
+-	spin_unlock(&dcache_lock);
++	if (lock) spin_unlock(&dcache_lock);
++}
++EXPORT_SYMBOL(__d_rehash);
++
++void d_rehash(struct dentry * entry)
++{
++	__d_rehash(entry, 1);
+ }
+ 
+ #define do_switch(x,y) do { \
+Index: linux-2.4.19.SuSE/fs/namespace.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/namespace.c	Mon Jan 27 05:08:07 2003
++++ linux-2.4.19.SuSE/fs/namespace.c	Sat Nov 15 17:56:42 2003
+@@ -97,6 +97,7 @@
+ {
+ 	old_nd->dentry = mnt->mnt_mountpoint;
+ 	old_nd->mnt = mnt->mnt_parent;
++	UNPIN(old_nd->dentry, old_nd->mnt, 1);
+ 	mnt->mnt_parent = mnt;
+ 	mnt->mnt_mountpoint = mnt->mnt_root;
+ 	list_del_init(&mnt->mnt_child);
+@@ -108,6 +109,7 @@
+ {
+ 	mnt->mnt_parent = mntget(nd->mnt);
+ 	mnt->mnt_mountpoint = dget(nd->dentry);
++	PIN(nd->dentry, nd->mnt, 1);
+ 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+ 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+ 	nd->dentry->d_mounted++;
+@@ -491,15 +493,18 @@
+ {
+ 	struct nameidata old_nd;
+ 	struct vfsmount *mnt = NULL;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int err = mount_is_safe(nd);
+ 	if (err)
+ 		return err;
+ 	if (!old_name || !*old_name)
+ 		return -EINVAL;
+ 	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+-		err = path_walk(old_name, &old_nd);
+-	if (err)
++		err = path_walk_it(old_name, &old_nd, &it);
++	if (err) {
++		intent_release(&it);
+ 		return err;
++	}
+ 
+ 	down_write(&current->namespace->sem);
+ 	err = -EINVAL;
+@@ -522,6 +527,7 @@
+ 	}
+ 
+ 	up_write(&current->namespace->sem);
++	intent_release(&it);
+ 	path_release(&old_nd);
+ 	return err;
+ }
+@@ -725,6 +731,7 @@
+ 		  unsigned long flags, void *data_page)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int retval = 0;
+ 	int mnt_flags = 0;
+ 
+@@ -750,9 +757,11 @@
+ 
+ 	/* ... and get the mountpoint */
+ 	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+-		retval = path_walk(dir_name, &nd);
+-	if (retval)
++		retval = path_walk_it(dir_name, &nd, &it);
++	if (retval) {
++		intent_release(&it);
+ 		return retval;
++	}
+ 
+ 	if (flags & MS_REMOUNT)
+ 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+@@ -764,6 +773,8 @@
+ 	else
+ 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+ 				      dev_name, data_page);
++
++	intent_release(&it);
+ 	path_release(&nd);
+ 	return retval;
+ }
+@@ -929,6 +940,8 @@
+ {
+ 	struct vfsmount *tmp;
+ 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
++	struct lookup_intent new_it = { .it_op = IT_GETATTR };
++	struct lookup_intent old_it = { .it_op = IT_GETATTR };
+ 	char *name;
+ 	int error;
+ 
+@@ -943,7 +956,7 @@
+ 		goto out0;
+ 	error = 0;
+ 	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
+-		error = path_walk(name, &new_nd);
++		error = path_walk_it(name, &new_nd, &new_it);
+ 	putname(name);
+ 	if (error)
+ 		goto out0;
+@@ -957,7 +970,7 @@
+ 		goto out1;
+ 	error = 0;
+ 	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
+-		error = path_walk(name, &old_nd);
++		error = path_walk_it(name, &old_nd, &old_it);
+ 	putname(name);
+ 	if (error)
+ 		goto out1;
+@@ -1013,8 +1026,10 @@
+ 	up(&old_nd.dentry->d_inode->i_zombie);
+ 	up_write(&current->namespace->sem);
+ 	path_release(&user_nd);
++	intent_release(&old_it);
+ 	path_release(&old_nd);
+ out1:
++	intent_release(&new_it);
+ 	path_release(&new_nd);
+ out0:
+ 	unlock_kernel();
+Index: linux-2.4.19.SuSE/fs/namei.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/namei.c	Mon Jan 27 05:08:07 2003
++++ linux-2.4.19.SuSE/fs/namei.c	Sat Nov 15 17:52:03 2003
+@@ -94,6 +94,13 @@
+  * XEmacs seems to be relying on it...
+  */
+ 
++void intent_release(struct lookup_intent *it)
++{
++	if (it && it->it_op_release)
++		it->it_op_release(it);
++
++}
++
+ /* In order to reduce some races, while at the same time doing additional
+  * checking and hopefully speeding things up, we copy filenames to the
+  * kernel data space before using them..
+@@ -260,10 +267,19 @@
+  * Internal lookup() using the new generic dcache.
+  * SMP-safe
+  */
+-static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
++static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
++				    int flags, struct lookup_intent *it)
+ {
+ 	struct dentry * dentry = d_lookup(parent, name);
+ 
++	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++		if (!dentry->d_op->d_revalidate_it(dentry, flags, it) &&
++		    !d_invalidate(dentry)) {
++			dput(dentry);
++			dentry = NULL;
++		}
++		return dentry;
++	} else
+ 	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
+ 		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
+ 			dput(dentry);
+@@ -281,11 +297,15 @@
+  * make sure that nobody added the entry to the dcache in the meantime..
+  * SMP-safe
+  */
+-static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
++static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
++				  int flags, struct lookup_intent *it)
+ {
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
++	int counter = 0;
+ 
++again:
++	counter++;
+ 	down(&dir->i_sem);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+@@ -300,6 +320,9 @@
+ 		result = ERR_PTR(-ENOMEM);
+ 		if (dentry) {
+ 			lock_kernel();
++			if (dir->i_op->lookup_it)
++				result = dir->i_op->lookup_it(dir, dentry, it, flags);
++			else
+ 			result = dir->i_op->lookup(dir, dentry);
+ 			unlock_kernel();
+ 			if (result)
+@@ -321,6 +344,15 @@
+ 			dput(result);
+ 			result = ERR_PTR(-ENOENT);
+ 		}
++	} else if (result->d_op && result->d_op->d_revalidate_it) {
++		if (!result->d_op->d_revalidate_it(result, flags, it) &&
++		    !d_invalidate(result)) {
++			dput(result);
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
++		}
+ 	}
+ 	return result;
+ }
+@@ -332,7 +364,8 @@
+  * Without that kind of total limit, nasty chains of consecutive
+  * symlinks can cause almost arbitrarily long lookups. 
+  */
+-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
++static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
++				 struct lookup_intent *it)
+ {
+ 	int err;
+ 	if (current->link_count >= 8)
+@@ -346,10 +379,12 @@
+ 	current->link_count++;
+ 	current->total_link_count++;
+ 	UPDATE_ATIME(dentry->d_inode);
++	nd->intent = it;
+ 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
+ 	current->link_count--;
+ 	return err;
+ loop:
++	intent_release(it);
+ 	path_release(nd);
+ 	return -ELOOP;
+ }
+@@ -447,7 +482,8 @@
+  *
+  * We expect 'base' to be positive and a directory.
+  */
+-int link_path_walk(const char * name, struct nameidata *nd)
++int link_path_walk_it(const char *name, struct nameidata *nd,
++		      struct lookup_intent *it)
+ {
+ 	struct dentry *dentry;
+ 	struct inode *inode;
+@@ -524,12 +560,13 @@
+ 				break;
+ 		}
+ 		/* This does the actual lookups.. */
+-		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
++		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE,NULL);
+ 		if (!dentry) {
+ 			err = -EWOULDBLOCKIO;
+ 			if (atomic)
+ 				break;
+-			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
++			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE,
++					     NULL);
+ 			err = PTR_ERR(dentry);
+ 			if (IS_ERR(dentry))
+ 				break;
+@@ -547,7 +584,7 @@
+ 			goto out_dput;
+ 
+ 		if (inode->i_op->follow_link) {
+-			err = do_follow_link(dentry, nd);
++			err = do_follow_link(dentry, nd, NULL);
+ 			dput(dentry);
+ 			if (err)
+ 				goto return_err;
+@@ -563,7 +600,7 @@
+ 			nd->dentry = dentry;
+ 		}
+ 		err = -ENOTDIR; 
+-		if (!inode->i_op->lookup)
++		if (!inode->i_op->lookup && !inode->i_op->lookup_it)
+ 			break;
+ 		continue;
+ 		/* here ends the main loop */
+@@ -590,12 +627,12 @@
+ 			if (err < 0)
+ 				break;
+ 		}
+-		dentry = cached_lookup(nd->dentry, &this, 0);
++		dentry = cached_lookup(nd->dentry, &this, 0, it);
+ 		if (!dentry) {
+ 			err = -EWOULDBLOCKIO;
+ 			if (atomic)
+ 				break;
+-			dentry = real_lookup(nd->dentry, &this, 0);
++			dentry = real_lookup(nd->dentry, &this, 0, it);
+ 			err = PTR_ERR(dentry);
+ 			if (IS_ERR(dentry))
+ 				break;
+@@ -605,7 +642,7 @@
+ 		inode = dentry->d_inode;
+ 		if ((lookup_flags & LOOKUP_FOLLOW)
+ 		    && inode && inode->i_op && inode->i_op->follow_link) {
+-			err = do_follow_link(dentry, nd);
++			err = do_follow_link(dentry, nd, it);
+ 			dput(dentry);
+ 			if (err)
+ 				goto return_err;
+@@ -619,7 +656,8 @@
+ 			goto no_inode;
+ 		if (lookup_flags & LOOKUP_DIRECTORY) {
+ 			err = -ENOTDIR; 
+-			if (!inode->i_op || !inode->i_op->lookup)
++			if (!inode->i_op ||
++			    (!inode->i_op->lookup && !inode->i_op->lookup_it))
+ 				break;
+ 		}
+ 		goto return_base;
+@@ -643,6 +681,25 @@
+ 		 * Check the cached dentry for staleness.
+ 		 */
+ 		dentry = nd->dentry;
++		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
++			err = -ESTALE;
++			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
++				struct dentry *new;
++				err = permission(dentry->d_parent->d_inode,
++						 MAY_EXEC);
++				if (err)
++					break;
++				new = real_lookup(dentry->d_parent,
++						  &dentry->d_name, 0, NULL);
++				d_invalidate(dentry);
++				dput(dentry);
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
++			}
++		} else
+ 		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
+ 			err = -ESTALE;
+ 			if (!dentry->d_op->d_revalidate(dentry, lookup_flags & LOOKUP_PARENT)) {
+@@ -656,15 +713,28 @@
+ 		dput(dentry);
+ 		break;
+ 	}
++	if (err)
++		intent_release(it);
+ 	path_release(nd);
+ return_err:
+ 	return err;
+ }
+ 
++int link_path_walk(const char * name, struct nameidata *nd)
++{
++	return link_path_walk_it(name, nd, NULL);
++}
++
++int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
++{
++	current->total_link_count = 0;
++	return link_path_walk_it(name, nd, it);
++}
++
+ int path_walk(const char * name, struct nameidata *nd)
+ {
+ 	current->total_link_count = 0;
+-	return link_path_walk(name, nd);
++	return link_path_walk_it(name, nd, NULL);
+ }
+ 
+ /* SMP-safe */
+@@ -753,6 +823,7 @@
+ {
+ 	nd->last_type = LAST_ROOT; /* if there are only slashes... */
+ 	nd->flags = flags;
++	nd->intent = NULL;
+ 	if (*name=='/')
+ 		return walk_init_root(name,nd);
+ 	read_lock(&current->fs->lock);
+@@ -767,7 +838,8 @@
+  * needs parent already locked. Doesn't follow mounts.
+  * SMP-safe.
+  */
+-struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
++struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
++			       struct lookup_intent *it)
+ {
+ 	struct dentry * dentry;
+ 	struct inode *inode;
+@@ -790,13 +862,16 @@
+ 			goto out;
+ 	}
+ 
+-	dentry = cached_lookup(base, name, 0);
++	dentry = cached_lookup(base, name, 0, it);
+ 	if (!dentry) {
+ 		struct dentry *new = d_alloc(base, name);
+ 		dentry = ERR_PTR(-ENOMEM);
+ 		if (!new)
+ 			goto out;
+ 		lock_kernel();
++		if (inode->i_op->lookup_it)
++			dentry = inode->i_op->lookup_it(inode, new, it, 0);
++		else
+ 		dentry = inode->i_op->lookup(inode, new);
+ 		unlock_kernel();
+ 		if (!dentry)
+@@ -808,6 +883,12 @@
+ 	return dentry;
+ }
+ 
++struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
++{
++	return lookup_hash_it(name, base, NULL);
++}
++
++
+ /* SMP-safe */
+ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
+ {
+@@ -829,7 +910,7 @@
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash(&this, base);
++	return lookup_hash_it(&this, base, NULL);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+@@ -861,6 +942,23 @@
+ 	return err;
+ }
+ 
++int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
++		   struct lookup_intent *it)
++{
++	char *tmp;
++	int err;
++
++	tmp = getname(name);
++	err = PTR_ERR(tmp);
++	if (!IS_ERR(tmp)) {
++		err = 0;
++		if (path_init(tmp, flags, nd))
++			err = path_walk_it(tmp, nd, it);
++		putname(tmp);
++	}
++	return err;
++}
++
+ /*
+  * It's inline, so penalty for filesystems that don't use sticky bit is
+  * minimal.
+@@ -958,7 +1056,8 @@
+ 	return retval;
+ }
+ 
+-int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
++static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode,
++			 struct lookup_intent *it)
+ {
+ 	int error;
+ 
+@@ -971,12 +1070,15 @@
+ 		goto exit_lock;
+ 
+ 	error = -EACCES;	/* shouldn't it be ENOSYS? */
+-	if (!dir->i_op || !dir->i_op->create)
++	if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it))
+ 		goto exit_lock;
+ 
+ 	DQUOT_INIT(dir);
+ 	lock_kernel();
+-	error = dir->i_op->create(dir, dentry, mode);
++	if (dir->i_op->create_it)
++		error = dir->i_op->create_it(dir, dentry, mode, it);
++	else
++		error = dir->i_op->create(dir, dentry, mode);
+ 	unlock_kernel();
+ exit_lock:
+ 	up(&dir->i_zombie);
+@@ -985,6 +1087,11 @@
+ 	return error;
+ }
+ 
++int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
++{
++	return vfs_create_it(dir, dentry, mode, NULL);
++}
++
+ /*
+  *	open_namei()
+  *
+@@ -999,7 +1106,8 @@
+  * for symlinks (where the permissions are checked later).
+  * SMP-safe
+  */
+-int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
++int open_namei_it(const char *pathname, int flag, int mode,
++		  struct nameidata *nd, struct lookup_intent *it)
+ {
+ 	int acc_mode, error = 0;
+ 	struct inode *inode;
+@@ -1009,12 +1117,14 @@
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
+ 	/*
+ 	 * The simplest case - just a plain lookup.
+ 	 */
+ 	if (!(flag & O_CREAT)) {
+ 		if (path_init(pathname, lookup_flags(flag), nd))
+-			error = path_walk(pathname, nd);
++			error = path_walk_it(pathname, nd, it);
+ 		if (error)
+ 			return error;
+ 		dentry = nd->dentry;
+@@ -1024,6 +1134,10 @@
+ 	/*
+ 	 * Create - we need to know the parent.
+ 	 */
++	if (it) {
++		it->it_create_mode = mode;
++		it->it_op |= IT_CREAT;
++	}
+ 	if (path_init(pathname, LOOKUP_PARENT, nd))
+ 		error = path_walk(pathname, nd);
+ 	if (error)
+@@ -1040,7 +1154,7 @@
+ 
+ 	dir = nd->dentry;
+ 	down(&dir->d_inode->i_sem);
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 
+ do_last:
+ 	error = PTR_ERR(dentry);
+@@ -1049,11 +1163,13 @@
+ 		goto exit;
+ 	}
+ 
++	it->it_create_mode = mode;
+ 	/* Negative dentry, just create the file */
+ 	if (!dentry->d_inode) {
+ 		if (!IS_POSIXACL(dir->d_inode))
+ 			mode &= ~current->fs->umask;
+-		error = vfs_create(dir->d_inode, dentry, mode);
++		error = vfs_create_it(dir->d_inode, dentry,
++				      mode & ~current->fs->umask, it);
+ 		up(&dir->d_inode->i_sem);
+ #ifndef DENTRY_WASTE_RAM
+ 		if (error)
+@@ -1161,7 +1277,7 @@
+ 		if (!error) {
+ 			DQUOT_INIT(inode);
+ 			
+-			error = do_truncate(dentry, 0);
++			error = do_truncate(dentry, 0, 1);
+ 		}
+ 		put_write_access(inode);
+ 		if (error)
+@@ -1173,8 +1289,10 @@
+ 	return 0;
+ 
+ exit_dput:
++	intent_release(it);
+ 	dput(dentry);
+ exit:
++	intent_release(it);
+ 	path_release(nd);
+ 	return error;
+ 
+@@ -1193,7 +1311,10 @@
+ 	 * are done. Procfs-like symlinks just set LAST_BIND.
+ 	 */
+ 	UPDATE_ATIME(dentry->d_inode);
++	nd->intent = it;
+ 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
++	if (error)
++		intent_release(it);
+ 	dput(dentry);
+ 	if (error)
+ 		return error;
+@@ -1215,13 +1336,20 @@
+ 	}
+ 	dir = nd->dentry;
+ 	down(&dir->d_inode->i_sem);
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 	putname(nd->last.name);
+ 	goto do_last;
+ }
+ 
++int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
++{
++	return open_namei_it(pathname, flag, mode, nd, NULL);
++}
++
++
+ /* SMP-safe */
+-static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
++static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
++				    struct lookup_intent *it)
+ {
+ 	struct dentry *dentry;
+ 
+@@ -1229,7 +1357,7 @@
+ 	dentry = ERR_PTR(-EEXIST);
+ 	if (nd->last_type != LAST_NORM)
+ 		goto fail;
+-	dentry = lookup_hash(&nd->last, nd->dentry);
++	dentry = lookup_hash_it(&nd->last, nd->dentry, it);
+ 	if (IS_ERR(dentry))
+ 		goto fail;
+ 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
+@@ -1286,7 +1414,16 @@
+ 		error = path_walk(tmp, &nd);
+ 	if (error)
+ 		goto out;
+-	dentry = lookup_create(&nd, 0);
++
++	if (nd.dentry->d_inode->i_op->mknod_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->mknod_raw(&nd, mode, dev);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto out2;
++	}
++
++	dentry = lookup_create(&nd, 0, NULL);
+ 	error = PTR_ERR(dentry);
+ 
+ 	if (!IS_POSIXACL(nd.dentry->d_inode))
+@@ -1308,6 +1445,7 @@
+ 		dput(dentry);
+ 	}
+ 	up(&nd.dentry->d_inode->i_sem);
++out2:
+ 	path_release(&nd);
+ out:
+ 	putname(tmp);
+@@ -1356,7 +1494,14 @@
+ 			error = path_walk(tmp, &nd);
+ 		if (error)
+ 			goto out;
+-		dentry = lookup_create(&nd, 1);
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
++		dentry = lookup_create(&nd, 1, NULL);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+ 			if (!IS_POSIXACL(nd.dentry->d_inode))
+@@ -1365,6 +1510,7 @@
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++out2:
+ 		path_release(&nd);
+ out:
+ 		putname(tmp);
+@@ -1466,8 +1612,16 @@
+ 			error = -EBUSY;
+ 			goto exit1;
+ 	}
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
+ 	down(&nd.dentry->d_inode->i_sem);
+-	dentry = lookup_hash(&nd.last, nd.dentry);
++	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
+@@ -1526,8 +1680,15 @@
+ 	error = -EISDIR;
+ 	if (nd.last_type != LAST_NORM)
+ 		goto exit1;
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
+ 	down(&nd.dentry->d_inode->i_sem);
+-	dentry = lookup_hash(&nd.last, nd.dentry);
++	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
+ 	error = PTR_ERR(dentry);
+ 	if (!IS_ERR(dentry)) {
+ 		/* Why not before? Because we want correct error value */
+@@ -1595,15 +1756,23 @@
+ 			error = path_walk(to, &nd);
+ 		if (error)
+ 			goto out;
+-		dentry = lookup_create(&nd, 0);
++		if (nd.dentry->d_inode->i_op->symlink_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->symlink_raw(&nd, from);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
++		dentry = lookup_create(&nd, 0, NULL);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+ 			error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++	out2:
+ 		path_release(&nd);
+-out:
++	out:
+ 		putname(to);
+ 	}
+ 	putname(from);
+@@ -1686,7 +1855,14 @@
+ 		error = -EXDEV;
+ 		if (old_nd.mnt != nd.mnt)
+ 			goto out_release;
+-		new_dentry = lookup_create(&nd, 0);
++		if (nd.dentry->d_inode->i_op->link_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->link_raw(&old_nd, &nd);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out_release;
++		}
++		new_dentry = lookup_create(&nd, 0, NULL);
+ 		error = PTR_ERR(new_dentry);
+ 		if (!IS_ERR(new_dentry)) {
+ 			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+@@ -1732,7 +1908,7 @@
+  *	   locking].
+  */
+ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++		   struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	int error;
+ 	struct inode *target;
+@@ -1811,7 +1987,7 @@
+ }
+ 
+ int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++		     struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	int error;
+ 
+@@ -1902,9 +2078,18 @@
+ 	if (newnd.last_type != LAST_NORM)
+ 		goto exit2;
+ 
++	if (old_dir->d_inode->i_op->rename_raw) {
++		lock_kernel();
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		unlock_kernel();
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
++
+ 	double_lock(new_dir, old_dir);
+ 
+-	old_dentry = lookup_hash(&oldnd.last, old_dir);
++	old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
+ 	error = PTR_ERR(old_dentry);
+ 	if (IS_ERR(old_dentry))
+ 		goto exit3;
+@@ -1920,16 +2105,16 @@
+ 		if (newnd.last.name[newnd.last.len])
+ 			goto exit4;
+ 	}
+-	new_dentry = lookup_hash(&newnd.last, new_dir);
++	new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
+ 	error = PTR_ERR(new_dentry);
+ 	if (IS_ERR(new_dentry))
+ 		goto exit4;
+ 
++
+ 	lock_kernel();
+ 	error = vfs_rename(old_dir->d_inode, old_dentry,
+ 				   new_dir->d_inode, new_dentry);
+ 	unlock_kernel();
+-
+ 	dput(new_dentry);
+ exit4:
+ 	dput(old_dentry);
+@@ -1980,20 +2165,26 @@
+ }
+ 
+ static inline int
+-__vfs_follow_link(struct nameidata *nd, const char *link)
++__vfs_follow_link(struct nameidata *nd, const char *link,
++		  struct lookup_intent *it)
+ {
+ 	int res = 0;
+ 	char *name;
+ 	if (IS_ERR(link))
+ 		goto fail;
+ 
++	if (it == NULL)
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
++
+ 	if (*link == '/') {
+ 		path_release(nd);
+ 		if (!walk_init_root(link, nd))
+ 			/* weird __emul_prefix() stuff did it */
+ 			goto out;
+ 	}
+-	res = link_path_walk(link, nd);
++	res = link_path_walk_it(link, nd, it);
+ out:
+ 	if (current->link_count || res || nd->last_type!=LAST_NORM)
+ 		return res;
+@@ -2015,7 +2206,13 @@
+ 
+ int vfs_follow_link(struct nameidata *nd, const char *link)
+ {
+-	return __vfs_follow_link(nd, link);
++	return __vfs_follow_link(nd, link, NULL);
++}
++
++int vfs_follow_link_it(struct nameidata *nd, const char *link,
++		       struct lookup_intent *it)
++{
++	return __vfs_follow_link(nd, link, it);
+ }
+ 
+ /* get the link contents into pagecache */
+@@ -2057,7 +2254,7 @@
+ {
+ 	struct page *page = NULL;
+ 	char *s = page_getlink(dentry, &page);
+-	int res = __vfs_follow_link(nd, s);
++	int res = __vfs_follow_link(nd, s, NULL);
+ 	if (page) {
+ 		kunmap(page);
+ 		page_cache_release(page);
+Index: linux-2.4.19.SuSE/fs/open.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/open.c	Mon Jan 27 05:08:00 2003
++++ linux-2.4.19.SuSE/fs/open.c	Sat Nov 15 17:43:27 2003
+@@ -19,6 +19,8 @@
+ #include <asm/uaccess.h>
+ 
+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
++extern int path_walk_it(const char *name, struct nameidata *nd,
++			struct lookup_intent *it);
+ 
+ int vfs_statfs(struct super_block *sb, struct statfs *buf)
+ {
+@@ -95,9 +97,10 @@
+ 	write_unlock(&files->file_lock);
+ }
+ 
+-int do_truncate(struct dentry *dentry, loff_t length)
++int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
+ {
+ 	struct inode *inode = dentry->d_inode;
++	struct inode_operations *op = dentry->d_inode->i_op;
+ 	int error;
+ 	struct iattr newattrs;
+ 
+@@ -108,7 +111,13 @@
+ 	down(&inode->i_sem);
+ 	newattrs.ia_size = length;
+ 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+-	error = notify_change(dentry, &newattrs);
++	if (called_from_open)
++		newattrs.ia_valid |= ATTR_FROM_OPEN;
++	if (op->setattr_raw) {
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++	} else
++		error = notify_change(dentry, &newattrs);
+ 	up(&inode->i_sem);
+ 	return error;
+ }
+@@ -118,12 +127,13 @@
+ 	struct nameidata nd;
+ 	struct inode * inode;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	error = -EINVAL;
+ 	if (length < 0)	/* sorry, but loff_t says... */
+ 		goto out;
+ 
+-	error = user_path_walk(path, &nd);
++	error = user_path_walk_it(path, &nd, &it);
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+@@ -163,11 +173,13 @@
+ 	error = locks_verify_truncate(inode, NULL, length);
+ 	if (!error) {
+ 		DQUOT_INIT(inode);
+-		error = do_truncate(nd.dentry, length);
++		intent_release(&it);
++		error = do_truncate(nd.dentry, length, 0);
+ 	}
+ 	put_write_access(inode);
+ 
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -215,7 +227,7 @@
+ 
+ 	error = locks_verify_truncate(inode, file, length);
+ 	if (!error)
+-		error = do_truncate(dentry, length);
++		error = do_truncate(dentry, length, 0);
+ out_putf:
+ 	fput(file);
+ out:
+@@ -260,11 +272,13 @@
+ 	struct inode * inode;
+ 	struct iattr newattrs;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, NULL);
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+ 
++	/* this is safe without a Lustre lock because it only depends
++	   on the super block */
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+@@ -279,11 +293,25 @@
+ 			goto dput_and_out;
+ 
+ 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-	} else {
++	}
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	}
++
++	error = -EPERM;
++	if (!times) {
+ 		if (current->fsuid != inode->i_uid &&
+ 		    (error = permission(inode,MAY_WRITE)) != 0)
+ 			goto dput_and_out;
+ 	}
++
+ 	error = notify_change(nd.dentry, &newattrs);
+ dput_and_out:
+ 	path_release(&nd);
+@@ -304,12 +332,14 @@
+ 	struct inode * inode;
+ 	struct iattr newattrs;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, NULL);
+ 
+ 	if (error)
+ 		goto out;
+ 	inode = nd.dentry->d_inode;
+ 
++	/* this is safe without a Lustre lock because it only depends
++	   on the super block */
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+@@ -324,7 +354,20 @@
+ 		newattrs.ia_atime = times[0].tv_sec;
+ 		newattrs.ia_mtime = times[1].tv_sec;
+ 		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-	} else {
++	}
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	}
++
++	error = -EPERM;
++	if (!utimes) {
+ 		if (current->fsuid != inode->i_uid &&
+ 		    (error = permission(inode,MAY_WRITE)) != 0)
+ 			goto dput_and_out;
+@@ -347,6 +390,7 @@
+ 	int old_fsuid, old_fsgid;
+ 	kernel_cap_t old_cap;
+ 	int res;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
+ 		return -EINVAL;
+@@ -364,13 +408,14 @@
+ 	else
+ 		current->cap_effective = current->cap_permitted;
+ 
+-	res = user_path_walk(filename, &nd);
++	res = user_path_walk_it(filename, &nd, &it);
+ 	if (!res) {
+ 		res = permission(nd.dentry->d_inode, mode);
+ 		/* SuS v2 requires we report a read only fs too */
+ 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+ 		   && !special_file(nd.dentry->d_inode->i_mode))
+ 			res = -EROFS;
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 
+@@ -386,6 +431,7 @@
+ 	int error;
+ 	struct nameidata nd;
+ 	char *name;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	name = getname(filename);
+ 	error = PTR_ERR(name);
+@@ -394,7 +440,7 @@
+ 
+ 	error = 0;
+ 	if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
+-		error = path_walk(name, &nd);
++		error = path_walk_it(name, &nd, &it);
+ 	putname(name);
+ 	if (error)
+ 		goto out;
+@@ -406,6 +452,7 @@
+ 	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+ 
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -446,6 +493,7 @@
+ 	int error;
+ 	struct nameidata nd;
+ 	char *name;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+ 	name = getname(filename);
+ 	error = PTR_ERR(name);
+@@ -454,7 +502,7 @@
+ 
+ 	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
+ 		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
+-	error = path_walk(name, &nd);	
++	error = path_walk_it(name, &nd, &it);
+ 	putname(name);
+ 	if (error)
+ 		goto out;
+@@ -471,39 +519,56 @@
+ 	set_fs_altroot();
+ 	error = 0;
+ dput_and_out:
++	intent_release(&it);
+ 	path_release(&nd);
+ out:
+ 	return error;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
+ 
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
++	if (inode->i_op->setattr_raw) {
++		newattrs.ia_mode = mode;
++		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
++		newattrs.ia_valid |= ATTR_RAW;
++		err = inode->i_op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (err != -EOPNOTSUPP)
++			goto out;
++	}
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -512,30 +577,14 @@
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
++	error = chmod_common(nd.dentry, mode);
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
+-
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -555,6 +604,20 @@
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto out;
++
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = dentry->d_inode->i_op;
++
++		newattrs.ia_uid = user;
++		newattrs.ia_gid = group;
++		newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			return error;
++	}
++
+ 	error = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ 		goto out;
+@@ -659,6 +722,7 @@
+ {
+ 	int namei_flags, error;
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_OPEN };
+ 
+ 	namei_flags = flags;
+ 	if ((namei_flags+1) & O_ACCMODE)
+@@ -666,14 +730,15 @@
+ 	if (namei_flags & O_TRUNC)
+ 		namei_flags |= 2;
+ 
+-	error = open_namei(filename, namei_flags, mode, &nd);
+-	if (!error)
+-		return dentry_open(nd.dentry, nd.mnt, flags);
++	error = open_namei_it(filename, namei_flags, mode, &nd, &it);
++	if (error)
++		return ERR_PTR(error);
+ 
+-	return ERR_PTR(error);
++	return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
+ }
+ 
+-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
++			    int flags, struct lookup_intent *it)
+ {
+ 	struct file * f;
+ 	struct inode *inode;
+@@ -710,7 +775,9 @@
+ 	}
+ 
+ 	if (f->f_op && f->f_op->open) {
++		f->f_it = it;
+ 		error = f->f_op->open(inode,f);
++		f->f_it = NULL;
+ 		if (error)
+ 			goto cleanup_all;
+ 	}
+@@ -722,6 +789,7 @@
+ 				      !inode->i_mapping->a_ops->direct_IO))
+ 		goto cleanup_all;
+ 
++	intent_release(it);
+ 	return f;
+ 
+ cleanup_all:
+@@ -736,11 +804,17 @@
+ cleanup_file:
+ 	put_filp(f);
+ cleanup_dentry:
++	intent_release(it);
+ 	dput(dentry);
+ 	mntput(mnt);
+ 	return ERR_PTR(error);
+ }
+ 
++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++{
++	return dentry_open_it(dentry, mnt, flags, NULL);
++}
++
+ /*
+  * Find an empty file descriptor entry, and mark it busy.
+  */
+Index: linux-2.4.19.SuSE/fs/stat.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/fs/stat.c	Mon Jan 27 05:08:00 2003
++++ linux-2.4.19.SuSE/fs/stat.c	Sat Nov 15 17:29:03 2003
+@@ -17,10 +17,14 @@
+  * Revalidate the inode. This is required for proper NFS attribute caching.
+  */
+ static __inline__ int
+-do_revalidate(struct dentry *dentry)
++do_revalidate(struct dentry *dentry, struct lookup_intent *it)
+ {
+ 	struct inode * inode = dentry->d_inode;
+-	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
++	if (inode->i_op && inode->i_op->revalidate_it)
++		return inode->i_op->revalidate_it(dentry, it);
++	else if (inode->i_op && inode->i_op->revalidate)
+ 		return inode->i_op->revalidate(dentry);
+ 	return 0;
+ }
+@@ -141,13 +145,15 @@
+ asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -157,13 +163,15 @@
+ asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -178,13 +186,15 @@
+ asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -195,13 +205,15 @@
+ asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -222,7 +234,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_old_stat(dentry->d_inode, statbuf);
+ 		fput(f);
+@@ -241,7 +253,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat(dentry->d_inode, statbuf);
+ 		fput(f);
+@@ -263,7 +275,7 @@
+ 
+ 		error = -EINVAL;
+ 		if (inode->i_op && inode->i_op->readlink &&
+-		    !(error = do_revalidate(nd.dentry))) {
++		    !(error = do_revalidate(nd.dentry, NULL))) {
+ 			UPDATE_ATIME(inode);
+ 			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
+ 		}
+@@ -339,12 +351,14 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -354,12 +368,14 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -374,7 +390,7 @@
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat64(dentry->d_inode, statbuf);
+ 		fput(f);
+Index: linux-2.4.19.SuSE/include/linux/dcache.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/dcache.h	Mon Jan 27 05:13:15 2003
++++ linux-2.4.19.SuSE/include/linux/dcache.h	Sat Nov 15 17:35:46 2003
+@@ -5,6 +5,51 @@
+ 
+ #include <asm/atomic.h>
+ #include <linux/mount.h>
++#include <linux/string.h>
++
++#define IT_OPEN     0x0001
++#define IT_CREAT    0x0002
++#define IT_READDIR  0x0004
++#define IT_GETATTR  0x0008
++#define IT_LOOKUP   0x0010
++#define IT_UNLINK   0x0020
++#define IT_GETXATTR 0x0040
++#define IT_EXEC     0x0080
++#define IT_PIN      0x0100
++
++#define IT_FL_LOCKED   0x0001
++#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */
++
++#define INTENT_MAGIC 0x19620323
++
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
++	int it_int_flags;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
++};
++
++static inline void intent_init(struct lookup_intent *it, int op, int flags)
++{
++	memset(it, 0, sizeof(*it));
++	it->it_magic = INTENT_MAGIC;
++	it->it_op = op;
++	it->it_flags = flags;
++}
++
+ 
+ /*
+  * linux/include/linux/dcache.h
+@@ -92,8 +137,22 @@
+ 	int (*d_delete)(struct dentry *);
+ 	void (*d_release)(struct dentry *);
+ 	void (*d_iput)(struct dentry *, struct inode *);
++	int (*d_revalidate_it)(struct dentry *, int, struct lookup_intent *);
++	void (*d_pin)(struct dentry *, struct vfsmount * , int);
++	void (*d_unpin)(struct dentry *, struct vfsmount *, int);
+ };
+ 
++#define PIN(de,mnt,flag)  if (de->d_op && de->d_op->d_pin) \
++				de->d_op->d_pin(de, mnt, flag);
++#define UNPIN(de,mnt,flag)  if (de->d_op && de->d_op->d_unpin) \
++				de->d_op->d_unpin(de, mnt, flag);
++
++
++/* defined in fs/namei.c */
++extern void intent_release(struct lookup_intent *it);
++/* defined in fs/dcache.c */
++extern void __d_rehash(struct dentry * entry, int lock);
++
+ /* the dentry parameter passed to d_hash and d_compare is the parent
+  * directory of the entries to be compared. It is used in case these
+  * functions need any directory specific information for determining
+@@ -125,6 +184,7 @@
+ 					 * s_nfsd_free_path semaphore will be down
+ 					 */
+ #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
++#define DCACHE_LUSTRE_INVALID	0x0010  /* Lustre invalidated */
+ 
+ extern spinlock_t dcache_lock;
+ 
+Index: linux-2.4.19.SuSE/include/linux/fs.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/fs.h	Sat Nov 15 17:25:06 2003
++++ linux-2.4.19.SuSE/include/linux/fs.h	Sat Nov 15 17:29:03 2003
+@@ -73,6 +73,7 @@
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -363,6 +364,9 @@
+ #define ATTR_MTIME_SET	256
+ #define ATTR_FORCE	512	/* Not a change, but a change it */
+ #define ATTR_ATTR_FLAG	1024
++#define ATTR_RAW	0x0800	/* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN	0x1000	/* called from open path, ie O_TRUNC */
++#define ATTR_CTIME_SET 0x2000
+ 
+ /*
+  * This is the Inode Attributes structure, used for notify_change().  It
+@@ -507,6 +511,7 @@
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -669,6 +674,7 @@
+ 
+ 	/* needed for tty driver, and maybe others */
+ 	void			*private_data;
++	struct lookup_intent    *f_it;
+ 
+ 	/* preallocated helper kiobuf to speedup O_DIRECT */
+ 	struct kiobuf		*f_iobuf;
+@@ -799,6 +805,7 @@
+ 	struct qstr last;
+ 	unsigned int flags;
+ 	int last_type;
++	struct lookup_intent *intent;
+ };
+ 
+ #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
+@@ -947,7 +954,8 @@
+ extern int __vfs_rmdir(struct inode *, struct dentry *);
+ extern int vfs_rmdir(struct inode *, struct dentry *);
+ extern int vfs_unlink(struct inode *, struct dentry *);
+-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
++int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++	       struct inode *new_dir, struct dentry *new_dentry);
+ 
+ /*
+  * File types
+@@ -1020,21 +1028,32 @@
+ 
+ struct inode_operations {
+ 	int (*create) (struct inode *,struct dentry *,int);
++	int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *);
++	struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct lookup_intent *, int flags);
+ 	int (*link) (struct dentry *,struct inode *,struct dentry *);
++	int (*link_raw) (struct nameidata *,struct nameidata *);
+ 	int (*unlink) (struct inode *,struct dentry *);
++	int (*unlink_raw) (struct nameidata *);
+ 	int (*symlink) (struct inode *,struct dentry *,const char *);
++	int (*symlink_raw) (struct nameidata *,const char *);
+ 	int (*mkdir) (struct inode *,struct dentry *,int);
++	int (*mkdir_raw) (struct nameidata *,int);
+ 	int (*rmdir) (struct inode *,struct dentry *);
++	int (*rmdir_raw) (struct nameidata *);
+ 	int (*mknod) (struct inode *,struct dentry *,int,int);
++	int (*mknod_raw) (struct nameidata *,int,dev_t);
+ 	int (*rename) (struct inode *, struct dentry *,
+ 			struct inode *, struct dentry *);
++	int (*rename_raw) (struct nameidata *, struct nameidata *);
+ 	int (*readlink) (struct dentry *, char *,int);
+ 	int (*follow_link) (struct dentry *, struct nameidata *);
+ 	void (*truncate) (struct inode *);
+ 	int (*permission) (struct inode *, int);
+ 	int (*revalidate) (struct dentry *);
++	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
+ 	int (*setattr) (struct dentry *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
+ 	int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
+ 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+@@ -1244,10 +1263,14 @@
+ 
+ asmlinkage long sys_open(const char *, int, int);
+ asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
+-extern int do_truncate(struct dentry *, loff_t start);
++extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
+ 
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
++extern int open_namei_it(const char *filename, int namei_flags, int mode,
++			 struct nameidata *nd, struct lookup_intent *it);
++extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
++			    int flags, struct lookup_intent *it);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char *);
+ 
+@@ -1515,6 +1538,7 @@
+ extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
+ 
+ extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
++extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
+ extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
+ extern int FASTCALL(path_walk(const char *, struct nameidata *));
+ extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
+@@ -1526,6 +1550,8 @@
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+ #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
++#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
++#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
+ 
+ extern void iput(struct inode *);
+ extern void force_delete(struct inode *);
+@@ -1646,6 +1672,8 @@
+ 
+ extern int vfs_readlink(struct dentry *, char *, int, const char *);
+ extern int vfs_follow_link(struct nameidata *, const char *);
++extern int vfs_follow_link_it(struct nameidata *, const char *,
++			      struct lookup_intent *it);
+ extern int page_readlink(struct dentry *, char *, int);
+ extern int page_follow_link(struct dentry *, struct nameidata *);
+ extern struct inode_operations page_symlink_inode_operations;
+Index: linux-2.4.19.SuSE/include/linux/fs_struct.h
+===================================================================
+--- linux-2.4.19.SuSE.orig/include/linux/fs_struct.h	Fri Jul 13 15:10:44 2001
++++ linux-2.4.19.SuSE/include/linux/fs_struct.h	Sat Nov 15 17:29:03 2003
+@@ -34,10 +34,12 @@
+ 	write_lock(&fs->lock);
+ 	old_root = fs->root;
+ 	old_rootmnt = fs->rootmnt;
++	PIN(dentry, mnt, 1);
+ 	fs->rootmnt = mntget(mnt);
+ 	fs->root = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_root) {
++		UNPIN(old_root, old_rootmnt, 1);
+ 		dput(old_root);
+ 		mntput(old_rootmnt);
+ 	}
+@@ -57,10 +59,12 @@
+ 	write_lock(&fs->lock);
+ 	old_pwd = fs->pwd;
+ 	old_pwdmnt = fs->pwdmnt;
++	PIN(dentry, mnt, 0);
+ 	fs->pwdmnt = mntget(mnt);
+ 	fs->pwd = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_pwd) {
++		UNPIN(old_pwd, old_pwdmnt, 0);
+ 		dput(old_pwd);
+ 		mntput(old_pwdmnt);
+ 	}
+Index: linux-2.4.19.SuSE/kernel/ksyms.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/kernel/ksyms.c	Sat Nov 15 17:24:46 2003
++++ linux-2.4.19.SuSE/kernel/ksyms.c	Sat Nov 15 17:29:03 2003
+@@ -315,6 +315,7 @@
+ EXPORT_SYMBOL(set_page_dirty);
+ EXPORT_SYMBOL(vfs_readlink);
+ EXPORT_SYMBOL(vfs_follow_link);
++EXPORT_SYMBOL(vfs_follow_link_it);
+ EXPORT_SYMBOL(page_readlink);
+ EXPORT_SYMBOL(page_follow_link);
+ EXPORT_SYMBOL(page_symlink_inode_operations);
+Index: linux-2.4.19.SuSE/kernel/fork.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/kernel/fork.c	Mon Jan 27 05:08:56 2003
++++ linux-2.4.19.SuSE/kernel/fork.c	Sat Nov 15 17:29:03 2003
+@@ -454,10 +454,13 @@
+ 		fs->umask = old->umask;
+ 		read_lock(&old->lock);
+ 		fs->rootmnt = mntget(old->rootmnt);
++		PIN(old->pwd, old->pwdmnt, 0);
++		PIN(old->root, old->rootmnt, 1);
+ 		fs->root = dget(old->root);
+ 		fs->pwdmnt = mntget(old->pwdmnt);
+ 		fs->pwd = dget(old->pwd);
+ 		if (old->altroot) {
++			PIN(old->altroot, old->altrootmnt, 1);
+ 			fs->altrootmnt = mntget(old->altrootmnt);
+ 			fs->altroot = dget(old->altroot);
+ 		} else {
+Index: linux-2.4.19.SuSE/kernel/exit.c
+===================================================================
+--- linux-2.4.19.SuSE.orig/kernel/exit.c	Mon Jan 27 05:08:16 2003
++++ linux-2.4.19.SuSE/kernel/exit.c	Sat Nov 15 17:29:03 2003
+@@ -288,11 +288,14 @@
+ {
+ 	/* No need to hold fs->lock if we are killing it */
+ 	if (atomic_dec_and_test(&fs->count)) {
++		UNPIN(fs->pwd, fs->pwdmnt, 0);
++		UNPIN(fs->root, fs->rootmnt, 1);
+ 		dput(fs->root);
+ 		mntput(fs->rootmnt);
+ 		dput(fs->pwd);
+ 		mntput(fs->pwdmnt);
+ 		if (fs->altroot) {
++			UNPIN(fs->altroot, fs->altrootmnt, 1);
+ 			dput(fs->altroot);
+ 			mntput(fs->altrootmnt);
+ 		}
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch
index 55046eab32db7ef0836470cff2222c9f9ec9f0ef..8cd36571718afda52c48d6f2712889d8b80ce905 100644
--- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch
@@ -1,32 +1,33 @@
  fs/dcache.c               |   19 ++
- fs/exec.c                 |   15 +-
- fs/namei.c                |  321 ++++++++++++++++++++++++++++++++++++++--------
- fs/namespace.c            |   28 +++-
- fs/open.c                 |  123 +++++++++++++++--
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  330 +++++++++++++++++++++++++++++++++++++++-------
+ fs/namespace.c            |   28 ++-
+ fs/open.c                 |  172 +++++++++++++++++------
  fs/proc/base.c            |    3 
- fs/stat.c                 |   50 ++++---
- include/linux/dcache.h    |   54 +++++++
- include/linux/fs.h        |   30 ++++
+ fs/stat.c                 |   52 ++++---
+ include/linux/dcache.h    |   60 ++++++++
+ include/linux/fs.h        |   32 ++++
  include/linux/fs_struct.h |    4 
  kernel/exit.c             |    3 
  kernel/fork.c             |    3 
  kernel/ksyms.c            |    1 
- 13 files changed, 552 insertions(+), 102 deletions(-)
+ 13 files changed, 591 insertions(+), 133 deletions(-)
 
---- linux/fs/exec.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:04:49 2003
-+++ linux-mmonroe/fs/exec.c	Sat Jul 12 14:05:24 2003
-@@ -116,8 +116,9 @@ asmlinkage long sys_uselib(const char * 
+--- linux-2.4.20-hp4-pnnl13/fs/exec.c~vfs_intent-2.4.20-hp	2003-09-13 15:19:27.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/exec.c	2003-09-14 17:33:51.000000000 +0400
+@@ -116,8 +116,10 @@ asmlinkage long sys_uselib(const char * 
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	error = user_path_walk(library, &nd);
 +	error = user_path_walk_it(library, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -129,7 +130,8 @@ asmlinkage long sys_uselib(const char * 
+@@ -129,7 +131,8 @@ asmlinkage long sys_uselib(const char * 
  	if (error)
  		goto exit;
  
@@ -36,18 +37,19 @@
  	error = PTR_ERR(file);
  	if (IS_ERR(file))
  		goto out;
-@@ -372,8 +374,9 @@ struct file *open_exec(const char *name)
+@@ -372,8 +375,10 @@ struct file *open_exec(const char *name)
  	struct inode *inode;
  	struct file *file;
  	int err = 0;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 +	err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
  	file = ERR_PTR(err);
  	if (!err) {
  		inode = nd.dentry->d_inode;
-@@ -385,7 +388,8 @@ struct file *open_exec(const char *name)
+@@ -385,7 +390,8 @@ struct file *open_exec(const char *name)
  				err = -EACCES;
  			file = ERR_PTR(err);
  			if (!err) {
@@ -57,7 +59,7 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
-@@ -397,6 +401,7 @@ out:
+@@ -397,6 +403,7 @@ out:
  				return file;
  			}
  		}
@@ -65,7 +67,7 @@
  		path_release(&nd);
  	}
  	goto out;
-@@ -1128,7 +1133,7 @@ int do_coredump(long signr, struct pt_re
+@@ -1128,7 +1135,7 @@ int do_coredump(long signr, struct pt_re
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
@@ -74,8 +76,8 @@
  		goto close_fail;
  
  	retval = binfmt->core_dump(signr, regs, file);
---- linux/fs/dcache.c~vfs_intent-2.4.20-hp	Thu Nov 28 15:53:15 2002
-+++ linux-mmonroe/fs/dcache.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/fs/dcache.c~vfs_intent-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/dcache.c	2003-09-14 17:33:51.000000000 +0400
 @@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
  		spin_unlock(&dcache_lock);
  		return 0;
@@ -113,8 +115,8 @@
  }
  
  #define do_switch(x,y) do { \
---- linux/fs/namespace.c~vfs_intent-2.4.20-hp	Thu Nov 28 15:53:15 2002
-+++ linux-mmonroe/fs/namespace.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/fs/namespace.c~vfs_intent-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/namespace.c	2003-09-14 17:33:51.000000000 +0400
 @@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
  {
  	old_nd->dentry = mnt->mnt_mountpoint;
@@ -228,8 +230,8 @@
  	path_release(&new_nd);
  out0:
  	unlock_kernel();
---- linux/fs/namei.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:04:48 2003
-+++ linux-mmonroe/fs/namei.c	Sat Jul 12 14:08:01 2003
+--- linux-2.4.20-hp4-pnnl13/fs/namei.c~vfs_intent-2.4.20-hp	2003-09-13 15:19:23.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/namei.c	2003-09-14 17:33:51.000000000 +0400
 @@ -94,6 +94,13 @@
   * XEmacs seems to be relying on it...
   */
@@ -265,7 +267,7 @@
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
  			dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
   * make sure that nobody added the entry to the dcache in the meantime..
   * SMP-safe
   */
@@ -275,13 +277,14 @@
  {
  	struct dentry * result;
  	struct inode *dir = parent->d_inode;
++	int counter = 0;
  
 +again:
-+
++	counter++;
  	down(&dir->i_sem);
  	/*
  	 * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
  		result = ERR_PTR(-ENOMEM);
  		if (dentry) {
  			lock_kernel();
@@ -291,7 +294,7 @@
  			result = dir->i_op->lookup(dir, dentry);
  			unlock_kernel();
  			if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
  			dput(result);
  			result = ERR_PTR(-ENOENT);
  		}
@@ -299,12 +302,15 @@
 +		if (!result->d_op->d_revalidate_it(result, flags, it) &&
 +		    !d_invalidate(result)) {
 +			dput(result);
-+			goto again;
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
 +		}
  	}
  	return result;
  }
-@@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
+@@ -332,7 +364,8 @@ static struct dentry * real_lookup(struc
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups. 
   */
@@ -314,13 +320,13 @@
  {
  	int err;
  	if (current->link_count >= 5)
-@@ -346,10 +375,18 @@ static inline int do_follow_link(struct 
+@@ -346,10 +379,18 @@ static inline int do_follow_link(struct 
  	current->link_count++;
  	current->total_link_count++;
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
++	if (!err && it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) {
 +		/* vfs_follow_link was never called */
 +		intent_release(it);
 +		path_release(nd);
@@ -333,7 +339,7 @@
  	path_release(nd);
  	return -ELOOP;
  }
-@@ -379,15 +416,26 @@ int follow_up(struct vfsmount **mnt, str
+@@ -379,15 +420,26 @@ int follow_up(struct vfsmount **mnt, str
  	return __follow_up(mnt, dentry);
  }
  
@@ -351,17 +357,17 @@
  		spin_unlock(&dcache_lock);
 +		if (it) {
 +			opc = it->it_op;
-+			mode = it->it_mode;
++			mode = it->it_create_mode;
 +		}
 +		intent_release(it);
 +		if (it) {
 +			it->it_op = opc;
-+			it->it_mode = mode;
++			it->it_create_mode = mode;
 +		}
  		dput(*dentry);
  		mntput(mounted->mnt_parent);
  		*dentry = dget(mounted->mnt_root);
-@@ -399,7 +447,7 @@ static inline int __follow_down(struct v
+@@ -399,7 +451,7 @@ static inline int __follow_down(struct v
  
  int follow_down(struct vfsmount **mnt, struct dentry **dentry)
  {
@@ -370,7 +376,7 @@
  }
   
  static inline void follow_dotdot(struct nameidata *nd)
-@@ -435,7 +483,7 @@ static inline void follow_dotdot(struct 
+@@ -435,7 +487,7 @@ static inline void follow_dotdot(struct 
  		mntput(nd->mnt);
  		nd->mnt = parent;
  	}
@@ -379,7 +385,7 @@
  		;
  }
  
-@@ -447,7 +495,8 @@ static inline void follow_dotdot(struct 
+@@ -447,7 +499,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
   */
@@ -389,7 +395,7 @@
  {
  	struct dentry *dentry;
  	struct inode *inode;
-@@ -520,15 +569,15 @@ int link_path_walk(const char * name, st
+@@ -520,15 +573,15 @@ int link_path_walk(const char * name, st
  				break;
  		}
  		/* This does the actual lookups.. */
@@ -408,7 +414,7 @@
  			;
  
  		err = -ENOENT;
-@@ -540,7 +589,7 @@ int link_path_walk(const char * name, st
+@@ -540,7 +593,7 @@ int link_path_walk(const char * name, st
  			goto out_dput;
  
  		if (inode->i_op->follow_link) {
@@ -417,7 +423,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -556,7 +605,7 @@ int link_path_walk(const char * name, st
+@@ -556,7 +609,7 @@ int link_path_walk(const char * name, st
  			nd->dentry = dentry;
  		}
  		err = -ENOTDIR; 
@@ -426,7 +432,7 @@
  			break;
  		continue;
  		/* here ends the main loop */
-@@ -583,19 +632,19 @@ last_component:
+@@ -583,19 +636,19 @@ last_component:
  			if (err < 0)
  				break;
  		}
@@ -450,7 +456,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -609,7 +658,8 @@ last_component:
+@@ -609,7 +662,8 @@ last_component:
  			goto no_inode;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
@@ -460,11 +466,10 @@
  				break;
  		}
  		goto return_base;
-@@ -633,6 +683,23 @@ return_reval:
+@@ -633,6 +687,25 @@ return_reval:
  		 * Check the cached dentry for staleness.
  		 */
  		dentry = nd->dentry;
-+	revalidate_again:
 +		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
 +			err = -ESTALE;
 +			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
@@ -477,14 +482,17 @@
 +						  &dentry->d_name, 0, NULL);
 +				d_invalidate(dentry);
 +				dput(dentry);
-+				dentry = new;
-+				goto revalidate_again;
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
 +			}
 +		} else
  		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  			err = -ESTALE;
  			if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -646,15 +713,28 @@ out_dput:
+@@ -646,15 +719,28 @@ out_dput:
  		dput(dentry);
  		break;
  	}
@@ -514,7 +522,7 @@
  }
  
  /* SMP-safe */
-@@ -739,6 +819,17 @@ walk_init_root(const char *name, struct 
+@@ -739,6 +825,17 @@ walk_init_root(const char *name, struct 
  }
  
  /* SMP-safe */
@@ -532,15 +540,15 @@
  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
  {
  	int error = 0;
-@@ -753,6 +844,7 @@ int path_init(const char *name, unsigned
+@@ -753,6 +850,7 @@ int path_init(const char *name, unsigned
  {
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
-+	nd->it = NULL;
++	nd->intent = NULL;
  	if (*name=='/')
  		return walk_init_root(name,nd);
  	read_lock(&current->fs->lock);
-@@ -767,7 +859,8 @@ int path_init(const char *name, unsigned
+@@ -767,7 +865,8 @@ int path_init(const char *name, unsigned
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -550,7 +558,7 @@
  {
  	struct dentry * dentry;
  	struct inode *inode;
-@@ -790,13 +883,16 @@ struct dentry * lookup_hash(struct qstr 
+@@ -790,13 +889,16 @@ struct dentry * lookup_hash(struct qstr 
  			goto out;
  	}
  
@@ -568,7 +576,7 @@
  		dentry = inode->i_op->lookup(inode, new);
  		unlock_kernel();
  		if (!dentry)
-@@ -808,6 +904,12 @@ out:
+@@ -808,6 +910,12 @@ out:
  	return dentry;
  }
  
@@ -581,7 +589,7 @@
  /* SMP-safe */
  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
  {
-@@ -829,7 +931,7 @@ struct dentry * lookup_one_len(const cha
+@@ -829,7 +937,7 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -590,7 +598,7 @@
  access:
  	return ERR_PTR(-EACCES);
  }
-@@ -860,6 +962,23 @@ int __user_walk(const char *name, unsign
+@@ -860,6 +968,23 @@ int __user_walk(const char *name, unsign
  	return err;
  }
  
@@ -614,7 +622,7 @@
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -955,7 +1074,8 @@ static inline int lookup_flags(unsigned 
+@@ -955,7 +1080,8 @@ static inline int lookup_flags(unsigned 
  	return retval;
  }
  
@@ -624,7 +632,7 @@
  {
  	int error;
  
-@@ -968,12 +1088,15 @@ int vfs_create(struct inode *dir, struct
+@@ -968,12 +1094,15 @@ int vfs_create(struct inode *dir, struct
  		goto exit_lock;
  
  	error = -EACCES;	/* shouldn't it be ENOSYS? */
@@ -642,7 +650,7 @@
  	unlock_kernel();
  exit_lock:
  	up(&dir->i_zombie);
-@@ -982,6 +1105,11 @@ exit_lock:
+@@ -982,6 +1111,11 @@ exit_lock:
  	return error;
  }
  
@@ -654,7 +662,7 @@
  /*
   *	open_namei()
   *
-@@ -996,7 +1124,8 @@ exit_lock:
+@@ -996,7 +1130,8 @@ exit_lock:
   * for symlinks (where the permissions are checked later).
   * SMP-safe
   */
@@ -664,7 +672,14 @@
  {
  	int acc_mode, error = 0;
  	struct inode *inode;
-@@ -1010,7 +1139,7 @@ int open_namei(const char * pathname, in
+@@ -1006,11 +1141,14 @@ int open_namei(const char * pathname, in
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
++
+ 	/*
  	 * The simplest case - just a plain lookup.
  	 */
  	if (!(flag & O_CREAT)) {
@@ -673,18 +688,18 @@
  		if (error)
  			return error;
  		dentry = nd->dentry;
-@@ -1020,6 +1149,10 @@ int open_namei(const char * pathname, in
+@@ -1020,6 +1158,10 @@ int open_namei(const char * pathname, in
  	/*
  	 * Create - we need to know the parent.
  	 */
-+ 	if (it) {
-+ 		it->it_mode = mode;
-+ 		it->it_op |= IT_CREAT;
-+ 	}
++	if (it) {
++		it->it_create_mode = mode;
++		it->it_op |= IT_CREAT;
++	}
  	error = path_lookup(pathname, LOOKUP_PARENT, nd);
  	if (error)
  		return error;
-@@ -1035,7 +1168,7 @@ int open_namei(const char * pathname, in
+@@ -1035,7 +1177,7 @@ int open_namei(const char * pathname, in
  
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -693,11 +708,11 @@
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1044,11 +1177,12 @@ do_last:
+@@ -1044,11 +1186,12 @@ do_last:
  		goto exit;
  	}
  
-+	it->it_mode = mode;
++	it->it_create_mode = mode;
  	/* Negative dentry, just create the file */
  	if (!dentry->d_inode) {
  		if (!IS_POSIXACL(dir->d_inode))
@@ -707,7 +722,7 @@
  		up(&dir->d_inode->i_sem);
  		dput(nd->dentry);
  		nd->dentry = dentry;
-@@ -1073,7 +1207,7 @@ do_last:
+@@ -1073,7 +1216,7 @@ do_last:
  		error = -ELOOP;
  		if (flag & O_NOFOLLOW)
  			goto exit_dput;
@@ -716,7 +731,7 @@
  	}
  	error = -ENOENT;
  	if (!dentry->d_inode)
-@@ -1152,7 +1286,7 @@ ok:
+@@ -1152,7 +1295,7 @@ ok:
  		if (!error) {
  			DQUOT_INIT(inode);
  			
@@ -725,7 +740,7 @@
  		}
  		put_write_access(inode);
  		if (error)
-@@ -1164,8 +1298,10 @@ ok:
+@@ -1164,8 +1307,10 @@ ok:
  	return 0;
  
  exit_dput:
@@ -736,15 +751,15 @@
  	path_release(nd);
  	return error;
  
-@@ -1184,7 +1320,16 @@ do_link:
+@@ -1184,7 +1329,16 @@ do_link:
  	 * are done. Procfs-like symlinks just set LAST_BIND.
  	 */
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 +	if (error) {
 +		intent_release(it);
-+	} else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
++	} else if (it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) {
 +		/* vfs_follow_link was never called */
 +		intent_release(it);
 +		path_release(nd);
@@ -753,7 +768,7 @@
  	dput(dentry);
  	if (error)
  		return error;
-@@ -1206,13 +1351,20 @@ do_link:
+@@ -1206,13 +1360,20 @@ do_link:
  	}
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -776,7 +791,7 @@
  {
  	struct dentry *dentry;
  
-@@ -1220,7 +1372,7 @@ static struct dentry *lookup_create(stru
+@@ -1220,7 +1381,7 @@ static struct dentry *lookup_create(stru
  	dentry = ERR_PTR(-EEXIST);
  	if (nd->last_type != LAST_NORM)
  		goto fail;
@@ -785,7 +800,7 @@
  	if (IS_ERR(dentry))
  		goto fail;
  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1276,7 +1428,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1276,7 +1437,16 @@ asmlinkage long sys_mknod(const char * f
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -803,7 +818,7 @@
  	error = PTR_ERR(dentry);
  
  	if (!IS_POSIXACL(nd.dentry->d_inode))
-@@ -1298,6 +1459,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1298,6 +1468,7 @@ asmlinkage long sys_mknod(const char * f
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -811,23 +826,23 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1345,7 +1507,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1345,7 +1516,14 @@ asmlinkage long sys_mkdir(const char * p
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
 -		dentry = lookup_create(&nd, 1);
-+ 		if (nd.dentry->d_inode->i_op->mkdir_raw) {
-+ 			struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 			error = op->mkdir_raw(&nd, mode);
-+ 			/* the file system wants to use normal vfs path now */
-+ 			if (error != -EOPNOTSUPP)
-+ 				goto out2;
-+ 		}
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
 +		dentry = lookup_create(&nd, 1, NULL);
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
  			if (!IS_POSIXACL(nd.dentry->d_inode))
-@@ -1354,6 +1523,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1354,6 +1532,7 @@ asmlinkage long sys_mkdir(const char * p
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -835,42 +850,42 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1454,8 +1624,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1454,8 +1633,16 @@ asmlinkage long sys_rmdir(const char * p
  			error = -EBUSY;
  			goto exit1;
  	}
-+ 	if (nd.dentry->d_inode->i_op->rmdir_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
 +
-+ 		error = op->rmdir_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1513,8 +1691,15 @@ asmlinkage long sys_unlink(const char * 
+@@ -1513,8 +1700,15 @@ asmlinkage long sys_unlink(const char * 
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
-+ 	if (nd.dentry->d_inode->i_op->unlink_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 		error = op->unlink_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
-@@ -1581,15 +1766,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1581,15 +1775,23 @@ asmlinkage long sys_symlink(const char *
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -896,7 +911,7 @@
  		putname(to);
  	}
  	putname(from);
-@@ -1665,7 +1858,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1665,7 +1867,14 @@ asmlinkage long sys_link(const char * ol
  		error = -EXDEV;
  		if (old_nd.mnt != nd.mnt)
  			goto out_release;
@@ -912,7 +927,7 @@
  		error = PTR_ERR(new_dentry);
  		if (!IS_ERR(new_dentry)) {
  			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1709,7 +1909,7 @@ exit:
+@@ -1709,7 +1918,7 @@ exit:
   *	   locking].
   */
  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -921,7 +936,7 @@
  {
  	int error;
  	struct inode *target;
-@@ -1788,7 +1988,7 @@ out_unlock:
+@@ -1788,7 +1997,7 @@ out_unlock:
  }
  
  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
@@ -930,18 +945,18 @@
  {
  	int error;
  
-@@ -1876,9 +2076,18 @@ static inline int do_rename(const char *
+@@ -1876,9 +2085,18 @@ static inline int do_rename(const char *
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
  
-+ 	if (old_dir->d_inode->i_op->rename_raw) {
++	if (old_dir->d_inode->i_op->rename_raw) {
 +		lock_kernel();
-+ 		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
 +		unlock_kernel();
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit2;
-+ 	}
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
 +
  	double_lock(new_dir, old_dir);
  
@@ -950,7 +965,7 @@
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
-@@ -1894,16 +2103,16 @@ static inline int do_rename(const char *
+@@ -1894,16 +2112,16 @@ static inline int do_rename(const char *
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
@@ -969,7 +984,7 @@
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
-@@ -1954,20 +2163,28 @@ out:
+@@ -1954,20 +2172,28 @@ out:
  }
  
  static inline int
@@ -983,11 +998,11 @@
  		goto fail;
  
 +	if (it == NULL)
-+		it = nd->it;
-+	else if (it != nd->it)
-+		printk("it != nd->it: tell phil@clusterfs.com\n");
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
 +	if (it != NULL)
-+		it->it_int_flags |= IT_FL_FOLLOWED;
++		it->d.lustre.it_int_flags |= IT_FL_FOLLOWED;
 +
  	if (*link == '/') {
  		path_release(nd);
@@ -1000,7 +1015,7 @@
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
  		return res;
-@@ -1989,7 +2206,13 @@ fail:
+@@ -1989,7 +2215,13 @@ fail:
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
@@ -1015,7 +1030,7 @@
  }
  
  /* get the link contents into pagecache */
-@@ -2031,7 +2254,7 @@ int page_follow_link(struct dentry *dent
+@@ -2031,7 +2263,7 @@ int page_follow_link(struct dentry *dent
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
@@ -1024,8 +1039,8 @@
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
---- linux/fs/open.c~vfs_intent-2.4.20-hp	Thu Nov 28 15:53:15 2002
-+++ linux-mmonroe/fs/open.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/fs/open.c~vfs_intent-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/open.c	2003-09-14 17:33:51.000000000 +0400
 @@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
@@ -1209,7 +1224,7 @@
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
 +	error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
@@ -1228,7 +1243,7 @@
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 -		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
@@ -1237,7 +1252,7 @@
  	if (error)
  		goto out;
  
-@@ -454,6 +502,7 @@ asmlinkage long sys_chroot(const char * 
+@@ -454,39 +502,56 @@ asmlinkage long sys_chroot(const char * 
  	set_fs_altroot();
  	error = 0;
  dput_and_out:
@@ -1245,26 +1260,102 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -508,6 +557,18 @@ asmlinkage long sys_chmod(const char * f
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
  
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
 +	if (inode->i_op->setattr_raw) {
-+		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
 +		newattrs.ia_mode = mode;
 +		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 +		newattrs.ia_valid |= ATTR_RAW;
-+		error = op->setattr_raw(inode, &newattrs);
++		err = inode->i_op->setattr_raw(inode, &newattrs);
 +		/* the file system wants to use normal vfs path now */
-+		if (error != -EOPNOTSUPP)
-+			goto dput_and_out;
++		if (err != -EOPNOTSUPP)
++			goto out;
 +	}
-+
- 	error = -EPERM;
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -538,6 +599,20 @@ static int chown_common(struct dentry * 
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -495,30 +560,14 @@ out:
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
++	error = chmod_common(nd.dentry, mode);
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
+-
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -538,6 +587,20 @@ static int chown_common(struct dentry * 
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto out;
@@ -1285,20 +1376,15 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
-@@ -638,10 +713,12 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+
- struct file *filp_open(const char * filename, int flags, int mode)
+@@ -642,6 +705,7 @@ struct file *filp_open(const char * file
  {
  	int namei_flags, error;
  	struct nameidata nd;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
++	struct lookup_intent it = { .it_op = IT_OPEN };
  
  	namei_flags = flags;
  	if ((namei_flags+1) & O_ACCMODE)
-@@ -649,14 +726,15 @@ struct file *filp_open(const char * file
+@@ -649,14 +713,15 @@ struct file *filp_open(const char * file
  	if (namei_flags & O_TRUNC)
  		namei_flags |= 2;
  
@@ -1319,7 +1405,7 @@
  {
  	struct file * f;
  	struct inode *inode;
-@@ -693,12 +771,15 @@ struct file *dentry_open(struct dentry *
+@@ -693,12 +758,15 @@ struct file *dentry_open(struct dentry *
  	}
  
  	if (f->f_op && f->f_op->open) {
@@ -1335,7 +1421,7 @@
  	return f;
  
  cleanup_all:
-@@ -713,11 +794,17 @@ cleanup_all:
+@@ -713,11 +781,17 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
@@ -1353,9 +1439,9 @@
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux/fs/stat.c~vfs_intent-2.4.20-hp	Thu Sep 13 16:04:43 2001
-+++ linux-mmonroe/fs/stat.c	Sat Jul 12 14:05:24 2003
-@@ -17,10 +17,12 @@
+--- linux-2.4.20-hp4-pnnl13/fs/stat.c~vfs_intent-2.4.20-hp	2001-09-14 03:04:43.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/stat.c	2003-09-14 17:34:07.000000000 +0400
+@@ -17,10 +17,14 @@
   * Revalidate the inode. This is required for proper NFS attribute caching.
   */
  static __inline__ int
@@ -1364,13 +1450,15 @@
  {
  	struct inode * inode = dentry->d_inode;
 -	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
 +	if (inode->i_op && inode->i_op->revalidate_it)
 +		return inode->i_op->revalidate_it(dentry, it);
 +	else if (inode->i_op && inode->i_op->revalidate)
  		return inode->i_op->revalidate(dentry);
  	return 0;
  }
-@@ -135,13 +137,15 @@ static int cp_new_stat(struct inode * in
+@@ -135,13 +139,15 @@ static int cp_new_stat(struct inode * in
  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
  {
  	struct nameidata nd;
@@ -1388,7 +1476,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -151,13 +155,15 @@ asmlinkage long sys_stat(char * filename
+@@ -151,13 +157,15 @@ asmlinkage long sys_stat(char * filename
  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
  {
  	struct nameidata nd;
@@ -1406,7 +1494,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -172,13 +178,15 @@ asmlinkage long sys_newstat(char * filen
+@@ -172,13 +180,15 @@ asmlinkage long sys_newstat(char * filen
  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
  {
  	struct nameidata nd;
@@ -1424,7 +1512,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -189,13 +197,15 @@ asmlinkage long sys_lstat(char * filenam
+@@ -189,13 +199,15 @@ asmlinkage long sys_lstat(char * filenam
  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
  {
  	struct nameidata nd;
@@ -1442,7 +1530,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -216,7 +226,7 @@ asmlinkage long sys_fstat(unsigned int f
+@@ -216,7 +228,7 @@ asmlinkage long sys_fstat(unsigned int f
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1451,7 +1539,7 @@
  		if (!err)
  			err = cp_old_stat(dentry->d_inode, statbuf);
  		fput(f);
-@@ -235,7 +245,7 @@ asmlinkage long sys_newfstat(unsigned in
+@@ -235,7 +247,7 @@ asmlinkage long sys_newfstat(unsigned in
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1460,7 +1548,7 @@
  		if (!err)
  			err = cp_new_stat(dentry->d_inode, statbuf);
  		fput(f);
-@@ -257,7 +267,7 @@ asmlinkage long sys_readlink(const char 
+@@ -257,7 +269,7 @@ asmlinkage long sys_readlink(const char 
  
  		error = -EINVAL;
  		if (inode->i_op && inode->i_op->readlink &&
@@ -1469,7 +1557,7 @@
  			UPDATE_ATIME(inode);
  			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
  		}
-@@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena
+@@ -333,12 +345,14 @@ asmlinkage long sys_stat64(char * filena
  {
  	struct nameidata nd;
  	int error;
@@ -1486,7 +1574,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen
+@@ -348,12 +362,14 @@ asmlinkage long sys_lstat64(char * filen
  {
  	struct nameidata nd;
  	int error;
@@ -1503,7 +1591,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -368,7 +382,7 @@ asmlinkage long sys_fstat64(unsigned lon
+@@ -368,7 +384,7 @@ asmlinkage long sys_fstat64(unsigned lon
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1512,27 +1600,26 @@
  		if (!err)
  			err = cp_new_stat64(dentry->d_inode, statbuf);
  		fput(f);
---- linux/fs/proc/base.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:04:46 2003
-+++ linux-mmonroe/fs/proc/base.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/fs/proc/base.c~vfs_intent-2.4.20-hp	2003-09-13 15:19:19.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/fs/proc/base.c	2003-09-14 17:33:51.000000000 +0400
 @@ -481,6 +481,9 @@ static int proc_pid_follow_link(struct d
  
  	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
  	nd->last_type = LAST_BIND;
 +
-+	if (nd->it != NULL)
-+		nd->it->it_int_flags |= IT_FL_FOLLOWED;
++	if (nd->intent != NULL)
++		nd->intent->d.lustre.it_int_flags |= IT_FL_FOLLOWED;
  out:
  	return error;
  }
---- linux/include/linux/dcache.h~vfs_intent-2.4.20-hp	Thu Nov 28 15:53:15 2002
-+++ linux-mmonroe/include/linux/dcache.h	Sat Jul 12 14:06:04 2003
-@@ -5,8 +5,47 @@
- 
+--- linux-2.4.20-hp4-pnnl13/include/linux/dcache.h~vfs_intent-2.4.20-hp	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.20-hp4-pnnl13-alexey/include/linux/dcache.h	2003-09-14 17:33:51.000000000 +0400
+@@ -6,6 +6,51 @@
  #include <asm/atomic.h>
  #include <linux/mount.h>
-+#include <linux/string.h>
  #include <linux/kernel.h>
- 
++#include <linux/string.h>
++
 +#define IT_OPEN     0x0001
 +#define IT_CREAT    0x0002
 +#define IT_READDIR  0x0004
@@ -1548,18 +1635,24 @@
 +
 +#define INTENT_MAGIC 0x19620323
 +
-+struct lookup_intent {
-+	int it_op;
-+	void (*it_op_release)(struct lookup_intent *);
-+	int it_magic;
-+	int it_mode;
-+	int it_flags;
-+	int it_disposition;
-+	int it_status;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
 +	int it_int_flags;
-+	__u64 it_lock_handle[2];
-+	int it_lock_mode;
-+	void *it_data;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op, int flags)
@@ -1570,11 +1663,10 @@
 +	it->it_flags = flags;
 +}
 +
-+
+ 
  /*
   * linux/include/linux/dcache.h
-  *
-@@ -91,8 +130,22 @@ struct dentry_operations {
+@@ -91,8 +136,22 @@ struct dentry_operations {
  	int (*d_delete)(struct dentry *);
  	void (*d_release)(struct dentry *);
  	void (*d_iput)(struct dentry *, struct inode *);
@@ -1597,7 +1689,7 @@
  /* the dentry parameter passed to d_hash and d_compare is the parent
   * directory of the entries to be compared. It is used in case these
   * functions need any directory specific information for determining
-@@ -124,6 +177,7 @@ d_iput:		no		no		yes
+@@ -124,6 +183,7 @@ d_iput:		no		no		yes
  					 * s_nfsd_free_path semaphore will be down
  					 */
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
@@ -1605,9 +1697,17 @@
  
  extern spinlock_t dcache_lock;
  
---- linux/include/linux/fs.h~vfs_intent-2.4.20-hp	Sat Jul 12 14:05:20 2003
-+++ linux-mmonroe/include/linux/fs.h	Sat Jul 12 14:05:24 2003
-@@ -340,6 +340,9 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.20-hp4-pnnl13/include/linux/fs.h~vfs_intent-2.4.20-hp	2003-09-14 17:33:50.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/include/linux/fs.h	2003-09-14 17:33:51.000000000 +0400
+@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -340,6 +341,9 @@ extern void set_bh_page(struct buffer_he
  #define ATTR_MTIME_SET	256
  #define ATTR_FORCE	512	/* Not a change, but a change it */
  #define ATTR_ATTR_FLAG	1024
@@ -1617,7 +1717,15 @@
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -576,6 +579,7 @@ struct file {
+@@ -474,6 +478,7 @@ struct inode {
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -576,6 +581,7 @@ struct file {
  
  	/* needed for tty driver, and maybe others */
  	void			*private_data;
@@ -1625,15 +1733,15 @@
  
  	/* preallocated helper kiobuf to speedup O_DIRECT */
  	struct kiobuf		*f_iobuf;
-@@ -697,6 +701,7 @@ struct nameidata {
+@@ -697,6 +703,7 @@ struct nameidata {
  	struct qstr last;
  	unsigned int flags;
  	int last_type;
-+	struct lookup_intent *it;
++	struct lookup_intent *intent;
  };
  
  /*
-@@ -817,7 +822,8 @@ extern int vfs_symlink(struct inode *, s
+@@ -817,7 +824,8 @@ extern int vfs_symlink(struct inode *, s
  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
  extern int vfs_rmdir(struct inode *, struct dentry *);
  extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1643,7 +1751,7 @@
  
  /*
   * File types
-@@ -877,21 +883,32 @@ struct file_operations {
+@@ -877,21 +885,32 @@ struct file_operations {
  
  struct inode_operations {
  	int (*create) (struct inode *,struct dentry *,int);
@@ -1672,11 +1780,11 @@
  	int (*revalidate) (struct dentry *);
 +	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
  	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
  	int (*getattr) (struct dentry *, struct iattr *);
  	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
  	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1088,10 +1105,14 @@ static inline int get_lease(struct inode
+@@ -1088,10 +1107,14 @@ static inline int get_lease(struct inode
  
  asmlinkage long sys_open(const char *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
@@ -1692,7 +1800,7 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char *);
  
-@@ -1353,6 +1374,7 @@ typedef int (*read_actor_t)(read_descrip
+@@ -1353,6 +1376,7 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
@@ -1700,7 +1808,7 @@
  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
  extern int FASTCALL(path_walk(const char *, struct nameidata *));
  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1364,6 +1386,8 @@ extern struct dentry * lookup_one_len(co
+@@ -1364,6 +1388,8 @@ extern struct dentry * lookup_one_len(co
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
  #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
@@ -1709,7 +1817,7 @@
  
  extern void inode_init_once(struct inode *);
  extern void iput(struct inode *);
-@@ -1499,6 +1523,8 @@ extern struct file_operations generic_ro
+@@ -1499,6 +1525,8 @@ extern struct file_operations generic_ro
  
  extern int vfs_readlink(struct dentry *, char *, int, const char *);
  extern int vfs_follow_link(struct nameidata *, const char *);
@@ -1718,8 +1826,8 @@
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- linux/include/linux/fs_struct.h~vfs_intent-2.4.20-hp	Fri Jul 13 15:10:44 2001
-+++ linux-mmonroe/include/linux/fs_struct.h	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/include/linux/fs_struct.h~vfs_intent-2.4.20-hp	2001-07-14 02:10:44.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/include/linux/fs_struct.h	2003-09-14 17:33:51.000000000 +0400
 @@ -34,10 +34,12 @@ static inline void set_fs_root(struct fs
  	write_lock(&fs->lock);
  	old_root = fs->root;
@@ -1746,8 +1854,8 @@
  		dput(old_pwd);
  		mntput(old_pwdmnt);
  	}
---- linux/kernel/ksyms.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:05:21 2003
-+++ linux-mmonroe/kernel/ksyms.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/kernel/ksyms.c~vfs_intent-2.4.20-hp	2003-09-14 17:33:50.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/kernel/ksyms.c	2003-09-14 17:33:51.000000000 +0400
 @@ -296,6 +296,7 @@ EXPORT_SYMBOL(read_cache_page);
  EXPORT_SYMBOL(set_page_dirty);
  EXPORT_SYMBOL(vfs_readlink);
@@ -1756,8 +1864,8 @@
  EXPORT_SYMBOL(page_readlink);
  EXPORT_SYMBOL(page_follow_link);
  EXPORT_SYMBOL(page_symlink_inode_operations);
---- linux/kernel/fork.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:04:49 2003
-+++ linux-mmonroe/kernel/fork.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/kernel/fork.c~vfs_intent-2.4.20-hp	2003-09-13 15:19:27.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/kernel/fork.c	2003-09-14 17:33:51.000000000 +0400
 @@ -388,10 +388,13 @@ static inline struct fs_struct *__copy_f
  		fs->umask = old->umask;
  		read_lock(&old->lock);
@@ -1772,8 +1880,8 @@
  			fs->altrootmnt = mntget(old->altrootmnt);
  			fs->altroot = dget(old->altroot);
  		} else {
---- linux/kernel/exit.c~vfs_intent-2.4.20-hp	Sat Jul 12 14:04:49 2003
-+++ linux-mmonroe/kernel/exit.c	Sat Jul 12 14:05:24 2003
+--- linux-2.4.20-hp4-pnnl13/kernel/exit.c~vfs_intent-2.4.20-hp	2003-09-13 15:19:27.000000000 +0400
++++ linux-2.4.20-hp4-pnnl13-alexey/kernel/exit.c	2003-09-14 17:33:51.000000000 +0400
 @@ -239,11 +239,14 @@ static inline void __put_fs_struct(struc
  {
  	/* No need to hold fs->lock if we are killing it */
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch
index 83218d926ead4723aa857b9660ae577b031c9430..7334495679b550ea9e5ea979336f330e0a95bc3f 100644
--- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch
@@ -1,7 +1,20 @@
- 0 files changed
+ fs/dcache.c               |   19 ++
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  333 ++++++++++++++++++++++++++++++++++++++--------
+ fs/namespace.c            |   28 ++-
+ fs/open.c                 |  176 +++++++++++++++++-------
+ fs/proc/base.c            |    3 
+ fs/stat.c                 |   28 ++-
+ include/linux/dcache.h    |   60 ++++++++
+ include/linux/fs.h        |   32 ++++
+ include/linux/fs_struct.h |    4 
+ kernel/exit.c             |    3 
+ kernel/fork.c             |    3 
+ kernel/ksyms.c            |    1 
+ 13 files changed, 578 insertions(+), 129 deletions(-)
 
---- linux-2.4.20/fs/dcache.c~vfs_intent-2.4.20-rh	2003-07-17 08:32:59.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/dcache.c	2003-07-17 08:35:22.000000000 -0700
+--- linux-2.4.20-rh-20.9/fs/dcache.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/dcache.c	2003-09-14 17:34:53.000000000 +0400
 @@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
  		spin_unlock(&dcache_lock);
  		return 0;
@@ -16,7 +29,7 @@
  	/*
  	 * Check whether to do a partial shrink_dcache
  	 * to get rid of unused child entries.
-@@ -839,13 +846,19 @@ void d_delete(struct dentry * dentry)
+@@ -841,13 +848,19 @@ void d_delete(struct dentry * dentry)
   * Adds a dentry to the hash according to its name.
   */
   
@@ -39,20 +52,21 @@
  }
  
  #define do_switch(x,y) do { \
---- linux-2.4.20/fs/exec.c~vfs_intent-2.4.20-rh	2003-07-17 08:33:09.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/exec.c	2003-07-17 08:35:22.000000000 -0700
-@@ -114,8 +114,9 @@ asmlinkage long sys_uselib(const char * 
+--- linux-2.4.20-rh-20.9/fs/exec.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/exec.c	2003-09-14 17:34:53.000000000 +0400
+@@ -114,8 +114,10 @@ asmlinkage long sys_uselib(const char * 
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	error = user_path_walk(library, &nd);
 +	error = user_path_walk_it(library, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -127,7 +128,8 @@ asmlinkage long sys_uselib(const char * 
+@@ -127,7 +129,8 @@ asmlinkage long sys_uselib(const char * 
  	if (error)
  		goto exit;
  
@@ -62,18 +76,19 @@
  	error = PTR_ERR(file);
  	if (IS_ERR(file))
  		goto out;
-@@ -382,8 +384,9 @@ struct file *open_exec(const char *name)
+@@ -382,8 +385,10 @@ struct file *open_exec(const char *name)
  	struct inode *inode;
  	struct file *file;
  	int err = 0;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 +	err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
  	file = ERR_PTR(err);
  	if (!err) {
  		inode = nd.dentry->d_inode;
-@@ -395,7 +398,8 @@ struct file *open_exec(const char *name)
+@@ -395,7 +400,8 @@ struct file *open_exec(const char *name)
  				err = -EACCES;
  			file = ERR_PTR(err);
  			if (!err) {
@@ -83,7 +98,7 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
-@@ -407,6 +411,7 @@ out:
+@@ -407,6 +413,7 @@ out:
  				return file;
  			}
  		}
@@ -91,7 +106,7 @@
  		path_release(&nd);
  	}
  	goto out;
-@@ -1283,7 +1288,7 @@ int do_coredump(long signr, int exit_cod
+@@ -1296,7 +1303,7 @@ int do_coredump(long signr, int exit_cod
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
@@ -100,125 +115,8 @@
  		goto close_fail;
  
  	retval = binfmt->core_dump(signr, regs, file);
---- linux-2.4.18-p4smp/fs/namespace.c~vfs_intent-2.4.18-18-chaos65	2002-06-25 22:16:14.000000000 -0600
-+++ linux-2.4.18-p4smp-braam/fs/namespace.c	2003-07-09 13:20:37.000000000 -0600
-@@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
- {
- 	old_nd->dentry = mnt->mnt_mountpoint;
- 	old_nd->mnt = mnt->mnt_parent;
-+	UNPIN(old_nd->dentry, old_nd->mnt, 1);
- 	mnt->mnt_parent = mnt;
- 	mnt->mnt_mountpoint = mnt->mnt_root;
- 	list_del_init(&mnt->mnt_child);
-@@ -110,6 +111,7 @@ static void attach_mnt(struct vfsmount *
- {
- 	mnt->mnt_parent = mntget(nd->mnt);
- 	mnt->mnt_mountpoint = dget(nd->dentry);
-+	PIN(nd->dentry, nd->mnt, 1);
- 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
- 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
- 	nd->dentry->d_mounted++;
-@@ -485,14 +487,17 @@ static int do_loopback(struct nameidata 
- {
- 	struct nameidata old_nd;
- 	struct vfsmount *mnt = NULL;
-+	struct lookup_intent it = { .it_op = IT_GETATTR };
- 	int err = mount_is_safe(nd);
- 	if (err)
- 		return err;
- 	if (!old_name || !*old_name)
- 		return -EINVAL;
--	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
--	if (err)
-+	err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it);
-+	if (err) {
-+		intent_release(&it);
- 		return err;
-+	}
- 
- 	down_write(&current->namespace->sem);
- 	err = -EINVAL;
-@@ -515,6 +520,7 @@ static int do_loopback(struct nameidata 
- 	}
- 
- 	up_write(&current->namespace->sem);
-+	intent_release(&it);
- 	path_release(&old_nd);
- 	return err;
- }
-@@ -698,7 +704,8 @@ long do_mount(char * dev_name, char * di
- 		  unsigned long flags, void *data_page)
- {
- 	struct nameidata nd;
--	int retval = 0;
-+	struct lookup_intent it = { .it_op = IT_GETATTR };
-+	int retval = 0;
- 	int mnt_flags = 0;
- 
- 	/* Discard magic */
-@@ -722,10 +729,11 @@ long do_mount(char * dev_name, char * di
- 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
- 
- 	/* ... and get the mountpoint */
--	retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
--	if (retval)
-+	retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-+	if (retval) {
-+		intent_release(&it);
- 		return retval;
--
-+	}
- 	if (flags & MS_REMOUNT)
- 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
- 				    data_page);
-@@ -736,6 +744,8 @@ long do_mount(char * dev_name, char * di
- 	else
- 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
- 				      dev_name, data_page);
-+
-+	intent_release(&it);
- 	path_release(&nd);
- 	return retval;
- }
-@@ -901,6 +911,8 @@ asmlinkage long sys_pivot_root(const cha
- {
- 	struct vfsmount *tmp;
- 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
-+	struct lookup_intent new_it = { .it_op = IT_GETATTR };
-+	struct lookup_intent old_it = { .it_op = IT_GETATTR };
- 	int error;
- 
- 	if (!capable(CAP_SYS_ADMIN))
-@@ -908,14 +920,14 @@ asmlinkage long sys_pivot_root(const cha
- 
- 	lock_kernel();
- 
--	error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
-+	error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it);
- 	if (error)
- 		goto out0;
- 	error = -EINVAL;
- 	if (!check_mnt(new_nd.mnt))
- 		goto out1;
- 
--	error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
-+	error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it);
- 	if (error)
- 		goto out1;
- 
-@@ -970,8 +982,10 @@ out2:
- 	up(&old_nd.dentry->d_inode->i_zombie);
- 	up_write(&current->namespace->sem);
- 	path_release(&user_nd);
-+	intent_release(&old_it);
- 	path_release(&old_nd);
- out1:
-+	intent_release(&new_it);
- 	path_release(&new_nd);
- out0:
- 	unlock_kernel();
---- linux-2.4.20/fs/namei.c~vfs_intent-2.4.20-rh	2003-07-17 08:32:47.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/namei.c	2003-07-17 08:35:22.000000000 -0700
+--- linux-2.4.20-rh-20.9/fs/namei.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:25.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/namei.c	2003-09-14 17:34:53.000000000 +0400
 @@ -94,6 +94,13 @@
   * XEmacs seems to be relying on it...
   */
@@ -254,7 +152,7 @@
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
  			dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
   * make sure that nobody added the entry to the dcache in the meantime..
   * SMP-safe
   */
@@ -264,13 +162,14 @@
  {
  	struct dentry * result;
  	struct inode *dir = parent->d_inode;
++	int counter = 0;
  
 +again:
-+
++	counter++;
  	down(&dir->i_sem);
  	/*
  	 * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
  		result = ERR_PTR(-ENOMEM);
  		if (dentry) {
  			lock_kernel();
@@ -280,7 +179,7 @@
  			result = dir->i_op->lookup(dir, dentry);
  			unlock_kernel();
  			if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
  			dput(result);
  			result = ERR_PTR(-ENOENT);
  		}
@@ -288,12 +187,15 @@
 +		if (!result->d_op->d_revalidate_it(result, flags, it) &&
 +		    !d_invalidate(result)) {
 +			dput(result);
-+			goto again;
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
 +		}
  	}
  	return result;
  }
-@@ -334,7 +362,8 @@ int max_recursive_link = 5;
+@@ -334,7 +366,8 @@ int max_recursive_link = 5;
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups. 
   */
@@ -303,13 +205,13 @@
  {
  	int err;
  	if (current->link_count >= max_recursive_link)
-@@ -348,10 +377,18 @@ static inline int do_follow_link(struct 
+@@ -348,10 +381,18 @@ static inline int do_follow_link(struct 
  	current->link_count++;
  	current->total_link_count++;
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
++	if (!err && it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) {
 +		/* vfs_follow_link was never called */
 +		intent_release(it);
 +		path_release(nd);
@@ -322,7 +224,7 @@
  	path_release(nd);
  	return -ELOOP;
  }
-@@ -381,15 +418,26 @@ int follow_up(struct vfsmount **mnt, str
+@@ -381,15 +422,26 @@ int follow_up(struct vfsmount **mnt, str
  	return __follow_up(mnt, dentry);
  }
  
@@ -340,17 +242,17 @@
  		spin_unlock(&dcache_lock);
 +		if (it) {
 +			opc = it->it_op;
-+			mode = it->it_mode;
++			mode = it->it_create_mode;
 +		}
 +		intent_release(it);
 +		if (it) {
 +			it->it_op = opc;
-+			it->it_mode = mode;
++			it->it_create_mode = mode;
 +		}
  		dput(*dentry);
  		mntput(mounted->mnt_parent);
  		*dentry = dget(mounted->mnt_root);
-@@ -401,7 +449,7 @@ static inline int __follow_down(struct v
+@@ -401,7 +453,7 @@ static inline int __follow_down(struct v
  
  int follow_down(struct vfsmount **mnt, struct dentry **dentry)
  {
@@ -359,7 +261,7 @@
  }
   
  static inline void follow_dotdot(struct nameidata *nd)
-@@ -437,7 +485,7 @@ static inline void follow_dotdot(struct 
+@@ -437,7 +489,7 @@ static inline void follow_dotdot(struct 
  		mntput(nd->mnt);
  		nd->mnt = parent;
  	}
@@ -368,7 +270,7 @@
  		;
  }
  
-@@ -449,7 +497,8 @@ static inline void follow_dotdot(struct 
+@@ -449,7 +501,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
   */
@@ -378,7 +280,7 @@
  {
  	struct dentry *dentry;
  	struct inode *inode;
-@@ -526,19 +575,18 @@ int link_path_walk(const char * name, st
+@@ -526,19 +579,18 @@ int link_path_walk(const char * name, st
  				break;
  		}
  		/* This does the actual lookups.. */
@@ -401,7 +303,7 @@
  
  		err = -ENOENT;
  		inode = dentry->d_inode;
-@@ -549,7 +597,7 @@ int link_path_walk(const char * name, st
+@@ -549,7 +601,7 @@ int link_path_walk(const char * name, st
  			goto out_dput;
  
  		if (inode->i_op->follow_link) {
@@ -410,7 +312,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -565,7 +613,7 @@ int link_path_walk(const char * name, st
+@@ -565,7 +617,7 @@ int link_path_walk(const char * name, st
  			nd->dentry = dentry;
  		}
  		err = -ENOTDIR; 
@@ -419,7 +321,7 @@
  			break;
  		continue;
  		/* here ends the main loop */
-@@ -592,22 +640,22 @@ last_component:
+@@ -592,22 +644,22 @@ last_component:
  			if (err < 0)
  				break;
  		}
@@ -446,7 +348,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -621,7 +669,8 @@ last_component:
+@@ -621,7 +673,8 @@ last_component:
  			goto no_inode;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
@@ -456,11 +358,10 @@
  				break;
  		}
  		goto return_base;
-@@ -645,6 +694,23 @@ return_reval:
+@@ -645,6 +698,25 @@ return_reval:
  		 * Check the cached dentry for staleness.
  		 */
  		dentry = nd->dentry;
-+	revalidate_again:
 +		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
 +			err = -ESTALE;
 +			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
@@ -473,14 +374,17 @@
 +						  &dentry->d_name, 0, NULL);
 +				d_invalidate(dentry);
 +				dput(dentry);
-+				dentry = new;
-+				goto revalidate_again;
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
 +			}
 +		} else
  		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  			err = -ESTALE;
  			if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -658,15 +724,28 @@ out_dput:
+@@ -658,15 +730,28 @@ out_dput:
  		dput(dentry);
  		break;
  	}
@@ -510,7 +414,7 @@
  }
  
  /* SMP-safe */
-@@ -751,6 +830,17 @@ walk_init_root(const char *name, struct 
+@@ -751,6 +836,17 @@ walk_init_root(const char *name, struct 
  }
  
  /* SMP-safe */
@@ -528,15 +432,15 @@
  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
  {
  	int error = 0;
-@@ -765,6 +855,7 @@ int path_init(const char *name, unsigned
+@@ -765,6 +861,7 @@ int path_init(const char *name, unsigned
  {
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
-+	nd->it = NULL;
++	nd->intent = NULL;
  	if (*name=='/')
  		return walk_init_root(name,nd);
  	read_lock(&current->fs->lock);
-@@ -779,7 +870,8 @@ int path_init(const char *name, unsigned
+@@ -779,7 +876,8 @@ int path_init(const char *name, unsigned
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -546,7 +450,7 @@
  {
  	struct dentry * dentry;
  	struct inode *inode;
-@@ -802,13 +894,16 @@ struct dentry * lookup_hash(struct qstr 
+@@ -802,13 +900,16 @@ struct dentry * lookup_hash(struct qstr 
  			goto out;
  	}
  
@@ -564,7 +468,7 @@
  		dentry = inode->i_op->lookup(inode, new);
  		unlock_kernel();
  		if (!dentry)
-@@ -820,6 +915,12 @@ out:
+@@ -820,6 +921,12 @@ out:
  	return dentry;
  }
  
@@ -577,7 +481,7 @@
  /* SMP-safe */
  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
  {
-@@ -841,7 +942,7 @@ struct dentry * lookup_one_len(const cha
+@@ -841,7 +948,7 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -586,7 +490,7 @@
  access:
  	return ERR_PTR(-EACCES);
  }
-@@ -872,6 +973,23 @@ int __user_walk(const char *name, unsign
+@@ -872,6 +979,23 @@ int __user_walk(const char *name, unsign
  	return err;
  }
  
@@ -610,45 +514,47 @@
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -969,6 +1087,37 @@ static inline int lookup_flags(unsigned 
+@@ -969,7 +1093,8 @@ static inline int lookup_flags(unsigned 
  	return retval;
  }
  
+-int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
 +static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode,
 +			 struct lookup_intent *it)
-+{
-+	int error;
-+
-+	mode &= S_IALLUGO;
-+	mode |= S_IFREG;
-+
-+	down(&dir->i_zombie);
-+	error = may_create(dir, dentry);
-+	if (error)
-+		goto exit_lock;
-+
-+	error = -EACCES;	/* shouldn't it be ENOSYS? */
+ {
+ 	int error;
+ 
+@@ -982,12 +1107,15 @@ int vfs_create(struct inode *dir, struct
+ 		goto exit_lock;
+ 
+ 	error = -EACCES;	/* shouldn't it be ENOSYS? */
+-	if (!dir->i_op || !dir->i_op->create)
 +	if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it))
-+		goto exit_lock;
-+
-+	DQUOT_INIT(dir);
-+	lock_kernel();
+ 		goto exit_lock;
+ 
+ 	DQUOT_INIT(dir);
+ 	lock_kernel();
+-	error = dir->i_op->create(dir, dentry, mode);
 +	if (dir->i_op->create_it)
 +		error = dir->i_op->create_it(dir, dentry, mode, it);
 +	else
 +		error = dir->i_op->create(dir, dentry, mode);
-+	unlock_kernel();
-+exit_lock:
-+	up(&dir->i_zombie);
-+	if (!error)
-+		inode_dir_notify(dir, DN_CREATE);
-+	return error;
+ 	unlock_kernel();
+ exit_lock:
+ 	up(&dir->i_zombie);
+@@ -996,6 +1124,11 @@ exit_lock:
+ 	return error;
+ }
+ 
++int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
++{
++	return vfs_create_it(dir, dentry, mode, NULL);
 +}
 +
- int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
- {
- 	int error;
-@@ -1010,7 +1137,8 @@ exit_lock:
+ /*
+  *	open_namei()
+  *
+@@ -1010,7 +1143,8 @@ exit_lock:
   * for symlinks (where the permissions are checked later).
   * SMP-safe
   */
@@ -658,7 +564,14 @@
  {
  	int acc_mode, error = 0;
  	struct inode *inode;
-@@ -1024,7 +1152,7 @@ int open_namei(const char * pathname, in
+@@ -1020,11 +1154,14 @@ int open_namei(const char * pathname, in
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
++
+ 	/*
  	 * The simplest case - just a plain lookup.
  	 */
  	if (!(flag & O_CREAT)) {
@@ -667,18 +580,18 @@
  		if (error)
  			return error;
  		dentry = nd->dentry;
-@@ -1034,6 +1162,10 @@ int open_namei(const char * pathname, in
+@@ -1034,6 +1171,10 @@ int open_namei(const char * pathname, in
  	/*
  	 * Create - we need to know the parent.
  	 */
 +	if (it) {
-+		it->it_mode = mode;
++		it->it_create_mode = mode;
 +		it->it_op |= IT_CREAT;
 +	}
  	error = path_lookup(pathname, LOOKUP_PARENT, nd);
  	if (error)
  		return error;
-@@ -1049,7 +1181,7 @@ int open_namei(const char * pathname, in
+@@ -1049,7 +1190,7 @@ int open_namei(const char * pathname, in
  
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -687,11 +600,11 @@
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1058,10 +1190,11 @@ do_last:
+@@ -1058,10 +1199,11 @@ do_last:
  		goto exit;
  	}
  
-+	it->it_mode = mode;
++	it->it_create_mode = mode;
  	/* Negative dentry, just create the file */
  	if (!dentry->d_inode) {
 -		error = vfs_create(dir->d_inode, dentry,
@@ -701,7 +614,7 @@
  		up(&dir->d_inode->i_sem);
  		dput(nd->dentry);
  		nd->dentry = dentry;
-@@ -1086,7 +1219,7 @@ do_last:
+@@ -1086,7 +1228,7 @@ do_last:
  		error = -ELOOP;
  		if (flag & O_NOFOLLOW)
  			goto exit_dput;
@@ -710,7 +623,7 @@
  	}
  	error = -ENOENT;
  	if (!dentry->d_inode)
-@@ -1165,7 +1298,7 @@ ok:
+@@ -1165,7 +1307,7 @@ ok:
  		if (!error) {
  			DQUOT_INIT(inode);
  			
@@ -719,7 +632,7 @@
  		}
  		put_write_access(inode);
  		if (error)
-@@ -1177,8 +1310,10 @@ ok:
+@@ -1177,8 +1319,10 @@ ok:
  	return 0;
  
  exit_dput:
@@ -730,15 +643,15 @@
  	path_release(nd);
  	return error;
  
-@@ -1197,7 +1332,16 @@ do_link:
+@@ -1197,7 +1341,16 @@ do_link:
  	 * are done. Procfs-like symlinks just set LAST_BIND.
  	 */
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 +	if (error) {
 +		intent_release(it);
-+	} else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
++	} else if (it != NULL && !(it->d.lustre.it_int_flags & IT_FL_FOLLOWED)) {
 +		/* vfs_follow_link was never called */
 +		intent_release(it);
 +		path_release(nd);
@@ -747,7 +660,7 @@
  	dput(dentry);
  	if (error)
  		return error;
-@@ -1219,13 +1363,20 @@ do_link:
+@@ -1219,13 +1372,20 @@ do_link:
  	}
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -770,7 +683,7 @@
  {
  	struct dentry *dentry;
  
-@@ -1233,7 +1384,7 @@ static struct dentry *lookup_create(stru
+@@ -1233,7 +1393,7 @@ static struct dentry *lookup_create(stru
  	dentry = ERR_PTR(-EEXIST);
  	if (nd->last_type != LAST_NORM)
  		goto fail;
@@ -779,7 +692,7 @@
  	if (IS_ERR(dentry))
  		goto fail;
  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1289,7 +1440,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1289,7 +1449,16 @@ asmlinkage long sys_mknod(const char * f
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -797,7 +710,7 @@
  	error = PTR_ERR(dentry);
  
  	mode &= ~current->fs->umask;
-@@ -1310,6 +1470,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1310,6 +1479,7 @@ asmlinkage long sys_mknod(const char * f
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -805,7 +718,7 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1357,7 +1518,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1357,7 +1527,14 @@ asmlinkage long sys_mkdir(const char * p
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -821,7 +734,7 @@
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
  			error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1365,6 +1533,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1365,6 +1542,7 @@ asmlinkage long sys_mkdir(const char * p
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -829,7 +742,7 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1465,8 +1634,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1465,8 +1643,16 @@ asmlinkage long sys_rmdir(const char * p
  			error = -EBUSY;
  			goto exit1;
  	}
@@ -847,7 +760,7 @@
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1524,8 +1701,15 @@ asmlinkage long sys_unlink(const char * 
+@@ -1524,8 +1710,15 @@ asmlinkage long sys_unlink(const char * 
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
@@ -864,7 +777,7 @@
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
-@@ -1592,15 +1776,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1592,15 +1785,23 @@ asmlinkage long sys_symlink(const char *
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -890,7 +803,7 @@
  		putname(to);
  	}
  	putname(from);
-@@ -1676,7 +1868,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1676,7 +1877,14 @@ asmlinkage long sys_link(const char * ol
  		error = -EXDEV;
  		if (old_nd.mnt != nd.mnt)
  			goto out_release;
@@ -906,7 +819,7 @@
  		error = PTR_ERR(new_dentry);
  		if (!IS_ERR(new_dentry)) {
  			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1720,7 +1919,7 @@ exit:
+@@ -1720,7 +1928,7 @@ exit:
   *	   locking].
   */
  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -915,7 +828,7 @@
  {
  	int error;
  	struct inode *target;
-@@ -1799,7 +1998,7 @@ out_unlock:
+@@ -1799,7 +2007,7 @@ out_unlock:
  }
  
  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
@@ -924,7 +837,7 @@
  {
  	int error;
  
-@@ -1887,9 +2086,18 @@ static inline int do_rename(const char *
+@@ -1887,9 +2095,18 @@ static inline int do_rename(const char *
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
  
@@ -944,7 +857,7 @@
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
-@@ -1905,16 +2113,16 @@ static inline int do_rename(const char *
+@@ -1905,16 +2122,16 @@ static inline int do_rename(const char *
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
@@ -963,7 +876,7 @@
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
-@@ -1965,20 +2173,28 @@ out:
+@@ -1965,20 +2182,28 @@ out:
  }
  
  static inline int
@@ -977,11 +890,11 @@
  		goto fail;
  
 +	if (it == NULL)
-+		it = nd->it;
-+	else if (it != nd->it)
-+		printk("it != nd->it: tell phil@clusterfs.com\n");
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
 +	if (it != NULL)
-+		it->it_int_flags |= IT_FL_FOLLOWED;
++		it->d.lustre.it_int_flags |= IT_FL_FOLLOWED;
 +
  	if (*link == '/') {
  		path_release(nd);
@@ -994,7 +907,7 @@
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
  		return res;
-@@ -2002,7 +2218,13 @@ fail:
+@@ -2002,7 +2227,13 @@ fail:
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
@@ -1009,7 +922,7 @@
  }
  
  /* get the link contents into pagecache */
-@@ -2044,7 +2266,7 @@ int page_follow_link(struct dentry *dent
+@@ -2044,7 +2275,7 @@ int page_follow_link(struct dentry *dent
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
@@ -1018,8 +931,123 @@
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
---- linux-2.4.20/fs/open.c~vfs_intent-2.4.20-rh	2003-07-17 08:32:45.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/open.c	2003-07-17 08:35:22.000000000 -0700
+--- linux-2.4.20-rh-20.9/fs/namespace.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/namespace.c	2003-09-14 17:34:53.000000000 +0400
+@@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
+ {
+ 	old_nd->dentry = mnt->mnt_mountpoint;
+ 	old_nd->mnt = mnt->mnt_parent;
++	UNPIN(old_nd->dentry, old_nd->mnt, 1);
+ 	mnt->mnt_parent = mnt;
+ 	mnt->mnt_mountpoint = mnt->mnt_root;
+ 	list_del_init(&mnt->mnt_child);
+@@ -110,6 +111,7 @@ static void attach_mnt(struct vfsmount *
+ {
+ 	mnt->mnt_parent = mntget(nd->mnt);
+ 	mnt->mnt_mountpoint = dget(nd->dentry);
++	PIN(nd->dentry, nd->mnt, 1);
+ 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+ 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+ 	nd->dentry->d_mounted++;
+@@ -485,14 +487,17 @@ static int do_loopback(struct nameidata 
+ {
+ 	struct nameidata old_nd;
+ 	struct vfsmount *mnt = NULL;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int err = mount_is_safe(nd);
+ 	if (err)
+ 		return err;
+ 	if (!old_name || !*old_name)
+ 		return -EINVAL;
+-	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
+-	if (err)
++	err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it);
++	if (err) {
++		intent_release(&it);
+ 		return err;
++	}
+ 
+ 	down_write(&current->namespace->sem);
+ 	err = -EINVAL;
+@@ -515,6 +520,7 @@ static int do_loopback(struct nameidata 
+ 	}
+ 
+ 	up_write(&current->namespace->sem);
++	intent_release(&it);
+ 	path_release(&old_nd);
+ 	return err;
+ }
+@@ -698,6 +704,7 @@ long do_mount(char * dev_name, char * di
+ 		  unsigned long flags, void *data_page)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int retval = 0;
+ 	int mnt_flags = 0;
+ 
+@@ -722,10 +729,11 @@ long do_mount(char * dev_name, char * di
+ 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
+ 
+ 	/* ... and get the mountpoint */
+-	retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
+-	if (retval)
++	retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
++	if (retval) {
++		intent_release(&it);
+ 		return retval;
+-
++	}
+ 	if (flags & MS_REMOUNT)
+ 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+ 				    data_page);
+@@ -736,6 +744,8 @@ long do_mount(char * dev_name, char * di
+ 	else
+ 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+ 				      dev_name, data_page);
++
++	intent_release(&it);
+ 	path_release(&nd);
+ 	return retval;
+ }
+@@ -901,6 +911,8 @@ asmlinkage long sys_pivot_root(const cha
+ {
+ 	struct vfsmount *tmp;
+ 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
++	struct lookup_intent new_it = { .it_op = IT_GETATTR };
++	struct lookup_intent old_it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+ 	if (!capable(CAP_SYS_ADMIN))
+@@ -908,14 +920,14 @@ asmlinkage long sys_pivot_root(const cha
+ 
+ 	lock_kernel();
+ 
+-	error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
++	error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it);
+ 	if (error)
+ 		goto out0;
+ 	error = -EINVAL;
+ 	if (!check_mnt(new_nd.mnt))
+ 		goto out1;
+ 
+-	error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
++	error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it);
+ 	if (error)
+ 		goto out1;
+ 
+@@ -970,8 +982,10 @@ out2:
+ 	up(&old_nd.dentry->d_inode->i_zombie);
+ 	up_write(&current->namespace->sem);
+ 	path_release(&user_nd);
++	intent_release(&old_it);
+ 	path_release(&old_nd);
+ out1:
++	intent_release(&new_it);
+ 	path_release(&new_nd);
+ out0:
+ 	unlock_kernel();
+--- linux-2.4.20-rh-20.9/fs/open.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:25.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/open.c	2003-09-14 17:34:53.000000000 +0400
 @@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
@@ -1199,16 +1227,14 @@
  		path_release(&nd);
  	}
  
-@@ -385,8 +430,11 @@ asmlinkage long sys_chdir(const char * f
+@@ -385,8 +430,9 @@ asmlinkage long sys_chdir(const char * f
  {
  	int error;
  	struct nameidata nd;
 +	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
-+	error = __user_walk_it(filename,
-+			       LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
-+			       &nd, &it);
++	error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
  	if (error)
  		goto out;
  
@@ -1229,11 +1255,11 @@
 -	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 -		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
 +	error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-+		      	       LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
++		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -454,6 +502,7 @@ asmlinkage long sys_chroot(const char * 
+@@ -454,39 +502,56 @@ asmlinkage long sys_chroot(const char * 
  	set_fs_altroot();
  	error = 0;
  dput_and_out:
@@ -1241,26 +1267,102 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -508,6 +557,18 @@ asmlinkage long sys_chmod(const char * f
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
  
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
 +	if (inode->i_op->setattr_raw) {
-+		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
 +		newattrs.ia_mode = mode;
 +		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 +		newattrs.ia_valid |= ATTR_RAW;
-+		error = op->setattr_raw(inode, &newattrs);
++		err = inode->i_op->setattr_raw(inode, &newattrs);
 +		/* the file system wants to use normal vfs path now */
-+		if (error != -EOPNOTSUPP)
-+			goto dput_and_out;
++		if (err != -EOPNOTSUPP)
++			goto out;
 +	}
-+
- 	error = -EPERM;
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -538,6 +599,20 @@ static int chown_common(struct dentry * 
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -495,30 +560,14 @@ out:
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+-
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
++	error = chmod_common(nd.dentry, mode);
+ 
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -538,6 +587,20 @@ static int chown_common(struct dentry * 
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto out;
@@ -1281,19 +1383,19 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
-@@ -642,8 +717,9 @@ struct file *filp_open(const char * file
+@@ -642,8 +705,9 @@ struct file *filp_open(const char * file
  {
  	int namei_flags, error;
  	struct nameidata nd;
 -	
 -	flags &= ~O_DIRECT;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
++	struct lookup_intent it = { .it_op = IT_OPEN };
 +
 +	//flags &= ~O_DIRECT;
  
  	namei_flags = flags;
  	if ((namei_flags+1) & O_ACCMODE)
-@@ -651,14 +727,15 @@ struct file *filp_open(const char * file
+@@ -651,14 +715,15 @@ struct file *filp_open(const char * file
  	if (namei_flags & O_TRUNC)
  		namei_flags |= 2;
  
@@ -1314,7 +1416,7 @@
  {
  	struct file * f;
  	struct inode *inode;
-@@ -695,12 +772,15 @@ struct file *dentry_open(struct dentry *
+@@ -695,12 +760,15 @@ struct file *dentry_open(struct dentry *
  	}
  
  	if (f->f_op && f->f_op->open) {
@@ -1330,7 +1432,7 @@
  	return f;
  
  cleanup_all:
-@@ -715,11 +795,17 @@ cleanup_all:
+@@ -715,11 +783,17 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
@@ -1348,21 +1450,21 @@
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux-2.4.20/fs/proc/base.c~vfs_intent-2.4.20-rh	2003-07-17 08:33:05.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/proc/base.c	2003-07-17 08:35:22.000000000 -0700
-@@ -464,6 +464,9 @@ static int proc_pid_follow_link(struct d
+--- linux-2.4.20-rh-20.9/fs/proc/base.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/proc/base.c	2003-09-14 17:34:53.000000000 +0400
+@@ -494,6 +494,9 @@ static int proc_pid_follow_link(struct d
  
  	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
  	nd->last_type = LAST_BIND;
 +
-+	if (nd->it != NULL)
-+		nd->it->it_int_flags |= IT_FL_FOLLOWED;
++	if (nd->intent != NULL)
++		nd->intent->d.lustre.it_int_flags |= IT_FL_FOLLOWED;
  out:
  	return error;
  }
---- linux-2.4.20/fs/stat.c~vfs_intent-2.4.20-rh	2003-07-17 08:33:05.000000000 -0700
-+++ linux-2.4.20-mmonroe/fs/stat.c	2003-07-17 08:51:33.000000000 -0700
-@@ -17,10 +17,12 @@
+--- linux-2.4.20-rh-20.9/fs/stat.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/fs/stat.c	2003-09-14 17:35:10.000000000 +0400
+@@ -17,10 +17,14 @@
   * Revalidate the inode. This is required for proper NFS attribute caching.
   */
  static __inline__ int
@@ -1371,13 +1473,15 @@
  {
  	struct inode * inode = dentry->d_inode;
 -	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
 +	if (inode->i_op && inode->i_op->revalidate_it)
 +		return inode->i_op->revalidate_it(dentry, it);
 +	else if (inode->i_op && inode->i_op->revalidate)
  		return inode->i_op->revalidate(dentry);
  	return 0;
  }
-@@ -32,13 +34,13 @@ static inline nlink_t user_nlink(struct 
+@@ -32,13 +36,13 @@ static inline nlink_t user_nlink(struct 
  	return inode->i_nlink;
  }
  
@@ -1393,7 +1497,7 @@
  	if (res)
  		return res;
  
-@@ -111,10 +113,12 @@ int vfs_stat(char *name, struct kstat *s
+@@ -111,10 +115,12 @@ int vfs_stat(char *name, struct kstat *s
  {
  	struct nameidata nd;
  	int error;
@@ -1408,7 +1512,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -124,10 +128,12 @@ int vfs_lstat(char *name, struct kstat *
+@@ -124,10 +130,12 @@ int vfs_lstat(char *name, struct kstat *
  {
  	struct nameidata nd;
  	int error;
@@ -1423,7 +1527,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -139,7 +145,7 @@ int vfs_fstat(unsigned int fd, struct ks
+@@ -139,7 +147,7 @@ int vfs_fstat(unsigned int fd, struct ks
  	int error = -EBADF;
  
  	if (f) {
@@ -1432,7 +1536,7 @@
  		fput(f);
  	}
  	return error;
-@@ -286,7 +292,7 @@ asmlinkage long sys_readlink(const char 
+@@ -286,7 +294,7 @@ asmlinkage long sys_readlink(const char 
  
  		error = -EINVAL;
  		if (inode->i_op && inode->i_op->readlink &&
@@ -1441,9 +1545,9 @@
  			UPDATE_ATIME(inode);
  			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
  		}
---- linux-2.4.20/include/linux/dcache.h~vfs_intent-2.4.20-rh	2003-07-17 08:32:48.000000000 -0700
-+++ linux-2.4.20-mmonroe/include/linux/dcache.h	2003-07-17 08:35:22.000000000 -0700
-@@ -6,6 +6,45 @@
+--- linux-2.4.20-rh-20.9/include/linux/dcache.h~vfs_intent-2.4.20-rh	2003-09-13 19:34:28.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/include/linux/dcache.h	2003-09-14 17:34:53.000000000 +0400
+@@ -6,6 +6,51 @@
  #include <asm/atomic.h>
  #include <linux/mount.h>
  #include <linux/kernel.h>
@@ -1464,18 +1568,24 @@
 +
 +#define INTENT_MAGIC 0x19620323
 +
-+struct lookup_intent {
-+	int it_op;
-+	void (*it_op_release)(struct lookup_intent *);
-+	int it_magic;
-+	int it_mode;
-+	int it_flags;
-+	int it_disposition;
-+	int it_status;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
 +	int it_int_flags;
-+	__u64 it_lock_handle[2];
-+	int it_lock_mode;
-+	void *it_data;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op, int flags)
@@ -1489,7 +1599,7 @@
  
  /*
   * linux/include/linux/dcache.h
-@@ -96,8 +135,22 @@ struct dentry_operations {
+@@ -96,8 +141,22 @@ struct dentry_operations {
  	int (*d_delete)(struct dentry *);
  	void (*d_release)(struct dentry *);
  	void (*d_iput)(struct dentry *, struct inode *);
@@ -1512,7 +1622,7 @@
  /* the dentry parameter passed to d_hash and d_compare is the parent
   * directory of the entries to be compared. It is used in case these
   * functions need any directory specific information for determining
-@@ -129,6 +182,7 @@ d_iput:		no		no		yes
+@@ -129,6 +188,7 @@ d_iput:		no		no		yes
  					 * s_nfsd_free_path semaphore will be down
  					 */
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
@@ -1520,19 +1630,35 @@
  
  extern spinlock_t dcache_lock;
  
---- linux-2.4.20/include/linux/fs.h~vfs_intent-2.4.20-rh	2003-07-17 08:34:44.000000000 -0700
-+++ linux-2.4.20-mmonroe/include/linux/fs.h	2003-07-17 08:35:22.000000000 -0700
-@@ -337,6 +337,9 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.20-rh-20.9/include/linux/fs.h~vfs_intent-2.4.20-rh	2003-09-14 17:34:50.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/include/linux/fs.h	2003-09-14 17:34:53.000000000 +0400
+@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -338,6 +339,9 @@ extern void set_bh_page(struct buffer_he
  #define ATTR_MTIME_SET	256
  #define ATTR_FORCE	512	/* Not a change, but a change it */
  #define ATTR_ATTR_FLAG	1024
 +#define ATTR_RAW	0x0800	/* file system, not vfs will massage attrs */
 +#define ATTR_FROM_OPEN	0x1000	/* called from open path, ie O_TRUNC */
-+#define ATTR_CTIME_SET	0x2000
++#define ATTR_CTIME_SET 0x2000
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -574,6 +577,7 @@ struct file {
+@@ -473,6 +477,7 @@ struct inode {
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -575,6 +580,7 @@ struct file {
  
  	/* needed for tty driver, and maybe others */
  	void			*private_data;
@@ -1540,15 +1666,15 @@
  
  	/* preallocated helper kiobuf to speedup O_DIRECT */
  	struct kiobuf		*f_iobuf;
-@@ -701,6 +705,7 @@ struct nameidata {
+@@ -702,6 +708,7 @@ struct nameidata {
  	struct qstr last;
  	unsigned int flags;
  	int last_type;
-+	struct lookup_intent *it;
++	struct lookup_intent *intent;
  };
  
  /*
-@@ -821,7 +826,8 @@ extern int vfs_symlink(struct inode *, s
+@@ -822,7 +829,8 @@ extern int vfs_symlink(struct inode *, s
  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
  extern int vfs_rmdir(struct inode *, struct dentry *);
  extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1558,7 +1684,7 @@
  
  /*
   * File types
-@@ -881,21 +887,32 @@ struct file_operations {
+@@ -882,21 +890,32 @@ struct file_operations {
  
  struct inode_operations {
  	int (*create) (struct inode *,struct dentry *,int);
@@ -1591,7 +1717,7 @@
  	int (*getattr) (struct dentry *, struct iattr *);
  	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
  	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1091,10 +1108,14 @@ static inline int get_lease(struct inode
+@@ -1092,10 +1111,14 @@ static inline int get_lease(struct inode
  
  asmlinkage long sys_open(const char *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
@@ -1607,7 +1733,7 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char *);
  
-@@ -1385,6 +1406,7 @@ typedef int (*read_actor_t)(read_descrip
+@@ -1386,6 +1409,7 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
@@ -1615,7 +1741,7 @@
  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
  extern int FASTCALL(path_walk(const char *, struct nameidata *));
  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1396,6 +1418,8 @@ extern struct dentry * lookup_one_len(co
+@@ -1397,6 +1421,8 @@ extern struct dentry * lookup_one_len(co
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
  #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
@@ -1624,7 +1750,7 @@
  
  extern void inode_init_once(struct inode *);
  extern void iput(struct inode *);
-@@ -1497,6 +1521,8 @@ extern struct file_operations generic_ro
+@@ -1504,6 +1530,8 @@ extern struct file_operations generic_ro
  
  extern int vfs_readlink(struct dentry *, char *, int, const char *);
  extern int vfs_follow_link(struct nameidata *, const char *);
@@ -1633,8 +1759,36 @@
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.20/kernel/ksyms.c~vfs_intent-2.4.20-rh	2003-07-17 08:34:45.000000000 -0700
-+++ linux-2.4.20-mmonroe/kernel/ksyms.c	2003-07-17 08:35:22.000000000 -0700
+--- linux-2.4.20-rh-20.9/include/linux/fs_struct.h~vfs_intent-2.4.20-rh	2003-09-13 19:34:19.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/include/linux/fs_struct.h	2003-09-14 17:34:53.000000000 +0400
+@@ -37,10 +37,12 @@ static inline void set_fs_root(struct fs
+ 	write_lock(&fs->lock);
+ 	old_root = fs->root;
+ 	old_rootmnt = fs->rootmnt;
++	PIN(dentry, mnt, 1);
+ 	fs->rootmnt = mntget(mnt);
+ 	fs->root = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_root) {
++		UNPIN(old_root, old_rootmnt, 1);
+ 		dput(old_root);
+ 		mntput(old_rootmnt);
+ 	}
+@@ -60,10 +62,12 @@ static inline void set_fs_pwd(struct fs_
+ 	write_lock(&fs->lock);
+ 	old_pwd = fs->pwd;
+ 	old_pwdmnt = fs->pwdmnt;
++	PIN(dentry, mnt, 0);
+ 	fs->pwdmnt = mntget(mnt);
+ 	fs->pwd = dget(dentry);
+ 	write_unlock(&fs->lock);
+ 	if (old_pwd) {
++		UNPIN(old_pwd, old_pwdmnt, 0);
+ 		dput(old_pwd);
+ 		mntput(old_pwdmnt);
+ 	}
+--- linux-2.4.20-rh-20.9/kernel/ksyms.c~vfs_intent-2.4.20-rh	2003-09-14 17:34:51.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/kernel/ksyms.c	2003-09-14 17:34:53.000000000 +0400
 @@ -298,6 +298,7 @@ EXPORT_SYMBOL(read_cache_page);
  EXPORT_SYMBOL(set_page_dirty);
  EXPORT_SYMBOL(vfs_readlink);
@@ -1643,5 +1797,38 @@
  EXPORT_SYMBOL(page_readlink);
  EXPORT_SYMBOL(page_follow_link);
  EXPORT_SYMBOL(page_symlink_inode_operations);
+--- linux-2.4.20-rh-20.9/kernel/fork.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/kernel/fork.c	2003-09-14 17:34:53.000000000 +0400
+@@ -440,10 +440,13 @@ static inline struct fs_struct *__copy_f
+ 		fs->umask = old->umask;
+ 		read_lock(&old->lock);
+ 		fs->rootmnt = mntget(old->rootmnt);
++		PIN(old->pwd, old->pwdmnt, 0);
++		PIN(old->root, old->rootmnt, 1);
+ 		fs->root = dget(old->root);
+ 		fs->pwdmnt = mntget(old->pwdmnt);
+ 		fs->pwd = dget(old->pwd);
+ 		if (old->altroot) {
++			PIN(old->altroot, old->altrootmnt, 1);
+ 			fs->altrootmnt = mntget(old->altrootmnt);
+ 			fs->altroot = dget(old->altroot);
+ 		} else {
+--- linux-2.4.20-rh-20.9/kernel/exit.c~vfs_intent-2.4.20-rh	2003-09-13 19:34:35.000000000 +0400
++++ linux-2.4.20-rh-20.9-alexey/kernel/exit.c	2003-09-14 17:34:53.000000000 +0400
+@@ -345,11 +345,14 @@ static inline void __put_fs_struct(struc
+ {
+ 	/* No need to hold fs->lock if we are killing it */
+ 	if (atomic_dec_and_test(&fs->count)) {
++		UNPIN(fs->pwd, fs->pwdmnt, 0);
++		UNPIN(fs->root, fs->rootmnt, 1);
+ 		dput(fs->root);
+ 		mntput(fs->rootmnt);
+ 		dput(fs->pwd);
+ 		mntput(fs->pwdmnt);
+ 		if (fs->altroot) {
++			UNPIN(fs->altroot, fs->altrootmnt, 1);
+ 			dput(fs->altroot);
+ 			mntput(fs->altrootmnt);
+ 		}
 
 _
diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch
index e5228968d131a73b6ab9600d5b89fd518ba993eb..3eca972e5fcbc994139a1c52ab9280556d8eb55a 100644
--- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch
@@ -1,32 +1,32 @@
  fs/dcache.c               |   19 ++
- fs/exec.c                 |   15 +-
- fs/namei.c                |  329 ++++++++++++++++++++++++++++++++++++++--------
- fs/namespace.c            |   30 +++-
- fs/open.c                 |  128 +++++++++++++++--
- fs/proc/base.c            |    3 
- fs/stat.c                 |   50 ++++--
- include/linux/dcache.h    |   53 +++++++
- include/linux/fs.h        |   29 +++-
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  295 +++++++++++++++++++++++++++++++++++++++-------
+ fs/namespace.c            |   28 +++-
+ fs/open.c                 |  172 +++++++++++++++++++-------
+ fs/stat.c                 |   52 +++++---
+ include/linux/dcache.h    |   60 +++++++++
+ include/linux/fs.h        |   32 ++++
  include/linux/fs_struct.h |    4 
  kernel/exit.c             |    3 
  kernel/fork.c             |    3 
  kernel/ksyms.c            |    1 
- 13 files changed, 560 insertions(+), 107 deletions(-)
+ 12 files changed, 558 insertions(+), 128 deletions(-)
 
---- linux-2.4.20-ad/fs/exec.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/fs/exec.c	2003-07-07 15:13:53.000000000 -0600
-@@ -107,8 +107,9 @@ asmlinkage long sys_uselib(const char * 
+--- linux-2.4.20-vanilla/fs/exec.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/exec.c	2003-09-17 21:05:04.000000000 +0400
+@@ -107,8 +107,10 @@ asmlinkage long sys_uselib(const char * 
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	error = user_path_walk(library, &nd);
 +	error = user_path_walk_it(library, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -120,7 +121,8 @@ asmlinkage long sys_uselib(const char * 
+@@ -120,7 +122,8 @@ asmlinkage long sys_uselib(const char * 
  	if (error)
  		goto exit;
  
@@ -36,18 +36,19 @@
  	error = PTR_ERR(file);
  	if (IS_ERR(file))
  		goto out;
-@@ -363,8 +365,9 @@ struct file *open_exec(const char *name)
+@@ -363,8 +366,10 @@ struct file *open_exec(const char *name)
  	struct inode *inode;
  	struct file *file;
  	int err = 0;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 +	err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
  	file = ERR_PTR(err);
  	if (!err) {
  		inode = nd.dentry->d_inode;
-@@ -376,7 +379,8 @@ struct file *open_exec(const char *name)
+@@ -376,7 +381,8 @@ struct file *open_exec(const char *name)
  				err = -EACCES;
  			file = ERR_PTR(err);
  			if (!err) {
@@ -57,7 +58,7 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
-@@ -388,6 +392,7 @@ out:
+@@ -388,6 +394,7 @@ out:
  				return file;
  			}
  		}
@@ -65,7 +66,7 @@
  		path_release(&nd);
  	}
  	goto out;
-@@ -989,7 +994,7 @@ int do_coredump(long signr, struct pt_re
+@@ -989,7 +996,7 @@ int do_coredump(long signr, struct pt_re
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
@@ -74,8 +75,8 @@
  		goto close_fail;
  
  	retval = binfmt->core_dump(signr, regs, file);
---- linux-2.4.20-ad/fs/dcache.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/fs/dcache.c	2003-07-09 01:46:27.000000000 -0600
+--- linux-2.4.20-vanilla/fs/dcache.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/dcache.c	2003-09-17 21:05:04.000000000 +0400
 @@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
  		spin_unlock(&dcache_lock);
  		return 0;
@@ -113,8 +114,8 @@
  }
  
  #define do_switch(x,y) do { \
---- linux-2.4.20-ad/fs/namespace.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/fs/namespace.c	2003-07-07 15:13:53.000000000 -0600
+--- linux-2.4.20-vanilla/fs/namespace.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/namespace.c	2003-09-17 21:05:04.000000000 +0400
 @@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
  {
  	old_nd->dentry = mnt->mnt_mountpoint;
@@ -159,16 +160,14 @@
  	path_release(&old_nd);
  	return err;
  }
-@@ -698,7 +704,8 @@ long do_mount(char * dev_name, char * di
+@@ -698,6 +704,7 @@ long do_mount(char * dev_name, char * di
  		  unsigned long flags, void *data_page)
  {
  	struct nameidata nd;
--	int retval = 0;
 +	struct lookup_intent it = { .it_op = IT_GETATTR };
-+	int retval = 0;
+ 	int retval = 0;
  	int mnt_flags = 0;
  
- 	/* Discard magic */
 @@ -722,10 +729,11 @@ long do_mount(char * dev_name, char * di
  	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
  
@@ -230,8 +229,8 @@
  	path_release(&new_nd);
  out0:
  	unlock_kernel();
---- linux-2.4.20-ad/fs/namei.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/fs/namei.c	2003-07-08 13:53:48.000000000 -0600
+--- linux-2.4.20-vanilla/fs/namei.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:12.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/namei.c	2003-09-17 21:05:04.000000000 +0400
 @@ -94,6 +94,13 @@
   * XEmacs seems to be relying on it...
   */
@@ -267,7 +266,7 @@
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
  			dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
   * make sure that nobody added the entry to the dcache in the meantime..
   * SMP-safe
   */
@@ -277,13 +276,14 @@
  {
  	struct dentry * result;
  	struct inode *dir = parent->d_inode;
++	int counter = 0;
  
 +again:
-+
++	counter++;
  	down(&dir->i_sem);
  	/*
  	 * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
  		result = ERR_PTR(-ENOMEM);
  		if (dentry) {
  			lock_kernel();
@@ -293,7 +293,7 @@
  			result = dir->i_op->lookup(dir, dentry);
  			unlock_kernel();
  			if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
  			dput(result);
  			result = ERR_PTR(-ENOENT);
  		}
@@ -301,12 +301,15 @@
 +		if (!result->d_op->d_revalidate_it(result, flags, it) &&
 +		    !d_invalidate(result)) {
 +			dput(result);
-+			goto again;
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
 +		}
  	}
  	return result;
  }
-@@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
+@@ -332,7 +364,8 @@ static struct dentry * real_lookup(struc
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups. 
   */
@@ -316,19 +319,12 @@
  {
  	int err;
  	if (current->link_count >= 5)
-@@ -346,10 +375,18 @@ static inline int do_follow_link(struct 
+@@ -346,10 +379,12 @@ static inline int do_follow_link(struct 
  	current->link_count++;
  	current->total_link_count++;
  	UPDATE_ATIME(dentry->d_inode);
--	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	nd->it = it;
-+	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
-+		intent_release(it);
-+		path_release(nd);
-+		err = -ENOLINK;
-+	}
++	nd->intent = it;
+ 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
  	current->link_count--;
  	return err;
  loop:
@@ -336,53 +332,7 @@
  	path_release(nd);
  	return -ELOOP;
  }
-@@ -379,15 +416,26 @@ int follow_up(struct vfsmount **mnt, str
- 	return __follow_up(mnt, dentry);
- }
- 
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+				struct lookup_intent *it)
- {
- 	struct vfsmount *mounted;
- 
- 	spin_lock(&dcache_lock);
- 	mounted = lookup_mnt(*mnt, *dentry);
- 	if (mounted) {
-+		int opc = 0, mode = 0;
- 		*mnt = mntget(mounted);
- 		spin_unlock(&dcache_lock);
-+		if (it) {
-+			opc = it->it_op;
-+			mode = it->it_mode;
-+		}
-+		intent_release(it);
-+		if (it) {
-+			it->it_op = opc;
-+			it->it_mode = mode;
-+		}
- 		dput(*dentry);
- 		mntput(mounted->mnt_parent);
- 		*dentry = dget(mounted->mnt_root);
-@@ -399,7 +447,7 @@ static inline int __follow_down(struct v
- 
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--	return __follow_down(mnt,dentry);
-+	return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -435,7 +483,7 @@ static inline void follow_dotdot(struct 
- 		mntput(nd->mnt);
- 		nd->mnt = parent;
- 	}
--	while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+	while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
- 		;
- }
- 
-@@ -447,7 +495,8 @@ static inline void follow_dotdot(struct 
+@@ -447,7 +482,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
   */
@@ -392,7 +342,7 @@
  {
  	struct dentry *dentry;
  	struct inode *inode;
-@@ -520,15 +569,15 @@ int link_path_walk(const char * name, st
+@@ -520,9 +556,9 @@ int link_path_walk(const char * name, st
  				break;
  		}
  		/* This does the actual lookups.. */
@@ -404,25 +354,16 @@
  			err = PTR_ERR(dentry);
  			if (IS_ERR(dentry))
  				break;
- 		}
- 		/* Check mountpoints.. */
--		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
- 			;
- 
- 		err = -ENOENT;
-@@ -539,8 +588,8 @@ int link_path_walk(const char * name, st
- 		if (!inode->i_op)
+@@ -540,7 +576,7 @@ int link_path_walk(const char * name, st
  			goto out_dput;
  
--		if (inode->i_op->follow_link) {
+ 		if (inode->i_op->follow_link) {
 -			err = do_follow_link(dentry, nd);
-+		if (inode->i_op->follow_link) {
 +			err = do_follow_link(dentry, nd, NULL);
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -556,7 +605,7 @@ int link_path_walk(const char * name, st
+@@ -556,7 +592,7 @@ int link_path_walk(const char * name, st
  			nd->dentry = dentry;
  		}
  		err = -ENOTDIR; 
@@ -431,7 +372,7 @@
  			break;
  		continue;
  		/* here ends the main loop */
-@@ -583,19 +632,19 @@ last_component:
+@@ -583,9 +619,9 @@ last_component:
  			if (err < 0)
  				break;
  		}
@@ -443,10 +384,7 @@
  			err = PTR_ERR(dentry);
  			if (IS_ERR(dentry))
  				break;
- 		}
--		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
- 			;
+@@ -595,7 +631,7 @@ last_component:
  		inode = dentry->d_inode;
  		if ((lookup_flags & LOOKUP_FOLLOW)
  		    && inode && inode->i_op && inode->i_op->follow_link) {
@@ -455,7 +393,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -609,7 +658,8 @@ last_component:
+@@ -609,7 +645,8 @@ last_component:
  			goto no_inode;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
@@ -465,11 +403,10 @@
  				break;
  		}
  		goto return_base;
-@@ -633,6 +683,23 @@ return_reval:
+@@ -633,6 +670,25 @@ return_reval:
  		 * Check the cached dentry for staleness.
  		 */
  		dentry = nd->dentry;
-+	revalidate_again:
 +		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
 +			err = -ESTALE;
 +			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
@@ -482,14 +419,17 @@
 +						  &dentry->d_name, 0, NULL);
 +				d_invalidate(dentry);
 +				dput(dentry);
-+				dentry = new;
-+				goto revalidate_again;
++                                if (IS_ERR(new)) { 
++                                        err = PTR_ERR(new);
++                                        break;
++                                }
++                                nd->dentry = new;
 +			}
 +		} else
  		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  			err = -ESTALE;
  			if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -646,15 +713,28 @@ out_dput:
+@@ -646,15 +702,28 @@ out_dput:
  		dput(dentry);
  		break;
  	}
@@ -519,7 +459,7 @@
  }
  
  /* SMP-safe */
-@@ -739,6 +819,17 @@ walk_init_root(const char *name, struct 
+@@ -739,6 +808,17 @@ walk_init_root(const char *name, struct 
  }
  
  /* SMP-safe */
@@ -537,15 +477,15 @@
  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
  {
  	int error = 0;
-@@ -753,6 +844,7 @@ int path_init(const char *name, unsigned
+@@ -753,6 +833,7 @@ int path_init(const char *name, unsigned
  {
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
-+	nd->it = NULL;
++	nd->intent = NULL;
  	if (*name=='/')
  		return walk_init_root(name,nd);
  	read_lock(&current->fs->lock);
-@@ -767,7 +859,8 @@ int path_init(const char *name, unsigned
+@@ -767,7 +848,8 @@ int path_init(const char *name, unsigned
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -555,7 +495,7 @@
  {
  	struct dentry * dentry;
  	struct inode *inode;
-@@ -790,13 +883,16 @@ struct dentry * lookup_hash(struct qstr 
+@@ -790,13 +872,16 @@ struct dentry * lookup_hash(struct qstr 
  			goto out;
  	}
  
@@ -573,7 +513,7 @@
  		dentry = inode->i_op->lookup(inode, new);
  		unlock_kernel();
  		if (!dentry)
-@@ -808,6 +904,12 @@ out:
+@@ -808,6 +893,12 @@ out:
  	return dentry;
  }
  
@@ -586,7 +526,7 @@
  /* SMP-safe */
  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
  {
-@@ -829,7 +931,7 @@ struct dentry * lookup_one_len(const cha
+@@ -829,7 +920,7 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -595,7 +535,7 @@
  access:
  	return ERR_PTR(-EACCES);
  }
-@@ -860,6 +962,23 @@ int __user_walk(const char *name, unsign
+@@ -860,6 +951,23 @@ int __user_walk(const char *name, unsign
  	return err;
  }
  
@@ -619,7 +559,7 @@
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -955,7 +1074,8 @@ static inline int lookup_flags(unsigned 
+@@ -955,7 +1063,8 @@ static inline int lookup_flags(unsigned 
  	return retval;
  }
  
@@ -629,7 +569,7 @@
  {
  	int error;
  
-@@ -968,12 +1088,15 @@ int vfs_create(struct inode *dir, struct
+@@ -968,12 +1077,15 @@ int vfs_create(struct inode *dir, struct
  		goto exit_lock;
  
  	error = -EACCES;	/* shouldn't it be ENOSYS? */
@@ -647,7 +587,7 @@
  	unlock_kernel();
  exit_lock:
  	up(&dir->i_zombie);
-@@ -982,6 +1105,11 @@ exit_lock:
+@@ -982,6 +1094,11 @@ exit_lock:
  	return error;
  }
  
@@ -659,7 +599,7 @@
  /*
   *	open_namei()
   *
-@@ -996,7 +1124,8 @@ exit_lock:
+@@ -996,7 +1113,8 @@ exit_lock:
   * for symlinks (where the permissions are checked later).
   * SMP-safe
   */
@@ -669,7 +609,14 @@
  {
  	int acc_mode, error = 0;
  	struct inode *inode;
-@@ -1010,7 +1139,7 @@ int open_namei(const char * pathname, in
+@@ -1006,11 +1124,14 @@ int open_namei(const char * pathname, in
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
++
+ 	/*
  	 * The simplest case - just a plain lookup.
  	 */
  	if (!(flag & O_CREAT)) {
@@ -678,18 +625,18 @@
  		if (error)
  			return error;
  		dentry = nd->dentry;
-@@ -1020,6 +1149,10 @@ int open_namei(const char * pathname, in
+@@ -1020,6 +1141,10 @@ int open_namei(const char * pathname, in
  	/*
  	 * Create - we need to know the parent.
  	 */
-+ 	if (it) {
-+ 		it->it_mode = mode;
-+ 		it->it_op |= IT_CREAT;
-+ 	}
++	if (it) {
++		it->it_create_mode = mode;
++		it->it_op |= IT_CREAT;
++	}
  	error = path_lookup(pathname, LOOKUP_PARENT, nd);
  	if (error)
  		return error;
-@@ -1035,7 +1168,7 @@ int open_namei(const char * pathname, in
+@@ -1035,7 +1160,7 @@ int open_namei(const char * pathname, in
  
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -698,11 +645,11 @@
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1044,10 +1177,11 @@ do_last:
+@@ -1044,10 +1169,11 @@ do_last:
  		goto exit;
  	}
  
-+	it->it_mode = mode;
++	it->it_create_mode = mode;
  	/* Negative dentry, just create the file */
  	if (!dentry->d_inode) {
 -		error = vfs_create(dir->d_inode, dentry,
@@ -712,16 +659,7 @@
  		up(&dir->d_inode->i_sem);
  		dput(nd->dentry);
  		nd->dentry = dentry;
-@@ -1072,7 +1206,7 @@ do_last:
- 		error = -ELOOP;
- 		if (flag & O_NOFOLLOW)
- 			goto exit_dput;
--		while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+		while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
- 	}
- 	error = -ENOENT;
- 	if (!dentry->d_inode)
-@@ -1151,7 +1285,7 @@ ok:
+@@ -1151,7 +1277,7 @@ ok:
  		if (!error) {
  			DQUOT_INIT(inode);
  			
@@ -730,7 +668,7 @@
  		}
  		put_write_access(inode);
  		if (error)
-@@ -1163,8 +1297,10 @@ ok:
+@@ -1163,8 +1289,10 @@ ok:
  	return 0;
  
  exit_dput:
@@ -741,25 +679,18 @@
  	path_release(nd);
  	return error;
  
-@@ -1183,7 +1319,16 @@ do_link:
+@@ -1183,7 +1311,10 @@ do_link:
  	 * are done. Procfs-like symlinks just set LAST_BIND.
  	 */
  	UPDATE_ATIME(dentry->d_inode);
--	error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	nd->it = it;
-+	error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (error) {
-+		intent_release(it);
-+	} else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
++	nd->intent = it;
+ 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
++	if (error)
 +		intent_release(it);
-+		path_release(nd);
-+		error = -ENOLINK;
-+	}
  	dput(dentry);
  	if (error)
  		return error;
-@@ -1205,13 +1350,20 @@ do_link:
+@@ -1205,13 +1336,20 @@ do_link:
  	}
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -782,7 +713,7 @@
  {
  	struct dentry *dentry;
  
-@@ -1219,7 +1371,7 @@ static struct dentry *lookup_create(stru
+@@ -1219,7 +1357,7 @@ static struct dentry *lookup_create(stru
  	dentry = ERR_PTR(-EEXIST);
  	if (nd->last_type != LAST_NORM)
  		goto fail;
@@ -791,7 +722,7 @@
  	if (IS_ERR(dentry))
  		goto fail;
  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1275,7 +1427,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1275,7 +1413,16 @@ asmlinkage long sys_mknod(const char * f
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -809,7 +740,7 @@
  	error = PTR_ERR(dentry);
  
  	mode &= ~current->fs->umask;
-@@ -1296,6 +1457,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1296,6 +1443,7 @@ asmlinkage long sys_mknod(const char * f
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -817,23 +748,23 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1343,7 +1505,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1343,7 +1491,14 @@ asmlinkage long sys_mkdir(const char * p
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
 -		dentry = lookup_create(&nd, 1);
-+ 		if (nd.dentry->d_inode->i_op->mkdir_raw) {
-+ 			struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 			error = op->mkdir_raw(&nd, mode);
-+ 			/* the file system wants to use normal vfs path now */
-+ 			if (error != -EOPNOTSUPP)
-+ 				goto out2;
-+ 		}
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
 +		dentry = lookup_create(&nd, 1, NULL);
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
  			error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1351,6 +1520,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1351,6 +1506,7 @@ asmlinkage long sys_mkdir(const char * p
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -841,42 +772,42 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1451,8 +1621,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1451,8 +1607,16 @@ asmlinkage long sys_rmdir(const char * p
  			error = -EBUSY;
  			goto exit1;
  	}
-+ 	if (nd.dentry->d_inode->i_op->rmdir_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
 +
-+ 		error = op->rmdir_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1510,8 +1688,15 @@ asmlinkage long sys_unlink(const char * 
+@@ -1510,8 +1674,15 @@ asmlinkage long sys_unlink(const char * 
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
-+ 	if (nd.dentry->d_inode->i_op->unlink_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 		error = op->unlink_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
-@@ -1578,15 +1763,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1578,15 +1749,23 @@ asmlinkage long sys_symlink(const char *
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -902,7 +833,7 @@
  		putname(to);
  	}
  	putname(from);
-@@ -1662,7 +1855,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1662,7 +1841,14 @@ asmlinkage long sys_link(const char * ol
  		error = -EXDEV;
  		if (old_nd.mnt != nd.mnt)
  			goto out_release;
@@ -918,7 +849,7 @@
  		error = PTR_ERR(new_dentry);
  		if (!IS_ERR(new_dentry)) {
  			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1706,7 +1906,7 @@ exit:
+@@ -1706,7 +1892,7 @@ exit:
   *	   locking].
   */
  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -927,7 +858,7 @@
  {
  	int error;
  	struct inode *target;
-@@ -1785,7 +1985,7 @@ out_unlock:
+@@ -1785,7 +1971,7 @@ out_unlock:
  }
  
  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
@@ -936,18 +867,18 @@
  {
  	int error;
  
-@@ -1873,9 +2073,18 @@ static inline int do_rename(const char *
+@@ -1873,9 +2059,18 @@ static inline int do_rename(const char *
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
  
-+ 	if (old_dir->d_inode->i_op->rename_raw) {
++	if (old_dir->d_inode->i_op->rename_raw) {
 +		lock_kernel();
-+ 		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
 +		unlock_kernel();
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit2;
-+ 	}
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
 +
  	double_lock(new_dir, old_dir);
  
@@ -956,7 +887,7 @@
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
-@@ -1891,16 +2100,16 @@ static inline int do_rename(const char *
+@@ -1891,16 +2086,16 @@ static inline int do_rename(const char *
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
@@ -975,7 +906,7 @@
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
-@@ -1951,20 +2160,28 @@ out:
+@@ -1951,20 +2146,26 @@ out:
  }
  
  static inline int
@@ -989,11 +920,9 @@
  		goto fail;
  
 +	if (it == NULL)
-+		it = nd->it;
-+	else if (it != nd->it)
-+		printk("it != nd->it: tell phil@clusterfs.com\n");
-+	if (it != NULL)
-+		it->it_int_flags |= IT_FL_FOLLOWED;
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
 +
  	if (*link == '/') {
  		path_release(nd);
@@ -1006,7 +935,7 @@
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
  		return res;
-@@ -1986,7 +2203,13 @@ fail:
+@@ -1986,7 +2187,13 @@ fail:
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
@@ -1021,7 +950,7 @@
  }
  
  /* get the link contents into pagecache */
-@@ -2028,7 +2251,7 @@ int page_follow_link(struct dentry *dent
+@@ -2028,7 +2235,7 @@ int page_follow_link(struct dentry *dent
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
@@ -1030,8 +959,8 @@
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
---- linux-2.4.20-ad/fs/open.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/fs/open.c	2003-07-08 13:51:14.000000000 -0600
+--- linux-2.4.20-vanilla/fs/open.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:13.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/open.c	2003-09-17 21:05:04.000000000 +0400
 @@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
@@ -1068,7 +997,7 @@
  	up(&inode->i_sem);
  	return error;
  }
-@@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
+@@ -118,12 +127,13 @@ static inline long do_sys_truncate(const
  	struct nameidata nd;
  	struct inode * inode;
  	int error;
@@ -1083,7 +1012,7 @@
  	if (error)
  		goto out;
  	inode = nd.dentry->d_inode;
-@@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
+@@ -163,11 +173,13 @@ static inline long do_sys_truncate(const
  	error = locks_verify_truncate(inode, NULL, length);
  	if (!error) {
  		DQUOT_INIT(inode);
@@ -1098,7 +1027,7 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
+@@ -215,7 +227,7 @@ static inline long do_sys_ftruncate(unsi
  
  	error = locks_verify_truncate(inode, file, length);
  	if (!error)
@@ -1107,7 +1036,7 @@
  out_putf:
  	fput(file);
  out:
-@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
+@@ -260,11 +272,13 @@ asmlinkage long sys_utime(char * filenam
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1122,7 +1051,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -279,11 +294,25 @@ asmlinkage long sys_utime(char * filenam
+@@ -279,11 +293,25 @@ asmlinkage long sys_utime(char * filenam
  			goto dput_and_out;
  
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1149,7 +1078,7 @@
  	error = notify_change(nd.dentry, &newattrs);
  dput_and_out:
  	path_release(&nd);
-@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
+@@ -304,12 +332,14 @@ asmlinkage long sys_utimes(char * filena
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1165,7 +1094,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
+@@ -324,7 +354,20 @@ asmlinkage long sys_utimes(char * filena
  		newattrs.ia_atime = times[0].tv_sec;
  		newattrs.ia_mtime = times[1].tv_sec;
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1187,7 +1116,7 @@
  		if (current->fsuid != inode->i_uid &&
  		    (error = permission(inode,MAY_WRITE)) != 0)
  			goto dput_and_out;
-@@ -347,6 +395,7 @@ asmlinkage long sys_access(const char * 
+@@ -347,6 +390,7 @@ asmlinkage long sys_access(const char * 
  	int old_fsuid, old_fsgid;
  	kernel_cap_t old_cap;
  	int res;
@@ -1195,7 +1124,7 @@
  
  	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
  		return -EINVAL;
-@@ -364,13 +413,14 @@ asmlinkage long sys_access(const char * 
+@@ -364,13 +408,14 @@ asmlinkage long sys_access(const char * 
  	else
  		current->cap_effective = current->cap_permitted;
  
@@ -1211,18 +1140,18 @@
  		path_release(&nd);
  	}
  
-@@ -385,8 +435,9 @@ asmlinkage long sys_chdir(const char * f
+@@ -385,8 +430,9 @@ asmlinkage long sys_chdir(const char * f
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
 +	error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
  	if (error)
  		goto out;
  
-@@ -397,6 +448,7 @@ asmlinkage long sys_chdir(const char * f
+@@ -397,6 +443,7 @@ asmlinkage long sys_chdir(const char * f
  	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
  
  dput_and_out:
@@ -1230,11 +1159,11 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -436,9 +488,10 @@ asmlinkage long sys_chroot(const char * 
+@@ -436,9 +483,10 @@ asmlinkage long sys_chroot(const char * 
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 -		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
@@ -1243,7 +1172,7 @@
  	if (error)
  		goto out;
  
-@@ -454,6 +507,7 @@ asmlinkage long sys_chroot(const char * 
+@@ -454,39 +502,56 @@ asmlinkage long sys_chroot(const char * 
  	set_fs_altroot();
  	error = 0;
  dput_and_out:
@@ -1251,26 +1180,102 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -508,6 +562,18 @@ asmlinkage long sys_chmod(const char * f
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
+ }
+ 
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
  
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
 +	if (inode->i_op->setattr_raw) {
-+		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
 +		newattrs.ia_mode = mode;
 +		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 +		newattrs.ia_valid |= ATTR_RAW;
-+		error = op->setattr_raw(inode, &newattrs);
++		err = inode->i_op->setattr_raw(inode, &newattrs);
 +		/* the file system wants to use normal vfs path now */
-+		if (error != -EOPNOTSUPP)
-+			goto dput_and_out;
++		if (err != -EOPNOTSUPP)
++			goto out;
 +	}
-+
- 	error = -EPERM;
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -538,6 +604,20 @@ static int chown_common(struct dentry * 
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -495,30 +560,14 @@ out:
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
++	error = chmod_common(nd.dentry, mode);
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
+-
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -538,6 +587,20 @@ static int chown_common(struct dentry * 
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto out;
@@ -1291,20 +1296,15 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
-@@ -638,10 +718,12 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
-+
- struct file *filp_open(const char * filename, int flags, int mode)
+@@ -642,6 +705,7 @@ struct file *filp_open(const char * file
  {
  	int namei_flags, error;
  	struct nameidata nd;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
++	struct lookup_intent it = { .it_op = IT_OPEN };
  
  	namei_flags = flags;
  	if ((namei_flags+1) & O_ACCMODE)
-@@ -649,14 +731,15 @@ struct file *filp_open(const char * file
+@@ -649,14 +713,15 @@ struct file *filp_open(const char * file
  	if (namei_flags & O_TRUNC)
  		namei_flags |= 2;
  
@@ -1325,7 +1325,7 @@
  {
  	struct file * f;
  	struct inode *inode;
-@@ -693,12 +776,15 @@ struct file *dentry_open(struct dentry *
+@@ -693,12 +758,15 @@ struct file *dentry_open(struct dentry *
  	}
  
  	if (f->f_op && f->f_op->open) {
@@ -1341,7 +1341,7 @@
  	return f;
  
  cleanup_all:
-@@ -713,11 +799,17 @@ cleanup_all:
+@@ -713,11 +781,17 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
@@ -1359,9 +1359,9 @@
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux-2.4.20-ad/fs/stat.c~vfs_intent-2.4.20-vanilla	2001-09-13 17:04:43.000000000 -0600
-+++ linux-2.4.20-ad-braam/fs/stat.c	2003-07-07 15:13:53.000000000 -0600
-@@ -17,10 +17,12 @@
+--- linux-2.4.20-vanilla/fs/stat.c~vfs_intent-2.4.20-vanilla	2001-09-14 03:04:43.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/fs/stat.c	2003-09-17 21:05:04.000000000 +0400
+@@ -17,10 +17,14 @@
   * Revalidate the inode. This is required for proper NFS attribute caching.
   */
  static __inline__ int
@@ -1370,13 +1370,15 @@
  {
  	struct inode * inode = dentry->d_inode;
 -	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
 +	if (inode->i_op && inode->i_op->revalidate_it)
 +		return inode->i_op->revalidate_it(dentry, it);
 +	else if (inode->i_op && inode->i_op->revalidate)
  		return inode->i_op->revalidate(dentry);
  	return 0;
  }
-@@ -135,13 +137,15 @@ static int cp_new_stat(struct inode * in
+@@ -135,13 +139,15 @@ static int cp_new_stat(struct inode * in
  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
  {
  	struct nameidata nd;
@@ -1394,7 +1396,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -151,13 +155,15 @@ asmlinkage long sys_stat(char * filename
+@@ -151,13 +157,15 @@ asmlinkage long sys_stat(char * filename
  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
  {
  	struct nameidata nd;
@@ -1412,7 +1414,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -172,13 +178,15 @@ asmlinkage long sys_newstat(char * filen
+@@ -172,13 +180,15 @@ asmlinkage long sys_newstat(char * filen
  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
  {
  	struct nameidata nd;
@@ -1430,7 +1432,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -189,13 +197,15 @@ asmlinkage long sys_lstat(char * filenam
+@@ -189,13 +199,15 @@ asmlinkage long sys_lstat(char * filenam
  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
  {
  	struct nameidata nd;
@@ -1448,7 +1450,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -216,7 +226,7 @@ asmlinkage long sys_fstat(unsigned int f
+@@ -216,7 +228,7 @@ asmlinkage long sys_fstat(unsigned int f
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1457,7 +1459,7 @@
  		if (!err)
  			err = cp_old_stat(dentry->d_inode, statbuf);
  		fput(f);
-@@ -235,7 +245,7 @@ asmlinkage long sys_newfstat(unsigned in
+@@ -235,7 +247,7 @@ asmlinkage long sys_newfstat(unsigned in
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1466,7 +1468,7 @@
  		if (!err)
  			err = cp_new_stat(dentry->d_inode, statbuf);
  		fput(f);
-@@ -257,7 +267,7 @@ asmlinkage long sys_readlink(const char 
+@@ -257,7 +269,7 @@ asmlinkage long sys_readlink(const char 
  
  		error = -EINVAL;
  		if (inode->i_op && inode->i_op->readlink &&
@@ -1475,7 +1477,7 @@
  			UPDATE_ATIME(inode);
  			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
  		}
-@@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena
+@@ -333,12 +345,14 @@ asmlinkage long sys_stat64(char * filena
  {
  	struct nameidata nd;
  	int error;
@@ -1492,7 +1494,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen
+@@ -348,12 +362,14 @@ asmlinkage long sys_lstat64(char * filen
  {
  	struct nameidata nd;
  	int error;
@@ -1509,7 +1511,7 @@
  		path_release(&nd);
  	}
  	return error;
-@@ -368,7 +382,7 @@ asmlinkage long sys_fstat64(unsigned lon
+@@ -368,7 +384,7 @@ asmlinkage long sys_fstat64(unsigned lon
  	if (f) {
  		struct dentry * dentry = f->f_dentry;
  
@@ -1518,24 +1520,14 @@
  		if (!err)
  			err = cp_new_stat64(dentry->d_inode, statbuf);
  		fput(f);
---- linux-2.4.20-ad/fs/proc/base.c~vfs_intent-2.4.20-vanilla	2002-08-02 18:39:45.000000000 -0600
-+++ linux-2.4.20-ad-braam/fs/proc/base.c	2003-07-07 15:13:53.000000000 -0600
-@@ -464,6 +464,9 @@ static int proc_pid_follow_link(struct d
- 
- 	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
- 	nd->last_type = LAST_BIND;
-+
-+	if (nd->it != NULL)
-+		nd->it->it_int_flags |= IT_FL_FOLLOWED;
- out:
- 	return error;
- }
---- linux-2.4.20-ad/include/linux/dcache.h~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/include/linux/dcache.h	2003-07-09 01:40:11.000000000 -0600
-@@ -7,6 +7,44 @@
+--- linux-2.4.20-vanilla/include/linux/dcache.h~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:15.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/dcache.h	2003-09-17 21:05:42.000000000 +0400
+@@ -6,6 +6,51 @@
+ #include <asm/atomic.h>
  #include <linux/mount.h>
  #include <linux/kernel.h>
- 
++#include <linux/string.h>
++
 +#define IT_OPEN     0x0001
 +#define IT_CREAT    0x0002
 +#define IT_READDIR  0x0004
@@ -1551,18 +1543,24 @@
 +
 +#define INTENT_MAGIC 0x19620323
 +
-+struct lookup_intent {
-+	int it_op;
-+	void (*it_op_release)(struct lookup_intent *);
-+	int it_magic;
-+	int it_mode;
-+	int it_flags;
-+	int it_disposition;
-+	int it_status;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
 +	int it_int_flags;
-+	__u64 it_lock_handle[2];
-+	int it_lock_mode;
-+	void *it_data;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op, int flags)
@@ -1573,11 +1571,10 @@
 +	it->it_flags = flags;
 +}
 +
-+
+ 
  /*
   * linux/include/linux/dcache.h
-  *
-@@ -91,8 +129,22 @@ struct dentry_operations {
+@@ -91,8 +136,22 @@ struct dentry_operations {
  	int (*d_delete)(struct dentry *);
  	void (*d_release)(struct dentry *);
  	void (*d_iput)(struct dentry *, struct inode *);
@@ -1600,7 +1597,7 @@
  /* the dentry parameter passed to d_hash and d_compare is the parent
   * directory of the entries to be compared. It is used in case these
   * functions need any directory specific information for determining
-@@ -124,6 +176,7 @@ d_iput:		no		no		yes
+@@ -124,6 +183,7 @@ d_iput:		no		no		yes
  					 * s_nfsd_free_path semaphore will be down
  					 */
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
@@ -1608,9 +1605,17 @@
  
  extern spinlock_t dcache_lock;
  
---- linux-2.4.20/include/linux/fs.h~vfs_intent-2.4.20-vanilla	2003-06-12 03:24:59.000000000 -0600
-+++ linux-2.4.20-braam/include/linux/fs.h	2003-06-12 03:25:00.000000000 -0600
-@@ -338,6 +338,9 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.20-vanilla/include/linux/fs.h~vfs_intent-2.4.20-vanilla	2003-09-17 21:05:03.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/fs.h	2003-09-17 21:05:04.000000000 +0400
+@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -338,6 +339,9 @@ extern void set_bh_page(struct buffer_he
  #define ATTR_MTIME_SET	256
  #define ATTR_FORCE	512	/* Not a change, but a change it */
  #define ATTR_ATTR_FLAG	1024
@@ -1620,7 +1625,15 @@
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -542,6 +544,7 @@ struct file {
+@@ -471,6 +475,7 @@ struct inode {
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -542,6 +547,7 @@ struct file {
  
  	/* needed for tty driver, and maybe others */
  	void			*private_data;
@@ -1628,15 +1641,15 @@
  
  	/* preallocated helper kiobuf to speedup O_DIRECT */
  	struct kiobuf		*f_iobuf;
-@@ -661,6 +664,7 @@ struct nameidata {
+@@ -661,6 +667,7 @@ struct nameidata {
  	struct qstr last;
  	unsigned int flags;
  	int last_type;
-+	struct lookup_intent *it;
++	struct lookup_intent *intent;
  };
  
  #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
-@@ -794,7 +798,8 @@ extern int vfs_symlink(struct inode *, s
+@@ -794,7 +801,8 @@ extern int vfs_symlink(struct inode *, s
  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
  extern int vfs_rmdir(struct inode *, struct dentry *);
  extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1646,7 +1659,7 @@
  
  /*
   * File types
-@@ -854,21 +859,32 @@ struct file_operations {
+@@ -854,21 +862,32 @@ struct file_operations {
  
  struct inode_operations {
  	int (*create) (struct inode *,struct dentry *,int);
@@ -1675,11 +1688,11 @@
  	int (*revalidate) (struct dentry *);
 +	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
  	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
  	int (*getattr) (struct dentry *, struct iattr *);
  	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
  	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1070,10 +1086,14 @@ static inline int get_lease(struct inode
+@@ -1070,10 +1089,14 @@ static inline int get_lease(struct inode
  
  asmlinkage long sys_open(const char *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
@@ -1695,7 +1708,7 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char *);
  
-@@ -1335,6 +1355,7 @@ typedef int (*read_actor_t)(read_descrip
+@@ -1335,6 +1358,7 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
@@ -1703,7 +1716,7 @@
  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
  extern int FASTCALL(path_walk(const char *, struct nameidata *));
  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1346,6 +1367,8 @@ extern struct dentry * lookup_one_len(co
+@@ -1346,6 +1370,8 @@ extern struct dentry * lookup_one_len(co
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
  #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
@@ -1712,7 +1725,7 @@
  
  extern void iput(struct inode *);
  extern void force_delete(struct inode *);
-@@ -1455,6 +1478,8 @@ extern struct file_operations generic_ro
+@@ -1455,6 +1481,8 @@ extern struct file_operations generic_ro
  
  extern int vfs_readlink(struct dentry *, char *, int, const char *);
  extern int vfs_follow_link(struct nameidata *, const char *);
@@ -1721,8 +1734,8 @@
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.20-ad/include/linux/fs_struct.h~vfs_intent-2.4.20-vanilla	2001-07-13 16:10:44.000000000 -0600
-+++ linux-2.4.20-ad-braam/include/linux/fs_struct.h	2003-07-07 15:13:53.000000000 -0600
+--- linux-2.4.20-vanilla/include/linux/fs_struct.h~vfs_intent-2.4.20-vanilla	2001-07-14 02:10:44.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/include/linux/fs_struct.h	2003-09-17 21:05:04.000000000 +0400
 @@ -34,10 +34,12 @@ static inline void set_fs_root(struct fs
  	write_lock(&fs->lock);
  	old_root = fs->root;
@@ -1749,8 +1762,8 @@
  		dput(old_pwd);
  		mntput(old_pwdmnt);
  	}
---- linux-2.4.20-ad/kernel/ksyms.c~vfs_intent-2.4.20-vanilla	2003-07-07 15:13:52.000000000 -0600
-+++ linux-2.4.20-ad-braam/kernel/ksyms.c	2003-07-07 15:13:53.000000000 -0600
+--- linux-2.4.20-vanilla/kernel/ksyms.c~vfs_intent-2.4.20-vanilla	2003-09-17 21:05:03.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/kernel/ksyms.c	2003-09-17 21:05:04.000000000 +0400
 @@ -269,6 +269,7 @@ EXPORT_SYMBOL(read_cache_page);
  EXPORT_SYMBOL(set_page_dirty);
  EXPORT_SYMBOL(vfs_readlink);
@@ -1759,8 +1772,8 @@
  EXPORT_SYMBOL(page_readlink);
  EXPORT_SYMBOL(page_follow_link);
  EXPORT_SYMBOL(page_symlink_inode_operations);
---- linux-2.4.20-ad/kernel/fork.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/kernel/fork.c	2003-07-07 15:13:53.000000000 -0600
+--- linux-2.4.20-vanilla/kernel/fork.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:15.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/kernel/fork.c	2003-09-17 21:05:04.000000000 +0400
 @@ -384,10 +384,13 @@ static inline struct fs_struct *__copy_f
  		fs->umask = old->umask;
  		read_lock(&old->lock);
@@ -1775,8 +1788,8 @@
  			fs->altrootmnt = mntget(old->altrootmnt);
  			fs->altroot = dget(old->altroot);
  		} else {
---- linux-2.4.20-ad/kernel/exit.c~vfs_intent-2.4.20-vanilla	2002-11-28 16:53:15.000000000 -0700
-+++ linux-2.4.20-ad-braam/kernel/exit.c	2003-07-07 15:13:53.000000000 -0600
+--- linux-2.4.20-vanilla/kernel/exit.c~vfs_intent-2.4.20-vanilla	2003-05-16 05:29:15.000000000 +0400
++++ linux-2.4.20-vanilla-alexey/kernel/exit.c	2003-09-17 21:05:04.000000000 +0400
 @@ -238,11 +238,14 @@ static inline void __put_fs_struct(struc
  {
  	/* No need to hold fs->lock if we are killing it */
diff --git a/lustre/kernel_patches/patches/vfs_intent_2.4.20_chaos.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch
similarity index 70%
rename from lustre/kernel_patches/patches/vfs_intent_2.4.20_chaos.patch
rename to lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch
index 3d6dd56c528f372ec5d7a85bee515121f2b028e3..5f266a8673c8c9b69491a17b567f743eba6afb29 100644
--- a/lustre/kernel_patches/patches/vfs_intent_2.4.20_chaos.patch
+++ b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch
@@ -1,32 +1,71 @@
  fs/dcache.c               |   19 ++
- fs/exec.c                 |   15 +-
- fs/namei.c                |  324 ++++++++++++++++++++++++++++++++++++++--------
- fs/namespace.c            |   28 ++-
- fs/open.c                 |  126 +++++++++++++++--
- fs/proc/base.c            |    3 
- fs/stat.c                 |   26 ++-
- include/linux/dcache.h    |   54 +++++++
- include/linux/fs.h        |   30 +++-
+ fs/exec.c                 |   17 +-
+ fs/namei.c                |  295 +++++++++++++++++++++++++++++++++++++++-------
+ fs/namespace.c            |   28 +++-
+ fs/open.c                 |  172 +++++++++++++++++++-------
+ fs/stat.c                 |   52 +++++---
+ include/linux/dcache.h    |   60 +++++++++
+ include/linux/fs.h        |   32 ++++
  include/linux/fs_struct.h |    4 
  kernel/exit.c             |    3 
  kernel/fork.c             |    3 
  kernel/ksyms.c            |    1 
- 13 files changed, 538 insertions(+), 98 deletions(-)
+ 12 files changed, 558 insertions(+), 128 deletions(-)
 
---- kernel-2.4.20-6chaos_18_7/fs/exec.c~vfs_intent_2.4.20_chaos	Thu Jun 19 10:06:09 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/exec.c	Wed Jul 16 04:21:21 2003
-@@ -113,8 +113,9 @@ asmlinkage long sys_uselib(const char * 
+--- linux-2.4.22-ac1/fs/dcache.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/dcache.c	2003-09-25 14:42:46.000000000 +0400
+@@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
+ 		spin_unlock(&dcache_lock);
+ 		return 0;
+ 	}
++
++	/* network invalidation by Lustre */
++	if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
++		spin_unlock(&dcache_lock);
++		return 0;
++	}
++
+ 	/*
+ 	 * Check whether to do a partial shrink_dcache
+ 	 * to get rid of unused child entries.
+@@ -833,13 +840,19 @@ void d_delete(struct dentry * dentry)
+  * Adds a dentry to the hash according to its name.
+  */
+  
+-void d_rehash(struct dentry * entry)
++void __d_rehash(struct dentry * entry, int lock)
+ {
+ 	struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+ 	if (!list_empty(&entry->d_hash)) BUG();
+-	spin_lock(&dcache_lock);
++	if (lock) spin_lock(&dcache_lock);
+ 	list_add(&entry->d_hash, list);
+-	spin_unlock(&dcache_lock);
++	if (lock) spin_unlock(&dcache_lock);
++}
++EXPORT_SYMBOL(__d_rehash);
++
++void d_rehash(struct dentry * entry)
++{
++	__d_rehash(entry, 1);
+ }
+ 
+ #define do_switch(x,y) do { \
+--- linux-2.4.22-ac1/fs/exec.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/exec.c	2003-09-25 14:42:46.000000000 +0400
+@@ -115,8 +115,10 @@ asmlinkage long sys_uselib(const char * 
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	error = user_path_walk(library, &nd);
 +	error = user_path_walk_it(library, &nd, &it);
  	if (error)
  		goto out;
  
-@@ -126,7 +127,8 @@ asmlinkage long sys_uselib(const char * 
+@@ -128,7 +130,8 @@ asmlinkage long sys_uselib(const char * 
  	if (error)
  		goto exit;
  
@@ -36,18 +75,19 @@
  	error = PTR_ERR(file);
  	if (IS_ERR(file))
  		goto out;
-@@ -381,8 +383,9 @@ struct file *open_exec(const char *name)
+@@ -390,8 +393,10 @@ struct file *open_exec(const char *name)
  	struct inode *inode;
  	struct file *file;
  	int err = 0;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
++	struct lookup_intent it = { .it_op = IT_OPEN,
++				    .it_flags = FMODE_READ|FMODE_EXEC };
  
 -	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 +	err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
  	file = ERR_PTR(err);
  	if (!err) {
  		inode = nd.dentry->d_inode;
-@@ -394,7 +397,8 @@ struct file *open_exec(const char *name)
+@@ -403,7 +408,8 @@ struct file *open_exec(const char *name)
  				err = -EACCES;
  			file = ERR_PTR(err);
  			if (!err) {
@@ -57,7 +97,7 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
-@@ -406,6 +410,7 @@ out:
+@@ -415,6 +421,7 @@ out:
  				return file;
  			}
  		}
@@ -65,7 +105,7 @@
  		path_release(&nd);
  	}
  	goto out;
-@@ -1134,7 +1139,7 @@ int do_coredump(long signr, struct pt_re
+@@ -1322,7 +1329,7 @@ int do_coredump(long signr, int exit_cod
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
@@ -74,162 +114,8 @@
  		goto close_fail;
  
  	retval = binfmt->core_dump(signr, regs, file);
---- kernel-2.4.20-6chaos_18_7/fs/dcache.c~vfs_intent_2.4.20_chaos	Thu May 15 20:14:24 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/dcache.c	Wed Jul 16 04:21:21 2003
-@@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
- 		spin_unlock(&dcache_lock);
- 		return 0;
- 	}
-+
-+	/* network invalidation by Lustre */
-+	if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+		spin_unlock(&dcache_lock);
-+		return 0;
-+	}
-+
- 	/*
- 	 * Check whether to do a partial shrink_dcache
- 	 * to get rid of unused child entries.
-@@ -839,13 +846,19 @@ void d_delete(struct dentry * dentry)
-  * Adds a dentry to the hash according to its name.
-  */
-  
--void d_rehash(struct dentry * entry)
-+void __d_rehash(struct dentry * entry, int lock)
- {
- 	struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
- 	if (!list_empty(&entry->d_hash)) BUG();
--	spin_lock(&dcache_lock);
-+	if (lock) spin_lock(&dcache_lock);
- 	list_add(&entry->d_hash, list);
--	spin_unlock(&dcache_lock);
-+	if (lock) spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(__d_rehash);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+	__d_rehash(entry, 1);
- }
- 
- #define do_switch(x,y) do { \
---- kernel-2.4.20-6chaos_18_7/fs/namespace.c~vfs_intent_2.4.20_chaos	Thu May 15 20:14:25 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/namespace.c	Wed Jul 16 04:21:21 2003
-@@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
- {
- 	old_nd->dentry = mnt->mnt_mountpoint;
- 	old_nd->mnt = mnt->mnt_parent;
-+	UNPIN(old_nd->dentry, old_nd->mnt, 1);
- 	mnt->mnt_parent = mnt;
- 	mnt->mnt_mountpoint = mnt->mnt_root;
- 	list_del_init(&mnt->mnt_child);
-@@ -110,6 +111,7 @@ static void attach_mnt(struct vfsmount *
- {
- 	mnt->mnt_parent = mntget(nd->mnt);
- 	mnt->mnt_mountpoint = dget(nd->dentry);
-+	PIN(nd->dentry, nd->mnt, 1);
- 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
- 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
- 	nd->dentry->d_mounted++;
-@@ -485,14 +487,17 @@ static int do_loopback(struct nameidata 
- {
- 	struct nameidata old_nd;
- 	struct vfsmount *mnt = NULL;
-+	struct lookup_intent it = { .it_op = IT_GETATTR };
- 	int err = mount_is_safe(nd);
- 	if (err)
- 		return err;
- 	if (!old_name || !*old_name)
- 		return -EINVAL;
--	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
--	if (err)
-+	err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it);
-+	if (err) {
-+		intent_release(&it);
- 		return err;
-+	}
- 
- 	down_write(&current->namespace->sem);
- 	err = -EINVAL;
-@@ -515,6 +520,7 @@ static int do_loopback(struct nameidata 
- 	}
- 
- 	up_write(&current->namespace->sem);
-+	intent_release(&it);
- 	path_release(&old_nd);
- 	return err;
- }
-@@ -698,6 +704,7 @@ long do_mount(char * dev_name, char * di
- 		  unsigned long flags, void *data_page)
- {
- 	struct nameidata nd;
-+	struct lookup_intent it = { .it_op = IT_GETATTR };
- 	int retval = 0;
- 	int mnt_flags = 0;
- 
-@@ -722,10 +729,11 @@ long do_mount(char * dev_name, char * di
- 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
- 
- 	/* ... and get the mountpoint */
--	retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
--	if (retval)
-+	retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
-+	if (retval) {
-+		intent_release(&it);
- 		return retval;
--
-+	}
- 	if (flags & MS_REMOUNT)
- 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
- 				    data_page);
-@@ -736,6 +744,8 @@ long do_mount(char * dev_name, char * di
- 	else
- 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
- 				      dev_name, data_page);
-+
-+	intent_release(&it);
- 	path_release(&nd);
- 	return retval;
- }
-@@ -901,6 +911,8 @@ asmlinkage long sys_pivot_root(const cha
- {
- 	struct vfsmount *tmp;
- 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
-+	struct lookup_intent new_it = { .it_op = IT_GETATTR };
-+	struct lookup_intent old_it = { .it_op = IT_GETATTR };
- 	int error;
- 
- 	if (!capable(CAP_SYS_ADMIN))
-@@ -908,14 +920,14 @@ asmlinkage long sys_pivot_root(const cha
- 
- 	lock_kernel();
- 
--	error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
-+	error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it);
- 	if (error)
- 		goto out0;
- 	error = -EINVAL;
- 	if (!check_mnt(new_nd.mnt))
- 		goto out1;
- 
--	error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
-+	error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it);
- 	if (error)
- 		goto out1;
- 
-@@ -970,8 +982,10 @@ out2:
- 	up(&old_nd.dentry->d_inode->i_zombie);
- 	up_write(&current->namespace->sem);
- 	path_release(&user_nd);
-+	intent_release(&old_it);
- 	path_release(&old_nd);
- out1:
-+	intent_release(&new_it);
- 	path_release(&new_nd);
- out0:
- 	unlock_kernel();
---- kernel-2.4.20-6chaos_18_7/fs/namei.c~vfs_intent_2.4.20_chaos	Thu May 15 20:14:25 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/namei.c	Wed Jul 16 04:21:21 2003
+--- linux-2.4.22-ac1/fs/namei.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:23.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/namei.c	2003-09-25 14:44:40.000000000 +0400
 @@ -94,6 +94,13 @@
   * XEmacs seems to be relying on it...
   */
@@ -265,7 +151,7 @@
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
  		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
  			dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
   * make sure that nobody added the entry to the dcache in the meantime..
   * SMP-safe
   */
@@ -275,13 +161,14 @@
  {
  	struct dentry * result;
  	struct inode *dir = parent->d_inode;
++	int counter = 0;
  
 +again:
-+
++	counter++;
  	down(&dir->i_sem);
  	/*
  	 * First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
  		result = ERR_PTR(-ENOMEM);
  		if (dentry) {
  			lock_kernel();
@@ -291,7 +178,7 @@
  			result = dir->i_op->lookup(dir, dentry);
  			unlock_kernel();
  			if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
  			dput(result);
  			result = ERR_PTR(-ENOENT);
  		}
@@ -299,12 +186,15 @@
 +		if (!result->d_op->d_revalidate_it(result, flags, it) &&
 +		    !d_invalidate(result)) {
 +			dput(result);
-+			goto again;
++			if (counter > 10)
++				result = ERR_PTR(-ESTALE);
++			if (!IS_ERR(result))
++				goto again;
 +		}
  	}
  	return result;
  }
-@@ -334,7 +362,8 @@ int max_recursive_link = 5;
+@@ -332,7 +364,8 @@ static struct dentry * real_lookup(struc
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups. 
   */
@@ -313,19 +203,13 @@
 +				 struct lookup_intent *it)
  {
  	int err;
- 	if (current->link_count >= max_recursive_link)
-@@ -348,10 +377,18 @@ static inline int do_follow_link(struct 
+ 	if (current->link_count >= 5)
+@@ -346,10 +379,12 @@ static inline int do_follow_link(struct 
  	current->link_count++;
  	current->total_link_count++;
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
-+		intent_release(it);
-+		path_release(nd);
-+		err = -ENOLINK;
-+	}
  	current->link_count--;
  	return err;
  loop:
@@ -333,53 +217,7 @@
  	path_release(nd);
  	return -ELOOP;
  }
-@@ -381,15 +418,26 @@ int follow_up(struct vfsmount **mnt, str
- 	return __follow_up(mnt, dentry);
- }
- 
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+				struct lookup_intent *it)
- {
- 	struct vfsmount *mounted;
- 
- 	spin_lock(&dcache_lock);
- 	mounted = lookup_mnt(*mnt, *dentry);
- 	if (mounted) {
-+		int opc = 0, mode = 0;
- 		*mnt = mntget(mounted);
- 		spin_unlock(&dcache_lock);
-+		if (it) {
-+			opc = it->it_op;
-+			mode = it->it_mode;
-+		}
-+		intent_release(it);
-+		if (it) {
-+			it->it_op = opc;
-+			it->it_mode = mode;
-+		}
- 		dput(*dentry);
- 		mntput(mounted->mnt_parent);
- 		*dentry = dget(mounted->mnt_root);
-@@ -401,7 +449,7 @@ static inline int __follow_down(struct v
- 
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--	return __follow_down(mnt,dentry);
-+	return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct nameidata *nd)
-@@ -437,7 +485,7 @@ static inline void follow_dotdot(struct 
- 		mntput(nd->mnt);
- 		nd->mnt = parent;
- 	}
--	while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
-+	while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
- 		;
- }
- 
-@@ -449,7 +497,8 @@ static inline void follow_dotdot(struct 
+@@ -447,7 +482,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
   */
@@ -389,30 +227,19 @@
  {
  	struct dentry *dentry;
  	struct inode *inode;
-@@ -526,19 +575,18 @@ int link_path_walk(const char * name, st
+@@ -520,9 +556,9 @@ int link_path_walk(const char * name, st
  				break;
  		}
  		/* This does the actual lookups.. */
 -		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
 +		dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
  		if (!dentry) {
- 			err = -EWOULDBLOCKIO;
- 			if (atomic)
- 				break;
 -			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
 +			dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
  			err = PTR_ERR(dentry);
  			if (IS_ERR(dentry))
  				break;
- 		}
- 		/* Check mountpoints.. */
--		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
--			;
-+		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL));
- 
- 		err = -ENOENT;
- 		inode = dentry->d_inode;
-@@ -549,7 +597,7 @@ int link_path_walk(const char * name, st
+@@ -540,7 +576,7 @@ int link_path_walk(const char * name, st
  			goto out_dput;
  
  		if (inode->i_op->follow_link) {
@@ -421,7 +248,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -565,7 +613,7 @@ int link_path_walk(const char * name, st
+@@ -556,7 +592,7 @@ int link_path_walk(const char * name, st
  			nd->dentry = dentry;
  		}
  		err = -ENOTDIR; 
@@ -430,25 +257,19 @@
  			break;
  		continue;
  		/* here ends the main loop */
-@@ -592,22 +640,22 @@ last_component:
+@@ -583,9 +619,9 @@ last_component:
  			if (err < 0)
  				break;
  		}
 -		dentry = cached_lookup(nd->dentry, &this, 0);
 +		dentry = cached_lookup(nd->dentry, &this, 0, it);
  		if (!dentry) {
- 			err = -EWOULDBLOCKIO;
- 			if (atomic)
- 				break;
 -			dentry = real_lookup(nd->dentry, &this, 0);
 +			dentry = real_lookup(nd->dentry, &this, 0, it);
  			err = PTR_ERR(dentry);
  			if (IS_ERR(dentry))
  				break;
- 		}
--		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
-+		while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
- 			;
+@@ -595,7 +631,7 @@ last_component:
  		inode = dentry->d_inode;
  		if ((lookup_flags & LOOKUP_FOLLOW)
  		    && inode && inode->i_op && inode->i_op->follow_link) {
@@ -457,7 +278,7 @@
  			dput(dentry);
  			if (err)
  				goto return_err;
-@@ -621,7 +669,8 @@ last_component:
+@@ -609,7 +645,8 @@ last_component:
  			goto no_inode;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
@@ -467,31 +288,33 @@
  				break;
  		}
  		goto return_base;
-@@ -645,6 +694,23 @@ return_reval:
+@@ -635,6 +672,25 @@ return_reval:
  		 * Check the cached dentry for staleness.
  		 */
  		dentry = nd->dentry;
-+	revalidate_again:
 +		if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
 +			err = -ESTALE;
 +			if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
 +				struct dentry *new;
 +				err = permission(dentry->d_parent->d_inode,
-+						 MAY_EXEC);
++						MAY_EXEC);
 +				if (err)
 +					break;
 +				new = real_lookup(dentry->d_parent,
-+						  &dentry->d_name, 0, NULL);
++						&dentry->d_name, 0, NULL);
 +				d_invalidate(dentry);
 +				dput(dentry);
-+				dentry = new;
-+				goto revalidate_again;
++				if (IS_ERR(new)) { 
++					err = PTR_ERR(new);
++					break;
++				}
++				nd->dentry = new;
 +			}
 +		} else
- 		if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
+ 		if (dentry && dentry->d_sb
+ 		    && (dentry->d_sb->s_type->fs_flags & FS_ALWAYS_REVAL)) {
  			err = -ESTALE;
- 			if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -658,15 +724,28 @@ out_dput:
+@@ -649,15 +705,28 @@ out_dput:
  		dput(dentry);
  		break;
  	}
@@ -521,7 +344,7 @@
  }
  
  /* SMP-safe */
-@@ -751,6 +830,17 @@ walk_init_root(const char *name, struct 
+@@ -742,6 +811,17 @@ walk_init_root(const char *name, struct 
  }
  
  /* SMP-safe */
@@ -539,15 +362,15 @@
  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
  {
  	int error = 0;
-@@ -765,6 +855,7 @@ int path_init(const char *name, unsigned
+@@ -756,6 +836,7 @@ int path_init(const char *name, unsigned
  {
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
-+	nd->it = NULL;
++	nd->intent = NULL;
  	if (*name=='/')
  		return walk_init_root(name,nd);
  	read_lock(&current->fs->lock);
-@@ -779,7 +870,8 @@ int path_init(const char *name, unsigned
+@@ -770,7 +851,8 @@ int path_init(const char *name, unsigned
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
@@ -557,7 +380,7 @@
  {
  	struct dentry * dentry;
  	struct inode *inode;
-@@ -802,13 +894,16 @@ struct dentry * lookup_hash(struct qstr 
+@@ -793,13 +875,16 @@ struct dentry * lookup_hash(struct qstr 
  			goto out;
  	}
  
@@ -575,7 +398,7 @@
  		dentry = inode->i_op->lookup(inode, new);
  		unlock_kernel();
  		if (!dentry)
-@@ -820,6 +915,12 @@ out:
+@@ -811,6 +896,12 @@ out:
  	return dentry;
  }
  
@@ -588,7 +411,7 @@
  /* SMP-safe */
  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
  {
-@@ -841,7 +942,7 @@ struct dentry * lookup_one_len(const cha
+@@ -832,7 +923,7 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -597,7 +420,7 @@
  access:
  	return ERR_PTR(-EACCES);
  }
-@@ -872,6 +973,23 @@ int __user_walk(const char *name, unsign
+@@ -863,6 +954,23 @@ int __user_walk(const char *name, unsign
  	return err;
  }
  
@@ -621,7 +444,7 @@
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -969,7 +1087,8 @@ static inline int lookup_flags(unsigned 
+@@ -958,7 +1066,8 @@ static inline int lookup_flags(unsigned 
  	return retval;
  }
  
@@ -631,7 +454,7 @@
  {
  	int error;
  
-@@ -982,12 +1101,15 @@ int vfs_create(struct inode *dir, struct
+@@ -971,12 +1080,15 @@ int vfs_create(struct inode *dir, struct
  		goto exit_lock;
  
  	error = -EACCES;	/* shouldn't it be ENOSYS? */
@@ -649,7 +472,7 @@
  	unlock_kernel();
  exit_lock:
  	up(&dir->i_zombie);
-@@ -996,6 +1118,11 @@ exit_lock:
+@@ -985,6 +1097,11 @@ exit_lock:
  	return error;
  }
  
@@ -661,7 +484,7 @@
  /*
   *	open_namei()
   *
-@@ -1010,7 +1137,8 @@ exit_lock:
+@@ -999,7 +1116,8 @@ exit_lock:
   * for symlinks (where the permissions are checked later).
   * SMP-safe
   */
@@ -671,7 +494,14 @@
  {
  	int acc_mode, error = 0;
  	struct inode *inode;
-@@ -1024,7 +1152,7 @@ int open_namei(const char * pathname, in
+@@ -1009,11 +1127,14 @@ int open_namei(const char * pathname, in
+ 
+ 	acc_mode = ACC_MODE(flag);
+ 
++	if (it)
++		it->it_flags = flag;
++
+ 	/*
  	 * The simplest case - just a plain lookup.
  	 */
  	if (!(flag & O_CREAT)) {
@@ -680,18 +510,18 @@
  		if (error)
  			return error;
  		dentry = nd->dentry;
-@@ -1034,6 +1162,10 @@ int open_namei(const char * pathname, in
+@@ -1023,6 +1144,10 @@ int open_namei(const char * pathname, in
  	/*
  	 * Create - we need to know the parent.
  	 */
-+ 	if (it) {
-+ 		it->it_mode = mode;
-+ 		it->it_op |= IT_CREAT;
-+ 	}
++	if (it) {
++		it->it_create_mode = mode;
++		it->it_op |= IT_CREAT;
++	}
  	error = path_lookup(pathname, LOOKUP_PARENT, nd);
  	if (error)
  		return error;
-@@ -1049,7 +1181,7 @@ int open_namei(const char * pathname, in
+@@ -1038,7 +1163,7 @@ int open_namei(const char * pathname, in
  
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -700,11 +530,11 @@
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1058,10 +1190,11 @@ do_last:
+@@ -1047,10 +1172,11 @@ do_last:
  		goto exit;
  	}
  
-+	it->it_mode = mode;
++	it->it_create_mode = mode;
  	/* Negative dentry, just create the file */
  	if (!dentry->d_inode) {
 -		error = vfs_create(dir->d_inode, dentry,
@@ -714,16 +544,7 @@
  		up(&dir->d_inode->i_sem);
  		dput(nd->dentry);
  		nd->dentry = dentry;
-@@ -1086,7 +1219,7 @@ do_last:
- 		error = -ELOOP;
- 		if (flag & O_NOFOLLOW)
- 			goto exit_dput;
--		while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+		while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
- 	}
- 	error = -ENOENT;
- 	if (!dentry->d_inode)
-@@ -1165,7 +1298,7 @@ ok:
+@@ -1154,7 +1280,7 @@ ok:
  		if (!error) {
  			DQUOT_INIT(inode);
  			
@@ -732,7 +553,7 @@
  		}
  		put_write_access(inode);
  		if (error)
-@@ -1177,8 +1310,10 @@ ok:
+@@ -1166,8 +1292,10 @@ ok:
  	return 0;
  
  exit_dput:
@@ -743,24 +564,18 @@
  	path_release(nd);
  	return error;
  
-@@ -1197,7 +1332,16 @@ do_link:
+@@ -1186,7 +1314,10 @@ do_link:
  	 * are done. Procfs-like symlinks just set LAST_BIND.
  	 */
  	UPDATE_ATIME(dentry->d_inode);
-+	nd->it = it;
++	nd->intent = it;
  	error = dentry->d_inode->i_op->follow_link(dentry, nd);
-+	if (error) {
-+		intent_release(it);
-+	} else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
-+		/* vfs_follow_link was never called */
++	if (error)
 +		intent_release(it);
-+		path_release(nd);
-+		error = -ENOLINK;
-+	}
  	dput(dentry);
  	if (error)
  		return error;
-@@ -1219,13 +1363,20 @@ do_link:
+@@ -1208,13 +1339,20 @@ do_link:
  	}
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
@@ -783,7 +598,7 @@
  {
  	struct dentry *dentry;
  
-@@ -1233,7 +1384,7 @@ static struct dentry *lookup_create(stru
+@@ -1222,7 +1360,7 @@ static struct dentry *lookup_create(stru
  	dentry = ERR_PTR(-EEXIST);
  	if (nd->last_type != LAST_NORM)
  		goto fail;
@@ -792,7 +607,7 @@
  	if (IS_ERR(dentry))
  		goto fail;
  	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1289,7 +1440,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1278,7 +1416,16 @@ asmlinkage long sys_mknod(const char * f
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -810,7 +625,7 @@
  	error = PTR_ERR(dentry);
  
  	mode &= ~current->fs->umask;
-@@ -1310,6 +1470,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1299,6 +1446,7 @@ asmlinkage long sys_mknod(const char * f
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -818,23 +633,23 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1357,7 +1518,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1346,7 +1494,14 @@ asmlinkage long sys_mkdir(const char * p
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
 -		dentry = lookup_create(&nd, 1);
-+ 		if (nd.dentry->d_inode->i_op->mkdir_raw) {
-+ 			struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 			error = op->mkdir_raw(&nd, mode);
-+ 			/* the file system wants to use normal vfs path now */
-+ 			if (error != -EOPNOTSUPP)
-+ 				goto out2;
-+ 		}
++		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->mkdir_raw(&nd, mode);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
 +		dentry = lookup_create(&nd, 1, NULL);
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
  			error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1365,6 +1533,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1354,6 +1509,7 @@ asmlinkage long sys_mkdir(const char * p
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -842,42 +657,42 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1465,8 +1634,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1454,8 +1610,16 @@ asmlinkage long sys_rmdir(const char * p
  			error = -EBUSY;
  			goto exit1;
  	}
-+ 	if (nd.dentry->d_inode->i_op->rmdir_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
 +
-+ 		error = op->rmdir_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++		error = op->rmdir_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1524,8 +1701,15 @@ asmlinkage long sys_unlink(const char * 
+@@ -1513,8 +1677,15 @@ asmlinkage long sys_unlink(const char * 
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
-+ 	if (nd.dentry->d_inode->i_op->unlink_raw) {
-+ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+ 		error = op->unlink_raw(&nd);
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit1;
-+ 	}
++	if (nd.dentry->d_inode->i_op->unlink_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->unlink_raw(&nd);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit1;
++	}
  	down(&nd.dentry->d_inode->i_sem);
 -	dentry = lookup_hash(&nd.last, nd.dentry);
 +	dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
-@@ -1592,15 +1776,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1581,15 +1752,23 @@ asmlinkage long sys_symlink(const char *
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
  			goto out;
@@ -903,7 +718,7 @@
  		putname(to);
  	}
  	putname(from);
-@@ -1676,7 +1868,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1665,7 +1844,14 @@ asmlinkage long sys_link(const char * ol
  		error = -EXDEV;
  		if (old_nd.mnt != nd.mnt)
  			goto out_release;
@@ -919,7 +734,7 @@
  		error = PTR_ERR(new_dentry);
  		if (!IS_ERR(new_dentry)) {
  			error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1720,7 +1919,7 @@ exit:
+@@ -1709,7 +1895,7 @@ exit:
   *	   locking].
   */
  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -928,7 +743,7 @@
  {
  	int error;
  	struct inode *target;
-@@ -1799,7 +1998,7 @@ out_unlock:
+@@ -1788,7 +1974,7 @@ out_unlock:
  }
  
  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
@@ -937,18 +752,18 @@
  {
  	int error;
  
-@@ -1887,9 +2086,18 @@ static inline int do_rename(const char *
+@@ -1876,9 +2062,18 @@ static inline int do_rename(const char *
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
  
-+ 	if (old_dir->d_inode->i_op->rename_raw) {
++	if (old_dir->d_inode->i_op->rename_raw) {
 +		lock_kernel();
-+ 		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
 +		unlock_kernel();
-+ 		/* the file system wants to use normal vfs path now */
-+ 		if (error != -EOPNOTSUPP)
-+ 			goto exit2;
-+ 	}
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto exit2;
++	}
 +
  	double_lock(new_dir, old_dir);
  
@@ -957,7 +772,7 @@
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
-@@ -1905,16 +2113,16 @@ static inline int do_rename(const char *
+@@ -1894,16 +2089,16 @@ static inline int do_rename(const char *
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
@@ -976,7 +791,7 @@
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
-@@ -1965,20 +2173,28 @@ out:
+@@ -1954,20 +2149,26 @@ out:
  }
  
  static inline int
@@ -990,11 +805,9 @@
  		goto fail;
  
 +	if (it == NULL)
-+		it = nd->it;
-+	else if (it != nd->it)
-+		printk("it != nd->it: tell phil@clusterfs.com\n");
-+	if (it != NULL)
-+		it->it_int_flags |= IT_FL_FOLLOWED;
++		it = nd->intent;
++	else if (it != nd->intent)
++		printk("it != nd->intent: tell phil@clusterfs.com\n");
 +
  	if (*link == '/') {
  		path_release(nd);
@@ -1007,7 +820,7 @@
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
  		return res;
-@@ -2002,7 +2218,13 @@ fail:
+@@ -1991,7 +2192,13 @@ fail:
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
@@ -1022,7 +835,7 @@
  }
  
  /* get the link contents into pagecache */
-@@ -2044,7 +2266,7 @@ int page_follow_link(struct dentry *dent
+@@ -2033,7 +2240,7 @@ int page_follow_link(struct dentry *dent
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
@@ -1031,8 +844,123 @@
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
---- kernel-2.4.20-6chaos_18_7/fs/open.c~vfs_intent_2.4.20_chaos	Tue Jun 24 09:11:51 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/open.c	Wed Jul 16 04:21:21 2003
+--- linux-2.4.22-ac1/fs/namespace.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/namespace.c	2003-09-25 14:42:46.000000000 +0400
+@@ -98,6 +98,7 @@ static void detach_mnt(struct vfsmount *
+ {
+ 	old_nd->dentry = mnt->mnt_mountpoint;
+ 	old_nd->mnt = mnt->mnt_parent;
++	UNPIN(old_nd->dentry, old_nd->mnt, 1);
+ 	mnt->mnt_parent = mnt;
+ 	mnt->mnt_mountpoint = mnt->mnt_root;
+ 	list_del_init(&mnt->mnt_child);
+@@ -109,6 +110,7 @@ static void attach_mnt(struct vfsmount *
+ {
+ 	mnt->mnt_parent = mntget(nd->mnt);
+ 	mnt->mnt_mountpoint = dget(nd->dentry);
++	PIN(nd->dentry, nd->mnt, 1);
+ 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+ 	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+ 	nd->dentry->d_mounted++;
+@@ -488,14 +490,17 @@ static int do_loopback(struct nameidata 
+ {
+ 	struct nameidata old_nd;
+ 	struct vfsmount *mnt = NULL;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int err = mount_is_safe(nd);
+ 	if (err)
+ 		return err;
+ 	if (!old_name || !*old_name)
+ 		return -EINVAL;
+-	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
+-	if (err)
++	err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it);
++	if (err) {
++		intent_release(&it);
+ 		return err;
++	}
+ 
+ 	down_write(&current->namespace->sem);
+ 	err = -EINVAL;
+@@ -518,6 +523,7 @@ static int do_loopback(struct nameidata 
+ 	}
+ 
+ 	up_write(&current->namespace->sem);
++	intent_release(&it);
+ 	path_release(&old_nd);
+ 	return err;
+ }
+@@ -701,6 +707,7 @@ long do_mount(char * dev_name, char * di
+ 		  unsigned long flags, void *data_page)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int retval = 0;
+ 	int mnt_flags = 0;
+ 
+@@ -725,10 +732,11 @@ long do_mount(char * dev_name, char * di
+ 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
+ 
+ 	/* ... and get the mountpoint */
+-	retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
+-	if (retval)
++	retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
++	if (retval) {
++		intent_release(&it);
+ 		return retval;
+-
++	}
+ 	if (flags & MS_REMOUNT)
+ 		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+ 				    data_page);
+@@ -739,6 +747,8 @@ long do_mount(char * dev_name, char * di
+ 	else
+ 		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+ 				      dev_name, data_page);
++
++	intent_release(&it);
+ 	path_release(&nd);
+ 	return retval;
+ }
+@@ -904,6 +914,8 @@ asmlinkage long sys_pivot_root(const cha
+ {
+ 	struct vfsmount *tmp;
+ 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
++	struct lookup_intent new_it = { .it_op = IT_GETATTR };
++	struct lookup_intent old_it = { .it_op = IT_GETATTR };
+ 	int error;
+ 
+ 	if (!capable(CAP_SYS_ADMIN))
+@@ -911,14 +923,14 @@ asmlinkage long sys_pivot_root(const cha
+ 
+ 	lock_kernel();
+ 
+-	error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
++	error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it);
+ 	if (error)
+ 		goto out0;
+ 	error = -EINVAL;
+ 	if (!check_mnt(new_nd.mnt))
+ 		goto out1;
+ 
+-	error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
++	error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it);
+ 	if (error)
+ 		goto out1;
+ 
+@@ -973,8 +985,10 @@ out2:
+ 	up(&old_nd.dentry->d_inode->i_zombie);
+ 	up_write(&current->namespace->sem);
+ 	path_release(&user_nd);
++	intent_release(&old_it);
+ 	path_release(&old_nd);
+ out1:
++	intent_release(&new_it);
+ 	path_release(&new_nd);
+ out0:
+ 	unlock_kernel();
+--- linux-2.4.22-ac1/fs/open.c~vfs_intent-2.4.22-rh	2003-08-25 15:44:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/open.c	2003-09-25 14:42:46.000000000 +0400
 @@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
@@ -1054,7 +982,7 @@
  	int error;
  	struct iattr newattrs;
  
-@@ -108,7 +111,13 @@ int do_truncate(struct dentry *dentry, l
+@@ -109,7 +112,13 @@ int do_truncate(struct dentry *dentry, l
  	down(&inode->i_sem);
  	newattrs.ia_size = length;
  	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
@@ -1067,9 +995,9 @@
 +	} else
 +		error = notify_change(dentry, &newattrs);
  	up(&inode->i_sem);
+ 	up_write(&inode->i_alloc_sem);
  	return error;
- }
-@@ -118,12 +127,13 @@ static inline long do_sys_truncate(const
+@@ -120,12 +129,13 @@ static inline long do_sys_truncate(const
  	struct nameidata nd;
  	struct inode * inode;
  	int error;
@@ -1084,7 +1012,7 @@
  	if (error)
  		goto out;
  	inode = nd.dentry->d_inode;
-@@ -163,11 +173,13 @@ static inline long do_sys_truncate(const
+@@ -165,11 +175,13 @@ static inline long do_sys_truncate(const
  	error = locks_verify_truncate(inode, NULL, length);
  	if (!error) {
  		DQUOT_INIT(inode);
@@ -1099,7 +1027,7 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -215,7 +227,7 @@ static inline long do_sys_ftruncate(unsi
+@@ -217,7 +229,7 @@ static inline long do_sys_ftruncate(unsi
  
  	error = locks_verify_truncate(inode, file, length);
  	if (!error)
@@ -1108,7 +1036,7 @@
  out_putf:
  	fput(file);
  out:
-@@ -260,11 +272,13 @@ asmlinkage long sys_utime(char * filenam
+@@ -262,11 +274,13 @@ asmlinkage long sys_utime(char * filenam
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1123,7 +1051,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -279,11 +293,25 @@ asmlinkage long sys_utime(char * filenam
+@@ -281,11 +295,25 @@ asmlinkage long sys_utime(char * filenam
  			goto dput_and_out;
  
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1150,7 +1078,7 @@
  	error = notify_change(nd.dentry, &newattrs);
  dput_and_out:
  	path_release(&nd);
-@@ -304,12 +332,14 @@ asmlinkage long sys_utimes(char * filena
+@@ -306,12 +334,14 @@ asmlinkage long sys_utimes(char * filena
  	struct inode * inode;
  	struct iattr newattrs;
  
@@ -1166,7 +1094,7 @@
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
-@@ -324,7 +354,20 @@ asmlinkage long sys_utimes(char * filena
+@@ -326,7 +356,20 @@ asmlinkage long sys_utimes(char * filena
  		newattrs.ia_atime = times[0].tv_sec;
  		newattrs.ia_mtime = times[1].tv_sec;
  		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
@@ -1188,7 +1116,7 @@
  		if (current->fsuid != inode->i_uid &&
  		    (error = permission(inode,MAY_WRITE)) != 0)
  			goto dput_and_out;
-@@ -347,6 +390,7 @@ asmlinkage long sys_access(const char * 
+@@ -349,6 +392,7 @@ asmlinkage long sys_access(const char * 
  	int old_fsuid, old_fsgid;
  	kernel_cap_t old_cap;
  	int res;
@@ -1196,7 +1124,7 @@
  
  	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
  		return -EINVAL;
-@@ -364,13 +408,14 @@ asmlinkage long sys_access(const char * 
+@@ -366,13 +410,14 @@ asmlinkage long sys_access(const char * 
  	else
  		current->cap_effective = current->cap_permitted;
  
@@ -1212,18 +1140,18 @@
  		path_release(&nd);
  	}
  
-@@ -385,8 +430,9 @@ asmlinkage long sys_chdir(const char * f
+@@ -387,8 +432,9 @@ asmlinkage long sys_chdir(const char * f
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
 +	error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
  	if (error)
  		goto out;
  
-@@ -397,6 +443,7 @@ asmlinkage long sys_chdir(const char * f
+@@ -399,6 +445,7 @@ asmlinkage long sys_chdir(const char * f
  	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
  
  dput_and_out:
@@ -1231,11 +1159,11 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -436,9 +483,10 @@ asmlinkage long sys_chroot(const char * 
+@@ -438,9 +485,10 @@ asmlinkage long sys_chroot(const char * 
  {
  	int error;
  	struct nameidata nd;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
 -	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 -		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
@@ -1244,7 +1172,7 @@
  	if (error)
  		goto out;
  
-@@ -454,6 +502,7 @@ asmlinkage long sys_chroot(const char * 
+@@ -456,39 +504,56 @@ asmlinkage long sys_chroot(const char * 
  	set_fs_altroot();
  	error = 0;
  dput_and_out:
@@ -1252,26 +1180,102 @@
  	path_release(&nd);
  out:
  	return error;
-@@ -508,6 +557,18 @@ asmlinkage long sys_chmod(const char * f
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
+ }
  
+-asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++int chmod_common(struct dentry *dentry, mode_t mode)
+ {
+-	struct inode * inode;
+-	struct dentry * dentry;
+-	struct file * file;
+-	int err = -EBADF;
++	struct inode *inode = dentry->d_inode;
+ 	struct iattr newattrs;
++	int err = -EROFS;
+ 
+-	file = fget(fd);
+-	if (!file)
++	if (IS_RDONLY(inode))
+ 		goto out;
+ 
+-	dentry = file->f_dentry;
+-	inode = dentry->d_inode;
 +	if (inode->i_op->setattr_raw) {
-+		struct inode_operations *op = nd.dentry->d_inode->i_op;
-+
 +		newattrs.ia_mode = mode;
 +		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 +		newattrs.ia_valid |= ATTR_RAW;
-+		error = op->setattr_raw(inode, &newattrs);
++		err = inode->i_op->setattr_raw(inode, &newattrs);
 +		/* the file system wants to use normal vfs path now */
-+		if (error != -EOPNOTSUPP)
-+			goto dput_and_out;
++		if (err != -EOPNOTSUPP)
++			goto out;
 +	}
-+
- 	error = -EPERM;
+ 
+-	err = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto out_putf;
+ 	err = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -538,6 +599,20 @@ static int chown_common(struct dentry * 
+-		goto out_putf;
++		goto out;
++
+ 	if (mode == (mode_t) -1)
+ 		mode = inode->i_mode;
+ 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+ 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+ 	err = notify_change(dentry, &newattrs);
+ 
+-out_putf:
++out:
++	return err;
++}
++
++asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
++{
++	struct file * file;
++	int err = -EBADF;
++
++	file = fget(fd);
++	if (!file)
++		goto out;
++
++	err = chmod_common(file->f_dentry, mode);
++
+ 	fput(file);
+ out:
+ 	return err;
+@@ -497,30 +562,14 @@ out:
+ asmlinkage long sys_chmod(const char * filename, mode_t mode)
+ {
+ 	struct nameidata nd;
+-	struct inode * inode;
+ 	int error;
+-	struct iattr newattrs;
+ 
+ 	error = user_path_walk(filename, &nd);
+ 	if (error)
+ 		goto out;
+-	inode = nd.dentry->d_inode;
+-
+-	error = -EROFS;
+-	if (IS_RDONLY(inode))
+-		goto dput_and_out;
+ 
+-	error = -EPERM;
+-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+-		goto dput_and_out;
++	error = chmod_common(nd.dentry, mode);
+ 
+-	if (mode == (mode_t) -1)
+-		mode = inode->i_mode;
+-	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+-	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+-	error = notify_change(nd.dentry, &newattrs);
+-
+-dput_and_out:
+ 	path_release(&nd);
+ out:
+ 	return error;
+@@ -540,6 +589,20 @@ static int chown_common(struct dentry * 
  	error = -EROFS;
  	if (IS_RDONLY(inode))
  		goto out;
@@ -1292,19 +1296,15 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
-@@ -642,8 +717,9 @@ struct file *filp_open(const char * file
+@@ -644,6 +707,7 @@ struct file *filp_open(const char * file
  {
  	int namei_flags, error;
  	struct nameidata nd;
--	
--	flags &= ~O_DIRECT;
-+	struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-+
-+	//flags &= ~O_DIRECT;
++	struct lookup_intent it = { .it_op = IT_OPEN };
  
  	namei_flags = flags;
  	if ((namei_flags+1) & O_ACCMODE)
-@@ -651,14 +727,15 @@ struct file *filp_open(const char * file
+@@ -651,14 +715,15 @@ struct file *filp_open(const char * file
  	if (namei_flags & O_TRUNC)
  		namei_flags |= 2;
  
@@ -1325,7 +1325,7 @@
  {
  	struct file * f;
  	struct inode *inode;
-@@ -695,12 +772,15 @@ struct file *dentry_open(struct dentry *
+@@ -695,12 +760,15 @@ struct file *dentry_open(struct dentry *
  	}
  
  	if (f->f_op && f->f_op->open) {
@@ -1341,7 +1341,7 @@
  	return f;
  
  cleanup_all:
-@@ -715,11 +795,17 @@ cleanup_all:
+@@ -715,11 +783,17 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
@@ -1359,9 +1359,9 @@
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- kernel-2.4.20-6chaos_18_7/fs/stat.c~vfs_intent_2.4.20_chaos	Thu May 15 20:14:25 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/stat.c	Wed Jul 16 04:21:21 2003
-@@ -17,21 +17,23 @@
+--- linux-2.4.22-ac1/fs/stat.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:27.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/stat.c	2003-09-25 14:42:46.000000000 +0400
+@@ -17,10 +17,14 @@
   * Revalidate the inode. This is required for proper NFS attribute caching.
   */
  static __inline__ int
@@ -1370,65 +1370,105 @@
  {
  	struct inode * inode = dentry->d_inode;
 -	if (inode->i_op && inode->i_op->revalidate)
++        if (!inode)
++                return -ENOENT;
 +	if (inode->i_op && inode->i_op->revalidate_it)
 +		return inode->i_op->revalidate_it(dentry, it);
 +	else if (inode->i_op && inode->i_op->revalidate)
  		return inode->i_op->revalidate(dentry);
  	return 0;
  }
- 
--static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat, struct lookup_intent *it)
+@@ -143,13 +147,15 @@ static int cp_new_stat(struct inode * in
+ asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
  {
- 	int res = 0;
- 	unsigned int blocks, indirect;
- 	struct inode *inode = dentry->d_inode;
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
  
--	res = do_revalidate(dentry);
-+	res = do_revalidate(dentry, it);
- 	if (res)
- 		return res;
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -159,13 +165,15 @@ asmlinkage long sys_stat(char * filename
+ asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+ {
+ 	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 	int error;
  
-@@ -104,10 +106,12 @@ int vfs_stat(char *name, struct kstat *s
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -180,13 +188,15 @@ asmlinkage long sys_newstat(char * filen
+ asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
  {
  	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  	int error;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
  
--	error = user_path_walk(name, &nd);
-+	error = user_path_walk_it(name, &nd, &it);
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
  	if (!error) {
--		error = do_getattr(nd.mnt, nd.dentry, stat);
-+		error = do_getattr(nd.mnt, nd.dentry, stat, &it);
-+ 		intent_release(&it);
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_old_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
  		path_release(&nd);
  	}
  	return error;
-@@ -117,10 +121,12 @@ int vfs_lstat(char *name, struct kstat *
+@@ -197,13 +207,15 @@ asmlinkage long sys_lstat(char * filenam
+ asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
  {
  	struct nameidata nd;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  	int error;
-+ 	struct lookup_intent it = { .it_op = IT_GETATTR };
  
--	error = user_path_walk_link(name, &nd);
-+	error = user_path_walk_link_it(name, &nd, &it);
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
  	if (!error) {
--		error = do_getattr(nd.mnt, nd.dentry, stat);
-+		error = do_getattr(nd.mnt, nd.dentry, stat, &it);
-+ 		intent_release(&it);
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
  		path_release(&nd);
  	}
  	return error;
-@@ -132,7 +138,7 @@ int vfs_fstat(unsigned int fd, struct ks
- 	int error = -EBADF;
+@@ -224,7 +236,7 @@ asmlinkage long sys_fstat(unsigned int f
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
  
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_old_stat(dentry->d_inode, statbuf);
+ 		fput(f);
+@@ -243,7 +255,7 @@ asmlinkage long sys_newfstat(unsigned in
  	if (f) {
--		error = do_getattr(f->f_vfsmnt, f->f_dentry, stat);
-+		error = do_getattr(f->f_vfsmnt, f->f_dentry, stat, NULL);
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat(dentry->d_inode, statbuf);
  		fput(f);
- 	}
- 	return error;
-@@ -279,7 +285,7 @@ asmlinkage long sys_readlink(const char 
+@@ -265,7 +277,7 @@ asmlinkage long sys_readlink(const char 
  
  		error = -EINVAL;
  		if (inode->i_op && inode->i_op->readlink &&
@@ -1437,21 +1477,52 @@
  			UPDATE_ATIME(inode);
  			error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
  		}
---- kernel-2.4.20-6chaos_18_7/fs/proc/base.c~vfs_intent_2.4.20_chaos	Mon Jun 23 05:49:00 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/fs/proc/base.c	Wed Jul 16 04:21:21 2003
-@@ -465,6 +465,9 @@ static int proc_pid_follow_link(struct d
+@@ -341,12 +353,14 @@ asmlinkage long sys_stat64(char * filena
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
  
- 	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
- 	nd->last_type = LAST_BIND;
-+
-+	if (nd->it != NULL)
-+		nd->it->it_int_flags |= IT_FL_FOLLOWED;
- out:
+-	error = user_path_walk(filename, &nd);
++	error = user_path_walk_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
  	return error;
- }
---- kernel-2.4.20-6chaos_18_7/include/linux/dcache.h~vfs_intent_2.4.20_chaos	Tue Jun 24 10:31:16 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/include/linux/dcache.h	Wed Jul 16 04:22:30 2003
-@@ -6,6 +6,45 @@
+@@ -356,12 +370,14 @@ asmlinkage long sys_lstat64(char * filen
+ {
+ 	struct nameidata nd;
+ 	int error;
++	struct lookup_intent it = { .it_op = IT_GETATTR };
+ 
+-	error = user_path_walk_link(filename, &nd);
++	error = user_path_walk_link_it(filename, &nd, &it);
+ 	if (!error) {
+-		error = do_revalidate(nd.dentry);
++		error = do_revalidate(nd.dentry, &it);
+ 		if (!error)
+ 			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
++		intent_release(&it);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -376,7 +392,7 @@ asmlinkage long sys_fstat64(unsigned lon
+ 	if (f) {
+ 		struct dentry * dentry = f->f_dentry;
+ 
+-		err = do_revalidate(dentry);
++		err = do_revalidate(dentry, NULL);
+ 		if (!err)
+ 			err = cp_new_stat64(dentry->d_inode, statbuf);
+ 		fput(f);
+--- linux-2.4.22-ac1/include/linux/dcache.h~vfs_intent-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/dcache.h	2003-09-25 14:42:46.000000000 +0400
+@@ -6,6 +6,51 @@
  #include <asm/atomic.h>
  #include <linux/mount.h>
  #include <linux/kernel.h>
@@ -1472,18 +1543,24 @@
 +
 +#define INTENT_MAGIC 0x19620323
 +
-+struct lookup_intent {
-+	int it_op;
-+	void (*it_op_release)(struct lookup_intent *);
-+	int it_magic;
-+	int it_mode;
-+	int it_flags;
-+	int it_disposition;
-+	int it_status;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
 +	int it_int_flags;
-+	__u64 it_lock_handle[2];
-+	int it_lock_mode;
-+	void *it_data;
++};
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int     it_flags;
++	int     it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op, int flags)
@@ -1497,7 +1574,7 @@
  
  /*
   * linux/include/linux/dcache.h
-@@ -96,8 +135,22 @@ struct dentry_operations {
+@@ -95,8 +140,22 @@ struct dentry_operations {
  	int (*d_delete)(struct dentry *);
  	void (*d_release)(struct dentry *);
  	void (*d_iput)(struct dentry *, struct inode *);
@@ -1520,7 +1597,7 @@
  /* the dentry parameter passed to d_hash and d_compare is the parent
   * directory of the entries to be compared. It is used in case these
   * functions need any directory specific information for determining
-@@ -129,6 +182,7 @@ d_iput:		no		no		yes
+@@ -128,6 +187,7 @@ d_iput:		no		no		yes
  					 * s_nfsd_free_path semaphore will be down
  					 */
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
@@ -1528,9 +1605,17 @@
  
  extern spinlock_t dcache_lock;
  
---- kernel-2.4.20-6chaos_18_7/include/linux/fs.h~vfs_intent_2.4.20_chaos	Wed Jul 16 04:21:20 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/include/linux/fs.h	Wed Jul 16 04:21:21 2003
-@@ -337,6 +337,9 @@ extern void set_bh_page(struct buffer_he
+--- linux-2.4.22-ac1/include/linux/fs.h~vfs_intent-2.4.22-rh	2003-09-25 14:39:01.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/fs.h	2003-09-25 14:42:46.000000000 +0400
+@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
+ 
+ #define FMODE_READ 1
+ #define FMODE_WRITE 2
++#define FMODE_EXEC 4
+ 
+ #define READ 0
+ #define WRITE 1
+@@ -343,6 +344,9 @@ extern void set_bh_page(struct buffer_he
  #define ATTR_MTIME_SET	256
  #define ATTR_FORCE	512	/* Not a change, but a change it */
  #define ATTR_ATTR_FLAG	1024
@@ -1540,7 +1625,15 @@
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -574,6 +577,7 @@ struct file {
+@@ -481,6 +485,7 @@ struct inode {
+ 	struct pipe_inode_info	*i_pipe;
+ 	struct block_device	*i_bdev;
+ 	struct char_device	*i_cdev;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -583,6 +588,7 @@ struct file {
  
  	/* needed for tty driver, and maybe others */
  	void			*private_data;
@@ -1548,15 +1641,15 @@
  
  	/* preallocated helper kiobuf to speedup O_DIRECT */
  	struct kiobuf		*f_iobuf;
-@@ -701,6 +705,7 @@ struct nameidata {
+@@ -703,6 +709,7 @@ struct nameidata {
  	struct qstr last;
  	unsigned int flags;
  	int last_type;
-+	struct lookup_intent *it;
++	struct lookup_intent *intent;
  };
  
  /*
-@@ -821,7 +826,8 @@ extern int vfs_symlink(struct inode *, s
+@@ -823,7 +830,8 @@ extern int vfs_symlink(struct inode *, s
  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
  extern int vfs_rmdir(struct inode *, struct dentry *);
  extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1566,7 +1659,7 @@
  
  /*
   * File types
-@@ -881,21 +887,32 @@ struct file_operations {
+@@ -883,21 +891,32 @@ struct file_operations {
  
  struct inode_operations {
  	int (*create) (struct inode *,struct dentry *,int);
@@ -1595,11 +1688,11 @@
  	int (*revalidate) (struct dentry *);
 +	int (*revalidate_it) (struct dentry *, struct lookup_intent *);
  	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
  	int (*getattr) (struct dentry *, struct iattr *);
  	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
  	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
-@@ -1093,10 +1110,14 @@ static inline int get_lease(struct inode
+@@ -1094,10 +1113,14 @@ static inline int get_lease(struct inode
  
  asmlinkage long sys_open(const char *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
@@ -1615,7 +1708,7 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char *);
  
-@@ -1387,6 +1408,7 @@ typedef int (*read_actor_t)(read_descrip
+@@ -1388,6 +1411,7 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
@@ -1623,7 +1716,7 @@
  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
  extern int FASTCALL(path_walk(const char *, struct nameidata *));
  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
-@@ -1398,6 +1420,8 @@ extern struct dentry * lookup_one_len(co
+@@ -1399,6 +1423,8 @@ extern struct dentry * lookup_one_len(co
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
  #define user_path_walk(name,nd)	 __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
@@ -1632,7 +1725,7 @@
  
  extern void inode_init_once(struct inode *);
  extern void iput(struct inode *);
-@@ -1497,6 +1521,8 @@ extern struct file_operations generic_ro
+@@ -1538,6 +1564,8 @@ extern struct file_operations generic_ro
  
  extern int vfs_readlink(struct dentry *, char *, int, const char *);
  extern int vfs_follow_link(struct nameidata *, const char *);
@@ -1641,8 +1734,8 @@
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- kernel-2.4.20-6chaos_18_7/include/linux/fs_struct.h~vfs_intent_2.4.20_chaos	Tue Jun 24 10:31:16 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/include/linux/fs_struct.h	Wed Jul 16 04:21:21 2003
+--- linux-2.4.22-ac1/include/linux/fs_struct.h~vfs_intent-2.4.22-rh	2003-09-25 14:16:24.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/fs_struct.h	2003-09-25 14:42:46.000000000 +0400
 @@ -37,10 +37,12 @@ static inline void set_fs_root(struct fs
  	write_lock(&fs->lock);
  	old_root = fs->root;
@@ -1669,35 +1762,9 @@
  		dput(old_pwd);
  		mntput(old_pwdmnt);
  	}
---- kernel-2.4.20-6chaos_18_7/kernel/ksyms.c~vfs_intent_2.4.20_chaos	Wed Jul 16 04:21:20 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/kernel/ksyms.c	Wed Jul 16 04:21:21 2003
-@@ -299,6 +299,7 @@ EXPORT_SYMBOL(read_cache_page);
- EXPORT_SYMBOL(set_page_dirty);
- EXPORT_SYMBOL(vfs_readlink);
- EXPORT_SYMBOL(vfs_follow_link);
-+EXPORT_SYMBOL(vfs_follow_link_it);
- EXPORT_SYMBOL(page_readlink);
- EXPORT_SYMBOL(page_follow_link);
- EXPORT_SYMBOL(page_symlink_inode_operations);
---- kernel-2.4.20-6chaos_18_7/kernel/fork.c~vfs_intent_2.4.20_chaos	Thu Jun 19 10:06:09 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/kernel/fork.c	Wed Jul 16 04:21:21 2003
-@@ -385,10 +385,13 @@ static inline struct fs_struct *__copy_f
- 		fs->umask = old->umask;
- 		read_lock(&old->lock);
- 		fs->rootmnt = mntget(old->rootmnt);
-+		PIN(old->pwd, old->pwdmnt, 0);
-+		PIN(old->root, old->rootmnt, 1);
- 		fs->root = dget(old->root);
- 		fs->pwdmnt = mntget(old->pwdmnt);
- 		fs->pwd = dget(old->pwd);
- 		if (old->altroot) {
-+			PIN(old->altroot, old->altrootmnt, 1);
- 			fs->altrootmnt = mntget(old->altrootmnt);
- 			fs->altroot = dget(old->altroot);
- 		} else {
---- kernel-2.4.20-6chaos_18_7/kernel/exit.c~vfs_intent_2.4.20_chaos	Thu Jun 19 10:06:09 2003
-+++ kernel-2.4.20-6chaos_18_7-shaver/kernel/exit.c	Wed Jul 16 04:21:21 2003
-@@ -241,11 +241,14 @@ static inline void __put_fs_struct(struc
+--- linux-2.4.22-ac1/kernel/exit.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/kernel/exit.c	2003-09-25 14:42:46.000000000 +0400
+@@ -342,11 +342,14 @@ static inline void __put_fs_struct(struc
  {
  	/* No need to hold fs->lock if we are killing it */
  	if (atomic_dec_and_test(&fs->count)) {
@@ -1712,5 +1779,31 @@
  			dput(fs->altroot);
  			mntput(fs->altrootmnt);
  		}
+--- linux-2.4.22-ac1/kernel/fork.c~vfs_intent-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/kernel/fork.c	2003-09-25 14:42:46.000000000 +0400
+@@ -457,10 +457,13 @@ static inline struct fs_struct *__copy_f
+ 		fs->umask = old->umask;
+ 		read_lock(&old->lock);
+ 		fs->rootmnt = mntget(old->rootmnt);
++		PIN(old->pwd, old->pwdmnt, 0);
++		PIN(old->root, old->rootmnt, 1);
+ 		fs->root = dget(old->root);
+ 		fs->pwdmnt = mntget(old->pwdmnt);
+ 		fs->pwd = dget(old->pwd);
+ 		if (old->altroot) {
++			PIN(old->altroot, old->altrootmnt, 1);
+ 			fs->altrootmnt = mntget(old->altrootmnt);
+ 			fs->altroot = dget(old->altroot);
+ 		} else {
+--- linux-2.4.22-ac1/kernel/ksyms.c~vfs_intent-2.4.22-rh	2003-09-25 14:39:02.000000000 +0400
++++ linux-2.4.22-ac1-alexey/kernel/ksyms.c	2003-09-25 14:42:46.000000000 +0400
+@@ -295,6 +295,7 @@ EXPORT_SYMBOL(read_cache_page);
+ EXPORT_SYMBOL(set_page_dirty);
+ EXPORT_SYMBOL(vfs_readlink);
+ EXPORT_SYMBOL(vfs_follow_link);
++EXPORT_SYMBOL(vfs_follow_link_it);
+ EXPORT_SYMBOL(page_readlink);
+ EXPORT_SYMBOL(page_follow_link);
+ EXPORT_SYMBOL(page_symlink_inode_operations);
 
 _
diff --git a/lustre/kernel_patches/patches/vfs_intent_2.5.72_rev1.patch b/lustre/kernel_patches/patches/vfs_intent_2.5.72_rev1.patch
deleted file mode 100644
index 566dec9f607caed09c0863adc4a4485748c963df..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/patches/vfs_intent_2.5.72_rev1.patch
+++ /dev/null
@@ -1,1031 +0,0 @@
- fs/exec.c              |   15 ++-
- fs/namei.c             |  189 ++++++++++++++++++++++++++++++++++++++++++-------
- fs/namespace.c         |    2 
- fs/open.c              |   64 ++++++++++------
- fs/stat.c              |   28 +++++--
- fs/sysfs/inode.c       |    2 
- include/linux/dcache.h |   36 +++++++++
- include/linux/fs.h     |   10 ++
- include/linux/namei.h  |   19 +++-
- kernel/ksyms.c         |    8 ++
- net/sunrpc/rpc_pipe.c  |    6 -
- net/unix/af_unix.c     |    2 
- 12 files changed, 310 insertions(+), 71 deletions(-)
-
---- linux-2.5.73/fs/sysfs/inode.c~vfs_intent_2.5.72_rev1	2003-06-22 12:33:11.000000000 -0600
-+++ linux-2.5.73-braam/fs/sysfs/inode.c	2003-07-15 02:23:28.000000000 -0600
-@@ -81,7 +81,7 @@ struct dentry * sysfs_get_dentry(struct 
- 	qstr.name = name;
- 	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
--	return lookup_hash(&qstr,parent);
-+	return lookup_hash(&qstr,parent, NULL);
- }
- 
- void sysfs_hash_and_remove(struct dentry * dir, const char * name)
---- linux-2.5.73/fs/exec.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:41.000000000 -0600
-+++ linux-2.5.73-braam/fs/exec.c	2003-07-15 02:23:28.000000000 -0600
-@@ -116,6 +116,9 @@ asmlinkage long sys_uselib(const char __
- 	struct file * file;
- 	struct nameidata nd;
- 	int error;
-+        intent_init(&nd.it, IT_OPEN, O_RDONLY);
-+  
-+ 	error = user_path_walk_it(library, &nd);
- 
- 	error = user_path_walk(library, &nd);
- 	if (error)
-@@ -129,7 +132,7 @@ asmlinkage long sys_uselib(const char __
- 	if (error)
- 		goto exit;
- 
--	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+	file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.it);
- 	error = PTR_ERR(file);
- 	if (IS_ERR(file))
- 		goto out;
-@@ -453,8 +456,12 @@ static inline void free_arg_pages(struct
- struct file *open_exec(const char *name)
- {
- 	struct nameidata nd;
--	int err = path_lookup(name, LOOKUP_FOLLOW, &nd);
--	struct file *file = ERR_PTR(err);
-+ 	int err;
-+ 	struct file *file;
-+         
-+        intent_init(&nd.it, IT_OPEN, O_RDONLY);
-+        err = path_lookup(name, LOOKUP_FOLLOW, &nd);
-+        file = ERR_PTR(err);
- 
- 	if (!err) {
- 		struct inode *inode = nd.dentry->d_inode;
-@@ -466,7 +473,7 @@ struct file *open_exec(const char *name)
- 				err = -EACCES;
- 			file = ERR_PTR(err);
- 			if (!err) {
--				file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
-+				file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.it);
- 				if (!IS_ERR(file)) {
- 					err = deny_write_access(file);
- 					if (err) {
---- linux-2.5.73/fs/namei.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:41.000000000 -0600
-+++ linux-2.5.73-braam/fs/namei.c	2003-07-15 02:23:28.000000000 -0600
-@@ -263,8 +263,19 @@ int deny_write_access(struct file * file
- 	return 0;
- }
- 
-+void intent_release(struct lookup_intent *it)
-+{
-+        if (!it) 
-+                return;
-+        if (it->it_magic != INTENT_MAGIC)
-+                return;
-+        if (it->it_op_release)
-+                it->it_op_release(it);
-+}
-+
- void path_release(struct nameidata *nd)
- {
-+        intent_release(&nd->it);
- 	dput(nd->dentry);
- 	mntput(nd->mnt);
- }
-@@ -273,7 +284,7 @@ void path_release(struct nameidata *nd)
-  * Internal lookup() using the new generic dcache.
-  * SMP-safe
-  */
--static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct nameidata *nd)
- {
- 	struct dentry * dentry = __d_lookup(parent, name);
- 
-@@ -283,6 +294,14 @@ static struct dentry * cached_lookup(str
- 	if (!dentry)
- 		dentry = d_lookup(parent, name);
- 
-+	if (dentry && dentry->d_op && dentry->d_op->d_revalidate_nd) {
-+		if (!dentry->d_op->d_revalidate_nd(dentry, flags, nd) &&
-+		    !d_invalidate(dentry)) {
-+			dput(dentry);
-+			dentry = NULL;
-+		}
-+		return dentry;
-+	} else
- 	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
- 		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
- 			dput(dentry);
-@@ -336,7 +355,7 @@ ok:
-  * make sure that nobody added the entry to the dcache in the meantime..
-  * SMP-safe
-  */
--static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
-+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct nameidata *nd)
- {
- 	struct dentry * result;
- 	struct inode *dir = parent->d_inode;
-@@ -361,7 +380,10 @@ static struct dentry * real_lookup(struc
- 		struct dentry * dentry = d_alloc(parent, name);
- 		result = ERR_PTR(-ENOMEM);
- 		if (dentry) {
--			result = dir->i_op->lookup(dir, dentry);
-+			if (dir->i_op->lookup_it)
-+				result = dir->i_op->lookup_it(dir, dentry, nd);
-+			else
-+                                result = dir->i_op->lookup(dir, dentry);
- 			if (result)
- 				dput(dentry);
- 			else
-@@ -381,6 +403,12 @@ static struct dentry * real_lookup(struc
- 			dput(result);
- 			result = ERR_PTR(-ENOENT);
- 		}
-+	} else if (result->d_op && result->d_op->d_revalidate_nd) {
-+		if (!result->d_op->d_revalidate_nd(result, flags, nd) &&
-+		    !d_invalidate(result)) {
-+			dput(result);
-+			result = ERR_PTR(-ENOENT);
-+		}
- 	}
- 	return result;
- }
-@@ -455,15 +483,25 @@ static int follow_mount(struct vfsmount 
- 	return res;
- }
- 
--static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
-+static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
-+                              struct lookup_intent *it)
- {
- 	struct vfsmount *mounted;
- 
- 	spin_lock(&dcache_lock);
- 	mounted = lookup_mnt(*mnt, *dentry);
- 	if (mounted) {
-+		int opc = 0, mode = 0;
- 		*mnt = mntget(mounted);
- 		spin_unlock(&dcache_lock);
-+		if (it) {
-+			opc = it->it_op;
-+			mode = it->it_mode;
-+		}
-+		if (it) {
-+			it->it_op = opc;
-+			it->it_mode = mode;
-+		}
- 		dput(*dentry);
- 		mntput(mounted->mnt_parent);
- 		*dentry = dget(mounted->mnt_root);
-@@ -475,7 +513,7 @@ static inline int __follow_down(struct v
- 
- int follow_down(struct vfsmount **mnt, struct dentry **dentry)
- {
--	return __follow_down(mnt,dentry);
-+	return __follow_down(mnt,dentry,NULL);
- }
-  
- static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
-@@ -531,7 +569,8 @@ static int do_lookup(struct nameidata *n
- 
- 	if (!dentry)
- 		goto need_lookup;
--	if (dentry->d_op && dentry->d_op->d_revalidate)
-+	if (dentry->d_op && (dentry->d_op->d_revalidate || 
-+                             dentry->d_op->d_revalidate_nd) )
- 		goto need_revalidate;
- done:
- 	path->mnt = mnt;
-@@ -539,13 +578,17 @@ done:
- 	return 0;
- 
- need_lookup:
--	dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE);
-+	dentry = real_lookup(nd->dentry, name, LOOKUP_CONTINUE, nd);
- 	if (IS_ERR(dentry))
- 		goto fail;
- 	goto done;
- 
- need_revalidate:
--	if (dentry->d_op->d_revalidate(dentry, flags))
-+	if (dentry->d_op->d_revalidate && 
-+            dentry->d_op->d_revalidate(dentry, flags))
-+		goto done;
-+	if (dentry->d_op->d_revalidate_nd && 
-+            dentry->d_op->d_revalidate_nd(dentry, flags, nd))
- 		goto done;
- 	if (d_invalidate(dentry))
- 		goto done;
-@@ -556,6 +599,32 @@ fail:
- 	return PTR_ERR(dentry);
- }
- 
-+
-+static int revalidate_special(struct nameidata *nd)
-+{
-+        struct dentry *dentry = nd->dentry;
-+        int err, counter = 0;
-+
-+        if (!dentry->d_op || !dentry->d_op->d_revalidate_nd)
-+                return 0;
-+ revalidate_again:
-+        if (!dentry->d_op->d_revalidate_nd(dentry, 0, nd)) {
-+                struct dentry *new;
-+                if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC)))
-+                        return err;
-+                new = real_lookup(dentry->d_parent, &dentry->d_name, 0, nd);
-+                d_invalidate(dentry);
-+                dput(dentry);
-+                dentry = new;
-+                counter++;
-+                if (counter < 10)
-+                        goto revalidate_again;
-+                printk("excessive revalidate_it loops\n");
-+                return -ESTALE;
-+        }
-+        return 0;
-+}
-+
- /*
-  * Name resolution.
-  *
-@@ -655,7 +724,9 @@ int link_path_walk(const char * name, st
- 
- 		if (inode->i_op->follow_link) {
- 			mntget(next.mnt);
-+                        nd->flags |= LOOKUP_LINK_NOTLAST;
- 			err = do_follow_link(next.dentry, nd);
-+                        nd->flags &= ~LOOKUP_LINK_NOTLAST;
- 			dput(next.dentry);
- 			mntput(next.mnt);
- 			if (err)
-@@ -673,7 +744,7 @@ int link_path_walk(const char * name, st
- 			nd->dentry = next.dentry;
- 		}
- 		err = -ENOTDIR; 
--		if (!inode->i_op->lookup)
-+		if (!inode->i_op->lookup && !inode->i_op->lookup_it)
- 			break;
- 		continue;
- 		/* here ends the main loop */
-@@ -693,6 +764,11 @@ last_component:
- 				inode = nd->dentry->d_inode;
- 				/* fallthrough */
- 			case 1:
-+                                nd->flags |= LOOKUP_LAST;
-+                                err = revalidate_special(nd);
-+                                nd->flags &= ~LOOKUP_LAST;
-+                                if (err)
-+                                        break;
- 				goto return_base;
- 		}
- 		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-@@ -700,7 +776,9 @@ last_component:
- 			if (err < 0)
- 				break;
- 		}
-+                nd->flags |= LOOKUP_LAST;
- 		err = do_lookup(nd, &this, &next, 0);
-+                nd->flags &= ~LOOKUP_LAST;
- 		if (err)
- 			break;
- 		follow_mount(&next.mnt, &next.dentry);
-@@ -724,7 +802,8 @@ last_component:
- 			break;
- 		if (lookup_flags & LOOKUP_DIRECTORY) {
- 			err = -ENOTDIR; 
--			if (!inode->i_op || !inode->i_op->lookup)
-+			if (!inode->i_op || 
-+                            (!inode->i_op->lookup && !inode->i_op->lookup_it))
- 				break;
- 		}
- 		goto return_base;
-@@ -743,7 +822,7 @@ out_dput:
- 		dput(next.dentry);
- 		break;
- 	}
--	path_release(nd);
-+        path_release(nd);
- return_err:
- 	return err;
- }
-@@ -866,7 +945,8 @@ int path_lookup(const char *name, unsign
-  * needs parent already locked. Doesn't follow mounts.
-  * SMP-safe.
-  */
--struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, 
-+                            struct nameidata *nd)
- {
- 	struct dentry * dentry;
- 	struct inode *inode;
-@@ -889,13 +969,16 @@ struct dentry * lookup_hash(struct qstr 
- 			goto out;
- 	}
- 
--	dentry = cached_lookup(base, name, 0);
-+	dentry = cached_lookup(base, name, 0, nd);
- 	if (!dentry) {
- 		struct dentry *new = d_alloc(base, name);
- 		dentry = ERR_PTR(-ENOMEM);
- 		if (!new)
- 			goto out;
--		dentry = inode->i_op->lookup(inode, new);
-+		if (inode->i_op->lookup_it)
-+			dentry = inode->i_op->lookup_it(inode, new, nd);
-+		else
-+			dentry = inode->i_op->lookup(inode, new);
- 		if (!dentry)
- 			dentry = new;
- 		else
-@@ -906,7 +989,7 @@ out:
- }
- 
- /* SMP-safe */
--struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
- {
- 	unsigned long hash;
- 	struct qstr this;
-@@ -926,11 +1009,16 @@ struct dentry * lookup_one_len(const cha
- 	}
- 	this.hash = end_name_hash(hash);
- 
--	return lookup_hash(&this, base);
-+	return lookup_hash(&this, base, nd);
- access:
- 	return ERR_PTR(-EACCES);
- }
- 
-+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
-+{
-+        return lookup_one_len_it(name, base, len, NULL);
-+}
-+
- /*
-  *	namei()
-  *
-@@ -942,10 +1030,11 @@ access:
-  * that namei follows links, while lnamei does not.
-  * SMP-safe
-  */
--int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
-+int __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
- {
- 	char *tmp = getname(name);
- 	int err = PTR_ERR(tmp);
-+ 
- 
- 	if (!IS_ERR(tmp)) {
- 		err = path_lookup(tmp, flags, nd);
-@@ -954,6 +1043,12 @@ int __user_walk(const char __user *name,
- 	return err;
- }
- 
-+int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
-+{
-+        intent_init(&nd->it, IT_LOOKUP, 0);
-+        return __user_walk_it(name, flags, nd);
-+}
-+
- /*
-  * It's inline, so penalty for filesystems that don't use sticky bit is
-  * minimal.
-@@ -1097,6 +1192,32 @@ void unlock_rename(struct dentry *p1, st
- 	}
- }
- 
-+int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
-+{
-+	int error = may_create(dir, dentry);
-+
-+	if (error)
-+		return error;
-+
-+	if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_nd))
-+		return -EACCES;	/* shouldn't it be ENOSYS? */
-+	mode &= S_IALLUGO;
-+	mode |= S_IFREG;
-+	error = security_inode_create(dir, dentry, mode);
-+	if (error)
-+		return error;
-+	DQUOT_INIT(dir);
-+        if (dir->i_op->create_nd)
-+                error = dir->i_op->create_nd(dir, dentry, mode, nd);
-+        else 
-+                error = dir->i_op->create(dir, dentry, mode);
-+	if (!error) {
-+		inode_dir_notify(dir, DN_CREATE);
-+		security_inode_post_create(dir, dentry, mode);
-+	}
-+	return error;
-+}
-+
- int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
- {
- 	int error = may_create(dir, dentry);
-@@ -1236,6 +1357,9 @@ int open_namei(const char * pathname, in
- 	/*
- 	 * Create - we need to know the parent.
- 	 */
-+	nd->it.it_mode = mode;
-+	nd->it.it_op |= IT_CREAT;
-+		
- 	error = path_lookup(pathname, LOOKUP_PARENT, nd);
- 	if (error)
- 		return error;
-@@ -1251,7 +1375,9 @@ int open_namei(const char * pathname, in
- 
- 	dir = nd->dentry;
- 	down(&dir->d_inode->i_sem);
--	dentry = lookup_hash(&nd->last, nd->dentry);
-+        nd->flags |= LOOKUP_LAST;
-+	dentry = lookup_hash(&nd->last, nd->dentry, nd);
-+        nd->flags &= ~LOOKUP_LAST;
- 
- do_last:
- 	error = PTR_ERR(dentry);
-@@ -1259,12 +1385,13 @@ do_last:
- 		up(&dir->d_inode->i_sem);
- 		goto exit;
- 	}
--
-+        
-+	nd->it.it_mode = mode;
- 	/* Negative dentry, just create the file */
- 	if (!dentry->d_inode) {
- 		if (!IS_POSIXACL(dir->d_inode))
- 			mode &= ~current->fs->umask;
--		error = vfs_create(dir->d_inode, dentry, mode);
-+		error = vfs_create_it(dir->d_inode, dentry, mode, nd);
- 		up(&dir->d_inode->i_sem);
- 		dput(nd->dentry);
- 		nd->dentry = dentry;
-@@ -1289,7 +1416,7 @@ do_last:
- 		error = -ELOOP;
- 		if (flag & O_NOFOLLOW)
- 			goto exit_dput;
--		while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
-+		while (__follow_down(&nd->mnt,&dentry,&nd->it) && d_mountpoint(dentry));
- 	}
- 	error = -ENOENT;
- 	if (!dentry->d_inode)
-@@ -1354,7 +1481,9 @@ do_link:
- 	}
- 	dir = nd->dentry;
- 	down(&dir->d_inode->i_sem);
--	dentry = lookup_hash(&nd->last, nd->dentry);
-+        nd->flags |= LOOKUP_LAST;
-+	dentry = lookup_hash(&nd->last, nd->dentry, nd);
-+        nd->flags &= ~LOOKUP_LAST;
- 	putname(nd->last.name);
- 	goto do_last;
- }
-@@ -1368,7 +1497,7 @@ static struct dentry *lookup_create(stru
- 	dentry = ERR_PTR(-EEXIST);
- 	if (nd->last_type != LAST_NORM)
- 		goto fail;
--	dentry = lookup_hash(&nd->last, nd->dentry);
-+	dentry = lookup_hash(&nd->last, nd->dentry, nd);
- 	if (IS_ERR(dentry))
- 		goto fail;
- 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1600,7 +1729,7 @@ asmlinkage long sys_rmdir(const char __u
- 			goto exit1;
- 	}
- 	down(&nd.dentry->d_inode->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, &nd);
- 	error = PTR_ERR(dentry);
- 	if (!IS_ERR(dentry)) {
- 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1669,7 +1798,7 @@ asmlinkage long sys_unlink(const char __
- 	if (nd.last_type != LAST_NORM)
- 		goto exit1;
- 	down(&nd.dentry->d_inode->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, &nd);
- 	error = PTR_ERR(dentry);
- 	if (!IS_ERR(dentry)) {
- 		/* Why not before? Because we want correct error value */
-@@ -2019,7 +2148,7 @@ static inline int do_rename(const char *
- 
- 	trap = lock_rename(new_dir, old_dir);
- 
--	old_dentry = lookup_hash(&oldnd.last, old_dir);
-+	old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd);
- 	error = PTR_ERR(old_dentry);
- 	if (IS_ERR(old_dentry))
- 		goto exit3;
-@@ -2039,7 +2168,7 @@ static inline int do_rename(const char *
- 	error = -EINVAL;
- 	if (old_dentry == trap)
- 		goto exit4;
--	new_dentry = lookup_hash(&newnd.last, new_dir);
-+	new_dentry = lookup_hash(&newnd.last, new_dir, &newnd);
- 	error = PTR_ERR(new_dentry);
- 	if (IS_ERR(new_dentry))
- 		goto exit4;
-@@ -2104,7 +2233,10 @@ static inline int
- __vfs_follow_link(struct nameidata *nd, const char *link)
- {
- 	int res = 0;
-+        struct lookup_intent it = nd->it;
-+        int mode = it.it_mode;
- 	char *name;
-+
- 	if (IS_ERR(link))
- 		goto fail;
- 
-@@ -2114,6 +2246,9 @@ __vfs_follow_link(struct nameidata *nd, 
- 			/* weird __emul_prefix() stuff did it */
- 			goto out;
- 	}
-+
-+        intent_init(&nd->it, it.it_op, it.it_flags);
-+        nd->it.it_mode = mode;
- 	res = link_path_walk(link, nd);
- out:
- 	if (current->link_count || res || nd->last_type!=LAST_NORM)
---- linux-2.5.73/fs/namespace.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:57.000000000 -0600
-+++ linux-2.5.73-braam/fs/namespace.c	2003-07-15 02:23:28.000000000 -0600
-@@ -728,6 +728,7 @@ long do_mount(char * dev_name, char * di
- 	int retval = 0;
- 	int mnt_flags = 0;
- 
-+        intent_init(&nd.it, IT_LOOKUP, 0);
- 	/* Discard magic */
- 	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
- 		flags &= ~MS_MGC_MSK;
-@@ -937,6 +938,7 @@ void set_fs_pwd(struct fs_struct *fs, st
- 		mntput(old_pwdmnt);
- 	}
- }
-+EXPORT_SYMBOL(set_fs_pwd);
- 
- static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
- {
---- linux-2.5.73/fs/open.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:31.000000000 -0600
-+++ linux-2.5.73-braam/fs/open.c	2003-07-15 02:23:28.000000000 -0600
-@@ -200,7 +200,7 @@ static inline long do_sys_truncate(const
- 	struct nameidata nd;
- 	struct inode * inode;
- 	int error;
--
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 	error = -EINVAL;
- 	if (length < 0)	/* sorry, but loff_t says... */
- 		goto out;
-@@ -443,6 +443,7 @@ asmlinkage long sys_access(const char __
- 	int old_fsuid, old_fsgid;
- 	kernel_cap_t old_cap;
- 	int res;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
- 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
- 		return -EINVAL;
-@@ -474,6 +475,7 @@ asmlinkage long sys_access(const char __
- 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
- 		   && !special_file(nd.dentry->d_inode->i_mode))
- 			res = -EROFS;
-+		                
- 		path_release(&nd);
- 	}
- 
-@@ -488,6 +490,7 @@ asmlinkage long sys_chdir(const char __u
- {
- 	struct nameidata nd;
- 	int error;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
- 	error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
- 	if (error)
-@@ -539,6 +542,7 @@ asmlinkage long sys_chroot(const char __
- {
- 	struct nameidata nd;
- 	int error;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
- 	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
- 	if (error)
-@@ -611,7 +615,7 @@ asmlinkage long sys_chmod(const char __u
- 	error = -EROFS;
- 	if (IS_RDONLY(inode))
- 		goto dput_and_out;
--
-+	
- 	error = -EPERM;
- 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- 		goto dput_and_out;
-@@ -719,25 +723,8 @@ asmlinkage long sys_fchown(unsigned int 
-  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
-  * used by symlinks.
-  */
--struct file *filp_open(const char * filename, int flags, int mode)
--{
--	int namei_flags, error;
--	struct nameidata nd;
--
--	namei_flags = flags;
--	if ((namei_flags+1) & O_ACCMODE)
--		namei_flags++;
--	if (namei_flags & O_TRUNC)
--		namei_flags |= 2;
--
--	error = open_namei(filename, namei_flags, mode, &nd);
--	if (!error)
--		return dentry_open(nd.dentry, nd.mnt, flags);
--
--	return ERR_PTR(error);
--}
--
--struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, 
-+                            struct lookup_intent *it)
- {
- 	struct file * f;
- 	struct inode *inode;
-@@ -749,6 +736,7 @@ struct file *dentry_open(struct dentry *
- 		goto cleanup_dentry;
- 	f->f_flags = flags;
- 	f->f_mode = (flags+1) & O_ACCMODE;
-+        f->f_it = it;
- 	inode = dentry->d_inode;
- 	if (f->f_mode & FMODE_WRITE) {
- 		error = get_write_access(inode);
-@@ -767,6 +755,7 @@ struct file *dentry_open(struct dentry *
- 		error = f->f_op->open(inode,f);
- 		if (error)
- 			goto cleanup_all;
-+                intent_release(it);
- 	}
- 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
- 
-@@ -778,7 +767,7 @@ struct file *dentry_open(struct dentry *
- 				f = ERR_PTR(-EINVAL);
- 		}
- 	}
--
-+        
- 	return f;
- 
- cleanup_all:
-@@ -791,11 +780,42 @@ cleanup_all:
- cleanup_file:
- 	put_filp(f);
- cleanup_dentry:
-+        intent_release(it);
- 	dput(dentry);
- 	mntput(mnt);
- 	return ERR_PTR(error);
- }
- 
-+struct file *filp_open(const char * filename, int flags, int mode)
-+{
-+	int namei_flags, error;
-+	struct file * temp_filp;
-+        struct nameidata nd;
-+	intent_init(&nd.it, IT_OPEN, flags);
-+
-+	namei_flags = flags;
-+	if ((namei_flags+1) & O_ACCMODE)
-+		namei_flags++;
-+	if (namei_flags & O_TRUNC)
-+		namei_flags |= 2;
-+
-+	error = open_namei(filename, namei_flags, mode, &nd);
-+	if (!error) {
-+		temp_filp = dentry_open_it(nd.dentry, nd.mnt, flags, &nd.it);
-+		return temp_filp;
-+	}	
-+	return ERR_PTR(error);
-+}
-+
-+
-+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+{
-+        struct lookup_intent it;
-+	intent_init(&it, IT_LOOKUP, 0);
-+
-+        return dentry_open_it(dentry, mnt, flags, &it);
-+}
-+
- /*
-  * Find an empty file descriptor entry, and mark it busy.
-  */
---- linux-2.5.73/fs/stat.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:35.000000000 -0600
-+++ linux-2.5.73-braam/fs/stat.c	2003-07-15 02:23:28.000000000 -0600
-@@ -33,7 +33,7 @@ void generic_fillattr(struct inode *inod
- 	stat->blksize = inode->i_blksize;
- }
- 
--int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
- {
- 	struct inode *inode = dentry->d_inode;
- 	int retval;
-@@ -44,6 +44,8 @@ int vfs_getattr(struct vfsmount *mnt, st
- 
- 	if (inode->i_op->getattr)
- 		return inode->i_op->getattr(mnt, dentry, stat);
-+	if (inode->i_op->getattr_it)
-+		return inode->i_op->getattr_it(mnt, dentry, it, stat);
- 
- 	generic_fillattr(inode, stat);
- 	if (!stat->blksize) {
-@@ -56,15 +58,21 @@ int vfs_getattr(struct vfsmount *mnt, st
- 	return 0;
- }
- 
-+int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+{
-+        return vfs_getattr_it(mnt, dentry, NULL, stat);
-+}
-+
- int vfs_stat(char __user *name, struct kstat *stat)
- {
- 	struct nameidata nd;
- 	int error;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
--	error = user_path_walk(name, &nd);
-+	error = user_path_walk_it(name, &nd);
- 	if (!error) {
--		error = vfs_getattr(nd.mnt, nd.dentry, stat);
--		path_release(&nd);
-+		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.it, stat);
-+                path_release(&nd);
- 	}
- 	return error;
- }
-@@ -73,11 +81,12 @@ int vfs_lstat(char __user *name, struct 
- {
- 	struct nameidata nd;
- 	int error;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
--	error = user_path_walk_link(name, &nd);
-+	error = user_path_walk_link_it(name, &nd);
- 	if (!error) {
--		error = vfs_getattr(nd.mnt, nd.dentry, stat);
--		path_release(&nd);
-+		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.it, stat);
-+                path_release(&nd);
- 	}
- 	return error;
- }
-@@ -86,9 +95,12 @@ int vfs_fstat(unsigned int fd, struct ks
- {
- 	struct file *f = fget(fd);
- 	int error = -EBADF;
-+        struct nameidata nd;
-+	intent_init(&nd.it, IT_GETATTR, 0);
- 
- 	if (f) {
--		error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
-+		error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.it, stat);
-+                intent_release(&nd.it);
- 		fput(f);
- 	}
- 	return error;
---- linux-2.5.73/include/linux/dcache.h~vfs_intent_2.5.72_rev1	2003-06-22 12:33:35.000000000 -0600
-+++ linux-2.5.73-braam/include/linux/dcache.h	2003-07-15 02:23:28.000000000 -0600
-@@ -4,6 +4,7 @@
- #ifdef __KERNEL__
- 
- #include <asm/atomic.h>
-+#include <linux/string.h>
- #include <linux/list.h>
- #include <linux/spinlock.h>
- #include <linux/cache.h>
-@@ -12,6 +13,38 @@
- 
- struct vfsmount;
- 
-+#define IT_OPEN     (1)
-+#define IT_CREAT    (1<<1)
-+#define IT_READDIR  (1<<2)
-+#define IT_GETATTR  (1<<3)
-+#define IT_LOOKUP   (1<<4)
-+#define IT_UNLINK   (1<<5)
-+#define IT_GETXATTR (1<<6)
-+
-+struct nameidata;
-+#define INTENT_MAGIC 0x19620323
-+struct lookup_intent {
-+        int it_op;
-+        int it_mode;
-+        void (*it_op_release)(struct lookup_intent *);
-+        int it_magic;
-+        int it_flags;
-+        int it_disposition;
-+        int it_status;
-+        struct iattr *it_iattr;
-+        __u64 it_lock_handle[2];
-+        int it_lock_mode;
-+        void *it_data;
-+};
-+
-+static inline void intent_init(struct lookup_intent *it, int op, int flags)
-+{
-+        memset(it, 0, sizeof(*it));
-+        it->it_magic = INTENT_MAGIC;
-+        it->it_op = op;
-+        it->it_flags = flags;
-+}
-+
- /*
-  * linux/include/linux/dcache.h
-  *
-@@ -34,6 +67,8 @@ struct qstr {
- 	char name_str[0];
- };
- 
-+#include <linux/namei.h>
-+
- struct dentry_stat_t {
- 	int nr_dentry;
- 	int nr_unused;
-@@ -112,6 +147,7 @@ struct dentry_operations {
- 	int (*d_delete)(struct dentry *);
- 	void (*d_release)(struct dentry *);
- 	void (*d_iput)(struct dentry *, struct inode *);
-+ 	int (*d_revalidate_nd)(struct dentry *, int, struct nameidata *);
- };
- 
- /* the dentry parameter passed to d_hash and d_compare is the parent
---- linux-2.5.73/include/linux/fs.h~vfs_intent_2.5.72_rev1	2003-06-22 12:32:38.000000000 -0600
-+++ linux-2.5.73-braam/include/linux/fs.h	2003-07-15 02:23:28.000000000 -0600
-@@ -237,6 +237,8 @@ typedef int (get_blocks_t)(struct inode 
- #define ATTR_ATTR_FLAG	1024
- #define ATTR_KILL_SUID	2048
- #define ATTR_KILL_SGID	4096
-+#define ATTR_RAW       	8192    /* file system, not vfs will massage attrs */
-+#define ATTR_FROM_OPEN 	16384    /* called from open path, ie O_TRUNC */
- 
- /*
-  * This is the Inode Attributes structure, used for notify_change().  It
-@@ -445,6 +447,7 @@ struct file {
- 	/* Used by fs/eventpoll.c to link all the hooks to this file */
- 	struct list_head	f_ep_links;
- 	spinlock_t		f_ep_lock;
-+        struct lookup_intent    *f_it;
- };
- extern spinlock_t files_lock;
- #define file_list_lock() spin_lock(&files_lock);
-@@ -731,7 +734,10 @@ struct file_operations {
- 
- struct inode_operations {
- 	int (*create) (struct inode *,struct dentry *,int);
-+	int (*create_nd) (struct inode *,struct dentry *,int, struct nameidata *);
- 	struct dentry * (*lookup) (struct inode *,struct dentry *);
-+ 	struct dentry * (*lookup_it) (struct inode *,struct dentry *,
-+                                      struct nameidata *);
- 	int (*link) (struct dentry *,struct inode *,struct dentry *);
- 	int (*unlink) (struct inode *,struct dentry *);
- 	int (*symlink) (struct inode *,struct dentry *,const char *);
-@@ -745,7 +751,9 @@ struct inode_operations {
- 	void (*truncate) (struct inode *);
- 	int (*permission) (struct inode *, int);
- 	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
- 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-+ 	int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
- 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
- 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
- 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
-@@ -958,6 +966,7 @@ extern int register_filesystem(struct fi
- extern int unregister_filesystem(struct file_system_type *);
- extern struct vfsmount *kern_mount(struct file_system_type *);
- extern int may_umount(struct vfsmount *);
-+struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
- extern long do_mount(char *, char *, char *, unsigned long, void *);
- 
- extern int vfs_statfs(struct super_block *, struct kstatfs *);
-@@ -1025,6 +1034,7 @@ extern int do_truncate(struct dentry *, 
- 
- extern struct file *filp_open(const char *, int, int);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
-+extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
- extern int filp_close(struct file *, fl_owner_t id);
- extern char * getname(const char __user *);
- 
---- linux-2.5.73/include/linux/namei.h~vfs_intent_2.5.72_rev1	2003-06-22 12:32:40.000000000 -0600
-+++ linux-2.5.73-braam/include/linux/namei.h	2003-07-15 02:23:28.000000000 -0600
-@@ -11,6 +11,7 @@ struct nameidata {
- 	struct qstr	last;
- 	unsigned int	flags;
- 	int		last_type;
-+        struct lookup_intent it;
- };
- 
- /*
-@@ -27,24 +28,32 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
-  *  - locked when lookup done with dcache_lock held
-  */
- #define LOOKUP_FOLLOW		 1
--#define LOOKUP_DIRECTORY	 2
--#define LOOKUP_CONTINUE		 4
--#define LOOKUP_PARENT		16
--#define LOOKUP_NOALT		32
-+#define LOOKUP_DIRECTORY	 (1<<1)
-+#define LOOKUP_CONTINUE		 (1<<2)
-+#define LOOKUP_PARENT		 (1<<3)
-+#define LOOKUP_NOALT		 (1<<4)
-+#define LOOKUP_LAST		 (1<<5)
-+#define LOOKUP_LINK_NOTLAST	 (1<<6)
- 
- 
- extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
-+extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
- #define user_path_walk(name,nd) \
- 	__user_walk(name, LOOKUP_FOLLOW, nd)
- #define user_path_walk_link(name,nd) \
- 	__user_walk(name, 0, nd)
-+#define user_path_walk_it(name,nd) \
-+	__user_walk_it(name, LOOKUP_FOLLOW, nd)
-+#define user_path_walk_link_it(name,nd) \
-+	__user_walk_it(name, 0, nd)
-+extern void intent_release(struct lookup_intent *);
- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
- extern int FASTCALL(path_walk(const char *, struct nameidata *));
- extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
- extern void path_release(struct nameidata *);
- 
- extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
--extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
-+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct nameidata *);
- 
- extern int follow_down(struct vfsmount **, struct dentry **);
- extern int follow_up(struct vfsmount **, struct dentry **);
---- linux-2.5.73/kernel/ksyms.c~vfs_intent_2.5.72_rev1	2003-07-15 02:21:56.000000000 -0600
-+++ linux-2.5.73-braam/kernel/ksyms.c	2003-07-16 16:36:31.000000000 -0600
-@@ -377,6 +377,7 @@ EXPORT_SYMBOL(unregister_filesystem);
- EXPORT_SYMBOL(kern_mount);
- EXPORT_SYMBOL(__mntput);
- EXPORT_SYMBOL(may_umount);
-+EXPORT_SYMBOL(reparent_to_init);
- 
- /* executable format registration */
- EXPORT_SYMBOL(register_binfmt);
-@@ -406,6 +407,12 @@ EXPORT_SYMBOL(del_timer);
- EXPORT_SYMBOL(request_irq);
- EXPORT_SYMBOL(free_irq);
- 
-+/* lustre */
-+EXPORT_SYMBOL(do_kern_mount);
-+EXPORT_SYMBOL(exit_files);
-+//EXPORT_SYMBOL(kmem_cache_validate);
-+
-+
- /* waitqueue handling */
- EXPORT_SYMBOL(add_wait_queue);
- EXPORT_SYMBOL(add_wait_queue_exclusive);
-@@ -551,6 +558,7 @@ EXPORT_SYMBOL(sys_tz);
- EXPORT_SYMBOL(file_fsync);
- EXPORT_SYMBOL(fsync_buffers_list);
- EXPORT_SYMBOL(clear_inode);
-+EXPORT_SYMBOL(__iget);
- EXPORT_SYMBOL(init_special_inode);
- EXPORT_SYMBOL(new_inode);
- EXPORT_SYMBOL(__insert_inode_hash);
---- linux-2.5.73/net/unix/af_unix.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:57.000000000 -0600
-+++ linux-2.5.73-braam/net/unix/af_unix.c	2003-07-15 02:23:28.000000000 -0600
-@@ -702,7 +702,7 @@ static int unix_bind(struct socket *sock
- 		/*
- 		 * Do the final lookup.
- 		 */
--		dentry = lookup_hash(&nd.last, nd.dentry);
-+		dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 		err = PTR_ERR(dentry);
- 		if (IS_ERR(dentry))
- 			goto out_mknod_unlock;
---- linux-2.5.73/net/sunrpc/rpc_pipe.c~vfs_intent_2.5.72_rev1	2003-06-22 12:32:39.000000000 -0600
-+++ linux-2.5.73-braam/net/sunrpc/rpc_pipe.c	2003-07-15 02:23:28.000000000 -0600
-@@ -598,7 +598,7 @@ rpc_lookup_negative(char *path, struct n
- 		return ERR_PTR(error);
- 	dir = nd->dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd->last, nd->dentry);
-+	dentry = lookup_hash(&nd->last, nd->dentry, NULL);
- 	if (IS_ERR(dentry))
- 		goto out_err;
- 	if (dentry->d_inode) {
-@@ -660,7 +660,7 @@ rpc_rmdir(char *path)
- 		return error;
- 	dir = nd.dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 	if (IS_ERR(dentry)) {
- 		error = PTR_ERR(dentry);
- 		goto out_release;
-@@ -721,7 +721,7 @@ rpc_unlink(char *path)
- 		return error;
- 	dir = nd.dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 	if (IS_ERR(dentry)) {
- 		error = PTR_ERR(dentry);
- 		goto out_release;
-
-_
diff --git a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch
index 96a0839f57e4d8dd0747b959fb7caca09c256cd7..1f840e80565bdb166e171a2d4bb232a54fd04908 100644
--- a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch
+++ b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch
@@ -1,40 +1,27 @@
  fs/exec.c              |   18 +++++++---
- fs/namei.c             |   81 +++++++++++++++++++++++++++++++++++++++++++++----
+ fs/namei.c             |   86 +++++++++++++++++++++++++++++++++++++++++++++----
  fs/namespace.c         |    2 +
- fs/open.c              |   64 +++++++++++++++++++++++++-------------
- fs/stat.c              |   28 ++++++++++++----
- fs/sysfs/inode.c       |    2 -
+ fs/nfs/dir.c           |    4 +-
+ fs/open.c              |   62 +++++++++++++++++++++++------------
+ fs/stat.c              |   24 ++++++++++---
  include/linux/dcache.h |    3 +
- include/linux/fs.h     |    7 ++++
- include/linux/namei.h  |   59 ++++++++++++++++++++++++++++++++---
+ include/linux/fs.h     |    8 ++++
+ include/linux/namei.h  |   56 ++++++++++++++++++++++++++-----
  kernel/ksyms.c         |    8 ++++
- net/sunrpc/rpc_pipe.c  |    6 +--
- net/unix/af_unix.c     |    2 -
- 12 files changed, 228 insertions(+), 52 deletions(-)
+ 10 files changed, 222 insertions(+), 49 deletions(-)
 
---- linux-2.6.0-test1/fs/sysfs/inode.c~vfs_intent_2.6.0-test1	2003-07-13 21:37:23.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/sysfs/inode.c	2003-07-16 17:32:36.000000000 -0600
-@@ -81,7 +81,7 @@ struct dentry * sysfs_get_dentry(struct 
- 	qstr.name = name;
- 	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
--	return lookup_hash(&qstr,parent);
-+	return lookup_hash(&qstr,parent, NULL);
- }
- 
- void sysfs_hash_and_remove(struct dentry * dir, const char * name)
---- linux-2.6.0-test1/fs/exec.c~vfs_intent_2.6.0-test1	2003-07-16 17:19:46.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/exec.c	2003-07-16 18:42:40.000000000 -0600
+--- linux-2.6.0-test1/fs/exec.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:34.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/exec.c	2003-09-14 18:13:44.000000000 +0400
 @@ -116,8 +116,11 @@ asmlinkage long sys_uselib(const char __
  	struct file * file;
  	struct nameidata nd;
  	int error;
-+        intent_init(&nd.intent, IT_OPEN);
-+  
-+ 	error = user_path_walk_it(library, &nd);
++	intent_init(&nd.intent, IT_OPEN);
  
 -	nd.intent.open.flags = O_RDONLY;
-+	nd.intent.intent.open.flags = O_RDONLY;
++	error = user_path_walk_it(library, &nd);
++
++	nd.intent.it_flags = O_RDONLY;
  	error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
  	if (error)
  		goto out;
@@ -53,13 +40,13 @@
  	struct nameidata nd;
 -	int err = path_lookup(name, LOOKUP_FOLLOW, &nd);
 -	struct file *file = ERR_PTR(err);
-+ 	int err;
-+ 	struct file *file;
-+         
-+        intent_init(&nd.intent, IT_OPEN);
-+        nd.intent.intent.open.flags = O_RDONLY;
-+        err = path_lookup(name, LOOKUP_FOLLOW, &nd);
-+        file = ERR_PTR(err);
++	int err;
++	struct file *file;
++
++	intent_init(&nd.intent, IT_OPEN);
++	nd.intent.it_flags = O_RDONLY;
++	err = path_lookup(name, LOOKUP_FOLLOW, &nd);
++	file = ERR_PTR(err);
  
  	if (!err) {
  		struct inode *inode = nd.dentry->d_inode;
@@ -72,103 +59,116 @@
  				if (!IS_ERR(file)) {
  					err = deny_write_access(file);
  					if (err) {
---- linux-2.6.0-test1/fs/namei.c~vfs_intent_2.6.0-test1	2003-07-16 17:19:46.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/namei.c	2003-07-16 18:37:11.000000000 -0600
+--- linux-2.6.0-test1/fs/namei.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:34.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/namei.c	2003-09-14 18:15:11.000000000 +0400
 @@ -263,8 +263,19 @@ int deny_write_access(struct file * file
  	return 0;
  }
  
 +void intent_release(struct lookup_intent *it)
 +{
-+        if (!it) 
-+                return;
-+        if (it->it_magic != INTENT_MAGIC)
-+                return;
-+        if (it->it_op_release)
-+                it->it_op_release(it);
++	if (!it)
++		return;
++	if (it->it_magic != INTENT_MAGIC)
++		return;
++	if (it->it_op_release)
++		it->it_op_release(it);
 +}
 +
  void path_release(struct nameidata *nd)
  {
-+        intent_release(&nd->intent);
++	intent_release(&nd->intent);
  	dput(nd->dentry);
  	mntput(nd->mnt);
  }
-@@ -554,6 +565,32 @@ fail:
+@@ -340,7 +351,10 @@ static struct dentry * real_lookup(struc
+ {
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
++        int counter = 0;
+ 
++again:
++        counter++;
+ 	down(&dir->i_sem);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+@@ -379,7 +393,10 @@ static struct dentry * real_lookup(struc
+ 	if (result->d_op && result->d_op->d_revalidate) {
+ 		if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
+ 			dput(result);
+-			result = ERR_PTR(-ENOENT);
++                        if (counter > 10)
++                                result = ERR_PTR(-ESTALE);
++                        if (!IS_ERR(result))
++                                goto again;
+ 		}
+ 	}
+ 	return result;
+@@ -554,6 +571,31 @@ fail:
  	return PTR_ERR(dentry);
  }
  
-+
 +static int revalidate_special(struct nameidata *nd)
 +{
-+        struct dentry *dentry = nd->dentry;
-+        int err, counter = 0;
++	struct dentry *dentry = nd->dentry;
++	int err, counter = 0;
 +
-+        if (!dentry->d_op || !dentry->d_op->d_revalidate)
-+                return 0;
++	if (!dentry->d_op || !dentry->d_op->d_revalidate)
++		return 0;
 + revalidate_again:
-+        if (!dentry->d_op->d_revalidate(dentry, nd)) {
-+                struct dentry *new;
-+                if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC,nd)))
-+                        return err;
-+                new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
-+                d_invalidate(dentry);
-+                dput(dentry);
-+                dentry = new;
-+                counter++;
-+                if (counter < 10)
-+                        goto revalidate_again;
-+                printk("excessive revalidate_it loops\n");
-+                return -ESTALE;
-+        }
-+        return 0;
++	if (!dentry->d_op->d_revalidate(dentry, nd)) {
++		struct dentry *new;
++		if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC,nd)))
++			return err;
++		new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
++		d_invalidate(dentry);
++		dput(dentry);
++		dentry = new;
++		counter++;
++		if (counter < 10)
++			goto revalidate_again;
++		printk("excessive revalidate_it loops\n");
++		return -ESTALE;
++	}
++	return 0;
 +}
 +
  /*
   * Name resolution.
   *
-@@ -654,7 +691,9 @@ int link_path_walk(const char * name, st
+@@ -654,7 +696,9 @@ int link_path_walk(const char * name, st
  
  		if (inode->i_op->follow_link) {
  			mntget(next.mnt);
-+                        nd->flags |= LOOKUP_LINK_NOTLAST;
++			nd->flags |= LOOKUP_LINK_NOTLAST;
  			err = do_follow_link(next.dentry, nd);
-+                        nd->flags &= ~LOOKUP_LINK_NOTLAST;
++			nd->flags &= ~LOOKUP_LINK_NOTLAST;
  			dput(next.dentry);
  			mntput(next.mnt);
  			if (err)
-@@ -693,6 +732,11 @@ last_component:
+@@ -693,6 +737,11 @@ last_component:
  				inode = nd->dentry->d_inode;
  				/* fallthrough */
  			case 1:
-+                                nd->flags |= LOOKUP_LAST;
-+                                err = revalidate_special(nd);
-+                                nd->flags &= ~LOOKUP_LAST;
-+                                if (err)
-+                                        break;
- 				goto return_base;
++ 				nd->flags |= LOOKUP_LAST;
++ 				err = revalidate_special(nd);
++ 				nd->flags &= ~LOOKUP_LAST;
++ 				if (err)
++ 					break;
+ 				goto return_reval;
  		}
  		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-@@ -700,7 +744,9 @@ last_component:
+@@ -700,7 +749,9 @@ last_component:
  			if (err < 0)
  				break;
  		}
-+                nd->flags |= LOOKUP_LAST;
++		nd->flags |= LOOKUP_LAST;
  		err = do_lookup(nd, &this, &next);
-+                nd->flags &= ~LOOKUP_LAST;
++		nd->flags &= ~LOOKUP_LAST;
  		if (err)
  			break;
  		follow_mount(&next.mnt, &next.dentry);
-@@ -743,7 +789,7 @@ out_dput:
- 		dput(next.dentry);
- 		break;
- 	}
--	path_release(nd);
-+        path_release(nd);
- return_err:
- 	return err;
- }
-@@ -912,7 +958,7 @@ struct dentry * lookup_hash(struct qstr 
+@@ -926,7 +977,7 @@ struct dentry * lookup_hash(struct qstr 
  }
  
  /* SMP-safe */
@@ -177,7 +177,7 @@
  {
  	unsigned long hash;
  	struct qstr this;
-@@ -932,11 +978,16 @@ struct dentry * lookup_one_len(const cha
+@@ -946,11 +997,16 @@ struct dentry * lookup_one_len(const cha
  	}
  	this.hash = end_name_hash(hash);
  
@@ -189,13 +189,13 @@
  
 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
 +{
-+        return lookup_one_len_it(name, base, len, NULL);
++	return lookup_one_len_it(name, base, len, NULL);
 +}
 +
  /*
   *	namei()
   *
-@@ -948,10 +999,11 @@ access:
+@@ -962,11 +1018,12 @@ access:
   * that namei follows links, while lnamei does not.
   * SMP-safe
   */
@@ -204,90 +204,91 @@
  {
  	char *tmp = getname(name);
  	int err = PTR_ERR(tmp);
-+ 
  
++
  	if (!IS_ERR(tmp)) {
  		err = path_lookup(tmp, flags, nd);
-@@ -960,6 +1012,12 @@ int __user_walk(const char __user *name,
+ 		putname(tmp);
+@@ -974,6 +1031,12 @@ int __user_walk(const char __user *name,
  	return err;
  }
  
 +int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
 +{
-+        intent_init(&nd->intent, IT_LOOKUP);
-+        return __user_walk_it(name, flags, nd);
++	intent_init(&nd->intent, IT_LOOKUP);
++	return __user_walk_it(name, flags, nd);
 +}
 +
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
-@@ -1232,8 +1290,8 @@ int open_namei(const char * pathname, in
+@@ -1246,8 +1309,8 @@ int open_namei(const char * pathname, in
  		acc_mode |= MAY_APPEND;
  
  	/* Fill in the open() intent data */
 -	nd->intent.open.flags = flag;
 -	nd->intent.open.create_mode = mode;
-+	nd->intent.intent.open.flags = flag;
-+	nd->intent.intent.open.create_mode = mode;
++	nd->intent.it_flags = flag;
++	nd->intent.it_create_mode = mode;
  
  	/*
  	 * The simplest case - just a plain lookup.
-@@ -1249,6 +1307,7 @@ int open_namei(const char * pathname, in
+@@ -1263,6 +1326,7 @@ int open_namei(const char * pathname, in
  	/*
  	 * Create - we need to know the parent.
  	 */
-+        nd->intent.it_op |= IT_CREAT;
++	nd->intent.it_op |= IT_CREAT;
  	error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
  	if (error)
  		return error;
-@@ -1265,7 +1324,9 @@ int open_namei(const char * pathname, in
+@@ -1279,7 +1343,9 @@ int open_namei(const char * pathname, in
  	dir = nd->dentry;
  	nd->flags &= ~LOOKUP_PARENT;
  	down(&dir->d_inode->i_sem);
-+        nd->flags |= LOOKUP_LAST;
++	nd->flags |= LOOKUP_LAST;
  	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
-+        nd->flags &= ~LOOKUP_LAST;
++	nd->flags &= ~LOOKUP_LAST;
  
  do_last:
  	error = PTR_ERR(dentry);
-@@ -1370,7 +1431,9 @@ do_link:
+@@ -1384,7 +1450,9 @@ do_link:
  	}
  	dir = nd->dentry;
  	down(&dir->d_inode->i_sem);
-+        nd->flags |= LOOKUP_LAST;
++	nd->flags |= LOOKUP_LAST;
  	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
-+        nd->flags &= ~LOOKUP_LAST;
++	nd->flags &= ~LOOKUP_LAST;
  	putname(nd->last.name);
  	goto do_last;
  }
-@@ -2143,7 +2206,9 @@ static inline int
+@@ -2142,7 +2210,9 @@ static inline int
  __vfs_follow_link(struct nameidata *nd, const char *link)
  {
  	int res = 0;
-+        struct lookup_intent it = nd->intent;
++	struct lookup_intent it = nd->intent;
  	char *name;
 +
  	if (IS_ERR(link))
  		goto fail;
  
-@@ -2153,6 +2218,10 @@ __vfs_follow_link(struct nameidata *nd, 
+@@ -2152,6 +2222,10 @@ __vfs_follow_link(struct nameidata *nd, 
  			/* weird __emul_prefix() stuff did it */
  			goto out;
  	}
 +
-+        intent_init(&nd->intent, it.it_op);
-+        nd->intent.intent.open.flags = it.intent.open.flags;
-+        nd->intent.intent.open.create_mode = it.intent.open.create_mode;
++	intent_init(&nd->intent, it.it_op);
++	nd->intent.it_flags = it.it_flags;
++	nd->intent.it_create_mode = it.it_create_mode;
  	res = link_path_walk(link, nd);
  out:
  	if (current->link_count || res || nd->last_type!=LAST_NORM)
---- linux-2.6.0-test1/fs/namespace.c~vfs_intent_2.6.0-test1	2003-07-16 17:19:46.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/namespace.c	2003-07-16 18:44:38.000000000 -0600
+--- linux-2.6.0-test1/fs/namespace.c~vfs_intent_2.6.0-test1	2003-09-13 19:07:44.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/namespace.c	2003-09-14 18:13:44.000000000 +0400
 @@ -738,6 +738,7 @@ long do_mount(char * dev_name, char * di
  	int retval = 0;
  	int mnt_flags = 0;
  
-+        intent_init(&nd.intent, IT_LOOKUP);
++	intent_init(&nd.intent, IT_LOOKUP);
  	/* Discard magic */
  	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
  		flags &= ~MS_MGC_MSK;
@@ -299,8 +300,8 @@
  
  static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
  {
---- linux-2.6.0-test1/fs/open.c~vfs_intent_2.6.0-test1	2003-07-13 21:29:30.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/open.c	2003-07-16 18:39:48.000000000 -0600
+--- linux-2.6.0-test1/fs/open.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:34.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/open.c	2003-09-14 18:13:44.000000000 +0400
 @@ -200,7 +200,7 @@ static inline long do_sys_truncate(const
  	struct nameidata nd;
  	struct inode * inode;
@@ -322,7 +323,7 @@
  		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
  		   && !special_file(nd.dentry->d_inode->i_mode))
  			res = -EROFS;
-+		                
++
  		path_release(&nd);
  	}
  
@@ -374,8 +375,8 @@
 -}
 -
 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, 
-+                            struct lookup_intent *it)
++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags,
++			    struct lookup_intent *it)
  {
  	struct file * f;
  	struct inode *inode;
@@ -383,7 +384,7 @@
  		goto cleanup_dentry;
  	f->f_flags = flags;
  	f->f_mode = (flags+1) & O_ACCMODE;
-+        f->f_it = it;
++	f->f_it = it;
  	inode = dentry->d_inode;
  	if (f->f_mode & FMODE_WRITE) {
  		error = get_write_access(inode);
@@ -391,24 +392,15 @@
  		error = f->f_op->open(inode,f);
  		if (error)
  			goto cleanup_all;
-+                intent_release(it);
++		intent_release(it);
  	}
  	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
  
-@@ -778,7 +767,7 @@ struct file *dentry_open(struct dentry *
- 				f = ERR_PTR(-EINVAL);
- 		}
- 	}
--
-+        
- 	return f;
- 
- cleanup_all:
 @@ -791,11 +780,42 @@ cleanup_all:
  cleanup_file:
  	put_filp(f);
  cleanup_dentry:
-+        intent_release(it);
++	intent_release(it);
  	dput(dentry);
  	mntput(mnt);
  	return ERR_PTR(error);
@@ -418,7 +410,7 @@
 +{
 +	int namei_flags, error;
 +	struct file * temp_filp;
-+        struct nameidata nd;
++	struct nameidata nd;
 +	intent_init(&nd.intent, IT_OPEN);
 +
 +	namei_flags = flags;
@@ -438,17 +430,17 @@
 +
 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
 +{
-+        struct lookup_intent it;
++	struct lookup_intent it;
 +	intent_init(&it, IT_LOOKUP);
 +
-+        return dentry_open_it(dentry, mnt, flags, &it);
++	return dentry_open_it(dentry, mnt, flags, &it);
 +}
 +
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux-2.6.0-test1/fs/stat.c~vfs_intent_2.6.0-test1	2003-07-13 21:31:21.000000000 -0600
-+++ linux-2.6.0-test1-braam/fs/stat.c	2003-07-16 18:44:27.000000000 -0600
+--- linux-2.6.0-test1/fs/stat.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:11.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/stat.c	2003-09-14 18:13:44.000000000 +0400
 @@ -33,7 +33,7 @@ void generic_fillattr(struct inode *inod
  	stat->blksize = inode->i_blksize;
  }
@@ -467,13 +459,13 @@
  
  	generic_fillattr(inode, stat);
  	if (!stat->blksize) {
-@@ -56,15 +58,21 @@ int vfs_getattr(struct vfsmount *mnt, st
+@@ -56,14 +58,20 @@ int vfs_getattr(struct vfsmount *mnt, st
  	return 0;
  }
  
 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 +{
-+        return vfs_getattr_it(mnt, dentry, NULL, stat);
++	return vfs_getattr_it(mnt, dentry, NULL, stat);
 +}
 +
  int vfs_stat(char __user *name, struct kstat *stat)
@@ -486,13 +478,11 @@
 +	error = user_path_walk_it(name, &nd);
  	if (!error) {
 -		error = vfs_getattr(nd.mnt, nd.dentry, stat);
--		path_release(&nd);
 +		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
-+                path_release(&nd);
+ 		path_release(&nd);
  	}
  	return error;
- }
-@@ -73,11 +81,12 @@ int vfs_lstat(char __user *name, struct 
+@@ -73,10 +81,11 @@ int vfs_lstat(char __user *name, struct 
  {
  	struct nameidata nd;
  	int error;
@@ -502,28 +492,26 @@
 +	error = user_path_walk_link_it(name, &nd);
  	if (!error) {
 -		error = vfs_getattr(nd.mnt, nd.dentry, stat);
--		path_release(&nd);
 +		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
-+                path_release(&nd);
+ 		path_release(&nd);
  	}
  	return error;
- }
 @@ -86,9 +95,12 @@ int vfs_fstat(unsigned int fd, struct ks
  {
  	struct file *f = fget(fd);
  	int error = -EBADF;
-+        struct nameidata nd;
++	struct nameidata nd;
 +	intent_init(&nd.intent, IT_GETATTR);
  
  	if (f) {
 -		error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
 +		error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
-+                intent_release(&nd.intent);
++		intent_release(&nd.intent);
  		fput(f);
  	}
  	return error;
---- linux-2.6.0-test1/include/linux/dcache.h~vfs_intent_2.6.0-test1	2003-07-13 21:39:22.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/dcache.h	2003-07-16 17:49:49.000000000 -0600
+--- linux-2.6.0-test1/include/linux/dcache.h~vfs_intent_2.6.0-test1	2003-09-13 19:08:13.000000000 +0400
++++ linux-2.6.0-test1-alexey/include/linux/dcache.h	2003-09-14 18:13:44.000000000 +0400
 @@ -4,6 +4,7 @@
  #ifdef __KERNEL__
  
@@ -541,9 +529,9 @@
  struct dentry_stat_t {
  	int nr_dentry;
  	int nr_unused;
---- linux-2.6.0-test1/include/linux/fs.h~vfs_intent_2.6.0-test1	2003-07-16 17:19:46.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/fs.h	2003-07-16 17:32:36.000000000 -0600
-@@ -237,6 +237,8 @@ typedef int (get_blocks_t)(struct inode 
+--- linux-2.6.0-test1/include/linux/fs.h~vfs_intent_2.6.0-test1	2003-09-13 19:08:41.000000000 +0400
++++ linux-2.6.0-test1-alexey/include/linux/fs.h	2003-09-14 18:13:44.000000000 +0400
+@@ -240,6 +240,8 @@ typedef void (dio_iodone_t)(struct inode
  #define ATTR_ATTR_FLAG	1024
  #define ATTR_KILL_SUID	2048
  #define ATTR_KILL_SGID	4096
@@ -552,25 +540,33 @@
  
  /*
   * This is the Inode Attributes structure, used for notify_change().  It
-@@ -511,6 +513,7 @@ struct file {
+@@ -399,6 +401,7 @@ struct inode {
+ 	struct block_device	*i_bdev;
+ 	struct cdev		*i_cdev;
+ 	int			i_cindex;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -514,6 +517,7 @@ struct file {
  	/* Used by fs/eventpoll.c to link all the hooks to this file */
  	struct list_head	f_ep_links;
  	spinlock_t		f_ep_lock;
-+        struct lookup_intent    *f_it;
++	struct lookup_intent    *f_it;
  };
  extern spinlock_t files_lock;
  #define file_list_lock() spin_lock(&files_lock);
-@@ -816,7 +819,9 @@ struct inode_operations {
+@@ -814,7 +818,9 @@ struct inode_operations {
  	void (*truncate) (struct inode *);
  	int (*permission) (struct inode *, int, struct nameidata *);
  	int (*setattr) (struct dentry *, struct iattr *);
-+ 	int (*setattr_raw) (struct inode *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
  	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
-+ 	int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
++	int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
  	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
  	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
  	ssize_t (*listxattr) (struct dentry *, char *, size_t);
-@@ -1029,6 +1034,7 @@ extern int register_filesystem(struct fi
+@@ -1027,6 +1033,7 @@ extern int register_filesystem(struct fi
  extern int unregister_filesystem(struct file_system_type *);
  extern struct vfsmount *kern_mount(struct file_system_type *);
  extern int may_umount(struct vfsmount *);
@@ -578,7 +574,7 @@
  extern long do_mount(char *, char *, char *, unsigned long, void *);
  
  extern int vfs_statfs(struct super_block *, struct kstatfs *);
-@@ -1096,6 +1102,7 @@ extern int do_truncate(struct dentry *, 
+@@ -1094,6 +1101,7 @@ extern int do_truncate(struct dentry *, 
  
  extern struct file *filp_open(const char *, int, int);
  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
@@ -586,9 +582,9 @@
  extern int filp_close(struct file *, fl_owner_t id);
  extern char * getname(const char __user *);
  
---- linux-2.6.0-test1/include/linux/namei.h~vfs_intent_2.6.0-test1	2003-07-13 21:32:39.000000000 -0600
-+++ linux-2.6.0-test1-braam/include/linux/namei.h	2003-07-16 18:38:10.000000000 -0600
-@@ -2,25 +2,64 @@
+--- linux-2.6.0-test1/include/linux/namei.h~vfs_intent_2.6.0-test1	2003-07-24 15:52:31.000000000 +0400
++++ linux-2.6.0-test1-alexey/include/linux/namei.h	2003-09-14 18:13:44.000000000 +0400
+@@ -2,25 +2,55 @@
  #define _LINUX_NAMEI_H
  
  #include <linux/linkage.h>
@@ -596,7 +592,10 @@
  
  struct vfsmount;
 +struct nameidata;
-+
+ 
+-struct open_intent {
+-	int	flags;
+-	int	create_mode;
 +/* intent opcodes */
 +#define IT_OPEN     (1)
 +#define IT_CREAT    (1<<1)
@@ -606,41 +605,32 @@
 +#define IT_UNLINK   (1<<5)
 +#define IT_TRUNC    (1<<6)
 +#define IT_GETXATTR (1<<7)
- 
- struct open_intent {
- 	int	flags;
- 	int	create_mode;
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
  };
  
-+struct lustre_intent_data {
-+        int it_mode;
-+        int it_flags;
-+        int it_disposition;
-+        int it_status;
-+        struct iattr *it_iattr;
-+        __u64 it_lock_handle[2];
-+        int it_lock_mode;
-+        void *it_data;
-+};
-+
 +#define INTENT_MAGIC 0x19620323
 +struct lookup_intent {
-+        int it_magic;
-+        void (*it_op_release)(struct lookup_intent *);
-+        int it_op;
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int	it_flags;
++	int	it_create_mode;
 +	union {
-+		struct open_intent open;
-+	} intent;
-+        union {
-+                struct lustre_intent_data lustre;
-+        } fsdata;
++		struct lustre_intent_data lustre;
++	} d;
 +};
 +
 +static inline void intent_init(struct lookup_intent *it, int op)
 +{
-+        memset(it, 0, sizeof(*it));
-+        it->it_magic = INTENT_MAGIC;
-+        it->it_op = op;
++	memset(it, 0, sizeof(*it));
++	it->it_magic = INTENT_MAGIC;
++	it->it_op = op;
 +}
 +
  struct nameidata {
@@ -654,11 +644,11 @@
 -	union {
 -		struct open_intent open;
 -	} intent;
-+        struct lookup_intent intent;
++	struct lookup_intent intent;
  };
  
  /*
-@@ -41,6 +80,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
+@@ -41,6 +71,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
  #define LOOKUP_CONTINUE		 4
  #define LOOKUP_PARENT		16
  #define LOOKUP_NOALT		32
@@ -668,7 +658,7 @@
  /*
   * Intent data
   */
-@@ -49,6 +91,12 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
+@@ -49,6 +82,12 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
  #define LOOKUP_ACCESS		(0x0400)
  
  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
@@ -681,7 +671,7 @@
  #define user_path_walk(name,nd) \
  	__user_walk(name, LOOKUP_FOLLOW, nd)
  #define user_path_walk_link(name,nd) \
-@@ -60,7 +108,6 @@ extern void path_release(struct nameidat
+@@ -60,7 +99,6 @@ extern void path_release(struct nameidat
  
  extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
@@ -689,9 +679,9 @@
  extern int follow_down(struct vfsmount **, struct dentry **);
  extern int follow_up(struct vfsmount **, struct dentry **);
  
---- linux-2.6.0-test1/kernel/ksyms.c~vfs_intent_2.6.0-test1	2003-07-16 17:20:31.000000000 -0600
-+++ linux-2.6.0-test1-braam/kernel/ksyms.c	2003-07-16 17:32:36.000000000 -0600
-@@ -383,6 +383,7 @@ EXPORT_SYMBOL(unregister_filesystem);
+--- linux-2.6.0-test1/kernel/ksyms.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:42.000000000 +0400
++++ linux-2.6.0-test1-alexey/kernel/ksyms.c	2003-09-14 18:13:44.000000000 +0400
+@@ -382,6 +382,7 @@ EXPORT_SYMBOL(unregister_filesystem);
  EXPORT_SYMBOL(kern_mount);
  EXPORT_SYMBOL(__mntput);
  EXPORT_SYMBOL(may_umount);
@@ -699,7 +689,7 @@
  
  /* executable format registration */
  EXPORT_SYMBOL(register_binfmt);
-@@ -412,6 +413,12 @@ EXPORT_SYMBOL(del_timer);
+@@ -409,6 +410,12 @@ EXPORT_SYMBOL(proc_doulongvec_minmax);
  EXPORT_SYMBOL(request_irq);
  EXPORT_SYMBOL(free_irq);
  
@@ -712,7 +702,7 @@
  /* waitqueue handling */
  EXPORT_SYMBOL(add_wait_queue);
  EXPORT_SYMBOL(add_wait_queue_exclusive);
-@@ -559,6 +566,7 @@ EXPORT_SYMBOL(sys_tz);
+@@ -558,6 +565,7 @@ EXPORT_SYMBOL(sys_tz);
  EXPORT_SYMBOL(file_fsync);
  EXPORT_SYMBOL(fsync_buffers_list);
  EXPORT_SYMBOL(clear_inode);
@@ -720,45 +710,25 @@
  EXPORT_SYMBOL(init_special_inode);
  EXPORT_SYMBOL(new_inode);
  EXPORT_SYMBOL(__insert_inode_hash);
---- linux-2.6.0-test1/net/unix/af_unix.c~vfs_intent_2.6.0-test1	2003-07-13 21:35:16.000000000 -0600
-+++ linux-2.6.0-test1-braam/net/unix/af_unix.c	2003-07-16 17:32:36.000000000 -0600
-@@ -702,7 +702,7 @@ static int unix_bind(struct socket *sock
- 		/*
- 		 * Do the final lookup.
- 		 */
--		dentry = lookup_hash(&nd.last, nd.dentry);
-+		dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 		err = PTR_ERR(dentry);
- 		if (IS_ERR(dentry))
- 			goto out_mknod_unlock;
---- linux-2.6.0-test1/net/sunrpc/rpc_pipe.c~vfs_intent_2.6.0-test1	2003-07-13 21:32:34.000000000 -0600
-+++ linux-2.6.0-test1-braam/net/sunrpc/rpc_pipe.c	2003-07-16 17:32:36.000000000 -0600
-@@ -598,7 +598,7 @@ rpc_lookup_negative(char *path, struct n
- 		return ERR_PTR(error);
- 	dir = nd->dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd->last, nd->dentry);
-+	dentry = lookup_hash(&nd->last, nd->dentry, NULL);
- 	if (IS_ERR(dentry))
- 		goto out_err;
- 	if (dentry->d_inode) {
-@@ -660,7 +660,7 @@ rpc_rmdir(char *path)
- 		return error;
- 	dir = nd.dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 	if (IS_ERR(dentry)) {
- 		error = PTR_ERR(dentry);
- 		goto out_release;
-@@ -721,7 +721,7 @@ rpc_unlink(char *path)
- 		return error;
- 	dir = nd.dentry->d_inode;
- 	down(&dir->i_sem);
--	dentry = lookup_hash(&nd.last, nd.dentry);
-+	dentry = lookup_hash(&nd.last, nd.dentry, NULL);
- 	if (IS_ERR(dentry)) {
- 		error = PTR_ERR(dentry);
- 		goto out_release;
+--- linux-2.6.0-test1/fs/nfs/dir.c~vfs_intent_2.6.0-test1	2003-09-13 19:08:34.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/nfs/dir.c	2003-09-14 18:13:44.000000000 +0400
+@@ -652,7 +652,7 @@ int nfs_is_exclusive_create(struct inode
+ 		return 0;
+ 	if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
+ 		return 0;
+-	return (nd->intent.open.flags & O_EXCL) != 0;
++	return (nd->intent.it_flags & O_EXCL) != 0;
+ }
+ 
+ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+@@ -825,7 +825,7 @@ static int nfs_create(struct inode *dir,
+ 	attr.ia_valid = ATTR_MODE;
+ 
+ 	if (nd && (nd->flags & LOOKUP_CREATE))
+-		open_flags = nd->intent.open.flags;
++		open_flags = nd->intent.it_flags;
+ 
+ 	/*
+ 	 * The 0 argument passed into the create function should one day
 
 _
diff --git a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5dd86e0d1eb269232053d18b02463955eb15e296
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch
@@ -0,0 +1,754 @@
+ fs/exec.c              |   18 +++++++---
+ fs/namei.c             |   86 +++++++++++++++++++++++++++++++++++++++++++++----
+ fs/namespace.c         |    2 +
+ fs/nfs/dir.c           |    4 +-
+ fs/open.c              |   62 +++++++++++++++++++++++------------
+ fs/stat.c              |   24 ++++++++++---
+ include/linux/dcache.h |    3 +
+ include/linux/fs.h     |    8 ++++
+ include/linux/namei.h  |   56 ++++++++++++++++++++++++++-----
+ kernel/ksyms.c         |    8 ++++
+ 10 files changed, 222 insertions(+), 49 deletions(-)
+
+Index: linux-2.6.0-test6/fs/exec.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/exec.c	2003-10-07 15:14:14.000000000 +0800
++++ linux-2.6.0-test6/fs/exec.c	2003-10-07 15:33:15.000000000 +0800
+@@ -120,8 +120,11 @@
+ 	struct file * file;
+ 	struct nameidata nd;
+ 	int error;
++	intent_init(&nd.intent, IT_OPEN);
+ 
+-	nd.intent.open.flags = O_RDONLY;
++	error = user_path_walk_it(library, &nd);
++
++	nd.intent.it_flags = O_RDONLY;
+ 	error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
+ 	if (error)
+ 		goto out;
+@@ -134,7 +137,7 @@
+ 	if (error)
+ 		goto exit;
+ 
+-	file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++	file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
+ 	error = PTR_ERR(file);
+ 	if (IS_ERR(file))
+ 		goto out;
+@@ -471,8 +474,13 @@
+ struct file *open_exec(const char *name)
+ {
+ 	struct nameidata nd;
+-	int err = path_lookup(name, LOOKUP_FOLLOW, &nd);
+-	struct file *file = ERR_PTR(err);
++	int err;
++	struct file *file;
++
++	intent_init(&nd.intent, IT_OPEN);
++	nd.intent.it_flags = O_RDONLY;
++	err = path_lookup(name, LOOKUP_FOLLOW, &nd);
++	file = ERR_PTR(err);
+ 
+ 	if (!err) {
+ 		struct inode *inode = nd.dentry->d_inode;
+@@ -484,7 +492,7 @@
+ 				err = -EACCES;
+ 			file = ERR_PTR(err);
+ 			if (!err) {
+-				file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++				file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
+ 				if (!IS_ERR(file)) {
+ 					err = deny_write_access(file);
+ 					if (err) {
+Index: linux-2.6.0-test6/fs/namei.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/namei.c	2003-10-07 15:14:14.000000000 +0800
++++ linux-2.6.0-test6/fs/namei.c	2003-10-07 15:33:15.000000000 +0800
+@@ -264,8 +264,19 @@
+ 	return 0;
+ }
+ 
++void intent_release(struct lookup_intent *it)
++{
++	if (!it)
++		return;
++	if (it->it_magic != INTENT_MAGIC)
++		return;
++	if (it->it_op_release)
++		it->it_op_release(it);
++}
++
+ void path_release(struct nameidata *nd)
+ {
++	intent_release(&nd->intent);
+ 	dput(nd->dentry);
+ 	mntput(nd->mnt);
+ }
+@@ -342,7 +353,10 @@
+ {
+ 	struct dentry * result;
+ 	struct inode *dir = parent->d_inode;
++        int counter = 0;
+ 
++again:
++        counter++;
+ 	down(&dir->i_sem);
+ 	/*
+ 	 * First re-do the cached lookup just in case it was created
+@@ -381,7 +395,10 @@
+ 	if (result->d_op && result->d_op->d_revalidate) {
+ 		if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
+ 			dput(result);
+-			result = ERR_PTR(-ENOENT);
++                        if (counter > 10)
++                                result = ERR_PTR(-ESTALE);
++                        if (!IS_ERR(result))
++                                goto again;
+ 		}
+ 	}
+ 	return result;
+@@ -556,6 +573,31 @@
+ 	return PTR_ERR(dentry);
+ }
+ 
++static int revalidate_special(struct nameidata *nd)
++{
++	struct dentry *dentry = nd->dentry;
++	int err, counter = 0;
++
++	if (!dentry->d_op || !dentry->d_op->d_revalidate)
++		return 0;
++ revalidate_again:
++	if (!dentry->d_op->d_revalidate(dentry, nd)) {
++		struct dentry *new;
++		if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC,nd)))
++			return err;
++		new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
++		d_invalidate(dentry);
++		dput(dentry);
++		dentry = new;
++		counter++;
++		if (counter < 10)
++			goto revalidate_again;
++		printk("excessive revalidate_it loops\n");
++		return -ESTALE;
++	}
++	return 0;
++}
++
+ /*
+  * Name resolution.
+  *
+@@ -656,7 +698,9 @@
+ 
+ 		if (inode->i_op->follow_link) {
+ 			mntget(next.mnt);
++			nd->flags |= LOOKUP_LINK_NOTLAST;
+ 			err = do_follow_link(next.dentry, nd);
++			nd->flags &= ~LOOKUP_LINK_NOTLAST;
+ 			dput(next.dentry);
+ 			mntput(next.mnt);
+ 			if (err)
+@@ -695,6 +739,11 @@
+ 				inode = nd->dentry->d_inode;
+ 				/* fallthrough */
+ 			case 1:
++ 				nd->flags |= LOOKUP_LAST;
++ 				err = revalidate_special(nd);
++ 				nd->flags &= ~LOOKUP_LAST;
++ 				if (err)
++ 					break;
+ 				goto return_reval;
+ 		}
+ 		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
+@@ -702,7 +751,9 @@
+ 			if (err < 0)
+ 				break;
+ 		}
++		nd->flags |= LOOKUP_LAST;
+ 		err = do_lookup(nd, &this, &next);
++		nd->flags &= ~LOOKUP_LAST;
+ 		if (err)
+ 			break;
+ 		follow_mount(&next.mnt, &next.dentry);
+@@ -928,7 +979,7 @@
+ }
+ 
+ /* SMP-safe */
+-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
+ {
+ 	unsigned long hash;
+ 	struct qstr this;
+@@ -948,11 +999,16 @@
+ 	}
+ 	this.hash = end_name_hash(hash);
+ 
+-	return lookup_hash(&this, base);
++	return __lookup_hash(&this, base, nd);
+ access:
+ 	return ERR_PTR(-EACCES);
+ }
+ 
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++	return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *	namei()
+  *
+@@ -964,11 +1020,12 @@
+  * that namei follows links, while lnamei does not.
+  * SMP-safe
+  */
+-int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
++int __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
+ {
+ 	char *tmp = getname(name);
+ 	int err = PTR_ERR(tmp);
+ 
++
+ 	if (!IS_ERR(tmp)) {
+ 		err = path_lookup(tmp, flags, nd);
+ 		putname(tmp);
+@@ -976,6 +1033,12 @@
+ 	return err;
+ }
+ 
++int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
++{
++	intent_init(&nd->intent, IT_LOOKUP);
++	return __user_walk_it(name, flags, nd);
++}
++
+ /*
+  * It's inline, so penalty for filesystems that don't use sticky bit is
+  * minimal.
+@@ -1248,8 +1311,8 @@
+ 		acc_mode |= MAY_APPEND;
+ 
+ 	/* Fill in the open() intent data */
+-	nd->intent.open.flags = flag;
+-	nd->intent.open.create_mode = mode;
++	nd->intent.it_flags = flag;
++	nd->intent.it_create_mode = mode;
+ 
+ 	/*
+ 	 * The simplest case - just a plain lookup.
+@@ -1265,6 +1328,7 @@
+ 	/*
+ 	 * Create - we need to know the parent.
+ 	 */
++	nd->intent.it_op |= IT_CREAT;
+ 	error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
+ 	if (error)
+ 		return error;
+@@ -1281,7 +1345,9 @@
+ 	dir = nd->dentry;
+ 	nd->flags &= ~LOOKUP_PARENT;
+ 	down(&dir->d_inode->i_sem);
++	nd->flags |= LOOKUP_LAST;
+ 	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
++	nd->flags &= ~LOOKUP_LAST;
+ 
+ do_last:
+ 	error = PTR_ERR(dentry);
+@@ -1386,7 +1452,9 @@
+ 	}
+ 	dir = nd->dentry;
+ 	down(&dir->d_inode->i_sem);
++	nd->flags |= LOOKUP_LAST;
+ 	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
++	nd->flags &= ~LOOKUP_LAST;
+ 	putname(nd->last.name);
+ 	goto do_last;
+ }
+@@ -2148,7 +2216,9 @@
+ __vfs_follow_link(struct nameidata *nd, const char *link)
+ {
+ 	int res = 0;
++	struct lookup_intent it = nd->intent;
+ 	char *name;
++
+ 	if (IS_ERR(link))
+ 		goto fail;
+ 
+@@ -2158,6 +2228,10 @@
+ 			/* weird __emul_prefix() stuff did it */
+ 			goto out;
+ 	}
++
++	intent_init(&nd->intent, it.it_op);
++	nd->intent.it_flags = it.it_flags;
++	nd->intent.it_create_mode = it.it_create_mode;
+ 	res = link_path_walk(link, nd);
+ out:
+ 	if (current->link_count || res || nd->last_type!=LAST_NORM)
+Index: linux-2.6.0-test6/fs/namespace.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/namespace.c	2003-09-28 08:50:31.000000000 +0800
++++ linux-2.6.0-test6/fs/namespace.c	2003-10-07 15:33:15.000000000 +0800
+@@ -738,6 +738,7 @@
+ 	int retval = 0;
+ 	int mnt_flags = 0;
+ 
++	intent_init(&nd.intent, IT_LOOKUP);
+ 	/* Discard magic */
+ 	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
+ 		flags &= ~MS_MGC_MSK;
+@@ -947,6 +948,7 @@
+ 		mntput(old_pwdmnt);
+ 	}
+ }
++EXPORT_SYMBOL(set_fs_pwd);
+ 
+ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
+ {
+Index: linux-2.6.0-test6/fs/open.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/open.c	2003-10-07 15:14:14.000000000 +0800
++++ linux-2.6.0-test6/fs/open.c	2003-10-07 15:33:15.000000000 +0800
+@@ -202,7 +202,7 @@
+ 	struct nameidata nd;
+ 	struct inode * inode;
+ 	int error;
+-
++	intent_init(&nd.intent, IT_GETATTR);
+ 	error = -EINVAL;
+ 	if (length < 0)	/* sorry, but loff_t says... */
+ 		goto out;
+@@ -461,6 +461,7 @@
+ 	int old_fsuid, old_fsgid;
+ 	kernel_cap_t old_cap;
+ 	int res;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+ 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
+ 		return -EINVAL;
+@@ -492,6 +493,7 @@
+ 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+ 		   && !special_file(nd.dentry->d_inode->i_mode))
+ 			res = -EROFS;
++
+ 		path_release(&nd);
+ 	}
+ 
+@@ -506,6 +508,7 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+ 	error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
+ 	if (error)
+@@ -557,6 +560,7 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+ 	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
+ 	if (error)
+@@ -629,7 +633,7 @@
+ 	error = -EROFS;
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+-
++	
+ 	error = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ 		goto dput_and_out;
+@@ -737,25 +741,8 @@
+  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
+  * used by symlinks.
+  */
+-struct file *filp_open(const char * filename, int flags, int mode)
+-{
+-	int namei_flags, error;
+-	struct nameidata nd;
+-
+-	namei_flags = flags;
+-	if ((namei_flags+1) & O_ACCMODE)
+-		namei_flags++;
+-	if (namei_flags & O_TRUNC)
+-		namei_flags |= 2;
+-
+-	error = open_namei(filename, namei_flags, mode, &nd);
+-	if (!error)
+-		return dentry_open(nd.dentry, nd.mnt, flags);
+-
+-	return ERR_PTR(error);
+-}
+-
+-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags,
++			    struct lookup_intent *it)
+ {
+ 	struct file * f;
+ 	struct inode *inode;
+@@ -767,6 +754,7 @@
+ 		goto cleanup_dentry;
+ 	f->f_flags = flags;
+ 	f->f_mode = (flags+1) & O_ACCMODE;
++	f->f_it = it;
+ 	inode = dentry->d_inode;
+ 	if (f->f_mode & FMODE_WRITE) {
+ 		error = get_write_access(inode);
+@@ -786,6 +774,7 @@
+ 		error = f->f_op->open(inode,f);
+ 		if (error)
+ 			goto cleanup_all;
++		intent_release(it);
+ 	}
+ 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ 
+@@ -810,11 +799,42 @@
+ cleanup_file:
+ 	put_filp(f);
+ cleanup_dentry:
++	intent_release(it);
+ 	dput(dentry);
+ 	mntput(mnt);
+ 	return ERR_PTR(error);
+ }
+ 
++struct file *filp_open(const char * filename, int flags, int mode)
++{
++	int namei_flags, error;
++	struct file * temp_filp;
++	struct nameidata nd;
++	intent_init(&nd.intent, IT_OPEN);
++
++	namei_flags = flags;
++	if ((namei_flags+1) & O_ACCMODE)
++		namei_flags++;
++	if (namei_flags & O_TRUNC)
++		namei_flags |= 2;
++
++	error = open_namei(filename, namei_flags, mode, &nd);
++	if (!error) {
++		temp_filp = dentry_open_it(nd.dentry, nd.mnt, flags, &nd.intent);
++		return temp_filp;
++	}	
++	return ERR_PTR(error);
++}
++
++
++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++{
++	struct lookup_intent it;
++	intent_init(&it, IT_LOOKUP);
++
++	return dentry_open_it(dentry, mnt, flags, &it);
++}
++
+ /*
+  * Find an empty file descriptor entry, and mark it busy.
+  */
+Index: linux-2.6.0-test6/fs/stat.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/stat.c	2003-09-28 08:50:10.000000000 +0800
++++ linux-2.6.0-test6/fs/stat.c	2003-10-07 15:33:15.000000000 +0800
+@@ -33,7 +33,7 @@
+ 	stat->blksize = inode->i_blksize;
+ }
+ 
+-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
++int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
+ {
+ 	struct inode *inode = dentry->d_inode;
+ 	int retval;
+@@ -44,6 +44,8 @@
+ 
+ 	if (inode->i_op->getattr)
+ 		return inode->i_op->getattr(mnt, dentry, stat);
++	if (inode->i_op->getattr_it)
++		return inode->i_op->getattr_it(mnt, dentry, it, stat);
+ 
+ 	generic_fillattr(inode, stat);
+ 	if (!stat->blksize) {
+@@ -56,14 +58,20 @@
+ 	return 0;
+ }
+ 
++int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
++{
++	return vfs_getattr_it(mnt, dentry, NULL, stat);
++}
++
+ int vfs_stat(char __user *name, struct kstat *stat)
+ {
+ 	struct nameidata nd;
+ 	int error;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+-	error = user_path_walk(name, &nd);
++	error = user_path_walk_it(name, &nd);
+ 	if (!error) {
+-		error = vfs_getattr(nd.mnt, nd.dentry, stat);
++		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -73,10 +81,11 @@
+ {
+ 	struct nameidata nd;
+ 	int error;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+-	error = user_path_walk_link(name, &nd);
++	error = user_path_walk_link_it(name, &nd);
+ 	if (!error) {
+-		error = vfs_getattr(nd.mnt, nd.dentry, stat);
++		error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
+ 		path_release(&nd);
+ 	}
+ 	return error;
+@@ -86,9 +95,12 @@
+ {
+ 	struct file *f = fget(fd);
+ 	int error = -EBADF;
++	struct nameidata nd;
++	intent_init(&nd.intent, IT_GETATTR);
+ 
+ 	if (f) {
+-		error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
++		error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
++		intent_release(&nd.intent);
+ 		fput(f);
+ 	}
+ 	return error;
+Index: linux-2.6.0-test6/include/linux/dcache.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/dcache.h	2003-09-28 08:51:16.000000000 +0800
++++ linux-2.6.0-test6/include/linux/dcache.h	2003-10-07 15:33:15.000000000 +0800
+@@ -4,6 +4,7 @@
+ #ifdef __KERNEL__
+ 
+ #include <asm/atomic.h>
++#include <linux/string.h>
+ #include <linux/list.h>
+ #include <linux/spinlock.h>
+ #include <linux/cache.h>
+@@ -35,6 +36,8 @@
+ 	char name_str[0];
+ };
+ 
++#include <linux/namei.h>
++
+ struct dentry_stat_t {
+ 	int nr_dentry;
+ 	int nr_unused;
+Index: linux-2.6.0-test6/include/linux/fs.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/fs.h	2003-10-07 15:14:15.000000000 +0800
++++ linux-2.6.0-test6/include/linux/fs.h	2003-10-07 15:34:10.000000000 +0800
+@@ -243,6 +243,8 @@
+ #define ATTR_ATTR_FLAG	1024
+ #define ATTR_KILL_SUID	2048
+ #define ATTR_KILL_SGID	4096
++#define ATTR_RAW       	8192    /* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN 	16384    /* called from open path, ie O_TRUNC */
+ 
+ /*
+  * This is the Inode Attributes structure, used for notify_change().  It
+@@ -402,6 +404,7 @@
+ 	struct block_device	*i_bdev;
+ 	struct cdev		*i_cdev;
+ 	int			i_cindex;
++	void			*i_filterdata;
+ 
+ 	unsigned long		i_dnotify_mask; /* Directory notify events */
+ 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
+@@ -530,6 +533,7 @@
+ 	struct list_head	f_ep_links;
+ 	spinlock_t		f_ep_lock;
+ 	struct address_space	*f_mapping;
++ 	struct lookup_intent    *f_it;
+ };
+ extern spinlock_t files_lock;
+ #define file_list_lock() spin_lock(&files_lock);
+@@ -839,7 +843,9 @@
+ 	void (*truncate) (struct inode *);
+ 	int (*permission) (struct inode *, int, struct nameidata *);
+ 	int (*setattr) (struct dentry *, struct iattr *);
++	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
++	int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
+ 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+ 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+ 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+@@ -1052,6 +1058,7 @@
+ extern int unregister_filesystem(struct file_system_type *);
+ extern struct vfsmount *kern_mount(struct file_system_type *);
+ extern int may_umount(struct vfsmount *);
++struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
+ extern long do_mount(char *, char *, char *, unsigned long, void *);
+ 
+ extern int vfs_statfs(struct super_block *, struct kstatfs *);
+@@ -1119,6 +1126,7 @@
+ 
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
++extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
+ extern int filp_close(struct file *, fl_owner_t id);
+ extern char * getname(const char __user *);
+ 
+Index: linux-2.6.0-test6/include/linux/namei.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/namei.h	2003-09-28 08:50:15.000000000 +0800
++++ linux-2.6.0-test6/include/linux/namei.h	2003-10-07 15:33:15.000000000 +0800
+@@ -2,25 +2,55 @@
+ #define _LINUX_NAMEI_H
+ 
+ #include <linux/linkage.h>
++#include <linux/string.h>
+ 
+ struct vfsmount;
++struct nameidata;
+ 
+-struct open_intent {
+-	int	flags;
+-	int	create_mode;
++/* intent opcodes */
++#define IT_OPEN     (1)
++#define IT_CREAT    (1<<1)
++#define IT_READDIR  (1<<2)
++#define IT_GETATTR  (1<<3)
++#define IT_LOOKUP   (1<<4)
++#define IT_UNLINK   (1<<5)
++#define IT_TRUNC    (1<<6)
++#define IT_GETXATTR (1<<7)
++
++struct lustre_intent_data {
++	int       it_disposition;
++	int       it_status;
++	__u64     it_lock_handle;
++	void     *it_data;
++	int       it_lock_mode;
+ };
+ 
++#define INTENT_MAGIC 0x19620323
++struct lookup_intent {
++	int     it_magic;
++	void    (*it_op_release)(struct lookup_intent *);
++	int     it_op;
++	int	it_flags;
++	int	it_create_mode;
++	union {
++		struct lustre_intent_data lustre;
++	} d;
++};
++
++static inline void intent_init(struct lookup_intent *it, int op)
++{
++	memset(it, 0, sizeof(*it));
++	it->it_magic = INTENT_MAGIC;
++	it->it_op = op;
++}
++
+ struct nameidata {
+ 	struct dentry	*dentry;
+ 	struct vfsmount *mnt;
+ 	struct qstr	last;
+ 	unsigned int	flags;
+ 	int		last_type;
+-
+-	/* Intent data */
+-	union {
+-		struct open_intent open;
+-	} intent;
++	struct lookup_intent intent;
+ };
+ 
+ /*
+@@ -41,6 +71,9 @@
+ #define LOOKUP_CONTINUE		 4
+ #define LOOKUP_PARENT		16
+ #define LOOKUP_NOALT		32
++#define LOOKUP_LAST		 (1<<6)
++#define LOOKUP_LINK_NOTLAST	 (1<<7)
++
+ /*
+  * Intent data
+  */
+@@ -49,6 +82,12 @@
+ #define LOOKUP_ACCESS		(0x0400)
+ 
+ extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
++extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
++#define user_path_walk_it(name,nd) \
++	__user_walk_it(name, LOOKUP_FOLLOW, nd)
++#define user_path_walk_link_it(name,nd) \
++	__user_walk_it(name, 0, nd)
++extern void intent_release(struct lookup_intent *);
+ #define user_path_walk(name,nd) \
+ 	__user_walk(name, LOOKUP_FOLLOW, nd)
+ #define user_path_walk_link(name,nd) \
+@@ -60,7 +99,6 @@
+ 
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+-
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
+ 
+Index: linux-2.6.0-test6/kernel/ksyms.c
+===================================================================
+--- linux-2.6.0-test6.orig/kernel/ksyms.c	2003-10-07 15:21:57.000000000 +0800
++++ linux-2.6.0-test6/kernel/ksyms.c	2003-10-07 15:33:15.000000000 +0800
+@@ -220,11 +220,18 @@
+ EXPORT_SYMBOL(unregister_filesystem);
+ EXPORT_SYMBOL(__mntput);
+ EXPORT_SYMBOL(may_umount);
++EXPORT_SYMBOL(reparent_to_init);
+ 
+ /* interrupt handling */
+ EXPORT_SYMBOL(request_irq);
+ EXPORT_SYMBOL(free_irq);
+ 
++/* lustre */
++EXPORT_SYMBOL(do_kern_mount);
++EXPORT_SYMBOL(exit_files);
++//EXPORT_SYMBOL(kmem_cache_validate);
++
++
+ /* waitqueue handling */
+ EXPORT_SYMBOL(add_wait_queue);
+ EXPORT_SYMBOL(add_wait_queue_exclusive);
+Index: linux-2.6.0-test6/fs/nfs/dir.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/nfs/dir.c	2003-09-28 08:50:20.000000000 +0800
++++ linux-2.6.0-test6/fs/nfs/dir.c	2003-10-07 15:33:15.000000000 +0800
+@@ -652,7 +652,7 @@
+ 		return 0;
+ 	if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
+ 		return 0;
+-	return (nd->intent.open.flags & O_EXCL) != 0;
++	return (nd->intent.it_flags & O_EXCL) != 0;
+ }
+ 
+ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+@@ -825,7 +825,7 @@
+ 	attr.ia_valid = ATTR_MODE;
+ 
+ 	if (nd && (nd->flags & LOOKUP_CREATE))
+-		open_flags = nd->intent.open.flags;
++		open_flags = nd->intent.it_flags;
+ 
+ 	/*
+ 	 * The 0 argument passed into the create function should one day
+Index: linux-2.6.0-test6/fs/inode.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/inode.c	2003-10-07 15:14:14.000000000 +0800
++++ linux-2.6.0-test6/fs/inode.c	2003-10-07 15:38:08.000000000 +0800
+@@ -224,6 +224,7 @@
+ 	inodes_stat.nr_unused--;
+ }
+ 
++EXPORT_SYMBOL(__iget);
+ /**
+  * clear_inode - clear an inode
+  * @inode: inode to clear
diff --git a/lustre/kernel_patches/patches/vfs_nointent_2.5.69_rev1.patch b/lustre/kernel_patches/patches/vfs_nointent_2.6.0-test1.patch
similarity index 78%
rename from lustre/kernel_patches/patches/vfs_nointent_2.5.69_rev1.patch
rename to lustre/kernel_patches/patches/vfs_nointent_2.6.0-test1.patch
index e2b086bbd189ec3f5e23d665f112c7ad9f142be3..79451605fc9d782a25ca651faf716a26a9435b66 100644
--- a/lustre/kernel_patches/patches/vfs_nointent_2.5.69_rev1.patch
+++ b/lustre/kernel_patches/patches/vfs_nointent_2.6.0-test1.patch
@@ -1,12 +1,8 @@
- fs/exec.c          |    2 -
- fs/namei.c         |   75 +++++++++++++++++++++++++++++++++++++++++++++++++----
- fs/open.c          |   73 ++++++++++++++++++++++++++++++++++++++++++++-------
- include/linux/fs.h |    9 +++++-
- 4 files changed, 142 insertions(+), 17 deletions(-)
+ 0 files changed
 
---- uml-2.5/fs/namei.c~vfs_nointent_2.5.69_rev1	2003-06-20 00:04:07.000000000 -0600
-+++ uml-2.5-braam/fs/namei.c	2003-06-20 06:22:37.000000000 -0600
-@@ -1279,7 +1279,7 @@ int may_open(struct nameidata *nd, int a
+--- linux-2.6.0-test1/fs/namei.c~vfs_nointent_2.6.0-test1	2003-07-22 20:18:30.000000000 +0800
++++ linux-2.6.0-test1-root/fs/namei.c	2003-07-22 20:27:38.000000000 +0800
+@@ -1249,7 +1249,7 @@ int may_open(struct nameidata *nd, int a
  		if (!error) {
  			DQUOT_INIT(inode);
  			
@@ -15,15 +11,15 @@
  		}
  		put_write_access(inode);
  		if (error)
-@@ -1517,6 +1517,7 @@ asmlinkage long sys_mknod(const char __u
- 	char * tmp;
- 	struct dentry * dentry;
+@@ -1494,6 +1494,7 @@ do_mknod(const char __user *filename, in
+ 	char *tmp;
+ 	struct dentry *dentry;
  	struct nameidata nd;
-+	intent_init(&nd.it, IT_LOOKUP, 0);
++	intent_init(&nd.intent, IT_LOOKUP);
  
  	if (S_ISDIR(mode))
  		return -EPERM;
-@@ -1527,6 +1528,15 @@ asmlinkage long sys_mknod(const char __u
+@@ -1504,6 +1505,15 @@ do_mknod(const char __user *filename, in
  	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  	if (error)
  		goto out;
@@ -39,7 +35,7 @@
  	dentry = lookup_create(&nd, 0);
  	error = PTR_ERR(dentry);
  
-@@ -1549,6 +1559,7 @@ asmlinkage long sys_mknod(const char __u
+@@ -1526,6 +1536,7 @@ do_mknod(const char __user *filename, in
  		dput(dentry);
  	}
  	up(&nd.dentry->d_inode->i_sem);
@@ -47,11 +43,11 @@
  	path_release(&nd);
  out:
  	putname(tmp);
-@@ -1590,10 +1601,18 @@ asmlinkage long sys_mkdir(const char __u
+@@ -1588,10 +1599,18 @@ asmlinkage long sys_mkdir(const char __u
  	if (!IS_ERR(tmp)) {
  		struct dentry *dentry;
  		struct nameidata nd;
-+                intent_init(&nd.it, IT_LOOKUP, 0);
++                intent_init(&nd.intent, IT_LOOKUP);
  
  		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
  		if (error)
@@ -66,7 +62,7 @@
  		dentry = lookup_create(&nd, 1);
  		error = PTR_ERR(dentry);
  		if (!IS_ERR(dentry)) {
-@@ -1603,6 +1622,7 @@ asmlinkage long sys_mkdir(const char __u
+@@ -1601,6 +1620,7 @@ asmlinkage long sys_mkdir(const char __u
  			dput(dentry);
  		}
  		up(&nd.dentry->d_inode->i_sem);
@@ -74,15 +70,15 @@
  		path_release(&nd);
  out:
  		putname(tmp);
-@@ -1683,6 +1703,7 @@ asmlinkage long sys_rmdir(const char __u
+@@ -1681,6 +1701,7 @@ asmlinkage long sys_rmdir(const char __u
  	char * name;
  	struct dentry *dentry;
  	struct nameidata nd;
-+        intent_init(&nd.it, IT_LOOKUP, 0);
++        intent_init(&nd.intent, IT_LOOKUP);
  
  	name = getname(pathname);
  	if(IS_ERR(name))
-@@ -1703,6 +1724,16 @@ asmlinkage long sys_rmdir(const char __u
+@@ -1701,6 +1722,16 @@ asmlinkage long sys_rmdir(const char __u
  			error = -EBUSY;
  			goto exit1;
  	}
@@ -97,13 +93,13 @@
 + 	}
 + 
  	down(&nd.dentry->d_inode->i_sem);
- 	dentry = lookup_hash(&nd.last, nd.dentry, &nd);
+ 	dentry = lookup_hash(&nd.last, nd.dentry);
  	error = PTR_ERR(dentry);
 @@ -1759,6 +1790,7 @@ asmlinkage long sys_unlink(const char __
  	struct dentry *dentry;
  	struct nameidata nd;
  	struct inode *inode = NULL;
-+        intent_init(&nd.it, IT_LOOKUP, 0);
++        intent_init(&nd.intent, IT_LOOKUP);
  
  	name = getname(pathname);
  	if(IS_ERR(name))
@@ -119,13 +115,13 @@
 + 			goto exit1;
 + 	}
  	down(&nd.dentry->d_inode->i_sem);
- 	dentry = lookup_hash(&nd.last, nd.dentry, &nd);
+ 	dentry = lookup_hash(&nd.last, nd.dentry);
  	error = PTR_ERR(dentry);
 @@ -1837,10 +1876,18 @@ asmlinkage long sys_symlink(const char _
  	if (!IS_ERR(to)) {
  		struct dentry *dentry;
  		struct nameidata nd;
-+                intent_init(&nd.it, IT_LOOKUP, 0);
++                intent_init(&nd.intent, IT_LOOKUP);
  
  		error = path_lookup(to, LOOKUP_PARENT, &nd);
  		if (error)
@@ -152,8 +148,8 @@
  	struct nameidata nd, old_nd;
  	int error;
  	char * to;
-+        intent_init(&nd.it, IT_LOOKUP, 0);
-+        intent_init(&old_nd.it, IT_LOOKUP, 0);
++        intent_init(&nd.intent, IT_LOOKUP);
++        intent_init(&old_nd.intent, IT_LOOKUP);
  
  	to = getname(newname);
  	if (IS_ERR(to))
@@ -193,8 +189,8 @@
  	struct dentry * old_dentry, *new_dentry;
  	struct dentry * trap;
  	struct nameidata oldnd, newnd;
-+        intent_init(&oldnd.it, IT_LOOKUP, 0);
-+        intent_init(&newnd.it, IT_LOOKUP, 0);
++        intent_init(&oldnd.intent, IT_LOOKUP);
++        intent_init(&newnd.intent, IT_LOOKUP);
  
  	error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
  	if (error)
@@ -211,7 +207,7 @@
 +
  	trap = lock_rename(new_dir, old_dir);
  
- 	old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd);
+ 	old_dentry = lookup_hash(&oldnd.last, old_dir);
 @@ -2150,8 +2216,7 @@ static inline int do_rename(const char *
  	if (new_dentry == trap)
  		goto exit5;
@@ -222,9 +218,9 @@
  exit5:
  	dput(new_dentry);
  exit4:
---- uml-2.5/fs/open.c~vfs_nointent_2.5.69_rev1	2003-06-18 21:42:57.000000000 -0600
-+++ uml-2.5-braam/fs/open.c	2003-06-20 06:22:37.000000000 -0600
-@@ -75,9 +75,10 @@ out:
+--- linux-2.6.0-test1/fs/open.c~vfs_nointent_2.6.0-test1	2003-07-22 20:18:30.000000000 +0800
++++ linux-2.6.0-test1-root/fs/open.c	2003-07-22 20:26:41.000000000 +0800
+@@ -178,9 +178,10 @@ out:
  	return error;
  }
  
@@ -236,7 +232,7 @@
  	struct iattr newattrs;
  
  	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
-@@ -87,7 +88,14 @@ int do_truncate(struct dentry *dentry, l
+@@ -190,7 +191,14 @@ int do_truncate(struct dentry *dentry, l
  	newattrs.ia_size = length;
  	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
  	down(&dentry->d_inode->i_sem);
@@ -252,7 +248,7 @@
  	up(&dentry->d_inode->i_sem);
  	return err;
  }
-@@ -142,7 +150,7 @@ static inline long do_sys_truncate(const
+@@ -245,7 +253,7 @@ static inline long do_sys_truncate(const
  	error = locks_verify_truncate(inode, NULL, length);
  	if (!error) {
  		DQUOT_INIT(inode);
@@ -261,7 +257,7 @@
  	}
  	put_write_access(inode);
  
-@@ -194,7 +202,7 @@ static inline long do_sys_ftruncate(unsi
+@@ -297,7 +305,7 @@ static inline long do_sys_ftruncate(unsi
  
  	error = locks_verify_truncate(inode, file, length);
  	if (!error)
@@ -270,8 +266,8 @@
  out_putf:
  	fput(file);
  out:
-@@ -265,9 +273,19 @@ asmlinkage long sys_utime(char __user * 
- 		    (error = permission(inode,MAY_WRITE)) != 0)
+@@ -368,9 +376,19 @@ asmlinkage long sys_utime(char __user * 
+ 		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
  			goto dput_and_out;
  	}
 -	down(&inode->i_sem);
@@ -293,8 +289,8 @@
  dput_and_out:
  	path_release(&nd);
  out:
-@@ -310,9 +328,19 @@ long do_utimes(char __user * filename, s
- 		    (error = permission(inode,MAY_WRITE)) != 0)
+@@ -413,9 +431,19 @@ long do_utimes(char __user * filename, s
+ 		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
  			goto dput_and_out;
  	}
 -	down(&inode->i_sem);
@@ -316,7 +312,7 @@
  dput_and_out:
  	path_release(&nd);
  out:
-@@ -513,6 +541,18 @@ asmlinkage long sys_chmod(const char __u
+@@ -616,6 +644,18 @@ asmlinkage long sys_chmod(const char __u
  	if (IS_RDONLY(inode))
  		goto dput_and_out;
  	
@@ -335,7 +331,7 @@
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto dput_and_out;
-@@ -546,6 +586,18 @@ static int chown_common(struct dentry * 
+@@ -649,6 +689,18 @@ static int chown_common(struct dentry * 
  	if (IS_RDONLY(inode))
  		goto out;
  	error = -EPERM;
@@ -354,7 +350,7 @@
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
  	newattrs.ia_valid =  ATTR_CTIME;
-@@ -559,6 +611,7 @@ static int chown_common(struct dentry * 
+@@ -662,6 +714,7 @@ static int chown_common(struct dentry * 
  	}
  	if (!S_ISDIR(inode->i_mode))
  		newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
@@ -362,11 +358,11 @@
  	down(&inode->i_sem);
  	error = notify_change(dentry, &newattrs);
  	up(&inode->i_sem);
---- uml-2.5/include/linux/fs.h~vfs_nointent_2.5.69_rev1	2003-06-18 21:40:58.000000000 -0600
-+++ uml-2.5-braam/include/linux/fs.h	2003-06-20 06:22:37.000000000 -0600
-@@ -738,13 +738,20 @@ struct inode_operations {
- 	struct dentry * (*lookup_it) (struct inode *,struct dentry *,
- 					struct nameidata *);
+--- linux-2.6.0-test1/include/linux/fs.h~vfs_nointent_2.6.0-test1	2003-07-22 20:18:30.000000000 +0800
++++ linux-2.6.0-test1-root/include/linux/fs.h	2003-07-22 20:26:41.000000000 +0800
+@@ -807,13 +807,20 @@ struct inode_operations {
+ 	int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
  	int (*link) (struct dentry *,struct inode *,struct dentry *);
 +	int (*link_raw) (struct nameidata *,struct nameidata *);
  	int (*unlink) (struct inode *,struct dentry *);
@@ -385,18 +381,18 @@
  	int (*readlink) (struct dentry *, char __user *,int);
  	int (*follow_link) (struct dentry *, struct nameidata *);
  	void (*truncate) (struct inode *);
-@@ -1029,7 +1036,7 @@ static inline int break_lease(struct ino
+@@ -1098,7 +1105,7 @@ static inline int break_lease(struct ino
  
- asmlinkage long sys_open(const char *, int, int);
+ asmlinkage long sys_open(const char __user *, int, int);
  asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
 -extern int do_truncate(struct dentry *, loff_t start);
 +extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
  
  extern struct file *filp_open(const char *, int, int);
  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
---- uml-2.5/fs/exec.c~vfs_nointent_2.5.69_rev1	2003-06-04 21:29:14.000000000 -0600
-+++ uml-2.5-braam/fs/exec.c	2003-06-20 06:22:37.000000000 -0600
-@@ -1358,7 +1358,7 @@ int do_coredump(long signr, int exit_cod
+--- linux-2.6.0-test1/fs/exec.c~vfs_nointent_2.6.0-test1	2003-07-22 20:18:30.000000000 +0800
++++ linux-2.6.0-test1-root/fs/exec.c	2003-07-22 20:26:41.000000000 +0800
+@@ -1352,7 +1352,7 @@ int do_coredump(long signr, int exit_cod
  		goto close_fail;
  	if (!file->f_op->write)
  		goto close_fail;
diff --git a/lustre/kernel_patches/patches/vfs_nointent_2.6.0-test6.patch b/lustre/kernel_patches/patches/vfs_nointent_2.6.0-test6.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7c2ea35205dad2edf61193d0a71f69beba14b02f
--- /dev/null
+++ b/lustre/kernel_patches/patches/vfs_nointent_2.6.0-test6.patch
@@ -0,0 +1,411 @@
+ 0 files changed
+
+Index: linux-2.6.0-test6/fs/namei.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/namei.c	2003-10-07 15:33:15.000000000 +0800
++++ linux-2.6.0-test6/fs/namei.c	2003-10-07 15:39:16.000000000 +0800
+@@ -1270,7 +1270,7 @@
+ 		if (!error) {
+ 			DQUOT_INIT(inode);
+ 			
+-			error = do_truncate(dentry, 0);
++			error = do_truncate(dentry, 0, 1);
+ 		}
+ 		put_write_access(inode);
+ 		if (error)
+@@ -1521,6 +1521,7 @@
+ 	char * tmp;
+ 	struct dentry * dentry;
+ 	struct nameidata nd;
++	intent_init(&nd.intent, IT_LOOKUP);
+ 
+ 	if (S_ISDIR(mode))
+ 		return -EPERM;
+@@ -1531,6 +1532,15 @@
+ 	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
+ 	if (error)
+ 		goto out;
++
++	if (nd.dentry->d_inode->i_op->mknod_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++		error = op->mknod_raw(&nd, mode, dev);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto out2;
++	}
++
+ 	dentry = lookup_create(&nd, 0);
+ 	error = PTR_ERR(dentry);
+ 
+@@ -1557,6 +1567,7 @@
+ 		dput(dentry);
+ 	}
+ 	up(&nd.dentry->d_inode->i_sem);
++out2:
+ 	path_release(&nd);
+ out:
+ 	putname(tmp);
+@@ -1598,10 +1609,18 @@
+ 	if (!IS_ERR(tmp)) {
+ 		struct dentry *dentry;
+ 		struct nameidata nd;
++                intent_init(&nd.intent, IT_LOOKUP);
+ 
+ 		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
+ 		if (error)
+ 			goto out;
++ 		if (nd.dentry->d_inode->i_op->mkdir_raw) {
++ 			struct inode_operations *op = nd.dentry->d_inode->i_op;
++ 			error = op->mkdir_raw(&nd, mode);
++ 			/* the file system wants to use normal vfs path now */
++ 			if (error != -EOPNOTSUPP)
++ 				goto out2;
++ 		}
+ 		dentry = lookup_create(&nd, 1);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+@@ -1611,6 +1630,7 @@
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++out2:
+ 		path_release(&nd);
+ out:
+ 		putname(tmp);
+@@ -1691,6 +1711,7 @@
+ 	char * name;
+ 	struct dentry *dentry;
+ 	struct nameidata nd;
++        intent_init(&nd.intent, IT_LOOKUP);
+ 
+ 	name = getname(pathname);
+ 	if(IS_ERR(name))
+@@ -1711,6 +1732,16 @@
+ 			error = -EBUSY;
+ 			goto exit1;
+ 	}
++ 
++ 	if (nd.dentry->d_inode->i_op->rmdir_raw) {
++ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++ 
++ 		error = op->rmdir_raw(&nd);
++ 		/* the file system wants to use normal vfs path now */
++ 		if (error != -EOPNOTSUPP)
++ 			goto exit1;
++ 	}
++ 
+ 	down(&nd.dentry->d_inode->i_sem);
+ 	dentry = lookup_hash(&nd.last, nd.dentry);
+ 	error = PTR_ERR(dentry);
+@@ -1769,6 +1800,7 @@
+ 	struct dentry *dentry;
+ 	struct nameidata nd;
+ 	struct inode *inode = NULL;
++        intent_init(&nd.intent, IT_LOOKUP);
+ 
+ 	name = getname(pathname);
+ 	if(IS_ERR(name))
+@@ -1780,6 +1812,13 @@
+ 	error = -EISDIR;
+ 	if (nd.last_type != LAST_NORM)
+ 		goto exit1;
++ 	if (nd.dentry->d_inode->i_op->unlink_raw) {
++ 		struct inode_operations *op = nd.dentry->d_inode->i_op;
++ 		error = op->unlink_raw(&nd);
++ 		/* the file system wants to use normal vfs path now */
++ 		if (error != -EOPNOTSUPP)
++ 			goto exit1;
++ 	}
+ 	down(&nd.dentry->d_inode->i_sem);
+ 	dentry = lookup_hash(&nd.last, nd.dentry);
+ 	error = PTR_ERR(dentry);
+@@ -1847,10 +1886,18 @@
+ 	if (!IS_ERR(to)) {
+ 		struct dentry *dentry;
+ 		struct nameidata nd;
++                intent_init(&nd.intent, IT_LOOKUP);
+ 
+ 		error = path_lookup(to, LOOKUP_PARENT, &nd);
+ 		if (error)
+ 			goto out;
++		if (nd.dentry->d_inode->i_op->symlink_raw) {
++			struct inode_operations *op = nd.dentry->d_inode->i_op;
++			error = op->symlink_raw(&nd, from);
++			/* the file system wants to use normal vfs path now */
++			if (error != -EOPNOTSUPP)
++				goto out2;
++		}
+ 		dentry = lookup_create(&nd, 0);
+ 		error = PTR_ERR(dentry);
+ 		if (!IS_ERR(dentry)) {
+@@ -1858,6 +1905,7 @@
+ 			dput(dentry);
+ 		}
+ 		up(&nd.dentry->d_inode->i_sem);
++out2:
+ 		path_release(&nd);
+ out:
+ 		putname(to);
+@@ -1921,6 +1969,8 @@
+ 	struct nameidata nd, old_nd;
+ 	int error;
+ 	char * to;
++        intent_init(&nd.intent, IT_LOOKUP);
++        intent_init(&old_nd.intent, IT_LOOKUP);
+ 
+ 	to = getname(newname);
+ 	if (IS_ERR(to))
+@@ -1935,6 +1985,13 @@
+ 	error = -EXDEV;
+ 	if (old_nd.mnt != nd.mnt)
+ 		goto out_release;
++        if (nd.dentry->d_inode->i_op->link_raw) {
++                struct inode_operations *op = nd.dentry->d_inode->i_op;
++                error = op->link_raw(&old_nd, &nd);
++                /* the file system wants to use normal vfs path now */
++                if (error != -EOPNOTSUPP)
++                        goto out_release;
++        }
+ 	new_dentry = lookup_create(&nd, 0);
+ 	error = PTR_ERR(new_dentry);
+ 	if (!IS_ERR(new_dentry)) {
+@@ -1985,7 +2042,7 @@
+  *	   locking].
+  */
+ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++                   struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	int error = 0;
+ 	struct inode *target;
+@@ -2030,7 +2087,7 @@
+ }
+ 
+ int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
+-	       struct inode *new_dir, struct dentry *new_dentry)
++                     struct inode *new_dir, struct dentry *new_dentry)
+ {
+ 	struct inode *target;
+ 	int error;
+@@ -2107,6 +2164,8 @@
+ 	struct dentry * old_dentry, *new_dentry;
+ 	struct dentry * trap;
+ 	struct nameidata oldnd, newnd;
++        intent_init(&oldnd.intent, IT_LOOKUP);
++        intent_init(&newnd.intent, IT_LOOKUP);
+ 
+ 	error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
+ 	if (error)
+@@ -2129,6 +2188,13 @@
+ 	if (newnd.last_type != LAST_NORM)
+ 		goto exit2;
+ 
++ 	if (old_dir->d_inode->i_op->rename_raw) {
++ 		error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
++ 		/* the file system wants to use normal vfs path now */
++ 		if (error != -EOPNOTSUPP)
++ 			goto exit2;
++ 	}
++
+ 	trap = lock_rename(new_dir, old_dir);
+ 
+ 	old_dentry = lookup_hash(&oldnd.last, old_dir);
+@@ -2160,8 +2226,7 @@
+ 	if (new_dentry == trap)
+ 		goto exit5;
+ 
+-	error = vfs_rename(old_dir->d_inode, old_dentry,
+-				   new_dir->d_inode, new_dentry);
++	error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);
+ exit5:
+ 	dput(new_dentry);
+ exit4:
+Index: linux-2.6.0-test6/fs/open.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/open.c	2003-10-07 15:33:15.000000000 +0800
++++ linux-2.6.0-test6/fs/open.c	2003-10-07 15:40:41.000000000 +0800
+@@ -178,9 +178,10 @@
+ 	return error;
+ }
+ 
+-int do_truncate(struct dentry *dentry, loff_t length)
++int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
+ {
+ 	int err;
++	struct inode_operations *op = dentry->d_inode->i_op;
+ 	struct iattr newattrs;
+ 
+ 	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
+@@ -191,7 +192,14 @@
+ 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+ 	down(&dentry->d_inode->i_sem);
+ 	down_write(&dentry->d_inode->i_alloc_sem);
+-	err = notify_change(dentry, &newattrs);
++	if (called_from_open)
++ 		newattrs.ia_valid |= ATTR_FROM_OPEN;
++ 	if (op->setattr_raw) {
++ 		newattrs.ia_valid |= ATTR_RAW;
++ 		newattrs.ia_ctime = CURRENT_TIME;
++ 		err = op->setattr_raw(dentry->d_inode, &newattrs);
++ 	} else 
++                err = notify_change(dentry, &newattrs);
+ 	up_write(&dentry->d_inode->i_alloc_sem);
+ 	up(&dentry->d_inode->i_sem);
+ 	return err;
+@@ -247,7 +255,7 @@
+ 	error = locks_verify_truncate(inode, NULL, length);
+ 	if (!error) {
+ 		DQUOT_INIT(inode);
+-		error = do_truncate(nd.dentry, length);
++		error = do_truncate(nd.dentry, length, 0);
+ 	}
+ 	put_write_access(inode);
+ 
+@@ -299,7 +307,7 @@
+ 
+ 	error = locks_verify_truncate(inode, file, length);
+ 	if (!error)
+-		error = do_truncate(dentry, length);
++		error = do_truncate(dentry, length, 0);
+ out_putf:
+ 	fput(file);
+ out:
+@@ -378,9 +386,19 @@
+ 		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ 			goto dput_and_out;
+ 	}
+-	down(&inode->i_sem);
+-	error = notify_change(nd.dentry, &newattrs);
+-	up(&inode->i_sem);
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	} else {
++                down(&inode->i_sem);
++                error = notify_change(nd.dentry, &newattrs);
++                up(&inode->i_sem);
++        }
+ dput_and_out:
+ 	path_release(&nd);
+ out:
+@@ -431,9 +449,19 @@
+ 		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
+ 			goto dput_and_out;
+ 	}
+-	down(&inode->i_sem);
+-	error = notify_change(nd.dentry, &newattrs);
+-	up(&inode->i_sem);
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	} else {
++                down(&inode->i_sem);
++                error = notify_change(nd.dentry, &newattrs);
++                up(&inode->i_sem);
++        }
+ dput_and_out:
+ 	path_release(&nd);
+ out:
+@@ -634,6 +662,18 @@
+ 	if (IS_RDONLY(inode))
+ 		goto dput_and_out;
+ 	
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++		newattrs.ia_mode = mode;
++		newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			goto dput_and_out;
++	}
++
+ 	error = -EPERM;
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ 		goto dput_and_out;
+@@ -667,6 +707,18 @@
+ 	if (IS_RDONLY(inode))
+ 		goto out;
+ 	error = -EPERM;
++	if (inode->i_op->setattr_raw) {
++		struct inode_operations *op = dentry->d_inode->i_op;
++
++		newattrs.ia_uid = user;
++		newattrs.ia_gid = group;
++		newattrs.ia_valid = ATTR_UID | ATTR_GID;
++		newattrs.ia_valid |= ATTR_RAW;
++		error = op->setattr_raw(inode, &newattrs);
++		/* the file system wants to use normal vfs path now */
++		if (error != -EOPNOTSUPP)
++			return error;
++	}
+ 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ 		goto out;
+ 	newattrs.ia_valid =  ATTR_CTIME;
+@@ -680,6 +732,7 @@
+ 	}
+ 	if (!S_ISDIR(inode->i_mode))
+ 		newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
++
+ 	down(&inode->i_sem);
+ 	error = notify_change(dentry, &newattrs);
+ 	up(&inode->i_sem);
+Index: linux-2.6.0-test6/include/linux/fs.h
+===================================================================
+--- linux-2.6.0-test6.orig/include/linux/fs.h	2003-10-07 15:34:10.000000000 +0800
++++ linux-2.6.0-test6/include/linux/fs.h	2003-10-07 15:39:17.000000000 +0800
+@@ -831,13 +831,20 @@
+ 	int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
+ 	struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
+ 	int (*link) (struct dentry *,struct inode *,struct dentry *);
++	int (*link_raw) (struct nameidata *,struct nameidata *);
+ 	int (*unlink) (struct inode *,struct dentry *);
++	int (*unlink_raw) (struct nameidata *);
+ 	int (*symlink) (struct inode *,struct dentry *,const char *);
++	int (*symlink_raw) (struct nameidata *,const char *);
+ 	int (*mkdir) (struct inode *,struct dentry *,int);
++	int (*mkdir_raw) (struct nameidata *,int);
+ 	int (*rmdir) (struct inode *,struct dentry *);
++	int (*rmdir_raw) (struct nameidata *);
+ 	int (*mknod) (struct inode *,struct dentry *,int,dev_t);
++	int (*mknod_raw) (struct nameidata *,int,dev_t);
+ 	int (*rename) (struct inode *, struct dentry *,
+ 			struct inode *, struct dentry *);
++	int (*rename_raw) (struct nameidata *, struct nameidata *);
+ 	int (*readlink) (struct dentry *, char __user *,int);
+ 	int (*follow_link) (struct dentry *, struct nameidata *);
+ 	void (*truncate) (struct inode *);
+@@ -1122,7 +1129,7 @@
+ 
+ asmlinkage long sys_open(const char __user *, int, int);
+ asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
+-extern int do_truncate(struct dentry *, loff_t start);
++extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
+ 
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
+Index: linux-2.6.0-test6/fs/exec.c
+===================================================================
+--- linux-2.6.0-test6.orig/fs/exec.c	2003-10-07 15:33:15.000000000 +0800
++++ linux-2.6.0-test6/fs/exec.c	2003-10-07 15:39:17.000000000 +0800
+@@ -1390,7 +1390,7 @@
+ 		goto close_fail;
+ 	if (!file->f_op->write)
+ 		goto close_fail;
+-	if (do_truncate(file->f_dentry, 0) != 0)
++	if (do_truncate(file->f_dentry, 0, 0) != 0)
+ 		goto close_fail;
+ 
+ 	retval = binfmt->core_dump(signr, regs, file);
diff --git a/lustre/kernel_patches/patches/vfs_races_2.5.72_rev1.patch b/lustre/kernel_patches/patches/vfs_races_2.5.72_rev1.patch
index f1eeb016873845ad10654b9dc8b63e3276142e33..1dfed6627affc51bc70d03d06e0f04d4031a361e 100644
--- a/lustre/kernel_patches/patches/vfs_races_2.5.72_rev1.patch
+++ b/lustre/kernel_patches/patches/vfs_races_2.5.72_rev1.patch
@@ -1,10 +1,9 @@
  fs/dcache.c            |   24 ++++++++++++++++++++----
- fs/namei.c             |    4 +++-
  include/linux/dcache.h |    2 ++
- 3 files changed, 25 insertions(+), 5 deletions(-)
+ 2 files changed, 22 insertions(+), 4 deletions(-)
 
---- linux-2.5.72/fs/dcache.c~vfs_races_2.5.72_rev1	2003-06-16 22:19:41.000000000 -0600
-+++ linux-2.5.72-braam/fs/dcache.c	2003-06-25 08:33:08.000000000 -0600
+--- linux-2.6.0-test1/fs/dcache.c~vfs_races_2.5.72_rev1	2003-07-24 15:52:47.000000000 +0400
++++ linux-2.6.0-test1-alexey/fs/dcache.c	2003-09-13 16:21:16.000000000 +0400
 @@ -212,7 +212,14 @@ int d_invalidate(struct dentry * dentry)
  		spin_unlock(&dcache_lock);
  		return 0;
@@ -21,7 +20,7 @@
  	 * Check whether to do a partial shrink_dcache
  	 * to get rid of unused child entries.
  	 */
-@@ -1132,14 +1139,23 @@ void d_delete(struct dentry * dentry)
+@@ -1135,14 +1142,23 @@ void d_delete(struct dentry * dentry)
   * Adds a dentry to the hash according to its name.
   */
   
@@ -48,29 +47,9 @@
  }
  
  #define do_switch(x,y) do { \
---- linux-2.5.72/fs/namei.c~vfs_races_2.5.72_rev1	2003-06-25 08:33:06.000000000 -0600
-+++ linux-2.5.72-braam/fs/namei.c	2003-06-25 08:50:18.000000000 -0600
-@@ -368,6 +368,8 @@ static struct dentry * real_lookup(struc
- 	struct dentry * result;
- 	struct inode *dir = parent->d_inode;
- 
-+ again: 
-+
- 	down(&dir->i_sem);
- 	/*
- 	 * First re-do the cached lookup just in case it was created
-@@ -415,7 +417,7 @@ static struct dentry * real_lookup(struc
- 		if (!result->d_op->d_revalidate_it(result, flags, nd) &&
- 		    !d_invalidate(result)) {
- 			dput(result);
--			result = ERR_PTR(-ENOENT);
-+			goto again;
- 		}
- 	}
- 	return result;
---- linux-2.5.72/include/linux/dcache.h~vfs_races_2.5.72_rev1	2003-06-25 08:25:04.000000000 -0600
-+++ linux-2.5.72-braam/include/linux/dcache.h	2003-06-25 08:33:08.000000000 -0600
-@@ -180,6 +180,8 @@ d_iput:		no		no		yes
+--- linux-2.6.0-test1/include/linux/dcache.h~vfs_races_2.5.72_rev1	2003-09-13 16:21:05.000000000 +0400
++++ linux-2.6.0-test1-alexey/include/linux/dcache.h	2003-09-13 16:21:16.000000000 +0400
+@@ -156,6 +156,8 @@ d_iput:		no		no		yes
  
  #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
  #define DCACHE_UNHASHED		0x0010	
diff --git a/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch b/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a213a485736ba9ce5f1deaf837c6ecb9e921d60f
--- /dev/null
+++ b/lustre/kernel_patches/patches/xattr-0.8.54-2.4.22-rh.patch
@@ -0,0 +1,5403 @@
+ Documentation/Configure.help  |   66 ++
+ arch/alpha/defconfig          |    7 
+ arch/alpha/kernel/entry.S     |   12 
+ arch/arm/defconfig            |    7 
+ arch/arm/kernel/calls.S       |   24 
+ arch/i386/defconfig           |    7 
+ arch/ia64/defconfig           |    7 
+ arch/m68k/defconfig           |    7 
+ arch/mips/defconfig           |    7 
+ arch/mips64/defconfig         |    7 
+ arch/ppc/defconfig            |   14 
+ arch/ppc64/kernel/misc.S      |    2 
+ arch/s390/defconfig           |    7 
+ arch/s390/kernel/entry.S      |   24 
+ arch/s390x/defconfig          |    7 
+ arch/s390x/kernel/entry.S     |   24 
+ arch/s390x/kernel/wrapper32.S |   90 +++
+ arch/sparc/defconfig          |    7 
+ arch/sparc64/defconfig        |    7 
+ fs/Config.in                  |   14 
+ fs/Makefile                   |    3 
+ fs/ext2/Makefile              |    4 
+ fs/ext2/file.c                |    5 
+ fs/ext2/ialloc.c              |    2 
+ fs/ext2/inode.c               |   34 -
+ fs/ext2/namei.c               |   14 
+ fs/ext2/super.c               |   29 
+ fs/ext2/symlink.c             |   14 
+ fs/ext2/xattr.c               | 1212 +++++++++++++++++++++++++++++++++++++++++
+ fs/ext2/xattr_user.c          |  103 +++
+ fs/ext3/Makefile              |   10 
+ fs/ext3/ext3-exports.c        |   13 
+ fs/ext3/file.c                |    5 
+ fs/ext3/ialloc.c              |    2 
+ fs/ext3/inode.c               |   35 -
+ fs/ext3/namei.c               |   21 
+ fs/ext3/super.c               |   37 +
+ fs/ext3/symlink.c             |   14 
+ fs/ext3/xattr.c               | 1225 ++++++++++++++++++++++++++++++++++++++++++
+ fs/ext3/xattr_user.c          |  111 +++
+ fs/jfs/jfs_xattr.h            |    6 
+ fs/jfs/xattr.c                |    6 
+ fs/mbcache.c                  |  648 ++++++++++++++++++++++
+ include/asm-arm/unistd.h      |    2 
+ include/asm-ppc64/unistd.h    |    2 
+ include/asm-s390/unistd.h     |   13 
+ include/asm-s390x/unistd.h    |   13 
+ include/linux/cache_def.h     |   15 
+ include/linux/errno.h         |    4 
+ include/linux/ext2_fs.h       |   31 -
+ include/linux/ext2_xattr.h    |  157 +++++
+ include/linux/ext3_fs.h       |   31 -
+ include/linux/ext3_jbd.h      |    8 
+ include/linux/ext3_xattr.h    |  157 +++++
+ include/linux/fs.h            |    2 
+ include/linux/mbcache.h       |   69 ++
+ kernel/ksyms.c                |    4 
+ mm/vmscan.c                   |   35 +
+ 58 files changed, 4306 insertions(+), 137 deletions(-)
+
+--- linux-2.4.22-ac1/arch/alpha/defconfig~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/alpha/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ALPHA=y
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+--- linux-2.4.22-ac1/arch/alpha/kernel/entry.S~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/alpha/kernel/entry.S	2003-09-25 23:57:02.000000000 +0400
+@@ -1158,6 +1158,18 @@ sys_call_table:
+ 	.quad sys_readahead
+ 	.quad sys_ni_syscall			/* 380, sys_security */
+ 	.quad sys_tkill
++	.quad sys_setxattr
++	.quad sys_lsetxattr
++	.quad sys_fsetxattr
++	.quad sys_getxattr			/* 385 */
++	.quad sys_lgetxattr
++	.quad sys_fgetxattr
++	.quad sys_listxattr
++	.quad sys_llistxattr
++	.quad sys_flistxattr			/* 390 */
++	.quad sys_removexattr
++	.quad sys_lremovexattr
++	.quad sys_fremovexattr
+ 
+ /* Remember to update everything, kids.  */
+ .ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
+--- linux-2.4.22-ac1/arch/arm/defconfig~xattr-0.8.54-2.4.22-rh	2001-05-20 04:43:05.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/arm/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_ARM=y
+ # CONFIG_EISA is not set
+ # CONFIG_SBUS is not set
+--- linux-2.4.22-ac1/arch/arm/kernel/calls.S~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:39.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/arm/kernel/calls.S	2003-09-26 00:00:10.000000000 +0400
+@@ -240,18 +240,18 @@ __syscall_start:
+ 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
+ 		.long	SYMBOL_NAME(sys_gettid)
+ /* 225 */	.long	SYMBOL_NAME(sys_readahead)
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* setxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* getxattr */
+-/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* listxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* llistxattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* flistxattr */
+-/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* removexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */
+-		.long	SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */
++ 		.long	SYMBOL_NAME(sys_setxattr)
++ 		.long	SYMBOL_NAME(sys_lsetxattr)
++ 		.long	SYMBOL_NAME(sys_fsetxattr)
++ 		.long	SYMBOL_NAME(sys_getxattr)
++/* 230 */	.long	SYMBOL_NAME(sys_lgetxattr)
++ 		.long	SYMBOL_NAME(sys_fgetxattr)
++ 		.long	SYMBOL_NAME(sys_listxattr)
++ 		.long	SYMBOL_NAME(sys_llistxattr)
++ 		.long	SYMBOL_NAME(sys_flistxattr)
++/* 235 */	.long	SYMBOL_NAME(sys_removexattr)
++ 		.long	SYMBOL_NAME(sys_lremovexattr)
++ 		.long	SYMBOL_NAME(sys_fremovexattr)
+ 		.long	SYMBOL_NAME(sys_tkill)
+ 		.long	SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */
+ /* 240 */	.long	SYMBOL_NAME(sys_ni_syscall) /* futex */
+--- linux-2.4.22-ac1/arch/i386/defconfig~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/i386/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+--- linux-2.4.22-ac1/arch/ia64/defconfig~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:39.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/ia64/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+--- linux-2.4.22-ac1/arch/m68k/defconfig~xattr-0.8.54-2.4.22-rh	2000-06-19 23:56:08.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/m68k/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ 
+ #
+--- linux-2.4.22-ac1/arch/mips64/defconfig~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:40.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/mips64/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ # CONFIG_MIPS32 is not set
+ CONFIG_MIPS64=y
+--- linux-2.4.22-ac1/arch/mips/defconfig~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:39.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/mips/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_MIPS=y
+ CONFIG_MIPS32=y
+ # CONFIG_MIPS64 is not set
+--- linux-2.4.22-ac1/arch/ppc64/kernel/misc.S~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:40.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/ppc64/kernel/misc.S	2003-09-25 23:57:02.000000000 +0400
+@@ -805,6 +805,7 @@ _GLOBAL(sys_call_table32)
+ 	.llong .sys_gettid		/* 207 */
+ #if 0 /* Reserved syscalls */
+ 	.llong .sys_tkill		/* 208 */
++#endif
+ 	.llong .sys_setxattr
+ 	.llong .sys_lsetxattr	/* 210 */
+ 	.llong .sys_fsetxattr
+@@ -817,6 +818,7 @@ _GLOBAL(sys_call_table32)
+ 	.llong .sys_removexattr
+ 	.llong .sys_lremovexattr
+ 	.llong .sys_fremovexattr	/* 220 */
++#if 0 /* Reserved syscalls */
+ 	.llong .sys_futex
+ #endif
+ 	.llong .sys_perfmonctl   /* Put this here for now ... */
+--- linux-2.4.22-ac1/arch/ppc/defconfig~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:31.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/ppc/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,20 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_UID16 is not set
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+--- linux-2.4.22-ac1/arch/s390/defconfig~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/s390/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+--- linux-2.4.22-ac1/arch/s390/kernel/entry.S~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/s390/kernel/entry.S	2003-09-25 23:57:02.000000000 +0400
+@@ -559,18 +559,18 @@ sys_call_table:
+         .long  sys_fcntl64 
+ 	.long  sys_readahead
+ 	.long  sys_ni_syscall
+-	.long  sys_ni_syscall		 /* 224 - reserved for setxattr  */
+-	.long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
+-	.long  sys_ni_syscall		 /* 226 - reserved for fsetxattr */
+-	.long  sys_ni_syscall		 /* 227 - reserved for getxattr  */
+-	.long  sys_ni_syscall		 /* 228 - reserved for lgetxattr */
+-	.long  sys_ni_syscall		 /* 229 - reserved for fgetxattr */
+-	.long  sys_ni_syscall		 /* 230 - reserved for listxattr */
+-	.long  sys_ni_syscall		 /* 231 - reserved for llistxattr */
+-	.long  sys_ni_syscall		 /* 232 - reserved for flistxattr */
+-	.long  sys_ni_syscall		 /* 233 - reserved for removexattr */
+-	.long  sys_ni_syscall		 /* 234 - reserved for lremovexattr */
+-	.long  sys_ni_syscall		 /* 235 - reserved for fremovexattr */
++	.long  sys_setxattr
++	.long  sys_lsetxattr		/* 225 */
++	.long  sys_fsetxattr
++	.long  sys_getxattr
++	.long  sys_lgetxattr
++	.long  sys_fgetxattr
++	.long  sys_listxattr		/* 230 */
++	.long  sys_llistxattr
++	.long  sys_flistxattr
++	.long  sys_removexattr
++	.long  sys_lremovexattr
++	.long  sys_fremovexattr		/* 235 */
+ 	.long  sys_gettid
+ 	.long  sys_tkill
+ 	.rept  255-237
+--- linux-2.4.22-ac1/arch/s390x/defconfig~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/s390x/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ # CONFIG_ISA is not set
+ # CONFIG_EISA is not set
+ # CONFIG_MCA is not set
+--- linux-2.4.22-ac1/arch/s390x/kernel/entry.S~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/s390x/kernel/entry.S	2003-09-25 23:57:02.000000000 +0400
+@@ -591,18 +591,18 @@ sys_call_table:
+ 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
+ 	.long  SYSCALL(sys_readahead,sys32_readahead)
+ 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr  */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */
+-	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */
++	.long  SYSCALL(sys_setxattr,sys32_setxattr_wrapper)
++	.long  SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper)	/* 225 */
++	.long  SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper)
++	.long  SYSCALL(sys_getxattr,sys32_getxattr_wrapper)
++	.long  SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper)
++	.long  SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper)
++	.long  SYSCALL(sys_listxattr,sys32_listxattr_wrapper)	/* 230 */
++	.long  SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper)
++	.long  SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper)
++	.long  SYSCALL(sys_removexattr,sys32_removexattr_wrapper)
++	.long  SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper)
++	.long  SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */
+ 	.long  SYSCALL(sys_gettid,sys_gettid)
+ 	.long  SYSCALL(sys_tkill,sys_tkill)
+ 	.rept  255-237
+--- linux-2.4.22-ac1/arch/s390x/kernel/wrapper32.S~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:40.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/s390x/kernel/wrapper32.S	2003-09-26 00:05:14.000000000 +0400
+@@ -1097,6 +1097,96 @@ sys32_fstat64_wrapper:
+ 	llgtr	%r3,%r3			# struct stat64 *
+ 	llgfr	%r4,%r4			# long
+ 	jg	sys32_fstat64		# branch to system call
++ 
++	.globl	sys32_setxattr_wrapper
++sys32_setxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_setxattr
++
++	.globl	sys32_lsetxattr_wrapper
++sys32_lsetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_lsetxattr
++
++	.globl	sys32_fsetxattr_wrapper
++sys32_fsetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	lgfr	%r6,%r6			# int
++	jg	sys_fsetxattr
++
++	.globl	sys32_getxattr_wrapper
++sys32_getxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_getxattr
++
++	.globl	sys32_lgetxattr_wrapper
++sys32_lgetxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_lgetxattr
++
++	.globl	sys32_fgetxattr_wrapper
++sys32_fgetxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgtr	%r4,%r4			# void *
++	llgfr	%r5,%r5			# size_t
++	jg	sys_fgetxattr
++ 
++	.globl	sys32_listxattr_wrapper
++sys32_listxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_listxattr
++
++	.globl	sys32_llistxattr_wrapper
++sys32_llistxattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_llistxattr
++
++	.globl	sys32_flistxattr_wrapper
++sys32_flistxattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	llgfr	%r4,%r4			# size_t
++	jg	sys_flistxattr
++
++	.globl	sys32_removexattr_wrapper
++sys32_removexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_removexattr
++
++	.globl	sys32_lremovexattr_wrapper
++sys32_lremovexattr_wrapper:
++	llgtr	%r2,%r2			# char *
++	llgtr	%r3,%r3			# char *
++	jg	sys_lremovexattr
++
++	.globl	sys32_fremovexattr_wrapper
++sys32_fremovexattr_wrapper:
++	lgfr	%r2,%r2			# int
++	llgtr	%r3,%r3			# char *
++	jg	sys_fremovexattr
+ 
+ 	.globl	sys32_stime_wrapper
+ sys32_stime_wrapper:
+--- linux-2.4.22-ac1/arch/sparc64/defconfig~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:40.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/sparc64/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ 
+ #
+ # Code maturity level options
+--- linux-2.4.22-ac1/arch/sparc/defconfig~xattr-0.8.54-2.4.22-rh	2002-08-03 04:39:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/arch/sparc/defconfig	2003-09-25 23:57:02.000000000 +0400
+@@ -1,6 +1,13 @@
+ #
+ # Automatically generated make config: don't edit
+ #
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT3_FS_XATTR_SHARING is not set
++# CONFIG_EXT3_FS_XATTR_USER is not set
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XATTR_SHARING is not set
++# CONFIG_EXT2_FS_XATTR_USER is not set
++# CONFIG_FS_MBCACHE is not set
+ CONFIG_UID16=y
+ CONFIG_HIGHMEM=y
+ 
+--- linux-2.4.22-ac1/Documentation/Configure.help~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:30.000000000 +0400
++++ linux-2.4.22-ac1-alexey/Documentation/Configure.help	2003-09-25 23:57:02.000000000 +0400
+@@ -16145,6 +16145,39 @@ CONFIG_EXT2_FS
+   be compiled as a module, and so this could be dangerous.  Most
+   everyone wants to say Y here.
+ 
++Ext2 extended attributes
++CONFIG_EXT2_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 extended attribute block sharing
++CONFIG_EXT2_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext2 extended user attributes
++CONFIG_EXT2_FS_XATTR_USER
++  This option enables extended user attributes on ext2. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext2 trusted extended attributes
++CONFIG_EXT2_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext2 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Ext3 journalling file system support (EXPERIMENTAL)
+ CONFIG_EXT3_FS
+   This is the journalling version of the Second extended file system
+@@ -16177,6 +16210,39 @@ CONFIG_EXT3_FS
+   of your root partition (the one containing the directory /) cannot
+   be compiled as a module, and so this may be dangerous.
+ 
++Ext3 extended attributes
++CONFIG_EXT3_FS_XATTR
++  Extended attributes are name:value pairs associated with inodes by
++  the kernel or by users (see the attr(5) manual page, or visit
++  <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 extended attribute block sharing
++CONFIG_EXT3_FS_XATTR_SHARING
++  This options enables code for sharing identical extended attribute
++  blocks among multiple inodes.
++
++  Usually, say Y.
++
++Ext3 extended user attributes
++CONFIG_EXT3_FS_XATTR_USER
++  This option enables extended user attributes on ext3. Processes can
++  associate extended user attributes with inodes to store additional
++  information such as the character encoding of files, etc. (see the
++  attr(5) manual page, or visit <http://acl.bestbits.at/> for details).
++
++  If unsure, say N.
++
++Ext3 trusted extended attributes
++CONFIG_EXT3_FS_XATTR_TRUSTED
++  This option enables extended attributes on ext3 that are accessible
++  (and visible) only to users capable of CAP_SYS_ADMIN. Usually this
++  is only the super user. Trusted extended attributes are meant for
++  implementing system/security services.
++
++  If unsure, say N.
++
+ Journal Block Device support (JBD for ext3) (EXPERIMENTAL)
+ CONFIG_JBD
+   This is a generic journalling layer for block devices.  It is
+--- linux-2.4.22-ac1/fs/Config.in~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:23.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/Config.in	2003-09-25 23:57:02.000000000 +0400
+@@ -29,6 +29,11 @@ dep_mbool '  Debug Befs' CONFIG_BEFS_DEB
+ dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
+ 
+ tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS
++dep_mbool '  Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS
++dep_bool '    Ext3 extended attribute block sharing' \
++    CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR
++dep_bool '    Ext3 extended user attributes' \
++    CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR
+ # CONFIG_JBD could be its own option (even modular), but until there are
+ # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
+ # dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
+@@ -88,6 +93,11 @@ dep_mbool '  QNX4FS write support (DANGE
+ tristate 'ROM file system support' CONFIG_ROMFS_FS
+ 
+ tristate 'Second extended fs support' CONFIG_EXT2_FS
++dep_mbool '  Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS
++dep_bool '    Ext2 extended attribute block sharing' \
++    CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR
++dep_bool '    Ext2 extended user attributes' \
++    CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR
+ 
+ tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS
+ 
+@@ -164,6 +174,10 @@ else
+    define_tristate CONFIG_ZISOFS_FS n
+ fi
+ 
++# Meta block cache for Extended Attributes (ext2/ext3)
++#tristate 'Meta block cache' CONFIG_FS_MBCACHE
++define_tristate CONFIG_FS_MBCACHE y 
++
+ mainmenu_option next_comment
+ comment 'Partition Types'
+ source fs/partitions/Config.in
+--- linux-2.4.22-ac1/fs/ext2/file.c~xattr-0.8.54-2.4.22-rh	2001-10-11 19:05:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/file.c	2003-09-25 23:57:02.000000000 +0400
+@@ -20,6 +20,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/sched.h>
+ 
+ /*
+@@ -51,4 +52,8 @@ struct file_operations ext2_file_operati
+ 
+ struct inode_operations ext2_file_inode_operations = {
+ 	truncate:	ext2_truncate,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- linux-2.4.22-ac1/fs/ext2/ialloc.c~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:37.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/ialloc.c	2003-09-25 23:57:02.000000000 +0400
+@@ -15,6 +15,7 @@
+ #include <linux/config.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/locks.h>
+ #include <linux/quotaops.h>
+ 
+@@ -167,6 +168,7 @@ void ext2_free_inode (struct inode * ino
+ 	 */
+ 	if (!is_bad_inode(inode)) {
+ 		/* Quota is already initialized in iput() */
++		ext2_xattr_delete_inode(inode);
+ 	    	DQUOT_FREE_INODE(inode);
+ 		DQUOT_DROP(inode);
+ 	}
+--- linux-2.4.22-ac1/fs/ext2/inode.c~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:37.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/inode.c	2003-09-25 23:57:02.000000000 +0400
+@@ -39,6 +39,18 @@ MODULE_LICENSE("GPL");
+ static int ext2_update_inode(struct inode * inode, int do_sync);
+ 
+ /*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext2_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext2_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
++/*
+  * Called at each iput()
+  */
+ void ext2_put_inode (struct inode * inode)
+@@ -53,9 +65,7 @@ void ext2_delete_inode (struct inode * i
+ {
+ 	lock_kernel();
+ 
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 	inode->u.ext2_i.i_dtime	= CURRENT_TIME;
+ 	mark_inode_dirty(inode);
+@@ -801,6 +811,8 @@ void ext2_truncate (struct inode * inode
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext2_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -903,8 +915,7 @@ void ext2_read_inode (struct inode * ino
+ 	unsigned long offset;
+ 	struct ext2_group_desc * gdp;
+ 
+-	if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
+-	     inode->i_ino != EXT2_ACL_DATA_INO &&
++	if ((inode->i_ino != EXT2_ROOT_INO &&
+ 	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||
+ 	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {
+ 		ext2_error (inode->i_sb, "ext2_read_inode",
+@@ -989,10 +1000,7 @@ void ext2_read_inode (struct inode * ino
+ 	for (block = 0; block < EXT2_N_BLOCKS; block++)
+ 		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
+ 
+-	if (inode->i_ino == EXT2_ACL_IDX_INO ||
+-	    inode->i_ino == EXT2_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext2_file_inode_operations;
+ 		inode->i_fop = &ext2_file_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+@@ -1001,15 +1009,17 @@ void ext2_read_inode (struct inode * ino
+ 		inode->i_fop = &ext2_dir_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext2_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext2_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext2_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext2_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext2_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(raw_inode->i_block[0]));
++	}
+ 	brelse (bh);
+ 	inode->i_attr_flags = 0;
+ 	ext2_set_inode_flags(inode);
+--- linux-2.4.22-ac1/fs/ext2/Makefile~xattr-0.8.54-2.4.22-rh	2001-10-11 19:05:18.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/Makefile	2003-09-25 23:57:02.000000000 +0400
+@@ -13,4 +13,8 @@ obj-y    := balloc.o bitmap.o dir.o file
+ 		ioctl.o namei.o super.o symlink.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.22-ac1/fs/ext2/namei.c~xattr-0.8.54-2.4.22-rh	2001-10-04 09:57:36.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/namei.c	2003-09-25 23:57:02.000000000 +0400
+@@ -31,6 +31,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/pagemap.h>
+ 
+ /*
+@@ -136,7 +137,7 @@ static int ext2_symlink (struct inode * 
+ 
+ 	if (l > sizeof (inode->u.ext2_i.i_data)) {
+ 		/* slow symlink */
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext2_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext2_aops;
+ 		err = block_symlink(inode, symname, l);
+ 		if (err)
+@@ -345,4 +346,15 @@ struct inode_operations ext2_dir_inode_o
+ 	rmdir:		ext2_rmdir,
+ 	mknod:		ext2_mknod,
+ 	rename:		ext2_rename,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
++struct inode_operations ext2_special_inode_operations = {
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- linux-2.4.22-ac1/fs/ext2/super.c~xattr-0.8.54-2.4.22-rh	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext2/super.c	2003-09-25 23:57:02.000000000 +0400
+@@ -21,6 +21,7 @@
+ #include <linux/string.h>
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -125,6 +126,7 @@ void ext2_put_super (struct super_block 
+ 	int db_count;
+ 	int i;
+ 
++	ext2_xattr_put_super(sb);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		struct ext2_super_block *es = EXT2_SB(sb)->s_es;
+ 
+@@ -175,6 +177,13 @@ static int parse_options (char * options
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -424,6 +433,9 @@ struct super_block * ext2_read_super (st
+ 	    blocksize = BLOCK_SIZE;
+ 
+ 	sb->u.ext2_sb.s_mount_opt = 0;
++#ifdef CONFIG_EXT2_FS_XATTR_USER
++	/* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */
++#endif
+ 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
+ 	    &sb->u.ext2_sb.s_mount_opt)) {
+ 		return NULL;
+@@ -813,12 +825,27 @@ static DECLARE_FSTYPE_DEV(ext2_fs_type, 
+ 
+ static int __init init_ext2_fs(void)
+ {
+-        return register_filesystem(&ext2_fs_type);
++	int error = init_ext2_xattr();
++	if (error)
++		return error;
++	error = init_ext2_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext2_fs_type);
++	if (!error)
++		return 0;
++
++	exit_ext2_xattr_user();
++fail:
++	exit_ext2_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext2_fs(void)
+ {
+ 	unregister_filesystem(&ext2_fs_type);
++	exit_ext2_xattr_user();
++	exit_ext2_xattr();
+ }
+ 
+ EXPORT_NO_SYMBOLS;
+--- linux-2.4.22-ac1/fs/ext2/symlink.c~xattr-0.8.54-2.4.22-rh	2000-09-28 00:41:33.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext2/symlink.c	2003-09-25 23:57:02.000000000 +0400
+@@ -19,6 +19,7 @@
+ 
+ #include <linux/fs.h>
+ #include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
+ 
+ static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -32,7 +33,20 @@ static int ext2_follow_link(struct dentr
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext2_symlink_inode_operations = {
++	readlink:	page_readlink,
++	follow_link:	page_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
++};
++
+ struct inode_operations ext2_fast_symlink_inode_operations = {
+ 	readlink:	ext2_readlink,
+ 	follow_link:	ext2_follow_link,
++	setxattr:	ext2_setxattr,
++	getxattr:	ext2_getxattr,
++	listxattr:	ext2_listxattr,
++	removexattr:	ext2_removexattr,
+ };
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext2/xattr.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,1212 @@
++/*
++ * linux/fs/ext2/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT2_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++/* These symbols may be needed by a module. */
++EXPORT_SYMBOL(ext2_xattr_register);
++EXPORT_SYMBOL(ext2_xattr_unregister);
++EXPORT_SYMBOL(ext2_xattr_get);
++EXPORT_SYMBOL(ext2_xattr_list);
++EXPORT_SYMBOL(ext2_xattr_set);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT2_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext2_xattr_set2(struct inode *, struct buffer_head *,
++			   struct ext2_xattr_header *);
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++static int ext2_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext2_xattr_cache_find(struct inode *,
++						 struct ext2_xattr_header *);
++static void ext2_xattr_cache_remove(struct buffer_head *);
++static void ext2_xattr_rehash(struct ext2_xattr_header *,
++			      struct ext2_xattr_entry *);
++
++static struct mb_cache *ext2_xattr_cache;
++
++#else
++# define ext2_xattr_cache_insert(bh) 0
++# define ext2_xattr_cache_find(inode, header) NULL
++# define ext2_xattr_cache_remove(bh) while(0) {}
++# define ext2_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext2_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext2_xattr_sem);
++
++static inline int
++ext2_xattr_new_block(struct inode *inode, int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) +
++		EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext2_new_block(inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext2_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext2_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext2_xattr_free_block(struct inode * inode, unsigned long block)
++{
++	ext2_free_blocks(inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext2_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext2_xattr_free_block(inode, block) \
++	ext2_free_blocks(inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX];
++rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		if (!ext2_xattr_handlers[name_index-1]) {
++			ext2_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext2_handler_lock);
++	}
++	return error;
++}
++
++void
++ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) {
++		write_lock(&ext2_handler_lock);
++		ext2_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext2_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static struct ext2_xattr_handler *
++ext2_xattr_resolve_name(const char **name)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext2_handler_lock);
++	for (i=0; i<EXT2_XATTR_INDEX_MAX; i++) {
++		if (ext2_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext2_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext2_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext2_handler_lock);
++	return handler;
++}
++
++static inline struct ext2_xattr_handler *
++ext2_xattr_handler(int name_index)
++{
++	struct ext2_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) {
++		read_lock(&ext2_handler_lock);
++		handler = ext2_xattr_handlers[name_index-1];
++		read_unlock(&ext2_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext2_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext2_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext2_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext2_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext2_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT2_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT2_I(inode)->i_file_acl)
++		return 0;
++	block = EXT2_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		struct ext2_xattr_entry *next =
++			EXT2_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext2_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT2_XATTR_NEXT(entry)) {
++		struct ext2_xattr_handler *handler;
++		
++		handler = ext2_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext2_xattr_update_super_block(struct super_block *sb)
++{
++	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT2_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext2_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext2_xattr_header *header = NULL;
++	struct ext2_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT2_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext2_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext2_error(sb, "ext2_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext2_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT2_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT2_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT2_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext2_xattr_cache_remove(bh);
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT2_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT2_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT2_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext2_xattr_set2(inode, bh, NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT2_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT2_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT2_XATTR_PAD, 0,
++			       EXT2_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext2_xattr_rehash(header, here);
++
++	error = ext2_xattr_set2(inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext2_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext2_xattr_set(): Update the file system.
++ */
++static int
++ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
++		struct ext2_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext2_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext2_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext2_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT2_I(inode)->i_file_acl != 0;
++			int block = ext2_xattr_new_block(inode, &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++				ext2_xattr_free_block(inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext2_xattr_cache_insert(new_bh);
++			
++			ext2_xattr_update_super_block(sb);
++		}
++		mark_buffer_dirty(new_bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &new_bh);
++			wait_on_buffer(new_bh); 
++			error = -EIO;
++			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
++				goto cleanup;
++		}
++	}
++
++	/* Update the inode. */
++	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	if (IS_SYNC(inode)) {
++		error = ext2_sync_inode (inode);
++		if (error)
++			goto cleanup;
++	} else
++		mark_inode_dirty(inode);
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext2_xattr_free_block(inode, old_bh->b_blocknr);
++			mark_buffer_clean(old_bh);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext2_xattr_quota_free(inode);
++			mark_buffer_dirty(old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext2_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT2_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext2_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext2_error(inode->i_sb, "ext2_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext2_xattr_cache_remove(bh);
++		ext2_xattr_free_block(inode, block);
++		bforget(bh);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		mark_buffer_dirty(bh);
++		if (IS_SYNC(inode)) {
++			ll_rw_block(WRITE, 1, &bh);
++			wait_on_buffer(bh);
++		}
++		ext2_xattr_quota_free(inode);
++	}
++	EXT2_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext2_xattr_sem);
++}
++
++/*
++ * ext2_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext2_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++	mb_cache_shrink(ext2_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT2_FS_XATTR_SHARING
++
++/*
++ * ext2_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext2_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext2_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext2_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext2_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext2_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext2_xattr_cmp(struct ext2_xattr_header *header1,
++	       struct ext2_xattr_header *header2)
++{
++	struct ext2_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT2_XATTR_NEXT(entry1);
++		entry2 = EXT2_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext2_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT2_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT2_XATTR_REFCOUNT_MAX);
++		} else if (!ext2_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext2_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext2_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header,
++					 struct ext2_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext2_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext2_xattr_rehash(struct ext2_xattr_header *header,
++			      struct ext2_xattr_entry *entry)
++{
++	struct ext2_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext2_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT2_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext2_xattr(void)
++{
++	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext2_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++	mb_cache_destroy(ext2_xattr_cache);
++}
++
++#else  /* CONFIG_EXT2_FS_XATTR_SHARING */
++
++int __init
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext2_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT2_FS_XATTR_SHARING */
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext2/xattr_user.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,103 @@
++/*
++ * linux/fs/ext2/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext2_fs.h>
++#include <linux/ext2_xattr.h>
++
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++# include <linux/ext2_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext2_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext2_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext2_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT2_FS_POSIX_ACL
++	error = ext2_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
++			      value, size, flags);
++}
++
++struct ext2_xattr_handler ext2_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext2_xattr_user_list,
++	get:	ext2_xattr_user_get,
++	set:	ext2_xattr_user_set,
++};
++
++int __init
++init_ext2_xattr_user(void)
++{
++	return ext2_xattr_register(EXT2_XATTR_INDEX_USER,
++				   &ext2_xattr_user_handler);
++}
++
++void
++exit_ext2_xattr_user(void)
++{
++	ext2_xattr_unregister(EXT2_XATTR_INDEX_USER,
++			      &ext2_xattr_user_handler);
++}
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/ext3-exports.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,13 @@
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
++
++EXPORT_SYMBOL(ext3_force_commit);
++EXPORT_SYMBOL(ext3_bread);
++EXPORT_SYMBOL(ext3_xattr_register);
++EXPORT_SYMBOL(ext3_xattr_unregister);
++EXPORT_SYMBOL(ext3_xattr_get);
++EXPORT_SYMBOL(ext3_xattr_list);
++EXPORT_SYMBOL(ext3_xattr_set);
+--- linux-2.4.22-ac1/fs/ext3/file.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:55:12.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/file.c	2003-09-25 23:57:02.000000000 +0400
+@@ -23,6 +23,7 @@
+ #include <linux/locks.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/ext3_jbd.h>
+ #include <linux/smp_lock.h>
+ 
+@@ -127,5 +128,9 @@ struct file_operations ext3_file_operati
+ struct inode_operations ext3_file_inode_operations = {
+ 	truncate:	ext3_truncate,		/* BKL held */
+ 	setattr:	ext3_setattr,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+ 
+--- linux-2.4.22-ac1/fs/ext3/ialloc.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c	2003-09-25 23:57:02.000000000 +0400
+@@ -17,6 +17,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+ #include <linux/locks.h>
+@@ -217,6 +218,7 @@ void ext3_free_inode (handle_t *handle, 
+ 	 * as writing the quota to disk may need the lock as well.
+ 	 */
+ 	DQUOT_INIT(inode);
++	ext3_xattr_delete_inode(handle, inode);
+ 	DQUOT_FREE_INODE(inode);
+ 	DQUOT_DROP(inode);
+ 
+--- linux-2.4.22-ac1/fs/ext3/inode.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:29.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c	2003-09-26 00:10:09.000000000 +0400
+@@ -39,6 +39,18 @@
+  */
+ #undef SEARCH_FROM_ZERO
+ 
++/*
++ * Test whether an inode is a fast symlink.
++ */
++static inline int ext3_inode_is_fast_symlink(struct inode *inode)
++{
++	int ea_blocks = inode->u.ext3_i.i_file_acl ?
++		(inode->i_sb->s_blocksize >> 9) : 0;
++
++	return (S_ISLNK(inode->i_mode) &&
++		inode->i_blocks - ea_blocks == 0);
++}
++
+ /* The ext3 forget function must perform a revoke if we are freeing data
+  * which has been journaled.  Metadata (eg. indirect blocks) must be
+  * revoked in all cases. 
+@@ -48,7 +60,7 @@
+  * still needs to be revoked.
+  */
+ 
+-static int ext3_forget(handle_t *handle, int is_metadata,
++int ext3_forget(handle_t *handle, int is_metadata,
+ 		       struct inode *inode, struct buffer_head *bh,
+ 		       int blocknr)
+ {
+@@ -179,9 +191,7 @@ void ext3_delete_inode (struct inode * i
+ {
+ 	handle_t *handle;
+ 	
+-	if (is_bad_inode(inode) ||
+-	    inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
++	if (is_bad_inode(inode))
+ 		goto no_delete;
+ 
+ 	lock_kernel();
+@@ -1874,6 +1884,8 @@ void ext3_truncate(struct inode * inode)
+ 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ 	    S_ISLNK(inode->i_mode)))
+ 		return;
++	if (ext3_inode_is_fast_symlink(inode))
++		return;
+ 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ 		return;
+ 
+@@ -2021,8 +2033,6 @@ int ext3_get_inode_loc (struct inode *in
+ 	struct ext3_group_desc * gdp;
+ 		
+ 	if ((inode->i_ino != EXT3_ROOT_INO &&
+-		inode->i_ino != EXT3_ACL_IDX_INO &&
+-		inode->i_ino != EXT3_ACL_DATA_INO &&
+ 		inode->i_ino != EXT3_JOURNAL_INO &&
+ 		inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
+ 		inode->i_ino > le32_to_cpu(
+@@ -2163,10 +2173,7 @@ void ext3_read_inode(struct inode * inod
+ 		inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block];
+ 	INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan);
+ 
+-	if (inode->i_ino == EXT3_ACL_IDX_INO ||
+-	    inode->i_ino == EXT3_ACL_DATA_INO)
+-		/* Nothing to do */ ;
+-	else if (S_ISREG(inode->i_mode)) {
++	if (S_ISREG(inode->i_mode)) {
+ 		inode->i_op = &ext3_file_inode_operations;
+ 		inode->i_fop = &ext3_file_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+@@ -2174,15 +2181,17 @@ void ext3_read_inode(struct inode * inod
+ 		inode->i_op = &ext3_dir_inode_operations;
+ 		inode->i_fop = &ext3_dir_operations;
+ 	} else if (S_ISLNK(inode->i_mode)) {
+-		if (!inode->i_blocks)
++		if (ext3_inode_is_fast_symlink(inode))
+ 			inode->i_op = &ext3_fast_symlink_inode_operations;
+ 		else {
+-			inode->i_op = &page_symlink_inode_operations;
++			inode->i_op = &ext3_symlink_inode_operations;
+ 			inode->i_mapping->a_ops = &ext3_aops;
+ 		}
+-	} else 
++	} else {
++		inode->i_op = &ext3_special_inode_operations;
+ 		init_special_inode(inode, inode->i_mode,
+ 				   le32_to_cpu(iloc.raw_inode->i_block[0]));
++	}
+ 	brelse(iloc.bh);
+ 	ext3_set_inode_flags(inode);
+ 	return;
+--- linux-2.4.22-ac1/fs/ext3/Makefile~xattr-0.8.54-2.4.22-rh	2003-09-25 14:55:12.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/Makefile	2003-09-25 23:57:02.000000000 +0400
+@@ -1,5 +1,5 @@
+ #
+-# Makefile for the linux ext2-filesystem routines.
++# Makefile for the linux ext3-filesystem routines.
+ #
+ # Note! Dependencies are done automagically by 'make dep', which also
+ # removes any old dependencies. DON'T put your own dependencies here
+@@ -9,10 +9,14 @@
+ 
+ O_TARGET := ext3.o
+ 
+-export-objs :=	super.o inode.o
++export-objs := ext3-exports.o
+ 
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+-		ioctl.o namei.o super.o symlink.o hash.o
++		ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ obj-m    := $(O_TARGET)
+ 
++export-objs += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
++obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
++
+ include $(TOPDIR)/Rules.make
+--- linux-2.4.22-ac1/fs/ext3/namei.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:58:37.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c	2003-09-25 23:57:02.000000000 +0400
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/fcntl.h>
+ #include <linux/stat.h>
+ #include <linux/string.h>
+@@ -1614,7 +1615,7 @@ static int ext3_mkdir(struct inode * dir
+ 	if (IS_SYNC(dir))
+ 		handle->h_sync = 1;
+ 
+-	inode = ext3_new_inode (handle, dir, S_IFDIR);
++	inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+ 	err = PTR_ERR(inode);
+ 	if (IS_ERR(inode))
+ 		goto out_stop;
+@@ -1622,7 +1623,6 @@ static int ext3_mkdir(struct inode * dir
+ 	inode->i_op = &ext3_dir_inode_operations;
+ 	inode->i_fop = &ext3_dir_operations;
+ 	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+-	inode->i_blocks = 0;	
+ 	dir_block = ext3_bread (handle, inode, 0, 1, &err);
+ 	if (!dir_block) {
+ 		inode->i_nlink--; /* is this nlink == 0? */
+@@ -1649,9 +1649,6 @@ static int ext3_mkdir(struct inode * dir
+ 	BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata");
+ 	ext3_journal_dirty_metadata(handle, dir_block);
+ 	brelse (dir_block);
+-	inode->i_mode = S_IFDIR | mode;
+-	if (dir->i_mode & S_ISGID)
+-		inode->i_mode |= S_ISGID;
+ 	ext3_mark_inode_dirty(handle, inode);
+ 	err = ext3_add_entry (handle, dentry, inode);
+ 	if (err) {
+@@ -2020,7 +2017,7 @@ static int ext3_symlink (struct inode * 
+ 		goto out_stop;
+ 
+ 	if (l > sizeof (EXT3_I(inode)->i_data)) {
+-		inode->i_op = &page_symlink_inode_operations;
++		inode->i_op = &ext3_symlink_inode_operations;
+ 		inode->i_mapping->a_ops = &ext3_aops;
+ 		/*
+ 		 * block_symlink() calls back into ext3_prepare/commit_write.
+@@ -2245,4 +2242,16 @@ struct inode_operations ext3_dir_inode_o
+ 	rmdir:		ext3_rmdir,		/* BKL held */
+ 	mknod:		ext3_mknod,		/* BKL held */
+ 	rename:		ext3_rename,		/* BKL held */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
++
++struct inode_operations ext3_special_inode_operations = {
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+--- linux-2.4.22-ac1/fs/ext3/super.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:55:12.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/ext3/super.c	2003-09-26 00:12:23.000000000 +0400
+@@ -24,6 +24,7 @@
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
++#include <linux/ext3_xattr.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/locks.h>
+@@ -406,6 +407,7 @@ void ext3_put_super (struct super_block 
+ 	kdev_t j_dev = sbi->s_journal->j_dev;
+ 	int i;
+ 
++	ext3_xattr_put_super(sb);
+ 	journal_destroy(sbi->s_journal);
+ 	if (!(sb->s_flags & MS_RDONLY)) {
+ 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
+@@ -506,6 +508,7 @@ static int parse_options (char * options
+ 			  int is_remount)
+ {
+ 	unsigned long *mount_options = &sbi->s_mount_opt;
++	
+ 	uid_t *resuid = &sbi->s_resuid;
+ 	gid_t *resgid = &sbi->s_resgid;
+ 	char * this_char;
+@@ -518,6 +521,13 @@ static int parse_options (char * options
+ 	     this_char = strtok (NULL, ",")) {
+ 		if ((value = strchr (this_char, '=')) != NULL)
+ 			*value++ = 0;
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++		if (!strcmp (this_char, "user_xattr"))
++			set_opt (*mount_options, XATTR_USER);
++		else if (!strcmp (this_char, "nouser_xattr"))
++			clear_opt (*mount_options, XATTR_USER);
++		else
++#endif
+ 		if (!strcmp (this_char, "bsddf"))
+ 			clear_opt (*mount_options, MINIX_DF);
+ 		else if (!strcmp (this_char, "nouid32")) {
+@@ -935,6 +945,12 @@ struct super_block * ext3_read_super (st
+ 	sbi->s_mount_opt = 0;
+ 	sbi->s_resuid = EXT3_DEF_RESUID;
+ 	sbi->s_resgid = EXT3_DEF_RESGID;
++
++	/* Default extended attribute flags */
++#ifdef CONFIG_EXT3_FS_XATTR_USER
++	/* set_opt(sbi->s_mount_opt, XATTR_USER); */
++#endif
++
+ 	if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) {
+ 		sb->s_dev = 0;
+ 		goto out_fail;
+@@ -1839,22 +1855,35 @@ static DECLARE_FSTYPE_DEV(ext3_fs_type, 
+ 
+ static int __init init_ext3_fs(void)
+ {
++	int error;
+ #ifdef CONFIG_QUOTA
+ 	init_dquot_operations(&ext3_qops);
+ 	old_sync_dquot = ext3_qops.sync_dquot;
+ 	ext3_qops.sync_dquot = ext3_sync_dquot;
+ #endif
+-        return register_filesystem(&ext3_fs_type);
++	error = init_ext3_xattr();
++	if (error)
++		return error;
++	error = init_ext3_xattr_user();
++	if (error)
++		goto fail;
++	error = register_filesystem(&ext3_fs_type);
++	if (!error)
++		return 0;
++	
++	exit_ext3_xattr_user();
++fail:
++	exit_ext3_xattr();
++	return error;
+ }
+ 
+ static void __exit exit_ext3_fs(void)
+ {
+ 	unregister_filesystem(&ext3_fs_type);
++	exit_ext3_xattr_user();
++	exit_ext3_xattr();
+ }
+ 
+-EXPORT_SYMBOL(ext3_force_commit);
+-EXPORT_SYMBOL(ext3_bread);
+-
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
+ MODULE_LICENSE("GPL");
+--- linux-2.4.22-ac1/fs/ext3/symlink.c~xattr-0.8.54-2.4.22-rh	2001-11-10 01:25:04.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/symlink.c	2003-09-25 23:57:02.000000000 +0400
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
+ 
+ static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen)
+ {
+@@ -33,7 +34,20 @@ static int ext3_follow_link(struct dentr
+ 	return vfs_follow_link(nd, s);
+ }
+ 
++struct inode_operations ext3_symlink_inode_operations = {
++	readlink:	page_readlink,		/* BKL not held.  Don't need */
++	follow_link:	page_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
++};
++
+ struct inode_operations ext3_fast_symlink_inode_operations = {
+ 	readlink:	ext3_readlink,		/* BKL not held.  Don't need */
+ 	follow_link:	ext3_follow_link,	/* BKL not held.  Don't need */
++	setxattr:	ext3_setxattr,		/* BKL held */
++	getxattr:	ext3_getxattr,		/* BKL held */
++	listxattr:	ext3_listxattr,		/* BKL held */
++	removexattr:	ext3_removexattr,	/* BKL held */
+ };
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/xattr.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,1225 @@
++/*
++ * linux/fs/ext3/xattr.c
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ *
++ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
++ * Ext3 code with a lot of help from Eric Jarman <ejarman@acm.org>.
++ * Extended attributes for symlinks and special files added per
++ *  suggestion of Luka Renko <luka.renko@hermes.si>.
++ */
++
++/*
++ * Extended attributes are stored on disk blocks allocated outside of
++ * any inode. The i_file_acl field is then made to point to this allocated
++ * block. If all extended attributes of an inode are identical, these
++ * inodes may share the same extended attribute block. Such situations
++ * are automatically detected by keeping a cache of recent attribute block
++ * numbers and hashes over the block's contents in memory.
++ *
++ *
++ * Extended attribute block layout:
++ *
++ *   +------------------+
++ *   | header           |
++ *   | entry 1          | |
++ *   | entry 2          | | growing downwards
++ *   | entry 3          | v
++ *   | four null bytes  |
++ *   | . . .            |
++ *   | value 1          | ^
++ *   | value 3          | | growing upwards
++ *   | value 2          | |
++ *   +------------------+
++ *
++ * The block header is followed by multiple entry descriptors. These entry
++ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
++ * byte boundaries. The entry descriptors are sorted by attribute name,
++ * so that two extended attribute blocks can be compared efficiently.
++ *
++ * Attribute values are aligned to the end of the block, stored in
++ * no specific order. They are also padded to EXT3_XATTR_PAD byte
++ * boundaries. No additional gaps are left between them.
++ *
++ * Locking strategy
++ * ----------------
++ * The VFS already holds the BKL and the inode->i_sem semaphore when any of
++ * the xattr inode operations are called, so we are guaranteed that only one
++ * processes accesses extended attributes of an inode at any time.
++ *
++ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that
++ * only a single process is modifying an extended attribute block, even
++ * if the block is shared among inodes.
++ *
++ * Note for porting to 2.5
++ * -----------------------
++ * The BKL will no longer be held in the xattr inode operations.
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/locks.h>
++#include <linux/slab.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++#include <linux/mbcache.h>
++#include <linux/quotaops.h>
++#include <asm/semaphore.h>
++#include <linux/compatmac.h>
++
++#define EXT3_EA_USER "user."
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1)
++#endif
++
++#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
++#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
++#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
++#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
++
++#ifdef EXT3_XATTR_DEBUG
++# define ea_idebug(inode, f...) do { \
++		printk(KERN_DEBUG "inode %s:%ld: ", \
++			kdevname(inode->i_dev), inode->i_ino); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++# define ea_bdebug(bh, f...) do { \
++		printk(KERN_DEBUG "block %s:%ld: ", \
++			kdevname(bh->b_dev), bh->b_blocknr); \
++		printk(f); \
++		printk("\n"); \
++	} while (0)
++#else
++# define ea_idebug(f...)
++# define ea_bdebug(f...)
++#endif
++
++static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
++			   struct ext3_xattr_header *);
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++static int ext3_xattr_cache_insert(struct buffer_head *);
++static struct buffer_head *ext3_xattr_cache_find(struct inode *,
++						 struct ext3_xattr_header *);
++static void ext3_xattr_cache_remove(struct buffer_head *);
++static void ext3_xattr_rehash(struct ext3_xattr_header *,
++			      struct ext3_xattr_entry *);
++
++static struct mb_cache *ext3_xattr_cache;
++
++#else
++# define ext3_xattr_cache_insert(bh) 0
++# define ext3_xattr_cache_find(inode, header) NULL
++# define ext3_xattr_cache_remove(bh) while(0) {}
++# define ext3_xattr_rehash(header, entry) while(0) {}
++#endif
++
++/*
++ * If a file system does not share extended attributes among inodes,
++ * we should not need the ext3_xattr_sem semaphore. However, the
++ * filesystem may still contain shared blocks, so we always take
++ * the lock.
++ */
++
++DECLARE_MUTEX(ext3_xattr_sem);
++
++static inline int
++ext3_xattr_new_block(handle_t *handle, struct inode *inode,
++		     int * errp, int force)
++{
++	struct super_block *sb = inode->i_sb;
++	int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
++		EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb);
++
++	/* How can we enforce the allocation? */
++	int block = ext3_new_block(handle, inode, goal, 0, 0, errp);
++#ifdef OLD_QUOTAS
++	if (!*errp)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#endif
++	return block;
++}
++
++static inline int
++ext3_xattr_quota_alloc(struct inode *inode, int force)
++{
++	/* How can we enforce the allocation? */
++#ifdef OLD_QUOTAS
++	int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1);
++	if (!error)
++		inode->i_blocks += inode->i_sb->s_blocksize >> 9;
++#else
++	int error = DQUOT_ALLOC_BLOCK(inode, 1);
++#endif
++	return error;
++}
++
++#ifdef OLD_QUOTAS
++
++static inline void
++ext3_xattr_quota_free(struct inode *inode)
++{
++	DQUOT_FREE_BLOCK(inode->i_sb, inode, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++static inline void
++ext3_xattr_free_block(handle_t *handle, struct inode * inode,
++		      unsigned long block)
++{
++	ext3_free_blocks(handle, inode, block, 1);
++	inode->i_blocks -= inode->i_sb->s_blocksize >> 9;
++}
++
++#else
++# define ext3_xattr_quota_free(inode) \
++	DQUOT_FREE_BLOCK(inode, 1)
++# define ext3_xattr_free_block(handle, inode, block) \
++	ext3_free_blocks(handle, inode, block, 1)
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
++
++static inline struct buffer_head *
++sb_bread(struct super_block *sb, int block)
++{
++	return bread(sb->s_dev, block, sb->s_blocksize);
++}
++
++static inline struct buffer_head *
++sb_getblk(struct super_block *sb, int block)
++{
++	return getblk(sb->s_dev, block, sb->s_blocksize);
++}
++
++#endif
++
++struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX];
++rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED;
++
++int
++ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler)
++{
++	int error = -EINVAL;
++
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		if (!ext3_xattr_handlers[name_index-1]) {
++			ext3_xattr_handlers[name_index-1] = handler;
++			error = 0;
++		}
++		write_unlock(&ext3_handler_lock);
++	}
++	return error;
++}
++
++void
++ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler)
++{
++	if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) {
++		write_lock(&ext3_handler_lock);
++		ext3_xattr_handlers[name_index-1] = NULL;
++		write_unlock(&ext3_handler_lock);
++	}
++}
++
++static inline const char *
++strcmp_prefix(const char *a, const char *a_prefix)
++{
++	while (*a_prefix && *a == *a_prefix) {
++		a++;
++		a_prefix++;
++	}
++	return *a_prefix ? NULL : a;
++}
++
++/*
++ * Decode the extended attribute name, and translate it into
++ * the name_index and name suffix.
++ */
++static inline struct ext3_xattr_handler *
++ext3_xattr_resolve_name(const char **name)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	int i;
++
++	if (!*name)
++		return NULL;
++	read_lock(&ext3_handler_lock);
++	for (i=0; i<EXT3_XATTR_INDEX_MAX; i++) {
++		if (ext3_xattr_handlers[i]) {
++			const char *n = strcmp_prefix(*name,
++				ext3_xattr_handlers[i]->prefix);
++			if (n) {
++				handler = ext3_xattr_handlers[i];
++				*name = n;
++				break;
++			}
++		}
++	}
++	read_unlock(&ext3_handler_lock);
++	return handler;
++}
++
++static inline struct ext3_xattr_handler *
++ext3_xattr_handler(int name_index)
++{
++	struct ext3_xattr_handler *handler = NULL;
++	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) {
++		read_lock(&ext3_handler_lock);
++		handler = ext3_xattr_handlers[name_index-1];
++		read_unlock(&ext3_handler_lock);
++	}
++	return handler;
++}
++
++/*
++ * Inode operation getxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_getxattr(struct dentry *dentry, const char *name,
++	      void *buffer, size_t size)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->get(inode, name, buffer, size);
++}
++
++/*
++ * Inode operation listxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++ssize_t
++ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
++{
++	return ext3_xattr_list(dentry->d_inode, buffer, size);
++}
++
++/*
++ * Inode operation setxattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_setxattr(struct dentry *dentry, const char *name,
++	      const void *value, size_t size, int flags)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	if (size == 0)
++		value = "";  /* empty EA, do not remove */
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, value, size, flags);
++}
++
++/*
++ * Inode operation removexattr()
++ *
++ * dentry->d_inode->i_sem down
++ * BKL held [before 2.5.x]
++ */
++int
++ext3_removexattr(struct dentry *dentry, const char *name)
++{
++	struct ext3_xattr_handler *handler;
++	struct inode *inode = dentry->d_inode;
++
++	handler = ext3_xattr_resolve_name(&name);
++	if (!handler)
++		return -ENOTSUP;
++	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
++}
++
++/*
++ * ext3_xattr_get()
++ *
++ * Copy an extended attribute into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size;
++	char *end;
++	int name_len, error;
++
++	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
++		  name_index, name, buffer, (long)buffer_size);
++
++	if (name == NULL)
++		return -EINVAL;
++	if (!EXT3_I(inode)->i_file_acl)
++		return -ENOATTR;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* find named attribute */
++	name_len = strlen(name);
++
++	error = -ERANGE;
++	if (name_len > 255)
++		goto cleanup;
++	entry = FIRST_ENTRY(bh);
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		if (name_index == entry->e_name_index &&
++		    name_len == entry->e_name_len &&
++		    memcmp(name, entry->e_name, name_len) == 0)
++			goto found;
++		entry = next;
++	}
++	/* Check the remaining name entries */
++	while (!IS_LAST_ENTRY(entry)) {
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++		entry = next;
++	}
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	error = -ENOATTR;
++	goto cleanup;
++found:
++	/* check the buffer size */
++	if (entry->e_value_block != 0)
++		goto bad_block;
++	size = le32_to_cpu(entry->e_value_size);
++	if (size > inode->i_sb->s_blocksize ||
++	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
++		goto bad_block;
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (buffer) {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++		/* return value of attribute */
++		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
++			size);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_list()
++ *
++ * Copy a list of attribute names into the buffer
++ * provided, or compute the buffer size required.
++ * Buffer is NULL to compute the size of the buffer required.
++ *
++ * Returns a negative error number on failure, or the number of bytes
++ * used / required on success.
++ */
++int
++ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
++{
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_entry *entry;
++	unsigned int block, size = 0;
++	char *buf, *end;
++	int error;
++
++	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
++		  buffer, (long)buffer_size);
++
++	if (!EXT3_I(inode)->i_file_acl)
++		return 0;
++	block = EXT3_I(inode)->i_file_acl;
++	ea_idebug(inode, "reading block %d", block);
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh)
++		return -EIO;
++	ea_bdebug(bh, "b_count=%d, refcount=%d",
++		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
++	end = bh->b_data + bh->b_size;
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		error = -EIO;
++		goto cleanup;
++	}
++	/* compute the size required for the list of attribute names */
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++		struct ext3_xattr_entry *next =
++			EXT3_XATTR_NEXT(entry);
++		if ((char *)next >= end)
++			goto bad_block;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			size += handler->list(NULL, inode, entry->e_name,
++					      entry->e_name_len);
++	}
++
++	if (ext3_xattr_cache_insert(bh))
++		ea_idebug(inode, "cache insert failed");
++	if (!buffer) {
++		error = size;
++		goto cleanup;
++	} else {
++		error = -ERANGE;
++		if (size > buffer_size)
++			goto cleanup;
++	}
++
++	/* list the attribute names */
++	buf = buffer;
++	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
++	     entry = EXT3_XATTR_NEXT(entry)) {
++		struct ext3_xattr_handler *handler;
++
++		handler = ext3_xattr_handler(entry->e_name_index);
++		if (handler)
++			buf += handler->list(buf, inode, entry->e_name,
++					     entry->e_name_len);
++	}
++	error = size;
++
++cleanup:
++	brelse(bh);
++
++	return error;
++}
++
++/*
++ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
++ * not set, set it.
++ */
++static void ext3_xattr_update_super_block(handle_t *handle,
++					  struct super_block *sb)
++{
++	if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR))
++		return;
++
++	lock_super(sb);
++	ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++	EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR;
++#endif
++	EXT3_SB(sb)->s_es->s_feature_compat |=
++		cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR);
++	sb->s_dirt = 1;
++	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++	unlock_super(sb);
++}
++
++/*
++ * ext3_xattr_set()
++ *
++ * Create, replace or remove an extended attribute for this inode. Buffer
++ * is NULL to remove an existing extended attribute, and non-NULL to
++ * either replace an existing extended attribute, or create a new extended
++ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
++ * specify that an extended attribute must exist and must not exist
++ * previous to the call, respectively.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t value_len, int flags)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh = NULL;
++	struct ext3_xattr_header *header = NULL;
++	struct ext3_xattr_entry *here, *last;
++	unsigned int name_len;
++	int block = EXT3_I(inode)->i_file_acl;
++	int min_offs = sb->s_blocksize, not_found = 1, free, error;
++	char *end;
++	
++	/*
++	 * header -- Points either into bh, or to a temporarily
++	 *           allocated buffer.
++	 * here -- The named entry found, or the place for inserting, within
++	 *         the block pointed to by header.
++	 * last -- Points right after the last named entry within the block
++	 *         pointed to by header.
++	 * min_offs -- The offset of the first value (values are aligned
++	 *             towards the end of the block).
++	 * end -- Points right after the block pointed to by header.
++	 */
++	
++	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
++		  name_index, name, value, (long)value_len);
++
++	if (IS_RDONLY(inode))
++		return -EROFS;
++	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
++		return -EPERM;
++	if (value == NULL)
++		value_len = 0;
++	if (name == NULL)
++		return -EINVAL;
++	name_len = strlen(name);
++	if (name_len > 255 || value_len > sb->s_blocksize)
++		return -ERANGE;
++	down(&ext3_xattr_sem);
++
++	if (block) {
++		/* The inode already has an extended attribute block. */
++		bh = sb_bread(sb, block);
++		error = -EIO;
++		if (!bh)
++			goto cleanup;
++		ea_bdebug(bh, "b_count=%d, refcount=%d",
++			atomic_read(&(bh->b_count)),
++			le32_to_cpu(HDR(bh)->h_refcount));
++		header = HDR(bh);
++		end = bh->b_data + bh->b_size;
++		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++		    header->h_blocks != cpu_to_le32(1)) {
++bad_block:		ext3_error(sb, "ext3_xattr_set",
++				"inode %ld: bad block %d", inode->i_ino, block);
++			error = -EIO;
++			goto cleanup;
++		}
++		/* Find the named attribute. */
++		here = FIRST_ENTRY(bh);
++		while (!IS_LAST_ENTRY(here)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!here->e_value_block && here->e_value_size) {
++				int offs = le16_to_cpu(here->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			not_found = name_index - here->e_name_index;
++			if (!not_found)
++				not_found = name_len - here->e_name_len;
++			if (!not_found)
++				not_found = memcmp(name, here->e_name,name_len);
++			if (not_found <= 0)
++				break;
++			here = next;
++		}
++		last = here;
++		/* We still need to compute min_offs and last. */
++		while (!IS_LAST_ENTRY(last)) {
++			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
++			if ((char *)next >= end)
++				goto bad_block;
++			if (!last->e_value_block && last->e_value_size) {
++				int offs = le16_to_cpu(last->e_value_offs);
++				if (offs < min_offs)
++					min_offs = offs;
++			}
++			last = next;
++		}
++
++		/* Check whether we have enough space left. */
++		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
++	} else {
++		/* We will use a new extended attribute block. */
++		free = sb->s_blocksize -
++			sizeof(struct ext3_xattr_header) - sizeof(__u32);
++		here = last = NULL;  /* avoid gcc uninitialized warning. */
++	}
++
++	if (not_found) {
++		/* Request to remove a nonexistent attribute? */
++		error = -ENOATTR;
++		if (flags & XATTR_REPLACE)
++			goto cleanup;
++		error = 0;
++		if (value == NULL)
++			goto cleanup;
++		else
++			free -= EXT3_XATTR_LEN(name_len);
++	} else {
++		/* Request to create an existing attribute? */
++		error = -EEXIST;
++		if (flags & XATTR_CREATE)
++			goto cleanup;
++		if (!here->e_value_block && here->e_value_size) {
++			unsigned int size = le32_to_cpu(here->e_value_size);
++
++			if (le16_to_cpu(here->e_value_offs) + size > 
++			    sb->s_blocksize || size > sb->s_blocksize)
++				goto bad_block;
++			free += EXT3_XATTR_SIZE(size);
++		}
++	}
++	free -= EXT3_XATTR_SIZE(value_len);
++	error = -ENOSPC;
++	if (free < 0)
++		goto cleanup;
++
++	/* Here we know that we can set the new attribute. */
++
++	if (header) {
++		if (header->h_refcount == cpu_to_le32(1)) {
++			ea_bdebug(bh, "modifying in-place");
++			ext3_xattr_cache_remove(bh);
++			error = ext3_journal_get_write_access(handle, bh);
++			if (error)
++				goto cleanup;
++		} else {
++			int offset;
++
++			ea_bdebug(bh, "cloning");
++			header = kmalloc(bh->b_size, GFP_KERNEL);
++			error = -ENOMEM;
++			if (header == NULL)
++				goto cleanup;
++			memcpy(header, HDR(bh), bh->b_size);
++			header->h_refcount = cpu_to_le32(1);
++			offset = (char *)header - bh->b_data;
++			here = ENTRY((char *)here + offset);
++			last = ENTRY((char *)last + offset);
++		}
++	} else {
++		/* Allocate a buffer where we construct the new block. */
++		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
++		error = -ENOMEM;
++		if (header == NULL)
++			goto cleanup;
++		memset(header, 0, sb->s_blocksize);
++		end = (char *)header + sb->s_blocksize;
++		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
++		header->h_blocks = header->h_refcount = cpu_to_le32(1);
++		last = here = ENTRY(header+1);
++	}
++
++	if (not_found) {
++		/* Insert the new name. */
++		int size = EXT3_XATTR_LEN(name_len);
++		int rest = (char *)last - (char *)here;
++		memmove((char *)here + size, here, rest);
++		memset(here, 0, size);
++		here->e_name_index = name_index;
++		here->e_name_len = name_len;
++		memcpy(here->e_name, name, name_len);
++	} else {
++		/* Remove the old value. */
++		if (!here->e_value_block && here->e_value_size) {
++			char *first_val = (char *)header + min_offs;
++			int offs = le16_to_cpu(here->e_value_offs);
++			char *val = (char *)header + offs;
++			size_t size = EXT3_XATTR_SIZE(
++				le32_to_cpu(here->e_value_size));
++			memmove(first_val + size, first_val, val - first_val);
++			memset(first_val, 0, size);
++			here->e_value_offs = 0;
++			min_offs += size;
++
++			/* Adjust all value offsets. */
++			last = ENTRY(header+1);
++			while (!IS_LAST_ENTRY(last)) {
++				int o = le16_to_cpu(last->e_value_offs);
++				if (!last->e_value_block && o < offs)
++					last->e_value_offs =
++						cpu_to_le16(o + size);
++				last = EXT3_XATTR_NEXT(last);
++			}
++		}
++		if (value == NULL) {
++			/* Remove this attribute. */
++			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
++				/* This block is now empty. */
++				error = ext3_xattr_set2(handle, inode, bh,NULL);
++				goto cleanup;
++			} else {
++				/* Remove the old name. */
++				int size = EXT3_XATTR_LEN(name_len);
++				last = ENTRY((char *)last - size);
++				memmove(here, (char*)here + size,
++					(char*)last - (char*)here);
++				memset(last, 0, size);
++			}
++		}
++	}
++
++	if (value != NULL) {
++		/* Insert the new value. */
++		here->e_value_size = cpu_to_le32(value_len);
++		if (value_len) {
++			size_t size = EXT3_XATTR_SIZE(value_len);
++			char *val = (char *)header + min_offs - size;
++			here->e_value_offs =
++				cpu_to_le16((char *)val - (char *)header);
++			memset(val + size - EXT3_XATTR_PAD, 0,
++			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
++			memcpy(val, value, value_len);
++		}
++	}
++	ext3_xattr_rehash(header, here);
++
++	error = ext3_xattr_set2(handle, inode, bh, header);
++
++cleanup:
++	brelse(bh);
++	if (!(bh && header == HDR(bh)))
++		kfree(header);
++	up(&ext3_xattr_sem);
++
++	return error;
++}
++
++/*
++ * Second half of ext3_xattr_set(): Update the file system.
++ */
++static int
++ext3_xattr_set2(handle_t *handle, struct inode *inode,
++		struct buffer_head *old_bh, struct ext3_xattr_header *header)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *new_bh = NULL;
++	int error;
++
++	if (header) {
++		new_bh = ext3_xattr_cache_find(inode, header);
++		if (new_bh) {
++			/*
++			 * We found an identical block in the cache.
++			 * The old block will be released after updating
++			 * the inode.
++			 */
++			ea_bdebug(old_bh, "reusing block %ld",
++				new_bh->b_blocknr);
++			
++			error = -EDQUOT;
++			if (ext3_xattr_quota_alloc(inode, 1))
++				goto cleanup;
++			
++			error = ext3_journal_get_write_access(handle, new_bh);
++			if (error)
++				goto cleanup;
++			HDR(new_bh)->h_refcount = cpu_to_le32(
++				le32_to_cpu(HDR(new_bh)->h_refcount) + 1);
++			ea_bdebug(new_bh, "refcount now=%d",
++				le32_to_cpu(HDR(new_bh)->h_refcount));
++		} else if (old_bh && header == HDR(old_bh)) {
++			/* Keep this block. */
++			new_bh = old_bh;
++			ext3_xattr_cache_insert(new_bh);
++		} else {
++			/* We need to allocate a new block */
++			int force = EXT3_I(inode)->i_file_acl != 0;
++			int block = ext3_xattr_new_block(handle, inode,
++							 &error, force);
++			if (error)
++				goto cleanup;
++			ea_idebug(inode, "creating block %d", block);
++
++			new_bh = sb_getblk(sb, block);
++			if (!new_bh) {
++getblk_failed:			ext3_xattr_free_block(handle, inode, block);
++				error = -EIO;
++				goto cleanup;
++			}
++			lock_buffer(new_bh);
++			error = ext3_journal_get_create_access(handle, new_bh);
++			if (error) {
++				unlock_buffer(new_bh);
++				goto getblk_failed;
++			}
++			memcpy(new_bh->b_data, header, new_bh->b_size);
++			mark_buffer_uptodate(new_bh, 1);
++			unlock_buffer(new_bh);
++			ext3_xattr_cache_insert(new_bh);
++			
++			ext3_xattr_update_super_block(handle, sb);
++		}
++		error = ext3_journal_dirty_metadata(handle, new_bh);
++		if (error)
++			goto cleanup;
++	}
++
++	/* Update the inode. */
++	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
++	inode->i_ctime = CURRENT_TIME;
++	ext3_mark_inode_dirty(handle, inode);
++	if (IS_SYNC(inode))
++		handle->h_sync = 1;
++
++	error = 0;
++	if (old_bh && old_bh != new_bh) {
++		/*
++		 * If there was an old block, and we are not still using it,
++		 * we now release the old block.
++		*/
++		unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount);
++
++		error = ext3_journal_get_write_access(handle, old_bh);
++		if (error)
++			goto cleanup;
++		if (refcount == 1) {
++			/* Free the old block. */
++			ea_bdebug(old_bh, "freeing");
++			ext3_xattr_free_block(handle, inode, old_bh->b_blocknr);
++
++			/* ext3_forget() calls bforget() for us, but we
++			   let our caller release old_bh, so we need to
++			   duplicate the handle before. */
++			get_bh(old_bh);
++			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
++		} else {
++			/* Decrement the refcount only. */
++			refcount--;
++			HDR(old_bh)->h_refcount = cpu_to_le32(refcount);
++			ext3_xattr_quota_free(inode);
++			ext3_journal_dirty_metadata(handle, old_bh);
++			ea_bdebug(old_bh, "refcount now=%d", refcount);
++		}
++	}
++
++cleanup:
++	if (old_bh != new_bh)
++		brelse(new_bh);
++
++	return error;
++}
++
++/*
++ * ext3_xattr_delete_inode()
++ *
++ * Free extended attribute resources associated with this inode. This
++ * is called immediately before an inode is freed.
++ */
++void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++	struct buffer_head *bh;
++	unsigned int block = EXT3_I(inode)->i_file_acl;
++
++	if (!block)
++		return;
++	down(&ext3_xattr_sem);
++
++	bh = sb_bread(inode->i_sb, block);
++	if (!bh) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: block %d read error", inode->i_ino, block);
++		goto cleanup;
++	}
++	ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count)));
++	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
++	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
++		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
++			"inode %ld: bad block %d", inode->i_ino, block);
++		goto cleanup;
++	}
++	ext3_journal_get_write_access(handle, bh);
++	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
++	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
++		ext3_xattr_cache_remove(bh);
++		ext3_xattr_free_block(handle, inode, block);
++		ext3_forget(handle, 1, inode, bh, block);
++		bh = NULL;
++	} else {
++		HDR(bh)->h_refcount = cpu_to_le32(
++			le32_to_cpu(HDR(bh)->h_refcount) - 1);
++		ext3_journal_dirty_metadata(handle, bh);
++		if (IS_SYNC(inode))
++			handle->h_sync = 1;
++		ext3_xattr_quota_free(inode);
++	}
++	EXT3_I(inode)->i_file_acl = 0;
++
++cleanup:
++	brelse(bh);
++	up(&ext3_xattr_sem);
++}
++
++/*
++ * ext3_xattr_put_super()
++ *
++ * This is called when a file system is unmounted.
++ */
++void
++ext3_xattr_put_super(struct super_block *sb)
++{
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++	mb_cache_shrink(ext3_xattr_cache, sb->s_dev);
++#endif
++}
++
++#ifdef CONFIG_EXT3_FS_XATTR_SHARING
++
++/*
++ * ext3_xattr_cache_insert()
++ *
++ * Create a new entry in the extended attribute cache, and insert
++ * it unless such an entry is already in the cache.
++ *
++ * Returns 0, or a negative error number on failure.
++ */
++static int
++ext3_xattr_cache_insert(struct buffer_head *bh)
++{
++	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
++	struct mb_cache_entry *ce;
++	int error;
++
++	ce = mb_cache_entry_alloc(ext3_xattr_cache);
++	if (!ce)
++		return -ENOMEM;
++	error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash);
++	if (error) {
++		mb_cache_entry_free(ce);
++		if (error == -EBUSY) {
++			ea_bdebug(bh, "already in cache (%d cache entries)",
++				atomic_read(&ext3_xattr_cache->c_entry_count));
++			error = 0;
++		}
++	} else {
++		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
++			  atomic_read(&ext3_xattr_cache->c_entry_count));
++		mb_cache_entry_release(ce);
++	}
++	return error;
++}
++
++/*
++ * ext3_xattr_cmp()
++ *
++ * Compare two extended attribute blocks for equality.
++ *
++ * Returns 0 if the blocks are equal, 1 if they differ, and
++ * a negative error number on errors.
++ */
++static int
++ext3_xattr_cmp(struct ext3_xattr_header *header1,
++	       struct ext3_xattr_header *header2)
++{
++	struct ext3_xattr_entry *entry1, *entry2;
++
++	entry1 = ENTRY(header1+1);
++	entry2 = ENTRY(header2+1);
++	while (!IS_LAST_ENTRY(entry1)) {
++		if (IS_LAST_ENTRY(entry2))
++			return 1;
++		if (entry1->e_hash != entry2->e_hash ||
++		    entry1->e_name_len != entry2->e_name_len ||
++		    entry1->e_value_size != entry2->e_value_size ||
++		    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
++			return 1;
++		if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
++			return -EIO;
++		if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
++			   (char *)header2 + le16_to_cpu(entry2->e_value_offs),
++			   le32_to_cpu(entry1->e_value_size)))
++			return 1;
++
++		entry1 = EXT3_XATTR_NEXT(entry1);
++		entry2 = EXT3_XATTR_NEXT(entry2);
++	}
++	if (!IS_LAST_ENTRY(entry2))
++		return 1;
++	return 0;
++}
++
++/*
++ * ext3_xattr_cache_find()
++ *
++ * Find an identical extended attribute block.
++ *
++ * Returns a pointer to the block found, or NULL if such a block was
++ * not found or an error occurred.
++ */
++static struct buffer_head *
++ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header)
++{
++	__u32 hash = le32_to_cpu(header->h_hash);
++	struct mb_cache_entry *ce;
++
++	if (!header->h_hash)
++		return NULL;  /* never share */
++	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
++	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash);
++	while (ce) {
++		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
++
++		if (!bh) {
++			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
++				"inode %ld: block %ld read error",
++				inode->i_ino, ce->e_block);
++		} else if (le32_to_cpu(HDR(bh)->h_refcount) >
++			   EXT3_XATTR_REFCOUNT_MAX) {
++			ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block,
++				le32_to_cpu(HDR(bh)->h_refcount),
++				EXT3_XATTR_REFCOUNT_MAX);
++		} else if (!ext3_xattr_cmp(header, HDR(bh))) {
++			ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count)));
++			mb_cache_entry_release(ce);
++			return bh;
++		}
++		brelse(bh);
++		ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash);
++	}
++	return NULL;
++}
++
++/*
++ * ext3_xattr_cache_remove()
++ *
++ * Remove the cache entry of a block from the cache. Called when a
++ * block becomes invalid.
++ */
++static void
++ext3_xattr_cache_remove(struct buffer_head *bh)
++{
++	struct mb_cache_entry *ce;
++
++	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr);
++	if (ce) {
++		ea_bdebug(bh, "removing (%d cache entries remaining)",
++			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
++		mb_cache_entry_free(ce);
++	} else 
++		ea_bdebug(bh, "no cache entry");
++}
++
++#define NAME_HASH_SHIFT 5
++#define VALUE_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_hash_entry()
++ *
++ * Compute the hash of an extended attribute.
++ */
++static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header,
++					 struct ext3_xattr_entry *entry)
++{
++	__u32 hash = 0;
++	char *name = entry->e_name;
++	int n;
++
++	for (n=0; n < entry->e_name_len; n++) {
++		hash = (hash << NAME_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
++		       *name++;
++	}
++
++	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
++		__u32 *value = (__u32 *)((char *)header +
++			le16_to_cpu(entry->e_value_offs));
++		for (n = (le32_to_cpu(entry->e_value_size) +
++		     EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) {
++			hash = (hash << VALUE_HASH_SHIFT) ^
++			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
++			       le32_to_cpu(*value++);
++		}
++	}
++	entry->e_hash = cpu_to_le32(hash);
++}
++
++#undef NAME_HASH_SHIFT
++#undef VALUE_HASH_SHIFT
++
++#define BLOCK_HASH_SHIFT 16
++
++/*
++ * ext3_xattr_rehash()
++ *
++ * Re-compute the extended attribute hash value after an entry has changed.
++ */
++static void ext3_xattr_rehash(struct ext3_xattr_header *header,
++			      struct ext3_xattr_entry *entry)
++{
++	struct ext3_xattr_entry *here;
++	__u32 hash = 0;
++	
++	ext3_xattr_hash_entry(header, entry);
++	here = ENTRY(header+1);
++	while (!IS_LAST_ENTRY(here)) {
++		if (!here->e_hash) {
++			/* Block is not shared if an entry's hash value == 0 */
++			hash = 0;
++			break;
++		}
++		hash = (hash << BLOCK_HASH_SHIFT) ^
++		       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
++		       le32_to_cpu(here->e_hash);
++		here = EXT3_XATTR_NEXT(here);
++	}
++	header->h_hash = cpu_to_le32(hash);
++}
++
++#undef BLOCK_HASH_SHIFT
++
++int __init
++init_ext3_xattr(void)
++{
++	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
++		sizeof(struct mb_cache_entry) +
++		sizeof(struct mb_cache_entry_index), 1, 61);
++	if (!ext3_xattr_cache)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++	if (ext3_xattr_cache)
++		mb_cache_destroy(ext3_xattr_cache);
++	ext3_xattr_cache = NULL;
++}
++
++#else  /* CONFIG_EXT3_FS_XATTR_SHARING */
++
++int __init
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++void
++exit_ext3_xattr(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_SHARING */
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/ext3/xattr_user.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,111 @@
++/*
++ * linux/fs/ext3/xattr_user.c
++ * Handler for extended user attributes.
++ *
++ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/ext3_jbd.h>
++#include <linux/ext3_fs.h>
++#include <linux/ext3_xattr.h>
++
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++# include <linux/ext3_acl.h>
++#endif
++
++#define XATTR_USER_PREFIX "user."
++
++static size_t
++ext3_xattr_user_list(char *list, struct inode *inode,
++		     const char *name, int name_len)
++{
++	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
++
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return 0;
++
++	if (list) {
++		memcpy(list, XATTR_USER_PREFIX, prefix_len);
++		memcpy(list+prefix_len, name, name_len);
++		list[prefix_len + name_len] = '\0';
++	}
++	return prefix_len + name_len + 1;
++}
++
++static int
++ext3_xattr_user_get(struct inode *inode, const char *name,
++		    void *buffer, size_t size)
++{
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_READ);
++#else
++	error = permission(inode, MAY_READ);
++#endif
++	if (error)
++		return error;
++
++	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
++			      buffer, size);
++}
++
++static int
++ext3_xattr_user_set(struct inode *inode, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	handle_t *handle;
++	int error;
++
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	if (!test_opt(inode->i_sb, XATTR_USER))
++		return -ENOTSUP;
++	if ( !S_ISREG(inode->i_mode) &&
++	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
++		return -EPERM;
++#ifdef CONFIG_EXT3_FS_POSIX_ACL
++	error = ext3_permission_locked(inode, MAY_WRITE);
++#else
++	error = permission(inode, MAY_WRITE);
++#endif
++	if (error)
++		return error;
++
++	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
++	if (IS_ERR(handle))
++		return PTR_ERR(handle);
++	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
++			       value, size, flags);
++	ext3_journal_stop(handle, inode);
++
++	return error;
++}
++
++struct ext3_xattr_handler ext3_xattr_user_handler = {
++	prefix:	XATTR_USER_PREFIX,
++	list:	ext3_xattr_user_list,
++	get:	ext3_xattr_user_get,
++	set:	ext3_xattr_user_set,
++};
++
++int __init
++init_ext3_xattr_user(void)
++{
++	return ext3_xattr_register(EXT3_XATTR_INDEX_USER,
++				   &ext3_xattr_user_handler);
++}
++
++void
++exit_ext3_xattr_user(void)
++{
++	ext3_xattr_unregister(EXT3_XATTR_INDEX_USER,
++			      &ext3_xattr_user_handler);
++}
+--- linux-2.4.22-ac1/fs/jfs/jfs_xattr.h~xattr-0.8.54-2.4.22-rh	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/jfs/jfs_xattr.h	2003-09-25 23:57:02.000000000 +0400
+@@ -52,8 +52,10 @@ struct jfs_ea_list {
+ #define	END_EALIST(ealist) \
+ 	((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
+ 
+-extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int);
+-extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int);
++extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
++			  int);
++extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
++			int);
+ extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
+ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
+ extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
+--- linux-2.4.22-ac1/fs/jfs/xattr.c~xattr-0.8.54-2.4.22-rh	2002-11-29 02:53:15.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/jfs/xattr.c	2003-09-25 23:57:02.000000000 +0400
+@@ -641,7 +641,7 @@ static int ea_put(struct inode *inode, s
+ }
+ 
+ static int can_set_xattr(struct inode *inode, const char *name,
+-			 void *value, size_t value_len)
++			 const void *value, size_t value_len)
+ {
+ 	if (IS_RDONLY(inode))
+ 		return -EROFS;
+@@ -660,7 +660,7 @@ static int can_set_xattr(struct inode *i
+ 	return permission(inode, MAY_WRITE);
+ }
+ 
+-int __jfs_setxattr(struct inode *inode, const char *name, void *value,
++int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
+ 		   size_t value_len, int flags)
+ {
+ 	struct jfs_ea_list *ealist;
+@@ -799,7 +799,7 @@ int __jfs_setxattr(struct inode *inode, 
+ 	return rc;
+ }
+ 
+-int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
++int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+ 		 size_t value_len, int flags)
+ {
+ 	if (value == NULL) {	/* empty EA, do not remove */
+--- linux-2.4.22-ac1/fs/Makefile~xattr-0.8.54-2.4.22-rh	2003-09-25 14:50:00.000000000 +0400
++++ linux-2.4.22-ac1-alexey/fs/Makefile	2003-09-25 23:57:02.000000000 +0400
+@@ -82,6 +82,9 @@ obj-y				+= binfmt_script.o
+ 
+ obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+ 
++export-objs += mbcache.o
++obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
++
+ # persistent filesystems
+ obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/fs/mbcache.c	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,648 @@
++/*
++ * linux/fs/mbcache.c
++ * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++/*
++ * Filesystem Meta Information Block Cache (mbcache)
++ *
++ * The mbcache caches blocks of block devices that need to be located
++ * by their device/block number, as well as by other criteria (such
++ * as the block's contents).
++ *
++ * There can only be one cache entry in a cache per device and block number.
++ * Additional indexes need not be unique in this sense. The number of
++ * additional indexes (=other criteria) can be hardwired at compile time
++ * or specified at cache create time.
++ *
++ * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
++ * in the cache. A valid entry is in the main hash tables of the cache,
++ * and may also be in the lru list. An invalid entry is not in any hashes
++ * or lists.
++ *
++ * A valid cache entry is only in the lru list if no handles refer to it.
++ * Invalid cache entries will be freed when the last handle to the cache
++ * entry is released. Entries that cannot be freed immediately are put
++ * back on the lru list.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/cache_def.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/mbcache.h>
++
++
++#ifdef MB_CACHE_DEBUG
++# define mb_debug(f...) do { \
++		printk(KERN_DEBUG f); \
++		printk("\n"); \
++	} while (0)
++#define mb_assert(c) do { if (!(c)) \
++		printk(KERN_ERR "assertion " #c " failed\n"); \
++	} while(0)
++#else
++# define mb_debug(f...) do { } while(0)
++# define mb_assert(c) do { } while(0)
++#endif
++#define mb_error(f...) do { \
++		printk(KERN_ERR f); \
++		printk("\n"); \
++	} while(0)
++		
++MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
++MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++MODULE_LICENSE("GPL");
++#endif
++
++EXPORT_SYMBOL(mb_cache_create);
++EXPORT_SYMBOL(mb_cache_shrink);
++EXPORT_SYMBOL(mb_cache_destroy);
++EXPORT_SYMBOL(mb_cache_entry_alloc);
++EXPORT_SYMBOL(mb_cache_entry_insert);
++EXPORT_SYMBOL(mb_cache_entry_release);
++EXPORT_SYMBOL(mb_cache_entry_takeout);
++EXPORT_SYMBOL(mb_cache_entry_free);
++EXPORT_SYMBOL(mb_cache_entry_dup);
++EXPORT_SYMBOL(mb_cache_entry_get);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++EXPORT_SYMBOL(mb_cache_entry_find_first);
++EXPORT_SYMBOL(mb_cache_entry_find_next);
++#endif
++
++
++/*
++ * Global data: list of all mbcache's, lru list, and a spinlock for
++ * accessing cache data structures on SMP machines. The lru list is
++ * global across all mbcaches.
++ */
++
++static LIST_HEAD(mb_cache_list);
++static LIST_HEAD(mb_cache_lru_list);
++static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED;
++
++static inline int
++mb_cache_indexes(struct mb_cache *cache)
++{
++#ifdef MB_CACHE_INDEXES_COUNT
++	return MB_CACHE_INDEXES_COUNT;
++#else
++	return cache->c_indexes_count;
++#endif
++}
++
++/*
++ * What the mbcache registers as to get shrunk dynamically.
++ */
++
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask);
++
++static struct cache_definition mb_cache_definition = {
++	"mb_cache",
++	mb_cache_memory_pressure
++};
++
++
++static inline int
++__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
++{
++	return !list_empty(&ce->e_block_list);
++}
++
++
++static inline void
++__mb_cache_entry_unhash(struct mb_cache_entry *ce)
++{
++	int n;
++
++	if (__mb_cache_entry_is_hashed(ce)) {
++		list_del_init(&ce->e_block_list);
++		for (n=0; n<mb_cache_indexes(ce->e_cache); n++)
++			list_del(&ce->e_indexes[n].o_list);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask)
++{
++	struct mb_cache *cache = ce->e_cache;
++
++	mb_assert(atomic_read(&ce->e_used) == 0);
++	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
++		/* free failed -- put back on the lru list
++		   for freeing later. */
++		spin_lock(&mb_cache_spinlock);
++		list_add(&ce->e_lru_list, &mb_cache_lru_list);
++		spin_unlock(&mb_cache_spinlock);
++	} else {
++		kmem_cache_free(cache->c_entry_cache, ce);
++		atomic_dec(&cache->c_entry_count);
++	}
++}
++
++
++static inline void
++__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
++{
++	if (atomic_dec_and_test(&ce->e_used)) {
++		if (__mb_cache_entry_is_hashed(ce))
++			list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
++		else {
++			spin_unlock(&mb_cache_spinlock);
++			__mb_cache_entry_forget(ce, GFP_KERNEL);
++			return;
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_memory_pressure()  memory pressure callback
++ *
++ * This function is called by the kernel memory management when memory
++ * gets low.
++ *
++ * @priority: Amount by which to shrink the cache (0 = highes priority)
++ * @gfp_mask: (ignored)
++ */
++static void
++mb_cache_memory_pressure(int priority, unsigned int gfp_mask)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int count = 0;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &mb_cache_list) {
++		struct mb_cache *cache =
++			list_entry(l, struct mb_cache, c_cache_list);
++		mb_debug("cache %s (%d)", cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++		count += atomic_read(&cache->c_entry_count);
++	}
++	mb_debug("trying to free %d of %d entries",
++		  count / (priority ? priority : 1), count);
++	if (priority)
++		count /= priority;
++	while (count-- && !list_empty(&mb_cache_lru_list)) {
++		struct mb_cache_entry *ce =
++			list_entry(mb_cache_lru_list.next,
++				   struct mb_cache_entry, e_lru_list);
++		list_del(&ce->e_lru_list);
++		__mb_cache_entry_unhash(ce);
++		list_add_tail(&ce->e_lru_list, &free_list);
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), gfp_mask);
++	}
++}
++
++
++/*
++ * mb_cache_create()  create a new cache
++ *
++ * All entries in one cache are equal size. Cache entries may be from
++ * multiple devices. If this is the first mbcache created, registers
++ * the cache with kernel memory management. Returns NULL if no more
++ * memory was available.
++ *
++ * @name: name of the cache (informal)
++ * @cache_op: contains the callback called when freeing a cache entry
++ * @entry_size: The size of a cache entry, including
++ *              struct mb_cache_entry
++ * @indexes_count: number of additional indexes in the cache. Must equal
++ *                 MB_CACHE_INDEXES_COUNT if the number of indexes is
++ *                 hardwired.
++ * @bucket_count: number of hash buckets
++ */
++struct mb_cache *
++mb_cache_create(const char *name, struct mb_cache_op *cache_op,
++		size_t entry_size, int indexes_count, int bucket_count)
++{
++	int m=0, n;
++	struct mb_cache *cache = NULL;
++
++	if(entry_size < sizeof(struct mb_cache_entry) +
++	   indexes_count * sizeof(struct mb_cache_entry_index))
++		return NULL;
++
++	MOD_INC_USE_COUNT;
++	cache = kmalloc(sizeof(struct mb_cache) +
++	                indexes_count * sizeof(struct list_head), GFP_KERNEL);
++	if (!cache)
++		goto fail;
++	cache->c_name = name;
++	cache->c_op.free = NULL;
++	if (cache_op)
++		cache->c_op.free = cache_op->free;
++	atomic_set(&cache->c_entry_count, 0);
++	cache->c_bucket_count = bucket_count;
++#ifdef MB_CACHE_INDEXES_COUNT
++	mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT);
++#else
++	cache->c_indexes_count = indexes_count;
++#endif
++	cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
++	                              GFP_KERNEL);
++	if (!cache->c_block_hash)
++		goto fail;
++	for (n=0; n<bucket_count; n++)
++		INIT_LIST_HEAD(&cache->c_block_hash[n]);
++	for (m=0; m<indexes_count; m++) {
++		cache->c_indexes_hash[m] = kmalloc(bucket_count *
++		                                 sizeof(struct list_head),
++		                                 GFP_KERNEL);
++		if (!cache->c_indexes_hash[m])
++			goto fail;
++		for (n=0; n<bucket_count; n++)
++			INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
++	}
++	cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
++		0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
++	if (!cache->c_entry_cache)
++		goto fail;
++
++	spin_lock(&mb_cache_spinlock);
++	list_add(&cache->c_cache_list, &mb_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	return cache;
++
++fail:
++	if (cache) {
++		while (--m >= 0)
++			kfree(cache->c_indexes_hash[m]);
++		if (cache->c_block_hash)
++			kfree(cache->c_block_hash);
++		kfree(cache);
++	}
++	MOD_DEC_USE_COUNT;
++	return NULL;
++}
++
++
++/*
++ * mb_cache_shrink()
++ *
++ * Removes all cache entires of a device from the cache. All cache entries
++ * currently in use cannot be freed, and thus remain in the cache.
++ *
++ * @cache: which cache to shrink
++ * @dev: which device's cache entries to shrink
++ */
++void
++mb_cache_shrink(struct mb_cache *cache, kdev_t dev)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_dev == dev) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++}
++
++
++/*
++ * mb_cache_destroy()
++ *
++ * Shrinks the cache to its minimum possible size (hopefully 0 entries),
++ * and then destroys it. If this was the last mbcache, un-registers the
++ * mbcache from kernel memory management.
++ */
++void
++mb_cache_destroy(struct mb_cache *cache)
++{
++	LIST_HEAD(free_list);
++	struct list_head *l, *ltmp;
++	int n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_lru_list);
++		if (ce->e_cache == cache) {
++			list_del(&ce->e_lru_list);
++			list_add_tail(&ce->e_lru_list, &free_list);
++			__mb_cache_entry_unhash(ce);
++		}
++	}
++	list_del(&cache->c_cache_list);
++	spin_unlock(&mb_cache_spinlock);
++	list_for_each_safe(l, ltmp, &free_list) {
++		__mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
++						   e_lru_list), GFP_KERNEL);
++	}
++
++	if (atomic_read(&cache->c_entry_count) > 0) {
++		mb_error("cache %s: %d orphaned entries",
++			  cache->c_name,
++			  atomic_read(&cache->c_entry_count));
++	}
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
++	/* We don't have kmem_cache_destroy() in 2.2.x */
++	kmem_cache_shrink(cache->c_entry_cache);
++#else
++	kmem_cache_destroy(cache->c_entry_cache);
++#endif
++	for (n=0; n < mb_cache_indexes(cache); n++)
++		kfree(cache->c_indexes_hash[n]);
++	kfree(cache->c_block_hash);
++	kfree(cache);
++
++	MOD_DEC_USE_COUNT;
++}
++
++
++/*
++ * mb_cache_entry_alloc()
++ *
++ * Allocates a new cache entry. The new entry will not be valid initially,
++ * and thus cannot be looked up yet. It should be filled with data, and
++ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
++ * if no more memory was available.
++ */
++struct mb_cache_entry *
++mb_cache_entry_alloc(struct mb_cache *cache)
++{
++	struct mb_cache_entry *ce;
++
++	atomic_inc(&cache->c_entry_count);
++	ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
++	if (ce) {
++		INIT_LIST_HEAD(&ce->e_lru_list);
++		INIT_LIST_HEAD(&ce->e_block_list);
++		ce->e_cache = cache;
++		atomic_set(&ce->e_used, 1);
++	}
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_insert()
++ *
++ * Inserts an entry that was allocated using mb_cache_entry_alloc() into
++ * the cache. After this, the cache entry can be looked up, but is not yet
++ * in the lru list as the caller still holds a handle to it. Returns 0 on
++ * success, or -EBUSY if a cache entry for that device + inode exists
++ * already (this may happen after a failed lookup, if another process has
++ * inserted the same cache entry in the meantime).
++ *
++ * @dev: device the cache entry belongs to
++ * @block: block number
++ * @keys: array of additional keys. There must be indexes_count entries
++ *        in the array (as specified when creating the cache).
++ */
++int
++mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev,
++		      unsigned long block, unsigned int keys[])
++{
++	struct mb_cache *cache = ce->e_cache;
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	int error = -EBUSY, n;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block)
++			goto out;
++	}
++	__mb_cache_entry_unhash(ce);
++	ce->e_dev = dev;
++	ce->e_block = block;
++	list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
++	for (n=0; n<mb_cache_indexes(cache); n++) {
++		ce->e_indexes[n].o_key = keys[n];
++		bucket = keys[n] % cache->c_bucket_count;
++		list_add(&ce->e_indexes[n].o_list,
++		         &cache->c_indexes_hash[n][bucket]);
++	}
++out:
++	spin_unlock(&mb_cache_spinlock);
++	return error;
++}
++
++
++/*
++ * mb_cache_entry_release()
++ *
++ * Release a handle to a cache entry. When the last handle to a cache entry
++ * is released it is either freed (if it is invalid) or otherwise inserted
++ * in to the lru list.
++ */
++void
++mb_cache_entry_release(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_takeout()
++ *
++ * Take a cache entry out of the cache, making it invalid. The entry can later
++ * be re-inserted using mb_cache_entry_insert(), or released using
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_takeout(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	spin_unlock(&mb_cache_spinlock);
++}
++
++
++/*
++ * mb_cache_entry_free()
++ *
++ * This is equivalent to the sequence mb_cache_entry_takeout() --
++ * mb_cache_entry_release().
++ */
++void
++mb_cache_entry_free(struct mb_cache_entry *ce)
++{
++	spin_lock(&mb_cache_spinlock);
++	mb_assert(list_empty(&ce->e_lru_list));
++	__mb_cache_entry_unhash(ce);
++	__mb_cache_entry_release_unlock(ce);
++}
++
++
++/*
++ * mb_cache_entry_dup()
++ *
++ * Duplicate a handle to a cache entry (does not duplicate the cache entry
++ * itself). After the call, both the old and the new handle must be released.
++ */
++struct mb_cache_entry *
++mb_cache_entry_dup(struct mb_cache_entry *ce)
++{
++	atomic_inc(&ce->e_used);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_get()
++ *
++ * Get a cache entry  by device / block number. (There can only be one entry
++ * in the cache per device and block.) Returns NULL if no such cache entry
++ * exists.
++ */
++struct mb_cache_entry *
++mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block)
++{
++	unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	spin_lock(&mb_cache_spinlock);
++	list_for_each(l, &cache->c_block_hash[bucket]) {
++		ce = list_entry(l, struct mb_cache_entry, e_block_list);
++		if (ce->e_dev == dev && ce->e_block == block) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			goto cleanup;
++		}
++	}
++	ce = NULL;
++
++cleanup:
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++
++static struct mb_cache_entry *
++__mb_cache_entry_find(struct list_head *l, struct list_head *head,
++		      int index, kdev_t dev, unsigned int key)
++{
++	while (l != head) {
++		struct mb_cache_entry *ce =
++			list_entry(l, struct mb_cache_entry,
++			           e_indexes[index].o_list);
++		if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) {
++			if (!list_empty(&ce->e_lru_list))
++				list_del_init(&ce->e_lru_list);
++			atomic_inc(&ce->e_used);
++			return ce;
++		}
++		l = l->next;
++	}
++	return NULL;
++}
++
++
++/*
++ * mb_cache_entry_find_first()
++ *
++ * Find the first cache entry on a given device with a certain key in
++ * an additional index. Additonal matches can be found with
++ * mb_cache_entry_find_next(). Returns NULL if no match was found.
++ *
++ * @cache: the cache to search
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_first(struct mb_cache *cache, int index, kdev_t dev,
++			  unsigned int key)
++{
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = cache->c_indexes_hash[index][bucket].next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	spin_unlock(&mb_cache_spinlock);
++	return ce;
++}
++
++
++/*
++ * mb_cache_entry_find_next()
++ *
++ * Find the next cache entry on a given device with a certain key in an
++ * additional index. Returns NULL if no match could be found. The previous
++ * entry is atomatically released, so that mb_cache_entry_find_next() can
++ * be called like this:
++ *
++ * entry = mb_cache_entry_find_first();
++ * while (entry) {
++ * 	...
++ *	entry = mb_cache_entry_find_next(entry, ...);
++ * }
++ *
++ * @prev: The previous match
++ * @index: the number of the additonal index to search (0<=index<indexes_count)
++ * @dev: the device the cache entry should belong to
++ * @key: the key in the index
++ */
++struct mb_cache_entry *
++mb_cache_entry_find_next(struct mb_cache_entry *prev, int index, kdev_t dev,
++			 unsigned int key)
++{
++	struct mb_cache *cache = prev->e_cache;
++	unsigned int bucket = key % cache->c_bucket_count;
++	struct list_head *l;
++	struct mb_cache_entry *ce;
++
++	mb_assert(index < mb_cache_indexes(cache));
++	spin_lock(&mb_cache_spinlock);
++	l = prev->e_indexes[index].o_list.next;
++	ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket],
++	                           index, dev, key);
++	__mb_cache_entry_release_unlock(prev);
++	return ce;
++}
++
++#endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
++
++static int __init init_mbcache(void)
++{
++	register_cache(&mb_cache_definition);
++	return 0;
++}
++
++static void __exit exit_mbcache(void)
++{
++	unregister_cache(&mb_cache_definition);
++}
++
++module_init(init_mbcache)
++module_exit(exit_mbcache)
++
+--- linux-2.4.22-ac1/include/asm-arm/unistd.h~xattr-0.8.54-2.4.22-rh	2003-08-25 15:44:43.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/asm-arm/unistd.h	2003-09-25 23:57:02.000000000 +0400
+@@ -250,7 +250,6 @@
+ #define __NR_security			(__NR_SYSCALL_BASE+223)
+ #define __NR_gettid			(__NR_SYSCALL_BASE+224)
+ #define __NR_readahead			(__NR_SYSCALL_BASE+225)
+-#if 0 /* allocated in 2.5 */
+ #define __NR_setxattr			(__NR_SYSCALL_BASE+226)
+ #define __NR_lsetxattr			(__NR_SYSCALL_BASE+227)
+ #define __NR_fsetxattr			(__NR_SYSCALL_BASE+228)
+@@ -263,7 +262,6 @@
+ #define __NR_removexattr		(__NR_SYSCALL_BASE+235)
+ #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
+ #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
+-#endif
+ #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+ #if 0 /* allocated in 2.5 */
+ #define __NR_sendfile64                 (__NR_SYSCALL_BASE+239)
+--- linux-2.4.22-ac1/include/asm-ppc64/unistd.h~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:38.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/asm-ppc64/unistd.h	2003-09-25 23:57:02.000000000 +0400
+@@ -218,6 +218,7 @@
+ #define __NR_mincore		206
+ #define __NR_gettid		207
+ #define __NR_tkill		208
++#endif
+ #define __NR_setxattr		209
+ #define __NR_lsetxattr		210
+ #define __NR_fsetxattr		211
+@@ -230,6 +231,7 @@
+ #define __NR_removexattr	218
+ #define __NR_lremovexattr	219
+ #define __NR_fremovexattr	220
++#if 0 /* Reserved syscalls */
+ #define __NR_futex		221
+ #define __NR_sched_setaffinity	222     
+ #define __NR_sched_getaffinity	223
+--- linux-2.4.22-ac1/include/asm-s390/unistd.h~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:38.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/asm-s390/unistd.h	2003-09-26 00:14:23.000000000 +0400
+@@ -213,6 +213,19 @@
+ #define __NR_getdents64		220
+ #define __NR_fcntl64		221
+ #define __NR_readahead		222
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
++
+ /*
+  * Numbers 224-235 are reserved for posix acl
+  */
+--- linux-2.4.22-ac1/include/asm-s390x/unistd.h~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:38.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/asm-s390x/unistd.h	2003-09-26 00:15:11.000000000 +0400
+@@ -181,6 +181,19 @@
+ #define __NR_mincore            218
+ #define __NR_madvise            219
+ #define __NR_readahead		222
++#define __NR_setxattr		224
++#define __NR_lsetxattr		225
++#define __NR_fsetxattr		226
++#define __NR_getxattr		227
++#define __NR_lgetxattr		228
++#define __NR_fgetxattr		229
++#define __NR_listxattr		230
++#define __NR_llistxattr		231
++#define __NR_flistxattr		232
++#define __NR_removexattr	233
++#define __NR_lremovexattr	234
++#define __NR_fremovexattr	235
++
+ /*
+  * Numbers 224-235 are reserved for posix acl
+  */
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/cache_def.h	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,15 @@
++/*
++ * linux/cache_def.h
++ * Handling of caches defined in drivers, filesystems, ...
++ *
++ * Copyright (C) 2002 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++ */
++
++struct cache_definition {
++	const char *name;
++	void (*shrink)(int, unsigned int);
++	struct list_head link;
++};
++
++extern void register_cache(struct cache_definition *);
++extern void unregister_cache(struct cache_definition *);
+--- linux-2.4.22-ac1/include/linux/errno.h~xattr-0.8.54-2.4.22-rh	2001-02-10 01:46:13.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/errno.h	2003-09-25 23:57:02.000000000 +0400
+@@ -23,4 +23,8 @@
+ 
+ #endif
+ 
++/* Defined for extended attributes */
++#define ENOATTR ENODATA		/* No such attribute */
++#define ENOTSUP EOPNOTSUPP	/* Operation not supported */
++
+ #endif
+--- linux-2.4.22-ac1/include/linux/ext2_fs.h~xattr-0.8.54-2.4.22-rh	2003-06-13 18:51:38.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext2_fs.h	2003-09-25 23:57:02.000000000 +0400
+@@ -57,8 +57,6 @@
+  */
+ #define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT2_ROOT_INO		 2	/* Root inode */
+-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ 
+@@ -86,7 +84,6 @@
+ #else
+ # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+ #define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -121,28 +118,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext2_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext2_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext2_group_desc
+@@ -314,6 +289,7 @@ struct ext2_inode {
+ #define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+ #define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+ #define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
++#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+ #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+@@ -397,6 +373,7 @@ struct ext2_super_block {
+ 
+ #ifdef __KERNEL__
+ #define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
++#define EXT2_I(inode)	(&((inode)->u.ext2_i))
+ #else
+ /* Assume that user mode programs are passing in an ext2fs superblock, not
+  * a kernel struct super_block.  This will allow us to call the feature-test
+@@ -466,7 +443,7 @@ struct ext2_super_block {
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008
+ #define EXT2_FEATURE_INCOMPAT_ANY		0xffffffff
+ 
+-#define EXT2_FEATURE_COMPAT_SUPP	0
++#define EXT2_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+ #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+@@ -624,8 +601,10 @@ extern struct address_space_operations e
+ 
+ /* namei.c */
+ extern struct inode_operations ext2_dir_inode_operations;
++extern struct inode_operations ext2_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext2_symlink_inode_operations;
+ extern struct inode_operations ext2_fast_symlink_inode_operations;
+ 
+ #endif	/* __KERNEL__ */
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/ext2_xattr.h	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext2_xattr.h
++
++  On-disk format of extended attributes for the ext2 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT2_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT2_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT2_XATTR_INDEX_MAX			10
++#define EXT2_XATTR_INDEX_USER			1
++#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext2_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext2_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT2_XATTR_PAD_BITS		2
++#define EXT2_XATTR_PAD		(1<<EXT2_XATTR_PAD_BITS)
++#define EXT2_XATTR_ROUND		(EXT2_XATTR_PAD-1)
++#define EXT2_XATTR_LEN(name_len) \
++	(((name_len) + EXT2_XATTR_ROUND + \
++	sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
++#define EXT2_XATTR_NEXT(entry) \
++	( (struct ext2_xattr_entry *)( \
++	  (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
++#define EXT2_XATTR_SIZE(size) \
++	(((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT2_FS_XATTR
++
++struct ext2_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext2_xattr_register(int, struct ext2_xattr_handler *);
++extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
++
++extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
++extern int ext2_removexattr(struct dentry *, const char *);
++
++extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext2_xattr_list(struct inode *, char *, size_t);
++extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext2_xattr_delete_inode(struct inode *);
++extern void ext2_xattr_put_super(struct super_block *);
++
++extern int init_ext2_xattr(void) __init;
++extern void exit_ext2_xattr(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR */
++#  define ext2_setxattr		NULL
++#  define ext2_getxattr		NULL
++#  define ext2_listxattr	NULL
++#  define ext2_removexattr	NULL
++
++static inline int
++ext2_xattr_get(struct inode *inode, int name_index,
++	       const char *name, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_list(struct inode *inode, char *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext2_xattr_set(struct inode *inode, int name_index, const char *name,
++	       const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext2_xattr_delete_inode(struct inode *inode)
++{
++}
++
++static inline void
++ext2_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext2_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR */
++
++# ifdef CONFIG_EXT2_FS_XATTR_USER
++
++extern int init_ext2_xattr_user(void) __init;
++extern void exit_ext2_xattr_user(void);
++
++# else  /* CONFIG_EXT2_FS_XATTR_USER */
++
++static inline int
++init_ext2_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext2_xattr_user(void)
++{
++}
++
++# endif  /* CONFIG_EXT2_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+--- linux-2.4.22-ac1/include/linux/ext3_fs.h~xattr-0.8.54-2.4.22-rh	2003-09-25 14:58:30.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h	2003-09-25 23:57:02.000000000 +0400
+@@ -63,8 +63,6 @@
+  */
+ #define	EXT3_BAD_INO		 1	/* Bad blocks inode */
+ #define EXT3_ROOT_INO		 2	/* Root inode */
+-#define EXT3_ACL_IDX_INO	 3	/* ACL inode */
+-#define EXT3_ACL_DATA_INO	 4	/* ACL inode */
+ #define EXT3_BOOT_LOADER_INO	 5	/* Boot loader inode */
+ #define EXT3_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+ #define EXT3_RESIZE_INO		 7	/* Reserved group descriptors inode */
+@@ -94,7 +92,6 @@
+ #else
+ # define EXT3_BLOCK_SIZE(s)		(EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+ #endif
+-#define EXT3_ACLE_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry))
+ #define	EXT3_ADDR_PER_BLOCK(s)		(EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+ #ifdef __KERNEL__
+ # define EXT3_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+@@ -129,28 +126,6 @@
+ #endif
+ 
+ /*
+- * ACL structures
+- */
+-struct ext3_acl_header	/* Header of Access Control Lists */
+-{
+-	__u32	aclh_size;
+-	__u32	aclh_file_count;
+-	__u32	aclh_acle_count;
+-	__u32	aclh_first_acle;
+-};
+-
+-struct ext3_acl_entry	/* Access Control List Entry */
+-{
+-	__u32	acle_size;
+-	__u16	acle_perms;	/* Access permissions */
+-	__u16	acle_type;	/* Type of entry */
+-	__u16	acle_tag;	/* User or group identity */
+-	__u16	acle_pad1;
+-	__u32	acle_next;	/* Pointer on next entry for the */
+-					/* same inode or on next free entry */
+-};
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext3_group_desc
+@@ -346,6 +321,7 @@ struct ext3_inode {
+   #define EXT3_MOUNT_WRITEBACK_DATA	0x0C00	/* No data ordering */
+ #define EXT3_MOUNT_UPDATE_JOURNAL	0x1000	/* Update the journal format */
+ #define EXT3_MOUNT_NO_UID32		0x2000  /* Disable 32-bit UIDs */
++#define EXT3_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
+ 
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
+ #ifndef _LINUX_EXT2_FS_H
+@@ -523,7 +499,7 @@ struct ext3_super_block {
+ #define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+ #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+ 
+-#define EXT3_FEATURE_COMPAT_SUPP	0
++#define EXT3_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
+ #define EXT3_FEATURE_INCOMPAT_SUPP	(EXT3_FEATURE_INCOMPAT_FILETYPE| \
+ 					 EXT3_FEATURE_INCOMPAT_RECOVER)
+ #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+@@ -707,6 +683,7 @@ extern void ext3_check_inodes_bitmap (st
+ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
+ 
+ /* inode.c */
++extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+ extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+ extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+ 
+@@ -776,8 +753,10 @@ extern struct address_space_operations e
+ 
+ /* namei.c */
+ extern struct inode_operations ext3_dir_inode_operations;
++extern struct inode_operations ext3_special_inode_operations;
+ 
+ /* symlink.c */
++extern struct inode_operations ext3_symlink_inode_operations;
+ extern struct inode_operations ext3_fast_symlink_inode_operations;
+ 
+ 
+--- linux-2.4.22-ac1/include/linux/ext3_jbd.h~xattr-0.8.54-2.4.22-rh	2003-09-25 14:55:12.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_jbd.h	2003-09-25 23:57:02.000000000 +0400
+@@ -30,13 +30,19 @@
+ 
+ #define EXT3_SINGLEDATA_TRANS_BLOCKS	8U
+ 
++/* Extended attributes may touch two data buffers, two bitmap buffers,
++ * and two group and summaries. */
++
++#define EXT3_XATTR_TRANS_BLOCKS		8
++
+ /* Define the minimum size for a transaction which modifies data.  This
+  * needs to take into account the fact that we may end up modifying two
+  * quota files too (one for the group, one for the user quota).  The
+  * superblock only gets updated once, of course, so don't bother
+  * counting that again for the quota updates. */
+ 
+-#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2)
++#define EXT3_DATA_TRANS_BLOCKS		(3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \
++					 EXT3_XATTR_TRANS_BLOCKS - 2)
+ 
+ extern int ext3_writepage_trans_blocks(struct inode *inode);
+ 
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/ext3_xattr.h	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,157 @@
++/*
++  File: linux/ext3_xattr.h
++
++  On-disk format of extended attributes for the ext3 filesystem.
++
++  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/xattr.h>
++
++/* Magic value in attribute blocks */
++#define EXT3_XATTR_MAGIC		0xEA020000
++
++/* Maximum number of references to one attribute block */
++#define EXT3_XATTR_REFCOUNT_MAX		1024
++
++/* Name indexes */
++#define EXT3_XATTR_INDEX_MAX			10
++#define EXT3_XATTR_INDEX_USER			1
++#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
++#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
++
++struct ext3_xattr_header {
++	__u32	h_magic;	/* magic number for identification */
++	__u32	h_refcount;	/* reference count */
++	__u32	h_blocks;	/* number of disk blocks used */
++	__u32	h_hash;		/* hash value of all attributes */
++	__u32	h_reserved[4];	/* zero right now */
++};
++
++struct ext3_xattr_entry {
++	__u8	e_name_len;	/* length of name */
++	__u8	e_name_index;	/* attribute name index */
++	__u16	e_value_offs;	/* offset in disk block of value */
++	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
++	__u32	e_value_size;	/* size of attribute value */
++	__u32	e_hash;		/* hash value of name and value */
++	char	e_name[0];	/* attribute name */
++};
++
++#define EXT3_XATTR_PAD_BITS		2
++#define EXT3_XATTR_PAD		(1<<EXT3_XATTR_PAD_BITS)
++#define EXT3_XATTR_ROUND		(EXT3_XATTR_PAD-1)
++#define EXT3_XATTR_LEN(name_len) \
++	(((name_len) + EXT3_XATTR_ROUND + \
++	sizeof(struct ext3_xattr_entry)) & ~EXT3_XATTR_ROUND)
++#define EXT3_XATTR_NEXT(entry) \
++	( (struct ext3_xattr_entry *)( \
++	  (char *)(entry) + EXT3_XATTR_LEN((entry)->e_name_len)) )
++#define EXT3_XATTR_SIZE(size) \
++	(((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND)
++
++#ifdef __KERNEL__
++
++# ifdef CONFIG_EXT3_FS_XATTR
++
++struct ext3_xattr_handler {
++	char *prefix;
++	size_t (*list)(char *list, struct inode *inode, const char *name,
++		       int name_len);
++	int (*get)(struct inode *inode, const char *name, void *buffer,
++		   size_t size);
++	int (*set)(struct inode *inode, const char *name, const void *buffer,
++		   size_t size, int flags);
++};
++
++extern int ext3_xattr_register(int, struct ext3_xattr_handler *);
++extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
++
++extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
++extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
++extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
++extern int ext3_removexattr(struct dentry *, const char *);
++
++extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
++extern int ext3_xattr_list(struct inode *, char *, size_t);
++extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
++
++extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
++extern void ext3_xattr_put_super(struct super_block *);
++
++extern int init_ext3_xattr(void) __init;
++extern void exit_ext3_xattr(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR */
++#  define ext3_setxattr		NULL
++#  define ext3_getxattr		NULL
++#  define ext3_listxattr	NULL
++#  define ext3_removexattr	NULL
++
++static inline int
++ext3_xattr_get(struct inode *inode, int name_index, const char *name,
++	       void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
++{
++	return -ENOTSUP;
++}
++
++static inline int
++ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
++	       const char *name, const void *value, size_t size, int flags)
++{
++	return -ENOTSUP;
++}
++
++static inline void
++ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
++{
++}
++
++static inline void
++ext3_xattr_put_super(struct super_block *sb)
++{
++}
++
++static inline int
++init_ext3_xattr(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr(void)
++{
++}
++
++# endif  /* CONFIG_EXT3_FS_XATTR */
++
++# ifdef CONFIG_EXT3_FS_XATTR_USER
++
++extern int init_ext3_xattr_user(void) __init;
++extern void exit_ext3_xattr_user(void);
++
++# else  /* CONFIG_EXT3_FS_XATTR_USER */
++
++static inline int
++init_ext3_xattr_user(void)
++{
++	return 0;
++}
++
++static inline void
++exit_ext3_xattr_user(void)
++{
++}
++
++#endif  /* CONFIG_EXT3_FS_XATTR_USER */
++
++#endif  /* __KERNEL__ */
++
+--- linux-2.4.22-ac1/include/linux/fs.h~xattr-0.8.54-2.4.22-rh	2003-09-25 14:45:32.000000000 +0400
++++ linux-2.4.22-ac1-alexey/include/linux/fs.h	2003-09-25 23:57:02.000000000 +0400
+@@ -918,7 +918,7 @@ struct inode_operations {
+ 	int (*setattr) (struct dentry *, struct iattr *);
+ 	int (*setattr_raw) (struct inode *, struct iattr *);
+ 	int (*getattr) (struct dentry *, struct iattr *);
+-	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
++	int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
+ 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+ 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+ 	int (*removexattr) (struct dentry *, const char *);
+--- /dev/null	2003-01-30 13:24:37.000000000 +0300
++++ linux-2.4.22-ac1-alexey/include/linux/mbcache.h	2003-09-25 23:57:02.000000000 +0400
+@@ -0,0 +1,69 @@
++/*
++  File: linux/mbcache.h
++
++  (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
++*/
++
++/* Hardwire the number of additional indexes */
++#define MB_CACHE_INDEXES_COUNT 1
++
++struct mb_cache_entry;
++
++struct mb_cache_op {
++	int (*free)(struct mb_cache_entry *, int);
++};
++
++struct mb_cache {
++	struct list_head		c_cache_list;
++	const char			*c_name;
++	struct mb_cache_op		c_op;
++	atomic_t			c_entry_count;
++	int				c_bucket_count;
++#ifndef MB_CACHE_INDEXES_COUNT
++	int				c_indexes_count;
++#endif
++	kmem_cache_t			*c_entry_cache;
++	struct list_head		*c_block_hash;
++	struct list_head		*c_indexes_hash[0];
++};
++
++struct mb_cache_entry_index {
++	struct list_head		o_list;
++	unsigned int			o_key;
++};
++
++struct mb_cache_entry {
++	struct list_head		e_lru_list;
++	struct mb_cache			*e_cache;
++	atomic_t			e_used;
++	kdev_t				e_dev;
++	unsigned long			e_block;
++	struct list_head		e_block_list;
++	struct mb_cache_entry_index	e_indexes[0];
++};
++
++/* Functions on caches */
++
++struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
++				  int, int);
++void mb_cache_shrink(struct mb_cache *, kdev_t);
++void mb_cache_destroy(struct mb_cache *);
++
++/* Functions on cache entries */
++
++struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
++int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long,
++			  unsigned int[]);
++void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
++void mb_cache_entry_release(struct mb_cache_entry *);
++void mb_cache_entry_takeout(struct mb_cache_entry *);
++void mb_cache_entry_free(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *);
++struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t,
++					  unsigned long);
++#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
++struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int,
++						 kdev_t, unsigned int);
++struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int,
++						kdev_t, unsigned int);
++#endif
+--- linux-2.4.22-ac1/kernel/ksyms.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:42:46.000000000 +0400
++++ linux-2.4.22-ac1-alexey/kernel/ksyms.c	2003-09-26 00:19:05.000000000 +0400
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/config.h>
+ #include <linux/slab.h>
++#include <linux/cache_def.h>
+ #include <linux/smp.h>
+ #include <linux/module.h>
+ #include <linux/blkdev.h>
+@@ -106,6 +107,7 @@ EXPORT_SYMBOL(exit_files);
+ EXPORT_SYMBOL(exit_fs);
+ EXPORT_SYMBOL(exit_sighand);
+ EXPORT_SYMBOL(unshare_files);
++EXPORT_SYMBOL(copy_fs_struct);
+ 
+ /* internal kernel memory management */
+ EXPORT_SYMBOL(_alloc_pages);
+@@ -124,6 +126,8 @@ EXPORT_SYMBOL(kmem_cache_validate);
+ EXPORT_SYMBOL(kmem_cache_alloc);
+ EXPORT_SYMBOL(kmem_cache_free);
+ EXPORT_SYMBOL(kmem_cache_size);
++EXPORT_SYMBOL(register_cache);
++EXPORT_SYMBOL(unregister_cache);
+ EXPORT_SYMBOL(kmalloc);
+ EXPORT_SYMBOL(kfree);
+ EXPORT_SYMBOL(vfree);
+--- linux-2.4.22-ac1/mm/vmscan.c~xattr-0.8.54-2.4.22-rh	2003-09-25 14:16:28.000000000 +0400
++++ linux-2.4.22-ac1-alexey/mm/vmscan.c	2003-09-25 23:57:02.000000000 +0400
+@@ -18,6 +18,7 @@
+ #include <linux/kernel_stat.h>
+ #include <linux/swap.h>
+ #include <linux/swapctl.h>
++#include <linux/cache_def.h>
+ #include <linux/smp_lock.h>
+ #include <linux/pagemap.h>
+ #include <linux/init.h>
+@@ -34,6 +35,39 @@
+  */
+ #define DEF_PRIORITY (6)
+ 
++static DECLARE_MUTEX(other_caches_sem);
++static LIST_HEAD(cache_definitions);
++
++void register_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_add(&cache->link, &cache_definitions);
++	up(&other_caches_sem);
++}
++
++void unregister_cache(struct cache_definition *cache)
++{
++	down(&other_caches_sem);
++	list_del(&cache->link);
++	up(&other_caches_sem);
++}
++
++static void shrink_other_caches(unsigned int priority, int gfp_mask)
++{
++	struct list_head *p;
++
++	if (down_trylock(&other_caches_sem))
++		return;
++
++	list_for_each_prev(p, &cache_definitions) {
++		struct cache_definition *cache =
++			list_entry(p, struct cache_definition, link);
++
++		cache->shrink(priority, gfp_mask);
++	}
++	up(&other_caches_sem);
++}
++
+ /*
+  * The swap-out function returns 1 if it successfully
+  * scanned all the pages it was asked to (`count').
+@@ -577,6 +611,7 @@ static int shrink_caches(zone_t * classz
+ 
+ 	shrink_dcache_memory(priority, gfp_mask);
+ 	shrink_icache_memory(priority, gfp_mask);
++	shrink_other_caches(priority, gfp_mask);
+ #ifdef CONFIG_QUOTA
+ 	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+ #endif
+
+_
diff --git a/lustre/kernel_patches/pc/2.6.0-test1-mm2.pc b/lustre/kernel_patches/pc/2.6.0-test1-mm2.pc
deleted file mode 100644
index 33e717923cecbb2d13cbad5be2762baf91b282d1..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/2.6.0-test1-mm2.pc
+++ /dev/null
@@ -1,1202 +0,0 @@
-arch/alpha/kernel/irq.c
-arch/alpha/kernel/smp.c
-arch/alpha/mm/init.c
-arch/alpha/mm/remap.c
-arch/arm26/kernel/setup.c
-arch/arm26/mm/init.c
-arch/arm26/mm/mm-memc.c
-arch/arm/mach-arc/mm.c
-arch/arm/mach-clps711x/autcpu12.c
-arch/arm/mm/consistent.c
-arch/arm/mm/ioremap.c
-arch/arm/mm/minicache.c
-arch/arm/mm/mm-armv.c
-arch/cris/mm/ioremap.c
-arch/h8300/kernel/setup.c
-arch/h8300/mm/init.c
-arch/i386/Kconfig
-arch/i386/kernel/apic.c
-arch/i386/kernel/apm.c
-arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
-arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
-arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
-arch/i386/kernel/cpuid.c
-arch/i386/kernel/cpu/mtrr/cyrix.c
-arch/i386/kernel/cpu/mtrr/main.c
-arch/i386/kernel/cpu/proc.c
-arch/i386/kernel/entry.S
-arch/i386/kernel/io_apic.c
-arch/i386/kernel/irq.c
-arch/i386/kernel/kgdb_stub.c
-arch/i386/kernel/ldt.c
-arch/i386/kernel/Makefile
-arch/i386/kernel/mpparse.c
-arch/i386/kernel/msr.c
-arch/i386/kernel/nmi.c
-arch/i386/kernel/reboot.c
-arch/i386/kernel/setup.c
-arch/i386/kernel/smpboot.c
-arch/i386/kernel/smp.c
-arch/i386/kernel/traps.c
-arch/i386/kernel/vm86.c
-arch/i386/lib/dec_and_lock.c
-arch/i386/lib/kgdb_serial.c
-arch/i386/lib/Makefile
-arch/i386/mach-generic/bigsmp.c
-arch/i386/mach-generic/default.c
-arch/i386/mach-generic/probe.c
-arch/i386/mach-generic/summit.c
-arch/i386/mach-visws/mpparse.c
-arch/i386/mach-voyager/voyager_smp.c
-arch/i386/Makefile
-arch/i386/mm/fault.c
-arch/i386/mm/hugetlbpage.c
-arch/i386/mm/init.c
-arch/i386/mm/ioremap.c
-arch/i386/mm/pageattr.c
-arch/i386/mm/pgtable.c
-arch/i386/pci/legacy.c
-arch/i386/pci/visws.c
-arch/ia64/hp/sim/simscsi.c
-arch/ia64/ia32/ia32_ioctl.c
-arch/ia64/kernel/acpi.c
-arch/ia64/kernel/entry.S
-arch/ia64/kernel/fsys.S
-arch/ia64/kernel/ia64_ksyms.c
-arch/ia64/kernel/init_task.c
-arch/ia64/kernel/iosapic.c
-arch/ia64/kernel/irq.c
-arch/ia64/kernel/module.c
-arch/ia64/kernel/perfmon.c
-arch/ia64/kernel/ptrace.c
-arch/ia64/kernel/setup.c
-arch/ia64/kernel/smpboot.c
-arch/ia64/kernel/smp.c
-arch/ia64/kernel/time.c
-arch/ia64/Makefile
-arch/ia64/mm/hugetlbpage.c
-arch/ia64/mm/init.c
-arch/ia64/pci/pci.c
-arch/ia64/scripts/check-model.c
-arch/ia64/scripts/toolchain-flags
-arch/m68k/apollo/dn_ints.c
-arch/m68k/atari/stram.c
-arch/m68k/kernel/head.S
-arch/m68k/mm/init.c
-arch/m68k/mm/kmap.c
-arch/m68k/mm/motorola.c
-arch/m68k/mm/sun3mmu.c
-arch/m68knommu/kernel/setup.c
-arch/m68knommu/mm/init.c
-arch/m68k/q40/q40ints.c
-arch/m68k/sun3x/dvma.c
-arch/mips64/kernel/irq.c
-arch/mips64/kernel/proc.c
-arch/mips64/kernel/setup.c
-arch/mips64/kernel/smp.c
-arch/mips/kernel/irq.c
-arch/mips/kernel/proc.c
-arch/mips/kernel/smp.c
-arch/mips/mm/fault.c
-arch/mips/mm/init.c
-arch/mips/mm/ioremap.c
-arch/mips/momentum/ocelot_c/setup.c
-arch/mips/momentum/ocelot_g/setup.c
-arch/mips/ramdisk/Makefile
-arch/mips/sgi-ip27/ip27-init.c
-arch/mips/sibyte/cfe/setup.c
-arch/mips/sibyte/cfe/smp.c
-arch/mips/sibyte/sb1250/prom.c
-arch/mips/sibyte/sb1250/smp.c
-arch/mips/sibyte/swarm/setup.c
-arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
-arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
-arch/mips/vr41xx/tanbac-tb0229/setup.c
-arch/parisc/kernel/ioctl32.c
-arch/parisc/kernel/pci-dma.c
-arch/parisc/kernel/smp.c
-arch/parisc/mm/ioremap.c
-arch/ppc64/boot/Makefile
-arch/ppc64/Kconfig
-arch/ppc64/kernel/htab.c
-arch/ppc64/kernel/irq.c
-arch/ppc64/kernel/iSeries_irq.c
-arch/ppc64/kernel/open_pic.c
-arch/ppc64/kernel/open_pic.h
-arch/ppc64/kernel/pacaData.c
-arch/ppc64/kernel/prom.c
-arch/ppc64/kernel/rtasd.c
-arch/ppc64/kernel/semaphore.c
-arch/ppc64/kernel/setup.c
-arch/ppc64/kernel/smp.c
-arch/ppc64/kernel/xics.c
-arch/ppc64/kernel/XmPciLpEvent.c
-arch/ppc64/mm/init.c
-arch/ppc/kernel/irq.c
-arch/ppc/kernel/misc.S
-arch/ppc/kernel/setup.c
-arch/ppc/kernel/smp.c
-arch/ppc/kernel/syscalls.c
-arch/ppc/kernel/time.c
-arch/ppc/mm/mem_pieces.c
-arch/ppc/platforms/4xx/beech.c
-arch/ppc/platforms/4xx/sycamore.c
-arch/ppc/platforms/4xx/walnut.c
-arch/ppc/platforms/pmac_cpufreq.c
-arch/ppc/platforms/residual.c
-arch/s390/defconfig
-arch/s390/kernel/compat_ioctl.c
-arch/s390/kernel/compat_linux.c
-arch/s390/kernel/entry64.S
-arch/s390/kernel/entry.S
-arch/s390/kernel/s390_ext.c
-arch/s390/kernel/setup.c
-arch/s390/kernel/smp.c
-arch/s390/mm/init.c
-arch/s390/mm/ioremap.c
-arch/sh/mm/init.c
-arch/sh/mm/ioremap.c
-arch/sparc64/kernel/devices.c
-arch/sparc64/kernel/head.S
-arch/sparc64/kernel/irq.c
-arch/sparc64/kernel/pci.c
-arch/sparc64/kernel/setup.c
-arch/sparc64/kernel/smp.c
-arch/sparc64/kernel/sparc64_ksyms.c
-arch/sparc64/kernel/time.c
-arch/sparc64/kernel/us2e_cpufreq.c
-arch/sparc64/kernel/us3_cpufreq.c
-arch/sparc64/lib/atomic.S
-arch/sparc64/lib/rwlock.S
-arch/sparc64/mm/fault.c
-arch/sparc64/mm/generic.c
-arch/sparc64/mm/hugetlbpage.c
-arch/sparc64/mm/init.c
-arch/sparc64/prom/bootstr.c
-arch/sparc/kernel/process.c
-arch/sparc/kernel/setup.c
-arch/sparc/mm/generic.c
-arch/sparc/mm/srmmu.c
-arch/sparc/mm/sun4c.c
-arch/um/drivers/ubd_kern.c
-arch/um/kernel/irq.c
-arch/um/kernel/skas/process_kern.c
-arch/um/kernel/smp.c
-arch/um/kernel/tt/process_kern.c
-arch/um/kernel/um_arch.c
-arch/v850/Kconfig
-arch/v850/kernel/anna.c
-arch/v850/kernel/as85ep1.c
-arch/v850/kernel/fpga85e2c.c
-arch/v850/kernel/gbus_int.c
-arch/v850/kernel/head.S
-arch/v850/kernel/highres_timer.c
-arch/v850/kernel/intv.S
-arch/v850/kernel/ma.c
-arch/v850/kernel/Makefile
-arch/v850/kernel/me2.c
-arch/v850/kernel/nb85e_cache.c
-arch/v850/kernel/nb85e_intc.c
-arch/v850/kernel/nb85e_timer_d.c
-arch/v850/kernel/nb85e_utils.c
-arch/v850/kernel/rte_cb.c
-arch/v850/kernel/rte_ma1_cb.c
-arch/v850/kernel/rte_me2_cb.c
-arch/v850/kernel/rte_nb85e_cb.c
-arch/v850/kernel/sim85e2.c
-arch/v850/kernel/sim85e2c.c
-arch/v850/kernel/teg.c
-arch/v850/kernel/v850e2_cache.c
-arch/v850/kernel/v850e_cache.c
-arch/v850/kernel/v850e_intc.c
-arch/v850/kernel/v850e_timer_d.c
-arch/v850/kernel/v850e_utils.c
-arch/v850/rte_me2_cb.ld
-arch/v850/sim85e2c.ld
-arch/v850/sim85e2.ld
-arch/v850/vmlinux.lds.S
-arch/x86_64/boot/compressed/head.S
-arch/x86_64/boot/compressed/misc.c
-arch/x86_64/ia32/syscall32.c
-arch/x86_64/kernel/apic.c
-arch/x86_64/kernel/io_apic.c
-arch/x86_64/kernel/irq.c
-arch/x86_64/kernel/ldt.c
-arch/x86_64/kernel/mpparse.c
-arch/x86_64/kernel/msr.c
-arch/x86_64/kernel/reboot.c
-arch/x86_64/kernel/setup.c
-arch/x86_64/kernel/smpboot.c
-arch/x86_64/kernel/smp.c
-arch/x86_64/mm/init.c
-arch/x86_64/mm/ioremap.c
-arch/x86_64/mm/numa.c
-Documentation/fb/neofb.txt
-Documentation/filesystems/proc.txt
-Documentation/i386/kgdb/andthen
-Documentation/i386/kgdb/debug-nmi.txt
-Documentation/i386/kgdb/gdb-globals.txt
-Documentation/i386/kgdb/gdbinit
-Documentation/i386/kgdb/gdbinit.hw
-Documentation/i386/kgdb/gdbinit-modules
-Documentation/i386/kgdb/kgdb.txt
-Documentation/i386/kgdb/loadmodule.sh
-Documentation/magic-number.txt
-Documentation/networking/vortex.txt
-Documentation/pnp.txt
-drivers/acorn/block/fd1772.c
-drivers/acorn/block/mfmhd.c
-drivers/acpi/executer/exutils.c
-drivers/acpi/hardware/hwregs.c
-drivers/acpi/osl.c
-drivers/acpi/processor.c
-drivers/acpi/tables.c
-drivers/acpi/tables/tbconvrt.c
-drivers/acpi/tables/tbget.c
-drivers/acpi/tables/tbinstal.c
-drivers/acpi/tables/tbrsdt.c
-drivers/acpi/tables/tbxfroot.c
-drivers/acpi/thermal.c
-drivers/acpi/utilities/utglobal.c
-drivers/atm/atmtcp.c
-drivers/base/node.c
-drivers/block/acsi.c
-drivers/block/amiflop.c
-drivers/block/as-iosched.c
-drivers/block/ataflop.c
-drivers/block/cciss.c
-drivers/block/cciss_scsi.c
-drivers/block/cpqarray.c
-drivers/block/cryptoloop.c
-drivers/block/DAC960.c
-drivers/block/deadline-iosched.c
-drivers/block/elevator.c
-drivers/block/floppy98.c
-drivers/block/floppy.c
-drivers/block/genhd.c
-drivers/block/ioctl.c
-drivers/block/Kconfig
-drivers/block/ll_rw_blk.c
-drivers/block/nbd.c
-drivers/block/paride/pcd.c
-drivers/block/paride/pd.c
-drivers/block/paride/pf.c
-drivers/block/ps2esdi.c
-drivers/block/swim3.c
-drivers/block/swim_iop.c
-drivers/block/umem.c
-drivers/block/xd.c
-drivers/block/z2ram.c
-drivers/cdrom/aztcd.c
-drivers/cdrom/cdrom.c
-drivers/cdrom/cdu31a.c
-drivers/cdrom/cm206.c
-drivers/cdrom/gscd.c
-drivers/cdrom/mcd.c
-drivers/cdrom/mcdx.c
-drivers/cdrom/optcd.c
-drivers/cdrom/sbpcd.c
-drivers/cdrom/sjcd.c
-drivers/cdrom/sonycd535.c
-drivers/char/agp/i460-agp.c
-drivers/char/busmouse.c
-drivers/char/drm/drm_memory.h
-drivers/char/ftape/lowlevel/fdc-io.c
-drivers/char/ftape/lowlevel/ftape-calibr.c
-drivers/char/ftape/lowlevel/ftape-format.c
-drivers/char/ftape/zftape/zftape-init.c
-drivers/char/ip2.c
-drivers/char/ip2/i2lib.c
-drivers/char/ip2/i2os.h
-drivers/char/ip2main.c
-drivers/char/istallion.c
-drivers/char/keyboard.c
-drivers/char/moxa.c
-drivers/char/nwbutton.h
-drivers/char/pcxx.c
-drivers/char/stallion.c
-drivers/char/sysrq.c
-drivers/char/tty_io.c
-drivers/char/watchdog/acquirewdt.c
-drivers/char/watchdog/i810-tco.c
-drivers/char/watchdog/i810-tco.h
-drivers/char/watchdog/ib700wdt.c
-drivers/char/watchdog/indydog.c
-drivers/char/watchdog/machzwd.c
-drivers/char/watchdog/pcwd.c
-drivers/char/watchdog/sbc60xxwdt.c
-drivers/char/watchdog/sc520_wdt.c
-drivers/char/watchdog/shwdt.c
-drivers/char/watchdog/softdog.c
-drivers/char/watchdog/wdt977.c
-drivers/char/watchdog/wdt_pci.c
-drivers/fc4/fc.c
-drivers/fc4/fcp_impl.h
-drivers/i2c/i2c-dev.c
-drivers/ide/ide-disk.c
-drivers/ide/ide-dma.c
-drivers/ide/ide-io.c
-drivers/ide/Kconfig
-drivers/ide/legacy/hd98.c
-drivers/ide/legacy/hd.c
-drivers/ide/ppc/mpc8xx.c
-drivers/ieee1394/amdtp.c
-drivers/ieee1394/sbp2.c
-drivers/input/keyboard/sunkbd.c
-drivers/input/mouse/psmouse-base.c
-drivers/md/dm.c
-drivers/md/dm.h
-drivers/md/dm-ioctl.c
-drivers/md/dm-ioctl-v1.c
-drivers/md/dm-ioctl-v4.c
-drivers/md/dm-table.c
-drivers/md/Kconfig
-drivers/md/linear.c
-drivers/md/md.c
-drivers/md/multipath.c
-drivers/md/raid0.c
-drivers/md/raid1.c
-drivers/media/common/Makefile
-drivers/media/common/saa7146_core.c
-drivers/media/common/saa7146_fops.c
-drivers/media/common/saa7146_hlp.c
-drivers/media/common/saa7146_i2c.c
-drivers/media/common/saa7146_vbi.c
-drivers/media/common/saa7146_video.c
-drivers/media/common/saa7146_vv_ksyms.c
-drivers/media/dvb/b2c2/Kconfig
-drivers/media/dvb/b2c2/Makefile
-drivers/media/dvb/b2c2/skystar2.c
-drivers/media/dvb/dvb-core/dvb_demux.c
-drivers/media/dvb/dvb-core/dvbdev.c
-drivers/media/dvb/dvb-core/dvbdev.h
-drivers/media/dvb/dvb-core/dvb_frontend.c
-drivers/media/dvb/dvb-core/dvb_functions.c
-drivers/media/dvb/dvb-core/dvb_functions.h
-drivers/media/dvb/dvb-core/dvb_net.c
-drivers/media/dvb/dvb-core/dvb_net.h
-drivers/media/dvb/frontends/alps_bsrv2.c
-drivers/media/dvb/frontends/alps_tdlb7.c
-drivers/media/dvb/frontends/grundig_29504-401.c
-drivers/media/dvb/frontends/grundig_29504-491.c
-drivers/media/dvb/frontends/Kconfig
-drivers/media/dvb/frontends/Makefile
-drivers/media/dvb/frontends/mt312.c
-drivers/media/dvb/frontends/mt312.h
-drivers/media/dvb/frontends/nxt6000.c
-drivers/media/dvb/frontends/tda1004x.c
-drivers/media/dvb/frontends/ves1820.c
-drivers/media/dvb/Kconfig
-drivers/media/dvb/Makefile
-drivers/media/dvb/ttpci/av7110.c
-drivers/media/dvb/ttpci/av7110.h
-drivers/media/dvb/ttpci/budget-av.c
-drivers/media/dvb/ttpci/budget.c
-drivers/media/dvb/ttpci/budget-ci.c
-drivers/media/dvb/ttpci/budget-core.c
-drivers/media/dvb/ttpci/budget-patch.c
-drivers/media/dvb/ttpci/Makefile
-drivers/media/dvb/ttpci/ttpci-eeprom.c
-drivers/media/dvb/ttpci/ttpci-eeprom.h
-drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
-drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
-drivers/media/dvb/ttusb-budget/Kconfig
-drivers/media/dvb/ttusb-budget/Makefile
-drivers/media/dvb/ttusb-dec/dec2000_frontend.c
-drivers/media/dvb/ttusb-dec/fdump.c
-drivers/media/dvb/ttusb-dec/Kconfig
-drivers/media/dvb/ttusb-dec/Makefile
-drivers/media/dvb/ttusb-dec/ttusb_dec.c
-drivers/media/dvb/ttusb-dec/ttusb_dec.h
-drivers/media/video/dpc7146.c
-drivers/media/video/hexium_gemini.c
-drivers/media/video/hexium_gemini.h
-drivers/media/video/hexium.h
-drivers/media/video/hexium_orion.c
-drivers/media/video/hexium_orion.h
-drivers/media/video/Kconfig
-drivers/media/video/Makefile
-drivers/media/video/mxb.c
-drivers/media/video/pms.c
-drivers/message/fusion/mptctl.c
-drivers/message/fusion/mptscsih.c
-drivers/message/i2o/i2o_block.c
-drivers/message/i2o/i2o_scsi.c
-drivers/mtd/devices/blkmtd.c
-drivers/mtd/mtd_blkdevs.c
-drivers/net/3c59x.c
-drivers/net/eql.c
-drivers/net/fc/iph5526.c
-drivers/net/irda/vlsi_ir.c
-drivers/net/Kconfig
-drivers/net/ni65.c
-drivers/net/ni65.h
-drivers/net/pcmcia/Kconfig
-drivers/net/seeq8005.c
-drivers/net/wan/comx-hw-comx.c
-drivers/net/wan/sdladrv.c
-drivers/net/wan/sdlamain.c
-drivers/net/wan/syncppp.c
-drivers/net/wireless/airo.c
-drivers/net/wireless/ray_cs.c
-drivers/parisc/led.c
-drivers/parport/parport_pc.c
-drivers/pci/hotplug/acpiphp_glue.c
-drivers/pci/hotplug/acpiphp_pci.c
-drivers/pci/hotplug.c
-drivers/pci/hotplug/cpci_hotplug_core.c
-drivers/pci/hotplug/cpci_hotplug.h
-drivers/pci/hotplug/cpci_hotplug_pci.c
-drivers/pci/hotplug/Kconfig
-drivers/pci/Makefile
-drivers/pci/pci.c
-drivers/pci/pool.c
-drivers/pci/probe.c
-drivers/pci/quirks.c
-drivers/pci/remove.c
-drivers/pci/setup-bus.c
-drivers/pci/setup-res.c
-drivers/pcmcia/hd64465_ss.c
-drivers/pcmcia/ricoh.h
-drivers/pcmcia/ti113x.h
-drivers/pcmcia/yenta_socket.c
-drivers/pnp/isapnp/core.c
-drivers/s390/block/dasd.c
-drivers/s390/block/dasd_genhd.c
-drivers/s390/block/dasd_int.h
-drivers/s390/block/dasd_ioctl.c
-drivers/s390/block/xpram.c
-drivers/s390/char/sclp.c
-drivers/s390/char/tape_block.c
-drivers/s390/cio/chsc.c
-drivers/s390/cio/cio.c
-drivers/s390/cio/device.c
-drivers/s390/cio/device_fsm.c
-drivers/s390/cio/device.h
-drivers/s390/cio/qdio.c
-drivers/s390/net/qeth.c
-drivers/s390/net/qeth.h
-drivers/s390/net/qeth_mpc.h
-drivers/sbus/char/envctrl.c
-drivers/sbus/char/jsflash.c
-drivers/scsi/3w-xxxx.c
-drivers/scsi/53c700.c
-drivers/scsi/53c7xx.c
-drivers/scsi/a2091.c
-drivers/scsi/a3000.c
-drivers/scsi/aacraid/aachba.c
-drivers/scsi/aacraid/commctrl.c
-drivers/scsi/aacraid/comminit.c
-drivers/scsi/aacraid/commsup.c
-drivers/scsi/aacraid/dpcsup.c
-drivers/scsi/aacraid/linit.c
-drivers/scsi/aacraid/rx.c
-drivers/scsi/aacraid/sa.c
-drivers/scsi/advansys.c
-drivers/scsi/aha152x.c
-drivers/scsi/aha1542.c
-drivers/scsi/aha1542.h
-drivers/scsi/aha1740.c
-drivers/scsi/aic7xxx/aic79xx_osm.c
-drivers/scsi/aic7xxx/aic79xx_osm.h
-drivers/scsi/aic7xxx/aic7xxx_osm.c
-drivers/scsi/aic7xxx/aic7xxx_osm.h
-drivers/scsi/aic7xxx/aiclib.c
-drivers/scsi/aic7xxx_old.c
-drivers/scsi/AM53C974.c
-drivers/scsi/amiga7xx.c
-drivers/scsi/arm/acornscsi.c
-drivers/scsi/arm/arxescsi.c
-drivers/scsi/arm/cumana_1.c
-drivers/scsi/arm/cumana_2.c
-drivers/scsi/arm/ecoscsi.c
-drivers/scsi/arm/eesox.c
-drivers/scsi/arm/fas216.c
-drivers/scsi/arm/oak.c
-drivers/scsi/arm/powertec.c
-drivers/scsi/arm/queue.c
-drivers/scsi/atari_scsi.c
-drivers/scsi/atp870u.c
-drivers/scsi/blz1230.c
-drivers/scsi/blz2060.c
-drivers/scsi/BusLogic.c
-drivers/scsi/bvme6000.c
-drivers/scsi/constants.c
-drivers/scsi/cpqfcTScontrol.c
-drivers/scsi/cpqfcTSinit.c
-drivers/scsi/cpqfcTSworker.c
-drivers/scsi/cyberstorm.c
-drivers/scsi/cyberstormII.c
-drivers/scsi/dc395x.c
-drivers/scsi/dec_esp.c
-drivers/scsi/dmx3191d.c
-drivers/scsi/dpt_i2o.c
-drivers/scsi/dtc.c
-drivers/scsi/eata.c
-drivers/scsi/eata_pio.c
-drivers/scsi/esp.c
-drivers/scsi/fastlane.c
-drivers/scsi/fcal.c
-drivers/scsi/fd_mcs.c
-drivers/scsi/fdomain.c
-drivers/scsi/gdth.c
-drivers/scsi/g_NCR5380.c
-drivers/scsi/gvp11.c
-drivers/scsi/hosts.c
-drivers/scsi/i91uscsi.c
-drivers/scsi/ibmmca.c
-drivers/scsi/ide-scsi.c
-drivers/scsi/imm.c
-drivers/scsi/imm.h
-drivers/scsi/in2000.c
-drivers/scsi/ini9100u.c
-drivers/scsi/inia100.c
-drivers/scsi/ips.c
-drivers/scsi/ips.h
-drivers/scsi/isp/asm_1000.h
-drivers/scsi/isp/asm_1040.h
-drivers/scsi/isp/asm_1080.h
-drivers/scsi/isp/asm_12160.h
-drivers/scsi/isp/asm_2100.h
-drivers/scsi/isp/asm_2200.h
-drivers/scsi/isp/asm_2300.h
-drivers/scsi/isp/isp.c
-drivers/scsi/isp/isp_cb_ops.c
-drivers/scsi/isp/isp_inline.h
-drivers/scsi/isp/isp_ioctl.h
-drivers/scsi/isp/isp_linux.c
-drivers/scsi/isp/isp_linux.h
-drivers/scsi/isp/ispmbox.h
-drivers/scsi/isp/isp_pci.c
-drivers/scsi/isp/ispreg.h
-drivers/scsi/isp/isp_target.c
-drivers/scsi/isp/isp_target.h
-drivers/scsi/isp/isp_tpublic.h
-drivers/scsi/isp/ispvar.h
-drivers/scsi/isp/Makefile
-drivers/scsi/jazz_esp.c
-drivers/scsi/Kconfig
-drivers/scsi/lasi700.c
-drivers/scsi/mac53c94.c
-drivers/scsi/mac_esp.c
-drivers/scsi/mac_scsi.c
-drivers/scsi/Makefile
-drivers/scsi/mca_53c9x.c
-drivers/scsi/megaraid.c
-drivers/scsi/mesh.c
-drivers/scsi/mvme147.c
-drivers/scsi/mvme16x.c
-drivers/scsi/NCR53c406a.c
-drivers/scsi/ncr53c8xx.c
-drivers/scsi/NCR53C9x.c
-drivers/scsi/NCR_D700.c
-drivers/scsi/NCR_Q720.c
-drivers/scsi/nsp32.c
-drivers/scsi/oktagon_esp.c
-drivers/scsi/osst.c
-drivers/scsi/pas16.c
-drivers/scsi/pc980155.c
-drivers/scsi/pci2000.c
-drivers/scsi/pci2220i.c
-drivers/scsi/pcmcia/aha152x_stub.c
-drivers/scsi/pcmcia/fdomain_stub.c
-drivers/scsi/pcmcia/nsp_cs.c
-drivers/scsi/pcmcia/qlogic_stub.c
-drivers/scsi/pluto.c
-drivers/scsi/ppa.c
-drivers/scsi/ppa.h
-drivers/scsi/psi240i.c
-drivers/scsi/qla1280.c
-drivers/scsi/qlogicfas.c
-drivers/scsi/qlogicfc.c
-drivers/scsi/qlogicisp.c
-drivers/scsi/qlogicpti.c
-drivers/scsi/scsicam.c
-drivers/scsi/scsi_debug.c
-drivers/scsi/scsi.h
-drivers/scsi/scsi_ioctl.c
-drivers/scsi/scsi_lib.c
-drivers/scsi/scsi_module.c
-drivers/scsi/scsi_pc98.c
-drivers/scsi/scsi_priv.h
-drivers/scsi/scsi_proc.c
-drivers/scsi/scsi_scan.c
-drivers/scsi/scsi_syms.c
-drivers/scsi/scsi_sysfs.c
-drivers/scsi/sd.c
-drivers/scsi/seagate.c
-drivers/scsi/sg.c
-drivers/scsi/sgiwd93.c
-drivers/scsi/sim710.c
-drivers/scsi/sr.c
-drivers/scsi/sr_ioctl.c
-drivers/scsi/sr_vendor.c
-drivers/scsi/st.c
-drivers/scsi/sun3_scsi.c
-drivers/scsi/sun3_scsi_vme.c
-drivers/scsi/sun3x_esp.c
-drivers/scsi/sym53c416.c
-drivers/scsi/sym53c8xx_2/sym_glue.c
-drivers/scsi/sym53c8xx_2/sym_glue.h
-drivers/scsi/sym53c8xx_2/sym_hipd.c
-drivers/scsi/sym53c8xx.c
-drivers/scsi/t128.c
-drivers/scsi/tmscsim.c
-drivers/scsi/u14-34f.c
-drivers/scsi/ultrastor.c
-drivers/scsi/wd33c93.c
-drivers/scsi/wd7000.c
-drivers/scsi/zalon.c
-drivers/serial/8250.c
-drivers/serial/core.c
-drivers/serial/Kconfig
-drivers/serial/Makefile
-drivers/serial/nb85e_uart.c
-drivers/serial/sunsu.c
-drivers/serial/sunzilog.c
-drivers/serial/v850e_uart.c
-drivers/telephony/ixj.c
-drivers/telephony/Kconfig
-drivers/usb/class/bluetty.c
-drivers/usb/class/cdc-acm.c
-drivers/usb/class/usblp.c
-drivers/usb/core/file.c
-drivers/usb/core/hcd.c
-drivers/usb/core/hcd-pci.c
-drivers/usb/core/usb.c
-drivers/usb/gadget/ether.c
-drivers/usb/gadget/net2280.c
-drivers/usb/gadget/net2280.h
-drivers/usb/gadget/zero.c
-drivers/usb/host/ohci-hcd.c
-drivers/usb/host/ohci-q.c
-drivers/usb/host/uhci-hcd.c
-drivers/usb/image/hpusbscsi.c
-drivers/usb/image/microtek.c
-drivers/usb/image/scanner.c
-drivers/usb/image/scanner.h
-drivers/usb/media/dabusb.c
-drivers/usb/media/vicam.c
-drivers/usb/misc/usblcd.c
-drivers/usb/misc/usbtest.c
-drivers/usb/net/ax8817x.c
-drivers/usb/net/catc.c
-drivers/usb/net/kaweth.c
-drivers/usb/net/pegasus.c
-drivers/usb/net/rtl8150.c
-drivers/usb/net/usbnet.c
-drivers/usb/serial/ftdi_sio.c
-drivers/usb/serial/ftdi_sio.h
-drivers/usb/serial/ipaq.c
-drivers/usb/serial/ipaq.h
-drivers/usb/serial/usb-serial.c
-drivers/usb/serial/visor.c
-drivers/usb/storage/debug.h
-drivers/usb/storage/isd200.c
-drivers/usb/storage/jumpshot.c
-drivers/usb/storage/protocol.c
-drivers/usb/storage/protocol.h
-drivers/usb/storage/scsiglue.c
-drivers/usb/storage/scsiglue.h
-drivers/usb/storage/sddr09.c
-drivers/usb/storage/sddr55.c
-drivers/usb/storage/transport.h
-drivers/usb/storage/unusual_devs.h
-drivers/usb/storage/usb.c
-drivers/usb/storage/usb.h
-drivers/usb/usb-skeleton.c
-drivers/video/cfbimgblt.c
-drivers/video/chipsfb.c
-drivers/video/console/fbcon.c
-drivers/video/controlfb.c
-drivers/video/epson1355fb.c
-drivers/video/fbmem.c
-drivers/video/g364fb.c
-drivers/video/i2c.c
-drivers/video/i2c.h
-drivers/video/Kconfig
-drivers/video/logo/logo.c
-drivers/video/macfb.c
-drivers/video/Makefile
-drivers/video/neofb.c
-drivers/video/platinumfb.c
-drivers/video/pvr2fb.c
-drivers/video/sis/300vtbl.h
-drivers/video/sis/310vtbl.h
-drivers/video/sis/init301.c
-drivers/video/sis/init301.h
-drivers/video/sis/init.c
-drivers/video/sis/initdef.h
-drivers/video/sis/init.h
-drivers/video/sis/oem300.h
-drivers/video/sis/oem310.h
-drivers/video/sis/osdef.h
-drivers/video/sis/sis_accel.c
-drivers/video/sis/sis_accel.h
-drivers/video/sis/sis_main.c
-drivers/video/sis/sis_main.h
-drivers/video/sis/vgatypes.h
-drivers/video/sis/vstruct.h
-drivers/video/skeletonfb.c
-drivers/video/softcursor.c
-drivers/video/valkyriefb.c
-drivers/video/vesafb.c
-fs/aio.c
-fs/binfmt_elf.c
-fs/bio.c
-fs/buffer.c
-fs/cifs/CHANGES
-fs/cifs/cifsfs.c
-fs/cifs/cifsglob.h
-fs/cifs/connect.c
-fs/cifs/misc.c
-fs/cifs/TODO
-fs/cifs/transport.c
-fs/compat_ioctl.c
-fs/devfs/base.c
-fs/exec.c
-fs/ext2/inode.c
-fs/ext3/acl.c
-fs/ext3/balloc.c
-fs/ext3/inode.c
-fs/ext3/super.c
-fs/ext3/xattr.c
-fs/inode.c
-fs/intermezzo/sysctl.c
-fs/intermezzo/vfs.c
-fs/jbd/journal.c
-fs/jbd/transaction.c
-fs/jffs2/Makefile
-fs/Kconfig
-fs/lockd/clntlock.c
-fs/lockd/svc.c
-fs/namei.c
-fs/namespace.c
-fs/nfs/direct.c
-fs/nfsd/nfssvc.c
-fs/nfs/inode.c
-fs/nfs/nfs3proc.c
-fs/nfs/nfs3xdr.c
-fs/nfs/nfs4proc.c
-fs/nfs/pagelist.c
-fs/nfs/proc.c
-fs/nfs/read.c
-fs/nfs/write.c
-fs/partitions/check.c
-fs/partitions/efi.h
-fs/partitions/nec98.c
-fs/proc/array.c
-fs/proc/proc_misc.c
-fs/stat.c
-fs/umsdos/ioctl.c
-fs/vfat/namei.c
-include/acpi/acconfig.h
-include/acpi/platform/acenv.h
-include/asm-alpha/lockmeter.h
-include/asm-alpha/pgalloc.h
-include/asm-alpha/pgtable.h
-include/asm-alpha/posix_types.h
-include/asm-alpha/smp.h
-include/asm-alpha/spinlock.h
-include/asm-arm26/pgalloc.h
-include/asm-arm26/pgtable.h
-include/asm-arm26/posix_types.h
-include/asm-arm/pgalloc.h
-include/asm-arm/pgtable.h
-include/asm-arm/posix_types.h
-include/asm-cris/pgalloc.h
-include/asm-cris/pgtable.h
-include/asm-cris/posix_types.h
-include/asm-generic/cpumask_array.h
-include/asm-generic/cpumask_const_reference.h
-include/asm-generic/cpumask_const_value.h
-include/asm-generic/cpumask_up.h
-include/asm-generic/local.h
-include/asm-generic/percpu.h
-include/asm-generic/sections.h
-include/asm-h8300/pgtable.h
-include/asm-h8300/posix_types.h
-include/asm-i386/atomic.h
-include/asm-i386/bitops.h
-include/asm-i386/bugs.h
-include/asm-i386/genapic.h
-include/asm-i386/highmem.h
-include/asm-i386/hw_irq.h
-include/asm-i386/kgdb.h
-include/asm-i386/kgdb_local.h
-include/asm-i386/kmap_types.h
-include/asm-i386/local.h
-include/asm-i386/lockmeter.h
-include/asm-i386/mach-bigsmp/mach_apic.h
-include/asm-i386/mach-bigsmp/mach_ipi.h
-include/asm-i386/mach-default/mach_apic.h
-include/asm-i386/mach-default/mach_ipi.h
-include/asm-i386/mach-es7000/mach_apic.h
-include/asm-i386/mach-es7000/mach_ipi.h
-include/asm-i386/mach-numaq/mach_apic.h
-include/asm-i386/mach-numaq/mach_ipi.h
-include/asm-i386/mach-summit/mach_apic.h
-include/asm-i386/mach-summit/mach_ipi.h
-include/asm-i386/mach-visws/mach_apic.h
-include/asm-i386/mmu_context.h
-include/asm-i386/mpspec.h
-include/asm-i386/numaq.h
-include/asm-i386/pgalloc.h
-include/asm-i386/pgtable-2level.h
-include/asm-i386/pgtable-3level.h
-include/asm-i386/pgtable.h
-include/asm-i386/posix_types.h
-include/asm-i386/rwlock.h
-include/asm-i386/smp.h
-include/asm-i386/spinlock.h
-include/asm-i386/stat.h
-include/asm-i386/thread_info.h
-include/asm-i386/topology.h
-include/asm-i386/unistd.h
-include/asm-ia64/atomic.h
-include/asm-ia64/bitops.h
-include/asm-ia64/elf.h
-include/asm-ia64/local.h
-include/asm-ia64/lockmeter.h
-include/asm-ia64/mmu_context.h
-include/asm-ia64/percpu.h
-include/asm-ia64/pgalloc.h
-include/asm-ia64/pgtable.h
-include/asm-ia64/posix_types.h
-include/asm-ia64/processor.h
-include/asm-ia64/smp.h
-include/asm-ia64/spinlock.h
-include/asm-ia64/system.h
-include/asm-ia64/tlb.h
-include/asm-m68k/motorola_pgalloc.h
-include/asm-m68k/motorola_pgtable.h
-include/asm-m68knommu/pgtable.h
-include/asm-m68k/posix_types.h
-include/asm-m68k/sun3_pgalloc.h
-include/asm-mips64/lockmeter.h
-include/asm-mips64/pgalloc.h
-include/asm-mips64/pgtable.h
-include/asm-mips64/posix_types.h
-include/asm-mips64/smp.h
-include/asm-mips/lockmeter.h
-include/asm-mips/pgalloc.h
-include/asm-mips/pgtable.h
-include/asm-mips/posix_types.h
-include/asm-mips/smp.h
-include/asm-mips/spinlock.h
-include/asm-parisc/pgalloc.h
-include/asm-parisc/pgtable.h
-include/asm-parisc/posix_types.h
-include/asm-parisc/smp.h
-include/asm-ppc64/mmu_context.h
-include/asm-ppc64/pgalloc.h
-include/asm-ppc64/pgtable.h
-include/asm-ppc64/semaphore.h
-include/asm-ppc64/smp.h
-include/asm-ppc64/tlb.h
-include/asm-ppc/hardirq.h
-include/asm-ppc/ipc.h
-include/asm-ppc/pci.h
-include/asm-ppc/pgalloc.h
-include/asm-ppc/pgtable.h
-include/asm-ppc/posix_types.h
-include/asm-ppc/processor.h
-include/asm-ppc/smp.h
-include/asm-ppc/uaccess.h
-include/asm-ppc/unistd.h
-include/asm-s390/bitops.h
-include/asm-s390/dma.h
-include/asm-s390/dma-mapping.h
-include/asm-s390/irq.h
-include/asm-s390/mmu_context.h
-include/asm-s390/pgalloc.h
-include/asm-s390/pgtable.h
-include/asm-s390/posix_types.h
-include/asm-s390/siginfo.h
-include/asm-s390/smp.h
-include/asm-s390/tlbflush.h
-include/asm-sh/pgalloc.h
-include/asm-sh/pgtable-2level.h
-include/asm-sh/posix_types.h
-include/asm-sparc64/atomic.h
-include/asm-sparc64/bitops.h
-include/asm-sparc64/local.h
-include/asm-sparc64/lockmeter.h
-include/asm-sparc64/mmu_context.h
-include/asm-sparc64/pgalloc.h
-include/asm-sparc64/pgtable.h
-include/asm-sparc64/posix_types.h
-include/asm-sparc64/sections.h
-include/asm-sparc64/smp.h
-include/asm-sparc64/spinlock.h
-include/asm-sparc/pgalloc.h
-include/asm-sparc/pgtable.h
-include/asm-sparc/posix_types.h
-include/asm-sparc/smp.h
-include/asm-um/pgalloc.h
-include/asm-um/pgtable.h
-include/asm-um/smp.h
-include/asm-v850/anna.h
-include/asm-v850/as85ep1.h
-include/asm-v850/asm.h
-include/asm-v850/cacheflush.h
-include/asm-v850/entry.h
-include/asm-v850/fpga85e2c.h
-include/asm-v850/highres_timer.h
-include/asm-v850/ma1.h
-include/asm-v850/machdep.h
-include/asm-v850/ma.h
-include/asm-v850/me2.h
-include/asm-v850/nb85e_cache.h
-include/asm-v850/nb85e.h
-include/asm-v850/nb85e_intc.h
-include/asm-v850/nb85e_timer_c.h
-include/asm-v850/nb85e_timer_d.h
-include/asm-v850/nb85e_uart.h
-include/asm-v850/nb85e_utils.h
-include/asm-v850/pgtable.h
-include/asm-v850/posix_types.h
-include/asm-v850/processor.h
-include/asm-v850/ptrace.h
-include/asm-v850/rte_cb.h
-include/asm-v850/rte_ma1_cb.h
-include/asm-v850/rte_me2_cb.h
-include/asm-v850/rte_nb85e_cb.h
-include/asm-v850/serial.h
-include/asm-v850/sim85e2c.h
-include/asm-v850/sim85e2.h
-include/asm-v850/sim85e2s.h
-include/asm-v850/stat.h
-include/asm-v850/system.h
-include/asm-v850/teg.h
-include/asm-v850/v850e2_cache.h
-include/asm-v850/v850e2.h
-include/asm-v850/v850e_cache.h
-include/asm-v850/v850e.h
-include/asm-v850/v850e_intc.h
-include/asm-v850/v850e_timer_c.h
-include/asm-v850/v850e_timer_d.h
-include/asm-v850/v850e_uarta.h
-include/asm-v850/v850e_uartb.h
-include/asm-v850/v850e_uart.h
-include/asm-v850/v850e_utils.h
-include/asm-x86_64/bitops.h
-include/asm-x86_64/mpspec.h
-include/asm-x86_64/pgalloc.h
-include/asm-x86_64/pgtable.h
-include/asm-x86_64/posix_types.h
-include/asm-x86_64/smp.h
-include/asm-x86_64/topology.h
-include/linux/aio.h
-include/linux/atmdev.h
-include/linux/bitmap.h
-include/linux/blkdev.h
-include/linux/blk.h
-include/linux/buffer_head.h
-include/linux/compiler.h
-include/linux/config.h
-include/linux/cpumask.h
-include/linux/dm-ioctl.h
-include/linux/dm-ioctl-v1.h
-include/linux/dm-ioctl-v4.h
-include/linux/elevator.h
-include/linux/elfcore.h
-include/linux/errno.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/fb.h
-include/linux/fs.h
-include/linux/hfs_sysdep.h
-include/linux/ide.h
-include/linux/init_task.h
-include/linux/irq.h
-include/linux/kdev_t.h
-include/linux/kernel_stat.h
-include/linux/linux_logo.h
-include/linux/list.h
-include/linux/lockmeter.h
-include/linux/loop.h
-include/linux/mm.h
-include/linux/module.h
-include/linux/namespace.h
-include/linux/netdevice.h
-include/linux/nfs_fs.h
-include/linux/nfs_fs_sb.h
-include/linux/nfs_mount.h
-include/linux/nfs_page.h
-include/linux/nfs_xdr.h
-include/linux/node.h
-include/linux/pagemap.h
-include/linux/pci.h
-include/linux/raid/md_k.h
-include/linux/rcupdate.h
-include/linux/root_dev.h
-include/linux/sched.h
-include/linux/serial_core.h
-include/linux/smp.h
-include/linux/spinlock.h
-include/linux/times.h
-include/linux/topology.h
-include/linux/tty.h
-include/linux/usb.h
-include/linux/wait.h
-include/linux/writeback.h
-include/media/saa7146.h
-include/media/saa7146_vv.h
-include/net/ip_vs.h
-include/pcmcia/ss.h
-include/scsi/scsi_device.h
-include/scsi/scsi_host.h
-include/scsi/scsi_request.h
-include/video/epson1355.h
-include/video/neomagic.h
-include/video/sisfb.h
-init/do_mounts.h
-init/do_mounts_initrd.c
-init/do_mounts_rd.c
-init/main.c
-kernel/compat.c
-kernel/extable.c
-kernel/fork.c
-kernel/ksyms.c
-kernel/lockmeter.c
-kernel/Makefile
-kernel/module.c
-kernel/printk.c
-kernel/profile.c
-kernel/rcupdate.c
-kernel/sched.c
-kernel/softirq.c
-kernel/suspend.c
-kernel/sys.c
-kernel/time.c
-kernel/timer.c
-kernel/workqueue.c
-MAINTAINERS
-Makefile
-mm/bootmem.c
-mm/filemap.c
-mm/fremap.c
-mm/memory.c
-mm/mprotect.c
-mm/mremap.c
-mm/msync.c
-mm/page-writeback.c
-mm/slab.c
-mm/swapfile.c
-mm/swap_state.c
-mm/vmalloc.c
-mm/vmscan.c
-net/atm/br2684.c
-net/atm/clip.c
-net/atm/common.c
-net/atm/common.h
-net/atm/lec.c
-net/atm/mpc.c
-net/atm/pppoatm.c
-net/atm/proc.c
-net/atm/pvc.c
-net/atm/raw.c
-net/atm/signaling.c
-net/atm/signaling.h
-net/atm/svc.c
-net/core/dev.c
-net/ipv4/ip_gre.c
-net/ipv4/ipip.c
-net/ipv4/ipvs/ip_vs_conn.c
-net/ipv4/ipvs/ip_vs_ctl.c
-net/ipv4/ipvs/ip_vs_xmit.c
-net/ipv4/ipvs/Kconfig
-net/ipv4/tcp_input.c
-net/ipv6/addrconf.c
-net/ipv6/ah6.c
-net/ipv6/esp6.c
-net/ipv6/route.c
-net/ipv6/sit.c
-net/ipv6/tcp_ipv6.c
-net/ipv6/xfrm6_input.c
-net/ipv6/xfrm6_policy.c
-net/ipv6/xfrm6_state.c
-net/netsyms.c
-net/sunrpc/auth_gss/auth_gss.c
-net/sunrpc/clnt.c
-net/sunrpc/xprt.c
-net/wanrouter/wanmain.c
-net/xfrm/xfrm_policy.c
-net/xfrm/xfrm_state.c
-net/xfrm/xfrm_user.c
-scripts/ver_linux
-security/Kconfig
-security/Makefile
-security/selinux/avc.c
-security/selinux/hooks.c
-security/selinux/include/avc.h
-security/selinux/include/avc_ss.h
-security/selinux/include/av_inherit.h
-security/selinux/include/av_permissions.h
-security/selinux/include/av_perm_to_string.h
-security/selinux/include/class_to_string.h
-security/selinux/include/common_perm_to_string.h
-security/selinux/include/flask.h
-security/selinux/include/initial_sid_to_string.h
-security/selinux/include/objsec.h
-security/selinux/include/security.h
-security/selinux/Kconfig
-security/selinux/Makefile
-security/selinux/selinuxfs.c
-security/selinux/ss/avtab.c
-security/selinux/ss/avtab.h
-security/selinux/ss/constraint.h
-security/selinux/ss/context.h
-security/selinux/ss/ebitmap.c
-security/selinux/ss/ebitmap.h
-security/selinux/ss/global.h
-security/selinux/ss/hashtab.c
-security/selinux/ss/hashtab.h
-security/selinux/ss/Makefile
-security/selinux/ss/mls.c
-security/selinux/ss/mls.h
-security/selinux/ss/mls_types.h
-security/selinux/ss/policydb.c
-security/selinux/ss/policydb.h
-security/selinux/ss/services.c
-security/selinux/ss/services.h
-security/selinux/ss/sidtab.c
-security/selinux/ss/sidtab.h
-security/selinux/ss/symtab.c
-security/selinux/ss/symtab.h
-sound/core/timer.c
-sound/isa/cmi8330.c
-sound/isa/es18xx.c
-sound/oss/ac97_plugin_ad1980.c
-sound/oss/ad1816.c
-sound/oss/ad1889.c
-sound/oss/btaudio.c
-sound/oss/dmasound/dmasound_core.c
-sound/oss/emu10k1/8010.h
-sound/oss/emu10k1/audio.c
-sound/oss/emu10k1/cardmi.c
-sound/oss/emu10k1/cardmo.c
-sound/oss/emu10k1/cardwo.c
-sound/oss/emu10k1/efxmgr.c
-sound/oss/emu10k1/efxmgr.h
-sound/oss/emu10k1/hwaccess.c
-sound/oss/emu10k1/hwaccess.h
-sound/oss/emu10k1/irqmgr.h
-sound/oss/emu10k1/main.c
-sound/oss/emu10k1/midi.h
-sound/oss/emu10k1/mixer.c
-sound/oss/emu10k1/passthrough.c
-sound/oss/emu10k1/passthrough.h
-sound/oss/emu10k1/recmgr.c
-sound/oss/emu10k1/voicemgr.c
-sound/oss/emu10k1/voicemgr.h
-sound/oss/hal2.c
-sound/oss/hal2.h
-sound/oss/harmony.c
-sound/oss/kahlua.c
-sound/oss/Kconfig
-sound/oss/Makefile
-sound/pci/ice1712/ak4xxx.c
-sound/pci/intel8x0.c
-usr/Makefile
diff --git a/lustre/kernel_patches/pc/dev_read_only.pc b/lustre/kernel_patches/pc/dev_read_only.pc
deleted file mode 100644
index 4760ad131ace785b2af060509e5cc38b6da2fc8e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dev_read_only.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dev_read_only_2.4.20-rh.pc b/lustre/kernel_patches/pc/dev_read_only_2.4.20-rh.pc
deleted file mode 100644
index 4760ad131ace785b2af060509e5cc38b6da2fc8e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dev_read_only_2.4.20-rh.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dev_read_only_2.4.20.pc b/lustre/kernel_patches/pc/dev_read_only_2.4.20.pc
deleted file mode 100644
index 4760ad131ace785b2af060509e5cc38b6da2fc8e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dev_read_only_2.4.20.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dev_read_only_hp_2.4.20.pc b/lustre/kernel_patches/pc/dev_read_only_hp_2.4.20.pc
deleted file mode 100644
index 4760ad131ace785b2af060509e5cc38b6da2fc8e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dev_read_only_hp_2.4.20.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-drivers/block/blkpg.c
-drivers/block/loop.c
-drivers/ide/ide-disk.c
diff --git a/lustre/kernel_patches/pc/dsp.pc b/lustre/kernel_patches/pc/dsp.pc
deleted file mode 100644
index fdbf41859b66af26536397ddfa7ef1fa4c4c56fd..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dsp.pc
+++ /dev/null
@@ -1,6 +0,0 @@
-kernel/bootimg.c
-kernel/bootimg_pic.c
-include/asm-i386/apic.h
-include/linux/crash.h
-arch/i386/kernel/crash.c
-arch/i386/kernel/nmi.c
diff --git a/lustre/kernel_patches/pc/dump_netdev.pc b/lustre/kernel_patches/pc/dump_netdev.pc
deleted file mode 100644
index bb2fde5fdb830b6e95eff89cda1cd9e7e17029e2..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/dump_netdev.pc
+++ /dev/null
@@ -1,9 +0,0 @@
-drivers/net/3c59x.c
-drivers/net/e100/e100_main.c
-drivers/net/e1000/e1000_main.c
-drivers/net/eepro100.c
-drivers/net/smc-ultra.c
-drivers/net/tlan.c
-drivers/net/tulip/tulip_core.c
-include/linux/netdevice.h
-net/core/dev.c
diff --git a/lustre/kernel_patches/pc/export-truncate-2.5.63.pc b/lustre/kernel_patches/pc/export-truncate-2.5.63.pc
deleted file mode 100644
index 3f61c00bc61dcc00544c843cb7adf65b0a8d54d4..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/export-truncate-2.5.63.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-include/linux/mm.h
-mm/truncate.c
diff --git a/lustre/kernel_patches/pc/export-truncate.pc b/lustre/kernel_patches/pc/export-truncate.pc
deleted file mode 100644
index bd58c8246a2c36094257bad9a42a9b87da122a0a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/export-truncate.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-include/linux/mm.h
-mm/filemap.c
diff --git a/lustre/kernel_patches/pc/exports.pc b/lustre/kernel_patches/pc/exports.pc
deleted file mode 100644
index 6472a115d0a42101a30888f96f2b1b336ffa0e9e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/exports.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_2.4.20-rh-hp.pc b/lustre/kernel_patches/pc/exports_2.4.20-rh-hp.pc
deleted file mode 100644
index 6472a115d0a42101a30888f96f2b1b336ffa0e9e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/exports_2.4.20-rh-hp.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_2.4.20.pc b/lustre/kernel_patches/pc/exports_2.4.20.pc
deleted file mode 100644
index 6472a115d0a42101a30888f96f2b1b336ffa0e9e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/exports_2.4.20.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/exports_hp_2.4.20.pc b/lustre/kernel_patches/pc/exports_hp_2.4.20.pc
deleted file mode 100644
index 6472a115d0a42101a30888f96f2b1b336ffa0e9e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/exports_hp_2.4.20.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/super.c
-include/linux/fs.h
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc b/lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc
deleted file mode 100644
index 634b9447a4b1d3e3325715d512aae1524179dd3c..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext-2.4-patch-1-chaos.pc
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/dir.c
-fs/ext3/file.c
-fs/ext3/hash.c
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-include/linux/ext3_jbd.h
-include/linux/rbtree.h
-lib/rbtree.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-1.pc b/lustre/kernel_patches/pc/ext-2.4-patch-1.pc
deleted file mode 100644
index 634b9447a4b1d3e3325715d512aae1524179dd3c..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext-2.4-patch-1.pc
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/Makefile
-fs/ext3/dir.c
-fs/ext3/file.c
-fs/ext3/hash.c
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
-include/linux/ext3_jbd.h
-include/linux/rbtree.h
-lib/rbtree.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-2.pc b/lustre/kernel_patches/pc/ext-2.4-patch-2.pc
deleted file mode 100644
index 9b16759409837969345582b3a3b1df9e54878ce9..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext-2.4-patch-2.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-3.pc b/lustre/kernel_patches/pc/ext-2.4-patch-3.pc
deleted file mode 100644
index 65d48452e4a71c92a55de1d9ccd771f2c7353254..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext-2.4-patch-3.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/dir.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext-2.4-patch-4.pc b/lustre/kernel_patches/pc/ext-2.4-patch-4.pc
deleted file mode 100644
index 9b16759409837969345582b3a3b1df9e54878ce9..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext-2.4-patch-4.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext3-2.4-ino_t.pc b/lustre/kernel_patches/pc/ext3-2.4-ino_t.pc
deleted file mode 100644
index 4cef9792a3a5283ba64958e19fabba9f51b3ca6f..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-2.4-ino_t.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc b/lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc
deleted file mode 100644
index cd21583d1e35d29942a82b075d644dfa2428b532..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-2.4.18-ino_sb_macro.pc
+++ /dev/null
@@ -1,10 +0,0 @@
-fs/ext3/balloc.c
-fs/ext3/dir.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/ioctl.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
diff --git a/lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc b/lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc
deleted file mode 100644
index 441ced84fc6d8aff5f93a13f30d71b7b2eecf3df..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-2.4.20-fixes.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/balloc.c
diff --git a/lustre/kernel_patches/pc/ext3-delete_thread-2.4.18.pc b/lustre/kernel_patches/pc/ext3-delete_thread-2.4.18.pc
deleted file mode 100644
index 1afa4d47dddc00c4371d158c51977995c66598de..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-delete_thread-2.4.18.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/ext3/super.c
-fs/ext3/file.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc b/lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc
deleted file mode 100644
index a2c3109470b220f02217a547dfa21b556dfd9a65..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-delete_thread-2.4.20.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/ext3/super.c
-fs/ext3/inode.c
-fs/ext3/file.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3-error-export.pc b/lustre/kernel_patches/pc/ext3-error-export.pc
deleted file mode 100644
index efd7db00869716ef60ef6eb4f74d478c4dc202f0..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-error-export.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/ext3-exports.c
diff --git a/lustre/kernel_patches/pc/ext3-largefile.pc b/lustre/kernel_patches/pc/ext3-largefile.pc
deleted file mode 100644
index 76d683f8bc874f058d79ae03b5be277071ff8f0f..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-largefile.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/ext3-map_inode_page.pc b/lustre/kernel_patches/pc/ext3-map_inode_page.pc
deleted file mode 100644
index 6631de4eabfcc025238dfe4557c12972d43290cb..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-map_inode_page.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/inode.c
-fs/ext3/ext3-exports.c
-fs/ext3/Makefile
diff --git a/lustre/kernel_patches/pc/ext3-map_inode_page_2.4.18.pc b/lustre/kernel_patches/pc/ext3-map_inode_page_2.4.18.pc
deleted file mode 100644
index 6631de4eabfcc025238dfe4557c12972d43290cb..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-map_inode_page_2.4.18.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/inode.c
-fs/ext3/ext3-exports.c
-fs/ext3/Makefile
diff --git a/lustre/kernel_patches/pc/ext3-noread-2.4.20.pc b/lustre/kernel_patches/pc/ext3-noread-2.4.20.pc
deleted file mode 100644
index 9c3cea8787b9ae962d2920bd75dc18523c0986da..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-noread-2.4.20.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-noread-inode.pc b/lustre/kernel_patches/pc/ext3-noread-inode.pc
deleted file mode 100644
index 9c3cea8787b9ae962d2920bd75dc18523c0986da..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-noread-inode.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/ext3-orphan_lock.pc b/lustre/kernel_patches/pc/ext3-orphan_lock.pc
deleted file mode 100644
index 98aebb043b373b876a567926287b6f7126d37ac4..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-orphan_lock.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3-san-2.4.20.pc b/lustre/kernel_patches/pc/ext3-san-2.4.20.pc
deleted file mode 100644
index 9ed5141bb1eb32d158fddc1fc90e232afc6d90d1..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-san-2.4.20.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/ext3/inode.c
-fs/ext3/ext3-exports.c
diff --git a/lustre/kernel_patches/pc/ext3-san-jdike-2.5.73.pc b/lustre/kernel_patches/pc/ext3-san-jdike-2.5.73.pc
deleted file mode 100644
index 231df0ecd171694c4f97d4d29992f92648a53522..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-san-jdike-2.5.73.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/ext3/inode.c
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/ext3-truncate_blocks.pc b/lustre/kernel_patches/pc/ext3-truncate_blocks.pc
deleted file mode 100644
index 76d683f8bc874f058d79ae03b5be277071ff8f0f..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-truncate_blocks.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/inode.c
diff --git a/lustre/kernel_patches/pc/ext3-unmount_sync.pc b/lustre/kernel_patches/pc/ext3-unmount_sync.pc
deleted file mode 100644
index 08795de2d8d557dd466e2501ca7d14f626016bac..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-unmount_sync.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/ext3-use-after-free.pc b/lustre/kernel_patches/pc/ext3-use-after-free.pc
deleted file mode 100644
index daf87871d9fc4d2fd84ba2bdf20337a4d21f2853..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3-use-after-free.pc
+++ /dev/null
@@ -1 +0,0 @@
-./fs/ext3/namei.c
diff --git a/lustre/kernel_patches/pc/ext3_delete_thread_2.4.20_chaos.pc b/lustre/kernel_patches/pc/ext3_delete_thread_2.4.20_chaos.pc
deleted file mode 100644
index a2c3109470b220f02217a547dfa21b556dfd9a65..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3_delete_thread_2.4.20_chaos.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/ext3/super.c
-fs/ext3/inode.c
-fs/ext3/file.c
-include/linux/ext3_fs.h
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc b/lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc
deleted file mode 100644
index 98aebb043b373b876a567926287b6f7126d37ac4..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/ext3_orphan_lock-2.4.20-rh.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs_sb.h
diff --git a/lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc b/lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc
deleted file mode 100644
index 7191405ee8cf31ec55fc6c119530d0e1ce29ce22..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/extN-2.4.18-ino_sb_fixup.pc
+++ /dev/null
@@ -1 +0,0 @@
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/extN-misc-fixup.pc b/lustre/kernel_patches/pc/extN-misc-fixup.pc
deleted file mode 100644
index 08795de2d8d557dd466e2501ca7d14f626016bac..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/extN-misc-fixup.pc
+++ /dev/null
@@ -1 +0,0 @@
-fs/ext3/super.c
diff --git a/lustre/kernel_patches/pc/extN-noread.pc b/lustre/kernel_patches/pc/extN-noread.pc
deleted file mode 100644
index 9c3cea8787b9ae962d2920bd75dc18523c0986da..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/extN-noread.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/extN-wantedi.pc b/lustre/kernel_patches/pc/extN-wantedi.pc
deleted file mode 100644
index 6ad25892094ac785e8b8efc7cc36e1f42840f7bc..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/extN-wantedi.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/ext3/namei.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/ioctl.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/gpl_header-chaos-2.4.20.pc b/lustre/kernel_patches/pc/gpl_header-chaos-2.4.20.pc
deleted file mode 100644
index 0c29f3651b93c0e5156b19c774a7eb6517bcd4aa..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/gpl_header-chaos-2.4.20.pc
+++ /dev/null
@@ -1 +0,0 @@
-include/linux/module.h
diff --git a/lustre/kernel_patches/pc/htree-ext3-2.4.18.pc b/lustre/kernel_patches/pc/htree-ext3-2.4.18.pc
deleted file mode 100644
index 649977896cfd523bfc084aa094efe2fabca3e825..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/htree-ext3-2.4.18.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/ext3/super.c
-fs/ext3/namei.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
diff --git a/lustre/kernel_patches/pc/inode-protection-from-pdflush.pc b/lustre/kernel_patches/pc/inode-protection-from-pdflush.pc
deleted file mode 100644
index c1b89a18173f71d0edcca88cb00eb731d7eedc3d..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/inode-protection-from-pdflush.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/fs-writeback.c
-include/linux/fs.h
diff --git a/lustre/kernel_patches/pc/inode-unhash_2.5.75.pc b/lustre/kernel_patches/pc/inode-unhash_2.5.75.pc
deleted file mode 100644
index 7d04f840395787f9376ab039883c6b16c7a05ca3..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/inode-unhash_2.5.75.pc
+++ /dev/null
@@ -1,2 +0,0 @@
-fs/inode.c
-include/linux/fs.h
diff --git a/lustre/kernel_patches/pc/invalidate_show-2.4.20-rh.pc b/lustre/kernel_patches/pc/invalidate_show-2.4.20-rh.pc
deleted file mode 100644
index 1d4ed77bf952e8e352200bfb5329aaee7774e4e6..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/invalidate_show-2.4.20-rh.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/inode.c
-fs/super.c
-include/linux/fs.h
-fs/smbfs/inode.c
diff --git a/lustre/kernel_patches/pc/invalidate_show.pc b/lustre/kernel_patches/pc/invalidate_show.pc
deleted file mode 100644
index 1d4ed77bf952e8e352200bfb5329aaee7774e4e6..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/invalidate_show.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/inode.c
-fs/super.c
-include/linux/fs.h
-fs/smbfs/inode.c
diff --git a/lustre/kernel_patches/pc/invalidate_show_2.4.20_chaos.pc b/lustre/kernel_patches/pc/invalidate_show_2.4.20_chaos.pc
deleted file mode 100644
index 1d4ed77bf952e8e352200bfb5329aaee7774e4e6..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/invalidate_show_2.4.20_chaos.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/inode.c
-fs/super.c
-include/linux/fs.h
-fs/smbfs/inode.c
diff --git a/lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc b/lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc
deleted file mode 100644
index 07288b0e6495ff3e19d1fda6cc351f76159ef4e1..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iod-rmap-exports-2.4.20.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/vmscan.c
-mm/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-rmap-exports.pc b/lustre/kernel_patches/pc/iod-rmap-exports.pc
deleted file mode 100644
index 07288b0e6495ff3e19d1fda6cc351f76159ef4e1..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iod-rmap-exports.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/vmscan.c
-mm/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-stock-24-exports.pc b/lustre/kernel_patches/pc/iod-stock-24-exports.pc
deleted file mode 100644
index e4eceee6577857fa83cb8377778a01b16def356c..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iod-stock-24-exports.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc b/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc
deleted file mode 100644
index e4eceee6577857fa83cb8377778a01b16def356c..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/inode.c
-fs/Makefile
-mm/page_alloc.c
diff --git a/lustre/kernel_patches/pc/iopen-2.4.18.pc b/lustre/kernel_patches/pc/iopen-2.4.18.pc
deleted file mode 100644
index b40b1f3af3b507d72b20cf91a857481f0730b564..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iopen-2.4.18.pc
+++ /dev/null
@@ -1,8 +0,0 @@
-Documentation/filesystems/ext2.txt
-fs/ext3/Makefile
-fs/ext3/inode.c
-fs/ext3/iopen.c
-fs/ext3/iopen.h
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/iopen-2.4.20.pc b/lustre/kernel_patches/pc/iopen-2.4.20.pc
deleted file mode 100644
index b40b1f3af3b507d72b20cf91a857481f0730b564..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iopen-2.4.20.pc
+++ /dev/null
@@ -1,8 +0,0 @@
-Documentation/filesystems/ext2.txt
-fs/ext3/Makefile
-fs/ext3/inode.c
-fs/ext3/iopen.c
-fs/ext3/iopen.h
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/iopen-2.5.73.pc b/lustre/kernel_patches/pc/iopen-2.5.73.pc
deleted file mode 100644
index b40b1f3af3b507d72b20cf91a857481f0730b564..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/iopen-2.5.73.pc
+++ /dev/null
@@ -1,8 +0,0 @@
-Documentation/filesystems/ext2.txt
-fs/ext3/Makefile
-fs/ext3/inode.c
-fs/ext3/iopen.c
-fs/ext3/iopen.h
-fs/ext3/namei.c
-fs/ext3/super.c
-include/linux/ext3_fs.h
diff --git a/lustre/kernel_patches/pc/kexec-2.5.73-full.pc b/lustre/kernel_patches/pc/kexec-2.5.73-full.pc
deleted file mode 100644
index 939f3d4a90e2fb0acb94fdac377277907ae29fef..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kexec-2.5.73-full.pc
+++ /dev/null
@@ -1,23 +0,0 @@
-MAINTAINERS
-arch/i386/Kconfig
-arch/i386/defconfig
-arch/i386/kernel/Makefile
-arch/i386/kernel/apic.c
-arch/i386/kernel/dmi_scan.c
-arch/i386/kernel/entry.S
-arch/i386/kernel/i8259.c
-arch/i386/kernel/io_apic.c
-arch/i386/kernel/machine_kexec.c
-arch/i386/kernel/reboot.c
-arch/i386/kernel/relocate_kernel.S
-arch/i386/kernel/smp.c
-fs/aio.c
-include/asm-i386/apic.h
-include/asm-i386/apicdef.h
-include/asm-i386/kexec.h
-include/asm-i386/unistd.h
-include/linux/kexec.h
-include/linux/reboot.h
-kernel/Makefile
-kernel/kexec.c
-kernel/sys.c
diff --git a/lustre/kernel_patches/pc/kexec-2.6.0-full.pc b/lustre/kernel_patches/pc/kexec-2.6.0-full.pc
deleted file mode 100644
index 939f3d4a90e2fb0acb94fdac377277907ae29fef..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kexec-2.6.0-full.pc
+++ /dev/null
@@ -1,23 +0,0 @@
-MAINTAINERS
-arch/i386/Kconfig
-arch/i386/defconfig
-arch/i386/kernel/Makefile
-arch/i386/kernel/apic.c
-arch/i386/kernel/dmi_scan.c
-arch/i386/kernel/entry.S
-arch/i386/kernel/i8259.c
-arch/i386/kernel/io_apic.c
-arch/i386/kernel/machine_kexec.c
-arch/i386/kernel/reboot.c
-arch/i386/kernel/relocate_kernel.S
-arch/i386/kernel/smp.c
-fs/aio.c
-include/asm-i386/apic.h
-include/asm-i386/apicdef.h
-include/asm-i386/kexec.h
-include/asm-i386/unistd.h
-include/linux/kexec.h
-include/linux/reboot.h
-kernel/Makefile
-kernel/kexec.c
-kernel/sys.c
diff --git a/lustre/kernel_patches/pc/kgdb-ga-2.5.73.pc b/lustre/kernel_patches/pc/kgdb-ga-2.5.73.pc
deleted file mode 100644
index 1d9952456891ea34034f77e309cfc05ed2bd4267..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kgdb-ga-2.5.73.pc
+++ /dev/null
@@ -1,28 +0,0 @@
-arch/i386/Kconfig
-arch/i386/kernel/entry.S
-arch/i386/kernel/kgdb_stub.c
-arch/i386/kernel/Makefile
-arch/i386/kernel/nmi.c
-arch/i386/kernel/smp.c
-arch/i386/kernel/traps.c
-arch/i386/lib/kgdb_serial.c
-arch/i386/lib/Makefile
-arch/i386/Makefile
-arch/i386/mm/fault.c
-Documentation/i386/kgdb/andthen
-Documentation/i386/kgdb/debug-nmi.txt
-Documentation/i386/kgdb/gdb-globals.txt
-Documentation/i386/kgdb/gdbinit
-Documentation/i386/kgdb/gdbinit.hw
-Documentation/i386/kgdb/gdbinit-modules
-Documentation/i386/kgdb/kgdb.txt
-Documentation/i386/kgdb/loadmodule.sh
-drivers/char/keyboard.c
-drivers/char/sysrq.c
-drivers/serial/8250.c
-include/asm-i386/bugs.h
-include/asm-i386/kgdb.h
-include/asm-i386/kgdb_local.h
-include/linux/config.h
-kernel/sched.c
-MAINTAINERS
diff --git a/lustre/kernel_patches/pc/kgdb-ga-docco-fixes-2.5.73.pc b/lustre/kernel_patches/pc/kgdb-ga-docco-fixes-2.5.73.pc
deleted file mode 100644
index 87e2eca59714f71243c751d7cef7a0e0542ef92e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kgdb-ga-docco-fixes-2.5.73.pc
+++ /dev/null
@@ -1 +0,0 @@
-Documentation/i386/kgdb/kgdb.txt
diff --git a/lustre/kernel_patches/pc/kgdb-use-ggdb-2.5.73.pc b/lustre/kernel_patches/pc/kgdb-use-ggdb-2.5.73.pc
deleted file mode 100644
index 43f4115564cbe9dc307b5b5457d3e7c7e620de31..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kgdb-use-ggdb-2.5.73.pc
+++ /dev/null
@@ -1 +0,0 @@
-arch/i386/Makefile
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate.pc b/lustre/kernel_patches/pc/kmem_cache_validate.pc
deleted file mode 100644
index a0a629722159ef1f0ee384d2b8b65af8978ff38d..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kmem_cache_validate.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-arch/i386/mm/init.c
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc b/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc
deleted file mode 100644
index a0a629722159ef1f0ee384d2b8b65af8978ff38d..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20-rh.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-arch/i386/mm/init.c
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc b/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc
deleted file mode 100644
index bdba88418531035f9482d2ad8415f32e8a83811f..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kmem_cache_validate_2.4.20.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-arch/i386/mm/init.c
diff --git a/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc b/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc
deleted file mode 100644
index bdba88418531035f9482d2ad8415f32e8a83811f..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/kmem_cache_validate_hp.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-arch/ia64/mm/init.c
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-arch/i386/mm/init.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc b/lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc
deleted file mode 100644
index 6c8010686af2f553653c3067393fd3c15f9c5720..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/linux-2.4.18ea-0.8.26.pc
+++ /dev/null
@@ -1,11 +0,0 @@
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/ext3-exports.c
-fs/ext3/xattr.c
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/xattr.h
-fs/ext3/Makefile
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc
deleted file mode 100644
index dbf35cb4ae16fa1a5390643ccb27b66c91862c28..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-chaos.pc
+++ /dev/null
@@ -1,62 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
-fs/ext3/ext3-exports.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc
deleted file mode 100644
index 1e8cf75cc49a80cb0a2afb24e43dd0cbf484e47c..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54-hp.pc
+++ /dev/null
@@ -1,62 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/ext3/ext3-exports.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
diff --git a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc b/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc
deleted file mode 100644
index 2de1b2c36381c780336f48594d72de3e7cdf13d7..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/linux-2.4.20-xattr-0.8.54.pc
+++ /dev/null
@@ -1,64 +0,0 @@
-Documentation/Configure.help
-arch/alpha/defconfig
-arch/alpha/kernel/entry.S
-arch/arm/defconfig
-arch/arm/kernel/calls.S
-arch/i386/defconfig
-arch/ia64/defconfig
-arch/ia64/kernel/entry.S
-arch/m68k/defconfig
-arch/mips/defconfig
-arch/mips64/defconfig
-arch/ppc/defconfig
-arch/ppc64/kernel/misc.S
-arch/s390/defconfig
-arch/s390/kernel/entry.S
-arch/s390x/defconfig
-arch/s390x/kernel/entry.S
-arch/s390x/kernel/wrapper32.S
-arch/sparc/defconfig
-arch/sparc/kernel/systbls.S
-arch/sparc64/defconfig
-arch/sparc64/kernel/systbls.S
-fs/Config.in
-fs/Makefile
-fs/ext2/Makefile
-fs/ext2/file.c
-fs/ext2/ialloc.c
-fs/ext2/inode.c
-fs/ext2/namei.c
-fs/ext2/super.c
-fs/ext2/symlink.c
-fs/ext2/xattr.c
-fs/ext2/xattr_user.c
-fs/ext3/Makefile
-fs/ext3/file.c
-fs/ext3/ialloc.c
-fs/ext3/inode.c
-fs/ext3/namei.c
-fs/ext3/super.c
-fs/ext3/symlink.c
-fs/ext3/xattr.c
-fs/ext3/xattr_user.c
-fs/jfs/jfs_xattr.h
-fs/jfs/xattr.c
-fs/mbcache.c
-include/asm-arm/unistd.h
-include/asm-ia64/unistd.h
-include/asm-ppc64/unistd.h
-include/asm-s390/unistd.h
-include/asm-s390x/unistd.h
-include/asm-sparc/unistd.h
-include/asm-sparc64/unistd.h
-include/linux/cache_def.h
-include/linux/errno.h
-include/linux/ext2_fs.h
-include/linux/ext2_xattr.h
-include/linux/ext3_fs.h
-include/linux/ext3_jbd.h
-include/linux/ext3_xattr.h
-include/linux/fs.h
-include/linux/mbcache.h
-kernel/ksyms.c
-mm/vmscan.c
-fs/ext3/ext3-exports.c
diff --git a/lustre/kernel_patches/pc/lkcd-cvs-2.5.69.pc b/lustre/kernel_patches/pc/lkcd-cvs-2.5.69.pc
deleted file mode 100644
index 2799a8eaf1f999aa34f623f982edb85ba182ebb8..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lkcd-cvs-2.5.69.pc
+++ /dev/null
@@ -1,19 +0,0 @@
-drivers/dump/Makefile
-drivers/dump/dump_blockdev.c
-drivers/dump/dump_execute.c
-drivers/dump/dump_filters.c
-drivers/dump/dump_fmt.c
-drivers/dump/dump_gzip.c
-drivers/dump/dump_i386.c
-drivers/dump/dump_memdev.c
-drivers/dump/dump_netdev.c
-drivers/dump/dump_overlay.c
-drivers/dump/dump_rle.c
-drivers/dump/dump_scheme.c
-drivers/dump/dump_setup.c
-include/linux/dumpdev.h
-include/linux/dump.h
-include/linux/dump_netdev.h
-include/asm-i386/dump.h
-init/kerntypes.c
-drivers/dump/dump_methods.h
diff --git a/lustre/kernel_patches/pc/lkcd-kernel-changes-2.5.73.pc b/lustre/kernel_patches/pc/lkcd-kernel-changes-2.5.73.pc
deleted file mode 100644
index 722bb20383d50789bd7702b354fa8897792c7517..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lkcd-kernel-changes-2.5.73.pc
+++ /dev/null
@@ -1,25 +0,0 @@
-drivers/Makefile
-include/linux/major.h
-include/linux/sysctl.h
-include/asm-i386/mach-default/irq_vectors.h
-include/asm-i386/kmap_types.h
-include/asm-i386/smp.h
-arch/i386/kernel/i386_ksyms.c
-arch/i386/kernel/nmi.c
-arch/i386/kernel/setup.c
-arch/i386/kernel/smp.c
-arch/i386/kernel/traps.c
-arch/i386/mm/init.c
-arch/i386/boot/Makefile
-arch/i386/Kconfig
-arch/s390/boot/Makefile
-arch/s390/boot/install.sh
-scripts/mkcompile_h
-kernel/ksyms.c
-kernel/panic.c
-kernel/sched.c
-lib/Kconfig
-mm/page_alloc.c
-init/Makefile
-init/main.c
-init/version.c
diff --git a/lustre/kernel_patches/pc/lkcd-kernel-changes-2.6.0-test1.pc b/lustre/kernel_patches/pc/lkcd-kernel-changes-2.6.0-test1.pc
deleted file mode 100644
index 722bb20383d50789bd7702b354fa8897792c7517..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lkcd-kernel-changes-2.6.0-test1.pc
+++ /dev/null
@@ -1,25 +0,0 @@
-drivers/Makefile
-include/linux/major.h
-include/linux/sysctl.h
-include/asm-i386/mach-default/irq_vectors.h
-include/asm-i386/kmap_types.h
-include/asm-i386/smp.h
-arch/i386/kernel/i386_ksyms.c
-arch/i386/kernel/nmi.c
-arch/i386/kernel/setup.c
-arch/i386/kernel/smp.c
-arch/i386/kernel/traps.c
-arch/i386/mm/init.c
-arch/i386/boot/Makefile
-arch/i386/Kconfig
-arch/s390/boot/Makefile
-arch/s390/boot/install.sh
-scripts/mkcompile_h
-kernel/ksyms.c
-kernel/panic.c
-kernel/sched.c
-lib/Kconfig
-mm/page_alloc.c
-init/Makefile
-init/main.c
-init/version.c
diff --git a/lustre/kernel_patches/pc/lustre-2.5.pc b/lustre/kernel_patches/pc/lustre-2.5.pc
deleted file mode 100644
index 71434ea29c96cec776160d3fd52983fc5b985a31..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lustre-2.5.pc
+++ /dev/null
@@ -1,11 +0,0 @@
-arch/um/kernel/mem.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/sysfs/inode.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/namei.h
-include/linux/slab.h
-kernel/ksyms.c
-mm/slab.c
-net/unix/af_unix.c
diff --git a/lustre/kernel_patches/pc/lustre_build.pc b/lustre/kernel_patches/pc/lustre_build.pc
deleted file mode 100644
index 98afcc65a0c7ca24a0363427683b7e1be0b151cd..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lustre_build.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-init/main.c
-fs/Makefile
-mm/Makefile
-fs/Kconfig
diff --git a/lustre/kernel_patches/pc/lustre_version.pc b/lustre/kernel_patches/pc/lustre_version.pc
deleted file mode 100644
index 898bebd69cacf24b3d658c0487a96f7013dad3f6..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/lustre_version.pc
+++ /dev/null
@@ -1 +0,0 @@
-include/linux/lustre_version.h
diff --git a/lustre/kernel_patches/pc/mcore-2.4.20-8.pc b/lustre/kernel_patches/pc/mcore-2.4.20-8.pc
deleted file mode 100644
index b290f604406dc62a6ae196c9e7a8801683a09643..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/mcore-2.4.20-8.pc
+++ /dev/null
@@ -1,34 +0,0 @@
-Makefile
-Documentation/Configure.help
-arch/i386/config.in
-arch/i386/vmlinux.lds
-arch/i386/boot/setup.S
-arch/i386/kernel/Makefile
-arch/i386/kernel/crash.c
-arch/i386/kernel/nmi.c
-arch/i386/kernel/process.c
-arch/i386/kernel/setup.c
-arch/i386/kernel/smp.c
-arch/i386/kernel/traps.c
-drivers/char/misc.c
-drivers/char/sysrq.c
-include/asm-i386/bootimg.h
-include/asm-i386/crash.h
-include/linux/bootimg.h
-include/linux/crash.h
-include/linux/mm.h
-include/linux/reboot.h
-include/linux/sysctl.h
-init/main.c
-kernel/Makefile
-kernel/bootimg.c
-kernel/bootimg_pic.c
-kernel/crash.c
-kernel/module.c
-kernel/panic.c
-kernel/sysctl.c
-lib/Config.in
-mm/memory.c
-mm/page_alloc.c
-arch/i386//boot/compressed/head.S
-arch/i386//kernel/head.S
diff --git a/lustre/kernel_patches/pc/qla2xxx-v8.00.00b1-2.5.73.pc b/lustre/kernel_patches/pc/qla2xxx-v8.00.00b1-2.5.73.pc
deleted file mode 100644
index 06952b0fc203104e00a1167649286b71b7702a4e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/qla2xxx-v8.00.00b1-2.5.73.pc
+++ /dev/null
@@ -1,42 +0,0 @@
-drivers/scsi/Makefile
-drivers/scsi/Kconfig
-drivers/scsi/qla2xxx/Kconfig
-drivers/scsi/qla2xxx/Makefile
-drivers/scsi/qla2xxx/README.qla2x00
-drivers/scsi/qla2xxx/exioct.h
-drivers/scsi/qla2xxx/exioctln.h
-drivers/scsi/qla2xxx/inioct.h
-drivers/scsi/qla2xxx/ql2100tp_fw.c
-drivers/scsi/qla2xxx/ql2200ip_fw.c
-drivers/scsi/qla2xxx/ql2300tpx_fw.c
-drivers/scsi/qla2xxx/qla_cfg.c
-drivers/scsi/qla2xxx/qla_cfg.h
-drivers/scsi/qla2xxx/qla_cfgln.c
-drivers/scsi/qla2xxx/qla_dbg.c
-drivers/scsi/qla2xxx/qla_dbg.h
-drivers/scsi/qla2xxx/qla_def.h
-drivers/scsi/qla2xxx/qla_fo.c
-drivers/scsi/qla2xxx/qla_fo.cfg
-drivers/scsi/qla2xxx/qla_fo.h
-drivers/scsi/qla2xxx/qla_gbl.h
-drivers/scsi/qla2xxx/qla_inioct.c
-drivers/scsi/qla2xxx/qla_init.c
-drivers/scsi/qla2xxx/qla_inline.h
-drivers/scsi/qla2xxx/qla_iocb.c
-drivers/scsi/qla2xxx/qla_ip.c
-drivers/scsi/qla2xxx/qla_ip.h
-drivers/scsi/qla2xxx/qla_isr.c
-drivers/scsi/qla2xxx/qla_listops.h
-drivers/scsi/qla2xxx/qla_mbx.c
-drivers/scsi/qla2xxx/qla_os.c
-drivers/scsi/qla2xxx/qla_os.h
-drivers/scsi/qla2xxx/qla_settings.h
-drivers/scsi/qla2xxx/qla_sup.c
-drivers/scsi/qla2xxx/qla_vendor.c
-drivers/scsi/qla2xxx/qla_version.h
-drivers/scsi/qla2xxx/qla_xioct.c
-drivers/scsi/qla2xxx/qlfo.h
-drivers/scsi/qla2xxx/qlfolimits.h
-drivers/scsi/qla2xxx/qlfoln.h
-drivers/scsi/qla2xxx/release.txt
-drivers/scsi/qla2xxx/revision.notes
diff --git a/lustre/kernel_patches/pc/socket-exports-vanilla.pc b/lustre/kernel_patches/pc/socket-exports-vanilla.pc
deleted file mode 100644
index 3277003af4129bbc0061e07e03e8ceb76733885d..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/socket-exports-vanilla.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-include/linux/socket.h
-net/netsyms.c
-net/socket.c
diff --git a/lustre/kernel_patches/pc/tcp-zero-copy.pc b/lustre/kernel_patches/pc/tcp-zero-copy.pc
deleted file mode 100644
index 02877c058daff5171e3f47ab1362d64bd569d520..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/tcp-zero-copy.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-include/linux/skbuff.h
-include/net/tcp.h
-net/netsyms.c
-net/core/skbuff.c
-net/ipv4/tcp.c
diff --git a/lustre/kernel_patches/pc/tcp_zero_copy_2.4.20_chaos.pc b/lustre/kernel_patches/pc/tcp_zero_copy_2.4.20_chaos.pc
deleted file mode 100644
index 02877c058daff5171e3f47ab1362d64bd569d520..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/tcp_zero_copy_2.4.20_chaos.pc
+++ /dev/null
@@ -1,5 +0,0 @@
-include/linux/skbuff.h
-include/net/tcp.h
-net/netsyms.c
-net/core/skbuff.c
-net/ipv4/tcp.c
diff --git a/lustre/kernel_patches/pc/uml-patch-2.4.20-6.pc b/lustre/kernel_patches/pc/uml-patch-2.4.20-6.pc
deleted file mode 100644
index cad87673451b59ac7b0997e7dda633a166ff14f0..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/uml-patch-2.4.20-6.pc
+++ /dev/null
@@ -1,398 +0,0 @@
-arch/um/common.ld.in
-arch/um/config_block.in
-arch/um/config_char.in
-arch/um/config.in
-arch/um/config_net.in
-arch/um/config.release
-arch/um/config_scsi.in
-arch/um/defconfig
-arch/um/drivers/chan_kern.c
-arch/um/drivers/chan_user.c
-arch/um/drivers/cow.h
-arch/um/drivers/cow_sys.h
-arch/um/drivers/cow_user.c
-arch/um/drivers/daemon.h
-arch/um/drivers/daemon_kern.c
-arch/um/drivers/daemon_user.c
-arch/um/drivers/fd.c
-arch/um/drivers/harddog_kern.c
-arch/um/drivers/harddog_user.c
-arch/um/drivers/hostaudio_kern.c
-arch/um/drivers/hostaudio_user.c
-arch/um/drivers/line.c
-arch/um/drivers/Makefile
-arch/um/drivers/mcast.h
-arch/um/drivers/mcast_kern.c
-arch/um/drivers/mcast_user.c
-arch/um/drivers/mconsole_kern.c
-arch/um/drivers/mconsole_user.c
-arch/um/drivers/mmapper_kern.c
-arch/um/drivers/net_kern.c
-arch/um/drivers/net_user.c
-arch/um/drivers/null.c
-arch/um/drivers/pcap_kern.c
-arch/um/drivers/pcap_user.c
-arch/um/drivers/pcap_user.h
-arch/um/drivers/port.h
-arch/um/drivers/port_kern.c
-arch/um/drivers/port_user.c
-arch/um/drivers/pty.c
-arch/um/drivers/slip.h
-arch/um/drivers/slip_kern.c
-arch/um/drivers/slip_proto.h
-arch/um/drivers/slip_user.c
-arch/um/drivers/slirp.h
-arch/um/drivers/slirp_kern.c
-arch/um/drivers/slirp_user.c
-arch/um/drivers/ssl.c
-arch/um/drivers/ssl.h
-arch/um/drivers/stdio_console.c
-arch/um/drivers/stdio_console.h
-arch/um/drivers/tty.c
-arch/um/drivers/ubd_kern.c
-arch/um/drivers/ubd_user.c
-arch/um/drivers/xterm.c
-arch/um/drivers/xterm.h
-arch/um/drivers/xterm_kern.c
-arch/um/dyn_link.ld.in
-arch/um/fs/hostfs/hostfs.h
-arch/um/fs/hostfs/hostfs_kern.c
-arch/um/fs/hostfs/hostfs_user.c
-arch/um/fs/hostfs/Makefile
-arch/um/fs/hppfs/hppfs_kern.c
-arch/um/fs/hppfs/Makefile
-arch/um/fs/Makefile
-arch/um/include/2_5compat.h
-arch/um/include/chan_kern.h
-arch/um/include/chan_user.h
-arch/um/include/choose-mode.h
-arch/um/include/frame.h
-arch/um/include/frame_kern.h
-arch/um/include/frame_user.h
-arch/um/include/helper.h
-arch/um/include/hostaudio.h
-arch/um/include/init.h
-arch/um/include/initrd.h
-arch/um/include/irq_kern.h
-arch/um/include/irq_user.h
-arch/um/include/kern.h
-arch/um/include/kern_util.h
-arch/um/include/line.h
-arch/um/include/Makefile
-arch/um/include/mconsole.h
-arch/um/include/mconsole_kern.h
-arch/um/include/mem.h
-arch/um/include/mem_user.h
-arch/um/include/mode.h
-arch/um/include/mode_kern.h
-arch/um/include/net_kern.h
-arch/um/include/net_user.h
-arch/um/include/os.h
-arch/um/include/process.h
-arch/um/include/ptrace_user.h
-arch/um/include/sigcontext.h
-arch/um/include/sigio.h
-arch/um/include/signal_kern.h
-arch/um/include/signal_user.h
-arch/um/include/skas_ptrace.h
-arch/um/include/syscall_user.h
-arch/um/include/sysdep-i386/checksum.h
-arch/um/include/sysdep-i386/frame.h
-arch/um/include/sysdep-i386/frame_kern.h
-arch/um/include/sysdep-i386/frame_user.h
-arch/um/include/sysdep-i386/ptrace.h
-arch/um/include/sysdep-i386/ptrace_user.h
-arch/um/include/sysdep-i386/sigcontext.h
-arch/um/include/sysdep-i386/syscalls.h
-arch/um/include/sysdep-ia64/ptrace.h
-arch/um/include/sysdep-ia64/sigcontext.h
-arch/um/include/sysdep-ia64/syscalls.h
-arch/um/include/sysdep-ppc/ptrace.h
-arch/um/include/sysdep-ppc/sigcontext.h
-arch/um/include/sysdep-ppc/syscalls.h
-arch/um/include/sysrq.h
-arch/um/include/tempfile.h
-arch/um/include/time_user.h
-arch/um/include/tlb.h
-arch/um/include/ubd_user.h
-arch/um/include/umid.h
-arch/um/include/uml_uaccess.h
-arch/um/include/um_mmu.h
-arch/um/include/umn.h
-arch/um/include/um_uaccess.h
-arch/um/include/user.h
-arch/um/include/user_util.h
-arch/um/kernel/checksum.c
-arch/um/kernel/config.c.in
-arch/um/kernel/exec_kern.c
-arch/um/kernel/exitcode.c
-arch/um/kernel/frame.c
-arch/um/kernel/frame_kern.c
-arch/um/kernel/gmon_syms.c
-arch/um/kernel/gprof_syms.c
-arch/um/kernel/helper.c
-arch/um/kernel/initrd_kern.c
-arch/um/kernel/initrd_user.c
-arch/um/kernel/init_task.c
-arch/um/kernel/irq.c
-arch/um/kernel/irq_user.c
-arch/um/kernel/ksyms.c
-arch/um/kernel/Makefile
-arch/um/kernel/mem.c
-arch/um/kernel/mem_user.c
-arch/um/kernel/mprot.h
-arch/um/kernel/process.c
-arch/um/kernel/process_kern.c
-arch/um/kernel/ptrace.c
-arch/um/kernel/reboot.c
-arch/um/kernel/resource.c
-arch/um/kernel/sigio_kern.c
-arch/um/kernel/sigio_user.c
-arch/um/kernel/signal_kern.c
-arch/um/kernel/signal_user.c
-arch/um/kernel/skas/exec_kern.c
-arch/um/kernel/skas/exec_user.c
-arch/um/kernel/skas/include/mmu.h
-arch/um/kernel/skas/include/mode.h
-arch/um/kernel/skas/include/mode_kern.h
-arch/um/kernel/skas/include/proc_mm.h
-arch/um/kernel/skas/include/ptrace-skas.h
-arch/um/kernel/skas/include/skas.h
-arch/um/kernel/skas/include/uaccess.h
-arch/um/kernel/skas/Makefile
-arch/um/kernel/skas/mem.c
-arch/um/kernel/skas/mem_user.c
-arch/um/kernel/skas/mmu.c
-arch/um/kernel/skas/process.c
-arch/um/kernel/skas/process_kern.c
-arch/um/kernel/skas/syscall_kern.c
-arch/um/kernel/skas/syscall_user.c
-arch/um/kernel/skas/sys-i386/Makefile
-arch/um/kernel/skas/sys-i386/sigcontext.c
-arch/um/kernel/skas/time.c
-arch/um/kernel/skas/tlb.c
-arch/um/kernel/skas/trap_user.c
-arch/um/kernel/skas/util/Makefile
-arch/um/kernel/skas/util/mk_ptregs.c
-arch/um/kernel/smp.c
-arch/um/kernel/syscall_kern.c
-arch/um/kernel/sys_call_table.c
-arch/um/kernel/syscall_user.c
-arch/um/kernel/sysrq.c
-arch/um/kernel/tempfile.c
-arch/um/kernel/time.c
-arch/um/kernel/time_kern.c
-arch/um/kernel/tlb.c
-arch/um/kernel/trap_kern.c
-arch/um/kernel/trap_user.c
-arch/um/kernel/tt/exec_kern.c
-arch/um/kernel/tt/exec_user.c
-arch/um/kernel/tt/gdb.c
-arch/um/kernel/tt/gdb_kern.c
-arch/um/kernel/tt/include/debug.h
-arch/um/kernel/tt/include/mmu.h
-arch/um/kernel/tt/include/mode.h
-arch/um/kernel/tt/include/mode_kern.h
-arch/um/kernel/tt/include/ptrace-tt.h
-arch/um/kernel/tt/include/tt.h
-arch/um/kernel/tt/include/uaccess.h
-arch/um/kernel/tt/ksyms.c
-arch/um/kernel/tt/Makefile
-arch/um/kernel/tt/mem.c
-arch/um/kernel/tt/mem_user.c
-arch/um/kernel/tt/process_kern.c
-arch/um/kernel/tt/ptproxy/Makefile
-arch/um/kernel/tt/ptproxy/proxy.c
-arch/um/kernel/tt/ptproxy/ptproxy.h
-arch/um/kernel/tt/ptproxy/ptrace.c
-arch/um/kernel/tt/ptproxy/sysdep.c
-arch/um/kernel/tt/ptproxy/sysdep.h
-arch/um/kernel/tt/ptproxy/wait.c
-arch/um/kernel/tt/ptproxy/wait.h
-arch/um/kernel/tt/syscall_kern.c
-arch/um/kernel/tt/syscall_user.c
-arch/um/kernel/tt/sys-i386/Makefile
-arch/um/kernel/tt/sys-i386/sigcontext.c
-arch/um/kernel/tt/time.c
-arch/um/kernel/tt/tlb.c
-arch/um/kernel/tt/tracer.c
-arch/um/kernel/tt/trap_user.c
-arch/um/kernel/tt/uaccess_user.c
-arch/um/kernel/tt/unmap.c
-arch/um/kernel/tty_log.c
-arch/um/kernel/uaccess_user.c
-arch/um/kernel/um_arch.c
-arch/um/kernel/umid.c
-arch/um/kernel/user_syms.c
-arch/um/kernel/user_util.c
-arch/um/link.ld.in
-arch/um/main.c
-arch/um/Makefile
-arch/um/Makefile-i386
-arch/um/Makefile-ia64
-arch/um/Makefile-os-Linux
-arch/um/Makefile-ppc
-arch/um/Makefile-skas
-arch/um/Makefile-tt
-arch/um/os-Linux/drivers/etap.h
-arch/um/os-Linux/drivers/ethertap_kern.c
-arch/um/os-Linux/drivers/ethertap_user.c
-arch/um/os-Linux/drivers/Makefile
-arch/um/os-Linux/drivers/tuntap.h
-arch/um/os-Linux/drivers/tuntap_kern.c
-arch/um/os-Linux/drivers/tuntap_user.c
-arch/um/os-Linux/file.c
-arch/um/os-Linux/include/file.h
-arch/um/os-Linux/Makefile
-arch/um/os-Linux/process.c
-arch/um/os-Linux/tty.c
-arch/um/sys-i386/bugs.c
-arch/um/sys-i386/checksum.S
-arch/um/sys-i386/fault.c
-arch/um/sys-i386/ksyms.c
-arch/um/sys-i386/ldt.c
-arch/um/sys-i386/Makefile
-arch/um/sys-i386/ptrace.c
-arch/um/sys-i386/ptrace_user.c
-arch/um/sys-i386/sigcontext.c
-arch/um/sys-i386/syscalls.c
-arch/um/sys-i386/sysrq.c
-arch/um/sys-i386/util/Makefile
-arch/um/sys-i386/util/mk_sc.c
-arch/um/sys-i386/util/mk_thread_kern.c
-arch/um/sys-i386/util/mk_thread_user.c
-arch/um/sys-ia64/Makefile
-arch/um/sys-ppc/Makefile
-arch/um/sys-ppc/misc.S
-arch/um/sys-ppc/miscthings.c
-arch/um/sys-ppc/ptrace.c
-arch/um/sys-ppc/ptrace_user.c
-arch/um/sys-ppc/sigcontext.c
-arch/um/sys-ppc/sysrq.c
-arch/um/util/Makefile
-arch/um/util/mk_constants_kern.c
-arch/um/util/mk_constants_user.c
-arch/um/util/mk_task_kern.c
-arch/um/util/mk_task_user.c
-CREDITS
-Documentation/Configure.help
-drivers/char/Makefile
-drivers/char/tty_io.c
-drivers/net/setup.c
-include/asm-i386/hardirq.h
-include/asm-um/a.out.h
-include/asm-um/archparam-i386.h
-include/asm-um/archparam-ppc.h
-include/asm-um/arch-signal-i386.h
-include/asm-um/atomic.h
-include/asm-um/bitops.h
-include/asm-um/boot.h
-include/asm-um/bugs.h
-include/asm-um/byteorder.h
-include/asm-um/cache.h
-include/asm-um/checksum.h
-include/asm-um/cobalt.h
-include/asm-um/current.h
-include/asm-um/delay.h
-include/asm-um/desc.h
-include/asm-um/div64.h
-include/asm-um/dma.h
-include/asm-um/elf.h
-include/asm-um/errno.h
-include/asm-um/fcntl.h
-include/asm-um/fixmap.h
-include/asm-um/floppy.h
-include/asm-um/hardirq.h
-include/asm-um/hdreg.h
-include/asm-um/highmem.h
-include/asm-um/hw_irq.h
-include/asm-um/ide.h
-include/asm-um/init.h
-include/asm-um/ioctl.h
-include/asm-um/ioctls.h
-include/asm-um/io.h
-include/asm-um/ipcbuf.h
-include/asm-um/ipc.h
-include/asm-um/irq.h
-include/asm-um/keyboard.h
-include/asm-um/kmap_types.h
-include/asm-um/linux_logo.h
-include/asm-um/locks.h
-include/asm-um/mca_dma.h
-include/asm-um/mman.h
-include/asm-um/mmu_context.h
-include/asm-um/mmu.h
-include/asm-um/module.h
-include/asm-um/msgbuf.h
-include/asm-um/mtrr.h
-include/asm-um/namei.h
-include/asm-um/page.h
-include/asm-um/page_offset.h
-include/asm-um/param.h
-include/asm-um/pci.h
-include/asm-um/pgalloc.h
-include/asm-um/pgtable.h
-include/asm-um/poll.h
-include/asm-um/posix_types.h
-include/asm-um/processor-generic.h
-include/asm-um/processor-i386.h
-include/asm-um/processor-ppc.h
-include/asm-um/ptrace-generic.h
-include/asm-um/ptrace-i386.h
-include/asm-um/resource.h
-include/asm-um/rwlock.h
-include/asm-um/rwsem.h
-include/asm-um/scatterlist.h
-include/asm-um/segment.h
-include/asm-um/semaphore.h
-include/asm-um/sembuf.h
-include/asm-um/serial.h
-include/asm-um/shmbuf.h
-include/asm-um/shmparam.h
-include/asm-um/sigcontext-generic.h
-include/asm-um/sigcontext-i386.h
-include/asm-um/sigcontext-ppc.h
-include/asm-um/siginfo.h
-include/asm-um/signal.h
-include/asm-um/smp.h
-include/asm-um/smplock.h
-include/asm-um/socket.h
-include/asm-um/sockios.h
-include/asm-um/softirq.h
-include/asm-um/spinlock.h
-include/asm-um/statfs.h
-include/asm-um/stat.h
-include/asm-um/string.h
-include/asm-um/system-generic.h
-include/asm-um/system-i386.h
-include/asm-um/system-ppc.h
-include/asm-um/termbits.h
-include/asm-um/termios.h
-include/asm-um/timex.h
-include/asm-um/tlb.h
-include/asm-um/types.h
-include/asm-um/uaccess.h
-include/asm-um/ucontext.h
-include/asm-um/unaligned.h
-include/asm-um/unistd.h
-include/asm-um/user.h
-include/asm-um/vga.h
-include/asm-um/xor.h
-include/linux/blk.h
-include/linux/fs.h
-include/linux/hostfs_fs_i.h
-include/linux/hppfs_fs_i.h
-include/linux/kernel.h
-include/linux/kernel_stat.h
-include/linux/mm.h
-include/linux/proc_mm.h
-include/linux/tty.h
-init/do_mounts.c
-kernel/panic.c
-MAINTAINERS
-Makefile
-mm/Makefile
-mm/mmap.c
-mm/mprotect.c
-mm/proc_mm.c
-mm/slab.c
diff --git a/lustre/kernel_patches/pc/uml_check_get_page.pc b/lustre/kernel_patches/pc/uml_check_get_page.pc
deleted file mode 100644
index 0e90ce539d2320fac8b65df8a3e8216f10cf7947..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/uml_check_get_page.pc
+++ /dev/null
@@ -1 +0,0 @@
-arch/um/kernel/mem.c
diff --git a/lustre/kernel_patches/pc/uml_no_panic.pc b/lustre/kernel_patches/pc/uml_no_panic.pc
deleted file mode 100644
index 0e90ce539d2320fac8b65df8a3e8216f10cf7947..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/uml_no_panic.pc
+++ /dev/null
@@ -1 +0,0 @@
-arch/um/kernel/mem.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18-chaos65.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.18-18-chaos65.pc
deleted file mode 100644
index adb81005e3649b590099028dfc44213fe5926aef..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent-2.4.18-18-chaos65.pc
+++ /dev/null
@@ -1,12 +0,0 @@
-fs/exec.c
-fs/dcache.c
-fs/namespace.c
-fs/namei.c
-fs/open.c
-fs/stat.c
-fs/proc/base.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/fork.c
-kernel/exit.c
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20-hp.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20-hp.pc
deleted file mode 100644
index f3375a39ce363bce99dd65f83196dd75b1f0118a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent-2.4.20-hp.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-fs/exec.c
-fs/dcache.c
-fs/namespace.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-fs/proc/base.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/fs_struct.h
-kernel/ksyms.c
-kernel/fork.c
-kernel/exit.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc
deleted file mode 100644
index 4be3527075bd49b4f82781506826dcc26effe90e..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent-2.4.20-rh.pc
+++ /dev/null
@@ -1,12 +0,0 @@
-fs/dcache.c
-fs/exec.c
-fs/namei.c
-fs/namespace.c
-fs/open.c
-fs/proc/base.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-kernel/exit.c
-kernel/fork.c
-kernel/ksyms.c
diff --git a/lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc b/lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc
deleted file mode 100644
index f3375a39ce363bce99dd65f83196dd75b1f0118a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent-2.4.20-vanilla.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-fs/exec.c
-fs/dcache.c
-fs/namespace.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-fs/proc/base.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/fs_struct.h
-kernel/ksyms.c
-kernel/fork.c
-kernel/exit.c
diff --git a/lustre/kernel_patches/pc/vfs_intent_2.4.20_chaos.pc b/lustre/kernel_patches/pc/vfs_intent_2.4.20_chaos.pc
deleted file mode 100644
index f3375a39ce363bce99dd65f83196dd75b1f0118a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent_2.4.20_chaos.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-fs/exec.c
-fs/dcache.c
-fs/namespace.c
-fs/namei.c
-fs/nfsd/vfs.c
-fs/open.c
-fs/stat.c
-fs/proc/base.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/fs_struct.h
-kernel/ksyms.c
-kernel/fork.c
-kernel/exit.c
diff --git a/lustre/kernel_patches/pc/vfs_intent_2.5.72_rev1.pc b/lustre/kernel_patches/pc/vfs_intent_2.5.72_rev1.pc
deleted file mode 100644
index 24a460363c1b48fbbb55d0553ab9e7b2272ec38a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent_2.5.72_rev1.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-fs/sysfs/inode.c
-fs/dcache.c
-fs/exec.c
-fs/xattr.c
-fs/namei.c
-fs/namespace.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/namei.h
-kernel/ksyms.c
-net/unix/af_unix.c
-net/sunrpc/rpc_pipe.c
diff --git a/lustre/kernel_patches/pc/vfs_intent_2.6.0-test1.pc b/lustre/kernel_patches/pc/vfs_intent_2.6.0-test1.pc
deleted file mode 100644
index 24a460363c1b48fbbb55d0553ab9e7b2272ec38a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_intent_2.6.0-test1.pc
+++ /dev/null
@@ -1,14 +0,0 @@
-fs/sysfs/inode.c
-fs/dcache.c
-fs/exec.c
-fs/xattr.c
-fs/namei.c
-fs/namespace.c
-fs/open.c
-fs/stat.c
-include/linux/dcache.h
-include/linux/fs.h
-include/linux/namei.h
-kernel/ksyms.c
-net/unix/af_unix.c
-net/sunrpc/rpc_pipe.c
diff --git a/lustre/kernel_patches/pc/vfs_mntcwd_2.5.72_rev1.pc b/lustre/kernel_patches/pc/vfs_mntcwd_2.5.72_rev1.pc
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/lustre/kernel_patches/pc/vfs_nointent_2.5.69_rev1.pc b/lustre/kernel_patches/pc/vfs_nointent_2.5.69_rev1.pc
deleted file mode 100644
index 2849da1e0a58addd1df8aadbcd007e918b57a10a..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_nointent_2.5.69_rev1.pc
+++ /dev/null
@@ -1,4 +0,0 @@
-fs/namei.c
-fs/open.c
-include/linux/fs.h
-fs/exec.c
diff --git a/lustre/kernel_patches/pc/vfs_races_2.5.72_rev1.pc b/lustre/kernel_patches/pc/vfs_races_2.5.72_rev1.pc
deleted file mode 100644
index 95a8dfd560684c4afd60b62cf23f3932a7dc2ec8..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/pc/vfs_races_2.5.72_rev1.pc
+++ /dev/null
@@ -1,3 +0,0 @@
-fs/dcache.c
-fs/namei.c
-include/linux/dcache.h
diff --git a/lustre/kernel_patches/series/bproc-2.4.20-hp-pnnl b/lustre/kernel_patches/series/bproc-2.4.20-hp-pnnl
new file mode 100644
index 0000000000000000000000000000000000000000..51e4937e041c9ba3c351aaf643daa55d72b7afcc
--- /dev/null
+++ b/lustre/kernel_patches/series/bproc-2.4.20-hp-pnnl
@@ -0,0 +1,36 @@
+dev_read_only_hp_2.4.20.patch
+exports_2.4.20-rh-hp.patch
+kmem_cache_validate_hp.patch
+lustre_version.patch
+vfs_intent-2.4.20-hp.patch
+invalidate_show.patch
+export-truncate.patch
+iod-stock-24-exports_hp.patch
+ext-2.4-patch-1.patch
+ext-2.4-patch-2.patch
+ext-2.4-patch-3.patch
+ext-2.4-patch-4.patch
+linux-2.4.20-xattr-0.8.54-hp.patch
+ext3-2.4.20-fixes.patch
+ext3-2.4-ino_t.patch
+ext3-largefile.patch
+ext3-truncate_blocks.patch
+ext3-use-after-free.patch
+ext3-orphan_lock.patch
+ext3-delete_thread-2.4.20.patch
+ext3-noread-2.4.20.patch
+extN-wantedi.patch
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.20.patch
+tcp-zero-copy.patch
+socket-exports-vanilla.patch
+add_page_private.patch
+removepage-2.4.20.patch
+jbd-ctx_switch.patch
+jbd-flushtime.patch
+jbd-get_write_access.patch
+nfs_export_kernel-2.4.20-hp.patch
+ext3-ea-in-inode-2.4.20.patch
+bproc-patch-2.4.20
diff --git a/lustre/kernel_patches/series/chaos-2.4.18 b/lustre/kernel_patches/series/chaos-2.4.18
index 4c32051391a2b9a79d7835f0055b4f2bede4d705..e517d06956654ccc6d95792e476d5a58d0ad299f 100644
--- a/lustre/kernel_patches/series/chaos-2.4.18
+++ b/lustre/kernel_patches/series/chaos-2.4.18
@@ -1,6 +1,5 @@
 dev_read_only.patch
 exports.patch
-kmem_cache_validate.patch
 lustre_version.patch
 vfs_intent-2.4.18-18-chaos65.patch
 invalidate_show.patch
@@ -18,4 +17,19 @@ extN-wantedi.patch
 ext3-san-2.4.20.patch
 extN-2.4.18-ino_sb_fixup.patch
 ext3-map_inode_page_2.4.18.patch
+ext3-error-export.patch
 iopen-2.4.18.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-o_direct-1-2.4.18-chaos.patch
+ext3-no-write-super-chaos.patch
+add_page_private.patch
+ext3-extents-2.4.18-chaos.patch
+ext3-extents-oflag-2.4.18-chaos.patch
+ext3-raw-lookup.patch
+nfs_export_kernel-2.4.18.patch
+ext3-ea-in-inode-2.4.18-chaos.patch
+listman-2.4.18.patch
+ext3-trusted_ea-2.4.18.patch
+gfp_memalloc-2.4.18-chaos.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/series/chaos-2.4.18-pdirops b/lustre/kernel_patches/series/chaos-2.4.18-pdirops
new file mode 100644
index 0000000000000000000000000000000000000000..09b85921f328908a0be1d288c4ce67650c8fd77f
--- /dev/null
+++ b/lustre/kernel_patches/series/chaos-2.4.18-pdirops
@@ -0,0 +1,34 @@
+dev_read_only.patch
+exports.patch
+kmem_cache_validate.patch
+lustre_version.patch
+vfs_intent-2.4.18-18-chaos65.patch
+invalidate_show.patch
+iod-rmap-exports.patch
+export-truncate.patch
+ext3-compat-2.4.18-chaos.patch
+ext3-htree.patch
+linux-2.4.18ea-0.8.26-2.patch
+ext3-2.4-ino_t.patch
+ext3-2.4.18-ino_sb_macro-2.patch
+ext3-orphan_lock.patch
+ext3-delete_thread-2.4.18-2.patch
+extN-misc-fixup.patch
+extN-noread.patch
+extN-wantedi.patch
+ext3-san-2.4.20.patch
+extN-2.4.18-ino_sb_fixup.patch
+ext3-map_inode_page_2.4.18.patch
+ext3-error-export.patch
+iopen-2.4.18-2.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-o_direct-1-2.4.18-chaos.patch
+ext3-no-write-super-chaos.patch
+add_page_private.patch
+dynamic-locks-2.4.18-chaos.patch
+vfs-pdirops-2.4.18-chaos.patch
+ext3-pdirops-2.4.18-chaos.patch
+ext3-extents-2.4.18-chaos-pdirops.patch
+nfs_export_kernel-2.4.18.patch
+ext3-raw-lookup-pdirops.patch
diff --git a/lustre/kernel_patches/series/chaos-2.4.20 b/lustre/kernel_patches/series/chaos-2.4.20
index 0ab55547ba4154dfb8f5a6c01f4cb6db0568b7fb..f7a209fe18c7dff26a19eb42bf2e38337c125978 100644
--- a/lustre/kernel_patches/series/chaos-2.4.20
+++ b/lustre/kernel_patches/series/chaos-2.4.20
@@ -22,3 +22,6 @@ ext3-error-export.patch
 iopen-2.4.20.patch
 tcp_zero_copy_2.4.20_chaos.patch
 gpl_header-chaos-2.4.20.patch
+add_page_private.patch
+jbd-flushtime.patch
+jbd-get_write_access.patch
diff --git a/lustre/kernel_patches/series/hp-pnnl-2.4.20 b/lustre/kernel_patches/series/hp-pnnl-2.4.20
index c2cc2fa6d7989f299ff4c6a564fb09dfc53af7a3..5b6876f17ab2e4cdd4fbd76439cb3d7442dc75f4 100644
--- a/lustre/kernel_patches/series/hp-pnnl-2.4.20
+++ b/lustre/kernel_patches/series/hp-pnnl-2.4.20
@@ -1,6 +1,5 @@
 dev_read_only_hp_2.4.20.patch
 exports_2.4.20-rh-hp.patch
-kmem_cache_validate_hp.patch
 lustre_version.patch
 vfs_intent-2.4.20-hp.patch
 invalidate_show.patch
@@ -25,3 +24,15 @@ ext3-map_inode_page.patch
 ext3-error-export.patch
 iopen-2.4.20.patch
 tcp-zero-copy.patch
+add_page_private.patch
+socket-exports-vanilla.patch
+removepage-2.4.20.patch
+jbd-ctx_switch.patch
+jbd-flushtime.patch
+jbd-get_write_access.patch
+nfs_export_kernel-2.4.20-hp.patch
+ext3-ea-in-inode-2.4.20.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+gfp_memalloc-2.4.22.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/series/kgdb-2.5.73 b/lustre/kernel_patches/series/kgdb-2.5.73
deleted file mode 100644
index 8ce37c38eb3c5b8dcc705516e4d5edae29cc30f3..0000000000000000000000000000000000000000
--- a/lustre/kernel_patches/series/kgdb-2.5.73
+++ /dev/null
@@ -1,19 +0,0 @@
-lkcd-cvs-2.5.69.patch
-lkcd-kernel-changes-2.5.73.patch
-kexec-2.5.73-full.patch
-dump_netdev.patch
-kgdb-ga-2.5.73.patch
-kgdb-use-ggdb-2.5.73.patch
-kgdb-ga-docco-fixes-2.5.73.patch
-lustre_build.patch
-lustre_version.patch
-vfs_intent_2.5.72_rev1.patch
-vfs_nointent_2.5.69_rev1.patch
-vfs_races_2.5.72_rev1.patch
-vfs_mntcwd_2.5.72_rev1.patch
-ext3-san-jdike-2.5.73.patch
-iopen-2.5.73.patch
-export-truncate-2.5.63.patch
-qla2xxx-v8.00.00b1-2.5.73.patch
-ext3-noread-inode.patch
-inode-protection-from-pdflush.patch
diff --git a/lustre/kernel_patches/series/kgdb_2.6.0_test1 b/lustre/kernel_patches/series/kgdb_2.6.0_test1
index dbafd56592b83e6713e87b2ca1ee11cdef46a889..f0613239bd46ea833ad80e8132c4c763cb2936c6 100644
--- a/lustre/kernel_patches/series/kgdb_2.6.0_test1
+++ b/lustre/kernel_patches/series/kgdb_2.6.0_test1
@@ -1,12 +1,13 @@
 2.6.0-test1-mm2.patch
-lkcd-cvs-2.5.69.patch
+lkcd-cvs-2.6.0-test1.patch
 lkcd-kernel-changes-2.6.0-test1.patch
 kexec-2.6.0-full.patch
 dump_netdev.patch
+kgdb_eth.patch
 lustre_build.patch
 lustre_version.patch
 vfs_intent_2.6.0-test1.patch
-vfs_nointent_2.5.69_rev1.patch
+vfs_nointent_2.6.0-test1.patch
 vfs_races_2.5.72_rev1.patch
 vfs_mntcwd_2.5.72_rev1.patch
 ext3-san-jdike-2.5.73.patch
diff --git a/lustre/kernel_patches/series/kgdb_2.6.0_test6 b/lustre/kernel_patches/series/kgdb_2.6.0_test6
index 8c9dfaaba742466a05ebd7c389e5b77e62388094..903a811e40771b418f60d5e961649ee57f72cf22 100644
--- a/lustre/kernel_patches/series/kgdb_2.6.0_test6
+++ b/lustre/kernel_patches/series/kgdb_2.6.0_test6
@@ -1,5 +1,6 @@
 2.6.0-test6-mm4.patch 
-netpoll-core.patch 
+netpoll-core.patch
+netpoll-pcnet32.patch
 kgdb-over-netpoll.patch 
 export-netpoll.patch 
 lkcd-cvs-2.6.0-test6.patch
diff --git a/lustre/kernel_patches/series/rh-2.4.20 b/lustre/kernel_patches/series/rh-2.4.20
index 970061d8e48d357bd4deaa7ded35144b5de66ec4..46052d9e3ad739f4deff90c64d840274839decc0 100644
--- a/lustre/kernel_patches/series/rh-2.4.20
+++ b/lustre/kernel_patches/series/rh-2.4.20
@@ -2,7 +2,6 @@ mcore-2.4.20-8.patch
 dsp.patch
 dev_read_only_2.4.20-rh.patch
 exports_2.4.20-rh-hp.patch
-kmem_cache_validate_2.4.20-rh.patch
 lustre_version.patch
 vfs_intent-2.4.20-rh.patch
 invalidate_show-2.4.20-rh.patch
@@ -22,5 +21,23 @@ ext3-san-2.4.20.patch
 ext3-map_inode_page.patch
 ext3-error-export.patch
 iopen-2.4.20.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-o_direct-1.2.4.20-rh.patch 
+ext3-no-write-super-chaos.patch
+dynamic-locks-2.4.20-rh.patch 
+vfs-pdirops-2.4.20-rh.patch 
+ext3-pdirops-2.4.18-chaos.patch
 tcp_zero_copy_2.4.20_chaos.patch
 gpl_header-chaos-2.4.20.patch
+add_page_private.patch
+jbd-flushtime.patch
+jbd-get_write_access.patch
+nfs_export_kernel-2.4.20-rh.patch
+ext3-ea-in-inode-2.4.20.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+netconsole-2.4.20-rh.patch
+kernel_text_address-2.4.20-rh.patch
+gfp_memalloc-2.4.20-rh.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/series/rh-2.4.22 b/lustre/kernel_patches/series/rh-2.4.22
new file mode 100644
index 0000000000000000000000000000000000000000..a3bd2b9ac62f7851d68f10756c237e9f70d92945
--- /dev/null
+++ b/lustre/kernel_patches/series/rh-2.4.22
@@ -0,0 +1,28 @@
+dev_read_only_2.4.20-rh.patch
+exports_2.4.20-rh-hp.patch
+lustre_version.patch
+vfs_intent-2.4.22-rh.patch
+invalidate_show-2.4.20-rh.patch
+export-truncate.patch
+iod-stock-exports-2.4.22-rh.patch
+ext3-htree-2.4.22-rh.patch
+xattr-0.8.54-2.4.22-rh.patch
+ext3-orphan_lock-2.4.22-rh.patch
+ext3-noread-2.4.20.patch
+ext3_delete_thread_2.4.20_chaos.patch
+extN-wantedi-2.4.22-rh.patch
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.20.patch
+tcp-zero-copy-2.4.22-rh.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+add_page_private.patch
+socket-exports-2.4.22-rh.patch
+nfs_export_kernel-2.4.22-rh.patch
+ext3-ea-in-inode-2.4.22-rh.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+gfp_memalloc-2.4.22.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/series/suse-2.4.19 b/lustre/kernel_patches/series/suse-2.4.19
new file mode 100644
index 0000000000000000000000000000000000000000..4365c39f34a717b1608ed0423f3ec21f3f16a020
--- /dev/null
+++ b/lustre/kernel_patches/series/suse-2.4.19
@@ -0,0 +1,35 @@
+dev_read_only_hp_2.4.20.patch
+exports_2.4.19-suse.patch 
+lustre_version.patch
+vfs_intent-2.4.19-suse.patch 
+invalidate_show.patch
+export-truncate.patch
+iod-stock-24-exports-2.4.19-suse.patch 
+jbd-2.4.18-jcberr.patch
+ext-2.4-patch-1-chaos.patch 
+ext-2.4-patch-2.patch
+ext-2.4-patch-3.patch
+ext-2.4-patch-4.patch
+linux-2.4.20-xattr-0.8.54-hp.patch 
+linux-2.4.19-xattr-0.8.54-suse.patch 
+ext3-2.4-ino_t.patch
+ext3-largefile.patch
+ext3-truncate_blocks.patch
+ext3-use-after-free-suse.patch 
+ext3-orphan_lock-2.4.19-suse.patch 
+ext3-delete_thread-2.4.19-suse.patch 
+ext3-noread-2.4.20.patch
+extN-wantedi-2.4.19-suse.patch 
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.19-suse.patch 
+tcp-zero-copy.patch
+add_page_private.patch
+removepage-2.4.19-suse.patch 
+jbd-ctx_switch.patch
+jbd-flushtime-2.4.19-suse.patch 
+jbd-get_write_access.patch
+ext3-ea-in-inode-2.4.20.patch 
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch 
diff --git a/lustre/kernel_patches/series/suse-2.4.21 b/lustre/kernel_patches/series/suse-2.4.21
new file mode 100644
index 0000000000000000000000000000000000000000..b3c5d0dbfa10a66d0080136c572d9d49de83ef5e
--- /dev/null
+++ b/lustre/kernel_patches/series/suse-2.4.21
@@ -0,0 +1,30 @@
+dev_read_only_2.4.20-rh.patch
+exports_2.4.20-rh-hp.patch
+lustre_version.patch
+vfs_intent-2.4.20-vanilla.patch
+invalidate_show.patch
+export-truncate.patch
+iod-stock-24-exports.patch
+ext3-htree-suse.patch
+linux-2.4.21-xattr-0.8.54-suse.patch
+ext3-orphan_lock-suse.patch 
+ext3-noread-2.4.20.patch
+ext3-delete_thread-suse.patch 
+extN-wantedi.patch
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.20.patch
+tcp-zero-copy-2.4.22-rh.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-no-write-super-chaos.patch
+add_page_private.patch
+socket-exports-vanilla.patch
+nfs_export_kernel-2.4.20.patch
+ext3-raw-lookup.patch
+ext3-ea-in-inode-2.4.20.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+gfp_memalloc-2.4.22.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/series/uml_2.6.0_test3 b/lustre/kernel_patches/series/uml_2.6.0_test3
new file mode 100644
index 0000000000000000000000000000000000000000..3474e045db4c290f4bcbb6d7f0730910a20ba1e1
--- /dev/null
+++ b/lustre/kernel_patches/series/uml_2.6.0_test3
@@ -0,0 +1,15 @@
+uml-patch-2.6.0-test5.patch
+lustre_build.patch
+lustre_version.patch
+vfs_intent_2.6.0-test1.patch
+vfs_nointent_2.6.0-test1.patch
+vfs_races_2.5.72_rev1.patch
+vfs_mntcwd_2.5.72_rev1.patch
+ext3-wantedi-2.6.patch
+ext3-san-jdike-2.5.73.patch
+iopen-2.6.0.patch
+export-truncate-2.5.63.patch
+qla2xxx-v8.00.00b1-2.5.73.patch
+uml-2.6.0-fix.patch
+ext3-map_inode_page-2.6.0.patch
+removepage-2.6.0.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.4.19-pre1 b/lustre/kernel_patches/series/vanilla-2.4.19-pre1
new file mode 100644
index 0000000000000000000000000000000000000000..b6ded90d989d2214a5d7c8bc24166167e5c77170
--- /dev/null
+++ b/lustre/kernel_patches/series/vanilla-2.4.19-pre1
@@ -0,0 +1,45 @@
+dev_read_only_2.4.20.patch
+exports_2.4.19-pre1.patch 
+lustre_version.patch
+vfs_intent-2.4.19-pre1.patch 
+invalidate_show-2.4.19-pre1.patch 
+export-truncate.patch
+iod-stock-24-exports.patch
+ext3-htree-2.4.19-pre1.patch 
+linux-2.4.19-pre1-xattr-0.8.54.patch 
+ext3-2.4.20-fixes.patch
+ext3-2.4-ino_t.patch
+ext3-largefile.patch
+ext3-truncate_blocks.patch
+ext3-unmount_sync.patch
+ext3-use-after-free-2.4.19-pre1.patch 
+ext3-orphan_lock.patch
+ext3-noread-2.4.20.patch
+ext3-delete_thread-2.4.20.patch
+extN-wantedi.patch
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.20.patch
+tcp-zero-copy.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-no-write-super.patch
+add_page_private-2.4.19-pre1.patch 
+socket-exports-vanilla.patch
+removepage-2.4.20.patch
+jbd-ctx_switch.patch
+jbd-flushtime-2.4.19-suse.patch
+jbd-get_write_access.patch
+nfs_export_kernel-2.4.19-pre1.patch 
+ext3-raw-lookup.patch
+ext3-ea-in-inode-2.4.20.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+kernel_text_address-2.4.19-pre1.patch
+jbd-2.4.19-pre1-jcberr.patch 
+seq-private-2.4.19-pre1.patch 
+kdev-2.4.19-pre1.patch 
+resched-2.4.19-pre1.patch
+ext3-xattr-ptr-arith-fix.patch
+gfp_memalloc-2.4.22.patch
diff --git a/lustre/kernel_patches/series/vanilla-2.4.20 b/lustre/kernel_patches/series/vanilla-2.4.20
index d36f90ab3131584b9df5bc82bebcdfc9e52037ed..46f5fd8843d9c511d8d78b82fc4de95b6176f408 100644
--- a/lustre/kernel_patches/series/vanilla-2.4.20
+++ b/lustre/kernel_patches/series/vanilla-2.4.20
@@ -1,7 +1,8 @@
 uml-patch-2.4.20-6.patch
+uml-2.4.20-do_mmap_pgoff-fix.patch
+uml-2.4.20-fixes-1.patch
 dev_read_only_2.4.20.patch
 exports_2.4.20.patch
-kmem_cache_validate_2.4.20.patch
 lustre_version.patch
 vfs_intent-2.4.20-vanilla.patch
 invalidate_show.patch
@@ -29,4 +30,19 @@ ext3-map_inode_page.patch
 ext3-error-export.patch
 iopen-2.4.20.patch
 tcp-zero-copy.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-no-write-super.patch
+add_page_private.patch
 socket-exports-vanilla.patch
+removepage-2.4.20.patch
+jbd-ctx_switch.patch
+jbd-flushtime.patch
+jbd-get_write_access.patch
+nfs_export_kernel-2.4.20.patch
+ext3-raw-lookup.patch
+ext3-ea-in-inode-2.4.20.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+kernel_text_address-2.4.20-vanilla.patch 
+ext3-xattr-ptr-arith-fix.patch 
diff --git a/lustre/kernel_patches/series/vanilla-2.4.22 b/lustre/kernel_patches/series/vanilla-2.4.22
new file mode 100644
index 0000000000000000000000000000000000000000..d3b71237e1485b614d1c87de606011cf8590572d
--- /dev/null
+++ b/lustre/kernel_patches/series/vanilla-2.4.22
@@ -0,0 +1,31 @@
+dev_read_only_2.4.20-rh.patch
+exports_2.4.20-rh-hp.patch
+lustre_version.patch
+vfs_intent-2.4.20-vanilla.patch
+invalidate_show.patch
+export-truncate.patch
+iod-stock-exports-2.4.22.patch 
+ext3-htree-2.4.22-rh.patch
+linux-2.4.22-xattr-0.8.54.patch 
+ext3-orphan_lock-2.4.22-rh.patch
+ext3-noread-2.4.20.patch
+ext3-delete_thread-suse.patch
+extN-wantedi.patch
+ext3-san-2.4.20.patch
+ext3-map_inode_page.patch
+ext3-error-export.patch
+iopen-2.4.20.patch
+tcp-zero-copy-2.4.22-rh.patch
+jbd-dont-account-blocks-twice.patch
+jbd-commit-tricks.patch
+ext3-no-write-super-chaos.patch
+add_page_private.patch
+socket-exports-2.4.22-rh.patch
+nfs_export_kernel-2.4.22.patch 
+ext3-raw-lookup.patch
+ext3-ea-in-inode-2.4.22-rh.patch
+listman-2.4.20.patch
+ext3-trusted_ea-2.4.20.patch
+kernel_text_address-2.4.22-vanilla.patch
+gfp_memalloc-2.4.22.patch
+ext3-xattr-ptr-arith-fix.patch
diff --git a/lustre/kernel_patches/targets/rh-2.4.target b/lustre/kernel_patches/targets/rh-2.4.target
new file mode 100644
index 0000000000000000000000000000000000000000..47585d9b7104e660cff775f813c08c1117ed21ab
--- /dev/null
+++ b/lustre/kernel_patches/targets/rh-2.4.target
@@ -0,0 +1,11 @@
+KERNEL=linux-2.4.20-20.9.tar.gz
+SERIES=rh-2.4.20
+VERSION=2.4.20
+EXTRA_VERSION=20.9
+
+BASE_ARCHS="i386"
+BIGMEM_ARCHS=""
+BOOT_ARCHS=""
+JENSEN_ARCHS=""
+SMP_ARCHS="i686"
+UP_ARCHS=""
diff --git a/lustre/kernel_patches/which_patch b/lustre/kernel_patches/which_patch
index 28e8648a4de60d4e315bb6ab33bf8e96666590e0..f86c76d79ab20cc4d2884a066c0f4fe12e11483d 100644
--- a/lustre/kernel_patches/which_patch
+++ b/lustre/kernel_patches/which_patch
@@ -1,8 +1,8 @@
-SERIES            MEMNONIC                 COMMENT                     ARCH
+SERIES                 MNEMONIC                 COMMENT                     ARCH
 
-chaos-2.4.18      linux-chaos-2.4.18       LLNL 2.4.18 chaos ~65       i386
-hp-pnnl-2.4.20    linux-2.4.20-hp4_pnnl1   same as vanilla but no uml  ia64
-vanilla-2.4.20    linux-2.4.20             patch with uml-2.4.20-6     um
-chaos-2.4.20      linux-chaos-2.4.20       same as rh-2.4.20-8         i386
-rh-2.4.20         linux-rh-2.4.20-8        same as chaos-2.4.20        i386
-kgdb-2.5.73       linux-2.5.73             vanilla 2.5.73 with kgdb    i386
+chaos-2.4.18           linux-chaos-2.4.18       LLNL 2.4.18 chaos ~65       i386
+hp-pnnl-2.4.20         linux-2.4.20-hp4_pnnl1   same as vanilla but no uml  ia64
+vanilla-2.4.20         linux-2.4.20             patch with uml-2.4.20-6     um
+chaos-2.4.20           linux-chaos-2.4.20       same as rh-2.4.20-8         i386
+kgdb-2.5.73            linux-2.5.73             vanilla 2.5.73 with kgdb    i386
+bproc-2.4.20-hp-pnnl   linux-2.4.20-hp4_pnnl9   hp-pnnl + bproc             i386
diff --git a/lustre/ldlm/Makefile.am b/lustre/ldlm/Makefile.am
index b4e4cea0ced8029f34a5c85d5e14e8fdfe53b5e0..768f778f30861366ec6de5d757ae42283a369609 100644
--- a/lustre/ldlm/Makefile.am
+++ b/lustre/ldlm/Makefile.am
@@ -3,20 +3,16 @@
 # This code is issued under the GNU General Public License.
 # See the file COPYING in this distribution
 
-DEFS= 
+#
+# ldlm is built into ptlrpc
+#
 
-LDLMSOURCES= l_lock.c ldlm_lock.c ldlm_resource.c ldlm_lib.c \
-ldlm_extent.c ldlm_request.c ldlm_lockd.c ldlm_internal.h
+DEFS= 
 
 if LIBLUSTRE
 lib_LIBRARIES = libldlm.a
-libldlm_a_SOURCES = $(LDLMSOURCES)
-else
-MODULE = ldlm
-modulefs_DATA = ldlm.o
-EXTRA_PROGRAMS = ldlm
-
-ldlm_SOURCES = $(LDLMSOURCES)
+libldlm_a_SOURCES = l_lock.c ldlm_lock.c ldlm_resource.c ldlm_lib.c \
+  ldlm_plain.c ldlm_extent.c ldlm_request.c ldlm_lockd.c ldlm_internal.h
 endif
 
 include $(top_srcdir)/Rules
diff --git a/lustre/ldlm/Makefile.mk b/lustre/ldlm/Makefile.mk
index 04402a74de5da3971cbff098318d47bf797076a4..650331e8ead8985064fa39da075c9c3578b3b5b1 100644
--- a/lustre/ldlm/Makefile.mk
+++ b/lustre/ldlm/Makefile.mk
@@ -7,4 +7,4 @@ include $(src)/../portals/Kernelenv
 
 obj-y += ldlm.o
 ldlm-objs := l_lock.o ldlm_lock.o ldlm_resource.o ldlm_extent.o ldlm_request.o \
-		ldlm_lockd.o ldlm_lib.o
+		ldlm_lockd.o ldlm_lib.o ldlm_flock.o ldlm_plain.o
diff --git a/lustre/ldlm/l_lock.c b/lustre/ldlm/l_lock.c
index ebf49d6f246056507097c80f893f4b5eee024ddf..262f196236750146e6f79eae20669d7bccf296b2 100644
--- a/lustre/ldlm/l_lock.c
+++ b/lustre/ldlm/l_lock.c
@@ -113,3 +113,26 @@ int l_has_lock(struct lustre_lock *lock)
                 CDEBUG(D_INFO, "lock_depth: %d\n", depth);
         return owner;
 }
+
+#ifdef __KERNEL__
+#include <linux/lustre_version.h>
+void l_check_no_ns_lock(struct ldlm_namespace *ns)
+{
+        static long next_msg;
+
+        if (l_has_lock(&ns->ns_lock) && time_after(jiffies, next_msg)) {
+                CERROR("namespace %s lock held during RPCs; tell phil\n",
+                       ns->ns_name);
+#if (LUSTRE_KERNEL_VERSION >= 30)
+                CERROR(portals_debug_dumpstack());
+#endif
+                next_msg = jiffies + 60 * HZ;
+        }
+}
+
+#else
+void l_check_no_ns_lock(struct ldlm_namespace *ns)
+{
+#warning "FIXME: check lock in user space??"
+}
+#endif /* __KERNEL__ */
diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c
index 08ee7faeb626bc531ebf2111b0d8ce846cca43f4..8e62496c1aeaf26804a7948696dbc25cb4c6bb3d 100644
--- a/lustre/ldlm/ldlm_extent.c
+++ b/lustre/ldlm/ldlm_extent.c
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- *  Copyright (c) 2002 Cluster File Systems, Inc.
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
  *   Author: Peter Braam <braam@clusterfs.com>
  *   Author: Phil Schwan <phil@clusterfs.com>
  *
@@ -30,16 +30,6 @@
 #include <linux/obd_support.h>
 #include <linux/lustre_lib.h>
 
-/* This function will be called to judge if one extent overlaps with another */
-int ldlm_extent_compat(struct ldlm_lock *a, struct ldlm_lock *b)
-{
-        if ((a->l_extent.start <= b->l_extent.end) &&
-            (a->l_extent.end >=  b->l_extent.start))
-                RETURN(0);
-
-        RETURN(1);
-}
-
 #include "ldlm_internal.h"
 
 /* The purpose of this function is to return:
@@ -47,78 +37,171 @@ int ldlm_extent_compat(struct ldlm_lock *a, struct ldlm_lock *b)
  * - containing the requested extent
  * - and not overlapping existing conflicting extents outside the requested one
  *
- * An alternative policy is to not shrink the new extent when conflicts exist.
- *
- * To reconstruct our formulas, take a deep breath. */
-static void policy_internal(struct list_head *queue, struct ldlm_extent *req_ex,
-                            struct ldlm_extent *new_ex, ldlm_mode_t mode)
+ * An alternative policy is to not shrink the new extent when conflicts exist */
+static void
+ldlm_extent_internal_policy(struct list_head *queue, struct ldlm_lock *req,
+                            struct ldlm_extent *new_ex)
 {
         struct list_head *tmp;
+        ldlm_mode_t req_mode = req->l_req_mode;
+        __u64 req_start = req->l_policy_data.l_extent.start;
+        __u64 req_end = req->l_policy_data.l_extent.end;
+        ENTRY;
+
+        if (new_ex->start == req_start && new_ex->end == req_end) {
+                EXIT;
+                return;
+        }
 
         list_for_each(tmp, queue) {
                 struct ldlm_lock *lock;
                 lock = list_entry(tmp, struct ldlm_lock, l_res_link);
 
+                if (req == lock) {
+                        EXIT;
+                        return;
+                }
+
                 /* if lock doesn't overlap new_ex, skip it. */
-                if (lock->l_extent.end < new_ex->start ||
-                    lock->l_extent.start > new_ex->end)
+                if (lock->l_policy_data.l_extent.end < new_ex->start ||
+                    lock->l_policy_data.l_extent.start > new_ex->end)
                         continue;
 
                 /* Locks are compatible, overlap doesn't matter */
-                if (lockmode_compat(lock->l_req_mode, mode))
+                if (lockmode_compat(lock->l_req_mode, req_mode))
                         continue;
 
-                if (lock->l_extent.start < req_ex->start) {
-                        if (lock->l_extent.end == ~0) {
-                                new_ex->start = req_ex->start;
-                                new_ex->end = req_ex->end;
+                if (lock->l_policy_data.l_extent.start < req_start) {
+                        if (lock->l_policy_data.l_extent.end == ~0) {
+                                new_ex->start = req_start;
+                                new_ex->end = req_end;
+                                EXIT;
                                 return;
                         }
-                        new_ex->start = MIN(lock->l_extent.end + 1,
-                                            req_ex->start);
+                        new_ex->start = MIN(lock->l_policy_data.l_extent.end+1,
+                                            req_start);
                 }
 
-                if (lock->l_extent.end > req_ex->end) {
-                        if (lock->l_extent.start == 0) {
-                                new_ex->start = req_ex->start;
-                                new_ex->end = req_ex->end;
+                if (lock->l_policy_data.l_extent.end > req_end) {
+                        if (lock->l_policy_data.l_extent.start == 0) {
+                                new_ex->start = req_start;
+                                new_ex->end = req_end;
+                                EXIT;
                                 return;
                         }
-                        new_ex->end = MAX(lock->l_extent.start - 1,
-                                          req_ex->end);
+                        new_ex->end = MAX(lock->l_policy_data.l_extent.start-1,
+                                          req_end);
                 }
         }
+        EXIT;
+}
+
+/* Determine if the lock is compatible with all locks on the queue. */
+static int
+ldlm_extent_compat_queue(struct list_head *queue, struct ldlm_lock *req,
+                         int send_cbs)
+{
+        struct list_head *tmp;
+        struct ldlm_lock *lock;
+        ldlm_mode_t req_mode = req->l_req_mode;
+        __u64 req_start = req->l_policy_data.l_extent.start;
+        __u64 req_end = req->l_policy_data.l_extent.end;
+        int compat = 1;
+        ENTRY;
+
+        list_for_each(tmp, queue) {
+                lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+                if (req == lock)
+                        RETURN(compat);
+
+                /* locks are compatible, overlap doesn't matter */
+                if (lockmode_compat(lock->l_req_mode, req_mode))
+                        continue;
+
+                /* if lock doesn't overlap skip it */
+                if (lock->l_policy_data.l_extent.end < req_start ||
+                    lock->l_policy_data.l_extent.start > req_end)
+                        continue;
+
+                if (!send_cbs)
+                        RETURN(0);
+
+                compat = 0;
+                if (lock->l_blocking_ast)
+                        ldlm_add_ast_work_item(lock, req, NULL, 0);
+        }
+
+        RETURN(compat);
 }
 
-/* apply the internal policy by walking all the lists */
-int ldlm_extent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
-                       void *req_cookie, ldlm_mode_t mode, int flags,
-                       void *data)
+/* If first_enq is 0 (ie, called from ldlm_reprocess_queue):
+  *   - blocking ASTs have already been sent
+  *   - the caller has already initialized req->lr_tmp
+  *   - must call this function with the ns lock held
+  *
+  * If first_enq is 1 (ie, called from ldlm_lock_enqueue):
+  *   - blocking ASTs have not been sent
+  *   - the caller has NOT initialized req->lr_tmp, so we must
+  *   - must call this function with the ns lock held once */
+int ldlm_process_extent_lock(struct ldlm_lock *lock, int *flags, int first_enq,
+                             ldlm_error_t *err)
 {
-        struct ldlm_lock *lock = *lockp;
         struct ldlm_resource *res = lock->l_resource;
-        struct ldlm_extent *req_ex = req_cookie;
-        struct ldlm_extent new_ex;
-        new_ex.start = 0;
-        new_ex.end = ~0;
-
-        if (!res)
-                LBUG();
-
-        l_lock(&ns->ns_lock);
-        policy_internal(&res->lr_granted, req_ex, &new_ex, mode);
-        policy_internal(&res->lr_converting, req_ex, &new_ex, mode);
-        policy_internal(&res->lr_waiting, req_ex, &new_ex, mode);
-        l_unlock(&ns->ns_lock);
-
-        memcpy(&lock->l_extent, &new_ex, sizeof(new_ex));
-
-        LDLM_DEBUG(lock, "requested extent ["LPU64"->"LPU64"], new extent ["
-                   LPU64"->"LPU64"]",
-                   req_ex->start, req_ex->end, new_ex.start, new_ex.end);
-
-        if (new_ex.end != req_ex->end || new_ex.start != req_ex->start)
-                return ELDLM_LOCK_CHANGED;
-        else 
-                return 0;
+        struct ldlm_extent new_ex = {0, ~0};
+        struct list_head rpc_list = LIST_HEAD_INIT(rpc_list);
+        int rc;
+        ENTRY;
+
+        LASSERT(list_empty(&res->lr_converting));
+
+        if (!first_enq) {
+                LASSERT(res->lr_tmp != NULL);
+                rc = ldlm_extent_compat_queue(&res->lr_granted, lock, 0);
+                if (!rc)
+                        RETURN(LDLM_ITER_STOP);
+                rc = ldlm_extent_compat_queue(&res->lr_waiting, lock, 0);
+                if (!rc)
+                        RETURN(LDLM_ITER_STOP);
+
+                ldlm_resource_unlink_lock(lock);
+                ldlm_grant_lock(lock, NULL, 0, 1);
+                RETURN(LDLM_ITER_CONTINUE);
+        }
+
+        /* In order to determine the largest possible extent we can
+         * grant, we need to scan all of the queues. */
+        ldlm_extent_internal_policy(&res->lr_granted, lock, &new_ex);
+        ldlm_extent_internal_policy(&res->lr_waiting, lock, &new_ex);
+
+        if (new_ex.start != lock->l_policy_data.l_extent.start ||
+            new_ex.end != lock->l_policy_data.l_extent.end)  {
+                *flags |= LDLM_FL_LOCK_CHANGED;
+                lock->l_policy_data.l_extent.start = new_ex.start;
+                lock->l_policy_data.l_extent.end = new_ex.end;
+        }
+
+ restart:
+        LASSERT(res->lr_tmp == NULL);
+        res->lr_tmp = &rpc_list;
+        rc = ldlm_extent_compat_queue(&res->lr_granted, lock, 1);
+        rc += ldlm_extent_compat_queue(&res->lr_waiting, lock, 1);
+        res->lr_tmp = NULL;
+
+        if (rc != 2) {
+                /* If either of the compat_queue()s returned 0, then we
+                 * have ASTs to send and must go onto the waiting list. */
+                ldlm_resource_unlink_lock(lock);
+                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
+                l_unlock(&res->lr_namespace->ns_lock);
+                rc = ldlm_run_ast_work(res->lr_namespace, &rpc_list);
+                l_lock(&res->lr_namespace->ns_lock);
+                if (rc == -ERESTART)
+                        GOTO(restart, -ERESTART);
+                *flags |= LDLM_FL_BLOCK_GRANTED;
+        } else {
+                ldlm_resource_unlink_lock(lock);
+                ldlm_grant_lock(lock, NULL, 0, 0);
+        }
+        RETURN(0);
 }
diff --git a/lustre/ldlm/ldlm_flock.c b/lustre/ldlm/ldlm_flock.c
new file mode 100644
index 0000000000000000000000000000000000000000..57c09c5cf14750ad91aa8b0abc45cc94d56891df
--- /dev/null
+++ b/lustre/ldlm/ldlm_flock.c
@@ -0,0 +1,518 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#ifdef __KERNEL__
+#include <linux/lustre_dlm.h>
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_lib.h>
+#include <portals/list.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include "ldlm_internal.h"
+
+#define l_flock_waitq   l_lru
+
+static struct list_head ldlm_flock_waitq = LIST_HEAD_INIT(ldlm_flock_waitq);
+
+/**
+ * list_for_remaining_safe - iterate over the remaining entries in a list
+ *              and safeguard against removal of a list entry.
+ * @pos:        the &struct list_head to use as a loop counter. pos MUST
+ *              have been initialized prior to using it in this macro.
+ * @n:          another &struct list_head to use as temporary storage
+ * @head:       the head for your list.
+ */
+#define list_for_remaining_safe(pos, n, head) \
+        for (n = pos->next; pos != (head); pos = n, n = pos->next)
+
+static inline int
+ldlm_same_flock_owner(struct ldlm_lock *lock, struct ldlm_lock *new)
+{
+        return((new->l_policy_data.l_flock.pid ==
+                lock->l_policy_data.l_flock.pid) &&
+               (new->l_export == lock->l_export));
+}
+
+static inline int
+ldlm_flocks_overlap(struct ldlm_lock *lock, struct ldlm_lock *new)
+{
+        return((new->l_policy_data.l_flock.start <=
+                lock->l_policy_data.l_flock.end) &&
+               (new->l_policy_data.l_flock.end >=
+                lock->l_policy_data.l_flock.start));
+}
+
+static inline void
+ldlm_flock_destroy(struct ldlm_lock *lock, ldlm_mode_t mode, int flags)
+{
+        ENTRY;
+
+        LDLM_DEBUG(lock, "ldlm_flock_destroy(mode: %d, flags: 0x%x)",
+                   mode, flags);
+
+        list_del_init(&lock->l_res_link);
+        if (flags == LDLM_FL_WAIT_NOREPROC) {
+                /* client side - set a flag to prevent sending a CANCEL */
+                lock->l_flags |= LDLM_FL_LOCAL_ONLY | LDLM_FL_CBPENDING;
+                ldlm_lock_decref_internal(lock, mode);
+        }
+
+        ldlm_lock_destroy(lock);
+        EXIT;
+}
+
+static int
+ldlm_flock_deadlock(struct ldlm_lock *req, struct ldlm_lock *blocking_lock)
+{
+        struct obd_export *req_export = req->l_export;
+        struct obd_export *blocking_export = blocking_lock->l_export;
+        pid_t req_pid = req->l_policy_data.l_flock.pid;
+        pid_t blocking_pid = blocking_lock->l_policy_data.l_flock.pid;
+        struct ldlm_lock *lock;
+
+restart:
+        list_for_each_entry(lock, &ldlm_flock_waitq, l_flock_waitq) {
+                if ((lock->l_policy_data.l_flock.pid != blocking_pid) ||
+                    (lock->l_export != blocking_export))
+                        continue;
+
+                blocking_pid = lock->l_policy_data.l_flock.blocking_pid;
+                blocking_export = (struct obd_export *)(long)
+                        lock->l_policy_data.l_flock.blocking_export;
+                if (blocking_pid == req_pid && blocking_export == req_export)
+                        return 1;
+
+                goto restart;
+        }
+
+        return 0;
+}
+
+int
+ldlm_process_flock_lock(struct ldlm_lock *req, int *flags, int first_enq,
+                        ldlm_error_t *err)
+{
+        struct ldlm_resource *res = req->l_resource;
+        struct ldlm_namespace *ns = res->lr_namespace;
+        struct list_head *tmp;
+        struct list_head *ownlocks = NULL;
+        struct ldlm_lock *lock = NULL;
+        struct ldlm_lock *new = req;
+        struct ldlm_lock *new2 = NULL;
+        ldlm_mode_t mode = req->l_req_mode;
+        int added = (mode == LCK_NL);
+        int overlaps = 0;
+        ENTRY;
+
+        CDEBUG(D_DLMTRACE, "flags %#x pid %u mode %u start "LPU64" end "LPU64
+               "\n", *flags, new->l_policy_data.l_flock.pid, mode,
+               req->l_policy_data.l_flock.start,
+               req->l_policy_data.l_flock.end);
+
+        *err = ELDLM_OK;
+
+        /* No blocking ASTs are sent for Posix file & record locks */
+        req->l_blocking_ast = NULL;
+
+        if ((*flags == LDLM_FL_WAIT_NOREPROC) || (mode == LCK_NL)) {
+                /* This loop determines where this processes locks start
+                 * in the resource lr_granted list. */
+                list_for_each(tmp, &res->lr_granted) {
+                        lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+                        if (ldlm_same_flock_owner(lock, req)) {
+                                ownlocks = tmp;
+                                break;
+                        }
+                }
+        } else {
+                /* This loop determines if there are existing locks
+                 * that conflict with the new lock request. */
+                list_for_each(tmp, &res->lr_granted) {
+                        lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+                        if (ldlm_same_flock_owner(lock, req)) {
+                                if (!ownlocks)
+                                        ownlocks = tmp;
+                                continue;
+                        }
+
+                        /* locks are compatible, overlap doesn't matter */
+                        if (lockmode_compat(lock->l_granted_mode, mode))
+                                continue;
+                        
+                        if (!ldlm_flocks_overlap(lock, req))
+                                continue;
+
+                        if (!first_enq)
+                                RETURN(LDLM_ITER_CONTINUE);
+
+                        if (*flags & LDLM_FL_BLOCK_NOWAIT) {
+                                ldlm_flock_destroy(req, mode, *flags);
+                                *err = -EAGAIN;
+                                RETURN(LDLM_ITER_STOP);
+                        }
+
+                        if (*flags & LDLM_FL_TEST_LOCK) {
+                                ldlm_flock_destroy(req, mode, *flags);
+                                req->l_req_mode = lock->l_granted_mode;
+                                req->l_policy_data.l_flock.pid =
+                                        lock->l_policy_data.l_flock.pid;
+                                req->l_policy_data.l_flock.start =
+                                        lock->l_policy_data.l_flock.start;
+                                req->l_policy_data.l_flock.end =
+                                        lock->l_policy_data.l_flock.end;
+                                *flags |= LDLM_FL_LOCK_CHANGED;
+                                RETURN(LDLM_ITER_STOP);
+                        }
+
+                        if (ldlm_flock_deadlock(req, lock)) {
+                                ldlm_flock_destroy(req, mode, *flags);
+                                *err = -EDEADLK;
+                                RETURN(LDLM_ITER_STOP);
+                        }
+
+                        req->l_policy_data.l_flock.blocking_pid =
+                                lock->l_policy_data.l_flock.pid;
+                        req->l_policy_data.l_flock.blocking_export =
+                                (long)(void *)lock->l_export;
+
+                        LASSERT(list_empty(&req->l_flock_waitq));
+                        list_add_tail(&req->l_flock_waitq, &ldlm_flock_waitq);
+
+                        ldlm_resource_add_lock(res, &res->lr_waiting, req);
+                        *flags |= LDLM_FL_BLOCK_GRANTED;
+                        RETURN(LDLM_ITER_STOP);
+                }
+        }
+
+        if (*flags & LDLM_FL_TEST_LOCK) {
+                ldlm_flock_destroy(req, mode, *flags);
+                req->l_req_mode = LCK_NL;
+                *flags |= LDLM_FL_LOCK_CHANGED;
+                RETURN(LDLM_ITER_STOP);
+        }
+
+        /* Scan the locks owned by this process that overlap this request.
+         * We may have to merge or split existing locks. */
+
+        if (!ownlocks)
+                ownlocks = &res->lr_granted;
+
+        list_for_remaining_safe(ownlocks, tmp, &res->lr_granted) {
+                lock = list_entry(ownlocks, struct ldlm_lock, l_res_link);
+
+                if (!ldlm_same_flock_owner(lock, new))
+                        break;
+
+                if (lock->l_granted_mode == mode) {
+                        /* If the modes are the same then we need to process
+                         * locks that overlap OR adjoin the new lock. The extra
+                         * logic condition is necessary to deal with arithmetic
+                         * overflow and underflow. */
+                        if ((new->l_policy_data.l_flock.start >
+                             (lock->l_policy_data.l_flock.end + 1))
+                            && (lock->l_policy_data.l_flock.end != ~0))
+                                continue;
+
+                        if ((new->l_policy_data.l_flock.end <
+                             (lock->l_policy_data.l_flock.start - 1))
+                            && (lock->l_policy_data.l_flock.start != 0))
+                                break;
+
+                        if (new->l_policy_data.l_flock.start <
+                            lock->l_policy_data.l_flock.start) {
+                                lock->l_policy_data.l_flock.start =
+                                        new->l_policy_data.l_flock.start;
+                        } else {
+                                new->l_policy_data.l_flock.start =
+                                        lock->l_policy_data.l_flock.start;
+                        }
+
+                        if (new->l_policy_data.l_flock.end >
+                            lock->l_policy_data.l_flock.end) {
+                                lock->l_policy_data.l_flock.end =
+                                        new->l_policy_data.l_flock.end;
+                        } else {
+                                new->l_policy_data.l_flock.end =
+                                        lock->l_policy_data.l_flock.end;
+                        }
+
+                        if (added) {
+                                ldlm_flock_destroy(lock, mode, *flags);
+                        } else {
+                                new = lock;
+                                added = 1;
+                        }
+                        continue;
+                }
+
+                if (new->l_policy_data.l_flock.start >
+                    lock->l_policy_data.l_flock.end)
+                        continue;
+
+                if (new->l_policy_data.l_flock.end <
+                    lock->l_policy_data.l_flock.start)
+                        break;
+
+                ++overlaps;
+
+                if (new->l_policy_data.l_flock.start <=
+                    lock->l_policy_data.l_flock.start) {
+                        if (new->l_policy_data.l_flock.end <
+                            lock->l_policy_data.l_flock.end) {
+                                lock->l_policy_data.l_flock.start =
+                                        new->l_policy_data.l_flock.end + 1;
+                                break;
+                        }
+                        ldlm_flock_destroy(lock, lock->l_req_mode, *flags);
+                        continue;
+                }
+                if (new->l_policy_data.l_flock.end >=
+                    lock->l_policy_data.l_flock.end) {
+                        lock->l_policy_data.l_flock.end =
+                                new->l_policy_data.l_flock.start - 1;
+                        continue;
+                }
+
+                /* split the existing lock into two locks */
+
+                /* if this is an F_UNLCK operation then we could avoid
+                 * allocating a new lock and use the req lock passed in
+                 * with the request but this would complicate the reply
+                 * processing since updates to req get reflected in the
+                 * reply. The client side replays the lock request so
+                 * it must see the original lock data in the reply. */
+
+                /* XXX - if ldlm_lock_new() can sleep we should
+                 * release the ns_lock, allocate the new lock,
+                 * and restart processing this lock. */
+                new2 = ldlm_lock_create(ns, NULL, res->lr_name, LDLM_FLOCK,
+                                        lock->l_granted_mode, NULL, NULL, NULL);
+                if (!new2) {
+                        ldlm_flock_destroy(req, lock->l_granted_mode, *flags);
+                        *err = -ENOLCK;
+                        RETURN(LDLM_ITER_STOP);
+                }
+
+                new2->l_granted_mode = lock->l_granted_mode;
+                new2->l_policy_data.l_flock.pid =
+                        new->l_policy_data.l_flock.pid;
+                new2->l_policy_data.l_flock.start =
+                        lock->l_policy_data.l_flock.start;
+                new2->l_policy_data.l_flock.end =
+                        new->l_policy_data.l_flock.start - 1;
+                lock->l_policy_data.l_flock.start =
+                        new->l_policy_data.l_flock.end + 1;
+                new2->l_conn_export = lock->l_conn_export;
+                if (lock->l_export != NULL) {
+                        new2->l_export = class_export_get(lock->l_export);
+                        list_add(&new2->l_export_chain,
+                                 &new2->l_export->exp_ldlm_data.led_held_locks);
+                }
+                if (*flags == LDLM_FL_WAIT_NOREPROC)
+                        ldlm_lock_addref_internal(new2, lock->l_granted_mode);
+
+                /* insert new2 at lock */
+                ldlm_resource_add_lock(res, ownlocks, new2);
+                LDLM_LOCK_PUT(new2);
+                break;
+        }
+
+        /* Add req to the granted queue before calling ldlm_reprocess_all(). */
+        if (!added) {
+                req->l_granted_mode = req->l_req_mode;
+                list_del_init(&req->l_res_link);
+                /* insert new lock before ownlocks in list. */
+                ldlm_resource_add_lock(res, ownlocks, req);
+        }
+
+        if (*flags != LDLM_FL_WAIT_NOREPROC) {
+                if (first_enq) {
+                        /* If this is an unlock, reprocess the waitq and
+                         * send completions ASTs for locks that can now be 
+                         * granted. The only problem with doing this
+                         * reprocessing here is that the completion ASTs for
+                         * newly granted locks will be sent before the unlock
+                         * completion is sent. It shouldn't be an issue. Also
+                         * note that ldlm_process_flock_lock() will recurse,
+                         * but only once because first_enq will be false from
+                         * ldlm_reprocess_queue. */
+                        if ((mode == LCK_NL) && overlaps) {
+                                struct list_head rpc_list
+                                                    = LIST_HEAD_INIT(rpc_list);
+                                int rc;
+restart:
+                                res->lr_tmp = &rpc_list;
+                                ldlm_reprocess_queue(res, &res->lr_waiting);
+                                res->lr_tmp = NULL;
+
+                                l_unlock(&ns->ns_lock);
+                                rc = ldlm_run_ast_work(res->lr_namespace,
+                                                       &rpc_list);
+                                l_lock(&ns->ns_lock);
+                                if (rc == -ERESTART)
+                                        GOTO(restart, -ERESTART);
+                       }
+                } else {
+                        LASSERT(req->l_completion_ast);
+                        ldlm_add_ast_work_item(req, NULL, NULL, 0);
+                }
+        }
+
+        /* In case we're reprocessing the requested lock we can't destroy
+         * it until after calling ldlm_ast_work_item() above so that lawi()
+         * can bump the reference count on req. Otherwise req could be freed
+         * before the completion AST can be sent.  */
+        if (added)
+                ldlm_flock_destroy(req, mode, *flags);
+
+        ldlm_resource_dump(res);
+        RETURN(LDLM_ITER_CONTINUE);
+}
+
+struct ldlm_flock_wait_data {
+        struct ldlm_lock *fwd_lock;
+        int               fwd_generation;
+};
+
+static void
+ldlm_flock_interrupted_wait(void *data)
+{
+        struct ldlm_lock *lock;
+        struct lustre_handle lockh;
+        int rc;
+        ENTRY;
+
+        lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
+        ldlm_lock_decref_internal(lock, lock->l_req_mode);
+        ldlm_lock2handle(lock, &lockh);
+        rc = ldlm_cli_cancel(&lockh);
+        CDEBUG(D_DLMTRACE, "ldlm_cli_cancel: %d\n", rc);
+        EXIT;
+}
+
+int
+ldlm_flock_completion_ast(struct ldlm_lock *lock, int flags, void *data)
+{
+        struct ldlm_namespace *ns;
+        struct file_lock *getlk = lock->l_ast_data;
+        struct ldlm_flock_wait_data fwd;
+        unsigned long irqflags;
+        struct obd_device *obd;
+        struct obd_import *imp = NULL;
+        ldlm_error_t err;
+        int rc = 0;
+        struct l_wait_info lwi;
+        ENTRY;
+
+        CDEBUG(D_DLMTRACE, "flags: 0x%x data: %p getlk: %p\n",
+               flags, data, getlk);
+
+        LASSERT(flags != LDLM_FL_WAIT_NOREPROC);
+
+        if (flags == 0) {
+                wake_up(&lock->l_waitq);
+                RETURN(0);
+        }
+
+        if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
+                       LDLM_FL_BLOCK_CONV)))
+                goto  granted;
+
+        LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, "
+                   "sleeping");
+
+        ldlm_lock_dump(D_OTHER, lock, 0);
+
+        fwd.fwd_lock = lock;
+        obd = class_exp2obd(lock->l_conn_export);
+
+        /* if this is a local lock, then there is no import */
+        if (obd != NULL)
+                imp = obd->u.cli.cl_import;
+
+        if (imp != NULL) {
+                spin_lock_irqsave(&imp->imp_lock, irqflags);
+                fwd.fwd_generation = imp->imp_generation;
+                spin_unlock_irqrestore(&imp->imp_lock, irqflags);
+        }
+
+        lwi = LWI_TIMEOUT_INTR(0,NULL,ldlm_flock_interrupted_wait,&fwd);
+
+        /* Go to sleep until the lock is granted. */
+        rc = l_wait_event(lock->l_waitq,
+                          ((lock->l_req_mode == lock->l_granted_mode) ||
+                           lock->l_destroyed), &lwi);
+
+        if (rc) {
+                LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
+                           rc);
+                RETURN(rc);
+        }
+
+        LASSERT(!(lock->l_destroyed));
+
+granted:
+
+        LDLM_DEBUG(lock, "client-side enqueue waking up");
+        ns = lock->l_resource->lr_namespace;
+        l_lock(&ns->ns_lock);
+
+        /* take data off of deadlock detection waitq. */
+        list_del_init(&lock->l_flock_waitq);
+
+        /* ldlm_lock_enqueue() has already placed lock on the granted list. */
+        list_del_init(&lock->l_res_link);
+
+        if (flags & LDLM_FL_TEST_LOCK) {
+                /* fcntl(F_GETLK) request */
+                /* The old mode was saved in getlk->fl_type so that if the mode
+                 * in the lock changes we can decref the approprate refcount. */
+                ldlm_flock_destroy(lock, getlk->fl_type, LDLM_FL_WAIT_NOREPROC);
+                switch (lock->l_granted_mode) {
+                case LCK_PR:
+                        getlk->fl_type = F_RDLCK;
+                        break;
+                case LCK_PW:
+                        getlk->fl_type = F_WRLCK;
+                        break;
+                default:
+                        getlk->fl_type = F_UNLCK;
+                }
+                getlk->fl_pid = lock->l_policy_data.l_flock.pid;
+                getlk->fl_start = lock->l_policy_data.l_flock.start;
+                getlk->fl_end = lock->l_policy_data.l_flock.end;
+        } else {
+                /* We need to reprocess the lock to do merges or splits
+                 * with existing locks owne by this process. */
+                flags = LDLM_FL_WAIT_NOREPROC;
+                ldlm_process_flock_lock(lock, &flags, 1, &err);
+        }
+        l_unlock(&ns->ns_lock);
+        RETURN(0);
+}
diff --git a/lustre/ldlm/ldlm_internal.h b/lustre/ldlm/ldlm_internal.h
index 5aca55fdec46f8c6a16e8b5a77445d27f4c91652..8dc312ea4ef1c74aae56fe78de70f417c99a15da 100644
--- a/lustre/ldlm/ldlm_internal.h
+++ b/lustre/ldlm/ldlm_internal.h
@@ -11,3 +11,41 @@ ldlm_lock_create(struct ldlm_namespace *ns,
                  ldlm_completion_callback, void *data);
 ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *, struct ldlm_lock **,
                                void *cookie, int cookie_len, int *flags);
+void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode);
+void ldlm_lock_decref_internal(struct ldlm_lock *, __u32 mode);
+void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
+                            void *data, int datalen);
+int ldlm_reprocess_queue(struct ldlm_resource *res, struct list_head *queue);
+int ldlm_run_ast_work(struct ldlm_namespace *, struct list_head *rpc_list);
+
+typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, int *flags,
+                                      int first_enq, ldlm_error_t *err);
+
+/* ldlm_plain.c */
+int ldlm_process_plain_lock(struct ldlm_lock *lock, int *flags, int first_enq,
+                            ldlm_error_t *err);
+
+/* ldlm_extent.c */
+int ldlm_process_extent_lock(struct ldlm_lock *lock, int *flags, int first_enq,
+                             ldlm_error_t *err);
+
+/* ldlm_flock.c */
+int ldlm_process_flock_lock(struct ldlm_lock *lock, int *flags, int first_enq,
+                            ldlm_error_t *err);
+
+/* l_lock.c */
+void l_check_no_ns_lock(struct ldlm_namespace *ns);
+
+extern struct proc_dir_entry *ldlm_svc_proc_dir;
+
+struct ldlm_state {
+        struct ptlrpc_service *ldlm_cb_service;
+        struct ptlrpc_service *ldlm_cancel_service;
+        struct ptlrpc_client *ldlm_client;
+        struct ptlrpc_connection *ldlm_server_conn;
+        struct ldlm_bl_pool *ldlm_bl_pool;
+};
+
+int __init ldlm_init(void);
+void __exit ldlm_exit(void);
+
diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c
index 1b04a74a54d3ddbe8b10ee3c8dba03c20394fc80..2d2196a4b5dbab7bd2e8d0880c6bb94042b9757d 100644
--- a/lustre/ldlm/ldlm_lib.c
+++ b/lustre/ldlm/ldlm_lib.c
@@ -19,7 +19,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_LDLM
 
 #ifdef __KERNEL__
@@ -27,29 +29,203 @@
 #else
 # include <liblustre.h>
 #endif
-#include <linux/obd_ost.h>
+#include <linux/obd.h>
+#include <linux/obd_ost.h> /* for LUSTRE_OSC_NAME */
+#include <linux/lustre_mds.h> /* for LUSTRE_MDC_NAME */
+#include <linux/lustre_mgmt.h>
 #include <linux/lustre_dlm.h>
-#include <linux/lustre_mds.h>
 #include <linux/lustre_net.h>
 
-int client_import_connect(struct lustre_handle *dlm_handle,
+int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
+{
+        struct ptlrpc_connection *conn;
+        struct lustre_cfg* lcfg = buf;
+        struct client_obd *cli = &obddev->u.cli;
+        struct obd_import *imp;
+        struct obd_uuid server_uuid;
+        int rq_portal, rp_portal, connect_op;
+        char *name = obddev->obd_type->typ_name;
+        char *mgmt_name = NULL;
+        int rc = 0;
+        struct obd_device *mgmt_obd;
+        mgmtcli_register_for_events_t register_f;
+        ENTRY;
+
+        /* In a more perfect world, we would hang a ptlrpc_client off of
+         * obd_type and just use the values from there. */
+        if (!strcmp(name, LUSTRE_OSC_NAME)) {
+                rq_portal = OST_REQUEST_PORTAL;
+                rp_portal = OSC_REPLY_PORTAL;
+                connect_op = OST_CONNECT;
+        } else if (!strcmp(name, LUSTRE_MDC_NAME)) {
+                rq_portal = MDS_REQUEST_PORTAL;
+                rp_portal = MDC_REPLY_PORTAL;
+                connect_op = MDS_CONNECT;
+        } else if (!strcmp(name, LUSTRE_MGMTCLI_NAME)) {
+                rq_portal = MGMT_REQUEST_PORTAL;
+                rp_portal = MGMT_REPLY_PORTAL;
+                connect_op = MGMT_CONNECT;
+        } else {
+                CERROR("unknown client OBD type \"%s\", can't setup\n",
+                       name);
+                RETURN(-EINVAL);
+        }
+
+        if (lcfg->lcfg_inllen1 < 1) {
+                CERROR("requires a TARGET UUID\n");
+                RETURN(-EINVAL);
+        }
+
+        if (lcfg->lcfg_inllen1 > 37) {
+                CERROR("client UUID must be less than 38 characters\n");
+                RETURN(-EINVAL);
+        }
+
+        if (lcfg->lcfg_inllen2 < 1) {
+                CERROR("setup requires a SERVER UUID\n");
+                RETURN(-EINVAL);
+        }
+
+        if (lcfg->lcfg_inllen2 > 37) {
+                CERROR("target UUID must be less than 38 characters\n");
+                RETURN(-EINVAL);
+        }
+
+        sema_init(&cli->cl_sem, 1);
+        cli->cl_conn_count = 0;
+        memcpy(server_uuid.uuid, lcfg->lcfg_inlbuf2, MIN(lcfg->lcfg_inllen2,
+                                                        sizeof(server_uuid)));
+
+        init_MUTEX(&cli->cl_dirty_sem);
+        cli->cl_dirty = 0;
+        cli->cl_dirty_granted = 0;
+        cli->cl_dirty_max = 64*1024*1024; /* some default */
+        cli->cl_ost_can_grant = 1;
+        INIT_LIST_HEAD(&cli->cl_cache_waiters);
+        INIT_LIST_HEAD(&cli->cl_loi_ready_list);
+        spin_lock_init(&cli->cl_loi_list_lock);
+        cli->cl_brw_in_flight = 0;
+        spin_lock_init(&cli->cl_read_rpc_hist.oh_lock);
+        spin_lock_init(&cli->cl_write_rpc_hist.oh_lock);
+        spin_lock_init(&cli->cl_read_page_hist.oh_lock);
+        spin_lock_init(&cli->cl_write_page_hist.oh_lock);
+        cli->cl_max_pages_per_rpc = PTL_MD_MAX_PAGES;
+        cli->cl_max_rpcs_in_flight = 8;
+
+        ldlm_get_ref();
+        if (rc) {
+                CERROR("ldlm_get_ref failed: %d\n", rc);
+                GOTO(err, rc);
+        }
+
+        conn = ptlrpc_uuid_to_connection(&server_uuid);
+        if (conn == NULL)
+                GOTO(err_ldlm, rc = -ENOENT);
+
+        ptlrpc_init_client(rq_portal, rp_portal, name,
+                           &obddev->obd_ldlm_client);
+
+        imp = class_new_import();
+        if (imp == NULL) {
+                ptlrpc_put_connection(conn);
+                GOTO(err_ldlm, rc = -ENOENT);
+        }
+        imp->imp_connection = conn;
+        imp->imp_client = &obddev->obd_ldlm_client;
+        imp->imp_obd = obddev;
+        imp->imp_connect_op = connect_op;
+        imp->imp_generation = 0;
+        INIT_LIST_HEAD(&imp->imp_pinger_chain);
+        memcpy(imp->imp_target_uuid.uuid, lcfg->lcfg_inlbuf1,
+              lcfg->lcfg_inllen1);
+        class_import_put(imp);
+
+        cli->cl_import = imp;
+        cli->cl_max_mds_easize = sizeof(struct lov_mds_md);
+        cli->cl_max_mds_cookiesize = sizeof(struct llog_cookie);
+        cli->cl_sandev = to_kdev_t(0);
+
+        if (lcfg->lcfg_inllen3 != 0) {
+                if (!strcmp(lcfg->lcfg_inlbuf3, "inactive")) {
+                        CDEBUG(D_HA, "marking %s %s->%s as inactive\n",
+                               name, obddev->obd_name,
+                               imp->imp_target_uuid.uuid);
+                        imp->imp_invalid = 1;
+
+                        if (lcfg->lcfg_inllen4 != 0)
+                                mgmt_name = lcfg->lcfg_inlbuf4;
+                } else {
+                        mgmt_name = lcfg->lcfg_inlbuf3;
+                }
+        }
+
+        if (mgmt_name != NULL) {
+                /* Register with management client if we need to. */
+                CDEBUG(D_HA, "%s registering with %s for events about %s\n",
+                       obddev->obd_name, mgmt_name, server_uuid.uuid);
+
+                mgmt_obd = class_name2obd(mgmt_name);
+                if (!mgmt_obd) {
+                        CERROR("can't find mgmtcli %s to register\n",
+                               mgmt_name);
+                        GOTO(err_import, rc = -ENOSYS);
+                }
+
+                register_f = inter_module_get("mgmtcli_register_for_events");
+                if (!register_f) {
+                        CERROR("can't i_m_g mgmtcli_register_for_events\n");
+                        GOTO(err_import, rc = -ENOSYS);
+                }
+
+                rc = register_f(mgmt_obd, obddev, &imp->imp_target_uuid);
+                inter_module_put("mgmtcli_register_for_events");
+
+                if (!rc)
+                        cli->cl_mgmtcli_obd = mgmt_obd;
+        }
+
+        RETURN(rc);
+
+err_import:
+        class_destroy_import(imp);
+err_ldlm:
+        ldlm_put_ref(0);
+err:
+        RETURN(rc);
+
+}
+
+int client_obd_cleanup(struct obd_device *obddev, int flags)
+{
+        struct client_obd *cli = &obddev->u.cli;
+
+        if (!cli->cl_import)
+                RETURN(-EINVAL);
+        if (cli->cl_mgmtcli_obd) {
+                mgmtcli_deregister_for_events_t dereg_f;
+
+                dereg_f = inter_module_get("mgmtcli_deregister_for_events");
+                dereg_f(cli->cl_mgmtcli_obd, obddev);
+                inter_module_put("mgmtcli_deregister_for_events");
+        }
+        class_destroy_import(cli->cl_import);
+        cli->cl_import = NULL;
+
+        ldlm_put_ref(flags & OBD_OPT_FORCE);
+
+        RETURN(0);
+}
+
+int client_connect_import(struct lustre_handle *dlm_handle,
                           struct obd_device *obd,
                           struct obd_uuid *cluuid)
 {
         struct client_obd *cli = &obd->u.cli;
         struct obd_import *imp = cli->cl_import;
         struct obd_export *exp;
-        struct ptlrpc_request *request;
-        /* XXX maybe this is a good time to create a connect struct? */
-        int rc, size[] = {sizeof(imp->imp_target_uuid),
-                          sizeof(obd->obd_uuid),
-                          sizeof(*dlm_handle)};
-        char *tmp[] = {imp->imp_target_uuid.uuid,
-                       obd->obd_uuid.uuid,
-                       (char *)dlm_handle};
-        int msg_flags;
-
+        int rc;
         ENTRY;
+
         down(&cli->cl_sem);
         rc = class_connect(dlm_handle, obd, cluuid);
         if (rc)
@@ -58,6 +234,7 @@ int client_import_connect(struct lustre_handle *dlm_handle,
         cli->cl_conn_count++;
         if (cli->cl_conn_count > 1)
                 GOTO(out_sem, rc);
+        exp = class_conn2export(dlm_handle);
 
         if (obd->obd_namespace != NULL)
                 CERROR("already have namespace!\n");
@@ -66,78 +243,56 @@ int client_import_connect(struct lustre_handle *dlm_handle,
         if (obd->obd_namespace == NULL)
                 GOTO(out_disco, rc = -ENOMEM);
 
-        request = ptlrpc_prep_req(imp, imp->imp_connect_op, 3, size, tmp);
-        if (!request)
-                GOTO(out_ldlm, rc = -ENOMEM);
-
-        request->rq_level = LUSTRE_CONN_NEW;
-        request->rq_replen = lustre_msg_size(0, NULL);
-
-        lustre_msg_add_op_flags(request->rq_reqmsg, MSG_CONNECT_PEER);
-
         imp->imp_dlm_handle = *dlm_handle;
+        imp->imp_state = LUSTRE_IMP_DISCON;
 
-        imp->imp_level = LUSTRE_CONN_CON;
-        rc = ptlrpc_queue_wait(request);
-        if (rc) {
-                class_disconnect(dlm_handle, 0);
-                GOTO(out_req, rc);
+        rc = ptlrpc_connect_import(imp);
+        if (rc != 0) {
+                LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
+                GOTO(out_ldlm, rc);
         }
 
-        exp = class_conn2export(dlm_handle);
-        exp->exp_connection = ptlrpc_connection_addref(request->rq_connection);
-        class_export_put(exp);
+        LASSERT (imp->imp_state == LUSTRE_IMP_FULL);
+
+        exp->exp_connection = ptlrpc_connection_addref(imp->imp_connection);
 
-        msg_flags = lustre_msg_get_op_flags(request->rq_repmsg);
-        if (msg_flags & MSG_CONNECT_REPLAYABLE) {
-                imp->imp_replayable = 1;
+        if (imp->imp_replayable) {
                 CDEBUG(D_HA, "connected to replayable target: %s\n",
                        imp->imp_target_uuid.uuid);
                 ptlrpc_pinger_add_import(imp);
         }
-        imp->imp_level = LUSTRE_CONN_FULL;
-        imp->imp_remote_handle = request->rq_repmsg->handle;
+
         CDEBUG(D_HA, "local import: %p, remote handle: "LPX64"\n", imp,
                imp->imp_remote_handle.cookie);
 
         EXIT;
-out_req:
-        ptlrpc_req_finished(request);
+
         if (rc) {
 out_ldlm:
-                ldlm_namespace_free(obd->obd_namespace);
+                ldlm_namespace_free(obd->obd_namespace, 0);
                 obd->obd_namespace = NULL;
 out_disco:
                 cli->cl_conn_count--;
-                class_disconnect(dlm_handle, 0);
+                class_disconnect(exp, 0);
+        } else {
+                class_export_put(exp);
         }
 out_sem:
         up(&cli->cl_sem);
         return rc;
 }
 
-int client_import_disconnect(struct lustre_handle *dlm_handle, int failover)
+int client_disconnect_export(struct obd_export *exp, int failover)
 {
-        struct obd_device *obd = class_conn2obd(dlm_handle);
+        struct obd_device *obd = class_exp2obd(exp);
         struct client_obd *cli = &obd->u.cli;
         struct obd_import *imp = cli->cl_import;
-        struct ptlrpc_request *request = NULL;
-        int rc = 0, err, rq_opc;
+        int rc = 0, err;
         ENTRY;
 
         if (!obd) {
-                CERROR("invalid connection for disconnect: cookie "LPX64"\n",
-                       dlm_handle ? dlm_handle->cookie : -1UL);
-                RETURN(-EINVAL);
-        }
-
-        switch (imp->imp_connect_op) {
-        case OST_CONNECT: rq_opc = OST_DISCONNECT; break;
-        case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break;
-        case MGMT_CONNECT:rq_opc = MGMT_DISCONNECT;break;
-        default:
-                CERROR("don't know how to disconnect from %s (connect_op %d)\n",
-                       imp->imp_target_uuid.uuid, imp->imp_connect_op);
+                CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
+                       exp, exp ? exp->exp_handle.h_cookie : -1);
                 RETURN(-EINVAL);
         }
 
@@ -152,37 +307,30 @@ int client_import_disconnect(struct lustre_handle *dlm_handle, int failover)
         if (cli->cl_conn_count)
                 GOTO(out_no_disconnect, rc = 0);
 
+        /* Some non-replayable imports (MDS's OSCs) are pinged, so just
+         * delete it regardless.  (It's safe to delete an import that was
+         * never added.) */
+        (void)ptlrpc_pinger_del_import(imp);
+
         if (obd->obd_namespace != NULL) {
                 /* obd_no_recov == local only */
                 ldlm_cli_cancel_unused(obd->obd_namespace, NULL,
                                        obd->obd_no_recov, NULL);
-                ldlm_namespace_free(obd->obd_namespace);
+                ldlm_namespace_free(obd->obd_namespace, obd->obd_no_recov);
                 obd->obd_namespace = NULL;
         }
 
         /* Yeah, obd_no_recov also (mainly) means "forced shutdown". */
-        if (obd->obd_no_recov) {
+        if (obd->obd_no_recov)
                 ptlrpc_set_import_active(imp, 0);
-        } else {
-                request = ptlrpc_prep_req(imp, rq_opc, 0, NULL, NULL);
-                if (!request)
-                        GOTO(out_req, rc = -ENOMEM);
+        else
+                rc = ptlrpc_disconnect_import(imp);
 
-                request->rq_replen = lustre_msg_size(0, NULL);
-
-                rc = ptlrpc_queue_wait(request);
-                if (rc)
-                        GOTO(out_req, rc);
-        }
-        if (imp->imp_replayable)
-                ptlrpc_pinger_del_import(imp);
+        imp->imp_state = LUSTRE_IMP_NEW;
 
         EXIT;
- out_req:
-        if (request)
-                ptlrpc_req_finished(request);
  out_no_disconnect:
-        err = class_disconnect(dlm_handle, 0);
+        err = class_disconnect(exp, 0);
         if (!rc && err)
                 rc = err;
  out_sem:
@@ -199,7 +347,7 @@ int target_handle_reconnect(struct lustre_handle *conn, struct obd_export *exp,
 {
         if (exp->exp_connection) {
                 struct lustre_handle *hdl;
-                hdl = &exp->exp_ldlm_data.led_import->imp_remote_handle;
+                hdl = &exp->exp_imp_reverse->imp_remote_handle;
                 /* Might be a re-connect after a partition. */
                 if (!memcmp(&conn->cookie, &hdl->cookie, sizeof conn->cookie)) {
                         CERROR("%s reconnecting\n", cluuid->uuid);
@@ -211,12 +359,7 @@ int target_handle_reconnect(struct lustre_handle *conn, struct obd_export *exp,
                                LPX64")\n", cluuid->uuid,
                                exp->exp_connection->c_remote_uuid.uuid,
                                hdl->cookie, conn->cookie);
-                        /* XXX disconnect them here? */
                         memset(conn, 0, sizeof *conn);
-                        /* This is a little scary, but right now we build this
-                         * file separately into each server module, so I won't
-                         * go _immediately_ to hell.
-                         */
                         RETURN(-EALREADY);
                 }
         }
@@ -232,7 +375,7 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
 {
         struct obd_device *target;
         struct obd_export *export = NULL;
-        struct obd_import *dlmimp;
+        struct obd_import *revimp;
         struct lustre_handle conn;
         struct obd_uuid tgtuuid;
         struct obd_uuid cluuid;
@@ -251,6 +394,10 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
 
         obd_str2uuid (&tgtuuid, str);
         target = class_uuid2obd(&tgtuuid);
+        if (!target) {
+                target = class_name2obd(str);
+        }
+
         if (!target || target->obd_stopping || !target->obd_set_up) {
                 CERROR("UUID '%s' is not available for connect\n", str);
                 GOTO(out, rc = -ENODEV);
@@ -281,12 +428,12 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
 
         memcpy(&conn, tmp, sizeof conn);
 
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc)
                 GOTO(out, rc);
 
         /* lctl gets a backstage, all-access pass. */
-        if (obd_uuid_equals(&cluuid, &lctl_fake_uuid))
+        if (obd_uuid_equals(&cluuid, &target->obd_uuid))
                 goto dont_check_exports;
 
         spin_lock(&target->obd_dev_lock);
@@ -302,8 +449,13 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
                 export = NULL;
         }
         /* If we found an export, we already unlocked. */
-        if (!export)
+        if (!export) {
                 spin_unlock(&target->obd_dev_lock);
+        } else if (req->rq_reqmsg->conn_cnt == 1) {
+                CERROR("%s reconnected with 1 conn_cnt; cookies not random?\n",
+                       cluuid.uuid);
+                GOTO(out, rc = -EALREADY);
+        }
 
         /* Tell the client if we're in recovery. */
         /* If this is the first client, start the recovery timer */
@@ -319,7 +471,9 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
         if (export == NULL) {
                 if (target->obd_recovering) {
                         CERROR("denying connection for new client %s: "
-                               "in recovery\n", cluuid.uuid);
+                               "%d clients in recovery for %lds\n", cluuid.uuid,
+                               target->obd_recoverable_clients,
+                               (target->obd_recovery_timer.expires-jiffies)/HZ);
                         rc = -EBUSY;
                 } else {
  dont_check_exports:
@@ -333,6 +487,11 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
         if (rc && rc != EALREADY)
                 GOTO(out, rc);
 
+        /* XXX track this all the time? */
+        if (target->obd_recovering) {
+                target->obd_connected_clients++;
+        }
+
         req->rq_repmsg->handle = conn;
 
         /* If the client and the server are the same node, we will already
@@ -357,6 +516,9 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
                                                        &remote_uuid);
         req->rq_connection = ptlrpc_connection_addref(export->exp_connection);
 
+        LASSERT(export->exp_conn_cnt < req->rq_reqmsg->conn_cnt);
+        export->exp_conn_cnt = req->rq_reqmsg->conn_cnt;
+
         if (rc == EALREADY) {
                 /* We indicate the reconnection in a flag, not an error code. */
                 lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_RECONNECT);
@@ -366,16 +528,16 @@ int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler)
         memcpy(&conn, lustre_msg_buf(req->rq_reqmsg, 2, sizeof conn),
                sizeof conn);
 
-        if (export->exp_ldlm_data.led_import != NULL)
-                class_destroy_import(export->exp_ldlm_data.led_import);
-        dlmimp = export->exp_ldlm_data.led_import = class_new_import();
-        dlmimp->imp_connection = ptlrpc_connection_addref(req->rq_connection);
-        dlmimp->imp_client = &export->exp_obd->obd_ldlm_client;
-        dlmimp->imp_remote_handle = conn;
-        dlmimp->imp_obd = target;
-        dlmimp->imp_dlm_fake = 1;
-        dlmimp->imp_level = LUSTRE_CONN_FULL;
-        class_import_put(dlmimp);
+        if (export->exp_imp_reverse != NULL)
+                class_destroy_import(export->exp_imp_reverse);
+        revimp = export->exp_imp_reverse = class_new_import();
+        revimp->imp_connection = ptlrpc_connection_addref(req->rq_connection);
+        revimp->imp_client = &export->exp_obd->obd_ldlm_client;
+        revimp->imp_remote_handle = conn;
+        revimp->imp_obd = target;
+        revimp->imp_dlm_fake = 1;
+        revimp->imp_state = LUSTRE_IMP_FULL;
+        class_import_put(revimp);
 out:
         if (rc)
                 req->rq_status = rc;
@@ -384,25 +546,30 @@ out:
 
 int target_handle_disconnect(struct ptlrpc_request *req)
 {
-        struct lustre_handle *conn = &req->rq_reqmsg->handle;
-        struct obd_import *dlmimp;
         int rc;
         ENTRY;
 
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc)
                 RETURN(rc);
 
-        req->rq_status = obd_disconnect(conn, 0);
-
-        dlmimp = req->rq_export->exp_ldlm_data.led_import;
-        class_destroy_import(dlmimp);
-
-        class_export_put(req->rq_export);
+        req->rq_status = obd_disconnect(req->rq_export, 0);
         req->rq_export = NULL;
         RETURN(0);
 }
 
+void target_destroy_export(struct obd_export *exp)
+{
+        /* exports created from last_rcvd data, and "fake"
+           exports created by lctl don't have an import */
+        if (exp->exp_imp_reverse != NULL)
+                class_destroy_import(exp->exp_imp_reverse);
+
+        /* We cancel locks at disconnect time, but this will catch any locks
+         * granted in a race with recovery-induced disconnect. */
+        ldlm_cancel_locks_for_export(exp);
+}
+
 /*
  * Recovery functions
  */
@@ -439,8 +606,7 @@ static void abort_recovery_queue(struct obd_device *obd)
                 DEBUG_REQ(D_ERROR, req, "aborted:");
                 req->rq_status = -ENOTCONN;
                 req->rq_type = PTL_RPC_MSG_ERR;
-                rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen,
-                                     &req->rq_repmsg);
+                rc = lustre_pack_reply(req, 0, NULL, NULL);
                 if (rc == 0) {
                         ptlrpc_reply(req);
                 } else {
@@ -457,6 +623,7 @@ static void abort_recovery_queue(struct obd_device *obd)
 void target_abort_recovery(void *data)
 {
         struct obd_device *obd = data;
+        int rc;
 
         CERROR("disconnecting clients and aborting recovery\n");
         spin_lock_bh(&obd->obd_processing_task_lock);
@@ -467,11 +634,22 @@ void target_abort_recovery(void *data)
         }
 
         obd->obd_recovering = obd->obd_abort_recovery = 0;
-        obd->obd_recoverable_clients = 0;
+
         wake_up(&obd->obd_next_transno_waitq);
         target_cancel_recovery_timer(obd);
         spin_unlock_bh(&obd->obd_processing_task_lock);
+
         class_disconnect_exports(obd, 0);
+
+        /* when recovery was abort, cleanup orphans for mds */
+        if (OBT(obd) && OBP(obd, postrecov)) {
+                rc = OBP(obd, postrecov)(obd);
+                if (rc >= 0)
+                        CWARN("Cleanup %d orphans after recovery was aborted\n", rc);
+                else
+                        CERROR("postrecov failed %d\n", rc);
+        }
+
         abort_delayed_replies(obd);
         abort_recovery_queue(obd);
         ptlrpc_run_recovery_over_upcall(obd);
@@ -496,7 +674,8 @@ static void reset_recovery_timer(struct obd_device *obd)
 
         if (!recovering)
                 return;
-        CERROR("timer will expire in %d seconds\n", OBD_RECOVERY_TIMEOUT / HZ);
+        CDEBUG(D_HA, "timer will expire in %u seconds\n",
+               OBD_RECOVERY_TIMEOUT / HZ);
         mod_timer(&obd->obd_recovery_timer, jiffies + OBD_RECOVERY_TIMEOUT);
 }
 
@@ -509,7 +688,8 @@ void target_start_recovery_timer(struct obd_device *obd, svc_handler_t handler)
                 spin_unlock_bh(&obd->obd_processing_task_lock);
                 return;
         }
-        CERROR("%s: starting recovery timer\n", obd->obd_name);
+        CWARN("%s: starting recovery timer (%us)\n", obd->obd_name,
+               OBD_RECOVERY_TIMEOUT / HZ);
         obd->obd_recovery_handler = handler;
         obd->obd_recovery_timer.function = target_recovery_expired;
         obd->obd_recovery_timer.data = (unsigned long)obd;
@@ -522,17 +702,38 @@ void target_start_recovery_timer(struct obd_device *obd, svc_handler_t handler)
 static int check_for_next_transno(struct obd_device *obd)
 {
         struct ptlrpc_request *req;
-        int wake_up;
+        int wake_up = 0, connected, completed, queue_len, max;
+        __u64 next_transno, req_transno;
 
+        spin_lock_bh(&obd->obd_processing_task_lock);
         req = list_entry(obd->obd_recovery_queue.next,
                          struct ptlrpc_request, rq_list);
-        LASSERT(req->rq_reqmsg->transno >= obd->obd_next_recovery_transno);
-
-        wake_up = req->rq_reqmsg->transno == obd->obd_next_recovery_transno ||
-                (obd->obd_recovering) == 0;
-        CDEBUG(D_HA, "check_for_next_transno: "LPD64" vs "LPD64", %d == %d\n",
-               req->rq_reqmsg->transno, obd->obd_next_recovery_transno,
-               obd->obd_recovering, wake_up);
+        max = obd->obd_max_recoverable_clients;
+        req_transno = req->rq_reqmsg->transno;
+        connected = obd->obd_connected_clients;
+        completed = max - obd->obd_recoverable_clients;
+        queue_len = obd->obd_requests_queued_for_recovery;
+        next_transno = obd->obd_next_recovery_transno;
+
+        if (obd->obd_abort_recovery) {
+                CDEBUG(D_HA, "waking for aborted recovery\n");
+                wake_up = 1;
+        } else if (!obd->obd_recovering) {
+                CDEBUG(D_HA, "waking for completed recovery (?)\n");
+                wake_up = 1;
+        } else if (req_transno == next_transno) {
+                CDEBUG(D_HA, "waking for next ("LPD64")\n", next_transno);
+                wake_up = 1;
+        } else if (queue_len + completed == max) {
+                CDEBUG(D_ERROR,
+                       "waking for skipped transno (skip: "LPD64
+                       ", ql: %d, comp: %d, conn: %d, next: "LPD64")\n",
+                       next_transno, queue_len, completed, max, req_transno);
+                obd->obd_next_recovery_transno = req_transno;
+                wake_up = 1;
+        }
+        spin_unlock_bh(&obd->obd_processing_task_lock);
+        LASSERT(req->rq_reqmsg->transno >= next_transno);
         return wake_up;
 }
 
@@ -567,10 +768,12 @@ static void process_recovery_queue(struct obd_device *obd)
                         continue;
                 }
                 list_del_init(&req->rq_list);
+                obd->obd_requests_queued_for_recovery--;
                 spin_unlock_bh(&obd->obd_processing_task_lock);
 
-                DEBUG_REQ(D_ERROR, req, "processing: ");
+                DEBUG_REQ(D_HA, req, "processing: ");
                 (void)obd->obd_recovery_handler(req);
+                obd->obd_replayed_requests++;
                 reset_recovery_timer(obd);
                 /* bug 1580: decide how to properly sync() in recovery */
                 //mds_fsync_super(mds->mds_sb);
@@ -659,12 +862,13 @@ int target_queue_recovery_request(struct ptlrpc_request *req,
                 list_add_tail(&req->rq_list, &obd->obd_recovery_queue);
         }
 
+        obd->obd_requests_queued_for_recovery++;
+
         if (obd->obd_processing_task != 0) {
                 /* Someone else is processing this queue, we'll leave it to
                  * them.
                  */
-                if (transno == obd->obd_next_recovery_transno)
-                        wake_up(&obd->obd_next_transno_waitq);
+                wake_up(&obd->obd_next_transno_waitq);
                 spin_unlock_bh(&obd->obd_processing_task_lock);
                 return 0;
         }
@@ -690,16 +894,17 @@ int target_queue_final_reply(struct ptlrpc_request *req, int rc)
         struct ptlrpc_request *saved_req;
         struct lustre_msg *reqmsg;
         int recovery_done = 0;
+        int rc2;
 
         if (rc) {
                 /* Just like ptlrpc_error, but without the sending. */
-                lustre_pack_msg(0, NULL, NULL, &req->rq_replen,
-                                &req->rq_repmsg);
+                rc = lustre_pack_reply(req, 0, NULL, NULL);
+                LASSERT(rc == 0); /* XXX handle this */
                 req->rq_type = PTL_RPC_MSG_ERR;
         }
 
         LASSERT(list_empty(&req->rq_list));
-        /* XXX just like the request-dup code in queue_recovery_request */
+        /* XXX a bit like the request-dup code in queue_recovery_request */
         OBD_ALLOC(saved_req, sizeof *saved_req);
         if (!saved_req)
                 LBUG();
@@ -720,9 +925,20 @@ int target_queue_final_reply(struct ptlrpc_request *req, int rc)
         if (recovery_done) {
                 struct list_head *tmp, *n;
                 ldlm_reprocess_all_ns(req->rq_export->exp_obd->obd_namespace);
-                CERROR("%s: all clients recovered, sending delayed replies\n",
+                CWARN("%s: all clients recovered, sending delayed replies\n",
                        obd->obd_name);
                 obd->obd_recovering = 0;
+
+                /* when recovering finished, cleanup orphans for mds */
+                if (OBT(obd) && OBP(obd, postrecov)) {
+                        rc2 = OBP(obd, postrecov)(obd);
+                        if (rc2 >= 0)
+                                CWARN("%s: all clients recovered, %d MDS orphans "
+                                       "deleted\n", obd->obd_name, rc2);
+                        else
+                                CERROR("postrecov failed %d\n", rc2);
+                }
+
                 list_for_each_safe(tmp, n, &obd->obd_delayed_reply_queue) {
                         req = list_entry(tmp, struct ptlrpc_request, rq_list);
                         DEBUG_REQ(D_ERROR, req, "delayed:");
@@ -735,6 +951,7 @@ int target_queue_final_reply(struct ptlrpc_request *req, int rc)
         } else {
                 CERROR("%s: %d recoverable clients remain\n",
                        obd->obd_name, obd->obd_recoverable_clients);
+                wake_up(&obd->obd_next_transno_waitq);
         }
 
         return 1;
@@ -809,9 +1026,16 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
         wait_queue_t commit_wait;
         struct obd_device *obd =
                 req->rq_export ? req->rq_export->exp_obd : NULL;
-        struct obd_export *exp =
-                (req->rq_export && req->rq_ack_locks[0].mode) ?
-                req->rq_export : NULL;
+        struct obd_export *exp = NULL;
+
+        if (req->rq_export) {
+                for (i = 0; i < REQ_MAX_ACK_LOCKS; i++) {
+                        if (req->rq_ack_locks[i].mode) {
+                                exp = req->rq_export;
+                                break;
+                        }
+                }
+        }
 
         if (exp) {
                 exp->exp_outstanding_reply = req;
@@ -834,7 +1058,7 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
         } else {
                 obd_fail_loc |= OBD_FAIL_ONCE | OBD_FAILED;
                 DEBUG_REQ(D_ERROR, req, "dropping reply");
-                if (!exp && req->rq_repmsg) {
+                if (req->rq_repmsg) {
                         OBD_FREE(req->rq_repmsg, req->rq_replen);
                         req->rq_repmsg = NULL;
                 }
@@ -879,14 +1103,33 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
 
         exp->exp_outstanding_reply = NULL;
 
-        for (ack_lock = req->rq_ack_locks, i = 0; i < 4; i++, ack_lock++) {
+        for (ack_lock = req->rq_ack_locks, i = 0;
+             i < REQ_MAX_ACK_LOCKS; i++, ack_lock++) {
                 if (!ack_lock->mode)
-                        break;
+                        continue;
                 ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);
         }
 }
 
 int target_handle_ping(struct ptlrpc_request *req)
 {
-        return lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        return lustre_pack_reply(req, 0, NULL, NULL);
+}
+
+void *ldlm_put_lock_into_req(struct ptlrpc_request *req,
+                                struct lustre_handle *lock, int mode)
+{
+        int i;
+
+        for (i = 0; i < REQ_MAX_ACK_LOCKS; i++) {
+                if (req->rq_ack_locks[i].mode)
+                        continue;
+                memcpy(&req->rq_ack_locks[i].lock, lock, sizeof(*lock));
+                req->rq_ack_locks[i].mode = mode;
+                return &req->rq_ack_locks[i];
+        }
+        CERROR("no space for lock in struct ptlrpc_request\n");
+        LBUG();
+        return NULL;
 }
+
diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c
index a1b5faad8755e6f158ef50a47b67a1a9da146dc4..3d52c4077b4ab36e6e438b5eba532072c2edb112 100644
--- a/lustre/ldlm/ldlm_lock.c
+++ b/lustre/ldlm/ldlm_lock.c
@@ -50,9 +50,9 @@ char *ldlm_lockname[] = {
 char *ldlm_typename[] = {
         [LDLM_PLAIN] "PLN",
         [LDLM_EXTENT] "EXT",
+        [LDLM_FLOCK] "FLK",
 };
 
-#ifdef __KERNEL__
 char *ldlm_it2str(int it)
 {
         switch (it) {
@@ -77,37 +77,20 @@ char *ldlm_it2str(int it)
                 return "UNKNOWN";
         }
 }
-#endif
 
 extern kmem_cache_t *ldlm_lock_slab;
 struct lustre_lock ldlm_handle_lock;
 
-static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b);
-
-static ldlm_res_compat ldlm_res_compat_table[] = {
-        [LDLM_PLAIN] ldlm_plain_compat,
-        [LDLM_EXTENT] ldlm_extent_compat,
+static ldlm_processing_policy ldlm_processing_policy_table[] = {
+        [LDLM_PLAIN] ldlm_process_plain_lock,
+        [LDLM_EXTENT] ldlm_process_extent_lock,
+#ifdef __KERNEL__
+        [LDLM_FLOCK] ldlm_process_flock_lock,
+#endif
 };
 
 static ldlm_res_policy ldlm_intent_policy_func;
 
-static int ldlm_plain_policy(struct ldlm_namespace *ns, struct ldlm_lock **lock,
-                             void *req_cookie, ldlm_mode_t mode, int flags,
-                             void *data)
-{
-        if ((flags & LDLM_FL_HAS_INTENT) && ldlm_intent_policy_func) {
-                return ldlm_intent_policy_func(ns, lock, req_cookie, mode,
-                                               flags, data);
-        }
-
-        return ELDLM_OK;
-}
-
-static ldlm_res_policy ldlm_res_policy_table[] = {
-        [LDLM_PLAIN] ldlm_plain_policy,
-        [LDLM_EXTENT] ldlm_extent_policy,
-};
-
 void ldlm_register_intent(ldlm_res_policy arg)
 {
         ldlm_intent_policy_func = arg;
@@ -137,10 +120,11 @@ struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock)
 
 void ldlm_lock_put(struct ldlm_lock *lock)
 {
-        struct ldlm_namespace *ns = lock->l_resource->lr_namespace;
         ENTRY;
 
         if (atomic_dec_and_test(&lock->l_refc)) {
+                struct ldlm_namespace *ns = lock->l_resource->lr_namespace;
+
                 l_lock(&ns->ns_lock);
                 LDLM_DEBUG(lock, "final lock_put on destroyed lock, freeing");
                 LASSERT(lock->l_destroyed);
@@ -384,23 +368,18 @@ struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *ns,
         return retval;
 }
 
-static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b)
-{
-        return lockmode_compat(a->l_req_mode, b->l_req_mode);
-}
-
 void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc)
 {
         ldlm_res2desc(lock->l_resource, &desc->l_resource);
         desc->l_req_mode = lock->l_req_mode;
         desc->l_granted_mode = lock->l_granted_mode;
-        memcpy(&desc->l_extent, &lock->l_extent, sizeof(desc->l_extent));
+        memcpy(&desc->l_policy_data, &lock->l_policy_data,
+               sizeof(desc->l_policy_data));
         memcpy(desc->l_version, lock->l_version, sizeof(desc->l_version));
 }
 
-static void ldlm_add_ast_work_item(struct ldlm_lock *lock,
-                                   struct ldlm_lock *new,
-                                   void *data, int datalen)
+void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
+                            void *data, int datalen)
 {
         struct ldlm_ast_work *w;
         ENTRY;
@@ -420,7 +399,12 @@ static void ldlm_add_ast_work_item(struct ldlm_lock *lock,
         w->w_data = data;
         w->w_datalen = datalen;
         if (new) {
+                LDLM_DEBUG(lock, "lock incompatible; sending blocking AST.\n");
                 lock->l_flags |= LDLM_FL_AST_SENT;
+                /* If the enqueuing client said so, tell the AST recipient to
+                 * discard dirty data, rather than writing back. */
+                if (new->l_flags & LDLM_AST_DISCARD_DATA)
+                        lock->l_flags |= LDLM_FL_DISCARD_DATA;
                 w->w_blocking = 1;
                 ldlm_lock2desc(new, &w->w_desc);
         }
@@ -430,7 +414,6 @@ static void ldlm_add_ast_work_item(struct ldlm_lock *lock,
         EXIT;
  out:
         l_unlock(&lock->l_resource->lr_namespace->ns_lock);
-        return;
 }
 
 void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode)
@@ -491,12 +474,11 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode)
                 LDLM_DEBUG(lock, "final decref done on cbpending lock");
                 l_unlock(&ns->ns_lock);
 
+                l_check_no_ns_lock(ns);
                 /* FIXME: need a real 'desc' here */
                 if (lock->l_blocking_ast != NULL)
-                        lock->l_blocking_ast(lock, NULL, lock->l_data,
+                        lock->l_blocking_ast(lock, NULL, lock->l_ast_data,
                                              LDLM_CB_BLOCKING);
-                else
-                        LDLM_DEBUG(lock, "No blocking AST?");
         } else if (ns->ns_client && !lock->l_readers && !lock->l_writers) {
                 /* If this is a client-side namespace and this was the last
                  * reference, put it on the LRU. */
@@ -540,56 +522,6 @@ void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode)
         LDLM_LOCK_PUT(lock);
 }
 
-static int ldlm_lock_compat_list(struct ldlm_lock *lock, int send_cbs,
-                                 struct list_head *queue)
-{
-        struct list_head *tmp, *pos;
-        int rc = 1;
-
-        list_for_each_safe(tmp, pos, queue) {
-                struct ldlm_lock *child;
-                ldlm_res_compat compat;
-
-                child = list_entry(tmp, struct ldlm_lock, l_res_link);
-                if (lock == child)
-                        continue;
-
-                compat = ldlm_res_compat_table[child->l_resource->lr_type];
-                if (compat && compat(child, lock)) {
-                        CDEBUG(D_OTHER, "compat function succeded, next.\n");
-                        continue;
-                }
-                if (lockmode_compat(child->l_granted_mode, lock->l_req_mode)) {
-                        CDEBUG(D_OTHER, "lock modes are compatible, next.\n");
-                        continue;
-                }
-
-                rc = 0;
-
-                if (send_cbs && child->l_blocking_ast != NULL)
-                        ldlm_add_ast_work_item(child, lock, NULL, 0);
-        }
-
-        return rc;
-}
-
-static int ldlm_lock_compat(struct ldlm_lock *lock, int send_cbs)
-{
-        int rc;
-        ENTRY;
-
-        l_lock(&lock->l_resource->lr_namespace->ns_lock);
-        rc = ldlm_lock_compat_list(lock, send_cbs,
-                                   &lock->l_resource->lr_granted);
-        /* FIXME: should we be sending ASTs to converting? */
-        if (rc)
-                rc = ldlm_lock_compat_list
-                        (lock, send_cbs, &lock->l_resource->lr_converting);
-
-        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
-        RETURN(rc);
-}
-
 /* NOTE: called by
  *  - ldlm_lock_enqueue
  *  - ldlm_reprocess_queue
@@ -602,8 +534,8 @@ void ldlm_grant_lock(struct ldlm_lock *lock, void *data, int datalen,
         ENTRY;
 
         l_lock(&lock->l_resource->lr_namespace->ns_lock);
-        ldlm_resource_add_lock(res, &res->lr_granted, lock);
         lock->l_granted_mode = lock->l_req_mode;
+        ldlm_resource_add_lock(res, &res->lr_granted, lock);
 
         if (lock->l_granted_mode < res->lr_most_restr)
                 res->lr_most_restr = lock->l_granted_mode;
@@ -619,8 +551,7 @@ void ldlm_grant_lock(struct ldlm_lock *lock, void *data, int datalen,
  * comment above ldlm_lock_match */
 static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode,
                                       struct ldlm_extent *extent,
-                                      struct ldlm_lock *old_lock, void *data,
-                                      int flags)
+                                      struct ldlm_lock *old_lock, int flags)
 {
         struct ldlm_lock *lock;
         struct list_head *tmp;
@@ -648,8 +579,8 @@ static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode,
                         continue;
 
                 if (lock->l_resource->lr_type == LDLM_EXTENT &&
-                    (lock->l_extent.start > extent->start ||
-                     lock->l_extent.end < extent->end))
+                    (lock->l_policy_data.l_extent.start > extent->start ||
+                     lock->l_policy_data.l_extent.end < extent->end))
                         continue;
 
                 if (lock->l_destroyed)
@@ -659,12 +590,6 @@ static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode,
                     !(lock->l_flags & LDLM_FL_LOCAL))
                         continue;
 
-                if ((flags & LDLM_FL_MATCH_DATA) && lock->l_data != data) {
-                        LDLM_DEBUG(lock, "data mismatch: have %p, want %p",
-                                   lock->l_data, data);
-                        continue;
-                }
-
                 ldlm_lock_addref_internal(lock, mode);
                 return lock;
         }
@@ -686,15 +611,13 @@ static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode,
  * If 'flags' contains LDLM_FL_CBPENDING, then locks that have been marked
  *     to be canceled can still be matched as long as they still have reader
  *     or writer refernces
- * If 'flags' contains LDLM_FL_MATCH_DATA, then only match a lock if the opaque
- *     data is the same.
  *
  * Returns 1 if it finds an already-existing lock that is compatible; in this
  * case, lockh is filled in with a addref()ed lock
  */
 int ldlm_lock_match(struct ldlm_namespace *ns, int flags,
                     struct ldlm_res_id *res_id, __u32 type, void *cookie,
-                    int cookielen, ldlm_mode_t mode, void *data,
+                    int cookielen, ldlm_mode_t mode,
                     struct lustre_handle *lockh)
 {
         struct ldlm_resource *res;
@@ -720,18 +643,15 @@ int ldlm_lock_match(struct ldlm_namespace *ns, int flags,
 
         l_lock(&ns->ns_lock);
 
-        lock = search_queue(&res->lr_granted, mode, cookie, old_lock, data,
-                            flags);
+        lock = search_queue(&res->lr_granted, mode, cookie, old_lock, flags);
         if (lock != NULL)
                 GOTO(out, rc = 1);
         if (flags & LDLM_FL_BLOCK_GRANTED)
                 GOTO(out, rc = 0);
-        lock = search_queue(&res->lr_converting, mode, cookie, old_lock, data,
-                            flags);
+        lock = search_queue(&res->lr_converting, mode, cookie, old_lock, flags);
         if (lock != NULL)
                 GOTO(out, rc = 1);
-        lock = search_queue(&res->lr_waiting, mode, cookie, old_lock, data,
-                            flags);
+        lock = search_queue(&res->lr_waiting, mode, cookie, old_lock, flags);
         if (lock != NULL)
                 GOTO(out, rc = 1);
 
@@ -789,7 +709,7 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
                 RETURN(NULL);
 
         lock->l_req_mode = mode;
-        lock->l_data = data;
+        lock->l_ast_data = data;
         lock->l_blocking_ast = blocking;
         lock->l_completion_ast = completion;
 
@@ -800,27 +720,22 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
                                struct ldlm_lock **lockp,
                                void *cookie, int cookie_len, int *flags)
 {
-        struct ldlm_resource *res;
         struct ldlm_lock *lock = *lockp;
-        int local;
-        ldlm_res_policy policy;
+        struct ldlm_resource *res = lock->l_resource;
+        int local = res->lr_namespace->ns_client;
+        ldlm_processing_policy policy;
+        ldlm_error_t rc = ELDLM_OK;
         ENTRY;
 
-        res = lock->l_resource;
-
-        if (res->lr_type == LDLM_EXTENT)
-                memcpy(&lock->l_extent, cookie, sizeof(lock->l_extent));
+        if (res->lr_type != LDLM_PLAIN)
+                memcpy(&lock->l_policy_data, cookie, cookie_len);
 
         /* policies are not executed on the client or during replay */
-        local = res->lr_namespace->ns_client;
-        if (!local && !(*flags & LDLM_FL_REPLAY) &&
-            (policy = ldlm_res_policy_table[res->lr_type])) {
-                int rc;
-                rc = policy(ns, lockp, cookie, lock->l_req_mode, *flags, NULL);
-                if (rc == ELDLM_LOCK_CHANGED) {
-                        res = lock->l_resource;
-                        *flags |= LDLM_FL_LOCK_CHANGED;
-                } else if (rc == ELDLM_LOCK_REPLACED) {
+        if ((*flags & (LDLM_FL_HAS_INTENT|LDLM_FL_REPLAY)) == LDLM_FL_HAS_INTENT
+            && !local && ldlm_intent_policy_func) {
+                rc = ldlm_intent_policy_func(ns, lockp, cookie,
+                                             lock->l_req_mode, *flags, NULL);
+                if (rc == ELDLM_LOCK_REPLACED) {
                         /* The lock that was returned has already been granted,
                          * and placed into lockp.  Destroy the old one and our
                          * work here is done. */
@@ -828,10 +743,12 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
                         LDLM_LOCK_PUT(lock);
                         *flags |= LDLM_FL_LOCK_CHANGED;
                         RETURN(0);
-                } else if (rc == ELDLM_LOCK_ABORTED) {
+                } else if (rc == ELDLM_LOCK_ABORTED ||
+                           (rc == 0 && (*flags & LDLM_FL_INTENT_ONLY))) {
                         ldlm_lock_destroy(lock);
                         RETURN(rc);
                 }
+                LASSERT(rc == ELDLM_OK);
         }
 
         l_lock(&ns->ns_lock);
@@ -844,6 +761,10 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
                 GOTO(out, ELDLM_OK);
         }
 
+        /* Some flags from the enqueue want to make it into the AST, via the
+         * lock's l_flags. */
+        lock->l_flags |= (*flags & LDLM_AST_DISCARD_DATA);
+
         /* This distinction between local lock trees is very important; a client
          * namespace only has information about locks taken by that client, and
          * thus doesn't have enough information to decide for itself if it can
@@ -878,58 +799,50 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
                 /* If no flags, fall through to normal enqueue path. */
         }
 
-        /* FIXME: We may want to optimize by checking lr_most_restr */
-        if (!list_empty(&res->lr_converting)) {
-                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
-                *flags |= LDLM_FL_BLOCK_CONV;
-                GOTO(out, ELDLM_OK);
-        }
-        if (!list_empty(&res->lr_waiting)) {
-                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
-                *flags |= LDLM_FL_BLOCK_WAIT;
-                GOTO(out, ELDLM_OK);
-        }
-        if (!ldlm_lock_compat(lock, 0)) {
-                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
-                *flags |= LDLM_FL_BLOCK_GRANTED;
-                GOTO(out, ELDLM_OK);
-        }
-        ldlm_grant_lock(lock, NULL, 0, 0);
+        policy = ldlm_processing_policy_table[res->lr_type];
+        policy(lock, flags, 1, &rc);
         EXIT;
-      out:
+out:
         l_unlock(&ns->ns_lock);
-        return ELDLM_OK;
+        return rc;
 }
 
 /* Must be called with namespace taken: queue is waiting or converting. */
-static int ldlm_reprocess_queue(struct ldlm_resource *res,
-                                struct list_head *queue)
+int ldlm_reprocess_queue(struct ldlm_resource *res, struct list_head *queue)
 {
         struct list_head *tmp, *pos;
+        ldlm_processing_policy policy;
+        int flags;
+        int rc = LDLM_ITER_CONTINUE;
+        ldlm_error_t err;
         ENTRY;
 
+        policy = ldlm_processing_policy_table[res->lr_type];
+        LASSERT(policy);
+
         list_for_each_safe(tmp, pos, queue) {
                 struct ldlm_lock *pending;
                 pending = list_entry(tmp, struct ldlm_lock, l_res_link);
 
                 CDEBUG(D_INFO, "Reprocessing lock %p\n", pending);
 
-                if (!ldlm_lock_compat(pending, 1))
-                        RETURN(1);
-
-                list_del_init(&pending->l_res_link);
-                ldlm_grant_lock(pending, NULL, 0, 1);
+                flags = 0;
+                rc = policy(pending, &flags, 0, &err);
+                if (rc != LDLM_ITER_CONTINUE)
+                        break;
         }
 
-        RETURN(0);
+        RETURN(rc);
 }
 
-int ldlm_run_ast_work(struct list_head *rpc_list)
+int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list)
 {
         struct list_head *tmp, *pos;
         int rc, retval = 0;
         ENTRY;
 
+        l_check_no_ns_lock(ns);
+
         list_for_each_safe(tmp, pos, rpc_list) {
                 struct ldlm_ast_work *w =
                         list_entry(tmp, struct ldlm_ast_work, w_list);
@@ -944,12 +857,14 @@ int ldlm_run_ast_work(struct list_head *rpc_list)
                  * will never call the local blocking_ast until we drop our
                  * reader/writer reference, which we won't do until we get the
                  * reply and finish enqueueing. */
+                LASSERT(w->w_lock != NULL);
                 if (w->w_blocking) {
                         LASSERT(w->w_lock->l_blocking_ast != NULL);
                         rc = w->w_lock->l_blocking_ast
                                 (w->w_lock, &w->w_desc, w->w_data,
                                  LDLM_CB_BLOCKING);
                 } else if (w->w_lock->l_completion_ast != NULL) {
+                        LASSERT(w->w_lock->l_completion_ast != NULL);
                         rc = w->w_lock->l_completion_ast(w->w_lock, w->w_flags,
                                                          w->w_data);
                 } else {
@@ -994,16 +909,18 @@ void ldlm_reprocess_all(struct ldlm_resource *res)
         l_lock(&res->lr_namespace->ns_lock);
         res->lr_tmp = &rpc_list;
 
-        ldlm_reprocess_queue(res, &res->lr_converting);
-        if (list_empty(&res->lr_converting))
+        rc = ldlm_reprocess_queue(res, &res->lr_converting);
+        if (rc == LDLM_ITER_CONTINUE)
                 ldlm_reprocess_queue(res, &res->lr_waiting);
 
         res->lr_tmp = NULL;
         l_unlock(&res->lr_namespace->ns_lock);
 
-        rc = ldlm_run_ast_work(&rpc_list);
-        if (rc == -ERESTART)
+        rc = ldlm_run_ast_work(res->lr_namespace, &rpc_list);
+        if (rc == -ERESTART) {
+                LASSERT(list_empty(&rpc_list));
                 goto restart;
+        }
         EXIT;
 }
 
@@ -1014,7 +931,8 @@ void ldlm_cancel_callback(struct ldlm_lock *lock)
                 lock->l_flags |= LDLM_FL_CANCEL;
                 if (lock->l_blocking_ast) {
                         l_unlock(&lock->l_resource->lr_namespace->ns_lock);
-                        lock->l_blocking_ast(lock, NULL, lock->l_data,
+                        // l_check_no_ns_lock(lock->l_resource->lr_namespace);
+                        lock->l_blocking_ast(lock, NULL, lock->l_ast_data,
                                              LDLM_CB_CANCELING);
                         return;
                 } else {
@@ -1047,7 +965,7 @@ void ldlm_lock_cancel(struct ldlm_lock *lock)
                 LBUG();
         }
 
-        ldlm_cancel_callback(lock); /* XXX FIXME bug 1030 */
+        ldlm_cancel_callback(lock);
 
         ldlm_resource_unlink_lock(lock);
         ldlm_lock_destroy(lock);
@@ -1063,29 +981,30 @@ int ldlm_lock_set_data(struct lustre_handle *lockh, void *data)
         if (lock == NULL)
                 RETURN(-EINVAL);
 
-        lock->l_data = data;
-
+        lock->l_ast_data = data;
         LDLM_LOCK_PUT(lock);
-
         RETURN(0);
 }
 
-/* This function is only called from one thread (per export); no locking around
- * the list ops needed */
 void ldlm_cancel_locks_for_export(struct obd_export *exp)
 {
-        struct list_head *iter, *n;
+        struct ldlm_namespace *ns = exp->exp_obd->obd_namespace;
+        struct ldlm_lock *lock;
+        struct ldlm_resource *res;
 
-        list_for_each_safe(iter, n, &exp->exp_ldlm_data.led_held_locks) {
-                struct ldlm_lock *lock;
-                struct ldlm_resource *res;
-                lock = list_entry(iter, struct ldlm_lock, l_export_chain);
+        l_lock(&ns->ns_lock);
+        while(!list_empty(&exp->exp_ldlm_data.led_held_locks)) {
+                lock = list_entry(exp->exp_ldlm_data.led_held_locks.next,
+                                  struct ldlm_lock, l_export_chain);
                 res = ldlm_resource_getref(lock->l_resource);
                 LDLM_DEBUG(lock, "export %p", exp);
                 ldlm_lock_cancel(lock);
+                l_unlock(&ns->ns_lock);
                 ldlm_reprocess_all(res);
                 ldlm_resource_putref(res);
+                l_lock(&ns->ns_lock);
         }
+        l_unlock(&ns->ns_lock);
 }
 
 struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
@@ -1134,13 +1053,14 @@ struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
         l_unlock(&ns->ns_lock);
 
         if (granted)
-                ldlm_run_ast_work(&rpc_list);
+                ldlm_run_ast_work(ns, &rpc_list);
         RETURN(res);
 }
 
 void ldlm_lock_dump(int level, struct ldlm_lock *lock, int pos)
 {
         char ver[128];
+        char str[PTL_NALFMT_SIZE];
         struct obd_device *obd = NULL;
 
         if (!((portal_debug | D_ERROR) & level))
@@ -1160,30 +1080,41 @@ void ldlm_lock_dump(int level, struct ldlm_lock *lock, int pos)
 
         CDEBUG(level, "  -- Lock dump: %p (%s) (rc: %d) (pos: %d)\n", lock, ver,
                atomic_read(&lock->l_refc), pos);
-        if (lock->l_connh != NULL)
-                obd = class_conn2obd(lock->l_connh);
+        if (lock->l_conn_export != NULL)
+                obd = lock->l_conn_export->exp_obd;
         if (lock->l_export && lock->l_export->exp_connection) {
-                CDEBUG(level, "  Node: NID "LPX64" on %s (rhandle: "LPX64")\n",
+                CDEBUG(level, "  Node: NID "LPX64" (%s) on %s (rhandle: "LPX64")\n",
                        lock->l_export->exp_connection->c_peer.peer_nid,
+                       portals_nid2str(lock->l_export->exp_connection->c_peer.peer_ni->pni_number,
+                                       lock->l_export->exp_connection->c_peer.peer_nid, str),
                        lock->l_export->exp_connection->c_peer.peer_ni->pni_name,
                        lock->l_remote_handle.cookie);
         } else if (obd == NULL) {
                 CDEBUG(level, "  Node: local\n");
         } else {
                 struct obd_import *imp = obd->u.cli.cl_import;
-                CDEBUG(level, "  Node: NID "LPX64" on %s (rhandle: "LPX64")\n",
+                CDEBUG(level, "  Node: NID "LPX64" (%s) on %s (rhandle: "LPX64")\n",
                        imp->imp_connection->c_peer.peer_nid,
+                       portals_nid2str(imp->imp_connection->c_peer.peer_ni->pni_number,
+                                       imp->imp_connection->c_peer.peer_nid, str),
                        imp->imp_connection->c_peer.peer_ni->pni_name,
                        lock->l_remote_handle.cookie);
         }
-        CDEBUG(level, "  Resource: %p ("LPD64")\n", lock->l_resource,
-               lock->l_resource->lr_name.name[0]);
-        CDEBUG(level, "  Req mode: %d, grant mode: %d, readers: %d, writers: "
-               "%d\n", (int)lock->l_req_mode, (int)lock->l_granted_mode,
-               lock->l_readers, lock->l_writers);
+        CDEBUG(level, "  Resource: %p ("LPU64"/"LPU64")\n", lock->l_resource,
+               lock->l_resource->lr_name.name[0],
+               lock->l_resource->lr_name.name[1]);
+        CDEBUG(level, "  Req mode: %d, grant mode: %d, rc: %u, read: %d, "
+               "write: %d\n", (int)lock->l_req_mode, (int)lock->l_granted_mode,
+               atomic_read(&lock->l_refc), lock->l_readers, lock->l_writers);
         if (lock->l_resource->lr_type == LDLM_EXTENT)
                 CDEBUG(level, "  Extent: "LPU64" -> "LPU64"\n",
-                       lock->l_extent.start, lock->l_extent.end);
+                       lock->l_policy_data.l_extent.start,
+                       lock->l_policy_data.l_extent.end);
+        else if (lock->l_resource->lr_type == LDLM_FLOCK)
+                CDEBUG(level, "  Pid: %d Extent: "LPU64" -> "LPU64"\n",
+                       lock->l_policy_data.l_flock.pid,
+                       lock->l_policy_data.l_flock.start,
+                       lock->l_policy_data.l_flock.end);
 }
 
 void ldlm_lock_dump_handle(int level, struct lustre_handle *lockh)
diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c
index 9350539e9d3bbdc285ff8d905423cda8afdfdf58..5ee9f0f8d1683c766a41d0da3f59d114015d377a 100644
--- a/lustre/ldlm/ldlm_lockd.c
+++ b/lustre/ldlm/ldlm_lockd.c
@@ -46,15 +46,19 @@ extern struct list_head ldlm_namespace_list;
 extern int (*mds_reint_p)(int offset, struct ptlrpc_request *req);
 extern int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req);
 
-static int ldlm_already_setup = 0;
+static DECLARE_MUTEX(ldlm_ref_sem);
+static int ldlm_refcount = 0;
 
-#ifdef __KERNEL__
+/* LDLM state */ 
+
+static struct ldlm_state *ldlm ;
 
 inline unsigned long round_timeout(unsigned long timeout)
 {
         return ((timeout / HZ) + 1) * HZ;
 }
 
+#ifdef __KERNEL__
 /* XXX should this be per-ldlm? */
 static struct list_head waiting_locks_list;
 static spinlock_t waiting_locks_spinlock;
@@ -66,11 +70,29 @@ static struct expired_lock_thread {
         struct list_head          elt_expired_locks;
         spinlock_t                elt_lock;
 } expired_lock_thread;
+#endif
 
 #define ELT_STOPPED   0
 #define ELT_READY     1
 #define ELT_TERMINATE 2
 
+struct ldlm_bl_pool {
+        spinlock_t              blp_lock;
+        struct list_head        blp_list;
+        wait_queue_head_t       blp_waitq;
+        atomic_t                blp_num_threads;
+        struct completion       blp_comp;
+};
+
+struct ldlm_bl_work_item {
+        struct list_head        blwi_entry;
+        struct ldlm_namespace   *blwi_ns;
+        struct ldlm_lock_desc   blwi_ld;
+        struct ldlm_lock        *blwi_lock;
+};
+
+#ifdef __KERNEL__
+
 static inline int have_expired_locks(void)
 {
         int need_to_run;
@@ -91,17 +113,17 @@ static int expired_lock_main(void *arg)
         ENTRY;
         lock_kernel();
         kportal_daemonize("ldlm_elt");
-        
+
         SIGNAL_MASK_LOCK(current, flags);
         sigfillset(&current->blocked);
         RECALC_SIGPENDING;
         SIGNAL_MASK_UNLOCK(current, flags);
-        
+
         unlock_kernel();
-        
+
         expired_lock_thread.elt_state = ELT_READY;
         wake_up(&expired_lock_thread.elt_waitq);
-        
+
         while (1) {
                 l_wait_event(expired_lock_thread.elt_waitq,
                              have_expired_locks() ||
@@ -114,7 +136,7 @@ static int expired_lock_main(void *arg)
                                                             struct ldlm_lock,
                                                             l_pending_chain);
                         spin_unlock_bh(&expired_lock_thread.elt_lock);
-                        
+
                         ptlrpc_fail_export(lock->l_export);
 
                         spin_lock_bh(&expired_lock_thread.elt_lock);
@@ -133,6 +155,7 @@ static int expired_lock_main(void *arg)
 static void waiting_locks_callback(unsigned long unused)
 {
         struct ldlm_lock *lock;
+        char str[PTL_NALFMT_SIZE];
 
         spin_lock_bh(&waiting_locks_spinlock);
         while (!list_empty(&waiting_locks_list)) {
@@ -143,10 +166,13 @@ static void waiting_locks_callback(unsigned long unused)
                         break;
 
                 LDLM_ERROR(lock, "lock callback timer expired: evicting client "
-                           "%s@%s nid "LPU64,
+                           "%s@%s nid "LPX64" (%s) ",
                            lock->l_export->exp_client_uuid.uuid,
                            lock->l_export->exp_connection->c_remote_uuid.uuid,
-                           lock->l_export->exp_connection->c_peer.peer_nid);
+                           lock->l_export->exp_connection->c_peer.peer_nid,
+                           portals_nid2str(lock->l_export->exp_connection->c_peer.peer_ni->pni_number,
+                                           lock->l_export->exp_connection->c_peer.peer_nid,
+                                           str));
 
                 spin_lock_bh(&expired_lock_thread.elt_lock);
                 list_del(&lock->l_pending_chain);
@@ -169,10 +195,14 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock)
 {
         unsigned long timeout_rounded;
 
+        spin_lock_bh(&waiting_locks_spinlock);
+        if (!list_empty(&lock->l_pending_chain)) {
+                LDLM_DEBUG(lock, "not re-adding to wait list");
+                spin_unlock_bh(&waiting_locks_spinlock);
+                return 0;
+        }
         LDLM_DEBUG(lock, "adding to wait list");
-        LASSERT(list_empty(&lock->l_pending_chain));
 
-        spin_lock_bh(&waiting_locks_spinlock);
         lock->l_callback_timeout = jiffies + (obd_timeout * HZ / 2);
 
         timeout_rounded = round_timeout(lock->l_callback_timeout);
@@ -245,15 +275,19 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock)
 
 static void ldlm_failed_ast(struct ldlm_lock *lock, int rc, char *ast_type)
 {
+        const struct ptlrpc_connection *conn = lock->l_export->exp_connection;
+        char str[PTL_NALFMT_SIZE];
+
         CERROR("%s AST failed (%d) for res "LPU64"/"LPU64
-               ", mode %s: evicting client %s@%s NID "LPU64"\n",
+               ", mode %s: evicting client %s@%s NID "LPX64" (%s)\n",
                ast_type, rc,
                lock->l_resource->lr_name.name[0],
                lock->l_resource->lr_name.name[1],
                ldlm_lockname[lock->l_granted_mode],
                lock->l_export->exp_client_uuid.uuid,
-               lock->l_export->exp_connection->c_remote_uuid.uuid,
-               lock->l_export->exp_connection->c_peer.peer_nid);
+               conn->c_remote_uuid.uuid, conn->c_peer.peer_nid,
+               portals_nid2str(conn->c_peer.peer_ni->pni_number,
+                               conn->c_peer.peer_nid, str));
         ptlrpc_fail_export(lock->l_export);
 }
 
@@ -274,11 +308,11 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock,
         LASSERT(lock);
 
         l_lock(&lock->l_resource->lr_namespace->ns_lock);
-        /* XXX This is necessary because, with the lock re-tasking, we actually
-         * _can_ get called in here twice.  (bug 830) */
-        if (!list_empty(&lock->l_pending_chain)) {
+        if (lock->l_granted_mode != lock->l_req_mode) {
+                /* this blocking AST will be communicated as part of the
+                 * completion AST instead */
                 l_unlock(&lock->l_resource->lr_namespace->ns_lock);
-                RETURN(0);
+                LDLM_DEBUG(lock, "lock not granted, not sending blocking AST");                 RETURN(0);
         }
 
         if (lock->l_destroyed) {
@@ -294,7 +328,7 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock,
         }
 #endif
 
-        req = ptlrpc_prep_req(lock->l_export->exp_ldlm_data.led_import,
+        req = ptlrpc_prep_req(lock->l_export->exp_imp_reverse,
                               LDLM_BL_CALLBACK, 1, &size, NULL);
         if (!req)
                 RETURN(-ENOMEM);
@@ -303,19 +337,36 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock,
         memcpy(&body->lock_handle1, &lock->l_remote_handle,
                sizeof(body->lock_handle1));
         memcpy(&body->lock_desc, desc, sizeof(*desc));
+        body->lock_flags |= (lock->l_flags & LDLM_AST_FLAGS);
 
         LDLM_DEBUG(lock, "server preparing blocking AST");
         req->rq_replen = lustre_msg_size(0, NULL);
 
-        ldlm_add_waiting_lock(lock);
+        if (lock->l_granted_mode == lock->l_req_mode)
+                ldlm_add_waiting_lock(lock);
         l_unlock(&lock->l_resource->lr_namespace->ns_lock);
 
-        req->rq_level = LUSTRE_CONN_RECOVER;
+        req->rq_send_state = LUSTRE_IMP_FULL;
         req->rq_timeout = 2; /* 2 second timeout for initial AST reply */
         rc = ptlrpc_queue_wait(req);
         if (rc == -ETIMEDOUT || rc == -EINTR) {
+#ifdef __KERNEL__
                 ldlm_del_waiting_lock(lock);
                 ldlm_failed_ast(lock, rc, "blocking");
+#else
+                /* XXX
+                 * Here we treat all clients as liblustre. When BLOCKING AST
+                 * timeout we don't evicting the client and only cancel
+                 * the lock.
+                 * restore to orignial implementation later!!!
+                 * XXX
+                 */
+                CERROR("BLOCKING AST to client (nid "LPU64") timeout, "
+                       "simply cancel lock 0x%p\n",
+                       req->rq_connection->c_peer.peer_nid, lock);
+                ldlm_lock_cancel(lock);
+                rc = -ERESTART;
+#endif
         } else if (rc) {
                 if (rc == -EINVAL)
                         CDEBUG(D_DLMTRACE, "client (nid "LPU64") returned %d "
@@ -332,9 +383,11 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock,
                         CDEBUG(D_ERROR, "client (nid "LPU64") returned %d "
                                "from blocking AST for lock %p\n",
                                req->rq_connection->c_peer.peer_nid,
-                               req->rq_repmsg->status, lock);
-                LDLM_DEBUG(lock, "client returned error %d from blocking AST",
-                           req->rq_status);
+                               (req->rq_repmsg != NULL)?
+                               req->rq_repmsg->status : 0,
+                               lock);
+                LDLM_DEBUG(lock, "client sent rc %d rq_status %d from blocking "
+                           "AST", rc, req->rq_status);
                 ldlm_lock_cancel(lock);
                 /* Server-side AST functions are called from ldlm_reprocess_all,
                  * which needs to be told to please restart its reprocessing. */
@@ -373,7 +426,7 @@ int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags, void *data)
         if (total_enqueue_wait / 1000000 > obd_timeout)
                 LDLM_ERROR(lock, "enqueue wait took %ldus", total_enqueue_wait);
 
-        req = ptlrpc_prep_req(lock->l_export->exp_ldlm_data.led_import,
+        req = ptlrpc_prep_req(lock->l_export->exp_imp_reverse,
                               LDLM_CP_CALLBACK, 1, &size, NULL);
         if (!req)
                 RETURN(-ENOMEM);
@@ -388,17 +441,24 @@ int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags, void *data)
                    total_enqueue_wait);
         req->rq_replen = lustre_msg_size(0, NULL);
 
-        req->rq_level = LUSTRE_CONN_RECOVER;
+        req->rq_send_state = LUSTRE_IMP_FULL;
         req->rq_timeout = 2; /* 2 second timeout for initial AST reply */
+
+        /* We only send real blocking ASTs after the lock is granted */
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+        if (lock->l_flags & LDLM_FL_AST_SENT) {
+                body->lock_flags |= LDLM_FL_AST_SENT;
+                ldlm_add_waiting_lock(lock); /* start the lock-timeout clock */
+        }
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+
         rc = ptlrpc_queue_wait(req);
         if (rc == -ETIMEDOUT || rc == -EINTR) {
                 ldlm_del_waiting_lock(lock);
                 ldlm_failed_ast(lock, rc, "completion");
         } else if (rc) {
-                CERROR("client returned %d from completion AST for lock %p\n",
-                       req->rq_status, lock);
-                LDLM_DEBUG(lock, "client returned error %d from completion AST",
-                           req->rq_status);
+                LDLM_ERROR(lock, "client sent rc %d rq_status %d from "
+                           "completion AST\n", rc, req->rq_status);
                 ldlm_lock_cancel(lock);
                 /* Server-side AST functions are called from ldlm_reprocess_all,
                  * which needs to be told to please restart its reprocessing. */
@@ -431,7 +491,7 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req,
                 CERROR ("Can't unpack dlm_req\n");
                 RETURN (-EFAULT);
         }
-        
+
         flags = dlm_req->lock_flags;
         if (dlm_req->lock_desc.l_resource.lr_type == LDLM_PLAIN &&
             (flags & LDLM_FL_HAS_INTENT)) {
@@ -440,15 +500,14 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req,
                 cookie = req;
                 cookielen = sizeof(*req);
         } else {
-                rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen,
-                                     &req->rq_repmsg);
+                rc = lustre_pack_reply(req, 1, &size, NULL);
                 if (rc) {
                         CERROR("out of memory\n");
                         RETURN(-ENOMEM);
                 }
-                if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) {
-                        cookie = &dlm_req->lock_desc.l_extent;
-                        cookielen = sizeof(struct ldlm_extent);
+                if (dlm_req->lock_desc.l_resource.lr_type != LDLM_PLAIN) {
+                        cookie = &dlm_req->lock_desc.l_policy_data;
+                        cookielen = sizeof(ldlm_policy_data_t);
                 }
         }
 
@@ -483,26 +542,33 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req,
         dlm_rep->lock_flags = flags;
 
         ldlm_lock2handle(lock, &dlm_rep->lock_handle);
-        if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT)
-                memcpy(&dlm_rep->lock_extent, &lock->l_extent,
-                       sizeof(lock->l_extent));
+        if (dlm_req->lock_desc.l_resource.lr_type != LDLM_PLAIN) {
+                memcpy(&dlm_rep->lock_policy_data, &lock->l_policy_data,
+                       cookielen);
+        }
         if (dlm_rep->lock_flags & LDLM_FL_LOCK_CHANGED) {
                 memcpy(&dlm_rep->lock_resource_name, &lock->l_resource->lr_name,
                        sizeof(dlm_rep->lock_resource_name));
                 dlm_rep->lock_mode = lock->l_req_mode;
         }
 
+        /* We never send a blocking AST until the lock is granted, but
+         * we can tell it right now */
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+        if (lock->l_flags & LDLM_FL_AST_SENT)
+                dlm_rep->lock_flags |= LDLM_FL_AST_SENT;
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+
         EXIT;
  out:
-        if (lock)
-                LDLM_DEBUG(lock, "server-side enqueue handler, sending reply"
-                           "(err=%d)", err);
         req->rq_status = err;
 
         /* The LOCK_CHANGED code in ldlm_lock_enqueue depends on this
          * ldlm_reprocess_all.  If this moves, revisit that code. -phil */
         if (lock) {
-                if (!err)
+                LDLM_DEBUG(lock, "server-side enqueue handler, sending reply"
+                           "(err=%d)", err);
+                if (!err && dlm_req->lock_desc.l_resource.lr_type != LDLM_FLOCK)
                         ldlm_reprocess_all(lock->l_resource);
                 LDLM_LOCK_PUT(lock);
         }
@@ -525,8 +591,8 @@ int ldlm_handle_convert(struct ptlrpc_request *req)
                 CERROR ("Can't unpack dlm_req\n");
                 RETURN (-EFAULT);
         }
-        
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc) {
                 CERROR("out of memory\n");
                 RETURN(-ENOMEM);
@@ -560,6 +626,7 @@ int ldlm_handle_cancel(struct ptlrpc_request *req)
 {
         struct ldlm_request *dlm_req;
         struct ldlm_lock *lock;
+        char str[PTL_NALFMT_SIZE];
         int rc;
         ENTRY;
 
@@ -570,7 +637,7 @@ int ldlm_handle_cancel(struct ptlrpc_request *req)
                 RETURN(-EFAULT);
         }
 
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc) {
                 CERROR("out of memory\n");
                 RETURN(-ENOMEM);
@@ -579,8 +646,10 @@ int ldlm_handle_cancel(struct ptlrpc_request *req)
         lock = ldlm_handle2lock(&dlm_req->lock_handle1);
         if (!lock) {
                 CERROR("received cancel for unknown lock cookie "LPX64
-                       " from nid "LPU64"\n", dlm_req->lock_handle1.cookie,
-                       req->rq_connection->c_peer.peer_nid);
+                       " from nid "LPX64" (%s)\n", dlm_req->lock_handle1.cookie,
+                       req->rq_connection->c_peer.peer_nid,
+                       portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                       req->rq_connection->c_peer.peer_nid, str));
                 LDLM_DEBUG_NOLOCK("server-side cancel handler stale lock "
                                   "(cookie "LPU64")",
                                   dlm_req->lock_handle1.cookie);
@@ -605,9 +674,8 @@ int ldlm_handle_cancel(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-static void ldlm_handle_bl_callback(struct ptlrpc_request *req,
-                                    struct ldlm_namespace *ns,
-                                    struct ldlm_request *dlm_req,
+static void ldlm_handle_bl_callback(struct ldlm_namespace *ns,
+                                    struct ldlm_lock_desc *ld,
                                     struct ldlm_lock *lock)
 {
         int do_ast;
@@ -624,8 +692,9 @@ static void ldlm_handle_bl_callback(struct ptlrpc_request *req,
                            "callback (%p)", lock->l_blocking_ast);
                 if (lock->l_blocking_ast != NULL) {
                         l_unlock(&ns->ns_lock);
-                        lock->l_blocking_ast(lock, &dlm_req->lock_desc,
-                                             lock->l_data, LDLM_CB_BLOCKING);
+                        l_check_no_ns_lock(ns);
+                        lock->l_blocking_ast(lock, ld, lock->l_ast_data,
+                                             LDLM_CB_BLOCKING);
                         l_lock(&ns->ns_lock);
                 }
         } else {
@@ -656,9 +725,9 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
                 lock->l_req_mode = dlm_req->lock_desc.l_granted_mode;
                 LDLM_DEBUG(lock, "completion AST, new lock mode");
         }
-        if (lock->l_resource->lr_type == LDLM_EXTENT)
-                memcpy(&lock->l_extent, &dlm_req->lock_desc.l_extent,
-                       sizeof(lock->l_extent));
+        if (lock->l_resource->lr_type != LDLM_PLAIN)
+                memcpy(&lock->l_policy_data, &dlm_req->lock_desc.l_policy_data,
+                       sizeof(lock->l_policy_data));
 
         ldlm_resource_unlink_lock(lock);
         if (memcmp(&dlm_req->lock_desc.l_resource.lr_name,
@@ -668,6 +737,12 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
                                          dlm_req->lock_desc.l_resource.lr_name);
                 LDLM_DEBUG(lock, "completion AST, new resource");
         }
+
+        if (dlm_req->lock_flags & LDLM_FL_AST_SENT) {
+                lock->l_flags |= LDLM_FL_CBPENDING;
+                LDLM_DEBUG(lock, "completion AST includes blocking AST");
+        }
+
         lock->l_resource->lr_tmp = &ast_list;
         ldlm_grant_lock(lock, req, sizeof(*req), 1);
         lock->l_resource->lr_tmp = NULL;
@@ -675,7 +750,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
         l_unlock(&ns->ns_lock);
         LDLM_LOCK_PUT(lock);
 
-        ldlm_run_ast_work(&ast_list);
+        ldlm_run_ast_work(ns, &ast_list);
 
         LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)",
                           lock);
@@ -685,18 +760,44 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
 static int ldlm_callback_reply(struct ptlrpc_request *req, int rc)
 {
         req->rq_status = rc;
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen,
-                             &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc)
                 return rc;
         return ptlrpc_reply(req);
 }
 
+#ifdef __KERNEL__
+static int ldlm_bl_to_thread(struct ldlm_state *ldlm, struct ldlm_namespace *ns,
+                             struct ldlm_lock_desc *ld, struct ldlm_lock *lock)
+{
+        struct ldlm_bl_pool *blp = ldlm->ldlm_bl_pool;
+        struct ldlm_bl_work_item *blwi;
+        ENTRY;
+
+        OBD_ALLOC(blwi, sizeof(*blwi));
+        if (blwi == NULL)
+                RETURN(-ENOMEM);
+
+        blwi->blwi_ns = ns;
+        blwi->blwi_ld = *ld;
+        blwi->blwi_lock = lock;
+
+        spin_lock(&blp->blp_lock);
+        list_add_tail(&blwi->blwi_entry, &blp->blp_list);
+        wake_up(&blp->blp_waitq);
+        spin_unlock(&blp->blp_lock);
+
+        RETURN(0);
+}
+#endif
+
 static int ldlm_callback_handler(struct ptlrpc_request *req)
 {
         struct ldlm_namespace *ns;
         struct ldlm_request *dlm_req;
         struct ldlm_lock *lock;
+        char str[PTL_NALFMT_SIZE];
+        int rc;
         ENTRY;
 
         /* Requests arrive in sender's byte order.  The ptlrpc service
@@ -707,10 +808,12 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
         if (req->rq_export == NULL) {
                 struct ldlm_request *dlm_req;
 
-                CDEBUG(D_RPCTRACE, "operation %d from nid "LPU64" with bad "
+                CDEBUG(D_RPCTRACE, "operation %d from nid "LPX64" (%s) with bad "
                        "export cookie "LPX64" (ptl req %d/rep %d); this is "
                        "normal if this node rebooted with a lock held\n",
                        req->rq_reqmsg->opc, req->rq_connection->c_peer.peer_nid,
+                       portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                       req->rq_connection->c_peer.peer_nid, str),
                        req->rq_reqmsg->handle.cookie,
                        req->rq_request_portal, req->rq_reply_portal);
 
@@ -728,6 +831,16 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                 OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0);
         } else if (req->rq_reqmsg->opc == LDLM_CP_CALLBACK) {
                 OBD_FAIL_RETURN(OBD_FAIL_LDLM_CP_CALLBACK, 0);
+        } else if (req->rq_reqmsg->opc == OBD_LOG_CANCEL) {
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOG_CANCEL_NET, 0);
+        } else if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_CREATE) {
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+        } else if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_NEXT_BLOCK) {
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+        } else if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_READ_HEADER) {
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+        } else if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_CLOSE) {
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
         } else {
                 ldlm_callback_reply(req, -EPROTO);
                 RETURN(0);
@@ -735,6 +848,42 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
 
         LASSERT(req->rq_export != NULL);
         LASSERT(req->rq_export->exp_obd != NULL);
+
+#ifdef ENABLE_ORPHANS
+        /* FIXME - how to send reply */
+        if (req->rq_reqmsg->opc == OBD_LOG_CANCEL) {
+                int rc = llog_origin_handle_cancel(req);
+                ldlm_callback_reply(req, rc);
+                RETURN(0);
+        }
+
+        if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_CREATE) {
+                int rc = llog_origin_handle_create(req);
+                req->rq_status = rc;
+                ptlrpc_reply(req);
+                RETURN(0);
+        }
+
+        if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_NEXT_BLOCK) {
+                int rc = llog_origin_handle_next_block(req);
+                req->rq_status = rc;
+                ptlrpc_reply(req);
+                RETURN(0);
+        }
+
+        if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_READ_HEADER) {
+                int rc = llog_origin_handle_read_header(req);
+                req->rq_status = rc;
+                ptlrpc_reply(req);
+                RETURN(0);
+        }
+
+        if (req->rq_reqmsg->opc == LLOG_ORIGIN_HANDLE_CLOSE) {
+                int rc = llog_origin_handle_close(req);
+                ldlm_callback_reply(req, rc);
+                RETURN(0);
+        }
+#endif
         ns = req->rq_export->exp_obd->obd_namespace;
         LASSERT(ns != NULL);
 
@@ -745,7 +894,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                 ldlm_callback_reply (req, -EPROTO);
                 RETURN (0);
         }
-        
+
         lock = ldlm_handle2lock_ns(ns, &dlm_req->lock_handle1);
         if (!lock) {
                 CDEBUG(D_INODE, "callback on lock "LPX64" - lock disappeared\n",
@@ -754,15 +903,31 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                 RETURN(0);
         }
 
-        /* we want the ost thread to get this reply so that it can respond
+        /* Copy hints/flags (e.g. LDLM_FL_DISCARD_DATA) from AST. */
+        lock->l_flags |= (dlm_req->lock_flags & LDLM_AST_FLAGS);
+
+        /* We want the ost thread to get this reply so that it can respond
          * to ost requests (write cache writeback) that might be triggered
-         * in the callback */
-        ldlm_callback_reply(req, 0);
+         * in the callback.
+         *
+         * But we'd also like to be able to indicate in the reply that we're
+         * cancelling right now, because it's unused, or have an intent result
+         * in the reply, so we might have to push the responsibility for sending
+         * the reply down into the AST handlers, alas. */
+        if (req->rq_reqmsg->opc != LDLM_BL_CALLBACK)
+                ldlm_callback_reply(req, 0);
 
         switch (req->rq_reqmsg->opc) {
         case LDLM_BL_CALLBACK:
                 CDEBUG(D_INODE, "blocking ast\n");
-                ldlm_handle_bl_callback(req, ns, dlm_req, lock);
+#ifdef __KERNEL__
+                rc = ldlm_bl_to_thread(ldlm, ns, &dlm_req->lock_desc, lock);
+                ldlm_callback_reply(req, rc);
+#else
+                rc = 0;
+                ldlm_callback_reply(req, rc);
+                ldlm_handle_bl_callback(ns, &dlm_req->lock_desc, lock);
+#endif
                 break;
         case LDLM_CP_CALLBACK:
                 CDEBUG(D_INODE, "completion ast\n");
@@ -818,75 +983,134 @@ static int ldlm_cancel_handler(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-static int ldlm_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
-                          void *karg, void *uarg)
+#ifdef __KERNEL__
+static struct ldlm_bl_work_item *ldlm_bl_get_work(struct ldlm_bl_pool *blp)
+{
+        struct ldlm_bl_work_item *blwi = NULL;
+
+        spin_lock(&blp->blp_lock);
+        if (!list_empty(&blp->blp_list)) {
+                blwi = list_entry(blp->blp_list.next, struct ldlm_bl_work_item,
+                                  blwi_entry);
+                list_del(&blwi->blwi_entry);
+        }
+        spin_unlock(&blp->blp_lock);
+
+        return blwi;
+}
+
+struct ldlm_bl_thread_data {
+        int                     bltd_num;
+        struct ldlm_bl_pool     *bltd_blp;
+};
+
+static int ldlm_bl_thread_main(void *arg)
 {
-        struct obd_device *obddev = class_conn2obd(conn);
-        struct ptlrpc_connection *connection;
-        struct obd_uuid uuid = { "ldlm" };
-        int err = 0;
+        struct ldlm_bl_thread_data *bltd = arg;
+        struct ldlm_bl_pool *blp = bltd->bltd_blp;
+        unsigned long flags;
         ENTRY;
 
-        if (_IOC_TYPE(cmd) != IOC_LDLM_TYPE || _IOC_NR(cmd) < IOC_LDLM_MIN_NR ||
-            _IOC_NR(cmd) > IOC_LDLM_MAX_NR) {
-                CDEBUG(D_IOCTL, "invalid ioctl (type %d, nr %d, size %d)\n",
-                       _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
-                RETURN(-EINVAL);
+        /* XXX boiler-plate */
+        {
+                char name[sizeof(current->comm)];
+                snprintf(name, sizeof(name) - 1, "ldlm_bl_%02d",
+                         bltd->bltd_num);
+                kportal_daemonize(name);
         }
+        SIGNAL_MASK_LOCK(current, flags);
+        sigfillset(&current->blocked);
+        RECALC_SIGPENDING;
+        SIGNAL_MASK_UNLOCK(current, flags);
 
-        OBD_ALLOC(obddev->u.ldlm.ldlm_client,
-                  sizeof(*obddev->u.ldlm.ldlm_client));
-        connection = ptlrpc_uuid_to_connection(&uuid);
-        if (!connection)
-                CERROR("No LDLM UUID found: assuming ldlm is local.\n");
-
-        switch (cmd) {
-        case IOC_LDLM_TEST:
-                //err = ldlm_test(obddev, conn);
-                err = 0;
-                CERROR("-- NO TESTS WERE RUN done err %d\n", err);
-                GOTO(out, err);
-        case IOC_LDLM_DUMP:
-                ldlm_dump_all_namespaces();
-                GOTO(out, err);
-        default:
-                GOTO(out, err = -EINVAL);
+        atomic_inc(&blp->blp_num_threads);
+        complete(&blp->blp_comp);
+
+        while(1) {
+                struct l_wait_info lwi = { 0 };
+                struct ldlm_bl_work_item *blwi = NULL;
+
+                l_wait_event_exclusive(blp->blp_waitq,
+                                       (blwi = ldlm_bl_get_work(blp)) != NULL,
+                                       &lwi);
+
+                if (blwi->blwi_ns == NULL)
+                        break;
+
+                ldlm_handle_bl_callback(blwi->blwi_ns, &blwi->blwi_ld,
+                                        blwi->blwi_lock);
+                OBD_FREE(blwi, sizeof(*blwi));
         }
 
- out:
-        if (connection)
-                ptlrpc_put_connection(connection);
-        OBD_FREE(obddev->u.ldlm.ldlm_client,
-                 sizeof(*obddev->u.ldlm.ldlm_client));
-        return err;
+        atomic_dec(&blp->blp_num_threads);
+        complete(&blp->blp_comp);
+        RETURN(0);
+}
+
+#endif
+
+static int ldlm_setup(void);
+static int ldlm_cleanup(int force);
+
+int ldlm_get_ref(void)
+{
+        int rc = 0;
+        down(&ldlm_ref_sem);
+        if (++ldlm_refcount == 1) {
+                rc = ldlm_setup();
+                if (rc)
+                        ldlm_refcount--;
+        }
+        up(&ldlm_ref_sem);
+
+        RETURN(rc);
 }
 
-static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf)
+void ldlm_put_ref(int force)
 {
-        struct ldlm_obd *ldlm = &obddev->u.ldlm;
-        int rc, i;
+        down(&ldlm_ref_sem);
+        if (ldlm_refcount == 1) {
+                int rc = ldlm_cleanup(force);
+                if (rc)
+                        CERROR("ldlm_cleanup failed: %d\n", rc);
+                else
+                        ldlm_refcount--;
+        } else {
+                ldlm_refcount--;
+        }
+        up(&ldlm_ref_sem);
+
+        EXIT;
+}
+
+static int ldlm_setup(void)
+{
+        struct ldlm_bl_pool *blp;
+        int rc = 0;
+#ifdef __KERNEL__
+        int i;
+#endif
         ENTRY;
 
-        if (ldlm_already_setup)
+        if (ldlm != NULL)
                 RETURN(-EALREADY);
 
-        rc = ldlm_proc_setup(obddev);
-        if (rc != 0)
-                RETURN(rc);
+        OBD_ALLOC(ldlm, sizeof(*ldlm));
+        if (ldlm == NULL)
+                RETURN(-ENOMEM);
 
 #ifdef __KERNEL__
-        inter_module_register("ldlm_cli_cancel_unused", THIS_MODULE,
-                              ldlm_cli_cancel_unused);
-        inter_module_register("ldlm_namespace_cleanup", THIS_MODULE,
-                              ldlm_namespace_cleanup);
-        inter_module_register("ldlm_replay_locks", THIS_MODULE,
-                              ldlm_replay_locks);
+        rc = ldlm_proc_setup();
+        if (rc != 0)
+                GOTO(out_free, rc);
+#endif
 
         ldlm->ldlm_cb_service =
                 ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE,
                                 LDLM_MAXREQSIZE, LDLM_CB_REQUEST_PORTAL,
                                 LDLM_CB_REPLY_PORTAL,
-                                ldlm_callback_handler, "ldlm_cbd", obddev);
+                                ldlm_callback_handler, "ldlm_cbd", 
+                                ldlm_svc_proc_dir);
 
         if (!ldlm->ldlm_cb_service) {
                 CERROR("failed to start service\n");
@@ -897,34 +1121,52 @@ static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf)
                 ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE,
                                 LDLM_MAXREQSIZE, LDLM_CANCEL_REQUEST_PORTAL,
                                 LDLM_CANCEL_REPLY_PORTAL,
-                                ldlm_cancel_handler, "ldlm_canceld", obddev);
+                                ldlm_cancel_handler, "ldlm_canceld", 
+                                ldlm_svc_proc_dir);
 
         if (!ldlm->ldlm_cancel_service) {
                 CERROR("failed to start service\n");
                 GOTO(out_proc, rc = -ENOMEM);
         }
 
+        OBD_ALLOC(blp, sizeof(*blp));
+        if (blp == NULL)
+                GOTO(out_proc, rc = -ENOMEM);
+        ldlm->ldlm_bl_pool = blp;
+
+        atomic_set(&blp->blp_num_threads, 0);
+        init_waitqueue_head(&blp->blp_waitq);
+        spin_lock_init(&blp->blp_lock);
+
+        INIT_LIST_HEAD(&blp->blp_list);
+
+#ifdef __KERNEL__
         for (i = 0; i < LDLM_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ldlm_cn_%02d", i);
-                rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cancel_service,
-                                         name);
-                if (rc) {
+                struct ldlm_bl_thread_data bltd = {
+                        .bltd_num = i,
+                        .bltd_blp = blp,
+                };
+                init_completion(&blp->blp_comp);
+                if (kernel_thread(ldlm_bl_thread_main, &bltd, 0) < 0) {
                         CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc);
                         LBUG();
                         GOTO(out_thread, rc);
                 }
+                wait_for_completion(&blp->blp_comp);
         }
 
-        for (i = 0; i < LDLM_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ldlm_cb_%02d", i);
-                rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cb_service, name);
-                if (rc) {
-                        CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc);
-                        LBUG();
-                        GOTO(out_thread, rc);
-                }
+        rc = ptlrpc_start_n_threads(NULL, ldlm->ldlm_cancel_service,
+                                    LDLM_NUM_THREADS, "ldlm_cn");
+        if (rc) {
+                LBUG();
+                GOTO(out_thread, rc);
+        }
+
+        rc = ptlrpc_start_n_threads(NULL, ldlm->ldlm_cb_service,
+                                    LDLM_NUM_THREADS, "ldlm_cb");
+        if (rc) {
+                LBUG();
+                GOTO(out_thread, rc);
         }
 
         INIT_LIST_HEAD(&expired_lock_thread.elt_expired_locks);
@@ -948,26 +1190,29 @@ static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf)
         init_timer(&waiting_locks_timer);
 #endif
 
-        ldlm_already_setup = 1;
-
         RETURN(0);
 
- out_thread:
 #ifdef __KERNEL__
-        ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service);
+ out_thread:
         ptlrpc_unregister_service(ldlm->ldlm_cancel_service);
-        ptlrpc_stop_all_threads(ldlm->ldlm_cb_service);
         ptlrpc_unregister_service(ldlm->ldlm_cb_service);
 #endif
- out_proc:
-        ldlm_proc_cleanup(obddev);
 
+ out_proc:
+#ifdef __KERNEL__
+        ldlm_proc_cleanup();
+ out_free:
+#endif
+        OBD_FREE(ldlm, sizeof(*ldlm));
+        ldlm = NULL;
         return rc;
 }
 
-static int ldlm_cleanup(struct obd_device *obddev, int flags)
+static int ldlm_cleanup(int force)
 {
-        struct ldlm_obd *ldlm = &obddev->u.ldlm;
+#ifdef __KERNEL__
+        struct ldlm_bl_pool *blp = ldlm->ldlm_bl_pool;
+#endif
         ENTRY;
 
         if (!list_empty(&ldlm_namespace_list)) {
@@ -977,56 +1222,41 @@ static int ldlm_cleanup(struct obd_device *obddev, int flags)
         }
 
 #ifdef __KERNEL__
-        if (flags & OBD_OPT_FORCE) {
-                ptlrpc_put_ldlm_hooks();
-        } else if (ptlrpc_ldlm_hooks_referenced()) {
-                CERROR("Some connections weren't cleaned up; run lconf with "
-                       "--force to forcibly unload.\n");
-                ptlrpc_dump_connections();
-                RETURN(-EBUSY);
+        while (atomic_read(&blp->blp_num_threads) > 0) {
+                struct ldlm_bl_work_item blwi = { .blwi_ns = NULL };
+
+                init_completion(&blp->blp_comp);
+
+                spin_lock(&blp->blp_lock);
+                list_add_tail(&blwi.blwi_entry, &blp->blp_list);
+                wake_up(&blp->blp_waitq);
+                spin_unlock(&blp->blp_lock);
+
+                wait_for_completion(&blp->blp_comp);
         }
+        OBD_FREE(blp, sizeof(*blp));
 
         ptlrpc_stop_all_threads(ldlm->ldlm_cb_service);
         ptlrpc_unregister_service(ldlm->ldlm_cb_service);
         ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service);
         ptlrpc_unregister_service(ldlm->ldlm_cancel_service);
-        ldlm_proc_cleanup(obddev);
+        ldlm_proc_cleanup();
 
         expired_lock_thread.elt_state = ELT_TERMINATE;
         wake_up(&expired_lock_thread.elt_waitq);
         wait_event(expired_lock_thread.elt_waitq,
                    expired_lock_thread.elt_state == ELT_STOPPED);
 
-        inter_module_unregister("ldlm_namespace_cleanup");
-        inter_module_unregister("ldlm_cli_cancel_unused");
-        inter_module_unregister("ldlm_replay_locks");
 #endif
 
-        ldlm_already_setup = 0;
-        RETURN(0);
-}
+        OBD_FREE(ldlm, sizeof(*ldlm));
+        ldlm = NULL;
 
-static int ldlm_connect(struct lustre_handle *conn, struct obd_device *src,
-                        struct obd_uuid *cluuid)
-{
-        return class_connect(conn, src, cluuid);
+        RETURN(0);
 }
 
-struct obd_ops ldlm_obd_ops = {
-        o_owner:       THIS_MODULE,
-        o_iocontrol:   ldlm_iocontrol,
-        o_setup:       ldlm_setup,
-        o_cleanup:     ldlm_cleanup,
-        o_connect:     ldlm_connect,
-        o_disconnect:  class_disconnect
-};
-
 int __init ldlm_init(void)
 {
-        int rc = class_register_type(&ldlm_obd_ops, 0, OBD_LDLM_DEVICENAME);
-        if (rc != 0)
-                return rc;
-
         ldlm_resource_slab = kmem_cache_create("ldlm_resources",
                                                sizeof(struct ldlm_resource), 0,
                                                SLAB_HWCACHE_ALIGN, NULL, NULL);
@@ -1046,15 +1276,19 @@ int __init ldlm_init(void)
         return 0;
 }
 
-static void __exit ldlm_exit(void)
+void __exit ldlm_exit(void)
 {
-        class_unregister_type(OBD_LDLM_DEVICENAME);
+        if ( ldlm_refcount )
+                CERROR("ldlm_refcount is %d in ldlm_exit!\n", ldlm_refcount);
         if (kmem_cache_destroy(ldlm_resource_slab) != 0)
                 CERROR("couldn't free ldlm resource slab\n");
         if (kmem_cache_destroy(ldlm_lock_slab) != 0)
                 CERROR("couldn't free ldlm lock slab\n");
 }
 
+/* ldlm_flock.c */
+EXPORT_SYMBOL(ldlm_flock_completion_ast);
+
 /* ldlm_lock.c */
 EXPORT_SYMBOL(ldlm_lock2desc);
 EXPORT_SYMBOL(ldlm_register_intent);
@@ -1097,6 +1331,8 @@ EXPORT_SYMBOL(ldlm_handle_enqueue);
 EXPORT_SYMBOL(ldlm_handle_cancel);
 EXPORT_SYMBOL(ldlm_handle_convert);
 EXPORT_SYMBOL(ldlm_del_waiting_lock);
+EXPORT_SYMBOL(ldlm_get_ref);
+EXPORT_SYMBOL(ldlm_put_ref);
 
 #if 0
 /* ldlm_test.c */
@@ -1116,22 +1352,17 @@ EXPORT_SYMBOL(l_lock);
 EXPORT_SYMBOL(l_unlock);
 
 /* ldlm_lib.c */
-EXPORT_SYMBOL(client_import_connect);
-EXPORT_SYMBOL(client_import_disconnect);
+EXPORT_SYMBOL(client_obd_setup);
+EXPORT_SYMBOL(client_obd_cleanup);
+EXPORT_SYMBOL(client_connect_import);
+EXPORT_SYMBOL(client_disconnect_export);
 EXPORT_SYMBOL(target_abort_recovery);
 EXPORT_SYMBOL(target_handle_connect);
+EXPORT_SYMBOL(target_destroy_export);
 EXPORT_SYMBOL(target_cancel_recovery_timer);
 EXPORT_SYMBOL(target_send_reply);
 EXPORT_SYMBOL(target_queue_recovery_request);
 EXPORT_SYMBOL(target_handle_ping);
 EXPORT_SYMBOL(target_handle_disconnect);
 EXPORT_SYMBOL(target_queue_final_reply);
-
-#ifdef __KERNEL__
-MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre Lock Management Module v0.1");
-MODULE_LICENSE("GPL");
-
-module_init(ldlm_init);
-module_exit(ldlm_exit);
-#endif
+EXPORT_SYMBOL(ldlm_put_lock_into_req);
diff --git a/lustre/ldlm/ldlm_plain.c b/lustre/ldlm/ldlm_plain.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9d77021378ce28794f266c437e837de248ba798
--- /dev/null
+++ b/lustre/ldlm/ldlm_plain.c
@@ -0,0 +1,122 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#ifdef __KERNEL__
+#include <linux/lustre_dlm.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include "ldlm_internal.h"
+
+static inline int
+ldlm_plain_compat_queue(struct list_head *queue, struct ldlm_lock *req,
+                        int send_cbs)
+{
+        struct list_head *tmp;
+        struct ldlm_lock *lock;
+        ldlm_mode_t req_mode = req->l_req_mode;
+        int compat = 1;
+        ENTRY;
+
+        list_for_each(tmp, queue) {
+                lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+                if (req == lock)
+                        RETURN(compat);
+
+                if (lockmode_compat(lock->l_req_mode, req_mode))
+                        continue;
+
+                if (!send_cbs)
+                        RETURN(0);
+
+                compat = 0;
+                if (lock->l_blocking_ast)
+                        ldlm_add_ast_work_item(lock, req, NULL, 0);
+        }
+
+        RETURN(compat);
+}
+
+/* If first_enq is 0 (ie, called from ldlm_reprocess_queue):
+ *   - blocking ASTs have already been sent
+ *   - the caller has already initialized req->lr_tmp
+ *   - must call this function with the ns lock held
+ *
+ * If first_enq is 1 (ie, called from ldlm_lock_enqueue):
+ *   - blocking ASTs have not been sent
+ *   - the caller has NOT initialized req->lr_tmp, so we must
+ *   - must call this function with the ns lock held once */
+int ldlm_process_plain_lock(struct ldlm_lock *lock, int *flags, int first_enq,
+                            ldlm_error_t *err)
+{
+        struct ldlm_resource *res = lock->l_resource;
+        struct list_head rpc_list = LIST_HEAD_INIT(rpc_list);
+        int rc;
+        ENTRY;
+
+        LASSERT(list_empty(&res->lr_converting));
+
+        if (!first_enq) {
+                LASSERT(res->lr_tmp != NULL);
+                rc = ldlm_plain_compat_queue(&res->lr_granted, lock, 0);
+                if (!rc)
+                        RETURN(LDLM_ITER_STOP);
+                rc = ldlm_plain_compat_queue(&res->lr_waiting, lock, 0);
+                if (!rc)
+                        RETURN(LDLM_ITER_STOP);
+
+                ldlm_resource_unlink_lock(lock);
+                ldlm_grant_lock(lock, NULL, 0, 1);
+                RETURN(LDLM_ITER_CONTINUE);
+        }
+
+ restart:
+        LASSERT(res->lr_tmp == NULL);
+        res->lr_tmp = &rpc_list;
+        rc = ldlm_plain_compat_queue(&res->lr_granted, lock, 1);
+        rc += ldlm_plain_compat_queue(&res->lr_waiting, lock, 1);
+        res->lr_tmp = NULL;
+
+        if (rc != 2) {
+                /* If either of the compat_queue()s returned 0, then we
+                 * have ASTs to send and must go onto the waiting list. */
+                ldlm_resource_unlink_lock(lock);
+                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
+                l_unlock(&res->lr_namespace->ns_lock);
+                rc = ldlm_run_ast_work(res->lr_namespace, &rpc_list);
+                l_lock(&res->lr_namespace->ns_lock);
+                if (rc == -ERESTART)
+                        GOTO(restart, -ERESTART);
+                *flags |= LDLM_FL_BLOCK_GRANTED;
+        } else {
+                ldlm_resource_unlink_lock(lock);
+                ldlm_grant_lock(lock, NULL, 0, 0);
+        }
+        RETURN(0);
+}
diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c
index 4c21bc676bdddccf0499ebac812b578aa9925d6d..7b6f50dd636dc77e29576574fcfaaddc86d7a881 100644
--- a/lustre/ldlm/ldlm_request.c
+++ b/lustre/ldlm/ldlm_request.c
@@ -44,19 +44,22 @@ int ldlm_expired_completion_wait(void *data)
 {
         struct lock_wait_data *lwd = data;
         struct ldlm_lock *lock = lwd->lwd_lock;
-        struct obd_device *obd = class_conn2obd(lock->l_connh);
+        struct obd_import *imp;
+        struct obd_device *obd;
 
-        if (obd == NULL) {
-                LDLM_ERROR(lock, "lock timed out; mot entering recovery in "
+        if (lock->l_conn_export == NULL) {
+                LDLM_ERROR(lock, "lock timed out; not entering recovery in "
                            "server code, just going back to sleep");
-        } else {
-                struct obd_import *imp = obd->u.cli.cl_import;
-                ptlrpc_fail_import(imp, lwd->lwd_generation);
-                LDLM_ERROR(lock, "lock timed out, entering recovery for %s@%s",
-                           imp->imp_target_uuid.uuid,
-                           imp->imp_connection->c_remote_uuid.uuid);
+                RETURN(0);
         }
-        
+
+        obd = lock->l_conn_export->exp_obd;
+        imp = obd->u.cli.cl_import;
+        ptlrpc_fail_import(imp, lwd->lwd_generation);
+        LDLM_ERROR(lock, "lock timed out, entering recovery for %s@%s",
+                   imp->imp_target_uuid.uuid,
+                   imp->imp_connection->c_remote_uuid.uuid);
+
         RETURN(0);
 }
 
@@ -69,17 +72,6 @@ int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data)
         struct obd_import *imp = NULL;
         int rc = 0;
         struct l_wait_info lwi;
-
-        obd = class_conn2obd(lock->l_connh);
-
-        /* if this is a local lock, then there is no import */
-        if (obd != NULL)
-                imp = obd->u.cli.cl_import;
-
-        lwd.lwd_lock = lock;
-
-        lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, ldlm_expired_completion_wait,
-                               interrupted_completion_wait, &lwd);
         ENTRY;
 
         if (flags == LDLM_FL_WAIT_NOREPROC)
@@ -99,7 +91,18 @@ int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data)
         ldlm_lock_dump(D_OTHER, lock, 0);
         ldlm_reprocess_all(lock->l_resource);
 
- noreproc:
+noreproc:
+
+        obd = class_exp2obd(lock->l_conn_export);
+
+        /* if this is a local lock, then there is no import */
+        if (obd != NULL)
+                imp = obd->u.cli.cl_import;
+
+        lwd.lwd_lock = lock;
+
+        lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, ldlm_expired_completion_wait,
+                               interrupted_completion_wait, &lwd);
         if (imp != NULL) {
                 spin_lock_irqsave(&imp->imp_lock, irqflags);
                 lwd.lwd_generation = imp->imp_generation;
@@ -161,8 +164,8 @@ static int ldlm_cli_enqueue_local(struct ldlm_namespace *ns,
         if (err != ELDLM_OK)
                 GOTO(out, err);
 
-        if (type == LDLM_EXTENT)
-                memcpy(cookie, &lock->l_extent, sizeof(lock->l_extent));
+        if (type != LDLM_PLAIN)
+                memcpy(cookie, &lock->l_policy_data, cookielen);
         if ((*flags) & LDLM_FL_LOCK_CHANGED)
                 memcpy(&res_id, &lock->l_resource->lr_name, sizeof(res_id));
 
@@ -180,7 +183,20 @@ static int ldlm_cli_enqueue_local(struct ldlm_namespace *ns,
         return err;
 }
 
-int ldlm_cli_enqueue(struct lustre_handle *connh,
+static void failed_lock_cleanup(struct ldlm_namespace *ns,
+                                struct ldlm_lock *lock,
+                                struct lustre_handle *lockh, int mode)
+{
+        /* Set a flag to prevent us from sending a CANCEL (bug 407) */
+        l_lock(&ns->ns_lock);
+        lock->l_flags |= LDLM_FL_LOCAL_ONLY;
+        LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
+        l_unlock(&ns->ns_lock);
+
+        ldlm_lock_decref_and_cancel(lockh, mode);
+}
+
+int ldlm_cli_enqueue(struct obd_export *exp,
                      struct ptlrpc_request *req,
                      struct ldlm_namespace *ns,
                      struct lustre_handle *parent_lock_handle,
@@ -201,9 +217,9 @@ int ldlm_cli_enqueue(struct lustre_handle *connh,
         ENTRY;
 
         is_replay = *flags & LDLM_FL_REPLAY;
-        LASSERT(connh != NULL || !is_replay);
+        LASSERT(exp != NULL || !is_replay);
 
-        if (connh == NULL) {
+        if (exp == NULL) {
                 rc = ldlm_cli_enqueue_local(ns, parent_lock_handle, res_id,
                                             type, cookie, cookielen, mode,
                                             flags, completion, blocking, data,
@@ -216,23 +232,22 @@ int ldlm_cli_enqueue(struct lustre_handle *connh,
         if (is_replay) {
                 lock = ldlm_handle2lock(lockh);
                 LDLM_DEBUG(lock, "client-side enqueue START");
-                LASSERT(connh == lock->l_connh);
+                LASSERT(exp == lock->l_conn_export);
         } else {
                 lock = ldlm_lock_create(ns, parent_lock_handle, res_id, type,
                                         mode, blocking, completion, data);
                 if (lock == NULL)
                         GOTO(out_nolock, rc = -ENOMEM);
-                LDLM_DEBUG(lock, "client-side enqueue START");
                 /* for the local lock, add the reference */
                 ldlm_lock_addref_internal(lock, mode);
                 ldlm_lock2handle(lock, lockh);
-                if (type == LDLM_EXTENT)
-                        memcpy(&lock->l_extent, cookie,
-                               sizeof(body->lock_desc.l_extent));
+                if (type != LDLM_PLAIN)
+                        memcpy(&lock->l_policy_data, cookie, cookielen);
+                LDLM_DEBUG(lock, "client-side enqueue START");
         }
 
         if (req == NULL) {
-                req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_ENQUEUE, 1,
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1,
                                       &size, NULL);
                 if (!req)
                         GOTO(out, rc = -ENOMEM);
@@ -255,7 +270,7 @@ int ldlm_cli_enqueue(struct lustre_handle *connh,
                 size = sizeof(*reply);
                 req->rq_replen = lustre_msg_size(1, &size);
         }
-        lock->l_connh = connh;
+        lock->l_conn_export = exp;
         lock->l_export = NULL;
         lock->l_blocking_ast = blocking;
 
@@ -266,48 +281,45 @@ int ldlm_cli_enqueue(struct lustre_handle *connh,
                 LASSERT(!is_replay);
                 LDLM_DEBUG(lock, "client-side enqueue END (%s)",
                            rc == ELDLM_LOCK_ABORTED ? "ABORTED" : "FAILED");
-                /* Set a flag to prevent us from sending a CANCEL (bug 407) */
-                l_lock(&ns->ns_lock);
-                lock->l_flags |= LDLM_FL_LOCAL_ONLY;
-                LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
-                l_unlock(&ns->ns_lock);
-
-                ldlm_lock_decref_and_cancel(lockh, mode);
-
+                failed_lock_cleanup(ns, lock, lockh, mode);
                 if (rc == ELDLM_LOCK_ABORTED) {
-                        /* caller expects reply buffer 0 to have been swabbed */
-                        reply = lustre_swab_repbuf(req, 0, sizeof (*reply),
+                        /* Before we return, swab the reply */
+                        reply = lustre_swab_repbuf(req, 0, sizeof(*reply),
                                                    lustre_swab_ldlm_reply);
                         if (reply == NULL) {
-                                CERROR ("Can't unpack ldlm_reply\n");
-                                GOTO (out_req, rc = -EPROTO);
+                                CERROR("Can't unpack ldlm_reply\n");
+                                GOTO(out_req, rc = -EPROTO);
                         }
                 }
                 GOTO(out_req, rc);
         }
 
-        reply = lustre_swab_repbuf(req, 0, sizeof (*reply),
+        reply = lustre_swab_repbuf(req, 0, sizeof(*reply),
                                    lustre_swab_ldlm_reply);
         if (reply == NULL) {
-                CERROR ("Can't unpack ldlm_reply\n");
-                GOTO (out_req, rc = -EPROTO);
+                CERROR("Can't unpack ldlm_reply\n");
+                GOTO(out_req, rc = -EPROTO);
         }
 
         memcpy(&lock->l_remote_handle, &reply->lock_handle,
                sizeof(lock->l_remote_handle));
         *flags = reply->lock_flags;
 
-        CDEBUG(D_INFO, "local: %p, remote cookie: "LPX64", flags: %d\n", lock,
-               reply->lock_handle.cookie, *flags);
+        CDEBUG(D_INFO, "local: %p, remote cookie: "LPX64", flags: 0x%x\n",
+               lock, reply->lock_handle.cookie, *flags);
         if (type == LDLM_EXTENT) {
                 CDEBUG(D_INFO, "requested extent: "LPU64" -> "LPU64", got "
                        "extent "LPU64" -> "LPU64"\n",
-                       body->lock_desc.l_extent.start,
-                       body->lock_desc.l_extent.end,
-                       reply->lock_extent.start, reply->lock_extent.end);
+                       body->lock_desc.l_policy_data.l_extent.start,
+                       body->lock_desc.l_policy_data.l_extent.end,
+                       reply->lock_policy_data.l_extent.start,
+                       reply->lock_policy_data.l_extent.end);
 
-                cookie = &reply->lock_extent; /* FIXME bug 267 */
-                cookielen = sizeof(reply->lock_extent);
+                cookie = &reply->lock_policy_data; /* FIXME bug 267 */
+                cookielen = sizeof(struct ldlm_extent);
+        } else if (type == LDLM_FLOCK) {
+                cookie = &reply->lock_policy_data;
+                cookielen = sizeof(struct ldlm_flock);
         }
 
         /* If enqueue returned a blocked lock but the completion handler has
@@ -338,11 +350,22 @@ int ldlm_cli_enqueue(struct lustre_handle *connh,
                         LDLM_DEBUG(lock, "client-side enqueue, new resource");
                 }
         }
+        if ((*flags) & LDLM_FL_AST_SENT) {
+                l_lock(&ns->ns_lock);
+                lock->l_flags |= LDLM_FL_CBPENDING;
+                l_unlock(&ns->ns_lock);
+                LDLM_DEBUG(lock, "enqueue reply includes blocking AST");
+        }
 
         if (!is_replay) {
                 rc = ldlm_lock_enqueue(ns, &lock, cookie, cookielen, flags);
-                if (lock->l_completion_ast)
-                        lock->l_completion_ast(lock, *flags, NULL);
+                if (lock->l_completion_ast != NULL) {
+                        int err = lock->l_completion_ast(lock, *flags, NULL);
+                        if (err)
+                                failed_lock_cleanup(ns, lock, lockh, mode);
+                        if (!rc)
+                                rc = err;
+                }
         }
 
         LDLM_DEBUG(lock, "client-side enqueue END");
@@ -362,7 +385,7 @@ int ldlm_cli_replay_enqueue(struct ldlm_lock *lock)
         struct ldlm_res_id junk;
         int flags = LDLM_FL_REPLAY;
         ldlm_lock2handle(lock, &lockh);
-        return ldlm_cli_enqueue(lock->l_connh, NULL, NULL, NULL, junk,
+        return ldlm_cli_enqueue(lock->l_conn_export, NULL, NULL, NULL, junk,
                                 lock->l_resource->lr_type, NULL, 0, -1, &flags,
                                 NULL, NULL, NULL, &lockh);
 }
@@ -390,7 +413,6 @@ static int ldlm_cli_convert_local(struct ldlm_lock *lock, int new_mode,
 int ldlm_cli_convert(struct lustre_handle *lockh, int new_mode, int *flags)
 {
         struct ldlm_request *body;
-        struct lustre_handle *connh;
         struct ldlm_reply *reply;
         struct ldlm_lock *lock;
         struct ldlm_resource *res;
@@ -404,15 +426,14 @@ int ldlm_cli_convert(struct lustre_handle *lockh, int new_mode, int *flags)
                 RETURN(-EINVAL);
         }
         *flags = 0;
-        connh = lock->l_connh;
 
-        if (!connh)
+        if (lock->l_conn_export == NULL)
                 RETURN(ldlm_cli_convert_local(lock, new_mode, flags));
 
         LDLM_DEBUG(lock, "client-side convert");
 
-        req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_CONVERT, 1, &size,
-                              NULL);
+        req = ptlrpc_prep_req(class_exp2cliimp(lock->l_conn_export), 
+                              LDLM_CONVERT, 1, &size, NULL);
         if (!req)
                 GOTO(out, rc = -ENOMEM);
 
@@ -464,7 +485,7 @@ int ldlm_cli_cancel(struct lustre_handle *lockh)
         if (lock == NULL)
                 RETURN(0);
 
-        if (lock->l_connh) {
+        if (lock->l_conn_export) {
                 int local_only;
                 struct obd_import *imp;
 
@@ -482,7 +503,7 @@ int ldlm_cli_cancel(struct lustre_handle *lockh)
                         goto local_cancel;
                 }
 
-                imp = class_conn2cliimp(lock->l_connh);
+                imp = class_exp2cliimp(lock->l_conn_export);
                 if (imp == NULL || imp->imp_invalid) {
                         CDEBUG(D_HA, "skipping cancel on invalid import %p\n",
                                imp);
@@ -612,9 +633,9 @@ static int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
                 struct ldlm_lock *lock;
                 lock = list_entry(tmp, struct ldlm_lock, l_res_link);
 
-                if (opaque != NULL && lock->l_data != opaque) {
+                if (opaque != NULL && lock->l_ast_data != opaque) {
                         LDLM_ERROR(lock, "data %p doesn't match opaque %p",
-				   lock->l_data, opaque);
+                                   lock->l_ast_data, opaque);
                         //LBUG();
                         continue;
                 }
@@ -873,7 +894,7 @@ static int replay_one_lock(struct obd_import *imp, struct ldlm_lock *lock)
                 RETURN(-ENOMEM);
 
         /* We're part of recovery, so don't wait for it. */
-        req->rq_level = LUSTRE_CONN_RECOVER;
+        req->rq_send_state = LUSTRE_IMP_REPLAY;
 
         body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
         ldlm_lock2desc(lock, &body->lock_desc);
diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c
index eb6ab1bd353274df171437b30a26c607ad73f6b0..59f04786a61f2d21cc3d5f1ccae4f2ce04e70eac 100644
--- a/lustre/ldlm/ldlm_resource.c
+++ b/lustre/ldlm/ldlm_resource.c
@@ -35,32 +35,86 @@ kmem_cache_t *ldlm_resource_slab, *ldlm_lock_slab;
 
 spinlock_t ldlm_namespace_lock = SPIN_LOCK_UNLOCKED;
 struct list_head ldlm_namespace_list = LIST_HEAD_INIT(ldlm_namespace_list);
-static struct proc_dir_entry *ldlm_ns_proc_dir = NULL;
+struct proc_dir_entry *ldlm_type_proc_dir = NULL;
+struct proc_dir_entry *ldlm_ns_proc_dir = NULL;
+struct proc_dir_entry *ldlm_svc_proc_dir = NULL;
 
-int ldlm_proc_setup(struct obd_device *obd)
+#ifdef __KERNEL__
+static int ldlm_proc_dump_ns(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+        ldlm_dump_all_namespaces();
+        RETURN(count);
+}
+
+int ldlm_proc_setup(void)
 {
         int rc;
+        struct lprocfs_vars list[] = { 
+                { "dump_namespaces", NULL, ldlm_proc_dump_ns, NULL },
+                { NULL }};
         ENTRY;
         LASSERT(ldlm_ns_proc_dir == NULL);
-        LASSERT(obd != NULL);
-        rc = lprocfs_obd_attach(obd, 0);
-        if (rc) {
+
+        ldlm_type_proc_dir = lprocfs_register(OBD_LDLM_DEVICENAME,
+                                               proc_lustre_root,
+                                               NULL, NULL);
+        if (IS_ERR(ldlm_type_proc_dir)) {
                 CERROR("LProcFS failed in ldlm-init\n");
-                RETURN(rc);
+                rc = PTR_ERR(ldlm_type_proc_dir);
+                GOTO(err, rc);
         }
-        ldlm_ns_proc_dir = obd->obd_proc_entry;
+
+        ldlm_ns_proc_dir = lprocfs_register("namespaces",
+                                            ldlm_type_proc_dir,
+                                            NULL, NULL);
+        if (IS_ERR(ldlm_ns_proc_dir)) {
+                CERROR("LProcFS failed in ldlm-init\n");
+                rc = PTR_ERR(ldlm_ns_proc_dir);
+                GOTO(err_type, rc);
+        }
+
+        ldlm_svc_proc_dir = lprocfs_register("services",
+                                            ldlm_type_proc_dir,
+                                            NULL, NULL);
+        if (IS_ERR(ldlm_svc_proc_dir)) {
+                CERROR("LProcFS failed in ldlm-init\n");
+                rc = PTR_ERR(ldlm_svc_proc_dir);
+                GOTO(err_ns, rc);
+        }
+
+        rc = lprocfs_add_vars(ldlm_type_proc_dir, list, NULL);
+
         RETURN(0);
+
+err_ns:        
+        lprocfs_remove(ldlm_ns_proc_dir);
+err_type:        
+        lprocfs_remove(ldlm_type_proc_dir);
+err:
+        ldlm_type_proc_dir = NULL;
+        ldlm_ns_proc_dir = NULL;
+        ldlm_svc_proc_dir = NULL;
+        RETURN(rc);
 }
 
-void ldlm_proc_cleanup(struct obd_device *obd)
+void ldlm_proc_cleanup(void)
 {
+        if (ldlm_svc_proc_dir) {
+                lprocfs_remove(ldlm_svc_proc_dir);
+                ldlm_svc_proc_dir = NULL;
+        }
+
         if (ldlm_ns_proc_dir) {
-                lprocfs_obd_detach(obd);
+                lprocfs_remove(ldlm_ns_proc_dir);
                 ldlm_ns_proc_dir = NULL;
         }
+
+        if (ldlm_type_proc_dir) {
+                lprocfs_remove(ldlm_type_proc_dir);
+                ldlm_type_proc_dir = NULL;
+        }
 }
 
-#ifdef __KERNEL__
 static int lprocfs_uint_rd(char *page, char **start, off_t off,
                            int count, int *eof, void *data)
 {
@@ -152,11 +206,18 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client)
 {
         struct ldlm_namespace *ns = NULL;
         struct list_head *bucket;
+        int rc;
         ENTRY;
 
+        rc = ldlm_get_ref();
+        if (rc) {
+                CERROR("ldlm_get_ref failed: %d\n", rc);
+                RETURN(NULL);
+        }
+
         OBD_ALLOC(ns, sizeof(*ns));
         if (!ns)
-                RETURN(NULL);
+                GOTO(out_ref, NULL);
 
         OBD_VMALLOC(ns->ns_hash, sizeof(*ns->ns_hash) * RES_HASH_SIZE);
         if (!ns->ns_hash)
@@ -197,21 +258,24 @@ out_hash:
         OBD_VFREE(ns->ns_hash, sizeof(*ns->ns_hash) * RES_HASH_SIZE);
 out_ns:
         OBD_FREE(ns, sizeof(*ns));
-        return NULL;
+out_ref:
+        ldlm_put_ref(0);
+        RETURN(NULL);
 }
 
 extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
 
-/* If 'local_only' is true, don't try to tell the server, just cleanup.
+/* If flags contains FL_LOCAL_ONLY, don't try to tell the server, just cleanup.
  * This is currently only used for recovery, and we make certain assumptions
  * as a result--notably, that we shouldn't cancel locks with refs. -phil
  *
  * Called with the ns_lock held. */
 static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
-                             int local_only)
+                             int flags)
 {
         struct list_head *tmp, *pos;
         int rc = 0, client = res->lr_namespace->ns_client;
+        int local_only = (flags & LDLM_FL_LOCAL_ONLY);
         ENTRY;
 
         list_for_each_safe(tmp, pos, q) {
@@ -227,15 +291,15 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
                         lock->l_flags |= LDLM_FL_CBPENDING;
                         /* ... without sending a CANCEL message. */
                         lock->l_flags |= LDLM_FL_LOCAL_ONLY;
+                        /* caller may also specify additional flags */
+                        lock->l_flags |= flags;
                         LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
-                        /* ... and without calling the cancellation callback */
-                        lock->l_flags |= LDLM_FL_CANCEL;
                         LDLM_LOCK_PUT(lock);
                         continue;
                 }
 
-                /* At shutdown time, don't call the cancellation callback */
-                lock->l_flags |= LDLM_FL_CANCEL;
+ 
+                lock->l_flags |= flags;
 
                 if (client) {
                         struct lustre_handle lockh;
@@ -260,7 +324,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
         EXIT;
 }
 
-int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only)
+int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags)
 {
         int i;
 
@@ -277,15 +341,16 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only)
                         res = list_entry(tmp, struct ldlm_resource, lr_hash);
                         ldlm_resource_getref(res);
 
-                        cleanup_resource(res, &res->lr_granted, local_only);
-                        cleanup_resource(res, &res->lr_converting, local_only);
-                        cleanup_resource(res, &res->lr_waiting, local_only);
+                        cleanup_resource(res, &res->lr_granted, flags);
+                        cleanup_resource(res, &res->lr_converting, flags);
+                        cleanup_resource(res, &res->lr_waiting, flags);
 
                         /* XXX what a mess: don't force cleanup if we're
                          * local_only (which is only used by recovery).  In that
                          * case, we probably still have outstanding lock refs
                          * which reference these resources. -phil */
-                        if (!ldlm_resource_putref(res) && !local_only) {
+                        if (!ldlm_resource_putref(res) &&
+                            !(flags & LDLM_FL_LOCAL_ONLY)) {
                                 CERROR("Resource refcount nonzero (%d) after "
                                        "lock cleanup; forcing cleanup.\n",
                                        atomic_read(&res->lr_refcount));
@@ -301,7 +366,7 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only)
 }
 
 /* Cleanup, but also free, the namespace */
-int ldlm_namespace_free(struct ldlm_namespace *ns)
+int ldlm_namespace_free(struct ldlm_namespace *ns, int force)
 {
         if (!ns)
                 RETURN(ELDLM_OK);
@@ -311,13 +376,29 @@ int ldlm_namespace_free(struct ldlm_namespace *ns)
 
         spin_unlock(&ldlm_namespace_lock);
 
-        ldlm_namespace_cleanup(ns, 0);
+        /* At shutdown time, don't call the cancellation callback */
+        ldlm_namespace_cleanup(ns, LDLM_FL_CANCEL);
+
+#ifdef __KERNEL__
+        {
+                struct proc_dir_entry *dir;
+                dir = lprocfs_srch(ldlm_ns_proc_dir, ns->ns_name);
+                if (dir == NULL) {
+                        CERROR("dlm namespace %s has no procfs dir?\n",
+                               ns->ns_name);
+                } else {
+                        lprocfs_remove(dir);
+                }
+        }
+#endif
 
         POISON(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE);
         OBD_VFREE(ns->ns_hash, sizeof(*ns->ns_hash) * RES_HASH_SIZE);
         OBD_FREE(ns->ns_name, strlen(ns->ns_name) + 1);
         OBD_FREE(ns, sizeof(*ns));
 
+        ldlm_put_ref(force);
+
         return ELDLM_OK;
 }
 
@@ -442,6 +523,8 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
 
 struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res)
 {
+        LASSERT(res != NULL);
+        LASSERT(res != (void *)0x5a5a5a5a);
         atomic_inc(&res->lr_refcount);
         CDEBUG(D_INFO, "getref res: %p count: %d\n", res,
                atomic_read(&res->lr_refcount));
@@ -494,9 +577,9 @@ int ldlm_resource_putref(struct ldlm_resource *res)
                 ns->ns_refcount--;
                 list_del_init(&res->lr_hash);
                 list_del_init(&res->lr_childof);
+                l_unlock(&ns->ns_lock);
 
                 OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
-                l_unlock(&ns->ns_lock);
 
                 spin_lock(&ns->ns_counter_lock);
                 ns->ns_resources--;
@@ -580,18 +663,14 @@ void ldlm_namespace_dump(struct ldlm_namespace *ns)
 void ldlm_resource_dump(struct ldlm_resource *res)
 {
         struct list_head *tmp;
-        char name[256];
         int pos;
 
-        if (RES_NAME_SIZE != 3)
+        if (RES_NAME_SIZE != 4)
                 LBUG();
 
-        snprintf(name, sizeof(name), "%Lx %Lx %Lx",
-                 (unsigned long long)res->lr_name.name[0],
-                 (unsigned long long)res->lr_name.name[1],
-                 (unsigned long long)res->lr_name.name[2]);
-
-        CDEBUG(D_OTHER, "--- Resource: %p (%s) (rc: %d)\n", res, name,
+        CDEBUG(D_OTHER, "--- Resource: %p ("LPU64"/"LPU64"/"LPU64"/"LPU64
+               ") (rc: %d)\n", res, res->lr_name.name[0], res->lr_name.name[1],
+               res->lr_name.name[2], res->lr_name.name[3],
                atomic_read(&res->lr_refcount));
         CDEBUG(D_OTHER, "Namespace: %p (%s)\n", res->lr_namespace,
                res->lr_namespace->ns_name);
diff --git a/lustre/ldlm/ldlm_test.c b/lustre/ldlm/ldlm_test.c
index 6cf10563c658f4e33b93be797c60f7fb5e84b5a1..5381b5b2d8d0efc5623e010b257d0144c901661b 100644
--- a/lustre/ldlm/ldlm_test.c
+++ b/lustre/ldlm/ldlm_test.c
@@ -197,7 +197,7 @@ int ldlm_test_basics(struct obd_device *obddev)
                 ldlm_reprocess_all(res);
 
         ldlm_resource_dump(res);
-        ldlm_namespace_free(ns);
+        ldlm_namespace_free(ns, 0);
 
         RETURN(0);
 }
@@ -267,7 +267,7 @@ int ldlm_test_extents(struct obd_device *obddev)
         if (res == NULL)
                 LBUG();
         ldlm_resource_dump(res);
-        ldlm_namespace_free(ns);
+        ldlm_namespace_free(ns, 0);
 
         RETURN(0);
 }
diff --git a/lustre/liblustre/Makefile.am b/lustre/liblustre/Makefile.am
index 6648aa8e8eb227e5f48c02398f9e26bdc24abb58..ef4fa2fe93d64404a15bb3b02bca54562c44f886 100644
--- a/lustre/liblustre/Makefile.am
+++ b/lustre/liblustre/Makefile.am
@@ -1,30 +1,63 @@
-# Administration utilities Makefile
+## Liblustre excecutables & libraries Makefile
 DEFS=
 
-CFLAGS:=-g -I$(top_srcdir)/utils -I$(top_srcdir)/portals/include  -I$(srcdir)/../include -I$(top_srcdir)/../libsysio/include -Wall -L../portals/utils
+CFLAGS := -g -Wall -I$(top_srcdir)/utils -I$(top_srcdir)/portals/include \
+          -I$(top_srcdir)/portals/unals -I$(SYSIO)/include \
+          -I/opt/lam/include -L/opt/lam/lib
 
 KFLAGS:=
 CPPFLAGS = $(HAVE_EFENCE) -D_LARGEFILE64_SOURCE=1
 LIBS = $(LIBEFENCE)
-LLIBS= ./libllite.a ../lov/liblov.a ../obdecho/libobdecho.a ../osc/libosc.a ../ldlm/libldlm.a  ../ptlrpc/libptlrpc.a ../obdclass/liblustreclass.a ../mdc/libmdc.a
 
-lib_LIBRARIES = libllite.a
-libllite_a_SOURCES = llite_lib.c super.c file.c rw.c
+## lustre components libs
+LLIBS := ./libllite.a \
+         ../lov/liblov.a \
+         ../obdecho/libobdecho.a \
+         ../osc/libosc.a \
+         ../mdc/libmdc.a \
+         ../ldlm/libldlm.a \
+         ../ptlrpc/libptlrpc.a \
+         ../obdclass/liblustreclass.a \
+	 ../lvfs/liblvfs.a
 
-bin_PROGRAMS = libtest lltest
+## portals components libs
+PTLLIBS := ../portals/utils/libptlctl.a \
+	   ../portals/unals/libtcpnal.a \
+           ../portals/portals/libportals.a
 
-libtest_LDADD := $(LIBREADLINE)  $(LLIBS) \
-                 ../portals/unals/libtpcnal.a \
-                 ../portals/portals/libportals.a\
-	          -lptlctl -lpthread 
-libtest_SOURCES = libtest.c
+## sysio components libs
+SYSIOLIBS := $(SYSIO)/drivers/native/libsysio_native.a \
+             $(SYSIO)/drivers/sockets/libsysio_sockets.a \
+             $(SYSIO)/src/libsysio.a \
+             $(SYSIO)/dev/stdfd/libsysio_stdfd.a
+
+LLIB_EXEC= $(PTLLIBS) $(SYSIOLIBS) -lpthread
+
+lib_LIBRARIES = 
+noinst_LIBRARIES = libllite.a libtestcommon.a
+libllite_a_SOURCES = llite_lib.c super.c namei.c rw.c file.c
+libtestcommon_a_SOURCES = test_common.c
+
+bin_PROGRAMS = libtest lltest recovery_small replay_single #test_lock_cancel
+
+libtest_SOURCES = libtest.c  ../utils/parser.c ../utils/obd.c ../utils/lustre_cfg.c
+libtest_LDADD := $(LLIBS) $(PTLLIBS) \
+                 $(LIBREADLINE) -lpthread 
+
+liblustre.a : libllite.a
+	$(shell ./genlib.sh $(SYSIO) $(AR) $(LINK))
 
-lltest_LDADD := $(LIBREADLINE)  $(LLIBS) \
-                ../../libsysio/src/libsysio.a ../../libsysio/dev/stdfd/libsysio_stdfd.a \
-                -lc \
-                ../portals/unals/libtcpnal.a ../portals/portals/libportals.a \
-		-lptlctl -lpthread
 lltest_SOURCES = lltest.c
+lltest_LDADD := ./libtestcommon.a $(LLIBS) $(LLIB_EXEC) $(LIBREADLINE)
+
+recovery_small_SOURCES = recovery_small.c
+recovery_small_LDADD := ./libtestcommon.a $(LLIBS) $(LLIB_EXEC) $(LIBREADLINE)
+
+replay_single_SOURCES = replay_single.c
+replay_single_LDADD := ./libtestcommon.a $(LLIBS) $(LLIB_EXEC) $(LIBREADLINE)
+
+#test_lock_cancel_SOURCES = test_lock_cancel.c
+#test_lock_cancel_LDADD :=  $(LLIBS) $(LLIB_EXEC) -lmpi -llam
 
 include $(top_srcdir)/Rules
 
diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c
index 88af0473db00bd28a0a6fde2f688d72a232653ed..58339c83df3e35cbc70c6ebe847d9d1fed4d85a2 100644
--- a/lustre/liblustre/file.c
+++ b/lustre/liblustre/file.c
@@ -25,7 +25,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <error.h>
 #include <assert.h>
 #include <time.h>
 #include <sys/types.h>
@@ -46,123 +45,51 @@ void llu_prepare_mdc_op_data(struct mdc_op_data *data,
                              int namelen,
                              int mode)
 {
-        struct llu_inode_info *lli1, *lli2;
-
         LASSERT(i1);
-
-        lli1 = llu_i2info(i1);
-        data->ino1 = lli1->lli_st_ino;
-        data->gen1 = lli1->lli_st_generation;
-        data->typ1 = lli1->lli_st_mode & S_IFMT;
-        data->gid1 = lli1->lli_st_gid;
+        
+        ll_i2uctxt(&data->ctxt, i1, i2);
+        ll_inode2fid(&data->fid1, i1);
 
         if (i2) {
-                lli2 = llu_i2info(i2);
-                data->ino2 = lli2->lli_st_ino;
-                data->gen2 = lli2->lli_st_generation;
-                data->typ2 = lli2->lli_st_mode & S_IFMT;
-                data->gid2 = lli2->lli_st_gid;
-        } else
-                data->ino2 = 0;
+                ll_inode2fid(&data->fid2, i2);
+        }
 
         data->name = name;
         data->namelen = namelen;
-        data->mode = mode;
+        data->create_mode = mode;
+        data->mod_time = CURRENT_TIME;
 }
 
-static struct inode *llu_create_node(struct inode *dir, const char *name,
-                                     int namelen, const void *data, int datalen,
-                                     int mode, __u64 extra,
-                                     struct lookup_intent *it)
+void obdo_refresh_inode(struct inode *dst,
+                        struct obdo *src,
+                        obd_flag valid)
 {
-        struct inode *inode;
-        struct ptlrpc_request *request = NULL;
-        struct mds_body *body;
-        time_t time = 123456;//time(NULL);
-        struct llu_sb_info *sbi = llu_i2sbi(dir);
-
-        if (it && it->it_disposition) {
-                LBUG();
-#if 0
-                ll_invalidate_inode_pages(dir);
-#endif
-                request = it->it_data;
-                body = lustre_msg_buf(request->rq_repmsg, 1, sizeof(*body));
-        } else {
-                struct mdc_op_data op_data;
-                struct llu_inode_info *lli_dir = llu_i2info(dir);
-                int gid = current->fsgid;
-                int rc;
-
-                if (lli_dir->lli_st_mode & S_ISGID) {
-                        gid = lli_dir->lli_st_gid;
-                        if (S_ISDIR(mode))
-                                mode |= S_ISGID;
-                }
-
-                llu_prepare_mdc_op_data(&op_data, dir, NULL, name, namelen, 0);
-                rc = mdc_create(&sbi->ll_mdc_conn, &op_data,
-                                data, datalen, mode, current->fsuid, gid,
-                                time, extra, &request);
-                if (rc) {
-                        inode = (struct inode*)rc;
-                        goto out;
-                }
-                body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
-        }
-
-        inode = llu_new_inode(dir->i_fs, body->ino, body->mode);
-        if (!inode) {
-                /* FIXME more cleanup needed? */
-                goto out;
-        }
-
-        llu_update_inode(inode, body, NULL);
-
-        if (it && it->it_disposition) {
-                /* We asked for a lock on the directory, but were
-                 * granted a lock on the inode.  Since we finally have
-                 * an inode pointer, stuff it in the lock. */
-#if 0
-                ll_mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle,
-                                      inode);
-#endif
-        }
-
- out:
-        ptlrpc_req_finished(request);
-        return inode;
+        struct llu_inode_info *lli = llu_i2info(dst);
+        valid &= src->o_valid;
+
+        if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
+                CDEBUG(D_INODE, "valid %x, cur time %lu/%lu, new %lu/%lu\n",
+                       src->o_valid, LTIME_S(lli->lli_st_mtime), 
+                       LTIME_S(lli->lli_st_ctime),
+                       (long)src->o_mtime, (long)src->o_ctime);
+
+        if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(lli->lli_st_atime))
+                LTIME_S(lli->lli_st_atime) = src->o_atime;
+        if (valid & OBD_MD_FLMTIME && src->o_mtime > LTIME_S(lli->lli_st_mtime))
+                LTIME_S(lli->lli_st_mtime) = src->o_mtime;
+        if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(lli->lli_st_ctime))
+                LTIME_S(lli->lli_st_ctime) = src->o_ctime;
+        if (valid & OBD_MD_FLSIZE && src->o_size > lli->lli_st_size)
+                lli->lli_st_size = src->o_size;
+        /* optimum IO size */
+        if (valid & OBD_MD_FLBLKSZ)
+                lli->lli_st_blksize = src->o_blksize;
+        /* allocation of space */
+        if (valid & OBD_MD_FLBLOCKS && src->o_blocks > lli->lli_st_blocks)
+                lli->lli_st_blocks = src->o_blocks;
 }
 
-int llu_create(struct inode *dir, struct pnode_base *pnode, int mode)
-{
-        struct inode *inode;
 #if 0
-        int rc = 0;
-
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,intent=%s\n",
-               dentry->d_name.name, dir->i_ino, LL_IT2STR(dentry->d_it));
-
-        it = dentry->d_it;
-
-        rc = ll_it_open_error(DISP_OPEN_CREATE, it);
-        if (rc) {
-                LL_GET_INTENT(dentry, it);
-                ptlrpc_req_finished(it->it_data);
-                RETURN(rc);
-        }
-#endif
-        inode = llu_create_node(dir, pnode->pb_name.name, pnode->pb_name.len,
-                                NULL, 0, mode, 0, NULL);
-
-        if (IS_ERR(inode))
-                RETURN(PTR_ERR(inode));
-
-        pnode->pb_ino = inode;
-
-        return 0;
-}
-
 static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
                           struct lov_stripe_md *lsm)
 {
@@ -172,6 +99,7 @@ static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
         struct obdo *oa;
         struct iattr iattr;
         struct mdc_op_data op_data;
+        struct obd_trans_info oti = { 0 };
         int rc, err, lmm_size = 0;;
         ENTRY;
 
@@ -179,18 +107,24 @@ static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
         if (!oa)
                 RETURN(-ENOMEM);
 
+        LASSERT(S_ISREG(inode->i_mode));
         oa->o_mode = S_IFREG | 0600;
         oa->o_id = lli->lli_st_ino;
+        oa->o_generation = lli->lli_st_generation;
         /* Keep these 0 for now, because chown/chgrp does not change the
          * ownership on the OST, and we don't want to allow BA OST NFS
          * users to access these objects by mistake.
          */
         oa->o_uid = 0;
         oa->o_gid = 0;
-        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE |
-                OBD_MD_FLUID | OBD_MD_FLGID;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGENER | OBD_MD_FLTYPE |
+                OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID;
+
+        obdo_from_inode(oa, inode, OBD_MD_FLTYPE|OBD_MD_FLATIME|OBD_MD_FLMTIME|
+                        OBD_MD_FLCTIME |
+                        (llu_i2info(inode)->lli_st_size ? OBD_MD_FLSIZE : 0));
 
-        rc = obd_create(conn, oa, &lsm, NULL);
+        rc = obd_create(conn, oa, &lsm, &oti);
         if (rc) {
                 CERROR("error creating objects for inode %lu: rc = %d\n",
                        lli->lli_st_ino, rc);
@@ -200,6 +134,7 @@ static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
                 }
                 GOTO(out_oa, rc);
         }
+        obdo_refresh_inode(inode, oa, OBD_MD_FLBLKSZ);
 
         LASSERT(lsm && lsm->lsm_object_id);
         rc = obd_packmd(conn, &lmm, lsm);
@@ -215,7 +150,8 @@ static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
         llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
 
         rc = mdc_setattr(&llu_i2sbi(inode)->ll_mdc_conn, &op_data,
-                         &iattr, lmm, lmm_size, &req);
+                         &iattr, lmm, lmm_size, oti.oti_logcookies,
+                         oti.oti_numcookies * sizeof(oti.oti_onecookie), &req);
         ptlrpc_req_finished(req);
 
         obd_free_diskmd(conn, &lmm);
@@ -229,16 +165,19 @@ static int llu_create_obj(struct lustre_handle *conn, struct inode *inode,
                 GOTO(out_destroy, rc);
         }
         lli->lli_smd = lsm;
+        lli->lli_maxbytes = lsm->lsm_maxbytes;
 
         EXIT;
 out_oa:
+        oti_free_cookies(&oti);
         obdo_free(oa);
         return rc;
 
 out_destroy:
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
         oa->o_id = lsm->lsm_object_id;
-        oa->o_valid |= OBD_MD_FLID;
+        oa->o_valid = OBD_MD_FLID;
+        obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
+
         err = obd_destroy(conn, oa, lsm, NULL);
         obd_free_memmd(conn, &lsm);
         if (err) {
@@ -247,33 +186,42 @@ out_destroy:
         }
         goto out_oa;
 }
+#endif
 
-/* FIXME currently no "it" passed in */
 static int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it)
 {
+        struct ptlrpc_request *req = it->d.lustre.it_data;
         struct ll_file_data *fd;
-#if 0
-        struct ptlrpc_request *req = it->it_data;
-        struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1);
+        struct mds_body *body;
         ENTRY;
-#endif
+
+        body = lustre_msg_buf (req->rq_repmsg, 1, sizeof (*body));
+        LASSERT (body != NULL);                 /* reply already checked out */
+        LASSERT_REPSWABBED (req, 1);            /* and swabbed down */
+
+        /* already opened? */
+        if (lli->lli_open_count++)
+                RETURN(0);
+                
         LASSERT(!lli->lli_file_data);
 
-        fd = malloc(sizeof(struct ll_file_data));
+        OBD_ALLOC(fd, sizeof(*fd));
         /* We can't handle this well without reorganizing ll_file_open and
          * ll_mdc_close, so don't even try right now. */
         LASSERT(fd != NULL);
 
         memset(fd, 0, sizeof(*fd));
-#if 0
+
         memcpy(&fd->fd_mds_och.och_fh, &body->handle, sizeof(body->handle));
-        fd->fd_mds_och.och_req = it->it_data;
-#endif
+        fd->fd_mds_och.och_magic = OBD_CLIENT_HANDLE_MAGIC;
         lli->lli_file_data = fd;
 
+        mdc_set_open_replay_data(&fd->fd_mds_och, it->d.lustre.it_data);
+
         RETURN(0);
 }
 
+#if 0
 static int llu_osc_open(struct lustre_handle *conn, struct inode *inode,
                         struct lov_stripe_md *lsm)
 {
@@ -293,7 +241,7 @@ static int llu_osc_open(struct lustre_handle *conn, struct inode *inode,
         if (rc)
                 GOTO(out, rc);
 
-//        file->f_flags &= ~O_LOV_DELAY_CREATE;
+        /* file->f_flags &= ~O_LOV_DELAY_CREATE; */
         obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS | OBD_MD_FLMTIME |
                       OBD_MD_FLCTIME);
 
@@ -302,40 +250,55 @@ out:
         obdo_free(oa);
         return rc;
 }
+#endif
 
-static int llu_file_open(struct inode *inode)
+
+int llu_iop_open(struct pnode *pnode, int flags, mode_t mode)
 {
-#if 0
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-#endif
+        struct inode *inode = pnode->p_base->pb_ino;
         struct llu_inode_info *lli = llu_i2info(inode);
-        struct lustre_handle *conn = llu_i2obdconn(inode);
+        struct ll_file_data *fd;
+        struct ptlrpc_request *request;
         struct lookup_intent *it;
         struct lov_stripe_md *lsm;
         int rc = 0;
+        ENTRY;
 
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
+        LL_GET_INTENT(inode, it);
+
+        if (!it->d.lustre.it_disposition) {
 #if 0
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
-        LL_GET_INTENT(file->f_dentry, it);
-        rc = ll_it_open_error(DISP_OPEN_OPEN, it);
-        if (rc)
-                RETURN(rc);
+                struct lookup_intent oit = { .it_op = IT_OPEN,
+                                             .it_flags = file->f_flags };
+                it = &oit;
+                rc = ll_intent_file_open(file, NULL, 0, it);
+                if (rc)
+                        GOTO(out_release, rc);
 #endif
+                CERROR("fixme!!\n");
+        }
+
+        rc = it_open_error(DISP_OPEN_OPEN, it);
+        if (rc)
+                GOTO(out_release, rc);
+
         rc = llu_local_open(lli, it);
         if (rc)
                 LBUG();
-#if 0
-        mdc_set_open_replay_data(&((struct ll_file_data *)
-				  file->private_data)->fd_mds_och);
-#endif
+
+        if (!S_ISREG(lli->lli_st_mode))
+                GOTO(out_release, rc = 0);
+                
+        fd = lli->lli_file_data;
+
         lsm = lli->lli_smd;
         if (lsm == NULL) {
-#if 0
-                if (file->f_flags & O_LOV_DELAY_CREATE) {
-                        CDEBUG(D_INODE, "delaying object creation\n");
-                        RETURN(0);
+                if (fd->fd_flags & O_LOV_DELAY_CREATE) {
+                        CDEBUG(D_INODE, "object creation was delayed\n");
+                        GOTO(out_release, rc);
                 }
-#endif
+#if 0
                 if (!lli->lli_smd) {
                         rc = llu_create_obj(conn, inode, NULL);
                         if (rc)
@@ -345,149 +308,164 @@ static int llu_file_open(struct inode *inode)
                                lli->lli_st_ino);
                 }
                 lsm = lli->lli_smd;
+#endif
         }
+        fd->fd_flags &= ~O_LOV_DELAY_CREATE;
 
-        rc = llu_osc_open(conn, inode, lsm);
-        if (rc)
-                GOTO(out_close, rc);
-        RETURN(0);
+ out_release:
+        request = it->d.lustre.it_data;
+        ptlrpc_req_finished(request);
 
- out_close:
-//        ll_mdc_close(&sbi->ll_mdc_conn, inode, file);
-        return rc;
+        it->it_op_release(it);
+        OBD_FREE(it, sizeof(*it));
+
+        RETURN(rc);
 }
 
-int llu_iop_open(struct pnode *pnode, int flags, mode_t mode)
+int llu_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
 {
-        struct inode *dir = pnode->p_parent->p_base->pb_ino;
+        struct mds_body *body;
+        struct lov_mds_md *eadata;
+        struct lov_stripe_md *lsm = NULL;
+        struct obd_trans_info oti = { 0 };
+        struct obdo *oa;
         int rc;
-        /* FIXME later we must add the ldlm here */
+        ENTRY;
 
-        LASSERT(dir);
+        /* req is swabbed so this is safe */
+        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
 
-        /* libsysio forgot to guarentee mode is valid XXX */
-        mode |= S_IFREG;
+        if (!(body->valid & OBD_MD_FLEASIZE))
+                RETURN(0);
 
-        if (!pnode->p_base->pb_ino) {
-                rc = llu_create(dir, pnode->p_base, mode);
-                if (rc)
-                        return rc;
+        if (body->eadatasize == 0) {
+                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
+                GOTO(out, rc = -EPROTO);
         }
 
-        LASSERT(pnode->p_base->pb_ino);
-        return llu_file_open(pnode->p_base->pb_ino);
-}
+        /* The MDS sent back the EA because we unlinked the last reference
+         * to this file. Use this EA to unlink the objects on the OST.
+         * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
+         * check it is complete and sensible. */
+        eadata = lustre_swab_repbuf(request, 1, body->eadatasize, NULL);
+        LASSERT(eadata != NULL);
+        if (eadata == NULL) {
+                CERROR("Can't unpack MDS EA data\n");
+                GOTO(out, rc = -EPROTO);
+        }
+
+        rc = obd_unpackmd(llu_i2obdexp(dir), &lsm, eadata, body->eadatasize);
+        if (rc < 0) {
+                CERROR("obd_unpackmd: %d\n", rc);
+                GOTO(out, rc);
+        }
+        LASSERT(rc >= sizeof(*lsm));
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out_free_memmd, rc = -ENOMEM);
+
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_mode = body->mode & S_IFMT;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
+
+        if (body->valid & OBD_MD_FLCOOKIE) {
+                oa->o_valid |= OBD_MD_FLCOOKIE;
+                oti.oti_logcookies =
+                        lustre_msg_buf(request->rq_repmsg, 2,
+                                       sizeof(struct llog_cookie) *
+                                       lsm->lsm_stripe_count);
+                if (oti.oti_logcookies == NULL) {
+                        oa->o_valid &= ~OBD_MD_FLCOOKIE;
+                        body->valid &= ~OBD_MD_FLCOOKIE;
+                }
+        }
 
+        rc = obd_destroy(llu_i2obdexp(dir), oa, lsm, &oti);
+        obdo_free(oa);
+        if (rc)
+                CERROR("obd destroy objid 0x"LPX64" error %d\n",
+                       lsm->lsm_object_id, rc);
+ out_free_memmd:
+        obd_free_memmd(llu_i2obdexp(dir), &lsm);
+ out:
+        return rc;
+}
 
-static int llu_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode)
+int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
         struct ll_file_data *fd = lli->lli_file_data;
         struct ptlrpc_request *req = NULL;
-        unsigned long flags;
-        struct obd_import *imp;
-        int rc;
-
-        /* FIXME add following code later FIXME */
-#if 0
-        /* Complete the open request and remove it from replay list */
-        rc = mdc_close(&ll_i2sbi(inode)->ll_mdc_conn, lli->lli_st_ino,
-                       inode->i_mode, &fd->fd_mds_och.och_fh, &req);
-        if (rc)
-                CERROR("inode %lu close failed: rc = %d\n",
-                                lli->lli_st_ino, rc);
-
-        imp = fd->fd_mds_och.och_req->rq_import;
-        LASSERT(imp != NULL);
-        spin_lock_irqsave(&imp->imp_lock, flags);
-
-        DEBUG_REQ(D_HA, fd->fd_mds_och.och_req, "matched open req %p", 
-		  fd->fd_mds_och.och_req);
-
-        /* We held on to the request for replay until we saw a close for that
-         * file.  Now that we've closed it, it gets replayed on the basis of
-         * its transno only. */
-        spin_lock (&fd->fd_mds_och.och_req->rq_lock);
-        fd->fd_mds_och.och_req->rq_replay = 0;
-        spin_unlock (&fd->fd_mds_och.och_req->rq_lock);
-
-        if (fd->fd_mds_och.och_req->rq_transno) {
-                /* This open created a file, so it needs replay as a
-                 * normal transaction now.  Our reference to it now
-                 * effectively owned by the imp_replay_list, and it'll
-                 * be committed just like other transno-having
-                 * requests from here on out. */
-
-                /* We now retain this close request, so that it is
-                 * replayed if the open is replayed.  We duplicate the
-                 * transno, so that we get freed at the right time,
-                 * and rely on the difference in xid to keep
-                 * everything ordered correctly.
-                 *
-                 * But! If this close was already given a transno
-                 * (because it caused real unlinking of an
-                 * open-unlinked file, f.e.), then we'll be ordered on
-                 * the basis of that and we don't need to do anything
-                 * magical here. */
-                if (!req->rq_transno) {
-                        req->rq_transno = fd->fd_mds_och.och_req->rq_transno;
-                        ptlrpc_retain_replayable_request(req, imp);
-                }
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
+        struct obd_client_handle *och = &fd->fd_mds_och;
+        struct obdo obdo;
+        int rc, valid;
+        ENTRY;
 
-                /* Should we free_committed now? we always free before
-                 * replay, so it's probably a wash.  We could check to
-                 * see if the fd_req should already be committed, in
-                 * which case we can avoid the whole retain_replayable
-                 * dance. */
+        valid = OBD_MD_FLID;
+        if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
+                valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+
+        memset(&obdo, 0, sizeof(obdo));
+        obdo.o_id = lli->lli_st_ino;
+        obdo.o_mode = lli->lli_st_mode;
+        obdo.o_size = lli->lli_st_size;
+        obdo.o_blocks = lli->lli_st_blocks;
+        if (0 /* ll_is_inode_dirty(inode) */) {
+                obdo.o_flags = MDS_BFLAG_UNCOMMITTED_WRITES;
+                valid |= OBD_MD_FLFLAGS;
+        }
+        obdo.o_valid = valid;
+        rc = mdc_close(mdc_exp, &obdo, och, &req);
+        if (rc == EAGAIN) {
+                /* We are the last writer, so the MDS has instructed us to get
+                 * the file size and any write cookies, then close again. */
+                //ll_queue_done_writing(inode);
+                rc = 0;
+        } else if (rc) {
+                CERROR("inode %lu close failed: rc = %d\n", lli->lli_st_ino, rc);
         } else {
-                /* No transno means that we can just drop our ref. */
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                rc = llu_objects_destroy(req, inode);
+                if (rc)
+                        CERROR("inode %lu ll_objects destroy: rc = %d\n",
+                                lli->lli_st_ino, rc);
         }
-        ptlrpc_req_finished(fd->fd_mds_och.och_req);
 
-        /* Do this after the fd_req->rq_transno check, because we don't want
-         * to bounce off zero references. */
+        mdc_clear_open_replay_data(och);
         ptlrpc_req_finished(req);
-        fd->fd_mds_och.och_fh.cookie = DEAD_HANDLE_MAGIC;
-#endif
+        och->och_fh.cookie = DEAD_HANDLE_MAGIC;
         lli->lli_file_data = NULL;
-        free(fd);
+        OBD_FREE(fd, sizeof(*fd));
 
-        RETURN(-abs(rc));
+        RETURN(rc);
 }
 
-static int llu_file_release(struct inode *inode)
+int llu_file_release(struct inode *inode)
 {
+        struct ll_file_data *fd;
         struct llu_sb_info *sbi = llu_i2sbi(inode);
         struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct ll_file_data *fd;
-        struct obdo oa;
         int rc = 0, rc2;
 
-        fd = lli->lli_file_data;
-        if (!fd) /* no process opened the file after an mcreate */
-                RETURN(rc = 0);
-
-        /* we might not be able to get a valid handle on this file
-         * again so we really want to flush our write cache.. */
-        if (S_ISREG(inode->i_mode) && lsm) {
-                memset(&oa, 0, sizeof(oa));
-                oa.o_id = lsm->lsm_object_id;
-                oa.o_mode = S_IFREG;
-                oa.o_valid = OBD_MD_FLTYPE | OBD_MD_FLID;
+        ENTRY;
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu\n", lli->lli_st_ino,
+               lli->lli_st_generation);
 
-                memcpy(&oa.o_inline, &fd->fd_ost_och, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
+        /* FIXME need add this check later. how to find the root pnode? */
+#if 0
+        /* don't do anything for / */
+        if (inode->i_sb->s_root == file->f_dentry)
+                RETURN(0);
+#endif
+        /* still opened by others? */
+        if (--lli->lli_open_count)
+                RETURN(0);
 
-                rc = obd_close(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                if (rc)
-                        CERROR("inode %lu object close failed: rc = "
-                               "%d\n", lli->lli_st_ino, rc);
-	}
+        fd = lli->lli_file_data;
+        if (!fd) /* no process opened the file after an mcreate */
+                RETURN(0);
 
-        rc2 = llu_mdc_close(&sbi->ll_mdc_conn, inode);
+        rc2 = llu_mdc_close(sbi->ll_mdc_exp, inode);
         if (rc2 && !rc)
                 rc = rc2;
 
@@ -496,58 +474,102 @@ static int llu_file_release(struct inode *inode)
 
 int llu_iop_close(struct inode *inode)
 {
-        return llu_file_release(inode);
+        int rc;
+
+        rc = llu_file_release(inode);
+        if (!llu_i2info(inode)->lli_open_count)
+                llu_i2info(inode)->lli_stale_flag = 1;
+        return rc;
 }
 
 int llu_iop_ipreadv(struct inode *ino,
-                    struct io_arguments *ioargs,
-                    struct ioctx **ioctxp)
+                    struct ioctx *ioctx)
 {
-        struct ioctx *ioctx;
-
-        if (!ioargs->ioarg_iovlen)
-                return 0;
-        if (ioargs->ioarg_iovlen < 0)
-                return -EINVAL;
+        ENTRY;
 
-        ioctx = _sysio_ioctx_new(ino, ioargs);
-        if (!ioctx)
-                return -ENOMEM;
+        if (!ioctx->ioctx_iovlen)
+                RETURN(0);
+        if (ioctx->ioctx_iovlen < 0)
+                RETURN(-EINVAL);
 
-        ioctx->ioctx_cc = llu_file_read(ino,
+        ioctx->ioctx_private = llu_file_read(ino,
                                         ioctx->ioctx_iovec,
                                         ioctx->ioctx_iovlen,
                                         ioctx->ioctx_offset);
-        if (ioctx->ioctx_cc < 0)
-                ioctx->ioctx_errno = ioctx->ioctx_cc;
+        if (IS_ERR(ioctx->ioctx_private))
+                return (PTR_ERR(ioctx->ioctx_private));
 
-        *ioctxp = ioctx;
-        return 0;
+        RETURN(0);
 }
 
 int llu_iop_ipwritev(struct inode *ino,
-                     struct io_arguments *ioargs,
-                     struct ioctx **ioctxp)
+                     struct ioctx *ioctx)
 {
-        struct ioctx *ioctx;
-
-        if (!ioargs->ioarg_iovlen)
-                return 0;
-        if (ioargs->ioarg_iovlen < 0)
-                return -EINVAL;
+        ENTRY;
 
-        ioctx = _sysio_ioctx_new(ino, ioargs);
-        if (!ioctx)
-                return -ENOMEM;
+        if (!ioctx->ioctx_iovlen)
+                RETURN(0);
+        if (ioctx->ioctx_iovlen < 0)
+                RETURN(-EINVAL);
 
-        ioctx->ioctx_cc = llu_file_write(ino,
+        ioctx->ioctx_private = llu_file_write(ino,
                                          ioctx->ioctx_iovec,
                                          ioctx->ioctx_iovlen,
                                          ioctx->ioctx_offset);
-        if (ioctx->ioctx_cc < 0)
-                ioctx->ioctx_errno = ioctx->ioctx_cc;
+        if (IS_ERR(ioctx->ioctx_private))
+                return (PTR_ERR(ioctx->ioctx_private));
 
-        *ioctxp = ioctx;
-        return 0;
+        RETURN(0);
 }
 
+/* this isn't where truncate starts.   roughly:
+ * sys_truncate->ll_setattr_raw->vmtruncate->ll_truncate
+ * we grab the lock back in setattr_raw to avoid races. */
+static void llu_truncate(struct inode *inode)
+{
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct lov_stripe_md *lsm = lli->lli_smd;
+        struct obdo oa = {0};
+        int err;
+        ENTRY;
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu\n", lli->lli_st_ino,
+               lli->lli_st_generation);
+
+        if (!lsm) {
+                CERROR("truncate on inode %lu with no objects\n", lli->lli_st_ino);
+                EXIT;
+                return;
+        }
+
+        oa.o_id = lsm->lsm_object_id;
+        oa.o_valid = OBD_MD_FLID;
+        obdo_from_inode(&oa, inode, OBD_MD_FLTYPE|OBD_MD_FLMODE|OBD_MD_FLATIME|
+                                    OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+
+        CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after %Lu)\n",
+               oa.o_id, lli->lli_st_size);
+
+        /* truncate == punch from new size to absolute end of file */
+        err = obd_punch(llu_i2obdexp(inode), &oa, lsm, lli->lli_st_size,
+                        OBD_OBJECT_EOF, NULL);
+        if (err)
+                CERROR("obd_truncate fails (%d) ino %lu\n", err, lli->lli_st_ino);
+        else
+                obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
+                                          OBD_MD_FLATIME | OBD_MD_FLMTIME |
+                                          OBD_MD_FLCTIME);
+
+        EXIT;
+        return;
+}
+
+int llu_vmtruncate(struct inode * inode, loff_t offset)
+{
+        struct llu_inode_info *lli = llu_i2info(inode);
+
+        lli->lli_st_size = offset;
+
+        llu_truncate(inode);
+
+        return 0;
+}
diff --git a/lustre/liblustre/genlib.sh b/lustre/liblustre/genlib.sh
new file mode 100755
index 0000000000000000000000000000000000000000..52b4b880a9de9eaa4d0543643792fbfbd8296742
--- /dev/null
+++ b/lustre/liblustre/genlib.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This script is to generate lib lustre library as a whole. It will leave
+# two files on current directory: liblustre.a and liblustre.so.
+# Integrate them into Makefile.am later
+#
+
+AR=/usr/bin/ar
+LD=/usr/bin/ld
+
+CWD=`pwd`
+
+SYSIO=$1
+
+ALL_OBJS=
+
+build_obj_list() {
+  _objs=`$AR -t $1/$2`
+  for _lib in $_objs; do
+  ALL_OBJS=$ALL_OBJS"$1/$_lib ";
+  done;
+}
+
+# lustre components libs
+build_obj_list . libllite.a
+build_obj_list ../lov liblov.a
+build_obj_list ../obdecho libobdecho.a
+build_obj_list ../osc libosc.a
+build_obj_list ../mdc libmdc.a
+build_obj_list ../ldlm libldlm.a
+build_obj_list ../ptlrpc libptlrpc.a
+build_obj_list ../obdclass liblustreclass.a
+build_obj_list ../lvfs liblvfs.a
+
+# portals components libs
+build_obj_list ../portals/utils libptlctl.a
+build_obj_list ../portals/unals libtcpnal.a
+build_obj_list ../portals/portals libportals.a
+
+# libsysio components libs
+build_obj_list $SYSIO/drivers/native libsysio_native.a
+build_obj_list $SYSIO/drivers/sockets libsysio_sockets.a
+build_obj_list $SYSIO/src libsysio.a
+build_obj_list $SYSIO/dev/stdfd libsysio_stdfd.a
+
+
+# create static lib
+rm -f $CWD/liblustre.a
+$AR -r $CWD/liblustre.a $ALL_OBJS
+
+# create shared lib
+rm -f $CWD/liblustre.so
+$LD -shared -o $CWD/liblustre.so -init __liblustre_setup_ -fini __liblustre_cleanup_ \
+	$ALL_OBJS -lpthread
diff --git a/lustre/liblustre/libtest.c b/lustre/liblustre/libtest.c
index 1d523a6e9c33a58762ab4addcee9c13371192f3d..87dba3d22b8924a212852a749192b1e71ace71b9 100644
--- a/lustre/liblustre/libtest.c
+++ b/lustre/liblustre/libtest.c
@@ -10,16 +10,15 @@
 #include <liblustre.h>
 #include <linux/obd.h>
 #include <linux/obd_class.h>
-#include <portals/procbridge.h>
+#include <procbridge.h>
+
+#define LIBLUSTRE_TEST 1
+#include "../utils/lctl.c"
 
 struct ldlm_namespace;
 struct ldlm_res_id;
 struct obd_import;
 
-extern int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, int flags);
-extern int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only);
-extern int ldlm_replay_locks(struct obd_import *imp);
-
 void *inter_module_get(char *arg)
 {
         if (!strcmp(arg, "tcpnal_ni"))
@@ -34,6 +33,29 @@ void *inter_module_get(char *arg)
                 return NULL;
 }
 
+/* XXX move to proper place */
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
+{
+        switch(nal){
+        case TCPNAL:
+                /* userspace NAL */
+        case SOCKNAL:
+                sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
+                        HIPQUAD(nid));
+                break;
+        case QSWNAL:
+        case GMNAL:
+        case IBNAL:
+        case TOENAL:
+        case SCIMACNAL:
+                sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
+                break;
+        default:
+                return NULL;
+        }
+        return str;
+}
+
 ptl_handle_ni_t         tcpnal_ni;
 
 struct pingcli_args {
@@ -52,7 +74,13 @@ struct obd_class_user_state ocus;
 ptl_handle_ni_t *
 kportal_get_ni (int nal)
 {
-        return &tcpnal_ni;
+        switch (nal)
+        {
+        case SOCKNAL:
+                return &tcpnal_ni;
+        default:
+                return NULL;
+        }
 }
 
 inline void
@@ -61,22 +89,44 @@ kportal_put_ni (int nal)
         return;
 }
 
-void init_current(int argc, char **argv)
+int
+kportal_nal_cmd(struct portals_cfg *pcfg)
+{
+#if 0
+        __u32 nal = pcfg->pcfg_nal;
+        int rc = -EINVAL;
+
+        ENTRY;
+
+        down(&nal_cmd_sem);
+        if (nal > 0 && nal <= NAL_MAX_NR && nal_cmd[nal].nch_handler) {
+                CDEBUG(D_IOCTL, "calling handler nal: %d, cmd: %d\n", nal, 
+                       pcfg->pcfg_command);
+                rc = nal_cmd[nal].nch_handler(pcfg, nal_cmd[nal].nch_private);
+        }
+        up(&nal_cmd_sem);
+        RETURN(rc);
+#else
+        CERROR("empty function!!!\n");
+        return 0;
+#endif
+}
+
+int init_current(int argc, char **argv)
 { 
         current = malloc(sizeof(*current));
         strncpy(current->comm, argv[0], sizeof(current->comm));
         current->pid = getpid();
-
+	return 0;
 }
 
 ptl_nid_t tcpnal_mynid;
 
-int init_lib_portals(struct pingcli_args *args)
+int init_lib_portals()
 {
         int rc;
 
         PtlInit();
-        tcpnal_mynid = args->mynid;
         rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni);
         if (rc != 0) {
                 CERROR("ksocknal: PtlNIInit failed: error %d\n", rc);
@@ -90,47 +140,108 @@ int init_lib_portals(struct pingcli_args *args)
 extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
 
 
+int lib_ioctl_nalcmd(int dev_id, int opc, void * ptr)
+{
+        struct portal_ioctl_data *ptldata;
+
+        if (opc == IOC_PORTAL_NAL_CMD) {
+                ptldata = (struct portal_ioctl_data *) ptr;
+
+                if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
+                        tcpnal_mynid = ptldata->ioc_nid;
+                        printf("mynid: %u.%u.%u.%u\n",
+                                (unsigned)(tcpnal_mynid>>24) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>16) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>8) & 0xFF,
+                                (unsigned)(tcpnal_mynid) & 0xFF);
+                }
+        }
+
+	return (0);
+}
+
 int lib_ioctl(int dev_id, int opc, void * ptr)
 {
 
 	if (dev_id == OBD_DEV_ID) {
-                struct obd_ioctl_data *ioc = ptr;
 		class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
 
 		/* you _may_ need to call obd_ioctl_unpack or some
 		   other verification function if you want to use ioc
 		   directly here */
+#if 0
 		printf ("processing ioctl cmd: %x buf len: %d\n", 
 			opc,  ioc->ioc_len);
+#endif
 	}
 	return (0);
 }
 
+int liblustre_ioctl(int dev_id, int opc, void *ptr)
+{
+	int   rc = -EINVAL;
+	
+	switch (dev_id) {
+	default:
+		fprintf(stderr, "Unexpected device id %d\n", dev_id);
+		abort();
+		break;
+		
+	case OBD_DEV_ID:
+		rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
+		break;
+	}
+
+	return rc;
+}
+
+extern int time_ptlwait1;
+extern int time_ptlwait2;
+extern int time_ptlselect;
 int main(int argc, char **argv) 
 {
-        struct pingcli_args *args;
-	args= malloc(sizeof(*args));
-        if (!args) { 
-                printf("Malloc error\n");
-                exit(1);
+        char *config_file;
+
+        if (argc > 2) {
+                printf("Usage: %s [config_file]\n", argv[0]);
+                return 1;
         }
 
-	args->mynid   = ntohl (inet_addr (argv[1]));
-        INIT_LIST_HEAD(&ocus.ocus_conns);
+        if (argc == 2) {
+                config_file = argv[1];
+		argc--;
+		argv++;
+	} else
+                config_file = "/tmp/DUMP_FILE";
 
-        init_current(argc, argv);
-        init_obdclass();
-        init_lib_portals(args);
-        ptlrpc_init();
-        ldlm_init();
-        mdc_init();
-        lov_init();
-        osc_init();
-        echo_client_init();
+        srand(time(NULL));
 
-	parse_dump("/tmp/DUMP_FILE", lib_ioctl);
+        INIT_LIST_HEAD(&ocus.ocus_conns);
+#if 1
+	portal_debug = 0;
+	portal_subsystem_debug = 0;
+#endif
+	parse_dump(config_file, lib_ioctl_nalcmd);
+
+        if (init_current(argc, argv) ||
+	    init_obdclass() || init_lib_portals() ||
+	    ptlrpc_init() ||
+	    ldlm_init() ||
+	    mdc_init() ||
+	    lov_init() ||
+	    osc_init() ||
+	    echo_client_init()) {
+		printf("error\n");
+		return 1;
+	}
 
-        printf("Hello\n");
-        return 0;
+	parse_dump(config_file, lib_ioctl);
+
+	set_ioc_handler(liblustre_ioctl);
+#if 0	
+	portal_debug = -1;
+	portal_subsystem_debug = -1;
+#endif
+	return lctl_main(argc, argv);
 }
 
diff --git a/lustre/liblustre/llite_lib.c b/lustre/liblustre/llite_lib.c
index b11de88ef96aa57c1cbd30add7b139a11dfbab36..ec0d06c8badf9608682d0f642bbb371e1de87a1a 100644
--- a/lustre/liblustre/llite_lib.c
+++ b/lustre/liblustre/llite_lib.c
@@ -21,27 +21,25 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define DEBUG_SUBSYSTEM S_LLITE
-
 #include <stdlib.h>
 #include <string.h>
-#include <error.h>
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/queue.h>
 
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
 #include <sysio.h>
 #include <fs.h>
 #include <mount.h>
 #include <inode.h>
 #include <file.h>
 
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
 #include <portals/api-support.h> /* needed for ptpctl.h */
 #include <portals/ptlctl.h>	/* needed for parse_dump */
+#include <procbridge.h>
 
 #include "llite_lib.h"
 
@@ -54,7 +52,13 @@ struct obd_class_user_state ocus;
 ptl_handle_ni_t *
 kportal_get_ni (int nal)
 {
-        return &tcpnal_ni;
+        switch (nal)
+        {
+        case SOCKNAL:
+                return &tcpnal_ni;
+        default:
+                return NULL;
+        }
 }
 
 inline void
@@ -67,10 +71,6 @@ struct ldlm_namespace;
 struct ldlm_res_id;
 struct obd_import;
 
-extern int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, int flags);
-extern int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only);
-extern int ldlm_replay_locks(struct obd_import *imp);
-
 void *inter_module_get(char *arg)
 {
         if (!strcmp(arg, "tcpnal_ni"))
@@ -85,6 +85,29 @@ void *inter_module_get(char *arg)
                 return NULL;
 }
 
+/* XXX move to proper place */
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
+{
+        switch(nal){
+        case TCPNAL:
+                /* userspace NAL */
+        case SOCKNAL:
+                sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
+                        HIPQUAD(nid));
+                break;
+        case QSWNAL:
+        case GMNAL:
+        case IBNAL:
+        case TOENAL:
+        case SCIMACNAL:
+                sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
+                break;
+        default:
+                return NULL;
+        }
+        return str;
+}
+
 void init_current(char *comm)
 { 
         current = malloc(sizeof(*current));
@@ -95,15 +118,26 @@ void init_current(char *comm)
         current->pid = getpid();
         current->fsuid = 0;
         current->fsgid = 0;
-        current->cap_effective = 0;
+        current->cap_effective = -1;
         memset(&current->pending, 0, sizeof(current->pending));
 }
 
+/* FIXME */
+void generate_random_uuid(unsigned char uuid_out[16])
+{
+        int *arr = (int*)uuid_out;
+        int i;
+
+        for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
+                arr[i] = rand();
+}
+
 ptl_nid_t tcpnal_mynid;
 
 int init_lib_portals()
 {
         int rc;
+        ENTRY;
 
         PtlInit();
         rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni);
@@ -113,58 +147,36 @@ int init_lib_portals()
                 RETURN (rc);
         }
         PtlNIDebug(tcpnal_ni, ~0);
-        return rc;
+        RETURN(rc);
 }
 
-extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
+int
+kportal_nal_cmd(struct portals_cfg *pcfg)
+{
+        /* handle portals command if we want */
+        return 0;
+}
 
-struct mount_option_s mount_option = {NULL, NULL};
+extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
 
-/* FIXME simple arg parser FIXME */
-void parse_mount_options(void *arg)
+int lib_ioctl_nalcmd(int dev_id, int opc, void * ptr)
 {
-        char *buf = NULL;
-        struct obd_ioctl_data *data;
-        char *ptr, *comma, *eq, **tgt, *v;
-        int len;
-
-        if (obd_ioctl_getdata(&buf, &len, arg)) {
-                CERROR("OBD ioctl: data error\n");
-                return;
-        }
-        data = (struct obd_ioctl_data *)buf;
-        ptr = data->ioc_inlbuf1;
-        printf("mount option: %s\n", ptr);
-
-        while (ptr) {
-                eq = strchr(ptr, '=');
-                if (!eq)
-                        return;
-
-                *eq = 0;
-                if (!strcmp("osc", ptr))
-                        tgt = &mount_option.osc_uuid;
-                else if (!strcmp("mdc", ptr))
-                        tgt = &mount_option.mdc_uuid;
-                else {
-                        printf("Unknown mount option %s\n", ptr);
-                        return;
+        struct portal_ioctl_data *ptldata;
+
+        if (opc == IOC_PORTAL_NAL_CMD) {
+                ptldata = (struct portal_ioctl_data *) ptr;
+
+                if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
+                        tcpnal_mynid = ptldata->ioc_nid;
+                        printf("mynid: %u.%u.%u.%u\n",
+                                (unsigned)(tcpnal_mynid>>24) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>16) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>8) & 0xFF,
+                                (unsigned)(tcpnal_mynid) & 0xFF);
                 }
-
-                v = eq + 1;
-                comma = strchr(v, ',');
-                if (comma) {
-                        *comma = 0;
-                        ptr = comma + 1;
-                } else
-                        ptr = NULL;
-
-                *tgt = malloc(strlen(v)+1);
-                strcpy(*tgt, v);
         }
 
-        if (buf)
-                obd_ioctl_freedata(buf, len);
+	return (0);
 }
 
 int lib_ioctl(int dev_id, int opc, void * ptr)
@@ -174,18 +186,14 @@ int lib_ioctl(int dev_id, int opc, void * ptr)
 	if (dev_id == OBD_DEV_ID) {
                 struct obd_ioctl_data *ioc = ptr;
 
-                if (opc == OBD_IOC_MOUNTOPT) {
-                        parse_mount_options(ptr);
-                        return 0;
-                }
+                //XXX hack!!!
+                ioc->ioc_plen1 = ioc->ioc_inllen1;
+                ioc->ioc_pbuf1 = ioc->ioc_bulk;
+                //XXX
 
-		rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
+                rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
 
-		/* you _may_ need to call obd_ioctl_unpack or some
-		   other verification function if you want to use ioc
-		   directly here */
-		printf ("processing ioctl cmd: %x buf len: %d, rc %d\n", 
-			opc,  ioc->ioc_len, rc);
+                printf ("proccssing ioctl cmd: %x, rc %d\n", opc,  rc);
 
                 if (rc)
                         return rc;
@@ -193,11 +201,22 @@ int lib_ioctl(int dev_id, int opc, void * ptr)
 	return (0);
 }
 
-int lllib_init(char *arg)
+int lllib_init(char *dumpfile)
 {
-	tcpnal_mynid = ntohl(inet_addr(arg));
         INIT_LIST_HEAD(&ocus.ocus_conns);
 
+        if (!g_zconf) {
+                /* this parse only get my nid from config file
+                 * before initialize portals
+                 */
+                if (parse_dump(dumpfile, lib_ioctl_nalcmd))
+                        return -1;
+        } else {
+                /* XXX need setup mynid before tcpnal initialize */
+                tcpnal_mynid = ((uint64_t)getpid() << 32) | time(0);
+                printf("set tcpnal mynid: %016llx\n", tcpnal_mynid);
+        }
+
         init_current("dummy");
         if (init_obdclass() ||
             init_lib_portals() ||
@@ -208,19 +227,250 @@ int lllib_init(char *arg)
             osc_init())
                 return -1;
 
-	if (parse_dump("/tmp/DUMP_FILE", lib_ioctl))
+        if (!g_zconf && parse_dump(dumpfile, lib_ioctl))
                 return -1;
 
         return _sysio_fssw_register("llite", &llu_fssw_ops);
 }
+ 
+#if 0
+static void llu_check_request()
+{
+        liblustre_wait_event(0);
+}
+#endif
 
-/* FIXME */
-void generate_random_uuid(unsigned char uuid_out[16])
+int liblustre_process_log(struct config_llog_instance *cfg)
 {
-        int *arr = (int*)uuid_out;
-        int i;
+        struct lustre_cfg lcfg;
+        char  *peer = "MDS_PEER_UUID";
+        struct obd_device *obd;
+        struct lustre_handle mdc_conn = {0, };
+        struct obd_export *exp;
+        char  *name = "mdc_dev";
+        class_uuid_t uuid;
+        struct obd_uuid mdc_uuid;
+        struct llog_ctxt *ctxt;
+        ptl_nid_t nid = 0;
+        int nal, err, rc = 0;
+        ENTRY;
+
+        generate_random_uuid(uuid);
+        class_uuid_unparse(uuid, &mdc_uuid);
+
+        if (ptl_parse_nid(&nid, g_zconf_mdsnid)) {
+                CERROR("Can't parse NID %s\n", g_zconf_mdsnid);
+                RETURN(-EINVAL);
+        }
+        nal = ptl_name2nal("tcp");
+        if (nal <= 0) {
+                CERROR("Can't parse NAL tcp\n");
+                RETURN(-EINVAL);
+        }
+        LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
+        lcfg.lcfg_nid = nid;
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        lcfg.lcfg_nal = nal;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+        LCFG_INIT(lcfg, LCFG_ATTACH, name);
+        lcfg.lcfg_inlbuf1 = "mdc";
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_del_uuid, err);
+
+        LCFG_INIT(lcfg, LCFG_SETUP, name);
+        lcfg.lcfg_inlbuf1 = g_zconf_mdsname;
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = peer;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_detach, err);
+        
+        obd = class_name2obd(name);
+        if (obd == NULL)
+                GOTO(out_cleanup, err = -EINVAL);
+
+        err = obd_connect(&mdc_conn, obd, &mdc_uuid);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n",
+                        g_zconf_mdsname, err);
+                GOTO(out_cleanup, err);
+        }
+        
+        exp = class_conn2export(&mdc_conn);
+        
+        ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
+        rc = class_config_parse_llog(ctxt, g_zconf_profile, cfg);
+        if (rc) {
+                CERROR("class_config_parse_llog failed: rc = %d\n", rc);
+        }
 
-        for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
-                arr[i] = rand();
+        err = obd_disconnect(exp, 0);
+
+out_cleanup:
+        LCFG_INIT(lcfg, LCFG_CLEANUP, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_detach:
+        LCFG_INIT(lcfg, LCFG_DETACH, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_del_uuid:
+        LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        err = class_process_config(&lcfg);
+
+out:
+        if (rc == 0)
+                rc = err;
+        
+        RETURN(rc);
+}
+
+static void sighandler_USR1(int signum)
+{
+        /* do nothing */
+}
+
+/* parse host:/mdsname/profile string */
+int ll_parse_mount_target(const char *target, char **mdsnid,
+                          char **mdsname, char **profile)
+{
+        static char buf[256];
+        char *s;
+
+        buf[255] = 0;
+        strncpy(buf, target, 255);
+
+        if ((s = strchr(buf, ':'))) {
+                *mdsnid = buf;
+                *s = '\0';
+                                                                                                                        
+                while (*++s == '/')
+                        ;
+                *mdsname = s;
+                if ((s = strchr(*mdsname, '/'))) {
+                        *s = '\0';
+                        *profile = s + 1;
+                        return 0;
+                }
+        }
+
+        return -1;
+}
+
+/* env variables */
+#define ENV_LUSTRE_MNTPNT               "LIBLUSTRE_MOUNT_POINT"
+#define ENV_LUSTRE_MNTTGT               "LIBLUSTRE_MOUNT_TARGET"
+#define ENV_LUSTRE_DUMPFILE             "LIBLUSTRE_DUMPFILE"
+
+extern int _sysio_native_init();
+
+/* global variables */
+int     g_zconf = 0;            /* zeroconf or dumpfile */
+char   *g_zconf_mdsname = NULL; /* mdsname, for zeroconf */
+char   *g_zconf_mdsnid = NULL;  /* mdsnid, for zeroconf */
+char   *g_zconf_profile = NULL; /* profile, for zeroconf */
+
+
+void __liblustre_setup_(void)
+{
+        char *lustre_path = NULL;
+        char *target = NULL;
+        char *dumpfile = NULL;
+        char *root_driver = "native";
+        char *lustre_driver = "llite";
+        char *root_path = "/";
+        unsigned mntflgs = 0;
+
+	int err;
+
+        srand(time(NULL));
+
+        signal(SIGUSR1, sighandler_USR1);
+
+	lustre_path = getenv(ENV_LUSTRE_MNTPNT);
+	if (!lustre_path) {
+                lustre_path = "/mnt/lustre";
+	}
+
+        target = getenv(ENV_LUSTRE_MNTTGT);
+        if (!target) {
+                dumpfile = getenv(ENV_LUSTRE_DUMPFILE);
+                if (!dumpfile) {
+                        CERROR("Neither mount target, nor dumpfile\n");
+                        exit(1);
+                }
+                g_zconf = 0;
+                printf("LibLustre: mount point %s, dumpfile %s\n",
+                        lustre_path, dumpfile);
+        } else {
+                if (ll_parse_mount_target(target,
+                                          &g_zconf_mdsnid,
+                                          &g_zconf_mdsname,
+                                          &g_zconf_profile)) {
+                        CERROR("mal-formed target %s \n", target);
+                        exit(1);
+                }
+                g_zconf = 1;
+                printf("LibLustre: mount point %s, target %s\n",
+                        lustre_path, target);
+        }
+
+	if (_sysio_init() != 0) {
+		perror("init sysio");
+		exit(1);
+	}
+
+        /* cygwin don't need native driver */
+#ifndef __CYGWIN__
+        _sysio_native_init();
+#endif
+
+	err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
+	if (err) {
+		perror(root_driver);
+		exit(1);
+	}
+
+#if 1
+	portal_debug = 0;
+	portal_subsystem_debug = 0;
+#endif
+	err = lllib_init(dumpfile);
+	if (err) {
+		perror("init llite driver");
+		exit(1);
+	}	
+
+        err = mount("/", lustre_path, lustre_driver, mntflgs, NULL);
+	if (err) {
+		errno = -err;
+		perror(lustre_driver);
+		exit(1);
+	}
+
+#if 0
+        __sysio_hook_sys_enter = llu_check_request;
+        __sysio_hook_sys_leave = NULL;
+#endif
 }
 
+void __liblustre_cleanup_(void)
+{
+	_sysio_shutdown();
+        PtlFini();
+}
diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h
index ce2e23b897e877e431cb7e0aec62bf02abc16020..f258ec92a1661c0b06e31ae70c83d18bc69231af 100644
--- a/lustre/liblustre/llite_lib.h
+++ b/lustre/liblustre/llite_lib.h
@@ -4,40 +4,61 @@
 #include <liblustre.h>
 #include <linux/obd.h>
 #include <linux/obd_class.h>
-#include <portals/procbridge.h>
+#include <linux/lustre_mds.h>
 #include <linux/lustre_lite.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#define PAGE_CACHE_MAXBYTES ((__u64)(~0UL) << PAGE_CACHE_SHIFT)
+
 struct ll_file_data {
         struct obd_client_handle fd_mds_och;
-        struct obd_client_handle fd_ost_och;
         __u32 fd_flags;
 };
 
 struct llu_sb_info
 {
         struct obd_uuid         ll_sb_uuid;
-        struct lustre_handle    ll_mdc_conn;
-        struct lustre_handle    ll_osc_conn;
+	struct obd_export      *ll_mdc_exp;
+        struct obd_export      *ll_osc_exp;
         obd_id                  ll_rootino;
         int                     ll_flags;
         struct list_head        ll_conn_chain;
+
+        struct obd_uuid         ll_mds_uuid;
+        struct obd_uuid         ll_mds_peer_uuid;
+        char                   *ll_instance; 
 };
 
+#define LLI_F_HAVE_OST_SIZE_LOCK        0
+#define LLI_F_HAVE_MDS_SIZE_LOCK        1
+#define LLI_F_PREFER_EXTENDED_SIZE      2
+
 struct llu_inode_info {
-	struct llu_sb_info	*lli_sbi;
-	struct ll_fid		lli_fid;
-        struct lov_stripe_md	*lli_smd;
-        char                	*lli_symlink_name;
-        /*struct semaphore      lli_open_sem;*/
+        struct llu_sb_info     *lli_sbi;
+        struct ll_fid           lli_fid;
+
+        struct lov_stripe_md   *lli_smd;
+        char                   *lli_symlink_name;
+        struct semaphore        lli_open_sem;
+	__u64                   lli_maxbytes;
         unsigned long        	lli_flags;
-        struct list_head     	lli_read_extents;
 
-	/* in libsysio we have no chance to store data in file,
-	 * so place it here */
-	struct ll_file_data	*lli_file_data;
+        /* for libsysio */
+        struct file_identifier  lli_sysio_fid;
+
+        struct lookup_intent   *lli_it;
+
+	/* XXX workaround for libsysio */
+        int                     lli_stale_flag;
+
+        /* in libsysio we have no chance to store data in file,
+         * so place it here. since it's possible that an file
+         * was opened several times without close, we track an
+         * open_count here */
+        struct ll_file_data    *lli_file_data;
+        int                     lli_open_count;
 
 	/* stat FIXME not 64 bit clean */
 	dev_t			lli_st_dev;
@@ -59,6 +80,29 @@ struct llu_inode_info {
 	unsigned long 		lli_st_generation;
 };
 
+#define LLU_SYSIO_COOKIE_SIZE(x) \
+        (sizeof(struct llu_sysio_cookie) + \
+         sizeof(struct ll_async_page) * (x) + \
+         sizeof(struct page) * (x))
+
+struct llu_sysio_cookie {
+        struct obd_sync_io_container lsc_osic;
+	struct inode           *lsc_inode;
+	int                     lsc_npages;
+        struct ll_async_page   *lsc_llap;
+        struct page            *lsc_pages;
+        __u64                   lsc_rwcount;
+};
+
+/* XXX why uio.h haven't the definition? */
+#define MAX_IOVEC 32
+
+struct llu_sysio_callback_args
+{
+	int ncookies;
+	struct llu_sysio_cookie *cookies[MAX_IOVEC];
+};
+
 static inline struct llu_sb_info *llu_fs2sbi(struct filesys *fs)
 {
 	return (struct llu_sb_info*)(fs->fs_private);
@@ -74,6 +118,7 @@ static inline struct llu_sb_info *llu_i2sbi(struct inode *inode)
         return llu_i2info(inode)->lli_sbi;
 }
 
+#if 0
 static inline struct client_obd *sbi2mdc(struct llu_sb_info *sbi)
 {
 	struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn);
@@ -81,13 +126,110 @@ static inline struct client_obd *sbi2mdc(struct llu_sb_info *sbi)
 		LBUG();
 	return &obd->u.cli;
 }
+#endif
+
+static inline struct obd_export *llu_i2obdexp(struct inode *inode)
+{
+        return llu_i2info(inode)->lli_sbi->ll_osc_exp;
+}
 
-static inline struct lustre_handle *llu_i2obdconn(struct inode *inode)
+static inline struct obd_export *llu_i2mdcexp(struct inode *inode)
 {
-        return &(llu_i2info(inode)->lli_sbi->ll_osc_conn);
+        return llu_i2info(inode)->lli_sbi->ll_mdc_exp;
 }
 
 
+#define LL_SAVE_INTENT(inode, it)                                              \
+do {                                                                           \
+	struct lookup_intent *temp;                                            \
+        LASSERT(llu_i2info(inode)->lli_it == NULL);                            \
+       	OBD_ALLOC(temp, sizeof(*temp));					       \
+        memcpy(temp, it, sizeof(*temp));                                       \
+        llu_i2info(inode)->lli_it = temp;                                      \
+        CDEBUG(D_DENTRY, "alloc intent %p to inode %p(ino %lu)\n",             \
+			temp, inode, llu_i2info(inode)->lli_st_ino);           \
+} while(0)
+
+
+#define LL_GET_INTENT(inode, it)                                               \
+do {                                                                           \
+        it = llu_i2info(inode)->lli_it;                                        \
+                                                                               \
+        LASSERT(it);                                                           \
+        llu_i2info(inode)->lli_it = NULL;                                      \
+        CDEBUG(D_DENTRY, "dettach intent %p from inode %p(ino %lu)\n",         \
+			it, inode, llu_i2info(inode)->lli_st_ino);             \
+} while(0)
+
+/* interpet return codes from intent lookup */
+#define LL_LOOKUP_POSITIVE 1
+#define LL_LOOKUP_NEGATIVE 2
+
+static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
+{
+	*fid = llu_i2info(inode)->lli_fid;
+}
+
+struct it_cb_data {
+	struct inode *icbd_parent;
+	struct pnode *icbd_child;
+	obd_id hash;
+};
+
+static inline void ll_i2uctxt(struct ll_uctxt *ctxt, struct inode *i1,
+                              struct inode *i2)
+{
+	struct llu_inode_info *lli1 = llu_i2info(i1);
+	struct llu_inode_info *lli2;
+
+        LASSERT(i1);
+        LASSERT(ctxt);
+
+        if (in_group_p(lli1->lli_st_gid))
+                ctxt->gid1 = lli1->lli_st_gid;
+        else
+                ctxt->gid1 = -1;
+
+        if (i2) {
+		lli2 = llu_i2info(i2);
+                if (in_group_p(lli2->lli_st_gid))
+                        ctxt->gid2 = lli2->lli_st_gid;
+                else
+                        ctxt->gid2 = -1;
+        } else 
+                ctxt->gid2 = 0;
+}
+
+
+typedef int (*intent_finish_cb)(struct ptlrpc_request *,
+                                struct inode *parent, struct pnode *pnode, 
+                                struct lookup_intent *, int offset, obd_id ino);
+int llu_intent_lock(struct inode *parent, struct pnode *pnode,
+                    struct lookup_intent *, int flags, intent_finish_cb);
+
+/* FIXME */
+static inline int ll_permission(struct inode *inode, int flag, void * unused)
+{
+	return 0;
+}
+
+#if 0
+static inline int it_disposition(struct lookup_intent *it, int flag)
+{
+        return it->d.lustre.it_disposition & flag;
+}
+
+static inline void it_set_disposition(struct lookup_intent *it, int flag)
+{
+        it->d.lustre.it_disposition |= flag;
+}
+#endif
+
+static inline __u64 ll_file_maxbytes(struct inode *inode)
+{
+        return llu_i2info(inode)->lli_maxbytes;
+}
+
 struct mount_option_s
 {
 	char *mdc_uuid;
@@ -96,7 +238,14 @@ struct mount_option_s
 
 /* llite_lib.c */
 void generate_random_uuid(unsigned char uuid_out[16]);
+int liblustre_process_log(struct config_llog_instance *cfg);
+int ll_parse_mount_target(const char *target, char **mdsnid,
+                          char **mdsname, char **profile);
 
+extern int g_zconf;
+extern char   *g_zconf_mdsnid;
+extern char   *g_zconf_mdsname;
+extern char   *g_zconf_profile;
 extern struct mount_option_s mount_option;
 
 /* super.c */
@@ -104,7 +253,11 @@ void llu_update_inode(struct inode *inode, struct mds_body *body,
                       struct lov_stripe_md *lmm);
 void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid);
 void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid);
-struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode);
+//struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode);
+//int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm, void *ostdata);
+int ll_it_open_error(int phase, struct lookup_intent *it);
+struct inode *llu_iget(struct filesys *fs, struct lustre_md *md);
+int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm);
 
 extern struct fssw_ops llu_fssw_ops;
 
@@ -117,19 +270,43 @@ void llu_prepare_mdc_op_data(struct mdc_op_data *data,
                              int mode);
 int llu_create(struct inode *dir, struct pnode_base *pnode, int mode);
 int llu_iop_open(struct pnode *pnode, int flags, mode_t mode);
+int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode);
 int llu_iop_close(struct inode *inode);
-int llu_iop_ipreadv(struct inode *ino,
-                    struct io_arguments *ioargs,
-                    struct ioctx **ioctxp);
-int llu_iop_ipwritev(struct inode *ino,
-                     struct io_arguments *ioargs,
-                     struct ioctx **ioctxp);
+int llu_iop_ipreadv(struct inode *ino, struct ioctx *ioctxp);
+int llu_iop_ipwritev(struct inode *ino, struct ioctx *ioctxp);
+int llu_vmtruncate(struct inode * inode, loff_t offset);
+void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid);
+int llu_objects_destroy(struct ptlrpc_request *request, struct inode *dir);
 
 /* rw.c */
 int llu_iop_iodone(struct ioctx *ioctxp __IS_UNUSED);
-ssize_t llu_file_write(struct inode *inode, const struct iovec *iovec,
+struct llu_sysio_callback_args*
+llu_file_write(struct inode *inode, const struct iovec *iovec,
 		       size_t iovlen, loff_t pos);
-ssize_t llu_file_read(struct inode *inode, const struct iovec *iovec,
+struct llu_sysio_callback_args*
+llu_file_read(struct inode *inode, const struct iovec *iovec,
                        size_t iovlen, loff_t pos);
+int llu_extent_lock_no_validate(struct ll_file_data *fd,
+                               struct inode *inode,
+                               struct lov_stripe_md *lsm,
+                               int mode,
+                               struct ldlm_extent *extent,
+                               struct lustre_handle *lockh,
+                               int ast_flags);
+int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
+                   struct lov_stripe_md *lsm,
+                   int mode, struct ldlm_extent *extent,
+                   struct lustre_handle *lockh);
+int llu_extent_unlock(struct ll_file_data *fd, struct inode *inode,
+                struct lov_stripe_md *lsm, int mode,
+                struct lustre_handle *lockh);
+
+/* namei.c */
+int llu_iop_lookup(struct pnode *pnode,
+                   struct inode **inop,
+                   struct intent *intnt,
+                   const char *path);
+void unhook_stale_inode(struct pnode *pno);
+struct inode *llu_inode_from_lock(struct ldlm_lock *lock);
 
 #endif
diff --git a/lustre/liblustre/lltest.c b/lustre/liblustre/lltest.c
index acdc47e987cfe5fc02ad6e22b84245aa863db134..ac6e8ad0dcceb8522cc5636753b54d9161658d92 100644
--- a/lustre/liblustre/lltest.c
+++ b/lustre/liblustre/lltest.c
@@ -27,132 +27,359 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <getopt.h>
-#include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/queue.h>
-#include <sys/statvfs.h>
+#include <signal.h>
 
 #include <sysio.h>
 #include <mount.h>
 
+#include "test_common.h"
 
-int do_stat(const char *name)
+#define ENTRY(str)                                                      \
+        do {                                                            \
+                char buf[100];                                          \
+                int len;                                                \
+                sprintf(buf, "===== START: %s ", (str));                \
+                len = strlen(buf);                                      \
+                if (len < 79) {                                         \
+                        memset(buf+len, '=', 100-len);                  \
+                        buf[79] = '\n';                                 \
+                        buf[80] = 0;                                    \
+                }                                                       \
+                printf("%s", buf);                                      \
+        } while (0)
+
+#define LEAVE()                                                         \
+        do {                                                            \
+                printf("----- END TEST successfully ---");              \
+                printf("-----------------------------");                \
+                printf("-------------------\n");                        \
+        } while (0)
+
+void t1()
 {
-	struct stat stat;
+        char *path="/mnt/lustre/test_t1";
+        ENTRY("create/delete");
 
-	if (lstat(name, &stat)) {
-		perror("failed to stat: ");
-		return -1;
-	}
-	printf("******* stat '%s' ********\n", name);
-	printf("ino:\t\t%lu\n",stat.st_ino);
-	printf("mode:\t\t%o\n",stat.st_mode);
-	printf("nlink:\t\t%d\n",stat.st_nlink);
-        printf("uid/gid:\t%d/%d\n", stat.st_uid, stat.st_gid);
-        printf("size:\t\t%ld\n", stat.st_size);
-        printf("blksize:\t%ld\n", stat.st_blksize);
-        printf("block count:\t%ld\n", stat.st_blocks);
-	printf("atime:\t\t%lu\n",stat.st_atime);
-	printf("mtime:\t\t%lu\n",stat.st_mtime);
-	printf("ctime:\t\t%lu\n",stat.st_ctime);
-	printf("******* end stat ********\n");
+        t_touch(path);
+        t_unlink(path);
+        LEAVE();
+}
 
-	return 0;
+void t2()
+{
+        char *path="/mnt/lustre/test_t2";
+        ENTRY("mkdir/rmdir");
+
+        t_mkdir(path);
+        t_rmdir(path);
+        LEAVE();
 }
-/*
- * Get stats of file and file system.
- *
- * Usage: test_stats [-a] [-r <root-path>] [-m <root-driver>] [<path> ...]
- */
 
-extern int lllib_init(char *arg);
+void t3()
+{
+        char *path="/mnt/lustre/test_t3";
+        ENTRY("regular stat");
 
-char	*root_driver = "llite";
-char	*root_path = "/";
-unsigned mntflgs = 0;
-struct mount root_mount;
+        t_touch(path);
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t4()
+{
+        char *path="/mnt/lustre/test_t4";
+        ENTRY("dir stat");
+
+        t_mkdir(path);
+        t_check_stat(path, NULL);
+        t_rmdir(path);
+        LEAVE();
+}
 
-extern int portal_debug;
-extern int portal_subsystem_debug;
+#define PAGE_SIZE (4096)
+#define _npages (512)
 
-char* files[] = {"/dir1", "/dir1/file1", "/dir1/file2", "/dir1/dir2", "/dir1/dir2/file3"};
+static int _buffer[_npages][PAGE_SIZE/sizeof(int)];
 
-int
-main(int argc, char * const argv[])
+/* pos:   i/o start from
+ * xfer:  npages per transfer
+ */
+static void pages_io(int xfer, loff_t pos)
 {
-	struct stat statbuf;
-	int rc, err, i, fd, written, readed;
-	char pgbuf[4096], readbuf[4096];
-	int npages;
-
-	if (_sysio_init() != 0) {
-		perror("init sysio");
-		exit(1);
-	}
-	err = lllib_init(argv[1]);
-	if (err) {
-		perror("init llite driver");
-		exit(1);
-	}	
-
-	err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
-	if (err) {
-		errno = -err;
-		perror(root_driver);
-		exit(1);
-	}
-#if 0
-	for (i=0; i< sizeof(files)/sizeof(char*); i++) {
-		printf("******** stat %s *********\n", files[i]);
-		/* XXX ugly, only for testing */
-		err = fixme_lstat(files[i], &statbuf);
-		if (err)
-			perror(root_driver);
-		printf("******** end stat %s: %d*********\n", files[i], err);
-	}
-#endif
-#if 0
-	portal_debug = 0;
-	portal_subsystem_debug = 0;
-	npages = 10;
-
-	fd = open("/newfile01", O_RDWR|O_CREAT|O_TRUNC, 00664);
-	printf("***************** open return %d ****************\n", fd);
-
-	printf("***************** begin write pages ****************\n");
-	for (i = 0; i < npages; i++ ) {
-		memset(pgbuf, ('A'+ i%10), 4096);
-		written = write(fd, pgbuf, 4096);
-		printf(">>> page %d: %d bytes written\n", i, written);
+        char *path="/mnt/lustre/test_t5";
+        int check_sum[_npages] = {0,};
+        int fd, rc, i, j;
+
+        memset(_buffer, 0, sizeof(_buffer));
+
+        /* create sample data */
+        for (i = 0; i < _npages; i++) {
+                for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
+                        _buffer[i][j] = rand();
+                }
+        }
+
+        /* compute checksum */
+        for (i = 0; i < _npages; i++) {
+                for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
+                        check_sum[i] += _buffer[i][j];
+                }
+        }
+
+        t_touch(path);
+
+	fd = t_open(path);
+
+        /* write */
+	lseek(fd, pos, SEEK_SET);
+	for (i = 0; i < _npages; i += xfer) {
+		rc = write(fd, _buffer[i], PAGE_SIZE * xfer);
+                if (rc != PAGE_SIZE * xfer) {
+                        printf("write error %d (i = %d)\n", rc, i);
+                        exit(1);
+                }
 	}
+        printf("succefully write %d pages\n", _npages);
 
-	printf("***************** begin read pages ****************\n");
-	lseek(fd, 0, SEEK_SET);
+        memset(_buffer, 0, sizeof(_buffer));
 
-	for (i = 0; i < npages; i++ ) {
-		memset(readbuf, '8', 4096);
-		readed = read(fd, readbuf, 4096);
-		readbuf[10] = 0;
-		printf("<<< page %d: %d bytes (%s)\n", i, readed, readbuf);
+        /* read */
+	lseek(fd, pos, SEEK_SET);
+	for (i = 0; i < _npages; i += xfer) {
+		rc = read(fd, _buffer[i], PAGE_SIZE * xfer);
+                if (rc != PAGE_SIZE * xfer) {
+                        printf("read error %d (i = %d)\n", rc, i);
+                        exit(1);
+                }
 	}
-        close(fd);
-#endif
+        printf("succefully read %d pages\n", _npages);
+
+        /* compute checksum */
+        for (i = 0; i < _npages; i++) {
+                int sum = 0;
+                for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
+                        sum += _buffer[i][j];
+                }
+                if (sum != check_sum[i]) {
+                        printf("chunk %d checksum error: expected 0x%x, get 0x%x\n",
+                                i, check_sum[i], sum);
+                }
+        }
+        printf("checksum verified OK!\n");
+
+	t_close(fd);
+        t_unlink(path);
+}
+
+void t5()
+{
+        char text[256];
+        loff_t off_array[] = {1, 17, 255, 257, 4095, 4097, 8191, 1024*1024*1024};
+        int np = 1, i;
+        loff_t offset = 0;
+
+        while (np <= _npages) {
+                sprintf(text, "pages_io: %d per transfer, offset %lld",
+                        np, offset);
+                ENTRY(text);
+                pages_io(np, offset);
+                LEAVE();
+                np += np;
+        }
+
+        for (i = 0; i < sizeof(off_array)/sizeof(loff_t); i++) {
+                offset = off_array[i];
+                sprintf(text, "pages_io: 16 per transfer, offset %lld",
+                        offset);
+                ENTRY(text);
+                pages_io(16, offset);
+                LEAVE();
+        }
+}
+
+void t6()
+{
+        char *path="/mnt/lustre/test_t6";
+        char *path2="/mnt/lustre/test_t6_link";
+        ENTRY("symlink");
+
+        t_touch(path);
+        t_symlink(path, path2);
+        t_check_stat(path2, NULL);
+        t_unlink(path2);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t7()
+{
+        char *path="/mnt/lustre/test_t7";
+        ENTRY("mknod");
+
+        t_mknod(path, S_IFCHR | 0644, 5, 4);
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t8()
+{
+        char *path="/mnt/lustre/test_t8";
+        ENTRY("chmod");
+
+        t_touch(path);
+        t_chmod_raw(path, 0700);
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t9()
+{
+        char *path="/mnt/lustre/test_t9";
+        char *path2="/mnt/lustre/test_t9_link";
+        ENTRY("hard link");
+
+        t_touch(path);
+        t_link(path, path2);
+        t_check_stat(path, NULL);
+        t_check_stat(path2, NULL);
+        t_unlink(path);
+        t_unlink(path2);
+        LEAVE();
+}
+
+void t10()
+{
+        char *dir1="/mnt/lustre/test_t10_dir1";
+        char *dir2="/mnt/lustre/test_t10_dir2";
+        char *path1="/mnt/lustre/test_t10_reg1";
+        char *path2="/mnt/lustre/test_t10_reg2";
+        char *rename1="/mnt/lustre/test_t10_dir1/rename1";
+        char *rename2="/mnt/lustre/test_t10_dir2/rename2";
+        char *rename3="/mnt/lustre/test_t10_dir2/rename3";
+        ENTRY("rename");
+
+        t_mkdir(dir1);
+        t_mkdir(dir2);
+        t_touch(path1);
+        t_touch(path2);
+        t_rename(path1, rename1);
+        t_rename(path2, rename2);
+        t_rename(rename1, rename2);
+        t_rename(dir1, rename3);
+        t_unlink(rename2);
+        t_rmdir(rename3);
+        t_rmdir(dir2);
+        LEAVE();
+}
+
+void t100()
+{
+        char *base="/mnt/lustre";
+        char path[4096], path2[4096];
+        int i, j, level = 5, nreg = 5;
+        ENTRY("deep tree");
+
+        strcpy(path, base);
+
+        for (i = 0; i < level; i++) {
+                for (j = 0; j < nreg; j++) {
+                        sprintf(path2, "%s/file%d", path, j);
+                        t_touch(path2);
+                }
+
+                strcat(path, "/dir");
+                t_mkdir(path);
+        }
+
+        for (i = level; i > 0; i--) {
+                strcpy(path, base);
+                for (j = 1; j < i; j++)
+                        strcat(path, "/dir");
+                
+                for (j = 0; j < nreg; j++) {
+                        sprintf(path2, "%s/file%d", path, j);
+                        t_unlink(path2);
+                }
+
+                strcat(path, "/dir");
+                t_rmdir(path);
+        }
+
+        LEAVE();
+}
+
+extern void __liblustre_setup_(void);
+extern void __liblustre_cleanup_(void);
+
+void usage(char *cmd)
+{
+        printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
+        printf("       \t%s --dumpfile dumpfile\n", cmd);
+        exit(-1);
+}
+
+int main(int argc, char * const argv[])
+{
+        int opt_index, c;
+        static struct option long_opts[] = {
+                {"target", 1, 0, 0},
+                {"dumpfile", 1, 0, 0},
+                {0, 0, 0, 0}
+        };
+
+        if (argc <= 1)
+                usage(argv[0]);
+
+        while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
+                switch (c) {
+                case 0: {
+                        printf("optindex %d\n", opt_index);
+                        if (!optarg[0])
+                                usage(argv[0]);
+
+                        if (!strcmp(long_opts[opt_index].name, "target")) {
+                                setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
+                        } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
+                                setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
+                        } else
+                                usage(argv[0]);
+                        break;
+                }
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+        if (optind != argc)
+                usage(argv[0]);
+
+        __liblustre_setup_();
+
+#ifndef __CYGWIN__
+        t1();
+        t2();
+        t3();
+        t4();
+        t5();
+        t6();
+        t7();
+        t8();
+        t9();
+        t10();
 
-#if 1
-        //rc = chown("/newfile01", 10, 20);
-        rc = chmod("/newfile01", 0777);
-        printf("-------------- chmod return %d -----------\n", rc);
-        do_stat("/newfile01");
+        t100();
 #endif
 
-	printf("sysio is about shutdown\n");
-	/*
-	 * Clean up.
-	 */
-	_sysio_shutdown();
+	printf("liblustre is about shutdown\n");
+        __liblustre_cleanup_();
 
 	printf("complete successfully\n");
 	return 0;
diff --git a/lustre/liblustre/namei.c b/lustre/liblustre/namei.c
new file mode 100644
index 0000000000000000000000000000000000000000..1dceb8b36485441bbfa42fe2616847c0260f84e1
--- /dev/null
+++ b/lustre/liblustre/namei.c
@@ -0,0 +1,634 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Light Super operations
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/queue.h>
+
+#include <sysio.h>
+#include <fs.h>
+#include <mount.h>
+#include <inode.h>
+#include <file.h>
+
+#include "llite_lib.h"
+
+static void ll_intent_release(struct lookup_intent *it)
+{
+        struct lustre_handle *handle;
+        ENTRY;
+
+        /* LASSERT(ll_d2d(de) != NULL); */
+
+        if (it->d.lustre.it_lock_mode) {
+                handle = (struct lustre_handle *)&it->d.lustre.it_lock_handle;
+                CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64
+                       " from it %p\n",
+                       handle->cookie, it);
+                ldlm_lock_decref(handle, it->d.lustre.it_lock_mode);
+
+                /* intent_release may be called multiple times, from
+                   this thread and we don't want to double-decref this
+                   lock (see bug 494) */
+                it->d.lustre.it_lock_mode = 0;
+        }
+        it->it_magic = 0;
+        it->it_op_release = 0;
+        EXIT;
+}
+
+#if 0
+static void llu_mdc_lock_set_inode(struct lustre_handle *lockh,
+                                   struct inode *inode)
+{
+        struct ldlm_lock *lock = ldlm_handle2lock(lockh);
+        ENTRY;
+
+        LASSERT(lock != NULL);
+        lock->l_data = inode;
+        LDLM_LOCK_PUT(lock);
+        EXIT;
+}
+
+static int pnode_revalidate_finish(struct ptlrpc_request *request,
+                                   struct inode *parent, struct pnode *pnode,
+                                   struct lookup_intent *it, int offset,
+                                   obd_id ino)
+{
+        struct llu_sb_info    *sbi = llu_i2sbi(parent);
+        struct pnode_base     *pb = pnode->p_base;
+        struct mds_body       *body;
+        struct lov_stripe_md  *lsm = NULL;
+        struct lov_mds_md     *lmm;
+        int                    lmmsize;
+        int                    rc = 0;
+        ENTRY;
+
+        /* NB 1 request reference will be taken away by ll_intent_lock()
+         * when I return */
+
+        if (it_disposition(it, DISP_LOOKUP_NEG))
+                RETURN(-ENOENT);
+
+        /* We only get called if the mdc_enqueue() called from
+         * ll_intent_lock() was successful.  Therefore the mds_body is
+         * present and correct, and the eadata is present (but still
+         * opaque, so only obd_unpackmd() can check the size) */
+        body = lustre_msg_buf(request->rq_repmsg, offset, sizeof (*body));
+        LASSERT (body != NULL);
+        LASSERT_REPSWABBED (request, offset);
+
+        if (body->valid & OBD_MD_FLEASIZE) {
+                /* Only bother with this if inodes's LSM not set? */
+
+                if (body->eadatasize == 0) {
+                        CERROR ("OBD_MD_FLEASIZE set, but eadatasize 0\n");
+                        GOTO (out, rc = -EPROTO);
+                }
+                lmmsize = body->eadatasize;
+                lmm = lustre_msg_buf (request->rq_repmsg, offset + 1, lmmsize);
+                LASSERT (lmm != NULL);
+                LASSERT_REPSWABBED (request, offset + 1);
+
+                rc = obd_unpackmd (&sbi->ll_osc_conn,
+                                   &lsm, lmm, lmmsize);
+                if (rc < 0) {
+                        CERROR ("Error %d unpacking eadata\n", rc);
+                        LBUG();
+                        /* XXX don't know if I should do this... */
+                        GOTO (out, rc);
+                        /* or skip the ll_update_inode but still do
+                         * mdc_lock_set_inode() */
+                }
+                LASSERT (rc >= sizeof (*lsm));
+                rc = 0;
+        }
+
+        llu_update_inode(pb->pb_ino, body, lsm);
+
+        if (lsm != NULL &&
+            llu_i2info(pb->pb_ino)->lli_smd != lsm)
+                obd_free_memmd (&sbi->ll_osc_conn, &lsm);
+
+        llu_mdc_lock_set_inode((struct lustre_handle *)&it->d.lustre.it_lock_handle,
+                               pb->pb_ino);
+ out:
+        RETURN(rc);
+}
+#endif
+
+/*
+ * remove the stale inode from pnode
+ */
+void unhook_stale_inode(struct pnode *pno)
+{
+        struct inode *inode = pno->p_base->pb_ino;
+        ENTRY;
+
+        LASSERT(inode);
+        LASSERT(llu_i2info(inode)->lli_stale_flag);
+
+        pno->p_base->pb_ino = NULL;
+
+        if (!llu_i2info(inode)->lli_open_count) {
+                CDEBUG(D_INODE, "unhook inode %p (ino %lu) from pno %p\n",
+                                inode, llu_i2info(inode)->lli_st_ino, pno);
+                I_RELE(inode);
+                if (!inode->i_ref)
+                        _sysio_i_gone(inode);
+        }
+
+        EXIT;
+        return;
+}
+
+void llu_lookup_finish_locks(struct lookup_intent *it, struct pnode *pnode)
+{
+        LASSERT(it);
+        LASSERT(pnode);
+
+        if (it && pnode->p_base->pb_ino != NULL) {
+                struct inode *inode = pnode->p_base->pb_ino;
+                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%lu)\n",
+                       inode, llu_i2info(inode)->lli_st_ino,
+                       llu_i2info(inode)->lli_st_generation);
+                mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);
+        }
+
+        /* drop IT_LOOKUP locks */
+        if (it->it_op == IT_LOOKUP)
+                ll_intent_release(it);
+
+}
+
+static inline void ll_invalidate_inode_pages(struct inode * inode)
+{
+        /* do nothing */
+}
+
+static int llu_mdc_blocking_ast(struct ldlm_lock *lock,
+                                struct ldlm_lock_desc *desc,
+                                void *data, int flag)
+{
+        int rc;
+        struct lustre_handle lockh;
+        ENTRY;
+
+
+        switch (flag) {
+        case LDLM_CB_BLOCKING:
+                ldlm_lock2handle(lock, &lockh);
+                rc = ldlm_cli_cancel(&lockh);
+                if (rc < 0) {
+                        CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc);
+                        RETURN(rc);
+                }
+                break;
+        case LDLM_CB_CANCELING: {
+                struct inode *inode = llu_inode_from_lock(lock);
+                struct llu_inode_info *lli;
+
+                /* Invalidate all dentries associated with this inode */
+                if (inode == NULL)
+                        break;
+
+                lli =  llu_i2info(inode);
+
+                clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags);
+
+                if (lock->l_resource->lr_name.name[0] != lli->lli_st_ino ||
+                    lock->l_resource->lr_name.name[1] != lli->lli_st_generation) {
+                        LDLM_ERROR(lock, "data mismatch with ino %lu/%lu",
+                                   lli->lli_st_ino, lli->lli_st_generation);
+                }
+                if (S_ISDIR(lli->lli_st_mode)) {
+                        CDEBUG(D_INODE, "invalidating inode %lu\n",
+                               lli->lli_st_ino);
+
+                        ll_invalidate_inode_pages(inode);
+                }
+
+/*
+                if (inode->i_sb->s_root &&
+                    inode != inode->i_sb->s_root->d_inode)
+                        ll_unhash_aliases(inode);
+*/
+                I_RELE(inode);
+                break;
+        }
+        default:
+                LBUG();
+        }
+
+        RETURN(0);
+}
+
+int llu_pb_revalidate(struct pnode *pnode, int flags, struct lookup_intent *it)
+{
+        struct pnode_base *pb = pnode->p_base;
+        struct ll_fid pfid, cfid;
+        struct it_cb_data icbd;
+        struct ll_uctxt ctxt;
+        struct ptlrpc_request *req = NULL;
+        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
+        struct obd_export *exp;
+        int rc;
+        ENTRY;
+
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%x\n",
+               pb->pb_name.name, it ? it->it_op : 0);
+
+        /* We don't want to cache negative dentries, so return 0 immediately.
+         * We believe that this is safe, that negative dentries cannot be
+         * pinned by someone else */
+        if (pb->pb_ino == NULL) {
+                CDEBUG(D_INODE, "negative pb\n");
+                RETURN(0);
+        }
+
+        /* check stale inode */
+        if (llu_i2info(pb->pb_ino)->lli_stale_flag)
+                unhook_stale_inode(pnode);
+
+        /* check again because unhook_stale_inode() might generate
+         * negative pnode */
+        if (pb->pb_ino == NULL) {
+                CDEBUG(D_INODE, "negative pb\n");
+                RETURN(0);
+        }
+
+        /* This is due to bad interaction with libsysio. remove this when we
+         * switched to libbsdio
+         */
+        {
+                struct llu_inode_info *lli = llu_i2info(pb->pb_ino);
+                if (lli->lli_it) {
+                        CDEBUG(D_INODE, "inode %lu still have intent "
+                                        "%p(opc 0x%x), release it\n",
+                                        lli->lli_st_ino, lli->lli_it,
+                                        lli->lli_it->it_op);
+                        ll_intent_release(lli->lli_it);
+                        OBD_FREE(lli->lli_it, sizeof(*lli->lli_it));
+                        lli->lli_it = NULL;
+                }
+        }
+
+        exp = llu_i2mdcexp(pb->pb_ino);
+        ll_inode2fid(&pfid, pnode->p_parent->p_base->pb_ino);
+        ll_inode2fid(&cfid, pb->pb_ino);
+        icbd.icbd_parent = pnode->p_parent->p_base->pb_ino;
+        icbd.icbd_child = pnode;
+
+        if (!it) {
+                it = &lookup_it;
+                it->it_op_release = ll_intent_release;
+        }
+
+        ll_i2uctxt(&ctxt, pnode->p_parent->p_base->pb_ino, pb->pb_ino);
+
+        rc = mdc_intent_lock(exp, &ctxt, &pfid,
+                             pb->pb_name.name, pb->pb_name.len,
+                             NULL, 0, &cfid, it, flags, &req,
+                             llu_mdc_blocking_ast);
+        /* If req is NULL, then mdc_intent_lock only tried to do a lock match;
+         * if all was well, it will return 1 if it found locks, 0 otherwise. */
+        if (req == NULL && rc >= 0)
+                GOTO(out, rc);
+
+        /* unfortunately ll_intent_lock may cause a callback and revoke our
+           dentry */
+        /*
+        spin_lock(&dcache_lock);
+        list_del_init(&de->d_hash);
+        spin_unlock(&dcache_lock);
+        d_rehash(de);
+        */
+        if (it->it_op & (IT_OPEN | IT_GETATTR))
+                LL_SAVE_INTENT(pb->pb_ino, it);
+        RETURN(1);
+ out:
+        if (req)
+                ptlrpc_req_finished(req);
+        if (rc == 0) {
+                LASSERT(pb->pb_ino);
+                if (S_ISDIR(llu_i2info(pb->pb_ino)->lli_st_mode))
+                        ll_invalidate_inode_pages(pb->pb_ino);
+                llu_i2info(pb->pb_ino)->lli_stale_flag = 1;
+                unhook_stale_inode(pnode);
+        } else {
+                llu_lookup_finish_locks(it, pnode);
+                llu_i2info(pb->pb_ino)->lli_stale_flag = 0;
+                if (it->it_op & (IT_OPEN | IT_GETATTR))
+                        LL_SAVE_INTENT(pb->pb_ino, it);
+        }
+        RETURN(rc);
+}
+
+static int lookup_it_finish(struct ptlrpc_request *request, int offset,
+                            struct lookup_intent *it, void *data)
+{
+        struct it_cb_data *icbd = data;
+        struct pnode *child = icbd->icbd_child;
+        struct inode *parent = icbd->icbd_parent;
+        struct llu_sb_info *sbi = llu_i2sbi(parent);
+        struct inode *inode = NULL;
+        int rc;
+
+        /* NB 1 request reference will be taken away by ll_intent_lock()
+         * when I return */
+        /* XXX libsysio require the inode must be generated here XXX */
+        if ((it->it_op & IT_CREAT) || !it_disposition(it, DISP_LOOKUP_NEG)) {
+                struct lustre_md md;
+                struct llu_inode_info *lli;
+                ENTRY;
+
+                rc = mdc_req2lustre_md(request, offset, sbi->ll_osc_exp, &md);
+                if (rc)
+                        RETURN(rc);
+
+                inode = llu_iget(parent->i_fs, &md);
+                if (!inode) {
+                        /* free the lsm if we allocated one above */
+                        if (md.lsm != NULL)
+                                obd_free_memmd(sbi->ll_osc_exp, &md.lsm);
+                        RETURN(-ENOMEM);
+                } else if (md.lsm != NULL &&
+                           llu_i2info(inode)->lli_smd != md.lsm) {
+                        obd_free_memmd(sbi->ll_osc_exp, &md.lsm);
+                }
+
+                lli = llu_i2info(inode);
+
+                /* If this is a stat, get the authoritative file size */
+                if (it->it_op == IT_GETATTR && S_ISREG(lli->lli_st_mode) &&
+                    lli->lli_smd != NULL) {
+                        struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
+                        struct lustre_handle lockh = {0};
+                        struct lov_stripe_md *lsm = lli->lli_smd;
+                        ldlm_error_t rc;
+
+                        LASSERT(lsm->lsm_object_id != 0);
+
+                        rc = llu_extent_lock(NULL, inode, lsm, LCK_PR, &extent,
+                                            &lockh);
+                        if (rc != ELDLM_OK) {
+                                I_RELE(inode);
+                                RETURN(-EIO);
+                        }
+                        llu_extent_unlock(NULL, inode, lsm, LCK_PR, &lockh);
+                }
+        } else {
+                ENTRY;
+        }
+
+        if (inode && (it->it_op & (IT_OPEN | IT_GETATTR)))
+                LL_SAVE_INTENT(inode, it);
+/*
+        dentry->d_op = &ll_d_ops;
+        ll_set_dd(dentry);
+
+        if (dentry == saved)
+                d_add(dentry, inode);
+*/
+        child->p_base->pb_ino = inode;
+
+        RETURN(0);
+}
+
+struct inode *llu_inode_from_lock(struct ldlm_lock *lock)
+{
+        struct inode *inode;
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+
+        if (lock->l_ast_data) {
+                inode = (struct inode *)lock->l_ast_data;
+                I_REF(inode);
+        } else
+                inode = NULL;
+
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+        return inode;
+}
+
+/* XXX */
+#define EXT2_NAME_LEN (255)
+
+static int llu_lookup_it(struct inode *parent, struct pnode *pnode,
+                         struct lookup_intent *it, int flags)
+{
+        struct ll_fid pfid;
+        struct ll_uctxt ctxt;
+        struct it_cb_data icbd;
+        struct ptlrpc_request *req = NULL;
+        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
+        int rc;
+        ENTRY;
+
+        if (pnode->p_base->pb_name.len > EXT2_NAME_LEN)
+                RETURN(-ENAMETOOLONG);
+
+
+/*
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p),intent=%s\n",
+               dentry->d_name.name, parent->i_ino, parent->i_generation,
+               parent, LL_IT2STR(it));
+
+        if (d_mountpoint(dentry))
+                CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it));
+
+        ll_frob_intent(&it, &lookup_it);
+*/
+
+        if (!it) {
+                it = &lookup_it;
+                it->it_op_release = ll_intent_release;
+        }
+
+        icbd.icbd_child = pnode;
+        icbd.icbd_parent = parent;
+        icbd.icbd_child = pnode;
+        ll_inode2fid(&pfid, parent);
+        ll_i2uctxt(&ctxt, parent, NULL);
+
+        rc = mdc_intent_lock(llu_i2mdcexp(parent), &ctxt, &pfid,
+                             pnode->p_base->pb_name.name,
+                             pnode->p_base->pb_name.len,
+                             NULL, 0, NULL, it, flags, &req,
+                             llu_mdc_blocking_ast);
+        if (rc < 0)
+                GOTO(out, rc);
+        
+        rc = lookup_it_finish(req, 1, it, &icbd);
+        if (rc != 0) {
+                ll_intent_release(it);
+                GOTO(out, rc);
+        }
+
+        llu_lookup_finish_locks(it, pnode);
+
+/*
+        if (dentry == save)
+                GOTO(out, retval = NULL);
+        else
+                GOTO(out, retval = dentry);
+*/
+ out:
+        if (req)
+                ptlrpc_req_finished(req);
+        return rc;
+}
+
+static struct lookup_intent*
+translate_lookup_intent(struct intent *intent, const char *path)
+{
+        struct lookup_intent *it;
+        int fmode;
+
+        /* libsysio trick */
+        if (!intent || path) {
+                CDEBUG(D_VFSTRACE, "not intent needed\n");
+                return NULL;
+        }
+
+        OBD_ALLOC(it, sizeof(*it));
+        LASSERT(it);
+
+        memset(it, 0, sizeof(*it));
+
+        /* libsysio will assign intent like following:
+         * NOTE: INT_CREAT has include INT_UPDPARENT
+         *
+         * open: INT_OPEN [| INT_CREAT]
+         * mkdir: INT_CREAT
+         * symlink: INT_CREAT
+         * unlink: INT_UPDPARENT
+         * rmdir: INT_UPDPARENT
+         * mknod: INT_CREAT
+         * stat: INT_GETATTR
+         * setattr: NULL
+         *
+         * following logic is adjusted for libsysio
+         */
+
+        it->it_flags = intent->int_arg2 ? *((int*)intent->int_arg2) : 0;
+
+        if (intent->int_opmask & INT_OPEN) {
+                it->it_op |= IT_OPEN;
+
+                /* convert access mode from O_ to FMODE_ */
+                if (it->it_flags & O_WRONLY)
+                        fmode = FMODE_WRITE;
+                else if (it->it_flags & O_RDWR)
+                        fmode = FMODE_READ | FMODE_WRITE;
+                else
+                        fmode = FMODE_READ;
+                it->it_flags &= ~O_ACCMODE;
+                it->it_flags |= fmode;
+        }
+
+        /*
+        else if (intent->int_opmask & INT_CREAT)
+                it->it_op |= IT_LOOKUP;
+         */
+
+        /* FIXME libsysio has strange code on intent handling,
+         * more check later */
+        if (it->it_flags & O_CREAT) {
+                it->it_op |= IT_CREAT;
+                it->it_create_mode = *((int*)intent->int_arg1);
+        }
+
+        if (intent->int_opmask & INT_GETATTR)
+                it->it_op |= IT_GETATTR;
+        /* XXX */
+        if (intent->int_opmask & INT_SETATTR)
+                LBUG();
+
+        /* libsysio is different to linux vfs when doing unlink/rmdir,
+         * INT_UPDPARENT was passed down during name resolution. Here
+         * we treat it as normal lookup, later unlink()/rmdir() will
+         * do the actual work */
+
+        /* conform to kernel code, if only IT_LOOKUP was set, don't
+         * pass down it */
+        if (!it->it_op || it->it_op == IT_LOOKUP) {
+                OBD_FREE(it, sizeof(*it));
+                it = NULL;
+        }
+        if (it)
+                it->it_op_release = ll_intent_release;
+
+        CDEBUG(D_VFSTRACE, "final intent 0x%x\n", it ? it->it_op : 0);
+        return it;
+}
+
+int llu_iop_lookup(struct pnode *pnode,
+                   struct inode **inop,
+                   struct intent *intnt,
+                   const char *path)
+{
+        struct lookup_intent *it;
+        int rc;
+        ENTRY;
+
+        *inop = NULL;
+
+        /* the mount root inode have no name, so don't call
+         * remote in this case. but probably we need revalidate
+         * it here? FIXME */
+        if (pnode->p_mount->mnt_root == pnode) {
+                struct inode *i = pnode->p_base->pb_ino;
+                *inop = i;
+                return 0;
+        }
+
+        if (!pnode->p_base->pb_name.len)
+                RETURN(-EINVAL);
+
+        it = translate_lookup_intent(intnt, path);
+
+        /* param flags is not used, let it be 0 */
+        if (llu_pb_revalidate(pnode, 0, it)) {
+                LASSERT(pnode->p_base->pb_ino);
+                *inop = pnode->p_base->pb_ino;
+                RETURN(0);
+        }
+
+        rc = llu_lookup_it(pnode->p_parent->p_base->pb_ino, pnode, it, 0);
+        if (!rc) {
+                if (!pnode->p_base->pb_ino)
+                        rc = -ENOENT;
+                else
+                        *inop = pnode->p_base->pb_ino;
+        }
+
+        RETURN(rc);
+}
+
diff --git a/lustre/liblustre/recovery_small.c b/lustre/liblustre/recovery_small.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1292c25ec4ee77df1d067491e1952d9fa4c5973
--- /dev/null
+++ b/lustre/liblustre/recovery_small.c
@@ -0,0 +1,375 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Light user test program
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/queue.h>
+#include <getopt.h>
+
+#include <sysio.h>
+#include <mount.h>
+
+#include "test_common.h"
+
+static struct {
+        const char   *name;
+        unsigned long code;
+} drop_arr [] =
+{
+        {"MDS_REQUEST", 0x123},
+        {"MDS_REPLY", 0x122},
+        {NULL, 0}
+};
+
+static int drop_index = 0;
+
+static char mds_server[1024] = {0, };
+
+int do_stat(const char *name, struct stat *buf)
+{
+	struct stat stat;
+        int rc;
+
+	rc = lstat(name, &stat);
+        if (rc) {
+		printf("error %d stat %s\n", rc, name);
+		exit(1);
+	}
+        if (buf)
+                memcpy(buf, &stat, sizeof(*buf));
+
+	return 0;
+}
+
+void prepare_reg(const char *path)
+{
+        int fd, rc;
+
+        fd = open(path, O_RDWR|O_CREAT, 00644);
+        if (fd < 0) {
+                printf("error %d create %s\n", fd, path);
+                exit(1);
+        }
+
+        rc = close(fd);
+        if (rc) {
+                printf("error %d close %s\n", rc, path);
+                exit(1);
+        }
+}
+
+void cleanup_reg(const char *path)
+{
+        int rc;
+
+        rc = unlink(path);
+        if (rc) {
+                printf("error %d unlink %s\n", rc, path);
+                exit(1);
+        }
+}
+
+void prepare_dir(const char *path)
+{
+        int rc;
+
+        rc = mkdir(path, 00644);
+        if (rc < 0) {
+                printf("error %d mkdir %s\n", rc, path);
+                exit(1);
+        }
+}
+
+void cleanup_dir(const char *path)
+{
+        int rc;
+
+        rc = rmdir(path);
+        if (rc) {
+                printf("error %d unlink %s\n", rc, path);
+                exit(1);
+        }
+}
+
+#define FAIL()                                                             \
+    do {                                                                   \
+        char cmd[1024];                                                    \
+        int rc;                                                            \
+                                                                           \
+        if (drop_arr[drop_index].name) {                                   \
+            printf("server drops next %s\n", drop_arr[drop_index].name);   \
+            sprintf(cmd,                                                   \
+                    "ssh %s \"echo %lu > /proc/sys/lustre/fail_loc\"",     \
+                    mds_server, drop_arr[drop_index].code);                \
+            if (system(cmd)) {                                             \
+                printf("error excuting remote command: %d\n", rc);         \
+                exit(rc);                                                  \
+            }                                                              \
+        }                                                                  \
+    } while (0)
+
+#define RECOVER()                                                          \
+    do {                                                                   \
+        char cmd[1024];                                                    \
+                                                                           \
+        if (drop_arr[drop_index].name) {                                   \
+            sprintf(cmd, "ssh %s \"echo 0 > /proc/sys/lustre/fail_loc\"",  \
+                    mds_server);                                           \
+            system(cmd);                                                   \
+        }                                                                  \
+    } while (0)
+
+#define ENTRY(str)                                                      \
+        do {                                                            \
+                char buf[100];                                          \
+                int len;                                                \
+                sprintf(buf, "===== START: %s ", (str));                \
+                len = strlen(buf);                                      \
+                if (len < 79) {                                         \
+                        memset(buf+len, '=', 100-len);                  \
+                        buf[79] = '\n';                                 \
+                        buf[80] = 0;                                    \
+                }                                                       \
+                printf("%s", buf);                                      \
+        } while (0)
+
+#define LEAVE()                                                         \
+        do {                                                            \
+                printf("----- END TEST successfully ---");              \
+                printf("-----------------------------");                \
+                printf("-------------------\n");                        \
+        } while (0)
+
+
+void t1()
+{
+        char *path="/mnt/lustre/test_t1";
+        ENTRY("create/delete");
+
+        FAIL();
+        t_touch(path);
+        RECOVER();
+        FAIL();
+        t_unlink(path);
+        RECOVER();
+        LEAVE();
+}
+
+void t2()
+{
+        char *path="/mnt/lustre/test_t2";
+        ENTRY("mkdir/rmdir");
+
+        FAIL();
+        t_mkdir(path);
+        RECOVER();
+        FAIL();
+        t_rmdir(path);
+        RECOVER();
+        LEAVE();
+}
+
+void t3()
+{
+        char *path="/mnt/lustre/test_t3";
+        ENTRY("regular stat");
+
+        t_touch(path);
+        FAIL();
+        t_check_stat(path, NULL);
+        RECOVER();
+        t_unlink(path);
+        LEAVE();
+}
+
+void t4()
+{
+        char *path="/mnt/lustre/test_t4";
+        ENTRY("dir stat");
+
+        t_mkdir(path);
+        FAIL();
+        t_check_stat(path, NULL);
+        RECOVER();
+        t_rmdir(path);
+        LEAVE();
+}
+
+void t5()
+{
+        char *path="/mnt/lustre/test_t5";
+        const int bufsize = 4096;
+	char wbuf[bufsize], rbuf[bufsize];
+        int npages = 100;
+        int fd, rc, i;
+        ENTRY("sequential page aligned file I/O");
+
+        t_touch(path);
+
+	fd = t_open(path);
+
+	for (i = 0; i < npages; i++ ) {
+                memset(wbuf, i, bufsize);
+		rc = write(fd, wbuf, bufsize);
+                if (rc != bufsize) {
+                        printf("write error %d (i = %d)\n", rc, i);
+                        exit(1);
+                }
+	}
+        printf("succefully write %d pages\n", npages);
+
+	lseek(fd, 0, SEEK_SET);
+
+	for (i = 0; i < npages; i++ ) {
+		memset(rbuf, 0, bufsize);
+		rc = read(fd, rbuf, bufsize);
+                if (rc != bufsize) {
+                        printf("read error %d (i = %d)\n", rc, i);
+                        exit(1);
+                }
+	}
+        printf("succefully read & verified %d pages\n", npages);
+
+        t_close(fd);
+
+        t_unlink(path);
+        LEAVE();
+}
+
+void t6()
+{
+        char *path="/mnt/lustre/test_t6";
+        char *path2="/mnt/lustre/test_t6_link";
+        ENTRY("symlink");
+
+        t_touch(path);
+        FAIL();
+        t_symlink(path, path2);
+        RECOVER();
+        t_check_stat(path2, NULL);
+        t_unlink(path2);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t7()
+{
+        char *path="/mnt/lustre/test_t7";
+        ENTRY("mknod");
+
+        FAIL();
+        t_mknod(path, S_IFCHR | 0644, 5, 4);
+        RECOVER();
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+extern int portal_debug;
+extern int portal_subsystem_debug;
+
+extern void __liblustre_setup_(void);
+extern void __liblustre_cleanup_(void);
+
+void usage(const char *cmd)
+{
+        printf("Usage: \t%s -s mds_hostname --target mdsnid:/mdsname/profile\n", cmd);
+        printf("       \t%s -s mds_hostname --dumpfile dumpfile\n", cmd);
+        exit(-1);
+}
+
+int main(int argc, char * argv[])
+{
+        int opt_index, c;
+        char cmd[1024];
+        static struct option long_opts[] = {
+                {"target", 1, 0, 0},
+                {"dumpfile", 1, 0, 0},
+                {0, 0, 0, 0}
+        };
+
+        if (argc < 3)
+                usage(argv[0]);
+
+        while ((c = getopt_long(argc, argv, "s:", long_opts, &opt_index)) != -1) {
+                switch (c) {
+                case 0: {
+                        if (!optarg[0])
+                                usage(argv[0]);
+
+                        if (!strcmp(long_opts[opt_index].name, "target")) {
+                                setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
+                        } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
+                                setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
+                        } else
+                                usage(argv[0]);
+                        break;
+                }
+                case 's':
+                        strcpy(mds_server, optarg);
+                        break;
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+        if (optind != argc)
+                usage(argv[0]);
+
+        if (strlen(mds_server) == 0)
+                usage(argv[0]);
+
+        sprintf(cmd, "ssh %s cat /dev/null", mds_server);
+        if (system(cmd)) {
+                printf("can't access server node: %s\n", mds_server);
+                exit(-1);
+        }
+
+        __liblustre_setup_();
+
+        while (drop_arr[drop_index].name) {
+                t1();
+                t2();
+                t3();
+                t4();
+                t5();
+                t6();
+                t7();
+
+                drop_index++;
+        }
+
+	printf("liblustre is about shutdown\n");
+        __liblustre_cleanup_();
+
+	printf("complete successfully\n");
+        return (0);
+}
diff --git a/lustre/liblustre/replay_single.c b/lustre/liblustre/replay_single.c
new file mode 100755
index 0000000000000000000000000000000000000000..1602a7c941b6e5f2b22e14d0ed3952b1a246638b
--- /dev/null
+++ b/lustre/liblustre/replay_single.c
@@ -0,0 +1,408 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Light user test program
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/queue.h>
+#include <signal.h>
+
+#include <sysio.h>
+#include <mount.h>
+
+#include "test_common.h"
+
+
+
+static char mds_server[1024] = {0,};
+static char barrier_script[1024] = {0,};
+static char failover_script[1024] = {0,};
+static char barrier_cmd[1024] = {0,};
+static char failover_cmd[1024] = {0,};
+
+static void replay_barrier()
+{
+        int rc;
+
+        if ((rc = system(barrier_cmd))) {
+                printf("excute barrier error: %d\n", rc);
+                exit(rc);
+        }
+}
+
+static void mds_failover()
+{
+        int rc;
+
+        if ((rc = system(failover_cmd))) {
+                printf("excute failover error: %d\n", rc);
+                exit(rc);
+        }
+}
+
+
+#define ENTRY(str)                                                      \
+        do {                                                            \
+                char buf[100];                                          \
+                int len;                                                \
+                sprintf(buf, "===== START: %s ", (str));                \
+                len = strlen(buf);                                      \
+                if (len < 79) {                                         \
+                        memset(buf+len, '=', 100-len);                  \
+                        buf[79] = '\n';                                 \
+                        buf[80] = 0;                                    \
+                }                                                       \
+                printf("%s", buf);                                      \
+        } while (0)
+
+#define LEAVE()                                                         \
+        do {                                                            \
+                printf("----- END TEST successfully ---");              \
+                printf("-----------------------------");                \
+                printf("-------------------\n");                        \
+        } while (0)
+
+void t0()
+{
+        ENTRY("empty replay");
+        replay_barrier();
+        mds_failover();
+        LEAVE();
+}
+
+void t1()
+{
+        char *path="/mnt/lustre/f1";
+        ENTRY("simple create");
+
+        replay_barrier();
+        t_create(path);
+        mds_failover();
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t2a()
+{
+        char *path="/mnt/lustre/f2a";
+        ENTRY("touch");
+
+        replay_barrier();
+        t_touch(path);
+        mds_failover();
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t2b()
+{
+        char *path="/mnt/lustre/f2b";
+        ENTRY("mcreate+touch");
+
+        t_create(path);
+        replay_barrier();
+        t_touch(path);
+        mds_failover();
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        LEAVE();
+}
+
+
+void n_create_delete(int nfiles)
+{
+        char *base="/mnt/lustre/f3_";
+        char path[100];
+        char str[100];
+        int i;
+
+        replay_barrier();
+        for (i = 0; i < nfiles; i++) {
+                sprintf(path, "%s%d\n", base, i);
+                sprintf(str, "TEST#%d CONTENT\n", i);
+                t_echo_create(path, str);
+        }
+        mds_failover();
+        for (i = 0; i < nfiles; i++) {
+                sprintf(path, "%s%d\n", base, i);
+                sprintf(str, "TEST#%d CONTENT\n", i);
+                t_grep(path, str);
+        }
+        replay_barrier();
+        for (i = 0; i < nfiles; i++) {
+                sprintf(path, "%s%d\n", base, i);
+                t_unlink(path);
+        }
+        mds_failover();
+        for (i = 0; i < nfiles; i++) {
+                sprintf(path, "%s%d\n", base, i);
+                t_check_stat_fail(path);
+        }
+        LEAVE();
+}
+
+void t3a()
+{
+        ENTRY("10 create/delete");
+        n_create_delete(10);
+        LEAVE();
+}
+
+void t3b()
+{
+        ENTRY("30 create/delete(>1'st block precreated)");
+        n_create_delete(30);
+        LEAVE();
+}
+
+void t4()
+{
+        char *dir="/mnt/lustre/d4";
+        char *path="/mnt/lustre/d4/f1";
+        ENTRY("mkdir + contained create");
+
+        replay_barrier();
+        t_mkdir(dir);
+        t_create(path);
+        mds_failover();
+        t_check_stat(dir, NULL);
+        t_check_stat(path, NULL);
+        sleep(2); /* wait for log process thread */
+
+        replay_barrier();
+        t_unlink(path);
+        t_rmdir(dir);
+        mds_failover();
+        t_check_stat_fail(dir);
+        t_check_stat_fail(path);
+        LEAVE();
+}
+
+void t5()
+{
+        char *dir="/mnt/lustre/d5";
+        char *path="/mnt/lustre/d5/f1";
+        ENTRY("mkdir |X| contained create");
+
+        t_mkdir(dir);
+        replay_barrier();
+        t_create(path);
+        mds_failover();
+        t_check_stat(dir, NULL);
+        t_check_stat(path, NULL);
+        t_unlink(path);
+        t_rmdir(dir);
+        LEAVE();
+}
+
+void t6()
+{
+        char *path="/mnt/lustre/f6";
+        int fd;
+        ENTRY("open |X| close");
+
+        replay_barrier();
+        t_create(path);
+        fd = t_open(path);
+        sleep(1);
+        mds_failover();
+        t_check_stat(path, NULL);
+        t_close(fd);
+        t_unlink(path);
+        LEAVE();
+}
+
+void t7()
+{
+        char *path="/mnt/lustre/f7";
+        char *path2="/mnt/lustre/f7-2";
+        ENTRY("create |X| rename unlink");
+
+        t_create(path);
+        replay_barrier();
+        t_rename(path, path2);
+        mds_failover();
+        t_check_stat_fail(path);
+        t_check_stat(path2, NULL);
+        t_unlink(path2);
+}
+
+void t8()
+{
+        char *path="/mnt/lustre/f8";
+        char *path2="/mnt/lustre/f8-2";
+        ENTRY("create open write rename |X| create-old-name read");
+
+        t_create(path);
+        t_echo_create(path, "old");
+        t_rename(path, path2);
+        replay_barrier();
+        t_echo_create(path, "new");
+        mds_failover();
+        t_grep(path, "new");
+        t_grep(path2, "old");
+        t_unlink(path);
+        t_unlink(path2);
+}
+
+void t9()
+{
+        char *path="/mnt/lustre/f9";
+        char *path2="/mnt/lustre/f9-2";
+        ENTRY("|X| open(O_CREAT), unlink, touch new, unlink new");
+
+        replay_barrier();
+        t_create(path);
+        t_unlink(path);
+        t_create(path2);
+        mds_failover();
+        t_check_stat_fail(path);
+        t_check_stat(path2, NULL);
+        t_unlink(path2);
+}
+
+void t10()
+{
+        char *path="/mnt/lustre/f10";
+        char *path2="/mnt/lustre/f10-2";
+        ENTRY("|X| mcreate, open write, rename");
+
+        replay_barrier();
+        t_create(path);
+        t_echo_create(path, "old");
+        t_rename(path, path2);
+        t_grep(path2, "old");
+        mds_failover();
+        t_grep(path2, "old");
+        t_unlink(path2);
+}
+
+extern int portal_debug;
+extern int portal_subsystem_debug;
+
+extern void __liblustre_setup_(void);
+extern void __liblustre_cleanup_(void);
+
+void usage(const char *cmd)
+{
+        printf("Usage: \t%s --target mdsnid:/mdsname/profile -s mds_hostname "
+                "-b \"barrier cmd\" -f \"failover cmd\"\n", cmd);
+        printf("       \t%s --dumpfile dumpfile -s mds_hostname -b \"barrier cmd\" "
+                "-f \"failover cmd\"\n", cmd);
+        exit(-1);
+}
+
+void test_ssh()
+{
+        char cmd[1024];
+
+        sprintf(cmd, "ssh %s cat /dev/null", mds_server);
+        if (system(cmd)) {
+                printf("ssh can't access server node: %s\n", mds_server);
+                exit(-1);
+        }
+}
+
+int main(int argc, char * const argv[])
+{
+        int opt_index, c;
+        static struct option long_opts[] = {
+                {"target", 1, 0, 0},
+                {"dumpfile", 1, 0, 0},
+                {0, 0, 0, 0}
+        };
+
+        if (argc < 4)
+                usage(argv[0]);
+
+        while ((c = getopt_long(argc, argv, "s:b:f:", long_opts, &opt_index)) != -1) {
+                switch (c) {
+                case 0: {
+                        if (!optarg[0])
+                                usage(argv[0]);
+
+                        if (!strcmp(long_opts[opt_index].name, "target")) {
+                                setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
+                        } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
+                                setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
+                        } else
+                                usage(argv[0]);
+                        break;
+                }
+                case 's':
+                        strcpy(mds_server, optarg);
+                        break;
+                case 'b':
+                        strcpy(barrier_script, optarg);
+                        break;
+                case 'f':
+                        strcpy(failover_script, optarg);
+                        break;
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+        if (optind != argc)
+                usage(argv[0]);
+        if (!strlen(mds_server) || !strlen(barrier_script) ||
+            !strlen(failover_script))
+                usage(argv[0]);
+
+        test_ssh();
+
+        /* prepare remote command */
+        sprintf(barrier_cmd, "ssh %s \"%s\"", mds_server, barrier_script);
+        sprintf(failover_cmd, "ssh %s \"%s\"", mds_server, failover_script);
+
+        __liblustre_setup_();
+
+        t0();
+        t1();
+        t2a();
+        t2b();
+        t3a();
+        t3b();
+        t4();
+        t5();
+        t6();
+        t7();
+        t8();
+        t9();
+        t10();
+
+	printf("liblustre is about shutdown\n");
+        __liblustre_cleanup_();
+
+	printf("complete successfully\n");
+	return 0;
+}
diff --git a/lustre/liblustre/rw.c b/lustre/liblustre/rw.c
index 847b1d02660a5d0eba3dbae199bff92a33c85056..70fd26e43a69205d98cf92b7e9b670865dcde8b5 100644
--- a/lustre/liblustre/rw.c
+++ b/lustre/liblustre/rw.c
@@ -25,7 +25,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <error.h>
 #include <assert.h>
 #include <time.h>
 #include <sys/types.h>
@@ -39,28 +38,80 @@
 
 #include "llite_lib.h"
 
-int llu_iop_iodone(struct ioctx *ioctxp __IS_UNUSED)
-{
-        return 1;
-}
-
-/*
- * this grabs a lock and manually implements behaviour that makes it look
- * like the OST is returning the file size with each lock acquisition
- */
-int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
-                   struct lov_stripe_md *lsm,
-                   int mode, struct ldlm_extent *extent,
-                   struct lustre_handle *lockh)
+#if 0
+void llu_pgcache_remove_extent(struct inode *inode, struct lov_stripe_md *lsm,
+                               struct ldlm_lock *lock)
 {
+        clear_bit(LLI_F_HAVE_SIZE_LOCK, &(llu_i2info(inode)->lli_flags));
 #if 0
-        struct ll_inode_info *lli = ll_i2info(inode);
-        int rc;
+        struct ldlm_extent *extent = &lock->l_extent;
+        unsigned long start, end, count, skip, i, j;
+        struct page *page;
+        int ret;
         ENTRY;
 
-        rc = ll_extent_lock_no_validate(fd, inode, lsm, mode, extent, lockh);
-        if (rc != ELDLM_OK)
-                RETURN(rc);
+        CDEBUG(D_INODE, "obdo %lu inode %p ["LPU64"->"LPU64"] size: %llu\n",
+               inode->i_ino, inode, extent->start, extent->end, inode->i_size);
+
+        start = extent->start >> PAGE_CACHE_SHIFT;
+        count = ~0;
+        skip = 0;
+        end = (extent->end >> PAGE_CACHE_SHIFT) + 1;
+        if ((end << PAGE_CACHE_SHIFT) < extent->end)
+                end = ~0;
+        if (lsm->lsm_stripe_count > 1) {
+                struct {
+                        char name[16];
+                        struct ldlm_lock *lock;
+                        struct lov_stripe_md *lsm;
+                } key = { .name = "lock_to_stripe", .lock = lock, .lsm = lsm };
+                __u32 stripe;
+                __u32 vallen = sizeof(stripe);
+                int rc;
+
+                /* get our offset in the lov */
+                rc = obd_get_info(ll_i2obdconn(inode), sizeof(key),
+                                  &key, &vallen, &stripe);
+                if (rc != 0) {
+                        CERROR("obd_get_info: rc = %d\n", rc);
+                        LBUG();
+                }
+                LASSERT(stripe < lsm->lsm_stripe_count);
+
+                count = lsm->lsm_stripe_size >> PAGE_CACHE_SHIFT;
+                skip = (lsm->lsm_stripe_count - 1) * count;
+                start += (start/count * skip) + (stripe * count);
+                if (end != ~0)
+                        end += (end/count * skip) + (stripe * count);
+        }
+
+        i = (inode->i_size + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
+        if (end >= i)
+                clear_bit(LLI_F_HAVE_SIZE_LOCK, &(ll_i2info(inode)->lli_flags));
+        if (i < end)
+                end = i;
+
+        CDEBUG(D_INODE, "start: %lu j: %lu count: %lu skip: %lu end: %lu\n",
+               start, start % count, count, skip, end);
+
+        /* start writeback on dirty pages in the extent when its PW */
+        for (i = start, j = start % count;
+                        lock->l_granted_mode == LCK_PW && i < end; j++, i++) {
+                if (j == count) {
+                        i += skip;
+                        j = 0;
+                }
+                /* its unlikely, but give us a chance to bail when we're out */
+                PGCACHE_WRLOCK(inode->i_mapping);
+                if (list_empty(&inode->i_mapping->dirty_pages)) {
+                        CDEBUG(D_INODE, "dirty list empty\n");
+                        PGCACHE_WRUNLOCK(inode->i_mapping);
+                        break;
+                }
+                PGCACHE_WRUNLOCK(inode->i_mapping);
+
+                if (need_resched())
+                        schedule();
 
         /* always do a getattr for the first person to pop out of lock
          * acquisition.. the DID_GETATTR flag and semaphore serialize
@@ -74,277 +125,500 @@ int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
         down(&lli->lli_getattr_sem);
 
         if (!test_bit(LLI_F_DID_GETATTR, &lli->lli_flags)) {
-                rc = ll_inode_getattr(inode, lsm, fd ? &fd->fd_ost_och : NULL);
+                rc = ll_inode_getattr(inode, lsm);
                 if (rc == 0) {
                         set_bit(LLI_F_DID_GETATTR, &lli->lli_flags);
                 } else {
-                        /* XXX can this fail? */
-                        ll_extent_unlock(fd, inode, lsm, mode, lockh);
+                        unlock_page(page);
                 }
+                page_cache_release(page);
+
         }
 
-        up(&lli->lli_getattr_sem);
-        RETURN(rc);
+        /* our locks are page granular thanks to osc_enqueue, we invalidate the
+         * whole page. */
+        LASSERT((extent->start & ~PAGE_CACHE_MASK) == 0);
+        LASSERT(((extent->end+1) & ~PAGE_CACHE_MASK) == 0);
+        for (i = start, j = start % count ; i < end ; j++, i++) {
+                if ( j == count ) {
+                        i += skip;
+                        j = 0;
+                }
+                PGCACHE_WRLOCK(inode->i_mapping);
+                if (list_empty(&inode->i_mapping->dirty_pages) &&
+                     list_empty(&inode->i_mapping->clean_pages) &&
+                     list_empty(&inode->i_mapping->locked_pages)) {
+                        CDEBUG(D_INODE, "nothing left\n");
+                        PGCACHE_WRUNLOCK(inode->i_mapping);
+                        break;
+                }
+                PGCACHE_WRUNLOCK(inode->i_mapping);
+                if (need_resched())
+                        schedule();
+                page = find_get_page(inode->i_mapping, i);
+                if (page == NULL)
+                        continue;
+                CDEBUG(D_INODE, "dropping page %p at %lu\n", page, page->index);
+                lock_page(page);
+                if (page->mapping) /* might have raced */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                        truncate_complete_page(page);
 #else
-        return ELDLM_OK;
+                        truncate_complete_page(page->mapping, page);
+#endif                
+                unlock_page(page);
+                page_cache_release(page);
+        }
+        EXIT;
 #endif
 }
 
-int ll_extent_unlock(struct ll_file_data *fd, struct inode *inode,
-                struct lov_stripe_md *lsm, int mode,
-                struct lustre_handle *lockh)
+int llu_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new,
+                      void *data, int flag)
 {
-#if 0
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct inode *inode = data;
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct lustre_handle lockh = {0};
         int rc;
         ENTRY;
 
-        /* XXX phil: can we do this?  won't it screw the file size up? */
-        if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) ||
-            (sbi->ll_flags & LL_SBI_NOLCK))
-                RETURN(0);
+        if (inode == NULL)
+                LBUG();
 
-        rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockh);
+        switch (flag) {
+        case LDLM_CB_BLOCKING:
+                ldlm_lock2handle(lock, &lockh);
+                rc = ldlm_cli_cancel(&lockh);
+                if (rc != ELDLM_OK)
+                        CERROR("ldlm_cli_cancel failed: %d\n", rc);
+                break;
+        case LDLM_CB_CANCELING: {
+                /* FIXME: we could be given 'canceling intents' so that we
+                 * could know to write-back or simply throw away the pages
+                 * based on if the cancel comes from a desire to, say,
+                 * read or truncate.. */
+                llu_pgcache_remove_extent(inode, lli->lli_smd, lock);
+                break;
+        }
+        default:
+                LBUG();
+        }
 
-        RETURN(rc);
-#else
-        return 0;
+        RETURN(0);
+}
 #endif
+
+static int llu_extent_lock_callback(struct ldlm_lock *lock,
+                                    struct ldlm_lock_desc *new, void *data,
+                                    int flag)
+{
+        struct lustre_handle lockh = { 0 };
+        int rc;
+        ENTRY;
+        
+
+        if ((unsigned long)data > 0 && (unsigned long)data < 0x1000) {
+                LDLM_ERROR(lock, "cancelling lock with bad data %p", data);
+                LBUG();
+        }
+        
+        switch (flag) {
+        case LDLM_CB_BLOCKING:
+                ldlm_lock2handle(lock, &lockh);
+                rc = ldlm_cli_cancel(&lockh);
+                if (rc != ELDLM_OK)
+                        CERROR("ldlm_cli_cancel failed: %d\n", rc);
+                break;
+        case LDLM_CB_CANCELING: {
+                struct inode *inode = llu_inode_from_lock(lock);
+                struct llu_inode_info *lli;
+                
+                if (!inode)
+                        RETURN(0);
+                lli= llu_i2info(inode);
+                if (!lli) {
+                        I_RELE(inode);
+                        RETURN(0);
+                }
+                if (!lli->lli_smd) {
+                        I_RELE(inode);
+                        RETURN(0);
+                }
+
+/*
+                ll_pgcache_remove_extent(inode, lli->lli_smd, lock);
+                iput(inode);
+*/
+                I_RELE(inode);
+                break;
+        }
+        default:
+                LBUG();
+        }
+        
+        RETURN(0);
 }
 
-static int llu_brw(int cmd, struct inode *inode, struct page *page, int flags)
+int llu_extent_lock_no_validate(struct ll_file_data *fd,
+                                struct inode *inode,
+                                struct lov_stripe_md *lsm,
+                                int mode,
+                                struct ldlm_extent *extent,
+                                struct lustre_handle *lockh,
+                                int ast_flags)
 {
+        struct llu_sb_info *sbi = llu_i2sbi(inode);
         struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct brw_page pg;
         int rc;
         ENTRY;
 
-        pg.pg = page;
-        pg.off = ((obd_off)page->index) << PAGE_SHIFT;
+        LASSERT(lockh->cookie == 0);
 
-        /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
 #if 0
-        if (cmd == OBD_BRW_WRITE && (pg.off + PAGE_SIZE > lli->lli_st_size))
-                pg.count = lli->lli_st_size % PAGE_SIZE;
-        else
+        /* XXX phil: can we do this?  won't it screw the file size up? */
+        if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) ||
+            (sbi->ll_flags & LL_SBI_NOLCK))
+                RETURN(0);
 #endif
-                pg.count = PAGE_SIZE;
 
-        CDEBUG(D_PAGE, "%s %d bytes ino %lu at "LPU64"/"LPX64"\n",
-               cmd & OBD_BRW_WRITE ? "write" : "read", pg.count, lli->lli_st_ino,
-               pg.off, pg.off);
-        if (pg.count == 0) {
-                LBUG();
-        }
-
-        pg.flag = flags;
+        CDEBUG(D_DLMTRACE, "Locking inode %lu, start "LPU64" end "LPU64"\n",
+               lli->lli_st_ino, extent->start, extent->end);
 
-        rc = obd_brw(cmd, llu_i2obdconn(inode), lsm, 1, &pg, set, NULL);
-        if (rc) {
-                CERROR("error from obd_brw: rc = %d\n", rc);
-        }
+        rc = obd_enqueue(sbi->ll_osc_exp, lsm, NULL, LDLM_EXTENT, extent,
+                         sizeof(extent), mode, &ast_flags,
+                         llu_extent_lock_callback, inode, lockh);
 
         RETURN(rc);
 }
 
-static int llu_prepare_write(struct inode *inode, struct page *page,
-                             unsigned from, unsigned to)
+/*
+ * this grabs a lock and manually implements behaviour that makes it look like
+ * the OST is returning the file size with each lock acquisition.
+ */
+int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
+                    struct lov_stripe_md *lsm, int mode,
+                    struct ldlm_extent *extent, struct lustre_handle *lockh)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
-        obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
-        int rc = 0;
+        struct obd_export *exp = llu_i2obdexp(inode);
+        struct ldlm_extent size_lock;
+        struct lustre_handle match_lockh = {0};
+        int flags, rc, matched;
         ENTRY;
 
-#if 0
-        if (!PageLocked(page))
-                LBUG();
-
-        if (PageUptodate(page))
-                RETURN(0);
+        rc = llu_extent_lock_no_validate(fd, inode, lsm, mode, extent, lockh, 0);
+        if (rc != ELDLM_OK)
+                RETURN(rc);
 
-        //POISON(addr + from, 0xca, to - from);
-#endif
-        /* We're completely overwriting an existing page, so _don't_ set it up
-         * to date until commit_write */
-        if (from == 0 && to == PAGE_SIZE)
+        if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
                 RETURN(0);
 
-        /* If are writing to a new page, no need to read old data.
-         * the extent locking and getattr procedures in ll_file_write have
-         * guaranteed that i_size is stable enough for our zeroing needs */
-        if (lli->lli_st_size <= offset) {
-                memset(kmap(page), 0, PAGE_SIZE);
-                kunmap(page);
-                GOTO(prepare_done, rc = 0);
+        rc = llu_inode_getattr(inode, lsm);
+        if (rc) {
+                llu_extent_unlock(fd, inode, lsm, mode, lockh);
+                RETURN(rc);
         }
 
-        rc = llu_brw(OBD_BRW_READ, inode, page, 0);
+        size_lock.start = lli->lli_st_size;
+        size_lock.end = OBD_OBJECT_EOF;
 
-        EXIT;
+        /* XXX I bet we should be checking the lock ignore flags.. */
+        flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED;
+        matched = obd_match(exp, lsm, LDLM_EXTENT, &size_lock,
+                            sizeof(size_lock), LCK_PR, &flags, inode,
+                            &match_lockh);
 
- prepare_done:
-        return rc;
+        /* hey, alright, we hold a size lock that covers the size we 
+         * just found, its not going to change for a while.. */
+        if (matched == 1) {
+                set_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags);
+                obd_cancel(exp, lsm, LCK_PR, &match_lockh);
+        } 
+
+        RETURN(0);
 }
 
-static int llu_commit_write(struct inode *inode, struct page *page,
-                            unsigned from, unsigned to)
+int llu_extent_unlock(struct ll_file_data *fd, struct inode *inode,
+                struct lov_stripe_md *lsm, int mode,
+                struct lustre_handle *lockh)
 {
-        struct llu_inode_info *lli = llu_i2info(inode);
-        loff_t size;
+        struct llu_sb_info *sbi = llu_i2sbi(inode);
         int rc;
         ENTRY;
 #if 0
-        LASSERT(inode == file->f_dentry->d_inode);
-        LASSERT(PageLocked(page));
-
-        CDEBUG(D_INODE, "inode %p is writing page %p from %d to %d at %lu\n",
-               inode, page, from, to, page->index);
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu,from=%d,to=%d\n",
-               inode->i_ino, from, to);
-        /* to match full page case in prepare_write */
-        SetPageUptodate(page);
-        /* mark the page dirty, put it on mapping->dirty,
-         * mark the inode PAGES_DIRTY, put it on sb->dirty */
-        set_page_dirty(page);
+        /* XXX phil: can we do this?  won't it screw the file size up? */
+        if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) ||
+            (sbi->ll_flags & LL_SBI_NOLCK))
+                RETURN(0);
 #endif
-        rc = llu_brw(OBD_BRW_WRITE, inode, page, 0);
-        if (rc)
-                return rc;
+        rc = obd_cancel(sbi->ll_osc_exp, lsm, mode, lockh);
 
-        /* this is matched by a hack in obdo_to_inode at the moment */
-        size = (((obd_off)page->index) << PAGE_SHIFT) + to;
-        if (size > lli->lli_st_size)
-                lli->lli_st_size = size;
+        RETURN(rc);
+}
 
-        RETURN(0);
-} /* ll_commit_write */
+#define LLAP_MAGIC 12346789
 
-ssize_t
-llu_generic_file_write(struct inode *inode, const char *buf,
-                       size_t count, loff_t pos)
+struct ll_async_page {
+        int             llap_magic;
+        void           *llap_cookie;
+        int             llap_queued;
+        struct page    *llap_page;
+        struct inode   *llap_inode;
+};
+
+static struct ll_async_page *llap_from_cookie(void *cookie)
 {
-	struct page	*page;
-	ssize_t		written;
-	long		status = 0;
-	int		err;
-	unsigned	bytes;
-
-	if ((ssize_t) count < 0)
-		return -EINVAL;
-#if 0
-	down(&inode->i_sem);
-#endif
-	if (pos < 0)
-                return -EINVAL;
+        struct ll_async_page *llap = cookie;
+        if (llap->llap_magic != LLAP_MAGIC)
+                return ERR_PTR(-EINVAL);
+        return llap;
+};
 
-	written = 0;
+static void llu_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
+{
+        struct ll_async_page *llap;
+        struct inode *inode;
+        struct lov_stripe_md *lsm;
+        obd_flag valid_flags;
+        ENTRY;
 
-#if 0
-	remove_suid(inode);
-	update_inode_times(inode);
-#endif
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) {
+                EXIT;
+                return;
+        }
+
+        inode = llap->llap_inode;
+        lsm = llu_i2info(inode)->lli_smd;
+
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_valid = OBD_MD_FLID;
+        valid_flags = OBD_MD_FLTYPE | OBD_MD_FLATIME;
+        if (cmd == OBD_BRW_WRITE)
+                valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME;
+
+        obdo_from_inode(oa, inode, valid_flags);
+        EXIT;
+}
+
+/* called for each page in a completed rpc.*/
+static void llu_ap_completion(void *data, int cmd, int rc)
+{
+        struct ll_async_page *llap;
+        struct page *page;
+
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) {
+                EXIT;
+                return;
+        }
+
+        llap->llap_queued = 0;
+        page = llap->llap_page;
+
+        if (rc != 0) {
+                if (cmd == OBD_BRW_WRITE)
+                        CERROR("writeback error on page %p index %ld: %d\n", 
+                               page, page->index, rc);
+        }
+        EXIT;
+}
+
+static struct obd_async_page_ops llu_async_page_ops = {
+        .ap_make_ready =        NULL,
+        .ap_refresh_count =     NULL,
+        .ap_fill_obdo =         llu_ap_fill_obdo,
+        .ap_completion =        llu_ap_completion,
+};
+
+static
+struct llu_sysio_cookie* get_sysio_cookie(struct inode *inode, int npages)
+{
+        struct llu_sysio_cookie *cookie;
+
+        OBD_ALLOC(cookie, LLU_SYSIO_COOKIE_SIZE(npages));
+        if (cookie) {
+                I_REF(inode);
+                cookie->lsc_inode = inode;
+                cookie->lsc_npages = npages;
+                cookie->lsc_llap = (struct ll_async_page *)(cookie + 1);
+                cookie->lsc_pages = (struct page *) (cookie->lsc_llap + npages);
+
+                osic_init(&cookie->lsc_osic);
+        }
+
+        return cookie;
+}
+
+static
+void put_sysio_cookie(struct llu_sysio_cookie *cookie)
+{
+        struct lov_stripe_md *lsm = llu_i2info(cookie->lsc_inode)->lli_smd;
+        struct obd_export *exp = llu_i2obdexp(cookie->lsc_inode);
+        struct ll_async_page *llap = cookie->lsc_llap;
+        int i;
+
+        for (i = 0; i< cookie->lsc_npages; i++) {
+                if (llap[i].llap_cookie)
+                        obd_teardown_async_page(exp, lsm, NULL,
+                                                llap[i].llap_cookie);
+        }
+
+        I_RELE(cookie->lsc_inode);
+
+        OBD_FREE(cookie, LLU_SYSIO_COOKIE_SIZE(cookie->lsc_npages));
+}
+
+static
+int llu_prep_async_io(struct llu_sysio_cookie *cookie, int cmd,
+                      char *buf, loff_t pos, size_t count)
+{
+        struct lov_stripe_md *lsm = llu_i2info(cookie->lsc_inode)->lli_smd;
+        struct obd_export *exp = llu_i2obdexp(cookie->lsc_inode);
+        struct page *pages = cookie->lsc_pages;
+        struct ll_async_page *llap = cookie->lsc_llap;
+        int i, rc, npages = 0;
+        ENTRY;
+
+        if (!exp)
+                RETURN(-EINVAL);
+
+        cookie->lsc_rwcount = count;
+
+        /* prepare the pages array */
 	do {
-		unsigned long index, offset;
-		char *kaddr;
-
-		/*
-		 * Try to find the page in the cache. If it isn't there,
-		 * allocate a free page.
-		 */
-		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
-		index = pos >> PAGE_CACHE_SHIFT;
-		bytes = PAGE_CACHE_SIZE - offset;
-		if (bytes > count) {
-			bytes = count;
-		}
-
-		status = -ENOMEM;	/* we'll assign it later anyway */
-		page = __grab_cache_page(index);
-		if (!page)
-			break;
-
-		kaddr = kmap(page);
-		status = llu_prepare_write(inode, page, offset, offset+bytes);
-		if (status)
-			goto sync_failure;
-
-		memcpy(kaddr+offset, buf, bytes);
-
-		status = llu_commit_write(inode, page, offset, offset+bytes);
-		if (!status)
-			status = bytes;
-
-		if (status >= 0) {
-			written += status;
-			count -= status;
-			pos += status;
-			buf += status;
-		}
-unlock:
-		kunmap(page);
-		page_cache_release(page);
-
-		if (status < 0)
-			break;
-	} while (count);
-done:
-	err = written ? written : status;
+                unsigned long index, offset, bytes;
+
+                offset = (pos & ~PAGE_CACHE_MASK);
+                index = pos >> PAGE_CACHE_SHIFT;
+                bytes = PAGE_CACHE_SIZE - offset;
+                if (bytes > count)
+                        bytes = count;
+
+                /* prepare page for this index */
+                pages[npages].index = index;
+                pages[npages].addr = buf - offset;
+
+                pages[npages]._offset = offset;
+                pages[npages]._count = bytes;
+
+                npages++;
+                count -= bytes;
+                pos += bytes;
+                buf += bytes;
+        } while (count);
+
+        for (i = 0; i < npages; i++) {
+                llap[i].llap_magic = LLAP_MAGIC;
+                rc = obd_prep_async_page(exp, lsm, NULL, &pages[i],
+                                         (obd_off)pages[i].index << PAGE_SHIFT,
+                                         &llu_async_page_ops,
+                                         &llap[i], &llap[i].llap_cookie);
+                if (rc) {
+                        llap[i].llap_cookie = NULL;
+                        RETURN(rc);
+                }
+                CDEBUG(D_CACHE, "llap %p page %p cookie %p obj off "LPU64"\n",
+                       &llap[i], &pages[i], llap[i].llap_cookie,
+                       (obd_off)pages[i].index << PAGE_SHIFT);
+                pages[i].private = (unsigned long)&llap[i];
+                llap[i].llap_page = &pages[i];
+                llap[i].llap_inode = cookie->lsc_inode;
+
+                rc = obd_queue_sync_io(exp, lsm, NULL, &cookie->lsc_osic,
+                                       llap[i].llap_cookie, cmd,
+                                       pages[i]._offset, pages[i]._count, 0);
+                if (rc)
+                        RETURN(rc);
+
+                llap[i].llap_queued = 1;
+        }
 
-#if 0
-	up(&inode->i_sem);
-#endif
-	return err;
-
-	status = -EFAULT;
-	goto unlock;
-
-sync_failure:
-	/*
-	 * If blocksize < pagesize, prepare_write() may have instantiated a
-	 * few blocks outside i_size.  Trim these off again.
-	 */
-	kunmap(page);
-	page_cache_release(page);
-	goto done;
+        RETURN(0);
 }
 
-ssize_t llu_file_write(struct inode *inode, const struct iovec *iovec,
-                       size_t iovlen, loff_t pos)
+static
+int llu_start_async_io(struct llu_sysio_cookie *cookie)
+{
+        struct lov_stripe_md *lsm = llu_i2info(cookie->lsc_inode)->lli_smd;
+        struct obd_export *exp = llu_i2obdexp(cookie->lsc_inode);
+
+        return obd_trigger_sync_io(exp, lsm, NULL, &cookie->lsc_osic);
+}
+
+/*
+ * read/write a continuous buffer for an inode (zero-copy)
+ */
+struct llu_sysio_cookie*
+llu_rw(int cmd, struct inode *inode, char *buf, size_t count, loff_t pos)
+{
+        struct llu_sysio_cookie *cookie;
+        int max_pages, rc;
+        ENTRY;
+
+        max_pages = (count >> PAGE_SHIFT) + 2;
+
+        cookie = get_sysio_cookie(inode, max_pages);
+        if (!cookie)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        rc = llu_prep_async_io(cookie, cmd, buf, pos, count);
+        if (rc)
+                GOTO(out_cleanup, rc);
+
+        rc = llu_start_async_io(cookie);
+        if (rc)
+                GOTO(out_cleanup, rc);
+
+/*
+        rc = osic_wait(&osic);
+        if (rc) {
+                CERROR("file i/o error!\n");
+                rw_count = rc;
+        }
+*/
+        RETURN(cookie);
+
+out_cleanup:
+        put_sysio_cookie(cookie);
+        RETURN(ERR_PTR(rc));
+}
+
+struct llu_sysio_callback_args*
+llu_file_write(struct inode *inode, const struct iovec *iovec,
+               size_t iovlen, loff_t pos)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
-        struct ll_file_data *fd = lli->lli_file_data; /* XXX not ready don't use it now */
-        struct lustre_handle lockh = { 0 };
+        struct ll_file_data *fd = lli->lli_file_data;
+        struct lustre_handle lockh = {0};
         struct lov_stripe_md *lsm = lli->lli_smd;
+        struct llu_sysio_callback_args *lsca;
+        struct llu_sysio_cookie *cookie;
         struct ldlm_extent extent;
         ldlm_error_t err;
-        ssize_t retval = 0;
+        int iovidx;
         ENTRY;
 
         /* XXX consider other types later */
         if (!S_ISREG(lli->lli_st_mode))
                 LBUG();
-#if 0
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu,size="LPSZ",offset=%Ld\n",
-               inode->i_ino, count, *ppos);
-
-        /*
-         * sleep doing some writeback work of this mount's dirty data
-         * if the VM thinks we're low on memory.. other dirtying code
-         * paths should think about doing this, too, but they should be
-         * careful not to hold locked pages while they do so.  like
-         * ll_prepare_write.  *cough*
-         */
-        ll_check_dirty(inode->i_sb);
-#endif
-        while (iovlen--) {
-                const char *buf = iovec[iovlen].iov_base;
-                size_t count = iovec[iovlen].iov_len;
 
-                /* POSIX, but surprised the VFS doesn't check this already */
+        LASSERT(iovlen <= MAX_IOVEC);
+
+        OBD_ALLOC(lsca, sizeof(*lsca));
+        if (!lsca)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        /* FIXME optimize the following extent locking */
+        for (iovidx = 0; iovidx < iovlen; iovidx++) {
+                char *buf = iovec[iovidx].iov_base;
+                size_t count = iovec[iovidx].iov_len;
+
                 if (count == 0)
                         continue;
 
+                /* FIXME libsysio haven't consider the open flags
+                 * such as O_APPEND */
 #if 0
                 if (!S_ISBLK(lli->lli_st_mode) && file->f_flags & O_APPEND) {
                         extent.start = 0;
@@ -360,26 +634,48 @@ ssize_t llu_file_write(struct inode *inode, const struct iovec *iovec,
 
                 err = llu_extent_lock(fd, inode, lsm, LCK_PW, &extent, &lockh);
                 if (err != ELDLM_OK)
-                        RETURN(-ENOLCK);
-
-#if 0
-                if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND)
-                        *ppos = inode->i_size;
+                        GOTO(err_out, err = -ENOLCK);
 
                 CDEBUG(D_INFO, "Writing inode %lu, "LPSZ" bytes, offset %Lu\n",
-                       inode->i_ino, count, *ppos);
-#endif
-                retval += llu_generic_file_write(inode, buf, count, pos);
+                       lli->lli_st_ino, count, pos);
+
+                cookie = llu_rw(OBD_BRW_WRITE, inode, buf, count, pos);
+                if (!IS_ERR(cookie)) {
+                        /* save cookie */
+                        lsca->cookies[lsca->ncookies++] = cookie;
+                        pos += count;
+                        /* file size grow. XXX should be done here? */
+                        if (pos > lli->lli_st_size) {
+                                lli->lli_st_size = pos;
+                                set_bit(LLI_F_PREFER_EXTENDED_SIZE,
+                                        &lli->lli_flags);
+                        }
+                } else {
+                        llu_extent_unlock(fd, inode, lsm, LCK_PW, &lockh);
+                        GOTO(err_out, err = PTR_ERR(cookie));
+                }
+
+                /* XXX errors? */
+                err = llu_extent_unlock(fd, inode, lsm, LCK_PW, &lockh);
+                if (err)
+                        CERROR("extent unlock error %d\n", err);
+        }
+
+        RETURN(lsca);
+
+err_out:
+        /* teardown all async stuff */
+        while (lsca->ncookies--) {
+                put_sysio_cookie(lsca->cookies[lsca->ncookies]);
         }
+        OBD_FREE(lsca, sizeof(*lsca));
 
-        /* XXX errors? */
-        ll_extent_unlock(fd, inode, lsm, LCK_PW, &lockh);
-        return(retval);
+        RETURN(ERR_PTR(err));
 }
 
+#if 0
 static void llu_update_atime(struct inode *inode)
 {
-#if 0
         struct llu_inode_info *lli = llu_i2info(inode);
 
 #ifdef USE_ATIME
@@ -398,122 +694,109 @@ static void llu_update_atime(struct inode *inode)
         /* update atime, but don't explicitly write it out just this change */
         inode->i_atime = CURRENT_TIME;
 #endif
-#endif
-}
-
-static size_t llu_generic_file_read(struct inode *inode, char *buf,
-                                    size_t count, loff_t pos)
-{
-        struct llu_inode_info *lli = llu_i2info(inode);
-	unsigned long index, offset;
-	int error = 0;
-        size_t readed = 0;
-
-	index = pos >> PAGE_CACHE_SHIFT;
-	offset = pos & ~PAGE_CACHE_MASK;
-
-	do {
-		struct page *page;
-		unsigned long end_index, nr;
-
-		end_index = lli->lli_st_size >> PAGE_CACHE_SHIFT;
-
-		if (index > end_index)
-			break;
-		nr = PAGE_CACHE_SIZE;
-		if (index == end_index) {
-			nr = lli->lli_st_size & ~PAGE_CACHE_MASK;
-			if (nr <= offset)
-				break;
-		}
-
-		nr = nr - offset;
-                if (nr > count)
-                        nr = count;
-
-                page = grab_cache_page(index);
-                if (!page) {
-                        error = -ENOMEM;
-                        break;
-                }
-
-                error = llu_brw(OBD_BRW_READ, inode, page, 0);
-		if (error) {
-		        page_cache_release(page);
-                        break;
-		}
-
-                memcpy(buf, kmap(page)+offset, nr);
-		offset += nr;
-		index += offset >> PAGE_CACHE_SHIFT;
-		offset &= ~PAGE_CACHE_MASK;
-                readed += nr;
-                count -= nr;
-
-		page_cache_release(page);
-	} while (count);
-
-        if (error)
-                return error;
-        return readed;
 }
+#endif
 
-ssize_t llu_file_read(struct inode *inode, const struct iovec *iovec,
+struct llu_sysio_callback_args*
+llu_file_read(struct inode *inode, const struct iovec *iovec,
                        size_t iovlen, loff_t pos)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
         struct ll_file_data *fd = lli->lli_file_data;
         struct lov_stripe_md *lsm = lli->lli_smd;
         struct lustre_handle lockh = { 0 };
-#if 0
-        struct ll_read_extent rextent;
-#else
         struct ldlm_extent extent;
-#endif
+        struct llu_sysio_callback_args *lsca;
+        struct llu_sysio_cookie *cookie;
+        int iovidx;
+
         ldlm_error_t err;
-        ssize_t retval = 0;
         ENTRY;
 
-        while (iovlen--) {
-                char *buf = iovec[iovlen].iov_base;
-                size_t count = iovec[iovlen].iov_len;
+        OBD_ALLOC(lsca, sizeof(*lsca));
+        if (!lsca)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        for (iovidx = 0; iovidx < iovlen; iovidx++) {
+                char *buf = iovec[iovidx].iov_base;
+                size_t count = iovec[iovidx].iov_len;
 
                 /* "If nbyte is 0, read() will return 0 and have no other results."
                  *                      -- Single Unix Spec */
                 if (count == 0)
-                        RETURN(0);
+                        continue;
 
-#if 0
-                rextent.re_extent.start = pos;
-                rextent.re_extent.end = pos + count - 1;
-#else
                 extent.start = pos;
                 extent.end = pos + count - 1;
-#endif
+
                 err = llu_extent_lock(fd, inode, lsm, LCK_PR, &extent, &lockh);
                 if (err != ELDLM_OK)
-                        RETURN(-ENOLCK);
-#if 0
-                rextent.re_task = current;
-                spin_lock(&lli->lli_read_extent_lock);
-                list_add(&rextent.re_lli_item, &lli->lli_read_extents);
-                spin_unlock(&lli->lli_read_extent_lock);
-#endif
+                        GOTO(err_out, err = -ENOLCK);
+
                 CDEBUG(D_INFO, "Reading inode %lu, "LPSZ" bytes, offset %Ld\n",
                        lli->lli_st_ino, count, pos);
-                retval = llu_generic_file_read(inode, buf, count, pos);
+
+                cookie = llu_rw(OBD_BRW_READ, inode, buf, count, pos);
+                if (!IS_ERR(cookie)) {
+                        /* save cookie */
+                        lsca->cookies[lsca->ncookies++] = cookie;
+                        pos += count;
+                } else {
+                        llu_extent_unlock(fd, inode, lsm, LCK_PR, &lockh);
+                        GOTO(err_out, err = PTR_ERR(cookie));
+                }
+
+                /* XXX errors? */
+                err = llu_extent_unlock(fd, inode, lsm, LCK_PR, &lockh);
+                if (err)
+                        CERROR("extent_unlock fail: %d\n", err);
+        }
 #if 0
-                spin_lock(&lli->lli_read_extent_lock);
-                list_del(&rextent.re_lli_item);
-                spin_unlock(&lli->lli_read_extent_lock);
+        if (readed > 0)
+                llu_update_atime(inode);
 #endif
-        }
+        RETURN(lsca);
 
-        if (retval > 0)
-                llu_update_atime(inode);
+err_out:
+        /* teardown all async stuff */
+        while (lsca->ncookies--) {
+                put_sysio_cookie(lsca->cookies[lsca->ncookies]);
+        }
+        OBD_FREE(lsca, sizeof(*lsca));
 
-        /* XXX errors? */
-        ll_extent_unlock(fd, inode, lsm, LCK_PR, &lockh);
-        RETURN(retval);
+        RETURN(ERR_PTR(err));
 }
 
+int llu_iop_iodone(struct ioctx *ioctxp)
+{
+        struct llu_sysio_callback_args *lsca = ioctxp->ioctx_private;
+        struct llu_sysio_cookie *cookie;
+        int i, err = 0, rc = 0;
+        ENTRY;
+
+        /* write/read(fd, buf, 0) */
+        if (!lsca)
+                return 1;
+
+        LASSERT(!IS_ERR(lsca));
+
+        for (i = 0; i < lsca->ncookies; i++) {
+                cookie = lsca->cookies[i];
+                if (cookie) {
+                        err = osic_wait(&cookie->lsc_osic);
+                        if (err && !rc)
+                                rc = err;
+                        if (!rc)
+                                ioctxp->ioctx_cc += cookie->lsc_rwcount;
+                        put_sysio_cookie(cookie);
+                }
+        }
+
+        if (rc)
+                ioctxp->ioctx_cc = rc;
+
+        OBD_FREE(lsca, sizeof(*lsca));
+        ioctxp->ioctx_private = NULL;
+
+        RETURN(1);
+}
diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c
index 0939352b32641d2a80964046b6aa964ac13719f0..af3d3aa0e856f2f2e793fe64c2aa383a1c8f9f59 100644
--- a/lustre/liblustre/super.c
+++ b/lustre/liblustre/super.c
@@ -25,11 +25,17 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <error.h>
 #include <assert.h>
 #include <time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
 #include <sys/queue.h>
+#ifndef __CYGWIN__
+# include <sys/statvfs.h>
+#else
+# include <sys/statfs.h>
+#endif
 
 #include <sysio.h>
 #include <fs.h>
@@ -41,7 +47,28 @@
 
 static void llu_fsop_gone(struct filesys *fs)
 {
-        /* FIXME */
+        struct llu_sb_info *sbi = (struct llu_sb_info *) fs->fs_private;
+        struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp);
+        struct ll_fid rootfid;
+        ENTRY;
+
+        list_del(&sbi->ll_conn_chain);
+        obd_disconnect(sbi->ll_osc_exp, 0);
+
+        /* NULL request to force sync on the MDS, and get the last_committed
+         * value to flush remaining RPCs from the sending queue on client.
+         *
+         * XXX This should be an mdc_sync() call to sync the whole MDS fs,
+         *     which we can call for other reasons as well.
+         */
+        if (!obd->obd_no_recov)
+                mdc_getstatus(sbi->ll_mdc_exp, &rootfid);
+
+        obd_disconnect(sbi->ll_mdc_exp, 0);
+
+        OBD_FREE(sbi, sizeof(*sbi));
+
+        EXIT;
 }
 
 static struct inode_ops llu_inode_ops;
@@ -53,11 +80,18 @@ void llu_update_inode(struct inode *inode, struct mds_body *body,
 
         LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
         if (lsm != NULL) {
-                if (lli->lli_smd == NULL)                        
+                if (lli->lli_smd == NULL) {
                         lli->lli_smd = lsm;
-                else
-                        LASSERT (!memcmp (lli->lli_smd, lsm,
-                                          sizeof (*lsm)));
+                        lli->lli_maxbytes = lsm->lsm_maxbytes;
+                        if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
+                                lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
+                } else {
+                        if (memcmp(lli->lli_smd, lsm, sizeof(*lsm))) {
+                                CERROR("lsm mismatch for inode %ld\n",
+                                       lli->lli_st_ino);
+                                LBUG();
+                        }
+                }
         }
 
         if (body->valid & OBD_MD_FLID)
@@ -104,6 +138,12 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
 
         valid &= src->o_valid;
 
+        if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
+                CDEBUG(D_INODE, "valid %x, cur time %lu/%lu, new %lu/%lu\n",
+                       src->o_valid, 
+                       LTIME_S(lli->lli_st_mtime), LTIME_S(lli->lli_st_ctime),
+                       (long)src->o_mtime, (long)src->o_ctime);
+
         if (valid & OBD_MD_FLATIME)
                 LTIME_S(lli->lli_st_atime) = src->o_atime;
         if (valid & OBD_MD_FLMTIME)
@@ -131,78 +171,153 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
         if (valid & OBD_MD_FLGENER)
                 lli->lli_st_generation = src->o_generation;
         if (valid & OBD_MD_FLRDEV)
-                lli->lli_st_rdev = src->o_rdev;
+                lli->lli_st_rdev = to_kdev_t(src->o_rdev);
 }
 
+#define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO       (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+
 void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
 {
         struct llu_inode_info *lli = llu_i2info(src);
+        obd_flag newvalid = 0;
 
-        if (valid & OBD_MD_FLATIME)
+        if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
+                CDEBUG(D_INODE, "valid %x, new time %lu/%lu\n",
+                       valid, LTIME_S(lli->lli_st_mtime), 
+                       LTIME_S(lli->lli_st_ctime));
+
+        if (valid & OBD_MD_FLATIME) {
                 dst->o_atime = LTIME_S(lli->lli_st_atime);
-        if (valid & OBD_MD_FLMTIME)
+                newvalid |= OBD_MD_FLATIME;
+        }
+        if (valid & OBD_MD_FLMTIME) {
                 dst->o_mtime = LTIME_S(lli->lli_st_mtime);
-        if (valid & OBD_MD_FLCTIME)
+                newvalid |= OBD_MD_FLMTIME;
+        }
+        if (valid & OBD_MD_FLCTIME) {
                 dst->o_ctime = LTIME_S(lli->lli_st_ctime);
-        if (valid & OBD_MD_FLSIZE)
+                newvalid |= OBD_MD_FLCTIME;
+        }
+        if (valid & OBD_MD_FLSIZE) {
                 dst->o_size = lli->lli_st_size;
-        if (valid & OBD_MD_FLBLOCKS)   /* allocation of space */
+                newvalid |= OBD_MD_FLSIZE;
+        }
+        if (valid & OBD_MD_FLBLOCKS) {  /* allocation of space (x512 bytes) */
                 dst->o_blocks = lli->lli_st_blocks;
-        if (valid & OBD_MD_FLBLKSZ)
+                newvalid |= OBD_MD_FLBLOCKS;
+        }
+        if (valid & OBD_MD_FLBLKSZ) {   /* optimal block size */
                 dst->o_blksize = lli->lli_st_blksize;
-        if (valid & OBD_MD_FLTYPE)
-                dst->o_mode = (dst->o_mode & ~S_IFMT) | (lli->lli_st_mode & S_IFMT);
-        if (valid & OBD_MD_FLMODE)
-                dst->o_mode = (dst->o_mode & S_IFMT) | (lli->lli_st_mode & ~S_IFMT);
-        if (valid & OBD_MD_FLUID)
+                newvalid |= OBD_MD_FLBLKSZ;
+        }
+        if (valid & OBD_MD_FLTYPE) {
+                dst->o_mode = (dst->o_mode & S_IALLUGO)|(lli->lli_st_mode & S_IFMT);
+                newvalid |= OBD_MD_FLTYPE;
+        }
+        if (valid & OBD_MD_FLMODE) {
+                dst->o_mode = (dst->o_mode & S_IFMT)|(lli->lli_st_mode & S_IALLUGO);
+                newvalid |= OBD_MD_FLMODE;
+        }
+        if (valid & OBD_MD_FLUID) {
                 dst->o_uid = lli->lli_st_uid;
-        if (valid & OBD_MD_FLGID)
+                newvalid |= OBD_MD_FLUID;
+        }
+        if (valid & OBD_MD_FLGID) {
                 dst->o_gid = lli->lli_st_gid;
-        if (valid & OBD_MD_FLFLAGS)
+                newvalid |= OBD_MD_FLGID;
+        }
+        if (valid & OBD_MD_FLFLAGS) {
                 dst->o_flags = lli->lli_st_flags;
-        if (valid & OBD_MD_FLNLINK)
+                newvalid |= OBD_MD_FLFLAGS;
+        }
+        if (valid & OBD_MD_FLNLINK) {
                 dst->o_nlink = lli->lli_st_nlink;
-        if (valid & OBD_MD_FLGENER)
+                newvalid |= OBD_MD_FLNLINK;
+        }
+        if (valid & OBD_MD_FLGENER) {
                 dst->o_generation = lli->lli_st_generation;
-        if (valid & OBD_MD_FLRDEV)
-                dst->o_rdev = (__u32)(lli->lli_st_rdev);
+                newvalid |= OBD_MD_FLGENER;
+        }
+        if (valid & OBD_MD_FLRDEV) {
+                dst->o_rdev = (__u32)kdev_t_to_nr(lli->lli_st_rdev);
+                newvalid |= OBD_MD_FLRDEV;
+        }
 
-        dst->o_valid |= (valid & ~OBD_MD_FLID);
+        dst->o_valid |= newvalid;
 }
 
-int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm,
-                      char *ostdata)
+/*
+ * really does the getattr on the inode and updates its fields
+ */
+int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm)
 {
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct obd_export *exp = llu_i2obdexp(inode);
+        struct ptlrpc_request_set *set;
         struct obdo oa;
+        obd_flag refresh_valid;
         int rc;
         ENTRY;
 
         LASSERT(lsm);
-        LASSERT(sbi);
+        LASSERT(lli);
 
         memset(&oa, 0, sizeof oa);
         oa.o_id = lsm->lsm_object_id;
         oa.o_mode = S_IFREG;
         oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
-                OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | OBD_MD_FLCTIME;
+                OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME |
+                OBD_MD_FLCTIME;
 
-        if (ostdata != NULL) {
-                memcpy(&oa.o_inline, ostdata, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
+        set = ptlrpc_prep_set();
+        if (set == NULL) {
+                CERROR ("ENOMEM allocing request set\n");
+                rc = -ENOMEM;
+        } else {
+                rc = obd_getattr_async(exp, &oa, lsm, set);
+                if (rc == 0)
+                        rc = ptlrpc_set_wait(set);
+                ptlrpc_set_destroy(set);
         }
-
-        rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm);
         if (rc)
                 RETURN(rc);
 
-        obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
-                           OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+        refresh_valid = OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME | 
+                        OBD_MD_FLCTIME | OBD_MD_FLSIZE;
+
+        /* We set this flag in commit write as we extend the file size.  When
+         * the bit is set and the lock is canceled that covers the file size,
+         * we clear the bit.  This is enough to protect the window where our
+         * local size extension is needed for writeback.  However, it relies on
+         * behaviour that won't be true in the near future.  This assumes that
+         * all getattr callers get extent locks, which they currnetly do.  It
+         * also assumes that we only send discarding asts for {0,eof} truncates
+         * as is currently the case.  This will have to be replaced by the
+         * proper eoc communication between clients and the ost, which is on
+         * its way. */
+        if (test_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags)) {
+                if (oa.o_size < lli->lli_st_size)
+                        refresh_valid &= ~OBD_MD_FLSIZE;
+                else 
+                        clear_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags);
+        }
+
+        obdo_refresh_inode(inode, &oa, refresh_valid);
 
+/*
+        if (inode->i_blksize < PAGE_CACHE_SIZE)
+                inode->i_blksize = PAGE_CACHE_SIZE;
+
+        CDEBUG(D_INODE, "objid "LPX64" size %Lu, blocks %lu, blksize %lu\n",
+               lsm->lsm_object_id, inode->i_size, inode->i_blocks,
+               inode->i_blksize);
+*/
         RETURN(0);
 }
 
-struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode)
+static struct inode* llu_new_inode(struct filesys *fs,
+                                   struct ll_fid *fid)
 {
 	struct inode *inode;
         struct llu_inode_info *lli;
@@ -216,17 +331,22 @@ struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode)
         lli->lli_smd = NULL;
         lli->lli_symlink_name = NULL;
         lli->lli_flags = 0;
-        INIT_LIST_HEAD(&lli->lli_read_extents);
+        lli->lli_maxbytes = (__u64)(~0UL);
         lli->lli_file_data = NULL;
 
-        /* could file_identifier be 0 ? FIXME */
-	inode = _sysio_i_new(fs, ino, NULL,
+        lli->lli_sysio_fid.fid_data = &lli->lli_fid;
+        lli->lli_sysio_fid.fid_len = sizeof(lli->lli_fid);
+
+        memcpy(&lli->lli_fid, fid, sizeof(*fid));
+
+        /* file identifier is needed by functions like _sysio_i_find() */
+	inode = _sysio_i_new(fs, &lli->lli_sysio_fid,
 #ifndef AUTOMOUNT_FILE_NAME
-	 	       	     mode & S_IFMT,
+	 	       	     fid->f_type & S_IFMT,
 #else
-			     mode,	/* all of the bits! */
+			     fid->f_type, /* all of the bits! */
 #endif
-                             0,
+                             0, 0,
 			     &llu_inode_ops, lli);
 
 	if (!inode)
@@ -235,113 +355,165 @@ struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode)
         return inode;
 }
 
-static int llu_iop_lookup(struct pnode *pnode,
-                          struct inode **inop,
-                          struct intent *intnt __IS_UNUSED,
-                          const char *path __IS_UNUSED)
+#if 0
+static int ll_intent_to_lock_mode(struct lookup_intent *it)
 {
-        struct pnode_base *pb_dir = pnode->p_parent->p_base;
-        struct ptlrpc_request *request = NULL;
-        struct llu_sb_info *sbi = llu_i2sbi(pb_dir->pb_ino);
-        struct ll_fid *fid = &llu_i2info(pb_dir->pb_ino)->lli_fid;
-        struct qstr *name = &pnode->p_base->pb_name;
-        struct mds_body *body;
-        unsigned long valid;
-        char *pname;
-        int rc, easize;
-        struct ll_read_inode2_cookie lic = {.lic_body = NULL, .lic_lsm = NULL};
-
-        /* the mount root inode have no name, so don't call
-         * remote in this case. but probably we need revalidate
-         * it here? FIXME */
-        if (pnode->p_mount->mnt_root == pnode) {
-                struct inode *i = pnode->p_base->pb_ino;
-                I_REF(i);
-                *inop = i;
-                return 0;
-        }
-
-        if (!name->len)
-                return -EINVAL;
-
-        /* mdc_getattr_name require NULL-terminated name */
-        OBD_ALLOC(pname, name->len + 1);
-        if (!pname)
-                return -ENOMEM;
-        memcpy(pname, name->name, name->len);
-        pname[name->len] = 0;
-
-        valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
-
-        /* FIXME before getattr_name, we don't know whether
-         * the inode we are finding is regular or not, so here
-         * we blindly require server feed in EA data */
-        easize = obd_size_diskmd(&sbi->ll_osc_conn, NULL);
-        valid |= OBD_MD_FLEASIZE;
-
-        rc = mdc_getattr_name(&sbi->ll_mdc_conn, fid,
-                              pname, name->len + 1,
-                              valid, easize, &request);
-        if (rc < 0) {
-                CERROR("mdc_getattr_name: %d\n", rc);
-                rc = -ENOENT;
-                goto out;
+        /* CREAT needs to be tested before open (both could be set) */
+        if (it->it_op & IT_CREAT)
+                return LCK_PW;
+        else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP))
+                return LCK_PR;
+
+        LBUG();
+        RETURN(-EINVAL);
+}
+#endif
+
+#if 0
+int ll_it_open_error(int phase, struct lookup_intent *it)
+{
+        if (it_disposition(it, DISP_OPEN_OPEN)) {
+                if (phase == DISP_OPEN_OPEN)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
         }
-        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
 
-        *inop = llu_new_inode(pnode->p_mount->mnt_fs, body->ino, body->mode);
-        if (!inop)
-                goto out;
-
-        lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*lic.lic_body));
-        LASSERT (lic.lic_body != NULL);
-        LASSERT_REPSWABBED (request, 0);
-
-        if (S_ISREG(lic.lic_body->mode) &&
-            lic.lic_body->valid & OBD_MD_FLEASIZE) {
-                struct lov_mds_md    *lmm;
-                int                   lmm_size;
-                int                   rc;
-                
-                lmm_size = lic.lic_body->eadatasize;
-                if (lmm_size == 0) {
-                        CERROR ("OBD_MD_FLEASIZE set but eadatasize 0\n");
-                        RETURN (-EPROTO);
+        if (it_disposition(it, DISP_OPEN_CREATE)) {
+                if (phase == DISP_OPEN_CREATE)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+
+        if (it_disposition(it, DISP_LOOKUP_EXECD)) {
+                if (phase == DISP_LOOKUP_EXECD)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+        CERROR("it disp: %X, status: %d\n", it->d.lustre.it_disposition, it->d.lustre.it_status);
+        LBUG();
+        return 0;
+}
+#endif
+
+static int llu_have_md_lock(struct inode *inode)
+{
+        struct llu_sb_info *sbi = llu_i2sbi(inode);
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct lustre_handle lockh;
+        struct ldlm_res_id res_id = { .name = {0} };
+        struct obd_device *obddev;
+        int flags;
+        ENTRY;
+
+        LASSERT(inode);
+
+        obddev = sbi->ll_mdc_exp->exp_obd;
+        res_id.name[0] = lli->lli_st_ino;
+        res_id.name[1] = lli->lli_st_generation;
+
+        CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
+
+        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING;
+        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PR, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PR);
+                RETURN(1);
+        }
+
+        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PW, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PW);
+                RETURN(1);
+        }
+        RETURN(0);
+}
+
+static int llu_inode_revalidate(struct inode *inode)
+{
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct lov_stripe_md *lsm = NULL;
+        ENTRY;
+
+        if (!inode) {
+                CERROR("REPORT THIS LINE TO PETER\n");
+                RETURN(0);
+        }
+
+        if (!llu_have_md_lock(inode)) {
+                struct lustre_md md;
+                struct ptlrpc_request *req = NULL;
+                struct llu_sb_info *sbi = llu_i2sbi(inode);
+                struct ll_fid fid;
+                unsigned long valid = 0;
+                int rc, ealen = 0;
+
+                /* Why don't we update all valid MDS fields here, if we're
+                 * doing an RPC anyways?  -phil */
+                if (S_ISREG(lli->lli_st_mode)) {
+                        ealen = obd_size_diskmd(sbi->ll_osc_exp, NULL);
+                        valid |= OBD_MD_FLEASIZE;
+                }
+                ll_inode2fid(&fid, inode);
+                rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, ealen, &req);
+                if (rc) {
+                        CERROR("failure %d inode %lu\n", rc, lli->lli_st_ino);
+                        RETURN(-abs(rc));
+                }
+                rc = mdc_req2lustre_md(req, 0, sbi->ll_osc_exp, &md);
+
+                /* XXX Too paranoid? */
+                if (((md.body->valid ^ valid) & OBD_MD_FLEASIZE) &&
+                    !((md.body->valid & OBD_MD_FLNLINK) &&
+                      (md.body->nlink == 0))) {
+                        CERROR("Asked for %s eadata but got %s (%d)\n",
+                               (valid & OBD_MD_FLEASIZE) ? "some" : "no",
+                               (md.body->valid & OBD_MD_FLEASIZE) ? "some":"none",
+                                md.body->eadatasize);
                 }
-                lmm = lustre_msg_buf(request->rq_repmsg, 0 + 1, lmm_size);
-                LASSERT(lmm != NULL);
-                LASSERT_REPSWABBED (request, 0 + 1);
-
-                rc = obd_unpackmd (&sbi->ll_osc_conn, 
-                                   &lic.lic_lsm, lmm, lmm_size);
-                if (rc < 0) {
-                        CERROR ("Error %d unpacking eadata\n", rc);
-                        RETURN (rc);
+                if (rc) {
+                        ptlrpc_req_finished(req);
+                        RETURN(rc);
                 }
-                LASSERT (rc >= sizeof (*lic.lic_lsm));
 
-        } else {
-                lic.lic_lsm = NULL;
-        }
 
-        llu_update_inode(*inop, body, lic.lic_lsm);
+                llu_update_inode(inode, md.body, md.lsm);
+                if (md.lsm != NULL && llu_i2info(inode)->lli_smd != md.lsm)
+                        obd_free_memmd(sbi->ll_osc_exp, &md.lsm);
 
-        if (llu_i2info(*inop)->lli_smd) {
-                rc = llu_inode_getattr(*inop, llu_i2info(*inop)->lli_smd, NULL);
-                if (rc)
-                        _sysio_i_gone(*inop);
+                if (md.body->valid & OBD_MD_FLSIZE)
+                        set_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
+                                &llu_i2info(inode)->lli_flags);
+                ptlrpc_req_finished(req);
         }
 
-out:
-        ptlrpc_req_finished(request);
-        OBD_FREE(pname, name->len + 1);
+        lsm = llu_i2info(inode)->lli_smd;
+        if (!lsm)       /* object not yet allocated, don't validate size */
+                RETURN(0);
 
-        return rc;
+        /*
+         * unfortunately stat comes in through revalidate and we don't
+         * differentiate this use from initial instantiation.  we're
+         * also being wildly conservative and flushing write caches
+         * so that stat really returns the proper size.
+         */
+        {
+                struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
+                struct lustre_handle lockh = {0};
+                ldlm_error_t err;
+
+                err = llu_extent_lock(NULL, inode, lsm, LCK_PR, &extent, &lockh);
+                if (err != ELDLM_OK)
+                        RETURN(err);
+
+                llu_extent_unlock(NULL, inode, lsm, LCK_PR, &lockh);
+        }
+        RETURN(0);
 }
 
-static int llu_iop_getattr(struct pnode *pno,
-                           struct inode *ino,
-                           struct intnl_stat *b)
+static void copy_stat_buf(struct inode *ino, struct intnl_stat *b)
 {
         struct llu_inode_info *lli = llu_i2info(ino);
 
@@ -358,46 +530,75 @@ static int llu_iop_getattr(struct pnode *pno,
         b->st_atime = lli->lli_st_atime;
         b->st_mtime = lli->lli_st_mtime;
         b->st_ctime = lli->lli_st_ctime;
-
-        return 0;
 }
 
-int llu_mdc_cancel_unused(struct lustre_handle *conn,
-                          struct llu_inode_info *lli,
-                          int flags)
+static int llu_iop_getattr(struct pnode *pno,
+                           struct inode *ino,
+                           struct intnl_stat *b)
 {
-        struct ldlm_res_id res_id =
-                { .name = {lli->lli_st_ino, lli->lli_st_generation} };
-        struct obd_device *obddev = class_conn2obd(conn);
+        int rc;
         ENTRY;
-        RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, &res_id, flags));
+
+        if (!ino) {
+                LASSERT(pno);
+                LASSERT(pno->p_base->pb_ino);
+                ino = pno->p_base->pb_ino;
+        } else {
+                LASSERT(!pno || pno->p_base->pb_ino == ino);
+        }
+
+        /* libsysio might call us directly without intent lock,
+         * we must re-fetch the attrs here
+         */
+        rc = llu_inode_revalidate(ino);
+        if (!rc) {
+                copy_stat_buf(ino, b);
+
+                if (llu_i2info(ino)->lli_it) {
+                        struct lookup_intent *it;
+
+                        LL_GET_INTENT(ino, it);
+                        it->it_op_release(it);
+                        OBD_FREE(it, sizeof(*it));
+                }
+        }
+
+        RETURN(rc);
 }
 
-static void llu_clear_inode(struct inode *inode)
+static int null_if_equal(struct ldlm_lock *lock, void *data)
 {
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
+        if (data == lock->l_ast_data)
+                lock->l_ast_data = NULL;
+
+        if (lock->l_req_mode != lock->l_granted_mode)
+                return LDLM_ITER_STOP;
+
+        return LDLM_ITER_CONTINUE;
+}
+
+void llu_clear_inode(struct inode *inode)
+{
+        struct ll_fid fid;
         struct llu_inode_info *lli = llu_i2info(inode);
-        int rc;
+        struct llu_sb_info *sbi = llu_i2sbi(inode);
         ENTRY;
 
-        CDEBUG(D_INODE, "clear inode: %lu\n", lli->lli_st_ino);
-        rc = llu_mdc_cancel_unused(&sbi->ll_mdc_conn, lli,
-                                   LDLM_FL_NO_CALLBACK);
-        if (rc < 0) {
-                CERROR("ll_mdc_cancel_unused: %d\n", rc);
-                /* XXX FIXME do something dramatic */
-        }
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%lu(%p)\n", lli->lli_st_ino,
+               lli->lli_st_generation, inode);
 
-        if (lli->lli_smd) {
-                rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0);
-                if (rc < 0) {
-                        CERROR("obd_cancel_unused: %d\n", rc);
-                        /* XXX FIXME do something dramatic */
-                }
-        }
+        ll_inode2fid(&fid, inode);
+        clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &(lli->lli_flags));
+        mdc_change_cbdata(sbi->ll_mdc_exp, &fid, null_if_equal, inode);
 
         if (lli->lli_smd)
-                obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
+                obd_change_cbdata(sbi->ll_osc_exp, lli->lli_smd,
+                                  null_if_equal, inode);
+
+        if (lli->lli_smd) {
+                obd_free_memmd(sbi->ll_osc_exp, &lli->lli_smd);
+                lli->lli_smd = NULL;
+        }
 
         if (lli->lli_symlink_name) {
                 OBD_FREE(lli->lli_symlink_name,
@@ -411,63 +612,214 @@ static void llu_clear_inode(struct inode *inode)
 void llu_iop_gone(struct inode *inode)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
+        ENTRY;
 
         llu_clear_inode(inode);
 
         OBD_FREE(lli, sizeof(*lli));
+        EXIT;
 }
 
-static int llu_setattr_raw(struct inode *inode, struct iattr *attr)
+static int inode_setattr(struct inode * inode, struct iattr * attr)
 {
-        struct ptlrpc_request *request = NULL;
+        unsigned int ia_valid = attr->ia_valid;
+        struct llu_inode_info *lli = llu_i2info(inode);
+        int error = 0;
+
+        if (ia_valid & ATTR_SIZE) {
+                error = llu_vmtruncate(inode, attr->ia_size);
+                if (error)
+                        goto out;
+        }
+
+        if (ia_valid & ATTR_UID)
+                lli->lli_st_uid = attr->ia_uid;
+        if (ia_valid & ATTR_GID)
+                lli->lli_st_gid = attr->ia_gid;
+        if (ia_valid & ATTR_ATIME)
+                lli->lli_st_atime = attr->ia_atime;
+        if (ia_valid & ATTR_MTIME)
+                lli->lli_st_mtime = attr->ia_mtime;
+        if (ia_valid & ATTR_CTIME)
+                lli->lli_st_ctime = attr->ia_ctime;
+        if (ia_valid & ATTR_MODE) {
+                lli->lli_st_mode = attr->ia_mode;
+                if (!in_group_p(lli->lli_st_gid) && !capable(CAP_FSETID))
+                        lli->lli_st_mode &= ~S_ISGID;
+        }
+        /* mark_inode_dirty(inode); */
+out:
+        return error;
+}
+
+/* If this inode has objects allocated to it (lsm != NULL), then the OST
+ * object(s) determine the file size and mtime.  Otherwise, the MDS will
+ * keep these values until such a time that objects are allocated for it.
+ * We do the MDS operations first, as it is checking permissions for us.
+ * We don't to the MDS RPC if there is nothing that we want to store there,
+ * otherwise there is no harm in updating mtime/atime on the MDS if we are
+ * going to do an RPC anyways.
+ *
+ * If we are doing a truncate, we will send the mtime and ctime updates
+ * to the OST with the punch RPC, otherwise we do an explicit setattr RPC.
+ * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE
+ * at the same time.
+ */
+#define OST_ATTR (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME | \
+                  ATTR_ATIME | ATTR_ATIME_SET | ATTR_SIZE)
+int llu_setattr_raw(struct inode *inode, struct iattr *attr)
+{
+        struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd;
         struct llu_sb_info *sbi = llu_i2sbi(inode);
         struct llu_inode_info *lli = llu_i2info(inode);
+        struct ptlrpc_request *request = NULL;
         struct mdc_op_data op_data;
-        int err = 0;
+        int ia_valid = attr->ia_valid;
+        int rc = 0;
         ENTRY;
+
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
 
-        /* if need truncate, do it at first */
-        if (attr->ia_valid & ATTR_SIZE) {
-                printf("************* don't support truncate now !!!!!!!!\n");
-                LBUG();
+        if (ia_valid & ATTR_SIZE) {
+                if (attr->ia_size > ll_file_maxbytes(inode)) {
+                        CDEBUG(D_INODE, "file too large %llu > "LPU64"\n",
+                               attr->ia_size, ll_file_maxbytes(inode));
+                        RETURN(-EFBIG);
+                }
+
+                attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
         }
 
-        /* Don't send size changes to MDS to avoid "fast EA" problems, and
-         * also avoid a pointless RPC (we get file size from OST anyways).
-         */
-        attr->ia_valid &= ~ATTR_SIZE;
-        if (!attr->ia_valid)
-                RETURN(0);
+        /* We mark all of the fields "set" so MDS/OST does not re-set them */
+        if (attr->ia_valid & ATTR_CTIME) {
+                attr->ia_ctime = CURRENT_TIME;
+                attr->ia_valid |= ATTR_CTIME_SET;
+        }
+        if (!(ia_valid & ATTR_ATIME_SET) && (attr->ia_valid & ATTR_ATIME)) {
+                attr->ia_atime = CURRENT_TIME;
+                attr->ia_valid |= ATTR_ATIME_SET;
+        }
+        if (!(ia_valid & ATTR_MTIME_SET) && (attr->ia_valid & ATTR_MTIME)) {
+                attr->ia_mtime = CURRENT_TIME;
+                attr->ia_valid |= ATTR_MTIME_SET;
+        }
 
-        llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
+        if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
+                CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",
+                       LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
+                       LTIME_S(CURRENT_TIME));
+        if (lsm)
+                attr->ia_valid &= ~ATTR_SIZE;
+
+        /* If only OST attributes being set on objects, don't do MDS RPC.
+         * In that case, we need to check permissions and update the local
+         * inode ourselves so we can call obdo_from_inode() always. */
+        if (ia_valid & (lsm ? ~(OST_ATTR | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) {
+                struct lustre_md md;
+                llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
+
+                rc = mdc_setattr(sbi->ll_mdc_exp, &op_data,
+                                  attr, NULL, 0, NULL, 0, &request);
+
+                if (rc) {
+                        ptlrpc_req_finished(request);
+                        if (rc != -EPERM && rc != -EACCES)
+                                CERROR("mdc_setattr fails: rc = %d\n", rc);
+                        RETURN(rc);
+                }
 
-        err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
-                          attr, NULL, 0, &request);
-        if (err)
-                CERROR("mdc_setattr fails: err = %d\n", err);
+                rc = mdc_req2lustre_md(request, 0, sbi->ll_osc_exp, &md);
+                if (rc) {
+                        ptlrpc_req_finished(request);
+                        RETURN(rc);
+                }
+                llu_update_inode(inode, md.body, md.lsm);
+                ptlrpc_req_finished(request);
 
-        ptlrpc_req_finished(request);
+                if (!md.lsm || !S_ISREG(lli->lli_st_mode)) {
+                        CDEBUG(D_INODE, "no lsm: not setting attrs on OST\n");
+                        RETURN(0);
+                }
+        } else {
+                /* The OST doesn't check permissions, but the alternative is
+                 * a gratuitous RPC to the MDS.  We already rely on the client
+                 * to do read/write/truncate permission checks, so is mtime OK?
+                 */
+                if (ia_valid & (ATTR_MTIME | ATTR_ATIME)) {
+                        /* from sys_utime() */
+                        if (!(ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))) {
+                                if (current->fsuid != lli->lli_st_uid &&
+                                    (rc = ll_permission(inode, 0/*MAY_WRITE*/, NULL)) != 0)
+                                        RETURN(rc);
+                        } else {
+				/* from inode_change_ok() */
+				if (current->fsuid != lli->lli_st_uid &&
+				    !capable(CAP_FOWNER))
+					RETURN(-EPERM);
+                        }
+                }
+
+                /* Won't invoke vmtruncate, as we already cleared ATTR_SIZE */
+                inode_setattr(inode, attr);
+        }
 
-        if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
-                struct lov_stripe_md *lsm = lli->lli_smd;
+        if (ia_valid & ATTR_SIZE) {
+                struct ldlm_extent extent = { .start = attr->ia_size,
+                                              .end = OBD_OBJECT_EOF };
+                struct lustre_handle lockh = { 0 };
+                int err, ast_flags = 0;
+                /* XXX when we fix the AST intents to pass the discard-range
+                 * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA
+                 * XXX here. */
+
+                /* Writeback uses inode->i_size to determine how far out
+                 * its cached pages go.  ll_truncate gets a PW lock, canceling
+                 * our lock, _after_ it has updated i_size.  this can confuse
+                 *
+                 * We really need to get our PW lock before we change
+                 * inode->i_size.  If we don't we can race with other
+                 * i_size updaters on our node, like ll_file_read.  We
+                 * can also race with i_size propogation to other
+                 * nodes through dirtying and writeback of final cached
+                 * pages.  This last one is especially bad for racing
+                 * o_append users on other nodes. */
+                if (extent.start == 0)
+                        ast_flags = LDLM_AST_DISCARD_DATA;
+                rc = llu_extent_lock_no_validate(NULL, inode, lsm, LCK_PW,
+                                                 &extent, &lockh, ast_flags);
+                if (rc != ELDLM_OK) {
+                        if (rc > 0)
+                                RETURN(-ENOLCK);
+                        RETURN(rc);
+                }
+
+                rc = llu_vmtruncate(inode, attr->ia_size);
+                if (rc == 0)
+                        set_bit(LLI_F_HAVE_OST_SIZE_LOCK,
+                                &llu_i2info(inode)->lli_flags);
+
+                /* unlock now as we don't mind others file lockers racing with
+                 * the mds updates below? */
+                err = llu_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh);
+                if (err) {
+                        CERROR("llu_extent_unlock failed: %d\n", err);
+                        if (!rc)
+                                rc = err;
+                }
+        } else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) {
                 struct obdo oa;
-                int err2;
 
                 CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
-                       lli->lli_st_ino, attr->ia_mtime);
+                       lli->lli_st_ino, LTIME_S(attr->ia_mtime));
                 oa.o_id = lsm->lsm_object_id;
-                oa.o_mode = S_IFREG;
-                oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME;
-                oa.o_mtime = attr->ia_mtime;
-                err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                if (err2) {
-                        CERROR("obd_setattr fails: rc=%d\n", err);
-                        if (!err)
-                                err = err2;
-                }
+                oa.o_valid = OBD_MD_FLID;
+                obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
+                                            OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+                rc = obd_setattr(sbi->ll_osc_exp, &oa, lsm, NULL);
+                if (rc)
+                        CERROR("obd_setattr fails: rc=%d\n", rc);
         }
-        RETURN(err);
+        RETURN(rc);
 }
 
 /* FIXME here we simply act as a thin layer to glue it with
@@ -479,6 +831,7 @@ static int llu_iop_setattr(struct pnode *pno,
                            struct intnl_stat *stbuf)
 {
         struct iattr iattr;
+        ENTRY;
 
         memset(&iattr, 0, sizeof(iattr));
 
@@ -508,99 +861,519 @@ static int llu_iop_setattr(struct pnode *pno,
         }
 
         iattr.ia_valid |= ATTR_RAW;
-        /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME
-         * without ATTR_FROM_OPEN, mds_reint_setattr will call
-         * mds_fid2locked_dentry() and deadlocked at completion_ast call.
-         * Here we workaround it and avoid any locking.
-         * FIXME FIXME FIXME FIXME FIXME FIXME FIXME
-         */
-        iattr.ia_valid |= ATTR_FROM_OPEN;
 
-        return llu_setattr_raw(ino, &iattr);
+        RETURN(llu_setattr_raw(ino, &iattr));
 }
 
+#define EXT2_LINK_MAX           32000
 
-static int llu_mkdir2(struct inode *dir, const char *name, int len, int mode)
+static int llu_iop_symlink_raw(struct pnode *pno, const char *tgt)
 {
+        struct inode *dir = pno->p_base->pb_parent->pb_ino;
+        struct qstr *qstr = &pno->p_base->pb_name;
+        const char *name = qstr->name;
+        int len = qstr->len;
         struct ptlrpc_request *request = NULL;
-        time_t curtime = CURRENT_TIME;
         struct llu_sb_info *sbi = llu_i2sbi(dir);
-        struct llu_inode_info *lli = llu_i2info(dir);
         struct mdc_op_data op_data;
         int err = -EMLINK;
         ENTRY;
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu\n",
-               name, lli->lli_st_ino);
 
-        /* FIXME check this later */
-#if 0 
-        if (dir->i_nlink >= EXT2_LINK_MAX)
+        if (llu_i2info(dir)->lli_st_nlink >= EXT2_LINK_MAX)
                 RETURN(err);
-        mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
-#endif
-        mode |= S_IFDIR;
+
         llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
-                         current->fsuid, current->fsgid,
-                         curtime, 0, &request);
+        err = mdc_create(sbi->ll_mdc_exp, &op_data,
+                         tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
+                         current->fsuid, current->fsgid, 0, &request);
         ptlrpc_req_finished(request);
         RETURN(err);
 }
 
-static int llu_iop_mkdir(struct pnode *pno, mode_t mode)
+static int llu_readlink_internal(struct inode *inode,
+                                 struct ptlrpc_request **request,
+                                 char **symname)
+{
+        struct llu_inode_info *lli = llu_i2info(inode);
+        struct llu_sb_info *sbi = llu_i2sbi(inode);
+        struct ll_fid fid;
+        struct mds_body *body;
+        int rc, symlen = lli->lli_st_size + 1;
+        ENTRY;
+
+        *request = NULL;
+
+        if (lli->lli_symlink_name) {
+                *symname = lli->lli_symlink_name;
+                CDEBUG(D_INODE, "using cached symlink %s\n", *symname);
+                RETURN(0);
+        }
+
+        ll_inode2fid(&fid, inode);
+        rc = mdc_getattr(sbi->ll_mdc_exp, &fid,
+                         OBD_MD_LINKNAME, symlen, request);
+        if (rc) {
+                CERROR("inode %lu: rc = %d\n", lli->lli_st_ino, rc);
+                RETURN(rc);
+        }
+
+        body = lustre_msg_buf ((*request)->rq_repmsg, 0, sizeof (*body));
+        LASSERT (body != NULL);
+        LASSERT_REPSWABBED (*request, 0);
+
+        if ((body->valid & OBD_MD_LINKNAME) == 0) {
+                CERROR ("OBD_MD_LINKNAME not set on reply\n");
+                GOTO (failed, rc = -EPROTO);
+        }
+        
+        LASSERT (symlen != 0);
+        if (body->eadatasize != symlen) {
+                CERROR ("inode %lu: symlink length %d not expected %d\n",
+                        lli->lli_st_ino, body->eadatasize - 1, symlen - 1);
+                GOTO (failed, rc = -EPROTO);
+        }
+
+        *symname = lustre_msg_buf ((*request)->rq_repmsg, 1, symlen);
+        if (*symname == NULL ||
+            strnlen (*symname, symlen) != symlen - 1) {
+                /* not full/NULL terminated */
+                CERROR ("inode %lu: symlink not NULL terminated string"
+                        "of length %d\n", lli->lli_st_ino, symlen - 1);
+                GOTO (failed, rc = -EPROTO);
+        }
+
+        OBD_ALLOC(lli->lli_symlink_name, symlen);
+        /* do not return an error if we cannot cache the symlink locally */
+        if (lli->lli_symlink_name)
+                memcpy(lli->lli_symlink_name, *symname, symlen);
+
+        RETURN(0);
+
+ failed:
+        ptlrpc_req_finished (*request);
+        RETURN (-EPROTO);
+}
+
+static int llu_iop_readlink(struct pnode *pno, char *data, size_t bufsize)
+{
+        struct inode *inode = pno->p_base->pb_ino;
+        struct ptlrpc_request *request;
+        char *symname;
+        int rc;
+        ENTRY;
+
+        /* on symlinks lli_open_sem protects lli_symlink_name allocation/data */
+/*
+        down(&lli->lli_open_sem);
+*/
+        rc = llu_readlink_internal(inode, &request, &symname);
+        if (rc)
+                GOTO(out, rc);
+
+        LASSERT(symname);
+        strncpy(data, symname, bufsize);
+
+        ptlrpc_req_finished(request);
+ out:
+/*
+        up(&lli->lli_open_sem);
+*/
+        RETURN(rc);
+}
+
+static int llu_iop_mknod_raw(struct pnode *pno,
+                             mode_t mode,
+                             dev_t dev)
+{
+        struct ptlrpc_request *request = NULL;
+        struct inode *dir = pno->p_parent->p_base->pb_ino;
+        struct llu_sb_info *sbi = llu_i2sbi(dir);
+        struct mdc_op_data op_data;
+        int err = -EMLINK;
+        ENTRY;
+
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu\n",
+               pno->p_base->pb_name.name, llu_i2info(dir)->lli_st_ino);
+
+        if (llu_i2info(dir)->lli_st_nlink >= EXT2_LINK_MAX)
+                RETURN(err);
+
+        mode &= ~current->fs->umask;
+
+        switch (mode & S_IFMT) {
+        case 0:
+        case S_IFREG:
+                mode |= S_IFREG; /* for mode = 0 case, fallthrough */
+        case S_IFCHR:
+        case S_IFBLK:
+        case S_IFIFO:
+        case S_IFSOCK:
+                llu_prepare_mdc_op_data(&op_data, dir, NULL,
+                                        pno->p_base->pb_name.name,
+                                        pno->p_base->pb_name.len,
+                                        0);
+                err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+                                 current->fsuid, current->fsgid, dev, &request);
+                ptlrpc_req_finished(request);
+                break;
+        case S_IFDIR:
+                err = -EPERM;
+                break;
+        default:
+                err = -EINVAL;
+        }
+        RETURN(err);
+}
+
+#if 0
+static int llu_mdc_unlink(struct inode *dir, struct inode *child, __u32 mode,
+                         const char *name, int len)
+{
+        struct ptlrpc_request *request = NULL;
+        struct mds_body *body;
+        struct lov_mds_md *eadata;
+        struct lov_stripe_md *lsm = NULL;
+        struct obd_trans_info oti = { 0 };
+        struct mdc_op_data op_data;
+        struct obdo *oa;
+        int rc;
+        ENTRY;
+
+        llu_prepare_mdc_op_data(&op_data, dir, child, name, len, mode);
+        rc = mdc_unlink(&llu_i2sbi(dir)->ll_mdc_conn, &op_data, &request);
+        if (rc)
+                GOTO(out, rc);
+        /* req is swabbed so this is safe */
+        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
+
+        if (!(body->valid & OBD_MD_FLEASIZE))
+                GOTO(out, rc = 0);
+
+        if (body->eadatasize == 0) {
+                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
+                GOTO(out, rc = -EPROTO);
+        }
+
+        /* The MDS sent back the EA because we unlinked the last reference
+         * to this file. Use this EA to unlink the objects on the OST.
+         * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
+         * check it is complete and sensible. */
+        eadata = lustre_swab_repbuf(request, 1, body->eadatasize, NULL);
+        LASSERT(eadata != NULL);
+        if (eadata == NULL) {
+                CERROR("Can't unpack MDS EA data\n");
+                GOTO(out, rc = -EPROTO);
+        }
+
+        rc = obd_unpackmd(llu_i2obdconn(dir), &lsm, eadata, body->eadatasize);
+        if (rc < 0) {
+                CERROR("obd_unpackmd: %d\n", rc);
+                GOTO(out, rc);
+        }
+        LASSERT(rc >= sizeof(*lsm));
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out_free_memmd, rc = -ENOMEM);
+
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_mode = body->mode & S_IFMT;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
+
+        if (body->valid & OBD_MD_FLCOOKIE) {
+                oa->o_valid |= OBD_MD_FLCOOKIE;
+                oti.oti_logcookies = lustre_msg_buf(request->rq_repmsg, 3,
+                                                    body->eadatasize);
+        }
+
+        rc = obd_destroy(llu_i2obdconn(dir), oa, lsm, &oti);
+        obdo_free(oa);
+        if (rc)
+                CERROR("obd destroy objid 0x"LPX64" error %d\n",
+                       lsm->lsm_object_id, rc);
+ out_free_memmd:
+        obd_free_memmd(llu_i2obdconn(dir), &lsm);
+ out:
+        ptlrpc_req_finished(request);
+        return rc;
+}
+#endif
+
+static int llu_iop_link_raw(struct pnode *old, struct pnode *new)
+{
+        struct inode *src = old->p_base->pb_ino;
+        struct inode *dir = new->p_parent->p_base->pb_ino;
+        const char *name = new->p_base->pb_name.name;
+        int namelen = new->p_base->pb_name.len;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
+        int rc;
+        ENTRY;
+
+        LASSERT(src);
+        LASSERT(dir);
+
+        llu_prepare_mdc_op_data(&op_data, src, dir, name, namelen, 0);
+        rc = mdc_link(llu_i2sbi(src)->ll_mdc_exp, &op_data, &request);
+        ptlrpc_req_finished(request);
+
+        RETURN(rc);
+}
+
+static int llu_iop_unlink_raw(struct pnode *pno)
 {
         struct inode *dir = pno->p_base->pb_parent->pb_ino;
         struct qstr *qstr = &pno->p_base->pb_name;
+        const char *name = qstr->name;
+        int len = qstr->len;
+        struct inode *target = pno->p_base->pb_ino;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
         int rc;
+        ENTRY;
 
-        LASSERT(dir);
+        LASSERT(target);
 
-        rc = llu_mkdir2(dir, qstr->name, qstr->len, mode);
+        llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+        rc = mdc_unlink(llu_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+        if (!rc) {
+                rc = llu_objects_destroy(request, dir);
 
-        return rc;
+                llu_i2info(target)->lli_stale_flag = 1;
+                unhook_stale_inode(pno);
+        }
+
+        ptlrpc_req_finished(request);
+        RETURN(rc);
 }
 
-#ifndef S_IRWXUGO
-#define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
+/* FIXME
+ * following cases need to be considered later:
+ * - rename an opened file/dir
+ * - an opened file be removed in rename
+ * - rename to remove and hardlink (?opened)
+ */
+static int llu_iop_rename_raw(struct pnode *old, struct pnode *new)
+{
+        struct inode *src = old->p_parent->p_base->pb_ino;
+        struct inode *tgt = new->p_parent->p_base->pb_ino;
+        struct inode *tgtinode = new->p_base->pb_ino;
+        const char *oldname = old->p_base->pb_name.name;
+        int oldnamelen = old->p_base->pb_name.len;
+        const char *newname = new->p_base->pb_name.name;
+        int newnamelen = new->p_base->pb_name.len;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
+        int rc;
+        ENTRY;
+
+        LASSERT(src);
+        LASSERT(tgt);
+
+        llu_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0);
+        rc = mdc_rename(llu_i2sbi(src)->ll_mdc_exp, &op_data,
+                        oldname, oldnamelen, newname, newnamelen,
+                        &request);
+        if (!rc) {
+                rc = llu_objects_destroy(request, src);
+
+                if (tgtinode) {
+                        llu_i2info(tgtinode)->lli_stale_flag = 1;
+                        unhook_stale_inode(new);
+                }
+        }
+
+        ptlrpc_req_finished(request);
+
+        RETURN(rc);
+}
+
+#if 0
+static int llu_statfs_internal(struct llu_sb_info *sbi,
+                               struct obd_statfs *osfs,
+                               unsigned long max_age)
+{
+        struct obd_statfs obd_osfs;
+        int rc;
+        ENTRY;
+
+        rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age);
+        if (rc) {
+                CERROR("mdc_statfs fails: rc = %d\n", rc);
+                RETURN(rc);
+        }
+
+        CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+               osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
+
+        rc = obd_statfs(class_exp2obd(sbi->ll_osc_exp), &obd_osfs, max_age);
+        if (rc) {
+                CERROR("obd_statfs fails: rc = %d\n", rc);
+                RETURN(rc);
+        }
+
+        CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+               obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree,
+               obd_osfs.os_files);
+
+        osfs->os_blocks = obd_osfs.os_blocks;
+        osfs->os_bfree = obd_osfs.os_bfree;
+        osfs->os_bavail = obd_osfs.os_bavail;
+
+        /* If we don't have as many objects free on the OST as inodes
+         * on the MDS, we reduce the total number of inodes to
+         * compensate, so that the "inodes in use" number is correct.
+         */
+        if (obd_osfs.os_ffree < osfs->os_ffree) {
+                osfs->os_files = (osfs->os_files - osfs->os_ffree) +
+                        obd_osfs.os_ffree;
+                osfs->os_ffree = obd_osfs.os_ffree;
+        }
+
+        RETURN(rc);
+}
+
+static int llu_statfs(struct llu_sb_info *sbi, struct kstatfs *sfs)
+{
+        struct obd_statfs osfs;
+        int rc;
+
+        CDEBUG(D_VFSTRACE, "VFS Op:\n");
+
+        /* For now we will always get up-to-date statfs values, but in the
+         * future we may allow some amount of caching on the client (e.g.
+         * from QOS or lprocfs updates). */
+        rc = llu_statfs_internal(sbi, &osfs, jiffies - 1);
+        if (rc)
+                return rc;
+
+        statfs_unpack(sfs, &osfs);
+
+        if (sizeof(sfs->f_blocks) == 4) {
+                while (osfs.os_blocks > ~0UL) {
+                        sfs->f_bsize <<= 1;
+
+                        osfs.os_blocks >>= 1;
+                        osfs.os_bfree >>= 1;
+                        osfs.os_bavail >>= 1;
+                }
+        }
+
+        sfs->f_blocks = osfs.os_blocks;
+        sfs->f_bfree = osfs.os_bfree;
+        sfs->f_bavail = osfs.os_bavail;
+
+        return 0;
+}
+
+static int llu_iop_statvfs(struct pnode *pno,
+                           struct inode *ino,
+                           struct intnl_statvfs *buf)
+{
+        struct statfs fs;
+        int rc;
+        ENTRY;
+
+#ifndef __CYGWIN__
+        LASSERT(pno->p_base->pb_ino);
+        rc = llu_statfs(llu_i2sbi(pno->p_base->pb_ino), &fs);
+        if (rc)
+                RETURN(rc);
+
+        /* from native driver */
+        buf->f_bsize = fs.f_bsize;  /* file system block size */
+        buf->f_frsize = fs.f_bsize; /* file system fundamental block size */
+        buf->f_blocks = fs.f_blocks;
+        buf->f_bfree = fs.f_bfree;
+        buf->f_bavail = fs.f_bavail;
+        buf->f_files = fs.f_files;  /* Total number serial numbers */
+        buf->f_ffree = fs.f_ffree;  /* Number free serial numbers */
+        buf->f_favail = fs.f_ffree; /* Number free ser num for non-privileged*/
+        buf->f_fsid = fs.f_fsid.__val[1];
+        buf->f_flag = 0;            /* No equiv in statfs; maybe use type? */
+        buf->f_namemax = fs.f_namelen;
+#endif
+
+        RETURN(0);
+}
 #endif
 
-static int llu_symlink2(struct inode *dir, const char *name, int len,
-                        const char *tgt)
+static int llu_iop_mkdir_raw(struct pnode *pno, mode_t mode)
 {
+        struct inode *dir = pno->p_base->pb_parent->pb_ino;
+        struct qstr *qstr = &pno->p_base->pb_name;
+        const char *name = qstr->name;
+        int len = qstr->len;
         struct ptlrpc_request *request = NULL;
-        time_t curtime = CURRENT_TIME;
-        struct llu_sb_info *sbi = llu_i2sbi(dir);
         struct llu_inode_info *lli = llu_i2info(dir);
         struct mdc_op_data op_data;
         int err = -EMLINK;
         ENTRY;
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%lu(%p)\n",
+               name, lli->lli_st_ino, lli->lli_st_generation, dir);
 
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,target=%s\n",
-               name, lli->lli_st_ino, tgt);
-
-#if 0
-        if (dir->i_nlink >= EXT2_LINK_MAX)
+        if (lli->lli_st_nlink >= EXT2_LINK_MAX)
                 RETURN(err);
-#endif
+
+        mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
         llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data,
-                         tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
-                         current->fsuid, current->fsgid, curtime, 0, &request);
+        err = mdc_create(llu_i2sbi(dir)->ll_mdc_exp, &op_data, NULL, 0, mode,
+                         current->fsuid, current->fsgid, 0, &request);
         ptlrpc_req_finished(request);
         RETURN(err);
 }
 
-static int llu_iop_symlink(struct pnode *pno, const char *data)
+static int llu_iop_rmdir_raw(struct pnode *pno)
 {
         struct inode *dir = pno->p_base->pb_parent->pb_ino;
         struct qstr *qstr = &pno->p_base->pb_name;
+        const char *name = qstr->name;
+        int len = qstr->len;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
+        struct llu_inode_info *lli = llu_i2info(dir);
         int rc;
-        
-        LASSERT(dir);
+        ENTRY;
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%lu(%p)\n",
+               name, lli->lli_st_ino, lli->lli_st_generation, dir);
 
-        rc = llu_symlink2(dir, qstr->name, qstr->len, data);
+        llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, S_IFDIR);
+        rc = mdc_unlink(llu_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+        ptlrpc_req_finished(request);
 
-        return rc;
+        /* libsysio: remove the pnode right away */
+        if (!rc) {
+                llu_i2info(pno->p_base->pb_ino)->lli_stale_flag = 1;
+                unhook_stale_inode(pno);
+        }
+
+        RETURN(rc);
+}
+
+static int llu_iop_fcntl(struct inode *ino, int cmd, va_list ap)
+{
+        CERROR("liblustre did not support fcntl\n");
+        return -ENOSYS;
+}
+
+static int llu_iop_ioctl(struct inode *ino, unsigned long int request,
+                         va_list ap)
+{
+        CERROR("liblustre did not support ioctl\n");
+        return -ENOSYS;
+}
+
+/*
+ * we already do syncronous read/write
+ */
+static int llu_iop_sync(struct inode *inode)
+{
+        return 0;
+}
+
+static int llu_iop_datasync(struct inode *inode)
+{
+        return 0;
 }
 
 struct filesys_ops llu_filesys_ops =
@@ -608,31 +1381,40 @@ struct filesys_ops llu_filesys_ops =
         fsop_gone: llu_fsop_gone,
 };
 
+struct inode *llu_iget(struct filesys *fs, struct lustre_md *md)
+{
+        struct inode *inode;
+        struct ll_fid fid;
+        struct file_identifier fileid = {&fid, sizeof(fid)};
+
+        if ((md->body->valid &
+             (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE)) !=
+            (OBD_MD_FLGENER | OBD_MD_FLID | OBD_MD_FLTYPE))
+                CERROR("invalide fields!\n");
+
+        /* try to find existing inode */
+        fid.id = md->body->ino;
+        fid.generation = md->body->generation;
+        fid.f_type = md->body->mode & S_IFMT;
+
+        inode = _sysio_i_find(fs, &fileid);
+        if (inode) {
+                if (llu_i2info(inode)->lli_st_generation ==
+                    md->body->generation) {
+                        llu_update_inode(inode, md->body, md->lsm);
+                        return inode;
+                } else
+                        I_RELE(inode);
+        }
 
-static struct inode_ops llu_inode_ops = {
-        inop_lookup:    llu_iop_lookup,
-        inop_getattr:   llu_iop_getattr,
-        inop_setattr:   llu_iop_setattr,
-        inop_getdirentries:     NULL,
-        inop_mkdir:     llu_iop_mkdir,
-        inop_rmdir:     NULL,
-        inop_symlink:   llu_iop_symlink,
-        inop_readlink:  NULL,
-        inop_open:      llu_iop_open,
-        inop_close:     llu_iop_close,
-        inop_unlink:    NULL,
-        inop_ipreadv:   llu_iop_ipreadv,
-        inop_ipwritev:  llu_iop_ipwritev,
-        inop_iodone:    llu_iop_iodone,
-        inop_fcntl:     NULL,
-        inop_sync:      NULL,
-        inop_datasync:  NULL,
-        inop_ioctl:     NULL,
-        inop_mknod:     NULL,
-        inop_statvfs:   NULL,
-        inop_gone:      llu_iop_gone,
-};
+        inode = llu_new_inode(fs, &fid);
+        if (inode)
+                llu_update_inode(inode, md->body, md->lsm);
+        
+        return inode;
+}
 
+extern struct list_head lustre_profile_list;
 
 static int
 llu_fsswop_mount(const char *source,
@@ -644,22 +1426,23 @@ llu_fsswop_mount(const char *source,
         struct filesys *fs;
         struct inode *root;
         struct pnode_base *rootpb;
-        static struct qstr noname = { NULL, 0, 0 };
+        struct obd_device *obd;
         struct ll_fid rootfid;
-
         struct llu_sb_info *sbi;
-        struct ptlrpc_connection *mdc_conn;
+        struct obd_statfs osfs;
+        static struct qstr noname = { NULL, 0, 0 };
         struct ptlrpc_request *request = NULL;
-        struct mds_body *root_body;
-        struct obd_uuid param_uuid;
+        struct lustre_handle mdc_conn = {0, };
+        struct lustre_handle osc_conn = {0, };
+        struct lustre_md md;
         class_uuid_t uuid;
-        struct obd_device *obd;
-        char *osc=mount_option.osc_uuid;
-        char *mdc=mount_option.mdc_uuid;
+        struct lustre_profile *lprof;
+        char *osc = NULL, *mdc = NULL;
         int err = -EINVAL;
 
         ENTRY;
 
+        /* allocate & initialize sbi */
         OBD_ALLOC(sbi, sizeof(*sbi));
         if (!sbi)
                 RETURN(-ENOMEM);
@@ -668,6 +1451,72 @@ llu_fsswop_mount(const char *source,
         generate_random_uuid(uuid);
         class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
 
+        /* zeroconf */
+        if (g_zconf) {
+                struct config_llog_instance cfg;
+                int len;
+
+                if (!g_zconf_mdsname) {
+                        CERROR("no mds name\n");
+                        GOTO(out_free, err = -EINVAL);
+                }
+
+                /* XXX */
+                /* generate a string unique to this super, let's try
+                 the address of the super itself.*/
+                len = (sizeof(sbi) * 2) + 1; 
+                OBD_ALLOC(sbi->ll_instance, len);
+                if (sbi->ll_instance == NULL) 
+                        GOTO(out_free, err = -ENOMEM);
+                sprintf(sbi->ll_instance, "%p", sbi);
+
+                cfg.cfg_instance = sbi->ll_instance;
+                cfg.cfg_uuid = sbi->ll_sb_uuid;
+                err = liblustre_process_log(&cfg);
+                if (err < 0) {
+                        CERROR("Unable to process log: %s\n", g_zconf_profile);
+
+                        GOTO(out_free, err);
+                }
+
+                lprof = class_get_profile(g_zconf_profile);
+                if (lprof == NULL) {
+                        CERROR("No profile found: %s\n", g_zconf_profile);
+                        GOTO(out_free, err = -EINVAL);
+                }
+                if (osc)
+                        OBD_FREE(osc, strlen(osc) + 1);
+                OBD_ALLOC(osc, strlen(lprof->lp_osc) + 
+                          strlen(sbi->ll_instance) + 2);
+                sprintf(osc, "%s-%s", lprof->lp_osc, sbi->ll_instance);
+
+                if (mdc)
+                        OBD_FREE(mdc, strlen(mdc) + 1);
+                OBD_ALLOC(mdc, strlen(lprof->lp_mdc) + 
+                          strlen(sbi->ll_instance) + 2);
+                sprintf(mdc, "%s-%s", lprof->lp_mdc, sbi->ll_instance);
+        } else {
+                /* setup from dump_file */
+                if (list_empty(&lustre_profile_list)) {
+                        CERROR("no profile\n");
+                        GOTO(out_free, err = -EINVAL);
+                }
+
+                lprof = list_entry(lustre_profile_list.next,
+                                   struct lustre_profile, lp_list);
+                osc = lprof->lp_osc;
+                mdc = lprof->lp_mdc;
+        }
+
+        if (!osc) {
+                CERROR("no osc\n");
+                GOTO(out_free, err = -EINVAL);
+        }
+        if (!mdc) {
+                CERROR("no mdc\n");
+                GOTO(out_free, err = -EINVAL);
+        }
+
         fs = _sysio_fs_new(&llu_filesys_ops, flags, sbi);
         if (!fs) {
                 err = -ENOMEM;
@@ -677,65 +1526,72 @@ llu_fsswop_mount(const char *source,
         obd = class_name2obd(mdc);
         if (!obd) {
                 CERROR("MDC %s: not setup or attached\n", mdc);
-                err = -EINVAL;
-                goto out_free;
+                GOTO(out_free, err = -EINVAL);
         }
 
+        if (mdc_init_ea_size(obd, osc))
+                GOTO(out_free, err = -EINVAL);
+
         /* setup mdc */
-        /* FIXME need recover stuff */
-        err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid);
+        err = obd_connect(&mdc_conn, obd, &sbi->ll_sb_uuid);
         if (err) {
                 CERROR("cannot connect to %s: rc = %d\n", mdc, err);
-                goto out_free;
+                GOTO(out_free, err);
         }
+        sbi->ll_mdc_exp = class_conn2export(&mdc_conn);
 
-        mdc_conn = sbi2mdc(sbi)->cl_import->imp_connection;
+        err = obd_statfs(obd, &osfs, 100000000);
+        if (err)
+                GOTO(out_mdc, err);
+
+        /*
+         * FIXME fill fs stat data into sbi here!!! FIXME
+         */
 
         /* setup osc */
         obd = class_name2obd(osc);
         if (!obd) {
                 CERROR("OSC %s: not setup or attached\n", osc);
-                err = -EINVAL;
-                goto out_mdc;
+                GOTO(out_mdc, err = -EINVAL);
         }
 
-        err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid);
+        err = obd_connect(&osc_conn, obd, &sbi->ll_sb_uuid);
         if (err) {
                 CERROR("cannot connect to %s: rc = %d\n", osc, err);
-                goto out_mdc;
+                GOTO(out_mdc, err);
         }
+        sbi->ll_osc_exp = class_conn2export(&osc_conn);
 
-        err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
+        err = mdc_getstatus(sbi->ll_mdc_exp, &rootfid);
         if (err) {
                 CERROR("cannot mds_connect: rc = %d\n", err);
-                goto out_osc;
+                GOTO(out_osc, err);
         }
         CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
         sbi->ll_rootino = rootfid.id;
 
-/* XXX do we need this??
-        memset(&osfs, 0, sizeof(osfs));
-        rc = obd_statfs(class_conn2obd(&sbi->ll_mdc_conn),&osfs,jiffies-100*HZ);
-*/
         /* fetch attr of root inode */
-        err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
+        err = mdc_getattr(sbi->ll_mdc_exp, &rootfid,
                           OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
         if (err) {
                 CERROR("mdc_getattr failed for root: rc = %d\n", err);
-                goto out_request;
+                GOTO(out_osc, err);
+        }
+
+        err = mdc_req2lustre_md(request, 0, sbi->ll_osc_exp, &md);
+        if (err) {
+                CERROR("failed to understand root inode md: rc = %d\n",err);
+                GOTO(out_request, err);
         }
 
-        root_body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*root_body));
         LASSERT(sbi->ll_rootino != 0);
 
-        root = llu_new_inode(fs, root_body->ino, root_body->mode);
-        if (!root) {
-		err = -ENOMEM;
-                goto out_request;
+        root = llu_iget(fs, &md);
+        if (root == NULL) {
+                CERROR("fail to generate root inode\n");
+                GOTO(out_request, err = -EBADF);
         }
 
-        llu_update_inode(root, root_body, NULL);
-
 	/*
 	 * Generate base path-node for root.
 	 */
@@ -745,18 +1601,15 @@ llu_fsswop_mount(const char *source,
 		goto out_inode;
 	}
 
-	err = _sysio_do_mount(fs, rootpb, flags, NULL, mntp);
+	err = _sysio_do_mount(fs, rootpb, flags, tocover, mntp);
 	if (err) {
                 _sysio_pb_gone(rootpb);
 		goto out_inode;
         }
 
         ptlrpc_req_finished(request);
-        request = NULL;
 
-        printf("************************************************\n");
-        printf("*          Mount successfully!!!!!!!           *\n");
-        printf("************************************************\n");
+        printf("LibLustre: namespace mounted successfully!\n");
 
         return 0;
 
@@ -765,9 +1618,9 @@ out_inode:
 out_request:
         ptlrpc_req_finished(request);
 out_osc:
-        obd_disconnect(&sbi->ll_osc_conn, 0);
+        obd_disconnect(sbi->ll_osc_exp, 0);
 out_mdc:
-        obd_disconnect(&sbi->ll_mdc_conn, 0);
+        obd_disconnect(sbi->ll_mdc_exp, 0);
 out_free:
         OBD_FREE(sbi, sizeof(*sbi));
         return err;
@@ -777,3 +1630,31 @@ struct fssw_ops llu_fssw_ops = {
         llu_fsswop_mount
 };
 
+static struct inode_ops llu_inode_ops = {
+        inop_lookup:    llu_iop_lookup,
+        inop_getattr:   llu_iop_getattr,
+        inop_setattr:   llu_iop_setattr,
+        inop_getdirentries:     NULL,
+        inop_mkdir:     llu_iop_mkdir_raw,
+        inop_rmdir:     llu_iop_rmdir_raw,
+        inop_symlink:   llu_iop_symlink_raw,
+        inop_readlink:  llu_iop_readlink,
+        inop_open:      llu_iop_open,
+        inop_close:     llu_iop_close,
+        inop_link:      llu_iop_link_raw,
+        inop_unlink:    llu_iop_unlink_raw,
+        inop_rename:    llu_iop_rename_raw,
+        inop_ipreadv:   llu_iop_ipreadv,
+        inop_ipwritev:  llu_iop_ipwritev,
+        inop_iodone:    llu_iop_iodone,
+        inop_fcntl:     llu_iop_fcntl,
+        inop_sync:      llu_iop_sync,
+        inop_datasync:  llu_iop_datasync,
+        inop_ioctl:     llu_iop_ioctl,
+        inop_mknod:     llu_iop_mknod_raw,
+#if 0
+        inop_statvfs:   llu_iop_statvfs,
+#endif
+        inop_gone:      llu_iop_gone,
+};
+
diff --git a/lustre/liblustre/test_common.c b/lustre/liblustre/test_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..210d57e7fcfa143ba7766fc94ed776eb8ed15e05
--- /dev/null
+++ b/lustre/liblustre/test_common.c
@@ -0,0 +1,280 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test_common.h"
+
+int exit_on_err = 1;
+
+/******************************************************************
+ * util functions
+ ******************************************************************/
+
+#define EXIT(err)					\
+	do {						\
+		if (exit_on_err)			\
+			exit(err);			\
+	} while (0)
+
+#define EXIT_RET(err)					\
+	do {						\
+		if (exit_on_err)			\
+			exit(err);			\
+		else					\
+			return (err);			\
+	} while (0)
+
+
+void t_touch(const char *path)
+{
+        int fd, rc;
+
+        fd = open(path, O_RDWR|O_CREAT, 0644);
+        if (fd < 0) {
+                printf("open(%s) error: %s\n", path, strerror(errno));
+                EXIT(fd);
+        }
+
+        rc = close(fd);
+        if (rc) {
+                printf("close(%s) error: %s\n", path, strerror(errno));
+                EXIT(rc);
+        }
+}
+
+/* XXX Now libsysio don't support mcreate */
+void t_create(const char *path)
+{
+        return t_touch(path);
+#if 0
+        int rc;
+
+        rc = mknod(path, S_IFREG | 0644, 0);
+        if (rc) {
+                printf("mknod(%s) error: %s\n", path, strerror(errno));
+                exit(-1);
+        }
+#endif
+}
+
+void t_link(const char *src, const char *dst)
+{
+	int rc;
+
+	rc = link(src, dst);
+	if (rc) {
+		printf("link(%s -> %s) error: %s\n", src, dst, strerror(errno));
+		EXIT(1);
+	}
+}
+
+void t_unlink(const char *path)
+{
+        int rc;
+
+        rc = unlink(path);
+        if (rc) {
+                printf("unlink(%s) error: %s\n", path, strerror(errno));
+                EXIT(-1);
+        }
+}
+
+void t_mkdir(const char *path)
+{
+        int rc;
+
+        rc = mkdir(path, 00644);
+        if (rc < 0) {
+                printf("mkdir(%s) error: %s\n", path, strerror(errno));
+                EXIT(1);
+        }
+}
+
+void t_rmdir(const char *path)
+{
+        int rc;
+
+        rc = rmdir(path);
+        if (rc) {
+                printf("rmdir(%s) error: %s\n", path, strerror(errno));
+                EXIT(1);
+        }
+}
+
+void t_symlink(const char *src, const char *new)
+{
+	int rc;
+
+	rc = symlink(src, new);
+	if (rc) {
+		printf("symlink(%s<-%s) error: %s\n", src, new, strerror(errno));
+		EXIT(1);
+	}
+}
+
+#define MKDEV(a,b) (((a) << 8) | (b))
+void t_mknod(const char *path, mode_t mode, int major, int minor)
+{
+	int rc;
+
+        rc = mknod(path, mode, MKDEV(5, 4));
+        if (rc) {
+                printf("mknod(%s) error: %s\n", path, strerror(errno));
+                EXIT(1);
+        }
+}
+
+void t_chmod_raw(const char *path, mode_t mode)
+{
+	int rc;
+	
+	rc = chmod(path, mode);
+	if (rc) {
+                printf("chmod(%s) error: %s\n", path, strerror(errno));
+                EXIT(1);
+        }
+}
+
+void t_chmod(const char *path, const char *format, ...)
+{
+}
+
+void t_rename(const char *oldpath, const char *newpath)
+{
+        int rc;
+
+        rc = rename(oldpath, newpath);
+        if (rc) {
+                printf("rename(%s -> %s) error: %s\n",
+		       oldpath, newpath, strerror(errno));
+                EXIT(1);
+        }
+}
+
+int t_open_readonly(const char *path)
+{
+        int fd;
+
+        fd = open(path, O_RDONLY);
+        if (fd < 0) {
+                printf("open(%s) error: %s\n", path, strerror(errno));
+                EXIT_RET(fd);
+        }
+        return fd;
+}
+
+int t_open(const char *path)
+{
+        int fd;
+
+        fd = open(path, O_RDWR);
+        if (fd < 0) {
+                printf("open(%s) error: %s\n", path, strerror(errno));
+                EXIT_RET(fd);
+        }
+        return fd;
+}
+
+void t_close(int fd)
+{
+        int rc;
+
+        rc = close(fd);
+        if (rc < 0) {
+                printf("close(%d) error: %s\n", fd, strerror(errno));
+                EXIT(1);
+        }
+}
+
+int t_check_stat(const char *name, struct stat *buf)
+{
+	struct stat stat;
+        int rc;
+
+	rc = lstat(name, &stat);
+        if (rc) {
+		printf("error %d stat %s\n", rc, name);
+		EXIT_RET(rc);
+	}
+        if (buf)
+                memcpy(buf, &stat, sizeof(*buf));
+
+	return 0;
+}
+
+int t_check_stat_fail(const char *name)
+{
+	struct stat stat;
+        int rc;
+
+	rc = lstat(name, &stat);
+        if (!rc) {
+		printf("%s still exists\n", name);
+		EXIT(-1);
+	}
+
+	return 0;
+}
+
+void t_echo_create(const char *path, const char *str)
+{
+        int fd, rc;
+
+        fd = open(path, O_RDWR|O_CREAT, 0644);
+        if (fd < 0) {
+                printf("open(%s) error: %s\n", path, strerror(errno));
+                EXIT(fd);
+        }
+
+	if (write(fd, str, strlen(str)+1) != strlen(str)+1) {
+                printf("write(%s) error: %s\n", path, strerror(errno));
+                EXIT(fd);
+	}
+
+        rc = close(fd);
+        if (rc) {
+                printf("close(%s) error: %s\n", path, strerror(errno));
+                EXIT(rc);
+        }
+}
+
+void _t_grep(const char *path, char *str, int should_contain)
+{
+	char buf[1024];
+	int fd;
+	int rc;
+	
+	fd = t_open_readonly(path);
+	if (lseek(fd, 0, SEEK_SET) == -1) {
+		printf("pread_once: seek to 0 error: %s\n", strerror(errno));
+		EXIT(fd);
+	}
+
+	rc = read(fd, buf, 1023);
+	if (rc < 0) {
+		printf("grep: read error: %s\n", strerror(errno));
+		EXIT(-1);
+	}
+	close(fd);
+	buf[rc] = 0;
+
+	if ((strstr(buf, str) != 0) ^ should_contain) {
+		printf("grep: can't find string %s\n", str);
+		EXIT(-1);
+	}
+}
+
+void t_grep(const char *path, char *str)
+{
+	_t_grep(path, str, 1);
+}
+
+void t_grep_v(const char *path, char *str)
+{
+	_t_grep(path, str, 0);
+}
diff --git a/lustre/liblustre/test_common.h b/lustre/liblustre/test_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..af638f23a28dab4ec17c8118d849e8e027c15eeb
--- /dev/null
+++ b/lustre/liblustre/test_common.h
@@ -0,0 +1,31 @@
+#ifndef __TEST_COMMON__H
+#define __TEST_COMMON__H
+
+#define ENV_LUSTRE_MNTPNT               "LIBLUSTRE_MOUNT_POINT"
+#define ENV_LUSTRE_MNTTGT               "LIBLUSTRE_MOUNT_TARGET"
+#define ENV_LUSTRE_DUMPFILE             "LIBLUSTRE_DUMPFILE"
+
+extern int exit_on_err;
+
+void t_touch(const char *path);
+void t_create(const char *path);
+void t_link(const char *src, const char *dst);
+void t_unlink(const char *path);
+void t_mkdir(const char *path);
+void t_rmdir(const char *path);
+void t_symlink(const char *src, const char *new);
+void t_mknod(const char *path, mode_t mode, int major, int minor);
+void t_chmod_raw(const char *path, mode_t mode);
+void t_chmod(const char *path, const char *format, ...);
+void t_rename(const char *oldpath, const char *newpath);
+int t_open_readonly(const char *path);
+int t_open(const char *path);
+void t_close(int fd);
+int t_check_stat(const char *name, struct stat *buf);
+int t_check_stat_fail(const char *name);
+void t_echo_create(const char *path, const char *str);
+//int t_pread_once(const char *path, char *buf, size_t size, off_t offset);
+void t_grep(const char *path, char *str);
+void t_grep_v(const char *path, char *str);
+
+#endif
diff --git a/lustre/liblustre/test_lock_cancel.c b/lustre/liblustre/test_lock_cancel.c
new file mode 100644
index 0000000000000000000000000000000000000000..9350e4c5f08267bd7accea1fd3d54ebf290982fa
--- /dev/null
+++ b/lustre/liblustre/test_lock_cancel.c
@@ -0,0 +1,194 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Light user test program
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/queue.h>
+
+#include <sysio.h>
+#include <mount.h>
+
+#include <test_common.h>
+
+#include <mpi.h>
+
+/******************************************************************************/
+/*
+ * MPI_CHECK will display a custom error message as well as an error string
+ * from the MPI_STATUS and then exit the program
+ */
+
+#define MPI_CHECK(MPI_STATUS, MSG) do {                                  \
+    char resultString[MPI_MAX_ERROR_STRING];                             \
+    int resultLength;                                                    \
+                                                                         \
+    if (MPI_STATUS != MPI_SUCCESS) {                                     \
+        fprintf(stdout, "** error **\n");                                \
+        fprintf(stdout, "ERROR in %s (line %d): %s.\n",                  \
+                __FILE__, __LINE__, MSG);                                \
+        MPI_Error_string(MPI_STATUS, resultString, &resultLength);       \
+        fprintf(stdout, "MPI %s\n", resultString);                       \
+        fprintf(stdout, "** exiting **\n");                              \
+        MPI_Abort(MPI_COMM_WORLD, 1);                                    \
+    }                                                                    \
+} while(0)
+
+int		numTasks     = 0,	/* MPI variables */
+		rank         = 0,
+		tasksPerNode = 0;	/* tasks per node */
+
+
+
+
+static char *test_file_name = "/mnt/lustre/test_lock_cancel";
+
+extern void __liblustre_setup_(void);
+extern void __liblustre_cleanup_(void);
+
+void usage(char *cmd)
+{
+        printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
+        printf("       \t%s --dumpfile dumpfile\n", cmd);
+        exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+        int opt_index, c;
+        static struct option long_opts[] = {
+                {"target", 1, 0, 0},
+                {"dumpfile", 1, 0, 0},
+                {0, 0, 0, 0}
+        };
+	int fd;
+        long time1, time2;
+        struct stat statbuf;
+
+        if (argc < 3)
+                usage(argv[0]);
+
+        while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
+                switch (c) {
+                case 0: {
+                        if (!optarg[0])
+                                usage(argv[0]);
+
+                        if (!strcmp(long_opts[opt_index].name, "target")) {
+                                setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
+                        } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
+                                setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
+                        } else
+                                usage(argv[0]);
+                        break;
+                }
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+        if (optind != argc)
+                usage(argv[0]);
+
+        __liblustre_setup_();
+
+	MPI_CHECK(MPI_Init(&argc, &argv), "MPI_Init()");
+	MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, &numTasks), "MPI_Comm_size");
+	MPI_CHECK(MPI_Comm_rank(MPI_COMM_WORLD, &rank), "MPI_Comm_rank");
+
+        if (numTasks < 2) {
+                printf("this demo can't run on single node!\n");
+                goto cleanup;
+        }
+
+        if (rank == 0) {
+                unlink(test_file_name);
+        }
+
+        MPI_Barrier(MPI_COMM_WORLD);
+        if (rank == 1) {
+                printf("Node 1: creating file %s ...\n", test_file_name);
+                fflush(stdout);
+
+                fd = open(test_file_name, O_CREAT|O_RDWR, 0755);
+                if (fd < 0) {
+                        printf("Node %d: creat file err: %d", rank, fd);
+                        fflush(stdout);
+                        goto cleanup;
+                }
+                close(fd);
+                printf("Node 1: done creation. perform stat on file %s ...\n", test_file_name);
+                fflush(stdout);
+
+                if (stat(test_file_name, &statbuf)) {
+                        printf("Node %d: stat file err: %d", rank, fd);
+                        fflush(stdout);
+                        goto cleanup;
+                }
+
+                printf("Node %d: done stat on file\n", rank);
+                fflush(stdout);
+        } else {
+                printf("Node %d: waiting node 1 create & stat file\n", rank);
+                fflush(stdout);
+        }
+
+        MPI_Barrier(MPI_COMM_WORLD);
+        
+        if (rank == 1) {
+                printf("Node 1: file has been create+stat, abort excution here!!!!!!!\n");
+                fflush(stdout);
+                exit(0);
+        }
+        
+        sleep(1);
+        printf("Node %d: synced with Node 1. sleep 5 seconds...\n", rank);
+        fflush(stdout);
+        sleep(5);
+        printf("Node %d: wakeup from sleep. perform unlink()...\n", rank);
+        fflush(stdout);
+
+        time1 = time(NULL);
+        if (unlink(test_file_name)) {
+                printf("Node %d: error unlink file: %d\n", rank, fd);
+                fflush(stdout);
+                goto cleanup;
+        }
+        time2 = time(NULL);
+        printf("Node %d: successfully unlink file, cost %ld seconds.\n",
+                rank, time2 - time1);
+        fflush(stdout);
+
+cleanup:
+        __liblustre_cleanup_();
+        printf("Node %d: end sucessfully.\n", rank);
+	return 0;
+}
diff --git a/lustre/llite/Makefile.am b/lustre/llite/Makefile.am
index 9ef9b7f5e08109e81b56d7f7aba1c96ddca3da81..9382d5df5f19d1afc72baa21759fbb98eca128ec 100644
--- a/lustre/llite/Makefile.am
+++ b/lustre/llite/Makefile.am
@@ -9,8 +9,8 @@ MODULE = llite
 modulefs_DATA = llite.o
 EXTRA_PROGRAMS = llite
 
-llite_SOURCES = dcache.c commit_callback.c  rw.c  super25.c
-llite_SOURCES += file.c dir.c sysctl.c symlink.c llite_lib.c
-llite_SOURCES += namei.c lproc_llite.c super.c iod.c llite_internal.h
+llite_SOURCES = dcache.c dir.c file.c llite_close.c llite_lib.c llite_nfs.c
+llite_SOURCES += lproc_llite.c namei.c rw.c rw24.c special.c super.c super25.c
+llite_SOURCES += symlink.c sysctl.c llite_internal.h
 
 include $(top_srcdir)/Rules
diff --git a/lustre/llite/Makefile.mk b/lustre/llite/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..f01dfdeceac753e28c18376c37e5295caf5a3067
--- /dev/null
+++ b/lustre/llite/Makefile.mk
@@ -0,0 +1,11 @@
+# Copyright (C) 2003  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += llite.o
+llite-objs := llite_lib.o dcache.o super.o rw.o \
+	super25.o file.o dir.o sysctl.o symlink.o namei.o lproc_llite.o \
+	rw26.o llite_nfs.o
diff --git a/lustre/llite/commit_callback.c b/lustre/llite/commit_callback.c
deleted file mode 100644
index 99fc2854c704391b10d967e067e62de5cbb24227..0000000000000000000000000000000000000000
--- a/lustre/llite/commit_callback.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  The daemon that causes completed but not committed transactions
- *   on the MDS to be flushed periodically when they are committed.
- *   A gratuitous getattr RPC is made to the MDS to discover the
- *   last committed record.
- *
- *  Lustre High Availability Daemon
- *
- *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
- *
- *  This code is issued under the GNU General Public License.
- *  See the file COPYING in this distribution
- *
- *  by Peter Braam <braam@clusterfs.com>
- *
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/kmod.h>
-#include <linux/quotaops.h>
-#include <asm/unistd.h>
-#include <asm/uaccess.h>
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <linux/lustre_lite.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_compat25.h>
-
-static int ll_commitcbd_check_event(struct ll_sb_info *sbi)
-{
-        int rc = 0;
-        ENTRY;
-
-        spin_lock(&sbi->ll_commitcbd_lock);
-        if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING)
-                GOTO(out, rc = 1);
-
-        EXIT;
- out:
-        spin_unlock(&sbi->ll_commitcbd_lock);
-        return rc;
-}
-
-static int ll_commitcbd_main(void *arg)
-{
-        struct ll_sb_info *sbi = (struct ll_sb_info *)arg;
-        unsigned long flags;
-        ENTRY;
-
-        lock_kernel();
-        kportal_daemonize("lustre_commitcbd");
-
-        SIGNAL_MASK_LOCK(current, flags);
-        sigfillset(&current->blocked);
-        RECALC_SIGPENDING;
-        SIGNAL_MASK_UNLOCK(current, flags);
-
-        unlock_kernel();
-
-        /* Record that the  thread is running */
-        sbi->ll_commitcbd_waketime = LTIME_S(CURRENT_TIME);
-        sbi->ll_commitcbd_timeout = 10 * HZ;
-        sbi->ll_commitcbd_thread = current;
-        sbi->ll_commitcbd_flags =  LL_COMMITCBD_RUNNING;
-        wake_up(&sbi->ll_commitcbd_ctl_waitq);
-
-        /* And now, loop forever on requests */
-        while (1) {
-                struct l_wait_info lwi = { 0 };
-                l_wait_event(sbi->ll_commitcbd_waitq,
-                             ll_commitcbd_check_event(sbi), &lwi);
-
-                spin_lock(&sbi->ll_commitcbd_lock);
-                if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING) {
-                        spin_unlock(&sbi->ll_commitcbd_lock);
-                        EXIT;
-                        break;
-                }
-
-                schedule_timeout(sbi->ll_commitcbd_timeout);
-                CERROR("commit callback daemon woken up - FIXME\n");
-                spin_unlock(&sbi->ll_commitcbd_lock);
-        }
-
-        sbi->ll_commitcbd_thread = NULL;
-        sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPED;
-        wake_up(&sbi->ll_commitcbd_ctl_waitq);
-        CDEBUG(D_NET, "commit callback daemon exiting %d\n", current->pid);
-        RETURN(0);
-}
-
-
-
-int ll_commitcbd_setup(struct ll_sb_info *sbi)
-{
-        int rc;
-        struct l_wait_info lwi = { 0 };
-        ENTRY;
-
-        rc = kernel_thread(ll_commitcbd_main, (void *) sbi,
-                           CLONE_VM | CLONE_FS | CLONE_FILES);
-        if (rc < 0) {
-                CERROR("cannot start thread\n");
-                RETURN(rc);
-        }
-        l_wait_event(sbi->ll_commitcbd_ctl_waitq,
-                     sbi->ll_commitcbd_flags & LL_COMMITCBD_RUNNING, &lwi);
-        RETURN(0);
-}
-
-
-int ll_commitcbd_cleanup(struct ll_sb_info *sbi)
-{
-        struct l_wait_info lwi = { 0 };
-        sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPING;
-
-        wake_up(&sbi->ll_commitcbd_waitq);
-        l_wait_event(sbi->ll_commitcbd_ctl_waitq,
-                     sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPED, &lwi);
-        RETURN(0);
-}
diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c
index 8c55b3d238d7beaf19dd0f11bb56c95b36d46bf7..9dba881179a43b4ea5592bff647f8ba7862d745c 100644
--- a/lustre/llite/dcache.c
+++ b/lustre/llite/dcache.c
@@ -36,9 +36,11 @@
 /* should NOT be called with the dcache lock, see fs/dcache.c */
 static void ll_release(struct dentry *de)
 {
-        struct ll_dentry_data *lld = ll_d2d(de);
+        struct ll_dentry_data *lld;
         ENTRY;
-
+        LASSERT(de != NULL);
+        lld = ll_d2d(de);
+        LASSERT(lld != NULL);
         LASSERT(lld->lld_cwd_count == 0);
         LASSERT(lld->lld_mnt_count == 0);
         OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data));
@@ -65,124 +67,129 @@ void ll_intent_release(struct lookup_intent *it)
         struct lustre_handle *handle;
         ENTRY;
 
-        if (it->it_op && it->it_lock_mode) {
-                handle = (struct lustre_handle *)it->it_lock_handle;
+        if (it->it_op && it->d.lustre.it_lock_mode) {
+                handle = (struct lustre_handle *)&it->d.lustre.it_lock_handle;
                 CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64
-                       " from it %p\n",
-                       handle->cookie, it);
-                ldlm_lock_decref(handle, it->it_lock_mode);
+                       " from it %p\n", handle->cookie, it);
+                ldlm_lock_decref(handle, it->d.lustre.it_lock_mode);
 
                 /* intent_release may be called multiple times, from
                    this thread and we don't want to double-decref this
                    lock (see bug 494) */
-                it->it_lock_mode = 0;
+                it->d.lustre.it_lock_mode = 0;
         }
         it->it_magic = 0;
         it->it_op_release = 0;
+        it->d.lustre.it_disposition = 0;
+        it->d.lustre.it_data = NULL;
         EXIT;
 }
 
 void ll_unhash_aliases(struct inode *inode)
 {
-        struct dentry *dentry = NULL;
-        struct list_head *tmp;
+	struct list_head *tmp, *head;
         struct ll_sb_info *sbi;
         ENTRY;
 
-        if (inode == NULL) {
-                CERROR("unexpected NULL inode, tell phil\n");
-                return;
-        }
-
         sbi = ll_i2sbi(inode);
 
-        CDEBUG(D_INODE, "marking dentries for ino %lx/%x invalid\n",
-               inode->i_ino, inode->i_generation);
+        CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n",
+               inode->i_ino, inode->i_generation, inode);
 
-        spin_lock(&dcache_lock);
-        list_for_each(tmp, &inode->i_dentry) {
-                dentry = list_entry(tmp, struct dentry, d_alias);
-
-                list_del_init(&dentry->d_hash);
-                dentry->d_flags |= DCACHE_LUSTRE_INVALID;
-                list_add(&dentry->d_hash, &sbi->ll_orphan_dentry_list);
+        if (inode == NULL) {
+                CERROR("unexpected NULL inode, tell phil\n");
+                return;
         }
-
-        spin_unlock(&dcache_lock);
+        head = &inode->i_dentry;
+restart:
+	spin_lock(&dcache_lock);
+	tmp = head;
+	while ((tmp = tmp->next) != head) {
+		struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
+		if (!atomic_read(&dentry->d_count)) {
+			dget_locked(dentry);
+			__d_drop(dentry);
+			spin_unlock(&dcache_lock);
+			dput(dentry);
+			goto restart;
+		} else {
+                        hlist_del_init(&dentry->d_hash);
+                        dentry->d_flags |= DCACHE_LUSTRE_INVALID;
+                        hlist_add_head(&dentry->d_hash, 
+                                       &sbi->ll_orphan_dentry_list);
+                }
+	}
+	spin_unlock(&dcache_lock);
         EXIT;
 }
 
 extern struct dentry *ll_find_alias(struct inode *, struct dentry *);
 
-static int revalidate_it_finish(struct ptlrpc_request *request,
-                              struct inode *parent, struct dentry **de,
-                              struct lookup_intent *it, int offset, obd_id ino)
+static int revalidate_it_finish(struct ptlrpc_request *request, int offset,
+                                struct lookup_intent *it,
+                                struct dentry *de)
 {
-        struct ll_sb_info     *sbi = ll_i2sbi(parent);
-        struct lustre_md      md;
-        int                    rc = 0;
+        struct ll_sb_info *sbi;
+        int rc = 0;
         ENTRY;
 
-        /* NB 1 request reference will be taken away by ll_intent_lock()
-         * when I return */
+        if (!request)
+                RETURN(0);
 
         if (it_disposition(it, DISP_LOOKUP_NEG))
                 RETURN(-ENOENT);
 
-        /* ll_intent_lock was successful, now prepare the lustre_md) */
-        rc = mdc_req2lustre_md(request, offset, &sbi->ll_osc_conn, &md);
-        if (rc)
-                RETURN(rc);
-
-        ll_update_inode((*de)->d_inode, md.body, md.lsm);
+        sbi = ll_i2sbi(de->d_inode);
+        rc = ll_prep_inode(sbi->ll_osc_exp, &de->d_inode, request, offset,NULL);
 
-        if (md.lsm != NULL && ll_i2info((*de)->d_inode)->lli_smd != md.lsm)
-                obd_free_memmd (&sbi->ll_osc_conn, &md.lsm);
-
-        CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
-               (*de)->d_inode, (*de)->d_inode->i_ino,
-               (*de)->d_inode->i_generation);
-        ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle,
-                           (*de)->d_inode);
         RETURN(rc);
 }
 
-int ll_have_md_lock(struct dentry *de)
+void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry)
 {
-        struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
-        struct lustre_handle lockh;
-        struct ldlm_res_id res_id = { .name = {0} };
-        struct obd_device *obddev;
-        int flags;
-        ENTRY;
-
-        if (!de->d_inode)
-               RETURN(0);
-
-        obddev = class_conn2obd(&sbi->ll_mdc_conn);
-        res_id.name[0] = de->d_inode->i_ino;
-        res_id.name[1] = de->d_inode->i_generation;
+        LASSERT(it != NULL);
+        LASSERT(dentry != NULL);
+
+        if (it->d.lustre.it_lock_mode && dentry->d_inode != NULL) {
+                struct inode *inode = dentry->d_inode;
+                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
+                       inode, inode->i_ino, inode->i_generation);
+                mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);
+        }
 
-        CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
+        /* drop IT_LOOKUP locks */
+        if (it->it_op == IT_LOOKUP)
+                ll_intent_release(it);
+}
 
-        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_MATCH_DATA;
-        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
-                            NULL, 0, LCK_PR, de->d_inode, &lockh)) {
-                ldlm_lock_decref(&lockh, LCK_PR);
-                RETURN(1);
+void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft)
+{
+        struct lookup_intent *it = *itp;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+        if (it && it->it_magic != INTENT_MAGIC) { 
+                CERROR("WARNING: uninitialized intent\n");
+                LBUG();
         }
+        if (it && (it->it_op == IT_GETATTR || it->it_op == 0))
+                it->it_op = IT_LOOKUP;
+        
+#endif
+        if (!it || it->it_op == IT_GETXATTR)
+                it = *itp = deft;
 
-        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
-                            NULL, 0, LCK_PW, de->d_inode, &lockh)) {
-                ldlm_lock_decref(&lockh, LCK_PW);
-                RETURN(1);
-        }
-        RETURN(0);
+        it->it_op_release = ll_intent_release;
 }
 
 int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it)
 {
         int rc;
+        struct ll_fid pfid, cfid;
+        struct it_cb_data icbd;
+        struct ll_uctxt ctxt;
+        struct ptlrpc_request *req = NULL;
+        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
+        struct obd_export *exp;
+
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%s\n", de->d_name.name,
                LL_IT2STR(it));
@@ -191,6 +198,12 @@ int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it)
         if (de->d_inode == NULL)
                 RETURN(0);
 
+        exp = ll_i2mdcexp(de->d_inode);
+        ll_inode2fid(&pfid, de->d_parent->d_inode);
+        ll_inode2fid(&cfid, de->d_inode);
+        icbd.icbd_parent = de->d_parent->d_inode;
+        icbd.icbd_childp = &de;
+
         /* 
          * never execute intents for mount points
          * - attrs will be fixed up in ll_revalidate_inode
@@ -198,65 +211,34 @@ int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it)
         if (d_mountpoint(de))
                 RETURN(1);
 
-        if (it)
-                it->it_op_release = ll_intent_release;
-
-        if (it == NULL || it->it_op == IT_GETATTR) {
-                /* We could just return 1 immediately, but since we should only
-                 * be called in revalidate2 if we already have a lock, let's
-                 * verify that. */
-                struct inode *inode = de->d_inode;
-                struct ll_sb_info *sbi = ll_i2sbi(inode);
-                struct obd_device *obddev = class_conn2obd(&sbi->ll_mdc_conn);
-                struct ldlm_res_id res_id =
-                        { .name = {inode->i_ino, (__u64)inode->i_generation} };
-                struct lustre_handle lockh;
-                int flags;
-                flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_MATCH_DATA;
-                rc = ldlm_lock_match(obddev->obd_namespace, flags, &res_id,
-                                     LDLM_PLAIN, NULL, 0, LCK_PR, inode,
-                                     &lockh);
-                if (rc) {
-                        de->d_flags &= ~DCACHE_LUSTRE_INVALID;
-                        if (it && it->it_op == IT_GETATTR) {
-                                memcpy(it->it_lock_handle, &lockh,
-                                       sizeof(lockh));
-                                it->it_lock_mode = LCK_PR;
-                        } else {
-                                ldlm_lock_decref(&lockh, LCK_PR);
-                        }
-                        RETURN(1);
-                }
-                rc = ldlm_lock_match(obddev->obd_namespace, flags, &res_id,
-                                     LDLM_PLAIN, NULL, 0, LCK_PW, inode,
-                                     &lockh);
-                if (rc) {
-                        de->d_flags &= ~DCACHE_LUSTRE_INVALID;
-                        if (it && it->it_op == IT_GETATTR) {
-                                memcpy(it->it_lock_handle, &lockh,
-                                       sizeof(lockh));
-                                it->it_lock_mode = LCK_PW;
-                        } else {
-                                ldlm_lock_decref(&lockh, LCK_PW);
-                        }
-                        RETURN(1);
-                }
-                if (S_ISDIR(de->d_inode->i_mode))
-                        ll_invalidate_inode_pages(de->d_inode);
-                ll_unhash_aliases(de->d_inode);
-                RETURN(0);
-        }
+        ll_frob_intent(&it, &lookup_it);
+        LASSERT(it);
+
+        ll_i2uctxt(&ctxt, de->d_parent->d_inode, de->d_inode);
+
+        rc = mdc_intent_lock(exp, &ctxt, &pfid, de->d_name.name, de->d_name.len,
+                             NULL, 0,
+                             &cfid, it, flags, &req, ll_mdc_blocking_ast);
+        /* If req is NULL, then mdc_intent_lock only tried to do a lock match;
+         * if all was well, it will return 1 if it found locks, 0 otherwise. */
+        if (req == NULL && rc >= 0)
+                GOTO(out, rc);
 
-        rc = ll_intent_lock(de->d_parent->d_inode, &de, it, flags,
-                            revalidate_it_finish);
         if (rc < 0) {
                 if (rc != -ESTALE) {
-                        CERROR("ll_intent_lock: rc %d : it->it_status %d\n", rc,
-                               it->it_status);
+                        CDEBUG(D_INFO, "ll_intent_lock: rc %d : it->it_status "
+                               "%d\n", rc, it->d.lustre.it_status);
                 }
-                ll_unhash_aliases(de->d_inode);
-                RETURN(0);
+                GOTO(out, rc = 0);
+        }
+
+        rc = revalidate_it_finish(req, 1, it, de);
+        if (rc != 0) {
+                ll_intent_release(it);
+                GOTO(out, rc = 0);
         }
+        rc = 1;
+
         /* unfortunately ll_intent_lock may cause a callback and revoke our
            dentry */
         spin_lock(&dcache_lock);
@@ -264,10 +246,20 @@ int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it)
         __d_rehash(de, 0);
         spin_unlock(&dcache_lock);
 
-        RETURN(1);
+ out:
+        if (req != NULL && rc == 1)
+                ptlrpc_req_finished(req);
+        if (rc == 0) { 
+                ll_unhash_aliases(de->d_inode);
+                de->d_flags |= DCACHE_LUSTRE_INVALID;
+        } else { 
+                ll_lookup_finish_locks(it, de);
+                de->d_flags &= ~DCACHE_LUSTRE_INVALID;
+        }
+        RETURN(rc);
 }
 
-static void ll_pin(struct dentry *de, struct vfsmount *mnt, int flag)
+/*static*/ void ll_pin(struct dentry *de, struct vfsmount *mnt, int flag)
 {
         struct inode *inode= de->d_inode;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
@@ -296,7 +288,7 @@ static void ll_pin(struct dentry *de, struct vfsmount *mnt, int flag)
         unlock_kernel();
 
         handle = (flag) ? &ldd->lld_mnt_och : &ldd->lld_cwd_och;
-        rc = obd_pin(&sbi->ll_mdc_conn, inode->i_ino, inode->i_generation,
+        rc = obd_pin(sbi->ll_mdc_exp, inode->i_ino, inode->i_generation,
                      inode->i_mode & S_IFMT, handle, flag);
 
         if (rc) {
@@ -313,7 +305,7 @@ static void ll_pin(struct dentry *de, struct vfsmount *mnt, int flag)
         return;
 }
 
-static void ll_unpin(struct dentry *de, struct vfsmount *mnt, int flag)
+/*static*/ void ll_unpin(struct dentry *de, struct vfsmount *mnt, int flag)
 {
         struct ll_sb_info *sbi = ll_i2sbi(de->d_inode);
         struct ll_dentry_data *ldd = ll_d2d(de);
@@ -346,14 +338,29 @@ static void ll_unpin(struct dentry *de, struct vfsmount *mnt, int flag)
                 return;
         }
 
-        rc = obd_unpin(&sbi->ll_mdc_conn, &handle, flag);
+        rc = obd_unpin(sbi->ll_mdc_exp, &handle, flag);
         EXIT;
         return;
 }
 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+static int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd)
+{
+        int rc;
+        ENTRY;
+
+        if (nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
+                rc = ll_revalidate_it(dentry, nd->flags, &nd->intent);
+        else 
+                rc = ll_revalidate_it(dentry, 0, NULL);
+
+        RETURN(rc);
+}
+#endif
+
 struct dentry_operations ll_d_ops = {
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        .d_revalidate_nd = ll_revalidate_nd,
+        .d_revalidate = ll_revalidate_nd,
 #else
         .d_revalidate_it = ll_revalidate_it,
 #endif
diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c
index a81a7d4d137b3e809bc77f160266e722ee4f97ba..05dfb095f5e1e4d67d1788ef1f046afbafd7bc17 100644
--- a/lustre/llite/dir.c
+++ b/lustre/llite/dir.c
@@ -34,9 +34,9 @@
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include <linux/locks.h>   // for wait_on_buffer
+# include <linux/locks.h>   // for wait_on_buffer
 #else
-#include <linux/buffer_head.h>   // for wait_on_buffer
+# include <linux/buffer_head.h>   // for wait_on_buffer
 #endif
 
 #define DEBUG_SUBSYSTEM S_LLITE
@@ -48,6 +48,7 @@
 #include <linux/lustre_mds.h>
 #include <linux/lustre_lite.h>
 #include <linux/lustre_dlm.h>
+#include "llite_internal.h"
 
 typedef struct ext2_dir_entry_2 ext2_dirent;
 
@@ -59,6 +60,7 @@ static int ll_dir_readpage(struct file *file, struct page *page)
 {
         struct inode *inode = page->mapping->host;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct ll_fid mdc_fid;
         __u64 offset;
         int rc = 0;
         struct ptlrpc_request *request;
@@ -66,10 +68,9 @@ static int ll_dir_readpage(struct file *file, struct page *page)
         struct mds_body *body;
         struct lookup_intent it = { .it_op = IT_READDIR };
         struct mdc_op_data data;
-        struct obd_device *obddev = class_conn2obd(&sbi->ll_mdc_conn);
+        struct obd_device *obddev = class_exp2obd(sbi->ll_mdc_exp);
         struct ldlm_res_id res_id =
                 { .name = {inode->i_ino, (__u64)inode->i_generation} };
-        int flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_MATCH_DATA;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
@@ -85,17 +86,16 @@ static int ll_dir_readpage(struct file *file, struct page *page)
                 GOTO(readpage_out, rc);
         }
 
-        rc = ldlm_lock_match(obddev->obd_namespace, flags, &res_id,
-                             LDLM_PLAIN, NULL, 0, LCK_PR, inode,
-                             &lockh);
+        rc = ldlm_lock_match(obddev->obd_namespace, LDLM_FL_BLOCK_GRANTED,
+                             &res_id, LDLM_PLAIN, NULL, 0, LCK_PR, &lockh);
         if (!rc) {
                 ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0);
 
-                rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_PR,
+                rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_PLAIN, &it, LCK_PR,
                                  &data, &lockh, NULL, 0,
                                  ldlm_completion_ast, ll_mdc_blocking_ast,
                                  inode);
-                request = (struct ptlrpc_request *)it.it_data;
+                request = (struct ptlrpc_request *)it.d.lustre.it_data;
                 if (request)
                         ptlrpc_req_finished(request);
                 if (rc < 0) {
@@ -111,9 +111,11 @@ static int ll_dir_readpage(struct file *file, struct page *page)
                 GOTO(readpage_out, rc);
         }
 
+        mdc_pack_fid(&mdc_fid, inode->i_ino, inode->i_generation, S_IFDIR);
+
         offset = page->index << PAGE_SHIFT;
-        rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino,
-                          S_IFDIR, offset, page, &request);
+        rc = mdc_readpage(sbi->ll_mdc_exp, &mdc_fid,
+                          offset, page, &request);
         if (!rc) {
                 body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
                 LASSERT (body != NULL);         /* checked by mdc_readpage() */
@@ -377,21 +379,23 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
         struct obd_ioctl_data *data;
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%u\n", inode->i_ino,
-               inode->i_generation, inode, cmd);
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), cmd=%#x\n",
+               inode->i_ino, inode->i_generation, inode, cmd);
 
         if (_IOC_TYPE(cmd) == 'T') /* tty ioctls */
                 return -ENOTTY;
 
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_IOCTL);
         switch(cmd) {
+        case EXT3_IOC_GETFLAGS:
+        case EXT3_IOC_SETFLAGS:
+                RETURN( ll_iocontrol(inode, file, cmd, arg) );
         case IOC_MDC_LOOKUP: {
                 struct ptlrpc_request *request = NULL;
                 struct ll_fid fid;
                 char *buf = NULL;
-                struct mds_body *body;
                 char *filename;
-                int namelen, rc, err, len = 0;
+                int namelen, rc, len = 0;
                 unsigned long valid;
 
                 rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
@@ -403,34 +407,21 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 namelen = data->ioc_inllen1;
 
                 if (namelen < 1) {
-                        CERROR("IOC_MDC_LOOKUP missing filename\n");
+                        CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");
                         GOTO(out, rc = -EINVAL);
                 }
 
-                valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE;
+                valid = OBD_MD_FLID;
                 ll_inode2fid(&fid, inode);
-                rc = mdc_getattr_name(&sbi->ll_mdc_conn, &fid,
+                rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid,
                                       filename, namelen, valid, 0, &request);
                 if (rc < 0) {
-                        CERROR("mdc_getattr_name: %d\n", rc);
+                        CDEBUG(D_INFO, "mdc_getattr_name: %d\n", rc);
                         GOTO(out, rc);
                 }
 
-                body = lustre_msg_buf(request->rq_repmsg, 0, sizeof (*body));
-                LASSERT(body != NULL);         /* checked by mdc_getattr_name */
-                LASSERT_REPSWABBED(request, 0);/* swabbed by mdc_getattr_name */
-
-                /* surely there's a better way -phik */
-                data->ioc_obdo1.o_mode = body->mode;
-                data->ioc_obdo1.o_uid = body->uid;
-                data->ioc_obdo1.o_gid = body->gid;
-
                 ptlrpc_req_finished(request);
 
-                err = copy_to_user((void *)arg, buf, len);
-                if (err)
-                        GOTO(out, rc = -EFAULT);
-
                 EXIT;
         out:
                 obd_ioctl_freedata(buf, len);
@@ -443,6 +434,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 struct ptlrpc_request *request = NULL;
                 struct ll_fid fid;
                 struct mds_body *body;
+                struct lov_user_md *lump = (struct lov_user_md *)arg;
                 struct lov_mds_md *lmm;
                 char *filename;
                 int rc, lmmsize;
@@ -452,12 +444,12 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                         RETURN(PTR_ERR(filename));
 
                 ll_inode2fid(&fid, inode);
-                rc = mdc_getattr_name(&sbi->ll_mdc_conn, &fid, filename,
+                rc = mdc_getattr_name(sbi->ll_mdc_exp, &fid, filename,
                                       strlen(filename)+1, OBD_MD_FLEASIZE,
-                                      obd_size_diskmd(&sbi->ll_osc_conn, NULL),
+                                      obd_size_diskmd(sbi->ll_osc_exp, NULL),
                                       &request);
                 if (rc < 0) {
-                        CERROR("mdc_getattr_name: failed on %s: rc %d\n",
+                        CDEBUG(D_INFO, "mdc_getattr_name failed on %s: rc %d\n",
                                filename, rc);
                         GOTO(out_name, rc);
                 }
@@ -478,7 +470,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 LASSERT(lmm != NULL);
                 LASSERT_REPSWABBED(request, 1);
 
-                rc = copy_to_user((struct lov_mds_md *)arg, lmm, lmmsize);
+                rc = copy_to_user(lump, lmm, lmmsize);
                 if (rc)
                         GOTO(out_req, rc = -EFAULT);
 
@@ -489,8 +481,48 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 putname(filename);
                 return rc;
         }
+        case OBD_IOC_PING: {
+                struct ptlrpc_request *req = NULL;
+                char *buf = NULL;
+                int rc, len=0;
+                struct client_obd *cli;
+                struct obd_device *obd;
+                                                                                                                             
+                rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
+                if (rc)
+                        RETURN(rc);
+                data = (void *)buf;
+
+                obd = class_name2obd(data->ioc_inlbuf1);
+                                                                                                                             
+                if (!obd )
+                        GOTO(out_ping, rc = -ENODEV);
+                                                                                                                             
+                if (!obd->obd_attached) {
+                        CERROR("Device %d not attached\n", obd->obd_minor);
+                        GOTO(out_ping, rc = -ENODEV);
+                }
+                if (!obd->obd_set_up) {
+                        CERROR("Device %d still not setup\n", obd->obd_minor);
+                        GOTO(out_ping, rc = -ENODEV);
+                }
+                cli = &obd->u.cli;
+                req = ptlrpc_prep_req(cli->cl_import, OBD_PING, 0, NULL, NULL);
+                if (!req)
+                        GOTO(out_ping, rc = -ENOMEM);
+
+                req->rq_replen = lustre_msg_size(0, NULL);
+                req->rq_send_state = LUSTRE_IMP_FULL;
+
+                rc = ptlrpc_queue_wait(req);
+
+                ptlrpc_req_finished(req);                                                                                                 
+        out_ping:
+                obd_ioctl_freedata(buf, len);
+                return rc;
+        }
         default:
-                return obd_iocontrol(cmd,&sbi->ll_osc_conn,0,NULL,(void *)arg);
+                return obd_iocontrol(cmd, sbi->ll_osc_exp,0,NULL,(void *)arg);
         }
 }
 
diff --git a/lustre/llite/file.c b/lustre/llite/file.c
index 164223bfa3b16d1a494e193e54a0065a993f99d3..8035feee8475cb09d3c0d979bd0316dcf7185ddb 100644
--- a/lustre/llite/file.c
+++ b/lustre/llite/file.c
@@ -28,85 +28,61 @@
 #include <linux/obd_lov.h>      /* for lov_mds_md_size() in lov_setstripe() */
 #include <linux/random.h>
 #include <linux/pagemap.h>
+#include <linux/file.h>
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 #include <linux/lustre_compat25.h>
 #endif
-
 #include "llite_internal.h"
 
-static int ll_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode,
+int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode,
                         struct file *file)
 {
         struct ll_file_data *fd = file->private_data;
         struct ptlrpc_request *req = NULL;
-        unsigned long flags;
-        struct obd_import *imp;
-        int rc;
+        struct obd_client_handle *och = &fd->fd_mds_och;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct obdo obdo;
+        int rc, valid;
         ENTRY;
 
-        /* Complete the open request and remove it from replay list */
-        rc = mdc_close(&ll_i2sbi(inode)->ll_mdc_conn, inode->i_ino,
-                       inode->i_mode, &fd->fd_mds_och.och_fh, &req);
-        if (rc)
-                CERROR("inode %lu close failed: rc = %d\n", inode->i_ino, rc);
-
-        imp = fd->fd_mds_och.och_req->rq_import;
-        LASSERT(imp != NULL);
-        spin_lock_irqsave(&imp->imp_lock, flags);
-
-        DEBUG_REQ(D_HA, fd->fd_mds_och.och_req, "matched open req %p",
-                  fd->fd_mds_och.och_req);
-
-        /* We held on to the request for replay until we saw a close for that
-         * file.  Now that we've closed it, it gets replayed on the basis of
-         * its transno only. */
-        spin_lock (&fd->fd_mds_och.och_req->rq_lock);
-        fd->fd_mds_och.och_req->rq_replay = 0;
-        spin_unlock (&fd->fd_mds_och.och_req->rq_lock);
-
-        if (fd->fd_mds_och.och_req->rq_transno) {
-                /* This open created a file, so it needs replay as a
-                 * normal transaction now.  Our reference to it now
-                 * effectively owned by the imp_replay_list, and it'll
-                 * be committed just like other transno-having
-                 * requests from here on out. */
-
-                /* We now retain this close request, so that it is
-                 * replayed if the open is replayed.  We duplicate the
-                 * transno, so that we get freed at the right time,
-                 * and rely on the difference in xid to keep
-                 * everything ordered correctly.
-                 *
-                 * But! If this close was already given a transno
-                 * (because it caused real unlinking of an
-                 * open-unlinked file, f.e.), then we'll be ordered on
-                 * the basis of that and we don't need to do anything
-                 * magical here. */
-                if (!req->rq_transno) {
-                        req->rq_transno = fd->fd_mds_och.och_req->rq_transno;
-                        ptlrpc_retain_replayable_request(req, imp);
-                }
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-
-                /* Should we free_committed now? we always free before
-                 * replay, so it's probably a wash.  We could check to
-                 * see if the fd_req should already be committed, in
-                 * which case we can avoid the whole retain_replayable
-                 * dance. */
-        } else {
-                /* No transno means that we can just drop our ref. */
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
+        valid = OBD_MD_FLID;
+        if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
+                valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+
+        memset(&obdo, 0, sizeof(obdo));
+        obdo.o_id = inode->i_ino;
+        obdo.o_mode = inode->i_mode;
+        obdo.o_size = inode->i_size;
+        obdo.o_blocks = inode->i_blocks;
+        if (0 /* ll_is_inode_dirty(inode) */) {
+                obdo.o_flags = MDS_BFLAG_UNCOMMITTED_WRITES;
+                valid |= OBD_MD_FLFLAGS;
+        }
+        obdo.o_valid = valid;
+        rc = mdc_close(mdc_exp, &obdo, och, &req);
+        if (rc == EAGAIN) {
+                /* We are the last writer, so the MDS has instructed us to get
+                 * the file size and any write cookies, then close again. */
+                //ll_queue_done_writing(inode);
+                rc = 0;
+        } else if (rc) {
+                CERROR("inode %lu mdc close failed: rc = %d\n",
+                       inode->i_ino, rc);
+        }
+        if (rc == 0) {
+                rc = ll_objects_destroy(req, file->f_dentry->d_inode);
+                if (rc)
+                        CERROR("inode %lu ll_objects destroy: rc = %d\n",
+                               inode->i_ino, rc);
         }
-        ptlrpc_req_finished(fd->fd_mds_och.och_req);
 
-        /* Do this after the fd_req->rq_transno check, because we don't want
-         * to bounce off zero references. */
+        mdc_clear_open_replay_data(och);
         ptlrpc_req_finished(req);
-        fd->fd_mds_och.och_fh.cookie = DEAD_HANDLE_MAGIC;
+        och->och_fh.cookie = DEAD_HANDLE_MAGIC;
         file->private_data = NULL;
         OBD_SLAB_FREE(fd, ll_file_data_slab, sizeof *fd);
 
-        RETURN(-abs(rc));
+        RETURN(rc);
 }
 
 /* While this returns an error code, fput() the caller does not, so we need
@@ -117,11 +93,8 @@ static int ll_mdc_close(struct lustre_handle *mdc_conn, struct inode *inode,
 int ll_file_release(struct inode *inode, struct file *file)
 {
         struct ll_file_data *fd;
-        struct obdo oa;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct ll_inode_info *lli = ll_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        int rc = 0, rc2;
+        int rc;
 
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
@@ -131,36 +104,42 @@ int ll_file_release(struct inode *inode, struct file *file)
         if (inode->i_sb->s_root == file->f_dentry)
                 RETURN(0);
 
-        lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_RELEASE);
+        lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
         fd = (struct ll_file_data *)file->private_data;
-        if (!fd) /* no process opened the file after an mcreate */
-                RETURN(0);
+        LASSERT(fd != NULL);
 
-        /* we might not be able to get a valid handle on this file
-         * again so we really want to flush our write cache.. */
-        if (S_ISREG(inode->i_mode) && lsm) {
-                write_inode_now(inode, 0);
-                obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
-                                            OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-                memcpy(obdo_handle(&oa), &fd->fd_ost_och, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
+        rc = ll_mdc_close(sbi->ll_mdc_exp, inode, file);
+        RETURN(rc);
+}
 
-                rc = obd_close(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                if (rc)
-                        CERROR("inode %lu object close failed: rc %d\n",
-                               inode->i_ino, rc);
-        }
+static int ll_intent_file_open(struct file *file, void *lmm,
+                               int lmmsize, struct lookup_intent *itp)
+{
+        struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode);
+        struct lustre_handle lockh;
+        struct mdc_op_data data;
+        struct dentry *parent = file->f_dentry->d_parent;
+        const char *name = file->f_dentry->d_name.name;
+        const int len = file->f_dentry->d_name.len;
+        int rc;
 
-        rc2 = ll_mdc_close(&sbi->ll_mdc_conn, inode, file);
-        if (rc2 && !rc)
-                rc = rc2;
+        if (!parent)
+                RETURN(-ENOENT);
 
+        ll_prepare_mdc_op_data(&data, parent->d_inode, NULL, name, len, O_RDWR);
+
+        rc = mdc_enqueue(sbi->ll_mdc_exp, LDLM_PLAIN, itp, LCK_PR, &data,
+                         &lockh, lmm, lmmsize, ldlm_completion_ast,
+                         ll_mdc_blocking_ast, parent->d_inode);
+        if (rc < 0)
+                CERROR("lock enqueue: err: %d\n", rc);
         RETURN(rc);
 }
 
-static int ll_local_open(struct file *file, struct lookup_intent *it)
+int ll_local_open(struct file *file, struct lookup_intent *it)
 {
-        struct ptlrpc_request *req = it->it_data;
+        struct ptlrpc_request *req = it->d.lustre.it_data;
+        struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode);
         struct ll_file_data *fd;
         struct mds_body *body;
         ENTRY;
@@ -176,156 +155,15 @@ static int ll_local_open(struct file *file, struct lookup_intent *it)
          * ll_mdc_close, so don't even try right now. */
         LASSERT(fd != NULL);
 
-        memset(fd, 0, sizeof(*fd));
-
         memcpy(&fd->fd_mds_och.och_fh, &body->handle, sizeof(body->handle));
-        fd->fd_mds_och.och_req = it->it_data;
+        fd->fd_mds_och.och_magic = OBD_CLIENT_HANDLE_MAGIC;
         file->private_data = fd;
 
-        RETURN(0);
-}
-
-static int ll_osc_open(struct lustre_handle *conn, struct inode *inode,
-                       struct file *file, struct lov_stripe_md *lsm)
-{
-        struct ll_file_data *fd = file->private_data;
-        struct obdo *oa;
-        int rc;
-        ENTRY;
-
-        oa = obdo_alloc();
-        if (!oa)
-                RETURN(-ENOMEM);
-        oa->o_id = lsm->lsm_object_id;
-        oa->o_mode = S_IFREG;
-        oa->o_valid = OBD_MD_FLID;
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
-        rc = obd_open(conn, oa, lsm, NULL, &fd->fd_ost_och);
-        if (rc)
-                GOTO(out, rc);
-
-        file->f_flags &= ~O_LOV_DELAY_CREATE;
-        obdo_refresh_inode(inode, oa, (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
-                                       OBD_MD_FLATIME | OBD_MD_FLMTIME |
-                                       OBD_MD_FLCTIME));
-        EXIT;
-out:
-        obdo_free(oa);
-        return rc;
-}
-
-/* Caller must hold lli_open_sem to protect lli->lli_smd from changing and
- * duplicate objects from being created.  We only install lsm to lli_smd if
- * the mdc open was successful (hence stored stripe MD on MDS), otherwise
- * other nodes could try to create different objects for the same file.
- */
-static int ll_create_obj(struct lustre_handle *conn, struct inode *inode,
-                         struct file *file, struct lov_stripe_md *lsm)
-{
-        struct ptlrpc_request *req = NULL;
-        struct ll_inode_info *lli = ll_i2info(inode);
-        struct lov_mds_md *lmm = NULL;
-        struct obdo *oa;
-        struct iattr iattr;
-        struct mdc_op_data op_data;
-        struct obd_trans_info oti = { 0 };
-        int rc, err, lmm_size = 0;
-        ENTRY;
-
-        oa = obdo_alloc();
-        if (!oa)
-                RETURN(-ENOMEM);
-
-        LASSERT(S_ISREG(inode->i_mode));
-        oa->o_mode = S_IFREG | 0600;
-        oa->o_id = inode->i_ino;
-        oa->o_generation = inode->i_generation;
-        /* Keep these 0 for now, because chown/chgrp does not change the
-         * ownership on the OST, and we don't want to allow BA OST NFS
-         * users to access these objects by mistake. */
-        oa->o_uid = 0;
-        oa->o_gid = 0;
-        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGENER | OBD_MD_FLTYPE |
-                OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID;
-#ifdef ENABLE_ORPHANS
-        oa->o_valid |= OBD_MD_FLCOOKIE;
-#endif
-
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE|OBD_MD_FLATIME|OBD_MD_FLMTIME|
-                        OBD_MD_FLCTIME | (inode->i_size ? OBD_MD_FLSIZE : 0));
-
-        rc = obd_create(conn, oa, &lsm, &oti);
-        if (rc) {
-                CERROR("error creating objects for inode %lu: rc = %d\n",
-                       inode->i_ino, rc);
-                if (rc > 0) {
-                        CERROR("obd_create returned invalid rc %d\n", rc);
-                        rc = -EIO;
-                }
-                GOTO(out_oa, rc);
-        }
-        obdo_refresh_inode(inode, oa, OBD_MD_FLBLKSZ);
-
-        LASSERT(lsm && lsm->lsm_object_id);
-        rc = obd_packmd(conn, &lmm, lsm);
-        if (rc < 0)
-                GOTO(out_destroy, rc);
-
-        lmm_size = rc;
-
-        /* Save the stripe MD with this file on the MDS */
-        memset(&iattr, 0, sizeof(iattr));
-        iattr.ia_valid = ATTR_FROM_OPEN;
-
-        ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
-
-#if 0
-#warning FIXME: next line is for debugging purposes only
-        obd_log_cancel(&ll_i2sbi(inode)->ll_osc_conn, lsm, oti.oti_numcookies,
-                       oti.oti_logcookies, OBD_LLOG_FL_SENDNOW);
-#endif
-
-        rc = mdc_setattr(&ll_i2sbi(inode)->ll_mdc_conn, &op_data, &iattr,
-                         lmm, lmm_size, oti.oti_logcookies,
-                         oti.oti_numcookies * sizeof(oti.oti_onecookie), &req);
-        ptlrpc_req_finished(req);
-
-        obd_free_diskmd(conn, &lmm);
-
-        /* If we couldn't complete mdc_open() and store the stripe MD on the
-         * MDS, we need to destroy the objects now or they will be leaked.
-         */
-        if (rc) {
-                CERROR("error: storing stripe MD for %lu: rc %d\n",
-                       inode->i_ino, rc);
-                GOTO(out_destroy, rc);
-        }
-        lli->lli_smd = lsm;
-        lli->lli_maxbytes = lsm->lsm_maxbytes;
+        lli->lli_io_epoch = body->io_epoch;
 
-        EXIT;
-out_oa:
-        oti_free_cookies(&oti);
-        obdo_free(oa);
-        return rc;
+        mdc_set_open_replay_data(&fd->fd_mds_och, it->d.lustre.it_data);
 
-out_destroy:
-        oa->o_id = lsm->lsm_object_id;
-        oa->o_valid = OBD_MD_FLID;
-        obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
-#if 0
-        err = obd_log_cancel(conn, lsm, oti.oti_numcookies, oti.oti_logcookies,
-                             OBD_LLOG_FL_SENDNOW);
-        if (err)
-                CERROR("error cancelling inode %lu log cookies: rc %d\n",
-                       inode->i_ino, err);
-#endif
-        err = obd_destroy(conn, oa, lsm, NULL);
-        obd_free_memmd(conn, &lsm);
-        if (err)
-                CERROR("error uncreating inode %lu objects: rc %d\n",
-                       inode->i_ino, err);
-        goto out_oa;
+        RETURN(0);
 }
 
 /* Open a file, and (for the very first open) create objects on the OSTs at
@@ -345,11 +183,10 @@ out_destroy:
  */
 int ll_file_open(struct inode *inode, struct file *file)
 {
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct ll_inode_info *lli = ll_i2info(inode);
-        struct lustre_handle *conn = ll_i2obdconn(inode);
         struct lookup_intent *it;
         struct lov_stripe_md *lsm;
+        struct ptlrpc_request *req;
         int rc = 0;
         ENTRY;
 
@@ -361,135 +198,78 @@ int ll_file_open(struct inode *inode, struct file *file)
                 RETURN(0);
 
         it = file->f_it;
-        lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
 
-        rc = ll_it_open_error(DISP_OPEN_OPEN, it);
+        if (!it->d.lustre.it_disposition) {
+                struct lookup_intent oit = { .it_op = IT_OPEN,
+                                             .it_flags = file->f_flags };
+                it = &oit;
+                rc = ll_intent_file_open(file, NULL, 0, it);
+                if (rc)
+                        GOTO(out, rc);
+        }
+
+        lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
+        rc = it_open_error(DISP_OPEN_OPEN, it);
         if (rc)
-                RETURN(rc);
+                GOTO(out, rc);
 
         rc = ll_local_open(file, it);
         if (rc)
                 LBUG();
 
-        mdc_set_open_replay_data(&((struct ll_file_data *)
-                                   file->private_data)->fd_mds_och);
         if (!S_ISREG(inode->i_mode))
-                RETURN(0);
+                GOTO(out, rc);
 
         lsm = lli->lli_smd;
         if (lsm == NULL) {
                 if (file->f_flags & O_LOV_DELAY_CREATE ||
                     !(file->f_mode & FMODE_WRITE)) {
-                        CDEBUG(D_INODE, "delaying object creation\n");
-                        RETURN(0);
-                }
-                down(&lli->lli_open_sem);
-                if (!lli->lli_smd) {
-                        rc = ll_create_obj(conn, inode, file, NULL);
-                        up(&lli->lli_open_sem);
-                        if (rc)
-                                GOTO(out_close, rc);
-                } else {
-                        CERROR("warning: stripe already set on ino %lu\n",
-                               inode->i_ino);
-                        up(&lli->lli_open_sem);
+                        CDEBUG(D_INODE, "object creation was delayed\n");
+                        GOTO(out, rc);
                 }
-                lsm = lli->lli_smd;
         }
-
-        rc = ll_osc_open(conn, inode, file, lsm);
-        if (rc)
-                GOTO(out_close, rc);
-        RETURN(0);
-
- out_close:
-        ll_mdc_close(&sbi->ll_mdc_conn, inode, file);
+        file->f_flags &= ~O_LOV_DELAY_CREATE;
+        GOTO(out, rc);
+ out:
+        req = it->d.lustre.it_data;
+        ptlrpc_req_finished(req);
+        if (rc == 0)
+                ll_open_complete(inode);
         return rc;
 }
 
-/*
- * really does the getattr on the inode and updates its fields
- */
-int ll_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm,
-                     void *ostdata)
+/* Fills the obdo with the attributes for the inode defined by lsm */
+int ll_lsm_getattr(struct obd_export *exp, struct lov_stripe_md *lsm,
+                   struct obdo *oa)
 {
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct ll_inode_info *lli = ll_i2info(inode);
         struct ptlrpc_request_set *set;
-        struct obdo oa;
-        int bef, aft;
-        unsigned long before, after;
         int rc;
         ENTRY;
 
-        LASSERT(lsm);
-        LASSERT(sbi);
-        LASSERT(lli);
+        LASSERT(lsm != NULL);
 
-        memset(&oa, 0, sizeof oa);
-        oa.o_id = lsm->lsm_object_id;
-        oa.o_mode = S_IFREG;
-        oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
+        memset(oa, 0, sizeof *oa);
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_mode = S_IFREG;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE |
                 OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME |
                 OBD_MD_FLCTIME;
 
-        if (ostdata != NULL) {
-                memcpy(obdo_handle(&oa), ostdata, FD_OSTDATA_SIZE);
-                oa.o_valid |= OBD_MD_FLHANDLE;
-        }
-
-        /* getattr can race with writeback.  we don't want to trust a getattr
-         * that doesn't include the writeback of our farthest cached pages
-         * that it raced with. */
-        /* Now that the OSC knows the cached-page status, it can and should be
-         * adjusting its getattr results to include the maximum cached offset
-         * for its stripe(s). */
-        do {
-                bef = obd_last_dirty_offset(ll_i2obdconn(inode), lli->lli_smd,
-                                            &before);
-#if 0
-                rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm);
-#else
-                set = ptlrpc_prep_set ();
-                if (set == NULL) {
-                        CERROR ("ENOMEM allocing request set\n");
-                        rc = -ENOMEM;
-                } else {
-                        rc = obd_getattr_async(&sbi->ll_osc_conn, &oa, lsm, set);
-                        if (rc == 0)
-                                rc = ptlrpc_set_wait (set);
-                        ptlrpc_set_destroy (set);
-                }
-#endif
-                if (rc)
-                        RETURN(rc);
-
-                aft = obd_last_dirty_offset(ll_i2obdconn(inode), lli->lli_smd,
-                                            &after);
-                CDEBUG(D_INODE, " %d,%lu -> %d,%lu\n", bef, before, aft, after);
-        } while (bef == 0 &&
-                 (aft != 0 || after < before) &&
-                 oa.o_size < ((u64)before + 1) << PAGE_CACHE_SHIFT);
-
-        obdo_refresh_inode(inode, &oa, (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ |
-                                        OBD_MD_FLMTIME | OBD_MD_FLCTIME));
-        if (inode->i_blksize < PAGE_CACHE_SIZE)
-                inode->i_blksize = PAGE_CACHE_SIZE;
-
-        /* make sure getattr doesn't return a size that causes writeback
-         * to forget about cached writes */
-        if ((aft == 0) && oa.o_size < ((u64)after + 1) << PAGE_CACHE_SHIFT) {
-                CDEBUG(D_INODE, "cached at %lu, keeping %llu i_size instead "
-                                "of oa "LPU64"\n", after, inode->i_size,
-                                oa.o_size);
-                RETURN(0);
+        set = ptlrpc_prep_set();
+        if (set == NULL) {
+                CERROR ("ENOMEM allocing request set\n");
+                rc = -ENOMEM;
+        } else {
+                rc = obd_getattr_async(exp, oa, lsm, set);
+                if (rc == 0)
+                        rc = ptlrpc_set_wait(set);
+                ptlrpc_set_destroy(set);
         }
+        if (rc)
+                RETURN(rc);
 
-        obdo_to_inode(inode, &oa, OBD_MD_FLSIZE);
-
-        CDEBUG(D_INODE, "objid "LPX64" size %Lu/%Lu blksize %lu\n",
-               lsm->lsm_object_id, inode->i_size, inode->i_size,
-               inode->i_blksize);
+        oa->o_valid &= (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME | 
+                        OBD_MD_FLCTIME | OBD_MD_FLSIZE);
         RETURN(0);
 }
 
@@ -508,165 +288,103 @@ static inline void ll_remove_suid(struct inode *inode)
         }
 }
 
-#if 0
-static void ll_update_atime(struct inode *inode)
-{
-        if (IS_RDONLY(inode)) return;
-
-        /* update atime, but don't explicitly write it out just this change */
-        inode->i_atime = CURRENT_TIME;
-}
-#endif
-
-/*
- * flush the page cache for an extent as its canceled.  when we're on an
- * lov we get a lock cancelation for each of the obd locks under the lov
- * so we have to map the obd's region back onto the stripes in the file
- * that it held.
- *
- * no one can dirty the extent until we've finished our work and they
- * can enqueue another lock.
- *
- * XXX this could be asking the inode's dirty tree for info
- */
+/* Flush the page cache for an extent as its canceled.  No one can dirty the
+ * extent until we've finished our work and they can enqueue another lock.
+ * The DLM protects us from ll_file_read/write here, but other kernel actors
+ * could have pages locked */
 void ll_pgcache_remove_extent(struct inode *inode, struct lov_stripe_md *lsm,
                               struct ldlm_lock *lock)
 {
-        struct ldlm_extent *extent = &lock->l_extent;
-        unsigned long start, end, count, skip, i, j;
+        struct ldlm_extent *extent = &lock->l_policy_data.l_extent;
+        struct obd_export *exp = ll_i2obdexp(inode);
+        struct ll_inode_info *lli = ll_i2info(inode);
+        unsigned long start, end, i;
         struct page *page;
-        int ret;
+        int rc, discard = lock->l_flags & LDLM_FL_DISCARD_DATA;
         ENTRY;
 
         CDEBUG(D_INODE, "obdo %lu inode %p ["LPU64"->"LPU64"] size: %llu\n",
                inode->i_ino, inode, extent->start, extent->end, inode->i_size);
 
         start = extent->start >> PAGE_CACHE_SHIFT;
-        count = ~0;
-        skip = 0;
         end = (extent->end >> PAGE_CACHE_SHIFT) + 1;
         if ((end << PAGE_CACHE_SHIFT) < extent->end)
                 end = ~0;
-        if (lsm->lsm_stripe_count > 1) {
-                struct {
-                        char name[16];
-                        struct ldlm_lock *lock;
-                        struct lov_stripe_md *lsm;
-                } key = { .name = "lock_to_stripe", .lock = lock, .lsm = lsm };
-                __u32 stripe;
-                __u32 vallen = sizeof(stripe);
-                int rc;
-
-                /* get our offset in the lov */
-                rc = obd_get_info(ll_i2obdconn(inode), sizeof(key),
-                                  &key, &vallen, &stripe);
-                if (rc != 0) {
-                        CERROR("obd_get_info: rc = %d\n", rc);
-                        LBUG();
-                }
-                LASSERT(stripe < lsm->lsm_stripe_count);
-
-                count = lsm->lsm_stripe_size >> PAGE_CACHE_SHIFT;
-                skip = (lsm->lsm_stripe_count - 1) * count;
-                start += (start/count * skip) + (stripe * count);
-                if (end != ~0)
-                        end += (end/count * skip) + (stripe * count);
-        }
 
         i = (inode->i_size + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
         if (end >= i)
-                clear_bit(LLI_F_HAVE_SIZE_LOCK, &(ll_i2info(inode)->lli_flags));
+                clear_bit(LLI_F_HAVE_OST_SIZE_LOCK,
+                          &(ll_i2info(inode)->lli_flags));
         if (i < end)
                 end = i;
 
-        CDEBUG(D_INODE, "start: %lu j: %lu count: %lu skip: %lu end: %lu\n",
-               start, start % count, count, skip, end);
+        CDEBUG(D_INODE, "walking page indices start: %lu end: %lu\n", start,
+               end);
 
-        /* start writeback on dirty pages in the extent when its PW */
-        for (i = start, j = start % count;
-             lock->l_granted_mode == LCK_PW && i < end; j++, i++) {
-                if (j == count) {
-                        i += skip;
-                        j = 0;
-                }
-                /* its unlikely, but give us a chance to bail when we're out */
+        for (i = start; i < end; i++) {
                 ll_pgcache_lock(inode->i_mapping);
-                if (list_empty(&inode->i_mapping->dirty_pages)) {
-                        CDEBUG(D_INODE, "dirty list empty\n");
+                if (list_empty(&inode->i_mapping->dirty_pages) &&
+                     list_empty(&inode->i_mapping->clean_pages) &&
+                     list_empty(&inode->i_mapping->locked_pages)) {
+                        CDEBUG(D_INODE, "nothing left\n");
                         ll_pgcache_unlock(inode->i_mapping);
                         break;
                 }
                 ll_pgcache_unlock(inode->i_mapping);
 
-                if (need_resched())
-                        schedule();
+                conditional_schedule();
 
                 page = find_get_page(inode->i_mapping, i);
                 if (page == NULL)
                         continue;
-                if (!PageDirty(page) || TryLockPage(page)) {
-                        page_cache_release(page);
-                        continue;
-                }
-                if (PageDirty(page)) {
-                        CDEBUG(D_INODE, "writing page %p\n", page);
+
+                LL_CDEBUG_PAGE(page, "locking\n");
+                lock_page(page);
+
+                /* page->mapping to check with racing against teardown */
+                if (page->mapping && PageDirty(page) && !discard) {
+                        ClearPageDirty(page);
+                        LL_CDEBUG_PAGE(page, "found dirty\n");
                         ll_pgcache_lock(inode->i_mapping);
                         list_del(&page->list);
                         list_add(&page->list, &inode->i_mapping->locked_pages);
                         ll_pgcache_unlock(inode->i_mapping);
 
-                        /* this writepage might write out pages outside
-                         * this extent, but that's ok, the pages are only
-                         * still dirty because a lock still covers them */
-                        ClearPageDirty(page);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                        ret = inode->i_mapping->a_ops->writepage(page);
+                        rc = inode->i_mapping->a_ops->writepage(page);
 #else
-                        ret = inode->i_mapping->a_ops->writepage(page, NULL);
+                        rc = inode->i_mapping->a_ops->writepage(page, NULL);
 #endif
-                        if (ret != 0)
-                                unlock_page(page);
-                } else {
-                        unlock_page(page);
+                        if (rc != 0) {
+                                CERROR("writepage of page %p failed: %d\n",
+                                       page, rc);
+                        } else {
+                                lock_page(page); /* wait for io to complete */
+                        }
                 }
-                page_cache_release(page);
-
-        }
 
-        /* our locks are page granular thanks to osc_enqueue, we invalidate the
-         * whole page. */
-        LASSERT((extent->start & ~PAGE_CACHE_MASK) == 0);
-        LASSERT(((extent->end+1) & ~PAGE_CACHE_MASK) == 0);
-        for (i = start, j = start % count ; i < end ; j++, i++) {
-                if (j == count) {
-                        i += skip;
-                        j = 0;
-                }
-                ll_pgcache_lock(inode->i_mapping);
-                if (list_empty(&inode->i_mapping->dirty_pages) &&
-                     list_empty(&inode->i_mapping->clean_pages) &&
-                     list_empty(&inode->i_mapping->locked_pages)) {
-                        CDEBUG(D_INODE, "nothing left\n");
-                        ll_pgcache_unlock(inode->i_mapping);
-                        break;
-                }
-                ll_pgcache_unlock(inode->i_mapping);
-                if (need_resched())
-                        schedule();
-                page = find_get_page(inode->i_mapping, i);
-                if (page == NULL)
-                        continue;
-                CDEBUG(D_INODE, "dropping page %p at %lu\n", page, page->index);
-                lock_page(page);
-                if (page->mapping) /* might have raced */
+                /* checking again to account for writeback's lock_page() */
+                if (page->mapping != NULL) {
+                        LL_CDEBUG_PAGE(page, "truncating\n");
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
                         truncate_complete_page(page);
 #else
                         truncate_complete_page(page->mapping, page);
 #endif
+                }
                 unlock_page(page);
                 page_cache_release(page);
         }
+
+        if (test_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags)) {
+                rc = obd_lock_contains(exp, lsm, lock, inode->i_size - 1);
+                if (rc != 0) {
+                        if (rc < 0)
+                                CERROR("obd_lock_contains: rc = %d\n", rc);
+                        clear_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags);
+                }
+        }
+
         EXIT;
 }
 
@@ -674,13 +392,12 @@ static int ll_extent_lock_callback(struct ldlm_lock *lock,
                                    struct ldlm_lock_desc *new, void *data,
                                    int flag)
 {
-        struct inode *inode = data;
-        struct ll_inode_info *lli = ll_i2info(inode);
         struct lustre_handle lockh = { 0 };
         int rc;
         ENTRY;
 
-        if ((unsigned long)inode < 0x1000) {
+
+        if ((unsigned long)data > 0 && (unsigned long)data < 0x1000) {
                 LDLM_ERROR(lock, "cancelling lock with bad data %p", data);
                 LBUG();
         }
@@ -692,22 +409,23 @@ static int ll_extent_lock_callback(struct ldlm_lock *lock,
                 if (rc != ELDLM_OK)
                         CERROR("ldlm_cli_cancel failed: %d\n", rc);
                 break;
-        case LDLM_CB_CANCELING:
-                /* FIXME: we could be given 'canceling intents' so that we
-                 * could know to write-back or simply throw away the pages
-                 * based on if the cancel comes from a desire to, say,
-                 * read or truncate.. */
-                if ((unsigned long)lli->lli_smd < 0x1000) {
-                        /* note that lli is part of the inode itself, so it
-                         * is valid if as checked the inode pointer above. */
-                        CERROR("inode %lu, sb %p, lli %p, lli_smd %p\n",
-                               inode->i_ino, inode->i_sb, lli, lli->lli_smd);
-                        LDLM_ERROR(lock, "cancel lock on bad inode %p", inode);
-                        LBUG();
-                }
+        case LDLM_CB_CANCELING: {
+                struct inode *inode = ll_inode_from_lock(lock);
+                struct ll_inode_info *lli;
+
+                if (!inode)
+                        RETURN(0);
+                lli= ll_i2info(inode);
+                if (!lli)
+                        RETURN(0);
+                if (!lli->lli_smd)
+                        RETURN(0);
 
                 ll_pgcache_remove_extent(inode, lli->lli_smd, lock);
+                //ll_try_done_writing(inode);
+                iput(inode);
                 break;
+        }
         default:
                 LBUG();
         }
@@ -723,10 +441,10 @@ static int ll_extent_lock_callback(struct ldlm_lock *lock,
 int ll_extent_lock_no_validate(struct ll_file_data *fd, struct inode *inode,
                    struct lov_stripe_md *lsm,
                    int mode, struct ldlm_extent *extent,
-                   struct lustre_handle *lockh)
+                   struct lustre_handle *lockh, int ast_flags)
 {
         struct ll_sb_info *sbi = ll_i2sbi(inode);
-        int rc, flags = 0;
+        int rc;
         ENTRY;
 
         LASSERT(lockh->cookie == 0);
@@ -739,10 +457,11 @@ int ll_extent_lock_no_validate(struct ll_file_data *fd, struct inode *inode,
         CDEBUG(D_DLMTRACE, "Locking inode %lu, start "LPU64" end "LPU64"\n",
                inode->i_ino, extent->start, extent->end);
 
-        rc = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, extent,
-                         sizeof(extent), mode, &flags, ll_extent_lock_callback,
-                         inode, lockh);
-
+        rc = obd_enqueue(sbi->ll_osc_exp, lsm, NULL, LDLM_EXTENT, extent,
+                         sizeof(extent), mode, &ast_flags,
+                         ll_extent_lock_callback, inode, lockh);
+        if (rc > 0)
+                rc = -EIO;
         RETURN(rc);
 }
 
@@ -755,47 +474,73 @@ int ll_extent_lock(struct ll_file_data *fd, struct inode *inode,
                    struct ldlm_extent *extent, struct lustre_handle *lockh)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
+        struct obd_export *exp = ll_i2obdexp(inode);
         struct ldlm_extent size_lock;
         struct lustre_handle match_lockh = {0};
+        struct obdo oa;
+        obd_flag refresh_valid;
         int flags, rc, matched;
         ENTRY;
 
-        rc = ll_extent_lock_no_validate(fd, inode, lsm, mode, extent, lockh);
+        rc = ll_extent_lock_no_validate(fd, inode, lsm, mode, extent, lockh, 0);
         if (rc != ELDLM_OK)
                 RETURN(rc);
 
-        if (test_bit(LLI_F_HAVE_SIZE_LOCK, &lli->lli_flags))
+        if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
                 RETURN(0);
 
-        rc = ll_inode_getattr(inode, lsm, fd ? &fd->fd_ost_och : NULL);
+        rc = ll_lsm_getattr(exp, lsm, &oa);
         if (rc) {
                 ll_extent_unlock(fd, inode, lsm, mode, lockh);
                 RETURN(rc);
         }
 
+        /* We set this flag in commit write as we extend the file size.  When
+         * the bit is set and the lock is canceled that covers the file size,
+         * we clear the bit.  This is enough to protect the window where our
+         * local size extension is needed for writeback.  However, it relies on
+         * behaviour that won't be true in the near future.  This assumes that
+         * all getattr callers get extent locks, which they currnetly do.  It
+         * also assumes that we only send discarding asts for {0,eof} truncates
+         * as is currently the case.  This will have to be replaced by the
+         * proper eoc communication between clients and the ost, which is on
+         * its way. */
+        refresh_valid = (OBD_MD_FLBLOCKS | OBD_MD_FLBLKSZ | OBD_MD_FLMTIME | 
+                         OBD_MD_FLCTIME | OBD_MD_FLSIZE);
+        if (test_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags)) {
+                if (oa.o_size < inode->i_size)
+                        refresh_valid &= ~OBD_MD_FLSIZE;
+                else 
+                        clear_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags);
+        }
+        obdo_refresh_inode(inode, &oa, refresh_valid);
+
+        CDEBUG(D_INODE, "objid "LPX64" size %Lu, blocks %lu, blksize %lu\n",
+               lsm->lsm_object_id, inode->i_size, inode->i_blocks,
+               inode->i_blksize);
+
         size_lock.start = inode->i_size;
         size_lock.end = OBD_OBJECT_EOF;
 
         /* XXX I bet we should be checking the lock ignore flags.. */
-        flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED | LDLM_FL_MATCH_DATA;
-        matched = obd_match(&ll_i2sbi(inode)->ll_osc_conn, lsm, LDLM_EXTENT,
-                            &size_lock, sizeof(size_lock), LCK_PR, &flags,
-                            inode, &match_lockh);
+        flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED;
+        matched = obd_match(exp, lsm, LDLM_EXTENT, &size_lock,
+                            sizeof(size_lock), LCK_PR, &flags, inode,
+                            &match_lockh);
 
         /* hey, alright, we hold a size lock that covers the size we
          * just found, its not going to change for a while.. */
         if (matched == 1) {
-                set_bit(LLI_F_HAVE_SIZE_LOCK, &lli->lli_flags);
-                obd_cancel(&ll_i2sbi(inode)->ll_osc_conn, lsm, LCK_PR,
-                           &match_lockh);
+                set_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags);
+                obd_cancel(exp, lsm, LCK_PR, &match_lockh);
         }
 
         RETURN(0);
 }
 
 int ll_extent_unlock(struct ll_file_data *fd, struct inode *inode,
-                struct lov_stripe_md *lsm, int mode,
-                struct lustre_handle *lockh)
+                     struct lov_stripe_md *lsm, int mode,
+                     struct lustre_handle *lockh)
 {
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         int rc;
@@ -806,7 +551,7 @@ int ll_extent_unlock(struct ll_file_data *fd, struct inode *inode,
             (sbi->ll_flags & LL_SBI_NOLCK))
                 RETURN(0);
 
-        rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockh);
+        rc = obd_cancel(sbi->ll_osc_exp, lsm, mode, lockh);
 
         RETURN(rc);
 }
@@ -819,7 +564,7 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count,
         struct ll_inode_info *lli = ll_i2info(inode);
         struct lov_stripe_md *lsm = lli->lli_smd;
         struct lustre_handle lockh = { 0 };
-        struct ll_read_extent rextent;
+        struct ldlm_extent extent;
         ldlm_error_t err;
         ssize_t retval;
         ENTRY;
@@ -841,27 +586,22 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count,
          * so we can see them at the getattr after lock acquisition.  this will
          * turn into a seperate [*ppos + count, EOF] 'size intent' lock attempt
          * in the future. */
-        rextent.re_extent.start = *ppos;
-        rextent.re_extent.end = OBD_OBJECT_EOF;
+        extent.start = *ppos;
+        extent.end = OBD_OBJECT_EOF;
 
-        err = ll_extent_lock(fd, inode, lsm, LCK_PR, &rextent.re_extent,&lockh);
+        err = ll_extent_lock(fd, inode, lsm, LCK_PR, &extent, &lockh);
         if (err != ELDLM_OK)
-                RETURN(-ENOLCK);
-
-        /* XXX tell ll_readpage what pages have a PR lock.. */
-        rextent.re_task = current;
-        spin_lock(&lli->lli_read_extent_lock);
-        list_add(&rextent.re_lli_item, &lli->lli_read_extents);
-        spin_unlock(&lli->lli_read_extent_lock);
+                RETURN(err);
 
         CDEBUG(D_INFO, "Reading inode %lu, "LPSZ" bytes, offset %Ld\n",
                inode->i_ino, count, *ppos);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+        filp->f_ramax = 0; /* turn off generic_file_readahead() */
+#else
+        filp->f_ra.ra_pages = 0;
+#endif
         retval = generic_file_read(filp, buf, count, ppos);
 
-        spin_lock(&lli->lli_read_extent_lock);
-        list_del(&rextent.re_lli_item);
-        spin_unlock(&lli->lli_read_extent_lock);
-
         /* XXX errors? */
         ll_extent_unlock(fd, inode, lsm, LCK_PR, &lockh);
         RETURN(retval);
@@ -887,14 +627,6 @@ static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
                inode->i_ino, inode->i_generation, inode, count, *ppos);
 
         SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
-        /*
-         * sleep doing some writeback work of this mount's dirty data
-         * if the VM thinks we're low on memory.. other dirtying code
-         * paths should think about doing this, too, but they should be
-         * careful not to hold locked pages while they do so.  like
-         * ll_prepare_write.  *cough*
-         */
-        ll_check_dirty(inode->i_sb);
 
         /* POSIX, but surprised the VFS doesn't check this already */
         if (count == 0)
@@ -919,9 +651,9 @@ static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
                 err = ll_extent_lock(fd, inode, lsm, LCK_PW, &extent, &lockh);
         else
                 err = ll_extent_lock_no_validate(fd, inode, lsm, LCK_PW,
-                                                 &extent, &lockh);
+                                                 &extent, &lockh, 0);
         if (err != ELDLM_OK)
-                RETURN(-ENOLCK);
+                RETURN(err);
 
         /* this is ok, g_f_w will overwrite this under i_sem if it races
          * with a local truncate, it just makes our maxbyte checking easier */
@@ -955,66 +687,94 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
                             unsigned long arg)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
-        struct lustre_handle *conn = ll_i2obdconn(inode);
+        struct file *f;
+        struct obd_export *exp = ll_i2obdexp(inode);
         struct lov_stripe_md *lsm;
+        struct lookup_intent oit = {.it_op = IT_OPEN, .it_flags = FMODE_WRITE};
+        struct lov_user_md lum, *lump = (struct lov_user_md *)arg;
+        struct ptlrpc_request *req = NULL;
+        struct lustre_md md;
         int rc;
         ENTRY;
 
+        /* Bug 1152: copy properly when this is no longer true */
+        LASSERT(sizeof(lum) == sizeof(*lump));
+        LASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lump->lmm_objects[0]));
+        rc = copy_from_user(&lum, lump, sizeof(lum));
+        if (rc)
+                RETURN(-EFAULT);
+
         down(&lli->lli_open_sem);
         lsm = lli->lli_smd;
         if (lsm) {
                 up(&lli->lli_open_sem);
                 CDEBUG(D_IOCTL, "stripe already exists for ino %lu\n",
                        inode->i_ino);
-                /* If we haven't already done the open, do so now */
-                if (file->f_flags & O_LOV_DELAY_CREATE) {
-                        int rc2 = ll_osc_open(conn, inode, file, lsm);
-                        if (rc2)
-                                RETURN(rc2);
-                }
-
                 RETURN(-EEXIST);
         }
 
-        rc = obd_iocontrol(LL_IOC_LOV_SETSTRIPE, conn, 0, &lsm, (void *)arg);
-        if (rc) {
-                up(&lli->lli_open_sem);
-                RETURN(rc);
-        }
-        rc = ll_create_obj(conn, inode, file, lsm);
-        up(&lli->lli_open_sem);
+        f = get_empty_filp();
+        if (!f)
+                GOTO(out, -ENOMEM);
 
-        if (rc) {
-                obd_free_memmd(conn, &lsm);
-                RETURN(rc);
-        }
-        rc = ll_osc_open(conn, inode, file, lli->lli_smd);
+        f->f_dentry = file->f_dentry;
+        f->f_vfsmnt = file->f_vfsmnt;
+
+        rc = ll_intent_file_open(f, &lum, sizeof(lum), &oit);
+        if (rc)
+                GOTO(out, rc);
+        if (it_disposition(&oit, DISP_LOOKUP_NEG))
+                GOTO(out, -ENOENT);
+        req = oit.d.lustre.it_data;
+        rc = oit.d.lustre.it_status;
+
+        if (rc < 0)
+                GOTO(out, rc);
+
+        rc = mdc_req2lustre_md(req, 1, exp, &md);
+        if (rc)
+                GOTO(out, rc);
+        ll_update_inode(f->f_dentry->d_inode, md.body, md.lsm);
+
+        rc = ll_local_open(f, &oit);
+        if (rc)
+                GOTO(out, rc);
+        ll_intent_release(&oit);
+
+        rc = ll_file_release(f->f_dentry->d_inode, f);
+
+ out:
+        if (f)
+                put_filp(f);
+        up(&lli->lli_open_sem);
+        if (req != NULL)
+                ptlrpc_req_finished(req);
         RETURN(rc);
 }
 
 static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
 {
         struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-        struct lustre_handle *conn = ll_i2obdconn(inode);
 
         if (!lsm)
                 RETURN(-ENODATA);
 
-        return obd_iocontrol(LL_IOC_LOV_GETSTRIPE, conn, 0, lsm, (void *)arg);
+        return obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2obdexp(inode), 0, lsm,
+                            (void *)arg);
 }
 
 int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                   unsigned long arg)
 {
         struct ll_file_data *fd = file->private_data;
-        struct lustre_handle *conn;
         int flags;
+        ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%u\n", inode->i_ino,
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%x\n", inode->i_ino,
                inode->i_generation, inode, cmd);
 
         if (_IOC_TYPE(cmd) == 'T') /* tty ioctls */
-                return -ENOTTY;
+                RETURN(-ENOTTY);
 
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_IOCTL);
         switch(cmd) {
@@ -1028,31 +788,31 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                  *     not abused, and to handle any flag side effects.
                  */
                 if (get_user(flags, (int *) arg))
-                        return -EFAULT;
+                        RETURN(-EFAULT);
 
                 if (cmd == LL_IOC_SETFLAGS)
                         fd->fd_flags |= flags;
                 else
                         fd->fd_flags &= ~flags;
-                return 0;
+                RETURN(0);
         case LL_IOC_LOV_SETSTRIPE:
-                return ll_lov_setstripe(inode, file, arg);
+                RETURN(ll_lov_setstripe(inode, file, arg));
         case LL_IOC_LOV_GETSTRIPE:
-                return ll_lov_getstripe(inode, arg);
-
+                RETURN(ll_lov_getstripe(inode, arg));
+        case EXT3_IOC_GETFLAGS:
+        case EXT3_IOC_SETFLAGS:
+                RETURN( ll_iocontrol(inode, file, cmd, arg) );
         /* We need to special case any other ioctls we want to handle,
          * to send them to the MDS/OST as appropriate and to properly
          * network encode the arg field.
-        case EXT2_IOC_GETFLAGS:
-        case EXT2_IOC_SETFLAGS:
         case EXT2_IOC_GETVERSION_OLD:
         case EXT2_IOC_GETVERSION_NEW:
         case EXT2_IOC_SETVERSION_OLD:
         case EXT2_IOC_SETVERSION_NEW:
         */
         default:
-                conn = ll_i2obdconn(inode);
-                return obd_iocontrol(cmd, conn, 0, NULL, (void *)arg);
+                RETURN( obd_iocontrol(cmd, ll_i2obdexp(inode), 0, NULL,
+                                      (void *)arg) );
         }
 }
 
@@ -1074,7 +834,7 @@ loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
                 struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
                 err = ll_extent_lock(fd, inode, lsm, LCK_PR, &extent, &lockh);
                 if (err != ELDLM_OK)
-                        RETURN(-ENOLCK);
+                        RETURN(err);
 
                 offset += inode->i_size;
         } else if (origin == 1) { /* SEEK_CUR */
@@ -1101,25 +861,155 @@ loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
 int ll_fsync(struct file *file, struct dentry *dentry, int data)
 {
         struct inode *inode = dentry->d_inode;
-        int rc;
+        struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
+        struct ll_fid fid;
+        struct ptlrpc_request *req;
+        int rc, err;
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
                inode->i_generation, inode);
 
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_FSYNC);
-        /*
-         * filemap_fdata{sync,wait} are also called at PW lock cancelation so
-         * we know that they can only find data to writeback here if we are
-         * still holding the PW lock that covered the dirty pages.  XXX we
-         * should probably get a reference on it, though, just to be clear.
-         */
-        rc = filemap_fdatasync(inode->i_mapping);
-        if (rc == 0)
-                rc = filemap_fdatawait(inode->i_mapping);
 
+        /* fsync's caller has already called _fdata{sync,write}, we want
+         * that IO to finish before calling the osc and mdc sync methods */
+        rc = filemap_fdatawait(inode->i_mapping);
+
+        ll_inode2fid(&fid, inode);
+        err = mdc_sync(ll_i2sbi(inode)->ll_mdc_exp, &fid, &req);
+        if (!rc)
+                rc = err;
+        if (!err)
+                ptlrpc_req_finished(req);
+
+        if (data && lsm) {
+                struct obdo *oa = obdo_alloc();
+
+                if (!oa)
+                        RETURN(rc ? rc : -ENOMEM);
+
+                oa->o_id = lsm->lsm_object_id;
+                oa->o_valid = OBD_MD_FLID;
+                obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
+                                           OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+
+                err = obd_sync(ll_i2sbi(inode)->ll_osc_exp, oa, lsm,
+                               0, OBD_OBJECT_EOF);
+                if (!rc)
+                        rc = err;
+                obdo_free(oa);
+        }
+
+        RETURN(rc);
+}
+
+int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
+{
+        struct inode *inode = file->f_dentry->d_inode;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct obd_device *obddev;
+        struct ldlm_res_id res_id =
+                    { .name = {inode->i_ino, inode->i_generation, LDLM_FLOCK} };
+        struct lustre_handle lockh = {0};
+        struct ldlm_flock flock;
+        ldlm_mode_t mode = 0;
+        int flags = 0;
+        int rc;
+        ENTRY;
+
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu file_lock=%p\n",
+               inode->i_ino, file_lock);
+
+        flock.pid = file_lock->fl_pid;
+        flock.start = file_lock->fl_start;
+        flock.end = file_lock->fl_end;
+
+        switch (file_lock->fl_type) {
+        case F_RDLCK:
+                mode = LCK_PR;
+                break;
+        case F_UNLCK:
+                /* An unlock request may or may not have any relation to
+                 * existing locks so we may not be able to pass a lock handle
+                 * via a normal ldlm_lock_cancel() request. The request may even
+                 * unlock a byte range in the middle of an existing lock. In
+                 * order to process an unlock request we need all of the same
+                 * information that is given with a normal read or write record
+                 * lock request. To avoid creating another ldlm unlock (cancel)
+                 * message we'll treat a LCK_NL flock request as an unlock. */
+                mode = LCK_NL;
+                break;
+        case F_WRLCK:
+                mode = LCK_PW;
+                break;
+        default:
+                CERROR("unknown fcntl lock type: %d\n", file_lock->fl_type);
+                LBUG();
+        }
+
+        switch (cmd) {
+        case F_SETLKW:
+                flags = 0;
+                break;
+        case F_SETLK:
+                flags = LDLM_FL_BLOCK_NOWAIT;
+                break;
+        case F_GETLK:
+                flags = LDLM_FL_TEST_LOCK;
+                /* Save the old mode so that if the mode in the lock changes we
+                 * can decrement the appropriate reader or writer refcount. */
+                file_lock->fl_type = mode;
+                break;
+        default:
+                CERROR("unknown fcntl lock command: %d\n", cmd);
+                LBUG();
+        }
+
+        CDEBUG(D_DLMTRACE, "inode=%lu, pid=%u, flags=%#x, mode=%u, "
+               "start="LPU64", end="LPU64"\n", inode->i_ino, flock.pid,
+               flags, mode, flock.start, flock.end);
+
+        obddev = sbi->ll_mdc_exp->exp_obd;
+        rc = ldlm_cli_enqueue(sbi->ll_mdc_exp, NULL, obddev->obd_namespace,
+                              NULL, res_id, LDLM_FLOCK, &flock, sizeof(flock),
+                              mode, &flags, ldlm_flock_completion_ast, NULL,
+                              file_lock, &lockh);
         RETURN(rc);
 }
 
+static int ll_have_md_lock(struct dentry *de)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
+        struct lustre_handle lockh;
+        struct ldlm_res_id res_id = { .name = {0} };
+        struct obd_device *obddev;
+        int flags;
+        ENTRY;
+
+        if (!de->d_inode)
+               RETURN(0);
+
+        obddev = sbi->ll_mdc_exp->exp_obd;
+        res_id.name[0] = de->d_inode->i_ino;
+        res_id.name[1] = de->d_inode->i_generation;
+
+        CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id.name[0]);
+
+        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING;
+        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PR, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PR);
+                RETURN(1);
+        }
+
+        if (ldlm_lock_match(obddev->obd_namespace, flags, &res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PW, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PW);
+                RETURN(1);
+        }
+        RETURN(0);
+}
+
 int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
 {
         struct inode *inode = dentry->d_inode;
@@ -1136,60 +1026,45 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_REVALIDATE);
 #endif
 
-        /* this is very tricky.  it is unsafe to call ll_have_md_lock
-           when we have a referenced lock: because it may cause an RPC
-           below when the lock is marked CB_PENDING.  That RPC may not
-           go out because someone else may be in another RPC waiting for
-           that lock*/
-        if (!(it && it->it_lock_mode) && !ll_have_md_lock(dentry)) {
-                struct lustre_md md;
+        if (!ll_have_md_lock(dentry)) {
                 struct ptlrpc_request *req = NULL;
                 struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
                 struct ll_fid fid;
                 unsigned long valid = 0;
-                int rc;
-                int ealen = 0;
+                int rc, ealen = 0;
 
                 if (S_ISREG(inode->i_mode)) {
-                        ealen = obd_size_diskmd(&sbi->ll_osc_conn, NULL);
+                        ealen = obd_size_diskmd(sbi->ll_osc_exp, NULL);
                         valid |= OBD_MD_FLEASIZE;
                 }
                 ll_inode2fid(&fid, inode);
-                rc = mdc_getattr(&sbi->ll_mdc_conn, &fid, valid, ealen, &req);
+                rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, ealen, &req);
                 if (rc) {
                         CERROR("failure %d inode %lu\n", rc, inode->i_ino);
                         RETURN(-abs(rc));
                 }
-                rc = mdc_req2lustre_md(req, 0, &sbi->ll_osc_conn, &md);
-
-                /* XXX Too paranoid? */
-                if ((md.body->valid ^ valid) & OBD_MD_FLEASIZE)
-                        CERROR("Asked for %s eadata but got %s\n",
-                               (valid & OBD_MD_FLEASIZE) ? "some" : "no",
-                               (md.body->valid & OBD_MD_FLEASIZE) ? "some":
-                               "none");
+                rc = ll_prep_inode(sbi->ll_osc_exp, &inode, req, 0, NULL);
                 if (rc) {
                         ptlrpc_req_finished(req);
                         RETURN(rc);
                 }
-
-                ll_update_inode(inode, md.body, md.lsm);
-                if (md.lsm != NULL && ll_i2info(inode)->lli_smd != md.lsm)
-                        obd_free_memmd(&sbi->ll_osc_conn, &md.lsm);
-
                 ptlrpc_req_finished(req);
         }
 
+#if 0
+        if (ll_have_md_lock(dentry) &&
+            test_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &ll_i2info(inode)->lli_flags))
+                RETURN(0);
+#endif
+
         lsm = ll_i2info(inode)->lli_smd;
         if (!lsm)       /* object not yet allocated, don't validate size */
                 RETURN(0);
 
-        /*
-         * unfortunately stat comes in through revalidate and we don't
+        /* unfortunately stat comes in through revalidate and we don't
          * differentiate this use from initial instantiation.  we're
          * also being wildly conservative and flushing write caches
-         * so that stat really returns the proper size.
-         */
+         * so that stat really returns the proper size. */
         {
                 struct ldlm_extent extent = {0, OBD_OBJECT_EOF};
                 struct lustre_handle lockh = {0};
@@ -1206,8 +1081,7 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 int ll_getattr(struct vfsmount *mnt, struct dentry *de,
-                      struct lookup_intent *it, 
-                      struct kstat *stat)
+               struct lookup_intent *it, struct kstat *stat)
 {
         int res = 0;
         struct inode *inode = de->d_inode;
@@ -1235,6 +1109,7 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de,
 }
 #endif
 
+
 struct file_operations ll_file_operations = {
         read:           ll_file_read,
         write:          ll_file_write,
@@ -1244,25 +1119,17 @@ struct file_operations ll_file_operations = {
         mmap:           generic_file_mmap,
         llseek:         ll_file_seek,
         fsync:          ll_fsync,
+        //lock:           ll_file_flock
 };
 
 struct inode_operations ll_file_inode_operations = {
         setattr_raw:    ll_setattr_raw,
-        setattr:    ll_setattr,
-        truncate:   ll_truncate,
+        setattr:        ll_setattr,
+        truncate:       ll_truncate,
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        getattr_it: ll_getattr,
+        getattr_it:     ll_getattr,
 #else
-        revalidate_it: ll_inode_revalidate_it,
+        revalidate_it:  ll_inode_revalidate_it,
 #endif
 };
 
-struct inode_operations ll_special_inode_operations = {
-        setattr_raw:    ll_setattr_raw,
-        setattr:    ll_setattr,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        getattr_it:    ll_getattr,
-#else
-        revalidate_it: ll_inode_revalidate_it,
-#endif
-};
diff --git a/lustre/llite/iod.c b/lustre/llite/iod.c
deleted file mode 100644
index eef67d416c37d23dac03d238ea8262dcc04c9b18..0000000000000000000000000000000000000000
--- a/lustre/llite/iod.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Copyright (C) 2002, 2003  Cluster File Systems, Inc
- *
- *  this started as an implementation of an io daemon that woke regularly
- *  to force writeback.. the throttling in prepare_write and kupdate's usual
- *  writeback pressure got rid of our thread, but the file name remains.
- */
-
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/kmod.h>
-#include <linux/pagemap.h>
-#include <linux/mm.h>
-#include <linux/rbtree.h>
-#include <linux/seq_file.h>
-#include <linux/time.h>
-
-/* PG_inactive_clean is shorthand for rmap, we want free_high/low here.. */
-#ifdef PG_inactive_clean
-#include <linux/mm_inline.h>
-#endif
-
-#define DEBUG_SUBSYSTEM S_LLITE
-#include <linux/lustre_lite.h>
-#include "llite_internal.h"
-
-#ifndef list_for_each_prev_safe
-#define list_for_each_prev_safe(pos, n, head) \
-        for (pos = (head)->prev, n = pos->prev; pos != (head); \
-                pos = n, n = pos->prev )
-#endif
-
-extern spinlock_t inode_lock;
-
-/*
- * check to see if we're racing with truncate and put the page in
- * the brw_page array.  returns 0 if there is more room and 1
- * if the array is full.
- */
-static int llwp_consume_page(struct ll_writeback_pages *llwp,
-                             struct inode *inode, struct page *page)
-{
-        obd_off off = ((obd_off)page->index) << PAGE_SHIFT;
-        struct brw_page *pg;
-
-        /* we raced with truncate? */
-        if ( off >= inode->i_size ) {
-                int rc;
-                rc = ll_clear_dirty_pages(ll_i2obdconn(inode),
-                                          ll_i2info(inode)->lli_smd,
-                                          page->index, page->index);
-
-                LASSERT(rc == 0);
-                CDEBUG(D_CACHE, "offset "LPU64" (index %lu) > i_size %llu\n",
-                       off, page->index, inode->i_size);
-                unlock_page(page);
-                return 0;
-        }
-
-        page_cache_get(page);
-        pg = &llwp->pga[llwp->npgs];
-        llwp->npgs++;
-        LASSERT(llwp->npgs <= llwp->max);
-
-        pg->pg = page;
-        pg->off = off;
-        pg->flag = OBD_BRW_CREATE|OBD_BRW_FROM_GRANT;
-        pg->count = PAGE_CACHE_SIZE;
-
-        /* catch partial writes for files that end mid-page */
-        if (pg->off + pg->count > inode->i_size)
-                pg->count = inode->i_size & ~PAGE_CACHE_MASK;
-
-        /*
-         * matches ptlrpc_bulk_get assert that trickles down
-         * from a 0 page length going through niobuf and into
-         * the buffer regions being posted
-         */
-        LASSERT(pg->count >= 0);
-
-        CDEBUG(D_CACHE, "brw_page %p: off "LPU64" cnt %d, page %p: ind %ld"
-                        " i_size: %llu\n", pg, pg->off, pg->count, page,
-                        page->index, inode->i_size);
-
-        return llwp->npgs == llwp->max;
-}
-
-/*
- * returns the number of pages that it added to the pgs array
- *
- * this duplicates filemap_fdatasync and gives us an opportunity to grab lots
- * of dirty pages..
- */
-static void ll_get_dirty_pages(struct inode *inode,
-                               struct ll_writeback_pages *llwp)
-{
-        struct address_space *mapping = inode->i_mapping;
-        struct page *page;
-        struct list_head *pos, *n;
-        ENTRY;
-
-        PGCACHE_WRLOCK(mapping);
-
-        list_for_each_prev_safe(pos, n, &mapping->dirty_pages) {
-                page = list_entry(pos, struct page, list);
-
-                if (TryLockPage(page))
-                        continue;
-
-                list_del(&page->list);
-                list_add(&page->list, &mapping->locked_pages);
-
-                if (!PageDirty(page)) {
-                        unlock_page(page);
-                        continue;
-                }
-                ClearPageDirty(page);
-
-                if (llwp_consume_page(llwp, inode, page) != 0)
-                        break;
-        }
-
-        PGCACHE_WRUNLOCK(mapping);
-        EXIT;
-}
-
-static void ll_writeback(struct inode *inode, struct obdo *oa,
-                         struct ll_writeback_pages *llwp)
-{
-        struct ptlrpc_request_set *set;
-        int rc, i;
-        ENTRY;
-
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),bytes=%u\n",
-               inode->i_ino, inode->i_generation, inode,
-               ((llwp->npgs-1) << PAGE_SHIFT) + llwp->pga[llwp->npgs-1].count);
-
-        SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
-        set = ptlrpc_prep_set();
-        if (set == NULL) {
-                CERROR ("Can't create request set\n");
-                rc = -ENOMEM;
-        } else {
-                rc = obd_brw_async(OBD_BRW_WRITE, ll_i2obdconn(inode), oa,
-                                   ll_i2info(inode)->lli_smd, llwp->npgs,
-                                   llwp->pga, set, NULL);
-                if (rc == 0)
-                        rc = ptlrpc_set_wait(set);
-                if (rc == 0) {
-                        /* bug 1598: don't clobber blksize */
-                        oa->o_valid &= ~(OBD_MD_FLSIZE | OBD_MD_FLBLKSZ);
-                        obdo_refresh_inode(inode, oa, oa->o_valid);
-                }
-                ptlrpc_set_destroy (set);
-        }
-        /*
-         * b=1038, we need to pass _brw errors up so that writeback
-         * doesn't get stuck in recovery leaving processes stuck in
-         * D waiting for pages
-         */
-        if (rc) {
-                CERROR("error from obd_brw_async: rc = %d\n", rc);
-                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                    LPROC_LL_WB_FAIL, llwp->npgs);
-        } else {
-                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                    LPROC_LL_WB_OK, (llwp->npgs));
-        }
-
-        for (i = 0 ; i < llwp->npgs ; i++) {
-                struct page *page = llwp->pga[i].pg;
-
-                CDEBUG(D_CACHE, "finished page %p at index %lu\n", page,
-                       page->index);
-                LASSERT(PageLocked(page));
-
-                rc = ll_clear_dirty_pages(ll_i2obdconn(inode),
-                                          ll_i2info(inode)->lli_smd,
-                                          page->index, page->index);
-                LASSERT(rc == 0);
-                unlock_page(page);
-                page_cache_release(page);
-        }
-
-        EXIT;
-}
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
-#ifndef PG_inactive_clean
-#ifdef CONFIG_DISCONTIGMEM
-#error "sorry, we don't support DISCONTIGMEM yet"
-#endif
-
-/*
- * __alloc_pages marks a zone as needing balancing if an allocation is
- * performed when the zone has fewer free pages than its 'low' water
- * mark.  its cleared when try_to_free_pages makes progress.
- */
-static int zones_need_balancing(void)
-{
-        pg_data_t * pgdat;
-        zone_t *zone;
-        int i;
-
-        for ( pgdat = pgdat_list ; pgdat != NULL ; pgdat = pgdat->node_next ) {
-                for ( i = pgdat->nr_zones-1 ; i >= 0 ; i-- ) {
-                        zone = &pgdat->node_zones[i];
-
-                        if ( zone->need_balance )
-                                return 1;
-                }
-        }
-        return 0;
-}
-#endif
-/* 2.4 doesn't give us a way to find out how many pages we have
- * cached 'cause we're not using buffer_heads.  we are very
- * conservative here and flush the superblock of all dirty data
- * when the vm (rmap or stock) thinks that it is running low
- * and kswapd would have done work.  kupdated isn't good enough
- * because writers (dbench) can dirty _very quickly_, and we
- * allocate under writepage..
- *
- * 2.5 gets this right, see the {inc,dec}_page_state(nr_dirty, )
- */
-static int should_writeback(void)
-{
-#ifdef PG_inactive_clean
-        if (free_high(ALL_ZONES) > 0 || free_low(ANY_ZONE) > 0)
-#else
-        if (zones_need_balancing())
-#endif
-                return 1;
-        return 0;
-}
-
-static int ll_alloc_brw(struct inode *inode, struct ll_writeback_pages *llwp)
-{
-        memset(llwp, 0, sizeof(struct ll_writeback_pages));
-
-        llwp->max = inode->i_blksize >> PAGE_CACHE_SHIFT;
-        if (llwp->max == 0) {
-                CERROR("forcing llwp->max to 1.  blksize: %lu\n",
-                       inode->i_blksize);
-                llwp->max = 1;
-        }
-        llwp->pga = kmalloc(llwp->max * sizeof(*llwp->pga), GFP_ATOMIC);
-        if (llwp->pga == NULL)
-                RETURN(-ENOMEM);
-        RETURN(0);
-}
-
-int ll_check_dirty(struct super_block *sb)
-{
-        unsigned long old_flags; /* hack? */
-        int making_progress;
-        struct inode *inode;
-        struct obdo oa;
-        int rc = 0;
-        ENTRY;
-
-        if (!should_writeback())
-                return 0;
-
-        old_flags = current->flags;
-        current->flags |= PF_MEMALLOC;
-
-        spin_lock(&inode_lock);
-
-        /*
-         * first we try and write back dirty pages from dirty inodes
-         * until the VM thinkgs we're ok again..
-         */
-        do {
-                struct ll_writeback_pages llwp;
-                struct list_head *pos;
-                inode = NULL;
-                making_progress = 0;
-
-                list_for_each_prev(pos, &sb->s_dirty) {
-                        inode = list_entry(pos, struct inode, i_list);
-
-                        if (!(inode->i_state & I_DIRTY_PAGES)) {
-                                inode = NULL;
-                                continue;
-                        }
-                        break;
-                }
-
-                if (inode == NULL)
-                        break;
-
-                /* duplicate __sync_one, *sigh* */
-                list_del(&inode->i_list);
-                list_add(&inode->i_list, &inode->i_sb->s_locked_inodes);
-                inode->i_state |= I_LOCK;
-                inode->i_state &= ~I_DIRTY_PAGES;
-
-                spin_unlock(&inode_lock);
-
-                rc = ll_alloc_brw(inode, &llwp);
-                if (rc != 0)
-                        GOTO(cleanup, rc);
-
-                do {
-                        llwp.npgs = 0;
-                        ll_get_dirty_pages(inode, &llwp);
-                        if (llwp.npgs) {
-                                oa.o_id =
-                                      ll_i2info(inode)->lli_smd->lsm_object_id;
-                                oa.o_valid = OBD_MD_FLID;
-                                obdo_from_inode(&oa, inode,
-                                                OBD_MD_FLTYPE | OBD_MD_FLATIME|
-                                                OBD_MD_FLMTIME| OBD_MD_FLCTIME);
-                                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                                    LPROC_LL_WB_PRESSURE,
-                                                    llwp.npgs);
-                                ll_writeback(inode, &oa, &llwp);
-                                rc += llwp.npgs;
-                                making_progress = 1;
-                        }
-                } while (llwp.npgs && should_writeback());
-
-                spin_lock(&inode_lock);
-
-                if (!list_empty(&inode->i_mapping->dirty_pages))
-                        inode->i_state |= I_DIRTY_PAGES;
-
-                inode->i_state &= ~I_LOCK;
-                /*
-                 * we are sneaky and leave the inode on the dirty list,
-                 * even though it might not still be..
-                 */
-                if (!(inode->i_state & I_FREEING)) {
-                        list_del(&inode->i_list);
-                        list_add(&inode->i_list, &inode->i_sb->s_dirty);
-                }
-                wake_up(&inode->i_wait);
-                kfree(llwp.pga);
-        } while (making_progress && should_writeback());
-
-        /*
-         * and if that didn't work, we sleep on any data that might
-         * be under writeback..
-         */
-        while (should_writeback()) {
-                if (list_empty(&sb->s_locked_inodes))
-                        break;
-
-                inode = list_entry(sb->s_locked_inodes.next, struct inode,
-                                   i_list);
-
-                atomic_inc(&inode->i_count); /* XXX hack? */
-                spin_unlock(&inode_lock);
-                wait_event(inode->i_wait, !(inode->i_state & I_LOCK));
-                iput(inode);
-                spin_lock(&inode_lock);
-        }
-
-        spin_unlock(&inode_lock);
-
-cleanup:
-        current->flags = old_flags;
-
-        RETURN(rc);
-}
-#endif /* linux 2.5 */
-
-int ll_batch_writepage(struct inode *inode, struct obdo *oa, struct page *page)
-{
-        unsigned long old_flags; /* hack? */
-        struct ll_writeback_pages llwp;
-        int rc = 0;
-        ENTRY;
-
-        SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
-        old_flags = current->flags;
-        current->flags |= PF_MEMALLOC;
-        rc = ll_alloc_brw(inode, &llwp);
-        if (rc != 0)
-                GOTO(restore_flags, rc);
-
-        if (llwp_consume_page(&llwp, inode, page) == 0)
-                ll_get_dirty_pages(inode, &llwp);
-
-        if (llwp.npgs) {
-                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                    LPROC_LL_WB_WRITEPAGE, llwp.npgs);
-                ll_writeback(inode, oa, &llwp);
-        }
-        kfree(llwp.pga);
-
-restore_flags:
-        current->flags = old_flags;
-        RETURN(rc);
-}
diff --git a/lustre/llite/llite_close.c b/lustre/llite/llite_close.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf064c09dc2bb5a1940a1196ee8d605e6d8e1730
--- /dev/null
+++ b/lustre/llite/llite_close.c
@@ -0,0 +1,263 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Lite routines to issue a secondary close after writeback
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <linux/lustre_mds.h>
+#include <linux/lustre_lite.h>
+#include "llite_internal.h"
+
+/* record that a write is in flight */
+void llap_write_pending(struct inode *inode, struct ll_async_page *llap)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        spin_lock(&lli->lli_lock);
+        list_add(&llap->llap_pending_write, &lli->lli_pending_write_llaps);
+        spin_unlock(&lli->lli_lock);
+}
+
+/* record that a write has completed */
+void llap_write_complete(struct inode *inode, struct ll_async_page *llap)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        spin_lock(&lli->lli_lock);
+        if (!list_empty(&llap->llap_pending_write))
+                list_del_init(&llap->llap_pending_write);
+        spin_unlock(&lli->lli_lock);
+}
+
+void ll_open_complete(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        spin_lock(&lli->lli_lock);
+        lli->lli_send_done_writing = 0;
+        spin_unlock(&lli->lli_lock);
+}
+
+/* if we close with writes in flight then we want the completion or cancelation
+ * of those writes to send a DONE_WRITING rpc to the MDS */
+int ll_is_inode_dirty(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        int rc = 0;
+        ENTRY;
+
+        spin_lock(&lli->lli_lock);
+        if (!list_empty(&lli->lli_pending_write_llaps))
+                rc = 1;
+        spin_unlock(&lli->lli_lock);
+        RETURN(rc);
+}
+
+void ll_try_done_writing(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;
+
+        spin_lock(&lli->lli_lock);
+
+        if (lli->lli_send_done_writing &&
+            list_empty(&lli->lli_pending_write_llaps)) {
+
+                spin_lock(&lcq->lcq_lock);
+                if (list_empty(&lli->lli_close_item)) {
+                        CDEBUG(D_INODE, "adding inode %lu/%u to close list\n",
+                               inode->i_ino, inode->i_generation);
+                        LASSERT(igrab(inode) == inode);
+                        list_add_tail(&lli->lli_close_item, &lcq->lcq_list);
+                        wake_up(&lcq->lcq_waitq);
+                }
+                spin_unlock(&lcq->lcq_lock);
+        }
+
+        spin_unlock(&lli->lli_lock);
+}
+
+/* The MDS needs us to get the real file attributes, then send a DONE_WRITING */
+void ll_queue_done_writing(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        ENTRY;
+
+        spin_lock(&lli->lli_lock);
+        lli->lli_send_done_writing = 1;
+        spin_unlock(&lli->lli_lock);
+
+        ll_try_done_writing(inode);
+        EXIT;
+}
+
+/* If we know the file size and have the cookies:
+ *  - send a DONE_WRITING rpc
+ *
+ * Otherwise:
+ *  - get a whole-file lock
+ *  - get the authoritative size and all cookies with GETATTRs
+ *  - send a DONE_WRITING rpc
+ */
+static void ll_close_done_writing(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct ldlm_extent extent = { .start = 0, .end = OBD_OBJECT_EOF };
+        struct lustre_handle lockh = { 0 };
+        struct obdo obdo;
+        obd_flag valid;
+        int rc, ast_flags = 0;
+        ENTRY;
+
+        memset(&obdo, 0, sizeof(obdo));
+        if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags))
+                goto rpc;
+
+        rc = ll_extent_lock_no_validate(NULL, inode, lli->lli_smd, LCK_PW,
+                                        &extent, &lockh, ast_flags);
+        if (rc != ELDLM_OK) {
+                CERROR("lock acquisition failed (%d): unable to send "
+                       "DONE_WRITING for inode %lu/%u\n", rc, inode->i_ino,
+                       inode->i_generation);
+                GOTO(out, rc);
+        }
+
+        rc = ll_lsm_getattr(ll_i2obdexp(inode), lli->lli_smd, &obdo);
+        if (rc) {
+                CERROR("inode_getattr failed (%d): unable to send DONE_WRITING "
+                       "for inode %lu/%u\n", rc, inode->i_ino,
+                       inode->i_generation);
+                ll_extent_unlock(NULL, inode, lli->lli_smd, LCK_PW, &lockh);
+                GOTO(out, rc);
+        }
+
+        obdo_refresh_inode(inode, &obdo, valid);
+
+        CDEBUG(D_INODE, "objid "LPX64" size %Lu, blocks %lu, blksize %lu\n",
+               lli->lli_smd->lsm_object_id, inode->i_size, inode->i_blocks,
+               inode->i_blksize);
+
+        set_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags);
+
+        rc = ll_extent_unlock(NULL, inode, lli->lli_smd, LCK_PW, &lockh);
+        if (rc != ELDLM_OK)
+                CERROR("unlock failed (%d)?  proceeding anyways...\n", rc);
+
+ rpc:
+        obdo.o_id = inode->i_ino;
+        obdo.o_size = inode->i_size;
+        obdo.o_blocks = inode->i_blocks;
+        obdo.o_valid = OBD_MD_FLID | OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+
+        rc = mdc_done_writing(ll_i2sbi(inode)->ll_mdc_exp, &obdo);
+ out:
+        iput(inode);
+}
+
+static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
+{
+        struct ll_inode_info *lli = NULL;
+
+        spin_lock(&lcq->lcq_lock);
+
+        if (lcq->lcq_list.next == NULL)
+                lli = ERR_PTR(-1);
+        else if (!list_empty(&lcq->lcq_list)) {
+                lli = list_entry(lcq->lcq_list.next, struct ll_inode_info,
+                                 lli_close_item);
+                list_del(&lli->lli_close_item);
+        }
+
+        spin_unlock(&lcq->lcq_lock);
+        return lli;
+}
+
+static int ll_close_thread(void *arg)
+{
+        struct ll_close_queue *lcq = arg;
+        ENTRY;
+
+        /* XXX boiler-plate */
+        {
+                char name[sizeof(current->comm)];
+                unsigned long flags;
+                snprintf(name, sizeof(name) - 1, "ll_close");
+                kportal_daemonize(name);
+                SIGNAL_MASK_LOCK(current, flags);
+                sigfillset(&current->blocked);
+                RECALC_SIGPENDING;
+                SIGNAL_MASK_UNLOCK(current, flags);
+        }
+
+        complete(&lcq->lcq_comp);
+
+        while (1) {
+                struct l_wait_info lwi = { 0 };
+                struct ll_inode_info *lli;
+                struct inode *inode;
+
+                l_wait_event_exclusive(lcq->lcq_waitq,
+                                       (lli = ll_close_next_lli(lcq)) != NULL,
+                                       &lwi);
+                if (IS_ERR(lli))
+                        break;
+
+                inode = ll_info2i(lli);
+                ll_close_done_writing(inode);
+        }
+
+        complete(&lcq->lcq_comp);
+        RETURN(0);
+}
+
+int ll_close_thread_start(struct ll_close_queue **lcq_ret)
+{
+        struct ll_close_queue *lcq;
+        pid_t pid;
+
+        OBD_ALLOC(lcq, sizeof(*lcq));
+        if (lcq == NULL)
+                return -ENOMEM;
+
+        spin_lock_init(&lcq->lcq_lock);
+        INIT_LIST_HEAD(&lcq->lcq_list);
+        init_waitqueue_head(&lcq->lcq_waitq);
+        init_completion(&lcq->lcq_comp);
+
+        pid = kernel_thread(ll_close_thread, lcq, 0);
+        if (pid < 0) {
+                OBD_FREE(lcq, sizeof(*lcq));
+                return pid;
+        }
+
+        wait_for_completion(&lcq->lcq_comp);
+        *lcq_ret = lcq;
+        return 0;
+}
+
+void ll_close_thread_shutdown(struct ll_close_queue *lcq)
+{
+        init_completion(&lcq->lcq_comp);
+        lcq->lcq_list.next = NULL;
+        wake_up(&lcq->lcq_waitq);
+        wait_for_completion(&lcq->lcq_comp);
+        OBD_FREE(lcq, sizeof(*lcq));
+}
diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h
index fd37709d6a7c886cef4d78074d57e23512cb99d6..14e04a7711bb3ec9ea5d6217f9c6bf692780b05a 100644
--- a/lustre/llite/llite_internal.h
+++ b/lustre/llite/llite_internal.h
@@ -10,11 +10,40 @@
 #ifndef LLITE_INTERNAL_H
 #define LLITE_INTERNAL_H
 
+struct ll_sb_info {
+        struct obd_uuid           ll_sb_uuid;
+//        struct lustre_handle      ll_mdc_conn;
+        struct obd_export        *ll_mdc_exp;
+        struct obd_export        *ll_osc_exp;
+        struct proc_dir_entry*    ll_proc_root;
+        obd_id                    ll_rootino; /* number of root inode */
+
+        struct obd_uuid           ll_mds_uuid;
+        struct obd_uuid           ll_mds_peer_uuid;
+        struct lustre_mount_data *ll_lmd;
+        char                     *ll_instance; 
+
+        int                       ll_flags;
+        wait_queue_head_t         ll_commitcbd_waitq;
+        wait_queue_head_t         ll_commitcbd_ctl_waitq;
+        int                       ll_commitcbd_flags;
+        struct task_struct       *ll_commitcbd_thread;
+        time_t                    ll_commitcbd_waketime;
+        time_t                    ll_commitcbd_timeout;
+        spinlock_t                ll_commitcbd_lock;
+        struct list_head          ll_conn_chain; /* per-conn chain of SBs */
+
+        struct hlist_head         ll_orphan_dentry_list; /*please don't ask -p*/
+        struct ll_close_queue    *ll_lcq;
+
+        struct lprocfs_stats     *ll_stats; /* lprocfs stats counter */
+};
 
-struct ll_sb_info;
 struct lustre_handle;
 struct lov_stripe_md;
 
+extern spinlock_t inode_lock;
+
 extern void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi);
 extern struct proc_dir_entry *proc_lustre_fs_root;
 
@@ -31,129 +60,257 @@ static inline struct inode *ll_info2i(struct ll_inode_info *lli)
 #endif
 }
 
-/* llite/commit_callback.c */
-int ll_commitcbd_setup(struct ll_sb_info *);
-int ll_commitcbd_cleanup(struct ll_sb_info *);
+static inline void ll_i2uctxt(struct ll_uctxt *ctxt, struct inode *i1,
+                              struct inode *i2)
+{
+        LASSERT(i1);
+        LASSERT(ctxt);
+
+        if (in_group_p(i1->i_gid))
+                ctxt->gid1 = i1->i_gid;
+        else
+                ctxt->gid1 = -1;
+
+        if (i2) {
+                if (in_group_p(i2->i_gid))
+                        ctxt->gid2 = i2->i_gid;
+                else
+                        ctxt->gid2 = -1;
+        } else 
+                ctxt->gid2 = 0;
+}
+
+struct it_cb_data {
+	struct inode *icbd_parent;
+	struct dentry **icbd_childp;
+	obd_id hash;
+};
+
+#define LLAP_MAGIC 98764321
+
+struct ll_async_page {
+        int             llap_magic;
+        void            *llap_cookie;
+        int             llap_queued;
+        struct page     *llap_page;
+        struct list_head llap_pending_write;
+};
 
-/* lproc_llite.c */
+#define LL_CDEBUG_PAGE(page, STR)                                       \
+        CDEBUG(D_PAGE, "page %p map %p ind %lu priv %0lx: " STR,        \
+               page, page->mapping, page->index, page->private)
+
+/* llite/lproc_llite.c */
 int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
                                 struct super_block *sb, char *osc, char *mdc);
 void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi);
 
+/* llite/dir.c */
+extern struct file_operations ll_dir_operations;
+extern struct inode_operations ll_dir_inode_operations;
+
 /* llite/namei.c */
+int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir);
 struct inode *ll_iget(struct super_block *sb, ino_t hash,
                       struct lustre_md *lic);
 struct dentry *ll_find_alias(struct inode *, struct dentry *);
-int ll_it_open_error(int phase, struct lookup_intent *it);
-int ll_mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode,
-                         int flags, void *opaque);
+int ll_mdc_cancel_unused(struct lustre_handle *, struct inode *, int flags,
+                         void *opaque);
+int ll_mdc_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *,
+                        void *data, int flag);
+void ll_prepare_mdc_op_data(struct mdc_op_data *,
+                            struct inode *i1, struct inode *i2,
+                            const char *name, int namelen, int mode);
 
 /* llite/rw.c */
-void ll_end_writeback(struct inode *, struct page *);
-
-void ll_remove_dirty(struct inode *inode, unsigned long start,
-                     unsigned long end);
-int ll_rd_dirty_pages(char *page, char **start, off_t off, int count,
-                      int *eof, void *data);
-int ll_rd_max_dirty_pages(char *page, char **start, off_t off, int count,
-                          int *eof, void *data);
-int ll_wr_max_dirty_pages(struct file *file, const char *buffer,
-                          unsigned long count, void *data);
-int ll_clear_dirty_pages(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                         unsigned long start, unsigned long end);
-int ll_mark_dirty_page(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                       unsigned long index);
-
-/* llite/file.c */
-extern int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *);
-
-/* llite/super.c */
-int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc);
-int ll_setattr(struct dentry *de, struct iattr *attr);
-
-/* iod.c */
-#define IO_STAT_ADD(FIS, STAT, VAL) do {        \
-        struct file_io_stats *_fis_ = (FIS);    \
-        spin_lock(&_fis_->fis_lock);            \
-        _fis_->fis_##STAT += VAL;               \
-        spin_unlock(&_fis_->fis_lock);          \
-} while (0)
-
-#define INODE_IO_STAT_ADD(INODE, STAT, VAL)        \
-        IO_STAT_ADD(&ll_i2sbi(INODE)->ll_iostats, STAT, VAL)
-
-#define PAGE_IO_STAT_ADD(PAGE, STAT, VAL)               \
-        INODE_IO_STAT_ADD((PAGE)->mapping, STAT, VAL)
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-/* XXX lliod needs more work in 2.5 before being proven and brought back
- * to 2.4, it'll at least require a patch to introduce page->private */
-int lliod_start(struct ll_sb_info *sbi, struct inode *inode);
-void lliod_stop(struct ll_sb_info *sbi);
-#else
-#define lliod_start(sbi, inode) ({int _ret = 0; (void)sbi, (void)inode; _ret;})
-#define lliod_stop(sbi) do { (void)sbi; } while (0)
+int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to);
+int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to);
+void ll_inode_fill_obdo(struct inode *inode, int cmd, struct obdo *oa);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define ll_ap_completion ll_ap_completion_24
+void ll_ap_completion_24(void *data, int cmd, int rc);
+#else 
+#define ll_ap_completion ll_ap_completion_26
+void ll_ap_completion_26(void *data, int cmd, int rc);
 #endif
-void lliod_wakeup(struct inode *inode);
-void lliod_give_plist(struct inode *inode, struct plist *plist, int rw);
-void lliod_give_page(struct inode *inode, struct page *page, int rw);
-void plist_init(struct plist *plist); /* for lli initialization.. */
+int ll_ocp_update_obdo(struct obd_client_page *ocp, int cmd, struct obdo *oa);
+int ll_ocp_set_io_ready(struct obd_client_page *ocp, int cmd);
+int ll_ocp_update_io_args(struct obd_client_page *ocp, int cmd);
+void ll_removepage(struct page *page);
+int ll_readpage(struct file *file, struct page *page);
+struct ll_async_page *llap_from_cookie(void *cookie);
+struct ll_async_page *llap_from_page(struct page *page);
 
-void ll_lldo_init(struct ll_dirty_offsets *lldo);
-void ll_record_dirty(struct inode *inode, unsigned long offset);
-void ll_remove_dirty(struct inode *inode, unsigned long start,
-                     unsigned long end);
-int ll_find_dirty(struct ll_dirty_offsets *lldo, unsigned long *start,
-                  unsigned long *end);
-int ll_farthest_dirty(struct ll_dirty_offsets *lldo, unsigned long *farthest);
+void ll_truncate(struct inode *inode);
 
+/* llite/file.c */
+extern struct file_operations ll_file_operations;
+extern struct inode_operations ll_file_inode_operations;
+extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *);
+int ll_extent_lock(struct ll_file_data *, struct inode *,
+                   struct lov_stripe_md *, int mode, struct ldlm_extent *,
+                   struct lustre_handle *);
+int ll_extent_unlock(struct ll_file_data *, struct inode *,
+                     struct lov_stripe_md *, int mode, struct lustre_handle *);
+int ll_file_open(struct inode *inode, struct file *file);
+int ll_file_release(struct inode *inode, struct file *file);
+int ll_lsm_getattr(struct obd_export *, struct lov_stripe_md *, struct obdo *);
+int ll_extent_lock_no_validate(struct ll_file_data *, struct inode *,
+                               struct lov_stripe_md *, int mode,
+                               struct ldlm_extent *, struct lustre_handle *,
+                               int ast_flags);
 
-/* llite/super25.c */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+int ll_local_open(struct file *file, struct lookup_intent *it);
+int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode, 
+                 struct file *file);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 int ll_getattr(struct vfsmount *mnt, struct dentry *de,
-               struct lookup_intent *it, 
-               struct kstat *stat);
+               struct lookup_intent *it, struct kstat *stat);
 #endif
 
+/* llite/special.c */
+extern struct inode_operations ll_special_inode_operations;
+extern struct file_operations ll_special_chr_inode_fops;
+extern struct file_operations ll_special_chr_file_fops;
+extern struct file_operations ll_special_blk_inode_fops;
+extern struct file_operations ll_special_fifo_inode_fops;
+extern struct file_operations ll_special_fifo_file_fops;
+extern struct file_operations ll_special_sock_inode_fops;
 
 /* llite/dcache.c */
 void ll_intent_release(struct lookup_intent *);
 extern void ll_set_dd(struct dentry *de);
 void ll_unhash_aliases(struct inode *);
-
-/* llite/rw.c */
-void ll_truncate(struct inode *inode);
-void ll_end_writeback(struct inode *inode, struct page *page);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-int ll_check_dirty(struct super_block *sb);
-int ll_batch_writepage(struct inode *inode, struct obdo *oa, struct page *page);
-#else
-#define ll_check_dirty(SB) do { (void)SB; } while (0)
-#endif
+void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft);
+void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry);
 
 /* llite/llite_lib.c */
 
 extern struct super_operations ll_super_operations;
+extern struct super_operations lustre_super_operations;
 
 char *ll_read_opt(const char *opt, char *data);
 int ll_set_opt(const char *opt, char *data, int fl);
 void ll_options(char *options, char **ost, char **mds, int *flags);
 void ll_lli_init(struct ll_inode_info *lli);
 int ll_fill_super(struct super_block *sb, void *data, int silent);
+int lustre_fill_super(struct super_block *sb, void *data, int silent);
+void lustre_put_super(struct super_block *sb);
 void ll_put_super(struct super_block *sb);
+struct inode *ll_inode_from_lock(struct ldlm_lock *lock);
 void ll_clear_inode(struct inode *inode);
 int ll_attr2inode(struct inode *inode, struct iattr *attr, int trunc);
-int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc);
 int ll_setattr_raw(struct inode *inode, struct iattr *attr);
 int ll_setattr(struct dentry *de, struct iattr *attr);
 int ll_statfs(struct super_block *sb, struct kstatfs *sfs);
+int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
+                       unsigned long maxage);
 void ll_update_inode(struct inode *inode, struct mds_body *body,
                      struct lov_stripe_md *lsm);
 int it_disposition(struct lookup_intent *it, int flag);
 void it_set_disposition(struct lookup_intent *it, int flag);
 void ll_read_inode2(struct inode *inode, void *opaque);
+int ll_iocontrol(struct inode *inode, struct file *file,
+                 unsigned int cmd, unsigned long arg);
 void ll_umount_begin(struct super_block *sb);
+int ll_prep_inode(struct obd_export *exp, struct inode **inode, 
+                  struct ptlrpc_request *req, int offset, struct super_block *);
+__u32 get_uuid2int(const char *name, int len);
+struct dentry *ll_fh_to_dentry(struct super_block *sb, __u32 *data, int len,
+                               int fhtype, int parent);
+int ll_dentry_to_fh(struct dentry *, __u32 *datap, int *lenp, int need_parent);
+/* llite/symlink.c */
+extern struct inode_operations ll_fast_symlink_inode_operations;
+
+/* llite/llite_close.c */
+struct ll_close_queue {
+        spinlock_t              lcq_lock;
+        struct list_head        lcq_list;
+        wait_queue_head_t       lcq_waitq;
+        struct completion       lcq_comp;
+};
 
+void llap_write_pending(struct inode *inode, struct ll_async_page *llap);
+void llap_write_complete(struct inode *inode, struct ll_async_page *llap);
+void ll_open_complete(struct inode *inode);
+int ll_is_inode_dirty(struct inode *inode);
+void ll_try_done_writing(struct inode *inode);
+void ll_queue_done_writing(struct inode *inode);
+void ll_close_thread_shutdown(struct ll_close_queue *lcq);
+int ll_close_thread_start(struct ll_close_queue **lcq_ret);
 
+/* generic */
+#define LL_SUPER_MAGIC 0x0BD00BD0
+
+#define LL_SBI_NOLCK            0x1
+#define LL_SBI_READAHEAD        0x2
+
+#if  (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+#define    ll_s2sbi(sb)     ((struct ll_sb_info *)((sb)->s_fs_info))
+void __d_rehash(struct dentry * entry, int lock);
+static inline __u64 ll_ts2u64(struct timespec *time)
+{
+        __u64 t = time->tv_sec;
+        return t;
+}
+#else  /* 2.4 here */
+#define    ll_s2sbi(sb)     ((struct ll_sb_info *)((sb)->u.generic_sbp))
+static inline __u64 ll_ts2u64(time_t *time)
+{
+        return *time;
+}
+#endif 
+
+/* don't need an addref as the sb_info should be holding one */
+static inline struct obd_export *ll_s2obdexp(struct super_block *sb)
+{
+        return ll_s2sbi(sb)->ll_osc_exp;
+}
+
+/* don't need an addref as the sb_info should be holding one */
+static inline struct obd_export *ll_s2mdcexp(struct super_block *sb)
+{
+        return ll_s2sbi(sb)->ll_mdc_exp;
+}
+
+static inline struct client_obd *sbi2mdc(struct ll_sb_info *sbi)
+{
+        struct obd_device *obd = sbi->ll_mdc_exp->exp_obd;
+        if (obd == NULL)
+                LBUG();
+        return &obd->u.cli;
+}
+
+// FIXME: replace the name of this with LL_SB to conform to kernel stuff
+static inline struct ll_sb_info *ll_i2sbi(struct inode *inode)
+{
+        return ll_s2sbi(inode->i_sb);
+}
+
+static inline struct obd_export *ll_i2obdexp(struct inode *inode)
+{
+        return ll_s2obdexp(inode->i_sb);
+}
+
+static inline struct obd_export *ll_i2mdcexp(struct inode *inode)
+{
+        return ll_s2mdcexp(inode->i_sb);
+}
+
+static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
+{
+        mdc_pack_fid(fid, inode->i_ino, inode->i_generation,
+                     inode->i_mode & S_IFMT);
+}
+
+static inline int ll_mds_max_easize(struct super_block *sb)
+{
+        return sbi2mdc(ll_s2sbi(sb))->cl_max_mds_easize;
+}
+
+static inline __u64 ll_file_maxbytes(struct inode *inode)
+{
+        return ll_i2info(inode)->lli_maxbytes;
+}
 
 #endif /* LLITE_INTERNAL_H */
diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c
index ba9ee45510864b875f56229561d1dc4dc8c7d2b0..deaa355a7c24b6378e903520c509ede6e3a63793 100644
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -26,11 +26,10 @@
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/version.h>
+
 #include <linux/lustre_lite.h>
 #include <linux/lustre_ha.h>
 #include <linux/lustre_dlm.h>
-#include <linux/init.h>
-#include <linux/fs.h>
 #include <linux/lprocfs_status.h>
 #include "llite_internal.h"
 
@@ -44,6 +43,187 @@ extern struct super_operations ll_super_operations;
 #define log2(n) ffz(~(n))
 #endif
 
+struct ll_sb_info *lustre_init_sbi(struct super_block *sb) 
+{
+        struct ll_sb_info *sbi = NULL;
+        class_uuid_t uuid;
+        ENTRY;
+
+        OBD_ALLOC(sbi, sizeof(*sbi));
+        if (!sbi)
+                RETURN(NULL);
+
+        INIT_LIST_HEAD(&sbi->ll_conn_chain);
+        INIT_HLIST_HEAD(&sbi->ll_orphan_dentry_list);
+        ll_s2sbi(sb) = sbi;
+
+        generate_random_uuid(uuid);
+        class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
+        RETURN(sbi);
+}
+
+void lustre_free_sbi(struct super_block *sb) 
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        ENTRY;
+
+        if (sbi != NULL)
+                OBD_FREE(sbi, sizeof(*sbi));
+        ll_s2sbi(sb) = NULL;
+        EXIT;
+}
+
+int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc)
+{
+        struct inode *root = 0;
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct obd_device *obd;
+        struct ll_fid rootfid;
+        struct obd_statfs osfs;
+        struct ptlrpc_request *request = NULL;
+        struct lustre_handle osc_conn = {0, };
+        struct lustre_handle mdc_conn = {0, };
+        struct lustre_md md;
+        kdev_t devno;
+        int err;
+
+        obd = class_name2obd(mdc);
+        if (!obd) {
+                CERROR("MDC %s: not setup or attached\n", mdc);
+                RETURN(-EINVAL);
+        }
+
+        if (proc_lustre_fs_root) {
+                err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
+                                                  osc, mdc);
+                if (err < 0)
+                        CERROR("could not register mount in /proc/lustre");
+        }
+
+        mdc_init_ea_size(obd, osc);
+
+        err = obd_connect(&mdc_conn, obd, &sbi->ll_sb_uuid);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n", mdc, err);
+                GOTO(out, err);
+        }
+        sbi->ll_mdc_exp = class_conn2export(&mdc_conn);
+
+        err = obd_statfs(obd, &osfs, jiffies - HZ);
+        if (err)
+                GOTO(out_mdc, err);
+
+        LASSERT(osfs.os_bsize);
+        sb->s_blocksize = osfs.os_bsize;
+        sb->s_blocksize_bits = log2(osfs.os_bsize);
+        sb->s_magic = LL_SUPER_MAGIC;
+        sb->s_maxbytes = PAGE_CACHE_MAXBYTES;
+        
+        devno = get_uuid2int(sbi2mdc(sbi)->cl_import->imp_target_uuid.uuid, 
+                             strlen(sbi2mdc(sbi)->cl_import->imp_target_uuid.uuid));
+        sb->s_dev = devno;
+
+        obd = class_name2obd(osc);
+        if (!obd) {
+                CERROR("OSC %s: not setup or attached\n", osc);
+                GOTO(out_mdc, err);
+        }
+
+        err = obd_connect(&osc_conn, obd, &sbi->ll_sb_uuid);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n", osc, err);
+                GOTO(out_mdc, err);
+        }
+        sbi->ll_osc_exp = class_conn2export(&osc_conn);
+
+        err = mdc_getstatus(sbi->ll_mdc_exp, &rootfid);
+        if (err) {
+                CERROR("cannot mds_connect: rc = %d\n", err);
+                GOTO(out_osc, err);
+        }
+        CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
+        sbi->ll_rootino = rootfid.id;
+
+        sb->s_op = &lustre_super_operations;
+
+        /* make root inode 
+         * XXX: move this to after cbd setup? */
+        err = mdc_getattr(sbi->ll_mdc_exp, &rootfid,
+                          OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
+        if (err) {
+                CERROR("mdc_getattr failed for root: rc = %d\n", err);
+                GOTO(out_osc, err);
+        }
+
+        err = mdc_req2lustre_md(request, 0, sbi->ll_osc_exp, &md);
+        if (err) {
+                CERROR("failed to understand root inode md: rc = %d\n",err);
+                ptlrpc_req_finished (request);
+                GOTO(out_osc, err);
+        }
+
+        LASSERT(sbi->ll_rootino != 0);
+        root = ll_iget(sb, sbi->ll_rootino, &md);
+
+        ptlrpc_req_finished(request);
+
+        if (root == NULL || is_bad_inode(root)) {
+                /* XXX might need iput() for bad inode */
+                CERROR("lustre_lite: bad iget4 for root\n");
+                GOTO(out_root, err = -EBADF);
+        }
+
+        err = ll_close_thread_start(&sbi->ll_lcq);
+        if (err) {
+                CERROR("cannot start close thread: rc %d\n", err);
+                GOTO(out_root, err);
+        }
+
+        sb->s_root = d_alloc_root(root);
+        RETURN(err);
+
+out_root:
+        if (root)
+                iput(root);
+out_osc:
+        obd_disconnect(sbi->ll_osc_exp, 0);
+out_mdc:
+        obd_disconnect(sbi->ll_mdc_exp, 0);
+out:
+        lprocfs_unregister_mountpoint(sbi);
+        RETURN(err);
+}
+
+void lustre_common_put_super(struct super_block *sb)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct hlist_node *tmp, *next;
+        ENTRY;
+
+        ll_close_thread_shutdown(sbi->ll_lcq);
+
+        list_del(&sbi->ll_conn_chain);
+        obd_disconnect(sbi->ll_osc_exp, 0);
+
+        lprocfs_unregister_mountpoint(sbi);
+        if (sbi->ll_proc_root) {
+                lprocfs_remove(sbi->ll_proc_root);
+                sbi->ll_proc_root = NULL;
+        }
+
+        obd_disconnect(sbi->ll_mdc_exp, 0);
+
+        // We do this to get rid of orphaned dentries. That is not really trw.
+        spin_lock(&dcache_lock);
+        hlist_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) {
+                struct dentry *dentry = hlist_entry(tmp, struct dentry, d_hash);
+                shrink_dcache_parent(dentry);
+        }
+        spin_unlock(&dcache_lock);
+        EXIT;
+}
+
+
 char *ll_read_opt(const char *opt, char *data)
 {
         char *value;
@@ -79,7 +259,7 @@ int ll_set_opt(const char *opt, char *data, int fl)
                 RETURN(fl);
 }
 
-void ll_options(char *options, char **ost, char **mds, int *flags)
+void ll_options(char *options, char **ost, char **mdc, int *flags)
 {
         char *this_char;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
@@ -100,11 +280,14 @@ void ll_options(char *options, char **ost, char **mds, int *flags)
         while ((this_char = strsep (&opt_ptr, ",")) != NULL) {
 #endif
                 CDEBUG(D_SUPER, "this_char %s\n", this_char);
-                if ((!*ost && (*ost = ll_read_opt("osc", this_char)))||
-                    (!*mds && (*mds = ll_read_opt("mdc", this_char)))||
-                    (!(*flags & LL_SBI_NOLCK) &&
-                     ((*flags) = (*flags) |
-                      ll_set_opt("nolock", this_char, LL_SBI_NOLCK))))
+                if (!*ost && (*ost = ll_read_opt("osc", this_char)))
+                        continue;
+                if (!*mdc && (*mdc = ll_read_opt("mdc", this_char)))
+                        continue;
+                if (!(*flags & LL_SBI_NOLCK) &&
+                    ((*flags) = (*flags) |
+                                ll_set_opt("nolock", this_char,
+                                           LL_SBI_NOLCK)))
                         continue;
         }
         EXIT;
@@ -113,171 +296,271 @@ void ll_options(char *options, char **ost, char **mds, int *flags)
 void ll_lli_init(struct ll_inode_info *lli)
 {
         sema_init(&lli->lli_open_sem, 1);
-        spin_lock_init(&lli->lli_read_extent_lock);
-        INIT_LIST_HEAD(&lli->lli_read_extents);
         lli->lli_flags = 0;
         lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        ll_lldo_init(&lli->lli_dirty);
-        spin_lock_init(&lli->lli_pg_lock);
-        INIT_LIST_HEAD(&lli->lli_lc_item);
-        plist_init(&lli->lli_pl_read);
-        plist_init(&lli->lli_pl_write);
-        atomic_set(&lli->lli_in_writepages, 0);
-#endif
+        spin_lock_init(&lli->lli_lock);
+        INIT_LIST_HEAD(&lli->lli_pending_write_llaps);
 }
 
 int ll_fill_super(struct super_block *sb, void *data, int silent)
 {
-        struct inode *root = 0;
-        struct obd_device *obd;
         struct ll_sb_info *sbi;
         char *osc = NULL;
         char *mdc = NULL;
         int err;
-        struct ll_fid rootfid;
-        struct obd_statfs osfs;
-        struct ptlrpc_request *request = NULL;
-        struct ptlrpc_connection *mdc_conn;
-        struct lustre_md md;
-        class_uuid_t uuid;
-
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
-        OBD_ALLOC(sbi, sizeof(*sbi));
+
+        sbi = lustre_init_sbi(sb);
         if (!sbi)
                 RETURN(-ENOMEM);
 
-        INIT_LIST_HEAD(&sbi->ll_conn_chain);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list);
-        sb->u.generic_sbp = sbi;
-#else
-        INIT_HLIST_HEAD(&sbi->ll_orphan_dentry_list);
-        spin_lock_init(&sbi->ll_iostats.fis_lock);
-        ll_s2sbi(sb) = sbi;
-#endif
-        generate_random_uuid(uuid);
-        class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
-
+        sbi->ll_flags |= LL_SBI_READAHEAD;
         ll_options(data, &osc, &mdc, &sbi->ll_flags);
 
         if (!osc) {
                 CERROR("no osc\n");
-                GOTO(out_free, err = -EINVAL);
+                GOTO(out, err = -EINVAL);
         }
 
         if (!mdc) {
                 CERROR("no mdc\n");
-                GOTO(out_free, err = -EINVAL);
+                GOTO(out, err = -EINVAL);
         }
 
-        obd = class_name2obd(mdc);
-        if (!obd) {
-                CERROR("MDC %s: not setup or attached\n", mdc);
-                GOTO(out_free, err = -EINVAL);
-        }
+        err = lustre_common_fill_super(sb, mdc, osc);
+out:
+        if (err)
+                lustre_free_sbi(sb);
 
-        err = obd_connect(&sbi->ll_mdc_conn, obd, &sbi->ll_sb_uuid);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", mdc, err);
-                GOTO(out_free, err);
-        }
+        if (mdc)
+                OBD_FREE(mdc, strlen(mdc) + 1);
+        if (osc)
+                OBD_FREE(osc, strlen(osc) + 1);
 
-        err = obd_statfs(obd, &osfs, jiffies - HZ);
-        if (err)
-                GOTO(out_mdc, err);
+        RETURN(err);
+} /* ll_read_super */
 
-        LASSERT(osfs.os_bsize);
-        sb->s_blocksize = osfs.os_bsize;
-        sb->s_blocksize_bits = log2(osfs.os_bsize);
-        sb->s_magic = LL_SUPER_MAGIC;
-        sb->s_maxbytes = PAGE_CACHE_MAXBYTES;
+void ll_put_super(struct super_block *sb)
+{
+        ENTRY;
 
-        mdc_conn = sbi2mdc(sbi)->cl_import->imp_connection;
+        CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
 
-        obd = class_name2obd(osc);
-        if (!obd) {
-                CERROR("OSC %s: not setup or attached\n", osc);
-                GOTO(out_mdc, err);
-        }
+        lustre_common_put_super(sb);
 
-        err = obd_connect(&sbi->ll_osc_conn, obd, &sbi->ll_sb_uuid);
-        if (err) {
-                CERROR("cannot connect to %s: rc = %d\n", osc, err);
-                GOTO(out_mdc, err);
-        }
+        lustre_free_sbi(sb);
 
-        err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
-        if (err) {
-                CERROR("cannot mds_connect: rc = %d\n", err);
-                GOTO(out_osc, err);
-        }
-        CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id);
-        sbi->ll_rootino = rootfid.id;
+        EXIT;
+} /* ll_put_super */
 
-        sb->s_op = &ll_super_operations;
+int lustre_process_log(struct lustre_mount_data *lmd, char * profile,
+                       struct config_llog_instance *cfg)
+{
+        struct lustre_cfg lcfg;
+        struct portals_cfg pcfg;
+        char * peer = "MDS_PEER_UUID";
+        struct obd_device *obd;
+        struct lustre_handle mdc_conn = {0, };
+        struct obd_export *exp;
+        char * name = "mdc_dev";
+        class_uuid_t uuid;
+        struct obd_uuid mdc_uuid;
+        struct llog_ctxt *ctxt;
+        int rc = 0;
+        int err;
+        ENTRY;
 
-        /* make root inode 
-         * XXX: move this to after cbd setup? */
-        err = mdc_getattr(&sbi->ll_mdc_conn, &rootfid,
-                          OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request);
-        if (err) {
-                CERROR("mdc_getattr failed for root: rc = %d\n", err);
-                GOTO(out_osc, err);
+        generate_random_uuid(uuid);
+        class_uuid_unparse(uuid, &mdc_uuid);
+
+        if (lmd->lmd_local_nid) {
+                PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
+                pcfg.pcfg_nal = lmd->lmd_nal;
+                pcfg.pcfg_nid = lmd->lmd_local_nid;
+                err = kportal_nal_cmd(&pcfg);
+                if (err <0)
+                        GOTO(out, err);
         }
 
-        /* initialize committed transaction callback daemon */
-        spin_lock_init(&sbi->ll_commitcbd_lock);
-        init_waitqueue_head(&sbi->ll_commitcbd_waitq);
-        init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq);
-        sbi->ll_commitcbd_flags = 0;
-        err = ll_commitcbd_setup(sbi);
-        if (err) {
-                CERROR("failed to start commit callback daemon: rc = %d\n",err);
-                ptlrpc_req_finished (request);
-                GOTO(out_lliod, err);
+        if (lmd->lmd_nal == SOCKNAL) {
+                PCFG_INIT(pcfg, NAL_CMD_ADD_AUTOCONN);
+                pcfg.pcfg_nal     = lmd->lmd_nal;
+                pcfg.pcfg_nid     = lmd->lmd_server_nid;
+                pcfg.pcfg_id      = lmd->lmd_server_ipaddr;
+                pcfg.pcfg_misc    = lmd->lmd_port;
+                pcfg.pcfg_size    = 0;
+                pcfg.pcfg_flags   = 0x4; /*share*/
+                err = kportal_nal_cmd(&pcfg);
+                if (err <0)
+                        GOTO(out, err);
         }
 
-        err = mdc_req2lustre_md(request, 0, &sbi->ll_osc_conn, &md);
+        LCFG_INIT(lcfg, LCFG_ADD_UUID, name);
+        lcfg.lcfg_nid = lmd->lmd_server_nid;
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        lcfg.lcfg_nal = lmd->lmd_nal;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_del_conn, err);
+
+        LCFG_INIT(lcfg, LCFG_ATTACH, name);
+        lcfg.lcfg_inlbuf1 = "mdc";
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_del_uuid, err);
+
+        LCFG_INIT(lcfg, LCFG_SETUP, name);
+        lcfg.lcfg_inlbuf1 = lmd->lmd_mds;
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = peer;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_detach, err);
+        
+        obd = class_name2obd(name);
+        if (obd == NULL)
+                GOTO(out_cleanup, err = -EINVAL);
+
+        err = obd_connect(&mdc_conn, obd, &mdc_uuid);
         if (err) {
-                CERROR("failed to understand root inode md: rc = %d\n",err);
-                ptlrpc_req_finished (request);
-                GOTO(out_lliod, err);
+                CERROR("cannot connect to %s: rc = %d\n", lmd->lmd_mds, err);
+                GOTO(out_cleanup, err);
+        }
+        
+        exp = class_conn2export(&mdc_conn);
+        
+        ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
+        rc = class_config_parse_llog(ctxt, profile, cfg);
+        if (rc) {
+                CERROR("class_config_parse_llog failed: rc = %d\n", rc);
         }
 
-        LASSERT(sbi->ll_rootino != 0);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        root = iget4(sb, sbi->ll_rootino, NULL, &md);
-#else
-        root = ll_iget(sb, sbi->ll_rootino, &md);
-#endif
+        err = obd_disconnect(exp, 0);
+
+out_cleanup:
+        LCFG_INIT(lcfg, LCFG_CLEANUP, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_detach:
+        LCFG_INIT(lcfg, LCFG_DETACH, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_del_uuid:
+        LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        err = class_process_config(&lcfg);
+
+out_del_conn:
+        if (lmd->lmd_nal == SOCKNAL) {
+                PCFG_INIT(pcfg, NAL_CMD_DEL_AUTOCONN);
+                pcfg.pcfg_nal     = lmd->lmd_nal;
+                pcfg.pcfg_nid     = lmd->lmd_server_nid;
+                pcfg.pcfg_id      = lmd->lmd_server_ipaddr;
+                pcfg.pcfg_flags   = 1; /*share*/
+                err = kportal_nal_cmd(&pcfg);
+                if (err <0)
+                        GOTO(out, err);
+        }
+out:
+        if (rc == 0)
+                rc = err;
+        
+        RETURN(rc);
+}
 
-        ptlrpc_req_finished(request);
+int lustre_fill_super(struct super_block *sb, void *data, int silent)
+{
+        struct lustre_mount_data * lmd = data;
+        struct ll_sb_info *sbi;
+        char *osc = NULL;
+        char *mdc = NULL;
+        int err;
+        ENTRY;
 
-        if (root == NULL || is_bad_inode(root)) {
-                /* XXX might need iput() for bad inode */
-                CERROR("lustre_lite: bad iget4 for root\n");
-                GOTO(out_cbd, err = -EBADF);
+        CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
+        sbi = lustre_init_sbi(sb);
+        if (!sbi)
+                RETURN(-ENOMEM);
+
+        sbi->ll_flags |= LL_SBI_READAHEAD;
+
+        if (lmd->lmd_profile) {
+                struct lustre_profile *lprof;
+                struct config_llog_instance cfg;
+                int len;
+
+                if (!lmd->lmd_mds) {
+                        CERROR("no mds name\n");
+                        GOTO(out_free, err = -EINVAL);
+                }
+
+                OBD_ALLOC(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
+                if (sbi->ll_lmd == NULL) 
+                        GOTO(out_free, err = -ENOMEM);
+                memcpy(sbi->ll_lmd, lmd, sizeof(*lmd));
+
+                /* generate a string unique to this super, let's try
+                 the address of the super itself.*/
+                len = (sizeof(sb) * 2) + 1; 
+                OBD_ALLOC(sbi->ll_instance, len);
+                if (sbi->ll_instance == NULL) 
+                        GOTO(out_free, err = -ENOMEM);
+                sprintf(sbi->ll_instance, "%p", sb);
+
+                cfg.cfg_instance = sbi->ll_instance;
+                cfg.cfg_uuid = sbi->ll_sb_uuid;
+                cfg.cfg_local_nid = lmd->lmd_local_nid;
+                err = lustre_process_log(lmd, lmd->lmd_profile, &cfg);
+                if (err < 0) {
+                        CERROR("Unable to process log: %s\n", lmd->lmd_profile);
+
+                        GOTO(out_free, err);
+                }
+
+                lprof = class_get_profile(lmd->lmd_profile);
+                if (lprof == NULL) {
+                        CERROR("No profile found: %s\n", lmd->lmd_profile);
+                        GOTO(out_free, err = -EINVAL);
+                }
+                if (osc)
+                        OBD_FREE(osc, strlen(osc) + 1);
+                OBD_ALLOC(osc, strlen(lprof->lp_osc) + 
+                          strlen(sbi->ll_instance) + 2);
+                sprintf(osc, "%s-%s", lprof->lp_osc, sbi->ll_instance);
+
+                if (mdc)
+                        OBD_FREE(mdc, strlen(mdc) + 1);
+                OBD_ALLOC(mdc, strlen(lprof->lp_mdc) + 
+                          strlen(sbi->ll_instance) + 2);
+                sprintf(mdc, "%s-%s", lprof->lp_mdc, sbi->ll_instance);
         }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        /* initialize the pagecache writeback thread */
-        err = lliod_start(sbi, root);
-        if (err) {
-                CERROR("failed to start lliod: rc = %d\n",err);
-                GOTO(out_root, sb = NULL);
+        if (!osc) {
+                CERROR("no osc\n");
+                GOTO(out_free, err = -EINVAL);
         }
-#endif
-        sb->s_root = d_alloc_root(root);
 
-        if (proc_lustre_fs_root) {
-                err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
-                                                  osc, mdc);
-                if (err < 0)
-                        CERROR("could not register mount in /proc/lustre");
+        if (!mdc) {
+                CERROR("no mdc\n");
+                GOTO(out_free, err = -EINVAL);
         }
+        
+        err = lustre_common_fill_super(sb, mdc, osc);
+        
+        if (err)
+                GOTO(out_free, err);
 
 out_dev:
         if (mdc)
@@ -287,113 +570,113 @@ out_dev:
 
         RETURN(err);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-out_root:
-        iput(root);
-#endif
-out_cbd:
-        ll_commitcbd_cleanup(sbi);
-out_lliod:
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        lliod_stop(sbi);
-#endif
-out_osc:
-        obd_disconnect(&sbi->ll_osc_conn, 0);
-out_mdc:
-        obd_disconnect(&sbi->ll_mdc_conn, 0);
 out_free:
-        lprocfs_unregister_mountpoint(sbi);
-        OBD_FREE(sbi, sizeof(*sbi));
+        if (sbi->ll_lmd) {
+                int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1;
+                int err;
+
+                if (sbi->ll_instance != NULL) {
+                        char * cln_prof;
+                        struct config_llog_instance cfg;
+
+                        cfg.cfg_instance = sbi->ll_instance;
+                        cfg.cfg_uuid = sbi->ll_sb_uuid;
+
+                        OBD_ALLOC(cln_prof, len);
+                        sprintf(cln_prof, "%s-clean", sbi->ll_lmd->lmd_profile);
+
+                        err = lustre_process_log(sbi->ll_lmd, cln_prof, &cfg);
+                        if (err < 0) 
+                                CERROR("Unable to process log: %s\n", cln_prof);
+                        OBD_FREE(cln_prof, len);
+                        OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance)+ 1);
+                }
+                OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
+        }
+        lustre_free_sbi(sb);
 
         goto out_dev;
-} /* ll_read_super */
+} /* lustre_fill_super */
 
-void ll_put_super(struct super_block *sb)
+void lustre_put_super(struct super_block *sb)
 {
         struct ll_sb_info *sbi = ll_s2sbi(sb);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn);
-        struct list_head *tmp, *next;
-#else
-        struct hlist_node *tmp, *next;
-#endif
-        struct ll_fid rootfid;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
-        list_del(&sbi->ll_conn_chain);
-        ll_commitcbd_cleanup(sbi);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        lliod_stop(sbi);
-#endif
-        obd_disconnect(&sbi->ll_osc_conn, 0);
 
-        /* NULL request to force sync on the MDS, and get the last_committed
-         * value to flush remaining RPCs from the sending queue on client.
-         *
-         * XXX This should be an mdc_sync() call to sync the whole MDS fs,
-         *     which we can call for other reasons as well.
-         */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        if (!obd->obd_no_recov)
-#endif
-                mdc_getstatus(&sbi->ll_mdc_conn, &rootfid);
+        lustre_common_put_super(sb);
 
-        lprocfs_unregister_mountpoint(sbi);
-        if (sbi->ll_proc_root) {
-                lprocfs_remove(sbi->ll_proc_root);
-                sbi->ll_proc_root = NULL;
-        }
+        if (sbi->ll_lmd != NULL) {
+                char * cln_prof;
+                int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1;
+                int err;
+                struct config_llog_instance cfg;
 
-        obd_disconnect(&sbi->ll_mdc_conn, 0);
+                cfg.cfg_instance = sbi->ll_instance;
+                cfg.cfg_uuid = sbi->ll_sb_uuid;
 
-        spin_lock(&dcache_lock);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) {
-                struct dentry *dentry = list_entry(tmp, struct dentry, d_hash);
-                shrink_dcache_parent(dentry);
-        }
-#else
-        hlist_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) {
-                struct dentry *dentry = hlist_entry(tmp, struct dentry, d_hash);
-                shrink_dcache_parent(dentry);
+                OBD_ALLOC(cln_prof, len);
+                sprintf(cln_prof, "%s-clean", sbi->ll_lmd->lmd_profile);
+
+                err = lustre_process_log(sbi->ll_lmd, cln_prof, &cfg);
+                if (err < 0)
+                        CERROR("Unable to process log: %s\n", cln_prof);
+
+                OBD_FREE(cln_prof, len);
+                OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
+                OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1);
         }
-#endif
-        spin_unlock(&dcache_lock);
 
-        OBD_FREE(sbi, sizeof(*sbi));
+        lustre_free_sbi(sb);
 
         EXIT;
-} /* ll_put_super */
+} /* lustre_put_super */
+
+
+struct inode *ll_inode_from_lock(struct ldlm_lock *lock)
+{
+        struct inode *inode;
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+        if (lock->l_ast_data)
+                inode = igrab(lock->l_ast_data);
+        else
+                inode = NULL;
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+        return inode;
+}
+
+static int null_if_equal(struct ldlm_lock *lock, void *data)
+{
+        if (data == lock->l_ast_data)
+                lock->l_ast_data = NULL;
+
+        if (lock->l_req_mode != lock->l_granted_mode)
+                return LDLM_ITER_STOP;
+
+        return LDLM_ITER_CONTINUE;
+}
 
 void ll_clear_inode(struct inode *inode)
 {
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct ll_fid fid;
         struct ll_inode_info *lli = ll_i2info(inode);
-        int rc;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
                inode->i_generation, inode);
-        rc = ll_mdc_cancel_unused(&sbi->ll_mdc_conn, inode,
-                                  LDLM_FL_WARN | LDLM_FL_NO_CALLBACK, inode);
-        if (rc < 0) {
-                CERROR("ll_mdc_cancel_unused: %d\n", rc);
-                /* XXX FIXME do something dramatic */
-        }
 
-        if (atomic_read(&inode->i_count) != 0)
-                CERROR("clearing in-use inode %lu: count = %d\n",
-                       inode->i_ino, atomic_read(&inode->i_count));
+        ll_inode2fid(&fid, inode);
+        clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &(ll_i2info(inode)->lli_flags));
+        mdc_change_cbdata(sbi->ll_mdc_exp, &fid, null_if_equal, inode);
+
+        if (lli->lli_smd)
+                obd_change_cbdata(sbi->ll_osc_exp, lli->lli_smd,
+                                  null_if_equal, inode);
 
         if (lli->lli_smd) {
-                rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd,
-                                       LDLM_FL_WARN, inode);
-                if (rc < 0) {
-                        CERROR("obd_cancel_unused: %d\n", rc);
-                        /* XXX FIXME do something dramatic */
-                }
-                obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd);
+                obd_free_memmd(sbi->ll_osc_exp, &lli->lli_smd);
                 lli->lli_smd = NULL;
         }
 
@@ -406,139 +689,6 @@ void ll_clear_inode(struct inode *inode)
         EXIT;
 }
 
-#if 0
-static void ll_delete_inode(struct inode *inode)
-{
-        ENTRY;
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu(%p)\n", inode->i_ino, inode);
-        if (S_ISREG(inode->i_mode)) {
-                int err;
-                struct obdo *oa;
-                struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-
-                /* mcreate with no open */
-                if (!lsm)
-                        GOTO(out, 0);
-
-                if (lsm->lsm_object_id == 0) {
-                        CERROR("This really happens\n");
-                        /* No obdo was ever created */
-                        GOTO(out, 0);
-                }
-
-                oa = obdo_alloc();
-                if (oa == NULL)
-                        GOTO(out, -ENOMEM);
-
-                oa->o_id = lsm->lsm_object_id;
-                oa->o_valid = OBD_MD_FLID;
-                obdo_from_inode(oa, inode, OBD_MD_FLTYPE);
-
-                err = obd_destroy(ll_i2obdconn(inode), oa, lsm, NULL);
-                obdo_free(oa);
-                if (err)
-                        CDEBUG(D_INODE,
-                               "inode %lu obd_destroy objid "LPX64" error %d\n",
-                               inode->i_ino, lsm->lsm_object_id, err);
-        }
-out:
-        clear_inode(inode);
-        EXIT;
-}
-#endif
-
-/* like inode_setattr, but doesn't mark the inode dirty */
-int ll_attr2inode(struct inode *inode, struct iattr *attr, int trunc)
-{
-        unsigned int ia_valid = attr->ia_valid;
-        int error = 0;
-
-        if ((ia_valid & ATTR_SIZE) && trunc) {
-                if (attr->ia_size > ll_file_maxbytes(inode)) {
-                        error = -EFBIG;
-                        goto out;
-                }
-                error = vmtruncate(inode, attr->ia_size);
-                if (error)
-                        goto out;
-        } else if (ia_valid & ATTR_SIZE)
-                inode->i_size = attr->ia_size;
-
-        if (ia_valid & ATTR_UID)
-                inode->i_uid = attr->ia_uid;
-        if (ia_valid & ATTR_GID)
-                inode->i_gid = attr->ia_gid;
-        if (ia_valid & ATTR_ATIME)
-                inode->i_atime = attr->ia_atime;
-        if (ia_valid & ATTR_MTIME)
-                inode->i_mtime = attr->ia_mtime;
-        if (ia_valid & ATTR_CTIME)
-                inode->i_ctime = attr->ia_ctime;
-        if (ia_valid & ATTR_MODE) {
-                inode->i_mode = attr->ia_mode;
-                if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
-                        inode->i_mode &= ~S_ISGID;
-        }
-out:
-        return error;
-}
-
-int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc)
-{
-        struct ptlrpc_request *request = NULL;
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        int err = 0;
-        ENTRY;
-
-        /* change incore inode */
-        err = ll_attr2inode(inode, attr, do_trunc);
-        if (err)
-                RETURN(err);
-
-        /* Don't send size changes to MDS to avoid "fast EA" problems, and
-         * also avoid a pointless RPC (we get file size from OST anyways).
-         */
-        attr->ia_valid &= ~ATTR_SIZE;
-        if (attr->ia_valid) {
-                struct mdc_op_data op_data;
-
-                ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
-                err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
-                                  attr, NULL, 0, NULL, 0, &request);
-                if (err)
-                        CERROR("mdc_setattr fails: err = %d\n", err);
-
-                ptlrpc_req_finished(request);
-                if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
-                        struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-                        struct obdo oa;
-                        int err2;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                        CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
-                               inode->i_ino, attr->ia_mtime);
-                        oa.o_mtime = attr->ia_mtime;
-#else
-                        CDEBUG(D_INODE, "set mtime on OST inode %lu to "
-                               LPU64"\n", inode->i_ino, 
-                               ll_ts2u64(&attr->ia_mtime));
-                        oa.o_mtime = ll_ts2u64(&attr->ia_mtime);
-#endif
-                        oa.o_id = lsm->lsm_object_id;
-                        oa.o_mode = S_IFREG;
-                        oa.o_valid = OBD_MD_FLID |OBD_MD_FLTYPE |OBD_MD_FLMTIME;
-                        err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
-                        if (err2) {
-                                CERROR("obd_setattr fails: rc=%d\n", err);
-                                if (!err)
-                                        err = err2;
-                        }
-                }
-        }
-
-        RETURN(err);
-}
-
 /* If this inode has objects allocated to it (lsm != NULL), then the OST
  * object(s) determine the file size and mtime.  Otherwise, the MDS will
  * keep these values until such a time that objects are allocated for it.
@@ -552,24 +702,18 @@ int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc)
  * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE
  * at the same time.
  */
-#define OST_ATTR (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME | \
-                  ATTR_ATIME | ATTR_ATIME_SET | ATTR_SIZE)
 int ll_setattr_raw(struct inode *inode, struct iattr *attr)
 {
         struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct ptlrpc_request *request = NULL;
         struct mdc_op_data op_data;
-        time_t now = LTIME_S(CURRENT_TIME);
         int ia_valid = attr->ia_valid;
         int rc = 0;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_SETATTR);
-#endif
 
         if (ia_valid & ATTR_SIZE) {
                 if (attr->ia_size > ll_file_maxbytes(inode)) {
@@ -581,35 +725,42 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
         }
 
+        /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
+        if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
+                if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
+                        RETURN(-EPERM);
+        }
+
         /* We mark all of the fields "set" so MDS/OST does not re-set them */
         if (attr->ia_valid & ATTR_CTIME) {
-                attr->ia_ctime = now;
+                attr->ia_ctime = CURRENT_TIME;
                 attr->ia_valid |= ATTR_CTIME_SET;
         }
         if (!(ia_valid & ATTR_ATIME_SET) && (attr->ia_valid & ATTR_ATIME)) {
-                attr->ia_atime = now;
+                attr->ia_atime = CURRENT_TIME;
                 attr->ia_valid |= ATTR_ATIME_SET;
         }
         if (!(ia_valid & ATTR_MTIME_SET) && (attr->ia_valid & ATTR_MTIME)) {
-                attr->ia_mtime = now;
+                attr->ia_mtime = CURRENT_TIME;
                 attr->ia_valid |= ATTR_MTIME_SET;
         }
 
         if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",
-                       attr->ia_mtime, attr->ia_ctime, now);
+                       LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
+                       LTIME_S(CURRENT_TIME));
         if (lsm)
                 attr->ia_valid &= ~ATTR_SIZE;
 
         /* If only OST attributes being set on objects, don't do MDS RPC.
          * In that case, we need to check permissions and update the local
          * inode ourselves so we can call obdo_from_inode() always. */
-        if (ia_valid & (lsm ? ~(OST_ATTR | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) {
+        if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN | ATTR_RAW) : ~0)) {
                 struct lustre_md md;
                 ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
 
-                rc = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
-                                  attr, NULL, 0, NULL, 0, &request);
+                rc = mdc_setattr(sbi->ll_mdc_exp, &op_data,
+                                 attr, NULL, 0, NULL, 0, &request);
 
                 if (rc) {
                         ptlrpc_req_finished(request);
@@ -618,15 +769,19 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                         RETURN(rc);
                 }
 
-                rc = mdc_req2lustre_md(request, 0, &sbi->ll_osc_conn, &md);
+                rc = mdc_req2lustre_md(request, 0, sbi->ll_osc_exp, &md);
                 if (rc) {
                         ptlrpc_req_finished(request);
                         RETURN(rc);
                 }
+
+                /* Won't invoke vmtruncate as we already cleared ATTR_SIZE,
+                 * but needed to set timestamps backwards on utime. */
+                inode_setattr(inode, attr);
                 ll_update_inode(inode, md.body, md.lsm);
                 ptlrpc_req_finished(request);
 
-                if (!md.lsm || !S_ISREG(inode->i_mode)) {
+                if (!lsm || !S_ISREG(inode->i_mode)) {
                         CDEBUG(D_INODE, "no lsm: not setting attrs on OST\n");
                         RETURN(0);
                 }
@@ -639,7 +794,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                         /* from sys_utime() */
                         if (!(ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))) {
                                 if (current->fsuid != inode->i_uid &&
-                                    (rc = permission(inode, MAY_WRITE)) != 0)
+                                    (rc = ll_permission(inode, MAY_WRITE, NULL)) != 0)
                                         RETURN(rc);
                         } else {
 				/* from inode_change_ok() */
@@ -653,40 +808,39 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                 inode_setattr(inode, attr);
         }
 
+        /* We really need to get our PW lock before we change inode->i_size.
+         * If we don't we can race with other i_size updaters on our node, like
+         * ll_file_read.  We can also race with i_size propogation to other
+         * nodes through dirtying and writeback of final cached pages.  This
+         * last one is especially bad for racing o_append users on other 
+         * nodes. */
         if (ia_valid & ATTR_SIZE) {
                 struct ldlm_extent extent = { .start = attr->ia_size,
                                               .end = OBD_OBJECT_EOF };
                 struct lustre_handle lockh = { 0 };
-                int err;
+                int err, ast_flags = 0;
+                /* XXX when we fix the AST intents to pass the discard-range
+                 * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA
+                 * XXX here. */
+                if (attr->ia_size == 0)
+                        ast_flags = LDLM_AST_DISCARD_DATA;
 
-                /* Writeback uses inode->i_size to determine how far out
-                 * its cached pages go.  ll_truncate gets a PW lock, canceling
-                 * our lock, _after_ it has updated i_size.  this can confuse
-                 *
-                 * We really need to get our PW lock before we change
-                 * inode->i_size.  If we don't we can race with other
-                 * i_size updaters on our node, like ll_file_read.  We
-                 * can also race with i_size propogation to other
-                 * nodes through dirtying and writeback of final cached
-                 * pages.  This last one is especially bad for racing
-                 * o_append users on other nodes. */
                 /* bug 1639: avoid write/truncate i_sem/DLM deadlock */
                 LASSERT(atomic_read(&inode->i_sem.count) <= 0);
                 up(&inode->i_sem);
                 rc = ll_extent_lock_no_validate(NULL, inode, lsm, LCK_PW,
-                                                 &extent, &lockh);
+                                                &extent, &lockh, ast_flags);
                 down(&inode->i_sem);
-                if (rc != ELDLM_OK) {
-                        if (rc > 0)
-                                RETURN(-ENOLCK);
+                if (rc != ELDLM_OK)
                         RETURN(rc);
-                }
 
                 rc = vmtruncate(inode, attr->ia_size);
                 if (rc == 0)
-                        set_bit(LLI_F_HAVE_SIZE_LOCK,
+                        set_bit(LLI_F_HAVE_OST_SIZE_LOCK,
                                 &ll_i2info(inode)->lli_flags);
 
+                //ll_try_done_writing(inode);
+
                 /* unlock now as we don't mind others file lockers racing with
                  * the mds updates below? */
                 err = ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh);
@@ -699,12 +853,12 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                 struct obdo oa;
 
                 CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
-                       inode->i_ino, attr->ia_mtime);
+                       inode->i_ino, LTIME_S(attr->ia_mtime));
                 oa.o_id = lsm->lsm_object_id;
                 oa.o_valid = OBD_MD_FLID;
                 obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
                                             OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-                rc = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
+                rc = obd_setattr(sbi->ll_osc_exp, &oa, lsm, NULL);
                 if (rc)
                         CERROR("obd_setattr fails: rc=%d\n", rc);
         }
@@ -713,13 +867,8 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
 
 int ll_setattr(struct dentry *de, struct iattr *attr)
 {
-        int rc = inode_change_ok(de->d_inode, attr);
-        CDEBUG(D_VFSTRACE, "VFS Op:name=%s\n", de->d_name.name);
-        if (rc)
-                return rc;
-
-        lprocfs_counter_incr(ll_i2sbi(de->d_inode)->ll_stats, LPROC_LL_SETATTR);
-        return ll_inode_setattr(de->d_inode, attr, 1);
+        LBUG(); /* code is unused, but leave this in case of VFS changes */
+        RETURN(-ENOSYS);
 }
 
 int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
@@ -730,7 +879,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
         int rc;
         ENTRY;
 
-        rc = obd_statfs(class_conn2obd(&sbi->ll_mdc_conn), osfs, max_age);
+        rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age);
         if (rc) {
                 CERROR("mdc_statfs fails: rc = %d\n", rc);
                 RETURN(rc);
@@ -739,7 +888,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
         CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
                osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
 
-        rc = obd_statfs(class_conn2obd(&sbi->ll_osc_conn), &obd_osfs, max_age);
+        rc = obd_statfs(class_exp2obd(sbi->ll_osc_exp), &obd_osfs, max_age);
         if (rc) {
                 CERROR("obd_statfs fails: rc = %d\n", rc);
                 RETURN(rc);
@@ -802,11 +951,10 @@ int ll_statfs(struct super_block *sb, struct kstatfs *sfs)
 
 void dump_lsm(int level, struct lov_stripe_md *lsm)
 {
-        CDEBUG(level, "objid "LPX64", maxbytes "LPX64", magic %#08x, "
-               "stripe_size %#08x, offset %u, stripe_count %u\n",
+        CDEBUG(level, "objid "LPX64", maxbytes "LPX64", magic 0x%08X, "
+               "stripe_size %u, stripe_count %u\n",
                lsm->lsm_object_id, lsm->lsm_maxbytes, lsm->lsm_magic,
-               lsm->lsm_stripe_size, lsm->lsm_stripe_offset,
-               lsm->lsm_stripe_count);
+               lsm->lsm_stripe_size, lsm->lsm_stripe_count);
 }
 
 void ll_update_inode(struct inode *inode, struct mds_body *body,
@@ -832,13 +980,16 @@ void ll_update_inode(struct inode *inode, struct mds_body *body,
                                 LBUG();
                         }
                 }
+                if (lli->lli_smd != lsm)
+                        obd_free_memmd(ll_i2obdexp(inode), &lsm);
         }
 
         if (body->valid & OBD_MD_FLID)
                 inode->i_ino = body->ino;
         if (body->valid & OBD_MD_FLATIME)
                 LTIME_S(inode->i_atime) = body->atime;
-        if (body->valid & OBD_MD_FLMTIME) {
+        if (body->valid & OBD_MD_FLMTIME &&
+            body->mtime > LTIME_S(inode->i_mtime)) {
                 CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %u\n",
                        inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
                 LTIME_S(inode->i_mtime) = body->mtime;
@@ -864,12 +1015,15 @@ void ll_update_inode(struct inode *inode, struct mds_body *body,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
                 inode->i_rdev = body->rdev;
 #else
-                inode->i_rdev = to_kdev_t(body->rdev);
+                inode->i_rdev = old_encode_dev(body->rdev);
 #endif
         if (body->valid & OBD_MD_FLSIZE)
                 inode->i_size = body->size;
         if (body->valid & OBD_MD_FLBLOCKS)
                 inode->i_blocks = body->blocks;
+
+        if (body->valid & OBD_MD_FLSIZE)
+                set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags);
 }
 
 void ll_read_inode2(struct inode *inode, void *opaque)
@@ -916,19 +1070,119 @@ void ll_read_inode2(struct inode *inode, void *opaque)
                                    kdev_t_to_nr(inode->i_rdev));
 #else
                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
+                
+                lli->ll_save_ifop = inode->i_fop;
+                if (S_ISCHR(inode->i_mode)) {
+                        inode->i_fop = &ll_special_chr_inode_fops;                                                         
+                }else if (S_ISBLK(inode->i_mode)) {
+                        inode->i_fop = &ll_special_blk_inode_fops; 
+                }else if (S_ISFIFO(inode->i_mode)){
+                        inode->i_fop = &ll_special_fifo_inode_fops;
+                }else if (S_ISSOCK(inode->i_mode)){ 
+                        inode->i_fop = &ll_special_sock_inode_fops;
+                }                                               
+                inode->i_fop->owner = lli->ll_save_ifop->owner;
 #endif
                 EXIT;
         }
 }
 
-int it_disposition(struct lookup_intent *it, int flag)
+int ll_iocontrol(struct inode *inode, struct file *file,
+                        unsigned int cmd, unsigned long arg)
 {
-        return it->it_disposition & flag;
-}
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct ptlrpc_request *req = NULL;
+        int rc, flags = 0;
+        ENTRY;
 
-void it_set_disposition(struct lookup_intent *it, int flag)
-{
-        it->it_disposition |= flag;
+        switch(cmd) {
+        case EXT3_IOC_GETFLAGS: {
+                struct ll_fid fid;
+                unsigned long valid = OBD_MD_FLFLAGS;
+                struct mds_body *body;
+
+                ll_inode2fid(&fid, inode);
+                rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, 0, &req);
+                if (rc) {
+                        CERROR("failure %d inode %lu\n", rc, inode->i_ino);
+                        RETURN(-abs(rc));
+                }
+
+                body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+
+                if (body->flags & S_APPEND)
+                        flags |= EXT3_APPEND_FL;
+                if (body->flags & S_IMMUTABLE)
+                        flags |= EXT3_IMMUTABLE_FL;
+                if (body->flags & S_NOATIME)
+                        flags |= EXT3_NOATIME_FL;
+
+                ptlrpc_req_finished (req);
+
+                RETURN(put_user(flags, (int *)arg));
+        }
+        case EXT3_IOC_SETFLAGS: {
+                struct mdc_op_data op_data;
+                struct iattr attr;
+                struct obdo *oa;
+                struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
+
+                if (get_user(flags, (int *)arg))
+                        RETURN(-EFAULT);
+
+                oa = obdo_alloc();
+                if (!oa)
+                        RETURN(-ENOMEM);
+
+                ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
+
+                memset(&attr, 0x0, sizeof(attr));
+                attr.ia_attr_flags = flags;
+                attr.ia_valid |= ATTR_ATTR_FLAG;
+
+                rc = mdc_setattr(sbi->ll_mdc_exp, &op_data,
+                                 &attr, NULL, 0, NULL, 0, &req);
+                if (rc) {
+                        ptlrpc_req_finished(req);
+                        if (rc != -EPERM && rc != -EACCES)
+                                CERROR("mdc_setattr fails: rc = %d\n", rc);
+                        obdo_free(oa);
+                        RETURN(rc);
+                }
+                ptlrpc_req_finished(req);
+
+                oa->o_id = lsm->lsm_object_id;
+                oa->o_flags = flags;
+                oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS;
+
+                rc = obd_setattr(sbi->ll_osc_exp, oa, lsm, NULL);
+                obdo_free(oa);
+                if (rc) {
+                        if (rc != -EPERM && rc != -EACCES)
+                                CERROR("mdc_setattr fails: rc = %d\n", rc);
+                        RETURN(rc);
+                }
+
+                if (flags & EXT3_APPEND_FL)
+                        inode->i_flags |= S_APPEND;
+                else
+                        inode->i_flags &= ~S_APPEND;
+                if (flags & EXT3_IMMUTABLE_FL)
+                        inode->i_flags |= S_IMMUTABLE;
+                else
+                        inode->i_flags &= ~S_IMMUTABLE;
+                if (flags & EXT3_NOATIME_FL)
+                        inode->i_flags |= S_NOATIME;
+                else
+                        inode->i_flags &= ~S_NOATIME;
+
+                RETURN(0);
+        }
+        default:
+                RETURN(-ENOSYS);
+        }
+
+        RETURN(0);
 }
 
 void ll_umount_begin(struct super_block *sb)
@@ -939,20 +1193,27 @@ void ll_umount_begin(struct super_block *sb)
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:\n");
 
-        obd = class_conn2obd(&sbi->ll_mdc_conn);
+        obd = class_exp2obd(sbi->ll_mdc_exp);
         if (obd == NULL) {
                 CERROR("Invalid MDC connection handle "LPX64"\n",
-                       sbi->ll_mdc_conn.cookie);
+                       sbi->ll_mdc_exp->exp_handle.h_cookie);
                 EXIT;
                 return;
         }
         obd->obd_no_recov = 1;
-        obd_iocontrol(IOC_OSC_SET_ACTIVE, &sbi->ll_mdc_conn, sizeof ioc_data,
+        obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_mdc_exp, sizeof ioc_data,
                       &ioc_data, NULL);
 
-        obd = class_conn2obd(&sbi->ll_osc_conn);
+        obd = class_exp2obd(sbi->ll_osc_exp);
+        if (obd == NULL) {
+                CERROR("Invalid LOV connection handle "LPX64"\n",
+                       sbi->ll_osc_exp->exp_handle.h_cookie);
+                EXIT;
+                return;
+        }
+
         obd->obd_no_recov = 1;
-        obd_iocontrol(IOC_OSC_SET_ACTIVE, &sbi->ll_osc_conn, sizeof ioc_data,
+        obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_osc_exp, sizeof ioc_data,
                       &ioc_data, NULL);
 
         /* Really, we'd like to wait until there are no requests outstanding,
@@ -963,3 +1224,30 @@ void ll_umount_begin(struct super_block *sb)
 
         EXIT;
 }
+
+int ll_prep_inode(struct obd_export *exp, struct inode **inode,
+                  struct ptlrpc_request *req, int offset,struct super_block *sb)
+{
+        struct lustre_md md;
+        int rc = 0;
+
+        rc = mdc_req2lustre_md(req, offset, exp, &md);
+        if (rc)
+                RETURN(rc);
+
+        if (*inode) {
+                ll_update_inode(*inode, md.body, md.lsm);
+        } else {
+                LASSERT(sb);
+                *inode = ll_iget(sb, md.body->ino, &md);
+                if (*inode == NULL || is_bad_inode(*inode)) {
+                        /* free the lsm if we allocated one above */
+                        if (md.lsm != NULL)
+                                obd_free_memmd(exp, &md.lsm);
+                        rc = -ENOMEM;
+                        CERROR("new_inode -fatal: rc %d\n", rc);
+                }
+        }
+
+        RETURN(rc);
+}
diff --git a/lustre/llite/llite_nfs.c b/lustre/llite/llite_nfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..f3b7fc3cb088d9a2d0e0f35dce605fd42aebcf28
--- /dev/null
+++ b/lustre/llite/llite_nfs.c
@@ -0,0 +1,179 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   NFS export of Lustre Light File System 
+ *
+ *   Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+#include <linux/lustre_lite.h>
+#include "llite_internal.h"
+
+__u32 get_uuid2int(const char *name, int len)
+{
+        __u32 key0 = 0x12a3fe2d, key1 = 0x37abe8f9;
+        while (len--) {
+                __u32 key = key1 + (key0 ^ (*name++ * 7152373));
+                if (key & 0x80000000) key -= 0x7fffffff;
+                key1 = key0;
+                key0 = key;
+        }
+        return (key0 << 1);
+}
+
+static struct inode * search_inode_for_lustre(struct super_block *sb,
+                                              unsigned long ino,
+                                              unsigned long generation,
+                                              int mode)
+{
+        struct ptlrpc_request *req = NULL;
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct ll_fid fid;
+        unsigned long valid = 0;
+        int eadatalen = 0, rc;
+        struct inode *inode = NULL;
+
+        inode = ILOOKUP(sb, ino, NULL, NULL);
+
+        if (inode)
+                return inode;
+        if (S_ISREG(mode)) {
+                eadatalen = obd_size_diskmd(sbi->ll_osc_exp, NULL);
+                valid |= OBD_MD_FLEASIZE;
+        }
+        fid.id = (__u64)ino;
+        fid.generation = generation;
+        fid.f_type = mode;
+
+        rc = mdc_getattr(sbi->ll_mdc_exp, &fid, valid, eadatalen, &req);
+        if (rc) {
+                CERROR("failure %d inode %lu\n", rc, ino);
+                return ERR_PTR(rc);
+        }
+
+        rc = ll_prep_inode(sbi->ll_osc_exp, &inode, req, 0, sb);
+        if (rc) {
+                ptlrpc_req_finished(req);
+                return ERR_PTR(rc);
+        }
+        ptlrpc_req_finished(req);
+
+        return inode;
+}
+
+extern struct dentry_operations ll_d_ops;
+
+static struct dentry *ll_iget_for_nfs(struct super_block *sb, unsigned long ino,
+                                      __u32 generation, umode_t mode)
+{                                      
+        struct inode *inode;      
+        struct dentry *result;
+        struct list_head *lp;
+
+        if (ino == 0)
+                return ERR_PTR(-ESTALE);
+
+        inode = search_inode_for_lustre(sb, ino, generation, mode);
+        if (IS_ERR(inode)) {
+                return ERR_PTR(PTR_ERR(inode));
+        }
+        if (is_bad_inode(inode) 
+            || (generation && inode->i_generation != generation)
+            ){
+                /* we didn't find the right inode.. */
+              CERROR(" Inode %lu, Bad count: %lu %d or version  %u %u\n",
+                        inode->i_ino, 
+                        (unsigned long)inode->i_nlink, 
+                        atomic_read(&inode->i_count), 
+                        inode->i_generation, 
+                        generation);
+                iput(inode);
+                return ERR_PTR(-ESTALE);
+        }
+        
+        /* now to find a dentry.
+         * If possible, get a well-connected one
+         */
+        spin_lock(&dcache_lock);
+        for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
+                result = list_entry(lp,struct dentry, d_alias);
+                if (!(result->d_flags & DCACHE_DISCONNECTED)) {
+                        dget_locked(result);
+                        result->d_vfs_flags |= DCACHE_REFERENCED;
+                        spin_unlock(&dcache_lock);
+                        iput(inode);
+                        return result;
+                }
+        }
+        spin_unlock(&dcache_lock);
+        result = d_alloc_root(inode);
+        if (result == NULL) {
+                iput(inode);
+                return ERR_PTR(-ENOMEM);
+        }
+        result->d_flags |= DCACHE_DISCONNECTED;
+        
+        ll_set_dd(result);
+        result->d_op = &ll_d_ops;
+        return result;
+}
+
+struct dentry *ll_fh_to_dentry(struct super_block *sb, __u32 *data, int len,
+                               int fhtype, int parent)
+{
+        switch (fhtype) {
+                case 2:
+                        if (len < 5)
+                                break;
+                        if (parent)
+                                return ll_iget_for_nfs(sb, data[3], 0, data[4]);
+                case 1:
+                        if (len < 3)
+                                break;
+                        if (parent)
+                                break;
+                        return ll_iget_for_nfs(sb, data[0], data[1], data[2]);
+                default: break;
+        }
+        return ERR_PTR(-EINVAL);
+}
+
+int ll_dentry_to_fh(struct dentry *dentry, __u32 *datap, int *lenp,
+                    int need_parent)
+{
+        if (*lenp < 3)
+                return 255;
+        *datap++ = dentry->d_inode->i_ino;
+        *datap++ = dentry->d_inode->i_generation;
+        *datap++ = (__u32)(S_IFMT & dentry->d_inode->i_mode);
+
+        if (*lenp == 3 || S_ISDIR(dentry->d_inode->i_mode)) {
+                *lenp = 3;
+                return 1;
+        }
+        if (dentry->d_parent) { 
+                *datap++ = dentry->d_parent->d_inode->i_ino;
+                *datap++ = (__u32)(S_IFMT & dentry->d_parent->d_inode->i_mode);
+         
+                *lenp = 5;
+                return 2;
+        }
+        *lenp = 3;
+        return 1;
+}
diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c
index 8908d44acd5cbd75bc2de10136daf46e24044a79..6954af870dffa458312fb9bdc228ce91c39b5754 100644
--- a/lustre/llite/lproc_llite.c
+++ b/lustre/llite/lproc_llite.c
@@ -164,6 +164,39 @@ static int ll_rd_sb_uuid(char *page, char **start, off_t off, int count,
         return snprintf(page, count, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid);
 }
 
+static int ll_rd_read_ahead(char *page, char **start, off_t off, int count,
+                            int *eof, void *data)
+{
+        struct super_block *sb = (struct super_block*)data;
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        int val, rc;
+        ENTRY;
+
+        *eof = 1;
+        val = (sbi->ll_flags & LL_SBI_READAHEAD) ? 1 : 0;
+        rc = snprintf(page, count, "%d\n", val);
+        RETURN(rc);
+}
+
+static int ll_wr_read_ahead(struct file *file, const char *buffer,
+                            unsigned long count, void *data)
+{
+        struct super_block *sb = (struct super_block*)data;
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        int readahead;
+        ENTRY;
+
+        if (1 != sscanf(buffer, "%d", &readahead))
+                RETURN(-EINVAL);        
+
+        if (readahead)
+                sbi->ll_flags |= LL_SBI_READAHEAD;
+        else
+                sbi->ll_flags &= ~LL_SBI_READAHEAD;
+
+        RETURN(count);
+}
+
 static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "uuid",         ll_rd_sb_uuid,          0, 0 },
         //{ "mntpt_path",   ll_rd_path,             0, 0 },
@@ -174,10 +207,7 @@ static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "filestotal",   ll_rd_filestotal,       0, 0 },
         { "filesfree",    ll_rd_filesfree,        0, 0 },
         //{ "filegroups",   lprocfs_rd_filegroups,  0, 0 },
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        { "dirty_pages",  ll_rd_dirty_pages,      0, 0},
-        { "max_dirty_pages", ll_rd_max_dirty_pages, ll_wr_max_dirty_pages, 0},
-#endif
+        { "read_ahead",   ll_rd_read_ahead, ll_wr_read_ahead, 0 },
         { 0 }
 };
 
@@ -215,7 +245,6 @@ struct llite_file_opcode {
         { LPROC_LL_LLSEEK,         LPROCFS_TYPE_REGS, "seek" },
         { LPROC_LL_FSYNC,          LPROCFS_TYPE_REGS, "fsync" },
         /* inode operation */
-        { LPROC_LL_SETATTR_RAW,    LPROCFS_TYPE_REGS, "setattr_raw" },
         { LPROC_LL_SETATTR,        LPROCFS_TYPE_REGS, "setattr" },
         { LPROC_LL_TRUNC,          LPROCFS_TYPE_REGS, "punch" },
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c
index 17afcefd692ed2865f60381e4d836bb423648253..e768933faf237894f6390e423e8539da4574731e 100644
--- a/lustre/llite/namei.c
+++ b/lustre/llite/namei.c
@@ -51,13 +51,29 @@ static int ll_test_inode(struct inode *inode, unsigned long ino, void *opaque)
 static int ll_test_inode(struct inode *inode, void *opaque)
 #endif
 {
+        static int last_ino, last_gen, last_count;
         struct lustre_md *md = opaque;
 
-        if (!(md->body->valid & (OBD_MD_FLGENER | OBD_MD_FLID)))
-                CERROR("invalid generation\n");
-        CDEBUG(D_VFSTRACE, "comparing inode %p ino %lu/%u to body %u/%u\n",
-               inode, inode->i_ino, inode->i_generation, 
-               md->body->ino, md->body->generation);
+        if (!(md->body->valid & (OBD_MD_FLGENER | OBD_MD_FLID))) {
+                CERROR("MDS body missing inum or generation\n");
+                return 0;
+        }
+
+        if (last_ino == md->body->ino && last_gen == md->body->generation &&
+            last_count < 500) {
+                last_count++;
+        } else {
+                if (last_count > 1)
+                        CDEBUG(D_VFSTRACE, "compared %u/%u %u times\n",
+                               last_ino, last_gen, last_count);
+                last_count = 0;
+                last_ino = md->body->ino;
+                last_gen = md->body->generation;
+                CDEBUG(D_VFSTRACE,
+                       "comparing inode %p ino %lu/%u to body %u/%u\n",
+                       inode, inode->i_ino, inode->i_generation,
+                       md->body->ino, md->body->generation);
+        }
 
         if (inode->i_generation != md->body->generation)
                 return 0;
@@ -95,13 +111,13 @@ struct inode *ll_iget(struct super_block *sb, ino_t hash,
         LASSERT(hash != 0);
         inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
 
-        if (!inode)
-                return (NULL);              /* removed ERR_PTR(-ENOMEM) -eeb */
-
-        if (inode->i_state & I_NEW)
-                unlock_new_inode(inode);
+        if (inode) {
+                if (inode->i_state & I_NEW)
+                        unlock_new_inode(inode);
+                CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
+                       inode->i_generation, inode);
+        }
 
-        // XXX Coda always fills inodes, should Lustre?
         return inode;
 }
 #else
@@ -111,64 +127,18 @@ struct inode *ll_iget(struct super_block *sb, ino_t hash,
         struct inode *inode;
         LASSERT(hash != 0);
         inode = iget4(sb, hash, ll_test_inode, md);
-        CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
-               inode->i_generation, inode);
+        if (inode)
+                CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
+                       inode->i_generation, inode);
         return inode;
 }
 #endif
 
-static int ll_intent_to_lock_mode(struct lookup_intent *it)
-{
-        /* CREAT needs to be tested before open (both could be set) */
-        if (it->it_op & IT_CREAT)
-                return LCK_PW;
-        else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP))
-                return LCK_PR;
-
-        LBUG();
-        RETURN(-EINVAL);
-}
-
-int ll_it_open_error(int phase, struct lookup_intent *it)
-{
-        if (it_disposition(it, DISP_OPEN_OPEN)) {
-                if (phase == DISP_OPEN_OPEN)
-                        return it->it_status;
-                else
-                        return 0;
-        }
-
-        if (it_disposition(it, DISP_OPEN_CREATE)) {
-                if (phase == DISP_OPEN_CREATE)
-                        return it->it_status;
-                else
-                        return 0;
-        }
-
-        if (it_disposition(it, DISP_LOOKUP_EXECD)) {
-                if (phase == DISP_LOOKUP_EXECD)
-                        return it->it_status;
-                else
-                        return 0;
-        }
-
-        if (it_disposition(it, DISP_IT_EXECD)) {
-                if (phase == DISP_IT_EXECD)
-                        return it->it_status;
-                else
-                        return 0;
-        }
-        CERROR("it disp: %X, status: %d\n", it->it_disposition, it->it_status);
-        LBUG();
-        return 0;
-}
-
 int ll_mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                         void *data, int flag)
 {
         int rc;
         struct lustre_handle lockh;
-        struct inode *inode = lock->l_data;
         ENTRY;
 
         switch (flag) {
@@ -181,9 +151,15 @@ int ll_mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                 }
                 break;
         case LDLM_CB_CANCELING: {
+                struct inode *inode = ll_inode_from_lock(lock);
+
                 /* Invalidate all dentries associated with this inode */
                 if (inode == NULL)
                         break;
+
+                clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK,
+                          &(ll_i2info(inode)->lli_flags));
+
                 if (lock->l_resource->lr_name.name[0] != inode->i_ino ||
                     lock->l_resource->lr_name.name[1] != inode->i_generation) {
                         LDLM_ERROR(lock, "data mismatch with ino %lu/%u",
@@ -196,10 +172,10 @@ int ll_mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                         ll_invalidate_inode_pages(inode);
                 }
 
-#warning FIXME: we should probably free this inode if there are no aliases
                 if (inode->i_sb->s_root &&
                     inode != inode->i_sb->s_root->d_inode)
                         ll_unhash_aliases(inode);
+                iput(inode);
                 break;
         }
         default:
@@ -220,228 +196,23 @@ int ll_mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode,
                                       opaque));
 }
 
-void ll_prepare_mdc_op_data(struct mdc_op_data *data,
-                            struct inode *i1,
-                            struct inode *i2,
-                            const char *name,
-                            int namelen,
+
+void ll_prepare_mdc_op_data(struct mdc_op_data *data, struct inode *i1,
+                            struct inode *i2, const char *name, int namelen,
                             int mode)
 {
         LASSERT(i1);
 
-        data->ino1 = i1->i_ino;
-        data->gen1 = i1->i_generation;
-        data->typ1 = i1->i_mode & S_IFMT;
-        data->gid1 = i1->i_gid;
+        ll_i2uctxt(&data->ctxt, i1, i2);
+        ll_inode2fid(&data->fid1, i1);
 
-        if (i2) {
-                data->ino2 = i2->i_ino;
-                data->gen2 = i2->i_generation;
-                data->typ2 = i2->i_mode & S_IFMT;
-                data->gid2 = i2->i_gid;
-        } else {
-                data->ino2 = 0;
-        }
+        if (i2)
+                ll_inode2fid(&data->fid2, i2);
 
         data->name = name;
         data->namelen = namelen;
-        data->mode = mode;
-}
-
-/* 
- *This long block is all about fixing up the local state so that it is
- *correct as of the moment _before_ the operation was applied; that
- *way, the VFS will think that everything is normal and call Lustre's
- *regular VFS methods.
- *
- * If we're performing a creation, that means that unless the creation
- * failed with EEXIST, we should fake up a negative dentry.
- *
- * For everything else, we want to lookup to succeed.
- *
- * One additional note: if CREATE or OPEN succeeded, we add an extra
- * reference to the request because we need to keep it around until
- * ll_create/ll_open gets called.
- *
- * The server will return to us, in it_disposition, an indication of
- * exactly what it_status refers to.
- *
- * If DISP_OPEN_OPEN is set, then it_status refers to the open() call,
- * otherwise if DISP_OPEN_CREATE is set, then it status is the
- * creation failure mode.  In either case, one of DISP_LOOKUP_NEG or
- * DISP_LOOKUP_POS will be set, indicating whether the child lookup
- * was successful.
- *
- * Else, if DISP_LOOKUP_EXECD then it_status is the rc of the child
- * lookup.
- */
-int ll_intent_lock(struct inode *parent, struct dentry **de,
-                   struct lookup_intent *it, int flags, intent_finish_cb intent_finish)
-{
-        struct dentry *dentry = *de;
-        struct inode *inode = dentry->d_inode;
-        struct ll_sb_info *sbi = ll_i2sbi(parent);
-        struct lustre_handle lockh;
-        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
-        struct ptlrpc_request *request;
-        int rc = 0;
-        struct mds_body *mds_body;
-        int mode;
-        obd_id ino = 0;
-        ENTRY;
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        if (it && it->it_magic != INTENT_MAGIC) { 
-                CERROR("WARNING: uninitialized intent\n");
-                LBUG();
-                intent_init(it, IT_LOOKUP, 0);
-        }
-        if (it->it_op == IT_GETATTR || 
-            it->it_op == 0)
-                it->it_op = IT_LOOKUP;
-        
-#endif
-        if (!it ||it->it_op == IT_GETXATTR)
-                it = &lookup_it;
-
-        it->it_op_release = ll_intent_release;
-
-        CDEBUG(D_DLMTRACE, "name: %*s, intent: %s\n", dentry->d_name.len,
-               dentry->d_name.name, ldlm_it2str(it->it_op));
-        
-        if (dentry->d_name.len > EXT2_NAME_LEN)
-                RETURN(-ENAMETOOLONG);
-
-        /* This function may be called twice, we only once want to
-           execute the request associated with the intent. If it was
-           done already, we skip past this and use the results. */ 
-        if (!it_disposition(it, DISP_ENQ_COMPLETE)) {
-                struct mdc_op_data op_data;
-
-                ll_prepare_mdc_op_data(&op_data, parent, dentry->d_inode,
-                                       dentry->d_name.name, dentry->d_name.len,
-                                       0);
-
-                rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, it,
-                                 ll_intent_to_lock_mode(it), &op_data,
-                                 &lockh, NULL, 0, ldlm_completion_ast,
-                                 ll_mdc_blocking_ast, NULL);
-                if (rc < 0)
-                        RETURN(rc);
-                memcpy(it->it_lock_handle, &lockh, sizeof(lockh));
-        }
-        request = it->it_data;
-        LASSERT(request != NULL);
-
-        if (!it_disposition(it, DISP_IT_EXECD)) {
-                /* The server failed before it even started executing the
-                 * intent, i.e. because it couldn't unpack the request. */
-                LASSERT(it->it_status != 0);
-                GOTO(drop_req, rc = it->it_status);
-        }
-        rc = ll_it_open_error(DISP_IT_EXECD, it);
-        if (rc)
-                GOTO(drop_req, rc);
-
-        mds_body = lustre_msg_buf(request->rq_repmsg, 1, sizeof(*mds_body));
-        LASSERT(mds_body != NULL);           /* mdc_enqueue checked */
-        LASSERT_REPSWABBED(request, 1); /* mdc_enqueue swabbed */
-
-        /* XXX everything with fids please, no ino's inode's etc */
-        ino = mds_body->fid1.id;
-        mode = mds_body->mode;
-
-        /*We were called from revalidate2: did we find the same inode?*/
-        if (inode && 
-            (ino != inode->i_ino ||
-             mds_body->fid1.generation != inode->i_generation)) {
-                it_set_disposition(it, DISP_ENQ_COMPLETE);
-                RETURN(-ESTALE);
-        }
-
-        /* If we're doing an IT_OPEN which did not result in an actual
-         * successful open, then we need to remove the bit which saves
-         * this request for unconditional replay. */
-        if (it->it_op & IT_OPEN) {
-                if (!it_disposition(it, DISP_OPEN_OPEN) ||
-                    it->it_status != 0) {
-                        unsigned long flags;
-                
-                        spin_lock_irqsave (&request->rq_lock, flags);
-                        request->rq_replay = 0;
-                        spin_unlock_irqrestore (&request->rq_lock, flags);
-                }
-        }
-
-        rc = ll_it_open_error(DISP_LOOKUP_EXECD, it);
-        if (rc)
-                GOTO(drop_req, rc);
-        
-        /* keep requests around for the multiple phases of the call
-         * this shows the DISP_XX must guarantee we make it into the call 
-         */ 
-        if (it_disposition(it, DISP_OPEN_CREATE))
-                ptlrpc_request_addref(request);
-        if (it_disposition(it, DISP_OPEN_OPEN))
-                ptlrpc_request_addref(request);
-        
-        if (it->it_op & IT_CREAT) {
-                /* XXX this belongs in ll_create_iit */
-        } else if (it->it_op == IT_OPEN) {
-                LASSERT(!it_disposition(it, DISP_OPEN_CREATE));
-        } else 
-                LASSERT(it->it_op & (IT_GETATTR | IT_LOOKUP));
-
-        if (intent_finish != NULL) {
-                struct lustre_handle old_lock;
-                struct ldlm_lock *lock;
-
-                rc = intent_finish(request, parent, de, it, 1, ino);
-                dentry = *de; /* intent_finish may change *de */
-                inode = dentry->d_inode;
-                if (rc != 0)
-                        GOTO(drop_lock, rc);
-
-                /* The intent processing may well have given us a lock different
-                 * from the one we requested.  If we already have a matching
-                 * lock, then cancel the new one.  (We have to do this here,
-                 * instead of in mdc_enqueue, because we need to use the child's
-                 * inode as the l_data to match, and that's not available until
-                 * intent_finish has performed the iget().) */
-                lock = ldlm_handle2lock(&lockh);
-                if (lock) {
-                        LDLM_DEBUG(lock, "matching against this");
-                        LDLM_LOCK_PUT(lock);
-                        memcpy(&old_lock, &lockh, sizeof(lockh));
-                        if (ldlm_lock_match(NULL,
-                                            LDLM_FL_BLOCK_GRANTED |
-                                            LDLM_FL_MATCH_DATA,
-                                            NULL, LDLM_PLAIN, NULL, 0, LCK_NL,
-                                            inode, &old_lock)) {
-                                ldlm_lock_decref_and_cancel(&lockh,
-                                                            it->it_lock_mode);
-                                memcpy(&lockh, &old_lock, sizeof(old_lock));
-                                memcpy(it->it_lock_handle, &lockh,
-                                       sizeof(lockh));
-                        }
-                }
-
-        }
-        ptlrpc_req_finished(request);
-
-        CDEBUG(D_DENTRY, "D_IT dentry %p intent: %s status %d disp %x\n",
-               dentry, ldlm_it2str(it->it_op), it->it_status, it->it_disposition);
-        
-        /* drop IT_LOOKUP locks */
-        if (it->it_op == IT_LOOKUP)
-                ll_intent_release(it);
-        RETURN(rc);
-
- drop_lock:
-        ll_intent_release(it);
- drop_req:
-        ptlrpc_req_finished(request);
-        RETURN(rc);
+        data->create_mode = mode;
+        data->mod_time = LTIME_S(CURRENT_TIME);
 }
 
 /* Search "inode"'s alias list for a dentry that has the same name and parent as
@@ -487,11 +258,12 @@ struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
         return de;
 }
 
-static int
-lookup2_finish(struct ptlrpc_request *request,
-               struct inode *parent, struct dentry **de,
-               struct lookup_intent *it, int offset, obd_id ino)
+static int lookup_it_finish(struct ptlrpc_request *request, int offset,
+                            struct lookup_intent *it, void *data)
 {
+        struct it_cb_data *icbd = data;
+        struct dentry **de = icbd->icbd_childp;
+        struct inode *parent = icbd->icbd_parent;
         struct ll_sb_info *sbi = ll_i2sbi(parent);
         struct dentry *dentry = *de, *saved = *de;
         struct inode *inode = NULL;
@@ -500,24 +272,13 @@ lookup2_finish(struct ptlrpc_request *request,
         /* NB 1 request reference will be taken away by ll_intent_lock()
          * when I return */
         if (!it_disposition(it, DISP_LOOKUP_NEG)) {
-                struct lustre_md md;
                 ENTRY;
 
-                rc =mdc_req2lustre_md(request, offset, &sbi->ll_osc_conn, &md);
-                if (rc) 
+                rc = ll_prep_inode(sbi->ll_osc_exp, &inode, request, offset,
+                                   dentry->d_sb);
+                if (rc)
                         RETURN(rc);
 
-                inode = ll_iget(dentry->d_sb, ino, &md);
-                if (!inode) {
-                        /* free the lsm if we allocated one above */
-                        if (md.lsm != NULL)
-                                obd_free_memmd(&sbi->ll_osc_conn, &md.lsm);
-                        RETURN(-ENOMEM);
-                } else if (md.lsm != NULL &&
-                           ll_i2info(inode)->lli_smd != md.lsm) {
-                        obd_free_memmd(&sbi->ll_osc_conn, &md.lsm);
-                }
-
                 /* If this is a stat, get the authoritative file size */
                 if (it->it_op == IT_GETATTR && S_ISREG(inode->i_mode) &&
                     ll_i2info(inode)->lli_smd != NULL) {
@@ -538,14 +299,6 @@ lookup2_finish(struct ptlrpc_request *request,
                 }
 
                 dentry = *de = ll_find_alias(inode, dentry);
-
-                /* We asked for a lock on the directory, and may have been
-                 * granted a lock on the inode.  Just in case, fixup the data
-                 * pointer. */
-                CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
-                       inode, inode->i_ino, inode->i_generation);
-                ldlm_lock_set_data((struct lustre_handle*)it->it_lock_handle,
-                                   inode);
         } else {
                 ENTRY;
         }
@@ -559,161 +312,103 @@ lookup2_finish(struct ptlrpc_request *request,
         RETURN(0);
 }
 
+
 static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
                                    struct lookup_intent *it, int flags)
 {
         struct dentry *save = dentry, *retval;
+        struct ll_fid pfid;
+        struct ll_uctxt ctxt;
+        struct it_cb_data icbd;
+        struct ptlrpc_request *req = NULL;
+        struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
         int rc;
         ENTRY;
 
+        if (dentry->d_name.len > EXT3_NAME_LEN)
+                RETURN(ERR_PTR(-ENAMETOOLONG));
+
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p),intent=%s\n",
                dentry->d_name.name, parent->i_ino, parent->i_generation,
                parent, LL_IT2STR(it));
 
-        if (d_mountpoint(dentry)) { 
+        if (d_mountpoint(dentry))
                 CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it));
-        }
 
-        rc = ll_intent_lock(parent, &dentry, it, flags, lookup2_finish);
-        if (rc < 0) {
-                CDEBUG(D_INFO, "ll_intent_lock: %d\n", rc);
+        ll_frob_intent(&it, &lookup_it);
+
+        icbd.icbd_childp = &dentry;
+        icbd.icbd_parent = parent;
+        ll_inode2fid(&pfid, parent);
+        ll_i2uctxt(&ctxt, parent, NULL);
+
+        rc = mdc_intent_lock(ll_i2mdcexp(parent), &ctxt, &pfid,
+                             dentry->d_name.name, dentry->d_name.len, NULL, 0,
+                             NULL, it, flags, &req, ll_mdc_blocking_ast);
+        if (rc < 0)
+                GOTO(out, retval = ERR_PTR(rc));
+
+        rc = lookup_it_finish(req, 1, it, &icbd);
+        if (rc != 0) {
+                ll_intent_release(it);
                 GOTO(out, retval = ERR_PTR(rc));
         }
 
+        ll_lookup_finish_locks(it, dentry);
+
         if (dentry == save)
                 GOTO(out, retval = NULL);
         else
                 GOTO(out, retval = dentry);
  out:
+        if (req)
+                ptlrpc_req_finished(req);
         return retval;
 }
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, 
+static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
                                    struct nameidata *nd)
 {
         struct dentry *de;
         ENTRY;
 
         if (nd->flags & LOOKUP_LAST && !(nd->flags & LOOKUP_LINK_NOTLAST))
-                de = ll_lookup_it(parent, dentry, &nd->it, nd->flags);
-        else 
+                de = ll_lookup_it(parent, dentry, &nd->intent, nd->flags);
+        else
                 de = ll_lookup_it(parent, dentry, NULL, 0);
 
         RETURN(de);
 }
 #endif
 
-static int ll_mdc_unlink(struct inode *dir, struct inode *child, __u32 mode,
-                         const char *name, int len)
-{
-        struct ptlrpc_request *request = NULL;
-        struct mds_body *body;
-        struct lov_mds_md *eadata;
-        struct lov_stripe_md *lsm = NULL;
-        struct obd_trans_info oti = { 0 };
-        struct mdc_op_data op_data;
-        struct obdo *oa;
-        int rc;
-        ENTRY;
-
-        ll_prepare_mdc_op_data(&op_data, dir, child, name, len, mode);
-        rc = mdc_unlink(&ll_i2sbi(dir)->ll_mdc_conn, &op_data, &request);
-        if (rc)
-                GOTO(out, rc);
-        /* req is swabbed so this is safe */
-        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
-
-        if (!(body->valid & OBD_MD_FLEASIZE))
-                GOTO(out, rc = 0);
-
-        if (body->eadatasize == 0) {
-                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
-                GOTO(out, rc = -EPROTO);
-        }
-
-        /* The MDS sent back the EA because we unlinked the last reference
-         * to this file. Use this EA to unlink the objects on the OST.
-         * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
-         * check it is complete and sensible. */
-        eadata = lustre_swab_repbuf(request, 1, body->eadatasize, NULL);
-        LASSERT(eadata != NULL);
-        if (eadata == NULL) {
-                CERROR("Can't unpack MDS EA data\n");
-                GOTO(out, rc = -EPROTO);
-        }
-
-        rc = obd_unpackmd(ll_i2obdconn(dir), &lsm, eadata, body->eadatasize);
-        if (rc < 0) {
-                CERROR("obd_unpackmd: %d\n", rc);
-                GOTO(out, rc);
-        }
-        LASSERT(rc >= sizeof(*lsm));
-
-        oa = obdo_alloc();
-        if (oa == NULL)
-                GOTO(out_free_memmd, rc = -ENOMEM);
-
-        oa->o_id = lsm->lsm_object_id;
-        oa->o_mode = body->mode & S_IFMT;
-        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
-
-        if (body->valid & OBD_MD_FLCOOKIE) {
-                oa->o_valid |= OBD_MD_FLCOOKIE;
-                oti.oti_logcookies = lustre_msg_buf(request->rq_repmsg, 3,
-                                                    body->eadatasize);
-        }
-
-        rc = obd_destroy(ll_i2obdconn(dir), oa, lsm, &oti);
-        obdo_free(oa);
-        if (rc)
-                CERROR("obd destroy objid "LPX64": rc %d\n",
-                       lsm->lsm_object_id, rc);
- out_free_memmd:
-        obd_free_memmd(ll_i2obdconn(dir), &lsm);
- out:
-        ptlrpc_req_finished(request);
-        return rc;
-}
-
 /* We depend on "mode" being set with the proper file type/umask by now */
 static struct inode *ll_create_node(struct inode *dir, const char *name,
                                     int namelen, const void *data, int datalen,
                                     int mode, __u64 extra,
                                     struct lookup_intent *it)
 {
-        struct inode *inode;
+        struct inode *inode = NULL;
         struct ptlrpc_request *request = NULL;
         struct ll_sb_info *sbi = ll_i2sbi(dir);
-        struct lustre_md md;
         int rc;
         ENTRY;
 
-        LASSERT(it && it->it_disposition);
-
-        ll_invalidate_inode_pages(dir);
+        LASSERT(it && it->d.lustre.it_disposition);
 
-        request = it->it_data;
-        rc = mdc_req2lustre_md(request, 1, &sbi->ll_osc_conn, &md);
-        if (rc) { 
+        request = it->d.lustre.it_data;
+        rc = ll_prep_inode(sbi->ll_osc_exp, &inode, request, 1, dir->i_sb);
+        if (rc)
                 GOTO(out, inode = ERR_PTR(rc));
-        }
 
-        inode = ll_iget(dir->i_sb, md.body->ino, &md);
-        if (!inode || is_bad_inode(inode)) {
-                /* XXX might need iput() for bad inode */
-                int rc = -EIO;
-                CERROR("new_inode -fatal: rc %d\n", rc);
-                LBUG();
-                GOTO(out, rc);
-        }
         LASSERT(list_empty(&inode->i_dentry));
 
-        CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
+        /* We asked for a lock on the directory, but were granted a
+         * lock on the inode.  Since we finally have an inode pointer,
+         * stuff it in the lock. */
+        CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",
                inode, inode->i_ino, inode->i_generation);
-        ldlm_lock_set_data((struct lustre_handle*)it->it_lock_handle,
-                           inode);
-
+        mdc_set_lock_data(&it->d.lustre.it_lock_handle, inode);
         EXIT;
  out:
         ptlrpc_req_finished(request);
@@ -734,10 +429,11 @@ static struct inode *ll_create_node(struct inode *dir, const char *name,
  * If the create succeeds, we fill in the inode information
  * with d_instantiate().
  */
-static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, struct lookup_intent *it)
+static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,
+                        struct lookup_intent *it)
 {
         struct inode *inode;
-        struct ptlrpc_request *request = it->it_data;
+        struct ptlrpc_request *request = it->d.lustre.it_data;
         int rc = 0;
         ENTRY;
 
@@ -745,11 +441,9 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, stru
                dentry->d_name.name, dir->i_ino, dir->i_generation, dir,
                LL_IT2STR(it));
 
-        rc = ll_it_open_error(DISP_OPEN_CREATE, it);
-        if (rc) {
-                ptlrpc_req_finished(request);
+        rc = it_open_error(DISP_OPEN_CREATE, it);
+        if (rc)
                 RETURN(rc);
-        }
 
         mdc_store_inode_generation(request, 2, 1);
         inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
@@ -765,17 +459,16 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, stru
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 static int ll_create_nd(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
 {
-        return ll_create_it(dir, dentry, mode, &nd->it);
+        return ll_create_it(dir, dentry, mode, &nd->intent);
 }
 #endif
 
 static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
 {
+        struct ptlrpc_request *request = NULL;
         struct inode *dir = nd->dentry->d_inode;
         const char *name = nd->last.name;
         int len = nd->last.len;
-        struct ptlrpc_request *request = NULL;
-        time_t time = LTIME_S(CURRENT_TIME);
         struct ll_sb_info *sbi = ll_i2sbi(dir);
         struct mdc_op_data op_data;
         int err = -EMLINK;
@@ -784,22 +477,22 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
                name, dir->i_ino, dir->i_generation, dir);
 
-        if (dir->i_nlink >= EXT2_LINK_MAX)
+        if (dir->i_nlink >= EXT3_LINK_MAX)
                 RETURN(err);
 
         mode &= ~current->fs->umask;
 
         switch (mode & S_IFMT) {
-        case 0: 
+        case 0:
         case S_IFREG:
                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
-        case S_IFCHR: 
+        case S_IFCHR:
         case S_IFBLK:
-        case S_IFIFO: 
+        case S_IFIFO:
         case S_IFSOCK:
                 ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-                err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
-                                 current->fsuid, current->fsgid, time,
+                err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+                                 current->fsuid, current->fsgid,
                                  rdev, &request);
                 ptlrpc_req_finished(request);
                 break;
@@ -812,13 +505,62 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
         RETURN(err);
 }
 
+static int ll_mknod(struct inode *dir, struct dentry *child, int mode,
+                    ll_dev_t rdev)
+{
+        struct ptlrpc_request *request = NULL;
+        struct inode *inode = NULL;
+        const char *name = child->d_name.name;
+        int len = child->d_name.len;
+        struct ll_sb_info *sbi = ll_i2sbi(dir);
+        struct mdc_op_data op_data;
+        int err = -EMLINK;
+        ENTRY;
+
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
+               name, dir->i_ino, dir->i_generation, dir);
+
+        if (dir->i_nlink >= EXT3_LINK_MAX)
+                RETURN(err);
+
+        mode &= ~current->fs->umask;
+
+        switch (mode & S_IFMT) {
+        case 0:
+        case S_IFREG:
+                mode |= S_IFREG; /* for mode = 0 case, fallthrough */
+        case S_IFCHR:
+        case S_IFBLK:
+        case S_IFIFO:
+        case S_IFSOCK:
+                ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+                err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+                                 current->fsuid, current->fsgid,
+                                 rdev, &request);
+                err = ll_prep_inode(sbi->ll_osc_exp, &inode, request, 0,
+                                    child->d_sb);
+                if (err)
+                        GOTO(out_err, err);
+                break;
+        case S_IFDIR:
+                RETURN(-EPERM);
+                break;
+        default:
+                RETURN(-EINVAL);
+        }
+
+        d_instantiate(child, inode);
+ out_err:
+        ptlrpc_req_finished(request);
+        RETURN(err);
+}
+
 static int ll_symlink_raw(struct nameidata *nd, const char *tgt)
 {
         struct inode *dir = nd->dentry->d_inode;
         const char *name = nd->last.name;
         int len = nd->last.len;
         struct ptlrpc_request *request = NULL;
-        time_t time = LTIME_S(CURRENT_TIME);
         struct ll_sb_info *sbi = ll_i2sbi(dir);
         struct mdc_op_data op_data;
         int err = -EMLINK;
@@ -827,13 +569,13 @@ static int ll_symlink_raw(struct nameidata *nd, const char *tgt)
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p),target=%s\n",
                name, dir->i_ino, dir->i_generation, dir, tgt);
 
-        if (dir->i_nlink >= EXT2_LINK_MAX)
+        if (dir->i_nlink >= EXT3_LINK_MAX)
                 RETURN(err);
 
         ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data,
+        err = mdc_create(sbi->ll_mdc_exp, &op_data,
                          tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
-                         current->fsuid, current->fsgid, time, 0, &request);
+                         current->fsuid, current->fsgid, 0, &request);
         ptlrpc_req_finished(request);
         RETURN(err);
 }
@@ -855,7 +597,7 @@ static int ll_link_raw(struct nameidata *srcnd, struct nameidata *tgtnd)
                dir->i_ino, dir->i_generation, dir, name);
 
         ll_prepare_mdc_op_data(&op_data, src, dir, name, len, 0);
-        err = mdc_link(&sbi->ll_mdc_conn, &op_data, &request);
+        err = mdc_link(sbi->ll_mdc_exp, &op_data, &request);
         ptlrpc_req_finished(request);
 
         RETURN(err);
@@ -868,7 +610,6 @@ static int ll_mkdir_raw(struct nameidata *nd, int mode)
         const char *name = nd->last.name;
         int len = nd->last.len;
         struct ptlrpc_request *request = NULL;
-        time_t time = LTIME_S(CURRENT_TIME);
         struct ll_sb_info *sbi = ll_i2sbi(dir);
         struct mdc_op_data op_data;
         int err = -EMLINK;
@@ -876,13 +617,13 @@ static int ll_mkdir_raw(struct nameidata *nd, int mode)
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
                name, dir->i_ino, dir->i_generation, dir);
 
-        if (dir->i_nlink >= EXT2_LINK_MAX)
+        if (dir->i_nlink >= EXT3_LINK_MAX)
                 RETURN(err);
 
         mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
         ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
-        err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
-                         current->fsuid, current->fsgid, time, 0, &request);
+        err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
+                         current->fsuid, current->fsgid, 0, &request);
         ptlrpc_req_finished(request);
         RETURN(err);
 }
@@ -892,26 +633,109 @@ static int ll_rmdir_raw(struct nameidata *nd)
         struct inode *dir = nd->dentry->d_inode;
         const char *name = nd->last.name;
         int len = nd->last.len;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
         int rc;
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
                name, dir->i_ino, dir->i_generation, dir);
 
-        rc = ll_mdc_unlink(dir, NULL, S_IFDIR, name, len);
+        ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, S_IFDIR);
+        rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+        ptlrpc_req_finished(request);
         RETURN(rc);
 }
 
+int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
+{
+        struct mds_body *body;
+        struct lov_mds_md *eadata;
+        struct lov_stripe_md *lsm = NULL;
+        struct obd_trans_info oti = { 0 };
+        struct obdo *oa;
+        int rc;
+        ENTRY;
+
+        /* req is swabbed so this is safe */
+        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
+
+        if (!(body->valid & OBD_MD_FLEASIZE))
+                RETURN(0);
+
+        if (body->eadatasize == 0) {
+                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
+                GOTO(out, rc = -EPROTO);
+        }
+
+        /* The MDS sent back the EA because we unlinked the last reference
+         * to this file. Use this EA to unlink the objects on the OST.
+         * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
+         * check it is complete and sensible. */
+        eadata = lustre_swab_repbuf(request, 1, body->eadatasize, NULL);
+        LASSERT(eadata != NULL);
+        if (eadata == NULL) {
+                CERROR("Can't unpack MDS EA data\n");
+                GOTO(out, rc = -EPROTO);
+        }
+
+        rc = obd_unpackmd(ll_i2obdexp(dir), &lsm, eadata, body->eadatasize);
+        if (rc < 0) {
+                CERROR("obd_unpackmd: %d\n", rc);
+                GOTO(out, rc);
+        }
+        LASSERT(rc >= sizeof(*lsm));
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out_free_memmd, rc = -ENOMEM);
+
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_mode = body->mode & S_IFMT;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
+
+        if (body->valid & OBD_MD_FLCOOKIE) {
+                oa->o_valid |= OBD_MD_FLCOOKIE;
+                oti.oti_logcookies =
+                        lustre_msg_buf(request->rq_repmsg, 2,
+                                       sizeof(struct llog_cookie) *
+                                       lsm->lsm_stripe_count);
+                if (oti.oti_logcookies == NULL) {
+                        oa->o_valid &= ~OBD_MD_FLCOOKIE;
+                        body->valid &= ~OBD_MD_FLCOOKIE;
+                }
+        }
+
+        rc = obd_destroy(ll_i2obdexp(dir), oa, lsm, &oti);
+        obdo_free(oa);
+        if (rc)
+                CERROR("obd destroy objid "LPX64" error %d\n",
+                       lsm->lsm_object_id, rc);
+ out_free_memmd:
+        obd_free_memmd(ll_i2obdexp(dir), &lsm);
+ out:
+        return rc;
+}
+
 static int ll_unlink_raw(struct nameidata *nd)
 {
         struct inode *dir = nd->dentry->d_inode;
         const char *name = nd->last.name;
         int len = nd->last.len;
+        struct ptlrpc_request *request = NULL;
+        struct mdc_op_data op_data;
         int rc;
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu/%u(%p)\n",
                name, dir->i_ino, dir->i_generation, dir);
 
-        rc = ll_mdc_unlink(dir, NULL, S_IFREG, name, len);
+        ll_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+        rc = mdc_unlink(ll_i2sbi(dir)->ll_mdc_exp, &op_data, &request);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = ll_objects_destroy(request, dir);
+ out:
+        ptlrpc_req_finished(request);
         RETURN(rc);
 }
 
@@ -933,8 +757,12 @@ static int ll_rename_raw(struct nameidata *oldnd, struct nameidata *newnd)
                src, newname, tgt->i_ino, tgt->i_generation, tgt);
 
         ll_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0);
-        err = mdc_rename(&sbi->ll_mdc_conn, &op_data,
+        err = mdc_rename(sbi->ll_mdc_exp, &op_data,
                          oldname, oldlen, newname, newlen, &request);
+        if (!err) {
+                err = ll_objects_destroy(request, src);
+        }
+
         ptlrpc_req_finished(request);
 
         RETURN(err);
@@ -947,6 +775,7 @@ struct inode_operations ll_dir_inode_operations = {
         mkdir_raw:          ll_mkdir_raw,
         rmdir_raw:          ll_rmdir_raw,
         mknod_raw:          ll_mknod_raw,
+        mknod:              ll_mknod,
         rename_raw:         ll_rename_raw,
         setattr:         ll_setattr,
         setattr_raw:     ll_setattr_raw,
@@ -955,8 +784,8 @@ struct inode_operations ll_dir_inode_operations = {
         lookup_it:            ll_lookup_it,
         revalidate_it:      ll_inode_revalidate_it,
 #else
-        lookup_it:          ll_lookup_nd,
-        create_nd:          ll_create_nd,
+        lookup:          ll_lookup_nd,
+        create:          ll_create_nd,
         getattr_it:         ll_getattr,
 #endif
 };
diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c
index 806618b52463254d0da14c3f29804ac14d702631..eb940cdb7ea41adc11c1c3eb8a6988c199b7db17 100644
--- a/lustre/llite/rw.c
+++ b/lustre/llite/rw.c
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Lustre Lite I/O Page Cache
+ * Lustre Lite I/O page cache routines shared by different kernel revs
  *
  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
  *
@@ -34,13 +34,6 @@
 #include <asm/uaccess.h>
 
 #include <linux/fs.h>
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-#include <linux/buffer_head.h>
-#include <linux/mpage.h>
-#include <linux/writeback.h>
-#else
-#include <linux/iobuf.h>
-#endif
 #include <linux/stat.h>
 #include <asm/uaccess.h>
 #include <asm/segment.h>
@@ -55,43 +48,14 @@
 #include "llite_internal.h"
 #include <linux/lustre_compat25.h>
 
-/*
- * Remove page from dirty list
- */
-static void __set_page_clean(struct page *page)
-{
-        struct address_space *mapping = page->mapping;
-        struct inode *inode;
-
-        if (!mapping)
-                return;
-
-        PGCACHE_WRLOCK(mapping);
-
-        list_del(&page->list);
-        list_add(&page->list, &mapping->clean_pages);
-
-        /* XXX doesn't inode_lock protect i_state ? */
-        inode = mapping->host;
-        if (list_empty(&mapping->dirty_pages)) {
-                CDEBUG(D_INODE, "inode clean\n");
-                inode->i_state &= ~I_DIRTY_PAGES;
-        }
-
-        PGCACHE_WRUNLOCK(mapping);
-        EXIT;
-}
-
-void set_page_clean(struct page *page)
-{
-        if (PageDirty(page)) {
-                ClearPageDirty(page);
-                __set_page_clean(page);
-        }
-}
+#ifndef list_for_each_prev_safe
+#define list_for_each_prev_safe(pos, n, head) \
+        for (pos = (head)->prev, n = pos->prev; pos != (head); \
+                pos = n, n = pos->prev )
+#endif
 
 /* SYNCHRONOUS I/O to object storage for an inode */
-static int ll_brw(int cmd, struct inode *inode, struct obdo *oa,
+static int ll_brw(int cmd, struct inode *inode, struct obdo *oa, 
                   struct page *page, int flags)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
@@ -126,208 +90,14 @@ static int ll_brw(int cmd, struct inode *inode, struct obdo *oa,
         else
                 lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
                                     LPROC_LL_BRW_READ, pg.count);
-        rc = obd_brw(cmd, ll_i2obdconn(inode), oa, lsm, 1, &pg, NULL);
-        if (rc != 0 && rc != -EIO)
+        rc = obd_brw(cmd, ll_i2obdexp(inode), oa, lsm, 1, &pg, NULL);
+        if (rc == 0)
+                obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS);
+        else if (rc != -EIO)
                 CERROR("error from obd_brw: rc = %d\n", rc);
-
         RETURN(rc);
 }
 
-/*
- * we were asked to read a single page but we're going to try and read a batch
- * of pages all at once.  this vaguely simulates 2.5's readpages.
- */
-static int ll_readpage(struct file *file, struct page *first_page)
-{
-        struct inode *inode = first_page->mapping->host;
-        struct ll_inode_info *lli = ll_i2info(inode);
-        struct page *page = first_page;
-        struct list_head *pos;
-        struct brw_page *pgs;
-        struct obdo *oa;
-        unsigned long end_index, extent_end = 0;
-        struct ptlrpc_request_set *set;
-        int npgs = 0, rc = 0, max_pages;
-        ENTRY;
-
-        LASSERT(PageLocked(page));
-        LASSERT(!PageUptodate(page));
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),offset="LPX64"\n",
-               inode->i_ino, inode->i_generation, inode,
-               (((obd_off)page->index) << PAGE_SHIFT));
-        LASSERT(atomic_read(&file->f_dentry->d_inode->i_count) > 0);
-
-        if (inode->i_size <= ((obd_off)page->index) << PAGE_SHIFT) {
-                CERROR("reading beyond EOF\n");
-                memset(kmap(page), 0, PAGE_SIZE);
-                kunmap(page);
-                SetPageUptodate(page);
-                unlock_page(page);
-                RETURN(rc);
-        }
-
-        /* try to read the file's preferred block size in a one-er */
-        end_index = first_page->index +
-                (inode->i_blksize >> PAGE_CACHE_SHIFT);
-        if (end_index > (inode->i_size >> PAGE_CACHE_SHIFT))
-                end_index = inode->i_size >> PAGE_CACHE_SHIFT;
-
-        max_pages = ((end_index - first_page->index) << PAGE_CACHE_SHIFT) >>
-                PAGE_SHIFT;
-        OBD_ALLOC_GFP(pgs, max_pages * sizeof(*pgs), GFP_USER);
-        if (pgs == NULL)
-                RETURN(-ENOMEM);
-
-        /*
-         * find how far we're allowed to read under the extent ll_file_read
-         * is passing us..
-         */
-        spin_lock(&lli->lli_read_extent_lock);
-        list_for_each(pos, &lli->lli_read_extents) {
-                struct ll_read_extent *rextent;
-                rextent = list_entry(pos, struct ll_read_extent, re_lli_item);
-                if (rextent->re_task != current)
-                        continue;
-
-                if (rextent->re_extent.end + PAGE_SIZE < rextent->re_extent.end)
-                        /* extent wrapping */
-                        extent_end = ~0;
-                else {
-                        extent_end = (rextent->re_extent.end + PAGE_SIZE)
-                                                        << PAGE_CACHE_SHIFT;
-                        /* 32bit indexes, 64bit extents.. */
-                        if (((u64)extent_end >> PAGE_CACHE_SHIFT) <
-                                        rextent->re_extent.end)
-                                extent_end = ~0;
-                }
-                break;
-        }
-        spin_unlock(&lli->lli_read_extent_lock);
-
-        if (extent_end == 0) {
-                static long next_print;
-                if (time_after(jiffies, next_print)) {
-                        next_print = jiffies + 30 * HZ;
-                        CDEBUG(D_INODE, "mmap readpage - check locks\n");
-                }
-                end_index = page->index + 1;
-        } else if (extent_end < end_index)
-                end_index = extent_end;
-
-        CDEBUG(D_INFO, "max_pages: %d, extent_end: %lu, end_index: %lu, "
-               "i_size: %llu\n",
-               max_pages, extent_end, end_index, inode->i_size);
-
-        /* to balance the find_get_page ref the other pages get that is
-         * decrefed on teardown.. */
-        page_cache_get(page);
-        do {
-                unsigned long index ;
-
-                pgs[npgs].pg = page;
-                pgs[npgs].off = ((obd_off)page->index) << PAGE_CACHE_SHIFT;
-                pgs[npgs].flag = 0;
-                pgs[npgs].count = PAGE_SIZE;
-                /* XXX Workaround for BA OSTs returning short reads at EOF.
-                 * The linux OST will return the full page, zero-filled at the
-                 * end, which will just overwrite the data we set here.  Bug
-                 * 593 relates to fixing this properly.
-                 */
-                if (inode->i_size < pgs[npgs].off + PAGE_SIZE) {
-                        int count = inode->i_size - pgs[npgs].off;
-                        void *addr = kmap(page);
-                        pgs[npgs].count = count;
-                        //POISON(addr, 0x7c, count);
-                        memset(addr + count, 0, PAGE_SIZE - count);
-                        kunmap(page);
-                }
-
-                npgs++;
-                if (npgs == max_pages)
-                        break;
-
-                /*
-                 * find pages ahead of us that we can read in.
-                 * grab_cache_page waits on pages that are locked so
-                 * we first try find_get_page, which doesn't.  this stops
-                 * the worst case behaviour of racing threads waiting on
-                 * each other, but doesn't remove it entirely.
-                 */
-                for (index = page->index + 1, page = NULL;
-                     page == NULL && index < end_index; index++) {
-
-                        /* see if the page already exists and needs updating */
-                        page = find_get_page(inode->i_mapping, index);
-                        if (page) {
-                                if (Page_Uptodate(page) || TryLockPage(page))
-                                        goto out_release;
-                                if (!page->mapping || Page_Uptodate(page))
-                                        goto out_unlock;
-                        } else {
-                                /* ok, we have to create it.. */
-                                page = grab_cache_page(inode->i_mapping, index);
-                                if (page == NULL)
-                                        continue;
-                                if (Page_Uptodate(page))
-                                        goto out_unlock;
-                        }
-
-                        break;
-
-                out_unlock:
-                        unlock_page(page);
-                out_release:
-                        page_cache_release(page);
-                        page = NULL;
-                }
-
-        } while (page);
-
-        if ((oa = obdo_alloc()) == NULL) {
-                CERROR("ENOMEM allocing obdo\n");
-                rc = -ENOMEM;
-        } else if ((set = ptlrpc_prep_set()) == NULL) {
-                CERROR("ENOMEM allocing request set\n");
-                obdo_free(oa);
-                rc = -ENOMEM;
-        } else {
-                struct ll_file_data *fd = file->private_data;
-
-                oa->o_id = lli->lli_smd->lsm_object_id;
-                memcpy(obdo_handle(oa), &fd->fd_ost_och.och_fh,
-                       sizeof(fd->fd_ost_och.och_fh));
-                oa->o_valid = OBD_MD_FLID | OBD_MD_FLHANDLE;
-                obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME);
-
-                rc = obd_brw_async(OBD_BRW_READ, ll_i2obdconn(inode), oa,
-                                   ll_i2info(inode)->lli_smd, npgs, pgs,
-                                   set, NULL);
-                if (rc == 0)
-                        rc = ptlrpc_set_wait(set);
-                ptlrpc_set_destroy(set);
-                if (rc == 0) {
-                        /* bug 1598: don't clobber blksize */
-                        oa->o_valid &= ~(OBD_MD_FLSIZE | OBD_MD_FLBLKSZ);
-                        obdo_refresh_inode(inode, oa, oa->o_valid);
-                }
-                if (rc && rc != -EIO)
-                        CERROR("error from obd_brw_async: rc = %d\n", rc);
-                obdo_free(oa);
-        }
-
-        while (npgs-- > 0) {
-                page = pgs[npgs].pg;
-
-                if (rc == 0)
-                        SetPageUptodate(page);
-                unlock_page(page);
-                page_cache_release(page);
-        }
-
-        OBD_FREE(pgs, max_pages * sizeof(*pgs));
-        RETURN(rc);
-} /* ll_readpage */
-
 /* this isn't where truncate starts.   roughly:
  * sys_truncate->ll_setattr_raw->vmtruncate->ll_truncate
  * we grab the lock back in setattr_raw to avoid races. */
@@ -335,25 +105,18 @@ void ll_truncate(struct inode *inode)
 {
         struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
         struct obdo oa;
-        int err;
+        int rc;
         ENTRY;
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
                inode->i_generation, inode);
 
-        /* object not yet allocated */
+        /* object not yet allocated - this is handled in ll_setattr_raw */
         if (!lsm) {
                 CERROR("truncate on inode %lu with no objects\n", inode->i_ino);
                 EXIT;
                 return;
         }
 
-        /* vmtruncate will just throw away our dirty pages, make sure
-         * we don't think they're still dirty, being careful to round
-         * i_size to the first whole page that was tossed */
-        err = ll_clear_dirty_pages(ll_i2obdconn(inode), lsm,
-                        (inode->i_size + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT,
-                        ~0);
-
         oa.o_id = lsm->lsm_object_id;
         oa.o_valid = OBD_MD_FLID;
         obdo_from_inode(&oa, inode, OBD_MD_FLTYPE|OBD_MD_FLMODE|OBD_MD_FLATIME|
@@ -363,10 +126,10 @@ void ll_truncate(struct inode *inode)
                oa.o_id, inode->i_size);
 
         /* truncate == punch from new size to absolute end of file */
-        err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size,
-                        OBD_OBJECT_EOF, NULL);
-        if (err)
-                CERROR("obd_truncate fails (%d) ino %lu\n", err, inode->i_ino);
+        rc = obd_punch(ll_i2obdexp(inode), &oa, lsm, inode->i_size,
+                       OBD_OBJECT_EOF, NULL);
+        if (rc)
+                CERROR("obd_truncate fails (%d) ino %lu\n", rc, inode->i_ino);
         else
                 obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
                                           OBD_MD_FLATIME | OBD_MD_FLMTIME |
@@ -376,14 +139,11 @@ void ll_truncate(struct inode *inode)
         return;
 } /* ll_truncate */
 
-//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
-static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
-                            unsigned to)
+int ll_prepare_write(struct file *file, struct page *page, unsigned from,
+                     unsigned to)
 {
         struct inode *inode = page->mapping->host;
         struct ll_inode_info *lli = ll_i2info(inode);
-        struct ll_file_data *fd = file->private_data;
         struct lov_stripe_md *lsm = lli->lli_smd;
         obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
         struct brw_page pg;
@@ -397,21 +157,22 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
         if (PageUptodate(page))
                 RETURN(0);
 
-        //POISON(addr + from, 0xca, to - from);
-
         /* Check to see if we should return -EIO right away */
         pg.pg = page;
         pg.off = offset;
         pg.count = PAGE_SIZE;
         pg.flag = 0;
-        rc = obd_brw(OBD_BRW_CHECK, ll_i2obdconn(inode), NULL, lsm, 1,&pg,NULL);
+        rc = obd_brw(OBD_BRW_CHECK, ll_i2obdexp(inode), NULL, lsm, 1, &pg, 
+                     NULL);
         if (rc)
                 RETURN(rc);
 
         /* We're completely overwriting an existing page, so _don't_ set it up
          * to date until commit_write */
-        if (from == 0 && to == PAGE_SIZE)
+        if (from == 0 && to == PAGE_SIZE) {
+                POISON_PAGE(page, 0x11);
                 RETURN(0);
+        }
 
         /* If are writing to a new page, no need to read old data.
          * the extent locking and getattr procedures in ll_file_write have
@@ -424,10 +185,9 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
 
         oa.o_id = lsm->lsm_object_id;
         oa.o_mode = inode->i_mode;
-        memcpy(obdo_handle(&oa), &fd->fd_ost_och.och_fh,
-               sizeof(fd->fd_ost_och.och_fh));
-        oa.o_valid = OBD_MD_FLID |OBD_MD_FLMODE |OBD_MD_FLTYPE |OBD_MD_FLHANDLE;
-
+        oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE;
+        
+        /* XXX could be an async ocp read.. read-ahead? */
         rc = ll_brw(OBD_BRW_READ, inode, &oa, page, 0);
         if (rc == 0) {
                 /* bug 1598: don't clobber blksize */
@@ -443,170 +203,171 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
         return rc;
 }
 
-/*
- * background file writeback.  This is called regularly from kupdated to write
- * dirty data, from kswapd when memory is low, and from filemap_fdatasync when
- * super blocks or inodes are synced..
- *
- * obd_brw errors down in _batch_writepage are ignored, so pages are always
- * unlocked.  Also, there is nobody to return an error code to from here - the
- * application may not even be running anymore.
- *
- * this should be async so that things like kswapd can have a chance to
- * free some more pages that our allocating writeback may need, but it isn't
- * yet.
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static unsigned long ll_local_cache_dirty_pages;
-static unsigned long ll_max_dirty_pages = 20 * 1024 * 1024 / PAGE_SIZE;
+int ll_write_count(struct page *page)
+{
+        struct inode *inode = page->mapping->host;
 
-static spinlock_t ll_local_cache_page_count_lock = SPIN_LOCK_UNLOCKED;
+        /* catch race with truncate */
+        if (((loff_t)page->index << PAGE_SHIFT) >= inode->i_size)
+                return 0;
 
-int ll_rd_dirty_pages(char *page, char **start, off_t off, int count, int *eof,
-                      void *data)
-{
-        unsigned long dirty_count;
-        spin_lock(&ll_local_cache_page_count_lock);
-        dirty_count = ll_local_cache_dirty_pages;
-        spin_unlock(&ll_local_cache_page_count_lock);
-        return snprintf(page, count, "%lu\n", dirty_count);
+        /* catch sub-page write at end of file */
+        if (((loff_t)page->index << PAGE_SHIFT) + PAGE_SIZE > inode->i_size)
+                return inode->i_size % PAGE_SIZE;
+
+        return PAGE_SIZE;
 }
 
-int ll_rd_max_dirty_pages(char *page, char **start, off_t off, int count,
-                          int *eof, void *data)
+struct ll_async_page *llap_from_cookie(void *cookie)
 {
-        unsigned long max_dirty;
-        spin_lock(&ll_local_cache_page_count_lock);
-        max_dirty = ll_max_dirty_pages;
-        spin_unlock(&ll_local_cache_page_count_lock);
-        return snprintf(page, count, "%lu\n", max_dirty);
-}
+        struct ll_async_page *llap = cookie;
+        if (llap->llap_magic != LLAP_MAGIC)
+                return ERR_PTR(-EINVAL);
+        return llap;
+};
 
-int ll_wr_max_dirty_pages(struct file *file, const char *buffer,
-                          unsigned long count, void *data)
+static int ll_ap_make_ready(void *data, int cmd)
 {
-        unsigned long max_dirty;
-        signed long max_dirty_signed;
-        char kernbuf[20], *end;
+        struct ll_async_page *llap;
+        struct page *page;
+        ENTRY;
         
-        if (count > (sizeof(kernbuf) - 1))
-                return -EINVAL;
+        /* reads are always locked between queueing and completion, 
+         * llite should never queue pages without _READY */
+        LASSERT(cmd != OBD_BRW_READ);
 
-        if (copy_from_user(kernbuf, buffer, count))
-                return -EFAULT;
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) 
+                RETURN(-EINVAL);
 
-        kernbuf[count] = '\0';
+        page = llap->llap_page;
 
-        max_dirty_signed = simple_strtol(kernbuf, &end, 0);
-        if (kernbuf == end)
-                return -EINVAL;
-        max_dirty = (unsigned long)max_dirty_signed;
+        if (TryLockPage(page))
+                RETURN(-EBUSY);
 
-#if 0
-        if (max_dirty < ll_local_cache_dirty_pages)
-                flush_to_new_max_dirty();
-#endif
+        LL_CDEBUG_PAGE(page, "made ready\n");
+        page_cache_get(page);
 
-        spin_lock(&ll_local_cache_page_count_lock);
-        CDEBUG(D_CACHE, "changing max_dirty from %lu to %lu\n",
-               ll_max_dirty_pages, max_dirty);
-        ll_max_dirty_pages = max_dirty;
-        spin_unlock(&ll_local_cache_page_count_lock);
-        return count;
+        /* if we left PageDirty we might get another writepage call
+         * in the future.  list walkers are bright enough
+         * to check page dirty so we can leave it on whatever list
+         * its on.  XXX also, we're called with the cli list so if
+         * we got the page cache list we'd create a lock inversion
+         * with the removepage path which gets the page lock then the
+         * cli lock */
+        clear_page_dirty(page);
+        RETURN(0);
 }
 
-static int ll_local_cache_full(void)
+static int ll_ap_refresh_count(void *data, int cmd)
 {
-        int full = 0;
-        spin_lock(&ll_local_cache_page_count_lock);
-        if (ll_max_dirty_pages &&
-            ll_local_cache_dirty_pages >= ll_max_dirty_pages) {
-                full = 1;
-        }
-        spin_unlock(&ll_local_cache_page_count_lock);
-        /* XXX instrument? */
-        /* XXX trigger async writeback when full, or 75% of full? */
-        return full;
-}
+        struct ll_async_page *llap;
+        ENTRY;
 
-static void ll_local_cache_flushed_pages(unsigned long pgcount)
-{
-        unsigned long dirty_count;
-        spin_lock(&ll_local_cache_page_count_lock);
-        dirty_count = ll_local_cache_dirty_pages;
-        ll_local_cache_dirty_pages -= pgcount;
-        CDEBUG(D_CACHE, "dirty pages: %lu->%lu)\n",
-               dirty_count, ll_local_cache_dirty_pages);
-        spin_unlock(&ll_local_cache_page_count_lock);
-        LASSERT(dirty_count >= pgcount);
-}
+        /* readpage queues with _COUNT_STABLE, shouldn't get here. */
+        LASSERT(cmd != OBD_BRW_READ);
 
-static void ll_local_cache_dirtied_pages(unsigned long pgcount)
-{
-        unsigned long dirty_count;
-        spin_lock(&ll_local_cache_page_count_lock);
-        dirty_count = ll_local_cache_dirty_pages;
-        ll_local_cache_dirty_pages += pgcount;
-        CDEBUG(D_CACHE, "dirty pages: %lu->%lu\n",
-               dirty_count, ll_local_cache_dirty_pages);
-        spin_unlock(&ll_local_cache_page_count_lock);
-        /* XXX track maximum cached, report to lprocfs */
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap))
+                RETURN(PTR_ERR(llap));
+
+        return ll_write_count(llap->llap_page);
 }
 
-int ll_clear_dirty_pages(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                         unsigned long start, unsigned long end)
+void ll_inode_fill_obdo(struct inode *inode, int cmd, struct obdo *oa)
 {
-        unsigned long cleared;
-        int rc;
+        struct lov_stripe_md *lsm;
+        obd_flag valid_flags;
 
-        ENTRY;
-        rc = obd_clear_dirty_pages(conn, lsm, start, end, &cleared);
-        if (!rc)
-                ll_local_cache_flushed_pages(cleared);
-        RETURN(rc);
+        lsm = ll_i2info(inode)->lli_smd;
+
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_valid = OBD_MD_FLID;
+        valid_flags = OBD_MD_FLTYPE | OBD_MD_FLATIME;
+        if (cmd == OBD_BRW_WRITE) {
+                oa->o_valid |= OBD_MD_FLIFID | OBD_MD_FLEPOCH;
+                mdc_pack_fid(obdo_fid(oa), inode->i_ino, 0, inode->i_mode);
+                oa->o_easize = ll_i2info(inode)->lli_io_epoch;
+
+                valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME;
+        }
+
+        obdo_from_inode(oa, inode, valid_flags);
 }
 
-int ll_mark_dirty_page(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                       unsigned long index)
+static void ll_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
 {
-        int rc;
-
+        struct ll_async_page *llap;
         ENTRY;
-        if (ll_local_cache_full())
-                RETURN(-EDQUOT);
 
-        rc = obd_mark_page_dirty(conn, lsm, index);
-        if (!rc)
-                ll_local_cache_dirtied_pages(1);
-        RETURN(rc);
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) {
+                EXIT;
+                return;
+        }
+
+        ll_inode_fill_obdo(llap->llap_page->mapping->host, cmd, oa);
+        EXIT;
 }
 
-static int ll_writepage(struct page *page)
+static struct obd_async_page_ops ll_async_page_ops = {
+        .ap_make_ready =        ll_ap_make_ready,
+        .ap_refresh_count =     ll_ap_refresh_count,
+        .ap_fill_obdo =         ll_ap_fill_obdo,
+        .ap_completion =        ll_ap_completion,
+};
+
+/* XXX have the exp be an argument? */
+struct ll_async_page *llap_from_page(struct page *page)
 {
+        struct ll_async_page *llap;
+        struct obd_export *exp;
         struct inode *inode = page->mapping->host;
-        struct obdo oa;
+        int rc;
         ENTRY;
 
-        CDEBUG(D_CACHE, "page %p [lau %d] inode %p\n", page,
-               PageLaunder(page), inode);
-        LASSERT(PageLocked(page));
-
-        oa.o_id = ll_i2info(inode)->lli_smd->lsm_object_id;
-        oa.o_valid = OBD_MD_FLID;
-        obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
-                                    OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+        if (page->private != 0) {
+                llap = (struct ll_async_page *)page->private;
+                if (llap->llap_magic != LLAP_MAGIC)
+                        RETURN(ERR_PTR(-EINVAL));
+                RETURN(llap);
+        } 
+
+        exp = ll_i2obdexp(page->mapping->host);
+        if (exp == NULL)
+                RETURN(ERR_PTR(-EINVAL));
+
+        OBD_ALLOC(llap, sizeof(*llap));
+        llap->llap_magic = LLAP_MAGIC;
+        rc = obd_prep_async_page(exp, ll_i2info(inode)->lli_smd,
+                                 NULL, page, 
+                                 (obd_off)page->index << PAGE_SHIFT,
+                                 &ll_async_page_ops, llap, &llap->llap_cookie);
+        if (rc) {
+                OBD_FREE(llap, sizeof(*llap));
+                RETURN(ERR_PTR(rc));
+        }
 
-        RETURN(ll_batch_writepage(inode, &oa, page));
+        CDEBUG(D_CACHE, "llap %p page %p cookie %p obj off "LPU64"\n", llap, 
+               page, llap->llap_cookie, (obd_off)page->index << PAGE_SHIFT);
+        page->private = (unsigned long)llap;
+        llap->llap_page = page;
+        RETURN(llap);
 }
 
-/*
- * we really don't want to start writeback here, we want to give callers some
- * time to further dirty the pages before we write them out.
- */
-static int ll_commit_write(struct file *file, struct page *page,
-                           unsigned from, unsigned to)
+/* update our write count to account for i_size increases that may have
+ * happened since we've queued the page for io. */
+
+/* be careful not to return success without setting the page Uptodate or
+ * the next pass through prepare_write will read in stale data from disk. */
+int ll_commit_write(struct file *file, struct page *page, unsigned from,
+                    unsigned to)
 {
         struct inode *inode = page->mapping->host;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct lov_stripe_md *lsm = lli->lli_smd;
+        struct obd_export *exp = NULL;
+        struct ll_async_page *llap;
         loff_t size;
         int rc = 0;
         ENTRY;
@@ -617,152 +378,273 @@ static int ll_commit_write(struct file *file, struct page *page,
 
         CDEBUG(D_INODE, "inode %p is writing page %p from %d to %d at %lu\n",
                inode, page, from, to, page->index);
+
+        llap = llap_from_page(page);
+        if (IS_ERR(llap))
+                RETURN(PTR_ERR(llap));
+
+        /* queue a write for some time in the future the first time we
+         * dirty the page */
         if (!PageDirty(page)) {
                 lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats,
                                      LPROC_LL_DIRTY_MISSES);
-                rc = ll_mark_dirty_page(ll_i2obdconn(inode),
-                                        ll_i2info(inode)->lli_smd,
-                                        page->index);
-                if (rc < 0 && rc != -EDQUOT)
-                        RETURN(rc); /* XXX lproc counter here? */
+
+                exp = ll_i2obdexp(inode);
+                if (exp == NULL)
+                        RETURN(-EINVAL);
+
+                rc = obd_queue_async_io(exp, lsm, NULL, llap->llap_cookie, 
+                                        OBD_BRW_WRITE, 0, 0, 0, 0);
+                if (rc != 0) { /* async failed, try sync.. */
+                        struct obd_sync_io_container osic;
+                        osic_init(&osic);
+
+                        rc = obd_queue_sync_io(exp, lsm, NULL, &osic, 
+                                               llap->llap_cookie, 
+                                               OBD_BRW_WRITE, 0, to, 0);
+                        if (rc)
+                                GOTO(out, rc);
+
+                        rc = obd_trigger_sync_io(exp, lsm, NULL, &osic);
+                        if (rc)
+                                GOTO(out, rc);
+
+                        rc = osic_wait(&osic);
+                        GOTO(out, rc);
+                }
+                LL_CDEBUG_PAGE(page, "write queued\n");
+                llap->llap_queued = 1;
+                //llap_write_pending(inode, llap);
         } else {
                 lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats,
                                      LPROC_LL_DIRTY_HITS);
         }
 
-        size = (((obd_off)page->index) << PAGE_SHIFT) + to;
-        if (size > inode->i_size)
-                inode->i_size = size;
-
-        SetPageUptodate(page);
+        /* put the page in the page cache, from now on ll_removepage is 
+         * responsible for cleaning up the llap */
         set_page_dirty(page);
 
-        /* This means that we've hit either the local cache limit or the limit
-         * of the OST's grant. */
-        if (rc == -EDQUOT) {
-                struct ll_file_data *fd = file->private_data;
-                struct obdo oa;
-                int rc;
-
-                oa.o_id = ll_i2info(inode)->lli_smd->lsm_object_id;
-                memcpy(obdo_handle(&oa), &fd->fd_ost_och.och_fh,
-                       sizeof(fd->fd_ost_och.och_fh));
-                oa.o_valid = OBD_MD_FLID | OBD_MD_FLHANDLE;
-                obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
-                                            OBD_MD_FLMTIME | OBD_MD_FLCTIME);
-
-                rc = ll_batch_writepage(inode, &oa, page);
-                lock_page(page); /* caller expects to unlock */
-                RETURN(rc);
+out:
+        if (rc == 0) {
+                /* XXX needs to be pushed down to the OSC as EOC */
+                size = (((obd_off)page->index) << PAGE_SHIFT) + to;
+                if (size > inode->i_size) {
+                        inode->i_size = size;
+                        /* see commentary in file.c:ll_inode_getattr() */
+                        set_bit(LLI_F_PREFER_EXTENDED_SIZE, &lli->lli_flags);
+                }
+                SetPageUptodate(page);
         }
+        RETURN(rc);
+}
 
-        RETURN(0);
-} /* ll_commit_write */
-#else
-static int ll_writepage(struct page *page,
-                        struct writeback_control *wbc)
+/* the kernel calls us here when a page is unhashed from the page cache.
+ * the page will be locked and the kernel is holding a spinlock, so
+ * we need to be careful.  we're just tearing down our book-keeping
+ * here. */
+void ll_removepage(struct page *page)
 {
+        struct inode *inode = page->mapping->host;
+        struct obd_export *exp;
+        struct ll_async_page *llap;
+        int rc;
+        ENTRY;
+
+        LASSERT(!in_interrupt());
+
+        /* sync pages or failed read pages can leave pages in the page
+         * cache that don't have our data associated with them anymore */
+        if (page->private == 0) {
+                EXIT;
+                return;
+        }
 
-        return 0;
+        LL_CDEBUG_PAGE(page, "being evicted\n");
+
+        exp = ll_i2obdexp(inode);
+        if (exp == NULL) {
+                CERROR("page %p ind %lu gave null export\n", page, 
+                       page->index);
+                EXIT;
+                return;
+        }
+
+        llap = llap_from_page(page);
+        if (IS_ERR(llap)) {
+                CERROR("page %p ind %lu couldn't find llap: %ld\n", page, 
+                       page->index, PTR_ERR(llap));
+                EXIT;
+                return;
+        }
+
+        //llap_write_complete(inode, llap);
+        rc = obd_teardown_async_page(exp, ll_i2info(inode)->lli_smd, NULL, 
+                                     llap->llap_cookie);
+        if (rc != 0)
+                CERROR("page %p ind %lu failed: %d\n", page, page->index, rc);
+
+        /* this unconditional free is only safe because the page lock
+         * is providing exclusivity to memory pressure/truncate/writeback..*/
+        page->private = 0;
+        OBD_FREE(llap, sizeof(*llap));
+        EXIT;
 }
-static int ll_commit_write(struct file *file, struct page *page,
-                           unsigned from, unsigned to)
+
+static int ll_start_readpage(struct obd_export *exp, struct inode *inode, 
+                             struct page *page)
 {
-        return 0;
+        struct ll_async_page *llap;
+        int rc;
+        ENTRY;
+
+        llap = llap_from_page(page);
+        if (IS_ERR(llap))
+                RETURN(PTR_ERR(llap));
+
+        page_cache_get(page);
+
+        rc = obd_queue_async_io(exp, ll_i2info(inode)->lli_smd, NULL, 
+                                llap->llap_cookie, OBD_BRW_READ, 0, PAGE_SIZE, 
+                                0, ASYNC_READY | ASYNC_URGENT | 
+                                   ASYNC_COUNT_STABLE);
+        /* XXX verify that failed pages here will make their way
+         * through ->removepage.. I suspect they will. */
+        if (rc)
+                page_cache_release(page);
+        else  {
+                llap->llap_queued = 1;
+                LL_CDEBUG_PAGE(page, "read queued\n");
+        }
+        RETURN(rc);
 }
-#endif
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int ll_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
-                        unsigned long blocknr, int blocksize)
+static void ll_start_readahead(struct obd_export *exp, struct inode *inode, 
+                               unsigned long first_index)
 {
-        struct ll_inode_info *lli = ll_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct brw_page *pga;
-        struct ptlrpc_request_set *set;
-        struct obdo oa;
-        int length, i, flags, rc = 0;
-        loff_t offset;
-        ENTRY;
+        struct lustre_handle match_lockh = {0};
+        struct ldlm_extent page_extent;
+        unsigned long index, end_index;
+        struct page *page;
+        int flags, matched, rc;
+
+        /* for good throughput we need to have many 'blksize' rpcs in
+         * flight per stripe, so we try to read-ahead a ridiculous amount
+         * of data. "- 3" for 8 rpcs */
+        end_index = first_index + (inode->i_blksize >> (PAGE_CACHE_SHIFT - 3));
+        if (end_index > (inode->i_size >> PAGE_CACHE_SHIFT))
+                end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 
-        if (!lsm || !lsm->lsm_object_id)
-                RETURN(-EBADF);
+        for (index = first_index + 1; index < end_index; index++) {
+                /* try to get a ref on an existing page or create a new
+                 * one.  if we find a locked page or lose the race
+                 * with another reader we stop trying */
+                page = grab_cache_page_nowait(inode->i_mapping, index);
+                if (page == NULL)
+                        break;
+                /* make sure we didn't race with other teardown/readers */
+                if (!page->mapping || Page_Uptodate(page)) {
+                        unlock_page(page);
+                        page_cache_release(page);
+                        continue;
+                }
 
-        /* FIXME: io smaller than PAGE_SIZE is broken on ia64 */
-        if ((iobuf->offset & (PAGE_SIZE - 1)) ||
-            (iobuf->length & (PAGE_SIZE - 1)))
-                RETURN(-EINVAL);
+                /* make sure the page we're about to read is covered
+                 * by a lock, stop when we go past the end of the lock */
+                page_extent.start = (__u64)page->index << PAGE_CACHE_SHIFT;
+                page_extent.end = page_extent.start + PAGE_CACHE_SIZE - 1;
+                flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED;
+                matched = obd_match(ll_i2sbi(inode)->ll_osc_exp, 
+                                    ll_i2info(inode)->lli_smd, LDLM_EXTENT,
+                                    &page_extent, sizeof(page_extent), LCK_PR, 
+                                    &flags, inode, &match_lockh);
+                if (!matched) {
+                        LL_CDEBUG_PAGE(page, "didn't match a lock\n");
+                        unlock_page(page);
+                        page_cache_release(page);
+                        break;
+                }
 
-        set = ptlrpc_prep_set();
-        if (set == NULL)
-                RETURN(-ENOMEM);
+                /* interestingly, we don't need to hold the lock across the IO.
+                 * As long as we match the lock while the page is locked in the
+                 * page cache we know that the lock's cancelation will wait for
+                 * the page to be unlocked.  XXX this should transition to
+                 * proper association of pages and locks in the future */
+                obd_cancel(ll_i2sbi(inode)->ll_osc_exp,
+                           ll_i2info(inode)->lli_smd, LCK_PR, &match_lockh);
 
-        OBD_ALLOC(pga, sizeof(*pga) * iobuf->nr_pages);
-        if (!pga) {
-                ptlrpc_set_destroy(set);
-                RETURN(-ENOMEM);
+                rc = ll_start_readpage(exp, inode, page);
+                if (rc != 0) {
+                        unlock_page(page);
+                        page_cache_release(page);
+                        break;
+                }
+                page_cache_release(page);
         }
+}
+/*
+ * for now we do our readpage the same on both 2.4 and 2.5.  The kernel's
+ * read-ahead assumes it is valid to issue readpage all the way up to
+ * i_size, but our dlm locks make that not the case.  We disable the
+ * kernel's read-ahead and do our own by walking ahead in the page cache
+ * checking for dlm lock coverage.  the main difference between 2.4 and
+ * 2.6 is how read-ahead gets batched and issued, but we're using our own,
+ * so they look the same.
+ */
+int ll_readpage(struct file *file, struct page *page)
+{
+        struct inode *inode = page->mapping->host;
+        struct lustre_handle match_lockh = {0};
+        struct obd_export *exp;
+        struct ldlm_extent page_extent;
+        int flags, rc = 0, matched;
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        ENTRY;
 
-        flags = (rw == WRITE ? OBD_BRW_CREATE : 0) /* | OBD_BRW_DIRECTIO */;
-        offset = ((obd_off)blocknr << inode->i_blkbits);
-        length = iobuf->length;
-
-        for (i = 0, length = iobuf->length; length > 0;
-             length -= pga[i].count, offset += pga[i].count, i++) { /*i last!*/
-                pga[i].pg = iobuf->maplist[i];
-                pga[i].off = offset;
-                /* To the end of the page, or the length, whatever is less */
-                pga[i].count = min_t(int, PAGE_SIZE - (offset & ~PAGE_MASK),
-                                     length);
-                pga[i].flag = flags;
-                if (rw == READ) {
-                        //POISON(kmap(iobuf->maplist[i]), 0xc5, PAGE_SIZE);
-                        //kunmap(iobuf->maplist[i]);
-                }
+        LASSERT(PageLocked(page));
+        LASSERT(!PageUptodate(page));
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),offset="LPX64"\n",
+               inode->i_ino, inode->i_generation, inode,
+               (((obd_off)page->index) << PAGE_SHIFT));
+        LASSERT(atomic_read(&file->f_dentry->d_inode->i_count) > 0);
+
+        if (inode->i_size <= ((obd_off)page->index) << PAGE_SHIFT) {
+                CERROR("reading beyond EOF\n");
+                memset(kmap(page), 0, PAGE_SIZE);
+                kunmap(page);
+                SetPageUptodate(page);
+                GOTO(out, rc = 0);
         }
 
-        oa.o_id = lsm->lsm_object_id;
-        oa.o_valid = OBD_MD_FLID;
-        obdo_from_inode(&oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
-                                    OBD_MD_FLMTIME | OBD_MD_FLCTIME);
+        exp = ll_i2obdexp(inode);
+        if (exp == NULL)
+                GOTO(out, rc = -EINVAL);
 
-        if (rw == WRITE)
-                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                    LPROC_LL_DIRECT_WRITE, iobuf->length);
-        else
-                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
-                                    LPROC_LL_DIRECT_READ, iobuf->length);
-        rc = obd_brw_async(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ,
-                           ll_i2obdconn(inode), &oa, lsm, iobuf->nr_pages, pga,
-                           set, NULL);
-        if (rc) {
-                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
-                       "error from obd_brw_async: rc = %d\n", rc);
-        } else {
-                rc = ptlrpc_set_wait(set);
-                if (rc)
-                        CERROR("error from callback: rc = %d\n", rc);
+        page_extent.start = (__u64)page->index << PAGE_CACHE_SHIFT;
+        page_extent.end = page_extent.start + PAGE_CACHE_SIZE - 1;
+        flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED;
+        matched = obd_match(sbi->ll_osc_exp, ll_i2info(inode)->lli_smd, 
+                            LDLM_EXTENT, &page_extent, sizeof(page_extent), 
+                            LCK_PR, &flags, inode, &match_lockh);
+
+        if (!matched) {
+                static unsigned long next_print;
+                CDEBUG(D_INODE, "didn't match a lock");
+                if (time_after(jiffies, next_print)) {
+                        next_print = jiffies + 30 * HZ;
+                        CERROR("not covered by a lock (mmap?).  check debug "
+                               "logs.\n");
+                }
         }
-        ptlrpc_set_destroy(set);
-        if (rc == 0)
-                rc = iobuf->length;
 
-        OBD_FREE(pga, sizeof(*pga) * iobuf->nr_pages);
+        rc = ll_start_readpage(exp, inode, page);
+        if (rc == 0 && (sbi->ll_flags & LL_SBI_READAHEAD))
+                ll_start_readahead(exp, inode, page->index);
+
+        if (matched)
+                obd_cancel(ll_i2sbi(inode)->ll_osc_exp, 
+                           ll_i2info(inode)->lli_smd, LCK_PR, &match_lockh);
+out:
+        if (rc)
+                unlock_page(page);
         RETURN(rc);
 }
-#endif
-
-//#endif
-
-struct address_space_operations ll_aops = {
-        readpage: ll_readpage,
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))
-        direct_IO: ll_direct_IO,
-#endif
-        writepage: ll_writepage,
-        sync_page: block_sync_page,
-        prepare_write: ll_prepare_write,
-        commit_write: ll_commit_write,
-        bmap: NULL
-//#endif
-};
diff --git a/lustre/llite/rw24.c b/lustre/llite/rw24.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe11b2747a88a66e8aafe28208cc380262790341
--- /dev/null
+++ b/lustre/llite/rw24.c
@@ -0,0 +1,214 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Lite I/O page cache for the 2.4 kernel version
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/smp_lock.h>
+#include <linux/unistd.h>
+#include <linux/version.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/fs.h>
+#include <linux/iobuf.h>
+#include <linux/stat.h>
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <linux/lustre_mds.h>
+#include <linux/lustre_lite.h>
+#include "llite_internal.h"
+#include <linux/lustre_compat25.h>
+
+/* called for each page in a completed rpc.*/
+void ll_ap_completion_24(void *data, int cmd, int rc)
+{
+        struct ll_async_page *llap;
+        struct page *page;
+
+        llap = llap_from_cookie(data);
+        if (IS_ERR(llap)) {
+                EXIT;
+                return;
+        }
+
+        llap->llap_queued = 0;
+        page = llap->llap_page;
+
+        LASSERT(PageLocked(page));
+
+        if (rc == 0)  {
+                if (cmd == OBD_BRW_READ)
+                        SetPageUptodate(page);
+        } else { 
+                SetPageError(page);
+        }
+
+        LL_CDEBUG_PAGE(page, "io complete, unlocking\n");
+
+        unlock_page(page);
+
+        if (0 && cmd == OBD_BRW_WRITE) {
+                llap_write_complete(page->mapping->host, llap);
+                ll_try_done_writing(page->mapping->host);
+        }
+
+        page_cache_release(page);
+}
+
+static int ll_writepage_24(struct page *page)
+{
+        struct inode *inode = page->mapping->host;
+        struct obd_export *exp;
+        struct ll_async_page *llap;
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(!PageDirty(page));
+        LASSERT(PageLocked(page));
+
+        exp = ll_i2obdexp(inode);
+        if (exp == NULL)
+                GOTO(out, rc = -EINVAL);
+
+        llap = llap_from_page(page);
+        if (IS_ERR(llap))
+                GOTO(out, rc = PTR_ERR(llap));
+
+        page_cache_get(page);
+        if (llap->llap_queued) {
+                LL_CDEBUG_PAGE(page, "marking urgent\n");
+                rc = obd_set_async_flags(exp, ll_i2info(inode)->lli_smd, NULL, 
+                                         llap->llap_cookie, ASYNC_READY | 
+                                         ASYNC_URGENT);
+        } else {
+                rc = obd_queue_async_io(exp, ll_i2info(inode)->lli_smd, NULL, 
+                                        llap->llap_cookie, OBD_BRW_WRITE, 0, 0, 
+                                        OBD_BRW_CREATE, ASYNC_READY | 
+                                        ASYNC_URGENT);
+                if (rc == 0) {
+                        LL_CDEBUG_PAGE(page, "mmap write queued\n");
+                        llap->llap_queued = 1;
+                }
+        }
+        if (rc)
+                page_cache_release(page);
+out:
+        if (rc)
+                unlock_page(page);
+        RETURN(rc);
+}
+
+static int ll_direct_IO_24(int rw, struct inode *inode, struct kiobuf *iobuf,
+                           unsigned long blocknr, int blocksize)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct lov_stripe_md *lsm = lli->lli_smd;
+        struct brw_page *pga;
+        struct ptlrpc_request_set *set;
+        struct obdo oa;
+        int length, i, flags, rc = 0;
+        loff_t offset;
+        ENTRY;
+
+        if (!lsm || !lsm->lsm_object_id)
+                RETURN(-EBADF);
+
+        /* FIXME: io smaller than PAGE_SIZE is broken on ia64 */
+        if ((iobuf->offset & (PAGE_SIZE - 1)) ||
+            (iobuf->length & (PAGE_SIZE - 1)))
+                RETURN(-EINVAL);
+
+        set = ptlrpc_prep_set();
+        if (set == NULL)
+                RETURN(-ENOMEM);
+
+        OBD_ALLOC(pga, sizeof(*pga) * iobuf->nr_pages);
+        if (!pga) {
+                ptlrpc_set_destroy(set);
+                RETURN(-ENOMEM);
+        }
+
+        flags = (rw == WRITE ? OBD_BRW_CREATE : 0) /* | OBD_BRW_DIRECTIO */;
+        offset = ((obd_off)blocknr << inode->i_blkbits);
+        length = iobuf->length;
+
+        for (i = 0, length = iobuf->length; length > 0;
+             length -= pga[i].count, offset += pga[i].count, i++) { /*i last!*/
+                pga[i].pg = iobuf->maplist[i];
+                pga[i].off = offset;
+                /* To the end of the page, or the length, whatever is less */
+                pga[i].count = min_t(int, PAGE_SIZE - (offset & ~PAGE_MASK),
+                                     length);
+                pga[i].flag = flags;
+                if (rw == READ)
+                        POISON_PAGE(iobuf->maplist[i], 0x0d);
+        }
+
+        ll_inode_fill_obdo(inode, rw, &oa);
+
+        if (rw == WRITE)
+                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
+                                    LPROC_LL_DIRECT_WRITE, iobuf->length);
+        else
+                lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
+                                    LPROC_LL_DIRECT_READ, iobuf->length);
+        rc = obd_brw_async(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ,
+                           ll_i2obdexp(inode), &oa, lsm, iobuf->nr_pages, pga,
+                           set, NULL);
+        if (rc) {
+                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
+                       "error from obd_brw_async: rc = %d\n", rc);
+        } else {
+                rc = ptlrpc_set_wait(set);
+                if (rc)
+                        CERROR("error from callback: rc = %d\n", rc);
+        }
+        ptlrpc_set_destroy(set);
+        if (rc == 0) {
+                rc = iobuf->length;
+                obdo_to_inode(inode, &oa, OBD_MD_FLBLOCKS);
+        }
+
+        OBD_FREE(pga, sizeof(*pga) * iobuf->nr_pages);
+        RETURN(rc);
+}
+
+struct address_space_operations ll_aops = {
+        readpage: ll_readpage,
+        direct_IO: ll_direct_IO_24,
+        writepage: ll_writepage_24,
+        prepare_write: ll_prepare_write,
+        commit_write: ll_commit_write,
+        removepage: ll_removepage,
+        bmap: NULL
+};
diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c
new file mode 100644
index 0000000000000000000000000000000000000000..2df14c40234554e3341ee817ff214d2230af5f26
--- /dev/null
+++ b/lustre/llite/rw26.c
@@ -0,0 +1,118 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Lustre Lite I/O page cache routines for the 2.5/2.6 kernel version
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/smp_lock.h>
+#include <linux/unistd.h>
+#include <linux/version.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/mpage.h>
+#include <linux/writeback.h>
+#include <linux/stat.h>
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <linux/lustre_mds.h>
+#include <linux/lustre_lite.h>
+#include "llite_internal.h"
+#include <linux/lustre_compat25.h>
+
+/* called as the osc engine completes an rpc that included our ocp.  
+ * the ocp itself holds a reference to the page and will drop it when
+ * the page is removed from the page cache.  our job is simply to
+ * transfer rc into the page and unlock it */
+void ll_complete_writepage_26(struct obd_client_page *ocp, int rc)
+{
+        struct page *page = ocp->ocp_page;
+
+        LASSERT(page->private == (unsigned long)ocp);
+        LASSERT(PageLocked(page));
+
+        if (rc != 0) {
+                CERROR("writeback error on page %p index %ld: %d\n", page,
+                       page->index, rc);
+                SetPageError(page);
+        }
+        ocp->ocp_flags &= ~OCP_IO_READY;
+
+        /* let everyone get at this page again.. I wonder if this ordering
+         * is corect */
+        unlock_page(page);
+        end_page_writeback(page);
+
+        page_cache_release(page);
+}
+
+static int ll_writepage_26(struct page *page, struct writeback_control *wbc)
+{
+        struct obd_client_page *ocp;
+        ENTRY;
+
+        LASSERT(!PageDirty(page));
+        LASSERT(PageLocked(page));
+        LASSERT(page->private != 0);
+
+        ocp = (struct obd_client_page *)page->private;
+        ocp->ocp_flags |= OCP_IO_READY;
+
+        page_cache_get(page);
+
+        /* filemap_fdatawait() makes me think we need to set PageWriteback
+         * on pages that are in flight.  But our ocp mechanics doesn't
+         * really expect a page to be on both the osc lru and in flight.
+         * so for now, we don't unlock the page.. dirtiers whill wait
+         * for io to complete */
+        SetPageWriteback(page);
+
+        /* sadly, not all callers who writepage eventually call sync_page
+         * (ahem, kswapd) so we need to raise this page's priority 
+         * immediately */
+        RETURN(ll_sync_page(page));
+}
+
+struct address_space_operations ll_aops = {
+        readpage: ll_readpage,
+//        readpages: ll_readpages,
+//        direct_IO: ll_direct_IO_26,
+        writepage: ll_writepage_26,
+        writepages: generic_writepages,
+        set_page_dirty: __set_page_dirty_nobuffers,
+        sync_page: block_sync_page,
+        prepare_write: ll_prepare_write,
+        commit_write: ll_commit_write,
+        bmap: NULL
+};
diff --git a/lustre/llite/special.c b/lustre/llite/special.c
new file mode 100644
index 0000000000000000000000000000000000000000..aeb281b1e62b657260142b3a7b60a7328d5ba301
--- /dev/null
+++ b/lustre/llite/special.c
@@ -0,0 +1,365 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+#include <linux/lustre_lite.h>
+#include <linux/file.h>
+#include <asm/poll.h>
+#include "llite_internal.h"
+
+#define FILE_OPS 0 
+#define INODE_OPS 1 
+
+static inline struct file_operations** 
+get_save_fops(struct file* filp, int mode)
+{
+        struct inode *inode = filp->f_dentry->d_inode;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        if (mode == FILE_OPS){
+                if (S_ISFIFO(inode->i_mode)){
+                        switch (filp->f_mode) {
+                        case 1: /*O_RDONLY*/
+                                return &(lli->ll_save_ffop);
+                        case 2: /*O_WRONLY*/
+                                return &(lli->ll_save_wfop);
+                        case 3: /* O_RDWR */
+                                return &(lli->ll_save_wrfop);
+                        default:
+                                return NULL;
+                        }
+                }
+                return &(lli->ll_save_ffop);
+        } else
+                return &(lli->ll_save_ifop);
+
+}
+                                          
+
+static inline void save_fops(struct file *filp, struct inode *inode,
+                             struct file_operations *sfops) 
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        
+        if (sfops != filp->f_op) {
+                struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+                
+                *pfop = filp->f_op;
+                if (S_ISCHR(inode->i_mode)) {
+                        filp->f_op = &ll_special_chr_file_fops;
+                }else if (S_ISFIFO(inode->i_mode)){
+                        filp->f_op = &ll_special_fifo_file_fops;
+                }
+                filp->f_op->owner = lli->ll_save_ffop->owner; 
+        }
+}
+
+static ssize_t ll_special_file_read(struct file *filp, char *buf, 
+                                    size_t count, loff_t *ppos)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->read) 
+                rc = (*pfop)->read(filp, buf, count, ppos);
+        
+        RETURN(rc);
+}
+
+static ssize_t ll_special_file_write(struct file *filp, const char *buf, 
+                                     size_t count, loff_t *ppos)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = -EINVAL;
+        
+        if (pfop && *pfop && (*pfop)->write) 
+                rc = (*pfop)->write(filp, buf, count, ppos);
+        
+        RETURN(rc);
+}
+static int ll_special_file_ioctl(struct inode *inode, struct file *filp, 
+                                 unsigned int cmd, unsigned long arg)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = -ENOTTY;
+
+        if (pfop && *pfop && (*pfop)->ioctl) { 
+                struct file_operations *sfops = filp->f_op;
+                
+                rc = (*pfop)->ioctl(inode, filp, cmd, arg);
+                save_fops(filp, inode, sfops);
+        }
+        RETURN(rc);
+}
+
+static loff_t ll_special_file_seek(struct file *filp, loff_t offset, int origin)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = 0;
+
+        if (pfop && *pfop && (*pfop)->llseek)  
+                rc = (*pfop)->llseek(filp, offset, origin);
+        else
+                rc = default_llseek(filp, offset, origin);
+       
+        RETURN(rc);
+}
+
+
+#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
+
+static unsigned int
+ll_special_file_poll(struct file *filp, struct poll_table_struct *poll_table) 
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = DEFAULT_POLLMASK;
+
+        if (pfop && *pfop && (*pfop)->poll)  
+                rc = (*pfop)->poll(filp, poll_table);
+
+        RETURN(rc);
+}
+
+static int ll_special_file_open(struct inode *inode, struct file *filp)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->open)  
+                rc = (*pfop)->open(inode, filp);
+        
+        RETURN(rc);
+}
+
+static ssize_t ll_special_read(struct file *filp, char *buf, 
+                               size_t count, loff_t *ppos)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->read)  
+                rc = (*pfop)->read(filp, buf, count, ppos);
+        
+        RETURN(rc);
+}
+
+static ssize_t ll_special_write(struct file *filp, const char *buf, 
+                                size_t count, loff_t *ppos)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->write)  
+                rc = (*pfop)->write(filp, buf, count, ppos);
+        
+        RETURN(rc);
+}
+
+static int ll_special_ioctl(struct inode *inode, struct file *filp, 
+                            unsigned int cmd, unsigned long arg)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = -ENOTTY;
+
+        if (pfop && *pfop && (*pfop)->ioctl) { 
+                struct file_operations *sfops = filp->f_op;
+                
+                rc = (*pfop)->ioctl(inode, filp, cmd, arg);
+                /* sometimes, file_operations will be changed in ioctl */
+                save_fops(filp, inode, sfops);
+        }
+
+        RETURN(rc);
+}
+
+static int ll_special_mmap(struct file * filp, struct vm_area_struct * vma)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = -ENODEV;
+
+        if (pfop && *pfop && (*pfop)->mmap)  
+                rc = (*pfop)->mmap(filp, vma);
+        
+        RETURN(rc);
+}
+
+static loff_t ll_special_seek(struct file *filp, loff_t offset, int origin)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = 0;
+
+        if (pfop && *pfop && (*pfop)->llseek)  
+                rc = (*pfop)->llseek(filp, offset, origin);
+        else
+                rc = default_llseek(filp, offset, origin);
+       
+        RETURN(rc);
+}
+
+static int ll_special_fsync(struct file *filp, struct dentry *dentry, int data)
+{
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        int    rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->fsync)  
+                rc = (*pfop)->fsync(filp, dentry, data);
+
+        RETURN(rc);
+}
+
+static int ll_special_file_fasync(int fd, struct file *filp, int on)
+{
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int    rc = -EINVAL;
+
+        if (pfop && *pfop && (*pfop)->fasync)  
+                rc = (*pfop)->fasync(fd, filp, on);
+
+        RETURN(rc);
+}
+
+static int ll_special_open(struct inode *inode, struct file *filp)
+{
+        struct ptlrpc_request *req;
+        struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+        struct lookup_intent *it;
+        int rc = -EINVAL;
+        ENTRY;
+        
+        if (pfop && *pfop && (*pfop)->open) { 
+                struct file_operations *sfops = filp->f_op;
+                
+                rc = (*pfop)->open(inode, filp);
+                 /* sometimes the file_operations will be changed in open */
+                save_fops(filp, inode, sfops);
+        }
+        
+        lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
+        
+        it = filp->f_it;
+        
+        rc = ll_local_open(filp, it);
+        if (rc)
+                RETURN(rc);
+        req = it->d.lustre.it_data;
+        if (req)
+                ptlrpc_req_finished(req);
+        
+        RETURN(rc);
+}
+
+static int ll_special_release(struct inode *inode, struct file *filp)
+{
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+       struct file_operations** pfop = get_save_fops (filp, INODE_OPS);
+       int rc = 0, rc2 = 0;
+       ENTRY;
+
+        if (pfop && *pfop && (*pfop)->release) { 
+                rc = (*pfop)->release(inode, filp);
+        }
+        lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
+                
+        rc2 = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
+                
+        if (rc2 && !rc)
+                rc = rc2;
+        
+        RETURN(rc);
+}
+
+static int ll_special_file_release(struct inode *inode, struct file *filp)
+{
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct file_operations** pfop = get_save_fops (filp, FILE_OPS);
+        int rc = 0, rc2 = 0;
+        ENTRY;
+
+        if (pfop && *pfop && (*pfop)->release) { 
+                rc = (*pfop)->release(inode, filp);
+        }
+        lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
+                
+        rc2 = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
+                
+        if (rc2 && !rc)
+               rc = rc2;
+
+        RETURN(rc);
+
+}
+
+struct inode_operations ll_special_inode_operations = {
+        setattr_raw:    ll_setattr_raw,
+        setattr:        ll_setattr,
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+        getattr_it:     ll_getattr,
+#else
+        revalidate_it:  ll_inode_revalidate_it,
+#endif
+};
+
+struct file_operations ll_special_chr_inode_fops = {
+       open:           ll_special_open,
+};
+
+struct file_operations ll_special_blk_inode_fops = {
+        read:           ll_special_read,
+        write:          ll_special_write,
+        ioctl:          ll_special_ioctl,
+        open:           ll_special_open,
+        release:        ll_special_release,
+        mmap:           ll_special_mmap,
+        llseek:         ll_special_seek,
+        fsync:          ll_special_fsync,
+};
+
+struct file_operations ll_special_fifo_inode_fops = {
+        open:           ll_special_open,      
+};
+
+struct file_operations ll_special_sock_inode_fops = {
+        open:           ll_special_open
+};
+
+struct file_operations ll_special_chr_file_fops = {
+	llseek:		ll_special_file_seek,
+	read:		ll_special_file_read,
+	write:		ll_special_file_write,
+	poll:		ll_special_file_poll,
+	ioctl:		ll_special_file_ioctl,
+	open:		ll_special_file_open,
+	release:	ll_special_file_release,
+	fasync:		ll_special_file_fasync,
+};
+
+struct file_operations ll_special_fifo_file_fops = {
+	llseek:		ll_special_file_seek,
+	read:		ll_special_file_read,
+	write:		ll_special_file_write,
+	poll:		ll_special_file_poll,
+	ioctl:		ll_special_file_ioctl,
+	open:		ll_special_file_open,
+	release:	ll_special_file_release,
+};
+
diff --git a/lustre/llite/super.c b/lustre/llite/super.c
index 9a3ffa15d3cfce9c72e6eea29e2a35646be41953..80a69380e29832b4dc3a00286042e53dd4b27b75 100644
--- a/lustre/llite/super.c
+++ b/lustre/llite/super.c
@@ -49,6 +49,17 @@ static struct super_block *ll_read_super(struct super_block *sb,
         RETURN(sb);
 }
 
+static struct super_block *lustre_read_super(struct super_block *sb,
+                                         void *data, int silent)
+{
+        int err;
+        ENTRY;
+        err = lustre_fill_super(sb, data, silent);
+        if (err)
+                RETURN(NULL);
+        RETURN(sb);
+}
+
 /* exported operations */
 struct super_operations ll_super_operations =
 {
@@ -57,19 +68,43 @@ struct super_operations ll_super_operations =
         //        delete_inode: ll_delete_inode,
         put_super: ll_put_super,
         statfs: ll_statfs,
-        umount_begin: ll_umount_begin
+        umount_begin: ll_umount_begin,
+        fh_to_dentry: ll_fh_to_dentry,
+        dentry_to_fh: ll_dentry_to_fh
 };
 
 static struct file_system_type lustre_lite_fs_type = {
         name:           "lustre_lite",
-        fs_flags:       0,
+        fs_flags:       FS_NFSEXP_FSID,
         read_super:     ll_read_super,
         owner:          THIS_MODULE,
 };
 
+/* exported operations */
+struct super_operations lustre_super_operations =
+{
+        read_inode2: ll_read_inode2,
+        clear_inode: ll_clear_inode,
+        //        delete_inode: ll_delete_inode,
+        put_super: lustre_put_super,
+        statfs: ll_statfs,
+        umount_begin: ll_umount_begin,
+        fh_to_dentry: ll_fh_to_dentry,
+        dentry_to_fh: ll_dentry_to_fh
+};
+
+static struct file_system_type lustre_fs_type = {
+        name:           "lustre",
+        fs_flags:       FS_NFSEXP_FSID,
+        read_super:     lustre_read_super,
+        owner:          THIS_MODULE,
+};
+
 static int __init init_lustre_lite(void)
 {
-        printk(KERN_INFO "Lustre Lite Client File System; "
+        int rc;
+
+        printk(KERN_INFO "Lustre: Lustre Lite Client File System; "
                "info@clusterfs.com\n");
         ll_file_data_slab = kmem_cache_create("ll_file_data",
                                               sizeof(struct ll_file_data), 0,
@@ -79,12 +114,19 @@ static int __init init_lustre_lite(void)
 
         proc_lustre_fs_root = proc_lustre_root ? proc_mkdir("llite", proc_lustre_root) : NULL;
 
-        return register_filesystem(&lustre_lite_fs_type);
+        rc = register_filesystem(&lustre_lite_fs_type);
+        if (rc == 0)
+                rc = register_filesystem(&lustre_fs_type);
+        if (rc)
+                unregister_filesystem(&lustre_lite_fs_type);
+        return rc;
 }
 
 static void __exit exit_lustre_lite(void)
 {
         unregister_filesystem(&lustre_lite_fs_type);
+        unregister_filesystem(&lustre_fs_type);
+
         kmem_cache_destroy(ll_file_data_slab);
 
         if (proc_lustre_fs_root) {
diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c
index 5ab03ff6e6459e7d23df7b24955c1815454d133b..6325ae12428903b9938488f534d0cc11a73b5463 100644
--- a/lustre/llite/super25.c
+++ b/lustre/llite/super25.c
@@ -113,7 +113,7 @@ struct file_system_type lustre_lite_fs_type = {
 static int __init init_lustre_lite(void)
 {
         int rc;
-        printk(KERN_INFO "Lustre Lite Client File System; "
+        printk(KERN_INFO "Lustre: Lustre Lite Client File System; "
                "info@clusterfs.com\n");
         rc = ll_init_inodecache();
         if (rc)
diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c
index 427f7f01cdceadec729baaed0dc4b3b558999dd5..3056bf5c995c65d74f842f75c5b09b6e524cb800 100644
--- a/lustre/llite/symlink.c
+++ b/lustre/llite/symlink.c
@@ -48,7 +48,7 @@ static int ll_readlink_internal(struct inode *inode,
         }
 
         ll_inode2fid(&fid, inode);
-        rc = mdc_getattr(&sbi->ll_mdc_conn, &fid,
+        rc = mdc_getattr(sbi->ll_mdc_exp, &fid,
                          OBD_MD_LINKNAME, symlen, request);
         if (rc) {
                 CERROR("inode %lu: rc = %d\n", inode->i_ino, rc);
@@ -127,11 +127,11 @@ static int ll_follow_link(struct dentry *dentry, struct nameidata *nd)
 
         if (it != NULL) {
                 int op = it->it_op;
-                int mode = it->it_mode;
+                int mode = it->it_create_mode;
 
                 ll_intent_release(it);
                 it->it_op = op;
-                it->it_mode = mode;
+                it->it_create_mode = mode;
         }
 
         CDEBUG(D_VFSTRACE, "VFS Op\n");
diff --git a/lustre/lov/Makefile.am b/lustre/lov/Makefile.am
index 83dba1a6a0180481b5dc1eb0ae3551709e48cd57..d6d35d848731d3aa37c213c46475379703edade2 100644
--- a/lustre/lov/Makefile.am
+++ b/lustre/lov/Makefile.am
@@ -7,12 +7,12 @@ DEFS=
 
 if LIBLUSTRE
 lib_LIBRARIES = liblov.a
-liblov_a_SOURCES = lov_obd.c lov_pack.c lov_internal.h
+liblov_a_SOURCES = lov_log.c lov_obd.c lov_pack.c lov_internal.h
 else
 MODULE = lov
 modulefs_DATA = lov.o
 EXTRA_PROGRAMS = lov
-lov_SOURCES = lov_obd.c lov_pack.c lproc_lov.c lov_internal.h
+lov_SOURCES = lov_log.c lov_obd.c lov_pack.c lproc_lov.c lov_internal.h
 endif
 
 include $(top_srcdir)/Rules
diff --git a/lustre/lov/Makefile.mk b/lustre/lov/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..48c14bb22b498115fc4f7ef93a69bfd49f41289b
--- /dev/null
+++ b/lustre/lov/Makefile.mk
@@ -0,0 +1,9 @@
+# Copyright (C) 2003  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += lov.o
+lov-objs := lov_obd.o lov_pack.o lproc_lov.o lov_log.o
diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h
index f3bc1919673f79f243d4ac4961db9e8b3cae4dd3..6c26a166744eec2dac6ca7cb0b78f3ed67042e00 100644
--- a/lustre/lov/lov_internal.h
+++ b/lustre/lov/lov_internal.h
@@ -7,20 +7,44 @@
  * See the file COPYING in this distribution
  */
 
+#ifndef LOV_INTERNAL_H
+#define LOV_INTERNAL_H
+
+#include <linux/lustre_user.h>
+
+#define LAP_MAGIC 8200
+
+struct lov_async_page {
+        int                             lap_magic;
+        int                             lap_stripe;
+        obd_off                         lap_sub_offset;
+        void                            *lap_sub_cookie;
+        struct obd_async_page_ops       *lap_caller_ops;
+        struct obd_async_page_ops       *lap_caller_data;
+        obd_id                          lap_loi_id;
+};
+
 /* lov_obd.c */
 int lov_get_stripecnt(struct lov_obd *lov, int stripe_count);
-int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count);
+int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count, int pattern);
 void lov_free_memmd(struct lov_stripe_md **lsmp);
 
+/* lov_log.c */
+int lov_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                  int count, struct llog_logid *logid);
+int lov_llog_finish(struct obd_device *obd, int count);
+
 /* lov_pack.c */
-int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmm,
+int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm,
                struct lov_stripe_md *lsm);
-int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsm,
-                 struct lov_mds_md *lmm, int lmmsize);
-int lov_setstripe(struct lustre_handle *conn,
-                  struct lov_stripe_md **lsmp, struct lov_mds_md *lmmu);
-int lov_getstripe(struct lustre_handle *conn,
-                  struct lov_stripe_md *lsm, struct lov_mds_md *lmmu);
+int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
+                 struct lov_mds_md *lmm, int lmm_bytes);
+int lov_setstripe(struct obd_export *exp,
+                  struct lov_stripe_md **lsmp, struct lov_user_md *lump);
+int lov_getstripe(struct obd_export *exp,
+                  struct lov_stripe_md *lsm, struct lov_user_md *lump);
 
 /* lproc_lov.c */
 extern struct file_operations lov_proc_target_fops;
+
+#endif
diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b9f6f3e26881a03924941a493880e49f84ece14
--- /dev/null
+++ b/lustre/lov/lov_log.c
@@ -0,0 +1,230 @@
+ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
+ * Author: Phil Schwan <phil@clusterfs.com>
+ *         Peter Braam <braam@clusterfs.com>
+ *         Mike Shaver <shaver@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_LOV
+#ifdef __KERNEL__
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <asm/div64.h>
+#include <linux/seq_file.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_net.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lustre_mds.h>
+#include <linux/obd_class.h>
+#include <linux/obd_lov.h>
+#include <linux/obd_ost.h>
+#include <linux/lprocfs_status.h>
+
+#include "lov_internal.h"
+
+#if 0
+static int lov_logop_cleanup(struct llog_ctxt *ctxt)
+{
+        struct lov_obd *lov = &ctxt->loc_obd->u.lov;
+        int i, rc = 0;
+
+        ENTRY;
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                struct obd_device *child = lov->tgts[i].ltd_exp->exp_obd;
+                struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
+                rc = llog_cleanup(cctxt);
+                if (rc) {
+                        CERROR("error lov_llog_open %d\n", i);
+                        break;
+                }
+        }
+        RETURN(rc);
+}
+#endif
+
+/* Add log records for each OSC that this object is striped over, and return
+ * cookies for each one.  We _would_ have nice abstraction here, except that
+ * we need to keep cookies in stripe order, even if some are NULL, so that
+ * the right cookies are passed back to the right OSTs at the client side.
+ * Unset cookies should be all-zero (which will never occur naturally). */
+static int lov_llog_origin_add(struct llog_ctxt *ctxt,
+                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                        struct llog_cookie *logcookies, int numcookies)
+{
+        struct obd_device *obd = ctxt->loc_obd;
+        struct lov_obd *lov = &obd->u.lov;
+        struct lov_oinfo *loi;
+        struct llog_unlink_rec *lur;
+        int i, rc = 0;
+        ENTRY;
+
+        OBD_ALLOC(lur, sizeof(*lur));
+        if (!lur)
+                RETURN(-ENOMEM);
+        lur->lur_hdr.lrh_len = lur->lur_tail.lrt_len = sizeof(*lur);
+        lur->lur_hdr.lrh_type = MDS_UNLINK_REC;
+
+        LASSERT(logcookies && numcookies >= lsm->lsm_stripe_count);
+
+        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
+                struct obd_device *child = lov->tgts[loi->loi_ost_idx].ltd_exp->exp_obd; 
+                struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
+
+                lur->lur_oid = loi->loi_id;
+                lur->lur_ogen = loi->loi_gr;
+                rc += llog_add(cctxt, &lur->lur_hdr, NULL, logcookies + rc, numcookies - rc);
+
+        }
+        OBD_FREE(lur, sizeof(*lur));
+
+        RETURN(rc);
+}
+
+static int lov_llog_origin_connect(struct llog_ctxt *ctxt, int count,
+                                   struct llog_logid *logid,
+                                   struct llog_ctxt_gen *gen)
+{
+        struct obd_device *obd = ctxt->loc_obd;
+        struct lov_obd *lov = &obd->u.lov;
+        int i, rc = 0;
+        ENTRY;
+
+        LASSERT(lov->desc.ld_tgt_count  == count);
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                struct obd_device *child = lov->tgts[i].ltd_exp->exp_obd;
+                struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
+                rc = llog_connect(cctxt, 1, logid, gen);
+                if (rc) {
+                        CERROR("error osc_llog_connect %d\n", i);
+                        break;
+                }
+        }
+
+        RETURN(rc);
+}
+
+/* the replicators commit callback */
+static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
+                          int count, struct llog_cookie *cookies, int flags)
+{
+        struct lov_obd *lov;
+        struct obd_device *obd = ctxt->loc_obd;
+        struct lov_oinfo *loi;
+        int rc = 0, i;
+        ENTRY;
+
+        LASSERT(lsm != NULL);
+        LASSERT(count == lsm->lsm_stripe_count);
+
+        loi = lsm->lsm_oinfo;
+        lov = &obd->u.lov;
+        for (i = 0; i < count; i++, cookies++, loi++) {
+                struct obd_device *child = lov->tgts[loi->loi_ost_idx].ltd_exp->exp_obd; 
+                struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
+                int err;
+
+                err = llog_cancel(cctxt, NULL, 1, cookies, flags);
+                if (err && lov->tgts[loi->loi_ost_idx].active) {
+                        CERROR("error: objid "LPX64" subobj "LPX64
+                               " on OST idx %d: rc = %d\n", lsm->lsm_object_id,
+                               loi->loi_id, loi->loi_ost_idx, err);
+                        if (!rc)
+                                rc = err;
+                }
+        }
+        RETURN(rc);
+}
+
+static struct llog_operations lov_unlink_orig_logops = {
+        lop_add: lov_llog_origin_add,
+        lop_connect: lov_llog_origin_connect
+};
+
+static struct llog_operations lov_size_repl_logops = {
+        lop_cancel: lov_llog_repl_cancel
+};
+
+
+int lov_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                  int count, struct llog_logid *logid)
+{
+        struct lov_obd *lov = &obd->u.lov;
+        int i, rc = 0;
+        ENTRY;
+        
+        rc = llog_setup(obd, LLOG_UNLINK_ORIG_CTXT, tgt, 0, NULL,
+                        &lov_unlink_orig_logops);
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_setup(obd, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, 
+                        &lov_size_repl_logops);
+        if (rc)
+                RETURN(rc);
+
+        LASSERT(lov->desc.ld_tgt_count  == count);
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                struct obd_device *child = lov->tgts[i].ltd_exp->exp_obd;
+                rc = obd_llog_init(child, tgt, 1, logid + i);
+                if (rc) {
+                        CERROR("error osc_llog_init %d\n", i);
+                        break;
+                }
+        }
+        RETURN(rc);
+}
+
+int lov_llog_finish(struct obd_device *obd, int count)
+{
+        struct lov_obd *lov = &obd->u.lov;
+        int i, rc = 0;
+        ENTRY;
+        
+        rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        LASSERT(lov->desc.ld_tgt_count  == count);
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                struct obd_device *child = lov->tgts[i].ltd_exp->exp_obd;
+                rc = obd_llog_finish(child, 1);
+                if (rc) {
+                        CERROR("error osc_llog_finish %d\n", i);
+                        break;
+                }
+        }
+        RETURN(rc);
+}
diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c
index 55ef691e9e515b6a32e0e6a558c841c7584a2499..c32739c2e5971c848be155f53582025731efbe7e 100644
--- a/lustre/lov/lov_obd.c
+++ b/lustre/lov/lov_obd.c
@@ -1,4 +1,4 @@
- /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
@@ -22,15 +22,17 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_LOV
 #ifdef __KERNEL__
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/seq_file.h>
 #include <asm/div64.h>
 #else
 #include <liblustre.h>
@@ -40,11 +42,11 @@
 #include <linux/lustre_lib.h>
 #include <linux/lustre_net.h>
 #include <linux/lustre_idl.h>
-#include <linux/lustre_lite.h> /* for LL_IOC_LOV_[GS]ETSTRIPE */
+#include <linux/lustre_dlm.h>
 #include <linux/lustre_mds.h>
 #include <linux/obd_class.h>
 #include <linux/obd_lov.h>
-#include <linux/seq_file.h>
+#include <linux/obd_ost.h>
 #include <linux/lprocfs_status.h>
 
 #include "lov_internal.h"
@@ -52,144 +54,28 @@
 static int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off,
                              int stripeno, obd_off *obd_off);
 
-struct lov_file_handles {
-        struct portals_handle lfh_handle;
-        atomic_t lfh_refcount;
-        struct list_head lfh_list;
-        int lfh_count;
-        struct obd_client_handle *lfh_och;
-};
-
-struct lov_lock_handles {
-        struct portals_handle llh_handle;
-        atomic_t llh_refcount;
-        int llh_stripe_count;
-        struct lustre_handle llh_handles[0];
-};
-
-/* lov_file_handles helpers */
-static void lov_lfh_addref(void *lfhp)
-{
-        struct lov_file_handles *lfh = lfhp;
-
-        atomic_inc(&lfh->lfh_refcount);
-        CDEBUG(D_MALLOC, "GETting lfh %p : new refcount %d\n", lfh,
-               atomic_read(&lfh->lfh_refcount));
-}
-
-static struct lov_file_handles *lov_lfh_new(void)
-{
-        struct lov_file_handles *lfh;
-
-        OBD_ALLOC(lfh, sizeof *lfh);
-        if (lfh == NULL) {
-                CERROR("out of memory\n");
-                return NULL;
-        }
-
-        atomic_set(&lfh->lfh_refcount, 2);
-
-        INIT_LIST_HEAD(&lfh->lfh_handle.h_link);
-        class_handle_hash(&lfh->lfh_handle, lov_lfh_addref);
-
-        return lfh;
-}
-
-static struct lov_file_handles *lov_handle2lfh(struct lustre_handle *handle)
-{
-        ENTRY;
-        LASSERT(handle != NULL);
-        RETURN(class_handle2object(handle->cookie));
-}
-
-static void lov_lfh_put(struct lov_file_handles *lfh)
-{
-        CDEBUG(D_MALLOC, "PUTting lfh %p : new refcount %d\n", lfh,
-               atomic_read(&lfh->lfh_refcount) - 1);
-        LASSERT(atomic_read(&lfh->lfh_refcount) > 0 &&
-                atomic_read(&lfh->lfh_refcount) < 0x5a5a);
-        if (atomic_dec_and_test(&lfh->lfh_refcount)) {
-                LASSERT(list_empty(&lfh->lfh_handle.h_link));
-                OBD_FREE(lfh, sizeof *lfh);
-        }
-}
-
-static void lov_lfh_destroy(struct lov_file_handles *lfh)
-{
-        class_handle_unhash(&lfh->lfh_handle);
-        lov_lfh_put(lfh);
-}
-
-static void lov_llh_addref(void *llhp)
-{
-        struct lov_lock_handles *llh = llhp;
-
-        atomic_inc(&llh->llh_refcount);
-        CDEBUG(D_INFO, "GETting llh %p : new refcount %d\n", llh,
-               atomic_read(&llh->llh_refcount));
-}
-
-static struct lov_lock_handles *lov_llh_new(struct lov_stripe_md *lsm)
-{
-        struct lov_lock_handles *llh;
-
-        OBD_ALLOC(llh, sizeof *llh +
-                  sizeof(*llh->llh_handles) * lsm->lsm_stripe_count);
-        if (llh == NULL) {
-                CERROR("out of memory\n");
-                return NULL;
-        }
-        atomic_set(&llh->llh_refcount, 2);
-        llh->llh_stripe_count = lsm->lsm_stripe_count;
-        INIT_LIST_HEAD(&llh->llh_handle.h_link);
-        class_handle_hash(&llh->llh_handle, lov_llh_addref);
-        return llh;
-}
-
-static struct lov_lock_handles *lov_handle2llh(struct lustre_handle *handle)
-{
-        ENTRY;
-        LASSERT(handle != NULL);
-        RETURN(class_handle2object(handle->cookie));
-}
-
-static void lov_llh_put(struct lov_lock_handles *llh)
-{
-        CDEBUG(D_INFO, "PUTting llh %p : new refcount %d\n", llh,
-               atomic_read(&llh->llh_refcount) - 1);
-        LASSERT(atomic_read(&llh->llh_refcount) > 0 &&
-                atomic_read(&llh->llh_refcount) < 0x5a5a);
-        if (atomic_dec_and_test(&llh->llh_refcount)) {
-                LASSERT(list_empty(&llh->llh_handle.h_link));
-                OBD_FREE(llh, sizeof *llh +
-                         sizeof(*llh->llh_handles) * llh->llh_stripe_count);
-        }
-}
-
-static void lov_llh_destroy(struct lov_lock_handles *llh)
-{
-        class_handle_unhash(&llh->llh_handle);
-        lov_llh_put(llh);
-}
-
 /* obd methods */
 int lov_attach(struct obd_device *dev, obd_count len, void *data)
 {
         struct lprocfs_static_vars lvars;
-        struct proc_dir_entry *entry;
         int rc;
 
         lprocfs_init_vars(lov, &lvars);
         rc = lprocfs_obd_attach(dev, lvars.obd_vars);
-        if (rc)
-                return rc;
-
-        entry = create_proc_entry("target_obd", 0444, dev->obd_proc_entry);
-        if (entry == NULL)
-                RETURN(-ENOMEM);
-        entry->proc_fops = &lov_proc_target_fops;
-        entry->data = dev;
+        if (rc == 0) {
+#ifdef __KERNEL__
+                struct proc_dir_entry *entry;
 
+                entry = create_proc_entry("target_obd", 0444, 
+                                          dev->obd_proc_entry);
+                if (entry == NULL) {
+                        rc = -ENOMEM;
+                } else {
+                        entry->proc_fops = &lov_proc_target_fops;
+                        entry->data = dev;
+                }
+#endif
+        }
         return rc;
 }
 
@@ -203,14 +89,9 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
 {
         struct ptlrpc_request *req = NULL;
         struct lov_obd *lov = &obd->u.lov;
-        struct client_obd *mdc = &lov->mdcobd->u.cli;
         struct lov_desc *desc = &lov->desc;
-        struct lov_desc *mdesc;
         struct lov_tgt_desc *tgts;
         struct obd_export *exp;
-        struct lustre_handle mdc_conn;
-        struct obd_uuid lov_mds_uuid = {"LOV_MDS_UUID"};
-        struct obd_uuid *uuids;
         int rc, rc2, i;
         ENTRY;
 
@@ -219,8 +100,6 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
                 RETURN(rc);
 
         exp = class_conn2export(conn);
-        spin_lock_init(&exp->exp_lov_data.led_lock);
-        INIT_LIST_HEAD(&exp->exp_lov_data.led_open_head);
 
         /* We don't want to actually do the underlying connections more than
          * once, so keep track. */
@@ -230,106 +109,52 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
                 RETURN(0);
         }
 
-        /* retrieve LOV metadata from MDS */
-        rc = obd_connect(&mdc_conn, lov->mdcobd, &lov_mds_uuid);
-        if (rc) {
-                CERROR("cannot connect to mdc: rc = %d\n", rc);
-                GOTO(out_conn, rc);
-        }
-
-        rc = mdc_getlovinfo(obd, &mdc_conn, &req);
-        rc2 = obd_disconnect(&mdc_conn, 0);
-        if (rc) {
-                CERROR("cannot get lov info %d\n", rc);
-                GOTO(out_conn, rc);
-        }
-
-        if (rc2) {
-                CERROR("error disconnecting from MDS %d\n", rc2);
-                GOTO(out_req, rc = rc2);
-        }
-
-        /* mdc_getlovinfo() has checked and swabbed the reply.  It has also
-         * done some simple checks (e.g. #uuids consistent with desc, uuid
-         * array fits in LOV_MAX_UUID_BUFFER_SIZE and all uuids are
-         * terminated), but I still need to verify it makes overall
-         * sense */
-        mdesc = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*mdesc));
-        LASSERT(mdesc != NULL);
-        LASSERT_REPSWABBED(req, 0);
-
-        *desc = *mdesc;
-
-        /* XXX We need a separate LOV 'service' UUID from the client device
-         *     UUID so that we can mount more than once on a client */
-        if (!obd_uuid_equals(&obd->obd_uuid, &desc->ld_uuid)) {
-                CERROR("LOV desc: uuid %s not on mds device (%s)\n",
-                       obd->obd_uuid.uuid, desc->ld_uuid.uuid);
-                GOTO(out_req, rc = -EINVAL);
-        }
-
-        /* Because of 64-bit divide/mod operations only work with a 32-bit
-         * divisor in a 32-bit kernel, we cannot support a stripe width
-         * of 4GB or larger on 32-bit CPUs.
-         */
-        if ((desc->ld_default_stripe_count ?
-             desc->ld_default_stripe_count : desc->ld_tgt_count) *
-             desc->ld_default_stripe_size > ~0UL) {
-                CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n",
-                       desc->ld_default_stripe_size,
-                       desc->ld_default_stripe_count ?
-                       desc->ld_default_stripe_count : desc->ld_tgt_count,~0UL);
-                GOTO(out_req, rc = -EINVAL);
-        }
-
-        /* We know ld_tgt_count is reasonable (the array of UUIDS fits in
-         * the maximum buffer size, so we won't be making outrageous
-         * demands on memory here. */
-        lov->bufsize = sizeof(struct lov_tgt_desc) * desc->ld_tgt_count;
-        OBD_ALLOC(lov->tgts, lov->bufsize);
-        if (lov->tgts == NULL) {
-                CERROR("Out of memory\n");
-                GOTO(out_req, rc = -ENOMEM);
-        }
-
-        uuids = lustre_msg_buf(req->rq_repmsg, 1,
-                               sizeof(*uuids) * desc->ld_tgt_count);
-        LASSERT(uuids != NULL);
-        LASSERT_REPSWABBED(req, 1);
-
         for (i = 0, tgts = lov->tgts; i < desc->ld_tgt_count; i++, tgts++) {
-                struct obd_uuid *uuid = &tgts->uuid;
+                struct obd_uuid *tgt_uuid = &tgts->uuid;
                 struct obd_device *tgt_obd;
                 struct obd_uuid lov_osc_uuid = { "LOV_OSC_UUID" };
+                struct lustre_handle conn = {0, };
 
-                /* NULL termination already checked */
-                *uuid = uuids[i];
+                LASSERT( tgt_uuid != NULL);
 
-                tgt_obd = client_tgtuuid2obd(uuid);
+                tgt_obd = class_find_client_obd(tgt_uuid, LUSTRE_OSC_NAME, 
+                                                &obd->obd_uuid);
 
                 if (!tgt_obd) {
-                        CERROR("Target %s not attached\n", uuid->uuid);
+                        CERROR("Target %s not attached\n", tgt_uuid->uuid);
                         GOTO(out_disc, rc = -EINVAL);
                 }
 
                 if (!tgt_obd->obd_set_up) {
-                        CERROR("Target %s not set up\n", uuid->uuid);
+                        CERROR("Target %s not set up\n", tgt_uuid->uuid);
                         GOTO(out_disc, rc = -EINVAL);
                 }
 
-                rc = obd_connect(&tgts->conn, tgt_obd, &lov_osc_uuid);
+                if (tgt_obd->u.cli.cl_import->imp_invalid) {
+                        CERROR("not connecting OSC %s; administratively "
+                               "disabled\n", tgt_uuid->uuid);
+                        rc = obd_register_observer(tgt_obd, obd);
+                        if (rc) {
+                                CERROR("Target %s register_observer error %d; "
+                                       "will not be able to reactivate\n",
+                                       tgt_uuid->uuid, rc);
+                        }
+                        continue;
+                }
 
+                rc = obd_connect(&conn, tgt_obd, &lov_osc_uuid);
                 if (rc) {
-                        CERROR("Target %s connect error %d\n", uuid->uuid, rc);
+                        CERROR("Target %s connect error %d\n", tgt_uuid->uuid,
+                               rc);
                         GOTO(out_disc, rc);
                 }
+                tgts->ltd_exp = class_conn2export(&conn);
 
-                rc = obd_iocontrol(IOC_OSC_REGISTER_LOV, &tgts->conn,
-                                   sizeof(struct obd_device *), obd, NULL);
+                rc = obd_register_observer(tgt_obd, obd);
                 if (rc) {
-                        CERROR("Target %s REGISTER_LOV error %d\n",
-                               uuid->uuid, rc);
-                        obd_disconnect(&tgts->conn, 0);
+                        CERROR("Target %s register_observer error %d\n",
+                               tgt_uuid->uuid, rc);
+                        obd_disconnect(tgts->ltd_exp, 0);
                         GOTO(out_disc, rc);
                 }
 
@@ -337,9 +162,6 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
                 tgts->active = 1;
         }
 
-        mdc->cl_max_mds_easize = obd_size_diskmd(conn, NULL);
-        mdc->cl_max_mds_cookiesize = desc->ld_tgt_count *
-                sizeof(struct llog_cookie);
         ptlrpc_req_finished(req);
         class_export_put(exp);
         RETURN (0);
@@ -352,26 +174,19 @@ static int lov_connect(struct lustre_handle *conn, struct obd_device *obd,
                 tgts->active = 0;
                 /* save for CERROR below; (we know it's terminated) */
                 uuid = tgts->uuid;
-                rc2 = obd_disconnect(&tgts->conn, 0);
+                rc2 = obd_disconnect(tgts->ltd_exp, 0);
                 if (rc2)
                         CERROR("error: LOV target %s disconnect on OST idx %d: "
                                "rc = %d\n", uuid.uuid, i, rc2);
         }
-        OBD_FREE(lov->tgts, lov->bufsize);
- out_req:
-        ptlrpc_req_finished (req);
- out_conn:
-        class_export_put(exp);
-        class_disconnect(conn, 0);
+        class_disconnect(exp, 0);
         RETURN (rc);
 }
 
-static int lov_disconnect(struct lustre_handle *conn, int flags)
+static int lov_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct lov_obd *lov = &obd->u.lov;
-        struct obd_export *exp;
-        struct list_head *p, *n;
         int rc, i;
         ENTRY;
 
@@ -384,16 +199,23 @@ static int lov_disconnect(struct lustre_handle *conn, int flags)
                 goto out_local;
 
         for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                if (lov->tgts[i].ltd_exp == NULL)
+                        continue;
+
                 if (obd->obd_no_recov) {
                         /* Pass it on to our clients.
                          * XXX This should be an argument to disconnect,
                          * XXX not a back-door flag on the OBD.  Ah well.
                          */
-                        struct obd_device *osc_obd =
-                                class_conn2obd(&lov->tgts[i].conn);
-                        osc_obd->obd_no_recov = 1;
+                        struct obd_device *osc_obd;
+                        osc_obd = class_exp2obd(lov->tgts[i].ltd_exp);
+                        if (osc_obd)
+                                osc_obd->obd_no_recov = 1;
                 }
-                rc = obd_disconnect(&lov->tgts[i].conn, flags);
+
+                obd_register_observer(lov->tgts[i].ltd_exp->exp_obd, NULL);
+
+                rc = obd_disconnect(lov->tgts[i].ltd_exp, flags);
                 if (rc) {
                         if (lov->tgts[i].active) {
                                 CERROR("Target %s disconnect error %d\n",
@@ -405,34 +227,11 @@ static int lov_disconnect(struct lustre_handle *conn, int flags)
                         lov->desc.ld_active_tgt_count--;
                         lov->tgts[i].active = 0;
                 }
+                lov->tgts[i].ltd_exp = NULL;
         }
-        OBD_FREE(lov->tgts, lov->bufsize);
-        lov->bufsize = 0;
-        lov->tgts = NULL;
 
  out_local:
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CERROR("export handle "LPU64" invalid!  If you can reproduce, "
-                       "please send a full debug log to phik\n", conn->cookie);
-                RETURN(0);
-        }
-        spin_lock(&exp->exp_lov_data.led_lock);
-        list_for_each_safe(p, n, &exp->exp_lov_data.led_open_head) {
-                /* XXX close these, instead of just discarding them? */
-                struct lov_file_handles *lfh;
-                lfh = list_entry(p, typeof(*lfh), lfh_list);
-                CERROR("discarding open LOV handle %p:"LPX64"\n",
-                       lfh, lfh->lfh_handle.h_cookie);
-                list_del(&lfh->lfh_list);
-                OBD_FREE(lfh->lfh_och, lfh->lfh_count * FD_OSTDATA_SIZE);
-                lov_lfh_destroy(lfh);
-                lov_lfh_put(lfh);
-        }
-        spin_unlock(&exp->exp_lov_data.led_lock);
-        class_export_put(exp);
-
-        rc = class_disconnect(conn, 0);
+        rc = class_disconnect(exp, 0);
         RETURN(rc);
 }
 
@@ -456,7 +255,7 @@ static int lov_set_osc_active(struct lov_obd *lov, struct obd_uuid *uuid,
         spin_lock(&lov->lov_lock);
         for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) {
                 CDEBUG(D_INFO, "lov idx %d is %s conn "LPX64"\n",
-                       i, tgt->uuid.uuid, tgt->conn.cookie);
+                       i, tgt->uuid.uuid, tgt->ltd_exp->exp_handle.h_cookie);
                 if (strncmp(uuid->uuid, tgt->uuid.uuid, sizeof uuid->uuid) == 0)
                         break;
         }
@@ -464,7 +263,7 @@ static int lov_set_osc_active(struct lov_obd *lov, struct obd_uuid *uuid,
         if (i == lov->desc.ld_tgt_count)
                 GOTO(out, rc = -EINVAL);
 
-        obd = class_conn2obd(&tgt->conn);
+        obd = class_exp2obd(tgt->ltd_exp);
         if (obd == NULL) {
                 /* This can happen if OST failure races with node shutdown */
                 GOTO(out, rc = -ENOTCONN);
@@ -484,54 +283,133 @@ static int lov_set_osc_active(struct lov_obd *lov, struct obd_uuid *uuid,
         CDEBUG(D_INFO, "Marking OBD %p %sactive\n", obd, activate ? "" : "in");
 
         tgt->active = activate;
-        if (activate) {
-                /*
-                 * foreach(export)
-                 *     foreach(open_file)
-                 *         if (file_handle uses this_osc)
-                 *             if (has_no_filehandle)
-                 *                 open(file_handle, this_osc);
-                 */
-                /* XXX reconnect? */
+        if (activate)
                 lov->desc.ld_active_tgt_count++;
-        } else {
-                /*
-                 * Should I invalidate filehandles that refer to this OSC, so
-                 * that I reopen them during reactivation?
-                 */
-                /* XXX disconnect from OSC? */
+        else
                 lov->desc.ld_active_tgt_count--;
-        }
 
-#warning "FIXME: walk open files list for objects that need opening"
         EXIT;
  out:
         spin_unlock(&lov->lov_lock);
         return rc;
 }
 
+static int lov_notify(struct obd_device *obd, struct obd_device *watched,
+                       int active)
+{
+        int rc;
+        struct obd_uuid *uuid;
+
+        if (strcmp(watched->obd_type->typ_name, "osc")) {
+                CERROR("unexpected notification of %s %s!\n",
+                       watched->obd_type->typ_name,
+                       watched->obd_name);
+                return -EINVAL;
+        }
+        uuid = &watched->u.cli.cl_import->imp_target_uuid;
+
+        /*
+         * Must notify (MDS) before we mark the OSC as active, so that
+         * the orphan deletion happens without interference from racing
+         * creates.
+         */
+        if (obd->obd_observer) {
+                /* Pass the notification up the chain. */
+                rc = obd_notify(obd->obd_observer, watched, active);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        rc = lov_set_osc_active(&obd->u.lov, uuid, active);
+
+        if (rc) {
+                CERROR("%sactivation of %s failed: %d\n",
+                       active ? "" : "de", uuid->uuid, rc);
+        }
+        RETURN(rc);
+}
+
 static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
 {
-        struct obd_ioctl_data *data = buf;
+        struct lustre_cfg *lcfg = buf;
+        struct lov_desc *desc;
         struct lov_obd *lov = &obd->u.lov;
+        struct obd_uuid *uuids;
+        struct lov_tgt_desc *tgts;
+        int i;
+        int count;
         int rc = 0;
         ENTRY;
 
-        if (data->ioc_inllen1 < 1) {
-                CERROR("LOV setup requires an MDC name\n");
+        if (lcfg->lcfg_inllen1 < 1) {
+                CERROR("LOV setup requires a descriptor\n");
+                RETURN(-EINVAL);
+        }
+
+        if (lcfg->lcfg_inllen2 < 1) {
+                CERROR("LOV setup requires an OST UUID list\n");
+                RETURN(-EINVAL);
+        }
+
+        desc = (struct lov_desc *)lcfg->lcfg_inlbuf1;
+        if (sizeof(*desc) > lcfg->lcfg_inllen1) {
+                CERROR("descriptor size wrong: %d > %d\n",
+                       (int)sizeof(*desc), lcfg->lcfg_inllen1);
+                RETURN(-EINVAL);
+        }
+
+        count = desc->ld_tgt_count;
+        uuids = (struct obd_uuid *)lcfg->lcfg_inlbuf2;
+        if (sizeof(*uuids) * count != lcfg->lcfg_inllen2) {
+                CERROR("UUID array size wrong: %u * %u != %u\n",
+                       sizeof(*uuids), count, lcfg->lcfg_inllen2);
+                RETURN(-EINVAL);
+        }
+
+        /* Because of 64-bit divide/mod operations only work with a 32-bit
+         * divisor in a 32-bit kernel, we cannot support a stripe width
+         * of 4GB or larger on 32-bit CPUs.
+         */
+        if ((desc->ld_default_stripe_count ?
+             desc->ld_default_stripe_count : desc->ld_tgt_count) *
+             desc->ld_default_stripe_size > ~0UL) {
+                CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n",
+                       desc->ld_default_stripe_size,
+                       desc->ld_default_stripe_count ?
+                       desc->ld_default_stripe_count : desc->ld_tgt_count,~0UL);
+                RETURN(-EINVAL);
+        }
+
+        lov->bufsize = sizeof(struct lov_tgt_desc) * count;
+        OBD_ALLOC(lov->tgts, lov->bufsize);
+        if (lov->tgts == NULL) {
+                CERROR("Out of memory\n");
                 RETURN(-EINVAL);
         }
 
+        lov->desc = *desc;
         spin_lock_init(&lov->lov_lock);
-        lov->mdcobd = class_name2obd(data->ioc_inlbuf1);
-        if (!lov->mdcobd) {
-                CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid.uuid,
-                       data->ioc_inlbuf1);
-                rc = -EINVAL;
+
+        for (i = 0, tgts = lov->tgts; i < desc->ld_tgt_count; i++, tgts++) {
+                struct obd_uuid *uuid = &tgts->uuid;
+
+                /* NULL termination already checked */
+                *uuid = uuids[i];
         }
+
+
         RETURN(rc);
 }
 
+static int lov_cleanup(struct obd_device *obd, int flags) 
+{
+        struct lov_obd *lov = &obd->u.lov;
+
+        OBD_FREE(lov->tgts, lov->bufsize);
+        RETURN(0);
+}
+
+
 /* compute object size given "stripeno" and the ost size */
 static obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size,
                                 int stripeno)
@@ -590,11 +468,71 @@ static void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_flag valid,
 #define log2(n) ffz(~(n))
 #endif
 
+static int lov_clear_orphans(struct obd_export *export, struct obdo *src_oa,
+                             struct lov_stripe_md **ea,
+                             struct obd_trans_info *oti)
+{
+        struct lov_obd *lov;
+        struct obdo *tmp_oa;
+        struct obd_uuid *ost_uuid = NULL;
+        int rc = 0, i;
+        ENTRY;
+
+        LASSERT(src_oa->o_valid & OBD_MD_FLFLAGS &&
+                src_oa->o_flags == OBD_FL_DELORPHAN);
+
+        lov = &export->exp_obd->u.lov;
+
+        tmp_oa = obdo_alloc();
+        if (tmp_oa == NULL)
+                RETURN(-ENOMEM);
+
+        if (src_oa->o_valid & OBD_MD_FLINLINE) {
+                ost_uuid = (struct obd_uuid *)src_oa->o_inline;
+                CDEBUG(D_HA, "clearing orphans only for %s\n",
+                       ost_uuid->uuid);
+        }
+
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                struct lov_stripe_md obj_md;
+                struct lov_stripe_md *obj_mdp = &obj_md;
+                int err;
+
+                /* if called for a specific target, we don't 
+                   care if it is not active. */
+                if (lov->tgts[i].active == 0 && ost_uuid == NULL) {
+                        CDEBUG(D_HA, "lov idx %d inactive\n", i);
+                        continue;
+                }
+
+                if (ost_uuid && !obd_uuid_equals(ost_uuid, &lov->tgts[i].uuid))
+                        continue;
+                
+                memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
+
+                /* XXX: LOV STACKING: use real "obj_mdp" sub-data */
+                err = obd_create(lov->tgts[i].ltd_exp, tmp_oa, &obj_mdp, oti);
+                if (err) {
+                        CERROR("error in orphan recovery on OST idx %d/%d: "
+                               "rc = %d\n", i, lov->desc.ld_tgt_count, err);
+                        if (!rc)
+                                rc = err;
+                }
+
+                if (ost_uuid)
+                        break;
+        }
+        obdo_free(tmp_oa);
+        RETURN(rc);
+}
+
+#define LOV_CREATE_RESEED_INTERVAL 1000
+
 /* the LOV expects oa->o_id to be set to the LOV object id */
-static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
+static int lov_create(struct obd_export *exp, struct obdo *src_oa,
                       struct lov_stripe_md **ea, struct obd_trans_info *oti)
 {
-        struct obd_export *export = class_conn2export(conn);
+        static int ost_start_idx, ost_start_count;
         struct lov_obd *lov;
         struct lov_stripe_md *lsm;
         struct lov_oinfo *loi = NULL;
@@ -604,45 +542,51 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
         int set = 0, obj_alloc = 0, cookie_sent = 0, rc = 0, i;
         ENTRY;
 
-        LASSERT(ea);
+        LASSERT(ea != NULL);
+
+        if ((src_oa->o_valid & OBD_MD_FLFLAGS) && 
+            src_oa->o_flags == OBD_FL_DELORPHAN) {
+                rc = lov_clear_orphans(exp, src_oa, ea, oti);
+                RETURN(rc);
+        }
 
-        if (!export)
+        if (exp == NULL)
                 RETURN(-EINVAL);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
 
         if (!lov->desc.ld_active_tgt_count)
-                GOTO(out_exp, rc = -EIO);
+                RETURN(-EIO);
 
         ret_oa = obdo_alloc();
         if (!ret_oa)
-                GOTO(out_exp, rc = -ENOMEM);
+                RETURN(-ENOMEM);
 
         tmp_oa = obdo_alloc();
         if (!tmp_oa)
                 GOTO(out_oa, rc = -ENOMEM);
 
         lsm = *ea;
-
-        if (!lsm) {
+        if (lsm == NULL) {
                 int stripes;
                 ost_count = lov_get_stripecnt(lov, 0);
 
                 /* If the MDS file was truncated up to some size, stripe over
-                 * enough OSTs to allow the file to be created at that size.
-                 */
+                 * enough OSTs to allow the file to be created at that size. */
                 if (src_oa->o_valid & OBD_MD_FLSIZE) {
                         stripes=((src_oa->o_size+LUSTRE_STRIPE_MAXBYTES)>>12)-1;
                         do_div(stripes, (__u32)(LUSTRE_STRIPE_MAXBYTES >> 12));
 
                         if (stripes > lov->desc.ld_active_tgt_count)
-                                GOTO(out_exp, rc = -EFBIG);
-                        if (stripes < ost_count)
+                                RETURN(-EFBIG);
+                        if (stripes > ost_count)
                                 stripes = ost_count;
-                } else
+                } else {
                         stripes = ost_count;
+                }
 
-                rc = lov_alloc_memmd(&lsm, stripes);
+                rc = lov_alloc_memmd(&lsm, stripes, lov->desc.ld_pattern ?
+                                     lov->desc.ld_pattern : LOV_PATTERN_RAID0);
                 if (rc < 0)
                         GOTO(out_tmp, rc);
 
@@ -655,12 +599,22 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
         lsm->lsm_object_id = src_oa->o_id;
         if (!lsm->lsm_stripe_size)
                 lsm->lsm_stripe_size = lov->desc.ld_default_stripe_size;
+        if (!lsm->lsm_pattern) {
+                lsm->lsm_pattern = lov->desc.ld_pattern ?
+                        lov->desc.ld_pattern : LOV_PATTERN_RAID0;
+        }
 
-        if (!*ea || lsm->lsm_stripe_offset >= ost_count) {
-                get_random_bytes(&ost_idx, 2);
-                ost_idx %= ost_count;
+        if (*ea == NULL || lsm->lsm_oinfo[0].loi_ost_idx >= ost_count) {
+                if (ost_start_count <= 0) {
+                        ost_start_idx = ll_insecure_random_int();
+                        ost_start_count = LOV_CREATE_RESEED_INTERVAL;
+                } else {
+                        --ost_start_count;
+                        ost_start_idx += lsm->lsm_stripe_count;
+                }
+                ost_idx = ost_start_idx % ost_count;
         } else {
-                ost_idx = lsm->lsm_stripe_offset;
+                ost_idx = lsm->lsm_oinfo[0].loi_ost_idx;
         }
 
         CDEBUG(D_INODE, "allocating %d subobjs for objid "LPX64" at idx %d\n",
@@ -702,8 +656,10 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
                                i, tmp_oa->o_size, src_oa->o_size);
                 }
 
+
                 /* XXX: LOV STACKING: use real "obj_mdp" sub-data */
-                err = obd_create(&lov->tgts[ost_idx].conn, tmp_oa,&obj_mdp,oti);
+                err = obd_create(lov->tgts[ost_idx].ltd_exp, tmp_oa, &obj_mdp,
+                                 oti);
                 if (err) {
                         if (lov->tgts[ost_idx].active) {
                                 CERROR("error creating objid "LPX64" sub-object"
@@ -720,17 +676,16 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
                                 rc = err;
                         continue;
                 }
+                if (oti->oti_objid)
+                        oti->oti_objid[ost_idx] = tmp_oa->o_id;
                 loi->loi_id = tmp_oa->o_id;
                 loi->loi_ost_idx = ost_idx;
                 CDEBUG(D_INODE, "objid "LPX64" has subobj "LPX64" at idx %d\n",
                        lsm->lsm_object_id, loi->loi_id, ost_idx);
 
-                if (set == 0)
-                        lsm->lsm_stripe_offset = ost_idx;
                 lov_merge_attrs(ret_oa, tmp_oa, tmp_oa->o_valid, lsm,
                                 obj_alloc, &set);
-                loi->loi_dirty_ot = &loi->loi_dirty_ot_inline;
-                ot_init(loi->loi_dirty_ot);
+                loi_init(loi);
 
                 if (cookies)
                         ++oti->oti_logcookies;
@@ -821,39 +776,27 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
                         src_oa->o_valid |= OBD_MD_FLCOOKIE;
                 }
         }
- out_exp:
-        class_export_put(export);
-        return rc;
+        RETURN(rc);
 
  out_cleanup:
         while (obj_alloc-- > 0) {
+                struct obd_export *sub_exp;
                 int err;
 
                 --loi;
+                sub_exp = lov->tgts[loi->loi_ost_idx].ltd_exp;
                 /* destroy already created objects here */
                 memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
                 tmp_oa->o_id = loi->loi_id;
 
-                if (oti && cookie_sent) {
-                        err = obd_log_cancel(&lov->tgts[loi->loi_ost_idx].conn,
-                                             NULL, 1, --oti->oti_logcookies,
-                                             OBD_LLOG_FL_SENDNOW);
-                        if (err)
-                                CERROR("Failed to cancel objid "LPX64" subobj "
-                                       LPX64" cookie on OST idx %d: rc = %d\n",
-                                       src_oa->o_id, loi->loi_id,
-                                       loi->loi_ost_idx, err);
-                }
-
-                err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, tmp_oa,
-                                  NULL, oti);
+                err = obd_destroy(sub_exp, tmp_oa, NULL, oti);
                 if (err)
                         CERROR("Failed to uncreate objid "LPX64" subobj "LPX64
                                " on OST idx %d: rc = %d\n", src_oa->o_id,
                                loi->loi_id, loi->loi_ost_idx, err);
         }
         if (*ea == NULL)
-                obd_free_memmd(conn, &lsm);
+                obd_free_memmd(exp, &lsm);
         goto out_tmp;
 }
 
@@ -872,27 +815,22 @@ static int lov_create(struct lustre_handle *conn, struct obdo *src_oa,
         _ret__;                                                 \
 })
 
-static int lov_destroy(struct lustre_handle *conn, struct obdo *oa,
+static int lov_destroy(struct obd_export *exp, struct obdo *oa,
                        struct lov_stripe_md *lsm, struct obd_trans_info *oti)
 {
         struct obdo tmp;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
         int rc = 0, i;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+                RETURN(-EINVAL);
 
-        if (oa->o_valid & OBD_MD_FLHANDLE)
-                lfh = lov_handle2lfh(obdo_handle(oa));
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
         for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
                 int err;
                 if (lov->tgts[loi->loi_ost_idx].active == 0) {
@@ -903,12 +841,7 @@ static int lov_destroy(struct lustre_handle *conn, struct obdo *oa,
 
                 memcpy(&tmp, oa, sizeof(tmp));
                 tmp.o_id = loi->loi_id;
-                if (lfh)
-                        memcpy(obdo_handle(&tmp), &lfh->lfh_och[i].och_fh,
-                               sizeof(lfh->lfh_och[i].och_fh));
-                else
-                        tmp.o_valid &= ~OBD_MD_FLHANDLE;
-                err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp,
+                err = obd_destroy(lov->tgts[loi->loi_ost_idx].ltd_exp, &tmp,
                                   NULL, oti);
                 if (err && lov->tgts[loi->loi_ost_idx].active) {
                         CERROR("error: destroying objid "LPX64" subobj "
@@ -918,35 +851,25 @@ static int lov_destroy(struct lustre_handle *conn, struct obdo *oa,
                                 rc = err;
                 }
         }
-        if (lfh != NULL)
-                lov_lfh_put(lfh);
-        EXIT;
- out:
-        class_export_put(export);
-        return rc;
+        RETURN(rc);
 }
 
-static int lov_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int lov_getattr(struct obd_export *exp, struct obdo *oa,
                        struct lov_stripe_md *lsm)
 {
         struct obdo tmp;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
         int i, rc = 0, set = 0;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+                RETURN(-EINVAL);
 
-        lov = &export->exp_obd->u.lov;
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        if (oa->o_valid & OBD_MD_FLHANDLE)
-                lfh = lov_handle2lfh(obdo_handle(oa));
+        lov = &exp->exp_obd->u.lov;
 
         CDEBUG(D_INFO, "objid "LPX64": %ux%u byte stripes\n",
                lsm->lsm_object_id, lsm->lsm_stripe_count, lsm->lsm_stripe_size);
@@ -963,20 +886,16 @@ static int lov_getattr(struct lustre_handle *conn, struct obdo *oa,
                 /* create data objects with "parent" OA */
                 memcpy(&tmp, oa, sizeof(tmp));
                 tmp.o_id = loi->loi_id;
-                if (lfh)
-                        memcpy(obdo_handle(&tmp), &lfh->lfh_och[i].och_fh,
-                               sizeof(lfh->lfh_och[i].och_fh));
-                else
-                        tmp.o_valid &= ~OBD_MD_FLHANDLE;
 
-                err = obd_getattr(&lov->tgts[loi->loi_ost_idx].conn, &tmp,NULL);
+                err = obd_getattr(lov->tgts[loi->loi_ost_idx].ltd_exp, &tmp,
+                                  NULL);
                 if (err) {
                         if (lov->tgts[loi->loi_ost_idx].active) {
                                 CERROR("error: getattr objid "LPX64" subobj "
                                        LPX64" on OST idx %d: rc = %d\n",
                                        oa->o_id, loi->loi_id, loi->loi_ost_idx,
                                        err);
-                                GOTO(out, rc = err);
+                                RETURN(err);
                         }
                 } else {
                         lov_merge_attrs(oa, &tmp, tmp.o_valid, lsm, i, &set);
@@ -984,12 +903,7 @@ static int lov_getattr(struct lustre_handle *conn, struct obdo *oa,
         }
         if (!set)
                 rc = -EIO;
-        GOTO(out, rc);
- out:
-        if (lfh != NULL)
-                lov_lfh_put(lfh);
-        class_export_put(export);
-        return rc;
+        RETURN(rc);
 }
 
 static int lov_getattr_interpret(struct ptlrpc_request_set *rqset, void *data, 
@@ -1026,43 +940,28 @@ static int lov_getattr_interpret(struct ptlrpc_request_set *rqset, void *data,
         RETURN (rc);
 }
 
-static int lov_getattr_async (struct lustre_handle *conn, struct obdo *oa,
+static int lov_getattr_async(struct obd_export *exp, struct obdo *oa,
                               struct lov_stripe_md *lsm,
                               struct ptlrpc_request_set *rqset)
 {
         struct obdo *obdos;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
         struct lov_getattr_async_args *aa;
-        int i;
-        int set = 0;
-        int rc = 0;
+        int i, rc = 0, set = 0;
         ENTRY;
 
-        if (!lsm) {
-                CERROR("LOV requires striping ea\n");
-                GOTO(out, rc = -EINVAL);
-        }
-
-        if (lsm->lsm_magic != LOV_MAGIC) {
-                CERROR("LOV striping magic bad %#x != %#x\n",
-                       lsm->lsm_magic, LOV_MAGIC);
-                GOTO(out, rc = -EINVAL);
-        }
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
 
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
 
         OBD_ALLOC (obdos, lsm->lsm_stripe_count * sizeof (*obdos));
         if (obdos == NULL)
-                GOTO (out, rc = -ENOMEM);
-
-        if (oa->o_valid & OBD_MD_FLHANDLE)
-                lfh = lov_handle2lfh(obdo_handle(oa));
+                RETURN(-ENOMEM);
 
         CDEBUG(D_INFO, "objid "LPX64": %ux%u byte stripes\n",
                lsm->lsm_object_id, lsm->lsm_stripe_count, lsm->lsm_stripe_size);
@@ -1080,13 +979,8 @@ static int lov_getattr_async (struct lustre_handle *conn, struct obdo *oa,
                 /* create data objects with "parent" OA */
                 memcpy(&obdos[i], oa, sizeof(obdos[i]));
                 obdos[i].o_id = loi->loi_id;
-                if (lfh)
-                        memcpy(obdo_handle(&obdos[i]), &lfh->lfh_och[i].och_fh,
-                               sizeof(lfh->lfh_och[i].och_fh));
-                else
-                        obdos[i].o_valid &= ~OBD_MD_FLHANDLE;
 
-                err = obd_getattr_async (&lov->tgts[loi->loi_ost_idx].conn,
+                err = obd_getattr_async(lov->tgts[loi->loi_ost_idx].ltd_exp,
                                          &obdos[i], NULL, rqset);
                 if (err) {
                         CERROR("error: getattr objid "LPX64" subobj "
@@ -1107,47 +1001,45 @@ static int lov_getattr_async (struct lustre_handle *conn, struct obdo *oa,
         aa->aa_lsm = lsm;
         aa->aa_oa = oa;
         aa->aa_obdos = obdos;
-        GOTO (out, rc = 0);
+        aa->aa_lov = lov;
+        GOTO(out, rc = 0);
 
- out_obdos:
+out_obdos:
         OBD_FREE (obdos, lsm->lsm_stripe_count * sizeof (*obdos));
- out:
-        if (lfh != NULL)
-                lov_lfh_put(lfh);
-        class_export_put(export);
-        RETURN (rc);
+out:
+        RETURN(rc);
 }
 
-static int lov_setattr(struct lustre_handle *conn, struct obdo *src_oa,
+
+static int lov_setattr(struct obd_export *exp, struct obdo *src_oa,
                        struct lov_stripe_md *lsm, struct obd_trans_info *oti)
 {
         struct obdo *tmp_oa, *ret_oa;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
         int rc = 0, i, set = 0;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
+                RETURN(-EINVAL);
 
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
         /* for now, we only expect time updates here */
-        LASSERT(!(src_oa->o_valid & ~(OBD_MD_FLID|OBD_MD_FLTYPE|OBD_MD_FLMODE|
+        LASSERT(!(src_oa->o_valid & ~(OBD_MD_FLID|OBD_MD_FLTYPE | OBD_MD_FLMODE|
                                       OBD_MD_FLATIME | OBD_MD_FLMTIME |
-                                      OBD_MD_FLCTIME)));
+                                      OBD_MD_FLCTIME | OBD_MD_FLFLAGS |
+                                      OBD_MD_FLSIZE)));
         ret_oa = obdo_alloc();
         if (!ret_oa)
-                GOTO(out, rc = -ENOMEM);
+                RETURN(-ENOMEM);
 
         tmp_oa = obdo_alloc();
         if (!tmp_oa)
                 GOTO(out_oa, rc = -ENOMEM);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
         for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
                 int err;
 
@@ -1157,16 +1049,19 @@ static int lov_setattr(struct lustre_handle *conn, struct obdo *src_oa,
                 }
 
                 memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
+                tmp_oa->o_id = loi->loi_id;
 
-                if (lfh)
-                        memcpy(obdo_handle(tmp_oa), &lfh->lfh_och[i].och_fh,
-                               sizeof(lfh->lfh_och[i].och_fh));
-                else
-                        tmp_oa->o_valid &= ~OBD_MD_FLHANDLE;
+                if (src_oa->o_valid & OBD_MD_FLSIZE) {
+                        if (lov_stripe_offset(lsm, src_oa->o_size, i,
+                                              &tmp_oa->o_size) < 0 &&
+                            tmp_oa->o_size)
+                                tmp_oa->o_size--;
 
-                tmp_oa->o_id = loi->loi_id;
+                        CDEBUG(D_INODE, "stripe %d has size "LPU64"/"LPU64"\n",
+                               i, tmp_oa->o_size, src_oa->o_size);
+                }
 
-                err = obd_setattr(&lov->tgts[loi->loi_ost_idx].conn, tmp_oa,
+                err = obd_setattr(lov->tgts[loi->loi_ost_idx].ltd_exp, tmp_oa,
                                   NULL, NULL);
                 if (err) {
                         if (lov->tgts[loi->loi_ost_idx].active) {
@@ -1179,13 +1074,10 @@ static int lov_setattr(struct lustre_handle *conn, struct obdo *src_oa,
                         }
                         continue;
                 }
-
                 lov_merge_attrs(ret_oa, tmp_oa, tmp_oa->o_valid, lsm, i, &set);
         }
         if (!set && !rc)
                 rc = -EIO;
-        if (lfh != NULL)
-                lov_lfh_put(lfh);
 
         ret_oa->o_id = src_oa->o_id;
         memcpy(src_oa, ret_oa, sizeof(*src_oa));
@@ -1194,185 +1086,6 @@ out_tmp:
         obdo_free(tmp_oa);
 out_oa:
         obdo_free(ret_oa);
-out:
-        class_export_put(export);
-        return rc;
-}
-
-static int lov_open(struct lustre_handle *conn, struct obdo *src_oa,
-                    struct lov_stripe_md *lsm, struct obd_trans_info *oti,
-                    struct obd_client_handle *och)
-{
-        struct obdo *tmp_oa, *ret_oa;
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
-        int set = 0, rc = 0, i;
-        ENTRY;
-        LASSERT(och != NULL);
-
-        if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out_exp, rc = -ENODEV);
-
-        ret_oa = obdo_alloc();
-        if (!ret_oa)
-                GOTO(out_exp, rc = -ENOMEM);
-
-        tmp_oa = obdo_alloc();
-        if (!tmp_oa)
-                GOTO(out_oa, rc = -ENOMEM);
-
-        lfh = lov_lfh_new();
-        if (lfh == NULL)
-                GOTO(out_tmp, rc = -ENOMEM);
-        OBD_ALLOC(lfh->lfh_och, lsm->lsm_stripe_count * sizeof(*och));
-        if (!lfh->lfh_och)
-                GOTO(out_lfh, rc = -ENOMEM);
-
-        lov = &export->exp_obd->u.lov;
-        src_oa->o_size = 0;
-        src_oa->o_blocks = 0;
-        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
-                if (lov->tgts[loi->loi_ost_idx].active == 0) {
-                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
-                        continue;
-                }
-
-                /* create data objects with "parent" OA */
-                memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
-                tmp_oa->o_id = loi->loi_id;
-
-                rc = obd_open(&lov->tgts[loi->loi_ost_idx].conn, tmp_oa,
-                              NULL, NULL, &lfh->lfh_och[i]);
-                if (rc) {
-                        if (!lov->tgts[loi->loi_ost_idx].active) {
-                                rc = 0;
-                                continue;
-                        }
-                        CERROR("error: open objid "LPX64" subobj "LPX64
-                               " on OST idx %d: rc = %d\n",
-                               src_oa->o_id, lsm->lsm_oinfo[i].loi_id,
-                               loi->loi_ost_idx, rc);
-                        goto out_handles;
-                }
-
-                lov_merge_attrs(ret_oa, tmp_oa, tmp_oa->o_valid, lsm, i, &set);
-        }
-
-        lfh->lfh_count = lsm->lsm_stripe_count;
-        och->och_fh.cookie = lfh->lfh_handle.h_cookie;
-        obdo_handle(ret_oa)->cookie = lfh->lfh_handle.h_cookie;
-        ret_oa->o_valid |= OBD_MD_FLHANDLE;
-        ret_oa->o_id = src_oa->o_id;
-        memcpy(src_oa, ret_oa, sizeof(*src_oa));
-
-        /* lfh refcount transfers to list */
-        spin_lock(&export->exp_lov_data.led_lock);
-        list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head);
-        spin_unlock(&export->exp_lov_data.led_lock);
-
-        GOTO(out_tmp, rc);
- out_tmp:
-        obdo_free(tmp_oa);
- out_oa:
-        obdo_free(ret_oa);
- out_exp:
-        class_export_put(export);
-        return rc;
-
- out_handles:
-        for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) {
-                int err;
-
-                if (lov->tgts[loi->loi_ost_idx].active == 0)
-                        continue;
-
-                memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
-                tmp_oa->o_id = loi->loi_id;
-                memcpy(obdo_handle(tmp_oa), &lfh->lfh_och[i], FD_OSTDATA_SIZE);
-
-                err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, tmp_oa,
-                                NULL, NULL);
-                if (err && lov->tgts[loi->loi_ost_idx].active) {
-                        CERROR("error: closing objid "LPX64" subobj "LPX64
-                               " on OST idx %d after open error: rc=%d\n",
-                               src_oa->o_id, loi->loi_id, loi->loi_ost_idx,err);
-                }
-        }
-
-        OBD_FREE(lfh->lfh_och, lsm->lsm_stripe_count * FD_OSTDATA_SIZE);
- out_lfh:
-        lov_lfh_destroy(lfh);
-        lov_lfh_put(lfh);
-        goto out_tmp;
-}
-
-static int lov_close(struct lustre_handle *conn, struct obdo *oa,
-                     struct lov_stripe_md *lsm, struct obd_trans_info *oti)
-{
-        struct obdo tmp;
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
-        int rc = 0, i;
-        ENTRY;
-
-        if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
-
-        if (oa->o_valid & OBD_MD_FLHANDLE)
-                lfh = lov_handle2lfh(obdo_handle(oa));
-        if (!lfh)
-                LBUG();
-
-        lov = &export->exp_obd->u.lov;
-        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
-                int err;
-
-                /* create data objects with "parent" OA */
-                memcpy(&tmp, oa, sizeof(tmp));
-                tmp.o_id = loi->loi_id;
-                if (lfh)
-                        memcpy(obdo_handle(&tmp), &lfh->lfh_och[i],
-                               FD_OSTDATA_SIZE);
-                else
-                        tmp.o_valid &= ~OBD_MD_FLHANDLE;
-
-                err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, &tmp,
-                                NULL, NULL);
-                if (err) {
-                        if (lov->tgts[loi->loi_ost_idx].active) {
-                                CERROR("error: close objid "LPX64" subobj "LPX64
-                                       " on OST idx %d: rc = %d\n", oa->o_id,
-                                       loi->loi_id, loi->loi_ost_idx, err);
-                        }
-                        if (!rc)
-                                rc = err;
-                }
-        }
-        if (lfh != NULL) {
-                spin_lock(&export->exp_lov_data.led_lock);
-                list_del(&lfh->lfh_list);
-                spin_unlock(&export->exp_lov_data.led_lock);
-                lov_lfh_put(lfh); /* drop the reference owned by the list */
-
-                OBD_FREE(lfh->lfh_och, lsm->lsm_stripe_count * FD_OSTDATA_SIZE);
-                lov_lfh_destroy(lfh);
-                LASSERT(atomic_read(&lfh->lfh_refcount) == 1);
-                lov_lfh_put(lfh); /* balance handle2lfh above */
-        } else
-                LBUG();
-        GOTO(out, rc);
- out:
-        class_export_put(export);
         return rc;
 }
 
@@ -1507,28 +1220,23 @@ static int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off)
 /* FIXME: maybe we'll just make one node the authoritative attribute node, then
  * we can send this 'punch' to just the authoritative node and the nodes
  * that the punch will affect. */
-static int lov_punch(struct lustre_handle *conn, struct obdo *oa,
+static int lov_punch(struct obd_export *exp, struct obdo *oa,
                      struct lov_stripe_md *lsm,
                      obd_off start, obd_off end, struct obd_trans_info *oti)
 {
         struct obdo tmp;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        struct lov_file_handles *lfh = NULL;
         int rc = 0, i;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+                RETURN(-EINVAL);
 
-        if (oa->o_valid & OBD_MD_FLHANDLE)
-                lfh = lov_handle2lfh(obdo_handle(oa));
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
         for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
                 obd_off starti, endi;
                 int err;
@@ -1544,13 +1252,8 @@ static int lov_punch(struct lustre_handle *conn, struct obdo *oa,
                 /* create data objects with "parent" OA */
                 memcpy(&tmp, oa, sizeof(tmp));
                 tmp.o_id = loi->loi_id;
-                if (lfh)
-                        memcpy(obdo_handle(&tmp), &lfh->lfh_och[i].och_fh,
-                               sizeof(lfh->lfh_och[i].och_fh));
-                else
-                        tmp.o_valid &= ~OBD_MD_FLHANDLE;
 
-                err = obd_punch(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL,
+                err = obd_punch(lov->tgts[loi->loi_ost_idx].ltd_exp, &tmp, NULL,
                                 starti, endi, NULL);
                 if (err) {
                         if (lov->tgts[loi->loi_ost_idx].active) {
@@ -1562,12 +1265,59 @@ static int lov_punch(struct lustre_handle *conn, struct obdo *oa,
                                 rc = err;
                 }
         }
-        if (lfh != NULL)
-                lov_lfh_put(lfh);
-        GOTO(out, rc);
- out:
-        class_export_put(export);
-        return rc;
+        RETURN(rc);
+}
+
+static int lov_sync(struct obd_export *exp, struct obdo *oa,
+                    struct lov_stripe_md *lsm, obd_off start, obd_off end)
+{
+        struct obdo *tmp;
+        struct lov_obd *lov;
+        struct lov_oinfo *loi;
+        int rc = 0, i;
+        ENTRY;
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        if (!exp->exp_obd)
+                RETURN(-ENODEV);
+
+        tmp = obdo_alloc();
+        if (!tmp)
+                RETURN(-ENOMEM);
+
+        lov = &exp->exp_obd->u.lov;
+        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
+                obd_off starti, endi;
+                int err;
+
+                if (lov->tgts[loi->loi_ost_idx].active == 0) {
+                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
+                        continue;
+                }
+
+                if (!lov_stripe_intersects(lsm, i, start, end, &starti, &endi))
+                        continue;
+
+                memcpy(tmp, oa, sizeof(*tmp));
+                tmp->o_id = loi->loi_id;
+
+                err = obd_sync(lov->tgts[loi->loi_ost_idx].ltd_exp, tmp, NULL,
+                               starti, endi);
+                if (err) {
+                        if (lov->tgts[loi->loi_ost_idx].active) {
+                                CERROR("error: fsync objid "LPX64" subobj "LPX64
+                                       " on OST idx %d: rc = %d\n", oa->o_id,
+                                       loi->loi_id, loi->loi_ost_idx, err);
+                        }
+                        if (!rc)
+                                rc = err;
+                }
+        }
+
+        obdo_free(tmp);
+        RETURN(rc);
 }
 
 static int lov_brw_check(struct lov_obd *lov, struct lov_stripe_md *lsm,
@@ -1596,7 +1346,7 @@ static int lov_brw_check(struct lov_obd *lov, struct lov_stripe_md *lsm,
         return 0;
 }
 
-static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
+static int lov_brw(int cmd, struct obd_export *exp, struct obdo *src_oa,
                    struct lov_stripe_md *lsm, obd_count oa_bufs,
                    struct brw_page *pga, struct obd_trans_info *oti)
 {
@@ -1607,9 +1357,7 @@ static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
                 struct lov_stripe_md lsm;
                 int ost_idx;
         } *stripeinfo, *si, *si_last;
-        struct obd_export *export = class_conn2export(conn);
         struct obdo *ret_oa = NULL, *tmp_oa = NULL;
-        struct lov_file_handles *lfh = NULL;
         struct lov_obd *lov;
         struct brw_page *ioarr;
         struct lov_oinfo *loi;
@@ -1617,18 +1365,18 @@ static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
+                RETURN(-EINVAL);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
 
         if (cmd == OBD_BRW_CHECK) {
                 rc = lov_brw_check(lov, lsm, oa_bufs, pga);
-                GOTO(out_exp, rc);
+                RETURN(rc);
         }
 
         OBD_ALLOC(stripeinfo, stripe_count * sizeof(*stripeinfo));
         if (!stripeinfo)
-                GOTO(out_exp, rc = -ENOMEM);
+                RETURN(-ENOMEM);
 
         OBD_ALLOC(where, sizeof(*where) * oa_bufs);
         if (!where)
@@ -1646,11 +1394,6 @@ static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
                 tmp_oa = obdo_alloc();
                 if (!tmp_oa)
                         GOTO(out_oa, rc = -ENOMEM);
-
-                if (src_oa->o_valid & OBD_MD_FLHANDLE)
-                        lfh = lov_handle2lfh(obdo_handle(src_oa));
-                else
-                        src_oa->o_valid &= ~OBD_MD_FLHANDLE;
         }
 
         for (i = 0; i < oa_bufs; i++) {
@@ -1687,18 +1430,13 @@ static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
 
                 if (si->bufct) {
                         LASSERT(shift < oa_bufs);
-                        if (src_oa) {
+                        if (src_oa)
                                 memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));
-                                if (lfh)
-                                        memcpy(obdo_handle(tmp_oa),
-                                               &lfh->lfh_och[i].och_fh,
-                                               sizeof(lfh->lfh_och[i].och_fh));
-                        }
 
                         tmp_oa->o_id = si->lsm.lsm_object_id;
-                        rc = obd_brw(cmd, &lov->tgts[si->ost_idx].conn, tmp_oa,
-                                     &si->lsm, si->bufct, &ioarr[shift],
-                                     oti);
+                        rc = obd_brw(cmd, lov->tgts[si->ost_idx].ltd_exp, 
+                                     tmp_oa, &si->lsm, si->bufct, 
+                                     &ioarr[shift], oti);
                         if (rc)
                                 GOTO(out_ioarr, rc);
 
@@ -1720,18 +1458,15 @@ static int lov_brw(int cmd, struct lustre_handle *conn, struct obdo *src_oa,
         OBD_FREE(ioarr, sizeof(*ioarr) * oa_bufs);
  out_where:
         OBD_FREE(where, sizeof(*where) * oa_bufs);
-        if (lfh)
-                lov_lfh_put(lfh);
  out_sinfo:
         OBD_FREE(stripeinfo, stripe_count * sizeof(*stripeinfo));
- out_exp:
-        class_export_put(export);
         return rc;
 }
 
-static int lov_brw_interpret(struct ptlrpc_request_set *rqset,
-                             struct lov_brw_async_args *aa, int rc)
+static int lov_brw_interpret(struct ptlrpc_request_set *reqset, void *data,
+                             int rc)
 {
+        struct lov_brw_async_args *aa = data;
         struct lov_stripe_md *lsm = aa->aa_lsm;
         obd_count             oa_bufs = aa->aa_oa_bufs;
         struct obdo          *oa = aa->aa_oa;
@@ -1765,7 +1500,7 @@ static int lov_brw_interpret(struct ptlrpc_request_set *rqset,
         RETURN(rc);
 }
 
-static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int lov_brw_async(int cmd, struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *lsm, obd_count oa_bufs,
                          struct brw_page *pga, struct ptlrpc_request_set *set,
                          struct obd_trans_info *oti)
@@ -1777,9 +1512,7 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 struct lov_stripe_md lsm;
                 int ost_idx;
         } *stripeinfo, *si, *si_last;
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
-        struct lov_file_handles *lfh = NULL;
         struct brw_page *ioarr;
         struct obdo *obdos = NULL;
         struct lov_oinfo *loi;
@@ -1788,18 +1521,18 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
+                RETURN(-EINVAL);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
 
         if (cmd == OBD_BRW_CHECK) {
                 rc = lov_brw_check(lov, lsm, oa_bufs, pga);
-                GOTO(out_exp, rc);
+                RETURN(rc);
         }
 
         OBD_ALLOC(stripeinfo, stripe_count * sizeof(*stripeinfo));
         if (!stripeinfo)
-                GOTO(out_exp, rc = -ENOMEM);
+                RETURN(-ENOMEM);
 
         OBD_ALLOC(where, sizeof(*where) * oa_bufs);
         if (!where)
@@ -1809,11 +1542,6 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 OBD_ALLOC(obdos, sizeof(*obdos) * stripe_count);
                 if (!obdos)
                         GOTO(out_where, rc = -ENOMEM);
-
-                if (oa->o_valid & OBD_MD_FLHANDLE)
-                        lfh = lov_handle2lfh(obdo_handle(oa));
-                else
-                        oa->o_valid &= ~OBD_MD_FLHANDLE;
         }
 
         OBD_ALLOC(ioarr, sizeof(*ioarr) * oa_bufs);
@@ -1835,10 +1563,6 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 if (oa) {
                         memcpy(&obdos[i], oa, sizeof(*obdos));
                         obdos[i].o_id = si->lsm.lsm_object_id;
-                        if (lfh)
-                                memcpy(obdo_handle(&obdos[i]),
-                                       &lfh->lfh_och[i].och_fh,
-                                       sizeof(lfh->lfh_och[i].och_fh));
                 }
         }
 
@@ -1866,7 +1590,7 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
 
                 LASSERT(shift < oa_bufs);
 
-                rc = obd_brw_async(cmd, &lov->tgts[si->ost_idx].conn,
+                rc = obd_brw_async(cmd, lov->tgts[si->ost_idx].ltd_exp,
                                    &obdos[i], &si->lsm, si->bufct,
                                    &ioarr[shift], set, oti);
                 if (rc)
@@ -1892,299 +1616,401 @@ static int lov_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
         OBD_FREE(obdos, stripe_count * sizeof(*obdos));
  out_where:
         OBD_FREE(where, sizeof(*where) * oa_bufs);
-        if (lfh)
-                lov_lfh_put(lfh);
  out_sinfo:
         OBD_FREE(stripeinfo, stripe_count * sizeof(*stripeinfo));
- out_exp:
-        class_export_put(export);
         return rc;
 }
 
-static int lov_enqueue(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                       struct lustre_handle *parent_lock,
-                       __u32 type, void *cookie, int cookielen, __u32 mode,
-                       int *flags, void *cb, void *data,
-                       struct lustre_handle *lockh)
+struct lov_async_page *lap_from_cookie(void *cookie)
 {
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_lock_handles *lov_lockh = NULL;
-        struct lustre_handle *lov_lockhp;
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        struct lov_stripe_md submd;
-        ldlm_error_t rc;
-        int i;
-        ENTRY;
-
-        if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
+        struct lov_async_page *lap = cookie;
+        if (lap->lap_magic != LAP_MAGIC)
+                return ERR_PTR(-EINVAL);
+        return lap;
+};
 
-        /* we should never be asked to replay a lock this way. */
-        LASSERT((*flags & LDLM_FL_REPLAY) == 0);
+static int lov_ap_make_ready(void *data, int cmd)
+{
+        struct lov_async_page *lap = lap_from_cookie(data);
+        /* XXX should these assert? */
+        if (IS_ERR(lap))
+                return -EINVAL;
 
-        if (!export || !export->exp_obd)
-                GOTO(out_exp, rc = -ENODEV);
+        return lap->lap_caller_ops->ap_make_ready(lap->lap_caller_data, cmd);
+}
+static int lov_ap_refresh_count(void *data, int cmd)
+{
+        struct lov_async_page *lap = lap_from_cookie(data);
+        if (IS_ERR(lap))
+                return -EINVAL;
 
-        if (lsm->lsm_stripe_count > 1) {
-                lov_lockh = lov_llh_new(lsm);
-                if (lov_lockh == NULL)
-                        GOTO(out_exp, rc = -ENOMEM);
+        return lap->lap_caller_ops->ap_refresh_count(lap->lap_caller_data, 
+                                                     cmd);
+}
+static void lov_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
+{
+        struct lov_async_page *lap = lap_from_cookie(data);
+        /* XXX should these assert? */
+        if (IS_ERR(lap))
+                return;
+
+        lap->lap_caller_ops->ap_fill_obdo(lap->lap_caller_data, cmd, oa);
+        /* XXX woah, shouldn't we be altering more here?  size? */
+        oa->o_id = lap->lap_loi_id;
+}
+static void lov_ap_completion(void *data, int cmd, int rc)
+{
+        struct lov_async_page *lap = lap_from_cookie(data);
+        if (IS_ERR(lap))
+                return;
+
+        /* in a raid1 regime this would down a count of many ios
+         * in flight, onl calling the caller_ops completion when all
+         * the raid1 ios are complete */
+        lap->lap_caller_ops->ap_completion(lap->lap_caller_data, cmd, rc);
+}
 
-                lockh->cookie = lov_lockh->llh_handle.h_cookie;
-                lov_lockhp = lov_lockh->llh_handles;
-        } else {
-                lov_lockhp = lockh;
-        }
+static struct obd_async_page_ops lov_async_page_ops = {
+        .ap_make_ready =        lov_ap_make_ready,
+        .ap_refresh_count =     lov_ap_refresh_count,
+        .ap_fill_obdo =         lov_ap_fill_obdo,
+        .ap_completion =        lov_ap_completion,
+};
 
-        lov = &export->exp_obd->u.lov;
-        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
-             i++, loi++, lov_lockhp++) {
-                struct ldlm_extent *extent = (struct ldlm_extent *)cookie;
-                struct ldlm_extent sub_ext;
-
-                *flags = 0;
-                if (!lov_stripe_intersects(lsm, i, extent->start, extent->end,
-                                           &sub_ext.start, &sub_ext.end))
-                        continue;
+int lov_prep_async_page(struct obd_export *exp, struct lov_stripe_md *lsm,
+                           struct lov_oinfo *loi, struct page *page,
+                           obd_off offset, struct obd_async_page_ops *ops, 
+                           void *data, void **res)
+{
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        struct lov_async_page *lap;
+        int rc;
+        ENTRY;
 
-                if (lov->tgts[loi->loi_ost_idx].active == 0) {
-                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
-                        continue;
-                }
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+        LASSERT(loi == NULL);
 
-                /* XXX LOV STACKING: submd should be from the subobj */
-                submd.lsm_object_id = loi->loi_id;
-                submd.lsm_stripe_count = 0;
-                /* XXX submd is not fully initialized here */
-                *flags = 0;
-                rc = obd_enqueue(&(lov->tgts[loi->loi_ost_idx].conn), &submd,
-                                  parent_lock, type, &sub_ext, sizeof(sub_ext),
-                                  mode, flags, cb, data, lov_lockhp);
-
-                // XXX add a lock debug statement here
-                if (rc != ELDLM_OK) {
-                        memset(lov_lockhp, 0, sizeof(*lov_lockhp));
-                        if (lov->tgts[loi->loi_ost_idx].active) {
-                                CERROR("error: enqueue objid "LPX64" subobj "
-                                       LPX64" on OST idx %d: rc = %d\n",
-                                       lsm->lsm_object_id, loi->loi_id,
-                                       loi->loi_ost_idx, rc);
-                                GOTO(out_locks, rc);
-                        }
-                }
-        }
-        if (lsm->lsm_stripe_count > 1)
-                lov_llh_put(lov_lockh);
-        GOTO(out_exp, rc = ELDLM_OK);
+        OBD_ALLOC(lap, sizeof(*lap));
+        if (lap == NULL)
+                RETURN(-ENOMEM);
 
- out_locks:
-        while (loi--, lov_lockhp--, i-- > 0) {
-                struct lov_stripe_md submd;
-                int err;
+        lap->lap_magic = LAP_MAGIC;
+        lap->lap_caller_ops = ops;
+        lap->lap_caller_data = data;
 
-                if (lov_lockhp->cookie == 0)
-                        continue;
+        /* for now only raid 0 which passes through */
+        lap->lap_stripe = lov_stripe_number(lsm, offset);
+        lov_stripe_offset(lsm, offset, lap->lap_stripe, &lap->lap_sub_offset);
+        loi = &lsm->lsm_oinfo[lap->lap_stripe];
 
-                /* XXX LOV STACKING: submd should be from the subobj */
-                submd.lsm_object_id = loi->loi_id;
-                submd.lsm_stripe_count = 0;
-                err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd,
-                                 mode, lov_lockhp);
-                if (err && lov->tgts[loi->loi_ost_idx].active) {
-                        CERROR("error: cancelling objid "LPX64" on OST "
-                               "idx %d after enqueue error: rc = %d\n",
-                               loi->loi_id, loi->loi_ost_idx, err);
-                }
-        }
+        /* so the callback doesn't need the lsm */ 
+        lap->lap_loi_id = loi->loi_id;
 
-        if (lsm->lsm_stripe_count > 1) {
-                lov_llh_destroy(lov_lockh);
-                lov_llh_put(lov_lockh);
+        rc = obd_prep_async_page(lov->tgts[loi->loi_ost_idx].ltd_exp, 
+                                 lsm, loi, page, lap->lap_sub_offset,
+                                 &lov_async_page_ops, lap, 
+                                 &lap->lap_sub_cookie);
+        if (rc) {
+                OBD_FREE(lap, sizeof(*lap));
+                RETURN(rc);
         }
- out_exp:
-        class_export_put(export);
-        return(rc);
+        CDEBUG(D_CACHE, "lap %p page %p cookie %p off "LPU64"\n", lap, page, 
+               lap->lap_sub_cookie, offset);
+        *res = lap;
+        RETURN(0);
 }
 
-static int lov_match(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                     __u32 type, void *cookie, int cookielen, __u32 mode,
-                     int *flags, void *data, struct lustre_handle *lockh)
+static int lov_queue_async_io(struct obd_export *exp, 
+                              struct lov_stripe_md *lsm, 
+                              struct lov_oinfo *loi, void *cookie, 
+                              int cmd, obd_off off, int count, 
+                              obd_flag brw_flags, obd_flag async_flags)
 {
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_lock_handles *lov_lockh = NULL;
-        struct lustre_handle *lov_lockhp;
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        struct lov_stripe_md submd;
-        ldlm_error_t rc = 0;
-        int i;
-        ENTRY;
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        struct lov_async_page *lap;
+        int rc;
 
-        if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
+        LASSERT(loi == NULL);
 
-        if (!export || !export->exp_obd)
-                GOTO(out_exp, rc = -ENODEV);
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
 
-        if (lsm->lsm_stripe_count > 1) {
-                lov_lockh = lov_llh_new(lsm);
-                if (lov_lockh == NULL)
-                        GOTO(out_exp, rc = -ENOMEM);
+        lap = lap_from_cookie(cookie);
+        if (IS_ERR(lap))
+                RETURN(PTR_ERR(lap));
 
-                lockh->cookie = lov_lockh->llh_handle.h_cookie;
-                lov_lockhp = lov_lockh->llh_handles;
-        } else {
-                lov_lockhp = lockh;
-        }
+        loi = &lsm->lsm_oinfo[lap->lap_stripe];
+        rc = obd_queue_async_io(lov->tgts[loi->loi_ost_idx].ltd_exp, lsm,
+                                loi, lap->lap_sub_cookie, cmd, off, count,
+                                brw_flags, async_flags);
+        RETURN(rc);
+}
 
-        lov = &export->exp_obd->u.lov;
-        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
-             i++, loi++, lov_lockhp++) {
-                struct ldlm_extent *extent = (struct ldlm_extent *)cookie;
-                struct ldlm_extent sub_ext;
-                int lov_flags;
-
-                if (!lov_stripe_intersects(lsm, i, extent->start, extent->end,
-                                           &sub_ext.start, &sub_ext.end))
-                        continue;
+static int lov_set_async_flags(struct obd_export *exp,
+                               struct lov_stripe_md *lsm,
+                               struct lov_oinfo *loi, void *cookie,
+                               obd_flag async_flags)
+{
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        struct lov_async_page *lap;
+        int rc;
 
-                if (lov->tgts[loi->loi_ost_idx].active == 0) {
-                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
-                        rc = -EIO;
-                        break;
-                }
+        LASSERT(loi == NULL);
 
-                /* XXX LOV STACKING: submd should be from the subobj */
-                submd.lsm_object_id = loi->loi_id;
-                submd.lsm_stripe_count = 0;
-                lov_flags = *flags;
-                /* XXX submd is not fully initialized here */
-                rc = obd_match(&(lov->tgts[loi->loi_ost_idx].conn), &submd,
-                               type, &sub_ext, sizeof(sub_ext), mode,
-                               &lov_flags, data, lov_lockhp);
-                if (rc != 1)
-                        break;
-        }
-        if (rc == 1) {
-                if (lsm->lsm_stripe_count > 1)
-                        lov_llh_put(lov_lockh);
-                GOTO(out_exp, 1);
-        }
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
 
-        while (loi--, lov_lockhp--, i-- > 0) {
-                struct lov_stripe_md submd;
-                int err;
+        lap = lap_from_cookie(cookie);
+        if (IS_ERR(lap))
+                RETURN(PTR_ERR(lap));
 
-                if (lov_lockhp->cookie == 0)
-                        continue;
+        loi = &lsm->lsm_oinfo[lap->lap_stripe];
+        rc = obd_set_async_flags(lov->tgts[loi->loi_ost_idx].ltd_exp, 
+                                 lsm, loi, lap->lap_sub_cookie, async_flags);
+        RETURN(rc);
+}
 
-                /* XXX LOV STACKING: submd should be from the subobj */
-                submd.lsm_object_id = loi->loi_id;
-                submd.lsm_stripe_count = 0;
-                err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd,
-                                 mode, lov_lockhp);
-                if (err && lov->tgts[loi->loi_ost_idx].active) {
-                        CERROR("error: cancelling objid "LPX64" on OST "
-                               "idx %d after match failure: rc = %d\n",
-                               loi->loi_id, loi->loi_ost_idx, err);
-                }
-        }
+static int lov_queue_sync_io(struct obd_export *exp, 
+                             struct lov_stripe_md *lsm, 
+                             struct lov_oinfo *loi, 
+                             struct obd_sync_io_container *osic, void *cookie,
+                             int cmd, obd_off off, int count, 
+                             obd_flag brw_flags)
+{
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        struct lov_async_page *lap;
+        int rc;
+
+        LASSERT(loi == NULL);
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        lap = lap_from_cookie(cookie);
+        if (IS_ERR(lap))
+                RETURN(PTR_ERR(lap));
 
-        if (lsm->lsm_stripe_count > 1) {
-                lov_llh_destroy(lov_lockh);
-                lov_llh_put(lov_lockh);
+        loi = &lsm->lsm_oinfo[lap->lap_stripe];
+        rc = obd_queue_sync_io(lov->tgts[loi->loi_ost_idx].ltd_exp, lsm, loi, 
+                               osic, lap->lap_sub_cookie, cmd, off, count, 
+                               brw_flags);
+        RETURN(rc);
+}
+
+/* this isn't exactly optimal.  we may have queued sync io in oscs on
+ * all stripes, but we don't record that fact at queue time.  so we 
+ * trigger sync io on all stripes. */
+static int lov_trigger_sync_io(struct obd_export *exp, 
+                               struct lov_stripe_md *lsm, 
+                               struct lov_oinfo *loi,
+                               struct obd_sync_io_container *osic)
+{
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        int rc = 0, i, err;
+
+        LASSERT(loi == NULL);
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; 
+             i++, loi++) {
+                err = obd_trigger_sync_io(lov->tgts[loi->loi_ost_idx].ltd_exp, 
+                                          lsm, loi, osic);
+                if (rc == 0 && err != 0)
+                        rc = err;
+        };
+        RETURN(rc);
+}
+
+static int lov_teardown_async_page(struct obd_export *exp,
+                                   struct lov_stripe_md *lsm,
+                                   struct lov_oinfo *loi, void *cookie)
+{
+        struct lov_obd *lov = &exp->exp_obd->u.lov;
+        struct lov_async_page *lap;
+        int rc;
+
+        LASSERT(loi == NULL);
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        lap = lap_from_cookie(cookie);
+        if (IS_ERR(lap))
+                RETURN(PTR_ERR(lap));
+
+        loi = &lsm->lsm_oinfo[lap->lap_stripe];
+        rc = obd_teardown_async_page(lov->tgts[loi->loi_ost_idx].ltd_exp, 
+                                     lsm, loi, lap->lap_sub_cookie);
+        if (rc) {
+                CERROR("unable to teardown sub cookie %p: %d\n", 
+                       lap->lap_sub_cookie, rc);
+                RETURN(rc);
         }
- out_exp:
-        class_export_put(export);
+        OBD_FREE(lap, sizeof(*lap));
         RETURN(rc);
 }
 
-static int lov_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                      __u32 mode, struct lustre_handle *lockh)
+static int lov_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
+                       struct lustre_handle *parent_lock,
+                       __u32 type, void *cookie, int cookielen, __u32 mode,
+                       int *flags, void *cb, void *data,
+                       struct lustre_handle *lockh)
 {
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_lock_handles *lov_lockh = NULL;
-        struct lustre_handle *lov_lockhp;
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        int rc = 0, i;
+        struct lov_stripe_md submd;
+        struct ldlm_extent *extent = cookie;
+        int rc;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
+                RETURN(-EINVAL);
+
+        /* we should never be asked to replay a lock this way. */
+        LASSERT((*flags & LDLM_FL_REPLAY) == 0);
 
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        LASSERT(lockh);
-        if (lsm->lsm_stripe_count > 1) {
-                lov_lockh = lov_handle2llh(lockh);
-                if (!lov_lockh) {
-                        CERROR("LOV: invalid lov lock handle %p\n", lockh);
-                        GOTO(out, rc = -EINVAL);
-                }
+        lov = &exp->exp_obd->u.lov;
+        loi = lsm->lsm_oinfo;
+        if (lov->tgts[loi->loi_ost_idx].active == 0) {
+                 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
+                 RETURN(-EIO);
+        }
+        
+        /* XXX LOV STACKING: submd should be from the subobj */
+        submd.lsm_object_id = loi->loi_id;
+        submd.lsm_stripe_count = 0;
+        /* XXX submd is not fully initialized here */
+        *flags = 0;
+        rc = obd_enqueue(lov->tgts[loi->loi_ost_idx].ltd_exp, &submd,
+                         parent_lock, type, extent, sizeof(*extent),
+                         mode, flags, cb, data, lockh);
+
+        if (rc != ELDLM_OK) {
+                memset(lockh, 0, sizeof(*lockh));
+                if (lov->tgts[loi->loi_ost_idx].active)
+                        CERROR("error: enqueue objid "LPX64" subobj "
+                               LPX64" on OST idx %d: rc = %d\n",
+                               lsm->lsm_object_id, loi->loi_id,
+                               loi->loi_ost_idx, rc);
+        }
+        RETURN(rc);
+}
 
-                lov_lockhp = lov_lockh->llh_handles;
-        } else {
-                lov_lockhp = lockh;
+static int lov_match(struct obd_export *exp, struct lov_stripe_md *lsm,
+                     __u32 type, void *cookie, int cookielen, __u32 mode,
+                     int *flags, void *data, struct lustre_handle *lockh)
+{
+        struct lov_obd *lov;
+        struct lov_oinfo *loi;
+        struct lov_stripe_md submd;
+        struct ldlm_extent *extent = cookie;
+        int rc = 0;
+        ENTRY;
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
+
+        lov = &exp->exp_obd->u.lov;
+        loi = lsm->lsm_oinfo;
+        if (lov->tgts[loi->loi_ost_idx].active == 0) {
+                CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
+                RETURN(-EIO);
         }
 
-        lov = &export->exp_obd->u.lov;
-        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count;
-             i++, loi++, lov_lockhp++) {
-                struct lov_stripe_md submd;
-                int err;
+        /* XXX LOV STACKING: submd should be from the subobj */
+        submd.lsm_object_id = loi->loi_id;
+        submd.lsm_stripe_count = 0;
+        /* XXX submd is not fully initialized here */
+        rc = obd_match(lov->tgts[loi->loi_ost_idx].ltd_exp, &submd, type,
+                       extent, sizeof(*extent), mode, flags, data, lockh);
+        RETURN(rc);
+}
 
-                if (lov_lockhp->cookie == 0) {
-                        CDEBUG(D_HA, "lov idx %d subobj "LPX64" no lock?\n",
-                               loi->loi_ost_idx, loi->loi_id);
-                        continue;
-                }
+static int lov_change_cbdata(struct obd_export *exp,
+                             struct lov_stripe_md *lsm, ldlm_iterator_t it,
+                             void *data)
+{
+        struct lov_obd *lov;
+        struct lov_oinfo *loi;
+        int rc = 0, i;
+        ENTRY;
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
+
+        lov = &exp->exp_obd->u.lov;
+        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
+                struct lov_stripe_md submd;
+                if (lov->tgts[loi->loi_ost_idx].active == 0)
+                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
 
-                /* XXX LOV STACKING: submd should be from the subobj */
                 submd.lsm_object_id = loi->loi_id;
                 submd.lsm_stripe_count = 0;
-                err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd,
-                                 mode, lov_lockhp);
-                if (err) {
-                        if (lov->tgts[loi->loi_ost_idx].active) {
-                                CERROR("error: cancel objid "LPX64" subobj "
-                                       LPX64" on OST idx %d: rc = %d\n",
-                                       lsm->lsm_object_id,
-                                       loi->loi_id, loi->loi_ost_idx, err);
-                                if (!rc)
-                                        rc = err;
-                        }
-                }
+                rc = obd_change_cbdata(lov->tgts[loi->loi_ost_idx].ltd_exp,
+                                       &submd, it, data);
         }
+        RETURN(rc);
+}
+
+static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm,
+                      __u32 mode, struct lustre_handle *lockh)
+{
+        struct lov_obd *lov;
+        struct lov_oinfo *loi;
+        struct lov_stripe_md submd;
+        int rc = 0;
+        ENTRY;
+
+        if (lsm_bad_magic(lsm))
+                RETURN(-EINVAL);
+
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
+
+        lov = &exp->exp_obd->u.lov;
+        loi = lsm->lsm_oinfo;
 
-        if (lsm->lsm_stripe_count > 1)
-                lov_llh_destroy(lov_lockh);
-        if (lov_lockh != NULL)
-                lov_llh_put(lov_lockh);
+        /* XXX LOV STACKING: submd should be from the subobj */
+        submd.lsm_object_id = loi->loi_id;
+        submd.lsm_stripe_count = 0;
+        rc = obd_cancel(lov->tgts[loi->loi_ost_idx].ltd_exp, &submd,
+                         mode, lockh);
+        if (rc && lov->tgts[loi->loi_ost_idx].active)
+                CERROR("error: cancel objid "LPX64" subobj "
+                       LPX64" on OST idx %d: rc = %d\n",
+                       lsm->lsm_object_id, loi->loi_id, loi->loi_ost_idx, rc);
         GOTO(out, rc);
- out:
-        class_export_put(export);
-        return rc;
+out:
+        RETURN(rc);
 }
 
-static int lov_cancel_unused(struct lustre_handle *conn,
+static int lov_cancel_unused(struct obd_export *exp,
                              struct lov_stripe_md *lsm, int flags, void *opaque)
 {
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
         int rc = 0, i;
         ENTRY;
 
         if (lsm_bad_magic(lsm))
-                GOTO(out, rc = -EINVAL);
+                RETURN(-EINVAL);
 
-        if (!export || !export->exp_obd)
-                GOTO(out, rc = -ENODEV);
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
 
-        lov = &export->exp_obd->u.lov;
+        lov = &exp->exp_obd->u.lov;
         for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
                 struct lov_stripe_md submd;
                 int err;
@@ -2194,7 +2020,7 @@ static int lov_cancel_unused(struct lustre_handle *conn,
 
                 submd.lsm_object_id = loi->loi_id;
                 submd.lsm_stripe_count = 0;
-                err = obd_cancel_unused(&lov->tgts[loi->loi_ost_idx].conn,
+                err = obd_cancel_unused(lov->tgts[loi->loi_ost_idx].ltd_exp,
                                         &submd, flags, opaque);
                 if (err && lov->tgts[loi->loi_ost_idx].active) {
                         CERROR("error: cancel unused objid "LPX64" subobj "LPX64
@@ -2204,10 +2030,7 @@ static int lov_cancel_unused(struct lustre_handle *conn,
                                 rc = err;
                 }
         }
-        GOTO(out, rc);
- out:
-        class_export_put(export);
-        return rc;
+        RETURN(rc);
 }
 
 #define LOV_U64_MAX ((__u64)~0ULL)
@@ -2239,7 +2062,7 @@ static int lov_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                         continue;
                 }
 
-                err = obd_statfs(class_conn2obd(&lov->tgts[i].conn), &lov_sfs,
+                err = obd_statfs(class_exp2obd(lov->tgts[i].ltd_exp), &lov_sfs,
                                  max_age);
                 if (err) {
                         if (lov->tgts[i].active && !rc)
@@ -2285,10 +2108,10 @@ static int lov_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         RETURN(rc);
 }
 
-static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
+static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                          void *karg, void *uarg)
 {
-        struct obd_device *obddev = class_conn2obd(conn);
+        struct obd_device *obddev = class_exp2obd(exp);
         struct lov_obd *lov = &obddev->u.lov;
         int i, count = lov->desc.ld_tgt_count;
         struct obd_uuid *uuidp;
@@ -2297,12 +2120,6 @@ static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
         ENTRY;
 
         switch (cmd) {
-        case IOC_LOV_SET_OSC_ACTIVE: {
-                struct obd_ioctl_data *data = karg;
-                uuidp = (struct obd_uuid *)data->ioc_inlbuf1;
-                rc = lov_set_osc_active(lov, uuidp, data->ioc_offset);
-                break;
-        }
         case OBD_IOC_LOV_GET_CONFIG: {
                 struct obd_ioctl_data *data = karg;
                 struct lov_tgt_desc *tgtdesc;
@@ -2341,10 +2158,10 @@ static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
                 break;
         }
         case LL_IOC_LOV_SETSTRIPE:
-                rc = lov_setstripe(conn, karg, uarg);
+                rc = lov_setstripe(exp, karg, uarg);
                 break;
         case LL_IOC_LOV_GETSTRIPE:
-                rc = lov_getstripe(conn, karg, uarg);
+                rc = lov_getstripe(exp, karg, uarg);
                 break;
         default: {
                 int set = 0;
@@ -2354,7 +2171,7 @@ static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
                 for (i = 0; i < count; i++) {
                         int err;
 
-                        err = obd_iocontrol(cmd, &lov->tgts[i].conn,
+                        err = obd_iocontrol(cmd, lov->tgts[i].ltd_exp,
                                             len, karg, uarg);
                         if (err) {
                                 if (lov->tgts[i].active) {
@@ -2375,10 +2192,10 @@ static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
         RETURN(rc);
 }
 
-static int lov_get_info(struct lustre_handle *conn, __u32 keylen,
+static int lov_get_info(struct obd_export *exp, __u32 keylen,
                         void *key, __u32 *vallen, void *val)
-{
-        struct obd_device *obddev = class_conn2obd(conn);
+{       
+        struct obd_device *obddev = class_exp2obd(exp);
         struct lov_obd *lov = &obddev->u.lov;
         int i;
         ENTRY;
@@ -2393,8 +2210,8 @@ static int lov_get_info(struct lustre_handle *conn, __u32 keylen,
                         struct ldlm_lock *lock;
                         struct lov_stripe_md *lsm;
                 } *data = key;
-                __u32 *stripe = val;
                 struct lov_oinfo *loi;
+                __u32 *stripe = val;
 
                 if (*vallen < sizeof(*stripe))
                         RETURN(-EFAULT);
@@ -2402,281 +2219,123 @@ static int lov_get_info(struct lustre_handle *conn, __u32 keylen,
 
                 /* XXX This is another one of those bits that will need to
                  * change if we ever actually support nested LOVs.  It uses
-                 * the lock's connection to find out which stripe it is. */
+                 * the lock's export to find out which stripe it is. */
                 for (i = 0, loi = data->lsm->lsm_oinfo;
                      i < data->lsm->lsm_stripe_count;
                      i++, loi++) {
-                        if (lov->tgts[loi->loi_ost_idx].conn.cookie ==
-                            data->lock->l_connh->cookie) {
+                        if (lov->tgts[loi->loi_ost_idx].ltd_exp ==
+                            data->lock->l_conn_export) {
                                 *stripe = i;
                                 RETURN(0);
                         }
                 }
                 RETURN(-ENXIO);
+        } else if (keylen >= strlen("last_id") && strcmp(key, "last_id") == 0) {
+                obd_id *ids = val;
+                int rc, size = sizeof(obd_id);
+                for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                        if (!lov->tgts[i].active)
+                                continue;
+                        rc = obd_get_info(lov->tgts[i].ltd_exp, keylen, key,
+                                          &size, &(ids[i]));
+                        if (rc != 0)
+                                RETURN(rc);
+                }
+                RETURN(0);
+        } else if (keylen >= strlen("lovdesc") && strcmp(key, "lovdesc") == 0) {
+                struct lov_desc *desc_ret = val;
+                *desc_ret = lov->desc;
+                
+                RETURN(0);
         }
 
         RETURN(-EINVAL);
 }
 
-static int lov_set_info(struct lustre_handle *conn, obd_count keylen,
+static int lov_set_info(struct obd_export *exp, obd_count keylen,
                         void *key, obd_count vallen, void *val)
 {
-        struct obd_device *obddev = class_conn2obd(conn);
+        struct obd_device *obddev = class_exp2obd(exp);
         struct lov_obd *lov = &obddev->u.lov;
         int i, rc = 0;
         ENTRY;
 
-        if (keylen < strlen("mds_conn") ||
-            memcmp(key, "mds_conn", strlen("mds_conn")) != 0)
-                RETURN(-EINVAL);
-
-        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                int er;
-                er = obd_set_info(&lov->tgts[i].conn, keylen, key, vallen, val);
-                if (!rc)
-                        rc = er;
-        }
-        RETURN(rc);
-}
-
-static int lov_mark_page_dirty(struct lustre_handle *conn,
-                               struct lov_stripe_md *lsm, unsigned long offset)
-{
-        struct lov_obd *lov = &class_conn2obd(conn)->u.lov;
-        struct lov_oinfo *loi;
-        struct lov_stripe_md *submd;
-        int stripe, rc;
-        obd_off off;
-        ENTRY;
-
-        if (lsm_bad_magic(lsm))
-                RETURN(-EINVAL);
-
-        OBD_ALLOC(submd, lov_stripe_md_size(1));
-        if (submd == NULL)
-                RETURN(-ENOMEM);
-
-        stripe = lov_stripe_number(lsm, (obd_off)offset << PAGE_CACHE_SHIFT);
-        lov_stripe_offset(lsm, (obd_off)offset << PAGE_CACHE_SHIFT, stripe,
-                          &off);
-        off >>= PAGE_CACHE_SHIFT;
-
-        loi = &lsm->lsm_oinfo[stripe];
-        CDEBUG(D_INODE, "off %lu => off %lu on stripe %d\n", offset,
-               (unsigned long)off, stripe);
-        submd->lsm_oinfo[0].loi_dirty_ot = &loi->loi_dirty_ot_inline;
-
-        rc = obd_mark_page_dirty(&lov->tgts[loi->loi_ost_idx].conn, submd, off);
-        OBD_FREE(submd, lov_stripe_md_size(1));
-        RETURN(rc);
-}
-
-static int lov_clear_dirty_pages(struct lustre_handle *conn,
-                                 struct lov_stripe_md *lsm, unsigned long start,
-                                 unsigned long end, unsigned long *cleared)
-
-{
-        struct obd_export *export = class_conn2export(conn);
-        __u64 start_off = (__u64)start << PAGE_CACHE_SHIFT;
-        __u64 end_off = (__u64)end << PAGE_CACHE_SHIFT;
-        __u64 obd_start, obd_end;
-        struct lov_stripe_md *submd = NULL;
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        int i, rc;
-        unsigned long osc_cleared;
-        ENTRY;
-
-        *cleared = 0;
-
-        if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
+#define KEY_IS(str) \
+        (keylen == strlen(str) && memcmp(key, str, keylen) == 0)
 
-        if (!export || !export->exp_obd)
-                GOTO(out_exp, rc = -ENODEV);
+        if (KEY_IS("next_id")) {
+                if (vallen != lov->desc.ld_tgt_count)
+                        RETURN(-EINVAL);
+                for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                        int er;
 
-        OBD_ALLOC(submd, lov_stripe_md_size(1));
-        if (submd == NULL)
-                GOTO(out_exp, rc = -ENOMEM);
+                        if (!lov->tgts[i].active)
+                                continue;
 
-        lov = &export->exp_obd->u.lov;
-        rc = 0;
-        for (i = 0, loi = lsm->lsm_oinfo;
-             i < lsm->lsm_stripe_count;
-             i++, loi++) {
-                if (lov->tgts[loi->loi_ost_idx].active == 0) {
-                        CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
-                        continue;
+                        er = obd_set_info(lov->tgts[i].ltd_exp, keylen, key,
+                                          sizeof(obd_id), ((obd_id*)val) + i);
+                        if (!rc)
+                                rc = er;
                 }
-
-                if(!lov_stripe_intersects(lsm, i, start_off, end_off,
-                                          &obd_start, &obd_end))
-                        continue;
-                obd_start >>= PAGE_CACHE_SHIFT;
-                obd_end >>= PAGE_CACHE_SHIFT;
-
-                CDEBUG(D_INODE, "offs [%lu,%lu] => offs [%lu,%lu] stripe %d\n",
-                       start, end, (unsigned long)obd_start,
-                       (unsigned long)obd_end, loi->loi_ost_idx);
-                submd->lsm_oinfo[0].loi_dirty_ot = &loi->loi_dirty_ot_inline;
-                rc = obd_clear_dirty_pages(&lov->tgts[loi->loi_ost_idx].conn,
-                                           submd, obd_start, obd_end,
-                                           &osc_cleared);
-                if (rc)
-                        break;
-                *cleared += osc_cleared;
+                RETURN(rc);
         }
-out_exp:
-        if (submd)
-                OBD_FREE(submd, lov_stripe_md_size(1));
-        class_export_put(export);
-        RETURN(rc);
-}
-
-static int lov_last_dirty_offset(struct lustre_handle *conn,
-                                 struct lov_stripe_md *lsm,
-                                 unsigned long *offset)
-{
-        struct obd_export *export = class_conn2export(conn);
-        struct lov_stripe_md *submd = NULL;
-        struct lov_obd *lov;
-        struct lov_oinfo *loi;
-        unsigned long tmp, count, skip;
-        int err, i, rc;
-        ENTRY;
-
-        if (lsm_bad_magic(lsm))
-                GOTO(out_exp, rc = -EINVAL);
-
-        if (!export || !export->exp_obd)
-                GOTO(out_exp, rc = -ENODEV);
 
-        OBD_ALLOC(submd, lov_stripe_md_size(1));
-        if (submd == NULL)
-                GOTO(out_exp, rc = -ENOMEM);
-
-        *offset = 0;
-        lov = &export->exp_obd->u.lov;
-        rc = -ENOENT;
-
-        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++){
-                count = lsm->lsm_stripe_size >> PAGE_CACHE_SHIFT;
-                skip = (lsm->lsm_stripe_count - 1) * count;
+        if (KEY_IS("growth_count")) {
+                if (vallen != sizeof(int))
+                        RETURN(-EINVAL);
+        } else if (KEY_IS("mds_conn") || KEY_IS("unlinked")) {
+                if (vallen != 0)
+                        RETURN(-EINVAL);
+        } else {
+                RETURN(-EINVAL);
+        }
 
-                submd->lsm_oinfo[0].loi_dirty_ot = &loi->loi_dirty_ot_inline;
+        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+                int er;
 
-                err = obd_last_dirty_offset(&lov->tgts[loi->loi_ost_idx].conn,
-                                            submd, &tmp);
-                if (err == -ENOENT)
+                if (!lov->tgts[i].active)
                         continue;
-                if (err)
-                        GOTO(out_exp, rc = err);
 
-                rc = 0;
-                if (tmp != ~0)
-                        tmp += (tmp/count * skip) + (i * count);
-                if (tmp > *offset)
-                        *offset = tmp;
-        }
-out_exp:
-        if (submd)
-                OBD_FREE(submd, lov_stripe_md_size(1));
-        class_export_put(export);
+                er = obd_set_info(lov->tgts[i].ltd_exp, keylen, key, vallen,
+                                   val);
+                if (!rc)
+                        rc = er;
+        }
         RETURN(rc);
-}
+#undef KEY_IS
 
-/* For LOV catalogs, we "nest" catalogs from the parent catalog.  What this
- * means is that the parent catalog has a bunch of log cookies that are
- * pointing at one catalog for each OSC.  The OSC catalogs in turn hold
- * cookies for actual log files. */
-static int lov_get_catalogs(struct lov_obd *lov, struct llog_handle *cathandle)
-{
-        int i, rc;
-
-        ENTRY;
-        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                lov->tgts[i].ltd_cathandle = llog_new_log(cathandle,
-                                                          &lov->tgts[i].uuid);
-                if (IS_ERR(lov->tgts[i].ltd_cathandle))
-                        continue;
-                rc = llog_init_catalog(cathandle, &lov->tgts[i].uuid);
-                if (rc)
-                        GOTO(err_logs, rc);
-        }
-        lov->lo_catalog_loaded = 1;
-        RETURN(0);
-err_logs:
-        while (i-- > 0) {
-                llog_delete_log(cathandle, lov->tgts[i].ltd_cathandle);
-                llog_close_log(cathandle, lov->tgts[i].ltd_cathandle);
-        }
-        return rc;
 }
 
-/* Add log records for each OSC that this object is striped over, and return
- * cookies for each one.  We _would_ have nice abstraction here, except that
- * we need to keep cookies in stripe order, even if some are NULL, so that
- * the right cookies are passed back to the right OSTs at the client side.
- * Unset cookies should be all-zero (which will never occur naturally). */
-static int lov_log_add(struct lustre_handle *conn,
-                       struct llog_handle *cathandle,
-                       struct llog_trans_hdr *rec, struct lov_stripe_md *lsm,
-                       struct llog_cookie *logcookies, int numcookies)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct lov_obd *lov = &obd->u.lov;
-        struct lov_oinfo *loi;
-        int i, rc = 0;
-        ENTRY;
-
-        LASSERT(logcookies && numcookies >= lsm->lsm_stripe_count);
-
-        if (unlikely(!lov->lo_catalog_loaded))
-                lov_get_catalogs(lov, cathandle);
 
-        for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) {
-                rc += obd_log_add(&lov->tgts[loi->loi_ost_idx].conn,
-                                  lov->tgts[loi->loi_ost_idx].ltd_cathandle,
-                                  rec, NULL, logcookies + rc, numcookies - rc);
-        }
-
-        RETURN(rc);
-}
-
-static int lov_log_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                          int count, struct llog_cookie *cookies, int flags)
+static int lov_lock_contains(struct obd_export *exp, struct lov_stripe_md *lsm,
+                             struct ldlm_lock *lock, obd_off offset)
 {
-        struct obd_export *export = class_conn2export(conn);
         struct lov_obd *lov;
         struct lov_oinfo *loi;
-        int rc = 0, i;
+        struct lov_stripe_md submd;
+        int rc;
         ENTRY;
 
         LASSERT(lsm != NULL);
-        if (export == NULL || export->exp_obd == NULL)
-                GOTO(out, rc = -ENODEV);
-
-        LASSERT(count == lsm->lsm_stripe_count);
+        if (exp == NULL)
+                RETURN(-ENODEV);
 
+        lov = &exp->exp_obd->u.lov;
         loi = lsm->lsm_oinfo;
-        lov = &export->exp_obd->u.lov;
-        for (i = 0; i < count; i++, cookies++, loi++) {
-                int err;
 
-                err = obd_log_cancel(&lov->tgts[loi->loi_ost_idx].conn,
-                                     NULL, 1, cookies, flags);
-                if (err && lov->tgts[loi->loi_ost_idx].active) {
-                        CERROR("error: objid "LPX64" subobj "LPX64
-                               " on OST idx %d: rc = %d\n", lsm->lsm_object_id,
-                               loi->loi_id, loi->loi_ost_idx, err);
-                        if (!rc)
-                                rc = err;
-                }
+        if (lov->tgts[loi->loi_ost_idx].active == 0) {
+                 CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
+                 RETURN(-EIO);
         }
-        GOTO(out, rc);
- out:
-        class_export_put(export);
-        return rc;
+        
+        /* XXX submd is not fully initialized here */
+        /* XXX LOV STACKING: submd should be from the subobj */
+        submd.lsm_object_id = loi->loi_id;
+        submd.lsm_stripe_count = 0;
+
+        rc = obd_lock_contains(lov->tgts[loi->loi_ost_idx].ltd_exp, &submd,
+                               lock, offset);
+        RETURN(rc);
 }
 
 struct obd_ops lov_obd_ops = {
@@ -2684,6 +2343,7 @@ struct obd_ops lov_obd_ops = {
         o_attach:      lov_attach,
         o_detach:      lov_detach,
         o_setup:       lov_setup,
+        o_cleanup:     lov_cleanup,
         o_connect:     lov_connect,
         o_disconnect:  lov_disconnect,
         o_statfs:      lov_statfs,
@@ -2694,23 +2354,28 @@ struct obd_ops lov_obd_ops = {
         o_getattr:     lov_getattr,
         o_getattr_async: lov_getattr_async,
         o_setattr:     lov_setattr,
-        o_open:        lov_open,
-        o_close:       lov_close,
         o_brw:         lov_brw,
         o_brw_async:   lov_brw_async,
+        .o_prep_async_page =    lov_prep_async_page,
+        .o_queue_async_io =     lov_queue_async_io,
+        .o_set_async_flags =    lov_set_async_flags,
+        .o_queue_sync_io =      lov_queue_sync_io,
+        .o_trigger_sync_io =    lov_trigger_sync_io,
+        .o_teardown_async_page  lov_teardown_async_page,
         o_punch:       lov_punch,
+        o_sync:        lov_sync,
         o_enqueue:     lov_enqueue,
         o_match:       lov_match,
+        o_change_cbdata: lov_change_cbdata,
         o_cancel:      lov_cancel,
         o_cancel_unused: lov_cancel_unused,
         o_iocontrol:   lov_iocontrol,
         o_get_info:    lov_get_info,
         o_set_info:    lov_set_info,
-        o_log_add:     lov_log_add,
-        o_log_cancel:  lov_log_cancel,
-        o_mark_page_dirty:   lov_mark_page_dirty,
-        o_clear_dirty_pages: lov_clear_dirty_pages,
-        o_last_dirty_offset: lov_last_dirty_offset,
+        o_llog_init:   lov_llog_init,
+        o_llog_finish: lov_llog_finish,
+        o_lock_contains:lov_lock_contains,
+        o_notify: lov_notify,
 };
 
 int __init lov_init(void)
@@ -2724,12 +2389,12 @@ int __init lov_init(void)
         RETURN(rc);
 }
 
+#ifdef __KERNEL__
 static void /*__exit*/ lov_exit(void)
 {
         class_unregister_type(OBD_LOV_DEVICENAME);
 }
 
-#ifdef __KERNEL__
 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
 MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver");
 MODULE_LICENSE("GPL");
diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c
index a719aac497891d41dfa8e771b1969690b2031c8b..db9ae6a01274893ea68a51bd4cae0ca709992f19 100644
--- a/lustre/lov/lov_pack.c
+++ b/lustre/lov/lov_pack.c
@@ -33,23 +33,49 @@
 #include <linux/obd_lov.h>
 #include <linux/obd_class.h>
 #include <linux/obd_support.h>
+#include <linux/lustre_user.h>
 
 #include "lov_internal.h"
 
-void lov_dump_lmm(int level, struct lov_mds_md *lmm)
+void lov_dump_lmm_v0(int level, struct lov_mds_md_v0 *lmm)
 {
-        struct lov_object_id *loi;
-        int idx;
+        int i, num_ost, stripe, idx;
 
-        CDEBUG(level, "objid "LPX64", magic %#08x, ost_count %u\n",
-               lmm->lmm_object_id, lmm->lmm_magic, lmm->lmm_ost_count);
+        num_ost = le32_to_cpu(lmm->lmm_ost_count);
+        idx = le32_to_cpu(lmm->lmm_stripe_offset);
+        CDEBUG(level, "objid "LPX64", magic 0x%08X, ost_count %u\n",
+               le64_to_cpu(lmm->lmm_object_id), le32_to_cpu(lmm->lmm_magic),
+               num_ost);
         CDEBUG(level,"stripe_size %u, stripe_count %u, stripe_offset %u\n",
-               lmm->lmm_stripe_size, lmm->lmm_stripe_count,
-               lmm->lmm_stripe_offset);
-        for (idx = 0, loi = lmm->lmm_objects; idx < lmm->lmm_ost_count;
-             idx++, loi++)
-                CDEBUG(level, "ost idx %u subobj "LPX64"\n", idx,
-                       loi->l_object_id);
+               le32_to_cpu(lmm->lmm_stripe_size),
+               le32_to_cpu(lmm->lmm_stripe_count), idx);
+        for (i = stripe = 0; i < le32_to_cpu(lmm->lmm_ost_count); i++, idx++) {
+                idx %= num_ost;
+                if (lmm->lmm_objects[idx].l_object_id == 0)
+                        continue;
+                CDEBUG(level, "stripe %u idx %u subobj "LPX64"\n", stripe, idx,
+                       le64_to_cpu(lmm->lmm_objects[idx].l_object_id));
+                stripe++;
+        }
+}
+
+void lov_dump_lmm_v1(int level, struct lov_mds_md_v1 *lmm)
+{
+        struct lov_ost_data_v1 *lod;
+        int i;
+
+        CDEBUG(level, "objid "LPX64", magic 0x%08X, pattern %#X\n",
+               le64_to_cpu(lmm->lmm_object_id), le32_to_cpu(lmm->lmm_magic),
+               le32_to_cpu(lmm->lmm_pattern));
+        CDEBUG(level,"stripe_size %u, stripe_count %u\n",
+               le32_to_cpu(lmm->lmm_stripe_size),
+               le32_to_cpu(lmm->lmm_stripe_count));
+        for (i = 0, lod = lmm->lmm_objects;
+             i < le32_to_cpu(lmm->lmm_stripe_count); i++, lod++)
+                CDEBUG(level, "stripe %u idx %u subobj "LPX64"/"LPX64"\n",
+                       i, le32_to_cpu(lod->l_ost_idx),
+                       le64_to_cpu(lod->l_object_gr),
+                       le64_to_cpu(lod->l_object_id));
 }
 
 #define LMM_ASSERT(test)                                                \
@@ -66,44 +92,36 @@ do {                                                                    \
  *     LOVs properly.  For now lov_mds_md_size() just assumes one obd_id
  *     per stripe.
  */
-int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp,
+int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
                struct lov_stripe_md *lsm)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct lov_obd *lov = &obd->u.lov;
         struct lov_oinfo *loi;
         struct lov_mds_md *lmm;
-        int ost_count = lov->desc.ld_tgt_count;
-        int stripe_count = ost_count;
+        int stripe_count = lov->desc.ld_tgt_count;
         int lmm_size;
         int i;
         ENTRY;
 
         if (lsm) {
-                int i, max = 0;
                 if (lsm->lsm_magic != LOV_MAGIC) {
-                        CERROR("bad mem LOV MAGIC: %#010x != %#010x\n",
+                        CERROR("bad mem LOV MAGIC: 0x%08X != 0x%08X\n",
                                lsm->lsm_magic, LOV_MAGIC);
                         RETURN(-EINVAL);
                 }
                 stripe_count = lsm->lsm_stripe_count;
-
-                for (i = 0,loi = lsm->lsm_oinfo; i < stripe_count; i++,loi++) {
-                        if (loi->loi_ost_idx > max)
-                                max = loi->loi_ost_idx;
-                }
-                ost_count = max + 1;
         }
 
         /* XXX LOV STACKING call into osc for sizes */
-        lmm_size = lov_mds_md_size(ost_count);
+        lmm_size = lov_mds_md_size(stripe_count);
 
         if (!lmmp)
                 RETURN(lmm_size);
 
         if (*lmmp && !lsm) {
-                ost_count = le32_to_cpu ((*lmmp)->lmm_ost_count);
-                OBD_FREE(*lmmp, lov_mds_md_size(ost_count));
+                stripe_count = le32_to_cpu((*lmmp)->lmm_stripe_count);
+                OBD_FREE(*lmmp, lov_mds_md_size(stripe_count));
                 *lmmp = NULL;
                 RETURN(0);
         }
@@ -115,24 +133,24 @@ int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp,
         }
 
         lmm = *lmmp;
-        lmm->lmm_magic = cpu_to_le32 (LOV_MAGIC);
-        lmm->lmm_ost_count = cpu_to_le16 (ost_count);
+        lmm->lmm_magic = cpu_to_le32(LOV_MAGIC); /* only write new format */
 
         if (!lsm)
                 RETURN(lmm_size);
 
-        lmm->lmm_object_id = cpu_to_le64 (lsm->lsm_object_id);
-        lmm->lmm_stripe_count = cpu_to_le16 (stripe_count);
-        lmm->lmm_stripe_size = cpu_to_le32 (lsm->lsm_stripe_size);
-        lmm->lmm_stripe_offset = cpu_to_le32 (lsm->lsm_stripe_offset);
+        lmm->lmm_object_id = cpu_to_le64(lsm->lsm_object_id);
+        lmm->lmm_object_gr = cpu_to_le64(lsm->lsm_object_gr);
+        lmm->lmm_stripe_size = cpu_to_le32(lsm->lsm_stripe_size);
+        lmm->lmm_stripe_count = cpu_to_le32(stripe_count);
+        lmm->lmm_pattern = cpu_to_le32(lsm->lsm_pattern);
 
-        /* Only fill in the object ids which we are actually using.
-         * Assumes lmm_objects is otherwise zero-filled. */
         for (i = 0, loi = lsm->lsm_oinfo; i < stripe_count; i++, loi++) {
-                /* XXX call down to osc_packmd() to do the packing */
-                LASSERT (loi->loi_id);
-                lmm->lmm_objects[loi->loi_ost_idx].l_object_id =
-                        cpu_to_le64 (loi->loi_id);
+                /* XXX LOV STACKING call down to osc_packmd() to do packing */
+                LASSERT(loi->loi_id);
+                lmm->lmm_objects[i].l_object_id = cpu_to_le64(loi->loi_id);
+                lmm->lmm_objects[i].l_object_gr = cpu_to_le64(loi->loi_gr);
+                lmm->lmm_objects[i].l_ost_gen = cpu_to_le32(loi->loi_ost_gen);
+                lmm->lmm_objects[i].l_ost_idx = cpu_to_le32(loi->loi_ost_idx);
         }
 
         RETURN(lmm_size);
@@ -148,8 +166,8 @@ int lov_get_stripecnt(struct lov_obd *lov, int stripe_count)
         return stripe_count;
 }
 
-static int lov_verify_lmm(struct lov_mds_md *lmm, int lmm_bytes,
-                          int *ost_count, int *stripe_count, int *ost_offset)
+static int lov_verify_lmm_v0(struct lov_mds_md_v0 *lmm, int lmm_bytes,
+                             int *stripe_count)
 {
         if (lmm_bytes < sizeof(*lmm)) {
                 CERROR("lov_mds_md too small: %d, need at least %d\n",
@@ -157,55 +175,114 @@ static int lov_verify_lmm(struct lov_mds_md *lmm, int lmm_bytes,
                 return -EINVAL;
         }
 
-        if (le32_to_cpu(lmm->lmm_magic) != LOV_MAGIC) {
-                CERROR("bad disk LOV MAGIC: %#08x != %#08x\n",
-                       le32_to_cpu(lmm->lmm_magic), LOV_MAGIC);
-                lov_dump_lmm(D_WARNING, lmm);
+        *stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
+
+        if (*stripe_count == 0 ||
+            *stripe_count > le32_to_cpu(lmm->lmm_ost_count)) {
+                CERROR("bad stripe count %d\n", *stripe_count);
+                lov_dump_lmm_v0(D_WARNING, lmm);
                 return -EINVAL;
         }
 
-        *ost_count = le16_to_cpu(lmm->lmm_ost_count);
-        *stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
-        *ost_offset = le32_to_cpu(lmm->lmm_stripe_offset);
+        if (lmm_bytes < lov_mds_md_v0_size(*stripe_count)) {
+                CERROR("LOV EA too small: %d, need %d\n",
+                       lmm_bytes, lov_mds_md_size(*stripe_count));
+                lov_dump_lmm_v0(D_WARNING, lmm);
+                return -EINVAL;
+        }
 
-        if (*ost_count == 0 || *stripe_count == 0) {
-                CERROR("zero OST count %d or stripe count %d\n",
-                       *ost_count, *stripe_count);
-                lov_dump_lmm(D_WARNING, lmm);
+        if (lmm->lmm_object_id == 0) {
+                CERROR("zero object id\n");
+                lov_dump_lmm_v0(D_WARNING, lmm);
+                return -EINVAL;
+        }
+
+        if (le32_to_cpu(lmm->lmm_stripe_offset) >
+            le32_to_cpu(lmm->lmm_ost_count)) {
+                CERROR("stripe offset %d more than number of OSTs %d\n",
+                       le32_to_cpu(lmm->lmm_stripe_offset),
+                       le32_to_cpu(lmm->lmm_ost_count));
+                lov_dump_lmm_v0(D_WARNING, lmm);
                 return -EINVAL;
         }
 
-        if (lmm_bytes < lov_mds_md_size(*ost_count)) {
-                CERROR("lov_mds_md too small: %d, need %d\n",
-                       lmm_bytes, lov_mds_md_size(*ost_count));
-                lov_dump_lmm(D_WARNING, lmm);
+        if (lmm->lmm_stripe_size == 0) {
+                CERROR("zero stripe size\n");
+                lov_dump_lmm_v0(D_WARNING, lmm);
                 return -EINVAL;
         }
 
-        if (*ost_offset > *ost_count) {
-                CERROR("starting OST offset %d > number of OSTs %d\n",
-                       *ost_offset, *ost_count);
-                lov_dump_lmm(D_WARNING, lmm);
+        return 0;
+}
+
+static int lov_verify_lmm_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes,
+                             int *stripe_count)
+{
+        if (lmm_bytes < sizeof(*lmm)) {
+                CERROR("lov_mds_md too small: %d, need at least %d\n",
+                       lmm_bytes, (int)sizeof(*lmm));
                 return -EINVAL;
         }
 
-        if (*stripe_count > *ost_count) {
-                CERROR("stripe count %d > number of OSTs %d\n",
-                       *stripe_count, *ost_count);
-                lov_dump_lmm(D_WARNING, lmm);
+        if (lmm->lmm_magic != le32_to_cpu(LOV_MAGIC_V1)) {
+                CERROR("bad disk LOV MAGIC: 0x%08X\n",
+                       le32_to_cpu(*(__u32 *)lmm));
+                return -EINVAL;
+        }
+
+        *stripe_count = le32_to_cpu(lmm->lmm_stripe_count);
+
+        if (*stripe_count == 0) {
+                CERROR("bad stripe count %d\n", *stripe_count);
+                lov_dump_lmm_v1(D_WARNING, lmm);
+                return -EINVAL;
+        }
+
+        if (lmm_bytes < lov_mds_md_size(*stripe_count)) {
+                CERROR("LOV EA too small: %d, need %d\n",
+                       lmm_bytes, lov_mds_md_size(*stripe_count));
+                lov_dump_lmm_v1(D_WARNING, lmm);
                 return -EINVAL;
         }
 
         if (lmm->lmm_object_id == 0) {
                 CERROR("zero object id\n");
-                lov_dump_lmm(D_WARNING, lmm);
+                lov_dump_lmm_v1(D_WARNING, lmm);
+                return -EINVAL;
+        }
+
+        if (lmm->lmm_pattern != cpu_to_le32(LOV_PATTERN_RAID0)) {
+                CERROR("bad striping pattern\n");
+                lov_dump_lmm_v1(D_WARNING, lmm);
+                return -EINVAL;
+        }
+
+        if (lmm->lmm_stripe_size == 0 ||
+            (__u64)le32_to_cpu(lmm->lmm_stripe_size) * *stripe_count > ~0UL) {
+                CERROR("bad stripe size %u\n",
+                       le32_to_cpu(lmm->lmm_stripe_size));
+                lov_dump_lmm_v1(D_WARNING, lmm);
                 return -EINVAL;
         }
 
         return 0;
 }
 
-int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count)
+static int lov_verify_lmm(void *lmm, int lmm_bytes, int *stripe_count)
+{
+        switch (le32_to_cpu(*(__u32 *)lmm)) {
+        case LOV_MAGIC_V1:
+                return lov_verify_lmm_v1(lmm, lmm_bytes, stripe_count);
+        case LOV_MAGIC_V0:
+                return lov_verify_lmm_v0(lmm, lmm_bytes, stripe_count);
+        default:
+                CERROR("bad disk LOV MAGIC: 0x%08X\n",
+                       le32_to_cpu(*(__u32 *)lmm));
+                return -EINVAL;
+        }
+}
+
+int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count, int pattern)
 {
         int lsm_size = lov_stripe_md_size(stripe_count);
         struct lov_oinfo *loi;
@@ -218,11 +295,12 @@ int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count)
         (*lsmp)->lsm_magic = LOV_MAGIC;
         (*lsmp)->lsm_stripe_count = stripe_count;
         (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES * stripe_count;
+        (*lsmp)->lsm_pattern = pattern;
+        (*lsmp)->lsm_oinfo[0].loi_ost_idx = ~0;
+
+        for (i = 0, loi = (*lsmp)->lsm_oinfo; i < stripe_count; i++, loi++)
+                loi_init(loi);
 
-        for (i = 0, loi = (*lsmp)->lsm_oinfo; i < stripe_count; i++, loi++){
-                loi->loi_dirty_ot = &loi->loi_dirty_ot_inline;
-                ot_init(loi->loi_dirty_ot);
-        }
         return lsm_size;
 }
 
@@ -232,33 +310,89 @@ void lov_free_memmd(struct lov_stripe_md **lsmp)
         *lsmp = NULL;
 }
 
+int lov_unpackmd_v0(struct lov_obd *lov, struct lov_stripe_md *lsm,
+                    struct lov_mds_md_v0 *lmm)
+{
+        struct lov_oinfo *loi;
+        int i, ost_offset, ost_count;
+
+        lsm->lsm_object_id = le64_to_cpu(lmm->lmm_object_id);
+        /* lsm->lsm_object_gr = 0; implicit */
+        lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size);
+        lsm->lsm_pattern = LOV_PATTERN_RAID0;
+        ost_offset = le32_to_cpu(lmm->lmm_stripe_offset);
+        ost_count = le16_to_cpu(lmm->lmm_ost_count);
+
+        for (i = 0, loi = lsm->lsm_oinfo; i < ost_count; i++, ost_offset++) {
+                ost_offset %= ost_count;
+
+                if (!lmm->lmm_objects[ost_offset].l_object_id)
+                        continue;
+
+                loi->loi_id =
+                        le64_to_cpu(lmm->lmm_objects[ost_offset].l_object_id);
+                /* loi->loi_gr = 0; implicit */
+                loi->loi_ost_idx = ost_offset;
+                /* loi->loi_ost_gen = 0; implicit */
+                loi++;
+        }
+
+        if (loi - lsm->lsm_oinfo != lsm->lsm_stripe_count) {
+                CERROR("missing objects in lmm struct\n");
+                lov_dump_lmm_v0(D_WARNING, lmm);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+int lov_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm,
+                    struct lov_mds_md_v1 *lmm)
+{
+        struct lov_oinfo *loi;
+        int i;
+
+        lsm->lsm_object_id = le64_to_cpu(lmm->lmm_object_id);
+        lsm->lsm_object_gr = le64_to_cpu(lmm->lmm_object_gr);
+        lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size);
+        lsm->lsm_pattern = le32_to_cpu(lmm->lmm_pattern);
+
+        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++) {
+                /* XXX LOV STACKING call down to osc_unpackmd() */
+                loi->loi_id = le64_to_cpu(lmm->lmm_objects[i].l_object_id);
+                loi->loi_gr = le64_to_cpu(lmm->lmm_objects[i].l_object_gr);
+                loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx);
+                loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen);
+                if (loi->loi_ost_idx > lov->desc.ld_tgt_count) {
+                        CERROR("OST index %d more than OST count %d\n",
+                               loi->loi_ost_idx, lov->desc.ld_tgt_count);
+                        lov_dump_lmm_v1(D_WARNING, lmm);
+                        return -EINVAL;
+                }
+                loi++;
+        }
+
+        return 0;
+}
+
 /* Unpack LOV object metadata from disk storage.  It is packed in LE byte
  * order and is opaque to the networking layer.
  */
-int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
+int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
                  struct lov_mds_md *lmm, int lmm_bytes)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct lov_obd *lov = &obd->u.lov;
-        struct lov_stripe_md *lsm;
-        struct lov_oinfo *loi;
-        int ost_count;
-        int ost_offset;
-        int stripe_count;
-        int lsm_size;
-        int i;
+        int rc = 0, stripe_count, lsm_size;
         ENTRY;
 
         /* If passed an MDS struct use values from there, otherwise defaults */
         if (lmm) {
-                i = lov_verify_lmm(lmm, lmm_bytes, &ost_count, &stripe_count,
-                                   &ost_offset);
-                if (i)
-                        RETURN(i);
+                rc = lov_verify_lmm(lmm, lmm_bytes, &stripe_count);
+                if (rc)
+                        RETURN(rc);
         } else {
-                ost_count = 0;
                 stripe_count = lov_get_stripecnt(lov, 0);
-                ost_offset = 0;
         }
 
         /* If we aren't passed an lsmp struct, we just want the size */
@@ -272,7 +406,7 @@ int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
                 RETURN(0);
         }
 
-        lsm_size = lov_alloc_memmd(lsmp, stripe_count);
+        lsm_size = lov_alloc_memmd(lsmp, stripe_count, LOV_PATTERN_RAID0);
         if (lsm_size < 0)
                 RETURN(lsm_size);
 
@@ -280,32 +414,20 @@ int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
         if (!lmm)
                 RETURN(lsm_size);
 
-        lsm = *lsmp;
-        lsm->lsm_object_id = le64_to_cpu(lmm->lmm_object_id);
-        lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size);
-        lsm->lsm_stripe_offset = ost_offset;
-
-        for (i = 0, loi = lsm->lsm_oinfo; i < ost_count; i++, ost_offset++) {
-                ost_offset %= ost_count;
-
-                if (!lmm->lmm_objects[ost_offset].l_object_id)
-                        continue;
-
-                /* XXX LOV STACKING call down to osc_unpackmd() */
-                loi->loi_id =
-                        le64_to_cpu(lmm->lmm_objects[ost_offset].l_object_id);
-                loi->loi_ost_idx = ost_offset;
-                loi++;
+        switch (le32_to_cpu(lmm->lmm_magic)) {
+        case LOV_MAGIC_V1:
+                rc = lov_unpackmd_v1(lov, *lsmp, lmm);
+                break;
+        case LOV_MAGIC_V0:
+                rc = lov_unpackmd_v0(lov, *lsmp, (void *)lmm);
+                break;
         }
 
-        if (loi - lsm->lsm_oinfo != stripe_count) {
-                CERROR("missing objects in lmm struct\n");
-                lov_dump_lmm(D_WARNING, lmm);
+        if (rc) {
                 lov_free_memmd(lsmp);
-                RETURN(-EINVAL);
+                RETURN(rc);
         }
 
-
         RETURN(lsm_size);
 }
 
@@ -316,102 +438,102 @@ int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
  * lmm_stripe_offset, and lmm_stripe_pattern.  lmm_magic must be LOV_MAGIC.
  * @lsmp is a pointer to an in-core stripe MD that needs to be filled in.
  */
-int lov_setstripe(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
-                  struct lov_mds_md *lmmu)
+int lov_setstripe(struct obd_export *exp, struct lov_stripe_md **lsmp,
+                  struct lov_user_md *lump)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         struct lov_obd *lov = &obd->u.lov;
-        struct lov_mds_md lmm;
+        struct lov_user_md lum;
         int stripe_count;
         int rc;
         ENTRY;
 
-        rc = copy_from_user(&lmm, lmmu, sizeof(lmm));
+        rc = copy_from_user(&lum, lump, sizeof(lum));
         if (rc)
                 RETURN(-EFAULT);
 
-        /* Bug 1185 FIXME: struct lov_mds_md is little-endian everywhere else */
-
-        if (lmm.lmm_magic != LOV_MAGIC) {
+        if (lum.lmm_magic != LOV_USER_MAGIC) {
                 CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x\n",
-                       lmm.lmm_magic, LOV_MAGIC);
+                       lum.lmm_magic, LOV_USER_MAGIC);
                 RETURN(-EINVAL);
         }
-#if 0   /* the stripe_count/offset is "advisory", and it gets fixed later */
-        if (lmm.lmm_stripe_count > lov->desc.ld_tgt_count &&
-            lmm.lmm_stripe_count != 0xffffffff) {
-                CERROR("stripe count %u more than OST count %d\n",
-                       lmm.lmm_stripe_count, lov->desc.ld_tgt_count);
-                RETURN(-EINVAL);
+
+        if (lum.lmm_pattern == 0) {
+                lum.lmm_pattern = lov->desc.ld_pattern ?
+                        lov->desc.ld_pattern : LOV_PATTERN_RAID0;
         }
-        if (lmm.lmm_stripe_offset >= lov->desc.ld_tgt_count &&
-            lmm.lmm_stripe_offset != 0xffffffff) {
-                CERROR("stripe offset %u more than max OST index %d\n",
-                       lmm.lmm_stripe_offset, lov->desc.ld_tgt_count);
+
+        if (lum.lmm_pattern != LOV_PATTERN_RAID0) {
+                CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n",
+                       lum.lmm_pattern);
                 RETURN(-EINVAL);
         }
-#endif
-        if (lmm.lmm_stripe_size & (PAGE_SIZE - 1)) {
+
+        if (lum.lmm_stripe_size & (PAGE_SIZE - 1)) {
                 CDEBUG(D_IOCTL, "stripe size %u not multiple of %lu\n",
-                       lmm.lmm_stripe_size, PAGE_SIZE);
+                       lum.lmm_stripe_size, PAGE_SIZE);
                 RETURN(-EINVAL);
         }
-        stripe_count = lov_get_stripecnt(lov, lmm.lmm_stripe_count);
+        stripe_count = lov_get_stripecnt(lov, lum.lmm_stripe_count);
 
-        if ((__u64)lmm.lmm_stripe_size * stripe_count > ~0UL) {
+        if ((__u64)lum.lmm_stripe_size * stripe_count > ~0UL) {
                 CDEBUG(D_IOCTL, "stripe width %ux%u > %lu on 32-bit system\n",
-                       lmm.lmm_stripe_size, (int)lmm.lmm_stripe_count, ~0UL);
+                       lum.lmm_stripe_size, (int)lum.lmm_stripe_count, ~0UL);
                 RETURN(-EINVAL);
         }
 
-        rc = lov_alloc_memmd(lsmp, stripe_count);
+        rc = lov_alloc_memmd(lsmp, stripe_count, lum.lmm_pattern);
 
         if (rc < 0)
                 RETURN(rc);
 
-        (*lsmp)->lsm_stripe_offset = lmm.lmm_stripe_offset;
-        (*lsmp)->lsm_stripe_size = lmm.lmm_stripe_size;
+        (*lsmp)->lsm_oinfo[0].loi_ost_idx = lum.lmm_stripe_offset;
+        (*lsmp)->lsm_stripe_size = lum.lmm_stripe_size;
 
         RETURN(0);
 }
 
 /* Retrieve object striping information.
  *
- * @lmmu is a pointer to an in-core struct with lmm_ost_count indicating
+ * @lump is a pointer to an in-core struct with lmm_ost_count indicating
  * the maximum number of OST indices which will fit in the user buffer.
- * lmm_magic must be LOV_MAGIC.
+ * lmm_magic must be LOV_USER_MAGIC.
  */
-int lov_getstripe(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                  struct lov_mds_md *lmmu)
+int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
+                  struct lov_user_md *lump)
 {
-        struct lov_mds_md lmm, *lmmk = NULL;
+        struct lov_user_md lum;
+        struct lov_mds_md *lmmk = NULL;
         int rc, lmm_size;
         ENTRY;
 
         if (!lsm)
                 RETURN(-ENODATA);
 
-        rc = copy_from_user(&lmm, lmmu, sizeof(lmm));
+        rc = copy_from_user(&lum, lump, sizeof(lum));
         if (rc)
                 RETURN(-EFAULT);
 
-        if (lmm.lmm_magic != LOV_MAGIC)
+        if (lum.lmm_magic != LOV_USER_MAGIC)
                 RETURN(-EINVAL);
 
-        rc = lov_packmd(conn, &lmmk, lsm);
+        rc = lov_packmd(exp, &lmmk, lsm);
         if (rc < 0)
                 RETURN(rc);
-        /* Bug 1185 FIXME: convert lmmk to big-endian before copy to userspace */
         lmm_size = rc;
         rc = 0;
 
+        /* FIXME: Bug 1185 - copy fields properly when structs change */
+        LASSERT(sizeof(lum) == sizeof(*lmmk));
+        LASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lmmk->lmm_objects[0]));
+
         /* User wasn't expecting this many OST entries */
-        if (lmm.lmm_ost_count < lmmk->lmm_ost_count)
+        if (lum.lmm_stripe_count < lmmk->lmm_stripe_count)
                 rc = -EOVERFLOW;
-        else if (copy_to_user(lmmu, lmmk, lmm_size))
+        else if (copy_to_user(lump, lmmk, lmm_size))
                 rc = -EFAULT;
 
-        obd_free_diskmd (conn, &lmmk);
+        obd_free_diskmd(exp, &lmmk);
 
         RETURN(rc);
 }
diff --git a/lustre/lov/lproc_lov.c b/lustre/lov/lproc_lov.c
index 7b7a00c08b44aa316faf240f8bbfe1a7766a2ca2..37d1159d251ff818dbdac6d835a75cd6d9c50cd0 100644
--- a/lustre/lov/lproc_lov.c
+++ b/lustre/lov/lproc_lov.c
@@ -107,8 +107,8 @@ static int lov_rd_activeobd(char *page, char **start, off_t off, int count,
         return snprintf(page, count, "%u\n", desc->ld_active_tgt_count);
 }
 
-static int lov_rd_mdc(char *page, char **start, off_t off, int count, int *eof,
-                      void *data)
+static int lov_rd_desc_uuid(char *page, char **start, off_t off, int count,
+                            int *eof, void *data)
 {
         struct obd_device *dev = (struct obd_device*) data;
         struct lov_obd *lov;
@@ -116,7 +116,7 @@ static int lov_rd_mdc(char *page, char **start, off_t off, int count, int *eof,
         LASSERT(dev != NULL);
         lov = &dev->u.lov;
         *eof = 1;
-        return snprintf(page, count, "%s\n", lov->mdcobd->obd_uuid.uuid);
+        return snprintf(page, count, "%s\n", lov->desc.ld_uuid.uuid);
 }
 
 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
@@ -187,7 +187,7 @@ struct lprocfs_vars lprocfs_obd_vars[] = {
         { "blocksize",    lprocfs_rd_blksize,     0, 0 },
         { "kbytestotal",  lprocfs_rd_kbytestotal, 0, 0 },
         { "kbytesfree",   lprocfs_rd_kbytesfree,  0, 0 },
-        { "target_mdc",   lov_rd_mdc,             0, 0 },
+        { "desc_uuid",    lov_rd_desc_uuid,       0, 0 },
         { 0 }
 };
 
diff --git a/lustre/lvfs/.cvsignore b/lustre/lvfs/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..49c6100f1c2fb7df19792a3171bd71a1ac6ec10a
--- /dev/null
+++ b/lustre/lvfs/.cvsignore
@@ -0,0 +1,9 @@
+.Xrefs
+config.log
+config.status
+configure
+Makefile
+Makefile.in
+.deps
+TAGS
+.*.cmd
diff --git a/lustre/lvfs/Makefile.am b/lustre/lvfs/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..30063061ada972a0ef86462bfee14d0978916d00
--- /dev/null
+++ b/lustre/lvfs/Makefile.am
@@ -0,0 +1,32 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+DEFS= 
+MODULE = lvfs
+
+
+if EXTN
+FSMOD = fsfilt_extN
+else
+FSMOD = fsfilt_ext3
+endif
+
+
+if LIBLUSTRE
+lib_LIBRARIES = liblvfs.a
+liblvfs_a_SOURCES = lvfs_userfs.c
+
+#if MYSQL
+#liblvfs_a_SOURCES += lvfs_user_mysql.c
+#endif
+
+else
+modulefs_DATA = lvfs.o $(FSMOD).o fsfilt_reiserfs.o
+
+EXTRA_PROGRAMS = lvfs $(FSMOD) fsfilt_reiserfs
+lvfs_SOURCES = lvfs_common.c lvfs_linux.c fsfilt.c lvfs_internal.h
+endif
+
+
+include $(top_srcdir)/Rules
diff --git a/lustre/lvfs/Makefile.mk b/lustre/lvfs/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..81c177abe3331f192b300807246d53808efa47d1
--- /dev/null
+++ b/lustre/lvfs/Makefile.mk
@@ -0,0 +1,4 @@
+include $(src)/../portals/Kernelenv
+
+obj-y += lvfs.o fsfilt_ext3.o 
+lvfs-objs := fsfilt.o  lvfs_common.o  lvfs_linux.o 
diff --git a/lustre/obdclass/fsfilt.c b/lustre/lvfs/fsfilt.c
similarity index 96%
rename from lustre/obdclass/fsfilt.c
rename to lustre/lvfs/fsfilt.c
index d0abdfe61d8c2fdf7acbba123609cf501cb5d423..a9ddf8be92bcbeddd5275feb96edd136b61e5583 100644
--- a/lustre/obdclass/fsfilt.c
+++ b/lustre/lvfs/fsfilt.c
@@ -1,4 +1,6 @@
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_FILTER
 
 #include <linux/fs.h>
@@ -76,7 +78,7 @@ struct fsfilt_operations *fsfilt_get_ops(const char *type)
                 snprintf(name, sizeof(name) - 1, "fsfilt_%s", type);
                 name[sizeof(name) - 1] = '\0';
 
-                if ((rc = request_module(name))) {
+                if (!(rc = request_module(name))) {
                         fs_ops = fsfilt_search_type(type);
                         CDEBUG(D_INFO, "Loaded module '%s'\n", name);
                         if (!fs_ops)
diff --git a/lustre/obdclass/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c
similarity index 71%
rename from lustre/obdclass/fsfilt_ext3.c
rename to lustre/lvfs/fsfilt_ext3.c
index 89f97e64767b72bae6345c9a87b7cbeb5f386ece..7c21ba4ec1b0351bd54e6a06cb40a84938f9c7a1 100644
--- a/lustre/obdclass/fsfilt_ext3.c
+++ b/lustre/lvfs/fsfilt_ext3.c
@@ -36,7 +36,7 @@
 /* XXX ugh */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  #include <linux/ext3_xattr.h>
-#else 
+#else
  #include <linux/../../fs/ext3/xattr.h>
 #endif
 #include <linux/kp30.h>
@@ -56,8 +56,13 @@ struct fsfilt_cb_data {
         void *cb_data;                  /* MDS/OST completion function data */
 };
 
-#define EXT3_XATTR_INDEX_LUSTRE         5
-#define XATTR_LUSTRE_MDS_OBJID          "system.lustre_mds_objid"
+#ifndef EXT3_XATTR_INDEX_TRUSTED        /* temporary until we hit l28 kernel */
+#define EXT3_XATTR_INDEX_TRUSTED        4
+#endif
+#define XATTR_LUSTRE_MDS_LOV_EA         "lov"
+
+#define EXT3_XATTR_INDEX_LUSTRE         5                         /* old */
+#define XATTR_LUSTRE_MDS_OBJID          "system.lustre_mds_objid" /* old */
 
 /*
  * We don't currently need any additional blocks for rmdir and
@@ -71,7 +76,10 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private)
         int nblocks = EXT3_DATA_TRANS_BLOCKS;
         void *handle;
 
-        LASSERT(current->journal_info == NULL);
+        if (current->journal_info) {
+                CDEBUG(D_INODE, "increasing refcount on %p\n", current->journal_info);
+                goto journal_start;
+        }
 
         switch(op) {
         case FSFILT_OP_CREATE_LOG:
@@ -116,6 +124,8 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private)
         }
 
         LASSERT(current->journal_info == desc_private);
+
+ journal_start:
         lock_kernel();
         handle = journal_start(EXT3_JOURNAL(inode), nblocks);
         unlock_kernel();
@@ -261,10 +271,58 @@ static int fsfilt_ext3_commit(struct inode *inode, void *h, int force_sync)
         rc = journal_stop(handle);
         unlock_kernel();
 
-        LASSERT(current->journal_info == NULL);
+        // LASSERT(current->journal_info == NULL);
         return rc;
 }
 
+static int fsfilt_ext3_commit_async(struct inode *inode, void *h,
+                                        void **wait_handle)
+{
+        transaction_t *transaction;
+        unsigned long tid, rtid;
+        handle_t *handle = h;
+        journal_t *journal;
+        int rc;
+
+        LASSERT(current->journal_info == handle);
+
+        lock_kernel();
+        transaction = handle->h_transaction;
+        journal = transaction->t_journal;
+        tid = transaction->t_tid;
+        /* we don't want to be blocked */
+        handle->h_sync = 0;
+        rc = journal_stop(handle);
+        if (rc) {
+                CERROR("error while stopping transaction: %d\n", rc);
+                unlock_kernel();
+                return rc;
+        }
+
+        rtid = log_start_commit(journal, transaction);
+        if (rtid != tid)
+                CERROR("strange race: %lu != %lu\n",
+                       (unsigned long) tid, (unsigned long) rtid);
+        unlock_kernel();
+
+        *wait_handle = (void *) tid;
+        CDEBUG(D_INODE, "commit async: %lu\n", (unsigned long) tid);
+        return 0;
+}
+
+static int fsfilt_ext3_commit_wait(struct inode *inode, void *h)
+{
+        tid_t tid = (tid_t)(long)h;
+
+        CDEBUG(D_INODE, "commit wait: %lu\n", (unsigned long) tid);
+	if (is_journal_aborted(EXT3_JOURNAL(inode)))
+                return -EIO;
+
+        log_wait_commit(EXT3_JOURNAL(inode), tid);
+
+        return 0;
+}
+
 static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle,
                                struct iattr *iattr, int do_trunc)
 {
@@ -311,44 +369,86 @@ static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle,
         return rc;
 }
 
+static int fsfilt_ext3_iocontrol(struct inode * inode, struct file *file,
+                                 unsigned int cmd, unsigned long arg)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (inode->i_fop->ioctl)
+                rc = inode->i_fop->ioctl(inode, file, cmd, arg);
+        else
+                RETURN(-ENOTTY);
+
+        RETURN(rc);
+}
+
+#undef INLINE_EA
+#undef OLD_EA
 static int fsfilt_ext3_set_md(struct inode *inode, void *handle,
                               void *lmm, int lmm_size)
 {
-        int rc;
+        int rc, old_ea = 0;
 
+#ifdef INLINE_EA  /* can go away before 1.0 - just for testing bug 2097 now */
         /* Nasty hack city - store stripe MD data in the block pointers if
          * it will fit, because putting it in an EA currently kills the MDS
          * performance.  We'll fix this with "fast EAs" in the future.
          */
         if (inode->i_blocks == 0 && lmm_size <= sizeof(EXT3_I(inode)->i_data) -
                                             sizeof(EXT3_I(inode)->i_data[0])) {
-                /* XXX old_size is debugging only */
-                int old_size = EXT3_I(inode)->i_data[0];
+                unsigned old_size = EXT3_I(inode)->i_data[0];
                 if (old_size != 0) {
                         LASSERT(old_size < sizeof(EXT3_I(inode)->i_data));
-                        CERROR("setting EA on %lu again... interesting\n",
-                               inode->i_ino);
+                        CERROR("setting EA on %lu/%u again... interesting\n",
+                               inode->i_ino, inode->i_generation);
                 }
 
                 EXT3_I(inode)->i_data[0] = cpu_to_le32(lmm_size);
                 memcpy(&EXT3_I(inode)->i_data[1], lmm, lmm_size);
                 mark_inode_dirty(inode);
                 return 0;
-        } else {
-                down(&inode->i_sem);
-                lock_kernel();
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-                rc = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_LUSTRE,
-                                    XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0);
-#else
-                rc = ext3_xattr_set_handle(handle, inode, 
-                                           EXT3_XATTR_INDEX_LUSTRE,
-                                           XATTR_LUSTRE_MDS_OBJID, lmm, 
-                                           lmm_size, 0);
+        }
 #endif
-                unlock_kernel();
-                up(&inode->i_sem);
+#ifdef OLD_EA
+        /* keep this when we get rid of OLD_EA (too noisy during conversion) */
+        if (EXT3_I(inode)->i_file_acl /* || large inode EA flag */) {
+                CWARN("setting EA on %lu/%u again... interesting\n",
+                       inode->i_ino, inode->i_generation);
+                old_ea = 1;
+        }
+
+        lock_kernel();
+        /* this can go away before 1.0.  For bug 2097 testing only. */
+        rc = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_LUSTRE,
+                                   XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0);
+#else
+        lock_kernel();
+        rc = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_TRUSTED,
+                                   XATTR_LUSTRE_MDS_LOV_EA, lmm, lmm_size, 0);
+
+        /* This tries to delete the old-format LOV EA, but only as long as we
+         * have successfully saved the new-format LOV EA (we can always try
+         * the conversion again the next time the file is accessed).  It is
+         * possible (although unlikely) that the new-format LOV EA couldn't be
+         * saved because it ran out of space but we would need a file striped
+         * over least 123 OSTs before the two EAs filled a 4kB block.
+         *
+         * This can be removed when all filesystems have converted to the
+         * new EA format, but otherwise adds little if any overhead.  If we
+         * wanted backward compatibility for existing files, we could keep
+         * the old EA around for a while but we'd have to clean it up later. */
+        if (rc >= 0 && old_ea) {
+                int err = ext3_xattr_set_handle(handle, inode,
+                                                EXT3_XATTR_INDEX_LUSTRE,
+                                                XATTR_LUSTRE_MDS_OBJID,
+                                                NULL, 0, 0);
+                if (err)
+                        CERROR("error deleting old LOV EA on %lu/%u: rc %d\n",
+                               inode->i_ino, inode->i_generation, err);
         }
+#endif
+        unlock_kernel();
 
         if (rc)
                 CERROR("error adding MD data to inode %lu: rc = %d\n",
@@ -356,35 +456,78 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle,
         return rc;
 }
 
+/* Must be called with i_sem held */
 static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int lmm_size)
 {
         int rc;
 
+        LASSERT(down_trylock(&inode->i_sem) != 0);
+        lock_kernel();
+        /* Keep support for reading "inline EAs" until we convert
+         * users over to new format entirely.  See bug 841/2097. */
         if (inode->i_blocks == 0 && EXT3_I(inode)->i_data[0]) {
-                int size = le32_to_cpu(EXT3_I(inode)->i_data[0]);
+                unsigned size = le32_to_cpu(EXT3_I(inode)->i_data[0]);
+                void *handle;
+
                 LASSERT(size < sizeof(EXT3_I(inode)->i_data));
                 if (lmm) {
-                        if (size > lmm_size)
+                        if (size > lmm_size) {
+                                CERROR("inline EA on %lu/%u bad size %u > %u\n",
+                                       inode->i_ino, inode->i_generation,
+                                       size, lmm_size);
                                 return -ERANGE;
+                        }
                         memcpy(lmm, &EXT3_I(inode)->i_data[1], size);
                 }
+
+#ifndef INLINE_EA
+                /* migrate LOV EA data to external block - keep same format */
+                CWARN("DEBUG: migrate inline EA for inode %lu/%u to block\n",
+                      inode->i_ino, inode->i_generation);
+
+                handle = journal_start(EXT3_JOURNAL(inode),
+                                       EXT3_XATTR_TRANS_BLOCKS);
+                if (!IS_ERR(handle)) {
+                        int err;
+                        rc = fsfilt_ext3_set_md(inode, handle,
+                                                &EXT3_I(inode)->i_data[1],size);
+                        if (rc == 0) {
+                                memset(EXT3_I(inode)->i_data, 0,
+                                       sizeof(EXT3_I(inode)->i_data));
+                                mark_inode_dirty(inode);
+                        }
+                        err = journal_stop(handle);
+                        if (err && rc == 0)
+                                rc = err;
+                } else {
+                        rc = PTR_ERR(handle);
+                }
+#endif
+                unlock_kernel();
                 return size;
         }
 
-        down(&inode->i_sem);
-        lock_kernel();
-        rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_LUSTRE,
-                            XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size);
+        rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED,
+                            XATTR_LUSTRE_MDS_LOV_EA, lmm, lmm_size);
+        /* try old EA type if new one failed - MDS will convert it for us */
+        if (rc == -ENODATA) {
+                CDEBUG(D_INFO,"failed new LOV EA %d/%s from inode %lu: rc %d\n",
+                       EXT3_XATTR_INDEX_TRUSTED, XATTR_LUSTRE_MDS_LOV_EA,
+                       inode->i_ino, rc);
+
+                rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_LUSTRE,
+                                    XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size);
+        }
         unlock_kernel();
-        up(&inode->i_sem);
 
         /* This gives us the MD size */
         if (lmm == NULL)
                 return (rc == -ENODATA) ? 0 : rc;
 
         if (rc < 0) {
-                CDEBUG(D_INFO, "error getting EA %s from inode %lu: "
-                       "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc);
+                CDEBUG(D_INFO, "error getting EA %d/%s from inode %lu: rc %d\n",
+                       EXT3_XATTR_INDEX_LUSTRE, XATTR_LUSTRE_MDS_OBJID,
+                       inode->i_ino, rc);
                 memset(lmm, 0, lmm_size);
                 return (rc == -ENODATA) ? 0 : rc;
         }
@@ -458,9 +601,9 @@ static void fsfilt_ext3_cb_func(struct journal_callback *jcb, int error)
         atomic_dec(&fcb_cache_count);
 }
 
-static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd,
-                                     void *handle, fsfilt_cb_t cb_func,
-                                     void *cb_data)
+static int fsfilt_ext3_add_journal_cb(struct obd_device *obd, __u64 last_rcvd,
+                                      void *handle, fsfilt_cb_t cb_func,
+                                      void *cb_data)
 {
         struct fsfilt_cb_data *fcb;
 
@@ -483,16 +626,6 @@ static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd,
         return 0;
 }
 
-static int fsfilt_ext3_journal_data(struct file *filp)
-{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        /* bug 1576: enable data journaling on 2.5 when appropriate */
-        struct inode *inode = filp->f_dentry->d_inode;
-        EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
-#endif
-        return 0;
-}
-
 /*
  * We need to hack the return value for the free inode counts because
  * the current EA code requires one filesystem block per inode with EAs,
@@ -519,8 +652,16 @@ static int fsfilt_ext3_sync(struct super_block *sb)
         return ext3_force_commit(sb);
 }
 
+extern int ext3_map_inode_page(struct inode *inode, struct page *page,
+                               unsigned long *blocks, int *created, int create);
+int fsfilt_ext3_map_inode_page(struct inode *inode, struct page *page,
+                               unsigned long *blocks, int *created, int create)
+{
+        return ext3_map_inode_page(inode, page, blocks, created, create);
+}
+
 extern int ext3_prep_san_write(struct inode *inode, long *blocks,
-			       int nblocks, loff_t newsize);
+                               int nblocks, loff_t newsize);
 static int fsfilt_ext3_prep_san_write(struct inode *inode, long *blocks,
                                       int nblocks, loff_t newsize)
 {
@@ -536,9 +677,13 @@ static int fsfilt_ext3_read_record(struct file * file, void *buf,
         int err;
 
         if (inode->i_size < *offs + size) {
-                CERROR("file size %llu is too short for read %u@%llu\n",
-                       inode->i_size, size, *offs);
-                return -EIO;
+                size = inode->i_size - *offs;
+                if (size < 0) {
+                        CERROR("size %llu is too short for read %u@%llu\n",
+                                        inode->i_size, size, *offs);
+                        return -EIO;
+                } else if (size == 0)
+                        return 0;
         }
 
         block = *offs >> inode->i_blkbits;
@@ -559,11 +704,11 @@ static int fsfilt_ext3_read_record(struct file * file, void *buf,
         memcpy(buf, bh->b_data + boffs, size);
         brelse(bh);
         *offs += size;
-        return size;
+        return 0;
 }
 
-static int fsfilt_ext3_write_record(struct file * file, void *buf,
-                                    int size, loff_t *offs)
+static int fsfilt_ext3_write_record(struct file *file, void *buf, int size,
+                                    loff_t *offs, int force_sync)
 {
         struct buffer_head *bh;
         unsigned long block, boffs;
@@ -575,16 +720,18 @@ static int fsfilt_ext3_write_record(struct file * file, void *buf,
 
         journal = EXT3_SB(inode->i_sb)->s_journal;
         handle = journal_start(journal, EXT3_DATA_TRANS_BLOCKS + 2);
-        if (handle == NULL) {
+        if (IS_ERR(handle)) {
                 CERROR("can't start transaction\n");
-                return -EIO;
+                return PTR_ERR(handle);
         }
 
         block = *offs >> inode->i_blkbits;
         if (*offs + size > inode->i_size) {
                 down(&inode->i_sem);
                 if (*offs + size > inode->i_size)
-                        inode->i_size = ((loff_t)block + 1) << inode->i_blkbits;
+                        inode->i_size = *offs + size;
+                if (inode->i_size > EXT3_I(inode)->i_disksize)
+                        EXT3_I(inode)->i_disksize = inode->i_size;
                 up(&inode->i_sem);
         }
 
@@ -621,33 +768,53 @@ static int fsfilt_ext3_write_record(struct file * file, void *buf,
                 CERROR("journal_dirty_metadata() returned error %d\n", err);
                 goto out;
         }
-        err = size;
+
+        if (force_sync)
+                handle->h_sync = 1; /* recovery likes this */
 out:
         if (bh)
                 brelse(bh);
         journal_stop(handle);
-        if (err > 0)
+        if (err == 0)
                 *offs += size;
         return err;
 }
 
+static int fsfilt_ext3_setup(struct super_block *sb)
+{
+#if 0
+        EXT3_SB(sb)->dx_lock = fsfilt_ext3_dx_lock;
+        EXT3_SB(sb)->dx_unlock = fsfilt_ext3_dx_unlock;
+#endif
+#ifdef S_PDIROPS
+        CWARN("Enabling PDIROPS\n");
+        set_opt(EXT3_SB(sb)->s_mount_opt, PDIROPS);
+        sb->s_flags |= S_PDIROPS;
+#endif
+        return 0;
+}
+
 static struct fsfilt_operations fsfilt_ext3_ops = {
         fs_type:                "ext3",
         fs_owner:               THIS_MODULE,
         fs_start:               fsfilt_ext3_start,
         fs_brw_start:           fsfilt_ext3_brw_start,
         fs_commit:              fsfilt_ext3_commit,
+        fs_commit_async:        fsfilt_ext3_commit_async,
+        fs_commit_wait:         fsfilt_ext3_commit_wait,
         fs_setattr:             fsfilt_ext3_setattr,
+        fs_iocontrol:           fsfilt_ext3_iocontrol,
         fs_set_md:              fsfilt_ext3_set_md,
         fs_get_md:              fsfilt_ext3_get_md,
         fs_readpage:            fsfilt_ext3_readpage,
-        fs_journal_data:        fsfilt_ext3_journal_data,
-        fs_set_last_rcvd:       fsfilt_ext3_set_last_rcvd,
+        fs_add_journal_cb:      fsfilt_ext3_add_journal_cb,
         fs_statfs:              fsfilt_ext3_statfs,
         fs_sync:                fsfilt_ext3_sync,
+        fs_map_inode_page:      fsfilt_ext3_map_inode_page,
         fs_prep_san_write:      fsfilt_ext3_prep_san_write,
         fs_write_record:        fsfilt_ext3_write_record,
         fs_read_record:         fsfilt_ext3_read_record,
+        fs_setup:               fsfilt_ext3_setup,
 };
 
 static int __init fsfilt_ext3_init(void)
@@ -686,9 +853,9 @@ static void __exit fsfilt_ext3_exit(void)
         //rc = ext3_xattr_unregister();
 }
 
+module_init(fsfilt_ext3_init);
+module_exit(fsfilt_ext3_exit);
+
 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
 MODULE_DESCRIPTION("Lustre ext3 Filesystem Helper v0.1");
 MODULE_LICENSE("GPL");
-
-module_init(fsfilt_ext3_init);
-module_exit(fsfilt_ext3_exit);
diff --git a/lustre/obdclass/fsfilt_extN.c b/lustre/lvfs/fsfilt_extN.c
similarity index 70%
rename from lustre/obdclass/fsfilt_extN.c
rename to lustre/lvfs/fsfilt_extN.c
index 8efc05b5f14f5ed366167d4fe1e2ddb36746030c..b4f3fc7068fbefd5d05b8cbb4f748fffb487089a 100644
--- a/lustre/obdclass/fsfilt_extN.c
+++ b/lustre/lvfs/fsfilt_extN.c
@@ -32,7 +32,13 @@
 #include <linux/quotaops.h>
 #include <linux/extN_fs.h>
 #include <linux/extN_jbd.h>
-#include <linux/extN_xattr.h>
+#include <linux/version.h>
+/* XXX ugh */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ #include <linux/extN_xattr.h>
+#else
+ #include <linux/../../fs/extN/xattr.h>
+#endif
 #include <linux/kp30.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/obd.h>
@@ -50,8 +56,13 @@ struct fsfilt_cb_data {
         void *cb_data;                  /* MDS/OST completion function data */
 };
 
-#define EXTN_XATTR_INDEX_LUSTRE         5
-#define XATTR_LUSTRE_MDS_OBJID          "system.lustre_mds_objid"
+#ifndef EXTN_XATTR_INDEX_TRUSTED        /* temporary until we hit l28 kernel */
+#define EXTN_XATTR_INDEX_TRUSTED        4
+#endif
+#define XATTR_LUSTRE_MDS_LOV_EA         "lov"
+
+#define EXTN_XATTR_INDEX_LUSTRE         5                         /* old */
+#define XATTR_LUSTRE_MDS_OBJID          "system.lustre_mds_objid" /* old */
 
 /*
  * We don't currently need any additional blocks for rmdir and
@@ -65,7 +76,10 @@ static void *fsfilt_extN_start(struct inode *inode, int op, void *desc_private)
         int nblocks = EXTN_DATA_TRANS_BLOCKS;
         void *handle;
 
-        LASSERT(current->journal_info == NULL);
+        if (current->journal_info) {
+                CDEBUG(D_INODE, "increasing refcount on %p\n", current->journal_info);
+                goto journal_start;
+        }
 
         switch(op) {
         case FSFILT_OP_CREATE_LOG:
@@ -110,6 +124,8 @@ static void *fsfilt_extN_start(struct inode *inode, int op, void *desc_private)
         }
 
         LASSERT(current->journal_info == desc_private);
+
+ journal_start:
         lock_kernel();
         handle = journal_start(EXTN_JOURNAL(inode), nblocks);
         unlock_kernel();
@@ -255,10 +271,58 @@ static int fsfilt_extN_commit(struct inode *inode, void *h, int force_sync)
         rc = journal_stop(handle);
         unlock_kernel();
 
-        LASSERT(current->journal_info == NULL);
+        // LASSERT(current->journal_info == NULL);
         return rc;
 }
 
+static int fsfilt_extN_commit_async(struct inode *inode, void *h,
+                                        void **wait_handle)
+{
+        transaction_t *transaction;
+        unsigned long tid, rtid;
+        handle_t *handle = h;
+        journal_t *journal;
+        int rc;
+
+        LASSERT(current->journal_info == handle);
+
+        lock_kernel();
+        transaction = handle->h_transaction;
+        journal = transaction->t_journal;
+        tid = transaction->t_tid;
+        /* we don't want to be blocked */
+        handle->h_sync = 0;
+        rc = journal_stop(handle);
+        if (rc) {
+                CERROR("error while stopping transaction: %d\n", rc);
+                unlock_kernel();
+                return rc;
+        }
+
+        rtid = log_start_commit(journal, transaction);
+        if (rtid != tid)
+                CERROR("strange race: %lu != %lu\n",
+                       (unsigned long) tid, (unsigned long) rtid);
+        unlock_kernel();
+
+        *wait_handle = (void *) tid;
+        CDEBUG(D_INODE, "commit async: %lu\n", (unsigned long) tid);
+        return 0;
+}
+
+static int fsfilt_extN_commit_wait(struct inode *inode, void *h)
+{
+        tid_t tid = (tid_t)(long)h;
+
+        CDEBUG(D_INODE, "commit wait: %lu\n", (unsigned long) tid);
+	if (is_journal_aborted(EXTN_JOURNAL(inode)))
+                return -EIO;
+
+        log_wait_commit(EXTN_JOURNAL(inode), tid);
+
+        return 0;
+}
+
 static int fsfilt_extN_setattr(struct dentry *dentry, void *handle,
                                struct iattr *iattr, int do_trunc)
 {
@@ -305,37 +369,86 @@ static int fsfilt_extN_setattr(struct dentry *dentry, void *handle,
         return rc;
 }
 
+static int fsfilt_extN_iocontrol(struct inode * inode, struct file *file,
+                                 unsigned int cmd, unsigned long arg)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (inode->i_fop->ioctl)
+                rc = inode->i_fop->ioctl(inode, file, cmd, arg);
+        else
+                RETURN(-ENOTTY);
+
+        RETURN(rc);
+}
+
+#undef INLINE_EA
+#undef OLD_EA
 static int fsfilt_extN_set_md(struct inode *inode, void *handle,
                               void *lmm, int lmm_size)
 {
-        int rc;
+        int rc, old_ea = 0;
 
+#ifdef INLINE_EA  /* can go away before 1.0 - just for testing bug 2097 now */
         /* Nasty hack city - store stripe MD data in the block pointers if
          * it will fit, because putting it in an EA currently kills the MDS
          * performance.  We'll fix this with "fast EAs" in the future.
          */
         if (inode->i_blocks == 0 && lmm_size <= sizeof(EXTN_I(inode)->i_data) -
                                             sizeof(EXTN_I(inode)->i_data[0])) {
-                /* XXX old_size is debugging only */
-                int old_size = EXTN_I(inode)->i_data[0];
+                unsigned old_size = EXTN_I(inode)->i_data[0];
                 if (old_size != 0) {
                         LASSERT(old_size < sizeof(EXTN_I(inode)->i_data));
-                        CERROR("setting EA on %lu again... interesting\n",
-                               inode->i_ino);
+                        CERROR("setting EA on %lu/%u again... interesting\n",
+                               inode->i_ino, inode->i_generation);
                 }
 
                 EXTN_I(inode)->i_data[0] = cpu_to_le32(lmm_size);
                 memcpy(&EXTN_I(inode)->i_data[1], lmm, lmm_size);
                 mark_inode_dirty(inode);
                 return 0;
-        } else {
-                down(&inode->i_sem);
-                lock_kernel();
-                rc = extN_xattr_set(handle, inode, EXTN_XATTR_INDEX_LUSTRE,
-                                    XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0);
-                unlock_kernel();
-                up(&inode->i_sem);
         }
+#endif
+#ifdef OLD_EA
+        /* keep this when we get rid of OLD_EA (too noisy during conversion) */
+        if (EXTN_I(inode)->i_file_acl /* || large inode EA flag */) {
+                CWARN("setting EA on %lu/%u again... interesting\n",
+                       inode->i_ino, inode->i_generation);
+                old_ea = 1;
+        }
+
+        lock_kernel();
+        /* this can go away before 1.0.  For bug 2097 testing only. */
+        rc = extN_xattr_set_handle(handle, inode, EXTN_XATTR_INDEX_LUSTRE,
+                                   XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0);
+#else
+        lock_kernel();
+        rc = extN_xattr_set_handle(handle, inode, EXTN_XATTR_INDEX_TRUSTED,
+                                   XATTR_LUSTRE_MDS_LOV_EA, lmm, lmm_size, 0);
+
+        /* This tries to delete the old-format LOV EA, but only as long as we
+         * have successfully saved the new-format LOV EA (we can always try
+         * the conversion again the next time the file is accessed).  It is
+         * possible (although unlikely) that the new-format LOV EA couldn't be
+         * saved because it ran out of space but we would need a file striped
+         * over least 123 OSTs before the two EAs filled a 4kB block.
+         *
+         * This can be removed when all filesystems have converted to the
+         * new EA format, but otherwise adds little if any overhead.  If we
+         * wanted backward compatibility for existing files, we could keep
+         * the old EA around for a while but we'd have to clean it up later. */
+        if (rc >= 0 && old_ea) {
+                int err = extN_xattr_set_handle(handle, inode,
+                                                EXTN_XATTR_INDEX_LUSTRE,
+                                                XATTR_LUSTRE_MDS_OBJID,
+                                                NULL, 0, 0);
+                if (err)
+                        CERROR("error deleting old LOV EA on %lu/%u: rc %d\n",
+                               inode->i_ino, inode->i_generation, err);
+        }
+#endif
+        unlock_kernel();
 
         if (rc)
                 CERROR("error adding MD data to inode %lu: rc = %d\n",
@@ -343,35 +456,78 @@ static int fsfilt_extN_set_md(struct inode *inode, void *handle,
         return rc;
 }
 
+/* Must be called with i_sem held */
 static int fsfilt_extN_get_md(struct inode *inode, void *lmm, int lmm_size)
 {
         int rc;
 
+        LASSERT(down_trylock(&inode->i_sem) != 0);
+        lock_kernel();
+        /* Keep support for reading "inline EAs" until we convert
+         * users over to new format entirely.  See bug 841/2097. */
         if (inode->i_blocks == 0 && EXTN_I(inode)->i_data[0]) {
-                int size = le32_to_cpu(EXTN_I(inode)->i_data[0]);
+                unsigned size = le32_to_cpu(EXTN_I(inode)->i_data[0]);
+                void *handle;
+
                 LASSERT(size < sizeof(EXTN_I(inode)->i_data));
                 if (lmm) {
-                        if (size > lmm_size)
+                        if (size > lmm_size) {
+                                CERROR("inline EA on %lu/%u bad size %u > %u\n",
+                                       inode->i_ino, inode->i_generation,
+                                       size, lmm_size);
                                 return -ERANGE;
+                        }
                         memcpy(lmm, &EXTN_I(inode)->i_data[1], size);
                 }
+
+#ifndef INLINE_EA
+                /* migrate LOV EA data to external block - keep same format */
+                CWARN("DEBUG: migrate inline EA for inode %lu/%u to block\n",
+                      inode->i_ino, inode->i_generation);
+
+                handle = journal_start(EXTN_JOURNAL(inode),
+                                       EXTN_XATTR_TRANS_BLOCKS);
+                if (!IS_ERR(handle)) {
+                        int err;
+                        rc = fsfilt_extN_set_md(inode, handle,
+                                                &EXTN_I(inode)->i_data[1],size);
+                        if (rc == 0) {
+                                memset(EXTN_I(inode)->i_data, 0,
+                                       sizeof(EXTN_I(inode)->i_data));
+                                mark_inode_dirty(inode);
+                        }
+                        err = journal_stop(handle);
+                        if (err && rc == 0)
+                                rc = err;
+                } else {
+                        rc = PTR_ERR(handle);
+                }
+#endif
+                unlock_kernel();
                 return size;
         }
 
-        down(&inode->i_sem);
-        lock_kernel();
-        rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_LUSTRE,
-                            XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size);
+        rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_TRUSTED,
+                            XATTR_LUSTRE_MDS_LOV_EA, lmm, lmm_size);
+        /* try old EA type if new one failed - MDS will convert it for us */
+        if (rc == -ENODATA) {
+                CDEBUG(D_INFO,"failed new LOV EA %d/%s from inode %lu: rc %d\n",
+                       EXTN_XATTR_INDEX_TRUSTED, XATTR_LUSTRE_MDS_LOV_EA,
+                       inode->i_ino, rc);
+
+                rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_LUSTRE,
+                                    XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size);
+        }
         unlock_kernel();
-        up(&inode->i_sem);
 
         /* This gives us the MD size */
         if (lmm == NULL)
                 return (rc == -ENODATA) ? 0 : rc;
 
         if (rc < 0) {
-                CDEBUG(D_INFO, "error getting EA %s from inode %lu: "
-                       "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc);
+                CDEBUG(D_INFO, "error getting EA %d/%s from inode %lu: rc %d\n",
+                       EXTN_XATTR_INDEX_LUSTRE, XATTR_LUSTRE_MDS_OBJID,
+                       inode->i_ino, rc);
                 memset(lmm, 0, lmm_size);
                 return (rc == -ENODATA) ? 0 : rc;
         }
@@ -445,9 +601,9 @@ static void fsfilt_extN_cb_func(struct journal_callback *jcb, int error)
         atomic_dec(&fcb_cache_count);
 }
 
-static int fsfilt_extN_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd,
-                                     void *handle, fsfilt_cb_t cb_func,
-                                     void *cb_data)
+static int fsfilt_extN_add_journal_cb(struct obd_device *obd, __u64 last_rcvd,
+                                      void *handle, fsfilt_cb_t cb_func,
+                                      void *cb_data)
 {
         struct fsfilt_cb_data *fcb;
 
@@ -470,15 +626,6 @@ static int fsfilt_extN_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd,
         return 0;
 }
 
-static int fsfilt_extN_journal_data(struct file *filp)
-{
-        struct inode *inode = filp->f_dentry->d_inode;
-
-        EXTN_I(inode)->i_flags |= EXTN_JOURNAL_DATA_FL;
-
-        return 0;
-}
-
 /*
  * We need to hack the return value for the free inode counts because
  * the current EA code requires one filesystem block per inode with EAs,
@@ -505,8 +652,16 @@ static int fsfilt_extN_sync(struct super_block *sb)
         return extN_force_commit(sb);
 }
 
+extern int extN_map_inode_page(struct inode *inode, struct page *page,
+                               unsigned long *blocks, int *created, int create);
+int fsfilt_extN_map_inode_page(struct inode *inode, struct page *page,
+                               unsigned long *blocks, int *created, int create)
+{
+        return extN_map_inode_page(inode, page, blocks, created, create);
+}
+
 extern int extN_prep_san_write(struct inode *inode, long *blocks,
-			       int nblocks, loff_t newsize);
+                               int nblocks, loff_t newsize);
 static int fsfilt_extN_prep_san_write(struct inode *inode, long *blocks,
                                       int nblocks, loff_t newsize)
 {
@@ -522,9 +677,13 @@ static int fsfilt_extN_read_record(struct file * file, void *buf,
         int err;
 
         if (inode->i_size < *offs + size) {
-                CERROR("file size %llu is too short for read %u@%llu\n",
-                       inode->i_size, size, *offs);
-                return -EIO;
+                size = inode->i_size - *offs;
+                if (size < 0) {
+                        CERROR("size %llu is too short for read %u@%llu\n",
+                                        inode->i_size, size, *offs);
+                        return -EIO;
+                } else if (size == 0)
+                        return 0;
         }
 
         block = *offs >> inode->i_blkbits;
@@ -545,11 +704,11 @@ static int fsfilt_extN_read_record(struct file * file, void *buf,
         memcpy(buf, bh->b_data + boffs, size);
         brelse(bh);
         *offs += size;
-        return size;
+        return 0;
 }
 
-static int fsfilt_extN_write_record(struct file * file, void *buf,
-                                    int size, loff_t *offs)
+static int fsfilt_extN_write_record(struct file *file, void *buf, int size,
+                                    loff_t *offs, int force_sync)
 {
         struct buffer_head *bh;
         unsigned long block, boffs;
@@ -561,16 +720,18 @@ static int fsfilt_extN_write_record(struct file * file, void *buf,
 
         journal = EXTN_SB(inode->i_sb)->s_journal;
         handle = journal_start(journal, EXTN_DATA_TRANS_BLOCKS + 2);
-        if (handle == NULL) {
+        if (IS_ERR(handle)) {
                 CERROR("can't start transaction\n");
-                return -EIO;
+                return PTR_ERR(handle);
         }
 
         block = *offs >> inode->i_blkbits;
         if (*offs + size > inode->i_size) {
                 down(&inode->i_sem);
                 if (*offs + size > inode->i_size)
-                        inode->i_size = ((loff_t)block + 1) << inode->i_blkbits;
+                        inode->i_size = *offs + size;
+                if (inode->i_size > EXTN_I(inode)->i_disksize)
+                        EXTN_I(inode)->i_disksize = inode->i_size;
                 up(&inode->i_sem);
         }
 
@@ -607,33 +768,53 @@ static int fsfilt_extN_write_record(struct file * file, void *buf,
                 CERROR("journal_dirty_metadata() returned error %d\n", err);
                 goto out;
         }
-        err = size;
+
+        if (force_sync)
+                handle->h_sync = 1; /* recovery likes this */
 out:
         if (bh)
                 brelse(bh);
         journal_stop(handle);
-        if (err > 0)
+        if (err == 0)
                 *offs += size;
         return err;
 }
 
+static int fsfilt_extN_setup(struct super_block *sb)
+{
+#if 0
+        EXTN_SB(sb)->dx_lock = fsfilt_extN_dx_lock;
+        EXTN_SB(sb)->dx_unlock = fsfilt_extN_dx_unlock;
+#endif
+#ifdef S_PDIROPS
+        CWARN("Enabling PDIROPS\n");
+        set_opt(EXTN_SB(sb)->s_mount_opt, PDIROPS);
+        sb->s_flags |= S_PDIROPS;
+#endif
+        return 0;
+}
+
 static struct fsfilt_operations fsfilt_extN_ops = {
         fs_type:                "extN",
         fs_owner:               THIS_MODULE,
         fs_start:               fsfilt_extN_start,
         fs_brw_start:           fsfilt_extN_brw_start,
         fs_commit:              fsfilt_extN_commit,
+        fs_commit_async:        fsfilt_extN_commit_async,
+        fs_commit_wait:         fsfilt_extN_commit_wait,
         fs_setattr:             fsfilt_extN_setattr,
+        fs_iocontrol:           fsfilt_extN_iocontrol,
         fs_set_md:              fsfilt_extN_set_md,
         fs_get_md:              fsfilt_extN_get_md,
         fs_readpage:            fsfilt_extN_readpage,
-        fs_journal_data:        fsfilt_extN_journal_data,
-        fs_set_last_rcvd:       fsfilt_extN_set_last_rcvd,
+        fs_add_journal_cb:      fsfilt_extN_add_journal_cb,
         fs_statfs:              fsfilt_extN_statfs,
         fs_sync:                fsfilt_extN_sync,
+        fs_map_inode_page:      fsfilt_extN_map_inode_page,
         fs_prep_san_write:      fsfilt_extN_prep_san_write,
         fs_write_record:        fsfilt_extN_write_record,
         fs_read_record:         fsfilt_extN_read_record,
+        fs_setup:               fsfilt_extN_setup,
 };
 
 static int __init fsfilt_extN_init(void)
@@ -672,9 +853,9 @@ static void __exit fsfilt_extN_exit(void)
         //rc = extN_xattr_unregister();
 }
 
+module_init(fsfilt_extN_init);
+module_exit(fsfilt_extN_exit);
+
 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
 MODULE_DESCRIPTION("Lustre extN Filesystem Helper v0.1");
 MODULE_LICENSE("GPL");
-
-module_init(fsfilt_extN_init);
-module_exit(fsfilt_extN_exit);
diff --git a/lustre/obdclass/fsfilt_reiserfs.c b/lustre/lvfs/fsfilt_reiserfs.c
similarity index 92%
rename from lustre/obdclass/fsfilt_reiserfs.c
rename to lustre/lvfs/fsfilt_reiserfs.c
index 00a670d3841df5777176edc48193cd3b29907bf6..c8a5d47a5f50202291eba0d1cec59f1bbbf9f9b2 100644
--- a/lustre/obdclass/fsfilt_reiserfs.c
+++ b/lustre/lvfs/fsfilt_reiserfs.c
@@ -47,6 +47,7 @@
 #include <linux/obd.h>
 #include <linux/obd_class.h>
 #include <linux/module.h>
+#include <linux/init.h>
 
 static void *fsfilt_reiserfs_start(struct inode *inode, int op,
                                    void *desc_private)
@@ -140,9 +141,9 @@ static ssize_t fsfilt_reiserfs_readpage(struct file *file, char *buf, size_t cou
         return file->f_op->read(file, buf, count, offset);
 }
 
-static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd,
-                                         __u64 last_rcvd, void *handle,
-                                         fsfilt_cb_t cb_func, void *cb_data)
+static int fsfilt_reiserfs_add_journal_cb(struct obd_device *obd,
+                                          __u64 last_rcvd, void *handle,
+                                          fsfilt_cb_t cb_func, void *cb_data)
 {
         static long next = 0;
 
@@ -156,12 +157,6 @@ static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd,
         return 0;
 }
 
-static int fsfilt_reiserfs_journal_data(struct file *filp)
-{
-        CERROR("not implemented yet\n");
-        return 0;
-}
-
 static int fsfilt_reiserfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
 {
         struct statfs sfs;
@@ -173,8 +168,7 @@ static int fsfilt_reiserfs_statfs(struct super_block *sb, struct obd_statfs *osf
 
 static int fsfilt_reiserfs_sync(struct super_block *sb)
 {
-        CERROR("not implemented yet\n");
-        return -ENOSYS;
+        return fsync_dev(sb->s_dev);
 }
 
 static struct fsfilt_operations fsfilt_reiserfs_ops = {
@@ -187,8 +181,7 @@ static struct fsfilt_operations fsfilt_reiserfs_ops = {
         fs_set_md:              fsfilt_reiserfs_set_md,
         fs_get_md:              fsfilt_reiserfs_get_md,
         fs_readpage:            fsfilt_reiserfs_readpage,
-        fs_journal_data:        fsfilt_reiserfs_journal_data,
-        fs_set_last_rcvd:       fsfilt_reiserfs_set_last_rcvd,
+        fs_add_journal_cb:      fsfilt_reiserfs_add_journal_cb,
         fs_statfs:              fsfilt_reiserfs_statfs,
         fs_sync:                fsfilt_reiserfs_sync,
 };
diff --git a/lustre/lvfs/lvfs_common.c b/lustre/lvfs/lvfs_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d18d0dc82092ae57736b7b514a46d1819633655
--- /dev/null
+++ b/lustre/lvfs/lvfs_common.c
@@ -0,0 +1,35 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/lvfs.h>
+
+struct dentry *lvfs_fid2dentry(struct obd_run_ctxt *ctxt, __u64 id, __u32 gen, __u64 gr,
+                               void *data)
+{
+        return ctxt->cb_ops.l_fid2dentry(id, gen, gr, data);
+}
+EXPORT_SYMBOL(lvfs_fid2dentry);
diff --git a/lustre/lvfs/lvfs_internal.h b/lustre/lvfs/lvfs_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d68116b19d5a36c69d59dfb88473345202d4bb6
--- /dev/null
+++ b/lustre/lvfs/lvfs_internal.h
@@ -0,0 +1,8 @@
+int  fsfilt_ext3_init(void);
+void fsfilt_ext3_exit(void);
+
+int  fsfilt_extN_init(void);
+void fsfilt_extN_exit(void);
+
+int  fsfilt_reiser_init(void);
+void fsfilt_reiser_exit(void);
diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c
new file mode 100644
index 0000000000000000000000000000000000000000..61cd57cddff6d0a3a21860bb78b74aadc4ac4358
--- /dev/null
+++ b/lustre/lvfs/lvfs_linux.c
@@ -0,0 +1,380 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/lib/fsfilt_ext3.c
+ *  Lustre filesystem abstraction routines
+ *
+ *  Copyright (C) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <asm/unistd.h>
+#include <linux/jbd.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/version.h>
+#include <linux/kp30.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/lustre_compat25.h>
+#include <linux/lvfs.h>
+#include "lvfs_internal.h"
+
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+
+/* Debugging check only needed during development */
+#ifdef OBD_CTXT_DEBUG
+# define ASSERT_CTXT_MAGIC(magic) LASSERT((magic) == OBD_RUN_CTXT_MAGIC)
+# define ASSERT_NOT_KERNEL_CTXT(msg) LASSERT(!segment_eq(get_fs(), get_ds()))
+# define ASSERT_KERNEL_CTXT(msg) LASSERT(segment_eq(get_fs(), get_ds()))
+#else
+# define ASSERT_CTXT_MAGIC(magic) do {} while(0)
+# define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0)
+# define ASSERT_KERNEL_CTXT(msg) do {} while(0)
+#endif
+
+/* push / pop to root of obd store */
+void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
+               struct obd_ucred *uc)
+{
+        //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
+        ASSERT_CTXT_MAGIC(new_ctx->magic);
+        OBD_SET_CTXT_MAGIC(save);
+
+        /*
+        CDEBUG(D_INFO,
+               "= push %p->%p = cur fs %p pwd %p:d%d:i%d (%*s), pwdmnt %p:%d\n",
+               save, current, current->fs, current->fs->pwd,
+               atomic_read(&current->fs->pwd->d_count),
+               atomic_read(&current->fs->pwd->d_inode->i_count),
+               current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+               current->fs->pwdmnt,
+               atomic_read(&current->fs->pwdmnt->mnt_count));
+        */
+
+        save->fs = get_fs();
+        LASSERT(atomic_read(&current->fs->pwd->d_count));
+        LASSERT(atomic_read(&new_ctx->pwd->d_count));
+        save->pwd = dget(current->fs->pwd);
+        save->pwdmnt = mntget(current->fs->pwdmnt);
+        save->ngroups = current->ngroups;
+
+        LASSERT(save->pwd);
+        LASSERT(save->pwdmnt);
+        LASSERT(new_ctx->pwd);
+        LASSERT(new_ctx->pwdmnt);
+
+        if (uc) {
+                save->ouc.ouc_fsuid = current->fsuid;
+                save->ouc.ouc_fsgid = current->fsgid;
+                save->ouc.ouc_cap = current->cap_effective;
+                save->ouc.ouc_suppgid1 = current->groups[0];
+                save->ouc.ouc_suppgid2 = current->groups[1];
+
+                current->fsuid = uc->ouc_fsuid;
+                current->fsgid = uc->ouc_fsgid;
+                current->cap_effective = uc->ouc_cap;
+                current->ngroups = 0;
+
+                if (uc->ouc_suppgid1 != -1)
+                        current->groups[current->ngroups++] = uc->ouc_suppgid1;
+                if (uc->ouc_suppgid2 != -1)
+                        current->groups[current->ngroups++] = uc->ouc_suppgid2;
+        }
+        set_fs(new_ctx->fs);
+        set_fs_pwd(current->fs, new_ctx->pwdmnt, new_ctx->pwd);
+
+        /*
+        CDEBUG(D_INFO,
+               "= push %p->%p = cur fs %p pwd %p:d%d:i%d (%*s), pwdmnt %p:%d\n",
+               new_ctx, current, current->fs, current->fs->pwd,
+               atomic_read(&current->fs->pwd->d_count),
+               atomic_read(&current->fs->pwd->d_inode->i_count),
+               current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+               current->fs->pwdmnt,
+               atomic_read(&current->fs->pwdmnt->mnt_count));
+        */
+}
+EXPORT_SYMBOL(push_ctxt);
+
+void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
+              struct obd_ucred *uc)
+{
+        //printk("pc0");
+        ASSERT_CTXT_MAGIC(saved->magic);
+        //printk("pc1");
+        ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
+
+        /*
+        CDEBUG(D_INFO,
+               " = pop  %p==%p = cur %p pwd %p:d%d:i%d (%*s), pwdmnt %p:%d\n",
+               new_ctx, current, current->fs, current->fs->pwd,
+               atomic_read(&current->fs->pwd->d_count),
+               atomic_read(&current->fs->pwd->d_inode->i_count),
+               current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+               current->fs->pwdmnt,
+               atomic_read(&current->fs->pwdmnt->mnt_count));
+        */
+
+        LASSERT(current->fs->pwd == new_ctx->pwd);
+        LASSERT(current->fs->pwdmnt == new_ctx->pwdmnt);
+
+        set_fs(saved->fs);
+        set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
+
+        dput(saved->pwd);
+        mntput(saved->pwdmnt);
+        if (uc) {
+                current->fsuid = saved->ouc.ouc_fsuid;
+                current->fsgid = saved->ouc.ouc_fsgid;
+                current->cap_effective = saved->ouc.ouc_cap;
+                current->ngroups = saved->ngroups;
+                current->groups[0] = saved->ouc.ouc_suppgid1;
+                current->groups[1] = saved->ouc.ouc_suppgid2;
+        }
+
+        /*
+        CDEBUG(D_INFO,
+               "= pop  %p->%p = cur fs %p pwd %p:d%d:i%d (%*s), pwdmnt %p:%d\n",
+               saved, current, current->fs, current->fs->pwd,
+               atomic_read(&current->fs->pwd->d_count),
+               atomic_read(&current->fs->pwd->d_inode->i_count),
+               current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+               current->fs->pwdmnt,
+               atomic_read(&current->fs->pwdmnt->mnt_count));
+        */
+}
+EXPORT_SYMBOL(pop_ctxt);
+
+/* utility to make a file */
+struct dentry *simple_mknod(struct dentry *dir, char *name, int mode)
+{
+        struct dentry *dchild;
+        int err = 0;
+        ENTRY;
+
+        ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n");
+        CDEBUG(D_INODE, "creating file %*s\n", (int)strlen(name), name);
+
+        dchild = ll_lookup_one_len(name, dir, strlen(name));
+        if (IS_ERR(dchild))
+                GOTO(out_up, dchild);
+
+        if (dchild->d_inode) {
+                if (!S_ISREG(dchild->d_inode->i_mode))
+                        GOTO(out_err, err = -EEXIST);
+
+                GOTO(out_up, dchild);
+        }
+
+        err = ll_vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG,
+                            NULL);
+        if (err)
+                GOTO(out_err, err);
+
+        RETURN(dchild);
+
+out_err:
+        dput(dchild);
+        dchild = ERR_PTR(err);
+out_up:
+        return dchild;
+}
+EXPORT_SYMBOL(simple_mknod);
+
+/* utility to make a directory */
+struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode)
+{
+        struct dentry *dchild;
+        int err = 0;
+        ENTRY;
+
+        ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n");
+        CDEBUG(D_INODE, "creating directory %*s\n", (int)strlen(name), name);
+        dchild = ll_lookup_one_len(name, dir, strlen(name));
+        if (IS_ERR(dchild))
+                GOTO(out_up, dchild);
+
+        if (dchild->d_inode) {
+                if (!S_ISDIR(dchild->d_inode->i_mode))
+                        GOTO(out_err, err = -ENOTDIR);
+
+                GOTO(out_up, dchild);
+        }
+
+        err = vfs_mkdir(dir->d_inode, dchild, mode);
+        if (err)
+                GOTO(out_err, err);
+
+        RETURN(dchild);
+
+out_err:
+        dput(dchild);
+        dchild = ERR_PTR(err);
+out_up:
+        return dchild;
+}
+EXPORT_SYMBOL(simple_mkdir);
+
+/*
+ * Read a file from within kernel context.  Prior to calling this
+ * function we should already have done a push_ctxt().
+ */
+int lustre_fread(struct file *file, void *buf, int len, loff_t *off)
+{
+        ASSERT_KERNEL_CTXT("kernel doing read outside kernel context\n");
+        if (!file || !file->f_op || !file->f_op->read || !off)
+                RETURN(-ENOSYS);
+
+        return file->f_op->read(file, buf, len, off);
+}
+EXPORT_SYMBOL(lustre_fread);
+
+/*
+ * Write a file from within kernel context.  Prior to calling this
+ * function we should already have done a push_ctxt().
+ */
+int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off)
+{
+        ENTRY;
+        ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n");
+        if (!file)
+                RETURN(-ENOENT);
+        if (!file->f_op)
+                RETURN(-ENOSYS);
+        if (!off)
+                RETURN(-EINVAL);
+
+        if (!file->f_op->write)
+                RETURN(-EROFS);
+
+        RETURN(file->f_op->write(file, buf, len, off));
+}
+EXPORT_SYMBOL(lustre_fwrite);
+
+/*
+ * Sync a file from within kernel context.  Prior to calling this
+ * function we should already have done a push_ctxt().
+ */
+int lustre_fsync(struct file *file)
+{
+        ENTRY;
+        ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n");
+        if (!file || !file->f_op || !file->f_op->fsync)
+                RETURN(-ENOSYS);
+
+        RETURN(file->f_op->fsync(file, file->f_dentry, 0));
+}
+EXPORT_SYMBOL(lustre_fsync);
+
+struct l_file *l_dentry_open(struct obd_run_ctxt *ctxt, struct l_dentry *de,
+                             int flags)
+{
+        mntget(ctxt->pwdmnt);
+        return dentry_open(de, ctxt->pwdmnt, flags);
+}
+EXPORT_SYMBOL(l_dentry_open);
+
+static int l_filldir(void *__buf, const char *name, int namlen, loff_t offset,
+                     ino_t ino, unsigned int d_type)
+{
+        struct l_linux_dirent *dirent;
+        struct l_readdir_callback *buf = (struct l_readdir_callback *)__buf;
+        int reclen = size_round(offsetof(struct l_linux_dirent, d_name) + namlen + 1);
+        
+        buf->error = -EINVAL;
+        if (reclen > buf->count)
+                return -EINVAL;
+        dirent = buf->previous;
+        if (dirent)
+               dirent->d_off = offset; 
+        dirent = buf->current_dir;
+        buf->previous = dirent;
+        dirent->d_ino = ino;
+        dirent->d_reclen = reclen;
+        memcpy(dirent->d_name, name, namlen);
+        ((char *)dirent) += reclen;
+        buf->current_dir = dirent;
+        buf->count -= reclen; 
+        return 0;
+}
+
+long l_readdir(struct file * file, void * dirent, unsigned int count)
+{
+        struct l_linux_dirent * lastdirent;
+        struct l_readdir_callback buf;
+        int error;
+
+        buf.current_dir = (struct l_linux_dirent *)dirent;
+        buf.previous = NULL;
+        buf.count = count;
+        buf.error = 0;
+
+        error = vfs_readdir(file, l_filldir, &buf);
+        if (error < 0)
+                return error;
+        error = buf.error;
+        lastdirent = buf.previous;
+
+        if (lastdirent) {
+                lastdirent->d_off = file->f_pos;
+                error = count - buf.count;        
+        }
+        return error; 
+}
+EXPORT_SYMBOL(l_readdir);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+static int __init lvfs_linux_init(void)
+{
+        RETURN(0);
+}
+
+static void __exit lvfs_linux_exit(void)
+{
+
+        return;
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre VFS Filesystem Helper v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(lvfs_linux_init);
+module_exit(lvfs_linux_exit);
+
+#else
+
+#warning "lvfs_linux_init() and fsfilt_ext3_exit() aren't called on 2.6. MUST be fixed"
+
+
+#endif
diff --git a/lustre/lvfs/lvfs_userfs.c b/lustre/lvfs/lvfs_userfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..021a0a3f85214126e32aa428a7eaa90eccee5e6a
--- /dev/null
+++ b/lustre/lvfs/lvfs_userfs.c
@@ -0,0 +1,44 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/lib/fsfilt_ext3.c
+ *  Lustre filesystem abstraction routines
+ *
+ *  Copyright (C) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <liblustre.h>
+#include <linux/lvfs.h>
+#include "lvfs_internal.h"
+
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+
+/* XXX currently ctxt functions should not be used ?? */
+void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
+               struct obd_ucred *uc)
+{
+        LBUG();
+}
+
+void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
+              struct obd_ucred *uc)
+{
+        LBUG();
+}
diff --git a/lustre/mdc/Makefile.am b/lustre/mdc/Makefile.am
index f4f02181bff7ddff28220ca6fb7f95e6aa256fb4..c254e76edf3d04f3165cd37bcf408b131e77bcf1 100644
--- a/lustre/mdc/Makefile.am
+++ b/lustre/mdc/Makefile.am
@@ -7,13 +7,13 @@ DEFS=
 
 if LIBLUSTRE
 lib_LIBRARIES = libmdc.a
-libmdc_a_SOURCES = mdc_request.c mdc_reint.c mdc_lib.c mdc_internal.h
+libmdc_a_SOURCES = mdc_request.c mdc_reint.c mdc_lib.c mdc_internal.h mdc_locks.c
 else
 MODULE = mdc
 modulefs_DATA = mdc.o
 EXTRA_PROGRAMS = mdc
 
-mdc_SOURCES = mdc_request.c mdc_reint.c lproc_mdc.c mdc_lib.c mdc_internal.h
+mdc_SOURCES = mdc_request.c mdc_reint.c lproc_mdc.c mdc_lib.c mdc_locks.c mdc_internal.h
 endif
 
 include $(top_srcdir)/Rules
diff --git a/lustre/mdc/Makefile.mk b/lustre/mdc/Makefile.mk
index b12e5fcb92613d7769f300114c18f8ef3b8ee5d9..a93f1cfc8b226536e6665ead5cdfa3c7ca09031b 100644
--- a/lustre/mdc/Makefile.mk
+++ b/lustre/mdc/Makefile.mk
@@ -6,4 +6,4 @@
 include $(src)/../portals/Kernelenv
 
 obj-y += mdc.o
-mdc-objs := mdc_request.o mdc_reint.o lproc_mdc.o mdc_lib.o
+mdc-objs := mdc_locks.o mdc_request.o mdc_reint.o lproc_mdc.o mdc_lib.o
diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h
index 49d85ab21138fc1d130e40fb6ca9191cde8cc390..2b459b4f0b4da9f7bb7828bdbfc22e76b6a486b2 100644
--- a/lustre/mdc/mdc_internal.h
+++ b/lustre/mdc/mdc_internal.h
@@ -1,7 +1,7 @@
 void mdc_pack_req_body(struct ptlrpc_request *);
 void mdc_pack_rep_body(struct ptlrpc_request *);
 void mdc_readdir_pack(struct ptlrpc_request *req, __u64 offset, __u32 size,
-                      obd_id ino, int type);
+                      struct ll_fid *mdc_fid);
 void mdc_getattr_pack(struct ptlrpc_request *req, int valid, int offset,
                       int flags, struct mdc_op_data *data);
 void mdc_setattr_pack(struct ptlrpc_request *req,
@@ -9,12 +9,10 @@ void mdc_setattr_pack(struct ptlrpc_request *req,
                       struct iattr *iattr, void *ea, int ealen,
 		      void *ea2, int ea2len);
 void mdc_create_pack(struct ptlrpc_request *req, int offset,
-                     struct mdc_op_data *op_data,
-                     __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time,
+                     struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
                      const void *data, int datalen);
 void mdc_open_pack(struct ptlrpc_request *req, int offset,
-                   struct mdc_op_data *op_data,
-                   __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time,
+                   struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
                    __u32 flags, const void *data, int datalen);
 void mdc_unlink_pack(struct ptlrpc_request *req, int offset,
                      struct mdc_op_data *data);
@@ -23,3 +21,46 @@ void mdc_link_pack(struct ptlrpc_request *req, int offset,
 void mdc_rename_pack(struct ptlrpc_request *req, int offset,
                      struct mdc_op_data *data,
                      const char *old, int oldlen, const char *new, int newlen);
+
+struct mdc_open_data {
+        struct obd_client_handle *mod_och;
+        struct ptlrpc_request    *mod_open_req;
+        struct ptlrpc_request    *mod_close_req;
+};
+
+struct mdc_rpc_lock {
+        struct semaphore rpcl_sem;
+        struct lookup_intent *rpcl_it;
+};
+
+static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
+{
+        sema_init(&lck->rpcl_sem, 1);
+        lck->rpcl_it = NULL;
+}
+
+static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 
+                                    struct lookup_intent *it)
+{
+        ENTRY;
+        down(&lck->rpcl_sem);
+        if (it) { 
+                lck->rpcl_it = it;
+        }
+}
+
+static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 
+                                    struct lookup_intent *it)
+{
+        EXIT;
+        if (it == NULL) {
+                LASSERT(it == lck->rpcl_it);
+                up(&lck->rpcl_sem);
+                return;
+        }
+        if (it) {
+                LASSERT(it == lck->rpcl_it);
+                lck->rpcl_it = NULL;
+                up(&lck->rpcl_sem);
+        }
+}
diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c
index a17f7a1301280c32d4b4aaecbc5e0d802b500a5c..0de8ad73a0c21a7ccfed08f4a67c074ce0017ab5 100644
--- a/lustre/mdc/mdc_lib.c
+++ b/lustre/mdc/mdc_lib.c
@@ -21,15 +21,23 @@
 
 #define DEBUG_SUBSYSTEM S_MDS
 #ifndef __KERNEL__
+# include <fcntl.h>
 # include <liblustre.h>
 #endif
 #include <linux/lustre_idl.h>
 #include <linux/lustre_net.h>
 #include <linux/lustre_mds.h>
-#include <linux/lustre_lite.h>
+#include "mdc_internal.h"
+
+#ifndef __KERNEL__
+/* some liblustre hackings here */
+#ifndef O_DIRECTORY
+#define O_DIRECTORY     0
+#endif
+#endif
 
 void mdc_readdir_pack(struct ptlrpc_request *req, __u64 offset, __u32 size,
-                      obd_id ino, int type, __u64 xid)
+                      struct ll_fid *mdc_fid)
 {
         struct mds_body *b;
 
@@ -37,11 +45,9 @@ void mdc_readdir_pack(struct ptlrpc_request *req, __u64 offset, __u32 size,
         b->fsuid = current->fsuid;
         b->fsgid = current->fsgid;
         b->capability = current->cap_effective;
-        b->fid1.id = ino;
-        b->fid1.f_type = type;
+        b->fid1 = *mdc_fid;
         b->size = offset;                       /* !! */
         b->suppgid = -1;
-        b->blocks = xid;                        /* !! */
         b->nlink = size;                        /* !! */
 }
 
@@ -62,8 +68,7 @@ void mdc_pack_req_body(struct ptlrpc_request *req)
 
 /* packing of MDS records */
 void mdc_create_pack(struct ptlrpc_request *req, int offset,
-                     struct mdc_op_data *op_data,
-                     __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time,
+                     struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
                      const void *data, int datalen)
 {
         struct mds_rec_create *rec;
@@ -74,17 +79,12 @@ void mdc_create_pack(struct ptlrpc_request *req, int offset,
         rec->cr_fsuid = current->fsuid;
         rec->cr_fsgid = current->fsgid;
         rec->cr_cap = current->cap_effective;
-        ll_ino2fid(&rec->cr_fid, op_data->ino1, op_data->gen1, op_data->typ1);
+        rec->cr_fid = op_data->fid1;
         memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid));
         rec->cr_mode = mode;
         rec->cr_rdev = rdev;
-        rec->cr_uid = uid;
-        rec->cr_gid = gid;
-        rec->cr_time = time;
-        if (in_group_p(op_data->gid1))
-                rec->cr_suppgid = op_data->gid1;
-        else
-                rec->cr_suppgid = -1;
+        rec->cr_time = op_data->mod_time;
+        rec->cr_suppgid = op_data->ctxt.gid1;
 
         tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, op_data->namelen + 1);
         LOGL0(op_data->name, op_data->namelen, tmp);
@@ -95,11 +95,24 @@ void mdc_create_pack(struct ptlrpc_request *req, int offset,
         }
 }
 
+static __u32 mds_pack_open_flags(__u32 flags)
+{
+        return
+                (flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC |
+                          MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA)) |
+                ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) |
+                ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) |
+                ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) |
+                ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) |
+                ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) |
+                ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) |
+                0;
+}
+
 /* packing of MDS records */
 void mdc_open_pack(struct ptlrpc_request *req, int offset,
-                   struct mdc_op_data *op_data,
-                   __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time,
-                   __u32 flags, const void *data, int datalen)
+                   struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
+                   __u32 flags, const void *lmm, int lmmlen)
 {
         struct mds_rec_create *rec;
         char *tmp;
@@ -111,19 +124,13 @@ void mdc_open_pack(struct ptlrpc_request *req, int offset,
         rec->cr_fsgid = current->fsgid;
         rec->cr_cap = current->cap_effective;
         if (op_data != NULL)
-                ll_ino2fid(&rec->cr_fid, op_data->ino1,
-                           op_data->gen1, op_data->typ1);
+                rec->cr_fid = op_data->fid1;
         memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid));
         rec->cr_mode = mode;
-        rec->cr_flags = flags;
+        rec->cr_flags = mds_pack_open_flags(flags);
         rec->cr_rdev = rdev;
-        rec->cr_uid = uid;
-        rec->cr_gid = gid;
-        rec->cr_time = time;
-        if (in_group_p(op_data->gid1))
-                rec->cr_suppgid = op_data->gid1;
-        else
-                rec->cr_suppgid = -1;
+        rec->cr_time = op_data->mod_time;
+        rec->cr_suppgid = op_data->ctxt.gid1;
 
         if (op_data->name) {
                 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1,
@@ -131,14 +138,14 @@ void mdc_open_pack(struct ptlrpc_request *req, int offset,
                 LOGL0(op_data->name, op_data->namelen, tmp);
         }
 
-        if (data) {
-                tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2, datalen);
-                memcpy (tmp, data, datalen);
+        if (lmm) {
+                rec->cr_flags |= MDS_OPEN_HAS_EA;
+                tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2, lmmlen);
+                memcpy (tmp, lmm, lmmlen);
         }
 }
 
-void mdc_setattr_pack(struct ptlrpc_request *req,
-                      struct mdc_op_data *data,
+void mdc_setattr_pack(struct ptlrpc_request *req, struct mdc_op_data *data,
                       struct iattr *iattr, void *ea, int ealen,
                       void *ea2, int ea2len)
 {
@@ -148,7 +155,7 @@ void mdc_setattr_pack(struct ptlrpc_request *req,
         rec->sa_fsuid = current->fsuid;
         rec->sa_fsgid = current->fsgid;
         rec->sa_cap = current->cap_effective;
-        ll_ino2fid(&rec->sa_fid, data->ino1, data->gen1, data->typ1);
+        rec->sa_fid = data->fid1;
 
         if (iattr) {
                 rec->sa_valid = iattr->ia_valid;
@@ -160,14 +167,14 @@ void mdc_setattr_pack(struct ptlrpc_request *req,
                 rec->sa_mtime = LTIME_S(iattr->ia_mtime);
                 rec->sa_ctime = LTIME_S(iattr->ia_ctime);
                 rec->sa_attr_flags = iattr->ia_attr_flags;
-
                 if ((iattr->ia_valid & ATTR_GID) && in_group_p(iattr->ia_gid))
                         rec->sa_suppgid = iattr->ia_gid;
                 else if ((iattr->ia_valid & ATTR_MODE) &&
-                         in_group_p(data->gid1))
-                        rec->sa_suppgid = data->gid1;
-                else
-                        rec->sa_suppgid = -1;
+                         in_group_p(iattr->ia_gid))
+                        rec->sa_suppgid = data->ctxt.gid1;
+                else if ((iattr->ia_valid & (ATTR_MTIME|ATTR_CTIME)) &&
+                         data->ctxt.gid1 != -1)
+                        rec->sa_suppgid = data->ctxt.gid1;
         }
 
         if (ealen == 0)
@@ -194,14 +201,11 @@ void mdc_unlink_pack(struct ptlrpc_request *req, int offset,
         rec->ul_fsuid = current->fsuid;
         rec->ul_fsgid = current->fsgid;
         rec->ul_cap = current->cap_effective;
-        rec->ul_mode = data->mode;
-        if (in_group_p(data->gid1))
-                rec->ul_suppgid = data->gid1;
-        else
-                rec->ul_suppgid = -1;
-        ll_ino2fid(&rec->ul_fid1, data->ino1, data->gen1, data->typ1);
-        if (data->ino2)
-                ll_ino2fid(&rec->ul_fid2, data->ino2, data->gen2, data->typ2);
+        rec->ul_mode = data->create_mode;
+        rec->ul_suppgid = data->ctxt.gid1;
+        rec->ul_fid1 = data->fid1;
+        rec->ul_fid2 = data->fid2;
+        rec->ul_time = data->mod_time;
 
         tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, data->namelen + 1);
         LASSERT (tmp != NULL);
@@ -220,16 +224,11 @@ void mdc_link_pack(struct ptlrpc_request *req, int offset,
         rec->lk_fsuid = current->fsuid;
         rec->lk_fsgid = current->fsgid;
         rec->lk_cap = current->cap_effective;
-        if (in_group_p(data->gid1))
-                rec->lk_suppgid1 = data->gid1;
-        else
-                rec->lk_suppgid1 = -1;
-        if (in_group_p(data->gid2))
-                rec->lk_suppgid2 = data->gid2;
-        else
-                rec->lk_suppgid2 = -1;
-        ll_ino2fid(&rec->lk_fid1, data->ino1, data->gen1, data->typ1);
-        ll_ino2fid(&rec->lk_fid2, data->ino2, data->gen2, data->typ2);
+        rec->lk_suppgid1 = data->ctxt.gid1;
+        rec->lk_suppgid2 = data->ctxt.gid2;
+        rec->lk_fid1 = data->fid1;
+        rec->lk_fid2 = data->fid2;
+        rec->lk_time = data->mod_time;
 
         tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, data->namelen + 1);
         LOGL0(data->name, data->namelen, tmp);
@@ -249,16 +248,17 @@ void mdc_rename_pack(struct ptlrpc_request *req, int offset,
         rec->rn_fsuid = current->fsuid;
         rec->rn_fsgid = current->fsgid;
         rec->rn_cap = current->cap_effective;
-        if (in_group_p(data->gid1))
-                rec->rn_suppgid1 = data->gid1;
+        if (in_group_p(data->ctxt.gid1))
+                rec->rn_suppgid1 = data->ctxt.gid1;
         else
                 rec->rn_suppgid1 = -1;
-        if (in_group_p(data->gid2))
-                rec->rn_suppgid2 = data->gid2;
+        if (in_group_p(data->ctxt.gid2))
+                rec->rn_suppgid2 = data->ctxt.gid2;
         else
                 rec->rn_suppgid2 = -1;
-        ll_ino2fid(&rec->rn_fid1, data->ino1, data->gen1, data->typ1);
-        ll_ino2fid(&rec->rn_fid2, data->ino2, data->gen2, data->typ2);
+        rec->rn_fid1 = data->fid1;
+        rec->rn_fid2 = data->fid2;
+        rec->rn_time = data->mod_time;
 
         tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, oldlen + 1);
         LOGL0(old, oldlen, tmp);
@@ -280,12 +280,9 @@ void mdc_getattr_pack(struct ptlrpc_request *req, int valid, int offset,
         b->capability = current->cap_effective;
         b->valid = valid;
         b->flags = flags;
-        if (in_group_p(data->gid1))
-                b->suppgid = data->gid1;
-        else
-                b->suppgid = -1;
+        b->suppgid = data->ctxt.gid1;
 
-        ll_ino2fid(&b->fid1, data->ino1, data->gen1, data->typ1);
+        b->fid1 = data->fid1;
         if (data->name) {
                 char *tmp;
                 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1,
@@ -293,3 +290,4 @@ void mdc_getattr_pack(struct ptlrpc_request *req, int valid, int offset,
                 LOGL0(data->name, data->namelen, tmp);
         }
 }
+
diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c
new file mode 100644
index 0000000000000000000000000000000000000000..8fbe9b7ab828f4ac97a44bd5093a0bfa506e9abb
--- /dev/null
+++ b/lustre/mdc/mdc_locks.c
@@ -0,0 +1,549 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.sf.net/projects/lustre/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MDC
+
+#ifdef __KERNEL__
+# include <linux/module.h>
+# include <linux/pagemap.h>
+# include <linux/miscdevice.h>
+# include <linux/init.h>
+#else
+# include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_mds.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lprocfs_status.h>
+#include "mdc_internal.h"
+
+int it_disposition(struct lookup_intent *it, int flag)
+{
+        return it->d.lustre.it_disposition & flag;
+}
+EXPORT_SYMBOL(it_disposition);
+
+void it_set_disposition(struct lookup_intent *it, int flag)
+{
+        it->d.lustre.it_disposition |= flag;
+}
+EXPORT_SYMBOL(it_set_disposition);
+
+static void mdc_fid2mdc_op_data(struct mdc_op_data *data, struct ll_uctxt *ctxt,
+                                struct ll_fid *f1, struct ll_fid *f2,
+                                const char *name, int namelen, int mode)
+{
+        LASSERT(data);
+        LASSERT(ctxt);
+        LASSERT(f1);
+
+        data->ctxt = *ctxt;
+        data->fid1 = *f1;
+        if (f2)
+                data->fid2 = *f2;
+        else
+                memset(&data->fid2, 0, sizeof(data->fid2));
+        data->name = name;
+        data->namelen = namelen;
+        data->create_mode = mode;
+        data->mod_time = LTIME_S(CURRENT_TIME);
+}
+
+static int it_to_lock_mode(struct lookup_intent *it)
+{
+        /* CREAT needs to be tested before open (both could be set) */
+        if (it->it_op & IT_CREAT)
+                return LCK_PW;
+        else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP))
+                return LCK_PR;
+
+        LBUG();
+        RETURN(-EINVAL);
+}
+
+int it_open_error(int phase, struct lookup_intent *it)
+{
+        if (it_disposition(it, DISP_OPEN_OPEN)) {
+                if (phase == DISP_OPEN_OPEN)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+
+        if (it_disposition(it, DISP_OPEN_CREATE)) {
+                if (phase == DISP_OPEN_CREATE)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+
+        if (it_disposition(it, DISP_LOOKUP_EXECD)) {
+                if (phase == DISP_LOOKUP_EXECD)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+
+        if (it_disposition(it, DISP_IT_EXECD)) {
+                if (phase == DISP_IT_EXECD)
+                        return it->d.lustre.it_status;
+                else
+                        return 0;
+        }
+        CERROR("it disp: %X, status: %d\n", it->d.lustre.it_disposition,
+               it->d.lustre.it_status);
+        LBUG();
+        return 0;
+}
+EXPORT_SYMBOL(it_open_error);
+
+/* this must be called on a lockh that is known to have a referenced lock */
+void mdc_set_lock_data(__u64 *l, void *data)
+{
+        struct ldlm_lock *lock;
+        struct lustre_handle *lockh = (struct lustre_handle *)l;
+        ENTRY;
+
+        if (!*l) {
+                EXIT;
+                return;
+        }
+
+        lock = ldlm_handle2lock(lockh);
+
+        LASSERT(lock != NULL);
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+#ifdef __KERNEL__
+        if (lock->l_ast_data && lock->l_ast_data != data) {
+                struct inode *new_inode = data;
+                struct inode *old_inode = lock->l_ast_data;
+                unsigned long state = old_inode->i_state & I_FREEING;
+                CERROR("Found existing inode %p/%lu/%u state %lu in lock: "
+                       "setting data to %p/%lu/%u\n", old_inode,
+                       old_inode->i_ino, old_inode->i_generation, state,
+                       new_inode, new_inode->i_ino, new_inode->i_generation);
+                LASSERT(state);
+        }
+#endif
+        lock->l_ast_data = data;
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+        LDLM_LOCK_PUT(lock);
+
+        EXIT;
+}
+EXPORT_SYMBOL(mdc_set_lock_data);
+
+int mdc_change_cbdata(struct obd_export *exp, struct ll_fid *fid, 
+                      ldlm_iterator_t it, void *data)
+{
+        struct ldlm_res_id res_id = { .name = {0} };
+        ENTRY;
+
+        res_id.name[0] = fid->id;
+        res_id.name[1] = fid->generation;
+
+        ldlm_change_cbdata(class_exp2obd(exp)->obd_namespace, &res_id, it, 
+                           data);
+        EXIT;
+        return 0;
+}
+
+
+
+/* We always reserve enough space in the reply packet for a stripe MD, because
+ * we don't know in advance the file type. */
+int mdc_enqueue(struct obd_export *exp,
+                int lock_type,
+                struct lookup_intent *it,
+                int lock_mode,
+                struct mdc_op_data *data,
+                struct lustre_handle *lockh,
+                void *lmm,
+                int lmmsize,
+                ldlm_completion_callback cb_completion,
+                ldlm_blocking_callback cb_blocking,
+                void *cb_data)
+{
+        struct ptlrpc_request *req;
+        struct obd_device *obddev = class_exp2obd(exp);
+        struct ldlm_res_id res_id =
+                { .name = {data->fid1.id, data->fid1.generation} };
+        int size[6] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)};
+        int rc, flags = LDLM_FL_HAS_INTENT;
+        int repsize[4] = {sizeof(struct ldlm_reply),
+                          sizeof(struct mds_body),
+                          obddev->u.cli.cl_max_mds_easize,
+                          obddev->u.cli.cl_max_mds_cookiesize};
+        struct ldlm_reply *dlm_rep;
+        struct ldlm_intent *lit;
+        struct ldlm_request *lockreq;
+        void *eadata;
+        unsigned long irqflags;
+        int   reply_buffers = 0;
+        ENTRY;
+
+//        LDLM_DEBUG_NOLOCK("mdsintent=%s,name=%s,dir=%lu",
+//                          ldlm_it2str(it->it_op), it_name, it_inode->i_ino);
+
+        if (it->it_op & IT_OPEN) {
+                it->it_create_mode |= S_IFREG;
+                it->it_create_mode &= ~current->fs->umask;
+
+                size[2] = sizeof(struct mds_rec_create);
+                size[3] = data->namelen + 1;
+                size[4] = obddev->u.cli.cl_max_mds_easize;
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 
+                                      5, size, NULL);
+                if (!req)
+                        RETURN(-ENOMEM);
+
+                spin_lock_irqsave (&req->rq_lock, irqflags);
+                req->rq_replay = 1;
+                spin_unlock_irqrestore (&req->rq_lock, irqflags);
+
+                /* pack the intent */
+                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
+                lit->opc = (__u64)it->it_op;
+
+                /* pack the intended request */
+                mdc_open_pack(req, 2, data, it->it_create_mode, 0,
+                              it->it_flags, lmm, lmmsize);
+                /* get ready for the reply */
+                reply_buffers = 3;
+                req->rq_replen = lustre_msg_size(3, repsize);
+        } else if (it->it_op & IT_UNLINK) {
+                size[2] = sizeof(struct mds_rec_unlink);
+                size[3] = data->namelen + 1;
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 4,
+                                      size, NULL);
+                if (!req)
+                        RETURN(-ENOMEM);
+
+                /* pack the intent */
+                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
+                lit->opc = (__u64)it->it_op;
+
+                /* pack the intended request */
+                mdc_unlink_pack(req, 2, data);
+                /* get ready for the reply */
+                reply_buffers = 4;
+                req->rq_replen = lustre_msg_size(4, repsize);
+        } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) {
+                int valid = OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE;
+                size[2] = sizeof(struct mds_body);
+                size[3] = data->namelen + 1;
+
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 4,
+                                      size, NULL);
+                if (!req)
+                        RETURN(-ENOMEM);
+
+                /* pack the intent */
+                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
+                lit->opc = (__u64)it->it_op;
+
+                /* pack the intended request */
+                mdc_getattr_pack(req, valid, 2, it->it_flags, data);
+                /* get ready for the reply */
+                reply_buffers = 3;
+                req->rq_replen = lustre_msg_size(3, repsize);
+        } else if (it->it_op == IT_READDIR) {
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1,
+                                      size, NULL);
+                if (!req)
+                        RETURN(-ENOMEM);
+
+                /* get ready for the reply */
+                reply_buffers = 1;
+                req->rq_replen = lustre_msg_size(1, repsize);
+        }  else {
+                LBUG();
+                RETURN(-EINVAL);
+        }
+
+        mdc_get_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
+        rc = ldlm_cli_enqueue(exp, req, obddev->obd_namespace, NULL, res_id,
+                              lock_type, NULL, 0, lock_mode, &flags,
+                              cb_completion, cb_blocking, cb_data, lockh);
+        mdc_put_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
+
+        /* Similarly, if we're going to replay this request, we don't want to
+         * actually get a lock, just perform the intent. */
+        if (req->rq_transno || req->rq_replay) {
+                lockreq = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*lockreq));
+                lockreq->lock_flags |= LDLM_FL_INTENT_ONLY;
+        }
+
+        /* This can go when we're sure that this can never happen */
+        LASSERT(rc != -ENOENT);
+        if (rc == ELDLM_LOCK_ABORTED) {
+                lock_mode = 0;
+                memset(lockh, 0, sizeof(*lockh));
+                rc = 0;
+        } else if (rc != 0) {
+                CERROR("ldlm_cli_enqueue: %d\n", rc);
+                LASSERT (rc < 0);
+                ptlrpc_req_finished(req);
+                RETURN(rc);
+        } else { /* rc = 0 */
+                struct ldlm_lock *lock = ldlm_handle2lock(lockh);
+                LASSERT(lock);
+
+                /* If the server gave us back a different lock mode, we should
+                 * fix up our variables. */
+                if (lock->l_req_mode != lock_mode) {
+                        ldlm_lock_addref(lockh, lock->l_req_mode);
+                        ldlm_lock_decref(lockh, lock_mode);
+                        lock_mode = lock->l_req_mode;
+                }
+
+                LDLM_LOCK_PUT(lock);
+        }
+
+        dlm_rep = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*dlm_rep));
+        LASSERT(dlm_rep != NULL);           /* checked by ldlm_cli_enqueue() */
+        LASSERT_REPSWABBED(req, 0);         /* swabbed by ldlm_cli_enqueue() */
+
+        it->d.lustre.it_disposition = (int) dlm_rep->lock_policy_res1;
+        it->d.lustre.it_status = (int) dlm_rep->lock_policy_res2;
+        it->d.lustre.it_lock_mode = lock_mode;
+        it->d.lustre.it_data = req;
+
+        /* We know what to expect, so we do any byte flipping required here */
+        LASSERT(reply_buffers == 4 || reply_buffers == 3 || reply_buffers == 1);
+        if (reply_buffers >= 3) {
+                struct mds_body *body;
+
+                body = lustre_swab_repbuf(req, 1, sizeof (*body),
+                                           lustre_swab_mds_body);
+                if (body == NULL) {
+                        CERROR ("Can't swab mds_body\n");
+                        RETURN (-EPROTO);
+                }
+
+                if ((body->valid & OBD_MD_FLEASIZE) != 0) {
+                        void *replayea;
+                        /* The eadata is opaque; just check that it is
+                         * there.  Eventually, obd_unpackmd() will check
+                         * the contents */
+                        eadata = lustre_swab_repbuf(req, 2, body->eadatasize,
+                                                    NULL);
+                        if (eadata == NULL) {
+                                CERROR ("Missing/short eadata\n");
+                                RETURN (-EPROTO);
+                        }
+                        if (it->it_op & IT_OPEN) {
+                                replayea = lustre_msg_buf(req->rq_reqmsg, 4, 
+                                                          obddev->u.cli.cl_max_mds_easize);
+                                LASSERT(replayea);
+                                memcpy(replayea, eadata, body->eadatasize);
+                        }
+                }
+        }
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(mdc_enqueue);
+
+/* 
+ * This long block is all about fixing up the lock and request state
+ * so that it is correct as of the moment _before_ the operation was
+ * applied; that way, the VFS will think that everything is normal and
+ * call Lustre's regular VFS methods.
+ *
+ * If we're performing a creation, that means that unless the creation
+ * failed with EEXIST, we should fake up a negative dentry.
+ *
+ * For everything else, we want to lookup to succeed.
+ *
+ * One additional note: if CREATE or OPEN succeeded, we add an extra
+ * reference to the request because we need to keep it around until
+ * ll_create/ll_open gets called.
+ *
+ * The server will return to us, in it_disposition, an indication of
+ * exactly what d.lustre.it_status refers to.
+ *
+ * If DISP_OPEN_OPEN is set, then d.lustre.it_status refers to the open() call,
+ * otherwise if DISP_OPEN_CREATE is set, then it status is the
+ * creation failure mode.  In either case, one of DISP_LOOKUP_NEG or
+ * DISP_LOOKUP_POS will be set, indicating whether the child lookup
+ * was successful.
+ *
+ * Else, if DISP_LOOKUP_EXECD then d.lustre.it_status is the rc of the
+ * child lookup.
+ */
+int mdc_intent_lock(struct obd_export *exp, struct ll_uctxt *uctxt,
+                    struct ll_fid *pfid, const char *name, int len,
+                    void *lmm, int lmmsize,
+                    struct ll_fid *cfid, struct lookup_intent *it, int flags,
+                    struct ptlrpc_request **reqp,
+                    ldlm_blocking_callback cb_blocking)
+{
+        struct lustre_handle lockh;
+        struct ptlrpc_request *request;
+        int rc = 0;
+        struct mds_body *mds_body;
+        struct lustre_handle old_lock;
+        struct ldlm_lock *lock;
+        ENTRY;
+        LASSERT(it);
+
+        CDEBUG(D_DLMTRACE, "name: %*s in %ld, intent: %s\n", len, name,
+               (unsigned long) pfid->id, ldlm_it2str(it->it_op));
+
+        if (cfid && (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR)) {
+                /* We could just return 1 immediately, but since we should only
+                 * be called in revalidate_it if we already have a lock, let's
+                 * verify that. */
+                struct ldlm_res_id res_id ={.name = {cfid->id, 
+                                                     cfid->generation}};
+                struct lustre_handle lockh;
+                int mode, flags = LDLM_FL_BLOCK_GRANTED;
+
+                mode = LCK_PR;
+                rc = ldlm_lock_match(exp->exp_obd->obd_namespace, flags,
+                                     &res_id, LDLM_PLAIN, NULL, 0, LCK_PR,
+                                     &lockh);
+                if (!rc) {
+                        mode = LCK_PW;
+                        rc = ldlm_lock_match(exp->exp_obd->obd_namespace, flags,
+                                             &res_id, LDLM_PLAIN, NULL, 0,
+                                             LCK_PW, &lockh);
+                }
+                if (rc) {
+                        memcpy(&it->d.lustre.it_lock_handle, &lockh, 
+                               sizeof(lockh));
+                        it->d.lustre.it_lock_mode = mode;
+                }
+                RETURN(rc);
+        }
+
+        /* lookup_it may be called only after revalidate_it has run, because
+         * revalidate_it cannot return errors, only zero.  Returning zero causes
+         * this call to lookup, which *can* return an error.
+         *
+         * We only want to execute the request associated with the intent one
+         * time, however, so don't send the request again.  Instead, skip past
+         * this and use the request from revalidate.  In this case, revalidate
+         * never dropped its reference, so the refcounts are all OK */
+        if (!it_disposition(it, DISP_ENQ_COMPLETE)) {
+                struct mdc_op_data op_data;
+                mdc_fid2mdc_op_data(&op_data, uctxt, pfid, cfid, name, len, 0);
+
+                rc = mdc_enqueue(exp, LDLM_PLAIN, it, it_to_lock_mode(it),
+                                 &op_data, &lockh, lmm, lmmsize,
+                                 ldlm_completion_ast, cb_blocking, NULL);
+                if (rc < 0)
+                        RETURN(rc);
+                memcpy(&it->d.lustre.it_lock_handle, &lockh, sizeof(lockh));
+        }
+        request = *reqp = it->d.lustre.it_data;
+        LASSERT(request != NULL);
+
+        if (!it_disposition(it, DISP_IT_EXECD)) {
+                /* The server failed before it even started executing the
+                 * intent, i.e. because it couldn't unpack the request. */
+                LASSERT(it->d.lustre.it_status != 0);
+                RETURN(it->d.lustre.it_status);
+        }
+        rc = it_open_error(DISP_IT_EXECD, it);
+        if (rc)
+                RETURN(rc);
+
+        mds_body = lustre_msg_buf(request->rq_repmsg, 1, sizeof(*mds_body));
+        LASSERT(mds_body != NULL);           /* mdc_enqueue checked */
+        LASSERT_REPSWABBED(request, 1); /* mdc_enqueue swabbed */
+
+        /* If we were revalidating a fid/name pair, mark the intent in
+         * case we fail and get called again from lookup */
+        if (cfid != NULL) {
+                it_set_disposition(it, DISP_ENQ_COMPLETE);
+                /* Also: did we find the same inode? */
+                if (memcmp(cfid, &mds_body->fid1, sizeof(*cfid)))
+                        RETURN(-ESTALE);
+        }
+
+        /* If we're doing an IT_OPEN which did not result in an actual
+         * successful open, then we need to remove the bit which saves
+         * this request for unconditional replay. */
+        if (it->it_op & IT_OPEN) {
+                if (!it_disposition(it, DISP_OPEN_OPEN) ||
+                    it->d.lustre.it_status != 0) {
+                        unsigned long flags;
+
+                        spin_lock_irqsave(&request->rq_lock, flags);
+                        request->rq_replay = 0;
+                        spin_unlock_irqrestore(&request->rq_lock, flags);
+                }
+        }
+
+        rc = it_open_error(DISP_LOOKUP_EXECD, it);
+        if (rc)
+                RETURN(rc);
+
+        /* keep requests around for the multiple phases of the call
+         * this shows the DISP_XX must guarantee we make it into the call
+         */
+        if (it_disposition(it, DISP_OPEN_CREATE) &&
+            !it_open_error(DISP_OPEN_CREATE, it))
+                ptlrpc_request_addref(request);
+        if (it_disposition(it, DISP_OPEN_OPEN) &&
+            !it_open_error(DISP_OPEN_OPEN, it))
+                ptlrpc_request_addref(request);
+
+        if (it->it_op & IT_CREAT) {
+                /* XXX this belongs in ll_create_iit */
+        } else if (it->it_op == IT_OPEN) {
+                LASSERT(!it_disposition(it, DISP_OPEN_CREATE));
+        } else {
+                LASSERT(it->it_op & (IT_GETATTR | IT_LOOKUP));
+        }
+
+        /* If we already have a matching lock, then cancel the new
+         * one.  We have to set the data here instead of in
+         * mdc_enqueue, because we need to use the child's inode as
+         * the l_ast_data to match, and that's not available until
+         * intent_finish has performed the iget().) */
+        lock = ldlm_handle2lock(&lockh);
+        if (lock) {
+                LDLM_DEBUG(lock, "matching against this");
+                LDLM_LOCK_PUT(lock);
+                memcpy(&old_lock, &lockh, sizeof(lockh));
+                if (ldlm_lock_match(NULL, LDLM_FL_BLOCK_GRANTED, NULL,
+                                    LDLM_PLAIN, NULL, 0, LCK_NL, &old_lock)) {
+                        ldlm_lock_decref_and_cancel(&lockh,
+                                                    it->d.lustre.it_lock_mode);
+                        memcpy(&lockh, &old_lock, sizeof(old_lock));
+                        memcpy(&it->d.lustre.it_lock_handle, &lockh,
+                               sizeof(lockh));
+                }
+        }
+        CDEBUG(D_DENTRY, "D_IT dentry %*s intent: %s status %d disp %x rc %d\n",
+               len, name, ldlm_it2str(it->it_op), it->d.lustre.it_status,
+               it->d.lustre.it_disposition, rc);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(mdc_intent_lock);
diff --git a/lustre/mdc/mdc_reint.c b/lustre/mdc/mdc_reint.c
index 4f7443e8a9d8f6d4386a9e9f70b59b5092498ee5..d09227029db1d6c815f2323acd6343d3104cb392 100644
--- a/lustre/mdc/mdc_reint.c
+++ b/lustre/mdc/mdc_reint.c
@@ -19,7 +19,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDC
 
 #ifdef __KERNEL__
@@ -41,7 +43,7 @@ static int mdc_reint(struct ptlrpc_request *request,
         int rc;
         
 
-        request->rq_level = level;
+        request->rq_send_state = level;
 
         mdc_get_rpc_lock(rpc_lock, NULL);
         rc = ptlrpc_queue_wait(request);
@@ -62,13 +64,14 @@ static int mdc_reint(struct ptlrpc_request *request,
  * If it is called with iattr->ia_valid & ATTR_FROM_OPEN, then it is a
  * magic open-path setattr that should take the setattr semaphore and
  * go to the setattr portal. */
-int mdc_setattr(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len,
                 struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
         struct mds_rec_setattr *rec;
         struct mdc_rpc_lock *rpc_lock;
+        struct obd_device *obd = exp->exp_obd;
         int rc, bufcount = 1, size[3] = {sizeof(*rec), ealen, ea2len};
         ENTRY;
 
@@ -80,27 +83,27 @@ int mdc_setattr(struct lustre_handle *conn, struct mdc_op_data *data,
                         bufcount = 3;
         }
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_REINT, bufcount,
                               size, NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
 
         if (iattr->ia_valid & ATTR_FROM_OPEN) {
                 req->rq_request_portal = MDS_SETATTR_PORTAL; //XXX FIXME bug 249
-                rpc_lock = &mdc_setattr_lock;
+                rpc_lock = obd->u.cli.cl_setattr_lock;
         } else {
-                rpc_lock = &mdc_rpc_lock;
+                rpc_lock = obd->u.cli.cl_rpc_lock;
         }
 
         if (iattr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n",
-                       iattr->ia_mtime, iattr->ia_ctime);
+                       LTIME_S(iattr->ia_mtime), LTIME_S(iattr->ia_ctime));
         mdc_setattr_pack(req, data, iattr, ea, ealen, ea2, ea2len);
 
         size[0] = sizeof(struct mds_body);
         req->rq_replen = lustre_msg_size(1, size);
 
-        rc = mdc_reint(req, rpc_lock, LUSTRE_CONN_FULL);
+        rc = mdc_reint(req, rpc_lock, LUSTRE_IMP_FULL);
         *request = req;
         if (rc == -ERESTARTSYS)
                 rc = 0;
@@ -108,10 +111,11 @@ int mdc_setattr(struct lustre_handle *conn, struct mdc_op_data *data,
         RETURN(rc);
 }
 
-int mdc_create(struct lustre_handle *conn, struct mdc_op_data *op_data,
+int mdc_create(struct obd_export *exp, struct mdc_op_data *op_data,
                const void *data, int datalen, int mode, __u32 uid, __u32 gid,
-               __u64 time, __u64 rdev, struct ptlrpc_request **request)
+               __u64 rdev, struct ptlrpc_request **request)
 {
+        struct obd_device *obd = exp->exp_obd;
         struct ptlrpc_request *req;
         int rc, size[3] = {sizeof(struct mds_rec_create), op_data->namelen + 1};
         int level, bufcount = 2;
@@ -122,25 +126,24 @@ int mdc_create(struct lustre_handle *conn, struct mdc_op_data *op_data,
                 bufcount++;
         }
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_REINT, bufcount,
                               size, NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
 
         /* mdc_create_pack fills msg->bufs[1] with name
          * and msg->bufs[2] with tgt, for symlinks or lov MD data */
-        mdc_create_pack(req, 0, op_data, mode, rdev, uid, gid, time,
-                        data, datalen);
+        mdc_create_pack(req, 0, op_data, mode, rdev, data, datalen);
 
         size[0] = sizeof(struct mds_body);
         req->rq_replen = lustre_msg_size(1, size);
 
-        level = LUSTRE_CONN_FULL;
+        level = LUSTRE_IMP_FULL;
  resend:
-        rc = mdc_reint(req, &mdc_rpc_lock, level);
+        rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, level);
         /* Resend if we were told to. */
         if (rc == -ERESTARTSYS) {
-                level = LUSTRE_CONN_RECOVER;
+                level = LUSTRE_IMP_RECOVER;
                 goto resend;
         }
 
@@ -151,16 +154,16 @@ int mdc_create(struct lustre_handle *conn, struct mdc_op_data *op_data,
         RETURN(rc);
 }
 
-int mdc_unlink(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_unlink(struct obd_export *exp, struct mdc_op_data *data,
                struct ptlrpc_request **request)
 {
-        struct obd_device *obddev = class_conn2obd(conn);
+        struct obd_device *obddev = class_exp2obd(exp);
         struct ptlrpc_request *req = *request;
         int rc, size[2] = {sizeof(struct mds_rec_unlink), data->namelen + 1};
         ENTRY;
 
         LASSERT(req == NULL);
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_REINT, 2, size,
                               NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
@@ -173,20 +176,21 @@ int mdc_unlink(struct lustre_handle *conn, struct mdc_op_data *data,
 
         mdc_unlink_pack(req, 0, data);
 
-        rc = mdc_reint(req, &mdc_rpc_lock, LUSTRE_CONN_FULL);
+        rc = mdc_reint(req, obddev->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
         if (rc == -ERESTARTSYS)
                 rc = 0;
         RETURN(rc);
 }
 
-int mdc_link(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_link(struct obd_export *exp, struct mdc_op_data *data,
              struct ptlrpc_request **request)
 {
+        struct obd_device *obd = exp->exp_obd;
         struct ptlrpc_request *req;
         int rc, size[2] = {sizeof(struct mds_rec_link), data->namelen + 1};
         ENTRY;
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_REINT, 2, size,
                               NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
@@ -196,7 +200,7 @@ int mdc_link(struct lustre_handle *conn, struct mdc_op_data *data,
         size[0] = sizeof(struct mds_body);
         req->rq_replen = lustre_msg_size(1, size);
 
-        rc = mdc_reint(req, &mdc_rpc_lock, LUSTRE_CONN_FULL);
+        rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
         *request = req;
         if (rc == -ERESTARTSYS)
                 rc = 0;
@@ -204,16 +208,17 @@ int mdc_link(struct lustre_handle *conn, struct mdc_op_data *data,
         RETURN(rc);
 }
 
-int mdc_rename(struct lustre_handle *conn, struct mdc_op_data *data,
+int mdc_rename(struct obd_export *exp, struct mdc_op_data *data,
                const char *old, int oldlen, const char *new, int newlen,
                struct ptlrpc_request **request)
 {
+        struct obd_device *obd = exp->exp_obd;
         struct ptlrpc_request *req;
         int rc, size[3] = {sizeof(struct mds_rec_rename), oldlen + 1,
                            newlen + 1};
         ENTRY;
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 3, size,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_REINT, 3, size,
                               NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
@@ -221,9 +226,10 @@ int mdc_rename(struct lustre_handle *conn, struct mdc_op_data *data,
         mdc_rename_pack(req, 0, data, old, oldlen, new, newlen);
 
         size[0] = sizeof(struct mds_body);
-        req->rq_replen = lustre_msg_size(1, size);
+        size[1] = obd->u.cli.cl_max_mds_easize;
+        req->rq_replen = lustre_msg_size(2, size);
 
-        rc = mdc_reint(req, &mdc_rpc_lock, LUSTRE_CONN_FULL);
+        rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
         *request = req;
         if (rc == -ERESTARTSYS)
                 rc = 0;
diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c
index 27f37175dd593e7b161f52f59f27be004915d2ca..d69f62490803f221cd2db4511c0b31ae69433bbd 100644
--- a/lustre/mdc/mdc_request.c
+++ b/lustre/mdc/mdc_request.c
@@ -19,7 +19,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDC
 
 #ifdef __KERNEL__
@@ -29,11 +31,10 @@
 # include <linux/init.h>
 #else
 # include <liblustre.h>
-# include <linux/obd_class.h>
 #endif
 
+#include <linux/obd_class.h>
 #include <linux/lustre_mds.h>
-#include <linux/lustre_lite.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lprocfs_status.h>
 #include "mdc_internal.h"
@@ -41,10 +42,6 @@
 #define REQUEST_MINOR 244
 
 extern int mds_queue_req(struct ptlrpc_request *);
-struct mdc_rpc_lock mdc_rpc_lock;
-struct mdc_rpc_lock mdc_setattr_lock;
-EXPORT_SYMBOL(mdc_rpc_lock);
-
 /* Helper that implements most of mdc_getstatus and signal_completed_replay. */
 /* XXX this should become mdc_get_info("key"), sending MDS_GET_INFO RPC */
 static int send_getstatus(struct obd_import *imp, struct ll_fid *rootfid,
@@ -60,7 +57,7 @@ static int send_getstatus(struct obd_import *imp, struct ll_fid *rootfid,
                 GOTO(out, rc = -ENOMEM);
 
         body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-        req->rq_level = level;
+        req->rq_send_state = level;
         req->rq_replen = lustre_msg_size(1, &size);
 
         mdc_pack_req_body(req);
@@ -90,84 +87,14 @@ static int send_getstatus(struct obd_import *imp, struct ll_fid *rootfid,
 }
 
 /* This should be mdc_get_info("rootfid") */
-int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid)
+int mdc_getstatus(struct obd_export *exp, struct ll_fid *rootfid)
 {
-        return send_getstatus(class_conn2cliimp(conn), rootfid, LUSTRE_CONN_CON,
+        return send_getstatus(class_exp2cliimp(exp), rootfid, LUSTRE_IMP_FULL,
                               0);
 }
 
-/* should call mdc_get_info("lovdesc") and mdc_get_info("lovtgts") */
-int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh,
-                   struct ptlrpc_request **request)
-{
-        struct ptlrpc_request *req;
-        struct mds_status_req *streq;
-        struct lov_desc       *desc;
-        struct obd_uuid       *uuids;
-        int rc, size[2] = {sizeof(*streq)};
-        int i;
-        ENTRY;
-
-        req = ptlrpc_prep_req(class_conn2cliimp(mdc_connh), MDS_GETLOVINFO, 1,
-                              size, NULL);
-        if (!req)
-                RETURN (-ENOMEM);
-
-        *request = req;
-        streq = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*streq));
-        streq->flags = MDS_STATUS_LOV;
-        streq->repbuf = LOV_MAX_UUID_BUFFER_SIZE;
-
-        /* prepare for reply */
-        req->rq_level = LUSTRE_CONN_CON;
-        size[0] = sizeof (*desc);
-        size[1] = LOV_MAX_UUID_BUFFER_SIZE;
-        req->rq_replen = lustre_msg_size(2, size);
-
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
-        rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
-
-        if (rc != 0) {
-                CERROR ("rcp failed\n");
-                GOTO (failed, rc);
-        }
-
-        desc = lustre_swab_repbuf (req, 0, sizeof (*desc),
-                                   lustre_swab_lov_desc);
-        if (desc == NULL) {
-                CERROR ("Can't unpack lov_desc\n");
-                GOTO (failed, rc = -EPROTO);
-        }
-
-        LASSERT_REPSWAB (req, 1);
-        /* array of uuids byte-sex insensitive; just verify they are all
-         * there and terminated */
-        uuids = lustre_msg_buf (req->rq_repmsg, 1,
-                                desc->ld_tgt_count * sizeof (*uuids));
-        if (uuids == NULL) {
-                CERROR ("Can't unpack %d uuids\n", desc->ld_tgt_count);
-                GOTO (failed, rc = -EPROTO);
-        }
-
-        for (i = 0; i < desc->ld_tgt_count; i++) {
-                int uid_len = strnlen (uuids[i].uuid, sizeof (uuids[i].uuid));
-
-                if (uid_len == sizeof (uuids[i].uuid)) {
-                        CERROR ("Unterminated uuid %d:%*s\n",
-                                i, (int)sizeof (uuids[i].uuid), uuids[i].uuid);
-                        GOTO (failed, rc = -EPROTO);
-                }
-        }
-        RETURN(0);
-
- failed:
-        ptlrpc_req_finished (req);
-        RETURN (rc);
-}
-
-int mdc_getattr_common (struct lustre_handle *conn,
-                        unsigned int ea_size, struct ptlrpc_request *req)
+int mdc_getattr_common(struct obd_export *exp, unsigned int ea_size, 
+                       struct ptlrpc_request *req)
 {
         struct mds_body *body;
         void            *eadata;
@@ -185,9 +112,9 @@ int mdc_getattr_common (struct lustre_handle *conn,
         }
         req->rq_replen = lustre_msg_size(bufcount, size);
 
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
         rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
         if (rc != 0)
                 RETURN (rc);
 
@@ -213,7 +140,7 @@ int mdc_getattr_common (struct lustre_handle *conn,
         RETURN (0);
 }
 
-int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
+int mdc_getattr(struct obd_export *exp, struct ll_fid *fid,
                 unsigned long valid, unsigned int ea_size,
                 struct ptlrpc_request **request)
 {
@@ -226,7 +153,7 @@ int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
         /* XXX do we need to make another request here?  We just did a getattr
          *     to do the lookup in the first place.
          */
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETATTR, 1, &size,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_GETATTR, 1, &size,
                               NULL);
         if (!req)
                 GOTO(out, rc = -ENOMEM);
@@ -237,7 +164,7 @@ int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
         body->eadatasize = ea_size;
         mdc_pack_req_body(req);
 
-        rc = mdc_getattr_common (conn, ea_size, req);
+        rc = mdc_getattr_common(exp, ea_size, req);
         if (rc != 0) {
                 ptlrpc_req_finished (req);
                 req = NULL;
@@ -247,7 +174,7 @@ int mdc_getattr(struct lustre_handle *conn, struct ll_fid *fid,
         RETURN (rc);
 }
 
-int mdc_getattr_name(struct lustre_handle *conn, struct ll_fid *fid,
+int mdc_getattr_name(struct obd_export *exp, struct ll_fid *fid,
                      char *filename, int namelen, unsigned long valid,
                      unsigned int ea_size, struct ptlrpc_request **request)
 {
@@ -256,7 +183,7 @@ int mdc_getattr_name(struct lustre_handle *conn, struct ll_fid *fid,
         int rc, size[2] = {sizeof(*body), namelen};
         ENTRY;
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETATTR_NAME, 2,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_GETATTR_NAME, 2,
                               size, NULL);
         if (!req)
                 GOTO(out, rc = -ENOMEM);
@@ -270,14 +197,14 @@ int mdc_getattr_name(struct lustre_handle *conn, struct ll_fid *fid,
         LASSERT (strnlen (filename, namelen) == namelen - 1);
         memcpy(lustre_msg_buf(req->rq_reqmsg, 1, namelen), filename, namelen);
 
-        rc = mdc_getattr_common (conn, ea_size, req);
+        rc = mdc_getattr_common(exp, ea_size, req);
         if (rc != 0) {
                 ptlrpc_req_finished (req);
                 req = NULL;
         }
  out:
         *request = req;
-        return rc;
+        RETURN(rc);
 }
 
 /* This should be called with both the request and the reply still packed. */
@@ -293,12 +220,12 @@ void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff,
         LASSERT (body != NULL);
 
         memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid);
-        DEBUG_REQ(D_HA, req, "storing generation %x for ino "LPD64,
+        DEBUG_REQ(D_HA, req, "storing generation %u for ino "LPU64,
                   rec->cr_replayfid.generation, rec->cr_replayfid.id);
 }
 
 int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
-                      struct lustre_handle *obd_import,
+                      struct obd_export *exp,
                       struct lustre_md *md)
 {
         int rc = 0;
@@ -326,7 +253,7 @@ int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
                 LASSERT (lmm != NULL);
                 LASSERT_REPSWABBED (req, offset + 1);
 
-                rc = obd_unpackmd(obd_import, &md->lsm, lmm, lmmsize);
+                rc = obd_unpackmd(exp, &md->lsm, lmm, lmmsize);
                 if (rc >= 0) {
                         LASSERT (rc >= sizeof (*md->lsm));
                         rc = 0;
@@ -335,263 +262,192 @@ int mdc_req2lustre_md(struct ptlrpc_request *req, int offset,
         RETURN(rc);
 }
 
-
-/* We always reserve enough space in the reply packet for a stripe MD, because
- * we don't know in advance the file type. */
-int mdc_enqueue(struct lustre_handle *conn,
-                int lock_type,
-                struct lookup_intent *it,
-                int lock_mode,
-                struct mdc_op_data *data,
-                struct lustre_handle *lockh,
-                char *tgt,
-                int tgtlen,
-                ldlm_completion_callback cb_completion,
-                ldlm_blocking_callback cb_blocking,
-                void *cb_data)
+static void mdc_commit_open(struct ptlrpc_request *req)
 {
-        struct ptlrpc_request *req;
-        struct obd_device *obddev = class_conn2obd(conn);
-        struct ldlm_res_id res_id =
-                { .name = {data->ino1, data->gen1} };
-        int size[6] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)};
-        int rc, flags = LDLM_FL_HAS_INTENT;
-        int repsize[4] = {sizeof(struct ldlm_reply),
-                          sizeof(struct mds_body),
-                          obddev->u.cli.cl_max_mds_easize,
-                          obddev->u.cli.cl_max_mds_cookiesize};
-        struct ldlm_reply *dlm_rep;
-        struct ldlm_intent *lit;
-        struct ldlm_request *lockreq;
-        void *eadata;
-        unsigned long irqflags;
-        int   reply_buffers = 0;
-        ENTRY;
-
-//        LDLM_DEBUG_NOLOCK("mdsintent=%s,name=%s,dir=%lu",
-//                          ldlm_it2str(it->it_op), it_name, it_inode->i_ino);
-
-        if (it->it_op & IT_OPEN) {
-                it->it_mode |= S_IFREG;
-                it->it_mode &= ~current->fs->umask;
-
-                size[2] = sizeof(struct mds_rec_create);
-                size[3] = data->namelen + 1;
-                req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4,
-                                      size, NULL);
-                if (!req)
-                        RETURN(-ENOMEM);
-
-                spin_lock_irqsave (&req->rq_lock, irqflags);
-                req->rq_replay = 1;
-                spin_unlock_irqrestore (&req->rq_lock, irqflags);
-
-                /* pack the intent */
-                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
-                lit->opc = (__u64)it->it_op;
-
-                /* pack the intended request */
-                mdc_open_pack(req, 2, data, it->it_mode, 0, current->fsuid,
-                              current->fsgid, LTIME_S(CURRENT_TIME),
-                              it->it_flags, tgt, tgtlen);
-                /* get ready for the reply */
-                reply_buffers = 3;
-                req->rq_replen = lustre_msg_size(3, repsize);
-        } else if (it->it_op & IT_UNLINK) {
-                size[2] = sizeof(struct mds_rec_unlink);
-                size[3] = data->namelen + 1;
-                req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4,
-                                      size, NULL);
-                if (!req)
-                        RETURN(-ENOMEM);
-
-                /* pack the intent */
-                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
-                lit->opc = (__u64)it->it_op;
-
-                /* pack the intended request */
-                mdc_unlink_pack(req, 2, data);
-                /* get ready for the reply */
-                reply_buffers = 4;
-                req->rq_replen = lustre_msg_size(4, repsize);
-        } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) {
-                int valid = OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE;
-                size[2] = sizeof(struct mds_body);
-                size[3] = data->namelen + 1;
-
-                req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4,
-                                      size, NULL);
-                if (!req)
-                        RETURN(-ENOMEM);
-
-                /* pack the intent */
-                lit = lustre_msg_buf(req->rq_reqmsg, 1, sizeof (*lit));
-                lit->opc = (__u64)it->it_op;
-
-                /* pack the intended request */
-                mdc_getattr_pack(req, valid, 2, it->it_flags, data);
-                /* get ready for the reply */
-                reply_buffers = 3;
-                req->rq_replen = lustre_msg_size(3, repsize);
-        } else if (it->it_op == IT_READDIR) {
-                req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 1,
-                                      size, NULL);
-                if (!req)
-                        RETURN(-ENOMEM);
-
-                /* get ready for the reply */
-                reply_buffers = 1;
-                req->rq_replen = lustre_msg_size(1, repsize);
-        }  else {
-                LBUG();
-                RETURN(-EINVAL);
-        }
-
-        mdc_get_rpc_lock(&mdc_rpc_lock, it);
-        rc = ldlm_cli_enqueue(conn, req, obddev->obd_namespace, NULL, res_id,
-                              lock_type, NULL, 0, lock_mode, &flags,
-                              cb_completion, cb_blocking, cb_data, lockh);
-        mdc_put_rpc_lock(&mdc_rpc_lock, it);
-
-        /* Similarly, if we're going to replay this request, we don't want to
-         * actually get a lock, just perform the intent. */
-        if (req->rq_transno || req->rq_replay) {
-                lockreq = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*lockreq));
-                lockreq->lock_flags |= LDLM_FL_INTENT_ONLY;
-        }
+        struct mdc_open_data *mod = req->rq_cb_data;
+        if (mod == NULL)
+                return;
 
-        /* This can go when we're sure that this can never happen */
-        LASSERT(rc != -ENOENT);
-        if (rc == ELDLM_LOCK_ABORTED) {
-                lock_mode = 0;
-                memset(lockh, 0, sizeof(*lockh));
-        } else if (rc != 0) {
-                CERROR("ldlm_cli_enqueue: %d\n", rc);
-                LASSERT (rc < 0);
-                ptlrpc_req_finished(req);
-                RETURN(rc);
-        } else { /* rc = 0 */
-                struct ldlm_lock *lock = ldlm_handle2lock(lockh);
-                LASSERT(lock);
-
-                /* If the server gave us back a different lock mode, we should
-                 * fix up our variables. */
-                if (lock->l_req_mode != lock_mode) {
-                        ldlm_lock_addref(lockh, lock->l_req_mode);
-                        ldlm_lock_decref(lockh, lock_mode);
-                        lock_mode = lock->l_req_mode;
-                }
-
-                LDLM_LOCK_PUT(lock);
-        }
-
-        dlm_rep = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*dlm_rep));
-        LASSERT(dlm_rep != NULL);           /* checked by ldlm_cli_enqueue() */
-        LASSERT_REPSWABBED(req, 0);         /* swabbed by ldlm_cli_enqueue() */
-
-        it->it_disposition = (int) dlm_rep->lock_policy_res1;
-        it->it_status = (int) dlm_rep->lock_policy_res2;
-        it->it_lock_mode = lock_mode;
-        it->it_data = req;
-
-        /* We know what to expect, so we do any byte flipping required here */
-        LASSERT(reply_buffers == 4 || reply_buffers == 3 || reply_buffers == 1);
-        if (reply_buffers >= 3) {
-                struct mds_body *body;
-
-                body = lustre_swab_repbuf (req, 1, sizeof (*body),
-                                           lustre_swab_mds_body);
-                if (body == NULL) {
-                        CERROR ("Can't swab mds_body\n");
-                        RETURN (-EPROTO);
-                }
+        if (mod->mod_close_req != NULL)
+                mod->mod_close_req->rq_cb_data = NULL;
 
-                if ((body->valid & OBD_MD_FLEASIZE) != 0) {
-                        /* The eadata is opaque; just check that it is
-                         * there.  Eventually, obd_unpackmd() will check
-                         * the contents */
-                        eadata = lustre_swab_repbuf(req, 2, body->eadatasize,
-                                                    NULL);
-                        if (eadata == NULL) {
-                                CERROR ("Missing/short eadata\n");
-                                RETURN (-EPROTO);
-                        }
-                }
-        }
+        if (mod->mod_och != NULL)
+                mod->mod_och->och_mod = NULL;
 
-        RETURN(rc);
+        OBD_FREE(mod, sizeof(*mod));
+        req->rq_cb_data = NULL;
 }
 
 static void mdc_replay_open(struct ptlrpc_request *req)
 {
-        struct obd_client_handle *och = req->rq_replay_data;
-        struct lustre_handle old, *file_fh = &och->och_fh;
-        struct list_head *tmp;
+        struct mdc_open_data *mod = req->rq_cb_data;
+        struct obd_client_handle *och;
+        struct ptlrpc_request *close_req;
+        struct lustre_handle old; 
         struct mds_body *body;
+        ENTRY;
 
         body = lustre_swab_repbuf(req, 1, sizeof(*body), lustre_swab_mds_body);
         LASSERT (body != NULL);
 
-        memcpy(&old, file_fh, sizeof(old));
-        CDEBUG(D_HA, "updating handle from "LPD64" to "LPD64"\n",
-               file_fh->cookie, body->handle.cookie);
-        memcpy(file_fh, &body->handle, sizeof(body->handle));
-
-        /* A few frames up, ptlrpc_replay holds the lock, so this is safe. */
-        list_for_each(tmp, &req->rq_import->imp_sending_list) {
-                req = list_entry(tmp, struct ptlrpc_request, rq_list);
-                if (req->rq_reqmsg->opc != MDS_CLOSE)
-                        continue;
-                body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-                if (memcmp(&body->handle, &old, sizeof(old)))
-                        continue;
+        if (mod == NULL) {
+                DEBUG_REQ(D_ERROR, req,
+                          "can't properly replay without open data");
+                EXIT;
+                return;
+        }
 
-                DEBUG_REQ(D_HA, req, "updating close body with new fh");
-                memcpy(&body->handle, file_fh, sizeof(*file_fh));
+        och = mod->mod_och;
+        if (och != NULL) {
+                struct lustre_handle *file_fh; 
+                LASSERT(och->och_magic == OBD_CLIENT_HANDLE_MAGIC);
+                file_fh = &och->och_fh;
+                CDEBUG(D_HA, "updating handle from "LPX64" to "LPX64"\n",
+                       file_fh->cookie, body->handle.cookie);
+                memcpy(&old, file_fh, sizeof(old));
+                memcpy(file_fh, &body->handle, sizeof(*file_fh));
+        } 
+
+        close_req = mod->mod_close_req;
+        if (close_req != NULL) {
+                struct mds_body *close_body;
+                LASSERT(close_req->rq_reqmsg->opc == MDS_CLOSE);
+                close_body = lustre_msg_buf(close_req->rq_reqmsg, 0,
+                                            sizeof(*close_body));
+                if (och != NULL)
+                        LASSERT(!memcmp(&old, &close_body->handle, sizeof old));
+                DEBUG_REQ(D_HA, close_req, "updating close body with new fh");
+                memcpy(&close_body->handle, &body->handle,
+                       sizeof(close_body->handle));
         }
+
+        EXIT;
 }
 
-void mdc_set_open_replay_data(struct obd_client_handle *och)
+void mdc_set_open_replay_data(struct obd_client_handle *och,
+                              struct ptlrpc_request *open_req)
 {
-        struct ptlrpc_request *req = och->och_req;
+        struct mdc_open_data *mod;
         struct mds_rec_create *rec =
-                lustre_msg_buf(req->rq_reqmsg, 2, sizeof(*rec));
+                lustre_msg_buf(open_req->rq_reqmsg, 2, sizeof(*rec));
         struct mds_body *body =
-                lustre_msg_buf(req->rq_repmsg, 1, sizeof(*body));
+                lustre_msg_buf(open_req->rq_repmsg, 1, sizeof(*body));
 
         LASSERT(rec != NULL);
         /* outgoing messages always in my byte order */
         LASSERT(body != NULL);
         /* incoming message in my byte order (it's been swabbed) */
-        LASSERT_REPSWABBED(req, 1);
+        LASSERT_REPSWABBED(open_req, 1);
+
+        OBD_ALLOC(mod, sizeof(*mod));
+        if (mod == NULL) {
+                DEBUG_REQ(D_ERROR, open_req, "can't allocate mdc_open_data");
+                return;
+        }
+
+        och->och_mod = mod;
+        mod->mod_och = och;
+        mod->mod_open_req = open_req;
 
         memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid);
-        req->rq_replay_cb = mdc_replay_open;
-        req->rq_replay_data = och;
+        open_req->rq_replay_cb = mdc_replay_open;
+        open_req->rq_commit_cb = mdc_commit_open;
+        open_req->rq_cb_data = mod;
+        DEBUG_REQ(D_HA, open_req, "set up replay data");
 }
 
-int mdc_close(struct lustre_handle *conn, obd_id ino, int type,
-              struct lustre_handle *fh, struct ptlrpc_request **request)
+void mdc_clear_open_replay_data(struct obd_client_handle *och)
+{
+        struct mdc_open_data *mod = och->och_mod;
+
+        /* Don't free the structure now (it happens in mdc_commit_open, after
+         * we're sure we won't need to fix up the close request in the future),
+         * but make sure that replay doesn't poke at the och, which is about to
+         * be freed. */
+        LASSERT(mod != (void *)0x5a5a5a5a);
+        if (mod != NULL)
+                mod->mod_och = NULL;
+        och->och_mod = NULL;
+}
+
+static void mdc_commit_close(struct ptlrpc_request *req)
+{
+        struct mdc_open_data *mod = req->rq_cb_data;
+        struct ptlrpc_request *open_req;
+        struct obd_import *imp = req->rq_import;
+
+        DEBUG_REQ(D_HA, req, "close req committed");
+        if (mod == NULL)
+                return;
+
+        mod->mod_close_req = NULL;
+        req->rq_cb_data = NULL;
+        req->rq_commit_cb = NULL;
+
+        open_req = mod->mod_open_req;
+        LASSERT(open_req != NULL);
+        LASSERT(open_req != (void *)0x5a5a5a5a);
+
+        DEBUG_REQ(D_HA, open_req, "open req balanced");
+        LASSERT(open_req->rq_transno != 0);
+        LASSERT(open_req->rq_import == imp);
+
+        /* We no longer want to preserve this for transno-unconditional
+         * replay. */
+        spin_lock(&open_req->rq_lock);
+        open_req->rq_replay = 0;
+        spin_unlock(&open_req->rq_lock);
+}
+
+int mdc_close(struct obd_export *exp, struct obdo *obdo,
+              struct obd_client_handle *och, struct ptlrpc_request **request)
 {
         struct mds_body *body;
-        int rc, size = sizeof(*body);
+        struct obd_device *obd = class_exp2obd(exp);
+        int reqsize = sizeof(*body);
+        int rc, repsize[3] = {sizeof(*body),
+                              obd->u.cli.cl_max_mds_easize,
+                              obd->u.cli.cl_max_mds_cookiesize};
         struct ptlrpc_request *req;
+        struct mdc_open_data *mod;
         ENTRY;
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_CLOSE, 1, &size,
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_CLOSE, 1, &reqsize,
                               NULL);
-        if (!req)
+        if (req == NULL)
                 GOTO(out, rc = -ENOMEM);
 
-        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-        ll_ino2fid(&body->fid1, ino, 0, type);
-        memcpy(&body->handle, fh, sizeof(body->handle));
-
-        req->rq_replen = lustre_msg_size(0, NULL);
+        /* Ensure that this close's handle is fixed up during replay. */
+        LASSERT(och != NULL);
+        mod = och->och_mod;
+        if (likely(mod != NULL)) {
+                mod->mod_close_req = req;
+                DEBUG_REQ(D_HA, mod->mod_open_req, "matched open req %p",
+                          mod->mod_open_req);
+        } else {
+                CDEBUG(D_HA, "couldn't find open req; expecting close error\n");
+        }
 
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
+        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body));
+        mdc_pack_fid(&body->fid1, obdo->o_id, 0, obdo->o_mode);
+        memcpy(&body->handle, &och->och_fh, sizeof(body->handle));
+        body->size = obdo->o_size;
+        body->blocks = obdo->o_blocks;
+        body->flags = obdo->o_flags;
+        body->valid = obdo->o_valid;
+
+        req->rq_replen = lustre_msg_size(3, repsize);
+        req->rq_commit_cb = mdc_commit_close;
+        LASSERT(req->rq_cb_data == NULL);
+        req->rq_cb_data = mod;
+
+        mdc_get_rpc_lock(obd->u.cli.cl_rpc_lock, NULL);
         rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_put_rpc_lock(obd->u.cli.cl_rpc_lock, NULL);
+
+        if (mod == NULL && rc == 0)
+                CERROR("Unexpected: can't find mdc_open_data, but the close "
+                       "succeeded.  Please tell CFS.\n");
 
         EXIT;
  out:
@@ -599,46 +455,72 @@ int mdc_close(struct lustre_handle *conn, obd_id ino, int type,
         return rc;
 }
 
-int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset,
+int mdc_done_writing(struct obd_export *exp, struct obdo *obdo)
+{
+        struct ptlrpc_request *req;
+        struct mds_body *body;
+        int rc, size = sizeof(*body);
+        ENTRY;
+
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_DONE_WRITING, 1,
+                              &size, NULL);
+        if (req == NULL)
+                RETURN(-ENOMEM);
+
+        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body));
+        mdc_pack_fid(&body->fid1, obdo->o_id, 0, obdo->o_mode);
+        body->size = obdo->o_size;
+        body->blocks = obdo->o_blocks;
+        body->flags = obdo->o_flags;
+        body->valid = obdo->o_valid;
+//        memcpy(&body->handle, &och->och_fh, sizeof(body->handle));
+
+        req->rq_replen = lustre_msg_size(1, &size);
+
+        rc = ptlrpc_queue_wait(req);
+        ptlrpc_req_finished(req);
+        RETURN(rc);
+}
+
+int mdc_readpage(struct obd_export *exp, struct ll_fid *mdc_fid, __u64 offset,
                  struct page *page, struct ptlrpc_request **request)
 {
-        struct obd_import *imp = class_conn2cliimp(conn);
+        struct obd_import *imp = class_exp2cliimp(exp);
         struct ptlrpc_request *req = NULL;
         struct ptlrpc_bulk_desc *desc = NULL;
         struct mds_body *body;
         int rc, size = sizeof(*body);
         ENTRY;
 
-        CDEBUG(D_INODE, "inode: %ld\n", (long)ino);
+        CDEBUG(D_INODE, "inode: %ld\n", (long)mdc_fid->id);
 
         req = ptlrpc_prep_req(imp, MDS_READPAGE, 1, &size, NULL);
-        if (!req)
+        if (req == NULL)
                 GOTO(out, rc = -ENOMEM);
         /* XXX FIXME bug 249 */
         req->rq_request_portal = MDS_READPAGE_PORTAL;
 
-        desc = ptlrpc_prep_bulk_imp (req, BULK_PUT_SINK, MDS_BULK_PORTAL);
-        if (desc == NULL) {
+        desc = ptlrpc_prep_bulk_imp(req, BULK_PUT_SINK, MDS_BULK_PORTAL);
+        if (desc == NULL)
                 GOTO(out, rc = -ENOMEM);
-        }
         /* NB req now owns desc and will free it when it gets freed */
 
         rc = ptlrpc_prep_bulk_page(desc, page, 0, PAGE_CACHE_SIZE);
         if (rc != 0)
                 GOTO(out, rc);
 
-        mdc_readdir_pack(req, offset, PAGE_CACHE_SIZE, ino, type);
+        mdc_readdir_pack(req, offset, PAGE_CACHE_SIZE, mdc_fid);
 
         req->rq_replen = lustre_msg_size(1, &size);
         rc = ptlrpc_queue_wait(req);
 
         if (rc == 0) {
-                LASSERT (desc->bd_page_count == 1);
-                body = lustre_swab_repbuf (req, 0, sizeof (*body),
-                                           lustre_swab_mds_body);
+                LASSERT(desc->bd_page_count == 1);
+                body = lustre_swab_repbuf(req, 0, sizeof(*body),
+                                          lustre_swab_mds_body);
                 if (body == NULL) {
-                        CERROR ("Can't unpack mds_body\n");
-                        GOTO (out, rc = -EPROTO);
+                        CERROR("Can't unpack mds_body\n");
+                        GOTO(out, rc = -EPROTO);
                 }
         }
 
@@ -648,12 +530,13 @@ int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset,
         return rc;
 }
 
-static int mdc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
+static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                          void *karg, void *uarg)
 {
-        struct obd_device *obddev = class_conn2obd(conn);
+        struct obd_device *obd = exp->exp_obd;
         struct obd_ioctl_data *data = karg;
-        struct obd_import *imp = obddev->u.cli.cl_import;
+        struct obd_import *imp = obd->u.cli.cl_import;
+        struct llog_ctxt *ctxt;
         int rc;
         ENTRY;
         
@@ -665,6 +548,20 @@ static int mdc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
                 RETURN(0);
         case IOC_OSC_SET_ACTIVE:
                 RETURN(ptlrpc_set_import_active(imp, data->ioc_offset));
+        case OBD_IOC_PARSE: {
+                ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT);
+                rc = class_config_parse_llog(ctxt, data->ioc_inlbuf1, NULL);
+                RETURN(rc);
+        }
+#ifdef __KERNEL__
+        case OBD_IOC_LLOG_INFO:
+        case OBD_IOC_LLOG_PRINT: {
+                ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
+                rc = llog_ioctl(ctxt, cmd, data);
+                
+                RETURN(rc);
+        }
+#endif
         default:
                 CERROR("osc_ioctl(): unrecognised ioctl %#x\n", cmd);
                 RETURN(-ENOTTY);
@@ -691,9 +588,9 @@ static int mdc_statfs(struct obd_device *obd, struct obd_statfs *osfs,
 
         req->rq_replen = lustre_msg_size(1, &size);
 
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_get_rpc_lock(obd->u.cli.cl_rpc_lock, NULL);
         rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_put_rpc_lock(obd->u.cli.cl_rpc_lock, NULL);
 
         if (rc)
                 GOTO(out, rc);
@@ -712,7 +609,7 @@ out:
         return rc;
 }
 
-static int mdc_pin(struct lustre_handle *conn, obd_id ino, __u32 gen, int type,
+static int mdc_pin(struct obd_export *exp, obd_id ino, __u32 gen, int type,
                    struct obd_client_handle *handle, int flag)
 {
         struct ptlrpc_request *req;
@@ -720,19 +617,19 @@ static int mdc_pin(struct lustre_handle *conn, obd_id ino, __u32 gen, int type,
         int rc, size = sizeof(*body);
         ENTRY;
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_PIN, 1, &size, NULL);
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_PIN, 1, &size, NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
 
         body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-        ll_ino2fid(&body->fid1, ino, gen, type);
+        mdc_pack_fid(&body->fid1, ino, gen, type);
         body->flags = flag;
 
         req->rq_replen = lustre_msg_size(1, &size);
 
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
         rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
         if (rc) {
                 CERROR("pin failed: %d\n", rc);
                 ptlrpc_req_finished(req);
@@ -746,12 +643,19 @@ static int mdc_pin(struct lustre_handle *conn, obd_id ino, __u32 gen, int type,
         }
 
         memcpy(&handle->och_fh, &body->handle, sizeof(body->handle));
-        handle->och_req = req; /* will be dropped by unpin */
         handle->och_magic = OBD_CLIENT_HANDLE_MAGIC;
+
+        OBD_ALLOC(handle->och_mod, sizeof(*handle->och_mod));
+        if (handle->och_mod == NULL) {
+                DEBUG_REQ(D_ERROR, req, "can't allocate mdc_open_data");
+                RETURN(-ENOMEM);
+        }
+        handle->och_mod->mod_open_req = req; /* will be dropped by unpin */
+
         RETURN(rc);
 }
 
-static int mdc_unpin(struct lustre_handle *conn,
+static int mdc_unpin(struct obd_export *exp,
                      struct obd_client_handle *handle, int flag)
 {
         struct ptlrpc_request *req;
@@ -762,8 +666,7 @@ static int mdc_unpin(struct lustre_handle *conn,
         if (handle->och_magic != OBD_CLIENT_HANDLE_MAGIC)
                 RETURN(0);
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_CLOSE, 1, &size,
-                              NULL);
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_CLOSE, 1, &size, NULL);
         if (req == NULL)
                 RETURN(-ENOMEM);
 
@@ -772,15 +675,46 @@ static int mdc_unpin(struct lustre_handle *conn,
         body->flags = flag;
 
         req->rq_replen = lustre_msg_size(0, NULL);
-        mdc_get_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
         rc = ptlrpc_queue_wait(req);
-        mdc_put_rpc_lock(&mdc_rpc_lock, NULL);
+        mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
 
         if (rc != 0)
                 CERROR("unpin failed: %d\n", rc);
 
         ptlrpc_req_finished(req);
-        ptlrpc_req_finished(handle->och_req);
+        ptlrpc_req_finished(handle->och_mod->mod_open_req);
+        OBD_FREE(handle->och_mod, sizeof(*handle->och_mod));
+        RETURN(rc);
+}
+
+int mdc_sync(struct obd_export *exp, struct ll_fid *fid,
+             struct ptlrpc_request **request)
+{
+        struct ptlrpc_request *req;
+        struct mds_body *body;
+        int size = sizeof(*body);
+        int rc;
+        ENTRY;
+
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), MDS_SYNC, 1,&size,NULL);
+        if (!req)
+                RETURN(rc = -ENOMEM);
+
+        if (fid) {
+                body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
+                memcpy(&body->fid1, fid, sizeof(*fid));
+                mdc_pack_req_body(req);
+        }
+
+        req->rq_replen = lustre_msg_size(1, &size);
+
+        rc = ptlrpc_queue_wait(req);
+        if (rc || request == NULL)
+                ptlrpc_req_finished(req);
+        else
+                *request = req;
+
         RETURN(rc);
 }
 
@@ -797,25 +731,149 @@ static int mdc_detach(struct obd_device *dev)
         return lprocfs_obd_detach(dev);
 }
 
+static int mdc_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct client_obd *cli = &obd->u.cli;
+        int rc;
+        ENTRY;
+
+        OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+        if (!cli->cl_rpc_lock)
+                RETURN(-ENOMEM);
+        mdc_init_rpc_lock(cli->cl_rpc_lock);
+        
+        OBD_ALLOC(cli->cl_setattr_lock, sizeof (*cli->cl_setattr_lock));
+        if (!cli->cl_setattr_lock)
+                GOTO(out_free_rpc, rc = -ENOMEM);
+        mdc_init_rpc_lock(cli->cl_setattr_lock);
+
+        rc = client_obd_setup(obd, len, buf);
+        if (rc) {
+                OBD_FREE(cli->cl_setattr_lock, sizeof (*cli->cl_setattr_lock));
+ out_free_rpc:
+                OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+        }
+
+        RETURN(rc);
+}
+
+
+int mdc_postsetup(struct obd_device *obd) 
+{
+        int rc;
+        rc = obd_llog_init(obd, obd, 0, NULL);
+        if (rc) {
+                CERROR("failed to setup llogging subsystems\n");
+        }
+        RETURN(rc);
+}
+
+int mdc_init_ea_size(struct obd_device *obd, char *lov_name)
+{
+        struct client_obd *cli = &obd->u.cli;
+        struct obd_device *lov_obd;
+        struct obd_export *exp;
+        struct lustre_handle conn;
+        struct lov_desc desc;
+        int valsize;
+        int rc;
+
+        lov_obd = class_name2obd(lov_name);
+        if (!lov_obd) {
+                CERROR("MDC cannot locate LOV %s!\n",
+                       lov_name);
+                RETURN(-ENOTCONN);
+        }
+
+        rc = obd_connect(&conn, lov_obd, &obd->obd_uuid);
+        if (rc) {
+                CERROR("MDS cannot connect to LOV %s (%d) - no logging!\n",
+                       lov_name, rc);
+                RETURN(rc);
+        }
+        exp = class_conn2export(&conn);
+
+        valsize = sizeof(desc);
+        rc = obd_get_info(exp, strlen("lovdesc") + 1, "lovdesc", 
+                          &valsize, &desc);
+        if (rc == 0) {
+                cli->cl_max_mds_easize = obd_size_diskmd(exp, NULL);
+                cli->cl_max_mds_cookiesize = desc.ld_tgt_count * 
+                        sizeof(struct llog_cookie);
+        }
+        obd_disconnect(exp, 0);
+        RETURN(rc);
+}
+
+static int mdc_precleanup(struct obd_device *obd, int flags)
+{
+        int rc = 0;
+        
+        rc = obd_llog_finish(obd, 0);
+        if (rc != 0)
+                CERROR("failed to cleanup llogging subsystems\n");
+
+        RETURN(rc);
+}
+
+static int mdc_cleanup(struct obd_device *obd, int flags)
+{
+        struct client_obd *cli = &obd->u.cli;
+ 
+        OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+        OBD_FREE(cli->cl_setattr_lock, sizeof (*cli->cl_setattr_lock));
+
+        return client_obd_cleanup(obd, flags);
+}
+
+
+static int mdc_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                         int count, struct llog_logid *logid)
+{
+        struct llog_ctxt *ctxt;
+        int rc;
+        ENTRY;
+
+        rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
+                        &llog_client_ops);
+        if (rc == 0) {
+                ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
+                ctxt->loc_imp = obd->u.cli.cl_import; 
+        }
+
+        RETURN(rc);
+}
+
+static int mdc_llog_finish(struct obd_device *obd, int count)
+{
+        int rc;
+        ENTRY;
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT));
+        RETURN(rc);
+}
+
 struct obd_ops mdc_obd_ops = {
         o_owner:       THIS_MODULE,
         o_attach:      mdc_attach,
         o_detach:      mdc_detach,
-        o_setup:       client_obd_setup,
-        o_cleanup:     client_obd_cleanup,
-        o_connect:     client_import_connect,
-        o_disconnect:  client_import_disconnect,
+        o_setup:       mdc_setup,
+        o_postsetup:   mdc_postsetup,
+        o_precleanup:  mdc_precleanup,
+        o_cleanup:     mdc_cleanup,
+        o_connect:     client_connect_import,
+        o_disconnect:  client_disconnect_export,
         o_iocontrol:   mdc_iocontrol,
         o_statfs:      mdc_statfs,
         o_pin:         mdc_pin,
         o_unpin:       mdc_unpin,
+        o_llog_init:   mdc_llog_init,
+        o_llog_finish: mdc_llog_finish,
 };
 
 int __init mdc_init(void)
 {
         struct lprocfs_static_vars lvars;
-        mdc_init_rpc_lock(&mdc_rpc_lock);
-        mdc_init_rpc_lock(&mdc_setattr_lock);
         lprocfs_init_vars(mdc, &lvars);
         return class_register_type(&mdc_obd_ops, lvars.module_vars,
                                    LUSTRE_MDC_NAME);
@@ -832,9 +890,8 @@ MODULE_DESCRIPTION("Lustre Metadata Client");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(mdc_req2lustre_md);
+EXPORT_SYMBOL(mdc_change_cbdata);
 EXPORT_SYMBOL(mdc_getstatus);
-EXPORT_SYMBOL(mdc_getlovinfo);
-EXPORT_SYMBOL(mdc_enqueue);
 EXPORT_SYMBOL(mdc_getattr);
 EXPORT_SYMBOL(mdc_getattr_name);
 EXPORT_SYMBOL(mdc_create);
@@ -844,9 +901,12 @@ EXPORT_SYMBOL(mdc_link);
 EXPORT_SYMBOL(mdc_readpage);
 EXPORT_SYMBOL(mdc_setattr);
 EXPORT_SYMBOL(mdc_close);
+EXPORT_SYMBOL(mdc_done_writing);
+EXPORT_SYMBOL(mdc_sync);
 EXPORT_SYMBOL(mdc_set_open_replay_data);
-
+EXPORT_SYMBOL(mdc_clear_open_replay_data);
 EXPORT_SYMBOL(mdc_store_inode_generation);
+EXPORT_SYMBOL(mdc_init_ea_size);
 
 module_init(mdc_init);
 module_exit(mdc_exit);
diff --git a/lustre/mds/Makefile.am b/lustre/mds/Makefile.am
index cb63910abbabf32f34c0bb3c5b656fee235ad756..c52651058987d208b5c01f2d53631028d4c93fd0 100644
--- a/lustre/mds/Makefile.am
+++ b/lustre/mds/Makefile.am
@@ -7,7 +7,7 @@ DEFS=
 MODULE = mds
 modulefs_DATA = mds.o
 EXTRA_PROGRAMS = mds
-mds_SOURCES = mds_lov.c handler.c mds_reint.c mds_fs.c lproc_mds.c mds_open.c \
+mds_SOURCES = mds_log.c mds_unlink_open.c mds_lov.c handler.c mds_reint.c mds_fs.c lproc_mds.c mds_open.c \
 mds_lib.c mds_internal.h
 
 include $(top_srcdir)/Rules
diff --git a/lustre/mds/Makefile.mk b/lustre/mds/Makefile.mk
index 0696bd796d6820cf4bb13fc1e3a5640406b2c30b..495bb0d8cec0f512ec735b8ec7435bc3d896eca5 100644
--- a/lustre/mds/Makefile.mk
+++ b/lustre/mds/Makefile.mk
@@ -7,5 +7,5 @@ include $(src)/../portals/Kernelenv
 
 obj-y += mds.o
 mds-objs := mds_lov.o handler.o mds_reint.o mds_fs.o lproc_mds.o mds_open.o \
-		mds_lib.o
+		mds_lib.o mds_unlink_open.o mds_log.o
 	
diff --git a/lustre/mds/commit_confd.c b/lustre/mds/commit_confd.c
index 557dc554774c82e19cba0d1050918e50a8e9728a..d08bd4bd02faae9e76ec1241cca53ab13e7f203b 100644
--- a/lustre/mds/commit_confd.c
+++ b/lustre/mds/commit_confd.c
@@ -24,13 +24,13 @@ void commit_confd_conf_import(struct obd_import *import,
 
 
         list_for_each_safe(&import->import_cc_list, tmp, save) {
-                struct llog_commit_data *cd;
+                struct llog_canceld_ctxt *cd;
 
                 if (atomic_read(import->import_cc_count) <=
                     lccd->llcconf_lowwater)
                         break;
 
-                cd = list_entry(tmp, struct llog_commit_data *, llcconf_entry);
+                cd = list_entry(tmp, struct llog_canceld_ctxt *, llcconf_entry);
                 atomic_dec(&import->import_cc_count);
                 commit_confd_add_and_fire(cd);
         }
diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c
index 3c5337e6d1557576d4873b5fdfa208738c6ccafd..67b3eb2cdecf35dc21e0b7136f51be2ce2d54f9c 100644
--- a/lustre/mds/handler.c
+++ b/lustre/mds/handler.c
@@ -26,7 +26,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <linux/module.h>
@@ -61,9 +63,9 @@ static int mds_bulk_timeout(void *data)
         struct ptlrpc_bulk_desc *desc = data;
         struct obd_export *exp = desc->bd_export;
 
-        CERROR("bulk send timed out: evicting %s@%s\n",
-               exp->exp_client_uuid.uuid,
-               exp->exp_connection->c_remote_uuid.uuid);
+        DEBUG_REQ(D_ERROR, desc->bd_req,"bulk send timed out: evicting %s@%s\n",
+                  exp->exp_client_uuid.uuid,
+                  exp->exp_connection->c_remote_uuid.uuid);
         ptlrpc_fail_export(exp);
         ptlrpc_abort_bulk (desc);
         RETURN(1);
@@ -71,37 +73,49 @@ static int mds_bulk_timeout(void *data)
 
 /* Assumes caller has already pushed into the kernel filesystem context */
 static int mds_sendpage(struct ptlrpc_request *req, struct file *file,
-                        __u64 offset, __u64 xid)
+                        loff_t offset, int count)
 {
         struct ptlrpc_bulk_desc *desc;
         struct l_wait_info lwi;
-        struct page *page;
-        int rc = 0;
+        struct page **pages;
+        int rc = 0, npages, i, tmpcount, tmpsize = 0;
         ENTRY;
 
-        LASSERT ((offset & (PAGE_CACHE_SIZE - 1)) == 0);
+        LASSERT((offset & (PAGE_SIZE - 1)) == 0); /* I'm dubious about this */
+
+        npages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+        OBD_ALLOC(pages, sizeof(*pages) * npages);
+        if (!pages)
+                GOTO(out, rc = -ENOMEM);
 
         desc = ptlrpc_prep_bulk_exp (req, BULK_PUT_SOURCE, MDS_BULK_PORTAL);
         if (desc == NULL)
-                GOTO(out, rc = -ENOMEM);
+                GOTO(out_free, rc = -ENOMEM);
 
-        LASSERT (PAGE_SIZE == PAGE_CACHE_SIZE);
-        page = alloc_pages (GFP_KERNEL, 0);
-        if (page == NULL)
-                GOTO(cleanup_bulk, rc = -ENOMEM);
+        for (i = 0, tmpcount = count; i < npages; i++, tmpcount -= tmpsize) {
+                tmpsize = tmpcount > PAGE_SIZE ? PAGE_SIZE : tmpcount;
 
-        rc = ptlrpc_prep_bulk_page(desc, page, 0, PAGE_CACHE_SIZE);
-        if (rc != 0)
-                GOTO(cleanup_buf, rc);
+                pages[i] = alloc_pages(GFP_KERNEL, 0);
+                if (pages[i] == NULL)
+                        GOTO(cleanup_buf, rc = -ENOMEM);
 
-        CDEBUG(D_EXT2, "reading %lu@"LPU64" from dir %lu (size %llu)\n",
-               PAGE_CACHE_SIZE, offset, file->f_dentry->d_inode->i_ino,
-               file->f_dentry->d_inode->i_size);
-        rc = fsfilt_readpage(req->rq_export->exp_obd, file, page_address (page),
-                             PAGE_CACHE_SIZE, (loff_t *)&offset);
+                rc = ptlrpc_prep_bulk_page(desc, pages[i], 0, tmpsize);
+                if (rc != 0)
+                        GOTO(cleanup_buf, rc);
+        }
+
+        for (i = 0, tmpcount = count; i < npages; i++, tmpcount -= tmpsize) {
+                tmpsize = tmpcount > PAGE_SIZE ? PAGE_SIZE : tmpcount;
+                CDEBUG(D_EXT2, "reading %u@%llu from dir %lu (size %llu)\n",
+                       tmpsize, offset, file->f_dentry->d_inode->i_ino,
+                       file->f_dentry->d_inode->i_size);
+
+                rc = fsfilt_readpage(req->rq_export->exp_obd, file,
+                                     page_address(pages[i]), tmpsize, &offset);
 
-        if (rc != PAGE_CACHE_SIZE)
-                GOTO(cleanup_buf, rc = -EIO);
+                if (rc != tmpsize)
+                        GOTO(cleanup_buf, rc = -EIO);
+        }
 
         rc = ptlrpc_bulk_put(desc);
         if (rc)
@@ -123,9 +137,13 @@ static int mds_sendpage(struct ptlrpc_request *req, struct file *file,
 
         EXIT;
  cleanup_buf:
-        __free_pages (page, 0);
- cleanup_bulk:
-        ptlrpc_free_bulk (desc);
+        for (i = 0; i < npages; i++)
+                if (pages[i])
+                        __free_pages(pages[i], 0);
+
+        ptlrpc_free_bulk(desc);
+ out_free:
+        OBD_FREE(pages, sizeof(*pages) * npages);
  out:
         return rc;
 }
@@ -133,7 +151,8 @@ static int mds_sendpage(struct ptlrpc_request *req, struct file *file,
 /* only valid locked dentries or errors should be returned */
 struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid,
                                      struct vfsmount **mnt, int lock_mode,
-                                     struct lustre_handle *lockh)
+                                     struct lustre_handle *lockh,
+                                     char *name, int namelen)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct dentry *de = mds_fid2dentry(mds, fid, mnt), *retval = de;
@@ -152,7 +171,7 @@ struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid,
                               mds_blocking_ast, NULL, lockh);
         if (rc != ELDLM_OK) {
                 l_dput(de);
-                retval = ERR_PTR(-ENOLCK); /* XXX translate ldlm code */
+                retval = ERR_PTR(-EIO); /* XXX translate ldlm code */
         }
 
         RETURN(retval);
@@ -195,8 +214,8 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid,
 
         if (generation && inode->i_generation != generation) {
                 /* we didn't find the right inode.. */
-                CERROR("bad inode %lu, link: %d ct: %d or generation %u/%u\n",
-                       inode->i_ino, inode->i_nlink,
+                CERROR("bad inode %lu, link: %lu ct: %d or generation %u/%u\n",
+                       inode->i_ino, (unsigned long)inode->i_nlink,
                        atomic_read(&inode->i_count), inode->i_generation,
                        generation);
                 dput(result);
@@ -222,7 +241,7 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd,
                        struct obd_uuid *cluuid)
 {
         struct obd_export *exp;
-        struct mds_export_data *med;
+        struct mds_export_data *med; /*  */
         struct mds_client_data *mcd;
         int rc, abort_recovery;
         ENTRY;
@@ -253,185 +272,58 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd,
         exp = class_conn2export(conn);
         LASSERT(exp);
         med = &exp->exp_mds_data;
-        class_export_put(exp);
 
         OBD_ALLOC(mcd, sizeof(*mcd));
         if (!mcd) {
                 CERROR("mds: out of memory for client data\n");
-                GOTO(out_export, rc = -ENOMEM);
+                GOTO(out, rc = -ENOMEM);
         }
 
         memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid));
         med->med_mcd = mcd;
 
-        INIT_LIST_HEAD(&med->med_open_head);
-        spin_lock_init(&med->med_open_lock);
-
         rc = mds_client_add(obd, &obd->u.mds, med, -1);
-        if (rc)
-                GOTO(out_mcd, rc);
-
-        RETURN(0);
-
-out_mcd:
-        OBD_FREE(mcd, sizeof(*mcd));
-out_export:
-        class_disconnect(conn, 0);
-
-        return rc;
-}
-
-static void mds_mfd_addref(void *mfdp)
-{
-        struct mds_file_data *mfd = mfdp;
-
-        atomic_inc(&mfd->mfd_refcount);
-        CDEBUG(D_INFO, "GETting mfd %p : new refcount %d\n", mfd,
-               atomic_read(&mfd->mfd_refcount));
-}
-
-struct mds_file_data *mds_mfd_new(void)
-{
-        struct mds_file_data *mfd;
-
-        OBD_ALLOC(mfd, sizeof *mfd);
-        if (mfd == NULL) {
-                CERROR("mds: out of memory\n");
-                return NULL;
-        }
-
-        atomic_set(&mfd->mfd_refcount, 2);
-
-        INIT_LIST_HEAD(&mfd->mfd_handle.h_link);
-        class_handle_hash(&mfd->mfd_handle, mds_mfd_addref);
-
-        return mfd;
-}
-
-static struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle)
-{
-        ENTRY;
-        LASSERT(handle != NULL);
-        RETURN(class_handle2object(handle->cookie));
-}
-
-void mds_mfd_put(struct mds_file_data *mfd)
-{
-        CDEBUG(D_INFO, "PUTting mfd %p : new refcount %d\n", mfd,
-               atomic_read(&mfd->mfd_refcount) - 1);
-        LASSERT(atomic_read(&mfd->mfd_refcount) > 0 &&
-                atomic_read(&mfd->mfd_refcount) < 0x5a5a);
-        if (atomic_dec_and_test(&mfd->mfd_refcount)) {
-                LASSERT(list_empty(&mfd->mfd_handle.h_link));
-                OBD_FREE(mfd, sizeof *mfd);
+        if (rc == 0)
+                EXIT;
+out:
+        if (rc) {
+                OBD_FREE(mcd, sizeof(*mcd));
+                class_disconnect(exp, 0);
         }
-}
+        class_export_put(exp);
 
-void mds_mfd_destroy(struct mds_file_data *mfd)
-{
-        class_handle_unhash(&mfd->mfd_handle);
-        mds_mfd_put(mfd);
+        return rc;
 }
 
-/* Close a "file descriptor" and possibly unlink an orphan from the
- * PENDING directory.
- *
- * If we are being called from mds_disconnect() because the client has
- * disappeared, then req == NULL and we do not update last_rcvd because
- * there is nothing that could be recovered by the client at this stage
- * (it will not even _have_ an entry in last_rcvd anymore).
- */
-static int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd,
-                         struct mds_file_data *mfd)
+static int mds_init_export(struct obd_export *exp) 
 {
-        struct dentry *dparent = mfd->mfd_dentry->d_parent;
-        struct inode *child_inode = mfd->mfd_dentry->d_inode;
-        char fidname[LL_FID_NAMELEN];
-        int last_orphan, fidlen, rc = 0;
-        ENTRY;
-
-        if (dparent) {
-                LASSERT(atomic_read(&dparent->d_count) > 0);
-                dparent = dget(dparent);
-        }
-
-        fidlen = ll_fid2str(fidname, child_inode->i_ino,
-                            child_inode->i_generation);
-
-        last_orphan = mds_open_orphan_dec_test(child_inode) &&
-                mds_inode_is_orphan(child_inode);
-
-        /* this is the actual "close" */
-        l_dput(mfd->mfd_dentry);
-        mds_mfd_destroy(mfd);
-
-        if (dparent)
-                l_dput(dparent);
-
-        if (last_orphan) {
-                struct mds_obd *mds = &obd->u.mds;
-                struct inode *pending_dir = mds->mds_pending_dir->d_inode;
-                struct dentry *pending_child = NULL;
-                void *handle;
+        struct mds_export_data *med = &exp->exp_mds_data;
 
-                CDEBUG(D_ERROR, "destroying orphan object %s\n", fidname);
-
-                /* Sadly, there is no easy way to save pending_child from
-                 * mds_reint_unlink() into mfd, so we need to re-lookup,
-                 * but normally it will still be in the dcache.
-                 */
-                down(&pending_dir->i_sem);
-                pending_child = lookup_one_len(fidname, mds->mds_pending_dir,
-                                               fidlen);
-                if (IS_ERR(pending_child))
-                        GOTO(out_lock, rc = PTR_ERR(pending_child));
-                LASSERT(pending_child->d_inode != NULL);
-
-                handle = fsfilt_start(obd, pending_dir, FSFILT_OP_UNLINK, NULL);
-                if (IS_ERR(handle))
-                        GOTO(out_dput, rc = PTR_ERR(handle));
-                rc = vfs_unlink(pending_dir, pending_child);
-                if (rc)
-                        CERROR("error unlinking orphan %s: rc %d\n",fidname,rc);
-
-                if (req) {
-                        rc = mds_finish_transno(mds, pending_dir, handle, req,
-                                                rc, 0);
-                } else {
-                        int err = fsfilt_commit(obd, pending_dir, handle, 0);
-                        if (err) {
-                                CERROR("error committing orphan unlink: %d\n",
-                                       err);
-                                if (!rc)
-                                        rc = err;
-                        }
-                }
-        out_dput:
-                dput(pending_child);
-        out_lock:
-                up(&pending_dir->i_sem);
-        }
-
-        RETURN(rc);
+        INIT_LIST_HEAD(&med->med_open_head);
+        spin_lock_init(&med->med_open_lock);
+        RETURN(0);
 }
 
-static int mds_disconnect(struct lustre_handle *conn, int flags)
+static int mds_destroy_export(struct obd_export *export)
 {
-        struct obd_export *export = class_conn2export(conn);
-        struct mds_export_data *med = &export->exp_mds_data;
+        struct mds_export_data *med;
         struct obd_device *obd = export->exp_obd;
         struct obd_run_ctxt saved;
-        int rc;
+        int rc = 0;
         ENTRY;
 
-        push_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
+        med = &export->exp_mds_data;
+        target_destroy_export(export);
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         /* Close any open files (which may also cause orphan unlinking). */
         spin_lock(&med->med_open_lock);
         while (!list_empty(&med->med_open_head)) {
                 struct list_head *tmp = med->med_open_head.next;
                 struct mds_file_data *mfd =
                         list_entry(tmp, struct mds_file_data, mfd_list);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                BDEVNAME_DECLARE_STORAGE(btmp);
+
                 /* bug 1579: fix force-closing for 2.5 */
                 struct dentry *dentry = mfd->mfd_dentry;
 
@@ -440,75 +332,53 @@ static int mds_disconnect(struct lustre_handle *conn, int flags)
 
                 CERROR("force closing client file handle for %*s (%s:%lu)\n",
                        dentry->d_name.len, dentry->d_name.name,
-                       kdevname(dentry->d_inode->i_sb->s_dev),
+                       ll_bdevname(dentry->d_inode->i_sb, btmp),
                        dentry->d_inode->i_ino);
-                rc = mds_mfd_close(NULL, obd, mfd);
-#endif
+                rc = mds_mfd_close(NULL, obd, mfd, 
+                                   !(export->exp_flags & OBD_OPT_FAILOVER));
+
                 if (rc)
                         CDEBUG(D_INODE, "Error closing file: %d\n", rc);
                 spin_lock(&med->med_open_lock);
         }
         spin_unlock(&med->med_open_lock);
-        pop_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
-
-        ldlm_cancel_locks_for_export(export);
-        if (!(flags & OBD_OPT_FAILOVER))
-                mds_client_free(export);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-        rc = class_disconnect(conn, flags);
-        class_export_put(export);
+        mds_client_free(export, !(export->exp_flags & OBD_OPT_FAILOVER));
 
         RETURN(rc);
 }
 
-/*
- * XXX This is NOT guaranteed to flush all transactions to disk (even though
- *     it is equivalent to calling sync()) because it only _starts_ the flush
- *     and does not wait for completion.  It's better than nothing though.
- *     What we really want is a mild form of fsync_dev_lockfs(), but it is
- *     non-standard, or enabling do_sync_supers in ext3, just for this call.
- */
-static void mds_fsync_super(struct super_block *sb)
+static int mds_disconnect(struct obd_export *export, int flags)
 {
-        lock_kernel();
-        lock_super(sb);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
-                sb->s_op->write_super(sb);
-#else
-        if (sb->s_dirt && sb->s_op) {
-                if (sb->s_op->sync_fs)
-                        sb->s_op->sync_fs(sb, 1);
-                else if (sb->s_op->write_super)
-                        sb->s_op->write_super(sb);
-        }
-#endif
-        unlock_super(sb);
-        unlock_kernel();
+        unsigned long irqflags;
+        int rc;
+        ENTRY;
+
+        ldlm_cancel_locks_for_export(export);
+
+        spin_lock_irqsave(&export->exp_lock, irqflags);
+        export->exp_flags = flags;
+        spin_unlock_irqrestore(&export->exp_lock, irqflags);
+
+        rc = class_disconnect(export, flags);
+        RETURN(rc);
 }
 
 static int mds_getstatus(struct ptlrpc_request *req)
 {
-        struct obd_device *obd = req->rq_export->exp_obd;
         struct mds_obd *mds = mds_req2mds(req);
         struct mds_body *body;
         int rc, size = sizeof(*body);
         ENTRY;
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETSTATUS_PACK)) {
                 CERROR("mds: out of memory for message: size=%d\n", size);
                 req->rq_status = -ENOMEM;       /* superfluous? */
                 RETURN(-ENOMEM);
         }
 
-        /* Flush any outstanding transactions to disk so the client will
-         * get the latest last_committed value and can drop their local
-         * requests if they have any.  This would be fsync_super() if it
-         * was exported.
-         */
-        fsfilt_sync(obd, mds->mds_sb);
-
         body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
         memcpy(&body->fid1, &mds->mds_rootfid, sizeof(body->fid1));
 
@@ -518,65 +388,6 @@ static int mds_getstatus(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-static int mds_getlovinfo(struct ptlrpc_request *req)
-{
-        struct mds_obd *mds = mds_req2mds(req);
-        struct mds_status_req *streq;
-        struct lov_desc *desc;
-        struct obd_uuid *uuid0;
-        int tgt_count;
-        int rc, size[2] = {sizeof(*desc)};
-        ENTRY;
-
-        streq = lustre_swab_reqbuf (req, 0, sizeof (*streq),
-                                    lustre_swab_mds_status_req);
-        if (streq == NULL) {
-                CERROR ("Can't unpack mds_status_req\n");
-                RETURN (-EFAULT);
-        }
-
-        if (streq->repbuf > LOV_MAX_UUID_BUFFER_SIZE) {
-                CERROR ("Illegal request for uuid array > %d\n",
-                        streq->repbuf);
-                RETURN (-EINVAL);
-        }
-        size[1] = streq->repbuf;
-
-        rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg);
-        if (rc) {
-                CERROR("mds: out of memory for message: size=%d\n", size[1]);
-                RETURN(-ENOMEM);
-        }
-
-        if (!mds->mds_has_lov_desc) {
-                req->rq_status = -ENOENT;
-                RETURN(0);
-        }
-
-        /* XXX We're sending the lov_desc in my byte order.
-         * Receiver will swab... */
-        desc = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*desc));
-        memcpy(desc, &mds->mds_lov_desc, sizeof (*desc));
-
-        tgt_count = mds->mds_lov_desc.ld_tgt_count;
-        uuid0 = lustre_msg_buf(req->rq_repmsg, 1, tgt_count * sizeof (*uuid0));
-        if (uuid0 == NULL) {
-                CERROR("too many targets, enlarge client buffers\n");
-                req->rq_status = -ENOSPC;
-                RETURN(0);
-        }
-
-        rc = mds_get_lovtgts(mds, tgt_count, uuid0);
-        if (rc) {
-                CERROR("get_lovtgts error %d\n", rc);
-                req->rq_status = rc;
-                RETURN(0);
-        }
-        memcpy(&mds->mds_osc_uuid, &mds->mds_lov_desc.ld_uuid,
-               sizeof(mds->mds_osc_uuid));
-        RETURN(0);
-}
-
 int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                      void *data, int flag)
 {
@@ -620,11 +431,13 @@ int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
         RETURN(0);
 }
 
-int mds_pack_md(struct obd_device *obd, struct lustre_msg *msg,
-                int offset, struct mds_body *body, struct inode *inode)
+/* Call with lock=1 if you want mds_pack_md to take the i_sem.
+ * Call with lock=0 if the caller has already taken the i_sem. */
+int mds_pack_md(struct obd_device *obd, struct lustre_msg *msg, int offset,
+                struct mds_body *body, struct inode *inode, int lock)
 {
         struct mds_obd *mds = &obd->u.mds;
-        struct lov_mds_md *lmm;
+        void *lmm;
         int lmm_size;
         int rc;
         ENTRY;
@@ -641,21 +454,30 @@ int mds_pack_md(struct obd_device *obd, struct lustre_msg *msg,
 
         /* I don't really like this, but it is a sanity check on the client
          * MD request.  However, if the client doesn't know how much space
-         * to reserve for the MD, this shouldn't be fatal either...
+         * to reserve for the MD, it shouldn't be bad to have too much space.
          */
         if (lmm_size > mds->mds_max_mdsize) {
-                CERROR("Reading MD for inode %lu of %d bytes > max %d\n",
+                CWARN("Reading MD for inode %lu of %d bytes > max %d\n",
                        inode->i_ino, lmm_size, mds->mds_max_mdsize);
                 // RETURN(-EINVAL);
         }
 
+        if (lock)
+                down(&inode->i_sem);
         rc = fsfilt_get_md(obd, inode, lmm, lmm_size);
+        if (lock)
+                up(&inode->i_sem);
         if (rc < 0) {
                 CERROR("Error %d reading eadata for ino %lu\n",
                        rc, inode->i_ino);
         } else if (rc > 0) {
+                lmm_size = rc;
+                rc = mds_convert_lov_ea(obd, inode, lmm, lmm_size);
+
+                if (rc > 0)
+                        lmm_size = rc;
                 body->valid |= OBD_MD_FLEASIZE;
-                body->eadatasize = rc;
+                body->eadatasize = lmm_size;
                 rc = 0;
         }
 
@@ -681,7 +503,8 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry,
         mds_pack_inode2body(body, inode);
 
         if (S_ISREG(inode->i_mode) && (reqbody->valid & OBD_MD_FLEASIZE) != 0) {
-                rc = mds_pack_md(obd, req->rq_repmsg, reply_off+1, body, inode);
+                rc = mds_pack_md(obd, req->rq_repmsg, reply_off + 1, body,
+                                 inode, 1);
 
                 /* If we have LOV EA data, the OST holds size, atime, mtime */
                 if (!(body->valid & OBD_MD_FLEASIZE))
@@ -727,7 +550,10 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode,
         LASSERT_REQSWABBED(req, offset);       /* swabbed by caller */
 
         if (S_ISREG(inode->i_mode) && (body->valid & OBD_MD_FLEASIZE)) {
-                int rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0);
+                int rc;
+                down(&inode->i_sem);
+                rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0);
+                up(&inode->i_sem);
                 CDEBUG(D_INODE, "got %d bytes MD data for inode %lu\n",
                        rc, inode->i_ino);
                 if (rc < 0) {
@@ -759,8 +585,7 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode,
                 GOTO(out, rc = -ENOMEM);
         }
 
-        rc = lustre_pack_msg(bufcount, size, NULL, &req->rq_replen,
-                             &req->rq_repmsg);
+        rc = lustre_pack_reply(req, bufcount, size, NULL);
         if (rc) {
                 CERROR("out of memory\n");
                 GOTO(out, req->rq_status = rc);
@@ -771,77 +596,9 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode,
         return(rc);
 }
 
-/* This is more copy-and-paste from getattr_name than I'd like. */
-static void reconstruct_getattr_name(int offset, struct ptlrpc_request *req,
-                                     struct lustre_handle *client_lockh)
-{
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
-        struct obd_device *obd = req->rq_export->exp_obd;
-        struct mds_obd *mds = mds_req2mds(req);
-        struct dentry *parent, *child;
-        struct mds_body *body;
-        struct inode *dir;
-        struct obd_run_ctxt saved;
-        struct obd_ucred uc;
-        int namelen, rc = 0;
-        char *name;
-
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
-
-        LASSERT (req->rq_export->exp_outstanding_reply);
-
-        mds_steal_ack_locks(req->rq_export, req);
-
-        if (req->rq_status)
-                return;
-
-        body = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*body));
-        LASSERT (body != NULL);                 /* checked by caller */
-        LASSERT_REQSWABBED (req, offset);       /* swabbed by caller */
-
-        name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);
-        LASSERT (name != NULL);                 /* checked by caller */
-        LASSERT_REQSWABBED (req, offset + 1);   /* swabbed by caller */
-        namelen = req->rq_reqmsg->buflens[offset + 1];
-
-        LASSERT (offset == 2 || offset == 0);
-        /* requests were at offset 2, replies go back at 1 */
-        if (offset)
-                offset = 1;
-
-        uc.ouc_fsuid = body->fsuid;
-        uc.ouc_fsgid = body->fsgid;
-        uc.ouc_cap = body->capability;
-        uc.ouc_suppgid1 = body->suppgid;
-        uc.ouc_suppgid2 = -1;
-
-        push_ctxt(&saved, &mds->mds_ctxt, &uc);
-        parent = mds_fid2dentry(mds, &body->fid1, NULL);
-        LASSERT(!IS_ERR(parent));
-        dir = parent->d_inode;
-        LASSERT(dir);
-        child = ll_lookup_one_len(name, parent, namelen - 1);
-        LASSERT(!IS_ERR(child));
-
-        if (req->rq_repmsg == NULL) {
-                rc = mds_getattr_pack_msg(req, child->d_inode, offset);
-                /* XXX need to handle error here */
-                LASSERT (rc == 0);
-        }
-
-        rc = mds_getattr_internal(obd, child, req, body, offset);
-        /* XXX need to handle error here */
-        LASSERT(!rc);
-        l_dput(child);
-        l_dput(parent);
-}
-
 static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                             struct lustre_handle *child_lockh)
 {
-        struct mds_obd *mds = mds_req2mds(req);
         struct obd_device *obd = req->rq_export->exp_obd;
         struct ldlm_reply *rep = NULL;
         struct obd_run_ctxt saved;
@@ -875,18 +632,6 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
         }
         namesize = req->rq_reqmsg->buflens[offset + 1];
 
-        if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
-                struct obd_export *exp = req->rq_export;
-                if (exp->exp_outstanding_reply &&
-                    exp->exp_outstanding_reply->rq_xid == req->rq_xid) {
-                        reconstruct_getattr_name(offset, req, child_lockh);
-                        RETURN(0);
-                }
-                DEBUG_REQ(D_HA, req, "no reply for RESENT req (have "LPD64")",
-                          exp->exp_outstanding_reply ?
-                          exp->exp_outstanding_reply->rq_xid : (u64)0);
-        }
-
         LASSERT (offset == 0 || offset == 2);
         /* if requests were at offset 2, the getattr reply goes back at 1 */
         if (offset) { 
@@ -899,11 +644,11 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
         uc.ouc_cap = body->capability;
         uc.ouc_suppgid1 = body->suppgid;
         uc.ouc_suppgid2 = -1;
-        push_ctxt(&saved, &mds->mds_ctxt, &uc);
+        push_ctxt(&saved, &obd->obd_ctxt, &uc);
         /* Step 1: Lookup/lock parent */
         intent_set_disposition(rep, DISP_LOOKUP_EXECD);
         de = mds_fid2locked_dentry(obd, &body->fid1, NULL, LCK_PR,
-                                   &parent_lockh);
+                                   &parent_lockh, name, namesize - 1);
         if (IS_ERR(de))
                 GOTO(cleanup, rc = PTR_ERR(de));
         dir = de->d_inode;
@@ -914,31 +659,59 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
         CDEBUG(D_INODE, "parent ino %lu, name %s\n", dir->i_ino, name);
 
         /* Step 2: Lookup child */
+#if 0
+        if (body->valid == OBD_MD_FLID) {
+                struct mds_body *mds_reply;
+                int size = sizeof(*mds_reply);
+                ino_t inum;
+                // The user requested ONLY the inode number, so do a raw lookup
+                rc = lustre_pack_reply(req, 1, &size, NULL);
+                if (rc) {
+                        CERROR("out of memory\n");
+                        GOTO(cleanup, rc);
+                }
+
+                rc = dir->i_op->lookup_raw(dir, name, namesize - 1, &inum);
+
+                mds_reply = lustre_msg_buf(req->rq_repmsg, offset,
+                                           sizeof(*mds_reply));
+                mds_reply->fid1.id = inum;
+                mds_reply->valid = OBD_MD_FLID;
+                GOTO(cleanup, rc);
+        }
+#endif
+
         dchild = ll_lookup_one_len(name, de, namesize - 1);
         if (IS_ERR(dchild)) {
                 CDEBUG(D_INODE, "child lookup error %ld\n", PTR_ERR(dchild));
                 GOTO(cleanup, rc = PTR_ERR(dchild));
         }
-
         cleanup_phase = 2; /* child dentry */
 
         if (dchild->d_inode == NULL) {
                 intent_set_disposition(rep, DISP_LOOKUP_NEG);
+                /* in the intent case, the policy clears this error:
+                   the disposition is enough */
                 GOTO(cleanup, rc = -ENOENT);
         } else {
                 intent_set_disposition(rep, DISP_LOOKUP_POS);
         }
 
         /* Step 3: Lock child */
-        child_res_id.name[0] = dchild->d_inode->i_ino;
-        child_res_id.name[1] = dchild->d_inode->i_generation;
-        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
-                              child_res_id, LDLM_PLAIN, NULL, 0, LCK_PR,
-                              &flags, ldlm_completion_ast, mds_blocking_ast,
-                              NULL, child_lockh);
-        if (rc != ELDLM_OK) {
-                CERROR("ldlm_cli_enqueue: %d\n", rc);
-                GOTO(cleanup, rc = -EIO);
+        /* fixup_handle_for_resent_req might have set the child_lockh for us, if
+         * the lock was already granted for this request on the last
+         * transmission. */
+        if (child_lockh->cookie == 0) {
+                child_res_id.name[0] = dchild->d_inode->i_ino;
+                child_res_id.name[1] = dchild->d_inode->i_generation;
+                rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
+                                      child_res_id, LDLM_PLAIN, NULL, 0, LCK_PR,
+                                      &flags, ldlm_completion_ast,
+                                      mds_blocking_ast, NULL, child_lockh);
+                if (rc != ELDLM_OK) {
+                        CERROR("ldlm_cli_enqueue: %d\n", rc);
+                        GOTO(cleanup, rc = -EIO);
+                }
         }
 
         cleanup_phase = 3; /* child lock */
@@ -966,15 +739,12 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                 if (rc) {
                         ldlm_lock_decref(&parent_lockh, LCK_PR);
                 } else {
-                        memcpy(&req->rq_ack_locks[0].lock, &parent_lockh,
-                               sizeof(parent_lockh));
-                        req->rq_ack_locks[0].mode = LCK_PR;
+                        ldlm_put_lock_into_req(req, &parent_lockh, LCK_PR);
                 }
                 l_dput(de);
         default: ;
         }
-        req->rq_status = rc;
-        pop_ctxt(&saved, &mds->mds_ctxt, &uc);
+        pop_ctxt(&saved, &obd->obd_ctxt, &uc);
         return rc;
 }
 
@@ -999,7 +769,7 @@ static int mds_getattr(int offset, struct ptlrpc_request *req)
         uc.ouc_fsuid = body->fsuid;
         uc.ouc_fsgid = body->fsgid;
         uc.ouc_cap = body->capability;
-        push_ctxt(&saved, &mds->mds_ctxt, &uc);
+        push_ctxt(&saved, &obd->obd_ctxt, &uc);
         de = mds_fid2dentry(mds, &body->fid1, NULL);
         if (IS_ERR(de)) {
                 rc = req->rq_status = -ENOENT;
@@ -1017,7 +787,7 @@ static int mds_getattr(int offset, struct ptlrpc_request *req)
         l_dput(de);
         GOTO(out_pop, rc);
 out_pop:
-        pop_ctxt(&saved, &mds->mds_ctxt, &uc);
+        pop_ctxt(&saved, &obd->obd_ctxt, &uc);
         return rc;
 }
 
@@ -1034,9 +804,9 @@ static int mds_statfs(struct ptlrpc_request *req)
         int rc, size = sizeof(struct obd_statfs);
         ENTRY;
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) {
-                CERROR("mds: statfs lustre_pack_msg failed: rc = %d\n", rc);
+                CERROR("mds: statfs lustre_pack_reply failed: rc = %d\n", rc);
                 GOTO(out, rc);
         }
 
@@ -1053,85 +823,66 @@ out:
         return 0;
 }
 
-static void reconstruct_close(struct ptlrpc_request *req)
+static int mds_sync(struct ptlrpc_request *req)
 {
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
-
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
-
-        /* XXX When open-unlink is working, we'll need to steal ack locks as
-         * XXX well, and make sure that we do the right unlinking after we
-         * XXX get the ack back.
-         */
-}
-
-static int mds_close(struct ptlrpc_request *req)
-{
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
         struct obd_device *obd = req->rq_export->exp_obd;
+        struct mds_obd *mds = &obd->u.mds;
         struct mds_body *body;
-        struct mds_file_data *mfd;
-        struct obd_run_ctxt saved;
-        int rc;
+        int rc, size = sizeof(*body);
         ENTRY;
 
-        MDS_CHECK_RESENT(req, reconstruct_close(req));
-
-        body = lustre_swab_reqbuf(req, 0, sizeof (*body),
-                                  lustre_swab_mds_body);
-        if (body == NULL) {
-                CERROR ("Can't unpack body\n");
-                RETURN (-EFAULT);
-        }
+        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body));
+        if (body == NULL)
+                GOTO(out, rc = -EPROTO);
 
-        mfd = mds_handle2mfd(&body->handle);
-        if (mfd == NULL) {
-                DEBUG_REQ(D_ERROR, req, "no handle for file close "LPD64
-                          ": cookie "LPX64"\n", body->fid1.id,
-                          body->handle.cookie);
-                RETURN(-ESTALE);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
+        if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_SYNC_PACK)) {
+                CERROR("fsync lustre_pack_reply failed: rc = %d\n", rc);
+                GOTO(out, rc);
         }
 
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
-        if (rc) {
-                CERROR("lustre_pack_msg: rc = %d\n", rc);
-                req->rq_status = rc;
-        }
+        if (body->fid1.id == 0) {
+                /* a fid of zero is taken to mean "sync whole filesystem" */
+                rc = fsfilt_sync(obd, mds->mds_sb);
+                if (rc)
+                        GOTO(out, rc);
+        } else {
+                /* just any file to grab fsync method - "file" arg unused */
+                struct file *file = mds->mds_rcvd_filp;
+                struct dentry *de;
 
-        spin_lock(&med->med_open_lock);
-        list_del(&mfd->mfd_list);
-        spin_unlock(&med->med_open_lock);
+                de = mds_fid2dentry(mds, &body->fid1, NULL);
+                if (IS_ERR(de))
+                        GOTO(out, rc = PTR_ERR(de));
 
-        push_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
-        req->rq_status = mds_mfd_close(rc ? NULL : req, obd, mfd);
-        pop_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
+                rc = file->f_op->fsync(NULL, de, 1);
+                l_dput(de);
+                if (rc)
+                        GOTO(out, rc);
 
-        if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK)) {
-                CERROR("test case OBD_FAIL_MDS_CLOSE_PACK\n");
-                req->rq_status = -ENOMEM;
-                mds_mfd_put(mfd);
-                RETURN(-ENOMEM);
+                body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+                mds_pack_inode2fid(&body->fid1, de->d_inode);
+                mds_pack_inode2body(body, de->d_inode);
         }
-
-        mds_mfd_put(mfd);
-        RETURN(0);
+out:
+        req->rq_status = rc;
+        return 0;
 }
 
 static int mds_readpage(struct ptlrpc_request *req)
 {
-        struct mds_obd *mds = mds_req2mds(req);
+        struct obd_device *obd = req->rq_export->exp_obd;
         struct vfsmount *mnt;
         struct dentry *de;
         struct file *file;
         struct mds_body *body, *repbody;
+        struct lustre_handle lockh;
         struct obd_run_ctxt saved;
         int rc, size = sizeof(*repbody);
         struct obd_ucred uc;
         ENTRY;
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_READPAGE_PACK)) {
                 CERROR("mds: out of memory\n");
                 GOTO(out, rc = -ENOMEM);
@@ -1142,23 +893,12 @@ static int mds_readpage(struct ptlrpc_request *req)
         if (body == NULL)
                 GOTO (out, rc = -EFAULT);
 
-        /* body->size is actually the offset -eeb */
-        if ((body->size & ~PAGE_MASK) != 0) {
-                CERROR ("offset "LPU64"not on a page boundary\n", body->size);
-                GOTO (out, rc = -EFAULT);
-        }
-
-        /* body->nlink is actually the #bytes to read -eeb */
-        if (body->nlink != PAGE_SIZE) {
-                CERROR ("size %d is not PAGE_SIZE\n", body->nlink);
-                GOTO (out, rc = -EFAULT);
-        }
-
         uc.ouc_fsuid = body->fsuid;
         uc.ouc_fsgid = body->fsgid;
         uc.ouc_cap = body->capability;
-        push_ctxt(&saved, &mds->mds_ctxt, &uc);
-        de = mds_fid2dentry(mds, &body->fid1, &mnt);
+        push_ctxt(&saved, &obd->obd_ctxt, &uc);
+        de = mds_fid2locked_dentry(obd, &body->fid1, &mnt, LCK_PR,
+                                   &lockh, NULL, 0);
         if (IS_ERR(de))
                 GOTO(out_pop, rc = PTR_ERR(de));
 
@@ -1167,7 +907,21 @@ static int mds_readpage(struct ptlrpc_request *req)
         file = dentry_open(de, mnt, O_RDONLY | O_LARGEFILE);
         /* note: in case of an error, dentry_open puts dentry */
         if (IS_ERR(file))
-                GOTO(out_pop, rc = PTR_ERR(file));
+                GOTO(out_lock, rc = PTR_ERR(file));
+
+        /* body->size is actually the offset -eeb */
+        if ((body->size & (de->d_inode->i_blksize - 1)) != 0) {
+                CERROR("offset "LPU64" not on a block boundary of %lu\n",
+                       body->size, de->d_inode->i_blksize);
+                GOTO(out_file, rc = -EFAULT);
+        }
+
+        /* body->nlink is actually the #bytes to read -eeb */
+        if (body->nlink & (de->d_inode->i_blksize - 1)) {
+                CERROR("size %u is not multiple of blocksize %lu\n",
+                       body->nlink, de->d_inode->i_blksize);
+                GOTO(out_file, rc = -EFAULT);
+        }
 
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*repbody));
         repbody->size = file->f_dentry->d_inode->i_size;
@@ -1176,13 +930,15 @@ static int mds_readpage(struct ptlrpc_request *req)
         /* to make this asynchronous make sure that the handling function
            doesn't send a reply when this function completes. Instead a
            callback function would send the reply */
-        /* body->blocks is actually the xid -phil */
         /* body->size is actually the offset -eeb */
-        rc = mds_sendpage(req, file, body->size, body->blocks);
+        rc = mds_sendpage(req, file, body->size, body->nlink);
 
+out_file:
         filp_close(file, 0);
+out_lock:
+        ldlm_lock_decref(&lockh, LCK_PR);
 out_pop:
-        pop_ctxt(&saved, &mds->mds_ctxt, &uc);
+        pop_ctxt(&saved, &obd->obd_ctxt, &uc);
 out:
         req->rq_status = rc;
         RETURN(0);
@@ -1210,8 +966,8 @@ int mds_reint(struct ptlrpc_request *req, int offset,
         return rc;
 }
 
-static int filter_recovery_request(struct ptlrpc_request *req,
-                                   struct obd_device *obd, int *process)
+static int mds_filter_recovery_request(struct ptlrpc_request *req,
+                                       struct obd_device *obd, int *process)
 {
         switch (req->rq_reqmsg->opc) {
         case MDS_CONNECT: /* This will never get here, but for completeness. */
@@ -1222,7 +978,7 @@ static int filter_recovery_request(struct ptlrpc_request *req,
                RETURN(0);
 
         case MDS_CLOSE:
-        case MDS_GETSTATUS: /* used in unmounting */
+        case MDS_SYNC: /* used in unmounting */
         case OBD_PING:
         case MDS_REINT:
         case LDLM_ENQUEUE:
@@ -1251,8 +1007,10 @@ void mds_steal_ack_locks(struct obd_export *exp,
                          struct ptlrpc_request *req)
 {
         unsigned long  flags;
-
         struct ptlrpc_request *oldrep = exp->exp_outstanding_reply;
+        
+        if (oldrep == NULL)
+                return;
         memcpy(req->rq_ack_locks, oldrep->rq_ack_locks,
                sizeof req->rq_ack_locks);
         spin_lock_irqsave (&req->rq_lock, flags);
@@ -1275,6 +1033,7 @@ int mds_handle(struct ptlrpc_request *req)
 
         LASSERT(!strcmp(req->rq_obd->obd_type->typ_name, LUSTRE_MDT_NAME));
 
+        LASSERT(current->journal_info == NULL);
         /* XXX identical to OST */
         if (req->rq_reqmsg->opc != MDS_CONNECT) {
                 struct mds_export_data *med;
@@ -1299,7 +1058,8 @@ int mds_handle(struct ptlrpc_request *req)
                 if (abort_recovery) {
                         target_abort_recovery(obd);
                 } else if (recovering) {
-                        rc = filter_recovery_request(req, obd, &should_process);
+                        rc = mds_filter_recovery_request(req, obd,
+                                                         &should_process);
                         if (rc || !should_process)
                                 RETURN(rc);
                 }
@@ -1310,21 +1070,15 @@ int mds_handle(struct ptlrpc_request *req)
                 DEBUG_REQ(D_INODE, req, "connect");
                 OBD_FAIL_RETURN(OBD_FAIL_MDS_CONNECT_NET, 0);
                 rc = target_handle_connect(req, mds_handle);
-                /* Make sure that last_rcvd is correct. */
-                if (!rc) {
+                if (!rc)
                         /* Now that we have an export, set mds. */
                         mds = mds_req2mds(req);
-                        mds_fsync_super(mds->mds_sb);
-                }
                 break;
 
         case MDS_DISCONNECT:
                 DEBUG_REQ(D_INODE, req, "disconnect");
                 OBD_FAIL_RETURN(OBD_FAIL_MDS_DISCONNECT_NET, 0);
                 rc = target_handle_disconnect(req);
-                /* Make sure that last_rcvd is correct. */
-                if (!rc)
-                        mds_fsync_super(mds->mds_sb);
                 req->rq_status = rc;            /* superfluous? */
                 break;
 
@@ -1334,11 +1088,6 @@ int mds_handle(struct ptlrpc_request *req)
                 rc = mds_getstatus(req);
                 break;
 
-        case MDS_GETLOVINFO:
-                DEBUG_REQ(D_INODE, req, "getlovinfo");
-                rc = mds_getlovinfo(req);
-                break;
-
         case MDS_GETATTR:
                 DEBUG_REQ(D_INODE, req, "getattr");
                 OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NET, 0);
@@ -1356,6 +1105,8 @@ int mds_handle(struct ptlrpc_request *req)
                  */
                 lockh.cookie = 0;
                 rc = mds_getattr_name(0, req, &lockh);
+                /* this non-intent call (from an ioctl) is special */
+                req->rq_status = rc;
                 if (rc == 0 && lockh.cookie)
                         ldlm_lock_decref(&lockh, LCK_PR);
                 break;
@@ -1401,13 +1152,12 @@ int mds_handle(struct ptlrpc_request *req)
 
                 if (opc == REINT_UNLINK)
                         bufcount = 3;
-                else if (opc == REINT_OPEN)
+                else if (opc == REINT_OPEN || opc == REINT_RENAME)
                         bufcount = 2;
                 else
                         bufcount = 1;
 
-                rc = lustre_pack_msg(bufcount, size, NULL,
-                                     &req->rq_replen, &req->rq_repmsg);
+                rc = lustre_pack_reply(req, bufcount, size, NULL);
                 if (rc)
                         break;
 
@@ -1422,12 +1172,24 @@ int mds_handle(struct ptlrpc_request *req)
                 rc = mds_close(req);
                 break;
 
+        case MDS_DONE_WRITING:
+                DEBUG_REQ(D_INODE, req, "done_writing");
+                OBD_FAIL_RETURN(OBD_FAIL_MDS_DONE_WRITING_NET, 0);
+                rc = mds_done_writing(req);
+                break;
+
         case MDS_PIN:
                 DEBUG_REQ(D_INODE, req, "pin");
                 OBD_FAIL_RETURN(OBD_FAIL_MDS_PIN_NET, 0);
                 rc = mds_pin(req);
                 break;
 
+        case MDS_SYNC:
+                DEBUG_REQ(D_INODE, req, "sync");
+                OBD_FAIL_RETURN(OBD_FAIL_MDS_SYNC_NET, 0);
+                rc = mds_sync(req);
+                break;
+
         case OBD_PING:
                 DEBUG_REQ(D_INODE, req, "ping");
                 rc = target_handle_ping(req);
@@ -1457,12 +1219,34 @@ int mds_handle(struct ptlrpc_request *req)
                 LBUG();
                 OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0);
                 break;
+        case LLOG_ORIGIN_HANDLE_CREATE:
+                DEBUG_REQ(D_INODE, req, "llog_init");
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+                rc = llog_origin_handle_create(req);
+                break;
+        case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
+                DEBUG_REQ(D_INODE, req, "llog next block");
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+                rc = llog_origin_handle_next_block(req);
+                break;
+        case LLOG_ORIGIN_HANDLE_READ_HEADER:
+                DEBUG_REQ(D_INODE, req, "llog read header");
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+                rc = llog_origin_handle_read_header(req);
+                break;
+        case LLOG_ORIGIN_HANDLE_CLOSE:
+                DEBUG_REQ(D_INODE, req, "llog close");
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+                rc = llog_origin_handle_close(req);
+                break;
         default:
                 req->rq_status = -ENOTSUPP;
                 rc = ptlrpc_error(req);
                 RETURN(rc);
         }
 
+        LASSERT(current->journal_info == NULL);
+
         EXIT;
 
         /* If we're DISCONNECTing, the mds_export_data is already freed */
@@ -1507,7 +1291,7 @@ int mds_handle(struct ptlrpc_request *req)
  *
  * Also assumes for mds_last_transno that we are not modifying it (no locking).
  */
-int mds_update_server_data(struct obd_device *obd)
+int mds_update_server_data(struct obd_device *obd, int force_sync)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct mds_server_data *msd = mds->mds_server_data;
@@ -1515,71 +1299,49 @@ int mds_update_server_data(struct obd_device *obd)
         struct obd_run_ctxt saved;
         loff_t off = 0;
         int rc;
+        ENTRY;
 
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         msd->msd_last_transno = cpu_to_le64(mds->mds_last_transno);
         msd->msd_mount_count = cpu_to_le64(mds->mds_mount_count);
 
         CDEBUG(D_SUPER, "MDS mount_count is "LPU64", last_transno is "LPU64"\n",
                mds->mds_mount_count, mds->mds_last_transno);
-        rc = fsfilt_write_record(obd, filp, msd, sizeof(*msd), &off);
-        if (rc != sizeof(*msd)) {
-                CERROR("error writing MDS server data: rc = %d\n", rc);
-                if (rc > 0)
-                        rc = -EIO;
-                GOTO(out, rc);
-        }
-        rc = file_fsync(filp, filp->f_dentry, 1);
+        rc = fsfilt_write_record(obd, filp, msd, sizeof(*msd), &off,force_sync);
         if (rc)
-                CERROR("error flushing MDS server data: rc = %d\n", rc);
-
-out:
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+                CERROR("error writing MDS server data: rc = %d\n", rc);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
         RETURN(rc);
 }
 
+
 /* mount the file system (secretly) */
 static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         struct mds_obd *mds = &obd->u.mds;
         struct vfsmount *mnt;
         int rc = 0;
         unsigned long page;
         ENTRY;
 
-
         dev_clear_rdonly(2);
-        if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2)
-                RETURN(rc = -EINVAL);
 
-        if (data->ioc_inlbuf4)
-                obd_str2uuid(&mds->mds_osc_uuid, data->ioc_inlbuf4);
+        if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
+                RETURN(rc = -EINVAL);
 
-        obd->obd_fsops = fsfilt_get_ops(data->ioc_inlbuf2);
+        obd->obd_fsops = fsfilt_get_ops(lcfg->lcfg_inlbuf2);
         if (IS_ERR(obd->obd_fsops))
                 RETURN(rc = PTR_ERR(obd->obd_fsops));
 
-
-        if (data->ioc_inllen3 > 0 && data->ioc_inlbuf3) {
-                if (*data->ioc_inlbuf3 == '/') {
-                        CERROR("mds namespace mount: %s\n", 
-                               data->ioc_inlbuf3);
-//                        mds->mds_nspath = strdup(ioc->inlbuf4);
-                } else {
-                        CERROR("namespace mount must be absolute path: '%s'\n",
-                               data->ioc_inlbuf3);
-                }
-        }
-
-	if (!(page = __get_free_page(GFP_KERNEL)))
-		return -ENOMEM;
+        if (!(page = __get_free_page(GFP_KERNEL)))
+                RETURN(-ENOMEM);
 
         memset((void *)page, 0, PAGE_SIZE);
         sprintf((char *)page, "iopen_nopriv");
 
-        mnt = do_kern_mount(data->ioc_inlbuf2, 0,
-                            data->ioc_inlbuf1, (void *)page);
+        mnt = do_kern_mount(lcfg->lcfg_inlbuf2, 0,
+                            lcfg->lcfg_inlbuf1, (void *)page);
         free_page(page);
         if (IS_ERR(mnt)) {
                 rc = PTR_ERR(mnt);
@@ -1587,54 +1349,59 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
                 GOTO(err_ops, rc);
         }
 
-        CDEBUG(D_SUPER, "%s: mnt = %p\n", data->ioc_inlbuf1, mnt);
-        mds->mds_sb = mnt->mnt_root->d_inode->i_sb;
-        if (!mds->mds_sb)
-                GOTO(err_put, rc = -ENODEV);
+        CDEBUG(D_SUPER, "%s: mnt = %p\n", lcfg->lcfg_inlbuf1, mnt);
 
+        sema_init(&mds->mds_orphan_recovery_sem, 1);
+        sema_init(&mds->mds_epoch_sem, 1);
         spin_lock_init(&mds->mds_transno_lock);
         mds->mds_max_mdsize = sizeof(struct lov_mds_md);
         mds->mds_max_cookiesize = sizeof(struct llog_cookie);
+
+        obd->obd_namespace = ldlm_namespace_new("mds_server",
+                                                LDLM_NAMESPACE_SERVER);
+        if (obd->obd_namespace == NULL) {
+                mds_cleanup(obd, 0);
+                GOTO(err_put, rc = -ENOMEM);
+        }
+
         rc = mds_fs_setup(obd, mnt);
         if (rc) {
                 CERROR("MDS filesystem method init failed: rc = %d\n", rc);
-                GOTO(err_put, rc);
+                GOTO(err_ns, rc);
         }
 
-#ifdef ENABLE_ORPHANS
         rc = llog_start_commit_thread();
         if (rc < 0)
                 GOTO(err_fs, rc);
-#endif
+        
 
-#ifdef ENABLE_ORPHANS
-        mds->mds_catalog = mds_get_catalog(obd);
-        if (IS_ERR(mds->mds_catalog))
-                GOTO(err_fs, rc = PTR_ERR(mds->mds_catalog));
-#endif
+        if (lcfg->lcfg_inllen3 > 0 && lcfg->lcfg_inlbuf3) {
+                class_uuid_t uuid;
 
-        obd->obd_namespace = ldlm_namespace_new("mds_server",
-                                                LDLM_NAMESPACE_SERVER);
-        if (obd->obd_namespace == NULL) {
-                mds_cleanup(obd, 0);
-                GOTO(err_log, rc = -ENOMEM);
-        }
+                generate_random_uuid(uuid);
+                class_uuid_unparse(uuid, &mds->mds_lov_uuid);
+
+                OBD_ALLOC(mds->mds_profile, lcfg->lcfg_inllen3);
+                if (mds->mds_profile == NULL) 
+                        GOTO(err_fs, rc = -ENOMEM);
+
+                memcpy(mds->mds_profile, lcfg->lcfg_inlbuf3,
+                       lcfg->lcfg_inllen3);
+
+        } 
 
         ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
                            "mds_ldlm_client", &obd->obd_ldlm_client);
-
-        mds->mds_has_lov_desc = 0;
         obd->obd_replayable = 1;
 
         RETURN(0);
 
-err_log:
-#ifdef ENABLE_ORPHANS
-        mds_put_catalog(mds->mds_catalog);
-        /* No extra cleanup needed for llog_init_commit_thread() */
 err_fs:
-#endif
+        /* No extra cleanup needed for llog_init_commit_thread() */
         mds_fs_cleanup(obd, 0);
+err_ns:
+        ldlm_namespace_free(obd->obd_namespace, 0);
+        obd->obd_namespace = NULL;
 err_put:
         unlock_kernel();
         mntput(mds->mds_vfsmnt);
@@ -1645,6 +1412,112 @@ err_ops:
         return rc;
 }
 
+static int mds_postsetup(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        int rc = 0;
+        ENTRY;
+
+
+        rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
+                        &llog_lvfs_ops);
+        if (rc)
+                RETURN(rc);
+
+        if (mds->mds_profile) {
+                struct obd_run_ctxt saved;
+                struct lustre_profile *lprof;
+                struct config_llog_instance cfg;
+
+                cfg.cfg_instance = NULL;
+                cfg.cfg_uuid = mds->mds_lov_uuid;
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = class_config_parse_llog(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), 
+                                             mds->mds_profile, &cfg);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                if (rc)
+                        GOTO(err_llog, rc);
+
+                lprof = class_get_profile(mds->mds_profile);
+                if (lprof == NULL) {
+                        CERROR("No profile found: %s\n", mds->mds_profile);
+                        GOTO(err_cleanup, rc = -ENOENT);
+                }
+                rc = mds_lov_connect(obd, lprof->lp_osc);
+                if (rc)
+                        GOTO(err_cleanup, rc);
+        }
+
+        RETURN(rc);
+
+err_cleanup:
+        mds_lov_clean(obd);
+err_llog:
+        llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+        RETURN(rc);
+}
+
+static int mds_postrecov(struct obd_device *obd) 
+
+{
+        int rc, rc2;
+
+        LASSERT(!obd->obd_recovering);
+
+#ifdef ENABLE_ORPHANS
+        rc = llog_connect(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT),
+                          obd->u.mds.mds_lov_desc.ld_tgt_count, NULL, NULL);
+        if (rc != 0) {
+                CERROR("faild at llog_origin_connect: %d\n", rc);
+        }
+#endif
+        rc = mds_cleanup_orphans(obd);
+
+        rc2 = mds_lov_set_nextid(obd);
+        if (rc2 == 0)
+                rc2 = rc;
+        RETURN(rc2);
+}
+
+int mds_lov_clean(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+
+        if (mds->mds_profile) {
+                char * cln_prof;
+                struct config_llog_instance cfg;
+                struct obd_run_ctxt saved;
+                int len = strlen(mds->mds_profile) + sizeof("-clean") + 1;
+
+                OBD_ALLOC(cln_prof, len);
+                sprintf(cln_prof, "%s-clean", mds->mds_profile);
+
+                cfg.cfg_instance = NULL;
+                cfg.cfg_uuid = mds->mds_lov_uuid;
+
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                class_config_parse_llog(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), 
+                                        cln_prof, &cfg);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+                OBD_FREE(cln_prof, len);
+                OBD_FREE(mds->mds_profile, strlen(mds->mds_profile) + 1);
+                mds->mds_profile = NULL;
+        }
+        RETURN(0);
+}
+
+static int mds_precleanup(struct obd_device *obd, int flags)
+{
+        int rc = 0;
+        ENTRY;
+
+        mds_lov_disconnect(obd, flags);
+        mds_lov_clean(obd);
+        llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+        RETURN(rc);
+}
+
 static int mds_cleanup(struct obd_device *obd, int flags)
 {
         struct mds_obd *mds = &obd->u.mds;
@@ -1653,12 +1526,11 @@ static int mds_cleanup(struct obd_device *obd, int flags)
         if (mds->mds_sb == NULL)
                 RETURN(0);
 
-#ifdef ENABLE_ORPHANS
-        mds_put_catalog(mds->mds_catalog);
-#endif
-        if (mds->mds_osc_obd)
-                obd_disconnect(&mds->mds_osc_conn, flags);
-        mds_update_server_data(obd);
+        mds_update_server_data(obd, 1);
+        if (mds->mds_lov_objids != NULL) {
+                OBD_FREE(mds->mds_lov_objids,
+                         mds->mds_lov_desc.ld_tgt_count * sizeof(obd_id));
+        }
         mds_fs_cleanup(obd, flags);
 
         unlock_kernel();
@@ -1666,13 +1538,14 @@ static int mds_cleanup(struct obd_device *obd, int flags)
         /* 2 seems normal on mds, (may_umount() also expects 2
           fwiw), but we only see 1 at this point in obdfilter. */
         if (atomic_read(&obd->u.mds.mds_vfsmnt->mnt_count) > 2)
-                CERROR("%s: mount point busy, mnt_count: %d\n", obd->obd_name,
+                CERROR("%s: mount busy, mnt_count %d != 2\n", obd->obd_name,
                        atomic_read(&obd->u.mds.mds_vfsmnt->mnt_count));
 
         mntput(mds->mds_vfsmnt);
+
         mds->mds_sb = 0;
 
-        ldlm_namespace_free(obd->obd_namespace);
+        ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE);
 
         if (obd->obd_recovering)
                 target_cancel_recovery_timer(obd);
@@ -1710,9 +1583,15 @@ static void fixup_handle_for_resent_req(struct ptlrpc_request *req,
                         l_unlock(&obd->obd_namespace->ns_lock);
                         return;
                 }
-
         }
         l_unlock(&obd->obd_namespace->ns_lock);
+
+        /* This remote handle isn't enqueued, so we never received or
+         * processed this request.  Clear MSG_RESENT, because it can
+         * be handled like any normal request now. */
+
+        lustre_msg_clear_flags(req->rq_reqmsg, MSG_RESENT);
+        
         DEBUG_REQ(D_HA, req, "no existing lock with rhandle "LPX64,
                   remote_hdl.cookie);
 }
@@ -1737,6 +1616,7 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
 {
         struct ptlrpc_request *req = req_cookie;
         struct ldlm_lock *lock = *lockp;
+        int rc;
         ENTRY;
 
         if (!req_cookie)
@@ -1747,7 +1627,7 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                 struct ldlm_intent *it;
                 struct mds_obd *mds = &req->rq_export->exp_obd->u.mds;
                 struct ldlm_reply *rep;
-                struct lustre_handle lockh;
+                struct lustre_handle lockh = { 0 };
                 struct ldlm_lock *new_lock;
                 int offset = 2, repsize[4] = {sizeof(struct ldlm_reply),
                                               sizeof(struct mds_body),
@@ -1765,11 +1645,10 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                 LDLM_DEBUG(lock, "intent policy, opc: %s",
                            ldlm_it2str(it->opc));
 
-                req->rq_status = lustre_pack_msg(it->opc == IT_UNLINK ? 4 : 3,
-                                                 repsize, NULL, &req->rq_replen,
-                                                 &req->rq_repmsg);
-                if (req->rq_status)
-                        RETURN(req->rq_status);
+                rc = lustre_pack_reply(req, it->opc == IT_UNLINK ? 4 : 3,
+                                       repsize, NULL);
+                if (rc)
+                        RETURN(req->rq_status = rc);
 
                 rep = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*rep));
                 intent_set_disposition(rep, DISP_IT_EXECD);
@@ -1783,12 +1662,14 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                         /* XXX swab here to assert that an mds_open reint
                          * packet is following */
                         rep->lock_policy_res2 = mds_reint(req, offset, &lockh);
+#if 0
                         /* We abort the lock if the lookup was negative and
                          * we did not make it to the OPEN portion */
                         if (!intent_disposition(rep, DISP_LOOKUP_EXECD))
                                 RETURN(ELDLM_LOCK_ABORTED);
                         if (intent_disposition(rep, DISP_LOOKUP_NEG) &&
                             !intent_disposition(rep, DISP_OPEN_OPEN))
+#endif 
                                 RETURN(ELDLM_LOCK_ABORTED);
                         break;
                 case IT_GETATTR:
@@ -1796,15 +1677,17 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                 case IT_READDIR:
                         rep->lock_policy_res2 = mds_getattr_name(offset, req,
                                                                  &lockh);
-                        /* FIXME: we need to sit down and decide on who should
-                         * set req->rq_status, who should return negative and
-                         * positive return values, and what they all mean. 
-                         * - replay: returns 0 & req->status is old status
-                         * - otherwise: returns req->status */
+                        /* FIXME: LDLM can set req->rq_status. MDS sets
+                           policy_res{1,2} with disposition and status.
+                           - replay: returns 0 & req->status is old status 
+                           - otherwise: returns req->status */
+                        if (intent_disposition(rep, DISP_LOOKUP_NEG))
+                                rep->lock_policy_res2 = 0;
                         if (!intent_disposition(rep, DISP_LOOKUP_POS) || 
                             rep->lock_policy_res2)
                                 RETURN(ELDLM_LOCK_ABORTED);
                         if (req->rq_status != 0) {
+                                LBUG();
                                 rep->lock_policy_res2 = req->rq_status;
                                 RETURN(ELDLM_LOCK_ABORTED);
                         }
@@ -1823,41 +1706,25 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                  * whatever lock it was about to get.
                  */
                 new_lock = ldlm_handle2lock(&lockh);
-                if (flags & LDLM_FL_INTENT_ONLY && !new_lock)
-                        RETURN(ELDLM_LOCK_ABORTED);
-
+                if (new_lock == NULL && (flags & LDLM_FL_INTENT_ONLY))
+                        RETURN(0);
+                
                 LASSERT(new_lock != NULL);
 
                 /* If we've already given this lock to a client once, then we
                  * should have no readers or writers.  Otherwise, we should
-                 * have one reader _or_ writer ref (which will be zeroed below
+                 * have one reader _or_ writer ref (which will be zeroed below)
                  * before returning the lock to a client.
                  */
-                if (new_lock->l_export == req->rq_export)
+                if (new_lock->l_export == req->rq_export) {
                         LASSERT(new_lock->l_readers + new_lock->l_writers == 0);
-                else {
+                } else {
                         LASSERT(new_lock->l_export == NULL);
                         LASSERT(new_lock->l_readers + new_lock->l_writers == 1);
                 }
 
-                /* If we're running an intent only, we want to abort the new
-                 * lock, and let the client abort the original lock. */
-                if (flags & LDLM_FL_INTENT_ONLY) {
-                        LDLM_DEBUG(lock, "INTENT_ONLY, aborting locks");
-                        l_lock(&new_lock->l_resource->lr_namespace->ns_lock);
-                        if (new_lock->l_readers)
-                                ldlm_lock_decref(&lockh, LCK_PR);
-                        else
-                                ldlm_lock_decref(&lockh, LCK_PW);
-                        l_unlock(&new_lock->l_resource->lr_namespace->ns_lock);
-                        LDLM_LOCK_PUT(new_lock);
-                        RETURN(ELDLM_LOCK_ABORTED);
-                }
-
                 *lockp = new_lock;
 
-                rep->lock_policy_res2 = req->rq_status;
-
                 if (new_lock->l_export == req->rq_export) {
                         /* Already gave this to the client, which means that we
                          * reconstructed a reply. */
@@ -1875,16 +1742,13 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                 list_add(&new_lock->l_export_chain,
                          &new_lock->l_export->exp_ldlm_data.led_held_locks);
 
-                /* We don't need to worry about completion_ast (which isn't set
-                 * in 'lock' yet anyways), because this lock is already
-                 * granted. */
                 new_lock->l_blocking_ast = lock->l_blocking_ast;
+                new_lock->l_completion_ast = lock->l_completion_ast;
 
                 memcpy(&new_lock->l_remote_handle, &lock->l_remote_handle,
                        sizeof(lock->l_remote_handle));
 
-                new_lock->l_flags &= ~(LDLM_FL_LOCAL | LDLM_FL_AST_SENT |
-                                       LDLM_FL_CBPENDING);
+                new_lock->l_flags &= ~LDLM_FL_LOCAL;
 
                 LDLM_LOCK_PUT(new_lock);
                 l_unlock(&new_lock->l_resource->lr_namespace->ns_lock);
@@ -1892,8 +1756,8 @@ static int ldlm_intent_policy(struct ldlm_namespace *ns,
                 RETURN(ELDLM_LOCK_REPLACED);
         } else {
                 int size = sizeof(struct ldlm_reply);
-                if (lustre_pack_msg(1, &size, NULL, &req->rq_replen,
-                                    &req->rq_repmsg)) {
+                rc = lustre_pack_reply(req, 1, &size, NULL);
+                if (rc) {
                         LBUG();
                         RETURN(-ENOMEM);
                 }
@@ -1930,83 +1794,65 @@ int mdt_detach(struct obd_device *dev)
 static int mdt_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
         struct mds_obd *mds = &obddev->u.mds;
-        int i, rc = 0;
+        int rc = 0;
         ENTRY;
 
         mds->mds_service = ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS,
                                            MDS_BUFSIZE, MDS_MAXREQSIZE,
                                            MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
-                                           mds_handle, "mds", obddev);
+                                           mds_handle, "mds", 
+                                           obddev->obd_proc_entry);
 
         if (!mds->mds_service) {
                 CERROR("failed to start service\n");
                 RETURN(rc = -ENOMEM);
         }
 
-        for (i = 0; i < MDT_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ll_mdt_%02d", i);
-                rc = ptlrpc_start_thread(obddev, mds->mds_service, name);
-                if (rc) {
-                        CERROR("cannot start MDT thread #%d: rc %d\n", i, rc);
-                        GOTO(err_thread, rc);
-                }
-        }
+        rc = ptlrpc_start_n_threads(obddev, mds->mds_service, MDT_NUM_THREADS,
+                                    "ll_mdt");
+        if (rc)
+                GOTO(err_thread, rc);
 
         mds->mds_setattr_service =
                 ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS,
                                 MDS_BUFSIZE, MDS_MAXREQSIZE,
                                 MDS_SETATTR_PORTAL, MDC_REPLY_PORTAL,
-                                mds_handle, "mds_setattr", obddev);
+                                mds_handle, "mds_setattr", 
+                                obddev->obd_proc_entry);
         if (!mds->mds_setattr_service) {
                 CERROR("failed to start getattr service\n");
                 GOTO(err_thread, rc = -ENOMEM);
         }
 
-        for (i = 0; i < MDT_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ll_mdt_attr_%02d", i);
-                rc = ptlrpc_start_thread(obddev, mds->mds_setattr_service,
-                                         name);
-                if (rc) {
-                        CERROR("cannot start MDT setattr thread #%d: rc %d\n",
-                               i, rc);
-                        GOTO(err_thread2, rc);
-                }
-        }
-
+        rc = ptlrpc_start_n_threads(obddev, mds->mds_setattr_service,
+                                 MDT_NUM_THREADS, "ll_mdt_attr");
+        if (rc)
+                GOTO(err_thread2, rc);
+                        
         mds->mds_readpage_service =
                 ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS,
                                 MDS_BUFSIZE, MDS_MAXREQSIZE,
                                 MDS_READPAGE_PORTAL, MDC_REPLY_PORTAL,
-                                mds_handle, "mds_readpage", obddev);
+                                mds_handle, "mds_readpage", 
+                                obddev->obd_proc_entry);
         if (!mds->mds_readpage_service) {
                 CERROR("failed to start readpage service\n");
                 GOTO(err_thread2, rc = -ENOMEM);
         }
 
-        for (i = 0; i < MDT_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ll_mdt_rdpg_%02d", i);
-                rc = ptlrpc_start_thread(obddev, mds->mds_readpage_service,
-                                         name);
-                if (rc) {
-                        CERROR("cannot start MDT readpage thread #%d: rc %d\n",
-                               i, rc);
-                        GOTO(err_thread3, rc);
-                }
-        }
+        rc = ptlrpc_start_n_threads(obddev, mds->mds_readpage_service,
+                                    MDT_NUM_THREADS, "ll_mdt_rdpg");
+
+        if (rc) 
+                GOTO(err_thread3, rc);
 
         RETURN(0);
 
 err_thread3:
-        ptlrpc_stop_all_threads(mds->mds_readpage_service);
         ptlrpc_unregister_service(mds->mds_readpage_service);
 err_thread2:
-        ptlrpc_stop_all_threads(mds->mds_setattr_service);
         ptlrpc_unregister_service(mds->mds_setattr_service);
 err_thread:
-        ptlrpc_stop_all_threads(mds->mds_service);
         ptlrpc_unregister_service(mds->mds_service);
         return rc;
 }
@@ -2029,8 +1875,18 @@ static int mdt_cleanup(struct obd_device *obddev, int flags)
         RETURN(0);
 }
 
-extern int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
-                         int len, void *karg, void *uarg);
+static struct dentry *mds_lvfs_fid2dentry(__u64 id, __u32 gen, __u64 gr, void *data)
+{
+        struct obd_device *obd = data;
+        struct ll_fid fid;
+        fid.id = id;
+        fid.generation = gen;
+        return mds_fid2dentry(&obd->u.mds, &fid, NULL);
+}
+
+struct lvfs_callback_ops mds_lvfs_ops = {
+        l_fid2dentry:     mds_lvfs_fid2dentry,
+};
 
 /* use obd ops to offer management infrastructure */
 static struct obd_ops mds_obd_ops = {
@@ -2038,11 +1894,21 @@ static struct obd_ops mds_obd_ops = {
         o_attach:      mds_attach,
         o_detach:      mds_detach,
         o_connect:     mds_connect,
+        o_init_export:  mds_init_export,
+        o_destroy_export:  mds_destroy_export,
         o_disconnect:  mds_disconnect,
         o_setup:       mds_setup,
+        o_postsetup:   mds_postsetup,
+        o_precleanup:  mds_precleanup,
         o_cleanup:     mds_cleanup,
+        o_postrecov:   mds_postrecov,
         o_statfs:      mds_obd_statfs,
-        o_iocontrol:   mds_iocontrol
+        o_iocontrol:   mds_iocontrol,
+        o_create:      mds_obd_create,
+        o_destroy:     mds_obd_destroy,
+        o_llog_init:   mds_llog_init,
+        o_llog_finish: mds_llog_finish,
+        o_notify:      mds_notify,
 };
 
 static struct obd_ops mdt_obd_ops = {
@@ -2053,7 +1919,6 @@ static struct obd_ops mdt_obd_ops = {
         o_cleanup:     mdt_cleanup,
 };
 
-
 static int __init mds_init(void)
 {
         struct lprocfs_static_vars lvars;
diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c
index e35541525f651856c5cfeaa7b1bef8d9801a9d27..fe883d91d2d16ee4ab33d913ca3c237ac491ac0d 100644
--- a/lustre/mds/lproc_mds.c
+++ b/lustre/mds/lproc_mds.c
@@ -25,8 +25,8 @@
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 #include <asm/statfs.h>
 #endif
-#include <linux/lustre_lite.h>
-#include <linux/lustre_fsfilt.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
 #include <linux/lprocfs_status.h>
 
 #ifndef LPROCFS
@@ -49,6 +49,99 @@ static int lprocfs_mds_rd_mntdev(char *page, char **start, off_t off, int count,
         return snprintf(page, count, "%s\n",obd->u.mds.mds_vfsmnt->mnt_devname);
 }
 
+static int lprocfs_mds_rd_recovery_status(char *page, char **start, off_t off,
+                                          int count, int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        int len = 0, n,
+                connected = obd->obd_connected_clients,
+                max_recoverable = obd->obd_max_recoverable_clients,
+                recoverable = obd->obd_recoverable_clients,
+                completed = max_recoverable - recoverable,
+                queue_len = obd->obd_requests_queued_for_recovery,
+                replayed = obd->obd_replayed_requests;
+        __u64 next_transno = obd->obd_next_recovery_transno;
+
+        LASSERT(obd != NULL);
+        *eof = 1;
+
+        n = snprintf(page, count, "status: ");
+        page += n; len += n; count -= n;
+        if (obd->obd_max_recoverable_clients == 0) {
+                n = snprintf(page, count, "INACTIVE\n");
+                return len + n;
+        }
+
+        if (obd->obd_recoverable_clients == 0) {
+                n = snprintf(page, count, "COMPLETE\n");
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "recovered_clients: %d\n",
+                             max_recoverable);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "last_transno: "LPD64"\n",
+                             next_transno - 1);
+                page += n; len += n; count -= n;
+                n = snprintf(page, count, "replayed_requests: %d\n", replayed);
+                return len + n;
+        }
+
+        /* sampled unlocked, but really... */
+        if (obd->obd_recovering == 0) {
+                n = snprintf(page, count, "ABORTED\n");
+                return len + n;
+        }
+
+        n = snprintf(page, count, "RECOVERING\n");
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "connected_clients: %d/%d\n",
+                     connected, max_recoverable);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "completed_clients: %d/%d\n",
+                     completed, max_recoverable);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "replayed_requests: %d/??\n", replayed);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "queued_requests: %d\n", queue_len);
+        page += n; len += n; count -= n;
+        n = snprintf(page, count, "next_transno: "LPD64"\n", next_transno);
+        return len + n;
+}
+
+static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer,
+                                       unsigned long count, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *doomed_exp = NULL;
+        struct obd_uuid doomed;
+        struct list_head *p;
+        char tmpbuf[sizeof(doomed)];
+
+        sscanf(buffer, "%40s", tmpbuf);
+        obd_str2uuid(&doomed, tmpbuf);
+
+        spin_lock(&obd->obd_dev_lock);
+        list_for_each(p, &obd->obd_exports) {
+                doomed_exp = list_entry(p, struct obd_export, exp_obd_chain);
+                if (obd_uuid_equals(&doomed, &doomed_exp->exp_client_uuid)) {
+                        class_export_get(doomed_exp);
+                        break;
+                }
+                doomed_exp = NULL;
+        }
+        spin_unlock(&obd->obd_dev_lock);
+
+        if (doomed_exp == NULL) {
+                CERROR("can't disconnect %s: no export found\n",
+                       doomed.uuid);
+        } else {
+                CERROR("evicting %s at adminstrative request\n",
+                       doomed.uuid);
+                ptlrpc_fail_export(doomed_exp);
+                class_export_put(doomed_exp);
+        }
+        return count;
+}
+
 struct lprocfs_vars lprocfs_mds_obd_vars[] = {
         { "uuid",         lprocfs_rd_uuid,        0, 0 },
         { "blocksize",    lprocfs_rd_blksize,     0, 0 },
@@ -59,6 +152,8 @@ struct lprocfs_vars lprocfs_mds_obd_vars[] = {
         { "filesfree",    lprocfs_rd_filesfree,   0, 0 },
         //{ "filegroups",   lprocfs_rd_filegroups,  0, 0 },
         { "mntdev",       lprocfs_mds_rd_mntdev,  0, 0 },
+        { "recovery_status", lprocfs_mds_rd_recovery_status, 0, 0 },
+        { "evict_client", 0, lprocfs_mds_wr_evict_client, 0 },
         { 0 }
 };
 
diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c
index 40d281b34afd30397ba9488d1b43c00bc97e169b..f0f7552734d7078a106b7c4ef75f834ecbe9c336 100644
--- a/lustre/mds/mds_fs.c
+++ b/lustre/mds/mds_fs.c
@@ -23,7 +23,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <linux/module.h>
@@ -46,6 +48,7 @@
 #define MDS_MAX_CLIENT_WORDS (MDS_MAX_CLIENTS / sizeof(unsigned long))
 
 #define LAST_RCVD "last_rcvd"
+#define LOV_OBJID "lov_objid"
 
 /* Add client data to the MDS.  We use a bitmap to locate a free space
  * in the last_rcvd file if cl_off is -1 (i.e. a new client).
@@ -57,11 +60,12 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
 {
         unsigned long *bitmap = mds->mds_client_bitmap;
         int new_client = (cl_idx == -1);
+        ENTRY;
 
         LASSERT(bitmap != NULL);
 
         /* XXX if mcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
-        if (!strcmp(med->med_mcd->mcd_uuid, "OBD_CLASS_UUID"))
+        if (!strcmp(med->med_mcd->mcd_uuid, obd->obd_uuid.uuid))
                 RETURN(0);
 
         /* the bitmap operations can handle cl_idx > sizeof(long) * 8, so
@@ -75,8 +79,6 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
                         return -ENOMEM;
                 }
                 if (test_and_set_bit(cl_idx, bitmap)) {
-                        CERROR("MDS client %d: found bit is set in bitmap\n",
-                               cl_idx);
                         cl_idx = find_next_zero_bit(bitmap, MDS_MAX_CLIENTS,
                                                     cl_idx);
                         goto repeat;
@@ -98,10 +100,11 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
         if (new_client) {
                 struct obd_run_ctxt saved;
                 loff_t off = med->med_off;
-                ssize_t written;
+                struct file *file = mds->mds_rcvd_filp;
                 void *handle;
+                int rc, err;
 
-                push_ctxt(&saved, &mds->mds_ctxt, NULL);
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
                 /* We need to start a transaction here first, to avoid a
                  * possible ordering deadlock on last_rcvd->i_sem and the
                  * journal lock. In most places we start the journal handle
@@ -117,27 +120,24 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
                  * ops include enough space for the last_rcvd update so we
                  * could use any of them, or maybe an FSFILT_OP_NONE is best?
                  */
-                handle = fsfilt_start(obd,mds->mds_rcvd_filp->f_dentry->d_inode,
+                handle = fsfilt_start(obd, file->f_dentry->d_inode,
                                       FSFILT_OP_SETATTR, NULL);
                 if (IS_ERR(handle)) {
-                        written = PTR_ERR(handle);
-                        CERROR("unable to start transaction: rc %d\n",
-                               (int)written);
+                        rc = PTR_ERR(handle);
+                        CERROR("unable to start transaction: rc %d\n", rc);
                 } else {
-                        written = fsfilt_write_record(obd, mds->mds_rcvd_filp,
-                                                      med->med_mcd,
-                                                      sizeof(*med->med_mcd),
-                                                      &off);
-                        fsfilt_commit(obd,mds->mds_rcvd_filp->f_dentry->d_inode,
-                                      handle, 0);
+                        rc = fsfilt_write_record(obd, file, med->med_mcd,
+                                                 sizeof(*med->med_mcd),
+                                                 &off, 1);
+                        err = fsfilt_commit(obd, file->f_dentry->d_inode,
+                                            handle, 1);
+                        if (rc == 0)
+                                rc = err;
                 }
-                pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-                if (written != sizeof(*med->med_mcd)) {
-                        if (written < 0)
-                                RETURN(written);
-                        RETURN(-EIO);
-                }
+                if (rc)
+                        return rc;
                 CDEBUG(D_INFO, "wrote client mcd at idx %u off %llu (len %u)\n",
                        med->med_idx, med->med_off,
                        (unsigned int)sizeof(*med->med_mcd));
@@ -145,14 +145,14 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
         return 0;
 }
 
-int mds_client_free(struct obd_export *exp)
+int mds_client_free(struct obd_export *exp, int clear_client)
 {
         struct mds_export_data *med = &exp->exp_mds_data;
         struct mds_obd *mds = &exp->exp_obd->u.mds;
         struct obd_device *obd = exp->exp_obd;
         struct mds_client_data zero_mcd;
         struct obd_run_ctxt saved;
-        int written;
+        int rc;
         unsigned long *bitmap = mds->mds_client_bitmap;
 
         LASSERT(bitmap);
@@ -160,7 +160,7 @@ int mds_client_free(struct obd_export *exp)
                 RETURN(0);
 
         /* XXX if mcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
-        if (!strcmp(med->med_mcd->mcd_uuid, "OBD_CLASS_UUID"))
+        if (!strcmp(med->med_mcd->mcd_uuid, obd->obd_uuid.uuid))
                 GOTO(free_and_out, 0);
 
         CDEBUG(D_INFO, "freeing client at index %u (%lld)with UUID '%s'\n",
@@ -172,19 +172,17 @@ int mds_client_free(struct obd_export *exp)
                 LBUG();
         }
 
-        memset(&zero_mcd, 0, sizeof zero_mcd);
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
-        written = fsfilt_write_record(obd, mds->mds_rcvd_filp, &zero_mcd,
-                                      sizeof(zero_mcd), &med->med_off);
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
-
-        if (written != sizeof(zero_mcd)) {
-                CERROR("error zeroing out client %s index %d in %s: %d\n",
-                       med->med_mcd->mcd_uuid, med->med_idx, LAST_RCVD,
-                       written);
-        } else {
-                CDEBUG(D_INFO, "zeroed out disconnecting client %s at off %d\n",
-                       med->med_mcd->mcd_uuid, med->med_idx);
+        if (clear_client) {
+                memset(&zero_mcd, 0, sizeof zero_mcd);
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = fsfilt_write_record(obd, mds->mds_rcvd_filp,
+                                              &zero_mcd, sizeof(zero_mcd),
+                                              &med->med_off, 1);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+                CDEBUG(rc == 0 ? D_INFO : D_ERROR,
+                       "zeroing out client %s off %u in %s rc %d\n",
+                       med->med_mcd->mcd_uuid, med->med_idx, LAST_RCVD, rc);
         }
 
  free_and_out:
@@ -209,20 +207,20 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
         struct mds_server_data *msd;
         struct mds_client_data *mcd = NULL;
         loff_t off = 0;
-        int cl_idx;
         unsigned long last_rcvd_size = file->f_dentry->d_inode->i_size;
         __u64 last_transno = 0;
         __u64 mount_count;
-        int rc = 0;
+        int cl_idx, rc = 0;
+        ENTRY;
 
         LASSERT(sizeof(struct mds_client_data) == MDS_LR_CLIENT_SIZE);
         LASSERT(sizeof(struct mds_server_data) <= MDS_LR_SERVER_SIZE);
 
-        OBD_ALLOC(msd, sizeof(*msd));
+        OBD_ALLOC_WAIT(msd, sizeof(*msd));
         if (!msd)
                 RETURN(-ENOMEM);
 
-        OBD_ALLOC(mds->mds_client_bitmap,
+        OBD_ALLOC_WAIT(mds->mds_client_bitmap,
                   MDS_MAX_CLIENT_WORDS * sizeof(unsigned long));
         if (!mds->mds_client_bitmap) {
                 OBD_FREE(msd, sizeof(*msd));
@@ -232,28 +230,24 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
         mds->mds_server_data = msd;
 
         if (last_rcvd_size == 0) {
-                int written;
                 CWARN("%s: initializing new %s\n", obd->obd_name, LAST_RCVD);
                 memcpy(msd->msd_uuid, obd->obd_uuid.uuid,sizeof(msd->msd_uuid));
                 msd->msd_server_size = cpu_to_le32(MDS_LR_SERVER_SIZE);
                 msd->msd_client_start = cpu_to_le32(MDS_LR_CLIENT_START);
                 msd->msd_client_size = cpu_to_le16(MDS_LR_CLIENT_SIZE);
-                written = fsfilt_write_record(obd, file, msd, sizeof(*msd),
-                                              &off);
+                msd->msd_feature_rocompat = cpu_to_le32(MDS_ROCOMPAT_LOVOBJID);
+                rc = fsfilt_write_record(obd, file, msd, sizeof(*msd), &off, 1);
 
-                if (written == sizeof(*msd))
+                if (rc == 0)
                         RETURN(0);
-                CERROR("%s: error writing new MSD: %d\n", obd->obd_name,
-                       written);
-                GOTO(err_msd, rc = (written < 0 ? written : -EIO));
+
+                CERROR("%s: error writing new MSD: %d\n", obd->obd_name, rc);
+                GOTO(err_msd, rc);
         }
 
         rc = fsfilt_read_record(obd, file, msd, sizeof(*msd), &off);
-
-        if (rc != sizeof(*msd)) {
-                CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD,rc);
-                if (rc >= 0)
-                        rc = -EIO;
+        if (rc) {
+                CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD, rc);
                 GOTO(err_msd, rc);
         }
         if (!msd->msd_server_size)
@@ -263,14 +257,18 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
         if (!msd->msd_client_size)
                 msd->msd_client_size = cpu_to_le16(MDS_LR_CLIENT_SIZE);
 
-        if (msd->msd_feature_incompat) {
+        if (msd->msd_feature_incompat & ~cpu_to_le32(MDS_INCOMPAT_SUPP)) {
                 CERROR("unsupported incompat feature %x\n",
-                       le32_to_cpu(msd->msd_feature_incompat));
+                       le32_to_cpu(msd->msd_feature_incompat) &
+                       ~MDS_INCOMPAT_SUPP);
                 GOTO(err_msd, rc = -EINVAL);
         }
-        if (msd->msd_feature_rocompat) {
+        /* XXX updating existing b_devel fs only, can be removed in future */
+        msd->msd_feature_rocompat = cpu_to_le32(MDS_ROCOMPAT_LOVOBJID);
+        if (msd->msd_feature_rocompat & ~cpu_to_le32(MDS_ROCOMPAT_SUPP)) {
                 CERROR("unsupported read-only feature %x\n",
-                       le32_to_cpu(msd->msd_feature_rocompat));
+                       le32_to_cpu(msd->msd_feature_rocompat) &
+                       ~MDS_ROCOMPAT_SUPP);
                 /* Do something like remount filesystem read-only */
                 GOTO(err_msd, rc = -EINVAL);
         }
@@ -294,33 +292,33 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
         CDEBUG(D_INODE, "%s: last_rcvd size: %lu\n",
                obd->obd_name, last_rcvd_size);
         CDEBUG(D_INODE, "%s: last_rcvd clients: %lu\n", obd->obd_name,
+               last_rcvd_size <= MDS_LR_CLIENT_START ? 0 :
                (last_rcvd_size - MDS_LR_CLIENT_START) / MDS_LR_CLIENT_SIZE);
 
-        /* When we do a clean FILTER shutdown, we save the last_transno into
+        /* When we do a clean MDS shutdown, we save the last_transno into
          * the header.  If we find clients with higher last_transno values
          * then those clients may need recovery done. */
-        for (cl_idx = 0; off < last_rcvd_size; cl_idx++) {
+        for (cl_idx = 0, off = le32_to_cpu(msd->msd_client_start);
+             off < last_rcvd_size; cl_idx++) {
                 __u64 last_transno;
                 int mount_age;
 
                 if (!mcd) {
-                        OBD_ALLOC(mcd, sizeof(*mcd));
+                        OBD_ALLOC_WAIT(mcd, sizeof(*mcd));
                         if (!mcd)
-                                GOTO(err_msd, rc = -ENOMEM);
+                                GOTO(err_client, rc = -ENOMEM);
                 }
 
-                /* Don't assume off is incremented properly, in case
-                 * sizeof(fsd) isn't the same as fsd->fsd_client_size.
-                 */
+                /* Don't assume off is incremented properly by
+                 * fsfilt_read_record(), in case sizeof(*mcd)
+                 * isn't the same as msd->msd_client_size.  */
                 off = le32_to_cpu(msd->msd_client_start) +
                         cl_idx * le16_to_cpu(msd->msd_client_size);
                 rc = fsfilt_read_record(obd, file, mcd, sizeof(*mcd), &off);
-                if (rc != sizeof(*mcd)) {
-                        CERROR("error reading MDS %s offset %d: rc = %d\n",
-                               LAST_RCVD, cl_idx, rc);
-                        if (rc > 0) /* XXX fatal error or just abort reading? */
-                                rc = -EIO;
-                        break;
+                if (rc) {
+                        CERROR("error reading MDS %s idx %d, off %llu: rc %d\n",
+                               LAST_RCVD, cl_idx, off, rc);
+                        break; /* read error shouldn't cause startup to fail */
                 }
 
                 if (mcd->mcd_uuid[0] == '\0') {
@@ -338,16 +336,13 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
                 if (mount_age < MDS_MOUNT_RECOV) {
                         struct obd_export *exp = class_new_export(obd);
                         struct mds_export_data *med;
-                        CERROR("RCVRNG CLIENT uuid: %s off: %d lr: "LPU64
-                               "srv lr: "LPU64" mnt: "LPU64" last mount: "LPU64
-                               "\n", mcd->mcd_uuid, cl_idx,
+                        CDEBUG(D_HA, "RCVRNG CLIENT uuid: %s idx: %d lr: "LPU64
+                               " srv lr: "LPU64" mnt: "LPU64" last mount: "
+                               LPU64"\n", mcd->mcd_uuid, cl_idx,
                                last_transno, le64_to_cpu(msd->msd_last_transno),
                                le64_to_cpu(mcd->mcd_mount_count), mount_count);
-
-                        if (!exp) {
-                                rc = -ENOMEM;
-                                break;
-                        }
+                        if (exp == NULL)
+                                GOTO(err_client, rc = -ENOMEM);
 
                         memcpy(&exp->exp_client_uuid.uuid, mcd->mcd_uuid,
                                sizeof exp->exp_client_uuid.uuid);
@@ -360,6 +355,7 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
 
                         mcd = NULL;
                         obd->obd_recoverable_clients++;
+                        obd->obd_max_recoverable_clients++;
                         class_export_put(exp);
                 } else {
                         CDEBUG(D_INFO, "discarded client %d, UUID '%s', count "
@@ -367,8 +363,8 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
                                le64_to_cpu(mcd->mcd_mount_count));
                 }
 
-                CDEBUG(D_OTHER, "client at offset %d has last_transno = "
-                       LPU64"\n", cl_idx, last_transno);
+                CDEBUG(D_OTHER, "client at idx %d has last_transno = "LPU64"\n",
+                       cl_idx, last_transno);
 
                 if (last_transno > mds->mds_last_transno)
                         mds->mds_last_transno = last_transno;
@@ -376,11 +372,10 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
 
         obd->obd_last_committed = mds->mds_last_transno;
         if (obd->obd_recoverable_clients) {
-                CERROR("RECOVERY: %d recoverable clients, last_transno "
-                       LPU64"\n",
-                       obd->obd_recoverable_clients, mds->mds_last_transno);
-                obd->obd_next_recovery_transno = obd->obd_last_committed
-                        + 1;
+                CWARN("RECOVERY: %d recoverable clients, last_transno "
+                       LPU64"\n", obd->obd_recoverable_clients,
+                       mds->mds_last_transno);
+                obd->obd_next_recovery_transno = obd->obd_last_committed + 1;
                 obd->obd_recovering = 1;
         }
 
@@ -389,20 +384,40 @@ static int mds_read_last_rcvd(struct obd_device *obd, struct file *file)
 
         return 0;
 
+err_client:
+        class_disconnect_exports(obd, 0);
 err_msd:
         mds_server_free_data(mds);
         return rc;
 }
 
-static int mds_fs_prep(struct obd_device *obd)
+int mds_fs_setup(struct obd_device *obd, struct vfsmount *mnt)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct obd_run_ctxt saved;
         struct dentry *dentry;
         struct file *file;
         int rc;
+        ENTRY;
+
+
+        /* Get rid of unneeded supplementary groups */
+        current->ngroups = 0;
+        memset(current->groups, 0, sizeof(current->groups));
+
+        mds->mds_vfsmnt = mnt;
+        mds->mds_sb = mnt->mnt_root->d_inode->i_sb;
+
+        fsfilt_setup(obd, mds->mds_sb);
+
+        OBD_SET_CTXT_MAGIC(&obd->obd_ctxt);
+        obd->obd_ctxt.pwdmnt = mnt;
+        obd->obd_ctxt.pwd = mnt->mnt_root;
+        obd->obd_ctxt.fs = get_ds();
+        obd->obd_ctxt.cb_ops = mds_lvfs_ops;
 
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
+        /* setup the directory tree */
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755);
         if (IS_ERR(dentry)) {
                 rc = PTR_ERR(dentry);
@@ -433,7 +448,7 @@ static int mds_fs_prep(struct obd_device *obd)
         }
         mds->mds_pending_dir = dentry;
 
-        dentry = simple_mkdir(current->fs->pwd, "LOGS", 0700);
+        dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777);
         if (IS_ERR(dentry)) {
                 rc = PTR_ERR(dentry);
                 CERROR("cannot create LOGS directory: rc = %d\n", rc);
@@ -441,48 +456,62 @@ static int mds_fs_prep(struct obd_device *obd)
         }
         mds->mds_logs_dir = dentry;
 
+        dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777);
+        if (IS_ERR(dentry)) {
+                rc = PTR_ERR(dentry);
+                CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
+                GOTO(err_logs, rc);
+        }
+        mds->mds_objects_dir = dentry;
+
+        /* open and test the last rcvd file */
         file = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0644);
         if (IS_ERR(file)) {
                 rc = PTR_ERR(file);
                 CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc);
-
-                GOTO(err_logs, rc = PTR_ERR(file));
+                GOTO(err_objects, rc = PTR_ERR(file));
         }
+        mds->mds_rcvd_filp = file;
         if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
                 CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD,
                        file->f_dentry->d_inode->i_mode);
-                GOTO(err_filp, rc = -ENOENT);
-        }
-
-        rc = fsfilt_journal_data(obd, file);
-        if (rc) {
-                CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_filp, rc);
+                GOTO(err_last_rcvd, rc = -ENOENT);
         }
 
         rc = mds_read_last_rcvd(obd, file);
         if (rc) {
                 CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_client, rc);
+                GOTO(err_last_rcvd, rc);
+        }
+
+        /* open and test the lov objd file */
+        file = filp_open(LOV_OBJID, O_RDWR | O_CREAT, 0644);
+        if (IS_ERR(file)) {
+                rc = PTR_ERR(file);
+                CERROR("cannot open/create %s file: rc = %d\n", LOV_OBJID, rc);
+                GOTO(err_client, rc = PTR_ERR(file));
+        }
+        mds->mds_lov_objid_filp = file;
+        if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+                CERROR("%s is not a regular file!: mode = %o\n", LOV_OBJID,
+                       file->f_dentry->d_inode->i_mode);
+                GOTO(err_lov_objid, rc = -ENOENT);
         }
-        mds->mds_rcvd_filp = file;
-#ifdef I_SKIP_PDFLUSH
-        /*
-         * we need this to protect from deadlock
-         * pdflush vs. lustre_fwrite()
-         */
-        file->f_dentry->d_inode->i_flags |= I_SKIP_PDFLUSH;
-#endif
 err_pop:
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
         return rc;
 
+err_lov_objid:
+        if (mds->mds_lov_objid_filp && filp_close(mds->mds_lov_objid_filp, 0))
+                CERROR("can't close %s after error\n", LOV_OBJID);
 err_client:
         class_disconnect_exports(obd, 0);
-err_filp:
-        if (filp_close(file, 0))
+err_last_rcvd:
+        if (mds->mds_rcvd_filp && filp_close(mds->mds_rcvd_filp, 0))
                 CERROR("can't close %s after error\n", LAST_RCVD);
+err_objects:
+        dput(mds->mds_objects_dir);
 err_logs:
         dput(mds->mds_logs_dir);
 err_pending:
@@ -492,19 +521,6 @@ err_fid:
         goto err_pop;
 }
 
-int mds_fs_setup(struct obd_device *obd, struct vfsmount *mnt)
-{
-        struct mds_obd *mds = &obd->u.mds;
-        ENTRY;
-
-        mds->mds_vfsmnt = mnt;
-
-        OBD_SET_CTXT_MAGIC(&mds->mds_ctxt);
-        mds->mds_ctxt.pwdmnt = mnt;
-        mds->mds_ctxt.pwd = mnt->mnt_root;
-        mds->mds_ctxt.fs = get_ds();
-        RETURN(mds_fs_prep(obd));
-}
 
 int mds_fs_cleanup(struct obd_device *obd, int flags)
 {
@@ -519,13 +535,23 @@ int mds_fs_cleanup(struct obd_device *obd, int flags)
         class_disconnect_exports(obd, flags); /* cleans up client info too */
         mds_server_free_data(mds);
 
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         if (mds->mds_rcvd_filp) {
                 rc = filp_close(mds->mds_rcvd_filp, 0);
                 mds->mds_rcvd_filp = NULL;
                 if (rc)
                         CERROR("%s file won't close, rc=%d\n", LAST_RCVD, rc);
         }
+        if (mds->mds_lov_objid_filp) {
+                rc = filp_close(mds->mds_lov_objid_filp, 0);
+                mds->mds_lov_objid_filp = NULL;
+                if (rc)
+                        CERROR("%s file won't close, rc=%d\n", LOV_OBJID, rc);
+        }
+        if (mds->mds_objects_dir != NULL) {
+                l_dput(mds->mds_objects_dir);
+                mds->mds_objects_dir = NULL;
+        }
         if (mds->mds_logs_dir) {
                 l_dput(mds->mds_logs_dir);
                 mds->mds_logs_dir = NULL;
@@ -534,239 +560,140 @@ int mds_fs_cleanup(struct obd_device *obd, int flags)
                 l_dput(mds->mds_pending_dir);
                 mds->mds_pending_dir = NULL;
         }
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
         shrink_dcache_parent(mds->mds_fid_de);
         dput(mds->mds_fid_de);
 
         return rc;
 }
 
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-int mds_log_close(struct llog_handle *cathandle, struct llog_handle *loghandle)
+/* Creates an object with the same name as its fid.  Because this is not at all
+ * performance sensitive, it is accomplished by creating a file, checking the
+ * fid, and renaming it. */
+int mds_obd_create(struct obd_export *exp, struct obdo *oa,
+                      struct lov_stripe_md **ea, struct obd_trans_info *oti)
 {
-        struct llog_object_hdr *llh = loghandle->lgh_hdr;
-        struct mds_obd *mds = &cathandle->lgh_obd->u.mds;
-        struct dentry *dchild = NULL;
-        int rc;
+        struct mds_obd *mds = &exp->exp_obd->u.mds;
+        struct inode *parent_inode = mds->mds_objects_dir->d_inode;
+        unsigned int tmpname = ll_insecure_random_int();
+        struct file *filp;
+        struct dentry *new_child;
+        struct obd_run_ctxt saved;
+        char fidname[LL_FID_NAMELEN];
+        void *handle;
+        int rc = 0, err, namelen;
         ENTRY;
 
-        /* If we are going to delete this log, grab a ref before we close
-         * it so we don't have to immediately do another lookup.
-         */
-        if (llh->llh_hdr.lth_type != LLOG_CATALOG_MAGIC && llh->llh_count == 0){
-                CDEBUG(D_INODE, "deleting log file "LPX64":%x\n",
-                       loghandle->lgh_cookie.lgc_lgl.lgl_oid,
-                       loghandle->lgh_cookie.lgc_lgl.lgl_ogen);
-                down(&mds->mds_logs_dir->d_inode->i_sem);
-                dchild = dget(loghandle->lgh_file->f_dentry);
-                llog_delete_log(cathandle, loghandle);
-        } else {
-                CDEBUG(D_INODE, "closing log file "LPX64":%x\n",
-                       loghandle->lgh_cookie.lgc_lgl.lgl_oid,
-                       loghandle->lgh_cookie.lgc_lgl.lgl_ogen);
-        }
-
-        rc = filp_close(loghandle->lgh_file, 0);
-
-        llog_free_handle(loghandle); /* also removes loghandle from list */
-
-        if (dchild) {
-                int err = vfs_unlink(mds->mds_logs_dir->d_inode, dchild);
-                if (err) {
-                        CERROR("error unlinking empty log %*s: rc %d\n",
-                               dchild->d_name.len, dchild->d_name.name, err);
-                        if (!rc)
-                                rc = err;
+        push_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
+        
+        sprintf(fidname, "OBJECTS/%u", tmpname);
+        filp = filp_open(fidname, O_CREAT | O_EXCL, 0644);
+        if (IS_ERR(filp)) {
+                rc = PTR_ERR(filp);
+                if (rc == -EEXIST) {
+                        CERROR("impossible object name collision %u\n",
+                               tmpname);
+                        LBUG();
                 }
-                l_dput(dchild);
-                up(&mds->mds_logs_dir->d_inode->i_sem);
+                CERROR("error creating tmp object %u: rc %d\n", tmpname, rc);
+                GOTO(out_pop, rc);
         }
-        RETURN(rc);
-}
 
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-struct llog_handle *mds_log_open(struct obd_device *obd,
-                                 struct llog_cookie *logcookie)
-{
-        struct ll_fid fid = { .id = logcookie->lgc_lgl.lgl_oid,
-                              .generation = logcookie->lgc_lgl.lgl_ogen,
-                              .f_type = S_IFREG };
-        struct llog_handle *loghandle;
-        struct dentry *dchild;
-        int rc;
-        ENTRY;
-
-        loghandle = llog_alloc_handle();
-        if (loghandle == NULL)
-                RETURN(ERR_PTR(-ENOMEM));
-
-        down(&obd->u.mds.mds_logs_dir->d_inode->i_sem);
-        dchild = mds_fid2dentry(&obd->u.mds, &fid, NULL);
-        up(&obd->u.mds.mds_logs_dir->d_inode->i_sem);
-        if (IS_ERR(dchild)) {
-                rc = PTR_ERR(dchild);
-                CERROR("error looking up log file "LPX64":%x: rc %d\n",
-                       fid.id, fid.generation, rc);
-                GOTO(out, rc);
-        }
-
-        if (dchild->d_inode == NULL) {
-                rc = -ENOENT;
-                CERROR("nonexistent log file "LPX64":%x: rc %d\n",
-                       fid.id, fid.generation, rc);
-                GOTO(out_put, rc);
-        }
-
-        /* dentry_open does a dput(de) and mntput(mds->mds_vfsmnt) on error */
-        mntget(obd->u.mds.mds_vfsmnt);
-        loghandle->lgh_file = dentry_open(dchild, obd->u.mds.mds_vfsmnt,
-                                          O_RDWR | O_LARGEFILE);
-        if (IS_ERR(loghandle->lgh_file)) {
-                rc = PTR_ERR(loghandle->lgh_file);
-                CERROR("error opening logfile "LPX64":%x: rc %d\n",
-                       fid.id, fid.generation, rc);
-                GOTO(out, rc);
-        }
-        memcpy(&loghandle->lgh_cookie, logcookie, sizeof(*logcookie));
-        loghandle->lgh_log_create = mds_log_create;
-        loghandle->lgh_log_open = mds_log_open;
-        loghandle->lgh_log_close = mds_log_close;
-        loghandle->lgh_obd = obd;
-
-        RETURN(loghandle);
-
-out_put:
-        l_dput(dchild);
-out:
-        llog_free_handle(loghandle);
-        return ERR_PTR(rc);
-}
+        LASSERT(mds->mds_objects_dir == filp->f_dentry->d_parent);
 
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-struct llog_handle *mds_log_create(struct obd_device *obd)
-{
-        char logbuf[24], *logname; /* logSSSSSSSSSS.count */
-        struct llog_handle *loghandle;
-        int rc, open_flags = O_RDWR | O_CREAT | O_LARGEFILE;
-        ENTRY;
+        oa->o_id = filp->f_dentry->d_inode->i_ino;
+        oa->o_generation = filp->f_dentry->d_inode->i_generation;
+        namelen = ll_fid2str(fidname, oa->o_id, oa->o_generation);
 
-        loghandle = llog_alloc_handle();
-        if (!loghandle)
-                RETURN(ERR_PTR(-ENOMEM));
+        down(&parent_inode->i_sem);
+        new_child = lookup_one_len(fidname, mds->mds_objects_dir, namelen);
 
-retry:
-        if (!obd->u.mds.mds_catalog) {
-                logname = "LOGS/catalog";
-        } else {
-                sprintf(logbuf, "LOGS/log%lu.%u\n",
-                        CURRENT_SECONDS, obd->u.mds.mds_catalog->lgh_index++);
-                open_flags |= O_EXCL;
-                logname = logbuf;
-        }
-        loghandle->lgh_file = filp_open(logname, open_flags, 0644);
-        if (IS_ERR(loghandle->lgh_file)) {
-                rc = PTR_ERR(loghandle->lgh_file);
-                if (rc == -EEXIST) {
-                        CDEBUG(D_HA, "collision in logfile %s creation\n",
-                               logname);
-                        obd->u.mds.mds_catalog->lgh_index++;
-                        goto retry;
-                }
-                CERROR("error opening/creating %s: rc %d\n", logname, rc);
-                GOTO(out_handle, rc);
+        if (IS_ERR(new_child)) {
+                CERROR("getting neg dentry for obj rename: %d\n", rc);
+                GOTO(out_close, rc = PTR_ERR(new_child));
+        }
+        if (new_child->d_inode != NULL) {
+                CERROR("impossible non-negative obj dentry " LPU64":%u!\n",
+                       oa->o_id, oa->o_generation);
+                LBUG();
         }
 
-        loghandle->lgh_cookie.lgc_lgl.lgl_oid =
-                loghandle->lgh_file->f_dentry->d_inode->i_ino;
-        loghandle->lgh_cookie.lgc_lgl.lgl_ogen =
-                loghandle->lgh_file->f_dentry->d_inode->i_generation;
-        loghandle->lgh_log_create = mds_log_create;
-        loghandle->lgh_log_open = mds_log_open;
-        loghandle->lgh_log_close = mds_log_close;
-        loghandle->lgh_obd = obd;
-
-        RETURN(loghandle);
-
-out_handle:
-        llog_free_handle(loghandle);
-        return ERR_PTR(rc);
+        handle = fsfilt_start(exp->exp_obd, mds->mds_objects_dir->d_inode,
+                              FSFILT_OP_RENAME, NULL);
+        if (IS_ERR(handle)) 
+                GOTO(out_dput, rc = PTR_ERR(handle));
+        
+        lock_kernel();
+        rc = vfs_rename(mds->mds_objects_dir->d_inode, filp->f_dentry,
+                        mds->mds_objects_dir->d_inode, new_child);
+        unlock_kernel();
+        if (rc)
+                CERROR("error renaming new object "LPU64":%u: rc %d\n",
+                       oa->o_id, oa->o_generation, rc);
+
+        err = fsfilt_commit(exp->exp_obd, mds->mds_objects_dir->d_inode,
+                            handle, 0);
+        if (!err)
+                oa->o_valid |= OBD_MD_FLID | OBD_MD_FLGENER;
+        else if (!rc)
+                rc = err;
+out_dput:
+        dput(new_child);
+out_close:
+        up(&parent_inode->i_sem);
+        err = filp_close(filp, 0);
+        if (err) {
+                CERROR("closing tmpfile %u: rc %d\n", tmpname, rc);
+                if (!rc)
+                        rc = err;
+        }
+out_pop:
+        pop_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
+        RETURN(rc);
 }
 
-struct llog_handle *mds_get_catalog(struct obd_device *obd)
+int mds_obd_destroy(struct obd_export *exp, struct obdo *oa,
+                    struct lov_stripe_md *ea, struct obd_trans_info *oti)
 {
-        struct mds_server_data *msd = obd->u.mds.mds_server_data;
+        struct mds_obd *mds = &exp->exp_obd->u.mds;
+        struct inode *parent_inode = mds->mds_objects_dir->d_inode;
+        struct obd_device *obd = exp->exp_obd;
         struct obd_run_ctxt saved;
-        struct llog_handle *cathandle = NULL;
-        int rc = 0;
+        char fidname[LL_FID_NAMELEN];
+        struct dentry *de;
+        void *handle;
+        int err, namelen, rc = 0;
         ENTRY;
 
-        push_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
-
-        if (msd->msd_catalog_oid) {
-                struct llog_cookie catcookie;
-
-                catcookie.lgc_lgl.lgl_oid = le64_to_cpu(msd->msd_catalog_oid);
-                catcookie.lgc_lgl.lgl_ogen = le32_to_cpu(msd->msd_catalog_ogen);
-                cathandle = mds_log_open(obd, &catcookie);
-                if (IS_ERR(cathandle)) {
-                        CERROR("error opening catalog "LPX64":%x: rc %d\n",
-                               catcookie.lgc_lgl.lgl_oid,
-                               catcookie.lgc_lgl.lgl_ogen,
-                               (int)PTR_ERR(cathandle));
-                        msd->msd_catalog_oid = 0;
-                        msd->msd_catalog_ogen = 0;
-                }
-                /* ORPHANS FIXME: compare catalog UUID to msd_peeruuid */
-        }
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-        if (!msd->msd_catalog_oid) {
-                struct llog_logid *lgl;
+        namelen = ll_fid2str(fidname, oa->o_id, oa->o_generation);
 
-                cathandle = mds_log_create(obd);
-                if (IS_ERR(cathandle)) {
-                        CERROR("error creating new catalog: rc %d\n",
-                               (int)PTR_ERR(cathandle));
-                        GOTO(out, cathandle);
-                }
-                lgl = &cathandle->lgh_cookie.lgc_lgl;
-                msd->msd_catalog_oid = cpu_to_le64(lgl->lgl_oid);
-                msd->msd_catalog_ogen = cpu_to_le32(lgl->lgl_ogen);
-                rc = mds_update_server_data(obd);
-                if (rc) {
-                        CERROR("error writing new catalog to disk: rc %d\n",rc);
-                        GOTO(out_handle, rc);
-                }
+        down(&parent_inode->i_sem);
+        de = lookup_one_len(fidname, mds->mds_objects_dir, namelen);
+        if (de == NULL || de->d_inode == NULL) {
+                CERROR("destroying non-existent object "LPU64"\n", oa->o_id);
+                GOTO(out, rc = IS_ERR(de) ? PTR_ERR(de) : -ENOENT);
         }
 
-        rc = llog_init_catalog(cathandle, &obd->u.mds.mds_osc_uuid);
-
+        handle = fsfilt_start(obd, mds->mds_objects_dir->d_inode,
+                              FSFILT_OP_UNLINK_LOG, oti);
+        if (IS_ERR(handle)) {
+                GOTO(out_dput, rc = PTR_ERR(handle));
+        }
+        
+        rc = vfs_unlink(mds->mds_objects_dir->d_inode, de);
+        if (rc) 
+                CERROR("error destroying object "LPU64":%u: rc %d\n",
+                       oa->o_id, oa->o_generation, rc);
+        
+        err = fsfilt_commit(obd, mds->mds_objects_dir->d_inode, handle, 0);
+        if (err && !rc)
+                rc = err;
+out_dput:
+        l_dput(de);
 out:
-        pop_ctxt(&saved, &obd->u.mds.mds_ctxt, NULL);
-        RETURN(cathandle);
-
-out_handle:
-        mds_log_close(cathandle, cathandle);
-        cathandle = ERR_PTR(rc);
-        goto out;
-
-}
-
-void mds_put_catalog(struct llog_handle *cathandle)
-{
-        struct llog_handle *loghandle, *n;
-        int rc;
-        ENTRY;
-
-        list_for_each_entry_safe(loghandle, n, &cathandle->lgh_list, lgh_list)
-                mds_log_close(cathandle, loghandle);
-
-        rc = filp_close(cathandle->lgh_file, 0);
-        if (rc)
-                CERROR("error closing catalog: rc %d\n", rc);
-
-        llog_free_handle(cathandle);
-        EXIT;
+        up(&parent_inode->i_sem);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        RETURN(rc);
 }
diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h
index c2d3d77f622009f8b9aeb5e102e3aa5744823f23..5dcd667e3ac2192baefd616391d8025ce2b5875c 100644
--- a/lustre/mds/mds_internal.h
+++ b/lustre/mds/mds_internal.h
@@ -1,47 +1,89 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
 #ifndef _MDS_INTERNAL_H
 #define _MDS_INTERNAL_H
+
+#include <linux/lustre_mds.h>
+
+struct mds_filter_data {
+        __u64 io_epoch;
+};
+
+#define MDS_FILTERDATA(inode) ((struct mds_filter_data *)(inode)->i_filterdata)
+
 static inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req)
 {
         return &req->rq_export->exp_obd->u.mds;
 }
 
-/* mds/mds_fs.c */
-struct llog_handle *mds_log_create(struct obd_device *obd);
-int mds_log_close(struct llog_handle *cathandle, struct llog_handle *loghandle);
-struct llog_handle *mds_log_open(struct obd_device *obd,
-                                 struct llog_cookie *logcookie);
-struct llog_handle *mds_get_catalog(struct obd_device *obd);
-void mds_put_catalog(struct llog_handle *cathandle);
-
-/* mds/handler.c */
-struct mds_file_data *mds_mfd_new(void);
-void mds_mfd_put(struct mds_file_data *mfd);
-void mds_mfd_destroy(struct mds_file_data *mfd);
-
 /* mds/mds_reint.c */
 void mds_commit_cb(struct obd_device *, __u64 last_rcvd, void *data, int error);
 int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,
                        struct ptlrpc_request *req, int rc, __u32 op_data);
+void mds_reconstruct_generic(struct ptlrpc_request *req);
+void mds_req_from_mcd(struct ptlrpc_request *req, struct mds_client_data *mcd);
 
 /* mds/mds_lib.c */
 int mds_update_unpack(struct ptlrpc_request *, int offset,
                       struct mds_update_record *);
 
+/* mds/mds_unlink_open.c */
+int mds_open_unlink_rename(struct mds_update_record *rec,
+                           struct obd_device *obd, struct dentry *dparent,
+                           struct dentry *dchild, void **handle);
+int mds_cleanup_orphans(struct obd_device *obd);
+
+
+/* mds/mds_log.c */
+int mds_log_op_unlink(struct obd_device *obd, struct inode *inode, 
+                      struct lustre_msg *repmsg, int offset);
+int mds_llog_init(struct obd_device *obd, struct obd_device *tgt, int count, 
+                  struct llog_logid *logid);
+int mds_llog_finish(struct obd_device *obd, int count);
+
 /* mds/mds_lov.c */
-int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,
-                    struct obd_uuid *uuidarray);
+int mds_lov_connect(struct obd_device *obd, char * lov_name);
+int mds_lov_disconnect(struct obd_device *obd, int flags);
+int mds_get_lovtgts(struct obd_device *, int tgt_count, struct obd_uuid *);
+int mds_lov_write_objids(struct obd_device *obd);
+void mds_lov_update_objids(struct obd_device *obd, obd_id *ids);
+int mds_lov_set_growth(struct mds_obd *mds, int count);
+int mds_lov_set_nextid(struct obd_device *obd);
+int mds_post_mds_lovconf(struct obd_device *obd);
+int mds_notify(struct obd_device *obd, struct obd_device *watched, int active);
+int mds_convert_lov_ea(struct obd_device *obd, struct inode *inode,
+                       struct lov_mds_md *lmm, int lmm_size);
 
 /* mds/mds_open.c */
+int mds_query_write_access(struct inode *inode);
 int mds_open(struct mds_update_record *rec, int offset,
              struct ptlrpc_request *req, struct lustre_handle *);
 int mds_pin(struct ptlrpc_request *req);
+int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd,
+                  struct mds_file_data *mfd, int unlink_orphan);
+int mds_close(struct ptlrpc_request *req);
+int mds_done_writing(struct ptlrpc_request *req);
+
 
 /* mds/mds_fs.c */
 int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
-		   struct mds_export_data *med, int cl_off);
-int mds_client_free(struct obd_export *exp);
+                   struct mds_export_data *med, int cl_off);
+int mds_client_free(struct obd_export *exp, int clear_client);
+int mds_obd_create(struct obd_export *exp, struct obdo *oa,
+                      struct lov_stripe_md **ea, struct obd_trans_info *oti);
+int mds_obd_destroy(struct obd_export *exp, struct obdo *oa,
+                    struct lov_stripe_md *ea, struct obd_trans_info *oti);
 
+/* mds/handler.c */
+extern struct lvfs_callback_ops mds_lvfs_ops;
+int mds_lov_clean(struct obd_device *obd);
+extern int mds_iocontrol(unsigned int cmd, struct obd_export *exp,
+                         int len, void *karg, void *uarg);
 #ifdef __KERNEL__
+int mds_pack_md(struct obd_device *, struct lustre_msg *, int offset,
+                struct mds_body *, struct inode *, int lock);
 void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode);
 void mds_pack_inode2body(struct mds_body *body, struct inode *inode);
 #endif
diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c
index 93ac3007ad0e80b8e716d76828890777882fa693..66d182cbb44de5e826ab7497a89d863d40fc6bd6 100644
--- a/lustre/mds/mds_lib.c
+++ b/lustre/mds/mds_lib.c
@@ -48,7 +48,6 @@
 #include <linux/obd_support.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_mds.h>
-#include <linux/lustre_lite.h>
 
 void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode)
 {
@@ -60,12 +59,14 @@ void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode)
 /* Note that we can copy all of the fields, just some will not be "valid" */
 void mds_pack_inode2body(struct mds_body *b, struct inode *inode)
 {
-        b->valid = OBD_MD_FLID | OBD_MD_FLCTIME | OBD_MD_FLUID | OBD_MD_FLGID |
-                OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLNLINK | OBD_MD_FLGENER;
+        b->valid |= OBD_MD_FLID | OBD_MD_FLCTIME | OBD_MD_FLUID |
+                    OBD_MD_FLGID | OBD_MD_FLFLAGS | OBD_MD_FLTYPE |
+                    OBD_MD_FLMODE | OBD_MD_FLNLINK | OBD_MD_FLGENER |
+                    OBD_MD_FLATIME | OBD_MD_FLMTIME; /* bug 2020 */
 
         if (!S_ISREG(inode->i_mode))
                 b->valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | OBD_MD_FLATIME |
-                            OBD_MD_FLMTIME;
+                            OBD_MD_FLMTIME | OBD_MD_FLRDEV;
 
         b->ino = inode->i_ino;
         b->atime = LTIME_S(inode->i_atime);
@@ -77,7 +78,7 @@ void mds_pack_inode2body(struct mds_body *b, struct inode *inode)
         b->uid = inode->i_uid;
         b->gid = inode->i_gid;
         b->flags = inode->i_flags;
-        b->rdev = b->rdev;
+        b->rdev = inode->i_rdev;
         /* Return the correct link count for orphan inodes */
         b->nlink = mds_inode_is_orphan(inode) ? 0 : inode->i_nlink;
         b->generation = inode->i_generation;
@@ -151,8 +152,6 @@ static int mds_create_unpack(struct ptlrpc_request *req, int offset,
         r->ur_fid2 = &rec->cr_replayfid;
         r->ur_mode = rec->cr_mode;
         r->ur_rdev = rec->cr_rdev;
-        r->ur_uid = rec->cr_uid;
-        r->ur_gid = rec->cr_gid;
         r->ur_time = rec->cr_time;
         r->ur_flags = rec->cr_flags;
         r->ur_suppgid1 = rec->cr_suppgid;
@@ -199,6 +198,7 @@ static int mds_link_unpack(struct ptlrpc_request *req, int offset,
         r->ur_suppgid2 = rec->lk_suppgid2;
         r->ur_fid1 = &rec->lk_fid1;
         r->ur_fid2 = &rec->lk_fid2;
+        r->ur_time = rec->lk_time;
 
         LASSERT_REQSWAB (req, offset + 1);
         r->ur_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
@@ -227,6 +227,7 @@ static int mds_unlink_unpack(struct ptlrpc_request *req, int offset,
         r->ur_suppgid2 = -1;
         r->ur_fid1 = &rec->ul_fid1;
         r->ur_fid2 = &rec->ul_fid2;
+        r->ur_time = rec->ul_time;
 
         LASSERT_REQSWAB (req, offset + 1);
         r->ur_name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);
@@ -254,6 +255,7 @@ static int mds_rename_unpack(struct ptlrpc_request *req, int offset,
         r->ur_suppgid2 = rec->rn_suppgid2;
         r->ur_fid1 = &rec->rn_fid1;
         r->ur_fid2 = &rec->rn_fid2;
+        r->ur_time = rec->rn_time;
 
         LASSERT_REQSWAB (req, offset + 1);
         r->ur_name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);
@@ -269,6 +271,45 @@ static int mds_rename_unpack(struct ptlrpc_request *req, int offset,
         RETURN(0);
 }
 
+static int mds_open_unpack(struct ptlrpc_request *req, int offset,
+                           struct mds_update_record *r)
+{
+        struct mds_rec_create *rec;
+        ENTRY;
+
+        rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
+                                  lustre_swab_mds_rec_create);
+        if (rec == NULL)
+                RETURN (-EFAULT);
+
+        r->ur_fsuid = rec->cr_fsuid;
+        r->ur_fsgid = rec->cr_fsgid;
+        r->ur_cap = rec->cr_cap;
+        r->ur_fid1 = &rec->cr_fid;
+        r->ur_fid2 = &rec->cr_replayfid;
+        r->ur_mode = rec->cr_mode;
+        r->ur_rdev = rec->cr_rdev;
+        r->ur_time = rec->cr_time;
+        r->ur_flags = rec->cr_flags;
+        r->ur_suppgid1 = rec->cr_suppgid;
+        r->ur_suppgid2 = -1;
+
+        LASSERT_REQSWAB (req, offset + 1);
+        r->ur_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
+        if (r->ur_name == NULL)
+                RETURN (-EFAULT);
+        r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
+
+        LASSERT_REQSWAB (req, offset + 2);
+        if (req->rq_reqmsg->bufcount > offset + 2) {
+                r->ur_eadata = lustre_msg_buf(req->rq_reqmsg, offset + 2, 0);
+                if (r->ur_eadata == NULL)
+                        RETURN (-EFAULT);
+                r->ur_eadatalen = req->rq_reqmsg->buflens[offset + 2];
+        }
+        RETURN(0);
+}
+
 typedef int (*update_unpacker)(struct ptlrpc_request *req, int offset,
                                struct mds_update_record *r);
 
@@ -278,7 +319,7 @@ static update_unpacker mds_unpackers[REINT_MAX + 1] = {
         [REINT_LINK] mds_link_unpack,
         [REINT_UNLINK] mds_unlink_unpack,
         [REINT_RENAME] mds_rename_unpack,
-        [REINT_OPEN] mds_create_unpack,
+        [REINT_OPEN] mds_open_unpack,
 };
 
 int mds_update_unpack(struct ptlrpc_request *req, int offset,
diff --git a/lustre/mds/mds_log.c b/lustre/mds/mds_log.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9b02ee53dcce1bba2f9c084924312418ddb968d
--- /dev/null
+++ b/lustre/mds/mds_log.c
@@ -0,0 +1,167 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/mds/mds_log.c
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <portals/list.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_commit_confd.h>
+
+#include "mds_internal.h"
+
+static int mds_llog_origin_add(struct llog_ctxt *ctxt,
+                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                        struct llog_cookie *logcookies, int numcookies)
+{
+        struct obd_device *obd = ctxt->loc_obd;
+        struct obd_device *lov_obd = obd->u.mds.mds_osc_obd;
+        struct llog_ctxt *lctxt;
+        int rc;
+        ENTRY;
+
+        lctxt = llog_get_context(lov_obd, ctxt->loc_idx);
+        rc = llog_add(lctxt, rec, lsm, logcookies, numcookies);
+        RETURN(rc);
+}
+
+static int mds_llog_origin_connect(struct llog_ctxt *ctxt, int count,
+                                   struct llog_logid *logid,
+                                   struct llog_ctxt_gen *gen) 
+{
+        struct obd_device *obd = ctxt->loc_obd;
+        struct obd_device *lov_obd = obd->u.mds.mds_osc_obd;
+        struct llog_ctxt *lctxt;
+        int rc;
+        ENTRY;
+
+        lctxt = llog_get_context(lov_obd, ctxt->loc_idx);
+        rc = llog_connect(lctxt, count, logid, gen);
+        RETURN(rc);
+}
+
+static int mds_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
+                          int count, struct llog_cookie *cookies, int flags)
+{
+        struct obd_device *obd = ctxt->loc_obd;
+        struct obd_device *lov_obd = obd->u.mds.mds_osc_obd;
+        struct llog_ctxt *lctxt;
+        int rc;
+        ENTRY;
+
+        lctxt = llog_get_context(lov_obd, ctxt->loc_idx);
+        rc = llog_cancel(lctxt, lsm, count, cookies,flags);
+        RETURN(rc);
+}
+
+int mds_log_op_unlink(struct obd_device *obd, struct inode *inode,
+                      struct lustre_msg *repmsg, int offset)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct lov_stripe_md *lsm = NULL;
+#ifdef ENABLE_ORPHANS
+        struct llog_ctxt *ctxt;
+#endif
+        int rc;
+        ENTRY;
+
+        if (IS_ERR(mds->mds_osc_obd))
+                RETURN(PTR_ERR(mds->mds_osc_obd));
+
+        rc = obd_unpackmd(mds->mds_osc_exp, &lsm,
+                          lustre_msg_buf(repmsg, offset, 0),
+                          repmsg->buflens[offset]);
+        if (rc < 0)
+                RETURN(rc);
+
+#ifdef ENABLE_ORPHANS
+        ctxt = llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT);
+        rc = llog_add(ctxt, NULL, lsm, lustre_msg_buf(repmsg, offset + 1, 0),
+                      repmsg->buflens[offset + 1] / sizeof(struct llog_cookie));
+#endif
+
+        obd_free_memmd(mds->mds_osc_exp, &lsm);
+
+        RETURN(rc);
+}
+
+static struct llog_operations mds_unlink_orig_logops = {
+        lop_add:        mds_llog_origin_add,
+        lop_connect:    mds_llog_origin_connect,
+};
+
+static struct llog_operations mds_size_repl_logops = {
+        lop_cancel:     mds_llog_repl_cancel
+};
+
+int mds_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                  int count, struct llog_logid *logid)
+{
+        struct obd_device *lov_obd = obd->u.mds.mds_osc_obd;
+        int rc;
+        ENTRY;
+        
+        rc = llog_setup(obd, LLOG_UNLINK_ORIG_CTXT, tgt, 0, NULL,
+                        &mds_unlink_orig_logops);
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_setup(obd, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL,
+                        &mds_size_repl_logops);
+        if (rc)
+                RETURN(rc);
+
+        rc = obd_llog_init(lov_obd, tgt, count, logid);        
+        if (rc) 
+                CERROR("error lov_llog_init\n"); 
+
+        RETURN(rc);
+}
+
+int mds_llog_finish(struct obd_device *obd, int count)
+{
+        struct obd_device *lov_obd = obd->u.mds.mds_osc_obd;
+        int rc;
+        ENTRY;
+        
+        rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        rc = obd_llog_finish(lov_obd, count);        
+        if (rc) 
+                CERROR("error lov_llog_finish\n"); 
+
+        RETURN(rc);
+}
diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c
index ecca88c3cdd14c3eae26bba1588098a22c83d8b7..077dccd71313f8881a6461d3963a35ff769c81f0 100644
--- a/lustre/mds/mds_lov.c
+++ b/lustre/mds/mds_lov.c
@@ -23,7 +23,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <linux/module.h>
@@ -52,233 +54,428 @@ void cpu_to_le_lov_desc (struct lov_desc *ld)
         ld->ld_pattern = cpu_to_le32 (ld->ld_pattern);
 }
 
-int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc,
-                    struct obd_uuid *uuidarray)
+void mds_lov_update_objids(struct obd_device *obd, obd_id *ids)
 {
         struct mds_obd *mds = &obd->u.mds;
-        struct obd_run_ctxt saved;
-        struct file *f;
-        int tgt_count;
-        int rc;
         int i;
-        struct lov_desc *disk_desc;
         ENTRY;
 
-        tgt_count = desc->ld_tgt_count;
-        if (desc->ld_default_stripe_count > desc->ld_tgt_count) {
-                CERROR("default stripe count %u > OST count %u\n",
-                       desc->ld_default_stripe_count, desc->ld_tgt_count);
-                RETURN(-EINVAL);
-        }
-        if (desc->ld_default_stripe_size & (PAGE_SIZE - 1)) {
-                CERROR("default stripe size "LPU64" not a multiple of %lu\n",
-                       desc->ld_default_stripe_size, PAGE_SIZE);
-                RETURN(-EINVAL);
-        }
-        if (desc->ld_default_stripe_offset > desc->ld_tgt_count) {
-                CERROR("default stripe offset "LPU64" > max OST index %u\n",
-                       desc->ld_default_stripe_offset, desc->ld_tgt_count);
-                RETURN(-EINVAL);
-        }
-        if (desc->ld_pattern != 0) {
-                CERROR("stripe pattern %u unknown\n",
-                       desc->ld_pattern);
-                RETURN(-EINVAL);
-        }
-
-        OBD_ALLOC (disk_desc, sizeof (*disk_desc));
-        if (disk_desc == NULL) {
-                CERROR ("Can't allocate disk_desc\n");
-                RETURN (-ENOMEM);
-        }
+        lock_kernel();
+        for (i = 0; i < mds->mds_lov_desc.ld_tgt_count; i++)
+                if (ids[i] > (mds->mds_lov_objids)[i])
+                        (mds->mds_lov_objids)[i] = ids[i];
+        unlock_kernel();
+        EXIT;
+}
 
-        *disk_desc = *desc;
-        cpu_to_le_lov_desc (disk_desc);
+static int mds_lov_read_objids(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        obd_id *ids;
+        loff_t off = 0;
+        int i, rc, size = mds->mds_lov_desc.ld_tgt_count * sizeof(*ids);
+        ENTRY;
 
-        rc = 0;
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
+        if (mds->mds_lov_objids != NULL)
+                RETURN(0);
 
-        /* Bug 1186: FIXME: if there is an existing LOVDESC, verify new
-         * tgt_count > old */
-        f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
-        if (IS_ERR(f)) {
-                CERROR("Cannot open/create LOVDESC file\n");
-                GOTO(out, rc = PTR_ERR(f));
-        }
+        OBD_ALLOC(ids, size);
+        if (ids == NULL)
+                RETURN(-ENOMEM);
+        mds->mds_lov_objids = ids;
 
-        rc = lustre_fwrite(f, (char *)disk_desc, sizeof(*disk_desc), &f->f_pos);
-        if (filp_close(f, 0))
-                CERROR("Error closing LOVDESC file\n");
-        if (rc != sizeof(*desc)) {
-                CERROR("Cannot open/create LOVDESC file\n");
-                if (rc >= 0)
-                        rc = -EIO;
-                GOTO(out, rc);
+        if (mds->mds_lov_objid_filp->f_dentry->d_inode->i_size == 0)
+                RETURN(0);
+        rc = fsfilt_read_record(obd, mds->mds_lov_objid_filp, ids, size, &off);
+        if (rc < 0) {
+                CERROR("Error reading objids %d\n", rc);
+        } else {
+                mds->mds_lov_objids_valid = 1;
+                rc = 0;
         }
 
-        /* Bug 1186: FIXME: if there is an existing LOVTGTS, verify
-         * existing UUIDs same */
-        f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
-        if (IS_ERR(f)) {
-                CERROR("Cannot open/create LOVTGTS file\n");
-                GOTO(out, rc = PTR_ERR(f));
-        }
+        for (i = 0; i < mds->mds_lov_desc.ld_tgt_count; i++)
+                CDEBUG(D_INFO, "read last object "LPU64" for idx %d\n",
+                       mds->mds_lov_objids[i], i);
 
-        rc = 0;
-        for (i = 0; i < tgt_count ; i++) {
-                rc = lustre_fwrite(f, uuidarray[i].uuid,
-                                   sizeof(uuidarray[i]), &f->f_pos);
-                if (rc != sizeof(uuidarray[i])) {
-                        CERROR("cannot write LOV UUID %s (%d)\n",
-                               uuidarray[i].uuid, i);
-                        if (rc >= 0)
-                                rc = -EIO;
-                        break;
-                }
-                rc = 0;
-        }
-        if (filp_close(f, 0))
-                CERROR("Error closing LOVTGTS file\n");
+        RETURN(rc);
+}
 
-        memcpy(&mds->mds_lov_desc, desc, sizeof *desc);
-        mds->mds_has_lov_desc = 1;
-        /* XXX the MDS should not really know about this */
-        mds->mds_max_mdsize = lov_mds_md_size(desc->ld_tgt_count);
-        mds->mds_max_cookiesize = desc->ld_tgt_count*sizeof(struct llog_cookie);
+int mds_lov_write_objids(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        loff_t off = 0;
+        int i, rc, size = mds->mds_lov_desc.ld_tgt_count * sizeof(obd_id);
+        ENTRY;
 
-out:
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
-        OBD_FREE (disk_desc, sizeof (*disk_desc));
+        for (i = 0; i < mds->mds_lov_desc.ld_tgt_count; i++)
+                CDEBUG(D_INFO, "writing last object "LPU64" for idx %d\n",
+                       mds->mds_lov_objids[i], i);
 
+        rc = fsfilt_write_record(obd, mds->mds_lov_objid_filp,
+                                 mds->mds_lov_objids, size, &off, 0);
         RETURN(rc);
 }
 
-int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
+static int mds_lov_clearorphans(struct mds_obd *mds, struct obd_uuid *ost_uuid)
 {
-        struct obd_run_ctxt saved;
-        struct file *f;
         int rc;
+        struct obdo oa;
+        struct obd_trans_info oti = {0};
+        struct lov_stripe_md  *empty_ea = NULL;
         ENTRY;
 
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
-        f = filp_open("LOVDESC", O_RDONLY, 0644);
-        if (IS_ERR(f)) {
-                CERROR("Cannot open LOVDESC file\n");
-                GOTO(out, rc = PTR_ERR(f));
+        LASSERT(mds->mds_lov_objids != NULL);
+
+        /* This create will in fact either create or destroy:  If the OST is
+         * missing objects below this ID, they will be created.  If it finds
+         * objects above this ID, they will be removed. */
+        memset(&oa, 0, sizeof(oa));
+        oa.o_valid = OBD_MD_FLFLAGS;
+        oa.o_flags = OBD_FL_DELORPHAN;
+        if (ost_uuid != NULL) {
+                memcpy(&oa.o_inline, ost_uuid, sizeof(*ost_uuid));
+                oa.o_valid |= OBD_MD_FLINLINE;
         }
+        rc = obd_create(mds->mds_osc_exp, &oa, &empty_ea, &oti);
+
+        RETURN(rc);
+}
 
-        rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
-        if (filp_close(f, 0))
-                CERROR("Error closing LOVDESC file\n");
+/* update the LOV-OSC knowledge of the last used object id's */
+int mds_lov_set_nextid(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        int rc;
+        ENTRY;
 
-        if (rc != sizeof(*desc)) {
-                CERROR("Cannot read LOVDESC file: rc = %d\n", rc);
-                GOTO(out, rc = -EIO);
-        } else
-                rc = 0;
+        LASSERT(!obd->obd_recovering);
 
-        le_lov_desc_to_cpu (desc);              /* convert to my byte order */
+        LASSERT(mds->mds_lov_objids != NULL);
+
+        rc = obd_set_info(mds->mds_osc_exp, strlen("next_id"), "next_id",
+                          mds->mds_lov_desc.ld_tgt_count, mds->mds_lov_objids);
+        if (rc < 0)
+                GOTO(out, rc);
+
+        rc = mds_lov_clearorphans(mds, NULL /* all OSTs */);
+        if (rc < 0)
+                GOTO(out, rc);
 
-        EXIT;
 out:
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+        if (rc && mds->mds_lov_objids) {
+                /* Might as well crash here, until we figure out what to do.
+                 * If we OBD_FREE, we'll just LASSERT the next time through this
+                 * function. */
+                LBUG();
+                OBD_FREE(mds->mds_lov_objids,
+                         mds->mds_lov_desc.ld_tgt_count * sizeof(obd_id));
+                mds->mds_lov_objids = NULL;
+        }
 
-        return rc;
+        RETURN(rc);
 }
 
-int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,
-                    struct obd_uuid *uuidarray)
+/* tell the LOV-OSC by how much to pre-create */
+int mds_lov_set_growth(struct mds_obd *mds, int count)
 {
-        struct obd_run_ctxt saved;
-        struct file *f;
         int rc;
-        int rc2;
+        ENTRY;
+
+        rc = obd_set_info(mds->mds_osc_exp, strlen("growth_count"),
+                          "growth_count", sizeof(count), &count);
+
+        RETURN(rc);
+}
+
+int mds_lov_connect(struct obd_device *obd, char * lov_name)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct lustre_handle conn = {0,};
+        int valsize;
+        int rc, i;
+        ENTRY;
+
+        if (IS_ERR(mds->mds_osc_obd))
+                RETURN(PTR_ERR(mds->mds_osc_obd));
+
+        if (mds->mds_osc_obd)
+                RETURN(0);
 
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
-        f = filp_open("LOVTGTS", O_RDONLY, 0644);
-        if (IS_ERR(f)) {
-                CERROR("Cannot open LOVTGTS file\n");
-                GOTO(out, rc = PTR_ERR(f));
+        mds->mds_osc_obd = class_name2obd(lov_name);
+        if (!mds->mds_osc_obd) {
+                CERROR("MDS cannot locate LOV %s\n",
+                       lov_name);
+                mds->mds_osc_obd = ERR_PTR(-ENOTCONN);
+                RETURN(-ENOTCONN);
         }
 
-        rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
-                          &f->f_pos);
-        rc2 = filp_close(f, 0);
-        if (rc2)
-                CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
+        rc = obd_connect(&conn, mds->mds_osc_obd, &obd->obd_uuid);
+        if (rc) {
+                CERROR("MDS cannot connect to LOV %s (%d)\n",
+                       lov_name, rc);
+                mds->mds_osc_obd = ERR_PTR(rc);
+                RETURN(rc);
+        }
+        mds->mds_osc_exp = class_conn2export(&conn);
 
-        if (rc != tgt_count * sizeof(*uuidarray)) {
-                CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
-                if (rc >= 0)
-                        rc = -EIO;
-                GOTO(out, rc);
-        } else
-                rc = 0;
-        EXIT;
-out:
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
+        rc = obd_register_observer(mds->mds_osc_obd, obd);
+        if (rc) {
+                CERROR("MDS cannot register as observer of LOV %s (%d)\n",
+                       lov_name, rc);
+                GOTO(err_discon, rc);
+        }
+
+        valsize = sizeof(mds->mds_lov_desc);
+        rc = obd_get_info(mds->mds_osc_exp, strlen("lovdesc") + 1, "lovdesc", 
+                          &valsize, &mds->mds_lov_desc);
+        if (rc) 
+                GOTO(err_reg, rc);
+
+        mds->mds_max_mdsize = lov_mds_md_size(mds->mds_lov_desc.ld_tgt_count);
+        mds->mds_max_cookiesize = mds->mds_lov_desc.ld_tgt_count*
+                sizeof(struct llog_cookie);
+        mds->mds_has_lov_desc = 1;
+        rc = mds_lov_read_objids(obd);
+        if (rc) {
+                CERROR("cannot read %s: rc = %d\n", "lov_objids", rc);
+                GOTO(err_reg, rc);
+        } 
+
+#ifdef ENABLE_ORPHANS
+        rc = llog_cat_initialize(obd, mds->mds_lov_desc.ld_tgt_count);
+        if (rc) {
+                CERROR("failed to initialize catalog %d\n", rc);
+                GOTO(err_reg, rc);
+        }
+#endif
+        /* FIXME before this set info call is made, we must initialize the logging */
+        rc = obd_set_info(mds->mds_osc_exp, strlen("mds_conn"), "mds_conn",
+                          0, NULL);
+        if (rc) 
+                GOTO(err_reg, rc);
+        
+        /* If we're mounting this code for the first time on an existing FS,
+         * we need to populate the objids array from the real OST values */
+        if (!mds->mds_lov_objids_valid) {
+                int size = sizeof(obd_id) * mds->mds_lov_desc.ld_tgt_count;
+                rc = obd_get_info(mds->mds_osc_exp, strlen("last_id"),
+                                  "last_id", &size, mds->mds_lov_objids);
+                if (!rc) {
+                        for (i = 0; i < mds->mds_lov_desc.ld_tgt_count; i++)
+                                CWARN("got last object "LPU64" from OST %d\n",
+                                      mds->mds_lov_objids[i], i);
+                        mds->mds_lov_objids_valid = 1;
+                        rc = mds_lov_write_objids(obd);
+                        if (rc)
+                                CERROR("got last objids from OSTs, but error "
+                                       "writing objids file: %d\n", rc);
+                }
+        }
+
+        /* I want to see a callback happen when the OBD moves to a
+         * "For General Use" state, and that's when we'll call
+         * set_nextid().  The class driver can help us here, because
+         * it can use the obd_recovering flag to determine when the
+         * the OBD is full available. */
+        if (!obd->obd_recovering) {
+#ifdef ENABLE_ORPHANS
+                rc = llog_connect(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT),
+                                  obd->u.mds.mds_lov_desc.ld_tgt_count, NULL, NULL);
+                if (rc != 0) {
+                        CERROR("faild at llog_origin_connect: %d\n", rc);
+                }
+#endif
+                rc = mds_cleanup_orphans(obd);
+                if (rc > 0)
+                        CERROR("Cleanup %d orphans while MDS isn't recovering\n", rc);
+
+                rc = mds_lov_set_nextid(obd);
+                if (rc)
+                        GOTO(err_llog, rc);
+        }
+        RETURN(rc);
+
+err_llog:
+#ifdef ENABLE_ORPHANS
+        /* cleanup all llogging subsystems */
+        rc = obd_llog_finish(obd, mds->mds_lov_desc.ld_tgt_count);
+        if (rc) 
+                CERROR("failed to cleanup llogging subsystems\n");
+#endif
+err_reg:
+        obd_register_observer(mds->mds_osc_obd, NULL);
+err_discon:
+        obd_disconnect(mds->mds_osc_exp, 0);
+        mds->mds_osc_exp = NULL;
+        mds->mds_osc_obd = ERR_PTR(rc);
+        RETURN(rc);
+}
+
+int mds_lov_disconnect(struct obd_device *obd, int flags)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        int rc = 0;
+        ENTRY;
+
+        if (!IS_ERR(mds->mds_osc_obd) && mds->mds_osc_exp != NULL) {
+#ifdef ENABLE_ORPHANS
+                /* cleanup all llogging subsystems */
+                rc = obd_llog_finish(obd, mds->mds_lov_desc.ld_tgt_count);
+                if (rc) 
+                        CERROR("failed to cleanup llogging subsystems\n");
+#endif
+
+                obd_register_observer(mds->mds_osc_obd, NULL);
+
+                rc = obd_disconnect(mds->mds_osc_exp, flags);
+                /* if obd_disconnect fails (probably because the
+                 * export was disconnected by class_disconnect_exports)
+                 * then we just need to drop our ref. */
+                if (rc != 0)
+                        class_export_put(mds->mds_osc_exp);
+                mds->mds_osc_exp = NULL;
+                mds->mds_osc_obd = NULL;
+        }
 
         RETURN(rc);
 }
 
-int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
-                  int len, void *karg, void *uarg)
+int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
+                  void *karg, void *uarg)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
+        struct obd_device *obd = exp->exp_obd;
+        struct mds_obd *mds = &obd->u.mds;
         struct obd_ioctl_data *data = karg;
-        struct lov_desc *desc;
-        struct obd_uuid *uuidarray;
-        int count;
-        int rc;
+        struct obd_run_ctxt saved;
+        int rc = 0;
 
         switch (cmd) {
-        case OBD_IOC_LOV_SET_CONFIG:
-                desc = (struct lov_desc *)data->ioc_inlbuf1;
-                if (sizeof(*desc) > data->ioc_inllen1) {
-                        CERROR("descriptor size wrong\n");
-                        RETURN(-EINVAL);
-                }
+        case OBD_IOC_RECORD: {
+                char *name = data->ioc_inlbuf1;
+                if (mds->mds_cfg_llh)
+                        RETURN(-EBUSY);
+
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT), 
+                                 &mds->mds_cfg_llh, NULL, name);
+                if (rc == 0)
+                        llog_init_handle(mds->mds_cfg_llh, LLOG_F_IS_PLAIN, 
+                                         &cfg_uuid);
+                else
+                        mds->mds_cfg_llh = NULL;
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-                count = desc->ld_tgt_count;
-                uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
-                if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
-                        CERROR("UUID array size wrong\n");
-                        RETURN(-EINVAL);
-                }
-                rc = mds_set_lovdesc(obd, desc, uuidarray);
+                RETURN(rc);
+        }
+
+        case OBD_IOC_ENDRECORD: {
+                if (!mds->mds_cfg_llh)
+                        RETURN(-EBADF);
 
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = llog_close(mds->mds_cfg_llh);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+                mds->mds_cfg_llh = NULL;
                 RETURN(rc);
-        case OBD_IOC_LOV_GET_CONFIG:
-                desc = (struct lov_desc *)data->ioc_inlbuf1;
-                if (sizeof(*desc) > data->ioc_inllen1) {
-                        CERROR("descriptor size wrong\n");
+        }
+
+        case OBD_IOC_DORECORD: {
+                char *cfg_buf;
+                struct llog_rec_hdr rec;
+                if (!mds->mds_cfg_llh)
+                        RETURN(-EBADF);
+
+                rec.lrh_len = llog_data_len(data->ioc_plen1);
+
+                if (data->ioc_type == LUSTRE_CFG_TYPE) {
+                        rec.lrh_type = OBD_CFG_REC;
+                } else if (data->ioc_type == PORTALS_CFG_TYPE) {
+                        rec.lrh_type = PTL_CFG_REC;
+                } else {
+                        CERROR("unknown cfg record type:%d \n", data->ioc_type);
                         RETURN(-EINVAL);
                 }
 
-                count = desc->ld_tgt_count;
-                uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
-                if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
-                        CERROR("UUID array size wrong\n");
+                OBD_ALLOC(cfg_buf, data->ioc_plen1);
+                if (cfg_buf == NULL)
                         RETURN(-EINVAL);
+                rc = copy_from_user(cfg_buf, data->ioc_pbuf1, data->ioc_plen1);
+                if (rc) {
+                        OBD_FREE(cfg_buf, data->ioc_plen1);
+                        RETURN(rc);
                 }
-                rc = mds_get_lovdesc(&obd->u.mds, desc);
-                if (desc->ld_tgt_count > count) {
-                        CERROR("UUID array size too small\n");
-                        RETURN(-ENOSPC);
-                }
-                rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count,
-                                     uuidarray);
+
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = llog_write_rec(mds->mds_cfg_llh, &rec, NULL, 0,
+                                    cfg_buf, -1);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+                OBD_FREE(cfg_buf, data->ioc_plen1);
+                RETURN(rc);
+        }
+
+        case OBD_IOC_PARSE: {
+                struct llog_ctxt *ctxt = 
+                        llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = class_config_parse_llog(ctxt, data->ioc_inlbuf1, NULL);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                if (rc)
+                        RETURN(rc);
 
                 RETURN(rc);
+        }
+
+        case OBD_IOC_DUMP_LOG: {
+                struct llog_ctxt *ctxt = 
+                        llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
+                rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                if (rc)
+                        RETURN(rc);
+
+                RETURN(rc);
+        }
 
         case OBD_IOC_SET_READONLY: {
+                void *handle;
+                struct inode *inode = obd->u.mds.mds_sb->s_root->d_inode;
                 BDEVNAME_DECLARE_STORAGE(tmp);
                 CERROR("setting device %s read-only\n",
-                       ll_bdevname(obd->u.mds.mds_sb->s_dev, tmp));
-                dev_set_rdonly(obd->u.mds.mds_sb->s_dev, 2);
+                       ll_bdevname(obd->u.mds.mds_sb, tmp));
+
+                handle = fsfilt_start(obd, inode, FSFILT_OP_MKNOD, NULL);
+                LASSERT(handle);
+                rc = fsfilt_commit(obd, inode, handle, 1);
+
+                dev_set_rdonly(ll_sbdev(obd->u.mds.mds_sb), 2);
                 RETURN(0);
         }
 
+        case OBD_IOC_CATLOGLIST: {
+                int count = mds->mds_lov_desc.ld_tgt_count;
+                rc = llog_catlog_list(obd, count, data);
+                RETURN(rc);
+
+        }
+        case OBD_IOC_LLOG_CANCEL:
+        case OBD_IOC_LLOG_REMOVE: 
+        case OBD_IOC_LLOG_INFO:
+        case OBD_IOC_LLOG_PRINT: {
+                struct llog_ctxt *ctxt = 
+                        llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+                
+                push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+                rc = llog_ioctl(ctxt, cmd, data);
+                pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+                
+                RETURN(rc);
+        }
+
         case OBD_IOC_ABORT_RECOVERY:
                 CERROR("aborting recovery for device %s\n", obd->obd_name);
                 target_abort_recovery(obd);
@@ -289,3 +486,76 @@ int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
         }
         RETURN(0);
 }
+
+int mds_notify(struct obd_device *obd, struct obd_device *watched,
+               int active)
+{
+        struct obd_uuid *uuid; 
+
+        if (!active)
+                RETURN(0);
+
+        if (strcmp(watched->obd_type->typ_name, "osc")) {
+                CERROR("unexpected notification of %s %s!\n",
+                       watched->obd_type->typ_name,
+                       watched->obd_name);
+                RETURN(-EINVAL);
+        }
+
+        uuid = &watched->u.cli.cl_import->imp_target_uuid;
+        CERROR("MDS %s: %s now active, resetting orphans\n",
+               obd->obd_name, uuid->uuid);
+        RETURN(mds_lov_clearorphans(&obd->u.mds, uuid));
+}
+
+/* Convert the on-disk LOV EA structre.
+ * We always try to convert from an old LOV EA format to the common in-memory
+ * (lsm) format (obd_unpackmd() understands the old on-disk (lmm) format) and
+ * then convert back to the new on-disk format and save it back to disk
+ * (obd_packmd() only ever saves to the new on-disk format) so we don't have
+ * to convert it each time this inode is accessed.
+ *
+ * This function is a bit interesting in the error handling.  We can safely
+ * ship the old lmm to the client in case of failure, since it uses the same
+ * obd_unpackmd() code and can do the conversion if the MDS fails for some
+ * reason.  We will not delete the old lmm data until we have written the
+ * new format lmm data in fsfilt_set_md(). */
+int mds_convert_lov_ea(struct obd_device *obd, struct inode *inode,
+                       struct lov_mds_md *lmm, int lmm_size)
+{
+        struct lov_stripe_md *lsm = NULL;
+        void *handle;
+        int rc, err;
+        ENTRY;
+
+        if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC)
+                RETURN(0);
+
+        CWARN("converting LOV EA on %lu/%u from V0 to V1\n",
+              inode->i_ino, inode->i_generation);
+        rc = obd_unpackmd(obd->u.mds.mds_osc_exp, &lsm, lmm, lmm_size);
+        if (rc < 0)
+                GOTO(conv_end, rc);
+
+        rc = obd_packmd(obd->u.mds.mds_osc_exp, &lmm, lsm);
+        if (rc < 0)
+                GOTO(conv_free, rc);
+        lmm_size = rc;
+
+        handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
+        if (IS_ERR(handle)) {
+                rc = PTR_ERR(handle);
+                GOTO(conv_free, rc);
+        }
+
+        rc = fsfilt_set_md(obd, inode, handle, lmm, lmm_size);
+
+        err = fsfilt_commit(obd, inode, handle, 0);
+        if (!rc)
+                rc = err ? err : lmm_size;
+        GOTO(conv_free, rc);
+conv_free:
+        obd_free_memmd(obd->u.mds.mds_osc_exp, &lsm);
+conv_end:
+        return rc;
+}
diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c
index c97c53e663c41e5523f4ba1d187711bd4062af4e..43fa20c5a1bd622074a51b26ea781b0e4d884d2a 100644
--- a/lustre/mds/mds_open.c
+++ b/lustre/mds/mds_open.c
@@ -23,54 +23,177 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <linux/module.h>
-#include <linux/lustre_mds.h>
-#include <linux/lustre_dlm.h>
 #include <linux/init.h>
-#include <linux/obd_class.h>
-#include <linux/random.h>
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 # include <linux/buffer_head.h>
 # include <linux/workqueue.h>
 #else
 # include <linux/locks.h>
 #endif
-#include <linux/obd_lov.h>
+
+#include <linux/obd_class.h>
 #include <linux/lustre_mds.h>
+#include <linux/obd_lov.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/lprocfs_status.h>
 
 #include "mds_internal.h"
 
-struct mds_file_data *mds_dentry_open(struct dentry *dentry,
-                                      struct vfsmount *mnt,
-                                      int flags,
-                                      struct ptlrpc_request *req)
+/* Exported function from this file are:
+ *
+ * mds_open - called by the intent handler
+ * mds_close - an rpc handling function
+ * mds_pin - an rpc handling function - which will go away
+ * mds_mfd_close - for force closing files when a client dies
+ */
+
+/* 
+ * MDS file data handling: file data holds a handle for a file opened
+ * by a client.
+ */
+
+static void mds_mfd_addref(void *mfdp)
+{
+        struct mds_file_data *mfd = mfdp;
+
+        atomic_inc(&mfd->mfd_refcount);
+        CDEBUG(D_INFO, "GETting mfd %p : new refcount %d\n", mfd,
+               atomic_read(&mfd->mfd_refcount));
+}
+
+struct mds_file_data *mds_mfd_new(void)
 {
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct inode *inode;
         struct mds_file_data *mfd;
-        int mode, error;
 
+        OBD_ALLOC(mfd, sizeof *mfd);
+        if (mfd == NULL) {
+                CERROR("mds: out of memory\n");
+                return NULL;
+        }
+
+        atomic_set(&mfd->mfd_refcount, 2);
+
+        INIT_LIST_HEAD(&mfd->mfd_handle.h_link);
+        class_handle_hash(&mfd->mfd_handle, mds_mfd_addref);
+
+        return mfd;
+}
+
+static struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle)
+{
+        ENTRY;
+        LASSERT(handle != NULL);
+        RETURN(class_handle2object(handle->cookie));
+}
+
+static void mds_mfd_put(struct mds_file_data *mfd)
+{
+        CDEBUG(D_INFO, "PUTting mfd %p : new refcount %d\n", mfd,
+               atomic_read(&mfd->mfd_refcount) - 1);
+        LASSERT(atomic_read(&mfd->mfd_refcount) > 0 &&
+                atomic_read(&mfd->mfd_refcount) < 0x5a5a);
+        if (atomic_dec_and_test(&mfd->mfd_refcount)) {
+                LASSERT(list_empty(&mfd->mfd_handle.h_link));
+                OBD_FREE(mfd, sizeof *mfd);
+        }
+}
+
+static void mds_mfd_destroy(struct mds_file_data *mfd)
+{
+        class_handle_unhash(&mfd->mfd_handle);
+        mds_mfd_put(mfd);
+}
+
+
+/* 
+ * Write access to a file: executors cause a negative count, 
+ * writers a positive count.  The spin lock is needed to perform
+ * a check for the sign and then increment or decrement atomically.
+ */
+
+static spinlock_t mds_exec_lock = SPIN_LOCK_UNLOCKED;
+static int mds_get_write_access(struct inode * inode)
+{
+        ENTRY;
+        spin_lock(&mds_exec_lock);
+        if (atomic_read(&inode->i_writecount) < 0) {
+                spin_unlock(&mds_exec_lock);
+                RETURN(-ETXTBSY);
+        }
+        atomic_inc(&inode->i_writecount);
+        spin_unlock(&mds_exec_lock);
+        RETURN(0);
+}
+
+static int mds_deny_write_access(struct inode *inode)
+{
+        ENTRY;
+        spin_lock(&mds_exec_lock);
+        if (atomic_read(&inode->i_writecount) > 0) {
+                spin_unlock(&mds_exec_lock);
+                RETURN(-ETXTBSY);
+        }
+        atomic_dec(&inode->i_writecount);
+        spin_unlock(&mds_exec_lock);
+        RETURN(0);
+}
+
+static void mds_put_write_access(struct inode * inode)
+{
+        ENTRY;
+        atomic_dec(&inode->i_writecount);
+}
+
+static void mds_allow_write_access(struct inode *inode)
+{
+        ENTRY;
+        atomic_inc(&inode->i_writecount);
+}
+
+int mds_query_write_access(struct inode *inode)
+{
+        ENTRY;
+        RETURN(atomic_read(&inode->i_writecount));
+}
+
+/* This replaces the VFS mds_dentry_open, it manages mfd and writecount */
+static struct mds_file_data *mds_dentry_open(struct dentry *dentry,
+                                             struct vfsmount *mnt, int flags,
+                                             struct ptlrpc_request *req)
+{
+        struct mds_export_data *med = &req->rq_export->exp_mds_data;
+        struct mds_file_data *mfd;
+        int error;
+        ENTRY;
+        
         mfd = mds_mfd_new();
         if (mfd == NULL) {
                 CERROR("mds: out of memory\n");
                 GOTO(cleanup_dentry, error = -ENOMEM);
         }
 
-        mode = (flags + 1) & O_ACCMODE;
-        inode = dentry->d_inode;
-
-        if (mode & FMODE_WRITE) {
-                error = get_write_access(inode);
+        if (flags & FMODE_WRITE) {
+                error = mds_get_write_access(dentry->d_inode);
+                if (error)
+                        GOTO(cleanup_mfd, error);
+        } else if (flags & FMODE_EXEC) {
+                error = mds_deny_write_access(dentry->d_inode);
                 if (error)
-                        goto cleanup_mfd;
+                        GOTO(cleanup_mfd, error);
         }
 
-        mfd->mfd_mode = mode;
+        dget(dentry);
+
+        /* Mark the file as open to handle open-unlink. */
+        mds_open_orphan_inc(dentry->d_inode);
+
+        mfd->mfd_mode = flags;
         mfd->mfd_dentry = dentry;
         mfd->mfd_xid = req->rq_xid;
 
@@ -78,20 +201,243 @@ struct mds_file_data *mds_dentry_open(struct dentry *dentry,
         list_add(&mfd->mfd_list, &med->med_open_head);
         spin_unlock(&med->med_open_lock);
         mds_mfd_put(mfd);
-        return mfd;
+        RETURN(mfd);
 
 cleanup_mfd:
         mds_mfd_put(mfd);
         mds_mfd_destroy(mfd);
 cleanup_dentry:
-        dput(dentry);
-        mntput(mnt);
         return ERR_PTR(error);
 }
 
-void reconstruct_open(struct mds_update_record *rec, int offset,
-                      struct ptlrpc_request *req,
-                      struct lustre_handle *child_lockh)
+static void mds_objids_from_lmm(obd_id *ids, struct lov_mds_md *lmm,
+                                struct lov_desc *desc)
+{
+        int i;
+        for (i = 0; i < le32_to_cpu(lmm->lmm_stripe_count); i++) {
+                ids[le32_to_cpu(lmm->lmm_objects[i].l_ost_idx)] =
+                        le64_to_cpu(lmm->lmm_objects[i].l_object_id);
+        }
+}
+
+/* Must be called with i_sem held */
+static int mds_create_objects(struct ptlrpc_request *req, int offset,
+                              struct mds_update_record *rec,
+                              struct mds_obd *mds, struct obd_device *obd,
+                              struct inode *inode, void **handle, obd_id **ids)
+{
+        struct obdo *oa;
+        struct obd_trans_info oti = { 0 };
+        struct mds_body *body;
+        struct lov_stripe_md *lsm = NULL;
+        struct lov_mds_md *lmm = NULL;
+        void *lmm_buf;
+        int rc, lmm_bufsize, lmm_size;
+        ENTRY;
+
+        if (rec->ur_flags & MDS_OPEN_DELAY_CREATE ||
+            !(rec->ur_flags & FMODE_WRITE))
+                RETURN(0);
+
+        body = lustre_msg_buf(req->rq_repmsg, 1, sizeof(*body));
+
+        if (!S_ISREG(inode->i_mode))
+                RETURN(0);
+        if (body->valid & OBD_MD_FLEASIZE)
+                RETURN(0);
+
+        OBD_ALLOC(*ids, mds->mds_lov_desc.ld_tgt_count * sizeof(**ids));
+        if (*ids == NULL)
+                RETURN(-ENOMEM);
+        oti.oti_objid = *ids;
+
+        if (*handle == NULL)
+                *handle = fsfilt_start(obd, inode, FSFILT_OP_CREATE, NULL);
+        if (IS_ERR(*handle)) {
+                rc = PTR_ERR(*handle);
+                *handle = NULL;
+                GOTO(out_ids, rc);
+        }
+
+        /* replay case */
+        if (rec->ur_fid2->id) {
+                body->valid |= OBD_MD_FLBLKSZ | OBD_MD_FLEASIZE;
+                lmm_size = rec->ur_eadatalen;
+                lmm = rec->ur_eadata;
+                LASSERT(lmm);
+
+                mds_objids_from_lmm(*ids, lmm, &mds->mds_lov_desc);
+
+                lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, 0);
+                lmm_bufsize = req->rq_repmsg->buflens[offset];
+                LASSERT(lmm_buf);
+                LASSERT(lmm_bufsize >= lmm_size);
+                memcpy(lmm_buf, lmm, lmm_size);
+                rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size);
+                if (rc)
+                        CERROR("open replay failed to set md:%d\n", rc);
+                RETURN(0);
+        }
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out_ids, rc = -ENOMEM);
+        oa->o_mode = S_IFREG | 0600;
+        oa->o_id = inode->i_ino;
+        oa->o_generation = inode->i_generation;
+        oa->o_uid = 0; /* must have 0 uid / gid on OST */
+        oa->o_gid = 0;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGENER | OBD_MD_FLTYPE |
+                OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID;
+        oa->o_size = 0;
+
+        obdo_from_inode(oa, inode, OBD_MD_FLTYPE|OBD_MD_FLATIME|OBD_MD_FLMTIME|
+                        OBD_MD_FLCTIME);
+
+        /* check if things like lstripe/lfs stripe are sending us the ea */
+        if (rec->ur_flags & MDS_OPEN_HAS_EA) {
+                rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, mds->mds_osc_exp,
+                                   0, &lsm, rec->ur_eadata);
+                if (rc)
+                        GOTO(out_oa, rc);
+        }
+
+        rc = obd_create(mds->mds_osc_exp, oa, &lsm, &oti);
+        if (rc) {
+                int level = D_ERROR;
+                if (rc == -ENOSPC)
+                        level = D_INODE;
+                CDEBUG(level, "error creating objects for inode %lu: rc = %d\n",
+                       inode->i_ino, rc);
+                if (rc > 0) {
+                        CERROR("obd_create returned invalid rc %d\n", rc);
+                        rc = -EIO;
+                }
+                GOTO(out_oa, rc);
+        }
+
+        if (inode->i_size) {
+                oa->o_size = inode->i_size;
+                obdo_from_inode(oa, inode, OBD_MD_FLTYPE|OBD_MD_FLATIME|
+                                OBD_MD_FLMTIME| OBD_MD_FLCTIME| OBD_MD_FLSIZE);
+                rc = obd_setattr(mds->mds_osc_exp, oa, lsm, &oti);
+                if (rc) {
+                        CERROR("error setting attrs for inode %lu: rc %d\n",
+                               inode->i_ino, rc);
+                        if (rc > 0) {
+                                CERROR("obd_setattr returned bad rc %d\n", rc);
+                                rc = -EIO;
+                        }
+                        GOTO(out_oa, rc);
+                }
+        }
+
+        body->valid |= OBD_MD_FLBLKSZ | OBD_MD_FLEASIZE;
+        obdo_refresh_inode(inode, oa, OBD_MD_FLBLKSZ);
+
+        LASSERT(lsm && lsm->lsm_object_id);
+        lmm = NULL;
+        rc = obd_packmd(mds->mds_osc_exp, &lmm, lsm);
+        if (!rec->ur_fid2->id)
+                obd_free_memmd(mds->mds_osc_exp, &lsm);
+        LASSERT(rc >= 0);
+        lmm_size = rc;
+        body->eadatasize = rc;
+        rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size);
+        lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, 0);
+        lmm_bufsize = req->rq_repmsg->buflens[offset];
+        LASSERT(lmm_buf);
+        LASSERT(lmm_bufsize >= lmm_size);
+
+        memcpy(lmm_buf, lmm, lmm_size);
+        obd_free_diskmd(mds->mds_osc_exp, &lmm);
+ out_oa:
+        oti_free_cookies(&oti);
+        obdo_free(oa);
+ out_ids:
+        if (rc) {
+                OBD_FREE(*ids, mds->mds_lov_desc.ld_tgt_count * sizeof(**ids));
+                *ids = NULL;
+        }
+        RETURN(rc);
+}
+
+/* Caller must hold mds->mds_epoch_sem */
+static int mds_alloc_filterdata(struct inode *inode)
+{
+        LASSERT(inode->i_filterdata == NULL);
+        OBD_ALLOC(inode->i_filterdata, sizeof(struct mds_filter_data));
+        if (inode->i_filterdata == NULL)
+                return -ENOMEM;
+        LASSERT(igrab(inode) == inode);
+        return 0;
+}
+
+/* Caller must hold mds->mds_epoch_sem */
+static void mds_free_filterdata(struct inode *inode)
+{
+        LASSERT(inode->i_filterdata != NULL);
+        OBD_FREE(inode->i_filterdata, sizeof(struct mds_filter_data));
+        inode->i_filterdata = NULL;
+        iput(inode);
+}
+
+/* epoch argument is nonzero during recovery */
+static int mds_open_io_epoch(struct mds_obd *mds, struct inode *inode,
+                             __u64 epoch)
+{
+        int rc = 0;
+
+        down(&mds->mds_epoch_sem);
+        if (MDS_FILTERDATA(inode) && MDS_FILTERDATA(inode)->io_epoch != 0) {
+                CDEBUG(D_INODE, "continuing MDS epoch "LPU64" for ino %lu/%u\n",
+                       MDS_FILTERDATA(inode)->io_epoch, inode->i_ino,
+                       inode->i_generation);
+                goto out;
+        }
+
+        if (inode->i_filterdata == NULL)
+                mds_alloc_filterdata(inode);
+        if (inode->i_filterdata == NULL) {
+                rc = -ENOMEM;
+                goto out;
+        }
+        if (epoch > mds->mds_io_epoch)
+                mds->mds_io_epoch = epoch;
+        else
+                mds->mds_io_epoch++;
+        MDS_FILTERDATA(inode)->io_epoch = mds->mds_io_epoch;
+        CDEBUG(D_INODE, "starting MDS epoch "LPU64" for ino %lu/%u\n",
+               mds->mds_io_epoch, inode->i_ino, inode->i_generation);
+ out:
+        up(&mds->mds_epoch_sem);
+        return rc;
+}
+
+/* Returns EAGAIN if the client needs to get size and/or cookies and close
+ * again -- which is never true if the file is about to be unlinked. */
+static int mds_close_io_epoch(struct mds_obd *mds, struct inode *inode,
+                              struct mds_body *body, int unlinking)
+{
+        int rc = 0;
+        ENTRY;
+
+        down(&mds->mds_epoch_sem);
+        if (mds_query_write_access(inode) > 0)
+                GOTO(out, rc);
+#if 0
+        if (!unlinking && !(body->valid & OBD_MD_FLSIZE))
+                GOTO(out, rc = EAGAIN);
+#endif
+        mds_free_filterdata(inode);
+ out:
+        up(&mds->mds_epoch_sem);
+        return rc;
+}
+
+static void reconstruct_open(struct mds_update_record *rec, int offset,
+                             struct ptlrpc_request *req,
+                             struct lustre_handle *child_lockh)
 {
         struct ptlrpc_request *oldreq = req->rq_export->exp_outstanding_reply;
         struct mds_export_data *med = &req->rq_export->exp_mds_data;
@@ -112,13 +458,9 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
         body = lustre_msg_buf(req->rq_repmsg, 1, sizeof (*body));
 
         /* copy rc, transno and disp; steal locks */
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
+        mds_req_from_mcd(req, mcd);
         intent_set_disposition(rep, mcd->mcd_last_data);
 
-        if (oldreq)
-                mds_steal_ack_locks(req->rq_export, req);
-
         /* Only replay if create or open actually happened. */
         if (!intent_disposition(rep, DISP_OPEN_CREATE | DISP_OPEN_OPEN) ) {
                 EXIT;
@@ -150,7 +492,7 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
         mds_pack_inode2body(body, child->d_inode);
         if (S_ISREG(child->d_inode->i_mode)) {
                 rc = mds_pack_md(obd, req->rq_repmsg, 2, body,
-                                 child->d_inode);
+                                 child->d_inode, 1);
 
                 if (rc)
                         LASSERT(rc == req->rq_status);
@@ -170,7 +512,8 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
          * exclusively, we can tell we failed because the file already existed.
          */
         if (req->rq_status == -EEXIST &&
-            ((rec->ur_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
+            ((rec->ur_flags & (MDS_OPEN_CREAT | MDS_OPEN_EXCL)) ==
+             (MDS_OPEN_CREAT | MDS_OPEN_EXCL))) {
                 GOTO(out_dput, 0);
         }
 
@@ -194,14 +537,14 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
                 mfd = NULL;
         }
 
-        if (oldreq) {
+        if (oldreq != NULL) {
                 /* if we're not recovering, it had better be found */
-                LASSERT(mfd);
+                LASSERT(mfd != NULL);
         } else if (mfd == NULL) {
                 mntget(mds->mds_vfsmnt);
                 CERROR("Re-opened file \n");
                 mfd = mds_dentry_open(child, mds->mds_vfsmnt,
-                                   rec->ur_flags & ~(O_DIRECT | O_TRUNC), req);
+                                      rec->ur_flags & ~MDS_OPEN_TRUNC, req);
                 if (!mfd) {
                         CERROR("mds: out of memory\n");
                         GOTO(out_dput, req->rq_status = -ENOMEM);
@@ -209,6 +552,9 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
                 put_child = 0;
         }
 
+        if ((rec->ur_flags & FMODE_WRITE) &&
+            mds_open_io_epoch(mds, child->d_inode, 0) == 0)
+                body->io_epoch = MDS_FILTERDATA(child->d_inode)->io_epoch;
         body->handle.cookie = mfd->mfd_handle.h_cookie;
 
  out_dput:
@@ -218,115 +564,177 @@ void reconstruct_open(struct mds_update_record *rec, int offset,
         EXIT;
 }
 
-int mds_pin(struct ptlrpc_request *req)
+/* do NOT or the MAY_*'s, you'll get the weakest */
+static int accmode(int flags)
+{
+        int res = 0;
+
+        if (flags & FMODE_READ)
+                res = MAY_READ;
+        if (flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
+                res |= MAY_WRITE;
+        if (flags & FMODE_EXEC)
+                res = MAY_EXEC;
+        return res;
+}
+
+/* Handles object creation, actual opening, and I/O epoch */
+static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild,
+                           struct mds_body *body, int flags, void **handle,
+                           struct mds_update_record *rec,struct ldlm_reply *rep)
 {
         struct mds_obd *mds = mds_req2mds(req);
-        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
+        struct obd_device *obd = req->rq_export->exp_obd;
         struct mds_file_data *mfd = NULL;
-        struct mds_body *body;
+        obd_id *ids = NULL; /* object IDs created */
+        int rc;
+        ENTRY;
+
+        /* atomically create objects if necessary */
+        down(&dchild->d_inode->i_sem);
+        if (S_ISREG(dchild->d_inode->i_mode) &&
+            !(body->valid & OBD_MD_FLEASIZE)) {
+                rc = mds_pack_md(obd, req->rq_repmsg, 2, body,
+                                 dchild->d_inode, 0);
+                if (rc) {
+                        up(&dchild->d_inode->i_sem);
+                        RETURN(rc);
+                }
+        }
+        if (rec != NULL) {
+                /* no EA: create objects */
+                rc = mds_create_objects(req, 2, rec, mds, obd,
+                                        dchild->d_inode, handle, &ids);
+                if (rc) {
+                        CERROR("mds_create_objects: rc = %d\n", rc);
+                        up(&dchild->d_inode->i_sem);
+                        RETURN(rc);
+                }
+        }
+        /* If the inode has EA data, then OSTs hold size, mtime */
+        if (S_ISREG(dchild->d_inode->i_mode) &&
+            !(body->valid & OBD_MD_FLEASIZE)) {
+                body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
+                                OBD_MD_FLATIME | OBD_MD_FLMTIME);
+        }
+        up(&dchild->d_inode->i_sem);
+
+        intent_set_disposition(rep, DISP_OPEN_OPEN);
+        mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, flags, req);
+        if (IS_ERR(mfd))
+                RETURN(PTR_ERR(mfd));
+
+        if ((rec->ur_flags & FMODE_WRITE) &&
+            mds_open_io_epoch(mds, dchild->d_inode, 0) == 0)
+                body->io_epoch = MDS_FILTERDATA(dchild->d_inode)->io_epoch;
+        body->handle.cookie = mfd->mfd_handle.h_cookie;
+
+        CDEBUG(D_INODE, "mfd %p, cookie "LPX64"\n", mfd,
+               mfd->mfd_handle.h_cookie);
+        if (ids != NULL) {
+                mds_lov_update_objids(obd, ids);
+                OBD_FREE(ids, sizeof(*ids) * mds->mds_lov_desc.ld_tgt_count);
+        }
+        if (rc)
+                mds_mfd_destroy(mfd);
+        RETURN(rc);
+}
+
+static int mds_open_by_fid(struct ptlrpc_request *req, struct ll_fid *fid,
+                           struct mds_body *body, int flags,
+                           struct mds_update_record *rec,struct ldlm_reply *rep)
+{
+        struct mds_obd *mds = mds_req2mds(req);
+        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
         struct dentry *dchild;
-        struct obd_run_ctxt saved;
         char fidname[LL_FID_NAMELEN];
-        int fidlen = 0, rc, cleanup_phase = 0, size = sizeof(*body);
+        int fidlen = 0, rc;
+        void *handle = NULL;
         ENTRY;
 
-        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-
         down(&pending_dir->i_sem);
-        fidlen = ll_fid2str(fidname, body->fid1.id, body->fid1.generation);
+        fidlen = ll_fid2str(fidname, fid->id, fid->generation);
         dchild = lookup_one_len(fidname, mds->mds_pending_dir, fidlen);
         if (IS_ERR(dchild)) {
                 up(&pending_dir->i_sem);
                 rc = PTR_ERR(dchild);
-                CERROR("error looking up %s in PENDING: rc = %d\n",
-                       fidname, rc);
+                CERROR("error looking up %s in PENDING: rc = %d\n",fidname, rc);
                 RETURN(rc);
         }
 
-        cleanup_phase = 2;
-
-        if (dchild->d_inode) {
+        if (dchild->d_inode != NULL) {
                 up(&pending_dir->i_sem);
                 mds_inode_set_orphan(dchild->d_inode);
                 mds_pack_inode2fid(&body->fid1, dchild->d_inode);
                 mds_pack_inode2body(body, dchild->d_inode);
-                GOTO(openit, rc = 0);
+                intent_set_disposition(rep, DISP_LOOKUP_EXECD);
+                intent_set_disposition(rep, DISP_LOOKUP_POS);
+                CWARN("Orphan %s found and opened in PENDING directory\n",
+                       fidname);
+                goto open;
         }
         dput(dchild);
         up(&pending_dir->i_sem);
 
         /* We didn't find it in PENDING so it isn't an orphan.  See
-         * if it's a regular inode. */
-        dchild = mds_fid2dentry(mds, &body->fid1, NULL);
-        if (!IS_ERR(dchild)) {
-                mds_pack_inode2fid(&body->fid1, dchild->d_inode);
-                mds_pack_inode2body(body, dchild->d_inode);
-                GOTO(openit, rc = 0);
-        }
+         * if it was a regular inode that was previously created. */
+        dchild = mds_fid2dentry(mds, fid, NULL);
+        if (IS_ERR(dchild))
+                RETURN(PTR_ERR(dchild));
 
-        /* We didn't find this inode on disk, but we're trying to pin it.
-         * This should never happen. */
-        CERROR("ENOENT during mds_pin for fid "LPU64"/%u\n", body->fid1.id,
-               body->fid1.generation);
-        RETURN(-ENOENT);
+        mds_pack_inode2fid(&body->fid1, dchild->d_inode);
+        mds_pack_inode2body(body, dchild->d_inode);
+        intent_set_disposition(rep, DISP_LOOKUP_EXECD);
+        intent_set_disposition(rep, DISP_LOOKUP_POS);
 
- openit:
-        /* dentry_open does a dput(de) and mntput(mds->mds_vfsmnt) on error */
-        mfd = mds_dentry_open(dchild, mds->mds_vfsmnt, body->flags, req);
-        if (IS_ERR(mfd)) {
-                dchild = NULL; /* prevent a double dput in cleanup phase 2 */
-                GOTO(cleanup, rc = PTR_ERR(mfd));
-        }
+ open:
+        rc = mds_finish_open(req, dchild, body, flags, &handle, rec, rep);
+        rc = mds_finish_transno(mds, dchild ? dchild->d_inode : NULL, handle,
+                                req, rc, rep ? rep->lock_policy_res1 : 0);
+        /* XXX what do we do here if mds_finish_transno itself failed? */
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
-        if (rc) {
-                CERROR("out of memoryK\n");
-                GOTO(cleanup, rc);
-        }
-        body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+        l_dput(dchild);
+        RETURN(rc);
+}
 
-        cleanup_phase = 4; /* mfd allocated */
-        body->handle.cookie = mfd->mfd_handle.h_cookie;
-        CDEBUG(D_INODE, "mfd %p, cookie "LPX64"\n", mfd,
-               mfd->mfd_handle.h_cookie);
-        GOTO(cleanup, rc = 0);
+int mds_pin(struct ptlrpc_request *req)
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct mds_body *request_body, *reply_body;
+        struct obd_run_ctxt saved;
+        int rc, size = sizeof(*reply_body);
+        ENTRY;
 
- cleanup:
-        push_ctxt(&saved, &mds->mds_ctxt, NULL);
-        rc = mds_finish_transno(mds, dchild ? dchild->d_inode : NULL, NULL,
-                                req, rc, 0);
-        pop_ctxt(&saved, &mds->mds_ctxt, NULL);
-        /* XXX what do we do here if mds_finish_transno itself failed? */
-        switch (cleanup_phase) {
-        case 4:
-                if (rc)
-                        mds_mfd_destroy(mfd);
-        case 2:
-                if (rc || S_ISLNK(dchild->d_inode->i_mode))
-                        l_dput(dchild);
-        }
-        return rc;
+        request_body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*request_body));
+
+        rc = lustre_pack_reply(req, 1, &size, NULL);
+        if (rc)
+                RETURN(rc);
+        reply_body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*reply_body));
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        rc = mds_open_by_fid(req, &request_body->fid1, reply_body,
+                             request_body->flags, NULL, NULL);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+        RETURN(rc);
 }
 
 int mds_open(struct mds_update_record *rec, int offset,
              struct ptlrpc_request *req, struct lustre_handle *child_lockh)
 {
         /* XXX ALLOCATE _something_ - 464 bytes on stack here */
-        static const char acc_table [] = {[O_RDONLY] MAY_READ,
-                                          [O_WRONLY] MAY_WRITE,
-                                          [O_RDWR]   MAY_READ | MAY_WRITE};
-        struct mds_obd *mds = mds_req2mds(req);
         struct obd_device *obd = req->rq_export->exp_obd;
+        struct mds_obd *mds = mds_req2mds(req);
         struct ldlm_reply *rep = NULL;
         struct mds_body *body = NULL;
         struct dentry *dchild = NULL, *parent = NULL;
         struct mds_export_data *med;
-        struct mds_file_data *mfd = NULL;
         struct ldlm_res_id child_res_id = { .name = {0} };
         struct lustre_handle parent_lockh;
-        int rc = 0, parent_mode, child_mode = LCK_PR, lock_flags, created = 0;
-        int cleanup_phase = 0, acc_mode;
+        int rc = 0, parent_mode = 0, cleanup_phase = 0, acc_mode, created = 0;
         void *handle = NULL;
+        struct dentry_params dp;
         ENTRY;
 
         if (offset == 2) { /* intent */
@@ -343,77 +751,37 @@ int mds_open(struct mds_update_record *rec, int offset,
 
         /* Step 0: If we are passed a fid, then we assume the client already
          * opened this file and is only replaying the RPC, so we open the
-         * inode by fid (at some large expense in security).
-         */
+         * inode by fid (at some large expense in security). */
         if (rec->ur_fid2->id) {
-                struct inode *pending_dir = mds->mds_pending_dir->d_inode;
-                char fidname[LL_FID_NAMELEN];
-                int fidlen = 0;
-
-                down(&pending_dir->i_sem);
-                fidlen = ll_fid2str(fidname, rec->ur_fid2->id,
-                                    rec->ur_fid2->generation);
-                dchild = lookup_one_len(fidname, mds->mds_pending_dir, fidlen);
-                if (IS_ERR(dchild)) {
-                        up(&pending_dir->i_sem);
-                        rc = PTR_ERR(dchild);
-                        CERROR("error looking up %s in PENDING: rc = %d\n",
-                               fidname, rc);
+                rc = mds_open_by_fid(req, rec->ur_fid2, body, rec->ur_flags,
+                                     rec, rep);
+                if (rc != -ENOENT)
                         RETURN(rc);
-                }
-
-                if (dchild->d_inode) {
-                        up(&pending_dir->i_sem);
-                        mds_inode_set_orphan(dchild->d_inode);
-                        mds_pack_inode2fid(&body->fid1, dchild->d_inode);
-                        mds_pack_inode2body(body, dchild->d_inode);
-                        cleanup_phase = 2;
-                        GOTO(openit, rc = 0);
-                }
-                dput(dchild);
-                up(&pending_dir->i_sem);
-
-                /* We didn't find it in PENDING so it isn't an orphan.  See
-                 * if it was a regular inode that was previously created.
-                 */
-                dchild = mds_fid2dentry(mds, rec->ur_fid2, NULL);
-                if (!IS_ERR(dchild)) {
-                        mds_pack_inode2fid(&body->fid1, dchild->d_inode);
-                        mds_pack_inode2body(body, dchild->d_inode);
-                        cleanup_phase = 2;
-                        GOTO(openit, rc = 0);
-                }
-
                 /* We didn't find the correct inode on disk either, so we
-                 * need to re-create it via a regular replay.  Do that below.
-                 */
-                LASSERT(rec->ur_flags & O_CREAT);
+                 * need to re-create it via a regular replay. */
+                LASSERT(rec->ur_flags & MDS_OPEN_CREAT);
         }
         LASSERT(offset == 2); /* If we got here, we must be called via intent */
 
         med = &req->rq_export->exp_mds_data;
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) {
                 CERROR("test case OBD_FAIL_MDS_OPEN_PACK\n");
-                req->rq_status = -ENOMEM;
                 RETURN(-ENOMEM);
         }
 
-        if ((rec->ur_flags & O_ACCMODE) >= sizeof (acc_table))
-                RETURN(-EINVAL);
-        acc_mode = acc_table[rec->ur_flags & O_ACCMODE];
-        if ((rec->ur_flags & O_TRUNC) != 0)
-                acc_mode |= MAY_WRITE;
+        acc_mode = accmode(rec->ur_flags);
 
         /* Step 1: Find and lock the parent */
-        parent_mode = (rec->ur_flags & O_CREAT) ? LCK_PW : LCK_PR;
+        parent_mode = (rec->ur_flags & MDS_OPEN_CREAT) ? LCK_PW : LCK_PR;
         parent = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, parent_mode,
-                                       &parent_lockh);
+                                       &parent_lockh, rec->ur_name,
+                                       rec->ur_namelen - 1);
         if (IS_ERR(parent)) {
                 rc = PTR_ERR(parent);
                 CERROR("parent lookup error %d\n", rc);
                 GOTO(cleanup, rc);
         }
-        LASSERT(parent->d_inode);
+        LASSERT(parent->d_inode != NULL);
 
         cleanup_phase = 1; /* parent dentry and lock */
 
@@ -430,12 +798,13 @@ int mds_open(struct mds_update_record *rec, int offset,
         else
                 intent_set_disposition(rep, DISP_LOOKUP_NEG);
 
-        /* Step 3: If the child was negative, and we're supposed to,
-         * create it. */
-        if (!dchild->d_inode) {
+        /*Step 3: If the child was negative, and we're supposed to, create it.*/
+        if (dchild->d_inode == NULL) {
                 unsigned long ino = rec->ur_fid2->id;
+                struct iattr iattr;
+                struct inode *inode;
 
-                if (!(rec->ur_flags & O_CREAT)) {
+                if (!(rec->ur_flags & MDS_OPEN_CREAT)) {
                         /* It's negative and we weren't supposed to create it */
                         GOTO(cleanup, rc = -ENOENT);
                 }
@@ -448,83 +817,62 @@ int mds_open(struct mds_update_record *rec, int offset,
                         handle = NULL;
                         GOTO(cleanup, rc);
                 }
-                if (ino)
-                        dchild->d_fsdata = (void *)(unsigned long)ino;
+                dchild->d_fsdata = (void *) &dp;
+                dp.p_ptr = req;
+                dp.p_inum = ino;
 
-                rc = vfs_create(parent->d_inode, dchild, rec->ur_mode);
+                rc = ll_vfs_create(parent->d_inode, dchild, rec->ur_mode, NULL);
                 if (dchild->d_fsdata == (void *)(unsigned long)ino)
                         dchild->d_fsdata = NULL;
 
                 if (rc) {
                         CDEBUG(D_INODE, "error during create: %d\n", rc);
                         GOTO(cleanup, rc);
-                } else {
-                        struct iattr iattr;
-                        struct inode *inode = dchild->d_inode;
-
-                        if (ino) {
-                                LASSERT(ino == inode->i_ino);
-                                /* Written as part of setattr */
-                                inode->i_generation = rec->ur_fid2->generation;
-                                CDEBUG(D_HA, "recreated ino %lu with gen %x\n",
-                                       inode->i_ino, inode->i_generation);
-                        }
+                }
+                inode = dchild->d_inode;
+                if (ino) {
+                        LASSERT(ino == inode->i_ino);
+                        /* Written as part of setattr */
+                        inode->i_generation = rec->ur_fid2->generation;
+                        CDEBUG(D_HA, "recreated ino %lu with gen %u\n",
+                               inode->i_ino, inode->i_generation);
+                }
 
-                        created = 1;
-                        LTIME_S(iattr.ia_atime) = rec->ur_time;
-                        LTIME_S(iattr.ia_ctime) = rec->ur_time;
-                        LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                created = 1;
+                LTIME_S(iattr.ia_atime) = rec->ur_time;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                LTIME_S(iattr.ia_mtime) = rec->ur_time;
 
-                        iattr.ia_uid = rec->ur_uid;
-                        if (parent->d_inode->i_mode & S_ISGID) {
-                                iattr.ia_gid = parent->d_inode->i_gid;
-                        } else
-                                iattr.ia_gid = rec->ur_gid;
+                iattr.ia_uid = rec->ur_fsuid;
+                if (parent->d_inode->i_mode & S_ISGID)
+                        iattr.ia_gid = parent->d_inode->i_gid;
+                else
+                        iattr.ia_gid = rec->ur_fsgid;
 
-                        iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME |
-                                ATTR_MTIME | ATTR_CTIME;
+                iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME |
+                        ATTR_MTIME | ATTR_CTIME;
 
-                        rc = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
-                        if (rc) {
-                                CERROR("error on setattr: rc = %d\n", rc);
-                                /* XXX should we abort here in case of error? */
-                        }
-                }
+                rc = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
+                if (rc)
+                        CERROR("error on child setattr: rc = %d\n", rc);
 
-                child_mode = LCK_PW;
-                acc_mode = 0;                  /* Don't check for permissions */
-        }
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
 
-        LASSERT(!mds_inode_is_orphan(dchild->d_inode));
+                rc = fsfilt_setattr(obd, parent, handle, &iattr, 0);
+                if (rc)
+                        CERROR("error on parent setattr: rc = %d\n", rc);
 
-        /* Step 4: It's positive, so lock the child */
-        child_res_id.name[0] = dchild->d_inode->i_ino;
-        child_res_id.name[1] = dchild->d_inode->i_generation;
- reacquire:
-        lock_flags = 0;
-        /* For the open(O_CREAT) case, this would technically be a lock
-         * inversion (getting a VFS lock after starting a transaction),
-         * but in that case we cannot possibly block on this lock because
-         * we just created the child and also hold a write lock on the
-         * parent, so nobody could be holding the lock yet.
-         */
-        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
-                              child_res_id, LDLM_PLAIN, NULL, 0, child_mode,
-                              &lock_flags, ldlm_completion_ast,
-                              mds_blocking_ast, NULL, child_lockh);
-        if (rc != ELDLM_OK) {
-                CERROR("ldlm_cli_enqueue: %d\n", rc);
-                GOTO(cleanup, rc = -EIO);
+                acc_mode = 0;                  /* Don't check for permissions */
         }
 
-        cleanup_phase = 3; /* child lock */
+        LASSERT(!mds_inode_is_orphan(dchild->d_inode));
 
         mds_pack_inode2fid(&body->fid1, dchild->d_inode);
         mds_pack_inode2body(body, dchild->d_inode);
 
         if (S_ISREG(dchild->d_inode->i_mode)) {
                 /* Check permissions etc */
-                rc = permission(dchild->d_inode, acc_mode);
+                rc = ll_permission(dchild->d_inode, acc_mode, NULL);
                 if (rc != 0)
                         GOTO(cleanup, rc);
 
@@ -535,90 +883,300 @@ int mds_open(struct mds_update_record *rec, int offset,
                 /* An append-only file must be opened in append mode for
                  * writing */
                 if (IS_APPEND(dchild->d_inode) && (acc_mode & MAY_WRITE) != 0 &&
-                    ((rec->ur_flags & O_APPEND) == 0 ||
-                     (rec->ur_flags & O_TRUNC) != 0))
+                    ((rec->ur_flags & MDS_OPEN_APPEND) == 0 ||
+                     (rec->ur_flags & MDS_OPEN_TRUNC) != 0))
                         GOTO(cleanup, rc = -EPERM);
-
-                rc = mds_pack_md(obd, req->rq_repmsg, 2, body, dchild->d_inode);
-                if (rc)
-                        GOTO(cleanup, rc);
-
-                /* If we have LOV EA data, the OST holds size, mtime */
-                if (!(body->valid & OBD_MD_FLEASIZE))
-                        body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
-                                        OBD_MD_FLATIME | OBD_MD_FLMTIME);
         }
 
-        if (!created && (rec->ur_flags & O_CREAT) &&
-            (rec->ur_flags & O_EXCL)) {
+        if (!created && (rec->ur_flags & MDS_OPEN_CREAT) &&
+            (rec->ur_flags & MDS_OPEN_EXCL)) {
                 /* File already exists, we didn't just create it, and we
                  * were passed O_EXCL; err-or. */
                 GOTO(cleanup, rc = -EEXIST); // returns a lock to the client
         }
 
-        /* If we're opening a file without an EA for write, the client needs
-         * a write lock. */
-        if (S_ISREG(dchild->d_inode->i_mode) && (rec->ur_flags & O_ACCMODE) &&
-            child_mode != LCK_PW && !(body->valid & OBD_MD_FLEASIZE)) {
-                ldlm_lock_decref(child_lockh, child_mode);
-                child_mode = LCK_PW;
-                goto reacquire;
-        }
-
         /* if we are following a symlink, don't open */
         if (S_ISLNK(dchild->d_inode->i_mode))
                 GOTO(cleanup, rc = 0);
 
-        if ((rec->ur_flags & O_DIRECTORY) && !S_ISDIR(dchild->d_inode->i_mode))
+        if ((rec->ur_flags & MDS_OPEN_DIRECTORY) &&
+            !S_ISDIR(dchild->d_inode->i_mode))
                 GOTO(cleanup, rc = -ENOTDIR);
 
         /* Step 5: mds_open it */
-        intent_set_disposition(rep, DISP_OPEN_OPEN);
- openit:
-        /* dentry_open does a dput(de) and mntput(mds->mds_vfsmnt) on error */
-        mfd = mds_dentry_open(dchild, mds->mds_vfsmnt,
-                              rec->ur_flags & ~(O_DIRECT | O_TRUNC), req);
-        if (IS_ERR(mfd)) {
-                dchild = NULL; /* prevent a double dput in cleanup phase 2 */
-                GOTO(cleanup, rc = PTR_ERR(mfd));
-        }
-
-        cleanup_phase = 4; /* mfd allocated */
-        body->handle.cookie = mfd->mfd_handle.h_cookie;
-        CDEBUG(D_INODE, "mfd %p, cookie "LPX64"\n", mfd,
-               mfd->mfd_handle.h_cookie);
-        GOTO(cleanup, rc = 0); /* returns a lock to the client */
+        rc = mds_finish_open(req, dchild, body, rec->ur_flags, &handle, rec,
+                             rep);
+        GOTO(cleanup, rc);
 
  cleanup:
         rc = mds_finish_transno(mds, dchild ? dchild->d_inode : NULL, handle,
-                                req, rc, rep->lock_policy_res1);
+                                req, rc, rep ? rep->lock_policy_res1 : 0);
         /* XXX what do we do here if mds_finish_transno itself failed? */
+        if (created) {
+                /* Step 4: Lock new child to sync inode reuse (bug 2029) */
+                int lock_flags = 0, err;
+                child_res_id.name[0] = dchild->d_inode->i_ino;
+                child_res_id.name[1] = 0;
+                err = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
+                                       child_res_id, LDLM_PLAIN, NULL, 0,
+                                       LCK_EX, &lock_flags, ldlm_completion_ast,
+                                       mds_blocking_ast, NULL, child_lockh);
+                if (err == ELDLM_OK)
+                        ldlm_lock_decref(child_lockh, LCK_EX);
+                else
+                        CERROR("ldlm_cli_enqueue: %d\n", err);
+        }
+
         switch (cleanup_phase) {
-        case 4:
-                if (rc && !S_ISLNK(dchild->d_inode->i_mode))
-                        mds_mfd_destroy(mfd);
-        case 3:
-                /* This is the same logic as in the IT_OPEN part of
-                 * ldlm_intent_policy: if we found the dentry, or we tried to
-                 * open it (meaning that we created, if it wasn't found), then
-                 * we return the lock to the caller and client. */
-                if (intent_disposition(rep, DISP_LOOKUP_NEG) &&
-                    !intent_disposition(rep, DISP_OPEN_OPEN))
-                        ldlm_lock_decref(child_lockh, child_mode);
         case 2:
-                if (rc || S_ISLNK(dchild->d_inode->i_mode))
-                        l_dput(dchild);
-        case 1:
-                if (parent) {
-                        l_dput(parent);
-                        if (rc) {
-                                ldlm_lock_decref(&parent_lockh, parent_mode);
-                        } else {
-                                memcpy(&req->rq_ack_locks[0].lock,&parent_lockh,
-                                       sizeof(parent_lockh));
-                                req->rq_ack_locks[0].mode = parent_mode;
+                if (rc && created) {
+                        int err = vfs_unlink(parent->d_inode, dchild);
+                        if (err) {
+                                CERROR("unlink(%*s) in error path: %d\n",
+                                       dchild->d_name.len, dchild->d_name.name,
+                                       err);
                         }
                 }
+                l_dput(dchild);
+        case 1:
+                if (parent == NULL)
+                        break;
+
+                l_dput(parent);
+                if (rc)
+                        ldlm_lock_decref(&parent_lockh, parent_mode);
+                else
+                        ldlm_put_lock_into_req(req, &parent_lockh, parent_mode);
         }
         RETURN(rc);
 }
+
+/* Close a "file descriptor" and possibly unlink an orphan from the
+ * PENDING directory.
+ *
+ * If we are being called from mds_disconnect() because the client has
+ * disappeared, then req == NULL and we do not update last_rcvd because
+ * there is nothing that could be recovered by the client at this stage
+ * (it will not even _have_ an entry in last_rcvd anymore).
+ *
+ * Returns EAGAIN if the client needs to get more data and re-close. */
+int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd,
+                  struct mds_file_data *mfd, int unlink_orphan)
+{
+        struct inode *inode = mfd->mfd_dentry->d_inode;
+        char fidname[LL_FID_NAMELEN];
+        int last_orphan, fidlen, rc = 0, cleanup_phase = 0;
+        struct dentry *pending_child = NULL;
+        struct mds_obd *mds = &obd->u.mds;
+        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
+        void *handle = NULL;
+        struct mds_body *request_body, *reply_body;
+        struct dentry_params dp;
+        ENTRY;
+
+        if (req != NULL) {
+                request_body = lustre_msg_buf(req->rq_reqmsg, 0,
+                                              sizeof(*request_body));
+                reply_body = lustre_msg_buf(req->rq_repmsg, 0,
+                                            sizeof(*reply_body));
+        }
+
+        fidlen = ll_fid2str(fidname, inode->i_ino, inode->i_generation);
+
+        last_orphan = mds_open_orphan_dec_test(inode) &&
+                mds_inode_is_orphan(inode);
+
+        /* this is the actual "close" */
+        if (mfd->mfd_mode & FMODE_WRITE) {
+                mds_put_write_access(inode);
+        } else if (mfd->mfd_mode & FMODE_EXEC) {
+                mds_allow_write_access(inode);
+        }
+
+        if (last_orphan && unlink_orphan) {
+                LASSERT(mds_query_write_access(inode) == 0);
+                if (mfd->mfd_mode & FMODE_WRITE)
+                        rc = mds_close_io_epoch(mds, inode, request_body, 1);
+
+                CWARN("destroying orphan object %s\n", fidname);
+
+                /* Sadly, there is no easy way to save pending_child from
+                 * mds_reint_unlink() into mfd, so we need to re-lookup,
+                 * but normally it will still be in the dcache. */
+                pending_dir = mds->mds_pending_dir->d_inode;
+                down(&pending_dir->i_sem);
+                cleanup_phase = 1; /* up(i_sem) when finished */
+                pending_child = lookup_one_len(fidname, mds->mds_pending_dir,
+                                               fidlen);
+                if (IS_ERR(pending_child))
+                        GOTO(cleanup, rc = PTR_ERR(pending_child));
+                LASSERT(pending_child->d_inode != NULL);
+
+                cleanup_phase = 2; /* dput(pending_child) when finished */
+                handle = fsfilt_start(obd, pending_dir, FSFILT_OP_UNLINK_LOG,
+                                      NULL);
+                if (IS_ERR(handle)) {
+                        rc = PTR_ERR(handle);
+                        handle = NULL;
+                        GOTO(cleanup, rc);
+                }
+
+#ifdef ENABLE_ORPHANS
+                if (req != NULL &&
+                    (reply_body->valid & OBD_MD_FLEASIZE) &&
+                    mds_log_op_unlink(obd, pending_child->d_inode,
+                                      req->rq_repmsg, 1) > 0) {
+                        reply_body->valid |= OBD_MD_FLCOOKIE;
+                }
+#endif
+                pending_child->d_fsdata = (void *) &dp;
+                dp.p_inum = 0;
+                dp.p_ptr = req;
+                if (S_ISDIR(pending_child->d_inode->i_mode))
+                        rc = vfs_rmdir(pending_dir, pending_child);
+                else
+                        rc = vfs_unlink(pending_dir, pending_child);
+                if (rc)
+                        CERROR("error unlinking orphan %s: rc %d\n",fidname,rc);
+        } else if (mfd->mfd_mode & FMODE_WRITE &&
+                   mds_query_write_access(inode) == 0) {
+                // XXX this should probably be abstracted with mds_reint_setattr
+                struct iattr iattr;
+
+                rc = mds_close_io_epoch(mds, inode, request_body, 0);
+                if (rc == EAGAIN)
+                        goto dput;
+
+#if 0
+                /* XXX can't set block count with fsfilt_setattr (!) */
+                iattr.ia_valid = ATTR_CTIME | ATTR_ATIME |
+                        ATTR_MTIME | ATTR_SIZE;
+                iattr.ia_atime = request_body->atime;
+                iattr.ia_ctime = request_body->ctime;
+                iattr.ia_mtime = request_body->mtime;
+                iattr.ia_size = request_body->size;
+                /* iattr.ia_blocks = request_body->blocks */
+
+                handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                rc = fsfilt_setattr(obd, mfd->mfd_dentry, handle, &iattr, 0);
+                if (rc)
+                        CERROR("error in setattr(%s): rc %d\n", fidname, rc);
+#endif
+        }
+ dput:
+        l_dput(mfd->mfd_dentry);
+        mds_mfd_destroy(mfd);
+
+ cleanup:
+        if (req) {
+                rc = mds_finish_transno(mds, pending_dir, handle, req, rc, 0);
+        } else if (handle) {
+                int err = fsfilt_commit(obd, pending_dir, handle, 0);
+                if (err) {
+                        CERROR("error committing close: %d\n", err);
+                        if (!rc)
+                                rc = err;
+                }
+        }
+
+        switch (cleanup_phase) {
+        case 2:
+                dput(pending_child);
+        case 1:
+                up(&pending_dir->i_sem);
+        }
+        RETURN(rc);
+}
+
+int mds_close(struct ptlrpc_request *req)
+{
+        struct mds_export_data *med = &req->rq_export->exp_mds_data;
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct mds_body *body;
+        struct mds_file_data *mfd;
+        struct obd_run_ctxt saved;
+        struct inode *inode;
+        int rc, repsize[3] = {sizeof(struct mds_body),
+                              obd->u.mds.mds_max_mdsize,
+                              obd->u.mds.mds_max_cookiesize};
+        ENTRY;
+
+        MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
+
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
+        if (body == NULL) {
+                CERROR("Can't unpack body\n");
+                req->rq_status = -EFAULT;
+                RETURN(-EFAULT);
+        }
+
+        if (body->flags & MDS_BFLAG_UNCOMMITTED_WRITES)
+                /* do some stuff */ ;
+
+        mfd = mds_handle2mfd(&body->handle);
+        if (mfd == NULL) {
+                DEBUG_REQ(D_ERROR, req, "no handle for file close ino "LPD64
+                          ": cookie "LPX64, body->fid1.id, body->handle.cookie);
+                req->rq_status = -ESTALE;
+                RETURN(-ESTALE);
+        }
+
+        rc = lustre_pack_reply(req, 3, repsize, NULL);
+        if (rc) {
+                CERROR("lustre_pack_reply: rc = %d\n", rc);
+                req->rq_status = rc;
+        }
+
+        inode = mfd->mfd_dentry->d_inode;
+        if (mds_inode_is_orphan(inode) && mds_open_orphan_count(inode) == 1) {
+                body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
+                LASSERT(body != NULL);
+
+                mds_pack_inode2fid(&body->fid1, inode);
+                mds_pack_inode2body(body, inode);
+                mds_pack_md(obd, req->rq_repmsg, 1, body, inode, 1);
+        }
+        spin_lock(&med->med_open_lock);
+        list_del(&mfd->mfd_list);
+        spin_unlock(&med->med_open_lock);
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        req->rq_status = mds_mfd_close(rc ? NULL : req, obd, mfd, 1);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+        if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK)) {
+                CERROR("test case OBD_FAIL_MDS_CLOSE_PACK\n");
+                req->rq_status = -ENOMEM;
+                mds_mfd_put(mfd);
+                RETURN(-ENOMEM);
+        }
+
+        mds_mfd_put(mfd);
+        RETURN(0);
+}
+
+int mds_done_writing(struct ptlrpc_request *req)
+{
+        struct mds_body *body;
+        int rc, size = sizeof(struct mds_body);
+        ENTRY;
+
+        MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
+
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
+        if (body == NULL) {
+                CERROR("Can't unpack body\n");
+                req->rq_status = -EFAULT;
+                RETURN(-EFAULT);
+        }
+
+        rc = lustre_pack_reply(req, 1, &size, NULL);
+        if (rc) {
+                CERROR("lustre_pack_reply: rc = %d\n", rc);
+                req->rq_status = rc;
+        }
+
+        RETURN(0);
+}
diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c
index 7255bf734541f0e397e90443c81de49a8b3850b3..392edab21eb5923aad3188d1e12530b254390ec0 100644
--- a/lustre/mds/mds_reint.c
+++ b/lustre/mds/mds_reint.c
@@ -25,7 +25,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <linux/fs.h>
@@ -54,45 +56,15 @@ struct mds_logcancel_data {
         struct llog_cookie      mlcd_cookies[0];
 };
 
-/* Establish a connection to the OSC when we first need it.  We don't do
- * this during MDS setup because that would introduce setup ordering issues. */
-static int mds_osc_connect(struct obd_device *obd, struct mds_obd *mds)
-{
-        int rc;
-        ENTRY;
-
-        if (IS_ERR(mds->mds_osc_obd))
-                RETURN(PTR_ERR(mds->mds_osc_obd));
-
-        if (mds->mds_osc_obd)
-                RETURN(0);
-
-        mds->mds_osc_obd = class_uuid2obd(&mds->mds_osc_uuid);
-        if (!mds->mds_osc_obd) {
-                CERROR("MDS cannot locate OSC/LOV %s - no logging!\n",
-                       mds->mds_osc_uuid.uuid);
-                mds->mds_osc_obd = ERR_PTR(-ENOTCONN);
-                RETURN(-ENOTCONN);
-        }
-
-        rc = obd_connect(&mds->mds_osc_conn, mds->mds_osc_obd, &obd->obd_uuid);
-        if (rc) {
-                CERROR("MDS cannot locate OSC/LOV %s - no logging!\n",
-                       mds->mds_osc_uuid.uuid);
-                mds->mds_osc_obd = ERR_PTR(rc);
-                RETURN(rc);
-        }
-
-        rc = obd_set_info(&mds->mds_osc_conn, strlen("mds_conn"), "mds_conn",
-                          0, NULL);
-        RETURN(rc);
-}
 
 static void mds_cancel_cookies_cb(struct obd_device *obd, __u64 transno,
                                   void *cb_data, int error)
 {
         struct mds_logcancel_data *mlcd = cb_data;
         struct lov_stripe_md *lsm = NULL;
+#ifdef ENABLE_ORPHANS
+        struct llog_ctxt *ctxt;
+#endif
         int rc;
 
         obd_transno_commit_cb(obd, transno, error);
@@ -100,22 +72,25 @@ static void mds_cancel_cookies_cb(struct obd_device *obd, __u64 transno,
         CDEBUG(D_HA, "cancelling %d cookies\n",
                (int)(mlcd->mlcd_cookielen / sizeof(*mlcd->mlcd_cookies)));
 
-        rc = obd_unpackmd(&obd->u.mds.mds_osc_conn, &lsm, mlcd->mlcd_lmm,
+        rc = obd_unpackmd(obd->u.mds.mds_osc_exp, &lsm, mlcd->mlcd_lmm,
                           mlcd->mlcd_eadatalen);
         if (rc < 0) {
                 CERROR("bad LSM cancelling %d log cookies: rc %d\n",
                        (int)(mlcd->mlcd_cookielen/sizeof(*mlcd->mlcd_cookies)),
                        rc);
         } else {
-                rc = obd_log_cancel(&obd->u.mds.mds_osc_conn, lsm,
-                                    mlcd->mlcd_cookielen /
-                                    sizeof(*mlcd->mlcd_cookies),
-                                    mlcd->mlcd_cookies, OBD_LLOG_FL_SENDNOW);
+#ifdef ENABLE_ORPHANS
                 ///* XXX 0 normally, SENDNOW for debug */);
+                ctxt = llog_get_context(obd, mlcd->mlcd_cookies[0].lgc_subsys + 1);
+                rc = llog_cancel(ctxt, lsm,
+                                         mlcd->mlcd_cookielen /
+                                         sizeof(*mlcd->mlcd_cookies),
+                                         mlcd->mlcd_cookies, OBD_LLOG_FL_SENDNOW);
                 if (rc)
                         CERROR("error cancelling %d log cookies: rc %d\n",
                                (int)(mlcd->mlcd_cookielen /
                                      sizeof(*mlcd->mlcd_cookies)), rc);
+#endif
         }
 
         OBD_FREE(mlcd, mlcd->mlcd_size);
@@ -131,7 +106,7 @@ int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,
         int err;
         __u64 transno;
         loff_t off;
-        ssize_t written;
+        int log_pri = D_HA;
         ENTRY;
 
         /* if the export has already been failed, we have no last_rcvd slot */
@@ -139,16 +114,19 @@ int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,
                 CERROR("committing transaction for disconnected client\n");
                 if (handle)
                         GOTO(commit, rc);
-                GOTO(out, rc);
+                RETURN(rc);
         }
 
-        if (!handle) {
+        if (IS_ERR(handle))
+                RETURN(rc);
+
+        if (handle == NULL) {
                 /* if we're starting our own xaction, use our own inode */
                 inode = mds->mds_rcvd_filp->f_dentry->d_inode;
                 handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
                 if (IS_ERR(handle)) {
                         CERROR("fsfilt_start: %ld\n", PTR_ERR(handle));
-                        GOTO(out, rc = PTR_ERR(handle));
+                        RETURN(PTR_ERR(handle));
                 }
         }
 
@@ -159,6 +137,11 @@ int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,
                 spin_lock(&mds->mds_transno_lock);
                 transno = ++mds->mds_last_transno;
                 spin_unlock(&mds->mds_transno_lock);
+        } else {
+                spin_lock(&mds->mds_transno_lock);
+                if (transno > mds->mds_last_transno)
+                        mds->mds_last_transno = transno;
+                spin_unlock(&mds->mds_transno_lock);
         }
         req->rq_repmsg->transno = req->rq_transno = transno;
         mcd->mcd_last_transno = cpu_to_le64(transno);
@@ -167,22 +150,28 @@ int mds_finish_transno(struct mds_obd *mds, struct inode *inode, void *handle,
         mcd->mcd_last_result = cpu_to_le32(rc);
         mcd->mcd_last_data = cpu_to_le32(op_data);
 
-        fsfilt_set_last_rcvd(req->rq_export->exp_obd, transno, handle,
-                             mds_commit_cb, NULL);
-        written = fsfilt_write_record(obd, mds->mds_rcvd_filp,
-                                      mcd, sizeof(*mcd), &off);
-        CDEBUG(D_INODE, "wrote trans "LPU64" client %s at idx %u: written = "
-               LPSZ"\n", transno, mcd->mcd_uuid, med->med_idx, written);
-
-        if (written != sizeof(*mcd)) {
-                CERROR("error writing to last_rcvd: rc = "LPSZ"\n", written);
-                if (rc == 0) {
-                        if (written < 0)
-                                rc = written;
-                        else
-                                rc = -EIO;
-                }
+        fsfilt_add_journal_cb(req->rq_export->exp_obd, transno, handle,
+                              mds_commit_cb, NULL);
+        err = fsfilt_write_record(obd, mds->mds_rcvd_filp, mcd, sizeof(*mcd),
+                                  &off, 0);
+
+        if (err) {
+                log_pri = D_ERROR;
+                if (rc == 0)
+                        rc = err;
+        }
+
+        DEBUG_REQ(log_pri, req,
+                  "wrote trans #"LPU64" client %s at idx %u: err = %d\n",
+                  transno, mcd->mcd_uuid, med->med_idx, err);
+
+        err = mds_lov_write_objids(obd);
+        if (err) {
+                log_pri = D_ERROR;
+                if (rc == 0)
+                        rc = err;
         }
+        CDEBUG(log_pri, "wrote objids: err = %d\n", err);
 
 commit:
         err = fsfilt_commit(obd, inode, handle, 0);
@@ -192,9 +181,7 @@ commit:
                         rc = err;
         }
 
-        EXIT;
- out:
-        return rc;
+        RETURN(rc);
 }
 
 /* this gives the same functionality as the code between
@@ -225,14 +212,14 @@ int mds_fix_attr(struct inode *inode, struct mds_update_record *rec)
                 RETURN(-EPERM);
 
         /* times */
-        if ((ia_valid & (ATTR_MTIME|ATTR_ATIME))==(ATTR_MTIME|ATTR_ATIME)) {
+        if ((ia_valid & (ATTR_MTIME|ATTR_ATIME)) == (ATTR_MTIME|ATTR_ATIME)) {
                 if (rec->ur_fsuid != inode->i_uid &&
-                    (error = permission(inode,MAY_WRITE)) != 0)
+                    (error = ll_permission(inode, MAY_WRITE, NULL)) != 0)
                         RETURN(error);
         }
 
         if (ia_valid & ATTR_SIZE) {
-                if ((error = permission(inode,MAY_WRITE)) != 0)
+                if ((error = ll_permission(inode, MAY_WRITE, NULL)) != 0)
                         RETURN(error);
         }
 
@@ -288,17 +275,26 @@ int mds_fix_attr(struct inode *inode, struct mds_update_record *rec)
         RETURN(0);
 }
 
+void mds_req_from_mcd(struct ptlrpc_request *req, struct mds_client_data *mcd)
+{
+        DEBUG_REQ(D_HA, req, "restoring transno "LPD64"/status %d",
+                  mcd->mcd_last_transno, mcd->mcd_last_result);
+        req->rq_repmsg->transno = req->rq_transno = mcd->mcd_last_transno;
+        req->rq_repmsg->status = req->rq_status = mcd->mcd_last_result;
+
+        if (req->rq_export->exp_outstanding_reply)
+                mds_steal_ack_locks(req->rq_export, req);
+}
+
 static void reconstruct_reint_setattr(struct mds_update_record *rec,
                                       int offset, struct ptlrpc_request *req)
 {
         struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
         struct mds_obd *obd = &req->rq_export->exp_obd->u.mds;
         struct dentry *de;
         struct mds_body *body;
 
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
+        mds_req_from_mcd(req, med->med_mcd);
 
         if (req->rq_export->exp_outstanding_reply)
                 mds_steal_ack_locks(req->rq_export, req);
@@ -354,7 +350,7 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
                         GOTO(cleanup, rc = PTR_ERR(de));
         } else {
                 de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW,
-                                           &lockh);
+                                           &lockh, NULL, 0);
                 if (IS_ERR(de))
                         GOTO(cleanup, rc = PTR_ERR(de));
                 locked = 1;
@@ -363,23 +359,15 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
         cleanup_phase = 1;
         inode = de->d_inode;
         LASSERT(inode);
+        if (S_ISREG(inode->i_mode) && rec->ur_eadata != NULL)
+                down(&inode->i_sem);
 
         CDEBUG(D_INODE, "ino %lu\n", inode->i_ino);
-
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE,
-                       to_kdev_t(inode->i_sb->s_dev));
-
-#ifdef ENABLE_ORPHANS
-        if (unlikely(mds->mds_osc_obd == NULL))
-                mds_osc_connect(obd, mds);
-#endif
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE, inode->i_sb);
 
         handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
-        if (IS_ERR(handle)) {
-                rc = PTR_ERR(handle);
-                handle = NULL;
-                GOTO(cleanup, rc);
-        }
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
 
         if (rec->ur_iattr.ia_valid & (ATTR_MTIME | ATTR_CTIME))
                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n",
@@ -389,7 +377,12 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
         if (rc)
                 GOTO(cleanup, rc);
 
-        rc = fsfilt_setattr(obd, de, handle, &rec->ur_iattr, 0);
+        if (rec->ur_iattr.ia_valid & ATTR_ATTR_FLAG)    /* ioctl */
+                rc = fsfilt_iocontrol(obd, inode, NULL, EXT3_IOC_SETFLAGS,
+                                      (long)&rec->ur_iattr.ia_attr_flags);
+        else                                            /* setattr */
+                rc = fsfilt_setattr(obd, de, handle, &rec->ur_iattr, 0);
+
         if (rc == 0 && S_ISREG(inode->i_mode) && rec->ur_eadata != NULL) {
                 rc = fsfilt_set_md(obd, inode, handle,
                                    rec->ur_eadata, rec->ur_eadatalen);
@@ -428,19 +421,19 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
         EXIT;
  cleanup:
         if (mlcd != NULL)
-                fsfilt_set_last_rcvd(req->rq_export->exp_obd, 0, handle,
-                                     mds_cancel_cookies_cb, mlcd);
+                fsfilt_add_journal_cb(req->rq_export->exp_obd, 0, handle,
+                                      mds_cancel_cookies_cb, mlcd);
         err = mds_finish_transno(mds, inode, handle, req, rc, 0);
         switch (cleanup_phase) {
         case 1:
+                if (S_ISREG(inode->i_mode) && rec->ur_eadata != NULL)
+                        down(&inode->i_sem);
                 l_dput(de);
                 if (locked) {
                         if (rc) {
                                 ldlm_lock_decref(&lockh, LCK_PW);
                         } else {
-                                memcpy(&req->rq_ack_locks[0].lock, &lockh,
-                                       sizeof(lockh));
-                                req->rq_ack_locks[0].mode = LCK_PW;
+                                ldlm_put_lock_into_req(req, &lockh, LCK_PW);
                         }
                 }
         case 0:
@@ -459,16 +452,11 @@ static void reconstruct_reint_create(struct mds_update_record *rec, int offset,
                                      struct ptlrpc_request *req)
 {
         struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
         struct mds_obd *obd = &req->rq_export->exp_obd->u.mds;
         struct dentry *parent, *child;
         struct mds_body *body;
 
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
-
-        if (req->rq_export->exp_outstanding_reply)
-                mds_steal_ack_locks(req->rq_export, req);
+        mds_req_from_mcd(req, med->med_mcd);
 
         if (req->rq_status)
                 return;
@@ -488,7 +476,7 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
                             struct ptlrpc_request *req,
                             struct lustre_handle *lh)
 {
-        struct dentry *de = NULL;
+        struct dentry *dparent = NULL;
         struct mds_obd *mds = mds_req2mds(req);
         struct obd_device *obd = req->rq_export->exp_obd;
         struct dentry *dchild = NULL;
@@ -497,6 +485,7 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
         struct lustre_handle lockh;
         int rc = 0, err, type = rec->ur_mode & S_IFMT, cleanup_phase = 0;
         int created = 0;
+        struct dentry_params dp;
         ENTRY;
 
         LASSERT(offset == 0);
@@ -507,21 +496,22 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE))
                 GOTO(cleanup, rc = -ESTALE);
 
-        de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW, &lockh);
-        if (IS_ERR(de)) {
-                rc = PTR_ERR(de);
+        dparent = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW, &lockh,
+                                        rec->ur_name, rec->ur_namelen - 1);
+        if (IS_ERR(dparent)) {
+                rc = PTR_ERR(dparent);
                 CERROR("parent lookup error %d\n", rc);
                 GOTO(cleanup, rc);
         }
         cleanup_phase = 1; /* locked parent dentry */
-        dir = de->d_inode;
+        dir = dparent->d_inode;
         LASSERT(dir);
         CDEBUG(D_INODE, "parent ino %lu creating name %s mode %o\n",
                dir->i_ino, rec->ur_name, rec->ur_mode);
 
         ldlm_lock_dump_handle(D_OTHER, &lockh);
 
-        dchild = ll_lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
+        dchild = ll_lookup_one_len(rec->ur_name, dparent, rec->ur_namelen - 1);
         if (IS_ERR(dchild)) {
                 rc = PTR_ERR(dchild);
                 CERROR("child lookup error %d\n", rc);
@@ -530,24 +520,23 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
 
         cleanup_phase = 2; /* child dentry */
 
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE,
-                       to_kdev_t(dir->i_sb->s_dev));
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE, dir->i_sb);
 
         if (dir->i_mode & S_ISGID) {
-                rec->ur_gid = dir->i_gid;
                 if (S_ISDIR(rec->ur_mode))
                         rec->ur_mode |= S_ISGID;
         }
 
-        if (rec->ur_fid2->id)
-                dchild->d_fsdata = (void *)(unsigned long)rec->ur_fid2->id;
+        dchild->d_fsdata = (void *)&dp;
+        dp.p_inum = (unsigned long)rec->ur_fid2->id;
+        dp.p_ptr = req;
 
         switch (type) {
         case S_IFREG:{
                 handle = fsfilt_start(obd, dir, FSFILT_OP_CREATE, NULL);
                 if (IS_ERR(handle))
                         GOTO(cleanup, rc = PTR_ERR(handle));
-                rc = vfs_create(dir, dchild, rec->ur_mode);
+                rc = ll_vfs_create(dir, dchild, rec->ur_mode, NULL);
                 EXIT;
                 break;
         }
@@ -604,8 +593,11 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
                 LTIME_S(iattr.ia_atime) = rec->ur_time;
                 LTIME_S(iattr.ia_ctime) = rec->ur_time;
                 LTIME_S(iattr.ia_mtime) = rec->ur_time;
-                iattr.ia_uid = rec->ur_uid;
-                iattr.ia_gid = rec->ur_gid;
+                iattr.ia_uid = rec->ur_fsuid;
+                if (dir->i_mode & S_ISGID)
+                        iattr.ia_gid = dir->i_gid;
+                else
+                        iattr.ia_gid = rec->ur_fsgid;
                 iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME |
                         ATTR_MTIME | ATTR_CTIME;
 
@@ -613,18 +605,45 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
                         LASSERT(rec->ur_fid2->id == inode->i_ino);
                         inode->i_generation = rec->ur_fid2->generation;
                         /* Dirtied and committed by the upcoming setattr. */
-                        CDEBUG(D_INODE, "recreated ino %lu with gen %x\n",
+                        CDEBUG(D_INODE, "recreated ino %lu with gen %u\n",
                                inode->i_ino, inode->i_generation);
                 } else {
+                        struct lustre_handle child_ino_lockh;
+                        struct ldlm_res_id child_res_id =
+                             { .name = { inode->i_ino, 0 } };
+                        int lock_flags = 0;
+
                         CDEBUG(D_INODE, "created ino %lu with gen %x\n",
                                inode->i_ino, inode->i_generation);
+
+                        /* The inode we were allocated may have just been freed
+                         * by an unlink operation.  We take this lock to
+                         * synchronize against the matching reply-ack-lock taken
+                         * in unlink, to avoid replay problems if this reply
+                         * makes it out to the client but the unlink's does not.
+                         * See bug 2029 for more detail.*/
+                        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace,
+                                              NULL, child_res_id, LDLM_PLAIN,
+                                              NULL, 0, LCK_EX, &lock_flags,
+                                              ldlm_completion_ast,
+                                              mds_blocking_ast, NULL,
+                                              &child_ino_lockh);
+                        if (rc != ELDLM_OK) {
+                                CERROR("error locking for unlink/create sync: "
+                                       "%d\n", rc);
+                        } else {
+                                ldlm_lock_decref(&child_ino_lockh, LCK_EX);
+                        }
                 }
 
                 rc = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
-                if (rc) {
-                        CERROR("error on setattr: rc = %d\n", rc);
-                        /* XXX should we abort here in case of error? */
-                }
+                if (rc)
+                        CERROR("error on child setattr: rc = %d\n", rc);
+
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt_setattr(obd, dparent, handle, &iattr, 0);
+                if (rc)
+                        CERROR("error on parent setattr: rc = %d\n", rc);
 
                 body = lustre_msg_buf(req->rq_repmsg, offset, sizeof (*body));
                 mds_pack_inode2fid(&body->fid1, inode);
@@ -663,11 +682,9 @@ cleanup:
                 if (rc) {
                         ldlm_lock_decref(&lockh, LCK_PW);
                 } else {
-                        memcpy(&req->rq_ack_locks[0].lock, &lockh,
-                               sizeof(lockh));
-                        req->rq_ack_locks[0].mode = LCK_PW;
+                        ldlm_put_lock_into_req(req, &lockh, LCK_PW);
                 }
-                l_dput(de);
+                l_dput(dparent);
         case 0:
                 break;
         default:
@@ -742,114 +759,11 @@ int enqueue_ordered_locks(int lock_mode, struct obd_device *obd,
         RETURN(0);
 }
 
-static void reconstruct_reint_unlink(struct mds_update_record *rec, int offset,
-                                    struct ptlrpc_request *req,
-                                    struct lustre_handle *child_lockh)
+void mds_reconstruct_generic(struct ptlrpc_request *req)
 {
         struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
-
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
-
-        if (req->rq_export->exp_outstanding_reply)
-                mds_steal_ack_locks(req->rq_export, req);
-
-        DEBUG_REQ(D_ERROR, req,
-                  "can't get EA for reconstructed unlink, leaking OST inodes");
-}
-
-/* If we are unlinking an open file/dir (i.e. creating an orphan) then
- * we instead link the inode into the PENDING directory until it is
- * finally released.  We can't simply call mds_reint_rename() or some
- * part thereof, because we don't have the inode to check for link
- * count/open status until after it is locked.
- *
- * For lock ordering, we always get the PENDING, then pending_child lock
- * last to avoid deadlocks.
- */
-static int mds_unlink_orphan(struct mds_update_record *rec,
-                             struct obd_device *obd, struct dentry *dparent,
-                             struct dentry *dchild, void **handle)
-{
-        struct mds_obd *mds = &obd->u.mds;
-        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
-        struct dentry *pending_child;
-        char fidname[LL_FID_NAMELEN];
-        int fidlen = 0, rc;
-        ENTRY;
-
-        LASSERT(!mds_inode_is_orphan(dchild->d_inode));
-
-        down(&pending_dir->i_sem);
-        fidlen = ll_fid2str(fidname, dchild->d_inode->i_ino,
-                            dchild->d_inode->i_generation);
-
-        CDEBUG(D_ERROR, "pending destroy of %dx open file %s = %s\n",
-               mds_open_orphan_count(dchild->d_inode),
-               rec->ur_name, fidname);
-
-        pending_child = lookup_one_len(fidname, mds->mds_pending_dir, fidlen);
-        if (IS_ERR(pending_child))
-                GOTO(out_lock, rc = PTR_ERR(pending_child));
-
-        if (pending_child->d_inode != NULL) {
-                CERROR("re-destroying orphan file %s?\n", rec->ur_name);
-                LASSERT(pending_child->d_inode == dchild->d_inode);
-                GOTO(out_dput, rc = 0);
-        }
 
-        *handle = fsfilt_start(obd, pending_dir, FSFILT_OP_RENAME, NULL);
-        if (IS_ERR(*handle))
-                GOTO(out_dput, rc = PTR_ERR(*handle));
-
-        rc = vfs_rename(dparent->d_inode, dchild, pending_dir, pending_child);
-        if (rc)
-                CERROR("error renaming orphan %lu/%s to PENDING: rc = %d\n",
-                       dparent->d_inode->i_ino, rec->ur_name, rc);
-        else
-                mds_inode_set_orphan(dchild->d_inode);
-out_dput:
-        dput(pending_child);
-out_lock:
-        up(&pending_dir->i_sem);
-        RETURN(rc);
-}
-
-static int mds_log_op_unlink(struct obd_device *obd, struct mds_obd *mds,
-                             struct inode *inode, struct lustre_msg *repmsg,
-                             int offset)
-{
-        struct lov_stripe_md *lsm = NULL;
-        struct llog_unlink_rec *lur;
-        int rc;
-        ENTRY;
-
-        if (IS_ERR(mds->mds_osc_obd))
-                RETURN(PTR_ERR(mds->mds_osc_obd));
-
-        rc = obd_unpackmd(&mds->mds_osc_conn, &lsm,
-                          lustre_msg_buf(repmsg, offset, 0),
-                          repmsg->buflens[offset]);
-        if (rc < 0)
-                RETURN(rc);
-
-        OBD_ALLOC(lur, sizeof(*lur));
-        if (!lur)
-                RETURN(-ENOMEM);
-        lur->lur_hdr.lth_len = lur->lur_end_len = sizeof(*lur);
-        lur->lur_hdr.lth_type = MDS_UNLINK_REC;
-        lur->lur_oid = inode->i_ino;
-        lur->lur_ogen = inode->i_generation;
-
-        rc = obd_log_add(&mds->mds_osc_conn, mds->mds_catalog, &lur->lur_hdr,
-                         lsm, lustre_msg_buf(repmsg, offset + 1, 0),
-                         repmsg->buflens[offset+1]/sizeof(struct llog_cookie));
-
-        obd_free_memmd(&mds->mds_osc_conn, &lsm);
-        OBD_FREE(lur, sizeof(*lur));
-
-        RETURN(rc);
+        mds_req_from_mcd(req, med->med_mcd);
 }
 
 static int mds_reint_unlink(struct mds_update_record *rec, int offset,
@@ -862,7 +776,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
         struct obd_device *obd = req->rq_export->exp_obd;
         struct mds_body *body = NULL;
         struct inode *child_inode;
-        struct lustre_handle parent_lockh, child_lockh;
+        struct lustre_handle parent_lockh, child_lockh, child_reuse_lockh;
         void *handle = NULL;
         struct ldlm_res_id child_res_id = { .name = {0} };
         int rc = 0, flags = 0, log_unlink = 0, cleanup_phase = 0;
@@ -870,15 +784,15 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
 
         LASSERT(offset == 0 || offset == 2);
 
-        MDS_CHECK_RESENT(req, reconstruct_reint_unlink(rec, offset, req,
-                                                       &child_lockh));
+        MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
 
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK))
                 GOTO(cleanup, rc = -ENOENT);
 
         /* Step 1: Lookup the parent by FID */
         dparent = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PW,
-                                        &parent_lockh);
+                                        &parent_lockh, rec->ur_name,
+                                        rec->ur_namelen - 1);
         if (IS_ERR(dparent))
                 GOTO(cleanup, rc = PTR_ERR(dparent));
         LASSERT(dparent->d_inode);
@@ -915,8 +829,20 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
 
         cleanup_phase = 3; /* child lock */
 
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE,
-                       to_kdev_t(dparent->d_inode->i_sb->s_dev));
+        /* Step 4: Get a lock on the ino to sync with creation WRT inode
+         * reuse (see bug 2029). */
+        child_res_id.name[1] = 0;
+        
+        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
+                              child_res_id, LDLM_PLAIN, NULL, 0, LCK_EX,
+                              &flags, ldlm_completion_ast, mds_blocking_ast,
+                              NULL, &child_reuse_lockh);
+        if (rc != ELDLM_OK)
+                GOTO(cleanup, rc);
+
+        cleanup_phase = 4; /* child lock */
+        
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE, dparent->d_inode->i_sb);
 
         /* ldlm_reply in buf[0] if called via intent */
         if (offset)
@@ -925,20 +851,21 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
         body = lustre_msg_buf(req->rq_repmsg, offset, sizeof (*body));
         LASSERT(body != NULL);
 
-#ifdef ENABLE_ORPHANS
-        if (unlikely(mds->mds_osc_obd == NULL))
-                mds_osc_connect(obd, mds);
-#endif
-
         /* If this is the last reference to this inode, get the OBD EA
-         * data first so the client can destroy OST objects */
-        if (S_ISREG(child_inode->i_mode) && child_inode->i_nlink == 1) {
+         * data first so the client can destroy OST objects. 
+         * we only do the object removal if no open files remain.
+         * Nobody can get at this name anymore because of the locks so 
+         * we make decisions here as to whether to remove the inode */
+        if (S_ISREG(child_inode->i_mode) && child_inode->i_nlink == 1 && 
+            mds_open_orphan_count(child_inode) == 0) {
                 mds_pack_inode2fid(&body->fid1, child_inode);
                 mds_pack_inode2body(body, child_inode);
-                mds_pack_md(obd, req->rq_repmsg, offset + 1, body, child_inode);
+                mds_pack_md(obd, req->rq_repmsg, offset + 1, body,
+                            child_inode, 1);
                 if (!(body->valid & OBD_MD_FLEASIZE)) {
                         body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
                                         OBD_MD_FLATIME | OBD_MD_FLMTIME);
+                } else {
                         log_unlink = 1;
                 }
         }
@@ -948,7 +875,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
          * so we need to return appropriate errors (bug 72).
          *
          * We don't have to check permissions, because vfs_rename (called from
-         * mds_unlink_orphan) also calls may_delete. */
+         * mds_open_unlink_rename) also calls may_delete. */
         if ((rec->ur_mode & S_IFMT) == S_IFDIR) {
                 if (!S_ISDIR(child_inode->i_mode))
                         GOTO(cleanup, rc = -ENOTDIR);
@@ -957,18 +884,15 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                         GOTO(cleanup, rc = -EISDIR);
         }
 
-        if (mds_open_orphan_count(child_inode) > 0) {
-                rc = mds_unlink_orphan(rec, obd, dparent, dchild, &handle);
-#ifdef ENABLE_ORPHANS
-                if (!rc && mds_log_op_unlink(obd, mds, child_inode,
-                                             req->rq_repmsg, offset + 1) > 0)
-                        body->valid |= OBD_MD_FLCOOKIE;
-#endif
+        if (child_inode->i_nlink == (S_ISDIR(child_inode->i_mode) ? 2 : 1) &&
+            mds_open_orphan_count(child_inode) > 0) {
+                rc = mds_open_unlink_rename(rec, obd, dparent, dchild, &handle);
+                cleanup_phase = 5; /* transaction */
                 GOTO(cleanup, rc);
         }
 
-        // Step 4: Do the unlink: client decides between rmdir/unlink! (bug 72)
-        switch (rec->ur_mode & S_IFMT) {
+        /* Step 4: Do the unlink: we already verified ur_mode above (bug 72) */
+        switch (child_inode->i_mode & S_IFMT) {
         case S_IFDIR:
                 /* Drop any lingering child directories before we start our
                  * transaction, to avoid doing multiple inode dirty/delete
@@ -978,7 +902,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                                       NULL);
                 if (IS_ERR(handle))
                         GOTO(cleanup, rc = PTR_ERR(handle));
-                cleanup_phase = 4;
+                cleanup_phase = 5; /* transaction */
                 rc = vfs_rmdir(dparent->d_inode, dchild);
                 break;
         case S_IFREG: {
@@ -987,12 +911,14 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                 if (IS_ERR(handle))
                         GOTO(cleanup, rc = PTR_ERR(handle));
 
-                cleanup_phase = 4;
+                cleanup_phase = 5; /* transaction */
                 rc = vfs_unlink(dparent->d_inode, dchild);
+
 #ifdef ENABLE_ORPHANS
+
                 if (!rc && log_unlink)
-                        if (mds_log_op_unlink(obd, mds, child_inode,
-                                              req->rq_repmsg, offset + 1) > 0)
+                        if (mds_log_op_unlink(obd, child_inode, req->rq_repmsg,
+                                              offset + 1) > 0)
                                 body->valid |= OBD_MD_FLCOOKIE;
 #endif
                 break;
@@ -1006,7 +932,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                                       NULL);
                 if (IS_ERR(handle))
                         GOTO(cleanup, rc = PTR_ERR(handle));
-                cleanup_phase = 4;
+                cleanup_phase = 5;
                 rc = vfs_unlink(dparent->d_inode, dchild);
                 break;
         default:
@@ -1017,14 +943,35 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
         }
 
  cleanup:
+        if (rc == 0) {
+                struct iattr iattr;
+                int err;
+
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+
+                err = fsfilt_setattr(obd, dparent, handle, &iattr, 0);
+                if (err)
+                        CERROR("error on parent setattr: rc = %d\n", err);
+        }
+
         switch(cleanup_phase) {
-        case 4:
+        case 5:
                 rc = mds_finish_transno(mds, dparent->d_inode, handle, req,
                                         rc, 0);
+                if (!rc)
+                        (void)obd_set_info(mds->mds_osc_exp, strlen("unlinked"),
+                                           "unlinked", 0, NULL);
+        case 4: /* child ino-reuse lock */
                 if (rc && body != NULL) {
                         // Don't unlink the OST objects if the MDS unlink failed
                         body->valid = 0;
                 }
+                if (rc)
+                        ldlm_lock_decref(&child_reuse_lockh, LCK_EX);
+                else
+                        ldlm_put_lock_into_req(req, &child_reuse_lockh, LCK_EX);
         case 3: /* child lock */
                 ldlm_lock_decref(&child_lockh, LCK_EX);
         case 2: /* child dentry */
@@ -1033,9 +980,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                 if (rc) {
                         ldlm_lock_decref(&parent_lockh, LCK_PW);
                 } else {
-                        memcpy(&req->rq_ack_locks[0].lock, &parent_lockh,
-                               sizeof(parent_lockh));
-                        req->rq_ack_locks[0].mode = LCK_PW;
+                        ldlm_put_lock_into_req(req, &parent_lockh, LCK_PW);
                 }
                 l_dput(dparent);
         case 0:
@@ -1048,19 +993,6 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
         return 0;
 }
 
-static void reconstruct_reint_link(struct mds_update_record *rec, int offset,
-                                   struct ptlrpc_request *req)
-{
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
-
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
-
-        if (req->rq_export->exp_outstanding_reply)
-                mds_steal_ack_locks(req->rq_export, req);
-}
-
 static int mds_reint_link(struct mds_update_record *rec, int offset,
                           struct ptlrpc_request *req,
                           struct lustre_handle *lh)
@@ -1078,7 +1010,7 @@ static int mds_reint_link(struct mds_update_record *rec, int offset,
 
         LASSERT(offset == 0);
 
-        MDS_CHECK_RESENT(req, reconstruct_reint_link(rec, offset, req));
+        MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
 
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_LINK))
                 GOTO(cleanup, rc = -ENOENT);
@@ -1133,8 +1065,7 @@ static int mds_reint_link(struct mds_update_record *rec, int offset,
         }
 
         /* Step 4: Do it. */
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE,
-                       to_kdev_t(de_src->d_inode->i_sb->s_dev));
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE, de_src->d_inode->i_sb);
 
         handle = fsfilt_start(obd, de_tgt_dir->d_inode, FSFILT_OP_LINK, NULL);
         if (IS_ERR(handle)) {
@@ -1158,12 +1089,8 @@ cleanup:
                         ldlm_lock_decref(&src_lockh, lock_mode);
                         ldlm_lock_decref(&tgt_dir_lockh, lock_mode);
                 } else {
-                        memcpy(&req->rq_ack_locks[0].lock, &src_lockh,
-                               sizeof(src_lockh));
-                        memcpy(&req->rq_ack_locks[1].lock, &tgt_dir_lockh,
-                               sizeof(tgt_dir_lockh));
-                        req->rq_ack_locks[0].mode = lock_mode;
-                        req->rq_ack_locks[1].mode = lock_mode;
+                        ldlm_put_lock_into_req(req, &src_lockh, lock_mode);
+                        ldlm_put_lock_into_req(req, &tgt_dir_lockh, lock_mode);
                 }
         case 2: /* target dentry */
                 l_dput(de_tgt_dir);
@@ -1179,20 +1106,54 @@ cleanup:
         return 0;
 }
 
-static void reconstruct_reint_rename(struct mds_update_record *rec,
-                                     int offset, struct ptlrpc_request *req)
+/*
+ * add a hard link in the PENDING directory, only used by rename()
+ */
+static int mds_add_link_orphan(struct mds_update_record *rec,
+                               struct obd_device *obd,
+                               struct dentry *dentry)
 {
-        struct mds_export_data *med = &req->rq_export->exp_mds_data;
-        struct mds_client_data *mcd = med->med_mcd;
+        struct mds_obd *mds = &obd->u.mds;
+        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
+        struct dentry *pending_child;
+        char fidname[LL_FID_NAMELEN];
+        int fidlen = 0, rc;
+        ENTRY;
 
-        req->rq_transno = mcd->mcd_last_transno;
-        req->rq_status = mcd->mcd_last_result;
+        LASSERT(dentry->d_inode);
+        LASSERT(!mds_inode_is_orphan(dentry->d_inode));
 
-        if (req->rq_export->exp_outstanding_reply)
-                mds_steal_ack_locks(req->rq_export, req);
-        else
-                LBUG(); /* don't support it yet, but it'll be fun! */
+        down(&pending_dir->i_sem);
+        fidlen = ll_fid2str(fidname, dentry->d_inode->i_ino,
+                            dentry->d_inode->i_generation);
 
+        CDEBUG(D_ERROR, "pending destroy of %dx open file %s = %s\n",
+               mds_open_orphan_count(dentry->d_inode),
+               rec->ur_name, fidname);
+
+        pending_child = lookup_one_len(fidname, mds->mds_pending_dir, fidlen);
+        if (IS_ERR(pending_child))
+                GOTO(out_lock, rc = PTR_ERR(pending_child));
+
+        if (pending_child->d_inode != NULL) {
+                CERROR("re-destroying orphan file %s?\n", rec->ur_name);
+                LASSERT(pending_child->d_inode == dentry->d_inode);
+                GOTO(out_dput, rc = 0);
+        }
+
+        lock_kernel();
+        rc = vfs_link(dentry, pending_dir, pending_child);
+        unlock_kernel();
+        if (rc)
+                CERROR("error addlink orphan %s to PENDING: rc = %d\n",
+                       rec->ur_name, rc);
+        else
+                mds_inode_set_orphan(dentry->d_inode);
+out_dput:
+        l_dput(pending_child);
+out_lock:
+        up(&pending_dir->i_sem);
+        RETURN(rc);
 }
 
 static int mds_reint_rename(struct mds_update_record *rec, int offset,
@@ -1210,6 +1171,7 @@ static int mds_reint_rename(struct mds_update_record *rec, int offset,
         struct ldlm_res_id p2_res_id = { .name = {0} };
         struct ldlm_res_id c1_res_id = { .name = {0} };
         struct ldlm_res_id c2_res_id = { .name = {0} };
+        struct mds_body *body = NULL;
         int rc = 0, lock_count = 3, flags = LDLM_FL_LOCAL_ONLY;
         int cleanup_phase = 0;
         void *handle = NULL;
@@ -1217,7 +1179,7 @@ static int mds_reint_rename(struct mds_update_record *rec, int offset,
 
         LASSERT(offset == 0);
 
-        MDS_CHECK_RESENT(req, reconstruct_reint_rename(rec, offset, req));
+        MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
 
         de_srcdir = mds_fid2dentry(mds, rec->ur_fid1, NULL);
         if (IS_ERR(de_srcdir))
@@ -1315,15 +1277,48 @@ static int mds_reint_rename(struct mds_update_record *rec, int offset,
 
         cleanup_phase = 6; /* child locks */
 
+        /* if we are about to remove the target at first, pass the EA of
+         * that inode to client to perform and cleanup on OST */
+        body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
+        LASSERT(body != NULL);
+
+        if (de_new->d_inode &&
+            S_ISREG(de_new->d_inode->i_mode) &&
+            de_new->d_inode->i_nlink == 1 &&
+            mds_open_orphan_count(de_new->d_inode) == 0) {
+                mds_pack_inode2fid(&body->fid1, de_new->d_inode);
+                mds_pack_inode2body(body, de_new->d_inode);
+                mds_pack_md(obd, req->rq_repmsg, 1, body, de_new->d_inode, 1);
+                if (!(body->valid & OBD_MD_FLEASIZE)) {
+                        body->valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS |
+                                        OBD_MD_FLATIME | OBD_MD_FLMTIME);
+                } else {
+                        /* XXX need log unlink? */
+                }
+        }
+
         /* Step 4: Execute the rename */
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE,
-                       to_kdev_t(de_srcdir->d_inode->i_sb->s_dev));
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE,de_srcdir->d_inode->i_sb);
 
         handle = fsfilt_start(obd, de_tgtdir->d_inode, FSFILT_OP_RENAME, NULL);
         if (IS_ERR(handle))
                 GOTO(cleanup, rc = PTR_ERR(handle));
 
+        /* FIXME need adjust the journal block count? */
+        /* if the target should be moved to PENDING, we at first increase the
+         * link and later vfs_rename() will decrease the link count again */
+        if (de_new->d_inode &&
+            S_ISREG(de_new->d_inode->i_mode) &&
+            de_new->d_inode->i_nlink == 1 &&
+            mds_open_orphan_count(de_new->d_inode) > 0) {
+                rc = mds_add_link_orphan(rec, obd, de_new);
+                if (rc)
+                        GOTO(cleanup, rc);
+        }
+
         lock_kernel();
+        de_old->d_fsdata = req;
+        de_new->d_fsdata = req;
         rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new);
         unlock_kernel();
 
@@ -1338,14 +1333,10 @@ cleanup:
                         if (lock_count == 4)
                                 ldlm_lock_decref(&(dlm_handles[3]), LCK_EX);
                 } else {
-                        memcpy(&req->rq_ack_locks[2].lock, &(dlm_handles[2]),
-                               sizeof(dlm_handles[2]));
-                        req->rq_ack_locks[2].mode = LCK_EX;
-                        if (lock_count == 4) {
-                                memcpy(&req->rq_ack_locks[3].lock,
-                                       &dlm_handles[3], sizeof(dlm_handles[3]));
-                                req->rq_ack_locks[3].mode = LCK_EX;
-                        }
+                        ldlm_put_lock_into_req(req, &(dlm_handles[2]), LCK_EX);
+                        if (lock_count == 4)
+                                ldlm_put_lock_into_req(req,
+                                                &(dlm_handles[3]), LCK_EX);
                 }
         case 5: /* target dentry */
                 l_dput(de_new);
@@ -1356,12 +1347,8 @@ cleanup:
                         ldlm_lock_decref(&(dlm_handles[0]), LCK_EX);
                         ldlm_lock_decref(&(dlm_handles[1]), LCK_EX);
                 } else {
-                        memcpy(&req->rq_ack_locks[0].lock, &(dlm_handles[0]),
-                               sizeof(dlm_handles[0]));
-                        memcpy(&req->rq_ack_locks[1].lock, &(dlm_handles[1]),
-                               sizeof(dlm_handles[1]));
-                        req->rq_ack_locks[0].mode = LCK_EX;
-                        req->rq_ack_locks[1].mode = LCK_EX;
+                        ldlm_put_lock_into_req(req, &(dlm_handles[0]), LCK_EX);
+                        ldlm_put_lock_into_req(req, &(dlm_handles[1]), LCK_EX);
                 }
         case 2: /* target directory dentry */
                 l_dput(de_tgtdir);
@@ -1392,7 +1379,7 @@ static mds_reinter reinters[REINT_MAX + 1] = {
 int mds_reint_rec(struct mds_update_record *rec, int offset,
                   struct ptlrpc_request *req, struct lustre_handle *lockh)
 {
-        struct mds_obd *mds = mds_req2mds(req);
+        struct obd_device *obd = req->rq_export->exp_obd;
         struct obd_run_ctxt saved;
         int rc;
         ENTRY;
@@ -1401,9 +1388,9 @@ int mds_reint_rec(struct mds_update_record *rec, int offset,
         LASSERT(rec->ur_opcode <= REINT_MAX &&
                 reinters[rec->ur_opcode] != NULL);
 
-        push_ctxt(&saved, &mds->mds_ctxt, &rec->ur_uc);
+        push_ctxt(&saved, &obd->obd_ctxt, &rec->ur_uc);
         rc = reinters[rec->ur_opcode] (rec, offset, req, lockh);
-        pop_ctxt(&saved, &mds->mds_ctxt, &rec->ur_uc);
+        pop_ctxt(&saved, &obd->obd_ctxt, &rec->ur_uc);
 
         RETURN(rc);
 }
diff --git a/lustre/mds/mds_unlink_open.c b/lustre/mds/mds_unlink_open.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b05cce5890ef311b6fb2d1a72dc4aef8df006d8
--- /dev/null
+++ b/lustre/mds/mds_unlink_open.c
@@ -0,0 +1,319 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/mds/mds_orphan.c
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* code for handling open unlinked files */
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <portals/list.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_commit_confd.h>
+#include <linux/lvfs.h>
+
+#include "mds_internal.h"
+
+
+/* If we are unlinking an open file/dir (i.e. creating an orphan) then
+ * we instead link the inode into the PENDING directory until it is
+ * finally released.  We can't simply call mds_reint_rename() or some
+ * part thereof, because we don't have the inode to check for link
+ * count/open status until after it is locked.
+ *
+ * For lock ordering, we always get the PENDING, then pending_child lock
+ * last to avoid deadlocks.
+ */
+
+int mds_open_unlink_rename(struct mds_update_record *rec,
+                           struct obd_device *obd, struct dentry *dparent,
+                           struct dentry *dchild, void **handle)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct inode *pending_dir = mds->mds_pending_dir->d_inode;
+        struct dentry *pending_child;
+        char fidname[LL_FID_NAMELEN];
+        int fidlen = 0, rc;
+        ENTRY;
+
+        LASSERT(!mds_inode_is_orphan(dchild->d_inode));
+
+        down(&pending_dir->i_sem);
+        fidlen = ll_fid2str(fidname, dchild->d_inode->i_ino,
+                            dchild->d_inode->i_generation);
+
+        CWARN("pending destroy of %dx open file %s = %s\n",
+              mds_open_orphan_count(dchild->d_inode),
+              rec->ur_name, fidname);
+
+        pending_child = lookup_one_len(fidname, mds->mds_pending_dir, fidlen);
+        if (IS_ERR(pending_child))
+                GOTO(out_lock, rc = PTR_ERR(pending_child));
+
+        if (pending_child->d_inode != NULL) {
+                CERROR("re-destroying orphan file %s?\n", rec->ur_name);
+                LASSERT(pending_child->d_inode == dchild->d_inode);
+                GOTO(out_dput, rc = 0);
+        }
+
+        *handle = fsfilt_start(obd, pending_dir, FSFILT_OP_RENAME, NULL);
+        if (IS_ERR(*handle))
+                GOTO(out_dput, rc = PTR_ERR(*handle));
+
+        lock_kernel();
+        rc = vfs_rename(dparent->d_inode, dchild, pending_dir, pending_child);
+        unlock_kernel();
+        if (rc)
+                CERROR("error renaming orphan %lu/%s to PENDING: rc = %d\n",
+                       dparent->d_inode->i_ino, rec->ur_name, rc);
+        else
+                mds_inode_set_orphan(dchild->d_inode);
+out_dput:
+        dput(pending_child);
+out_lock:
+        up(&pending_dir->i_sem);
+        RETURN(rc);
+}
+
+static int mds_osc_destroy_orphan(struct mds_obd *mds, 
+                                  struct ptlrpc_request *request)
+{
+        struct mds_body *body;
+        struct lov_mds_md *lmm = NULL;
+        struct lov_stripe_md *lsm = NULL;
+        struct obd_trans_info oti = { 0 };
+        struct obdo *oa;
+        int rc;
+        ENTRY;
+
+        body = lustre_msg_buf(request->rq_repmsg, 0, sizeof(*body));
+        if (!(body->valid & OBD_MD_FLEASIZE))
+                RETURN(0);
+        if (body->eadatasize == 0) {
+                CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
+                RETURN(rc = -EPROTO); 
+        }
+
+        lmm = lustre_msg_buf(request->rq_repmsg, 1, body->eadatasize);
+        LASSERT(lmm != NULL);
+
+        rc = obd_unpackmd(mds->mds_osc_exp, &lsm, lmm, body->eadatasize);
+        if (rc < 0) {
+                CERROR("Error unpack md %p\n", lmm);
+                RETURN(rc);
+        } else {
+                LASSERT(rc >= sizeof(*lsm));
+                rc = 0;
+        }
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out_free_memmd, rc = -ENOMEM);
+        oa->o_id = lsm->lsm_object_id;
+        oa->o_mode = body->mode & S_IFMT;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
+
+#ifdef ENABLE_ORPHANS
+        if (body->valid & OBD_MD_FLCOOKIE) {
+                oa->o_valid |= OBD_MD_FLCOOKIE;
+                oti.oti_logcookies = 
+                        lustre_msg_buf(request->rq_repmsg, 2,
+                                       sizeof(struct llog_cookie) *
+                                       lsm->lsm_stripe_count);
+                if (oti.oti_logcookies == NULL)
+                        oa->o_valid &= ~OBD_MD_FLCOOKIE;
+                        body->valid &= ~OBD_MD_FLCOOKIE;
+        }
+#endif
+
+        rc = obd_destroy(mds->mds_osc_exp, oa, lsm, &oti);
+        obdo_free(oa);
+        if (rc) 
+                CERROR("destroy orphan objid 0x"LPX64" on ost error "
+                       "%d\n", lsm->lsm_object_id, rc);
+out_free_memmd:
+        obd_free_memmd(mds->mds_osc_exp, &lsm);
+        RETURN(rc);
+}
+
+static int mds_unlink_orphan(struct obd_device *obd, struct dentry *dchild,
+                      struct inode *inode, struct inode *pending_dir)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct mds_body *body;
+        void *handle = NULL;
+        struct ptlrpc_request *req;
+        int lengths[3] = {sizeof(struct mds_body),
+                          mds->mds_max_mdsize,
+                          mds->mds_max_cookiesize};
+        int rc;
+        ENTRY;
+
+        LASSERT(mds->mds_osc_obd != NULL);
+        OBD_ALLOC(req, sizeof(*req));
+        if (!req) {
+                CERROR("request allocation out of memory\n");
+                GOTO(err_alloc_req, rc = -ENOMEM);
+        }
+        rc = lustre_pack_reply(req, 3, lengths, NULL);
+        if (rc) {
+                CERROR("cannot pack request %d\n", rc);
+                GOTO(out_free_req, rc);
+        }
+        body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+        LASSERT(body != NULL);
+
+        mds_pack_inode2body(body, inode);
+        mds_pack_md(obd, req->rq_repmsg, 1, body, inode, 1);
+
+        handle = fsfilt_start(obd, pending_dir, FSFILT_OP_UNLINK_LOG, NULL);
+        if (IS_ERR(handle)) {
+                rc = PTR_ERR(handle);
+                CERROR("error fsfilt_start: %d\n", rc);
+                handle = NULL;
+                GOTO(out_free_msg, rc);
+        }
+        rc = vfs_unlink(pending_dir, dchild);
+        if (rc) 
+                CERROR("error unlinking orphan from PENDING directory");
+
+#ifdef ENABLE_ORPHANS
+        if ((body->valid & OBD_MD_FLEASIZE)) {
+                if (mds_log_op_unlink(obd, inode, req->rq_repmsg, 1) > 0)
+                        body->valid |= OBD_MD_FLCOOKIE;
+        }
+#endif
+        if (handle) {
+                int err = fsfilt_commit(obd, pending_dir, handle, 0);
+                if (err) {
+                        CERROR("error committing orphan unlink: %d\n",
+                               err);
+                        rc = err;
+                        GOTO(out_free_msg, rc);
+                }
+        }
+        rc = mds_osc_destroy_orphan(mds, req);
+out_free_msg:
+        OBD_FREE(req->rq_repmsg, req->rq_replen);
+        req->rq_repmsg = NULL;
+out_free_req:
+        OBD_FREE(req, sizeof(*req));
+err_alloc_req:
+        RETURN(rc);
+}
+
+int mds_cleanup_orphans(struct obd_device *obd)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct obd_run_ctxt saved;
+        struct file *file;
+        struct dentry *dchild;
+        struct inode *child_inode, *pending_dir = mds->mds_pending_dir->d_inode;
+        struct l_linux_dirent *dirent, *ptr;
+        unsigned int count = pending_dir->i_size;
+        int rc = 0, rc2 = 0, item = 0;
+        ENTRY;
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        dget(mds->mds_pending_dir);
+        mntget(mds->mds_vfsmnt);
+        file = dentry_open(mds->mds_pending_dir, mds->mds_vfsmnt,
+                           O_RDONLY | O_LARGEFILE);
+        if (IS_ERR(file))
+                GOTO(err_open, rc2 = PTR_ERR(file));
+
+        OBD_ALLOC(dirent, count);
+        if (dirent == NULL)
+                GOTO(err_alloc_dirent, rc2 = -ENOMEM);
+
+        rc = l_readdir(file, dirent, count);
+        filp_close(file, 0);
+        if (rc < 0)
+                GOTO(err_out, rc2 = rc);
+
+        for (ptr = dirent; (char *)ptr < (char *)dirent + rc;
+                        (char *)ptr += ptr->d_reclen) {
+                int namlen = strlen(ptr->d_name);
+
+                if (((namlen == 1) && !strcmp(ptr->d_name, ".")) ||
+                    ((namlen == 2) && !strcmp(ptr->d_name, "..")))
+                        continue;
+
+                down(&pending_dir->i_sem);
+                dchild = lookup_one_len(ptr->d_name, mds->mds_pending_dir,
+                                        namlen);
+                if (IS_ERR(dchild)) {
+                        up(&pending_dir->i_sem);
+                        GOTO(err_out, rc2 = PTR_ERR(dchild));
+                }
+                if (!dchild->d_inode) {
+                        CDEBUG(D_ERROR, "orphan %s has been removed\n",
+                               ptr->d_name);
+                        GOTO(next, rc2 = 0);
+                }
+
+                child_inode = dchild->d_inode;
+                if (mds_inode_is_orphan(child_inode) &&
+                    mds_open_orphan_count(child_inode)) {
+                        CWARN("orphan %s was re-opened during recovery\n", 
+                              ptr->d_name);
+                        GOTO(next, rc2 = 0);
+                }
+
+                rc2 = mds_unlink_orphan(obd, dchild, child_inode, pending_dir);
+                if (rc2 == 0) {
+                        item ++;
+                        CWARN("removed orphan %s from MDS and OST\n",
+                               ptr->d_name);
+                } else {
+                        l_dput(dchild); 
+                        up(&pending_dir->i_sem);
+                        GOTO(err_out, rc2);
+                }
+next:
+                l_dput(dchild);
+                up(&pending_dir->i_sem);
+        }
+err_out:
+        OBD_FREE(dirent, count);
+err_pop:
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        if (rc2 == 0)
+                rc2 = item;
+
+        RETURN(rc2);
+
+err_open:
+        mntput(mds->mds_vfsmnt);
+        l_dput(mds->mds_pending_dir);
+        goto err_pop;
+err_alloc_dirent:
+        filp_close(file, 0);
+        goto err_pop;
+}
diff --git a/lustre/mgmt/.cvsignore b/lustre/mgmt/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..067f05c882cdae29bb1a07d695df6d6af77a526e
--- /dev/null
+++ b/lustre/mgmt/.cvsignore
@@ -0,0 +1,9 @@
+.Xrefs
+config.log
+config.status
+configure
+Makefile
+Makefile.in
+.deps
+tags
+TAGS
diff --git a/lustre/mgmt/Makefile.am b/lustre/mgmt/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..f7307c8faa3cd8ced374a5460fded430d8975ff2
--- /dev/null
+++ b/lustre/mgmt/Makefile.am
@@ -0,0 +1,11 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+DEFS=
+
+modulefs_DATA = mgmt_svc.o mgmt_cli.o
+EXTRA_PROGRAMS = mgmt_svc mgmt_cli
+
+include $(top_srcdir)/Rules
diff --git a/lustre/mgmt/mgmt_cli.c b/lustre/mgmt/mgmt_cli.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cbcfaee0c8d92b36baaa8cad0f83edb9130a10d
--- /dev/null
+++ b/lustre/mgmt/mgmt_cli.c
@@ -0,0 +1,284 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Implementation of the management/health monitoring client.
+ *
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
+ *   Author: Mike Shaver <shaver@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MGMT
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_net.h>
+#include <linux/lustre_mgmt.h>
+
+/*** Registration and service/thread management. ***/
+
+/* An entry representing one obd which has registered for management events. */
+struct mgmtcli_registrant {
+        struct list_head   chain;
+        struct obd_device *notify_obd;
+        struct obd_uuid   *relevant_uuid;
+};
+ 
+static int mgmtcli_pinger_main(void *arg)
+{
+        struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg;
+        struct ptlrpc_thread *thread = data->thread;
+        unsigned long flags;
+        struct l_wait_info lwi = { 0 };
+        ENTRY;
+
+        lock_kernel();
+        /* vv ptlrpc_daemonize(); vv */
+        exit_mm(current);
+
+        current->session = 1;
+        current->pgrp = 1;
+        current->tty = NULL;
+
+        exit_files(current);
+        reparent_to_init();
+        /* ^^ ptlrpc_daemonize(); ^^ */
+
+        SIGNAL_MASK_LOCK(current, flags);
+        sigfillset(&current->blocked);
+        RECALC_SIGPENDING;
+        SIGNAL_MASK_UNLOCK(current, flags);
+
+#if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
+        sprintf(current->comm, "%s|%d", data->name,current->thread.extern_pid);
+#elif defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+        sprintf(current->comm, "%s|%d", data->name,
+                current->thread.mode.tt.extern_pid);
+#else
+        strcpy(current->comm, data->name);
+#endif
+        unlock_kernel();
+
+        /* Record that the thread is running */
+        thread->t_flags = SVC_RUNNING;
+        wake_up(&thread->t_ctl_waitq);
+
+        /* And now, loop forever, pinging as needed. */
+        l_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPING, &lwi);
+        
+        thread->t_flags = SVC_STOPPED;
+        wake_up(&thread->t_ctl_waitq);
+
+        CDEBUG(D_NET, "pinger thread exiting");
+        return 0;
+}
+
+static int mgmtcli_connect_to_svc(struct obd_device *obd)
+{
+        int rc;
+        struct mgmtcli_obd *mc = &obd->u.mgmtcli;
+        struct ptlrpc_svc_data svc_data;
+        struct ptlrpc_thread *thread;
+        struct l_wait_info lwi = { 0 };
+        struct lustre_handle conn = {0, };
+        ENTRY;
+
+        /* Connect to ourselves, and thusly to the mgmt service. */
+        rc = client_connect_import(&conn, obd, &obd->obd_uuid);
+        if (rc) {
+                CERROR("failed to connect to mgmt svc: %d\n", rc);
+                (void)client_obd_cleanup(obd, 0);
+                RETURN(rc);
+        }
+        mc->mc_ping_exp = class_conn2export(&conn);
+        
+        LASSERT(mc->mc_ping_thread == NULL);
+        OBD_ALLOC(thread, sizeof (*thread));
+        if (thread == NULL)
+                GOTO(out, rc = -ENOMEM);
+        mc->mc_ping_thread = thread;
+        init_waitqueue_head(&thread->t_ctl_waitq);
+
+        svc_data.name = "mgmtcli";
+        svc_data.thread = thread;
+
+        rc = kernel_thread(mgmtcli_pinger_main, &svc_data, CLONE_VM | CLONE_FILES);
+out:
+        if (rc < 0) {
+                CERROR("can't start thread to ping mgmt svc %s: %d\n",
+                       mc->mc_import->imp_target_uuid.uuid, rc);
+                OBD_FREE(mc->mc_ping_thread, sizeof (*mc->mc_ping_thread));
+                (void)client_disconnect_import(mc->mc_ping_exp, 0);
+                RETURN(rc);
+        }
+        l_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_RUNNING, &lwi);
+        
+        RETURN(0);
+}
+
+static int mgmtcli_disconnect_from_svc(struct obd_device *obd)
+{
+        struct mgmtcli_obd *mc = &obd->u.mgmtcli;
+        struct obd_import *imp = mc->mc_import;
+        struct ptlrpc_thread *thread = mc->mc_ping_thread;
+        struct l_wait_info lwi = { 0 };
+        int rc;
+
+        ENTRY;
+        rc = client_disconnect_import(mc->mc_ping_exp, 0);
+        if (rc) {
+                CERROR("can't disconnect from %s: %d (%s)\n",
+                       imp->imp_target_uuid.uuid, rc,
+                       (thread ? 
+                        "stopping pinger thread anyway" :
+                        "pinger thread already stopped"));
+        }
+
+        if (thread) {
+                thread->t_flags = SVC_STOPPING;
+                wake_up(&thread->t_ctl_waitq);
+                l_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED, &lwi);
+                
+                OBD_FREE(mc->mc_ping_thread, sizeof (*mc->mc_ping_thread));
+        }
+
+        RETURN(rc);
+}
+
+static int mgmtcli_register_for_events(struct obd_device *mgmt_obd,
+                                       struct obd_device *notify_obd,
+                                       struct obd_uuid *relevant_uuid)
+{
+        int start_thread;
+        struct mgmtcli_registrant *reg;
+        struct mgmtcli_obd *mcobd = &mgmt_obd->u.mgmtcli;
+
+        ENTRY;
+        if (strcmp(mgmt_obd->obd_type->typ_name, LUSTRE_MGMTCLI_NAME))
+                RETURN(-EINVAL);
+
+        OBD_ALLOC(reg, sizeof(*reg));
+        if (reg == NULL)
+                RETURN(-ENOMEM);
+
+        reg->notify_obd = notify_obd;
+        reg->relevant_uuid = relevant_uuid; /* XXX hash */
+
+        spin_lock(&mgmt_obd->obd_dev_lock);
+        start_thread = list_empty(&mcobd->mc_registered);
+        list_add(&reg->chain, &mcobd->mc_registered);
+        spin_unlock(&mgmt_obd->obd_dev_lock);
+
+        if (start_thread)
+                RETURN(mgmtcli_connect_to_svc(mgmt_obd));
+
+        RETURN(0);
+}
+
+static int mgmtcli_deregister_for_events(struct obd_device *mgmt_obd,
+                                         struct obd_device *notify_obd)
+{
+        int stop_thread, found = 0;
+        struct mgmtcli_registrant *reg = NULL;
+        struct list_head *tmp, *n;
+        struct mgmtcli_obd *mc = &mgmt_obd->u.mgmtcli;
+
+        ENTRY;
+        if (strcmp(mgmt_obd->obd_type->typ_name, LUSTRE_MGMTCLI_NAME))
+                RETURN(-EINVAL);
+
+        spin_lock(&mgmt_obd->obd_dev_lock);
+        list_for_each_safe(tmp, n, &mc->mc_registered) {
+                reg = list_entry(tmp, struct mgmtcli_registrant, chain);
+                if (reg->notify_obd == notify_obd) {
+                        list_del(&reg->chain);
+                        found = 1;
+                        OBD_FREE(reg, sizeof(*reg));
+                        break;
+                }
+        }
+        spin_unlock(&mgmt_obd->obd_dev_lock);
+
+        if (!found)
+                RETURN(-ENOENT);
+        RETURN(0);
+}
+
+/*** OBD scaffolding and module paraphernalia. ***/
+
+static int mgmtcli_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct mgmtcli_obd *mc = &obd->u.mgmtcli;
+        INIT_LIST_HEAD(&mc->mc_registered);
+        
+        /* Initialize our nested client_obd structure. */
+        RETURN(client_obd_setup(obd, len, buf));
+}
+
+static int mgmtcli_cleanup(struct obd_device *obd, int flags)
+{
+        struct mgmtcli_obd *mc = &obd->u.mgmtcli;
+        
+        if (!list_empty(&mc->mc_registered))
+                RETURN(-EBUSY);
+
+        if (mc->mc_ping_thread) {
+                rc = mgmtcli_disconnect_from_svc(obd);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        RETURN(client_obd_cleanup(obd, flags);
+}
+
+static struct obd_ops mgmtcli_obd_ops = {
+        o_owner:   THIS_MODULE,
+        o_setup:   mgmtcli_setup,
+        o_cleanup: client_obd_cleanup
+};
+
+static int __init mgmtcli_init(void)
+{
+        inter_module_register("mgmtcli_register_for_events", THIS_MODULE,
+                              mgmtcli_register_for_events);
+        inter_module_register("mgmtcli_deregister_for_events", THIS_MODULE,
+                              mgmtcli_deregister_for_events);
+        return class_register_type(&mgmtcli_obd_ops, 0, LUSTRE_MGMTCLI_NAME);
+}
+
+static void __exit mgmtcli_exit(void)
+{
+        class_unregister_type(LUSTRE_MGMTCLI_NAME);
+        inter_module_unregister("mgmtcli_register_for_events");
+        inter_module_unregister("mgmtcli_deregister_for_events");
+}
+
+#ifdef __KERNEL__
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre monitoring client v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(mgmtcli_init);
+module_exit(mgmtcli_exit);
+#endif
diff --git a/lustre/mgmt/mgmt_svc.c b/lustre/mgmt/mgmt_svc.c
new file mode 100644
index 0000000000000000000000000000000000000000..51abb746a8385355eb8d020eeadddc467e9cfd2d
--- /dev/null
+++ b/lustre/mgmt/mgmt_svc.c
@@ -0,0 +1,154 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Implementation of the management/health monitoring service.
+ *
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
+ *   Author: Mike Shaver <shaver@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_MGMT
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/obd_class.h>
+#include <linux/lustre_net.h>
+
+#define MGMT_NEVENTS     1024UL
+#define MGMT_NBUFS       128UL
+#define MGMT_BUFSIZE     8192
+#define MGMT_MAXREQSIZE  512
+#define MGMT_NUM_THREADS 4
+#define MGMT_DEVICE_NAME "mgmt"
+
+static int mgmt_initialized;
+static struct ptlrpc_service *mgmt_service;
+
+static int mgmt_ping(struct ptlrpc_request *req)
+{
+        /* handle_incoming_request will have already updated the export's
+         * last_request_time, so we don't need to do anything else.
+         */
+        return lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+}
+
+static int mgmt_handler(struct ptlrpc_request *req)
+{
+        int rc;
+        ENTRY;
+
+        switch (req->rq_reqmsg->opc) {
+        case OBD_PING:
+                DEBUG_REQ(D_RPCTRACE, req, "ping");
+                rc = mgmt_ping(req);
+                break;
+        case MGMT_CONNECT:
+                DEBUG_REQ(D_RPCTRACE, req, "connect");
+                rc = target_handle_connect(req, NULL /* no recovery handler */);
+                break;
+        case MGMT_DISCONNECT:
+                DEBUG_REQ(D_RPCTRACE, req, "disconnect");
+                rc = target_handle_disconnect(req);
+                break;
+        default:
+                DEBUG_REQ(D_RPCTRACE, req, "UNKNOWN OP");
+                rc = -EINVAL;
+        }
+
+        if (rc)
+                ptlrpc_error(req);
+        else
+                ptlrpc_reply(req);
+
+        RETURN(0);
+}
+
+static int mgmt_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        int i, rc;
+        ENTRY;
+
+        if (mgmt_initialized)
+                RETURN(-EALREADY);
+        
+        mgmt_service = ptlrpc_init_svc(MGMT_NEVENTS, MGMT_NBUFS, MGMT_BUFSIZE,
+                                       MGMT_MAXREQSIZE, MGMT_REQUEST_PORTAL,
+                                       MGMT_REPLY_PORTAL, mgmt_handler,
+                                       "mgmt", obd->obd_proc_entry);
+        if (!mgmt_service) {
+                CERROR("Failed to start mgmt service\n");
+                RETURN(-ENOMEM);
+        }
+
+        rc = ptlrpc_start_n_threads(obd, mgmt_service, MGMT_NUM_THREADS,"mgmt");
+        if (rc)
+                GOTO(err, rc);
+                
+        mgmt_initialized = 1;
+        
+        RETURN(0);
+err:
+        ptlrpc_unregister_service(mgmt_service);
+        RETURN(rc):
+}
+
+static int mgmt_cleanup(struct obd_device *obd, int flags)
+{
+        ENTRY;
+        
+        if (!mgmt_initialized)
+                RETURN(-ENOENT);
+
+        ptlrpc_stop_all_threads(mgmt_service);
+        ptlrpc_unregister_service(mgmt_service);
+        
+        mgmt_initialized = 0;
+        RETURN(0);
+}
+
+static struct obd_ops mgmt_obd_ops = {
+        o_owner:      THIS_MODULE,
+        o_setup:      mgmt_setup,
+        o_cleanup:    mgmt_cleanup,
+        o_connect:    class_connect,
+        o_disconnect: class_disconnect
+};
+
+static int __init mgmt_init(void)
+{
+        int rc = class_register_type(&mgmt_obd_ops, 0, MGMT_DEVICE_NAME);
+
+        return rc;
+}
+
+static void __exit mgmt_exit(void)
+{
+        class_unregister_type(MGMT_DEVICE_NAME);
+}
+
+#ifdef __KERNEL__
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre monitoring service v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(mgmt_init);
+module_exit(mgmt_exit);
+#endif
diff --git a/lustre/obdclass/Makefile.am b/lustre/obdclass/Makefile.am
index 06d60d431b01c842d61405535d369a5decc62598..d7c3c1e0fed8ece142e6a3823d6c97c605ba2581 100644
--- a/lustre/obdclass/Makefile.am
+++ b/lustre/obdclass/Makefile.am
@@ -1,36 +1,34 @@
 DEFS=
 MODULE = obdclass
 
-if EXTN
-FSMOD = fsfilt_extN
-else
-FSMOD = fsfilt_ext3
-endif
-
 class_obd.o: lustre_build_version
 
 if LIBLUSTRE
 lib_LIBRARIES = liblustreclass.a
-liblustreclass_a_SOURCES = uuid.c statfs_pack.c genops.c debug.c class_obd.c
+liblustreclass_a_SOURCES = class_obd.c debug.c genops.c statfs_pack.c uuid.c 
 liblustreclass_a_SOURCES += lustre_handles.c lustre_peer.c lprocfs_status.c
-liblustreclass_a_SOURCES += simple.c recov_log.c obdo.c
+liblustreclass_a_SOURCES += obdo.c obd_config.c llog.c llog_obd.c llog_cat.c
+liblustreclass_a_SOURCES += llog_lvfs.c #llog_ioctl.c rbtree.c
+
+lustre_build_version:
+	echo '#define LUSTRE_VERSION 31' > $(top_builddir)/include/linux/lustre_build_version.h
+	echo '#define BUILD_VERSION "1"' >> $(top_builddir)/include/linux/lustre_build_version.h
 
 else
-modulefs_DATA = lustre_build_version obdclass.o $(FSMOD).o fsfilt_reiserfs.o
-EXTRA_PROGRAMS = obdclass $(FSMOD) fsfilt_reiserfs
+modulefs_DATA = lustre_build_version obdclass.o llog_test.o
+EXTRA_PROGRAMS = obdclass llog_test
 
-obdclass_SOURCES = class_obd.c debug.c genops.c sysctl.c uuid.c simple.c
+obdclass_SOURCES = llog.c llog_cat.c llog_lvfs.c llog_obd.c  class_obd.c debug.c genops.c sysctl.c uuid.c llog_ioctl.c
 obdclass_SOURCES += lprocfs_status.c lustre_handles.c lustre_peer.c
-obdclass_SOURCES += fsfilt.c statfs_pack.c otree.c recov_log.c obdo.c
-endif
-
-include $(top_srcdir)/Rules
+obdclass_SOURCES += statfs_pack.c obdo.c obd_config.c llog_internal.h
 
 lustre_build_version:
 	perl $(top_srcdir)/scripts/version_tag.pl $(top_srcdir) $(top_builddir) > tmpver
-	echo #define LUSTRE_RELEASE @RELEASE@ >> tmpver
+	echo "#define LUSTRE_RELEASE @RELEASE@" >> tmpver
 	cmp -s $(top_builddir)/include/linux/lustre_build_version.h tmpver \
                 2> /dev/null &&                                            \
                 $(RM) tmpver ||                                            \
                 mv tmpver $(top_builddir)/include/linux/lustre_build_version.h
+endif
 
+include $(top_srcdir)/Rules
diff --git a/lustre/obdclass/Makefile.mk b/lustre/obdclass/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..43bdb68d26425bb9dd3c6cd069641bb113b4afcd
--- /dev/null
+++ b/lustre/obdclass/Makefile.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += obdclass.o
+obdclass-objs := llog.o llog_cat.o class_obd.o debug.o \
+		genops.o sysctl.o uuid.o lprocfs_status.o lustre_handles.o \
+		lustre_peer.o statfs_pack.o obdo.o llog_lvfs.o llog_obd.o \
+		obd_config.o llog_ioctl.o
+
+$(obj)/class_obd.o: lustre_build_version
+
+# XXX I'm sure there's some automake mv-if-different helper for this.
+.PHONY:
+lustre_build_version:
+	pwd
+	perl $(src)/../scripts/version_tag.pl $(src)/.. $(obj)/.. > $(obj)/tmpver
+	cmp -s $(src)/../include/linux/lustre_build_version.h $(obj)/tmpver \
+		2> /dev/null &&                                            \
+		$(RM) $(obj)/tmpver ||                                            \
+		mv $(obj)/tmpver $(src)/../include/linux/lustre_build_version.h
diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c
index 7ee897e18fcc31e119972ec1254a891bad6d8b42..40561ac858d8a905f21fd45172b2346df98ff785 100644
--- a/lustre/obdclass/class_obd.c
+++ b/lustre/obdclass/class_obd.c
@@ -25,7 +25,9 @@
  */
 
 #define DEBUG_SUBSYSTEM S_CLASS
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #ifdef __KERNEL__
 #include <linux/config.h> /* for CONFIG_PROC_FS */
 #include <linux/module.h>
@@ -52,6 +54,7 @@
 #include <asm/uaccess.h>
 #include <linux/miscdevice.h>
 #include <linux/smp_lock.h>
+#include <linux/seq_file.h>
 #else
 # include <liblustre.h>
 #endif
@@ -60,9 +63,9 @@
 #include <linux/obd_class.h>
 #include <linux/lustre_debug.h>
 #include <linux/lprocfs_status.h>
-#include <portals/lib-types.h> /* for PTL_MD_MAX_IOV */
 #include <linux/lustre_build_version.h>
 #include <portals/list.h>
+#include "llog_internal.h"
 
 struct semaphore obd_conf_sem;   /* serialize configuration commands */
 struct obd_device obd_dev[MAX_OBD_DEVICES];
@@ -70,10 +73,6 @@ struct list_head obd_types;
 atomic_t obd_memory;
 int obd_memmax;
 
-/* Root for /proc/lustre */
-struct proc_dir_entry *proc_lustre_root = NULL;
-int obd_proc_read_version(char *page, char **start, off_t off, int count, int *eof, void *data);
-struct lprocfs_vars lprocfs_version[] = {{"version", obd_proc_read_version, NULL, NULL },{NULL,NULL,NULL,NULL}};
 int proc_version;
 
 /* The following are visible and mutable through /proc/sys/lustre/. */
@@ -112,10 +111,10 @@ static int obd_class_release(struct inode * inode, struct file * file)
                                 struct obd_class_user_conn, ocuc_chain);
                 list_del (&c->ocuc_chain);
 
-                CDEBUG (D_IOCTL, "Auto-disconnect %p\n", &c->ocuc_conn);
+                CDEBUG (D_IOCTL, "Auto-disconnect exp %p\n", c->ocuc_exp);
 
                 down (&obd_conf_sem);
-                obd_disconnect (&c->ocuc_conn, 0);
+                obd_disconnect (c->ocuc_exp, 0);
                 up (&obd_conf_sem);
 
                 OBD_FREE (c, sizeof (*c));
@@ -128,40 +127,40 @@ static int obd_class_release(struct inode * inode, struct file * file)
 }
 #endif
 
-static int
-obd_class_add_user_conn (struct obd_class_user_state *ocus,
-                         struct lustre_handle *conn)
+static int obd_class_add_user_exp(struct obd_class_user_state *ocus,
+                                  struct obd_export *exp)
 {
         struct obd_class_user_conn *c;
-
+        ENTRY;
         /* NB holding obd_conf_sem */
 
         OBD_ALLOC (c, sizeof (*c));
-        if (ocus == NULL)
-                return (-ENOMEM);
+        if (c == NULL)
+                RETURN(-ENOMEM);
 
-        c->ocuc_conn = *conn;
+        c->ocuc_exp = class_export_get(exp);
         list_add (&c->ocuc_chain, &ocus->ocus_conns);
-        return (0);
+        RETURN(0);
 }
 
-static void
-obd_class_remove_user_conn (struct obd_class_user_state *ocus,
-                            struct lustre_handle *conn)
+static void obd_class_remove_user_exp(struct obd_class_user_state *ocus,
+                                      struct obd_export *exp)
 {
-        struct list_head *e;
         struct obd_class_user_conn *c;
+        ENTRY;
 
         /* NB holding obd_conf_sem or last reference */
 
-        list_for_each (e, &ocus->ocus_conns) {
-                c = list_entry (e, struct obd_class_user_conn, ocuc_chain);
-                if (conn->cookie == c->ocuc_conn.cookie) {
+        list_for_each_entry(c, &ocus->ocus_conns, ocuc_chain) {
+                if (exp == c->ocuc_exp) {
                         list_del (&c->ocuc_chain);
                         OBD_FREE (c, sizeof (*c));
+                        class_export_put(exp);
+                        EXIT;
                         return;
                 }
         }
+        EXIT;
 }
 
 static inline void obd_data2conn(struct lustre_handle *conn,
@@ -177,16 +176,32 @@ static inline void obd_conn2data(struct obd_ioctl_data *data,
         data->ioc_cookie = conn->cookie;
 }
 
-static void dump_exports(struct obd_device *obd)
+int class_resolve_dev_name(uint32_t len, char *name)
 {
-        struct obd_export *exp, *n;
+        int rc;
+        int dev;
+
+        if (!len || !name) {
+                CERROR("No name passed,!\n");
+                GOTO(out, rc = -EINVAL);
+        }
+        if (name[len - 1] != 0) {
+                CERROR("Name not nul terminated!\n");
+                GOTO(out, rc = -EINVAL);
+        }
 
-        list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
-                CERROR("%s: %p %s %d %d %p\n",
-                       obd->obd_name, exp, exp->exp_client_uuid.uuid,
-                       atomic_read(&exp->exp_refcount),
-                       exp->exp_failed, exp->exp_outstanding_reply );
+        CDEBUG(D_IOCTL, "device name %s\n", name);
+        dev = class_name2dev(name);
+        if (dev == -1) {
+                CDEBUG(D_IOCTL, "No device for name %s!\n", name);
+                GOTO(out, rc = -EINVAL);
         }
+
+        CDEBUG(D_IOCTL, "device name %s, dev %d\n", name, dev);
+        rc = dev;
+
+out:
+        RETURN(rc);
 }
 
 int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
@@ -200,6 +215,9 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
         int err = 0, len = 0, serialised = 0;
         ENTRY;
 
+        if (current->fsuid != 0)
+                RETURN(err = -EACCES);
+
         if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
                 RETURN(err = -ENOTTY);
 
@@ -217,6 +235,12 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
         case OBD_IOC_GETATTR:
         case ECHO_IOC_ENQUEUE:
         case ECHO_IOC_CANCEL:
+        case OBD_IOC_CLIENT_RECOVER:
+        case OBD_IOC_CATLOGLIST:
+        case OBD_IOC_LLOG_INFO:
+        case OBD_IOC_LLOG_PRINT:
+        case OBD_IOC_LLOG_CANCEL:
+        case OBD_IOC_LLOG_REMOVE:
                 break;
         default:
                 down(&obd_conf_sem);
@@ -228,8 +252,7 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
         if (!obd && cmd != OBD_IOC_DEVICE &&
             cmd != OBD_IOC_LIST && cmd != OBD_GET_VERSION &&
             cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_UUID2DEV &&
-            cmd != OBD_IOC_NEWDEV && cmd != OBD_IOC_ADD_UUID &&
-            cmd != OBD_IOC_DEL_UUID && cmd != OBD_IOC_CLOSE_UUID) {
+            cmd != OBD_IOC_PROCESS_CFG) {
                 CERROR("OBD ioctl: No device\n");
                 GOTO(out, err = -EINVAL);
         }
@@ -242,17 +265,42 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
         switch (cmd) {
         case OBD_IOC_DEVICE: {
                 CDEBUG(D_IOCTL, "\n");
-                if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
+                if (data->ioc_dev >= MAX_OBD_DEVICES) {
                         CERROR("OBD ioctl: DEVICE invalid device %d\n",
                                data->ioc_dev);
+                        ocus->ocus_current_obd = &obd_dev[data->ioc_dev];
                         GOTO(out, err = -EINVAL);
                 }
                 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
-
                 ocus->ocus_current_obd = &obd_dev[data->ioc_dev];
                 GOTO(out, err = 0);
         }
 
+        case OBD_IOC_PROCESS_CFG: {
+                char *buf;
+                struct lustre_cfg *lcfg;
+
+                /* FIXME hack to liblustre dump, remove when switch
+                   to zeroconf */
+#ifndef __KERNEL__
+                data->ioc_pbuf1 = data->ioc_inlbuf1;
+                data->ioc_plen1 = data->ioc_inllen1;
+#endif
+                if (!data->ioc_plen1 || !data->ioc_pbuf1) {
+                        CERROR("No config buffer passed!\n");
+                        GOTO(out, err = -EINVAL);
+                }
+                err = lustre_cfg_getdata(&buf, data->ioc_plen1,
+                                         data->ioc_pbuf1, 0);
+                if (err)
+                        GOTO(out, err);
+                lcfg = (struct lustre_cfg* ) buf;
+
+                err = class_process_config(lcfg);
+                lustre_cfg_freedata(buf, data->ioc_plen1);
+                GOTO(out, err);
+        }
+
         case OBD_IOC_LIST: {
                 int i;
                 char *buf2 = data->ioc_bulk;
@@ -322,26 +370,12 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
                  */
                 int dev;
 
-                if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
-                        CERROR("No name passed,!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
-                        CERROR("Name not nul terminated!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-
-                CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
-                dev = class_name2dev(data->ioc_inlbuf1);
+                dev = class_resolve_dev_name(data->ioc_inllen1,
+                                             data->ioc_inlbuf1);
                 data->ioc_dev = dev;
-                if (dev == -1) {
-                        CDEBUG(D_IOCTL, "No device for name %s!\n",
-                               data->ioc_inlbuf1);
+                if (dev < 0)
                         GOTO(out, err = -EINVAL);
-                }
 
-                CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
-                       dev);
                 err = copy_to_user((void *)arg, data, sizeof(*data));
                 if (err)
                         err = -EFAULT;
@@ -384,301 +418,46 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
 
 
 
-        case OBD_IOC_NEWDEV: {
-                int dev = -1;
-                int i;
-
-                ocus->ocus_current_obd = NULL;
-                for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
-                        struct obd_device *obd = &obd_dev[i];
-                        if (!obd->obd_type) {
-                                ocus->ocus_current_obd = obd;
-                                dev = i;
-                                break;
-                        }
-                }
-
-
-                data->ioc_dev = dev;
-                if (dev == -1)
-                        GOTO(out, err = -EINVAL);
-
-                err = copy_to_user((void *)arg, data, sizeof(*data));
-                if (err)
-                        err = -EFAULT;
-                GOTO(out, err);
-        }
-
-        case OBD_IOC_ATTACH: {
-                struct obd_type *type;
-                int minor, len;
-
-                /* have we attached a type to this device */
-                if (obd->obd_attached|| obd->obd_type) {
-                        CERROR("OBD: Device %d already typed as %s.\n",
-                               obd->obd_minor, MKSTR(obd->obd_type->typ_name));
-                        GOTO(out, err = -EBUSY);
-                }
-
-                if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
-                        CERROR("No type passed!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
-                        CERROR("Type not nul terminated!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (!data->ioc_inllen2 || !data->ioc_inlbuf2) {
-                        CERROR("No name passed!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (data->ioc_inlbuf2[data->ioc_inllen2 - 1] != 0) {
-                        CERROR("Name not nul terminated!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (!data->ioc_inllen3 || !data->ioc_inlbuf3) {
-                        CERROR("No UUID passed!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-                if (data->ioc_inlbuf3[data->ioc_inllen3 - 1] != 0) {
-                        CERROR("UUID not nul terminated!\n");
-                        GOTO(out, err = -EINVAL);
-                }
-
-                CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
-                       MKSTR(data->ioc_inlbuf1),
-                       MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
-
-                /* find the type */
-                type = class_get_type(data->ioc_inlbuf1);
-                if (!type) {
-                        CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
-                        GOTO(out, err = -EINVAL);
-                }
-
-                minor = obd->obd_minor;
-                memset(obd, 0, sizeof(*obd));
-                obd->obd_minor = minor;
-                obd->obd_type = type;
-                INIT_LIST_HEAD(&obd->obd_exports);
-                obd->obd_num_exports = 0;
-                INIT_LIST_HEAD(&obd->obd_imports);
-                spin_lock_init(&obd->obd_dev_lock);
-                init_waitqueue_head(&obd->obd_refcount_waitq);
-
-                /* XXX belong ins setup not attach  */
-                /* recovery data */
-                spin_lock_init(&obd->obd_processing_task_lock);
-                init_waitqueue_head(&obd->obd_next_transno_waitq);
-                INIT_LIST_HEAD(&obd->obd_recovery_queue);
-                INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
-
-                init_waitqueue_head(&obd->obd_commit_waitq);
-
-                len = strlen(data->ioc_inlbuf2) + 1;
-                OBD_ALLOC(obd->obd_name, len);
-                if (!obd->obd_name) {
-                        class_put_type(obd->obd_type);
-                        obd->obd_type = NULL;
-                        GOTO(out, err = -ENOMEM);
-                }
-                memcpy(obd->obd_name, data->ioc_inlbuf2, len);
-
-                len = strlen(data->ioc_inlbuf3);
-                if (len >= sizeof(obd->obd_uuid)) {
-                        CERROR("uuid must be < "LPSZ" bytes long\n",
-                               sizeof(obd->obd_uuid));
-                        if (obd->obd_name)
-                                OBD_FREE(obd->obd_name,
-                                         strlen(obd->obd_name) + 1);
-                        class_put_type(obd->obd_type);
-                        obd->obd_type = NULL;
-                        GOTO(out, err = -EINVAL);
-                }
-                memcpy(obd->obd_uuid.uuid, data->ioc_inlbuf3, len);
-
-                /* do the attach */
-                if (OBP(obd, attach))
-                        err = OBP(obd,attach)(obd, sizeof(*data), data);
-                if (err) {
-                        if(data->ioc_inlbuf2)
-                                OBD_FREE(obd->obd_name,
-                                         strlen(obd->obd_name) + 1);
-                        class_put_type(obd->obd_type);
-                        obd->obd_type = NULL;
-                } else {
-                        obd->obd_attached = 1;
-
-                        type->typ_refcnt++;
-                        CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
-                               obd->obd_minor, data->ioc_inlbuf1);
-                }
-
-                GOTO(out, err);
-        }
-
-        case OBD_IOC_DETACH: {
-                ENTRY;
-                if (obd->obd_set_up) {
-                        CERROR("OBD device %d still set up\n", obd->obd_minor);
-                        GOTO(out, err = -EBUSY);
-                }
-                if (!obd->obd_attached) {
-                        CERROR("OBD device %d not attached\n", obd->obd_minor);
-                        GOTO(out, err = -ENODEV);
-                }
-                if (OBP(obd, detach))
-                        err = OBP(obd,detach)(obd);
-
-                if (obd->obd_name) {
-                        OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
-                        obd->obd_name = NULL;
-                }
-
-                obd->obd_attached = 0;
-                obd->obd_type->typ_refcnt--;
-                class_put_type(obd->obd_type);
-                obd->obd_type = NULL;
-                memset(obd, 0, sizeof(*obd));
-                GOTO(out, err = 0);
-        }
-
-        case OBD_IOC_SETUP: {
-                /* have we attached a type to this device? */
-                if (!obd->obd_attached) {
-                        CERROR("Device %d not attached\n", obd->obd_minor);
-                        GOTO(out, err = -ENODEV);
-                }
-
-                /* has this been done already? */
-                if (obd->obd_set_up) {
-                        CERROR("Device %d already setup (type %s)\n",
-                               obd->obd_minor, obd->obd_type->typ_name);
-                        GOTO(out, err = -EBUSY);
-                }
-
-                atomic_set(&obd->obd_refcount, 0);
-
-                if (OBT(obd) && OBP(obd, setup))
-                        err = obd_setup(obd, sizeof(*data), data);
-
-                if (!err) {
-                        obd->obd_type->typ_refcnt++;
-                        obd->obd_set_up = 1;
-                        atomic_inc(&obd->obd_refcount);
-                }
-
-                GOTO(out, err);
-        }
-        case OBD_IOC_CLEANUP: {
-                int flags = 0;
-                char *flag;
-
-                if (!obd->obd_set_up) {
-                        CERROR("Device %d not setup\n", obd->obd_minor);
-                        GOTO(out, err = -ENODEV);
-                }
-
-                if (data->ioc_inlbuf1) {
-                        for (flag = data->ioc_inlbuf1; *flag != 0; flag++)
-                                switch (*flag) {
-                                case 'F':
-                                        flags |= OBD_OPT_FORCE;
-                                        break;
-                                case 'A':
-                                        flags |= OBD_OPT_FAILOVER;
-                                        break;
-                                default:
-                                        CERROR("unrecognised flag '%c'\n",
-                                               *flag);
-                                }
-                }
-
-                if (atomic_read(&obd->obd_refcount) == 1 ||
-                    flags & OBD_OPT_FORCE) {
-                        /* this will stop new connections, and need to
-                           do it before class_disconnect_exports() */
-                        obd->obd_stopping = 1;
-                }
-
-                if (atomic_read(&obd->obd_refcount) > 1) {
-                        struct l_wait_info lwi = LWI_TIMEOUT_INTR(60 * HZ, NULL,
-                                                                  NULL, NULL);
-                        int rc;
-
-                        if (!(flags & OBD_OPT_FORCE)) {
-                                CERROR("OBD device %d (%p) has refcount %d\n",
-                                       obd->obd_minor, obd,
-                                       atomic_read(&obd->obd_refcount));
-                                dump_exports(obd);
-                                GOTO(out, err = -EBUSY);
-                        }
-                        class_disconnect_exports(obd, flags);
-                        CDEBUG(D_IOCTL,
-                               "%s: waiting for obd refs to go away: %d\n",
-                               obd->obd_name, atomic_read(&obd->obd_refcount));
-
-                        rc = l_wait_event(obd->obd_refcount_waitq,
-                                     atomic_read(&obd->obd_refcount) < 2, &lwi);
-                        if (rc == 0) {
-                                LASSERT(atomic_read(&obd->obd_refcount) == 1);
-                        } else {
-                                CERROR("wait cancelled cleaning anyway. "
-                                       "refcount: %d\n",
-                                       atomic_read(&obd->obd_refcount));
-                                dump_exports(obd);
-                        }
-                        CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
-                               obd->obd_name);
-                }
-
-                if (OBT(obd) && OBP(obd, cleanup))
-                        err = obd_cleanup(obd, flags);
-
-                if (!err) {
-                        obd->obd_set_up = obd->obd_stopping = 0;
-                        obd->obd_type->typ_refcnt--;
-                        atomic_dec(&obd->obd_refcount);
-                        /* XXX this should be an LASSERT */
-                        if (atomic_read(&obd->obd_refcount) > 0) 
-                                CERROR("%s still has refcount %d after "
-                                       "cleanup.\n", obd->obd_name,
-                                       atomic_read(&obd->obd_refcount));
-                }
-
-                GOTO(out, err);
-        }
-
         case OBD_IOC_CONNECT: {
-                struct obd_uuid cluuid = { "OBD_CLASS_UUID" };
+                struct obd_export *exp;
                 obd_data2conn(&conn, data);
 
-                err = obd_connect(&conn, obd, &cluuid);
+                err = obd_connect(&conn, obd, &obd->obd_uuid);
 
                 CDEBUG(D_IOCTL, "assigned export "LPX64"\n", conn.cookie);
                 obd_conn2data(data, &conn);
                 if (err)
                         GOTO(out, err);
 
-                err = obd_class_add_user_conn (ocus, &conn);
+                exp = class_conn2export(&conn);
+                if (exp == NULL)
+                        GOTO(out, err = -EINVAL);
+
+                err = obd_class_add_user_exp(ocus, exp);
                 if (err != 0) {
-                        obd_disconnect (&conn, 0);
+                        obd_disconnect(exp, 0);
                         GOTO (out, err);
                 }
 
                 err = copy_to_user((void *)arg, data, sizeof(*data));
                 if (err != 0) {
-                        obd_class_remove_user_conn (ocus, &conn);
-                        obd_disconnect (&conn, 0);
+                        obd_class_remove_user_exp(ocus, exp);
+                        obd_disconnect(exp, 0);
                         GOTO (out, err = -EFAULT);
                 }
+                class_export_put(exp);
                 GOTO(out, err);
         }
 
         case OBD_IOC_DISCONNECT: {
+                struct obd_export *exp;
                 obd_data2conn(&conn, data);
-                obd_class_remove_user_conn (ocus, &conn);
-                err = obd_disconnect(&conn, 0);
+                exp = class_conn2export(&conn);
+                if (exp == NULL)
+                        GOTO(out, err = -EINVAL);
+
+                obd_class_remove_user_exp(ocus, exp);
+                err = obd_disconnect(exp, 0);
                 GOTO(out, err);
         }
 
@@ -701,27 +480,16 @@ int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
                 lustre_uuid_to_peer(data->ioc_inlbuf1, &peer);
                 GOTO(out, err = 0);
         }
-        case OBD_IOC_ADD_UUID: {
-                CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
-                       ", nal %d\n", data->ioc_inlbuf1, data->ioc_nid,
-                       data->ioc_nal);
 
-                err = class_add_uuid(data->ioc_inlbuf1, data->ioc_nid,
-                                     data->ioc_nal);
-                GOTO(out, err);
-        }
-        case OBD_IOC_DEL_UUID: {
-                CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
-                       data->ioc_inlbuf1 == NULL ? "<all uuids>" :
-                       data->ioc_inlbuf1);
-
-                err = class_del_uuid(data->ioc_inlbuf1);
-                GOTO(out, err);
-        }
-        default: { 
+        default: {
                 // obd_data2conn(&conn, data);
-                struct obd_class_user_conn *oconn = list_entry(ocus->ocus_conns.next, struct obd_class_user_conn, ocuc_chain);
-                err = obd_iocontrol(cmd, &oconn->ocuc_conn, len, data, NULL);
+                struct obd_class_user_conn *oconn;
+
+                if (list_empty(&ocus->ocus_conns)) 
+                        GOTO(out, err = -ENOTCONN);
+                        
+                oconn = list_entry(ocus->ocus_conns.next, struct obd_class_user_conn, ocuc_chain);
+                err = obd_iocontrol(cmd, oconn->ocuc_exp, len, data, NULL);
                 if (err)
                         GOTO(out, err);
 
@@ -780,8 +548,6 @@ EXPORT_SYMBOL(ptlrpc_put_connection_superhack);
 EXPORT_SYMBOL(ptlrpc_abort_inflight_superhack);
 EXPORT_SYMBOL(proc_lustre_root);
 
-EXPORT_SYMBOL(lctl_fake_uuid);
-
 EXPORT_SYMBOL(class_register_type);
 EXPORT_SYMBOL(class_unregister_type);
 EXPORT_SYMBOL(class_get_type);
@@ -790,8 +556,8 @@ EXPORT_SYMBOL(class_name2dev);
 EXPORT_SYMBOL(class_name2obd);
 EXPORT_SYMBOL(class_uuid2dev);
 EXPORT_SYMBOL(class_uuid2obd);
-EXPORT_SYMBOL(class_export_get);
-EXPORT_SYMBOL(class_export_put);
+EXPORT_SYMBOL(class_find_client_obd);
+EXPORT_SYMBOL(__class_export_put);
 EXPORT_SYMBOL(class_new_export);
 EXPORT_SYMBOL(class_unlink_export);
 EXPORT_SYMBOL(class_import_get);
@@ -800,21 +566,137 @@ EXPORT_SYMBOL(class_new_import);
 EXPORT_SYMBOL(class_destroy_import);
 EXPORT_SYMBOL(class_connect);
 EXPORT_SYMBOL(class_conn2export);
+EXPORT_SYMBOL(class_exp2obd);
 EXPORT_SYMBOL(class_conn2obd);
+EXPORT_SYMBOL(class_exp2cliimp);
 EXPORT_SYMBOL(class_conn2cliimp);
-EXPORT_SYMBOL(class_conn2ldlmimp);
 EXPORT_SYMBOL(class_disconnect);
 EXPORT_SYMBOL(class_disconnect_exports);
 
+EXPORT_SYMBOL(osic_init);
+EXPORT_SYMBOL(osic_add_one);
+EXPORT_SYMBOL(osic_wait);
+EXPORT_SYMBOL(osic_complete_one);
+
 /* uuid.c */
 EXPORT_SYMBOL(class_uuid_unparse);
 EXPORT_SYMBOL(lustre_uuid_to_peer);
-EXPORT_SYMBOL(client_tgtuuid2obd);
 
 EXPORT_SYMBOL(class_handle_hash);
 EXPORT_SYMBOL(class_handle_unhash);
 EXPORT_SYMBOL(class_handle2object);
 
+/* config.c */
+EXPORT_SYMBOL(class_get_profile);
+EXPORT_SYMBOL(class_process_config);
+EXPORT_SYMBOL(class_config_parse_llog);
+EXPORT_SYMBOL(class_config_dump_llog);
+EXPORT_SYMBOL(class_attach);
+EXPORT_SYMBOL(class_setup);
+EXPORT_SYMBOL(class_cleanup);
+EXPORT_SYMBOL(class_detach);
+
+#ifdef LPROCFS
+int obd_proc_read_version(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+        *eof = 1;
+        return snprintf(page, count, "%s\n", BUILD_VERSION);
+}
+
+int obd_proc_read_pinger(char *page, char **start, off_t off, int count,
+                         int *eof, void *data)
+{
+        *eof = 1;
+        return snprintf(page, count, "%s\n",
+#ifdef ENABLE_PINGER
+                        "on"
+#else
+                        "off"
+#endif
+                       );
+}
+
+/* Root for /proc/fs/lustre */
+struct proc_dir_entry *proc_lustre_root = NULL;
+struct lprocfs_vars lprocfs_base[] = {
+        { "version", obd_proc_read_version, NULL, NULL },
+        { "pinger", obd_proc_read_pinger, NULL, NULL },
+        { 0 }
+};
+
+static void *obd_device_list_seq_start(struct seq_file *p, loff_t*pos)
+{
+        if (*pos >= MAX_OBD_DEVICES)
+                return NULL;
+        return &obd_dev[*pos];
+}
+
+static void obd_device_list_seq_stop(struct seq_file *p, void *v)
+{
+}
+
+static void *obd_device_list_seq_next(struct seq_file *p, void *v, loff_t *pos)
+{
+        ++*pos;
+        if (*pos >= MAX_OBD_DEVICES)
+                return NULL;
+        return &obd_dev[*pos];
+}
+
+static int obd_device_list_seq_show(struct seq_file *p, void *v)
+{
+        struct obd_device *obd = (struct obd_device *)v;
+        int index = obd - &obd_dev[0];
+        char *status;
+
+        if (!obd->obd_type)
+                return 0;
+        if (obd->obd_stopping)
+                status = "ST";
+        else if (obd->obd_set_up)
+                status = "UP";
+        else if (obd->obd_attached)
+                status = "AT";
+        else
+                status = "--";
+
+        return seq_printf(p, "%3d %s %s %s %s %d\n",
+                          (int)index, status, obd->obd_type->typ_name,
+                          obd->obd_name, obd->obd_uuid.uuid,
+                          atomic_read(&obd->obd_refcount));
+}
+
+struct seq_operations obd_device_list_sops = {
+        .start = obd_device_list_seq_start,
+        .stop = obd_device_list_seq_stop,
+        .next = obd_device_list_seq_next,
+        .show = obd_device_list_seq_show,
+};
+
+static int obd_device_list_open(struct inode *inode, struct file *file)
+{
+        struct proc_dir_entry *dp = inode->u.generic_ip;
+        struct seq_file *seq;
+        int rc = seq_open(file, &obd_device_list_sops);
+
+        if (rc)
+                return rc;
+
+        seq = file->private_data;
+        seq->private = dp->data;
+
+        return 0;
+}
+
+struct file_operations obd_device_list_fops = {
+        .open = obd_device_list_open,
+        .read = seq_read,
+        .llseek = seq_lseek,
+        .release = seq_release,
+};
+#endif
+
 #ifdef __KERNEL__
 static int __init init_obdclass(void)
 #else
@@ -822,11 +704,14 @@ int init_obdclass(void)
 #endif
 {
         struct obd_device *obd;
+#ifdef LPROCFS
+        struct proc_dir_entry *entry;
+#endif
         int err;
         int i;
 
-        printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION
-                      ", info@clusterfs.com\n");
+        printk(KERN_INFO "Lustre: OBD class driver Build Version: "
+               BUILD_VERSION", info@clusterfs.com\n");
 
         class_init_uuidlist();
         err = class_handle_init();
@@ -856,32 +741,31 @@ int init_obdclass(void)
 
 #ifdef LPROCFS
         proc_lustre_root = proc_mkdir("lustre", proc_root_fs);
-        if (!proc_lustre_root)
-                printk(KERN_ERR "error registering /proc/fs/lustre\n");
-        proc_version = lprocfs_add_vars(proc_lustre_root,lprocfs_version,NULL);
-#else
-        proc_lustre_root = NULL;
-        proc_version = -1;
+        if (!proc_lustre_root) {
+                printk(KERN_ERR
+                       "LustreError: error registering /proc/fs/lustre\n");
+                RETURN(-ENOMEM);
+        }
+        proc_version = lprocfs_add_vars(proc_lustre_root, lprocfs_base, NULL);
+        entry = create_proc_entry("devices", 0444, proc_lustre_root);
+        if (entry == NULL) {
+                printk(KERN_ERR "LustreError: error registering "
+                       "/proc/fs/lustre/devices\n");
+                lprocfs_remove(proc_lustre_root);
+                RETURN(-ENOMEM);
+        }
+        entry->proc_fops = &obd_device_list_fops;
 #endif
         return 0;
 }
 
-#ifdef LPROCFS
-int obd_proc_read_version(char *page, char **start, off_t off, int count, int *eof, void *data) {
-        *eof = 1;
-        return snprintf(page, count, "%s\n", BUILD_VERSION);
-}
-#else
-int obd_proc_read_version(char *page, char **start, off_t off, int count, int *eof, void *data) { return 0; }
-#endif
-
 #ifdef __KERNEL__
 static void /*__exit*/ cleanup_obdclass(void)
 #else
 static void cleanup_obdclass(void)
 #endif
 {
-        int i;
+        int i, leaked;
         ENTRY;
 
         misc_deregister(&obd_psdev);
@@ -898,16 +782,20 @@ static void cleanup_obdclass(void)
 #ifdef __KERNEL__
         obd_sysctl_clean();
 #endif
+#ifdef LPROCFS
         if (proc_lustre_root) {
                 lprocfs_remove(proc_lustre_root);
                 proc_lustre_root = NULL;
         }
+#endif
 
         class_handle_cleanup();
         class_exit_uuidlist();
 
-        CERROR("obd mem max: %d leaked: %d\n", obd_memmax,
-               atomic_read(&obd_memory));
+        leaked = atomic_read(&obd_memory);
+        CDEBUG(leaked ? D_ERROR : D_INFO,
+               "obd mem max: %d leaked: %d\n", obd_memmax, leaked);
+
         EXIT;
 }
 
@@ -915,8 +803,8 @@ static void cleanup_obdclass(void)
  * kernel patch */
 #ifdef __KERNEL__
 #include <linux/lustre_version.h>
-#define LUSTRE_MIN_VERSION 23
-#define LUSTRE_MAX_VERSION 23
+#define LUSTRE_MIN_VERSION 28
+#define LUSTRE_MAX_VERSION 32
 #if (LUSTRE_KERNEL_VERSION < LUSTRE_MIN_VERSION)
 # error Cannot continue: Your Lustre kernel patch is older than the sources
 #elif (LUSTRE_KERNEL_VERSION > LUSTRE_MAX_VERSION)
diff --git a/lustre/obdclass/debug.c b/lustre/obdclass/debug.c
index f824b984ed09db6c5a9da3f0dfc159eafe2bcb6a..04d17b90bb353fa566b65d11c1e7fd942368edac 100644
--- a/lustre/obdclass/debug.c
+++ b/lustre/obdclass/debug.c
@@ -23,7 +23,9 @@
 
 #define DEBUG_SUBSYSTEM D_OTHER
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #ifndef __KERNEL__
 # include <liblustre.h>
 #endif
@@ -82,15 +84,15 @@ int dump_obdo(struct obdo *oa)
                        oa->o_mode & ((valid & OBD_MD_FLTYPE ?  S_IFMT : 0) |
                                      (valid & OBD_MD_FLMODE ? ~S_IFMT : 0)));
         if (valid & OBD_MD_FLUID)
-                CERROR("obdo: o_uid = %d\n", oa->o_uid);
+                CERROR("obdo: o_uid = %u\n", oa->o_uid);
         if (valid & OBD_MD_FLGID)
-                CERROR("obdo: o_gid = %d\n", oa->o_gid);
+                CERROR("obdo: o_gid = %u\n", oa->o_gid);
         if (valid & OBD_MD_FLFLAGS)
                 CERROR("obdo: o_flags = %x\n", oa->o_flags);
         if (valid & OBD_MD_FLNLINK)
-                CERROR("obdo: o_nlink = %d\n", oa->o_nlink);
+                CERROR("obdo: o_nlink = %u\n", oa->o_nlink);
         if (valid & OBD_MD_FLGENER)
-                CERROR("obdo: o_generation = %d\n", oa->o_generation);
+                CERROR("obdo: o_generation = %u\n", oa->o_generation);
 
         return -EINVAL;
 }
diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c
index ce6049d7effa781cf111d1ecc145fd9f9ac80460..12451d103faf66f2153ac2ce558033b7b2f43546 100644
--- a/lustre/obdclass/genops.c
+++ b/lustre/obdclass/genops.c
@@ -29,6 +29,7 @@
 #include <linux/obd_class.h>
 #include <linux/random.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 #else 
 #include <liblustre.h>
 #include <linux/obd_class.h>
@@ -44,8 +45,6 @@ kmem_cache_t *import_cachep = NULL;
 int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);
 void (*ptlrpc_abort_inflight_superhack)(struct obd_import *imp);
 
-struct obd_uuid lctl_fake_uuid = { .uuid = "OBD_CLASS_UUID" };
-
 /*
  * support functions: we could use inter-module communication, but this
  * is more portable to other OS's
@@ -119,8 +118,10 @@ int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars,
         *(type->typ_ops) = *ops;
         strcpy(type->typ_name, name);
 
+#ifdef LPROCFS
         type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root,
                                               vars, type);
+#endif
         if (IS_ERR(type->typ_procroot)) {
                 rc = PTR_ERR(type->typ_procroot);
                 type->typ_procroot = NULL;
@@ -134,10 +135,11 @@ int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars,
         RETURN (0);
 
  failed:
-        if (type->typ_ops != NULL)
+        if (type->typ_name != NULL)
                 OBD_FREE(type->typ_name, strlen(name) + 1);
         if (type->typ_ops != NULL)
                 OBD_FREE (type->typ_ops, sizeof (*type->typ_ops));
+        OBD_FREE(type, sizeof(*type));
         RETURN(rc);
 }
 
@@ -174,6 +176,23 @@ int class_unregister_type(char *name)
         RETURN(0);
 } /* class_unregister_type */
 
+struct obd_device *class_newdev(int *dev)
+{
+        struct obd_device *result = NULL;
+        int i;
+
+        for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
+                struct obd_device *obd = &obd_dev[i];
+                if (!obd->obd_type) {
+                        result = obd;
+                        if (dev)
+                                *dev = i;
+                        break;
+                }
+        }
+        return result;
+}
+
 int class_name2dev(char *name)
 {
         int i;
@@ -219,6 +238,34 @@ struct obd_device *class_uuid2obd(struct obd_uuid *uuid)
         return &obd_dev[dev];
 }
 
+/* Search for a client OBD connected to tgt_uuid.  If grp_uuid is
+   specified, then only the client with that uuid is returned,
+   otherwise any client connected to the tgt is returned. */
+struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid, 
+                                          char * typ_name,
+                                          struct obd_uuid *grp_uuid)
+{
+        int i;
+
+        for (i = 0; i < MAX_OBD_DEVICES; i++) {
+                struct obd_device *obd = &obd_dev[i];
+                if (obd->obd_type == NULL)
+                        continue;
+                if ((strncmp(obd->obd_type->typ_name, typ_name, 
+                             strlen(typ_name)) == 0)) {
+                        struct client_obd *cli = &obd->u.cli;
+                        struct obd_import *imp = cli->cl_import;
+                        if (obd_uuid_equals(tgt_uuid, &imp->imp_target_uuid) &&
+                            ((grp_uuid)? obd_uuid_equals(grp_uuid, 
+                                                        &obd->obd_uuid) : 1)) {
+                                return obd;
+                        }
+                }
+        }
+
+        return NULL;
+}
+
 void obd_cleanup_caches(void)
 {
         int rc;
@@ -282,6 +329,13 @@ struct obd_export *class_conn2export(struct lustre_handle *conn)
         RETURN(export);
 }
 
+struct obd_device *class_exp2obd(struct obd_export *exp)
+{
+        if (exp)
+                return exp->exp_obd;
+        return NULL;
+}
+
 struct obd_device *class_conn2obd(struct lustre_handle *conn)
 {
         struct obd_export *export;
@@ -294,51 +348,31 @@ struct obd_device *class_conn2obd(struct lustre_handle *conn)
         return NULL;
 }
 
-struct obd_import *class_conn2cliimp(struct lustre_handle *conn)
+struct obd_import *class_exp2cliimp(struct obd_export *exp)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = exp->exp_obd;
         if (obd == NULL)
                 return NULL;
         return obd->u.cli.cl_import;
 }
 
-struct obd_import *class_conn2ldlmimp(struct lustre_handle *conn)
+struct obd_import *class_conn2cliimp(struct lustre_handle *conn)
 {
-        struct obd_export *export;
-        export = class_conn2export(conn);
-        if (export) {
-                struct obd_import *imp = export->exp_ldlm_data.led_import;
-                class_export_put(export);
-                return imp;
-        }
-        fixme();
-        return NULL;
+        struct obd_device *obd = class_conn2obd(conn);
+        if (obd == NULL)
+                return NULL;
+        return obd->u.cli.cl_import;
 }
 
+
 /* Export management functions */
 static void export_handle_addref(void *export)
 {
         class_export_get(export);
 }
 
-struct obd_export *class_export_get(struct obd_export *exp)
+void __class_export_put(struct obd_export *exp)
 {
-        atomic_inc(&exp->exp_refcount);
-        CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp,
-               atomic_read(&exp->exp_refcount));
-        return exp;
-}
-
-void class_export_put(struct obd_export *exp)
-{
-        ENTRY;
-        LASSERT(exp != NULL);
-
-        LASSERT(exp);
-        CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", exp,
-               atomic_read(&exp->exp_refcount) - 1);
-        LASSERT(atomic_read(&exp->exp_refcount) > 0);
-        LASSERT(atomic_read(&exp->exp_refcount) < 0x5a5a5a);
         if (atomic_dec_and_test(&exp->exp_refcount)) {
                 struct obd_device *obd = exp->exp_obd;
                 CDEBUG(D_IOCTL, "destroying export %p/%s\n", exp,
@@ -351,16 +385,19 @@ void class_export_put(struct obd_export *exp)
                         ptlrpc_put_connection_superhack(exp->exp_connection);
 
                 LASSERT(list_empty(&exp->exp_handle.h_link));
-
                 obd_destroy_export(exp);
 
                 OBD_FREE(exp, sizeof(*exp));
-                atomic_dec(&obd->obd_refcount);
-                wake_up(&obd->obd_refcount_waitq);
+                if (obd->obd_set_up) {
+                        atomic_dec(&obd->obd_refcount);
+                        wake_up(&obd->obd_refcount_waitq);
+                }
         }
-        EXIT;
 }
 
+/* Creates a new export, adds it to the hash table, and returns a
+ * pointer to it. The refcount is 2: one for the hash reference, and
+ * one for the pointer returned by this function. */
 struct obd_export *class_new_export(struct obd_device *obd)
 {
         struct obd_export *export;
@@ -371,6 +408,7 @@ struct obd_export *class_new_export(struct obd_device *obd)
                 return NULL;
         }
 
+        export->exp_conn_cnt = 0;
         atomic_set(&export->exp_refcount, 2);
         export->exp_obd = obd;
         /* XXX this should be in LDLM init */
@@ -386,6 +424,7 @@ struct obd_export *class_new_export(struct obd_device *obd)
         list_add(&export->exp_obd_chain, &export->exp_obd->obd_exports);
         export->exp_obd->obd_num_exports++;
         spin_unlock(&obd->obd_dev_lock);
+        obd_init_export(export);
         return export;
 }
 
@@ -450,8 +489,11 @@ struct obd_import *class_new_import(void)
         INIT_LIST_HEAD(&imp->imp_sending_list);
         INIT_LIST_HEAD(&imp->imp_delayed_list);
         spin_lock_init(&imp->imp_lock);
+        imp->imp_conn_cnt = 0;
         imp->imp_max_transno = 0;
         imp->imp_peer_committed_transno = 0;
+        imp->imp_state = LUSTRE_IMP_NEW;
+        sema_init(&imp->imp_recovery_sem, 1);
 
         atomic_set(&imp->imp_refcount, 2);
         INIT_LIST_HEAD(&imp->imp_handle.h_link);
@@ -463,6 +505,7 @@ struct obd_import *class_new_import(void)
 void class_destroy_import(struct obd_import *import)
 {
         LASSERT(import != NULL);
+        LASSERT((unsigned long)import != 0x5a5a5a5a);
 
         class_handle_unhash(&import->imp_handle);
 
@@ -476,8 +519,10 @@ void class_destroy_import(struct obd_import *import)
         class_import_put(import);
 }
 
-/* a connection defines an export context in which preallocation can
-   be managed. */
+/* A connection defines an export context in which preallocation can
+   be managed. This releases the export pointer reference, and returns
+   the export handle, so the export refcount is 1 when this function
+   returns. */
 int class_connect(struct lustre_handle *conn, struct obd_device *obd,
                   struct obd_uuid *cluuid)
 {
@@ -485,10 +530,11 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd,
         LASSERT(conn != NULL);
         LASSERT(obd != NULL);
         LASSERT(cluuid != NULL);
+        ENTRY;
 
         export = class_new_export(obd);
         if (export == NULL)
-                return -ENOMEM;
+                RETURN(-ENOMEM);
 
         conn->cookie = export->exp_handle.h_cookie;
         memcpy(&export->exp_client_uuid, cluuid,
@@ -497,22 +543,32 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd,
 
         CDEBUG(D_IOCTL, "connect: client %s, cookie "LPX64"\n",
                cluuid->uuid, conn->cookie);
-        return 0;
+        RETURN(0);
 }
 
-int class_disconnect(struct lustre_handle *conn, int flags)
+/* This function removes two references from the export: one for the
+ * hash entry and one for the export pointer passed in.  The export
+ * pointer passed to this function is destroyed should not be used
+ * again. */
+int class_disconnect(struct obd_export *export, int flags)
 {
-        struct obd_export *export = class_conn2export(conn);
         ENTRY;
 
         if (export == NULL) {
                 fixme();
                 CDEBUG(D_IOCTL, "disconnect: attempting to free "
-                       "nonexistent client "LPX64"\n", conn->cookie);
+                       "null export %p\n", export);
                 RETURN(-EINVAL);
         }
 
-        CDEBUG(D_IOCTL, "disconnect: cookie "LPX64"\n", conn->cookie);
+        /* XXX this shouldn't have to be here, but double-disconnect will crash
+         * otherwise, and sometimes double-disconnect happens.  abort_recovery,
+         * for example. */
+        if (list_empty(&export->exp_handle.h_link))
+                RETURN(0);
+
+        CDEBUG(D_IOCTL, "disconnect: cookie "LPX64"\n", 
+               export->exp_handle.h_cookie);
 
         class_unlink_export(export);
         class_export_put(export);
@@ -524,6 +580,7 @@ void class_disconnect_exports(struct obd_device *obd, int flags)
         int rc;
         struct list_head *tmp, *n, work_list;
         struct lustre_handle fake_conn;
+        struct obd_export *fake_exp, *exp;
         ENTRY;
 
         /* Move all of the exports from obd_exports to a work list, en masse. */
@@ -535,18 +592,26 @@ void class_disconnect_exports(struct obd_device *obd, int flags)
         CDEBUG(D_IOCTL, "OBD device %d (%p) has exports, "
                "disconnecting them\n", obd->obd_minor, obd);
         list_for_each_safe(tmp, n, &work_list) {
-                struct obd_export *exp = list_entry(tmp, struct obd_export,
-                                                    exp_obd_chain);
-
+                exp = list_entry(tmp, struct obd_export, exp_obd_chain);
                 class_export_get(exp);
+                
+                if (obd_uuid_equals(&exp->exp_client_uuid, 
+                                    &exp->exp_obd->obd_uuid)) {
+                        CDEBUG(D_IOCTL, 
+                               "exp %p export uuid == obd uuid, don't discon\n",
+                               exp);
+                        class_export_put(exp);
+                        continue;
+                }
+
                 fake_conn.cookie = exp->exp_handle.h_cookie;
-                rc = obd_disconnect(&fake_conn, flags);
-                /* exports created from last_rcvd data, and "fake"
-                   exports created by lctl don't have an import */
-                if (exp->exp_ldlm_data.led_import != NULL)
-                        class_destroy_import(exp->exp_ldlm_data.led_import);
+                fake_exp = class_conn2export(&fake_conn);
+                if (!fake_exp) {
+                        class_export_put(exp);
+                        continue;
+                }
+                rc = obd_disconnect(fake_exp, flags);
                 class_export_put(exp);
-
                 if (rc) {
                         CDEBUG(D_IOCTL, "disconnecting export %p failed: %d\n",
                                exp, rc);
@@ -556,3 +621,61 @@ void class_disconnect_exports(struct obd_device *obd, int flags)
         }
         EXIT;
 }
+
+void osic_init(struct obd_sync_io_container *osic)
+{
+        spin_lock_init(&osic->osic_lock);
+        osic->osic_rc = 0;
+        osic->osic_pending = 0;
+        init_waitqueue_head(&osic->osic_waitq);
+};
+
+void osic_add_one(struct obd_sync_io_container *osic)
+{
+        unsigned long flags;
+        CDEBUG(D_CACHE, "osic %p ready to roll\n", osic);
+        spin_lock_irqsave(&osic->osic_lock, flags);
+        osic->osic_pending++;
+        spin_unlock_irqrestore(&osic->osic_lock, flags);
+}
+
+void osic_complete_one(struct obd_sync_io_container *osic, int rc)
+{
+        unsigned long flags;
+        wait_queue_head_t *wake = NULL; 
+        int old_rc;
+
+        spin_lock_irqsave(&osic->osic_lock, flags);
+        old_rc = osic->osic_rc;
+        if (osic->osic_rc == 0 && rc != 0)
+                osic->osic_rc = rc;
+        if (--osic->osic_pending <= 0)
+                wake = &osic->osic_waitq;
+        spin_unlock_irqrestore(&osic->osic_lock, flags);
+        CDEBUG(D_CACHE, "osic %p completed, rc %d -> %d via %d, %d now "
+                        "pending (racey)\n", osic, old_rc, osic->osic_rc, rc, 
+                        osic->osic_pending);
+        if (wake)
+                wake_up(wake);
+}
+
+static int osic_done(struct obd_sync_io_container *osic)
+{
+        unsigned long flags;
+        int rc = 0;
+        spin_lock_irqsave(&osic->osic_lock, flags);
+        if (osic->osic_pending <= 0)
+                rc = 1;
+        spin_unlock_irqrestore(&osic->osic_lock, flags);
+        return rc;
+}
+
+int osic_wait(struct obd_sync_io_container *osic)
+{
+        struct l_wait_info lwi = LWI_INTR(NULL, NULL);
+
+        CDEBUG(D_CACHE, "waiting for osic %p\n", osic);
+        l_wait_event(osic->osic_waitq, osic_done(osic), &lwi);
+        CDEBUG(D_CACHE, "done waiting on osic %p\n", osic);
+        return osic->osic_rc;
+}
diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c
new file mode 100644
index 0000000000000000000000000000000000000000..ad7ddcd9b172002e0664f1bc1dc584c86b68e240
--- /dev/null
+++ b/lustre/obdclass/llog.c
@@ -0,0 +1,255 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * OST<->MDS recovery logging infrastructure.
+ *
+ * Invariants in implementation:
+ * - we do not share logs among different OST<->MDS connections, so that
+ *   if an OST or MDS fails it need only look at log(s) relevant to itself
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <portals/list.h>
+
+/* Allocate a new log or catalog handle */
+struct llog_handle *llog_alloc_handle(void)
+{
+        struct llog_handle *loghandle;
+        ENTRY;
+
+        OBD_ALLOC(loghandle, sizeof(*loghandle));
+        if (loghandle == NULL)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        init_rwsem(&loghandle->lgh_lock);
+
+        RETURN(loghandle);
+}
+EXPORT_SYMBOL(llog_alloc_handle);
+
+
+void llog_free_handle(struct llog_handle *loghandle)
+{
+        if (!loghandle)
+                return;
+
+        if (!loghandle->lgh_hdr)
+                goto out;
+        if (le32_to_cpu(loghandle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)
+                list_del_init(&loghandle->u.phd.phd_entry);
+        if (le32_to_cpu(loghandle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
+                LASSERT(list_empty(&loghandle->u.chd.chd_head));
+        OBD_FREE(loghandle->lgh_hdr, LLOG_CHUNK_SIZE);
+
+ out:
+        OBD_FREE(loghandle, sizeof(*loghandle));
+}
+EXPORT_SYMBOL(llog_free_handle);
+
+/* returns negative on error; 0 if success; 1 if success & log destroyed */ 
+int llog_cancel_rec(struct llog_handle *loghandle, int index)
+{
+        struct llog_log_hdr *llh = loghandle->lgh_hdr;
+        int rc = 0;
+        ENTRY;
+
+        CDEBUG(D_HA, "canceling %d in log "LPX64"\n",
+               index, loghandle->lgh_id.lgl_oid);
+
+        if (index == 0) {
+                CERROR("cannot cancel index 0 (which is header)\n");
+                RETURN(-EINVAL);
+        }
+
+        if (!ext2_clear_bit(index, llh->llh_bitmap)) {
+                CERROR("catalog index %u already clear?\n", index);
+                RETURN(-EINVAL);
+        }
+
+        llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) - 1);
+
+        if ((le32_to_cpu(llh->llh_flags) & LLOG_F_ZAP_WHEN_EMPTY) &&
+            (le32_to_cpu(llh->llh_count) == 1) &&
+            (loghandle->lgh_last_idx == (LLOG_BITMAP_BYTES * 8) - 1)) { 
+                rc = llog_destroy(loghandle);
+                if (rc)
+                        CERROR("failure destroying log after last cancel: %d\n",
+                               rc);
+                LASSERT(rc == 0);
+                RETURN(1);
+        }
+
+        rc = llog_write_rec(loghandle, &llh->llh_hdr, NULL, 0, NULL, 0);
+        if (rc) 
+                CERROR("failure re-writing header %d\n", rc);
+        LASSERT(rc == 0);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cancel_rec);
+
+int llog_init_handle(struct llog_handle *handle, int flags,
+                     struct obd_uuid *uuid)
+{
+        int rc;
+        struct llog_log_hdr *llh;
+        ENTRY;
+        LASSERT(handle->lgh_hdr == NULL);
+
+        OBD_ALLOC(llh, sizeof(*llh));
+        if (llh == NULL)
+                RETURN(-ENOMEM);
+        handle->lgh_hdr = llh;
+        /* first assign flags to use llog_client_ops */
+        llh->llh_flags = cpu_to_le32(flags);
+        rc = llog_read_header(handle);
+        if (rc == 0) {
+                flags = le32_to_cpu(llh->llh_flags);
+                if (uuid)
+                        LASSERT(obd_uuid_equals(uuid, &llh->llh_tgtuuid));
+                GOTO(out, rc);
+        } else if (rc != LLOG_EEMPTY || !flags) {
+                /* set a pesudo flag for initialization */
+                flags = LLOG_F_IS_CAT;
+                GOTO(out, rc);
+        }
+        rc = 0;
+        
+        handle->lgh_last_idx = 0; /* header is record with index 0 */
+        llh->llh_count = cpu_to_le32(1);         /* for the header record */
+        llh->llh_hdr.lrh_type = cpu_to_le32(LLOG_HDR_MAGIC);
+        llh->llh_hdr.lrh_len = llh->llh_tail.lrt_len = cpu_to_le32(LLOG_CHUNK_SIZE);
+        llh->llh_hdr.lrh_index = llh->llh_tail.lrt_index = 0;
+        llh->llh_timestamp = cpu_to_le64(LTIME_S(CURRENT_TIME));
+        if (uuid)
+                memcpy(&llh->llh_tgtuuid, uuid, sizeof(llh->llh_tgtuuid));
+        llh->llh_bitmap_offset = cpu_to_le32(offsetof(typeof(*llh), llh_bitmap));
+        ext2_set_bit(0, llh->llh_bitmap);
+
+out:
+        if (flags & LLOG_F_IS_CAT) {
+                INIT_LIST_HEAD(&handle->u.chd.chd_head);
+                llh->llh_size = cpu_to_le32(sizeof(struct llog_logid_rec));
+        }
+        else if (flags & LLOG_F_IS_PLAIN)
+                INIT_LIST_HEAD(&handle->u.phd.phd_entry);
+        else
+                LBUG();
+        
+        if (rc) {
+                OBD_FREE(llh, sizeof(*llh));
+                handle->lgh_hdr = NULL;
+        }
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_init_handle);
+
+int llog_close(struct llog_handle *loghandle)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_handle2ops(loghandle, &lop);
+        if (rc)
+                GOTO(out, rc);
+        if (lop->lop_close == NULL)
+                GOTO(out, -EOPNOTSUPP);
+        rc = lop->lop_close(loghandle);
+ out:
+        llog_free_handle(loghandle);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_close);
+
+int llog_process(struct llog_handle *loghandle, llog_cb_t cb, void *data)
+{
+        struct llog_log_hdr *llh = loghandle->lgh_hdr;
+        void *buf;
+        __u64 cur_offset = LLOG_CHUNK_SIZE;
+        int rc = 0, index = 1;
+        int saved_index = 0;
+        ENTRY;
+
+        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
+        if (!buf)
+                RETURN(-ENOMEM);
+
+        while (rc == 0) {
+                struct llog_rec_hdr *rec;
+                
+                /* skip records not set in bitmap */
+                while (index < (LLOG_BITMAP_BYTES * 8) &&
+                       !ext2_test_bit(index, llh->llh_bitmap))
+                        ++index;
+
+                LASSERT(index <= LLOG_BITMAP_BYTES * 8);
+                if (index == LLOG_BITMAP_BYTES * 8)
+                        break;
+
+                /* get the buf with our target record; avoid old garbage */
+                memset(buf, 0, LLOG_CHUNK_SIZE);
+                rc = llog_next_block(loghandle, &saved_index, index, 
+                                     &cur_offset, buf, LLOG_CHUNK_SIZE);
+                if (rc)
+                        GOTO(out, rc);
+
+                rec = buf;
+                index = le32_to_cpu(rec->lrh_index);
+
+                /* process records in buffer, starting where we found one */
+                while ((void *)rec < buf + LLOG_CHUNK_SIZE) {
+                        if (rec->lrh_index == 0)
+                                GOTO(out, 0); /* no more records */
+
+                        /* if set, process the callback on this record */
+                        if (ext2_test_bit(index, llh->llh_bitmap)) {
+                                rc = cb(loghandle, rec, data);
+                                if (rc) 
+                                        GOTO(out, rc);
+                        }
+
+                        /* next record, still in buffer? */
+                        ++index;
+                        if (index > LLOG_BITMAP_BYTES * 8 - 1)
+                                GOTO(out, rc = 0);
+                        rec = ((void *)rec + le32_to_cpu(rec->lrh_len));
+                }
+        }
+
+ out:
+        if (buf)
+                OBD_FREE(buf, LLOG_CHUNK_SIZE);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_process);
diff --git a/lustre/obdclass/llog_cat.c b/lustre/obdclass/llog_cat.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c49a1064d1f6f8205f8c7801287cf489960e1d1
--- /dev/null
+++ b/lustre/obdclass/llog_cat.c
@@ -0,0 +1,396 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * OST<->MDS recovery logging infrastructure.
+ *
+ * Invariants in implementation:
+ * - we do not share logs among different OST<->MDS connections, so that
+ *   if an OST or MDS fails it need only look at log(s) relevant to itself
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <portals/list.h>
+
+/* Create a new log handle and add it to the open list.
+ * This log handle will be closed when all of the records in it are removed.
+ *
+ * Assumes caller has already pushed us into the kernel context and is locking.
+ */
+static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
+{
+        struct llog_handle *loghandle;
+        struct llog_log_hdr *llh;
+        struct llog_logid_rec rec;
+        int rc, index, bitmap_size, i;
+        ENTRY;
+
+        rc = llog_create(cathandle->lgh_ctxt, &loghandle, NULL, NULL);
+        if (rc)
+                RETURN(ERR_PTR(rc));
+
+        rc = llog_init_handle(loghandle, 
+                              LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY, 
+                              &cathandle->lgh_hdr->llh_tgtuuid);
+        if (rc)
+                GOTO(out_destroy, rc);
+
+        /* Find first free entry */
+        llh = cathandle->lgh_hdr;
+        bitmap_size = sizeof(llh->llh_bitmap) * 8;
+        for (i = 0, index = le32_to_cpu(llh->llh_count); i < bitmap_size; 
+             i++, index++) {
+                index %= bitmap_size;
+                if (ext2_set_bit(index, llh->llh_bitmap)) {
+                        /* XXX This should trigger log clean up or similar */
+                        CERROR("catalog index %d is still in use\n", index);
+                } else {
+                        cathandle->lgh_last_idx = index;
+                        llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) + 1);
+                        break;
+                }
+        }
+        if (i == bitmap_size) {
+                CERROR("no free catalog slots for log...\n");
+                GOTO(out_destroy, rc = -ENOSPC);
+        }
+        CWARN("new recovery log "LPX64":%x for index %u of catalog "LPX64"\n",
+               loghandle->lgh_id.lgl_oid, loghandle->lgh_id.lgl_ogen, index,
+               cathandle->lgh_id.lgl_oid);
+        /* build the record for this log in the catalog */
+        rec.lid_hdr.lrh_len = cpu_to_le32(sizeof(rec));
+        rec.lid_hdr.lrh_index = cpu_to_le32(index);
+        rec.lid_hdr.lrh_type = cpu_to_le32(LLOG_LOGID_MAGIC);
+        rec.lid_id = loghandle->lgh_id;
+        rec.lid_tail.lrt_len = cpu_to_le32(sizeof(rec));
+        rec.lid_tail.lrt_index = cpu_to_le32(index);
+
+        /* update the catalog: header and record */
+        rc = llog_write_rec(cathandle, &rec.lid_hdr, 
+                            &loghandle->u.phd.phd_cookie, 1, NULL, index);
+        if (rc < 0) {
+                GOTO(out_destroy, rc);
+        }
+
+        loghandle->lgh_hdr->llh_cat_idx = cpu_to_le32(index);
+        cathandle->u.chd.chd_current_log = loghandle;
+        LASSERT(list_empty(&loghandle->u.phd.phd_entry));
+        list_add_tail(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head);
+
+ out_destroy:
+        if (rc < 0)
+                llog_destroy(loghandle);
+
+        RETURN(loghandle);
+}
+EXPORT_SYMBOL(llog_cat_new_log);
+
+/* Assumes caller has already pushed us into the kernel context and is locking.
+ * We return a lock on the handle to ensure nobody yanks it from us.
+ */
+int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res,
+                       struct llog_logid *logid)
+{
+        struct llog_handle *loghandle;
+        int rc = 0;
+        ENTRY;
+
+        if (cathandle == NULL)
+                RETURN(-EBADF);
+
+        list_for_each_entry(loghandle, &cathandle->u.chd.chd_head, 
+                            u.phd.phd_entry) {
+                struct llog_logid *cgl = &loghandle->lgh_id;
+                if (cgl->lgl_oid == logid->lgl_oid) {
+                        if (cgl->lgl_ogen != logid->lgl_ogen) {
+                                CERROR("log "LPX64" generation %x != %x\n",
+                                       logid->lgl_oid, cgl->lgl_ogen,
+                                       logid->lgl_ogen);
+                                continue;
+                        }
+                        loghandle->u.phd.phd_cat_handle = cathandle;
+                        cathandle->u.chd.chd_current_log = loghandle;
+                        GOTO(out, rc = 0);
+                }
+        }
+
+        rc = llog_create(cathandle->lgh_ctxt, &loghandle, logid, NULL);
+        if (rc) {
+                CERROR("error opening log id "LPX64":%x: rc %d\n",
+                       logid->lgl_oid, logid->lgl_ogen, rc);
+        } else {
+                rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
+                if (!rc) {
+                        list_add(&loghandle->u.phd.phd_entry, 
+                                 &cathandle->u.chd.chd_head);
+                        cathandle->u.chd.chd_current_log = loghandle;
+                }
+        }
+        if (!rc) {
+                loghandle->u.phd.phd_cat_handle = cathandle;
+                loghandle->u.phd.phd_cookie.lgc_lgl = cathandle->lgh_id;
+                loghandle->u.phd.phd_cookie.lgc_index = 
+                        le32_to_cpu(loghandle->lgh_hdr->llh_cat_idx);
+        }
+
+out:
+        *res = loghandle;
+        RETURN(rc);
+}
+
+int llog_cat_put(struct llog_handle *cathandle)
+{
+        struct llog_handle *loghandle, *n;
+        int rc;
+        ENTRY;
+
+        list_for_each_entry_safe(loghandle, n, &cathandle->u.chd.chd_head, 
+                                 u.phd.phd_entry) {
+                int err = llog_close(loghandle);
+                if (err)
+                        CERROR("error closing loghandle\n");
+        }
+        rc = llog_close(cathandle);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_put);
+
+/* Return the currently active log handle.  If the current log handle doesn't
+ * have enough space left for the current record, start a new one.
+ *
+ * If reclen is 0, we only want to know what the currently active log is,
+ * otherwise we get a lock on this log so nobody can steal our space.
+ *
+ * Assumes caller has already pushed us into the kernel context and is locking.
+ *
+ * NOTE: loghandle is write-locked upon successful return
+ */
+static struct llog_handle *llog_cat_current_log(struct llog_handle *cathandle, 
+                                                int create)
+{
+        struct llog_handle *loghandle = NULL;
+        ENTRY;
+
+        down_read(&cathandle->lgh_lock);
+        loghandle = cathandle->u.chd.chd_current_log;
+        if (loghandle) {
+                struct llog_log_hdr *llh = loghandle->lgh_hdr;
+                if (loghandle->lgh_last_idx < (sizeof(llh->llh_bitmap) * 8) - 1) {
+                        down_write(&loghandle->lgh_lock);
+                        up_read(&cathandle->lgh_lock);
+                        RETURN(loghandle);
+                }
+        }
+        if (!create) {
+                if (loghandle)
+                        down_write(&loghandle->lgh_lock);
+                up_read(&cathandle->lgh_lock);
+                RETURN(loghandle);
+        }
+        up_read(&cathandle->lgh_lock);
+
+        /* time to create new log */
+
+        /* first, we have to make sure the state hasn't changed */
+        down_write(&cathandle->lgh_lock);
+        loghandle = cathandle->u.chd.chd_current_log;
+        if (loghandle) {
+                struct llog_log_hdr *llh = loghandle->lgh_hdr;
+                if (loghandle->lgh_last_idx < (sizeof(llh->llh_bitmap) * 8) - 1) {
+                        down_write(&loghandle->lgh_lock);
+                        up_write(&cathandle->lgh_lock);
+                        RETURN(loghandle);
+                }
+        }
+
+        CDEBUG(D_INODE, "creating new log\n");
+        loghandle = llog_cat_new_log(cathandle);
+        if (loghandle)
+                down_write(&loghandle->lgh_lock);
+        up_write(&cathandle->lgh_lock);
+        RETURN(loghandle);
+}
+
+/* Add a single record to the recovery log(s) using a catalog
+ * Returns as llog_write_record
+ *
+ * Assumes caller has already pushed us into the kernel context.
+ */
+int llog_cat_add_rec(struct llog_handle *cathandle, struct llog_rec_hdr *rec,
+                    struct llog_cookie *reccookie, void *buf)
+{
+        struct llog_handle *loghandle;
+        int rc;
+        ENTRY;
+
+        LASSERT(le32_to_cpu(rec->lrh_len) <= LLOG_CHUNK_SIZE);
+        loghandle = llog_cat_current_log(cathandle, 1);
+        if (IS_ERR(loghandle))
+                RETURN(PTR_ERR(loghandle));
+        /* loghandle is already locked by llog_cat_current_log() for us */
+        rc = llog_write_rec(loghandle, rec, reccookie, 1, buf, -1);
+        up_write(&loghandle->lgh_lock);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_add_rec);
+
+/* For each cookie in the cookie array, we clear the log in-use bit and either:
+ * - the log is empty, so mark it free in the catalog header and delete it
+ * - the log is not empty, just write out the log header
+ *
+ * The cookies may be in different log files, so we need to get new logs
+ * each time.
+ *
+ * Assumes caller has already pushed us into the kernel context.
+ */
+int llog_cat_cancel_records(struct llog_handle *cathandle, int count,
+                        struct llog_cookie *cookies)
+{
+        int i, index, rc = 0;
+        ENTRY;
+
+        down_write(&cathandle->lgh_lock);
+        for (i = 0; i < count; i++, cookies++) {
+                struct llog_handle *loghandle;
+                struct llog_logid *lgl = &cookies->lgc_lgl;
+
+                rc = llog_cat_id2handle(cathandle, &loghandle, lgl);
+                if (rc) {
+                        CERROR("Cannot find log "LPX64"\n", lgl->lgl_oid);
+                        break;
+                }
+
+                down_write(&loghandle->lgh_lock);
+                rc = llog_cancel_rec(loghandle, cookies->lgc_index);
+                up_write(&loghandle->lgh_lock);
+                
+                if (rc == 1) {          /* log has been destroyed */
+                        index = loghandle->u.phd.phd_cookie.lgc_index;
+                        if (cathandle->u.chd.chd_current_log == loghandle)
+                                cathandle->u.chd.chd_current_log = NULL;
+                        llog_free_handle(loghandle);
+                        
+                        LASSERT(index);
+                        rc = llog_cancel_rec(cathandle, index);
+                }
+        }
+        up_write(&cathandle->lgh_lock);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_cancel_records);
+
+int llog_cat_process_cb(struct llog_handle *cat_llh, struct llog_rec_hdr *rec, void *data)
+{
+        struct llog_process_data *d = data;
+        struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
+        struct llog_handle *llh;
+        int rc;
+
+        if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
+                CERROR("invalid record in catalog\n");
+                RETURN(-EINVAL);
+        }
+        CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n", 
+               lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
+               le32_to_cpu(rec->lrh_index), cat_llh->lgh_id.lgl_oid);
+
+        rc = llog_cat_id2handle(cat_llh, &llh, &lir->lid_id);
+        if (rc) {
+                CERROR("Cannot find handle for log "LPX64"\n", lir->lid_id.lgl_oid);
+                RETURN(rc);
+        }        
+
+        rc = llog_process(llh, d->lpd_cb, d->lpd_data);
+        RETURN(rc);
+}
+
+int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data)
+{
+        struct llog_process_data d;
+        int rc;
+        ENTRY;
+        d.lpd_data = data;
+        d.lpd_cb = cb;
+
+        rc = llog_process(cat_llh, llog_cat_process_cb, &d);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_process);
+
+
+#if 0
+/* Assumes caller has already pushed us into the kernel context. */
+int llog_cat_init(struct llog_handle *cathandle, struct obd_uuid *tgtuuid)
+{
+        struct llog_log_hdr *llh;
+        loff_t offset = 0;
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(sizeof(*llh) == LLOG_CHUNK_SIZE);
+
+        down(&cathandle->lgh_lock);
+        llh = cathandle->lgh_hdr;
+
+        if (cathandle->lgh_file->f_dentry->d_inode->i_size == 0) {
+                llog_write_rec(cathandle, &llh->llh_hdr, NULL, 0, NULL, 0);
+
+write_hdr:    
+                rc = lustre_fwrite(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
+                                   &offset);
+                if (rc != LLOG_CHUNK_SIZE) {
+                        CERROR("error writing catalog header: rc %d\n", rc);
+                        OBD_FREE(llh, sizeof(*llh));
+                        if (rc >= 0)
+                                rc = -ENOSPC;
+                } else
+                        rc = 0;
+        } else {
+                rc = lustre_fread(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
+                                  &offset);
+                if (rc != LLOG_CHUNK_SIZE) {
+                        CERROR("error reading catalog header: rc %d\n", rc);
+                        /* Can we do much else if the header is bad? */
+                        goto write_hdr;
+                } else
+                        rc = 0;
+        }
+
+        cathandle->lgh_tgtuuid = &llh->llh_tgtuuid;
+        up(&cathandle->lgh_lock);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_init);
+
+#endif
diff --git a/lustre/obdclass/llog_internal.h b/lustre/obdclass/llog_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..8674351940beae1932907e60c1d43350918a123e
--- /dev/null
+++ b/lustre/obdclass/llog_internal.h
@@ -0,0 +1,10 @@
+#ifndef __LLOG_INTERNAL_H__
+#define __LLOG_INTERNAL_H__
+
+int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, 
+                      char *name, int count, struct llog_logid *idarray);
+int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, 
+                      char *name, int count, struct llog_logid *);
+int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res,
+                       struct llog_logid *logid);
+#endif
diff --git a/lustre/obdclass/llog_ioctl.c b/lustre/obdclass/llog_ioctl.c
new file mode 100644
index 0000000000000000000000000000000000000000..03279f8cd6d46b30eb8c86d5a5ad89e2d206bf88
--- /dev/null
+++ b/lustre/obdclass/llog_ioctl.c
@@ -0,0 +1,294 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#include <linux/fs.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <portals/list.h>
+#include "llog_internal.h"
+
+static int str2logid(struct llog_logid *logid, char *str, int len)
+{
+        char *start, *end, *endp;
+        
+        start = str;
+        if (*start != '#')
+                RETURN(-EINVAL);
+        
+        start++;
+        if (start - str >= len - 1)
+                RETURN(-EINVAL);
+        end = strchr(start, '#');
+        if (end == NULL || end == start)
+                RETURN(-EINVAL);
+
+        *end = '\0';
+        logid->lgl_oid = simple_strtoull(start, &endp, 16); 
+        if (endp != end)
+                RETURN(-EINVAL);
+
+        start = ++end;
+        if (start - str >= len - 1)
+                RETURN(-EINVAL);
+        end = strchr(start, '#');
+        if (end == NULL || end == start)
+                RETURN(-EINVAL);
+
+        *end = '\0';
+        logid->lgl_ogr = simple_strtoull(start, &endp, 16);
+        if (endp != end)
+                RETURN(-EINVAL);
+
+        start = ++end;
+        if (start - str >= len - 1)
+                RETURN(-EINVAL);
+        logid->lgl_ogen = simple_strtoul(start, &endp, 16);
+        if (*endp != '\0')
+                RETURN(-EINVAL);
+
+        RETURN(0);
+}
+
+static int llog_print_cb(struct llog_handle *handle, struct llog_rec_hdr *rec, 
+                         void *data)
+{
+        struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
+        static int l, remains, from, to;
+        static char *out;
+        char *endp;
+        int cur_index;
+        
+        if (ioc_data->ioc_inllen1) {
+                l = 0;
+                remains = ioc_data->ioc_inllen4 + 
+                        size_round(ioc_data->ioc_inllen1) +
+                        size_round(ioc_data->ioc_inllen2) +
+                        size_round(ioc_data->ioc_inllen3);
+                from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
+                if (*endp != '\0')
+                        RETURN(-EINVAL);
+                to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
+                if (*endp != '\0')
+                        RETURN(-EINVAL);
+                out = ioc_data->ioc_bulk;
+                ioc_data->ioc_inllen1 = 0;
+        }
+
+        cur_index = le32_to_cpu(rec->lrh_index);
+        if (cur_index < from)
+                RETURN(0);
+        if (to > 0 && cur_index > to)
+                RETURN(-LLOG_EEMPTY);
+
+        if (le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT) {
+                struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
+                if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
+                        CERROR("invalid record in catalog\n");
+                        RETURN(-EINVAL);
+                }
+
+                l = snprintf(out, remains,
+                             "[index]: %05d  [logid]: #%llx#%llx#%08x\n",
+                             cur_index, lir->lid_id.lgl_oid, 
+                             lir->lid_id.lgl_ogr, lir->lid_id.lgl_ogen);
+        } else {
+                l = snprintf(out, remains,
+                             "[index]: %05d  [type]: %02x  [len]: %04d\n", 
+                             cur_index, le32_to_cpu(rec->lrh_type),
+                             le32_to_cpu(rec->lrh_len));
+        }
+        out += l;
+        remains -= l;
+        if (remains <= 0) {
+                CERROR("not enough space for print log records\n");
+                RETURN(-LLOG_EEMPTY);
+        }
+
+        RETURN(0);
+}
+
+static int llog_remove_log(struct llog_handle *cat, struct llog_logid *logid)
+{
+        struct llog_handle *log;
+        int rc, index = 0;
+        
+        down_write(&cat->lgh_lock);
+        rc = llog_cat_id2handle(cat, &log, logid);
+        if (rc) {
+                CDEBUG(D_IOCTL, "cannot find log #%0llx#%0llx#%08x\n",
+                       logid->lgl_oid, logid->lgl_ogr, logid->lgl_ogen);
+                GOTO(out, rc = -ENOENT);
+        }
+        
+        index = log->u.phd.phd_cookie.lgc_index;
+        LASSERT(index);
+        rc = llog_destroy(log);
+        if (rc) {
+                CDEBUG(D_IOCTL, "cannot destroy log\n");
+                GOTO(out, rc);
+        }
+        rc = llog_cancel_rec(cat, index);
+out:
+        up_write(&cat->lgh_lock);
+        RETURN(rc);
+
+}
+
+int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data)
+{
+        struct llog_logid logid;
+        int err = 0;
+        struct llog_handle *handle = NULL;
+ 
+        if (*data->ioc_inlbuf1 == '#') {
+                err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
+                if (err)
+                        GOTO(out, err);
+                err = llog_create(ctxt, &handle, &logid, NULL);
+                if (err)
+                        GOTO(out, err);        
+        } else if (*data->ioc_inlbuf1 == '$') {
+                char *name = data->ioc_inlbuf1 + 1;
+                err = llog_create(ctxt, &handle, NULL, name);
+                if (err)
+                        GOTO(out, err);
+        } else {
+                GOTO(out, err = -EINVAL);
+        }
+
+        err = llog_init_handle(handle, 0, NULL);
+        if (err) 
+                GOTO(out_close, err = -ENOENT);
+       
+        switch (cmd) {
+        case OBD_IOC_LLOG_INFO: {
+                int l;
+                int remains = data->ioc_inllen2 + 
+                        size_round(data->ioc_inllen1);
+                char *out = data->ioc_bulk;
+
+                l = snprintf(out, remains, 
+                             "logid:            #%llx#%llx#%08x\n"
+                             "flags:            %x (%s)\n"
+                             "records count:    %d\n"
+                             "last index:       %d\n",
+                             handle->lgh_id.lgl_oid, handle->lgh_id.lgl_ogr,
+                             handle->lgh_id.lgl_ogen,
+                             le32_to_cpu(handle->lgh_hdr->llh_flags),
+                             le32_to_cpu(handle->lgh_hdr->llh_flags) & 
+                             LLOG_F_IS_CAT ? "cat" : "plain",
+                             le32_to_cpu(handle->lgh_hdr->llh_count),
+                             handle->lgh_last_idx);
+                out += l;
+                remains -= l;
+                if (remains <= 0) 
+                        CERROR("not enough space for log header info\n");
+
+                GOTO(out_close, err);
+        }
+        case OBD_IOC_LLOG_PRINT: {
+                LASSERT(data->ioc_inllen1);
+                err = llog_process(handle, llog_print_cb, data);
+                if (err == -LLOG_EEMPTY)
+                        err = 0;
+
+                GOTO(out_close, err);
+        }
+        case OBD_IOC_LLOG_CANCEL: {
+                struct llog_cookie cookie;
+                struct llog_logid plain;
+                char *endp;
+                
+                if (!le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
+                        GOTO(out_close, err = -EINVAL);
+        
+                err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
+                if (err)
+                        GOTO(out_close, err);
+                cookie.lgc_lgl = plain;
+                cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, 
+                                                  &endp, 0);
+                if (*endp != '\0')
+                        GOTO(out_close, err = -EINVAL);
+
+                err = llog_cat_cancel_records(handle, 1, &cookie);
+                GOTO(out_close, err);
+        }
+        case OBD_IOC_LLOG_REMOVE: {
+                struct llog_logid plain;
+                
+                if (!le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
+                        GOTO(out_close, err = -EINVAL);
+        
+                err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
+                if (err)
+                        GOTO(out_close, err);
+                err = llog_remove_log(handle, &plain);
+                GOTO(out_close, err);
+        }
+        }
+        
+out_close:
+        if (handle->lgh_hdr && 
+            le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
+                llog_cat_put(handle);
+        else
+                llog_close(handle);
+out:
+        RETURN(err);
+}
+EXPORT_SYMBOL(llog_ioctl);
+
+int llog_catlog_list(struct obd_device *obd, int count, 
+                     struct obd_ioctl_data *data)
+{
+        int size, i;
+        struct llog_logid *idarray, *id;
+        char name[32] = "CATLIST";
+        char *out;
+        int l, remains, rc = 0;
+        
+        size = sizeof(*idarray) * count;
+        
+        OBD_ALLOC(idarray, size);
+        if (!idarray)
+                RETURN(-ENOMEM);
+        memset(idarray, 0, size);
+        
+        rc = llog_get_cat_list(obd, obd, name, count, idarray);
+        if (rc) {
+                OBD_FREE(idarray, size);
+                RETURN(rc);
+        }
+        
+        out = data->ioc_bulk;
+        remains = data->ioc_inllen1;
+        id = idarray;
+        for (i = 0; i < count; i++) {
+                l = snprintf(out, remains, 
+                             "catalog log: #%llx#%llx#%08x\n",
+                             id->lgl_oid, id->lgl_ogr, id->lgl_ogen);
+                id++;
+                out += l;
+                remains -= l;
+                if (remains <= 0) {
+                        CWARN("not enough memory for catlog list\n");
+                        break;
+                }
+        }
+        OBD_FREE(idarray, size);
+        RETURN(0);
+
+}
+EXPORT_SYMBOL(llog_catlog_list);
diff --git a/lustre/obdclass/llog_lvfs.c b/lustre/obdclass/llog_lvfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..21992991e7e79f09200c7f2dfa42e30673a77312
--- /dev/null
+++ b/lustre/obdclass/llog_lvfs.c
@@ -0,0 +1,712 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * OST<->MDS recovery logging infrastructure.
+ *
+ * Invariants in implementation:
+ * - we do not share logs among different OST<->MDS connections, so that
+ *   if an OST or MDS fails it need only look at log(s) relevant to itself
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <linux/obd_ost.h>
+#include <portals/list.h>
+#include <linux/lvfs.h>
+#include <linux/lustre_fsfilt.h>
+#include "llog_internal.h"
+
+#ifdef __KERNEL__
+
+static int llog_lvfs_pad(struct obd_device *obd, struct l_file *file,
+                                int len, int index)
+{
+        struct llog_rec_hdr rec;
+        struct llog_rec_tail tail;
+        int rc;
+        ENTRY;
+
+        LASSERT(len >= LLOG_MIN_REC_SIZE && (len & 0xf) == 0);
+
+        tail.lrt_len = rec.lrh_len = cpu_to_le32(len);
+        tail.lrt_index = rec.lrh_index = cpu_to_le32(index);
+        rec.lrh_type = 0;
+
+        rc = fsfilt_write_record(obd, file, &rec, sizeof(rec), &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing padding record: rc %d\n", rc);
+                goto out;
+        }
+
+        file->f_pos += len - sizeof(rec) - sizeof(tail);
+        rc = fsfilt_write_record(obd, file, &tail, sizeof(tail), &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing padding record: rc %d\n", rc);
+                goto out;
+        }
+
+ out:
+        RETURN(rc);
+}
+
+static int llog_lvfs_write_blob(struct obd_device *obd, struct l_file *file,
+                                struct llog_rec_hdr *rec, void *buf, loff_t off)
+{
+        int rc;
+        struct llog_rec_tail end;
+        loff_t saved_off = file->f_pos;
+        int buflen = le32_to_cpu(rec->lrh_len);
+
+        ENTRY;
+        file->f_pos = off;
+
+        if (!buf) {
+                rc = fsfilt_write_record(obd, file, rec, buflen, &file->f_pos, 0);
+                if (rc) {
+                        CERROR("error writing log record: rc %d\n", rc);
+                        goto out;
+                }
+                GOTO(out, rc = 0);
+        }
+
+        /* the buf case */
+        rec->lrh_len = cpu_to_le32(sizeof(*rec) + buflen + sizeof(end));
+        rc = fsfilt_write_record(obd, file, rec, sizeof(*rec), &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log hdr: rc %d\n", rc);
+                goto out;
+        }
+
+        rc = fsfilt_write_record(obd, file, buf, buflen, &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log buffer: rc %d\n", rc);
+                goto out;
+        }
+
+        end.lrt_len = rec->lrh_len;
+        end.lrt_index = rec->lrh_index;
+        rc = fsfilt_write_record(obd, file, &end, sizeof(end), &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log tail: rc %d\n", rc);
+                goto out;
+        }
+
+        rc = 0;
+ out:
+        if (saved_off > file->f_pos)
+                file->f_pos = saved_off;
+        LASSERT(rc <= 0);
+        RETURN(rc);
+}
+
+static int llog_lvfs_read_blob(struct obd_device *obd, struct l_file *file,
+                                void *buf, int size, loff_t off)
+{
+        loff_t offset = off;
+        int rc;
+        ENTRY;
+
+        rc = fsfilt_read_record(obd, file, buf, size, &offset);
+        if (rc) {
+                CERROR("error reading log record: rc %d\n", rc);
+                RETURN(rc);
+        }
+        RETURN(0);
+}
+
+static int llog_lvfs_read_header(struct llog_handle *handle)
+{
+        struct llog_rec_tail tail;
+        struct obd_device *obd;
+        int rc;
+        ENTRY;
+
+        LASSERT(sizeof(*handle->lgh_hdr) == LLOG_CHUNK_SIZE);
+        
+        obd = handle->lgh_ctxt->loc_exp->exp_obd;
+
+        if (handle->lgh_file->f_dentry->d_inode->i_size == 0) {
+                CDEBUG(D_HA, "not reading header from 0-byte log\n");
+                RETURN(LLOG_EEMPTY);
+        }
+
+        rc = llog_lvfs_read_blob(obd, handle->lgh_file, handle->lgh_hdr,
+                                 LLOG_CHUNK_SIZE, 0);
+        if (rc)
+                CERROR("error reading log header\n");
+
+        rc = llog_lvfs_read_blob(obd, handle->lgh_file, &tail, sizeof(tail),
+                                 handle->lgh_file->f_dentry->d_inode->i_size -
+                                 sizeof(tail));
+        if (rc)
+                CERROR("error reading log tail\n");
+
+        handle->lgh_last_idx = le32_to_cpu(tail.lrt_index);
+        handle->lgh_file->f_pos = handle->lgh_file->f_dentry->d_inode->i_size;
+
+        RETURN(rc);
+}
+
+/* returns negative in on error; 0 if success && reccookie == 0; 1 otherwise */
+/* appends if idx == -1, otherwise overwrites record idx. */
+static int llog_lvfs_write_rec(struct llog_handle *loghandle,
+                               struct llog_rec_hdr *rec,
+                               struct llog_cookie *reccookie, int cookiecount,
+                               void *buf, int idx)
+{
+        struct llog_log_hdr *llh;
+        int reclen = le32_to_cpu(rec->lrh_len), index, rc;
+        struct llog_rec_tail *lrt;
+        struct obd_device *obd;
+        struct file *file;
+        loff_t offset;
+        size_t left;
+        ENTRY;
+
+        llh = loghandle->lgh_hdr;
+        file = loghandle->lgh_file;
+        obd = loghandle->lgh_ctxt->loc_exp->exp_obd;
+
+        /* record length should not bigger than LLOG_CHUNK_SIZE */
+        if (buf)
+                rc = (reclen > LLOG_CHUNK_SIZE - sizeof(struct llog_rec_hdr)
+                      - sizeof(struct llog_rec_tail)) ? -E2BIG : 0;
+        else
+                rc = (reclen > LLOG_CHUNK_SIZE) ? -E2BIG : 0;
+        if (rc)
+                RETURN(rc);
+
+        if (idx != -1) { 
+                loff_t saved_offset;
+
+                /* no header: only allowed to insert record 1 */
+                if (idx != 1 && !file->f_dentry->d_inode->i_size) {
+                        CERROR("idx != -1 in empty log\n");
+                        LBUG();
+                }
+
+                if (idx && llh->llh_size && llh->llh_size != reclen)
+                        RETURN(-EINVAL);
+
+                rc = llog_lvfs_write_blob(obd, file, &llh->llh_hdr, NULL, 0);
+                /* we are done if we only write the header or on error */
+                if (rc || idx == 0)
+                        RETURN(rc);
+
+                saved_offset = sizeof(*llh) + (idx-1) * le32_to_cpu(rec->lrh_len);
+                rc = llog_lvfs_write_blob(obd, file, rec, buf, saved_offset);
+                if (rc == 0 && reccookie) {
+                        reccookie->lgc_lgl = loghandle->lgh_id;
+                        reccookie->lgc_index = idx;
+                        rc = 1;
+                }       
+                RETURN(rc);
+        }
+
+        /* Make sure that records don't cross a chunk boundary, so we can
+         * process them page-at-a-time if needed.  If it will cross a chunk
+         * boundary, write in a fake (but referenced) entry to pad the chunk.
+         *
+         * We know that llog_current_log() will return a loghandle that is
+         * big enough to hold reclen, so all we care about is padding here.
+         */
+        left = LLOG_CHUNK_SIZE - (file->f_pos & (LLOG_CHUNK_SIZE - 1));
+        if (buf) 
+                reclen = sizeof(*rec) + le32_to_cpu(rec->lrh_len) + 
+                        sizeof(struct llog_rec_tail);
+
+        /* NOTE: padding is a record, but no bit is set */
+        if (left != 0 && left < reclen) {
+                loghandle->lgh_last_idx++;
+                rc = llog_lvfs_pad(obd, file, left, loghandle->lgh_last_idx);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        loghandle->lgh_last_idx++;
+        index = loghandle->lgh_last_idx;
+        rec->lrh_index = cpu_to_le32(index);
+        if (buf == NULL) {
+                lrt = (void *)rec + le32_to_cpu(rec->lrh_len) - sizeof(*lrt);
+                lrt->lrt_len = rec->lrh_len;
+                lrt->lrt_index = rec->lrh_index;
+        }
+        if (ext2_set_bit(index, llh->llh_bitmap)) {
+                CERROR("argh, index %u already set in log bitmap?\n", index);
+                LBUG(); /* should never happen */
+        }
+        llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) + 1);
+
+        offset = 0;
+        rc = llog_lvfs_write_blob(obd, file, &llh->llh_hdr, NULL, 0);
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_lvfs_write_blob(obd, file, rec, buf, file->f_pos);
+        if (rc)
+                RETURN(rc);
+
+        CDEBUG(D_HA, "added record "LPX64": idx: %u, %u bytes\n",
+               loghandle->lgh_id.lgl_oid, index, le32_to_cpu(rec->lrh_len));
+        if (rc == 0 && reccookie) {
+                reccookie->lgc_lgl = loghandle->lgh_id;
+                reccookie->lgc_index = index;
+                if (le32_to_cpu(rec->lrh_type) == MDS_UNLINK_REC)
+                        reccookie->lgc_subsys = LLOG_UNLINK_ORIG_CTXT;
+                else if (le32_to_cpu(rec->lrh_type) == OST_SZ_REC)
+                        reccookie->lgc_subsys = LLOG_SIZE_ORIG_CTXT;
+                else if (le32_to_cpu(rec->lrh_type) == OST_RAID1_REC)
+                        reccookie->lgc_subsys = LLOG_RD1_ORIG_CTXT;
+                else 
+                        reccookie->lgc_subsys = -1;
+                rc = 1;
+        }
+        RETURN(rc);
+}
+
+/* We can skip reading at least as many log blocks as the number of
+* minimum sized log records we are skipping.  If it turns out
+* that we are not far enough along the log (because the
+* actual records are larger than minimum size) we just skip
+* some more records. */
+
+static void llog_skip_over(__u64 *off, int curr, int goal)
+{
+        if (goal <= curr)
+                return;
+        *off = (*off + (goal-curr-1) * LLOG_MIN_REC_SIZE) & 
+                ~(LLOG_CHUNK_SIZE - 1);
+}
+
+
+/* sets:
+ *  - cur_offset to the furthest point read in the log file
+ *  - cur_idx to the log index preceeding cur_offset
+ * returns -EIO/-EINVAL on error
+ */
+static int llog_lvfs_next_block(struct llog_handle *loghandle, int *cur_idx,
+                                int next_idx, __u64 *cur_offset, void *buf,
+                                int len)
+{
+        int rc;
+        ENTRY;
+
+        if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
+                RETURN(-EINVAL);
+
+        CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n",
+               next_idx, *cur_idx, *cur_offset);
+
+        while (*cur_offset < loghandle->lgh_file->f_dentry->d_inode->i_size) {
+                struct llog_rec_hdr *rec;
+                struct llog_rec_tail *tail;
+                loff_t ppos;
+
+                llog_skip_over(cur_offset, *cur_idx, next_idx);
+
+                ppos = *cur_offset;
+                rc = fsfilt_read_record(loghandle->lgh_ctxt->loc_exp->exp_obd,
+                                        loghandle->lgh_file, buf, len,
+                                        cur_offset);
+
+                if (rc) {
+                        CERROR("Cant read llog block at log id "LPU64
+                               "/%u offset "LPU64"\n",
+                               loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, 
+                               *cur_offset);
+                         RETURN(rc);
+                }
+
+                /* put number of readed bytes in rc to make code simpler */
+                rc = *cur_offset - ppos;
+
+                if (rc == 0) /* end of file, nothing to do */
+                        RETURN(0);
+
+                if (rc < sizeof(*tail)) {
+                        CERROR("Invalid llog block at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, *cur_offset);
+                         RETURN(-EINVAL);
+                }
+
+                tail = buf + rc - sizeof(struct llog_rec_tail);
+                *cur_idx = le32_to_cpu(tail->lrt_index);
+
+                /* this shouldn't happen */
+                if (tail->lrt_index == 0) {
+                        CERROR("Invalid llog tail at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, *cur_offset);
+                        RETURN(-EINVAL);
+                }
+                if (le32_to_cpu(tail->lrt_index) < next_idx)
+                        continue;
+
+                /* sanity check that the start of the new buffer is no farther
+                 * than the record that we wanted.  This shouldn't happen. */
+                rec = buf;
+                if (le32_to_cpu(rec->lrh_index) > next_idx) {
+                        CERROR("missed desired record? %u > %u\n",
+                               le32_to_cpu(rec->lrh_index), next_idx);
+                        RETURN(-ENOENT);
+                }
+                RETURN(0);
+        }
+        RETURN(-EIO);
+}
+
+static struct file *llog_filp_open(char *name, int flags, int mode)
+{
+        char *logname;
+        struct file *filp;
+        int len;
+
+        OBD_ALLOC(logname, PATH_MAX);
+        if (logname == NULL)
+                return ERR_PTR(-ENOMEM);
+
+        len = snprintf(logname, PATH_MAX, "LOGS/%s", name);
+        if (len >= PATH_MAX - 1) {
+                filp = ERR_PTR(-ENAMETOOLONG);
+        } else {
+                filp = l_filp_open(logname, flags, mode);
+                if (IS_ERR(filp))
+                        CERROR("logfile creation %s: %ld\n", logname, 
+                               PTR_ERR(filp));
+        }
+
+        OBD_FREE(logname, PATH_MAX); 
+        return filp;
+}
+
+/* This is a callback from the llog_* functions.
+ * Assumes caller has already pushed us into the kernel context. */
+static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res,
+                            struct llog_logid *logid, char *name)
+{
+        struct llog_handle *handle;
+        struct obd_device *obd;
+        struct l_dentry *dchild = NULL;
+        struct obdo *oa = NULL;
+        int rc = 0, cleanup_phase = 1;
+        int open_flags = O_RDWR | O_CREAT | O_LARGEFILE;
+        ENTRY;
+
+        handle = llog_alloc_handle();
+        if (handle == NULL)
+                RETURN(-ENOMEM);
+        *res = handle;
+
+        LASSERT(ctxt);
+        LASSERT(ctxt->loc_exp);
+        obd = ctxt->loc_exp->exp_obd;
+
+        if (logid != NULL) {
+                dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, logid->lgl_oid,
+                                             logid->lgl_ogen, logid->lgl_ogr);
+
+                if (IS_ERR(dchild)) {
+                        rc = PTR_ERR(dchild);
+                        CERROR("error looking up log file "LPX64":0x%x: rc %d\n",
+                               logid->lgl_oid, logid->lgl_ogen, rc);
+                        GOTO(cleanup, rc);
+                }
+
+                cleanup_phase = 2;
+                if (dchild->d_inode == NULL) {
+                        rc = -ENOENT;
+                        CERROR("nonexistent log file "LPX64":"LPX64": rc %d\n",
+                               logid->lgl_oid, logid->lgl_ogr, rc);
+                        GOTO(cleanup, rc);
+                }
+
+                handle->lgh_file = l_dentry_open(&obd->obd_ctxt, dchild,
+                                                    O_RDWR | O_LARGEFILE);
+                if (IS_ERR(handle->lgh_file)) {
+                        rc = PTR_ERR(handle->lgh_file);
+                        CERROR("error opening logfile "LPX64"0x%x: rc %d\n",
+                               logid->lgl_oid, logid->lgl_ogen, rc);
+                        GOTO(cleanup, rc);
+                }
+
+                /* assign the value of lgh_id for handle directly */
+                handle->lgh_id = *logid;
+
+        } else if (name) {
+                handle->lgh_file = llog_filp_open(name, open_flags, 0644);
+                if (IS_ERR(handle->lgh_file))
+                        GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+
+                handle->lgh_id.lgl_ogr = 1;
+                handle->lgh_id.lgl_oid =
+                        handle->lgh_file->f_dentry->d_inode->i_ino;
+                handle->lgh_id.lgl_ogen =
+                        handle->lgh_file->f_dentry->d_inode->i_generation;
+        } else {
+                oa = obdo_alloc();
+                if (oa == NULL)
+                        GOTO(cleanup, rc = -ENOMEM);
+                /* XXX get some filter group constants */
+                oa->o_gr = 1;
+                oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP;
+                rc = obd_create(ctxt->loc_exp, oa, NULL, NULL);
+                if (rc)
+                        GOTO(cleanup, rc);
+
+                dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, oa->o_id,
+                                             oa->o_generation, oa->o_gr);
+
+                if (IS_ERR(dchild))
+                        GOTO(cleanup, rc = PTR_ERR(dchild));
+                cleanup_phase = 2;
+                handle->lgh_file = l_dentry_open(&obd->obd_ctxt, dchild,
+                                                 open_flags);
+                if (IS_ERR(handle->lgh_file))
+                        GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+
+                handle->lgh_id.lgl_ogr = oa->o_gr;
+                handle->lgh_id.lgl_oid = oa->o_id;
+                handle->lgh_id.lgl_ogen = oa->o_generation;
+        }
+
+        handle->lgh_ctxt = ctxt;
+ finish:
+        if (oa)
+                obdo_free(oa);
+        RETURN(rc);
+cleanup:
+        switch (cleanup_phase) {
+        case 2:
+                l_dput(dchild);
+        case 1:
+                llog_free_handle(handle);
+        }
+        goto finish;
+}
+
+static int llog_lvfs_close(struct llog_handle *handle)
+{
+        int rc;
+        ENTRY;
+
+        rc = filp_close(handle->lgh_file, 0);
+        if (rc)
+                CERROR("error closing log: rc %d\n", rc);
+        RETURN(rc);
+}
+
+static int llog_lvfs_destroy(struct llog_handle *handle)
+{
+        struct obdo *oa;
+        int rc;
+        ENTRY;
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                RETURN(-ENOMEM);
+
+        oa->o_id = handle->lgh_id.lgl_oid;
+        oa->o_gr = handle->lgh_id.lgl_ogr;
+        oa->o_generation = handle->lgh_id.lgl_ogen;
+        oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLGENER;
+
+        rc = llog_lvfs_close(handle);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = obd_destroy(handle->lgh_ctxt->loc_exp, oa, NULL, NULL);
+ out:
+        obdo_free(oa);
+        RETURN(rc);
+}
+
+/* reads the catalog list */
+int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
+                      char *name, int count, struct llog_logid *idarray)
+{
+        struct obd_run_ctxt saved;
+        struct l_file *file;
+        int rc;
+        int size = sizeof(*idarray) * count;
+        loff_t off = 0;
+
+        LASSERT(count);
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        file = filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
+        if (!file || IS_ERR(file)) {
+                rc = PTR_ERR(file);
+                CERROR("OBD filter: cannot open/create %s: rc = %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+        if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+                CERROR("%s is not a regular file!: mode = %o\n", name,
+                       file->f_dentry->d_inode->i_mode);
+                GOTO(out, rc = -ENOENT);
+        }
+
+        rc = fsfilt_read_record(disk_obd, file, idarray, size, &off);
+        if (rc) {
+                CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+ out:
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        if (file && !IS_ERR(file))
+                rc = filp_close(file, 0);
+        RETURN(rc);
+}
+
+/* writes the cat list */
+int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
+                      char *name, int count, struct llog_logid *idarray)
+{
+        struct obd_run_ctxt saved;
+        struct l_file *file;
+        int rc;
+        int size = sizeof(*idarray) * count;
+        loff_t off = 0;
+
+        LASSERT(count);
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        file = filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
+        if (!file || IS_ERR(file)) {
+                rc = PTR_ERR(file);
+                CERROR("OBD filter: cannot open/create %s: rc = %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+        if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+                CERROR("%s is not a regular file!: mode = %o\n", name,
+                       file->f_dentry->d_inode->i_mode);
+                GOTO(out, rc = -ENOENT);
+        }
+
+        rc = fsfilt_write_record(disk_obd, file, idarray, size, &off, 1);
+        if (rc) {
+                CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+ out:
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        if (file && !IS_ERR(file))
+                rc = filp_close(file, 0);
+        RETURN(rc);
+}
+
+struct llog_operations llog_lvfs_ops = {
+        lop_write_rec:   llog_lvfs_write_rec,
+        lop_next_block:  llog_lvfs_next_block,
+        lop_read_header: llog_lvfs_read_header,
+        lop_create:      llog_lvfs_create,
+        lop_destroy:     llog_lvfs_destroy,
+        lop_close:       llog_lvfs_close,
+        //        lop_cancel: llog_lvfs_cancel,
+};
+
+EXPORT_SYMBOL(llog_lvfs_ops);
+
+#else /* !__KERNEL__ */
+
+static int llog_lvfs_read_header(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+static int llog_lvfs_write_rec(struct llog_handle *loghandle,
+                               struct llog_rec_hdr *rec,
+                               struct llog_cookie *reccookie, int cookiecount, 
+                               void *buf, int idx)
+{
+        LBUG();
+        return 0;
+}
+static int llog_lvfs_next_block(struct llog_handle *loghandle, int *cur_idx,
+                                int next_idx, __u64 *cur_offset, void *buf,
+                                int len)
+{
+        LBUG();
+        return 0;
+}
+static int llog_lvfs_create(struct llog_obd_ctxt *ctxt, struct llog_handle **res,
+                            struct llog_logid *logid, char *name)
+{
+        LBUG();
+        return 0;
+}
+static int llog_lvfs_close(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+static int llog_lvfs_destroy(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, 
+                      char *name, int count, struct llog_logid *idarray)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, 
+                      char *name, int count, struct llog_logid *idarray)
+{
+        LBUG();
+        return 0;
+}
+
+struct llog_operations llog_lvfs_ops = {
+        lop_write_rec:   llog_lvfs_write_rec,
+        lop_next_block:  llog_lvfs_next_block,
+        lop_read_header: llog_lvfs_read_header,
+        lop_create:      llog_lvfs_create,
+        lop_destroy:     llog_lvfs_destroy,
+        lop_close:       llog_lvfs_close,
+//        lop_cancel:      llog_lvfs_cancel,
+};
+#endif
diff --git a/lustre/obdclass/llog_obd.c b/lustre/obdclass/llog_obd.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c9abb735384cf9a1c864a39f16589b979bc1c08
--- /dev/null
+++ b/lustre/obdclass/llog_obd.c
@@ -0,0 +1,347 @@
+
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <portals/list.h>
+#include "llog_internal.h"
+
+/* helper functions for calling the llog obd methods */
+
+int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd, 
+               int count, struct llog_logid *logid, struct llog_operations *op)
+{
+        int rc = 0;
+        struct llog_ctxt *ctxt;
+        ENTRY;
+
+        if (index < 0 || index >= LLOG_MAX_CTXTS)
+                RETURN(-EFAULT);
+
+        OBD_ALLOC(ctxt, sizeof(*ctxt));
+        if (!ctxt)
+                RETURN(-ENOMEM);
+
+        obd->obd_llog_ctxt[index] = ctxt;
+        ctxt->loc_obd = obd;
+        ctxt->loc_exp = class_export_get(disk_obd->obd_self_export);
+        ctxt->loc_idx = index;
+        ctxt->loc_logops = op;
+        sema_init(&ctxt->loc_sem, 1);
+
+        if (op->lop_setup)
+                rc = op->lop_setup(obd, index, disk_obd, count, logid);
+        if (ctxt && rc) 
+                OBD_FREE(ctxt, sizeof(*ctxt));
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_setup);
+
+int llog_cleanup(struct llog_ctxt *ctxt)
+{
+        int rc = 0;
+        ENTRY;
+
+        down(&ctxt->loc_sem);
+        LASSERT(ctxt);
+
+        if (CTXTP(ctxt, cleanup))
+                rc = CTXTP(ctxt, cleanup)(ctxt);
+
+        ctxt->loc_obd->obd_llog_ctxt[ctxt->loc_idx] = NULL;
+        class_export_put(ctxt->loc_exp);
+        ctxt->loc_exp = NULL;
+        up(&ctxt->loc_sem);
+        OBD_FREE(ctxt, sizeof(*ctxt));
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cleanup);
+
+int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (!ctxt)
+                RETURN(0);
+        down(&ctxt->loc_sem);
+        if (ctxt->loc_llcd && CTXTP(ctxt, sync))
+                rc = CTXTP(ctxt, sync)(ctxt, exp);
+        else
+                up(&ctxt->loc_sem);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_sync);
+
+int llog_add(struct llog_ctxt *ctxt,
+                 struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                 struct llog_cookie *logcookies, int numcookies)
+{
+        int rc;
+        ENTRY;
+
+        LASSERT(ctxt);
+        down(&ctxt->loc_sem);
+        CTXT_CHECK_OP(ctxt, add, -EOPNOTSUPP);
+
+        rc = CTXTP(ctxt, add)(ctxt, rec, lsm, logcookies, numcookies);
+        up(&ctxt->loc_sem);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_add);
+
+int llog_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
+                int count, struct llog_cookie *cookies, int flags)
+{
+        int rc;
+        ENTRY;
+
+        LASSERT(ctxt);
+        CTXT_CHECK_OP(ctxt, cancel, -EOPNOTSUPP);
+        rc = CTXTP(ctxt, cancel)(ctxt, lsm, count, cookies, flags);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cancel);
+
+/* callback func for llog_process in llog_obd_origin_setup */
+static int cat_cancel_cb(struct llog_handle *cathandle, 
+                          struct llog_rec_hdr *rec, void *data)
+{
+        struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
+        struct llog_handle *loghandle;
+        struct llog_log_hdr *llh;
+        int rc, index;
+        ENTRY;
+
+        if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
+                CERROR("invalid record in catalog\n");
+                RETURN(-EINVAL);
+        }
+        CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n", 
+               lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
+               le32_to_cpu(rec->lrh_index), cathandle->lgh_id.lgl_oid);
+
+        rc = llog_cat_id2handle(cathandle, &loghandle, &lir->lid_id);
+        if (rc) {
+                CERROR("Cannot find handle for log "LPX64"\n", lir->lid_id.lgl_oid);
+                RETURN(rc);
+        }        
+        
+        llh = loghandle->lgh_hdr;
+        if ((le32_to_cpu(llh->llh_flags) & LLOG_F_ZAP_WHEN_EMPTY) &&
+            (le32_to_cpu(llh->llh_count) == 1)) {
+                rc = llog_destroy(loghandle);
+                if (rc)
+                        CERROR("failure destroying log during postsetup: %d\n", rc);
+                LASSERT(rc == 0);
+
+                index = loghandle->u.phd.phd_cookie.lgc_index;
+                if (cathandle->u.chd.chd_current_log == loghandle)
+                        cathandle->u.chd.chd_current_log = NULL;
+                llog_free_handle(loghandle);
+                                                                                                                
+                LASSERT(index);
+                rc = llog_cancel_rec(cathandle, index);
+                if (rc == 0)
+                        CWARN("cancel log "LPX64":%x at index %u of catalog "LPX64"\n", 
+                               lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
+                               le32_to_cpu(rec->lrh_index), cathandle->lgh_id.lgl_oid);
+        }
+
+        RETURN(rc);
+}
+
+/* lop_setup method for filter/osc */
+// XXX how to set exports
+int llog_obd_origin_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
+                          int count, struct llog_logid *logid)
+{
+        struct llog_ctxt *ctxt;
+        struct llog_handle *handle;
+        struct obd_run_ctxt saved;
+        int rc;
+        ENTRY;
+
+        if (count == 0)
+                RETURN(0);
+
+        LASSERT(count == 1);
+        
+        ctxt = llog_get_context(obd, index);
+        LASSERT(ctxt);
+        log_gen_init(ctxt);
+
+        down(&ctxt->loc_sem);
+        if (logid->lgl_oid)
+                rc = llog_create(ctxt, &handle, logid, NULL);
+        else {
+                rc = llog_create(ctxt, &handle, NULL, NULL);
+                if (!rc) 
+                        *logid = handle->lgh_id;
+        }
+        if (rc) 
+                GOTO(out, rc);
+
+        ctxt->loc_handle = handle;
+        push_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        rc = llog_init_handle(handle, LLOG_F_IS_CAT, NULL);
+        pop_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = llog_process(handle, (llog_cb_t)cat_cancel_cb, NULL);
+        if (rc) 
+                CERROR("llog_process with cat_cancel_cb failed: %d\n", rc);
+ out:
+        up(&ctxt->loc_sem);
+        if (ctxt && rc) {
+                obd->obd_llog_ctxt[index] = NULL;
+                OBD_FREE(ctxt, sizeof(*ctxt));
+        }
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_obd_origin_setup);
+
+int llog_obd_origin_cleanup(struct llog_ctxt *ctxt)
+{
+        struct llog_handle *cathandle, *n, *loghandle;
+        struct llog_log_hdr *llh;
+        int rc, index;
+        ENTRY;
+        
+        if (!ctxt)
+                return 0;
+
+        cathandle = ctxt->loc_handle;
+        if (cathandle) {
+                list_for_each_entry_safe(loghandle, n, &cathandle->u.chd.chd_head, 
+                                 u.phd.phd_entry) {
+                        llh = loghandle->lgh_hdr;
+                        if ((le32_to_cpu(llh->llh_flags) & LLOG_F_ZAP_WHEN_EMPTY) &&
+                            (le32_to_cpu(llh->llh_count) == 1)) {
+                                rc = llog_destroy(loghandle);
+                                if (rc)
+                                        CERROR("failure destroying log during cleanup: %d\n",
+                                               rc);
+                                LASSERT(rc == 0);
+
+                                index = loghandle->u.phd.phd_cookie.lgc_index;
+                                if (cathandle->u.chd.chd_current_log == loghandle)
+                                        cathandle->u.chd.chd_current_log = NULL;
+                                llog_free_handle(loghandle);
+                                                                                                                             
+                                LASSERT(index);
+                                rc = llog_cancel_rec(cathandle, index);
+                                if (rc == 0)
+                                        CWARN("cancel plain log at index %u of catalog "LPX64"\n", 
+                                              index, cathandle->lgh_id.lgl_oid);
+                        }
+                }
+                llog_cat_put(ctxt->loc_handle);
+        }
+        return 0;
+}
+EXPORT_SYMBOL(llog_obd_origin_cleanup);
+
+
+/* add for obdfilter/sz and mds/unlink */
+int llog_obd_origin_add(struct llog_ctxt *ctxt,
+                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+                        struct llog_cookie *logcookies, int numcookies)
+{
+        struct llog_handle *cathandle;
+        int rc;
+        ENTRY;
+
+        cathandle = ctxt->loc_handle;
+        LASSERT(cathandle != NULL);
+        rc = llog_cat_add_rec(cathandle, rec, logcookies, NULL);
+        if (rc != 1)
+                CERROR("write one catalog record failed: %d\n", rc);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_obd_origin_add);
+
+int llog_cat_initialize(struct obd_device *obd, int count)
+{
+        struct llog_logid *idarray;
+        int size = sizeof(*idarray) * count;
+        char name[32] = "CATLIST";
+        int rc;
+        ENTRY;
+
+        OBD_ALLOC(idarray, size);
+        if (!idarray)
+                RETURN(-ENOMEM);
+
+        memset(idarray, 0, size);
+
+        rc = llog_get_cat_list(obd, obd, name, count, idarray);
+        if (rc) {
+                CERROR("rc: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+        rc = obd_llog_init(obd, obd, count, idarray);
+        if (rc) {
+                CERROR("rc: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+        rc = llog_put_cat_list(obd, obd, name, count, idarray);
+        if (rc) {
+                CERROR("rc: %d\n", rc);
+                GOTO(out, rc);
+        }
+                        
+ out:
+        OBD_FREE(idarray, size);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_initialize);
+
+int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd,
+                  int count, struct llog_logid *logid)
+{
+        int rc;
+        ENTRY;
+        OBD_CHECK_OP(obd, llog_init, 0);
+        OBD_COUNTER_INCREMENT(obd, llog_init);
+
+        rc = OBP(obd, llog_init)(obd, disk_obd, count, logid);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(obd_llog_init);
+
+int obd_llog_finish(struct obd_device *obd, int count)
+{
+        int rc;
+        ENTRY;
+        OBD_CHECK_OP(obd, llog_finish, 0);
+        OBD_COUNTER_INCREMENT(obd, llog_finish);
+
+        rc = OBP(obd, llog_finish)(obd, count);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(obd_llog_finish);
diff --git a/lustre/obdclass/llog_test.c b/lustre/obdclass/llog_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..4f58a40eda49156879667bf7e4a8c8b5d699d147
--- /dev/null
+++ b/lustre/obdclass/llog_test.c
@@ -0,0 +1,652 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2003 Cluster File Systems, Inc.
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * A kernel module which tests the llog API from the OBD setup function.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_CLASS
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <linux/lustre_mds.h> /* for LUSTRE_MDC_NAME */
+
+static int llog_test_rand;
+static struct obd_uuid uuid = { .uuid = "test_uuid" };
+static struct llog_logid cat_logid;
+
+struct llog_mini_rec {
+        struct llog_rec_hdr     lmr_hdr;
+        __u32                   padding[2];
+        struct llog_rec_tail    lmr_tail;
+} __attribute__((packed));
+
+static int verify_handle(char *test, struct llog_handle *llh, int num_recs)
+{
+        int i;
+        int last_idx = 0;
+        int active_recs = 0;
+
+        for (i = 0; i < LLOG_BITMAP_BYTES * 8; i++) {
+                if (ext2_test_bit(i, llh->lgh_hdr->llh_bitmap)) {
+                        last_idx = i;
+                        active_recs++;
+                }
+        }
+
+        if (active_recs != num_recs) {
+                CERROR("%s: expected %d active recs after write, found %d\n",
+                       test, num_recs, active_recs);
+                RETURN(-ERANGE);
+        }
+
+        if (le32_to_cpu(llh->lgh_hdr->llh_count) != num_recs) {
+                CERROR("%s: handle->count is %d, expected %d after write\n",
+                       test, le32_to_cpu(llh->lgh_hdr->llh_count), num_recs);
+                RETURN(-ERANGE);
+        }
+
+        if (llh->lgh_last_idx < last_idx) {
+                CERROR("%s: handle->last_idx is %d, expected %d after write\n",
+                       test, llh->lgh_last_idx, last_idx);
+                RETURN(-ERANGE);
+        }
+
+        RETURN(0);
+}
+
+/* Test named-log create/open, close */
+static int llog_test_1(struct obd_device *obd, char *name)
+{
+        struct llog_handle *llh;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+        int rc;
+        int rc2;
+        ENTRY;
+
+        CERROR("1a: create a log with name: %s\n", name);
+        LASSERT(ctxt);
+
+        rc = llog_create(ctxt, &llh, NULL, name);
+        if (rc) {
+                CERROR("1a: llog_create with name %s failed: %d\n", name, rc);
+                RETURN(rc);
+        }
+        llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid);
+
+        if ((rc = verify_handle("1", llh, 1)))
+                GOTO(out, rc);
+
+ out:
+        CERROR("1b: close newly-created log\n");
+        rc2 = llog_close(llh);
+        if (rc2) {
+                CERROR("1b: close log %s failed: %d\n", name, rc2);
+                if (rc == 0)
+                        rc = rc2;
+        }
+        RETURN(rc);
+}
+
+/* Test named-log reopen; returns opened log on success */
+static int llog_test_2(struct obd_device *obd, char *name,
+                       struct llog_handle **llh)
+{
+        struct llog_handle *loghandle;
+        struct llog_logid logid;
+        int rc;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+        ENTRY;
+
+        CERROR("2a: re-open a log with name: %s\n", name);
+        rc = llog_create(ctxt, llh, NULL, name);
+        if (rc) {
+                CERROR("2a: re-open log with name %s failed: %d\n", name, rc);
+                RETURN(rc);
+        }
+        llog_init_handle(*llh, LLOG_F_IS_PLAIN, &uuid);
+
+        if ((rc = verify_handle("2", *llh, 1)))
+                RETURN(rc);
+
+        CERROR("2b: create a log without specified NAME & LOGID\n");
+        rc = llog_create(ctxt, &loghandle, NULL, NULL);
+        if (rc) {
+                CERROR("2b: create log failed\n");
+                RETURN(rc);
+        }
+        llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid);
+        logid = loghandle->lgh_id;
+        llog_close(loghandle);
+
+        CERROR("2b: re-open the log by LOGID\n");
+        rc = llog_create(ctxt, &loghandle, &logid, NULL);
+        if (rc) {
+                CERROR("2b: re-open log by LOGID failed\n");
+                RETURN(rc);
+        }
+        llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid);
+
+        CERROR("2b: destroy this log\n");
+        rc = llog_destroy(loghandle);
+        if (rc) {
+                CERROR("2b: destroy log failed\n");
+                RETURN(rc);
+        }
+        llog_free_handle(loghandle);
+
+        RETURN(rc);
+}
+
+/* Test record writing, single and in bulk */
+static int llog_test_3(struct obd_device *obd, struct llog_handle *llh)
+{
+        struct llog_create_rec lcr;
+        int rc, i;
+        int num_recs = 1;       /* 1 for the header */
+        ENTRY;
+
+        lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = cpu_to_le32(sizeof(lcr));
+        lcr.lcr_hdr.lrh_type = cpu_to_le32(OST_SZ_REC);
+
+        CERROR("3a: write one create_rec\n");
+        rc = llog_write_rec(llh,  &lcr.lcr_hdr, NULL, 0, NULL, -1);
+        num_recs++;
+        if (rc) {
+                CERROR("3a: write one log record failed: %d\n", rc);
+                RETURN(rc);
+        }
+
+        if ((rc = verify_handle("3a", llh, num_recs)))
+                RETURN(rc);
+
+        CERROR("3b: write 10 cfg log records with 8 bytes bufs\n");
+        for (i = 0; i < 10; i++) {
+                struct llog_rec_hdr hdr;
+                char buf[8];
+                hdr.lrh_len = cpu_to_le32(8);
+                hdr.lrh_type = cpu_to_le32(OBD_CFG_REC);
+                memset(buf, 0, sizeof buf);
+                rc = llog_write_rec(llh, &hdr, NULL, 0, buf, -1);
+                if (rc) {
+                        CERROR("3b: write 10 records failed at #%d: %d\n",
+                               i + 1, rc);
+                        RETURN(rc);
+                }
+                num_recs++;
+                if ((rc = verify_handle("3c", llh, num_recs)))
+                        RETURN(rc);
+        }
+
+        if ((rc = verify_handle("3b", llh, num_recs)))
+                RETURN(rc);
+
+        CERROR("3c: write 1000 more log records\n");
+        for (i = 0; i < 1000; i++) {
+                rc = llog_write_rec(llh, &lcr.lcr_hdr, NULL, 0, NULL, -1);
+                if (rc) {
+                        CERROR("3c: write 1000 records failed at #%d: %d\n",
+                               i + 1, rc);
+                        RETURN(rc);
+                }
+                num_recs++;
+                if ((rc = verify_handle("3b", llh, num_recs)))
+                        RETURN(rc);
+        }
+
+        if ((rc = verify_handle("3c", llh, num_recs)))
+                RETURN(rc);
+
+        RETURN(rc);
+}
+
+/* Test catalogue additions */
+static int llog_test_4(struct obd_device *obd)
+{
+        struct llog_handle *cath;
+        char name[10];
+        int rc, i, buflen;
+        struct llog_mini_rec lmr;
+        struct llog_cookie cookie;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+        int num_recs = 0;
+        char *buf;
+        struct llog_rec_hdr rec;
+
+        ENTRY;
+
+        lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len =
+                cpu_to_le32(LLOG_MIN_REC_SIZE);
+        lmr.lmr_hdr.lrh_type = cpu_to_le32(0xf00f00);
+
+        sprintf(name, "%x", llog_test_rand+1);
+        CERROR("4a: create a catalog log with name: %s\n", name);
+        rc = llog_create(ctxt, &cath, NULL, name);
+        if (rc) {
+                CERROR("1a: llog_create with name %s failed: %d\n", name, rc);
+                GOTO(out, rc);
+        }
+        llog_init_handle(cath, LLOG_F_IS_CAT, &uuid);
+        num_recs++;
+        cat_logid = cath->lgh_id;
+
+        CERROR("4b: write 1 record into the catalog\n");
+        rc = llog_cat_add_rec(cath, &lmr.lmr_hdr, &cookie, NULL);
+        if (rc != 1) {
+                CERROR("4b: write 1 catalog record failed at: %d\n", rc);
+                GOTO(out, rc);
+        }
+        num_recs++;
+        if ((rc = verify_handle("4b", cath, 2)))
+                RETURN(rc);
+
+        if ((rc = verify_handle("4b", cath->u.chd.chd_current_log, num_recs)))
+                RETURN(rc);
+
+        CERROR("4c: cancel 1 log record\n");
+        rc = llog_cat_cancel_records(cath, 1, &cookie);
+        if (rc) {
+                CERROR("4c: cancel 1 catalog based record failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+        num_recs--;
+
+        if ((rc = verify_handle("4c", cath->u.chd.chd_current_log, num_recs)))
+                RETURN(rc);
+
+        CERROR("4d: write 40,000 more log records\n");
+        for (i = 0; i < 40000; i++) {
+                rc = llog_cat_add_rec(cath, &lmr.lmr_hdr, NULL, NULL);
+                if (rc) {
+                        CERROR("4d: write 40000 records failed at #%d: %d\n",
+                               i + 1, rc);
+                        GOTO(out, rc);
+                }
+                num_recs++;
+        }
+
+        CERROR("4e: add 5 large records, one record per block\n");
+        buflen = LLOG_CHUNK_SIZE - sizeof(struct llog_rec_hdr)
+                        - sizeof(struct llog_rec_tail);
+        OBD_ALLOC(buf, buflen);
+        if (buf == NULL)
+                GOTO(out, rc = -ENOMEM);
+        for (i = 0; i < 5; i++) {
+                rec.lrh_len = cpu_to_le32(buflen);
+                rec.lrh_type = cpu_to_le32(OBD_CFG_REC);
+                rc = llog_cat_add_rec(cath, &rec, NULL, buf);
+                if (rc) {
+                        CERROR("4e: write 5 records failed at #%d: %d\n",
+                               i + 1, rc);
+                        OBD_FREE(buf, buflen);
+                        GOTO(out, rc);
+                }
+                num_recs++;
+        }
+        OBD_FREE(buf, buflen);
+
+ out:
+        CERROR("4f: put newly-created catalog\n");
+        rc = llog_cat_put(cath);
+        if (rc)
+                CERROR("1b: close log %s failed: %d\n", name, rc);
+        RETURN(rc);
+}
+
+static int cat_print_cb(struct llog_handle *llh, struct llog_rec_hdr *rec,
+                        void *data)
+{
+        struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
+
+        if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
+                CERROR("invalid record in catalog\n");
+                RETURN(-EINVAL);
+        }
+
+        CERROR("seeing record at index %d - "LPX64":%x in log "LPX64"\n",
+               le32_to_cpu(rec->lrh_index), lir->lid_id.lgl_oid,
+               lir->lid_id.lgl_ogen, llh->lgh_id.lgl_oid);
+        RETURN(0);
+}
+
+static int plain_print_cb(struct llog_handle *llh, struct llog_rec_hdr *rec,
+                          void *data)
+{
+        if (!le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN) {
+                CERROR("log is not plain\n");
+                RETURN(-EINVAL);
+        }
+
+        CERROR("seeing record at index %d in log "LPX64"\n",
+               le32_to_cpu(rec->lrh_index), llh->lgh_id.lgl_oid);
+        RETURN(0);
+}
+
+static int llog_cancel_rec_cb(struct llog_handle *llh, struct llog_rec_hdr *rec,
+                              void *data)
+{
+        struct llog_cookie cookie;
+        static int i = 0;
+
+        if (!le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN) {
+                CERROR("log is not plain\n");
+                RETURN(-EINVAL);
+        }
+
+        cookie.lgc_lgl = llh->lgh_id;
+        cookie.lgc_index = le32_to_cpu(rec->lrh_index);
+
+        llog_cat_cancel_records(llh->u.phd.phd_cat_handle, 1, &cookie);
+        i++;
+        if (i == 40000)
+                RETURN(-4711);
+        RETURN(0);
+}
+
+
+
+/* Test log and catalogue processing */
+static int llog_test_5(struct obd_device *obd)
+{
+        struct llog_handle *llh = NULL;
+        char name[10];
+        int rc;
+        struct llog_mini_rec lmr;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+
+        ENTRY;
+
+        lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len =
+                cpu_to_le32(LLOG_MIN_REC_SIZE);
+        lmr.lmr_hdr.lrh_type = cpu_to_le32(0xf00f00);
+
+        CERROR("5a: re-open catalog by id\n");
+        rc = llog_create(ctxt, &llh, &cat_logid, NULL);
+        if (rc) {
+                CERROR("5a: llog_create with logid failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+        llog_init_handle(llh, LLOG_F_IS_CAT, &uuid);
+
+        CERROR("5b: print the catalog entries.. we expect 2\n");
+        rc = llog_process(llh, (llog_cb_t)cat_print_cb, "test 5");
+        if (rc) {
+                CERROR("5b: process with cat_print_cb failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+        CERROR("5c: Cancel 40000 records, see one log zapped\n");
+        rc = llog_cat_process(llh, llog_cancel_rec_cb, "foobar");
+        if (rc != -4711) {
+                CERROR("5c: process with cat_cancel_cb failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+        CERROR("5d: add 1 record to the log with many canceled empty pages\n");
+        rc = llog_cat_add_rec(llh, &lmr.lmr_hdr, NULL, NULL);
+        if (rc) {
+                CERROR("5d: add record to the log with many canceled empty\
+                       pages failed\n");
+                GOTO(out, rc);
+        }
+
+        CERROR("5b: print the catalog entries.. we expect 1\n");
+        rc = llog_process(llh, (llog_cb_t)cat_print_cb, "test 5");
+        if (rc) {
+                CERROR("5b: process with cat_print_cb failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+        CERROR("5e: print plain log entries.. expect 6\n");
+        rc = llog_cat_process(llh, plain_print_cb, "foobar");
+        if (rc) {
+                CERROR("5e: process with plain_print_cb failed: %d\n", rc);
+                GOTO(out, rc);
+        }
+
+ out:
+        CERROR("5: close re-opened catalog\n");
+        if (llh)
+                rc = llog_cat_put(llh);
+        if (rc)
+                CERROR("1b: close log %s failed: %d\n", name, rc);
+        RETURN(rc);
+}
+
+/* Test client api; open log by name and process */
+static int llog_test_6(struct obd_device *obd, char *name)
+{
+        struct obd_device *mdc_obd;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+        struct obd_uuid *mds_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;
+        struct lustre_handle exph = {0, };
+        struct obd_export *exp;
+        struct obd_uuid uuid = {"LLOG_TEST6_UUID"};
+        struct llog_handle *llh = NULL;
+        struct llog_ctxt *nctxt;
+        int rc;
+
+        CERROR("6a: re-open log %s using client API\n", name);
+        mdc_obd = class_find_client_obd(mds_uuid, LUSTRE_MDC_NAME, NULL);
+        if (mdc_obd == NULL) {
+                CERROR("6: no MDC devices connected to %s found.\n",
+                       mds_uuid->uuid);
+                RETURN(-ENOENT);
+        }
+
+        rc = obd_connect(&exph, mdc_obd, &uuid);
+        if (rc) {
+                CERROR("6: failed to connect to MDC: %s\n", mdc_obd->obd_name);
+                RETURN(rc);
+        }
+        exp = class_conn2export(&exph);
+
+        nctxt = llog_get_context(mdc_obd, LLOG_CONFIG_REPL_CTXT);
+        rc = llog_create(nctxt, &llh, NULL, name);
+        if (rc) {
+                CERROR("6: llog_create failed %d\n", rc);
+                RETURN(rc);
+        }
+
+        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
+        if (rc) {
+                CERROR("6: llog_init_handle failed %d\n", rc);
+                GOTO(parse_out, rc);
+        }
+
+        rc = llog_process(llh, (llog_cb_t)plain_print_cb, NULL);
+        if (rc)
+                CERROR("6: llog_process failed %d\n", rc);
+
+parse_out:
+        rc = llog_close(llh);
+        if (rc) {
+                CERROR("6: llog_close failed: rc = %d\n", rc);
+        }
+
+        rc = obd_disconnect(exp, 0);
+
+        RETURN(rc);
+}
+
+/* -------------------------------------------------------------------------
+ * Tests above, boring obd functions below
+ * ------------------------------------------------------------------------- */
+static int llog_run_tests(struct obd_device *obd)
+{
+        struct llog_handle *llh;
+        struct obd_run_ctxt saved;
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
+        int rc, err, cleanup_phase = 0;
+        char name[10];
+        ENTRY;
+
+        sprintf(name, "%x", llog_test_rand);
+        push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+
+        rc = llog_test_1(obd, name);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        rc = llog_test_2(obd, name, &llh);
+        if (rc)
+                GOTO(cleanup, rc);
+        cleanup_phase = 1; /* close llh */
+
+        rc = llog_test_3(obd, llh);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        rc = llog_test_4(obd);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        rc = llog_test_5(obd);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        rc = llog_test_6(obd, name);
+        if (rc)
+                GOTO(cleanup, rc);
+
+ cleanup:
+        switch (cleanup_phase) {
+        case 1:
+                err = llog_close(llh);
+                if (err)
+                        CERROR("cleanup: llog_close failed: %d\n", err);
+                if (!rc)
+                        rc = err;
+        case 0:
+                pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+        }
+
+        return rc;
+}
+
+
+static int llog_test_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                               int count, struct llog_logid *logid)
+{
+        int rc;
+        ENTRY;
+
+        rc = llog_setup(obd, LLOG_TEST_ORIG_CTXT, tgt, 0, NULL, &llog_lvfs_ops);
+        RETURN(rc);
+}
+
+static int llog_test_llog_finish(struct obd_device *obd, int count)
+{
+        int rc;
+        ENTRY;
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_TEST_ORIG_CTXT));
+        RETURN(rc);
+}
+
+static int llog_test_cleanup(struct obd_device *obd, int flags)
+{
+        int rc = obd_llog_finish(obd, 0);
+        if (rc)
+                CERROR("failed to llog_test_llog_finish: %d\n", rc);
+
+        return rc;
+}
+
+static int llog_test_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct lustre_cfg *lcfg = buf;
+        struct obd_device *tgt;
+        int rc;
+        ENTRY;
+
+        if (lcfg->lcfg_inllen1 < 1) {
+                CERROR("requires a TARGET OBD name\n");
+                RETURN(-EINVAL);
+        }
+
+        tgt = class_name2obd(lcfg->lcfg_inlbuf1);
+        if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
+                CERROR("target device not attached or not set up (%s)\n",
+                       lcfg->lcfg_inlbuf1);
+                RETURN(-EINVAL);
+        }
+
+        rc = obd_llog_init(obd, tgt, 0, NULL);
+        if (rc)
+                RETURN(rc);
+
+        llog_test_rand = ll_insecure_random_int();
+
+        rc = llog_run_tests(obd);
+        if (rc)
+                llog_test_cleanup(obd, 0);
+        RETURN(rc);
+}
+
+static int llog_test_attach(struct obd_device *dev, obd_count len, void *data)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(ost, &lvars);
+        return lprocfs_obd_attach(dev, lvars.obd_vars);
+}
+
+static int llog_test_detach(struct obd_device *dev)
+{
+        return lprocfs_obd_detach(dev);
+}
+
+static struct obd_ops llog_obd_ops = {
+        o_owner:       THIS_MODULE,
+        o_attach:      llog_test_attach,
+        o_detach:      llog_test_detach,
+        o_setup:       llog_test_setup,
+        o_cleanup:     llog_test_cleanup,
+        o_llog_init:   llog_test_llog_init,
+        o_llog_finish: llog_test_llog_finish,
+
+};
+
+static int __init llog_test_init(void)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_multi_vars(0, &lvars);
+        return class_register_type(&llog_obd_ops,lvars.module_vars,"llog_test");
+}
+
+static void __exit llog_test_exit(void)
+{
+        class_unregister_type("llog_test");
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("llog test module");
+MODULE_LICENSE("GPL");
+
+module_init(llog_test_init);
+module_exit(llog_test_exit);
diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c
index bb48e5d5d66d72aec0d0f03c1031958d5e736c66..ecb747e9443353f6dd37cfc53a33b5bf16f7b93a 100644
--- a/lustre/obdclass/lprocfs_status.c
+++ b/lustre/obdclass/lprocfs_status.c
@@ -20,7 +20,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_CLASS
 
 #ifdef __KERNEL__
@@ -41,7 +43,7 @@
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_fsfilt.h>
 
-#ifdef LPROCFS
+#if defined(LPROCFS) && defined(__KERNEL__)
 
 struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
                                     const char *name)
@@ -101,9 +103,11 @@ int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
                                 cur_root = (proc ? proc :
                                             proc_mkdir(cur, cur_root));
                         } else if (proc == NULL) {
-                                mode_t mode = 0444;
+                                mode_t mode = 0;
+                                if (list->read_fptr)
+                                        mode = 0444;
                                 if (list->write_fptr)
-                                        mode = 0644;
+                                        mode |= 0200;
                                 proc = create_proc_entry(cur, mode, cur_root);
                         }
                 }
@@ -297,13 +301,20 @@ int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
                            int *eof, void *data)
 {
         struct obd_device *obd = (struct obd_device *)data;
-        struct client_obd *cli;
-
+        struct obd_import *imp;
+        static char* import_state_names[] = {
+                "<UNKNOWN 0>", "INVALID", "NEW", "DISCONN", "CONNECTING",
+                "REPLAY", "RECOVER", "FULL", "EVICTED",
+        };
+        char *imp_state_name = NULL;
+        
         LASSERT(obd != NULL);
-        cli = &obd->u.cli;
+        imp = obd->u.cli.cl_import;
+        LASSERT(imp->imp_state <= LUSTRE_IMP_EVICTED);
+        imp_state_name = import_state_names[imp->imp_state];
         *eof = 1;
-        return snprintf(page, count, "%s\n",
-                        cli->cl_import->imp_target_uuid.uuid);
+        return snprintf(page, count, "%s\t%s\n",
+                        imp->imp_target_uuid.uuid, imp_state_name);
 }
 
 int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
@@ -562,7 +573,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LASSERT(obd->obd_proc_entry != NULL);
         LASSERT(obd->obd_cntr_base == 0);
 
-        num_stats = 1 + OBD_COUNTER_OFFSET(unpin) +
+        num_stats = 1 + OBD_COUNTER_OFFSET(notify) +
                 num_private_stats;
         stats = lprocfs_alloc_stats(num_stats);
         if (stats == NULL)
@@ -574,11 +585,13 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, postsetup);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, syncfs);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
@@ -587,10 +600,14 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, open);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, close);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw_async);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, prep_async_page);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_async_io);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_async_flags);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_sync_io);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_sync_io);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, teardown_async_page);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
@@ -600,18 +617,20 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, match);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, log_add);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, log_cancel);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, san_preprw);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, mark_page_dirty);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, clear_dirty_pages);
-        LPROCFS_OBD_OP_INIT(num_private_stats, stats, last_dirty_offset);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, lock_contains);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init); 
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish); 
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin); 
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
-
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, invalidate_import);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
+        
         for (i = num_private_stats; i < num_stats; i++) {
                 /* If this LBUGs, it is likely that an obd
                  * operation was added to struct obd_ops in
@@ -645,6 +664,27 @@ void lprocfs_free_obd_stats(struct obd_device *obd)
         }
 }
 
+int lprocfs_write_helper(const char *buffer, unsigned long count,
+                         int *val)
+{
+        char kernbuf[20], *end;
+        
+        if (count > (sizeof(kernbuf) - 1))
+                return -EINVAL;
+
+        if (copy_from_user(kernbuf, buffer, count))
+                return -EFAULT;
+
+        kernbuf[count] = '\0';
+
+        *val = simple_strtol(kernbuf, &end, 0);
+        if (kernbuf == end)
+                return -EINVAL;
+
+        return 0;
+}
+
+
 #endif /* LPROCFS*/
 
 EXPORT_SYMBOL(lprocfs_register);
@@ -673,3 +713,5 @@ EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
 EXPORT_SYMBOL(lprocfs_rd_filestotal);
 EXPORT_SYMBOL(lprocfs_rd_filesfree);
 EXPORT_SYMBOL(lprocfs_rd_filegroups);
+
+EXPORT_SYMBOL(lprocfs_write_helper);
diff --git a/lustre/obdclass/lustre_handles.c b/lustre/obdclass/lustre_handles.c
index bc07df91b3d91a8c8101d5b8f99fa5413c5cd106..2339f28d18936c3666e736912c79233697d612b3 100644
--- a/lustre/obdclass/lustre_handles.c
+++ b/lustre/obdclass/lustre_handles.c
@@ -32,7 +32,8 @@
 #include <linux/lustre_handles.h>
 
 static spinlock_t handle_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t random_lock = SPIN_LOCK_UNLOCKED;
+static __u64 handle_base;
+#define HANDLE_INCR 7
 static struct list_head *handle_hash = NULL;
 static int handle_count = 0;
 
@@ -47,16 +48,13 @@ void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb)
         LASSERT(h != NULL);
         LASSERT(list_empty(&h->h_link));
 
-        /* My hypothesis is that get_random_bytes, if called from two threads at
-         * the same time, will return the same bytes. -phil */
-        spin_lock(&random_lock);
-        get_random_bytes(&h->h_cookie, sizeof(h->h_cookie));
-        spin_unlock(&random_lock);
+        spin_lock(&handle_lock);
+        h->h_cookie = handle_base;
+        handle_base += HANDLE_INCR;
+        spin_unlock(&handle_lock);
 
         h->h_addref = cb;
-
         bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK);
-
         CDEBUG(D_INFO, "adding object %p with handle "LPX64" to hash\n",
                h, h->h_cookie);
 
@@ -69,7 +67,11 @@ void class_handle_hash(struct portals_handle *h, portals_handle_addref_cb cb)
 
 static void class_handle_unhash_nolock(struct portals_handle *h)
 {
-        LASSERT(!list_empty(&h->h_link));
+        if (list_empty(&h->h_link)) {
+                CERROR("removing an already-removed handle ("LPX64")\n",
+                       h->h_cookie);
+                return;
+        }
 
         CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n",
                h, h->h_cookie);
@@ -93,9 +95,9 @@ void *class_handle2object(__u64 cookie)
 
         LASSERT(handle_hash != NULL);
 
-        spin_lock(&handle_lock);
         bucket = handle_hash + (cookie & HANDLE_HASH_MASK);
 
+        spin_lock(&handle_lock);
         list_for_each(tmp, bucket) {
                 struct portals_handle *h;
                 h = list_entry(tmp, struct portals_handle, h_link);
@@ -125,6 +127,9 @@ int class_handle_init(void)
              bucket--)
                 INIT_LIST_HEAD(bucket);
 
+        get_random_bytes(&handle_base, sizeof(handle_base));
+        LASSERT(handle_base != 0ULL);
+
         return 0;
 }
 
diff --git a/lustre/obdclass/lustre_peer.c b/lustre/obdclass/lustre_peer.c
index 5987d2e98ff376708593d7adc3872f6c29bf490c..bbe334012591805007ef06c29e7c8c0336afc1dd 100644
--- a/lustre/obdclass/lustre_peer.c
+++ b/lustre/obdclass/lustre_peer.c
@@ -57,16 +57,8 @@ void class_init_uuidlist(void)
 
 void class_exit_uuidlist(void)
 {
-        struct list_head *tmp, *n;
-
-        /* Module going => sole user => don't need to lock g_uuid_list */
-        list_for_each_safe(tmp, n, &g_uuid_list) {
-                struct uuid_nid_data *data =
-                        list_entry(tmp, struct uuid_nid_data, head);
-
-                OBD_FREE(data->uuid, strlen(data->uuid) + 1);
-                OBD_FREE(data, sizeof(*data));
-        }
+        /* delete all */
+        class_del_uuid(NULL);
 }
 
 int lustre_uuid_to_peer(char *uuid, struct lustre_peer *peer)
@@ -117,6 +109,7 @@ int class_add_uuid(char *uuid, __u64 nid, __u32 nal)
         if (data == NULL)
                 goto fail_1;
 
+        CDEBUG(D_INFO, "add uuid %s "LPX64" %u\n", uuid, nid, nal);
         memcpy(data->uuid, uuid, nob);
         data->nid = nid;
         data->nal = nal;
diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..d34dffceab59496df9d3e78bfaf496548c495a55
--- /dev/null
+++ b/lustre/obdclass/obd_config.c
@@ -0,0 +1,732 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Config API
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_CLASS
+#ifdef __KERNEL__
+#include <linux/kmod.h>   /* for request_module() */
+#include <linux/module.h>
+#include <linux/obd_class.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#else 
+#include <liblustre.h>
+#include <linux/obd_class.h>
+#include <linux/obd.h>
+#endif
+#include <linux/lustre_log.h>
+#include <linux/lprocfs_status.h>
+#include <portals/list.h>
+
+
+/* Create a new device and set the type, name and uuid.  If
+ * successful, the new device can be accessed by either name or uuid.
+ */
+int class_attach(struct lustre_cfg *lcfg)
+{
+        int minor;
+        struct obd_type *type;
+        int err = 0;
+        int len;
+	char *typename;
+	char *name;
+	char *uuid;
+	struct obd_device *obd;
+	int dev;
+                 
+	if (!lcfg->lcfg_inllen1 || !lcfg->lcfg_inlbuf1) {
+		CERROR("No type passed!\n");
+		RETURN(-EINVAL);
+	}
+	if (lcfg->lcfg_inlbuf1[lcfg->lcfg_inllen1 - 1] != 0) {
+		CERROR("Type not nul terminated!\n");
+		RETURN(-EINVAL);
+	}
+	typename = lcfg->lcfg_inlbuf1;
+
+	if (!lcfg->lcfg_dev_namelen || !lcfg->lcfg_dev_name) {
+		CERROR("No name passed!\n");
+		RETURN(-EINVAL);
+	}
+	if (lcfg->lcfg_dev_name[lcfg->lcfg_dev_namelen - 1] != 0) {
+		CERROR("Name not nul terminated!\n");
+		RETURN(-EINVAL);
+	}
+	name = lcfg->lcfg_dev_name;
+
+	if (!lcfg->lcfg_inllen2 || !lcfg->lcfg_inlbuf2) {
+		CERROR("No UUID passed!\n");
+		RETURN(-EINVAL);
+	}
+	if (lcfg->lcfg_inlbuf2[lcfg->lcfg_inllen2 - 1] != 0) {
+		CERROR("UUID not nul terminated!\n");
+		RETURN(-EINVAL);
+	}
+	uuid = lcfg->lcfg_inlbuf2;
+
+	CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
+	       MKSTR(lcfg->lcfg_inlbuf1),
+	       MKSTR(lcfg->lcfg_dev_name), MKSTR(lcfg->lcfg_inlbuf2));
+
+        /* find the type */
+        type = class_get_type(typename);
+        if (!type) {
+                CERROR("OBD: unknown type: %s\n", typename);
+                RETURN(-EINVAL);
+        }
+        
+        obd = class_name2obd(name);
+        if (obd != NULL) {
+                CERROR("obd %s already attached\n", name);
+                RETURN(-EEXIST);
+        }
+
+	obd = class_newdev(&dev);
+	if (obd == NULL)
+		RETURN(-EINVAL);
+
+	/* have we attached a type to this device */
+	if (obd->obd_attached || obd->obd_type) {
+		CERROR("OBD: Device %d already typed as %s.\n",
+		       obd->obd_minor, MKSTR(obd->obd_type->typ_name));
+		RETURN(-EBUSY);
+	}
+
+        LASSERT(obd == (obd_dev + obd->obd_minor));
+
+        minor = obd->obd_minor;
+        memset(obd, 0, sizeof(*obd));
+        obd->obd_minor = minor;
+        obd->obd_type = type;
+        INIT_LIST_HEAD(&obd->obd_exports);
+        obd->obd_num_exports = 0;
+        spin_lock_init(&obd->obd_dev_lock);
+        init_waitqueue_head(&obd->obd_refcount_waitq);
+        
+        /* XXX belongs in setup not attach  */
+        /* recovery data */
+        spin_lock_init(&obd->obd_processing_task_lock);
+        init_waitqueue_head(&obd->obd_next_transno_waitq);
+        INIT_LIST_HEAD(&obd->obd_recovery_queue);
+        INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
+        
+        init_waitqueue_head(&obd->obd_commit_waitq);
+        
+        len = strlen(name) + 1;
+        OBD_ALLOC(obd->obd_name, len);
+        if (!obd->obd_name) {
+                class_put_type(obd->obd_type);
+                obd->obd_type = NULL;
+                RETURN(-ENOMEM);
+        }
+        memcpy(obd->obd_name, name, len);
+        
+        len = strlen(uuid);
+        if (len >= sizeof(obd->obd_uuid)) {
+                CERROR("uuid must be < "LPSZ" bytes long\n",
+                       sizeof(obd->obd_uuid));
+                OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
+                class_put_type(obd->obd_type);
+                obd->obd_type = NULL;
+                RETURN(-EINVAL);
+        }
+        memcpy(obd->obd_uuid.uuid, uuid, len);
+
+        /* do the attach */
+        if (OBP(obd, attach))
+                err = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
+
+        if (err) {
+                OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
+                class_put_type(obd->obd_type);
+                obd->obd_type = NULL;
+        } else {
+                obd->obd_attached = 1;
+                type->typ_refcnt++;
+                CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
+                       obd->obd_minor, typename);
+        }
+        RETURN(err);
+}
+
+int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
+{
+        int err = 0;
+        struct obd_export *exp;
+        ENTRY;
+
+        LASSERT(obd == (obd_dev + obd->obd_minor));
+
+        /* have we attached a type to this device? */
+        if (!obd->obd_attached) {
+                CERROR("Device %d not attached\n", obd->obd_minor);
+                RETURN(-ENODEV);
+        }
+
+        /* has this been done already? */
+        if (obd->obd_set_up) {
+                CERROR("Device %d already setup (type %s)\n",
+                       obd->obd_minor, obd->obd_type->typ_name);
+                RETURN(-EBUSY);
+        }
+
+        atomic_set(&obd->obd_refcount, 0);
+
+        err = obd_setup(obd, sizeof(*lcfg), lcfg);
+        if (err) {
+                RETURN(err);
+        }
+        
+        obd->obd_type->typ_refcnt++;
+        obd->obd_set_up = 1;
+
+        exp = class_new_export(obd);
+        if (exp == NULL) {
+                GOTO(err_cleanup, err = -ENOMEM);
+        }
+        memcpy(&exp->exp_client_uuid, &obd->obd_uuid, 
+               sizeof(exp->exp_client_uuid));
+        obd->obd_self_export = exp;
+        class_export_put(exp);
+
+        if (OBT(obd) && OBP(obd, postsetup)) {
+                err = obd_postsetup(obd);
+                if (err) 
+                        GOTO(err_exp, err);
+        } 
+
+        RETURN(err);
+
+err_exp:
+        class_unlink_export(obd->obd_self_export);
+        obd->obd_self_export = NULL;
+err_cleanup:
+        obd->obd_stopping = 1;
+        obd_cleanup(obd, 0);
+        obd->obd_set_up = obd->obd_stopping = 0;
+        obd->obd_type->typ_refcnt--;
+        RETURN(err);
+}
+
+int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
+{
+        int minor;
+        int err = 0;
+
+        ENTRY;
+        if (obd->obd_set_up) {
+                CERROR("OBD device %d still set up\n", obd->obd_minor);
+                RETURN(-EBUSY);
+        }
+        if (!obd->obd_attached) {
+                CERROR("OBD device %d not attached\n", obd->obd_minor);
+                RETURN(-ENODEV);
+        }
+        if (OBP(obd, detach))
+                err = OBP(obd,detach)(obd);
+
+        if (obd->obd_name) {
+                OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
+                obd->obd_name = NULL;
+        } else 
+                CERROR("device %d: no name at detach\n", obd->obd_minor);
+
+        obd->obd_attached = 0;
+        obd->obd_type->typ_refcnt--;
+        class_put_type(obd->obd_type);
+        obd->obd_type = NULL;
+        minor = obd->obd_minor;
+        memset(obd, 0, sizeof(*obd));
+        obd->obd_minor = minor;
+        RETURN(err);
+}
+
+static void dump_exports(struct obd_device *obd)
+{
+        struct obd_export *exp, *n;
+
+        list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
+                CERROR("%s: %p %s %d %d %p\n",
+                       obd->obd_name, exp, exp->exp_client_uuid.uuid,
+                       atomic_read(&exp->exp_refcount),
+                       exp->exp_failed, exp->exp_outstanding_reply );
+        }
+}
+
+int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
+{
+        int flags = 0;
+	int err = 0;
+        char *flag;
+        
+        ENTRY;
+        if (!obd->obd_set_up) {
+                CERROR("Device %d not setup\n", obd->obd_minor);
+                RETURN(-ENODEV);
+        }
+
+        if (lcfg->lcfg_inlbuf1) {
+                for (flag = lcfg->lcfg_inlbuf1; *flag != 0; flag++)
+                        switch (*flag) {
+                        case 'F':
+                                flags |= OBD_OPT_FORCE;
+                                break;
+                        case 'A':
+                                flags |= OBD_OPT_FAILOVER;
+                                break;
+                        default:
+                                CERROR("unrecognised flag '%c'\n",
+                                       *flag);
+                        }
+        }
+
+        /* The one reference that should be remaining is the
+         * obd_self_export */
+        if (atomic_read(&obd->obd_refcount) <= 1 ||
+            flags & OBD_OPT_FORCE) {
+                /* this will stop new connections, and need to
+                   do it before class_disconnect_exports() */
+                obd->obd_stopping = 1;
+        }
+
+        if (atomic_read(&obd->obd_refcount) > 1) {
+                struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
+                                                          NULL, NULL);
+                int rc;
+
+                if (!(flags & OBD_OPT_FORCE)) {
+                        CERROR("OBD device %d (%p) has refcount %d\n",
+                               obd->obd_minor, obd,
+                               atomic_read(&obd->obd_refcount));
+                        dump_exports(obd);
+                        GOTO(out, err = -EBUSY);
+                }
+                class_disconnect_exports(obd, flags);
+                CDEBUG(D_IOCTL,
+                       "%s: waiting for obd refs to go away: %d\n",
+                       obd->obd_name, atomic_read(&obd->obd_refcount));
+
+                rc = l_wait_event(obd->obd_refcount_waitq,
+                                  atomic_read(&obd->obd_refcount) < 2, &lwi);
+                if (rc == 0) {
+                        LASSERT(atomic_read(&obd->obd_refcount) == 1);
+                } else {
+                        CERROR("wait cancelled cleaning anyway. "
+                               "refcount: %d\n",
+                               atomic_read(&obd->obd_refcount));
+                        dump_exports(obd);
+                }
+                CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
+                       obd->obd_name);
+        }
+
+        if (obd->obd_self_export) {
+                err = obd_precleanup(obd, flags);
+                if (err) 
+                        GOTO(out, err);
+                class_unlink_export(obd->obd_self_export);
+                obd->obd_self_export = NULL;
+        }
+
+        err = obd_cleanup(obd, flags);
+out:
+        if (!err) {
+                obd->obd_set_up = obd->obd_stopping = 0;
+                obd->obd_type->typ_refcnt--;
+                /* XXX this should be an LASSERT */
+                if (atomic_read(&obd->obd_refcount) > 0) 
+                        CERROR("%s still has refcount %d after "
+                               "cleanup.\n", obd->obd_name,
+                               atomic_read(&obd->obd_refcount));
+        } 
+
+        RETURN(err);
+
+}
+
+LIST_HEAD(lustre_profile_list);
+
+struct lustre_profile *class_get_profile(char * prof)
+{
+        struct lustre_profile *lprof;
+        
+        list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
+                if (!strcmp(lprof->lp_profile, prof)) {
+                        RETURN(lprof);
+                }
+        }
+        RETURN(NULL);
+}
+
+int class_add_profile(int proflen, char *prof, 
+                      int osclen, char *osc, 
+                      int mdclen, char *mdc)
+{
+        struct lustre_profile *lprof;
+        int err = 0;
+
+        OBD_ALLOC(lprof, sizeof(*lprof));
+        if (lprof == NULL)
+                GOTO(out, err = -ENOMEM);
+        INIT_LIST_HEAD(&lprof->lp_list);
+
+        LASSERT(proflen == (strlen(prof) + 1));
+        OBD_ALLOC(lprof->lp_profile, proflen);
+        if (lprof->lp_profile == NULL)
+                GOTO(out, err = -ENOMEM);
+        memcpy(lprof->lp_profile, prof, proflen);
+        
+        LASSERT(osclen == (strlen(osc) + 1));
+        OBD_ALLOC(lprof->lp_osc, osclen);
+        if (lprof->lp_profile == NULL)
+                GOTO(out, err = -ENOMEM);
+        memcpy(lprof->lp_osc, osc, osclen);
+
+        if (mdclen > 0) {
+                LASSERT(mdclen == (strlen(mdc) + 1));
+                OBD_ALLOC(lprof->lp_mdc, mdclen);
+                if (lprof->lp_mdc == NULL)
+                        GOTO(out, err = -ENOMEM);
+                memcpy(lprof->lp_mdc, mdc, mdclen);
+        }
+
+        list_add(&lprof->lp_list, &lustre_profile_list);
+
+out:
+        RETURN(err);
+}
+
+void class_del_profile(char *prof)
+{
+        struct lustre_profile *lprof;
+        
+        lprof = class_get_profile(prof);
+        if (lprof) {
+                list_del(&lprof->lp_list);
+                OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
+                OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
+                if (lprof->lp_mdc)
+                        OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
+                OBD_FREE(lprof, sizeof *lprof);
+        }
+}
+
+int class_process_config(struct lustre_cfg *lcfg)
+{
+	struct obd_device *obd;
+        char str[PTL_NALFMT_SIZE];
+        int err;
+
+        LASSERT(lcfg && !IS_ERR(lcfg));
+
+        CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
+
+        /* Commands that don't need a device */
+	switch(lcfg->lcfg_command) {
+        case LCFG_ATTACH: {
+                err = class_attach(lcfg);
+                GOTO(out, err);
+        }
+        case LCFG_ADD_UUID: {
+                CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
+                       " (%s), nal %d\n", lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
+                       portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
+                       lcfg->lcfg_nal);
+
+                err = class_add_uuid(lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
+                                     lcfg->lcfg_nal);
+                GOTO(out, err);
+        }
+        case LCFG_DEL_UUID: {
+                CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
+                       lcfg->lcfg_inlbuf1 == NULL ? "<all uuids>" :
+                       lcfg->lcfg_inlbuf1);
+
+                err = class_del_uuid(lcfg->lcfg_inlbuf1);
+                GOTO(out, err);
+        }
+        case LCFG_MOUNTOPT: {
+                CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n", 
+                       lcfg->lcfg_inlbuf1, lcfg->lcfg_inlbuf2, lcfg->lcfg_inlbuf3);
+                /* set these mount options somewhere, so ll_fill_super
+                 * can find them. */
+                err = class_add_profile(lcfg->lcfg_inllen1, lcfg->lcfg_inlbuf1, 
+                                        lcfg->lcfg_inllen2, lcfg->lcfg_inlbuf2, 
+                                        lcfg->lcfg_inllen3, lcfg->lcfg_inlbuf3);
+                GOTO(out, err);
+        }
+        case LCFG_DEL_MOUNTOPT: {
+                CDEBUG(D_IOCTL, "mountopt: profile %s\n", lcfg->lcfg_inlbuf1);
+                /* set these mount options somewhere, so ll_fill_super
+                 * can find them. */
+                class_del_profile(lcfg->lcfg_inlbuf1);
+                GOTO(out, err = 0);
+        }
+        case LCFG_SET_TIMEOUT: {
+                CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n", 
+                       obd_timeout,
+                       lcfg->lcfg_num);
+                obd_timeout = lcfg->lcfg_num;
+                GOTO(out, err = 0);
+        }
+        case LCFG_SET_UPCALL: {
+                CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n", 
+                       lcfg->lcfg_inlbuf1);
+                if (lcfg->lcfg_inllen1 > sizeof obd_lustre_upcall)
+                        GOTO(out, err = -EINVAL);
+                memcpy(obd_lustre_upcall, lcfg->lcfg_inlbuf1, 
+                       lcfg->lcfg_inllen1);
+                GOTO(out, err = 0);
+        }
+	}
+	
+
+	/* Commands that require a device */
+        obd = class_name2obd(lcfg->lcfg_dev_name);
+        if (obd == NULL) {
+                if (lcfg->lcfg_dev_name == NULL) {
+                        CERROR("this lcfg command requires a device name\n");
+                } else {
+                        CERROR("no device for: %s\n", lcfg->lcfg_dev_name);
+                }
+                GOTO(out, err = -EINVAL);
+	}
+	    
+        switch(lcfg->lcfg_command) {
+        case LCFG_SETUP: {
+                err = class_setup(obd, lcfg);
+                GOTO(out, err);
+        }
+        case LCFG_DETACH: {
+                err = class_detach(obd, lcfg);
+                GOTO(out, err = 0);
+        }
+        case LCFG_CLEANUP: {
+                err = class_cleanup(obd, lcfg);
+                GOTO(out, err = 0);
+        }
+        default: { 
+                CERROR("Unknown command: %d\n", lcfg->lcfg_command);
+                GOTO(out, err = -EINVAL);
+
+        }
+	}
+out:
+        RETURN(err);
+}
+	    
+static int class_config_llog_handler(struct llog_handle * handle,
+                                     struct llog_rec_hdr *rec, void *data)
+{
+        struct config_llog_instance *cfg = data;
+        int cfg_len = rec->lrh_len;
+        char *cfg_buf = (char*) (rec + 1);
+        int rc = 0;
+
+        if (rec->lrh_type == OBD_CFG_REC) {
+                char *buf;
+                struct lustre_cfg *lcfg;
+                char *old_name = NULL;
+                int old_len = 0;
+                char *old_uuid = NULL;
+                int old_uuid_len = 0;
+                char *inst_name = NULL;
+                int inst_len = 0;
+
+                rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
+                if (rc) 
+                        GOTO(out, rc);
+                lcfg = (struct lustre_cfg* ) buf;
+
+                if (cfg && cfg->cfg_instance && lcfg->lcfg_dev_name) {
+                        inst_len = strlen(lcfg->lcfg_dev_name) + 
+                                strlen(cfg->cfg_instance) + 2;
+                        OBD_ALLOC(inst_name, inst_len);
+                        if (inst_name == NULL) 
+                                GOTO(out, rc = -ENOMEM);
+                        sprintf(inst_name, "%s-%s", lcfg->lcfg_dev_name, 
+                                cfg->cfg_instance);
+                        old_name = lcfg->lcfg_dev_name;
+                        old_len = lcfg->lcfg_dev_namelen;
+                        lcfg->lcfg_dev_name = inst_name;
+                        lcfg->lcfg_dev_namelen = strlen(inst_name) + 1;
+                }
+                
+                if (cfg && lcfg->lcfg_command == LCFG_ATTACH) {
+                        old_uuid = lcfg->lcfg_inlbuf2;
+                        old_uuid_len = lcfg->lcfg_inllen2;
+
+                        lcfg->lcfg_inlbuf2 = (char*)&cfg->cfg_uuid.uuid;
+                        lcfg->lcfg_inllen2 = sizeof(cfg->cfg_uuid);
+                }
+
+                rc = class_process_config(lcfg);
+
+                if (old_name) {
+                        lcfg->lcfg_dev_name = old_name;
+                        lcfg->lcfg_dev_namelen = old_len;
+                        OBD_FREE(inst_name, inst_len);
+                }
+              
+                if (old_uuid) {
+                        lcfg->lcfg_inlbuf2 = old_uuid;
+                        lcfg->lcfg_inllen2 = old_uuid_len;
+                }
+                
+                lustre_cfg_freedata(buf, cfg_len);
+        } else if (rec->lrh_type == PTL_CFG_REC) {
+                struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
+                if (pcfg->pcfg_command ==NAL_CMD_REGISTER_MYNID &&
+                    cfg->cfg_local_nid != PTL_NID_ANY) {
+                        pcfg->pcfg_nid = cfg->cfg_local_nid;
+                }
+
+                rc = kportal_nal_cmd(pcfg);
+        }
+out:
+        RETURN(rc);
+}
+
+int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, 
+                          struct config_llog_instance *cfg)
+{
+        struct llog_handle *llh;
+        int rc, rc2;
+        ENTRY;
+
+        rc = llog_create(ctxt, &llh, NULL, name);
+        if (rc) 
+                RETURN(rc);
+
+        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
+        if (rc) 
+                GOTO(parse_out, rc);
+
+        rc = llog_process(llh, class_config_llog_handler, cfg);
+parse_out:
+        rc2 = llog_close(llh);
+        if (rc == 0)
+                rc = rc2;
+
+        RETURN(rc);
+
+}
+
+static int class_config_dump_handler(struct llog_handle * handle,
+                                     struct llog_rec_hdr *rec, void *data)
+{
+        int cfg_len = rec->lrh_len;
+        char *cfg_buf = (char*) (rec + 1);
+        int rc = 0;
+
+        if (rec->lrh_type == OBD_CFG_REC) {
+                char *buf;
+                struct lustre_cfg *lcfg;
+
+                rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
+                if (rc) 
+                        GOTO(out, rc);
+                lcfg = (struct lustre_cfg* ) buf;
+                
+                CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
+                if (lcfg->lcfg_dev_name)
+                        CDEBUG(D_INFO, "     devname: %s\n",
+                               lcfg->lcfg_dev_name);
+                if (lcfg->lcfg_flags)
+                        CDEBUG(D_INFO, "       flags: %x\n", lcfg->lcfg_flags);
+                if (lcfg->lcfg_nid)
+                        CDEBUG(D_INFO, "         nid: "LPX64"\n",
+                               lcfg->lcfg_nid);
+                if (lcfg->lcfg_nal)
+                        CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_nal);
+                if (lcfg->lcfg_num)
+                        CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_num);
+                if (lcfg->lcfg_inlbuf1)
+                        CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf1);
+                if (lcfg->lcfg_inlbuf2)
+                        CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf2);
+                if (lcfg->lcfg_inlbuf3)
+                        CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf3);
+                if (lcfg->lcfg_inlbuf4)
+                        CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf4);
+
+                lustre_cfg_freedata(buf, cfg_len);
+        } else if (rec->lrh_type == PTL_CFG_REC) {
+                struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
+
+                CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
+                if (pcfg->pcfg_nal)
+                        CDEBUG(D_INFO, "         nal: %d\n",
+                               pcfg->pcfg_nal);
+                if (pcfg->pcfg_gw_nal)
+                        CDEBUG(D_INFO, "      gw_nal: %d\n",
+                               pcfg->pcfg_gw_nal);
+                if (pcfg->pcfg_nid)
+                        CDEBUG(D_INFO, "         nid: "LPX64"\n",
+                               pcfg->pcfg_nid);
+                if (pcfg->pcfg_nid2)
+                        CDEBUG(D_INFO, "         nid: "LPX64"\n",
+                               pcfg->pcfg_nid2);
+                if (pcfg->pcfg_nid3)
+                        CDEBUG(D_INFO, "         nid: "LPX64"\n",
+                               pcfg->pcfg_nid3);
+                if (pcfg->pcfg_misc)
+                        CDEBUG(D_INFO, "         nid: %d\n",
+                               pcfg->pcfg_misc);
+                if (pcfg->pcfg_id)
+                        CDEBUG(D_INFO, "          id: %x\n",
+                               pcfg->pcfg_id);
+                if (pcfg->pcfg_flags)
+                        CDEBUG(D_INFO, "       flags: %x\n",
+                               pcfg->pcfg_flags);
+        }
+out:
+        RETURN(rc);
+}
+
+int class_config_dump_llog(struct llog_ctxt *ctxt, char *name, 
+                          struct config_llog_instance *cfg)
+{
+        struct llog_handle *llh;
+        int rc, rc2;
+        ENTRY;
+
+        rc = llog_create(ctxt, &llh, NULL, name);
+        if (rc) 
+                RETURN(rc);
+
+        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
+        if (rc) 
+                GOTO(parse_out, rc);
+
+        rc = llog_process(llh, class_config_dump_handler, cfg);
+parse_out:
+        rc2 = llog_close(llh);
+        if (rc == 0)
+                rc = rc2;
+
+        RETURN(rc);
+
+}
+
diff --git a/lustre/obdclass/obdo.c b/lustre/obdclass/obdo.c
index 6481121ee4eab0a8fd704ea2b28dd08ae981e4bb..996ef58d4ccf3b2940e9fb5f35106cab19d0c0b9 100644
--- a/lustre/obdclass/obdo.c
+++ b/lustre/obdclass/obdo.c
@@ -25,14 +25,21 @@
  */
 
 #define DEBUG_SUBSYSTEM S_CLASS
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
+#ifndef __KERNEL__
+#include <liblustre.h>
+#else
 #include <linux/module.h>
 #include <linux/obd_class.h>
 #include <linux/lustre_idl.h>
+#endif
 
 #ifdef __KERNEL__
 #include <linux/fs.h>
+#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */
 
 void obdo_from_iattr(struct obdo *oa, struct iattr *attr, unsigned int ia_valid)
 {
@@ -114,6 +121,10 @@ void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid)
                 attr->ia_gid = oa->o_gid;
                 attr->ia_valid |= ATTR_GID;
         }
+        if (valid & OBD_MD_FLFLAGS) {
+                attr->ia_attr_flags = oa->o_flags;
+                attr->ia_valid |= ATTR_ATTR_FLAG;
+        }
 }
 EXPORT_SYMBOL(iattr_from_obdo);
 
@@ -125,7 +136,8 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
 
         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
                 CDEBUG(D_INODE, "valid %x, new time %lu/%lu\n",
-                       valid, src->i_mtime, src->i_ctime);
+                       valid, LTIME_S(src->i_mtime), 
+                       LTIME_S(src->i_ctime));
 
         if (valid & OBD_MD_FLATIME) {
                 dst->o_atime = LTIME_S(src->i_atime);
@@ -180,7 +192,11 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid)
                 newvalid |= OBD_MD_FLGENER;
         }
         if (valid & OBD_MD_FLRDEV) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
                 dst->o_rdev = (__u32)kdev_t_to_nr(src->i_rdev);
+#else
+                dst->o_rdev = (__u32)old_decode_dev(src->i_rdev);
+#endif
                 newvalid |= OBD_MD_FLRDEV;
         }
 
@@ -194,7 +210,8 @@ void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid)
 
         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
                 CDEBUG(D_INODE, "valid %x, cur time %lu/%lu, new %lu/%lu\n",
-                       src->o_valid, dst->i_mtime, dst->i_ctime,
+                       src->o_valid, LTIME_S(dst->i_mtime), 
+                       LTIME_S(dst->i_ctime),
                        (long)src->o_mtime, (long)src->o_ctime);
 
         if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(dst->i_atime))
@@ -203,11 +220,13 @@ void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid)
                 LTIME_S(dst->i_mtime) = src->o_mtime;
         if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime))
                 LTIME_S(dst->i_ctime) = src->o_ctime;
-        if (valid & OBD_MD_FLSIZE && src->o_size > dst->i_size)
+        if (valid & OBD_MD_FLSIZE) 
                 dst->i_size = src->o_size;
         /* optimum IO size */
         if (valid & OBD_MD_FLBLKSZ && src->o_blksize > dst->i_blksize)
                 dst->i_blksize = src->o_blksize;
+        if (dst->i_blksize < PAGE_CACHE_SIZE)
+                dst->i_blksize = PAGE_CACHE_SIZE;
         /* allocation of space */
         if (valid & OBD_MD_FLBLOCKS && src->o_blocks > dst->i_blocks)
                 dst->i_blocks = src->o_blocks;
@@ -220,7 +239,8 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
 
         if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
                 CDEBUG(D_INODE, "valid %x, cur time %lu/%lu, new %lu/%lu\n",
-                       src->o_valid, dst->i_mtime, dst->i_ctime,
+                       src->o_valid, 
+                       LTIME_S(dst->i_mtime), LTIME_S(dst->i_ctime),
                        (long)src->o_mtime, (long)src->o_ctime);
 
         if (valid & OBD_MD_FLATIME)
@@ -250,7 +270,11 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
         if (valid & OBD_MD_FLGENER)
                 dst->i_generation = src->o_generation;
         if (valid & OBD_MD_FLRDEV)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
                 dst->i_rdev = to_kdev_t(src->o_rdev);
+#else
+                dst->i_rdev = old_decode_dev(src->o_rdev);
+#endif
 }
 EXPORT_SYMBOL(obdo_to_inode);
 #endif
@@ -341,3 +365,14 @@ int obdo_cmp_md(struct obdo *dst, struct obdo *src, obd_flag compare)
         return res;
 }
 EXPORT_SYMBOL(obdo_cmp_md);
+
+void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj)
+{
+        ioobj->ioo_id = oa->o_id;
+        if (oa->o_valid & OBD_MD_FLGROUP)
+                ioobj->ioo_gr = oa->o_gr;
+        else 
+                ioobj->ioo_gr = 0;
+        ioobj->ioo_type = oa->o_mode;
+}
+EXPORT_SYMBOL(obdo_to_ioobj);
diff --git a/lustre/obdclass/otree.c b/lustre/obdclass/otree.c
deleted file mode 100644
index 16ef088faedf52bb9184f9c77e87e81312444df2..0000000000000000000000000000000000000000
--- a/lustre/obdclass/otree.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Copyright (C) 2002, 2003  Cluster File Systems, Inc
- *
- *  our offset trees (otrees) track single-bit state of offsets in an
- *  extent tree.  
- */
-
-#define EXPORT_SYMTAB
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/module.h>
-
-#define DEBUG_SUBSYSTEM S_OSC
-#include <linux/kp30.h>
-#include <linux/obd.h>
-#include <linux/lustre_debug.h>
-#include <linux/lustre_otree.h>
-
-struct offset_extent {
-        rb_node_t       oe_node;
-        unsigned long   oe_start, oe_end;
-};
-
-static struct offset_extent * ot_find_oe(rb_root_t *root,
-                                         struct offset_extent *needle)
-{
-        struct rb_node_s *node = root->rb_node;
-        struct offset_extent *oe;
-        ENTRY;
-
-        CDEBUG(D_INODE, "searching [%lu -> %lu]\n", needle->oe_start,
-               needle->oe_end);
-
-        while (node) {
-                oe = rb_entry(node, struct offset_extent, oe_node);
-                if (needle->oe_end < oe->oe_start)
-                        node = node->rb_left;
-                else if (needle->oe_start > oe->oe_end)
-                        node = node->rb_right;
-                else {
-                        CDEBUG(D_INODE, "returning [%lu -> %lu]\n",
-                               oe->oe_start, oe->oe_end);
-                        RETURN(oe);
-                }
-        }
-        RETURN(NULL);
-}
-
-/* do the rbtree mechanics to insert a node, callers are responsible
- * for making sure that this new node doesn't overlap with existing
- * nodes */
-static void ot_indert_oe(rb_root_t *root, struct offset_extent *new_oe)
-{
-        rb_node_t ** p = &root->rb_node;
-        rb_node_t * parent = NULL;
-        struct offset_extent *oe;
-        ENTRY;
-
-        LASSERT(new_oe->oe_start <= new_oe->oe_end);
-
-        while (*p) {
-                parent = *p;
-                oe = rb_entry(parent, struct offset_extent, oe_node);
-                if ( new_oe->oe_end < oe->oe_start )
-                        p = &(*p)->rb_left;
-                else if ( new_oe->oe_start > oe->oe_end )
-                        p = &(*p)->rb_right;
-                else
-                        LBUG();
-        }
-        rb_link_node(&new_oe->oe_node, parent, p);
-        rb_insert_color(&new_oe->oe_node, root);
-        EXIT;
-}
-
-int ot_mark_offset(struct otree *ot, unsigned long offset)
-{
-        struct offset_extent needle, *oe, *new_oe;
-        int rc = 0;
-        ENTRY;
-
-        OBD_ALLOC(new_oe, sizeof(*new_oe));
-        if (new_oe == NULL)
-                RETURN(-ENOMEM);
-
-        spin_lock(&ot->ot_lock);
-
-        /* find neighbours that we might glom on to */
-        needle.oe_start = (offset > 0) ? offset - 1 : offset;
-        needle.oe_end = (offset < ~0) ? offset + 1 : offset;
-        oe = ot_find_oe(&ot->ot_root, &needle);
-        if ( oe == NULL ) {
-                new_oe->oe_start = offset;
-                new_oe->oe_end = offset;
-                ot_indert_oe(&ot->ot_root, new_oe);
-                ot->ot_num_marked++;
-                new_oe = NULL;
-                GOTO(out, rc);
-        }
-
-        /* already recorded */
-        if ( offset >= oe->oe_start && offset <= oe->oe_end )
-                GOTO(out, rc);
-
-        /* ok, need to check for adjacent neighbours */
-        needle.oe_start = offset;
-        needle.oe_end = offset;
-        if (ot_find_oe(&ot->ot_root, &needle))
-                GOTO(out, rc);
-
-        /* ok, its safe to extend the oe we found */
-        if ( offset == oe->oe_start - 1 )
-                oe->oe_start--;
-        else if ( offset == oe->oe_end + 1 )
-                oe->oe_end++;
-        else
-                LBUG();
-        ot->ot_num_marked++;
-
-out:
-        CDEBUG(D_INODE, "%lu now dirty\n", ot->ot_num_marked);
-        spin_unlock(&ot->ot_lock);
-        if (new_oe)
-                OBD_FREE(new_oe, sizeof(*new_oe));
-        RETURN(rc);
-}
-
-int ot_clear_extent(struct otree *ot, unsigned long start, unsigned long end)
-{
-        struct offset_extent needle, *oe, *new_oe;
-        int rc = 0;
-        ENTRY;
-
-        /* will allocate more intelligently later */
-        OBD_ALLOC(new_oe, sizeof(*new_oe));
-        if (new_oe == NULL)
-                RETURN(-ENOMEM);
-
-        needle.oe_start = start;
-        needle.oe_end = end;
-
-        spin_lock(&ot->ot_lock);
-        for ( ; (oe = ot_find_oe(&ot->ot_root, &needle)) ; ) {
-                rc = 0;
-
-                /* see if we're punching a hole and need to create a node */
-                if (oe->oe_start < start && oe->oe_end > end) {
-                        new_oe->oe_start = end + 1;
-                        new_oe->oe_end = oe->oe_end;
-                        oe->oe_end = start - 1;
-                        ot_indert_oe(&ot->ot_root, new_oe);
-                        new_oe = NULL;
-                        ot->ot_num_marked -= end - start + 1;
-                        break;
-                }
-
-                /* overlapping edges */
-                if (oe->oe_start < start && oe->oe_end <= end) {
-                        ot->ot_num_marked -= oe->oe_end - start + 1;
-                        oe->oe_end = start - 1;
-                        oe = NULL;
-                        continue;
-                }
-                if (oe->oe_end > end && oe->oe_start >= start) {
-                        ot->ot_num_marked -= end - oe->oe_start + 1;
-                        oe->oe_start = end + 1;
-                        oe = NULL;
-                        continue;
-                }
-
-                /* an extent entirely within the one we're clearing */
-                rb_erase(&oe->oe_node, &ot->ot_root);
-                ot->ot_num_marked -= oe->oe_end - oe->oe_start + 1;
-                spin_unlock(&ot->ot_lock);
-                OBD_FREE(oe, sizeof(*oe));
-                spin_lock(&ot->ot_lock);
-        }
-        CDEBUG(D_INODE, "%lu now dirty\n", ot->ot_num_marked);
-        spin_unlock(&ot->ot_lock);
-        if (new_oe)
-                OBD_FREE(new_oe, sizeof(*new_oe));
-        RETURN(rc);
-}
-
-int ot_find_marked_extent(struct otree *ot, unsigned long *start,
-                  unsigned long *end)
-{
-        struct offset_extent needle, *oe;
-        int rc = -ENOENT;
-        ENTRY;
-
-        needle.oe_start = *start;
-        needle.oe_end = *end;
-
-        spin_lock(&ot->ot_lock);
-        oe = ot_find_oe(&ot->ot_root, &needle);
-        if (oe) {
-                *start = oe->oe_start;
-                *end = oe->oe_end;
-                rc = 0;
-        }
-        spin_unlock(&ot->ot_lock);
-
-        RETURN(rc);
-}
-
-int ot_last_marked(struct otree *ot, unsigned long *last)
-{
-        struct rb_node_s *found, *node;
-        struct offset_extent *oe;
-        int rc = -ENOENT;
-        ENTRY;
-
-        spin_lock(&ot->ot_lock);
-        for (node = ot->ot_root.rb_node, found = NULL;
-             node;
-             found = node, node = node->rb_right)
-                ;
-
-        if (found) {
-                oe = rb_entry(found, struct offset_extent, oe_node);
-                *last = oe->oe_end;
-                rc = 0;
-        }
-        spin_unlock(&ot->ot_lock);
-        RETURN(rc);
-}
-
-unsigned long ot_num_marked(struct otree *ot)
-{
-        return ot->ot_num_marked;
-}
-
-void ot_init(struct otree *ot)
-{
-        CDEBUG(D_INODE, "initializing %p\n", ot);
-        spin_lock_init(&ot->ot_lock);
-        ot->ot_num_marked = 0;
-        ot->ot_root.rb_node = NULL;
-}
-
-EXPORT_SYMBOL(ot_mark_offset);
-EXPORT_SYMBOL(ot_clear_extent);
-EXPORT_SYMBOL(ot_find_marked_extent);
-EXPORT_SYMBOL(ot_last_marked);
-EXPORT_SYMBOL(ot_num_marked);
-EXPORT_SYMBOL(ot_init);
diff --git a/lustre/obdclass/rbtree.c b/lustre/obdclass/rbtree.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d393d3f0a9f8eb2f63ff4ac2e7d98a2f605021a
--- /dev/null
+++ b/lustre/obdclass/rbtree.c
@@ -0,0 +1,338 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  
+  This program 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.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/lib/rbtree.c
+
+  rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002
+*/
+
+#include <liblustre.h>
+#include <linux/rbtree.h>
+
+static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
+{
+	rb_node_t * right = node->rb_right;
+
+	if ((node->rb_right = right->rb_left))
+		right->rb_left->rb_parent = node;
+	right->rb_left = node;
+
+	if ((right->rb_parent = node->rb_parent))
+	{
+		if (node == node->rb_parent->rb_left)
+			node->rb_parent->rb_left = right;
+		else
+			node->rb_parent->rb_right = right;
+	}
+	else
+		root->rb_node = right;
+	node->rb_parent = right;
+}
+
+static void __rb_rotate_right(rb_node_t * node, rb_root_t * root)
+{
+	rb_node_t * left = node->rb_left;
+
+	if ((node->rb_left = left->rb_right))
+		left->rb_right->rb_parent = node;
+	left->rb_right = node;
+
+	if ((left->rb_parent = node->rb_parent))
+	{
+		if (node == node->rb_parent->rb_right)
+			node->rb_parent->rb_right = left;
+		else
+			node->rb_parent->rb_left = left;
+	}
+	else
+		root->rb_node = left;
+	node->rb_parent = left;
+}
+
+void rb_insert_color(rb_node_t * node, rb_root_t * root)
+{
+	rb_node_t * parent, * gparent;
+
+	while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
+	{
+		gparent = parent->rb_parent;
+
+		if (parent == gparent->rb_left)
+		{
+			{
+				register rb_node_t * uncle = gparent->rb_right;
+				if (uncle && uncle->rb_color == RB_RED)
+				{
+					uncle->rb_color = RB_BLACK;
+					parent->rb_color = RB_BLACK;
+					gparent->rb_color = RB_RED;
+					node = gparent;
+					continue;
+				}
+			}
+
+			if (parent->rb_right == node)
+			{
+				register rb_node_t * tmp;
+				__rb_rotate_left(parent, root);
+				tmp = parent;
+				parent = node;
+				node = tmp;
+			}
+
+			parent->rb_color = RB_BLACK;
+			gparent->rb_color = RB_RED;
+			__rb_rotate_right(gparent, root);
+		} else {
+			{
+				register rb_node_t * uncle = gparent->rb_left;
+				if (uncle && uncle->rb_color == RB_RED)
+				{
+					uncle->rb_color = RB_BLACK;
+					parent->rb_color = RB_BLACK;
+					gparent->rb_color = RB_RED;
+					node = gparent;
+					continue;
+				}
+			}
+
+			if (parent->rb_left == node)
+			{
+				register rb_node_t * tmp;
+				__rb_rotate_right(parent, root);
+				tmp = parent;
+				parent = node;
+				node = tmp;
+			}
+
+			parent->rb_color = RB_BLACK;
+			gparent->rb_color = RB_RED;
+			__rb_rotate_left(gparent, root);
+		}
+	}
+
+	root->rb_node->rb_color = RB_BLACK;
+}
+EXPORT_SYMBOL(rb_insert_color);
+
+static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
+			     rb_root_t * root)
+{
+	rb_node_t * other;
+
+	while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
+	{
+		if (parent->rb_left == node)
+		{
+			other = parent->rb_right;
+			if (other->rb_color == RB_RED)
+			{
+				other->rb_color = RB_BLACK;
+				parent->rb_color = RB_RED;
+				__rb_rotate_left(parent, root);
+				other = parent->rb_right;
+			}
+			if ((!other->rb_left ||
+			     other->rb_left->rb_color == RB_BLACK)
+			    && (!other->rb_right ||
+				other->rb_right->rb_color == RB_BLACK))
+			{
+				other->rb_color = RB_RED;
+				node = parent;
+				parent = node->rb_parent;
+			}
+			else
+			{
+				if (!other->rb_right ||
+				    other->rb_right->rb_color == RB_BLACK)
+				{
+					register rb_node_t * o_left;
+					if ((o_left = other->rb_left))
+						o_left->rb_color = RB_BLACK;
+					other->rb_color = RB_RED;
+					__rb_rotate_right(other, root);
+					other = parent->rb_right;
+				}
+				other->rb_color = parent->rb_color;
+				parent->rb_color = RB_BLACK;
+				if (other->rb_right)
+					other->rb_right->rb_color = RB_BLACK;
+				__rb_rotate_left(parent, root);
+				node = root->rb_node;
+				break;
+			}
+		}
+		else
+		{
+			other = parent->rb_left;
+			if (other->rb_color == RB_RED)
+			{
+				other->rb_color = RB_BLACK;
+				parent->rb_color = RB_RED;
+				__rb_rotate_right(parent, root);
+				other = parent->rb_left;
+			}
+			if ((!other->rb_left ||
+			     other->rb_left->rb_color == RB_BLACK)
+			    && (!other->rb_right ||
+				other->rb_right->rb_color == RB_BLACK))
+			{
+				other->rb_color = RB_RED;
+				node = parent;
+				parent = node->rb_parent;
+			}
+			else
+			{
+				if (!other->rb_left ||
+				    other->rb_left->rb_color == RB_BLACK)
+				{
+					register rb_node_t * o_right;
+					if ((o_right = other->rb_right))
+						o_right->rb_color = RB_BLACK;
+					other->rb_color = RB_RED;
+					__rb_rotate_left(other, root);
+					other = parent->rb_left;
+				}
+				other->rb_color = parent->rb_color;
+				parent->rb_color = RB_BLACK;
+				if (other->rb_left)
+					other->rb_left->rb_color = RB_BLACK;
+				__rb_rotate_right(parent, root);
+				node = root->rb_node;
+				break;
+			}
+		}
+	}
+	if (node)
+		node->rb_color = RB_BLACK;
+}
+
+void rb_erase(rb_node_t * node, rb_root_t * root)
+{
+	rb_node_t * child, * parent;
+	int color;
+
+	if (!node->rb_left)
+		child = node->rb_right;
+	else if (!node->rb_right)
+		child = node->rb_left;
+	else
+	{
+		rb_node_t * old = node, * left;
+
+		node = node->rb_right;
+		while ((left = node->rb_left))
+			node = left;
+		child = node->rb_right;
+		parent = node->rb_parent;
+		color = node->rb_color;
+
+		if (child)
+			child->rb_parent = parent;
+		if (parent)
+		{
+			if (parent->rb_left == node)
+				parent->rb_left = child;
+			else
+				parent->rb_right = child;
+		}
+		else
+			root->rb_node = child;
+
+		if (node->rb_parent == old)
+			parent = node;
+		node->rb_parent = old->rb_parent;
+		node->rb_color = old->rb_color;
+		node->rb_right = old->rb_right;
+		node->rb_left = old->rb_left;
+
+		if (old->rb_parent)
+		{
+			if (old->rb_parent->rb_left == old)
+				old->rb_parent->rb_left = node;
+			else
+				old->rb_parent->rb_right = node;
+		} else
+			root->rb_node = node;
+
+		old->rb_left->rb_parent = node;
+		if (old->rb_right)
+			old->rb_right->rb_parent = node;
+		goto color;
+	}
+
+	parent = node->rb_parent;
+	color = node->rb_color;
+
+	if (child)
+		child->rb_parent = parent;
+	if (parent)
+	{
+		if (parent->rb_left == node)
+			parent->rb_left = child;
+		else
+			parent->rb_right = child;
+	}
+	else
+		root->rb_node = child;
+
+ color:
+	if (color == RB_BLACK)
+		__rb_erase_color(child, parent, root);
+}
+EXPORT_SYMBOL(rb_erase);
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+rb_node_t *rb_get_first(rb_root_t *root)
+{
+	rb_node_t	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return 0;
+	while (n->rb_left)
+		n = n->rb_left;
+	return n;
+}
+EXPORT_SYMBOL(rb_get_first);
+
+/*
+ * Given a node, this function will return the next node in the tree.
+ */
+rb_node_t *rb_get_next(rb_node_t *n)
+{
+	rb_node_t	*parent;
+
+	if (n->rb_right) {
+		n = n->rb_right;
+		while (n->rb_left)
+			n = n->rb_left;
+		return n;
+	} else {
+		while ((parent = n->rb_parent)) {
+			if (n == parent->rb_left)
+				return parent;
+			n = parent;
+		}
+		return 0;
+	}
+}
+EXPORT_SYMBOL(rb_get_next);
+
diff --git a/lustre/obdclass/recov_log.c b/lustre/obdclass/recov_log.c
deleted file mode 100644
index bff90f3f5c1325b09abf083b0ebb57de551e70ba..0000000000000000000000000000000000000000
--- a/lustre/obdclass/recov_log.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
- *   Author: Andreas Dilger <adilger@clusterfs.com>
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * OST<->MDS recovery logging infrastructure.
- *
- * Invariants in implementation:
- * - we do not share logs among different OST<->MDS connections, so that
- *   if an OST or MDS fails it need only look at log(s) relevant to itself
- */
-
-#define DEBUG_SUBSYSTEM S_LOG
-
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
-
-#include <linux/fs.h>
-#include <linux/obd_class.h>
-#include <linux/lustre_log.h>
-#include <portals/list.h>
-
-/* Allocate a new log or catalog handle */
-struct llog_handle *llog_alloc_handle(void)
-{
-        struct llog_handle *loghandle;
-        ENTRY;
-
-        OBD_ALLOC(loghandle, sizeof(*loghandle));
-        if (loghandle == NULL)
-                RETURN(ERR_PTR(-ENOMEM));
-
-        OBD_ALLOC(loghandle->lgh_hdr, LLOG_CHUNK_SIZE);
-        if (loghandle->lgh_hdr == NULL) {
-                OBD_FREE(loghandle, sizeof(*loghandle));
-                RETURN(ERR_PTR(-ENOMEM));
-        }
-
-        INIT_LIST_HEAD(&loghandle->lgh_list);
-        sema_init(&loghandle->lgh_lock, 1);
-
-        RETURN(loghandle);
-}
-EXPORT_SYMBOL(llog_alloc_handle);
-
-void llog_free_handle(struct llog_handle *loghandle)
-{
-        if (!loghandle)
-                return;
-
-        list_del_init(&loghandle->lgh_list);
-        OBD_FREE(loghandle->lgh_hdr, LLOG_CHUNK_SIZE);
-        OBD_FREE(loghandle, sizeof(*loghandle));
-}
-EXPORT_SYMBOL(llog_free_handle);
-
-/* Create a new log handle and add it to the open list.
- * This log handle will be closed when all of the records in it are removed.
- *
- * Assumes caller has already pushed us into the kernel context and is locking.
- */
-struct llog_handle *llog_new_log(struct llog_handle *cathandle,
-                                 struct obd_uuid *tgtuuid)
-{
-        struct llog_handle *loghandle;
-        struct llog_object_hdr *llh;
-        loff_t offset;
-        int rc, index, bitmap_size, i;
-        ENTRY;
-
-        LASSERT(sizeof(*llh) == LLOG_CHUNK_SIZE);
-
-        loghandle = cathandle->lgh_log_create(cathandle->lgh_obd);
-        if (IS_ERR(loghandle))
-                RETURN(loghandle);
-
-        llh = loghandle->lgh_hdr;
-        llh->llh_hdr.lth_type = LLOG_OBJECT_MAGIC;
-        llh->llh_hdr.lth_len = llh->llh_hdr_end_len = sizeof(*llh);
-        llh->llh_timestamp = LTIME_S(CURRENT_TIME);
-        llh->llh_bitmap_offset = offsetof(typeof(*llh), llh_bitmap);
-        memcpy(&llh->llh_tgtuuid, tgtuuid, sizeof(llh->llh_tgtuuid));
-        loghandle->lgh_tgtuuid = &llh->llh_tgtuuid;
-
-        llh = cathandle->lgh_hdr;
-        bitmap_size = sizeof(llh->llh_bitmap) * 8;
-        /* This should basically always find the first entry free */
-        for (i = 0, index = llh->llh_count; i < bitmap_size; i++, index++) {
-                index %= bitmap_size;
-                if (ext2_set_bit(index, llh->llh_bitmap)) {
-                        /* XXX This should trigger log clean up or similar */
-                        CERROR("catalog index %d is still in use\n", index);
-                } else {
-                        llh->llh_count = (index + 1) % bitmap_size;
-                        break;
-                }
-        }
-        if (i == bitmap_size)
-                CERROR("no free catalog slots for log...\n");
-
-        CDEBUG(D_HA, "new recovery log "LPX64":%x catalog index %u\n",
-               loghandle->lgh_cookie.lgc_lgl.lgl_oid,
-               loghandle->lgh_cookie.lgc_lgl.lgl_ogen, index);
-        loghandle->lgh_cookie.lgc_index = index;
-
-        offset = sizeof(*llh) + index * sizeof(loghandle->lgh_cookie);
-
-        /* XXX Hmm, what to do if the catalog update fails?  Under normal
-         *     operations we would clean this handle up anyways, and at
-         *     worst we leak some objects, but there is little point in
-         *     doing the logging in that case...
-         *
-         *     We don't want to mark a catalog in-use if it wasn't written.
-         *     The only danger is if the OST crashes - the log is lost.
-         */
-        rc = lustre_fwrite(cathandle->lgh_file, &loghandle->lgh_cookie,
-                           sizeof(loghandle->lgh_cookie), &offset);
-        if (rc != sizeof(loghandle->lgh_cookie)) {
-                CERROR("error adding log "LPX64" to catalog: rc %d\n",
-                       loghandle->lgh_cookie.lgc_lgl.lgl_oid, rc);
-                rc = rc < 0 ? : -ENOSPC;
-        } else {
-                offset = 0;
-                rc = lustre_fwrite(cathandle->lgh_file, llh, sizeof(*llh),
-                                   &offset);
-                if (rc != sizeof(*llh)) {
-                        CERROR("error marking catalog entry %d in use: rc %d\n",
-                               index, rc);
-                        rc = rc < 0 ? : -ENOSPC;
-                }
-        }
-        cathandle->lgh_current = loghandle;
-        list_add_tail(&loghandle->lgh_list, &cathandle->lgh_list);
-
-        RETURN(loghandle);
-}
-EXPORT_SYMBOL(llog_new_log);
-
-/* Assumes caller has already pushed us into the kernel context. */
-int llog_init_catalog(struct llog_handle *cathandle, struct obd_uuid *tgtuuid)
-{
-        struct llog_object_hdr *llh;
-        loff_t offset = 0;
-        int rc = 0;
-        ENTRY;
-
-        LASSERT(sizeof(*llh) == LLOG_CHUNK_SIZE);
-
-        down(&cathandle->lgh_lock);
-        llh = cathandle->lgh_hdr;
-
-        if (cathandle->lgh_file->f_dentry->d_inode->i_size == 0) {
-write_hdr:      llh->llh_hdr.lth_type = LLOG_CATALOG_MAGIC;
-                llh->llh_hdr.lth_len = llh->llh_hdr_end_len = LLOG_CHUNK_SIZE;
-                llh->llh_timestamp = LTIME_S(CURRENT_TIME);
-                llh->llh_bitmap_offset = offsetof(typeof(*llh), llh_bitmap);
-                memcpy(&llh->llh_tgtuuid, tgtuuid, sizeof(llh->llh_tgtuuid));
-                rc = lustre_fwrite(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
-                                   &offset);
-                if (rc != LLOG_CHUNK_SIZE) {
-                        CERROR("error writing catalog header: rc %d\n", rc);
-                        OBD_FREE(llh, sizeof(*llh));
-                        if (rc >= 0)
-                                rc = -ENOSPC;
-                } else
-                        rc = 0;
-        } else {
-                rc = lustre_fread(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
-                                  &offset);
-                if (rc != LLOG_CHUNK_SIZE) {
-                        CERROR("error reading catalog header: rc %d\n", rc);
-                        /* Can we do much else if the header is bad? */
-                        goto write_hdr;
-                } else
-                        rc = 0;
-        }
-
-        cathandle->lgh_tgtuuid = &llh->llh_tgtuuid;
-        up(&cathandle->lgh_lock);
-        RETURN(rc);
-}
-EXPORT_SYMBOL(llog_init_catalog);
-
-/* Return the currently active log handle.  If the current log handle doesn't
- * have enough space left for the current record, start a new one.
- *
- * If reclen is 0, we only want to know what the currently active log is,
- * otherwise we get a lock on this log so nobody can steal our space.
- *
- * Assumes caller has already pushed us into the kernel context and is locking.
- */
-static struct llog_handle *llog_current_log(struct llog_handle *cathandle,
-                                            int reclen)
-{
-        struct llog_handle *loghandle = NULL;
-        ENTRY;
-
-        loghandle = cathandle->lgh_current;
-        if (loghandle) {
-                struct llog_object_hdr *llh = loghandle->lgh_hdr;
-                if (llh->llh_count < sizeof(llh->llh_bitmap) * 8)
-                        RETURN(loghandle);
-        }
-
-        if (reclen)
-                loghandle = llog_new_log(cathandle, cathandle->lgh_tgtuuid);
-        RETURN(loghandle);
-}
-
-/* Add a single record to the recovery log(s).
- * Returns number of bytes in returned logcookies, or negative error code.
- *
- * Assumes caller has already pushed us into the kernel context.
- */
-int llog_add_record(struct llog_handle *cathandle, struct llog_trans_hdr *rec,
-                    struct llog_cookie *logcookies)
-{
-        struct llog_handle *loghandle;
-        struct llog_object_hdr *llh;
-        int reclen = rec->lth_len;
-        struct file *file;
-        loff_t offset;
-        size_t left;
-        int index;
-        int rc;
-        ENTRY;
-
-        LASSERT(rec->lth_len <= LLOG_CHUNK_SIZE);
-        down(&cathandle->lgh_lock);
-        loghandle = llog_current_log(cathandle, reclen);
-        if (IS_ERR(loghandle)) {
-                up(&cathandle->lgh_lock);
-                RETURN(PTR_ERR(loghandle));
-        }
-        down(&loghandle->lgh_lock);
-        up(&cathandle->lgh_lock);
-
-        llh = loghandle->lgh_hdr;
-        file = loghandle->lgh_file;
-
-        /* Make sure that records don't cross a chunk boundary, so we can
-         * process them page-at-a-time if needed.  If it will cross a chunk
-         * boundary, write in a fake (but referenced) entry to pad the chunk.
-         *
-         * We know that llog_current_log() will return a loghandle that is
-         * big enough to hold reclen, so all we care about is padding here.
-         */
-        left = LLOG_CHUNK_SIZE - (file->f_pos & (LLOG_CHUNK_SIZE - 1));
-        if (left != 0 && left != reclen && left < reclen + LLOG_MIN_REC_SIZE) {
-                struct llog_null_trans {
-                        struct llog_trans_hdr hdr;
-                        __u32 padding[6];
-                } pad = { .hdr = { .lth_len = left } };
-
-                LASSERT(left >= LLOG_MIN_REC_SIZE);
-                if (left <= sizeof(pad))
-                        *(__u32 *)((char *)&pad + left - sizeof(__u32)) = left;
-
-                rc = lustre_fwrite(loghandle->lgh_file, &pad,
-                                   min(sizeof(pad), left),
-                                   &loghandle->lgh_file->f_pos);
-                if (rc != min(sizeof(pad), left)) {
-                        CERROR("error writing padding record: rc %d\n", rc);
-                        GOTO(out, rc = rc < 0 ? rc : -EIO);
-                }
-
-                left -= rc;
-                if (left) {
-                        LASSERT(left >= sizeof(__u32));
-                        loghandle->lgh_file->f_pos += left - sizeof(__u32);
-                        rc = lustre_fwrite(loghandle->lgh_file, &pad,
-                                           sizeof(__u32),
-                                           &loghandle->lgh_file->f_pos);
-                        if (rc != sizeof(__u32)) {
-                                CERROR("error writing padding end: rc %d\n",
-                                       rc);
-                                GOTO(out, rc < 0 ? rc : -ENOSPC);
-                        }
-                }
-
-                loghandle->lgh_index++;
-        }
-
-        index = loghandle->lgh_index++;
-        if (ext2_set_bit(index, llh->llh_bitmap)) {
-                CERROR("argh, index %u already set in log bitmap?\n", index);
-                LBUG(); /* should never happen */
-        }
-        llh->llh_count++;
-
-        offset = 0;
-        rc = lustre_fwrite(loghandle->lgh_file, llh, sizeof(*llh), &offset);
-        if (rc != sizeof(*llh)) {
-                CERROR("error writing log header: rc %d\n", rc);
-                GOTO(out, rc < 0 ? rc : -EIO);
-        }
-
-        rc = lustre_fwrite(loghandle->lgh_file, rec, reclen,
-                           &loghandle->lgh_file->f_pos);
-        if (rc != reclen) {
-                CERROR("error writing log record: rc %d\n", rc);
-                GOTO(out, rc < 0 ? rc : -ENOSPC);
-        }
-
-        CDEBUG(D_HA, "added record "LPX64":%x+%u, %u bytes\n",
-               loghandle->lgh_cookie.lgc_lgl.lgl_oid,
-               loghandle->lgh_cookie.lgc_lgl.lgl_ogen, index, rec->lth_len);
-        *logcookies = loghandle->lgh_cookie;
-        logcookies->lgc_index = index;
-
-        rc = 0;
-out:
-        up(&loghandle->lgh_lock);
-        RETURN(rc);
-}
-EXPORT_SYMBOL(llog_add_record);
-
-/* Remove a log entry from the catalog.
- * Assumes caller has already pushed us into the kernel context and is locking.
- */
-int llog_delete_log(struct llog_handle *cathandle,struct llog_handle *loghandle)
-{
-        struct llog_cookie *lgc = &loghandle->lgh_cookie;
-        int catindex = lgc->lgc_index;
-        struct llog_object_hdr *llh = cathandle->lgh_hdr;
-        loff_t offset = 0;
-        int rc = 0;
-        ENTRY;
-
-        CDEBUG(D_HA, "log "LPX64":%x empty, closing\n",
-               lgc->lgc_lgl.lgl_oid, lgc->lgc_lgl.lgl_ogen);
-
-        if (ext2_clear_bit(catindex, llh->llh_bitmap)) {
-                CERROR("catalog index %u already clear?\n", catindex);
-                LBUG();
-        } else {
-                rc = lustre_fwrite(cathandle->lgh_file, llh, sizeof(*llh),
-                                   &offset);
-
-                if (rc != sizeof(*llh)) {
-                        CERROR("log %u cancel error: rc %d\n", catindex, rc);
-                        if (rc >= 0)
-                                rc = -EIO;
-                } else
-                        rc = 0;
-        }
-        RETURN(rc);
-}
-EXPORT_SYMBOL(llog_delete_log);
-
-/* Assumes caller has already pushed us into the kernel context and is locking.
- * We return a lock on the handle to ensure nobody yanks it from us.
- */
-static struct llog_handle *llog_id2handle(struct llog_handle *cathandle,
-                                          struct llog_cookie *logcookie)
-{
-        struct llog_handle *loghandle;
-        struct llog_logid *lgl = &logcookie->lgc_lgl;
-        ENTRY;
-
-        if (cathandle == NULL)
-                RETURN(ERR_PTR(-EBADF));
-
-        list_for_each_entry(loghandle, &cathandle->lgh_list, lgh_list) {
-                struct llog_logid *cgl = &loghandle->lgh_cookie.lgc_lgl;
-                if (cgl->lgl_oid == lgl->lgl_oid) {
-                        if (cgl->lgl_ogen != lgl->lgl_ogen) {
-                                CERROR("log "LPX64" generation %x != %x\n",
-                                       lgl->lgl_oid, cgl->lgl_ogen,
-                                       lgl->lgl_ogen);
-                                continue;
-                        }
-                        GOTO(out, loghandle);
-                }
-        }
-
-        loghandle = cathandle->lgh_log_open(cathandle->lgh_obd, logcookie);
-        if (IS_ERR(loghandle)) {
-                CERROR("error opening log id "LPX64":%x: rc %d\n",
-                       lgl->lgl_oid, lgl->lgl_ogen, (int)PTR_ERR(loghandle));
-        } else {
-                list_add(&loghandle->lgh_list, &cathandle->lgh_list);
-        }
-
-out:
-        RETURN(loghandle);
-}
-
-/* For each cookie in the cookie array, we clear the log in-use bit and either:
- * - the log is empty, so mark it free in the catalog header and delete it
- * - the log is not empty, just write out the log header
- *
- * The cookies may be in different log files, so we need to get new logs
- * each time.
- *
- * Assumes caller has already pushed us into the kernel context.
- */
-int llog_cancel_records(struct llog_handle *cathandle, int count,
-                        struct llog_cookie *cookies)
-{
-        int i, rc = 0;
-        ENTRY;
-
-        down(&cathandle->lgh_lock);
-        for (i = 0; i < count; i++, cookies++) {
-                struct llog_handle *loghandle;
-                struct llog_object_hdr *llh;
-                struct llog_logid *lgl = &cookies->lgc_lgl;
-
-                loghandle = llog_id2handle(cathandle, cookies);
-                if (IS_ERR(loghandle)) {
-                        if (!rc)
-                                rc = PTR_ERR(loghandle);
-                        continue;
-                }
-
-                down(&loghandle->lgh_lock);
-                llh = loghandle->lgh_hdr;
-                CDEBUG(D_HA, "cancelling "LPX64" index %u: %u\n",
-                       lgl->lgl_oid, cookies->lgc_index,
-                       ext2_test_bit(cookies->lgc_index, llh->llh_bitmap));
-                if (!ext2_clear_bit(cookies->lgc_index, llh->llh_bitmap)) {
-                        CERROR("log index %u in "LPX64":%x already clear?\n",
-                               cookies->lgc_index, lgl->lgl_oid, lgl->lgl_ogen);
-                } else if (--llh->llh_count == 0 &&
-                           loghandle != llog_current_log(cathandle, 0)) {
-                        loghandle->lgh_log_close(cathandle, loghandle);
-                } else {
-                        loff_t offset = 0;
-                        int ret = lustre_fwrite(loghandle->lgh_file, llh,
-                                                sizeof(*llh), &offset);
-
-                        if (ret != sizeof(*llh)) {
-                                CERROR("error cancelling index %u: rc %d\n",
-                                       cookies->lgc_index, ret);
-                                /* XXX mark handle bad? */
-                                if (!rc)
-                                        rc = ret;
-                        }
-                }
-                up(&loghandle->lgh_lock);
-        }
-        up(&cathandle->lgh_lock);
-
-        RETURN(rc);
-}
-EXPORT_SYMBOL(llog_cancel_records);
-
-int llog_close_log(struct llog_handle *cathandle, struct llog_handle *loghandle)
-{
-        return loghandle->lgh_log_close(cathandle, loghandle);
-}
-EXPORT_SYMBOL(llog_close_log);
diff --git a/lustre/obdclass/simple.c b/lustre/obdclass/simple.c
index bd1363a951e983349468291dc318dd14a861e7db..722de4a7c3284df683f1a45bc08cc52a722e5152 100644
--- a/lustre/obdclass/simple.c
+++ b/lustre/obdclass/simple.c
@@ -21,7 +21,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/version.h>
 #include <linux/fs.h>
@@ -31,6 +33,7 @@
 
 #include <linux/obd.h>
 #include <linux/lustre_lib.h>
+#include <linux/lustre_compat25.h>
 
 /* Debugging check only needed during development */
 #ifdef OBD_CTXT_DEBUG
@@ -177,7 +180,7 @@ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode)
                 GOTO(out_up, dchild);
         }
 
-        err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG);
+        err = ll_vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG, NULL);
         if (err)
                 GOTO(out_err, err);
 
@@ -261,17 +264,3 @@ int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off)
 }
 EXPORT_SYMBOL(lustre_fwrite);
 
-/*
- * Sync a file from within kernel context.  Prior to calling this
- * function we should already have done a push_ctxt().
- */
-int lustre_fsync(struct file *file)
-{
-        ENTRY;
-        ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n");
-        if (!file || !file->f_op || !file->f_op->fsync)
-                RETURN(-ENOSYS);
-
-        RETURN(file->f_op->fsync(file, file->f_dentry, 0));
-}
-EXPORT_SYMBOL(lustre_fsync);
diff --git a/lustre/obdclass/statfs_pack.c b/lustre/obdclass/statfs_pack.c
index 8bb78cc444706959c332c1fa37c9bf3a9507ccce..74fbc5b1a034c98952e927e6a41c5f7ba975c5ac 100644
--- a/lustre/obdclass/statfs_pack.c
+++ b/lustre/obdclass/statfs_pack.c
@@ -25,7 +25,9 @@
 
 #define DEBUG_SUBSYSTEM S_CLASS
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #ifndef __KERNEL__
 #include <liblustre.h>
 #else
diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c
index 3d68f2ed368e91b0117657201d3c12b184a63146..610fbc79d3dda9857af52fe1d03b24ea56895a4d 100644
--- a/lustre/obdclass/sysctl.c
+++ b/lustre/obdclass/sysctl.c
@@ -79,7 +79,7 @@ static ctl_table obd_table[] = {
          &proc_dostring, &sysctl_string },
         {OBD_SYNCFILTER, "filter_sync_on_commit", &obd_sync_filter, sizeof(int),
                 0644, NULL, &proc_dointvec},
-	{ 0 }
+        { 0 }
 };
 
 static ctl_table parent_table[] = {
diff --git a/lustre/obdclass/uuid.c b/lustre/obdclass/uuid.c
index 9f103df08fa2252ef020cd26e6532ff41abe8716..2226f9058dd7b125ed04d42be9b73b2665287e84 100644
--- a/lustre/obdclass/uuid.c
+++ b/lustre/obdclass/uuid.c
@@ -23,7 +23,8 @@
 
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
-#include <linux/obd_ost.h>
+#include <linux/obd_ost.h> /* for LUSTRE_OST_NAME */
+#include <linux/lustre_mds.h> /* for LUSTRE_MDC_NAME */
 
 struct uuid {
 	__u32	time_low;
diff --git a/lustre/obdecho/Makefile.mk b/lustre/obdecho/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..07b704028ba3a189a9ce6ccf70e7e16616c315ce
--- /dev/null
+++ b/lustre/obdecho/Makefile.mk
@@ -0,0 +1,9 @@
+# Copyright (C) 2001  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += obdecho.o
+obdecho-objs := echo.o echo_client.o lproc_echo.o
diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c
index 30cfc3ff79d6a6ad7bcf6ccc6cb5fbdef8bcf8b2..a32f2be7f9ae8015eeba5bcdd85de4c6d26ccb3d 100644
--- a/lustre/obdecho/echo.c
+++ b/lustre/obdecho/echo.c
@@ -21,7 +21,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -64,15 +66,28 @@ static int echo_connect(struct lustre_handle *conn, struct obd_device *obd,
         return class_connect(conn, obd, cluuid);
 }
 
-static int echo_disconnect(struct lustre_handle *conn, int flags)
+static int echo_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_export *exp = class_conn2export(conn);
+        unsigned long irqflags;
 
         LASSERT (exp != NULL);
 
         ldlm_cancel_locks_for_export(exp);
-        class_export_put(exp);
-        return class_disconnect(conn, flags);
+
+        spin_lock_irqsave(&exp->exp_lock, irqflags);
+        exp->exp_flags = flags;
+        spin_unlock_irqrestore(&exp->exp_lock, irqflags);
+
+        return class_disconnect(exp, flags);
+}
+
+static int echo_destroy_export(struct obd_export *exp)
+{
+        ENTRY;
+        
+        target_destroy_export(exp);
+
+        RETURN(0);
 }
 
 static __u64 echo_next_id(struct obd_device *obddev)
@@ -86,13 +101,14 @@ static __u64 echo_next_id(struct obd_device *obddev)
         return id;
 }
 
-int echo_create(struct lustre_handle *conn, struct obdo *oa,
+int echo_create(struct obd_export *exp, struct obdo *oa,
                 struct lov_stripe_md **ea, struct obd_trans_info *oti)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
 
         if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 return -EINVAL;
         }
 
@@ -113,13 +129,14 @@ int echo_create(struct lustre_handle *conn, struct obdo *oa,
         return 0;
 }
 
-int echo_destroy(struct lustre_handle *conn, struct obdo *oa,
+int echo_destroy(struct obd_export *exp, struct obdo *oa,
                  struct lov_stripe_md *ea, struct obd_trans_info *oti)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
 
         if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 RETURN(-EINVAL);
         }
 
@@ -138,61 +155,15 @@ int echo_destroy(struct lustre_handle *conn, struct obdo *oa,
         return 0;
 }
 
-static int echo_open(struct lustre_handle *conn, struct obdo *oa,
-                     struct lov_stripe_md *md, struct obd_trans_info *oti,
-                     struct obd_client_handle *och)
-{
-        struct lustre_handle *fh = obdo_handle (oa);
-        struct obd_device    *obd = class_conn2obd (conn);
-
-        if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
-                return (-EINVAL);
-        }
-
-        if (!(oa->o_valid & OBD_MD_FLID)) {
-                CERROR ("obdo missing FLID valid flag: %08x\n", oa->o_valid);
-                return (-EINVAL);
-        }
-
-        fh->cookie = ECHO_HANDLE_MAGIC;
-
-        oa->o_valid |= OBD_MD_FLHANDLE;
-        return 0;
-}
-
-static int echo_close(struct lustre_handle *conn, struct obdo *oa,
-                      struct lov_stripe_md *md, struct obd_trans_info *oti)
-{
-        struct lustre_handle *fh = obdo_handle (oa);
-        struct obd_device    *obd = class_conn2obd(conn);
-
-        if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
-                return (-EINVAL);
-        }
-
-        if (!(oa->o_valid & OBD_MD_FLHANDLE)) {
-                CERROR("obdo missing FLHANDLE valid flag: %08x\n", oa->o_valid);
-                return (-EINVAL);
-        }
-
-        if (fh->cookie != ECHO_HANDLE_MAGIC) {
-                CERROR ("invalid file handle on close: "LPX64"\n", fh->cookie);
-                return (-EINVAL);
-        }
-
-        return 0;
-}
-
-static int echo_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int echo_getattr(struct obd_export *exp, struct obdo *oa,
                         struct lov_stripe_md *md)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
         obd_id id = oa->o_id;
 
         if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 RETURN(-EINVAL);
         }
 
@@ -207,13 +178,14 @@ static int echo_getattr(struct lustre_handle *conn, struct obdo *oa,
         return 0;
 }
 
-static int echo_setattr(struct lustre_handle *conn, struct obdo *oa,
+static int echo_setattr(struct obd_export *exp, struct obdo *oa,
                         struct lov_stripe_md *md, struct obd_trans_info *oti)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
 
         if (!obd) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
+                CERROR("invalid client cookie "LPX64"\n", 
+                       exp->exp_handle.h_cookie);
                 RETURN(-EINVAL);
         }
 
@@ -305,8 +277,8 @@ int echo_preprw(int cmd, struct obd_export *export, struct obdo *oa,
                         } else {
                                 if (verify) {
                                         page_debug_setup(kmap (r->page), r->len,
-                                                         0xecc0ecc0ecc0ecc0,
-                                                         0xecc0ecc0ecc0ecc0);
+                                                         0xecc0ecc0ecc0ecc0ULL,
+                                                         0xecc0ecc0ecc0ecc0ULL);
                                         kunmap (r->page);
                                 }
                         }
@@ -380,7 +352,7 @@ int echo_commitrw(int cmd, struct obd_export *export, struct obdo *oa,
                         void *addr;
 
                         if (!page || !(addr = kmap(page)) ||
-                            !kern_addr_valid(addr)) {
+                            !kern_addr_valid((unsigned long)addr)) {
 
                                 CERROR("bad page objid "LPU64":%p, buf %d/%d\n",
                                        obj->ioo_id, page, j, obj->ioo_bufcnt);
@@ -443,11 +415,14 @@ static int echo_setup(struct obd_device *obddev, obd_count len, void *buf)
 
 static int echo_cleanup(struct obd_device *obddev, int flags)
 {
+        int     leaked;
         ENTRY;
 
-        ldlm_namespace_free(obddev->obd_namespace);
-        CERROR("%d prep/commitrw pages leaked\n",
-               atomic_read(&obddev->u.echo.eo_prep));
+        ldlm_namespace_free(obddev->obd_namespace, flags & OBD_OPT_FORCE);
+
+        leaked = atomic_read(&obddev->u.echo.eo_prep);
+        if (leaked != 0)
+                CERROR("%d prep/commitrw pages leaked\n", leaked);
 
         RETURN(0);
 }
@@ -479,25 +454,24 @@ int echo_detach(struct obd_device *dev)
 }
 
 static struct obd_ops echo_obd_ops = {
-        o_owner:       THIS_MODULE,
-        o_attach:      echo_attach,
-        o_detach:      echo_detach,
-        o_connect:     echo_connect,
-        o_disconnect:  echo_disconnect,
-        o_create:      echo_create,
-        o_destroy:     echo_destroy,
-        o_open:        echo_open,
-        o_close:       echo_close,
-        o_getattr:     echo_getattr,
-        o_setattr:     echo_setattr,
-        o_preprw:      echo_preprw,
-        o_commitrw:    echo_commitrw,
-        o_setup:       echo_setup,
-        o_cleanup:     echo_cleanup
+        o_owner:           THIS_MODULE,
+        o_attach:          echo_attach,
+        o_detach:          echo_detach,
+        o_connect:         echo_connect,
+        o_disconnect:      echo_disconnect,
+        o_destroy_export:  echo_destroy_export,
+        o_create:          echo_create,
+        o_destroy:         echo_destroy,
+        o_getattr:         echo_getattr,
+        o_setattr:         echo_setattr,
+        o_preprw:          echo_preprw,
+        o_commitrw:        echo_commitrw,
+        o_setup:           echo_setup,
+        o_cleanup:         echo_cleanup
 };
 
 extern int echo_client_init(void);
-extern void echo_client_cleanup(void);
+extern void echo_client_exit(void);
 
 static void
 echo_object0_pages_fini (void)
@@ -541,7 +515,7 @@ static int __init obdecho_init(void)
         struct lprocfs_static_vars lvars;
         int rc;
 
-        printk(KERN_INFO "Lustre Echo OBD driver; info@clusterfs.com\n");
+        printk(KERN_INFO "Lustre: Echo OBD driver; info@clusterfs.com\n");
 
         lprocfs_init_vars(echo, &lvars);
 
@@ -567,7 +541,7 @@ static int __init obdecho_init(void)
 
 static void /*__exit*/ obdecho_exit(void)
 {
-        echo_client_cleanup();
+        echo_client_exit();
         class_unregister_type(OBD_ECHO_DEVICENAME);
         echo_object0_pages_fini ();
 }
diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c
index c01079886f46f294d381ba5450bf3489cb977cc5..87b2f92b691b7771baab359d88a9441cda886291 100644
--- a/lustre/obdecho/echo_client.c
+++ b/lustre/obdecho/echo_client.c
@@ -24,6 +24,7 @@
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/completion.h>
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 #include <linux/iobuf.h>
 #endif
@@ -38,7 +39,8 @@
 #include <linux/obd_echo.h>
 #include <linux/lustre_debug.h>
 #include <linux/lprocfs_status.h>
-#include <linux/lustre_lite.h>                  /* for LL_IOC_LOV_SETSTRIPE */
+
+static obd_id last_object_id;
 
 #if 0
 static void
@@ -47,14 +49,14 @@ echo_printk_object (char *msg, struct ec_object *eco)
         struct lov_stripe_md *lsm = eco->eco_lsm;
         int                   i;
 
-        printk (KERN_INFO "%s: object %p: "LPX64", refs %d%s: "LPX64
-                "=%u!%u@%d\n", msg, eco, eco->eco_id, eco->eco_refcount,
+        printk (KERN_INFO "Lustre: %s: object %p: "LPX64", refs %d%s: "LPX64
+                "=%u!%u\n", msg, eco, eco->eco_id, eco->eco_refcount,
                 eco->eco_deleted ? "(deleted) " : "",
                 lsm->lsm_object_id, lsm->lsm_stripe_size,
-                lsm->lsm_stripe_count, lsm->lsm_stripe_offset);
+                lsm->lsm_stripe_count);
 
         for (i = 0; i < lsm->lsm_stripe_count; i++)
-                printk (KERN_INFO "   [%2u]"LPX64"\n",
+                printk (KERN_INFO "Lustre:   @%2u:"LPX64"\n",
                         lsm->lsm_oinfo[i].loi_ost_idx,
                         lsm->lsm_oinfo[i].loi_id);
 }
@@ -109,15 +111,10 @@ echo_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm,
         if (ulsm_nob < nob ||
             lsm->lsm_stripe_count > ec->ec_nstripes ||
             lsm->lsm_magic != LOV_MAGIC ||
-            (lsm->lsm_stripe_offset != 0 &&
-             lsm->lsm_stripe_offset != 0xffffffff &&
-             lsm->lsm_stripe_offset >= ec->ec_nstripes) ||
             (lsm->lsm_stripe_size & (PAGE_SIZE - 1)) != 0 ||
             ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL))
                 return (-EINVAL);
 
-        LASSERT (ec->ec_lsmsize >= sizeof (*lsm) + nob);
-
         if (copy_from_user(lsm->lsm_oinfo,
                            ((struct lov_stripe_md *)ulsm)->lsm_oinfo, nob))
                 return (-EFAULT);
@@ -130,15 +127,16 @@ echo_allocate_object (struct obd_device *obd)
 {
         struct echo_client_obd *ec = &obd->u.echo_client;
         struct ec_object       *eco;
+        int rc;
 
-        OBD_ALLOC (eco, sizeof (*eco));
+        OBD_ALLOC(eco, sizeof (*eco));
         if (eco == NULL)
-                return (NULL);
+                return NULL;
 
-        OBD_ALLOC (eco->eco_lsm, ec->ec_lsmsize);
-        if (eco->eco_lsm == NULL) {
-                OBD_FREE (eco, sizeof (*eco));
-                return (NULL);
+        rc = obd_alloc_memmd(ec->ec_exp, &eco->eco_lsm);
+        if (rc < 0) {
+                OBD_FREE(eco, sizeof (*eco));
+                return NULL;
         }
 
         eco->eco_device = obd;
@@ -157,20 +155,20 @@ echo_free_object (struct ec_object *eco)
         struct echo_client_obd *ec = &obd->u.echo_client;
 
         LASSERT (eco->eco_refcount == 0);
-        OBD_FREE (eco->eco_lsm, ec->ec_lsmsize);
+        obd_free_memmd(ec->ec_exp, &eco->eco_lsm);
         OBD_FREE (eco, sizeof (*eco));
 }
 
-static int
-echo_create_object (struct obd_device *obd, int on_target, struct obdo *oa,
-                    void *ulsm, int ulsm_nob)
+static int echo_create_object(struct obd_device *obd, int on_target,
+                              struct obdo *oa, void *ulsm, int ulsm_nob,
+                              struct obd_trans_info *oti)
 {
         struct echo_client_obd *ec = &obd->u.echo_client;
         struct ec_object       *eco2;
         struct ec_object       *eco;
         struct lov_stripe_md   *lsm;
         int                     rc;
-        int                     i;
+        int                     i, idx;
 
         if ((oa->o_valid & OBD_MD_FLID) == 0 && /* no obj id */
             (on_target ||                       /* set_stripe */
@@ -179,49 +177,60 @@ echo_create_object (struct obd_device *obd, int on_target, struct obdo *oa,
                 return (-EINVAL);
         }
 
-        eco = echo_allocate_object (obd);
-        if (eco == NULL)
-                return (-ENOMEM);
+        if (ulsm != NULL) {
+                eco = echo_allocate_object (obd);
+                if (eco == NULL)
+                        return (-ENOMEM);
 
-        lsm = eco->eco_lsm;
+                lsm = eco->eco_lsm;
 
-        if (ulsm != NULL) {
                 rc = echo_copyin_lsm (obd, lsm, ulsm, ulsm_nob);
                 if (rc != 0)
                         goto failed;
-        }
 
-        /* setup object ID here for !on_target and LOV hint */
-        if ((oa->o_valid & OBD_MD_FLID) != 0)
-                eco->eco_id = lsm->lsm_object_id = oa->o_id;
+                /* setup object ID here for !on_target and LOV hint */
+                if ((oa->o_valid & OBD_MD_FLID) != 0)
+                        eco->eco_id = lsm->lsm_object_id = oa->o_id;
 
-        /* defaults -> actual values */
-        if (lsm->lsm_stripe_offset == 0xffffffff)
-                lsm->lsm_stripe_offset = 0;
+                if (lsm->lsm_stripe_count == 0)
+                        lsm->lsm_stripe_count = ec->ec_nstripes;
 
-        if (lsm->lsm_stripe_count == 0)
-                lsm->lsm_stripe_count = ec->ec_nstripes;
+                if (lsm->lsm_stripe_size == 0)
+                        lsm->lsm_stripe_size = PAGE_SIZE;
 
-        if (lsm->lsm_stripe_size == 0)
-                lsm->lsm_stripe_size = PAGE_SIZE;
+                idx = ll_insecure_random_int();
 
-        /* setup stripes: indices + default ids if required */
-        for (i = 0; i < lsm->lsm_stripe_count; i++) {
-                if (lsm->lsm_oinfo[i].loi_id == 0)
-                        lsm->lsm_oinfo[i].loi_id = lsm->lsm_object_id;
+                /* setup stripes: indices + default ids if required */
+                for (i = 0; i < lsm->lsm_stripe_count; i++) {
+                        if (lsm->lsm_oinfo[i].loi_id == 0)
+                                lsm->lsm_oinfo[i].loi_id = lsm->lsm_object_id;
 
-                lsm->lsm_oinfo[i].loi_ost_idx =
-                        (lsm->lsm_stripe_offset + i) % ec->ec_nstripes;
+                        lsm->lsm_oinfo[i].loi_ost_idx =
+                                (idx + i) % ec->ec_nstripes;
+                }
+        } else {
+                OBD_ALLOC(eco, sizeof(*eco));
+                eco->eco_device = obd;
+                lsm = NULL;
         }
 
+        if (oa->o_id == 0)
+                oa->o_id = ++last_object_id;
+
         if (on_target) {
-                rc = obd_create (&ec->ec_conn, oa, &lsm, NULL);
+                /* XXX get some filter group constants */
+                oa->o_gr = 2;
+                oa->o_valid |= OBD_MD_FLGROUP;
+                rc = obd_create(ec->ec_exp, oa, &lsm, oti);
                 if (rc != 0)
                         goto failed;
 
                 /* See what object ID we were given */
-                LASSERT ((oa->o_valid & OBD_MD_FLID) != 0);
-                eco->eco_id = lsm->lsm_object_id = oa->o_id;
+                eco->eco_id = oa->o_id = lsm->lsm_object_id;
+                oa->o_valid |= OBD_MD_FLID;
+
+                LASSERT(eco->eco_lsm == NULL || eco->eco_lsm == lsm);
+                eco->eco_lsm = lsm;
         }
 
         spin_lock (&ec->ec_lock);
@@ -234,7 +243,7 @@ echo_create_object (struct obd_device *obd, int on_target, struct obdo *oa,
                         oa->o_id, on_target ? " (undoing create)" : "");
 
                 if (on_target)
-                        obd_destroy (&ec->ec_conn, oa, lsm, NULL);
+                        obd_destroy(ec->ec_exp, oa, lsm, oti);
 
                 rc = -EEXIST;
                 goto failed;
@@ -243,11 +252,11 @@ echo_create_object (struct obd_device *obd, int on_target, struct obdo *oa,
         list_add (&eco->eco_obj_chain, &ec->ec_objects);
         spin_unlock (&ec->ec_lock);
         CDEBUG (D_INFO,
-                "created %p: "LPX64"=%u#%u&%d refs %d del %d\n",
+                "created %p: "LPX64"=%u#%u@%u refs %d del %d\n",
                 eco, eco->eco_id,
                 eco->eco_lsm->lsm_stripe_size,
                 eco->eco_lsm->lsm_stripe_count,
-                eco->eco_lsm->lsm_stripe_offset,
+                eco->eco_lsm->lsm_oinfo[0].loi_ost_idx,
                 eco->eco_refcount, eco->eco_deleted);
         return (0);
 
@@ -281,11 +290,11 @@ echo_get_object (struct ec_object **ecop, struct obd_device *obd,
                 spin_unlock (&ec->ec_lock);
                 *ecop = eco;
                 CDEBUG (D_INFO,
-                        "found %p: "LPX64"=%u#%u&%d refs %d del %d\n",
+                        "found %p: "LPX64"=%u#%u@%u refs %d del %d\n",
                         eco, eco->eco_id,
                         eco->eco_lsm->lsm_stripe_size,
                         eco->eco_lsm->lsm_stripe_count,
-                        eco->eco_lsm->lsm_stripe_offset,
+                        eco->eco_lsm->lsm_oinfo[0].loi_ost_idx,
                         eco->eco_refcount, eco->eco_deleted);
                 return (0);
         }
@@ -309,11 +318,11 @@ echo_get_object (struct ec_object **ecop, struct obd_device *obd,
                 eco->eco_refcount = 1;
                 *ecop = eco;
                 CDEBUG (D_INFO,
-                        "created %p: "LPX64"=%u#%u&%d refs %d del %d\n",
+                        "created %p: "LPX64"=%u#%u@%d refs %d del %d\n",
                         eco, eco->eco_id,
                         eco->eco_lsm->lsm_stripe_size,
                         eco->eco_lsm->lsm_stripe_count,
-                        eco->eco_lsm->lsm_stripe_offset,
+                        eco->eco_lsm->lsm_oinfo[0].loi_ost_idx,
                         eco->eco_refcount, eco->eco_deleted);
                 return (0);
         }
@@ -326,11 +335,11 @@ echo_get_object (struct ec_object **ecop, struct obd_device *obd,
                 rc = 0;
                 LASSERT (eco2->eco_id == eco2->eco_lsm->lsm_object_id);
                 CDEBUG (D_INFO,
-                        "found(2) %p: "LPX64"=%u#%u&%d refs %d del %d\n",
+                        "found(2) %p: "LPX64"=%u#%u@%d refs %d del %d\n",
                         eco2, eco2->eco_id,
                         eco2->eco_lsm->lsm_stripe_size,
                         eco2->eco_lsm->lsm_stripe_count,
-                        eco2->eco_lsm->lsm_stripe_offset,
+                        eco2->eco_lsm->lsm_oinfo[0].loi_ost_idx,
                         eco2->eco_refcount, eco2->eco_deleted);
         }
 
@@ -355,11 +364,11 @@ echo_put_object (struct ec_object *eco)
         eco->eco_refcount--;
         LASSERT (eco->eco_refcount >= 0);
 
-        CDEBUG(D_INFO, "put %p: "LPX64"=%u#%u&%d refs %d del %d\n",
+        CDEBUG(D_INFO, "put %p: "LPX64"=%u#%u@%d refs %d del %d\n",
                eco, eco->eco_id,
                eco->eco_lsm->lsm_stripe_size,
                eco->eco_lsm->lsm_stripe_count,
-               eco->eco_lsm->lsm_stripe_offset,
+               eco->eco_lsm->lsm_oinfo[0].loi_ost_idx,
                eco->eco_refcount, eco->eco_deleted);
 
         if (eco->eco_refcount != 0 || !eco->eco_deleted) {
@@ -373,7 +382,7 @@ echo_put_object (struct ec_object *eco)
          * attempting to enqueue on this object number until we can be
          * sure there will be no more lock callbacks.
          */
-        obd_cancel_unused(&ec->ec_conn, eco->eco_lsm, 0, NULL);
+        obd_cancel_unused(ec->ec_exp, eco->eco_lsm, 0, NULL);
 
         /* now we can let it go */
         spin_lock (&ec->ec_lock);
@@ -414,10 +423,9 @@ echo_get_stripe_off_id (struct lov_stripe_md *lsm, obd_off *offp, obd_id *idp)
         *offp = offset * stripe_size + woffset % stripe_size;
 }
 
-static int
-echo_client_kbrw (struct obd_device *obd, int rw,
-                  struct obdo *oa, struct lov_stripe_md *lsm,
-                  obd_off offset, obd_size count)
+static int echo_client_kbrw(struct obd_device *obd, int rw, struct obdo *oa,
+                            struct lov_stripe_md *lsm, obd_off offset,
+                            obd_size count, struct obd_trans_info *oti)
 {
         struct echo_client_obd *ec = &obd->u.echo_client;
         obd_count               npages;
@@ -477,14 +485,14 @@ echo_client_kbrw (struct obd_device *obd, int rw,
                                                  stripe_off, stripe_id);
                         } else {
                                 page_debug_setup(addr, pgp->count,
-                                                 0xdeadbeef00c0ffee,
-                                                 0xdeadbeef00c0ffee);
+                                                 0xdeadbeef00c0ffeeULL,
+                                                 0xdeadbeef00c0ffeeULL);
                         }
                         kunmap(pgp->pg);
                 }
         }
 
-        rc = obd_brw(rw, &ec->ec_conn, oa, lsm, npages, pga, NULL);
+        rc = obd_brw(rw, ec->ec_exp, oa, lsm, npages, pga, oti);
 
  out:
         if (rc != 0)
@@ -518,7 +526,8 @@ echo_client_kbrw (struct obd_device *obd, int rw,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 static int echo_client_ubrw(struct obd_device *obd, int rw,
                             struct obdo *oa, struct lov_stripe_md *lsm,
-                            obd_off offset, obd_size count, char *buffer)
+                            obd_off offset, obd_size count, char *buffer,
+                            struct obd_trans_info *oti)
 {
         struct echo_client_obd *ec = &obd->u.echo_client;
         obd_count               npages;
@@ -568,7 +577,7 @@ static int echo_client_ubrw(struct obd_device *obd, int rw,
                 pgp->flag = 0;
         }
 
-        rc = obd_brw(rw, &ec->ec_conn, oa, lsm, npages, pga, NULL);
+        rc = obd_brw(rw, ec->ec_exp, oa, lsm, npages, pga, oti);
 
         //        if (rw == OBD_BRW_READ)
         //                mark_dirty_kiobuf (kiobuf, count);
@@ -583,92 +592,385 @@ static int echo_client_ubrw(struct obd_device *obd, int rw,
 #else
 static int echo_client_ubrw(struct obd_device *obd, int rw,
                             struct obdo *oa, struct lov_stripe_md *lsm,
-                            obd_off offset, obd_size count, char *buffer)
+                            obd_off offset, obd_size count, char *buffer,
+                            struct obd_trans_info *oti)
 {
+#warning "echo_client_ubrw() needs to be ported on 2.6 yet"
         LBUG();
         return 0;
 }
 #endif
 #endif
 
-static int
-echo_open (struct obd_export *exp, struct obdo *oa)
-{
-        struct obd_device      *obd = exp->exp_obd;
-        struct echo_client_obd *ec = &obd->u.echo_client;
-        struct lustre_handle   *ufh = obdo_handle (oa);
-        struct ec_open_object  *ecoo;
-        struct ec_object       *eco;
-        int                     rc;
+struct echo_async_state;
 
-        rc = echo_get_object (&eco, obd, oa);
-        if (rc != 0)
-                return rc;
-
-        rc = -ENOMEM;
-        OBD_ALLOC (ecoo, sizeof (*ecoo));
-        if (ecoo == NULL)
-                goto failed_0;
+#define EAP_MAGIC 79277927
+struct echo_async_page {
+        int                     eap_magic;
+        struct page             *eap_page;
+        void                    *eap_cookie;
+        obd_off                 eap_off;
+        struct echo_async_state *eap_eas;
+        struct list_head        eap_item;
+};
 
-        rc = obd_open(&ec->ec_conn, oa, eco->eco_lsm, NULL, &ecoo->ecoo_och);
-        if (rc != 0)
-                goto failed_1;
+struct echo_async_state {
+        spinlock_t              eas_lock;
+        obd_off                 eas_next_offset;
+        obd_off                 eas_end_offset;
+        int                     eas_in_flight;
+        int                     eas_rc;
+        wait_queue_head_t       eas_waitq;
+        struct list_head        eas_avail;
+        struct obdo             eas_oa;
+};
 
-        memcpy (&ecoo->ecoo_oa, oa, sizeof (*oa));
-        ecoo->ecoo_object = eco;
-        /* ecoo takes ref from echo_get_object() above */
+static int eas_should_wake(struct echo_async_state *eas)
+{
+        unsigned long flags;
+        int rc = 0;
+        spin_lock_irqsave(&eas->eas_lock, flags);
+        if (eas->eas_rc == 0 && !list_empty(&eas->eas_avail))
+            rc = 1;
+        spin_unlock_irqrestore(&eas->eas_lock, flags);
+        return rc;
+};
 
-        spin_lock (&ec->ec_lock);
+struct echo_async_page *eap_from_cookie(void *cookie)
+{
+        struct echo_async_page *eap = cookie;
+        if (eap->eap_magic != EAP_MAGIC)
+                return ERR_PTR(-EINVAL);
+        return eap;
+};
 
-        list_add (&ecoo->ecoo_exp_chain, &exp->exp_ec_data.eced_open_head);
-        ufh->cookie = ecoo->ecoo_cookie = ec->ec_unique++;
-        spin_unlock (&ec->ec_lock);
+static int ec_ap_make_ready(void *data, int cmd)
+{
+        /* our pages are issued ready */
+        LBUG();
         return 0;
+}
+static int ec_ap_refresh_count(void *data, int cmd)
+{
+        /* our pages are issued with a stable count */
+        LBUG();
+        return PAGE_SIZE;
+}
+static void ec_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
+{
+        struct echo_async_page *eap;
+        eap = eap_from_cookie(data);
+        if (IS_ERR(eap))
+                return;
 
- failed_1:
-        OBD_FREE (ecoo, sizeof (*ecoo));
- failed_0:
-        echo_put_object (eco);
-        return (rc);
+        memcpy(oa, &eap->eap_eas->eas_oa, sizeof(*oa));
 }
+static void ec_ap_completion(void *data, int cmd, int rc)
+{
+        struct echo_async_page *eap = eap_from_cookie(data);
+        struct echo_async_state *eas;
+        unsigned long flags;
 
-static int
-echo_close (struct obd_export *exp, struct obdo *oa)
+        if (IS_ERR(eap))
+                return;
+        eas = eap->eap_eas;
+
+        spin_lock_irqsave(&eas->eas_lock, flags);
+        if (rc && !eas->eas_rc)
+                eas->eas_rc = rc;
+        eas->eas_in_flight--;
+        list_add(&eap->eap_item, &eas->eas_avail);
+        wake_up(&eas->eas_waitq);
+        spin_unlock_irqrestore(&eas->eas_lock, flags);
+}
+
+static struct obd_async_page_ops ec_async_page_ops = {
+        .ap_make_ready =        ec_ap_make_ready,
+        .ap_refresh_count =     ec_ap_refresh_count,
+        .ap_fill_obdo =         ec_ap_fill_obdo,
+        .ap_completion =        ec_ap_completion,
+};
+
+static int echo_client_async_page(struct obd_export *exp, int rw,
+                                   struct obdo *oa, struct lov_stripe_md *lsm,
+                                   obd_off offset, obd_size count,
+                                   obd_size batching)
 {
-        struct obd_device      *obd = exp->exp_obd;
-        struct echo_client_obd *ec = &obd->u.echo_client;
-        struct lustre_handle   *ufh = obdo_handle (oa);
-        struct ec_open_object  *ecoo = NULL;
-        int                     found = 0;
-        struct list_head       *el;
-        int                     rc;
+        obd_count npages, i;
+        struct echo_async_page *eap;
+        struct echo_async_state eas;
+        struct list_head *pos, *n;
+        int rc = 0;
+        unsigned long flags;
+        LIST_HEAD(pages);
+#if 0
+        int                     verify;
+        int                     gfp_mask;
+        /* oa_id  == 0    => speed test (no verification) else...
+         * oa & 1         => use HIGHMEM
+         */
+        verify = (oa->o_id != 0);
+        gfp_mask = ((oa->o_id & 1) == 0) ? GFP_KERNEL : GFP_HIGHUSER;
+#endif
 
-        if ((oa->o_valid & OBD_MD_FLHANDLE) == 0)
-                return -EINVAL;
+        LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ);
 
-        spin_lock (&ec->ec_lock);
+        if (count <= 0 ||
+            (count & (PAGE_SIZE - 1)) != 0 ||
+            (lsm != NULL &&
+             lsm->lsm_object_id != oa->o_id))
+                return (-EINVAL);
 
-        list_for_each (el, &exp->exp_ec_data.eced_open_head) {
-                ecoo = list_entry (el, struct ec_open_object, ecoo_exp_chain);
-                found = (ecoo->ecoo_cookie == ufh->cookie);
-                if (found) {
-                        list_del (&ecoo->ecoo_exp_chain);
+        /* XXX think again with misaligned I/O */
+        npages = batching >> PAGE_SHIFT;
+
+        memcpy(&eas.eas_oa, oa, sizeof(*oa));
+        eas.eas_next_offset = offset;
+        eas.eas_end_offset = offset + count;
+        spin_lock_init(&eas.eas_lock);
+        init_waitqueue_head(&eas.eas_waitq);
+        eas.eas_in_flight = 0;
+        eas.eas_rc = 0;
+        INIT_LIST_HEAD(&eas.eas_avail);
+
+        /* prepare the group of pages that we're going to be keeping
+         * in flight */
+        for (i = 0; i < npages; i++) {
+                struct page *page = alloc_page(GFP_KERNEL);
+                if (page == NULL)
+                        GOTO(out, rc = -ENOMEM);
+
+                list_add_tail(&page->list, &pages);
+
+                OBD_ALLOC(eap, sizeof(*eap));
+                if (eap == NULL)
+                        GOTO(out, rc = -ENOMEM);
+
+                eap->eap_magic = EAP_MAGIC;
+                eap->eap_page = page;
+                eap->eap_eas = &eas;
+                eap->eap_cookie = ERR_PTR(-ENOENT);
+                list_add_tail(&eap->eap_item, &eas.eas_avail);
+        }
+
+        /* first we spin queueing io and being woken by its completion */
+        spin_lock_irqsave(&eas.eas_lock, flags);
+        for(;;) {
+                int rc;
+
+                /* sleep until we have a page to send */
+                spin_unlock_irqrestore(&eas.eas_lock, flags);
+                rc = wait_event_interruptible(eas.eas_waitq, 
+                                              eas_should_wake(&eas));
+                spin_lock_irqsave(&eas.eas_lock, flags);
+                if (rc && !eas.eas_rc)
+                        eas.eas_rc = rc;
+                if (eas.eas_rc)
+                        break;
+                if (list_empty(&eas.eas_avail))
+                        continue;
+                eap = list_entry(eas.eas_avail.next, struct echo_async_page,
+                                 eap_item);
+                list_del(&eap->eap_item);
+                spin_unlock_irqrestore(&eas.eas_lock, flags);
+
+                /* unbind the eap from its old page offset */
+                if (!IS_ERR(eap->eap_cookie)) {
+                        obd_teardown_async_page(exp, lsm, NULL, 
+                                                eap->eap_cookie);
+                        eap->eap_cookie = ERR_PTR(-ENOENT);
+                }
+
+                eas.eas_next_offset += PAGE_SIZE;
+                eap->eap_off = eas.eas_next_offset;
+
+                rc = obd_prep_async_page(exp, lsm, NULL, eap->eap_page, 
+                                         eap->eap_off, &ec_async_page_ops, 
+                                         eap, &eap->eap_cookie);
+                if (rc) {
+                        spin_lock_irqsave(&eas.eas_lock, flags);
+                        eas.eas_rc = rc;
                         break;
                 }
+
+                /* always asserts urgent, which isn't quite right */
+                rc = obd_queue_async_io(exp, lsm, NULL, eap->eap_cookie, 
+                                        rw, 0, PAGE_SIZE, 0, 
+                                        ASYNC_READY | ASYNC_URGENT |
+                                        ASYNC_COUNT_STABLE);
+                spin_lock_irqsave(&eas.eas_lock, flags);
+                if (rc && !eas.eas_rc) {
+                        eas.eas_rc = rc;
+                        break;
+                }
+                eas.eas_in_flight++;
+                if (eas.eas_next_offset == eas.eas_end_offset)
+                        break;
+        } 
+
+        /* still hold the eas_lock here.. */
+
+        /* now we just spin waiting for all the rpcs to complete */
+        while(eas.eas_in_flight) {
+                spin_unlock_irqrestore(&eas.eas_lock, flags);
+                wait_event_interruptible(eas.eas_waitq, 
+                                         eas.eas_in_flight == 0);
+                spin_lock_irqsave(&eas.eas_lock, flags);
+        }
+        spin_unlock_irqrestore(&eas.eas_lock, flags);
+
+out:
+        list_for_each_safe(pos, n, &pages) {
+                struct page *page = list_entry(pos, struct page, list);
+
+                list_del(&page->list);
+                if (page->private) {
+                        eap = (struct echo_async_page *)page->private;
+                        if (!IS_ERR(eap->eap_cookie))
+                                obd_teardown_async_page(exp, lsm, NULL, 
+                                                        eap->eap_cookie);
+                        OBD_FREE(eap, sizeof(*eap));
+                }
+                __free_page(page);
         }
 
-        spin_unlock (&ec->ec_lock);
+        RETURN(rc);
+}
 
-        memcpy(&ecoo->ecoo_oa.o_inline, &ecoo->ecoo_och, FD_OSTDATA_SIZE);
-        ecoo->ecoo_oa.o_valid |= OBD_MD_FLHANDLE;
+static int echo_client_prep_commit(struct obd_export *exp, int rw,
+                                   struct obdo *oa, struct lov_stripe_md *lsm,
+                                   obd_off offset, obd_size count,  
+                                   obd_size batch, struct obd_trans_info *oti)
+{
+        struct obd_ioobj ioo;
+        struct niobuf_local *lnb;
+        struct niobuf_remote *rnb;
+        obd_off off;
+        obd_size npages, tot_pages;
+        int i, ret = 0, err = 0;
+        ENTRY;
 
-        rc = obd_close (&ec->ec_conn, &ecoo->ecoo_oa,
-                        ecoo->ecoo_object->eco_lsm, NULL);
+        if (count <= 0 || (count & (PAGE_SIZE - 1)) != 0 ||
+            (lsm != NULL && lsm->lsm_object_id != oa->o_id))
+                RETURN(-EINVAL);
 
-        echo_put_object (ecoo->ecoo_object);
-        OBD_FREE (ecoo, sizeof (*ecoo));
+        npages = batch >> PAGE_SHIFT;
+        tot_pages = count >> PAGE_SHIFT;
 
-        return (rc);
+        OBD_ALLOC(lnb, npages * sizeof(struct niobuf_local));
+        OBD_ALLOC(rnb, npages * sizeof(struct niobuf_remote));
+
+        if (lnb == NULL || rnb == NULL)
+                GOTO(out, ret = -ENOMEM);
+
+        obdo_to_ioobj(oa, &ioo);
+        ioo.ioo_bufcnt = npages;
+
+        off = offset;
+
+        for(; tot_pages; tot_pages -= npages) {
+                if (tot_pages < npages)
+                        npages = tot_pages;
+
+                for (i = 0; i < npages; i++, off += PAGE_SIZE) {
+                        rnb[i].offset = off;
+                        rnb[i].len = PAGE_SIZE;
+                }
+
+                /* XXX this can't be the best.. */
+                memset(oti, 0, sizeof(*oti));
+
+                ret = obd_preprw(rw, exp, oa, 1, &ioo, npages, rnb, lnb, oti);
+                if (ret != 0)
+                        GOTO(out, ret);
+
+                for (i = 0; i < npages; i++) {
+                        struct page *page = lnb[i].page;
+                        void *addr;
+
+                        /* read past eof? */
+                        if (page == NULL && lnb[i].rc == 0) 
+                                continue;
+
+                        addr = kmap(lnb[i].page);
+
+                        if (rw == OBD_BRW_WRITE) 
+                                page_debug_setup(addr, PAGE_SIZE,
+                                                 rnb[i].offset, oa->o_id);
+                        else 
+                                err = page_debug_check("prep_commit", addr, 
+                                                 PAGE_SIZE, rnb[i].offset,
+                                                 oa->o_id);
+
+                        kunmap(lnb[i].page);
+                }
+
+                ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti);
+                if (ret != 0)
+                        GOTO(out, ret);
+                if (err)
+                        GOTO(out, ret = err);
+        }
+
+out:
+        if (lnb)
+                OBD_FREE(lnb, npages * sizeof(struct niobuf_local));
+        if (rnb)
+                OBD_FREE(rnb, npages * sizeof(struct niobuf_remote));
+        RETURN(ret);
+}
+
+int echo_client_brw_ioctl(int rw, struct obd_export *exp, 
+                          struct obd_ioctl_data *data)
+{
+        struct obd_device *obd = class_exp2obd(exp);
+        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct obd_trans_info dummy_oti;
+        struct ec_object *eco;
+        int rc;
+        ENTRY;
+
+        rc = echo_get_object(&eco, obd, &data->ioc_obdo1);
+        if (rc)
+                RETURN(rc);
+
+        memset(&dummy_oti, 0, sizeof(dummy_oti));
+
+        data->ioc_obdo1.o_valid &= ~OBD_MD_FLHANDLE;
+        data->ioc_obdo1.o_valid |= OBD_MD_FLGROUP;
+        data->ioc_obdo1.o_gr = 2;
+
+        switch((long)data->ioc_pbuf1) {
+        case 1:
+                if (data->ioc_pbuf2 == NULL) { // NULL user data pointer
+                        rc = echo_client_kbrw(obd, rw, &data->ioc_obdo1,
+                                              eco->eco_lsm, data->ioc_offset,
+                                              data->ioc_count, &dummy_oti);
+                } else {
+#ifdef __KERNEL__
+                        rc = echo_client_ubrw(obd, rw, &data->ioc_obdo1,
+                                              eco->eco_lsm, data->ioc_offset,
+                                              data->ioc_count, data->ioc_pbuf2,
+                                              &dummy_oti);
+#endif
+                }
+                break;
+        case 2:
+                rc = echo_client_async_page(ec->ec_exp, rw, &data->ioc_obdo1,
+                                           eco->eco_lsm, data->ioc_offset,
+                                           data->ioc_count, data->ioc_plen1);
+                break;
+        case 3:
+                rc = echo_client_prep_commit(ec->ec_exp, rw, &data->ioc_obdo1,
+                                            eco->eco_lsm, data->ioc_offset,
+                                            data->ioc_count, data->ioc_plen1,
+                                            &dummy_oti);
+                break;
+        default:
+                rc = -EINVAL;
+        }
+        echo_put_object(eco);
+        RETURN(rc);
 }
 
 static int
@@ -717,8 +1019,8 @@ echo_ldlm_callback (struct ldlm_lock *lock, struct ldlm_lock_desc *new,
 }
 
 static int
-echo_enqueue (struct obd_export *exp, struct obdo *oa,
-              int mode, obd_off offset, obd_size nob)
+echo_client_enqueue(struct obd_export *exp, struct obdo *oa,
+                    int mode, obd_off offset, obd_size nob)
 {
         struct obd_device      *obd = exp->exp_obd;
         struct echo_client_obd *ec = &obd->u.echo_client;
@@ -750,7 +1052,7 @@ echo_enqueue (struct obd_export *exp, struct obdo *oa,
         ecl->ecl_extent.end = (nob == 0) ? ((obd_off) -1) : (offset + nob - 1);
 
         flags = 0;
-        rc = obd_enqueue(&ec->ec_conn, eco->eco_lsm, NULL, LDLM_EXTENT,
+        rc = obd_enqueue(ec->ec_exp, eco->eco_lsm, NULL, LDLM_EXTENT,
                          &ecl->ecl_extent,sizeof(ecl->ecl_extent), mode,
                          &flags, echo_ldlm_callback, eco,
                          &ecl->ecl_lock_handle);
@@ -778,7 +1080,7 @@ echo_enqueue (struct obd_export *exp, struct obdo *oa,
 }
 
 static int
-echo_cancel (struct obd_export *exp, struct obdo *oa)
+echo_client_cancel(struct obd_export *exp, struct obdo *oa)
 {
         struct obd_device      *obd = exp->exp_obd;
         struct echo_client_obd *ec = &obd->u.echo_client;
@@ -807,7 +1109,7 @@ echo_cancel (struct obd_export *exp, struct obdo *oa)
         if (!found)
                 return (-ENOENT);
 
-        rc = obd_cancel(&ec->ec_conn, ecl->ecl_object->eco_lsm, ecl->ecl_mode,
+        rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm, ecl->ecl_mode,
                         &ecl->ecl_lock_handle);
 
         echo_put_object (ecl->ecl_object);
@@ -816,22 +1118,23 @@ echo_cancel (struct obd_export *exp, struct obdo *oa)
         return rc;
 }
 
-static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
-                          int len, void *karg, void *uarg)
+static int
+echo_client_iocontrol(unsigned int cmd, struct obd_export *exp,
+                      int len, void *karg, void *uarg)
 {
-        struct obd_export      *exp = class_conn2export (obdconn);
         struct obd_device      *obd;
         struct echo_client_obd *ec;
         struct ec_object       *eco;
         struct obd_ioctl_data  *data = karg;
+        struct obd_trans_info   dummy_oti;
+        struct oti_req_ack_lock *ack_lock;
+        struct obdo            *oa;
         int                     rw = OBD_BRW_READ;
         int                     rc = 0;
+        int                     i;
         ENTRY;
 
-        if (exp == NULL) {
-                CERROR("ioctl: No device\n");
-                GOTO(out, rc = -EINVAL);
-        }
+        memset(&dummy_oti, 0, sizeof(dummy_oti));
 
         obd = exp->exp_obd;
         ec = &obd->u.echo_client;
@@ -842,7 +1145,8 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
                         GOTO (out, rc = -EPERM);
 
                 rc = echo_create_object (obd, 1, &data->ioc_obdo1,
-                                         data->ioc_pbuf1, data->ioc_plen1);
+                                         data->ioc_pbuf1, data->ioc_plen1,
+                                         &dummy_oti);
                 GOTO(out, rc);
 
         case OBD_IOC_DESTROY:
@@ -851,8 +1155,11 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
 
                 rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
                 if (rc == 0) {
-                        rc = obd_destroy(&ec->ec_conn, &data->ioc_obdo1,
-                                         eco->eco_lsm, NULL);
+                        oa = &data->ioc_obdo1;
+                        oa->o_gr = 2;
+                        oa->o_valid |= OBD_MD_FLGROUP;
+                        rc = obd_destroy(ec->ec_exp, oa, eco->eco_lsm, 
+                                         &dummy_oti);
                         if (rc == 0)
                                 eco->eco_deleted = 1;
                         echo_put_object(eco);
@@ -862,7 +1169,7 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
         case OBD_IOC_GETATTR:
                 rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
                 if (rc == 0) {
-                        rc = obd_getattr(&ec->ec_conn, &data->ioc_obdo1,
+                        rc = obd_getattr(ec->ec_exp, &data->ioc_obdo1,
                                          eco->eco_lsm);
                         echo_put_object(eco);
                 }
@@ -874,20 +1181,12 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
 
                 rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
                 if (rc == 0) {
-                        rc = obd_setattr(&ec->ec_conn, &data->ioc_obdo1,
+                        rc = obd_setattr(ec->ec_exp, &data->ioc_obdo1,
                                          eco->eco_lsm, NULL);
                         echo_put_object(eco);
                 }
                 GOTO(out, rc);
 
-        case OBD_IOC_OPEN:
-                rc = echo_open (exp, &data->ioc_obdo1);
-                GOTO(out, rc);
-
-        case OBD_IOC_CLOSE:
-                rc = echo_close (exp, &data->ioc_obdo1);
-                GOTO(out, rc);
-
         case OBD_IOC_BRW_WRITE:
                 if (!capable (CAP_SYS_ADMIN))
                         GOTO (out, rc = -EPERM);
@@ -895,23 +1194,7 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
                 rw = OBD_BRW_WRITE;
                 /* fall through */
         case OBD_IOC_BRW_READ:
-                rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
-                if (rc == 0) {
-                        if (data->ioc_pbuf2 == NULL) // NULL user data pointer
-                                rc = echo_client_kbrw(obd, rw, &data->ioc_obdo1,
-                                                      eco->eco_lsm,
-                                                      data->ioc_offset,
-                                                      data->ioc_count);
-                        else
-#ifdef __KERNEL__
-                                rc = echo_client_ubrw(obd, rw, &data->ioc_obdo1,
-                                                      eco->eco_lsm,
-                                                      data->ioc_offset,
-                                                      data->ioc_count,
-                                                      data->ioc_pbuf2);
-#endif
-                        echo_put_object(eco);
-                }
+                rc = echo_client_brw_ioctl(rw, exp, data);
                 GOTO(out, rc);
 
         case ECHO_IOC_GET_STRIPE:
@@ -936,7 +1219,7 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
                 } else {
                         rc = echo_create_object(obd, 0, &data->ioc_obdo1,
                                                 data->ioc_pbuf1,
-                                                data->ioc_plen1);
+                                                data->ioc_plen1, &dummy_oti);
                 }
                 GOTO (out, rc);
 
@@ -944,13 +1227,13 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
                 if (!capable (CAP_SYS_ADMIN))
                         GOTO (out, rc = -EPERM);
 
-                rc = echo_enqueue (exp, &data->ioc_obdo1,
-                                   data->ioc_conn1, /* lock mode */
+                rc = echo_client_enqueue(exp, &data->ioc_obdo1,
+                                         data->ioc_conn1, /* lock mode */
                                    data->ioc_offset, data->ioc_count);/*extent*/
                 GOTO (out, rc);
 
         case ECHO_IOC_CANCEL:
-                rc = echo_cancel (exp, &data->ioc_obdo1);
+                rc = echo_client_cancel(exp, &data->ioc_obdo1);
                 GOTO (out, rc);
 
         default:
@@ -960,29 +1243,38 @@ static int echo_iocontrol(unsigned int cmd, struct lustre_handle *obdconn,
 
         EXIT;
  out:
-        class_export_put(exp);
+
+        /* XXX this should be in a helper also called by target_send_reply */
+        for (ack_lock = dummy_oti.oti_ack_locks, i = 0; i < 4; 
+             i++, ack_lock++) {
+                if (!ack_lock->mode)
+                        break;
+                ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);
+        }
+
         return rc;
 }
 
-static int echo_setup(struct obd_device *obddev, obd_count len, void *buf)
+static int
+echo_client_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         struct echo_client_obd *ec = &obddev->u.echo_client;
         struct obd_device *tgt;
-        struct lov_stripe_md *lsm = NULL;
+        struct lustre_handle conn = {0, };
         struct obd_uuid echo_uuid = { "ECHO_UUID" };
         int rc;
         ENTRY;
 
-        if (data->ioc_inllen1 < 1) {
+        if (lcfg->lcfg_inllen1 < 1) {
                 CERROR("requires a TARGET OBD name\n");
                 RETURN(-EINVAL);
         }
 
-        tgt = class_name2obd(data->ioc_inlbuf1);
+        tgt = class_name2obd(lcfg->lcfg_inlbuf1);
         if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
-                CERROR("device not attached or not set up (%d/%s)\n",
-                       data->ioc_dev, data->ioc_inlbuf1);
+                CERROR("device not attached or not set up (%s)\n",
+                       lcfg->lcfg_inlbuf1);
                 RETURN(-EINVAL);
         }
 
@@ -990,26 +1282,17 @@ static int echo_setup(struct obd_device *obddev, obd_count len, void *buf)
         INIT_LIST_HEAD (&ec->ec_objects);
         ec->ec_unique = 0;
 
-        rc = obd_connect(&ec->ec_conn, tgt, &echo_uuid);
+        rc = obd_connect(&conn, tgt, &echo_uuid);
         if (rc) {
-                CERROR("fail to connect to device %d\n", data->ioc_dev);
+                CERROR("fail to connect to device %s\n", lcfg->lcfg_inlbuf1);
                 return (rc);
         }
-
-        ec->ec_lsmsize = obd_alloc_memmd (&ec->ec_conn, &lsm);
-        if (ec->ec_lsmsize < 0) {
-                CERROR ("Can't get # stripes: %d\n", rc);
-                obd_disconnect (&ec->ec_conn, 0);
-                rc = ec->ec_lsmsize;
-        } else {
-                ec->ec_nstripes = lsm->lsm_stripe_count;
-                obd_free_memmd (&ec->ec_conn, &lsm);
-        }
+        ec->ec_exp = class_conn2export(&conn);
 
         RETURN(rc);
 }
 
-static int echo_cleanup(struct obd_device *obddev, int flags)
+static int echo_client_cleanup(struct obd_device *obddev, int flags)
 {
         struct list_head       *el;
         struct ec_object       *eco;
@@ -1033,23 +1316,22 @@ static int echo_cleanup(struct obd_device *obddev, int flags)
                 echo_put_object(eco);
         }
 
-        rc = obd_disconnect(&ec->ec_conn, 0);
+        rc = obd_disconnect(ec->ec_exp, 0);
         if (rc != 0)
                 CERROR("fail to disconnect device: %d\n", rc);
 
         RETURN(rc);
 }
 
-static int echo_connect(struct lustre_handle *conn, struct obd_device *src,
-                        struct obd_uuid *cluuid)
+static int echo_client_connect(struct lustre_handle *conn,
+                               struct obd_device *src, struct obd_uuid *cluuid)
 {
         struct obd_export *exp;
         int                rc;
 
         rc = class_connect(conn, src, cluuid);
         if (rc == 0) {
-                exp = class_conn2export (conn);
-                INIT_LIST_HEAD(&exp->exp_ec_data.eced_open_head);
+                exp = class_conn2export(conn);
                 INIT_LIST_HEAD(&exp->exp_ec_data.eced_locks);
                 class_export_put(exp);
         }
@@ -1057,14 +1339,13 @@ static int echo_connect(struct lustre_handle *conn, struct obd_device *src,
         RETURN (rc);
 }
 
-static int echo_disconnect(struct lustre_handle *conn, int flags)
+static int echo_client_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_export      *exp = class_conn2export (conn);
         struct obd_device      *obd;
         struct echo_client_obd *ec;
-        struct ec_open_object  *ecoo;
         struct ec_lock         *ecl;
         int                     rc;
+        ENTRY;
 
         if (exp == NULL)
                 GOTO(out, rc = -EINVAL);
@@ -1078,50 +1359,29 @@ static int echo_disconnect(struct lustre_handle *conn, int flags)
                                   struct ec_lock, ecl_exp_chain);
                 list_del (&ecl->ecl_exp_chain);
 
-                rc = obd_cancel (&ec->ec_conn, ecl->ecl_object->eco_lsm,
+                rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm,
                                  ecl->ecl_mode, &ecl->ecl_lock_handle);
 
-                CDEBUG (D_INFO, "Cancel lock on object "LPX64" on disconnect (%d)\n",
-                        ecl->ecl_object->eco_id, rc);
+                CDEBUG (D_INFO, "Cancel lock on object "LPX64" on disconnect "
+                        "(%d)\n", ecl->ecl_object->eco_id, rc);
 
                 echo_put_object (ecl->ecl_object);
                 OBD_FREE (ecl, sizeof (*ecl));
         }
 
-        /* no more contention on export's open handle list  */
-        while (!list_empty (&exp->exp_ec_data.eced_open_head)) {
-                ecoo = list_entry (exp->exp_ec_data.eced_open_head.next,
-                                   struct ec_open_object, ecoo_exp_chain);
-                list_del (&ecoo->ecoo_exp_chain);
-
-                memcpy (&ecoo->ecoo_oa.o_inline, &ecoo->ecoo_och, 
-                        FD_OSTDATA_SIZE);
-                ecoo->ecoo_oa.o_valid |= OBD_MD_FLHANDLE;
-                
-                rc = obd_close (&ec->ec_conn, &ecoo->ecoo_oa,
-                                ecoo->ecoo_object->eco_lsm, NULL);
-
-                CDEBUG (D_INFO, "Closed object "LPX64" on disconnect (%d)\n",
-                        ecoo->ecoo_oa.o_id, rc);
-
-                echo_put_object (ecoo->ecoo_object);
-                OBD_FREE (ecoo, sizeof (*ecoo));
-        }
-
-        rc = class_disconnect (conn, 0);
+        rc = class_disconnect(exp, 0);
         GOTO(out, rc);
  out:
-        class_export_put(exp);
         return rc;
 }
 
 static struct obd_ops echo_obd_ops = {
         o_owner:       THIS_MODULE,
-        o_setup:       echo_setup,
-        o_cleanup:     echo_cleanup,
-        o_iocontrol:   echo_iocontrol,
-        o_connect:     echo_connect,
-        o_disconnect:  echo_disconnect
+        o_setup:       echo_client_setup,
+        o_cleanup:     echo_client_cleanup,
+        o_iocontrol:   echo_client_iocontrol,
+        o_connect:     echo_client_connect,
+        o_disconnect:  echo_client_disconnect
 };
 
 int echo_client_init(void)
@@ -1133,7 +1393,7 @@ int echo_client_init(void)
                                    OBD_ECHO_CLIENT_DEVICENAME);
 }
 
-void echo_client_cleanup(void)
+void echo_client_exit(void)
 {
         class_unregister_type(OBD_ECHO_CLIENT_DEVICENAME);
 }
diff --git a/lustre/obdfilter/Makefile.am b/lustre/obdfilter/Makefile.am
index ed4ca1e9a573bac9b99bde426cd3228df921f955..fca412b0e46681fd129c6d984f18edcd2e0ea7ea 100644
--- a/lustre/obdfilter/Makefile.am
+++ b/lustre/obdfilter/Makefile.am
@@ -7,6 +7,6 @@ MODULE = obdfilter
 modulefs_DATA = obdfilter.o
 EXTRA_PROGRAMS = obdfilter
 obdfilter_SOURCES = filter.c filter_io.c filter_log.c filter_san.c \
-lproc_obdfilter.c filter_internal.h
+			filter_io_24.c lproc_obdfilter.c filter_internal.h
 
 include $(top_srcdir)/Rules
diff --git a/lustre/obdfilter/Makefile.mk b/lustre/obdfilter/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..e8515ddc2590ec157f211a6aad86c6b52d16ee5b
--- /dev/null
+++ b/lustre/obdfilter/Makefile.mk
@@ -0,0 +1,11 @@
+# Copyright (C) 2003  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += obdfilter.o
+obdfilter-objs := filter.o lproc_obdfilter.o filter_log.o filter_io.o \
+			filter_san.o filter_io_26.o
+
diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c
index e2b1d3064adf6fbb8c90d4b7c0175417d866ab76..9a2743e0f0d3a8015201b7f0cc8185d3b6d7fbfe 100644
--- a/lustre/obdfilter/filter.c
+++ b/lustre/obdfilter/filter.c
@@ -47,6 +47,7 @@
 #endif
 
 #include <linux/obd_class.h>
+#include <linux/obd_lov.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/lprocfs_status.h>
@@ -55,78 +56,10 @@
 
 #include "filter_internal.h"
 
-#define S_SHIFT 12
-static char *obd_type_by_mode[S_IFMT >> S_SHIFT] = {
-        [0]                     NULL,
-        [S_IFREG >> S_SHIFT]    "R",
-        [S_IFDIR >> S_SHIFT]    "D",
-        [S_IFCHR >> S_SHIFT]    "C",
-        [S_IFBLK >> S_SHIFT]    "B",
-        [S_IFIFO >> S_SHIFT]    "F",
-        [S_IFSOCK >> S_SHIFT]   "S",
-        [S_IFLNK >> S_SHIFT]    "L"
-};
-
-static inline const char *obd_mode_to_type(int mode)
-{
-        return obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
-}
-
-static void filter_ffd_addref(void *ffdp)
-{
-        struct filter_file_data *ffd = ffdp;
-
-        atomic_inc(&ffd->ffd_refcount);
-        CDEBUG(D_INFO, "GETting ffd %p : new refcount %d\n", ffd,
-               atomic_read(&ffd->ffd_refcount));
-}
-
-static struct filter_file_data *filter_ffd_new(void)
-{
-        struct filter_file_data *ffd;
-
-        OBD_ALLOC(ffd, sizeof *ffd);
-        if (ffd == NULL) {
-                CERROR("out of memory\n");
-                return NULL;
-        }
-
-        atomic_set(&ffd->ffd_refcount, 2);
-
-        INIT_LIST_HEAD(&ffd->ffd_handle.h_link);
-        class_handle_hash(&ffd->ffd_handle, filter_ffd_addref);
-
-        return ffd;
-}
+static struct lvfs_callback_ops filter_lvfs_ops;
 
-static struct filter_file_data *filter_handle2ffd(struct lustre_handle *handle)
-{
-        struct filter_file_data *ffd = NULL;
-        ENTRY;
-        LASSERT(handle != NULL);
-        ffd = class_handle2object(handle->cookie);
-        if (ffd != NULL)
-                LASSERT(ffd->ffd_file->private_data == ffd);
-        RETURN(ffd);
-}
-
-static void filter_ffd_put(struct filter_file_data *ffd)
-{
-        CDEBUG(D_INFO, "PUTting ffd %p : new refcount %d\n", ffd,
-               atomic_read(&ffd->ffd_refcount) - 1);
-        LASSERT(atomic_read(&ffd->ffd_refcount) > 0 &&
-                atomic_read(&ffd->ffd_refcount) < 0x5a5a);
-        if (atomic_dec_and_test(&ffd->ffd_refcount)) {
-                LASSERT(list_empty(&ffd->ffd_handle.h_link));
-                OBD_FREE(ffd, sizeof *ffd);
-        }
-}
-
-static void filter_ffd_destroy(struct filter_file_data *ffd)
-{
-        class_handle_unhash(&ffd->ffd_handle);
-        filter_ffd_put(ffd);
-}
+static int filter_destroy(struct obd_export *exp, struct obdo *oa,
+                          struct lov_stripe_md *ea, struct obd_trans_info *);
 
 static void filter_commit_cb(struct obd_device *obd, __u64 transno,
                              void *cb_data, int error)
@@ -134,64 +67,6 @@ static void filter_commit_cb(struct obd_device *obd, __u64 transno,
         obd_transno_commit_cb(obd, transno, error);
 }
 
-static int filter_client_log_cancel(struct lustre_handle *conn,
-                                    struct lov_stripe_md *lsm, int count,
-                                    struct llog_cookie *cookies, int flags)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct llog_commit_data *llcd;
-        struct filter_obd *filter = &obd->u.filter;
-        int rc = 0;
-        ENTRY;
-
-        if (count == 0 || cookies == NULL) {
-                down(&filter->fo_sem);
-                if (filter->fo_llcd == NULL || !(flags & OBD_LLOG_FL_SENDNOW))
-                        GOTO(out, rc);
-
-                llcd = filter->fo_llcd;
-                GOTO(send_now, rc);
-        }
-
-        down(&filter->fo_sem);
-        llcd = filter->fo_llcd;
-        if (llcd == NULL) {
-                llcd = llcd_grab();
-                if (llcd == NULL) {
-                        CERROR("couldn't get an llcd - dropped "LPX64":%x+%u\n",
-                               cookies->lgc_lgl.lgl_oid,
-                               cookies->lgc_lgl.lgl_ogen, cookies->lgc_index);
-                        GOTO(out, rc = -ENOMEM);
-                }
-                llcd->llcd_import = filter->fo_mdc_imp;
-                filter->fo_llcd = llcd;
-        }
-
-        memcpy(llcd->llcd_cookies + llcd->llcd_cookiebytes, cookies,
-               sizeof(*cookies));
-        llcd->llcd_cookiebytes += sizeof(*cookies);
-
-        GOTO(send_now, rc);
-send_now:
-        if ((PAGE_SIZE - llcd->llcd_cookiebytes < sizeof(*cookies) ||
-             flags & OBD_LLOG_FL_SENDNOW)) {
-                filter->fo_llcd = NULL;
-                llcd_send(llcd);
-        }
-out:
-        up(&filter->fo_sem);
-
-        return rc;
-}
-
-/* When this (destroy) operation is committed, return the cancel cookie */
-static void filter_cancel_cookies_cb(struct obd_device *obd, __u64 transno,
-                                     void *cb_data, int error)
-{
-        filter_client_log_cancel(&obd->u.filter.fo_mdc_conn, NULL, 1,
-                                 cb_data, OBD_LLOG_FL_SENDNOW);
-        OBD_FREE(cb_data, sizeof(struct llog_cookie));
-}
 
 /* Assumes caller has already pushed us into the kernel context. */
 int filter_finish_transno(struct obd_export *exp, struct obd_trans_info *oti,
@@ -202,48 +77,51 @@ int filter_finish_transno(struct obd_export *exp, struct obd_trans_info *oti,
         struct filter_client_data *fcd = fed->fed_fcd;
         __u64 last_rcvd;
         loff_t off;
-        ssize_t written;
+        int err, log_pri = D_HA;
 
         /* Propagate error code. */
         if (rc)
                 RETURN(rc);
 
-        if (!exp->exp_obd->obd_replayable)
+        if (!exp->exp_obd->obd_replayable || oti == NULL)
                 RETURN(rc);
 
         /* we don't allocate new transnos for replayed requests */
-        if (oti != NULL && oti->oti_transno == 0) {
+        if (oti->oti_transno == 0) {
                 spin_lock(&filter->fo_translock);
                 last_rcvd = le64_to_cpu(filter->fo_fsd->fsd_last_transno) + 1;
                 filter->fo_fsd->fsd_last_transno = cpu_to_le64(last_rcvd);
                 spin_unlock(&filter->fo_translock);
                 oti->oti_transno = last_rcvd;
-                fcd->fcd_last_rcvd = cpu_to_le64(last_rcvd);
-                fcd->fcd_mount_count = filter->fo_fsd->fsd_mount_count;
-
-                /* could get xid from oti, if it's ever needed */
-                fcd->fcd_last_xid = 0;
-
-                off = fed->fed_lr_off;
-                fsfilt_set_last_rcvd(exp->exp_obd, last_rcvd, oti->oti_handle,
-                                     filter_commit_cb, NULL);
-                written = fsfilt_write_record(exp->exp_obd,
-                                              filter->fo_rcvd_filp, fcd,
-                                              sizeof(*fcd), &off);
-                CDEBUG(D_HA, "wrote trans #"LPD64" for client %s at #%d: "
-                       "written = "LPSZ"\n", last_rcvd, fcd->fcd_uuid,
-                       fed->fed_lr_idx, written);
-
-                if (written == sizeof(*fcd))
-                        RETURN(0);
-                CERROR("error writing to %s: rc = %d\n", LAST_RCVD,
-                       (int)written);
-                if (written >= 0)
-                        RETURN(-ENOSPC);
-                RETURN(written);
+        } else { 
+                spin_lock(&filter->fo_translock);
+                last_rcvd = oti->oti_transno;
+                if (last_rcvd > le64_to_cpu(filter->fo_fsd->fsd_last_transno))
+                        filter->fo_fsd->fsd_last_transno =
+                                cpu_to_le64(last_rcvd);
+                spin_unlock(&filter->fo_translock);
         }
+        fcd->fcd_last_rcvd = cpu_to_le64(last_rcvd);
+        fcd->fcd_mount_count = filter->fo_fsd->fsd_mount_count;
 
-        RETURN(0);
+        /* could get xid from oti, if it's ever needed */
+        fcd->fcd_last_xid = 0;
+
+        off = fed->fed_lr_off;
+        fsfilt_add_journal_cb(exp->exp_obd, last_rcvd, oti->oti_handle,
+                              filter_commit_cb, NULL);
+        err = fsfilt_write_record(exp->exp_obd, filter->fo_rcvd_filp, fcd,
+                                  sizeof(*fcd), &off, 0);
+        if (err) {
+                log_pri = D_ERROR;
+                if (rc == 0)
+                        rc = err;
+        }
+
+        CDEBUG(log_pri, "wrote trans "LPU64" for client %s at #%d: err = %d\n",
+               last_rcvd, fcd->fcd_uuid, fed->fed_lr_idx, err);
+
+        RETURN(rc);
 }
 
 void f_dput(struct dentry *dentry)
@@ -256,17 +134,6 @@ void f_dput(struct dentry *dentry)
         dput(dentry);
 }
 
-/* Not racy w.r.t. others, because we are the only user of this dentry */
-static void filter_drelease(struct dentry *dentry)
-{
-        if (dentry->d_fsdata)
-                OBD_FREE(dentry->d_fsdata, sizeof(struct filter_dentry_data));
-}
-
-struct dentry_operations filter_dops = {
-        d_release: filter_drelease,
-};
-
 /* Add client data to the FILTER.  We use a bitmap to locate a free space
  * in the last_rcvd file if cl_idx is -1 (i.e. a new client).
  * Otherwise, we have just read the data from the last_rcvd file and
@@ -281,7 +148,7 @@ static int filter_client_add(struct obd_device *obd, struct filter_obd *filter,
         LASSERT(bitmap != NULL);
 
         /* XXX if fcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
-        if (!strcmp(fed->fed_fcd->fcd_uuid, "OBD_CLASS_UUID"))
+        if (!strcmp(fed->fed_fcd->fcd_uuid, obd->obd_uuid.uuid))
                 RETURN(0);
 
         /* the bitmap operations can handle cl_idx > sizeof(long) * 8, so
@@ -320,38 +187,35 @@ static int filter_client_add(struct obd_device *obd, struct filter_obd *filter,
         if (new_client) {
                 struct obd_run_ctxt saved;
                 loff_t off = fed->fed_lr_off;
-                int written;
+                int err;
                 void *handle;
 
                 CDEBUG(D_INFO, "writing client fcd at idx %u (%llu) (len %u)\n",
                        fed->fed_lr_idx,off,(unsigned int)sizeof(*fed->fed_fcd));
 
-                push_ctxt(&saved, &filter->fo_ctxt, NULL);
+                push_ctxt(&saved, &obd->obd_ctxt, NULL);
                 /* Transaction needed to fix bug 1403 */
                 handle = fsfilt_start(obd,
                                       filter->fo_rcvd_filp->f_dentry->d_inode,
                                       FSFILT_OP_SETATTR, NULL);
                 if (IS_ERR(handle)) {
-                        written = PTR_ERR(handle);
-                        CERROR("unable to start transaction: rc %d\n",
-                               (int)written);
+                        err = PTR_ERR(handle);
+                        CERROR("unable to start transaction: rc %d\n", err);
                 } else {
-                        written = fsfilt_write_record(obd, filter->fo_rcvd_filp,
-                                                      fed->fed_fcd,
-                                                      sizeof(*fed->fed_fcd),
-                                                      &off);
+                        err = fsfilt_write_record(obd, filter->fo_rcvd_filp,
+                                                  fed->fed_fcd,
+                                                  sizeof(*fed->fed_fcd),
+                                                  &off, 1);
                         fsfilt_commit(obd,
                                       filter->fo_rcvd_filp->f_dentry->d_inode,
-                                      handle, 0);
+                                      handle, 1);
                 }
-                pop_ctxt(&saved, &filter->fo_ctxt, NULL);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-                if (written != sizeof(*fed->fed_fcd)) {
+                if (err) {
                         CERROR("error writing %s client idx %u: rc %d\n",
-                               LAST_RCVD, fed->fed_lr_idx, written);
-                        if (written < 0)
-                                RETURN(written);
-                        RETURN(-ENOSPC);
+                               LAST_RCVD, fed->fed_lr_idx, err);
+                        RETURN(err);
                 }
         }
         RETURN(0);
@@ -364,7 +228,7 @@ static int filter_client_free(struct obd_export *exp, int flags)
         struct obd_device *obd = exp->exp_obd;
         struct filter_client_data zero_fcd;
         struct obd_run_ctxt saved;
-        int written;
+        int rc;
         loff_t off;
         ENTRY;
 
@@ -375,7 +239,7 @@ static int filter_client_free(struct obd_export *exp, int flags)
                 GOTO(free, 0);
 
         /* XXX if fcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
-        if (strcmp(fed->fed_fcd->fcd_uuid, "OBD_CLASS_UUID") == 0)
+        if (strcmp(fed->fed_fcd->fcd_uuid, obd->obd_uuid.uuid ) == 0)
                 GOTO(free, 0);
 
         LASSERT(filter->fo_last_rcvd_slots != NULL);
@@ -392,25 +256,15 @@ static int filter_client_free(struct obd_export *exp, int flags)
         }
 
         memset(&zero_fcd, 0, sizeof zero_fcd);
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
-        written = fsfilt_write_record(obd, filter->fo_rcvd_filp,
-                                      &zero_fcd, sizeof(zero_fcd), &off);
-
-        /* XXX: this write gets lost sometimes, unless this sync is here. */
-        if (written > 0)
-                file_fsync(filter->fo_rcvd_filp,
-                           filter->fo_rcvd_filp->f_dentry, 1);
-        pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-
-        if (written != sizeof(zero_fcd)) {
-                CERROR("error zeroing out client %s idx %u (%llu) in %s: %d\n",
-                       fed->fed_fcd->fcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
-                       LAST_RCVD, written);
-        } else {
-                CDEBUG(D_INFO,
-                       "zeroed disconnecting client %s at idx %u (%llu)\n",
-                       fed->fed_fcd->fcd_uuid, fed->fed_lr_idx,fed->fed_lr_off);
-        }
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        rc = fsfilt_write_record(obd, filter->fo_rcvd_filp, &zero_fcd,
+                                 sizeof(zero_fcd), &off, 1);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+        CDEBUG(rc == 0 ? D_INFO : D_ERROR,
+               "zeroing disconnecting client %s at idx %u (%llu) in %s rc %d\n",
+               fed->fed_fcd->fcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
+               LAST_RCVD, rc);
 
 free:
         OBD_FREE(fed->fed_fcd, sizeof(*fed->fed_fcd));
@@ -429,41 +283,56 @@ static int filter_free_server_data(struct filter_obd *filter)
 }
 
 /* assumes caller is already in kernel ctxt */
-int filter_update_server_data(struct obd_device *obd,
-                              struct file *filp, struct filter_server_data *fsd)
+int filter_update_server_data(struct obd_device *obd, struct file *filp,
+                              struct filter_server_data *fsd, int force_sync)
 {
         loff_t off = 0;
         int rc;
         ENTRY;
 
         CDEBUG(D_INODE, "server uuid      : %s\n", fsd->fsd_uuid);
-        CDEBUG(D_INODE, "server last_objid: "LPU64"\n",
-               le64_to_cpu(fsd->fsd_last_objid));
         CDEBUG(D_INODE, "server last_rcvd : "LPU64"\n",
                le64_to_cpu(fsd->fsd_last_transno));
         CDEBUG(D_INODE, "server last_mount: "LPU64"\n",
                le64_to_cpu(fsd->fsd_mount_count));
 
-        rc = fsfilt_write_record(obd, filp, fsd, sizeof(*fsd), &off);
-        if (rc == sizeof(*fsd))
-                RETURN(0);
+        rc = fsfilt_write_record(obd, filp, fsd, sizeof(*fsd), &off,force_sync);
+        if (rc)
+                CERROR("error writing filter_server_data: rc = %d\n", rc);
+
+        RETURN(rc);
+}
+
+int filter_update_last_objid(struct obd_device *obd, obd_gr group,
+                             int force_sync)
+{
+        struct filter_obd *filter = &obd->u.filter;
+        __u64 tmp;
+        loff_t off = 0;
+        int rc;
+        ENTRY;
+
+        CDEBUG(D_INODE, "server last_objid for group "LPU64": "LPU64"\n",
+               group, filter->fo_last_objids[group]);
 
-        CDEBUG(D_INODE, "error writing filter_server_data: rc = %d\n", rc);
-        if (rc >= 0)
-                RETURN(-ENOSPC);
+        tmp = cpu_to_le64(filter->fo_last_objids[group]);
+        rc = fsfilt_write_record(obd, filter->fo_last_objid_files[group],
+                                 &tmp, sizeof(tmp), &off, force_sync);
+        if (rc)
+                CERROR("error writing group "LPU64" last objid: rc = %d\n",
+                       group, rc);
         RETURN(rc);
 }
 
 /* assumes caller has already in kernel ctxt */
-static int filter_init_server_data(struct obd_device *obd, struct file * filp,
-                                   __u64 init_lastobjid)
+static int filter_init_server_data(struct obd_device *obd, struct file * filp)
 {
         struct filter_obd *filter = &obd->u.filter;
         struct filter_server_data *fsd;
         struct filter_client_data *fcd = NULL;
         struct inode *inode = filp->f_dentry->d_inode;
         unsigned long last_rcvd_size = inode->i_size;
-        __u64 mount_count = 0;
+        __u64 mount_count;
         int cl_idx;
         loff_t off = 0;
         int rc;
@@ -490,7 +359,6 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp,
                 CWARN("%s: initializing new %s\n", obd->obd_name, LAST_RCVD);
 
                 memcpy(fsd->fsd_uuid, obd->obd_uuid.uuid,sizeof(fsd->fsd_uuid));
-                fsd->fsd_last_objid = cpu_to_le64(init_lastobjid);
                 fsd->fsd_last_transno = 0;
                 mount_count = fsd->fsd_mount_count = 0;
                 fsd->fsd_server_size = cpu_to_le32(FILTER_LR_SERVER_SIZE);
@@ -499,34 +367,35 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp,
                 fsd->fsd_subdir_count = cpu_to_le16(FILTER_SUBDIR_COUNT);
                 filter->fo_subdir_count = FILTER_SUBDIR_COUNT;
         } else {
-                int retval = fsfilt_read_record(obd, filp, fsd,
-                                                sizeof(*fsd), &off);
-                if (retval != sizeof(*fsd)) {
+                rc = fsfilt_read_record(obd, filp, fsd, sizeof(*fsd), &off);
+                if (rc) {
                         CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
-                               LAST_RCVD, retval);
-                        GOTO(err_fsd, rc = -EIO);
+                               LAST_RCVD, rc);
+                        GOTO(err_fsd, rc);
+                }
+                if (strcmp(fsd->fsd_uuid, obd->obd_uuid.uuid) != 0) {
+                        CERROR("OBD UUID %s does not match last_rcvd UUID %s\n",
+                               obd->obd_uuid.uuid, fsd->fsd_uuid);
+                        GOTO(err_fsd, rc = -EINVAL);
                 }
                 mount_count = le64_to_cpu(fsd->fsd_mount_count);
                 filter->fo_subdir_count = le16_to_cpu(fsd->fsd_subdir_count);
-                fsd->fsd_last_objid =
-                        cpu_to_le64(le64_to_cpu(fsd->fsd_last_objid) +
-                                    FILTER_SKIP_OBJID);
         }
 
-        if (fsd->fsd_feature_incompat) {
+        if (fsd->fsd_feature_incompat & ~le32_to_cpu(FILTER_INCOMPAT_SUPP)) {
                 CERROR("unsupported feature %x\n",
-                       le32_to_cpu(fsd->fsd_feature_incompat));
+                       le32_to_cpu(fsd->fsd_feature_incompat) &
+                       ~FILTER_INCOMPAT_SUPP);
                 GOTO(err_fsd, rc = -EINVAL);
         }
-        if (fsd->fsd_feature_rocompat) {
+        if (fsd->fsd_feature_rocompat & ~le32_to_cpu(FILTER_ROCOMPAT_SUPP)) {
                 CERROR("read-only feature %x\n",
-                       le32_to_cpu(fsd->fsd_feature_rocompat));
+                       le32_to_cpu(fsd->fsd_feature_rocompat) &
+                       ~FILTER_ROCOMPAT_SUPP);
                 /* Do something like remount filesystem read-only */
                 GOTO(err_fsd, rc = -EINVAL);
         }
 
-        CDEBUG(D_INODE, "%s: server last_objid: "LPU64"\n",
-               obd->obd_name, le64_to_cpu(fsd->fsd_last_objid));
         CDEBUG(D_INODE, "%s: server last_rcvd : "LPU64"\n",
                obd->obd_name, le64_to_cpu(fsd->fsd_last_transno));
         CDEBUG(D_INODE, "%s: server last_mount: "LPU64"\n",
@@ -539,34 +408,36 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp,
                obd->obd_name, le32_to_cpu(fsd->fsd_client_size));
         CDEBUG(D_INODE, "%s: server subdir_count: %u\n",
                obd->obd_name, le16_to_cpu(fsd->fsd_subdir_count));
+        CDEBUG(D_INODE, "%s: last_rcvd clients: %lu\n", obd->obd_name,
+               last_rcvd_size <= FILTER_LR_CLIENT_START ? 0 :
+               (last_rcvd_size-FILTER_LR_CLIENT_START) /FILTER_LR_CLIENT_SIZE);
 
         if (!obd->obd_replayable) {
                 CWARN("%s: recovery support OFF\n", obd->obd_name);
                 GOTO(out, rc = 0);
         }
 
-        for (cl_idx = 0; off < last_rcvd_size; cl_idx++) {
+        for (cl_idx = 0, off = le32_to_cpu(fsd->fsd_client_start);
+             off < last_rcvd_size; cl_idx++) {
                 __u64 last_rcvd;
                 int mount_age;
 
                 if (!fcd) {
                         OBD_ALLOC(fcd, sizeof(*fcd));
                         if (!fcd)
-                                GOTO(err_fsd, rc = -ENOMEM);
+                                GOTO(err_client, rc = -ENOMEM);
                 }
 
-                /* Don't assume off is incremented properly, in case
-                 * sizeof(fsd) isn't the same as fsd->fsd_client_size.
-                 */
+                /* Don't assume off is incremented properly by
+                 * fsfilt_read_record(), in case sizeof(*fcd)
+                 * isn't the same as fsd->fsd_client_size.  */
                 off = le32_to_cpu(fsd->fsd_client_start) +
                         cl_idx * le16_to_cpu(fsd->fsd_client_size);
                 rc = fsfilt_read_record(obd, filp, fcd, sizeof(*fcd), &off);
-                if (rc != sizeof(*fcd)) {
-                        CERROR("error reading FILTER %s offset %d: rc = %d\n",
-                               LAST_RCVD, cl_idx, rc);
-                        if (rc > 0) /* XXX fatal error or just abort reading? */
-                                rc = -EIO;
-                        break;
+                if (rc) {
+                        CERROR("error reading FILT %s idx %d off %llu: rc %d\n",
+                               LAST_RCVD, cl_idx, off, rc);
+                        break; /* read error shouldn't cause startup to fail */
                 }
 
                 if (fcd->fcd_uuid[0] == '\0') {
@@ -589,27 +460,23 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp,
                                LPU64"\n", fcd->fcd_uuid, cl_idx,
                                last_rcvd, le64_to_cpu(fsd->fsd_last_transno),
                                le64_to_cpu(fcd->fcd_mount_count), mount_count);
-                        if (exp == NULL) {
-                                /* XXX this rc is ignored  */
-                                rc = -ENOMEM;
-                                break;
-                        }
+                        if (exp == NULL)
+                                GOTO(err_client, rc = -ENOMEM);
+
                         memcpy(&exp->exp_client_uuid.uuid, fcd->fcd_uuid,
                                sizeof exp->exp_client_uuid.uuid);
                         fed = &exp->exp_filter_data;
                         fed->fed_fcd = fcd;
                         filter_client_add(obd, filter, fed, cl_idx);
                         /* create helper if export init gets more complex */
-                        INIT_LIST_HEAD(&fed->fed_open_head);
                         spin_lock_init(&fed->fed_lock);
 
                         fcd = NULL;
                         obd->obd_recoverable_clients++;
                         class_export_put(exp);
                 } else {
-                        CDEBUG(D_INFO,
-                               "discarded client %d UUID '%s' count "LPU64"\n",
-                               cl_idx, fcd->fcd_uuid,
+                        CDEBUG(D_INFO, "discarded client %d UUID '%s' count "
+                               LPU64"\n", cl_idx, fcd->fcd_uuid,
                                le64_to_cpu(fcd->fcd_mount_count));
                 }
 
@@ -619,18 +486,16 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp,
                 if (last_rcvd > le64_to_cpu(filter->fo_fsd->fsd_last_transno))
                         filter->fo_fsd->fsd_last_transno=cpu_to_le64(last_rcvd);
 
-                obd->obd_last_committed =
-                        le64_to_cpu(filter->fo_fsd->fsd_last_transno);
+        }
 
-                if (obd->obd_recoverable_clients) {
-                        CERROR("RECOVERY: %d recoverable clients, last_rcvd "
-                               LPU64"\n", obd->obd_recoverable_clients,
-                               le64_to_cpu(filter->fo_fsd->fsd_last_transno));
-                        obd->obd_next_recovery_transno =
-                                obd->obd_last_committed + 1;
-                        obd->obd_recovering = 1;
-                }
+        obd->obd_last_committed = le64_to_cpu(filter->fo_fsd->fsd_last_transno);
 
+        if (obd->obd_recoverable_clients) {
+                CERROR("RECOVERY: %d recoverable clients, last_rcvd "
+                       LPU64"\n", obd->obd_recoverable_clients,
+                       le64_to_cpu(filter->fo_fsd->fsd_last_transno));
+                obd->obd_next_recovery_transno = obd->obd_last_committed + 1;
+                obd->obd_recovering = 1;
         }
 
         if (fcd)
@@ -640,65 +505,245 @@ out:
         fsd->fsd_mount_count = cpu_to_le64(mount_count + 1);
 
         /* save it, so mount count and last_transno is current */
-        rc = filter_update_server_data(obd, filp, filter->fo_fsd);
+        rc = filter_update_server_data(obd, filp, filter->fo_fsd, 1);
 
         RETURN(rc);
 
+err_client:
+        class_disconnect_exports(obd, 0);
 err_fsd:
         filter_free_server_data(filter);
         RETURN(rc);
 }
 
-/* setup the object store with correct subdirectories */
-static int filter_prep(struct obd_device *obd)
+static int filter_cleanup_groups(struct obd_device *obd)
 {
-        struct obd_run_ctxt saved;
         struct filter_obd *filter = &obd->u.filter;
-        struct dentry *dentry, *O_dentry;
-        struct file *file;
-        struct inode *inode;
         int i;
-        int rc = 0;
-        int mode = 0;
+        ENTRY;
+
+        if (filter->fo_subdir_count) {
+                for (i = 0; i < filter->fo_subdir_count; i++) {
+                        struct dentry *dentry = filter->fo_dentry_O_sub[i];
+                        f_dput(dentry);
+                        filter->fo_dentry_O_sub[i] = NULL;
+                }
+                OBD_FREE(filter->fo_dentry_O_sub,
+                         filter->fo_subdir_count *
+                         sizeof(*filter->fo_dentry_O_sub));
+        }
+        if (filter->fo_dentry_O_groups != NULL &&
+            filter->fo_last_objids != NULL &&
+            filter->fo_last_objid_files != NULL) {
+                for (i = 0; i < FILTER_GROUPS; i++) {
+                        struct dentry *dentry = filter->fo_dentry_O_groups[i];
+                        struct file *filp = filter->fo_last_objid_files[i];
+                        if (dentry != NULL) {
+                                f_dput(dentry);
+                                filter->fo_dentry_O_groups[i] = NULL;
+                        }
+                        if (filp != NULL) {
+                                filp_close(filp, 0);
+                                filter->fo_last_objid_files[i] = NULL;
+                        }
+                }
+        }
+        if (filter->fo_dentry_O_groups != NULL)
+                OBD_FREE(filter->fo_dentry_O_groups,
+                         FILTER_GROUPS * sizeof(struct dentry *));
+        if (filter->fo_last_objids != NULL)
+                OBD_FREE(filter->fo_last_objids,
+                         FILTER_GROUPS * sizeof(__u64));
+        if (filter->fo_last_objid_files != NULL)
+                OBD_FREE(filter->fo_last_objid_files,
+                         FILTER_GROUPS * sizeof(struct file *));
+        RETURN(0);
+}
+
+/* FIXME: object groups */
+static int filter_prep_groups(struct obd_device *obd)
+{
+        struct filter_obd *filter = &obd->u.filter;
+        struct dentry *dentry, *O_dentry;
+        struct file *filp;
+        int i, rc = 0, cleanup_phase = 0;
+        ENTRY;
 
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
-        dentry = simple_mkdir(current->fs->pwd, "O", 0700);
-        CDEBUG(D_INODE, "got/created O: %p\n", dentry);
-        if (IS_ERR(dentry)) {
-                rc = PTR_ERR(dentry);
+        O_dentry = simple_mkdir(current->fs->pwd, "O", 0700);
+        CDEBUG(D_INODE, "got/created O: %p\n", O_dentry);
+        if (IS_ERR(O_dentry)) {
+                rc = PTR_ERR(O_dentry);
                 CERROR("cannot open/create O: rc = %d\n", rc);
-                GOTO(out, rc);
+                GOTO(cleanup, rc);
         }
-        filter->fo_dentry_O = dentry;
+        filter->fo_dentry_O = O_dentry;
+        cleanup_phase = 1; /* O_dentry */
 
-        /*
-         * Create directories and/or get dentries for each object type.
-         * This saves us from having to do multiple lookups for each one.
-         */
-        O_dentry = filter->fo_dentry_O;
-        for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) {
-                char *name = obd_type_by_mode[mode];
+        /* Lookup "R" to tell if we're on an old OST FS and need to convert
+         * from O/R/<dir>/<objid> to O/0/<dir>/<objid>.  This can be removed
+         * some time post 1.0 when all old-style OSTs have converted along
+         * with the init_objid hack. */
+        dentry = ll_lookup_one_len("R", O_dentry, 1);
+        if (IS_ERR(dentry))
+                GOTO(cleanup, rc = PTR_ERR(dentry));
+        if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
+                struct dentry *O0_dentry = lookup_one_len("0", O_dentry, 1);
+                ENTRY;
+
+                CWARN("converting OST to new object layout\n");
+                if (IS_ERR(O0_dentry)) {
+                        rc = PTR_ERR(O0_dentry);
+                        CERROR("error looking up O/0: rc %d\n", rc);
+                        GOTO(cleanup_R, rc);
+                }
 
-                if (!name) {
-                        filter->fo_dentry_O_mode[mode] = NULL;
-                        continue;
+                if (O0_dentry->d_inode) {
+                        CERROR("Both O/R and O/0 exist. Fix manually.\n");
+                        GOTO(cleanup_O0, rc = -EEXIST);
+                }
+
+                down(&O_dentry->d_inode->i_sem);
+                rc = vfs_rename(O_dentry->d_inode, dentry,
+                                O_dentry->d_inode, O0_dentry);
+                up(&O_dentry->d_inode->i_sem);
+
+                if (rc) {
+                        CERROR("error renaming O/R to O/0: rc %d\n", rc);
+                        GOTO(cleanup_O0, rc);
                 }
+                filter->fo_fsd->fsd_feature_incompat |=
+                        cpu_to_le32(FILTER_INCOMPAT_GROUPS);
+                rc = filter_update_server_data(obd, filter->fo_rcvd_filp,
+                                               filter->fo_fsd, 1);
+                GOTO(cleanup_O0, rc);
+
+        cleanup_O0:
+                dput(O0_dentry);
+        cleanup_R:
+                dput(dentry);
+                if (rc)
+                        GOTO(cleanup, rc);
+        } else {
+                dput(dentry);
+        }
+
+        OBD_ALLOC(filter->fo_last_objids, FILTER_GROUPS * sizeof(__u64));
+        if (filter->fo_last_objids == NULL)
+                GOTO(cleanup, rc = -ENOMEM);
+        cleanup_phase = 2; /* groups */
+
+        OBD_ALLOC(filter->fo_dentry_O_groups, FILTER_GROUPS * sizeof(dentry));
+        if (filter->fo_dentry_O_groups == NULL)
+                GOTO(cleanup, rc = -ENOMEM);
+        OBD_ALLOC(filter->fo_last_objid_files, FILTER_GROUPS * sizeof(filp));
+        if (filter->fo_last_objid_files == NULL)
+                GOTO(cleanup, rc = -ENOMEM);
+
+        for (i = 0; i < FILTER_GROUPS; i++) {
+                char name[25];
+                loff_t off = 0;
+
+                sprintf(name, "%d", i);
                 dentry = simple_mkdir(O_dentry, name, 0700);
                 CDEBUG(D_INODE, "got/created O/%s: %p\n", name, dentry);
                 if (IS_ERR(dentry)) {
                         rc = PTR_ERR(dentry);
                         CERROR("cannot create O/%s: rc = %d\n", name, rc);
-                        GOTO(err_O_mode, rc);
+                        GOTO(cleanup, rc);
+                }
+                filter->fo_dentry_O_groups[i] = dentry;
+
+                sprintf(name, "O/%d/LAST_ID", i);
+                filp = filp_open(name, O_CREAT | O_RDWR, 0700);
+                if (IS_ERR(dentry)) {
+                        rc = PTR_ERR(dentry);
+                        CERROR("cannot create %s: rc = %d\n", name, rc);
+                        GOTO(cleanup, rc);
+                }
+                filter->fo_last_objid_files[i] = filp;
+
+                if (filp->f_dentry->d_inode->i_size == 0) {
+                        if (i == 0 && filter->fo_fsd->fsd_unused != 0) {
+                                /* OST conversion, remove sometime post 1.0 */
+                                filter->fo_last_objids[i] =
+                                        le64_to_cpu(filter->fo_fsd->fsd_unused);
+                                CWARN("saving old objid "LPU64" to LAST_ID\n",
+                                      filter->fo_last_objids[i]);
+                                rc = filter_update_last_objid(obd, 0, 1);
+                                if (rc)
+                                        GOTO(cleanup, rc);
+                        } else {
+                                filter->fo_last_objids[i] = FILTER_INIT_OBJID;
+                        }
+                        continue;
+                }
+
+                rc = fsfilt_read_record(obd, filp, &filter->fo_last_objids[i],
+                                        sizeof(__u64), &off);
+                if (rc) {
+                        CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+                               name, rc);
+                        GOTO(cleanup, rc);
+                }
+                filter->fo_last_objids[i] =
+                        le64_to_cpu(filter->fo_last_objids[i]);
+                CDEBUG(D_INODE, "%s: server last_objid group %d: "LPU64"\n",
+                       obd->obd_name, i, filter->fo_last_objids[i]);
+        }
+
+        if (filter->fo_subdir_count) {
+                O_dentry = filter->fo_dentry_O_groups[0];
+                OBD_ALLOC(filter->fo_dentry_O_sub,
+                          filter->fo_subdir_count * sizeof(dentry));
+                if (filter->fo_dentry_O_sub == NULL)
+                        GOTO(cleanup, rc = -ENOMEM);
+
+                for (i = 0; i < filter->fo_subdir_count; i++) {
+                        char dir[20];
+                        snprintf(dir, sizeof(dir), "d%u", i);
+
+                        dentry = simple_mkdir(O_dentry, dir, 0700);
+                        CDEBUG(D_INODE, "got/created O/0/%s: %p\n", dir,dentry);
+                        if (IS_ERR(dentry)) {
+                                rc = PTR_ERR(dentry);
+                                CERROR("can't create O/0/%s: rc = %d\n",dir,rc);
+                                GOTO(cleanup, rc);
+                        }
+                        filter->fo_dentry_O_sub[i] = dentry;
                 }
-                filter->fo_dentry_O_mode[mode] = dentry;
         }
+        RETURN(0);
+
+ cleanup:
+        switch (cleanup_phase) {
+        case 2:
+                filter_cleanup_groups(obd);
+        case 1:
+                f_dput(filter->fo_dentry_O);
+                filter->fo_dentry_O = NULL;
+        default:
+                break;
+        }
+        return rc;
+}
+
+/* setup the object store with correct subdirectories */
+static int filter_prep(struct obd_device *obd)
+{
+        struct obd_run_ctxt saved;
+        struct filter_obd *filter = &obd->u.filter;
+        struct file *file;
+        struct inode *inode;
+        int rc = 0;
+        ENTRY;
 
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         file = filp_open(LAST_RCVD, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
         if (!file || IS_ERR(file)) {
                 rc = PTR_ERR(file);
                 CERROR("OBD filter: cannot open/create %s: rc = %d\n",
                        LAST_RCVD, rc);
-                GOTO(err_O_mode, rc);
+                GOTO(out, rc);
         }
 
         if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
@@ -707,84 +752,35 @@ static int filter_prep(struct obd_device *obd)
                 GOTO(err_filp, rc = -ENOENT);
         }
 
-        rc = fsfilt_journal_data(obd, file);
-        if (rc) {
-                CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_filp, rc);
-        }
         /* steal operations */
         inode = file->f_dentry->d_inode;
         filter->fo_fop = file->f_op;
         filter->fo_iop = inode->i_op;
         filter->fo_aops = inode->i_mapping->a_ops;
-#ifdef I_SKIP_PDFLUSH
-        /*
-         * we need this to protect from deadlock
-         * pdflush vs. lustre_fwrite()
-         */
-        inode->i_flags |= I_SKIP_PDFLUSH;
-#endif
 
-        rc = filter_init_server_data(obd, file, FILTER_INIT_OBJID);
+        rc = filter_init_server_data(obd, file);
         if (rc) {
                 CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc);
-                GOTO(err_client, rc);
+                GOTO(err_filp, rc);
         }
         filter->fo_rcvd_filp = file;
 
-        if (filter->fo_subdir_count) {
-                O_dentry = filter->fo_dentry_O_mode[S_IFREG >> S_SHIFT];
-                OBD_ALLOC(filter->fo_dentry_O_sub,
-                          filter->fo_subdir_count * sizeof(dentry));
-                if (!filter->fo_dentry_O_sub)
-                        GOTO(err_client, rc = -ENOMEM);
-
-                for (i = 0; i < filter->fo_subdir_count; i++) {
-                        char dir[20];
-                        snprintf(dir, sizeof(dir), "d%u", i);
+        rc = filter_prep_groups(obd);
+        if (rc)
+                GOTO(err_server_data, rc);
 
-                        dentry = simple_mkdir(O_dentry, dir, 0700);
-                        CDEBUG(D_INODE, "got/created O/R/%s: %p\n", dir,dentry);
-                        if (IS_ERR(dentry)) {
-                                rc = PTR_ERR(dentry);
-                                CERROR("can't create O/R/%s: rc = %d\n",dir,rc);
-                                GOTO(err_O_sub, rc);
-                        }
-                        filter->fo_dentry_O_sub[i] = dentry;
-                }
-        }
-        rc = 0;
  out:
-        pop_ctxt(&saved, &filter->fo_ctxt, NULL);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
         return(rc);
 
-err_O_sub:
-        while (i-- > 0) {
-                struct dentry *dentry = filter->fo_dentry_O_sub[i];
-                if (dentry) {
-                        f_dput(dentry);
-                        filter->fo_dentry_O_sub[i] = NULL;
-                }
-        }
-        OBD_FREE(filter->fo_dentry_O_sub,
-                 filter->fo_subdir_count * sizeof(dentry));
-err_client:
-        class_disconnect_exports(obd, 0);
-err_filp:
+ err_server_data:
+        //class_disconnect_exports(obd, 0);
+        filter_free_server_data(filter);
+ err_filp:
         if (filp_close(file, 0))
                 CERROR("can't close %s after error\n", LAST_RCVD);
         filter->fo_rcvd_filp = NULL;
-err_O_mode:
-        while (mode-- > 0) {
-                struct dentry *dentry = filter->fo_dentry_O_mode[mode];
-                if (dentry) {
-                        f_dput(dentry);
-                        filter->fo_dentry_O_mode[mode] = NULL;
-                }
-        }
-        f_dput(filter->fo_dentry_O);
-        filter->fo_dentry_O = NULL;
         goto out;
 }
 
@@ -793,60 +789,66 @@ static void filter_post(struct obd_device *obd)
 {
         struct obd_run_ctxt saved;
         struct filter_obd *filter = &obd->u.filter;
-        long rc;
-        int mode;
+        int rc, i;
 
         /* XXX: filter_update_lastobjid used to call fsync_dev.  It might be
          * best to start a transaction with h_sync, because we removed this
          * from lastobjid */
 
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
         rc = filter_update_server_data(obd, filter->fo_rcvd_filp,
-                                       filter->fo_fsd);
+                                       filter->fo_fsd, 0);
         if (rc)
-                CERROR("error writing lastobjid: rc = %ld\n", rc);
+                CERROR("error writing server data: rc = %d\n", rc);
 
-
-        if (filter->fo_rcvd_filp) {
-                rc = file_fsync(filter->fo_rcvd_filp,
-                                filter->fo_rcvd_filp->f_dentry, 1);
-                filp_close(filter->fo_rcvd_filp, 0);
-                filter->fo_rcvd_filp = NULL;
+        for (i = 0; i < FILTER_GROUPS; i++) {
+                rc = filter_update_last_objid(obd, i, (i == FILTER_GROUPS - 1));
                 if (rc)
-                        CERROR("error closing %s: rc = %ld\n", LAST_RCVD, rc);
+                        CERROR("error writing group %d lastobjid: rc = %d\n",
+                               i, rc);
         }
 
-        if (filter->fo_subdir_count) {
-                int i;
-                for (i = 0; i < filter->fo_subdir_count; i++) {
-                        struct dentry *dentry = filter->fo_dentry_O_sub[i];
-                        f_dput(dentry);
-                        filter->fo_dentry_O_sub[i] = NULL;
-                }
-                OBD_FREE(filter->fo_dentry_O_sub,
-                         filter->fo_subdir_count *
-                         sizeof(*filter->fo_dentry_O_sub));
-        }
-        for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) {
-                struct dentry *dentry = filter->fo_dentry_O_mode[mode];
-                if (dentry) {
-                        f_dput(dentry);
-                        filter->fo_dentry_O_mode[mode] = NULL;
-                }
-        }
+        filp_close(filter->fo_rcvd_filp, 0);
+        filter->fo_rcvd_filp = NULL;
+        if (rc)
+                CERROR("error closing %s: rc = %d\n", LAST_RCVD, rc);
+
+        filter_cleanup_groups(obd);
         f_dput(filter->fo_dentry_O);
         filter_free_server_data(filter);
-        pop_ctxt(&saved, &filter->fo_ctxt, NULL);
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+}
+
+static void filter_set_last_id(struct filter_obd *filter, struct obdo *oa,
+                               obd_id id)
+{
+        obd_gr group = 0;
+        LASSERT(filter->fo_fsd != NULL);
+
+        if (oa != NULL) {
+                LASSERT(oa->o_gr <= FILTER_GROUPS);
+                group = oa->o_gr;
+        }
+
+        spin_lock(&filter->fo_objidlock);
+        filter->fo_last_objids[group] = id;
+        spin_unlock(&filter->fo_objidlock);
 }
 
-__u64 filter_next_id(struct filter_obd *filter)
+__u64 filter_last_id(struct filter_obd *filter, struct obdo *oa)
 {
         obd_id id;
+        obd_gr group = 0;
         LASSERT(filter->fo_fsd != NULL);
 
+        if (oa != NULL) {
+                LASSERT(oa->o_gr <= FILTER_GROUPS);
+                group = oa->o_gr;
+        }
+
+        /* FIXME: object groups */
         spin_lock(&filter->fo_objidlock);
-        id = le64_to_cpu(filter->fo_fsd->fsd_last_objid);
-        filter->fo_fsd->fsd_last_objid = cpu_to_le64(id + 1);
+        id = filter->fo_last_objids[group];
         spin_unlock(&filter->fo_objidlock);
 
         return id;
@@ -868,7 +870,7 @@ static int filter_blocking_ast(struct ldlm_lock *lock,
         /* XXX layering violation!  -phil */
         l_lock(&lock->l_resource->lr_namespace->ns_lock);
         /* Get this: if filter_blocking_ast is racing with ldlm_intent_policy,
-         * such that mds_blocking_ast is called just before l_i_p takes the
+         * such that filter_blocking_ast is called just before l_i_p takes the
          * ns_lock, then by the time we get the lock, we might not be the
          * correct blocking function anymore.  So check, and return early, if
          * so. */
@@ -911,7 +913,7 @@ static int filter_lock_dentry(struct obd_device *obd, struct dentry *de,
                               &flags, ldlm_completion_ast,
                               filter_blocking_ast, NULL, lockh);
 
-        RETURN(rc == ELDLM_OK ? 0 : -ENOLCK);  /* XXX translate ldlm code */
+        RETURN(rc == ELDLM_OK ? 0 : -EIO);  /* XXX translate ldlm code */
 }
 
 /* We never dget the object parent, so DON'T dput it either */
@@ -923,25 +925,24 @@ static void filter_parent_unlock(struct dentry *dparent,
 }
 
 /* We never dget the object parent, so DON'T dput it either */
-struct dentry *filter_parent(struct obd_device *obd, obd_mode mode,
-                             obd_id objid)
+struct dentry *filter_parent(struct obd_device *obd, obd_gr group, obd_id objid)
 {
         struct filter_obd *filter = &obd->u.filter;
+        LASSERT(group < FILTER_GROUPS); /* FIXME: object groups */
 
-        LASSERT(S_ISREG(mode));   /* only regular files for now */
-        if (!S_ISREG(mode) || filter->fo_subdir_count == 0)
-                return filter->fo_dentry_O_mode[(mode & S_IFMT) >> S_SHIFT];
+        if (group > 0 || filter->fo_subdir_count == 0)
+                return filter->fo_dentry_O_groups[group];
 
         return filter->fo_dentry_O_sub[objid & (filter->fo_subdir_count - 1)];
 }
 
 /* We never dget the object parent, so DON'T dput it either */
-struct dentry *filter_parent_lock(struct obd_device *obd, obd_mode mode,
+struct dentry *filter_parent_lock(struct obd_device *obd, obd_gr group,
                                   obd_id objid, ldlm_mode_t lock_mode,
                                   struct lustre_handle *lockh)
 {
         unsigned long now = jiffies;
-        struct dentry *de = filter_parent(obd, mode, objid);
+        struct dentry *de = filter_parent(obd, group, objid);
         int rc;
 
         if (IS_ERR(de))
@@ -962,7 +963,7 @@ struct dentry *filter_parent_lock(struct obd_device *obd, obd_mode mode,
  * internal to the filesystem code. */
 struct dentry *filter_fid2dentry(struct obd_device *obd,
                                  struct dentry *dir_dentry,
-                                 obd_mode mode, obd_id id)
+                                 obd_gr group, obd_id id)
 {
         struct lustre_handle lockh;
         struct dentry *dparent = dir_dentry;
@@ -973,13 +974,12 @@ struct dentry *filter_fid2dentry(struct obd_device *obd,
 
         if (id == 0) {
                 CERROR("fatal: invalid object id 0\n");
-                LBUG();
                 RETURN(ERR_PTR(-ESTALE));
         }
 
         len = sprintf(name, LPU64, id);
         if (dir_dentry == NULL) {
-                dparent = filter_parent_lock(obd, mode, id, LCK_PR, &lockh);
+                dparent = filter_parent_lock(obd, group, id, LCK_PR, &lockh);
                 if (IS_ERR(dparent))
                         RETURN(dparent);
         }
@@ -1001,135 +1001,32 @@ struct dentry *filter_fid2dentry(struct obd_device *obd,
         RETURN(dchild);
 }
 
-static struct file *filter_obj_open(struct obd_export *export,
-                                    struct obd_trans_info *oti,
-                                    __u64 id, __u32 type, int parent_mode,
-                                    struct lustre_handle *parent_lockh)
+static int filter_prepare_destroy(struct obd_device *obd, obd_id objid)
 {
-        struct obd_device *obd = export->exp_obd;
-        struct filter_obd *filter = &obd->u.filter;
-        struct dentry *dchild = NULL, *dparent = NULL;
-        struct filter_export_data *fed = &export->exp_filter_data;
-        struct filter_dentry_data *fdd = NULL;
-        struct filter_file_data *ffd = NULL;
-        struct obd_run_ctxt saved;
-        char name[24];
-        struct file *file;
-        int len, cleanup_phase = 0;
+        struct lustre_handle lockh;
+        int flags = LDLM_AST_DISCARD_DATA, rc;
+        struct ldlm_res_id res_id = { .name = { objid } };
+        struct ldlm_extent extent = { 0, OBD_OBJECT_EOF };
         ENTRY;
 
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
-
-        if (!id) {
-                CERROR("fatal: invalid obdo "LPU64"\n", id);
-                GOTO(cleanup, file = ERR_PTR(-ESTALE));
-        }
+        /* Tell the clients that the object is gone now and that they should
+         * throw away any cached pages.  If we're the OST at stripe 0 in the
+         * file then this enqueue will communicate the DISCARD to all the
+         * clients.  This assumes that we always destroy all the objects for
+         * a file at a time, as is currently the case.  If we're not the
+         * OST at stripe 0 then we'll harmlessly get a very lonely lock in 
+         * the local DLM and immediately drop it. */
+        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
+                              res_id, LDLM_EXTENT, &extent,
+                              sizeof(extent), LCK_PW, &flags,
+                              ldlm_completion_ast, filter_blocking_ast,
+                              NULL, &lockh);
 
-        if (!(type & S_IFMT)) {
-                CERROR("OBD %s, object "LPU64" has bad type: %o\n",
-                       __FUNCTION__, id, type);
-                GOTO(cleanup, file = ERR_PTR(-EINVAL));
-        }
+        /* We only care about the side-effects, just drop the lock. */
+        if (rc == ELDLM_OK)
+                ldlm_lock_decref(&lockh, LCK_PW);
 
-        ffd = filter_ffd_new();
-        if (ffd == NULL) {
-                CERROR("obdfilter: out of memory\n");
-                GOTO(cleanup, file = ERR_PTR(-ENOMEM));
-        }
-
-        cleanup_phase = 1;
-
-        /* We preallocate this to avoid blocking while holding fo_fddlock */
-        OBD_ALLOC(fdd, sizeof *fdd);
-        if (fdd == NULL) {
-                CERROR("obdfilter: out of memory\n");
-                GOTO(cleanup, file = ERR_PTR(-ENOMEM));
-        }
-
-        cleanup_phase = 2;
-
-        dparent = filter_parent_lock(obd, type, id, parent_mode, parent_lockh);
-        if (IS_ERR(dparent))
-                GOTO(cleanup, file = (void *)dparent);
-
-        cleanup_phase = 3;
-
-        len = snprintf(name, sizeof(name), LPU64, id);
-        dchild = ll_lookup_one_len(name, dparent, len);
-        if (IS_ERR(dchild))
-                GOTO(cleanup, file = (void *)dchild);
-
-        cleanup_phase = 4;
-
-        if (dchild->d_inode == NULL) {
-                CERROR("opening non-existent object %s - O_CREAT?\n", name);
-                /* dput(dchild); call filter_create_internal here */
-                file = ERR_PTR(-ENOENT);
-                GOTO(cleanup, file);
-        }
-
-        /* dentry_open does a dput(dchild) and mntput(mnt) on error */
-        mntget(filter->fo_vfsmnt);
-        file = dentry_open(dchild, filter->fo_vfsmnt, O_RDWR | O_LARGEFILE);
-        if (IS_ERR(file)) {
-                dchild = NULL; /* prevent a double dput in step 4 */
-                CERROR("error opening %s: rc %ld\n", name, PTR_ERR(file));
-                GOTO(cleanup, file);
-        }
-
-        spin_lock(&filter->fo_fddlock);
-        if (dchild->d_fsdata) {
-                spin_unlock(&filter->fo_fddlock);
-                OBD_FREE(fdd, sizeof *fdd);
-                fdd = dchild->d_fsdata;
-                LASSERT(fdd->fdd_magic == FILTER_DENTRY_MAGIC);
-                /* should only happen during client recovery */
-                if (fdd->fdd_flags & FILTER_FLAG_DESTROY)
-                        CDEBUG(D_INODE,"opening destroyed object "LPU64"\n",id);
-                atomic_inc(&fdd->fdd_open_count);
-        } else {
-                atomic_set(&fdd->fdd_open_count, 1);
-                fdd->fdd_magic = FILTER_DENTRY_MAGIC;
-                fdd->fdd_flags = 0;
-                fdd->fdd_objid = id;
-                /* If this is racy, then we can use {cmp}xchg and atomic_add */
-                dchild->d_fsdata = fdd;
-                spin_unlock(&filter->fo_fddlock);
-        }
-
-        ffd->ffd_file = file;
-        LASSERT(file->private_data == NULL);
-        file->private_data = ffd;
-
-        if (!dchild->d_op)
-                dchild->d_op = &filter_dops;
-        else
-                LASSERT(dchild->d_op == &filter_dops);
-
-        spin_lock(&fed->fed_lock);
-        list_add(&ffd->ffd_export_list, &fed->fed_open_head);
-        spin_unlock(&fed->fed_lock);
-
-        CDEBUG(D_INODE, "opened objid "LPU64": rc = %p\n", id, file);
-cleanup:
-        switch (cleanup_phase) {
-        case 4:
-                if (IS_ERR(file))
-                        f_dput(dchild);
-        case 3:
-                if (IS_ERR(file))
-                        filter_parent_unlock(dparent, parent_lockh,parent_mode);
-        case 2:
-                if (IS_ERR(file))
-                        OBD_FREE(fdd, sizeof *fdd);
-        case 1:
-                if (IS_ERR(file))
-                        filter_ffd_destroy(ffd);
-                filter_ffd_put(ffd);
-        case 0:
-                pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-        }
-        RETURN(file);
+        RETURN(rc);
 }
 
 /* Caller must hold LCK_PW on parent and push us into kernel context.
@@ -1143,42 +1040,10 @@ static int filter_destroy_internal(struct obd_device *obd, obd_id objid,
         ENTRY;
 
         if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 1) {
-                CERROR("destroying objid %*s nlink = %d, count = %d\n",
+                CERROR("destroying objid %*s nlink = %lu, count = %d\n",
                        dchild->d_name.len, dchild->d_name.name,
-                       inode->i_nlink, atomic_read(&inode->i_count));
-        }
-
-        
-#if 0
-        /* Tell the clients that the object is gone now and that they should
-         * throw away any cached pages.  We don't need to wait until they're
-         * done, so just decref the lock right away and let ldlm_completion_ast
-         * clean up when it's all over. */
-        ldlm_cli_enqueue(..., LCK_PW, AST_INTENT_DESTROY, &lockh);
-        ldlm_lock_decref(&lockh, LCK_PW);
-#endif
-
-        if (0) {
-                struct lustre_handle lockh;
-                int flags = 0, rc;
-                struct ldlm_res_id res_id = { .name = { objid } };
-
-                /* This part is a wee bit iffy: we really only want to bust the
-                 * locks on our stripe, so that we don't end up bouncing
-                 * [0->EOF] locks around on each of the OSTs as the rest of the
-                 * destroys get processed.  Because we're only talking to
-                 * the local LDLM, though, we should only end up locking the 
-                 * whole of our stripe.  When bug 1425 (take all locks on OST
-                 * for stripe 0) is fixed, this code should be revisited. */
-                struct ldlm_extent extent = { 0, OBD_OBJECT_EOF };
-
-                rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL,
-                                      res_id, LDLM_EXTENT, &extent,
-                                      sizeof(extent), LCK_PW, &flags,
-                                      ldlm_completion_ast, filter_blocking_ast,
-                                      NULL, &lockh);
-                /* We only care about the side-effects, just drop the lock. */
-                ldlm_lock_decref(&lockh, LCK_PW);
+                       (unsigned long)inode->i_nlink, 
+                       atomic_read(&inode->i_count));
         }
 
         rc = vfs_unlink(dparent->d_inode, dchild);
@@ -1190,150 +1055,43 @@ static int filter_destroy_internal(struct obd_device *obd, obd_id objid,
         RETURN(rc);
 }
 
-/* If closing because we are failing this device, then
-   don't do the unlink on close.
-*/
-static int filter_close_internal(struct obd_export *exp,
-                                 struct filter_file_data *ffd,
-                                 struct obd_trans_info *oti, int flags)
-{
-        struct obd_device *obd = exp->exp_obd;
-        struct filter_obd *filter = &obd->u.filter;
-        struct file *filp = ffd->ffd_file;
-        struct dentry *dchild = dget(filp->f_dentry);
-        struct filter_dentry_data *fdd = dchild->d_fsdata;
-        struct lustre_handle parent_lockh;
-        int rc, rc2, cleanup_phase = 0;
-        struct dentry *dparent = NULL;
-        struct obd_run_ctxt saved;
-        int nested_trans = (current->journal_info != NULL);
-        ENTRY;
-
-        LASSERT(filp->private_data == ffd);
-        LASSERT(fdd != NULL);
-        LASSERT(fdd->fdd_magic == FILTER_DENTRY_MAGIC);
-
-        rc = filp_close(filp, 0);
-
-        if (atomic_dec_and_test(&fdd->fdd_open_count) &&
-            (fdd->fdd_flags & FILTER_FLAG_DESTROY) &&
-            !(flags & OBD_OPT_FAILOVER)) {
-                void *handle;
-
-                push_ctxt(&saved, &filter->fo_ctxt, NULL);
-                cleanup_phase = 1;
-
-                LASSERT(fdd->fdd_objid > 0);
-                dparent = filter_parent_lock(obd, S_IFREG, fdd->fdd_objid,
-                                             LCK_PW, &parent_lockh);
-                if (IS_ERR(dparent))
-                        GOTO(cleanup, rc = PTR_ERR(dparent));
-                cleanup_phase = 2;
-
-                handle = fsfilt_start(obd, dparent->d_inode,
-                                      FSFILT_OP_UNLINK_LOG, oti);
-                if (IS_ERR(handle))
-                        GOTO(cleanup, rc = PTR_ERR(handle));
-
-                if (oti != NULL) {
-                        if (oti->oti_handle == NULL)
-                                oti->oti_handle = handle;
-                        else
-                                LASSERT(oti->oti_handle == handle);
-                }
-
-#ifdef ENABLE_ORPHANS
-                /* Remove orphan unlink record from log */
-                llog_cancel_records(filter->fo_catalog, 1, &fdd->fdd_cookie);
-#endif
-                /* XXX unlink from PENDING directory now too */
-                rc2 = filter_destroy_internal(obd, fdd->fdd_objid, dparent,
-                                              dchild);
-                if (rc2 && !rc)
-                        rc = rc2;
-                rc = filter_finish_transno(exp, oti, rc);
-                rc2 = fsfilt_commit(obd, dparent->d_inode, handle, 0);
-                if (rc2) {
-                        CERROR("error on commit, err = %d\n", rc2);
-                        if (!rc)
-                                rc = rc2;
-                }
-                if (nested_trans == 0) {
-                        LASSERT(current->journal_info == NULL);
-                        if (oti != NULL)
-                                oti->oti_handle = NULL;
-                }
-        }
-
-cleanup:
-        switch(cleanup_phase) {
-        case 2:
-                if (rc || oti == NULL) {
-                        filter_parent_unlock(dparent, &parent_lockh, LCK_PW);
-                } else {
-                        memcpy(&oti->oti_ack_locks[0].lock, &parent_lockh,
-                               sizeof(parent_lockh));
-                        oti->oti_ack_locks[0].mode = LCK_PW;
-                }
-        case 1:
-                pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-        case 0:
-                f_dput(dchild);
-                filter_ffd_destroy(ffd);
-                break;
-        default:
-                CERROR("invalid cleanup_phase %d\n", cleanup_phase);
-                LBUG();
-        }
-
-        RETURN(rc);
-}
-
 /* mount the file system (secretly) */
 int filter_common_setup(struct obd_device *obd, obd_count len, void *buf,
                         char *option)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         struct filter_obd *filter = &obd->u.filter;
         struct vfsmount *mnt;
         int rc = 0;
         ENTRY;
 
-        if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2)
+        dev_clear_rdonly(2);
+
+        if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
                 RETURN(-EINVAL);
 
-        obd->obd_fsops = fsfilt_get_ops(data->ioc_inlbuf2);
+        obd->obd_fsops = fsfilt_get_ops(lcfg->lcfg_inlbuf2);
         if (IS_ERR(obd->obd_fsops))
                 RETURN(PTR_ERR(obd->obd_fsops));
 
-        mnt = do_kern_mount(data->ioc_inlbuf2, MS_NOATIME | MS_NODIRATIME,
-                            data->ioc_inlbuf1, option);
+        mnt = do_kern_mount(lcfg->lcfg_inlbuf2, MS_NOATIME | MS_NODIRATIME,
+                            lcfg->lcfg_inlbuf1, option);
         rc = PTR_ERR(mnt);
         if (IS_ERR(mnt))
                 GOTO(err_ops, rc);
 
-        if (data->ioc_inllen3 > 0 && data->ioc_inlbuf3) {
-                if (*data->ioc_inlbuf3 == 'f') {
+        if (lcfg->lcfg_inllen3 > 0 && lcfg->lcfg_inlbuf3) {
+                if (*lcfg->lcfg_inlbuf3 == 'f') {
                         obd->obd_replayable = 1;
                         obd_sync_filter = 1;
-                        CERROR("%s: configured for recovery and sync write\n",
-                               obd->obd_name);
+                        CERROR("%s: recovery enabled\n", obd->obd_name);
                 } else {
-                        if (*data->ioc_inlbuf3 != 'n') {
+                        if (*lcfg->lcfg_inlbuf3 != 'n') {
                                 CERROR("unrecognised flag '%c'\n",
-                                       *data->ioc_inlbuf3);
+                                       *lcfg->lcfg_inlbuf3);
                         }
-                }
-        }
-
-        if (data->ioc_inllen4 > 0 && data->ioc_inlbuf4) {
-                if (*data->ioc_inlbuf4 == '/') {
-                        CERROR("filter namespace mount: %s\n",
-                               data->ioc_inlbuf4);
-                        filter->fo_nspath = strdup(data->ioc_inlbuf4);
-                } else {
-                        CERROR("namespace mount must be absolute path: '%s'\n",
-                               data->ioc_inlbuf4);
+                        // XXX Robert? Why do we get errors here
+                        // GOTO(err_mntput, rc = -EINVAL);
                 }
         }
 
@@ -1342,23 +1100,20 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf,
         filter->fo_fstype = mnt->mnt_sb->s_type->name;
         CDEBUG(D_SUPER, "%s: mnt = %p\n", filter->fo_fstype, mnt);
 
-        OBD_SET_CTXT_MAGIC(&filter->fo_ctxt);
-        filter->fo_ctxt.pwdmnt = mnt;
-        filter->fo_ctxt.pwd = mnt->mnt_root;
-        filter->fo_ctxt.fs = get_ds();
+        OBD_SET_CTXT_MAGIC(&obd->obd_ctxt);
+        obd->obd_ctxt.pwdmnt = mnt;
+        obd->obd_ctxt.pwd = mnt->mnt_root;
+        obd->obd_ctxt.fs = get_ds();
+        obd->obd_ctxt.cb_ops = filter_lvfs_ops;
 
         rc = filter_prep(obd);
         if (rc)
                 GOTO(err_mntput, rc);
 
         spin_lock_init(&filter->fo_translock);
-        spin_lock_init(&filter->fo_fddlock);
         spin_lock_init(&filter->fo_objidlock);
         INIT_LIST_HEAD(&filter->fo_export_list);
-
-        ptlrpc_init_client(MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
-                           "filter_mdc", &filter->fo_mdc_client);
-        sema_init(&filter->fo_sem, 1);
+        sema_init(&filter->fo_alloc_lock, 1);
 
         obd->obd_namespace = ldlm_namespace_new("filter-tgt",
                                                 LDLM_NAMESPACE_SERVER);
@@ -1368,15 +1123,6 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf,
         ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
                            "filter_ldlm_cb_client", &obd->obd_ldlm_client);
 
-        /* Create a non-replaying connection for recovery logging, so that
-         * we don't create a client entry for this local connection, and do
-         * not log or assign transaction numbers for logging operations. */
-#ifdef ENABLE_ORPHANS
-        filter->fo_catalog = filter_get_catalog(obd);
-        if (IS_ERR(filter->fo_catalog))
-                GOTO(err_post, rc = PTR_ERR(filter->fo_catalog));
-#endif
-
         RETURN(0);
 
 err_post:
@@ -1393,16 +1139,44 @@ err_ops:
 
 static int filter_setup(struct obd_device *obd, obd_count len, void *buf)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
+        const char *str = NULL;
         char *option = NULL;
+        int n = 0;
+        int rc;
 
+        if (!strcmp(lcfg->lcfg_inlbuf2, "ext3")) {
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         /* bug 1577: implement async-delete for 2.5 */
-        if (!strcmp(data->ioc_inlbuf2, "ext3"))
-                option = "asyncdel";
+                str = "errors=remount-ro,asyncdel";
+#else
+                str = "errors=remount-ro";
 #endif
+                n = strlen(str) + 1;
+                OBD_ALLOC(option, n);
+                if (option == NULL)
+                        RETURN(-ENOMEM);
+                strcpy(option, str);
+        }
 
-        return filter_common_setup(obd, len, buf, option);
+        rc = filter_common_setup(obd, len, buf, option);
+        if (option)
+                OBD_FREE(option, n);
+        return rc;
+}
+
+static int filter_postsetup(struct obd_device *obd)
+{
+        int rc = 0;
+        ENTRY;
+
+        // XXX add a storage location for the logid for size changes
+#ifdef ENABLE_ORPHANS
+        rc = llog_cat_initialize(obd, 1);
+        if (rc)
+                CERROR("failed to setup llogging subsystems\n");
+#endif
+        RETURN(rc);
 }
 
 static int filter_cleanup(struct obd_device *obd, int flags)
@@ -1423,11 +1197,7 @@ static int filter_cleanup(struct obd_device *obd, int flags)
                 }
         }
 
-#ifdef ENABLE_ORPHANS
-        filter_put_catalog(filter->fo_catalog);
-#endif
-
-        ldlm_namespace_free(obd->obd_namespace);
+        ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE);
 
         if (filter->fo_sb == NULL)
                 RETURN(0);
@@ -1438,7 +1208,8 @@ static int filter_cleanup(struct obd_device *obd, int flags)
         filter->fo_sb = 0;
 
         if (atomic_read(&filter->fo_vfsmnt->mnt_count) > 1)
-                CERROR("%s: mount point busy, mnt_count: %d\n", obd->obd_name,
+                CERROR("%s: mount point %p busy, mnt_count: %d\n",
+                       obd->obd_name, filter->fo_vfsmnt,
                        atomic_read(&filter->fo_vfsmnt->mnt_count));
 
         unlock_kernel();
@@ -1448,6 +1219,8 @@ static int filter_cleanup(struct obd_device *obd, int flags)
         fsfilt_put_ops(obd->obd_fsops);
         lock_kernel();
 
+        dev_clear_rdonly(2);
+
         RETURN(0);
 }
 
@@ -1485,7 +1258,7 @@ static int filter_connect(struct lustre_handle *conn, struct obd_device *obd,
 {
         struct obd_export *exp;
         struct filter_export_data *fed;
-        struct filter_client_data *fcd;
+        struct filter_client_data *fcd = NULL;
         struct filter_obd *filter = &obd->u.filter;
         int rc;
         ENTRY;
@@ -1500,18 +1273,16 @@ static int filter_connect(struct lustre_handle *conn, struct obd_device *obd,
         LASSERT(exp != NULL);
 
         fed = &exp->exp_filter_data;
-        class_export_put(exp);
 
-        INIT_LIST_HEAD(&fed->fed_open_head);
         spin_lock_init(&fed->fed_lock);
 
         if (!obd->obd_replayable)
-                RETURN(0);
+                GOTO(cleanup, rc = 0);
 
         OBD_ALLOC(fcd, sizeof(*fcd));
         if (!fcd) {
                 CERROR("filter: out of memory for client data\n");
-                GOTO(out_export, rc = -ENOMEM);
+                GOTO(cleanup, rc = -ENOMEM);
         }
 
         memcpy(fcd->fcd_uuid, cluuid, sizeof(fcd->fcd_uuid));
@@ -1519,53 +1290,48 @@ static int filter_connect(struct lustre_handle *conn, struct obd_device *obd,
         fcd->fcd_mount_count = cpu_to_le64(filter->fo_fsd->fsd_mount_count);
 
         rc = filter_client_add(obd, filter, fed, -1);
-        if (rc)
-                GOTO(out_fcd, rc);
 
-        RETURN(rc);
+cleanup:
+        if (rc) {
+                if (fcd)
+                        OBD_FREE(fcd, sizeof(*fcd));
+                class_disconnect(exp, 0);
+        } else {
+                class_export_put(exp);
+        }
+        return rc;
+}
 
-out_fcd:
-        OBD_FREE(fcd, sizeof(*fcd));
-out_export:
-        class_disconnect(conn, 0);
+static int filter_precleanup(struct obd_device *obd, int flags)
+{
+        int rc = 0;
+        ENTRY;
+
+#ifdef ENABLE_ORPHANS
+        rc = obd_llog_finish(obd, 0);
+        if (rc)
+                CERROR("failed to cleanup llogging subsystem\n");
+#endif
 
         RETURN(rc);
 }
 
-static void filter_destroy_export(struct obd_export *exp)
+static int filter_destroy_export(struct obd_export *exp)
 {
-        struct filter_export_data *fed = &exp->exp_filter_data;
-
         ENTRY;
-        spin_lock(&fed->fed_lock);
-        while (!list_empty(&fed->fed_open_head)) {
-                struct filter_file_data *ffd;
 
-                ffd = list_entry(fed->fed_open_head.next, typeof(*ffd),
-                                 ffd_export_list);
-                list_del(&ffd->ffd_export_list);
-                spin_unlock(&fed->fed_lock);
-
-                CDEBUG(D_INFO, "force close file %*s (hdl %p:"LPX64") on "
-                       "disconnect\n", ffd->ffd_file->f_dentry->d_name.len,
-                       ffd->ffd_file->f_dentry->d_name.name,
-                       ffd, ffd->ffd_handle.h_cookie);
-
-                filter_close_internal(exp, ffd, NULL, exp->exp_flags);
-                spin_lock(&fed->fed_lock);
-        }
-        spin_unlock(&fed->fed_lock);
+        target_destroy_export(exp);
 
         if (exp->exp_obd->obd_replayable)
                 filter_client_free(exp, exp->exp_flags);
-        EXIT;
+        RETURN(0);
 }
 
 /* also incredibly similar to mds_disconnect */
-static int filter_disconnect(struct lustre_handle *conn, int flags)
+static int filter_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_export *exp = class_conn2export(conn);
         unsigned long irqflags;
+        struct llog_ctxt *ctxt;
         int rc;
         ENTRY;
 
@@ -1576,11 +1342,14 @@ static int filter_disconnect(struct lustre_handle *conn, int flags)
         exp->exp_flags = flags;
         spin_unlock_irqrestore(&exp->exp_lock, irqflags);
 
-        rc = class_disconnect(conn, flags);
-
         fsfilt_sync(exp->exp_obd, exp->exp_obd->u.filter.fo_sb);
-        class_export_put(exp);
         /* XXX cleanup preallocated inodes */
+
+        /* flush any remaining cancel messages out to the target */
+        ctxt = llog_get_context(exp->exp_obd, LLOG_UNLINK_REPL_CTXT);
+        llog_sync(ctxt, exp);
+
+        rc = class_disconnect(exp, flags);
         RETURN(rc);
 }
 
@@ -1588,33 +1357,19 @@ struct dentry *__filter_oa2dentry(struct obd_device *obd,
                                   struct obdo *oa, const char *what)
 {
         struct dentry *dchild = NULL;
+        obd_gr group = 0;
 
-        if (oa->o_valid & OBD_MD_FLHANDLE) {
-                struct lustre_handle *ost_handle = obdo_handle(oa);
-                struct filter_file_data *ffd = filter_handle2ffd(ost_handle);
+        if (oa->o_valid & OBD_MD_FLGROUP)
+                group = oa->o_gr;
 
-                if (ffd != NULL) {
-                        struct filter_dentry_data *fdd;
-                        dchild = dget(ffd->ffd_file->f_dentry);
-                        fdd = dchild->d_fsdata;
-                        LASSERT(fdd->fdd_magic == FILTER_DENTRY_MAGIC);
-                        filter_ffd_put(ffd);
-
-                        CDEBUG(D_INODE,"%s got child objid %*s: %p, count %d\n",
-                               what, dchild->d_name.len, dchild->d_name.name,
-                               dchild, atomic_read(&dchild->d_count));
-                }
-        }
-
-        if (!dchild)
-                dchild = filter_fid2dentry(obd, NULL, oa->o_mode, oa->o_id);
+        dchild = filter_fid2dentry(obd, NULL, group, oa->o_id);
 
         if (IS_ERR(dchild)) {
                 CERROR("%s error looking up object: "LPU64"\n", what, oa->o_id);
                 RETURN(dchild);
         }
 
-        if (!dchild->d_inode) {
+        if (dchild->d_inode == NULL) {
                 CERROR("%s on non-existent object: "LPU64"\n", what, oa->o_id);
                 f_dput(dchild);
                 RETURN(ERR_PTR(-ENOENT));
@@ -1623,7 +1378,7 @@ struct dentry *__filter_oa2dentry(struct obd_device *obd,
         return dchild;
 }
 
-static int filter_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int filter_getattr(struct obd_export *exp, struct obdo *oa,
                           struct lov_stripe_md *md)
 {
         struct dentry *dentry = NULL;
@@ -1631,9 +1386,10 @@ static int filter_getattr(struct lustre_handle *conn, struct obdo *oa,
         int rc = 0;
         ENTRY;
 
-        obd = class_conn2obd(conn);
+        obd = class_exp2obd(exp);
         if (obd == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",conn->cookie);
+                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",
+                       exp->exp_handle.h_cookie);
                 RETURN(-EINVAL);
         }
 
@@ -1650,11 +1406,10 @@ static int filter_getattr(struct lustre_handle *conn, struct obdo *oa,
 }
 
 /* this is called from filter_truncate() until we have filter_punch() */
-static int filter_setattr(struct lustre_handle *conn, struct obdo *oa,
+static int filter_setattr(struct obd_export *exp, struct obdo *oa,
                           struct lov_stripe_md *md, struct obd_trans_info *oti)
 {
         struct obd_run_ctxt saved;
-        struct obd_export *exp;
         struct filter_obd *filter;
         struct dentry *dentry;
         struct iattr iattr;
@@ -1663,33 +1418,32 @@ static int filter_setattr(struct lustre_handle *conn, struct obdo *oa,
         ENTRY;
 
         LASSERT(oti != NULL);
-        exp = class_conn2export(conn);
-        if (!exp) {
-                CERROR("invalid client cookie "LPX64"\n", conn->cookie);
-                RETURN(-EINVAL);
-        }
 
         dentry = filter_oa2dentry(exp->exp_obd, oa);
         if (IS_ERR(dentry))
-                GOTO(out_exp, rc = PTR_ERR(dentry));
+                RETURN(PTR_ERR(dentry));
 
         filter = &exp->exp_obd->u.filter;
 
         iattr_from_obdo(&iattr, oa, oa->o_valid);
 
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
+        push_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
         lock_kernel();
 
-        /* XXX this could be a rwsem instead, if filter_preprw played along */
         if (iattr.ia_valid & ATTR_SIZE)
                 down(&dentry->d_inode->i_sem);
-
         handle = fsfilt_start(exp->exp_obd, dentry->d_inode, FSFILT_OP_SETATTR,
                               oti);
         if (IS_ERR(handle))
                 GOTO(out_unlock, rc = PTR_ERR(handle));
 
-        rc = fsfilt_setattr(exp->exp_obd, dentry, handle, &iattr, 1);
+        /* XXX this could be a rwsem instead, if filter_preprw played along */
+        if (iattr.ia_valid & ATTR_ATTR_FLAG)
+                rc = fsfilt_iocontrol(exp->exp_obd, dentry->d_inode, NULL,
+                                      EXT3_IOC_SETFLAGS,
+                                      (long)&iattr.ia_attr_flags);
+        else
+                rc = fsfilt_setattr(exp->exp_obd, dentry, handle, &iattr, 1);
         rc = filter_finish_transno(exp, oti, rc);
         rc2 = fsfilt_commit(exp->exp_obd, dentry->d_inode, handle, 0);
         if (rc2) {
@@ -1698,260 +1452,302 @@ static int filter_setattr(struct lustre_handle *conn, struct obdo *oa,
                         rc = rc2;
         }
 
-        if (iattr.ia_valid & ATTR_SIZE)
-                up(&dentry->d_inode->i_sem);
-
         oa->o_valid = OBD_MD_FLID;
         obdo_from_inode(oa, dentry->d_inode, FILTER_VALID_FLAGS);
 
 out_unlock:
+        if (iattr.ia_valid & ATTR_SIZE)
+                up(&dentry->d_inode->i_sem);
         unlock_kernel();
-        pop_ctxt(&saved, &filter->fo_ctxt, NULL);
+        pop_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
 
         f_dput(dentry);
- out_exp:
-        class_export_put(exp);
         RETURN(rc);
 }
 
-static int filter_open(struct lustre_handle *conn, struct obdo *oa,
-                       struct lov_stripe_md *ea, struct obd_trans_info *oti,
-                       struct obd_client_handle *och)
+/* XXX identical to osc_unpackmd */
+static int filter_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
+                           struct lov_mds_md *lmm, int lmm_bytes)
 {
-        struct obd_export *exp;
-        struct lustre_handle *handle;
-        struct filter_file_data *ffd;
-        struct file *filp;
-        struct lustre_handle parent_lockh;
-        int rc = 0;
+        int lsm_size;
         ENTRY;
 
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",conn->cookie);
-                RETURN(-EINVAL);
+        if (lmm != NULL) {
+                if (lmm_bytes < sizeof (*lmm)) {
+                        CERROR("lov_mds_md too small: %d, need %d\n",
+                               lmm_bytes, (int)sizeof(*lmm));
+                        RETURN(-EINVAL);
+                }
+                /* XXX LOV_MAGIC etc check? */
+
+                if (lmm->lmm_object_id == cpu_to_le64(0)) {
+                        CERROR("lov_mds_md: zero lmm_object_id\n");
+                        RETURN(-EINVAL);
+                }
         }
 
-        filp = filter_obj_open(exp, oti, oa->o_id, oa->o_mode,
-                               LCK_PR, &parent_lockh);
-        if (IS_ERR(filp))
-                GOTO(out, rc = PTR_ERR(filp));
+        lsm_size = lov_stripe_md_size(1);
+        if (lsmp == NULL)
+                RETURN(lsm_size);
 
-        oa->o_valid = OBD_MD_FLID;
-        obdo_from_inode(oa, filp->f_dentry->d_inode, FILTER_VALID_FLAGS);
+        if (*lsmp != NULL && lmm == NULL) {
+                OBD_FREE(*lsmp, lsm_size);
+                *lsmp = NULL;
+                RETURN(0);
+        }
 
-        ffd = filp->private_data;
-        handle = obdo_handle(oa);
-        handle->cookie = ffd->ffd_handle.h_cookie;
-        oa->o_valid |= OBD_MD_FLHANDLE;
+        if (*lsmp == NULL) {
+                OBD_ALLOC(*lsmp, lsm_size);
+                if (*lsmp == NULL)
+                        RETURN(-ENOMEM);
 
-out:
-        class_export_put(exp);
-        if (!rc) {
-                memcpy(&oti->oti_ack_locks[0].lock, &parent_lockh,
-                       sizeof(parent_lockh));
-                oti->oti_ack_locks[0].mode = LCK_PR;
+                loi_init((*lsmp)->lsm_oinfo);
         }
-        RETURN(rc);
+
+        if (lmm != NULL) {
+                /* XXX zero *lsmp? */
+                (*lsmp)->lsm_object_id = le64_to_cpu (lmm->lmm_object_id);
+                LASSERT((*lsmp)->lsm_object_id);
+        }
+
+        (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES;
+
+        RETURN(lsm_size);
 }
 
-static int filter_close(struct lustre_handle *conn, struct obdo *oa,
-                        struct lov_stripe_md *ea, struct obd_trans_info *oti)
+static void filter_destroy_precreated(struct obd_export *exp, struct obdo *oa,
+                                      struct filter_obd *filter)
 {
-        struct obd_export *exp;
-        struct filter_file_data *ffd;
-        struct filter_export_data *fed;
-        int rc;
+        struct obdo doa; /* XXX obdo on stack */
+        __u64 last, id;
         ENTRY;
+        LASSERT(oa);
 
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",conn->cookie);
-                RETURN(-EINVAL);
+        memset(&doa, 0, sizeof(doa));
+        if (oa->o_valid & OBD_MD_FLGROUP)
+                doa.o_gr = oa->o_gr;
+        else
+                doa.o_gr = 0;
+        doa.o_mode = S_IFREG;
+        last = filter_last_id(filter, &doa); /* FIXME: object groups */
+        CWARN("deleting orphan objects from "LPU64" to "LPU64"\n",
+               oa->o_id + 1, last);
+        for (id = oa->o_id + 1; id <= last; id++) {
+                doa.o_id = id;
+                filter_destroy(exp, &doa, NULL, NULL);
         }
+        spin_lock(&filter->fo_objidlock);
+        filter->fo_last_objids[0] = oa->o_id; /* FIXME: object groups */
+        spin_unlock(&filter->fo_objidlock);
+        EXIT;
+}
 
-        if (!(oa->o_valid & OBD_MD_FLHANDLE)) {
-                CERROR("no handle for close of objid "LPU64"\n", oa->o_id);
-                GOTO(out, rc = -EINVAL);
-        }
+/* returns a negative error or a nonnegative number of files to create */
+static int filter_should_precreate(struct obd_export *exp, struct obdo *oa,
+                                   int group)
+{
+        struct obd_device *obd = exp->exp_obd;
+        struct filter_obd *filter = &obd->u.filter;
+        int diff, rc;
+        ENTRY;
 
-        ffd = filter_handle2ffd(obdo_handle(oa));
-        if (ffd == NULL) {
-                CERROR("bad handle ("LPX64") for close\n",
-                       obdo_handle(oa)->cookie);
-                GOTO(out, rc = -ESTALE);
-        }
+        /* only precreate if group == 0 and o_id is specfied */
+        if (group != 0 || oa->o_id == 0)
+                RETURN(1);
 
-        fed = &exp->exp_filter_data;
-        spin_lock(&fed->fed_lock);
-        list_del(&ffd->ffd_export_list);
-        spin_unlock(&fed->fed_lock);
+        diff = oa->o_id - filter_last_id(filter, oa);
+        CDEBUG(D_INFO, "filter_last_id() = "LPU64" -> diff = %d\n",
+               filter_last_id(filter, oa), diff);
+        if (diff >= 0)
+                RETURN(diff);
 
-        oa->o_valid = OBD_MD_FLID;
-        obdo_from_inode(oa,ffd->ffd_file->f_dentry->d_inode,FILTER_VALID_FLAGS);
+        if (!(oa->o_valid & OBD_MD_FLFLAGS) ||
+            !(oa->o_flags & OBD_FL_DELORPHAN)) {
+                CERROR("filter asked to delete %d objects, but DELORPHAN flag "
+                       "isn't set!\n", -diff);
+                RETURN(0);
+        }
 
-        rc = filter_close_internal(exp, ffd, oti, 0);
-        filter_ffd_put(ffd);
-        GOTO(out, rc);
- out:
-        class_export_put(exp);
-        return rc;
+        /* delete orphan request */
+        filter_destroy_precreated(exp, oa, filter);
+        rc = filter_update_last_objid(obd, group, 0);
+        if (rc)
+                CERROR("unable to write lastobjid, but orphans were deleted\n");
+        RETURN(rc);
 }
 
-static int filter_create(struct lustre_handle *conn, struct obdo *oa,
-                         struct lov_stripe_md **ea, struct obd_trans_info *oti)
+/* We rely on the fact that only one thread will be creating files in a given
+ * group at a time, which is why we don't need an atomic filter_get_new_id.
+ * Even if we had that atomic function, the following race would exist:
+ *
+ * thread 1: gets id x from filter_next_id
+ * thread 2: gets id (x + 1) from filter_next_id
+ * thread 2: creates object (x + 1)
+ * thread 1: tries to create object x, gets -ENOSPC
+ */
+static int filter_precreate(struct obd_device *obd, struct obdo *oa,
+                            obd_gr group, int *num)
 {
-        struct obd_export *exp;
-        struct obd_device *obd;
-        struct filter_obd *filter;
-        struct obd_run_ctxt saved;
         struct lustre_handle parent_lockh;
-        struct dentry *dparent;
-        struct ll_fid mds_fid = { .id = 0 };
         struct dentry *dchild = NULL;
+        struct filter_obd *filter;
+        struct dentry *dparent;
+        struct iattr attr;
+        int err = 0, rc = 0, i;
+        __u64 next_id;
         void *handle;
-        int err, rc, cleanup_phase;
         ENTRY;
 
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CDEBUG(D_IOCTL,"invalid client cookie "LPX64"\n", conn->cookie);
-                RETURN(-EINVAL);
-        }
-
-        obd = exp->exp_obd;
         filter = &obd->u.filter;
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
- retry:
-        oa->o_id = filter_next_id(filter);
 
-        cleanup_phase = 0;
-        dparent = filter_parent_lock(obd, S_IFREG, oa->o_id, LCK_PW,
-                                     &parent_lockh);
-        if (IS_ERR(dparent))
-                GOTO(cleanup, rc = PTR_ERR(dparent));
-        cleanup_phase = 1;
+        for (i = 0; i < *num && err == 0; i++) {
+                next_id = filter_last_id(filter, NULL) + 1;
+                CDEBUG(D_INFO, "precreate objid "LPU64"\n", next_id);
 
-        dchild = filter_fid2dentry(obd, dparent, S_IFREG, oa->o_id);
-        if (IS_ERR(dchild))
-                GOTO(cleanup, rc = PTR_ERR(dchild));
-        if (dchild->d_inode) {
-                /* This would only happen if lastobjid was bad on disk */
-                CERROR("Serious error: objid %*s already exists; is this "
-                       "filesystem corrupt?  I will try to work around it.\n",
-                       dchild->d_name.len, dchild->d_name.name);
+                dparent = filter_parent_lock(obd, group, next_id, LCK_PW,
+                                             &parent_lockh);
+                if (IS_ERR(dparent)) {
+                        rc = PTR_ERR(dparent);
+                        break;
+                }
+
+                dchild = filter_fid2dentry(obd, dparent, group, next_id);
+                if (IS_ERR(dchild))
+                        GOTO(cleanup_lock, rc = PTR_ERR(dchild));
+
+                if (dchild->d_inode != NULL) {
+                        /* This would only happen if lastobjid was bad on disk*/
+                        CERROR("Serious error: objid %*s already exists; is "
+                               "this filesystem corrupt?\n",
+                               dchild->d_name.len, dchild->d_name.name);
+                        GOTO(cleanup_dchild, rc = -EEXIST);
+                }
+
+                handle = fsfilt_start(obd, dparent->d_inode,
+                                      FSFILT_OP_CREATE_LOG, NULL);
+                if (IS_ERR(handle))
+                        GOTO(cleanup_dchild, rc = PTR_ERR(handle));
+
+                rc = ll_vfs_create(dparent->d_inode, dchild, S_IFREG, NULL);
+                if (rc) {
+                        CERROR("create failed rc = %d\n", rc);
+                        GOTO(cleanup_commit, rc);
+                } else if (oa != NULL &&
+                           (oa->o_valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME |
+                                           OBD_MD_FLSIZE))) {
+                        iattr_from_obdo(&attr, oa, oa->o_valid);
+                        rc = fsfilt_setattr(obd, dchild, handle, &attr, 1);
+                        if (rc)
+                                CERROR("create setattr failed rc = %d\n", rc);
+                }
+                filter_set_last_id(filter, NULL, next_id);
+                err = filter_update_last_objid(obd, group, 0);
+                if (err)
+                        CERROR("unable to write lastobjid but file created\n");
+        cleanup_commit:
+                err = fsfilt_commit(obd, dparent->d_inode, handle, 0);
+                if (err) {
+                        CERROR("error on commit, err = %d\n", err);
+                        if (!rc)
+                                rc = err;
+                }
+                if (dchild->d_inode != NULL && oa != NULL)
+                        obdo_from_inode(oa, dchild->d_inode,
+                                        FILTER_VALID_FLAGS);
+        cleanup_dchild:
                 f_dput(dchild);
+        cleanup_lock:
                 filter_parent_unlock(dparent, &parent_lockh, LCK_PW);
-                goto retry;
+                if (rc)
+                        break;
+                oa = NULL; /* oa applies for first iteration only */
         }
+        *num = i;
 
-        cleanup_phase = 2;
-        handle = fsfilt_start(obd, dparent->d_inode, FSFILT_OP_CREATE_LOG, oti);
-        if (IS_ERR(handle))
-                GOTO(cleanup, rc = PTR_ERR(handle));
+        CDEBUG(D_INFO, "filter_precreate() created %d objects\n", i);
+        RETURN(rc);
+}
 
-        rc = vfs_create(dparent->d_inode, dchild, oa->o_mode);
-        if (rc) {
-                CERROR("create failed rc = %d\n", rc);
-        } else if (oa->o_valid & (OBD_MD_FLCTIME|OBD_MD_FLMTIME|OBD_MD_FLSIZE)){
-                struct iattr attr;
+static int filter_create(struct obd_export *exp, struct obdo *oa,
+                         struct lov_stripe_md **ea, struct obd_trans_info *oti)
+{
+        struct obd_device *obd = NULL;
+        struct obd_run_ctxt saved;
+        struct lov_stripe_md *lsm = NULL;
+        obd_gr group = 0;
+        int rc = 0, diff;
+        ENTRY;
 
-                iattr_from_obdo(&attr, oa, oa->o_valid);
-                rc = fsfilt_setattr(obd, dchild, handle, &attr, 1);
-                if (rc)
-                        CERROR("create setattr failed rc = %d\n", rc);
-        }
-        rc = filter_finish_transno(exp, oti, rc);
-        err = filter_update_server_data(obd, filter->fo_rcvd_filp,
-                                        filter->fo_fsd);
-        if (err)
-                CERROR("unable to write lastobjid but file created\n");
-
-        /* Set flags for fields we have set in the inode struct */
-        if (!rc && mds_fid.id && (oa->o_valid & OBD_MD_FLCOOKIE)) {
-                err = filter_log_op_create(obd->u.filter.fo_catalog, &mds_fid,
-                                           dchild->d_inode->i_ino,
-                                           dchild->d_inode->i_generation,
-                                           oti->oti_logcookies);
-                if (err) {
-                        CERROR("error logging create record: rc %d\n", err);
-                        oa->o_valid = OBD_MD_FLID;
-                } else {
-                        oa->o_valid = OBD_MD_FLID | OBD_MD_FLCOOKIE;
+        if (oa->o_valid & OBD_MD_FLGROUP)
+                group = oa->o_gr;
+
+        CDEBUG(D_INFO, "filter_create(od->o_gr="LPU64",od->o_id="LPU64")\n",
+               group, oa->o_id);
+        if (ea != NULL) {
+                lsm = *ea;
+                if (lsm == NULL) {
+                        rc = obd_alloc_memmd(exp, &lsm);
+                        if (rc < 0)
+                                RETURN(rc);
                 }
-        } else
-                oa->o_valid = OBD_MD_FLID;
-
-        err = fsfilt_commit(obd, dparent->d_inode, handle, 0);
-        if (err) {
-                CERROR("error on commit, err = %d\n", err);
-                if (!rc)
-                        rc = err;
         }
 
-        if (rc)
-                GOTO(cleanup, rc);
+        obd = exp->exp_obd;
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
 
-        /* Set flags for fields we have set in the inode struct */
-        obdo_from_inode(oa, dchild->d_inode, FILTER_VALID_FLAGS);
+        diff = filter_should_precreate(exp, oa, group);
+        if (diff > 0) {
+                oa->o_id = filter_last_id(&obd->u.filter, oa);
+                rc = filter_precreate(obd, oa, group, &diff);
+                oa->o_id += diff;
+                oa->o_valid = OBD_MD_FLID;
+        }
 
-        EXIT;
-cleanup:
-        switch(cleanup_phase) {
-        case 2:
-                f_dput(dchild);
-        case 1: /* locked parent dentry */
-                if (rc || oti == NULL) {
-                        filter_parent_unlock(dparent, &parent_lockh, LCK_PW);
-                } else {
-                        memcpy(&oti->oti_ack_locks[0].lock, &parent_lockh,
-                               sizeof(parent_lockh));
-                        oti->oti_ack_locks[0].mode = LCK_PW;
-                }
-        case 0:
-                pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-                class_export_put(exp);
-                break;
-        default:
-                CERROR("invalid cleanup_phase %d\n", cleanup_phase);
-                LBUG();
+        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        if (rc && ea != NULL && *ea != lsm) {
+                obd_free_memmd(exp, &lsm);
+        } else if (rc == 0 && ea != NULL) {
+                /* XXX LOV STACKING: the lsm that is passed to us from
+                 * LOV does not have valid lsm_oinfo data structs, so
+                 * don't go touching that.  This needs to be fixed in a
+                 * big way. */
+                lsm->lsm_object_id = oa->o_id;
+                *ea = lsm;
         }
 
         RETURN(rc);
 }
 
-static int filter_destroy(struct lustre_handle *conn, struct obdo *oa,
+static int filter_destroy(struct obd_export *exp, struct obdo *oa,
                           struct lov_stripe_md *ea, struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         struct obd_device *obd;
         struct filter_obd *filter;
         struct dentry *dchild = NULL, *dparent = NULL;
-        struct filter_dentry_data *fdd;
         struct obd_run_ctxt saved;
         void *handle = NULL;
         struct lustre_handle parent_lockh;
         struct llog_cookie *fcc = NULL;
-        int rc, rc2, cleanup_phase = 0;
+        int rc, rc2, cleanup_phase = 0, have_prepared = 0;
+        obd_gr group = 0;
         ENTRY;
 
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",conn->cookie);
-                RETURN(-EINVAL);
-        }
+        if (oa->o_valid & OBD_MD_FLGROUP)
+                group = oa->o_gr;
 
         obd = exp->exp_obd;
         filter = &obd->u.filter;
 
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
-        dparent = filter_parent_lock(obd, oa->o_mode, oa->o_id,
-                                     LCK_PW, &parent_lockh);
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+
+ acquire_locks:
+        dparent = filter_parent_lock(obd, group, oa->o_id, LCK_PW,
+                                     &parent_lockh);
         if (IS_ERR(dparent))
                 GOTO(cleanup, rc = PTR_ERR(dparent));
         cleanup_phase = 1;
 
-        dchild = filter_fid2dentry(obd, dparent, S_IFREG, oa->o_id);
+        dchild = filter_fid2dentry(obd, dparent, group, oa->o_id);
         if (IS_ERR(dchild))
                 GOTO(cleanup, rc = -ENOENT);
         cleanup_phase = 2;
@@ -1960,48 +1756,48 @@ static int filter_destroy(struct lustre_handle *conn, struct obdo *oa,
                 CERROR("destroying non-existent object "LPU64"\n", oa->o_id);
                 GOTO(cleanup, rc = -ENOENT);
         }
+
+        if (!have_prepared) {
+                /* If we're really going to destroy the object, get ready
+                 * by getting the clients to discard their cached data.
+                 *
+                 * We have to drop the parent lock, because
+                 * filter_prepare_destroy will acquire a PW on the object, and
+                 * we don't want to deadlock with an incoming write to the
+                 * object, which has the extent PW and then wants to get the
+                 * parent dentry to do the lookup.
+                 *
+                 * We dput the child because it's not worth the extra
+                 * complication of condition the above code to skip it on the
+                 * second time through. */
+                f_dput(dchild);
+                filter_parent_unlock(dparent, &parent_lockh, LCK_PW);
+
+                filter_prepare_destroy(obd, oa->o_id);
+                have_prepared = 1;
+                goto acquire_locks;
+        }
+
         handle = fsfilt_start(obd, dparent->d_inode, FSFILT_OP_UNLINK_LOG, oti);
         if (IS_ERR(handle))
                 GOTO(cleanup, rc = PTR_ERR(handle));
         cleanup_phase = 3;
 
-        fdd = dchild->d_fsdata;
-
         /* Our MDC connection is established by the MDS to us */
-        if ((oa->o_valid & OBD_MD_FLCOOKIE) && filter->fo_mdc_imp != NULL) {
+        if (oa->o_valid & OBD_MD_FLCOOKIE) {
                 OBD_ALLOC(fcc, sizeof(*fcc));
                 if (fcc != NULL)
                         memcpy(fcc, obdo_logcookie(oa), sizeof(*fcc));
         }
 
-        if (fdd != NULL && atomic_read(&fdd->fdd_open_count)) {
-                LASSERT(fdd->fdd_magic == FILTER_DENTRY_MAGIC);
-                if (!(fdd->fdd_flags & FILTER_FLAG_DESTROY)) {
-                        fdd->fdd_flags |= FILTER_FLAG_DESTROY;
-
-#ifdef ENABLE_ORPHANS
-                        filter_log_op_orphan(filter->fo_catalog, oa->o_id,
-                                             oa->o_generation,&fdd->fdd_cookie);
-#endif
-                        CDEBUG(D_INODE,
-                               "defer destroy of %dx open objid "LPU64"\n",
-                               atomic_read(&fdd->fdd_open_count), oa->o_id);
-                } else {
-                        CDEBUG(D_INODE,
-                               "repeat destroy of %dx open objid "LPU64"\n",
-                               atomic_read(&fdd->fdd_open_count), oa->o_id);
-                }
-                GOTO(cleanup, rc = 0);
-        }
-
         rc = filter_destroy_internal(obd, oa->o_id, dparent, dchild);
 
 cleanup:
         switch(cleanup_phase) {
         case 3:
                 if (fcc != NULL)
-                        fsfilt_set_last_rcvd(obd, 0, oti->oti_handle,
-                                             filter_cancel_cookies_cb, fcc);
+                        fsfilt_add_journal_cb(obd, 0, oti->oti_handle,
+                                              filter_cancel_cookies_cb, fcc);
                 rc = filter_finish_transno(exp, oti, rc);
                 rc2 = fsfilt_commit(obd, dparent->d_inode, handle, 0);
                 if (rc2) {
@@ -2020,8 +1816,7 @@ cleanup:
                         oti->oti_ack_locks[0].mode = LCK_PW;
                 }
         case 0:
-                pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-                class_export_put(exp);
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
                 break;
         default:
                 CERROR("invalid cleanup_phase %d\n", cleanup_phase);
@@ -2032,7 +1827,7 @@ cleanup:
 }
 
 /* NB start and end are used for punch, but not truncate */
-static int filter_truncate(struct lustre_handle *conn, struct obdo *oa,
+static int filter_truncate(struct obd_export *exp, struct obdo *oa,
                            struct lov_stripe_md *lsm,
                            obd_off start, obd_off end,
                            struct obd_trans_info *oti)
@@ -2047,15 +1842,57 @@ static int filter_truncate(struct lustre_handle *conn, struct obdo *oa,
         CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = %x, "
                "o_size = "LPD64"\n", oa->o_id, oa->o_valid, start);
         oa->o_size = start;
-        error = filter_setattr(conn, oa, NULL, oti);
+        error = filter_setattr(exp, oa, NULL, oti);
         RETURN(error);
 }
 
-static int filter_syncfs(struct obd_export *exp)
+static int filter_sync(struct obd_export *exp, struct obdo *oa,
+                       struct lov_stripe_md *lsm, obd_off start, obd_off end)
 {
+        struct obd_run_ctxt saved;
+        struct filter_obd *filter;
+        struct dentry *dentry;
+        int rc, rc2;
         ENTRY;
 
-        RETURN(fsfilt_sync(exp->exp_obd, exp->exp_obd->u.filter.fo_sb));
+        filter = &exp->exp_obd->u.filter;
+
+        /* an objid of zero is taken to mean "sync whole filesystem" */
+        if (!oa || !oa->o_valid & OBD_MD_FLID) {
+                rc = fsfilt_sync(exp->exp_obd, filter->fo_sb);
+                GOTO(out_exp, rc);
+        }
+
+        dentry = filter_oa2dentry(exp->exp_obd, oa);
+        if (IS_ERR(dentry))
+                GOTO(out_exp, rc = PTR_ERR(dentry));
+
+        push_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
+
+        down(&dentry->d_inode->i_sem);
+        rc = filemap_fdatasync(dentry->d_inode->i_mapping);
+        if (rc == 0) {
+                /* just any file to grab fsync method - "file" arg unused */
+                struct file *file = filter->fo_rcvd_filp;
+
+                if (file->f_op && file->f_op->fsync)
+                        rc = file->f_op->fsync(NULL, dentry, 1);
+
+                rc2 = filemap_fdatawait(dentry->d_inode->i_mapping);
+                if (!rc)
+                        rc = rc2;
+        }
+        up(&dentry->d_inode->i_sem);
+
+        oa->o_valid = OBD_MD_FLID;
+        obdo_from_inode(oa, dentry->d_inode, FILTER_VALID_FLAGS);
+
+        pop_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
+
+        f_dput(dentry);
+out_exp:
+        class_export_put(exp);
+        RETURN(rc);
 }
 
 static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs,
@@ -2065,16 +1902,16 @@ static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs,
         RETURN(fsfilt_statfs(obd, obd->u.filter.fo_sb, osfs));
 }
 
-static int filter_get_info(struct lustre_handle *conn, __u32 keylen,
+static int filter_get_info(struct obd_export *exp, __u32 keylen,
                            void *key, __u32 *vallen, void *val)
 {
         struct obd_device *obd;
         ENTRY;
 
-        obd = class_conn2obd(conn);
+        obd = class_exp2obd(exp);
         if (obd == NULL) {
                 CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",
-                       conn->cookie);
+                       exp->exp_handle.h_cookie);
                 RETURN(-EINVAL);
         }
 
@@ -2094,22 +1931,33 @@ static int filter_get_info(struct lustre_handle *conn, __u32 keylen,
                 RETURN(0);
         }
 
+        if (keylen >= strlen("last_id") && memcmp(key, "last_id", 7) == 0) {
+                obd_id *last_id = val;
+                /* FIXME: object groups */
+                *last_id = filter_last_id(&obd->u.filter, 0);
+                RETURN(0);
+        }
         CDEBUG(D_IOCTL, "invalid key\n");
         RETURN(-EINVAL);
 }
 
-static int filter_set_info(struct lustre_handle *conn, __u32 keylen,
+static int filter_set_info(struct obd_export *exp, __u32 keylen,
                            void *key, __u32 vallen, void *val)
 {
         struct obd_device *obd;
-        struct obd_export *exp;
-        struct obd_import *imp;
+        struct lustre_handle conn;
+#ifdef ENABLE_ORPHANS
+        struct llog_ctxt *ctxt;
+#endif
+        int rc = 0;
         ENTRY;
 
-        obd = class_conn2obd(conn);
+        conn.cookie = exp->exp_handle.h_cookie;
+
+        obd = exp->exp_obd;
         if (obd == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",
-                       conn->cookie);
+                CDEBUG(D_IOCTL, "invalid exp %p cookie "LPX64"\n",
+                       exp, conn.cookie);
                 RETURN(-EINVAL);
         }
 
@@ -2117,29 +1965,21 @@ static int filter_set_info(struct lustre_handle *conn, __u32 keylen,
             memcmp(key, "mds_conn", keylen) != 0)
                 RETURN(-EINVAL);
 
-        CERROR("Received MDS connection ("LPX64")\n", conn->cookie);
-        memcpy(&obd->u.filter.fo_mdc_conn, conn, sizeof(*conn));
-
-        imp = obd->u.filter.fo_mdc_imp = class_new_import();
-
-        exp = class_conn2export(conn);
-        imp->imp_connection = ptlrpc_connection_addref(exp->exp_connection);
-        class_export_put(exp);
-
-        imp->imp_client = &obd->u.filter.fo_mdc_client;
-        imp->imp_remote_handle = *conn;
-        imp->imp_obd = obd;
-        imp->imp_dlm_fake = 1; /* XXX rename imp_dlm_fake to something else */
-        imp->imp_level = LUSTRE_CONN_FULL;
-        class_import_put(imp);
-
-        RETURN(0);
+        CWARN("Received MDS connection ("LPX64")\n", conn.cookie);
+        memcpy(&obd->u.filter.fo_mdc_conn, &conn, sizeof(conn));
+#ifdef ENABLE_ORPHANS
+        ctxt = llog_get_context(obd, LLOG_UNLINK_REPL_CTXT);
+        rc = llog_receptor_accept(ctxt, exp->exp_imp_reverse);
+#endif
+        RETURN(rc);
 }
 
-int filter_iocontrol(unsigned int cmd, struct lustre_handle *conn,
+int filter_iocontrol(unsigned int cmd, struct obd_export *exp,
                      int len, void *karg, void *uarg)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_ioctl_data *data = karg;
+        int rc = 0;
 
         switch (cmd) {
         case OBD_IOC_ABORT_RECOVERY:
@@ -2147,12 +1987,106 @@ int filter_iocontrol(unsigned int cmd, struct lustre_handle *conn,
                 target_abort_recovery(obd);
                 RETURN(0);
 
+        case OBD_IOC_SET_READONLY: {
+                void *handle;
+                struct super_block *sb = obd->u.filter.fo_sb;
+                struct inode *inode = sb->s_root->d_inode;
+                BDEVNAME_DECLARE_STORAGE(tmp);
+                CERROR("setting device %s read-only\n",
+                       ll_bdevname(sb, tmp));
+                
+                handle = fsfilt_start(obd, inode, FSFILT_OP_MKNOD, NULL);
+                LASSERT(handle);
+                (void)fsfilt_commit(obd, inode, handle, 1);
+
+                dev_set_rdonly(ll_sbdev(obd->u.filter.fo_sb), 2);
+                RETURN(0);
+        }
+
+        case OBD_IOC_CATLOGLIST: {
+                rc = llog_catlog_list(obd, 1, data);
+                RETURN(rc);
+        }
+
+        case OBD_IOC_LLOG_CANCEL:
+        case OBD_IOC_LLOG_REMOVE: 
+        case OBD_IOC_LLOG_INFO:
+        case OBD_IOC_LLOG_PRINT: {
+                /* FIXME to be finished */
+                RETURN(-EOPNOTSUPP);
+/*
+                struct llog_ctxt *ctxt = NULL;
+                
+                push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+                rc = llog_ioctl(ctxt, cmd, data);
+                pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL);
+                
+                RETURN(rc);
+*/
+        }
+
+
         default:
                 RETURN(-EINVAL);
         }
         RETURN(0);
 }
 
+static struct llog_operations filter_unlink_repl_logops;
+static struct llog_operations filter_size_orig_logops = {
+        lop_setup: llog_obd_origin_setup,
+        lop_cleanup: llog_obd_origin_cleanup,
+        lop_add: llog_obd_origin_add
+};
+
+static int filter_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                            int count, struct llog_logid *logid) 
+{
+        struct llog_ctxt *ctxt;
+        int rc;
+        ENTRY;
+        
+        filter_unlink_repl_logops = llog_client_ops;
+        filter_unlink_repl_logops.lop_cancel = llog_obd_repl_cancel;
+        filter_unlink_repl_logops.lop_connect = llog_repl_connect;
+        filter_unlink_repl_logops.lop_sync = llog_obd_repl_sync;
+
+        rc = llog_setup(obd, LLOG_UNLINK_REPL_CTXT, tgt, 0, NULL,
+                        &filter_unlink_repl_logops);
+        if (rc)
+                RETURN(rc);
+        /* FIXME - assign unlink_cb for filter's recovery */
+        ctxt = llog_get_context(obd, LLOG_UNLINK_REPL_CTXT);
+        ctxt->llog_proc_cb = filter_recov_log_unlink_cb;
+
+        rc = llog_setup(obd, LLOG_SIZE_ORIG_CTXT, tgt, 0, NULL,
+                        &filter_size_orig_logops);
+        RETURN(rc);
+}
+
+static int filter_llog_finish(struct obd_device *obd, int count)
+{
+        int rc;
+        ENTRY;
+        
+        rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_REPL_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_ORIG_CTXT));
+        RETURN(rc);
+}
+
+static struct dentry *filter_lvfs_fid2dentry(__u64 id, __u32 gen, __u64 gr,
+                                             void *data)
+{
+        return filter_fid2dentry(data, NULL, gr, id);
+}
+
+static struct lvfs_callback_ops filter_lvfs_ops = {
+        l_fid2dentry:     filter_lvfs_fid2dentry,
+};
+
 static struct obd_ops filter_obd_ops = {
         o_owner:          THIS_MODULE,
         o_attach:         filter_attach,
@@ -2160,23 +2094,25 @@ static struct obd_ops filter_obd_ops = {
         o_get_info:       filter_get_info,
         o_set_info:       filter_set_info,
         o_setup:          filter_setup,
+        o_postsetup:      filter_postsetup,
+        o_precleanup:     filter_precleanup,
         o_cleanup:        filter_cleanup,
         o_connect:        filter_connect,
         o_disconnect:     filter_disconnect,
         o_statfs:         filter_statfs,
-        o_syncfs:         filter_syncfs,
         o_getattr:        filter_getattr,
+        o_unpackmd:       filter_unpackmd,
         o_create:         filter_create,
         o_setattr:        filter_setattr,
         o_destroy:        filter_destroy,
-        o_open:           filter_open,
-        o_close:          filter_close,
         o_brw:            filter_brw,
         o_punch:          filter_truncate,
+        o_sync:           filter_sync,
         o_preprw:         filter_preprw,
         o_commitrw:       filter_commitrw,
-        o_log_cancel:     filter_log_cancel,
         o_destroy_export: filter_destroy_export,
+        o_llog_init:      filter_llog_init,
+        o_llog_finish:    filter_llog_finish,
         o_iocontrol:      filter_iocontrol,
 };
 
@@ -2187,23 +2123,25 @@ static struct obd_ops filter_sanobd_ops = {
         o_get_info:       filter_get_info,
         o_set_info:       filter_set_info,
         o_setup:          filter_san_setup,
+        o_precleanup:     filter_precleanup,
         o_cleanup:        filter_cleanup,
         o_connect:        filter_connect,
         o_disconnect:     filter_disconnect,
         o_statfs:         filter_statfs,
         o_getattr:        filter_getattr,
+        o_unpackmd:       filter_unpackmd,
         o_create:         filter_create,
         o_setattr:        filter_setattr,
         o_destroy:        filter_destroy,
-        o_open:           filter_open,
-        o_close:          filter_close,
         o_brw:            filter_brw,
         o_punch:          filter_truncate,
+        o_sync:           filter_sync,
         o_preprw:         filter_preprw,
         o_commitrw:       filter_commitrw,
-        o_log_cancel:     filter_log_cancel,
         o_san_preprw:     filter_san_preprw,
         o_destroy_export: filter_destroy_export,
+        o_llog_init:      filter_llog_init,
+        o_llog_finish:    filter_llog_finish,
         o_iocontrol:      filter_iocontrol,
 };
 
@@ -2212,7 +2150,7 @@ static int __init obdfilter_init(void)
         struct lprocfs_static_vars lvars;
         int rc;
 
-        printk(KERN_INFO "Lustre Filtering OBD driver; info@clusterfs.com\n");
+        printk(KERN_INFO "Lustre: Filtering OBD driver; info@clusterfs.com\n");
 
         lprocfs_init_vars(filter, &lvars);
 
diff --git a/lustre/obdfilter/filter_internal.h b/lustre/obdfilter/filter_internal.h
index 4207056b7d530fa53c633b04f763c34738bdc67c..da8faa3dc1942c62479db797b495a2945f152c39 100644
--- a/lustre/obdfilter/filter_internal.h
+++ b/lustre/obdfilter/filter_internal.h
@@ -16,6 +16,8 @@
 #include <linux/lustre_handles.h>
 #include <linux/obd.h>
 
+#define FILTER_LAYOUT_VERSION "2"
+
 #ifndef OBD_FILTER_DEVICENAME
 # define OBD_FILTER_DEVICENAME "obdfilter"
 #endif
@@ -25,9 +27,7 @@
 #endif
 
 #define LAST_RCVD "last_rcvd"
-#define FILTER_INIT_OBJID 2
-/* max creates/sec * journal->j_commit_interval */
-#define FILTER_SKIP_OBJID (10000 * 5)
+#define FILTER_INIT_OBJID 0
 
 #define FILTER_LR_SERVER_SIZE    512
 
@@ -39,15 +39,21 @@
 #define FILTER_LR_MAX_CLIENT_WORDS (FILTER_LR_MAX_CLIENTS/sizeof(unsigned long))
 
 #define FILTER_SUBDIR_COUNT      32            /* set to zero for no subdirs */
+#define FILTER_GROUPS 3 /* must be at least 3; not dynamic yet */
 
 #define FILTER_MOUNT_RECOV 2
 #define FILTER_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */
 
-/* Data stored per server at the head of the last_rcvd file.  In le32 order. */
+#define FILTER_ROCOMPAT_SUPP   (0)
+
+#define FILTER_INCOMPAT_GROUPS 0x00000001
+#define FILTER_INCOMPAT_SUPP   (FILTER_INCOMPAT_GROUPS)
+
+/* Data stored per server at the head of the last_rcvd file.  In le32 order.
+ * Try to keep this the same as mds_server_data so we might one day merge. */
 struct filter_server_data {
-        __u8  fsd_uuid[37];        /* server UUID */
-        __u8  fsd_uuid_padding[3]; /* unused */
-        __u64 fsd_last_objid;      /* last created object ID */
+        __u8  fsd_uuid[40];        /* server UUID */
+        __u64 fsd_unused;          /* was fsd_last_objid - don't use for now */
         __u64 fsd_last_transno;    /* last completed transaction ID */
         __u64 fsd_mount_count;     /* FILTER incarnation number */
         __u32 fsd_feature_compat;  /* compatible feature flags */
@@ -59,37 +65,19 @@ struct filter_server_data {
         __u16 fsd_subdir_count;    /* number of subdirectories for objects */
         __u64 fsd_catalog_oid;     /* recovery catalog object id */
         __u32 fsd_catalog_ogen;    /* recovery catalog inode generation */
-        __u8  fsd_peeruuid[37];    /* UUID of MDS associated with this OST */
-        __u8  peer_padding[3];     /* unused */
+        __u8  fsd_peeruuid[40];    /* UUID of MDS associated with this OST */
         __u8  fsd_padding[FILTER_LR_SERVER_SIZE - 140];
 };
 
 /* Data stored per client in the last_rcvd file.  In le32 order. */
 struct filter_client_data {
-        __u8  fcd_uuid[37];        /* client UUID */
-        __u8  fcd_uuid_padding[3]; /* unused */
+        __u8  fcd_uuid[40];        /* client UUID */
         __u64 fcd_last_rcvd;       /* last completed transaction ID */
         __u64 fcd_mount_count;     /* FILTER incarnation number */
         __u64 fcd_last_xid;        /* client RPC xid for the last transaction */
         __u8  fcd_padding[FILTER_LR_CLIENT_SIZE - 64];
 };
 
-/* file data for open files on OST */
-struct filter_file_data {
-        struct portals_handle ffd_handle;
-        atomic_t              ffd_refcount;
-        struct list_head      ffd_export_list; /* export open list - fed_lock */
-        struct file          *ffd_file;         /* file handle */
-};
-
-struct filter_dentry_data {
-        struct llog_cookie      fdd_cookie;
-        obd_id                  fdd_objid;
-        __u32                   fdd_magic;
-        atomic_t                fdd_open_count;
-        int                     fdd_flags;
-};
-
 #define FILTER_DENTRY_MAGIC 0x9efba101
 #define FILTER_FLAG_DESTROY 0x0001      /* destroy dentry on last file close */
 
@@ -105,21 +93,22 @@ enum {
 };
 
 /* filter.c */
-struct dentry *filter_parent(struct obd_device *, obd_mode mode, obd_id objid);
-struct dentry *filter_parent_lock(struct obd_device *, obd_mode mode,
-                                  obd_id objid, ldlm_mode_t lock_mode,
-                                  struct lustre_handle *lockh);
+struct dentry *filter_parent(struct obd_device *, obd_gr group, obd_id objid);
+struct dentry *filter_parent_lock(struct obd_device *, obd_gr, obd_id,
+                                  ldlm_mode_t, struct lustre_handle *);
 void f_dput(struct dentry *);
 struct dentry *filter_fid2dentry(struct obd_device *, struct dentry *dir,
-                                 obd_mode mode, obd_id id);
+                                 obd_gr group, obd_id id);
 struct dentry *__filter_oa2dentry(struct obd_device *obd, struct obdo *oa,
                                   const char *what);
 #define filter_oa2dentry(obd, oa) __filter_oa2dentry(obd, oa, __FUNCTION__)
 
 int filter_finish_transno(struct obd_export *, struct obd_trans_info *, int rc);
-__u64 filter_next_id(struct filter_obd *);
+__u64 filter_next_id(struct filter_obd *, struct obdo *);
+__u64 filter_last_id(struct filter_obd *, struct obdo *);
 int filter_update_server_data(struct obd_device *, struct file *,
-                              struct filter_server_data *);
+                              struct filter_server_data *, int force_sync);
+int filter_update_last_objid(struct obd_device *, obd_gr, int force_sync);
 int filter_common_setup(struct obd_device *, obd_count len, void *buf,
                         char *option);
 
@@ -130,23 +119,35 @@ int filter_preprw(int cmd, struct obd_export *, struct obdo *, int objcount,
 int filter_commitrw(int cmd, struct obd_export *, struct obdo *, int objcount,
                     struct obd_ioobj *, int niocount, struct niobuf_local *,
                     struct obd_trans_info *);
-int filter_brw(int cmd, struct lustre_handle *, struct obdo *,
+int filter_brw(int cmd, struct obd_export *, struct obdo *,
 	       struct lov_stripe_md *, obd_count oa_bufs, struct brw_page *,
 	       struct obd_trans_info *);
+void flip_into_page_cache(struct inode *inode, struct page *new_page);
+
+/* filter_io_*.c */
+int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
+                          struct obd_ioobj *obj, int niocount,
+                          struct niobuf_local *res, struct obd_trans_info *oti);
 
 /* filter_log.c */
-int filter_log_cancel(struct lustre_handle *, struct lov_stripe_md *,
-                      int num_cookies, struct llog_cookie *, int flags);
-int filter_log_op_create(struct llog_handle *cathandle, struct ll_fid *mds_fid,
-                         obd_id oid, obd_count ogen, struct llog_cookie *);
-int filter_log_op_orphan(struct llog_handle *cathandle, obd_id oid,
-                         obd_count ogen, struct llog_cookie *);
-struct llog_handle *filter_get_catalog(struct obd_device *);
-void filter_put_catalog(struct llog_handle *cathandle);
+struct ost_filterdata {
+        __u32  ofd_epoch;
+};
+int filter_log_sz_change(struct llog_handle *cathandle, 
+                         struct ll_fid *mds_fid,
+                         __u32 io_epoch,
+                         struct llog_cookie *logcookie, 
+                         struct inode *inode);
+//int filter_get_catalog(struct obd_device *);
+void filter_cancel_cookies_cb(struct obd_device *obd, __u64 transno,
+                              void *cb_data, int error);
+int filter_recov_log_unlink_cb(struct llog_handle *llh,
+                               struct llog_rec_hdr *rec, void *data);
 
 /* filter_san.c */
 int filter_san_setup(struct obd_device *obd, obd_count len, void *buf);
 int filter_san_preprw(int cmd, struct obd_export *, struct obdo *, int objcount,
                       struct obd_ioobj *, int niocount, struct niobuf_remote *);
 
+
 #endif
diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c
index 001dc0f061a76d6edb9921ba132f0b8bfda6eeec..1ce8825621f24a28775cabcd2cf08919e4b77ea3 100644
--- a/lustre/obdfilter/filter_io.c
+++ b/lustre/obdfilter/filter_io.c
@@ -43,8 +43,8 @@ static int filter_start_page_read(struct inode *inode, struct niobuf_local *lnb)
         int rc;
 
         page = grab_cache_page(mapping, index); /* locked page */
-        if (IS_ERR(page))
-                return lnb->rc = PTR_ERR(page);
+        if (page == NULL)
+                return lnb->rc = -ENOMEM;
 
         LASSERT(page->mapping == mapping);
 
@@ -99,138 +99,6 @@ err_page:
         return lnb->rc;
 }
 
-static struct page *lustre_get_page_write(struct inode *inode,
-                                          unsigned long index)
-{
-        struct address_space *mapping = inode->i_mapping;
-        struct page *page;
-        int rc;
-
-        page = grab_cache_page(mapping, index); /* locked page */
-
-        if (!IS_ERR(page)) {
-                /* Note: Called with "O" and "PAGE_SIZE" this is essentially
-                 * a no-op for most filesystems, because we write the whole
-                 * page.  For partial-page I/O this will read in the page.
-                 */
-                rc = mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
-                if (rc) {
-                        CERROR("page index %lu, rc = %d\n", index, rc);
-                        if (rc != -ENOSPC)
-                                LBUG();
-                        GOTO(err_unlock, rc);
-                }
-                /* XXX not sure if we need this if we are overwriting page */
-                if (PageError(page)) {
-                        CERROR("error on page index %lu, rc = %d\n", index, rc);
-                        LBUG();
-                        GOTO(err_unlock, rc = -EIO);
-                }
-        }
-        return page;
-
-err_unlock:
-        unlock_page(page);
-        page_cache_release(page);
-        return ERR_PTR(rc);
-}
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-int wait_on_page_locked(struct page *page)
-{
-        waitfor_one_page(page);
-        return 0;
-}
-
-/* We should only change the file mtime (and not the ctime, like
- * update_inode_times() in generic_file_write()) when we only change data. */
-static inline void inode_update_time(struct inode *inode, int ctime_too)
-{
-        time_t now = CURRENT_TIME;
-        if (inode->i_mtime == now && (!ctime_too || inode->i_ctime == now))
-                return;
-        inode->i_mtime = now;
-        if (ctime_too)
-                inode->i_ctime = now;
-        mark_inode_dirty_sync(inode);
-}
-#endif
-
-static int lustre_commit_write(struct niobuf_local *lnb)
-{
-        struct page *page = lnb->page;
-        unsigned from = lnb->offset & ~PAGE_MASK;
-        unsigned to = from + lnb->len;
-        struct inode *inode = page->mapping->host;
-        int err;
-
-        LASSERT(to <= PAGE_SIZE);
-        err = page->mapping->a_ops->commit_write(NULL, page, from, to);
-#warning 2.4 folks: wait_on_page_locked does NOT return its error here.
-        if (!err && IS_SYNC(inode))
-                wait_on_page_locked(page);
-        //SetPageUptodate(page); // the client commit_write will do this
-
-        SetPageReferenced(page);
-        unlock_page(page);
-        page_cache_release(page);
-        return err;
-}
-
-int filter_get_page_write(struct inode *inode, struct niobuf_local *lnb,
-                          int *pglocked)
-{
-        unsigned long index = lnb->offset >> PAGE_SHIFT;
-        struct address_space *mapping = inode->i_mapping;
-        struct page *page;
-        int rc;
-
-        //ASSERT_PAGE_INDEX(index, GOTO(err, rc = -EINVAL));
-        if (*pglocked)
-                page = grab_cache_page_nowait(mapping, index); /* locked page */
-        else
-                page = grab_cache_page(mapping, index); /* locked page */
-
-
-        /* This page is currently locked, so get a temporary page instead. */
-        if (page == NULL) {
-                CDEBUG(D_INFO, "ino %lu page %ld locked\n", inode->i_ino,index);
-                page = alloc_pages(GFP_KERNEL, 0); /* locked page */
-                if (page == NULL) {
-                        CERROR("no memory for a temp page\n");
-                        GOTO(err, rc = -ENOMEM);
-                }
-                page->index = index;
-                lnb->page = page;
-                lnb->flags |= N_LOCAL_TEMP_PAGE;
-        } else if (!IS_ERR(page)) {
-                unsigned from = lnb->offset & ~PAGE_MASK, to = from + lnb->len;
-                (*pglocked)++;
-
-                rc = mapping->a_ops->prepare_write(NULL, page, from, to);
-                if (rc) {
-                        if (rc != -ENOSPC)
-                                CERROR("page index %lu, rc = %d\n", index, rc);
-                        GOTO(err_unlock, rc);
-                }
-                /* XXX not sure if we need this if we are overwriting page */
-                if (PageError(page)) {
-                        CERROR("error on page index %lu, rc = %d\n", index, rc);
-                        LBUG();
-                        GOTO(err_unlock, rc = -EIO);
-                }
-                lnb->page = page;
-        }
-
-        return 0;
-
-err_unlock:
-        unlock_page(page);
-        page_cache_release(page);
-err:
-        return lnb->rc = rc;
-}
-
 static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
                               int objcount, struct obd_ioobj *obj,
                               int niocount, struct niobuf_remote *nb,
@@ -240,7 +108,7 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
         struct obd_run_ctxt saved;
         struct obd_ioobj *o;
         struct niobuf_remote *rnb;
-        struct niobuf_local *lnb;
+        struct niobuf_local *lnb = NULL;
         struct fsfilt_objinfo *fso;
         struct dentry *dentry;
         struct inode *inode;
@@ -258,9 +126,8 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
 
         memset(res, 0, niocount * sizeof(*res));
 
-        push_ctxt(&saved, &exp->exp_obd->u.filter.fo_ctxt, NULL);
+        push_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
         for (i = 0, o = obj; i < objcount; i++, o++) {
-                struct filter_dentry_data *fdd;
                 LASSERT(o->ioo_bufcnt);
 
                 dentry = filter_oa2dentry(exp->exp_obd, oa);
@@ -276,15 +143,13 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
 
                 fso[i].fso_dentry = dentry;
                 fso[i].fso_bufcnt = o->ioo_bufcnt;
-
-                fdd = dentry->d_fsdata;
-                if (fdd == NULL || !atomic_read(&fdd->fdd_open_count))
-                        CDEBUG(D_PAGE, "I/O to unopened object "LPU64"\n",
-                               o->ioo_id);
         }
 
         if (time_after(jiffies, now + 15 * HZ))
-                CERROR("slow prep setup %lus\n", (jiffies - now) / HZ);
+                CERROR("slow preprw_read setup %lus\n", (jiffies - now) / HZ);
+        else
+                CDEBUG(D_INFO, "preprw_read setup: %lu jiffies\n",
+                       (jiffies - now));
 
         for (i = 0, o = obj, rnb = nb, lnb = res; i < objcount; i++, o++) {
                 dentry = fso[i].fso_dentry;
@@ -325,7 +190,10 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
         }
 
         if (time_after(jiffies, now + 15 * HZ))
-                CERROR("slow prep get page %lus\n", (jiffies - now) / HZ);
+                CERROR("slow start_page_read %lus\n", (jiffies - now) / HZ);
+        else
+                CDEBUG(D_INFO, "start_page_read: %lu jiffies\n",
+                       (jiffies - now));
 
         lprocfs_counter_add(exp->exp_obd->obd_stats, LPROC_FILTER_READ_BYTES,
                             tot_bytes);
@@ -340,7 +208,10 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
         }
 
         if (time_after(jiffies, now + 15 * HZ))
-                CERROR("slow prep finish page %lus\n", (jiffies - now) / HZ);
+                CERROR("slow finish_page_read %lus\n", (jiffies - now) / HZ);
+        else
+                CDEBUG(D_INFO, "finish_page_read: %lu jiffies\n",
+                       (jiffies - now));
 
         EXIT;
 
@@ -355,49 +226,26 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
                         f_dput(res->dentry);
                 else
                         CERROR("NULL dentry in cleanup -- tell CFS\n");
-                res->dentry = NULL;
         case 0:
                 OBD_FREE(fso, objcount * sizeof(*fso));
-                pop_ctxt(&saved, &exp->exp_obd->u.filter.fo_ctxt, NULL);
+                pop_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
         }
         return rc;
 }
 
-/* We need to balance prepare_write() calls with commit_write() calls.
- * If the page has been prepared, but we have no data for it, we don't
- * want to overwrite valid data on disk, but we still need to zero out
- * data for space which was newly allocated.  Like part of what happens
- * in __block_prepare_write() for newly allocated blocks.
- *
- * XXX currently __block_prepare_write() creates buffers for all the
- *     pages, and the filesystems mark these buffers as BH_New if they
- *     were newly allocated from disk. We use the BH_New flag similarly. */
-static int filter_commit_write(struct niobuf_local *lnb, int err)
+static int filter_start_page_write(struct inode *inode,
+                                   struct niobuf_local *lnb)
 {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        if (err) {
-                unsigned block_start, block_end;
-                struct buffer_head *bh, *head = lnb->page->buffers;
-                unsigned blocksize = head->b_size;
-
-                /* debugging: just seeing if this ever happens */
-                CDEBUG(err == -ENOSPC ? D_INODE : D_ERROR,
-                       "called for ino %lu:%lu on err %d\n",
-                       lnb->page->mapping->host->i_ino, lnb->page->index, err);
-
-                /* Currently one buffer per page, but in the future... */
-                for (bh = head, block_start = 0; bh != head || !block_start;
-                     block_start = block_end, bh = bh->b_this_page) {
-                        block_end = block_start + blocksize;
-                        if (buffer_new(bh)) {
-                                memset(kmap(lnb->page) + block_start, 0,
-                                       blocksize);
-                                kunmap(lnb->page);
-                        }
-                }
+        struct page *page = alloc_pages(GFP_HIGHUSER, 0);
+        if (page == NULL) {
+                CERROR("no memory for a temp page\n");
+                RETURN(lnb->rc = -ENOMEM);
         }
-#endif
-        return lustre_commit_write(lnb);
+        POISON_PAGE(page, 0xf1);
+        page->index = lnb->offset >> PAGE_SHIFT;
+        lnb->page = page;
+
+        return 0;
 }
 
 /* If we ever start to support multi-object BRW RPCs, we will need to get locks
@@ -417,130 +265,73 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
                                struct obd_trans_info *oti)
 {
         struct obd_run_ctxt saved;
-        struct obd_ioobj *o;
         struct niobuf_remote *rnb;
-        struct niobuf_local *lnb;
-        struct fsfilt_objinfo *fso;
+        struct niobuf_local *lnb = NULL;
+        struct fsfilt_objinfo fso;
         struct dentry *dentry;
-        int pglocked = 0, rc = 0, i, j, tot_bytes = 0;
+        int rc = 0, i, tot_bytes = 0;
         unsigned long now = jiffies;
         ENTRY;
         LASSERT(objcount == 1);
-
-        /* We should never be called during a transaction */
-        LASSERT(oti != NULL);
-        LASSERT(oti->oti_handle == NULL);
-        LASSERT(current->journal_info == NULL);
-
-        OBD_ALLOC(fso, objcount * sizeof(*fso));
-        if (fso == NULL)
-                RETURN(-ENOMEM);
+        LASSERT(obj->ioo_bufcnt > 0);
 
         memset(res, 0, niocount * sizeof(*res));
 
-        push_ctxt(&saved, &exp->exp_obd->u.filter.fo_ctxt, NULL);
-        for (i = 0, o = obj; i < objcount; i++, o++) {
-                struct filter_dentry_data *fdd;
-                LASSERT(o->ioo_bufcnt);
-
-                dentry = filter_oa2dentry(exp->exp_obd, oa);
-                if (IS_ERR(dentry))
-                        GOTO(out_objinfo, rc = PTR_ERR(dentry));
-
-                if (dentry->d_inode == NULL) {
-                        CERROR("trying to BRW to non-existent file "LPU64"\n",
-                               o->ioo_id);
-                        f_dput(dentry);
-                        GOTO(out_objinfo, rc = -ENOENT);
-                }
-
-                fso[i].fso_dentry = dentry;
-                fso[i].fso_bufcnt = o->ioo_bufcnt;
-
-                down(&dentry->d_inode->i_sem);
-                fdd = dentry->d_fsdata;
-                if (fdd == NULL || !atomic_read(&fdd->fdd_open_count))
-                        CDEBUG(D_PAGE, "I/O to unopened object "LPU64"\n",
-                               o->ioo_id);
+        push_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
+        dentry = filter_fid2dentry(exp->exp_obd, NULL, obj->ioo_gr, 
+                                   obj->ioo_id);
+        if (IS_ERR(dentry))
+                GOTO(cleanup, rc = PTR_ERR(dentry));
+
+        if (dentry->d_inode == NULL) {
+                CERROR("trying to BRW to non-existent file "LPU64"\n",
+                       obj->ioo_id);
+                f_dput(dentry);
+                GOTO(cleanup, rc = -ENOENT);
         }
 
-        if (time_after(jiffies, now + 15 * HZ))
-                CERROR("slow prep setup %lus\n", (jiffies - now) / HZ);
-
-        oti->oti_handle = fsfilt_brw_start(exp->exp_obd, objcount, fso,
-                                           niocount, oti);
-        if (IS_ERR(oti->oti_handle)) {
-                rc = PTR_ERR(oti->oti_handle);
-                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
-                       "error starting transaction: rc = %d\n", rc);
-                oti->oti_handle = NULL;
-                GOTO(out_objinfo, rc);
-        }
-
-        for (i = 0, o = obj, rnb = nb, lnb = res; i < objcount; i++, o++) {
-                dentry = fso[i].fso_dentry;
-                for (j = 0; j < o->ioo_bufcnt; j++, rnb++, lnb++) {
-                        if (j == 0)
-                                lnb->dentry = dentry;
-                        else
-                                lnb->dentry = dget(dentry);
-
-                        lnb->offset = rnb->offset;
-                        lnb->len    = rnb->len;
-                        lnb->flags  = rnb->flags;
-                        lnb->start  = jiffies;
-
-                        rc = filter_get_page_write(dentry->d_inode, lnb,
-                                                   &pglocked);
-                        if (rc)
-                                up(&dentry->d_inode->i_sem);
+        fso.fso_dentry = dentry;
+        fso.fso_bufcnt = obj->ioo_bufcnt;
 
-                        if (rc) {
-                                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
-                                       "page err %u@"LPU64" %u/%u %p: rc %d\n",
-                                       lnb->len, lnb->offset, j, o->ioo_bufcnt,
-                                       dentry, rc);
-                                f_dput(dentry);
-                                GOTO(out_pages, rc);
-                        }
-                        tot_bytes += lnb->len;
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow preprw_write setup %lus\n", (jiffies - now) / HZ);
+        else
+                CDEBUG(D_INFO, "preprw_write setup: %lu jiffies\n",
+                       (jiffies - now));
+
+        for (i = 0, rnb = nb, lnb = res; i < obj->ioo_bufcnt;
+             i++, lnb++, rnb++) {
+                lnb->dentry = dentry;
+                lnb->offset = rnb->offset;
+                lnb->len    = rnb->len;
+                lnb->flags  = rnb->flags;
+                lnb->start  = jiffies;
+
+                rc = filter_start_page_write(dentry->d_inode, lnb);
+                if (rc) {
+                        CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR, "page err %u@"
+                               LPU64" %u/%u %p: rc %d\n", lnb->len, lnb->offset,
+                               i, obj->ioo_bufcnt, dentry, rc);
+                        while (lnb-- > res)
+                                __free_pages(lnb->page, 0);
+                        f_dput(dentry);
+                        GOTO(cleanup, rc);
                 }
+                tot_bytes += lnb->len;
         }
 
         if (time_after(jiffies, now + 15 * HZ))
-                CERROR("slow prep get page %lus\n", (jiffies - now) / HZ);
+                CERROR("slow start_page_write %lus\n", (jiffies - now) / HZ);
+        else
+                CDEBUG(D_INFO, "start_page_write: %lu jiffies\n",
+                       (jiffies - now));
 
         lprocfs_counter_add(exp->exp_obd->obd_stats, LPROC_FILTER_WRITE_BYTES,
                             tot_bytes);
-
         EXIT;
-out:
-        OBD_FREE(fso, objcount * sizeof(*fso));
-        /* we saved the journal handle into oti->oti_handle instead */
-        current->journal_info = NULL;
-        pop_ctxt(&saved, &exp->exp_obd->u.filter.fo_ctxt, NULL);
+cleanup:
+        pop_ctxt(&saved, &exp->exp_obd->obd_ctxt, NULL);
         return rc;
-
-out_pages:
-        while (lnb-- > res) {
-                filter_commit_write(lnb, rc);
-                up(&lnb->dentry->d_inode->i_sem);
-                f_dput(lnb->dentry);
-        }
-        filter_finish_transno(exp, oti, rc);
-        fsfilt_commit(exp->exp_obd,
-                      filter_parent(exp->exp_obd,S_IFREG,obj->ioo_id)->d_inode,
-                      oti->oti_handle, 0);
-        LASSERT(current->journal_info == NULL);
-        oti->oti_handle = NULL;
-        goto out; /* dropped the dentry refs already (one per page) */
-
-out_objinfo:
-        for (i = 0; i < objcount && fso[i].fso_dentry; i++) {
-                up(&fso[i].fso_dentry->d_inode->i_sem);
-                f_dput(fso[i].fso_dentry);
-        }
-        goto out;
 }
 
 int filter_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
@@ -557,58 +348,12 @@ int filter_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
                                           niocount, nb, res, oti);
 
         LBUG();
-
         return -EPROTO;
 }
 
-/* It is highly unlikely that we would ever get an error here.  The page we want
- * to get was previously locked, so it had to have already allocated the space,
- * and we were just writing over the same data, so there would be no hole in the
- * file.
- *
- * XXX: possibility of a race with truncate could exist, need to check that.
- *      There are no guarantees w.r.t. write order even on a local filesystem,
- *      although the normal response would be to return the number of bytes
- *      successfully written and leave the rest to the app. */
-static int filter_write_locked_page(struct niobuf_local *lnb)
-{
-        struct page *lpage;
-        void *lpage_addr, *lnb_addr;
-        int rc;
-        ENTRY;
-
-        lpage = lustre_get_page_write(lnb->dentry->d_inode, lnb->page->index);
-        if (IS_ERR(lpage)) {
-                rc = PTR_ERR(lpage);
-                CERROR("error getting locked page index %ld: rc = %d\n",
-                       lnb->page->index, rc);
-                LBUG();
-                lustre_commit_write(lnb);
-                RETURN(rc);
-        }
-
-        /* 2 kmaps == vanishingly small deadlock opportunity */
-        lpage_addr = kmap(lpage);
-        lnb_addr = kmap(lnb->page);
-
-        memcpy(lpage_addr, lnb_addr, PAGE_SIZE);
-
-        kunmap(lnb->page);
-        kunmap(lpage);
-
-        page_cache_release(lnb->page);
-
-        lnb->page = lpage;
-        rc = lustre_commit_write(lnb);
-        if (rc)
-                CERROR("error committing locked page %ld: rc = %d\n",
-                       lnb->page->index, rc);
-        RETURN(rc);
-}
-
-static int filter_commitrw_read(struct obd_export *exp, int objcount,
-                                struct obd_ioobj *obj, int niocount,
-                                struct niobuf_local *res,
+static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa,
+                                int objcount, struct obd_ioobj *obj,
+                                int niocount, struct niobuf_local *res,
                                 struct obd_trans_info *oti)
 {
         struct obd_ioobj *o;
@@ -627,144 +372,47 @@ static int filter_commitrw_read(struct obd_export *exp, int objcount,
         RETURN(0);
 }
 
-static int
-filter_commitrw_write(int cmd, struct obd_export *exp, struct obdo *oa,
-                      int objcount, struct obd_ioobj *obj, int niocount,
-                      struct niobuf_local *res, struct obd_trans_info *oti)
+void flip_into_page_cache(struct inode *inode, struct page *new_page)
 {
-        struct obd_run_ctxt saved;
-        struct obd_ioobj *o;
-        struct niobuf_local *lnb;
-        struct obd_device *obd = exp->exp_obd;
-        int found_locked = 0, rc = 0, i;
-        unsigned long now = jiffies;  /* DEBUGGING OST TIMEOUTS */
-        ENTRY;
-
-        push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL);
-
-        LASSERT(current->journal_info == NULL);
-        if (cmd & OBD_BRW_WRITE) {
-                LASSERT(oti != NULL);
-                LASSERT(oti->oti_handle != NULL);
-                current->journal_info = oti->oti_handle;
-        }
-
-        for (i = 0, o = obj, lnb = res; i < objcount; i++, o++) {
-                struct inode *inode;
-                int j;
-
-                /* If all of the page reads were beyond EOF, let's pretend
-                 * this read didn't really happen at all. */
-                if (lnb->dentry == NULL) {
-                        oa->o_valid = OBD_MD_FLID|(oa->o_valid&OBD_MD_FLCKSUM);
-                        continue;
-                }
-
-                inode = igrab(lnb->dentry->d_inode);
-
-                if (cmd & OBD_BRW_WRITE) {
-                        /* FIXME: MULTI OBJECT BRW */
-                        if (oa && oa->o_valid & (OBD_MD_FLMTIME|OBD_MD_FLCTIME))
-                                obdo_refresh_inode(inode, oa, OBD_MD_FLATIME |
-                                                   OBD_MD_FLMTIME |
-                                                   OBD_MD_FLCTIME);
-                        else
-                                inode_update_time(lnb->dentry->d_inode, 1);
-                } else if (oa && oa->o_valid & OBD_MD_FLATIME) {
-                        /* Note that we don't necessarily write this to disk */
-                        obdo_refresh_inode(inode, oa, OBD_MD_FLATIME);
-                }
-
-                for (j = 0 ; j < o->ioo_bufcnt ; j++, lnb++) {
-                        if (lnb->page == NULL) {
-                                continue;
-                        }
-
-                        if (lnb->flags & N_LOCAL_TEMP_PAGE) {
-                                found_locked++;
-                                continue;
-                        }
-
-                        if (time_after(jiffies, lnb->start + 15 * HZ))
-                                CERROR("slow commitrw %lusi (%lus)\n",
-                                       (jiffies - lnb->start) / HZ,
-                                       (jiffies - now) / HZ);
-
-                        if (cmd & OBD_BRW_WRITE) {
-                                int err = filter_commit_write(lnb, 0);
-
-                                if (!rc)
-                                        rc = err;
-                        } else {
-                                page_cache_release(lnb->page);
-                        }
+        struct page *old_page;
+        int rc;
 
-                        f_dput(lnb->dentry);
-                        if (time_after(jiffies, lnb->start + 15 * HZ))
-                                CERROR("slow commit_write %lus (%lus)\n",
-                                       (jiffies - lnb->start) / HZ,
-                                       (jiffies - now) / HZ);
+        do {
+                /* the dlm is protecting us from read/write concurrency, so we
+                 * expect this find_lock_page to return quickly.  even if we
+                 * race with another writer it won't be doing much work with
+                 * the page locked.  we do this 'cause t_c_p expects a 
+                 * locked page, and it wants to grab the pagecache lock
+                 * as well. */
+                old_page = find_lock_page(inode->i_mapping, new_page->index);
+                if (old_page) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                        truncate_complete_page(old_page);
+#else
+                        truncate_complete_page(old_page->mapping, old_page);
+#endif
+                        unlock_page(old_page);
+                        page_cache_release(old_page);
                 }
 
-                /* FIXME: MULTI OBJECT BRW */
-                if (oa) {
-                        oa->o_valid = OBD_MD_FLID|(oa->o_valid&OBD_MD_FLCKSUM);
-                        obdo_from_inode(oa, inode, FILTER_VALID_FLAGS);
+#if 0 /* this should be a /proc tunable someday */
+                /* racing o_directs (no locking ioctl) could race adding
+                 * their pages, so we repeat the page invalidation unless
+                 * we successfully added our new page */
+                rc = add_to_page_cache_unique(new_page, inode->i_mapping, 
+                                              new_page->index,
+                                              page_hash(inode->i_mapping, 
+                                                        new_page->index));
+                if (rc == 0) {
+                        /* add_to_page_cache clears uptodate|dirty and locks
+                         * the page */
+                        SetPageUptodate(new_page);
+                        unlock_page(new_page);
                 }
-
-                if (cmd & OBD_BRW_WRITE)
-                        up(&inode->i_sem);
-
-                iput(inode);
-        }
-
-        for (i = 0, o = obj, lnb = res; found_locked > 0 && i < objcount;
-             i++, o++) {
-                int j;
-
-                for (j = 0 ; j < o->ioo_bufcnt ; j++, lnb++) {
-                        int err;
-                        if (!(lnb->flags & N_LOCAL_TEMP_PAGE))
-                                continue;
-
-                        if (time_after(jiffies, lnb->start + 15 * HZ))
-                                CERROR("slow commitrw locked %lus (%lus)\n",
-                                       (jiffies - lnb->start) / HZ,
-                                       (jiffies - now) / HZ);
-
-                        err = filter_write_locked_page(lnb);
-                        if (!rc)
-                                rc = err;
-                        f_dput(lnb->dentry);
-                        found_locked--;
-
-                        if (time_after(jiffies, lnb->start + 15 * HZ))
-                                CERROR("slow commit_write locked %lus (%lus)\n",
-                                       (jiffies - lnb->start) / HZ,
-                                       (jiffies - now) / HZ);
-                }
-        }
-
-        if (cmd & OBD_BRW_WRITE) {
-                /* We just want any dentry for the commit, for now */
-                struct dentry *dparent = filter_parent(obd, S_IFREG, 0);
-                int err;
-
-                rc = filter_finish_transno(exp, oti, rc);
-                err = fsfilt_commit(obd, dparent->d_inode, oti->oti_handle,
-                                    obd_sync_filter);
-                LASSERT(current->journal_info == NULL);
-                oti->oti_handle = NULL;
-                if (err)
-                        rc = err;
-                if (obd_sync_filter)
-                        LASSERT(oti->oti_transno <= obd->obd_last_committed);
-                if (time_after(jiffies, now + 15 * HZ))
-                        CERROR("slow commitrw commit %lus\n", (jiffies-now)/HZ);
-        }
-
-        pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL);
-        RETURN(rc);
+#else   
+                rc = 0;
+#endif
+        } while (rc != 0);
 }
 
 /* XXX needs to trickle its oa down */
@@ -773,20 +421,19 @@ int filter_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
                     struct niobuf_local *res, struct obd_trans_info *oti)
 {
         if (cmd == OBD_BRW_WRITE)
-                return filter_commitrw_write(cmd, exp, oa, objcount, obj,
-                                             niocount, res, oti);
+                return filter_commitrw_write(exp, oa, objcount, obj, niocount,
+                                             res, oti);
         if (cmd == OBD_BRW_READ)
-                return filter_commitrw_read(exp, objcount, obj, niocount,
+                return filter_commitrw_read(exp, oa, objcount, obj, niocount,
                                             res, oti);
         LBUG();
         return -EPROTO;
 }
 
-int filter_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
+int filter_brw(int cmd, struct obd_export *exp, struct obdo *oa,
                struct lov_stripe_md *lsm, obd_count oa_bufs,
                struct brw_page *pga, struct obd_trans_info *oti)
 {
-        struct obd_export *exp;
         struct obd_ioobj ioo;
         struct niobuf_local *lnb;
         struct niobuf_remote *rnb;
@@ -794,12 +441,6 @@ int filter_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
         int ret = 0;
         ENTRY;
 
-        exp = class_conn2export(conn);
-        if (exp == NULL) {
-                CDEBUG(D_IOCTL, "invalid client cookie "LPX64"\n",conn->cookie);
-                RETURN(-EINVAL);
-        }
-
         OBD_ALLOC(lnb, oa_bufs * sizeof(struct niobuf_local));
         OBD_ALLOC(rnb, oa_bufs * sizeof(struct niobuf_remote));
 
@@ -811,9 +452,7 @@ int filter_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 rnb[i].len = pga[i].count;
         }
 
-        ioo.ioo_id = oa->o_id;
-        ioo.ioo_gr = 0;
-        ioo.ioo_type = oa->o_mode & S_IFMT;
+        obdo_to_ioobj(oa, &ioo);
         ioo.ioo_bufcnt = oa_bufs;
 
         ret = filter_preprw(cmd, exp, oa, 1, &ioo, oa_bufs, rnb, lnb, oti);
@@ -832,8 +471,8 @@ int filter_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 else
                         memcpy(virt + off, addr + off, pga[i].count);
 
-                kunmap(addr);
-                kunmap(virt);
+                kunmap(lnb[i].page);
+                kunmap(pga[i].pg);
         }
 
         ret = filter_commitrw(cmd, exp, oa, 1, &ioo, oa_bufs, lnb, oti);
@@ -843,6 +482,5 @@ out:
                 OBD_FREE(lnb, oa_bufs * sizeof(struct niobuf_local));
         if (rnb)
                 OBD_FREE(rnb, oa_bufs * sizeof(struct niobuf_remote));
-        class_export_put(exp);
         RETURN(ret);
 }
diff --git a/lustre/obdfilter/filter_io_24.c b/lustre/obdfilter/filter_io_24.c
new file mode 100644
index 0000000000000000000000000000000000000000..5795cebb831163ea6d94b82b3b7ca0e0c857248a
--- /dev/null
+++ b/lustre/obdfilter/filter_io_24.c
@@ -0,0 +1,299 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  linux/fs/obdfilter/filter_io.c
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pagemap.h> // XXX kill me soon
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/iobuf.h>
+#include <linux/locks.h>
+
+#include <linux/obd_class.h>
+#include <linux/lustre_fsfilt.h>
+#include "filter_internal.h"
+
+
+/* We should only change the file mtime (and not the ctime, like
+ * update_inode_times() in generic_file_write()) when we only change data. */
+void inode_update_time(struct inode *inode, int ctime_too)
+{
+        time_t now = CURRENT_TIME;
+        if (inode->i_mtime == now && (!ctime_too || inode->i_ctime == now))
+                return;
+        inode->i_mtime = now;
+        if (ctime_too)
+                inode->i_ctime = now;
+        mark_inode_dirty_sync(inode);
+}
+
+/* Bug 2254 -- this is better done in ext3_map_inode_page, but this
+ * workaround will suffice until everyone has upgraded their kernels */
+static void check_pending_bhs(unsigned long *blocks, int nr_pages, dev_t dev,
+                              int size)
+{
+#if (LUSTRE_KERNEL_VERSION < 32)
+        struct buffer_head *bh;
+        int i;
+
+        for (i = 0; i < nr_pages; i++) {
+                bh = get_hash_table(dev, blocks[i], size);
+                if (bh == NULL)
+                        continue;
+                if (!buffer_dirty(bh)) {
+                        put_bh(bh);
+                        continue;
+                }
+                mark_buffer_clean(bh);
+                wait_on_buffer(bh);
+                clear_bit(BH_Req, &bh->b_state);
+                __brelse(bh);
+        }
+#endif
+}
+
+/* Must be called with i_sem taken; this will drop it */
+static int filter_direct_io(int rw, struct dentry *dchild, struct kiobuf *iobuf,
+                            struct obd_export *exp, struct iattr *attr,
+                            struct obd_trans_info *oti, void **wait_handle)
+{
+        struct obd_device *obd = exp->exp_obd;
+        struct inode *inode = dchild->d_inode;
+        struct page *page;
+        unsigned long *b = iobuf->blocks;
+        int rc, i, create = (rw == OBD_BRW_WRITE), blocks_per_page;
+        int *cr, cleanup_phase = 0, *created = NULL;
+        int committed = 0;
+        ENTRY;
+
+        blocks_per_page = PAGE_SIZE >> inode->i_blkbits;
+        if (iobuf->nr_pages * blocks_per_page > KIO_MAX_SECTORS)
+                GOTO(cleanup, rc = -EINVAL);
+
+        OBD_ALLOC(created, sizeof(*created) * iobuf->nr_pages*blocks_per_page);
+        if (created == NULL)
+                GOTO(cleanup, rc = -ENOMEM);
+        cleanup_phase = 1;
+
+        rc = lock_kiovec(1, &iobuf, 1);
+        if (rc < 0)
+                GOTO(cleanup, rc);
+        cleanup_phase = 2;
+
+        down(&exp->exp_obd->u.filter.fo_alloc_lock);
+        for (i = 0, cr = created, b = iobuf->blocks; i < iobuf->nr_pages; i++){
+                page = iobuf->maplist[i];
+
+                rc = fsfilt_map_inode_page(obd, inode, page, b, cr, create);
+                if (rc) {
+                        CERROR("ino %lu, blk %lu cr %u create %d: rc %d\n",
+                               inode->i_ino, *b, *cr, create, rc);
+                        up(&exp->exp_obd->u.filter.fo_alloc_lock);
+                        GOTO(cleanup, rc);
+                }
+
+                b += blocks_per_page;
+                cr += blocks_per_page;
+        }
+        up(&exp->exp_obd->u.filter.fo_alloc_lock);
+
+        if (attr->ia_size > inode->i_size)
+                attr->ia_valid |= ATTR_SIZE;
+        rc = fsfilt_setattr(obd, dchild, oti->oti_handle, attr, 0);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        up(&inode->i_sem);
+        cleanup_phase = 3;
+
+        rc = filter_finish_transno(exp, oti, 0);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        rc = fsfilt_commit_async(obd, inode, oti->oti_handle, wait_handle);
+        oti->oti_handle = NULL;
+        committed = 1;
+        if (rc)
+                GOTO(cleanup, rc);
+
+        check_pending_bhs(iobuf->blocks, iobuf->nr_pages, inode->i_dev,
+                          1 << inode->i_blkbits);
+
+        rc = brw_kiovec(WRITE, 1, &iobuf, inode->i_dev, iobuf->blocks,
+                        1 << inode->i_blkbits);
+        CDEBUG(D_INFO, "tried to write %d pages, rc = %d\n",
+               iobuf->nr_pages, rc);
+        if (rc != (1 << inode->i_blkbits) * iobuf->nr_pages * blocks_per_page)
+                CERROR("short write?  expected %d, wrote %d\n",
+                       (1 << inode->i_blkbits) * iobuf->nr_pages *
+                       blocks_per_page, rc);
+        if (rc > 0)
+                rc = 0;
+
+        EXIT;
+cleanup:
+        if (!committed) {
+                int err = fsfilt_commit_async(obd, inode,
+                                              oti->oti_handle, wait_handle);
+                oti->oti_handle = NULL;
+                if (err)
+                        CERROR("can't close transaction: %d\n", err);
+                /*
+                 * this is error path, so we prefer to return
+                 * original error, not this one
+                 */
+        }
+
+        switch(cleanup_phase) {
+        case 3:
+        case 2:
+                unlock_kiovec(1, &iobuf);
+        case 1:
+                OBD_FREE(created, sizeof(*created) *
+                         iobuf->nr_pages*blocks_per_page);
+        case 0:
+                if (cleanup_phase == 3)
+                        break;
+                up(&inode->i_sem);
+                break;
+        default:
+                CERROR("corrupt cleanup_phase (%d)?\n", cleanup_phase);
+                LBUG();
+                break;
+        }
+        return rc;
+}
+
+int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
+                          struct obd_ioobj *obj, int niocount,
+                          struct niobuf_local *res, struct obd_trans_info *oti)
+{
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_run_ctxt saved;
+        struct niobuf_local *lnb;
+        struct fsfilt_objinfo fso;
+        struct iattr iattr = { 0 };
+        struct kiobuf *iobuf;
+        struct inode *inode = NULL;
+        int rc = 0, i, cleanup_phase = 0, err;
+        unsigned long now = jiffies; /* DEBUGGING OST TIMEOUTS */
+        void *wait_handle;
+        ENTRY;
+        LASSERT(oti != NULL);
+        LASSERT(objcount == 1);
+        LASSERT(current->journal_info == NULL);
+
+        rc = alloc_kiovec(1, &iobuf);
+        if (rc)
+                GOTO(cleanup, rc);
+        cleanup_phase = 1;
+
+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,4,18))
+        iobuf->dovary = 0; /* this prevents corruption, not present in 2.4.20 */
+#endif
+        rc = expand_kiobuf(iobuf, obj->ioo_bufcnt);
+        if (rc)
+                GOTO(cleanup, rc);
+
+        iobuf->offset = 0;
+        iobuf->length = PAGE_SIZE * obj->ioo_bufcnt;
+        iobuf->nr_pages = obj->ioo_bufcnt;
+
+        cleanup_phase = 1;
+        fso.fso_dentry = res->dentry;
+        fso.fso_bufcnt = obj->ioo_bufcnt;
+        inode = res->dentry->d_inode;
+
+        iattr_from_obdo(&iattr,oa,OBD_MD_FLATIME|OBD_MD_FLMTIME|OBD_MD_FLCTIME);
+        for (i = 0, lnb = res; i < obj->ioo_bufcnt; i++, lnb++) {
+                loff_t this_size;
+                iobuf->maplist[i] = lnb->page;
+                /* We expect these pages to be in offset order, but we'll
+                 * be forgiving */
+                this_size = lnb->offset + lnb->len;
+                if (this_size > iattr.ia_size)
+                        iattr.ia_size = this_size;
+        }
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        cleanup_phase = 2;
+
+        down(&inode->i_sem);
+        oti->oti_handle = fsfilt_brw_start(obd, objcount, &fso, niocount, oti);
+        if (IS_ERR(oti->oti_handle)) {
+                rc = PTR_ERR(oti->oti_handle);
+                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
+                       "error starting transaction: rc = %d\n", rc);
+                oti->oti_handle = NULL;
+                GOTO(cleanup, rc);
+        }
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow brw_start %lus\n", (jiffies - now) / HZ);
+
+        rc = filter_direct_io(OBD_BRW_WRITE, res->dentry, iobuf, exp, &iattr,
+                              oti, &wait_handle);
+        if (rc == 0)
+                obdo_from_inode(oa, inode, FILTER_VALID_FLAGS);
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow direct_io %lus\n", (jiffies - now) / HZ);
+
+        err = fsfilt_commit_wait(obd, inode, wait_handle);
+        if (err)
+                rc = err;
+        if (obd_sync_filter)
+                LASSERT(oti->oti_transno <= obd->obd_last_committed);
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow commitrw commit %lus\n", (jiffies - now) / HZ);
+
+cleanup:
+        switch (cleanup_phase) {
+        case 2:
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                LASSERT(current->journal_info == NULL);
+        case 1:
+                free_kiovec(1, &iobuf);
+        case 0:
+                for (i = 0, lnb = res; i < obj->ioo_bufcnt; i++, lnb++) {
+                        /* flip_.. gets a ref, while free_page only frees
+                         * when it decrefs to 0 */
+                        if (rc == 0)
+                                flip_into_page_cache(inode, lnb->page);
+                        __free_page(lnb->page);
+                }
+                f_dput(res->dentry);
+        }
+
+        RETURN(rc);
+}
+
+#endif
+
diff --git a/lustre/obdfilter/filter_io_26.c b/lustre/obdfilter/filter_io_26.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc0007fce4fa76f725fbcc2639dc16cc7cb516b3
--- /dev/null
+++ b/lustre/obdfilter/filter_io_26.c
@@ -0,0 +1,229 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  linux/fs/obdfilter/filter_io.c
+ *
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Peter Braam <braam@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pagemap.h> // XXX kill me soon
+#include <linux/version.h>
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/obd_class.h>
+#include <linux/lustre_fsfilt.h>
+#include "filter_internal.h"
+
+#warning "implement writeback mode -bzzz"
+
+int ext3_map_inode_page(struct inode *inode, struct page *page,
+                        unsigned long *blocks, int *created, int create);
+
+/* 512byte block min */
+#define MAX_BLOCKS_PER_PAGE (PAGE_SIZE / 512)
+struct dio_request {
+        atomic_t numreqs;       /* number of reqs being processed */
+        struct bio *bio_list;   /* list of completed bios */
+        wait_queue_head_t wait;
+	int created[MAX_BLOCKS_PER_PAGE];
+	unsigned long blocks[MAX_BLOCKS_PER_PAGE];
+        spinlock_t lock;
+};
+
+static int dio_complete_routine(struct bio *bio, unsigned int done, int error)
+{
+        struct dio_request *dreq = bio->bi_private;
+        unsigned long flags;
+
+        spin_lock_irqsave(&dreq->lock, flags);
+        bio->bi_private = dreq->bio_list;
+        dreq->bio_list = bio;
+        spin_unlock_irqrestore(&dreq->lock, flags);
+        if (atomic_dec_and_test(&dreq->numreqs))
+                wake_up(&dreq->wait);
+
+        return 0;
+}
+
+static int can_be_merged(struct bio *bio, sector_t sector)
+{
+	int size;
+	
+	if (!bio)
+		return 0;
+	
+	size = bio->bi_size >> 9;
+	return bio->bi_sector + size == sector ? 1 : 0;
+}
+
+int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
+                          struct obd_ioobj *obj, int niocount,
+                          struct niobuf_local *res, struct obd_trans_info *oti)
+{
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_run_ctxt saved;
+        struct niobuf_local *lnb;
+        struct fsfilt_objinfo fso;
+        struct iattr iattr = { .ia_valid = ATTR_SIZE, .ia_size = 0, };
+        struct inode *inode = NULL;
+        int rc = 0, i, k, cleanup_phase = 0, err;
+        unsigned long now = jiffies; /* DEBUGGING OST TIMEOUTS */
+	int blocks_per_page;
+        struct dio_request *dreq;
+        struct bio *bio = NULL;
+        ENTRY;
+        LASSERT(oti != NULL);
+        LASSERT(objcount == 1);
+        LASSERT(current->journal_info == NULL);
+
+        inode = res->dentry->d_inode;
+        blocks_per_page = PAGE_SIZE >> inode->i_blkbits;
+	LASSERT(blocks_per_page <= MAX_BLOCKS_PER_PAGE);
+
+        OBD_ALLOC(dreq, sizeof(*dreq));
+        if (dreq == NULL)
+                RETURN(-ENOMEM);
+        dreq->bio_list = NULL;
+        init_waitqueue_head(&dreq->wait);
+        atomic_set(&dreq->numreqs, 0);
+        spin_lock_init(&dreq->lock);
+
+        cleanup_phase = 1;
+        fso.fso_dentry = res->dentry;
+        fso.fso_bufcnt = obj->ioo_bufcnt;
+
+        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        cleanup_phase = 2; 
+
+        oti->oti_handle = fsfilt_brw_start(obd, objcount, &fso, niocount, oti);
+        if (IS_ERR(oti->oti_handle)) {
+                rc = PTR_ERR(oti->oti_handle);
+                CDEBUG(rc == -ENOSPC ? D_INODE : D_ERROR,
+                       "error starting transaction: rc = %d\n", rc);
+                oti->oti_handle = NULL;
+                GOTO(cleanup, rc);
+        }
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow brw_start %lus\n", (jiffies - now) / HZ);
+
+        for (i = 0, lnb = res; i < obj->ioo_bufcnt; i++, lnb++) {
+                loff_t this_size;
+		sector_t sector;
+		int offs;
+
+		/* get block number for next page */
+                rc = ext3_map_inode_page(inode, lnb->page, dreq->blocks,
+                                                dreq->created, 1);
+                if (rc)
+                        GOTO(cleanup, rc);
+
+		for (k = 0; k < blocks_per_page; k++) {
+			sector = dreq->blocks[k] * (inode->i_sb->s_blocksize >> 9);
+			offs = k * inode->i_sb->s_blocksize;
+
+			if (!bio || !can_be_merged(bio, sector) ||
+				!bio_add_page(bio, lnb->page, lnb->len, offs)) {
+				if (bio) {
+                                        atomic_inc(&dreq->numreqs);
+					submit_bio(WRITE, bio);
+					bio = NULL;
+				}
+				/* allocate new bio */
+				bio = bio_alloc(GFP_NOIO, obj->ioo_bufcnt);
+				bio->bi_bdev = inode->i_sb->s_bdev;
+				bio->bi_sector = sector;
+				bio->bi_end_io = dio_complete_routine; 
+                                bio->bi_private = dreq;
+
+				if (!bio_add_page(bio, lnb->page, lnb->len, 0))
+					LBUG();
+			}
+		}
+
+                /* We expect these pages to be in offset order, but we'll
+                 * be forgiving */
+                this_size = lnb->offset + lnb->len;
+                if (this_size > iattr.ia_size)
+                        iattr.ia_size = this_size;
+        }
+	if (bio) {
+                atomic_inc(&dreq->numreqs);
+                submit_bio(WRITE, bio);
+        }
+
+	/* time to wait for I/O completion */
+        wait_event(dreq->wait, atomic_read(&dreq->numreqs) == 0);
+
+        /* free all bios */
+        while (dreq->bio_list) {
+                bio = dreq->bio_list;
+                dreq->bio_list = bio->bi_private;
+                bio_put(bio);
+        }
+
+        if (rc == 0) {
+                down(&inode->i_sem);
+                inode_update_time(inode, 1);
+                if (iattr.ia_size > inode->i_size) {
+                        CDEBUG(D_INFO, "setting i_size to "LPU64"\n",
+                               iattr.ia_size);
+                        fsfilt_setattr(obd, res->dentry, oti->oti_handle,
+                                       &iattr, 0);
+                }
+                up(&inode->i_sem);
+        }
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow direct_io %lus\n", (jiffies - now) / HZ);
+
+        rc = filter_finish_transno(exp, oti, rc);
+        err = fsfilt_commit(obd, inode, oti->oti_handle, obd_sync_filter);
+        if (err)
+                rc = err;
+        if (obd_sync_filter)
+                LASSERT(oti->oti_transno <= obd->obd_last_committed);
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("slow commitrw commit %lus\n", (jiffies - now) / HZ);
+
+cleanup:
+        switch (cleanup_phase) {
+        case 2:
+                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                LASSERT(current->journal_info == NULL);
+        case 1:
+                OBD_FREE(dreq, sizeof(*dreq));
+        case 0:
+                for (i = 0, lnb = res; i < obj->ioo_bufcnt; i++, lnb++) {
+                        /* flip_.. gets a ref, while free_page only frees
+                         * when it decrefs to 0 */
+                        if (rc == 0)
+                                flip_into_page_cache(inode, lnb->page);
+                        __free_page(lnb->page);
+                }
+                f_dput(res->dentry);
+        }
+
+        RETURN(rc);
+}
diff --git a/lustre/obdfilter/filter_log.c b/lustre/obdfilter/filter_log.c
index d91e1e853a3ce782143036df41e224ce39bd19f9..b63c4c25445eba672433952043ef0acf29276d85 100644
--- a/lustre/obdfilter/filter_log.c
+++ b/lustre/obdfilter/filter_log.c
@@ -37,344 +37,123 @@
 
 #include "filter_internal.h"
 
-static struct llog_handle *filter_log_create(struct obd_device *obd);
-
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-static int filter_log_close(struct llog_handle *cathandle,
-                            struct llog_handle *loghandle)
+int filter_log_sz_change(struct llog_handle *cathandle, 
+                         struct ll_fid *mds_fid,
+                         __u32 io_epoch,
+                         struct llog_cookie *logcookie, 
+                         struct inode *inode)
 {
-        struct llog_object_hdr *llh = loghandle->lgh_hdr;
-        struct file *file = loghandle->lgh_file;
-        struct dentry *dparent = NULL, *dchild = NULL;
-        struct lustre_handle parent_lockh;
-        struct llog_logid *lgl = &loghandle->lgh_cookie.lgc_lgl;
+        struct llog_size_change_rec *lsc;
         int rc;
+        struct ost_filterdata *ofd;
         ENTRY;
 
-        /* If we are going to delete this log, grab a ref before we close
-         * it so we don't have to immediately do another lookup. */
-        if (llh->llh_hdr.lth_type != LLOG_CATALOG_MAGIC && llh->llh_count == 0){
-                CDEBUG(D_INODE, "deleting log file "LPX64":%x\n",
-                       lgl->lgl_oid, lgl->lgl_ogen);
-                dparent = filter_parent_lock(loghandle->lgh_obd, S_IFREG,
-                                             lgl->lgl_oid,LCK_PW,&parent_lockh);
-                if (IS_ERR(dparent)) {
-                        rc = PTR_ERR(dparent);
-                        CERROR("error locking parent, orphan log %*s: rc %d\n",
-                               file->f_dentry->d_name.len,
-                               file->f_dentry->d_name.name, rc);
-                        RETURN(rc);
-                } else {
-                        dchild = dget(file->f_dentry);
-                        llog_delete_log(cathandle, loghandle);
-                }
-        } else {
-                CDEBUG(D_INODE, "closing log file "LPX64":%x\n",
-                       lgl->lgl_oid, lgl->lgl_ogen);
+        down(&inode->i_sem);
+        ofd = inode->i_filterdata;
+        
+        if (ofd && ofd->ofd_epoch >= io_epoch) {
+                if (ofd->ofd_epoch > io_epoch)
+                        CERROR("client sent old epoch %d for obj ino %ld\n", 
+                               io_epoch, inode->i_ino);
+                up(&inode->i_sem);
+                RETURN(0);
         }
 
-        rc = filp_close(file, 0);
-
-        llog_free_handle(loghandle); /* also removes loghandle from list */
-
-        if (dchild != NULL) {
-                int err = vfs_unlink(dparent->d_inode, dchild);
-                if (err) {
-                        CERROR("error unlinking empty log %*s: rc %d\n",
-                               dchild->d_name.len, dchild->d_name.name, err);
-                        if (!rc)
-                                rc = err;
-                }
-                f_dput(dchild);
-                ldlm_lock_decref(&parent_lockh, LCK_PW);
+        if (ofd && ofd->ofd_epoch < io_epoch) {
+                ofd->ofd_epoch = io_epoch;
+        } else if (!ofd) {
+                OBD_ALLOC(ofd, sizeof(*ofd));
+                if (!ofd)
+                        GOTO(out, rc = -ENOMEM);
+                igrab(inode);
+                inode->i_filterdata = ofd;
+                ofd->ofd_epoch = io_epoch;
         }
-        RETURN(rc);
-}
-
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-static struct llog_handle *filter_log_open(struct obd_device *obd,
-                                           struct llog_cookie *logcookie)
-{
-        struct llog_logid *lgl = &logcookie->lgc_lgl;
-        struct llog_handle *loghandle;
-        struct dentry *dchild;
-        int rc;
-        ENTRY;
-
-        loghandle = llog_alloc_handle();
-        if (!loghandle)
-                RETURN(ERR_PTR(-ENOMEM));
-
-        dchild = filter_fid2dentry(obd, NULL, S_IFREG, lgl->lgl_oid);
-        if (IS_ERR(dchild))
-                GOTO(out_handle, rc = PTR_ERR(dchild));
+        /* the decision to write a record is now made, unlock */
+        up(&inode->i_sem);
 
-        if (dchild->d_inode == NULL) {
-                CERROR("logcookie references non-existent object %*s\n",
-                       dchild->d_name.len, dchild->d_name.name);
-                GOTO(out_dentry, rc = -ENOENT);
-        }
+        OBD_ALLOC(lsc, sizeof(*lsc));
+        if (lsc == NULL)
+                RETURN(-ENOMEM);
+        lsc->lsc_hdr.lrh_len = lsc->lsc_tail.lrt_len = sizeof(*lsc);
+        lsc->lsc_hdr.lrh_type =  OST_SZ_REC;
+        lsc->lsc_fid = *mds_fid;
+        lsc->lsc_io_epoch = io_epoch;
 
-        if (dchild->d_inode->i_generation != lgl->lgl_ogen) {
-                CERROR("logcookie for %*s had different generation %x != %x\n",
-                       dchild->d_name.len, dchild->d_name.name,
-                       dchild->d_inode->i_generation, lgl->lgl_ogen);
-                GOTO(out_dentry, rc = -ESTALE);
-        }
+        rc = llog_cat_add_rec(cathandle, &lsc->lsc_hdr, logcookie, NULL);
+        OBD_FREE(lsc, sizeof(*lsc));
 
-        /* dentry_open does a dput(dchild) and mntput(mnt) on error */
-        mntget(obd->u.filter.fo_vfsmnt);
-        loghandle->lgh_file = dentry_open(dchild, obd->u.filter.fo_vfsmnt,
-                                          O_RDWR);
-        if (IS_ERR(loghandle->lgh_file)) {
-                rc = PTR_ERR(loghandle->lgh_file);
-                CERROR("error opening logfile %*s: rc %d\n",
-                       dchild->d_name.len, dchild->d_name.name, rc);
-                GOTO(out_dentry, rc);
+        if (rc > 0) {
+                LASSERT(rc == sizeof(*logcookie));
+                rc = 0;
         }
-        memcpy(&loghandle->lgh_cookie, logcookie, sizeof(*logcookie));
-        loghandle->lgh_log_create = filter_log_create;
-        loghandle->lgh_log_open = filter_log_open;
-        loghandle->lgh_log_close = filter_log_close;
-        loghandle->lgh_obd = obd;
-        RETURN(loghandle);
 
-out_dentry:
-        f_dput(dchild);
-out_handle:
-        llog_free_handle(loghandle);
-        RETURN(ERR_PTR(rc));
+        out:
+        RETURN(rc);
 }
 
-/* This is a callback from the llog_* functions.
- * Assumes caller has already pushed us into the kernel context. */
-static struct llog_handle *filter_log_create(struct obd_device *obd)
+/* When this (destroy) operation is committed, return the cancel cookie */
+void filter_cancel_cookies_cb(struct obd_device *obd, __u64 transno,
+                                     void *cb_data, int error)
 {
-        struct filter_obd *filter = &obd->u.filter;
-        struct lustre_handle parent_lockh;
-        struct dentry *dparent, *dchild;
-        struct llog_handle *loghandle;
-        struct file *file;
-        int err, rc;
-        obd_id id;
-        ENTRY;
-
-        loghandle = llog_alloc_handle();
-        if (!loghandle)
-                RETURN(ERR_PTR(-ENOMEM));
-
- retry:
-        id = filter_next_id(filter);
-
-        dparent = filter_parent_lock(obd, S_IFREG, id, LCK_PW, &parent_lockh);
-        if (IS_ERR(dparent))
-                GOTO(out_ctxt, rc = PTR_ERR(dparent));
-
-        dchild = filter_fid2dentry(obd, dparent, S_IFREG, id);
-        if (IS_ERR(dchild))
-                GOTO(out_lock, rc = PTR_ERR(dchild));
-
-        if (dchild->d_inode != NULL) {
-                /* This would only happen if lastobjid was bad on disk */
-                CERROR("Serious error: objid %*s already exists; is this "
-                       "filesystem corrupt?  I will try to work around it.\n",
-                       dchild->d_name.len, dchild->d_name.name);
-                f_dput(dchild);
-                ldlm_lock_decref(&parent_lockh, LCK_PW);
-                goto retry;
-        }
-
-        rc = vfs_create(dparent->d_inode, dchild, S_IFREG);
-        if (rc) {
-                CERROR("log create failed rc = %d\n", rc);
-                GOTO(out_child, rc);
-        }
-
-        rc = filter_update_server_data(obd, filter->fo_rcvd_filp,
-                                       filter->fo_fsd);
-        if (rc) {
-                CERROR("can't write lastobjid but log created: rc %d\n",rc);
-                GOTO(out_destroy, rc);
-        }
-
-        /* dentry_open does a dput(dchild) and mntput(mnt) on error */
-        mntget(filter->fo_vfsmnt);
-        file = dentry_open(dchild, filter->fo_vfsmnt, O_RDWR | O_LARGEFILE);
-        if (IS_ERR(file)) {
-                rc = PTR_ERR(file);
-                CERROR("error opening log file "LPX64": rc %d\n", id, rc);
-                GOTO(out_destroy, rc);
-        }
-        ldlm_lock_decref(&parent_lockh, LCK_PW);
-
-        loghandle->lgh_file = file;
-        loghandle->lgh_cookie.lgc_lgl.lgl_oid = id;
-        loghandle->lgh_cookie.lgc_lgl.lgl_ogen = dchild->d_inode->i_generation;
-        loghandle->lgh_log_create = filter_log_create;
-        loghandle->lgh_log_open = filter_log_open;
-        loghandle->lgh_log_close = filter_log_close;
-        loghandle->lgh_obd = obd;
-
-        RETURN(loghandle);
-
-out_destroy:
-        err = vfs_unlink(dparent->d_inode, dchild);
-        if (err)
-                CERROR("error unlinking %*s on error: rc %d\n",
-                       dchild->d_name.len, dchild->d_name.name, err);
-out_child:
-        f_dput(dchild);
-out_lock:
-        ldlm_lock_decref(&parent_lockh, LCK_PW);
-out_ctxt:
-        llog_free_handle(loghandle);
-        RETURN(ERR_PTR(rc));
+        struct llog_cookie *cookie = cb_data;
+        llog_cancel(llog_get_context(obd, cookie->lgc_subsys + 1),
+                             NULL, 1, cookie, 0);
+                             //NULL, 1, cookie, OBD_LLOG_FL_SENDNOW);
+        OBD_FREE(cb_data, sizeof(struct llog_cookie));
 }
 
-/* This is called from filter_setup() and should be single threaded */
-struct llog_handle *filter_get_catalog(struct obd_device *obd)
+/* Callback for processing the unlink log record received from MDS by 
+ * llog_client_api.
+ */
+int filter_recov_log_unlink_cb(struct llog_handle *llh, 
+                               struct llog_rec_hdr *rec, void *data)
 {
-        struct filter_obd *filter = &obd->u.filter;
-        struct filter_server_data *fsd = filter->fo_fsd;
-        struct obd_run_ctxt saved;
-        struct llog_handle *cathandle = NULL;
-        int rc;
+        struct llog_ctxt *ctxt = llh->lgh_ctxt;
+        struct obd_device *obd = ctxt->loc_obd;
+        struct obd_export *exp = obd->obd_self_export;
+        struct llog_cookie cookie;
+        struct llog_unlink_rec *lur;
+        struct obdo *oa;
+        struct obd_trans_info oti = { 0 };
+        obd_id oid;
+        int rc = 0;
         ENTRY;
-
-        push_ctxt(&saved, &filter->fo_ctxt, NULL);
-        if (fsd->fsd_catalog_oid) {
-                struct llog_cookie catcookie;
-
-                catcookie.lgc_lgl.lgl_oid = le64_to_cpu(fsd->fsd_catalog_oid);
-                catcookie.lgc_lgl.lgl_ogen = le32_to_cpu(fsd->fsd_catalog_ogen);
-                cathandle = filter_log_open(obd, &catcookie);
-                if (IS_ERR(cathandle)) {
-                        CERROR("error opening catalog "LPX64":%x: rc %d\n",
-                               catcookie.lgc_lgl.lgl_oid,
-                               catcookie.lgc_lgl.lgl_ogen,
-                               (int)PTR_ERR(cathandle));
-                        fsd->fsd_catalog_oid = 0;
-                        fsd->fsd_catalog_ogen = 0;
-                }
+                                                                                                                             
+        if (!le32_to_cpu(llh->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN) {
+                CERROR("log is not plain\n");
+                RETURN(-EINVAL);
         }
-
-        if (!fsd->fsd_catalog_oid) {
-                struct llog_logid *lgl;
-
-                cathandle = filter_log_create(obd);
-                if (IS_ERR(cathandle)) {
-                        CERROR("error creating new catalog: rc %d\n",
-                               (int)PTR_ERR(cathandle));
-                        GOTO(out, cathandle);
-                }
-                lgl = &cathandle->lgh_cookie.lgc_lgl;
-                fsd->fsd_catalog_oid = cpu_to_le64(lgl->lgl_oid);
-                fsd->fsd_catalog_ogen = cpu_to_le32(lgl->lgl_ogen);
-                rc = filter_update_server_data(obd, filter->fo_rcvd_filp, fsd);
-                if (rc) {
-                        CERROR("error writing new catalog to disk: rc %d\n",rc);
-                        GOTO(out_handle, rc);
-                }
+        if (rec->lrh_type != MDS_UNLINK_REC) {
+                CERROR("log record type error\n");
+                RETURN(-EINVAL);
         }
-
-        rc = llog_init_catalog(cathandle, &obd->u.filter.fo_mdc_uuid);
-        if (rc)
-                GOTO(out_handle, rc);
-out:
-        pop_ctxt(&saved, &filter->fo_ctxt, NULL);
-        RETURN(cathandle);
-
-out_handle:
-        filter_log_close(cathandle, cathandle);
-        cathandle = ERR_PTR(rc);
-        goto out;
-}
-
-void filter_put_catalog(struct llog_handle *cathandle)
-{
-        struct llog_handle *loghandle, *n;
-        int rc;
-        ENTRY;
-
-        list_for_each_entry_safe(loghandle, n, &cathandle->lgh_list, lgh_list)
-                filter_log_close(cathandle, loghandle);
-
-        rc = filp_close(cathandle->lgh_file, 0);
-        if (rc)
-                CERROR("error closing catalog: rc %d\n", rc);
-
-        llog_free_handle(cathandle);
-        EXIT;
-}
-
-int filter_log_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                      int num_cookies, struct llog_cookie *logcookies,
-                      int flags)
-{
-        struct obd_device *obd = class_conn2obd(conn);
-        struct obd_run_ctxt saved;
-        int rc;
-        ENTRY;
-
-        push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL);
-        rc = llog_cancel_records(obd->u.filter.fo_catalog, num_cookies,
-                                 logcookies);
-        pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL);
-
-        RETURN(rc);
-}
-
-int filter_log_op_create(struct llog_handle *cathandle, struct ll_fid *mds_fid,
-                         obd_id oid, obd_count ogen,
-                         struct llog_cookie *logcookie)
-{
-        struct llog_create_rec *lcr;
-        int rc;
-        ENTRY;
-
-        OBD_ALLOC(lcr, sizeof(*lcr));
-        if (lcr == NULL)
+ 
+        cookie.lgc_lgl = llh->lgh_id;
+        cookie.lgc_subsys = LLOG_UNLINK_ORIG_CTXT;
+        cookie.lgc_index = le32_to_cpu(rec->lrh_index);
+                                                                                                                             
+        lur = (struct llog_unlink_rec *)rec;
+        
+        oa = obdo_alloc();
+        if (oa == NULL) 
                 RETURN(-ENOMEM);
-        lcr->lcr_hdr.lth_len = lcr->lcr_end_len = sizeof(*lcr);
-        lcr->lcr_hdr.lth_type = OST_CREATE_REC;
-        lcr->lcr_fid.id = mds_fid->id;
-        lcr->lcr_fid.generation = mds_fid->generation;
-        lcr->lcr_fid.f_type = mds_fid->f_type;
-        lcr->lcr_oid = oid;
-        lcr->lcr_ogen = ogen;
-
-        rc = llog_add_record(cathandle, &lcr->lcr_hdr, logcookie);
-        OBD_FREE(lcr, sizeof(*lcr));
-
-        if (rc > 0) {
-                LASSERT(rc == sizeof(*logcookie));
-                rc = 0;
+        oa->o_valid |= OBD_MD_FLCOOKIE;
+        oa->o_id = lur->lur_oid;
+        oa->o_gr = lur->lur_ogen;
+        memcpy(obdo_logcookie(oa), &cookie, sizeof(cookie));
+        oid = oa->o_id;
+
+        rc = obd_destroy(exp, oa, NULL, &oti);
+        obdo_free(oa);
+        if (rc == -ENOENT) {
+                CWARN("object already removed: send cookie\n");
+                llog_cancel(ctxt, NULL, 1, &cookie, 0);
+                RETURN(0);
         }
-        RETURN(rc);
-}
 
-int filter_log_op_orphan(struct llog_handle *cathandle, obd_id oid,
-                         obd_count ogen, struct llog_cookie *logcookie)
-{
-        struct llog_orphan_rec *lor;
-        int rc;
-        ENTRY;
-
-        OBD_ALLOC(lor, sizeof(*lor));
-        if (lor == NULL)
-                RETURN(-ENOMEM);
-        lor->lor_hdr.lth_len = lor->lor_end_len = sizeof(*lor);
-        lor->lor_hdr.lth_type = OST_ORPHAN_REC;
-        lor->lor_oid = oid;
-        lor->lor_ogen = ogen;
+        if (rc == 0)
+                CWARN("object: "LPU64" in record is destroyed\n", oid);
 
-        rc = llog_add_record(cathandle, &lor->lor_hdr, logcookie);
-
-        if (rc > 0) {
-                LASSERT(rc == sizeof(*logcookie));
-                rc = 0;
-        }
         RETURN(rc);
 }
diff --git a/lustre/obdfilter/filter_san.c b/lustre/obdfilter/filter_san.c
index 30ce9d701adf8b02c8258e429a96b83f85a9e7b0..f6d8d0651f4d9160852330ea415978a33f5f4074 100644
--- a/lustre/obdfilter/filter_san.c
+++ b/lustre/obdfilter/filter_san.c
@@ -37,16 +37,16 @@
 /* sanobd setup methods - use a specific mount option */
 int filter_san_setup(struct obd_device *obd, obd_count len, void *buf)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         char *option = NULL;
 
-        if (!data->ioc_inlbuf2)
+        if (!lcfg->lcfg_inlbuf2)
                 RETURN(-EINVAL);
 
         /* for extN/ext3 filesystem, we must mount it with 'writeback' mode */
-        if (!strcmp(data->ioc_inlbuf2, "extN"))
+        if (!strcmp(lcfg->lcfg_inlbuf2, "extN"))
                 option = "data=writeback";
-        else if (!strcmp(data->ioc_inlbuf2, "ext3"))
+        else if (!strcmp(lcfg->lcfg_inlbuf2, "ext3"))
                 option = "data=writeback,asyncdel";
         else
                 LBUG(); /* just a reminder */
diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c
index 411a9fb92b826be8771afaf23fbdd603268f6c71..308b8f294f8e9319ff8992e7299c089df391f13c 100644
--- a/lustre/obdfilter/lproc_obdfilter.c
+++ b/lustre/obdfilter/lproc_obdfilter.c
@@ -25,6 +25,8 @@
 #include <linux/lprocfs_status.h>
 #include <linux/obd.h>
 
+#include "filter_internal.h"
+
 #ifndef LPROCFS
 static struct lprocfs_vars lprocfs_obd_vars[]  = { {0} };
 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
@@ -42,6 +44,18 @@ static int lprocfs_filter_rd_mntdev(char *page, char **start, off_t off,
                         obd->u.filter.fo_vfsmnt->mnt_devname);
 }
 
+static int lprocfs_filter_rd_last_id(char *page, char **start, off_t off,
+                                     int count, int *eof, void *data)
+{
+        struct obd_device *obd = data;
+
+        if (obd == NULL)
+                return 0;
+
+        return snprintf(page, count, LPU64"\n",
+                        filter_last_id(&obd->u.filter, 0));
+}
+
 static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "uuid",         lprocfs_rd_uuid,          0, 0 },
         { "blocksize",    lprocfs_rd_blksize,       0, 0 },
@@ -52,6 +66,7 @@ static struct lprocfs_vars lprocfs_obd_vars[] = {
         //{ "filegroups",   lprocfs_rd_filegroups,    0, 0 },
         { "fstype",       lprocfs_rd_fstype,        0, 0 },
         { "mntdev",       lprocfs_filter_rd_mntdev, 0, 0 },
+        { "last_id",      lprocfs_filter_rd_last_id, 0, 0 },
         { 0 }
 };
 
diff --git a/lustre/osc/Makefile.am b/lustre/osc/Makefile.am
index dc0b4d8d03c4fdd96a59d3c143cda2dcc4cd4eb5..67e8d16d690814190a2dc5277c3b8de3ab891f95 100644
--- a/lustre/osc/Makefile.am
+++ b/lustre/osc/Makefile.am
@@ -7,12 +7,12 @@ DEFS=
 
 if LIBLUSTRE
 lib_LIBRARIES = libosc.a
-libosc_a_SOURCES = osc_request.c
+libosc_a_SOURCES = osc_request.c osc_lib.c osc_create.c osc_rpcd.c osc_internal.h
 else
 MODULE = osc
 modulefs_DATA = osc.o
 EXTRA_PROGRAMS = osc
-osc_SOURCES = osc_request.c lproc_osc.c osc_lib.c
+osc_SOURCES = osc_request.c lproc_osc.c osc_lib.c  osc_create.c osc_rpcd.c osc_internal.h
 endif
 
 include $(top_srcdir)/Rules
diff --git a/lustre/osc/Makefile.mk b/lustre/osc/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..40ac179039dde0a5dcd4118bd3976c844013ac7f
--- /dev/null
+++ b/lustre/osc/Makefile.mk
@@ -0,0 +1,10 @@
+# Copyright (C) 2003  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../portals/Kernelenv
+
+obj-y += osc.o
+osc-objs := osc_request.o lproc_osc.o osc_lib.o osc_rpcd.o osc_create.o
+
diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c
index e9affd033b7967fab3e9da32e2354b3d70252f93..d394a47f0d1a5f8ac19fe2da4ac5770f1ee7f8c1 100644
--- a/lustre/osc/lproc_osc.c
+++ b/lustre/osc/lproc_osc.c
@@ -27,11 +27,258 @@
 #endif
 #include <linux/obd_class.h>
 #include <linux/lprocfs_status.h>
+#include <linux/seq_file.h>
+#include "osc_internal.h"
 
 #ifndef LPROCFS
 static struct lprocfs_vars lprocfs_obd_vars[]  = { {0} };
 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
 #else
+
+#define OSC_MAX_RIF_MAX 32
+#define OSC_MAX_DIRTY_MB_MAX 4096 /* totally arbitrary */
+
+int osc_rd_max_pages_per_rpc(char *page, char **start, off_t off, int count,
+                             int *eof, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int rc;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        rc = snprintf(page, count, "%d\n", cli->cl_max_pages_per_rpc);
+        spin_unlock(&cli->cl_loi_list_lock);
+        return rc;
+}
+
+int osc_wr_max_pages_per_rpc(struct file *file, const char *buffer,
+                             unsigned long count, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int val, rc;
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 1 || val > PTL_MD_MAX_PAGES)
+                return -ERANGE;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        cli->cl_max_pages_per_rpc = val;
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        return count;
+}
+
+int osc_rd_max_rpcs_in_flight(char *page, char **start, off_t off, int count,
+                              int *eof, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int rc;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        rc = snprintf(page, count, "%d\n", cli->cl_max_rpcs_in_flight);
+        spin_unlock(&cli->cl_loi_list_lock);
+        return rc;
+}
+
+int osc_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
+                              unsigned long count, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int val, rc;
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 1 || val > OSC_MAX_RIF_MAX)
+                return -ERANGE;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        cli->cl_max_rpcs_in_flight = val;
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        return count;
+}
+
+int osc_rd_max_dirty_mb(char *page, char **start, off_t off, int count,
+                        int *eof, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int val;
+        int rc;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        val = cli->cl_dirty_max >> 20;
+        rc = snprintf(page, count, "%d\n", val);
+        spin_unlock(&cli->cl_loi_list_lock);
+        return rc;
+}
+
+int osc_wr_max_dirty_mb(struct file *file, const char *buffer,
+                        unsigned long count, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int val, rc;
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 0 || val > OSC_MAX_DIRTY_MB_MAX)
+                return -ERANGE;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        cli->cl_dirty_max = (obd_count)val * 1024 * 1024;
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        return count;
+}
+
+int osc_rd_cur_dirty_bytes(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_device *dev = data;
+        struct client_obd *cli = &dev->u.cli;
+        int rc;
+
+        spin_lock(&cli->cl_loi_list_lock);
+        rc = snprintf(page, count, LPU64"\n", cli->cl_dirty);
+        spin_unlock(&cli->cl_loi_list_lock);
+        return rc;
+}
+
+int osc_rd_create_low_wm(char *page, char **start, off_t off, int count,
+                         int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        spin_unlock(&obd->obd_dev_lock);
+
+        return snprintf(page, count, "%d\n",
+                        exp->exp_osc_data.oed_oscc.oscc_kick_barrier);
+}
+
+int osc_wr_create_low_wm(struct file *file, const char *buffer,
+                         unsigned long count, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+        int val, rc;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 0)
+                return -ERANGE;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        exp->exp_osc_data.oed_oscc.oscc_kick_barrier = val;
+        spin_unlock(&obd->obd_dev_lock);
+
+        return count;
+}
+
+int osc_rd_create_count(char *page, char **start, off_t off, int count,
+                        int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        spin_unlock(&obd->obd_dev_lock);
+
+        return snprintf(page, count, "%d\n",
+                        exp->exp_osc_data.oed_oscc.oscc_grow_count);
+}
+
+int osc_wr_create_count(struct file *file, const char *buffer,
+                        unsigned long count, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+        int val, rc;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 0)
+                return -ERANGE;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        exp->exp_osc_data.oed_oscc.oscc_grow_count = val;
+        spin_unlock(&obd->obd_dev_lock);
+
+        return count;
+}
+
+int osc_rd_prealloc_next_id(char *page, char **start, off_t off, int count,
+                            int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        spin_unlock(&obd->obd_dev_lock);
+
+        return snprintf(page, count, LPU64"\n",
+                        exp->exp_osc_data.oed_oscc.oscc_next_id);
+}
+
+int osc_rd_prealloc_last_id(char *page, char **start, off_t off, int count,
+                            int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        struct obd_export *exp;
+
+        if (obd == NULL || list_empty(&obd->obd_exports))
+                return 0;
+
+        spin_lock(&obd->obd_dev_lock);
+        exp = list_entry(obd->obd_exports.next, struct obd_export,
+                         exp_obd_chain);
+        spin_unlock(&obd->obd_dev_lock);
+
+        return snprintf(page, count, LPU64"\n",
+                        exp->exp_osc_data.oed_oscc.oscc_last_id);
+}
+
 static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "uuid",            lprocfs_rd_uuid,        0, 0 },
         { "blocksize",       lprocfs_rd_blksize,     0, 0 },
@@ -41,7 +288,17 @@ static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "filesfree",       lprocfs_rd_filesfree,   0, 0 },
         //{ "filegroups",      lprocfs_rd_filegroups,  0, 0 },
         { "ost_server_uuid", lprocfs_rd_server_uuid, 0, 0 },
-        { "ost_conn_uuid",   lprocfs_rd_conn_uuid,   0, 0 },
+        { "ost_conn_uuid",   lprocfs_rd_conn_uuid, 0, 0 },
+        { "max_pages_per_rpc", osc_rd_max_pages_per_rpc, 
+                               osc_wr_max_pages_per_rpc, 0 },
+        { "max_rpcs_in_flight", osc_rd_max_rpcs_in_flight, 
+                                osc_wr_max_rpcs_in_flight, 0 },
+        { "max_dirty_mb", osc_rd_max_dirty_mb, osc_wr_max_dirty_mb, 0 },
+        { "cur_dirty_bytes", osc_rd_cur_dirty_bytes, 0, 0 },
+        {"create_low_watermark", osc_rd_create_low_wm, osc_wr_create_low_wm, 0},
+        { "create_count", osc_rd_create_count, osc_wr_create_count, 0 },
+        { "prealloc_next_id", osc_rd_prealloc_next_id, 0, 0 },
+        { "prealloc_last_id", osc_rd_prealloc_last_id, 0, 0 },
         { 0 }
 };
 
@@ -50,5 +307,195 @@ static struct lprocfs_vars lprocfs_module_vars[] = {
         { 0 }
 };
 
+void lproc_osc_hist(struct osc_histogram *oh, unsigned int value)
+{
+        unsigned long flags;
+
+        if (value >= OSC_HIST_MAX)
+                value = OSC_HIST_MAX - 1;
+
+        spin_lock_irqsave(&oh->oh_lock, flags);
+        oh->oh_buckets[value]++;
+        spin_unlock_irqrestore(&oh->oh_lock, flags);
+}
+
+void lproc_osc_hist_pow2(struct osc_histogram *oh, unsigned int value)
+{
+        unsigned int pow;
+
+        for (pow = 0; ((1 << pow) < value) && (pow <= OSC_HIST_MAX); pow++)
+                ;
+
+        lproc_osc_hist(oh, pow);
+}
+
+static unsigned long lproc_oh_sum(struct osc_histogram *oh)
+{
+        unsigned long ret = 0;
+        int i;
+
+        for (i = 0; i < OSC_HIST_MAX; i++)
+                ret +=  oh->oh_buckets[i];
+        return ret;
+}
+
+static void lproc_clear_oh(struct osc_histogram *oh)
+{
+        unsigned long flags;
+        spin_lock_irqsave(&oh->oh_lock, flags);
+        memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
+        spin_unlock_irqrestore(&oh->oh_lock, flags);
+}
+
+#define pct(a,b) (b ? a * 100 / b : 0)
+
+static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
+{
+        struct timeval now;
+        struct obd_device *dev = seq->private;
+        struct client_obd *cli = &dev->u.cli;
+        unsigned long flags;
+        unsigned long read_tot = 0, write_tot = 0, read_cum, write_cum;
+        int i, rpcs, r, w;
+
+        do_gettimeofday(&now);
+
+        spin_lock_irqsave(&cli->cl_loi_list_lock, flags);
+
+        rpcs = cli->cl_brw_in_flight;
+        r = cli->cl_pending_r_pages;
+        w = cli->cl_pending_w_pages;
+                                                                                
+        seq_printf(seq, "snapshot_time:         %lu:%lu (secs:usecs)\n",
+                   now.tv_sec, now.tv_usec);
+        seq_printf(seq, "RPCs in flight:        %d\n", rpcs);
+        seq_printf(seq, "pending write pages:   %d\n", w);
+        seq_printf(seq, "pending read pages:   %d\n", r);
+
+        seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+        seq_printf(seq, "pages per rpc         rpcs   %% cum %% |");
+        seq_printf(seq, "       rpcs   %% cum %%\n");
+
+        read_tot = lproc_oh_sum(&cli->cl_read_page_hist);
+        write_tot = lproc_oh_sum(&cli->cl_write_page_hist);
+
+        read_cum = 0;
+        write_cum = 0;
+        for (i = 0; i < OSC_HIST_MAX; i++) {
+                unsigned long r = cli->cl_read_page_hist.oh_buckets[i];
+                unsigned long w = cli->cl_write_page_hist.oh_buckets[i];
+                read_cum += r;
+                write_cum += w;
+                seq_printf(seq, "%d:\t\t%10lu %3lu %3lu   | %10lu %3lu %3lu\n", 
+                                 1 << i, r, pct(r, read_tot), 
+                                 pct(read_cum, read_tot), w, 
+                                 pct(w, write_tot),
+                                 pct(write_cum, write_tot));
+                if (read_cum == read_tot && write_cum == write_tot)
+                        break;
+        }
+
+        seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
+        seq_printf(seq, "rpcs in flight        rpcs   %% cum %% |");
+        seq_printf(seq, "       rpcs   %% cum %%\n");
+
+        read_tot = lproc_oh_sum(&cli->cl_read_rpc_hist);
+        write_tot = lproc_oh_sum(&cli->cl_write_rpc_hist);
+
+        read_cum = 0;
+        write_cum = 0;
+        for (i = 0; i < OSC_HIST_MAX; i++) {
+                unsigned long r = cli->cl_read_rpc_hist.oh_buckets[i];
+                unsigned long w = cli->cl_write_rpc_hist.oh_buckets[i];
+                read_cum += r;
+                write_cum += w;
+                seq_printf(seq, "%d:\t\t%10lu %3lu %3lu   | %10lu %3lu %3lu\n", 
+                                 i, r, pct(r, read_tot), 
+                                 pct(read_cum, read_tot), w, 
+                                 pct(w, write_tot),
+                                 pct(write_cum, write_tot));
+                if (read_cum == read_tot && write_cum == write_tot)
+                        break;
+        }
+
+        spin_unlock_irqrestore(&cli->cl_loi_list_lock, flags);
+
+        return 0;
+}
+#undef pct
+
+static void *osc_rpc_stats_seq_start(struct seq_file *p, loff_t *pos)
+{
+        if (*pos == 0)
+                return (void *)1;
+        return NULL;
+}
+static void *osc_rpc_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
+{
+        ++*pos;
+        return NULL;
+}
+static void osc_rpc_stats_seq_stop(struct seq_file *p, void *v)
+{
+}
+struct seq_operations osc_rpc_stats_seq_sops = {
+        .start = osc_rpc_stats_seq_start,
+        .stop = osc_rpc_stats_seq_stop,
+        .next = osc_rpc_stats_seq_next,
+        .show = osc_rpc_stats_seq_show,
+};
+
+static int osc_rpc_stats_seq_open(struct inode *inode, struct file *file)
+{
+        struct proc_dir_entry *dp = inode->u.generic_ip;
+        struct seq_file *seq;
+        int rc;
+ 
+        rc = seq_open(file, &osc_rpc_stats_seq_sops);
+        if (rc)
+                return rc;
+        seq = file->private_data;
+        seq->private = dp->data;
+        return 0;
+}
+
+static ssize_t osc_rpc_stats_seq_write(struct file *file, const char *buf,
+                                       size_t len, loff_t *off)
+{
+        struct seq_file *seq = file->private_data;
+        struct obd_device *dev = seq->private;
+        struct client_obd *cli = &dev->u.cli;
+
+        lproc_clear_oh(&cli->cl_read_rpc_hist);
+        lproc_clear_oh(&cli->cl_write_rpc_hist);
+        lproc_clear_oh(&cli->cl_read_page_hist);
+        lproc_clear_oh(&cli->cl_write_page_hist);
+
+        return len;
+}
+
+struct file_operations osc_rpc_stats_fops = {
+        .open    = osc_rpc_stats_seq_open,
+        .read    = seq_read,
+        .write   = osc_rpc_stats_seq_write,
+        .llseek  = seq_lseek,
+        .release = seq_release,
+};
+
+int lproc_osc_attach_seqstat(struct obd_device *dev)
+{
+        struct proc_dir_entry *entry;
+        ENTRY;
+
+        entry = create_proc_entry("rpc_stats", 0444, dev->obd_proc_entry);
+        if (entry == NULL)
+                RETURN(-ENOMEM);
+        entry->proc_fops = &osc_rpc_stats_fops;
+        entry->data = dev;
+
+        RETURN(0);
+}
+
+
 #endif /* LPROCFS */
 LPROCFS_INIT_VARS(osc,lprocfs_module_vars, lprocfs_obd_vars)
diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b8c50906f9508061ffdde35692de61eb9a3b01d
--- /dev/null
+++ b/lustre/osc/osc_create.c
@@ -0,0 +1,281 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author Peter Braam <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  For testing and management it is treated as an obd_device,
+ *  although * it does not export a full OBD method table (the
+ *  requests are coming * in over the wire, so object target modules
+ *  do not have a full * method table.)
+ *
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_OSC
+
+#ifdef __KERNEL__
+# include <linux/version.h>
+# include <linux/module.h>
+# include <linux/mm.h>
+# include <linux/highmem.h>
+# include <linux/lustre_dlm.h>
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+#  include <linux/workqueue.h>
+#  include <linux/smp_lock.h>
+# else
+#  include <linux/locks.h>
+# endif
+#else /* __KERNEL__ */
+# include <liblustre.h>
+#endif
+
+#ifndef  __CYGWIN__
+# include <linux/ctype.h>
+# include <linux/init.h>
+#else
+# include <ctype.h>
+#endif
+
+#include <linux/obd_class.h>
+#include "osc_internal.h"
+
+static int osc_interpret_create(struct ptlrpc_request *req, void *data,
+                                int rc)
+{
+        struct osc_creator *oscc;
+        struct ost_body *body = NULL;
+        ENTRY;
+
+        if (req->rq_repmsg) {
+                body = lustre_swab_repbuf(req, 0, sizeof(*body),
+                                          lustre_swab_ost_body);
+                if (body == NULL && rc == 0)
+                        rc = -EPROTO;
+        }
+
+        oscc = req->rq_async_args.pointer_arg[0];
+        spin_lock(&oscc->oscc_lock);
+        if (body)
+                oscc->oscc_last_id = body->oa.o_id;
+        if (rc == -ENOSPC) {
+                DEBUG_REQ(D_INODE, req, "OST out of space, flagging");
+                oscc->oscc_flags |= OSCC_FLAG_NOSPC;
+        } else if (rc != 0 && rc != -EIO) {
+                DEBUG_REQ(D_ERROR, req,
+                          "unknown rc %d from async create: failing oscc",
+                          rc);
+                ptlrpc_fail_import(req->rq_import, req->rq_import_generation);
+        }
+        oscc->oscc_flags &= ~OSCC_FLAG_CREATING;
+        spin_unlock(&oscc->oscc_lock);
+
+        CDEBUG(D_INFO, "preallocated through id "LPU64" (last used "LPU64")\n",
+               oscc->oscc_last_id, oscc->oscc_next_id);
+
+        wake_up(&oscc->oscc_waitq);
+        RETURN(rc);
+}
+
+static int oscc_internal_create(struct osc_creator *oscc)
+{
+        struct ptlrpc_request *request;
+        struct ost_body *body;
+        int size = sizeof(*body);
+        ENTRY;
+
+        spin_lock(&oscc->oscc_lock);
+        if (oscc->oscc_flags & OSCC_FLAG_CREATING) {
+                spin_unlock(&oscc->oscc_lock);
+                RETURN(0);
+        }
+        oscc->oscc_flags |= OSCC_FLAG_CREATING;
+        spin_unlock(&oscc->oscc_lock);
+
+        request = ptlrpc_prep_req(class_exp2cliimp(oscc->oscc_exp), OST_CREATE,
+                                  1, &size, NULL);
+        if (request == NULL) {
+                spin_lock(&oscc->oscc_lock);
+                oscc->oscc_flags &= ~OSCC_FLAG_CREATING;
+                spin_unlock(&oscc->oscc_lock);
+                RETURN(-ENOMEM);
+        }
+
+        request->rq_request_portal = OST_CREATE_PORTAL; //XXX FIXME bug 249
+        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*body));
+
+        spin_lock(&oscc->oscc_lock);
+        body->oa.o_id = oscc->oscc_last_id + oscc->oscc_grow_count;
+        body->oa.o_valid |= OBD_MD_FLID;
+        CDEBUG(D_INFO, "preallocating through id "LPU64" (last used "LPU64")\n",
+               body->oa.o_id, oscc->oscc_next_id);
+        spin_unlock(&oscc->oscc_lock);
+
+        request->rq_replen = lustre_msg_size(1, &size);
+
+        request->rq_async_args.pointer_arg[0] = oscc;
+        request->rq_interpret_reply = osc_interpret_create;
+        osc_rpcd_add_req(request);
+
+        RETURN(0);
+}
+
+static int oscc_has_objects(struct osc_creator *oscc, int count)
+{
+        int have_objs;
+        spin_lock(&oscc->oscc_lock);
+        have_objs = ((__s64)(oscc->oscc_last_id - oscc->oscc_next_id) >= count);
+        spin_unlock(&oscc->oscc_lock);
+
+        if (!have_objs)
+                oscc_internal_create(oscc);
+
+        return have_objs;
+}
+
+static int oscc_wait_for_objects(struct osc_creator *oscc, int count)
+{
+        int have_objs;
+        int ost_full;
+        int osc_invalid;
+
+        have_objs = oscc_has_objects(oscc, count);
+
+        spin_lock(&oscc->oscc_lock);
+        ost_full = (oscc->oscc_flags & OSCC_FLAG_NOSPC);
+        spin_unlock(&oscc->oscc_lock);
+
+        osc_invalid = class_exp2cliimp(oscc->oscc_exp)->imp_invalid;
+
+        return have_objs || ost_full || osc_invalid;
+}
+
+static int oscc_precreate(struct osc_creator *oscc, int wait)
+{
+        struct l_wait_info lwi = { 0 };
+        int rc = 0;
+        ENTRY;
+
+        if (oscc_has_objects(oscc, oscc->oscc_kick_barrier))
+                RETURN(0);
+
+        if (!wait)
+                RETURN(0);
+
+        /* no rc check -- a no-INTR, no-TIMEOUT wait can't fail */
+        l_wait_event(oscc->oscc_waitq, oscc_wait_for_objects(oscc, 1), &lwi);
+
+        if (!oscc_has_objects(oscc, 1) && (oscc->oscc_flags & OSCC_FLAG_NOSPC))
+                rc = -ENOSPC;
+
+        if (class_exp2cliimp(oscc->oscc_exp)->imp_invalid)
+                rc = -EIO;
+
+        RETURN(rc);
+}
+
+int osc_create(struct obd_export *exp, struct obdo *oa,
+               struct lov_stripe_md **ea, struct obd_trans_info *oti)
+{
+        struct lov_stripe_md *lsm;
+        struct osc_creator *oscc = &exp->u.eu_osc_data.oed_oscc;
+        int try_again = 1, rc = 0;
+        ENTRY;
+        LASSERT(oa);
+        LASSERT(ea);
+
+        if ((oa->o_valid & OBD_MD_FLGROUP) && (oa->o_gr != 0))
+                RETURN(osc_real_create(exp, oa, ea, oti));
+
+        lsm = *ea;
+        if (lsm == NULL) {
+                rc = obd_alloc_memmd(exp, &lsm);
+                if (rc < 0)
+                        RETURN(rc);
+        }
+
+	/* this is the special case where create removes orphans */
+	if ((oa->o_valid & OBD_MD_FLFLAGS) &&
+	    oa->o_flags == OBD_FL_DELORPHAN) {
+                /* delete from next_id on up */
+                oa->o_valid |= OBD_MD_FLID;
+                oa->o_id = oscc->oscc_next_id;
+                if (oa->o_id == 0)
+                        RETURN(0);
+                rc = osc_real_create(oscc->oscc_exp, oa, ea, NULL);
+
+                spin_lock(&oscc->oscc_lock);
+                if (rc == -ENOSPC)
+                        oscc->oscc_flags |= OSCC_FLAG_NOSPC;
+                oscc->oscc_last_id = oscc->oscc_next_id - 1;
+                spin_unlock(&oscc->oscc_lock);
+
+		RETURN(rc);
+	}
+
+        while (try_again) {
+                spin_lock(&oscc->oscc_lock);
+                if (oscc->oscc_last_id >= oscc->oscc_next_id) {
+                        memcpy(oa, &oscc->oscc_oa, sizeof(*oa));
+                        oa->o_id = oscc->oscc_next_id;
+                        lsm->lsm_object_id = oscc->oscc_next_id;
+                        *ea = lsm;
+                        oscc->oscc_next_id++;
+                        try_again = 0;
+                } else if (oscc->oscc_flags & OSCC_FLAG_NOSPC) {
+                        rc = -ENOSPC;
+                        spin_unlock(&oscc->oscc_lock);
+                        break;
+                }
+                spin_unlock(&oscc->oscc_lock);
+                rc = oscc_precreate(oscc, try_again);
+                if (rc == -EIO)
+                        break;
+        }
+
+        if (rc == 0)
+                CDEBUG(D_INFO, "returning objid "LPU64"\n", lsm->lsm_object_id);
+        else if (*ea == NULL)
+                obd_free_memmd(exp, &lsm);
+        RETURN(rc);
+}
+
+void oscc_init(struct obd_export *exp)
+{
+        struct osc_export_data *oed;
+
+        if (exp == NULL)
+                return;
+
+        oed = &exp->exp_osc_data;
+        memset(oed, 0, sizeof(*oed));
+        INIT_LIST_HEAD(&oed->oed_oscc.oscc_list);
+        init_waitqueue_head(&oed->oed_oscc.oscc_waitq);
+        spin_lock_init(&oed->oed_oscc.oscc_lock);
+        oed->oed_oscc.oscc_exp = exp;
+        oed->oed_oscc.oscc_kick_barrier = 100;
+        oed->oed_oscc.oscc_grow_count = 2000;
+        oed->oed_oscc.oscc_initial_create_count = 2000;
+
+        oed->oed_oscc.oscc_next_id = 2;
+        oed->oed_oscc.oscc_last_id = 1;
+        /* XXX the export handle should give the oscc the last object */
+        /* oed->oed_oscc.oscc_last_id = exph->....; */
+}
diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4ed9a8dc79e4e3bd625dfe0fe896f9e83b8203d
--- /dev/null
+++ b/lustre/osc/osc_internal.h
@@ -0,0 +1,71 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2003 Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ */
+
+#ifndef OSC_INTERNAL_H
+#define OSC_INTERNAL_H
+
+#include <portals/lib-types.h> /* for PTL_MTU and PTL_MD_MAX_PAGES */
+
+/* bug 1578: negotiate BRW_MAX_SIZE with the OST, instead of hard-coding it */
+#define OSC_BRW_MAX_SIZE PTL_MTU
+#define OSC_BRW_MAX_IOV PTL_MD_MAX_PAGES
+
+#define OAP_MAGIC 8675309
+
+struct osc_async_page {
+        int                     oap_magic;
+        struct list_head        oap_pending_item;
+        struct list_head        oap_urgent_item;
+        struct list_head        oap_rpc_item;
+        struct page             *oap_page;
+        int                     oap_cmd;
+
+        obd_off                 oap_obj_off;
+        obd_off                 oap_page_off;
+        int                     oap_count;
+        obd_flag                oap_brw_flags;
+        enum async_flags        oap_async_flags;
+
+        struct obd_sync_io_container *oap_osic;
+
+	struct obd_async_page_ops *oap_caller_ops;
+        void                   *oap_caller_data;
+};
+
+#define OSCC_FLAG_RECOVERING 1
+#define OSCC_FLAG_CREATING   2
+#define OSCC_FLAG_NOSPC      4 /* can't create more objects on this OST */
+
+int osc_create(struct obd_export *exp, struct obdo *oa,
+	       struct lov_stripe_md **ea, struct obd_trans_info *oti);
+int osc_real_create(struct obd_export *exp, struct obdo *oa,
+	       struct lov_stripe_md **ea, struct obd_trans_info *oti);
+void oscc_init(struct obd_export *exp);
+
+extern atomic_t osc_max_rpcs_in_flight;
+extern atomic_t osc_max_pages_per_rpc;
+int osc_rpcd_addref(void);
+int osc_rpcd_decref(void);
+void osc_rpcd_add_req(struct ptlrpc_request *req);
+
+#ifdef __KERNEL__
+
+int lproc_osc_attach_seqstat(struct obd_device *dev);
+void lproc_osc_hist(struct osc_histogram *oh, unsigned int value);
+void lproc_osc_hist_pow2(struct osc_histogram *oh, unsigned int value);
+
+#else /* !__KERNEL__ */
+
+#define lproc_osc_attach_seqstat(dev) (0)
+#define lproc_osc_hist(o,v) do{}while(0)
+#define lproc_osc_hist_pow2(o, v) do{}while(0)
+
+#endif
+
+#endif /* OSC_INTERNAL_H */
diff --git a/lustre/osc/osc_lib.c b/lustre/osc/osc_lib.c
index c8cd6adb8c7596bcb9a8724383ca915032b15ed2..79b4b6b4aadabf114a1d81f110a2d87222fa9d3b 100644
--- a/lustre/osc/osc_lib.c
+++ b/lustre/osc/osc_lib.c
@@ -19,7 +19,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_OSC
 
 #ifdef __KERNEL__
@@ -28,6 +30,8 @@
 # include <linux/obd_ost.h>
 # include <linux/lustre_net.h>
 # include <linux/lustre_dlm.h>
+# include <linux/lustre_lib.h>
+# include <linux/lustre_compat25.h>
 
 /* convert a pathname into a kdev_t */
 static kdev_t path2dev(char *path)
@@ -36,11 +40,8 @@ static kdev_t path2dev(char *path)
         struct nameidata nd;
         kdev_t dev = KDEVT_INIT(0);
 
-        if (!path_init(path, LOOKUP_FOLLOW, &nd))
-                return 0;
-
-        if (path_walk(path, &nd))
-                return 0;
+        if (ll_path_lookup(path, LOOKUP_FOLLOW, &nd))
+                return val_to_kdev(0);
 
         dentry = nd.dentry;
         if (dentry->d_inode && !is_bad_inode(dentry->d_inode) &&
@@ -53,20 +54,20 @@ static kdev_t path2dev(char *path)
 
 int client_sanobd_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         struct client_obd *cli = &obddev->u.cli;
         ENTRY;
 
-        if (data->ioc_inllen3 < 1) {
+        if (lcfg->lcfg_inllen3 < 1) {
                 CERROR("setup requires a SAN device pathname\n");
                 RETURN(-EINVAL);
         }
 
         client_obd_setup(obddev, len, buf);
 
-        cli->cl_sandev = path2dev(data->ioc_inlbuf3);
+        cli->cl_sandev = path2dev(lcfg->lcfg_inlbuf3);
         if (!kdev_t_to_nr(cli->cl_sandev)) {
-                CERROR("%s seems not a valid SAN device\n", data->ioc_inlbuf3);
+                CERROR("%s seems not a valid SAN device\n", lcfg->lcfg_inlbuf3);
                 RETURN(-EINVAL);
         }
 
diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c
index 595070c8ce3779c1db1883316e74ec2acd90317c..41ca89180b096720dd9901a3a0b812d1342ee9f5 100644
--- a/lustre/osc/osc_request.c
+++ b/lustre/osc/osc_request.c
@@ -26,7 +26,9 @@
  *
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_OSC
 
 #ifdef __KERNEL__
@@ -46,10 +48,9 @@
 #endif
 
 #include <linux/kp30.h>
-#include <linux/lustre_mds.h> /* for mds_objid */
-#include <linux/lustre_otree.h>
+#include <linux/lustre_net.h>
+#include <linux/lustre_user.h>
 #include <linux/obd_ost.h>
-#include <linux/lustre_commit_confd.h>
 #include <linux/obd_lov.h>
 
 #ifndef  __CYGWIN__
@@ -60,28 +61,41 @@
 #endif
 
 #include <linux/lustre_ha.h>
-#include <linux/obd_support.h> /* for OBD_FAIL_CHECK */
-#include <linux/lustre_lite.h> /* for ll_i2info */
-#include <portals/lib-types.h> /* for PTL_MD_MAX_IOV */
 #include <linux/lprocfs_status.h>
+#include <linux/lustre_log.h>
+#include "osc_internal.h"
 
-static struct llog_cookie zero_cookie = { { 0 } };
 
 static int osc_attach(struct obd_device *dev, obd_count len, void *data)
 {
         struct lprocfs_static_vars lvars;
+        int rc;
+        ENTRY;
 
         lprocfs_init_vars(osc,&lvars);
-        return lprocfs_obd_attach(dev, lvars.obd_vars);
+        rc = lprocfs_obd_attach(dev, lvars.obd_vars);
+        if (rc < 0)
+                RETURN(rc);
+
+        rc = lproc_osc_attach_seqstat(dev);
+        if (rc < 0) {
+                lprocfs_obd_detach(dev);
+                RETURN(rc);
+        }
+
+        ptlrpc_lprocfs_register_obd(dev);
+        RETURN(0);
 }
 
 static int osc_detach(struct obd_device *dev)
 {
+        ptlrpc_lprocfs_unregister_obd(dev);
         return lprocfs_obd_detach(dev);
 }
 
+
 /* Pack OSC object metadata for disk storage (LE byte order). */
-static int osc_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp,
+static int osc_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
                       struct lov_stripe_md *lsm)
 {
         int lmm_size;
@@ -105,14 +119,14 @@ static int osc_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp,
 
         if (lsm) {
                 LASSERT(lsm->lsm_object_id);
-                (*lmmp)->lmm_object_id = cpu_to_le64 (lsm->lsm_object_id);
+                (*lmmp)->lmm_object_id = cpu_to_le64(lsm->lsm_object_id);
         }
 
         RETURN(lmm_size);
 }
 
 /* Unpack OSC object metadata from disk storage (LE byte order). */
-static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
+static int osc_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
                         struct lov_mds_md *lmm, int lmm_bytes)
 {
         int lsm_size;
@@ -126,7 +140,7 @@ static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
                 }
                 /* XXX LOV_MAGIC etc check? */
 
-                if (lmm->lmm_object_id == cpu_to_le64(0)) {
+                if (lmm->lmm_object_id == 0) {
                         CERROR("lov_mds_md: zero lmm_object_id\n");
                         RETURN(-EINVAL);
                 }
@@ -146,10 +160,7 @@ static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
                 OBD_ALLOC(*lsmp, lsm_size);
                 if (*lsmp == NULL)
                         RETURN(-ENOMEM);
-
-                (*lsmp)->lsm_oinfo[0].loi_dirty_ot =
-                        &(*lsmp)->lsm_oinfo[0].loi_dirty_ot_inline;
-                ot_init((*lsmp)->lsm_oinfo[0].loi_dirty_ot);
+                loi_init((*lsmp)->lsm_oinfo);
         }
 
         if (lmm != NULL) {
@@ -163,10 +174,6 @@ static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp,
         RETURN(lsm_size);
 }
 
-#warning "FIXME: make this be sent from OST"
-#define OSC_BRW_MAX_SIZE 65536
-#define OSC_BRW_MAX_IOV min_t(int, PTL_MD_MAX_IOV, OSC_BRW_MAX_SIZE/PAGE_SIZE)
-
 static int osc_getattr_interpret(struct ptlrpc_request *req,
                                  struct osc_getattr_async_args *aa, int rc)
 {
@@ -193,7 +200,7 @@ static int osc_getattr_interpret(struct ptlrpc_request *req,
         RETURN(rc);
 }
 
-static int osc_getattr_async(struct lustre_handle *conn, struct obdo *oa,
+static int osc_getattr_async(struct obd_export *exp, struct obdo *oa,
                              struct lov_stripe_md *md,
                              struct ptlrpc_request_set *set)
 {
@@ -203,7 +210,7 @@ static int osc_getattr_async(struct lustre_handle *conn, struct obdo *oa,
         struct osc_getattr_async_args *aa;
         ENTRY;
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_GETATTR, 1,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_GETATTR, 1,
                                   &size, NULL);
         if (!request)
                 RETURN(-ENOMEM);
@@ -222,7 +229,7 @@ static int osc_getattr_async(struct lustre_handle *conn, struct obdo *oa,
         RETURN (0);
 }
 
-static int osc_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int osc_getattr(struct obd_export *exp, struct obdo *oa,
                        struct lov_stripe_md *md)
 {
         struct ptlrpc_request *request;
@@ -230,7 +237,7 @@ static int osc_getattr(struct lustre_handle *conn, struct obdo *oa,
         int rc, size = sizeof(*body);
         ENTRY;
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_GETATTR, 1,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_GETATTR, 1,
                                   &size, NULL);
         if (!request)
                 RETURN(-ENOMEM);
@@ -266,83 +273,20 @@ static int osc_getattr(struct lustre_handle *conn, struct obdo *oa,
         return rc;
 }
 
-/* The import lock must already be held. */
-static inline void osc_update_body_handle(struct list_head *head,
-                                          struct lustre_handle *old,
-                                          struct lustre_handle *new, int op)
-{
-        struct list_head *tmp;
-        struct ost_body *body;
-        struct ptlrpc_request *req;
-        struct ptlrpc_request *last_req = NULL; /* temporary fire escape */
-
-        list_for_each(tmp, head) {
-                req = list_entry(tmp, struct ptlrpc_request, rq_list);
-
-                /* XXX ok to remove when bug 1303 resolved - rread 05/27/03  */
-                LASSERT (req != last_req);
-                last_req = req;
-
-                if (req->rq_reqmsg->opc != op)
-                        continue;
-                body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
-                if (memcmp(obdo_handle(&body->oa), old, sizeof(*old)))
-                        continue;
-
-                DEBUG_REQ(D_HA, req, "updating close body with new fh");
-                memcpy(obdo_handle(&body->oa), new, sizeof(*new));
-        }
-}
-
-static void osc_replay_open(struct ptlrpc_request *req)
-{
-        struct lustre_handle old;
-        struct ost_body *body;
-        struct obd_client_handle *och = req->rq_replay_data;
-        struct lustre_handle *oa_handle;
-        ENTRY;
-
-        body = lustre_swab_repbuf (req, 0, sizeof (*body),
-                                   lustre_swab_ost_body);
-        LASSERT (body != NULL);
-
-        oa_handle = obdo_handle(&body->oa);
-
-        memcpy(&old, &och->och_fh, sizeof(old));
-        CDEBUG(D_HA, "updating cookie from "LPD64" to "LPD64"\n",
-               och->och_fh.cookie, oa_handle->cookie);
-        memcpy(&och->och_fh, oa_handle, sizeof(och->och_fh));
-
-        /* A few frames up, ptlrpc_replay holds the lock, so this is safe. */
-        osc_update_body_handle(&req->rq_import->imp_sending_list, &old,
-                              &och->och_fh, OST_CLOSE);
-        osc_update_body_handle(&req->rq_import->imp_delayed_list, &old,
-                              &och->och_fh, OST_CLOSE);
-        EXIT;
-}
-
-
-static int osc_open(struct lustre_handle *conn, struct obdo *oa,
-                    struct lov_stripe_md *md, struct obd_trans_info *oti,
-                    struct obd_client_handle *och)
+static int osc_setattr(struct obd_export *exp, struct obdo *oa,
+                       struct lov_stripe_md *md, struct obd_trans_info *oti)
 {
         struct ptlrpc_request *request;
         struct ost_body *body;
-        unsigned long flags;
         int rc, size = sizeof(*body);
         ENTRY;
-        LASSERT(och != NULL);
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_OPEN, 1, &size,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_SETATTR, 1, &size,
                                   NULL);
         if (!request)
-                RETURN(-ENOMEM);
-
-        spin_lock_irqsave (&request->rq_lock, flags);
-        request->rq_replay = 1;
-        spin_unlock_irqrestore (&request->rq_lock, flags);
+		RETURN(-ENOMEM);
 
-        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
+        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*body));
         memcpy(&body->oa, oa, sizeof(*oa));
 
         request->rq_replen = lustre_msg_size(1, &size);
@@ -351,138 +295,21 @@ static int osc_open(struct lustre_handle *conn, struct obdo *oa,
         if (rc)
                 GOTO(out, rc);
 
-        body = lustre_swab_repbuf (request, 0, sizeof (*body),
-                                   lustre_swab_ost_body);
-        if (body == NULL) {
-                CERROR ("Can't unpack ost_body\n");
-                GOTO (out, rc = -EPROTO);
-        }
+        body = lustre_swab_repbuf(request, 0, sizeof(*body),
+                                  lustre_swab_ost_body);
+        if (body == NULL)
+                GOTO(out, rc = -EPROTO);
 
         memcpy(oa, &body->oa, sizeof(*oa));
 
-        /* If the open succeeded, we better have a handle */
-        /* BlueArc OSTs don't send back (o_valid | FLHANDLE).  sigh.
-         * Temporary workaround until fixed. -phil 24 Feb 03 */
-        // if ((oa->o_valid & OBD_MD_FLHANDLE) == 0) {
-        //         CERROR ("No file handle\n");
-        //         GOTO (out, rc = -EPROTO);
-        // }
-        oa->o_valid |= OBD_MD_FLHANDLE;
-
-        /* This should really be sent by the OST */
-        oa->o_blksize = OSC_BRW_MAX_SIZE;
-        oa->o_valid |= OBD_MD_FLBLKSZ;
-
-        memcpy(&och->och_fh, obdo_handle(oa), sizeof(och->och_fh));
-        request->rq_replay_cb = osc_replay_open;
-        request->rq_replay_data = och;
-        och->och_req = ptlrpc_request_addref(request);
-        och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
-
         EXIT;
- out:
-        ptlrpc_req_finished(request);
-        return rc;
-}
-
-static int osc_close(struct lustre_handle *conn, struct obdo *oa,
-                     struct lov_stripe_md *md, struct obd_trans_info *oti)
-{
-        struct obd_import *import = class_conn2cliimp(conn);
-        struct ptlrpc_request *request;
-        struct ost_body *body;
-        struct obd_client_handle *och;
-        unsigned long flags;
-        int rc, size = sizeof(*body);
-        ENTRY;
-
-        LASSERT(oa != NULL);
-        och = (struct obd_client_handle *)&oa->o_inline;
-        if (och->och_magic == 0) {
-                /* Zero magic means that this file was never opened on this
-                 * OST--almost certainly because the OST was inactive at
-                 * open-time */
-                RETURN(0);
-        }
-        LASSERT(och->och_magic == OBD_CLIENT_HANDLE_MAGIC);
-
-        request = ptlrpc_prep_req(import, OST_CLOSE, 1, &size, NULL);
-        if (!request)
-                RETURN(-ENOMEM);
-
-        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
-        memcpy(&body->oa, oa, sizeof(*oa));
-
-        request->rq_replen = lustre_msg_size(1, &size);
-
-        rc = ptlrpc_queue_wait(request);
-        if (rc)
-                CDEBUG(D_HA, "Suppressing close error %d\n", rc); // bug 1036
-
-        /* och_req == NULL can't happen any more, right? --phik */
-        if (och->och_req != NULL) {
-                spin_lock_irqsave(&import->imp_lock, flags);
-                spin_lock (&och->och_req->rq_lock);
-                och->och_req->rq_replay = 0;
-                spin_unlock (&och->och_req->rq_lock);
-                /* see comments in llite/file.c:ll_mdc_close() */
-                if (och->och_req->rq_transno) {
-                        /* this can't happen yet, because the OSTs don't yet
-                         * issue transnos for OPEN requests -phik 21 Apr 2003 */
-                        LBUG();
-                        if (!request->rq_transno && import->imp_replayable) {
-                                request->rq_transno = och->och_req->rq_transno;
-                                ptlrpc_retain_replayable_request(request,
-                                                                 import);
-                        }
-                        spin_unlock_irqrestore(&import->imp_lock, flags);
-                } else {
-                        spin_unlock_irqrestore(&import->imp_lock, flags);
-                }
-
-                ptlrpc_req_finished(och->och_req);
-        }
-
-        if (!rc) {
-                body = lustre_swab_repbuf (request, 0, sizeof (*body),
-                                           lustre_swab_ost_body);
-                if (body == NULL) {
-                        rc = -EPROTO;
-                        CDEBUG(D_HA, "Suppressing close error %d\n", rc); // bug 1036
-                } else
-                        memcpy(oa, &body->oa, sizeof(*oa));
-        }
-
+out:
         ptlrpc_req_finished(request);
         RETURN(0);
 }
 
-static int osc_setattr(struct lustre_handle *conn, struct obdo *oa,
-                       struct lov_stripe_md *md, struct obd_trans_info *oti)
-{
-        struct ptlrpc_request *request;
-        struct ost_body *body;
-        int rc, size = sizeof(*body);
-        ENTRY;
-
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SETATTR, 1,
-                                  &size, NULL);
-        if (!request)
-                RETURN(-ENOMEM);
-
-        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
-        memcpy(&body->oa, oa, sizeof(*oa));
-
-        request->rq_replen = lustre_msg_size(1, &size);
-
-        rc = ptlrpc_queue_wait(request);
-
-        ptlrpc_req_finished(request);
-        return rc;
-}
-
-static int osc_create(struct lustre_handle *conn, struct obdo *oa,
-                      struct lov_stripe_md **ea, struct obd_trans_info *oti)
+int osc_real_create(struct obd_export *exp, struct obdo *oa,
+                    struct lov_stripe_md **ea, struct obd_trans_info *oti)
 {
         struct ptlrpc_request *request;
         struct ost_body *body;
@@ -495,12 +322,12 @@ static int osc_create(struct lustre_handle *conn, struct obdo *oa,
 
         lsm = *ea;
         if (!lsm) {
-                rc = obd_alloc_memmd(conn, &lsm);
+                rc = obd_alloc_memmd(exp, &lsm);
                 if (rc < 0)
                         RETURN(rc);
         }
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_CREATE, 1, &size,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_CREATE, 1, &size,
                                   NULL);
         if (!request)
                 GOTO(out, rc = -ENOMEM);
@@ -509,6 +336,13 @@ static int osc_create(struct lustre_handle *conn, struct obdo *oa,
         memcpy(&body->oa, oa, sizeof(body->oa));
 
         request->rq_replen = lustre_msg_size(1, &size);
+        if (oa->o_valid & OBD_MD_FLINLINE) {
+                LASSERT((oa->o_valid & OBD_MD_FLFLAGS) &&
+                        oa->o_flags == OBD_FL_DELORPHAN);
+                DEBUG_REQ(D_HA, request,
+                          "delorphan from OST integration; level == RECOVER");
+                request->rq_send_state = LUSTRE_IMP_RECOVER;
+        }
 
         rc = ptlrpc_queue_wait(request);
         if (rc)
@@ -551,11 +385,11 @@ out_req:
         ptlrpc_req_finished(request);
 out:
         if (rc && !*ea)
-                obd_free_memmd(conn, &lsm);
+                obd_free_memmd(exp, &lsm);
         return rc;
 }
 
-static int osc_punch(struct lustre_handle *conn, struct obdo *oa,
+static int osc_punch(struct obd_export *exp, struct obdo *oa,
                      struct lov_stripe_md *md, obd_size start,
                      obd_size end, struct obd_trans_info *oti)
 {
@@ -569,7 +403,7 @@ static int osc_punch(struct lustre_handle *conn, struct obdo *oa,
                 RETURN(-EINVAL);
         }
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_PUNCH, 1, &size,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_PUNCH, 1, &size,
                                   NULL);
         if (!request)
                 RETURN(-ENOMEM);
@@ -603,7 +437,54 @@ static int osc_punch(struct lustre_handle *conn, struct obdo *oa,
         return rc;
 }
 
-static int osc_destroy(struct lustre_handle *conn, struct obdo *oa,
+static int osc_sync(struct obd_export *exp, struct obdo *oa,
+                    struct lov_stripe_md *md, obd_size start, obd_size end)
+{
+        struct ptlrpc_request *request;
+        struct ost_body *body;
+        int rc, size = sizeof(*body);
+        ENTRY;
+
+        if (!oa) {
+                CERROR("oa NULL\n");
+                RETURN(-EINVAL);
+        }
+
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_SYNC, 1, &size,
+                                  NULL);
+        if (!request)
+                RETURN(-ENOMEM);
+
+        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
+        memcpy(&body->oa, oa, sizeof(*oa));
+
+        /* overload the size and blocks fields in the oa with start/end */
+        body->oa.o_size = start;
+        body->oa.o_blocks = end;
+        body->oa.o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
+
+        request->rq_replen = lustre_msg_size(1, &size);
+
+        rc = ptlrpc_queue_wait(request);
+        if (rc)
+                GOTO(out, rc);
+
+        body = lustre_swab_repbuf(request, 0, sizeof(*body),
+                                  lustre_swab_ost_body);
+        if (body == NULL) {
+                CERROR ("can't unpack ost_body\n");
+                GOTO (out, rc = -EPROTO);
+        }
+
+        memcpy(oa, &body->oa, sizeof(*oa));
+
+        EXIT;
+ out:
+        ptlrpc_req_finished(request);
+        return rc;
+}
+
+static int osc_destroy(struct obd_export *exp, struct obdo *oa,
                        struct lov_stripe_md *ea, struct obd_trans_info *oti)
 {
         struct ptlrpc_request *request;
@@ -615,20 +496,21 @@ static int osc_destroy(struct lustre_handle *conn, struct obdo *oa,
                 CERROR("oa NULL\n");
                 RETURN(-EINVAL);
         }
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_DESTROY, 1,
+
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_DESTROY, 1,
                                   &size, NULL);
         if (!request)
                 RETURN(-ENOMEM);
 
         body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof (*body));
-        memcpy(&body->oa, oa, sizeof(*oa));
 
-        if (oti && oa->o_valid & OBD_MD_FLCOOKIE) {
+        if (oti != NULL && oa->o_valid & OBD_MD_FLCOOKIE) {
                 memcpy(obdo_logcookie(oa), oti->oti_logcookies,
                        sizeof(*oti->oti_logcookies));
                 oti->oti_logcookies++;
         }
 
+        memcpy(&body->oa, oa, sizeof(*oa));
         request->rq_replen = lustre_msg_size(1, &size);
 
         rc = ptlrpc_queue_wait(request);
@@ -725,7 +607,7 @@ static int check_write_rcs(struct ptlrpc_request *request, int niocount,
                            obd_count page_count, struct brw_page *pga)
 {
         int    i;
-        __u32 *remote_rcs;
+        int    *remote_rcs;
 
         /* return error if any niobuf was in error */
         remote_rcs = lustre_swab_repbuf(request, 1,
@@ -752,14 +634,17 @@ static int check_write_rcs(struct ptlrpc_request *request, int niocount,
         return (0);
 }
 
-static inline int can_merge_pages (struct brw_page *p1, struct brw_page *p2)
+static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2)
 {
         if (p1->flag != p2->flag) {
-                /* XXX we don't make much use of 'flag' right now
-                 * but this will warn about usage when we do */
-                CERROR ("different flags set %d, %d\n",
-                        p1->flag, p2->flag);
-                return (0);
+                unsigned mask = ~(OBD_BRW_CREATE|OBD_BRW_FROM_GRANT);
+
+                /* warn if we try to combine flags that we don't know to be
+                 * safe to combine */
+                if ((p1->flag & mask) != (p2->flag & mask))
+                        CERROR("is it ok to have flags 0x%x and 0x%x in the "
+                               "same brw?\n", p1->flag, p2->flag);
+                return 0;
         }
 
         return (p1->off + p1->count == p2->off);
@@ -771,15 +656,14 @@ static obd_count cksum_pages(int nob, obd_count page_count,
 {
         obd_count cksum = 0;
         char *ptr;
-        int   i;
 
         while (nob > 0) {
                 LASSERT (page_count > 0);
 
-                ptr = kmap (pga->pg);
-                ost_checksum (&cksum, ptr + (pga->off & (PAGE_SIZE - 1)),
-                              pga->count > nob ? nob : pga->count);
-                kunmap (pga->pg);
+                ptr = kmap(pga->pg);
+                ost_checksum(&cksum, ptr + (pga->off & (PAGE_SIZE - 1)),
+                             pga->count > nob ? nob : pga->count);
+                kunmap(pga->pg);
 
                 nob -= pga->count;
                 page_count--;
@@ -839,9 +723,7 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
 
         memcpy(&body->oa, oa, sizeof(*oa));
 
-        ioobj->ioo_id = oa->o_id;
-        ioobj->ioo_gr = oa->o_valid & 0 ? oa->o_gr : 0;
-        ioobj->ioo_type = oa->o_mode;
+        obdo_to_ioobj(oa, ioobj);
         ioobj->ioo_bufcnt = niocount;
 
         LASSERT (page_count > 0);
@@ -851,7 +733,13 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
 
                 LASSERT(pg->count > 0);
                 LASSERT((pg->off & ~PAGE_MASK) + pg->count <= PAGE_SIZE);
-                LASSERT(i == 0 || pg->off > pg_prev->off);
+                LASSERTF(i == 0 || pg->off > pg_prev->off,
+                         "i %d p_c %u pg %p [pri %lu ind %lu] off "LPU64
+                         " prev_pg %p [pri %lu ind %lu] off "LPU64,
+                         i, page_count,
+                         pg->pg, pg->pg->private, pg->pg->index, pg->off,
+                         pg_prev->pg, pg_prev->pg->private, pg_prev->pg->index,
+                                 pg_prev->off);
 
                 rc = ptlrpc_prep_bulk_page(desc, pg->pg, pg->off & ~PAGE_MASK,
                                            pg->count);
@@ -872,11 +760,6 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
 
         LASSERT((void *)(niobuf - niocount) ==
                 lustre_msg_buf(req->rq_reqmsg, 2, niocount * sizeof(*niobuf)));
-#if CHECKSUM_BULK
-        body->oa.o_valid |= OBD_MD_FLCKSUM;
-        if (opc == OST_BRW_WRITE)
-                body->oa.o_nlink = cksum_pages(requested_nob, page_count, pga);
-#endif
         osc_announce_cached(cli, body);
         spin_lock_irqsave(&req->rq_lock, flags);
         req->rq_no_resend = 1;
@@ -884,6 +767,10 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
 
         /* size[0] still sizeof (*body) */
         if (opc == OST_WRITE) {
+#if CHECKSUM_BULK
+                body->oa.o_valid |= OBD_MD_FLCKSUM;
+                body->oa.o_nlink = cksum_pages(requested_nob, page_count, pga);
+#endif
                 /* 1 RC per niobuf */
                 size[1] = sizeof(__u32) * niocount;
                 req->rq_replen = lustre_msg_size(2, size);
@@ -942,34 +829,40 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa,
 
 #if CHECKSUM_BULK
         if (oa->o_valid & OBD_MD_FLCKSUM) {
+                const struct ptlrpc_peer *peer =
+                        &req->rq_import->imp_connection->c_peer;
                 static int cksum_counter;
                 obd_count server_cksum = oa->o_nlink;
                 obd_count cksum = cksum_pages(rc, page_count, pga);
+                char str[PTL_NALFMT_SIZE];
+
+                portals_nid2str(peer->peer_ni->pni_number, peer->peer_nid, str);
 
                 cksum_counter++;
                 if (server_cksum != cksum) {
-                        CERROR("Bad checksum: server "LPX64", client "LPX64
-                               ", server NID "LPX64"\n", server_cksum, cksum,
-                               imp->imp_connection->c_peer.peer_nid);
+                        CERROR("Bad checksum: server %x, client %x, server NID "
+                               LPX64" (%s)\n", server_cksum, cksum,
+                               peer->peer_nid, str);
                         cksum_counter = 0;
-                        oa->o_rdev = cksum;
-                } else if ((cksum_counter & (-cksum_counter)) == cksum_counter)
-                        CERROR("Checksum %u from "LPX64" OK: %x\n",
-                               cksum_counter,
-                               imp->imp_connection->c_peer.peer_nid, cksum);
+                        oa->o_nlink = cksum;
+                } else if ((cksum_counter & (-cksum_counter)) == cksum_counter){
+                        CWARN("Checksum %u from "LPX64" (%s) OK: %x\n",
+                              cksum_counter, peer->peer_nid, str, cksum);
+                }
         } else {
                 static int cksum_missed;
+
                 cksum_missed++;
                 if ((cksum_missed & (-cksum_missed)) == cksum_missed)
                         CERROR("Request checksum %u from "LPX64", no reply\n",
                                cksum_missed,
-                               imp->imp_connection->c_peer.peer_nid);
+                               req->rq_import->imp_connection->c_peer.peer_nid);
         }
 #endif
         return (0);
 }
 
-static int osc_brw_internal(int cmd, struct lustre_handle *conn,struct obdo *oa,
+static int osc_brw_internal(int cmd, struct obd_export *exp,struct obdo *oa,
                             struct lov_stripe_md *lsm,
                             obd_count page_count, struct brw_page *pga)
 {
@@ -980,7 +873,7 @@ static int osc_brw_internal(int cmd, struct lustre_handle *conn,struct obdo *oa,
         ENTRY;
 
 restart_bulk:
-        rc = osc_brw_prep_request(cmd, class_conn2cliimp(conn), oa, lsm,
+        rc = osc_brw_prep_request(cmd, class_exp2cliimp(exp), oa, lsm,
                                   page_count, pga, &requested_nob, &niocount,
                                   &request);
         /* NB ^ sets rq_no_resend */
@@ -1025,7 +918,7 @@ static int brw_interpret(struct ptlrpc_request *request,
         RETURN (rc);
 }
 
-static int async_internal(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int async_internal(int cmd, struct obd_export *exp, struct obdo *oa,
                           struct lov_stripe_md *lsm, obd_count page_count,
                           struct brw_page *pga, struct ptlrpc_request_set *set)
 {
@@ -1036,7 +929,7 @@ static int async_internal(int cmd, struct lustre_handle *conn, struct obdo *oa,
         int                        rc;
         ENTRY;
 
-        rc = osc_brw_prep_request(cmd, class_conn2cliimp(conn), oa, lsm,
+        rc = osc_brw_prep_request(cmd, class_exp2cliimp(exp), oa, lsm,
                                   page_count, pga, &requested_nob, &nio_count,
                                   &request);
         /* NB ^ sets rq_no_resend */
@@ -1115,7 +1008,7 @@ static obd_count check_elan_limit(struct brw_page *pg, obd_count pages)
         return i;
 }
 
-static int osc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int osc_brw(int cmd, struct obd_export *exp, struct obdo *oa,
                    struct lov_stripe_md *md, obd_count page_count,
                    struct brw_page *pga, struct obd_trans_info *oti)
 {
@@ -1124,7 +1017,7 @@ static int osc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
         if (cmd == OBD_BRW_CHECK) {
                 /* The caller just wants to know if there's a chance that this
                  * I/O can succeed */
-                struct obd_import *imp = class_conn2cliimp(conn);
+                struct obd_import *imp = class_exp2cliimp(exp);
 
                 if (imp == NULL || imp->imp_invalid)
                         RETURN(-EIO);
@@ -1143,7 +1036,7 @@ static int osc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 sort_brw_pages(pga, pages_per_brw);
                 pages_per_brw = check_elan_limit(pga, pages_per_brw);
 
-                rc = osc_brw_internal(cmd, conn, oa, md, pages_per_brw, pga);
+                rc = osc_brw_internal(cmd, exp, oa, md, pages_per_brw, pga);
 
                 if (rc != 0)
                         RETURN(rc);
@@ -1154,7 +1047,7 @@ static int osc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
         RETURN(0);
 }
 
-static int osc_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int osc_brw_async(int cmd, struct obd_export *exp, struct obdo *oa,
                          struct lov_stripe_md *md, obd_count page_count,
                          struct brw_page *pga, struct ptlrpc_request_set *set,
                          struct obd_trans_info *oti)
@@ -1164,7 +1057,7 @@ static int osc_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
         if (cmd == OBD_BRW_CHECK) {
                 /* The caller just wants to know if there's a chance that this
                  * I/O can succeed */
-                struct obd_import *imp = class_conn2cliimp(conn);
+                struct obd_import *imp = class_exp2cliimp(exp);
 
                 if (imp == NULL || imp->imp_invalid)
                         RETURN(-EIO);
@@ -1183,7 +1076,7 @@ static int osc_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
                 sort_brw_pages(pga, pages_per_brw);
                 pages_per_brw = check_elan_limit(pga, pages_per_brw);
 
-                rc = async_internal(cmd, conn, oa, md, pages_per_brw, pga, set);
+                rc = async_internal(cmd, exp, oa, md, pages_per_brw, pga, set);
 
                 if (rc != 0)
                         RETURN(rc);
@@ -1194,101 +1087,854 @@ static int osc_brw_async(int cmd, struct lustre_handle *conn, struct obdo *oa,
         RETURN(0);
 }
 
-#ifdef __KERNEL__
-/* Note: caller will lock/unlock, and set uptodate on the pages */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int sanosc_brw_read(struct lustre_handle *conn, struct obdo *oa,
-                           struct lov_stripe_md *lsm, obd_count page_count,
-                           struct brw_page *pga)
+static void osc_check_rpcs(struct client_obd *cli);
+static void osc_exit_cache(struct client_obd *cli, struct osc_async_page *oap);
+
+static void osc_complete_oap(struct client_obd *cli,
+                             struct osc_async_page *oap, int rc)
 {
-        struct ptlrpc_request *request = NULL;
-        struct ost_body *body;
-        struct niobuf_remote *nioptr;
-        struct obd_ioobj *iooptr;
-        int rc, size[3] = {sizeof(*body)}, mapped = 0;
-        int swab;
         ENTRY;
+        osc_exit_cache(cli, oap);
+        oap->oap_async_flags = 0;
+        if (oap->oap_osic) {
+                osic_complete_one(oap->oap_osic, rc);
+                oap->oap_osic = NULL;
+                EXIT;
+                return;
+        }
 
-        /* XXX does not handle 'new' brw protocol */
+        oap->oap_caller_ops->ap_completion(oap->oap_caller_data, oap->oap_cmd,
+                                           rc);
+        EXIT;
+}
 
-        size[1] = sizeof(struct obd_ioobj);
-        size[2] = page_count * sizeof(*nioptr);
+static int brw_interpret_oap(struct ptlrpc_request *request,
+                             struct osc_brw_async_args *aa, int rc)
+{
+        struct osc_async_page *oap;
+        struct client_obd *cli;
+        struct list_head *pos, *n;
+        ENTRY;
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SAN_READ, 3,
-                                  size, NULL);
-        if (!request)
-                RETURN(-ENOMEM);
+        CDEBUG(D_INODE, "request %p aa %p\n", request, aa);
 
-        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*body));
-        iooptr = lustre_msg_buf(request->rq_reqmsg, 1, sizeof(*iooptr));
-        nioptr = lustre_msg_buf(request->rq_reqmsg, 2,
-                                sizeof(*nioptr) * page_count);
+        rc = osc_brw_fini_request(request, aa->aa_oa, aa->aa_requested_nob,
+                                  aa->aa_nio_count, aa->aa_page_count,
+                                  aa->aa_pga, rc);
 
-        memcpy(&body->oa, oa, sizeof(body->oa));
+        cli = aa->aa_cli;
+        /* in failout recovery we ignore writeback failure and want
+         * to just tell llite to unlock the page and continue */
+        if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
+                rc = 0;
 
-        iooptr->ioo_id = oa->o_id;
-        iooptr->ioo_gr = oa->o_valid & 0 ? oa->o_gr : 0;
-        iooptr->ioo_type = oa->o_mode;
-        iooptr->ioo_bufcnt = page_count;
+        spin_lock(&cli->cl_loi_list_lock);
 
-        for (mapped = 0; mapped < page_count; mapped++, nioptr++) {
-                LASSERT(PageLocked(pga[mapped].pg));
-                LASSERT(mapped == 0 || pga[mapped].off > pga[mapped - 1].off);
+        /* the caller may re-use the oap after the completion call so
+         * we need to clean it up a little */
+        list_for_each_safe(pos, n, &aa->aa_oaps) {
+                oap = list_entry(pos, struct osc_async_page, oap_rpc_item);
 
-                nioptr->offset = pga[mapped].off;
-                nioptr->len    = pga[mapped].count;
-                nioptr->flags  = pga[mapped].flag;
+                //CDEBUG(D_INODE, "page %p index %lu oap %p\n",
+                       //oap->oap_page, oap->oap_page->index, oap);
+
+                list_del_init(&oap->oap_rpc_item);
+                osc_complete_oap(cli, oap, rc);
         }
 
-        size[1] = page_count * sizeof(*nioptr);
-        request->rq_replen = lustre_msg_size(2, size);
+        cli->cl_brw_in_flight--;
+        osc_check_rpcs(cli);
 
-        rc = ptlrpc_queue_wait(request);
-        if (rc)
-                GOTO(out_req, rc);
+        spin_unlock(&cli->cl_loi_list_lock);
 
-        body = lustre_swab_repbuf(request, 0, sizeof(*body),
-                                  lustre_swab_ost_body);
-        if (body == NULL) {
-                CERROR("Can't unpack body\n");
-                GOTO(out_req, rc = -EPROTO);
-        }
+        obdo_free(aa->aa_oa);
+        OBD_FREE(aa->aa_pga, aa->aa_page_count * sizeof(struct brw_page));
 
-        memcpy(oa, &body->oa, sizeof(*oa));
+        RETURN(0);
+}
 
-        swab = lustre_msg_swabbed(request->rq_repmsg);
-        LASSERT_REPSWAB(request, 1);
-        nioptr = lustre_msg_buf(request->rq_repmsg, 1, size[1]);
-        if (!nioptr) {
-                /* nioptr missing or short */
-                GOTO(out_req, rc = -EPROTO);
+static struct ptlrpc_request *osc_build_req(struct client_obd *cli,
+                                            struct list_head *rpc_list,
+                                            int page_count, int cmd)
+{
+        struct ptlrpc_request *req;
+        struct brw_page *pga = NULL;
+        int requested_nob, nio_count;
+        struct osc_brw_async_args *aa;
+        struct obdo *oa = NULL;
+        struct obd_async_page_ops *ops = NULL;
+        void *caller_data = NULL;
+        struct list_head *pos;
+        int i, rc;
+
+        LASSERT(!list_empty(rpc_list));
+
+        OBD_ALLOC(pga, sizeof(*pga) * page_count);
+        if (pga == NULL)
+                RETURN(ERR_PTR(-ENOMEM));
+
+        oa = obdo_alloc();
+        if (oa == NULL)
+                GOTO(out, req = ERR_PTR(-ENOMEM));
+
+        i = 0;
+        list_for_each(pos, rpc_list) {
+                struct osc_async_page *oap;
+
+                oap = list_entry(pos, struct osc_async_page, oap_rpc_item);
+                if (ops == NULL) {
+                        ops = oap->oap_caller_ops;
+                        caller_data = oap->oap_caller_data;
+                }
+                pga[i].off = oap->oap_obj_off + oap->oap_page_off;
+                pga[i].pg = oap->oap_page;
+                pga[i].count = oap->oap_count;
+                pga[i].flag = oap->oap_brw_flags;
+                //CDEBUG(D_INODE, "putting page %p index %lu oap %p into pga\n",
+                       //pga[i].pg, oap->oap_page->index, oap);
+                i++;
         }
 
-        /* actual read */
-        for (mapped = 0; mapped < page_count; mapped++, nioptr++) {
-                struct page *page = pga[mapped].pg;
-                struct buffer_head *bh;
-                kdev_t dev;
-
-                if (swab)
-                        lustre_swab_niobuf_remote (nioptr);
+        /* always get the data for the obdo for the rpc */
+        LASSERT(ops != NULL);
+        ops->ap_fill_obdo(caller_data, cmd, oa);
 
-                /* got san device associated */
-                LASSERT(class_conn2obd(conn));
-                dev = class_conn2obd(conn)->u.cli.cl_sandev;
+        sort_brw_pages(pga, page_count);
+        rc = osc_brw_prep_request(cmd, cli->cl_import, oa, NULL, page_count,
+                                  pga, &requested_nob, &nio_count, &req);
+        if (rc != 0) {
+                CERROR("prep_req failed: %d\n", rc);
+                GOTO(out, req = ERR_PTR(rc));
+        }
 
-                /* hole */
-                if (!nioptr->offset) {
-                        CDEBUG(D_PAGE, "hole at ino %lu; index %ld\n",
-                                        page->mapping->host->i_ino,
-                                        page->index);
-                        memset(page_address(page), 0, PAGE_SIZE);
-                        continue;
-                }
+        LASSERT(sizeof(*aa) <= sizeof(req->rq_async_args));
+        aa = (struct osc_brw_async_args *)&req->rq_async_args;
+        aa->aa_oa = oa;
+        aa->aa_requested_nob = requested_nob;
+        aa->aa_nio_count = nio_count;
+        aa->aa_page_count = page_count;
+        aa->aa_pga = pga;
+        aa->aa_cli = cli;
 
-                if (!page->buffers) {
-                        create_empty_buffers(page, dev, PAGE_SIZE);
-                        bh = page->buffers;
+out:
+        if (IS_ERR(req)) {
+                if (oa)
+                        obdo_free(oa);
+                if (pga)
+                        OBD_FREE(pga, sizeof(*pga) * page_count);
+        }
+        RETURN(req);
+}
+
+static void lop_update_pending(struct client_obd *cli,
+                               struct loi_oap_pages *lop, int cmd, int delta)
+{
+        lop->lop_num_pending += delta;
+        if (cmd == OBD_BRW_WRITE)
+                cli->cl_pending_w_pages += delta;
+        else
+                cli->cl_pending_r_pages += delta;
+}
+
+/* the loi lock is held across this function but it's allowed to release
+ * and reacquire it during its work */
+static int osc_send_oap_rpc(struct client_obd *cli, int cmd,
+                            struct loi_oap_pages *lop)
+{
+        struct ptlrpc_request *request;
+        obd_count page_count = 0;
+        struct list_head *tmp, *pos;
+        struct osc_async_page *oap = NULL;
+        struct osc_brw_async_args *aa;
+        struct obd_async_page_ops *ops;
+        LIST_HEAD(rpc_list);
+        ENTRY;
+
+        /* first we find the pages we're allowed to work with */
+        list_for_each_safe(pos, tmp, &lop->lop_pending) {
+                oap = list_entry(pos, struct osc_async_page, oap_pending_item);
+                ops = oap->oap_caller_ops;
+
+                /* in llite being 'ready' equates to the page being locked
+                 * until completion unlocks it.  commit_write submits a page
+                 * as not ready because its unlock will happen unconditionally
+                 * as the call returns.  if we race with commit_write giving
+                 * us that page we dont' want to create a hole in the page
+                 * stream, so we stop and leave the rpc to be fired by
+                 * another dirtier or kupdated interval (the not ready page
+                 * will still be on the dirty list).  we could call in
+                 * at the end of ll_file_write to process the queue again. */
+                if (!(oap->oap_async_flags & ASYNC_READY)) {
+                        if (ops->ap_make_ready(oap->oap_caller_data, cmd)) {
+                                CDEBUG(D_INODE, "oap at page_count %d not "
+                                                "ready\n", page_count);
+                                break;
+                        }
+                        oap->oap_async_flags |= ASYNC_READY;
+                }
+
+                /* take the page out of our book-keeping */
+                list_del_init(&oap->oap_pending_item);
+                lop_update_pending(cli, lop, cmd, -1);
+                if (!list_empty(&oap->oap_urgent_item))
+                        list_del_init(&oap->oap_urgent_item);
+
+                /* ask the caller for the size of the io as the rpc leaves. */
+                if (!(oap->oap_async_flags & ASYNC_COUNT_STABLE))
+                        oap->oap_count = ops->ap_refresh_count(
+                                                        oap->oap_caller_data,
+                                                        cmd);
+                if (oap->oap_count <= 0) {
+                        CDEBUG(D_INODE, "oap %p count %d, completing\n", oap,
+                               oap->oap_count);
+                        osc_complete_oap(cli, oap, oap->oap_count);
+                        continue;
+                }
+
+                /* now put the page back in our accounting */
+                list_add_tail(&oap->oap_rpc_item, &rpc_list);
+                if (++page_count >= cli->cl_max_pages_per_rpc)
+                        break;
+        }
+
+        if (page_count == 0)
+                RETURN(0);
+
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        request = osc_build_req(cli, &rpc_list, page_count, cmd);
+        if (IS_ERR(request)) {
+                /* this should happen rarely and is pretty bad, it makes the
+                 * pending list not follow the dirty order */
+                spin_lock(&cli->cl_loi_list_lock);
+                list_for_each_safe(pos, tmp, &rpc_list) {
+                        oap = list_entry(pos, struct osc_async_page,
+                                         oap_rpc_item);
+                        list_del_init(&oap->oap_rpc_item);
+                        list_add_tail(&oap->oap_pending_item,
+                                      &lop->lop_pending);
+                        lop_update_pending(cli, lop, cmd, 1);
+                        if (oap->oap_async_flags & ASYNC_URGENT)
+                                list_add(&oap->oap_urgent_item,
+                                         &lop->lop_urgent);
+                }
+                RETURN(PTR_ERR(request));
+        }
+
+        LASSERT(sizeof(*aa) <= sizeof(request->rq_async_args));
+        aa = (struct osc_brw_async_args *)&request->rq_async_args;
+        INIT_LIST_HEAD(&aa->aa_oaps);
+        list_splice(&rpc_list, &aa->aa_oaps);
+        INIT_LIST_HEAD(&rpc_list);
+
+        if (cmd == OBD_BRW_READ)
+                lproc_osc_hist_pow2(&cli->cl_read_page_hist, page_count);
+        else 
+                lproc_osc_hist_pow2(&cli->cl_write_page_hist, page_count);
+
+        spin_lock(&cli->cl_loi_list_lock);
+        if (cmd == OBD_BRW_READ)
+                lproc_osc_hist(&cli->cl_read_rpc_hist, cli->cl_brw_in_flight);
+        else 
+                lproc_osc_hist(&cli->cl_write_rpc_hist, cli->cl_brw_in_flight);
+
+        cli->cl_brw_in_flight++;
+        CDEBUG(D_INODE, "req %p: %d pages, aa %p.  now %d in flight\n", request,
+               page_count, aa, cli->cl_brw_in_flight);
+
+        request->rq_interpret_reply = brw_interpret_oap;
+        osc_rpcd_add_req(request);
+        RETURN(1);
+}
+
+static int lop_makes_rpc(struct client_obd *cli, struct loi_oap_pages *lop,
+                         int cmd)
+{
+        int optimal;
+        ENTRY;
+
+        /* stream rpcs until we complete the urgent pages in the object */
+        if (!list_empty(&lop->lop_urgent))
+                RETURN(1);
+
+        /* fire off rpcs when we have 'optimal' rpcs as tuned for the wire. */
+        optimal = cli->cl_max_pages_per_rpc;
+        /* *2 to avoid triggering rpcs that would want to include pages that
+         * are being queued but which can't be made ready until the queuer
+         * finishes with the page. this is a wart for llite::commit_write() */
+        if (cmd == OBD_BRW_WRITE)
+                optimal *= 2;
+        if (lop->lop_num_pending >= optimal)
+                RETURN(1);
+
+        /* trigger a write rpc stream as long as there are dirtiers waiting
+         * for space.  as they're waiting, they're not going to create more
+         * pages to coallesce with what's waiting.. */
+        if (!list_empty(&cli->cl_cache_waiters))
+                RETURN(1);
+
+        RETURN(0);
+}
+
+static int loi_makes_rpc(struct client_obd *cli, struct lov_oinfo *loi)
+{
+        return lop_makes_rpc(cli, &loi->loi_write_lop, OBD_BRW_WRITE) ||
+               lop_makes_rpc(cli, &loi->loi_read_lop, OBD_BRW_READ);
+}
+
+static void loi_onto_ready_list(struct client_obd *cli, struct lov_oinfo *loi)
+{
+        if (list_empty(&loi->loi_cli_item) && loi_makes_rpc(cli, loi))
+                list_add_tail(&loi->loi_cli_item, &cli->cl_loi_ready_list);
+}
+
+#define LOI_DEBUG(LOI, STR, args...) \
+        CDEBUG(D_INODE, "loi rdy %d [%p,%p] wr %d:%d rd %d:%d " STR, \
+               !list_empty(&(LOI)->loi_cli_item),                  \
+               (LOI)->loi_cli_item.next,                  \
+               (LOI)->loi_cli_item.prev,                  \
+               (LOI)->loi_write_lop.lop_num_pending,                     \
+               !list_empty(&(LOI)->loi_write_lop.lop_urgent),         \
+               (LOI)->loi_read_lop.lop_num_pending,                      \
+               !list_empty(&(LOI)->loi_read_lop.lop_urgent),         \
+               args)                       \
+
+/* called with the loi list lock held */
+static void osc_check_rpcs(struct client_obd *cli)
+{
+        struct lov_oinfo *loi;
+        int rc = 0, making_progress;
+        ENTRY;
+
+        if (list_empty(&cli->cl_loi_ready_list)) {
+                CDEBUG(D_INODE, "no lois ready\n");
+                EXIT;
+                return;
+        }
+
+        while (!list_empty(&cli->cl_loi_ready_list)) {
+                loi = list_entry(cli->cl_loi_ready_list.next, struct lov_oinfo,
+                                 loi_cli_item);
+
+                if (cli->cl_brw_in_flight >= cli->cl_max_rpcs_in_flight)
+                        break;
+
+                making_progress = 0;
+
+                /* hmm, it occurs to me that having rpc preparation fail
+                 * with num_pending == num_urgent means that there won't
+                 * be any more calls into here unless other traffic comes
+                 * in.  hmm. */
+
+                /* attempt some read/write balancing by alternating between
+                 * reads and writes in an object */
+                if (lop_makes_rpc(cli, &loi->loi_write_lop, OBD_BRW_WRITE)) {
+                        rc = osc_send_oap_rpc(cli, OBD_BRW_WRITE,
+                                              &loi->loi_write_lop);
+                        if (rc < 0)
+                                break;
+                        if (rc > 0)
+                                making_progress++;
+                }
+                if (lop_makes_rpc(cli, &loi->loi_read_lop, OBD_BRW_READ)) {
+                        rc = osc_send_oap_rpc(cli, OBD_BRW_READ,
+                                              &loi->loi_read_lop);
+                        if (rc < 0)
+                                break;
+                        if (rc > 0)
+                                making_progress++;
+                }
+
+                /* attempt some inter-object balancing by issueing rpcs
+                 * for each object in turn */
+                if (!list_empty(&loi->loi_cli_item))
+                        list_del_init(&loi->loi_cli_item);
+
+                loi_onto_ready_list(cli, loi);
+
+                LOI_DEBUG(loi, "mp %d\n", making_progress);
+
+                /* could be smarter, !making_progress can happen in theory
+                 * if all the pages can not be locked in set_io_ready */
+                if (!making_progress)
+                        break;
+        }
+        EXIT;
+}
+
+/* we're trying to queue a page in the osc so we're subject to the
+ * 'cl_dirty_max' limit on the number of pages that can be queued in the osc.
+ * If the osc's queued pages are already at that limit, then we want to sleep
+ * until there is space in the osc's queue for us.  we need this goofy
+ * little struct to really tell that our allocation was fulfilled in
+ * the presence of pending signals */
+struct osc_cache_waiter {
+        struct list_head        ocw_entry;
+        wait_queue_head_t       ocw_waitq;
+};
+static int ocw_granted(struct client_obd *cli, struct osc_cache_waiter *ocw)
+{
+        int rc;
+        ENTRY;
+        spin_lock(&cli->cl_loi_list_lock);
+        rc = list_empty(&ocw->ocw_entry);
+        spin_unlock(&cli->cl_loi_list_lock);
+        RETURN(rc);
+};
+static int osc_enter_cache(struct client_obd *cli, struct lov_oinfo *loi,
+                           struct osc_async_page *oap)
+{
+        struct osc_cache_waiter ocw;
+        struct l_wait_info lwi = {0};
+        int rc = 0;
+        ENTRY;
+
+        /* XXX check for ost grants here as well.. for now we ignore them. */
+        if (cli->cl_dirty_max < PAGE_SIZE)
+                RETURN(-EDQUOT);
+
+        /* if we fail this test then cl_dirty contains at least one page
+         * that will have to be completed after we release the lock */
+        if (cli->cl_dirty + PAGE_SIZE <= cli->cl_dirty_max) {
+                /* account for ourselves */
+                cli->cl_dirty += PAGE_SIZE;
+                GOTO(out, rc = 0);
+        }
+
+        init_waitqueue_head(&ocw.ocw_waitq);
+        list_add_tail(&ocw.ocw_entry, &cli->cl_cache_waiters);
+
+        /* make sure that there are write rpcs in flight to wait for. this
+         * is a little silly as this object may not have any pending
+         * but other objects sure might. this should probably be cleaned. */
+        loi_onto_ready_list(cli, loi);
+        osc_check_rpcs(cli);
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        CDEBUG(D_INODE, "sleeping for cache space\n");
+        l_wait_event(ocw.ocw_waitq, ocw_granted(cli, &ocw), &lwi);
+
+        spin_lock(&cli->cl_loi_list_lock);
+        if (!list_empty(&ocw.ocw_entry)) {
+                rc = -EINTR;
+                list_del(&ocw.ocw_entry);
+        }
+        GOTO(out, rc);
+out:
+        if (rc == 0)
+                oap->oap_brw_flags |= OBD_BRW_FROM_GRANT;
+        return rc;
+}
+
+/* the companion to enter_cache, called when an oap is now longer part of the
+ * dirty accounting.. so writeback completes or truncate happens before writing
+ * starts.  must be called with the loi lock held. */
+static void osc_exit_cache(struct client_obd *cli, struct osc_async_page *oap)
+{
+        struct osc_cache_waiter *ocw;
+        ENTRY;
+
+        if (!(oap->oap_brw_flags & OBD_BRW_FROM_GRANT)) {
+                EXIT;
+                return;
+        }
+
+        if (list_empty(&cli->cl_cache_waiters)) {
+                cli->cl_dirty -= PAGE_SIZE;
+        } else {
+                ocw = list_entry(cli->cl_cache_waiters.next,
+                                 struct osc_cache_waiter, ocw_entry);
+                list_del_init(&ocw->ocw_entry);
+                wake_up(&ocw->ocw_waitq);
+        }
+
+        oap->oap_brw_flags &= ~OBD_BRW_FROM_GRANT;
+        EXIT;
+}
+
+int osc_prep_async_page(struct obd_export *exp, struct lov_stripe_md *lsm,
+                        struct lov_oinfo *loi, struct page *page,
+                        obd_off offset, struct obd_async_page_ops *ops,
+                        void *data, void **res)
+{
+        struct osc_async_page *oap;
+        ENTRY;
+
+        OBD_ALLOC(oap, sizeof(*oap));
+        if (oap == NULL)
+                return -ENOMEM;
+
+        oap->oap_magic = OAP_MAGIC;
+        oap->oap_caller_ops = ops;
+        oap->oap_caller_data = data;
+
+        oap->oap_page = page;
+        oap->oap_obj_off = offset;
+
+        INIT_LIST_HEAD(&oap->oap_pending_item);
+        INIT_LIST_HEAD(&oap->oap_urgent_item);
+        INIT_LIST_HEAD(&oap->oap_rpc_item);
+
+        CDEBUG(D_CACHE, "oap %p page %p obj off "LPU64"\n", oap, page, offset);
+        *res = oap;
+        RETURN(0);
+}
+
+struct osc_async_page *oap_from_cookie(void *cookie)
+{
+        struct osc_async_page *oap = cookie;
+        if (oap->oap_magic != OAP_MAGIC)
+                return ERR_PTR(-EINVAL);
+        return oap;
+};
+
+static int osc_queue_async_io(struct obd_export *exp, struct lov_stripe_md *lsm,
+                              struct lov_oinfo *loi, void *cookie,
+                              int cmd, obd_off off, int count,
+                              obd_flag brw_flags, enum async_flags async_flags)
+{
+        struct client_obd *cli = &exp->exp_obd->u.cli;
+        struct osc_async_page *oap;
+        struct loi_oap_pages *lop;
+        int rc;
+        ENTRY;
+
+        oap = oap_from_cookie(cookie);
+        if (IS_ERR(oap))
+                RETURN(PTR_ERR(oap));
+
+        if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
+                RETURN(-EIO);
+
+        if (!list_empty(&oap->oap_pending_item) ||
+            !list_empty(&oap->oap_urgent_item) ||
+            !list_empty(&oap->oap_rpc_item))
+                RETURN(-EBUSY);
+
+        if (loi == NULL)
+                loi = &lsm->lsm_oinfo[0];
+
+        spin_lock(&cli->cl_loi_list_lock);
+
+        oap->oap_cmd = cmd;
+        oap->oap_async_flags = async_flags;
+        oap->oap_page_off = off;
+        oap->oap_count = count;
+        oap->oap_brw_flags = brw_flags;
+
+        if (cmd == OBD_BRW_WRITE) {
+                rc = osc_enter_cache(cli, loi, oap);
+                if (rc) {
+                        spin_unlock(&cli->cl_loi_list_lock);
+                        RETURN(rc);
+                }
+                lop = &loi->loi_write_lop;
+        } else {
+                lop = &loi->loi_read_lop;
+        }
+
+        if (oap->oap_async_flags & ASYNC_URGENT)
+                list_add(&oap->oap_urgent_item, &lop->lop_urgent);
+        list_add_tail(&oap->oap_pending_item, &lop->lop_pending);
+        lop_update_pending(cli, lop, cmd, 1);
+
+        loi_onto_ready_list(cli, loi);
+
+        LOI_DEBUG(loi, "oap %p page %p added for cmd %d\n", oap, oap->oap_page,
+                  cmd);
+
+        osc_check_rpcs(cli);
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        RETURN(0);
+}
+
+/* aka (~was & now & flag), but this is more clear :) */
+#define SETTING(was, now, flag) (!(was & flag) && (now & flag))
+
+static int osc_set_async_flags(struct obd_export *exp,
+                               struct lov_stripe_md *lsm,
+                               struct lov_oinfo *loi, void *cookie,
+                               obd_flag async_flags)
+{
+        struct client_obd *cli = &exp->exp_obd->u.cli;
+        struct loi_oap_pages *lop;
+        struct osc_async_page *oap;
+        int rc = 0;
+        ENTRY;
+
+        oap = oap_from_cookie(cookie);
+        if (IS_ERR(oap))
+                RETURN(PTR_ERR(oap));
+
+        if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
+                RETURN(-EIO);
+
+        if (loi == NULL)
+                loi = &lsm->lsm_oinfo[0];
+
+        if (oap->oap_cmd == OBD_BRW_WRITE) {
+                lop = &loi->loi_write_lop;
+        } else {
+                lop = &loi->loi_read_lop;
+        }
+
+        spin_lock(&cli->cl_loi_list_lock);
+
+        if (oap->oap_async_flags == async_flags)
+                GOTO(out, rc = 0);
+
+        if (SETTING(oap->oap_async_flags, async_flags, ASYNC_READY))
+                oap->oap_async_flags |= ASYNC_READY;
+
+        if (SETTING(oap->oap_async_flags, async_flags, ASYNC_URGENT)) {
+                if (list_empty(&oap->oap_rpc_item)) {
+                        list_add(&oap->oap_urgent_item, &lop->lop_urgent);
+                        loi_onto_ready_list(cli, loi);
+                }
+        }
+
+        LOI_DEBUG(loi, "oap %p page %p has flags %x\n", oap, oap->oap_page,
+                        oap->oap_async_flags);
+out:
+        osc_check_rpcs(cli);
+        spin_unlock(&cli->cl_loi_list_lock);
+        RETURN(rc);
+}
+
+static int osc_queue_sync_io(struct obd_export *exp, struct lov_stripe_md *lsm,
+                             struct lov_oinfo *loi,
+                             struct obd_sync_io_container *osic, void *cookie,
+                             int cmd, obd_off off, int count,
+                             obd_flag brw_flags)
+{
+        struct client_obd *cli = &exp->exp_obd->u.cli;
+        struct osc_async_page *oap;
+        struct loi_oap_pages *lop;
+        ENTRY;
+
+        oap = oap_from_cookie(cookie);
+        if (IS_ERR(oap))
+                RETURN(PTR_ERR(oap));
+
+        if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
+                RETURN(-EIO);
+
+        if (!list_empty(&oap->oap_pending_item) ||
+            !list_empty(&oap->oap_urgent_item) ||
+            !list_empty(&oap->oap_rpc_item))
+                RETURN(-EBUSY);
+
+        if (loi == NULL)
+                loi = &lsm->lsm_oinfo[0];
+
+        spin_lock(&cli->cl_loi_list_lock);
+
+        oap->oap_cmd = cmd;
+        oap->oap_page_off = off;
+        oap->oap_count = count;
+        oap->oap_brw_flags = brw_flags;
+
+        if (cmd == OBD_BRW_WRITE)
+                lop = &loi->loi_write_lop;
+        else
+                lop = &loi->loi_read_lop;
+
+        list_add_tail(&oap->oap_pending_item, &lop->lop_pending_sync);
+        oap->oap_osic = osic;
+        osic_add_one(osic);
+
+        LOI_DEBUG(loi, "oap %p page %p on sync pending\n", oap, oap->oap_page);
+
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        RETURN(0);
+}
+
+static void osc_sync_to_pending(struct client_obd *cli, struct lov_oinfo *loi,
+                                struct loi_oap_pages *lop, int cmd)
+{
+        struct list_head *pos, *tmp;
+        struct osc_async_page *oap;
+
+        list_for_each_safe(pos, tmp, &lop->lop_pending_sync) {
+                oap = list_entry(pos, struct osc_async_page, oap_pending_item);
+                list_del(&oap->oap_pending_item);
+                oap->oap_async_flags |= ASYNC_READY | ASYNC_URGENT |
+                                        ASYNC_COUNT_STABLE;
+                list_add_tail(&oap->oap_pending_item, &lop->lop_pending);
+                list_add(&oap->oap_urgent_item, &lop->lop_urgent);
+                lop_update_pending(cli, lop, cmd, 1);
+        }
+        loi_onto_ready_list(cli, loi);
+}
+
+static int osc_trigger_sync_io(struct obd_export *exp,
+                               struct lov_stripe_md *lsm,
+                               struct lov_oinfo *loi,
+                               struct obd_sync_io_container *osic)
+{
+        struct client_obd *cli = &exp->exp_obd->u.cli;
+        ENTRY;
+
+        if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
+                RETURN(-EIO);
+
+        if (loi == NULL)
+                loi = &lsm->lsm_oinfo[0];
+
+        spin_lock(&cli->cl_loi_list_lock);
+
+        osc_sync_to_pending(cli, loi, &loi->loi_write_lop, OBD_BRW_WRITE);
+        osc_sync_to_pending(cli, loi, &loi->loi_read_lop, OBD_BRW_READ);
+
+        osc_check_rpcs(cli);
+        spin_unlock(&cli->cl_loi_list_lock);
+
+        RETURN(0);
+}
+
+static int osc_teardown_async_page(struct obd_export *exp,
+                                   struct lov_stripe_md *lsm,
+                                   struct lov_oinfo *loi, void *cookie)
+{
+        struct client_obd *cli = &exp->exp_obd->u.cli;
+        struct loi_oap_pages *lop;
+        struct osc_async_page *oap;
+        int rc = 0;
+        ENTRY;
+
+        oap = oap_from_cookie(cookie);
+        if (IS_ERR(oap))
+                RETURN(PTR_ERR(oap));
+
+        if (loi == NULL)
+                loi = &lsm->lsm_oinfo[0];
+
+        if (oap->oap_cmd == OBD_BRW_WRITE) {
+                lop = &loi->loi_write_lop;
+        } else {
+                lop = &loi->loi_read_lop;
+        }
+
+        spin_lock(&cli->cl_loi_list_lock);
+
+        osc_exit_cache(cli, oap);
+
+        if (!list_empty(&oap->oap_rpc_item))
+                GOTO(out, rc = -EBUSY);
+
+        if (!list_empty(&oap->oap_urgent_item)) {
+                list_del_init(&oap->oap_urgent_item);
+                oap->oap_async_flags &= ~ASYNC_URGENT;
+        }
+        if (!list_empty(&oap->oap_pending_item)) {
+                list_del_init(&oap->oap_pending_item);
+                lop_update_pending(cli, lop, oap->oap_cmd, -1);
+        }
+        if (!list_empty(&loi->loi_cli_item) && !loi_makes_rpc(cli, loi))
+                list_del_init(&loi->loi_cli_item);
+
+        LOI_DEBUG(loi, "oap %p page %p torn down\n", oap, oap->oap_page);
+out:
+        spin_unlock(&cli->cl_loi_list_lock);
+        OBD_FREE(oap, sizeof(*oap));
+        RETURN(rc);
+}
+
+#ifdef __KERNEL__
+/* Note: caller will lock/unlock, and set uptodate on the pages */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static int sanosc_brw_read(struct obd_export *exp, struct obdo *oa,
+                           struct lov_stripe_md *lsm, obd_count page_count,
+                           struct brw_page *pga)
+{
+        struct ptlrpc_request *request = NULL;
+        struct ost_body *body;
+        struct niobuf_remote *nioptr;
+        struct obd_ioobj *iooptr;
+        int rc, size[3] = {sizeof(*body)}, mapped = 0;
+        int swab;
+        ENTRY;
+
+        /* XXX does not handle 'new' brw protocol */
+
+        size[1] = sizeof(struct obd_ioobj);
+        size[2] = page_count * sizeof(*nioptr);
+
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_SAN_READ, 3,
+                                  size, NULL);
+        if (!request)
+                RETURN(-ENOMEM);
+
+        body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*body));
+        iooptr = lustre_msg_buf(request->rq_reqmsg, 1, sizeof(*iooptr));
+        nioptr = lustre_msg_buf(request->rq_reqmsg, 2,
+                                sizeof(*nioptr) * page_count);
+
+        memcpy(&body->oa, oa, sizeof(body->oa));
+
+        obdo_to_ioobj(oa, iooptr);
+        iooptr->ioo_bufcnt = page_count;
+
+        for (mapped = 0; mapped < page_count; mapped++, nioptr++) {
+                LASSERT(PageLocked(pga[mapped].pg));
+                LASSERT(mapped == 0 || pga[mapped].off > pga[mapped - 1].off);
+
+                nioptr->offset = pga[mapped].off;
+                nioptr->len    = pga[mapped].count;
+                nioptr->flags  = pga[mapped].flag;
+        }
+
+        size[1] = page_count * sizeof(*nioptr);
+        request->rq_replen = lustre_msg_size(2, size);
+
+        rc = ptlrpc_queue_wait(request);
+        if (rc)
+                GOTO(out_req, rc);
+
+        body = lustre_swab_repbuf(request, 0, sizeof(*body),
+                                  lustre_swab_ost_body);
+        if (body == NULL) {
+                CERROR("Can't unpack body\n");
+                GOTO(out_req, rc = -EPROTO);
+        }
+
+        memcpy(oa, &body->oa, sizeof(*oa));
+
+        swab = lustre_msg_swabbed(request->rq_repmsg);
+        LASSERT_REPSWAB(request, 1);
+        nioptr = lustre_msg_buf(request->rq_repmsg, 1, size[1]);
+        if (!nioptr) {
+                /* nioptr missing or short */
+                GOTO(out_req, rc = -EPROTO);
+        }
+
+        /* actual read */
+        for (mapped = 0; mapped < page_count; mapped++, nioptr++) {
+                struct page *page = pga[mapped].pg;
+                struct buffer_head *bh;
+                kdev_t dev;
+
+                if (swab)
+                        lustre_swab_niobuf_remote (nioptr);
+
+                /* got san device associated */
+                LASSERT(exp->exp_obd != NULL);
+                dev = exp->exp_obd->u.cli.cl_sandev;
+
+                /* hole */
+                if (!nioptr->offset) {
+                        CDEBUG(D_PAGE, "hole at ino %lu; index %ld\n",
+                                        page->mapping->host->i_ino,
+                                        page->index);
+                        memset(page_address(page), 0, PAGE_SIZE);
+                        continue;
+                }
+
+                if (!page->buffers) {
+                        create_empty_buffers(page, dev, PAGE_SIZE);
+                        bh = page->buffers;
 
                         clear_bit(BH_New, &bh->b_state);
                         set_bit(BH_Mapped, &bh->b_state);
@@ -1329,7 +1975,7 @@ out_req:
         RETURN(rc);
 }
 
-static int sanosc_brw_write(struct lustre_handle *conn, struct obdo *oa,
+static int sanosc_brw_write(struct obd_export *exp, struct obdo *oa,
                             struct lov_stripe_md *lsm, obd_count page_count,
                             struct brw_page *pga)
 {
@@ -1344,7 +1990,7 @@ static int sanosc_brw_write(struct lustre_handle *conn, struct obdo *oa,
         size[1] = sizeof(struct obd_ioobj);
         size[2] = page_count * sizeof(*nioptr);
 
-        request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SAN_WRITE,
+        request = ptlrpc_prep_req(class_exp2cliimp(exp), OST_SAN_WRITE,
                                   3, size, NULL);
         if (!request)
                 RETURN(-ENOMEM);
@@ -1356,9 +2002,7 @@ static int sanosc_brw_write(struct lustre_handle *conn, struct obdo *oa,
 
         memcpy(&body->oa, oa, sizeof(body->oa));
 
-        iooptr->ioo_id = oa->o_id;
-        iooptr->ioo_gr = oa->o_valid & 0 ? oa->o_gr : 0;
-        iooptr->ioo_type = oa->o_mode;
+        obdo_to_ioobj(oa, iooptr);
         iooptr->ioo_bufcnt = page_count;
 
         /* pack request */
@@ -1396,8 +2040,8 @@ static int sanosc_brw_write(struct lustre_handle *conn, struct obdo *oa,
                         lustre_swab_niobuf_remote (nioptr);
 
                 /* got san device associated */
-                LASSERT(class_conn2obd(conn));
-                dev = class_conn2obd(conn)->u.cli.cl_sandev;
+                LASSERT(exp->exp_obd != NULL);
+                dev = exp->exp_obd->u.cli.cl_sandev;
 
                 if (!page->buffers) {
                         create_empty_buffers(page, dev, PAGE_SIZE);
@@ -1444,7 +2088,7 @@ out_req:
         RETURN(rc);
 }
 
-static int sanosc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
+static int sanosc_brw(int cmd, struct obd_export *exp, struct obdo *oa,
                       struct lov_stripe_md *lsm, obd_count page_count,
                       struct brw_page *pga, struct obd_trans_info *oti)
 {
@@ -1460,9 +2104,9 @@ static int sanosc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
                         pages_per_brw = page_count;
 
                 if (cmd & OBD_BRW_WRITE)
-                        rc = sanosc_brw_write(conn, oa, lsm, pages_per_brw,pga);
+                        rc = sanosc_brw_write(exp, oa, lsm, pages_per_brw,pga);
                 else
-                        rc = sanosc_brw_read(conn, oa, lsm, pages_per_brw, pga);
+                        rc = sanosc_brw_read(exp, oa, lsm, pages_per_brw, pga);
 
                 if (rc != 0)
                         RETURN(rc);
@@ -1475,90 +2119,47 @@ static int sanosc_brw(int cmd, struct lustre_handle *conn, struct obdo *oa,
 #endif
 #endif
 
-static int osc_mark_page_dirty(struct lustre_handle *conn,
-                               struct lov_stripe_md *lsm, unsigned long offset)
+static void osc_set_data_with_check(struct lustre_handle *lockh, void *data)
 {
-        struct client_obd *cli = &class_conn2obd(conn)->u.cli;
-        struct otree *dirty_ot = lsm->lsm_oinfo[0].loi_dirty_ot;
-        int rc;
-        ENTRY;
+        struct ldlm_lock *lock = ldlm_handle2lock(lockh);
 
-        down(&cli->cl_dirty_sem);
-
-#if 0
-        if (cli->cl_ost_can_grant &&
-            (cli->cl_dirty + PAGE_CACHE_SIZE >= cli->cl_dirty_granted)) {
-                CDEBUG(D_INODE, "granted "LPU64" < "LPU64"\n",
-                       cli->cl_dirty_granted, cli->cl_dirty + PAGE_CACHE_SIZE);
-                GOTO(out, rc = -EDQUOT);
+        LASSERT(lock != NULL);
+        l_lock(&lock->l_resource->lr_namespace->ns_lock);
+#ifdef __KERNEL__
+        if (lock->l_ast_data && lock->l_ast_data != data) {
+                struct inode *new_inode = data;
+                struct inode *old_inode = lock->l_ast_data;
+                unsigned long state = old_inode->i_state & I_FREEING;
+                CERROR("Found existing inode %p/%lu/%u state %lu in lock: "
+                       "setting data to %p/%lu/%u\n", old_inode,
+                       old_inode->i_ino, old_inode->i_generation, state,
+                       new_inode, new_inode->i_ino, new_inode->i_generation);
+                LASSERT(state);
         }
 #endif
-
-        rc = ot_mark_offset(dirty_ot, offset);
-        if (rc)
-                GOTO(out, rc);
-
-        cli->cl_dirty += PAGE_CACHE_SIZE;
-        CDEBUG(D_INODE, "dirtied off %lu, now "LPU64" bytes dirty\n",
-                        offset, cli->cl_dirty);
-out:
-        up(&cli->cl_dirty_sem);
-        RETURN(rc);
+        lock->l_ast_data = data;
+        l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+        LDLM_LOCK_PUT(lock);
 }
 
-static int osc_clear_dirty_pages(struct lustre_handle *conn,
-                                 struct lov_stripe_md *lsm,
-                                 unsigned long start, unsigned long end,
-                                 unsigned long *cleared)
+static int osc_change_cbdata(struct obd_export *exp, struct lov_stripe_md *lsm,
+                             ldlm_iterator_t replace, void *data)
 {
-        struct client_obd *cli = &class_conn2obd(conn)->u.cli;
-        struct otree *dirty_ot = lsm->lsm_oinfo[0].loi_dirty_ot;
-        unsigned long old_marked, new_marked;
-        int rc;
-        ENTRY;
-
-        down(&cli->cl_dirty_sem);
-
-        old_marked = ot_num_marked(dirty_ot);
-
-        rc = ot_clear_extent(dirty_ot, start, end);
-        if (rc)
-                GOTO(out, rc);
-
-        new_marked = ot_num_marked(dirty_ot);
-
-        LASSERT(new_marked <= old_marked);
-        LASSERT(old_marked * PAGE_CACHE_SIZE <= cli->cl_dirty);
-        *cleared = old_marked - new_marked;
-        cli->cl_dirty -= (__u64)*cleared << PAGE_CACHE_SHIFT;
-        CDEBUG(D_INODE, "cleared [%lu,%lu], now "LPU64" bytes dirty\n",
-                        start, end, cli->cl_dirty);
-
-out:
-        up(&cli->cl_dirty_sem);
-        RETURN(rc);
-}
-
-static int osc_last_dirty_offset(struct lustre_handle *conn,
-                                 struct lov_stripe_md *lsm,
-                                 unsigned long *offset)
-{
-        struct otree *dirty_ot = lsm->lsm_oinfo[0].loi_dirty_ot;
-        int rc;
-        ENTRY;
+        struct ldlm_res_id res_id = { .name = {lsm->lsm_object_id} };
+        struct obd_device *obd = class_exp2obd(exp);
 
-        rc = ot_last_marked(dirty_ot, offset);
-        RETURN(rc);
+        ldlm_change_cbdata(obd->obd_namespace, &res_id, replace, data);
+        return 0;
 }
 
-static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *lsm,
+static int osc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                        struct lustre_handle *parent_lock,
                        __u32 type, void *extentp, int extent_len, __u32 mode,
                        int *flags, void *callback, void *data,
                        struct lustre_handle *lockh)
 {
         struct ldlm_res_id res_id = { .name = {lsm->lsm_object_id} };
-        struct obd_device *obd = class_conn2obd(connh);
+        struct obd_device *obd = exp->exp_obd;
         struct ldlm_extent *extent = extentp;
         int rc;
         ENTRY;
@@ -1569,11 +2170,13 @@ static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *lsm,
         extent->end |= ~PAGE_MASK;
 
         /* Next, search for already existing extent locks that will cover us */
-        rc = ldlm_lock_match(obd->obd_namespace, LDLM_FL_MATCH_DATA, &res_id,
-                             type, extent, sizeof(extent), mode, data, lockh);
-        if (rc == 1)
+        rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id,
+                             type, extent, sizeof(*extent), mode, lockh);
+        if (rc == 1) {
+                osc_set_data_with_check(lockh, data);
                 /* We already have a lock, and it's referenced */
                 RETURN(ELDLM_OK);
+        }
 
         /* If we're trying to read, we also search for an existing PW lock.  The
          * VFS and page cache already protect us locally, so lots of readers/
@@ -1588,32 +2191,31 @@ static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *lsm,
          * locks out from other users right now, too. */
 
         if (mode == LCK_PR) {
-                rc = ldlm_lock_match(obd->obd_namespace, LDLM_FL_MATCH_DATA,
-                                     &res_id, type, extent, sizeof(extent),
-                                     LCK_PW, data, lockh);
+                rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type,
+                                     extent, sizeof(*extent), LCK_PW, lockh);
                 if (rc == 1) {
                         /* FIXME: This is not incredibly elegant, but it might
                          * be more elegant than adding another parameter to
                          * lock_match.  I want a second opinion. */
                         ldlm_lock_addref(lockh, LCK_PR);
                         ldlm_lock_decref(lockh, LCK_PW);
-
+                        osc_set_data_with_check(lockh, data);
                         RETURN(ELDLM_OK);
                 }
         }
 
-        rc = ldlm_cli_enqueue(connh, NULL, obd->obd_namespace, parent_lock,
-                              res_id, type, extent, sizeof(extent), mode, flags,
-                              ldlm_completion_ast, callback, data, lockh);
+        rc = ldlm_cli_enqueue(exp, NULL, obd->obd_namespace, parent_lock,
+                              res_id, type, extent, sizeof(*extent), mode,
+                              flags,ldlm_completion_ast, callback, data, lockh);
         RETURN(rc);
 }
 
-static int osc_match(struct lustre_handle *connh, struct lov_stripe_md *lsm,
+static int osc_match(struct obd_export *exp, struct lov_stripe_md *lsm,
                        __u32 type, void *extentp, int extent_len, __u32 mode,
                        int *flags, void *data, struct lustre_handle *lockh)
 {
         struct ldlm_res_id res_id = { .name = {lsm->lsm_object_id} };
-        struct obd_device *obd = class_conn2obd(connh);
+        struct obd_device *obd = exp->exp_obd;
         struct ldlm_extent *extent = extentp;
         int rc;
         ENTRY;
@@ -1625,21 +2227,22 @@ static int osc_match(struct lustre_handle *connh, struct lov_stripe_md *lsm,
 
         /* Next, search for already existing extent locks that will cover us */
         rc = ldlm_lock_match(obd->obd_namespace, *flags, &res_id, type,
-                             extent, sizeof(extent), mode, data, lockh);
-        if (rc)
+                             extent, sizeof(*extent), mode, lockh);
+        if (rc) {
+                osc_set_data_with_check(lockh, data);
                 RETURN(rc);
-
+        }
         /* If we're trying to read, we also search for an existing PW lock.  The
          * VFS and page cache already protect us locally, so lots of readers/
          * writers can share a single PW lock. */
         if (mode == LCK_PR) {
-                rc = ldlm_lock_match(obd->obd_namespace, *flags, &res_id,
-                                     type, extent, sizeof(extent), LCK_PW,
-                                     data, lockh);
+                rc = ldlm_lock_match(obd->obd_namespace, *flags, &res_id, type,
+                                     extent, sizeof(*extent), LCK_PW, lockh);
                 if (rc == 1) {
                         /* FIXME: This is not incredibly elegant, but it might
                          * be more elegant than adding another parameter to
                          * lock_match.  I want a second opinion. */
+                        osc_set_data_with_check(lockh, data);
                         ldlm_lock_addref(lockh, LCK_PR);
                         ldlm_lock_decref(lockh, LCK_PW);
                 }
@@ -1647,7 +2250,7 @@ static int osc_match(struct lustre_handle *connh, struct lov_stripe_md *lsm,
         RETURN(rc);
 }
 
-static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md,
+static int osc_cancel(struct obd_export *exp, struct lov_stripe_md *md,
                       __u32 mode, struct lustre_handle *lockh)
 {
         ENTRY;
@@ -1657,10 +2260,10 @@ static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md,
         RETURN(0);
 }
 
-static int osc_cancel_unused(struct lustre_handle *connh,
+static int osc_cancel_unused(struct obd_export *exp,
                              struct lov_stripe_md *lsm, int flags, void *opaque)
 {
-        struct obd_device *obd = class_conn2obd(connh);
+        struct obd_device *obd = class_exp2obd(exp);
         struct ldlm_res_id res_id = { .name = {lsm->lsm_object_id} };
 
         return ldlm_cli_cancel_unused(obd->obd_namespace, &res_id, flags,
@@ -1686,6 +2289,7 @@ static int osc_statfs(struct obd_device *obd, struct obd_statfs *osfs,
                 RETURN(-ENOMEM);
 
         request->rq_replen = lustre_msg_size(1, &size);
+        request->rq_request_portal = OST_CREATE_PORTAL; //XXX FIXME bug 249
 
         rc = ptlrpc_queue_wait(request);
         if (rc)
@@ -1712,37 +2316,36 @@ static int osc_statfs(struct obd_device *obd, struct obd_statfs *osfs,
  * the maximum number of OST indices which will fit in the user buffer.
  * lmm_magic must be LOV_MAGIC (we only use 1 slot here).
  */
-static int osc_getstripe(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                         struct lov_mds_md *lmmu)
+static int osc_getstripe(struct lov_stripe_md *lsm, struct lov_user_md *lump)
 {
-        struct lov_mds_md lmm, *lmmk;
+        struct lov_user_md lum;
+        struct lov_mds_md *lmmk;
         int rc, lmm_size;
         ENTRY;
 
         if (!lsm)
                 RETURN(-ENODATA);
 
-        rc = copy_from_user(&lmm, lmmu, sizeof(lmm));
+        rc = copy_from_user(&lum, lump, sizeof(lum));
         if (rc)
                 RETURN(-EFAULT);
 
-        if (lmm.lmm_magic != LOV_MAGIC)
+        if (lum.lmm_magic != LOV_USER_MAGIC)
                 RETURN(-EINVAL);
 
-        if (lmm.lmm_ost_count < 1)
+        if (lum.lmm_stripe_count < 1)
                 RETURN(-EOVERFLOW);
 
-        lmm_size = sizeof(lmm) + sizeof(lmm.lmm_objects[0]);
+        lmm_size = sizeof(lum) + sizeof(lum.lmm_objects[0]);
         OBD_ALLOC(lmmk, lmm_size);
-        if (rc < 0)
-                RETURN(rc);
+        if (!lmmk)
+                RETURN(-ENOMEM);
 
         lmmk->lmm_stripe_count = 1;
-        lmmk->lmm_ost_count = 1;
         lmmk->lmm_object_id = lsm->lsm_object_id;
         lmmk->lmm_objects[0].l_object_id = lsm->lsm_object_id;
 
-        if (copy_to_user(lmmu, lmmk, lmm_size))
+        if (copy_to_user(lump, lmmk, lmm_size))
                 rc = -EFAULT;
 
         OBD_FREE(lmmk, lmm_size);
@@ -1750,21 +2353,15 @@ static int osc_getstripe(struct lustre_handle *conn, struct lov_stripe_md *lsm,
         RETURN(rc);
 }
 
-static int osc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
+static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                          void *karg, void *uarg)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = exp->exp_obd;
         struct obd_ioctl_data *data = karg;
         int err = 0;
         ENTRY;
 
         switch (cmd) {
-        case IOC_OSC_REGISTER_LOV: {
-                if (obd->u.cli.cl_containing_lov)
-                        GOTO(out, err = -EALREADY);
-                obd->u.cli.cl_containing_lov = (struct obd_device *)karg;
-                GOTO(out, err);
-        }
         case OBD_IOC_LOV_GET_CONFIG: {
                 char *buf;
                 struct lov_desc *desc;
@@ -1805,12 +2402,12 @@ static int osc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
                 GOTO(out, err);
         }
         case LL_IOC_LOV_SETSTRIPE:
-                err = obd_alloc_memmd(conn, karg);
+                err = obd_alloc_memmd(exp, karg);
                 if (err > 0)
                         err = 0;
                 GOTO(out, err);
         case LL_IOC_LOV_GETSTRIPE:
-                err = osc_getstripe(conn, karg, uarg);
+                err = osc_getstripe(karg, uarg);
                 GOTO(out, err);
         case OBD_IOC_CLIENT_RECOVER:
                 err = ptlrpc_recover_import(obd->u.cli.cl_import,
@@ -1823,14 +2420,14 @@ static int osc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len,
                                                data->ioc_offset);
                 GOTO(out, err);
         default:
-                CERROR("unrecognised ioctl %#x by %s\n", cmd, current->comm);
+                CDEBUG(D_INODE, "unrecognised ioctl %#x by %s\n", cmd, current->comm);
                 GOTO(out, err = -ENOTTY);
         }
 out:
         return err;
 }
 
-static int osc_get_info(struct lustre_handle *conn, obd_count keylen,
+static int osc_get_info(struct obd_export *exp, obd_count keylen,
                         void *key, __u32 *vallen, void *val)
 {
         ENTRY;
@@ -1843,115 +2440,232 @@ static int osc_get_info(struct lustre_handle *conn, obd_count keylen,
                 *vallen = sizeof(*stripe);
                 *stripe = 0;
                 RETURN(0);
+        } else if (keylen >= strlen("last_id") && strcmp(key, "last_id") == 0) {
+                struct ptlrpc_request *req;
+                obd_id *reply;
+                char *bufs[1] = {key};
+                int rc;
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), OST_GET_INFO, 1,
+                                      &keylen, bufs);
+                if (req == NULL)
+                        RETURN(-ENOMEM);
+
+                req->rq_replen = lustre_msg_size(1, vallen);
+                rc = ptlrpc_queue_wait(req);
+                if (rc)
+                        GOTO(out, rc);
+
+                reply = lustre_swab_repbuf(req, 0, sizeof(*reply),
+                                           lustre_swab_ost_last_id);
+                if (reply == NULL) {
+                        CERROR("Can't unpack OST last ID\n");
+                        GOTO(out, rc = -EPROTO);
+                }
+                *((obd_id *)val) = *reply;
+        out:
+                ptlrpc_req_finished(req);
+                RETURN(rc);
         }
         RETURN(-EINVAL);
 }
 
-static int osc_set_info(struct lustre_handle *conn, obd_count keylen,
+static int osc_set_info(struct obd_export *exp, obd_count keylen,
                         void *key, obd_count vallen, void *val)
 {
         struct ptlrpc_request *req;
+        struct obd_import *imp = class_exp2cliimp(exp);
+        struct llog_ctxt *ctxt;
         int rc, size = keylen;
         char *bufs[1] = {key};
         ENTRY;
 
+        if (keylen == strlen("next_id") &&
+            memcmp(key, "next_id", strlen("next_id")) == 0) {
+                if (vallen != sizeof(obd_id))
+                        RETURN(-EINVAL);
+		exp->u.eu_osc_data.oed_oscc.oscc_next_id = *((obd_id*)val) + 1;
+                CDEBUG(D_INODE, "%s: set oscc_next_id = "LPU64"\n",
+                       exp->exp_obd->obd_name,
+                       exp->u.eu_osc_data.oed_oscc.oscc_next_id);
+
+                RETURN(0);
+        }
+
+        if (keylen == strlen("growth_count") &&
+            memcmp(key, "growth_count", strlen("growth_count")) == 0) {
+                if (vallen != sizeof(int))
+                        RETURN(-EINVAL);
+		exp->u.eu_osc_data.oed_oscc.oscc_grow_count = *((int*)val);
+                RETURN(0);
+        }
+
+        if (keylen == strlen("unlinked") &&
+            memcmp(key, "unlinked", keylen) == 0) {
+                struct osc_creator *oscc = &exp->u.eu_osc_data.oed_oscc;
+                spin_lock(&oscc->oscc_lock);
+                oscc->oscc_flags &= ~OSCC_FLAG_NOSPC;
+                spin_unlock(&oscc->oscc_lock);
+                RETURN(0);
+        }
+
         if (keylen < strlen("mds_conn") ||
             memcmp(key, "mds_conn", strlen("mds_conn")) != 0)
                 RETURN(-EINVAL);
 
-        req = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SET_INFO, 1,
-                              &size, bufs);
+
+        req = ptlrpc_prep_req(imp, OST_SET_INFO, 1, &size, bufs);
         if (req == NULL)
                 RETURN(-ENOMEM);
 
         req->rq_replen = lustre_msg_size(0, NULL);
         rc = ptlrpc_queue_wait(req);
         ptlrpc_req_finished(req);
+
+        ctxt = llog_get_context(exp->exp_obd, LLOG_UNLINK_ORIG_CTXT);
+        if (ctxt) {
+                rc = llog_initiator_connect(ctxt);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        imp->imp_server_timeout = 1;
+        CDEBUG(D_HA, "pinging OST %s\n", imp->imp_target_uuid.uuid);
+        ptlrpc_pinger_add_import(imp);
+
         RETURN(rc);
 }
 
-static int osc_log_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm,
-                          int count, struct llog_cookie *cookies, int flags)
+
+static struct llog_operations osc_size_repl_logops = {
+        lop_cancel: llog_obd_repl_cancel
+};
+
+static struct llog_operations osc_unlink_orig_logops;
+static int osc_llog_init(struct obd_device *obd, struct obd_device *tgt,
+                        int count, struct llog_logid *logid)
 {
-        struct obd_device *obd = class_conn2obd(conn);
-        struct llog_commit_data *llcd;
-        struct client_obd *cli;
-        int rc = 0;
+        int rc;
         ENTRY;
 
-        cli = &obd->u.cli;
-        if ((count == 0 || cookies == NULL ||
-             memcmp(cookies, &zero_cookie, sizeof(*cookies)) == 0)) {
-                down(&cli->cl_sem);
-                if (cli->cl_llcd == NULL || !(flags & OBD_LLOG_FL_SENDNOW))
-                        GOTO(out, rc);
+        osc_unlink_orig_logops = llog_lvfs_ops;
+        osc_unlink_orig_logops.lop_setup = llog_obd_origin_setup;
+        osc_unlink_orig_logops.lop_cleanup = llog_obd_origin_cleanup;
+        osc_unlink_orig_logops.lop_add = llog_obd_origin_add;
+        osc_unlink_orig_logops.lop_connect = llog_origin_connect;
 
-                llcd = cli->cl_llcd;
-                GOTO(send_now, rc);
-        }
+        rc = llog_setup(obd, LLOG_UNLINK_ORIG_CTXT, tgt, count, logid,
+                        &osc_unlink_orig_logops);
+        if (rc)
+                RETURN(rc);
 
-        down(&cli->cl_sem);
-        llcd = cli->cl_llcd;
-        if (llcd == NULL) {
-                llcd = llcd_grab();
-                if (llcd == NULL) {
-                        CERROR("couldn't get an llcd - dropped "LPX64":%x+%u\n",
-                               cookies->lgc_lgl.lgl_oid,
-                               cookies->lgc_lgl.lgl_ogen, cookies->lgc_index);
-                        GOTO(out, rc = -ENOMEM);
-                }
-                llcd->llcd_import = cli->cl_import;
-                cli->cl_llcd = llcd;
-        }
+        rc = llog_setup(obd, LLOG_SIZE_REPL_CTXT, tgt, count, NULL,
+                        &osc_size_repl_logops);
+        RETURN(rc);
+}
+
+static int osc_llog_finish(struct obd_device *obd, int count)
+{
+        int rc;
+        ENTRY;
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT));
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT));
+        RETURN(rc);
+}
 
-        memcpy(llcd->llcd_cookies + llcd->llcd_cookiebytes, cookies,
-               sizeof(*cookies));
-        llcd->llcd_cookiebytes += sizeof(*cookies);
 
-        /* If we can't fit any more cookies into the page, we need to send it */
-send_now:
-        if ((PAGE_SIZE - llcd->llcd_cookiebytes < sizeof(*cookies) ||
-             flags & OBD_LLOG_FL_SENDNOW)) {
-                cli->cl_llcd = NULL;
-                llcd_send(llcd);
+static int osc_connect(struct lustre_handle *exph,
+                       struct obd_device *obd, struct obd_uuid *cluuid)
+{
+        int rc;
+        struct obd_export *exp;
+
+        rc = client_connect_import(exph, obd, cluuid);
+
+        if (obd->u.cli.cl_conn_count == 1) {
+                exp = class_conn2export(exph);
+                oscc_init(exp);
         }
-out:
-        up(&cli->cl_sem);
 
         return rc;
 }
 
-static int osc_disconnect(struct lustre_handle *conn, int flags)
+static int osc_disconnect(struct obd_export *exp, int flags)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = class_exp2obd(exp);
+        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT);
+        int rc;
 
-        /* flush any remaining cancel messages out to the target */
-        if (obd->u.cli.cl_llcd)
-                osc_log_cancel(conn, NULL, 0, NULL, OBD_LLOG_FL_SENDNOW);
+        if (obd->u.cli.cl_conn_count == 1) {
+                /* flush any remaining cancel messages out to the target */
+                llog_sync(ctxt, exp);
+                
+                /* balance the conn2export for oscc in osc_connect */
+                class_export_put(exp);
+        }
 
-        return client_import_disconnect(conn, flags);
+        rc = client_disconnect_export(exp, flags);
+        return rc;
 }
 
-static int osc_log_add(struct lustre_handle *conn,
-                       struct llog_handle *cathandle,
-                       struct llog_trans_hdr *rec, struct lov_stripe_md *lsm,
-                       struct llog_cookie *logcookies, int numcookies)
+static int osc_lock_contains(struct obd_export *exp, struct lov_stripe_md *lsm,
+                             struct ldlm_lock *lock, obd_off offset)
 {
         ENTRY;
-        LASSERT(logcookies && numcookies > 0);
+        if (exp == NULL)
+                RETURN(-ENODEV);
 
-        llog_add_record(cathandle, rec, logcookies);
+        if (lock->l_policy_data.l_extent.start <= offset &&
+            lock->l_policy_data.l_extent.end >= offset)
+                RETURN(1);
+        RETURN(0);
+}
 
-        RETURN(1);
+static int osc_invalidate_import(struct obd_device *obd,
+                                  struct obd_import *imp)
+{
+        LASSERT(imp->imp_obd == obd);
+        /* this used to try and tear down queued pages, but it was
+         * not correctly implemented.  We'll have to do it again once
+         * we call obd_invalidate_import() agian */
+        LBUG();
+        RETURN(0);
 }
 
+int osc_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        int rc;
+        
+        rc = osc_rpcd_addref();
+        if (rc)
+                return rc;
+
+        rc = client_obd_setup(obd, len, buf);
+        if (rc)
+                osc_rpcd_decref();
+        RETURN(rc);
+}
+
+int osc_cleanup(struct obd_device *obd, int flags)
+{
+        int rc;
+
+        rc = client_obd_cleanup(obd, flags);
+        osc_rpcd_decref();
+        RETURN(rc);
+}
+
+
 struct obd_ops osc_obd_ops = {
         o_owner:        THIS_MODULE,
         o_attach:       osc_attach,
         o_detach:       osc_detach,
-        o_setup:        client_obd_setup,
-        o_cleanup:      client_obd_cleanup,
-        o_connect:      client_import_connect,
+        o_setup:        osc_setup,
+        o_cleanup:      osc_cleanup,
+        o_connect:      osc_connect,
         o_disconnect:   osc_disconnect,
         o_statfs:       osc_statfs,
         o_packmd:       osc_packmd,
@@ -1961,23 +2675,28 @@ struct obd_ops osc_obd_ops = {
         o_getattr:      osc_getattr,
         o_getattr_async:osc_getattr_async,
         o_setattr:      osc_setattr,
-        o_open:         osc_open,
-        o_close:        osc_close,
         o_brw:          osc_brw,
         o_brw_async:    osc_brw_async,
+        .o_prep_async_page =            osc_prep_async_page,
+        .o_queue_async_io =             osc_queue_async_io,
+        .o_set_async_flags =            osc_set_async_flags,
+        .o_queue_sync_io =              osc_queue_sync_io,
+        .o_trigger_sync_io =            osc_trigger_sync_io,
+        .o_teardown_async_page =        osc_teardown_async_page,
         o_punch:        osc_punch,
+        o_sync:         osc_sync,
         o_enqueue:      osc_enqueue,
         o_match:        osc_match,
+        o_change_cbdata:osc_change_cbdata,
         o_cancel:       osc_cancel,
         o_cancel_unused:osc_cancel_unused,
         o_iocontrol:    osc_iocontrol,
         o_get_info:     osc_get_info,
         o_set_info:     osc_set_info,
-        o_log_cancel:   osc_log_cancel,
-        o_log_add:      osc_log_add,
-        o_mark_page_dirty:    osc_mark_page_dirty,
-        o_clear_dirty_pages:  osc_clear_dirty_pages,
-        o_last_dirty_offset:  osc_last_dirty_offset,
+        o_lock_contains:osc_lock_contains,
+        o_invalidate_import: osc_invalidate_import,
+        o_llog_init:    osc_llog_init,
+        o_llog_finish:  osc_llog_finish,
 };
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
@@ -1986,31 +2705,30 @@ struct obd_ops sanosc_obd_ops = {
         o_attach:       osc_attach,
         o_detach:       osc_detach,
         o_cleanup:      client_obd_cleanup,
-        o_connect:      client_import_connect,
-        o_disconnect:   client_import_disconnect,
+        o_connect:      osc_connect,
+        o_disconnect:   client_disconnect_export,
         o_statfs:       osc_statfs,
         o_packmd:       osc_packmd,
         o_unpackmd:     osc_unpackmd,
-        o_create:       osc_create,
+        o_create:       osc_real_create,
         o_destroy:      osc_destroy,
         o_getattr:      osc_getattr,
-        o_getattr_async: osc_getattr_async,
+        o_getattr_async:osc_getattr_async,
         o_setattr:      osc_setattr,
-        o_open:         osc_open,
-        o_close:        osc_close,
         o_setup:        client_sanobd_setup,
         o_brw:          sanosc_brw,
         o_punch:        osc_punch,
+        o_sync:         osc_sync,
         o_enqueue:      osc_enqueue,
         o_match:        osc_match,
+        o_change_cbdata:osc_change_cbdata,
         o_cancel:       osc_cancel,
-        o_cancel_unused: osc_cancel_unused,
+        o_cancel_unused:osc_cancel_unused,
         o_iocontrol:    osc_iocontrol,
-        o_log_cancel:   osc_log_cancel,
-        o_log_add:      osc_log_add,
-        o_mark_page_dirty:   osc_mark_page_dirty,
-        o_clear_dirty_pages: osc_clear_dirty_pages,
-        o_last_dirty_offset: osc_last_dirty_offset,
+        o_lock_contains:osc_lock_contains,
+        o_invalidate_import: osc_invalidate_import,
+        o_llog_init:    osc_llog_init,
+        o_llog_finish:  osc_llog_finish,
 };
 #endif
 
@@ -2020,11 +2738,8 @@ int __init osc_init(void)
         int rc;
         ENTRY;
 
-        LASSERT(sizeof(struct obd_client_handle) <= FD_OSTDATA_SIZE);
-        LASSERT(sizeof(struct obd_client_handle) <= OBD_INLINESZ);
-
-        lprocfs_init_vars(osc,&lvars);
-        lprocfs_init_vars(osc,&sanlvars);
+        lprocfs_init_vars(osc, &lvars);
+        lprocfs_init_vars(osc, &sanlvars);
 
         rc = class_register_type(&osc_obd_ops, lvars.module_vars,
                                  LUSTRE_OSC_NAME);
diff --git a/lustre/osc/osc_rpcd.c b/lustre/osc/osc_rpcd.c
new file mode 100644
index 0000000000000000000000000000000000000000..603fb0c50ca07366fad5b45e07d4e0592a69e2ed
--- /dev/null
+++ b/lustre/osc/osc_rpcd.c
@@ -0,0 +1,247 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author Peter Braam <braam@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  For testing and management it is treated as an obd_device,
+ *  although * it does not export a full OBD method table (the
+ *  requests are coming * in over the wire, so object target modules
+ *  do not have a full * method table.)
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_OSC
+
+#ifdef __KERNEL__
+# include <linux/version.h>
+# include <linux/module.h>
+# include <linux/mm.h>
+# include <linux/highmem.h>
+# include <linux/lustre_dlm.h>
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+#  include <linux/workqueue.h>
+#  include <linux/smp_lock.h>
+# else
+#  include <linux/locks.h>
+# endif
+#else /* __KERNEL__ */
+# include <liblustre.h>
+#endif
+
+#include <linux/kp30.h>
+#include <linux/lustre_net.h>
+#include <linux/obd_ost.h>
+#include <linux/obd_lov.h>
+
+#ifndef  __CYGWIN__
+# include <linux/ctype.h>
+# include <linux/init.h>
+#else
+# include <ctype.h>
+#endif
+
+#include <linux/lustre_ha.h>
+#include <linux/obd_support.h> /* for OBD_FAIL_CHECK */
+#include <linux/lprocfs_status.h>
+
+#define LIOD_STOP 0
+static struct osc_rpcd_ctl {
+        unsigned long             orc_flags;
+        spinlock_t                orc_lock;
+        struct completion         orc_starting;
+        struct completion         orc_finishing;
+        struct list_head          orc_req_list;
+        wait_queue_head_t         orc_waitq;
+        struct ptlrpc_request_set *orc_set;
+} osc_orc;
+
+static DECLARE_MUTEX(osc_rpcd_sem);
+static int osc_rpcd_users = 0;
+
+void osc_rpcd_add_req(struct ptlrpc_request *req)
+{
+        struct osc_rpcd_ctl *orc = &osc_orc;
+
+        ptlrpc_set_add_new_req(orc->orc_set, req);
+        wake_up(&orc->orc_waitq);
+}
+
+static int osc_rpcd_check(struct osc_rpcd_ctl *orc)
+{
+        struct list_head *tmp, *pos;
+        struct ptlrpc_request *req;
+        unsigned long flags;
+        int rc = 0;
+        ENTRY;
+
+        if (test_bit(LIOD_STOP, &orc->orc_flags))
+                RETURN(1);
+
+        spin_lock_irqsave(&orc->orc_set->set_new_req_lock, flags);
+        list_for_each_safe(pos, tmp, &orc->orc_set->set_new_requests) {
+                req = list_entry(pos, struct ptlrpc_request, rq_set_chain);
+                list_del_init(&req->rq_set_chain);
+                ptlrpc_set_add_req(orc->orc_set, req);
+                rc = 1; /* need to calculate its timeout */
+        }
+        spin_unlock_irqrestore(&orc->orc_set->set_new_req_lock, flags);
+
+        if (orc->orc_set->set_remaining) {
+                rc = rc | ptlrpc_check_set(orc->orc_set);
+
+                /* XXX our set never completes, so we prune the completed
+                 * reqs after each iteration. boy could this be smarter. */
+                list_for_each_safe(pos, tmp, &orc->orc_set->set_requests) {
+                        req = list_entry(pos, struct ptlrpc_request,
+                                         rq_set_chain);
+                        if (req->rq_phase != RQ_PHASE_COMPLETE)
+                                continue;
+
+                        list_del_init(&req->rq_set_chain);
+                        req->rq_set = NULL;
+                        ptlrpc_req_finished (req);
+                }
+        }
+
+        RETURN(rc);
+}
+
+#ifdef __KERNEL__
+/* ptlrpc's code paths like to execute in process context, so we have this
+ * thread which spins on a set which contains the io rpcs.  llite specifies
+ * osc_rpcd's set when it pushes pages down into the oscs */
+static int osc_rpcd(void *arg)
+{
+        struct osc_rpcd_ctl *orc = arg;
+        unsigned long flags;
+        ENTRY;
+
+        kportal_daemonize("liod_writeback");
+
+        SIGNAL_MASK_LOCK(current, flags);
+        sigfillset(&current->blocked);
+        RECALC_SIGPENDING;
+        SIGNAL_MASK_UNLOCK(current, flags);
+
+        complete(&orc->orc_starting);
+
+        /* like kswapd */
+        current->flags |= PF_MEMALLOC;
+
+        /* this mainloop strongly resembles ptlrpc_set_wait except
+         * that our set never completes.  osc_rpcd_check calls ptlrpc_check_set
+         * when there are requests in the set.  new requests come in
+         * on the set's new_req_list and osc_rpcd_check moves them into
+         * the set. */
+        while (1) {
+                wait_queue_t set_wait;
+                struct l_wait_info lwi;
+                int timeout;
+
+                timeout = ptlrpc_set_next_timeout(orc->orc_set) * HZ;
+                lwi = LWI_TIMEOUT(timeout, ptlrpc_expired_set, orc->orc_set);
+
+                /* ala the pinger, wait on orc's waitqueue and the set's */
+                init_waitqueue_entry(&set_wait, current);
+                add_wait_queue(&orc->orc_set->set_waitq, &set_wait);
+                l_wait_event(orc->orc_waitq, osc_rpcd_check(orc), &lwi);
+                remove_wait_queue(&orc->orc_set->set_waitq, &set_wait);
+
+                if (test_bit(LIOD_STOP, &orc->orc_flags))
+                        break;
+        }
+        /* XXX should be making sure we don't have anything in flight */
+        complete(&orc->orc_finishing);
+        return 0;
+}
+#else
+static int osc_rpcd_recurred = 0;
+static void *osc_rpcd_callback;
+
+int osc_check_async_rpcs(void *arg)
+{
+        struct osc_rpcd_ctl *orc = arg;
+        int                  rc = 0;
+
+        /* single threaded!! */
+        osc_rpcd_recurred++;
+
+        if (osc_rpcd_recurred == 1)
+                rc = osc_rpcd_check(orc);
+
+        osc_rpcd_recurred--;
+        return rc;
+}
+#endif
+
+int osc_rpcd_addref(void)
+{
+        struct osc_rpcd_ctl *orc = &osc_orc;
+        int rc = 0;
+        ENTRY;
+
+        down(&osc_rpcd_sem);
+        if (++osc_rpcd_users != 1)
+                GOTO(out, rc);
+
+        memset(orc, 0, sizeof(*orc));
+        init_completion(&orc->orc_starting);
+        init_completion(&orc->orc_finishing);
+        init_waitqueue_head(&orc->orc_waitq);
+        orc->orc_flags = 0;
+        spin_lock_init(&orc->orc_lock);
+        INIT_LIST_HEAD(&orc->orc_req_list);
+
+        orc->orc_set = ptlrpc_prep_set();
+        if (orc->orc_set == NULL)
+                GOTO(out, rc = -ENOMEM);
+
+#ifdef __KERNEL__
+        if (kernel_thread(osc_rpcd, orc, 0) < 0)  {
+                ptlrpc_set_destroy(orc->orc_set);
+                GOTO(out, rc = -ECHILD);
+        }
+
+        wait_for_completion(&orc->orc_starting);
+#else
+        osc_rpcd_callback =
+                liblustre_register_wait_callback(&osc_check_async_rpcs, orc);
+#endif
+out:
+        up(&osc_rpcd_sem);
+        RETURN(rc);
+}
+
+void osc_rpcd_decref(void)
+{
+        struct osc_rpcd_ctl *orc = &osc_orc;
+
+        down(&osc_rpcd_sem);
+        if (--osc_rpcd_users == 0) {
+                set_bit(LIOD_STOP, &orc->orc_flags);
+                wake_up(&orc->orc_waitq);
+#ifdef __KERNEL__
+                wait_for_completion(&orc->orc_finishing);
+#else
+                liblustre_deregister_wait_callback(osc_rpcd_callback);
+#endif
+                ptlrpc_set_destroy(orc->orc_set);
+        }
+        up(&osc_rpcd_sem);
+}
diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c
index 5f3575806b76f20217b76e354922cd391e24fbb3..74a6d1d1afc5be7d0087dc0e794adb058c3da174 100644
--- a/lustre/ost/ost_handler.c
+++ b/lustre/ost/ost_handler.c
@@ -30,7 +30,9 @@
  *  modules do not have a full method table.)
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_OST
 
 #include <linux/module.h>
@@ -68,16 +70,14 @@ void oti_to_request(struct obd_trans_info *oti, struct ptlrpc_request *req)
         for (ack_lock = oti->oti_ack_locks, i = 0; i < 4; i++, ack_lock++) {
                 if (!ack_lock->mode)
                         break;
-                memcpy(&req->rq_ack_locks[i].lock, &ack_lock->lock,
-                       sizeof(req->rq_ack_locks[i].lock));
-                req->rq_ack_locks[i].mode = ack_lock->mode;
+                ldlm_put_lock_into_req(req, &ack_lock->lock, ack_lock->mode);
         }
 }
 
-static int ost_destroy(struct ptlrpc_request *req, struct obd_trans_info *oti)
+static int ost_destroy(struct obd_export *exp, struct ptlrpc_request *req, 
+                       struct obd_trans_info *oti)
 {
-        struct lustre_handle *conn = &req->rq_reqmsg->handle;
-        struct ost_body *body;
+        struct ost_body *body, *repbody;
         int rc, size = sizeof(*body);
         ENTRY;
 
@@ -85,19 +85,20 @@ static int ost_destroy(struct ptlrpc_request *req, struct obd_trans_info *oti)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
         if (body->oa.o_valid & OBD_MD_FLCOOKIE)
                 oti->oti_logcookies = obdo_logcookie(&body->oa);
-        req->rq_status = obd_destroy(conn, &body->oa, NULL, oti);
+        repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
+        memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
+        req->rq_status = obd_destroy(exp, &body->oa, NULL, oti);
         RETURN(0);
 }
 
-static int ost_getattr(struct ptlrpc_request *req)
+static int ost_getattr(struct obd_export *exp, struct ptlrpc_request *req)
 {
-        struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg;
         struct ost_body *body, *repbody;
         int rc, size = sizeof(*body);
         ENTRY;
@@ -106,13 +107,13 @@ static int ost_getattr(struct ptlrpc_request *req)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
         repbody = lustre_msg_buf (req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
-        req->rq_status = obd_getattr(conn, &repbody->oa, NULL);
+        req->rq_status = obd_getattr(exp, &repbody->oa, NULL);
         RETURN(0);
 }
 
@@ -122,7 +123,7 @@ static int ost_statfs(struct ptlrpc_request *req)
         int rc, size = sizeof(*osfs);
         ENTRY;
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
@@ -135,29 +136,9 @@ static int ost_statfs(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-static int ost_syncfs(struct ptlrpc_request *req)
-{
-        struct obd_statfs *osfs;
-        int rc, size = sizeof(*osfs);
-        ENTRY;
-
-        rc = lustre_pack_msg(0, &size, NULL, &req->rq_replen, &req->rq_repmsg);
-        if (rc)
-                RETURN(rc);
-
-        rc = obd_syncfs(req->rq_export);
-        if (rc) {
-                CERROR("ost: syncfs failed: rc %d\n", rc);
-                req->rq_status = rc;
-                RETURN(rc);
-        }
-
-        RETURN(0);
-}
-
-static int ost_open(struct ptlrpc_request *req, struct obd_trans_info *oti)
+static int ost_create(struct obd_export *exp, struct ptlrpc_request *req,
+                      struct obd_trans_info *oti)
 {
-        struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg;
         struct ost_body *body, *repbody;
         int rc, size = sizeof(*repbody);
         ENTRY;
@@ -166,19 +147,21 @@ static int ost_open(struct ptlrpc_request *req, struct obd_trans_info *oti)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
         repbody = lustre_msg_buf (req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
-        req->rq_status = obd_open(conn, &repbody->oa, NULL, oti, NULL);
+        oti->oti_logcookies = obdo_logcookie(&repbody->oa);
+        req->rq_status = obd_create(exp, &repbody->oa, NULL, oti);
+        //obd_log_cancel(conn, NULL, 1, oti->oti_logcookies, 0);
         RETURN(0);
 }
 
-static int ost_close(struct ptlrpc_request *req, struct obd_trans_info *oti)
+static int ost_punch(struct obd_export *exp, struct ptlrpc_request *req, 
+                     struct obd_trans_info *oti)
 {
-        struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg;
         struct ost_body *body, *repbody;
         int rc, size = sizeof(*repbody);
         ENTRY;
@@ -187,42 +170,23 @@ static int ost_close(struct ptlrpc_request *req, struct obd_trans_info *oti)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
-        if (rc)
-                RETURN(rc);
-
-        repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
-        memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
-        req->rq_status = obd_close(conn, &repbody->oa, NULL, oti);
-        RETURN(0);
-}
-
-static int ost_create(struct ptlrpc_request *req, struct obd_trans_info *oti)
-{
-        struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg;
-        struct ost_body *body, *repbody;
-        int rc, size = sizeof(*repbody);
-        ENTRY;
-
-        body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_ost_body);
-        if (body == NULL)
-                RETURN(-EFAULT);
+        if ((body->oa.o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) !=
+            (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS))
+                RETURN(-EINVAL);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
-        repbody = lustre_msg_buf (req->rq_repmsg, 0, sizeof(*repbody));
+        repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
-        oti->oti_logcookies = obdo_logcookie(&repbody->oa);
-        req->rq_status = obd_create(conn, &repbody->oa, NULL, oti);
-        //obd_log_cancel(conn, NULL, 1, oti->oti_logcookies, 0);
+        req->rq_status = obd_punch(exp, &repbody->oa, NULL, repbody->oa.o_size,
+                                   repbody->oa.o_blocks, oti);
         RETURN(0);
 }
 
-static int ost_punch(struct ptlrpc_request *req, struct obd_trans_info *oti)
+static int ost_sync(struct obd_export *exp, struct ptlrpc_request *req)
 {
-        struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg;
         struct ost_body *body, *repbody;
         int rc, size = sizeof(*repbody);
         ENTRY;
@@ -231,24 +195,20 @@ static int ost_punch(struct ptlrpc_request *req, struct obd_trans_info *oti)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        if ((body->oa.o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) !=
-            (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS))
-                RETURN(-EINVAL);
-
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
-        req->rq_status = obd_punch(conn, &repbody->oa, NULL, repbody->oa.o_size,
-                                   repbody->oa.o_blocks, oti);
+        req->rq_status = obd_sync(exp, &repbody->oa, NULL, repbody->oa.o_size,
+                                  repbody->oa.o_blocks);
         RETURN(0);
 }
 
-static int ost_setattr(struct ptlrpc_request *req, struct obd_trans_info *oti)
+static int ost_setattr(struct obd_export *exp, struct ptlrpc_request *req, 
+                       struct obd_trans_info *oti)
 {
-        struct lustre_handle *conn = &req->rq_reqmsg->handle;
         struct ost_body *body, *repbody;
         int rc, size = sizeof(*repbody);
         ENTRY;
@@ -257,14 +217,14 @@ static int ost_setattr(struct ptlrpc_request *req, struct obd_trans_info *oti)
         if (body == NULL)
                 RETURN(-EFAULT);
 
-        rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
 
-        req->rq_status = obd_setattr(conn, &repbody->oa, NULL, oti);
+        req->rq_status = obd_setattr(exp, &repbody->oa, NULL, oti);
         RETURN(0);
 }
 
@@ -377,9 +337,9 @@ static void free_per_page_niobufs (int npages, struct niobuf_remote *pp_rnb,
 }
 
 #if CHECKSUM_BULK
-__u64 ost_checksum_bulk (struct ptlrpc_bulk_desc *desc)
+obd_count ost_checksum_bulk(struct ptlrpc_bulk_desc *desc)
 {
-        __u64             cksum = 0;
+        obd_count cksum = 0;
         struct ptlrpc_bulk_page *bp;
 
         list_for_each_entry(bp, &desc->bd_page_list, bp_link) {
@@ -387,6 +347,8 @@ __u64 ost_checksum_bulk (struct ptlrpc_bulk_desc *desc)
                              bp->bp_buflen);
                 kunmap(bp->bp_page);
         }
+
+        return cksum;
 }
 #endif
 
@@ -400,6 +362,7 @@ static int ost_brw_read(struct ptlrpc_request *req)
         struct ost_body         *body, *repbody;
         struct l_wait_info       lwi;
         struct obd_trans_info    oti = { 0 };
+        char                     str[PTL_NALFMT_SIZE];
         int                      size[1] = { sizeof(*body) };
         int                      comms_error = 0;
         int                      niocount;
@@ -443,7 +406,7 @@ static int ost_brw_read(struct ptlrpc_request *req)
         }
 
         size[0] = sizeof(*body);
-        rc = lustre_pack_msg(1, size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, size, NULL);
         if (rc)
                 GOTO(out, rc);
 
@@ -508,8 +471,8 @@ static int ost_brw_read(struct ptlrpc_request *req)
                         }
                 } else {
                         DEBUG_REQ(D_ERROR, req, "bulk PUT failed: rc %d\n", rc);
-		}
-		comms_error = rc != 0;
+                }
+                comms_error = rc != 0;
         }
 
         /* Must commit after prep above in all cases */
@@ -521,7 +484,7 @@ static int ost_brw_read(struct ptlrpc_request *req)
 
 #if CHECKSUM_BULK
         if (rc == 0) {
-                repbody->oa.o_rdev = ost_checksum_bulk(desc);
+                repbody->oa.o_nlink = ost_checksum_bulk(desc);
                 repbody->oa.o_valid |= OBD_MD_FLCKSUM;
         }
 #endif
@@ -546,11 +509,26 @@ static int ost_brw_read(struct ptlrpc_request *req)
                         /* reply out callback would free */
                         OBD_FREE(req->rq_repmsg, req->rq_replen);
                 }
-                CERROR("bulk IO comms error: evicting %s@%s nid "LPU64"\n",
-                       req->rq_export->exp_client_uuid.uuid,
-                       req->rq_connection->c_remote_uuid.uuid,
-                       req->rq_connection->c_peer.peer_nid);
-                ptlrpc_fail_export(req->rq_export);
+                if (req->rq_reqmsg->conn_cnt == req->rq_export->exp_conn_cnt) {
+                        CERROR("bulk IO comms error: "
+                               "evicting %s@%s nid "LPX64" (%s)\n",
+                               req->rq_export->exp_client_uuid.uuid,
+                               req->rq_connection->c_remote_uuid.uuid,
+                               req->rq_connection->c_peer.peer_nid,
+                               portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                               req->rq_connection->c_peer.peer_nid,
+                                               str));
+                        ptlrpc_fail_export(req->rq_export);
+                } else {
+                        CERROR("ignoring bulk IO comms error: "
+                               "client reconnected %s@%s nid "LPX64" (%s)\n",  
+                               req->rq_export->exp_client_uuid.uuid,
+                               req->rq_connection->c_remote_uuid.uuid,
+                               req->rq_connection->c_peer.peer_nid,
+                               portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                               req->rq_connection->c_peer.peer_nid,
+                                               str));
+                }
         }
 
         RETURN(rc);
@@ -570,6 +548,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
         int                      objcount, niocount, npages;
         int                      comms_error = 0;
         int                      rc, rc2, swab, i, j;
+        char                    str[PTL_NALFMT_SIZE];
         ENTRY;
 
         if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_WRITE_BULK))
@@ -619,8 +598,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
         }
 
         size[1] = niocount * sizeof(*rcs);
-        rc = lustre_pack_msg(2, size, NULL, &req->rq_replen,
-                             &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 2, size, NULL);
         if (rc != 0)
                 GOTO(out, rc);
         rcs = lustre_msg_buf(req->rq_repmsg, 1, niocount * sizeof(*rcs));
@@ -667,9 +645,9 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
                                 ptlrpc_abort_bulk(desc);
                         }
                 } else {
-			DEBUG_REQ(D_ERROR, req, "bulk GET failed: rc %d\n", rc);
-		}
-		comms_error = rc != 0;
+                        DEBUG_REQ(D_ERROR, req, "bulk GET failed: rc %d\n", rc);
+                }
+                comms_error = rc != 0;
         }
 
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
@@ -678,22 +656,24 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
 #if CHECKSUM_BULK
         if (rc == 0 && (body->oa.o_valid & OBD_MD_FLCKSUM) != 0) {
                 static int cksum_counter;
-                __u64 client_cksum = body->oa.o_rdev;
-                __u64 cksum = ost_checksum_bulk(desc);
+                obd_count client_cksum = body->oa.o_nlink;
+                obd_count cksum = ost_checksum_bulk(desc);
 
+                portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                req->rq_connection->c_peer.peer_nid, str);
                 if (client_cksum != cksum) {
-                        CERROR("Bad checksum: client "LPX64", server "LPX64
-                               ", client NID "LPX64"\n", client_cksum, cksum,
-                               req->rq_connection->c_peer.peer_nid);
+                        CERROR("Bad checksum: client %x, server %x, client NID "
+                               LPX64" (%s)\n", client_cksum, cksum,
+                               req->rq_connection->c_peer.peer_nid, str);
                         cksum_counter = 1;
-                        repbody->oa.o_rdev = cksum;
+                        repbody->oa.o_nlink = cksum;
                 } else {
                         cksum_counter++;
                         if ((cksum_counter & (-cksum_counter)) == cksum_counter)
-                                CERROR("Checksum %d from "LPX64": "LPX64" OK\n",
-                                        cksum_counter,
-                                        req->rq_connection->c_peer.peer_nid,
-                                        cksum);
+                                CWARN("Checksum %u from "LPX64": %x OK\n",
+                                      cksum_counter,
+                                      req->rq_connection->c_peer.peer_nid,
+                                      cksum);
                 }
         }
 #endif
@@ -740,22 +720,36 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
                         /* reply out callback would free */
                         OBD_FREE (req->rq_repmsg, req->rq_replen);
                 }
-                CERROR("bulk IO comms error: evicting %s@%s nid "LPU64"\n",
-                       req->rq_export->exp_client_uuid.uuid,
-                       req->rq_connection->c_remote_uuid.uuid,
-                       req->rq_connection->c_peer.peer_nid);
-                ptlrpc_fail_export(req->rq_export);
+                if (req->rq_reqmsg->conn_cnt == req->rq_export->exp_conn_cnt) {
+                        CERROR("bulk IO comms error: "
+                               "evicting %s@%s nid "LPX64" (%s)\n",
+                               req->rq_export->exp_client_uuid.uuid,
+                               req->rq_connection->c_remote_uuid.uuid,
+                               req->rq_connection->c_peer.peer_nid,
+                               portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                               req->rq_connection->c_peer.peer_nid,
+                                               str));
+                        ptlrpc_fail_export(req->rq_export);
+                } else {
+                        CERROR("ignoring bulk IO comms error: "
+                               "client reconnected %s@%s nid "LPX64" (%s)\n",
+                               req->rq_export->exp_client_uuid.uuid,
+                               req->rq_connection->c_remote_uuid.uuid,
+                               req->rq_connection->c_peer.peer_nid,
+                               portals_nid2str(req->rq_connection->c_peer.peer_ni->pni_number,
+                                               req->rq_connection->c_peer.peer_nid,
+                                               str));
+                }        
         }
         RETURN(rc);
 }
 
 static int ost_san_brw(struct ptlrpc_request *req, int cmd)
 {
-        struct niobuf_remote *remote_nb, *res_nb;
+        struct niobuf_remote *remote_nb, *res_nb, *pp_rnb;
         struct obd_ioobj *ioo;
         struct ost_body *body, *repbody;
-        int rc, i, j, objcount, niocount, size[2] = {sizeof(*body)};
-        int n;
+        int rc, i, objcount, niocount, size[2] = {sizeof(*body)}, npages;
         int swab;
         ENTRY;
 
@@ -792,33 +786,21 @@ static int ost_san_brw(struct ptlrpc_request *req, int cmd)
                         lustre_swab_niobuf_remote (&remote_nb[i]);
         }
 
-        for (i = n = 0; i < objcount; i++) {
-                for (j = 0; j < ioo[i].ioo_bufcnt; j++, n++) {
-                        if (remote_nb[n].len == 0) {
-                                CERROR("zero len BRW: objid "LPX64" buf %u\n",
-                                       ioo[i].ioo_id, j);
-                                GOTO(out, rc = -EINVAL);
-                        }
-                        if (j && remote_nb[n].offset <= remote_nb[n-1].offset) {
-                                CERROR("unordered BRW: objid "LPX64
-                                       " buf %u offset "LPX64" <= "LPX64"\n",
-                                       ioo[i].ioo_id, j, remote_nb[n].offset,
-                                       remote_nb[n-1].offset);
-                                GOTO(out, rc = -EINVAL);
-                        }
-                }
-        }
-
-        size[1] = niocount * sizeof(*remote_nb);
-        rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg);
+        /* CAVEAT EMPTOR this sets ioo->ioo_bufcnt to # pages */
+        npages = get_per_page_niobufs(ioo, objcount,remote_nb,niocount,&pp_rnb);
+        if (npages < 0)
+                GOTO (out, rc = npages);
+ 
+        size[1] = npages * sizeof(*pp_rnb);
+        rc = lustre_pack_reply(req, 2, size, NULL);
         if (rc)
-                GOTO(out, rc);
+                GOTO(out_pp_rnb, rc);
 
         req->rq_status = obd_san_preprw(cmd, req->rq_export, &body->oa,
-                                        objcount, ioo, niocount, remote_nb);
+                                        objcount, ioo, npages, pp_rnb);
 
         if (req->rq_status)
-                GOTO(out, rc = 0);
+                GOTO(out_pp_rnb, rc = 0);
 
         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
@@ -826,6 +808,8 @@ static int ost_san_brw(struct ptlrpc_request *req, int cmd)
         res_nb = lustre_msg_buf(req->rq_repmsg, 1, size[1]);
         memcpy(res_nb, remote_nb, size[1]);
         rc = 0;
+out_pp_rnb:
+        free_per_page_niobufs(npages, pp_rnb, remote_nb);
 out:
         if (rc) {
                 OBD_FREE(req->rq_repmsg, req->rq_replen);
@@ -838,59 +822,58 @@ out:
         return rc;
 }
 
-static int ost_log_cancel(struct ptlrpc_request *req)
+
+static int ost_set_info(struct obd_export *exp, struct ptlrpc_request *req)
 {
-        struct lustre_handle *conn;
-        struct llog_cookie *logcookies;
-        int num_cookies, rc = 0;
+        char *key;
+        int keylen, rc = 0;
         ENTRY;
 
-        logcookies = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*logcookies));
-        if (logcookies == NULL) {
-                DEBUG_REQ(D_HA, req, "no cookies sent");
+        key = lustre_msg_buf(req->rq_reqmsg, 0, 1);
+        if (key == NULL) {
+                DEBUG_REQ(D_HA, req, "no set_info key");
                 RETURN(-EFAULT);
         }
-        num_cookies = req->rq_reqmsg->buflens[0] / sizeof(*logcookies);
+        keylen = req->rq_reqmsg->buflens[0];
 
-        /* workaround until we don't need to send replies */
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc)
                 RETURN(rc);
-        req->rq_repmsg->status = 0;
-        /* end workaround */
-
-        conn = (struct lustre_handle *)&req->rq_reqmsg->handle;
-        rc = obd_log_cancel(conn, NULL, num_cookies, logcookies, 0);
 
+        rc = obd_set_info(exp, keylen, key, 0, NULL);
+        req->rq_repmsg->status = 0;
         RETURN(rc);
 }
 
-static int ost_set_info(struct ptlrpc_request *req)
+static int ost_get_info(struct obd_export *exp, struct ptlrpc_request *req)
 {
-        struct lustre_handle *conn;
         char *key;
-        int keylen, rc = 0;
+        int keylen, rc = 0, size = sizeof(obd_id);
+        obd_id *reply;
         ENTRY;
 
         key = lustre_msg_buf(req->rq_reqmsg, 0, 1);
         if (key == NULL) {
-                DEBUG_REQ(D_HA, req, "no set_info key");
+                DEBUG_REQ(D_HA, req, "no get_info key");
                 RETURN(-EFAULT);
         }
         keylen = req->rq_reqmsg->buflens[0];
 
-        rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg);
+        if (keylen < strlen("last_id") || memcmp(key, "last_id", 7) != 0)
+                RETURN(-EPROTO);
+
+        rc = lustre_pack_reply(req, 1, &size, NULL);
         if (rc)
                 RETURN(rc);
 
-        conn = (struct lustre_handle *)&req->rq_reqmsg->handle;
-        rc = obd_set_info(conn, keylen, key, 0, NULL);
+        reply = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*reply));
+        rc = obd_get_info(exp, keylen, key, &size, reply);
         req->rq_repmsg->status = 0;
         RETURN(rc);
 }
 
-static int filter_recovery_request(struct ptlrpc_request *req,
-                                   struct obd_device *obd, int *process)
+static int ost_filter_recovery_request(struct ptlrpc_request *req,
+                                       struct obd_device *obd, int *process)
 {
         switch (req->rq_reqmsg->opc) {
         case OST_CONNECT: /* This will never get here, but for completeness. */
@@ -899,13 +882,11 @@ static int filter_recovery_request(struct ptlrpc_request *req,
                RETURN(0);
 
         case OBD_PING:
-        case OST_CLOSE:
         case OST_CREATE:
         case OST_DESTROY:
-        case OST_OPEN:
         case OST_PUNCH:
         case OST_SETATTR:
-        case OST_SYNCFS:
+        case OST_SYNC:
         case OST_WRITE:
         case OBD_LOG_CANCEL:
         case LDLM_ENQUEUE:
@@ -928,6 +909,7 @@ static int ost_handle(struct ptlrpc_request *req)
         struct obd_trans_info trans_info = { 0, };
         struct obd_trans_info *oti = &trans_info;
         int should_process, fail = OBD_FAIL_OST_ALL_REPLY_NET, rc = 0;
+        struct obd_export *exp = NULL;
         ENTRY;
 
         LASSERT(current->journal_info == NULL);
@@ -936,14 +918,16 @@ static int ost_handle(struct ptlrpc_request *req)
                 struct obd_device *obd;
                 int abort_recovery, recovering;
 
-                if (req->rq_export == NULL) {
+                exp = req->rq_export;
+
+                if (exp == NULL) {
                         CDEBUG(D_HA, "operation %d on unconnected OST\n",
                                req->rq_reqmsg->opc);
                         req->rq_status = -ENOTCONN;
                         GOTO(out, rc = -ENOTCONN);
                 }
 
-                obd = req->rq_export->exp_obd;
+                obd = exp->exp_obd;
 
                 /* Check for aborted recovery. */
                 spin_lock_bh(&obd->obd_processing_task_lock);
@@ -953,7 +937,8 @@ static int ost_handle(struct ptlrpc_request *req)
                 if (abort_recovery) {
                         target_abort_recovery(obd);
                 } else if (recovering) {
-                        rc = filter_recovery_request(req, obd, &should_process);
+                        rc = ost_filter_recovery_request(req, obd,
+                                                         &should_process);
                         if (rc || !should_process)
                                 RETURN(rc);
                 }
@@ -978,32 +963,22 @@ static int ost_handle(struct ptlrpc_request *req)
         case OST_CREATE:
                 CDEBUG(D_INODE, "create\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_CREATE_NET, 0);
-                rc = ost_create(req, oti);
+                rc = ost_create(exp, req, oti);
                 break;
         case OST_DESTROY:
                 CDEBUG(D_INODE, "destroy\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0);
-                rc = ost_destroy(req, oti);
+                rc = ost_destroy(exp, req, oti);
                 break;
         case OST_GETATTR:
                 CDEBUG(D_INODE, "getattr\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_GETATTR_NET, 0);
-                rc = ost_getattr(req);
+                rc = ost_getattr(exp, req);
                 break;
         case OST_SETATTR:
                 CDEBUG(D_INODE, "setattr\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_SETATTR_NET, 0);
-                rc = ost_setattr(req, oti);
-                break;
-        case OST_OPEN:
-                CDEBUG(D_INODE, "open\n");
-                OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0);
-                rc = ost_open(req, oti);
-                break;
-        case OST_CLOSE:
-                CDEBUG(D_INODE, "close\n");
-                OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0);
-                rc = ost_close(req, oti);
+                rc = ost_setattr(exp, req, oti);
                 break;
         case OST_WRITE:
                 CDEBUG(D_INODE, "write\n");
@@ -1034,30 +1009,52 @@ static int ost_handle(struct ptlrpc_request *req)
         case OST_PUNCH:
                 CDEBUG(D_INODE, "punch\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_PUNCH_NET, 0);
-                rc = ost_punch(req, oti);
+                rc = ost_punch(exp, req, oti);
                 break;
         case OST_STATFS:
                 CDEBUG(D_INODE, "statfs\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0);
                 rc = ost_statfs(req);
                 break;
-        case OST_SYNCFS:
+        case OST_SYNC:
                 CDEBUG(D_INODE, "sync\n");
-                OBD_FAIL_RETURN(OBD_FAIL_OST_SYNCFS_NET, 0);
-                rc = ost_syncfs(req);
+                OBD_FAIL_RETURN(OBD_FAIL_OST_SYNC_NET, 0);
+                rc = ost_sync(exp, req);
                 break;
         case OST_SET_INFO:
                 DEBUG_REQ(D_INODE, req, "set_info");
-                rc = ost_set_info(req);
+                rc = ost_set_info(exp, req);
+                break;
+        case OST_GET_INFO:
+                DEBUG_REQ(D_INODE, req, "get_info");
+                rc = ost_get_info(exp, req);
+                break;
         case OBD_PING:
                 DEBUG_REQ(D_INODE, req, "ping");
                 rc = target_handle_ping(req);
                 break;
+#ifdef ENABLE_ORPHANS
+        /* FIXME - just reply status */
+        case LLOG_ORIGIN_CONNECT:
+                DEBUG_REQ(D_INODE, req, "log connect\n");
+                rc = llog_handle_connect(req); 
+                req->rq_status = rc;
+                rc = lustre_pack_reply(req, 0, NULL, NULL);
+                if (rc)
+                        RETURN(rc);
+                RETURN(ptlrpc_reply(req));
+                //break;
         case OBD_LOG_CANCEL:
                 CDEBUG(D_INODE, "log cancel\n");
                 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOG_CANCEL_NET, 0);
-                rc = ost_log_cancel(req);
-                break;
+                rc = llog_origin_handle_cancel(req);
+                req->rq_status = rc;
+                rc = lustre_pack_reply(req, 0, NULL, NULL);
+                if (rc)
+                        RETURN(rc);
+                RETURN(ptlrpc_reply(req));
+                //break;
+#endif
         case LDLM_ENQUEUE:
                 CDEBUG(D_INODE, "enqueue\n");
                 OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0);
@@ -1126,35 +1123,54 @@ out:
 static int ost_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
         struct ost_obd *ost = &obddev->u.ost;
-        int err, i;
+        int rc;
         ENTRY;
 
-#ifdef ENABLE_ORPHANS
-        err = llog_start_commit_thread();
-        if (err < 0)
-                RETURN(err);
-#endif
+        /* Get rid of unneeded supplementary groups */
+        current->ngroups = 0;
+        memset(current->groups, 0, sizeof(current->groups));
+
+        rc = llog_start_commit_thread();
+        if (rc < 0)
+                RETURN(rc);
 
         ost->ost_service = ptlrpc_init_svc(OST_NEVENTS, OST_NBUFS,
                                            OST_BUFSIZE, OST_MAXREQSIZE,
                                            OST_REQUEST_PORTAL, OSC_REPLY_PORTAL,
-                                           ost_handle, "ost", obddev);
-        if (!ost->ost_service) {
+                                           ost_handle, "ost", 
+                                           obddev->obd_proc_entry);
+        if (ost->ost_service == NULL) {
                 CERROR("failed to start service\n");
                 RETURN(-ENOMEM);
         }
+        
+        rc = ptlrpc_start_n_threads(obddev, ost->ost_service, OST_NUM_THREADS, 
+                                 "ll_ost");
+        if (rc)
+                GOTO(out, rc = -EINVAL);
 
-        for (i = 0; i < OST_NUM_THREADS; i++) {
-                char name[32];
-                sprintf(name, "ll_ost_%02d", i);
-                err = ptlrpc_start_thread(obddev, ost->ost_service, name);
-                if (err) {
-                        CERROR("error starting thread #%d: rc %d\n", i, err);
-                        RETURN(-EINVAL);
-                }
+        ost->ost_create_service =
+                ptlrpc_init_svc(OST_NEVENTS, OST_NBUFS, OST_BUFSIZE,
+                                OST_MAXREQSIZE, OST_CREATE_PORTAL,
+                                OSC_REPLY_PORTAL, ost_handle, "ost_create",
+                                obddev->obd_proc_entry);
+        if (ost->ost_create_service == NULL) {
+                CERROR("failed to start OST create service\n");
+                GOTO(out, rc = -ENOMEM);
         }
 
+        rc = ptlrpc_start_n_threads(obddev, ost->ost_create_service, 1,
+                                    "ll_ost_create");
+        if (rc) 
+                GOTO(out_create, rc = -EINVAL);
+
         RETURN(0);
+
+out_create:
+        ptlrpc_unregister_service(ost->ost_create_service);
+out:
+        ptlrpc_unregister_service(ost->ost_service);
+        RETURN(rc);
 }
 
 static int ost_cleanup(struct obd_device *obddev, int flags)
@@ -1169,6 +1185,9 @@ static int ost_cleanup(struct obd_device *obddev, int flags)
         ptlrpc_stop_all_threads(ost->ost_service);
         ptlrpc_unregister_service(ost->ost_service);
 
+        ptlrpc_stop_all_threads(ost->ost_create_service);
+        ptlrpc_unregister_service(ost->ost_create_service);
+
         RETURN(err);
 }
 
@@ -1185,29 +1204,6 @@ int ost_detach(struct obd_device *dev)
         return lprocfs_obd_detach(dev);
 }
 
-/* I don't think this function is ever used, since nothing
- * connects directly to this module.
- */
-static int ost_connect(struct lustre_handle *conn,
-                       struct obd_device *obd, struct obd_uuid *cluuid)
-{
-        struct obd_export *exp;
-        int rc;
-        ENTRY;
-
-        if (!conn || !obd || !cluuid)
-                RETURN(-EINVAL);
-
-        rc = class_connect(conn, obd, cluuid);
-        if (rc)
-                RETURN(rc);
-        exp = class_conn2export(conn);
-        LASSERT(exp);
-        class_export_put(exp);
-
-        RETURN(0);
-}
-
 /* use obd ops to offer management infrastructure */
 static struct obd_ops ost_obd_ops = {
         o_owner:        THIS_MODULE,
@@ -1215,7 +1211,6 @@ static struct obd_ops ost_obd_ops = {
         o_detach:       ost_detach,
         o_setup:        ost_setup,
         o_cleanup:      ost_cleanup,
-        o_connect:      ost_connect,
 };
 
 static int __init ost_init(void)
diff --git a/lustre/portals/archdep.m4 b/lustre/portals/archdep.m4
index 1a7741bc3a1584c3165d2fd184d309ed3942c8b1..6171555571d89ddbc90206bab5c6047c86747a86 100644
--- a/lustre/portals/archdep.m4
+++ b/lustre/portals/archdep.m4
@@ -225,7 +225,8 @@ fi
 #AC_SUBST(usrprefix)
 
 AC_MSG_CHECKING(if kernel has CPU affinity support)
-if test "$target_cpu" != ia64 ; then
+SET_CPUS_ALLOW="`grep -c set_cpus_allowed $LINUX/kernel/softirq.c`"
+if test "$SET_CPUS_ALLOW" != 0 ; then
   enable_affinity_temp="-DCPU_AFFINITY=1"
   AC_MSG_RESULT(yes)
 else
@@ -285,7 +286,7 @@ if test "${with_gm+set}" = set; then
   if test "${with_gm}" = yes; then
     with_gm="-I/usr/local/gm/include"
   else
-    with_gm=-I"$with_gm/include"
+    with_gm="-I$with_gm/include -I$with_gm/drivers -I$with_gm/drivers/linux/gm"
   fi
   GMNAL="gmnal"
 else
@@ -296,6 +297,28 @@ AC_SUBST(with_gm)
 AC_SUBST(GMNAL)
 
 
+#fixme: where are the default IB includes?
+default_ib_include_dir=/usr/local/ib/include
+an_ib_include_file=vapi.h
+
+AC_ARG_WITH(ib, [ --with-ib=[yes/no/path] Path to IB includes], with_ib=$withval, with_ib=$default_ib)
+AC_MSG_CHECKING(if IB headers are present)
+if test "$with_ib" = yes; then
+    with_ib=$default_ib_include_dir
+fi
+if test "$with_ib" != no -a -f ${with_ib}/${an_ib_include_file}; then
+    AC_MSG_RESULT(yes)
+    IBNAL="ibnal"
+    with_ib="-I${with_ib}"
+else
+    AC_MSG_RESULT(no)
+    IBNAL=""
+    with_ib=""
+fi
+AC_SUBST(IBNAL)
+AC_SUBST(with_ib)
+
+
 def_scamac=/opt/scali/include
 AC_ARG_WITH(scamac, [  --with-scamac=[yes/no/path] Path to ScaMAC includes (default=/opt/scali/include)], with_scamac=$withval, with_scamac=$def_scamac)
 AC_MSG_CHECKING(if ScaMAC headers are present)
@@ -316,7 +339,7 @@ AC_SUBST(with_scamac)
 AC_SUBST(SCIMACNAL)
 
 CFLAGS="$KCFLAGS"
-CPPFLAGS="$KINCFLAGS $KCPPFLAGS $MFLAGS $enable_zerocopy $enable_affinity $with_quadrics $with_gm $with_scamac "
+CPPFLAGS="$KINCFLAGS $KCPPFLAGS $MFLAGS $enable_zerocopy $enable_affinity $with_quadrics $with_gm $with_scamac $with_ib"
 
 AC_SUBST(MOD_LINK)
 AC_SUBST(LINUX25)
diff --git a/lustre/portals/build.m4 b/lustre/portals/build.m4
index 025f243840d8e9ce9e33989f9b579e2a957282ff..8c55b20c130f948e09ee11aabf6e224cb3ec5884 100644
--- a/lustre/portals/build.m4
+++ b/lustre/portals/build.m4
@@ -16,6 +16,9 @@ bindir='${exec_prefix}/usr/bin'
 sbindir='${exec_prefix}/usr/sbin'
 includedir='${prefix}/usr/include'
 
+rootsbindir='${exec_prefix}/sbin'
+AC_SUBST(rootsbindir)
+
 # Directories for documentation and demos.
 docdir='${prefix}/usr/share/doc/$(PACKAGE)'
 AC_SUBST(docdir)
diff --git a/lustre/portals/configure.in b/lustre/portals/configure.in
index 31d349245706b4d38038926f68b0b2d9f13eea9d..44657e06171c788b8d3009c7d0586ea6f19ddc62 100644
--- a/lustre/portals/configure.in
+++ b/lustre/portals/configure.in
@@ -29,6 +29,6 @@ AM_CONFIG_HEADER(include/config.h)
 AC_OUTPUT([Makefile Kernelenv libcfs/Makefile portals/Makefile \
           unals/Makefile knals/Makefile router/Makefile \
 	  knals/socknal/Makefile knals/gmnal/Makefile knals/qswnal/Makefile \
-	  knals/scimacnal/Makefile knals/toenal/Makefile \
+	  knals/scimacnal/Makefile knals/toenal/Makefile knals/ibnal/Makefile\
           utils/Makefile tests/Makefile doc/Makefile ])
 
diff --git a/lustre/portals/include/cygwin-ioctl.h b/lustre/portals/include/cygwin-ioctl.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ecefff056314df652356c33465ee31df502119a
--- /dev/null
+++ b/lustre/portals/include/cygwin-ioctl.h
@@ -0,0 +1,82 @@
+/* $Id: cygwin-ioctl.h,v 1.2 2003/12/03 03:14:43 phil Exp $
+ *
+ * linux/ioctl.h for Linux by H.H. Bergman.
+ */
+
+#ifndef _ASMI386_IOCTL_H
+#define _ASMI386_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#undef _IO
+#undef _IOR
+#undef _IOW
+#undef _IOC
+#undef IOC_IN
+#undef IOC_OUT
+
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _ASMI386_IOCTL_H */
diff --git a/lustre/portals/include/linux/kp30.h b/lustre/portals/include/linux/kp30.h
index 0a1cc57a78b4e8bec72c552a828ae9583d294ad9..3e6d5e31704c8dd6ba68f7bdf73e15230a5e079c 100644
--- a/lustre/portals/include/linux/kp30.h
+++ b/lustre/portals/include/linux/kp30.h
@@ -19,6 +19,7 @@ extern unsigned int portal_subsystem_debug;
 extern unsigned int portal_stack;
 extern unsigned int portal_debug;
 extern unsigned int portal_printk;
+extern unsigned int portal_cerror;
 /* Debugging subsystems (32 bits, non-overlapping) */
 #define S_UNDEFINED    (1 << 0)
 #define S_MDC          (1 << 1)
@@ -42,6 +43,7 @@ extern unsigned int portal_printk;
 #define S_GMNAL       (1 << 19)
 #define S_PTLROUTER   (1 << 20)
 #define S_COBD        (1 << 21)
+#define S_IBNAL       (1 << 22)
 
 /* If you change these values, please keep portals/utils/debug.c
  * up to date! */
@@ -57,7 +59,7 @@ extern unsigned int portal_printk;
 #define D_IOCTL     (1 << 7) /* ioctl related information */
 #define D_BLOCKS    (1 << 8) /* ext2 block allocation */
 #define D_NET       (1 << 9) /* network communications */
-#define D_WARNING   (1 << 10)
+#define D_WARNING   (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
 #define D_BUFFS     (1 << 11)
 #define D_OTHER     (1 << 12)
 #define D_DENTRY    (1 << 13)
@@ -72,10 +74,14 @@ extern unsigned int portal_printk;
 
 #ifdef __KERNEL__
 # include <linux/sched.h> /* THREAD_SIZE */
-#else
-# define THREAD_SIZE 8192
+#else 
+# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */
+#  define THREAD_SIZE 8192
+# endif
 #endif
 
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
 #ifdef __KERNEL__
 # ifdef  __ia64__
 #  define CDEBUG_STACK (THREAD_SIZE -                                      \
@@ -106,6 +112,8 @@ extern unsigned int portal_printk;
 #if 1
 #define CDEBUG(mask, format, a...)                                            \
 do {                                                                          \
+        if (portal_cerror == 0)                                               \
+                break;                                                        \
         CHECK_STACK(CDEBUG_STACK);                                            \
         if (!(mask) || ((mask) & (D_ERROR | D_EMERG)) ||                      \
             (portal_debug & (mask) &&                                         \
@@ -185,6 +193,7 @@ static inline void our_cond_resched(void)
         if (current->need_resched)
                schedule ();
 }
+#define work_struct_t       struct tq_struct 
 
 #else
 
@@ -200,6 +209,8 @@ static inline void our_cond_resched(void)
 {
         cond_resched();
 }
+#define work_struct_t      struct work_struct
+
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
 
 #ifdef PORTAL_DEBUG
@@ -207,8 +218,22 @@ extern void kportal_assertion_failed(char *expr, char *file, const char *func,
                                      const int line);
 #define LASSERT(e) ((e) ? 0 : kportal_assertion_failed( #e , __FILE__,  \
                                                         __FUNCTION__, __LINE__))
+/* it would be great to dump_stack() here, but some kernels
+ * export it as show_stack() and I can't be bothered to
+ * proprely engage in that dance right now */ 
+#define LASSERTF(cond, fmt...)                                                \
+        do {                                                                  \
+                if (unlikely(!(cond))) {                                      \
+                        portals_debug_msg(0, D_EMERG,  __FILE__, __FUNCTION__,\
+                                          __LINE__,  CDEBUG_STACK,            \
+                                          "ASSERTION(" #cond ") failed:" fmt);\
+                        LBUG();                                               \
+                }                                                             \
+        } while (0)
+                                
 #else
 #define LASSERT(e)
+#define LASSERTF(cond, fmt...) do { } while (0)
 #endif
 
 #ifdef __arch_um__
@@ -254,13 +279,17 @@ do {                                                                          \
 
 #define PORTAL_VMALLOC_SIZE        16384
 
+#ifndef GFP_MEMALLOC
+#define GFP_MEMALLOC 0
+#endif
+
 #define PORTAL_ALLOC(ptr, size)                                           \
 do {                                                                      \
         LASSERT (!in_interrupt());                                        \
         if ((size) > PORTAL_VMALLOC_SIZE)                                 \
                 (ptr) = vmalloc(size);                                    \
         else                                                              \
-                (ptr) = kmalloc((size), GFP_NOFS);                        \
+                (ptr) = kmalloc((size), (GFP_KERNEL | GFP_MEMALLOC));     \
         if ((ptr) == NULL)                                                \
                 CERROR("PORTALS: out of memory at %s:%d (tried to alloc '"\
                        #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));\
@@ -289,10 +318,14 @@ do {                                                                    \
                s, (ptr), atomic_read(&portal_kmemory));                 \
 } while (0)
 
+#ifndef SLAB_MEMALLOC
+#define SLAB_MEMALLOC 0
+#endif
+
 #define PORTAL_SLAB_ALLOC(ptr, slab, size)                                \
 do {                                                                      \
         LASSERT(!in_interrupt());                                         \
-        (ptr) = kmem_cache_alloc((slab), SLAB_KERNEL);                    \
+        (ptr) = kmem_cache_alloc((slab), (SLAB_KERNEL | SLAB_MEMALLOC));  \
         if ((ptr) == NULL) {                                              \
                 CERROR("PORTALS: out of memory at %s:%d (tried to alloc"  \
                        " '" #ptr "' from slab '" #slab "')\n", __FILE__,  \
@@ -575,6 +608,9 @@ extern struct prof_ent prof_ents[MAX_PROFS];
 #endif /* PORTALS_PROFILING */
 
 /* debug.c */
+extern spinlock_t stack_backtrace_lock;
+
+char *portals_debug_dumpstack(void);
 void portals_run_upcall(char **argv);
 void portals_run_lbug_upcall(char * file, const char *fn, const int line);
 void portals_debug_dumplog(void);
@@ -596,7 +632,7 @@ __s32 portals_debug_copy_to_user(char *buf, unsigned long len);
 #endif
 void portals_debug_msg(int subsys, int mask, char *file, const char *fn,
                        const int line, unsigned long stack,
-                       const char *format, ...)
+                       char *format, ...)
         __attribute__ ((format (printf, 7, 8)));
 #else
 void portals_debug_msg(int subsys, int mask, char *file, const char *fn,
@@ -617,6 +653,8 @@ extern void kportal_blockallsigs (void);
 # include <stdlib.h>
 #ifndef __CYGWIN__
 # include <stdint.h>
+#else
+# include <cygwin-ioctl.h>
 #endif
 # include <unistd.h>
 # include <time.h>
@@ -628,8 +666,10 @@ extern void kportal_blockallsigs (void);
 #  undef NDEBUG
 #  include <assert.h>
 #  define LASSERT(e)     assert(e)
+#  define LASSERTF(cond, args...)     assert(cond)
 # else
 #  define LASSERT(e)
+#  define LASSERTF(cond, args...) do { } while (0)
 # endif
 # define printk(format, args...) printf (format, ## args)
 # define PORTAL_ALLOC(ptr, size) do { (ptr) = malloc(size); } while (0);
@@ -640,6 +680,9 @@ extern void kportal_blockallsigs (void);
            getpid() , stack, ## a);
 #endif
 
+/* support decl needed both by kernel and liblustre */
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str);
+
 #ifndef CURRENT_TIME
 # define CURRENT_TIME time(0)
 #endif
@@ -657,6 +700,9 @@ typedef struct {
         long        lwte_p2;
         long        lwte_p3;
         long        lwte_p4;
+#if BITS_PER_LONG > 32
+        long        lwte_pad;
+#endif
 } lwt_event_t;
 
 #if LWT_SUPPORT
@@ -736,6 +782,40 @@ do {                                                                    \
  * USER LEVEL STUFF BELOW
  */
 
+#define PORTALS_CFG_VERSION 0x00010001;
+
+struct portals_cfg {
+        __u32 pcfg_version;
+        __u32 pcfg_command;
+
+        __u32 pcfg_nal;
+        __u32 pcfg_flags;
+
+        __u32 pcfg_gw_nal;
+        __u64 pcfg_nid;
+        __u64 pcfg_nid2;
+        __u64 pcfg_nid3;
+        __u32 pcfg_id;
+        __u32 pcfg_misc;
+        __u32 pcfg_fd;
+        __u32 pcfg_count;
+        __u32 pcfg_size;
+        __u32 pcfg_wait;
+
+        __u32 pcfg_plen1; /* buffers in userspace */
+        char *pcfg_pbuf1;
+        __u32 pcfg_plen2; /* buffers in userspace */
+        char *pcfg_pbuf2;
+};
+
+#define PCFG_INIT(pcfg, cmd)                            \
+do {                                                    \
+        memset(&pcfg, 0, sizeof(pcfg));                 \
+        pcfg.pcfg_version = PORTALS_CFG_VERSION;        \
+        pcfg.pcfg_command = (cmd);                      \
+                                                        \
+} while (0)
+
 #define PORTAL_IOCTL_VERSION 0x00010007
 #define PING_SYNC       0
 #define PING_ASYNC      1
@@ -957,18 +1037,14 @@ static inline int portal_ioctl_getdata(char *buf, char *end, void *arg)
 #define IOC_PORTAL_CLEAR_DEBUG             _IOWR('e', 32, long)
 #define IOC_PORTAL_MARK_DEBUG              _IOWR('e', 33, long)
 #define IOC_PORTAL_PANIC                   _IOWR('e', 34, long)
-#define IOC_PORTAL_ADD_ROUTE               _IOWR('e', 35, long)
-#define IOC_PORTAL_DEL_ROUTE               _IOWR('e', 36, long)
-#define IOC_PORTAL_GET_ROUTE               _IOWR('e', 37, long)
-#define IOC_PORTAL_NAL_CMD	           _IOWR('e', 38, long)
-#define IOC_PORTAL_GET_NID                 _IOWR('e', 39, long)
-#define IOC_PORTAL_FAIL_NID                _IOWR('e', 40, long)
-#define IOC_PORTAL_SET_DAEMON              _IOWR('e', 41, long)
-#define IOC_PORTAL_NOTIFY_ROUTER           _IOWR('e', 42, long)
-#define IOC_PORTAL_LWT_CONTROL             _IOWR('e', 43, long)
-#define IOC_PORTAL_LWT_SNAPSHOT            _IOWR('e', 44, long)
-#define IOC_PORTAL_LWT_LOOKUP_STRING       _IOWR('e', 45, long)
-#define IOC_PORTAL_MAX_NR                             45
+#define IOC_PORTAL_NAL_CMD	           _IOWR('e', 35, long)
+#define IOC_PORTAL_GET_NID                 _IOWR('e', 36, long)
+#define IOC_PORTAL_FAIL_NID                _IOWR('e', 37, long)
+#define IOC_PORTAL_SET_DAEMON              _IOWR('e', 38, long)
+#define IOC_PORTAL_LWT_CONTROL             _IOWR('e', 39, long)
+#define IOC_PORTAL_LWT_SNAPSHOT            _IOWR('e', 40, long)
+#define IOC_PORTAL_LWT_LOOKUP_STRING       _IOWR('e', 41, long)
+#define IOC_PORTAL_MAX_NR                             41
 
 enum {
         QSWNAL  =  1,
@@ -977,6 +1053,8 @@ enum {
         TOENAL,
         TCPNAL,
         SCIMACNAL,
+        ROUTER,
+        IBNAL,
         NAL_ENUM_END_MARKER
 };
 
@@ -985,9 +1063,12 @@ extern ptl_handle_ni_t  kqswnal_ni;
 extern ptl_handle_ni_t  ksocknal_ni;
 extern ptl_handle_ni_t  ktoenal_ni;
 extern ptl_handle_ni_t  kgmnal_ni;
+extern ptl_handle_ni_t  kibnal_ni;
 extern ptl_handle_ni_t  kscimacnal_ni;
 #endif
 
+#define PTL_NALFMT_SIZE         16
+
 #define NAL_MAX_NR (NAL_ENUM_END_MARKER - 1)
 
 #define NAL_CMD_REGISTER_PEER_FD     100
@@ -999,6 +1080,10 @@ extern ptl_handle_ni_t  kscimacnal_ni;
 #define NAL_CMD_ADD_AUTOCONN         106
 #define NAL_CMD_GET_AUTOCONN         107
 #define NAL_CMD_GET_TXDESC           108
+#define NAL_CMD_ADD_ROUTE            109
+#define NAL_CMD_DEL_ROUTE            110
+#define NAL_CMD_GET_ROUTE            111
+#define NAL_CMD_NOTIFY_ROUTER        112
 
 enum {
         DEBUG_DAEMON_START       =  1,
@@ -1013,11 +1098,20 @@ struct lustre_peer {
         ptl_handle_ni_t peer_ni;
 };
 
+
 /* module.c */
-typedef int (*nal_cmd_handler_t)(struct portal_ioctl_data *, void * private);
+typedef int (*nal_cmd_handler_t)(struct portals_cfg *, void * private);
 int kportal_nal_register(int nal, nal_cmd_handler_t handler, void * private);
 int kportal_nal_unregister(int nal);
 
+enum cfg_record_type {
+        PORTALS_CFG_TYPE = 1,
+        LUSTRE_CFG_TYPE = 123,
+};
+
+typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
+int kportal_nal_cmd(struct portals_cfg *);
+
 ptl_handle_ni_t *kportal_get_ni (int nal);
 void kportal_put_ni (int nal);
 
@@ -1031,14 +1125,19 @@ void kportal_put_ni (int nal);
 # endif
 #endif
 
-#if (BITS_PER_LONG == 32 || __WORDSIZE == 32)
+#if defined(__x86_64__)
+# define LPU64 "%Lu"
+# define LPD64 "%Ld"
+# define LPX64 "%#Lx"
+# define LPSZ  "%lu"
+# define LPSSZ "%ld"
+#elif (BITS_PER_LONG == 32 || __WORDSIZE == 32)
 # define LPU64 "%Lu"
 # define LPD64 "%Ld"
 # define LPX64 "%#Lx"
 # define LPSZ  "%u"
 # define LPSSZ "%d"
-#endif
-#if (BITS_PER_LONG == 64 || __WORDSIZE == 64)
+#elif (BITS_PER_LONG == 64 || __WORDSIZE == 64)
 # define LPU64 "%lu"
 # define LPD64 "%ld"
 # define LPX64 "%#lx"
diff --git a/lustre/portals/include/linux/portals_lib.h b/lustre/portals/include/linux/portals_lib.h
index a528a80fb440513929ee310911cb099293dc3b3d..609290ddcb15c383fe0bfbb30405a7d1a55aa908 100644
--- a/lustre/portals/include/linux/portals_lib.h
+++ b/lustre/portals/include/linux/portals_lib.h
@@ -42,6 +42,16 @@ static inline int size_round (int val)
         return (val + 7) & (~0x7);
 }
 
+static inline int size_round16(int val)
+{
+        return (val + 0xf) & (~0xf);
+}
+
+static inline int size_round32(int val)
+{
+        return (val + 0x1f) & (~0x1f);
+}
+
 static inline int size_round0(int val)
 {
         if (!val)
diff --git a/lustre/portals/include/portals/lib-p30.h b/lustre/portals/include/portals/lib-p30.h
index b623b938b6e76116f53d0257738a47067e9b98f4..55fd720eebe80998306696bddc0f4045b3d2f4dc 100644
--- a/lustre/portals/include/portals/lib-p30.h
+++ b/lustre/portals/include/portals/lib-p30.h
@@ -30,7 +30,6 @@ static inline int ptl_is_wire_handle_none (ptl_handle_wire_t *wh)
                 wh->wh_object_cookie == PTL_WIRE_HANDLE_NONE.wh_object_cookie);
 }
 
-#ifdef __KERNEL__
 #define state_lock(nal,flagsp)                          \
 do {                                                    \
         CDEBUG(D_PORTALS, "taking state lock\n");       \
@@ -42,20 +41,6 @@ do {                                                    \
         CDEBUG(D_PORTALS, "releasing state lock\n");    \
         nal->cb_sti(nal, flagsp);                       \
 }
-#else
-/* not needed in user space until we thread there */
-#define state_lock(nal,flagsp)                          \
-do {                                                    \
-        CDEBUG(D_PORTALS, "taking state lock\n");       \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-} while (0)
-
-#define state_unlock(nal,flagsp)                        \
-{                                                       \
-        CDEBUG(D_PORTALS, "releasing state lock\n");    \
-        CDEBUG(D_PORTALS, "%p:%p\n", nal, flagsp);      \
-}
-#endif /* __KERNEL__ */
 
 #ifndef PTL_USE_SLAB_CACHE
 
@@ -361,6 +346,8 @@ extern char *dispatch_name(int index);
  */
 extern int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private);
 extern int lib_finalize(nal_cb_t * nal, void *private, lib_msg_t * msg);
+extern lib_msg_t *lib_fake_reply_msg (nal_cb_t *nal, ptl_nid_t peer_nid, 
+                                      lib_md_t *getmd);
 extern void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr);
 
 extern ptl_size_t lib_iov_nob (int niov, struct iovec *iov);
diff --git a/lustre/portals/include/portals/lib-types.h b/lustre/portals/include/portals/lib-types.h
index 47c0dd247b8ea187d754c88027250bccda9292e6..30e56af8138c89a54a443355727a199f3a972894 100644
--- a/lustre/portals/include/portals/lib-types.h
+++ b/lustre/portals/include/portals/lib-types.h
@@ -54,72 +54,68 @@ typedef enum {
         PTL_MSG_HELLO,
 } ptl_msg_type_t;
 
-/* Each of these structs should start with an odd number of
- * __u32, or the compiler could add its own padding and confuse
- * everyone.
- *
- * Also, "length" needs to be at offset 28 of each struct.
- */
+/* The variant fields of the portals message header are aligned on an 8
+ * byte boundary in the message header.  Note that all types used in these
+ * wire structs MUST be fixed size and the smaller types are placed at the
+ * end. */
 typedef struct ptl_ack {
-        ptl_size_t mlength;
-        ptl_handle_wire_t dst_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length (0 for acks) moving out RSN */
+        ptl_handle_wire_t  dst_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_size_t         mlength;
 } WIRE_ATTR ptl_ack_t;
 
 typedef struct ptl_put {
-        ptl_pt_index_t ptl_index;
-        ptl_handle_wire_t ack_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length moving out RSN */
-        ptl_size_t offset;
-        ptl_hdr_data_t hdr_data;
+        ptl_handle_wire_t  ack_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_hdr_data_t     hdr_data;
+        ptl_pt_index_t     ptl_index;
+        ptl_size_t         offset;
 } WIRE_ATTR ptl_put_t;
 
 typedef struct ptl_get {
-        ptl_pt_index_t ptl_index;
-        ptl_handle_wire_t return_wmd;
-        ptl_match_bits_t match_bits;
-        ptl_size_t length;                      /* common length (0 for gets) moving out RSN */
-        ptl_size_t src_offset;
-        ptl_size_t return_offset;               /* unused: going RSN */
-        ptl_size_t sink_length;
+        ptl_handle_wire_t  return_wmd;
+        ptl_match_bits_t   match_bits;
+        ptl_pt_index_t     ptl_index;
+        ptl_size_t         src_offset;
+        ptl_size_t         sink_length;
 } WIRE_ATTR ptl_get_t;
 
 typedef struct ptl_reply {
-        __u32 unused1;                          /* unused fields going RSN */
-        ptl_handle_wire_t dst_wmd;
-        ptl_size_t dst_offset;                  /* unused: going RSN */
-        __u32 unused2;
-        ptl_size_t length;                      /* common length moving out RSN */
+        ptl_handle_wire_t  dst_wmd;
 } WIRE_ATTR ptl_reply_t;
 
+typedef struct ptl_hello {
+        __u64              incarnation;
+        __u32              type;
+} WIRE_ATTR ptl_hello_t;
+
 typedef struct {
-        ptl_nid_t dest_nid;
-        ptl_nid_t src_nid;
-        ptl_pid_t dest_pid;
-        ptl_pid_t src_pid;
-        __u32 type; /* ptl_msg_type_t */
+        ptl_nid_t           dest_nid;
+        ptl_nid_t           src_nid;
+        ptl_pid_t           dest_pid;
+        ptl_pid_t           src_pid;
+        __u32               type;               /* ptl_msg_type_t */
+        __u32               payload_length;     /* payload data to follow */
+        /*<------__u64 aligned------->*/
         union {
-                ptl_ack_t ack;
-                ptl_put_t put;
-                ptl_get_t get;
+                ptl_ack_t   ack;
+                ptl_put_t   put;
+                ptl_get_t   get;
                 ptl_reply_t reply;
+                ptl_hello_t hello;
         } msg;
 } WIRE_ATTR ptl_hdr_t;
 
-/* All length fields in individual unions at same offset */
-/* LASSERT for same in lib-move.c */
-#define PTL_HDR_LENGTH(h) ((h)->msg.ack.length)
-
 /* A HELLO message contains the portals magic number and protocol version
  * code in the header's dest_nid, the peer's NID in the src_nid, and
- * PTL_MSG_HELLO in the type field.  All other fields are zero (including
- * PTL_HDR_LENGTH; i.e. no payload).
+ * PTL_MSG_HELLO in the type field.  All other common fields are zero
+ * (including payload_size; i.e. no payload).  
  * This is for use by byte-stream NALs (e.g. TCP/IP) to check the peer is
  * running the same protocol and to find out its NID, so that hosts with
  * multiple IP interfaces can have a single NID. These NALs should exchange
- * HELLO messages when a connection is first established. */
+ * HELLO messages when a connection is first established. 
+ * Individual NALs can put whatever else they fancy in ptl_hdr_t::msg. 
+ */
 typedef struct {
         __u32	magic;                          /* PORTALS_PROTO_MAGIC */
         __u16   version_major;                  /* increment on incompatible change */
@@ -129,7 +125,7 @@ typedef struct {
 #define PORTALS_PROTO_MAGIC                0xeebc0ded
 
 #define PORTALS_PROTO_VERSION_MAJOR        0
-#define PORTALS_PROTO_VERSION_MINOR        1
+#define PORTALS_PROTO_VERSION_MINOR        3
 
 typedef struct {
         long recv_count, recv_length, send_count, send_length, drop_count,
@@ -137,11 +133,9 @@ typedef struct {
 } lib_counters_t;
 
 /* temporary expedient: limit number of entries in discontiguous MDs */
-#if PTL_LARGE_MTU
-# define PTL_MD_MAX_IOV	64
-#else
-# define PTL_MD_MAX_IOV 16
-#endif
+# define PTL_MTU        (512<<10)
+# define PTL_MD_MAX_IOV 128
+# define PTL_MD_MAX_PAGES min_t(int, PTL_MD_MAX_IOV, PTL_MTU / PAGE_SIZE)
 
 struct lib_msg_t {
         struct list_head  msg_list;
diff --git a/lustre/portals/include/portals/list.h b/lustre/portals/include/portals/list.h
index 78a1e2dd31bea8ac1be54cc9aac1636283cded3f..57713cb637ed3c725954ef16a7793a073966d4cf 100644
--- a/lustre/portals/include/portals/list.h
+++ b/lustre/portals/include/portals/list.h
@@ -16,6 +16,8 @@ struct list_head {
 	struct list_head *next, *prev;
 };
 
+typedef struct list_head list_t;
+
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
 #define LIST_HEAD(name) \
diff --git a/lustre/portals/include/portals/lltrace.h b/lustre/portals/include/portals/lltrace.h
index d389aab4300ed5955a7cd605d1a294104eaf0466..5f266e25b2f74bd207bc8e19e8caf6f7a31f79bc 100644
--- a/lustre/portals/include/portals/lltrace.h
+++ b/lustre/portals/include/portals/lltrace.h
@@ -18,8 +18,8 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <portals/types.h>
-#include <portals/ptlctl.h>
 #include <linux/kp30.h>
+#include <portals/ptlctl.h>
 #include <linux/limits.h>
 #include <asm/page.h>
 #include <linux/version.h>
diff --git a/lustre/portals/include/portals/ptlctl.h b/lustre/portals/include/portals/ptlctl.h
index 7763f1b548be7333ab117ae02733f89d8bc34ddc..f581e7228beebdf2f92a11894890fabeab92ff1f 100644
--- a/lustre/portals/include/portals/ptlctl.h
+++ b/lustre/portals/include/portals/ptlctl.h
@@ -29,6 +29,7 @@
 #define OBD_DEV_PATH "/dev/obd"
 
 int ptl_name2nal(char *str);
+int ptl_parse_ipaddr (__u32 *ipaddrp, char *str);
 int ptl_parse_nid (ptl_nid_t *nidp, char *str);
 char * ptl_nid2str (char *buffer, ptl_nid_t nid);
 
@@ -71,7 +72,11 @@ int jt_dbg_mark_debug_buf(int argc, char **argv);
 int jt_dbg_modules(int argc, char **argv);
 int jt_dbg_panic(int argc, char **argv);
 
+int ptl_set_cfg_record_cb(cfg_record_cb_t cb);
+
 /* l_ioctl.c */
+typedef int (ioc_handler_t)(int dev_id, int opc, void *buf);
+void set_ioc_handler(ioc_handler_t *handler);
 int register_ioc_dev(int dev_id, const char * dev_name);
 void unregister_ioc_dev(int dev_id);
 int set_ioctl_dump(char * file);
diff --git a/lustre/portals/include/portals/socknal.h b/lustre/portals/include/portals/socknal.h
new file mode 100644
index 0000000000000000000000000000000000000000..27e6f8e07f58cb9345296fb9949e0805bcf574fa
--- /dev/null
+++ b/lustre/portals/include/portals/socknal.h
@@ -0,0 +1,14 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * <portals/socknal.h>
+ *
+ * #defines shared between socknal implementation and utilities
+ */
+
+#define SOCKNAL_CONN_NONE     (-1)
+#define SOCKNAL_CONN_ANY        0
+#define SOCKNAL_CONN_CONTROL    1
+#define SOCKNAL_CONN_BULK_IN    2
+#define SOCKNAL_CONN_BULK_OUT   3
+#define SOCKNAL_CONN_NTYPES     4
diff --git a/lustre/portals/include/portals/types.h b/lustre/portals/include/portals/types.h
index 02692905d03be1cb47f97831f3de66abd0b738e9..e4ccebfdbb5f3d02883736cf3494a9a4416279af 100644
--- a/lustre/portals/include/portals/types.h
+++ b/lustre/portals/include/portals/types.h
@@ -104,6 +104,13 @@ typedef enum {
 typedef unsigned PTL_SEQ_BASETYPE ptl_seq_t;
 #define PTL_SEQ_GT(a,b)	(((signed PTL_SEQ_BASETYPE)((a) - (b))) > 0)
 
+/* XXX
+ * cygwin need the pragma line, not clear if it's needed in other places.
+ * checking!!!
+ */
+#ifdef __CYGWIN__
+#pragma pack(push, 4)
+#endif
 typedef struct {
         ptl_event_kind_t type;
         ptl_process_id_t initiator;
@@ -116,6 +123,9 @@ typedef struct {
         struct timeval arrival_time;
         volatile ptl_seq_t sequence;
 } ptl_event_t;
+#ifdef __CYGWIN__
+#pragma pop
+#endif
 
 typedef enum {
         PTL_ACK_REQ,
diff --git a/lustre/portals/knals/Makefile.am b/lustre/portals/knals/Makefile.am
index fed2785b5b467bed04c0436f9cbd5ddd6d68206f..25aab9db39ccb5e72d0f45935a974497f24ed321 100644
--- a/lustre/portals/knals/Makefile.am
+++ b/lustre/portals/knals/Makefile.am
@@ -3,5 +3,5 @@
 # This code is issued under the GNU General Public License.
 # See the file COPYING in this distribution
 
-DIST_SUBDIRS= socknal toenal qswnal gmnal scimacnal 
-SUBDIRS= socknal toenal	@QSWNAL@ @GMNAL@ @SCIMACNAL@
+DIST_SUBDIRS= socknal toenal qswnal gmnal scimacnal ibnal
+SUBDIRS= socknal toenal	@QSWNAL@ @GMNAL@ @SCIMACNAL@ @IBNAL@
diff --git a/lustre/portals/knals/gmnal/Makefile.am b/lustre/portals/knals/gmnal/Makefile.am
index 1dc6f4eb083126287ea5936a84e4672766ca1dcf..bac4680c9a17db8874f2c2394c4a1f08415d4d9c 100644
--- a/lustre/portals/knals/gmnal/Makefile.am
+++ b/lustre/portals/knals/gmnal/Makefile.am
@@ -9,5 +9,5 @@ MODULE = kgmnal
 modulenet_DATA = kgmnal.o
 EXTRA_PROGRAMS = kgmnal
 
-DEFS =
-kgmnal_SOURCES = gmnal.c gmnal_cb.c gmnal.h
+DEFS = -DGM_KERNEL
+kgmnal_SOURCES = gmnal.h gmnal_api.c gmnal_cb.c gmnal_comm.c gmnal_utils.c gmnal_module.c
diff --git a/lnet/klnds/lgmlnd/Makefile.mk b/lustre/portals/knals/gmnal/Makefile.mk
similarity index 63%
rename from lnet/klnds/lgmlnd/Makefile.mk
rename to lustre/portals/knals/gmnal/Makefile.mk
index c8ca67fad856c015acb207c3f2a1a251a95ebe31..b799a47e4db54219178eade8164e38f50e13a755 100644
--- a/lnet/klnds/lgmlnd/Makefile.mk
+++ b/lustre/portals/knals/gmnal/Makefile.mk
@@ -5,6 +5,6 @@
 
 include ../../Kernelenv
 
-obj-y += lgmnal.o
-lgmnal-objs    := lgmnal_api.o lgmnal_cb.o lgmnal_utils.o lgmnal_comm.o lgmnal_module.o
+obj-y += gmnal.o
+gmnal-objs    := gmnal_api.o gmnal_cb.o gmnal_utils.o gmnal_comm.o gmnal_module.o
 
diff --git a/lustre/portals/knals/gmnal/gm-1.5.2.1-exports.patch b/lustre/portals/knals/gmnal/gm-1.5.2.1-exports.patch
deleted file mode 100644
index 23c80d940806e4b91c75bd7d023b4262ca3b3753..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/gmnal/gm-1.5.2.1-exports.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -ru gm-1.5.2.1_Linux/drivers/linux/gm/gm_arch.c gm-1.5.2.1_Linux-cfs/drivers/linux/gm/gm_arch.c
---- gm-1.5.2.1_Linux/drivers/linux/gm/gm_arch.c	Mon Jul  1 10:35:09 2002
-+++ gm-1.5.2.1_Linux-cfs/drivers/linux/gm/gm_arch.c	Thu Sep 19 14:19:38 2002
-@@ -30,6 +30,8 @@
-  *
-  ************************************************************************/
- 
-+#define EXPORT_SYMTAB
-+
- #include <linux/config.h>
- #include <linux/module.h>
- 
-@@ -4075,6 +4077,28 @@
-   return 0;
- }
- 
-+EXPORT_SYMBOL(gm_blocking_receive_no_spin);
-+EXPORT_SYMBOL(gm_close);
-+EXPORT_SYMBOL(gm_dma_free);
-+EXPORT_SYMBOL(gm_dma_malloc);
-+EXPORT_SYMBOL(gm_drop_sends);
-+EXPORT_SYMBOL(gm_finalize);
-+EXPORT_SYMBOL(gm_get_node_id);
-+EXPORT_SYMBOL(gm_init);
-+EXPORT_SYMBOL(gm_initialize_alarm);
-+EXPORT_SYMBOL(gm_max_node_id_in_use);
-+EXPORT_SYMBOL(gm_min_size_for_length);
-+EXPORT_SYMBOL(gm_num_receive_tokens);
-+EXPORT_SYMBOL(gm_num_send_tokens);
-+EXPORT_SYMBOL(gm_open);
-+EXPORT_SYMBOL(gm_provide_receive_buffer);
-+EXPORT_SYMBOL(gm_resume_sending);
-+EXPORT_SYMBOL(gm_send_with_callback);
-+EXPORT_SYMBOL(gm_set_acceptable_sizes);
-+EXPORT_SYMBOL(gm_set_alarm);
-+EXPORT_SYMBOL(gm_unknown);
-+
-+
- /*
-   This file uses GM standard indentation.
- 
-Only in gm-1.5.2.1_Linux-cfs/drivers/linux/gm: gm_arch.c~
-Only in gm-1.5.2.1_Linux-cfs/: trace
diff --git a/lustre/portals/knals/gmnal/gmnal.c b/lustre/portals/knals/gmnal/gmnal.c
deleted file mode 100644
index 0cffc1587b48367e547bfe0e0dbf3c3d20d98b59..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/gmnal/gmnal.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Based on ksocknal and qswnal
- *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *   Author: Robert Read  <rread@datarithm.net>
- *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- *
- *   Portals is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Portals 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 Portals; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "gmnal.h"
-
-ptl_handle_ni_t kgmnal_ni;
-nal_t  kgmnal_api;
-
-kgmnal_data_t kgmnal_data;
-int gmnal_debug = 0;
-
-kpr_nal_interface_t kqswnal_router_interface = {
-        kprni_nalid:        GMNAL,
-        kprni_arg:        NULL,
-        kprni_fwd:          kgmnal_fwd_packet,
-};
-
-static int kgmnal_forward(nal_t   *nal,
-                          int     id,
-                          void    *args,  size_t args_len,
-                          void    *ret,   size_t ret_len)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        lib_dispatch(nal_cb, k, id, args, ret); /* nal needs k */
-        return PTL_OK;
-}
-
-static void kgmnal_lock(nal_t *nal, unsigned long *flags)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        nal_cb->cb_cli(nal_cb,flags);
-}
-
-static void kgmnal_unlock(nal_t *nal, unsigned long *flags)
-{
-        kgmnal_data_t *k = nal->nal_data;
-        nal_cb_t      *nal_cb = k->kgm_cb;
-
-
-        LASSERT (nal == &kgmnal_api);
-        LASSERT (k == &kgmnal_data);
-        LASSERT (nal_cb == &kgmnal_lib);
-
-        nal_cb->cb_sti(nal_cb,flags);
-}
-
-static int kgmnal_shutdown(nal_t *nal, int ni)
-{
-        LASSERT (nal == &kgmnal_api);
-        return 0;
-}
-
-static void kgmnal_yield( nal_t *nal )
-{
-        LASSERT (nal == &kgmnal_api);
-
-        if (current->need_resched)
-                schedule();
-        return;
-}
-
-kgmnal_rx_t *kgm_add_recv(kgmnal_data_t *data,int ndx)
-{
-        kgmnal_rx_t *conn;
-
-        PORTAL_ALLOC(conn, sizeof(kgmnal_rx_t));
-        /* Check for out of mem here */
-        if (conn==NULL) {
-                        printk("kgm_add_recv: memory alloc failed\n");
-                        return NULL;
-        }
-
-        list_add(&conn->krx_item,(struct list_head *)&data->kgm_list);
-        //        conn->ndx=ndx;
-        //        conn->len=conn->ptlhdr_copied=0;
-        //        conn->loopback=0;
-        return conn;
-}
-
-static nal_t *kgmnal_init(int interface, ptl_pt_index_t ptl_size,
-                          ptl_ac_index_t  ac_size, ptl_pid_t requested_pid)
-{
-        unsigned int nnids;
-
-        gm_max_node_id_in_use(kgmnal_data.kgm_port, &nnids);
-
-        CDEBUG(D_NET, "calling lib_init with nid 0x%Lx of %d\n",
-               kgmnal_data.kgm_nid, nnids);
-        lib_init(&kgmnal_lib, kgmnal_data.kgm_nid, 0, nnids,ptl_size, ac_size);
-        return &kgmnal_api;
-}
-
-static void /*__exit*/
-kgmnal_finalize(void)
-{
-        struct list_head *tmp;
-
-        PORTAL_SYMBOL_UNREGISTER (kgmnal_ni);
-        PtlNIFini(kgmnal_ni);
-        lib_fini(&kgmnal_api);
-
-        if (kgmnal_data.kgm_port) {
-                gm_close(kgmnal_data.kgm_port);
-        }
-
-        /* FIXME: free dma buffers */
-        /* FIXME: kill receiver thread */
-
-        PORTAL_FREE (kgmnal_data.kgm_trans, bsizeof(kgmnal_tx_t)*TXMSGS);
-
-        list_for_each(tmp, &kgmnal_data.kgm_list) {
-                kgmnal_rx_t *conn;
-                conn = list_entry(tmp, kgmnal_rx_t, krx_item);
-                CDEBUG(D_IOCTL, "freeing conn %p\n",conn);
-                tmp = tmp->next;
-                list_del(&conn->krx_item);
-                PORTAL_FREE(conn, sizeof(*conn));
-        }
-
-        CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read (&portal_kmemory));
-
-        return;
-}
-
-static int __init
-kgmnal_initialize(void)
-{
-        int rc;
-        int ntok;
-        unsigned long sizemask;
-        unsigned int nid;
-
-        CDEBUG (D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
-
-        kgmnal_api.forward = kgmnal_forward;
-        kgmnal_api.shutdown = kgmnal_shutdown;
-        kgmnal_api.yield = kgmnal_yield;
-        kgmnal_api.validate = NULL;         /* our api validate is a NOOP */
-        kgmnal_api.lock= kgmnal_lock;
-        kgmnal_api.unlock= kgmnal_unlock;
-        kgmnal_api.nal_data = &kgmnal_data;
-
-        kgmnal_lib.nal_data = &kgmnal_data;
-
-        memset(&kgmnal_data, 0, sizeof(kgmnal_data));
-
-        INIT_LIST_HEAD(&kgmnal_data.kgm_list);
-        kgmnal_data.kgm_cb = &kgmnal_lib;
-
-        /* Allocate transmit descriptors */
-        PORTAL_ALLOC (kgmnal_data.kgm_trans, sizeof(kgmnal_tx_t)*TXMSGS);
-        if (kgmnal_data.kgm_trans==NULL) {
-                printk("kgmnal: init: failed to allocate transmit "
-                       "descriptors\n");
-                return -1;
-        }
-        memset(kgmnal_data.kgm_trans,-1,sizeof(kgmnal_tx_t)*(TXMSGS));
-
-        spin_lock_init(&kgmnal_data.kgm_dispatch_lock);
-        spin_lock_init(&kgmnal_data.kgm_update_lock);
-        spin_lock_init(&kgmnal_data.kgm_send_lock);
-
-        /* Do the receiver and xmtr allocation */
-
-        rc = gm_init();
-        if (rc != GM_SUCCESS) {
-                CERROR("gm_init failed: %d\n", rc);
-                return -1;
-        }
-
-        rc = gm_open(&kgmnal_data.kgm_port, 0 , KGM_PORT_NUM, KGM_HOSTNAME,
-                     GM_API_VERSION_1_1);
-        if (rc != GM_SUCCESS) {
-                gm_finalize();
-                kgmnal_data.kgm_port = NULL;
-                CERROR("gm_open failed: %d\n", rc);
-                return -1;
-        }
-        gm_get_node_id(kgmnal_data.kgm_port, &nid);
-        kgmnal_data.kgm_nid = nid;
-        /* Allocate 2 different sizes of buffers. For new, use half
-           the tokens for each. */
-        ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
-        CDEBUG(D_NET, "gmnal_init: creating %d large %d byte recv buffers\n",
-               ntok, MSG_LEN_LARGE);
-        while (ntok-- > 0) {
-                void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
-                                              MSG_LEN_LARGE);
-                if (buffer == NULL) {
-                        CERROR("gm_init failed: %d\n", rc);
-                        return (-ENOMEM);
-                }
-                CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
-                       "pri %d\n ", kgmnal_data.kgm_port, buffer,
-                       MSG_LEN_LARGE, MSG_SIZE_LARGE, GM_LOW_PRIORITY);
-
-                gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
-                                          MSG_SIZE_LARGE, GM_LOW_PRIORITY);
-        }
-
-        ntok = gm_num_receive_tokens(kgmnal_data.kgm_port)/2;
-        CDEBUG(D_NET, "gmnal_init: creating %d small %d byte recv buffers\n",
-               ntok, MSG_LEN_SMALL);
-        while (ntok-- > 0) {
-                void * buffer = gm_dma_malloc(kgmnal_data.kgm_port,
-                                              MSG_LEN_SMALL);
-                if (buffer == NULL) {
-                        CERROR("gm_init failed: %d\n", rc);
-                        return (-ENOMEM);
-                }
-                CDEBUG(D_NET, " add buffer: port %p buf %p len %d size %d "
-                       "pri %d\n ", kgmnal_data.kgm_port, buffer,
-                       MSG_LEN_SMALL, MSG_SIZE_SMALL, GM_LOW_PRIORITY);
-
-                gm_provide_receive_buffer(kgmnal_data.kgm_port, buffer,
-                                          MSG_SIZE_SMALL, GM_LOW_PRIORITY);
-
-        }
-        sizemask = (1 << MSG_SIZE_LARGE) | (1 << MSG_SIZE_SMALL);
-        CDEBUG(D_NET, "gm_set_acceptable_sizes port %p pri %d mask 0x%x\n",
-                        kgmnal_data.kgm_port, GM_LOW_PRIORITY, sizemask);
-        gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_LOW_PRIORITY,
-                                sizemask);
-        gm_set_acceptable_sizes(kgmnal_data.kgm_port, GM_HIGH_PRIORITY, 0);
-
-        /* Initialize Network Interface */
-        rc = PtlNIInit(kgmnal_init, 32, 4, 0, &kgmnal_ni);
-        if (rc) {
-                CERROR("PtlNIInit failed %d\n", rc);
-                return (-ENOMEM);
-        }
-
-        /* Start receiver thread */
-        kernel_thread(kgmnal_recv_thread, &kgmnal_data, 0);
-
-        PORTAL_SYMBOL_REGISTER(kgmnal_ni);
-
-        kgmnal_data.kgm_init = 1;
-
-        return 0;
-}
-
-MODULE_AUTHOR("Robert Read <rread@datarithm.net>");
-MODULE_DESCRIPTION("Kernel Myrinet GM NAL v0.1");
-MODULE_LICENSE("GPL");
-
-module_init (kgmnal_initialize);
-module_exit (kgmnal_finalize);
-
-EXPORT_SYMBOL (kgmnal_ni);
diff --git a/lustre/portals/knals/gmnal/gmnal.h b/lustre/portals/knals/gmnal/gmnal.h
index 47e8c3c36f115326e1f6f2c90f293e82a6bebeac..53757ab48de082fe5cb4d58adefec5bf30d14e14 100644
--- a/lustre/portals/knals/gmnal/gmnal.h
+++ b/lustre/portals/knals/gmnal/gmnal.h
@@ -1,101 +1,483 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#ifndef _GMNAL_H
-#define _GMNAL_H
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/locks.h>
-#include <linux/unistd.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/stat.h>
-#include <linux/list.h>
-#include <asm/uaccess.h>
-#include <asm/segment.h>
+
+
+/*
+ *	Portals GM kernel NAL header file
+ *	This file makes all declaration and prototypes 
+ *	for the API side and CB side of the NAL
+ */
+#ifndef __INCLUDE_GMNAL_H__
+#define __INCLUDE_GMNAL_H__
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#include "linux/config.h"
+#include "linux/module.h"
+#include "linux/tty.h"
+#include "linux/kernel.h"
+#include "linux/mm.h"
+#include "linux/string.h"
+#include "linux/stat.h"
+#include "linux/errno.h"
+#include "linux/locks.h"
+#include "linux/unistd.h"
+#include "linux/init.h"
+#include "linux/sem.h"
+#include "linux/vmalloc.h"
 
 #define DEBUG_SUBSYSTEM S_GMNAL
 
-#include <linux/kp30.h>
-#include <portals/p30.h>
-#include <portals/lib-p30.h>
+#include "portals/nal.h"
+#include "portals/api.h"
+#include "portals/errno.h"
+#include "linux/kp30.h"
+#include "portals/p30.h"
+
+#include "portals/lib-nal.h"
+#include "portals/lib-p30.h"
+
+#define GM_STRONG_TYPES 1
+#include "gm.h"
+#include "gm_internal.h"
+
+
+
+/*
+ *	Defines for the API NAL
+ */
+
+/*
+ *	Small message size is configurable
+ *	insmod can set small_msg_size
+ *	which is used to populate nal_data.small_msg_size
+ */
+#define GMNAL_SMALL_MESSAGE		1078
+#define GMNAL_LARGE_MESSAGE_INIT	1079
+#define GMNAL_LARGE_MESSAGE_ACK	1080
+#define GMNAL_LARGE_MESSAGE_FINI	1081
+
+extern  int gmnal_small_msg_size;
+extern  int num_rx_threads;
+extern  int num_stxds;
+#define GMNAL_SMALL_MSG_SIZE(a)		a->small_msg_size
+#define GMNAL_IS_SMALL_MESSAGE(n,a,b,c)	gmnal_is_small_msg(n, a, b, c)
+#define GMNAL_MAGIC				0x1234abcd
+
+
+/*
+ *	Small Transmit Descriptor
+ *	A structre to keep track of a small transmit operation
+ *	This structure has a one-to-one relationship with a small
+ *	transmit buffer (both create by gmnal_stxd_alloc). 
+ *	There are two free list of stxd. One for use by clients of the NAL
+ *	and the other by the NAL rxthreads when doing sends. 
+ *	This helps prevent deadlock caused by stxd starvation.
+ */
+typedef struct _gmnal_stxd_t {
+	void 			*buffer;
+	int			buffer_size;
+	gm_size_t		gm_size;
+	int			msg_size;
+	int			gm_target_node;
+	int			gm_priority;
+	int			type;
+	struct _gmnal_data_t 	*nal_data;
+	lib_msg_t		*cookie;
+	int			niov;
+	struct iovec		iov[PTL_MD_MAX_IOV];
+	struct _gmnal_stxd_t	*next;
+        int                     rxt; 
+        int                     kniov;
+        struct iovec            *iovec_dup;
+} gmnal_stxd_t;
+
+/*
+ *	keeps a transmit token for large transmit (gm_get)
+ *	and a pointer to rxd that is used as context for large receive
+ */
+typedef struct _gmnal_ltxd_t {
+	struct _gmnal_ltxd_t	*next;
+	struct	_gmnal_srxd_t  *srxd;
+} gmnal_ltxd_t;
+
+
+/*
+ *	as for gmnal_stxd_t 
+ *	a hash table in nal_data find srxds from
+ *	the rx buffer address. hash table populated at init time
+ */
+typedef struct _gmnal_srxd_t {
+	void 			*buffer;
+	int			size;
+	gm_size_t		gmsize;
+	unsigned int		gm_source_node;
+	gmnal_stxd_t		*source_stxd;
+	int			type;
+	int			nsiov;
+	int			nriov;
+	struct iovec 		*riov;
+	int			ncallbacks;
+	spinlock_t		callback_lock;
+	int			callback_status;
+	lib_msg_t		*cookie;
+	struct _gmnal_srxd_t	*next;
+	struct _gmnal_data_t	*nal_data;
+} gmnal_srxd_t;
+
+/*
+ *	Header which lmgnal puts at the start of each message
+ */
+typedef struct	_gmnal_msghdr {
+	int		magic;
+	int 		type;
+	unsigned int	sender_node_id;
+	gmnal_stxd_t	*stxd;
+	int		niov;
+	} gmnal_msghdr_t;
+#define GMNAL_MSGHDR_SIZE	sizeof(gmnal_msghdr_t)
+
+/*
+ *	the caretaker thread (ct_thread) gets receive events
+ *	(and other events) from the myrinet device via the GM2 API.
+ *	caretaker thread populates one work entry for each receive event,
+ *	puts it on a Q in nal_data and wakes a receive thread to  
+ *	process the receive.  
+ *	Processing a portals receive can involve a transmit operation. 
+ *	Because of this the caretaker thread cannot process receives 
+ *	as it may get deadlocked when supply of transmit descriptors 
+ *	is exhausted (as caretaker thread is responsible for replacing 
+ *	transmit descriptors on the free list)
+ */
+typedef struct _gmnal_rxtwe {
+	void			*buffer;
+	unsigned		snode;
+	unsigned		sport;
+	unsigned		type;
+	unsigned		length;
+	struct _gmnal_rxtwe	*next;
+} gmnal_rxtwe_t;
+
+/*
+ *	1 receive thread started on each CPU
+ */
+#define NRXTHREADS 10 /* max number of receiver threads */
+
+typedef struct _gmnal_data_t {
+	int		refcnt;
+	spinlock_t	cb_lock;
+	spinlock_t 	stxd_lock;
+	struct semaphore stxd_token;
+	gmnal_stxd_t	*stxd;
+	spinlock_t 	rxt_stxd_lock;
+	struct semaphore rxt_stxd_token;
+	gmnal_stxd_t	*rxt_stxd;
+	spinlock_t 	ltxd_lock;
+	struct semaphore ltxd_token;
+	gmnal_ltxd_t	*ltxd;
+	spinlock_t 	srxd_lock;
+	struct semaphore srxd_token;
+	gmnal_srxd_t	*srxd;
+	struct gm_hash	*srxd_hash;
+	nal_t		*nal;	
+	nal_cb_t	*nal_cb;
+	struct gm_port	*gm_port;
+	unsigned int	gm_local_nid;
+	unsigned int	gm_global_nid;
+	spinlock_t 	gm_lock;
+	long		rxthread_pid[NRXTHREADS];
+	int		rxthread_stop_flag;
+	spinlock_t	rxthread_flag_lock;
+	long		rxthread_flag;
+	long		ctthread_pid;
+	int		ctthread_flag;
+	gm_alarm_t	ctthread_alarm;
+	int		small_msg_size;
+	int		small_msg_gmsize;
+	gmnal_rxtwe_t	*rxtwe_head;
+	gmnal_rxtwe_t	*rxtwe_tail;
+	spinlock_t	rxtwe_lock;
+	struct	semaphore rxtwe_wait;
+} gmnal_data_t;
+
+/*
+ *	Flags to start/stop and check status of threads
+ *	each rxthread sets 1 bit (any bit) of the flag on startup
+ *	and clears 1 bit when exiting
+ */
+#define GMNAL_THREAD_RESET	0
+#define GMNAL_THREAD_STOP	666
+#define GMNAL_CTTHREAD_STARTED	333
+#define GMNAL_RXTHREADS_STARTED ( (1<<num_rx_threads)-1)
+
+
+extern gmnal_data_t	*global_nal_data;
+
+/*
+ *	The gm_port to use for gmnal
+ */
+#define GMNAL_GM_PORT	4
+
+/*
+ * for ioctl get pid
+ */
+#define GMNAL_IOC_GET_GNID 1	
+
+/*
+ *	Return codes
+ */
+#define GMNAL_STATUS_OK	0
+#define GMNAL_STATUS_FAIL	1
+#define GMNAL_STATUS_NOMEM	2
+
+
+/*
+ *	FUNCTION PROTOTYPES
+ */
+
+/*
+ *	Locking macros
+ */
+
+/*
+ *	For the Small tx and rx descriptor lists
+ */
+#define GMNAL_TXD_LOCK_INIT(a)		spin_lock_init(&a->stxd_lock);
+#define GMNAL_TXD_LOCK(a)		spin_lock(&a->stxd_lock);
+#define GMNAL_TXD_UNLOCK(a)		spin_unlock(&a->stxd_lock);
+#define GMNAL_TXD_TOKEN_INIT(a, n)	sema_init(&a->stxd_token, n);
+#define GMNAL_TXD_GETTOKEN(a)		down(&a->stxd_token);
+#define GMNAL_TXD_TRYGETTOKEN(a)	down_trylock(&a->stxd_token)
+#define GMNAL_TXD_RETURNTOKEN(a)	up(&a->stxd_token);
+
+#define GMNAL_RXT_TXD_LOCK_INIT(a)	spin_lock_init(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_LOCK(a)		spin_lock(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_UNLOCK(a)	        spin_unlock(&a->rxt_stxd_lock);
+#define GMNAL_RXT_TXD_TOKEN_INIT(a, n)	sema_init(&a->rxt_stxd_token, n);
+#define GMNAL_RXT_TXD_GETTOKEN(a)	down(&a->rxt_stxd_token);
+#define GMNAL_RXT_TXD_TRYGETTOKEN(a)	down_trylock(&a->rxt_stxd_token)
+#define GMNAL_RXT_TXD_RETURNTOKEN(a)	up(&a->rxt_stxd_token);
+
+#define GMNAL_LTXD_LOCK_INIT(a)		spin_lock_init(&a->ltxd_lock);
+#define GMNAL_LTXD_LOCK(a)		spin_lock(&a->ltxd_lock);
+#define GMNAL_LTXD_UNLOCK(a)		spin_unlock(&a->ltxd_lock);
+#define GMNAL_LTXD_TOKEN_INIT(a, n)	sema_init(&a->ltxd_token, n);
+#define GMNAL_LTXD_GETTOKEN(a)		down(&a->ltxd_token);
+#define GMNAL_LTXD_TRYGETTOKEN(a)	down_trylock(&a->ltxd_token)
+#define GMNAL_LTXD_RETURNTOKEN(a)	up(&a->ltxd_token);
+
+#define GMNAL_RXD_LOCK_INIT(a)		spin_lock_init(&a->srxd_lock);
+#define GMNAL_RXD_LOCK(a)		spin_lock(&a->srxd_lock);
+#define GMNAL_RXD_UNLOCK(a)		spin_unlock(&a->srxd_lock);
+#define GMNAL_RXD_TOKEN_INIT(a, n)	sema_init(&a->srxd_token, n);
+#define GMNAL_RXD_GETTOKEN(a)		down(&a->srxd_token);
+#define GMNAL_RXD_TRYGETTOKEN(a)	down_trylock(&a->srxd_token)
+#define GMNAL_RXD_RETURNTOKEN(a)	up(&a->srxd_token);
+
+#define GMNAL_GM_LOCK_INIT(a)		spin_lock_init(&a->gm_lock);
+#define GMNAL_GM_LOCK(a)		spin_lock(&a->gm_lock);
+#define GMNAL_GM_UNLOCK(a)		spin_unlock(&a->gm_lock);
+#define GMNAL_CB_LOCK_INIT(a)		spin_lock_init(&a->cb_lock);
+
+
+/*
+ *	Memory Allocator
+ */
+
+/*
+ *	API NAL
+ */
+int gmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
+
+int gmnal_api_shutdown(nal_t *, int);
 
-#include <gm.h>
+int gmnal_api_validate(nal_t *, void *, size_t);
+
+void gmnal_api_yield(nal_t *);
+
+void gmnal_api_lock(nal_t *, unsigned long *);
+
+void gmnal_api_unlock(nal_t *, unsigned long *);
+
+
+#define GMNAL_INIT_NAL(a)	do { 	\
+				a->forward = gmnal_api_forward; \
+				a->shutdown = gmnal_api_shutdown; \
+				a->validate = NULL; \
+				a->yield = gmnal_api_yield; \
+				a->lock = gmnal_api_lock; \
+				a->unlock = gmnal_api_unlock; \
+				a->timeout = NULL; \
+				a->refct = 1; \
+				a->nal_data = NULL; \
+				} while (0)
 
 
 /*
- *  Myrinet GM NAL
+ *	CB NAL
  */
-#define NPAGES_LARGE            16
-#define NPAGES_SMALL            1
-#define MSG_LEN_LARGE            NPAGES_LARGE*PAGE_SIZE
-#define MSG_LEN_SMALL            NPAGES_SMALL*PAGE_SIZE
-#define MSG_SIZE_LARGE           (gm_min_size_for_length(MSG_LEN_LARGE))
-#define MSG_SIZE_SMALL           (gm_min_size_for_length(MSG_LEN_SMALL))
 
-#define TXMSGS                  64 /* Number of Transmit Messages */
-#define ENVELOPES               8  /* Number of outstanding receive msgs */
+int gmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
+	int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
+
+int gmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
+	int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
+
+int gmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
+	unsigned int, struct iovec *, size_t, size_t);
+
+int gmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
+	unsigned int, ptl_kiov_t *, size_t, size_t);
+
+int gmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
+
+int gmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
+
+int gmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
+
+void *gmnal_cb_malloc(nal_cb_t *, size_t);
+
+void gmnal_cb_free(nal_cb_t *, void *, size_t);
+
+void gmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
+
+int  gmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
 
-#define KGM_PORT_NUM 3
-#define KGM_HOSTNAME "kgmnal"
+void gmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
 
+void gmnal_cb_cli(nal_cb_t *, unsigned long *);
 
-typedef struct {
-        char *krx_buffer;
-        unsigned long   krx_len;
-        unsigned int   krx_size;
-        unsigned int   krx_priority;
-        struct list_head krx_item;
-}  kgmnal_rx_t;
+void gmnal_cb_sti(nal_cb_t *, unsigned long *);
 
+int gmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
+
+nal_t *gmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
+
+void  gmnal_fini(void);
+
+
+
+#define GMNAL_INIT_NAL_CB(a)	do {	\
+				a->cb_send = gmnal_cb_send; \
+				a->cb_send_pages = gmnal_cb_send_pages; \
+				a->cb_recv = gmnal_cb_recv; \
+				a->cb_recv_pages = gmnal_cb_recv_pages; \
+				a->cb_read = gmnal_cb_read; \
+				a->cb_write = gmnal_cb_write; \
+				a->cb_callback = gmnal_cb_callback; \
+				a->cb_malloc = gmnal_cb_malloc; \
+				a->cb_free = gmnal_cb_free; \
+				a->cb_map = NULL; \
+				a->cb_unmap = NULL; \
+				a->cb_printf = gmnal_cb_printf; \
+				a->cb_cli = gmnal_cb_cli; \
+				a->cb_sti = gmnal_cb_sti; \
+				a->cb_dist = gmnal_cb_dist; \
+				a->nal_data = NULL; \
+				} while (0)
+
+
+/*
+ *	Small and Large Transmit and Receive Descriptor Functions
+ */
+int  		gmnal_alloc_txd(gmnal_data_t *);
+void 		gmnal_free_txd(gmnal_data_t *);
+gmnal_stxd_t* 	gmnal_get_stxd(gmnal_data_t *, int);
+void 		gmnal_return_stxd(gmnal_data_t *, gmnal_stxd_t *);
+gmnal_ltxd_t* 	gmnal_get_ltxd(gmnal_data_t *);
+void 		gmnal_return_ltxd(gmnal_data_t *, gmnal_ltxd_t *);
+
+int  		gmnal_alloc_srxd(gmnal_data_t *);
+void 		gmnal_free_srxd(gmnal_data_t *);
+gmnal_srxd_t* 	gmnal_get_srxd(gmnal_data_t *, int);
+void 		gmnal_return_srxd(gmnal_data_t *, gmnal_srxd_t *);
+
+/*
+ *	general utility functions
+ */
+gmnal_srxd_t	*gmnal_rxbuffer_to_srxd(gmnal_data_t *, void*);
+void		gmnal_stop_rxthread(gmnal_data_t *);
+void		gmnal_stop_ctthread(gmnal_data_t *);
+void		gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
+void		gmnal_drop_sends_callback(gm_port_t *, void *, gm_status_t);
+char		*gmnal_gm_error(gm_status_t);
+char		*gmnal_rxevent(gm_recv_event_t*);
+int		gmnal_is_small_msg(gmnal_data_t*, int, struct iovec*, int);
+void 		gmnal_yield(int);
+int		gmnal_start_kernel_threads(gmnal_data_t *);
+
+
+/*
+ *	Communication functions
+ */
+
+/*
+ *	Receive threads
+ */
+int 		gmnal_ct_thread(void *); /* caretaker thread */
+int 		gmnal_rx_thread(void *); /* receive thread */
+int 		gmnal_pre_receive(gmnal_data_t*, gmnal_rxtwe_t*, int);
+int		gmnal_rx_bad(gmnal_data_t *, gmnal_rxtwe_t *, gmnal_srxd_t*);
+int		gmnal_rx_requeue_buffer(gmnal_data_t *, gmnal_srxd_t *);
+int		gmnal_add_rxtwe(gmnal_data_t *, gm_recv_t *);
+gmnal_rxtwe_t * gmnal_get_rxtwe(gmnal_data_t *);
+void		gmnal_remove_rxtwe(gmnal_data_t *);
+
+
+/*
+ *	Small messages
+ */
+int 		gmnal_small_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
+			        struct iovec *, size_t, size_t);
+int 		gmnal_small_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
+				int, ptl_nid_t, ptl_pid_t, 
+				unsigned int, struct iovec*, int);
+void 		gmnal_small_tx_callback(gm_port_t *, void *, gm_status_t);
+
+
+
+/*
+ *	Large messages
+ */
+int 		gmnal_large_rx(nal_cb_t *, void *, lib_msg_t *, unsigned int, 
+				struct iovec *, size_t, size_t);
 
-typedef struct {
-        nal_cb_t  *ktx_nal;
-        void      *ktx_private;
-        lib_msg_t *ktx_cookie;
-        char      *ktx_buffer;
-        size_t     ktx_len;
-        unsigned long ktx_size;
-        int        ktx_ndx;
-        unsigned int ktx_priority;
-        unsigned int ktx_tgt_node;
-        unsigned int ktx_tgt_port_id;
-}  kgmnal_tx_t;
+int 		gmnal_large_tx(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, 
+				int, ptl_nid_t, ptl_pid_t, unsigned int, 
+				struct iovec*, int);
 
+void 		gmnal_large_tx_callback(gm_port_t *, void *, gm_status_t);
 
-typedef struct {
-        char              kgm_init;
-        char              kgm_shuttingdown;
-        struct gm_port   *kgm_port;
-        struct list_head  kgm_list;
-        ptl_nid_t         kgm_nid;
-        nal_cb_t         *kgm_cb;
-        struct kgm_trans *kgm_trans;
-        struct tq_struct  kgm_ready_tq;
-        spinlock_t        kgm_dispatch_lock;
-        spinlock_t        kgm_update_lock;
-        spinlock_t        kgm_send_lock;
-}  kgmnal_data_t;
+int 		gmnal_remote_get(gmnal_srxd_t *, int, struct iovec*, int, 
+				  struct iovec*);
 
-int kgm_init(kgmnal_data_t *kgm_data);
-int kgmnal_recv_thread(void *);
-int gm_return_mynid(void);
-void kgmnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
+void		gmnal_remote_get_callback(gm_port_t *, void *, gm_status_t);
 
-extern kgmnal_data_t      kgmnal_data;
-extern nal_t              kgmnal_api;
-extern nal_cb_t           kgmnal_lib;
+int 		gmnal_copyiov(int, gmnal_srxd_t *, int, struct iovec*, int, 
+			       struct iovec*);
 
-#endif  /* _GMNAL_H */
+void 		gmnal_large_tx_ack(gmnal_data_t *, gmnal_srxd_t *);
+void 		gmnal_large_tx_ack_callback(gm_port_t *, void *, gm_status_t);
+void 		gmnal_large_tx_ack_received(gmnal_data_t *, gmnal_srxd_t *);
 
+#endif /*__INCLUDE_GMNAL_H__*/
diff --git a/lustre/portals/knals/gmnal/gmnal_api.c b/lustre/portals/knals/gmnal/gmnal_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..1cb13178794e6100209ba42cc26e9f9cab406918
--- /dev/null
+++ b/lustre/portals/knals/gmnal/gmnal_api.c
@@ -0,0 +1,465 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *	Implements the API NAL functions
+ */
+
+#include "gmnal.h"
+
+gmnal_data_t	*global_nal_data = NULL;
+/*
+ *	gmnal_api_forward
+ *	This function takes a pack block of arguments from the NAL API
+ *	module and passes them to the NAL CB module. The CB module unpacks
+ *	the args and calls the appropriate function indicated by index.
+ *	Typically this function is used to pass args between kernel and use
+ *	space.
+ *	As lgmanl exists entirely in kernel, just pass the arg block directly 
+ *	to the NAL CB, buy passing the args to lib_dispatch
+ *	Arguments are
+ *	nal_t	nal 	Our nal
+ *	int	index	the api function that initiated this call 
+ *	void 	*args	packed block of function args
+ *	size_t	arg_len	length of args block
+ *	void 	*ret	A return value for the API NAL
+ *	size_t	ret_len	Size of the return value
+ *	
+ */
+
+int
+gmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
+		void *ret, size_t ret_len)
+{
+
+	nal_cb_t	*nal_cb = NULL;
+	gmnal_data_t	*nal_data = NULL;
+
+
+
+
+
+	if (!nal || !args || (index < 0) || (arg_len < 0)) {
+			CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
+		return (PTL_FAIL);
+	}
+
+	if (ret && (ret_len <= 0)) {
+		CDEBUG(D_ERROR, "Bad args to gmnal_api_forward\n");
+		return (PTL_FAIL);
+	}
+
+
+	if (!nal->nal_data) {
+		CDEBUG(D_ERROR, "bad nal, no nal data\n");	
+		return (PTL_FAIL);
+	}
+	
+	nal_data = nal->nal_data;
+	CDEBUG(D_INFO, "nal_data is [%p]\n", nal_data);	
+
+	if (!nal_data->nal_cb) {
+		CDEBUG(D_ERROR, "bad nal_data, no nal_cb\n");	
+		return (PTL_FAIL);
+	}
+	
+	nal_cb = nal_data->nal_cb;
+	CDEBUG(D_INFO, "nal_cb is [%p]\n", nal_cb);	
+	
+	CDEBUG(D_PORTALS, "gmnal_api_forward calling lib_dispatch\n");
+	lib_dispatch(nal_cb, NULL, index, args, ret);
+	CDEBUG(D_PORTALS, "gmnal_api_forward returns from lib_dispatch\n");
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	gmnal_api_shutdown
+ *	Close down this interface and free any resources associated with it
+ *	nal_t	nal	our nal to shutdown
+ */
+int
+gmnal_api_shutdown(nal_t *nal, int interface)
+{
+
+	gmnal_data_t	*nal_data = nal->nal_data;
+
+	CDEBUG(D_TRACE, "gmnal_api_shutdown: nal_data [%p]\n", nal_data);
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	gmnal_api_validate
+ *	validate a user address for use in communications
+ *	There's nothing to be done here
+ */
+int
+gmnal_api_validate(nal_t *nal, void *base, size_t extent)
+{
+
+	return(PTL_OK);
+}
+
+
+
+/*
+ *	gmnal_api_yield
+ *	Give up the processor
+ */
+void
+gmnal_api_yield(nal_t *nal)
+{
+	CDEBUG(D_TRACE, "gmnal_api_yield : nal [%p]\n", nal);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule();
+
+	return;
+}
+
+
+
+/*
+ *	gmnal_api_lock
+ *	Take a threadsafe lock
+ */
+void
+gmnal_api_lock(nal_t *nal, unsigned long *flags)
+{
+
+	gmnal_data_t	*nal_data;
+	nal_cb_t	*nal_cb;
+
+	nal_data = nal->nal_data;
+	nal_cb = nal_data->nal_cb;
+
+	nal_cb->cb_cli(nal_cb, flags);
+
+	return;
+}
+
+/*
+ *	gmnal_api_unlock
+ *	Release a threadsafe lock
+ */
+void
+gmnal_api_unlock(nal_t *nal, unsigned long *flags)
+{
+	gmnal_data_t	*nal_data;
+	nal_cb_t	*nal_cb;
+
+	nal_data = nal->nal_data;
+	nal_cb = nal_data->nal_cb;
+
+	nal_cb->cb_sti(nal_cb, flags);
+
+	return;
+}
+
+
+nal_t *
+gmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, 
+	    ptl_pid_t rpid)
+{
+
+	nal_t		*nal = NULL;
+	nal_cb_t	*nal_cb = NULL;
+	gmnal_data_t	*nal_data = NULL;
+	gmnal_srxd_t	*srxd = NULL;
+	gm_status_t	gm_status;
+	unsigned int	local_nid = 0, global_nid = 0;
+	ptl_nid_t	portals_nid;
+	ptl_pid_t	portals_pid = 0;
+
+
+	CDEBUG(D_TRACE, "gmnal_init : interface [%d], ptl_size [%d], 
+	       ac_size[%d]\n", interface, ptl_size, ac_size);
+
+
+	PORTAL_ALLOC(nal_data, sizeof(gmnal_data_t));
+	if (!nal_data) {
+		CDEBUG(D_ERROR, "can't get memory\n");
+		return(NULL);
+	}	
+	memset(nal_data, 0, sizeof(gmnal_data_t));
+	/*
+ 	 *	set the small message buffer size 
+	 */
+	nal_data->refcnt = 1;
+
+	CDEBUG(D_INFO, "Allocd and reset nal_data[%p]\n", nal_data);
+	CDEBUG(D_INFO, "small_msg_size is [%d]\n", nal_data->small_msg_size);
+
+	PORTAL_ALLOC(nal, sizeof(nal_t));
+	if (!nal) {
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
+		return(NULL);
+	}
+	memset(nal, 0, sizeof(nal_t));
+	CDEBUG(D_INFO, "Allocd and reset nal[%p]\n", nal);
+
+	PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
+	if (!nal_cb) {
+		PORTAL_FREE(nal, sizeof(nal_t));
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));
+		return(NULL);
+	}
+	memset(nal_cb, 0, sizeof(nal_cb_t));
+	CDEBUG(D_INFO, "Allocd and reset nal_cb[%p]\n", nal_cb);
+
+	GMNAL_INIT_NAL(nal);
+	GMNAL_INIT_NAL_CB(nal_cb);
+	/*
+	 *	String them all together
+	 */
+	nal->nal_data = (void*)nal_data;
+	nal_cb->nal_data = (void*)nal_data;
+	nal_data->nal = nal;
+	nal_data->nal_cb = nal_cb;
+
+	GMNAL_CB_LOCK_INIT(nal_data);
+	GMNAL_GM_LOCK_INIT(nal_data);
+
+
+	/*
+ 	 *	initialise the interface, 
+	 */
+	CDEBUG(D_INFO, "Calling gm_init\n");
+	if (gm_init() != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "call to gm_init failed\n");
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+
+	CDEBUG(D_NET, "Calling gm_open with interface [%d], port [%d], 
+       	       name [%s], version [%d]\n", interface, GMNAL_GM_PORT, 
+	       "gmnal", GM_API_VERSION);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_open(&nal_data->gm_port, 0, GMNAL_GM_PORT, "gmnal", 
+			    GM_API_VERSION);
+	GMNAL_GM_UNLOCK(nal_data);
+
+	CDEBUG(D_INFO, "gm_open returned [%d]\n", gm_status);
+	if (gm_status == GM_SUCCESS) {
+		CDEBUG(D_INFO, "gm_open succeeded port[%p]\n", 
+		       nal_data->gm_port);
+	} else {
+		switch(gm_status) {
+		case(GM_INVALID_PARAMETER):
+			CDEBUG(D_ERROR, "gm_open Failure. Invalid Parameter\n");
+			break;
+		case(GM_BUSY):
+			CDEBUG(D_ERROR, "gm_open Failure. GM Busy\n");
+			break;
+		case(GM_NO_SUCH_DEVICE):
+			CDEBUG(D_ERROR, "gm_open Failure. No such device\n");
+			break;
+		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+			CDEBUG(D_ERROR, "gm_open Failure. Incompatile lib 
+			       and driver\n");
+			break;
+		case(GM_OUT_OF_MEMORY):
+			CDEBUG(D_ERROR, "gm_open Failure. Out of Memory\n");
+			break;
+		default:
+			CDEBUG(D_ERROR, "gm_open Failure. Unknow error 
+			       code [%d]\n", gm_status);
+			break;
+		}	
+		GMNAL_GM_LOCK(nal_data);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+	
+	nal_data->small_msg_size = gmnal_small_msg_size;
+	nal_data->small_msg_gmsize = 
+			gm_min_size_for_length(gmnal_small_msg_size);
+
+	if (gmnal_alloc_srxd(nal_data) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "Failed to allocate small rx descriptors\n");
+		gmnal_free_txd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+
+	/*
+ 	 *	Hang out a bunch of small receive buffers
+	 *	In fact hang them all out
+	 */
+	while((srxd = gmnal_get_srxd(nal_data, 0))) {
+		CDEBUG(D_NET, "giving [%p] to gm_provide_recvive_buffer\n", 
+		       srxd->buffer);
+		GMNAL_GM_LOCK(nal_data);
+		gm_provide_receive_buffer_with_tag(nal_data->gm_port, 
+						   srxd->buffer, srxd->gmsize, 
+						   GM_LOW_PRIORITY, 0);
+		GMNAL_GM_UNLOCK(nal_data);
+	}
+	
+	/*
+	 *	Allocate pools of small tx buffers and descriptors
+	 */
+	if (gmnal_alloc_txd(nal_data) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "Failed to allocate small tx descriptors\n");
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+
+	gmnal_start_kernel_threads(nal_data);
+
+	while (nal_data->rxthread_flag != GMNAL_RXTHREADS_STARTED) {
+		gmnal_yield(1);
+		CDEBUG(D_INFO, "Waiting for receive thread signs of life\n");
+	}
+
+	CDEBUG(D_INFO, "receive thread seems to have started\n");
+
+
+	/*
+	 *	Initialise the portals library
+	 */
+	CDEBUG(D_NET, "Getting node id\n");
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		CDEBUG(D_ERROR, "can't determine node id\n");
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+	nal_data->gm_local_nid = local_nid;
+	CDEBUG(D_INFO, "Local node id is [%u]\n", local_nid);
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, 
+					    &global_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "failed to obtain global id\n");
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+	}
+	CDEBUG(D_INFO, "Global node id is [%u]\n", global_nid);
+	nal_data->gm_global_nid = global_nid;
+
+/*
+	pid = gm_getpid();
+*/
+	CDEBUG(D_INFO, "portals_pid is [%u]\n", portals_pid);
+	portals_nid = (unsigned long)global_nid;
+	CDEBUG(D_INFO, "portals_nid is ["LPU64"]\n", portals_nid);
+	
+	CDEBUG(D_PORTALS, "calling lib_init\n");
+	if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, 
+		     ac_size) != PTL_OK) {
+		CDEBUG(D_ERROR, "lib_init failed\n");
+		gmnal_stop_rxthread(nal_data);
+		gmnal_stop_ctthread(nal_data);
+		gmnal_free_txd(nal_data);
+		gmnal_free_srxd(nal_data);
+		GMNAL_GM_LOCK(nal_data);
+		gm_close(nal_data->gm_port);
+		gm_finalize();
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(nal, sizeof(nal_t));	
+		PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+		return(NULL);
+		
+	}
+	
+	CDEBUG(D_INFO, "gmnal_init finished\n");
+	global_nal_data = nal->nal_data;
+	return(nal);
+}
+
+
+
+/*
+ *	Called when module removed
+ */
+void gmnal_fini()
+{
+	gmnal_data_t	*nal_data = global_nal_data;
+	nal_t		*nal = nal_data->nal;
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+
+	CDEBUG(D_TRACE, "gmnal_fini\n");
+
+	PtlNIFini(kgmnal_ni);
+	lib_fini(nal_cb);
+
+	gmnal_stop_rxthread(nal_data);
+	gmnal_stop_ctthread(nal_data);
+	gmnal_free_txd(nal_data);
+	gmnal_free_srxd(nal_data);
+	GMNAL_GM_LOCK(nal_data);
+	gm_close(nal_data->gm_port);
+	gm_finalize();
+	GMNAL_GM_UNLOCK(nal_data);
+	PORTAL_FREE(nal, sizeof(nal_t));	
+	PORTAL_FREE(nal_data, sizeof(gmnal_data_t));	
+	PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
+}
diff --git a/lustre/portals/knals/gmnal/gmnal_cb.c b/lustre/portals/knals/gmnal/gmnal_cb.c
index 3d4c86dac71a98bdd04f38c719b70d4895ea73d3..6ae91dbb44b158707adb0bb0916b9fa9fd669943 100644
--- a/lustre/portals/knals/gmnal/gmnal_cb.c
+++ b/lustre/portals/knals/gmnal/gmnal_cb.c
@@ -1,517 +1,271 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Based on ksocknal and qswnal
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
  *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *  Author: Robert Read  <rread@datarithm.net>
+ *   This file is part of Lustre, http://www.lustre.org/
  *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- *
- *   Portals is free software; you can redistribute it and/or
+ *   Lustre is free software; you can redistribute it and/or
  *   modify it under the terms of version 2 of the GNU General Public
  *   License as published by the Free Software Foundation.
  *
- *   Portals is distributed in the hope that it will be useful,
+ *   Lustre 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 Portals; if not, write to the Free Software
+ *   along with Lustre; if not, write to the Free Software
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* TODO
- * preallocate send buffers, store on list
- * put receive buffers on queue, handle with receive threads
- * use routing
- */
-
-#include "gmnal.h"
-
-extern kgmnal_rx_t *kgm_add_recv(kgmnal_data_t *,int);
-
-static kgmnal_tx_t *
-get_trans(void)
-{
-        kgmnal_tx_t *t;
-        PORTAL_ALLOC(t, (sizeof(kgmnal_tx_t)));
-        return t;
-}
-
-static void
-put_trans(kgmnal_tx_t *t)
-{
-        PORTAL_FREE(t, sizeof(kgmnal_tx_t));
-}
-
-int
-kgmnal_ispeer (ptl_nid_t nid)
-{
-   unsigned int gmnid = (unsigned int)nid;
-   unsigned int nnids;
-
-   gm_max_node_id_in_use(kgmnal_data.kgm_port, &nnids);
-
-   return ((ptl_nid_t)gmnid == nid &&/* didn't lose high bits on conversion ? */
-           gmnid < nnids); /* it's in this machine */
-}
 
 /*
- *  LIB functions follow
- *
+ *	This file implements the nal cb functions
  */
-static int
-kgmnal_read (nal_cb_t *nal, void *private, void *dst_addr, user_ptr src_addr,
-             size_t len)
-{
-        CDEBUG(D_NET, "0x%Lx: reading %ld bytes from %p -> %p\n",
-               nal->ni.nid, (long)len, src_addr, dst_addr );
-        memcpy( dst_addr, src_addr, len );
-        return 0;
-}
-
-static int
-kgmnal_write(nal_cb_t *nal, void *private, user_ptr dst_addr, void *src_addr,
-             size_t len)
-{
-        CDEBUG(D_NET, "0x%Lx: writing %ld bytes from %p -> %p\n",
-               nal->ni.nid, (long)len, src_addr, dst_addr );
-        memcpy( dst_addr, src_addr, len );
-        return 0;
-}
 
-static void *
-kgmnal_malloc(nal_cb_t *nal, size_t len)
-{
-        void *buf;
 
-        PORTAL_ALLOC(buf, len);
-        return buf;
-}
+#include "gmnal.h"
 
-static void
-kgmnal_free(nal_cb_t *nal, void *buf, size_t len)
+int gmnal_cb_recv(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		   unsigned int niov, struct iovec *iov, size_t mlen, 
+		   size_t rlen)
 {
-        PORTAL_FREE(buf, len);
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	int		status = PTL_OK;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_recv nal_cb [%p], private[%p], cookie[%p], 
+	       niov[%d], iov [%p], mlen["LPSZ"], rlen["LPSZ"]\n", 
+	       nal_cb, private, cookie, niov, iov, mlen, rlen);
+
+	switch(srxd->type) {
+	case(GMNAL_SMALL_MESSAGE):
+		CDEBUG(D_INFO, "gmnal_cb_recv got small message\n");
+		status = gmnal_small_rx(nal_cb, private, cookie, niov, 
+				         iov, mlen, rlen);
+	break;
+	case(GMNAL_LARGE_MESSAGE_INIT):
+		CDEBUG(D_INFO, "gmnal_cb_recv got large message init\n");
+		status = gmnal_large_rx(nal_cb, private, cookie, niov, 
+					 iov, mlen, rlen);
+	}
+		
+
+	CDEBUG(D_INFO, "gmnal_cb_recv gmnal_return status [%d]\n", status);
+	return(status);
 }
 
-static void
-kgmnal_printf(nal_cb_t *nal, const char *fmt, ...)
+int gmnal_cb_recv_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+			 unsigned int kniov, ptl_kiov_t *kiov, size_t mlen, 
+			 size_t rlen)
 {
-        va_list                ap;
-        char msg[256];
-
-        if (portal_debug & D_NET) {
-                va_start( ap, fmt );
-                vsnprintf( msg, sizeof(msg), fmt, ap );
-                va_end( ap );
-
-                printk("CPUId: %d %s",smp_processor_id(), msg);
-        }
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	int		status = PTL_OK;
+	struct iovec	*iovec = NULL, *iovec_dup = NULL;
+	int		i = 0;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_recv_pages nal_cb [%p],private[%p], 
+	       cookie[%p], kniov[%d], kiov [%p], mlen["LPSZ"], rlen["LPSZ"]\n",
+	       nal_cb, private, cookie, kniov, kiov, mlen, rlen);
+
+	if (srxd->type == GMNAL_SMALL_MESSAGE) {
+		PORTAL_ALLOC(iovec, sizeof(struct iovec)*kniov);
+		if (!iovec) {
+			CDEBUG(D_ERROR, "Can't malloc\n");
+			return(GMNAL_STATUS_FAIL);
+		}
+                iovec_dup = iovec;
+
+		/*
+		 *	map each page and create an iovec for it
+		 */
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+		 	       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+			iovec->iov_len = kiov->kiov_len;
+			CDEBUG(D_INFO, "Calling kmap[%p]", kiov->kiov_page);
+
+			iovec->iov_base = kmap(kiov->kiov_page) + 
+					          kiov->kiov_offset;
+
+			CDEBUG(D_INFO, "iov_base is [%p]\n", iovec->iov_base);
+                        iovec++;
+                        kiov++;
+		}
+		CDEBUG(D_INFO, "calling gmnal_small_rx\n");
+		status = gmnal_small_rx(nal_cb, private, cookie, kniov, 
+				         iovec_dup, mlen, rlen);
+		PORTAL_FREE(iovec_dup, sizeof(struct iovec)*kniov);
+	}
+		
+
+	CDEBUG(D_INFO, "gmnal_return status [%d]\n", status);
+	return(status);
 }
 
 
-static void
-kgmnal_cli(nal_cb_t *nal, unsigned long *flags)
+int gmnal_cb_send(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		   ptl_hdr_t *hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 
+		   unsigned int niov, struct iovec *iov, size_t len)
 {
-        kgmnal_data_t *data= nal->nal_data;
 
-        spin_lock_irqsave(&data->kgm_dispatch_lock,*flags);
+	gmnal_data_t	*nal_data;
+
+
+	CDEBUG(D_TRACE, "gmnal_cb_send niov[%d] len["LPSZ"] nid["LPU64"]\n", 
+	       niov, len, nid);
+	nal_data = nal_cb->nal_data;
+	
+	if (GMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, len)) {
+		CDEBUG(D_INFO, "This is a small message send\n");
+		gmnal_small_tx(nal_cb, private, cookie, hdr, type, nid, pid, 
+			       	niov, iov, len);
+	} else {
+		CDEBUG(D_ERROR, "Large message send it is not supported\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+		gmnal_large_tx(nal_cb, private, cookie, hdr, type, nid, pid, 
+				niov, iov, len);
+	}
+	return(PTL_OK);
 }
 
-
-static void
-kgmnal_sti(nal_cb_t *nal, unsigned long *flags)
+int gmnal_cb_send_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+			 ptl_hdr_t *hdr, int type, ptl_nid_t nid, ptl_pid_t pid, 			 unsigned int kniov, ptl_kiov_t *kiov, size_t len)
 {
-        kgmnal_data_t *data= nal->nal_data;
-
-        spin_unlock_irqrestore(&data->kgm_dispatch_lock,*flags);
-}
-
 
-static int
-kgmnal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
-{
-        /* network distance doesn't mean much for this nal */
-        if ( nal->ni.nid == nid ) {
-                *dist = 0;
-        } else {
-                *dist = 1;
-        }
-
-        return 0;
+	int	i = 0;
+	gmnal_data_t	*nal_data;
+	struct	iovec 	*iovec = NULL, *iovec_dup = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_cb_send_pages nid ["LPU64"] niov[%d] len["LPSZ"]\n", nid, kniov, len);
+	nal_data = nal_cb->nal_data;
+	PORTAL_ALLOC(iovec, kniov*sizeof(struct iovec));
+        iovec_dup = iovec;
+	if (GMNAL_IS_SMALL_MESSAGE(nal_data, 0, NULL, len)) {
+		CDEBUG(D_INFO, "This is a small message send\n");
+		
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+			       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+
+			iovec->iov_base = kmap(kiov->kiov_page) 
+					        + kiov->kiov_offset;
+
+			iovec->iov_len = kiov->kiov_len;
+                        iovec++;
+                        kiov++;
+		}
+		gmnal_small_tx(nal_cb, private, cookie, hdr, type, nid, 
+				pid, kniov, iovec_dup, len);
+	} else {
+		CDEBUG(D_ERROR, "Large message send it is not supported yet\n");
+		return(PTL_FAIL);
+		for (i=0; i<kniov; i++) {
+			CDEBUG(D_INFO, "processing kniov [%d] [%p]\n", i, kiov);
+			CDEBUG(D_INFO, "kniov page [%p] len [%d] offset[%d]\n",
+			       kiov->kiov_page, kiov->kiov_len, 
+			       kiov->kiov_offset);
+
+			iovec->iov_base = kmap(kiov->kiov_page) 
+					         + kiov->kiov_offset;
+			iovec->iov_len = kiov->kiov_len;
+                        iovec++;
+                        kiov++;
+		}
+		gmnal_large_tx(nal_cb, private, cookie, hdr, type, nid, 
+				pid, kniov, iovec, len);
+	}
+	PORTAL_FREE(iovec_dup, kniov*sizeof(struct iovec));
+	return(PTL_OK);
 }
 
-/* FIXME rmr: add rounting code here */
-static void
-kgmnal_tx_done(kgmnal_tx_t  *trans, int error)
-{
-        lib_finalize(trans->ktx_nal, trans->ktx_private, trans->ktx_cookie);
-
-        gm_dma_free(kgmnal_data.kgm_port, trans->ktx_buffer);
-
-        trans->ktx_buffer = NULL;
-        trans->ktx_len = 0;
-
-        put_trans(trans);
-}
-static char * gm_error_strings[GM_NUM_STATUS_CODES] = {
-        [GM_SUCCESS] = "GM_SUCCESS",
-        [GM_SEND_TIMED_OUT] = "GM_SEND_TIMED_OUT",
-        [GM_SEND_REJECTED] = "GM_SEND_REJECTED",
-        [GM_SEND_TARGET_PORT_CLOSED] = "GM_SEND_TARGET_PORT_CLOSED",
-        [GM_SEND_TARGET_NODE_UNREACHABLE] = "GM_SEND_TARGET_NODE_UNREACHABLE",
-        [GM_SEND_DROPPED] = "GM_SEND_DROPPED",
-        [GM_SEND_PORT_CLOSED] = "GM_SEND_PORT_CLOSED",
-};
-
-inline char * get_error(int status)
+int gmnal_cb_read(nal_cb_t *nal_cb, void *private, void *dst, 
+		   user_ptr src, size_t len)
 {
-        if (gm_error_strings[status] != NULL)
-                return gm_error_strings[status];
-        else
-                return "Unknown error";
+	gm_bcopy(src, dst, len);
+	return(PTL_OK);
 }
 
-static void
-kgmnal_errhandler(struct gm_port *p, void *context, gm_status_t status)
+int gmnal_cb_write(nal_cb_t *nal_cb, void *private, user_ptr dst, 
+		    void *src, size_t len)
 {
-        CDEBUG(D_NET,"error callback: ktx %p status %d\n", context, status);
+	gm_bcopy(src, dst, len);
+	return(PTL_OK);
 }
 
-static void
-kgmnal_txhandler(struct gm_port *p, void *context, gm_status_t status)
+int gmnal_cb_callback(nal_cb_t *nal_cb, void *private, lib_eq_t *eq, 
+		       ptl_event_t *ev)
 {
-        kgmnal_tx_t *ktx = (kgmnal_tx_t *)context;
-        int err = 0;
-
-        LASSERT (p != NULL);
-        LASSERT (ktx != NULL);
-
-        CDEBUG(D_NET,"ktx %p status %d nid 0x%x pid %d\n", ktx, status,
-                ktx->ktx_tgt_node, ktx->ktx_tgt_port_id);
-
-        switch((int)status) {
-        case GM_SUCCESS:        /* normal */
-                break;
-        case GM_SEND_TIMED_OUT: /* application error */
-        case GM_SEND_REJECTED:  /* size of msg unacceptable */
-        case GM_SEND_TARGET_PORT_CLOSED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                gm_resume_sending(kgmnal_data.kgm_port, ktx->ktx_priority,
-                                  ktx->ktx_tgt_node, ktx->ktx_tgt_port_id,
-                                  kgmnal_errhandler, NULL);
-                err = -EIO;
-                break;
-        case GM_SEND_TARGET_NODE_UNREACHABLE:
-        case GM_SEND_PORT_CLOSED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                gm_drop_sends(kgmnal_data.kgm_port, ktx->ktx_priority,
-                              ktx->ktx_tgt_node, ktx->ktx_tgt_port_id,
-                              kgmnal_errhandler, NULL);
-                err = -EIO;
-                break;
-        case GM_SEND_DROPPED:
-                CERROR("%s (%d):\n", get_error(status), status);
-                err = -EIO;
-                break;
-        default:
-                CERROR("Unknown status: %d\n", status);
-                err = -EIO;
-                break;
-        }
-
-        kgmnal_tx_done(ktx, err);
-}
-
-/*
- */
 
-static int
-kgmnal_send(nal_cb_t        *nal,
-           void            *private,
-           lib_msg_t       *cookie,
-           ptl_hdr_t       *hdr,
-           int              type,
-           ptl_nid_t        nid,
-           ptl_pid_t        pid,
-           int              options,
-           unsigned int     niov,
-           lib_md_iov_t    *iov,
-           size_t           len)
-{
-        /*
-         * ipnal assumes that this is the private as passed to lib_dispatch..
-         * so do we :/
-         */
-        kgmnal_tx_t *ktx=NULL;
-        int rc=0;
-        void * buf;
-        int buf_len = sizeof(ptl_hdr_t) + len;
-        int buf_size = 0;
-
-        LASSERT ((options & PTL_MD_KIOV) == 0);
-        
-        PROF_START(gmnal_send);
-
-
-        CDEBUG(D_NET, "sending %d bytes from %p to nid: 0x%Lx pid %d\n",
-               len, iov, nid, KGM_PORT_NUM);
-
-        /* ensure there is an available tx handle */
-
-        /* save transaction info to trans for later finalize and cleanup */
-        ktx = get_trans();
-        if (ktx == NULL) {
-                rc = -ENOMEM;
-                goto send_exit;
-        }
-
-        /* hmmm... GM doesn't support vectored write, so need to allocate buffer to coalesce
-           header and data.
-           Also, memory must be dma'able or registered with GM. */
-
-        if (buf_len <= MSG_LEN_SMALL) {
-                buf_size = MSG_SIZE_SMALL;
-        } else if (buf_len <= MSG_LEN_LARGE) {
-                buf_size = MSG_SIZE_LARGE;
-        } else {
-                printk("kgmnal:request exceeds TX MTU size (%d).\n",
-                       MSG_SIZE_LARGE);
-                rc = -1;
-                goto send_exit;
-        }
-
-               buf = gm_dma_malloc(kgmnal_data.kgm_port, buf_len);
-        if (buf == NULL) {
-                rc = -ENOMEM;
-                goto send_exit;
-        }
-        memcpy(buf, hdr, sizeof(ptl_hdr_t));
-
-        if (len != 0)
-                lib_copy_iov2buf(((char *)buf) + sizeof (ptl_hdr_t), 
-                                 options, niov, iov, len);
-
-        ktx->ktx_nal = nal;
-        ktx->ktx_private = private;
-        ktx->ktx_cookie = cookie;
-        ktx->ktx_len = buf_len;
-        ktx->ktx_size = buf_size;
-        ktx->ktx_buffer = buf;
-        ktx->ktx_priority = GM_LOW_PRIORITY;
-        ktx->ktx_tgt_node = nid;
-        ktx->ktx_tgt_port_id = KGM_PORT_NUM;
-
-        CDEBUG(D_NET, "gm_send %d bytes (size %d) from %p to nid: 0x%Lx "
-               "pid %d pri %d\n", buf_len, buf_size, iov, nid, KGM_PORT_NUM,
-               GM_LOW_PRIORITY);
-
-        gm_send_with_callback(kgmnal_data.kgm_port, buf, buf_size,
-                              buf_len, GM_LOW_PRIORITY,
-                              nid, KGM_PORT_NUM,
-                              kgmnal_txhandler, ktx);
-
-        PROF_FINISH(gmnal_send);
- send_exit:
-        return rc;
-}
-void
-kgmnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
-{
-        CERROR ("forwarding not implemented\n");
+	if (eq->event_callback != NULL) {
+		CDEBUG(D_INFO, "found callback\n");
+		eq->event_callback(ev);
+	}
+	
+	return(PTL_OK);
 }
 
-void
-kqswnal_fwd_callback (void *arg, int error)
+void *gmnal_cb_malloc(nal_cb_t *nal_cb, size_t len)
 {
-        CERROR ("forwarding not implemented\n");
+	void *ptr = NULL;
+	CDEBUG(D_TRACE, "gmnal_cb_malloc len["LPSZ"]\n", len);
+	PORTAL_ALLOC(ptr, len);
+	return(ptr);
 }
 
-
-static inline void
-kgmnal_requeue_rx(kgmnal_rx_t *krx)
+void gmnal_cb_free(nal_cb_t *nal_cb, void *buf, size_t len)
 {
-        gm_provide_receive_buffer(kgmnal_data.kgm_port, krx->krx_buffer,
-                                  krx->krx_size, krx->krx_priority);
+	CDEBUG(D_TRACE, "gmnal_cb_free :: buf[%p] len["LPSZ"]\n", buf, len);
+	PORTAL_FREE(buf, len);
+	return;
 }
 
-/* Process a received portals packet */
-
-/* Receive Interrupt Handler */
-static void kgmnal_rx(kgmnal_data_t *kgm, unsigned long len, unsigned int size,
-                      void * buf, unsigned int pri)
+void gmnal_cb_unmap(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, 
+		     void **addrkey)
 {
-        ptl_hdr_t  *hdr = buf;
-        kgmnal_rx_t krx;
-
-        CDEBUG(D_NET,"buf %p, len %ld\n", buf, len);
-
-        if ( len < sizeof( ptl_hdr_t ) ) {
-                /* XXX what's this for? */
-                if (kgm->kgm_shuttingdown)
-                        return;
-                CERROR("kgmnal: did not receive complete portal header, "
-                       "len= %ld", len);
-                gm_provide_receive_buffer(kgm->kgm_port, buf, size, pri);
-                return;
-        }
-
-       /* might want to use seperate threads to handle receive */
-        krx.krx_buffer = buf;
-        krx.krx_len = len;
-        krx.krx_size = size;
-        krx.krx_priority = pri;
-
-        if ( hdr->dest_nid == kgmnal_lib.ni.nid ) {
-                PROF_START(lib_parse);
-                lib_parse(&kgmnal_lib, (ptl_hdr_t *)krx.krx_buffer, &krx);
-                PROF_FINISH(lib_parse);
-        } else if (kgmnal_ispeer(hdr->dest_nid)) {
-                /* should have gone direct to peer */
-                CERROR("dropping packet from 0x%llx to 0x%llx: target is "
-                       "a peer", hdr->src_nid, hdr->dest_nid);
-                kgmnal_requeue_rx(&krx);
-        } else {
-                /* forward to gateway */
-                CERROR("forwarding not implemented yet");
-                kgmnal_requeue_rx(&krx);
-        }
-
-        return;
+	return;
 }
 
-
-static int kgmnal_recv(nal_cb_t     *nal,
-                      void         *private,
-                      lib_msg_t    *cookie,
-                      int           options,
-                      unsigned int  niov,
-                      lib_md_iov_t *iov,
-                      size_t        mlen,
-                      size_t        rlen)
+int  gmnal_cb_map(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, 
+		   void**addrkey)
 {
-        kgmnal_rx_t *krx = private;
-
-        LASSERT ((options & PTL_MD_KIOV) == 0);
-
-        CDEBUG(D_NET,"mlen=%d, rlen=%d\n", mlen, rlen);
-
-        /* What was actually received must be >= what sender claims to
-         * have sent.  This is an LASSERT, since lib-move doesn't
-         * check cb return code yet. */
-        LASSERT (krx->krx_len >= sizeof (ptl_hdr_t) + rlen);
-        LASSERT (mlen <= rlen);
-
-        PROF_START(gmnal_recv);
-
-        if(mlen != 0) {
-                PROF_START(memcpy);
-                lib_copy_buf2iov (options, niov, iov, 
-                                  krx->krx_buffer + sizeof (ptl_hdr_t), mlen);
-                PROF_FINISH(memcpy);
-        }
-
-        PROF_START(lib_finalize);
-        lib_finalize(nal, private, cookie);
-        PROF_FINISH(lib_finalize);
-
-        kgmnal_requeue_rx(krx);
-
-        PROF_FINISH(gmnal_recv);
-
-        return rlen;
+	return(PTL_OK);
 }
 
-
-static void kgmnal_shutdown(void * none)
+void gmnal_cb_printf(nal_cb_t *nal_cb, const char *fmt, ...)
 {
-        CERROR("called\n");
-        return;
+	CDEBUG(D_TRACE, "gmnal_cb_printf\n");
+	printk(fmt);
+	return;
 }
 
-/*
- * Set terminate and use alarm to wake up the recv thread.
- */
-static void  recv_shutdown(kgmnal_data_t *kgm)
+void gmnal_cb_cli(nal_cb_t *nal_cb, unsigned long *flags)
 {
-        gm_alarm_t alarm;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
 
-        kgm->kgm_shuttingdown = 1;
-        gm_initialize_alarm(&alarm);
-        gm_set_alarm(kgm->kgm_port, &alarm, 1, kgmnal_shutdown, NULL);
+	spin_lock_irqsave(&nal_data->cb_lock, *flags);
+	return;
 }
 
-int kgmnal_end(kgmnal_data_t *kgm)
+void gmnal_cb_sti(nal_cb_t *nal_cb, unsigned long *flags)
 {
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
 
-        /* wait for sends to finish ? */
-        /* remove receive buffers */
-        /* shutdown receive thread */
-
-        recv_shutdown(kgm);
-
-        return 0;
+	spin_unlock_irqrestore(&nal_data->cb_lock, *flags);
+	return;
 }
 
-/* Used only for the spinner */
-int kgmnal_recv_thread(void *arg)
+int gmnal_cb_dist(nal_cb_t *nal_cb, ptl_nid_t nid, unsigned long *dist)
 {
-        kgmnal_data_t *kgm = arg;
-
-        LASSERT(kgm != NULL);
-
-        kportal_daemonize("kgmnal_rx");
-        
-        while(1) {
-                gm_recv_event_t *e;
-                int priority = GM_LOW_PRIORITY;
-                if (kgm->kgm_shuttingdown)
-                        break;
-
-                e = gm_blocking_receive_no_spin(kgm->kgm_port);
-                if (e == NULL) {
-                        CERROR("gm_blocking_receive returned NULL\n");
-                        break;
-                }
-
-                switch(gm_ntohc(e->recv.type)) {
-                case GM_HIGH_RECV_EVENT:
-                        priority = GM_HIGH_PRIORITY;
-                        /* fall through */
-                case GM_RECV_EVENT:
-                        kgmnal_rx(kgm, gm_ntohl(e->recv.length),
-                                  gm_ntohc(e->recv.size),
-                                  gm_ntohp(e->recv.buffer), priority);
-                        break;
-                case GM_ALARM_EVENT:
-                        CERROR("received alarm");
-                        gm_unknown(kgm->kgm_port, e);
-                        break;
-                case GM_BAD_SEND_DETECTED_EVENT: /* ?? */
-                        CERROR("received bad send!\n");
-                        break;
-                default:
-                        gm_unknown(kgm->kgm_port, e);
-                }
-        }
-
-        CERROR("shuttting down.\n");
-        return 0;
+	CDEBUG(D_TRACE, "gmnal_cb_dist\n");
+	if (dist)
+		*dist = 27;
+	return(PTL_OK);
 }
-
-nal_cb_t kgmnal_lib = {
-        nal_data: &kgmnal_data,                /* NAL private data */
-        cb_send: kgmnal_send,
-        cb_recv: kgmnal_recv,
-        cb_read: kgmnal_read,
-        cb_write: kgmnal_write,
-        cb_malloc: kgmnal_malloc,
-        cb_free: kgmnal_free,
-        cb_printf: kgmnal_printf,
-        cb_cli: kgmnal_cli,
-        cb_sti: kgmnal_sti,
-        cb_dist: kgmnal_dist
-};
diff --git a/lustre/portals/knals/gmnal/gmnal_comm.c b/lustre/portals/knals/gmnal/gmnal_comm.c
new file mode 100644
index 0000000000000000000000000000000000000000..4171df669f481d76c17b0c742806564d0e21ced7
--- /dev/null
+++ b/lustre/portals/knals/gmnal/gmnal_comm.c
@@ -0,0 +1,1319 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *	This file contains all gmnal send and receive functions
+ */
+
+#include "gmnal.h"
+
+/*
+ *	The caretaker thread
+ *	This is main thread of execution for the NAL side
+ *	This guy waits in gm_blocking_recvive and gets
+ *	woken up when the myrinet adaptor gets an interrupt.
+ *	Hands off receive operations to the receive thread 
+ *	This thread Looks after gm_callbacks etc inline.
+ */
+int
+gmnal_ct_thread(void *arg)
+{
+	gmnal_data_t		*nal_data;
+	gm_recv_event_t		*rxevent = NULL;
+	gm_recv_t		*recv = NULL;
+
+	if (!arg) {
+		CDEBUG(D_TRACE, "NO nal_data. Exiting\n");
+		return(-1);
+	}
+
+	nal_data = (gmnal_data_t*)arg;
+	CDEBUG(D_TRACE, "nal_data is [%p]\n", arg);
+
+	daemonize();
+
+	nal_data->ctthread_flag = GMNAL_CTTHREAD_STARTED;
+
+	GMNAL_GM_LOCK(nal_data);
+	while(nal_data->ctthread_flag == GMNAL_CTTHREAD_STARTED) {
+		CDEBUG(D_NET, "waiting\n");
+		rxevent = gm_blocking_receive_no_spin(nal_data->gm_port);
+		if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+			CDEBUG(D_INFO, "time to exit\n");
+			break;
+		}
+		CDEBUG(D_INFO, "got [%s]\n", gmnal_rxevent(rxevent));
+		switch (GM_RECV_EVENT_TYPE(rxevent)) {
+
+			case(GM_RECV_EVENT):
+				CDEBUG(D_NET, "CTTHREAD:: GM_RECV_EVENT\n");
+				recv = (gm_recv_t*)&rxevent->recv;
+				GMNAL_GM_UNLOCK(nal_data);
+				gmnal_add_rxtwe(nal_data, recv);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_NET, "CTTHREAD:: Added event to Q\n");
+			break;
+			case(_GM_SLEEP_EVENT):
+				/*
+				 *	Blocking receive above just returns
+				 *	immediatly with _GM_SLEEP_EVENT
+				 *	Don't know what this is
+				 */
+				CDEBUG(D_NET, "Sleeping in gm_unknown\n");
+				GMNAL_GM_UNLOCK(nal_data);
+				gm_unknown(nal_data->gm_port, rxevent);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_INFO, "Awake from gm_unknown\n");
+				break;
+				
+			default:
+				/*
+				 *	Don't know what this is
+				 *	gm_unknown will make sense of it
+				 *	Should be able to do something with
+				 *	FAST_RECV_EVENTS here.
+				 */
+				CDEBUG(D_NET, "Passing event to gm_unknown\n");
+				GMNAL_GM_UNLOCK(nal_data);
+				gm_unknown(nal_data->gm_port, rxevent);
+				GMNAL_GM_LOCK(nal_data);
+				CDEBUG(D_INFO, "Processed unknown event\n");
+		}
+	}
+	GMNAL_GM_UNLOCK(nal_data);
+	nal_data->ctthread_flag = GMNAL_THREAD_RESET;
+	CDEBUG(D_INFO, "thread nal_data [%p] is exiting\n", nal_data);
+	return(GMNAL_STATUS_OK);
+}
+
+
+/*
+ *	process a receive event
+ */
+int gmnal_rx_thread(void *arg)
+{
+	gmnal_data_t		*nal_data;
+	void			*buffer;
+	gmnal_rxtwe_t		*we = NULL;
+
+	if (!arg) {
+		CDEBUG(D_TRACE, "NO nal_data. Exiting\n");
+		return(-1);
+	}
+
+	nal_data = (gmnal_data_t*)arg;
+	CDEBUG(D_TRACE, "nal_data is [%p]\n", arg);
+
+	daemonize();
+	/*
+	 * 	set 1 bit for each thread started
+	 *	doesn't matter which bit
+	 */
+	spin_lock(&nal_data->rxthread_flag_lock);
+	if (nal_data->rxthread_flag)
+		nal_data->rxthread_flag=nal_data->rxthread_flag*2 + 1;
+	else
+		nal_data->rxthread_flag = 1;
+	CDEBUG(D_INFO, "rxthread flag is [%ld]\n", nal_data->rxthread_flag);
+	spin_unlock(&nal_data->rxthread_flag_lock);
+
+	while(nal_data->rxthread_stop_flag != GMNAL_THREAD_STOP) {
+		CDEBUG(D_NET, "RXTHREAD:: Receive thread waiting\n");
+		we = gmnal_get_rxtwe(nal_data);
+		if (!we) {
+			CDEBUG(D_INFO, "Receive thread time to exit\n");
+			break;
+		}
+
+		buffer = we->buffer;
+		switch(((gmnal_msghdr_t*)buffer)->type) {
+		case(GMNAL_SMALL_MESSAGE):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_SMALL_MESSAGE);
+		break;	
+		case(GMNAL_LARGE_MESSAGE_INIT):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_LARGE_MESSAGE_INIT);
+		break;	
+		case(GMNAL_LARGE_MESSAGE_ACK):
+			gmnal_pre_receive(nal_data, we, 
+					   GMNAL_LARGE_MESSAGE_ACK);
+		break;	
+		default:
+			CDEBUG(D_ERROR, "Unsupported message type\n");
+			gmnal_rx_bad(nal_data, we, NULL);
+		}
+		PORTAL_FREE(we, sizeof(gmnal_rxtwe_t));
+	}
+
+	spin_lock(&nal_data->rxthread_flag_lock);
+	nal_data->rxthread_flag/=2;
+	CDEBUG(D_INFO, "rxthread flag is [%ld]\n", nal_data->rxthread_flag);
+	spin_unlock(&nal_data->rxthread_flag_lock);
+	CDEBUG(D_INFO, "thread nal_data [%p] is exiting\n", nal_data);
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	Start processing a small message receive
+ *	Get here from gmnal_receive_thread
+ *	Hand off to lib_parse, which calls cb_recv
+ *	which hands back to gmnal_small_receive
+ *	Deal with all endian stuff here.
+ */
+int
+gmnal_pre_receive(gmnal_data_t *nal_data, gmnal_rxtwe_t *we, int gmnal_type)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	void		*buffer = NULL;
+	unsigned int snode, sport, type, length;
+	gmnal_msghdr_t	*gmnal_msghdr;
+	ptl_hdr_t	*portals_hdr;
+
+	CDEBUG(D_INFO, "nal_data [%p], we[%p] type [%d]\n", 
+	       nal_data, we, gmnal_type);
+
+	buffer = we->buffer;
+	snode = we->snode;
+	sport = we->sport;
+	type = we->type;
+	buffer = we->buffer;
+	length = we->length;
+
+	gmnal_msghdr = (gmnal_msghdr_t*)buffer;
+	portals_hdr = (ptl_hdr_t*)(buffer+GMNAL_MSGHDR_SIZE);
+
+	CDEBUG(D_INFO, "rx_event:: Sender node [%d], Sender Port [%d], 
+	       type [%d], length [%d], buffer [%p]\n",
+	       snode, sport, type, length, buffer);
+	CDEBUG(D_INFO, "gmnal_msghdr:: Sender node [%u], magic [%d], 
+	       gmnal_type [%d]\n", gmnal_msghdr->sender_node_id, 
+	       gmnal_msghdr->magic, gmnal_msghdr->type);
+	CDEBUG(D_INFO, "portals_hdr:: Sender node ["LPD64"], 
+	       dest_node ["LPD64"]\n", portals_hdr->src_nid, 
+	       portals_hdr->dest_nid);
+
+	
+	/*
+ 	 *	Get a receive descriptor for this message
+	 */
+	srxd = gmnal_rxbuffer_to_srxd(nal_data, buffer);
+	CDEBUG(D_INFO, "Back from gmnal_rxbuffer_to_srxd\n");
+	srxd->nal_data = nal_data;
+	if (!srxd) {
+		CDEBUG(D_ERROR, "Failed to get receive descriptor\n");
+		lib_parse(nal_data->nal_cb, portals_hdr, srxd);
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	/*
+ 	 *	no need to bother portals library with this
+	 */
+	if (gmnal_type == GMNAL_LARGE_MESSAGE_ACK) {
+		gmnal_large_tx_ack_received(nal_data, srxd);
+		return(GMNAL_STATUS_OK);
+	}
+
+	srxd->type = gmnal_type;
+	srxd->nsiov = gmnal_msghdr->niov;
+	srxd->gm_source_node = gmnal_msghdr->sender_node_id;
+	
+	CDEBUG(D_PORTALS, "Calling lib_parse buffer is [%p]\n", 
+	       buffer+GMNAL_MSGHDR_SIZE);
+	/*
+ 	 *	control passes to lib, which calls cb_recv 
+	 *	cb_recv is responsible for returning the buffer 
+	 *	for future receive
+	 */
+	lib_parse(nal_data->nal_cb, portals_hdr, srxd);
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	After a receive has been processed, 
+ *	hang out the receive buffer again.
+ *	This implicitly returns a receive token.
+ */
+int
+gmnal_rx_requeue_buffer(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+	CDEBUG(D_TRACE, "gmnal_rx_requeue_buffer\n");
+
+	CDEBUG(D_NET, "requeueing srxd[%p] nal_data[%p]\n", srxd, nal_data);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer,
+					srxd->gmsize, GM_LOW_PRIORITY, 0 );
+	GMNAL_GM_UNLOCK(nal_data);
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+/*
+ *	Handle a bad message
+ *	A bad message is one we don't expect or can't interpret
+ */
+int
+gmnal_rx_bad(gmnal_data_t *nal_data, gmnal_rxtwe_t *we, gmnal_srxd_t *srxd)
+{
+	CDEBUG(D_TRACE, "Can't handle message\n");
+
+	if (!srxd)
+		srxd = gmnal_rxbuffer_to_srxd(nal_data, 
+					       we->buffer);
+	if (srxd) {
+		gmnal_rx_requeue_buffer(nal_data, srxd);
+	} else {
+		CDEBUG(D_ERROR, "Can't find a descriptor for this buffer\n");
+		/*
+		 *	get rid of it ?
+		 */
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*
+ *	Process a small message receive.
+ *	Get here from gmnal_receive_thread, gmnal_pre_receive
+ *	lib_parse, cb_recv
+ *	Put data from prewired receive buffer into users buffer(s)
+ *	Hang out the receive buffer again for another receive
+ *	Call lib_finalize
+ */
+int
+gmnal_small_rx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		unsigned int niov, struct iovec *iov, size_t mlen, size_t rlen)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	void	*buffer = NULL;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
+
+
+	CDEBUG(D_TRACE, "niov [%d] mlen["LPSZ"]\n", niov, mlen);
+
+	if (!private) {
+		CDEBUG(D_ERROR, "gmnal_small_rx no context\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+	}
+
+	srxd = (gmnal_srxd_t*)private;
+	buffer = srxd->buffer;
+	buffer += sizeof(gmnal_msghdr_t);
+	buffer += sizeof(ptl_hdr_t);
+
+	while(niov--) {
+		CDEBUG(D_INFO, "processing [%p] len ["LPSZ"]\n", iov, 
+		       iov->iov_len);
+		gm_bcopy(buffer, iov->iov_base, iov->iov_len);			
+		buffer += iov->iov_len;
+		iov++;
+	}
+
+
+	/*
+ 	 *	let portals library know receive is complete
+	 */
+	CDEBUG(D_PORTALS, "calling lib_finalize\n");
+	if (lib_finalize(nal_cb, private, cookie) != PTL_OK) {
+		/* TO DO what to do with failed lib_finalise? */
+		CDEBUG(D_INFO, "lib_finalize failed\n");
+	}
+	/*
+	 *	return buffer so it can be used again
+	 */
+	CDEBUG(D_NET, "calling gm_provide_receive_buffer\n");
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
+					   srxd->gmsize, GM_LOW_PRIORITY, 0);	
+	GMNAL_GM_UNLOCK(nal_data);
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	Start a small transmit. 
+ *	Get a send token (and wired transmit buffer).
+ *	Copy data from senders buffer to wired buffer and
+ *	initiate gm_send from the wired buffer.
+ *	The callback function informs when the send is complete.
+ */
+int
+gmnal_small_tx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		ptl_hdr_t *hdr, int type, ptl_nid_t global_nid, ptl_pid_t pid, 
+		unsigned int niov, struct iovec *iov, int size)
+{
+	gmnal_data_t	*nal_data = (gmnal_data_t*)nal_cb->nal_data;
+	gmnal_stxd_t	*stxd = NULL;
+	void		*buffer = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	int		tot_size = 0;
+	unsigned int	local_nid;
+	gm_status_t	gm_status = GM_SUCCESS;
+
+	CDEBUG(D_TRACE, "gmnal_small_tx nal_cb [%p] private [%p] cookie [%p] 
+	       hdr [%p] type [%d] global_nid ["LPU64"] pid [%d] niov [%d] 
+	       iov [%p] size [%d]\n", nal_cb, private, cookie, hdr, type, 
+	       global_nid, pid, niov, iov, size);
+
+	CDEBUG(D_INFO, "portals_hdr:: dest_nid ["LPU64"], src_nid ["LPU64"]\n",
+	       hdr->dest_nid, hdr->src_nid);
+
+	if (!nal_data) {
+		CDEBUG(D_ERROR, "no nal_data\n");
+		return(GMNAL_STATUS_FAIL);
+	} else {
+		CDEBUG(D_INFO, "nal_data [%p]\n", nal_data);
+	}
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, 
+					    &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%u][%x]\n", local_nid, local_nid);
+
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_INFO, "stxd [%p]\n", stxd);
+
+	stxd->type = GMNAL_SMALL_MESSAGE;
+	stxd->cookie = cookie;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the data in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_SMALL_MESSAGE;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	buffer += sizeof(gmnal_msghdr_t);
+
+	CDEBUG(D_INFO, "processing  portals hdr at [%p]\n", buffer);
+	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
+
+	buffer += sizeof(ptl_hdr_t);
+
+	while(niov--) {
+		CDEBUG(D_INFO, "processing iov [%p] len ["LPSZ"] to [%p]\n", 
+		       iov, iov->iov_len, buffer);
+		gm_bcopy(iov->iov_base, buffer, iov->iov_len);
+		buffer+= iov->iov_len;
+		iov++;
+	}
+
+	CDEBUG(D_INFO, "sending\n");
+	tot_size = size+sizeof(ptl_hdr_t)+sizeof(gmnal_msghdr_t);
+	stxd->msg_size = tot_size;
+
+
+	CDEBUG(D_NET, "Calling gm_send_to_peer port [%p] buffer [%p] 
+   	       gmsize [%lu] msize [%d] global_nid ["LPU64"] local_nid[%d] 
+	       stxd [%p]\n", nal_data->gm_port, stxd->buffer, stxd->gm_size, 
+	       stxd->msg_size, global_nid, local_nid, stxd);
+
+	GMNAL_GM_LOCK(nal_data);
+	stxd->gm_priority = GM_LOW_PRIORITY;
+	stxd->gm_target_node = local_nid;
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, stxd->msg_size, 
+				      GM_LOW_PRIORITY, local_nid, 
+				      gmnal_small_tx_callback, (void*)stxd);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "done\n");
+		
+	return(PTL_OK);
+}
+
+
+/*
+ *	A callback to indicate the small transmit operation is compete
+ *	Check for erros and try to deal with them.
+ *	Call lib_finalise to inform the client application that the send 
+ *	is complete and the memory can be reused.
+ *	Return the stxd when finished with it (returns a send token)
+ */
+void 
+gmnal_small_tx_callback(gm_port_t *gm_port, void *context, gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	lib_msg_t	*cookie = stxd->cookie;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)stxd->nal_data;
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+
+	if (!stxd) {
+		CDEBUG(D_TRACE, "send completion event for unknown stxd\n");
+		return;
+	}
+	if (status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Result of send stxd [%p] is [%s]\n", 
+		       stxd, gmnal_gm_error(status));
+	}
+
+	switch(status) {
+  		case(GM_SUCCESS):
+		break;
+
+
+
+  		case(GM_SEND_DROPPED):
+		/*
+		 *	do a resend on the dropped ones
+		 */
+			CDEBUG(D_ERROR, "send stxd [%p] was dropped 
+			       resending\n", context);
+			GMNAL_GM_LOCK(nal_data);
+			gm_send_to_peer_with_callback(nal_data->gm_port, 
+						      stxd->buffer, 
+						      stxd->gm_size, 
+						      stxd->msg_size, 
+						      stxd->gm_priority, 
+						      stxd->gm_target_node, 
+						      gmnal_small_tx_callback,
+						      context);
+			GMNAL_GM_UNLOCK(nal_data);
+		
+		return;
+  		case(GM_TIMED_OUT):
+  		case(GM_SEND_TIMED_OUT):
+		/*
+		 *	drop these ones
+		 */
+			CDEBUG(D_INFO, "calling gm_drop_sends\n");
+			GMNAL_GM_LOCK(nal_data);
+			gm_drop_sends(nal_data->gm_port, stxd->gm_priority, 
+				      stxd->gm_target_node, GMNAL_GM_PORT, 
+				      gmnal_drop_sends_callback, context);
+			GMNAL_GM_UNLOCK(nal_data);
+
+		return;
+
+
+		/*
+		 *	abort on these ?
+		 */
+  		case(GM_TRY_AGAIN):
+  		case(GM_INTERRUPTED):
+  		case(GM_FAILURE):
+  		case(GM_INPUT_BUFFER_TOO_SMALL):
+  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
+  		case(GM_BUSY):
+  		case(GM_MEMORY_FAULT):
+  		case(GM_INVALID_PARAMETER):
+  		case(GM_OUT_OF_MEMORY):
+  		case(GM_INVALID_COMMAND):
+  		case(GM_PERMISSION_DENIED):
+  		case(GM_INTERNAL_ERROR):
+  		case(GM_UNATTACHED):
+  		case(GM_UNSUPPORTED_DEVICE):
+  		case(GM_SEND_REJECTED):
+  		case(GM_SEND_TARGET_PORT_CLOSED):
+  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
+  		case(GM_SEND_PORT_CLOSED):
+  		case(GM_NODE_ID_NOT_YET_SET):
+  		case(GM_STILL_SHUTTING_DOWN):
+  		case(GM_CLONE_BUSY):
+  		case(GM_NO_SUCH_DEVICE):
+  		case(GM_ABORTED):
+  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
+  		case(GM_ACCESS_DENIED):
+  		case(GM_NO_DRIVER_SUPPORT):
+  		case(GM_PTE_REF_CNT_OVERFLOW):
+  		case(GM_NOT_SUPPORTED_IN_KERNEL):
+  		case(GM_NOT_SUPPORTED_ON_ARCH):
+  		case(GM_NO_MATCH):
+  		case(GM_USER_ERROR):
+  		case(GM_DATA_CORRUPTED):
+  		case(GM_HARDWARE_FAULT):
+  		case(GM_SEND_ORPHANED):
+  		case(GM_MINOR_OVERFLOW):
+  		case(GM_PAGE_TABLE_FULL):
+  		case(GM_UC_ERROR):
+  		case(GM_INVALID_PORT_NUMBER):
+  		case(GM_DEV_NOT_FOUND):
+  		case(GM_FIRMWARE_NOT_RUNNING):
+  		case(GM_YP_NO_MATCH):
+		default:
+			CDEBUG(D_ERROR, "Unknown send error\n");
+	}
+
+	/*
+	 *	TO DO
+	 *	If this is a large message init,
+	 *	we're not finished with the data yet,
+	 *	so can't call lib_finalise.
+	 *	However, we're also holding on to a 
+	 *	stxd here (to keep track of the source
+	 *	iovec only). Should use another structure
+	 *	to keep track of iovec and return stxd to 
+	 *	free list earlier.
+	 */
+	if (stxd->type == GMNAL_LARGE_MESSAGE_INIT) {
+		CDEBUG(D_INFO, "large transmit done\n");
+		return;
+	}
+	gmnal_return_stxd(nal_data, stxd);
+	if (lib_finalize(nal_cb, stxd, cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for stxd [%p]\n", 
+		       stxd);
+	}
+	return;
+}
+
+
+
+void gmnal_drop_sends_callback(struct gm_port *gm_port, void *context, 
+			        gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	gmnal_data_t	*nal_data = stxd->nal_data;
+
+	CDEBUG(D_TRACE, "status is [%d] context is [%p]\n", status, context);
+	if (status == GM_SUCCESS) {
+		GMNAL_GM_LOCK(nal_data);
+		gm_send_to_peer_with_callback(gm_port, stxd->buffer, 
+					      stxd->gm_size, stxd->msg_size, 
+					      stxd->gm_priority, 
+					      stxd->gm_target_node, 
+					      gmnal_small_tx_callback, 
+					      context);
+		GMNAL_GM_LOCK(nal_data);
+	} else {
+		CDEBUG(D_ERROR, "send_to_peer status for stxd [%p] is 
+		       [%d][%s]\n", stxd, status, gmnal_gm_error(status));
+	}
+
+
+	return;
+}
+
+
+/*
+ *	Begine a large transmit.
+ *	Do a gm_register of the memory pointed to by the iovec 
+ *	and send details to the receiver. The receiver does a gm_get
+ *	to pull the data and sends and ack when finished. Upon receipt of
+ *	this ack, deregister the memory. Only 1 send token is required here.
+ */
+int
+gmnal_large_tx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+	        ptl_hdr_t *hdr, int type, ptl_nid_t global_nid, ptl_pid_t pid, 
+		unsigned int niov, struct iovec *iov, int size)
+{
+
+	gmnal_data_t	*nal_data;
+	gmnal_stxd_t	*stxd = NULL;
+	void		*buffer = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	unsigned int	local_nid;
+	int		mlen = 0;	/* the size of the init message data */
+	struct iovec	*iov_dup = NULL;
+	gm_status_t	gm_status;
+	int		niov_dup;
+
+
+	CDEBUG(D_TRACE, "gmnal_large_tx nal_cb [%p] private [%p], cookie [%p] 
+	       hdr [%p], type [%d] global_nid ["LPU64"], pid [%d], niov [%d], 
+	       iov [%p], size [%d]\n", nal_cb, private, cookie, hdr, type, 
+	       global_nid, pid, niov, iov, size);
+
+	if (nal_cb)
+		nal_data = (gmnal_data_t*)nal_cb->nal_data;
+	else  {
+		CDEBUG(D_ERROR, "no nal_cb.\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	
+
+	/*
+	 *	Get stxd and buffer. Put local address of data in buffer, 
+	 *	send local addresses to target, 
+	 *	wait for the target node to suck the data over.
+	 *	The stxd is used to ren
+	 */
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_INFO, "stxd [%p]\n", stxd);
+
+	stxd->type = GMNAL_LARGE_MESSAGE_INIT;
+	stxd->cookie = cookie;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the iov in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_LARGE_MESSAGE_INIT;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	msghdr->stxd = stxd;
+	msghdr->niov = niov ;
+	buffer += sizeof(gmnal_msghdr_t);
+	mlen = sizeof(gmnal_msghdr_t);
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+
+	CDEBUG(D_INFO, "processing  portals hdr at [%p]\n", buffer);
+
+	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
+	buffer += sizeof(ptl_hdr_t);
+	mlen += sizeof(ptl_hdr_t); 
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+	/*
+	 *	copy the iov to the buffer so target knows 
+	 *	where to get the data from
+	 */
+	CDEBUG(D_INFO, "processing iov to [%p]\n", buffer);
+	gm_bcopy(iov, buffer, niov*sizeof(struct iovec));
+	mlen += niov*(sizeof(struct iovec));
+	CDEBUG(D_INFO, "mlen is [%d]\n", mlen);
+
+
+	/*
+	 *	Store the iovs in the stxd for we can get 
+	 *	them later if we need them
+	 */
+	CDEBUG(D_NET, "Copying iov [%p] to [%p]\n", iov, stxd->iov);
+	gm_bcopy(iov, stxd->iov, niov*sizeof(struct iovec));
+	stxd->niov = niov;
+	
+
+	/*
+	 *	register the memory so the NIC can get hold of the data
+	 *	This is a slow process. it'd be good to overlap it 
+	 *	with something else.
+	 */
+	iov_dup = iov;
+	niov_dup = niov;
+	while(niov--) {
+		CDEBUG(D_INFO, "Registering memory [%p] len ["LPSZ"] \n", 
+		       iov->iov_base, iov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, 
+					       iov->iov_base, iov->iov_len);
+		if (gm_status != GM_SUCCESS) {
+			GMNAL_GM_UNLOCK(nal_data);
+			CDEBUG(D_ERROR, "gm_register_memory returns [%d][%s] 
+			       for memory [%p] len ["LPSZ"]\n", 
+			       gm_status, gmnal_gm_error(gm_status), 
+			       iov->iov_base, iov->iov_len);
+			GMNAL_GM_LOCK(nal_data);
+			while (iov_dup != iov) {
+				gm_deregister_memory(nal_data->gm_port, 
+						     iov_dup->iov_base, 
+						     iov_dup->iov_len);
+				iov_dup++;
+			}
+			GMNAL_GM_UNLOCK(nal_data);
+			gmnal_return_stxd(nal_data, stxd);
+			return(PTL_FAIL);
+		}
+
+		GMNAL_GM_UNLOCK(nal_data);
+		iov++;
+	}
+
+	/*
+ 	 *	Send the init message to the target
+	 */
+	CDEBUG(D_INFO, "sending mlen [%d]\n", mlen);
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, 
+					    &local_nid);
+	if (gm_status != GM_SUCCESS) {
+		GMNAL_GM_UNLOCK(nal_data);
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		gmnal_return_stxd(nal_data, stxd);
+		/* TO DO deregister memory on failure */
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%d]\n", local_nid);
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, mlen, GM_LOW_PRIORITY, 
+				      local_nid, gmnal_large_tx_callback, 
+				      (void*)stxd);
+	GMNAL_GM_UNLOCK(nal_data);
+	
+	CDEBUG(D_INFO, "done\n");
+		
+	return(PTL_OK);
+}
+
+/*
+ *	Callback function indicates that send of buffer with 
+ *	large message iovec has completed (or failed).
+ */
+void 
+gmnal_large_tx_callback(gm_port_t *gm_port, void *context, gm_status_t status)
+{
+	gmnal_small_tx_callback(gm_port, context, status);
+
+}
+
+
+
+/*
+ *	Have received a buffer that contains an iovec of the sender. 
+ *	Do a gm_register_memory of the receivers buffer and then do a get
+ *	data from the sender.
+ */
+int
+gmnal_large_rx(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, 
+		unsigned int nriov, struct iovec *riov, size_t mlen, 
+		size_t rlen)
+{
+	gmnal_data_t	*nal_data = nal_cb->nal_data;
+	gmnal_srxd_t	*srxd = (gmnal_srxd_t*)private;
+	void		*buffer = NULL;
+	struct	iovec	*riov_dup;
+	int		nriov_dup;
+	gmnal_msghdr_t	*msghdr = NULL;
+	gm_status_t	gm_status;
+
+	CDEBUG(D_TRACE, "gmnal_large_rx :: nal_cb[%p], private[%p], 
+	       cookie[%p], niov[%d], iov[%p], mlen["LPSZ"], rlen["LPSZ"]\n",
+		nal_cb, private, cookie, nriov, riov, mlen, rlen);
+
+	if (!srxd) {
+		CDEBUG(D_ERROR, "gmnal_large_rx no context\n");
+		lib_finalize(nal_cb, private, cookie);
+		return(PTL_FAIL);
+	}
+
+	buffer = srxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+	buffer += sizeof(gmnal_msghdr_t);
+	buffer += sizeof(ptl_hdr_t);
+
+	/*
+	 *	Store the senders stxd address in the srxd for this message
+	 *	The gmnal_large_message_ack needs it to notify the sender
+	 *	the pull of data is complete
+	 */
+	srxd->source_stxd = msghdr->stxd;
+
+	/*
+	 *	Register the receivers memory
+	 *	get the data,
+	 *	tell the sender that we got the data
+	 *	then tell the receiver we got the data
+	 *	TO DO
+	 *	If the iovecs match, could interleave 
+	 *	gm_registers and gm_gets for each element
+	 */
+	nriov_dup = nriov;
+	riov_dup = riov;
+	while(nriov--) {
+		CDEBUG(D_INFO, "Registering memory [%p] len ["LPSZ"] \n", 
+		       riov->iov_base, riov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, 
+					       riov->iov_base, riov->iov_len);
+		if (gm_status != GM_SUCCESS) {
+			GMNAL_GM_UNLOCK(nal_data);
+			CDEBUG(D_ERROR, "gm_register_memory returns [%d][%s] 
+			       for memory [%p] len ["LPSZ"]\n", 
+			       gm_status, gmnal_gm_error(gm_status), 
+			       riov->iov_base, riov->iov_len);
+			GMNAL_GM_LOCK(nal_data);
+			while (riov_dup != riov) {
+				gm_deregister_memory(nal_data->gm_port, 
+						     riov_dup->iov_base, 
+						     riov_dup->iov_len);
+				riov_dup++;
+			}
+			GMNAL_GM_LOCK(nal_data);
+			/*
+			 *	give back srxd and buffer. Send NACK to sender
+			 */
+			return(PTL_FAIL);
+		}
+		GMNAL_GM_UNLOCK(nal_data);
+		riov++;
+	}
+	/*
+	 *	do this so the final gm_get callback can deregister the memory
+	 */
+	PORTAL_ALLOC(srxd->riov, nriov_dup*(sizeof(struct iovec)));
+	gm_bcopy(riov_dup, srxd->riov, nriov_dup*(sizeof(struct iovec)));
+	srxd->nriov = nriov_dup;
+
+	/*
+	 *	now do gm_get to get the data
+	 */
+	srxd->cookie = cookie;
+	if (gmnal_remote_get(srxd, srxd->nsiov, (struct iovec*)buffer, 
+			      nriov_dup, riov_dup) != GMNAL_STATUS_OK) {
+		CDEBUG(D_ERROR, "can't get the data");
+	}
+
+	CDEBUG(D_INFO, "lgmanl_large_rx done\n");
+
+	return(PTL_OK);
+}
+
+
+/*
+ *	Perform a number of remote gets as part of receiving 
+ *	a large message.
+ *	The final one to complete (i.e. the last callback to get called)
+ *	tidies up.
+ *	gm_get requires a send token.
+ */
+int
+gmnal_remote_get(gmnal_srxd_t *srxd, int nsiov, struct iovec *siov, 
+		  int nriov, struct iovec *riov)
+{
+
+	int	ncalls = 0;
+
+	CDEBUG(D_TRACE, "gmnal_remote_get srxd[%p], nriov[%d], riov[%p], 
+	       nsiov[%d], siov[%p]\n", srxd, nriov, riov, nsiov, siov);
+
+
+	ncalls = gmnal_copyiov(0, srxd, nsiov, siov, nriov, riov);
+	if (ncalls < 0) {
+		CDEBUG(D_ERROR, "there's something wrong with the iovecs\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	CDEBUG(D_INFO, "gmnal_remote_get ncalls [%d]\n", ncalls);
+	spin_lock_init(&srxd->callback_lock);
+	srxd->ncallbacks = ncalls;
+	srxd->callback_status = 0;
+
+	ncalls = gmnal_copyiov(1, srxd, nsiov, siov, nriov, riov);
+	if (ncalls < 0) {
+		CDEBUG(D_ERROR, "there's something wrong with the iovecs\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	return(GMNAL_STATUS_OK);
+
+}
+
+
+/*
+ *	pull data from source node (source iovec) to a local iovec.
+ *	The iovecs may not match which adds the complications below.
+ *	Count the number of gm_gets that will be required to the callbacks
+ *	can determine who is the last one.
+ */	
+int
+gmnal_copyiov(int do_copy, gmnal_srxd_t *srxd, int nsiov, 
+	       struct iovec *siov, int nriov, struct iovec *riov)
+{
+
+	int	ncalls = 0;
+	int	slen = siov->iov_len, rlen = riov->iov_len;
+	char	*sbuf = siov->iov_base, *rbuf = riov->iov_base;	
+	unsigned long	sbuf_long;
+	gm_remote_ptr_t	remote_ptr = 0;
+	unsigned int	source_node;
+	gmnal_ltxd_t	*ltxd = NULL;
+	gmnal_data_t	*nal_data = srxd->nal_data;
+
+	CDEBUG(D_TRACE, "copy[%d] nal_data[%p]\n", do_copy, nal_data);
+	if (do_copy) {
+		if (!nal_data) {
+			CDEBUG(D_ERROR, "Bad args No nal_data\n");
+			return(GMNAL_STATUS_FAIL);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		if (gm_global_id_to_node_id(nal_data->gm_port, 
+					    srxd->gm_source_node, 
+					    &source_node) != GM_SUCCESS) {
+
+			CDEBUG(D_ERROR, "cannot resolve global_id [%u] 
+			       to local node_id\n", srxd->gm_source_node);
+			GMNAL_GM_UNLOCK(nal_data);
+			return(GMNAL_STATUS_FAIL);
+		}
+		GMNAL_GM_UNLOCK(nal_data);
+		/*
+		 *	We need a send token to use gm_get
+		 *	getting an stxd gets us a send token.
+		 *	the stxd is used as the context to the
+	 	 *	callback function (so stxd can be returned).
+		 *	Set pointer in stxd to srxd so callback count in srxd
+		 *	can be decremented to find last callback to complete
+		 */
+		CDEBUG(D_INFO, "gmnal_copyiov source node is G[%u]L[%d]\n", 
+		       srxd->gm_source_node, source_node);
+	}
+
+	do {
+		CDEBUG(D_INFO, "sbuf[%p] slen[%d] rbuf[%p], rlen[%d]\n",
+				sbuf, slen, rbuf, rlen);
+		if (slen > rlen) {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "slen>rlen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				/* 
+				 *	funny business to get rid 
+				 *	of compiler warning 
+				 */
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       rlen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at the end of 1 iov element
+		 	 */
+			sbuf+=rlen;
+			slen-=rlen;
+			riov++;
+			nriov--;
+			rbuf = riov->iov_base;
+			rlen = riov->iov_len;
+		} else if (rlen > slen) {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "slen<rlen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       slen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at end of siov element
+			 */
+			rbuf+=slen;
+			rlen-=slen;
+			siov++;
+			sbuf = siov->iov_base;
+			slen = siov->iov_len;
+		} else {
+			ncalls++;
+			if (do_copy) {
+				CDEBUG(D_INFO, "rlen=slen\n");
+				ltxd = gmnal_get_ltxd(nal_data);
+				ltxd->srxd = srxd;
+				GMNAL_GM_LOCK(nal_data);
+				sbuf_long = (unsigned long) sbuf;
+				remote_ptr = (gm_remote_ptr_t)sbuf_long;
+				gm_get(nal_data->gm_port, remote_ptr, rbuf, 
+				       rlen, GM_LOW_PRIORITY, source_node, 
+				       GMNAL_GM_PORT, 
+				       gmnal_remote_get_callback, ltxd);
+				GMNAL_GM_UNLOCK(nal_data);
+			}
+			/*
+			 *	at end of siov and riov element
+			 */
+			siov++;
+			sbuf = siov->iov_base;
+			slen = siov->iov_len;
+			riov++;
+			nriov--;
+			rbuf = riov->iov_base;
+			rlen = riov->iov_len;
+		}
+
+	} while (nriov);
+	return(ncalls);
+}
+
+
+/*
+ *	The callback function that is invoked after each gm_get call completes.
+ *	Multiple callbacks may be invoked for 1 transaction, only the final
+ *	callback has work to do.
+ */
+void
+gmnal_remote_get_callback(gm_port_t *gm_port, void *context, 
+			   gm_status_t status)
+{
+
+	gmnal_ltxd_t	*ltxd = (gmnal_ltxd_t*)context;
+	gmnal_srxd_t	*srxd = ltxd->srxd;
+	nal_cb_t	*nal_cb = srxd->nal_data->nal_cb;
+	int		lastone;
+	struct	iovec	*riov;
+	int		nriov;
+	gmnal_data_t	*nal_data;
+
+	CDEBUG(D_TRACE, "called for context [%p]\n", context);
+
+	if (status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "reports error [%d][%s]\n", status, 
+		       gmnal_gm_error(status));
+	}
+
+	spin_lock(&srxd->callback_lock);
+	srxd->ncallbacks--;
+	srxd->callback_status |= status;
+	lastone = srxd->ncallbacks?0:1;
+	spin_unlock(&srxd->callback_lock);
+	nal_data = srxd->nal_data;
+
+	/*
+	 *	everyone returns a send token
+	 */
+	gmnal_return_ltxd(nal_data, ltxd);
+
+	if (!lastone) {
+		CDEBUG(D_ERROR, "NOT final callback context[%p]\n", srxd);
+		return;
+	}
+	
+	/*
+	 *	Let our client application proceed
+	 */	
+	CDEBUG(D_ERROR, "final callback context[%p]\n", srxd);
+	if (lib_finalize(nal_cb, srxd, srxd->cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for srxd [%p]\n", 
+		       srxd);
+	}
+
+	/*
+	 *	send an ack to the sender to let him know we got the data
+	 */
+	gmnal_large_tx_ack(nal_data, srxd);
+
+	/*
+	 *	Unregister the memory that was used
+	 *	This is a very slow business (slower then register)
+	 */
+	nriov = srxd->nriov;
+	riov = srxd->riov;
+	GMNAL_GM_LOCK(nal_data);
+	while (nriov--) {
+		CDEBUG(D_ERROR, "deregister memory [%p]\n", riov->iov_base);
+		if (gm_deregister_memory(srxd->nal_data->gm_port, 
+		    		         riov->iov_base, riov->iov_len)) {
+			CDEBUG(D_ERROR, "failed to deregister memory [%p]\n", 
+			       riov->iov_base);
+		}
+		riov++;
+	}
+	GMNAL_GM_UNLOCK(nal_data);
+	PORTAL_FREE(srxd->riov, sizeof(struct iovec)*nriov);
+
+	/*
+	 *	repost the receive buffer (return receive token)
+	 */
+	GMNAL_GM_LOCK(nal_data);
+	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
+					   srxd->gmsize, GM_LOW_PRIORITY, 0);	
+	GMNAL_GM_UNLOCK(nal_data);
+	
+	return;
+}
+
+
+/*
+ *	Called on target node.
+ *	After pulling data from a source node
+ *	send an ack message to indicate the large transmit is complete.
+ */
+void 
+gmnal_large_tx_ack(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+
+	gmnal_stxd_t	*stxd;
+	gmnal_msghdr_t *msghdr;
+	void		*buffer = NULL;
+	unsigned int	local_nid;
+	gm_status_t	gm_status = GM_SUCCESS;
+
+	CDEBUG(D_TRACE, "srxd[%p] target_node [%u]\n", srxd, 
+	       srxd->gm_source_node);
+
+	GMNAL_GM_LOCK(nal_data);
+	gm_status = gm_global_id_to_node_id(nal_data->gm_port, 
+					    srxd->gm_source_node, &local_nid);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (gm_status != GM_SUCCESS) {
+		CDEBUG(D_ERROR, "Failed to obtain local id\n");
+		return;
+	}
+	CDEBUG(D_INFO, "Local Node_id is [%u][%x]\n", local_nid, local_nid);
+
+	stxd = gmnal_get_stxd(nal_data, 1);
+	CDEBUG(D_TRACE, "gmnal_large_tx_ack got stxd[%p]\n", stxd);
+
+	stxd->nal_data = nal_data;
+	stxd->type = GMNAL_LARGE_MESSAGE_ACK;
+
+	/*
+	 *	Copy gmnal_msg_hdr and portals header to the transmit buffer
+	 *	Then copy the data in
+	 */
+	buffer = stxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+
+	/*
+	 *	Add in the address of the original stxd from the sender node
+	 *	so it knows which thread to notify.
+	 */
+	msghdr->magic = GMNAL_MAGIC;
+	msghdr->type = GMNAL_LARGE_MESSAGE_ACK;
+	msghdr->sender_node_id = nal_data->gm_global_nid;
+	msghdr->stxd = srxd->source_stxd;
+	CDEBUG(D_INFO, "processing msghdr at [%p]\n", buffer);
+
+	CDEBUG(D_INFO, "sending\n");
+	stxd->msg_size= sizeof(gmnal_msghdr_t);
+
+
+	CDEBUG(D_NET, "Calling gm_send_to_peer port [%p] buffer [%p] 
+	       gmsize [%lu] msize [%d] global_nid [%u] local_nid[%d] 
+	       stxd [%p]\n", nal_data->gm_port, stxd->buffer, stxd->gm_size, 
+	       stxd->msg_size, srxd->gm_source_node, local_nid, stxd);
+	GMNAL_GM_LOCK(nal_data);
+	stxd->gm_priority = GM_LOW_PRIORITY;
+	stxd->gm_target_node = local_nid;
+	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, 
+				      stxd->gm_size, stxd->msg_size, 
+				      GM_LOW_PRIORITY, local_nid, 
+				      gmnal_large_tx_ack_callback, 
+				      (void*)stxd);
+	
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "gmnal_large_tx_ack :: done\n");
+		
+	return;
+}
+
+
+/*
+ *	A callback to indicate the small transmit operation is compete
+ *	Check for errors and try to deal with them.
+ *	Call lib_finalise to inform the client application that the 
+ *	send is complete and the memory can be reused.
+ *	Return the stxd when finished with it (returns a send token)
+ */
+void 
+gmnal_large_tx_ack_callback(gm_port_t *gm_port, void *context, 
+			     gm_status_t status)
+{
+	gmnal_stxd_t	*stxd = (gmnal_stxd_t*)context;
+	gmnal_data_t	*nal_data = (gmnal_data_t*)stxd->nal_data;
+
+	if (!stxd) {
+		CDEBUG(D_ERROR, "send completion event for unknown stxd\n");
+		return;
+	}
+	CDEBUG(D_TRACE, "send completion event for stxd [%p] status is [%d]\n",
+	       stxd, status);
+	gmnal_return_stxd(stxd->nal_data, stxd);
+
+	GMNAL_GM_UNLOCK(nal_data);
+	return;
+}
+
+/*
+ *	Indicates the large transmit operation is compete.
+ *	Called on transmit side (means data has been pulled  by receiver 
+ *	or failed).
+ *	Call lib_finalise to inform the client application that the send 
+ *	is complete, deregister the memory and return the stxd. 
+ *	Finally, report the rx buffer that the ack message was delivered in.
+ */
+void 
+gmnal_large_tx_ack_received(gmnal_data_t *nal_data, gmnal_srxd_t *srxd)
+{
+	nal_cb_t	*nal_cb = nal_data->nal_cb;
+	gmnal_stxd_t	*stxd = NULL;
+	gmnal_msghdr_t	*msghdr = NULL;
+	void		*buffer = NULL;
+	struct	iovec	*iov;
+
+
+	CDEBUG(D_TRACE, "gmnal_large_tx_ack_received buffer [%p]\n", buffer);
+
+	buffer = srxd->buffer;
+	msghdr = (gmnal_msghdr_t*)buffer;
+	stxd = msghdr->stxd;
+
+	CDEBUG(D_INFO, "gmnal_large_tx_ack_received stxd [%p]\n", stxd);
+
+	if (lib_finalize(nal_cb, stxd, stxd->cookie) != PTL_OK) {
+		CDEBUG(D_INFO, "Call to lib_finalize failed for stxd [%p]\n", 
+		       stxd);
+	}
+
+	/*
+	 *	extract the iovec from the stxd, deregister the memory.
+	 *	free the space used to store the iovec
+	 */
+	iov = stxd->iov;
+	while(stxd->niov--) {
+		CDEBUG(D_INFO, "deregister memory [%p] size ["LPSZ"]\n",
+		       iov->iov_base, iov->iov_len);
+		GMNAL_GM_LOCK(nal_data);
+		gm_deregister_memory(nal_data->gm_port, iov->iov_base, 
+				     iov->iov_len);
+		GMNAL_GM_UNLOCK(nal_data);
+		iov++;
+	}
+
+	/*
+	 *	return the send token
+	 *	TO DO It is bad to hold onto the send token so long?
+	 */
+	gmnal_return_stxd(nal_data, stxd);
+
+
+	/*
+	 *	requeue the receive buffer 
+	 */
+	gmnal_rx_requeue_buffer(nal_data, srxd);
+	
+
+	return;
+}
diff --git a/lustre/portals/knals/gmnal/gmnal_module.c b/lustre/portals/knals/gmnal/gmnal_module.c
new file mode 100644
index 0000000000000000000000000000000000000000..126062916ef63ed9095a81afff3625c5c6416d50
--- /dev/null
+++ b/lustre/portals/knals/gmnal/gmnal_module.c
@@ -0,0 +1,147 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gmnal.h"
+
+
+int gmnal_small_msg_size = 525312;
+/*
+ *      -1 indicates default value.
+ *      This is 1 thread per cpu
+ *      See start_kernel_threads
+ */
+int num_rx_threads = -1;
+int num_stxds = 5;
+
+ptl_handle_ni_t	kgmnal_ni;
+
+
+int 
+gmnal_cmd(struct portals_cfg *pcfg, void *private)
+{
+	gmnal_data_t	*nal_data = NULL;
+	char		*name = NULL;
+	int		nid = -2;
+	int		gnid;
+	gm_status_t	gm_status;
+
+
+	CDEBUG(D_TRACE, "gmnal_cmd [%d] private [%p]\n", 
+	       pcfg->pcfg_command, private);
+	nal_data = (gmnal_data_t*)private;
+	switch(pcfg->pcfg_command) {
+	/*
+	 * just reuse already defined GET_NID. Should define GMNAL version
+	 */
+	case(GMNAL_IOC_GET_GNID):
+
+		PORTAL_ALLOC(name, pcfg->pcfg_plen1);
+		copy_from_user(name, pcfg->pcfg_pbuf1, pcfg->pcfg_plen1);
+	
+		GMNAL_GM_LOCK(nal_data);
+		nid = gm_host_name_to_node_id(nal_data->gm_port, name);
+		GMNAL_GM_UNLOCK(nal_data);
+		CDEBUG(D_INFO, "Local node id is [%d]\n", nid);
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_node_id_to_global_id(nal_data->gm_port, 
+						    nid, &gnid);
+		GMNAL_GM_UNLOCK(nal_data);
+		if (gm_status != GM_SUCCESS) {
+			CDEBUG(D_INFO, "gm_node_id_to_global_id failed[%d]\n", 
+			       gm_status);
+			return(-1);
+		}
+		CDEBUG(D_INFO, "Global node is is [%u][%x]\n", gnid, gnid);
+		copy_to_user(pcfg->pcfg_pbuf2, &gnid, pcfg->pcfg_plen2);
+	break;
+	default:
+		CDEBUG(D_INFO, "gmnal_cmd UNKNOWN[%d]\n", pcfg->pcfg_command);
+		pcfg->pcfg_nid2 = -1;
+	}
+
+
+	return(0);
+}
+
+
+static int __init
+gmnal_load(void)
+{
+	int	status;
+	CDEBUG(D_TRACE, "This is the gmnal module initialisation routine\n");
+
+
+
+	CDEBUG(D_INFO, "Calling gmnal_init\n");
+	status = PtlNIInit(gmnal_init, 32, 4, 0, &kgmnal_ni);
+	if (status == PTL_OK) {
+		CDEBUG(D_INFO, "Portals GMNAL initialised ok kgmnal_ni\n");
+	} else {
+		CDEBUG(D_INFO, "Portals GMNAL Failed to initialise\n");
+		return(1);
+		
+	}
+
+	CDEBUG(D_INFO, "Calling kportal_nal_register\n");
+	/*
+ 	 *	global_nal_data is set by gmnal_init
+	 */
+	if (kportal_nal_register(GMNAL, &gmnal_cmd, global_nal_data) != 0) {
+		CDEBUG(D_INFO, "kportal_nal_register failed\n");
+		return(1);
+	}
+
+	CDEBUG(D_INFO, "Calling PORTAL_SYMBOL_REGISTER\n");
+	PORTAL_SYMBOL_REGISTER(kgmnal_ni);
+	CDEBUG(D_INFO, "This is the end of the gmnal init routine");
+
+
+	return(0);
+}
+
+
+static void __exit
+gmnal_unload(void)
+{
+
+	kportal_nal_unregister(GMNAL);
+	PORTAL_SYMBOL_UNREGISTER(kgmnal_ni);
+	gmnal_fini();
+	global_nal_data = NULL;
+	return;
+}
+
+
+module_init(gmnal_load);
+
+module_exit(gmnal_unload);
+
+EXPORT_SYMBOL(kgmnal_ni);
+
+MODULE_PARM(gmnal_small_msg_size, "i");
+MODULE_PARM(num_rx_threads, "i");
+MODULE_PARM(num_stxds, "i");
+
+MODULE_AUTHOR("Morgan Doyle");
+
+MODULE_DESCRIPTION("A Portals kernel NAL for Myrinet GM.");
+
+MODULE_LICENSE("GPL");
diff --git a/lustre/portals/knals/gmnal/gmnal_utils.c b/lustre/portals/knals/gmnal/gmnal_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..55606f3cda530f496538506c29e8306c1f12777a
--- /dev/null
+++ b/lustre/portals/knals/gmnal/gmnal_utils.c
@@ -0,0 +1,1073 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ *	All utilities required by lgmanl
+ */
+
+#include "gmnal.h"
+
+/*
+ *	Am I one of the gmnal rxthreads ?
+ */
+int
+gmnal_is_rxthread(gmnal_data_t *nal_data)
+{
+	int i;
+	for (i=0; i<num_rx_threads; i++) {
+		if (nal_data->rxthread_pid[i] == current->pid)
+			return(1);
+	}
+	return(0);
+}
+
+
+/*
+ *	Allocate tx descriptors/tokens (large and small)
+ *	allocate a number of small tx buffers and register with GM
+ *	so they are wired and set up for DMA. This is a costly operation.
+ *	Also allocate a corrosponding descriptor to keep track of 
+ *	the buffer.
+ *	Put all small descriptors on singly linked list to be available to send 
+ *	function.
+ *	Allocate the rest of the available tx tokens for large messages. These will be
+ *	used to do gm_gets in gmnal_copyiov	
+ */
+int
+gmnal_alloc_txd(gmnal_data_t *nal_data)
+{
+	int ntx= 0, nstx= 0, nrxt_stx= 0,
+	    nltx= 0, i = 0;
+	gmnal_stxd_t	*txd = NULL;
+	gmnal_ltxd_t	*ltxd = NULL;
+	void	*txbuffer = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_alloc_small tx\n");
+
+	GMNAL_GM_LOCK(nal_data);
+	/*
+	 *	total number of transmit tokens
+	 */
+	ntx = gm_num_send_tokens(nal_data->gm_port);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "total number of send tokens available is [%d]\n", ntx);
+	
+	/*
+ 	 *	allocate a number for small sends
+	 * 	num_stxds from gmnal_module.c
+	 */
+	nstx = num_stxds;
+	/*
+	 *	give that number plus 1 to the receive threads
+	 */
+        nrxt_stx = nstx + 1;
+
+	/*
+	 *	give the rest for gm_gets
+	 */
+	nltx = ntx - (nrxt_stx + nstx);
+	if (nltx < 1) {
+		CDEBUG(D_ERROR, "No tokens available for large messages\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+
+	/*
+	 * A semaphore is initialised with the 
+	 * number of transmit tokens available.
+	 * To get a stxd, acquire the token semaphore.
+ 	 * this decrements the available token count
+	 * (if no tokens you block here, someone returning a 
+	 * stxd will release the semaphore and wake you)
+	 * When token is obtained acquire the spinlock 
+	 * to manipulate the list
+	 */
+	GMNAL_TXD_TOKEN_INIT(nal_data, nstx);
+	GMNAL_TXD_LOCK_INIT(nal_data);
+	GMNAL_RXT_TXD_TOKEN_INIT(nal_data, nrxt_stx);
+	GMNAL_RXT_TXD_LOCK_INIT(nal_data);
+	GMNAL_LTXD_TOKEN_INIT(nal_data, nltx);
+	GMNAL_LTXD_LOCK_INIT(nal_data);
+	
+	for (i=0; i<=nstx; i++) {
+		PORTAL_ALLOC(txd, sizeof(gmnal_stxd_t));
+		if (!txd) {
+			CDEBUG(D_ERROR, "Failed to malloc txd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		txbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!txbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc txbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(txd, sizeof(gmnal_stxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		txd->buffer = txbuffer;
+		txd->buffer_size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		txd->gm_size = gm_min_size_for_length(txd->buffer_size);
+		txd->nal_data = (struct _gmnal_data_t*)nal_data;
+                txd->rxt = 0;
+
+		txd->next = nal_data->stxd;
+		nal_data->stxd = txd;
+		CDEBUG(D_INFO, "Registered txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+	}
+
+	for (i=0; i<=nrxt_stx; i++) {
+		PORTAL_ALLOC(txd, sizeof(gmnal_stxd_t));
+		if (!txd) {
+			CDEBUG(D_ERROR, "Failed to malloc txd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+		GMNAL_GM_LOCK(nal_data);
+		txbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!txbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc txbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(txd, sizeof(gmnal_stxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		txd->buffer = txbuffer;
+		txd->buffer_size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		txd->gm_size = gm_min_size_for_length(txd->buffer_size);
+		txd->nal_data = (struct _gmnal_data_t*)nal_data;
+                txd->rxt = 1;
+
+		txd->next = nal_data->rxt_stxd;
+		nal_data->rxt_stxd = txd;
+		CDEBUG(D_INFO, "Registered txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+	}
+
+	/*
+	 *	string together large tokens
+	 */
+	for (i=0; i<=nltx ; i++) {
+		PORTAL_ALLOC(ltxd, sizeof(gmnal_ltxd_t));
+		ltxd->next = nal_data->ltxd;
+		nal_data->ltxd = ltxd;
+	}
+	return(GMNAL_STATUS_OK);
+}
+
+/*	Free the list of wired and gm_registered small tx buffers and 
+ *	the tx descriptors that go along with them.
+ */
+void
+gmnal_free_txd(gmnal_data_t *nal_data)
+{
+	gmnal_stxd_t *txd = nal_data->stxd, *_txd = NULL;
+	gmnal_ltxd_t *ltxd = NULL, *_ltxd = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_free_small tx\n");
+
+	while(txd) {
+		CDEBUG(D_INFO, "Freeing txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+		_txd = txd;
+		txd = txd->next;
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _txd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_txd, sizeof(gmnal_stxd_t));
+	}
+        txd = nal_data->rxt_stxd;
+	while(txd) {
+		CDEBUG(D_INFO, "Freeing txd [%p] with buffer [%p], 
+		       size [%d]\n", txd, txd->buffer, txd->buffer_size);
+		_txd = txd;
+		txd = txd->next;
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _txd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_txd, sizeof(gmnal_stxd_t));
+	}
+	ltxd = nal_data->ltxd;
+	while(txd) {
+		_ltxd = ltxd;
+		ltxd = ltxd->next;
+		PORTAL_FREE(_ltxd, sizeof(gmnal_ltxd_t));
+	}
+	
+	return;
+}
+
+
+/*
+ *	Get a txd from the list
+ *	This get us a wired and gm_registered small tx buffer.
+ *	This implicitly gets us a send token also.
+ */
+gmnal_stxd_t *
+gmnal_get_stxd(gmnal_data_t *nal_data, int block)
+{
+
+	gmnal_stxd_t	*txd = NULL;
+	pid_t		pid = current->pid;
+
+
+	CDEBUG(D_TRACE, "gmnal_get_stxd nal_data [%p] block[%d] pid [%d]\n", 
+	       nal_data, block, pid);
+
+	if (gmnal_is_rxthread(nal_data)) {
+                CDEBUG(D_INFO, "RXTHREAD Attempting to get token\n");
+		GMNAL_RXT_TXD_GETTOKEN(nal_data);
+	        GMNAL_RXT_TXD_LOCK(nal_data);
+	        txd = nal_data->rxt_stxd;
+		nal_data->rxt_stxd = txd->next;
+	        GMNAL_RXT_TXD_UNLOCK(nal_data);
+	        CDEBUG(D_INFO, "RXTHREAD got [%p], head is [%p]\n", 
+		       txd, nal_data->rxt_stxd);
+                txd->kniov = 0;
+                txd->rxt = 1;
+        } else {
+	        if (block) {
+                        CDEBUG(D_INFO, "Attempting to get token\n");
+		        GMNAL_TXD_GETTOKEN(nal_data);
+                        CDEBUG(D_PORTALS, "Got token\n");
+	        } else {
+		        if (GMNAL_TXD_TRYGETTOKEN(nal_data)) {
+			        CDEBUG(D_ERROR, "can't get token\n");
+			        return(NULL);
+		        }
+	        }
+	        GMNAL_TXD_LOCK(nal_data);
+	        txd = nal_data->stxd;
+		nal_data->stxd = txd->next;
+	        GMNAL_TXD_UNLOCK(nal_data);
+	        CDEBUG(D_INFO, "got [%p], head is [%p]\n", txd, 
+		       nal_data->stxd);
+                txd->kniov = 0;
+        }       /* general txd get */
+	return(txd);
+}
+
+/*
+ *	Return a txd to the list
+ */
+void
+gmnal_return_stxd(gmnal_data_t *nal_data, gmnal_stxd_t *txd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], txd[%p] rxt[%d]\n", nal_data, 
+	       txd, txd->rxt);
+
+        /*
+         *      this transmit descriptor is 
+         *      for the rxthread
+         */
+        if (txd->rxt) {
+	        GMNAL_RXT_TXD_LOCK(nal_data);
+	        txd->next = nal_data->rxt_stxd;
+	        nal_data->rxt_stxd = txd;
+	        GMNAL_RXT_TXD_UNLOCK(nal_data);
+	        GMNAL_RXT_TXD_RETURNTOKEN(nal_data);
+                CDEBUG(D_INFO, "Returned stxd to rxthread list\n");
+        } else {
+	        GMNAL_TXD_LOCK(nal_data);
+	        txd->next = nal_data->stxd;
+	        nal_data->stxd = txd;
+	        GMNAL_TXD_UNLOCK(nal_data);
+	        GMNAL_TXD_RETURNTOKEN(nal_data);
+                CDEBUG(D_INFO, "Returned stxd to general list\n");
+        }
+	return;
+}
+
+
+/*
+ *	Get a large transmit descriptor from the free list
+ *	This implicitly gets us a transmit  token .
+ *	always wait for one.
+ */
+gmnal_ltxd_t *
+gmnal_get_ltxd(gmnal_data_t *nal_data)
+{
+
+	gmnal_ltxd_t	*ltxd = NULL;
+
+	CDEBUG(D_TRACE, "nal_data [%p]\n", nal_data);
+
+	GMNAL_LTXD_GETTOKEN(nal_data);
+	GMNAL_LTXD_LOCK(nal_data);
+	ltxd = nal_data->ltxd;
+	nal_data->ltxd = ltxd->next;
+	GMNAL_LTXD_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "got [%p], head is [%p]\n", ltxd, nal_data->ltxd);
+	return(ltxd);
+}
+
+/*
+ *	Return an ltxd to the list
+ */
+void
+gmnal_return_ltxd(gmnal_data_t *nal_data, gmnal_ltxd_t *ltxd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], ltxd[%p]\n", nal_data, ltxd);
+
+	GMNAL_LTXD_LOCK(nal_data);
+	ltxd->next = nal_data->ltxd;
+	nal_data->ltxd = ltxd;
+	GMNAL_LTXD_UNLOCK(nal_data);
+	GMNAL_LTXD_RETURNTOKEN(nal_data);
+	return;
+}
+/*
+ *	allocate a number of small rx buffers and register with GM
+ *	so they are wired and set up for DMA. This is a costly operation.
+ *	Also allocate a corrosponding descriptor to keep track of 
+ *	the buffer.
+ *	Put all descriptors on singly linked list to be available to 
+ *	receive thread.
+ */
+int
+gmnal_alloc_srxd(gmnal_data_t *nal_data)
+{
+	int nrx = 0, nsrx = 0, i = 0;
+	gmnal_srxd_t	*rxd = NULL;
+	void	*rxbuffer = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_alloc_small rx\n");
+
+	GMNAL_GM_LOCK(nal_data);
+	nrx = gm_num_receive_tokens(nal_data->gm_port);
+	GMNAL_GM_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "total number of receive tokens available is [%d]\n", 
+	       nrx);
+	
+	nsrx = nrx/2;
+	nsrx = 12;
+	/*
+	 *	make the number of rxds twice our total
+	 *	number of stxds plus 1
+	 */
+	nsrx = num_stxds*2 + 2;
+
+	CDEBUG(D_INFO, "Allocated [%d] receive tokens to small messages\n", 
+	       nsrx);
+
+
+	GMNAL_GM_LOCK(nal_data);
+	nal_data->srxd_hash = gm_create_hash(gm_hash_compare_ptrs, 
+					     gm_hash_hash_ptr, 0, 0, nsrx, 0);
+	GMNAL_GM_UNLOCK(nal_data);
+	if (!nal_data->srxd_hash) {
+			CDEBUG(D_ERROR, "Failed to create hash table\n");
+			return(GMNAL_STATUS_NOMEM);
+	}
+
+	GMNAL_RXD_TOKEN_INIT(nal_data, nsrx);
+	GMNAL_RXD_LOCK_INIT(nal_data);
+
+	for (i=0; i<=nsrx; i++) {
+		PORTAL_ALLOC(rxd, sizeof(gmnal_srxd_t));
+		if (!rxd) {
+			CDEBUG(D_ERROR, "Failed to malloc rxd [%d]\n", i);
+			return(GMNAL_STATUS_NOMEM);
+		}
+#if 0
+		PORTAL_ALLOC(rxbuffer, GMNAL_SMALL_MSG_SIZE(nal_data));
+		if (!rxbuffer) {
+			CDEBUG(D_ERROR, "Failed to malloc rxbuffer [%d], 
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(rxd, sizeof(gmnal_srxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+		CDEBUG(D_NET, "Calling gm_register_memory with port [%p] 
+		       rxbuffer [%p], size [%d]\n", nal_data->gm_port, 
+		       rxbuffer, GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_LOCK(nal_data);
+		gm_status = gm_register_memory(nal_data->gm_port, rxbuffer, 
+					       GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (gm_status != GM_SUCCESS) {
+			CDEBUG(D_ERROR, "gm_register_memory failed buffer [%p],
+			       index [%d]\n", rxbuffer, i);
+			switch(gm_status) {
+				case(GM_FAILURE):
+					CDEBUG(D_ERROR, "GM_FAILURE\n");
+				break;
+				case(GM_PERMISSION_DENIED):
+					CDEBUG(D_ERROR, "PERMISSION_DENIED\n");
+				break;
+				case(GM_INVALID_PARAMETER):
+					CDEBUG(D_ERROR, "INVALID_PARAMETER\n");
+				break;
+				default:
+					CDEBUG(D_ERROR, "Unknown error[%d]\n", 
+					       gm_status);
+				break;
+				
+			}
+			return(GMNAL_STATUS_FAIL);
+		}
+#else
+		GMNAL_GM_LOCK(nal_data);
+		rxbuffer = gm_dma_malloc(nal_data->gm_port, 
+					 GMNAL_SMALL_MSG_SIZE(nal_data));
+		GMNAL_GM_UNLOCK(nal_data);
+		if (!rxbuffer) {
+			CDEBUG(D_ERROR, "Failed to gm_dma_malloc rxbuffer [%d],
+			       size [%d]\n", i, 
+			       GMNAL_SMALL_MSG_SIZE(nal_data));
+			PORTAL_FREE(rxd, sizeof(gmnal_srxd_t));
+			return(GMNAL_STATUS_FAIL);
+		}
+#endif
+		
+		rxd->buffer = rxbuffer;
+		rxd->size = GMNAL_SMALL_MSG_SIZE(nal_data);
+		rxd->gmsize = gm_min_size_for_length(rxd->size);
+
+		if (gm_hash_insert(nal_data->srxd_hash, 
+				   (void*)rxbuffer, (void*)rxd)) {
+
+			CDEBUG(D_ERROR, "failed to create hash entry rxd[%p] 
+			       for rxbuffer[%p]\n", rxd, rxbuffer);
+			return(GMNAL_STATUS_FAIL);
+		}
+
+		rxd->next = nal_data->srxd;
+		nal_data->srxd = rxd;
+		CDEBUG(D_INFO, "Registered rxd [%p] with buffer [%p], 
+		       size [%d]\n", rxd, rxd->buffer, rxd->size);
+	}
+
+	return(GMNAL_STATUS_OK);
+}
+
+
+
+/*	Free the list of wired and gm_registered small rx buffers and the 
+ *	rx descriptors that go along with them.
+ */
+void
+gmnal_free_srxd(gmnal_data_t *nal_data)
+{
+	gmnal_srxd_t *rxd = nal_data->srxd, *_rxd = NULL;
+
+	CDEBUG(D_TRACE, "gmnal_free_small rx\n");
+
+	while(rxd) {
+		CDEBUG(D_INFO, "Freeing rxd [%p] buffer [%p], size [%d]\n",
+		       rxd, rxd->buffer, rxd->size);
+		_rxd = rxd;
+		rxd = rxd->next;
+
+#if 0
+		GMNAL_GM_LOCK(nal_data);
+		gm_deregister_memory(nal_data->gm_port, _rxd->buffer, 
+				     _rxd->size);
+		GMNAL_GM_UNLOCK(nal_data);
+		PORTAL_FREE(_rxd->buffer, GMNAL_SMALL_RXBUFFER_SIZE);
+#else
+		GMNAL_GM_LOCK(nal_data);
+		gm_dma_free(nal_data->gm_port, _rxd->buffer);
+		GMNAL_GM_UNLOCK(nal_data);
+#endif
+		PORTAL_FREE(_rxd, sizeof(gmnal_srxd_t));
+	}
+	return;
+}
+
+
+/*
+ *	Get a rxd from the free list
+ *	This get us a wired and gm_registered small rx buffer.
+ *	This implicitly gets us a receive token also.
+ */
+gmnal_srxd_t *
+gmnal_get_srxd(gmnal_data_t *nal_data, int block)
+{
+
+	gmnal_srxd_t	*rxd = NULL;
+	CDEBUG(D_TRACE, "nal_data [%p] block [%d]\n", nal_data, block);
+
+	if (block) {
+		GMNAL_RXD_GETTOKEN(nal_data);
+	} else {
+		if (GMNAL_RXD_TRYGETTOKEN(nal_data)) {
+			CDEBUG(D_INFO, "gmnal_get_srxd Can't get token\n");
+			return(NULL);
+		}
+	}
+	GMNAL_RXD_LOCK(nal_data);
+	rxd = nal_data->srxd;
+	if (rxd)
+		nal_data->srxd = rxd->next;
+	GMNAL_RXD_UNLOCK(nal_data);
+	CDEBUG(D_INFO, "got [%p], head is [%p]\n", rxd, nal_data->srxd);
+	return(rxd);
+}
+
+/*
+ *	Return an rxd to the list
+ */
+void
+gmnal_return_srxd(gmnal_data_t *nal_data, gmnal_srxd_t *rxd)
+{
+	CDEBUG(D_TRACE, "nal_data [%p], rxd[%p]\n", nal_data, rxd);
+
+	GMNAL_RXD_LOCK(nal_data);
+	rxd->next = nal_data->srxd;
+	nal_data->srxd = rxd;
+	GMNAL_RXD_UNLOCK(nal_data);
+	GMNAL_RXD_RETURNTOKEN(nal_data);
+	return;
+}
+
+/*
+ *	Given a pointer to a srxd find 
+ *	the relevant descriptor for it
+ *	This is done by searching a hash
+ *	list that is created when the srxd's 
+ *	are created
+ */
+gmnal_srxd_t *
+gmnal_rxbuffer_to_srxd(gmnal_data_t *nal_data, void *rxbuffer)
+{
+	gmnal_srxd_t	*srxd = NULL;
+	CDEBUG(D_TRACE, "nal_data [%p], rxbuffer [%p]\n", nal_data, rxbuffer);
+	srxd = gm_hash_find(nal_data->srxd_hash, rxbuffer);
+	CDEBUG(D_INFO, "srxd is [%p]\n", srxd);
+	return(srxd);
+}
+
+
+void
+gmnal_stop_rxthread(gmnal_data_t *nal_data)
+{
+	int 	delay = 30;
+
+
+
+	CDEBUG(D_TRACE, "Attempting to stop rxthread nal_data [%p]\n", 
+	        nal_data);
+	
+	nal_data->rxthread_stop_flag = GMNAL_THREAD_STOP;
+
+	gmnal_remove_rxtwe(nal_data);
+	/*
+	 *	kick the thread 
+	 */
+	up(&nal_data->rxtwe_wait);
+
+	while(nal_data->rxthread_flag != GMNAL_THREAD_RESET && delay--) {
+		CDEBUG(D_INFO, "gmnal_stop_rxthread sleeping\n");
+                gmnal_yield(1);
+		up(&nal_data->rxtwe_wait);
+	}
+
+	if (nal_data->rxthread_flag != GMNAL_THREAD_RESET) {
+		CDEBUG(D_ERROR, "I don't know how to wake the thread\n");
+	} else {
+		CDEBUG(D_INFO, "rx thread seems to have stopped\n");
+	}
+}
+
+void
+gmnal_stop_ctthread(gmnal_data_t *nal_data)
+{
+	int 	delay = 15;
+
+
+
+	CDEBUG(D_TRACE, "Attempting to stop ctthread nal_data [%p]\n", 
+	       nal_data);
+	
+	nal_data->ctthread_flag = GMNAL_THREAD_STOP;
+	GMNAL_GM_LOCK(nal_data);
+	gm_set_alarm(nal_data->gm_port, &nal_data->ctthread_alarm, 10, 
+		     NULL, NULL);
+	GMNAL_GM_UNLOCK(nal_data);
+
+	while(nal_data->ctthread_flag == GMNAL_THREAD_STOP && delay--) {
+		CDEBUG(D_INFO, "gmnal_stop_ctthread sleeping\n");
+                gmnal_yield(1);
+	}
+
+	if (nal_data->ctthread_flag == GMNAL_THREAD_STOP) {
+		CDEBUG(D_ERROR, "I DON'T KNOW HOW TO WAKE THE THREAD\n");
+	} else {
+		CDEBUG(D_INFO, "CT THREAD SEEMS TO HAVE STOPPED\n");
+	}
+}
+
+
+
+char * 
+gmnal_gm_error(gm_status_t status)
+{
+	switch(status) {
+		case(GM_SUCCESS):
+			return("SUCCESS");
+  		case(GM_FAILURE):
+			return("FAILURE");
+  		case(GM_INPUT_BUFFER_TOO_SMALL):
+			return("INPUT_BUFFER_TOO_SMALL");
+  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
+			return("OUTPUT_BUFFER_TOO_SMALL");
+  		case(GM_TRY_AGAIN ):
+			return("TRY_AGAIN");
+  		case(GM_BUSY):
+			return("BUSY");
+  		case(GM_MEMORY_FAULT):
+			return("MEMORY_FAULT");
+  		case(GM_INTERRUPTED):
+			return("INTERRUPTED");
+  		case(GM_INVALID_PARAMETER):
+			return("INVALID_PARAMETER");
+  		case(GM_OUT_OF_MEMORY):
+			return("OUT_OF_MEMORY");
+  		case(GM_INVALID_COMMAND):
+			return("INVALID_COMMAND");
+  		case(GM_PERMISSION_DENIED):
+			return("PERMISSION_DENIED");
+  		case(GM_INTERNAL_ERROR):
+			return("INTERNAL_ERROR");
+  		case(GM_UNATTACHED):
+			return("UNATTACHED");
+  		case(GM_UNSUPPORTED_DEVICE):
+			return("UNSUPPORTED_DEVICE");
+  		case(GM_SEND_TIMED_OUT):
+			return("GM_SEND_TIMEDOUT");
+  		case(GM_SEND_REJECTED):
+			return("GM_SEND_REJECTED");
+  		case(GM_SEND_TARGET_PORT_CLOSED):
+			return("GM_SEND_TARGET_PORT_CLOSED");
+  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
+			return("GM_SEND_TARGET_NODE_UNREACHABLE");
+  		case(GM_SEND_DROPPED):
+			return("GM_SEND_DROPPED");
+  		case(GM_SEND_PORT_CLOSED):
+			return("GM_SEND_PORT_CLOSED");
+  		case(GM_NODE_ID_NOT_YET_SET):
+			return("GM_NODE_ID_NOT_YET_SET");
+  		case(GM_STILL_SHUTTING_DOWN):
+			return("GM_STILL_SHUTTING_DOWN");
+  		case(GM_CLONE_BUSY):
+			return("GM_CLONE_BUSY");
+  		case(GM_NO_SUCH_DEVICE):
+			return("GM_NO_SUCH_DEVICE");
+  		case(GM_ABORTED):
+			return("GM_ABORTED");
+  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
+			return("GM_INCOMPATIBLE_LIB_AND_DRIVER");
+  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
+			return("GM_UNTRANSLATED_SYSTEM_ERROR");
+  		case(GM_ACCESS_DENIED):
+			return("GM_ACCESS_DENIED");
+
+
+/*
+ *	These ones are in the docs but aren't in the header file 
+  		case(GM_DEV_NOT_FOUND):
+			return("GM_DEV_NOT_FOUND");
+  		case(GM_INVALID_PORT_NUMBER):
+			return("GM_INVALID_PORT_NUMBER");
+  		case(GM_UC_ERROR):
+			return("GM_US_ERROR");
+  		case(GM_PAGE_TABLE_FULL):
+			return("GM_PAGE_TABLE_FULL");
+  		case(GM_MINOR_OVERFLOW):
+			return("GM_MINOR_OVERFLOW");
+  		case(GM_SEND_ORPHANED):
+			return("GM_SEND_ORPHANED");
+  		case(GM_HARDWARE_FAULT):
+			return("GM_HARDWARE_FAULT");
+  		case(GM_DATA_CORRUPTED):
+			return("GM_DATA_CORRUPTED");
+  		case(GM_TIMED_OUT):
+			return("GM_TIMED_OUT");
+  		case(GM_USER_ERROR):
+			return("GM_USER_ERROR");
+  		case(GM_NO_MATCH):
+			return("GM_NOMATCH");
+  		case(GM_NOT_SUPPORTED_IN_KERNEL):
+			return("GM_NOT_SUPPORTED_IN_KERNEL");
+  		case(GM_NOT_SUPPORTED_ON_ARCH):
+			return("GM_NOT_SUPPORTED_ON_ARCH");
+  		case(GM_PTE_REF_CNT_OVERFLOW):
+			return("GM_PTR_REF_CNT_OVERFLOW");
+  		case(GM_NO_DRIVER_SUPPORT):
+			return("GM_NO_DRIVER_SUPPORT");
+  		case(GM_FIRMWARE_NOT_RUNNING):
+			return("GM_FIRMWARE_NOT_RUNNING");
+
+ *	These ones are in the docs but aren't in the header file 
+ */
+		default:
+			return("UNKNOWN GM ERROR CODE");
+	}
+}
+
+
+char *
+gmnal_rxevent(gm_recv_event_t	*ev)
+{
+	short	event;
+	event = GM_RECV_EVENT_TYPE(ev);
+	switch(event) {
+  		case(GM_NO_RECV_EVENT):
+			return("GM_NO_RECV_EVENT");
+  		case(GM_SENDS_FAILED_EVENT):
+			return("GM_SEND_FAILED_EVENT");
+  		case(GM_ALARM_EVENT):
+			return("GM_ALARM_EVENT");
+  		case(GM_SENT_EVENT):
+			return("GM_SENT_EVENT");
+  		case(_GM_SLEEP_EVENT):
+			return("_GM_SLEEP_EVENT");
+  		case(GM_RAW_RECV_EVENT):
+			return("GM_RAW_RECV_EVENT");
+  		case(GM_BAD_SEND_DETECTED_EVENT):
+			return("GM_BAD_SEND_DETECTED_EVENT");
+  		case(GM_SEND_TOKEN_VIOLATION_EVENT):
+			return("GM_SEND_TOKEN_VIOLATION_EVENT");
+  		case(GM_RECV_TOKEN_VIOLATION_EVENT):
+			return("GM_RECV_TOKEN_VIOLATION_EVENT");
+  		case(GM_BAD_RECV_TOKEN_EVENT):
+			return("GM_BAD_RECV_TOKEN_EVENT");
+  		case(GM_ALARM_VIOLATION_EVENT):
+			return("GM_ALARM_VIOLATION_EVENT");
+  		case(GM_RECV_EVENT):
+			return("GM_RECV_EVENT");
+  		case(GM_HIGH_RECV_EVENT):
+			return("GM_HIGH_RECV_EVENT");
+  		case(GM_PEER_RECV_EVENT):
+			return("GM_PEER_RECV_EVENT");
+  		case(GM_HIGH_PEER_RECV_EVENT):
+			return("GM_HIGH_PEER_RECV_EVENT");
+  		case(GM_FAST_RECV_EVENT):
+			return("GM_FAST_RECV_EVENT");
+  		case(GM_FAST_HIGH_RECV_EVENT):
+			return("GM_FAST_HIGH_RECV_EVENT");
+  		case(GM_FAST_PEER_RECV_EVENT):
+			return("GM_FAST_PEER_RECV_EVENT");
+  		case(GM_FAST_HIGH_PEER_RECV_EVENT):
+			return("GM_FAST_HIGH_PEER_RECV_EVENT");
+  		case(GM_REJECTED_SEND_EVENT):
+			return("GM_REJECTED_SEND_EVENT");
+  		case(GM_ORPHANED_SEND_EVENT):
+			return("GM_ORPHANED_SEND_EVENT");
+  		case(GM_BAD_RESEND_DETECTED_EVENT):
+			return("GM_BAD_RESEND_DETETED_EVENT");
+  		case(GM_DROPPED_SEND_EVENT):
+			return("GM_DROPPED_SEND_EVENT");
+  		case(GM_BAD_SEND_VMA_EVENT):
+			return("GM_BAD_SEND_VMA_EVENT");
+  		case(GM_BAD_RECV_VMA_EVENT):
+			return("GM_BAD_RECV_VMA_EVENT");
+  		case(_GM_FLUSHED_ALARM_EVENT):
+			return("GM_FLUSHED_ALARM_EVENT");
+  		case(GM_SENT_TOKENS_EVENT):
+			return("GM_SENT_TOKENS_EVENTS");
+  		case(GM_IGNORE_RECV_EVENT):
+			return("GM_IGNORE_RECV_EVENT");
+  		case(GM_ETHERNET_RECV_EVENT):
+			return("GM_ETHERNET_RECV_EVENT");
+  		case(GM_NEW_NO_RECV_EVENT):
+			return("GM_NEW_NO_RECV_EVENT");
+  		case(GM_NEW_SENDS_FAILED_EVENT):
+			return("GM_NEW_SENDS_FAILED_EVENT");
+  		case(GM_NEW_ALARM_EVENT):
+			return("GM_NEW_ALARM_EVENT");
+  		case(GM_NEW_SENT_EVENT):
+			return("GM_NEW_SENT_EVENT");
+  		case(_GM_NEW_SLEEP_EVENT):
+			return("GM_NEW_SLEEP_EVENT");
+  		case(GM_NEW_RAW_RECV_EVENT):
+			return("GM_NEW_RAW_RECV_EVENT");
+  		case(GM_NEW_BAD_SEND_DETECTED_EVENT):
+			return("GM_NEW_BAD_SEND_DETECTED_EVENT");
+  		case(GM_NEW_SEND_TOKEN_VIOLATION_EVENT):
+			return("GM_NEW_SEND_TOKEN_VIOLATION_EVENT");
+  		case(GM_NEW_RECV_TOKEN_VIOLATION_EVENT):
+			return("GM_NEW_RECV_TOKEN_VIOLATION_EVENT");
+  		case(GM_NEW_BAD_RECV_TOKEN_EVENT):
+			return("GM_NEW_BAD_RECV_TOKEN_EVENT");
+  		case(GM_NEW_ALARM_VIOLATION_EVENT):
+			return("GM_NEW_ALARM_VIOLATION_EVENT");
+  		case(GM_NEW_RECV_EVENT):
+			return("GM_NEW_RECV_EVENT");
+  		case(GM_NEW_HIGH_RECV_EVENT):
+			return("GM_NEW_HIGH_RECV_EVENT");
+  		case(GM_NEW_PEER_RECV_EVENT):
+			return("GM_NEW_PEER_RECV_EVENT");
+  		case(GM_NEW_HIGH_PEER_RECV_EVENT):
+			return("GM_NEW_HIGH_PEER_RECV_EVENT");
+  		case(GM_NEW_FAST_RECV_EVENT):
+			return("GM_NEW_FAST_RECV_EVENT");
+  		case(GM_NEW_FAST_HIGH_RECV_EVENT):
+			return("GM_NEW_FAST_HIGH_RECV_EVENT");
+  		case(GM_NEW_FAST_PEER_RECV_EVENT):
+			return("GM_NEW_FAST_PEER_RECV_EVENT");
+  		case(GM_NEW_FAST_HIGH_PEER_RECV_EVENT):
+			return("GM_NEW_FAST_HIGH_PEER_RECV_EVENT");
+  		case(GM_NEW_REJECTED_SEND_EVENT):
+			return("GM_NEW_REJECTED_SEND_EVENT");
+  		case(GM_NEW_ORPHANED_SEND_EVENT):
+			return("GM_NEW_ORPHANED_SEND_EVENT");
+  		case(_GM_NEW_PUT_NOTIFICATION_EVENT):
+			return("_GM_NEW_PUT_NOTIFICATION_EVENT");
+  		case(GM_NEW_FREE_SEND_TOKEN_EVENT):
+			return("GM_NEW_FREE_SEND_TOKEN_EVENT");
+  		case(GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT):
+			return("GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT");
+  		case(GM_NEW_BAD_RESEND_DETECTED_EVENT):
+			return("GM_NEW_BAD_RESEND_DETECTED_EVENT");
+  		case(GM_NEW_DROPPED_SEND_EVENT):
+			return("GM_NEW_DROPPED_SEND_EVENT");
+  		case(GM_NEW_BAD_SEND_VMA_EVENT):
+			return("GM_NEW_BAD_SEND_VMA_EVENT");
+  		case(GM_NEW_BAD_RECV_VMA_EVENT):
+			return("GM_NEW_BAD_RECV_VMA_EVENT");
+  		case(_GM_NEW_FLUSHED_ALARM_EVENT):
+			return("GM_NEW_FLUSHED_ALARM_EVENT");
+  		case(GM_NEW_SENT_TOKENS_EVENT):
+			return("GM_NEW_SENT_TOKENS_EVENT");
+  		case(GM_NEW_IGNORE_RECV_EVENT):
+			return("GM_NEW_IGNORE_RECV_EVENT");
+  		case(GM_NEW_ETHERNET_RECV_EVENT):
+			return("GM_NEW_ETHERNET_RECV_EVENT");
+		default:
+			return("Unknown Recv event");
+#if 0
+  		case(/* _GM_PUT_NOTIFICATION_EVENT */
+  		case(/* GM_FREE_SEND_TOKEN_EVENT */
+  		case(/* GM_FREE_HIGH_SEND_TOKEN_EVENT */
+#endif
+	}
+}
+
+
+void
+gmnal_yield(int delay)
+{
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(delay);
+}
+
+int
+gmnal_is_small_msg(gmnal_data_t *nal_data, int niov, struct iovec *iov, 
+		    int len)
+{
+
+	CDEBUG(D_TRACE, "len [%d] limit[%d]\n", len, 
+	       GMNAL_SMALL_MSG_SIZE(nal_data));
+
+	if ((len + sizeof(ptl_hdr_t) + sizeof(gmnal_msghdr_t)) 
+	             < GMNAL_SMALL_MSG_SIZE(nal_data)) {
+
+		CDEBUG(D_INFO, "Yep, small message\n");
+		return(1);
+	} else {
+		CDEBUG(D_ERROR, "No, not small message\n");
+		/*
+		 *	could be made up of lots of little ones !
+		 */
+		return(0);
+	}
+
+}
+
+/* 
+ *	extract info from the receive event.
+ *	Have to do this before the next call to gm_receive
+ *	Deal with all endian stuff here.
+ *	Then stick work entry on list where rxthreads
+ *	can get it to complete the receive
+ */
+int
+gmnal_add_rxtwe(gmnal_data_t *nal_data, gm_recv_t *recv)
+{
+	gmnal_rxtwe_t	*we = NULL;
+
+	CDEBUG(D_NET, "adding entry to list\n");
+
+	PORTAL_ALLOC(we, sizeof(gmnal_rxtwe_t));
+	if (!we) {
+		CDEBUG(D_ERROR, "failed to malloc\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+	we->buffer = gm_ntohp(recv->buffer);
+	we->snode = (int)gm_ntoh_u16(recv->sender_node_id);
+	we->sport = (int)gm_ntoh_u8(recv->sender_port_id);
+	we->type = (int)gm_ntoh_u8(recv->type);
+	we->length = (int)gm_ntohl(recv->length);
+
+	spin_lock(&nal_data->rxtwe_lock);
+	if (nal_data->rxtwe_tail) {
+		nal_data->rxtwe_tail->next = we;
+	} else {
+		nal_data->rxtwe_head = we;
+		nal_data->rxtwe_tail = we;
+	}
+	nal_data->rxtwe_tail = we;
+	spin_unlock(&nal_data->rxtwe_lock);
+
+	up(&nal_data->rxtwe_wait);
+	return(GMNAL_STATUS_OK);
+}
+
+void
+gmnal_remove_rxtwe(gmnal_data_t *nal_data)
+{
+	gmnal_rxtwe_t	*_we, *we = nal_data->rxtwe_head;
+
+	CDEBUG(D_NET, "removing all work list entries\n");
+
+	spin_lock(&nal_data->rxtwe_lock);
+	CDEBUG(D_NET, "Got lock\n");
+	while (we) {
+		_we = we;
+		we = we->next;
+		PORTAL_FREE(_we, sizeof(gmnal_rxtwe_t));
+	}
+	spin_unlock(&nal_data->rxtwe_lock);
+	nal_data->rxtwe_head = NULL;
+	nal_data->rxtwe_tail = NULL;
+}
+
+gmnal_rxtwe_t *
+gmnal_get_rxtwe(gmnal_data_t *nal_data)
+{
+	gmnal_rxtwe_t	*we = NULL;
+
+	CDEBUG(D_NET, "Getting entry to list\n");
+
+	do  {
+		down(&nal_data->rxtwe_wait);
+		if (nal_data->rxthread_stop_flag == GMNAL_THREAD_STOP) {
+			/*
+			 *	time to stop
+			 * 	TO DO some one free the work entries	
+			 */
+			return(NULL);
+		}
+		spin_lock(&nal_data->rxtwe_lock);
+		if (nal_data->rxtwe_head) {
+			CDEBUG(D_WARNING, "Got a work entry\n");
+			we = nal_data->rxtwe_head;
+			nal_data->rxtwe_head = we->next;
+			if (!nal_data->rxtwe_head)
+				nal_data->rxtwe_tail = NULL;
+		} else {
+			CDEBUG(D_WARNING, "woken but no work\n");
+		}
+		spin_unlock(&nal_data->rxtwe_lock);
+	} while (!we);
+
+	CDEBUG(D_WARNING, "Returning we[%p]\n", we);
+	return(we);
+}
+
+
+/*
+ *	Start the caretaker thread and a number of receiver threads
+ *	The caretaker thread gets events from the gm library.
+ *	It passes receive events to the receiver threads via a work list.
+ *	It processes other events itself in gm_unknown. These will be
+ *	callback events or sleeps.
+ */
+int
+gmnal_start_kernel_threads(gmnal_data_t *nal_data)
+{
+
+	int	threads = 0;
+	/*
+ 	 *	the alarm is used to wake the caretaker thread from 
+	 *	gm_unknown call (sleeping) to exit it.
+	 */
+	CDEBUG(D_NET, "Initializing caretaker thread alarm and flag\n");
+	gm_initialize_alarm(&nal_data->ctthread_alarm);
+	nal_data->ctthread_flag = GMNAL_THREAD_RESET;
+
+
+	CDEBUG(D_INFO, "Starting caretaker thread\n");
+	nal_data->ctthread_pid = 
+	         kernel_thread(gmnal_ct_thread, (void*)nal_data, 0);
+	if (nal_data->ctthread_pid <= 0) {
+		CDEBUG(D_ERROR, "Caretaker thread failed to start\n");
+		return(GMNAL_STATUS_FAIL);
+	}
+
+	while (nal_data->rxthread_flag != GMNAL_THREAD_RESET) {
+		gmnal_yield(1);
+		CDEBUG(D_INFO, "Waiting for caretaker thread signs of life\n");
+	}
+
+	CDEBUG(D_INFO, "caretaker thread has started\n");
+
+
+	/*
+ 	 *	Now start a number of receiver threads
+	 *	these treads get work to do from the caretaker (ct) thread
+	 */
+	nal_data->rxthread_flag = GMNAL_THREAD_RESET;
+	nal_data->rxthread_stop_flag = GMNAL_THREAD_RESET;
+
+	for (threads=0; threads<NRXTHREADS; threads++)
+		nal_data->rxthread_pid[threads] = -1;
+	spin_lock_init(&nal_data->rxtwe_lock);
+	spin_lock_init(&nal_data->rxthread_flag_lock);
+	sema_init(&nal_data->rxtwe_wait, 0);
+	nal_data->rxtwe_head = NULL;
+	nal_data->rxtwe_tail = NULL;
+        /*
+         *      If the default number of receive threades isn't
+         *      modified at load time, then start one thread per cpu
+         */
+        if (num_rx_threads == -1)
+                num_rx_threads = smp_num_cpus;
+	CDEBUG(D_INFO, "Starting [%d] receive threads\n", num_rx_threads);
+	for (threads=0; threads<num_rx_threads; threads++) {
+		nal_data->rxthread_pid[threads] = 
+		       kernel_thread(gmnal_rx_thread, (void*)nal_data, 0);
+		if (nal_data->rxthread_pid[threads] <= 0) {
+			CDEBUG(D_ERROR, "Receive thread failed to start\n");
+			gmnal_stop_rxthread(nal_data);
+			gmnal_stop_ctthread(nal_data);
+			return(GMNAL_STATUS_FAIL);
+		}
+	}
+
+	for (;;) {
+		spin_lock(&nal_data->rxthread_flag_lock);
+		if (nal_data->rxthread_flag == GMNAL_RXTHREADS_STARTED) {
+			spin_unlock(&nal_data->rxthread_flag_lock);
+			break;
+		}
+		spin_unlock(&nal_data->rxthread_flag_lock);
+		gmnal_yield(1);
+	}
+
+	CDEBUG(D_INFO, "receive threads seem to have started\n");
+
+	return(GMNAL_STATUS_OK);
+}
diff --git a/lustre/portals/knals/ibnal/.cvsignore b/lustre/portals/knals/ibnal/.cvsignore
new file mode 100644
index 0000000000000000000000000000000000000000..e9955884756af11fe171e89bf99e459ac44f1a2a
--- /dev/null
+++ b/lustre/portals/knals/ibnal/.cvsignore
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in
diff --git a/lustre/portals/knals/ibnal/Makefile.am b/lustre/portals/knals/ibnal/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..84818dc115cdadc8c42e7c6f4a8d042f7fedf482
--- /dev/null
+++ b/lustre/portals/knals/ibnal/Makefile.am
@@ -0,0 +1,10 @@
+include ../../Rules.linux
+
+MODULE = kibnal
+modulenet_DATA = kibnal.o
+EXTRA_PROGRAMS = kibnal
+
+
+DEFS =
+CPPFLAGS=@CPPFLAGS@ @with_ib@
+kibnal_SOURCES = ibnal.h ibnal.c ibnal_cb.c
diff --git a/lustre/portals/knals/ibnal/ibnal.c b/lustre/portals/knals/ibnal/ibnal.c
new file mode 100644
index 0000000000000000000000000000000000000000..948badf0213a5d90ac81549e01baa5fc18f553b4
--- /dev/null
+++ b/lustre/portals/knals/ibnal/ibnal.c
@@ -0,0 +1,2146 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Based on ksocknal, qswnal, and gmnal
+ *
+ * Copyright (C) 2003 LANL 
+ *   Author: HB Chen <hbchen@lanl.gov>
+ *   Los Alamos National Lab
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals 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 Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *   
+ */
+
+#include "ibnal.h"
+
+// portal handle ID for this IB-NAL
+ptl_handle_ni_t kibnal_ni;
+
+// message send buffer mutex
+spinlock_t   MSBuf_mutex[NUM_MBUF];
+
+// message recv buffer mutex
+spinlock_t   MRBuf_mutex[NUM_MBUF];
+
+// IB-NAL API information 
+nal_t  kibnal_api; 
+
+// nal's private data 
+kibnal_data_t kibnal_data; 
+
+int ibnal_debug = 0;
+VAPI_pd_hndl_t      Pd_hndl;    
+unsigned int    Num_posted_recv_buf;
+
+// registered send buffer list
+Memory_buffer_info MSbuf_list[NUM_MBUF]; 
+
+// registered recv buffer list 
+Memory_buffer_info MRbuf_list[NUM_MBUF];
+
+//
+// for router 
+// currently there is no need fo IBA  
+//
+kpr_nal_interface_t kibnal_router_interface = {
+        kprni_nalid: IBNAL,
+        kprni_arg:   &kibnal_data,
+        kprni_fwd:   kibnal_fwd_packet, // forward data to router  
+                                        // is router invloving the
+                                        // data transmision 
+};
+
+
+// Queue-pair list 
+QP_info QP_list[NUM_QPS];
+
+// information associated with a HCA 
+HCA_info        Hca_data;
+
+// something about HCA 
+VAPI_hca_hndl_t      Hca_hndl; // assume we only use one HCA now 
+VAPI_hca_vendor_t    Hca_vendor;
+VAPI_hca_cap_t       Hca_cap;
+VAPI_hca_port_t      Hca_port_1_props;
+VAPI_hca_port_t      Hca_port_2_props;
+VAPI_hca_attr_t      Hca_attr;
+VAPI_hca_attr_mask_t Hca_attr_mask;
+VAPI_cq_hndl_t       Cq_RQ_hndl;    // CQ's handle
+VAPI_cq_hndl_t       Cq_SQ_hndl;    // CQ's handle
+VAPI_cq_hndl_t       Cq_hndl;    // CQ's handle
+Remote_QP_Info       L_QP_data;
+Remote_QP_Info       R_QP_data;
+
+
+//
+// forward  API
+//
+int 
+kibnal_forward(nal_t   *nal,
+               int     id,
+               void    *args,  
+               size_t args_len,
+               void    *ret,   
+               size_t ret_len)
+{
+        kibnal_data_t *knal_data = nal->nal_data;
+        nal_cb_t      *nal_cb = knal_data->kib_cb;
+
+        // ASSERT checking 
+        LASSERT (nal == &kibnal_api);
+        LASSERT (knal_data == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // dispatch forward API function 
+        
+        CDEBUG(D_NET,"kibnal_forward: function id = %d\n", id);
+
+        lib_dispatch(nal_cb, knal_data, id, args, ret); 
+
+        CDEBUG(D_TRACE,"IBNAL- Done kibnal_forward\n");
+
+        return PTL_OK; // always return PTL_OK
+}
+
+//
+// lock API  
+//
+void 
+kibnal_lock(nal_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *knal_data = nal->nal_data;
+        nal_cb_t      *nal_cb = knal_data->kib_cb;
+
+        // ASSERT checking 
+        LASSERT (nal == &kibnal_api);
+        LASSERT (knal_data == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // disable logical interrrupt 
+        nal_cb->cb_cli(nal_cb,flags);
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_lock\n");
+
+}
+
+//
+// unlock API
+//
+void 
+kibnal_unlock(nal_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+
+        // ASSERT checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // enable logical interrupt 
+        nal_cb->cb_sti(nal_cb,flags);
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_unlock");
+
+}
+
+//
+// shutdown API 
+//     showdown this network interface 
+//
+int
+kibnal_shutdown(nal_t *nal, int ni)
+{       
+        VAPI_ret_t          vstat;
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+
+        // assert checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // take down this IB network interface 
+        // there is not corresponding cb function to hande this
+        // do we actually need this one 
+        // reference to IB network interface shutdown 
+        //
+        
+        vstat = IB_Close_HCA();
+
+        if (vstat != VAPI_OK) {
+           CERROR("Failed to close HCA  - %s\n",VAPI_strerror(vstat));
+           return (~PTL_OK);
+        }
+
+        CDEBUG(D_TRACE,"IBNAL- Done kibnal_shutdown\n");
+
+        return PTL_OK;
+}
+
+//
+// yield 
+// when do we call this yield function 
+//
+void 
+kibnal_yield( nal_t *nal )
+{
+        kibnal_data_t *k = nal->nal_data;
+        nal_cb_t      *nal_cb = k->kib_cb;
+        
+        // assert checking
+        LASSERT (nal == &kibnal_api);
+        LASSERT (k    == &kibnal_data);
+        LASSERT (nal_cb == &kibnal_lib);
+
+        // check under what condition that we need to 
+        // call schedule()
+        // who set this need_resched 
+        if (current->need_resched)
+                schedule();
+
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_yield");
+
+        return;
+}
+
+//
+// ibnal init 
+//
+nal_t *
+kibnal_init(int             interface, // no use here 
+            ptl_pt_index_t  ptl_size,
+            ptl_ac_index_t  ac_size, 
+            ptl_pid_t       requested_pid // no use here
+           )
+{
+  nal_t         *nal       = NULL;
+  nal_cb_t      *nal_cb    = NULL;
+  kibnal_data_t *nal_data  = NULL;
+  int            rc;
+
+  unsigned int nnids = 1; // number of nids 
+                          // do we know how many nodes are in this
+                          // system related to this kib_nid  
+                          //
+
+  CDEBUG(D_NET, "kibnal_init:calling lib_init with nid 0x%u\n",
+                  kibnal_data.kib_nid);
+
+
+  CDEBUG(D_NET, "kibnal_init: interface [%d], ptl_size [%d], ac_size[%d]\n", 
+                 interface, ptl_size, ac_size);
+  CDEBUG(D_NET, "kibnal_init: &kibnal_lib  0x%X\n", &kibnal_lib);
+  CDEBUG(D_NET, "kibnal_init: kibnal_data.kib_nid  %d\n", kibnal_data.kib_nid);
+
+  rc = lib_init(&kibnal_lib, 
+                kibnal_data.kib_nid, 
+                0, // process id is set as 0  
+                nnids,
+                ptl_size, 
+                ac_size);
+
+  if(rc != PTL_OK) {
+     CERROR("kibnal_init: Failed lib_init with nid 0x%u, rc=%d\n",
+                                  kibnal_data.kib_nid,rc);
+  }
+  else {
+      CDEBUG(D_NET,"kibnal_init: DONE lib_init with nid 0x%x%x\n",
+                                  kibnal_data.kib_nid);
+  }
+
+  return &kibnal_api;
+
+}
+
+
+//
+// called before remove ibnal kernel module 
+//
+void __exit 
+kibnal_finalize(void) 
+{ 
+        struct list_head *tmp;
+
+        inter_module_unregister("kibnal_ni");
+
+        // release resources allocated to this Infiniband network interface 
+        PtlNIFini(kibnal_ni); 
+
+        lib_fini(&kibnal_lib); 
+
+        IB_Close_HCA();
+
+        // how much do we need to do here?
+        list_for_each(tmp, &kibnal_data.kib_list) {
+                kibnal_rx_t *conn;
+                conn = list_entry(tmp, kibnal_rx_t, krx_item);
+                CDEBUG(D_IOCTL, "freeing conn %p\n",conn);
+                tmp = tmp->next;
+                list_del(&conn->krx_item);
+                PORTAL_FREE(conn, sizeof(*conn));
+        }
+
+        CDEBUG(D_MALLOC,"done kmem %d\n",atomic_read(&portal_kmemory));
+        CDEBUG(D_TRACE,"IBNAL-Done kibnal_finalize\n");
+
+        return;
+}
+
+
+//
+// * k_server_thread is a kernel thread 
+//   use a shared memory ro exchange HCA's data with a pthread in user 
+//   address space
+// * will be replaced when CM is used to handle communication management 
+//
+
+void k_server_thread(Remote_QP_Info *hca_data)
+{
+  int              segment_id;
+  const int        shared_segment_size = sizeof(Remote_QP_Info); 
+  key_t            key = HCA_EXCHANGE_SHM_KEY;
+  unsigned long    raddr;
+  int exchanged_done = NO;
+  int i;
+
+  Remote_QP_Info  *exchange_hca_data;
+
+  long *n;
+  long *uaddr;
+  long ret = 0;
+ 
+  // create a shared memory with pre-agreement key
+  segment_id =  sys_shmget(key,
+                           shared_segment_size,
+                           IPC_CREAT | 0666);
+
+
+  // attached to shared memoru 
+  // raddr is pointed to an user address space 
+  // use this address to update shared menory content 
+  ret = sys_shmat(segment_id, 0 , SHM_RND, &raddr);
+
+#ifdef IBNAL_DEBUG 
+  if(ret >= 0) {
+    CDEBUG(D_NET,"k_server_thread: Shared memory attach success ret = 0X%d,&raddr"
+                   " 0X%x (*(&raddr))=0x%x \n", ret, &raddr,  (*(&raddr)));
+    printk("k_server_thread: Shared memory attach success ret = 0X%d, &raddr"
+                   " 0X%x (*(&raddr))=0x%x \n", ret, &raddr,  (*(&raddr)));
+  }
+  else {
+    CERROR("k_server_thread: Shared memory attach failed ret = 0x%d \n", ret); 
+    printk("k_server_thread: Shared memory attach failed ret = 0x%d \n", ret); 
+    return;
+  }
+#endif
+
+  n = &raddr;
+  uaddr = *n; // get the U-address 
+  /* cast uaddr to exchange_hca_data */
+  exchange_hca_data = (Remote_QP_Info  *) uaddr; 
+  
+  /* copy data from local HCA to shared memory */
+  exchange_hca_data->opcode  = hca_data->opcode;
+  exchange_hca_data->length  = hca_data->length;
+
+  for(i=0; i < NUM_QPS; i++) {
+    exchange_hca_data->dlid[i]    = hca_data->dlid[i];
+    exchange_hca_data->rqp_num[i] = hca_data->rqp_num[i];
+  }
+
+  // periodically check shared memory until get updated 
+  // remote HCA's data from user mode pthread  
+  while(exchanged_done == NO) {
+    if(exchange_hca_data->opcode == RECV_QP_INFO){
+       exchanged_done = YES;
+       /* copy data to local buffer from shared memory */
+       hca_data->opcode  = exchange_hca_data->opcode;
+       hca_data->length  = exchange_hca_data->length;
+
+       for(i=0; i < NUM_QPS; i++) {
+         hca_data->dlid[i]    = exchange_hca_data->dlid[i];
+         hca_data->rqp_num[i] = exchange_hca_data->rqp_num[i];
+       }
+       break;
+    }
+    else { 
+       schedule_timeout(1000);
+    }
+  }
+  
+  // detached shared memory 
+  sys_shmdt(uaddr);
+
+  CDEBUG(D_NET, "Exit from kernel thread: k_server_thread \n");
+  printk("Exit from kernel thread: k_server_thread \n");
+
+  return;
+
+}
+
+//
+// create QP 
+// 
+VAPI_ret_t 
+create_qp(QP_info *qp, int qp_index)
+{
+
+  VAPI_ret_t          vstat;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_prop_t      qp_prop;
+
+  qp->hca_hndl = Hca_hndl;
+  qp->port     = 1; // default 
+  qp->slid     = Hca_port_1_props.lid;
+  qp->hca_port = Hca_port_1_props;
+
+
+  /* Queue Pair Creation Attributes */
+  qp_init_attr.cap.max_oust_wr_rq = NUM_WQE;
+  qp_init_attr.cap.max_oust_wr_sq = NUM_WQE;
+  qp_init_attr.cap.max_sg_size_rq = NUM_SG;
+  qp_init_attr.cap.max_sg_size_sq = NUM_SG;
+  qp_init_attr.pd_hndl            = qp->pd_hndl;
+  qp_init_attr.rdd_hndl           = 0;
+  qp_init_attr.rq_cq_hndl         = qp->rq_cq_hndl;
+  /* we use here polling */
+  //qp_init_attr.rq_sig_type        = VAPI_SIGNAL_REQ_WR;
+  qp_init_attr.rq_sig_type        = VAPI_SIGNAL_ALL_WR;
+  qp_init_attr.sq_cq_hndl         = qp->sq_cq_hndl;
+  /* we use here polling */
+  //qp_init_attr.sq_sig_type        = VAPI_SIGNAL_REQ_WR;
+  qp_init_attr.sq_sig_type        = VAPI_SIGNAL_ALL_WR;
+  // transport servce - reliable connection
+
+  qp_init_attr.ts_type            = VAPI_TS_RC;
+          
+  vstat = VAPI_create_qp(qp->hca_hndl,   
+                         &qp_init_attr,      
+                         &qp->qp_hndl, &qp_prop); 
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed creating QP. Return Failed - %s\n",VAPI_strerror(vstat));
+     return vstat;
+  }
+  
+  qp->qp_num = qp_prop.qp_num; // the qp number 
+  qp->last_posted_send_id  = 0; // user defined work request ID
+  qp->last_posted_rcv_id   = 0; // user defined work request ID
+  qp->cur_send_outstanding = 0;
+  qp->cur_posted_rcv_bufs  = 0;
+  qp->snd_rcv_balance      = 0;
+  
+  CDEBUG(D_OTHER, "create_qp: qp_num = %d, slid = %d, qp_hndl = 0X%X", 
+                  qp->qp_num, qp->slid, qp->qp_hndl);
+
+  // initialize spin-lock mutex variables
+  spin_lock_init(&(qp->snd_mutex));
+  spin_lock_init(&(qp->rcv_mutex));
+  spin_lock_init(&(qp->bl_mutex));
+  spin_lock_init(&(qp->cln_mutex));
+  // number of outstanding requests on the send Q
+  qp->cur_send_outstanding = 0; 
+  // number of posted receive buffers
+  qp->cur_posted_rcv_bufs  = 0;  
+  qp->snd_rcv_balance      = 0;
+
+  return(VAPI_OK);
+
+}
+
+//
+// initialize a UD qp state to RTR and RTS 
+//
+VAPI_ret_t 
+init_qp_UD(QP_info *qp, int qp_index)
+{
+  VAPI_qp_attr_t      qp_attr;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_attr_mask_t qp_attr_mask;
+  VAPI_qp_cap_t       qp_cap;
+  VAPI_ret_t       vstat;
+
+  /* Move from RST to INIT */
+  /* Change QP to INIT */
+
+  CDEBUG(D_OTHER, "Changing QP state to INIT qp-index = %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state = VAPI_INIT;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix  = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "pkey_ix qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.port     = qp->port;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PORT);
+
+  CDEBUG(D_OTHER, "port qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.qkey = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QKEY);
+
+  CDEBUG(D_OTHER, "qkey qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  /* If I do not set this mask, I get an error from HH. QPM should catch it */
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RST to INIT. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  CDEBUG(D_OTHER, "Modifying QP from RST to INIT.\n");
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Move from INIT to RTR */
+  /* Change QP to RTR */
+  CDEBUG(D_OTHER, "Changing QP state to RTR\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state         = VAPI_RTR;  
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "INIT to RTR- qp_state : qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from INIT to RTR. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+  
+  CDEBUG(D_OTHER, "Modifying QP from INIT to RTR.\n");
+  
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                                      
+  /* RTR to RTS - Change QP to RTS */
+  CDEBUG(D_OTHER, "Changing QP state to RTS\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state        = VAPI_RTS;   
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+  
+  qp_attr.sq_psn          = START_SQ_PSN;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_SQ_PSN);
+  
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RTR to RTS. %s:%s\n",
+                          VAPI_strerror_sym(vstat), 
+                          VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  CDEBUG(D_OTHER, "Modifying QP from RTR to RTS. \n");
+                     
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                        
+  //
+  // a QP is at RTS state NOW
+  //
+ 
+  CDEBUG(D_OTHER, "IBNAL- UD qp is at RTS NOW\n");
+  
+  return(vstat);
+
+}
+
+
+
+//
+// initialize a RC qp state to RTR and RTS 
+// RC transport service 
+//
+VAPI_ret_t 
+init_qp_RC(QP_info *qp, int qp_index)
+{
+  VAPI_qp_attr_t      qp_attr;
+  VAPI_qp_init_attr_t qp_init_attr;
+  VAPI_qp_attr_mask_t qp_attr_mask;
+  VAPI_qp_cap_t       qp_cap;
+  VAPI_ret_t       vstat;
+
+  /* Move from RST to INIT */
+  /* Change QP to INIT */
+  
+  CDEBUG(D_OTHER, "Changing QP state to INIT qp-index = %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state = VAPI_INIT;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+   CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix  = 0;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "pkey_ix qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.port     = qp->port;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PORT);
+
+  CDEBUG(D_OTHER, "port qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.remote_atomic_flags = VAPI_EN_REM_WRITE | VAPI_EN_REM_READ;
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_REMOTE_ATOMIC_FLAGS);
+
+  CDEBUG(D_OTHER, "remote_atomic_flags qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  /* If I do not set this mask, I get an error from HH. QPM should catch it */
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RST to INIT. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Move from INIT to RTR */
+  /* Change QP to RTR */
+  CDEBUG(D_OTHER, "Changing QP state to RTR qp_indexi %d\n", qp_index);
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+  qp_attr.qp_state         = VAPI_RTR;  
+
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.av.sl            = 0;/* RESPONDER_SL */
+  qp_attr.av.grh_flag      = FALSE;
+  qp_attr.av.dlid          = qp->dlid;/*RESPONDER_LID;*/
+  qp_attr.av.static_rate   = 0;
+  qp_attr.av.src_path_bits = 0;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_AV);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.path_mtu         = MTU_2048;// default is MTU_2048             
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PATH_MTU);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.rq_psn           = START_RQ_PSN;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RQ_PSN);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.qp_ous_rd_atom   = NUM_WQE;        
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_OUS_RD_ATOM);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.pkey_ix          = 0;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_PKEY_IX);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.min_rnr_timer    = 10;              
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_MIN_RNR_TIMER);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  qp_attr.dest_qp_num = qp->rqp_num;                   
+
+  CDEBUG(D_OTHER, "remore qp num %d\n",  qp->rqp_num);
+
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_DEST_QP_NUM);
+
+  CDEBUG(D_OTHER, "qp_state qp_attr_mask = 0X%x\n", qp_attr_mask);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from INIT to RTR. qp_index %d - %s\n",
+                                                qp_index, VAPI_strerror(vstat));
+     return(vstat);
+  }
+  
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                                      
+  /* RTR to RTS - Change QP to RTS */
+  CDEBUG(D_OTHER, "Changing QP state to RTS\n");
+
+  QP_ATTR_MASK_CLR_ALL(qp_attr_mask);
+
+  qp_attr.qp_state        = VAPI_RTS;   
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_QP_STATE);
+
+  qp_attr.sq_psn          = START_SQ_PSN;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_SQ_PSN);
+
+  qp_attr.timeout         = 0x18;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_TIMEOUT);
+
+  qp_attr.retry_count     = 10;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RETRY_COUNT);
+
+  qp_attr.rnr_retry       = 14;         
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_RNR_RETRY);
+
+  qp_attr.ous_dst_rd_atom = 100;        
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_OUS_DST_RD_ATOM);
+
+  qp_attr.min_rnr_timer   = 5;          
+  QP_ATTR_MASK_SET(qp_attr_mask,QP_ATTR_MIN_RNR_TIMER);
+
+  vstat = VAPI_modify_qp(qp->hca_hndl,
+                         qp->qp_hndl,
+                         &qp_attr,
+                         &qp_attr_mask,
+                         &qp_cap);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed modifying QP from RTR to RTS. %s:%s\n",
+                   VAPI_strerror_sym(vstat), VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat= VAPI_query_qp(qp->hca_hndl,
+                       qp->qp_hndl,
+                       &qp_attr,
+                       &qp_attr_mask,
+                       &qp_init_attr);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query QP. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+                        
+  //
+  // a QP is at RTS state NOW
+  //
+ 
+   CDEBUG(D_OTHER, "IBNAL- RC qp is at RTS NOW\n");
+  
+  return(vstat);
+}
+
+
+
+VAPI_ret_t 
+IB_Open_HCA(kibnal_data_t *kib_data)
+{
+
+  VAPI_ret_t     vstat;
+  VAPI_cqe_num_t cqe_active_num;
+  QP_info        *qp; 
+  int            i;
+  int            Num_posted_recv_buf;
+
+  /* Open HCA */
+  CDEBUG(D_PORTALS, "Opening an HCA\n");
+
+  vstat = VAPI_open_hca(HCA_ID, &Hca_hndl);
+  vstat = EVAPI_get_hca_hndl(HCA_ID, &Hca_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed opening the HCA: %s. %s...\n",HCA_ID,VAPI_strerror(vstat));
+     return(vstat);
+  } 
+
+  /* Get HCA CAP */
+  vstat = VAPI_query_hca_cap(Hca_hndl, &Hca_vendor, &Hca_cap);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query hca cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Get port 1 info */
+  vstat = VAPI_query_hca_port_prop(Hca_hndl, HCA_PORT_1 , &Hca_port_1_props);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query port cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }      
+
+  /* Get port 2 info */
+  vstat = VAPI_query_hca_port_prop(Hca_hndl, HCA_PORT_2, &Hca_port_2_props);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed query port cap %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }      
+
+  // Get a PD 
+  CDEBUG(D_PORTALS, "Allocating PD \n");
+  vstat = VAPI_alloc_pd(Hca_hndl,&Pd_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed allocating a PD. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  vstat = createMemRegion(Hca_hndl, Pd_hndl);
+  if (vstat != VAPI_OK) {
+     CERROR("Failed registering a memory region.%s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  /* Create CQ for RQ*/
+  CDEBUG(D_PORTALS, "Creating a send completion queue\n");
+
+  vstat = VAPI_create_cq(Hca_hndl,    
+                         NUM_CQE,    
+                         &Cq_hndl, 
+                         &cqe_active_num);
+
+  if (vstat != VAPI_OK) {
+     CERROR("Failed creating a CQ. %s\n",VAPI_strerror(vstat));
+     return(vstat);
+  }
+
+  if(NUM_CQE == cqe_active_num) {
+    CERROR("VAPI_create_cq: NUM_CQE EQ cqe_active_num \n");
+  }
+  else {
+    CDEBUG(D_NET, "VAPI_create_cq: NUM_CQE %d , actual cqe_active_num %d \n",
+                   NUM_CQE, cqe_active_num);
+  }
+
+  Cq_SQ_hndl     = Cq_hndl;
+  Cq_RQ_hndl     = Cq_hndl;
+
+  //
+  // create  QPs 
+  //
+  for(i=0; i < NUM_QPS; i++) {
+      QP_list[i].pd_hndl    = Pd_hndl;
+      QP_list[i].hca_hndl   = Hca_hndl;
+      // sq rq use the same Cq_hndl 
+      QP_list[i].sq_cq_hndl = Cq_hndl; 
+      QP_list[i].rq_cq_hndl = Cq_hndl;
+      vstat = create_qp(&QP_list[i], i);
+      if (vstat != VAPI_OK) {
+         CERROR("Failed creating a QP %d %s\n",i, VAPI_strerror(vstat));
+         return(vstat);
+      }
+  }      
+
+  //
+  // record HCA data 
+  //
+
+  Hca_data.hca_hndl     = Hca_hndl;      // HCA handle
+  Hca_data.pd_hndl      = Pd_hndl;       // protection domain
+  Hca_data.port         = 1;             // port number
+  Hca_data.num_qp       = NUM_QPS;        // number of qp used
+
+  for(i=0; i < NUM_QPS; i++) {
+    Hca_data.qp_ptr[i]    = &QP_list[i];   // point to QP_list
+  }
+
+  Hca_data.num_cq       = NUM_CQ;        // number of cq used
+  Hca_data.cq_hndl      = Cq_hndl;       // 
+  Hca_data.sq_cq_hndl   = Cq_SQ_hndl;    // 
+  Hca_data.rq_cq_hndl   = Cq_RQ_hndl;    // 
+  Hca_data.kib_data     = kib_data;       //
+  Hca_data.slid         = QP_list[0].slid;//
+
+  // prepare L_QP_data
+
+#ifdef USE_SHARED_MEMORY_AND_SOCKET
+
+  /*
+   *  + use a shared-memory between a user thread and a kernel thread 
+   *    for HCA's data exchange on the same node  
+   *  + use socket in user mode to exhange HCA's data with a remote node 
+   */
+
+  
+  R_QP_data.opcode  = SEND_QP_INFO;
+  R_QP_data.length  = sizeof(L_QP_data);
+
+  for(i=0; i < NUM_QPS; i++) {
+    // my slid  will be used in a remote node as dlid 
+    R_QP_data.dlid[i]    = QP_list[i].slid;
+    // my qp_num will be used in remode node as remote_qp_number 
+    // RC is used here so we need dlid and rqp_num  
+    R_QP_data.rqp_num[i] = QP_list[i].qp_num ;
+  }
+
+  // create a kernel thread for exchanging HCA's data 
+  // R_QP_data will be exchanged with a remoe node
+
+  kernel_thread(k_server_thread, &R_QP_data, 0); // 
+  // check if the HCA'data have been updated by kernel_thread 
+  // loop until the HCA's data is updated 
+  // make sure that uagent is running 
+  
+  // QP info is exchanged with a remote node   
+  while (1) {
+    schedule_timeout(1000);
+    if(R_QP_data.opcode ==  RECV_QP_INFO) {
+       CDEBUG(D_NET, "HCA's data is being updated\n");
+       break;
+   }
+  }
+ 
+#endif
+
+#ifdef USE_SHARED_MEMORY_AND_MULTICAST
+
+  /*
+   *  + use a shared-memory between a user thread and a kernel thread 
+   *    for HCA's data exchange on the same node  
+   *  + use Infinoband UR/multicast in user mode to exhange HCA's data with i
+   *    a remote node 
+   */
+
+  // use CM, opemSM 
+  
+#endif
+
+  // 
+  for(i=0; i < NUM_QPS; i++) {
+     qp = (QP_info *) &QP_list[i];
+     QP_list[i].rqp_num = R_QP_data.rqp_num[i]; // remoter qp number 
+     QP_list[i].dlid    = R_QP_data.dlid[i];    // remote dlid 
+  }
+
+  // already have remote_qp_num adn dlid information
+  // initialize QP to RTR/RTS state 
+  //
+  for(i=0; i < NUM_QPS; i++) {
+    vstat = init_qp_RC(&QP_list[i], i);
+    if (vstat != VAPI_OK) {
+       CERROR("Failed change a QP %d to RTS state%s\n",
+                    i,VAPI_strerror(vstat));
+       return(vstat);
+    }
+  }
+
+  // post receiving buffer before any send happened 
+  
+  Num_posted_recv_buf = post_recv_bufs( (VAPI_wr_id_t ) START_RECV_WRQ_ID); 
+
+  // for irregular completion event or some unexpected failure event 
+  vstat = IB_Set_Async_Event_Handler(Hca_data, &kibnal_data);
+  if (vstat != VAPI_OK) {
+     CERROR("IB_Set_Async_Event_Handler failed: %d\n", vstat);
+     return vstat;
+  }
+
+
+  CDEBUG(D_PORTALS, "IBNAL- done with IB_Open_HCA\n");
+
+  for(i=0;  i < NUM_MBUF; i++) {
+    spin_lock_init(&MSB_mutex[i]);
+  }
+
+  return(VAPI_OK);
+
+}
+
+
+/* 
+  Function:  IB_Set_Event_Handler()
+             
+             IN   Hca_info hca_data
+             IN   kibnal_data_t *kib_data  -- private data      
+             OUT  NONE
+
+        return: VAPI_OK - success
+                else    - fail 
+
+*/
+
+VAPI_ret_t 
+IB_Set_Event_Handler(HCA_info hca_data, kibnal_data_t *kib_data)
+{
+  VAPI_ret_t vstat;
+  EVAPI_compl_handler_hndl_t   comp_handler_hndl;
+
+  // register CQE_Event_Hnadler 
+  // VAPI function 
+  vstat = VAPI_set_comp_event_handler(hca_data.hca_hndl,
+                                      CQE_event_handler,
+                                      &hca_data);
+
+  /*
+  or use extended VAPI function 
+  vstat = EVAPI_set_comp_eventh(hca_data.hca_hndl,
+                                hca_data.cq_hndl,
+                                CQE_event_handler,
+                                &hca_data,
+                                &comp_handler_hndl
+                                );
+  */
+                                    
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Event_Handler: failed EVAPI_set_comp_eventh for"
+             " HCA ID = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+      return vstat;
+  }
+
+  // issue a request for completion ievent notification 
+  vstat = VAPI_req_comp_notif(hca_data.hca_hndl, 
+                              hca_data.cq_hndl,
+                              VAPI_NEXT_COMP); 
+
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Event_Handler: failed VAPI_req_comp_notif for HCA ID"
+             " = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+  }
+
+  return vstat;
+}
+
+
+
+/* 
+  Function:  IB_Set_Async_Event_Handler()
+             
+             IN   HCA_info hca_data
+             IN   kibnal_data_t *kib_data -- private data      
+             OUT  NONE
+
+        return: VAPI_OK - success
+                else    - fail 
+
+*/
+
+
+VAPI_ret_t 
+IB_Set_Async_Event_Handler(HCA_info hca_data, kibnal_data_t *kib_data)
+{
+  VAPI_ret_t    vstat;
+
+  //
+  // register an asynchronous event handler for this HCA 
+  //
+
+  vstat= VAPI_set_async_event_handler(hca_data.hca_hndl,
+                                      async_event_handler, 
+                                      kib_data);
+
+  if (vstat != VAPI_OK) {
+      CERROR("IB_Set_Async_Event_Handler: failed VAPI_set_async_comp_event_handler"
+             " for HCA ID = %s (%s).\n", HCA_ID, VAPI_strerror(vstat));
+  }
+
+  return vstat;
+}
+
+//
+// IB_Close_HCA
+// close this Infiniband HCA interface 
+// release allocated resources to system 
+//
+VAPI_ret_t 
+IB_Close_HCA(void )
+{
+        
+  VAPI_ret_t  vstat;
+  int         ok = 1;
+  int         i;
+            
+  /* Destroy QP */
+  CDEBUG(D_PORTALS, "Destroying QP\n");
+
+  for(i=0; i < NUM_QPS; i++) {
+     vstat = VAPI_destroy_qp(QP_list[i].hca_hndl, QP_list[i].qp_hndl);
+     if (vstat != VAPI_OK) {
+        CERROR("Failed destroying QP %d. %s\n", i, VAPI_strerror(vstat));
+        ok = 0;
+     }
+  }
+
+  if (ok) {
+     /* Destroy CQ */
+     CDEBUG(D_PORTALS, "Destroying CQ\n");
+     for(i=0; i < NUM_QPS; i++) {
+        // send_cq adn receive_cq are shared the same CQ
+        // so only destroy one of them 
+        vstat = VAPI_destroy_cq(QP_list[i].hca_hndl, QP_list[i].sq_cq_hndl);
+        if (vstat != VAPI_OK) {
+           CERROR("Failed destroying CQ %d. %s\n", i, VAPI_strerror(vstat));
+           ok = 0;
+        }
+     }
+  }
+
+  if (ok) {
+     /* Destroy Memory Region */
+     CDEBUG(D_PORTALS, "Deregistering MR\n");
+     for(i=0; i < NUM_QPS; i++) {
+        vstat = deleteMemRegion(&QP_list[i], i);
+        if (vstat != VAPI_OK) {
+           CERROR("Failed deregister mem reg %d. %s\n",i, VAPI_strerror(vstat));
+           ok = 0;
+           break;
+        }
+     }
+  }
+
+  if (ok) {
+     // finally 
+     /* Close HCA */
+     CDEBUG(D_PORTALS, "Closing HCA\n");
+     vstat = VAPI_close_hca(Hca_hndl);
+     if (vstat != VAPI_OK) {
+        CERROR("Failed to close HCA. %s\n", VAPI_strerror(vstat));
+        ok = 0;
+     }
+  }
+
+  CDEBUG(D_PORTALS, "IBNAL- Done with closing HCA \n");
+  
+  return vstat; 
+}
+
+
+VAPI_ret_t 
+createMemRegion(VAPI_hca_hndl_t hca_hndl, 
+                   VAPI_pd_hndl_t  pd_hndl) 
+{
+  VAPI_ret_t  vstat;
+  VAPI_mrw_t  mrw;
+  VAPI_mrw_t  rep_mr;   
+  VAPI_mr_hndl_t   rep_mr_hndl;
+  int         buf_size;
+  char        *bufptr;
+  int         i;
+
+  // send registered memory region 
+  for(i=0; i < NUM_ENTRY; i++) {
+    MSbuf_list[i].buf_size = KB_32; 
+    PORTAL_ALLOC(bufptr, MSbuf_list[i].buf_size);
+    if(bufptr == NULL) {
+       CDEBUG(D_MALLOC,"Failed to malloc a block of send memory, qix %d size %d\n",
+                                          i, MSbuf_list[i].buf_size);
+       CERROR("Failed to malloc a block of send memory, qix %d size %d\n",
+                                          i, MSbuf_list[i].buf_size);
+       return(VAPI_ENOMEM);
+    }
+
+    mrw.type   = VAPI_MR; 
+    mrw.pd_hndl= pd_hndl;
+    mrw.start  = MSbuf_list[i].buf_addr = (VAPI_virt_addr_t)(MT_virt_addr_t) bufptr;
+    mrw.size   = MSbuf_list[i].buf_size;
+    mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+                 VAPI_EN_REMOTE_WRITE | 
+                 VAPI_EN_REMOTE_READ;
+
+    // register send memory region  
+    vstat = VAPI_register_mr(hca_hndl, 
+                             &mrw, 
+                             &rep_mr_hndl, 
+                             &rep_mr);
+
+    // this memory region is going to be reused until deregister is called 
+    if(vstat != VAPI_OK) {
+       CERROR("Failed registering a mem region qix %d Addr=%p, Len=%d. %s\n",
+                          i, mrw.start, mrw.size, VAPI_strerror(vstat));
+       return(vstat);
+    }
+
+    MSbuf_list[i].mr        = rep_mr;
+    MSbuf_list[i].mr_hndl   = rep_mr_hndl;
+    MSbuf_list[i].bufptr    = bufptr;
+    MSbuf_list[i].buf_addr  = rep_mr.start;
+    MSbuf_list[i].status    = BUF_REGISTERED;
+    MSbuf_list[i].ref_count = 0;
+    MSbuf_list[i].buf_type  = REG_BUF;
+    MSbuf_list[i].raddr     = 0x0;
+    MSbuf_list[i].rkey      = 0x0;
+  }
+
+  // RDAM buffer is not reserved for RDAM WRITE/READ
+  
+  for(i=NUM_ENTRY; i< NUM_MBUF; i++) {
+    MSbuf_list[i].status    = BUF_UNREGISTERED;
+    MSbuf_list[i].buf_type  = RDMA_BUF;
+  }
+
+
+  // recv registered memory region 
+  for(i=0; i < NUM_ENTRY; i++) {
+    MRbuf_list[i].buf_size = KB_32; 
+    PORTAL_ALLOC(bufptr, MRbuf_list[i].buf_size);
+
+    if(bufptr == NULL) {
+       CDEBUG(D_MALLOC, "Failed to malloc a block of send memory, qix %d size %d\n",
+                      i, MRbuf_list[i].buf_size);
+       return(VAPI_ENOMEM);
+    }
+
+    mrw.type   = VAPI_MR; 
+    mrw.pd_hndl= pd_hndl;
+    mrw.start  = (VAPI_virt_addr_t)(MT_virt_addr_t) bufptr;
+    mrw.size   = MRbuf_list[i].buf_size;
+    mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+                 VAPI_EN_REMOTE_WRITE | 
+                 VAPI_EN_REMOTE_READ;
+
+    // register send memory region  
+    vstat = VAPI_register_mr(hca_hndl, 
+                             &mrw, 
+                             &rep_mr_hndl, 
+                             &rep_mr);
+
+    // this memory region is going to be reused until deregister is called 
+    if(vstat != VAPI_OK) {
+       CERROR("Failed registering a mem region qix %d Addr=%p, Len=%d. %s\n",
+                          i, mrw.start, mrw.size, VAPI_strerror(vstat));
+       return(vstat);
+    }
+
+    MRbuf_list[i].mr        = rep_mr;
+    MRbuf_list[i].mr_hndl   = rep_mr_hndl;
+    MRbuf_list[i].bufptr    = bufptr;
+    MRbuf_list[i].buf_addr  = rep_mr.start;
+    MRbuf_list[i].status    = BUF_REGISTERED;
+    MRbuf_list[i].ref_count = 0;
+    MRbuf_list[i].buf_type  = REG_BUF;
+    MRbuf_list[i].raddr     = 0x0;
+    MRbuf_list[i].rkey      = rep_mr.r_key;
+    MRbuf_list[i].lkey      = rep_mr.l_key;
+  
+  }
+ 
+  // keep extra information for a qp 
+  for(i=0; i < NUM_QPS; i++) {
+    QP_list[i].mr_hndl    = MSbuf_list[i].mr_hndl; 
+    QP_list[i].mr         = MSbuf_list[i].mr;
+    QP_list[i].bufptr     = MSbuf_list[i].bufptr;
+    QP_list[i].buf_addr   = MSbuf_list[i].buf_addr;
+    QP_list[i].buf_size   = MSbuf_list[i].buf_size;
+    QP_list[i].raddr      = MSbuf_list[i].raddr;
+    QP_list[i].rkey       = MSbuf_list[i].rkey;
+    QP_list[i].lkey       = MSbuf_list[i].lkey;
+  }
+
+  CDEBUG(D_PORTALS, "IBNAL- done VAPI_ret_t createMemRegion \n");
+
+  return vstat;
+
+} /* createMemRegion */
+
+
+
+VAPI_ret_t  
+deleteMemRegion(QP_info *qp, int qix)
+{
+  VAPI_ret_t  vstat;
+
+  //
+  // free send memory assocaited with this memory region  
+  //
+  PORTAL_FREE(MSbuf_list[qix].bufptr, MSbuf_list[qix].buf_size);
+
+  // de-register it 
+  vstat =  VAPI_deregister_mr(qp->hca_hndl, MSbuf_list[qix].mr_hndl);
+
+  if(vstat != VAPI_OK) {
+     CERROR("Failed deregistering a send mem region qix %d %s\n",
+                         qix, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  //
+  // free recv memory assocaited with this memory region  
+  //
+  PORTAL_FREE(MRbuf_list[qix].bufptr, MRbuf_list[qix].buf_size);
+
+  // de-register it 
+  vstat =  VAPI_deregister_mr(qp->hca_hndl, MRbuf_list[qix].mr_hndl);
+
+  if(vstat != VAPI_OK) {
+     CERROR("Failed deregistering a recv mem region qix %d %s\n",
+                         qix, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  return vstat;
+}
+
+
+//
+// polling based event handling 
+// + a daemon process
+// + poll the CQ and check what is in the CQ 
+// + process incoming CQ event
+// + 
+//
+
+
+RDMA_Info_Exchange   Rdma_info;
+int                  Cts_Message_arrived = NO;
+
+void k_recv_thread(HCA_info *hca_data)
+{
+ VAPI_ret_t       vstat; 
+ VAPI_wc_desc_t   comp_desc;   
+ unsigned long    polling_count = 0;
+ u_int32_t        timeout_usec;
+ unsigned int     priority = 100;
+ unsigned int     length;
+ VAPI_wr_id_t     wrq_id;
+ u_int32_t        transferred_data_length; /* Num. of bytes transferred */
+ void             *bufdata;
+ VAPI_virt_addr_t bufaddr;
+ unsigned long    buf_size = 0;
+ QP_info          *qp;       // point to QP_list
+
+ kportal_daemonize("k_recv_thread"); // make it as a daemon process 
+
+ // tuning variable 
+ timeout_usec = 100; // how is the impact on the performance
+
+ // send Q and receive Q are using the same CQ 
+ // so only poll one CQ for both operations 
+ 
+ CDEBUG(D_NET, "IBNAL- enter kibnal_recv_thread\n");
+ CDEBUG(D_NET, "hca_hndl = 0X%x, cq_hndl=0X%x\n", 
+                         hca_data->hca_hndl,hca_data->cq_hndl); 
+
+ qp = hca_data->qp_ptr;
+ if(qp == NULL) {
+   CDEBUG(D_NET, "in recv_thread qp is NULL\n");
+   CDEBUG(D_NET, "Exit from  recv_thread qp is NULL\n");
+   return; 
+ }
+ else {
+   CDEBUG(D_NET, "in recv_thread qp is 0X%X\n", qp);
+ }
+
+ CDEBUG(D_NET, "kibnal_recv_thread - enter event driver polling loop\n");
+
+ //
+ // use event driver 
+ //
+ 
+
+
+ while(1) {
+    polling_count++;
+
+    //
+    // send Q and receive Q are using the same CQ 
+    // so only poll one CQ for both operations 
+    //
+
+    vstat = VAPI_poll_cq(hca_data->hca_hndl,hca_data->cq_hndl, &comp_desc);                      
+
+    if (vstat == VAPI_CQ_EMPTY) { 
+      // there is no event in CQE 
+      continue;
+    } 
+    else {
+      if (vstat != (VAPI_OK)) {
+        CERROR("error while polling completion queuei vstat %d \n", vstat);
+        return; 
+      }
+    }
+
+    // process the complete event 
+    switch(comp_desc.opcode) {
+      case   VAPI_CQE_SQ_SEND_DATA:
+        // about the Send Q ,POST SEND completion 
+        // who needs this information
+        // get wrq_id
+        // mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+               
+        wrq_id = comp_desc.id;
+
+        if(RDMA_OP_ID < wrq_id) {
+          // this RDMA message id, adjust it to the right entry       
+          wrq_id = wrq_id - RDMA_OP_ID;
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.send_rdma_mr_hndl);
+        }
+        
+        if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_SQ_SEND_DATA: Failed deregistering a RDMAi recv"                   " mem region %s\n", VAPI_strerror(vstat));
+        }
+
+        if((RDMA_CTS_ID <= wrq_id) && (RDMA_OP_ID < wrq_id)) {
+          // RTS or CTS send complete, release send buffer 
+          if(wrq_id >= RDMA_RTS_ID)
+            wrq_id = wrq_id - RDMA_RTS_ID;
+          else 
+            wrq_id = wrq_id - RDMA_CTS_ID;
+        }
+
+        spin_lock(&MSB_mutex[(int) wrq_id]);
+        MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+        spin_unlock(&MSB_mutex[(int) wrq_id]);
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_SEND_DATA\n");  
+        break;
+
+      case   VAPI_CQE_SQ_RDMA_WRITE:
+        // about the Send Q,  RDMA write completion 
+        // who needs this information
+        // data is successfully write from pource to  destionation 
+             
+        //  get wr_id
+        //  mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+        //  de-register  rdma buffer 
+        //
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_RDMA_WRITE\n");  
+        break;
+
+      case   VAPI_CQE_SQ_RDMA_READ:
+        // about the Send Q
+        // RDMA read completion 
+        // who needs this information
+        // data is successfully read from destionation to source 
+        CDEBUG(D_NET, "CQE opcode- VAPI_CQE_SQ_RDMA_READ\n");  
+        break;
+
+      case   VAPI_CQE_SQ_COMP_SWAP:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_COMP_SWAP\n");  
+        break;
+
+      case   VAPI_CQE_SQ_FETCH_ADD:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_FETCH_ADD\n");  
+        break;
+
+      case   VAPI_CQE_SQ_BIND_MRW:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_BIND_MRW\n");  
+        break;
+
+      case   VAPI_CQE_RQ_SEND_DATA:
+        // about the Receive Q
+        // process the incoming data and
+        // forward it to .....
+        // a completion recevie event is arriving at CQ 
+        // issue a recevie to get this arriving data out from CQ 
+        // pass the receiving data for further processing 
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_SEND_DATA\n");  
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if((wrq_id >= RDMA_CTS_ID) && (wrq_id < RDMA_OP_ID)) {
+          // this is RTS/CTS message 
+          // process it locally and don't pass it to portals layer 
+          // adjust wrq_id to get the right entry in MRbfu_list 
+                   
+          if(wrq_id >= RDMA_RTS_ID)
+            wrq_id = wrq_id - RDMA_RTS_ID;
+          else 
+            wrq_id = wrq_id - RDMA_CTS_ID;
+
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[wrq_id].buf_addr; 
+          MRbuf_list[wrq_id].status = BUF_INUSE; 
+          memcpy(&Rdma_info, &bufaddr, sizeof(RDMA_Info_Exchange));    
+        
+          if(Ready_To_send == Rdma_info.opcode) 
+            // an RTS request message from remote node 
+            // prepare local RDMA buffer and send local rdma info to
+            // remote node 
+            CTS_handshaking_protocol(&Rdma_info);
+          else 
+            if((Clear_To_send == Rdma_info.opcode) && 
+                              (RDMA_BUFFER_RESERVED == Rdma_info.flag))
+               Cts_Message_arrived = YES;
+            else 
+              if(RDMA_BUFFER_UNAVAILABLE == Rdma_info.flag) 
+                  CERROR("RDMA operation abort-RDMA_BUFFER_UNAVAILABLE\n");
+        }
+        else {
+          //
+          // this is an incoming mesage for portals layer 
+          // move to PORTALS layer for further processing 
+          //
+                     
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t)
+                                       MRbuf_list[wrq_id].buf_addr; 
+
+          MRbuf_list[wrq_id].status = BUF_INUSE; 
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    MRbuf_list[wrq_id].buf_size, 
+                    priority); 
+        }
+
+        // repost this receiving buffer and makr it at BUF_REGISTERED 
+
+        vstat = repost_recv_buf(qp, wrq_id);
+        if(vstat != (VAPI_OK)) {
+          CERROR("error while polling completion queue\n");
+        }
+        else {
+          MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+        }
+
+        break;
+
+      case   VAPI_CQE_RQ_RDMA_WITH_IMM:
+        // about the Receive Q
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if(wrq_id ==  RDMA_OP_ID) {
+          // this is RDAM op , locate the RDAM memory buffer address   
+               
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) Local_rdma_info.raddr;
+
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    Local_rdma_info.buf_length, 
+                    priority); 
+
+          // de-regiser this RDAM receiving memory buffer
+          // too early ??    test & check 
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.recv_rdma_mr_hndl);
+          if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_RQ_RDMA_WITH_IMM: Failed deregistering a RDMA"
+                   " recv  mem region %s\n", VAPI_strerror(vstat));
+          }
+        }
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+        break;
+
+      case   VAPI_CQE_INVAL_OPCODE:
+        //
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_INVAL_OPCODE\n");  
+        break;
+
+      default :
+        CDEBUG(D_NET, "CQE opcode-unknown opcode\n");  
+             break;
+    } // switch 
+    
+    schedule_timeout(RECEIVING_THREAD_TIMEOUT);//how often do we need to poll CQ 
+
+  }// receiving while loop
+
+
+}
+
+
+void CQE_event_handler(VAPI_hca_hndl_t hca_hndl, 
+                       VAPI_cq_hndl_t  cq_hndl, 
+                       void           *private)
+{
+ VAPI_ret_t       vstat; 
+ VAPI_wc_desc_t   comp_desc;   
+ unsigned long    polling_count = 0;
+ u_int32_t        timeout_usec;
+ unsigned int     priority = 100;
+ unsigned int     length;
+ VAPI_wr_id_t     wrq_id;
+ u_int32_t        transferred_data_length; /* Num. of bytes transferred */
+ void             *bufdata;
+ VAPI_virt_addr_t bufaddr;
+ unsigned long    buf_size = 0;
+ QP_info          *qp;       // point to QP_list
+ HCA_info         *hca_data;
+
+ // send Q and receive Q are using the same CQ 
+ // so only poll one CQ for both operations 
+ 
+ CDEBUG(D_NET, "IBNAL- enter CQE_event_handler\n");
+ printk("IBNAL- enter CQE_event_handler\n");
+
+ hca_data  = (HCA_info *) private; 
+
+ //
+ // use event driven  
+ //
+ 
+
+ vstat = VAPI_poll_cq(hca_data->hca_hndl,hca_data->cq_hndl, &comp_desc);   
+
+ if (vstat == VAPI_CQ_EMPTY) { 
+   CDEBUG(D_NET, "CQE_event_handler: there is no event in CQE, how could"
+                  " this " "happened \n");
+   printk("CQE_event_handler: there is no event in CQE, how could"
+                  " this " "happened \n");
+
+ } 
+ else {
+   if (vstat != (VAPI_OK)) {
+     CDEBUG(D_NET, "error while polling completion queue vstat %d - %s\n", 
+                vstat, VAPI_strerror(vstat));
+     printk("error while polling completion queue vstat %d - %s\n", 
+                                               vstat, VAPI_strerror(vstat));
+     return; 
+   }
+ }
+
+ // process the complete event 
+ switch(comp_desc.opcode) {
+    case   VAPI_CQE_SQ_SEND_DATA:
+      // about the Send Q ,POST SEND completion 
+      // who needs this information
+      // get wrq_id
+      // mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+               
+      wrq_id = comp_desc.id;
+
+#ifdef IBNAL_SELF_TESTING
+      if(wrq_id == SEND_RECV_TEST_ID) {
+        printk("IBNAL_SELF_TESTING - VAPI_CQE_SQ_SEND_DATA \n"); 
+      }
+#else  
+      if(RDMA_OP_ID < wrq_id) {
+        // this RDMA message id, adjust it to the right entry       
+        wrq_id = wrq_id - RDMA_OP_ID;
+        vstat = VAPI_deregister_mr(qp->hca_hndl, 
+                                   Local_rdma_info.send_rdma_mr_hndl);
+      }
+
+      if(vstat != VAPI_OK) {
+        CERROR(" VAPI_CQE_SQ_SEND_DATA: Failed deregistering a RDMA"
+               " recv  mem region %s\n", VAPI_strerror(vstat));
+      }
+
+      if((RDMA_CTS_ID <= wrq_id) && (RDMA_OP_ID < wrq_id)) {
+        // RTS or CTS send complete, release send buffer 
+        if(wrq_id >= RDMA_RTS_ID)
+          wrq_id = wrq_id - RDMA_RTS_ID;
+        else 
+          wrq_id = wrq_id - RDMA_CTS_ID;
+      }
+
+      spin_lock(&MSB_mutex[(int) wrq_id]);
+      MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+      spin_unlock(&MSB_mutex[(int) wrq_id]);
+#endif 
+
+      CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_SEND_DATA\n");  
+
+      break;
+
+    case   VAPI_CQE_SQ_RDMA_WRITE:
+      // about the Send Q,  RDMA write completion 
+      // who needs this information
+      // data is successfully write from pource to  destionation 
+             
+      //  get wr_id
+      //  mark MSbuf_list[wr_id].status = BUF_REGISTERED 
+      //  de-register  rdma buffer 
+      //
+             
+       CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_RDMA_WRITE\n");  
+       break;
+
+      case   VAPI_CQE_SQ_RDMA_READ:
+        // about the Send Q
+        // RDMA read completion 
+        // who needs this information
+        // data is successfully read from destionation to source 
+         CDEBUG(D_NET, "CQE opcode- VAPI_CQE_SQ_RDMA_READ\n");  
+         break;
+
+      case   VAPI_CQE_SQ_COMP_SWAP:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+            
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_COMP_SWAP\n");  
+        break;
+
+      case   VAPI_CQE_SQ_FETCH_ADD:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_FETCH_ADD\n");  
+        break;
+
+      case   VAPI_CQE_SQ_BIND_MRW:
+        // about the Send Q
+        // RDMA write completion 
+        // who needs this information
+             
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_SQ_BIND_MRW\n");  
+        break;
+
+      case   VAPI_CQE_RQ_SEND_DATA:
+        // about the Receive Q
+        // process the incoming data and
+        // forward it to .....
+        // a completion recevie event is arriving at CQ 
+        // issue a recevie to get this arriving data out from CQ 
+        // pass the receiving data for further processing 
+         
+         CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_SEND_DATA\n");  
+          
+         wrq_id = comp_desc.id ;
+
+#ifdef IBNAL_SELF_TESTING
+
+      char        rbuf[KB_32];
+      int i;
+
+      if(wrq_id == SEND_RECV_TEST_ID) {
+        printk("IBNAL_SELF_TESTING - VAPI_CQE_RQ_SEND_DATA\n"); 
+      }
+
+      bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) 
+                       MRbuf_list[ SEND_RECV_TEST_BUF_ID].buf_addr; 
+      MRbuf_list[SEND_RECV_TEST_BUF_ID].status = BUF_INUSE; 
+      memcpy(&rbuf, &bufaddr, KB_32);    
+      
+
+      for(i=0; i < 16; i++)
+              printk("rbuf[%d]=%c, ", rbuf[i]);
+      printk("\n");
+
+      // repost this receiving buffer and makr it at BUF_REGISTERED 
+      vstat = repost_recv_buf(qp,SEND_RECV_TEST_BUF_ID);
+      if(vstat != (VAPI_OK)) {
+        printk("error while polling completion queue\n");
+      }
+      else {
+        MRbuf_list[SEND_RECV_TEST_BUF_ID].status = BUF_REGISTERED; 
+      }
+#else  
+         transferred_data_length = comp_desc.byte_len;
+             
+         if((wrq_id >= RDMA_CTS_ID) && (wrq_id < RDMA_OP_ID)) {
+           // this is RTS/CTS message 
+           // process it locally and don't pass it to portals layer 
+           // adjust wrq_id to get the right entry in MRbfu_list 
+                   
+           if(wrq_id >= RDMA_RTS_ID)
+             wrq_id = wrq_id - RDMA_RTS_ID;
+           else 
+             wrq_id = wrq_id - RDMA_CTS_ID;
+
+           bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) 
+                                           MRbuf_list[wrq_id].buf_addr; 
+           MRbuf_list[wrq_id].status = BUF_INUSE; 
+           memcpy(&Rdma_info, &bufaddr, sizeof(RDMA_Info_Exchange));    
+        
+           if(Ready_To_send == Rdma_info.opcode) 
+             // an RTS request message from remote node 
+             // prepare local RDMA buffer and send local rdma info to
+             // remote node 
+             CTS_handshaking_protocol(&Rdma_info);
+           else 
+             if((Clear_To_send == Rdma_info.opcode) && 
+                                (RDMA_BUFFER_RESERVED == Rdma_info.flag))
+               Cts_Message_arrived = YES;
+             else 
+               if(RDMA_BUFFER_UNAVAILABLE == Rdma_info.flag) 
+                 CERROR("RDMA operation abort-RDMA_BUFFER_UNAVAILABLE\n");
+         }
+         else {
+           //
+           // this is an incoming mesage for portals layer 
+           // move to PORTALS layer for further processing 
+           //
+                     
+           bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t)
+                                MRbuf_list[wrq_id].buf_addr; 
+
+           MRbuf_list[wrq_id].status = BUF_INUSE; 
+           transferred_data_length = comp_desc.byte_len;
+
+           kibnal_rx(hca_data->kib_data, 
+                     bufaddr, 
+                     transferred_data_length, 
+                     MRbuf_list[wrq_id].buf_size, 
+                     priority); 
+         }
+
+         // repost this receiving buffer and makr it at BUF_REGISTERED 
+         vstat = repost_recv_buf(qp, wrq_id);
+         if(vstat != (VAPI_OK)) {
+           CERROR("error while polling completion queue\n");
+         }
+         else {
+           MRbuf_list[wrq_id].status = BUF_REGISTERED; 
+         }
+#endif
+
+         break;
+
+      case   VAPI_CQE_RQ_RDMA_WITH_IMM:
+        // about the Receive Q
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+
+        wrq_id = comp_desc.id ;
+        transferred_data_length = comp_desc.byte_len;
+             
+        if(wrq_id ==  RDMA_OP_ID) {
+          // this is RDAM op , locate the RDAM memory buffer address   
+              
+          bufaddr = (VAPI_virt_addr_t)(MT_virt_addr_t) Local_rdma_info.raddr;
+
+          transferred_data_length = comp_desc.byte_len;
+
+          kibnal_rx(hca_data->kib_data, 
+                    bufaddr, 
+                    transferred_data_length, 
+                    Local_rdma_info.buf_length, 
+                    priority); 
+
+          // de-regiser this RDAM receiving memory buffer
+          // too early ??    test & check 
+          vstat = VAPI_deregister_mr(qp->hca_hndl, Local_rdma_info.recv_rdma_mr_hndl);
+          if(vstat != VAPI_OK) {
+            CERROR("VAPI_CQE_RQ_RDMA_WITH_IMM: Failed deregistering a RDMA"
+               " recv  mem region %s\n", VAPI_strerror(vstat));
+          }
+        }
+
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_RQ_RDMA_WITH_IMM\n");  
+        break;
+
+      case   VAPI_CQE_INVAL_OPCODE:
+        //
+        CDEBUG(D_NET, "CQE opcode-VAPI_CQE_INVAL_OPCODE\n");  
+        break;
+
+      default :
+        CDEBUG(D_NET, "CQE opcode-unknown opcode\n");  
+
+        break;
+    } // switch 
+    
+  // issue a new request for completion ievent notification 
+  vstat = VAPI_req_comp_notif(hca_data->hca_hndl, 
+                              hca_data->cq_hndl,
+                              VAPI_NEXT_COMP); 
+
+
+  if(vstat != VAPI_OK) {
+    CERROR("PI_req_comp_notif: Failed %s\n", VAPI_strerror(vstat));
+  }
+
+  return; // end of event handler 
+
+}
+
+
+
+int
+kibnal_cmd(struct portal_ioctl_data * data, void * private)
+{
+  int rc ;
+
+  CDEBUG(D_NET, "kibnal_cmd \n");  
+
+  return YES;
+}
+
+
+
+void ibnal_send_recv_self_testing(int *my_role)
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+ int                  buf_id;
+ char                 sbuf[KB_32];
+ char                 rbuf[KB_32];
+ int                  i;
+ int                  buf_length = KB_32;
+ VAPI_wc_desc_t       comp_desc;
+ int                  num_send = 1;
+ int                  loop_count = 0;
+
+ // make it as a daemon process 
+ // kportal_daemonize("ibnal_send_recv_self_testing");  
+
+ printk("My role is 0X%X\n", *my_role);
+
+if(*my_role ==  TEST_SEND_MESSAGE)  {
+ printk("Enter ibnal_send_recv_self_testing\n");
+
+ memset(&sbuf, 'a', KB_32);
+ memset(&rbuf, ' ', KB_32);
+ 
+ send_id = SEND_RECV_TEST_ID; 
+ buf_id = SEND_RECV_TEST_BUF_ID;
+
+ qp = &QP_list[buf_id];
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        =  send_id;
+
+ // scatter and gather info
+ sr_sg.len  = KB_32;
+ sr_sg.lkey = MSbuf_list[buf_id].mr.l_key; // use send MR
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[buf_id].buf_addr;
+
+ // copy data to register send buffer
+ memcpy(&sr_sg.addr, &sbuf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ /*
+ // call VAPI_post_sr to send out this data
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+   printk("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ printk("VAPI_post_sr success.\n");
+ */
+
+ }
+else {
+  printk("I am a receiver and doing nothing here\n"); 
+}
+         
+ printk("ibnal_send_recv_self_testing thread exit \n");
+
+ return;
+
+}
+
+
+//
+// ibnal initialize process  
+//
+// 1.  Bring up Infiniband network interface 
+//     * 
+// 2.  Initialize a PORTALS nal interface 
+// 
+//
+int __init 
+kibnal_initialize(void)
+{
+   int           rc;
+   int           ntok;
+   unsigned long sizemask;
+   unsigned int  nid;
+   VAPI_ret_t    vstat;
+
+
+   portals_debug_set_level(IBNAL_DEBUG_LEVEL_1);
+
+   CDEBUG(D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
+
+   CDEBUG(D_PORTALS, "kibnal_initialize: Enter kibnal_initialize\n");
+
+   // set api functional pointers 
+   kibnal_api.forward    = kibnal_forward;
+   kibnal_api.shutdown   = kibnal_shutdown;
+   kibnal_api.yield      = kibnal_yield;
+   kibnal_api.validate   = NULL; /* our api validate is a NOOP */
+   kibnal_api.lock       = kibnal_lock;
+   kibnal_api.unlock     = kibnal_unlock;
+   kibnal_api.nal_data   = &kibnal_data; // this is so called private data 
+   kibnal_api.refct      = 1;
+   kibnal_api.timeout    = NULL;
+   kibnal_lib.nal_data   = &kibnal_data;
+  
+   memset(&kibnal_data, 0, sizeof(kibnal_data));
+
+   // initialize kib_list list data structure 
+   INIT_LIST_HEAD(&kibnal_data.kib_list);
+
+   kibnal_data.kib_cb = &kibnal_lib;
+
+   spin_lock_init(&kibnal_data.kib_dispatch_lock);
+
+
+   //  
+   // bring up the IB inter-connect network interface 
+   // setup QP, CQ 
+   //
+   vstat = IB_Open_HCA(&kibnal_data);
+
+   if(vstat != VAPI_OK) {
+     CERROR("kibnal_initialize: IB_Open_HCA failed: %d- %s\n", 
+                                                vstat, VAPI_strerror(vstat));
+
+     printk("kibnal_initialize: IB_Open_HCA failed: %d- %s\n", 
+                                                vstat, VAPI_strerror(vstat));
+     return NO;
+   }
+
+   kibnal_data.kib_nid = (__u64 )Hca_hndl;//convert Hca_hndl to 64-bit format
+   kibnal_data.kib_init = 1;
+
+   CDEBUG(D_NET, " kibnal_data.kib_nid 0x%x%x\n", kibnal_data.kib_nid);
+   printk(" kibnal_data.kib_nid 0x%x%x\n", kibnal_data.kib_nid);
+
+   /* Network interface ready to initialise */
+   // get an entery in the PORTALS table for this IB protocol 
+
+   CDEBUG(D_PORTALS,"Call PtlNIInit to register this Infiniband Interface\n");
+   printk("Call PtlNIInit to register this Infiniband Interface\n");
+
+   rc = PtlNIInit(kibnal_init, 32, 4, 0, &kibnal_ni);
+
+   if(rc != PTL_OK) {
+     CERROR("kibnal_initialize: PtlNIInit failed %d\n", rc);
+     printk("kibnal_initialize: PtlNIInit failed %d\n", rc);
+     kibnal_finalize();
+     return (-ENOMEM);
+   }
+
+   CDEBUG(D_PORTALS,"kibnal_initialize: PtlNIInit DONE\n");
+   printk("kibnal_initialize: PtlNIInit DONE\n");
+
+
+
+#ifdef  POLL_BASED_CQE_HANDLING 
+   // create a receiving thread: main loopa
+   // this is polling based mail loop   
+   kernel_thread(k_recv_thread, &Hca_data, 0);
+#endif
+
+#ifdef EVENT_BASED_CQE_HANDLING
+  // for completion event handling,  this is event based CQE handling 
+  vstat = IB_Set_Event_Handler(Hca_data, &kibnal_data);
+
+  if (vstat != VAPI_OK) {
+     CERROR("IB_Set_Event_Handler failed: %d - %s \n", 
+                                           vstat, VAPI_strerror(vstat));
+     return vstat;
+  }
+
+  CDEBUG(D_PORTALS,"IB_Set_Event_Handler Done \n");
+  printk("IB_Set_Event_Handler Done \n");
+  
+#endif
+
+   PORTAL_SYMBOL_REGISTER(kibnal_ni);
+
+#ifdef IBNAL_SELF_TESTING
+  //
+  // test HCA send recv before normal event handling 
+  //
+  int  my_role;
+  my_role = TEST_SEND_MESSAGE;
+
+  printk("my role is TEST_RECV_MESSAGE\n");
+
+  // kernel_thread(ibnal_send_recv_self_testing, &my_role, 0);
+   
+  ibnal_send_recv_self_testing(&my_role);
+
+#endif 
+
+  return 0;
+
+}
+
+
+
+MODULE_AUTHOR("Hsingbung(HB) Chen <hbchen@lanl.gov>");
+MODULE_DESCRIPTION("Kernel Infiniband NAL v0.1");
+MODULE_LICENSE("GPL");
+
+module_init (kibnal_initialize);
+module_exit (kibnal_finalize);
+
+EXPORT_SYMBOL(kibnal_ni);
+
diff --git a/lustre/portals/knals/ibnal/ibnal.h b/lustre/portals/knals/ibnal/ibnal.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff5aeb34a75704ed3b5880e0b24a119046fa69ac
--- /dev/null
+++ b/lustre/portals/knals/ibnal/ibnal.h
@@ -0,0 +1,564 @@
+#ifndef _IBNAL_H
+#define _IBNAL_H
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <linux/ipc.h>
+#include <linux/shm.h>
+
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/locks.h>
+#include <linux/unistd.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/list.h>
+#include <linux/in.h>
+#include <unistd.h>
+
+#define DEBUG_SUBSYSTEM S_IBNAL
+
+#include <portals/p30.h>
+#include <portals/lib-p30.h>
+#include <linux/kp30.h>
+
+// Infiniband VAPI/EVAPI header files  
+// Mellanox MT23108 VAPI
+#include <vapi.h>
+#include <vapi_types.h>
+#include <vapi_common.h>
+#include <evapi.h>
+
+// pick a port for this RDMA information exhange between two hosts
+#define HOST_PORT           11211 
+#define QUEUE_SIZE          1024
+#define HCA_PORT_1          1
+#define HCA_PORT_2          2 
+#define DEBUG_SUBSYSTEM S_IBNAL
+
+#define START_SEND_WRQ_ID        0
+#define START_RECV_WRQ_ID        0
+#define START_RDMA_WRQ_ID        0  
+
+#define DEFAULT_PRIORITY         100
+
+#define WAIT_FOT_R_RDMA_TIMEOUT 10000
+#define MAX_NUM_TRY      3000 
+
+#define MAX_NUM_POLL     300 
+#define MAX_LOOP_COUNT   500
+
+#define MAX_GID          32 
+#define MCG_BUF_LENGTH   128
+
+#define SHARED_SEGMENT_SIZE   0x10000   
+#define HCA_EXCHANGE_SHM_KEY  999 // shared memory key for HCA data exchange 
+
+// some internals opcodes for IB operations used in IBNAL
+#define SEND_QP_INFO          0X00000001 
+#define RECV_QP_INFO          0X00000010 
+
+// Mellanox InfiniHost MT23108 
+// QP/CQ related information
+//
+
+#define MTU_256     1 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_512     2 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_1024    3 /* 1-256,2-512,3-1024,4-2048 */
+#define MTU_2048    4 /* 1-256,2-512,3-1024,4-2048 */
+
+// number of entries for each CQ and WQ 
+// how much do we need ?
+#define NUM_CQE        1024
+#define NUM_WQE        1024 
+#define MAX_OUT_SQ     64 
+#define MAX_OUT_RQ     64
+
+#define NUM_MBUF       256 
+#define NUM_RDMA_RESERVED_ENTRY 128 
+#define NUM_QPS        256 
+
+#define INVALID_WR_ID  ((VAPI_wr_id_t) -1)
+
+
+// for Vector IO 
+// scatter and gather 
+// Portals can support upto 64 IO-Vectors 
+// how much do we need ? 
+#define NUM_SGE        1 
+#define NUM_SG         1 
+#define NUM_CQ	       1	
+
+#define ONE_KB    1024
+#define ONE_MB    1024 * ONE_KB 
+#define ONE_GB    1024 * ONE_MB 
+
+
+#define KB_4      1024 * 4 
+#define KB_8      1024 * 8 
+#define KB_16     1024 * 16
+#define KB_32     1024 * 32
+#define KB_64     1024 * 64
+#define KB_128    1024 * 128 
+#define KB_256    1024 * 256 
+
+// 256 entry in registered buffer list 
+// small size message 
+#define Num_4_KB       64 
+#define Num_8_KB       64 
+#define Num_16_KB      40 
+#define Num_32_KB      40 
+#define Num_64_KB      40 
+#define Num_128_KB     4 
+#define Num_256_KB     4 
+
+#define SMALL_MSG_SIZE KB_32     
+
+#define MAX_MSG_SIZE   ONE_MB * 512   
+
+//   128's  64KB bufer for send
+//   128's  64KB bufer for recv  
+//   used in RDAM operation only 
+
+#define NUM_ENTRY      128 
+
+#define End_4_kb        Num_4_KB 
+#define End_8_kb        End_4_kb  + Num_8_KB 
+#define End_16_kb       End_8_kb  + Num_16_KB
+#define End_32_kb       End_16_kb + Num_32_KB
+#define End_64_kb       End_32_kb + Num_64_KB
+#define End_128_kb      End_64_kb + Num_128_KB
+#define End_256_kb      End_128_kb+ Num_256_KB
+
+
+#define SEND_BUF_SIZE   KB_32
+#define RECV_BUF_SIZE   SEND_BUF_SIZE
+
+// #define POLL_BASED_CQE_HANDLING	1
+#define EVENT_BASED_CQE_HANDLING        1
+#define IBNAL_SELF_TESTING		1
+
+#ifdef  IBNAL_SELF_TESTING
+#undef  IBNAL_SELF_TESTING
+#endif
+
+
+#define MSG_SIZE_SMALL 1 
+#define MSG_SIZE_LARGE 2 
+
+
+
+// some defauly configuration values for early testing 
+#define DEFAULT_DLID   1  // default destination link ID
+#define DEFAULT_QP_NUM 4  // default QP number 
+#define P_KEY          0xFFFF // do we need default value
+#define PKEY_IX        0x0 // do we need default value
+#define Q_KEY          0x012  // do we need default value 
+#define L_KEY          0x12345678 // do we need default value 
+#define R_KEY          0x87654321 // do we need default value 
+#define HCA_ID         "InfiniHost0" // default 
+#define START_PSN      0
+#define START_SQ_PSN   0
+#define START_RQ_PSN   0
+
+
+#define __u_long_long   unsigned long long
+
+#define         IBNAL_DEBUG      1
+
+#define         USE_SHARED_MEMORY_AND_SOCKET 1
+
+// operation type
+#define TRY_SEND_ONLY    1
+
+#define YES     1  
+#define NO      0 
+
+//
+// a common data structure for IB QP's operation
+// each QP is associated with an QP_info structure 
+//
+typedef struct QP_info 
+{
+  VAPI_hca_hndl_t       hca_hndl;      // HCA handle
+  IB_port_t             port;          // port number 
+  VAPI_qp_hndl_t        qp_hndl;       // QP's handle list 
+  VAPI_qp_state_t       qp_state;      // QP's current state 
+  VAPI_pd_hndl_t        pd_hndl;       // protection domain
+  VAPI_cq_hndl_t        cq_hndl;    // send-queue CQ's handle 
+  VAPI_cq_hndl_t        sq_cq_hndl;    // send-queue CQ's handle 
+  VAPI_cq_hndl_t        rq_cq_hndl;    // receive-queue CQ's handle
+  VAPI_ud_av_hndl_t     av_hndl;    // receive-queue CQ's handle
+  VAPI_qp_init_attr_t   qp_init_attr;  // QP's init attribute 
+  VAPI_qp_attr_t        qp_attr;       // QP's attribute - dlid 
+  VAPI_qp_prop_t        qp_prop;       // QP's propertities
+  VAPI_hca_port_t       hca_port;  
+  VAPI_qp_num_t         qp_num;    // QP's number 
+  VAPI_qp_num_t         rqp_num;       // remote QP's number 
+  IB_lid_t              slid;
+  IB_lid_t              dlid;
+  VAPI_gid_t            src_gid;
+
+  u_int32_t 	        buf_size;
+  VAPI_virt_addr_t      buf_addr;
+  char		       *bufptr;
+  VAPI_mrw_t            mr;       
+  VAPI_mr_hndl_t        mr_hndl;
+  VAPI_virt_addr_t      raddr;
+  VAPI_rkey_t           rkey;
+  VAPI_lkey_t           lkey;
+
+  VAPI_wr_id_t          last_posted_send_id; // user defined work request ID 
+  VAPI_wr_id_t          last_posted_rcv_id;  // user defined work request ID
+  VAPI_mw_hndl_t        mw_hndl;       // memory window handle 
+  VAPI_rkey_t           mw_rkey;       // memory window rkey
+  VAPI_sg_lst_entry_t   sg_lst[256];       // scatter and gather list 
+  int                   sg_list_sz;    // set as NUM_SGE
+  VAPI_wr_id_t          wr_id;         //
+  spinlock_t            snd_mutex;
+  spinlock_t            rcv_mutex;
+  spinlock_t            bl_mutex;
+  spinlock_t            cln_mutex;
+  int                   cur_RDMA_outstanding;
+  int                   cur_send_outstanding;
+  int                   cur_posted_rcv_bufs;
+  int                   snd_rcv_balance;
+} QP_info; 
+
+
+// buffer status 
+#define  BUF_REGISTERED   0x10000000 
+#define  BUF_INUSE 	  0x01000000  
+#define  BUF_UNREGISTERED 0x00100000 
+
+// buffer type 
+#define  REG_BUF          0x10000000
+#define  RDMA_BUF         0x01000000 
+
+//
+// IMM data 
+// 
+#define   IMM_000         (0 << 32); 
+#define   IMM_001         (1 << 32); 
+#define   IMM_002         (2 << 32); 
+#define   IMM_003         (3 << 32); 
+#define   IMM_004         (4 << 32); 
+#define   IMM_005         (5 << 32); 
+#define   IMM_006         (6 << 32); 
+#define   IMM_007         (7 << 32); 
+#define   IMM_008         (8 << 32); 
+#define   IMM_009         (9 << 32); 
+#define   IMM_010         (10 << 32); 
+#define   IMM_011         (11 << 32); 
+#define   IMM_012         (12 << 32); 
+#define   IMM_013         (13 << 32); 
+#define   IMM_014         (14 << 32); 
+#define   IMM_015         (15 << 32); 
+#define   IMM_016         (16 << 32); 
+#define   IMM_017         (17 << 32); 
+#define   IMM_018         (18 << 32); 
+#define   IMM_019         (19 << 32); 
+#define   IMM_020         (20 << 32); 
+#define   IMM_021         (21 << 32); 
+#define   IMM_022         (22 << 32); 
+#define   IMM_023         (23 << 32); 
+#define   IMM_024         (24 << 32); 
+#define   IMM_025         (25 << 32); 
+#define   IMM_026         (26 << 32); 
+#define   IMM_027         (27 << 32); 
+#define   IMM_028         (28 << 32); 
+#define   IMM_029         (29 << 32); 
+#define   IMM_030         (30 << 32); 
+#define   IMM_031         (31 << 32); 
+ 
+
+
+typedef struct Memory_buffer_info{
+	u_int32_t 	 buf_size;
+	VAPI_virt_addr_t buf_addr;
+	char		 *bufptr;
+	VAPI_mrw_t       mr;       
+	VAPI_mr_hndl_t   mr_hndl;
+        int              status;
+	int              ref_count;  
+        int              buf_type;
+	VAPI_virt_addr_t raddr;
+	VAPI_rkey_t      rkey;
+	VAPI_lkey_t      lkey;
+} Memory_buffer_info;
+
+typedef struct RDMA_Info_Exchange {
+	int               opcode;
+	int               buf_length;
+	VAPI_mrw_t        recv_rdma_mr;
+	VAPI_mr_hndl_t    recv_rdma_mr_hndl;
+	VAPI_mrw_t        send_rdma_mr;
+	VAPI_mr_hndl_t    send_rdma_mr_hndl;
+	VAPI_virt_addr_t  raddr;
+	VAPI_rkey_t       rkey;
+	int               flag;
+}  RDMA_Info_Exchange;
+
+// opcode for Rdma info exchange RTS/CTS 
+#define  Ready_To_send     0x10000000
+#define  Clear_To_send     0x01000000
+
+#define  RDMA_RTS_ID	   5555 
+#define  RDMA_CTS_ID	   7777 
+#define  RDMA_OP_ID	   9999 
+#define  SEND_RECV_TEST_ID 2222 
+#define  SEND_RECV_TEST_BUF_ID 0 
+
+#define  TEST_SEND_MESSAGE 0x00000001 
+#define  TEST_RECV_MESSAGE 0x00000002
+
+
+#define  RTS_CTS_TIMEOUT           50
+#define  RECEIVING_THREAD_TIMEOUT  50 
+#define  WAIT_FOR_SEND_BUF_TIMEOUT 50
+
+#define  IBNAL_DEBUG_LEVEL_1   0XFFFFFFFF  
+#define  IBNAL_DEBUG_LEVEL_2   D_PORTALS | D_NET   | D_WARNING | D_MALLOC | \ 
+			       D_ERROR   | D_OTHER | D_TRACE   | D_INFO
+			       
+
+// flag for Rdma info exhange 
+#define  RDMA_BUFFER_RESERVED       0x10000000
+#define  RDMA_BUFFER_UNAVAILABLE    0x01000000
+
+
+// receiving data structure 
+typedef struct {
+        ptl_hdr_t         *krx_buffer; // pointer to receiving buffer
+        unsigned long     krx_len;  // length of buffer
+        unsigned int      krx_size; // 
+        unsigned int      krx_priority; // do we need this 
+        struct list_head  krx_item;
+}  kibnal_rx_t;
+
+// transmitting data structure 
+typedef struct {
+        nal_cb_t      *ktx_nal;
+        void          *ktx_private;
+        lib_msg_t     *ktx_cookie;
+        char          *ktx_buffer;
+        size_t         ktx_len;
+        unsigned long  ktx_size;
+        int            ktx_ndx;
+        unsigned int   ktx_priority;
+        unsigned int   ktx_tgt_node;
+        unsigned int   ktx_tgt_port_id;
+}  kibnal_tx_t;
+
+
+typedef struct {
+        char              kib_init;
+        char              kib_shuttingdown;
+        IB_port_t         port_num; // IB port information
+        struct list_head  kib_list;
+        ptl_nid_t         kib_nid;
+        nal_t            *kib_nal; 
+        nal_cb_t         *kib_cb;
+        struct kib_trans *kib_trans; // do I need this 
+        struct tq_struct  kib_ready_tq;
+        spinlock_t        kib_dispatch_lock;
+}  kibnal_data_t;
+
+
+//
+// A data structure for keeping the HCA information in system
+// information related to HCA and hca_handle will be kept here 
+//
+typedef struct HCA_Info 
+{
+  VAPI_hca_hndl_t       hca_hndl;     // HCA handle
+  VAPI_pd_hndl_t        pd_hndl;      // protection domain
+  IB_port_t             port;         // port number 
+  int                   num_qp;       // number of qp used  
+  QP_info               *qp_ptr[NUM_QPS]; // point to QP_list
+  int                   num_cq;       // number of cq used 
+  VAPI_cq_hndl_t        cq_hndl;   
+  VAPI_cq_hndl_t        sq_cq_hndl;   
+  VAPI_cq_hndl_t        rq_cq_hndl;   
+  IB_lid_t              dlid;
+  IB_lid_t              slid;
+  kibnal_data_t         *kib_data; // for PORTALS operations
+} HCA_info;
+
+
+
+
+// Remote HCA Info information 
+typedef struct Remote_HCA_Info {
+        unsigned long     opcode;
+        unsigned long     length; 
+        IB_lid_t          dlid[NUM_QPS];
+        VAPI_qp_num_t     rqp_num[NUM_QPS];
+} Remote_QP_Info;
+
+typedef struct  Bucket_index{
+     int start;
+     int end;
+} Bucket_index;
+
+// functional prototypes 
+// infiniband initialization 
+int kib_init(kibnal_data_t *);
+
+// receiving thread 
+void kibnal_recv_thread(HCA_info *);
+void recv_thread(HCA_info *);
+
+// forward data packet 
+void kibnal_fwd_packet (void *, kpr_fwd_desc_t *);
+
+// global data structures 
+extern kibnal_data_t        kibnal_data;
+extern ptl_handle_ni_t      kibnal_ni;
+extern nal_t                kibnal_api;
+extern nal_cb_t             kibnal_lib;
+extern QP_info              QP_list[];
+extern QP_info              CQ_list[];
+extern HCA_info             Hca_data;
+extern VAPI_hca_hndl_t      Hca_hndl; 
+extern VAPI_pd_hndl_t       Pd_hndl;
+extern VAPI_hca_vendor_t    Hca_vendor;
+extern VAPI_hca_cap_t       Hca_cap;
+extern VAPI_hca_port_t      Hca_port_1_props;
+extern VAPI_hca_port_t      Hca_port_2_props;
+extern VAPI_hca_attr_t      Hca_attr;
+extern VAPI_hca_attr_mask_t Hca_attr_mask;
+extern VAPI_cq_hndl_t       Cq_SQ_hndl;   
+extern VAPI_cq_hndl_t       Cq_RQ_hndl;   
+extern VAPI_cq_hndl_t       Cq_hndl;   
+extern unsigned long        User_Defined_Small_Msg_Size;
+extern Remote_QP_Info      L_HCA_RDMA_Info;  
+extern Remote_QP_Info      R_HCA_RDMA_Info; 
+extern unsigned int         Num_posted_recv_buf;
+extern int                  R_RDMA_DATA_ARRIVED;
+extern Memory_buffer_info   MRbuf_list[];
+extern Memory_buffer_info   MSbuf_list[];
+extern Bucket_index         Bucket[]; 
+extern RDMA_Info_Exchange   Rdma_info;
+extern int                  Cts_Message_arrived;
+extern RDMA_Info_Exchange   Local_rdma_info;
+extern spinlock_t	    MSB_mutex[];
+
+
+
+// kernel NAL API function prototype 
+int  kibnal_forward(nal_t *,int ,void *,size_t ,void *,size_t );
+void kibnal_lock(nal_t *, unsigned long *);
+void kibnal_unlock(nal_t *, unsigned long *);
+int  kibnal_shutdown(nal_t *, int );
+void kibnal_yield( nal_t * );
+void kibnal_invalidate(nal_cb_t *,void *,size_t ,void *);
+int  kibnal_validate(nal_cb_t *,void *,size_t ,void  **);
+
+
+
+nal_t *kibnal_init(int , ptl_pt_index_t , ptl_ac_index_t , ptl_pid_t );
+void __exit kibnal_finalize(void ); 
+VAPI_ret_t create_qp(QP_info *, int );
+VAPI_ret_t init_qp(QP_info *, int );
+VAPI_ret_t IB_Open_HCA(kibnal_data_t *);
+VAPI_ret_t IB_Close_HCA(void );
+VAPI_ret_t createMemRegion(VAPI_hca_hndl_t, VAPI_pd_hndl_t); 
+VAPI_ret_t  deleteMemRegion(QP_info *, int );
+
+void ibnal_send_recv_self_testing(int *);
+
+int  __init kibnal_initialize(void);
+
+
+
+/* CB NAL functions */
+int kibnal_send(nal_cb_t *, 
+                void *, 
+                lib_msg_t *, 
+                ptl_hdr_t *,
+                int, 
+                ptl_nid_t, 
+                ptl_pid_t, 
+                unsigned int, 
+                ptl_kiov_t *, 
+                size_t);
+
+int kibnal_send_pages(nal_cb_t *, 
+                      void *, 
+                      lib_msg_t *, 
+                      ptl_hdr_t *,
+                      int, 
+                      ptl_nid_t, 
+                      ptl_pid_t, 
+                      unsigned int, 
+                      ptl_kiov_t *, 
+                      size_t);
+int kibnal_recv(nal_cb_t *, void *, lib_msg_t *,
+                        unsigned int, struct iovec *, size_t, size_t);
+int kibnal_recv_pages(nal_cb_t *, void *, lib_msg_t *,
+                        unsigned int, ptl_kiov_t *, size_t, size_t);
+int  kibnal_read(nal_cb_t *,void *,void *,user_ptr ,size_t );
+int  kibnal_write(nal_cb_t *,void *,user_ptr ,void *,size_t );
+int  kibnal_callback(nal_cb_t * , void *, lib_eq_t *, ptl_event_t *);
+void *kibnal_malloc(nal_cb_t *,size_t );
+void kibnal_free(nal_cb_t *,void *,size_t );
+int  kibnal_map(nal_cb_t *, unsigned int , struct iovec *, void **);
+void kibnal_unmap(nal_cb_t *, unsigned int , struct iovec *, void **);
+int  kibnal_map_pages(nal_cb_t *, unsigned int , ptl_kiov_t *, void **);
+void kibnal_unmap_pages(nal_cb_t * , unsigned int , ptl_kiov_t *, void **);
+void kibnal_printf(nal_cb_t *, const char *, ...);
+void kibnal_cli(nal_cb_t *,unsigned long *); 
+void kibnal_sti(nal_cb_t *,unsigned long *);
+int  kibnal_dist(nal_cb_t *,ptl_nid_t ,unsigned long *);
+
+void kibnal_fwd_packet (void *, kpr_fwd_desc_t *);
+void kibnal_rx(kibnal_data_t *, 
+               VAPI_virt_addr_t ,
+               u_int32_t,
+               u_int32_t,
+               unsigned int);
+                
+int  kibnal_end(kibnal_data_t *);
+
+void async_event_handler(VAPI_hca_hndl_t , VAPI_event_record_t *,void *);
+
+void CQE_event_handler(VAPI_hca_hndl_t ,VAPI_cq_hndl_t , void  *);
+
+
+VAPI_ret_t Send_Small_Msg(char *, int );
+VAPI_ret_t Send_Large_Msg(char *, int );
+
+VAPI_ret_t repost_recv_buf(QP_info *, VAPI_wr_id_t );
+int post_recv_bufs(VAPI_wr_id_t );
+int  server_listen_thread(void *);
+VAPI_wr_id_t RTS_handshaking_protocol(int );
+VAPI_wr_id_t CTS_handshaking_protocol(RDMA_Info_Exchange *);
+
+VAPI_ret_t createMemRegion_RDMA(VAPI_hca_hndl_t ,
+		                VAPI_pd_hndl_t  ,
+				char         *,
+				int             , 
+	                        VAPI_mr_hndl_t  *,
+		                VAPI_mrw_t      *);
+
+
+VAPI_ret_t IB_Set_Event_Handler(HCA_info , kibnal_data_t *);
+
+VAPI_ret_t IB_Set_Async_Event_Handler(HCA_info ,kibnal_data_t *);
+
+VAPI_wr_id_t find_available_buf(int );
+VAPI_wr_id_t search_send_buf(int );
+VAPI_wr_id_t find_filler_list(int ,int );
+int insert_MRbuf_list(int );
+
+
+#endif  /* _IBNAL_H */
diff --git a/lustre/portals/knals/ibnal/ibnal_cb.c b/lustre/portals/knals/ibnal/ibnal_cb.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c07cc4feacaa493fff748be4fe53f3e33a8e36b
--- /dev/null
+++ b/lustre/portals/knals/ibnal/ibnal_cb.c
@@ -0,0 +1,1288 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Based on ksocknal and qswnal
+ *
+ *  Author: Hsing-bung Chen <hbchen@lanl.gov>
+ *
+ *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals 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 Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "ibnal.h"
+
+
+
+
+RDMA_Info_Exchange   Rdma_nfo;
+int  Cts_Msg_Arrived = NO;
+
+
+/*
+ *  LIB functions follow
+ */
+
+//
+// read
+// copy a block of data from scr_addr to dst_addr 
+// it all happens in kernel space - dst_addr and src_addr 
+//
+// original definition is to read a block od data from a 
+// specified user address  
+// 
+// cb_read
+
+int kibnal_read (nal_cb_t *nal, 
+                 void     *private, 
+                 void     *dst_addr, 
+                 user_ptr src_addr, 
+                 size_t   len)
+{
+        CDEBUG(D_NET, "kibnal_read: 0x%Lx: reading %ld bytes from %p -> %p\n",
+               nal->ni.nid, (long)len, src_addr, dst_addr );
+
+        memcpy( dst_addr, src_addr, len );
+
+        return 0;
+}
+
+//
+// it seems that read and write are doing the same thing
+// because they all happen in kernel space 
+// why do we need two functions like read and write 
+// to make PORTALS API compatable 
+//
+
+//
+// write 
+// copy a block of data from scr_addr to dst_addr 
+// it all happens in kernel space - dst_addr and src_addr 
+//
+// original definition is to write a block od data to a 
+// specified user address  
+// 
+// cb_write
+
+int kibnal_write(nal_cb_t   *nal, 
+                 void       *private, 
+                 user_ptr   dst_addr, 
+                 void       *src_addr, 
+                 size_t     len)
+{
+        CDEBUG(D_NET, "kibnal_write: 0x%Lx: writing %ld bytes from %p -> %p\n",
+               nal->ni.nid, (long)len, src_addr, dst_addr );
+
+
+        memcpy( dst_addr, src_addr, len );
+
+        return 0;
+}
+
+//
+// malloc
+//
+// either vmalloc or kmalloc is used 
+// dynamically allocate a block of memory based on the size of buffer  
+//
+// cb_malloc
+
+void * kibnal_malloc(nal_cb_t *nal, size_t length)
+{
+        void *buffer;
+
+        // PORTAL_ALLOC will do the job 
+        // allocate a buffer with size "length"
+        PORTAL_ALLOC(buffer, length);
+
+        return buffer;
+}
+
+//
+// free
+// release a dynamically allocated memory pointed by buffer pointer 
+//
+// cb_free
+
+void kibnal_free(nal_cb_t *nal, void *buffer, size_t length)
+{
+        //
+        // release allocated buffer to system 
+        //
+        PORTAL_FREE(buffer, length);
+}
+
+//
+// invalidate 
+// because evernthing is in kernel space (LUSTRE)
+// there is no need to mark a piece of user memory as no longer in use by
+// the system
+//
+// cb_invalidate
+
+void kibnal_invalidate(nal_cb_t      *nal, 
+                              void          *base, 
+                              size_t        extent, 
+                              void          *addrkey)
+{
+  // do nothing 
+  CDEBUG(D_NET, "kibnal_invalidate: 0x%Lx: invalidating %p : %d\n", 
+                                        nal->ni.nid, base, extent);
+  return;
+}
+
+
+//
+// validate 
+// because everything is in kernel space (LUSTRE)
+// there is no need to mark a piece of user memory in use by
+// the system
+//
+// cb_validate
+
+int kibnal_validate(nal_cb_t        *nal,  
+                           void            *base, 
+                           size_t          extent, 
+                           void            **addrkey)
+{
+  // do nothing 
+  CDEBUG(D_NET, "kibnal_validate: 0x%Lx: validating %p : %d\n", 
+                                        nal->ni.nid, base, extent);
+
+  return 0;
+}
+
+
+//
+// log messages from kernel space 
+// printk() is used 
+//
+// cb_printf
+
+void kibnal_printf(nal_cb_t *nal, const char *fmt, ...)
+{
+        va_list ap;
+        char    msg[256];
+
+        if (portal_debug & D_NET) {
+                va_start( ap, fmt );
+                vsnprintf( msg, sizeof(msg), fmt, ap );
+                va_end( ap );
+
+                printk("CPUId: %d %s",smp_processor_id(), msg);
+        }
+}
+
+//
+// clear interrupt
+// use spin_lock to lock protected area such as MD, ME...
+// so a process can enter a protected area and do some works
+// this won't physicall disable interrup but use a software 
+// spin-lock to control some protected areas 
+//
+// cb_cli 
+
+void kibnal_cli(nal_cb_t *nal, unsigned long *flags) 
+{ 
+        kibnal_data_t *data= nal->nal_data;
+
+        CDEBUG(D_NET, "kibnal_cli \n");
+
+        spin_lock_irqsave(&data->kib_dispatch_lock,*flags);
+
+}
+
+//
+// set interrupt
+// use spin_lock to unlock protected area such as MD, ME...
+// this won't physicall enable interrup but use a software 
+// spin-lock to control some protected areas 
+//
+// cb_sti
+
+void kibnal_sti(nal_cb_t *nal, unsigned long *flags)
+{
+        kibnal_data_t *data= nal->nal_data;
+
+        CDEBUG(D_NET, "kibnal_sti \n");
+
+        spin_unlock_irqrestore(&data->kib_dispatch_lock,*flags);
+}
+
+
+
+//
+// nic distance 
+// 
+// network distance doesn't mean much for this nal 
+// here we only indicate 
+//      0 - operation is happened on the same node 
+//      1 - operation is happened on different nodes 
+//          router will handle the data routing 
+//
+// cb_dist
+
+int kibnal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
+{
+        CDEBUG(D_NET, "kibnal_dist \n");
+
+        if ( nal->ni.nid == nid ) {
+                *dist = 0;
+        } 
+        else {
+                *dist = 1;
+        }
+
+        return 0; // always retrun 0 
+}
+
+
+//
+// This is the cb_send() on IB based interconnect system
+// prepare a data package and use VAPI_post_sr() to send it
+// down-link out-going message 
+//
+
+
+int
+kibnal_send(nal_cb_t        *nal,
+            void            *private,
+            lib_msg_t       *cookie,
+            ptl_hdr_t       *hdr,
+            int              type,
+            ptl_nid_t        nid,
+            ptl_pid_t        pid,
+            unsigned int     niov,
+            ptl_kiov_t      *iov,
+            size_t           len)
+{
+        
+        int           rc=0;
+        void         *buf = NULL; 
+        unsigned long buf_length = sizeof(ptl_hdr_t) + len;
+        int           expected_buf_size = 0;
+        VAPI_ret_t    vstat;
+
+        PROF_START(kibnal_send); // time stamp send start 
+
+        CDEBUG(D_NET,"kibnal_send: sending %d bytes from %p to nid: 0x%Lx pid %d\n",
+               buf_length, iov, nid, HCA_PORT_1);
+
+
+        // do I need to check the gateway information
+        // do I have problem to send direct 
+        // do I have to forward a data packet to gateway
+        // 
+        // The current connection is back-to-back 
+        // I always know that data will be send from one-side to
+        // the other side
+        //
+        
+        //
+        //  check data buffer size 
+        //
+        //  MSG_SIZE_SMALL 
+        //      regular post send 
+        //  
+        //  MSG_SIZE_LARGE
+        //      rdma write
+        
+        if(buf_length <= SMALL_MSG_SIZE) {  
+           expected_buf_size = MSG_SIZE_SMALL;
+        } 
+        else { 
+          if(buf_length > MAX_MSG_SIZE) { 
+             CERROR("kibnal_send:request exceeds Transmit data size (%d).\n",
+                      MAX_MSG_SIZE);
+             rc = -1;
+             return rc;
+          }
+          else {
+             expected_buf_size = MSG_SIZE_LARGE; // this is a large data package 
+          } 
+        }
+                
+        // prepare data packet for send operation 
+        //
+        // allocate a data buffer "buf" with size of buf_len(header + payload)
+        //                 ---------------
+        //  buf            | hdr         |  size = sizeof(ptl_hdr_t)
+        //                 --------------
+        //                 |payload data |  size = len
+        //                 ---------------
+        
+        // copy header to buf 
+        memcpy(buf, hdr, sizeof(ptl_hdr_t));
+
+        // copy payload data from iov to buf
+        // use portals library function lib_copy_iov2buf()
+        
+        if (len != 0)
+           lib_copy_iov2buf(((char *)buf) + sizeof (ptl_hdr_t),
+                            niov, 
+                            iov, 
+                            len);
+
+        // buf is ready to do a post send 
+        // the send method is base on the buf_size 
+
+        CDEBUG(D_NET,"ib_send %d bytes (size %d) from %p to nid: 0x%Lx "
+               " port %d\n", buf_length, expected_buf_size, iov, nid, HCA_PORT_1);
+
+        switch(expected_buf_size) {
+          case MSG_SIZE_SMALL:
+            // send small message 
+            if((vstat = Send_Small_Msg(buf, buf_length)) != VAPI_OK){
+                CERROR("Send_Small_Msg() is failed\n");
+            } 
+            break;
+
+          case MSG_SIZE_LARGE:
+            // send small message 
+            if((vstat = Send_Large_Msg(buf, buf_length)) != VAPI_OK){
+                CERROR("Send_Large_Msg() is failed\n");
+            } 
+            break;
+
+          default:
+            CERROR("Unknown message size %d\n", expected_buf_size);
+            break;
+        }
+
+        PROF_FINISH(kibnal_send); // time stapm of send operation 
+
+        rc = 1;
+
+        return rc; 
+}
+
+//
+// kibnal_send_pages
+//
+// no support 
+//
+// do you need this 
+//
+int kibnal_send_pages(nal_cb_t * nal, 
+                      void *private, 
+                      lib_msg_t * cookie,
+                      ptl_hdr_t * hdr, 
+                      int type, 
+                      ptl_nid_t nid, 
+                      ptl_pid_t pid,
+                      unsigned int niov, 
+                      ptl_kiov_t *iov, 
+                      size_t mlen)
+{
+   int rc = 1;
+
+   CDEBUG(D_NET, "kibnal_send_pages\n");
+
+   // do nothing now for Infiniband 
+   
+   return rc;
+}
+
+
+
+
+
+//
+// kibnal_fwd_packet 
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
+{
+        CDEBUG(D_NET, "forwarding not implemented\n");
+        return;
+      
+}
+
+//
+// kibnal_callback 
+//
+// no support 
+//
+// do you need this 
+//
+int kibnal_callback(nal_cb_t * nal, 
+                           void *private, 
+                           lib_eq_t *eq,
+                           ptl_event_t *ev)
+{
+        CDEBUG(D_NET,  "callback not implemented\n");
+        return PTL_OK;
+}
+
+
+/* Process a received portals packet */
+//
+//  conver receiving data in to PORTALS header 
+//
+
+void kibnal_rx(kibnal_data_t    *kib, 
+                      VAPI_virt_addr_t buffer_addr,
+                      u_int32_t        buffer_len,
+                      u_int32_t        buffer_size,
+                      unsigned int     priority) 
+{
+        ptl_hdr_t  *hdr = (ptl_hdr_t *)  buffer_addr; // case to ptl header format 
+        kibnal_rx_t krx;
+
+        CDEBUG(D_NET,"kibnal_rx: buf %p, len %ld\n", buffer_addr, buffer_len);
+
+        if ( buffer_len < sizeof( ptl_hdr_t ) ) {
+                /* XXX what's this for? */
+                if (kib->kib_shuttingdown)
+                        return;
+                CERROR("kibnal_rx: did not receive complete portal header, "
+                       "len= %ld", buffer_len);
+
+                return;
+        }
+
+       // typedef struct {
+       //         char             *krx_buffer; // pointer to receiving buffer
+       //         unsigned long     krx_len;  // length of buffer
+       //         unsigned int      krx_size; //
+       //         unsigned int      krx_priority; // do we need this
+       //         struct list_head  krx_item;
+       // } kibnal_rx_t;
+       //
+        krx.krx_buffer    = hdr;
+        krx.krx_len       = buffer_len;
+        krx.krx_size      = buffer_size;
+        krx.krx_priority  = priority;
+
+        if ( hdr->dest_nid == kibnal_lib.ni.nid ) {
+           // this is my data 
+           PROF_START(lib_parse);
+
+           lib_parse(&kibnal_lib, (ptl_hdr_t *)krx.krx_buffer, &krx);
+
+           PROF_FINISH(lib_parse);
+        } else {
+           /* forward to gateway */
+           // Do we expect this happened ?
+           //      
+           CERROR("kibnal_rx: forwarding not implemented yet");
+        }
+
+        return;
+}
+
+
+
+
+//
+// kibnal_recv_pages 
+//
+// no support 
+//
+// do you need this 
+//
+int
+kibnal_recv_pages(nal_cb_t * nal, 
+                  void *private, 
+                  lib_msg_t * cookie,
+                  unsigned int niov, 
+                  ptl_kiov_t *iov, 
+                  size_t mlen,
+                  size_t rlen)
+{
+
+  CDEBUG(D_NET, "recv_pages not implemented\n");
+  return PTL_OK;
+       
+}
+
+
+int 
+kibnal_recv(nal_cb_t     *nal,
+            void         *private,
+            lib_msg_t    *cookie,
+            unsigned int  niov,
+            struct iovec *iov,
+            size_t        mlen,
+            size_t        rlen)
+{
+        kibnal_rx_t *krx = private;
+
+        CDEBUG(D_NET,"kibnal_recv: mlen=%d, rlen=%d\n", mlen, rlen);
+
+        /* What was actually received must be >= what sender claims to
+         * have sent.  This is an LASSERT, since lib-move doesn't
+         * check cb return code yet. */
+        LASSERT (krx->krx_len >= sizeof (ptl_hdr_t) + rlen);
+        LASSERT (mlen <= rlen);
+
+        PROF_START(kibnal_recv);
+
+        if(mlen != 0) {
+                PROF_START(memcpy);
+                lib_copy_buf2iov (niov, iov, krx->krx_buffer +
+                                  sizeof (ptl_hdr_t), mlen);
+                PROF_FINISH(memcpy);
+        }
+
+        PROF_START(lib_finalize);
+        
+        lib_finalize(nal, private, cookie);
+        
+        PROF_FINISH(lib_finalize);
+        PROF_FINISH(kibnal_recv);
+
+        return rlen;
+}
+
+//
+// kibnal_map 
+// no support 
+// do you need this 
+//
+int kibnal_map(nal_cb_t * nal, 
+               unsigned int niov, 
+               struct iovec *iov,
+               void **addrkey)
+{
+  CDEBUG(D_NET, "map not implemented\n");
+  return PTL_OK; 
+}
+
+
+
+//
+// kibnal_unmap
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_unmap(nal_cb_t * nal, 
+                  unsigned int niov, 
+                  struct iovec *iov,
+                  void **addrkey)
+{
+  CDEBUG(D_NET, "unmap not implemented\n");
+  return;
+}
+
+
+
+//
+// kibnal_map_pages 
+// no support 
+// do you need this 
+/* as (un)map, but with a set of page fragments */
+int kibnal_map_pages(nal_cb_t * nal, 
+                     unsigned int niov, 
+                     ptl_kiov_t *iov,
+                     void **addrkey)
+{
+  CDEBUG(D_NET, "map_pages not implemented\n");
+  return PTL_OK;
+}
+
+
+
+//
+// kibnal_unmap_pages 
+//
+// no support 
+//
+// do you need this 
+//
+void kibnal_unmap_pages(nal_cb_t * nal, 
+                               unsigned int niov, 
+                               ptl_kiov_t *iov,
+                               void **addrkey)
+{
+  CDEBUG(D_NET, "unmap_pages not implemented\n");
+  return ;
+}
+
+
+int kibnal_end(kibnal_data_t *kib)
+{
+
+  /* wait for sends to finish ? */
+  /* remove receive buffers */
+  /* shutdown receive thread */
+
+  CDEBUG(D_NET, "kibnal_end\n");
+  IB_Close_HCA();
+
+  return 0;
+}
+
+
+//
+//
+//  asynchronous event handler: response to some unexpetced operation errors 
+//    
+//  void async_event_handler(VAPI_hca_hndl_t      hca_hndl,
+//                           VAPI_event_record_t *event_record_p,
+//                           void*                private_data)
+//  the HCA drive will prepare evetn_record_p                        
+//
+//  this handler is registered with VAPI_set_async_event_handler()
+//  VAPI_set_async_event_handler() is issued when an HCA is created 
+//
+//
+void async_event_handler(VAPI_hca_hndl_t      hca_hndl,
+                         VAPI_event_record_t *event_record_p,  
+                         void*                private_data)
+{
+  //
+  // * event_record_p is prepared by the system when an async
+  //   event happened
+  // * what to do with private_data 
+  // * do we expect more async events happened if so what are they 
+  //
+  //   only log ERROR message now 
+
+  switch (event_record_p->type) {
+    case VAPI_PORT_ERROR:
+         printk("Got PORT_ERROR event. port number=%d\n", 
+                 event_record_p->modifier.port_num);
+         break;
+    case VAPI_PORT_ACTIVE:
+         printk("Got PORT_ACTIVE event. port number=%d\n", 
+                 event_record_p->modifier.port_num);
+         break;
+    case VAPI_QP_PATH_MIGRATED:    /*QP*/
+         printk("Got P_PATH_MIGRATED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_EEC_PATH_MIGRATED:   /*EEC*/
+         printk("Got EEC_PATH_MIGRATED event. eec_hndl=%d\n", 
+                 event_record_p->modifier.eec_hndl);
+         break;
+    case VAPI_QP_COMM_ESTABLISHED: /*QP*/
+         printk("Got QP_COMM_ESTABLISHED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_EEC_COMM_ESTABLISHED: /*EEC*/
+         printk("Got EEC_COMM_ESTABLISHED event. eec_hndl=%d\n",
+                 event_record_p->modifier.eec_hndl);
+         break;
+    case VAPI_SEND_QUEUE_DRAINED:  /*QP*/
+         printk("Got SEND_QUEUE_DRAINED event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_CQ_ERROR:            /*CQ*/
+         printk("Got CQ_ERROR event. cq_hndl=%lu\n", 
+                 event_record_p->modifier.cq_hndl);
+         break;
+    case VAPI_LOCAL_WQ_INV_REQUEST_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_INV_REQUEST_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_WQ_ACCESS_VIOL_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_ACCESS_VIOL_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_WQ_CATASTROPHIC_ERROR: /*QP*/
+         printk("Got LOCAL_WQ_CATASTROPHIC_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_PATH_MIG_REQ_ERROR:  /*QP*/
+         printk("Got PATH_MIG_REQ_ERROR event. qp_hndl=%lu\n", 
+                 event_record_p->modifier.qp_hndl);
+         break;
+    case VAPI_LOCAL_CATASTROPHIC_ERROR: /*none*/
+         printk("Got LOCAL_CATASTROPHIC_ERROR event. \n");
+         break;
+    default:
+         printk(":got non-valid event type=%d. IGNORING\n",
+                    event_record_p->type);
+  }
+
+}
+
+
+
+
+VAPI_wr_id_t 
+search_send_buf(int buf_length)
+{
+  VAPI_wr_id_t send_id = -1;
+  u_int32_t    i;
+  int          flag = NO;
+  int          loop_count = 0;  
+
+  CDEBUG(D_NET, "search_send_buf \n");
+  
+  while((flag == NO) && (loop_count < MAX_LOOP_COUNT)) {
+    for(i=0; i < NUM_ENTRY; i++) {
+      // problem about using spinlock
+      spin_lock(&MSB_mutex[i]);
+      if(MSbuf_list[i].status == BUF_REGISTERED)  {
+        MSbuf_list[i].status = BUF_INUSE;// make send buf as inuse
+        flag =  YES;
+        spin_unlock(&MSB_mutex[i]);
+        break;
+      }
+      else
+        spin_unlock(&MSB_mutex[i]); 
+    }
+
+    loop_count++;
+    schedule_timeout(200); // wait for a while 
+  }
+   
+  if(flag == NO)  {
+    CDEBUG(D_NET, "search_send_buf: could not locate an entry in MSbuf_list\n");
+  }
+
+  send_id = (VAPI_wr_id_t ) i;
+
+  return send_id;
+}
+
+
+
+VAPI_wr_id_t 
+search_RDMA_recv_buf(int buf_length)
+{
+  VAPI_wr_id_t recv_id = -1;
+  u_int32_t    i;
+  int          flag = NO;
+  int          loop_count = 0;  
+
+  CDEBUG(D_NET, "search_RDMA_recv_buf\n");
+
+  while((flag == NO) && (loop_count < MAX_LOOP_COUNT)) {
+
+    for(i=NUM_ENTRY; i < NUM_MBUF; i++) {
+
+      spin_lock(&MSB_mutex[i]);
+
+      if((MRbuf_list[i].status == BUF_REGISTERED)  &&
+         (MRbuf_list[i].buf_size >= buf_length)) {
+          MSbuf_list[i].status = BUF_INUSE;// make send buf as inuse
+          flag =  YES;
+          spin_unlock(&MSB_mutex[i]);
+          break;
+      }
+      else
+        spin_unlock(&MSB_mutex[i]);
+    }
+
+    loop_count++;
+
+    schedule_timeout(200); // wait for a while 
+  }
+   
+  if(flag == NO)  {
+    CERROR("search_RDMA_recv_buf: could not locate an entry in MBbuf_list\n");
+  }
+
+  recv_id = (VAPI_wr_id_t ) i;
+
+  return recv_id;
+
+}
+
+
+
+
+
+
+
+VAPI_ret_t Send_Small_Msg(char *buf, int buf_length)
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+
+ CDEBUG(D_NET, "Send_Small_Msg\n");
+
+ send_id = search_send_buf(buf_length); 
+
+ if(send_id < 0){
+   CERROR("Send_Small_Msg: Can not find a QP \n");
+   return(~VAPI_OK);
+ }
+
+ qp = &QP_list[(int) send_id];
+
+ // find a suitable/registered send_buf from MSbuf_list
+ CDEBUG(D_NET, "Send_Small_Msg: current send id  %d \n", send_id);
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        =  send_id;
+
+
+ // scatter and gather info 
+ sr_sg.len  = buf_length;
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, buf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ CDEBUG(D_NET, "VAPI_post_sr success.\n");
+
+ return (vstat);
+
+}
+
+
+
+
+VAPI_wr_id_t
+RTS_handshaking_protocol(int buf_length) 
+{
+
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ VAPI_wr_id_t         send_id;
+
+ RDMA_Info_Exchange   rdma_info;
+
+ rdma_info.opcode     = Ready_To_send;
+ rdma_info.buf_length = buf_length; 
+ rdma_info.raddr      = (VAPI_virt_addr_t) 0;
+ rdma_info.rkey       = (VAPI_rkey_t) 0 ; 
+
+ QP_info              *qp;
+
+ CDEBUG(D_NET, "RTS_handshaking_protocol\n");
+
+ // find a suitable/registered send_buf from MSbuf_list
+ send_id = search_send_buf(sizeof(RDMA_Info_Exchange));   
+
+ qp = &QP_list[(int) send_id];
+
+ CDEBUG(D_NET, "RTS_CTS: current send id  %d \n", send_id);
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        = send_id + RDMA_RTS_ID;// this RTS mesage ID 
+
+ // scatter and gather info 
+ sr_sg.len  = sizeof(RDMA_Info_Exchange);
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, &rdma_info, sizeof(RDMA_Info_Exchange));
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this RTS message data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("RTS: VAPI_post_sr failed (%s).\n",VAPI_strerror_sym(vstat));
+ }
+
+ return send_id;
+
+}
+
+
+
+// create local receiving Memory Region for a HCA
+VAPI_ret_t
+createMemRegion_RDMA(VAPI_hca_hndl_t  hca_hndl,
+                     VAPI_pd_hndl_t   pd_hndl,
+                     char            *bufptr,
+                     int              buf_length,
+                     VAPI_mr_hndl_t   *rep_mr_hndl,
+                     VAPI_mrw_t       *rep_mr)
+{
+  VAPI_ret_t      vstat;
+  VAPI_mrw_t      mrw;
+  
+  CDEBUG(D_NET, "createMemRegion_RDMA\n");
+
+  // memory region address and size of memory region
+  // allocate a block of memory for this HCA 
+  // RDMA data buffer
+  
+  
+  if(bufptr == NULL) {
+    // need to allcate a local buffer to receive data from a
+    // remore VAPI_RDMA_WRITE_IMM
+    PORTAL_ALLOC(bufptr, buf_length);
+  }
+
+  if(bufptr == NULL) {
+    CDEBUG(D_MALLOC, "Failed to malloc a block of RDMA receiving memory, size %d\n",
+                                    buf_length);
+    return(VAPI_ENOMEM);
+  }
+
+  /* Register RDAM data Memory region */
+  CDEBUG(D_NET, "Register a RDMA data memory region\n");
+
+  mrw.type   = VAPI_MR;
+  mrw.pd_hndl= pd_hndl;
+  mrw.start  = (VAPI_virt_addr_t )(MT_virt_addr_t )bufptr;
+  mrw.size   = buf_length;
+  mrw.acl    = VAPI_EN_LOCAL_WRITE  | 
+               VAPI_EN_REMOTE_WRITE | 
+               VAPI_EN_REMOTE_READ;
+
+  // register send memory region
+  vstat = VAPI_register_mr(hca_hndl,
+                           &mrw,
+                           rep_mr_hndl,
+                           rep_mr);
+
+  // this memory region is going to be reused until deregister is called
+  if (vstat != VAPI_OK) {
+     CERROR("Failed registering a mem region Addr=%p, Len=%d. %s\n",
+             bufptr, buf_length, VAPI_strerror(vstat));
+  }
+
+  return(vstat);
+
+}
+
+
+
+RDMA_Info_Exchange  Local_rdma_info;
+
+int insert_MRbuf_list(int buf_lenght)
+{
+  int  recv_id = NUM_ENTRY;      
+
+  CDEBUG(D_NET, "insert_MRbuf_list\n");
+
+  for(recv_id= NUM_ENTRY; recv_id < NUM_MBUF; recv_id++){
+       if(BUF_UNREGISTERED == MRbuf_list[recv_id].status)  {
+         MRbuf_list[recv_id].status   = BUF_UNREGISTERED;
+         MRbuf_list[recv_id].buf_size = buf_lenght;
+         break;
+       }
+  }
+
+  return recv_id;
+
+}  
+
+VAPI_wr_id_t
+CTS_handshaking_protocol(RDMA_Info_Exchange *rdma_info) 
+{
+
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info             *qp;
+ VAPI_wr_id_t         send_id;
+ VAPI_mr_hndl_t       rep_mr_hndl;
+ VAPI_mrw_t           rep_mr;
+ int                  recv_id;
+ char                *bufptr = NULL;
+
+ // search MRbuf_list for an available entry that
+ // has registered data buffer with size equal to rdma_info->buf_lenght
+
+ CDEBUG(D_NET, "CTS_handshaking_protocol\n");
+
+ // register memory buffer for RDAM operation
+
+ vstat = createMemRegion_RDMA(Hca_hndl,
+                              Pd_hndl,
+                              bufptr, 
+                              rdma_info->buf_length,
+                              &rep_mr_hndl,
+                              &rep_mr);
+
+
+ Local_rdma_info.opcode            = Clear_To_send;
+ Local_rdma_info.recv_rdma_mr      = rep_mr;
+ Local_rdma_info.recv_rdma_mr_hndl = rep_mr_hndl;
+
+ if (vstat != VAPI_OK) {
+    CERROR("CST_handshaking_protocol: Failed registering a mem region"
+           "Len=%d. %s\n", rdma_info->buf_length, VAPI_strerror(vstat));
+    Local_rdma_info.flag = RDMA_BUFFER_UNAVAILABLE;
+ }
+ else {
+    // successfully allcate reserved RDAM data buffer 
+    recv_id = insert_MRbuf_list(rdma_info->buf_length);   
+
+    if(recv_id >=  NUM_ENTRY) { 
+      MRbuf_list[recv_id].buf_addr     = rep_mr.start;
+      MRbuf_list[recv_id].mr           = rep_mr;
+      MRbuf_list[recv_id].mr_hndl      = rep_mr_hndl;
+      MRbuf_list[recv_id].ref_count    = 0;
+      Local_rdma_info.flag             = RDMA_BUFFER_RESERVED;
+      Local_rdma_info.buf_length       = rdma_info->buf_length; 
+      Local_rdma_info.raddr            = rep_mr.start;
+      Local_rdma_info.rkey             = rep_mr.r_key; 
+    }
+    else {
+      CERROR("Can not find an entry in MRbuf_list - how could this happen\n");  
+    }
+ }
+
+ // find a suitable/registered send_buf from MSbuf_list
+ send_id = search_send_buf(sizeof(RDMA_Info_Exchange)); 
+ CDEBUG(D_NET, "CTS: current send id  %d \n", send_id);
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+ sr_desc.id        = send_id + RDMA_CTS_ID; // this CST message ID 
+
+ // scatter and gather info 
+ sr_sg.len  = sizeof(RDMA_Info_Exchange);
+ sr_sg.lkey = MSbuf_list[send_id].mr.l_key; // use send MR 
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[send_id].buf_addr;
+
+ // copy data to register send buffer 
+ memcpy(&sr_sg.addr, &Local_rdma_info, sizeof(RDMA_Info_Exchange));
+
+ sr_desc.sg_lst_p   = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used 
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+ // call VAPI_post_sr to send out this RTS message data 
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+    CERROR("CTS: VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+
+}
+
+
+
+VAPI_ret_t Send_Large_Msg(char *buf, int buf_length)
+{
+  VAPI_ret_t           vstat;
+  VAPI_sr_desc_t       sr_desc;
+  VAPI_sg_lst_entry_t  sr_sg;
+  QP_info             *qp;
+  VAPI_mrw_t           rep_mr; 
+  VAPI_mr_hndl_t       rep_mr_hndl;
+  int                  send_id;
+  VAPI_imm_data_t      imm_data = 0XAAAA5555;
+
+
+  CDEBUG(D_NET, "Send_Large_Msg: Enter\n");
+
+  // register this large buf 
+  // don't need to copy this buf to send buffer
+  vstat = createMemRegion_RDMA(Hca_hndl,
+                               Pd_hndl,
+                               buf,
+                               buf_length,
+                               &rep_mr_hndl,
+                               &rep_mr);
+
+  if (vstat != VAPI_OK) {
+    CERROR("Send_Large_M\sg:  createMemRegion_RDMAi() failed (%s).\n",
+                        VAPI_strerror(vstat));
+  }
+  
+
+  Local_rdma_info.send_rdma_mr      = rep_mr;
+  Local_rdma_info.send_rdma_mr_hndl = rep_mr_hndl;
+
+  //
+  //     Prepare descriptor for send queue
+  //
+ 
+  // ask for a remote rdma buffer with size buf_lenght
+  send_id = RTS_handshaking_protocol(buf_length); 
+
+  qp = &QP_list[send_id];
+
+  // wait for CTS message receiving from remote node 
+  while(1){
+     if(YES == Cts_Message_arrived) {
+        // receive CST message from remote node 
+        // Rdma_info is available for use
+        break;
+     }
+     schedule_timeout(RTS_CTS_TIMEOUT);
+  }
+  
+  sr_desc.id        = send_id + RDMA_OP_ID;
+  sr_desc.opcode    = VAPI_RDMA_WRITE_WITH_IMM;
+  sr_desc.comp_type = VAPI_SIGNALED;
+
+  // scatter and gather info 
+  sr_sg.len  = buf_length;
+
+  // rdma mr 
+  sr_sg.lkey = rep_mr.l_key;  
+  sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) rep_mr.start;
+  sr_desc.sg_lst_p = &sr_sg;
+  sr_desc.sg_lst_len = 1; // only 1 entry is used 
+
+  // immediate data - not used here 
+  sr_desc.imm_data = imm_data;
+  sr_desc.fence = TRUE;
+  sr_desc.set_se = FALSE;
+
+  // RDAM operation only
+  // raddr and rkey is receiving from remote node  
+  sr_desc.remote_addr = Rdma_info.raddr;
+  sr_desc.r_key       = Rdma_info.rkey;
+
+  // call VAPI_post_sr to send out this data 
+  vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+  if (vstat != VAPI_OK) {
+     CERROR("VAPI_post_sr failed (%s).\n",VAPI_strerror_sym(vstat));
+  }
+
+}
+
+
+
+
+
+
+//
+//  repost_recv_buf
+//  post a used recv buffer back to recv WQE list 
+//  wrq_id is used to indicate the starting position of recv-buffer 
+//
+VAPI_ret_t 
+repost_recv_buf(QP_info      *qp,
+                VAPI_wr_id_t  wrq_id) 
+{
+  VAPI_rr_desc_t       rr;
+  VAPI_sg_lst_entry_t  sg_entry;
+  VAPI_ret_t           ret;
+
+  CDEBUG(D_NET, "repost_recv_buf\n");
+
+  sg_entry.lkey = MRbuf_list[wrq_id].mr.l_key;
+  sg_entry.len  = MRbuf_list[wrq_id].buf_size;
+  sg_entry.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[wrq_id].buf_addr;
+  rr.opcode     = VAPI_RECEIVE;
+  rr.comp_type  = VAPI_SIGNALED; /* All with CQE (IB compliant) */
+  rr.sg_lst_len = 1; /* single buffers */
+  rr.sg_lst_p   = &sg_entry;
+  rr.id         = wrq_id; /* WQE id used is the index to buffers ptr array */
+
+  ret= VAPI_post_rr(qp->hca_hndl,qp->qp_hndl,&rr);
+     
+  if (ret != VAPI_OK){
+     CERROR("failed reposting RQ WQE (%s) buffer \n",VAPI_strerror_sym(ret));
+     return ret;
+  }
+
+  CDEBUG(D_NET, "Successfully reposting an RQ WQE %d recv bufer \n", wrq_id);
+
+  return ret ;
+}
+			
+//
+// post_recv_bufs
+// 	post "num_o_bufs" for receiving data
+//      each receiving buf (buffer starting address, size of buffer)
+//      each buffer is associated with an id 
+//
+int 
+post_recv_bufs(VAPI_wr_id_t  start_id)
+{
+  int i;
+  VAPI_rr_desc_t       rr;
+  VAPI_sg_lst_entry_t  sg_entry;
+  VAPI_ret_t           ret;
+
+  CDEBUG(D_NET, "post_recv_bufs\n");
+
+  for(i=0; i< NUM_ENTRY; i++) {
+    sg_entry.lkey = MRbuf_list[i].mr.l_key;
+    sg_entry.len  = MRbuf_list[i].buf_size;
+    sg_entry.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MRbuf_list[i].buf_addr;
+    rr.opcode     = VAPI_RECEIVE;
+    rr.comp_type  = VAPI_SIGNALED;  /* All with CQE (IB compliant) */
+    rr.sg_lst_len = 1; /* single buffers */
+    rr.sg_lst_p   = &sg_entry;
+    rr.id         = start_id+i; /* WQE id used is the index to buffers ptr array */
+
+    ret= VAPI_post_rr(QP_list[i].hca_hndl,QP_list[i].qp_hndl, &rr);
+    if (ret != VAPI_OK) {
+       CERROR("failed posting RQ WQE (%s)\n",VAPI_strerror_sym(ret));
+       return i;
+    } 
+  }
+
+  return i; /* num of buffers posted */
+}
+			
+int 
+post_RDMA_bufs(QP_info      *qp, 
+               void         *buf_array,
+               unsigned int  num_bufs,
+               unsigned int  buf_size,
+               VAPI_wr_id_t  start_id)
+{
+
+  CDEBUG(D_NET, "post_RDMA_bufs \n");
+  return YES;
+}
+
+
+
+//
+// LIB NAL
+// assign function pointers to theirs corresponding entries
+//
+
+nal_cb_t kibnal_lib = {
+        nal_data:       &kibnal_data,  /* NAL private data */
+        cb_send:        kibnal_send,
+        cb_send_pages:  NULL, // not implemented  
+        cb_recv:        kibnal_recv,
+        cb_recv_pages:  NULL, // not implemented 
+        cb_read:        kibnal_read,
+        cb_write:       kibnal_write,
+        cb_callback:    NULL, // not implemented 
+        cb_malloc:      kibnal_malloc,
+        cb_free:        kibnal_free,
+        cb_map:         NULL, // not implemented 
+        cb_unmap:       NULL, // not implemented 
+        cb_map_pages:   NULL, // not implemented 
+        cb_unmap_pages: NULL, // not implemented 
+        cb_printf:      kibnal_printf,
+        cb_cli:         kibnal_cli,
+        cb_sti:         kibnal_sti,
+        cb_dist:        kibnal_dist // no used at this moment 
+};
diff --git a/lustre/portals/knals/ibnal/ibnal_send_recv_self_testing.c b/lustre/portals/knals/ibnal/ibnal_send_recv_self_testing.c
new file mode 100644
index 0000000000000000000000000000000000000000..82defdba876d0bf3ce03f66809031e157bdffaf4
--- /dev/null
+++ b/lustre/portals/knals/ibnal/ibnal_send_recv_self_testing.c
@@ -0,0 +1,116 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *  *
+ *  * Based on ksocknal, qswnal, and gmnal
+ *  *
+ *  * Copyright (C) 2003 LANL
+ *  *   Author: HB Chen <hbchen@lanl.gov>
+ *  *   Los Alamos National Lab
+ *  *
+ *  *   Portals is free software; you can redistribute it and/or
+ *  *   modify it under the terms of version 2 of the GNU General Public
+ *  *   License as published by the Free Software Foundation.
+ *  *
+ *  *   Portals 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 Portals; if not, write to the Free Software
+ *  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  *
+ *  */
+
+#include "ibnal.h"
+
+
+
+VAPI_ret_t ibnal_send_recv_self_testing()
+{
+ VAPI_ret_t           vstat;
+ VAPI_sr_desc_t       sr_desc;
+ VAPI_sg_lst_entry_t  sr_sg;
+ QP_info              *qp;
+ VAPI_wr_id_t         send_id;
+ int                  buf_id;
+ char                 sbuf[KB_32];
+ char                 rbuf[KB_32];
+ int                  i;
+ int                  buf_length = KB_32;
+ VAPI_wc_desc_t       comp_desc;
+ int                  num_send = 1;
+ int                  loop_count = 0;
+
+
+ printk("ibnal_send_recv_self_testing\n");
+
+ memset(&sbuf, 'a', KB_32);
+ memset(&rbuf, ' ', KB_32);
+ 
+ send_id = 2222; 
+ buf_id = 0;
+
+ qp = &QP_list[0];
+
+ sr_desc.opcode    = VAPI_SEND;
+ sr_desc.comp_type = VAPI_SIGNALED;
+
+ // scatter and gather info
+ sr_sg.len  = KB_32;
+ sr_sg.lkey = MSbuf_list[buf_id].mr.l_key; // use send MR
+ sr_sg.addr = (VAPI_virt_addr_t)(MT_virt_addr_t) MSbuf_list[buf_id].buf_addr;
+
+ // copy data to register send buffer
+ memcpy(&sr_sg.addr, &buf, buf_length);
+
+ sr_desc.sg_lst_p = &sr_sg;
+ sr_desc.sg_lst_len = 1; // only 1 entry is used
+ sr_desc.fence = TRUE;
+ sr_desc.set_se = FALSE;
+
+
+ // call VAPI_post_sr to send out this data
+ vstat = VAPI_post_sr(qp->hca_hndl, qp->qp_hndl, &sr_desc);
+
+ if (vstat != VAPI_OK) {
+   printk("VAPI_post_sr failed (%s).\n",VAPI_strerror(vstat));
+ }
+
+ printk("VAPI_post_sr success.\n");
+
+ // poll for completion
+
+ while( loop_count < 100 ){
+   vstat = VAPI_poll_cq(qp->hca_hndl, qp->cq_hndl, &comp_desc);
+   if( vstat == VAPI_OK ) {
+       if(comp_desc.opcode == VAPI_CQE_SQ_SEND_DATA ) {
+          /* SEND completion */
+         printk("received SQ completion\n");
+       }
+       else { 
+          if(comp_desc.opcode == VAPI_CQE_RQ_SEND_DATA ) {
+	    /* RECEIVE completion */
+            printk("received RQ completion\n");
+            memcpy(&rbuf, (char *) MRbuf_list[buf_id].buf_addar, KB_32);
+	    
+	    int n;
+
+	    n = memcmp($sbuf, &rbuf, KB_32);
+	    printk("compare sbuf and rbuf  n = %d\n", n); 
+	    
+          }
+       	  else  {
+            printk("unexpected completion opcode %d \n", comp_desc.opcode);
+	  }
+       }
+   }
+
+   loop_count++; 
+   schedule_timeout(500);
+ }
+
+ printk("end of ibnal_self_send_recv_testing\n");
+
+
+}
diff --git a/lustre/portals/knals/ibnal/uagent.c b/lustre/portals/knals/ibnal/uagent.c
new file mode 100644
index 0000000000000000000000000000000000000000..d7e939ae97880022db10ed5395cea884375a4191
--- /dev/null
+++ b/lustre/portals/knals/ibnal/uagent.c
@@ -0,0 +1,391 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+
+#include <linux/shm.h>
+#include <linux/ipc.h>
+#include <linux/stat.h>
+#include <linux/types.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+// Infiniband VAPI/EVAPI header files Mellanox MT23108 VAPI
+#include <vapi.h>
+#include <vapi_types.h>
+#include <vapi_common.h>
+#include <evapi.h>
+
+// Remote HCA Info information
+ typedef struct Remote_HCA_Info {
+       unsigned long     opcode;
+       unsigned long     length;
+       IB_lid_t          dlid[256];
+       VAPI_qp_num_t     rqp_num[256];
+       VAPI_rkey_t       rkey;   // for remote RDAM request
+       unsigned long     vaddr1; // virtual address fisrt 4 bytes
+       unsigned long     vaddr2; // virtual address second 4 bytes
+       u_int32_t         size;   // size of RDMA memory buffer
+       char              dest_ip[256]; //destination server IP address 
+ } Remote_HCA_Info;
+
+#define SHARED_SEGMENT_SIZE  0x10000 // 16KB shared memory between U and K
+
+// some internals opcodes for IB operations used in IBNAL
+#define SEND_QP_INFO          0X00000001
+#define RECV_QP_INFO          0X00000010
+#define DEFAULT_SOCKET_PORT   11211 
+#define LISTEN_QUEUE_SIZE     2048 
+#define DEST_IP		      "10.128.105.26"
+
+// server_thread
+// + wait for an incoming connection from remote node 
+// + receive remote HCA's data 
+//
+//
+//
+//
+// 
+void *server_thread(void *vargp)
+{
+  Remote_HCA_Info   *hca_data;
+  Remote_HCA_Info   hca_data_buffer;
+  
+  int    serverfd;
+  int    infd;
+  struct hostent  *hp;
+  struct sockaddr_in serveraddr;
+  struct sockaddr_in clientaddr;
+  int    sin_size=sizeof(struct sockaddr_in);
+  int	 bytes_recv;
+  int    i;
+
+
+  hca_data = (Remote_HCA_Info *) vargp;
+  
+  if((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    printf("server_thread couldnot create a socket \n");
+    pthread_exit((void *) 0);
+  }
+ 
+  printf("server_thread create a socket \n");
+
+  bzero((char *) &serveraddr, sizeof(serveraddr));
+
+  serveraddr.sin_family = AF_INET;
+  serveraddr.sin_addr.s_addr = htons(INADDR_ANY);
+  serveraddr.sin_port = htons((unsigned short) DEFAULT_SOCKET_PORT);
+  
+  if(bind(serverfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr)) < 0) {
+    printf("server_thread couldnot bind to a socket \n");
+    pthread_exit((void *) 0);
+  }
+
+  printf("server_thread bind to a socket \n");
+
+  if(listen(serverfd, LISTEN_QUEUE_SIZE) < 0) {
+    printf("server_thread couldnot listen to a socket \n");
+    pthread_exit((void *) 0);
+  }
+
+  printf("server_thread listen to a socket \n");
+
+  //
+  // I only expect to receive one HCA data from a remote HCA 
+  //
+  printf("server_thread: Waiting for a connection\n");
+  infd= accept(serverfd,(struct sockaddr*)&clientaddr,&sin_size);
+  printf("server_thread: Got an incoming connection");
+
+  /* receive data from socket into buffer */
+  bytes_recv = recv(infd,
+                    &hca_data_buffer,  
+                    sizeof(Remote_HCA_Info),
+		    0);
+
+  if(bytes_recv > 0) {
+/*	  
+      printf("server_thread receive data\n");
+      printf("opcode is 0x%X\n", hca_data_buffer.opcode);
+      printf("length is 0x%X\n", hca_data_buffer.length);
+
+      for(i=0; i < 256; i++) {
+        printf("dlid %d is 0x%X\n", i, hca_data_buffer.dlid[i]);
+        printf("rqp_num %d is 0x%X\n", hca_data_buffer.rqp_num[i]);
+      }
+
+      printf("rkey is 0x%X\n", hca_data_buffer.rkey);
+      printf("vaddr1 is 0x%X\n", hca_data_buffer.vaddr1);
+      printf("vaddr2 is 0x%X\n", hca_data_buffer.vaddr2);
+      printf("size is 0x%X\n", hca_data_buffer.size);
+      printf("After conversion hton \n");
+      printf("opcode is 0x%X\n", htonl(hca_data_buffer.opcode));
+      printf("length is 0x%X\n", htonl(hca_data_buffer.length));
+
+      for(i=0; i < 256; i++) {
+        printf("dlid %d is 0x%X\n", htons(hca_data_buffer.dlid[i]));
+        printf("rqp_num %d is 0x%X\n", htonl(hca_data_buffer.rqp_num[i]));
+      }
+
+      printf("rkey is 0x%X\n", htonl(hca_data_buffer.rkey));
+      printf("vaddr1 is 0x%X\n", htonl(hca_data_buffer.vaddr1));
+      printf("vaddr2 is 0x%X\n", htonl(hca_data_buffer.vaddr2));
+      printf("size is 0x%X\n", htonl(hca_data_buffer.size));
+*/     
+
+      hca_data->opcode  = ntohl(hca_data_buffer.opcode); // long 
+      hca_data->length  = ntohl(hca_data_buffer.length); // long
+
+      for(i=0; i < 256; i++) {
+        hca_data->dlid[i]    = ntohs(hca_data_buffer.dlid[i]);   // u_int16
+        hca_data->rqp_num[i] = ntohl(hca_data_buffer.rqp_num[i]);// u_int32
+      }
+
+      hca_data->rkey    = ntohl(hca_data_buffer.rkey);   // u_int32
+      hca_data->vaddr1  = ntohl(hca_data_buffer.vaddr1); // first word u_int32
+      hca_data->vaddr2  = ntohl(hca_data_buffer.vaddr2); // second word u_int32
+      hca_data->size    = ntohl(hca_data_buffer.size);   // u_int32
+    }
+    else {
+      printf("server_thread receive ERROR bytes_recv = %d\n", bytes_recv);
+    }
+
+    close(infd);
+    close(serverfd);
+
+  printf("server_thread EXIT \n");
+      
+  pthread_exit((void *) 0);
+
+}
+
+//
+// client_thread 
+// + connect to a remote server_thread
+// + send local HCA's data to remote server_thread
+//
+void *client_thread(void *vargp)
+{
+
+  Remote_HCA_Info   *hca_data;
+  Remote_HCA_Info   hca_data_buffer;
+
+  int    clientfd;
+  struct hostent  *hp;
+  struct sockaddr_in clientaddr;
+  int    bytes_send;
+  int    i;
+  
+  hca_data = (Remote_HCA_Info *) vargp;
+
+  if((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    printf("client_thread couldnot create a socket \n");
+    pthread_exit((void *) 0);
+  }
+ 
+  printf("client_thread create a socket \n");
+  
+  bzero((char *) &clientaddr, sizeof(clientaddr));
+
+  clientaddr.sin_family = AF_INET;
+  clientaddr.sin_addr.s_addr = inet_addr(hca_data->dest_ip);
+  printf("client_thread get server Ip address = %s\n", hca_data->dest_ip);
+  clientaddr.sin_port = htons((unsigned short) DEFAULT_SOCKET_PORT);
+  memset(&(clientaddr.sin_zero), '\0', 8);
+
+  connect(clientfd, (struct sockaddr *) &clientaddr, sizeof(struct sockaddr));
+
+  printf("client_thread connect to  server Ip address = %s\n", hca_data->dest_ip);
+
+  hca_data_buffer.opcode  = htonl(hca_data->opcode); // long 
+  hca_data_buffer.length  = htonl(hca_data->length); // long
+
+  for(i=0; i < 256; i++) {
+    hca_data_buffer.dlid[i]    = htons(hca_data->dlid[i]);   // u_int16
+    hca_data_buffer.rqp_num[i] = htonl(hca_data->rqp_num[i]);// u_int32
+  }
+
+  hca_data_buffer.rkey    = htonl(hca_data->rkey);   // u_int32
+  hca_data_buffer.vaddr1  = htonl(hca_data->vaddr1); // first word u_int32
+  hca_data_buffer.vaddr2  = htonl(hca_data->vaddr2); // second word u_int32
+  hca_data_buffer.size    = htonl(hca_data->size);   // u_int32
+ 
+  bytes_send = send(clientfd, & hca_data_buffer, sizeof(Remote_HCA_Info), 0); 
+  
+  if(bytes_send == sizeof(Remote_HCA_Info)) {
+    printf("client_thread: send successfully \n");
+  }
+  else {
+    printf("client_thread: send failed \n");
+  }
+
+  printf("client_thread EXIT \n");
+
+  pthread_exit((void *) 0);
+}
+
+
+//
+//  main 
+//  + create a shared-memory between this main()/user address and
+//    a kernel thread/kernel address space associated with inbal 
+//    kernel module 
+//  + access local HCA's data through this shared memory 
+//
+//  + create a server_thread for receiving remote HCA's data
+//  + create a client_thread for sending out local HCA's data
+//  + after receiving remote HCA's data update this shared memory
+//
+int  main(int argc , char *argv[])
+{
+  int              segment_id;
+  struct shmid_ds  shmbuffer;
+  int              segment_size;
+  const int        shared_segment_size = sizeof(Remote_HCA_Info);
+  key_t            key = 999;
+  unsigned long    raddr;
+  Remote_HCA_Info  *shared_memory;
+  Remote_HCA_Info  exchange_hca_data;
+  Remote_HCA_Info  remote_hca_data;
+  int i; 
+
+  /* pthread */
+  pthread_t          sid;
+  pthread_t          cid;
+  pthread_attr_t     attr; 
+  int                rc, status;
+
+  char dest_ip[256];
+
+  if(argc != 2) {
+	  printf("USAGE:   uagent   server_ip_address\n");
+	  printf("argc = %d \n", argc);
+	  exit(1);
+  }
+
+  strcpy(&exchange_hca_data.dest_ip[0], argv[1]);
+  printf("the destinational server IP address = %s\n", 
+		                       &exchange_hca_data.dest_ip); 
+
+  segment_id =  shmget(key, shared_segment_size, IPC_CREAT | 0666);
+
+  printf("sys_shmget is done segment_id = %d\n", segment_id);
+
+  shared_memory = (Remote_HCA_Info *) shmat(segment_id, 0, 0);
+
+  if(shared_memory == (char *) -1) {
+    printf("Shared memory attach failed shared_memory=%p\n",shared_memory);
+    exit(0);
+  }
+
+  printf("shared menory attached at address %p\n", shared_memory);
+
+  while (1) {
+    if(shared_memory->opcode ==  SEND_QP_INFO) {
+      printf("Local HCA data received from kernel thread\n");
+      break;
+    }
+    usleep(1000);
+    continue;
+  }
+
+  printf("Local HCA data received from kernel thread\n");
+
+  // save local HCA's data in exchange_hca_data
+  //
+  exchange_hca_data.opcode  = shared_memory->opcode;
+  exchange_hca_data.length  = shared_memory->length;
+
+  for(i=0; i < 256; i++) {
+    exchange_hca_data.dlid[i]    = shared_memory->dlid[i];
+    exchange_hca_data.rqp_num[i] = shared_memory->rqp_num[i];
+  }
+
+  exchange_hca_data.rkey    = shared_memory->rkey;
+  exchange_hca_data.vaddr1  = shared_memory->vaddr1;
+  exchange_hca_data.vaddr2  = shared_memory->vaddr2;
+  exchange_hca_data.size    = shared_memory->size;
+
+  /* Initialize and set thread detached attribute */
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+  /* create a server thread for procsssing incoming remote node socket data */
+  // 
+  pthread_create(&sid, 
+		  &attr, 
+		  server_thread,
+		  (Remote_HCA_Info *) &remote_hca_data);
+
+  printf("Main: created a server thread \n");
+
+  sleep(10);
+  
+  /* create a clint thread to send out local HCA data to remote node */
+  pthread_create(&cid, 
+		  &attr, 
+		  client_thread,
+		  (Remote_HCA_Info *) &exchange_hca_data);
+
+  printf("Main: created a client  thread \n");
+
+  /* synchronization between server_thread and client_thread */
+  pthread_attr_destroy(&attr);
+
+  rc = pthread_join(sid, (void **) &status);
+  if(rc) {
+    printf("Error: return code from pthread_join() is %d\n", rc);
+    exit(-1);
+  }
+
+  printf("completed join with thread %d status = %d\n", sid, status);
+
+  rc = pthread_join(cid, (void **) &status);
+  if(rc) {
+    printf("Error: return code from pthread_join() is %d\n", rc);
+    exit(-1);
+  }
+  printf("completed join with thread %d status = %d\n", cid, status);
+
+  // update shared memory with remote HCA's data 
+
+  shared_memory->opcode = RECV_QP_INFO;
+  shared_memory->length = remote_hca_data.length;
+  for(i=0; i < 256; i++) {
+    shared_memory->dlid[i]   = remote_hca_data.dlid[i];
+    shared_memory->rqp_num[i]= remote_hca_data.rqp_num[i];
+  }
+  shared_memory->rkey   = remote_hca_data.rkey;
+  shared_memory->vaddr1 = remote_hca_data.vaddr1;
+  shared_memory->vaddr2 = remote_hca_data.vaddr2;
+  shared_memory->size   = remote_hca_data.size;
+
+  sleep(5);
+
+  shared_memory->opcode = RECV_QP_INFO;
+  shared_memory->length = remote_hca_data.length;
+  for(i=0; i < 256; i++) {
+    shared_memory->dlid[i]   = remote_hca_data.dlid[i];
+    shared_memory->rqp_num[i]= remote_hca_data.rqp_num[i];
+  }
+  
+  shared_memory->rkey   = remote_hca_data.rkey;
+  shared_memory->vaddr1 = remote_hca_data.vaddr1;
+  shared_memory->vaddr2 = remote_hca_data.vaddr2;
+  shared_memory->size   = remote_hca_data.size;
+
+  sleep(10);
+  
+//  shmdt(shared_memory);
+   
+  printf("uagent is DONE \n");
+  
+ 
+
+  exit(0);
+
+}
+
diff --git a/lustre/portals/knals/lgmnal/Makefile.am b/lustre/portals/knals/lgmnal/Makefile.am
deleted file mode 100644
index 6794494ecbf180bfb08e6e23da13d9c62fd045ed..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2001  Cluster File Systems, Inc.
-#
-# This code is issued under the GNU General Public License.
-# See the file COPYING in this distribution
-
-include ../../Rules.linux
-
-MODULE = lgmnal
-modulenet_DATA = lgmnal.o
-EXTRA_PROGRAMS = lgmnal
-
-DEFS =
-lgmnal_SOURCES = lgmnal.h lgmnal_api.c lgmnal_cb.c lgmnal_comm.c lgmnal_utils.c lgmnal_module.c
diff --git a/lustre/portals/knals/lgmnal/lgmnal.h b/lustre/portals/knals/lgmnal/lgmnal.h
deleted file mode 100644
index 8b496ec1880a947c2e65538d835ff6e69ee6a669..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	Portals GM kernel NAL header file
- *	This file makes all declaration and prototypes 
- *	for the API side and CB side of the NAL
- */
-#ifndef __INCLUDE_LGMNAL_H__
-#define __INCLUDE_LGMNAL_H__
-
-#include "linux/config.h"
-#include "linux/module.h"
-#include "linux/tty.h"
-#include "linux/kernel.h"
-#include "linux/mm.h"
-#include "linux/string.h"
-#include "linux/stat.h"
-#include "linux/errno.h"
-#include "linux/locks.h"
-#include "linux/unistd.h"
-#include "linux/init.h"
-#include "linux/sem.h"
-#include "linux/vmalloc.h"
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
-
-
-#include "portals/nal.h"
-#include "portals/api.h"
-#include "portals/errno.h"
-#include "linux/kp30.h"
-#include "portals/p30.h"
-
-#include "portals/lib-nal.h"
-#include "portals/lib-p30.h"
-
-#define GM_STRONG_TYPES 1
-#include "gm.h"
-#include "gm_internal.h"
-
-
-/*
- *	Defines for the API NAL
- */
-
-
-
-/*
- *	Small message size is configurable
- *	insmod can set small_msg_size
- *	which is used to populate nal_data.small_msg_size
- */
-#define LGMNAL_SMALL_MESSAGE		1078
-#define LGMNAL_LARGE_MESSAGE_INIT	1079
-#define LGMNAL_LARGE_MESSAGE_ACK	1080
-#define LGMNAL_LARGE_MESSAGE_FINI	1081
-
-extern  int lgmnal_small_msg_size;
-#define LGMNAL_SMALL_MSG_SIZE(a)	a->small_msg_size
-#define LGMNAL_IS_SMALL_MESSAGE(n,a,b,c)	lgmnal_is_small_message(n, a, b, c)
-#define LGMNAL_MAGIC	0x1234abcd
-
-typedef struct _lgmnal_hash {
-		void *key;
-		void *data;
-		struct _lgmnal_hash	*next;
-	} lgmnal_hash_t;
-
-/*
- *	Small Transmit Descriptor
- *	A structre to keep track of a small transmit operation
- *	This structure has a one-to-one relationship with a small
- *	transmit buffer (both create by lgmnal_stxd_alloc). 
- *	stxd has pointer to txbuffer and the hash table in nal_data
- *	allows us to go the other way.
- */
-typedef struct _lgmnal_stxd_t {
-	void 	*buffer;		/* Address of small wired buffer this decriptor uses */
-	int	size;			/* size (in bytes) of the tx buffer this descripto uses */
-	gm_size_t	gmsize;		/* gmsize of the tx buffer this descripto uses */
-	int	type;			/* large or small message */
-	struct _lgmnal_data_t *nal_data;
-	lib_msg_t	*cookie;	/* the cookie the portals library gave us */
-	int	niov;
-	struct iovec	iov[PTL_MD_MAX_IOV];
-	struct _lgmnal_stxd_t	*next;
-} lgmnal_stxd_t;
-
-/*
- *	as for lgmnal_stxd_t 
- */
-typedef struct _lgmnal_srxd_t {
-	void 	*buffer;
-	int	size;
-	gm_size_t	gmsize;
-	int	type;
-	struct _lgmnal_srxd_t	*next;
-} lgmnal_srxd_t;
-
-/*
- *	Header which lmgnal puts at the start of each message
- */
-typedef struct	_lgmnal_msghdr {
-	int	magic;
-	int 	type;
-	unsigned int	sender_node_id;
-	lgmnal_stxd_t	*stxd;
-	} lgmnal_msghdr_t;
-#define LGMNAL_MSGHDR_SIZE	sizeof(lgmnal_msghdr_t)
-
-/* 
- *	There's one of these for each interface that is initialised
- *	There's a maximum of LGMNAL_NUM_IF lgmnal_data_t
- */
-
-typedef struct _lgmnal_data_t {
-	int	refcnt;
-#ifdef LGMNAL_API_LOCK_SPIN
-	spinlock_t	api_lock;	/* lock provided for api->lock function */
-#else
-	struct semaphore api_lock;
-#endif
-	spinlock_t	cb_lock;	/* lock provided for cb_cli function */
-	char		_cb_file[128];
-	char		_cb_function[128];
-	int		_cb_line;
-	spinlock_t 	stxd_lock;	/* lock to add or remove stxd to/from free list */
-	struct semaphore stxd_token;	/* Don't try to access the list until get a token */
-	lgmnal_stxd_t	*stxd;		/* list of free stxd's */
-#ifdef LGMNAL_USE_GM_HASH
-	struct gm_hash	*stxd_hash;	/* hash to translate txbuffer to stxd. Created in stxd_alloc */
-#else
-	lgmnal_hash_t	*stxd_hash;	/* hash to translate txbuffer to stxd. Created in stxd_alloc */
-#endif
-	spinlock_t 	srxd_lock;
-	struct semaphore srxd_token;
-	lgmnal_srxd_t	*srxd;
-#ifdef LGMNAL_USE_GM_HASH
-	struct gm_hash	*srxd_hash;
-#else
-	lgmnal_hash_t	*srxd_hash;
-#endif
-	nal_t		*nal;		/* our API NAL */
-	nal_cb_t	*nal_cb;	/* our CB nal */
-	struct gm_port	*gm_port;	/* the gm port structure we open in lgmnal_init */
-	unsigned int	gm_local_nid;	/* our gm local node id */
-	unsigned int	gm_global_nid;	/* our gm global node id */
-	spinlock_t 	gm_lock;	/* GM is not threadsage */
-	long		rxthread_pid;	/* thread id of our receiver thread */
-	int		rxthread_flag;	/* stop the thread flag	*/
-	gm_alarm_t	rxthread_alarm;	/* used to wake sleeping rx thread */
-	int		small_msg_size;
-	int		small_msg_gmsize;
-	char		_file[128];
-	char		_function[128];
-	int		_line;
-} lgmnal_data_t;
-
-/*
- *	For nal_data->rxthread_flag
- */
-#define LGMNAL_THREAD_START	444	
-#define LGMNAL_THREAD_STARTED	333
-#define LGMNAL_THREAD_CONTINUE	777
-#define LGMNAL_THREAD_STOP	666
-#define LGMNAL_THREAD_STOPPED	555
-
-#define LGMNAL_NUM_IF 	1
-
-#if 0
-/*
- *	A global structre to maintain 1 nal_data structure for each 
- *	myrinet card that the user initialises (only tested for 1)
- *	To add or remove any nal_data structures from the ifs arrary the 
- *	init_lock must be acquired. This is the only time this lock is acquired
- */
-typedef struct _lgmnal_global_t {
-	int 	debug_level;
-	struct	semaphore	init_lock;
-	lgmnal_data_t		*ifs[LGMNAL_NUM_IF];
-} lgmnal_global_t;
-
-extern lgmnal_data_t	global_nal_data;
-#define LGMNAL_DEBUG_LEVEL	lgmnal_global.debug_level
-#else
-extern lgmnal_data_t	*global_nal_data;
-extern int	lgmnal_debug_level;
-#define LGMNAL_DEBUG_LEVEL	lgmnal_debug_level
-#endif
-
-/*
- *	The gm_port to use for lgmnal
- */
-#define LGMNAL_GM_PORT	4
-
-/*
- * for ioctl get pid
- */
-#define LGMNAL_IOC_GET_GNID 1	
-
-/*
- *	LGMNAL_DEBUG_LEVEL set by module load 0<debug_level<4
- *	Increase it to get more debug info
- */	
-
-#define LGMNAL_DEBUG 1
-#ifdef LGMNAL_DEBUG
-#define LGMNAL_PRINT(level, args)	if (LGMNAL_DEBUG_LEVEL >= level) lgmnal_print args
-#else
-#define LGMNAL_PRINT(level, args)
-#endif
-
-#define LGMNAL_DEBUG_ERR 1	/* only report errors */
-#define LGMNAL_DEBUG_TRACE 2	/* on entering function */
-#define LGMNAL_DEBUG_V 3	/* debug */
-#define LGMNAL_DEBUG_VV 4	/* more debug */
-
-/*
- *	Return codes
- */
-#define LGMNAL_STATUS_OK	0
-#define LGMNAL_STATUS_FAIL	1
-#define LGMNAL_STATUS_NOMEM	2
-
-
-/*
- *	FUNCTION PROTOTYPES
- */
-
-/*
- *	Locking macros
- */
-
-/*
- *	To access the global structure
- *	to add or remove interface (lgmnal_init) or shutdown only
- */
-#define LGMNAL_GLOBAL_LOCK_INIT	sema_init(&(lgmnal_global.init_lock), 1)
-#define LGMNAL_GLOBAL_LOCK	do {	\
-				LGMNAL_PRINT(1, ("Acquiring global mutex\n")); \
-				down(&(lgmnal_global.init_lock)); \
-				LGMNAL_PRINT(1, ("Got global lock\n")); \
-				} while (0)
-#define LGMNAL_GLOBAL_UNLOCK	do {		\
-				LGMNAL_PRINT(1, ("Releasing global mutex\n")); \
-				up(&(lgmnal_global.init_lock)); \
-				LGMNAL_PRINT(1, ("Release global mutex\n")); \
-				} while (0)
-
-/*
- *	For the API lock function
- */
-#ifdef LGMNAL_API_LOCK_SPIN
-#define LGMNAL_API_LOCK_INIT(a)		spin_lock_init(&a->api_lock)
-#define LGMNAL_API_LOCK(a)		spin_lock(&a->api_lock)
-#define LGMNAL_API_UNLOCK(a)		spin_unlock(&a->api_lock)
-#else
-#define LGMNAL_API_LOCK_INIT(a)		sema_init(&a->api_lock, 1)
-#define LGMNAL_API_LOCK(a)		down(&a->api_lock)
-#define LGMNAL_API_UNLOCK(a)		up(&a->api_lock)
-#endif
-
-/*
- *	For the Small tx and rx descriptor lists
- */
-#define LGMNAL_TXD_LOCK_INIT(a)			spin_lock_init(&a->stxd_lock);
-#define LGMNAL_TXD_LOCK(a)			spin_lock(&a->stxd_lock);
-#define LGMNAL_TXD_UNLOCK(a)			spin_unlock(&a->stxd_lock);
-#define LGMNAL_TXD_TOKEN_INIT(a, n)		sema_init(&a->stxd_token, n);
-#define LGMNAL_TXD_GETTOKEN(a)			down(&a->stxd_token);
-#define LGMNAL_TXD_TRYGETTOKEN(a)		down_trylock(&a->stxd_token)
-#define LGMNAL_TXD_RETURNTOKEN(a)		up(&a->stxd_token);
-
-
-#define LGMNAL_RXD_LOCK_INIT(a)			spin_lock_init(&a->srxd_lock);
-#define LGMNAL_RXD_LOCK(a)			spin_lock(&a->srxd_lock);
-#define LGMNAL_RXD_UNLOCK(a)			spin_unlock(&a->srxd_lock);
-#define LGMNAL_RXD_TOKEN_INIT(a, n)		sema_init(&a->srxd_token, n);
-#define LGMNAL_RXD_GETTOKEN(a)			down(&a->srxd_token);
-#define LGMNAL_RXD_TRYGETTOKEN(a)		down_trylock(&a->srxd_token)
-#define LGMNAL_RXD_RETURNTOKEN(a)		up(&a->srxd_token);
-
-#define LGMNAL_GM_LOCK_INIT(a)			spin_lock_init(&a->gm_lock);
-#define LGMNAL_GM_LOCK(a)			do { \
-							while (!spin_trylock(&a->gm_lock)) { \
-								LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("waiting %s:%s:%d holder %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__, nal_data->_function, nal_data->_file, nal_data->_line)); \
-								lgmnal_yield(128); \
-							} \
-								LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Locked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
-								sprintf(nal_data->_function, "%s", __FUNCTION__); \
-								sprintf(nal_data->_file, "%s", __FILE__); \
-								nal_data->_line = __LINE__; \
-						} while (0)
-#define LGMNAL_GM_UNLOCK(a)			do { \
-							spin_unlock(&a->gm_lock); \
-							memset(nal_data->_function, 0, 128); \
-							memset(nal_data->_file, 0, 128); \
-							nal_data->_line = 0; \
-							LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("GM Unlocked %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__)); \
-						} while(0);
-
-#define LGMNAL_CB_LOCK_INIT(a)			spin_lock_init(&a->cb_lock);
-
-
-/*
- *	API NAL
- */
-int lgmnal_api_forward(nal_t *, int, void *, size_t, void *, size_t);
-
-int lgmnal_api_shutdown(nal_t *, int);
-
-int lgmnal_api_validate(nal_t *, void *, size_t);
-
-void lgmnal_api_yield(nal_t *);
-
-void lgmnal_api_lock(nal_t *, unsigned long *);
-
-void lgmnal_api_unlock(nal_t *, unsigned long *);
-
-
-#define LGMNAL_INIT_NAL(a)	do { 	\
-				a->forward = lgmnal_api_forward; \
-				a->shutdown = lgmnal_api_shutdown; \
-				a->validate = NULL; \
-				a->yield = lgmnal_api_yield; \
-				a->lock = lgmnal_api_lock; \
-				a->unlock = lgmnal_api_unlock; \
-				a->timeout = NULL; \
-				a->refct = 1; \
-				a->nal_data = NULL; \
-				} while (0)
-
-
-/*
- *	CB NAL
- */
-
-int lgmnal_cb_send(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
-	int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec *, size_t);
-
-int lgmnal_cb_send_pages(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *,
-	int, ptl_nid_t, ptl_pid_t, unsigned int, ptl_kiov_t *, size_t);
-
-int lgmnal_cb_recv(nal_cb_t *, void *, lib_msg_t *, 
-	unsigned int, struct iovec *, size_t, size_t);
-
-int lgmnal_cb_recv_pages(nal_cb_t *, void *, lib_msg_t *, 
-	unsigned int, ptl_kiov_t *, size_t, size_t);
-
-int lgmnal_cb_read(nal_cb_t *, void *private, void *, user_ptr, size_t);
-
-int lgmnal_cb_write(nal_cb_t *, void *private, user_ptr, void *, size_t);
-
-int lgmnal_cb_callback(nal_cb_t *, void *, lib_eq_t *, ptl_event_t *);
-
-void *lgmnal_cb_malloc(nal_cb_t *, size_t);
-
-void lgmnal_cb_free(nal_cb_t *, void *, size_t);
-
-void lgmnal_cb_unmap(nal_cb_t *, unsigned int, struct iovec*, void **);
-
-int  lgmnal_cb_map(nal_cb_t *, unsigned int, struct iovec*, void **); 
-
-void lgmnal_cb_printf(nal_cb_t *, const char *fmt, ...);
-
-void lgmnal_cb_cli(nal_cb_t *, unsigned long *);
-
-void lgmnal_cb_sti(nal_cb_t *, unsigned long *);
-
-int lgmnal_cb_dist(nal_cb_t *, ptl_nid_t, unsigned long *);
-
-nal_t *lgmnal_init(int, ptl_pt_index_t, ptl_ac_index_t, ptl_pid_t rpid);
-
-void  lgmnal_fini(void);
-
-
-
-#define LGMNAL_INIT_NAL_CB(a)	do {	\
-				a->cb_send = lgmnal_cb_send; \
-				a->cb_send_pages = lgmnal_cb_send_pages; \
-				a->cb_recv = lgmnal_cb_recv; \
-				a->cb_recv_pages = lgmnal_cb_recv_pages; \
-				a->cb_read = lgmnal_cb_read; \
-				a->cb_write = lgmnal_cb_write; \
-				a->cb_callback = lgmnal_cb_callback; \
-				a->cb_malloc = lgmnal_cb_malloc; \
-				a->cb_free = lgmnal_cb_free; \
-				a->cb_map = NULL; \
-				a->cb_unmap = NULL; \
-				a->cb_printf = lgmnal_cb_printf; \
-				a->cb_cli = lgmnal_cb_cli; \
-				a->cb_sti = lgmnal_cb_sti; \
-				a->cb_dist = lgmnal_cb_dist; \
-				a->nal_data = NULL; \
-				} while (0)
-
-/*
- *	lgmnal utilities
- */
-
-void lgmnal_print(const char *, ...);
-
-/*
- *	Small Transmit and Receive Descriptor Functions
- */
-int  lgmnal_alloc_stxd(lgmnal_data_t *);
-void lgmnal_free_stxd(lgmnal_data_t *);
-lgmnal_stxd_t* lgmnal_get_stxd(lgmnal_data_t *, int);
-void lgmnal_return_stxd(lgmnal_data_t *, lgmnal_stxd_t *);
-
-int  lgmnal_alloc_srxd(lgmnal_data_t *);
-void lgmnal_free_srxd(lgmnal_data_t *);
-lgmnal_srxd_t* lgmnal_get_srxd(lgmnal_data_t *, int);
-void lgmnal_return_srxd(lgmnal_data_t *, lgmnal_srxd_t *);
-
-/*
- *	general utility functions
- */
-lgmnal_srxd_t	*lgmnal_rxbuffer_to_srxd(lgmnal_data_t *, void*);
-lgmnal_stxd_t	*lgmnal_txbuffer_to_stxd(lgmnal_data_t *, void*);
-void	lgmnal_stop_rxthread(lgmnal_data_t *);
-void	lgmnal_small_tx_done(gm_port_t *, void *, gm_status_t);
-char	*lgmnal_gm_error(gm_status_t);
-char	*lgmnal_rxevent(gm_recv_event_t*);
-int	lgmnal_is_small_message(lgmnal_data_t*, int, struct iovec*, int);
-
-void *lgmnal_hash_find(lgmnal_hash_t *, void*);
-int lgmnal_hash_add(lgmnal_hash_t**, void*, void*);
-void lgmnal_hash_free(lgmnal_hash_t**);
-
-/*
- *	Communication functions
- */
-int lgmnal_receive_thread(void *);
-int
-lgmnal_small_transmit(nal_cb_t *, void *, lib_msg_t *, ptl_hdr_t *, int, ptl_nid_t, ptl_pid_t, unsigned int, struct iovec*, int);
-
-int
-lgmnal_small_receive2(nal_cb_t *, void *, lib_msg_t *, unsigned int, struct iovec *, size_t, size_t);
-
-void lgmnal_yield(int);
-
-#endif /*__INCLUDE_LGMNAL_H__*/
diff --git a/lustre/portals/knals/lgmnal/lgmnal_api.c b/lustre/portals/knals/lgmnal/lgmnal_api.c
deleted file mode 100644
index 8322e834a603d8a05cb316ec3804e9a18384bdeb..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal_api.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	Implements the API NAL functions
- */
-
-#include "lgmnal.h"
-
-lgmnal_data_t	*global_nal_data = NULL;
-/*
- *	lgmnal_api_forward
- *	This function takes a pack block of arguments from the NAL API
- *	module and passes them to the NAL CB module. The CB module unpacks
- *	the args and calls the appropriate function indicated by index.
- *	Typically this function is used to pass args between kernel and use
- *	space.
- *	As lgmanl exists entirely in kernel, just pass the arg block directly to
- *	the NAL CB, buy passing the args to lib_dispatch
- *	Arguments are
- *	nal_t	nal 	Our nal
- *	int	index	the api function that initiated this call 
- *	void 	*args	packed block of function args
- *	size_t	arg_len	length of args block
- *	void 	*ret	A return value for the API NAL
- *	size_t	ret_len	Size of the return value
- *	
- */
-
-int
-lgmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
-		void *ret, size_t ret_len)
-{
-
-	nal_cb_t	*nal_cb = NULL;
-	lgmnal_data_t	*nal_data = NULL;
-
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_forward: nal [%p], index [%d], args [%p], arglen [%d], ret [%p], retlen [%d]\n", nal, index, args, arg_len, ret, ret_len));
-
-	if (!nal || !args || (index < 0) || (arg_len < 0)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
-#ifdef LGMNAL_DEBUG
-		if (!nal)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No nal specified\n"));
-		if (!args)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No args specified\n"));
-		if (index < 0)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Index is negative[%d]\n", index));
-		if (arg_len < 0)
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("arg_len is negative [%d]\n", arg_len));
-#endif
-		return (PTL_FAIL);
-	}
-
-	if (ret && (ret_len <= 0)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
-#ifdef LGMNAL_DEBUG
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("ret_len is [%d]\n", ret_len));
-#endif
-		return (PTL_FAIL);
-	}
-
-
-	if (!nal->nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal, no nal data\n"));	
-		return (PTL_FAIL);
-	}
-	
-	nal_data = nal->nal_data;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_data is [%p]\n", nal_data));	
-
-	if (!nal_data->nal_cb) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal_data, no nal_cb\n"));	
-		return (PTL_FAIL);
-	}
-	
-	nal_cb = nal_data->nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_cb is [%p]\n", nal_cb));	
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward calling lib_dispatch\n"));
-	lib_dispatch(nal_cb, NULL, index, args, ret);
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward returns from lib_dispatch\n"));
-
-	return(PTL_OK);
-}
-
-
-/*
- *	lgmnal_api_shutdown
- *	Close down this interface and free any resources associated with it
- *	nal_t	nal	our nal to shutdown
- */
-int
-lgmnal_api_shutdown(nal_t *nal, int interface)
-{
-
-	lgmnal_data_t	*nal_data = nal->nal_data;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_shutdown: nal_data [%p]\n", nal_data));
-
-	/*
- 	 *	TO DO	lgmnal_api_shutdown what is to be done?
- 	 */
-
-	return(PTL_OK);
-}
-
-
-/*
- *	lgmnal_api_validate
- *	validate a user address for use in communications
- *	There's nothing to be done here
- */
-int
-lgmnal_api_validate(nal_t *nal, void *base, size_t extent)
-{
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_validate : nal [%p], base [%p], extent [%d]\n", nal, base, extent));
-
-	return(PTL_OK);
-}
-
-
-
-/*
- *	lgmnal_api_yield
- *	Give up the processor
- */
-void
-lgmnal_api_yield(nal_t *nal)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_yield : nal [%p]\n", nal));
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule();
-
-	return;
-}
-
-
-
-/*
- *	lgmnal_api_lock
- *	Take a threadsafe lock
- */
-void
-lgmnal_api_lock(nal_t *nal, unsigned long *flags)
-{
-
-	lgmnal_data_t	*nal_data;
-	nal_cb_t	*nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flagsa [%p] flags[%ul]\n", nal, flags, *flags));
-
-	nal_data = nal->nal_data;
-	nal_cb = nal_data->nal_cb;
-
-	nal_cb->cb_cli(nal_cb, flags);
-/*
-	LGMNAL_API_LOCK(nal_data);
-*/
-
-	return;
-}
-
-/*
- *	lgmnal_api_unlock
- *	Release a threadsafe lock
- */
-void
-lgmnal_api_unlock(nal_t *nal, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data;
-	nal_cb_t	*nal_cb;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flags [%p]\n", nal, flags));
-
-	nal_data = nal->nal_data;
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal, no nal_data\n"));
-	}
-	nal_cb = nal_data->nal_cb;
-	if (!nal_cb) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal_data, no nal_cb\n"));
-	}
-
-	nal_cb->cb_sti(nal_cb, flags);
-/*
-	LGMNAL_API_UNLOCK(nal_data);
-*/
-
-	return;
-}
-
-
-nal_t *
-lgmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, ptl_pid_t rpid)
-{
-
-	nal_t		*nal = NULL;
-	nal_cb_t	*nal_cb = NULL;
-	lgmnal_data_t	*nal_data = NULL;
-	lgmnal_srxd_t	*srxd = NULL;
-	gm_status_t	gm_status;
-	unsigned int	local_nid = 0, global_nid = 0;
-	ptl_nid_t	portals_nid;
-	ptl_pid_t	portals_pid = 0;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_init : interface [%d], ptl_size [%d], ac_size[%d]\n",
-			interface, ptl_size, ac_size));
-
-	if ((interface < 0) || (interface > LGMNAL_NUM_IF) || (ptl_size <= 0) || (ac_size <= 0) ) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad args\n"));
-		return(NULL);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("parameters check out ok\n"));
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Acquired global lock\n"));
-
-
-	PORTAL_ALLOC(nal_data, sizeof(lgmnal_data_t));
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't get memory\n"));
-		return(NULL);
-	}	
-	memset(nal_data, 0, sizeof(lgmnal_data_t));
-	/*
- 	 *	set the small message buffer size 
-	 */
-	nal_data->refcnt = 1;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_data[%p]\n", nal_data));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("small_msg_size is [%d]\n", nal_data->small_msg_size));
-
-	PORTAL_ALLOC(nal, sizeof(nal_t));
-	if (!nal) {
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
-		return(NULL);
-	}
-	memset(nal, 0, sizeof(nal_t));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal[%p]\n", nal));
-
-	PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
-	if (!nal_cb) {
-		PORTAL_FREE(nal, sizeof(nal_t));
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
-		return(NULL);
-	}
-	memset(nal_cb, 0, sizeof(nal_cb_t));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_cb[%p]\n", nal_cb));
-
-	LGMNAL_INIT_NAL(nal);
-	LGMNAL_INIT_NAL_CB(nal_cb);
-	/*
-	 *	String them all together
-	 */
-	nal->nal_data = (void*)nal_data;
-	nal_cb->nal_data = (void*)nal_data;
-	nal_data->nal = nal;
-	nal_data->nal_cb = nal_cb;
-
-	LGMNAL_API_LOCK_INIT(nal_data);
-	LGMNAL_CB_LOCK_INIT(nal_data);
-	LGMNAL_GM_LOCK_INIT(nal_data);
-
-
-	/*
- 	 *	initialise the interface, 
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling gm_init\n"));
-	if (gm_init() != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("call to gm_init failed\n"));
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_open with interface [%d], port [%d], name [%s], version [%d]\n", interface, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION));
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_open(&nal_data->gm_port, 0, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION);
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open returned [%d]\n", gm_status));
-	if (gm_status == GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open succeeded port[%p]\n", nal_data->gm_port));
-	} else {
-		switch(gm_status) {
-		case(GM_INVALID_PARAMETER):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Invalid Parameter\n"));
-			break;
-		case(GM_BUSY):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. GM Busy\n"));
-			break;
-		case(GM_NO_SUCH_DEVICE):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. No such device\n"));
-			break;
-		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Incompatile lib and driver\n"));
-			break;
-		case(GM_OUT_OF_MEMORY):
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Out of Memory\n"));
-			break;
-		default:
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Unknow error code [%d]\n", gm_status));
-			break;
-		}	
-		LGMNAL_GM_LOCK(nal_data);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-	
-	nal_data->small_msg_size = lgmnal_small_msg_size;
-	nal_data->small_msg_gmsize = gm_min_size_for_length(lgmnal_small_msg_size);
-
-	if (lgmnal_alloc_srxd(nal_data) != LGMNAL_STATUS_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small rx descriptors\n"));
-		lgmnal_free_stxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-
-	/*
- 	 *	Hang out a bunch of small receive buffers
-	 *	In fact hang them all out
-	 */
-	while((srxd = lgmnal_get_srxd(nal_data, 0))) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("giving [%p] to gm_provide_recvive_buffer\n", srxd->buffer));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, 
-									srxd->gmsize, GM_LOW_PRIORITY, 0);
-		LGMNAL_GM_UNLOCK(nal_data);
-	}
-	
-	/*
-	 *	Allocate pools of small tx buffers and descriptors
-	 */
-	if (lgmnal_alloc_stxd(nal_data) != LGMNAL_STATUS_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small tx descriptors\n"));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-
-	/*
- 	 *	Start the recieve thread
-	 *	Initialise the gm_alarm we will use to wake the thread is 
-	 *	it needs to be stopped
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Initializing receive thread alarm and flag\n"));
-	gm_initialize_alarm(&nal_data->rxthread_alarm);
-	nal_data->rxthread_flag = LGMNAL_THREAD_START;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Starting receive thread\n"));
-	nal_data->rxthread_pid = kernel_thread(lgmnal_receive_thread, (void*)nal_data, 0);
-	if (nal_data->rxthread_pid <= 0) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Receive thread failed to start\n"));
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	while (nal_data->rxthread_flag != LGMNAL_THREAD_STARTED) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1024);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Waiting for receive thread signs of life\n"));
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("receive thread seems to have started\n"));
-	nal_data->rxthread_flag = LGMNAL_THREAD_CONTINUE;
-
-
-
-	/*
-	 *	Initialise the portals library
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Getting node id\n"));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		lgmnal_stop_rxthread(nal_data);
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't determine node id\n"));
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	nal_data->gm_local_nid = local_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%u]\n", local_nid));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, &global_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to obtain global id\n"));
-		lgmnal_stop_rxthread(nal_data);
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node id is [%u][%x]\n", global_nid));
-	nal_data->gm_global_nid = global_nid;
-
-/*
-	pid = gm_getpid();
-*/
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_pid is [%u]\n", portals_pid));
-	portals_nid = (unsigned long)global_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_nid is [%lu]\n", portals_nid));
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_init\n"));
-	if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, ac_size) != PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lib_init failed\n"));
-		lgmnal_stop_rxthread(nal_data);
-		lgmnal_free_stxd(nal_data);
-		lgmnal_free_srxd(nal_data);
-		LGMNAL_GM_LOCK(nal_data);
-		gm_close(nal_data->gm_port);
-		gm_finalize();
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(nal, sizeof(nal_t));	
-		PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-		PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-		return(NULL);
-		
-	}
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_init finished\n"));
-	global_nal_data = nal->nal_data;
-	return(nal);
-}
-
-
-
-/*
- *	Called when module removed
- */
-void lgmnal_fini()
-{
-	lgmnal_data_t	*nal_data = global_nal_data;
-	nal_t		*nal = nal_data->nal;
-	nal_cb_t	*nal_cb = nal_data->nal_cb;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_fini\n"));
-
-	PtlNIFini(lgmnal_ni);
-	lib_fini(nal_cb);
-
-	lgmnal_stop_rxthread(nal_data);
-	lgmnal_free_stxd(nal_data);
-	lgmnal_free_srxd(nal_data);
-	LGMNAL_GM_LOCK(nal_data);
-	gm_close(nal_data->gm_port);
-	gm_finalize();
-	LGMNAL_GM_UNLOCK(nal_data);
-	PORTAL_FREE(nal, sizeof(nal_t));	
-	PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));	
-	PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
-}
-
-EXPORT_SYMBOL(lgmnal_init);
-EXPORT_SYMBOL(lgmnal_fini);
-EXPORT_SYMBOL(lgmnal_api_forward);
-EXPORT_SYMBOL(lgmnal_api_validate);
-EXPORT_SYMBOL(lgmnal_api_yield);
-EXPORT_SYMBOL(lgmnal_api_lock);
-EXPORT_SYMBOL(lgmnal_api_unlock);
-EXPORT_SYMBOL(lgmnal_api_shutdown);
diff --git a/lustre/portals/knals/lgmnal/lgmnal_cb.c b/lustre/portals/knals/lgmnal/lgmnal_cb.c
deleted file mode 100644
index dcd5446127e425f2595e0bb3b9086659a54f0af1..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal_cb.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- *	This file implements the nal cb functions
- */
-
-
-#include "lgmnal.h"
-
-int lgmnal_cb_recv(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int niov, struct iovec *iov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = (lgmnal_srxd_t*)private;
-	int		status = PTL_OK;
-	lgmnal_data_t	*nal_data = nal_cb->nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_recv nal_cb [%p],private[%p], cookie[%p], niov[%d], iov [%p], mlen[%d], rlen[%d]\n", nal_cb, private, cookie, niov, iov, mlen, rlen));
-
-	if (srxd->type == LGMNAL_SMALL_MESSAGE) {
-		if (!LGMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, mlen)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_cb_recv. This is not a small message\n"));
-		}
-		status = lgmnal_small_receive2(nal_cb, private, cookie, niov, iov, mlen, rlen);
-	}
-		
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_return status [%d]\n", status));
-	return(status);
-}
-
-int lgmnal_cb_recv_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int kniov, ptl_kiov_t *kiov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = (lgmnal_srxd_t*)private;
-	int		status = PTL_OK;
-	struct iovec	*iovec = NULL;
-	int		i = 0;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_recv_pages nal_cb [%p],private[%p], cookie[%p], kniov[%d], kiov [%p], mlen[%d], rlen[%d]\n", nal_cb, private, cookie, kniov, kiov, mlen, rlen));
-
-	if (srxd->type == LGMNAL_SMALL_MESSAGE) {
-		PORTAL_ALLOC(iovec, sizeof(struct iovec)*kniov);
-		if (!iovec) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Can't malloc\n"));
-			return(LGMNAL_STATUS_FAIL);
-		}
-
-		/*
-		 *	map each page and create an iovec for it
-		 */
-		for (i=0; i<kniov; i++) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing kniov [%d] [%p]\n", i, kiov));
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kniov page [%p] len [%d] offset[%d]\n", kiov->kiov_page, kiov->kiov_len, kiov->kiov_offset));
-			iovec->iov_len = kiov->kiov_len;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling kmap", kiov->kiov_page));
-			iovec->iov_base = kmap(kiov->kiov_page) + kiov->kiov_offset;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling iov_base is [%p]", iovec->iov_base));
-			iovec->iov_len = kiov->kiov_len;
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("calling lgmnal_small_receive2\n"));
-		status = lgmnal_small_receive2(nal_cb, private, cookie, kniov, iovec, mlen, rlen);
-		PORTAL_FREE(iovec, sizeof(struct iovec)*kniov);
-	}
-		
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_return status [%d]\n", status));
-	return(status);
-}
-
-
-int lgmnal_cb_send(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr,
-	int type, ptl_nid_t nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, size_t len)
-{
-
-	lgmnal_data_t	*nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_sendnid [%lu] niov[%d] len[%d]\n", nid, niov, len));
-	nal_data = nal_cb->nal_data;
-	
-	if (LGMNAL_IS_SMALL_MESSAGE(nal_data, niov, iov, len)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is a small message send\n"));
-		lgmnal_small_transmit(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("This is a large message send it is not supported yet\n"));
-/*
-		lgmnal_large_transmit1(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-*/
-		return(LGMNAL_STATUS_FAIL);
-	}
-	return(PTL_OK);
-}
-
-int lgmnal_cb_send_pages(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr,
-	int type, ptl_nid_t nid, ptl_pid_t pid, unsigned int kniov, ptl_kiov_t *kiov, size_t len)
-{
-
-	int	i = 0;
-	lgmnal_data_t	*nal_data;
-	struct	iovec 	*iovec;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_send_pages nid [%lu] niov[%d] len[%d]\n", nid, kniov, len));
-	nal_data = nal_cb->nal_data;
-	if (LGMNAL_IS_SMALL_MESSAGE(nal_data, 0, NULL, len)) {
-		/* TO DO fix small message for send pages */
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is a small message send\n"));
-		PORTAL_ALLOC(iovec, kniov*sizeof(struct iovec));
-		
-		for (i=0; i<kniov; i++) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing kniov [%d] [%p]\n", i, kiov));
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kniov page [%p] len [%d] offset[%d]\n", kiov->kiov_page, kiov->kiov_len, kiov->kiov_offset));
-			iovec->iov_len = kiov->kiov_len;
-			iovec->iov_base = kmap(kiov->kiov_page) + kiov->kiov_offset;
-			iovec->iov_len = kiov->kiov_len;
-		}
-		lgmnal_small_transmit(nal_cb, private, cookie, hdr, type, nid, pid, kniov, iovec, len);
-		PORTAL_FREE(iovec, kniov*sizeof(struct iovec));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("This is a large message send it is not supported yet\n"));
-/*
-		lgmnal_large_transmit1(nal_cb, private, cookie, hdr, type, nid, pid, niov, iov, len);
-*/
-		return(LGMNAL_STATUS_FAIL);
-	}
-	return(PTL_OK);
-}
-
-int lgmnal_cb_read(nal_cb_t *nal_cb, void *private, void *dst, user_ptr src, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_read dst [%p] src [%p] len[%d]\n", dst, src, len));
-	gm_bcopy(src, dst, len);
-	return(PTL_OK);
-}
-
-int lgmnal_cb_write(nal_cb_t *nal_cb, void *private, user_ptr dst, void *src, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_write :: dst [%p] src [%p] len[%d]\n", dst, src, len));
-	gm_bcopy(src, dst, len);
-	return(PTL_OK);
-}
-
-int lgmnal_cb_callback(nal_cb_t *nal_cb, void *private, lib_eq_t *eq, ptl_event_t *ev)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_callback nal_cb[%p], private[%p], eq[%p], ev[%p]\n", nal_cb, private, eq, ev));
-
-	if (eq->event_callback != NULL) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("found callback\n"));
-		eq->event_callback(ev);
-	}
-	
-	return(PTL_OK);
-}
-
-void *lgmnal_cb_malloc(nal_cb_t *nal_cb, size_t len)
-{
-	void *ptr = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_malloc len[%d]\n", len));
-	PORTAL_ALLOC(ptr, len);
-	return(ptr);
-}
-
-void lgmnal_cb_free(nal_cb_t *nal_cb, void *buf, size_t len)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_free :: buf[%p] len[%d]\n", buf, len));
-	PORTAL_FREE(buf, len);
-	return;
-}
-
-void lgmnal_cb_unmap(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, void **addrkey)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_unmap niov[%d] iov[%], addrkey[%p]\n", niov, iov, addrkey));
-	return;
-}
-
-int  lgmnal_cb_map(nal_cb_t *nal_cb, unsigned int niov, struct iovec *iov, void**addrkey)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_map niov[%d], iov[%p], addrkey[%p], niov, iov, addrkey\n"));
-	return(PTL_OK);
-}
-
-void lgmnal_cb_printf(nal_cb_t *nal_cb, const char *fmt, ...)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_printf\n"));
-	lgmnal_print(fmt);
-	return;
-}
-
-void lgmnal_cb_cli(nal_cb_t *nal_cb, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	spinlock_t	cb_lock = nal_data->cb_lock;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_cli\n"));
-/*
-	local_irq_save(*flags);
-	spin_lock_irqsave(&cb_lock, *flags);
-*/
-	spin_lock(&cb_lock);
-	return;
-}
-
-void lgmnal_cb_sti(nal_cb_t *nal_cb, unsigned long *flags)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	spinlock_t	cb_lock = nal_data->cb_lock;
-
-/*
-	local_irq_restore(*flags);
-	spin_unlock_irqrestore(&cb_lock, *flags);
-*/
-	spin_unlock(&cb_lock);
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_sti\n"));
-	return;
-}
-
-int lgmnal_cb_dist(nal_cb_t *nal_cb, ptl_nid_t nid, unsigned long *dist)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cb_dist\n"));
-	if (dist)
-		*dist = 27;
-	return(PTL_OK);
-}
-
-
-
-
-EXPORT_SYMBOL(lgmnal_cb_send);
-EXPORT_SYMBOL(lgmnal_cb_send_pages);
-EXPORT_SYMBOL(lgmnal_cb_recv);
-EXPORT_SYMBOL(lgmnal_cb_recv_pages);
-EXPORT_SYMBOL(lgmnal_cb_read);
-EXPORT_SYMBOL(lgmnal_cb_write);
-EXPORT_SYMBOL(lgmnal_cb_cli);
-EXPORT_SYMBOL(lgmnal_cb_sti);
-EXPORT_SYMBOL(lgmnal_cb_dist);
-EXPORT_SYMBOL(lgmnal_cb_printf);
-EXPORT_SYMBOL(lgmnal_cb_map);
-EXPORT_SYMBOL(lgmnal_cb_unmap);
-EXPORT_SYMBOL(lgmnal_cb_callback);
-EXPORT_SYMBOL(lgmnal_cb_free);
-EXPORT_SYMBOL(lgmnal_cb_malloc);
diff --git a/lustre/portals/knals/lgmnal/lgmnal_comm.c b/lustre/portals/knals/lgmnal/lgmnal_comm.c
deleted file mode 100644
index 4cd1b8384dcdfb21d59b52951fb38e7f2574711f..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal_comm.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-/*
- *	This file contains all lgmnal send and receive functions
- */
-
-#include "lgmnal.h"
-
-int
-lgmnal_requeue_rxbuffer(lgmnal_data_t *nal_data, lgmnal_srxd_t *srxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_requeue_rxbuffer\n"));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("requeueing srxd[%p] nal_data[%p]\n", srxd, nal_data));
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer,
-					srxd->gmsize, GM_LOW_PRIORITY, 0 );
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-/*
- *	Handle a bad message
- *	A bad message is one we don't expect or can't interpret
- */
-int
-lgmnal_badrx_message(lgmnal_data_t *nal_data, gm_recv_t *recv, lgmnal_srxd_t *srxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Can't handle message\n"));
-
-	if (!srxd)
-		srxd = lgmnal_rxbuffer_to_srxd(nal_data, gm_ntohp(recv->buffer));
-	if (srxd) {
-		lgmnal_requeue_rxbuffer(nal_data, srxd);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Can't find a descriptor for this buffer\n"));
-		/*
-		 *	get rid of it ?
-		 */
-		return(LGMNAL_STATUS_FAIL);
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-/*
- *	Start processing a small message receive
- *	Get here from lgmnal_receive_thread
- *	Hand off to lib_parse, which calls cb_recv
- *	which hands back to lgmnal_small_receive2
- *	Deal with all endian stuff here (if we can!)
- */
-int
-lgmnal_small_receive1(lgmnal_data_t *nal_data, gm_recv_t *recv)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	void		*buffer = NULL;
-	unsigned int snode, sport, type, length;
-	lgmnal_msghdr_t	*lgmnal_msghdr;
-	ptl_hdr_t	*portals_hdr;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_receive1 nal_data [%p], recv [%p]\n", nal_data, recv));
-
-	buffer = gm_ntohp(recv->buffer);;
-	snode = (int)gm_ntoh_u16(recv->sender_node_id);
-	sport = (int)gm_ntoh_u8(recv->sender_port_id);
-	type = (int)gm_ntoh_u8(recv->type);
-	buffer = gm_ntohp(recv->buffer);
-	length = (int) gm_ntohl(recv->length);
-
-	lgmnal_msghdr = (lgmnal_msghdr_t*)buffer;
-	portals_hdr = (ptl_hdr_t*)(buffer+LGMNAL_MSGHDR_SIZE);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("rx_event:: Sender node [%d], Sender Port [%d], type [%d], length [%d], buffer [%p]\n",
-				snode, sport, type, length, buffer));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_msghdr:: Sender node [%u], magic [%lx], type [%d]\n",
-				lgmnal_msghdr->sender_node_id, lgmnal_msghdr->magic, lgmnal_msghdr->type));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_hdr:: Sender node [%ul], dest_node [%ul]\n",
-				portals_hdr->src_nid, portals_hdr->dest_nid));
-
-
-	/*
- 	 *	Get a transmit descriptor for this message
-	 */
-	srxd = lgmnal_rxbuffer_to_srxd(nal_data, buffer);
-	LGMNAL_PRINT(LGMNAL_DEBUG, ("Back from lgmnal_rxbuffer_to_srxd\n"));
-	if (!srxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG, ("Failed to get receive descriptor for this buffer\n"));
-		lib_parse(nal_data->nal_cb, portals_hdr, srxd);
-		return(LGMNAL_STATUS_FAIL);
-	}
-	srxd->type = LGMNAL_SMALL_MESSAGE;
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling lib_parse buffer is [%p]\n", buffer+LGMNAL_MSGHDR_SIZE));
-	/*
- 	 *	control passes to lib, which calls cb_recv 
-	 *	cb_recv is responsible for returning the buffer 
-	 *	for future receive
-	 */
-	lib_parse(nal_data->nal_cb, portals_hdr, srxd);
-
-	return(LGMNAL_STATUS_OK);
-}
-
-/*
- *	Get here from lgmnal_receive_thread, lgmnal_small_receive1
- *	lib_parse, cb_recv
- *	Put data from prewired receive buffer into users buffer(s)
- *	Hang out the receive buffer again for another receive
- *	Call lib_finalize
- */
-int
-lgmnal_small_receive2(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, unsigned int niov, 
-							struct iovec *iov, size_t mlen, size_t rlen)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	void	*buffer = NULL;
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_receive2 niov [%d] mlen[%d]\n", niov, mlen));
-
-	if (!private) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_small_receive2 no context\n"));
-		lib_finalize(nal_cb, private, cookie);
-		return(PTL_FAIL);
-	}
-
-	srxd = (lgmnal_srxd_t*)private;
-	buffer = srxd->buffer;
-	buffer += sizeof(lgmnal_msghdr_t);
-	buffer += sizeof(ptl_hdr_t);
-
-	while(niov--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing [%p] len [%d]\n", iov, iov->iov_len));
-		gm_bcopy(buffer, iov->iov_base, iov->iov_len);			
-		buffer += iov->iov_len;
-		iov++;
-	}
-
-
-	/*
- 	 *	let portals library know receive is complete
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_finalize\n"));
-	if (lib_finalize(nal_cb, private, cookie) != PTL_OK) {
-		/* TO DO what to do with failed lib_finalise? */
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lib_finalize failed\n"));
-	}
-	/*
-	 *	return buffer so it can be used again
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling gm_provide_receive_buffer\n"));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer, srxd->gmsize, GM_LOW_PRIORITY, 0);	
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	return(PTL_OK);
-}
-
-
-
-/*
- *	The recevive thread
- *	This guy wait in gm_blocking_recvive and gets
- *	woken up when the myrinet adaptor gets an interrupt.
- *	Hands off processing of small messages and blocks again
- */
-int
-lgmnal_receive_thread(void *arg)
-{
-	lgmnal_data_t		*nal_data;
-	gm_recv_event_t		*rxevent = NULL;
-	gm_recv_t		*recv = NULL;
-	void			*buffer;
-
-	if (!arg) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("RXTHREAD:: This is the lgmnal_receive_thread. NO nal_data. Exiting\n", arg));
-		return(-1);
-	}
-
-	nal_data = (lgmnal_data_t*)arg;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("RXTHREAD:: This is the lgmnal_receive_thread nal_data is [%p]\n", arg));
-
-	nal_data->rxthread_flag = LGMNAL_THREAD_STARTED;
-	while (nal_data->rxthread_flag == LGMNAL_THREAD_STARTED) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: lgmnal_receive_threads waiting for LGMNAL_CONTINUE flag\n"));
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1024);
-		
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: calling daemonize\n"));
-	daemonize();
-	LGMNAL_GM_LOCK(nal_data);
-	while(nal_data->rxthread_flag == LGMNAL_THREAD_CONTINUE) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Receive thread waiting\n"));
-		rxevent = gm_blocking_receive_no_spin(nal_data->gm_port);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: receive thread got [%s]\n", lgmnal_rxevent(rxevent)));
-		if (nal_data->rxthread_flag != LGMNAL_THREAD_CONTINUE) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Receive thread time to exit\n"));
-			break;
-		}
-		switch (GM_RECV_EVENT_TYPE(rxevent)) {
-
-			case(GM_RECV_EVENT):
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: GM_RECV_EVENT\n"));
-				recv = (gm_recv_t*)&(rxevent->recv);
-				buffer = gm_ntohp(recv->buffer);
-				if (((lgmnal_msghdr_t*)buffer)->type == LGMNAL_SMALL_MESSAGE) {
-					LGMNAL_GM_UNLOCK(nal_data);
-					lgmnal_small_receive1(nal_data, recv);
-					LGMNAL_GM_LOCK(nal_data);
-				} else {
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("RXTHREAD:: Unsupported message type\n"));
-					lgmnal_badrx_message(nal_data, recv, NULL);
-				}
-			break;
-			case(_GM_SLEEP_EVENT):
-				/*
-				 *	Blocking receive above just returns
-				 *	immediatly with _GM_SLEEP_EVENT
-				 *	Don't know what this is
-				 */
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Sleeping in gm_unknown\n"));
-				LGMNAL_GM_UNLOCK(nal_data);
-				gm_unknown(nal_data->gm_port, rxevent);
-				LGMNAL_GM_LOCK(nal_data);
-				LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Awake from gm_unknown\n"));
-				break;
-				
-			default:
-				/*
-				 *	Don't know what this is
-				 *	gm_unknown will make sense of it
-				 */
-				LGMNAL_PRINT(LGMNAL_DEBUG_V, ("RXTHREAD:: Passing event to gm_unknown\n"));
-				gm_unknown(nal_data->gm_port, rxevent);
-				LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RXTHREAD:: Processed unknown event\n"));
-				
-		}
-
-		
-	}
-	LGMNAL_GM_UNLOCK(nal_data);
-	nal_data->rxthread_flag = LGMNAL_THREAD_STOPPED;
-	LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("RXTHREAD:: The lgmnal_receive_thread nal_data [%p] is exiting\n", nal_data));
-	return(LGMNAL_STATUS_OK);
-}
-
-
-int
-lgmnal_small_transmit(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr, int type,
-	ptl_nid_t global_nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, int size)
-{
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	lgmnal_stxd_t	*stxd = NULL;
-	void		*buffer = NULL;
-	lgmnal_msghdr_t	*msghdr = NULL;
-	int		tot_size = 0;
-	unsigned int	local_nid;
-	gm_status_t	gm_status = GM_SUCCESS;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_small_transmit nal_cb [%p] private [%p] cookie [%p] hdr [%p] type [%d] global_nid [%u][%x] pid [%d] niov [%d] iov [%p] size [%d]\n", nal_cb, private, cookie, hdr, type, global_nid, global_nid, pid, niov, iov, size));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_hdr:: dest_nid [%lu], src_nid [%lu]\n", hdr->dest_nid, hdr->src_nid));
-
-	if (!nal_data) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("no nal_data\n"));
-		return(LGMNAL_STATUS_FAIL);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("nal_data [%p]\n", nal_data));
-	}
-
-	LGMNAL_GM_LOCK(nal_data);
-	gm_status = gm_global_id_to_node_id(nal_data->gm_port, global_nid, &local_nid);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (gm_status != GM_SUCCESS) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to obtain local id\n"));
-		return(LGMNAL_STATUS_FAIL);
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local Node_id is [%u][%x]\n", local_nid, local_nid));
-
-	stxd = lgmnal_get_stxd(nal_data, 1);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("stxd [%p]\n", stxd));
-
-	stxd->type = LGMNAL_SMALL_MESSAGE;
-	stxd->cookie = cookie;
-
-	/*
-	 *	Copy lgmnal_msg_hdr and portals header to the transmit buffer
-	 *	Then copy the data in
-	 */
-	buffer = stxd->buffer;
-	msghdr = (lgmnal_msghdr_t*)buffer;
-
-	msghdr->magic = LGMNAL_MAGIC;
-	msghdr->type = LGMNAL_SMALL_MESSAGE;
-	msghdr->sender_node_id = nal_data->gm_global_nid;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing msghdr at [%p]\n", buffer));
-
-	buffer += sizeof(lgmnal_msghdr_t);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Advancing buffer pointer by [%x] to [%p]\n", sizeof(lgmnal_msghdr_t), buffer));
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing  portals hdr at [%p]\n", buffer));
-	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
-
-	buffer += sizeof(ptl_hdr_t);
-
-	while(niov--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing iov [%p] len [%d] to [%p]\n", iov, iov->iov_len, buffer));
-		gm_bcopy(iov->iov_base, buffer, iov->iov_len);
-		buffer+= iov->iov_len;
-		iov++;
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("sending\n"));
-	tot_size = size+sizeof(ptl_hdr_t)+sizeof(lgmnal_msghdr_t);
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_send_to_peer port [%p] buffer [%p] gmsize [%d] msize [%d] global_nid [%u][%x] local_nid[%d] stxd [%p]\n",
-			nal_data->gm_port, stxd->buffer, stxd->gmsize, tot_size, global_nid, global_nid, local_nid, stxd));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, stxd->gmsize, tot_size, GM_LOW_PRIORITY, local_nid, lgmnal_small_tx_done, (void*)stxd);
-	
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("done\n"));
-		
-	return(PTL_OK);
-}
-
-
-void 
-lgmnal_small_tx_done(gm_port_t *gm_port, void *context, gm_status_t status)
-{
-	lgmnal_stxd_t	*stxd = (lgmnal_stxd_t*)context;
-	lib_msg_t	*cookie = stxd->cookie;
-	lgmnal_data_t	*nal_data = (lgmnal_data_t*)stxd->nal_data;
-	nal_cb_t	*nal_cb = nal_data->nal_cb;
-
-	if (!stxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("send completion event for unknown stxd\n"));
-		return;
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Result of send stxd [%p] is [%s]\n", stxd, lgmnal_gm_error(status)));
-	/* TO DO figure out which sends are worth retrying and get a send token to retry */
-	if (lib_finalize(nal_cb, stxd, cookie) != PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Call to lib_finalize failed for stxd [%p]\n", stxd));
-	}
-	lgmnal_return_stxd(nal_data, stxd);
-	return;
-}
-
-
-void 
-lgmnal_large_tx1_done(gm_port_t *gm_port, void *context, gm_status_t status)
-{
-
-}
-
-/*
- *	Begin a large transmit
- */
-int
-lgmnal_large_transmit1(nal_cb_t *nal_cb, void *private, lib_msg_t *cookie, ptl_hdr_t *hdr, int type,
-	ptl_nid_t global_nid, ptl_pid_t pid, unsigned int niov, struct iovec *iov, int size)
-{
-
-	lgmnal_data_t	*nal_data;
-	lgmnal_stxd_t	*stxd = NULL;
-	void		*buffer = NULL;
-	lgmnal_msghdr_t	*msghdr = NULL;
-	unsigned int	local_nid;
-	int		mlen = 0;	/* the size of the init message data */
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_large_transmit1 nal_cb [%p] private [%p], cookie [%p] hdr [%p], type [%d] global_nid [%u], pid [%d], 
-					niov [%d], iov [%p], size [%d]\n",
-					nal_cb, private, cookie, hdr, type, global_nid, pid, niov, iov, size));
-
-	if (nal_cb)
-		nal_data = (lgmnal_data_t*)nal_cb->nal_data;
-	else  {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("no nal_cb.\n"));
-		return(LGMNAL_STATUS_FAIL);
-	}
-	
-
-	/*
-	 *	TO DO large transmit uses stxd. Should it have control descriptor?
-	 */
-	stxd = lgmnal_get_stxd(nal_data, 1);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("stxd [%p]\n", stxd));
-
-	stxd->type = LGMNAL_LARGE_MESSAGE_INIT;
-	stxd->cookie = cookie;
-
-	/*
-	 *	Copy lgmnal_msg_hdr and portals header to the transmit buffer
-	 *	Then copy the iov in
-	 */
-	buffer = stxd->buffer;
-	msghdr = (lgmnal_msghdr_t*)buffer;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing msghdr at [%p]\n", buffer));
-
-	msghdr->magic = LGMNAL_MAGIC;
-	msghdr->type = LGMNAL_LARGE_MESSAGE_INIT;
-	msghdr->sender_node_id = nal_data->gm_global_nid;
-	msghdr->stxd = stxd;
-	buffer += sizeof(lgmnal_msghdr_t);
-	mlen = sizeof(lgmnal_msghdr_t);
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("processing  portals hdr at [%p]\n", buffer));
-
-	gm_bcopy(hdr, buffer, sizeof(ptl_hdr_t));
-	buffer += sizeof(ptl_hdr_t);
-	mlen += sizeof(ptl_hdr_t); 
-
-	/*
-	 *	Store the iovs in the stxd for we can get them later
-	 *	in large_transmit2
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Copying iov [%p] to [%p]\n", iov, stxd->iov));
-	gm_bcopy(iov, stxd->iov, niov*sizeof(struct iovec));
-	stxd->niov = niov;
-	
-	/*
- 	 *	Send the init message to the target
-	 */
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("sending mlen [%d]\n", mlen));
-	LGMNAL_GM_LOCK(nal_data);
-	gm_send_to_peer_with_callback(nal_data->gm_port, stxd->buffer, stxd->gmsize, mlen, GM_LOW_PRIORITY, local_nid, lgmnal_large_tx1_done, (void*)stxd);
-	LGMNAL_GM_UNLOCK(nal_data);
-	
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("done\n"));
-		
-	return(PTL_OK);
-}
-
-
-
-
-EXPORT_SYMBOL(lgmnal_requeue_rxbuffer);
-EXPORT_SYMBOL(lgmnal_badrx_message);
-EXPORT_SYMBOL(lgmnal_large_tx1_done);
-EXPORT_SYMBOL(lgmnal_large_transmit1);
-EXPORT_SYMBOL(lgmnal_small_receive1);
-EXPORT_SYMBOL(lgmnal_small_receive2);
-EXPORT_SYMBOL(lgmnal_receive_thread);
-EXPORT_SYMBOL(lgmnal_small_transmit);
-EXPORT_SYMBOL(lgmnal_small_tx_done);
diff --git a/lustre/portals/knals/lgmnal/lgmnal_module.c b/lustre/portals/knals/lgmnal/lgmnal_module.c
deleted file mode 100644
index ce870f05c5d5f21fe47160b4d2c2f40a19a00291..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal_module.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include "lgmnal.h"
-
-
-ptl_handle_ni_t	lgmnal_ni;
-
-
-int 
-lgmnal_cmd(struct portal_ioctl_data *data, void *private)
-{
-	lgmnal_data_t	*nal_data = NULL;
-	char		*name = NULL;
-	int		nid = -2;
-	int		gnid;
-	gm_status_t	gm_status;
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_cmd [d] private [%p]\n", data->ioc_nal_cmd, private));
-	nal_data = (lgmnal_data_t*)private;
-	LGMNAL_PRINT(LGMNAL_DEBUG_V, ("nal_data is [%p]\n", nal_data));
-	switch(data->ioc_nal_cmd) {
-	/*
-	 * just reuse already defined GET_NID. Should define LGMNAL version
-	 */
-	case(LGMNAL_IOC_GET_GNID):
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_cmd GETNID (Get GM Global Network Id\n"));
-
-		PORTAL_ALLOC(name, data->ioc_plen1);
-		copy_from_user(name, data->ioc_pbuf1, data->ioc_plen1);
-	
-		LGMNAL_GM_LOCK(nal_data);
-		nid = gm_host_name_to_node_id(nal_data->gm_port, name);
-		LGMNAL_GM_UNLOCK(nal_data);
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%d]\n", nid));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_node_id_to_global_id(nal_data->gm_port, nid, &gnid);
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_node_id_to_global_id failed\n", gm_status));
-			return(-1);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node is is [%u][%x]\n", gnid, gnid));
-		copy_to_user(data->ioc_pbuf2, &gnid, data->ioc_plen2);
-	break;
-	default:
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_cmd UNKNOWN[%d]\n", data->ioc_nal_cmd));
-		data->ioc_nid2 = -1;
-	}
-
-
-	return(0);
-}
-
-int lgmnal_small_msg_size = 81920;
-int lgmnal_debug_level = 1;
-
-int
-init_module()
-{
-	int	status;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("This is the lgmnal module initialisation routine\n"));
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling lgmnal_init\n"));
-	status = PtlNIInit(lgmnal_init, 32, 4, 0, &lgmnal_ni);
-	if (status == PTL_OK) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Portals LGMNAL initialised ok lgmnal_ni [%lx]\n", lgmnal_ni));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Portals LGMNAL Failed to initialise\n"));
-		return(1);
-		
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling kportal_nal_register\n"));
-	/*
- 	 *	global_nal_data is set by lgmnal_init
-	 */
-	if (kportal_nal_register(LGMNAL, &lgmnal_cmd, global_nal_data) != 0) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("kportal_nal_register failed\n"));
-		return(1);
-	}
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling PORTAL_SYMBOL_REGISTER\n"));
-	PORTAL_SYMBOL_REGISTER(lgmnal_ni);
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("This is the end of the lgmnal module initialisation routine"));
-
-
-	return(0);
-}
-
-
-void cleanup_module()
-{
-	int interface=0;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Cleaning up lgmnal module"));
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Interface [%d] Calling shutdown\n", interface));
-	kportal_nal_unregister(LGMNAL);
-	PORTAL_SYMBOL_UNREGISTER(lgmnal_ni);
-	lgmnal_fini();
-	global_nal_data = NULL;
-	return;
-}
-
-
-EXPORT_SYMBOL(lgmnal_ni);
-EXPORT_SYMBOL(lgmnal_debug_level);
-
-MODULE_PARM(lgmnal_small_msg_size, "i");
-MODULE_PARM(lgmnal_debug_level, "i");
-
-MODULE_AUTHOR("Morgan Doyle. morgan.doyle@hp.com");
-
-MODULE_DESCRIPTION("A Portals kernel NAL for Myrinet GM2. [0<lgmnal_debug_level<4]");
-
-MODULE_LICENSE("GPL");
diff --git a/lustre/portals/knals/lgmnal/lgmnal_utils.c b/lustre/portals/knals/lgmnal/lgmnal_utils.c
deleted file mode 100644
index 8a91ca45a7c7983a95f54ca680ba3c209d0e23f7..0000000000000000000000000000000000000000
--- a/lustre/portals/knals/lgmnal/lgmnal_utils.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
- *
- *   This file is part of Lustre, http://www.lustre.org/
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *	All utilities required by lgmanl
- */
-
-#include "lgmnal.h"
-
-/*
- *	print a console message
- *	the header of each messages specifies
- *	the function, file and line number of the caller
- */
-
-/*
- *	TO DO	lgmnal_print find how to determine the caller function
- */
-
-#define DEFAULT_LEN	64
-void lgmnal_print(const char *fmt, ...)
-{
-	va_list	ap;
-	char	*varbuf = NULL, fixedbuf[DEFAULT_LEN];
-	int	len = 0;
-
-
-	va_start(ap, fmt);
-	sprintf(fixedbuf, "LGMNAL::");
-	len = vsnprintf(fixedbuf+8, DEFAULT_LEN-8, fmt, ap);
-	if ((len+8) >= DEFAULT_LEN) {
-		PORTAL_ALLOC(varbuf, len+1+8);
-		if (!varbuf) {
-			printk("lgmnal_cb_printf Failed to malloc\n");
-			printk("Truncated message is\n");
-			printk(fixedbuf);
-			va_end(ap);
-			return;
-		}
-		sprintf(varbuf, "LGMNAL::");
-		len = vsnprintf(varbuf+8, len+1, fmt, ap);
-	} else {
-		varbuf = fixedbuf;
-	}
-	va_end(ap);
-	printk(varbuf);
-	if (fixedbuf != varbuf)
-		PORTAL_FREE(varbuf, len+1+8);
-	return;
-}
-	
-
-/*
- *	allocate a number of small tx buffers and register with GM
- *	so they are wired and set up for DMA. This is a costly operation.
- *	Also allocate a corrosponding descriptor to keep track of 
- *	the buffer.
- *	Put all descriptors on singly linked list to be available to send function.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the txd spinlock.
- */
-int
-lgmnal_alloc_stxd(lgmnal_data_t *nal_data)
-{
-	int ntx = 0, nstx = 0, i = 0;
-	lgmnal_stxd_t	*txd = NULL;
-	void	*txbuffer = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_alloc_small tx\n"));
-
-	LGMNAL_GM_LOCK(nal_data);
-	ntx = gm_num_send_tokens(nal_data->gm_port);
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("total number of send tokens available is [%d]\n", ntx));
-	
-	nstx = ntx/2;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocated [%d] send tokens to small messages\n", nstx));
-
-
-#ifdef LGMNAL_USE_GM_HASH
-	nal_data->stxd_hash = gm_create_hash(gm_hash_compare_ptrs, gm_hash_hash_ptr, 0, sizeof(void*), nstx, 0);
-	if (!nal_data->srxd_hash) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to create hash table\n\n"));
-			return(LGMNAL_STATUS_NOMEM);
-	}
-#else
-	nal_data->stxd_hash = NULL;
-#endif
-
-	/*
-	 * A semaphore is initialised with the 
-	 * number of transmit tokens available.
-	 * To get a stxd, acquire the token semaphore.
- 	 * this decrements the available token count
-	 * (if no tokens you block here, someone returning a 
-	 * stxd will release the semaphore and wake you)
-	 * When token is obtained acquire the spinlock 
-	 * to manipulate the list
-	 */
-	LGMNAL_TXD_TOKEN_INIT(nal_data, nstx);
-	LGMNAL_TXD_LOCK_INIT(nal_data);
-	
-	for (i=0; i<=nstx; i++) {
-		PORTAL_ALLOC(txd, sizeof(lgmnal_stxd_t));
-		if (!txd) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc txd [%d]\n", i));
-			return(LGMNAL_STATUS_NOMEM);
-		}
-#if 0
-		PORTAL_ALLOC(txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		if (!txbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc txbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(txd, sizeof(lgmnal_stxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_register_memory with port [%p] txbuffer [%p], size [%d]\n",
-				nal_data->gm_port, txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_register_memory(nal_data->gm_port, txbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_register_memory failed buffer [%p], index [%d]\n", txbuffer, i));
-			switch(gm_status) {
-				case(GM_FAILURE):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_FAILURE\n"));
-				break;
-				case(GM_PERMISSION_DENIED):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_PERMISSION_DENIED\n"));
-				break;
-				case(GM_INVALID_PARAMETER):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_INVALID_PARAMETER\n"));
-				break;
-				default:
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Unknown error\n"));
-				break;
-			}
-			return(LGMNAL_STATUS_FAIL);
-		} else {
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_register_memory ok for buffer [%p], index [%d]\n", txbuffer, i));
-		}
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		txbuffer = gm_dma_malloc(nal_data->gm_port, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (!txbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to gm_dma_malloc txbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(txd, sizeof(lgmnal_stxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-#endif
-		
-		txd->buffer = txbuffer;
-		txd->size = LGMNAL_SMALL_MSG_SIZE(nal_data);
-		txd->gmsize = gm_min_size_for_length(txd->size);
-		txd->nal_data = (struct _lgmnal_data_t*)nal_data;
-
-		if (lgmnal_hash_add(&nal_data->stxd_hash, (void*)txbuffer, (void*)txd)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to create hash entry\n"));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		
-
-		txd->next = nal_data->stxd;
-		nal_data->stxd = txd;
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Registered txd [%p] with buffer [%p], size [%d]\n", txd, txd->buffer, txd->size));
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-/*	Free the list of wired and gm_registered small tx buffers and the tx descriptors
-  	that go along with them.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the txd spinlock.
- */
-void
-lgmnal_free_stxd(lgmnal_data_t *nal_data)
-{
-	lgmnal_stxd_t *txd = nal_data->stxd, *_txd = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_free_small tx\n"));
-
-	while(txd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Freeing txd [%p] with buffer [%p], size [%d]\n", txd, txd->buffer, txd->size));
-		_txd = txd;
-		txd = txd->next;
-#if 0
-		LGMNAL_GM_LOCK(nal_data);
-		gm_deregister_memory(nal_data->gm_port, _txd->buffer, _txd->size);
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(_txd->buffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		gm_dma_free(nal_data->gm_port, _txd->buffer);
-		LGMNAL_GM_UNLOCK(nal_data);
-#endif
-		PORTAL_FREE(_txd, sizeof(lgmnal_stxd_t));
-	}
-	return;
-}
-
-
-/*
- *	Get a txd from the list
- *	This get us a wired and gm_registered small tx buffer.
- *	This implicitly gets us a send token also.
- */
-lgmnal_stxd_t *
-lgmnal_get_stxd(lgmnal_data_t *nal_data, int block)
-{
-
-	lgmnal_stxd_t	*txd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_get_stxd nal_data [%p] block[%d]\n", 
-						nal_data, block));
-
-	if (block) {
-		LGMNAL_TXD_GETTOKEN(nal_data);
-	} else {
-		if (LGMNAL_TXD_TRYGETTOKEN(nal_data)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_get_stxd can't get token\n"));
-			return(NULL);
-		}
-	}
-	LGMNAL_TXD_LOCK(nal_data);
-	txd = nal_data->stxd;
-	if (txd)
-		nal_data->stxd = txd->next;
-	LGMNAL_TXD_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_get_stxd got [%p], head is [%p]\n", txd, nal_data->stxd));
-	return(txd);
-}
-
-/*
- *	Return a txd to the list
- */
-void
-lgmnal_return_stxd(lgmnal_data_t *nal_data, lgmnal_stxd_t *txd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_return_stxd nal_data [%p], txd[%p]\n", nal_data, txd));
-
-	LGMNAL_TXD_LOCK(nal_data);
-	txd->next = nal_data->stxd;
-	nal_data->stxd = txd;
-	LGMNAL_TXD_UNLOCK(nal_data);
-	LGMNAL_TXD_RETURNTOKEN(nal_data);
-	return;
-}
-
-
-/*
- *	allocate a number of small rx buffers and register with GM
- *	so they are wired and set up for DMA. This is a costly operation.
- *	Also allocate a corrosponding descriptor to keep track of 
- *	the buffer.
- *	Put all descriptors on singly linked list to be available to receive thread.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the rxd spinlock.
- */
-int
-lgmnal_alloc_srxd(lgmnal_data_t *nal_data)
-{
-	int nrx = 0, nsrx = 0, i = 0;
-	lgmnal_srxd_t	*rxd = NULL;
-	void	*rxbuffer = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_alloc_small rx\n"));
-
-	LGMNAL_GM_LOCK(nal_data);
-	nrx = gm_num_receive_tokens(nal_data->gm_port);
-	LGMNAL_GM_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("total number of receive tokens available is [%d]\n", nrx));
-	
-	nsrx = nrx/2;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocated [%d] receive tokens to small messages\n", nsrx));
-
-
-#ifdef LGMNAL_USE_GM_HASH
-	LGMNAL_GM_LOCK(nal_data);
-	nal_data->srxd_hash = gm_create_hash(gm_hash_compare_ptrs, gm_hash_hash_ptr, 0, sizeof(void*), nsrx, 0);
-	LGMNAL_GM_UNLOCK(nal_data);
-	if (!nal_data->srxd_hash) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to create hash table\n"));
-			return(LGMNAL_STATUS_NOMEM);
-	}
-#else
-	nal_data->srxd_hash = NULL;
-#endif
-
-	LGMNAL_RXD_TOKEN_INIT(nal_data, nsrx);
-	LGMNAL_RXD_LOCK_INIT(nal_data);
-
-	for (i=0; i<=nsrx; i++) {
-		PORTAL_ALLOC(rxd, sizeof(lgmnal_srxd_t));
-		if (!rxd) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc rxd [%d]\n", i));
-			return(LGMNAL_STATUS_NOMEM);
-		}
-#if 0
-		PORTAL_ALLOC(rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		if (!rxbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to malloc rxbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(rxd, sizeof(lgmnal_srxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-		LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_register_memory with port [%p] rxbuffer [%p], size [%d]\n",
-				nal_data->gm_port, rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-		LGMNAL_GM_LOCK(nal_data);
-		gm_status = gm_register_memory(nal_data->gm_port, rxbuffer, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (gm_status != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_register_memory failed buffer [%p], index [%d]\n", rxbuffer, i));
-			switch(gm_status) {
-				case(GM_FAILURE):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_FAILURE\n"));
-				break;
-				case(GM_PERMISSION_DENIED):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_PERMISSION_DENIED\n"));
-				break;
-				case(GM_INVALID_PARAMETER):
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("GM_INVALID_PARAMETER\n"));
-				break;
-				default:
-					LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Unknown GM error[%d]\n", gm_status));
-				break;
-				
-			}
-			return(LGMNAL_STATUS_FAIL);
-		}
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		rxbuffer = gm_dma_malloc(nal_data->gm_port, LGMNAL_SMALL_MSG_SIZE(nal_data));
-		LGMNAL_GM_UNLOCK(nal_data);
-		if (!rxbuffer) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to gm_dma_malloc rxbuffer [%d], size [%d]\n", i, LGMNAL_SMALL_MSG_SIZE(nal_data)));
-			PORTAL_FREE(rxd, sizeof(lgmnal_srxd_t));
-			return(LGMNAL_STATUS_FAIL);
-		}
-#endif
-		
-		rxd->buffer = rxbuffer;
-		rxd->size = LGMNAL_SMALL_MSG_SIZE(nal_data);
-		rxd->gmsize = gm_min_size_for_length(rxd->size);
-
-		if (lgmnal_hash_add(&nal_data->srxd_hash, (void*)rxbuffer, (void*)rxd) != GM_SUCCESS) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to create hash entry rxd[%p] for rxbuffer[%p]\n", rxd, rxbuffer));
-			return(LGMNAL_STATUS_FAIL);
-		}
-
-		rxd->next = nal_data->srxd;
-		nal_data->srxd = rxd;
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Registered rxd [%p] with buffer [%p], size [%d]\n", rxd, rxd->buffer, rxd->size));
-	}
-
-	return(LGMNAL_STATUS_OK);
-}
-
-
-
-/*	Free the list of wired and gm_registered small rx buffers and the rx descriptors
- *	that go along with them.
- *	This function is only called when the API mutex is held (init or shutdown),
- *	so there is no need to hold the rxd spinlock.
- */
-void
-lgmnal_free_srxd(lgmnal_data_t *nal_data)
-{
-	lgmnal_srxd_t *rxd = nal_data->srxd, *_rxd = NULL;
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_free_small rx\n"));
-
-	while(rxd) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Freeing rxd [%p] with buffer [%p], size [%d]\n", rxd, rxd->buffer, rxd->size));
-		_rxd = rxd;
-		rxd = rxd->next;
-
-#if 0
-		LGMNAL_GM_LOCK(nal_data);
-		gm_deregister_memory(nal_data->gm_port, _rxd->buffer, _rxd->size);
-		LGMNAL_GM_UNLOCK(nal_data);
-		PORTAL_FREE(_rxd->buffer, LGMNAL_SMALL_RXBUFFER_SIZE);
-#else
-		LGMNAL_GM_LOCK(nal_data);
-		gm_dma_free(nal_data->gm_port, _rxd->buffer);
-		LGMNAL_GM_UNLOCK(nal_data);
-#endif
-		PORTAL_FREE(_rxd, sizeof(lgmnal_srxd_t));
-	}
-	return;
-}
-
-
-/*
- *	Get a rxd from the free list
- *	This get us a wired and gm_registered small rx buffer.
- *	This implicitly gets us a receive token also.
- */
-lgmnal_srxd_t *
-lgmnal_get_srxd(lgmnal_data_t *nal_data, int block)
-{
-
-	lgmnal_srxd_t	*rxd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_get_srxd nal_data [%p] block [%d]\n", nal_data, block));
-
-	if (block) {
-		LGMNAL_RXD_GETTOKEN(nal_data);
-	} else {
-		if (LGMNAL_RXD_TRYGETTOKEN(nal_data)) {
-			LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_get_srxd Can't get token\n"));
-			return(NULL);
-		}
-	}
-	LGMNAL_RXD_LOCK(nal_data);
-	rxd = nal_data->srxd;
-	if (rxd)
-		nal_data->srxd = rxd->next;
-	LGMNAL_RXD_UNLOCK(nal_data);
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_get_srxd got [%p], head is [%p]\n", rxd, nal_data->srxd));
-	return(rxd);
-}
-
-/*
- *	Return an rxd to the list
- */
-void
-lgmnal_return_srxd(lgmnal_data_t *nal_data, lgmnal_srxd_t *rxd)
-{
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_return_srxd nal_data [%p], rxd[%p]\n", nal_data, rxd));
-
-	LGMNAL_RXD_LOCK(nal_data);
-	rxd->next = nal_data->srxd;
-	nal_data->srxd = rxd;
-	LGMNAL_RXD_UNLOCK(nal_data);
-	LGMNAL_RXD_RETURNTOKEN(nal_data);
-	return;
-}
-
-/*
- *	Given a pointer to a srxd find 
- *	the relevant descriptor for it
- *	This is done by searching a hash
- *	list that is created when the srxd's 
- *	are created
- */
-lgmnal_srxd_t *
-lgmnal_rxbuffer_to_srxd(lgmnal_data_t *nal_data, void *rxbuffer)
-{
-	lgmnal_srxd_t	*srxd = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_rxbuffer_to_srxd nal_data [%p], rxbuffer [%p]\n", nal_data, rxbuffer));
-#ifdef LGMNAL_USE_GM_HASH
-	srxd = gm_hash_find(nal_data->srxd_hash, rxbuffer);
-#else
-	srxd = lgmnal_hash_find(nal_data->srxd_hash, rxbuffer);
-#endif
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("srxd is [%p]\n", srxd));
-	return(srxd);
-}
-
-
-void
-lgmnal_stop_rxthread(lgmnal_data_t *nal_data)
-{
-	int 	delay = 15;
-
-
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("Attempting to stop rxthread nal_data [%p]\n", nal_data));
-	
-	if (nal_data->rxthread_flag != LGMNAL_THREAD_CONTINUE) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("thread flag not correctly set\n"));
-	}	
-
-	nal_data->rxthread_flag = LGMNAL_THREAD_STOP;
-	LGMNAL_GM_LOCK(nal_data);
-	gm_set_alarm(nal_data->gm_port, &nal_data->rxthread_alarm, 10, NULL, NULL);
-	LGMNAL_GM_UNLOCK(nal_data);
-
-	while(nal_data->rxthread_flag == LGMNAL_THREAD_STOP && delay--) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_stop_rxthread sleeping\n"));
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1024);
-	}
-
-	if (nal_data->rxthread_flag == LGMNAL_THREAD_STOP) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("I DON'T KNOW HOW TO WAKE THE THREAD\n"));
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("RX THREAD SEEMS TO HAVE STOPPED\n"));
-	}
-
-}
-
-
-
-char * 
-lgmnal_gm_error(gm_status_t status)
-{
-	switch(status) {
-		case(GM_SUCCESS):
-			return("SUCCESS");
-  		case(GM_FAILURE):
-			return("FAILURE");
-  		case(GM_INPUT_BUFFER_TOO_SMALL):
-			return("INPUT_BUFFER_TOO_SMALL");
-  		case(GM_OUTPUT_BUFFER_TOO_SMALL):
-			return("OUTPUT_BUFFER_TOO_SMALL");
-  		case(GM_TRY_AGAIN ):
-			return("TRY_AGAIN");
-  		case(GM_BUSY):
-			return("BUSY");
-  		case(GM_MEMORY_FAULT):
-			return("MEMORY_FAULT");
-  		case(GM_INTERRUPTED):
-			return("INTERRUPTED");
-  		case(GM_INVALID_PARAMETER):
-			return("INVALID_PARAMETER");
-  		case(GM_OUT_OF_MEMORY):
-			return("OUT_OF_MEMORY");
-  		case(GM_INVALID_COMMAND):
-			return("INVALID_COMMAND");
-  		case(GM_PERMISSION_DENIED):
-			return("PERMISSION_DENIED");
-  		case(GM_INTERNAL_ERROR):
-			return("INTERNAL_ERROR");
-  		case(GM_UNATTACHED):
-			return("UNATTACHED");
-  		case(GM_UNSUPPORTED_DEVICE):
-			return("UNSUPPORTED_DEVICE");
-  		case(GM_SEND_TIMED_OUT):
-			return("GM_SEND_TIMEDOUT");
-  		case(GM_SEND_REJECTED):
-			return("GM_SEND_REJECTED");
-  		case(GM_SEND_TARGET_PORT_CLOSED):
-			return("GM_SEND_TARGET_PORT_CLOSED");
-  		case(GM_SEND_TARGET_NODE_UNREACHABLE):
-			return("GM_SEND_TARGET_NODE_UNREACHABLE");
-  		case(GM_SEND_DROPPED):
-			return("GM_SEND_DROPPED");
-  		case(GM_SEND_PORT_CLOSED):
-			return("GM_SEND_PORT_CLOSED");
-  		case(GM_NODE_ID_NOT_YET_SET):
-			return("GM_NODE_ID_NOT_YET_SET");
-  		case(GM_STILL_SHUTTING_DOWN):
-			return("GM_STILL_SHUTTING_DOWN");
-  		case(GM_CLONE_BUSY):
-			return("GM_CLONE_BUSY");
-  		case(GM_NO_SUCH_DEVICE):
-			return("GM_NO_SUCH_DEVICE");
-  		case(GM_ABORTED):
-			return("GM_ABORTED");
-  		case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
-			return("GM_INCOMPATIBLE_LIB_AND_DRIVER");
-  		case(GM_UNTRANSLATED_SYSTEM_ERROR):
-			return("GM_UNTRANSLATED_SYSTEM_ERROR");
-  		case(GM_ACCESS_DENIED):
-			return("GM_ACCESS_DENIED");
-
-
-/*
- *	These ones are in the docs but aren't in the header file 
-  		case(GM_DEV_NOT_FOUND):
-			return("GM_DEV_NOT_FOUND");
-  		case(GM_INVALID_PORT_NUMBER):
-			return("GM_INVALID_PORT_NUMBER");
-  		case(GM_UC_ERROR):
-			return("GM_US_ERROR");
-  		case(GM_PAGE_TABLE_FULL):
-			return("GM_PAGE_TABLE_FULL");
-  		case(GM_MINOR_OVERFLOW):
-			return("GM_MINOR_OVERFLOW");
-  		case(GM_SEND_ORPHANED):
-			return("GM_SEND_ORPHANED");
-  		case(GM_HARDWARE_FAULT):
-			return("GM_HARDWARE_FAULT");
-  		case(GM_DATA_CORRUPTED):
-			return("GM_DATA_CORRUPTED");
-  		case(GM_TIMED_OUT):
-			return("GM_TIMED_OUT");
-  		case(GM_USER_ERROR):
-			return("GM_USER_ERROR");
-  		case(GM_NO_MATCH):
-			return("GM_NOMATCH");
-  		case(GM_NOT_SUPPORTED_IN_KERNEL):
-			return("GM_NOT_SUPPORTED_IN_KERNEL");
-  		case(GM_NOT_SUPPORTED_ON_ARCH):
-			return("GM_NOT_SUPPORTED_ON_ARCH");
-  		case(GM_PTE_REF_CNT_OVERFLOW):
-			return("GM_PTR_REF_CNT_OVERFLOW");
-  		case(GM_NO_DRIVER_SUPPORT):
-			return("GM_NO_DRIVER_SUPPORT");
-  		case(GM_FIRMWARE_NOT_RUNNING):
-			return("GM_FIRMWARE_NOT_RUNNING");
-
- *	These ones are in the docs but aren't in the header file 
- */
-		default:
-			return("UNKNOWN GM ERROR CODE");
-	}
-}
-
-
-char *
-lgmnal_rxevent(gm_recv_event_t	*ev)
-{
-	short	event;
-	char	msg[24];
-	event = GM_RECV_EVENT_TYPE(ev);
-	switch(event) {
-  		case(GM_NO_RECV_EVENT):
-			return("GM_NO_RECV_EVENT");
-  		case(GM_SENDS_FAILED_EVENT):
-			return("GM_SEND_FAILED_EVENT");
-  		case(GM_ALARM_EVENT):
-			return("GM_ALARM_EVENT");
-  		case(GM_SENT_EVENT):
-			return("GM_SENT_EVENT");
-  		case(_GM_SLEEP_EVENT):
-			return("_GM_SLEEP_EVENT");
-  		case(GM_RAW_RECV_EVENT):
-			return("GM_RAW_RECV_EVENT");
-  		case(GM_BAD_SEND_DETECTED_EVENT):
-			return("GM_BAD_SEND_DETECTED_EVENT");
-  		case(GM_SEND_TOKEN_VIOLATION_EVENT):
-			return("GM_SEND_TOKEN_VIOLATION_EVENT");
-  		case(GM_RECV_TOKEN_VIOLATION_EVENT):
-			return("GM_RECV_TOKEN_VIOLATION_EVENT");
-  		case(GM_BAD_RECV_TOKEN_EVENT):
-			return("GM_BAD_RECV_TOKEN_EVENT");
-  		case(GM_ALARM_VIOLATION_EVENT):
-			return("GM_ALARM_VIOLATION_EVENT");
-  		case(GM_RECV_EVENT):
-			return("GM_RECV_EVENT");
-  		case(GM_HIGH_RECV_EVENT):
-			return("GM_HIGH_RECV_EVENT");
-  		case(GM_PEER_RECV_EVENT):
-			return("GM_PEER_RECV_EVENT");
-  		case(GM_HIGH_PEER_RECV_EVENT):
-			return("GM_HIGH_PEER_RECV_EVENT");
-  		case(GM_FAST_RECV_EVENT):
-			return("GM_FAST_RECV_EVENT");
-  		case(GM_FAST_HIGH_RECV_EVENT):
-			return("GM_FAST_HIGH_RECV_EVENT");
-  		case(GM_FAST_PEER_RECV_EVENT):
-			return("GM_FAST_PEER_RECV_EVENT");
-  		case(GM_FAST_HIGH_PEER_RECV_EVENT):
-			return("GM_FAST_HIGH_PEER_RECV_EVENT");
-  		case(GM_REJECTED_SEND_EVENT):
-			return("GM_REJECTED_SEND_EVENT");
-  		case(GM_ORPHANED_SEND_EVENT):
-			return("GM_ORPHANED_SEND_EVENT");
-  		case(GM_BAD_RESEND_DETECTED_EVENT):
-			return("GM_BAD_RESEND_DETETED_EVENT");
-  		case(GM_DROPPED_SEND_EVENT):
-			return("GM_DROPPED_SEND_EVENT");
-  		case(GM_BAD_SEND_VMA_EVENT):
-			return("GM_BAD_SEND_VMA_EVENT");
-  		case(GM_BAD_RECV_VMA_EVENT):
-			return("GM_BAD_RECV_VMA_EVENT");
-  		case(_GM_FLUSHED_ALARM_EVENT):
-			return("GM_FLUSHED_ALARM_EVENT");
-  		case(GM_SENT_TOKENS_EVENT):
-			return("GM_SENT_TOKENS_EVENTS");
-  		case(GM_IGNORE_RECV_EVENT):
-			return("GM_IGNORE_RECV_EVENT");
-  		case(GM_ETHERNET_RECV_EVENT):
-			return("GM_ETHERNET_RECV_EVENT");
-  		case(GM_NEW_NO_RECV_EVENT):
-			return("GM_NEW_NO_RECV_EVENT");
-  		case(GM_NEW_SENDS_FAILED_EVENT):
-			return("GM_NEW_SENDS_FAILED_EVENT");
-  		case(GM_NEW_ALARM_EVENT):
-			return("GM_NEW_ALARM_EVENT");
-  		case(GM_NEW_SENT_EVENT):
-			return("GM_NEW_SENT_EVENT");
-  		case(_GM_NEW_SLEEP_EVENT):
-			return("GM_NEW_SLEEP_EVENT");
-  		case(GM_NEW_RAW_RECV_EVENT):
-			return("GM_NEW_RAW_RECV_EVENT");
-  		case(GM_NEW_BAD_SEND_DETECTED_EVENT):
-			return("GM_NEW_BAD_SEND_DETECTED_EVENT");
-  		case(GM_NEW_SEND_TOKEN_VIOLATION_EVENT):
-			return("GM_NEW_SEND_TOKEN_VIOLATION_EVENT");
-  		case(GM_NEW_RECV_TOKEN_VIOLATION_EVENT):
-			return("GM_NEW_RECV_TOKEN_VIOLATION_EVENT");
-  		case(GM_NEW_BAD_RECV_TOKEN_EVENT):
-			return("GM_NEW_BAD_RECV_TOKEN_EVENT");
-  		case(GM_NEW_ALARM_VIOLATION_EVENT):
-			return("GM_NEW_ALARM_VIOLATION_EVENT");
-  		case(GM_NEW_RECV_EVENT):
-			return("GM_NEW_RECV_EVENT");
-  		case(GM_NEW_HIGH_RECV_EVENT):
-			return("GM_NEW_HIGH_RECV_EVENT");
-  		case(GM_NEW_PEER_RECV_EVENT):
-			return("GM_NEW_PEER_RECV_EVENT");
-  		case(GM_NEW_HIGH_PEER_RECV_EVENT):
-			return("GM_NEW_HIGH_PEER_RECV_EVENT");
-  		case(GM_NEW_FAST_RECV_EVENT):
-			return("GM_NEW_FAST_RECV_EVENT");
-  		case(GM_NEW_FAST_HIGH_RECV_EVENT):
-			return("GM_NEW_FAST_HIGH_RECV_EVENT");
-  		case(GM_NEW_FAST_PEER_RECV_EVENT):
-			return("GM_NEW_FAST_PEER_RECV_EVENT");
-  		case(GM_NEW_FAST_HIGH_PEER_RECV_EVENT):
-			return("GM_NEW_FAST_HIGH_PEER_RECV_EVENT");
-  		case(GM_NEW_REJECTED_SEND_EVENT):
-			return("GM_NEW_REJECTED_SEND_EVENT");
-  		case(GM_NEW_ORPHANED_SEND_EVENT):
-			return("GM_NEW_ORPHANED_SEND_EVENT");
-  		case(_GM_NEW_PUT_NOTIFICATION_EVENT):
-			return("_GM_NEW_PUT_NOTIFICATION_EVENT");
-  		case(GM_NEW_FREE_SEND_TOKEN_EVENT):
-			return("GM_NEW_FREE_SEND_TOKEN_EVENT");
-  		case(GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT):
-			return("GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT");
-  		case(GM_NEW_BAD_RESEND_DETECTED_EVENT):
-			return("GM_NEW_BAD_RESEND_DETECTED_EVENT");
-  		case(GM_NEW_DROPPED_SEND_EVENT):
-			return("GM_NEW_DROPPED_SEND_EVENT");
-  		case(GM_NEW_BAD_SEND_VMA_EVENT):
-			return("GM_NEW_BAD_SEND_VMA_EVENT");
-  		case(GM_NEW_BAD_RECV_VMA_EVENT):
-			return("GM_NEW_BAD_RECV_VMA_EVENT");
-  		case(_GM_NEW_FLUSHED_ALARM_EVENT):
-			return("GM_NEW_FLUSHED_ALARM_EVENT");
-  		case(GM_NEW_SENT_TOKENS_EVENT):
-			return("GM_NEW_SENT_TOKENS_EVENT");
-  		case(GM_NEW_IGNORE_RECV_EVENT):
-			return("GM_NEW_IGNORE_RECV_EVENT");
-  		case(GM_NEW_ETHERNET_RECV_EVENT):
-			return("GM_NEW_ETHERNET_RECV_EVENT");
-		default:
-			snprintf(msg, 24,  "Unknown Recv event [%d]", event);
-			return(msg);
-#if 0
-  		case(/* _GM_PUT_NOTIFICATION_EVENT */
-  		case(/* GM_FREE_SEND_TOKEN_EVENT */
-  		case(/* GM_FREE_HIGH_SEND_TOKEN_EVENT */
-#endif
-	}
-}
-
-
-void
-lgmnal_yield(int delay)
-{
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(delay);
-}
-
-int
-lgmnal_is_small_message(lgmnal_data_t *nal_data, int niov, struct iovec *iov, int len)
-{
-
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_is_small_message len is [%d]\n", len));
-	if (len < LGMNAL_SMALL_MSG_SIZE(nal_data)) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Yep, small message]\n"));
-		return(1);
-	} else {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No, not small message]\n"));
-		return(0);
-	}
-}
-
-void *
-lgmnal_hash_find(lgmnal_hash_t *hash, void *key)
-{
-	void 	*data = NULL;
-	int	count = 0;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_find hash [%p] key [%p]\n", hash, key));
-
-	while (hash) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find Stepping [%d]\n", count++));
-		if (hash->key == key) {
-			data = hash->data;
-			LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find hash got data[%p]\n", data));
-			return(data);
-		} else
-			hash = hash->next;
-	}
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_find data not found\n"));
-	return(NULL);
-}
-
-/* 
- *	TO DO hash. figure out why getting bad stuff from gm_hash and thne use it.
- */
-
-int
-lgmnal_hash_add(lgmnal_hash_t **hash, void *key, void *data)
-{
-	
-#ifdef LGMNAL_USE_GM_HASH
-	return(gm_hash_insert(*hash, (void*)key, (void*)data);
-#else
-	lgmnal_hash_t	*new = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_add hash [%p]\n", *hash));
-	PORTAL_ALLOC(new, sizeof(lgmnal_hash_t));
-	memset(new, 0, sizeof(lgmnal_hash_t));
-	if (!new) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_hash_add :: can't get memory\n"));
-		return(-1);
-	}
-	new->data = data;
-	new->key = key;
-	new->next = *hash;
-	*hash = new;
-	LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_add hash head [%p]\n", *hash));
-	return(0);
-#endif
-}
-
-void
-lgmnal_hash_free(lgmnal_hash_t **hash)
-{
-	
-	lgmnal_hash_t	*_hash = NULL;
-	LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_hash_free hash [p%]\n", *hash));
-	
-	while (*hash) {
-		LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_hash_free freeing hash [p%]\n", _hash));
-		_hash = *hash;
-		*hash = _hash->next;
-		PORTAL_FREE(_hash, sizeof(lgmnal_hash_t));
-	}
-	return;
-}
-
-
-EXPORT_SYMBOL(lgmnal_yield);
-EXPORT_SYMBOL(lgmnal_print);
-EXPORT_SYMBOL(lgmnal_alloc_srxd);
-EXPORT_SYMBOL(lgmnal_get_srxd);
-EXPORT_SYMBOL(lgmnal_return_srxd);
-EXPORT_SYMBOL(lgmnal_free_srxd);
-EXPORT_SYMBOL(lgmnal_alloc_stxd);
-EXPORT_SYMBOL(lgmnal_get_stxd);
-EXPORT_SYMBOL(lgmnal_return_stxd);
-EXPORT_SYMBOL(lgmnal_free_stxd);
-EXPORT_SYMBOL(lgmnal_rxbuffer_to_srxd);
-EXPORT_SYMBOL(lgmnal_rxevent);
-EXPORT_SYMBOL(lgmnal_gm_error);
-EXPORT_SYMBOL(lgmnal_stop_rxthread);
diff --git a/lustre/portals/knals/qswnal/qswnal.c b/lustre/portals/knals/qswnal/qswnal.c
index 0841d641dc3134709c69e280a35b9feb46f74913..70b45c0a61dadac04402f2adcbccd2b2c8a77a30 100644
--- a/lustre/portals/knals/qswnal/qswnal.c
+++ b/lustre/portals/knals/qswnal/qswnal.c
@@ -113,12 +113,12 @@ kqswnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size,
 }
 
 int
-kqswnal_get_tx_desc (struct portal_ioctl_data *data)
+kqswnal_get_tx_desc (struct portals_cfg *pcfg)
 {
 	unsigned long      flags;
 	struct list_head  *tmp;
 	kqswnal_tx_t      *ktx;
-	int                index = data->ioc_count;
+	int                index = pcfg->pcfg_count;
 	int                rc = -ENOENT;
 
 	spin_lock_irqsave (&kqswnal_data.kqn_idletxd_lock, flags);
@@ -126,19 +126,18 @@ kqswnal_get_tx_desc (struct portal_ioctl_data *data)
 	list_for_each (tmp, &kqswnal_data.kqn_activetxds) {
 		if (index-- != 0)
 			continue;
-		
-		ktx = list_entry (tmp, kqswnal_tx_t, ktx_list);
 
-		data->ioc_pbuf1 = (char *)ktx;
-		data->ioc_count = NTOH__u32(ktx->ktx_wire_hdr->type);
-		data->ioc_size  = NTOH__u32(PTL_HDR_LENGTH(ktx->ktx_wire_hdr));
-		data->ioc_nid   = NTOH__u64(ktx->ktx_wire_hdr->dest_nid);
-		data->ioc_nid2  = ktx->ktx_nid;
-		data->ioc_misc  = ktx->ktx_launcher;
-		data->ioc_flags = (list_empty (&ktx->ktx_delayed_list) ? 0 : 1) |
-				  ((!ktx->ktx_forwarding)              ? 0 : 2) |
-				  ((!ktx->ktx_isnblk)                  ? 0 : 4);
+		ktx = list_entry (tmp, kqswnal_tx_t, ktx_list);
 
+		pcfg->pcfg_pbuf1 = (char *)ktx;
+		pcfg->pcfg_count = NTOH__u32(ktx->ktx_wire_hdr->type);
+		pcfg->pcfg_size  = NTOH__u32(ktx->ktx_wire_hdr->payload_length);
+		pcfg->pcfg_nid   = NTOH__u64(ktx->ktx_wire_hdr->dest_nid);
+		pcfg->pcfg_nid2  = ktx->ktx_nid;
+		pcfg->pcfg_misc  = ktx->ktx_launcher;
+		pcfg->pcfg_flags = (list_empty (&ktx->ktx_delayed_list) ? 0 : 1) |
+				  (!ktx->ktx_isnblk                    ? 0 : 2) |
+				  (ktx->ktx_state << 2);
 		rc = 0;
 		break;
 	}
@@ -148,21 +147,21 @@ kqswnal_get_tx_desc (struct portal_ioctl_data *data)
 }
 
 int
-kqswnal_cmd (struct portal_ioctl_data *data, void *private)
+kqswnal_cmd (struct portals_cfg *pcfg, void *private)
 {
-	LASSERT (data != NULL);
+	LASSERT (pcfg != NULL);
 	
-	switch (data->ioc_nal_cmd) {
+	switch (pcfg->pcfg_command) {
 	case NAL_CMD_GET_TXDESC:
-		return (kqswnal_get_tx_desc (data));
+		return (kqswnal_get_tx_desc (pcfg));
 
 	case NAL_CMD_REGISTER_MYNID:
 		CDEBUG (D_IOCTL, "setting NID offset to "LPX64" (was "LPX64")\n",
-			data->ioc_nid - kqswnal_data.kqn_elanid,
+			pcfg->pcfg_nid - kqswnal_data.kqn_elanid,
 			kqswnal_data.kqn_nid_offset);
 		kqswnal_data.kqn_nid_offset =
-			data->ioc_nid - kqswnal_data.kqn_elanid;
-		kqswnal_lib.ni.nid = data->ioc_nid;
+			pcfg->pcfg_nid - kqswnal_data.kqn_elanid;
+		kqswnal_lib.ni.nid = pcfg->pcfg_nid;
 		return (0);
 		
 	default:
@@ -180,6 +179,7 @@ kqswnal_finalise (void)
 
 	case KQN_INIT_ALL:
 		PORTAL_SYMBOL_UNREGISTER (kqswnal_ni);
+                kportal_nal_unregister(QSWNAL);
 		/* fall through */
 
 	case KQN_INIT_PTL:
@@ -188,6 +188,7 @@ kqswnal_finalise (void)
 		/* fall through */
 
 	case KQN_INIT_DATA:
+		LASSERT(list_empty(&kqswnal_data.kqn_activetxds));
 		break;
 
 	case KQN_INIT_NOTHING:
@@ -323,7 +324,7 @@ kqswnal_finalise (void)
 
 	CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read(&portal_kmemory));
 
-	printk (KERN_INFO "Routing QSW NAL unloaded (final mem %d)\n",
+	printk (KERN_INFO "Lustre: Routing QSW NAL unloaded (final mem %d)\n",
                 atomic_read(&portal_kmemory));
 }
 
@@ -423,12 +424,14 @@ kqswnal_initialise (void)
 	}
 
 	/**********************************************************************/
-	/* Reserve Elan address space for transmit buffers */
+	/* Reserve Elan address space for transmit descriptors NB we may
+	 * either send the contents of associated buffers immediately, or
+	 * map them for the peer to suck/blow... */
 
         dmareq.Waitfn   = DDI_DMA_SLEEP;
         dmareq.ElanAddr = (E3_Addr) 0;
         dmareq.Attr     = PTE_LOAD_LITTLE_ENDIAN;
-        dmareq.Perm     = ELAN_PERM_REMOTEREAD;
+        dmareq.Perm     = ELAN_PERM_REMOTEWRITE;
 
 	rc = elan3_dma_reserve(kqswnal_data.kqn_epdev->DmaState,
 			      KQSW_NTXMSGPAGES*(KQSW_NTXMSGS+KQSW_NNBLK_TXMSGS),
@@ -500,6 +503,7 @@ kqswnal_initialise (void)
 
 		INIT_LIST_HEAD (&ktx->ktx_delayed_list);
 
+		ktx->ktx_state = KTX_IDLE;
 		ktx->ktx_isnblk = (i >= KQSW_NTXMSGS);
 		list_add_tail (&ktx->ktx_list, 
 			       ktx->ktx_isnblk ? &kqswnal_data.kqn_nblk_idletxds :
@@ -592,7 +596,7 @@ kqswnal_initialise (void)
 		rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
 				      krx->krx_elanaddr,
 				      krx->krx_npages * PAGE_SIZE, 0);
-		if (rc != 0)
+		if (rc != ESUCCESS)
 		{
 			CERROR ("failed ep_queue_receive %d\n", rc);
 			kqswnal_finalise ();
@@ -628,7 +632,7 @@ kqswnal_initialise (void)
 	PORTAL_SYMBOL_REGISTER(kqswnal_ni);
 	kqswnal_data.kqn_init = KQN_INIT_ALL;
 
-	printk(KERN_INFO "Routing QSW NAL loaded on node %d of %d "
+	printk(KERN_INFO "Lustre: Routing QSW NAL loaded on node %d of %d "
 	       "(Routing %s, initial mem %d)\n", 
 	       kqswnal_data.kqn_elanid, kqswnal_data.kqn_nnodes,
 	       kpr_routing (&kqswnal_data.kqn_router) ? "enabled" : "disabled",
diff --git a/lustre/portals/knals/qswnal/qswnal.h b/lustre/portals/knals/qswnal/qswnal.h
index 0d8e2fa61d59de54787c60beab6f12e81d5aaef1..4cb9ad9f8357c5062156bdd290a4319d576b18ed 100644
--- a/lustre/portals/knals/qswnal/qswnal.h
+++ b/lustre/portals/knals/qswnal/qswnal.h
@@ -24,7 +24,9 @@
 
 #ifndef _QSWNAL_H
 #define _QSWNAL_H
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #ifdef PROPRIETARY_ELAN
 # include <qsw/kernel.h>
@@ -73,6 +75,8 @@
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
 
+#define KQSW_OPTIMIZE_GETS 1
+
 #define KQSW_CHECKSUM   0
 #if KQSW_CHECKSUM
 typedef unsigned long kqsw_csum_t;
@@ -93,12 +97,7 @@ typedef unsigned long kqsw_csum_t;
  * Performance Tuning defines
  * NB no mention of PAGE_SIZE for interoperability
  */
-#if PTL_LARGE_MTU
-# define KQSW_MAXPAYLOAD                (256<<10) /* biggest message this NAL will cope with */
-#else
-# define KQSW_MAXPAYLOAD                (64<<10) /* biggest message this NAL will cope with */
-#endif
-
+#define KQSW_MAXPAYLOAD                 PTL_MTU
 #define KQSW_SMALLPAYLOAD               ((4<<10) - KQSW_HDR_SIZE) /* small/large ep receiver breakpoint */
 
 #define KQSW_TX_MAXCONTIG               (1<<10) /* largest payload that gets made contiguous on transmit */
@@ -134,6 +133,12 @@ typedef unsigned long kqsw_csum_t;
 #define KQSW_NRXMSGBYTES_LARGE  (KQSW_NRXMSGPAGES_LARGE * PAGE_SIZE)
 /* biggest complete packet we can receive (or transmit) */
 
+/* Remote memory descriptor */
+typedef struct
+{
+        __u32            kqrmd_neiov;           /* # frags */
+        EP_IOVEC         kqrmd_eiov[0];         /* actual frags */
+} kqswnal_remotemd_t;
 
 typedef struct 
 {
@@ -143,6 +148,8 @@ typedef struct
         E3_Addr          krx_elanaddr;          /* Elan address of buffer (contiguous in elan vm) */
         int              krx_npages;            /* # pages in receive buffer */
         int              krx_nob;               /* Number Of Bytes received into buffer */
+        atomic_t         krx_refcount;          /* who's using me? */
+        int              krx_rpc_completed;     /* I completed peer's RPC */
         kpr_fwd_desc_t   krx_fwd;               /* embedded forwarding descriptor */
         struct page     *krx_pages[KQSW_NRXMSGPAGES_LARGE]; /* pages allocated */
         struct iovec     krx_iov[KQSW_NRXMSGPAGES_LARGE]; /* iovec for forwarding */
@@ -153,12 +160,10 @@ typedef struct
         struct list_head  ktx_list;             /* enqueue idle/active */
         struct list_head  ktx_delayed_list;     /* enqueue delayedtxds */
         int               ktx_isnblk:1;         /* reserved descriptor? */
-        int               ktx_forwarding:1;     /* forwarding (rather than local send) */
+        int               ktx_state:7;          /* What I'm doing */
         uint32_t          ktx_basepage;         /* page offset in reserved elan tx vaddrs for mapping pages */
         int               ktx_npages;           /* pages reserved for mapping messages */
         int               ktx_nmappedpages;     /* # pages mapped for current message */
-        EP_IOVEC          ktx_iov[EP_MAXFRAG];  /* msg frags (elan vaddrs) */
-        int               ktx_niov;             /* # message frags */
         int               ktx_port;             /* destination ep port */
         ptl_nid_t         ktx_nid;              /* destination node */
         void             *ktx_args[2];          /* completion passthru */
@@ -169,8 +174,19 @@ typedef struct
         /* debug/info fields */
         pid_t             ktx_launcher;         /* pid of launching process */
         ptl_hdr_t        *ktx_wire_hdr;         /* portals header (wire endian) */
+
+        int               ktx_nfrag;            /* # message frags */
+        union {
+                EP_IOVEC   iov[EP_MAXFRAG];     /* msg frags (elan vaddrs) */
+                EP_DATAVEC datav[EP_MAXFRAG];   /* DMA frags (eolan vaddrs) */
+        }                 ktx_frags;
 } kqswnal_tx_t;
 
+#define KTX_IDLE        0                       /* on kqn_(nblk_)idletxds */
+#define KTX_SENDING     1                       /* local send */
+#define KTX_FORWARDING  2                       /* routing a packet */
+#define KTX_GETTING     3                       /* local optimised get */
+
 typedef struct
 {
         char               kqn_init;            /* what's been initialised */
@@ -223,6 +239,8 @@ extern int kqswnal_thread_start (int (*fn)(void *arg), void *arg);
 extern void kqswnal_rxhandler(EP_RXD *rxd);
 extern int kqswnal_scheduler (void *);
 extern void kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd);
+extern void kqswnal_reply_complete (EP_RXD *rxd);
+extern void kqswnal_requeue_rx (kqswnal_rx_t *krx);
 
 static inline ptl_nid_t
 kqswnal_elanid2nid (int elanid) 
@@ -241,13 +259,6 @@ kqswnal_nid2elanid (ptl_nid_t nid)
         return (nid - kqswnal_data.kqn_nid_offset);
 }
 
-static inline void
-kqswnal_requeue_rx (kqswnal_rx_t *krx)
-{
-        ep_requeue_receive (krx->krx_rxd, kqswnal_rxhandler, krx,
-                            krx->krx_elanaddr, krx->krx_npages * PAGE_SIZE);
-}
-
 static inline int
 kqswnal_pages_spanned (void *base, int nob)
 {
diff --git a/lustre/portals/knals/qswnal/qswnal_cb.c b/lustre/portals/knals/qswnal/qswnal_cb.c
index 9452fafe019ac138201b486cca9cdc4fef6454de..43926c9ac35fc835f483dab95f3af16eff493140 100644
--- a/lustre/portals/knals/qswnal/qswnal_cb.c
+++ b/lustre/portals/knals/qswnal/qswnal_cb.c
@@ -26,11 +26,6 @@
 
 #include "qswnal.h"
 
-atomic_t kqswnal_packets_launched;
-atomic_t kqswnal_packets_transmitted;
-atomic_t kqswnal_packets_received;
-
-
 /*
  *  LIB functions follow
  *
@@ -137,7 +132,7 @@ kqswnal_unmap_tx (kqswnal_tx_t *ktx)
                 return;
 
         CDEBUG (D_NET, "%p[%d] unloading pages %d for %d\n",
-                ktx, ktx->ktx_niov, ktx->ktx_basepage, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_basepage, ktx->ktx_nmappedpages);
 
         LASSERT (ktx->ktx_nmappedpages <= ktx->ktx_npages);
         LASSERT (ktx->ktx_basepage + ktx->ktx_nmappedpages <=
@@ -152,15 +147,14 @@ kqswnal_unmap_tx (kqswnal_tx_t *ktx)
 int
 kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 {
-        int       nfrags    = ktx->ktx_niov;
-        const int maxfrags  = sizeof (ktx->ktx_iov)/sizeof (ktx->ktx_iov[0]);
+        int       nfrags    = ktx->ktx_nfrag;
         int       nmapped   = ktx->ktx_nmappedpages;
         int       maxmapped = ktx->ktx_npages;
         uint32_t  basepage  = ktx->ktx_basepage + nmapped;
         char     *ptr;
         
         LASSERT (nmapped <= maxmapped);
-        LASSERT (nfrags <= maxfrags);
+        LASSERT (nfrags <= EP_MAXFRAG);
         LASSERT (niov > 0);
         LASSERT (nob > 0);
         
@@ -179,9 +173,9 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                         return (-EMSGSIZE);
                 }
 
-                if (nfrags == maxfrags) {
+                if (nfrags == EP_MAXFRAG) {
                         CERROR("Message too fragmented in Elan VM (max %d frags)\n",
-                               maxfrags);
+                               EP_MAXFRAG);
                         return (-EMSGSIZE);
                 }
 
@@ -197,7 +191,7 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                 elan3_dvma_kaddr_load (kqswnal_data.kqn_epdev->DmaState,
                                        kqswnal_data.kqn_eptxdmahandle,
                                        ptr, fraglen,
-                                       basepage, &ktx->ktx_iov[nfrags].Base);
+                                       basepage, &ktx->ktx_frags.iov[nfrags].Base);
 
                 kunmap (kiov->kiov_page);
                 
@@ -205,12 +199,12 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
                 ktx->ktx_nmappedpages = nmapped;
 
                 if (nfrags > 0 &&                /* previous frag mapped */
-                    ktx->ktx_iov[nfrags].Base == /* contiguous with this one */
-                    (ktx->ktx_iov[nfrags-1].Base + ktx->ktx_iov[nfrags-1].Len))
+                    ktx->ktx_frags.iov[nfrags].Base == /* contiguous with this one */
+                    (ktx->ktx_frags.iov[nfrags-1].Base + ktx->ktx_frags.iov[nfrags-1].Len))
                         /* just extend previous */
-                        ktx->ktx_iov[nfrags - 1].Len += fraglen;
+                        ktx->ktx_frags.iov[nfrags - 1].Len += fraglen;
                 else {
-                        ktx->ktx_iov[nfrags].Len = fraglen;
+                        ktx->ktx_frags.iov[nfrags].Len = fraglen;
                         nfrags++;                /* new frag */
                 }
 
@@ -224,9 +218,9 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 
         } while (nob > 0);
 
-        ktx->ktx_niov = nfrags;
+        ktx->ktx_nfrag = nfrags;
         CDEBUG (D_NET, "%p got %d frags over %d pages\n",
-                ktx, ktx->ktx_niov, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_nmappedpages);
 
         return (0);
 }
@@ -234,14 +228,13 @@ kqswnal_map_tx_kiov (kqswnal_tx_t *ktx, int nob, int niov, ptl_kiov_t *kiov)
 int
 kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
 {
-        int       nfrags    = ktx->ktx_niov;
-        const int maxfrags  = sizeof (ktx->ktx_iov)/sizeof (ktx->ktx_iov[0]);
+        int       nfrags    = ktx->ktx_nfrag;
         int       nmapped   = ktx->ktx_nmappedpages;
         int       maxmapped = ktx->ktx_npages;
         uint32_t  basepage  = ktx->ktx_basepage + nmapped;
 
         LASSERT (nmapped <= maxmapped);
-        LASSERT (nfrags <= maxfrags);
+        LASSERT (nfrags <= EP_MAXFRAG);
         LASSERT (niov > 0);
         LASSERT (nob > 0);
 
@@ -259,9 +252,9 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
                         return (-EMSGSIZE);
                 }
 
-                if (nfrags == maxfrags) {
+                if (nfrags == EP_MAXFRAG) {
                         CERROR("Message too fragmented in Elan VM (max %d frags)\n",
-                               maxfrags);
+                               EP_MAXFRAG);
                         return (-EMSGSIZE);
                 }
 
@@ -273,17 +266,17 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
                 elan3_dvma_kaddr_load (kqswnal_data.kqn_epdev->DmaState,
                                        kqswnal_data.kqn_eptxdmahandle,
                                        iov->iov_base, fraglen,
-                                       basepage, &ktx->ktx_iov[nfrags].Base);
+                                       basepage, &ktx->ktx_frags.iov[nfrags].Base);
                 /* keep in loop for failure case */
                 ktx->ktx_nmappedpages = nmapped;
 
                 if (nfrags > 0 &&                /* previous frag mapped */
-                    ktx->ktx_iov[nfrags].Base == /* contiguous with this one */
-                    (ktx->ktx_iov[nfrags-1].Base + ktx->ktx_iov[nfrags-1].Len))
+                    ktx->ktx_frags.iov[nfrags].Base == /* contiguous with this one */
+                    (ktx->ktx_frags.iov[nfrags-1].Base + ktx->ktx_frags.iov[nfrags-1].Len))
                         /* just extend previous */
-                        ktx->ktx_iov[nfrags - 1].Len += fraglen;
+                        ktx->ktx_frags.iov[nfrags - 1].Len += fraglen;
                 else {
-                        ktx->ktx_iov[nfrags].Len = fraglen;
+                        ktx->ktx_frags.iov[nfrags].Len = fraglen;
                         nfrags++;                /* new frag */
                 }
 
@@ -297,13 +290,14 @@ kqswnal_map_tx_iov (kqswnal_tx_t *ktx, int nob, int niov, struct iovec *iov)
 
         } while (nob > 0);
 
-        ktx->ktx_niov = nfrags;
+        ktx->ktx_nfrag = nfrags;
         CDEBUG (D_NET, "%p got %d frags over %d pages\n",
-                ktx, ktx->ktx_niov, ktx->ktx_nmappedpages);
+                ktx, ktx->ktx_nfrag, ktx->ktx_nmappedpages);
 
         return (0);
 }
 
+
 void
 kqswnal_put_idle_tx (kqswnal_tx_t *ktx)
 {
@@ -311,6 +305,7 @@ kqswnal_put_idle_tx (kqswnal_tx_t *ktx)
         unsigned long     flags;
 
         kqswnal_unmap_tx (ktx);                 /* release temporary mappings */
+        ktx->ktx_state = KTX_IDLE;
 
         spin_lock_irqsave (&kqswnal_data.kqn_idletxd_lock, flags);
 
@@ -407,18 +402,45 @@ kqswnal_get_idle_tx (kpr_fwd_desc_t *fwd, int may_block)
 
         /* Idle descs can't have any mapped (as opposed to pre-mapped) pages */
         LASSERT (ktx == NULL || ktx->ktx_nmappedpages == 0);
+
         return (ktx);
 }
 
 void
 kqswnal_tx_done (kqswnal_tx_t *ktx, int error)
 {
-        if (ktx->ktx_forwarding)                /* router asked me to forward this packet */
+        lib_msg_t     *msg;
+        lib_msg_t     *repmsg;
+
+        switch (ktx->ktx_state) {
+        case KTX_FORWARDING:       /* router asked me to forward this packet */
                 kpr_fwd_done (&kqswnal_data.kqn_router,
                               (kpr_fwd_desc_t *)ktx->ktx_args[0], error);
-        else                                    /* packet sourced locally */
+                break;
+
+        case KTX_SENDING:          /* packet sourced locally */
                 lib_finalize (&kqswnal_lib, ktx->ktx_args[0],
                               (lib_msg_t *)ktx->ktx_args[1]);
+                break;
+
+        case KTX_GETTING:          /* Peer has DMA-ed direct? */
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                msg = (lib_msg_t *)ktx->ktx_args[1];
+                repmsg = NULL;
+
+                if (error == 0) 
+                        repmsg = lib_fake_reply_msg (&kqswnal_lib, 
+                                                     ktx->ktx_nid, msg->md);
+                
+                lib_finalize (&kqswnal_lib, ktx->ktx_args[0], msg);
+
+                if (repmsg != NULL) 
+                        lib_finalize (&kqswnal_lib, NULL, repmsg);
+                break;
+
+        default:
+                LASSERT (0);
+        }
 
         kqswnal_put_idle_tx (ktx);
 }
@@ -427,15 +449,12 @@ static void
 kqswnal_txhandler(EP_TXD *txd, void *arg, int status)
 {
         kqswnal_tx_t      *ktx = (kqswnal_tx_t *)arg;
-        
+
         LASSERT (txd != NULL);
         LASSERT (ktx != NULL);
 
         CDEBUG(D_NET, "txd %p, arg %p status %d\n", txd, arg, status);
 
-        if (status == EP_SUCCESS)
-                atomic_inc (&kqswnal_packets_transmitted);
-
         if (status != EP_SUCCESS)
         {
                 CERROR ("Tx completion to "LPX64" failed: %d\n", 
@@ -443,6 +462,14 @@ kqswnal_txhandler(EP_TXD *txd, void *arg, int status)
 
                 kqswnal_notify_peer_down(ktx);
                 status = -EIO;
+
+        } else if (ktx->ktx_state == KTX_GETTING) {
+                /* RPC completed OK; what did our peer put in the status
+                 * block? */
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                status = ep_txd_statusblk(txd)->Status;
+        } else {
+                status = 0;
         }
 
         kqswnal_tx_done (ktx, status);
@@ -460,12 +487,19 @@ kqswnal_launch (kqswnal_tx_t *ktx)
         ktx->ktx_launchtime = jiffies;
 
         LASSERT (dest >= 0);                    /* must be a peer */
-        rc = ep_transmit_large(kqswnal_data.kqn_eptx, dest,
-                               ktx->ktx_port, attr, kqswnal_txhandler,
-                               ktx, ktx->ktx_iov, ktx->ktx_niov);
+        if (ktx->ktx_state == KTX_GETTING) {
+                LASSERT (KQSW_OPTIMIZE_GETS);
+                rc = ep_transmit_rpc(kqswnal_data.kqn_eptx, dest,
+                                     ktx->ktx_port, attr, kqswnal_txhandler,
+                                     ktx, NULL, ktx->ktx_frags.iov, ktx->ktx_nfrag);
+        } else {
+                rc = ep_transmit_large(kqswnal_data.kqn_eptx, dest,
+                                       ktx->ktx_port, attr, kqswnal_txhandler,
+                                       ktx, ktx->ktx_frags.iov, ktx->ktx_nfrag);
+        }
+
         switch (rc) {
-        case 0: /* success */
-                atomic_inc (&kqswnal_packets_launched);
+        case ESUCCESS: /* success */
                 return (0);
 
         case ENOMEM: /* can't allocate ep txd => queue for later */
@@ -508,8 +542,9 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
 {
         char *type_str = hdr_type_string (hdr);
 
-        CERROR("P3 Header at %p of type %s\n", hdr, type_str);
-        CERROR("    From nid/pid "LPU64"/%u", NTOH__u64(hdr->src_nid),
+        CERROR("P3 Header at %p of type %s length %d\n", hdr, type_str,
+               NTOH__u32(hdr->payload_length));
+        CERROR("    From nid/pid "LPU64"/%u\n", NTOH__u64(hdr->src_nid),
                NTOH__u32(hdr->src_pid));
         CERROR("    To nid/pid "LPU64"/%u\n", NTOH__u64(hdr->dest_nid),
                NTOH__u32(hdr->dest_pid));
@@ -522,8 +557,7 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
                        hdr->msg.put.ack_wmd.wh_interface_cookie,
                        hdr->msg.put.ack_wmd.wh_object_cookie,
                        NTOH__u64 (hdr->msg.put.match_bits));
-                CERROR("    Length %d, offset %d, hdr data "LPX64"\n",
-                       NTOH__u32(PTL_HDR_LENGTH(hdr)),
+                CERROR("    offset %d, hdr data "LPX64"\n",
                        NTOH__u32(hdr->msg.put.offset),
                        hdr->msg.put.hdr_data);
                 break;
@@ -548,18 +582,148 @@ kqswnal_cerror_hdr(ptl_hdr_t * hdr)
                 break;
 
         case PTL_MSG_REPLY:
-                CERROR("    dst md "LPX64"."LPX64", length %d\n",
+                CERROR("    dst md "LPX64"."LPX64"\n",
                        hdr->msg.reply.dst_wmd.wh_interface_cookie,
-                       hdr->msg.reply.dst_wmd.wh_object_cookie,
-                       NTOH__u32 (PTL_HDR_LENGTH(hdr)));
+                       hdr->msg.reply.dst_wmd.wh_object_cookie);
         }
 
 }                               /* end of print_hdr() */
 
+void
+kqswnal_print_eiov (int how, char *str, int n, EP_IOVEC *iov) 
+{
+        int          i;
+
+        CDEBUG (how, "%s: %d\n", str, n);
+        for (i = 0; i < n; i++) {
+                CDEBUG (how, "   %08x for %d\n", iov[i].Base, iov[i].Len);
+        }
+}
+
+int
+kqswnal_eiovs2datav (int ndv, EP_DATAVEC *dv,
+                     int nsrc, EP_IOVEC *src,
+                     int ndst, EP_IOVEC *dst) 
+{
+        int        count;
+        int        nob;
+
+        LASSERT (ndv > 0);
+        LASSERT (nsrc > 0);
+        LASSERT (ndst > 0);
+
+        for (count = 0; count < ndv; count++, dv++) {
+
+                if (nsrc == 0 || ndst == 0) {
+                        if (nsrc != ndst) {
+                                /* For now I'll barf on any left over entries */
+                                CERROR ("mismatched src and dst iovs\n");
+                                return (-EINVAL);
+                        }
+                        return (count);
+                }
+
+                nob = (src->Len < dst->Len) ? src->Len : dst->Len;
+                dv->Len    = nob;
+                dv->Source = src->Base;
+                dv->Dest   = dst->Base;
+
+                if (nob >= src->Len) {
+                        src++;
+                        nsrc--;
+                } else {
+                        src->Len -= nob;
+                        src->Base += nob;
+                }
+                
+                if (nob >= dst->Len) {
+                        dst++;
+                        ndst--;
+                } else {
+                        src->Len -= nob;
+                        src->Base += nob;
+                }
+        }
+
+        CERROR ("DATAVEC too small\n");
+        return (-E2BIG);
+}
+
+int
+kqswnal_dma_reply (kqswnal_tx_t *ktx, int nfrag, 
+                   struct iovec *iov, ptl_kiov_t *kiov, int nob)
+{
+        kqswnal_rx_t       *krx = (kqswnal_rx_t *)ktx->ktx_args[0];
+        char               *buffer = (char *)page_address(krx->krx_pages[0]);
+        kqswnal_remotemd_t *rmd = (kqswnal_remotemd_t *)(buffer + KQSW_HDR_SIZE);
+        EP_IOVEC            eiov[EP_MAXFRAG];
+        EP_STATUSBLK        blk;
+        int                 rc;
+
+        LASSERT (ep_rxd_isrpc(krx->krx_rxd) && !krx->krx_rpc_completed);
+        LASSERT ((iov == NULL) != (kiov == NULL));
+
+        /* see .*_pack_k?iov comment regarding endian-ness */
+        if (buffer + krx->krx_nob < (char *)(rmd + 1)) {
+                /* msg too small to discover rmd size */
+                CERROR ("Incoming message [%d] too small for RMD (%d needed)\n",
+                        krx->krx_nob, (int)(((char *)(rmd + 1)) - buffer));
+                return (-EINVAL);
+        }
+        
+        if (buffer + krx->krx_nob < (char *)&rmd->kqrmd_eiov[rmd->kqrmd_neiov]) {
+                /* rmd doesn't fit in the incoming message */
+                CERROR ("Incoming message [%d] too small for RMD[%d] (%d needed)\n",
+                        krx->krx_nob, rmd->kqrmd_neiov,
+                        (int)(((char *)&rmd->kqrmd_eiov[rmd->kqrmd_neiov]) - buffer));
+                return (-EINVAL);
+        }
+
+        /* Ghastly hack part 1, uses the existing procedures to map the source data... */
+        ktx->ktx_nfrag = 0;
+        if (kiov != NULL)
+                rc = kqswnal_map_tx_kiov (ktx, nob, nfrag, kiov);
+        else
+                rc = kqswnal_map_tx_iov (ktx, nob, nfrag, iov);
+
+        if (rc != 0) {
+                CERROR ("Can't map source data: %d\n", rc);
+                return (rc);
+        }
+
+        /* Ghastly hack part 2, copy out eiov so we can create the datav; Ugghh... */
+        memcpy (eiov, ktx->ktx_frags.iov, ktx->ktx_nfrag * sizeof (eiov[0]));
+
+        rc = kqswnal_eiovs2datav (EP_MAXFRAG, ktx->ktx_frags.datav,
+                                  ktx->ktx_nfrag, eiov,
+                                  rmd->kqrmd_neiov, rmd->kqrmd_eiov);
+        if (rc < 0) {
+                CERROR ("Can't create datavec: %d\n", rc);
+                return (rc);
+        }
+        ktx->ktx_nfrag = rc;
+
+        memset (&blk, 0, sizeof (blk));         /* zero blk.Status */
+
+        /* Our caller will start to race with kqswnal_rpc_complete... */
+        LASSERT (atomic_read (&krx->krx_refcount) == 1);
+        atomic_set (&krx->krx_refcount, 2);
+
+        rc = ep_complete_rpc (krx->krx_rxd, kqswnal_reply_complete, ktx,
+                              &blk, ktx->ktx_frags.datav, ktx->ktx_nfrag);
+        if (rc == ESUCCESS)
+                return (0);
+
+        /* reset refcount back to 1: we're not going to be racing with
+         * kqswnal_rely_complete. */
+        atomic_set (&krx->krx_refcount, 1);
+        return (-ECONNABORTED);
+}
+
 static int
 kqswnal_sendmsg (nal_cb_t     *nal,
                  void         *private,
-                 lib_msg_t    *cookie,
+                 lib_msg_t    *libmsg,
                  ptl_hdr_t    *hdr,
                  int           type,
                  ptl_nid_t     nid,
@@ -571,7 +735,7 @@ kqswnal_sendmsg (nal_cb_t     *nal,
 {
         kqswnal_tx_t      *ktx;
         int                rc;
-        ptl_nid_t          gatewaynid;
+        ptl_nid_t          targetnid;
 #if KQSW_CHECKSUM
         int                i;
         kqsw_csum_t        csum;
@@ -595,20 +759,20 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 return (PTL_FAIL);
         }
 
+        targetnid = nid;
         if (kqswnal_nid2elanid (nid) < 0) {     /* Can't send direct: find gateway? */
                 rc = kpr_lookup (&kqswnal_data.kqn_router, nid, 
-                                 sizeof (ptl_hdr_t) + payload_nob, &gatewaynid);
+                                 sizeof (ptl_hdr_t) + payload_nob, &targetnid);
                 if (rc != 0) {
                         CERROR("Can't route to "LPX64": router error %d\n",
                                nid, rc);
                         return (PTL_FAIL);
                 }
-                if (kqswnal_nid2elanid (gatewaynid) < 0) {
+                if (kqswnal_nid2elanid (targetnid) < 0) {
                         CERROR("Bad gateway "LPX64" for "LPX64"\n",
-                               gatewaynid, nid);
+                               targetnid, nid);
                         return (PTL_FAIL);
                 }
-                nid = gatewaynid;
         }
 
         /* I may not block for a transmit descriptor if I might block the
@@ -621,6 +785,35 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 return (PTL_NOSPACE);
         }
 
+        ktx->ktx_args[0] = private;
+        ktx->ktx_args[1] = libmsg;
+
+#if KQSW_OPTIMIZE_GETS
+        if (type == PTL_MSG_REPLY &&
+            ep_rxd_isrpc(((kqswnal_rx_t *)private)->krx_rxd)) {
+                if (nid != targetnid ||
+                    kqswnal_nid2elanid(nid) != 
+                    ep_rxd_node(((kqswnal_rx_t *)private)->krx_rxd)) {
+                        CERROR("Optimized reply nid conflict: "
+                               "nid "LPX64" via "LPX64" elanID %d\n",
+                               nid, targetnid,
+                               ep_rxd_node(((kqswnal_rx_t *)private)->krx_rxd));
+                        return(PTL_FAIL);
+                }
+
+                /* peer expects RPC completion with GET data */
+                rc = kqswnal_dma_reply (ktx,
+                                        payload_niov, payload_iov, 
+                                        payload_kiov, payload_nob);
+                if (rc == 0)
+                        return (0);
+                
+                CERROR ("Can't DMA reply to "LPX64": %d\n", nid, rc);
+                kqswnal_put_idle_tx (ktx);
+                return (PTL_FAIL);
+        }
+#endif
+
         memcpy (ktx->ktx_buffer, hdr, sizeof (*hdr)); /* copy hdr from caller's stack */
         ktx->ktx_wire_hdr = (ptl_hdr_t *)ktx->ktx_buffer;
 
@@ -644,13 +837,57 @@ kqswnal_sendmsg (nal_cb_t     *nal,
         }
         memcpy(ktx->ktx_buffer +sizeof(*hdr) +sizeof(csum), &csum,sizeof(csum));
 #endif
-
+        
         /* Set up first frag from pre-mapped buffer (it's at least the
          * portals header) */
-        ktx->ktx_iov[0].Base = ktx->ktx_ebuffer;
-        ktx->ktx_iov[0].Len = KQSW_HDR_SIZE;
-        ktx->ktx_niov = 1;
+        ktx->ktx_frags.iov[0].Base = ktx->ktx_ebuffer;
+        ktx->ktx_frags.iov[0].Len = KQSW_HDR_SIZE;
+        ktx->ktx_nfrag = 1;
+        ktx->ktx_state = KTX_SENDING;   /* => lib_finalize() on completion */
+
+#if KQSW_OPTIMIZE_GETS
+        if (type == PTL_MSG_GET &&              /* doing a GET */
+            nid == targetnid) {                 /* not forwarding */
+                lib_md_t           *md = libmsg->md;
+                kqswnal_remotemd_t *rmd = (kqswnal_remotemd_t *)(ktx->ktx_buffer + KQSW_HDR_SIZE);
+                
+                /* Optimised path: I send over the Elan vaddrs of the get
+                 * sink buffers, and my peer DMAs directly into them.
+                 *
+                 * First I set up ktx as if it was going to send this
+                 * payload, (it needs to map it anyway).  This fills
+                 * ktx_frags.iov[1] and onward with the network addresses
+                 * of the get sink frags.  I copy these into ktx_buffer,
+                 * immediately after the header, and send that as my GET
+                 * message.
+                 *
+                 * Note that the addresses are sent in native endian-ness.
+                 * When EKC copes with different endian nodes, I'll fix
+                 * this (and eat my hat :) */
+
+                if ((libmsg->md->options & PTL_MD_KIOV) != 0) 
+                        rc = kqswnal_map_tx_kiov (ktx, md->length,
+                                                  md->md_niov, md->md_iov.kiov);
+                else
+                        rc = kqswnal_map_tx_iov (ktx, md->length,
+                                                 md->md_niov, md->md_iov.iov);
+
+                if (rc < 0) {
+                        kqswnal_put_idle_tx (ktx);
+                        return (PTL_FAIL);
+                }
+
+                rmd->kqrmd_neiov = ktx->ktx_nfrag - 1;
+                memcpy (&rmd->kqrmd_eiov[0], &ktx->ktx_frags.iov[1],
+                        rmd->kqrmd_neiov * sizeof (EP_IOVEC));
 
+                ktx->ktx_nfrag = 1;
+                ktx->ktx_frags.iov[0].Len += offsetof (kqswnal_remotemd_t,
+                                                       kqrmd_eiov[rmd->kqrmd_neiov]);
+                payload_nob = ktx->ktx_frags.iov[0].Len;
+                ktx->ktx_state = KTX_GETTING;
+        } else 
+#endif
         if (payload_nob > 0) { /* got some payload (something more to do) */
                 /* make a single contiguous message? */
                 if (payload_nob <= KQSW_TX_MAXCONTIG) {
@@ -662,7 +899,7 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                                 lib_copy_iov2buf (ktx->ktx_buffer + KQSW_HDR_SIZE,
                                                   payload_niov, payload_iov, payload_nob);
                         /* first frag includes payload */
-                        ktx->ktx_iov[0].Len += payload_nob;
+                        ktx->ktx_frags.iov[0].Len += payload_nob;
                 } else {
                         if (payload_kiov != NULL)
                                 rc = kqswnal_map_tx_kiov (ktx, payload_nob, 
@@ -677,28 +914,26 @@ kqswnal_sendmsg (nal_cb_t     *nal,
                 } 
         }
 
-        ktx->ktx_port       = (payload_nob <= KQSW_SMALLPAYLOAD) ?
-                              EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
-        ktx->ktx_nid        = nid;
-        ktx->ktx_forwarding = 0;   /* => lib_finalize() on completion */
-        ktx->ktx_args[0]    = private;
-        ktx->ktx_args[1]    = cookie;
+        ktx->ktx_nid  = targetnid;
+        ktx->ktx_port = (payload_nob <= KQSW_SMALLPAYLOAD) ?
+                        EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
 
         rc = kqswnal_launch (ktx);
         if (rc != 0) {                    /* failed? */
-                CERROR ("Failed to send packet to "LPX64": %d\n", nid, rc);
+                CERROR ("Failed to send packet to "LPX64": %d\n", targetnid, rc);
                 kqswnal_put_idle_tx (ktx);
                 return (PTL_FAIL);
         }
 
-        CDEBUG(D_NET, "sent "LPSZ" bytes to "LPX64"\n", payload_nob, nid);
+        CDEBUG(D_NET, "sent "LPSZ" bytes to "LPX64" via "LPX64"\n", 
+               payload_nob, nid, targetnid);
         return (PTL_OK);
 }
 
 static int
 kqswnal_send (nal_cb_t     *nal,
               void         *private,
-              lib_msg_t    *cookie,
+              lib_msg_t    *libmsg,
               ptl_hdr_t    *hdr,
               int           type,
               ptl_nid_t     nid,
@@ -707,14 +942,14 @@ kqswnal_send (nal_cb_t     *nal,
               struct iovec *payload_iov,
               size_t        payload_nob)
 {
-        return (kqswnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+        return (kqswnal_sendmsg (nal, private, libmsg, hdr, type, nid, pid,
                                  payload_niov, payload_iov, NULL, payload_nob));
 }
 
 static int
 kqswnal_send_pages (nal_cb_t     *nal,
                     void         *private,
-                    lib_msg_t    *cookie,
+                    lib_msg_t    *libmsg,
                     ptl_hdr_t    *hdr,
                     int           type,
                     ptl_nid_t     nid,
@@ -723,7 +958,7 @@ kqswnal_send_pages (nal_cb_t     *nal,
                     ptl_kiov_t   *payload_kiov,
                     size_t        payload_nob)
 {
-        return (kqswnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+        return (kqswnal_sendmsg (nal, private, libmsg, hdr, type, nid, pid,
                                  payload_niov, NULL, payload_kiov, payload_nob));
 }
 
@@ -775,16 +1010,15 @@ kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
         {
                 /* send from ktx's pre-allocated/mapped contiguous buffer? */
                 lib_copy_iov2buf (ktx->ktx_buffer, niov, iov, nob);
-                ktx->ktx_iov[0].Base = ktx->ktx_ebuffer; /* already mapped */
-                ktx->ktx_iov[0].Len = nob;
-                ktx->ktx_niov = 1;
-
+                ktx->ktx_frags.iov[0].Base = ktx->ktx_ebuffer; /* already mapped */
+                ktx->ktx_frags.iov[0].Len = nob;
+                ktx->ktx_nfrag = 1;
                 ktx->ktx_wire_hdr = (ptl_hdr_t *)ktx->ktx_buffer;
         }
         else
         {
                 /* zero copy */
-                ktx->ktx_niov = 0;        /* no frags mapped yet */
+                ktx->ktx_nfrag = 0;       /* no frags mapped yet */
                 rc = kqswnal_map_tx_iov (ktx, nob, niov, iov);
                 if (rc != 0)
                         goto failed;
@@ -792,11 +1026,11 @@ kqswnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
                 ktx->ktx_wire_hdr = (ptl_hdr_t *)iov[0].iov_base;
         }
 
-        ktx->ktx_port       = (nob <= (sizeof (ptl_hdr_t) + KQSW_SMALLPAYLOAD)) ?
-                              EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
-        ktx->ktx_nid        = nid;
-        ktx->ktx_forwarding = 1;
-        ktx->ktx_args[0]    = fwd;
+        ktx->ktx_port    = (nob <= (sizeof (ptl_hdr_t) + KQSW_SMALLPAYLOAD)) ?
+                        EP_SVC_LARGE_PORTALS_SMALL : EP_SVC_LARGE_PORTALS_LARGE;
+        ktx->ktx_nid     = nid;
+        ktx->ktx_state   = KTX_FORWARDING; /* kpr_put_packet() on completion */
+        ktx->ktx_args[0] = fwd;
 
         rc = kqswnal_launch (ktx);
         if (rc == 0)
@@ -829,6 +1063,97 @@ kqswnal_fwd_callback (void *arg, int error)
         kqswnal_requeue_rx (krx);
 }
 
+void
+kqswnal_reply_complete (EP_RXD *rxd) 
+{
+        int           status = ep_rxd_status(rxd);
+        kqswnal_tx_t *ktx = (kqswnal_tx_t *)ep_rxd_arg(rxd);
+        kqswnal_rx_t *krx = (kqswnal_rx_t *)ktx->ktx_args[0];
+        lib_msg_t    *msg = (lib_msg_t *)ktx->ktx_args[1];
+        
+        CDEBUG((status == EP_SUCCESS) ? D_NET : D_ERROR,
+               "rxd %p, ktx %p, status %d\n", rxd, ktx, status);
+
+        LASSERT (krx->krx_rxd == rxd);
+
+        krx->krx_rpc_completed = 1;
+        kqswnal_requeue_rx (krx);
+
+        lib_finalize (&kqswnal_lib, NULL, msg);
+        kqswnal_put_idle_tx (ktx);
+}
+
+void
+kqswnal_rpc_complete (EP_RXD *rxd)
+{
+        int           status = ep_rxd_status(rxd);
+        kqswnal_rx_t *krx    = (kqswnal_rx_t *)ep_rxd_arg(rxd);
+        
+        CDEBUG((status == EP_SUCCESS) ? D_NET : D_ERROR,
+               "rxd %p, krx %p, status %d\n", rxd, krx, status);
+
+        LASSERT (krx->krx_rxd == rxd);
+        
+        krx->krx_rpc_completed = 1;
+        kqswnal_requeue_rx (krx);
+}
+
+void
+kqswnal_requeue_rx (kqswnal_rx_t *krx)
+{
+        EP_STATUSBLK  blk;
+        int           rc;
+
+        LASSERT (atomic_read (&krx->krx_refcount) > 0);
+        if (!atomic_dec_and_test (&krx->krx_refcount))
+                return;
+
+        if (!ep_rxd_isrpc(krx->krx_rxd) ||
+            krx->krx_rpc_completed) {
+
+                /* don't actually requeue on shutdown */
+                if (kqswnal_data.kqn_shuttingdown)
+                        return;
+                
+                ep_requeue_receive (krx->krx_rxd, kqswnal_rxhandler, krx,
+                                    krx->krx_elanaddr, krx->krx_npages * PAGE_SIZE);
+                return;
+        }
+
+        /* Sender wanted an RPC, but we didn't complete it (we must have
+         * dropped the sender's message).  We complete it now with
+         * failure... */
+        memset (&blk, 0, sizeof (blk));
+        blk.Status = -ECONNREFUSED;
+
+        atomic_set (&krx->krx_refcount, 1);
+
+        rc = ep_complete_rpc (krx->krx_rxd, 
+                              kqswnal_rpc_complete, krx,
+                              &blk, NULL, 0);
+        if (rc == ESUCCESS) {
+                /* callback will call me again to requeue, having set
+                 * krx_rpc_completed... */
+                return;
+        }
+
+        CERROR("can't complete RPC: %d\n", rc);
+
+        /* we don't actually requeue on shutdown */
+        if (kqswnal_data.kqn_shuttingdown)
+                return;
+
+        /* NB ep_complete_rpc() frees rxd on failure, so we have to requeue
+         * from scratch here... */
+        rc = ep_queue_receive(krx->krx_eprx, kqswnal_rxhandler, krx,
+                              krx->krx_elanaddr, 
+                              krx->krx_npages * PAGE_SIZE, 0);
+
+        LASSERT (rc == ESUCCESS);
+        /* This needs to be fixed by ep_complete_rpc NOT freeing
+         * krx->krx_rxd on failure so we can just ep_requeue_receive() */
+}
+
 void
 kqswnal_rx (kqswnal_rx_t *krx)
 {
@@ -851,6 +1176,7 @@ kqswnal_rx (kqswnal_rx_t *krx)
         {
                 CERROR("dropping packet from "LPX64" for "LPX64
                        ": target is peer\n", NTOH__u64(hdr->src_nid), dest_nid);
+
                 kqswnal_requeue_rx (krx);
                 return;
         }
@@ -886,21 +1212,26 @@ kqswnal_rxhandler(EP_RXD *rxd)
 
         krx->krx_rxd = rxd;
         krx->krx_nob = nob;
-
+        LASSERT (atomic_read (&krx->krx_refcount) == 0);
+        atomic_set (&krx->krx_refcount, 1);
+        krx->krx_rpc_completed = 0;
+        
         /* must receive a whole header to be able to parse */
         if (status != EP_SUCCESS || nob < sizeof (ptl_hdr_t))
         {
                 /* receives complete with failure when receiver is removed */
-                if (kqswnal_data.kqn_shuttingdown)
-                        return;
+                if (!kqswnal_data.kqn_shuttingdown)
+                        CERROR("receive status failed with status %d nob %d\n",
+                               ep_rxd_status(rxd), nob);
 
-                CERROR("receive status failed with status %d nob %d\n",
-                       ep_rxd_status(rxd), nob);
                 kqswnal_requeue_rx (krx);
                 return;
         }
 
-        atomic_inc (&kqswnal_packets_received);
+        if (!in_interrupt()) {
+                kqswnal_rx (krx);
+                return;
+        }
 
         spin_lock_irqsave (&kqswnal_data.kqn_sched_lock, flags);
 
@@ -960,7 +1291,7 @@ kqswnal_csum_error (kqswnal_rx_t *krx, int ishdr)
 static int
 kqswnal_recvmsg (nal_cb_t     *nal,
                  void         *private,
-                 lib_msg_t    *cookie,
+                 lib_msg_t    *libmsg,
                  unsigned int  niov,
                  struct iovec *iov,
                  ptl_kiov_t   *kiov,
@@ -1084,7 +1415,7 @@ kqswnal_recvmsg (nal_cb_t     *nal,
                        "csum_nob %d\n",
                         hdr_csum, payload_csum, csum_frags, csum_nob);
 #endif
-        lib_finalize(nal, private, cookie);
+        lib_finalize(nal, private, libmsg);
 
         kqswnal_requeue_rx (krx);
 
@@ -1094,25 +1425,25 @@ kqswnal_recvmsg (nal_cb_t     *nal,
 static int
 kqswnal_recv(nal_cb_t     *nal,
              void         *private,
-             lib_msg_t    *cookie,
+             lib_msg_t    *libmsg,
              unsigned int  niov,
              struct iovec *iov,
              size_t        mlen,
              size_t        rlen)
 {
-        return (kqswnal_recvmsg (nal, private, cookie, niov, iov, NULL, mlen, rlen));
+        return (kqswnal_recvmsg (nal, private, libmsg, niov, iov, NULL, mlen, rlen));
 }
 
 static int
 kqswnal_recv_pages (nal_cb_t     *nal,
                     void         *private,
-                    lib_msg_t    *cookie,
+                    lib_msg_t    *libmsg,
                     unsigned int  niov,
                     ptl_kiov_t   *kiov,
                     size_t        mlen,
                     size_t        rlen)
 {
-        return (kqswnal_recvmsg (nal, private, cookie, niov, NULL, kiov, mlen, rlen));
+        return (kqswnal_recvmsg (nal, private, libmsg, niov, NULL, kiov, mlen, rlen));
 }
 
 int
diff --git a/lustre/portals/knals/scimacnal/README.scimacnal b/lustre/portals/knals/scimacnal/README.scimacnal
index d4c6a492cfc857abedb221895de24c808420dfea..e1ee3b56fbed45f0b9ebbb3fa0469f6a45484451 100644
--- a/lustre/portals/knals/scimacnal/README.scimacnal
+++ b/lustre/portals/knals/scimacnal/README.scimacnal
@@ -2,13 +2,41 @@
 scimacnal - A NAL for the Scali ScaMAC midlayer.
 
 The ScaMAC midlayer is a simplified API to the SCI high performance
-interconnect.
+interconnect (http://www.scali.com/, http://www.dolphinics.com/).
 
 In order to use this NAL you'll need to tune scimac to use larger buffers.
 See scimac.conf in this directory for an example.
 
-Overall performance and stability isn't great but this can be attributed
-to the scimac driver which apparently is in need of some development.
+You'll also need to edit portals/include/portals/lib-types.h and reduce
+the MTU to 64kB (the limit of scimac), this diff should help:
+
+----------------------8<----------------------------------
+--- portals/include/portals/lib-types.h 27 Jul 2003 02:05:47 -0000      1.1.2.5
++++ portals/include/portals/lib-types.h 14 Aug 2003 08:32:14 -0000
+@@ -137,8 +137,8 @@
+ } lib_counters_t;
+ 
+ /* temporary expedient: limit number of entries in discontiguous MDs */
+-# define PTL_MTU        (512<<10)
+-# define PTL_MD_MAX_IOV 128
++# define PTL_MTU        (64<<10)
++# define PTL_MD_MAX_IOV 16
+ 
+ struct lib_msg_t {
+         struct list_head  msg_list;
+----------------------8<----------------------------------
+
+The NAL itself seems quite stable, though scimac has recovery bugs when
+rebooting nodes at times (confirmed by the fact that the IP driver that
+also uses scimac loses connectivity when scimacnal does).  This is
+solved by unloading lustre and reloading the scimac driver on the
+affected nodes.
+
+Performance isn't great when it comes to latency, scimac seems to have
+problems with per packet latencies (confirmed with the IP driver which
+has similar behaviour). Bandwidth using large packets is pretty OK
+(probably due to the fact that it hides the latency issues).
 
 TODO:
 Routing isn't yet implemented.
+Need some way to inform portals about our MTU.
diff --git a/lustre/portals/knals/scimacnal/scimacnal.c b/lustre/portals/knals/scimacnal/scimacnal.c
index 479cc2c8930b2cb375ac939b4010641d7354cb5b..5ffba31044af7ad0a9f0dce137cebe4735ea9575 100644
--- a/lustre/portals/knals/scimacnal/scimacnal.c
+++ b/lustre/portals/knals/scimacnal/scimacnal.c
@@ -38,6 +38,24 @@ kpr_nal_interface_t kscimacnal_router_interface = {
 };
 
 
+int kscimacnal_cmd (struct portal_ioctl_data *data, void *private)
+{
+        LASSERT (data != NULL);
+
+        switch (data->ioc_nal_cmd) {
+                case NAL_CMD_REGISTER_MYNID:
+                        if(kscimacnal_lib.ni.nid == data->ioc_nid) {
+                                break;
+                        }
+                        CDEBUG (D_IOCTL, "Can't change NID from "LPX64" to "LPX64")\n", kscimacnal_lib.ni.nid, data->ioc_nid);
+                        return(-EINVAL);
+                default:
+                        return(-EINVAL);
+        }
+
+        return(0);
+}
+
 static int kscimacnal_forward(nal_t   *nal,
                           int     id,
                           void    *args,  size_t args_len,
@@ -105,7 +123,7 @@ static nal_t *kscimacnal_init(int interface, ptl_pt_index_t  ptl_size,
 {
         int     nnids = 512; /* FIXME: Need ScaMac funktion to get #nodes */
 
-        CDEBUG(D_NET, "calling lib_init with nid 0x%Lx nnids %d\n", kscimacnal_data.ksci_nid, nnids);
+        CDEBUG(D_NET, "calling lib_init with nid "LPX64" nnids %d\n", kscimacnal_data.ksci_nid, nnids);
         lib_init(&kscimacnal_lib, kscimacnal_data.ksci_nid, 0, nnids,ptl_size, ac_size); 
         return &kscimacnal_api;
 }
@@ -200,6 +218,16 @@ kscimacnal_initialize(void)
                 return (-ENOMEM);
         }
 
+        /* Init command interface */
+        rc = kportal_nal_register (SCIMACNAL, &kscimacnal_cmd, NULL);
+        if (rc != 0) {
+                CERROR ("Can't initialise command interface (rc = %d)\n", rc);
+                PtlNIFini(kscimacnal_ni);
+                mac_finish(machandle);
+                return (rc);
+        }
+
+
         PORTAL_SYMBOL_REGISTER(kscimacnal_ni);
 
         /* We're done now, it's OK for the RX callback to do stuff */
@@ -210,7 +238,7 @@ kscimacnal_initialize(void)
 
 
 MODULE_AUTHOR("Niklas Edmundsson <nikke@hpc2n.umu.se>");
-MODULE_DESCRIPTION("Kernel Scali ScaMAC SCI NAL v0.0");
+MODULE_DESCRIPTION("Kernel Scali ScaMAC SCI NAL v0.1");
 MODULE_LICENSE("GPL");
 
 module_init (kscimacnal_initialize);
diff --git a/lustre/portals/knals/scimacnal/scimacnal.h b/lustre/portals/knals/scimacnal/scimacnal.h
index 1ff180e5ccb4a259c9010647ddfa388bfedea7f9..694955780c338130a73cae4345db61455b22bffb 100644
--- a/lustre/portals/knals/scimacnal/scimacnal.h
+++ b/lustre/portals/knals/scimacnal/scimacnal.h
@@ -43,10 +43,10 @@
 #define MAC_SAPID_LUSTRE MAC_SAPID_TEST1
 #endif /* MAC_SAPID_LUSTRE */
 
+/* scimac has an annoying MTU limit of 64k */
 #define SCIMACNAL_MTU 65536
-/* FIXME: What is really the MTU of lustre? */
-#if PTL_MD_MAX_IOV*PAGE_SIZE > SCIMACNAL_MTU
-#error Max MTU of ScaMAC is 64k, PTL_MD_MAX_IOV*PAGE_SIZE is bigger.
+#if PTL_MTU > SCIMACNAL_MTU
+#error Max MTU of ScaMAC is 64k, PTL_MTU is bigger.
 #endif
 
 typedef struct {
@@ -62,6 +62,9 @@ typedef struct {
         void            *ktx_private;
         lib_msg_t       *ktx_cookie;
         ptl_hdr_t       ktx_hdr;
+        /* To be able to kunmap() kmap():ed pages */
+        struct page     *ktx_kpages[PTL_MD_MAX_IOV];
+        int              ktx_nmapped;
 }  kscimacnal_tx_t;
 
 
diff --git a/lustre/portals/knals/scimacnal/scimacnal_cb.c b/lustre/portals/knals/scimacnal/scimacnal_cb.c
index 7e4a2e892debc081f7f1b058a7db1bb36d68b7fa..b31c2eae0e8a024137d1cc1b34bdf3cac4fe4465 100644
--- a/lustre/portals/knals/scimacnal/scimacnal_cb.c
+++ b/lustre/portals/knals/scimacnal/scimacnal_cb.c
@@ -74,7 +74,7 @@ kscimacnal_printf(nal_cb_t *nal, const char *fmt, ...)
                 vsnprintf( msg, sizeof(msg), fmt, ap );
                 va_end( ap );
 
-                printk("CPUId: %d %s",smp_processor_id(), msg);
+                printk("Lustre: CPUId: %d %s",smp_processor_id(), msg);
         }
 }
 
@@ -156,9 +156,15 @@ static void
 kscimacnal_txrelease(mac_mblk_t *msg, mac_msg_status_t status, void *context)
 {
         kscimacnal_tx_t *ktx = (kscimacnal_tx_t *)context;
-        int err=0;
+        int err=0, i;
         
         LASSERT (ktx != NULL);
+        /* Unmap any mapped pages */
+        for(i=0; i<ktx->ktx_nmapped; i++) {
+                kunmap(ktx->ktx_kpages[i]);
+        }
+
+        CDEBUG(D_NET, "kunmapped %d pages\n", ktx->ktx_nmapped);
 
         /* Euh, there is no feedback when transmission fails?! */
         switch(status) {
@@ -178,17 +184,21 @@ kscimacnal_txrelease(mac_mblk_t *msg, mac_msg_status_t status, void *context)
 
 /* Called by portals when it wants to send a message.
  * Since ScaMAC has it's own TX thread we don't bother setting up our own. */
-static int 
-kscimacnal_send(nal_cb_t        *nal,
-           void            *private,
-           lib_msg_t       *cookie,
-           ptl_hdr_t       *hdr,
-           int              type, 
-           ptl_nid_t        nid,
-           ptl_pid_t        pid,
-           unsigned int     payload_niov,
-           struct iovec    *payload_iov,
-           size_t           payload_len)
+
+/* FIXME: Read comments in qswnal_cb.c for _sendmsg and fix return-on-error
+ *        issues */
+static inline int 
+kscimacnal_sendmsg(nal_cb_t        *nal,
+                   void            *private,
+                   lib_msg_t       *cookie,
+                   ptl_hdr_t       *hdr,
+                   int              type, 
+                   ptl_nid_t        nid,
+                   ptl_pid_t        pid,
+                   unsigned int     payload_niov,
+                   struct iovec    *payload_iov,
+                   ptl_kiov_t      *payload_kiov,
+                   size_t           payload_len)
 {
         kscimacnal_tx_t    *ktx=NULL;
         kscimacnal_data_t  *ksci = nal->nal_data;
@@ -198,12 +208,18 @@ kscimacnal_send(nal_cb_t        *nal,
         unsigned long   physaddr;
         
 
-        CDEBUG(D_NET, "sending %d bytes from %p to nid 0x%Lx niov: %d\n",
-               payload_len, payload_iov, nid, payload_niov);
+        CDEBUG(D_NET, "sending %d bytes from %p/%p to nid "LPX64" niov: %d\n",
+               payload_len, payload_iov, payload_kiov, nid, payload_niov);
 
+        /* Basic sanity checks */
         LASSERT(ksci != NULL);
-
         LASSERT(hdr != NULL);
+        LASSERT (payload_len == 0 || payload_niov > 0);
+        LASSERT (payload_niov <= PTL_MD_MAX_IOV);
+        /* It must be OK to kmap() if required */
+        LASSERT (payload_kiov == NULL || !in_interrupt ());
+        /* payload is either all vaddrs or all pages */
+        LASSERT (!(payload_kiov != NULL && payload_iov != NULL));
 
         /* Do real check if we can send this */
         if (buf_len > mac_get_mtusize(ksci->ksci_machandle)) {
@@ -219,6 +235,8 @@ kscimacnal_send(nal_cb_t        *nal,
                 return -ENOMEM;
         }
 
+        ktx->ktx_nmapped = 0; /* Start with no mapped pages :) */
+
         /* *SIGH* hdr is a stack variable in the calling function, so we
          * need to copy it to a buffer. Zerocopy magic (or is it just
          * deferred memcpy?) is annoying sometimes.  */
@@ -235,19 +253,34 @@ kscimacnal_send(nal_cb_t        *nal,
         lastblk=msg;
 
         /* Allocate additional mblks for each iov as needed.
-         * Essentially lib_copy_iov2buf with a twist or two */
+         * Essentially lib_copy_(k)iov2buf with a twist or two */
         while (payload_len > 0)
         {
-                ptl_size_t nob;
+                ptl_size_t       nob;
+                char            *addr;
 
                 LASSERT (payload_niov > 0);
 
-                nob = MIN (payload_iov->iov_len, payload_len);
+                if(payload_iov != NULL) {
+                        nob = MIN (payload_iov->iov_len, payload_len);
+                        addr = payload_iov->iov_base;
+                }
+                else {
+                        nob = MIN (payload_kiov->kiov_len, payload_len);
+                        /* Bollocks. We need to handle paged IO for things to
+                         * work but there is no good way to do this. We
+                         * do it by kmap():ing all pages and keep them
+                         * mapped until scimac is done with them. */
+                        /* FIXME: kunmap() on error */
+                        addr = kmap(payload_kiov->kiov_page);
+                        ktx->ktx_kpages[ktx->ktx_nmapped++] = 
+                                payload_kiov->kiov_page;
+                }
+                /* We don't need a callback on the additional mblks,
+                 * since all release callbacks seems to be called when
+                 * the entire message has been sent */
+                newblk=mac_alloc_mblk(addr, nob, NULL, NULL);
 
-                /* We don't need a callback on the additional mblks, since
-                 * all release callbacks seems to be called when the entire
-                 * message has been sent */
-                newblk=mac_alloc_mblk(payload_iov->iov_base, nob, NULL, NULL);
                 if(!newblk) {
                         mac_free_msg(msg);
                         PORTAL_FREE(ktx, (sizeof(kscimacnal_tx_t)));
@@ -259,9 +292,16 @@ kscimacnal_send(nal_cb_t        *nal,
 
                 payload_len -= nob;
                 payload_niov--;
-                payload_iov++;
+                if(payload_iov != NULL) {
+                        payload_iov++;
+                }
+                else {
+                        payload_kiov++;
+                }
         }
 
+        CDEBUG(D_NET, "kmapped %d pages\n", ktx->ktx_nmapped);
+
         ktx->ktx_nal = nal;
         ktx->ktx_private = private;
         ktx->ktx_cookie = cookie;
@@ -282,6 +322,39 @@ kscimacnal_send(nal_cb_t        *nal,
 }
 
 
+static int
+kscimacnal_send (nal_cb_t     *nal,
+                 void         *private,
+                 lib_msg_t    *cookie,
+                 ptl_hdr_t    *hdr,
+                 int           type,
+                 ptl_nid_t     nid,
+                 ptl_pid_t     pid,
+                 unsigned int  payload_niov,
+                 struct iovec *payload_iov,
+                 size_t        payload_nob)
+{
+        return (kscimacnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+                                payload_niov, payload_iov, NULL, payload_nob));
+}
+
+static int
+kscimacnal_send_pages (nal_cb_t     *nal,
+                       void         *private,
+                       lib_msg_t    *cookie,
+                       ptl_hdr_t    *hdr,
+                       int           type,
+                       ptl_nid_t     nid,
+                       ptl_pid_t     pid,
+                       unsigned int  payload_niov,
+                       ptl_kiov_t   *payload_kiov,
+                       size_t        payload_nob)
+{
+        return (kscimacnal_sendmsg (nal, private, cookie, hdr, type, nid, pid,
+                                payload_niov, NULL, payload_kiov, payload_nob));
+}
+
+
 void
 kscimacnal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
 {
@@ -366,19 +439,22 @@ kscimacnal_rx(mac_handle_t *handle, mac_mblk_t *msg, mac_msg_type_t type,
 
 
 /* Called by portals to process a recieved packet */
-static int kscimacnal_recv(nal_cb_t     *nal, 
-                      void         *private, 
-                      lib_msg_t    *cookie, 
-                      unsigned int  niov, 
-                      struct iovec *iov, 
-                      size_t        mlen, 
-                      size_t        rlen)
+inline static int 
+kscimacnal_recvmsg(nal_cb_t     *nal, 
+                   void         *private, 
+                   lib_msg_t    *cookie, 
+                   unsigned int  niov, 
+                   struct iovec *iov, 
+                   ptl_kiov_t   *kiov,
+                   size_t        mlen, 
+                   size_t        rlen)
 {
         kscimacnal_rx_t    *krx = private;
         mac_mblk_t      *mblk;
         void            *src;
         mac_size_t       pkt_len;
         ptl_size_t       iovused=0;
+        char            *base=NULL;
 
         LASSERT (krx != NULL);
         LASSERT (krx->msg != NULL);
@@ -393,6 +469,10 @@ static int kscimacnal_recv(nal_cb_t     *nal,
          */
         LASSERT (mlen==0 || mac_msg_size(krx->msg) >= sizeof(ptl_hdr_t)+rlen);
         LASSERT (mlen==0 || mlen <= rlen);
+        /* It must be OK to kmap() if required */
+        LASSERT (kiov == NULL || !in_interrupt ());
+        /* Either all pages or all vaddrs */
+        LASSERT (!(kiov != NULL && iov != NULL));
 
         PROF_START(memcpy);
 
@@ -407,36 +487,59 @@ static int kscimacnal_recv(nal_cb_t     *nal,
 
                 LASSERT(src != NULL);
 
-                /* Essentially lib_copy_buf2iov but with continuation support,
-                 * we "gracefully" thrash the argument vars ;) */
+                /* Essentially lib_copy_buf2(k)iov but with continuation
+                 * support, we "gracefully" thrash the argument vars ;) */
                 while (pkt_len > 0) {
-                        ptl_size_t nob;
+                        ptl_size_t  nob, len;
 
                         LASSERT (niov > 0);
 
-                        LASSERT(iovused < iov->iov_len);
+                        if(iov != NULL) {
+                                LASSERT(iovused < iov->iov_len);
+                                len = iov->iov_len;
+                                base = iov->iov_base;
+                        }
+                        else {
+                                LASSERT(iovused < kiov->kiov_len);
+                                len = kiov->kiov_len;
+                                if(base==NULL) {
+                                        /* New page */
+                                        base = kmap(kiov->kiov_page);
+                                }
+                        }
 
-                        nob = MIN (iov->iov_len-iovused, pkt_len);
-                        CDEBUG(D_NET, "iovbase: %p iovlen: %d src: %p  nob: %d "
+                        nob = MIN (len-iovused, pkt_len);
+                        CDEBUG(D_NET, "base: %p len: %d src: %p  nob: %d "
                                         "iovused: %d\n",
-                                        iov->iov_base, iov->iov_len,
-                                        src, nob, iovused);
+                                        base, len, src, nob, iovused);
 
-                        memcpy (iov->iov_base+iovused, src, nob);
+                        memcpy (base+iovused, src, nob);
                         pkt_len -= nob;
                         src += nob;
 
-                        if(nob+iovused < iov->iov_len) {
+                        if(nob+iovused < len) {
                                 /* We didn't use all of the iov */
                                 iovused+=nob;
                         }
                         else {
                                 niov--;
-                                iov++;
                                 iovused=0;
+                                if(iov != NULL) {
+                                        iov++;
+                                }
+                                else {
+                                        kunmap(kiov->kiov_page);
+                                        base=NULL;
+                                        kiov++;
+                                }
                         }
                 }
         }
+        /* Just to make sure the last page is unmapped */
+        if(kiov!=NULL && base!=NULL) {
+                kunmap(kiov->kiov_page);
+                base=NULL;
+        }
         PROF_FINISH(memcpy);
 
         CDEBUG(D_NET, "Calling lib_finalize.\n");
@@ -451,12 +554,38 @@ static int kscimacnal_recv(nal_cb_t     *nal,
 }
 
 
+static int
+kscimacnal_recv(nal_cb_t     *nal,
+             void         *private,
+             lib_msg_t    *cookie,
+             unsigned int  niov,
+             struct iovec *iov,
+             size_t        mlen,
+             size_t        rlen)
+{
+        return (kscimacnal_recvmsg (nal, private, cookie, niov, iov, NULL, mlen, rlen));
+}
+
+
+static int
+kscimacnal_recv_pages (nal_cb_t     *nal,
+                    void         *private,
+                    lib_msg_t    *cookie,
+                    unsigned int  niov,
+                    ptl_kiov_t   *kiov,
+                    size_t        mlen,
+                    size_t        rlen)
+{
+        return (kscimacnal_recvmsg (nal, private, cookie, niov, NULL, kiov, mlen, rlen));
+}
+
+
 nal_cb_t kscimacnal_lib = {
         nal_data:       &kscimacnal_data,               /* NAL private data */
         cb_send:         kscimacnal_send,
-        cb_send_pages:   NULL,                  /* Ignore for now */
+        cb_send_pages:   kscimacnal_send_pages,
         cb_recv:         kscimacnal_recv,
-        cb_recv_pages:   NULL,
+        cb_recv_pages:   kscimacnal_recv_pages,
         cb_read:         kscimacnal_read,
         cb_write:        kscimacnal_write,
         cb_malloc:       kscimacnal_malloc,
diff --git a/lustre/portals/knals/socknal/socknal.c b/lustre/portals/knals/socknal/socknal.c
index 7a02735663cb5ae348cb7e672448ac7323de37ac..6f6fa7ebb5a2fbc3cc83d93e2cd9507d09b2ac1f 100644
--- a/lustre/portals/knals/socknal/socknal.c
+++ b/lustre/portals/knals/socknal/socknal.c
@@ -45,6 +45,8 @@ kpr_nal_interface_t ksocknal_router_interface = {
 #define SOCKNAL_SYSCTL_TIMEOUT     1
 #define SOCKNAL_SYSCTL_EAGER_ACK   2
 #define SOCKNAL_SYSCTL_ZERO_COPY   3
+#define SOCKNAL_SYSCTL_TYPED       4
+#define SOCKNAL_SYSCTL_MIN_BULK    5
 
 static ctl_table ksocknal_ctl_table[] = {
         {SOCKNAL_SYSCTL_TIMEOUT, "timeout", 
@@ -58,6 +60,12 @@ static ctl_table ksocknal_ctl_table[] = {
          &ksocknal_data.ksnd_zc_min_frag, sizeof (int),
          0644, NULL, &proc_dointvec},
 #endif
+        {SOCKNAL_SYSCTL_TYPED, "typed", 
+         &ksocknal_data.ksnd_typed_conns, sizeof (int),
+         0644, NULL, &proc_dointvec},
+        {SOCKNAL_SYSCTL_MIN_BULK, "min_bulk", 
+         &ksocknal_data.ksnd_min_bulk, sizeof (int),
+         0644, NULL, &proc_dointvec},
         { 0 }
 };
 
@@ -86,7 +94,7 @@ ksocknal_api_shutdown(nal_t *nal, int ni)
         CDEBUG (D_NET, "closing all connections\n");
 
         ksocknal_del_route (PTL_NID_ANY, 0, 0, 0);
-        ksocknal_close_conn (PTL_NID_ANY, 0);
+        ksocknal_close_matching_conns (PTL_NID_ANY, 0);
         return PTL_OK;
 }
 
@@ -186,7 +194,7 @@ ksocknal_bind_irq (unsigned int irq)
         snprintf (cmdline, sizeof (cmdline),
                   "echo %d > /proc/irq/%u/smp_affinity", 1 << info->ksni_sched, irq);
 
-        printk (KERN_INFO "Binding irq %u to CPU %d with cmd: %s\n",
+        printk (KERN_INFO "Lustre: Binding irq %u to CPU %d with cmd: %s\n",
                 irq, info->ksni_sched, cmdline);
 
         /* FIXME: Find a better method of setting IRQ affinity...
@@ -198,7 +206,7 @@ ksocknal_bind_irq (unsigned int irq)
 
 ksock_route_t *
 ksocknal_create_route (__u32 ipaddr, int port, int buffer_size,
-                       int nonagel, int xchange_nids, int irq_affinity, int eager)
+                       int nonagel, int irq_affinity, int eager)
 {
         ksock_route_t *route;
 
@@ -215,13 +223,12 @@ ksocknal_create_route (__u32 ipaddr, int port, int buffer_size,
         route->ksnr_port = port;
         route->ksnr_buffer_size = buffer_size;
         route->ksnr_irq_affinity = irq_affinity;
-        route->ksnr_xchange_nids = xchange_nids;
         route->ksnr_nonagel = nonagel;
         route->ksnr_eager = eager;
         route->ksnr_connecting = 0;
+        route->ksnr_connected = 0;
         route->ksnr_deleted = 0;
-        route->ksnr_generation = 0;
-        route->ksnr_conn = NULL;
+        route->ksnr_conn_count = 0;
 
         return (route);
 }
@@ -230,7 +237,6 @@ void
 ksocknal_destroy_route (ksock_route_t *route)
 {
         LASSERT (route->ksnr_sharecount == 0);
-        LASSERT (route->ksnr_conn == NULL);
 
         if (route->ksnr_peer != NULL)
                 ksocknal_put_peer (route->ksnr_peer);
@@ -397,8 +403,7 @@ ksocknal_get_route_by_idx (int index)
 
 int
 ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
-                    int nonagle, int xchange_nids, int bind_irq, 
-                    int share, int eager)
+                    int nonagle, int bind_irq, int share, int eager)
 {
         unsigned long      flags;
         ksock_peer_t      *peer;
@@ -415,8 +420,8 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
         if (peer == NULL)
                 return (-ENOMEM);
 
-        route = ksocknal_create_route (ipaddr, port, bufnob, nonagle,
-                                       xchange_nids, bind_irq, eager);
+        route = ksocknal_create_route (ipaddr, port, bufnob, 
+                                       nonagle, bind_irq, eager);
         if (route == NULL) {
                 ksocknal_put_peer (peer);
                 return (-ENOMEM);
@@ -455,7 +460,7 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
                 route->ksnr_peer = peer;
                 atomic_inc (&peer->ksnp_refcount);
                 /* peer's route list takes existing ref on route */
-                list_add (&route->ksnr_list, &peer->ksnp_routes);
+                list_add_tail (&route->ksnr_list, &peer->ksnp_routes);
         }
         
         route->ksnr_sharecount++;
@@ -468,8 +473,10 @@ ksocknal_add_route (ptl_nid_t nid, __u32 ipaddr, int port, int bufnob,
 void
 ksocknal_del_route_locked (ksock_route_t *route, int share, int keep_conn)
 {
-        ksock_peer_t *peer = route->ksnr_peer;
-        ksock_conn_t *conn = route->ksnr_conn;
+        ksock_peer_t     *peer = route->ksnr_peer;
+        ksock_conn_t     *conn;
+        struct list_head *ctmp;
+        struct list_head *cnxt;
 
         if (!share)
                 route->ksnr_sharecount = 0;
@@ -479,18 +486,22 @@ ksocknal_del_route_locked (ksock_route_t *route, int share, int keep_conn)
                         return;
         }
 
-        if (conn != NULL) {
-                if (!keep_conn)
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry(ctmp, ksock_conn_t, ksnc_list);
+
+                if (conn->ksnc_route != route)
+                        continue;
+                
+                if (!keep_conn) {
                         ksocknal_close_conn_locked (conn, 0);
-                else {
-                        /* keeping the conn; just dissociate it and route... */
-                        conn->ksnc_route = NULL;
-                        route->ksnr_conn = NULL;
-                        ksocknal_put_route (route); /* drop conn's ref on route */
-                        ksocknal_put_conn (conn); /* drop route's ref on conn */
+                        continue;
                 }
+                
+                /* keeping the conn; just dissociate it and route... */
+                conn->ksnc_route = NULL;
+                ksocknal_put_route (route); /* drop conn's ref on route */
         }
-
+        
         route->ksnr_deleted = 1;
         list_del (&route->ksnr_list);
         ksocknal_put_route (route);             /* drop peer's ref */
@@ -669,9 +680,11 @@ ksocknal_choose_scheduler_locked (unsigned int irq)
 }
 
 int
-ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
-                      struct socket *sock, int bind_irq)
+ksocknal_create_conn (ksock_route_t *route, struct socket *sock,
+                      int bind_irq, int type)
 {
+        ptl_nid_t          nid;
+        __u64              incarnation;
         unsigned long      flags;
         ksock_conn_t      *conn;
         ksock_peer_t      *peer;
@@ -692,6 +705,19 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
         if (rc != 0)
                 return (rc);
 
+        if (route == NULL) {
+                /* acceptor or explicit connect */
+                nid = PTL_NID_ANY;
+        } else {
+                LASSERT (type != SOCKNAL_CONN_NONE);
+                /* autoconnect: expect this nid on exchange */
+                nid = route->ksnr_peer->ksnp_nid;
+        }
+
+        rc = ksocknal_hello (sock, &nid, &type, &incarnation);
+        if (rc != 0)
+                return (rc);
+        
         peer = NULL;
         if (route == NULL) {                    /* not autoconnect */
                 /* Assume this socket connects to a brand new peer */
@@ -711,6 +737,8 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
         conn->ksnc_peer = NULL;
         conn->ksnc_route = NULL;
         conn->ksnc_sock = sock;
+        conn->ksnc_type = type;
+        conn->ksnc_incarnation = incarnation;
         conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;
         conn->ksnc_saved_write_space = sock->sk->sk_write_space;
         atomic_set (&conn->ksnc_refcount, 1);    /* 1 ref for me */
@@ -732,7 +760,8 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
 
         if (route != NULL) {
                 /* Autoconnected! */
-                LASSERT (route->ksnr_conn == NULL && route->ksnr_connecting);
+                LASSERT ((route->ksnr_connected & (1 << type)) == 0);
+                LASSERT ((route->ksnr_connecting & (1 << type)) != 0);
 
                 if (route->ksnr_deleted) {
                         /* This conn was autoconnected, but the autoconnect
@@ -745,14 +774,13 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
                 }
 
 
-                /* associate conn/route for auto-reconnect */
-                route->ksnr_conn = conn;
-                atomic_inc (&conn->ksnc_refcount);
+                /* associate conn/route */
                 conn->ksnc_route = route;
                 atomic_inc (&route->ksnr_refcount);
-                route->ksnr_connecting = 0;
 
-                route->ksnr_generation++;
+                route->ksnr_connecting &= ~(1 << type);
+                route->ksnr_connected  |= (1 << type);
+                route->ksnr_conn_count++;
                 route->ksnr_retry_interval = SOCKNAL_MIN_RECONNECT_INTERVAL;
 
                 peer = route->ksnr_peer;
@@ -803,8 +831,13 @@ ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
                 ksocknal_queue_tx_locked (tx, conn);
         }
 
+        rc = ksocknal_close_stale_conns_locked (peer, incarnation);
+
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
+        if (rc != 0)
+                CERROR ("Closed %d stale conns to "LPX64"\n", rc, nid);
+
         if (bind_irq)                           /* irq binding required */
                 ksocknal_bind_irq (irq);
 
@@ -836,14 +869,17 @@ ksocknal_close_conn_locked (ksock_conn_t *conn, int error)
         route = conn->ksnc_route;
         if (route != NULL) {
                 /* dissociate conn from route... */
-                LASSERT (!route->ksnr_connecting &&
-                         !route->ksnr_deleted);
+                LASSERT (!route->ksnr_deleted);
+                LASSERT ((route->ksnr_connecting & (1 << conn->ksnc_type)) == 0);
+                LASSERT ((route->ksnr_connected & (1 << conn->ksnc_type)) != 0);
 
-                route->ksnr_conn = NULL;
+                route->ksnr_connected &= ~(1 << conn->ksnc_type);
                 conn->ksnc_route = NULL;
 
+                list_del (&route->ksnr_list);   /* make route least favourite */
+                list_add_tail (&route->ksnr_list, &peer->ksnp_routes);
+                
                 ksocknal_put_route (route);     /* drop conn's ref on route */
-                ksocknal_put_conn (conn);       /* drop route's ref on conn */
         }
 
         /* ksnd_deathrow_conns takes over peer's ref */
@@ -869,24 +905,6 @@ ksocknal_close_conn_locked (ksock_conn_t *conn, int error)
         spin_unlock (&ksocknal_data.ksnd_reaper_lock);
 }
 
-int
-ksocknal_close_conn_unlocked (ksock_conn_t *conn, int why) 
-{
-        unsigned long flags;
-        int           did_it = 0;
-        
-        write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
-                
-        if (!conn->ksnc_closing) {
-                did_it = 1;
-                ksocknal_close_conn_locked (conn, why);
-        }
-        
-        write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
-
-        return (did_it);
-}
-
 void
 ksocknal_terminate_conn (ksock_conn_t *conn)
 {
@@ -896,15 +914,34 @@ ksocknal_terminate_conn (ksock_conn_t *conn)
          * destroy it. */
         unsigned long   flags;
         ksock_peer_t   *peer = conn->ksnc_peer;
+        ksock_sched_t  *sched = conn->ksnc_scheduler;
         struct timeval  now;
         time_t          then = 0;
         int             notify = 0;
 
+        LASSERT(conn->ksnc_closing);
+
+        /* wake up the scheduler to "send" all remaining packets to /dev/null */
+        spin_lock_irqsave(&sched->kss_lock, flags);
+
+        if (!conn->ksnc_tx_scheduled &&
+            !list_empty(&conn->ksnc_tx_queue)){
+                list_add_tail (&conn->ksnc_tx_list,
+                               &sched->kss_tx_conns);
+                /* a closing conn is always ready to tx */
+                conn->ksnc_tx_ready = 1;
+                conn->ksnc_tx_scheduled = 1;
+                /* extra ref for scheduler */
+                atomic_inc (&conn->ksnc_refcount);
+
+                wake_up (&sched->kss_waitq);
+        }
+
+        spin_unlock_irqrestore (&sched->kss_lock, flags);
+
         /* serialise with callbacks */
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
-        LASSERT (conn->ksnc_closing);
-        
         /* Remove conn's network callbacks.
          * NB I _have_ to restore the callback, rather than storing a noop,
          * since the socket could survive past this module being unloaded!! */
@@ -916,6 +953,8 @@ ksocknal_terminate_conn (ksock_conn_t *conn)
          * sk_user_data is NULL. */
         conn->ksnc_sock->sk->sk_user_data = NULL;
 
+        /* OK, so this conn may not be completely disengaged from its
+         * scheduler yet, but it _has_ committed to terminate... */
         conn->ksnc_scheduler->kss_nconns--;
 
         if (peer->ksnp_error != 0) {
@@ -952,26 +991,20 @@ ksocknal_destroy_conn (ksock_conn_t *conn)
         LASSERT (conn->ksnc_route == NULL);
         LASSERT (!conn->ksnc_tx_scheduled);
         LASSERT (!conn->ksnc_rx_scheduled);
-
-        /* complete queued packets */
-        while (!list_empty (&conn->ksnc_tx_queue)) {
-                ksock_tx_t *tx = list_entry (conn->ksnc_tx_queue.next,
-                                             ksock_tx_t, tx_list);
-
-                CERROR ("Deleting packet type %d len %d ("LPX64"->"LPX64")\n",
-                        NTOH__u32 (tx->tx_hdr->type),
-                        NTOH__u32 (PTL_HDR_LENGTH(tx->tx_hdr)),
-                        NTOH__u64 (tx->tx_hdr->src_nid),
-                        NTOH__u64 (tx->tx_hdr->dest_nid));
-
-                list_del (&tx->tx_list);
-                ksocknal_tx_done (tx, 0);
-        }
+        LASSERT (list_empty(&conn->ksnc_tx_queue));
 
         /* complete current receive if any */
         switch (conn->ksnc_rx_state) {
         case SOCKNAL_RX_BODY:
+#if 0
                 lib_finalize (&ksocknal_lib, NULL, conn->ksnc_cookie);
+#else
+                CERROR ("Refusing to complete a partial receive from "
+                        LPX64", ip %08x\n", conn->ksnc_peer->ksnp_nid,
+                        conn->ksnc_ipaddr);
+                CERROR ("This may hang communications and "
+                        "prevent modules from unloading\n");
+#endif
                 break;
         case SOCKNAL_RX_BODY_FWD:
                 ksocknal_fmb_callback (conn->ksnc_cookie, -ECONNABORTED);
@@ -1012,19 +1045,75 @@ ksocknal_put_conn (ksock_conn_t *conn)
 }
 
 int
-ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr)
+ksocknal_close_peer_conns_locked (ksock_peer_t *peer, __u32 ipaddr, int why)
+{
+        ksock_conn_t       *conn;
+        struct list_head   *ctmp;
+        struct list_head   *cnxt;
+        int                 count = 0;
+
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+                if (ipaddr == 0 ||
+                    conn->ksnc_ipaddr == ipaddr) {
+                        count++;
+                        ksocknal_close_conn_locked (conn, why);
+                }
+        }
+
+        return (count);
+}
+
+int
+ksocknal_close_stale_conns_locked (ksock_peer_t *peer, __u64 incarnation)
 {
-        unsigned long       flags;
         ksock_conn_t       *conn;
         struct list_head   *ctmp;
         struct list_head   *cnxt;
+        int                 count = 0;
+
+        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+                conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+                if (conn->ksnc_incarnation == incarnation)
+                        continue;
+                
+                count++;
+                ksocknal_close_conn_locked (conn, -ESTALE);
+        }
+
+        return (count);
+}
+
+int
+ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why) 
+{
+        ksock_peer_t     *peer = conn->ksnc_peer;
+        __u32             ipaddr = conn->ksnc_ipaddr;
+        unsigned long     flags;
+        int               count;
+
+        write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
+
+        count = ksocknal_close_peer_conns_locked (peer, ipaddr, why);
+        
+        write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
+
+        return (count);
+}
+
+int
+ksocknal_close_matching_conns (ptl_nid_t nid, __u32 ipaddr)
+{
+        unsigned long       flags;
         ksock_peer_t       *peer;
         struct list_head   *ptmp;
         struct list_head   *pnxt;
         int                 lo;
         int                 hi;
         int                 i;
-        int                 rc = -ENOENT;
+        int                 count = 0;
 
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
@@ -1043,24 +1132,17 @@ ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr)
                         if (!(nid == PTL_NID_ANY || nid == peer->ksnp_nid))
                                 continue;
 
-                        list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
-
-                                conn = list_entry (ctmp, ksock_conn_t,
-                                                   ksnc_list);
-
-                                if (!(ipaddr == 0 ||
-                                      conn->ksnc_ipaddr == ipaddr))
-                                        continue;
-
-                                rc = 0;
-                                ksocknal_close_conn_locked (conn, 0);
-                        }
+                        count += ksocknal_close_peer_conns_locked (peer, ipaddr, 0);
                 }
         }
 
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
-        return (rc);
+        /* wildcards always succeed */
+        if (nid == PTL_NID_ANY || ipaddr == 0)
+                return (0);
+        
+        return (count == 0 ? -ENOENT : 0);
 }
 
 void
@@ -1073,7 +1155,7 @@ ksocknal_notify (void *arg, ptl_nid_t gw_nid, int alive)
 
         if (!alive) {
                 /* If the gateway crashed, close all open connections... */
-                ksocknal_close_conn (gw_nid, 0);
+                ksocknal_close_matching_conns (gw_nid, 0);
                 return;
         }
         
@@ -1216,85 +1298,95 @@ ksocknal_push (ptl_nid_t nid)
 }
 
 int
-ksocknal_cmd(struct portal_ioctl_data * data, void * private)
+ksocknal_cmd(struct portals_cfg *pcfg, void * private)
 {
         int rc = -EINVAL;
 
-        LASSERT (data != NULL);
+        LASSERT (pcfg != NULL);
 
-        switch(data->ioc_nal_cmd) {
+        switch(pcfg->pcfg_command) {
         case NAL_CMD_GET_AUTOCONN: {
-                ksock_route_t *route = ksocknal_get_route_by_idx (data->ioc_count);
+                ksock_route_t *route = ksocknal_get_route_by_idx (pcfg->pcfg_count);
 
                 if (route == NULL)
                         rc = -ENOENT;
                 else {
                         rc = 0;
-                        data->ioc_nid   = route->ksnr_peer->ksnp_nid;
-                        data->ioc_id    = route->ksnr_ipaddr;
-                        data->ioc_misc  = route->ksnr_port;
-                        data->ioc_count = route->ksnr_generation;
-                        data->ioc_size  = route->ksnr_buffer_size;
-                        data->ioc_wait  = route->ksnr_sharecount;
-                        data->ioc_flags = (route->ksnr_nonagel      ? 1 : 0) |
-                                          (route->ksnr_xchange_nids ? 2 : 0) |
-                                          (route->ksnr_irq_affinity ? 4 : 0) |
-                                          (route->ksnr_eager        ? 8 : 0);
+                        pcfg->pcfg_nid   = route->ksnr_peer->ksnp_nid;
+                        pcfg->pcfg_id    = route->ksnr_ipaddr;
+                        pcfg->pcfg_misc  = route->ksnr_port;
+                        pcfg->pcfg_count = route->ksnr_conn_count;
+                        pcfg->pcfg_size  = route->ksnr_buffer_size;
+                        pcfg->pcfg_wait  = route->ksnr_sharecount;
+                        pcfg->pcfg_flags = (route->ksnr_nonagel      ? 1 : 0) |
+                                           (route->ksnr_irq_affinity ? 2 : 0) |
+                                           (route->ksnr_eager        ? 4 : 0);
                         ksocknal_put_route (route);
                 }
                 break;
         }
         case NAL_CMD_ADD_AUTOCONN: {
-                rc = ksocknal_add_route (data->ioc_nid, data->ioc_id,
-                                         data->ioc_misc, data->ioc_size,
-                                         (data->ioc_flags & 0x01) != 0,
-                                         (data->ioc_flags & 0x02) != 0,
-                                         (data->ioc_flags & 0x04) != 0,
-                                         (data->ioc_flags & 0x08) != 0,
-                                         (data->ioc_flags & 0x10) != 0);
+                rc = ksocknal_add_route (pcfg->pcfg_nid, pcfg->pcfg_id,
+                                         pcfg->pcfg_misc, pcfg->pcfg_size,
+                                         (pcfg->pcfg_flags & 0x01) != 0,
+                                         (pcfg->pcfg_flags & 0x02) != 0,
+                                         (pcfg->pcfg_flags & 0x04) != 0,
+                                         (pcfg->pcfg_flags & 0x08) != 0);
                 break;
         }
         case NAL_CMD_DEL_AUTOCONN: {
-                rc = ksocknal_del_route (data->ioc_nid, data->ioc_id, 
-                                         (data->ioc_flags & 1) != 0,
-                                         (data->ioc_flags & 2) != 0);
+                rc = ksocknal_del_route (pcfg->pcfg_nid, pcfg->pcfg_id, 
+                                         (pcfg->pcfg_flags & 1) != 0,
+                                         (pcfg->pcfg_flags & 2) != 0);
                 break;
         }
         case NAL_CMD_GET_CONN: {
-                ksock_conn_t *conn = ksocknal_get_conn_by_idx (data->ioc_count);
+                ksock_conn_t *conn = ksocknal_get_conn_by_idx (pcfg->pcfg_count);
 
                 if (conn == NULL)
                         rc = -ENOENT;
                 else {
                         rc = 0;
-                        data->ioc_nid  = conn->ksnc_peer->ksnp_nid;
-                        data->ioc_id   = conn->ksnc_ipaddr;
-                        data->ioc_misc = conn->ksnc_port;
+                        pcfg->pcfg_nid   = conn->ksnc_peer->ksnp_nid;
+                        pcfg->pcfg_id    = conn->ksnc_ipaddr;
+                        pcfg->pcfg_misc  = conn->ksnc_port;
+                        pcfg->pcfg_flags = conn->ksnc_type;
                         ksocknal_put_conn (conn);
                 }
                 break;
         }
         case NAL_CMD_REGISTER_PEER_FD: {
-                struct socket *sock = sockfd_lookup (data->ioc_fd, &rc);
+                struct socket *sock = sockfd_lookup (pcfg->pcfg_fd, &rc);
+                int            type = pcfg->pcfg_misc;
 
-                if (sock != NULL) {
-                        rc = ksocknal_create_conn (data->ioc_nid, NULL,
-                                                   sock, data->ioc_flags);
-                        if (rc != 0)
-                                fput (sock->file);
+                if (sock == NULL)
+                        break;
+
+                switch (type) {
+                case SOCKNAL_CONN_NONE:
+                case SOCKNAL_CONN_ANY:
+                case SOCKNAL_CONN_CONTROL:
+                case SOCKNAL_CONN_BULK_IN:
+                case SOCKNAL_CONN_BULK_OUT:
+                        rc = ksocknal_create_conn(NULL, sock, pcfg->pcfg_flags, type);
+                default:
+                        break;
                 }
+                if (rc != 0)
+                        fput (sock->file);
                 break;
         }
         case NAL_CMD_CLOSE_CONNECTION: {
-                rc = ksocknal_close_conn (data->ioc_nid, data->ioc_id);
+                rc = ksocknal_close_matching_conns (pcfg->pcfg_nid, 
+                                                    pcfg->pcfg_id);
                 break;
         }
         case NAL_CMD_REGISTER_MYNID: {
-                rc = ksocknal_set_mynid (data->ioc_nid);
+                rc = ksocknal_set_mynid (pcfg->pcfg_nid);
                 break;
         }
         case NAL_CMD_PUSH_CONNECTION: {
-                rc = ksocknal_push (data->ioc_nid);
+                rc = ksocknal_push (pcfg->pcfg_nid);
                 break;
         }
         }
@@ -1337,7 +1429,7 @@ ksocknal_free_buffers (void)
                      ksocknal_data.ksnd_peer_hash_size);
 }
 
-void /*__exit*/
+void
 ksocknal_module_fini (void)
 {
         int   i;
@@ -1416,11 +1508,27 @@ ksocknal_module_fini (void)
         CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
                atomic_read (&portal_kmemory));
 
-        printk(KERN_INFO "Routing socket NAL unloaded (final mem %d)\n",
+        printk(KERN_INFO "Lustre: Routing socket NAL unloaded (final mem %d)\n",
                atomic_read(&portal_kmemory));
 }
 
 
+void __init
+ksocknal_init_incarnation (void)
+{
+        struct timeval tv;
+
+        /* The incarnation number is the time this module loaded and it
+         * identifies this particular instance of the socknal.  Hopefully
+         * we won't be able to reboot more frequently than 1MHz for the
+         * forseeable future :) */
+        
+        do_gettimeofday(&tv);
+        
+        ksocknal_data.ksnd_incarnation = 
+                (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
+}
+
 int __init
 ksocknal_module_init (void)
 {
@@ -1434,7 +1542,9 @@ ksocknal_module_init (void)
         /* the following must be sizeof(int) for proc_dointvec() */
         LASSERT(sizeof (ksocknal_data.ksnd_io_timeout) == sizeof (int));
         LASSERT(sizeof (ksocknal_data.ksnd_eager_ack) == sizeof (int));
-
+        /* check ksnr_connected/connecting field large enough */
+        LASSERT(SOCKNAL_CONN_NTYPES <= 4);
+        
         LASSERT (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING);
 
         ksocknal_api.forward  = ksocknal_api_forward;
@@ -1451,10 +1561,13 @@ ksocknal_module_init (void)
 
         ksocknal_data.ksnd_io_timeout = SOCKNAL_IO_TIMEOUT;
         ksocknal_data.ksnd_eager_ack  = SOCKNAL_EAGER_ACK;
+        ksocknal_data.ksnd_typed_conns = SOCKNAL_TYPED_CONNS;
+        ksocknal_data.ksnd_min_bulk   = SOCKNAL_MIN_BULK;
 #if SOCKNAL_ZC
         ksocknal_data.ksnd_zc_min_frag = SOCKNAL_ZC_MIN_FRAG;
 #endif
-
+        ksocknal_init_incarnation();
+        
         ksocknal_data.ksnd_peer_hash_size = SOCKNAL_PEER_HASH_SIZE;
         PORTAL_ALLOC (ksocknal_data.ksnd_peers,
                       sizeof (struct list_head) * ksocknal_data.ksnd_peer_hash_size);
@@ -1643,9 +1756,9 @@ ksocknal_module_init (void)
 #endif
         /* flag everything initialised */
         ksocknal_data.ksnd_init = SOCKNAL_INIT_ALL;
-        
-        printk(KERN_INFO "Routing socket NAL loaded (Routing %s, initial "
-               "mem %d)\n",
+
+        printk(KERN_INFO "Lustre: Routing socket NAL loaded "
+               "(Routing %s, initial mem %d)\n",
                kpr_routing (&ksocknal_data.ksnd_router) ?
                "enabled" : "disabled", pkmem);
 
diff --git a/lustre/portals/knals/socknal/socknal.h b/lustre/portals/knals/socknal/socknal.h
index abd8e7b718c211e15b35b6f23aafb48f82c2fd2c..227a24ff6fb781341820faac491bb4e557d4f59c 100644
--- a/lustre/portals/knals/socknal/socknal.h
+++ b/lustre/portals/knals/socknal/socknal.h
@@ -25,7 +25,9 @@
  */
 
 #define DEBUG_PORTAL_ALLOC
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -58,9 +60,10 @@
 #include <linux/kp30.h>
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
+#include <portals/socknal.h>
 
 #if CONFIG_SMP
-# define SOCKNAL_N_SCHED        smp_num_cpus    /* # socknal schedulers */
+# define SOCKNAL_N_SCHED       num_online_cpus() /* # socknal schedulers */
 #else
 # define SOCKNAL_N_SCHED        1               /* # socknal schedulers */
 #endif
@@ -71,19 +74,14 @@
 
 /* default vals for runtime tunables */
 #define SOCKNAL_IO_TIMEOUT       50             /* default comms timeout (seconds) */
-#define SOCKNAL_EAGER_ACK        1              /* default eager ack (boolean) */
+#define SOCKNAL_EAGER_ACK        0              /* default eager ack (boolean) */
+#define SOCKNAL_TYPED_CONNS      1              /* unidirectional large, bidirectional small? */
 #define SOCKNAL_ZC_MIN_FRAG     (2<<10)         /* default smallest zerocopy fragment */
-
+#define SOCKNAL_MIN_BULK        (1<<10)         /* smallest "large" message */
 #define SOCKNAL_USE_KEEPALIVES   0              /* use tcp/ip keepalive? */
 
 #define SOCKNAL_PEER_HASH_SIZE   101            /* # peer lists */
 
-#if PTL_LARGE_MTU
-# define SOCKNAL_MAX_FWD_PAYLOAD (256<<10)      /* biggest payload I can forward */
-#else
-# define SOCKNAL_MAX_FWD_PAYLOAD (64<<10)       /* biggest payload I can forward */
-#endif
-
 #define SOCKNAL_NLTXS           128             /* # normal transmit messages */
 #define SOCKNAL_NNBLK_LTXS	128             /* # transmit messages reserved if can't block */
 
@@ -92,7 +90,7 @@
 
 #define SOCKNAL_SMALL_FWD_PAGES	1               /* # pages in a small message fwd buffer */
 
-#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + SOCKNAL_MAX_FWD_PAYLOAD) >> PAGE_SHIFT)
+#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
 						/* # pages in a large message fwd buffer */
 
 #define SOCKNAL_RESCHED         100             /* # scheduler loops before reschedule */
@@ -108,6 +106,10 @@
 # define sk_socket      socket
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# define sk_wmem_queued wmem_queued
+#endif
+
 typedef struct                                  /* pool of forwarding buffers */
 {
         spinlock_t        fmp_lock;             /* serialise */
@@ -138,10 +140,13 @@ typedef struct {
         int               ksnd_init;            /* initialisation state */
         int               ksnd_io_timeout;      /* "stuck" socket timeout (seconds) */
         int               ksnd_eager_ack;       /* make TCP ack eagerly? */
+        int               ksnd_typed_conns;     /* drive sockets by type? */
+        int               ksnd_min_bulk;        /* smallest "large" message */
 #if SOCKNAL_ZC
         unsigned int      ksnd_zc_min_frag;     /* minimum zero copy frag size */
 #endif
         struct ctl_table_header *ksnd_sysctl;   /* sysctl interface */
+        __u64             ksnd_incarnation;     /* my epoch */
         
         rwlock_t          ksnd_global_lock;     /* stabilize peer/conn ops */
         struct list_head *ksnd_peers;           /* hash table of all my known peers */
@@ -296,8 +301,10 @@ typedef struct ksock_conn
         __u32               ksnc_ipaddr;        /* peer's IP */
         int                 ksnc_port;          /* peer's port */
         int                 ksnc_closing;       /* being shut down */
+        int                 ksnc_type;          /* type of connection */
+        __u64               ksnc_incarnation;   /* peer's incarnation */
         
-        /* READER */
+        /* reader */
         struct list_head    ksnc_rx_list;       /* where I enq waiting input or a forwarding descriptor */
         unsigned long       ksnc_rx_deadline;   /* when (in jiffies) receive times out */
         int                 ksnc_rx_started;    /* started receiving a message */
@@ -323,6 +330,10 @@ typedef struct ksock_conn
         int                 ksnc_tx_scheduled;  /* being progressed */
 } ksock_conn_t;
 
+#define KSNR_TYPED_ROUTES   ((1 << SOCKNAL_CONN_CONTROL) |      \
+                             (1 << SOCKNAL_CONN_BULK_IN) |      \
+                             (1 << SOCKNAL_CONN_BULK_OUT))
+
 typedef struct ksock_route
 {
         struct list_head    ksnr_list;          /* chain on peer route list */
@@ -336,13 +347,12 @@ typedef struct ksock_route
         int                 ksnr_port;          /* port to connect to */
         int                 ksnr_buffer_size;   /* size of socket buffers */
         unsigned int        ksnr_irq_affinity:1; /* set affinity? */
-        unsigned int        ksnr_xchange_nids:1; /* do hello protocol? */
         unsigned int        ksnr_nonagel:1;     /* disable nagle? */
         unsigned int        ksnr_eager:1;       /* connect eagery? */
-        unsigned int        ksnr_connecting:1;  /* autoconnect in progress? */
+        unsigned int        ksnr_connecting:4;  /* autoconnects in progress by type */
+        unsigned int        ksnr_connected:4;   /* connections established by type */
         unsigned int        ksnr_deleted:1;     /* been removed from peer? */
-        int                 ksnr_generation;    /* connection incarnation # */
-        ksock_conn_t       *ksnr_conn;          /* NULL/active connection */
+        int                 ksnr_conn_count;    /* # conns established by this route */
 } ksock_route_t;
 
 typedef struct ksock_peer
@@ -397,14 +407,15 @@ extern ksock_peer_t *ksocknal_find_peer_locked (ptl_nid_t nid);
 extern ksock_peer_t *ksocknal_get_peer (ptl_nid_t nid);
 extern int ksocknal_del_route (ptl_nid_t nid, __u32 ipaddr,
                                int single, int keep_conn);
-extern int ksocknal_create_conn (ptl_nid_t nid, ksock_route_t *route,
-                                 struct socket *sock, int bind_irq);
+extern int ksocknal_create_conn (ksock_route_t *route,
+                                 struct socket *sock, int bind_irq, int type);
 extern void ksocknal_close_conn_locked (ksock_conn_t *conn, int why);
-extern int ksocknal_close_conn_unlocked (ksock_conn_t *conn, int why);
 extern void ksocknal_terminate_conn (ksock_conn_t *conn);
 extern void ksocknal_destroy_conn (ksock_conn_t *conn);
 extern void ksocknal_put_conn (ksock_conn_t *conn);
-extern int ksocknal_close_conn (ptl_nid_t nid, __u32 ipaddr);
+extern int ksocknal_close_stale_conns_locked (ksock_peer_t *peer, __u64 incarnation);
+extern int ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why);
+extern int ksocknal_close_matching_conns (ptl_nid_t nid, __u32 ipaddr);
 
 extern void ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn);
 extern void ksocknal_tx_done (ksock_tx_t *tx, int asynch);
@@ -419,3 +430,5 @@ extern void ksocknal_write_space(struct sock *sk);
 extern int ksocknal_autoconnectd (void *arg);
 extern int ksocknal_reaper (void *arg);
 extern int ksocknal_setup_sock (struct socket *sock);
+extern int ksocknal_hello (struct socket *sock, 
+                           ptl_nid_t *nid, int *type, __u64 *incarnation);
diff --git a/lustre/portals/knals/socknal/socknal_cb.c b/lustre/portals/knals/socknal/socknal_cb.c
index bc52a5ce2811e158bae957becfb7f7793187da66..6ea4fa8d126f0e1b29220f6c812efc4f23ff08e3 100644
--- a/lustre/portals/knals/socknal/socknal_cb.c
+++ b/lustre/portals/knals/socknal/socknal_cb.c
@@ -218,9 +218,9 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
         struct iovec  *iov = tx->tx_iov;
         int            fragsize = iov->iov_len;
         unsigned long  vaddr = (unsigned long)iov->iov_base;
-        int            more = (!list_empty (&conn->ksnc_tx_queue)) |
-                              (tx->tx_niov > 1) |
-                              (tx->tx_nkiov > 1);
+        int            more = (tx->tx_niov > 1) || 
+                              (tx->tx_nkiov > 0) ||
+                              (!list_empty (&conn->ksnc_tx_queue));
 #if SOCKNAL_ZC
         int            offset = vaddr & (PAGE_SIZE - 1);
         int            zcsize = MIN (fragsize, PAGE_SIZE - offset);
@@ -266,7 +266,7 @@ ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
                         .msg_flags      = more ? (MSG_DONTWAIT | MSG_MORE) : MSG_DONTWAIT
                 };
                 mm_segment_t oldmm = get_fs();
-                
+
                 set_fs (KERNEL_DS);
                 rc = sock_sendmsg(sock, &msg, fragsize);
                 set_fs (oldmm);
@@ -298,8 +298,8 @@ ksocknal_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
         int            fragsize = kiov->kiov_len;
         struct page   *page = kiov->kiov_page;
         int            offset = kiov->kiov_offset;
-        int            more = (!list_empty (&conn->ksnc_tx_queue)) |
-                              (tx->tx_nkiov > 1);
+        int            more = (tx->tx_nkiov > 1) ||
+                              (!list_empty (&conn->ksnc_tx_queue));
         int            rc;
 
         /* NB we can't trust socket ops to either consume our iovs
@@ -464,7 +464,7 @@ ksocknal_recv_iov (ksock_conn_t *conn)
          * or leave them alone, so we only receive 1 frag at a time. */
         LASSERT (conn->ksnc_rx_niov > 0);
         LASSERT (fragsize <= conn->ksnc_rx_nob_wanted);
-        
+
         set_fs (KERNEL_DS);
         rc = sock_recvmsg (conn->ksnc_sock, &msg, fragsize, MSG_DONTWAIT);
         /* NB this is just a boolean............................^ */
@@ -521,7 +521,7 @@ ksocknal_recv_kiov (ksock_conn_t *conn)
         LASSERT (fragsize <= conn->ksnc_rx_nob_wanted);
         LASSERT (conn->ksnc_rx_nkiov > 0);
         LASSERT (offset + fragsize <= PAGE_SIZE);
-        
+
         set_fs (KERNEL_DS);
         rc = sock_recvmsg (conn->ksnc_sock, &msg, fragsize, MSG_DONTWAIT);
         /* NB this is just a boolean............................^ */
@@ -597,7 +597,7 @@ ksocknal_recvmsg (ksock_conn_t *conn)
 
                 if (conn->ksnc_rx_nob_wanted == 0) {
                         /* Completed a message segment (header or payload) */
-                        if (ksocknal_data.ksnd_eager_ack &&
+                        if ((ksocknal_data.ksnd_eager_ack & conn->ksnc_type) != 0 &&
                             (conn->ksnc_rx_state ==  SOCKNAL_RX_BODY ||
                              conn->ksnc_rx_state == SOCKNAL_RX_BODY_FWD)) {
                                 /* Remind the socket to ack eagerly... */
@@ -691,71 +691,37 @@ ksocknal_tx_launched (ksock_tx_t *tx)
         ksocknal_tx_done (tx, 0);
 }
 
-void
-ksocknal_process_transmit (ksock_sched_t *sched, unsigned long *irq_flags)
+int
+ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
 {
-        ksock_conn_t  *conn;
-        ksock_tx_t    *tx;
         int            rc;
-        
-        LASSERT (!list_empty (&sched->kss_tx_conns));
-        conn = list_entry(sched->kss_tx_conns.next, ksock_conn_t, ksnc_tx_list);
-        list_del (&conn->ksnc_tx_list);
-
-        LASSERT (conn->ksnc_tx_scheduled);
-        LASSERT (conn->ksnc_tx_ready);
-        LASSERT (!list_empty (&conn->ksnc_tx_queue));
-        tx = list_entry (conn->ksnc_tx_queue.next, ksock_tx_t, tx_list);
-        /* assume transmit will complete now, so dequeue while I've got lock */
-        list_del (&tx->tx_list);
-
-        spin_unlock_irqrestore (&sched->kss_lock, *irq_flags);
-
-        LASSERT (tx->tx_resid > 0);
-
-        conn->ksnc_tx_ready = 0;/* write_space may race with me and set ready */
-        mb();                   /* => clear BEFORE trying to write */
-
+       
         rc = ksocknal_sendmsg (conn, tx);
 
         CDEBUG (D_NET, "send(%d) %d\n", tx->tx_resid, rc);
+        LASSERT (rc != -EAGAIN);
 
-        if (rc != 0) {
-                if (ksocknal_close_conn_unlocked (conn, rc)) {
-                        /* I'm the first to close */
-                        CERROR ("[%p] Error %d on write to "LPX64" ip %08x:%d\n",
-                                conn, rc, conn->ksnc_peer->ksnp_nid,
-                                conn->ksnc_ipaddr, conn->ksnc_port);
+        if (rc == 0) {
+                /* no errors */
+                if (tx->tx_resid != 0) {
+                        /* didn't send everything */
+                        return (-EAGAIN);
                 }
+                
                 ksocknal_tx_launched (tx);
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
+                return (0);
+        }
 
-        } else if (tx->tx_resid == 0) {  
-                /* everything went; assume more can go, and avoid
-                 * write_space locking */
-                conn->ksnc_tx_ready = 1;
+        if (!conn->ksnc_closing)
+                CERROR ("[%p] Error %d on write to "LPX64" ip %08x:%d\n",
+                        conn, rc, conn->ksnc_peer->ksnp_nid,
+                        conn->ksnc_ipaddr, conn->ksnc_port);
 
-                ksocknal_tx_launched (tx);
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-        } else {
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
+        ksocknal_close_conn_and_siblings (conn, rc);
+        ksocknal_tx_launched (tx);
 
-                /* back onto HEAD of tx_queue */
-                list_add (&tx->tx_list, &conn->ksnc_tx_queue);
-        }
-
-        /* no space to write, or nothing to write? */
-        if (!conn->ksnc_tx_ready ||
-            list_empty (&conn->ksnc_tx_queue)) {
-                /* mark not scheduled */
-                conn->ksnc_tx_scheduled = 0;
-                /* drop scheduler's ref */
-                ksocknal_put_conn (conn);
-        } else {
-                /* stay scheduled */
-                list_add_tail (&conn->ksnc_tx_list, &sched->kss_tx_conns);
-        }
-}
+        return (rc);
+} 
 
 void
 ksocknal_launch_autoconnect_locked (ksock_route_t *route)
@@ -764,10 +730,17 @@ ksocknal_launch_autoconnect_locked (ksock_route_t *route)
 
         /* called holding write lock on ksnd_global_lock */
 
-        LASSERT (route->ksnr_conn == NULL);
-        LASSERT (!route->ksnr_deleted && !route->ksnr_connecting);
+        LASSERT (!route->ksnr_deleted);
+        LASSERT ((route->ksnr_connected & (1 << SOCKNAL_CONN_ANY)) == 0);
+        LASSERT ((route->ksnr_connected & KSNR_TYPED_ROUTES) != KSNR_TYPED_ROUTES);
+        LASSERT (!route->ksnr_connecting);
         
-        route->ksnr_connecting = 1;
+        if (ksocknal_data.ksnd_typed_conns)
+                route->ksnr_connecting = 
+                        KSNR_TYPED_ROUTES & ~route->ksnr_connected;
+        else
+                route->ksnr_connecting = (1 << SOCKNAL_CONN_ANY);
+
         atomic_inc (&route->ksnr_refcount);     /* extra ref for asynchd */
         
         spin_lock_irqsave (&ksocknal_data.ksnd_autoconnectd_lock, flags);
@@ -814,21 +787,51 @@ ksock_conn_t *
 ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer) 
 {
         struct list_head *tmp;
-        ksock_conn_t     *conn = NULL;
-
+        ksock_conn_t     *typed = NULL;
+        int               tnob  = 0;
+        ksock_conn_t     *fallback = NULL;
+        int               fnob     = 0;
+        
         /* Find the conn with the shortest tx queue */
         list_for_each (tmp, &peer->ksnp_conns) {
-                ksock_conn_t *c = list_entry (tmp, ksock_conn_t, ksnc_list);
+                ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list);
+                int           nob = atomic_read(&c->ksnc_tx_nob);
 
                 LASSERT (!c->ksnc_closing);
-                
-                if (conn == NULL ||
-                    atomic_read (&conn->ksnc_tx_nob) >
-                    atomic_read (&c->ksnc_tx_nob))
-                        conn = c;
+
+                if (fallback == NULL || nob < fnob) {
+                        fallback = c;
+                        fnob     = nob;
+                }
+
+                if (!ksocknal_data.ksnd_typed_conns)
+                        continue;
+
+                switch (c->ksnc_type) {
+                default:
+                        LBUG();
+                case SOCKNAL_CONN_ANY:
+                        break;
+                case SOCKNAL_CONN_BULK_IN:
+                        continue;
+                case SOCKNAL_CONN_BULK_OUT:
+                        if (tx->tx_nob < ksocknal_data.ksnd_min_bulk)
+                                continue;
+                        break;
+                case SOCKNAL_CONN_CONTROL:
+                        if (tx->tx_nob >= ksocknal_data.ksnd_min_bulk)
+                                continue;
+                        break;
+                }
+
+                if (typed == NULL || nob < tnob) {
+                        typed = c;
+                        tnob  = nob;
+                }
         }
 
-        return (conn);
+        /* prefer the typed selection */
+        return ((typed != NULL) ? typed : fallback);
 }
 
 void
@@ -854,6 +857,10 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
 
         spin_lock_irqsave (&sched->kss_lock, flags);
 
+        conn->ksnc_tx_deadline = jiffies + 
+                                 ksocknal_data.ksnd_io_timeout * HZ;
+        mb();                                   /* order with list_add_tail */
+
         list_add_tail (&tx->tx_list, &conn->ksnc_tx_queue);
                 
         if (conn->ksnc_tx_ready &&      /* able to send */
@@ -870,22 +877,46 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
 }
 
 ksock_route_t *
-ksocknal_find_connectable_route_locked (ksock_peer_t *peer, int eager_only)
+ksocknal_find_connectable_route_locked (ksock_peer_t *peer)
 {
         struct list_head  *tmp;
         ksock_route_t     *route;
+        ksock_route_t     *candidate = NULL;
+        int                found = 0;
+        int                bits;
         
         list_for_each (tmp, &peer->ksnp_routes) {
                 route = list_entry (tmp, ksock_route_t, ksnr_list);
+                bits  = route->ksnr_connected;
+                
+                if ((bits & KSNR_TYPED_ROUTES) == KSNR_TYPED_ROUTES ||
+                    (bits & (1 << SOCKNAL_CONN_ANY)) != 0 ||
+                    route->ksnr_connecting != 0) {
+                        /* All typed connections have been established, or
+                         * an untyped connection has been established, or
+                         * connections are currently being established */
+                        found = 1;
+                        continue;
+                }
+
+                /* too soon to retry this guy? */
+                if (!time_after_eq (jiffies, route->ksnr_timeout))
+                        continue;
                 
-                if (route->ksnr_conn == NULL && /* not connected */
-                    !route->ksnr_connecting &&  /* not connecting */
-                    (!eager_only || route->ksnr_eager) && /* wants to connect */
-                    time_after_eq (jiffies, route->ksnr_timeout)) /* OK to retry */
+                /* always do eager routes */
+                if (route->ksnr_eager)
                         return (route);
+
+                if (candidate == NULL) {
+                        /* If we don't find any other route that is fully
+                         * connected or connecting, the first connectable
+                         * route is returned.  If it fails to connect, it
+                         * will get placed at the end of the list */
+                        candidate = route;
+                }
         }
-        
-        return (NULL);
+ 
+        return (found ? NULL : candidate);
 }
 
 ksock_route_t *
@@ -897,7 +928,7 @@ ksocknal_find_connecting_route_locked (ksock_peer_t *peer)
         list_for_each (tmp, &peer->ksnp_routes) {
                 route = list_entry (tmp, ksock_route_t, ksnr_list);
                 
-                if (route->ksnr_connecting)
+                if (route->ksnr_connecting != 0)
                         return (route);
         }
         
@@ -912,7 +943,7 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         ksock_conn_t     *conn;
         ksock_route_t    *route;
         rwlock_t         *g_lock;
-
+        
         /* Ensure the frags we've been given EXACTLY match the number of
          * bytes we want to send.  Many TCP/IP stacks disregard any total
          * size parameters passed to them and just look at the frags. 
@@ -936,18 +967,17 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         peer = ksocknal_find_target_peer_locked (tx, nid);
         if (peer == NULL) {
                 read_unlock (g_lock);
-                return (PTL_FAIL);
+                return (-EHOSTUNREACH);
         }
 
-        if (ksocknal_find_connectable_route_locked(peer, 1) == NULL) {
+        if (ksocknal_find_connectable_route_locked(peer) == NULL) {
                 conn = ksocknal_find_conn_locked (tx, peer);
                 if (conn != NULL) {
-                        /* I've got no unconnected autoconnect routes that
-                         * need to be connected, and I do have an actual
-                         * connection... */
+                        /* I've got no autoconnect routes that need to be
+                         * connecting and I do have an actual connection... */
                         ksocknal_queue_tx_locked (tx, conn);
                         read_unlock (g_lock);
-                        return (PTL_OK);
+                        return (0);
                 }
         }
         
@@ -960,14 +990,13 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
         if (peer->ksnp_closing) {               /* peer deleted as I blocked! */
                 write_unlock_irqrestore (g_lock, flags);
                 ksocknal_put_peer (peer);
-                return (PTL_FAIL);
+                return (-EHOSTUNREACH);
         }
         ksocknal_put_peer (peer);               /* drop ref I got above */
 
-
         for (;;) {
-                /* launch all eager autoconnections */
-                route = ksocknal_find_connectable_route_locked (peer, 1);
+                /* launch any/all autoconnections that need it */
+                route = ksocknal_find_connectable_route_locked (peer);
                 if (route == NULL)
                         break;
 
@@ -979,26 +1008,20 @@ ksocknal_launch_packet (ksock_tx_t *tx, ptl_nid_t nid)
                 /* Connection exists; queue message on it */
                 ksocknal_queue_tx_locked (tx, conn);
                 write_unlock_irqrestore (g_lock, flags);
-                return (PTL_OK);
+                return (0);
         }
 
-        if (ksocknal_find_connecting_route_locked (peer) == NULL) {
-                /* no autoconnect routes actually connecting now.  Scrape
-                 * the barrel for non-eager autoconnects */
-                route = ksocknal_find_connectable_route_locked (peer, 0);
-                if (route != NULL) {
-                        ksocknal_launch_autoconnect_locked (route);
-                } else {
-                        write_unlock_irqrestore (g_lock, flags);
-                        return (PTL_FAIL);
-                }
+        route = ksocknal_find_connecting_route_locked (peer);
+        if (route != NULL) {
+                /* At least 1 connection is being established; queue the
+                 * message... */
+                list_add_tail (&tx->tx_list, &peer->ksnp_tx_queue);
+                write_unlock_irqrestore (g_lock, flags);
+                return (0);
         }
-
-        /* At least 1 connection is being established; queue the message... */
-        list_add_tail (&tx->tx_list, &peer->ksnp_tx_queue);
-
+        
         write_unlock_irqrestore (g_lock, flags);
-        return (PTL_OK);
+        return (-EHOSTUNREACH);
 }
 
 ksock_ltx_t *
@@ -1069,10 +1092,11 @@ ksocknal_send (nal_cb_t *nal, void *private, lib_msg_t *cookie,
         ltx->ltx_tx.tx_nob = sizeof (*hdr) + payload_len;
 
         rc = ksocknal_launch_packet (&ltx->ltx_tx, nid);
-        if (rc != PTL_OK)
-                ksocknal_put_ltx (ltx);
+        if (rc == 0)
+                return (PTL_OK);
         
-        return (rc);
+        ksocknal_put_ltx (ltx);
+        return (PTL_FAIL);
 }
 
 int
@@ -1104,10 +1128,11 @@ ksocknal_send_pages (nal_cb_t *nal, void *private, lib_msg_t *cookie,
         ltx->ltx_tx.tx_nob = sizeof (*hdr) + payload_len;
 
         rc = ksocknal_launch_packet (&ltx->ltx_tx, nid);
-        if (rc != PTL_OK) 
-                ksocknal_put_ltx (ltx);
-                
-        return (rc);
+        if (rc == 0)
+                return (PTL_OK);
+
+        ksocknal_put_ltx (ltx);
+        return (PTL_FAIL);
 }
 
 void
@@ -1133,10 +1158,8 @@ ksocknal_fwd_packet (void *arg, kpr_fwd_desc_t *fwd)
         tx->tx_hdr   = (ptl_hdr_t *)fwd->kprfd_iov[0].iov_base;
 
         rc = ksocknal_launch_packet (tx, nid);
-        if (rc != 0) {
-                /* FIXME, could pass a better completion error */
-                kpr_fwd_done (&ksocknal_data.ksnd_router, fwd, -EHOSTUNREACH);
-        }
+        if (rc != 0)
+                kpr_fwd_done (&ksocknal_data.ksnd_router, fwd, rc);
 }
 
 int
@@ -1353,38 +1376,43 @@ ksocknal_fwd_parse (ksock_conn_t *conn)
 {
         ksock_peer_t *peer;
         ptl_nid_t     dest_nid = NTOH__u64 (conn->ksnc_hdr.dest_nid);
-        int           body_len = NTOH__u32 (PTL_HDR_LENGTH(&conn->ksnc_hdr));
+        ptl_nid_t     src_nid = NTOH__u64 (conn->ksnc_hdr.src_nid);
+        int           body_len = NTOH__u32 (conn->ksnc_hdr.payload_length);
+        char str[PTL_NALFMT_SIZE];
 
         CDEBUG (D_NET, "%p "LPX64"->"LPX64" %d parsing header\n", conn,
-                NTOH__u64 (conn->ksnc_hdr.src_nid),
-                dest_nid, conn->ksnc_rx_nob_left);
+                src_nid, dest_nid, conn->ksnc_rx_nob_left);
 
         LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_HEADER);
         LASSERT (conn->ksnc_rx_scheduled);
 
         if (body_len < 0) {                 /* length corrupt (overflow) */
-                CERROR("dropping packet from "LPX64" for "LPX64": packet "
-                       "size %d illegal\n", NTOH__u64 (conn->ksnc_hdr.src_nid),
-                       dest_nid, body_len);
+                CERROR("dropping packet from "LPX64" (%s) for "LPX64" (%s): "
+                       "packet size %d illegal\n",
+                       src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                       dest_nid, portals_nid2str(TCPNAL, dest_nid, str),
+                       body_len);
 
                 ksocknal_new_packet (conn, 0);  /* on to new packet */
-                ksocknal_close_conn_unlocked (conn, -EINVAL); /* give up on conn */
                 return;
         }
 
         if (ksocknal_data.ksnd_fmbs == NULL) {        /* not forwarding */
-                CERROR("dropping packet from "LPX64" for "LPX64": not "
-                       "forwarding\n", conn->ksnc_hdr.src_nid,
-                       conn->ksnc_hdr.dest_nid);
+                CERROR("dropping packet from "LPX64" (%s) for "LPX64
+                       " (%s): not forwarding\n",
+                       src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                       dest_nid, portals_nid2str(TCPNAL, dest_nid, str));
                 /* on to new packet (skip this one's body) */
                 ksocknal_new_packet (conn, body_len);
                 return;
         }
 
-        if (body_len > SOCKNAL_MAX_FWD_PAYLOAD) {      /* too big to forward */
-                CERROR ("dropping packet from "LPX64" for "LPX64
-                        ": packet size %d too big\n", conn->ksnc_hdr.src_nid,
-                        conn->ksnc_hdr.dest_nid, body_len);
+        if (body_len > PTL_MTU) {      /* too big to forward */
+                CERROR ("dropping packet from "LPX64" (%s) for "LPX64
+                        "(%s): packet size %d too big\n",
+                        src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                        dest_nid, portals_nid2str(TCPNAL, dest_nid, str),
+                        body_len);
                 /* on to new packet (skip this one's body) */
                 ksocknal_new_packet (conn, body_len);
                 return;
@@ -1393,9 +1421,10 @@ ksocknal_fwd_parse (ksock_conn_t *conn)
         /* should have gone direct */
         peer = ksocknal_get_peer (conn->ksnc_hdr.dest_nid);
         if (peer != NULL) {
-                CERROR ("dropping packet from "LPX64" for "LPX64
-                        ": target is a peer\n", conn->ksnc_hdr.src_nid,
-                        conn->ksnc_hdr.dest_nid);
+                CERROR ("dropping packet from "LPX64" (%s) for "LPX64
+                        "(%s): target is a peer\n",
+                        src_nid, portals_nid2str(TCPNAL, src_nid, str),
+                        dest_nid, portals_nid2str(TCPNAL, dest_nid, str));
                 ksocknal_put_peer (peer);  /* drop ref from get above */
 
                 /* on to next packet (skip this one's body) */
@@ -1463,25 +1492,13 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
         return (0);
 }
 
-void
-ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
+int
+ksocknal_process_receive (ksock_conn_t *conn)
 {
-        ksock_conn_t *conn;
         ksock_fmb_t  *fmb;
         int           rc;
-
-        /* NB: sched->ksnc_lock lock held */
-
-        LASSERT (!list_empty (&sched->kss_rx_conns));
-        conn = list_entry(sched->kss_rx_conns.next, ksock_conn_t, ksnc_rx_list);
-        list_del (&conn->ksnc_rx_list);
-
-        spin_unlock_irqrestore (&sched->kss_lock, *irq_flags);
-
-        CDEBUG(D_NET, "sched %p conn %p\n", sched, conn);
+        
         LASSERT (atomic_read (&conn->ksnc_refcount) > 0);
-        LASSERT (conn->ksnc_rx_scheduled);
-        LASSERT (conn->ksnc_rx_ready);
 
         /* doesn't need a forwarding buffer */
         if (conn->ksnc_rx_state != SOCKNAL_RX_GET_FMB)
@@ -1489,13 +1506,15 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
  get_fmb:
         fmb = ksocknal_get_idle_fmb (conn);
-        if (fmb == NULL) {      /* conn descheduled waiting for idle fmb */
-                spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-                return;
+        if (fmb == NULL) {
+                /* conn descheduled waiting for idle fmb */
+                return (0);
         }
 
-        if (ksocknal_init_fmb (conn, fmb)) /* packet forwarded ? */
-                goto out;               /* come back later for next packet */
+        if (ksocknal_init_fmb (conn, fmb)) {
+                /* packet forwarded */
+                return (0);
+        }
 
  try_read:
         /* NB: sched lock NOT held */
@@ -1506,33 +1525,27 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
         LASSERT (conn->ksnc_rx_nob_wanted > 0);
 
-        conn->ksnc_rx_ready = 0;/* data ready may race with me and set ready */
-        mb();                   /* => clear BEFORE trying to read */
-
         rc = ksocknal_recvmsg(conn);
 
         if (rc <= 0) {
-                if (ksocknal_close_conn_unlocked (conn, rc)) {
-                        /* I'm the first to close */
-                        if (rc < 0)
-                                CERROR ("[%p] Error %d on read from "LPX64" ip %08x:%d\n",
-                                        conn, rc, conn->ksnc_peer->ksnp_nid,
-                                        conn->ksnc_ipaddr, conn->ksnc_port);
-                        else
-                                CWARN ("[%p] EOF from "LPX64" ip %08x:%d\n",
-                                       conn, conn->ksnc_peer->ksnp_nid,
-                                       conn->ksnc_ipaddr, conn->ksnc_port);
-                }
-                goto out;
+                if (rc == 0)
+                        CWARN ("[%p] EOF from "LPX64" ip %08x:%d\n",
+                               conn, conn->ksnc_peer->ksnp_nid,
+                               conn->ksnc_ipaddr, conn->ksnc_port);
+                else if (!conn->ksnc_closing)
+                        CERROR ("[%p] Error %d on read from "LPX64" ip %08x:%d\n",
+                                conn, rc, conn->ksnc_peer->ksnp_nid,
+                                conn->ksnc_ipaddr, conn->ksnc_port);
+
+                ksocknal_close_conn_and_siblings (conn, rc);
+                return (rc == 0 ? -ESHUTDOWN : rc);
         }
 
+        if (conn->ksnc_rx_nob_wanted != 0) {
+                /* short read */
+                return (-EAGAIN);
+        }
         
-        if (conn->ksnc_rx_nob_wanted != 0)      /* short read */
-                goto out;                       /* try again later */
-
-        /* got all I wanted, assume there's more - prevent data_ready locking */
-        conn->ksnc_rx_ready = 1;
-
         switch (conn->ksnc_rx_state) {
         case SOCKNAL_RX_HEADER:
                 if (conn->ksnc_hdr.type != HTON__u32(PTL_MSG_HELLO) &&
@@ -1541,7 +1554,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
                         ksocknal_fwd_parse (conn);
                         switch (conn->ksnc_rx_state) {
                         case SOCKNAL_RX_HEADER: /* skipped (zero payload) */
-                                goto out;       /* => come back later */
+                                return (0);     /* => come back later */
                         case SOCKNAL_RX_SLOP:   /* skipping packet's body */
                                 goto try_read;  /* => go read it */
                         case SOCKNAL_RX_GET_FMB: /* forwarding */
@@ -1569,7 +1582,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
         case SOCKNAL_RX_SLOP:
                 /* starting new packet? */
                 if (ksocknal_new_packet (conn, conn->ksnc_rx_nob_left))
-                        goto out;       /* come back later */
+                        return (0);     /* come back later */
                 goto try_read;          /* try to finish reading slop now */
 
         case SOCKNAL_RX_BODY_FWD:
@@ -1588,7 +1601,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
                 LASSERT (conn->ksnc_rx_nob_left == 0);
 
                 ksocknal_new_packet (conn, 0);  /* on to next packet */
-                goto out;                       /* (later) */
+                return (0);                     /* (later) */
 
         default:
                 break;
@@ -1596,20 +1609,7 @@ ksocknal_process_receive (ksock_sched_t *sched, unsigned long *irq_flags)
 
         /* Not Reached */
         LBUG ();
-
- out:
-        spin_lock_irqsave (&sched->kss_lock, *irq_flags);
-
-        /* no data there to read? */
-        if (!conn->ksnc_rx_ready) {
-                /* let socket callback schedule again */
-                conn->ksnc_rx_scheduled = 0;
-                /* drop scheduler's ref */
-                ksocknal_put_conn (conn);   
-        } else {
-                /* stay scheduled */
-                list_add_tail (&conn->ksnc_rx_list, &sched->kss_rx_conns);
-        }
+        return (-EINVAL);                       /* keep gcc happy */
 }
 
 int
@@ -1667,6 +1667,8 @@ ksocknal_recv_pages (nal_cb_t *nal, void *private, lib_msg_t *msg,
 int ksocknal_scheduler (void *arg)
 {
         ksock_sched_t     *sched = (ksock_sched_t *)arg;
+        ksock_conn_t      *conn;
+        ksock_tx_t        *tx;
         unsigned long      flags;
         int                rc;
         int                nloops = 0;
@@ -1677,6 +1679,8 @@ int ksocknal_scheduler (void *arg)
         kportal_daemonize (name);
         kportal_blockallsigs ();
 
+        current->flags |= PF_MEMALLOC;
+
 #if (CONFIG_SMP && CPU_AFFINITY)
         if ((cpu_online_map & (1 << id)) != 0) {
 #if 1
@@ -1697,15 +1701,96 @@ int ksocknal_scheduler (void *arg)
                 /* Ensure I progress everything semi-fairly */
 
                 if (!list_empty (&sched->kss_rx_conns)) {
+                        conn = list_entry(sched->kss_rx_conns.next,
+                                          ksock_conn_t, ksnc_rx_list);
+                        list_del(&conn->ksnc_rx_list);
+
+                        LASSERT(conn->ksnc_rx_scheduled);
+                        LASSERT(conn->ksnc_rx_ready);
+
+                        /* clear rx_ready in case receive isn't complete.
+                         * Do it BEFORE we call process_recv, since
+                         * data_ready can set it any time after we release
+                         * kss_lock. */
+                        conn->ksnc_rx_ready = 0;
+                        spin_unlock_irqrestore(&sched->kss_lock, flags);
+                        
+                        rc = ksocknal_process_receive(conn);
+                        
+                        spin_lock_irqsave(&sched->kss_lock, flags);
+
+                        /* I'm the only one that can clear this flag */
+                        LASSERT(conn->ksnc_rx_scheduled);
+
+                        /* Did process_receive get everything it wanted? */
+                        if (rc == 0)
+                                conn->ksnc_rx_ready = 1;
+                        
+                        if (conn->ksnc_rx_state == SOCKNAL_RX_FMB_SLEEP ||
+                            conn->ksnc_rx_state == SOCKNAL_RX_GET_FMB) {
+                                /* Conn blocked for a forwarding buffer.
+                                 * It will get queued for my attention when
+                                 * one becomes available (and it might just
+                                 * already have been!).  Meanwhile my ref
+                                 * on it stays put. */
+                        } else if (conn->ksnc_rx_ready) {
+                                /* reschedule for rx */
+                                list_add_tail (&conn->ksnc_rx_list,
+                                               &sched->kss_rx_conns);
+                        } else {
+                                conn->ksnc_rx_scheduled = 0;
+                                /* drop my ref */
+                                ksocknal_put_conn(conn);
+                        }
+
                         did_something = 1;
-                        /* drops & regains kss_lock */
-                        ksocknal_process_receive (sched, &flags);
                 }
 
                 if (!list_empty (&sched->kss_tx_conns)) {
+                        conn = list_entry(sched->kss_tx_conns.next,
+                                          ksock_conn_t, ksnc_tx_list);
+                        list_del (&conn->ksnc_tx_list);
+                        
+                        LASSERT(conn->ksnc_tx_scheduled);
+                        LASSERT(conn->ksnc_tx_ready);
+                        LASSERT(!list_empty(&conn->ksnc_tx_queue));
+                        
+                        tx = list_entry(conn->ksnc_tx_queue.next,
+                                        ksock_tx_t, tx_list);
+                        /* dequeue now so empty list => more to send */
+                        list_del(&tx->tx_list);
+                        
+                        /* Clear tx_ready in case send isn't complete.  Do
+                         * it BEFORE we call process_transmit, since
+                         * write_space can set it any time after we release
+                         * kss_lock. */
+                        conn->ksnc_tx_ready = 0;
+                        spin_unlock_irqrestore (&sched->kss_lock, flags);
+                        
+                        rc = ksocknal_process_transmit(conn, tx);
+                        
+                        spin_lock_irqsave (&sched->kss_lock, flags);
+
+                        if (rc != -EAGAIN) {
+                                /* error or everything went: assume more can go */
+                                conn->ksnc_tx_ready = 1;
+                        } else {
+                                 /* back onto HEAD of tx_queue */
+                                list_add (&tx->tx_list, &conn->ksnc_tx_queue);
+                        }
+                        
+                        if (conn->ksnc_tx_ready &&
+                            !list_empty (&conn->ksnc_tx_queue)) {
+                                /* reschedule for tx */
+                                list_add_tail (&conn->ksnc_tx_list, 
+                                               &sched->kss_tx_conns);
+                        } else {
+                                conn->ksnc_tx_scheduled = 0;
+                                /* drop my ref */
+                                ksocknal_put_conn (conn);
+                        }
+                                
                         did_something = 1;
-                        /* drops and regains kss_lock */
-                        ksocknal_process_transmit (sched, &flags);
                 }
 #if SOCKNAL_ZC
                 if (!list_empty (&sched->kss_zctxdone_list)) {
@@ -1769,18 +1854,11 @@ ksocknal_data_ready (struct sock *sk, int n)
         if (conn == NULL) {             /* raced with ksocknal_close_sock */
                 LASSERT (sk->sk_data_ready != &ksocknal_data_ready);
                 sk->sk_data_ready (sk, n);
-                goto out;
-        }
-
-        if (!conn->ksnc_rx_ready) {        /* new news */
-                /* Set ASAP in case of concurrent calls to me */
-                conn->ksnc_rx_ready = 1;
-
+        } else {
                 sched = conn->ksnc_scheduler;
 
                 spin_lock_irqsave (&sched->kss_lock, flags);
 
-                /* Set again (process_receive may have cleared while I blocked for the lock) */
                 conn->ksnc_rx_ready = 1;
 
                 if (!conn->ksnc_rx_scheduled) {  /* not being progressed */
@@ -1796,7 +1874,6 @@ ksocknal_data_ready (struct sock *sk, int n)
                 spin_unlock_irqrestore (&sched->kss_lock, flags);
         }
 
- out:
         read_unlock (&ksocknal_data.ksnd_global_lock);
 
         EXIT;
@@ -1834,31 +1911,24 @@ ksocknal_write_space (struct sock *sk)
         if (tcp_wspace(sk) >= SOCKNAL_TX_LOW_WATER(sk)) { /* got enough space */
                 clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);
 
-                if (!conn->ksnc_tx_ready) {      /* new news */
-                        /* Set ASAP in case of concurrent calls to me */
-                        conn->ksnc_tx_ready = 1;
-
-                        sched = conn->ksnc_scheduler;
-
-                        spin_lock_irqsave (&sched->kss_lock, flags);
+                sched = conn->ksnc_scheduler;
 
-                        /* Set again (process_transmit may have
-                           cleared while I blocked for the lock) */
-                        conn->ksnc_tx_ready = 1;
+                spin_lock_irqsave (&sched->kss_lock, flags);
 
-                        if (!conn->ksnc_tx_scheduled && // not being progressed
-                            !list_empty(&conn->ksnc_tx_queue)){//packets to send
-                                list_add_tail (&conn->ksnc_tx_list,
-                                               &sched->kss_tx_conns);
-                                conn->ksnc_tx_scheduled = 1;
-                                /* extra ref for scheduler */
-                                atomic_inc (&conn->ksnc_refcount);
+                conn->ksnc_tx_ready = 1;
 
-                                wake_up (&sched->kss_waitq);
-                        }
+                if (!conn->ksnc_tx_scheduled && // not being progressed
+                    !list_empty(&conn->ksnc_tx_queue)){//packets to send
+                        list_add_tail (&conn->ksnc_tx_list,
+                                       &sched->kss_tx_conns);
+                        conn->ksnc_tx_scheduled = 1;
+                        /* extra ref for scheduler */
+                        atomic_inc (&conn->ksnc_refcount);
 
-                        spin_unlock_irqrestore (&sched->kss_lock, flags);
+                        wake_up (&sched->kss_waitq);
                 }
+
+                spin_unlock_irqrestore (&sched->kss_lock, flags);
         }
 
         read_unlock (&ksocknal_data.ksnd_global_lock);
@@ -1943,7 +2013,7 @@ ksocknal_sock_read (struct socket *sock, void *buffer, int nob)
 }
 
 int
-ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
+ksocknal_hello (struct socket *sock, ptl_nid_t *nid, int *type, __u64 *incarnation)
 {
         int                 rc;
         ptl_hdr_t           hdr;
@@ -1958,24 +2028,28 @@ ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
         
         hdr.src_nid = __cpu_to_le64 (ksocknal_lib.ni.nid);
         hdr.type    = __cpu_to_le32 (PTL_MSG_HELLO);
-        
+
+        hdr.msg.hello.type = __cpu_to_le32 (*type);
+        hdr.msg.hello.incarnation = 
+                __cpu_to_le64 (ksocknal_data.ksnd_incarnation);
+
         /* Assume sufficient socket buffering for this message */
         rc = ksocknal_sock_write (sock, &hdr, sizeof (hdr));
         if (rc != 0) {
-                CERROR ("Error %d sending HELLO to "LPX64"\n", rc, nid);
+                CERROR ("Error %d sending HELLO to "LPX64"\n", rc, *nid);
                 return (rc);
         }
 
         rc = ksocknal_sock_read (sock, hmv, sizeof (*hmv));
         if (rc != 0) {
-                CERROR ("Error %d reading HELLO from "LPX64"\n", rc, nid);
+                CERROR ("Error %d reading HELLO from "LPX64"\n", rc, *nid);
                 return (rc);
         }
         
         if (hmv->magic != __le32_to_cpu (PORTALS_PROTO_MAGIC)) {
                 CERROR ("Bad magic %#08x (%#08x expected) from "LPX64"\n",
-                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, nid);
-                return (-EINVAL);
+                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, *nid);
+                return (-EPROTO);
         }
 
         if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
@@ -1986,63 +2060,99 @@ ksocknal_exchange_nids (struct socket *sock, ptl_nid_t nid)
                         __le16_to_cpu (hmv->version_minor),
                         PORTALS_PROTO_VERSION_MAJOR,
                         PORTALS_PROTO_VERSION_MINOR,
-                        nid);
-                return (-EINVAL);
+                        *nid);
+                return (-EPROTO);
         }
 
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
+#if (PORTALS_PROTO_VERSION_MAJOR != 0)
+# error "This code only understands protocol version 0.x"
+#endif
         /* version 0 sends magic/version as the dest_nid of a 'hello' header,
          * so read the rest of it in now... */
 
         rc = ksocknal_sock_read (sock, hmv + 1, sizeof (hdr) - sizeof (*hmv));
         if (rc != 0) {
                 CERROR ("Error %d reading rest of HELLO hdr from "LPX64"\n",
-                        rc, nid);
+                        rc, *nid);
                 return (rc);
         }
 
         /* ...and check we got what we expected */
         if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
-            PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
+            hdr.payload_length != __cpu_to_le32 (0)) {
                 CERROR ("Expecting a HELLO hdr with 0 payload,"
                         " but got type %d with %d payload from "LPX64"\n",
                         __le32_to_cpu (hdr.type),
-                        __le32_to_cpu (PTL_HDR_LENGTH (&hdr)), nid);
-                return (-EINVAL);
+                        __le32_to_cpu (hdr.payload_length), *nid);
+                return (-EPROTO);
         }
-        
-        if (__le64_to_cpu (hdr.src_nid) != nid) {
+
+        if (__le64_to_cpu(hdr.src_nid) == PTL_NID_ANY) {
+                CERROR("Expecting a HELLO hdr with a NID, but got PTL_NID_ANY\n");
+                return (-EPROTO);
+        }
+
+        if (*nid == PTL_NID_ANY) {              /* don't know peer's nid yet */
+                *nid = __le64_to_cpu(hdr.src_nid);
+        } else if (*nid != __le64_to_cpu (hdr.src_nid)) {
                 CERROR ("Connected to nid "LPX64", but expecting "LPX64"\n",
-                        __le64_to_cpu (hdr.src_nid), nid);
-                return (-EINVAL);
+                        __le64_to_cpu (hdr.src_nid), *nid);
+                return (-EPROTO);
+        }
+
+        if (*type == SOCKNAL_CONN_NONE) {
+                /* I've accepted this connection; peer determines type */
+                *type = __le32_to_cpu(hdr.msg.hello.type);
+                switch (*type) {
+                case SOCKNAL_CONN_ANY:
+                case SOCKNAL_CONN_CONTROL:
+                        break;
+                case SOCKNAL_CONN_BULK_IN:
+                        *type = SOCKNAL_CONN_BULK_OUT;
+                        break;
+                case SOCKNAL_CONN_BULK_OUT:
+                        *type = SOCKNAL_CONN_BULK_IN;
+                        break;
+                default:
+                        CERROR ("Unexpected type %d from "LPX64"\n", *type, *nid);
+                        return (-EPROTO);
+                }
+        } else if (__le32_to_cpu(hdr.msg.hello.type) != SOCKNAL_CONN_NONE) {
+                CERROR ("Mismatched types: me %d "LPX64" %d\n",
+                        *type, *nid, __le32_to_cpu(hdr.msg.hello.type));
+                return (-EPROTO);
         }
 
+        *incarnation = __le64_to_cpu(hdr.msg.hello.incarnation);
+
         return (0);
 }
 
 int
-ksocknal_setup_sock (struct socket *sock) 
+ksocknal_setup_sock (struct socket *sock)
 {
         mm_segment_t    oldmm = get_fs ();
         int             rc;
         int             option;
         struct linger   linger;
 
+        sock->sk->allocation = GFP_NOFS;
+
         /* Ensure this socket aborts active sends immediately when we close
          * it. */
-        
+
         linger.l_onoff = 0;
         linger.l_linger = 0;
 
         set_fs (KERNEL_DS);
-        rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER, 
+        rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,
                               (char *)&linger, sizeof (linger));
         set_fs (oldmm);
         if (rc != 0) {
                 CERROR ("Can't set SO_LINGER: %d\n", rc);
                 return (rc);
         }
-        
+
         option = -1;
         set_fs (KERNEL_DS);
         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,
@@ -2101,7 +2211,7 @@ ksocknal_setup_sock (struct socket *sock)
 }
 
 int
-ksocknal_connect_peer (ksock_route_t *route)
+ksocknal_connect_peer (ksock_route_t *route, int type)
 {
         struct sockaddr_in  peer_addr;
         mm_segment_t        oldmm = get_fs();
@@ -2206,14 +2316,7 @@ ksocknal_connect_peer (ksock_route_t *route)
                 goto out;
         }
         
-        if (route->ksnr_xchange_nids) {
-                rc = ksocknal_exchange_nids (sock, route->ksnr_peer->ksnp_nid);
-                if (rc != 0)
-                        goto out;
-        }
-
-        rc = ksocknal_create_conn (route->ksnr_peer->ksnp_nid,
-                                   route, sock, route->ksnr_irq_affinity);
+        rc = ksocknal_create_conn (route, sock, route->ksnr_irq_affinity, type);
         if (rc == 0) {
                 /* Take an extra ref on sock->file to compensate for the
                  * upcoming close which will lose fd's ref on it. */
@@ -2233,20 +2336,36 @@ ksocknal_autoconnect (ksock_route_t *route)
         ksock_peer_t     *peer;
         unsigned long     flags;
         int               rc;
+        int               type;
         
-        rc = ksocknal_connect_peer (route);
-        if (rc == 0) {
+        for (;;) {
+                for (type = 0; type < SOCKNAL_CONN_NTYPES; type++)
+                        if ((route->ksnr_connecting & (1 << type)) != 0)
+                                break;
+                LASSERT (type < SOCKNAL_CONN_NTYPES);
+
+                rc = ksocknal_connect_peer (route, type);
+
+                if (rc != 0)
+                        break;
+                
                 /* successfully autoconnected: create_conn did the
-                 * route/conn binding and scheduled any blocked packets, 
-                 * so there's nothing left to do now. */
-                return;
+                 * route/conn binding and scheduled any blocked packets */
+
+                if (route->ksnr_connecting == 0) {
+                        /* No more connections required */
+                        return;
+                }
         }
 
+        /* Connection attempt failed */
+
         write_lock_irqsave (&ksocknal_data.ksnd_global_lock, flags);
 
         peer = route->ksnr_peer;
         route->ksnr_connecting = 0;
 
+        /* This is a retry rather than a new connection */
         LASSERT (route->ksnr_retry_interval != 0);
         route->ksnr_timeout = jiffies + route->ksnr_retry_interval;
         route->ksnr_retry_interval = MIN (route->ksnr_retry_interval * 2,
@@ -2266,6 +2385,12 @@ ksocknal_autoconnect (ksock_route_t *route)
                 } while (!list_empty (&peer->ksnp_tx_queue));
         }
 
+        /* make this route least-favourite for re-selection */
+        if (!route->ksnr_deleted) {
+                list_del(&route->ksnr_list);
+                list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
+        }
+        
         write_unlock_irqrestore (&ksocknal_data.ksnd_global_lock, flags);
 
         while (!list_empty (&zombies)) {
@@ -2273,7 +2398,7 @@ ksocknal_autoconnect (ksock_route_t *route)
                 
                 CERROR ("Deleting packet type %d len %d ("LPX64"->"LPX64")\n",
                         NTOH__u32 (tx->tx_hdr->type),
-                        NTOH__u32 (PTL_HDR_LENGTH(tx->tx_hdr)),
+                        NTOH__u32 (tx->tx_hdr->payload_length),
                         NTOH__u64 (tx->tx_hdr->src_nid),
                         NTOH__u64 (tx->tx_hdr->dest_nid));
 
@@ -2354,7 +2479,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
                 }
                 
                 if ((!list_empty (&conn->ksnc_tx_queue) ||
-                     conn->ksnc_sock->sk->wmem_queued != 0) &&
+                     conn->ksnc_sock->sk->sk_wmem_queued != 0) &&
                     time_after_eq (jiffies, conn->ksnc_tx_deadline)) {
                         /* Timed out messages queued for sending, or
                          * messages buffered in the socket's send buffer */
@@ -2362,7 +2487,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
                         CERROR ("Timed out TX to "LPX64" %s%d %p\n", 
                                 peer->ksnp_nid, 
                                 list_empty (&conn->ksnc_tx_queue) ? "" : "Q ",
-                                conn->ksnc_sock->sk->wmem_queued, conn);
+                                conn->ksnc_sock->sk->sk_wmem_queued, conn);
                         return (conn);
                 }
         }
@@ -2391,13 +2516,11 @@ ksocknal_check_peer_timeouts (int idx)
                 if (conn != NULL) {
                         read_unlock (&ksocknal_data.ksnd_global_lock);
 
-                        if (ksocknal_close_conn_unlocked (conn, -ETIMEDOUT)) {
-                                /* I actually closed... */
-                                CERROR ("Timeout out conn->"LPX64" ip %x:%d\n",
-                                        peer->ksnp_nid, conn->ksnc_ipaddr,
-                                        conn->ksnc_port);
-                        }
-                
+                        CERROR ("Timeout out conn->"LPX64" ip %x:%d\n",
+                                peer->ksnp_nid, conn->ksnc_ipaddr,
+                                conn->ksnc_port);
+                        ksocknal_close_conn_and_siblings (conn, -ETIMEDOUT);
+                        
                         /* NB we won't find this one again, but we can't
                          * just proceed with the next peer, since we dropped
                          * ksnd_global_lock and it might be dead already! */
diff --git a/lustre/portals/knals/toenal/toenal.c b/lustre/portals/knals/toenal/toenal.c
index 77ee47393ebc660f9ba4a3716bf9380885decc27..07b93cbf8041d6d665bf7ac003a9f956de9c37d9 100644
--- a/lustre/portals/knals/toenal/toenal.c
+++ b/lustre/portals/knals/toenal/toenal.c
@@ -210,7 +210,7 @@ error:
 int
 ktoenal_close_sock(ptl_nid_t nid)
 {
-        long               flags;
+        unsigned long     flags;
         ksock_conn_t      *conn;
         LIST_HEAD         (death_row);
         struct list_head  *tmp;
@@ -354,23 +354,23 @@ ktoenal_free_buffers (void)
 }
 
 int
-ktoenal_cmd(struct portal_ioctl_data * data, void * private)
+ktoenal_cmd(struct portals_cfg *pcfg, void * private)
 {
         int rc = -EINVAL;
 
-        LASSERT (data != NULL);
+        LASSERT (pcfg != NULL);
 
-        switch(data->ioc_nal_cmd) {
+        switch(pcfg->pcfg_command) {
         case NAL_CMD_REGISTER_PEER_FD: {
-                rc = ktoenal_add_sock(data->ioc_nid, data->ioc_fd);
+                rc = ktoenal_add_sock(pcfg->pcfg_nid, pcfg->pcfg_fd);
                 break;
         }
         case NAL_CMD_CLOSE_CONNECTION: {
-                rc = ktoenal_close_sock(data->ioc_nid);
+                rc = ktoenal_close_sock(pcfg->pcfg_nid);
                 break;
         }
         case NAL_CMD_REGISTER_MYNID: {
-                rc = ktoenal_set_mynid (data->ioc_nid);
+                rc = ktoenal_set_mynid (pcfg->pcfg_nid);
                 break;
         }
         }
@@ -438,7 +438,7 @@ ktoenal_module_fini (void)
         CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
                atomic_read (&portal_kmemory));
 
-        printk(KERN_INFO "Routing socket NAL unloaded (final mem %d)\n",
+        printk(KERN_INFO "Lustre: Routing socket NAL unloaded (final mem %d)\n",
                atomic_read(&portal_kmemory));
 }
 
@@ -612,7 +612,7 @@ ktoenal_module_init (void)
         /* flag everything initialised */
         ktoenal_data.ksnd_init = SOCKNAL_INIT_ALL;
 
-	printk(KERN_INFO"Routing TOE NAL loaded (Routing %s, initial mem %d)\n",
+	printk(KERN_INFO "Lustre: Routing TOE NAL loaded (Routing %s, initial mem %d)\n",
 	       kpr_routing(&ktoenal_data.ksnd_router) ? "enabled" : "disabled",
                pkmem);
 
diff --git a/lustre/portals/knals/toenal/toenal.h b/lustre/portals/knals/toenal/toenal.h
index f793d3b4b6b400085e9bb132664d85b7e54f2cbe..b211d6c6006c8f46f6b3cec0da78440a5d0c5213 100644
--- a/lustre/portals/knals/toenal/toenal.h
+++ b/lustre/portals/knals/toenal/toenal.h
@@ -27,7 +27,9 @@
  */
 
 #define DEBUG_PORTAL_ALLOC
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -58,8 +60,6 @@
 #include <portals/p30.h>
 #include <portals/lib-p30.h>
 
-#define SOCKNAL_MAX_FWD_PAYLOAD (64<<10)        /* biggest payload I can forward */
-
 #define SOCKNAL_NLTXS           128             /* # normal transmit messages */
 #define SOCKNAL_NNBLK_LTXS	128             /* # transmit messages reserved if can't block */
 
@@ -68,7 +68,7 @@
 
 #define SOCKNAL_SMALL_FWD_PAGES	1               /* # pages in a small message fwd buffer */
 
-#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + SOCKNAL_MAX_FWD_PAYLOAD) >> PAGE_SHIFT)
+#define SOCKNAL_LARGE_FWD_PAGES (PAGE_ALIGN (sizeof (ptl_hdr_t) + PTL_MTU) >> PAGE_SHIFT)
 						/* # pages in a large message fwd buffer */
 
 #define SOCKNAL_RESCHED         100             /* # scheduler loops before reschedule */
diff --git a/lustre/portals/knals/toenal/toenal_cb.c b/lustre/portals/knals/toenal/toenal_cb.c
index 478f3c1387ed7687adaa710a45b99a960ab42ad3..3af9e3318a5fcc954af472020521986a8630af51 100644
--- a/lustre/portals/knals/toenal/toenal_cb.c
+++ b/lustre/portals/knals/toenal/toenal_cb.c
@@ -140,7 +140,7 @@ ktoenal_dist(nal_cb_t *nal, ptl_nid_t nid, unsigned long *dist)
 ksock_ltx_t *
 ktoenal_get_ltx (int may_block)
 {
-        long	     flags;
+        unsigned long   flags;
         ksock_ltx_t *ltx = NULL;
         
         for (;;)
@@ -268,7 +268,7 @@ ktoenal_recvmsg(struct file *sock, struct iovec *iov, int niov, int toread)
 }
 
 void
-ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
+ktoenal_process_transmit (ksock_conn_t *conn, unsigned long *irq_flags)
 {
         ksock_tx_t *tx = list_entry (conn->ksnc_tx_queue.next, ksock_tx_t, tx_list);
         int         rc;
@@ -300,7 +300,7 @@ ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
                         rc = 0;                 /* nothing sent */
                 else
                 {
-#warning FIXME: handle socket errors properly
+                        //warning FIXME: handle socket errors properly
                         CERROR ("Error socknal send(%d) %p: %d\n", tx->tx_nob, conn, rc);
                         rc = tx->tx_nob;        /* kid on for now whole packet went */
                 }
@@ -358,7 +358,7 @@ ktoenal_process_transmit (ksock_conn_t *conn, long *irq_flags)
 void
 ktoenal_launch_packet (ksock_conn_t *conn, ksock_tx_t *tx)
 {
-        long          flags;
+        unsigned long flags;
         int           nob = tx->tx_nob;
         struct iovec *iov = tx->tx_iov;
         int           niov = 1;
@@ -371,7 +371,6 @@ ktoenal_launch_packet (ksock_conn_t *conn, ksock_tx_t *tx)
         for (;;)
         {
                 LASSERT (niov <= tx->tx_niov);
-                LASSERT (iov->iov_len >= 0);
                 
                 if (iov->iov_len >= nob)
                 {
@@ -542,7 +541,7 @@ ktoenal_fmb_callback (void *arg, int error)
         ksock_fmb_t       *fmb = (ksock_fmb_t *)arg;
         ptl_hdr_t         *hdr = (ptl_hdr_t *) page_address(fmb->fmb_pages[0]);
         ksock_conn_t      *conn;
-        long               flags;
+        unsigned long     flags;
 
         CDEBUG (D_NET, "routed packet from "LPX64" to "LPX64": %d\n", 
                 hdr->src_nid, hdr->dest_nid, error);
@@ -709,26 +708,7 @@ ktoenal_fwd_parse (ksock_conn_t *conn)
         LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_HEADER);
         LASSERT (conn->ksnc_rx_scheduled);
 
-        switch (conn->ksnc_hdr.type)
-        {
-        case PTL_MSG_GET:
-        case PTL_MSG_ACK:
-                body_len = 0;
-                break;
-        case PTL_MSG_PUT:
-                body_len = conn->ksnc_hdr.msg.put.length;
-                break;
-        case PTL_MSG_REPLY:
-                body_len = conn->ksnc_hdr.msg.reply.length;
-                break;
-        default:
-                /* Unrecognised packet type */
-                CERROR ("Unrecognised packet type %d from "LPX64" for "LPX64"\n",
-                        conn->ksnc_hdr.type, conn->ksnc_hdr.src_nid, conn->ksnc_hdr.dest_nid);
-                /* Ignore this header and go back to reading a new packet. */
-                ktoenal_new_packet (conn, 0);
-                return;
-        }
+        body_len = conn->ksnc_hdr.payload_length;
 
         if (body_len < 0)                               /* length corrupt */
         {
@@ -738,7 +718,7 @@ ktoenal_fwd_parse (ksock_conn_t *conn)
                 return;
         }
 
-        if (body_len > SOCKNAL_MAX_FWD_PAYLOAD)         /* too big to forward */
+        if (body_len > PTL_MTU)         /* too big to forward */
         {
                 CERROR ("dropping packet from "LPX64" for "LPX64": packet size %d too big\n",
                         conn->ksnc_hdr.src_nid, conn->ksnc_hdr.dest_nid, body_len);
@@ -810,7 +790,7 @@ ktoenal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 }
 
 void
-ktoenal_process_receive (ksock_conn_t *conn, long *irq_flags)
+ktoenal_process_receive (ksock_conn_t *conn, unsigned long *irq_flags)
 {
         ksock_fmb_t *fmb;
         int          len;
@@ -862,7 +842,7 @@ ktoenal_process_receive (ksock_conn_t *conn, long *irq_flags)
                 if (len != -EAGAIN &&           /* ! nothing to read now */
                     len != 0)                   /* ! nothing to read ever */
                 {
-#warning FIXME: handle socket errors properly
+                        // warning FIXME: handle socket errors properly
                         CERROR ("Error socknal read(%d) %p: %d\n",
                                 conn->ksnc_rx_nob_wanted, conn, len);
                 }
diff --git a/lustre/portals/libcfs/Makefile.mk b/lustre/portals/libcfs/Makefile.mk
index 9aa838f92c571f5ebf45e0b51351242adf526b68..c2014296df33b9bdaab54dd2c6bb58d4acc63486 100644
--- a/lustre/portals/libcfs/Makefile.mk
+++ b/lustre/portals/libcfs/Makefile.mk
@@ -6,4 +6,4 @@
 include fs/lustre/portals/Kernelenv
 
 obj-y += libcfs.o
-libcfs-objs    := module.o proc.o debug.o
+libcfs-objs    := module.o proc.o debug.o lwt.o
diff --git a/lustre/portals/libcfs/debug.c b/lustre/portals/libcfs/debug.c
index 90eb185da7243cced18e3d1186c889e0475f7340..6e2c1ca1d606ba0427db783829706162a46e636b 100644
--- a/lustre/portals/libcfs/debug.c
+++ b/lustre/portals/libcfs/debug.c
@@ -20,14 +20,15 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/notifier.h>
 #include <linux/kernel.h>
-#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/stat.h>
@@ -48,6 +49,7 @@
 # define DEBUG_SUBSYSTEM S_PORTALS
 
 #include <linux/kp30.h>
+#include <linux/portals_compat25.h>
 
 #define DEBUG_OVERFLOW 1024
 static char *debug_buf = NULL;
@@ -233,15 +235,15 @@ int portals_do_debug_dumplog(void *arg)
         reparent_to_init();
         journal_info = current->journal_info;
         current->journal_info = NULL;
-        sprintf(debug_file_name, "%s.%ld", debug_file_path, CURRENT_TIME);
-        file = filp_open(debug_file_name, O_CREAT|O_TRUNC|O_RDWR, 0644);
+        sprintf(debug_file_name, "%s.%ld", debug_file_path, CURRENT_SECONDS);
+        file = filp_open(debug_file_name, O_CREAT|O_EXCL|O_RDWR, 0644);
 
         if (!file || IS_ERR(file)) {
                 CERROR("cannot open %s for dumping: %ld\n", debug_file_name,
                        PTR_ERR(file));
                 GOTO(out, PTR_ERR(file));
         } else {
-                printk(KERN_ALERT "dumping log to %s ... writing ...\n",
+                printk(KERN_ALERT "LustreError: dumping log to %s ... writing ...\n",
                        debug_file_name);
         }
 
@@ -256,7 +258,7 @@ int portals_do_debug_dumplog(void *arg)
         } else {
                 rc = file->f_op->write(file, debug_buf, debug_off,&file->f_pos);
         }
-        printk("wrote %d bytes\n", rc);
+        printk("LustreError: wrote %d bytes\n", rc);
         set_fs(oldfs);
 
         rc = file->f_op->fsync(file, file->f_dentry, 1);
@@ -289,10 +291,8 @@ int portals_debug_daemon(void *arg)
         if (!file || IS_ERR(file)) {
                 CERROR("cannot open %s for logging", debug_daemon_file_path);
                 GOTO(out1, PTR_ERR(file));
-        } else {
-                printk(KERN_ALERT "daemon dumping log to %s ... writing ...\n",
-                       debug_daemon_file_path);
         }
+        printk(KERN_INFO "daemon dumping log to %s\n", debug_daemon_file_path);
 
         debug_daemon_state.overlapped = 0;
         debug_daemon_state.stopped = 0;
@@ -336,8 +336,8 @@ int portals_debug_daemon(void *arg)
                         rc = file->f_op->write(file, debug_buf+start,
                                                size, &file->f_pos);
                         if (rc < 0) {
-                                printk(KERN_ALERT
-                                           "Debug_daemon write error %d\n", rc);
+                                printk(KERN_ALERT "LustreError: Debug_daemon "
+                                       "write error %d\n", rc);
                                 goto out;
                         }
                         start += rc;
@@ -358,16 +358,16 @@ int portals_debug_daemon(void *arg)
                 if (force_flush) {
                         rc = file->f_op->fsync(file, file->f_dentry, 1);
                         if (rc < 0) {
-                                printk(KERN_ALERT
-                                       "Debug_daemon sync error %d\n", rc);
+                                printk(KERN_ALERT "LustreError: Debug_daemon "
+                                       "sync error %d\n", rc);
                                 goto out;
                         }
                         if (debug_daemon_state.stopped)
-                               break;           
+                               break;
                         debug_daemon_state.lctl_event = 1;
                         wake_up(&debug_daemon_state.lctl);
                 }
-                wait_event(debug_daemon_state.daemon, 
+                wait_event(debug_daemon_state.daemon,
                            debug_daemon_state.daemon_event);
                 }
 out:
@@ -403,12 +403,12 @@ void portals_debug_print(void)
 
         while (start1 < end1) {
                 int count = MIN(1024, end1 - start1);
-                printk("%*s", count, start1);
+                printk("LustreError: %*s", count, start1);
                 start1 += 1024;
         }
         while (start2 < end2) {
                 int count = MIN(1024, end2 - start2);
-                printk("%*s", count, start2);
+                printk("LustreError: %*s", count, start2);
                 start2 += 1024;
         }
 }
@@ -423,7 +423,7 @@ void portals_debug_dumplog(void)
         rc = kernel_thread(portals_do_debug_dumplog,
                            NULL, CLONE_VM | CLONE_FS | CLONE_FILES);
         if (rc < 0) {
-                printk(KERN_ERR "cannot start dump thread\n");
+                printk(KERN_ERR "LustreError: cannot start dump thread\n");
                 return;
         }
         sleep_on(&debug_ctlwq);
@@ -447,7 +447,7 @@ int portals_debug_daemon_start(char *file, unsigned int size)
         debug_daemon_state.lctl_event = 0;
         rc = kernel_thread(portals_debug_daemon, NULL, 0);
         if (rc < 0) {
-                printk(KERN_ERR "cannot start debug daemon thread\n");
+                printk(KERN_ERR "LustreError: cannot start debug daemon thread\n");
                 strncpy(debug_daemon_file_path, "\0", 1);
                 return rc;
         }
@@ -633,7 +633,7 @@ int portals_debug_mark_buffer(char *text)
                 return -EINVAL;
 
         CDEBUG(0, "********************************************************\n");
-        CDEBUG(0, "DEBUG MARKER: %s\n", text);
+        CWARN("DEBUG MARKER: %s\n", text);
         CDEBUG(0, "********************************************************\n");
 
         return 0;
@@ -641,39 +641,107 @@ int portals_debug_mark_buffer(char *text)
 #undef DEBUG_SUBSYSTEM
 #define DEBUG_SUBSYSTEM S_PORTALS
 
+/* this copies a snapshot of the debug buffer into an array of pages
+ * before doing the potentially blocking copy into userspace. it could
+ * be warning userspace if things wrap heavily while its off copying. */
 __s32 portals_debug_copy_to_user(char *buf, unsigned long len)
 {
         int rc;
-        unsigned long debug_off;
+        unsigned long total, debug_off, i, off, copied;
         unsigned long flags;
+        struct page *page;
+        LIST_HEAD(my_pages);
+        struct list_head *pos, *n;
 
         if (len < debug_size)
                 return -ENOSPC;
 
-        debug_off = atomic_read(&debug_off_a);
+        for (i = 0 ; i < debug_size; i += PAGE_SIZE) {
+                page = alloc_page(GFP_NOFS);
+                if (page == NULL) {
+                        rc = -ENOMEM;
+                        goto cleanup;
+                }
+                list_add(&page->list, &my_pages);
+        }
+
         spin_lock_irqsave(&portals_debug_lock, flags);
+        debug_off = atomic_read(&debug_off_a);
+
+        /* Sigh. If the buffer is empty, then skip to the end. */
+        if (debug_off == 0 && !debug_wrapped) {
+                spin_unlock_irqrestore(&portals_debug_lock, flags);
+                rc = 0;
+                goto cleanup;
+        }
+
         if (debug_wrapped) {
-                /* All of this juggling with the 1s is to keep the trailing nul
-                 * (which falls at debug_buf + debug_off) at the end of what we
-                 * copy into user space */
-                copy_to_user(buf, debug_buf + debug_off + 1,
-                             debug_size - debug_off - 1);
-                copy_to_user(buf + debug_size - debug_off - 1,
-                             debug_buf, debug_off + 1);
-                rc = debug_size;
+                off = debug_off + 1;
+                total = debug_size;
         } else {
-                copy_to_user(buf, debug_buf, debug_off);
-                rc = debug_off;
+                off = 0;
+                total = debug_off;
+        }
+        copied = 0;
+        list_for_each(pos, &my_pages) {
+                unsigned long to_copy;
+                page = list_entry(pos, struct page, list);
+
+                to_copy = min(total - off, PAGE_SIZE);
+                if (to_copy == 0) {
+                        off = 0;
+                        to_copy = min(debug_size - off, PAGE_SIZE);
+                }
+finish_partial:
+                memcpy(kmap(page), debug_buf + off, to_copy);
+                kunmap(page);
+                copied += to_copy;
+                if (copied >= total)
+                        break;
+
+                off += to_copy;
+                if (off >= debug_size) {
+                        off = 0;
+                        if (to_copy != PAGE_SIZE) {
+                                to_copy = PAGE_SIZE - to_copy;
+                                goto finish_partial;
+                        }
+                }
         }
+
         spin_unlock_irqrestore(&portals_debug_lock, flags);
 
+        off = 0;
+        list_for_each(pos, &my_pages) {
+                unsigned long to_copy;
+                page = list_entry(pos, struct page, list);
+
+                to_copy = min(copied - off, PAGE_SIZE);
+                rc = copy_to_user(buf + off, kmap(page), to_copy);
+                kunmap(page);
+                if (rc) {
+                        rc = -EFAULT;
+                        goto cleanup;
+                }
+                off += to_copy;
+                if (off >= copied)
+                        break;
+        }
+        rc = copied;
+
+cleanup:
+        list_for_each_safe(pos, n, &my_pages) {
+                page = list_entry(pos, struct page, list);
+                list_del(&page->list);
+                __free_page(page);
+        }
         return rc;
 }
 
 /* FIXME: I'm not very smart; someone smarter should make this better. */
 void
 portals_debug_msg(int subsys, int mask, char *file, const char *fn,
-                  const int line, unsigned long stack, const char *format, ...)
+                  const int line, unsigned long stack, char *format, ...)
 {
         va_list       ap;
         unsigned long flags;
@@ -685,7 +753,7 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         unsigned long debug_off;
 
         if (debug_buf == NULL) {
-                printk("portals_debug_msg: debug_buf is NULL!\n");
+                printk("LustreError: portals_debug_msg: debug_buf is NULL!\n");
                 return;
         }
 
@@ -707,8 +775,9 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
                         /* If this is the first time, leave a marker in the
                          * output */
                         debug_daemon_state.overlapped = 1;
-                        ap = NULL;
                         format = "DEBUG MARKER: Debug buffer overlapped\n";
+                        printk(KERN_ERR "LustreError: debug daemon buffer "
+                               "overlapped\n");
                 } else  /* More space just became available */
                         debug_daemon_state.overlapped = 0;
         }
@@ -716,7 +785,8 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         max_nob = debug_size - debug_off + DEBUG_OVERFLOW;
         if (max_nob <= 0) {
                 spin_unlock_irqrestore(&portals_debug_lock, flags);
-                printk("logic error in portals_debug_msg: <0 bytes to write\n");
+                printk("LustreError: logic error in portals_debug_msg: "
+                       "< 0 bytes to write\n");
                 return;
         }
 
@@ -728,27 +798,26 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         do_gettimeofday(&tv);
 
         prefix_nob = snprintf(debug_buf + debug_off, max_nob,
-                              "%06x:%06x:%d:%lu.%06lu ",
+                              "%06x:%06x:%d:%lu.%06lu:%lu:%d:",
                               subsys, mask, smp_processor_id(),
-                              tv.tv_sec, tv.tv_usec);
+                              tv.tv_sec, tv.tv_usec, stack, current->pid);
         max_nob -= prefix_nob;
+        if(*(format + strlen(format) - 1) != '\n')
+                *(format + strlen(format)) = '\n';
 
 #if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d | %d+%lu): ",
-                           file, line, fn, current->pid,
-                           current->thread.extern_pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->thread.extern_pid, file, line, fn);
 #elif defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d | %d+%lu): ",
-                           file, line, fn, current->pid,
-                           current->thread.mode.tt.extern_pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->thread.mode.tt.extern_pid, file, line, fn);
 #else
         msg_nob = snprintf(debug_buf + debug_off + prefix_nob, max_nob,
-                           "(%s:%d:%s() %d+%lu): ",
-                           file, line, fn, current->pid, stack);
+                           "%d:(%s:%d:%s()) ",
+                           current->pid, file, line, fn);
 #endif
-        max_nob -= msg_nob;
 
         va_start(ap, format);
         msg_nob += vsnprintf(debug_buf + debug_off + prefix_nob + msg_nob,
@@ -759,11 +828,17 @@ portals_debug_msg(int subsys, int mask, char *file, const char *fn,
         /* Print to console, while msg is contiguous in debug_buf */
         /* NB safely terminated see above */
         if ((mask & D_EMERG) != 0)
-                printk(KERN_EMERG "%s", debug_buf + debug_off + prefix_nob);
-        if ((mask & D_ERROR) != 0)
-                printk(KERN_ERR   "%s", debug_buf + debug_off + prefix_nob);
+                printk(KERN_EMERG "LustreError: %s",
+                       debug_buf + debug_off + prefix_nob);
+        else if ((mask & D_ERROR) != 0)
+                printk(KERN_ERR "LustreError: %s",
+                       debug_buf + debug_off + prefix_nob);
+        else if ((mask & D_WARNING) != 0)
+                printk(KERN_WARNING "Lustre: %s",
+                       debug_buf + debug_off + prefix_nob);
         else if (portal_printk)
-                printk("<%d>%s", portal_printk, debug_buf+debug_off+prefix_nob);
+                printk("<%d>Lustre: %s", portal_printk,
+                       debug_buf+debug_off+prefix_nob);
         base_offset = debug_off & 0xFFFF;
 
         debug_off += prefix_nob + msg_nob;
@@ -786,7 +861,7 @@ out:
 
 void portals_debug_set_level(unsigned int debug_level)
 {
-        printk("Setting portals debug level to %08x\n", debug_level);
+        printk("Lustre: Setting portals debug level to %08x\n", debug_level);
         portal_debug = debug_level;
 }
 
@@ -806,8 +881,8 @@ void portals_run_upcall(char **argv)
                 argc++;
 
         LASSERT(argc >= 2);
-        
-        rc = call_usermodehelper(argv[0], argv, envp);
+
+        rc = USERMODEHELPER(argv[0], argv, envp);
         if (rc < 0) {
                 CERROR("Error %d invoking portals upcall %s %s%s%s%s%s%s%s%s; "
                        "check /proc/sys/portals/upcall\n",
@@ -843,8 +918,131 @@ void portals_run_lbug_upcall(char *file, const char *fn, const int line)
         portals_run_upcall (argv);
 }
 
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
+{
+        switch(nal){
+        case TCPNAL:
+                /* userspace NAL */
+        case SOCKNAL:
+                sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
+                        HIPQUAD(nid));
+                break;
+        case QSWNAL:
+        case GMNAL:
+        case IBNAL:
+        case TOENAL:
+        case SCIMACNAL:
+                sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
+                break;
+        default:
+                return NULL;
+        }
+        return str;
+}
+
+#ifdef __KERNEL__
+#include <linux/lustre_version.h>
+#if (LUSTRE_KERNEL_VERSION >= 30)
+#warning "FIXME: remove workaround when l30 is widely used"
+char stack_backtrace[LUSTRE_TRACE_SIZE];
+spinlock_t stack_backtrace_lock = SPIN_LOCK_UNLOCKED;
+
+#if defined(__arch_um__)
+
+extern int is_kernel_text_address(unsigned long addr);
+
+char *portals_debug_dumpstack(void)
+{
+        int size;
+        unsigned long addr;
+        char *buf = stack_backtrace;
+        char *pbuf = buf;
+        unsigned long *stack = (unsigned long *)&buf;
+
+        size = sprintf(pbuf, " Call Trace: ");
+        pbuf += size;
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+                addr = *stack++;
+                if (is_kernel_text_address(addr)) {
+                        size = sprintf(pbuf, "[<%08lx>] ", addr);
+                        pbuf += size;
+                        if (buf + LUSTRE_TRACE_SIZE <= pbuf + 12)
+                                break;
+                }
+        }
+
+        return buf;
+}
+
+#elif defined(CONFIG_X86)
+
+extern int is_kernel_text_address(unsigned long addr);
+extern int lookup_symbol(unsigned long address, char *buf, int buflen);
+
+char *portals_debug_dumpstack(void)
+{
+#if defined(__x86_64__)
+        unsigned long esp = current->thread.rsp;
+#else
+        unsigned long esp = current->thread.esp;
+#endif
+        unsigned long *stack = (unsigned long *)&esp;
+        int size;
+        unsigned long addr;
+        char *buf = stack_backtrace;
+        char *pbuf = buf;
+        static char buffer[512];
+        int rc = 0;
+
+        /* User space on another CPU? */
+        if ((esp ^ (unsigned long)current) & (PAGE_MASK<<1)){
+                buf[0] = '\0';
+                goto out;
+        }
+
+        size = sprintf(pbuf, " Call Trace: ");
+        pbuf += size;
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+                addr = *stack++;
+                if (is_kernel_text_address(addr)) {
+                        rc = lookup_symbol(addr, buffer, 512);
+                        if (rc == -ENOSYS) {
+                                if (buf + LUSTRE_TRACE_SIZE <= pbuf + 12)
+                                        break;
+                                size = sprintf(pbuf, "[<%08lx>] ", addr);
+                        } else {
+                                if (buf + LUSTRE_TRACE_SIZE
+                                            /* fix length + sizeof('\0') */
+                                    <= pbuf + strlen(buffer) + 28 + 1)
+                                        break;
+                                size = sprintf(pbuf, "([<%08lx>] %s (0x%p)) ",
+                                               addr, buffer, stack-1);
+                        }
+                        pbuf += size;
+                }
+        }
+out:
+        return buf;
+}
+
+#else /* !__arch_um__ && !__i386__ */
+
+char *portals_debug_dumpstack(void)
+{
+        char *buf = stack_backtrace;
+        buf[0] = '\0';
+        return buf;
+}
+
+#endif /* __arch_um__ */
+EXPORT_SYMBOL(stack_backtrace_lock);
+EXPORT_SYMBOL(portals_debug_dumpstack);
+#endif /* LUSTRE_KERNEL_VERSION < 30 */
+#endif /* __KERNEL__ */
+
 EXPORT_SYMBOL(portals_debug_dumplog);
 EXPORT_SYMBOL(portals_debug_msg);
 EXPORT_SYMBOL(portals_debug_set_level);
 EXPORT_SYMBOL(portals_run_upcall);
 EXPORT_SYMBOL(portals_run_lbug_upcall);
+EXPORT_SYMBOL(portals_nid2str);
diff --git a/lustre/portals/libcfs/lwt.c b/lustre/portals/libcfs/lwt.c
index a40a7ed5127e07b7073fb2b8cd31f7e350b8588a..89fe8f707de5e6c7c87e790e0de6f78a6b3d5f43 100644
--- a/lustre/portals/libcfs/lwt.c
+++ b/lustre/portals/libcfs/lwt.c
@@ -20,7 +20,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -57,6 +59,8 @@ int
 lwt_lookup_string (int *size, char *knl_ptr,
                    char *user_ptr, int user_size)
 {
+        int   maxsize = 128;
+        
         /* knl_ptr was retrieved from an LWT snapshot and the caller wants to
          * turn it into a string.  NB we can crash with an access violation
          * trying to determine the string length, so we're trusting our
@@ -65,12 +69,24 @@ lwt_lookup_string (int *size, char *knl_ptr,
         if (!capable(CAP_SYS_ADMIN))
                 return (-EPERM);
 
-        *size = strlen (knl_ptr) + 1;
-        
-        if (user_ptr != NULL &&
-            copy_to_user (user_ptr, knl_ptr, *size))
-                return (-EFAULT);
+        if (user_size > 0 && 
+            maxsize > user_size)
+                maxsize = user_size;
+
+        *size = strnlen (knl_ptr, maxsize - 1) + 1;
         
+        if (user_ptr != NULL) {
+                if (user_size < 4)
+                        return (-EINVAL);
+                
+                if (copy_to_user (user_ptr, knl_ptr, *size))
+                        return (-EFAULT);
+
+                /* Did I truncate the string?  */
+                if (knl_ptr[*size - 1] != 0)
+                        copy_to_user (user_ptr + *size - 4, "...", 4);
+        }
+
         return (0);
 }
 
@@ -87,11 +103,10 @@ lwt_control (int enable, int clear)
         if (clear)
                 for (i = 0; i < num_online_cpus(); i++) {
                         p = lwt_cpus[i].lwtc_current_page;
-                        
+
                         for (j = 0; j < lwt_pages_per_cpu; j++) {
-                                
                                 memset (p->lwtp_events, 0, PAGE_SIZE);
-                                
+
                                 p = list_entry (p->lwtp_list.next,
                                                 lwt_page_t, lwtp_list);
                         }
@@ -108,8 +123,7 @@ lwt_control (int enable, int clear)
 }
 
 int
-lwt_snapshot (int *ncpu, int *total_size, 
-              void *user_ptr, int user_size) 
+lwt_snapshot (int *ncpu, int *total_size, void *user_ptr, int user_size)
 {
         const int    events_per_page = PAGE_SIZE / sizeof(lwt_event_t);
         const int    bytes_per_page = events_per_page * sizeof(lwt_event_t);
diff --git a/lustre/portals/libcfs/module.c b/lustre/portals/libcfs/module.c
index 586b67548865d9652d00483f9761127f590a1eeb..7c0cafc7817f363619c91730eed88b85dc42de29 100644
--- a/lustre/portals/libcfs/module.c
+++ b/lustre/portals/libcfs/module.c
@@ -210,17 +210,69 @@ kportal_get_route(int index, __u32 *gateway_nalidp, ptl_nid_t *gateway_nidp,
         return (rc);
 }
 
-static int
-kportal_nal_cmd(int nal, struct portal_ioctl_data *data)
+static int 
+kportal_router_cmd(struct portals_cfg *pcfg, void * private)
+{
+        int err = -EINVAL;
+        ENTRY;
+
+        switch(pcfg->pcfg_command) {
+        default:
+                CDEBUG(D_IOCTL, "Inappropriate cmd: %d\n", pcfg->pcfg_command);
+                break;
+                
+        case NAL_CMD_ADD_ROUTE:
+                CDEBUG(D_IOCTL, "Adding route: [%d] "LPU64" : "LPU64" - "LPU64"\n",
+                       pcfg->pcfg_nal, pcfg->pcfg_nid, 
+                       pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                err = kportal_add_route(pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                        pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                break;
+
+        case NAL_CMD_DEL_ROUTE:
+                CDEBUG (D_IOCTL, "Removing routes via [%d] "LPU64" : "LPU64" - "LPU64"\n",
+                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid, 
+                        pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                err = kportal_del_route (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                         pcfg->pcfg_nid2, pcfg->pcfg_nid3);
+                break;
+
+        case NAL_CMD_NOTIFY_ROUTER: {
+                CDEBUG (D_IOCTL, "Notifying peer [%d] "LPU64" %s @ %ld\n",
+                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                        pcfg->pcfg_flags ? "Enabling" : "Disabling",
+                        (time_t)pcfg->pcfg_nid3);
+                
+                err = kportal_notify_router (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
+                                             pcfg->pcfg_flags, 
+                                             (time_t)pcfg->pcfg_nid3);
+                break;
+        }
+                
+        case NAL_CMD_GET_ROUTE:
+                CDEBUG (D_IOCTL, "Getting route [%d]\n", pcfg->pcfg_count);
+                err = kportal_get_route(pcfg->pcfg_count, &pcfg->pcfg_gw_nal,
+                                        &pcfg->pcfg_nid, 
+                                        &pcfg->pcfg_nid2, &pcfg->pcfg_nid3,
+                                        &pcfg->pcfg_flags);
+                break;
+        }
+        RETURN(err);
+}
+
+int
+kportal_nal_cmd(struct portals_cfg *pcfg)
 {
+        __u32 nal = pcfg->pcfg_nal;
         int rc = -EINVAL;
 
         ENTRY;
 
         down(&nal_cmd_sem);
         if (nal > 0 && nal <= NAL_MAX_NR && nal_cmd[nal].nch_handler) {
-                CDEBUG(D_IOCTL, "calling handler nal: %d, cmd: %d\n", nal, data->ioc_nal_cmd);
-                rc = nal_cmd[nal].nch_handler(data, nal_cmd[nal].nch_private);
+                CDEBUG(D_IOCTL, "calling handler nal: %d, cmd: %d\n", nal, 
+                       pcfg->pcfg_command);
+                rc = nal_cmd[nal].nch_handler(pcfg, nal_cmd[nal].nch_private);
         }
         up(&nal_cmd_sem);
         RETURN(rc);
@@ -240,6 +292,8 @@ kportal_get_ni (int nal)
                 return  (PORTAL_SYMBOL_GET(ktoenal_ni));
         case GMNAL:
                 return  (PORTAL_SYMBOL_GET(kgmnal_ni));
+        case IBNAL:
+                return  (PORTAL_SYMBOL_GET(kibnal_ni));
         case TCPNAL:
                 /* userspace NAL */
                 return (NULL);
@@ -270,6 +324,9 @@ kportal_put_ni (int nal)
         case GMNAL:
                 PORTAL_SYMBOL_PUT(kgmnal_ni);
                 break;
+        case IBNAL:
+                PORTAL_SYMBOL_PUT(kibnal_ni);
+                break;
         case TCPNAL:
                 /* A lesson to a malicious caller */
                 LBUG ();
@@ -324,9 +381,13 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
         int err = 0;
         char buf[1024];
         struct portal_ioctl_data *data;
+        char str[PTL_NALFMT_SIZE];
 
         ENTRY;
 
+        if (current->fsuid != 0)
+                RETURN(err = -EACCES);
+
         if ( _IOC_TYPE(cmd) != IOC_PORTAL_TYPE ||
              _IOC_NR(cmd) < IOC_PORTAL_MIN_NR  ||
              _IOC_NR(cmd) > IOC_PORTAL_MAX_NR ) {
@@ -377,8 +438,9 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
         case IOC_PORTAL_PING: {
                 void (*ping)(struct portal_ioctl_data *);
 
-                CDEBUG(D_IOCTL, "doing %d pings to nid "LPU64"\n",
-                       data->ioc_count, data->ioc_nid);
+                CDEBUG(D_IOCTL, "doing %d pings to nid "LPX64" (%s)\n",
+                       data->ioc_count, data->ioc_nid,
+                       portals_nid2str(data->ioc_nal, data->ioc_nid, str));
                 ping = PORTAL_SYMBOL_GET(kping_client);
                 if (!ping)
                         CERROR("PORTAL_SYMBOL_GET failed\n");
@@ -389,50 +451,11 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
                 RETURN(0);
         }
 
-        case IOC_PORTAL_ADD_ROUTE:
-                CDEBUG(D_IOCTL, "Adding route: [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                       data->ioc_nal, data->ioc_nid, 
-                       data->ioc_nid2, data->ioc_nid3);
-                err = kportal_add_route(data->ioc_nal, data->ioc_nid,
-                                        data->ioc_nid2, data->ioc_nid3);
-                break;
-
-        case IOC_PORTAL_DEL_ROUTE:
-                CDEBUG (D_IOCTL, "Removing routes via [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                        data->ioc_nal, data->ioc_nid, 
-                        data->ioc_nid2, data->ioc_nid3);
-                err = kportal_del_route (data->ioc_nal, data->ioc_nid,
-                                         data->ioc_nid2, data->ioc_nid3);
-                break;
-
-        case IOC_PORTAL_NOTIFY_ROUTER: {
-                CDEBUG (D_IOCTL, "Notifying peer [%d] "LPU64" %s @ %ld\n",
-                        data->ioc_nal, data->ioc_nid,
-                        data->ioc_flags ? "Enabling" : "Disabling",
-                        (time_t)data->ioc_nid3);
-                
-                err = kportal_notify_router (data->ioc_nal, data->ioc_nid,
-                                             data->ioc_flags, 
-                                             (time_t)data->ioc_nid3);
-                break;
-        }
-                
-        case IOC_PORTAL_GET_ROUTE:
-                CDEBUG (D_IOCTL, "Getting route [%d]\n", data->ioc_count);
-                err = kportal_get_route(data->ioc_count, &data->ioc_nal,
-                                        &data->ioc_nid, 
-                                        &data->ioc_nid2, &data->ioc_nid3,
-                                        &data->ioc_flags);
-                if (err == 0)
-                        if (copy_to_user((char *)arg, data, sizeof (*data)))
-                                err = -EFAULT;
-                break;
-
         case IOC_PORTAL_GET_NID: {
                 const ptl_handle_ni_t *nip;
                 ptl_process_id_t       pid;
 
-                CDEBUG (D_IOCTL, "Getting nid [%d]\n", data->ioc_nal);
+                CDEBUG (D_IOCTL, "Getting nid for nal [%d]\n", data->ioc_nal);
 
                 nip = kportal_get_ni (data->ioc_nal);
                 if (nip == NULL)
@@ -448,15 +471,29 @@ static int kportal_ioctl(struct inode *inode, struct file *file,
                 break;
         }
 
-        case IOC_PORTAL_NAL_CMD:
-                CDEBUG (D_IOCTL, "nal command nal %d cmd %d\n", data->ioc_nal,
-                        data->ioc_nal_cmd);
-                err = kportal_nal_cmd(data->ioc_nal, data);
-                if (err == 0)
+        case IOC_PORTAL_NAL_CMD: {
+                struct portals_cfg pcfg;
+
+                LASSERT (data->ioc_plen1 == sizeof(pcfg));
+                err = copy_from_user(&pcfg, (void *)data->ioc_pbuf1, 
+                                     sizeof(pcfg));
+                if ( err ) {
+                        EXIT;
+                        return err;
+                }
+
+                CDEBUG (D_IOCTL, "nal command nal %d cmd %d\n", pcfg.pcfg_nal,
+                        pcfg.pcfg_command);
+                err = kportal_nal_cmd(&pcfg);
+                if (err == 0) {
+                        if (copy_to_user((char *)data->ioc_pbuf1, &pcfg, 
+                                         sizeof (pcfg)))
+                                err = -EFAULT;
                         if (copy_to_user((char *)arg, data, sizeof (*data)))
                                 err = -EFAULT;
+                }
                 break;
-
+        }
         case IOC_PORTAL_FAIL_NID: {
                 const ptl_handle_ni_t *nip;
 
@@ -526,7 +563,7 @@ static int init_kportals_module(void)
 
         rc = portals_debug_init(5 * 1024 * 1024);
         if (rc < 0) {
-                printk(KERN_ERR "portals_debug_init: %d\n", rc);
+                printk(KERN_ERR "LustreError: portals_debug_init: %d\n", rc);
                 return (rc);
         }
 
@@ -557,9 +594,17 @@ static int init_kportals_module(void)
                 goto cleanup_fini;
         }
 
+        rc = kportal_nal_register(ROUTER, kportal_router_cmd, NULL);
+        if (rc) {
+                CERROR("kportal_nal_registre: ROUTER error %d\n", rc);
+                goto cleanup_proc;
+        }
+
         CDEBUG (D_OTHER, "portals setup OK\n");
         return (0);
 
+ cleanup_proc:
+        remove_proc();
  cleanup_fini:
         PtlFini();
  cleanup_deregister:
@@ -577,6 +622,7 @@ static void exit_kportals_module(void)
 {
         int rc;
 
+        kportal_nal_unregister(ROUTER);
         remove_proc();
         PtlFini();
 
@@ -598,7 +644,7 @@ static void exit_kportals_module(void)
 
         rc = portals_debug_cleanup();
         if (rc)
-                printk(KERN_ERR "portals_debug_cleanup: %d\n", rc);
+                printk(KERN_ERR "LustreError: portals_debug_cleanup: %d\n", rc);
 }
 
 EXPORT_SYMBOL(lib_dispatch);
@@ -620,6 +666,7 @@ EXPORT_SYMBOL(portal_subsystem_debug);
 EXPORT_SYMBOL(portal_debug);
 EXPORT_SYMBOL(portal_stack);
 EXPORT_SYMBOL(portal_printk);
+EXPORT_SYMBOL(portal_cerror);
 EXPORT_SYMBOL(PtlEQWait);
 EXPORT_SYMBOL(PtlEQFree);
 EXPORT_SYMBOL(PtlEQGet);
@@ -633,6 +680,7 @@ EXPORT_SYMBOL(lib_copy_kiov2buf);
 EXPORT_SYMBOL(lib_copy_buf2kiov);
 EXPORT_SYMBOL(lib_finalize);
 EXPORT_SYMBOL(lib_parse);
+EXPORT_SYMBOL(lib_fake_reply_msg);
 EXPORT_SYMBOL(lib_init);
 EXPORT_SYMBOL(lib_fini);
 EXPORT_SYMBOL(portal_kmemory);
@@ -644,6 +692,7 @@ EXPORT_SYMBOL(kportal_assertion_failed);
 EXPORT_SYMBOL(dispatch_name);
 EXPORT_SYMBOL(kportal_get_ni);
 EXPORT_SYMBOL(kportal_put_ni);
+EXPORT_SYMBOL(kportal_nal_cmd);
 
 module_init(init_kportals_module);
 module_exit (exit_kportals_module);
diff --git a/lustre/portals/libcfs/proc.c b/lustre/portals/libcfs/proc.c
index 564a0bd090b203623e536643280cc34d01f8841d..c1b2aecb15bba6d28ccc2162d704c01e378ca176 100644
--- a/lustre/portals/libcfs/proc.c
+++ b/lustre/portals/libcfs/proc.c
@@ -22,7 +22,9 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -63,11 +65,12 @@ extern char portals_upcall[1024];
 #define PSDEV_DEBUG           1   /* control debugging */
 #define PSDEV_SUBSYSTEM_DEBUG 2   /* control debugging */
 #define PSDEV_PRINTK          3   /* force all errors to console */
-#define PSDEV_DEBUG_PATH      4   /* crashdump log location */
-#define PSDEV_DEBUG_DUMP_PATH 5   /* crashdump tracelog location */
-#define PSDEV_PORTALS_UPCALL  6   /* User mode upcall script  */
+#define PSDEV_CONSOLE         4   /* allow _any_ messages to console */
+#define PSDEV_DEBUG_PATH      5   /* crashdump log location */
+#define PSDEV_DEBUG_DUMP_PATH 6   /* crashdump tracelog location */
+#define PSDEV_PORTALS_UPCALL  7   /* User mode upcall script  */
 
-#define PORTALS_PRIMARY_CTLCNT 6
+#define PORTALS_PRIMARY_CTLCNT 7
 static struct ctl_table portals_table[PORTALS_PRIMARY_CTLCNT + 1] = {
         {PSDEV_DEBUG, "debug", &portal_debug, sizeof(int), 0644, NULL,
          &proc_dointvec},
@@ -75,6 +78,8 @@ static struct ctl_table portals_table[PORTALS_PRIMARY_CTLCNT + 1] = {
          sizeof(int), 0644, NULL, &proc_dointvec},
         {PSDEV_PRINTK, "printk", &portal_printk, sizeof(int), 0644, NULL,
          &proc_dointvec},
+        {PSDEV_CONSOLE, "console", &portal_cerror, sizeof(int), 0644, NULL,
+         &proc_dointvec},
         {PSDEV_DEBUG_PATH, "debug_path", debug_file_path,
          sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string},
         {PSDEV_DEBUG_DUMP_PATH, "debug_daemon_path", debug_daemon_file_path,
diff --git a/lustre/portals/portals/api-eq.c b/lustre/portals/portals/api-eq.c
index e066619ab3d9402384ba78ca874a846c066aa946..9bc9c36d84e06fcc616a19c470e6e28712b013e2 100644
--- a/lustre/portals/portals/api-eq.c
+++ b/lustre/portals/portals/api-eq.c
@@ -123,13 +123,22 @@ static jmp_buf eq_jumpbuf;
 
 static void eq_timeout(int signal)
 {
+        sigset_t set;
+
+        /* signal will be automatically disabled in sig handler,
+         * must enable it before long jump
+         */
+        sigemptyset(&set);
+        sigaddset(&set, SIGALRM);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+
         longjmp(eq_jumpbuf, -1);
 }
 
 int PtlEQWait_timeout(ptl_handle_eq_t eventq_in, ptl_event_t * event_out,
                       int timeout)
 {
-        static void (*prev) (int);
+        static void (*prev) (int) = NULL;
         static int left_over;
         time_t time_at_start;
         int rc;
@@ -143,7 +152,7 @@ int PtlEQWait_timeout(ptl_handle_eq_t eventq_in, ptl_event_t * event_out,
         left_over = alarm(timeout);
         prev = signal(SIGALRM, eq_timeout);
         time_at_start = time(NULL);
-        if (left_over < timeout)
+        if (left_over && left_over < timeout)
                 alarm(left_over);
 
         rc = PtlEQWait(eventq_in, event_out);
diff --git a/lustre/portals/portals/api-init.c b/lustre/portals/portals/api-init.c
index dc1fead5c1a6f134de0d391c0dc885434c6a729f..020a2a9fa21824e30d35795d1a6e27b9b4e5db40 100644
--- a/lustre/portals/portals/api-init.c
+++ b/lustre/portals/portals/api-init.c
@@ -26,8 +26,9 @@
 #include <portals/api-support.h>
 
 int ptl_init;
-unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL | S_GMNAL);
+unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL | S_GMNAL | S_IBNAL);
 unsigned int portal_debug = ~0;
+unsigned int portal_cerror = 1;
 unsigned int portal_printk;
 unsigned int portal_stack;
 
diff --git a/lustre/portals/portals/lib-init.c b/lustre/portals/portals/lib-init.c
index 99c4d32c3e28e31a524ade40acfbdeb051012a62..ab223d6de670dc2f5435a18c326132086fe7e3ff 100644
--- a/lustre/portals/portals/lib-init.c
+++ b/lustre/portals/portals/lib-init.c
@@ -127,6 +127,8 @@ kportal_descriptor_setup (nal_cb_t *nal)
 void
 kportal_descriptor_cleanup (nal_cb_t *nal)
 {
+        int rc;
+
         if (--ptl_slab_users != 0)
                 return;
 
@@ -135,14 +137,26 @@ kportal_descriptor_cleanup (nal_cb_t *nal)
         LASSERT (atomic_read (&eq_in_use_count) == 0);
         LASSERT (atomic_read (&msg_in_use_count) == 0);
 
-        if (ptl_md_slab != NULL)
-                kmem_cache_destroy(ptl_md_slab);
-        if (ptl_msg_slab != NULL)
-                kmem_cache_destroy(ptl_msg_slab);
-        if (ptl_me_slab != NULL)
-                kmem_cache_destroy(ptl_me_slab);
-        if (ptl_eq_slab != NULL)
-                kmem_cache_destroy(ptl_eq_slab);
+        if (ptl_md_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_md_slab);
+                if (rc != 0)
+                        CERROR("unable to free MD slab\n");
+        }
+        if (ptl_msg_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_msg_slab);
+                if (rc != 0)
+                        CERROR("unable to free MSG slab\n");
+        }
+        if (ptl_me_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_me_slab);
+                if (rc != 0)
+                        CERROR("unable to free ME slab\n");
+        }
+        if (ptl_eq_slab != NULL) {
+                rc = kmem_cache_destroy(ptl_eq_slab);
+                if (rc != 0)
+                        CERROR("unable to free EQ slab\n");
+        }
 }
 #else
 
diff --git a/lustre/portals/portals/lib-md.c b/lustre/portals/portals/lib-md.c
index a79e2be30bf1506e74abf9dcdcf0957b8935e6a7..be6949c11f982e83f4c61d84a25cd79757137ab8 100644
--- a/lustre/portals/portals/lib-md.c
+++ b/lustre/portals/portals/lib-md.c
@@ -396,8 +396,7 @@ int do_PtlMDUpdate_internal(nal_cb_t * nal, void *private, void *v_args,
             test_eq->sequence == args->sequence_in) {
                 lib_me_t *me = md->me;
 
-#warning this does not track eq refcounts properly
-
+                // #warning this does not track eq refcounts properly 
                 ret->rc = lib_md_build(nal, md, private,
                                        new, &new->eventq, md->unlink);
 
diff --git a/lustre/portals/portals/lib-me.c b/lustre/portals/portals/lib-me.c
index bd1af5bbdcd06e16d4655e62ab2d7a579391d5b1..31ac21454cd5ebb4b7a2ccc06d3e676e37dcf132 100644
--- a/lustre/portals/portals/lib-me.c
+++ b/lustre/portals/portals/lib-me.c
@@ -44,7 +44,7 @@ int do_PtlMEAttach(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         unsigned long flags;
         lib_me_t *me;
 
-        if (args->index_in < 0 || args->index_in >= tbl->size)
+        if (args->index_in >= tbl->size)
                 return ret->rc = PTL_INV_PTINDEX;
 
         /* Should check for valid matchid, but not yet */
diff --git a/lustre/portals/portals/lib-move.c b/lustre/portals/portals/lib-move.c
index 691588596fcbc548077b8f1fdffcc0383411da4b..6e904ba7e330ccabc9e40c5bbc0713fb454d5bfd 100644
--- a/lustre/portals/portals/lib-move.c
+++ b/lustre/portals/portals/lib-move.c
@@ -305,8 +305,6 @@ lib_extract_iov (struct iovec *dst, lib_md_t *md,
         ptl_size_t      frag_len;
         int             dst_niov;
 
-        LASSERT (len >= 0);
-        LASSERT (offset >= 0);
         LASSERT (offset + len <= md->length);
         
         if (len == 0)                           /* no data => */
@@ -442,8 +440,6 @@ lib_extract_kiov (ptl_kiov_t *dst, lib_md_t *md,
         ptl_size_t      frag_len;
         int             dst_niov;
 
-        LASSERT (len >= 0);
-        LASSERT (offset >= 0);
         LASSERT (offset + len <= md->length);
         
         if (len == 0)                           /* no data => */
@@ -587,7 +583,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         me = lib_find_me(nal, hdr->msg.put.ptl_index, PTL_MD_OP_PUT,
                          hdr->src_nid, hdr->src_pid,
-                         PTL_HDR_LENGTH (hdr), hdr->msg.put.offset,
+                         hdr->payload_length, hdr->msg.put.offset,
                          hdr->msg.put.match_bits,
                          &mlength, &offset, &unlink);
         if (me == NULL)
@@ -596,7 +592,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         md = me->md;
         CDEBUG(D_NET, "Incoming put index %x from "LPU64"/%u of length %d/%d "
                "into md "LPX64" [%d] + %d\n", hdr->msg.put.ptl_index,
-               hdr->src_nid, hdr->src_pid, mlength, PTL_HDR_LENGTH(hdr), 
+               hdr->src_nid, hdr->src_pid, mlength, hdr->payload_length, 
                md->md_lh.lh_cookie, md->md_niov, offset);
 
         msg = get_new_msg (nal, md);
@@ -621,7 +617,7 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                 msg->ev.initiator.pid = hdr->src_pid;
                 msg->ev.portal = hdr->msg.put.ptl_index;
                 msg->ev.match_bits = hdr->msg.put.match_bits;
-                msg->ev.rlength = PTL_HDR_LENGTH(hdr);
+                msg->ev.rlength = hdr->payload_length;
                 msg->ev.mlength = mlength;
                 msg->ev.offset = offset;
                 msg->ev.hdr_data = hdr->msg.put.hdr_data;
@@ -650,14 +646,14 @@ static int parse_put(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         state_unlock(nal, &flags);
 
-        lib_recv (nal, private, msg, md, offset, mlength, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, msg, md, offset, mlength, hdr->payload_length);
         return 0;
 
  drop:
         nal->ni.counters.drop_count++;
-        nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+        nal->ni.counters.drop_length += hdr->payload_length;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -680,11 +676,6 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         hdr->msg.get.sink_length = NTOH__u32 (hdr->msg.get.sink_length);
         hdr->msg.get.src_offset = NTOH__u32 (hdr->msg.get.src_offset);
 
-        /* compatibility check until field is deleted */
-        if (hdr->msg.get.return_offset != 0)
-                CERROR("Unexpected non-zero get.return_offset %x from "
-                       LPU64"\n", hdr->msg.get.return_offset, hdr->src_nid);
-
         state_lock(nal, &flags);
 
         me = lib_find_me(nal, hdr->msg.get.ptl_index, PTL_MD_OP_GET,
@@ -698,7 +689,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         md = me->md;
         CDEBUG(D_NET, "Incoming get index %d from "LPU64".%u of length %d/%d "
                "from md "LPX64" [%d] + %d\n", hdr->msg.get.ptl_index,
-               hdr->src_nid, hdr->src_pid, mlength, PTL_HDR_LENGTH(hdr), 
+               hdr->src_nid, hdr->src_pid, mlength, hdr->payload_length, 
                md->md_lh.lh_cookie, md->md_niov, offset);
 
         msg = get_new_msg (nal, md);
@@ -714,7 +705,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                 msg->ev.initiator.pid = hdr->src_pid;
                 msg->ev.portal = hdr->msg.get.ptl_index;
                 msg->ev.match_bits = hdr->msg.get.match_bits;
-                msg->ev.rlength = PTL_HDR_LENGTH(hdr);
+                msg->ev.rlength = hdr->payload_length;
                 msg->ev.mlength = mlength;
                 msg->ev.offset = offset;
                 msg->ev.hdr_data = 0;
@@ -749,7 +740,7 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         reply.src_nid  = HTON__u64 (ni->nid);
         reply.dest_pid = HTON__u32 (hdr->src_pid);
         reply.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&reply) = HTON__u32 (mlength);
+        reply.payload_length = HTON__u32 (mlength);
 
         reply.msg.reply.dst_wmd = hdr->msg.get.return_wmd;
 
@@ -767,13 +758,13 @@ static int parse_get(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         }
 
         /* Complete the incoming message */
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return (rc);
  drop:
         ni->counters.drop_count++;
         ni->counters.drop_length += hdr->msg.get.sink_length;
         state_unlock(nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -786,11 +777,6 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
         lib_msg_t       *msg;
         unsigned long    flags;
 
-        /* compatibility check until field is deleted */
-        if (hdr->msg.reply.dst_offset != 0)
-                CERROR("Unexpected non-zero reply.dst_offset %x from "LPU64"\n",
-                       hdr->msg.reply.dst_offset, hdr->src_nid);
-
         state_lock(nal, &flags);
 
         /* NB handles only looked up by creator (no flips) */
@@ -806,7 +792,7 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         LASSERT (md->offset == 0);
 
-        length = rlength = PTL_HDR_LENGTH(hdr);
+        length = rlength = hdr->payload_length;
 
         if (length > md->length) {
                 if ((md->options & PTL_MD_TRUNCATE) == 0) {
@@ -852,9 +838,9 @@ static int parse_reply(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
  drop:
         nal->ni.counters.drop_count++;
-        nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+        nal->ni.counters.drop_length += hdr->payload_length;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -905,13 +891,13 @@ static int parse_ack(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
         ni->counters.recv_count++;
         state_unlock(nal, &flags);
-        lib_recv (nal, private, msg, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, msg, NULL, 0, 0, hdr->payload_length);
         return 0;
 
  drop:
         nal->ni.counters.drop_count++;
         state_unlock (nal, &flags);
-        lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+        lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
         return -1;
 }
 
@@ -958,7 +944,7 @@ void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr)
                                hdr->msg.put.match_bits);
                 nal->cb_printf(nal,
                                "    Length %d, offset %d, hdr data "LPX64"\n",
-                               PTL_HDR_LENGTH(hdr), hdr->msg.put.offset,
+                               hdr->payload_length, hdr->msg.put.offset,
                                hdr->msg.put.hdr_data);
                 break;
 
@@ -988,7 +974,7 @@ void print_hdr(nal_cb_t * nal, ptl_hdr_t * hdr)
                                "length %d\n",
                                hdr->msg.reply.dst_wmd.wh_interface_cookie,
                                hdr->msg.reply.dst_wmd.wh_object_cookie,
-                               PTL_HDR_LENGTH(hdr));
+                               hdr->payload_length);
         }
 
 }                               /* end of print_hdr() */
@@ -998,21 +984,13 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 {
         unsigned long  flags;
 
-        /* NB static check; optimizer will elide this if it's right */
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.put.length));
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.get.length));
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) ==
-                 offsetof (ptl_hdr_t, msg.reply.length));
-
         /* convert common fields to host byte order */
         hdr->dest_nid = NTOH__u64 (hdr->dest_nid);
         hdr->src_nid = NTOH__u64 (hdr->src_nid);
         hdr->dest_pid = NTOH__u32 (hdr->dest_pid);
         hdr->src_pid = NTOH__u32 (hdr->src_pid);
         hdr->type = NTOH__u32 (hdr->type);
-        PTL_HDR_LENGTH(hdr) = NTOH__u32 (PTL_HDR_LENGTH(hdr));
+        hdr->payload_length = NTOH__u32(hdr->payload_length);
 #if 0
         nal->cb_printf(nal, "%d: lib_parse: nal=%p hdr=%p type=%d\n",
                        nal->ni.nid, nal, hdr, hdr->type);
@@ -1027,7 +1005,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                         nal->ni.nid, mv->magic, 
                         mv->version_major, mv->version_minor,
                         hdr->src_nid);
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
         
@@ -1038,10 +1016,10 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
 
                 state_lock (nal, &flags);
                 nal->ni.counters.drop_count++;
-                nal->ni.counters.drop_length += PTL_HDR_LENGTH(hdr);
+                nal->ni.counters.drop_length += hdr->payload_length;
                 state_unlock (nal, &flags);
 
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
 
@@ -1052,6 +1030,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                        ": simulated failure\n",
                        nal->ni.nid, hdr_type_string (hdr), 
                        hdr->src_nid);
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
         
@@ -1072,7 +1051,7 @@ int lib_parse(nal_cb_t * nal, ptl_hdr_t * hdr, void *private)
                        ": Bad type=0x%x\n",  nal->ni.nid, hdr->src_nid,
                        hdr->type);
 
-                lib_recv (nal, private, NULL, NULL, 0, 0, PTL_HDR_LENGTH (hdr));
+                lib_recv (nal, private, NULL, NULL, 0, 0, hdr->payload_length);
                 return (-1);
         }
 }
@@ -1129,7 +1108,7 @@ int do_PtlPut(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         hdr.src_nid  = HTON__u64 (ni->nid);
         hdr.dest_pid = HTON__u32 (id->pid);
         hdr.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&hdr) = HTON__u32 (md->length);
+        hdr.payload_length = HTON__u32 (md->length);
 
         /* NB handles only looked up by creator (no flips) */
         if (args->ack_req_in == PTL_ACK_REQ) {
@@ -1193,6 +1172,68 @@ int do_PtlPut(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         return ret->rc = PTL_OK;
 }
 
+lib_msg_t * lib_fake_reply_msg (nal_cb_t *nal, ptl_nid_t peer_nid, 
+                                lib_md_t *getmd)
+{
+        /* The NAL can DMA direct to the GET md (i.e. no REPLY msg).  This
+         * returns a msg the NAL can pass to lib_finalize() so that a REPLY
+         * event still occurs. 
+         *
+         * CAVEAT EMPTOR: 'getmd' is passed by pointer so it MUST be valid.
+         * This can only be guaranteed while a lib_msg_t holds a reference
+         * on it (ie. pending > 0), so best call this before the
+         * lib_finalize() of the original GET. */
+
+        lib_ni_t        *ni = &nal->ni;
+        lib_msg_t       *msg;
+        unsigned long    flags;
+
+        state_lock(nal, &flags);
+
+        LASSERT (getmd->pending > 0);
+
+        if (getmd->threshold == 0) {
+                CERROR ("Dropping REPLY from "LPU64" for inactive MD %p\n",
+                        peer_nid, getmd);
+                goto drop;
+        }
+
+        LASSERT (getmd->offset == 0);
+
+        CDEBUG(D_NET, "Reply from "LPU64" md %p\n", peer_nid, getmd);
+
+        msg = get_new_msg (nal, getmd);
+        if (msg == NULL) {
+                CERROR("Dropping REPLY from "LPU64" md %p: can't allocate msg\n", 
+                       peer_nid, getmd);
+                goto drop;
+        }
+
+        if (getmd->eq) {
+                msg->ev.type = PTL_EVENT_REPLY;
+                msg->ev.initiator.nid = peer_nid;
+                msg->ev.initiator.pid = 0;      /* XXX FIXME!!! */
+                msg->ev.rlength = msg->ev.mlength = getmd->length;
+                msg->ev.offset = 0;
+
+                lib_md_deconstruct(nal, getmd, &msg->ev.mem_desc);
+        }
+
+        ni->counters.recv_count++;
+        ni->counters.recv_length += getmd->length;
+
+        state_unlock(nal, &flags);
+
+        return msg;
+        
+ drop:
+        nal->ni.counters.drop_count++;
+        nal->ni.counters.drop_length += getmd->length;
+
+        state_unlock (nal, &flags);
+
+        return NULL;
+}
 
 int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 {
@@ -1244,7 +1285,7 @@ int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
         hdr.src_nid  = HTON__u64 (ni->nid);
         hdr.dest_pid = HTON__u32 (id->pid);
         hdr.src_pid  = HTON__u32 (ni->pid);
-        PTL_HDR_LENGTH(&hdr) = 0;
+        hdr.payload_length = 0;
 
         /* NB handles only looked up by creator (no flips) */
         hdr.msg.get.return_wmd.wh_interface_cookie = ni->ni_interface_cookie;
@@ -1305,12 +1346,15 @@ int do_PtlGet(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 
 void lib_assert_wire_constants (void)
 {
-        /* Wire protocol assertions generated by 'wirecheck' */
+        /* Wire protocol assertions generated by 'wirecheck'
+         * running on Linux robert.bartonsoftware.com 2.4.20-18.9 #1 Thu May 29 06:54:41 EDT 2003 i68
+         * with gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) */
+
 
         /* Constants... */
         LASSERT (PORTALS_PROTO_MAGIC == 0xeebc0ded);
         LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        LASSERT (PORTALS_PROTO_VERSION_MINOR == 1);
+        LASSERT (PORTALS_PROTO_VERSION_MINOR == 3);
         LASSERT (PTL_MSG_ACK == 0);
         LASSERT (PTL_MSG_PUT == 1);
         LASSERT (PTL_MSG_GET == 2);
@@ -1318,79 +1362,77 @@ void lib_assert_wire_constants (void)
         LASSERT (PTL_MSG_HELLO == 4);
 
         /* Checks for struct ptl_handle_wire_t */
-        LASSERT (sizeof (ptl_handle_wire_t) == 16);
-        LASSERT (offsetof (ptl_handle_wire_t, wh_interface_cookie) == 0);
-        LASSERT (sizeof (((ptl_handle_wire_t *)0)->wh_interface_cookie) == 8);
-        LASSERT (offsetof (ptl_handle_wire_t, wh_object_cookie) == 8);
-        LASSERT (sizeof (((ptl_handle_wire_t *)0)->wh_object_cookie) == 8);
+        LASSERT ((int)sizeof(ptl_handle_wire_t) == 16);
+        LASSERT (offsetof(ptl_handle_wire_t, wh_interface_cookie) == 0);
+        LASSERT ((int)sizeof(((ptl_handle_wire_t *)0)->wh_interface_cookie) == 8);
+        LASSERT (offsetof(ptl_handle_wire_t, wh_object_cookie) == 8);
+        LASSERT ((int)sizeof(((ptl_handle_wire_t *)0)->wh_object_cookie) == 8);
 
         /* Checks for struct ptl_magicversion_t */
-        LASSERT (sizeof (ptl_magicversion_t) == 8);
-        LASSERT (offsetof (ptl_magicversion_t, magic) == 0);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->magic) == 4);
-        LASSERT (offsetof (ptl_magicversion_t, version_major) == 4);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->version_major) == 2);
-        LASSERT (offsetof (ptl_magicversion_t, version_minor) == 6);
-        LASSERT (sizeof (((ptl_magicversion_t *)0)->version_minor) == 2);
+        LASSERT ((int)sizeof(ptl_magicversion_t) == 8);
+        LASSERT (offsetof(ptl_magicversion_t, magic) == 0);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->magic) == 4);
+        LASSERT (offsetof(ptl_magicversion_t, version_major) == 4);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->version_major) == 2);
+        LASSERT (offsetof(ptl_magicversion_t, version_minor) == 6);
+        LASSERT ((int)sizeof(((ptl_magicversion_t *)0)->version_minor) == 2);
 
         /* Checks for struct ptl_hdr_t */
-        LASSERT (sizeof (ptl_hdr_t) == 72);
-        LASSERT (offsetof (ptl_hdr_t, dest_nid) == 0);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->dest_nid) == 8);
-        LASSERT (offsetof (ptl_hdr_t, src_nid) == 8);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->src_nid) == 8);
-        LASSERT (offsetof (ptl_hdr_t, dest_pid) == 16);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->dest_pid) == 4);
-        LASSERT (offsetof (ptl_hdr_t, src_pid) == 20);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->src_pid) == 4);
-        LASSERT (offsetof (ptl_hdr_t, type) == 24);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->type) == 4);
+        LASSERT ((int)sizeof(ptl_hdr_t) == 72);
+        LASSERT (offsetof(ptl_hdr_t, dest_nid) == 0);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->dest_nid) == 8);
+        LASSERT (offsetof(ptl_hdr_t, src_nid) == 8);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->src_nid) == 8);
+        LASSERT (offsetof(ptl_hdr_t, dest_pid) == 16);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->dest_pid) == 4);
+        LASSERT (offsetof(ptl_hdr_t, src_pid) == 20);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->src_pid) == 4);
+        LASSERT (offsetof(ptl_hdr_t, type) == 24);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->type) == 4);
+        LASSERT (offsetof(ptl_hdr_t, payload_length) == 28);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->payload_length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg) == 40);
 
         /* Ack */
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.mlength) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.mlength) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.dst_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.dst_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.ack.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.ack.length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.dst_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.dst_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.ack.mlength) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.ack.mlength) == 4);
 
         /* Put */
-        LASSERT (offsetof (ptl_hdr_t, msg.put.ptl_index) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.ptl_index) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.ack_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.ack_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.length) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.offset) == 60);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.put.hdr_data) == 64);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.put.hdr_data) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.ack_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.ack_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.hdr_data) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.hdr_data) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.ptl_index) == 64);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.ptl_index) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.put.offset) == 68);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.put.offset) == 4);
 
         /* Get */
-        LASSERT (offsetof (ptl_hdr_t, msg.get.ptl_index) == 28);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.ptl_index) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.return_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.return_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.match_bits) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.match_bits) == 8);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.length) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.src_offset) == 60);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.src_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.return_offset) == 64);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.return_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.get.sink_length) == 68);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.get.sink_length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.return_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.return_wmd) == 16);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.match_bits) == 48);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.match_bits) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.ptl_index) == 56);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.ptl_index) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.src_offset) == 60);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.src_offset) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.get.sink_length) == 64);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.get.sink_length) == 4);
 
         /* Reply */
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.dst_wmd) == 32);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.dst_wmd) == 16);
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.dst_offset) == 48);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.dst_offset) == 4);
-        LASSERT (offsetof (ptl_hdr_t, msg.reply.length) == 56);
-        LASSERT (sizeof (((ptl_hdr_t *)0)->msg.reply.length) == 4);
+        LASSERT (offsetof(ptl_hdr_t, msg.reply.dst_wmd) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.reply.dst_wmd) == 16);
+
+        /* Hello */
+        LASSERT (offsetof(ptl_hdr_t, msg.hello.incarnation) == 32);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.hello.incarnation) == 8);
+        LASSERT (offsetof(ptl_hdr_t, msg.hello.type) == 40);
+        LASSERT ((int)sizeof(((ptl_hdr_t *)0)->msg.hello.type) == 4);
 }
diff --git a/lustre/portals/portals/lib-msg.c b/lustre/portals/portals/lib-msg.c
index 9363251054ae662971c22d04df3919ef43d8337a..9840ff53d086ffd30d162a8d738d48a7bb8915a6 100644
--- a/lustre/portals/portals/lib-msg.c
+++ b/lustre/portals/portals/lib-msg.c
@@ -59,7 +59,7 @@ int lib_finalize(nal_cb_t * nal, void *private, lib_msg_t *msg)
                 ack.src_nid  = HTON__u64 (nal->ni.nid);
                 ack.dest_pid = HTON__u32 (msg->pid);
                 ack.src_pid  = HTON__u32 (nal->ni.pid);
-                PTL_HDR_LENGTH(&ack) = 0;
+                ack.payload_length = 0;
 
                 ack.msg.ack.dst_wmd = msg->ack_wmd;
                 ack.msg.ack.match_bits = msg->ev.match_bits;
diff --git a/lustre/portals/portals/lib-ni.c b/lustre/portals/portals/lib-ni.c
index aa30329dcd9a06160b4673f8f9d3bd88d2d8cbad..9e90576c29dd9d80ecfa889caa578d8d786c30f8 100644
--- a/lustre/portals/portals/lib-ni.c
+++ b/lustre/portals/portals/lib-ni.c
@@ -27,7 +27,7 @@
 #include <portals/lib-p30.h>
 #include <portals/arg-blocks.h>
 
-#define MAX_DIST 18446744073709551615UL
+#define MAX_DIST 18446744073709551615ULL
 
 int do_PtlNIDebug(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
 {
diff --git a/lustre/portals/router/router.c b/lustre/portals/router/router.c
index f0824157d5e1c2f14a202bbb8d574cb0df7d8bfd..e29f62877c1dccdd1c6e495aaf793e4d8e0d8a50 100644
--- a/lustre/portals/router/router.c
+++ b/lustre/portals/router/router.c
@@ -126,12 +126,16 @@ kpr_do_upcall (void *arg)
 void
 kpr_upcall (int gw_nalid, ptl_nid_t gw_nid, int alive, time_t when)
 {
+        char str[PTL_NALFMT_SIZE];
+        
         /* May be in arbitrary context */
         kpr_upcall_t  *u = kmalloc (sizeof (kpr_upcall_t), GFP_ATOMIC);
 
         if (u == NULL) {
-                CERROR ("Upcall out of memory: nal %d nid "LPX64" %s\n",
-                        gw_nalid, gw_nid, alive ? "up" : "down");
+                CERROR ("Upcall out of memory: nal %d nid "LPX64" (%s) %s\n",
+                        gw_nalid, gw_nid,
+                        portals_nid2str(gw_nalid, gw_nid, str),
+                        alive ? "up" : "down");
                 return;
         }
 
@@ -155,6 +159,7 @@ kpr_do_notify (int byNal, int gateway_nalid, ptl_nid_t gateway_nid,
         struct timeval       now;
 	struct list_head    *e;
 	struct list_head    *n;
+        char                 str[PTL_NALFMT_SIZE];
 
         CDEBUG (D_NET, "%s notifying [%d] "LPX64": %s\n", 
                 byNal ? "NAL" : "userspace", 
@@ -253,8 +258,9 @@ kpr_do_notify (int byNal, int gateway_nalid, ptl_nid_t gateway_nid,
         
         if (byNal) {
                 /* It wasn't userland that notified me... */
-                CWARN ("Upcall: NAL %d NID "LPX64" is %s\n",
+                CWARN ("Upcall: NAL %d NID "LPX64" (%s) is %s\n",
                        gateway_nalid, gateway_nid,
+                       portals_nid2str(gateway_nalid, gateway_nid, str),
                        alive ? "alive" : "dead");
                 kpr_upcall (gateway_nalid, gateway_nid, alive, when);
         } else {
@@ -580,8 +586,10 @@ kpr_add_route (int gateway_nalid, ptl_nid_t gateway_nid,
         atomic_set (&ge->kpge_weight, 0);
 
         PORTAL_ALLOC (re, sizeof (*re));
-        if (re == NULL)
+        if (re == NULL) {
+                PORTAL_FREE (ge, sizeof (*ge));
                 return (-ENOMEM);
+        }
 
         re->kpre_lo_nid = lo_nid;
         re->kpre_hi_nid = hi_nid;
diff --git a/lustre/portals/router/router.h b/lustre/portals/router/router.h
index c5cc1d3efdfb4a9f8595b9f68db6d4a0942f7b34..ea25439e9229bd61ed5864d05689be5c6a69d79c 100644
--- a/lustre/portals/router/router.h
+++ b/lustre/portals/router/router.h
@@ -23,7 +23,9 @@
 
 #ifndef _KPTLROUTER_H
 #define _KPTLROUTER_H
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -69,7 +71,7 @@ typedef struct
 
 typedef struct
 {
-        struct tq_struct        kpru_tq;
+        work_struct_t           kpru_tq;
         int                     kpru_nal_id;
         ptl_nid_t               kpru_nid;
         int                     kpru_alive;
diff --git a/lustre/portals/tests/ping_cli.c b/lustre/portals/tests/ping_cli.c
index 4d04ffbcbb8bfd8cd773da448ed170f35b7275fb..85c0d71dcd4ba67d0e6215d8fa1ae0c7afb8c778 100644
--- a/lustre/portals/tests/ping_cli.c
+++ b/lustre/portals/tests/ping_cli.c
@@ -91,14 +91,14 @@ static int pingcli_callback(ptl_event_t *ev)
         magic = *(int *)(ev->mem_desc.start + ev->offset);
 
         if(magic != 0xcafebabe) {
-                printk ("Unexpected response \n");
+                printk ("LustreError: Unexpected response \n");
                 return 1;
         }
 
         if((i == count) || !count)
                 wake_up_process (client->tsk);
         else
-                printk ("Received response after timeout for %d\n",i);
+                printk ("LustreError: Received response after timeout for %d\n",i);
         return 1;
 }
 
@@ -111,11 +111,15 @@ pingcli_start(struct portal_ioctl_data *args)
         unsigned ping_bulk_magic = PING_BULK_MAGIC;
         int rc;
         struct timeval tv1, tv2;
+        char str[PTL_NALFMT_SIZE];
+        
         client->tsk = current;
         client->args = args;
-        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64",  \
+        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64" (%s),  \
                         nal %d, size %u, count: %u, timeout: %u\n",
-                        args->ioc_nid, args->ioc_nal, args->ioc_size,
+                        args->ioc_nid,
+                        portals_nid2str(args->ioc_nal, args->ioc_nid, str),
+                        args->ioc_nal, args->ioc_size,
                         args->ioc_count, args->ioc_timeout);
 
 
@@ -229,15 +233,15 @@ pingcli_start(struct portal_ioctl_data *args)
                          pingcli_shutdown (1);
                          return NULL;
                 }
-                printk ("sent msg no %d", count);
+                printk ("Lustre: sent msg no %d", count);
 
                 set_current_state (TASK_INTERRUPTIBLE);
                 rc = schedule_timeout (20 * args->ioc_timeout);
                 if (rc == 0) {
-                        printk ("   ::  timeout .....\n");
+                        printk ("LustreError:   ::  timeout .....\n");
                 } else {
                         do_gettimeofday (&tv2);
-                        printk("   ::  Reply in %u usec\n",
+                        printk("Lustre:   ::  Reply in %u usec\n",
                                 (unsigned)((tv2.tv_sec - tv1.tv_sec)
                                  * 1000000 +  (tv2.tv_usec - tv1.tv_usec)));
                 }
diff --git a/lustre/portals/tests/ping_srv.c b/lustre/portals/tests/ping_srv.c
index 873e11ce312e84981f6eb8312e33dc54bddf09eb..2a96f5531df9636a007acf4fd661534f50495cbd 100644
--- a/lustre/portals/tests/ping_srv.c
+++ b/lustre/portals/tests/ping_srv.c
@@ -121,7 +121,7 @@ int pingsrv_thread(void *arg)
                 
                 
                 if(magic != 0xdeadbeef) {
-                        printk("Unexpected Packet to the server\n");
+                        printk("LustreError: Unexpected Packet to the server\n");
                         
                 } 
                 memcpy (server->in_buf, &ping_bulk_magic, sizeof(ping_bulk_magic));
@@ -183,7 +183,7 @@ static int pingsrv_callback(ptl_event_t *ev)
         }
         server->evnt = *ev;
         
-        printk ("received ping from nid "LPX64" "
+        printk ("Lustre: received ping from nid "LPX64" "
                "(off=%u rlen=%u mlen=%u head=%x seq=%d size=%d)\n",
                ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
                *((int *)(ev->mem_desc.start + ev->offset)),
diff --git a/lustre/portals/tests/sping_cli.c b/lustre/portals/tests/sping_cli.c
index 35e114b6af491e1f74f5aba1f0c752dc7fc219cf..64a1dd2ef660248cd94f2d31e5cd990d18a8129d 100644
--- a/lustre/portals/tests/sping_cli.c
+++ b/lustre/portals/tests/sping_cli.c
@@ -104,14 +104,17 @@ pingcli_start(struct portal_ioctl_data *args)
 {
         const ptl_handle_ni_t *nip;
         unsigned ping_head_magic = PING_HEADER_MAGIC;
+        char str[PTL_NALFMT_SIZE];
         int rc;
 
         client->tsk = current;
         client->args = args;
 
-        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64",  \
+        CDEBUG (D_OTHER, "pingcli_setup args: nid "LPX64" (%s),  \
                         nal %d, size %u, count: %u, timeout: %u\n",
-                        args->ioc_nid, args->ioc_nal, args->ioc_size,
+                        args->ioc_nid,
+                        portals_nid2str(args->ioc_nid, args->ioc_nal, str),
+                        args->ioc_nal, args->ioc_size,
                         args->ioc_count, args->ioc_timeout);
 
 
@@ -219,11 +222,11 @@ pingcli_start(struct portal_ioctl_data *args)
         set_current_state (TASK_INTERRUPTIBLE);
         rc = schedule_timeout (20 * args->ioc_timeout);
         if (rc == 0) {
-                printk (" Time out on the server\n");
+                printk ("LustreError: Time out on the server\n");
                 pingcli_shutdown (2);
                 return NULL;
         } else
-                printk("Received respose from the server \n");
+                printk("Lustre: Received respose from the server \n");
 
 
         pingcli_shutdown (2);
diff --git a/lustre/portals/tests/sping_srv.c b/lustre/portals/tests/sping_srv.c
index 2b45a46ff7a197d35d2b27e67a58c455b05fd2dc..0d52e1f1020f8ab71c7733e7c69ac2464e2a6099 100644
--- a/lustre/portals/tests/sping_srv.c
+++ b/lustre/portals/tests/sping_srv.c
@@ -175,7 +175,7 @@ static int pingsrv_callback(ptl_event_t *ev)
         }
         server->evnt = *ev;
         
-        printk ("received ping from nid "LPX64" "
+        printk ("Lustre: received ping from nid "LPX64" "
                "(off=%u rlen=%u mlen=%u head=%x)\n",
                ev->initiator.nid, ev->offset, ev->rlength, ev->mlength,
                *((int *)(ev->mem_desc.start + ev->offset)));
diff --git a/lustre/portals/tests/startclient.sh b/lustre/portals/tests/startclient.sh
index c9b7c166f3a5664736acd6d0b36402ad2c68e640..de01bc7ac8e040df880afb027feb2d5ce4d02c3d 100755
--- a/lustre/portals/tests/startclient.sh
+++ b/lustre/portals/tests/startclient.sh
@@ -29,9 +29,16 @@ case "$1" in
 		/sbin/insmod ./$PING
 		echo kqswnal > /tmp/nal
 	;;
+
+	gm)
+		/sbin/insmod  portals
+		/sbin/insmod kgmnal
+		/sbin/insmod ./$PING
+		echo kgmnal > /tmp/nal
+	;;
 	
 	*)
-		echo "Usage : ${0} < tcp | toe | elan >"
+		echo "Usage : ${0} < tcp | toe | elan | gm>"
 		exit 1;
 esac
 exit 0;
diff --git a/lustre/portals/tests/startserver.sh b/lustre/portals/tests/startserver.sh
index 942300efadf2aa2e866c9d7d43e6bbc5496e24de..4f66eeb908b0d3013331187c69eeaa918c8aaed0 100755
--- a/lustre/portals/tests/startserver.sh
+++ b/lustre/portals/tests/startserver.sh
@@ -29,9 +29,16 @@ case "$1" in
 		/sbin/insmod ./$PING nal=4
 		echo kqswnal > /tmp/nal
 	;;
+
+	gm)
+		/sbin/insmod  portals
+		/sbin/insmod kgmnal
+		/sbin/insmod ./$PING nal=3
+		echo kgmnal > /tmp/nal
+	;;
 	
 	*)
-		echo "Usage : ${0} < tcp | toe | elan >"
+		echo "Usage : ${0} < tcp | toe | elan | gm>"
 		exit 1;
 esac
 ../utils/acceptor 9999&
diff --git a/lustre/portals/unals/connection.c b/lustre/portals/unals/connection.c
index edd7c961a31ec21ee4813eb187c932cfb6fa14b4..3e64b330444cb16c7e42f73e48ab88ada1ddb65d 100644
--- a/lustre/portals/unals/connection.c
+++ b/lustre/portals/unals/connection.c
@@ -34,13 +34,21 @@
 #include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <portals/types.h>
+#include <portals/list.h>
+#include <portals/lib-types.h>
+#include <portals/socknal.h>
+#include <linux/kp30.h>
 #include <connection.h>
+#include <pthread.h>
 #include <errno.h>
-
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* global variable: acceptor port */
 unsigned short tcpnal_acceptor_port = 988;
@@ -55,9 +63,14 @@ unsigned short tcpnal_acceptor_port = 988;
  */
 static int compare_connection(void *arg1, void *arg2)
 {
-        connection c = arg1;
-        unsigned int * id = arg2;
-        return((c->ip==id[0]) && (c->port==id[1]));
+    connection c = arg1;
+    unsigned int * id = arg2;
+#if 0
+    return((c->ip==id[0]) && (c->port==id[1]));
+#else
+    /* CFS specific hacking */
+    return (c->ip == id[0]);
+#endif
 }
 
 
@@ -68,7 +81,12 @@ static int compare_connection(void *arg1, void *arg2)
  */
 static unsigned int connection_key(unsigned int *id)
 {
+#if 0
     return(id[0]^id[1]);
+#else
+    /* CFS specific hacking */
+    return (unsigned int) id[0];
+#endif
 }
 
 
@@ -102,22 +120,27 @@ int read_connection(connection c,
                     unsigned char *dest,
                     int len)
 {
-    int offset=0,rc;
+    int offset = 0,rc;
 
-    if (len){
+    if (len) {
         do {
-            if((rc=syscall(SYS_read, c->fd, dest+offset, len-offset))<=0){
-                if (errno==EINTR) {
-                    rc=0;
+#ifndef __CYGWIN__
+            rc = syscall(SYS_read, c->fd, dest+offset, len-offset);
+#else
+            rc = recv(c->fd, dest+offset, len-offset, 0);
+#endif
+            if (rc <= 0) {
+                if (errno == EINTR) {
+                    rc = 0;
                 } else {
                     remove_connection(c);
-                    return(0);
+                    return (0);
                 }
             }
-            offset+=rc;
-        } while (offset<len);
+            offset += rc;
+        } while (offset < len);
     }
-    return(1);
+    return (1);
 }
 
 static int connection_input(void *d)
@@ -172,10 +195,111 @@ static int new_connection(void *z)
     unsigned int nid=*((unsigned int *)&s.sin_addr);
     /* cfs specific hack */
     //unsigned short pid=s.sin_port;
+    pthread_mutex_lock(&m->conn_lock);
     allocate_connection(m,htonl(nid),0/*pid*/,fd);
+    pthread_mutex_unlock(&m->conn_lock);
     return(1);
 }
 
+/* FIXME assuming little endian, cleanup!! */
+#define __cpu_to_le64(x) ((__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(x))
+#define __cpu_to_le32(x) ((__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(x))
+#define __cpu_to_le16(x) ((__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(x))
+
+extern ptl_nid_t tcpnal_mynid;
+
+int
+tcpnal_hello (int sockfd, ptl_nid_t *nid, int type, __u64 incarnation)
+{
+        int                 rc;
+        ptl_hdr_t           hdr;
+        ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
+
+        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
+
+        memset (&hdr, 0, sizeof (hdr));
+        hmv->magic         = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
+        hmv->version_major = __cpu_to_le32 (PORTALS_PROTO_VERSION_MAJOR);
+        hmv->version_minor = __cpu_to_le32 (PORTALS_PROTO_VERSION_MINOR);
+        
+        hdr.src_nid = __cpu_to_le64 (tcpnal_mynid);
+        hdr.type    = __cpu_to_le32 (PTL_MSG_HELLO);
+
+        hdr.msg.hello.type = __cpu_to_le32 (type);
+        hdr.msg.hello.incarnation = 0;
+
+        /* Assume sufficient socket buffering for this message */
+        rc = syscall(SYS_write, sockfd, &hdr, sizeof(hdr));
+        if (rc <= 0) {
+                CERROR ("Error %d sending HELLO to %llx\n", rc, *nid);
+                return (rc);
+        }
+
+        rc = syscall(SYS_read, sockfd, hmv, sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading HELLO from %llx\n", rc, *nid);
+                return (rc);
+        }
+        
+        if (hmv->magic != __le32_to_cpu (PORTALS_PROTO_MAGIC)) {
+                CERROR ("Bad magic %#08x (%#08x expected) from %llx\n",
+                        __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC, *nid);
+                return (-EPROTO);
+        }
+
+        if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
+            hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
+                CERROR ("Incompatible protocol version %d.%d (%d.%d expected)"
+                        " from %llx\n",
+                        __le16_to_cpu (hmv->version_major),
+                        __le16_to_cpu (hmv->version_minor),
+                        PORTALS_PROTO_VERSION_MAJOR,
+                        PORTALS_PROTO_VERSION_MINOR,
+                        *nid);
+                return (-EPROTO);
+        }
+
+#if (PORTALS_PROTO_VERSION_MAJOR != 0)
+# error "This code only understands protocol version 0.x"
+#endif
+        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
+         * so read the rest of it in now... */
+
+        rc = syscall(SYS_read, sockfd, hmv + 1, sizeof(hdr) - sizeof(*hmv));
+        if (rc <= 0) {
+                CERROR ("Error %d reading rest of HELLO hdr from %llx\n",
+                        rc, *nid);
+                return (rc);
+        }
+
+        /* ...and check we got what we expected */
+        if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
+            hdr.payload_length != __cpu_to_le32 (0)) {
+                CERROR ("Expecting a HELLO hdr with 0 payload,"
+                        " but got type %d with %d payload from %llx\n",
+                        __le32_to_cpu (hdr.type),
+                        __le32_to_cpu (hdr.payload_length), *nid);
+                return (-EPROTO);
+        }
+
+        if (__le64_to_cpu(hdr.src_nid) == PTL_NID_ANY) {
+                CERROR("Expecting a HELLO hdr with a NID, but got PTL_NID_ANY\n");
+                return (-EPROTO);
+        }
+
+        if (*nid == PTL_NID_ANY) {              /* don't know peer's nid yet */
+                *nid = __le64_to_cpu(hdr.src_nid);
+        } else if (*nid != __le64_to_cpu (hdr.src_nid)) {
+                CERROR ("Connected to nid %llx, but expecting %llx\n",
+                        __le64_to_cpu (hdr.src_nid), *nid);
+                return (-EPROTO);
+        }
+
+        return (0);
+}
 
 /* Function:  force_tcp_connection
  * Arguments: t: tcpnal
@@ -187,17 +311,22 @@ connection force_tcp_connection(manager m,
                                 unsigned int ip,
                                 unsigned short port)
 {
-    connection c;
+    connection conn;
     struct sockaddr_in addr;
     unsigned int id[2];
 
     port = tcpnal_acceptor_port;
 
-    id[0]=ip;
-    id[1]=port;
+    id[0] = ip;
+    id[1] = port;
 
-    if (!(c=hash_table_find(m->connections,id))){
+    pthread_mutex_lock(&m->conn_lock);
+
+    conn = hash_table_find(m->connections, id);
+    if (!conn) {
         int fd;
+        int option;
+        ptl_nid_t peernid = PTL_NID_ANY;
 
         bzero((char *) &addr, sizeof(addr));
         addr.sin_family      = AF_INET;
@@ -208,16 +337,30 @@ connection force_tcp_connection(manager m,
             perror("tcpnal socket failed");
             exit(-1);
         }
-        if (connect(fd,
-                    (struct sockaddr *)&addr,
-                    sizeof(struct sockaddr_in)))
-            {
-                perror("tcpnal connect");
-                return(0);
-            }
-        return(allocate_connection(m,ip,port,fd));
+        if (connect(fd, (struct sockaddr *)&addr,
+                    sizeof(struct sockaddr_in))) {
+            perror("tcpnal connect");
+            return(0);
+        }
+
+#if 1
+        option = 1;
+        setsockopt(fd, SOL_TCP, TCP_NODELAY, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
+        option = 1<<20;
+        setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
+#endif
+   
+        /* say hello */
+        if (tcpnal_hello(fd, &peernid, SOCKNAL_CONN_ANY, 0))
+            exit(-1);
+
+        conn = allocate_connection(m, ip, port, fd);
     }
-    return(c);
+
+    pthread_mutex_unlock(&m->conn_lock);
+    return (conn);
 }
 
 
@@ -243,8 +386,8 @@ static int bind_socket(manager m,unsigned short port)
     bzero((char *) &addr, sizeof(addr));
     addr.sin_family      = AF_INET;
     addr.sin_addr.s_addr = 0;
-    addr.sin_port        = port; 
-    
+    addr.sin_port        = htons(port);
+
     if (bind(m->bound,(struct sockaddr *)&addr,alen)<0){
         perror ("tcpnal bind"); 
         return(0);
@@ -284,11 +427,15 @@ manager init_connections(unsigned short pid,
                          int (*input)(void *, void *),
                          void *a)
 {
-    manager m=(manager)malloc(sizeof(struct manager));
-    m->connections=hash_create_table(compare_connection,connection_key);
-    m->handler=input;
-    m->handler_arg=a;
-    if (bind_socket(m,pid)) return(m);
+    manager m = (manager)malloc(sizeof(struct manager));
+    m->connections = hash_create_table(compare_connection,connection_key);
+    m->handler = input;
+    m->handler_arg = a;
+    pthread_mutex_init(&m->conn_lock, 0);
+
+    if (bind_socket(m,pid))
+        return(m);
+
     free(m);
     return(0);
 }
diff --git a/lustre/portals/unals/connection.h b/lustre/portals/unals/connection.h
index 6f572874a4ebd100a44038f52b6d74b037d87e04..fb1eaabd0e99d4bf1133e601758c7c772c21630e 100644
--- a/lustre/portals/unals/connection.h
+++ b/lustre/portals/unals/connection.h
@@ -10,6 +10,7 @@
 
 typedef struct manager {
     table connections;
+    pthread_mutex_t conn_lock; /* protect connections table */
     int bound;
     io_handler bound_handler;
     int (*handler)(void *, void *);
diff --git a/lustre/portals/unals/procapi.c b/lustre/portals/unals/procapi.c
index f4820b26ca38251b71d6f25fb7b0962aaca970c4..2a3fbd881a514ca79f1282250187a700eb108694 100644
--- a/lustre/portals/unals/procapi.c
+++ b/lustre/portals/unals/procapi.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,7 +32,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <pqtimer.h>
 #include <dispatch.h>
@@ -48,35 +48,22 @@
  * forwards a packaged api call from the 'api' side to the 'library'
  *   side, and collects the result
  */
-#define forward_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(PTL_SEGV);\
-       }
-static int procbridge_forward(nal_t *n, int id, void *args, ptl_size_t args_len,
+static int procbridge_forward(nal_t *n, int id, void *args, size_t args_len,
 			      void *ret, ptl_size_t ret_len)
 {
-    bridge b=(bridge)n->nal_data;
-    procbridge p=(procbridge)b->local;
-    int lib=p->to_lib[1];
-    int k;
+    bridge b = (bridge) n->nal_data;
 
-    forward_failure(write,lib, &id, sizeof(id));
-    forward_failure(write,lib,&args_len, sizeof(args_len));
-    forward_failure(write,lib,&ret_len, sizeof(ret_len));
-    forward_failure(write,lib,args, args_len);
-
-    do {
-        k=syscall(SYS_read, p->from_lib[0], ret, ret_len);
-    } while ((k!=ret_len) && (errno += EINTR));
+    if (id == PTL_FINI) {
+            lib_fini(b->nal_cb);
 
-    if(k!=ret_len){
-        perror("nal: read return block");
-        return PTL_SEGV;
+            if (b->shutdown)
+                (*b->shutdown)(b);
     }
+
+    lib_dispatch(b->nal_cb, NULL, id, args, ret);
+
     return (PTL_OK);
 }
-#undef forward_failure
 
 
 /* Function: shutdown
@@ -90,15 +77,18 @@ static int procbridge_shutdown(nal_t *n, int ni)
 {
     bridge b=(bridge)n->nal_data;
     procbridge p=(procbridge)b->local;
-    int code=PTL_FINI;
 
-    syscall(SYS_write, p->to_lib[1],&code,sizeof(code));
-    syscall(SYS_read, p->from_lib[0],&code,sizeof(code));
+    p->nal_flags |= NAL_FLAG_STOPPING;
 
-    syscall(SYS_close, p->to_lib[0]);
-    syscall(SYS_close, p->to_lib[1]);
-    syscall(SYS_close, p->from_lib[0]);
-    syscall(SYS_close, p->from_lib[1]);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & NAL_FLAG_STOPPED) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
 
     free(p);
     return(0);
@@ -108,7 +98,7 @@ static int procbridge_shutdown(nal_t *n, int ni)
 /* Function: validate
  *    useless stub
  */
-static int procbridge_validate(nal_t *nal, void *base, ptl_size_t extent)
+static int procbridge_validate(nal_t *nal, void *base, size_t extent)
 {
     return(0);
 }
@@ -151,7 +141,9 @@ static nal_t api_nal = {
     unlock:   procbridge_unlock
 };
 
-/* Function: bridge_init
+ptl_nid_t tcpnal_mynid;
+
+/* Function: procbridge_interface
  *
  * Arguments:  pid: requested process id (port offset)
  *                  PTL_ID_ANY not supported.
@@ -165,77 +157,17 @@ static nal_t api_nal = {
  * initializes the tcp nal. we define unix_failure as an
  * error wrapper to cut down clutter.
  */
-#define unix_failure(operand,fd,buffer,length,text)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          perror(text);\
-          return(NULL);\
-       }
-#if 0
-static nal_t *bridge_init(ptl_interface_t nal,
-                          ptl_pid_t pid_request,
-                          ptl_ni_limits_t *desired,
-                          ptl_ni_limits_t *actual,
-                          int *rc)
-{
-    procbridge p;
-    bridge b;
-    static int initialized=0;
-    ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-
-    if(initialized) return (&api_nal);
-
-    init_unix_timer();
-
-    b=(bridge)malloc(sizeof(struct bridge));
-    p=(procbridge)malloc(sizeof(struct procbridge));
-    api_nal.nal_data=b;
-    b->local=p;
-
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
-    if (desired) limits = *desired;
-    unix_failure(write,p->to_lib[1], &pid_request, sizeof(pid_request),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal, sizeof(ptl_interface_t),
-                       "nal_init: write");
-
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
-        perror("nal_init: pthread_create");
-        return(NULL);
-    }
-
-    unix_failure(read,p->from_lib[0], actual, sizeof(ptl_ni_limits_t),
-                 "tcp_init: read");
-    unix_failure(read,p->from_lib[0], rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(*rc) return(NULL);
-
-    initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
-
-    return (&api_nal);
-}
-#endif
-
-ptl_nid_t tcpnal_mynid;
-
 nal_t *procbridge_interface(int num_interface,
                             ptl_pt_index_t ptl_size,
                             ptl_ac_index_t acl_size,
                             ptl_pid_t requested_pid)
 {
+    nal_init_args_t args;
     procbridge p;
     bridge b;
     static int initialized=0;
     ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
-    int rc, nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
+    int nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
 
     if(initialized) return (&api_nal);
 
@@ -246,38 +178,42 @@ nal_t *procbridge_interface(int num_interface,
     api_nal.nal_data=b;
     b->local=p;
 
-    if(pipe(p->to_lib) || pipe(p->from_lib)) {
-        perror("nal_init: pipe");
-        return(NULL);
-    }
-
     if (ptl_size)
 	    limits.max_ptable_index = ptl_size;
     if (acl_size)
 	    limits.max_atable_index = acl_size;
 
-    unix_failure(write,p->to_lib[1], &requested_pid, sizeof(requested_pid),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
-                       "nal_init: write");
-    unix_failure(write,p->to_lib[1], &nal_type, sizeof(nal_type),
-                       "nal_init: write");
+    args.nia_requested_pid = requested_pid;
+    args.nia_limits = &limits;
+    args.nia_nal_type = nal_type;
+    args.nia_bridge = b;
 
-    if(pthread_create(&p->t, NULL, nal_thread, b)) {
+    /* init procbridge */
+    pthread_mutex_init(&p->mutex,0);
+    pthread_cond_init(&p->cond, 0);
+    p->nal_flags = 0;
+    pthread_mutex_init(&p->nal_cb_lock, 0);
+
+    if (pthread_create(&p->t, NULL, nal_thread, &args)) {
         perror("nal_init: pthread_create");
         return(NULL);
     }
 
-    unix_failure(read,p->from_lib[0], &rc, sizeof(rc),
-                 "nal_init: read");
-
-    if(rc) return(NULL);
+    do {
+        pthread_mutex_lock(&p->mutex);
+        if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
+                pthread_mutex_unlock(&p->mutex);
+                break;
+        }
+        pthread_cond_wait(&p->cond, &p->mutex);
+        pthread_mutex_unlock(&p->mutex);
+    } while (1);
+
+    if (p->nal_flags & NAL_FLAG_STOPPED)
+        return (NULL);
 
     b->nal_cb->ni.nid = tcpnal_mynid;
     initialized = 1;
-    pthread_mutex_init(&p->mutex,0);
-    pthread_cond_init(&p->cond, 0);
 
     return (&api_nal);
 }
-#undef unix_failure
diff --git a/lustre/portals/unals/procbridge.h b/lustre/portals/unals/procbridge.h
index 060ae7b2b937ae52a20e88f55165efc9b4dc6be0..317e22f876149687c944521deee997ae523cac43 100644
--- a/lustre/portals/unals/procbridge.h
+++ b/lustre/portals/unals/procbridge.h
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
  */
@@ -14,14 +15,28 @@
 #include <ipmap.h>
 
 
+#define NAL_FLAG_RUNNING        1
+#define NAL_FLAG_STOPPING       2
+#define NAL_FLAG_STOPPED        4
+
 typedef struct procbridge {
+    /* sync between user threads and nal thread */
     pthread_t t;
     pthread_cond_t cond;
     pthread_mutex_t mutex;
-    int to_lib[2];
-    int from_lib[2];
+
+    int nal_flags;
+
+    pthread_mutex_t nal_cb_lock;
 } *procbridge;
 
+typedef struct nal_init_args {
+    ptl_pid_t        nia_requested_pid;
+    ptl_ni_limits_t *nia_limits;
+    int              nia_nal_type;
+    bridge           nia_bridge;
+} nal_init_args_t;
+
 extern void *nal_thread(void *);
 
 
@@ -33,8 +48,8 @@ extern void *nal_thread(void *);
 
 extern void set_address(bridge t,ptl_pid_t pidrequest);
 extern nal_t *procbridge_interface(int num_interface,
-                            ptl_pt_index_t ptl_size,
-                            ptl_ac_index_t acl_size,
-                            ptl_pid_t requested_pid);
+                                   ptl_pt_index_t ptl_size,
+                                   ptl_ac_index_t acl_size,
+                                   ptl_pid_t requested_pid);
 
 #endif
diff --git a/lustre/portals/unals/proclib.c b/lustre/portals/unals/proclib.c
index 99afe66ced9535aa39f3485fa7f9c9878cf20343..2627253d51c76f5fd61f11a3afc7952b18009078 100644
--- a/lustre/portals/unals/proclib.c
+++ b/lustre/portals/unals/proclib.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -31,14 +32,12 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <procbridge.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <errno.h>
 #include <timer.h>
-//#include <util/pqtimer.h>
 #include <dispatch.h>
 
 /* the following functions are stubs to satisfy the nal definition
@@ -48,7 +47,7 @@ static int nal_write(nal_cb_t *nal,
                      void *private,
                      user_ptr dst_addr,
                      void *src_addr,
-                     ptl_size_t len)
+                     size_t len)
 {
     memcpy(dst_addr, src_addr, len);
     return 0;
@@ -65,7 +64,7 @@ static int nal_read(nal_cb_t * nal,
 }
 
 static void *nal_malloc(nal_cb_t *nal,
-                        ptl_size_t len)
+                        size_t len)
 {
     void *buf =  malloc(len);
     return buf;
@@ -73,7 +72,7 @@ static void *nal_malloc(nal_cb_t *nal,
 
 static void nal_free(nal_cb_t *nal,
                      void *buf,
-                     ptl_size_t len)
+                     size_t len)
 {
     free(buf);
 }
@@ -93,12 +92,20 @@ static void nal_printf(nal_cb_t *nal,
 static void nal_cli(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge) nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_lock(&p->nal_cb_lock);
 }
 
 
 static void nal_sti(nal_cb_t *nal,
                     unsigned long *flags)
 {
+    bridge b = (bridge)nal->nal_data;
+    procbridge p = (procbridge) b->local;
+
+    pthread_mutex_unlock(&p->nal_cb_lock);
 }
 
 
@@ -108,69 +115,22 @@ static int nal_dist(nal_cb_t *nal,
 {
     return 0;
 }
-    
-
-
-/* Function:  data_from_api
- * Arguments: t: the nal state for this interface
- * Returns: whether to continue reading from the pipe
- *
- *   data_from_api() reads data from the api side in response
- *   to a select.
- *
- *   We define data_failure() for syntactic convenience
- *   of unix error reporting.
- */
-
-#define data_failure(operand,fd,buffer,length)\
-       if(syscall(SYS_##operand,fd,buffer,length)!=length){\
-          lib_fini(b->nal_cb);\
-          return(0);\
-       }
-static int data_from_api(void *arg)
-{
-        bridge b = arg;
-    procbridge p=(procbridge)b->local;
-    /* where are these two sizes derived from ??*/
-    char arg_block[ 256 ];
-    char ret_block[ 128 ];
-    ptl_size_t arg_len,ret_len;
-    int fd=p->to_lib[0];
-    int index;
-
-    data_failure(read,fd, &index, sizeof(index));
-
-    if (index==PTL_FINI) {
-        lib_fini(b->nal_cb);
-        if (b->shutdown) (*b->shutdown)(b);
-        syscall(SYS_write, p->from_lib[1],&b->alive,sizeof(b->alive));
-
-        /* a heavy-handed but convenient way of shutting down
-           the lower side thread */
-        pthread_exit(0);
-    }
-
-    data_failure(read,fd, &arg_len, sizeof(arg_len));
-    data_failure(read,fd, &ret_len, sizeof(ret_len));
-    data_failure(read,fd, arg_block, arg_len);
-
-    lib_dispatch(b->nal_cb, NULL, index, arg_block, ret_block);
-
-    data_failure(write,p->from_lib[1],ret_block, ret_len);
-    return(1);
-}
-#undef data_failure
-
-
 
 static void wakeup_topside(void *z)
 {
-    bridge b=z;
-    procbridge p=b->local;
+    bridge b = z;
+    procbridge p = b->local;
+    int stop;
 
     pthread_mutex_lock(&p->mutex);
+    stop = p->nal_flags & NAL_FLAG_STOPPING;
+    if (stop)
+        p->nal_flags |= NAL_FLAG_STOPPED;
     pthread_cond_broadcast(&p->cond);
     pthread_mutex_unlock(&p->mutex);
+
+    if (stop)
+        pthread_exit(0);
 }
 
 
@@ -195,7 +155,8 @@ nal_initialize nal_table[PTL_IFACE_MAX]={0,tcpnal_init,0};
 
 void *nal_thread(void *z)
 {
-    bridge b=z;
+    nal_init_args_t *args = (nal_init_args_t *) z;
+    bridge b = args->nia_bridge;
     procbridge p=b->local;
     int rc;
     ptl_pid_t pid_request;
@@ -216,15 +177,9 @@ void *nal_thread(void *z)
     b->nal_cb->cb_sti=nal_sti;
     b->nal_cb->cb_dist=nal_dist;
 
-
-    register_io_handler(p->to_lib[0],READ_HANDLER,data_from_api,(void *)b);
-
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &pid_request, sizeof(pid_request))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &desired, sizeof(ptl_ni_limits_t))))
-        perror("procbridge read from api");
-    if(!(rc = syscall(SYS_read, p->to_lib[0], &nal_type, sizeof(nal_type))))
-        perror("procbridge read from api");
+    pid_request = args->nia_requested_pid;
+    desired = *args->nia_limits;
+    nal_type = args->nia_nal_type;
 
     actual = desired;
     LIMIT(desired.max_match_entries,actual.max_match_entries,MAX_MES);
@@ -251,12 +206,12 @@ void *nal_thread(void *z)
      * it is non-zero since something went wrong.
      */
     /* this should perform error checking */
-#if 0
-    write(p->from_lib[1], &actual, sizeof(ptl_ni_limits_t));
-#endif
-    syscall(SYS_write, p->from_lib[1], &rc, sizeof(rc));
-    
-    if(!rc) {
+    pthread_mutex_lock(&p->mutex);
+    p->nal_flags |= rc ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
+    pthread_cond_broadcast(&p->cond);
+    pthread_mutex_unlock(&p->mutex);
+
+    if (!rc) {
         /* the thunk function is called each time the timer loop
            performs an operation and returns to blocking mode. we
            overload this function to inform the api side that
@@ -267,4 +222,3 @@ void *nal_thread(void *z)
     return(0);
 }
 #undef LIMIT
-
diff --git a/lustre/portals/unals/select.c b/lustre/portals/unals/select.c
index 47adc50490749c24168a043e0fabf48315739853..fe24efcf3cf8066192cd6cc41963969a369ad659 100644
--- a/lustre/portals/unals/select.c
+++ b/lustre/portals/unals/select.c
@@ -97,9 +97,9 @@ void remove_io_handler (io_handler i)
 
 static void set_flag(io_handler n,fd_set *fds)
 {
-    if (n->type & READ_HANDLER) FD_SET(n->fd,fds);
-    if (n->type & WRITE_HANDLER) FD_SET(n->fd,fds+1);
-    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd,fds+2);
+    if (n->type & READ_HANDLER) FD_SET(n->fd, &fds[0]);
+    if (n->type & WRITE_HANDLER) FD_SET(n->fd,&fds[1]);
+    if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd, &fds[2]);
 }
 
 
@@ -126,9 +126,18 @@ void select_timer_block(when until)
         timeout_pointer=&timeout;
     } else timeout_pointer=0;
 
-    FD_ZERO(fds);
-    FD_ZERO(fds+1);
-    FD_ZERO(fds+2);
+
+    /* FIXME
+     * temporarily add timer for endless waiting problem.
+     * FIXME
+     */
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    timeout_pointer=&timeout;
+
+    FD_ZERO(&fds[0]);
+    FD_ZERO(&fds[1]);
+    FD_ZERO(&fds[2]);
     for (k=&io_handlers;*k;){
         if ((*k)->disabled){
             j=*k;
@@ -140,14 +149,15 @@ void select_timer_block(when until)
 	    k=&(*k)->next;
 	}
     }
-    result=select(FD_SETSIZE,fds,fds+1,fds+2,timeout_pointer);
+
+    result=select(FD_SETSIZE, &fds[0], &fds[1], &fds[2], timeout_pointer);
 
     if (result > 0)
         for (j=io_handlers;j;j=j->next){
             if (!(j->disabled) && 
-                ((FD_ISSET(j->fd,fds) && (j->type & READ_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+1) && (j->type & WRITE_HANDLER)) ||
-                 (FD_ISSET(j->fd,fds+2) && (j->type & EXCEPTION_HANDLER)))){
+                ((FD_ISSET(j->fd, &fds[0]) && (j->type & READ_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[1]) && (j->type & WRITE_HANDLER)) ||
+                 (FD_ISSET(j->fd, &fds[2]) && (j->type & EXCEPTION_HANDLER)))){
                 if (!(*j->function)(j->argument))
                     j->disabled=1;
             }
diff --git a/lustre/portals/unals/tcpnal.c b/lustre/portals/unals/tcpnal.c
index d6b5ed08645f135276623ff6ab3ccf25790a8088..1041d1d7870bc6ccaac05b340e881a0bc5547f16 100644
--- a/lustre/portals/unals/tcpnal.c
+++ b/lustre/portals/unals/tcpnal.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (c) 2002 Cray Inc.
+ *  Copyright (c) 2003 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -27,7 +28,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <syscall.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -36,6 +36,11 @@
 #include <bridge.h>
 #include <ipmap.h>
 #include <connection.h>
+#include <pthread.h>
+#include <errno.h>
+#ifndef __CYGWIN__
+#include <syscall.h>
+#endif
 
 /* Function:  tcpnal_send
  * Arguments: nal:     pointer to my nal control block
@@ -50,7 +55,6 @@
  *
  * sends a packet to the peer, after insuring that a connection exists
  */
-#warning FIXME: "param 'type' is newly added, make use of it!!"
 int tcpnal_send(nal_cb_t *n,
 		void *private,
 		lib_msg_t *cookie,
@@ -64,8 +68,11 @@ int tcpnal_send(nal_cb_t *n,
 {
     connection c;
     bridge b=(bridge)n->nal_data;
-    struct iovec tiov[2];
-    int count = 1;
+    struct iovec tiov[257];
+    static pthread_mutex_t send_lock = PTHREAD_MUTEX_INITIALIZER;
+    int   rc;
+    int   total;
+    int i;
 
     if (!(c=force_tcp_connection((manager)b->lower,
                                  PNAL_IP(nid,b),
@@ -83,18 +90,46 @@ int tcpnal_send(nal_cb_t *n,
     LASSERT (niov <= 1);
     if (len) syscall(SYS_write, c->fd,iov[0].iov_base,len);
 #else
-    LASSERT (niov <= 1);
+    LASSERT (niov <= 256);
 
     tiov[0].iov_base = hdr;
     tiov[0].iov_len = sizeof(ptl_hdr_t);
 
-    if (len) {
-            tiov[1].iov_base = iov[0].iov_base;
-            tiov[1].iov_len = len;
-            count++;
+    if (niov > 0)
+            memcpy(&tiov[1], iov, niov * sizeof(struct iovec));
+    pthread_mutex_lock(&send_lock);
+#if 1
+    for (i = total = 0; i <= niov; i++)
+            total += tiov[i].iov_len;
+    
+    rc = syscall(SYS_writev, c->fd, tiov, niov+1);
+    if (rc != total) {
+            fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                     rc, total, errno);
+            abort();
     }
-
-    syscall(SYS_writev, c->fd, tiov, count);
+#else
+    for (i = total = 0; i <= niov; i++) {
+            rc = send(c->fd, tiov[i].iov_base, tiov[i].iov_len, 0);
+            
+            if (rc != tiov[i].iov_len) {
+                    fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
+                             rc, tiov[i].iov_len, errno);
+                    abort();
+            }
+            total != rc;
+    }
+#endif
+#if 0
+    fprintf (stderr, "sent %s total %d in %d frags\n", 
+             hdr->type == PTL_MSG_ACK ? "ACK" :
+             hdr->type == PTL_MSG_PUT ? "PUT" :
+             hdr->type == PTL_MSG_GET ? "GET" :
+             hdr->type == PTL_MSG_REPLY ? "REPLY" :
+             hdr->type == PTL_MSG_HELLO ? "HELLO" : "UNKNOWN",
+             total, niov + 1);
+#endif
+    pthread_mutex_unlock(&send_lock);
 #endif
     lib_finalize(n, private, cookie);
         
@@ -120,15 +155,29 @@ int tcpnal_recv(nal_cb_t *n,
 		lib_msg_t *cookie,
                 unsigned int niov,
                 struct iovec *iov,
-		ptl_size_t mlen,
-		ptl_size_t rlen)
+		size_t mlen,
+		size_t rlen)
 
 {
-    if (mlen) {
-        LASSERT (niov <= 1);
-        read_connection(private,iov[0].iov_base,mlen);
-        lib_finalize(n, private, cookie);
-    }
+    int i;
+
+    if (!niov)
+            goto finalize;
+
+    LASSERT(mlen);
+    LASSERT(rlen);
+    LASSERT(rlen >= mlen);
+
+    /* FIXME
+     * 1. Is this effecient enough? change to use readv() directly?
+     * 2. need check return from read_connection()
+     * - MeiJia
+     */
+    for (i = 0; i < niov; i++)
+        read_connection(private, iov[i].iov_base, iov[i].iov_len);
+
+finalize:
+    lib_finalize(n, private, cookie);
 
     if (mlen!=rlen){
         char *trash=malloc(rlen-mlen);
@@ -153,15 +202,15 @@ int tcpnal_recv(nal_cb_t *n,
  */
 static int from_connection(void *a, void *d)
 {
-        connection c = d;
-        bridge b=a;
-        ptl_hdr_t hdr;
-
-        if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
-                lib_parse(b->nal_cb, &hdr, c);
-                return(1);
-        }
-        return(0);
+    connection c = d;
+    bridge b = a;
+    ptl_hdr_t hdr;
+
+    if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
+        lib_parse(b->nal_cb, &hdr, c);
+        return(1);
+    }
+    return(0);
 }
 
 
diff --git a/lustre/portals/utils/.cvsignore b/lustre/portals/utils/.cvsignore
index 8e474adcd884083fbc900a3d73f5dc12107a6d35..e2a0d447ef8b2d66b880b1c76c8c02170a27e597 100644
--- a/lustre/portals/utils/.cvsignore
+++ b/lustre/portals/utils/.cvsignore
@@ -6,4 +6,5 @@ ptlctl
 .deps
 routerstat
 wirecheck
+gmnalnid
 .*.cmd
diff --git a/lustre/portals/utils/Makefile.am b/lustre/portals/utils/Makefile.am
index 05af5983f2b3a7572e137e3b7e78e0f572bd071e..f1878df2279c359d0afae30970f37da55fe14318 100644
--- a/lustre/portals/utils/Makefile.am
+++ b/lustre/portals/utils/Makefile.am
@@ -4,10 +4,16 @@
 # See the file COPYING in this distribution
 
 
-COMPILE = gcc -Wall -g -I$(srcdir)/../include 
-LINK = gcc -o $@
+COMPILE = $(CC) -Wall -g -I$(srcdir)/../include
+LINK = $(CC) -o $@
 
-sbin_PROGRAMS = acceptor ptlctl debugctl routerstat wirecheck
+if LIBLUSTRE
+tmp=
+else
+tmp=gmnalnid
+endif
+
+sbin_PROGRAMS = acceptor ptlctl debugctl routerstat wirecheck $(tmp)
 lib_LIBRARIES = libptlctl.a
 
 acceptor_SOURCES = acceptor.c # -lefence
@@ -16,6 +22,8 @@ wirecheck_SOURCES = wirecheck.c
 
 libptlctl_a_SOURCES = portals.c debug.c l_ioctl.c parser.c parser.h
 
+gmnalnid_SOURCES = gmnalnid.c
+
 ptlctl_SOURCES = ptlctl.c
 ptlctl_LDADD =  -L. -lptlctl -lncurses # -lefence
 ptlctl_DEPENDENCIES = libptlctl.a
diff --git a/lustre/portals/utils/acceptor.c b/lustre/portals/utils/acceptor.c
index c6590db7528211f9b2cea603770e6ec9efccad5a..29b8d1e52cfafce441c20357a0d5eb8f0acf1fb0 100644
--- a/lustre/portals/utils/acceptor.c
+++ b/lustre/portals/utils/acceptor.c
@@ -19,6 +19,7 @@
 #include <portals/api-support.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
+#include <portals/socknal.h>
 
 /* should get this from autoconf somehow */
 #ifndef PIDFILE_DIR
@@ -100,7 +101,7 @@ parse_size (int *sizep, char *str)
 }
 
 void
-show_connection (int fd, __u32 net_ip, ptl_nid_t nid)
+show_connection (int fd, __u32 net_ip)
 {
         struct hostent *h = gethostbyaddr ((char *)&net_ip, sizeof net_ip, AF_INET);
         __u32 host_ip = ntohl (net_ip);
@@ -128,136 +129,8 @@ show_connection (int fd, __u32 net_ip, ptl_nid_t nid)
         else
                 snprintf (host, sizeof(host), "%s", h->h_name);
                 
-        syslog (LOG_INFO, "Accepted host: %s NID: "LPX64" snd: %d rcv %d nagle: %s\n", 
-                 host, nid, txmem, rxmem, nonagle ? "disabled" : "enabled");
-}
-
-int
-sock_write (int cfd, void *buffer, int nob)
-{
-        while (nob > 0)
-        {
-                int rc = write (cfd, buffer, nob);
-
-                if (rc < 0)
-                {
-                        if (errno == EINTR)
-                                continue;
-                        
-                        return (rc);
-                }
-
-                if (rc == 0)
-                {
-                        fprintf (stderr, "Unexpected zero sock_write\n");
-                        abort();
-                }
-
-                nob -= rc;
-                buffer = (char *)buffer + nob;
-        }
-        
-        return (0);
-}
-
-int
-sock_read (int cfd, void *buffer, int nob)
-{
-        while (nob > 0)
-        {
-                int rc = read (cfd, buffer, nob);
-                
-                if (rc < 0)
-                {
-                        if (errno == EINTR)
-                                continue;
-                        
-                        return (rc);
-                }
-                
-                if (rc == 0)                    /* EOF */
-                {
-                        errno = ECONNABORTED;
-                        return (-1);
-                }
-                
-                nob -= rc;
-                buffer = (char *)buffer + nob;
-        }
-        
-        return (0);
-}
-
-int
-exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
-{
-        int                      rc;
-        ptl_hdr_t                hdr;
-        ptl_magicversion_t      *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
-
-        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
-
-        memset (&hdr, 0, sizeof (hdr));
-        
-        hmv->magic          = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
-        hmv->version_major  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
-        hmv->version_minor  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
-
-        hdr.src_nid = __cpu_to_le64 (my_nid);
-        hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
-        
-        /* Assume there's sufficient socket buffering for a portals HELLO header */
-        rc = sock_write (cfd, &hdr, sizeof (hdr));
-        if (rc != 0) {
-                perror ("Can't send initial HELLO");
-                return (-1);
-        }
-
-        /* First few bytes down the wire are the portals protocol magic and
-         * version, no matter what protocol version we're running. */
-
-        rc = sock_read (cfd, hmv, sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read from peer");
-                return (-1);
-        }
-
-        if (__cpu_to_le32 (hmv->magic) != PORTALS_PROTO_MAGIC) {
-                fprintf (stderr, "Bad magic %#08x (%#08x expected)\n", 
-                         __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC);
-                return (-1);
-        }
-
-        if (__cpu_to_le16 (hmv->version_major) != PORTALS_PROTO_VERSION_MAJOR ||
-            __cpu_to_le16 (hmv->version_minor) != PORTALS_PROTO_VERSION_MINOR) {
-                fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
-                         __cpu_to_le16 (hmv->version_major),
-                         __cpu_to_le16 (hmv->version_minor),
-                         PORTALS_PROTO_VERSION_MAJOR,
-                         PORTALS_PROTO_VERSION_MINOR);
-        }
-
-        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
-         * so read the rest of it in now... */
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read rest of HELLO hdr");
-                return (-1);
-        }
-
-        /* ...and check we got what we expected */
-        if (__cpu_to_le32 (hdr.type) != PTL_MSG_HELLO ||
-            __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)) != 0) {
-                fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
-                         " but got type %d with %d payload\n",
-                         __cpu_to_le32 (hdr.type),
-                         __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)));
-                return (-1);
-        }
-        
-        *peer_nid = __le64_to_cpu (hdr.src_nid);
-        return (0);
+        syslog (LOG_INFO, "Accepted host: %s snd: %d rcv %d nagle: %s\n", 
+                host, txmem, rxmem, nonagle ? "disabled" : "enabled");
 }
 
 void
@@ -277,10 +150,9 @@ int main(int argc, char **argv)
         int noclose = 0;
         int nonagle = 1;
         int nal = SOCKNAL;
-        int xchg_nids = 0;
         int bind_irq = 0;
         
-        while ((c = getopt (argc, argv, "N:r:s:nlxi")) != -1)
+        while ((c = getopt (argc, argv, "N:r:s:nli")) != -1)
                 switch (c)
                 {
                 case 'r':
@@ -301,10 +173,6 @@ int main(int argc, char **argv)
                         noclose = 1;
                         break;
 
-                case 'x':
-                        xchg_nids = 1;
-                        break;
-
                 case 'i':
                         bind_irq = 1;
                         break;
@@ -409,7 +277,7 @@ int main(int argc, char **argv)
                 int len = sizeof(clntaddr);
                 int cfd;
                 struct portal_ioctl_data data;
-                ptl_nid_t peer_nid;
+                struct portals_cfg pcfg;
                 
                 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
                 if ( cfd < 0 ) {
@@ -418,40 +286,20 @@ int main(int argc, char **argv)
                         continue;
                 }
 
-                if (!xchg_nids)
-                        peer_nid = ntohl (clntaddr.sin_addr.s_addr); /* HOST byte order */
-                else
-                {
-                        PORTAL_IOC_INIT (data);
-                        data.ioc_nal = nal;
-                        rc = ioctl (pfd, IOC_PORTAL_GET_NID, &data);
-                        if (rc < 0)
-                        {
-                                perror ("Can't get my NID");
-                                close (cfd);
-                                continue;
-                        }
-                        
-                        rc = exchange_nids (cfd, data.ioc_nid, &peer_nid);
-                        if (rc != 0)
-                        {
-                                close (cfd);
-                                continue;
-                        }
-                }
+                show_connection (cfd, clntaddr.sin_addr.s_addr);
 
-                show_connection (cfd, clntaddr.sin_addr.s_addr, peer_nid);
+                PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
+                pcfg.pcfg_nal = nal;
+                pcfg.pcfg_fd = cfd;
+                pcfg.pcfg_flags = bind_irq;
+                pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
                 
                 PORTAL_IOC_INIT(data);
-                data.ioc_fd = cfd;
-                data.ioc_nal = nal;
-                data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
-                data.ioc_nid = peer_nid;
-                data.ioc_flags = bind_irq;
+                data.ioc_pbuf1 = (char*)&pcfg;
+                data.ioc_plen1 = sizeof(pcfg);
                 
                 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
                         perror("ioctl failed");
-
                 } else {
                         printf("client registered\n");
                 }
diff --git a/lustre/portals/utils/debug.c b/lustre/portals/utils/debug.c
index 0a009d255117eaa3eb38fe804eb3caeff4c5de07..3f3e69c658468fa9c50e5d38c350d47b186ae699 100644
--- a/lustre/portals/utils/debug.c
+++ b/lustre/portals/utils/debug.c
@@ -31,13 +31,16 @@
 #include <errno.h>
 #include <unistd.h>
 #include <time.h>
-#include <syscall.h>
+#ifndef __CYGWIN__
+# include <syscall.h>
+#endif
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+
 #define BUG()                            /* workaround for module.h includes */
 #include <linux/version.h>
 
@@ -56,6 +59,8 @@ static int max = 8192;
 static int subsystem_mask = ~0;
 static int debug_mask = ~0;
 
+#define MAX_MARK_SIZE 100
+
 static const char *portal_debug_subsystems[] =
         {"undefined", "mdc", "mds", "osc", "ost", "class", "log", "llite",
          "rpc", "mgmt", "portals", "socknal", "qswnal", "pinger", "filter",
@@ -410,13 +415,17 @@ int jt_dbg_debug_file(int argc, char **argv)
                         strerror(errno));
                 return -1;
         }
-#warning FIXME: cleanup fstat issue here
-#ifndef SYS_fstat64
-#define __SYS_fstat__ SYS_fstat
+
+#ifndef __CYGWIN__
+# ifndef SYS_fstat64
+#  define __SYS_fstat__ SYS_fstat
+# else
+#  define __SYS_fstat__ SYS_fstat64
+# endif
+        rc = syscall(__SYS_fstat__, fd, &statbuf);
 #else
-#define __SYS_fstat__ SYS_fstat64
+        rc = fstat(fd, &statbuf);
 #endif
-        rc = syscall(__SYS_fstat__, fd, &statbuf);
         if (rc < 0) {
                 fprintf(stderr, "fstat failed: %s\n", strerror(errno));
                 goto out;
@@ -480,22 +489,29 @@ int jt_dbg_clear_debug_buf(int argc, char **argv)
 
 int jt_dbg_mark_debug_buf(int argc, char **argv)
 {
-        int rc;
+        int rc, max_size = MAX_MARK_SIZE-1;
         struct portal_ioctl_data data;
         char *text;
         time_t now = time(NULL);
 
-        if (argc > 2) {
-                fprintf(stderr, "usage: %s [marker text]\n", argv[0]);
-                return 0;
-        }
-
-        if (argc == 2) {
-                text = argv[1];
+        if (argc > 1) {
+                int counter;
+                text = malloc(MAX_MARK_SIZE);
+                strncpy(text, argv[1], max_size);
+                max_size-=strlen(argv[1]);
+                for(counter = 2; (counter < argc) && (max_size > 0) ; counter++){
+                        strncat(text, " ", 1);
+                        max_size-=1;
+                        strncat(text, argv[counter], max_size);
+                        max_size-=strlen(argv[counter]);
+                }
         } else {
                 text = ctime(&now);
                 text[strlen(text) - 1] = '\0'; /* stupid \n */
         }
+        if (!max_size) {
+                text[MAX_MARK_SIZE - 1] = '\0';
+        }
 
         memset(&data, 0, sizeof(data));
         data.ioc_inllen1 = strlen(text) + 1;
@@ -514,7 +530,6 @@ int jt_dbg_mark_debug_buf(int argc, char **argv)
         return 0;
 }
 
-
 int jt_dbg_modules(int argc, char **argv)
 {
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
@@ -523,7 +538,10 @@ int jt_dbg_modules(int argc, char **argv)
         } *mp, mod_paths[] = {
                 {"portals", "lustre/portals/libcfs"},
                 {"ksocknal", "lustre/portals/knals/socknal"},
+                {"kptlrouter", "lustre/portals/router"},
+                {"lvfs", "lustre/lvfs"},
                 {"obdclass", "lustre/obdclass"},
+                {"llog_test", "lustre/obdclass"},
                 {"ptlrpc", "lustre/ptlrpc"},
                 {"obdext2", "lustre/obdext2"},
                 {"ost", "lustre/ost"},
@@ -536,8 +554,9 @@ int jt_dbg_modules(int argc, char **argv)
                 {"obdfilter", "lustre/obdfilter"},
                 {"extN", "lustre/extN"},
                 {"lov", "lustre/lov"},
-                {"fsfilt_ext3", "lustre/obdclass"},
-                {"fsfilt_extN", "lustre/obdclass"},
+                {"fsfilt_ext3", "lustre/lvfs"},
+                {"fsfilt_extN", "lustre/lvfs"},
+                {"fsfilt_reiserfs", "lustre/lvfs"},
                 {"mds_ext2", "lustre/mds"},
                 {"mds_ext3", "lustre/mds"},
                 {"mds_extN", "lustre/mds"},
diff --git a/lustre/portals/utils/gmnalnid.c b/lustre/portals/utils/gmnalnid.c
new file mode 100644
index 0000000000000000000000000000000000000000..84ac97f55e52577fc0ab65e7b52a75728b41fe28
--- /dev/null
+++ b/lustre/portals/utils/gmnalnid.c
@@ -0,0 +1,119 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+  * vim:expandtab:shiftwidth=8:tabstop=8:
+  *
+  *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+  *
+  *   This file is part of Lustre, http://www.lustre.org/
+  *
+  *   This file is free software; you can redistribute it and/or
+  *   modify it under the terms of version 2.1 of the GNU Lesser General
+  *   Public License as published by the Free Software Foundation.
+  *
+  *   Lustre 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 Lesser General Public License for more details.
+  *
+  *   You should have received a copy of the GNU Lesser General Public
+  *   License along with Portals; if not, write to the Free Software
+  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <asm/byteorder.h>
+#include <syslog.h>
+
+#include <errno.h>
+
+#include <portals/api-support.h>
+#include <portals/list.h>
+#include <portals/lib-types.h>
+
+#define GMNAL_IOC_GET_GNID 1
+
+int
+roundup(int len)
+{
+	return((len+7) & (~0x7));
+}
+
+int main(int argc, char **argv)
+{
+        int rc, pfd;
+        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
+	unsigned int	nid = 0, len;
+	char	*name = NULL;
+	int	c;
+
+
+
+	while ((c = getopt(argc, argv, "n:l")) != -1) {
+		switch(c) {
+		case('n'):
+			name = optarg;	
+		break;
+		case('l'):
+			printf("Get local id not implemented yet!\n");
+			exit(-1);
+		default:
+			printf("usage %s -n nodename [-p]\n", argv[0]);
+		}
+	}
+
+	if (!name) {
+		printf("usage %s -n nodename [-p]\n", argv[0]);
+		exit(-1);
+	}
+
+
+
+
+        PCFG_INIT(pcfg, GMNAL_IOC_GET_GNID);
+        pcfg.pcfg_nal = GMNAL;
+
+	/*
+	 *	set up the inputs
+	 */
+	len = strlen(name) + 1;
+	pcfg.pcfg_pbuf1 = malloc(len);
+	strcpy(pcfg.pcfg_pbuf1, name);
+	pcfg.pcfg_plen1 = len;
+
+	/*
+	 *	set up the outputs
+	 */
+	pcfg.pcfg_pbuf2 = (void*)&nid;
+	pcfg.pcfg_plen2 = sizeof(unsigned int*);
+
+        pfd = open("/dev/portals", O_RDWR);
+        if ( pfd < 0 ) {
+                perror("opening portals device");
+		free(pcfg.pcfg_pbuf1);
+                exit(-1);
+        }
+
+        PORTAL_IOC_INIT(data);
+        data.ioc_pbuf1 = (char*)&pcfg;
+        data.ioc_plen1 = sizeof(pcfg);
+                
+        rc = ioctl (pfd, IOC_PORTAL_NAL_CMD, &data);
+        if (rc < 0)
+        {
+        	perror ("Can't get my NID");
+        }
+                        
+	free(pcfg.pcfg_pbuf1);
+	close(pfd);
+	printf("%u\n", nid);
+        exit(nid);
+}
diff --git a/lustre/portals/utils/l_ioctl.c b/lustre/portals/utils/l_ioctl.c
index 722bb57e24690012388cbaa372f5ffb1661955ff..c6628ff1b374e91197d971101b330126b7db665b 100644
--- a/lustre/portals/utils/l_ioctl.c
+++ b/lustre/portals/utils/l_ioctl.c
@@ -213,7 +213,6 @@ parse_dump(char * dump_file, int (*ioc_func)(int dev_id, int opc, void *))
 	
 	fd = syscall(SYS_open, dump_file, O_RDONLY);
 
-#warning FIXME: cleanup fstat issue here
 #ifndef SYS_fstat64
 #define __SYS_fstat__ SYS_fstat
 #else
diff --git a/lustre/portals/utils/parser.c b/lustre/portals/utils/parser.c
index eccf50704800952aaf7a9f14e3bdabf41d952997..db5292d30db3dfa199283696df783fb630b4b2b3 100644
--- a/lustre/portals/utils/parser.c
+++ b/lustre/portals/utils/parser.c
@@ -80,7 +80,7 @@ static int line2args(char *line, char **argv, int maxargs)
 
     arg = strtok(line, " \t");
     if ( arg ) {
-	argv[i] = arg;
+            argv[i] = arg;
 	i++;
     } else
 	return 0;
@@ -110,7 +110,10 @@ int Parser_execarg(int argc, char **argv, command_t cmds[])
 
         cmd = Parser_findargcmd(argv[0], cmds);
 	if ( cmd ) {
-		return (cmd->pc_func)(argc, argv);
+                int rc = (cmd->pc_func)(argc, argv);
+                if (rc == CMD_HELP)
+                        fprintf(stderr, "%s\n", cmd->pc_help);
+                return rc;
 	} else {
 		printf("Try interactive use without arguments or use one of:\n");
 		for (cmd = cmds; cmd->pc_name; cmd++)
diff --git a/lustre/portals/utils/parser.h b/lustre/portals/utils/parser.h
index dead9f5f1671d2e164c161474f91b1da98d6fe55..44e8f2a4fadfef23ae7f914513ac919ae2f6e475 100644
--- a/lustre/portals/utils/parser.h
+++ b/lustre/portals/utils/parser.h
@@ -2,7 +2,7 @@
 #define _PARSER_H_
 
 #define HISTORY	100		/* Don't let history grow unbounded    */
-#define MAXARGS 100
+#define MAXARGS 512
 
 #define CMD_COMPLETE	0
 #define CMD_INCOMPLETE	1
diff --git a/lustre/portals/utils/portals.c b/lustre/portals/utils/portals.c
index eb53305738fdb5ff7282d7033e49cfa8b77ccbea..3325892ba528a4795db596c8d90bdf7c430fcea9 100644
--- a/lustre/portals/utils/portals.c
+++ b/lustre/portals/utils/portals.c
@@ -40,12 +40,13 @@
 #include <portals/ptlctl.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
+#include <portals/socknal.h>
 #include "parser.h"
 
 unsigned int portal_debug;
 unsigned int portal_printk;
 unsigned int portal_stack;
-
+unsigned int portal_cerror;
 
 static unsigned int g_nal = 0;
 
@@ -65,10 +66,44 @@ static name2num_t nalnames[] = {
         {"toe",		TOENAL},
         {"elan",	QSWNAL},
         {"gm",	        GMNAL},
+        {"ib",	        IBNAL},
         {"scimac",      SCIMACNAL},
         {NULL,		-1}
 };
 
+static cfg_record_cb_t g_record_cb;
+
+int 
+ptl_set_cfg_record_cb(cfg_record_cb_t cb)
+{
+        g_record_cb = cb;
+        return 0;
+}
+
+int 
+pcfg_ioctl(struct portals_cfg *pcfg) 
+{
+        int rc;
+
+        if (pcfg->pcfg_nal ==0)
+                pcfg->pcfg_nal    = g_nal;
+
+        if (g_record_cb) {
+                rc = g_record_cb(PORTALS_CFG_TYPE, sizeof(*pcfg), pcfg);
+        } else {
+                struct portal_ioctl_data data;
+                PORTAL_IOC_INIT (data);
+                data.ioc_pbuf1   = (char*)pcfg;
+                data.ioc_plen1   = sizeof(*pcfg);
+
+                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        }
+
+        return (rc);
+}
+
+
+
 static name2num_t *
 name2num_lookup_name (name2num_t *table, char *str)
 {
@@ -227,8 +262,9 @@ ptl_ipaddr_2_str (__u32 ipaddr, char *str)
 int
 ptl_parse_nid (ptl_nid_t *nidp, char *str)
 {
-        __u32 ipaddr;
-        long  lval;
+        __u32               ipaddr;
+        char               *end;
+        unsigned long long  ullval;
         
         if (!strcmp (str, "_all_")) {
                 *nidp = PTL_NID_ANY;
@@ -240,15 +276,10 @@ ptl_parse_nid (ptl_nid_t *nidp, char *str)
                 return (0);
         }
 
-        if (sscanf (str, "%li", &lval) == 1)
-        {
-                *nidp = (ptl_nid_t)lval;
-                return (0);
-        }
-
-        if (sscanf (str, "%lx", &lval) == 1)
-        {
-                *nidp = (ptl_nid_t)lval;
+        ullval = strtoull(str, &end, 0);
+        if (*end == 0) {
+                /* parsed whole string */
+                *nidp = (ptl_nid_t)ullval;
                 return (0);
         }
 
@@ -391,7 +422,7 @@ int jt_ptl_network(int argc, char **argv)
 int 
 jt_ptl_print_autoconnects (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         char                     buffer[64];
         int                      index;
         int                      rc;
@@ -400,24 +431,21 @@ jt_ptl_print_autoconnects (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_AUTOCONN;
-                data.ioc_count   = index;
-                
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                PCFG_INIT (pcfg, NAL_CMD_GET_AUTOCONN);
+                pcfg.pcfg_count   = index;
+
+                rc = pcfg_ioctl (&pcfg);
                 if (rc != 0)
                         break;
 
-                printf (LPX64"@%s:%d #%d buffer %d nonagle %s xchg %s "
-                        "affinity %s eager %s share %d\n",
-                        data.ioc_nid, ptl_ipaddr_2_str (data.ioc_id, buffer),
-                        data.ioc_misc, data.ioc_count, data.ioc_size, 
-                        (data.ioc_flags & 1) ? "on" : "off",
-                        (data.ioc_flags & 2) ? "on" : "off",
-                        (data.ioc_flags & 4) ? "on" : "off",
-                        (data.ioc_flags & 8) ? "on" : "off",
-                        data.ioc_wait);
+                printf (LPX64"@%s:%d #%d buffer %d "
+                        "nonagle %s affinity %s eager %s share %d\n",
+                        pcfg.pcfg_nid, ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
+                        pcfg.pcfg_misc, pcfg.pcfg_count, pcfg.pcfg_size, 
+                        (pcfg.pcfg_flags & 1) ? "on" : "off",
+                        (pcfg.pcfg_flags & 2) ? "on" : "off",
+                        (pcfg.pcfg_flags & 4) ? "on" : "off",
+                        pcfg.pcfg_wait);
         }
 
         if (index == 0)
@@ -428,18 +456,17 @@ jt_ptl_print_autoconnects (int argc, char **argv)
 int 
 jt_ptl_add_autoconnect (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         ptl_nid_t                nid;
         __u32                    ip;
         int                      port;
-        int                      xchange_nids = 0;
         int                      irq_affinity = 0;
         int                      share = 0;
         int                      eager = 0;
         int                      rc;
 
         if (argc < 4 || argc > 5) {
-                fprintf (stderr, "usage: %s nid ipaddr port [ixse]\n", argv[0]);
+                fprintf (stderr, "usage: %s nid ipaddr port [ise]\n", argv[0]);
                 return 0;
         }
 
@@ -467,9 +494,6 @@ jt_ptl_add_autoconnect (int argc, char **argv)
                 
                 while (*opts != 0)
                         switch (*opts++) {
-                        case 'x':
-                                xchange_nids = 1;
-                                break;
                         case 'i':
                                 irq_affinity = 1;
                                 break;
@@ -486,21 +510,18 @@ jt_ptl_add_autoconnect (int argc, char **argv)
                         }
         }
 
-        PORTAL_IOC_INIT (data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_ADD_AUTOCONN;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ip;
-        data.ioc_misc    = port;
+        PCFG_INIT(pcfg, NAL_CMD_ADD_AUTOCONN);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ip;
+        pcfg.pcfg_misc    = port;
         /* only passing one buffer size! */
-        data.ioc_size    = MAX (g_socket_rxmem, g_socket_txmem);
-        data.ioc_flags   = (g_socket_nonagle ? 0x01 : 0) |
-                           (xchange_nids     ? 0x02 : 0) |
-                           (irq_affinity     ? 0x04 : 0) |
-                           (share            ? 0x08 : 0) |
-                           (eager            ? 0x10 : 0);
-
-        rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        pcfg.pcfg_size    = MAX (g_socket_rxmem, g_socket_txmem);
+        pcfg.pcfg_flags   = (g_socket_nonagle ? 0x01 : 0) |
+                            (irq_affinity     ? 0x02 : 0) |
+                            (share            ? 0x04 : 0) |
+                            (eager            ? 0x08 : 0);
+
+        rc = pcfg_ioctl (&pcfg);
         if (rc != 0) {
                 fprintf (stderr, "failed to enable autoconnect: %s\n",
                          strerror (errno));
@@ -513,7 +534,7 @@ jt_ptl_add_autoconnect (int argc, char **argv)
 int 
 jt_ptl_del_autoconnect (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ip  = 0;
         int                      share = 0;
@@ -559,15 +580,13 @@ jt_ptl_del_autoconnect (int argc, char **argv)
                         }
         }
 
-        PORTAL_IOC_INIT (data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_DEL_AUTOCONN;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ip;
-        data.ioc_flags   = (share     ? 1 : 0) |
+        PCFG_INIT(pcfg, NAL_CMD_DEL_AUTOCONN);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ip;
+        pcfg.pcfg_flags   = (share     ? 1 : 0) |
                            (keep_conn ? 2 : 0);
-        
-        rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+
+        rc = pcfg_ioctl (&pcfg);
         if (rc != 0) {
                 fprintf (stderr, "failed to remove autoconnect route: %s\n",
                          strerror (errno));
@@ -580,7 +599,7 @@ jt_ptl_del_autoconnect (int argc, char **argv)
 int 
 jt_ptl_print_connections (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         char                     buffer[64];
         int                      index;
         int                      rc;
@@ -589,19 +608,21 @@ jt_ptl_print_connections (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_CONN;
-                data.ioc_count   = index;
+                PCFG_INIT (pcfg,  NAL_CMD_GET_CONN);
+                pcfg.pcfg_count   = index;
                 
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                rc = pcfg_ioctl (&pcfg);
                 if (rc != 0)
                         break;
 
-                printf (LPX64"@%s:%d\n",
-                        data.ioc_nid, 
-                        ptl_ipaddr_2_str (data.ioc_id, buffer),
-                        data.ioc_misc);
+                printf (LPX64"@%s:%d:%s\n",
+                        pcfg.pcfg_nid, 
+                        ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
+                        pcfg.pcfg_misc,
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_ANY) ? "A" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_CONTROL) ? "C" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_IN) ? "I" :
+                        (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
         }
 
         if (index == 0)
@@ -609,82 +630,9 @@ jt_ptl_print_connections (int argc, char **argv)
         return 0;
 }
 
-int
-exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
-{
-        int                      rc;
-        ptl_hdr_t                hdr;
-        ptl_magicversion_t      *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
-
-        LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
-
-        memset (&hdr, 0, sizeof (hdr));
-        
-        hmv->magic          = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
-        hmv->version_major  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
-        hmv->version_minor  = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
-
-        hdr.src_nid = __cpu_to_le64 (my_nid);
-        hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
-        
-        /* Assume there's sufficient socket buffering for a portals HELLO header */
-        rc = sock_write (cfd, &hdr, sizeof (hdr));
-        if (rc != 0) {
-                perror ("Can't send initial HELLO");
-                return (-1);
-        }
-
-        /* First few bytes down the wire are the portals protocol magic and
-         * version, no matter what protocol version we're running. */
-
-        rc = sock_read (cfd, hmv, sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read from peer");
-                return (-1);
-        }
-
-        if (hmv->magic != __cpu_to_le32 (PORTALS_PROTO_MAGIC)) {
-                fprintf (stderr, "Bad magic %#08x (%#08x expected)\n", 
-                         __le32_to_cpu (hmv->magic), PORTALS_PROTO_MAGIC);
-                return (-1);
-        }
-
-        if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
-            hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
-                fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
-                         __le16_to_cpu (hmv->version_major),
-                         __le16_to_cpu (hmv->version_minor),
-                         PORTALS_PROTO_VERSION_MAJOR,
-                         PORTALS_PROTO_VERSION_MINOR);
-        }
-
-        /* version 0 sends magic/version as the dest_nid of a 'hello' header,
-         * so read the rest of it in now... */
-        LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
-        rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
-        if (rc != 0) {
-                perror ("Can't read rest of HELLO hdr");
-                return (-1);
-        }
-
-        /* ...and check we got what we expected */
-        if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
-            PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
-                fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
-                         " but got type %d with %d payload\n",
-                         __le32_to_cpu (hdr.type),
-                         __le32_to_cpu (PTL_HDR_LENGTH (&hdr)));
-                return (-1);
-        }
-        
-        *peer_nid = __le64_to_cpu (hdr.src_nid);
-        return (0);
-}
-
 int jt_ptl_connect(int argc, char **argv)
 {
-        ptl_nid_t peer_nid;
-        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
         struct sockaddr_in srvaddr;
         __u32 ipaddr;
         char *flag;
@@ -693,13 +641,13 @@ int jt_ptl_connect(int argc, char **argv)
         int rxmem = 0;
         int txmem = 0;
         int bind_irq = 0;
-        int xchange_nids = 0;
+        int type = SOCKNAL_CONN_ANY;
         int port;
         int o;
         int olen;
 
         if (argc < 3) {
-                fprintf(stderr, "usage: %s ip port [xi]\n", argv[0]);
+                fprintf(stderr, "usage: %s ip port [xibctr]\n", argv[0]);
                 return 0;
         }
 
@@ -725,8 +673,28 @@ int jt_ptl_connect(int argc, char **argv)
                                 bind_irq = 1;
                                 break;
                                 
-                        case 'x':
-                                xchange_nids = 1;
+                        case 'I':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_BULK_IN;
+                                break;
+
+                        case 'O':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_BULK_OUT;
+                                break;
+
+                        case 'C':
+                                if (type != SOCKNAL_CONN_ANY) {
+                                        fprintf(stderr, "Can't flag type twice\n");
+                                        return -1;
+                                }
+                                type = SOCKNAL_CONN_CONTROL;
                                 break;
                                 
                         default:
@@ -787,36 +755,20 @@ int jt_ptl_connect(int argc, char **argv)
         if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
                 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
 
-        if (!xchange_nids) 
-                peer_nid = ipaddr;
-        else {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal = g_nal;
-                rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
-                if (rc != 0) {
-                        fprintf (stderr, "failed to get my nid: %s\n",
-                                 strerror (errno));
-                        close (fd);
-                        return (-1);
-                }
-
-                rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
-                if (rc != 0) {
-                        close (fd);
-                        return (-1);
-                }
-        } 
-        printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
-               peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
-
-        PORTAL_IOC_INIT(data);
-        data.ioc_fd = fd;
-        data.ioc_nal = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
-        data.ioc_nid = peer_nid;
-        data.ioc_flags = bind_irq;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        printf("Connected host: %s snd: %d rcv: %d nagle: %s type: %s\n", 
+               argv[1], txmem, rxmem, nonagle ? "Disabled" : "Enabled",
+               (type == SOCKNAL_CONN_ANY) ? "A" :
+               (type == SOCKNAL_CONN_CONTROL) ? "C" :
+               (type == SOCKNAL_CONN_BULK_IN) ? "I" :
+               (type == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
+
+        PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
+        pcfg.pcfg_nal = g_nal;
+        pcfg.pcfg_fd = fd;
+        pcfg.pcfg_flags = bind_irq;
+        pcfg.pcfg_misc = type;
+        
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to register fd with portals: %s\n", 
                         strerror(errno));
@@ -824,7 +776,7 @@ int jt_ptl_connect(int argc, char **argv)
                 return -1;
         }
 
-        printf("Connection to "LPX64" registered with socknal\n", peer_nid);
+        printf("Connection to %s registered with socknal\n", argv[1]);
 
         rc = close(fd);
         if (rc)
@@ -835,7 +787,7 @@ int jt_ptl_connect(int argc, char **argv)
 
 int jt_ptl_disconnect(int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ipaddr = 0;
         int                      rc;
@@ -860,13 +812,11 @@ int jt_ptl_disconnect(int argc, char **argv)
                 return -1;
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ipaddr;
+        PCFG_INIT(pcfg, NAL_CMD_CLOSE_CONNECTION);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ipaddr;
         
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to remove connection: %s\n",
                         strerror(errno));
@@ -878,7 +828,7 @@ int jt_ptl_disconnect(int argc, char **argv)
 
 int jt_ptl_push_connection (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         int                      rc;
         ptl_nid_t                nid = PTL_NID_ANY;
         __u32                    ipaddr = 0;
@@ -902,13 +852,11 @@ int jt_ptl_push_connection (int argc, char **argv)
                 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal     = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
-        data.ioc_nid     = nid;
-        data.ioc_id      = ipaddr;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        PCFG_INIT(pcfg, NAL_CMD_PUSH_CONNECTION);
+        pcfg.pcfg_nid     = nid;
+        pcfg.pcfg_id      = ipaddr;
+        
+        rc = pcfg_ioctl(&pcfg);
         if (rc) {
                 fprintf(stderr, "failed to push connection: %s\n",
                         strerror(errno));
@@ -921,7 +869,7 @@ int jt_ptl_push_connection (int argc, char **argv)
 int 
 jt_ptl_print_active_txs (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg        pcfg;
         int                      index;
         int                      rc;
 
@@ -929,28 +877,26 @@ jt_ptl_print_active_txs (int argc, char **argv)
                 return -1;
 
         for (index = 0;;index++) {
-                PORTAL_IOC_INIT (data);
-                data.ioc_nal     = g_nal;
-                data.ioc_nal_cmd = NAL_CMD_GET_TXDESC;
-                data.ioc_count   = index;
-                
-                rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+                PCFG_INIT(pcfg, NAL_CMD_GET_TXDESC);
+                pcfg.pcfg_count   = index;
+        
+                rc = pcfg_ioctl(&pcfg);
                 if (rc != 0)
                         break;
 
-                printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s,%s,%s\n",
-                        data.ioc_pbuf1,
-                        data.ioc_count == PTL_MSG_ACK ? "ACK" :
-                        data.ioc_count == PTL_MSG_PUT ? "PUT" :
-                        data.ioc_count == PTL_MSG_GET ? "GET" :
-                        data.ioc_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
-                        data.ioc_size,
-                        data.ioc_nid,
-                        data.ioc_nid2,
-                        data.ioc_misc,
-                        (data.ioc_flags & 1) ? "delayed" : "active",
-                        (data.ioc_flags & 2) ? "forwarding" : "sending",
-                        (data.ioc_flags & 4) ? "nblk" : "normal");
+                printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s, %s, state %d\n",
+                        pcfg.pcfg_pbuf1,
+                        pcfg.pcfg_count == PTL_MSG_ACK ? "ACK" :
+                        pcfg.pcfg_count == PTL_MSG_PUT ? "PUT" :
+                        pcfg.pcfg_count == PTL_MSG_GET ? "GET" :
+                        pcfg.pcfg_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
+                        pcfg.pcfg_size,
+                        pcfg.pcfg_nid,
+                        pcfg.pcfg_nid2,
+                        pcfg.pcfg_misc,
+                        (pcfg.pcfg_flags & 1) ? "delayed" : "immediate",
+                        (pcfg.pcfg_flags & 2) ? "nblk"    : "normal",
+                        pcfg.pcfg_flags >> 2);
         }
 
         if (index == 0)
@@ -1043,7 +989,7 @@ int jt_ptl_mynid(int argc, char **argv)
         int rc;
         char hostname[1024];
         char *nidstr;
-        struct portal_ioctl_data data;
+        struct portals_cfg pcfg;
         ptl_nid_t mynid;
         
         if (argc > 2) {
@@ -1071,12 +1017,10 @@ int jt_ptl_mynid(int argc, char **argv)
                 return -1;
         }
         
-        PORTAL_IOC_INIT(data);
-        data.ioc_nid = mynid;
-        data.ioc_nal = g_nal;
-        data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
+        PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
+        pcfg.pcfg_nid = mynid;
 
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc < 0)
                 fprintf(stderr, "setting my NID failed: %s\n",
                        strerror(errno));
@@ -1190,7 +1134,7 @@ jt_ptl_nagle (int argc, char **argv)
 int
 jt_ptl_add_route (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid1;
         ptl_nid_t                nid2;
         ptl_nid_t                gateway_nid;
@@ -1225,16 +1169,17 @@ jt_ptl_add_route (int argc, char **argv)
                 return (-1);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nid = gateway_nid;
-        data.ioc_nal = g_nal;
-        data.ioc_nid2 = MIN (nid1, nid2);
-        data.ioc_nid3 = MAX (nid1, nid2);
+        PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE);
+        pcfg.pcfg_nid = gateway_nid;
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid2 = MIN (nid1, nid2);
+        pcfg.pcfg_nid3 = MAX (nid1, nid2);
 
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
+                fprintf (stderr, "NAL_CMD_ADD_ROUTE failed: %s\n", strerror (errno));
                 return (-1);
         }
         
@@ -1244,7 +1189,7 @@ jt_ptl_add_route (int argc, char **argv)
 int
 jt_ptl_del_route (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         ptl_nid_t                nid;
         ptl_nid_t                nid1 = PTL_NID_ANY;
         ptl_nid_t                nid2 = PTL_NID_ANY;
@@ -1288,16 +1233,17 @@ jt_ptl_del_route (int argc, char **argv)
                 }
         }
         
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal = g_nal;
-        data.ioc_nid = nid;
-        data.ioc_nid2 = nid1;
-        data.ioc_nid3 = nid2;
-
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
+        PCFG_INIT(pcfg, NAL_CMD_DEL_ROUTE);
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid = nid;
+        pcfg.pcfg_nid2 = nid1;
+        pcfg.pcfg_nid3 = nid2;
+
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
+                fprintf (stderr, "NAL_CMD_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
                 return (-1);
         }
         
@@ -1307,7 +1253,7 @@ jt_ptl_del_route (int argc, char **argv)
 int
 jt_ptl_notify_router (int argc, char **argv)
 {
-        struct portal_ioctl_data data;
+        struct portals_cfg       pcfg;
         int                      enable;
         ptl_nid_t                nid;
         int                      rc;
@@ -1347,17 +1293,18 @@ jt_ptl_notify_router (int argc, char **argv)
                 return (-1);
         }
 
-        PORTAL_IOC_INIT(data);
-        data.ioc_nal = g_nal;
-        data.ioc_nid = nid;
-        data.ioc_flags = enable;
+        PCFG_INIT(pcfg, NAL_CMD_NOTIFY_ROUTER);
+        pcfg.pcfg_nal = ROUTER;
+        pcfg.pcfg_gw_nal = g_nal;
+        pcfg.pcfg_nid = nid;
+        pcfg.pcfg_flags = enable;
         /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
-        data.ioc_nid3 = (__u64)when;
+        pcfg.pcfg_nid3 = (__u64)when;
         
-        rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NOTIFY_ROUTER, &data);
+        rc = pcfg_ioctl(&pcfg);
         if (rc != 0) 
         {
-                fprintf (stderr, "IOC_PORTAL_NOTIFY_ROUTER ("LPX64") failed: %s\n",
+                fprintf (stderr, "NAL_CMD_NOTIFY_ROUTER ("LPX64") failed: %s\n",
                          nid, strerror (errno));
                 return (-1);
         }
@@ -1369,7 +1316,7 @@ int
 jt_ptl_print_routes (int argc, char **argv)
 {
         char                      buffer[3][128];
-        struct portal_ioctl_data  data;
+        struct portals_cfg        pcfg;
         int                       rc;
         int                       index;
         int			  gateway_nal;
@@ -1380,18 +1327,19 @@ jt_ptl_print_routes (int argc, char **argv)
 
         for (index = 0;;index++)
         {
-                PORTAL_IOC_INIT(data);
-                data.ioc_count = index;
+                PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE);
+                pcfg.pcfg_nal = ROUTER;
+                pcfg.pcfg_count = index;
                 
-                rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
+                rc = pcfg_ioctl(&pcfg);
                 if (rc != 0)
                         break;
 
-                gateway_nal = data.ioc_nal;
-                gateway_nid = data.ioc_nid;
-                nid1 = data.ioc_nid2;
-                nid2 = data.ioc_nid3;
-                alive = data.ioc_flags;
+                gateway_nal = pcfg.pcfg_gw_nal;
+                gateway_nid = pcfg.pcfg_nid;
+                nid1 = pcfg.pcfg_nid2;
+                nid2 = pcfg.pcfg_nid3;
+                alive = pcfg.pcfg_flags;
 
                 printf ("%8s %18s : %s - %s, %s\n", 
                         nal2name (gateway_nal), 
diff --git a/lustre/portals/utils/ptlctl.c b/lustre/portals/utils/ptlctl.c
index 1a8e637291ee307f49aa58533029d5da234f7f51..c65ecb2443634f00d93f848570ab46c1d46fb101 100644
--- a/lustre/portals/utils/ptlctl.c
+++ b/lustre/portals/utils/ptlctl.c
@@ -31,10 +31,10 @@
 command_t list[] = {
         {"network", jt_ptl_network, 0,"setup the NAL (args: nal name)"},
         {"print_autoconns", jt_ptl_print_autoconnects, 0, "print autoconnect entries (no args)"},
-        {"add_autoconn", jt_ptl_add_autoconnect, 0, "add autoconnect entry (args: nid host [ixse])"},
+        {"add_autoconn", jt_ptl_add_autoconnect, 0, "add autoconnect entry (args: nid host [ise])"},
         {"del_autoconn", jt_ptl_del_autoconnect, 0, "delete autoconnect entry (args: [nid] [host] [ks])"},
         {"print_conns", jt_ptl_print_connections, 0, "print connections (no args)"},
-        {"connect", jt_ptl_connect, 0, "connect to a remote nid (args: host port [xi])"},
+        {"connect", jt_ptl_connect, 0, "connect to a remote nid (args: host port [iIOC])"},
         {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid (args: [nid] [host]"},
         {"push", jt_ptl_push_connection, 0, "flush connection to a remote nid (args: [nid]"},
         {"active_tx", jt_ptl_print_active_txs, 0, "print active transmits (no args)"},
diff --git a/lustre/portals/utils/wirecheck.c b/lustre/portals/utils/wirecheck.c
index 6a4377b300c91510be79ad1ec6abd08c2284e946..77ad126a3e00176cec899accf4fb0119897f7246 100644
--- a/lustre/portals/utils/wirecheck.c
+++ b/lustre/portals/utils/wirecheck.c
@@ -2,10 +2,14 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  */
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <portals/api-support.h>
 #include <portals/list.h>
 #include <portals/lib-types.h>
 
+extern size_t strnlen(const char *, size_t);
+
 #define BLANK_LINE()				\
 do {						\
 	printf ("\n");				\
@@ -77,47 +81,109 @@ check_ptl_hdr (void)
 	CHECK_MEMBER (ptl_hdr_t, dest_pid);
 	CHECK_MEMBER (ptl_hdr_t, src_pid);
 	CHECK_MEMBER (ptl_hdr_t, type);
-
+	CHECK_MEMBER (ptl_hdr_t, payload_length);
+        CHECK_MEMBER (ptl_hdr_t, msg);
+        
         BLANK_LINE ();
         COMMENT ("Ack");
-        CHECK_MEMBER (ptl_hdr_t, msg.ack.mlength);
         CHECK_MEMBER (ptl_hdr_t, msg.ack.dst_wmd);
         CHECK_MEMBER (ptl_hdr_t, msg.ack.match_bits);
-        CHECK_MEMBER (ptl_hdr_t, msg.ack.length);
+        CHECK_MEMBER (ptl_hdr_t, msg.ack.mlength);
 
         BLANK_LINE ();
         COMMENT ("Put");
-	CHECK_MEMBER (ptl_hdr_t, msg.put.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.ack_wmd);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.match_bits);
-	CHECK_MEMBER (ptl_hdr_t, msg.put.length);
-	CHECK_MEMBER (ptl_hdr_t, msg.put.offset);
 	CHECK_MEMBER (ptl_hdr_t, msg.put.hdr_data);
+	CHECK_MEMBER (ptl_hdr_t, msg.put.ptl_index);
+	CHECK_MEMBER (ptl_hdr_t, msg.put.offset);
 
         BLANK_LINE ();
         COMMENT ("Get");
-	CHECK_MEMBER (ptl_hdr_t, msg.get.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.return_wmd);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.match_bits);
-	CHECK_MEMBER (ptl_hdr_t, msg.get.length);
+	CHECK_MEMBER (ptl_hdr_t, msg.get.ptl_index);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.src_offset);
-	CHECK_MEMBER (ptl_hdr_t, msg.get.return_offset);
 	CHECK_MEMBER (ptl_hdr_t, msg.get.sink_length);
 
         BLANK_LINE ();
         COMMENT ("Reply");
 	CHECK_MEMBER (ptl_hdr_t, msg.reply.dst_wmd);
-	CHECK_MEMBER (ptl_hdr_t, msg.reply.dst_offset);
-	CHECK_MEMBER (ptl_hdr_t, msg.reply.length);
+
+        BLANK_LINE ();
+        COMMENT ("Hello");
+	CHECK_MEMBER (ptl_hdr_t, msg.hello.incarnation);
+	CHECK_MEMBER (ptl_hdr_t, msg.hello.type);
+}
+
+void
+system_string (char *cmdline, char *str, int len)
+{
+        int   fds[2];
+        int   rc;
+        pid_t pid;
+        
+        rc = pipe (fds);
+        if (rc != 0)
+                abort ();
+        
+        pid = fork ();
+        if (pid == 0) {
+                /* child */
+                int   fd = fileno(stdout);
+
+                rc = dup2(fds[1], fd);
+                if (rc != fd)
+                        abort();
+
+                exit(system(cmdline));
+                /* notreached */
+        } else if ((int)pid < 0) {
+                abort();
+        } else {
+                FILE *f = fdopen (fds[0], "r");
+
+                if (f == NULL)
+                        abort();
+                
+                close(fds[1]);
+                
+                if (fgets(str, len, f) == NULL)
+                        abort();
+                
+                if (waitpid(pid, &rc, 0) != pid)
+                        abort();
+                
+                if (!WIFEXITED(rc) ||
+                    WEXITSTATUS(rc) != 0)
+                        abort();
+
+                if (strnlen(str, len) == len)
+                        str[len - 1] = 0;
+                
+                if (str[strlen(str) - 1] == '\n')
+                        str[strlen(str) - 1] = 0;
+                
+                fclose(f);
+        }
 }
 
 int
 main (int argc, char **argv)
 {
+        char unameinfo[80];
+        char gccinfo[80];
+        
+        system_string("uname -a", unameinfo, sizeof(unameinfo));
+        system_string("gcc -v 2>&1 | tail -1", gccinfo, sizeof(gccinfo));
+        
 	printf ("void lib_assert_wire_constants (void)\n"
-		"{\n");
-
-	COMMENT ("Wire protocol assertions generated by 'wirecheck'");
+		"{\n"
+                "        /* Wire protocol assertions generated by 'wirecheck'\n"
+                "         * running on %s\n"
+                "         * with %s */\n"
+                "\n", unameinfo, gccinfo);
+        
 	BLANK_LINE ();
 	
 	COMMENT ("Constants...");
diff --git a/lustre/ptlbd/blk.c b/lustre/ptlbd/blk.c
index a367903434d57d07ed8a97c0a94b2c4b40dc5d95..d8b7f02cf81c2233bf36f551a1dbda47e718eb34 100644
--- a/lustre/ptlbd/blk.c
+++ b/lustre/ptlbd/blk.c
@@ -26,7 +26,6 @@
 
 #define DEBUG_SUBSYSTEM S_PTLBD
 
-#include <linux/lustre_lite.h>
 #include <linux/lustre_ha.h>
 #include <linux/obd_support.h>
 #include <linux/lustre_idl.h>
diff --git a/lustre/ptlbd/client.c b/lustre/ptlbd/client.c
index af603fd1748b7b6bd013e050388475fb8d72d2e2..1acac79eb2e68d4b702046c2e69035694fc90947 100644
--- a/lustre/ptlbd/client.c
+++ b/lustre/ptlbd/client.c
@@ -36,23 +36,23 @@ static int ptlbd_cl_setup(struct obd_device *obd, obd_count len, void *buf)
 {
         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
         struct obd_import *imp;
-        struct obd_ioctl_data* data = buf;
+        struct lustre_cfg* lcfg = buf;
         ENTRY;
 
         if (ptlbd->bd_import != NULL)
                 RETURN(-EALREADY);
 
-        if (data->ioc_inllen1 < 1) {
+        if (lcfg->lcfg_inllen1 < 1) {
                 CERROR("requires a PTLBD server UUID\n");
                 RETURN(-EINVAL);
         }
 
-        if (data->ioc_inllen1 > 37) {
+        if (lcfg->lcfg_inllen1 > 37) {
                 CERROR("PTLBD server UUID must be less than 38 characters\n");
                 RETURN(-EINVAL);
         }
 
-        obd_str2uuid(&ptlbd->bd_server_uuid, data->ioc_inlbuf1);
+        obd_str2uuid(&ptlbd->bd_server_uuid, lcfg->lcfg_inlbuf1);
 
         /*
          * from client_obd_connect.. *shrug*
@@ -64,13 +64,14 @@ static int ptlbd_cl_setup(struct obd_device *obd, obd_count len, void *buf)
                 class_import_put(imp);
                 RETURN(-ENOENT);
         }
-        imp->imp_level = LUSTRE_CONN_FULL;
+        imp->imp_state = LUSTRE_IMP_FULL;
 
         ptlrpc_init_client(PTLBD_REQUEST_PORTAL, PTLBD_REPLY_PORTAL, 
                         "ptlbd", &ptlbd->bd_client);
         imp->imp_client = &ptlbd->bd_client;
         imp->imp_obd = obd;
-        memcpy(imp->imp_target_uuid.uuid, data->ioc_inlbuf1, data->ioc_inllen1);
+        memcpy(imp->imp_target_uuid.uuid, lcfg->lcfg_inlbuf1, 
+               lcfg->lcfg_inllen1);
         ptlbd_blk_register(ptlbd);
 
         RETURN(0);
@@ -120,40 +121,40 @@ int ptlbd_cl_connect(struct lustre_handle *conn, struct obd_device *obd,
         rc = class_connect(conn, obd, target_uuid);
         if (rc)
                 RETURN(rc);
+        exp = class_conn2export(conn);
 
         request = ptlrpc_prep_req(imp, PTLBD_CONNECT, 3, size, tmp);
         if (!request)
                 GOTO(out_disco, rc = -ENOMEM);
-        request->rq_level = LUSTRE_CONN_NEW;
+        request->rq_send_state = LUSTRE_IMP_NEW;
         request->rq_replen = lustre_msg_size(0, NULL);
 
         imp->imp_dlm_handle = *conn;
 
-        imp->imp_level = LUSTRE_CONN_CON;
+        imp->imp_state = LUSTRE_IMP_NEW;
         rc = ptlrpc_queue_wait(request);
         if (rc)
                 GOTO(out_req, rc);
 
-        exp = class_conn2export(conn);
         exp->exp_connection = ptlrpc_connection_addref(request->rq_connection);
-        class_export_put(exp);
 
-        imp->imp_level = LUSTRE_CONN_FULL;
+        imp->imp_state = LUSTRE_IMP_FULL;
         imp->imp_remote_handle = request->rq_repmsg->handle;
         
 out_req:
         ptlrpc_req_finished(request);
 out_disco:
         if (rc)
-                class_disconnect(conn, 0);
+                class_disconnect(exp, 0);
+        class_export_put(exp);
         RETURN(rc);
 }
 
 
 /* modelled after ptlrpc_import_disconnect() */
-int ptlbd_cl_disconnect(struct lustre_handle *conn, int failover)
+int ptlbd_cl_disconnect(struct obd_export *exp, int failover)
 {
-        struct obd_device *obd = class_conn2obd(conn);
+        struct obd_device *obd = exp->exp_obd;
         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
         struct obd_import *imp = ptlbd->bd_import;
         struct ptlrpc_request *request;
@@ -168,14 +169,14 @@ int ptlbd_cl_disconnect(struct lustre_handle *conn, int failover)
                 GOTO(out_req, rc = -ENOMEM);
 
         request->rq_replen = lustre_msg_size(0, NULL);
-        request->rq_level = LUSTRE_CONN_RECOVER;
+        request->rq_send_state = LUSTRE_IMP_FULL;
 
         rc = ptlrpc_queue_wait(request);
 
 out_req:
         if (request)
                 ptlrpc_req_finished(request);
-        err = class_disconnect(conn, 0);
+        err = class_disconnect(exp, 0);
         memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
         if (!rc && err)
                 rc = err;
@@ -215,11 +216,14 @@ int ptlbd_do_connect(struct ptlbd_obd *ptlbd)
 {
         int     rc;
         struct obd_device       *obd = ptlbd->bd_import->imp_obd;
+        struct lustre_handle conn;
         ENTRY;
 
-        memset(&ptlbd->bd_connect_handle, 0, sizeof(ptlbd->bd_connect_handle));
-        rc = obd_connect(&ptlbd->bd_connect_handle, obd, 
-                         &ptlbd->bd_server_uuid);
+        memset(&conn, 0, sizeof(conn));
+        rc = obd_connect(&conn, obd, &ptlbd->bd_server_uuid);
+        if (rc < 0)
+                RETURN(rc);
+        ptlbd->bd_exp = class_conn2export(&conn);
         RETURN(rc);
 }
 
@@ -229,7 +233,7 @@ int ptlbd_do_disconnect(struct ptlbd_obd *ptlbd)
         int     rc;
         ENTRY;
 
-        rc = obd_disconnect(&ptlbd->bd_connect_handle, 0);
+        rc = obd_disconnect(ptlbd->bd_exp, 0);
         RETURN(rc);
 }
 
diff --git a/lustre/ptlbd/main.c b/lustre/ptlbd/main.c
index dc591f4b24fc4f17be1d52bce357b8322850e439..3a091ffba6bdec9f271526808b44b2efb9ba2a08 100644
--- a/lustre/ptlbd/main.c
+++ b/lustre/ptlbd/main.c
@@ -20,12 +20,12 @@
  */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/major.h>
 #include <linux/smp.h>
 
 #define DEBUG_SUBSYSTEM S_PTLBD
 
-#include <linux/lustre_lite.h>
 #include <linux/lustre_ha.h>
 #include <linux/obd_support.h>
 
diff --git a/lustre/ptlbd/rpc.c b/lustre/ptlbd/rpc.c
index f817802e6d69f890fed657980829e130be83e7f5..51883f2bc6ce928c6b731fa862be1df8a7753606 100644
--- a/lustre/ptlbd/rpc.c
+++ b/lustre/ptlbd/rpc.c
@@ -92,7 +92,7 @@ int ptlbd_send_rw_req(struct ptlbd_obd *ptlbd, ptlbd_cmd_t cmd,
         req->rq_replen = lustre_msg_size(1, &rep_size);
 
         /* XXX find out how we're really supposed to manage levels */
-        req->rq_level = imp->imp_level;
+        req->rq_send_state = imp->imp_state;
         rc = ptlrpc_queue_wait(req);
 
         if ( rc != 0 )
@@ -144,7 +144,7 @@ int ptlbd_send_flush_req(struct ptlbd_obd *ptlbd, ptlbd_cmd_t cmd)
         req->rq_replen = lustre_msg_size(1, &rep_size);
 
         /* XXX find out how we're really supposed to manage levels */
-        req->rq_level = imp->imp_level;
+        req->rq_send_state = imp->imp_state;
 
         rc = ptlrpc_queue_wait(req);
         if ( rc != 0 )
@@ -199,7 +199,7 @@ int ptlbd_srv_rw_req(ptlbd_cmd_t cmd, __u16 index,
         struct ptlbd_niob *niob, *niobs;
         struct ptlbd_rsp *rsp;
         struct ptlrpc_bulk_desc *desc = NULL;
-        struct file *filp = req->rq_obd->u.ptlbd.filp;
+        struct file *filp = req->rq_export->exp_obd->u.ptlbd.filp;
         struct l_wait_info lwi;
         int size[1], i, page_count, rc = 0, error_cnt = 0;
         struct list_head *pos, *n;
@@ -213,7 +213,7 @@ int ptlbd_srv_rw_req(ptlbd_cmd_t cmd, __u16 index,
                 GOTO (out, rc = -EFAULT);
 
         size[0] = sizeof(struct ptlbd_rsp);
-        rc = lustre_pack_msg(1, size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, size, NULL);
         if ( rc )
                 GOTO(out, rc);
 
@@ -314,12 +314,12 @@ int ptlbd_srv_flush_req(ptlbd_cmd_t cmd, __u16 index,
                         struct ptlrpc_request *req)
 {
         struct ptlbd_rsp *rsp;
-        struct file *filp = req->rq_obd->u.ptlbd.filp;
+        struct file *filp = req->rq_export->exp_obd->u.ptlbd.filp;
         int size[1], rc, status;
         ENTRY;
 
         size[0] = sizeof(struct ptlbd_rsp);
-        rc = lustre_pack_msg(1, size, NULL, &req->rq_replen, &req->rq_repmsg);
+        rc = lustre_pack_reply(req, 1, size, NULL);
         if ( rc )
                 RETURN(rc);
 
diff --git a/lustre/ptlbd/server.c b/lustre/ptlbd/server.c
index 8dfda2b07c7ff671d662c7ebb3e56740a334a346..e159df03c85a4cf3ae354bc3d459329e55c8744d 100644
--- a/lustre/ptlbd/server.c
+++ b/lustre/ptlbd/server.c
@@ -52,12 +52,13 @@ static int ptlbd_sv_setup(struct obd_device *obddev, obd_count len, void *buf)
                 ptlrpc_init_svc(PTLBD_NEVENTS, PTLBD_NBUFS, PTLBD_BUFSIZE,
                                 PTLBD_MAXREQSIZE, PTLBD_REQUEST_PORTAL,
                                 PTLBD_REPLY_PORTAL,
-                                ptlbd_handle, "ptlbd_sv", obddev);
+                                ptlbd_handle, "ptlbd_sv", 
+                                obddev->obd_proc_entry);
 
         if (ptlbd->ptlbd_service == NULL) 
                 GOTO(out_filp, rc = -ENOMEM);
 
-        rc = ptlrpc_start_thread(obddev, ptlbd->ptlbd_service, "ptldb");
+        rc = ptlrpc_start_n_threads(obddev, ptlbd->ptlbd_service, 1, "ptldb");
         if (rc != 0) 
                 GOTO(out_thread, rc);
 
@@ -66,7 +67,6 @@ static int ptlbd_sv_setup(struct obd_device *obddev, obd_count len, void *buf)
         RETURN(0);
 
 out_thread:
-        ptlrpc_stop_all_threads(ptlbd->ptlbd_service);
         ptlrpc_unregister_service(ptlbd->ptlbd_service);
 out_filp:
         filp_close(ptlbd->filp, NULL);
diff --git a/lustre/ptlrpc/Makefile.am b/lustre/ptlrpc/Makefile.am
index 355d48c30cfffef80a3d3572cb74df2b3df9c5dd..09f935fe911e33f3aa1c62fa058e4de45dd45f8d 100644
--- a/lustre/ptlrpc/Makefile.am
+++ b/lustre/ptlrpc/Makefile.am
@@ -5,18 +5,34 @@
 
 DEFS=
 
+LDLMSOURCES= $(top_srcdir)/ldlm/l_lock.c $(top_srcdir)/ldlm/ldlm_lock.c \
+   $(top_srcdir)/ldlm/ldlm_resource.c $(top_srcdir)/ldlm/ldlm_lib.c     \
+   $(top_srcdir)/ldlm/ldlm_plain.c $(top_srcdir)/ldlm/ldlm_extent.c     \
+   $(top_srcdir)/ldlm/ldlm_flock.c $(top_srcdir)/ldlm/ldlm_request.c    \
+   $(top_srcdir)/ldlm/ldlm_lockd.c $(top_srcdir)/ldlm/ldlm_internal.h
+
 if LIBLUSTRE
+
 lib_LIBRARIES = libptlrpc.a
 libptlrpc_a_SOURCES = client.c niobuf.c pack_generic.c recover.c connection.c \
-ptlrpc_module.c events.c ptlrpc_lib.c
+ptlrpc_module.c events.c service.c pinger.c import.c \
+recov_thread.c llog_net.c llog_client.c $(LDLMSOURCES)
+
 else
+
 MODULE = ptlrpc
 modulefs_DATA = ptlrpc.o
 EXTRA_PROGRAMS = ptlrpc
 
 ptlrpc_SOURCES = recover.c connection.c ptlrpc_module.c events.c service.c \
-client.c niobuf.c pack_generic.c lproc_ptlrpc.c pinger.c ptlrpc_lib.c \
-ptlrpc_internal.h recov_thread.c
+   client.c niobuf.c pack_generic.c lproc_ptlrpc.c pinger.c                \
+   ptlrpc_internal.h recov_thread.c import.c llog_net.c llog_server.c      \
+   llog_client.c $(LDLMSOURCES)
 endif
 
+ptlrpc_DEPENDENCIES=symlinks
+
+symlinks:
+	ln -sf $(subst /ldlm/,/ptlrpc/,$(addsuffix .o,$(basename $(LDLMSOURCES)))) ../ldlm
+
 include $(top_srcdir)/Rules
diff --git a/lustre/ptlrpc/Makefile.mk b/lustre/ptlrpc/Makefile.mk
index 064cf51065b9a2f3ea0a1b387211d49ccfc74f18..a2801c83113dfa2f044b5f79fac445ea95d5dfdb 100644
--- a/lustre/ptlrpc/Makefile.mk
+++ b/lustre/ptlrpc/Makefile.mk
@@ -8,4 +8,4 @@ include $(src)/../portals/Kernelenv
 obj-y += ptlrpc.o
 ptlrpc-objs := recover.o connection.o ptlrpc_module.o events.o service.o \
 		client.o niobuf.o pack_generic.o lproc_ptlrpc.o pinger.o \
-		recov_thread.o ptlrpc_lib.o
+		recov_thread.o ptlrpc_lib.o import.o llog_net.o llogd.o
diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c
index 18a75a5de586f6e1b953910bedca949adefa8fc9..60f2d4eef6f07dba0d51886fd4ba2fdf0eeed702 100644
--- a/lustre/ptlrpc/client.c
+++ b/lustre/ptlrpc/client.c
@@ -64,7 +64,6 @@ struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid)
         if (c) {
                 memcpy(c->c_remote_uuid.uuid,
                        uuid->uuid, sizeof(c->c_remote_uuid.uuid));
-                c->c_epoch++;
         }
 
         CDEBUG(D_INFO, "%s -> %p\n", uuid->uuid, c);
@@ -227,16 +226,18 @@ struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode,
                 RETURN(NULL);
         }
 
-        rc = lustre_pack_msg(count, lengths, bufs,
-                             &request->rq_reqlen, &request->rq_reqmsg);
+        rc = lustre_pack_request(request, count, lengths, bufs);
         if (rc) {
                 CERROR("cannot pack request %d\n", rc);
                 OBD_FREE(request, sizeof(*request));
                 RETURN(NULL);
         }
 
-        request->rq_timeout = obd_timeout;
-        request->rq_level = LUSTRE_CONN_FULL;
+        if (imp->imp_server_timeout)
+                request->rq_timeout = obd_timeout / 2;
+        else
+                request->rq_timeout = obd_timeout;
+        request->rq_send_state = LUSTRE_IMP_FULL;
         request->rq_type = PTL_RPC_MSG_REQUEST;
         request->rq_import = class_import_get(imp);
         request->rq_phase = RQ_PHASE_NEW;
@@ -269,6 +270,8 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void)
         INIT_LIST_HEAD(&set->set_requests);
         init_waitqueue_head(&set->set_waitq);
         set->set_remaining = 0;
+        spin_lock_init(&set->set_new_req_lock);
+        INIT_LIST_HEAD(&set->set_new_requests);
 
         RETURN(set);
 }
@@ -337,6 +340,66 @@ void ptlrpc_set_add_req(struct ptlrpc_request_set *set,
         set->set_remaining++;
 }
 
+/* lock so many callers can add things, the context that owns the set
+ * is supposed to notice these and move them into the set proper. */
+void ptlrpc_set_add_new_req(struct ptlrpc_request_set *set,
+                            struct ptlrpc_request *req)
+{
+        unsigned long flags;
+        spin_lock_irqsave(&set->set_new_req_lock, flags);
+        /* The set takes over the caller's request reference */
+        list_add_tail(&req->rq_set_chain, &set->set_new_requests);
+        req->rq_set = set;
+        spin_unlock_irqrestore(&set->set_new_req_lock, flags);
+}
+
+/*
+ * Based on the current state of the import, determine if the request
+ * can be sent, is an error, or should be delayed.
+ *
+ * Returns true if this request should be delayed. If false, and
+ * *status is set, then the request can not be sent and *status is the
+ * error code.  If false and status is 0, then request can be sent.
+ *
+ * The imp->imp_lock must be held.
+ */
+static int ptlrpc_import_delay_req(struct obd_import *imp, 
+                                   struct ptlrpc_request *req, int *status)
+{
+        int delay = 0;
+        ENTRY;
+
+        LASSERT (status != NULL);
+        *status = 0;
+
+        /* A new import, or one that has been cleaned up.
+         */
+        if (imp->imp_state == LUSTRE_IMP_NEW) {
+                DEBUG_REQ(D_ERROR, req, "Uninitialized import.");
+                *status = -EIO;
+        }
+        /*
+         * If the import has been invalidated (such as by an OST failure), the
+         * request must fail with -EIO.  
+         */
+        else if (imp->imp_invalid) {
+                DEBUG_REQ(D_ERROR, req, "IMP_INVALID");
+                *status = -EIO;
+        } 
+        else if (req->rq_import_generation != imp->imp_generation) {
+                DEBUG_REQ(D_ERROR, req, "req wrong generation:");
+                *status = -EIO;
+        } 
+        else if (req->rq_send_state != imp->imp_state) {
+                if (imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) 
+                        *status = -EWOULDBLOCK;
+                else
+                        delay = 1;
+        }
+
+        RETURN(delay);
+}
+
 static int ptlrpc_check_reply(struct ptlrpc_request *req)
 {
         unsigned long flags;
@@ -379,9 +442,7 @@ static int ptlrpc_check_status(struct ptlrpc_request *req)
 
         err = req->rq_repmsg->status;
         if (req->rq_repmsg->type == PTL_RPC_MSG_ERR) {
-                DEBUG_REQ(D_ERROR, req, "type == PTL_RPC_MSG_ERR (%d)", err);
-                if (err >= 0)
-                        CERROR("Error Reply has >= zero status\n");
+                DEBUG_REQ(D_ERROR, req, "type == PTL_RPC_MSG_ERR");
                 RETURN(err < 0 ? err : -EINVAL);
         }
 
@@ -437,7 +498,7 @@ static int after_reply(struct ptlrpc_request *req, int *restartp)
          * some reason. Try to reconnect, and if that fails, punt to the
          * upcall. */
         if (rc == -ENOTCONN) {
-                if (req->rq_level < LUSTRE_CONN_FULL || req->rq_no_recov ||
+                if (req->rq_send_state != LUSTRE_IMP_FULL ||
                     imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) {
                         RETURN(-ENOTCONN);
                 }
@@ -468,8 +529,10 @@ static int after_reply(struct ptlrpc_request *req, int *restartp)
 
         if (req->rq_import->imp_replayable) {
                 spin_lock_irqsave(&imp->imp_lock, flags);
-                if ((req->rq_replay || req->rq_transno != 0) && rc >= 0)
+                if (req->rq_replay || req->rq_transno != 0)
                         ptlrpc_retain_replayable_request(req, imp);
+                else if (req->rq_commit_cb != NULL)
+                        req->rq_commit_cb(req);
 
                 if (req->rq_transno > imp->imp_max_transno)
                         imp->imp_max_transno = req->rq_transno;
@@ -485,10 +548,77 @@ static int after_reply(struct ptlrpc_request *req, int *restartp)
         RETURN(rc);
 }
 
+static int ptlrpc_send_new_req(struct ptlrpc_request *req)
+{
+        struct obd_import     *imp;
+        unsigned long          flags;
+        int rc;
+        ENTRY;
+
+        LASSERT(req->rq_send_state == LUSTRE_IMP_FULL);
+        LASSERT(req->rq_phase == RQ_PHASE_NEW);
+        req->rq_phase = RQ_PHASE_RPC;
+
+        imp = req->rq_import;
+        spin_lock_irqsave(&imp->imp_lock, flags);
+
+        if (imp->imp_invalid) {
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                req->rq_status = -EIO;
+                req->rq_phase = RQ_PHASE_INTERPRET;
+                RETURN(-EIO);
+        }
+
+        req->rq_import_generation = imp->imp_generation;
+
+        if (ptlrpc_import_delay_req(imp, req, &rc)) {
+                spin_lock (&req->rq_lock);
+                req->rq_waiting = 1;
+                spin_unlock (&req->rq_lock);
+
+                LASSERT(list_empty (&req->rq_list));
+
+                // list_del(&req->rq_list);
+                list_add_tail(&req->rq_list, &imp->imp_delayed_list);
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                RETURN(0);
+        }
+
+        if (rc != 0) {
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                req->rq_status = rc;
+                req->rq_phase = RQ_PHASE_INTERPRET;
+                RETURN(rc);
+        }
+
+        /* XXX this is the same as ptlrpc_queue_wait */
+        LASSERT(list_empty(&req->rq_list));
+        list_add_tail(&req->rq_list, &imp->imp_sending_list);
+        spin_unlock_irqrestore(&imp->imp_lock, flags);
+
+        req->rq_reqmsg->status = current->pid;
+        CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:ni:nid:opc"
+               " %s:%s:%d:"LPU64":%s:"LPX64":%d\n", current->comm,
+               imp->imp_obd->obd_uuid.uuid, req->rq_reqmsg->status,
+               req->rq_xid,
+               imp->imp_connection->c_peer.peer_ni->pni_name,
+               imp->imp_connection->c_peer.peer_nid,
+               req->rq_reqmsg->opc);
+
+        rc = ptl_send_rpc(req);
+        if (rc) {
+                DEBUG_REQ(D_HA, req, "send failed (%d); expect timeout", rc);
+                req->rq_timeout = 1;
+                RETURN(rc);
+        }
+        RETURN(0);
+}
+
 int ptlrpc_check_set(struct ptlrpc_request_set *set)
 {
         unsigned long flags;
         struct list_head *tmp;
+        int sending_error = 0;
         ENTRY;
 
         if (set->set_remaining == 0)
@@ -500,6 +630,11 @@ int ptlrpc_check_set(struct ptlrpc_request_set *set)
                 struct obd_import *imp = req->rq_import;
                 int rc = 0;
 
+                if (req->rq_phase == RQ_PHASE_NEW &&
+                    ptlrpc_send_new_req(req)) {
+                        sending_error = 1;
+                }
+
                 if (!(req->rq_phase == RQ_PHASE_RPC ||
                       req->rq_phase == RQ_PHASE_BULK ||
                       req->rq_phase == RQ_PHASE_INTERPRET ||
@@ -543,21 +678,21 @@ int ptlrpc_check_set(struct ptlrpc_request_set *set)
                 if (req->rq_phase == RQ_PHASE_RPC) {
                         int do_restart = 0;
                         if (req->rq_waiting || req->rq_resend) {
+                                int status;
                                 spin_lock_irqsave(&imp->imp_lock, flags);
 
-                                if (req->rq_level > imp->imp_level) {
+                                if (ptlrpc_import_delay_req(imp, req, &status)) {
                                         spin_unlock_irqrestore(&imp->imp_lock,
                                                                flags);
                                         continue;
-                                }
+                                } 
 
                                 list_del(&req->rq_list);
                                 list_add_tail(&req->rq_list,
                                               &imp->imp_sending_list);
 
-                                if (req->rq_import_generation <
-                                    imp->imp_generation) {
-                                        req->rq_status = -EIO;
+                                if (status != 0)  {
+                                        req->rq_status = status;
                                         req->rq_phase = RQ_PHASE_INTERPRET;
                                         spin_unlock_irqrestore(&imp->imp_lock,
                                                                flags);
@@ -575,17 +710,25 @@ int ptlrpc_check_set(struct ptlrpc_request_set *set)
                                                                flags);
 
                                         ptlrpc_unregister_reply(req);
-                                        if (req->rq_bulk)
+                                        if (req->rq_bulk) {
+                                                __u64 old_xid = req->rq_xid;
                                                 ptlrpc_unregister_bulk(req);
+                                                /* ensure previous bulk fails */
+                                                req->rq_xid = ptlrpc_next_xid();
+                                                CDEBUG(D_HA, "resend bulk "
+                                                       "old x"LPU64
+                                                       " new x"LPU64"\n",
+                                                       old_xid, req->rq_xid);
+                                        }
                                 }
 
                                 rc = ptl_send_rpc(req);
                                 if (rc) {
-                                        req->rq_status = rc;
-                                        req->rq_phase = RQ_PHASE_INTERPRET;
-                                        GOTO(interpret, req->rq_status);
+                                        DEBUG_REQ(D_HA, req, "send failed (%d)",
+                                                  rc);
+                                        sending_error = 1;
+                                        req->rq_timeout = 0;
                                 }
-
                         }
 
                         /* Ensure the network callback returned */
@@ -654,7 +797,8 @@ int ptlrpc_check_set(struct ptlrpc_request_set *set)
                 set->set_remaining--;
         }
 
-        RETURN(set->set_remaining == 0);
+        /* If we hit an error, we want to recover promptly. */
+        RETURN(set->set_remaining == 0 || sending_error);
 }
 
 int ptlrpc_expire_one_request(struct ptlrpc_request *req)
@@ -682,8 +826,7 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req)
 
         /* If this request is for recovery or other primordial tasks,
          * don't go back to sleep, and don't start recovery again.. */
-        if (req->rq_level < LUSTRE_CONN_FULL || req->rq_no_recov ||
-            imp->imp_obd->obd_no_recov)
+        if (req->rq_send_state != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov)
                 RETURN(1);
 
         ptlrpc_fail_import(imp, req->rq_import_generation);
@@ -691,7 +834,7 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-static int expired_set(void *data)
+int ptlrpc_expired_set(void *data)
 {
         struct ptlrpc_request_set *set = data;
         struct list_head          *tmp;
@@ -725,7 +868,7 @@ static int expired_set(void *data)
         RETURN(1);
 }
 
-static void interrupted_set(void *data)
+void ptlrpc_interrupted_set(void *data)
 {
         struct ptlrpc_request_set *set = data;
         struct list_head *tmp;
@@ -747,109 +890,62 @@ static void interrupted_set(void *data)
         }
 }
 
-int ptlrpc_set_wait(struct ptlrpc_request_set *set)
+int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set)
 {
         struct list_head      *tmp;
-        struct obd_import     *imp;
-        struct ptlrpc_request *req;
-        struct l_wait_info     lwi;
-        unsigned long          flags;
-        int                    rc;
-        time_t                 now;
+        time_t                 now = LTIME_S(CURRENT_TIME);
         time_t                 deadline;
-        int                    timeout;
+        int                    timeout = 0;
+        struct ptlrpc_request *req;
         ENTRY;
 
         SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
-        LASSERT(!list_empty(&set->set_requests));
+
         list_for_each(tmp, &set->set_requests) {
                 req = list_entry(tmp, struct ptlrpc_request, rq_set_chain);
 
-                LASSERT(req->rq_level == LUSTRE_CONN_FULL);
-                LASSERT(req->rq_phase == RQ_PHASE_NEW);
-                req->rq_phase = RQ_PHASE_RPC;
-
-                imp = req->rq_import;
-                spin_lock_irqsave(&imp->imp_lock, flags);
-
-                if (imp->imp_invalid) {
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
-                        req->rq_status = -EIO;
-                        req->rq_phase = RQ_PHASE_INTERPRET;
+                /* request in-flight? */
+                if (!((req->rq_phase == RQ_PHASE_RPC && !req->rq_waiting) ||
+                      (req->rq_phase == RQ_PHASE_BULK)))
                         continue;
-                }
 
-                req->rq_import_generation = imp->imp_generation;
-
-                if (req->rq_level > imp->imp_level) {
-                        if (req->rq_no_recov || imp->imp_obd->obd_no_recov ||
-                            imp->imp_dlm_fake) {
-                                spin_unlock_irqrestore(&imp->imp_lock, flags);
-                                req->rq_status = -EWOULDBLOCK;
-                                req->rq_phase = RQ_PHASE_INTERPRET;
-                                continue;
-                        }
-
-                        spin_lock (&req->rq_lock);
-                        req->rq_waiting = 1;
-                        spin_unlock (&req->rq_lock);
-                        LASSERT(list_empty (&req->rq_list));
-                        // list_del(&req->rq_list);
-                        list_add_tail(&req->rq_list, &imp->imp_delayed_list);
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
+                if (req->rq_timedout)   /* already timed out */
                         continue;
-                }
 
-                /* XXX this is the same as ptlrpc_queue_wait */
-                LASSERT(list_empty(&req->rq_list));
-                list_add_tail(&req->rq_list, &imp->imp_sending_list);
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                deadline = req->rq_sent + req->rq_timeout;
+                if (deadline <= now)    /* actually expired already */
+                        timeout = 1;    /* ASAP */
+                else if (timeout == 0 || timeout > deadline - now)
+                        timeout = deadline - now;
+        }
+        RETURN(timeout);
+}
+                
 
-                req->rq_reqmsg->status = current->pid;
-                CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:ni:nid:opc"
-                       " %s:%s:%d:"LPU64":%s:"LPX64":%d\n", current->comm,
-                       imp->imp_obd->obd_uuid.uuid, req->rq_reqmsg->status,
-                       req->rq_xid,
-                       imp->imp_connection->c_peer.peer_ni->pni_name,
-                       imp->imp_connection->c_peer.peer_nid,
-                       req->rq_reqmsg->opc);
+int ptlrpc_set_wait(struct ptlrpc_request_set *set)
+{
+        struct list_head      *tmp;
+        struct ptlrpc_request *req;
+        struct l_wait_info     lwi;
+        int                    rc, timeout;
+        ENTRY;
 
-                rc = ptl_send_rpc(req);
-                if (rc) {
-                        req->rq_status = rc;
-                        req->rq_phase = RQ_PHASE_INTERPRET;
-                }
+        LASSERT(!list_empty(&set->set_requests));
+        list_for_each(tmp, &set->set_requests) {
+                req = list_entry(tmp, struct ptlrpc_request, rq_set_chain);
+                (void)ptlrpc_send_new_req(req);
         }
 
         do {
-                now = LTIME_S (CURRENT_TIME);
-                timeout = 0;
-                list_for_each (tmp, &set->set_requests) {
-                        req = list_entry(tmp, struct ptlrpc_request,
-                                         rq_set_chain);
-
-                        /* request in-flight? */
-                        if (!((req->rq_phase == RQ_PHASE_RPC &&
-                               !req->rq_waiting) ||
-                              (req->rq_phase == RQ_PHASE_BULK)))
-                                continue;
-
-                        if (req->rq_timedout)   /* already timed out */
-                                continue;
-
-                        deadline = req->rq_sent + req->rq_timeout;
-                        if (deadline <= now)    /* actually expired already */
-                                timeout = 1;    /* ASAP */
-                        else if (timeout == 0 || timeout > deadline - now)
-                                timeout = deadline - now;
-                }
+                timeout = ptlrpc_set_next_timeout(set);
 
                 /* wait until all complete, interrupted, or an in-flight
                  * req times out */
                 CDEBUG(D_HA, "set %p going to sleep for %d seconds\n",
                        set, timeout);
                 lwi = LWI_TIMEOUT_INTR((timeout ? timeout : 1) * HZ,
-                                       expired_set, interrupted_set, set);
+                                       ptlrpc_expired_set, 
+                                       ptlrpc_interrupted_set, set);
                 rc = l_wait_event(set->set_waitq, ptlrpc_check_set(set), &lwi);
 
                 LASSERT(rc == 0 || rc == -EINTR || rc == -ETIMEDOUT);
@@ -940,14 +1036,23 @@ void ptlrpc_free_req(struct ptlrpc_request *request)
         __ptlrpc_free_req(request, 0);
 }
 
+static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked);
+void ptlrpc_req_finished_with_imp_lock(struct ptlrpc_request *request)
+{
+#ifdef CONFIG_SMP
+        LASSERT(spin_is_locked(&request->rq_import->imp_lock));
+#endif
+        (void)__ptlrpc_req_finished(request, 1);
+}
+
 static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked)
 {
         ENTRY;
         if (request == NULL)
                 RETURN(1);
 
-        if (request == (void *)(long)(0x5a5a5a5a5a5a5a5a) ||
-            request->rq_obd == (void *)(long)(0x5a5a5a5a5a5a5a5a)) {
+        if (request == (void *)(unsigned long)(0x5a5a5a5a5a5a5a5a) ||
+            request->rq_reqmsg == (void *)(unsigned long)(0x5a5a5a5a5a5a5a5a)) {
                 CERROR("dereferencing freed request (bug 575)\n");
                 LBUG();
                 RETURN(1);
@@ -1089,6 +1194,8 @@ void ptlrpc_free_committed(struct obd_import *imp)
                 DEBUG_REQ(D_HA, req, "committing (last_committed "LPU64")",
                           imp->imp_peer_committed_transno);
 free_req:
+                if (req->rq_commit_cb != NULL)
+                        req->rq_commit_cb(req);
                 list_del_init(&req->rq_list);
                 __ptlrpc_req_finished(req, 1);
         }
@@ -1213,7 +1320,6 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         int brc;
         struct l_wait_info lwi;
         struct obd_import *imp = req->rq_import;
-        struct obd_device *obd = imp->imp_obd;
         unsigned long flags;
         int do_restart = 0;
         int timeout = 0;
@@ -1239,59 +1345,42 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         spin_lock_irqsave(&imp->imp_lock, flags);
         req->rq_import_generation = imp->imp_generation;
 restart:
-        /*
-         * If the import has been invalidated (such as by an OST failure), the
-         * request must fail with -EIO.  Recovery requests are allowed to go
-         * through, though, so that they have a chance to revalidate the
-         * import.
-         */
-        if (req->rq_import->imp_invalid && req->rq_level == LUSTRE_CONN_FULL) {
-                DEBUG_REQ(D_ERROR, req, "IMP_INVALID:");
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-                GOTO(out, rc = -EIO);
-        }
-
-        if (req->rq_import_generation < imp->imp_generation) {
-                DEBUG_REQ(D_ERROR, req, "req old gen:");
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-                GOTO(out, rc = -EIO);
-        }
-
-        if (req->rq_level > imp->imp_level) {
+        if (ptlrpc_import_delay_req(imp, req, &rc)) {
                 list_del(&req->rq_list);
-                if (req->rq_no_recov || obd->obd_no_recov ||
-                    imp->imp_dlm_fake) {
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
-                        GOTO(out, rc = -EWOULDBLOCK);
-                }
 
                 list_add_tail(&req->rq_list, &imp->imp_delayed_list);
                 spin_unlock_irqrestore(&imp->imp_lock, flags);
 
                 DEBUG_REQ(D_HA, req, "\"%s\" waiting for recovery: (%d > %d)",
-                          current->comm, req->rq_level, imp->imp_level);
-                lwi = LWI_INTR(NULL, NULL);
+                          current->comm, req->rq_send_state, imp->imp_state);
+                lwi = LWI_INTR(interrupted_request, req);
                 rc = l_wait_event(req->rq_wait_for_rep,
-                                  (req->rq_level <= imp->imp_level ||
+                                  (req->rq_send_state == imp->imp_state ||
                                    req->rq_err),
                                   &lwi);
                 DEBUG_REQ(D_HA, req, "\"%s\" awake: (%d > %d or %d == 1)",
-                          current->comm, imp->imp_level, req->rq_level,
+                          current->comm, imp->imp_state, req->rq_send_state,
                           req->rq_err);
 
                 spin_lock_irqsave(&imp->imp_lock, flags);
                 list_del_init(&req->rq_list);
 
-                if (req->rq_err ||
-                    req->rq_import_generation < imp->imp_generation)
+                if (req->rq_err) {
                         rc = -EIO;
-
-                if (rc) {
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
-                        GOTO(out, rc);
+                } 
+                else if (req->rq_intr) {
+                        rc = -EINTR;
+                }
+                else {
+                        GOTO(restart, rc);
                 }
+        } 
 
-                DEBUG_REQ(D_HA, req, "resumed");
+        if (rc != 0) {
+                list_del_init(&req->rq_list);
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                req->rq_status = rc; // XXX this ok?
+                GOTO(out, rc);
         }
 
         /* XXX this is the same as ptlrpc_set_wait */
@@ -1301,52 +1390,15 @@ restart:
 
         rc = ptl_send_rpc(req);
         if (rc) {
-                /* The DLM's fake imports want to avoid all forms of
-                 * recovery. */
-                if (imp->imp_dlm_fake) {
-                        spin_lock_irqsave(&imp->imp_lock, flags);
-                        list_del_init(&req->rq_list);
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
-                        GOTO(out, rc);
-                }
-
-                DEBUG_REQ(D_ERROR, req, "send failed (%d); recovering", rc);
-
-                ptlrpc_fail_import(imp, req->rq_import_generation);
-
-                /* If we've been told to not wait, we're done. */
-                if (req->rq_level < LUSTRE_CONN_FULL || req->rq_no_recov ||
-                    obd->obd_no_recov) {
-                        spin_lock_irqsave(&imp->imp_lock, flags);
-                        list_del_init(&req->rq_list);
-                        spin_unlock_irqrestore(&imp->imp_lock, flags);
-                        GOTO(out, rc);
-                }
-
-                /* If we errored, allow the user to interrupt immediately */
+                DEBUG_REQ(D_HA, req, "send failed (%d); recovering", rc);
                 timeout = 1;
         } else {
-                timeout = req->rq_timeout * HZ;
+                timeout = MAX(req->rq_timeout * HZ, 1);
                 DEBUG_REQ(D_NET, req, "-- sleeping");
         }
-#ifdef __KERNEL__
         lwi = LWI_TIMEOUT_INTR(timeout, expired_request, interrupted_request,
                                req);
         l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi);
-#else
-        {
-                extern int reply_in_callback(ptl_event_t *ev);
-                ptl_event_t reply_ev;
-                PtlEQWait(req->rq_connection->c_peer.peer_ni->pni_reply_in_eq_h,
-                          &reply_ev);
-                reply_in_callback(&reply_ev);
-
-                LASSERT(reply_ev.mem_desc.user_ptr == (void *)req);
-                // ptlrpc_check_reply(req);
-                // not required now it only tests
-        }
-#endif
-
         DEBUG_REQ(D_NET, req, "-- done sleeping");
 
         CDEBUG(D_RPCTRACE, "Completed RPC pname:cluuid:pid:xid:ni:nid:opc "
@@ -1440,11 +1492,13 @@ restart:
 
 int ptlrpc_replay_req(struct ptlrpc_request *req)
 {
-        int rc = 0, old_level, old_status = 0;
+        int rc = 0, old_state, old_status = 0;
         // struct ptlrpc_client *cli = req->rq_import->imp_client;
         struct l_wait_info lwi;
         ENTRY;
 
+        LASSERT(req->rq_import->imp_state == LUSTRE_IMP_REPLAY);
+
         /* I don't touch rq_phase here, so the debug log can show what
          * state it was left in */
 
@@ -1458,11 +1512,19 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
         req->rq_connection =
                 ptlrpc_connection_addref(req->rq_import->imp_connection);
 
-        /* temporarily set request to RECOVD level (reset at out:) */
-        old_level = req->rq_level;
+        /* temporarily set request to REPLAY level---not strictly
+         * necessary since ptl_send_rpc doesn't check state, but let's
+         * be consistent.*/
+        old_state = req->rq_send_state;
+
+        /*
+         * Q: "How can a req get on the replay list if it wasn't replied?"
+         * A: "If we failed during the replay of this request, it will still
+         *     be on the list, but rq_replied will have been reset to 0."
+         */
         if (req->rq_replied)
                 old_status = req->rq_repmsg->status;
-        req->rq_level = LUSTRE_CONN_RECOVER;
+        req->rq_send_state = LUSTRE_IMP_REPLAY;
         rc = ptl_send_rpc(req);
         if (rc) {
                 CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc);
@@ -1510,6 +1572,10 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
         }
 #endif
 
+        if (req->rq_repmsg->type == PTL_RPC_MSG_ERR && 
+            req->rq_repmsg->status == -ENOTCONN) 
+                GOTO(out, rc = req->rq_repmsg->status);
+
         /* The transno had better not change over replay. */
         LASSERT(req->rq_reqmsg->transno == req->rq_repmsg->transno);
 
@@ -1520,12 +1586,15 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
                 req->rq_replay_cb(req);
 
         if (req->rq_replied && req->rq_repmsg->status != old_status) {
-                DEBUG_REQ(D_HA, req, "status %d, old was %d",
+                DEBUG_REQ(D_ERROR, req, "status %d, old was %d",
                           req->rq_repmsg->status, old_status);
+        } else {
+                /* Put it back for re-replay. */
+                req->rq_status = old_status;
         }
 
  out:
-        req->rq_level = old_level;
+        req->rq_send_state = old_state;
         RETURN(rc);
 }
 
diff --git a/lustre/ptlrpc/connection.c b/lustre/ptlrpc/connection.c
index 6b7690b3000ad92601c169a6b5374af28dd97252..466916b53879c1418219a3e293488a08dcc4a0a1 100644
--- a/lustre/ptlrpc/connection.c
+++ b/lustre/ptlrpc/connection.c
@@ -62,13 +62,6 @@ struct ptlrpc_connection *ptlrpc_get_connection(struct ptlrpc_peer *peer,
                peer->peer_nid, peer->peer_ni->pni_name);
 
         spin_lock(&conn_lock);
-        if (list_empty(&conn_list)) {
-                if (!ptlrpc_get_ldlm_hooks()) {
-                        spin_unlock(&conn_lock);
-                        RETURN(NULL);
-                }
-        }
-
         list_for_each(tmp, &conn_list) {
                 c = list_entry(tmp, struct ptlrpc_connection, c_link);
                 if (peer->peer_nid == c->c_peer.peer_nid &&
@@ -95,15 +88,10 @@ struct ptlrpc_connection *ptlrpc_get_connection(struct ptlrpc_peer *peer,
         if (c == NULL)
                 GOTO(out, c);
 
-        c->c_generation = 1;
-        c->c_epoch = 1;
-        c->c_bootcount = 0;
-        c->c_flags = 0;
         if (uuid && uuid->uuid)                         /* XXX ???? */
                 obd_str2uuid(&c->c_remote_uuid, uuid->uuid);
         atomic_set(&c->c_refcount, 0);
         memcpy(&c->c_peer, peer, sizeof(c->c_peer));
-        spin_lock_init(&c->c_lock);
 
         ptlrpc_connection_addref(c);
 
@@ -133,9 +121,6 @@ int ptlrpc_put_connection(struct ptlrpc_connection *c)
                 spin_lock(&conn_lock);
                 list_del(&c->c_link);
                 list_add(&c->c_link, &conn_unused_list);
-                if (list_empty(&conn_list)) {
-                        ptlrpc_put_ldlm_hooks();
-                }
                 spin_unlock(&conn_lock);
                 rc = 1;
         }
diff --git a/lustre/ptlrpc/events.c b/lustre/ptlrpc/events.c
index 25580bfd6b702a905498666942fc90f8fe01ce89..7807dcca16c4ff1c2ac12524487247c1ffbe0e5a 100644
--- a/lustre/ptlrpc/events.c
+++ b/lustre/ptlrpc/events.c
@@ -99,7 +99,7 @@ int reply_in_callback(ptl_event_t *ev)
         /* replies always contiguous */
         LASSERT((ev->mem_desc.options & (PTL_MD_IOV | PTL_MD_KIOV)) == 0);
 
-        if (req->rq_xid == 0x5a5a5a5a5a5a5a5a) {
+        if (req->rq_xid == 0x5a5a5a5a5a5a5a5aULL) {
                 CERROR("Reply received for freed request!  Probably a missing "
                        "ptlrpc_abort()\n");
                 LBUG();
@@ -218,7 +218,7 @@ static int bulk_put_sink_callback(ptl_event_t *ev)
         LASSERT((ev->mem_desc.options & (PTL_MD_IOV | PTL_MD_KIOV)) ==
                 PTL_MD_KIOV);
         /* Honestly, it's best to find out early. */
-        if (desc->bd_page_count == 0x5a5a5a5a5a ||
+        if (desc->bd_page_count == 0x5a5a5a5a ||
             desc->bd_page_count != ev->mem_desc.niov ||
             ev->mem_desc.start != &desc->bd_iov) {
                 /* not guaranteed (don't LASSERT) but good for this bug hunt */
@@ -453,6 +453,60 @@ int ptlrpc_ni_init(int number, char *name, struct ptlrpc_ni *pni)
         return (rc);
 }
 
+#ifndef __KERNEL__
+int
+liblustre_check_events (int block)
+{
+        ptl_event_t ev;
+        int         rc;
+        ENTRY;
+
+        if (block) {
+                /* XXX to accelerate recovery tests XXX */
+                if (block > 10)
+                        block = 10;
+                rc = PtlEQWait_timeout(ptlrpc_interfaces[0].pni_eq_h, &ev, block);
+        } else {
+                rc = PtlEQGet (ptlrpc_interfaces[0].pni_eq_h, &ev);
+        }
+        if (rc == PTL_EQ_EMPTY)
+                RETURN(0);
+        
+        LASSERT (rc == PTL_EQ_DROPPED || rc == PTL_OK);
+        
+#if PORTALS_DOES_NOT_SUPPORT_CALLBACKS
+        if (rc == PTL_EQ_DROPPED)
+                CERROR ("Dropped an event!!!\n");
+        
+        ptlrpc_master_callback (&ev);
+#endif
+        RETURN(1);
+}
+
+int liblustre_wait_event(struct l_wait_info *lwi) 
+{
+        ENTRY;
+
+        /* non-blocking checks (actually we might block in a service for
+         * bulk but we won't block in a blocked service)
+         */
+        if (liblustre_check_events(0) ||
+            liblustre_check_services()) {
+                /* the condition the caller is waiting for may now hold */
+                RETURN(0);
+        }
+        
+        /* block for an event */
+        liblustre_check_events(lwi->lwi_timeout);
+
+        /* check it's not for some service */
+        liblustre_check_services ();
+
+        /* XXX check this */
+        RETURN(0);
+}
+#endif
+
 int ptlrpc_init_portals(void)
 {
         /* Add new portals network interfaces here.
@@ -464,6 +518,7 @@ int ptlrpc_init_portals(void)
                 {QSWNAL,  "qswnal"},
                 {SOCKNAL, "socknal"},
                 {GMNAL,   "gmnal"},
+                {IBNAL,   "ibnal"},
                 {TOENAL,  "toenal"},
                 {TCPNAL,  "tcpnal"},
                 {SCIMACNAL, "scimacnal"}};
diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c
new file mode 100644
index 0000000000000000000000000000000000000000..80742c8befab9931e3c05f055dbdafd4e90ba8fc
--- /dev/null
+++ b/lustre/ptlrpc/import.c
@@ -0,0 +1,210 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Mike Shaver <shaver@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_RPC
+#ifdef __KERNEL__
+# include <linux/config.h>
+# include <linux/module.h>
+# include <linux/kmod.h>
+#else
+# include <liblustre.h>
+#endif
+
+#include <linux/obd_support.h>
+#include <linux/lustre_ha.h>
+#include <linux/lustre_net.h>
+#include <linux/lustre_import.h>
+#include <linux/lustre_export.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+
+#include "ptlrpc_internal.h"
+
+/* should this take an imp_sem to ensure connect is single threaded? */
+int ptlrpc_connect_import(struct obd_import *imp)
+{
+        struct obd_device *obd = imp->imp_obd;
+        int msg_flags;
+        int initial_connect = 0;
+        int rc;
+        __u64 committed_before_reconnect = 0;
+        struct ptlrpc_request *request;
+        struct lustre_handle old_hdl;
+        int size[] = {sizeof(imp->imp_target_uuid),
+                                 sizeof(obd->obd_uuid),
+                                 sizeof(imp->imp_dlm_handle)};
+        char *tmp[] = {imp->imp_target_uuid.uuid,
+                       obd->obd_uuid.uuid,
+                       (char *)&imp->imp_dlm_handle};
+        unsigned long flags;
+
+        spin_lock_irqsave(&imp->imp_lock, flags);
+        if (imp->imp_state == LUSTRE_IMP_CONNECTING) {
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                RETURN(-EALREADY);
+        } else {
+                LASSERT(imp->imp_state == LUSTRE_IMP_DISCON);
+        }
+        CDEBUG(D_HA, "%s: new state: CONNECTING\n", 
+               imp->imp_client->cli_name);
+        imp->imp_state = LUSTRE_IMP_CONNECTING;
+        imp->imp_conn_cnt++; 
+        if (imp->imp_remote_handle.cookie == 0) {
+                initial_connect = 1;
+        } else {
+                committed_before_reconnect = imp->imp_peer_committed_transno;
+        }
+        spin_unlock_irqrestore(&imp->imp_lock, flags);
+
+        request = ptlrpc_prep_req(imp, imp->imp_connect_op, 3, size, tmp);
+        if (!request)
+                GOTO(out, rc = -ENOMEM);
+
+        request->rq_send_state = LUSTRE_IMP_CONNECTING;
+        request->rq_replen = lustre_msg_size(0, NULL);
+
+        // lustre_msg_add_op_flags(request->rq_reqmsg, MSG_CONNECT_PEER);
+
+        rc = ptlrpc_queue_wait(request);
+        if (rc) {
+                GOTO(free_req, rc);
+        }
+
+        msg_flags = lustre_msg_get_op_flags(request->rq_repmsg);
+
+        if (initial_connect) {
+                CDEBUG(D_HA, "%s: new state: FULL\n", 
+                       imp->imp_client->cli_name);
+                if (msg_flags & MSG_CONNECT_REPLAYABLE)
+                        imp->imp_replayable = 1;
+                imp->imp_remote_handle = request->rq_repmsg->handle;
+                imp->imp_state = LUSTRE_IMP_FULL;
+                GOTO(free_req, rc = 0);
+        }
+
+        /* Determine what recovery state to move the import to. */
+        if (MSG_CONNECT_RECONNECT & msg_flags) {
+                memset(&old_hdl, 0, sizeof(old_hdl));
+                if (!memcmp(&old_hdl, &request->rq_repmsg->handle,
+                            sizeof (old_hdl))) {
+                        CERROR("%s@%s didn't like our handle "LPX64
+                               ", failed\n", imp->imp_target_uuid.uuid,
+                               imp->imp_connection->c_remote_uuid.uuid,
+                               imp->imp_dlm_handle.cookie);
+                        GOTO(free_req, rc = -ENOTCONN);
+                }
+
+                if (memcmp(&imp->imp_remote_handle, &request->rq_repmsg->handle,
+                           sizeof(imp->imp_remote_handle))) {
+                        CERROR("%s@%s changed handle from "LPX64" to "LPX64
+                               "; copying, but this may foreshadow disaster\n",
+                               imp->imp_target_uuid.uuid,
+                               imp->imp_connection->c_remote_uuid.uuid,
+                               imp->imp_remote_handle.cookie,
+                               request->rq_repmsg->handle.cookie);
+                        imp->imp_remote_handle = request->rq_repmsg->handle;
+                } else {
+                        CERROR("reconnected to %s@%s after partition\n",
+                               imp->imp_target_uuid.uuid, 
+                               imp->imp_connection->c_remote_uuid.uuid);
+                }
+                CDEBUG(D_HA, "%s: new state: RECOVER\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_RECOVER;
+        } 
+        else if (MSG_CONNECT_RECOVERING & msg_flags) {
+                CDEBUG(D_HA, "%s: new state: REPLAY\n", 
+                       imp->imp_client->cli_name);
+                LASSERT(imp->imp_replayable);
+                imp->imp_state = LUSTRE_IMP_RECOVER;
+                imp->imp_remote_handle = request->rq_repmsg->handle;
+                imp->imp_state = LUSTRE_IMP_REPLAY;
+        } 
+        else {
+                CDEBUG(D_HA, "%s: new state: EVICTED\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_remote_handle = request->rq_repmsg->handle;
+                imp->imp_state = LUSTRE_IMP_EVICTED;
+        }
+        
+        /* Sanity checks for a reconnected import. */
+        if (!(imp->imp_replayable) != 
+             !(msg_flags & MSG_CONNECT_REPLAYABLE)) {
+                CERROR("imp_replayable flag does not match server "
+                       "after reconnect. We should LBUG right here.\n");
+        }
+
+        if (request->rq_repmsg->last_committed < committed_before_reconnect) {
+                CERROR("%s went back in time (transno "LPD64
+                       " was previously committed, server now claims "LPD64
+                       ")! is shared storage not coherent?\n",
+                       imp->imp_target_uuid.uuid,
+                       committed_before_reconnect,
+                       request->rq_repmsg->last_committed);
+        }
+
+ free_req:
+        ptlrpc_req_finished(request);
+
+ out:
+        if (rc != 0)
+                imp->imp_state = LUSTRE_IMP_DISCON;
+        RETURN(rc);
+}
+
+
+
+int ptlrpc_disconnect_import(struct obd_import *imp)
+{
+        struct ptlrpc_request *request;
+        int rq_opc;
+        int rc = 0;
+        ENTRY;
+
+        switch (imp->imp_connect_op) {
+        case OST_CONNECT: rq_opc = OST_DISCONNECT; break;
+        case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break;
+        case MGMT_CONNECT:rq_opc = MGMT_DISCONNECT;break;
+        default:
+                CERROR("don't know how to disconnect from %s (connect_op %d)\n",
+                       imp->imp_target_uuid.uuid, imp->imp_connect_op);
+                RETURN(-EINVAL);
+        }
+
+        request = ptlrpc_prep_req(imp, rq_opc, 0, NULL, NULL);
+        if (request) {
+                /* For non-replayable connections, don't attempt
+                   reconnect if this fails */
+                if (!imp->imp_obd->obd_replayable) {
+                        imp->imp_state = LUSTRE_IMP_DISCON;
+                        request->rq_send_state =  LUSTRE_IMP_DISCON;
+                }
+                request->rq_replen = lustre_msg_size(0, NULL);
+                rc = ptlrpc_queue_wait(request);
+                ptlrpc_req_finished(request);
+        }
+
+        imp->imp_state = LUSTRE_IMP_DISCON;
+        memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
+        RETURN(rc);
+}
+
diff --git a/lustre/ptlrpc/llog_client.c b/lustre/ptlrpc/llog_client.c
new file mode 100644
index 0000000000000000000000000000000000000000..55248433e890b9a988d7e76bb3b7ce6bfb0a2267
--- /dev/null
+++ b/lustre/ptlrpc/llog_client.c
@@ -0,0 +1,217 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  remote api for llog - client side
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <linux/lustre_net.h>
+#include <portals/list.h>
+
+/* This is a callback from the llog_* functions.
+ * Assumes caller has already pushed us into the kernel context. */
+static int llog_client_create(struct llog_ctxt *ctxt, struct llog_handle **res,
+                            struct llog_logid *logid, char *name)
+{
+        struct obd_import *imp;
+        struct llogd_body req_body;
+        struct llogd_body *body;
+        struct llog_handle *handle;
+        struct ptlrpc_request *req = NULL;
+        int size[2] = {sizeof(req_body)};
+        char *tmp[2] = {(char*) &req_body};
+        int bufcount = 1;
+        int repsize[] = {sizeof (req_body)};
+        int rc;
+        ENTRY;
+
+        LASSERT(ctxt->loc_imp);
+        imp = ctxt->loc_imp;
+
+        handle = llog_alloc_handle();
+        if (handle == NULL)
+                RETURN(-ENOMEM);
+        *res = handle;
+
+        memset(&req_body, 0, sizeof(req_body));
+        if (logid)
+                req_body.lgd_logid = *logid;
+        req_body.lgd_ctxt_idx = ctxt->loc_idx - 1;
+
+        if (name) {
+                size[bufcount] = strlen(name) + 1;
+                tmp[bufcount] = name;
+                bufcount++;
+        }
+
+        req = ptlrpc_prep_req(imp, LLOG_ORIGIN_HANDLE_CREATE,bufcount,size,tmp);
+        if (!req)
+                GOTO(err_free, rc = -ENOMEM);
+
+        req->rq_replen = lustre_msg_size(1, repsize);
+        rc = ptlrpc_queue_wait(req);
+        if (rc)
+                GOTO(err_free, rc);
+
+	body = lustre_swab_repbuf(req, 0, sizeof(*body),
+                                 lustre_swab_llogd_body);
+	if (body == NULL) {
+                CERROR ("Can't unpack llogd_body\n");
+                GOTO(err_free, rc =-EFAULT);
+	}
+
+        handle->lgh_id = body->lgd_logid;
+        handle->lgh_ctxt = ctxt;
+
+out:
+        if (req)
+                ptlrpc_req_finished(req);
+        RETURN(rc);
+
+err_free:
+        llog_free_handle(handle);
+        goto out;
+}
+
+
+static int llog_client_next_block(struct llog_handle *loghandle,
+                                  int *cur_idx, int next_idx,
+                                  __u64 *cur_offset, void *buf, int len)
+{
+        struct obd_import *imp = loghandle->lgh_ctxt->loc_imp;
+        struct ptlrpc_request *req = NULL;
+        struct llogd_body *body;
+        void * ptr;
+        int size = sizeof(*body);
+        int repsize[2] = {sizeof (*body)};
+        int rc;
+        ENTRY;
+
+        req = ptlrpc_prep_req(imp, LLOG_ORIGIN_HANDLE_NEXT_BLOCK, 1,&size,NULL);
+        if (!req)
+                GOTO(out, rc = -ENOMEM);
+
+        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
+        body->lgd_logid = loghandle->lgh_id;
+        body->lgd_ctxt_idx = loghandle->lgh_ctxt->loc_idx - 1;
+        body->lgd_llh_flags = loghandle->lgh_hdr->llh_flags;
+        body->lgd_index = next_idx;
+        body->lgd_saved_index = *cur_idx;
+        body->lgd_len = len;
+        body->lgd_cur_offset = *cur_offset;
+        repsize[1] = len;
+
+        req->rq_replen = lustre_msg_size(2, repsize);
+        rc = ptlrpc_queue_wait(req);
+        if (rc)
+                GOTO(out, rc);
+
+	body = lustre_swab_repbuf(req, 0, sizeof(*body),
+                                 lustre_swab_llogd_body);
+	if (body == NULL) {
+                CERROR ("Can't unpack llogd_body\n");
+                GOTO(out, rc =-EFAULT);
+	}
+
+        ptr = lustre_msg_buf(req->rq_repmsg, 1, len);
+	if (ptr == NULL) {
+                CERROR ("Can't unpack bitmap\n");
+                GOTO(out, rc =-EFAULT);
+	}
+
+        *cur_idx = body->lgd_saved_index;
+        *cur_offset = body->lgd_cur_offset;
+
+        memcpy(buf, ptr, len);
+
+out:
+        if (req)
+                ptlrpc_req_finished(req);
+        RETURN(rc);
+}
+
+
+static int llog_client_read_header(struct llog_handle *handle)
+{
+        struct obd_import *imp = handle->lgh_ctxt->loc_imp;
+        struct ptlrpc_request *req = NULL;
+        struct llogd_body *body;
+        struct llog_log_hdr *hdr;
+        int size = sizeof(*body);
+        int repsize = sizeof (*hdr);
+        int rc;
+        ENTRY;
+
+        req = ptlrpc_prep_req(imp, LLOG_ORIGIN_HANDLE_READ_HEADER,1,&size,NULL);
+        if (!req)
+                GOTO(out, rc = -ENOMEM);
+
+        body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
+        body->lgd_logid = handle->lgh_id;
+        body->lgd_ctxt_idx = handle->lgh_ctxt->loc_idx - 1;
+        body->lgd_llh_flags = handle->lgh_hdr->llh_flags;
+
+        req->rq_replen = lustre_msg_size(1, &repsize);
+        rc = ptlrpc_queue_wait(req);
+        if (rc)
+                GOTO(out, rc);
+
+	hdr = lustre_swab_repbuf(req, 0, sizeof(*hdr), lustre_swab_llog_hdr);
+	if (hdr == NULL) {
+                CERROR ("Can't unpack llog_hdr\n");
+                GOTO(out, rc =-EFAULT);
+	}
+        memcpy(handle->lgh_hdr, hdr, sizeof (*hdr));
+
+out:
+        if (req)
+                ptlrpc_req_finished(req);
+        RETURN(rc);
+}
+
+static int llog_client_close(struct llog_handle *handle)
+{
+        int rc = 0;
+
+        RETURN(rc);
+}
+
+
+struct llog_operations llog_client_ops = {
+        lop_next_block:  llog_client_next_block,
+        lop_read_header: llog_client_read_header,
+        lop_create:      llog_client_create,
+        lop_close:       llog_client_close,
+};
diff --git a/lustre/ptlrpc/llog_net.c b/lustre/ptlrpc/llog_net.c
new file mode 100644
index 0000000000000000000000000000000000000000..1dd2f9a694c540383609331cc4b2c9e1c2723b29
--- /dev/null
+++ b/lustre/ptlrpc/llog_net.c
@@ -0,0 +1,130 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * OST<->MDS recovery logging infrastructure.
+ *
+ * Invariants in implementation:
+ * - we do not share logs among different OST<->MDS connections, so that
+ *   if an OST or MDS fails it need only look at log(s) relevant to itself
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <portals/list.h>
+#include <linux/lvfs.h>
+
+#ifdef __KERNEL__
+int llog_origin_connect(struct llog_ctxt *ctxt, int count,
+                        struct llog_logid *logid,
+                        struct llog_ctxt_gen *gen)
+{
+        struct obd_import *imp;
+        struct ptlrpc_request *request;
+        struct llogd_conn_body *req_body;
+        int size = sizeof(struct llogd_conn_body);
+        int rc;
+        ENTRY;
+
+        LASSERT(ctxt->loc_imp);
+        imp = ctxt->loc_imp;
+
+        request = ptlrpc_prep_req(imp, LLOG_ORIGIN_CONNECT, 1, &size, NULL);
+        if (!request) 
+                RETURN(-ENOMEM);
+
+        req_body = lustre_msg_buf(request->rq_reqmsg, 0, sizeof(*req_body));
+
+        req_body->lgdc_gen = ctxt->loc_gen;
+        req_body->lgdc_logid = ctxt->loc_handle->lgh_id;
+        req_body->lgdc_ctxt_idx = ctxt->loc_idx + 1;
+        request->rq_replen = lustre_msg_size(0, NULL);
+
+        rc = ptlrpc_queue_wait(request);
+        ptlrpc_req_finished(request);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_origin_connect);
+
+int llog_handle_connect(struct ptlrpc_request *req)
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct llogd_conn_body *req_body;
+        struct llog_ctxt *ctxt;
+        int rc;
+        ENTRY;
+
+        req_body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_body));
+
+        ctxt = llog_get_context(obd, req_body->lgdc_ctxt_idx);
+        rc = llog_connect(ctxt, 1, &req_body->lgdc_logid, 
+                          &req_body->lgdc_gen);
+        if (rc != 0) 
+                CERROR("failed at llog_relp_connect\n");
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_handle_connect);
+
+int llog_receptor_accept(struct llog_ctxt *ctxt, struct obd_import *imp)
+{
+        ENTRY;
+        LASSERT(ctxt);
+        ctxt->loc_imp = imp;
+        RETURN(0);
+}
+EXPORT_SYMBOL(llog_receptor_accept);
+
+int llog_initiator_connect(struct llog_ctxt *ctxt)
+{
+        ENTRY;
+        LASSERT(ctxt);
+        ctxt->loc_imp = ctxt->loc_obd->u.cli.cl_import;
+        RETURN(0);
+}
+EXPORT_SYMBOL(llog_initiator_connect);
+
+#else /* !__KERNEL__ */
+
+int llog_origin_connect(struct llog_ctxt *ctxt, int count,
+                        struct llog_logid *logid,
+                        struct llog_ctxt_gen *gen)
+{
+        return 0;
+}
+
+int llog_initiator_connect(struct llog_ctxt *ctxt)
+{
+        return 0;
+}
+#endif
diff --git a/lustre/ptlrpc/llog_server.c b/lustre/ptlrpc/llog_server.c
new file mode 100644
index 0000000000000000000000000000000000000000..742b54588de25c1f7f88a2b6ec29099f7bd31a95
--- /dev/null
+++ b/lustre/ptlrpc/llog_server.c
@@ -0,0 +1,283 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  remote api for llog - server side
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#include <linux/fs.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_log.h>
+#include <linux/lustre_net.h>
+#include <portals/list.h>
+
+int llog_origin_handle_create(struct ptlrpc_request *req)
+{
+        struct obd_export *exp = req->rq_export;
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_device *disk_obd;
+        struct llog_handle  *loghandle;
+        struct llogd_body *body;
+        struct obd_run_ctxt saved;
+        struct llog_logid *logid = NULL;
+        struct llog_ctxt *ctxt;
+        char * name = NULL;
+        int size = sizeof (*body);
+        int rc, rc2;
+        ENTRY;
+
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body),
+                                 lustre_swab_llogd_body);
+        if (body == NULL) {
+                CERROR ("Can't unpack llogd_body\n");
+                GOTO(out, rc =-EFAULT);
+        }
+
+        if (body->lgd_logid.lgl_oid > 0)
+                logid = &body->lgd_logid;
+
+        if (req->rq_reqmsg->bufcount > 1) {
+                name = lustre_msg_string(req->rq_reqmsg, 1, 0);
+                if (name == NULL) {
+                        CERROR("Can't unpack name\n");
+                        GOTO(out, rc = -EFAULT);
+                }
+        }
+
+        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
+        LASSERT(ctxt != NULL);
+        disk_obd = ctxt->loc_exp->exp_obd;
+        push_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+
+        rc = llog_create(ctxt, &loghandle, logid, name);
+        if (rc)
+                GOTO(out_pop, rc);
+
+        rc = lustre_pack_reply(req, 1, &size, NULL);
+        if (rc)
+                GOTO(out_close, rc = -ENOMEM);
+
+        body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
+        body->lgd_logid = loghandle->lgh_id;
+
+out_close:
+        rc2 = llog_close(loghandle);
+        if (!rc)
+                rc = rc2;
+out_pop:
+        pop_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+out:
+        RETURN(rc);
+}
+
+int llog_origin_handle_next_block(struct ptlrpc_request *req)
+{
+        struct obd_export *exp = req->rq_export;
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_device *disk_obd;
+        struct llog_handle  *loghandle;
+        struct llogd_body *body;
+        struct obd_run_ctxt saved;
+        struct llog_ctxt *ctxt;
+        __u32 flags;
+        __u8 *buf;
+        void * ptr;
+        int size[] = {sizeof (*body),
+                      LLOG_CHUNK_SIZE};
+        int rc, rc2;
+        ENTRY;
+
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body),
+                                  lustre_swab_llogd_body);
+        if (body == NULL) {
+                CERROR ("Can't unpack llogd_body\n");
+                GOTO(out, rc =-EFAULT);
+        }
+
+        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
+        if (!buf)
+                GOTO(out, rc = -ENOMEM);
+
+        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
+        LASSERT(ctxt != NULL);
+        disk_obd = ctxt->loc_exp->exp_obd;
+        push_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+
+        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
+        if (rc)
+                GOTO(out_pop, rc);
+
+        flags = body->lgd_llh_flags;
+        rc = llog_init_handle(loghandle, flags, NULL);
+        if (rc)
+                GOTO(out_close, rc);
+
+        memset(buf, 0, LLOG_CHUNK_SIZE);
+        rc = llog_next_block(loghandle, &body->lgd_saved_index,
+                             body->lgd_index,
+                             &body->lgd_cur_offset, buf, LLOG_CHUNK_SIZE);
+        if (rc)
+                GOTO(out_close, rc);
+
+
+        rc = lustre_pack_reply(req, 2, size, NULL);
+        if (rc)
+                GOTO(out_close, rc = -ENOMEM);
+
+        ptr = lustre_msg_buf(req->rq_repmsg, 0, sizeof (body));
+        memcpy(ptr, body, sizeof(*body));
+
+        ptr = lustre_msg_buf(req->rq_repmsg, 1, LLOG_CHUNK_SIZE);
+        memcpy(ptr, buf, LLOG_CHUNK_SIZE);
+
+out_close:
+        rc2 = llog_close(loghandle);
+        if (!rc)
+                rc = rc2;
+
+out_pop:
+        pop_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        OBD_FREE(buf, LLOG_CHUNK_SIZE);
+out:
+        RETURN(rc);
+}
+
+int llog_origin_handle_read_header(struct ptlrpc_request *req)
+{
+        struct obd_export *exp = req->rq_export;
+        struct obd_device *obd = exp->exp_obd;
+        struct obd_device *disk_obd;
+        struct llog_handle  *loghandle;
+        struct llogd_body *body;
+        struct llog_log_hdr *hdr;
+        struct obd_run_ctxt saved;
+        struct llog_ctxt *ctxt;
+        __u32 flags;
+        __u8 *buf;
+        int size[] = {sizeof (*hdr)};
+        int rc, rc2;
+        ENTRY;
+
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body),
+                                  lustre_swab_llogd_body);
+        if (body == NULL) {
+                CERROR ("Can't unpack llogd_body\n");
+                GOTO(out, rc =-EFAULT);
+        }
+
+        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
+        if (!buf)
+                GOTO(out, rc = -ENOMEM);
+
+        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
+        LASSERT(ctxt != NULL);
+        disk_obd = ctxt->loc_exp->exp_obd;
+        push_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+
+        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
+        if (rc)
+                GOTO(out_pop, rc);
+
+        /* init_handle reads the header */
+        flags = body->lgd_llh_flags;
+        rc = llog_init_handle(loghandle, flags, NULL);
+        if (rc)
+                GOTO(out_close, rc);
+
+
+        rc = lustre_pack_reply(req, 1, size, NULL);
+        if (rc)
+                GOTO(out_close, rc = -ENOMEM);
+
+        hdr = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*hdr));
+        memcpy(hdr, loghandle->lgh_hdr, sizeof(*hdr));
+
+out_close:
+        rc2 = llog_close(loghandle);
+        if (!rc)
+                rc = rc2;
+
+out_pop:
+        pop_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        OBD_FREE(buf, LLOG_CHUNK_SIZE);
+
+out:
+        RETURN(rc);
+}
+
+int llog_origin_handle_close(struct ptlrpc_request *req)
+{
+        int rc;
+
+        rc = 0;
+
+        RETURN(rc);
+}
+
+#ifdef ENABLE_ORPHANS
+int llog_origin_handle_cancel(struct ptlrpc_request *req)
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct obd_device *disk_obd;
+        struct llog_cookie *logcookies;
+        struct llog_ctxt *ctxt;
+        int num_cookies, rc = 0;
+        struct obd_run_ctxt saved;
+        struct llog_handle *cathandle;
+        ENTRY;
+
+        logcookies = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*logcookies));
+        num_cookies = req->rq_reqmsg->buflens[0]/sizeof(*logcookies);
+        if (logcookies == NULL || num_cookies == 0) {
+                DEBUG_REQ(D_HA, req, "no cookies sent");
+                RETURN(-EFAULT);
+        }
+
+        ctxt = llog_get_context(obd, logcookies->lgc_subsys);
+        if (ctxt == NULL) {
+                CWARN("llog subsys not setup or already cleanup\n");
+                RETURN(-ENOENT);
+        }
+        down(&ctxt->loc_sem);
+        disk_obd = ctxt->loc_exp->exp_obd;
+        cathandle = ctxt->loc_handle;
+        LASSERT(cathandle);
+
+        push_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        rc = llog_cat_cancel_records(cathandle, num_cookies, logcookies);
+        if (rc)
+                CERROR("cancel %d llog-records failed: %d\n", num_cookies, rc);
+        else
+                CWARN("cancel %d llog-records\n", num_cookies);
+
+        pop_ctxt(&saved, &disk_obd->obd_ctxt, NULL);
+        up(&ctxt->loc_sem);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_origin_handle_cancel);
+#endif
diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c
index c4c47d3d0a9019928eaa66afbb557958c77b8d3d..43e650eb665f2f6f6bddaccbe93010b89fac6fe6 100644
--- a/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/lustre/ptlrpc/lproc_ptlrpc.c
@@ -49,7 +49,7 @@ struct ll_rpc_opcode {
         { OST_STATFS,       "ost_statfs" },
         { OST_SAN_READ,     "ost_san_read" },
         { OST_SAN_WRITE,    "ost_san_write" },
-        { OST_SYNCFS,       "ost_syncfs" },
+        { OST_SYNC,         "ost_sync" },
         { OST_SET_INFO,     "ost_set_info" },
         { MDS_GETATTR,      "mds_getattr" },
         { MDS_GETATTR_NAME, "mds_getattr_name" },
@@ -60,9 +60,10 @@ struct ll_rpc_opcode {
         { MDS_DISCONNECT,   "mds_disconnect" },
         { MDS_GETSTATUS,    "mds_getstatus" },
         { MDS_STATFS,       "mds_statfs" },
-        { MDS_GETLOVINFO,   "mds_getlovinfo" },
         { MDS_PIN,          "mds_pin" },
         { MDS_UNPIN,        "mds_unpin" },
+        { MDS_SYNC,         "mds_sync" },
+        { MDS_DONE_WRITING, "mds_done_writing" },
         { LDLM_ENQUEUE,     "ldlm_enqueue" },
         { LDLM_CONVERT,     "ldlm_convert" },
         { LDLM_CANCEL,      "ldlm_cancel" },
@@ -75,7 +76,7 @@ struct ll_rpc_opcode {
         { PTLBD_CONNECT,    "ptlbd_connect" },
         { PTLBD_DISCONNECT, "ptlbd_disconnect" },
         { OBD_PING,         "obd_ping" },
-        { OBD_LOG_CANCEL,   "obd_log_cancel" },
+        { OBD_LOG_CANCEL,   "llog_origin_handle_cancel"},
 };
 
 const char* ll_opcode2str(__u32 opcode)
@@ -99,8 +100,9 @@ void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
 void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc) { return; }
 #else
 
-void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
-                                     struct ptlrpc_service *svc)
+void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
+                             char *name, struct proc_dir_entry **procroot_ret,
+                             struct lprocfs_stats **stats_ret)
 {
         struct proc_dir_entry *svc_procroot;
         struct lprocfs_stats *svc_stats;
@@ -108,19 +110,21 @@ void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
         unsigned int svc_counter_config = LPROCFS_CNTR_EXTERNALLOCK |
                 LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV;
 
-        LASSERT(svc->svc_procroot == NULL);
-        LASSERT(svc->svc_stats == NULL);
-
-        svc_procroot = lprocfs_register(svc->srv_name, obddev->obd_proc_entry,
-                                        NULL, NULL);
-        if (svc_procroot == NULL)
-                return;
+        LASSERT(*procroot_ret == NULL);
+        LASSERT(*stats_ret == NULL);
 
         svc_stats = lprocfs_alloc_stats(PTLRPC_LAST_CNTR + LUSTRE_MAX_OPCODES);
-        if (svc_stats == NULL) {
-                lprocfs_remove(svc_procroot);
+        if (svc_stats == NULL)
                 return;
-        }
+
+        if (dir) {
+                svc_procroot = lprocfs_register(dir, root, NULL, NULL);
+                if (IS_ERR(svc_procroot)) {
+                        lprocfs_free_stats(svc_stats);
+                        return;
+                }
+        } else 
+                svc_procroot = root;
 
         lprocfs_counter_init(svc_stats, PTLRPC_REQWAIT_CNTR,
                              svc_counter_config, "req_waittime", "usec");
@@ -139,16 +143,45 @@ void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
                                      "usec");
         }
 
-        rc = lprocfs_register_stats(svc_procroot, "stats", svc_stats);
+        rc = lprocfs_register_stats(svc_procroot, name, svc_stats);
         if (rc < 0) {
-                lprocfs_remove(svc_procroot);
+                if (dir)
+                        lprocfs_remove(svc_procroot);
                 lprocfs_free_stats(svc_stats);
         } else {
-                svc->svc_procroot = svc_procroot;
-                svc->svc_stats = svc_stats;
+                if (dir)
+                        *procroot_ret = svc_procroot;
+                *stats_ret = svc_stats;
         }
 }
 
+void ptlrpc_lprocfs_register_service(struct proc_dir_entry *entry,
+                                     struct ptlrpc_service *svc)
+{
+        ptlrpc_lprocfs_register(entry, svc->srv_name,
+                                "stats", &svc->svc_procroot, 
+                                &svc->svc_stats);
+}
+
+void ptlrpc_lprocfs_register_obd(struct obd_device *obddev)
+{
+        ptlrpc_lprocfs_register(obddev->obd_proc_entry, NULL, "stats", 
+                                &obddev->obd_svc_procroot, 
+                                &obddev->obd_svc_stats);
+}
+
+void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req)
+{
+        struct lprocfs_stats *svc_stats;
+        int opc =  opcode_offset(req->rq_reqmsg->opc);
+
+        svc_stats = req->rq_import->imp_obd->obd_svc_stats;
+        if (svc_stats == NULL || opc <= 0)
+                return;
+        LASSERT(opc < LUSTRE_MAX_OPCODES);
+        lprocfs_counter_add(svc_stats, opc + PTLRPC_LAST_CNTR, 0);
+}
+
 void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc)
 {
         if (svc->svc_procroot) {
@@ -160,4 +193,15 @@ void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc)
                 svc->svc_stats = NULL;
         }
 }
+void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd)
+{
+        if (obd->obd_svc_procroot) {
+                lprocfs_remove(obd->obd_svc_procroot);
+                obd->obd_svc_procroot = NULL;
+        }
+        if (obd->obd_svc_stats) {
+                lprocfs_free_stats(obd->obd_svc_stats);
+                obd->obd_svc_stats = NULL;
+        }
+}
 #endif /* LPROCFS */
diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c
index c0ccb4dacfa54aaa0c635549a8316c09c3403e6d..fe8a4cd3b5c7b851382eef9cf2fce5e6e78f04d7 100644
--- a/lustre/ptlrpc/niobuf.c
+++ b/lustre/ptlrpc/niobuf.c
@@ -39,12 +39,16 @@ static int ptl_send_buf(struct ptlrpc_request *request,
         ptl_process_id_t remote_id;
         ptl_handle_md_t md_h;
         ptl_ack_req_t ack_req;
+        char str[PTL_NALFMT_SIZE];
 
         LASSERT (portal != 0);
         LASSERT (conn != NULL);
-        CDEBUG (D_INFO, "conn=%p ni %s nid "LPX64" on %s\n",
+        CDEBUG (D_INFO, "conn=%p ni %s nid "LPX64" (%s) on %s\n",
                 conn, conn->c_peer.peer_ni->pni_name,
-                conn->c_peer.peer_nid, conn->c_peer.peer_ni->pni_name);
+                conn->c_peer.peer_nid,
+                portals_nid2str(conn->c_peer.peer_ni->pni_number,
+                                conn->c_peer.peer_nid, str),
+                conn->c_peer.peer_ni->pni_name);
 
         request->rq_req_md.user_ptr = request;
 
@@ -391,7 +395,7 @@ int ptlrpc_register_bulk (struct ptlrpc_request *req)
 
         /* NB no locking required until desc is on the network */
         LASSERT (!desc->bd_network_rw);
-        LASSERT (desc->bd_page_count <= PTL_MD_MAX_IOV);
+        LASSERT (desc->bd_page_count <= PTL_MD_MAX_PAGES);
         LASSERT (desc->bd_req != NULL);
         LASSERT (desc->bd_type == BULK_PUT_SINK ||
                  desc->bd_type == BULK_GET_SOURCE);
@@ -580,8 +584,7 @@ int ptlrpc_error(struct ptlrpc_request *req)
         ENTRY;
 
         if (!req->rq_repmsg) {
-                rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen,
-                                     &req->rq_repmsg);
+                rc = lustre_pack_reply(req, 0, NULL, NULL);
                 if (rc)
                         RETURN(rc);
         }
@@ -615,12 +618,14 @@ int ptl_send_rpc(struct ptlrpc_request *request)
         }
 
         request->rq_reqmsg->handle = request->rq_import->imp_remote_handle;
+        request->rq_reqmsg->conn_cnt = request->rq_import->imp_conn_cnt;
 
         source_id.nid = request->rq_connection->c_peer.peer_nid;
         source_id.pid = PTL_PID_ANY;
 
         LASSERT (request->rq_replen != 0);
-        OBD_ALLOC(request->rq_repmsg, request->rq_replen);
+        if (request->rq_repmsg == NULL)
+                OBD_ALLOC(request->rq_repmsg, request->rq_replen);
         if (request->rq_repmsg == NULL) {
                 LBUG();
                 RETURN(-ENOMEM);
@@ -676,8 +681,10 @@ int ptl_send_rpc(struct ptlrpc_request *request)
         ptlrpc_pinger_sending_on_import(request->rq_import);
         rc = ptl_send_buf(request, request->rq_connection,
                           request->rq_request_portal);
-        if (rc == 0)
+        if (rc == 0) {
+                ptlrpc_lprocfs_rpc_sent(request);
                 RETURN(rc);
+        }
 
         spin_lock_irqsave (&request->rq_lock, flags);
         request->rq_receiving_reply = 0;
diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c
index 0e2d65123d8bd74e89eea6315ff472783cab3b8b..7a5c3a2a441ac07a82189daf6f2478c93b71292c 100644
--- a/lustre/ptlrpc/pack_generic.c
+++ b/lustre/ptlrpc/pack_generic.c
@@ -37,8 +37,13 @@
 #define HDR_SIZE(count) \
     size_round(offsetof (struct lustre_msg, buflens[(count)]))
 
-int lustre_pack_msg(int count, int *lens, char **bufs, int *len,
-                    struct lustre_msg **msg)
+int lustre_msg_swabbed(struct lustre_msg *msg)
+{
+        return (msg->magic == __swab32(PTLRPC_MSG_MAGIC));
+}
+
+static int lustre_pack_msg(int count, int *lens, char **bufs, int *len,
+                           struct lustre_msg **msg)
 {
         char *ptr;
         struct lustre_msg *m;
@@ -73,6 +78,20 @@ int lustre_pack_msg(int count, int *lens, char **bufs, int *len,
         return 0;
 }
 
+int lustre_pack_request(struct ptlrpc_request *req, int count, int *lens,
+                        char **bufs)
+{
+        return lustre_pack_msg(count, lens, bufs, &req->rq_reqlen,
+                               &req->rq_reqmsg);
+}
+
+int lustre_pack_reply(struct ptlrpc_request *req, int count, int *lens,
+                      char **bufs)
+{
+        return lustre_pack_msg(count, lens, bufs, &req->rq_replen,
+                               &req->rq_repmsg);
+}
+
 /* This returns the size of the buffer that is required to hold a lustre_msg
  * with the given sub-buffer lengths. */
 int lustre_msg_size(int count, int *lengths)
@@ -334,6 +353,11 @@ void lustre_swab_ost_body (struct ost_body *b)
         lustre_swab_obdo (&b->oa);
 }
 
+void lustre_swab_ost_last_id(obd_id *id)
+{
+        __swab64s(id);
+}
+
 void lustre_swab_ll_fid (struct ll_fid *fid)
 {
         __swab64s (&fid->id);
@@ -347,11 +371,6 @@ void lustre_swab_mds_status_req (struct mds_status_req *r)
         __swab32s (&r->repbuf);
 }
 
-void lustre_swab_mds_fileh_body (struct mds_fileh_body *f)
-{
-        lustre_swab_ll_fid (&f->f_fid);
-}
-
 void lustre_swab_mds_body (struct mds_body *b)
 {
         lustre_swab_ll_fid (&b->fid1);
@@ -384,7 +403,7 @@ void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa)
         __swab32s (&sa->sa_fsuid);
         __swab32s (&sa->sa_fsgid);
         __swab32s (&sa->sa_cap);
-        __swab32s (&sa->sa_reserved);
+        __swab32s (&sa->sa_suppgid);
         __swab32s (&sa->sa_valid);
         lustre_swab_ll_fid (&sa->sa_fid);
         __swab32s (&sa->sa_mode);
@@ -395,7 +414,6 @@ void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa)
         __swab64s (&sa->sa_atime);
         __swab64s (&sa->sa_mtime);
         __swab64s (&sa->sa_ctime);
-        __swab32s (&sa->sa_suppgid);
 }
 
 void lustre_swab_mds_rec_create (struct mds_rec_create *cr)
@@ -408,8 +426,6 @@ void lustre_swab_mds_rec_create (struct mds_rec_create *cr)
         __swab32s (&cr->cr_mode);
         lustre_swab_ll_fid (&cr->cr_fid);
         lustre_swab_ll_fid (&cr->cr_replayfid);
-        __swab32s (&cr->cr_uid);
-        __swab32s (&cr->cr_gid);
         __swab64s (&cr->cr_time);
         __swab64s (&cr->cr_rdev);
         __swab32s (&cr->cr_suppgid);
@@ -433,9 +449,8 @@ void lustre_swab_mds_rec_unlink (struct mds_rec_unlink *ul)
         __swab32s (&ul->ul_fsuid);
         __swab32s (&ul->ul_fsgid);
         __swab32s (&ul->ul_cap);
-        __swab32s (&ul->ul_reserved);
-        __swab32s (&ul->ul_mode);
         __swab32s (&ul->ul_suppgid);
+        __swab32s (&ul->ul_mode);
         lustre_swab_ll_fid (&ul->ul_fid1);
         lustre_swab_ll_fid (&ul->ul_fid2);
 }
@@ -471,10 +486,14 @@ void lustre_swab_ldlm_res_id (struct ldlm_res_id *id)
                 __swab64s (&id->name[i]);
 }
 
-void lustre_swab_ldlm_extent (struct ldlm_extent *e)
+void lustre_swab_ldlm_policy_data (ldlm_policy_data_t *d)
 {
-        __swab64s (&e->start);
-        __swab64s (&e->end);
+        /* the lock data is a union and the first two fields are always an
+         * extent so it's ok to process an LDLM_EXTENT and LDLM_FLOCK lock
+         * data the same way. */
+        __swab64s (&d->l_flock.start);
+        __swab64s (&d->l_flock.end);
+        __swab32s (&d->l_flock.pid);
 }
 
 void lustre_swab_ldlm_intent (struct ldlm_intent *i)
@@ -499,7 +518,7 @@ void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l)
         lustre_swab_ldlm_resource_desc (&l->l_resource);
         __swab32s (&l->l_req_mode);
         __swab32s (&l->l_granted_mode);
-        lustre_swab_ldlm_extent (&l->l_extent);
+        lustre_swab_ldlm_policy_data (&l->l_policy_data);
         for (i = 0; i < RES_VERSION_SIZE; i++)
                 __swab32s (&l->l_version[i]);
 }
@@ -518,7 +537,7 @@ void lustre_swab_ldlm_reply (struct ldlm_reply *r)
         __swab32s (&r->lock_mode);
         lustre_swab_ldlm_res_id (&r->lock_resource_name);
         /* lock_handle opaque */
-        lustre_swab_ldlm_extent (&r->lock_extent);
+        lustre_swab_ldlm_policy_data (&r->lock_policy_data);
         __swab64s (&r->lock_policy_res1);
         __swab64s (&r->lock_policy_res2);
 }
@@ -546,6 +565,52 @@ void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r)
         __swab16s (&r->r_error_cnt);
 }
 
+/* no one calls this */
+int llog_log_swabbed(struct llog_log_hdr *hdr)
+{
+        if (hdr->llh_hdr.lrh_type == __swab32(LLOG_HDR_MAGIC))
+                return 1;
+        if (hdr->llh_hdr.lrh_type == LLOG_HDR_MAGIC)
+                return 0;
+        return -1;
+}
+
+void lustre_swab_llogd_body (struct llogd_body *d)
+{
+        __swab64s (&d->lgd_logid.lgl_oid);
+        __swab64s (&d->lgd_logid.lgl_ogr);
+        __swab32s (&d->lgd_logid.lgl_ogen);
+        __swab32s (&d->lgd_ctxt_idx);
+        __swab32s (&d->lgd_llh_flags);
+        __swab32s (&d->lgd_index);
+        __swab32s (&d->lgd_saved_index);
+        __swab32s (&d->lgd_len);
+        __swab64s (&d->lgd_cur_offset);
+}
+
+void lustre_swab_llog_hdr (struct llog_log_hdr *h)
+{
+        __swab32s (&h->llh_hdr.lrh_index);
+        __swab32s (&h->llh_hdr.lrh_len);
+        __swab32s (&h->llh_hdr.lrh_type);
+        __swab64s (&h->llh_timestamp);
+        __swab32s (&h->llh_count);
+        __swab32s (&h->llh_bitmap_offset);
+        __swab32s (&h->llh_flags);
+        __swab32s (&h->llh_tail.lrt_index);
+        __swab32s (&h->llh_tail.lrt_len);
+}
+
+void lustre_swab_llogd_conn_body (struct llogd_conn_body *d)
+{
+        __swab64s (&d->lgdc_gen.mnt_cnt);
+        __swab64s (&d->lgdc_gen.conn_cnt);
+        __swab64s (&d->lgdc_logid.lgl_oid);
+        __swab64s (&d->lgdc_logid.lgl_ogr);
+        __swab32s (&d->lgdc_logid.lgl_ogen);
+        __swab32s (&d->lgdc_ctxt_idx);
+}
+
 void lustre_assert_wire_constants (void)
 {
 #if BUG_1343
@@ -578,7 +643,7 @@ void lustre_assert_wire_constants (void)
         LASSERT (OST_STATFS == 13);
         LASSERT (OST_SAN_READ == 14);
         LASSERT (OST_SAN_WRITE == 15);
-        LASSERT (OST_SYNCFS == 16);
+        LASSERT (OST_SYNC == 16);
         LASSERT (OST_LAST_OPC == 17);
         LASSERT (OST_FIRST_OPC == 0);
         LASSERT (OBD_FL_INLINEDATA == 1);
@@ -639,7 +704,7 @@ void lustre_assert_wire_constants (void)
         LASSERT (DISP_OPEN_OPEN == 32);
         LASSERT (MDS_STATUS_CONN == 1);
         LASSERT (MDS_STATUS_LOV == 2);
-        LASSERT (MDS_OPEN_HAS_EA == 1);
+        LASSERT (MDS_OPEN_HAS_EA == (1 << 30));
         LASSERT (LOV_RAID0 == 0);
         LASSERT (LOV_RAIDRR == 1);
         LASSERT (LDLM_ENQUEUE == 101);
@@ -794,11 +859,6 @@ void lustre_assert_wire_constants (void)
         LASSERT (offsetof (struct mds_status_req, repbuf) == 4);
         LASSERT (sizeof (((struct mds_status_req *)0)->repbuf) == 4);
 
-        /* Checks for struct mds_fileh_body */
-        LASSERT (sizeof (struct mds_fileh_body) == 24);
-        LASSERT (offsetof (struct mds_fileh_body, f_fid) == 0);
-        LASSERT (sizeof (((struct mds_fileh_body *)0)->f_fid) == 16);
-
         /* Checks for struct mds_body */
         LASSERT (sizeof (struct mds_body) == 124);
         LASSERT (offsetof (struct mds_body, fid1) == 0);
@@ -989,12 +1049,14 @@ void lustre_assert_wire_constants (void)
         LASSERT (offsetof (struct ldlm_res_id, name[3]) == 24);
         LASSERT (sizeof (((struct ldlm_res_id *)0)->name[3]) == 8);
 
-        /* Checks for struct ldlm_extent */
-        LASSERT (sizeof (struct ldlm_extent) == 16);
-        LASSERT (offsetof (struct ldlm_extent, start) == 0);
-        LASSERT (sizeof (((struct ldlm_extent *)0)->start) == 8);
-        LASSERT (offsetof (struct ldlm_extent, end) == 8);
-        LASSERT (sizeof (((struct ldlm_extent *)0)->end) == 8);
+        /* Checks for struct ldlm_data */
+        LASSERT (sizeof (struct ldlm_data) == 16);
+        LASSERT (offsetof (struct ldlm_data, l_extent.start) == 0);
+        LASSERT (sizeof (((struct ldlm_data *)0)->l_extent.start) == 8);
+        LASSERT (offsetof (struct ldlm_data, l_extent.end) == 8);
+        LASSERT (sizeof (((struct ldlm_data *)0)->l_extent.end) == 8);
+        LASSERT (sizeof (((struct ldlm_data *)0)->l_flock.pid) == 4);
+        LASSERT (offsetof (struct ldlm_data, l_flock.pid) == 16);
 
         /* Checks for struct ldlm_intent */
         LASSERT (sizeof (struct ldlm_intent) == 8);
diff --git a/lustre/ptlrpc/pinger.c b/lustre/ptlrpc/pinger.c
index c81fb516d89b4368918dded4abea4a088b5ea6ad..3caf74e448bb1d6994ad1aa6c04c0256dc74cd0b 100644
--- a/lustre/ptlrpc/pinger.c
+++ b/lustre/ptlrpc/pinger.c
@@ -23,86 +23,24 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#ifndef __KERNEL__
+#include <liblustre.h>
+#else
 #include <linux/version.h>
 #include <asm/semaphore.h>
-
 #define DEBUG_SUBSYSTEM S_RPC
+#endif
+
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
 #include "ptlrpc_internal.h"
 
+#ifdef __KERNEL__
+
 static struct ptlrpc_thread *pinger_thread = NULL;
 static DECLARE_MUTEX(pinger_sem);
 static struct list_head pinger_imports = LIST_HEAD_INIT(pinger_imports);
 
-int ptlrpc_start_pinger(void);
-int ptlrpc_stop_pinger(void);
-
-void ptlrpc_pinger_sending_on_import(struct obd_import *imp)
-{
-        down(&pinger_sem);
-        imp->imp_next_ping = jiffies + (obd_timeout * HZ);
-        up(&pinger_sem);
-}
-
-int ptlrpc_pinger_add_import(struct obd_import *imp)
-{
-#ifndef ENABLE_PINGER
-        return 0;
-#else
-        int rc;
-        ENTRY;
-
-        if (!list_empty(&imp->imp_pinger_chain))
-                RETURN(-EALREADY);
-
-        down(&pinger_sem);
-        if (list_empty(&pinger_imports)) {
-                up(&pinger_sem);
-                rc = ptlrpc_start_pinger();
-                if (rc < 0)
-                        RETURN(rc);
-                down(&pinger_sem);
-        }
-                
-        CDEBUG(D_HA, "adding pingable import %s->%s\n",
-               imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid);
-        imp->imp_next_ping = jiffies + (obd_timeout * HZ);
-        list_add_tail(&imp->imp_pinger_chain, &pinger_imports); /* XXX sort, blah blah */
-        class_import_get(imp);
-        up(&pinger_sem);
-        RETURN(0);
-#endif
-}
-
-int ptlrpc_pinger_del_import(struct obd_import *imp)
-{
-#ifndef ENABLE_PINGER
-        return 0;
-#else
-        int rc;
-        ENTRY;
-
-        if (list_empty(&imp->imp_pinger_chain))
-                RETURN(-ENOENT);
-
-        down(&pinger_sem);
-        list_del_init(&imp->imp_pinger_chain);
-        CDEBUG(D_HA, "removing pingable import %s->%s\n",
-               imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid);
-        class_import_put(imp);
-        if (list_empty(&pinger_imports)) {
-                up(&pinger_sem);
-                rc = ptlrpc_stop_pinger();
-                if (rc)
-                        RETURN(rc);
-                down(&pinger_sem);
-        }
-        up(&pinger_sem);
-        RETURN(0);
-#endif
-}
-
 static int ptlrpc_pinger_main(void *arg)
 {
         struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg;
@@ -129,7 +67,8 @@ static int ptlrpc_pinger_main(void *arg)
         while (1) {
                 unsigned long this_ping = jiffies;
                 long time_to_next_ping;
-                struct l_wait_info lwi = LWI_TIMEOUT(10 * HZ, NULL, NULL);
+                struct l_wait_info lwi = LWI_TIMEOUT(obd_timeout * HZ,
+                                                     NULL, NULL);
                 struct ptlrpc_request_set *set;
                 struct ptlrpc_request *req;
                 struct list_head *iter;
@@ -149,10 +88,10 @@ static int ptlrpc_pinger_main(void *arg)
                                 /* Add a ping. */
                                 spin_lock_irqsave(&imp->imp_lock, flags);
                                 generation = imp->imp_generation;
-                                level = imp->imp_level;
+                                level = imp->imp_state;
                                 spin_unlock_irqrestore(&imp->imp_lock, flags);
 
-                                if (level != LUSTRE_CONN_FULL) {
+                                if (level != LUSTRE_IMP_FULL) {
                                         CDEBUG(D_HA,
                                                "not pinging %s (in recovery)\n",
                                                imp->imp_target_uuid.uuid);
@@ -167,14 +106,14 @@ static int ptlrpc_pinger_main(void *arg)
                                 }
                                 req->rq_no_resend = 1;
                                 req->rq_replen = lustre_msg_size(0, NULL);
-                                req->rq_level = LUSTRE_CONN_FULL;
+                                req->rq_send_state = LUSTRE_IMP_FULL;
                                 req->rq_phase = RQ_PHASE_RPC;
                                 req->rq_import_generation = generation;
                                 ptlrpc_set_add_req(set, req);
                         } else {
-                                CDEBUG(D_HA, "don't need to ping %s (%lu > %lu)\n",
-                                       imp->imp_target_uuid.uuid, imp->imp_next_ping,
-                                       this_ping);
+                                CDEBUG(D_HA, "don't need to ping %s (%lu > "
+                                       "%lu)\n", imp->imp_target_uuid.uuid,
+                                       imp->imp_next_ping, this_ping);
                         }
                 }
                 up(&pinger_sem);
@@ -184,7 +123,8 @@ static int ptlrpc_pinger_main(void *arg)
                         CDEBUG(D_HA, "nothing to ping\n");
                 list_for_each(iter, &set->set_requests) {
                         struct ptlrpc_request *req =
-                                list_entry(iter, struct ptlrpc_request, rq_set_chain);
+                                list_entry(iter, struct ptlrpc_request,
+                                           rq_set_chain);
                         DEBUG_REQ(D_HA, req, "pinging %s->%s",
                                   req->rq_import->imp_obd->obd_uuid.uuid,
                                   req->rq_import->imp_target_uuid.uuid);
@@ -195,7 +135,8 @@ static int ptlrpc_pinger_main(void *arg)
                 init_waitqueue_entry(&set_wait, current);
                 add_wait_queue(&set->set_waitq, &set_wait);
                 rc = l_wait_event(thread->t_ctl_waitq,
-                                  thread->t_flags & SVC_STOPPING || ptlrpc_check_set(set),
+                                  thread->t_flags & SVC_STOPPING ||
+                                  ptlrpc_check_set(set),
                                   &lwi);
                 remove_wait_queue(&set->set_waitq, &set_wait);
                 CDEBUG(D_HA, "ping complete (%lu)\n", jiffies);
@@ -216,7 +157,8 @@ static int ptlrpc_pinger_main(void *arg)
                 /* Expire all the requests that didn't come back. */
                 down(&pinger_sem);
                 list_for_each(iter, &set->set_requests) {
-                        req = list_entry(iter, struct ptlrpc_request, rq_set_chain);
+                        req = list_entry(iter, struct ptlrpc_request,
+                                         rq_set_chain);
 
                         if (req->rq_replied)
                                 continue;
@@ -224,8 +166,10 @@ static int ptlrpc_pinger_main(void *arg)
                         req->rq_phase = RQ_PHASE_COMPLETE;
                         set->set_remaining--;
                         /* If it was disconnected, don't sweat it. */
-                        if (list_empty(&req->rq_import->imp_pinger_chain))
+                        if (list_empty(&req->rq_import->imp_pinger_chain)) {
+                                ptlrpc_unregister_reply(req);
                                 continue;
+                        }
 
                         ptlrpc_expire_one_request(req);
                 }
@@ -238,12 +182,16 @@ static int ptlrpc_pinger_main(void *arg)
                        this_ping + (obd_timeout * HZ));
                 if (time_to_next_ping > 0) {
                         lwi = LWI_TIMEOUT(time_to_next_ping, NULL, NULL);
-                        l_wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPING,
+                        l_wait_event(thread->t_ctl_waitq,
+                                     thread->t_flags & (SVC_STOPPING|SVC_EVENT),
                                      &lwi);
                         if (thread->t_flags & SVC_STOPPING) {
                                 thread->t_flags &= ~SVC_STOPPING;
                                 EXIT;
                                 break;
+                        } else if (thread->t_flags & SVC_EVENT) {
+                                /* woken after adding import to reset timer */
+                                thread->t_flags &= ~SVC_EVENT;
                         }
                 }
         }
@@ -260,15 +208,17 @@ int ptlrpc_start_pinger(void)
         struct l_wait_info lwi = { 0 };
         struct ptlrpc_svc_data d;
         int rc;
+#ifndef ENABLE_PINGER
+        return 0;
+#endif
         ENTRY;
 
-        down(&pinger_sem);
         if (pinger_thread != NULL)
-                GOTO(out, rc = -EALREADY);
+                RETURN(-EALREADY);
 
         OBD_ALLOC(pinger_thread, sizeof(*pinger_thread));
         if (pinger_thread == NULL)
-                GOTO(out, rc = -ENOMEM);
+                RETURN(-ENOMEM);
         init_waitqueue_head(&pinger_thread->t_ctl_waitq);
 
         d.name = "ll_ping";
@@ -280,13 +230,11 @@ int ptlrpc_start_pinger(void)
         if (rc < 0) {
                 CERROR("cannot start thread: %d\n", rc);
                 OBD_FREE(pinger_thread, sizeof(*pinger_thread));
-                GOTO(out, rc);
+                RETURN(rc);
         }
         l_wait_event(pinger_thread->t_ctl_waitq,
                      pinger_thread->t_flags & SVC_RUNNING, &lwi);
 
- out:
-        up(&pinger_sem);
         RETURN(rc);
 }
 
@@ -294,20 +242,95 @@ int ptlrpc_stop_pinger(void)
 {
         struct l_wait_info lwi = { 0 };
         int rc = 0;
+#ifndef ENABLE_PINGER
+        return 0;
+#endif
         ENTRY;
 
-        down(&pinger_sem);
         if (pinger_thread == NULL)
-                GOTO(out, rc = -EALREADY);
-
+                RETURN(-EALREADY);
+        down(&pinger_sem);
         pinger_thread->t_flags = SVC_STOPPING;
         wake_up(&pinger_thread->t_ctl_waitq);
+        up(&pinger_sem);
+
         l_wait_event(pinger_thread->t_ctl_waitq,
                      (pinger_thread->t_flags & SVC_STOPPED), &lwi);
 
         OBD_FREE(pinger_thread, sizeof(*pinger_thread));
+        pinger_thread = NULL;
+        RETURN(rc);
+}
 
- out:
+void ptlrpc_pinger_sending_on_import(struct obd_import *imp)
+{
+        down(&pinger_sem);
+        imp->imp_next_ping = jiffies + (obd_timeout * HZ);
         up(&pinger_sem);
-        RETURN(rc);
 }
+
+int ptlrpc_pinger_add_import(struct obd_import *imp)
+{
+        ENTRY;
+        if (!list_empty(&imp->imp_pinger_chain))
+                RETURN(-EALREADY);
+
+        down(&pinger_sem);
+        CDEBUG(D_HA, "adding pingable import %s->%s\n",
+               imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid);
+        imp->imp_next_ping = jiffies + (obd_timeout * HZ);
+        /* XXX sort, blah blah */
+        list_add_tail(&imp->imp_pinger_chain, &pinger_imports);
+        class_import_get(imp);
+
+#ifdef ENABLE_PINGER
+        pinger_thread->t_flags |= SVC_EVENT;
+        wake_up(&pinger_thread->t_ctl_waitq);
+#endif
+        up(&pinger_sem);
+
+        RETURN(0);
+}
+
+int ptlrpc_pinger_del_import(struct obd_import *imp)
+{
+        ENTRY;
+        if (list_empty(&imp->imp_pinger_chain))
+                RETURN(-ENOENT);
+
+        down(&pinger_sem);
+        list_del_init(&imp->imp_pinger_chain);
+        CDEBUG(D_HA, "removing pingable import %s->%s\n",
+               imp->imp_obd->obd_uuid.uuid, imp->imp_target_uuid.uuid);
+        class_import_put(imp);
+        up(&pinger_sem);
+        RETURN(0);
+}
+
+#else /* !__KERNEL__ */
+
+int ptlrpc_start_pinger(void)
+{
+        return 0;
+}
+
+int ptlrpc_stop_pinger(void)
+{
+        return 0;
+}
+
+int ptlrpc_pinger_add_import(struct obd_import *imp)
+{
+        return 0;
+}
+
+int ptlrpc_pinger_del_import(struct obd_import *imp)
+{
+        return 0;
+}
+
+void ptlrpc_pinger_sending_on_import(struct obd_import *imp)
+{
+}
+
+#endif
diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h
index a84a29c85b4ae3e284c6de96b7a5e6ea05dcce90..7ec654c01bc7644bbfdcacf133ac210eca980a4c 100644
--- a/lustre/ptlrpc/ptlrpc_internal.h
+++ b/lustre/ptlrpc/ptlrpc_internal.h
@@ -25,26 +25,31 @@
 #ifndef PTLRPC_INTERNAL_H
 #define PTLRPC_INTERNAL_H
 
+#include "../ldlm/ldlm_internal.h"
+
 struct ldlm_namespace;
 struct obd_import;
 struct ldlm_res_id;
 struct ptlrpc_request_set;
 
-/* ldlm hooks that we need, managed via inter_module_{get,put} */
-extern int (*ptlrpc_ldlm_namespace_cleanup)(struct ldlm_namespace *, int);
-extern int (*ptlrpc_ldlm_cli_cancel_unused)(struct ldlm_namespace *,
-                                            struct ldlm_res_id *, int);
-extern int (*ptlrpc_ldlm_replay_locks)(struct obd_import *);
-
-int ptlrpc_get_ldlm_hooks(void);
 void ptlrpc_daemonize(void);
 
 void ptlrpc_request_handle_notconn(struct ptlrpc_request *);
 void lustre_assert_wire_constants(void);
 
-void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
+#ifdef __KERNEL__
+void ptlrpc_lprocfs_register_service(struct proc_dir_entry *proc_entry,
                                      struct ptlrpc_service *svc);
 void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc);
+void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req);
+void ptlrpc_lprocfs_do_request_stat (struct ptlrpc_request *req,
+                                     long q_usec, long work_usec);
+#else
+#define ptlrpc_lprocfs_register_service(params...) do{}while(0)
+#define ptlrpc_lprocfs_unregister_service(params...) do{}while(0)
+#define ptlrpc_lprocfs_rpc_sent(params...) do{}while(0)
+#define ptlrpc_lprocfs_do_request_stat(params...) do{}while(0)
+#endif /* __KERNEL__ */
 
 /* recovd_thread.c */
 int llog_init_commit_master(void);
@@ -96,7 +101,10 @@ enum {
 };
 
 int ptlrpc_expire_one_request(struct ptlrpc_request *req);
-int ptlrpc_check_set(struct ptlrpc_request_set *set);
 
+/* pinger.c */
+int ptlrpc_start_pinger(void);
+int ptlrpc_stop_pinger(void);
 void ptlrpc_pinger_sending_on_import(struct obd_import *imp);
+
 #endif /* PTLRPC_INTERNAL_H */
diff --git a/lustre/ptlrpc/ptlrpc_lib.c b/lustre/ptlrpc/ptlrpc_lib.c
deleted file mode 100644
index 3dfec9a62cd99966a100e1c51ff56829803ce7e6..0000000000000000000000000000000000000000
--- a/lustre/ptlrpc/ptlrpc_lib.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2003 Cluster File Systems, Inc.
- *
- *   This file is part of Lustre, http://www.lustre.org.
- *
- *   Lustre is free software; you can redistribute it and/or
- *   modify it under the terms of version 2 of the GNU General Public
- *   License as published by the Free Software Foundation.
- *
- *   Lustre 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 Lustre; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define EXPORT_SYMTAB
-#define DEBUG_SUBSYSTEM S_RPC
-
-#ifdef __KERNEL__
-# include <linux/module.h>
-#else
-# include <liblustre.h>
-#endif
-#include <linux/obd.h>
-#include <linux/obd_ost.h>
-#include <linux/lustre_mgmt.h>
-#include <linux/lustre_net.h>
-#include <linux/lustre_dlm.h>
-
-int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
-{
-        struct ptlrpc_connection *conn;
-        struct obd_ioctl_data* data = buf;
-        struct client_obd *cli = &obddev->u.cli;
-        struct obd_import *imp;
-        struct obd_uuid server_uuid;
-        int rq_portal, rp_portal, connect_op;
-        char *name = obddev->obd_type->typ_name;
-        ENTRY;
-
-        /* In a more perfect world, we would hang a ptlrpc_client off of
-         * obd_type and just use the values from there. */
-        if (!strcmp(name, LUSTRE_OSC_NAME)) {
-                rq_portal = OST_REQUEST_PORTAL;
-                rp_portal = OSC_REPLY_PORTAL;
-                connect_op = OST_CONNECT;
-        } else if (!strcmp(name, LUSTRE_MDC_NAME)) {
-                rq_portal = MDS_REQUEST_PORTAL;
-                rp_portal = MDC_REPLY_PORTAL;
-                connect_op = MDS_CONNECT;
-        } else if (!strcmp(name, LUSTRE_MGMTCLI_NAME)) {
-                rq_portal = MGMT_REQUEST_PORTAL;
-                rp_portal = MGMT_REPLY_PORTAL;
-                connect_op = MGMT_CONNECT;
-        } else {
-                CERROR("unknown client OBD type \"%s\", can't setup\n",
-                       name);
-                RETURN(-EINVAL);
-        }
-
-        if (data->ioc_inllen1 < 1) {
-                CERROR("requires a TARGET UUID\n");
-                RETURN(-EINVAL);
-        }
-
-        if (data->ioc_inllen1 > 37) {
-                CERROR("client UUID must be less than 38 characters\n");
-                RETURN(-EINVAL);
-        }
-
-        if (data->ioc_inllen2 < 1) {
-                CERROR("setup requires a SERVER UUID\n");
-                RETURN(-EINVAL);
-        }
-
-        if (data->ioc_inllen2 > 37) {
-                CERROR("target UUID must be less than 38 characters\n");
-                RETURN(-EINVAL);
-        }
-
-        sema_init(&cli->cl_sem, 1);
-        cli->cl_conn_count = 0;
-        memcpy(server_uuid.uuid, data->ioc_inlbuf2, MIN(data->ioc_inllen2,
-                                                        sizeof(server_uuid)));
-
-        init_MUTEX(&cli->cl_dirty_sem);
-        cli->cl_dirty = 0;
-        cli->cl_dirty_granted = 0;
-        cli->cl_ost_can_grant = 1;
-
-        conn = ptlrpc_uuid_to_connection(&server_uuid);
-        if (conn == NULL)
-                RETURN(-ENOENT);
-
-        ptlrpc_init_client(rq_portal, rp_portal, name,
-                           &obddev->obd_ldlm_client);
-
-        imp = class_new_import();
-        if (imp == NULL) {
-                ptlrpc_put_connection(conn);
-                RETURN(-ENOMEM);
-        }
-        imp->imp_connection = conn;
-        imp->imp_client = &obddev->obd_ldlm_client;
-        imp->imp_obd = obddev;
-        imp->imp_connect_op = connect_op;
-        imp->imp_generation = 0;
-        INIT_LIST_HEAD(&imp->imp_pinger_chain);
-        memcpy(imp->imp_target_uuid.uuid, data->ioc_inlbuf1, data->ioc_inllen1);
-        class_import_put(imp);
-
-        cli->cl_import = imp;
-        cli->cl_max_mds_easize = sizeof(struct lov_mds_md);
-        cli->cl_max_mds_cookiesize = sizeof(struct llog_cookie);
-        cli->cl_sandev = to_kdev_t(0);
-
-        /* Register with management client if we need to. */
-        if (data->ioc_inllen3 > 0) {
-                char *mgmt_name = data->ioc_inlbuf3;
-                int rc;
-                struct obd_device *mgmt_obd;
-                mgmtcli_register_for_events_t register_f;
-
-                CDEBUG(D_HA, "%s registering with %s for events about %s\n",
-                       obddev->obd_name, mgmt_name, server_uuid.uuid);
-
-                mgmt_obd = class_name2obd(mgmt_name);
-                if (!mgmt_obd) {
-                        CERROR("can't find mgmtcli %s to register\n",
-                               mgmt_name);
-                        class_destroy_import(imp);
-                        RETURN(-ENOENT);
-                }
-                
-                register_f = inter_module_get("mgmtcli_register_for_events");
-                if (!register_f) {
-                        CERROR("can't i_m_g mgmtcli_register_for_events\n");
-                        class_destroy_import(imp);
-                        RETURN(-ENOSYS);
-                }
-                
-                rc = register_f(mgmt_obd, obddev, &imp->imp_target_uuid);
-                inter_module_put("mgmtcli_register_for_events");
-
-                if (!rc)
-                        cli->cl_mgmtcli_obd = mgmt_obd;
-
-                RETURN(rc);
-        }
-
-        RETURN(0);
-}
-
-int client_obd_cleanup(struct obd_device *obddev, int flags)
-{
-        struct client_obd *cli = &obddev->u.cli;
-
-        if (!cli->cl_import)
-                RETURN(-EINVAL);
-        if (cli->cl_mgmtcli_obd) {
-                mgmtcli_deregister_for_events_t dereg_f;
-                
-                dereg_f = inter_module_get("mgmtcli_deregister_for_events");
-                dereg_f(cli->cl_mgmtcli_obd, obddev);
-                inter_module_put("mgmtcli_deregister_for_events");
-        }
-        class_destroy_import(cli->cl_import);
-        cli->cl_import = NULL;
-        RETURN(0);
-}
diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c
index 4b75026ecd7d98ec5675683bad44892930125943..44e3ebc10311926d0777f9dc7da047fd543f5c58 100644
--- a/lustre/ptlrpc/ptlrpc_module.c
+++ b/lustre/ptlrpc/ptlrpc_module.c
@@ -20,7 +20,9 @@
  *
  */
 
-#define EXPORT_SYMTAB
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
 #define DEBUG_SUBSYSTEM S_RPC
 
 #ifdef __KERNEL__
@@ -38,62 +40,6 @@
 
 extern int ptlrpc_init_portals(void);
 extern void ptlrpc_exit_portals(void);
-static int ldlm_hooks_referenced = 0;
-
-int (*ptlrpc_ldlm_namespace_cleanup)(struct ldlm_namespace *, int);
-int (*ptlrpc_ldlm_replay_locks)(struct obd_import *);
-
-#define GET_HOOK(name)                                                         \
-if (!ptlrpc_##name) {                                                          \
-        if (!(ptlrpc_##name = inter_module_get(#name))) {                      \
-                CERROR("can't i_m_g(\"" #name "\")\n");                        \
-                return 0;                                                      \
-        }                                                                      \
-}
-
-static int ldlm_hooks_referenced;
-
-/* This is called from ptlrpc_get_connection, which runs after all the modules
- * are loaded, but before anything else interesting happens.
- */
-int ptlrpc_get_ldlm_hooks(void)
-{
-        if (ldlm_hooks_referenced)
-                return 1;
-
-        GET_HOOK(ldlm_namespace_cleanup);
-        GET_HOOK(ldlm_replay_locks);
-
-        ldlm_hooks_referenced = 1;
-        RETURN(1);
-}
-
-#undef GET_HOOK
-
-#define PUT_HOOK(hook)                                                         \
-if (ptlrpc_##hook) {                                                           \
-        inter_module_put(#hook);                                               \
-        ptlrpc_##hook = NULL;                                                  \
-}
-
-void ptlrpc_put_ldlm_hooks(void)
-{
-        ENTRY;
-        if (!ldlm_hooks_referenced)
-                return;
-
-        PUT_HOOK(ldlm_namespace_cleanup);
-        PUT_HOOK(ldlm_replay_locks);
-        ldlm_hooks_referenced = 0;
-        EXIT;
-}
-
-#undef PUT_HOOK
-
-int ptlrpc_ldlm_hooks_referenced(void)
-{
-        return ldlm_hooks_referenced;
-}
 
 __init int ptlrpc_init(void)
 {
@@ -111,16 +57,20 @@ __init int ptlrpc_init(void)
 
         ptlrpc_put_connection_superhack = ptlrpc_put_connection;
         ptlrpc_abort_inflight_superhack = ptlrpc_abort_inflight;
+
+        ptlrpc_start_pinger();
+        ldlm_init();
         RETURN(0);
 }
 
+#ifdef __KERNEL__
 static void __exit ptlrpc_exit(void)
 {
+        ldlm_exit();
+        ptlrpc_stop_pinger();
         ptlrpc_exit_portals();
         ptlrpc_cleanup_connection();
-#ifdef ENABLE_ORPHANS
         llog_cleanup_commit_master(0);
-#endif
 }
 
 /* connection.c */
@@ -156,6 +106,7 @@ EXPORT_SYMBOL(ptlrpc_prep_req);
 EXPORT_SYMBOL(ptlrpc_free_req);
 EXPORT_SYMBOL(ptlrpc_unregister_reply);
 EXPORT_SYMBOL(ptlrpc_req_finished);
+EXPORT_SYMBOL(ptlrpc_req_finished_with_imp_lock);
 EXPORT_SYMBOL(ptlrpc_request_addref);
 EXPORT_SYMBOL(ptlrpc_prep_bulk_imp);
 EXPORT_SYMBOL(ptlrpc_prep_bulk_exp);
@@ -168,17 +119,25 @@ EXPORT_SYMBOL(ptlrpc_next_xid);
 
 EXPORT_SYMBOL(ptlrpc_prep_set);
 EXPORT_SYMBOL(ptlrpc_set_add_req);
+EXPORT_SYMBOL(ptlrpc_set_add_new_req);
 EXPORT_SYMBOL(ptlrpc_set_destroy);
+EXPORT_SYMBOL(ptlrpc_set_next_timeout);
+EXPORT_SYMBOL(ptlrpc_check_set);
 EXPORT_SYMBOL(ptlrpc_set_wait);
+EXPORT_SYMBOL(ptlrpc_expired_set);
+EXPORT_SYMBOL(ptlrpc_interrupted_set);
 
 /* service.c */
 EXPORT_SYMBOL(ptlrpc_init_svc);
 EXPORT_SYMBOL(ptlrpc_stop_all_threads);
+EXPORT_SYMBOL(ptlrpc_start_n_threads);
 EXPORT_SYMBOL(ptlrpc_start_thread);
 EXPORT_SYMBOL(ptlrpc_unregister_service);
 
 /* pack_generic.c */
-EXPORT_SYMBOL(lustre_pack_msg);
+EXPORT_SYMBOL(lustre_msg_swabbed);
+EXPORT_SYMBOL(lustre_pack_request);
+EXPORT_SYMBOL(lustre_pack_reply);
 EXPORT_SYMBOL(lustre_msg_size);
 EXPORT_SYMBOL(lustre_unpack_msg);
 EXPORT_SYMBOL(lustre_msg_buf);
@@ -190,9 +149,9 @@ EXPORT_SYMBOL(lustre_swab_obd_statfs);
 EXPORT_SYMBOL(lustre_swab_obd_ioobj);
 EXPORT_SYMBOL(lustre_swab_niobuf_remote);
 EXPORT_SYMBOL(lustre_swab_ost_body);
+EXPORT_SYMBOL(lustre_swab_ost_last_id);
 EXPORT_SYMBOL(lustre_swab_ll_fid);
 EXPORT_SYMBOL(lustre_swab_mds_status_req);
-EXPORT_SYMBOL(lustre_swab_mds_fileh_body);
 EXPORT_SYMBOL(lustre_swab_mds_body);
 EXPORT_SYMBOL(lustre_swab_mds_rec_setattr);
 EXPORT_SYMBOL(lustre_swab_mds_rec_create);
@@ -201,7 +160,7 @@ EXPORT_SYMBOL(lustre_swab_mds_rec_unlink);
 EXPORT_SYMBOL(lustre_swab_mds_rec_rename);
 EXPORT_SYMBOL(lustre_swab_lov_desc);
 EXPORT_SYMBOL(lustre_swab_ldlm_res_id);
-EXPORT_SYMBOL(lustre_swab_ldlm_extent);
+EXPORT_SYMBOL(lustre_swab_ldlm_policy_data);
 EXPORT_SYMBOL(lustre_swab_ldlm_intent);
 EXPORT_SYMBOL(lustre_swab_ldlm_resource_desc);
 EXPORT_SYMBOL(lustre_swab_ldlm_lock_desc);
@@ -211,14 +170,11 @@ EXPORT_SYMBOL(lustre_swab_ptlbd_op);
 EXPORT_SYMBOL(lustre_swab_ptlbd_niob);
 EXPORT_SYMBOL(lustre_swab_ptlbd_rsp);
 
-/* ptlrpc_module.c */
-EXPORT_SYMBOL(ptlrpc_put_ldlm_hooks);
-EXPORT_SYMBOL(ptlrpc_ldlm_hooks_referenced);
-
 /* recover.c */
 EXPORT_SYMBOL(ptlrpc_run_recovery_over_upcall);
 EXPORT_SYMBOL(ptlrpc_run_failed_import_upcall);
-EXPORT_SYMBOL(ptlrpc_reconnect_import);
+EXPORT_SYMBOL(ptlrpc_connect_import);
+EXPORT_SYMBOL(ptlrpc_disconnect_import);
 EXPORT_SYMBOL(ptlrpc_replay);
 EXPORT_SYMBOL(ptlrpc_resend);
 EXPORT_SYMBOL(ptlrpc_wake_delayed);
@@ -227,18 +183,24 @@ EXPORT_SYMBOL(ptlrpc_fail_import);
 EXPORT_SYMBOL(ptlrpc_fail_export);
 EXPORT_SYMBOL(ptlrpc_recover_import);
 
-/*ptlrpc_lib.c*/
-EXPORT_SYMBOL(client_obd_setup);
-EXPORT_SYMBOL(client_obd_cleanup);
-
 /* pinger.c */
 EXPORT_SYMBOL(ptlrpc_pinger_add_import);
 EXPORT_SYMBOL(ptlrpc_pinger_del_import);
 EXPORT_SYMBOL(ptlrpc_pinger_sending_on_import);
 
-#ifdef __KERNEL__
+/* lproc_ptlrpc.c */
+EXPORT_SYMBOL(ptlrpc_lprocfs_register_obd);
+EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);
+
+/* llogd.c */
+EXPORT_SYMBOL(llog_origin_handle_create);
+EXPORT_SYMBOL(llog_origin_handle_next_block);
+EXPORT_SYMBOL(llog_origin_handle_read_header);
+EXPORT_SYMBOL(llog_origin_handle_close);
+EXPORT_SYMBOL(llog_client_ops);
+
 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre Request Processor");
+MODULE_DESCRIPTION("Lustre Request Processor and Lock Management");
 MODULE_LICENSE("GPL");
 
 module_init(ptlrpc_init);
diff --git a/lustre/ptlrpc/recov_thread.c b/lustre/ptlrpc/recov_thread.c
index 45cda954d14b151fc3b96253be79988b507cb075..74aa72b2b73002640bcf201584c700b8ed850c2a 100644
--- a/lustre/ptlrpc/recov_thread.c
+++ b/lustre/ptlrpc/recov_thread.c
@@ -32,12 +32,14 @@
 # define EXPORT_SYMTAB
 #endif
 
-#ifndef __KERNEL__
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
 # include <portals/list.h>
 # include <liblustre.h>
 #endif
+
 #include <linux/kp30.h>
-#include <linux/fs.h>
 #include <linux/obd_class.h>
 #include <linux/lustre_commit_confd.h>
 #include <linux/obd_support.h>
@@ -45,17 +47,21 @@
 #include <linux/lustre_net.h>
 #include <portals/types.h>
 #include <portals/list.h>
+#include <linux/lustre_log.h>
 #include "ptlrpc_internal.h"
 
+#ifdef __KERNEL__
+
 static struct llog_commit_master lustre_lcm;
 static struct llog_commit_master *lcm = &lustre_lcm;
 
 /* Allocate new commit structs in case we do not have enough */
 static int llcd_alloc(void)
 {
-        struct llog_commit_data *llcd;
+        struct llog_canceld_ctxt *llcd;
+        int offset = offsetof(struct llog_canceld_ctxt, llcd_cookies);
 
-        OBD_ALLOC(llcd, PAGE_SIZE);
+        OBD_ALLOC(llcd, PAGE_SIZE + offset);
         if (llcd == NULL)
                 return -ENOMEM;
 
@@ -70,9 +76,9 @@ static int llcd_alloc(void)
 }
 
 /* Get a free cookie struct from the list */
-struct llog_commit_data *llcd_grab(void)
+struct llog_canceld_ctxt *llcd_grab(void)
 {
-        struct llog_commit_data *llcd;
+        struct llog_canceld_ctxt *llcd;
 
         spin_lock(&lcm->lcm_llcd_lock);
         if (list_empty(&lcm->lcm_llcd_free)) {
@@ -96,10 +102,12 @@ struct llog_commit_data *llcd_grab(void)
 }
 EXPORT_SYMBOL(llcd_grab);
 
-static void llcd_put(struct llog_commit_data *llcd)
+static void llcd_put(struct llog_canceld_ctxt *llcd)
 {
+        int offset = offsetof(struct llog_canceld_ctxt, llcd_cookies);
+
         if (atomic_read(&lcm->lcm_llcd_numfree) >= lcm->lcm_llcd_maxfree) {
-                OBD_FREE(llcd, PAGE_SIZE);
+                OBD_FREE(llcd, PAGE_SIZE + offset);
         } else {
                 spin_lock(&lcm->lcm_llcd_lock);
                 list_add(&llcd->llcd_list, &lcm->lcm_llcd_free);
@@ -109,7 +117,7 @@ static void llcd_put(struct llog_commit_data *llcd)
 }
 
 /* Send some cookies to the appropriate target */
-void llcd_send(struct llog_commit_data *llcd)
+void llcd_send(struct llog_canceld_ctxt *llcd)
 {
         spin_lock(&llcd->llcd_lcm->lcm_llcd_lock);
         list_add_tail(&llcd->llcd_list, &llcd->llcd_lcm->lcm_llcd_pending);
@@ -119,11 +127,88 @@ void llcd_send(struct llog_commit_data *llcd)
 }
 EXPORT_SYMBOL(llcd_send);
 
+/* deleted objects have a commit callback that cancels the MDS
+ * log record for the deletion.  The commit callback calls this 
+ * function 
+ */
+int llog_obd_repl_cancel(struct llog_ctxt *ctxt,
+                         struct lov_stripe_md *lsm, int count,
+                         struct llog_cookie *cookies, int flags)
+{
+        struct llog_canceld_ctxt *llcd;
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(ctxt);
+
+        if (count == 0 || cookies == NULL) {
+                down(&ctxt->loc_sem);
+                if (ctxt->loc_llcd == NULL || !(flags & OBD_LLOG_FL_SENDNOW))
+                        GOTO(out, rc);
+
+                llcd = ctxt->loc_llcd;
+                GOTO(send_now, rc);
+        }
+
+        down(&ctxt->loc_sem);
+        llcd = ctxt->loc_llcd;
+        if (llcd == NULL) {
+                llcd = llcd_grab();
+                if (llcd == NULL) {
+                        CERROR("couldn't get an llcd - dropped "LPX64":%x+%u\n",
+                               cookies->lgc_lgl.lgl_oid,
+                               cookies->lgc_lgl.lgl_ogen, cookies->lgc_index);
+                        GOTO(out, rc = -ENOMEM);
+                }
+                llcd->llcd_import = ctxt->loc_imp;
+                llcd->llcd_gen = ctxt->loc_gen;
+                ctxt->loc_llcd = llcd;
+        }
+
+        memcpy((char *)llcd->llcd_cookies + llcd->llcd_cookiebytes, cookies,
+               sizeof(*cookies));
+        llcd->llcd_cookiebytes += sizeof(*cookies);
+
+send_now:
+        if ((PAGE_SIZE - llcd->llcd_cookiebytes < sizeof(*cookies) ||
+             flags & OBD_LLOG_FL_SENDNOW)) {
+                CDEBUG(D_HA, "send llcd: %p\n", llcd);
+                ctxt->loc_llcd = NULL;
+                llcd_send(llcd);
+        }
+out:
+        up(&ctxt->loc_sem);
+        return rc;
+}
+EXPORT_SYMBOL(llog_obd_repl_cancel);
+
+int llog_obd_repl_sync(struct llog_ctxt *ctxt, struct obd_export *exp)
+{
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(ctxt->loc_llcd);
+
+        if (exp && (ctxt->loc_imp == exp->exp_imp_reverse)) {
+                CWARN("import will be destroyed, put llcd %p\n", 
+                      ctxt->loc_llcd);
+                llcd_put(ctxt->loc_llcd);
+                ctxt->loc_llcd = NULL;
+                up(&ctxt->loc_sem);
+        } else {
+                up(&ctxt->loc_sem);
+                rc = llog_cancel(ctxt, NULL, 0, NULL, OBD_LLOG_FL_SENDNOW);
+        }
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_obd_repl_sync);
+
 static int log_commit_thread(void *arg)
 {
         struct llog_commit_master *lcm = arg;
         struct llog_commit_daemon *lcd;
-        struct llog_commit_data *llcd, *n;
+        struct llog_canceld_ctxt *llcd, *n;
         unsigned long flags;
         ENTRY;
 
@@ -231,7 +316,27 @@ static int log_commit_thread(void *arg)
                 /* We are the only one manipulating our local list - no lock */
                 list_for_each_entry_safe(llcd,n, &lcd->lcd_llcd_list,llcd_list){
                         char *bufs[1] = {(char *)llcd->llcd_cookies};
+                        struct obd_device *obd = import->imp_obd;
+                        struct llog_ctxt *ctxt;
+
                         list_del(&llcd->llcd_list);
+                        if (llcd->llcd_cookiebytes == 0) {
+                                CDEBUG(D_HA, "just put empty llcd %p\n", llcd);
+                                llcd_put(llcd);
+                                continue;
+                        }
+                        /* check whether the cookies are new. if new then send, otherwise
+                         * just put llcd */
+                        ctxt = llog_get_context(obd, llcd->llcd_cookies[0].lgc_subsys + 1);
+                        LASSERT(ctxt != NULL);
+                        down(&ctxt->loc_sem);
+                        if (log_gen_lt(llcd->llcd_gen, ctxt->loc_gen)) {
+                                up(&ctxt->loc_sem); 
+                                CDEBUG(D_HA, "just put stale llcd %p\n", llcd);
+                                llcd_put(llcd);
+                                continue;
+                        }
+                        up(&ctxt->loc_sem); 
 
                         request = ptlrpc_prep_req(import, OBD_LOG_CANCEL, 1,
                                                   &llcd->llcd_cookiebytes,
@@ -259,10 +364,11 @@ static int log_commit_thread(void *arg)
                                 continue;
                         }
 
+#if 0                   /* FIXME just put llcd, not send it again */
                         spin_lock(&lcm->lcm_llcd_lock);
                         list_splice(&lcd->lcd_llcd_list, &lcm->lcm_llcd_resend);
                         if (++llcd->llcd_tries < 5) {
-                                CERROR("commit %p failed %dx: rc %d\n",
+                                CERROR("commit %p failed on attempt %d: rc %d\n",
                                        llcd, llcd->llcd_tries, rc);
 
                                 list_add_tail(&llcd->llcd_list,
@@ -270,12 +376,13 @@ static int log_commit_thread(void *arg)
                                 spin_unlock(&lcm->lcm_llcd_lock);
                         } else {
                                 spin_unlock(&lcm->lcm_llcd_lock);
+#endif
                                 CERROR("commit %p dropped %d cookies: rc %d\n",
                                        llcd, (int)(llcd->llcd_cookiebytes /
                                                    sizeof(*llcd->llcd_cookies)),
                                        rc);
                                 llcd_put(llcd);
-                        }
+//                        }
                         break;
                 }
 
@@ -298,6 +405,9 @@ static int log_commit_thread(void *arg)
                         llcd_put(llcd);
         }
 
+        spin_lock(&lcm->lcm_thread_lock);
+        list_del(&lcd->lcd_lcm_list);
+        spin_unlock(&lcm->lcm_thread_lock);
         OBD_FREE(lcd, sizeof(*lcd));
 
         spin_lock(&lcm->lcm_thread_lock);
@@ -328,6 +438,12 @@ int llog_start_commit_thread(void)
 }
 EXPORT_SYMBOL(llog_start_commit_thread);
 
+static struct llog_process_args {
+        struct semaphore         llpa_sem; 
+        struct llog_ctxt        *llpa_ctxt;
+        void                    *llpa_cb;
+        void                    *llpa_arg;
+} llpa;
 int llog_init_commit_master(void)
 {
         INIT_LIST_HEAD(&lcm->lcm_thread_busy);
@@ -342,6 +458,8 @@ int llog_init_commit_master(void)
         atomic_set(&lcm->lcm_llcd_numfree, 0);
         lcm->lcm_llcd_minfree = 0;
         lcm->lcm_thread_max = 5;
+        /* FIXME initialize semaphore for llog_process_args */
+        sema_init(&llpa.llpa_sem, 1);
         return 0;
 }
 
@@ -356,3 +474,116 @@ int llog_cleanup_commit_master(int force)
                                  atomic_read(&lcm->lcm_thread_total) == 0);
         return 0;
 }
+
+
+static int log_process_thread(void *args)
+{
+        struct llog_process_args *data = args;
+        struct llog_ctxt *ctxt = data->llpa_ctxt;
+        void   *cb = data->llpa_cb;
+        struct llog_logid logid = *(struct llog_logid *)(data->llpa_arg);
+        struct llog_handle *llh = NULL;
+        unsigned long flags;
+        int rc;
+        ENTRY;
+                                                                                                                             
+        up(&data->llpa_sem);
+        lock_kernel();
+        ptlrpc_daemonize(); /* thread never needs to do IO */
+                                                                                                                             
+        SIGNAL_MASK_LOCK(current, flags);
+        sigfillset(&current->blocked);
+        RECALC_SIGPENDING;
+        SIGNAL_MASK_UNLOCK(current, flags);
+        unlock_kernel();
+                                                                                                                             
+        rc = llog_create(ctxt, &llh, &logid, NULL);
+        if (rc) {
+                CERROR("llog_create failed %d\n", rc);
+                RETURN(rc);
+        }
+        rc = llog_init_handle(llh, LLOG_F_IS_CAT, NULL);
+        if (rc) {
+                CERROR("llog_init_handle failed %d\n", rc);
+                GOTO(out, rc);
+        }
+                                                                                                                             
+        if (cb) {
+                rc = llog_cat_process(llh, (llog_cb_t)cb, NULL);
+                if (rc)
+                        CERROR("llog_cat_process failed %d\n", rc);
+        } else
+                CWARN("no callback function for recovery\n");
+
+        CDEBUG(D_HA, "send to llcd :%p forcibly\n", ctxt->loc_llcd);
+        llog_sync(ctxt, NULL);
+out:
+        rc = llog_cat_put(llh);
+        if (rc)
+                CERROR("llog_cat_put failed %d\n", rc);
+                                                                                                                             
+        RETURN(rc);
+}
+static int llog_recovery_generic(struct llog_ctxt *ctxt,
+                                 void *handle,
+                                 void *arg)
+{
+        int rc;
+        ENTRY;
+
+        down(&llpa.llpa_sem);
+        llpa.llpa_ctxt = ctxt;
+        llpa.llpa_cb = handle;
+        llpa.llpa_arg = arg;
+
+        rc = kernel_thread(log_process_thread, &llpa, CLONE_VM | CLONE_FILES);
+        if (rc < 0)
+                CERROR("error starting log_process_thread: %d\n", rc);
+        else {
+                CDEBUG(D_HA, "log_process_thread: %d\n", rc);
+                rc = 0;
+        }
+
+        RETURN(rc);
+}
+int llog_repl_connect(struct llog_ctxt *ctxt, int count,
+                      struct llog_logid *logid, struct llog_ctxt_gen *gen)
+{
+        struct llog_canceld_ctxt *llcd;
+        int rc;
+        ENTRY;
+                                                                                                                             
+        down(&ctxt->loc_sem);
+        ctxt->loc_gen = *gen;
+        llcd = ctxt->loc_llcd;
+        if (llcd) {
+                CDEBUG(D_HA, "put current llcd when new connection arrives\n");
+                llcd_put(llcd);
+        }
+        llcd = llcd_grab();
+        if (llcd == NULL) {
+                CERROR("couldn't get an llcd\n");
+                RETURN(-ENOMEM);
+        }
+        llcd->llcd_import = ctxt->loc_imp;
+        llcd->llcd_gen = ctxt->loc_gen;
+        ctxt->loc_llcd = llcd;
+        up(&ctxt->loc_sem);
+
+        rc = llog_recovery_generic(ctxt, ctxt->llog_proc_cb, logid); 
+        if (rc != 0)
+                CERROR("error recovery process: %d\n", rc);
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_repl_connect);
+
+#else /* !__KERNEL__ */
+
+int llog_obd_repl_cancel(struct llog_ctxt *ctxt,
+                         struct lov_stripe_md *lsm, int count,
+                         struct llog_cookie *cookies, int flags)
+{
+        return 0;
+}
+#endif
diff --git a/lustre/ptlrpc/recover.c b/lustre/ptlrpc/recover.c
index 3320a448f0b6a31ddcf8b2ee442307cdc28fd621..3d5c1ec4611ecdcb2f7ebf86116a5d79ad61625d 100644
--- a/lustre/ptlrpc/recover.c
+++ b/lustre/ptlrpc/recover.c
@@ -37,98 +37,13 @@
 #include <linux/lustre_import.h>
 #include <linux/lustre_export.h>
 #include <linux/obd.h>
+#include <linux/obd_ost.h>
 #include <linux/obd_class.h>
 #include <linux/obd_lov.h> /* for IOC_LOV_SET_OSC_ACTIVE */
 
 #include "ptlrpc_internal.h"
 
-enum reconnect_result {
-        RECON_RESULT_RECOVERING  =  1,
-        RECON_RESULT_RECONNECTED  = 2,
-        RECON_RESULT_EVICTED      = 3,
-};
-
-int ptlrpc_reconnect_import(struct obd_import *imp)
-{
-        struct obd_device *obd = imp->imp_obd;
-        int rc, size[] = {sizeof(imp->imp_target_uuid),
-                                 sizeof(obd->obd_uuid),
-                                 sizeof(imp->imp_dlm_handle)};
-        char *tmp[] = {imp->imp_target_uuid.uuid,
-                       obd->obd_uuid.uuid,
-                       (char *)&imp->imp_dlm_handle};
-        struct ptlrpc_connection *conn = imp->imp_connection;
-        struct ptlrpc_request *req;
-        struct lustre_handle old_hdl;
-        __u64 committed_before_reconnect = imp->imp_peer_committed_transno;
-        ENTRY;
-
-        req = ptlrpc_prep_req(imp, imp->imp_connect_op, 3, size, tmp);
-        if (!req)
-                RETURN(-ENOMEM);
-        req->rq_level = LUSTRE_CONN_NEW;
-        req->rq_replen = lustre_msg_size(0, NULL);
-        rc = ptlrpc_queue_wait(req);
-        if (rc) {
-                /* what if rc > 0 ??*/
-                CERROR("cannot connect to %s@%s: rc = %d\n",
-                       imp->imp_target_uuid.uuid, conn->c_remote_uuid.uuid, rc);
-                GOTO(out_disc, rc);
-        }
-
-        if (lustre_msg_get_op_flags(req->rq_repmsg) & MSG_CONNECT_RECONNECT) {
-                memset(&old_hdl, 0, sizeof(old_hdl));
-                if (!memcmp(&old_hdl, &req->rq_repmsg->handle,
-                            sizeof (old_hdl))) {
-                        CERROR("%s@%s didn't like our handle "LPX64
-                               ", failed\n", imp->imp_target_uuid.uuid,
-                               conn->c_remote_uuid.uuid,
-                               imp->imp_dlm_handle.cookie);
-                        GOTO(out_disc, rc = -ENOTCONN);
-                }
-
-                if (memcmp(&imp->imp_remote_handle, &req->rq_repmsg->handle,
-                           sizeof(imp->imp_remote_handle))) {
-                        CERROR("%s@%s changed handle from "LPX64" to "LPX64
-                               "; copying, but this may foreshadow disaster\n",
-                               imp->imp_target_uuid.uuid,
-                               conn->c_remote_uuid.uuid,
-                               imp->imp_remote_handle.cookie,
-                               req->rq_repmsg->handle.cookie);
-                        imp->imp_remote_handle = req->rq_repmsg->handle;
-                        GOTO(out_disc, rc = RECON_RESULT_RECONNECTED);
-                }
-
-                CERROR("reconnected to %s@%s after partition\n",
-                       imp->imp_target_uuid.uuid, conn->c_remote_uuid.uuid);
-                GOTO(out_disc, rc = RECON_RESULT_RECONNECTED);
-        } else if (lustre_msg_get_op_flags(req->rq_repmsg) &
-                   MSG_CONNECT_RECOVERING) {
-                rc = RECON_RESULT_RECOVERING;
-        } else {
-                rc = RECON_RESULT_EVICTED;
-        }
-
-        old_hdl = imp->imp_remote_handle;
-        imp->imp_remote_handle = req->rq_repmsg->handle;
-        CERROR("reconnected to %s@%s ("LPX64", was "LPX64")!\n",
-               imp->imp_target_uuid.uuid, conn->c_remote_uuid.uuid,
-               imp->imp_remote_handle.cookie, old_hdl.cookie);
-        if (req->rq_repmsg->last_committed < committed_before_reconnect) {
-                CERROR("%s went back in time (transno "LPD64
-                       " was committed, server claims "LPD64
-                       ")! is shared storage not coherent?\n",
-                       imp->imp_target_uuid.uuid,
-                       imp->imp_peer_committed_transno,
-                       req->rq_repmsg->last_committed);
-        }
-
-        GOTO(out_disc, rc);
-
- out_disc:
-        ptlrpc_req_finished(req);
-        return rc;
-}
+static int ptlrpc_recover_import_no_retry(struct obd_import *, char *);
 
 void ptlrpc_run_recovery_over_upcall(struct obd_device *obd)
 {
@@ -160,6 +75,7 @@ void ptlrpc_run_recovery_over_upcall(struct obd_device *obd)
 
 void ptlrpc_run_failed_import_upcall(struct obd_import* imp)
 {
+#ifdef __KERNEL__
         char *argv[7];
         char *envp[3];
         int rc;
@@ -187,6 +103,9 @@ void ptlrpc_run_failed_import_upcall(struct obd_import* imp)
                 CERROR("Invoked upcall %s %s %s %s %s\n",
                        argv[0], argv[1], argv[2], argv[3], argv[4]);
         }
+#else
+        ptlrpc_recover_import(imp, NULL);
+#endif
 }
 
 int ptlrpc_replay(struct obd_import *imp)
@@ -259,7 +178,7 @@ int ptlrpc_resend(struct obd_import *imp)
         /* Well... what if lctl recover is called twice at the same time?
          */
         spin_lock_irqsave(&imp->imp_lock, flags);
-        LASSERT(imp->imp_level == LUSTRE_CONN_RECOVER);
+        LASSERT(imp->imp_state == LUSTRE_IMP_RECOVER);
         spin_unlock_irqrestore(&imp->imp_lock, flags);
 
         list_for_each_safe(tmp, pos, &imp->imp_sending_list) {
@@ -297,12 +216,16 @@ void ptlrpc_wake_delayed(struct obd_import *imp)
 
 inline void ptlrpc_invalidate_import_state(struct obd_import *imp)
 {
-        struct ldlm_namespace *ns = imp->imp_obd->obd_namespace;
-        if (ptlrpc_ldlm_namespace_cleanup == NULL)
-                CERROR("ptlrpc/ldlm hook is NULL!  Please tell phil\n");
-        else
-                ptlrpc_ldlm_namespace_cleanup(ns, 1 /* no network ops */);
+        struct obd_device *obd = imp->imp_obd;
+        struct ldlm_namespace *ns = obd->obd_namespace;
+
         ptlrpc_abort_inflight(imp);
+
+#if 0
+        obd_invalidate_import(obd, imp);
+#endif
+
+        ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY | LDLM_FL_CANCEL);
 }
 
 void ptlrpc_handle_failed_import(struct obd_import *imp)
@@ -332,38 +255,29 @@ void ptlrpc_request_handle_notconn(struct ptlrpc_request *failed_req)
                imp->imp_obd->obd_name,
                imp->imp_target_uuid.uuid,
                imp->imp_connection->c_remote_uuid.uuid);
-        rc = ptlrpc_recover_import(imp, NULL);
-        if (rc < 0) {
-                ptlrpc_resend_req(failed_req);
-                if (rc != -EALREADY)
-                        ptlrpc_handle_failed_import(imp);
-        } else if (rc == RECON_RESULT_RECOVERING) {
-                ptlrpc_resend_req(failed_req);
-        } else {
-                if (rc != RECON_RESULT_EVICTED) {
-                        /* like LBUG, without the locking up */
-                        CERROR("unknown recover_import result %d\n", rc);
-                        portals_debug_dumplog();
-                        portals_run_lbug_upcall(__FILE__, __FUNCTION__,
-                                                __LINE__);
-                }
-                LASSERT(failed_req->rq_import_generation < imp->imp_generation);
+
+        rc = ptlrpc_recover_import_no_retry(imp, NULL);
+
+        if (failed_req->rq_import_generation != imp->imp_generation) {
                 spin_lock_irqsave (&failed_req->rq_lock, flags);
                 failed_req->rq_err = 1;
                 spin_unlock_irqrestore (&failed_req->rq_lock, flags);
         }
+        else {
+                ptlrpc_resend_req(failed_req);
+                if (rc && rc != -EALREADY)
+                        ptlrpc_handle_failed_import(imp);
+                        
+        }
         EXIT;
 }
 
 int ptlrpc_set_import_active(struct obd_import *imp, int active)
 {
-        struct obd_device *notify_obd;
+        struct obd_device *obd = imp->imp_obd;
         unsigned long flags;
-        int rc;
 
-        LASSERT(imp->imp_obd);
-
-        notify_obd = imp->imp_obd->u.cli.cl_containing_lov;
+        LASSERT(obd);
 
         /* When deactivating, mark import invalid, and abort in-flight
          * requests. */
@@ -380,40 +294,10 @@ int ptlrpc_set_import_active(struct obd_import *imp, int active)
                 imp->imp_generation++;
                 spin_unlock_irqrestore(&imp->imp_lock, flags);
                 ptlrpc_invalidate_import_state(imp);
-                //ptlrpc_abort_inflight(imp);
         }
 
-        if (notify_obd == NULL)
-                GOTO(out, rc = 0);
-
-        /* How gross is _this_? */
-        if (!list_empty(&notify_obd->obd_exports)) {
-                struct lustre_handle fakeconn;
-                struct obd_ioctl_data ioc_data = { 0 };
-                struct obd_export *exp =
-                        list_entry(notify_obd->obd_exports.next,
-                                   struct obd_export, exp_obd_chain);
-
-                fakeconn.cookie = exp->exp_handle.h_cookie;
-                ioc_data.ioc_inlbuf1 = (char *)&imp->imp_target_uuid;
-                ioc_data.ioc_offset = active;
-                rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn,
-                                   sizeof ioc_data, &ioc_data, NULL);
-                if (rc)
-                        CERROR("error %sabling %s on LOV %p/%s: %d\n",
-                               active ? "en" : "dis",
-                               imp->imp_target_uuid.uuid, notify_obd,
-                               notify_obd->obd_uuid.uuid, rc);
-        } else {
-                CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about "
-                       "%p\n", notify_obd, notify_obd->obd_uuid.uuid,
-                       imp->imp_obd->obd_uuid.uuid);
-                rc = -ENOENT;
-        }
-
-out:
         /* When activating, mark import valid */
-        if (active && !rc) {
+        if (active) {
                 CDEBUG(D_HA, "setting import %s VALID\n",
                        imp->imp_target_uuid.uuid);
                 spin_lock_irqsave(&imp->imp_lock, flags);
@@ -421,7 +305,10 @@ out:
                 spin_unlock_irqrestore(&imp->imp_lock, flags);
         }
 
-        RETURN(rc);
+        if (obd->obd_observer)
+                RETURN(obd_notify(obd->obd_observer, obd, active));
+
+        RETURN(0);
 }
 
 void ptlrpc_fail_import(struct obd_import *imp, int generation)
@@ -433,10 +320,13 @@ void ptlrpc_fail_import(struct obd_import *imp, int generation)
         LASSERT (!imp->imp_dlm_fake);
 
         spin_lock_irqsave(&imp->imp_lock, flags);
-        if (imp->imp_level != LUSTRE_CONN_FULL)
+        if (imp->imp_state != LUSTRE_IMP_FULL) {
                 in_recovery = 1;
-        else
-                imp->imp_level = LUSTRE_CONN_NOTCONN;
+        } else {
+                CDEBUG(D_HA, "%s: new state: DISCON\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_DISCON;
+        }
         spin_unlock_irqrestore(&imp->imp_lock, flags);
 
         if (in_recovery) {
@@ -459,8 +349,9 @@ static int signal_completed_replay(struct obd_import *imp)
                 RETURN(-ENOMEM);
 
         req->rq_replen = lustre_msg_size(0, NULL);
-        req->rq_level = LUSTRE_CONN_RECOVER;
+        req->rq_send_state = LUSTRE_IMP_REPLAY;
         req->rq_reqmsg->flags |= MSG_LAST_REPLAY;
+        req->rq_timeout *= 3; 
 
         rc = ptlrpc_queue_wait(req);
 
@@ -469,24 +360,61 @@ static int signal_completed_replay(struct obd_import *imp)
 }
 
 int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid)
+{
+        int rc;
+        ENTRY;
+        
+        rc = ptlrpc_recover_import_no_retry(imp, new_uuid);
+
+        if (rc && rc != -EALREADY) {
+                unsigned long flags;
+                CDEBUG(D_HA, "recovery of %s on %s failed (%d); restarting\n",
+                       imp->imp_target_uuid.uuid,
+                       new_uuid ? new_uuid :
+                       (char *)imp->imp_connection->c_remote_uuid.uuid, rc);
+                spin_lock_irqsave(&imp->imp_lock, flags);
+                imp->imp_state = LUSTRE_IMP_FULL;
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                ptlrpc_fail_import(imp, imp->imp_generation);
+        }
+        RETURN(rc);
+}
+
+static int ptlrpc_recover_import_no_retry(struct obd_import *imp,
+                                          char *new_uuid)
 {
         int rc;
         unsigned long flags;
-        int in_recover = 0;
-        int recon_result;
+        int in_recovery = 0;
+        int was_invalid = 0;
         ENTRY;
 
         spin_lock_irqsave(&imp->imp_lock, flags);
-        if (imp->imp_level == LUSTRE_CONN_FULL ||
-            imp->imp_level == LUSTRE_CONN_NOTCONN)
-                    imp->imp_level = LUSTRE_CONN_RECOVER;
-        else
-                in_recover = 1;
+        if (imp->imp_state == LUSTRE_IMP_FULL) {
+                CDEBUG(D_HA, "%s: new state: DISCON\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_DISCON;
+        } 
+        
+        if (imp->imp_state != LUSTRE_IMP_DISCON) {
+                in_recovery = 1;
+        } else if (imp->imp_invalid) {
+                imp->imp_invalid = 0;
+                was_invalid = 1;
+        }
+
         spin_unlock_irqrestore(&imp->imp_lock, flags);
 
-        if (in_recover == 1)
+        if (in_recovery == 1)
                 RETURN(-EALREADY);
 
+        down(&imp->imp_recovery_sem);
+        /* If recovery happened while we waited, we're done. */
+        if (imp->imp_state == LUSTRE_IMP_FULL)
+                GOTO(out, rc = 0);
+
+        LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
+
         if (new_uuid) {
                 struct ptlrpc_connection *conn;
                 struct obd_uuid uuid;
@@ -496,12 +424,12 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid)
                 obd_str2uuid(&uuid, new_uuid);
                 if (ptlrpc_uuid_to_peer(&uuid, &peer)) {
                         CERROR("no connection found for UUID %s\n", new_uuid);
-                        RETURN(-EINVAL);
+                        GOTO(out, rc = -EINVAL);
                 }
 
                 conn = ptlrpc_get_connection(&peer, &uuid);
                 if (!conn)
-                        RETURN(-ENOMEM);
+                        GOTO(out, rc = -ENOMEM);
 
                 CDEBUG(D_HA, "switching import %s/%s from %s to %s\n",
                        imp->imp_target_uuid.uuid, imp->imp_obd->obd_name,
@@ -524,68 +452,86 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid)
 
         }
 
-        recon_result = ptlrpc_reconnect_import(imp);
+ connect:
+        rc = ptlrpc_connect_import(imp);
 
-        if (recon_result < 0) {
+        if (rc < 0) {
                 CERROR("failed to reconnect to %s@%s: %d\n",
                        imp->imp_target_uuid.uuid,
-                       imp->imp_connection->c_remote_uuid.uuid, recon_result);
-                spin_lock_irqsave(&imp->imp_lock, flags);
-                imp->imp_level = LUSTRE_CONN_NOTCONN;
-                spin_unlock_irqrestore(&imp->imp_lock, flags);
-                RETURN(recon_result);
-        }
+                       imp->imp_connection->c_remote_uuid.uuid, rc);
+                GOTO(out, rc);
+        } 
 
-        if (recon_result == RECON_RESULT_RECOVERING) {
+        if (imp->imp_state == LUSTRE_IMP_EVICTED) {
+                CDEBUG(D_HA, "evicted from %s@%s; invalidating\n",
+                       imp->imp_target_uuid.uuid,
+                       imp->imp_connection->c_remote_uuid.uuid);
+                ptlrpc_set_import_active(imp, 0);
+                CDEBUG(D_HA, "%s: new state: RECOVER\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_RECOVER;
+        } 
+        
+        if (imp->imp_state == LUSTRE_IMP_REPLAY) {
                 CDEBUG(D_HA, "replay requested by %s\n",
                        imp->imp_target_uuid.uuid);
                 rc = ptlrpc_replay(imp);
                 if (rc)
                         GOTO(out, rc);
 
-                if (ptlrpc_ldlm_replay_locks == NULL)
-                        CERROR("ptlrpc/ldlm hook is NULL!  Please tell phil\n");
-                else
-                        rc = ptlrpc_ldlm_replay_locks(imp);
+                rc = ldlm_replay_locks(imp);
                 if (rc)
                         GOTO(out, rc);
 
                 rc = signal_completed_replay(imp);
                 if (rc)
                         GOTO(out, rc);
-        } else if (recon_result == RECON_RESULT_RECONNECTED) {
+                CDEBUG(D_HA, "%s: new state: RECOVER\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_RECOVER;
+        } 
+
+        if (imp->imp_state == LUSTRE_IMP_RECOVER) {
                 CDEBUG(D_HA, "reconnected to %s@%s\n",
                        imp->imp_target_uuid.uuid,
                        imp->imp_connection->c_remote_uuid.uuid);
-        } else if (recon_result == RECON_RESULT_EVICTED) {
-                CDEBUG(D_HA, "evicted from %s@%s; invalidating\n",
-                       imp->imp_target_uuid.uuid,
-                       imp->imp_connection->c_remote_uuid.uuid);
-                ptlrpc_set_import_active(imp, 0);
-        } else {
-                LBUG();
-        }
 
-        ptlrpc_set_import_active(imp, 1);
+                ptlrpc_set_import_active(imp, 1);
+                ptlrpc_resend(imp);
+                spin_lock_irqsave(&imp->imp_lock, flags);
+                CDEBUG(D_HA, "%s: new state: FULL\n", 
+                       imp->imp_client->cli_name);
+                imp->imp_state = LUSTRE_IMP_FULL;
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                ptlrpc_wake_delayed(imp);
+        } 
 
-        rc = ptlrpc_resend(imp);
 
-        spin_lock_irqsave(&imp->imp_lock, flags);
-        imp->imp_level = LUSTRE_CONN_FULL;
-        spin_unlock_irqrestore(&imp->imp_lock, flags);
+        LASSERT(imp->imp_state == LUSTRE_IMP_FULL);
 
-        ptlrpc_wake_delayed(imp);
-        EXIT;
-        if (!rc)
-                rc = recon_result;
  out:
-        return rc;
+        if (rc != 0) {
+                spin_lock_irqsave(&imp->imp_lock, flags);
+                imp->imp_state = LUSTRE_IMP_DISCON;
+                spin_unlock_irqrestore(&imp->imp_lock, flags);
+                
+                if (rc == -ENOTCONN) {
+                        CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery;"
+                               "invalidating and reconnecting\n",
+                               imp->imp_target_uuid.uuid,
+                               imp->imp_connection->c_remote_uuid.uuid);
+                        GOTO(connect, -ENOTCONN);
+                } else if (was_invalid) {
+                        ptlrpc_set_import_active(imp, 0);
+                }
+        }
+        up(&imp->imp_recovery_sem);
+        RETURN(rc);
 }
 
 void ptlrpc_fail_export(struct obd_export *exp)
 {
         int rc, already_failed;
-        struct lustre_handle hdl;
         unsigned long flags;
 
         spin_lock_irqsave(&exp->exp_lock, flags);
@@ -601,8 +547,12 @@ void ptlrpc_fail_export(struct obd_export *exp)
 
         CDEBUG(D_HA, "disconnecting export %p/%s\n",
                exp, exp->exp_client_uuid.uuid);
-        hdl.cookie = exp->exp_handle.h_cookie;
-        rc = obd_disconnect(&hdl, 0);
+
+        /* Most callers into obd_disconnect are removing their own reference
+         * (request, for example) in addition to the one from the hash table.
+         * We don't have such a reference here, so make one. */
+        class_export_get(exp);
+        rc = obd_disconnect(exp, 0);
         if (rc)
                 CERROR("disconnecting export %p failed: %d\n", exp, rc);
 }
diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c
index 22ccb093a7688896b5898b8b805abef8b3426944..526b35c62af2bf5530f4fc037b3874f83bf761f5 100644
--- a/lustre/ptlrpc/service.c
+++ b/lustre/ptlrpc/service.c
@@ -37,9 +37,7 @@ static int ptlrpc_check_event(struct ptlrpc_service *svc,
                               struct ptlrpc_thread *thread, ptl_event_t *event)
 {
         struct ptlrpc_srv_ni *srv_ni;
-        int i;
-        int idx;
-        int rc;
+        int i, idx, rc;
         ENTRY;
 
         spin_lock(&svc->srv_lock);
@@ -67,6 +65,11 @@ static int ptlrpc_check_event(struct ptlrpc_service *svc,
                 case PTL_EQ_EMPTY:
                         continue;
 
+                case PTL_EQ_DROPPED:
+                        CWARN("Event queue overflow (bug 2125): timeouts will "
+                              "follow.\n");
+                        continue;
+
                 default:
                         CERROR("BUG: PtlEQGet returned %d\n", rc);
                         LBUG();
@@ -83,7 +86,7 @@ struct ptlrpc_service * ptlrpc_init_svc(__u32 nevents, __u32 nbufs,
                                         __u32 bufsize, __u32 max_req_size,
                                         int req_portal, int rep_portal,
                                         svc_handler_t handler, char *name,
-                                        struct obd_device *obddev)
+                                        struct proc_dir_entry *proc_entry)
 {
         int i, j, ssize, rc;
         struct ptlrpc_service *service;
@@ -141,7 +144,7 @@ struct ptlrpc_service * ptlrpc_init_svc(__u32 nevents, __u32 nbufs,
                 for (j = 0; j < nbufs; j++) {
                         struct ptlrpc_request_buffer_desc *rqbd;
 
-                        OBD_ALLOC(rqbd, sizeof(*rqbd));
+                        OBD_ALLOC_WAIT(rqbd, sizeof(*rqbd));
                         if (rqbd == NULL) {
                                 CERROR ("%s.%d: Can't allocate request "
                                         "descriptor %d on %s\n",
@@ -154,7 +157,7 @@ struct ptlrpc_service * ptlrpc_init_svc(__u32 nevents, __u32 nbufs,
                         rqbd->rqbd_me_h = PTL_HANDLE_NONE;
                         atomic_set(&rqbd->rqbd_refcount, 0);
 
-                        OBD_ALLOC(rqbd->rqbd_buffer, service->srv_buf_size);
+                        OBD_ALLOC_WAIT(rqbd->rqbd_buffer, service->srv_buf_size);
                         if (rqbd->rqbd_buffer == NULL) {
                                 CERROR ("%s.%d: Can't allocate request "
                                         "buffer %d on %s\n",
@@ -170,7 +173,8 @@ struct ptlrpc_service * ptlrpc_init_svc(__u32 nevents, __u32 nbufs,
                 }
         }
 
-        ptlrpc_lprocfs_register_service(obddev, service);
+        if (proc_entry != NULL)
+                ptlrpc_lprocfs_register_service(proc_entry, service);
 
         CDEBUG(D_NET, "%s: Started on %d interfaces, listening on portal %d\n",
                service->srv_name, ptlrpc_ninterfaces, service->srv_req_portal);
@@ -236,6 +240,15 @@ static int handle_incoming_request(struct obd_device *obddev,
         if (request->rq_export) {
                 request->rq_connection = request->rq_export->exp_connection;
                 ptlrpc_connection_addref(request->rq_connection);
+                if (request->rq_reqmsg->conn_cnt < 
+                    request->rq_export->exp_conn_cnt) {
+                        DEBUG_REQ(D_ERROR, request,
+                                  "DROPPING req from old connection %d < %d",
+                                  request->rq_reqmsg->conn_cnt,
+                                  request->rq_export->exp_conn_cnt);
+                        goto put_conn;
+                }
+
                 request->rq_export->exp_last_request_time =
                         LTIME_S(CURRENT_TIME);
         } else {
@@ -246,25 +259,28 @@ static int handle_incoming_request(struct obd_device *obddev,
                         ptlrpc_get_connection(&request->rq_peer, NULL);
         }
 
-        CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid:pid:xid:ni:nid:opc %s:%s:%d:"
-               LPU64":%s:"LPX64":%d\n",
-               current->comm,
-               (request->rq_export ? 
-                (char *)request->rq_export->exp_client_uuid.uuid : "0"), 
+        CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:ni:nid:opc "
+               "%s:%s+%d:%d:"LPU64":%s:"LPX64":%d\n", current->comm,
+               (request->rq_export ?
+                (char *)request->rq_export->exp_client_uuid.uuid : "0"),
+               (request->rq_export ?
+                atomic_read(&request->rq_export->exp_refcount) : -99),
                request->rq_reqmsg->status, request->rq_xid,
                rqbd->rqbd_srv_ni->sni_ni->pni_name, event->initiator.nid,
                request->rq_reqmsg->opc);
 
         rc = svc->srv_handler(request);
-        CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid:pid:xid:ni:nid:opc %s:%s:%d:"
-               LPU64":%s:"LPX64":%d\n",
-               current->comm,
-               (request->rq_export ? 
+        CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:ni:nid:opc "
+               "%s:%s+%d:%d:"LPU64":%s:"LPX64":%d\n", current->comm,
+               (request->rq_export ?
                 (char *)request->rq_export->exp_client_uuid.uuid : "0"),
+               (request->rq_export ?
+                atomic_read(&request->rq_export->exp_refcount) : -99),
                request->rq_reqmsg->status, request->rq_xid,
                rqbd->rqbd_srv_ni->sni_ni->pni_name, event->initiator.nid,
                request->rq_reqmsg->opc);
 
+put_conn:
         ptlrpc_put_connection(request->rq_connection);
         if (request->rq_export != NULL)
                 class_export_put(request->rq_export);
@@ -280,11 +296,7 @@ static int handle_incoming_request(struct obd_device *obddev,
 void ptlrpc_daemonize(void)
 {
         exit_mm(current);
-
-        current->session = 1;
-        current->pgrp = 1;
-        current->tty = NULL;
-
+        lustre_daemonize_helper();
         exit_files(current);
         reparent_to_init();
 }
@@ -337,8 +349,9 @@ static int ptlrpc_main(void *arg)
         /* And now, loop forever on requests */
         while (1) {
                 struct l_wait_info lwi = { 0 };
-                l_wait_event(svc->srv_waitq,
-                             ptlrpc_check_event(svc, thread, event), &lwi);
+                l_wait_event_exclusive(svc->srv_waitq,
+                                       ptlrpc_check_event(svc, thread, event),
+                                       &lwi);
 
                 spin_lock(&svc->srv_lock);
                 if (thread->t_flags & SVC_STOPPING) {
@@ -428,7 +441,7 @@ static void ptlrpc_stop_thread(struct ptlrpc_service *svc,
         thread->t_flags = SVC_STOPPING;
         spin_unlock(&svc->srv_lock);
 
-        wake_up(&svc->srv_waitq);
+        wake_up_all(&svc->srv_waitq);
         l_wait_event(thread->t_ctl_waitq, (thread->t_flags & SVC_STOPPED),
                      &lwi);
 }
@@ -449,6 +462,25 @@ void ptlrpc_stop_all_threads(struct ptlrpc_service *svc)
         spin_unlock(&svc->srv_lock);
 }
 
+int ptlrpc_start_n_threads(struct obd_device *dev, struct ptlrpc_service *svc,
+                           int num_threads, char *base_name)
+{
+        int i, rc = 0;
+        ENTRY;
+
+        for (i = 0; i < num_threads; i++) {
+                char name[32];
+                sprintf(name, "%s_%02d", base_name, i);
+                rc = ptlrpc_start_thread(dev, svc, name);
+                if (rc) {
+                        CERROR("cannot start %s thread #%d: rc %d\n", base_name,
+                               i, rc);
+                        ptlrpc_stop_all_threads(svc);
+                }
+        }
+        RETURN(rc);
+}
+
 int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc,
                         char *name)
 {
diff --git a/lustre/scripts/Makefile.am b/lustre/scripts/Makefile.am
index 199f5bebc97c1a31b94ed8a7af882fe6200e25f4..a1c8feadfdd58804609eecf4c30741dc1eae527d 100644
--- a/lustre/scripts/Makefile.am
+++ b/lustre/scripts/Makefile.am
@@ -6,5 +6,6 @@
 EXTRA_DIST = license-status maketags.sh lustre.spec version_tag.pl $(initd_SCRIPTS)
 initddir = $(sysconfdir)/init.d
 initd_SCRIPTS = lustre
+
 include $(top_srcdir)/Rules
 
diff --git a/lustre/scripts/lbuild b/lustre/scripts/lbuild
new file mode 100755
index 0000000000000000000000000000000000000000..327ae91c11f97f15e22a780065934f80c459c17a
--- /dev/null
+++ b/lustre/scripts/lbuild
@@ -0,0 +1,437 @@
+#!/bin/sh
+
+TOPDIR=$PWD
+
+# CVSROOT is inherited from the environment
+KERNELDIR=
+LUSTRE=
+PUBLISH=0
+RELEASE=0
+DO_SRC=1
+TAG=
+TARGET=
+TARGET_ARCHS=
+CONFIGURE_FLAGS=
+EXTRA_VERSION=
+
+# from target file
+KERNEL=
+SERIES=
+CONFIG=
+VERSION=
+
+BASE_ARCH=
+BIGMEM_ARCHS=
+BOOT_ARCHS=
+JENSEN_ARCHS=
+SMP_ARCHS=
+UP_ARCHS=
+
+DATE=$(date)
+
+cleanup()
+{
+    true
+}
+
+fatal()
+{
+    cleanup
+    [ "$2" ] && echo
+    [ "$2" ] && echo "${0##*/}: $2"
+    exit $1
+}
+
+publishing()
+{
+    (( $PUBLISH )) || return 0
+}
+
+is_release()
+{
+    (( $RELEASE )) || return 0
+}
+
+list_targets()
+{
+    echo -n "Available targets:"
+    for target in $TOPDIR/lustre/kernel_patches/targets/*.target ; do
+	target_file=${target##*/}
+	echo -n " ${target_file%%.target}"
+    done
+    echo
+}
+
+usage()
+{
+    cat <<EOF
+Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
+
+  -d CVSROOT
+    Specifies the CVS Root to use when pulling files from CVS.  The
+    environment variable \$CVSROOT is used if this option is not
+    present.
+
+  --extraversion=EXTRAVERSION
+    Text to use for the rpm release and kernel extraversion.
+
+  --kerneldir=KERNELDIR
+    Directory containing Linux source tarballs referenced by target
+    files.
+
+  --lustre=LUSTRE
+    Path to an existing lustre source tarball to use instead of
+    pulling from CVS.
+
+  --nosrc
+    Do not build a .src.rpm, a full kernel patch, or a patched kernel
+    tarball.
+
+  --publish
+    Publish the packages, patches, and tarballs on the ftp server.
+
+  --release
+    Specifies that the files generated do not include timestamps, and
+    that this is an official release.
+
+  --tag=TAG
+    A CVS branch/tag name to build from when pulling from CVS.
+
+  --target=TARGET
+    The name of the target to build.  The available targets are listed
+    below.
+
+  --target-archs=TARGET_ARCHS
+    A (space delimited) list of architectures to build.  By default,
+    all of the archs supported by the TARGET will be built, in
+    addition to a .src.rpm.  This option can limit those, for machines
+    that can only build certain archs or if you only want a certain
+    arch built (for testing, or a one-off kernel).
+
+    Also note that by using a non-"base" arch (eg, i386) only kernels
+    will be built - there will be no lustre-lite-utils package.
+
+EOF
+
+#   list_targets
+
+    fatal "$1" "$2"
+}
+
+check_options()
+{
+    if [ "$LUSTRE" ] ; then
+	[ -r "$LUSTRE" ] || \
+	    usage 1 "Could not find Lustre source tarball '$LUSTRE'."
+    else
+	[ "$CVSROOT" ] || \
+	    usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
+	[ "$TAG" ] || \
+	    usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
+    fi
+
+    [ "$KERNELDIR" ] || \
+	usage 1 "A kernel directory must be specified with --kerneldir."
+
+    [ -d "$KERNELDIR" ] || \
+	usage 1 "$KERNELDIR is not a directory."
+
+    if [ "$RELEASE" = "no" ] ; then
+	[ "$TAG" ] || \
+	    usage 1 "When building a snapshot, a tag name must be used."
+    fi
+
+    TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M")
+
+    [ "$TARGET" ] || usage 1 "A target must be specified with --target."
+#    TARGET_FILE="$TOPDIR/kernel_patches/targets/$TARGET.target"
+#    [ -r "$TARGET_FILE" ] || \
+#	usage 1 "Target '$TARGET' was not found."
+}
+
+uniqify()
+{
+    echo $(echo "$*" | xargs -n 1 | sort -u)
+}
+
+load_target()
+{
+    EXTRA_VERSION_save="$EXTRA_VERSION"
+    TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
+    [ -r "$TARGET_FILE" ] || \
+	fatal 1 "Target $TARGET was not found."
+
+    echo "Loading target config file $TARGET.target..."	
+
+    . "$TARGET_FILE"
+
+    [ "$KERNEL"  ] || fatal 1 "Target $TARGET did not specify a kernel."
+    [ "$SERIES"  ] || fatal 1 "Target $TARGET did not specify a kernel patch series."
+#    [ "$CONFIG"  ] || fatal 1 "Target $TARGET did not specify a kernel config."
+    [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify a kernel version."
+
+    if [ "$KERNELDIR" ] ; then
+	KERNEL_FILE="$KERNELDIR/$KERNEL"
+	[ -r "$KERNELDIR/$KERNEL" ] || \
+	    fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
+    fi
+
+    SERIES_FILE="$TOPDIR/lustre/kernel_patches/series/$SERIES"
+    [ -r "$SERIES_FILE" ] || \
+	fatal 1 "Target $TARGET's series $SERIES missing from $TOPDIR/lustre/kernel_patches/series."
+
+    CONFIG_FILE="$TOPDIR/lustre/kernel_patches/kernel_configs/$CONFIG"
+    [ -r "$CONFIG_FILE" ] || \
+	fatal 1 "Target $TARGET's config file $CONFIG missing from $TOPDIR/lustre/kernel_patches/kernel_configs/configs."
+
+    if [ "$EXTRA_VERSION_save" ] ; then
+	EXTRA_VERSION="$EXTRA_VERSION_save"
+    else
+	EXTRA_VERSION="${EXTRA_VERSION}_${TAG//_/}.${TIMESTAMP}"
+    fi
+    EXTRA_VERSION=${EXTRA_VERSION//-/_/}
+
+    ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $UP_ARCHS"
+
+    BUILD_ARCHS=
+    for arch in $(uniqify "$ALL_ARCHS") ; do
+	if [ -z "$TARGET_ARCHS" ] || echo "$TARGET_ARCHS" | grep -s "$arch" ; then
+	    BUILD_ARCHS="$BUILD_ARCHS $arch"
+	fi
+    done
+    [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
+    echo "Building for: $BUILD_ARCHS"
+}
+
+tarflags()
+{
+    case "$1" in
+	'')
+	    fatal 1 "tarflags(): File name argument missing."
+	    ;;
+	*.tar.gz)
+	    echo 'zxf'
+	    ;;
+	*.tar.bz2)
+	    echo 'jxf'
+	    ;;
+	*)
+	    fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
+	    ;;
+    esac
+}
+
+untar()
+{
+    echo "Untarring ${1##*/}..."
+    tar $(tarflags "$1") "$1"
+}
+
+unpack_lustre()
+{
+    DIRNAME="lustre-$TAG-$TIMESTAMP"
+    if [ "$LUSTRE" ] ; then
+	untar "$LUSTRE"
+	[ -d lustre ] || ln -sf lustre* lustre
+    else
+	cvs -d "$CVSROOT" -qz3 co -D "$DATE" "-r$TAG" -d "$DIRNAME" lustre || \
+	    fatal 1 "There was an error checking out Lustre from CVS."
+	echo "Creating lustre tarball..."
+	tar zcf "$DIRNAME.tar.gz" "$DIRNAME" \
+	    --exclude "CVS" --exclude "*~" --exclude ".cvsignore" || \
+	    fatal 1 "Could not create Lustre tarball."
+	LUSTRE="$PWD/$DIRNAME.tar.gz"
+	ln -sf "$DIRNAME" lustre
+    fi
+}
+
+unpack_linux()
+{
+    untar "$KERNEL_FILE"
+    [ -d linux ] || ln -sf linux* linux
+}
+
+patch_linux()
+{
+    FULL_PATCH="$PWD/lustre-kernel-${target}-${EXTRA_VERSION}.patch"
+    [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
+    pushd linux >/dev/null
+    echo -n "Applying patches:"
+    for patch in $(<"$SERIES_FILE") ; do
+	echo -n " $patch"
+	PATCH_FILE="$TOPDIR/lustre/kernel_patches/patches/$patch"
+	[ -r "$PATCH_FILE" ] || \
+	    fatal 1 "Patch $patch does not exist in Lustre tree."
+	cat "$PATCH_FILE" >> "$FULL_PATCH" || \
+	    fatal 1 "Error adding patch $patch to full patch."
+	patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
+    done
+    echo
+    popd >/dev/null
+    echo "Full patch has been saved in ${FULL_PATCH##*/}."
+    echo "Replacing .config files..."
+    rm -f linux/configs/*
+    cp -v lustre/kernel_patches/kernel_configs/kernel-${VERSION}-${TARGET}*.config linux/configs/
+}
+
+pack_linux()
+{
+    TARBALL="$(readlink linux)-$EXTRA_VERSION.tar.gz"
+    echo "Creating patched linux tarball $TARBALL..."
+    tar zcf "$TARBALL" "$(readlink linux)" \
+	--exclude "CVS" --exclude ".cvsignore" || \
+	--exclude "*.orig" --exclude "*~" --exclude "*.rej" || \
+	fatal 1 "Error creating patched Linux tarball."
+}
+
+clean_linux()
+{
+    [ -d linux ] || return 0
+    echo "Cleaning linux..."
+    [ -L linux ] && rm -rf $(readlink linux)
+    rm -rf linux
+}
+
+prep_build()
+{
+    # make .spec file
+    sed -e s/@KERNEL_VERSION@/$VERSION/g \
+	-e s/@KERNEL_RELEASE@/$EXTRA_VERSION/g \
+	-e s/@KERNEL_SOURCE@/$KERNEL/g \
+	-e s/@LUSTRE_SOURCE@/${LUSTRE##*/}/g \
+	-e s/@LUSTRE_TARGET@/$TARGET/g \
+	-e s/@CONFIGURE_FLAGS@/$CONFIGURE_FLAGS/g \
+	-e s/@BASE_ARCHS@/$BASE_ARCHS/g \
+	-e s/@BIGMEM_ARCHS@/$BIGMEM_ARCHS/g \
+	-e s/@BOOT_ARCHS@/$BOOT_ARCHS/g \
+	-e s/@JENSEN_ARCHS@/$BOOT_ARCHS/g \
+	-e s/@SMP_ARCHS@/$SMP_ARCHS/g \
+	-e s/@UP_ARCHS@/$UP_ARCHS/g \
+	< $TOPDIR/lustre/scripts/lustre-kernel-2.4.spec.in \
+	> lustre-kernel-2.4.spec
+    [ -d SRPMS ] || mkdir SRPMS
+    [ -d RPMS ] || mkdir RPMS
+    [ -d BUILD ] || mkdir BUILD
+    [ -d SOURCES ] || mkdir SOURCES
+    cp $TOPDIR/lustre/scripts/linux-merge-config.awk SOURCES
+    cp $TOPDIR/lustre/scripts/linux-merge-modules.awk SOURCES
+    cp "$LUSTRE" "$KERNEL_FILE" SOURCES
+}
+
+clean_lustre()
+{
+    [ -d lustre ] || return 0
+    echo "Cleaning lustre..."
+    [ -L lustre ] && rm -rf $(readlink lustre)
+    rm -rf lustre
+}
+
+build()
+{
+    echo "Building rpms for: $BUILD_ARCHS..."
+    targets=
+    for arch in $BUILD_ARCHS ; do
+	targets="--target $arch $targets"
+    done
+
+    rpmbuild $targets -bb lustre-kernel-2.4.spec \
+	--define "_topdir $TOPDIR" \
+	fatal 1 "Error building rpms for $arch."
+
+    (( $DO_SRC )) && rpmbuild -bs lustre-kernel-2.4.spec \
+	--define "_topdir $TOPDIR" \
+	fatal 1 "Error building .src.rpm."
+}
+
+publish()
+{
+    publishing || return 0
+}
+
+[ -r ~/.lbuildrc ] && . ~/.lbuildrc
+
+options=$(getopt -o d:D:h -l extraversion:,kerneldir:,lustre:,nosrc,publish,release,tag:,target:,target-archs: -- "$@")
+
+eval set -- "$options"
+    
+while [ "$1" ] ; do
+    case "$1" in
+	'')
+	    usage 1
+	    ;;
+	-d)
+	    CVSROOT=$2
+	    shift 2
+	    ;;
+	-D)
+	    DATE=$2
+	    shift 2
+	    ;;
+	--extraversion)
+	    EXTRA_VERSION=$2
+	    shift 2
+	    ;;
+	--help | -h)
+	    usage 0
+	    ;;
+	--kerneldir)
+	    KERNELDIR=$2
+	    shift 2
+	    ;;
+	--lustre)
+	    LUSTRE=$2
+	    shift 2
+	    ;;
+	--nosrc)
+	    DO_SRC=0
+	    shift 1
+	    ;;
+	--publish)
+	    PUBLISH=1
+	    shift
+	    ;;
+	--release)
+	    RELEASE=1
+	    shift
+	    ;;
+	--tag)
+	    TAG=$2
+	    shift 2
+	    ;;
+	--target)
+	    TARGET=$2
+	    shift 2
+	    ;;
+	--target-archs)
+	    TARGET_ARCHS=$2
+	    shift 2
+	    ;;
+	--)
+	    shift
+	    CONFIGURE_FLAGS=$@
+	    break
+	    ;; 
+	*)
+	    usage 1 "Unrecognized option: $1"
+	    ;;
+    esac
+done
+
+check_options
+
+unpack_lustre
+load_target
+
+if (( $DO_SRC )) ; then
+    unpack_linux
+    patch_linux
+    pack_linux
+    clean_linux
+fi
+
+# prep_build needs the .spec.in from the lustre source
+prep_build
+clean_lustre
+
+build
+publish
diff --git a/lustre/scripts/linux-merge-config.awk b/lustre/scripts/linux-merge-config.awk
new file mode 100644
index 0000000000000000000000000000000000000000..9a9338cc542ecbd34aae26f042eca9c8bb59b428
--- /dev/null
+++ b/lustre/scripts/linux-merge-config.awk
@@ -0,0 +1,317 @@
+#!/bin/awk -f
+BEGIN {
+	nsects = 0
+}
+{
+	ARCH = $1
+	ARCHES[ARCH] = 1
+	TYPE = $2
+	TYPES[TYPE] = 1
+	NTOTAL++
+	ARCHTYPES[ARCH ":" TYPE] = 1
+	NARCHES[TYPE]++
+	if (NARCHES[TYPE] == 1)
+	    NTOTALTYPES++
+	NTYPES[ARCH]++
+	if (NTYPES[ARCH] == 1)
+	    NTOTALARCHES++
+	FILE = $3
+	cursects = nsects
+	while ((getline < FILE) > 0) {
+		if ($0 ~ /^\/\*/ || $0 ~ /^ \*\// || $0 ~ /^[ 	]*$/)
+			continue
+		if ($0 ~ /^ * /) {
+			SECTION = gensub(/^ \* /,"",$0)
+			if (!(SECTION in sectno)) {
+				sectno[SECTION] = nsects
+				counts[SECTION] = 0
+				nsects++
+			} else if (cursects && cursects != nsects) {
+				no = sectno[SECTION]
+				diff = nsects - cursects
+				for (s in sectno) {
+					if (sectno[s] >= cursects)
+						sectno[s] = sectno[s] - cursects + no
+					else if (sectno[s] >= no)
+						sectno[s] += diff
+				}
+			}
+			cursects = nsect
+			cursym[SECTION] = counts[SECTION]
+			continue
+		}
+		if ($1 != "#define" && $1 != "#undef")
+			exit 1
+		SYMBOL = $2
+		n = index($0,SYMBOL)+length(SYMBOL)
+		if ($1 == "#define") {
+			n = index($0,SYMBOL)+length(SYMBOL)
+			VALUE = gensub(/^[ 	]*/,"","",substr($0,n))
+			if (VALUE == "") VALUE = "__novalue__"
+		} else
+			VALUE = "__undefined__"
+		if (values[SYMBOL]) {
+			if (present[SYMBOL,ARCH,TYPE]) continue
+			present[SYMBOL,ARCH,TYPE] = 1
+			values[SYMBOL] = values[SYMBOL] SUBSEP ARCH ":" TYPE ":" VALUE
+			if (SECTION == sections[SYMBOL] && cursym[SECTION] && cursym[SECTION] != counts[SECTION]) {
+				no = pos[SYMBOL]
+				diff = counts[SECTION]-cursym[SECTION]
+				for (s in pos)
+					if (sections[s] == SECTION) {
+						if (pos[s] >= cursym[SECTION])
+							pos[s] = pos[s] - cursym[SECTION] + no
+						else if (pos[s] >= no)
+							pos[s] += diff
+					}
+				cursym[SECTION] = counts[SECTION]
+			}
+		} else {
+			present[SYMBOL,ARCH,TYPE] = 1
+			values[SYMBOL] = ARCH ":" TYPE ":" VALUE
+			sections[SYMBOL] = SECTION
+			pos[SYMBOL] = counts[SECTION]
+			counts[SECTION]++
+		}
+	}
+	close(FILE)
+}
+END {
+	for (SECTION in sectno)
+		x[sectno[SECTION]] = SECTION
+	for (i = 0; i < nsects; i++) {
+		SECTION = x[i]
+		if (i > 0)
+			printf "\n"
+		printf "/*\n * %s\n */\n", SECTION
+		split("",lines)
+		lastelse = ""
+		for (SYMBOL in sections)
+			if (sections[SYMBOL] == SECTION)
+				y[pos[SYMBOL]] = SYMBOL
+		for (j = 0; j < counts[SECTION]; j++) {
+			SYMBOL = y[j]
+			split("",ntype)
+			split("",total)
+			split(values[SYMBOL],z,SUBSEP)
+			split("",val)
+			totalsum = 0
+			for (k in z) {
+				split(z[k],l,":")
+				ARCH = l[1]
+				TYPE = l[2]
+				VALUE = substr(z[k],length(ARCH)+length(TYPE)+3)
+				if (val[VALUE])
+					val[VALUE] = val[VALUE] " "
+				val[VALUE] = val[VALUE] ARCH ":" TYPE
+				ntype[VALUE,TYPE] += 1
+				total[VALUE] += 1
+				totalsum += 1
+			}
+			split("",curlines)
+			append = 1
+			for (VALUE in val) {
+			    if (total[VALUE] == NTOTAL) {
+				if (VALUE == "__undefined__")
+				    curlines["1"] = "#undef  " SYMBOL "\n"
+				else if (VALUE == "__novalue__")
+				    curlines["1"] = "#define " SYMBOL "\n"
+				else
+				    curlines["1"] = "#define " SYMBOL " " VALUE "\n"
+				if (!lines["1"])
+				    append = 0
+				break
+			    }
+			    shorteststr = ""
+			    curcount = 0
+			    for (m = 0; m < 4; m++) {
+				str = ""
+				split(val[VALUE],yy)
+				if (total[VALUE] > 1 && total[VALUE] == NTOTAL - 1) {
+				    found = 0
+				    for (arch in ARCHES) {
+					for (type in TYPES) {
+					    archtype = arch ":" type
+					    if (ARCHTYPES [archtype] == 1) {
+						for (n in yy)
+						    if (yy[n] == archtype)
+							break
+						if (yy[n] != archtype) {
+						    found = 1
+						    break
+						}
+					    }
+					}
+					if (found)
+					    break
+				    }
+				    if (NARCHES[type] > 1 && NTYPES[arch] > 1) {
+					str = "!defined(__module__" arch "_" type ")"
+					shorteststr = str
+					break
+				    }
+				}
+				if (m == 0 || m == 2) {
+				    nfull = 0
+				    split("",yysave)
+				    for (type in TYPES)
+					if (ntype[VALUE,type] == NARCHES[type]) {
+					    if (str) str = str " || "
+					    str = str "defined(__module__" type ")"
+					    for (k in yy) {
+						split(yy[k], z, ":")
+						if (z[2] == type) {
+						    yysave[k] = yy[k]
+						    delete yy[k]
+						}
+					    }
+					    nfull++
+					} else
+					    NOTYPE = type
+				    if (m < 2 && nfull > 1 && nfull == NTOTALTYPES - 1) {
+					str = "!defined(__module__" NOTYPE ")"
+					for (k in yysave)
+					    yy[k] = yysave[k]
+					for (k in yy) {
+					    split(yy[k], z, ":")
+					    if (z[2] != NOTYPE)
+						delete yy[k]
+					}
+				    }
+				}
+				savestr = str
+				nfull = 0
+				split("",yysave)
+				for (arch in ARCHES) {
+				    narch = 0
+				    for (k in yy) {
+					split(yy[k], z, ":")
+					if (z[1] == arch)
+					    narch++
+				    }
+				    if (narch == NTYPES[arch]) {
+					if (str) str = str " || "
+					str = str "defined(__module__" arch ")"
+					for (k in yy) {
+					    split(yy[k], z, ":")
+					    if (z[1] == arch) {
+						yysave[k] = yy[k]
+						delete yy[k]
+					    }
+					}
+					nfull++
+				    } else
+					NOARCH = arch
+				}
+				if (m < 2 && nfull > 1 && nfull == NTOTALARCHES - 1) {
+				    str = savestr
+				    for (k in yysave)
+					yy[k] = yysave[k]
+				    if (str) str = str " || "
+				    str = str "!defined(__module__" NOARCH ")"
+				    for (k in yy) {
+					split(yy[k], z, ":")
+					if (z[1] != NOARCH)
+					    delete yy[k]
+				    }
+				}
+				if (m == 1 || m == 3) {
+				    savestr = str
+				    nfull = 0
+				    split("",yysave)
+				    for (type in TYPES) {
+					ntypex = 0
+					for (k in yy) {
+					    split(yy[k], z, ":")
+					    if (z[2] == type)
+						ntypex++
+					}
+					if (ntypex == NARCHES[type]) {
+					    if (str) str = str " || "
+					    str = str "defined(__module__" type ")"
+					    for (k in yy) {
+						split(yy[k], z, ":")
+						if (z[2] == type) {
+						    yysave[k] = yy[k]
+						    delete yy[k]
+						}
+					    }
+					    nfull++
+					} else
+					    NOTYPE = type
+				    }
+				    if (m < 2 && nfull > 1 && nfull == NTOTALTYPES - 1) {
+					str = savestr
+				 	for (k in yysave)
+					    yy[k] = yysave[k]
+					if (str) str = str " || "
+					str = "!defined(__module__" NOTYPE ")"
+					for (k in yy) {
+					    split(yy[k], z, ":")
+					    if (z[2] != NOTYPE)
+						delete yy[k]
+					}
+				    }
+				}
+				for (k in yy) {
+				    split(yy[k], z, ":")
+				    if (str) str = str " || "
+				    str = str "defined(__module__" z[1] "_" z[2] ")"
+				}
+				if (m == 0 || length(str) < length(shorteststr))
+				    shorteststr = str
+			    }
+			    str = shorteststr
+			    if (VALUE == "__undefined__")
+				curlines[str] = "#undef  " SYMBOL "\n"
+			    else if (VALUE == "__novalue__")
+				curlines[str] = "#define " SYMBOL "\n"
+			    else
+				curlines[str] = "#define " SYMBOL " " VALUE "\n"
+			    if (!lines[str])
+				append = 0
+			}
+			if (append) {
+			    for (str in curlines)
+				if (curlines[str])
+				    lines[str] = lines[str] curlines[str]
+			} else {
+			    if (lines["1"])
+				printf "%s", lines["1"]
+			    else if (j > 0) {
+				ifstr = "#if "
+				for (str in lines)
+				    if (lines[str] && str != lastelse) {
+					printf "%s %s\n%s", ifstr, str, lines[str]
+					ifstr = "#elif "
+				    }
+				if (lastelse != "")
+				    printf "#else\n%s", lines[lastelse]
+				printf "#endif\n"
+			    }
+			    split("",lines)
+			    lastelse = ""
+			    for (str in curlines)
+				if (curlines[str]) {
+				    lines[str] = curlines[str]
+				    if (totalsum == NTOTAL && length(str) > length(lastelse)) {
+					lastelse = str
+				    }
+				}
+			}
+		}
+		if (lines["1"])
+		    printf "%s", lines["1"]
+		else if (j > 0) {
+		    ifstr = "#if "
+		    for (str in lines)
+			if (lines[str] && str != lastelse) {
+			    printf "%s %s\n%s", ifstr, str, lines[str]
+			    ifstr = "#elif "
+			}
+		    if (lastelse != "")
+			printf "#else\n%s", lines[lastelse]
+		    printf "#endif\n"
+		}
+	}
+}
diff --git a/lustre/scripts/linux-merge-modules.awk b/lustre/scripts/linux-merge-modules.awk
new file mode 100644
index 0000000000000000000000000000000000000000..babc81583969e2ab2679acf47aaab627703bb35d
--- /dev/null
+++ b/lustre/scripts/linux-merge-modules.awk
@@ -0,0 +1,125 @@
+#!/bin/awk -f
+{
+	# lines in input look like ARCH TYPE path/to/TYPE/ARCH/modules/foo.ver
+	ARCH=$1
+	ARCHES[ARCH]=1
+	TYPE=$2
+	TYPES[TYPE]=1
+	NTOTAL++
+	NARCHES[TYPE]++
+	NTYPES[ARCH]++
+	FILE=$3
+
+	# read files that look like pairs of repeating
+	# #define __ver_foo hexstring
+	# #define foo _set_ver(foo)
+	while ((getline < FILE) > 0) {
+		if ($0 ~ /^[ 	]*$/)
+			continue
+		if ($1 != "#define" || $2 !~ /^__ver_/)
+			exit 1
+
+		# this is a "#define __ver_foo somehex" line
+		SYMBOL=gensub(/^__ver_/,"","",$2)
+		VALUE=gensub(/^(smp_|2gig_|smp2gig_)/,"","",$3)
+		VALUE=gensub(/^(smp|2gig|smp2gig)/,"","",VALUE)
+		values[SYMBOL,ARCH,TYPE]=VALUE
+
+		# skip the "#define foo _set_ver(foo)" line
+		if ((getline < FILE) <= 0)
+			exit 2
+		if ($1 != "#define" || $2 != SYMBOL || $3 != "_set_ver(" SYMBOL ")")
+			exit 3
+	}
+	close(FILE)
+}
+END {
+	count=0
+	for (key in values)
+		if (values[key]) {
+			count++
+			split(key,x,SUBSEP)
+			SYMBOL=x[1]
+			ARCH=x[2]
+			TYPE=x[3]
+
+			# (re)initialize a few arrays to have no elements
+			split("",x)
+			split("",ntype)
+			split("",total)
+
+			totalsum=0
+			for (arch in ARCHES)
+			    for (type in TYPES)
+				if (values[SYMBOL,arch,type]) {
+				    VALUE = values[SYMBOL,arch,type]
+				    values[SYMBOL,arch,type] = ""
+				    ntype[VALUE,type] += 1
+				    total[VALUE] += 1
+				    if (x[VALUE])
+					x[VALUE] = x[VALUE] " "
+				    x[VALUE] = x[VALUE] arch ":" type
+				}
+			ifstr="#if "
+			for (VALUE in x) {
+			    if (total[VALUE] == NTOTAL) {
+				# there is only one checksum for this symbol
+				printf "#define __ver_%s\t_ver_str(%s)\n", SYMBOL, VALUE
+				printf "#define %s _set_ver(%s)\n", SYMBOL, SYMBOL
+				break
+			    }
+
+			    totalsum += total[VALUE]
+			    if (totalsum == NTOTAL && ifstr == "#elif") {
+				# this is the last unique checksum for this symbol
+				printf "#else\n#define __ver_%s\t_ver_str(%s)\n", SYMBOL, VALUE
+				printf "#define %s _set_ver(%s)\n", SYMBOL, SYMBOL
+				break
+			    }
+
+			    # there must be more than one checksum still to
+			    # print for this symbol
+			    str=""
+			    split(x[VALUE],y)
+			    for (type in TYPES)
+				if (ntype[VALUE,type] == NARCHES[type]) {
+				    if (str) str = str " || "
+				    str = str "defined(__module__" type ")"
+				    for (k in y) {
+					split(y[k], z, ":")
+					if (z[2] == type)
+					    delete y[k]
+				    }
+				}
+			    for (arch in ARCHES) {
+				narch=0
+				for (k in y) {
+				    split(y[k], z, ":")
+				    if (z[1] == arch)
+					narch++
+				}
+				if (narch == NTYPES[arch]) {
+				    if (str) str = str " || "
+				    str = str "defined(__module__" arch ")"
+				    for (k in y) {
+					split(y[k], z, ":")
+					if (z[1] == arch)
+					    delete y[k]
+				    }
+				}
+			    }
+			    for (k in y) {
+				split(y[k], z, ":")
+				if (str) str = str " || "
+				str = str "defined(__module__" z[1] "_" z[2] ")"
+			    }
+			    printf "%s %s\n#define __ver_%s\t_ver_str(%s)\n", ifstr, str, SYMBOL, VALUE
+			    printf "#define %s _set_ver(%s)\n", SYMBOL, SYMBOL
+			    ifstr="#elif "
+			}
+			if (ifstr == "#elif ")
+			    printf "#endif\n"
+		}
+	if (!count)
+		printf "\n"
+}
diff --git a/lustre/scripts/lmake b/lustre/scripts/lmake
new file mode 100755
index 0000000000000000000000000000000000000000..addbe4f5dfb2d4495f2613f08838a529490d6314
--- /dev/null
+++ b/lustre/scripts/lmake
@@ -0,0 +1,542 @@
+#!/bin/sh
+
+# option variables
+DESTDIR=
+KERNELDIR=
+TARGET=
+# Not sure what to put here
+# TARGET_ARCH=$(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+TARGET_ARCH="i386"
+TARGET_CONFIG=
+JOBS=1
+CONFIGURE_FLAGS=
+
+# commands to run
+BUILD_LUSTRE=0
+BUILD_KERNEL=0
+DEPEND_KERNEL=0
+INSTALL_LUSTRE=0
+INSTALL_KERNEL=0
+SAVE_HEADERS=0
+UNPACK_KERNEL=0
+
+# provided by target file
+KERNEL=
+SERIES=
+CONFIG=
+VERSION=
+EXTRA_VERSION=
+
+BASE_ARCH=
+BIGMEM_ARCHS=
+BOOT_ARCHS=
+JENSEN_ARCHS=
+SMP_ARCHS=
+UP_ARCHS=
+
+# flat-out globals
+TOPDIR=
+TARGET_FILE=
+KERNEL_FILE=
+SERIES_FILE=
+CONFIG_FILE=
+CC=${CC:-gcc}
+
+canon()
+{
+    pushd $1 >/dev/null
+    echo $PWD
+    popd >/dev/null
+}
+TOPDIR=$(canon "${0%%${0##*/}}/..")
+
+cleanup()
+{
+    true
+}
+
+fatal()
+{
+    cleanup
+    [ "$2" ] && echo
+    [ "$2" ] && echo "${0##*/}: $2"
+    exit $1
+}
+
+list_targets()
+{
+    echo -n "Available targets:"
+    for target in $TOPDIR/kernel_patches/targets/*.target ; do
+	target_file=${target##*/}
+	echo -n " ${target_file%%.target}"
+    done
+    echo
+}
+
+
+usage()
+{
+    cat <<EOF
+Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
+
+Options:
+
+  --build
+    same as --build-kernel --build-lustre --unpack-kernel
+
+  --build-lustre
+    configure and compile lustre.  Requires that --build-kernel was
+    already run.
+
+  --build-kernel
+    configure and compile a kernel.  Implies --depend-kernel.
+    Requires that --unpack-kernel was already run.
+
+  --depend-kernel)
+    Prepares a kernel tree for building (similar to make mrproper
+    oldconfig dep).  Requires that --unpack-kernel was already run.
+
+  --destdir=DESTDIR
+    Root directory to install into (like DESTDIR with auto*).
+
+  --extraversion=EXTRAVERSION
+    Overrides the target kernel\'s EXTRAVERSION text.
+
+  -h, --help
+    Display this message.
+
+  --install
+    same as --install-kernel --install-lustre
+
+  --install-lustre
+    run make install in the Lustre tree.
+
+  --install-kernel
+    install the kernel image and modules.
+
+  -j jobs
+    This works just like the -j option to make, and is passed to make
+    when building.
+
+  --kerneldir=KERNELDIR
+    Directory containing linux source tarballs.
+
+  --target=TARGET
+    Name of the configuration to use.  The available targets are
+    listed below.
+
+  --target-arch=ARCH
+    Specifies an architecture to use when choosing a kernel config
+    file.  Default is i386.
+
+  --target-config=CONFIG
+    Specifies a special option (such as smp, bigmem, or BOOT) to use
+    when choosing a kernel config file.  This also modifies the kernel
+    version and modules directory.
+
+  --unpack-kernel
+    Untars and patches the kernel source.
+
+  The order that commands (--build-lustre, --unpack-kernel) are
+  specified on the command line is ignored; ${0##*/} will always
+  execute them in the correct order (unpack, then build, then install
+  etc.).
+
+EOF
+    list_targets
+
+    fatal "$1" "$2"
+}
+
+check_options()
+{
+    (( $BUILD_LUSTRE || $BUILD_KERNEL || $DEPEND_KERNEL || \
+	    $INSTALL_LUSTRE || $INSTALL_KERNEL || $SAVE_HEADERS || \
+	    $UNPACK_KERNEL )) || \
+		fatal 1 "No commands specified."
+
+    if (( $UNPACK_KERNEL )) ; then
+	[ "$KERNELDIR" ] || \
+	    fatal 1 "A kernel directory must be specified with --kerneldir."
+	[ -d "$KERNELDIR" ] || \
+	    fatal 1 "$KERNELDIR is not a directory."
+    fi
+
+    if (( $INSTALL_LUSTRE || $INSTALL_KERNEL || $SAVE_HEADERS )) ; then
+	[ -z "$DESTDIR" -o -d "$DESTDIR" ] || \
+	    fatal 1 "$DESTDIR is not a directory."
+    fi
+
+    [ "$TARGET" ] || usage 1 "A target must be specified with --target."
+    TARGET_FILE="$TOPDIR/kernel_patches/targets/$TARGET.target"
+    [ -r "$TARGET_FILE" ] || \
+	fatal 1 "Target '$TARGET' was not found.  Try --list-targets."
+
+    if [ -z "$JOBS" -o "$JOBS" -lt "1" ] ; then
+	JOBS=1
+    fi
+}
+
+get_lustre_version()
+{
+    lustre_patch=$(grep lustre_version "$SERIES_FILE" 2>/dev/null)
+    [ "$lustre_patch" ] || \
+	fatal 1 "Could not determine Lustre version from $SERIES series."
+
+    awk '/^\+#define LUSTRE_KERNEL_VERSION /{ print $3 }' \
+	"$TOPDIR/kernel_patches/patches/$lustre_patch" 2>/dev/null
+}
+
+load_target()
+{
+    EXTRA_VERSION_save="$EXTRA_VERSION"
+
+    . "$TARGET_FILE"
+
+    [ "$KERNEL" ] || fatal 1 "Target $TARGET did not specify a kernel."
+    [ "$SERIES" ] || fatal 1 "Target $TARGET did not specify a patch series."
+#    [ "$CONFIG" ] || fatal 1 "Target $TARGET did not specify a kernel config."
+    [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify the kernel version."
+    
+    if [ "$KERNELDIR" ] ; then
+	KERNEL_FILE="$KERNELDIR/$KERNEL"
+	[ -r "$KERNELDIR/$KERNEL" ] || \
+	    fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
+    fi
+
+    SERIES_FILE="$TOPDIR/kernel_patches/series/$SERIES"
+    [ -r "$SERIES_FILE" ] || \
+	fatal 1 "Target $TARGET's series $SERIES missing from $TOPDIR/kernel_patches/series."
+
+    CONFIG_TARGET="$TARGET${TARGET_ARCH:+-$TARGET_ARCH}${TARGET_CONFIG:+-$TARGET_CONFIG}"
+    CONFIG_FILE="$TOPDIR/kernel_patches/kernel_configs/kernel-$VERSION-$CONFIG_TARGET.config"
+    [ -r "$CONFIG_FILE" ] || \
+	fatal 1 "Target $TARGET's config file $CONFIG missing from $TOPDIR/kernel_patches/configs."
+
+    if [ "$EXTRA_VERSION_save" ] ; then
+	EXTRA_VERSION="$EXTRA_VERSION_save"
+    else
+	EXTRA_VERSION="${EXTRA_VERSION}_lustre.$(get_lustre_version)"
+    fi
+    EXTRA_VERSION=${EXTRA_VERSION//-/_}
+}
+
+tarflags()
+{
+    case "$1" in
+	'')
+	    fatal 1 "tarflags(): File name argument missing."
+	    ;;
+	*.tar.gz)
+	    echo 'zxf'
+	    ;;
+	*.tar.bz2)
+	    echo 'jxf'
+	    ;;
+	*)
+	    fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
+	    ;;
+    esac
+}
+
+untar()
+{
+    echo "Untarring ${1##*/}..."
+    tar $(tarflags $1) $1
+}
+
+
+extract_kernel()
+{
+    (( $UNPACK_KERNEL )) || return 0
+    pushd "$TOPDIR" >/dev/null
+    if [ -d linux ] ; then
+	[ -L linux ] && rm -rf $(readlink linux)
+	rm -rf linux
+    fi
+    untar "$KERNEL_FILE"
+    [ -d linux ] || ln -sf linux* linux
+    popd >/dev/null
+}
+
+patch_kernel()
+{
+    (( $UNPACK_KERNEL )) || return 0
+    pushd "$TOPDIR/linux" >/dev/null
+    echo -n "Applying patch"
+    for patch in $(<"$SERIES_FILE") ; do
+	PATCH_FILE="$TOPDIR/kernel_patches/patches/$patch"
+	[ -r "$PATCH_FILE" ] || \
+	    fatal 1 "Patch file not found: $patch"
+	echo -n " $patch"
+	patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
+    done
+    echo
+    popd >/dev/null
+}
+
+depend_kernel()
+{
+    (( $DEPEND_KERNEL )) || return 0
+    # we need to override $CC at make time, since there is no
+    # configure
+    MAKE="make -s CC=$CC"
+    pushd "$TOPDIR/linux" >/dev/null
+    echo "Overriding EXTRAVERSION in kernel..."
+    perl -p -i -e "s/^EXTRAVERSION.*/EXTRAVERSION = -${EXTRA_VERSION}${TARGET_CONFIG}/" Makefile
+    echo "Making depend in $PWD..."
+    $MAKE mrproper || fatal 1 "Error running make mrproper"
+    cp "$CONFIG_FILE" .config
+    $MAKE oldconfig_nonint || fatal 1 "Error running make oldconfig"
+    $MAKE -j $JOBS dep || fatal 1 "Error running make dep"
+    $MAKE include/linux/version.h || fatal 1 "Error making include/linux/version.h"
+}
+
+build_kernel()
+{
+    (( $BUILD_KERNEL )) || return 0
+    # we need to override $CC at make time, since there is no
+    # configure
+    MAKE="make -s CC=$CC"
+    echo "Building kernel in $PWD..."
+    case "$TARGET_ARCH" in
+	i386 | i586 | i686 | athlon | x86_64)
+	    $MAKE -j $JOBS -s bzImage || fatal 1 "Error making bzImage."
+	    ;;
+	*)
+	    $MAKE -j $JOBS -s boot || fatal 1 "Error making boot."
+	    ;;
+    esac
+    $MAKE -j $JOBS -s modules || fatal 1 "Error building modules."
+
+    popd >/dev/null
+}
+
+configure_lustre()
+{
+    (( $BUILD_LUSTRE )) || return 0
+    pushd "$TOPDIR" >/dev/null
+    [ -f Makefile ] && make -s clean
+    [ -f configure ] || sh ./autogen.sh
+    ./configure --with-linux=$PWD/linux $CONFIGURE_FLAGS || \
+	fatal 1 "Error configuring Lustre."
+    popd >/dev/null
+}
+
+build_lustre()
+{
+    (( $BUILD_LUSTRE )) || return 0
+    pushd "$TOPDIR" >/dev/null
+    make -j $JOBS -s
+    popd >/dev/null
+}
+
+install_kernel()
+{
+    (( $INSTALL_KERNEL )) || return 0
+    FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
+    pushd "$TOPDIR/linux" >/dev/null
+    mkdir -p "$DESTDIR/boot"
+
+    install -m 644 System.map "$DESTDIR/boot/System.map-${FULL_VERSION}"
+    # install -m 644 module-info ...
+    install -m 644 "$CONFIG_FILE" "$DESTDIR/boot/config-${FULL_VERSION}"
+
+    mkdir -p "$DESTDIR/dev/shm"
+
+    case "$TARGET_ARCH" in
+	i386 | i586 | i686 | athlon)
+	    cp arch/i386/boot/bzImage "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
+	    cp vmlinux "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
+	    ;;
+	x86_64)
+	    cp arch/x86_64/boot/bzImage "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
+	    cp vmlinux "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
+	    ;;
+	ia64)
+	    gzip -cfv vmlinux > vmlinuz
+	    mkdir -p "$DESTDIR/boot/efi/redhat"
+	    install -m 755 vmlinux "$DESTDIR/boot/efi/redhat/vmlinux-${FULL_VERSION}"
+	    install -m 755 vmlinuz "$DESTDIR/boot/efi/redhat/vmlinuz-${FULL_VERSION}"
+	    ln -sf "efi/vmlinux-${FULL_VERSION}" "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
+	    ln -sf "efi/vmlinuz-${FULL_VERSION}" "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
+	    ;;
+	*)
+	    cp vmlinuz "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
+	    cp vmlinux "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
+	    ;;
+    esac
+
+    mkdir -p "$DESTDIR/lib/modules/${FULL_VERSION}"
+    make CC="$CC" INSTALL_MOD_PATH="$DESTDIR" KERNELRELEASE="$FULL_VERSION" \
+	-s modules_install || \
+	fatal 1 "Error installing modules."
+
+    popd >/dev/null
+}
+
+install_lustre()
+{
+    (( $INSTALL_LUSTRE )) || return 0
+    FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
+    pushd "$TOPDIR" >/dev/null
+    make -s install "DESTDIR=$DESTDIR" KERNELRELEASE="$FULL_VERSION" || fatal 1 "Error installing Lustre."
+    popd >/dev/null
+}
+
+save_headers()
+{
+    echo "Saving headers for $1 $2..."
+    pushd linux >/dev/null
+
+    KVERREL="${VERSION}-${EXTRA_VERSION}"
+    # deal with the kernel headers that are version specific
+    
+    saveddir="$RPM_BUILD_ROOT/usr/src/linux-${KVERREL}/savedheaders/$2/$1"
+    mkdir -p "$saveddir"
+    install -m 644 include/linux/autoconf.h "$saveddir/autoconf.h"
+    install -m 644 include/linux/version.h  "$saveddir/version.h"
+    mv include/linux/modules "$saveddir/"
+    echo $2 $1 ../../savedheaders/$2/$1/ >>  $RPM_BUILD_ROOT/usr/src/linux-${KVERREL}/savedheaders/list
+    popd >/dev/null
+}
+
+save_all_headers()
+{
+    (( $SAVE_HEADERS )) || return 0
+
+    for arch in $BIGMEM_ARCHS ; do
+	save_headers bigmem $arch
+    done
+
+    for arch in $BOOT_ARCHS ; do
+	save_headers BOOT $arch
+    done
+
+    for arch in $JENSEN_ARCHS ; do
+	save_headers jensen $arch
+    done
+
+    for arch in $SMP_ARCHS ; do
+	save_headers smp $arch
+    done
+
+    for arch in $UP_ARCHS ; do
+	save_headers up $arch
+    done
+}
+
+longopts="build,build-lustre,build-kernel,depend-kernel,destdir:,extraversion:"
+longopts="$longopts,help,install,install-lustre,install-kernel,kerneldir:"
+longopts="$longopts,save-headers,target:,target-arch:,target-config:,unpack-kernel"
+
+options=$(getopt -o hj: -l "$longopts" -- "$@")
+
+eval set -- "$options"
+    
+while [ "$1" ] ; do
+    case "$1" in
+	'')
+	    usage 1
+	    ;;
+	--build)
+	    BUILD_LUSTRE=1
+	    BUILD_KERNEL=1
+	    DEPEND_KERNEL=1
+	    UNPACK_KERNEL=1
+	    shift
+	    ;;
+	--build-lustre)
+	    BUILD_LUSTRE=1
+	    shift
+	    ;;
+	--build-kernel)
+	    BUILD_KERNEL=1
+	    DEPEND_KERNEL=1
+	    shift
+	    ;;
+	--depend-kernel)
+	    DEPEND_KERNEL=1
+	    shift
+	    ;;
+	--destdir)
+	    DESTDIR=$2
+	    shift 2
+	    ;;
+	--extraversion)
+	    EXTRA_VERSION=$2
+	    shift 2
+	    ;;
+	--help | -h)
+	    usage 0
+	    ;;
+	--install)
+	    INSTALL_LUSTRE=1
+	    INSTALL_KERNEL=1
+	    shift
+	    ;;
+	--install-lustre)
+	    INSTALL_LUSTRE=1
+	    shift
+	    ;;
+	--install-kernel)
+	    INSTALL_KERNEL=1
+	    shift
+	    ;;
+	-j)
+	    JOBS=$2
+	    shift 2
+	    ;;
+	--kerneldir)
+	    KERNELDIR=$2
+	    shift 2
+	    ;;
+	--save-headers)
+	    SAVE_HEADERS=1
+	    shift
+	    ;;
+	--target)
+	    TARGET=$2
+	    shift 2
+	    ;;
+	--target-arch)
+	    TARGET_ARCH=$2
+	    shift 2
+	    ;;
+	--target-config)
+	    TARGET_CONFIG=$2
+	    shift 2
+	    ;;
+	--unpack-kernel)
+	    UNPACK_KERNEL=1
+	    shift
+	    ;;
+	--)
+	    shift
+	    CONFIGURE_FLAGS=$@
+	    break
+	    ;; 
+	*)
+	    usage 1 "Unrecognized option: $1"
+	    ;;
+    esac
+done
+
+check_options
+load_target
+
+extract_kernel
+patch_kernel
+
+depend_kernel
+build_kernel
+
+configure_lustre
+build_lustre
+
+install_kernel
+install_lustre
+
+save_all_headers
+
+exit 0
diff --git a/lustre/scripts/lustre-kernel-2.4.spec.in b/lustre/scripts/lustre-kernel-2.4.spec.in
new file mode 100644
index 0000000000000000000000000000000000000000..c30bb549fefe4f202a410d93caaec6e14c58af9f
--- /dev/null
+++ b/lustre/scripts/lustre-kernel-2.4.spec.in
@@ -0,0 +1,778 @@
+Summary: The Linux kernel (the core of the Linux operating system)
+
+# Versions of various parts
+
+#
+# Polite request for people who spin their own kernel rpms:
+# please modify the "release" field in a way that identifies
+# that the kernel isn't the stock RHL kernel, for example by
+# adding some text to the end of the version number.
+#
+%define kversion @KERNEL_VERSION@
+%define release @KERNEL_RELEASE@
+# /usr/src/%{kslnk} -> /usr/src/linux-%{KVERREL}
+%define kslnk linux-2.4
+
+# groups of related archs
+%define all_x86 i386 i686 i586 athlon
+#define all_x86 i686 i386 i586 athlon
+
+%define nptlarchs %{all_x86}
+#define nptlarchs noarch
+
+# disable build root strip policy
+%define __spec_install_post /usr/lib/rpm/brp-compress || :
+#
+# RPM foo magic
+%define _missing_doc_files_terminate_build    0
+%define _unpackaged_files_terminate_build 0
+%define debug_package %{nil}
+
+# Enable this to build a board-specific kernel configuration 
+# some architectures have LOTS of different setups and this 
+# is a way to deal with that cleanly.
+#
+#define targetboard assabet
+%define dashtargetboard %{?targetboard:-%{targetboard}}
+%define withtargetboard 0
+%{?targetboard: %{expand: %%define withtargetboard 1}}
+	
+# Override generic defaults with per-arch defaults (which can
+# themselves be overridden with --with/--without).  These must
+# ONLY be "0", never "1"
+
+%define buildbase 0
+%define buildbigmem 0
+%define buildBOOT 0
+%define buildjensen 0
+%define buildsmp 0
+%define buildup 0
+
+%ifarch @BASE_ARCHS@
+%define buildbase 1
+%endif
+
+%ifarch @BIGMEM_ARCHS@
+%define buildbigmem 1
+%endif
+
+%ifarch @BOOT_ARCHS@
+%define buildBOOT 1
+%endif
+
+%ifarch @JENSEN_ARCHS@
+%define buildjensen 1
+%endif
+
+%ifarch @SMP_ARCHS@
+%define buildsmp 1
+%endif
+
+%ifarch @UP_ARCHS@
+%define buildup 1
+%endif
+
+# For board-specific kernels, build only the normal kernel (which may actually be smp, not up).
+%if %{withtargetboard}
+%define buildsmp 0
+%define buildBOOT 0
+%define buildbigmem 0
+%define buildjensen 0
+%endif
+
+%if 0
+Second, per-architecture exclusions (ifarch)
+%ifarch i386
+%define buildsmp 0
+%endif
+%ifarch ia64
+%define buildBOOT 0
+%endif
+%endif
+
+# we can't test values inline, only whether a macro exists
+%{expand: %%define buildup_%{buildup} yadda}
+%{expand: %%define buildsmp_%{buildsmp} yadda}
+%{expand: %%define buildBOOT_%{buildBOOT} yadda}
+%{expand: %%define buildbigmem_%{buildbigmem} yadda}
+%{expand: %%define buildjensen_%{buildjensen} yadda}
+%{expand: %%define ikd_%{ikd} yadda}
+%{expand: %%define ibcs_%{ibcs} yadda}
+%{expand: %%define debuglevel_%{debugging} yadda}
+
+%{expand: %%define kernel_conflicts  ppp <= 2.3.15, pcmcia-cs <= 3.1.20, isdn4k-utils <= 3.0, mount < 2.10r-5, nfs-utils < 0.3.1, cipe < 1.4.5, tux < 2.1.0, kudzu <= 0.92, e2fsprogs < 1.22, initscripts < 5.84, dev < 3.2-7, iptables < 1.2.5-3, bcm5820 < 1.81, nvidia-rh72 <= 1.0, oprofile < 0.4}
+
+%define BOOT_kernel_prereq fileutils, modutils >=  2.4.18
+%define kernel_prereq %{BOOT_kernel_prereq}, initscripts >= 5.83, mkinitrd >= 3.2.6
+%ifarch ia64
+%define initrd_dir /boot/efi/redhat
+%else
+%define initrd_dir /boot
+%endif
+
+%ifarch %{all_x86} x86_64
+%define kernel_glob vmlinu?-%{KVERREL}
+%endif
+%ifarch ia64
+# <sigh>, no GLOB_BRACE for filelists, efi needs to be done separately
+%define kernel_glob vmlinuz-%{KVERREL}
+%endif
+%ifarch alpha
+%define kernel_glob vmlinu?-%{KVERREL}
+%endif
+
+Name: kernel
+Version: %{kversion}
+Release: %{release}%{?targetboard:%{targetboard}}%{?debuglevel_1:.dbg}
+%define KVERREL %{PACKAGE_VERSION}-%{PACKAGE_RELEASE}
+License: GPL
+Group: System Environment/Kernel
+ExclusiveArch: %{all_x86} x86_64
+ExclusiveOS: Linux
+Obsoletes: kernel-modules, kernel-sparc
+Provides: kernel = %{version}
+BuildConflicts: rhbuildsys(DiscFree) < 500Mb
+%ifarch %{all_x86} ia64 x86_64
+Provides: kernel-drm = 4.1.0, kernel-drm = 4.2.0, kernel-drm = 4.3.0, kernel-drm = 4.2.99.3
+%endif
+Autoreqprov: no
+Prereq: %{kernel_prereq}
+Conflicts: %{kernel_conflicts}
+
+BuildPreReq: patch >= 2.5.4, bash >= 2.03, sh-utils, gnupg, tar
+BuildPreReq: bzip2, findutils, dev, gzip, m4
+
+Vendor: Cluster File Systems, Inc.
+URL: http://www.kernel.org/
+Buildroot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root
+
+Source0: @LUSTRE_SOURCE@
+Source1: @KERNEL_SOURCE@
+
+Source16: linux-merge-config.awk
+Source17: linux-merge-modules.awk
+
+%package source
+Summary: The source code for the Linux kernel.
+Group: Development/System
+Prereq: fileutils
+Requires: gawk
+Requires: gcc >= 2.96-98
+
+%package doc
+Summary: Various documentation bits found in the kernel source.
+Group: Documentation
+
+%description
+The kernel package contains the Linux kernel (vmlinuz), the core of a
+Linux operating system.  The kernel handles the basic functions of the
+operating system: memory allocation, process allocation, device input
+and output, etc.
+
+%description source
+The kernel-source package contains the source code files for the Linux
+kernel. These source files are needed to build custom/third party device
+drivers. The source files can also be used to build a custom kernel that is
+better tuned to your particular hardware, if you are so inclined (and you
+know what you're doing).
+
+%description doc
+This package contains documentation files form the kernel
+source. Various bits of information about the Linux kernel and the
+device drivers shipped with it are documented in these files. 
+
+You'll want to install this package if you need a reference to the
+options that can be passed to Linux kernel modules at load time.
+
+%package smp
+Summary: The Linux kernel compiled for SMP machines.
+Group: System Environment/Kernel
+Provides: module-info, kernel = %{version}
+%ifarch %{all_x86} ia64 x86_64
+Provides: kernel-drm = 4.1.0, kernel-drm = 4.2.0, kernel-drm = 4.3.0, kernel-drm = 4.2.99.3
+%endif
+Prereq: %{kernel_prereq}
+Conflicts: %{kernel_conflicts}
+
+%description smp
+This package includes a SMP version of the Linux kernel. It is
+required only on machines with two or more CPUs, although it should
+work fine on single-CPU boxes.
+
+Install the kernel-smp package if your machine uses two or more CPUs.
+
+%package bigmem
+Summary: The Linux Kernel for machines with more than 4 Gigabyte of memory.
+Group: System Environment/Kernel
+Provides: module-info, kernel = %{version}
+%ifarch %{all_x86} ia64 x86_64
+Provides: kernel-drm = 4.1.0, kernel-drm = 4.2.0, kernel-drm = 4.3.0, kernel-drm = 4.2.99.3
+%endif
+Prereq: %{kernel_prereq}
+Conflicts: %{kernel_conflicts}
+Obsoletes: kernel-enterprise <= 2.4.10
+
+%description bigmem
+This package includes a kernel that has appropriate configuration options
+enabled for Pentium III machines with 4 Gigabyte of memory or more.
+
+%package BOOT
+Summary: The version of the Linux kernel used on installation boot disks.
+Group: System Environment/Kernel
+Provides: kernel = %{version}
+Prereq: %{BOOT_kernel_prereq}
+Conflicts: %{kernel_conflicts}
+
+%description BOOT
+This package includes a trimmed down version of the Linux kernel.
+This kernel is used on the installation boot disks only and should not
+be used for an installed system, as many features in this kernel are
+turned off because of the size constraints.
+
+%package BOOTsmp
+Summary: The Linux kernel used on installation boot disks for SMP machines.
+Group: System Environment/Kernel
+Provides: kernel = %{version}
+Prereq: %{BOOT_kernel_prereq}
+Conflicts: %{kernel_conflicts}
+
+%description BOOTsmp
+This package includes a trimmed down version of the Linux kernel. This
+kernel is used on the installation boot disks only and should not be used
+for an installed system, as many features in this kernel are turned off
+because of the size constraints. This kernel is used when booting SMP
+machines that have trouble coming up to life with the uniprocessor kernel.
+
+%package jensen
+Summary: The Linux Kernel compiled for the Alpha Jensen platform.
+Group: System Environment/Kernel
+Provides: kernel = %{version}
+Prereq: %{kernel_prereq}
+Conflicts: %{kernel_conflicts}
+
+%description jensen
+This package includes a kernel that has appropriate configuration
+options enabled for use on the Alpha Jensen platform.  The Jensen
+platform is not supported in the normal generic alpha kernel support.
+
+%package -n lustre-lite-utils
+Summary: Lustre utils for Linux
+Group: Applications/System
+
+%description -n lustre-lite-utils
+The Lustre Lite file system utilities.  This includes the tools needed
+to configure, mount, and administer a Lustre filesystem.  This package
+is necessary if you want to access a Lustre filesystem.
+
+# the lustre-doc files are just included as %doc wiht
+# lustre-lite-utils
+
+#%package -n lustre-doc
+#Summary: Sample Lustre configurations and documentation
+#Group: Documentation
+
+#%description -n lustre-doc
+#The Lustre book, sample configurations, and other documentation for
+#Lustre.
+
+%package -n lustre-ldap
+Summary: LDAP schema files for Lustre
+Group: System Environment/Daemons
+
+%description -n lustre-ldap
+LDAP schema files for Lustre.  These are needed if you plan to store
+your Lustre configuration in LDAP, rather than on disk.
+
+%prep
+%setup -n lustre-kernel-%{version} -q -c
+if [ ! -d lustre ] ; then
+    ln -sf lustre* lustre
+fi
+pushd lustre >/dev/null
+sh -x ./scripts/lmake \
+	--unpack-kernel \
+	--target @LUSTRE_TARGET@ \
+	--kerneldir $RPM_SOURCE_DIR
+popd >/dev/null
+
+%build
+# if RPM_BUILD_NCPUS unset, set it
+if [ -z "$RPM_BUILD_NCPUS" ] ; then
+    RPM_BUILD_NCPUS=$(egrep -c "^cpu[0-9]+" /proc/stat || :)
+    if [ $RPM_BUILD_NCPUS -eq 0 ] ; then
+        RPM_BUILD_NCPUS=1
+    fi
+    if [ $RPM_BUILD_NCPUS -gt 8 ] ; then
+        RPM_BUILD_NCPUS=8
+    fi
+fi
+
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+
+DependKernel()
+{
+  target_config=${1:+--target-config $1}
+  sh -x ./scripts/lmake \
+	--depend-kernel \
+	--target @LUSTRE_TARGET@ \
+	--target-arch %{_target_cpu} \
+	${target_config} \
+	--extraversion %{release} \
+	-j $RPM_BUILD_NCPUS
+}
+
+BuildKernel()
+{
+  target_config=${1:+--target-config $1}
+  sh -x ./scripts/lmake \
+	--build-kernel --build-lustre \
+	--install \
+	--target @LUSTRE_TARGET@ \
+	--target-arch %{_target_cpu} \
+	${target_config} \
+	--extraversion %{release} \
+	--kerneldir $RPM_SOURCE_DIR \
+	-j $RPM_BUILD_NCPUS \
+	--destdir $RPM_BUILD_ROOT \
+	-- @CONFIGURE_FLAGS@
+}
+
+SaveHeaders()
+{
+  sh -x ./scripts/lmake \
+	--save-headers \
+	--target @LUSTRE_TARGET@ \
+	--extraversion %{release} \
+	--destdir $RPM_BUILD_ROOT
+}
+
+pushd lustre >/dev/null
+
+%if %{buildbigmem}
+BuildKernel bigmem
+%endif
+
+%if %{buildBOOT}
+BuildKernel BOOT
+%endif
+
+%if %{buildjensen}
+BuildKernel jensen
+%endif
+
+%if %{buildsmp}
+BuildKernel smp
+%endif
+
+# we want this one last, so that it is the one populating /usr/bin
+%if %{buildup} || %{buildbase}
+BuildKernel
+%endif
+
+%if %{buildbase}
+SaveHeaders
+%endif
+
+popd >/dev/null
+
+%install
+pushd lustre >/dev/null
+# it's already installed, so just clean up some things that are rpm
+# specific
+for i in $RPM_BUILD_ROOT/lib/modules/* ; do
+  rm -f $i/modules.*
+  rm -f $i/build
+  ln -sf ../../../usr/src/linux-%{KVERREL} $i/build
+%ifarch %{ntplarchs}
+  # remove legacy pcmcia symlink that's no longer useful
+  rm -rf $i/pcmcia
+%endif
+done
+
+# mark the vmlinux* non-executable to fool strip-to-file
+chmod a-x $RPM_BUILD_ROOT/boot/vmlinux*
+
+##
+## do -source package cleanup/install
+##
+%if %{buildbase}
+pushd linux >/dev/null
+mkdir -p $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+rm -f drivers/net/hamradio/soundmodem/gentbl scripts/mkdep
+tar cf - . | tar xf - -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+perl -p -i -e "s/^EXTRAVERSION.*/EXTRAVERSION = -%{release}custom/" $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/Makefile
+ln -sf linux-%{KVERREL} $RPM_BUILD_ROOT/usr/src/linux
+# install -m 644 %{SOURCE10}  $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+
+#clean up the destination
+make -s mrproper -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+rm -rf $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/configs/*
+cp ../kernel_patches/kernel_configs/kernel-%{kversion}-@LUSTRE_TARGET@*.config $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/configs
+cp ../kernel_patches/kernel_configs/kernel-%{kversion}-@LUSTRE_TARGET@-%{_target_cpu}%{dashtargetboard}.config $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/.config
+make -s oldconfig_nonint -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+make -s symlinks -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+make -s include/linux/version.h -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+
+#this generates modversions info which we want to include and we may as
+#well include the depends stuff as well, after we fix the paths
+make -s depend -C $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}
+find $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL} -name ".*depend" | \
+while read file ; do
+    mv $file $file.old
+    sed -e "s|[^ ]*\(/usr/src/linux\)|\1|g" < $file.old > $file
+    rm -f $file.old
+done
+
+# Try to put some smarter autoconf.h and version.h files in place
+pushd $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/include/linux ; {
+rm -rf modules modversions.h autoconf.h version.h
+cat > modversions.h <<EOF
+#ifndef _LINUX_MODVERSIONS_H
+#define _LINUX_MODVERSIONS_H
+#include <linux/rhconfig.h>
+#include <linux/modsetver.h>
+EOF
+echo '#include <linux/rhconfig.h>' > autoconf.h
+list=`find ../../savedheaders/* -name '*.ver' -exec basename '{}' \; | sort`
+mkdir modules
+for l in $list; do
+    sed 's,$,modules/'$l, ../../savedheaders/list | awk -f %{SOURCE17} > modules/$l
+    touch -r modules/$l modules/`basename $l .ver`.stamp
+    echo '#include <linux/modules/'$l'>' >> modversions.h
+done
+echo '#endif' >> modversions.h
+sed 's,$,autoconf.h,' ../../savedheaders/list | awk -f %{SOURCE16} >> autoconf.h
+# install -m 644 %{SOURCE15} rhconfig.h
+echo "#include <linux/rhconfig.h>" >> version.h
+keyword=if
+for i in smp BOOT BOOTsmp bigmem  up ; do
+# When we build in an i386, we don't have an bigmem header directory
+# in savedheaders/i386/bigmem.  We also don't have a BOOT directory
+# anywhere except in savedheaders/i386.  So, we need to use this method
+# of determining if a kernel version string needs to be included in the
+# version.h file
+    verh=`echo ../../savedheaders/*/$i/version.h | awk ' { print $1 } '`
+    if [ -n "$verh" -a -f "$verh" ]; then
+	if [ "$i" = up ]; then
+	    if [ "$keyword" = if ]; then
+		echo "#if 0" >> version.h
+	    fi
+  	    echo "#else" >> version.h
+	else
+	    echo "#$keyword defined(__module__$i)" >> version.h
+	    keyword=elif
+	fi
+	grep UTS_RELEASE $verh >> version.h
+    fi
+done
+echo "#endif" >> version.h
+if [ -f ../../savedheaders/%{_target_cpu}/up/version.h ] ; then
+    # keep to a standard normally
+    HEADER_FILE=../../savedheaders/%{_target_cpu}/up/version.h
+else
+    # test build not including uniprocessor, must get info from somewhere
+    HEADER_FILE=$(ls ../../savedheaders/*/*/version.h | head -1)
+fi
+grep -v UTS_RELEASE $HEADER_FILE >> version.h
+rm -rf ../../savedheaders
+} ; popd
+touch $RPM_BUILD_ROOT/boot/kernel.h-%{kversion}
+
+rm -f $RPM_BUILD_ROOT/usr/include/linux
+
+rm -rf $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/savedheaders
+
+# fix up the tmp_include_depends file wrt the buildroot
+perl -p -i -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT/usr/src/linux-%{KVERREL}/tmp_include_depends
+popd >/dev/null
+%endif
+
+popd >/dev/null
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+###
+### scripts
+###
+
+# do this for upgrades...in case the old modules get removed we have
+# loopback in the kernel so that mkinitrd will work.
+%pre 
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+exit 0
+
+%pre smp
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+exit 0
+
+%pre bigmem
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+exit 0
+
+%post 
+cd /boot
+%ifnarch ia64 
+ln -sf vmlinuz-%{KVERREL} vmlinuz
+%endif
+ln -sf System.map-%{KVERREL} System.map
+ln -sf module-info-%{KVERREL} module-info
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade
+[ -x /sbin/mkkerneldoth ] && /sbin/mkkerneldoth
+if [ -x /sbin/new-kernel-pkg ] ; then
+        /sbin/new-kernel-pkg --mkinitrd --depmod --install %{KVERREL}
+fi
+
+
+%post smp
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade
+[ -x /sbin/mkkerneldoth ] && /sbin/mkkerneldoth
+if [ -x /sbin/new-kernel-pkg ] ; then
+        /sbin/new-kernel-pkg --mkinitrd --depmod --install %{KVERREL}smp
+fi
+
+%post bigmem
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade
+[ -x /sbin/mkkerneldoth ] && /sbin/mkkerneldoth
+if [ -x /sbin/new-kernel-pkg ] ; then
+        /sbin/new-kernel-pkg --mkinitrd --depmod --install %{KVERREL}bigmem
+fi
+
+%post jensen
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade
+[ -x /sbin/mkkerneldoth ] && /sbin/mkkerneldoth
+if [ -x /sbin/new-kernel-pkg ] ; then
+        /sbin/new-kernel-pkg --mkinitrd --depmod --install %{KVERREL}jensen
+fi
+
+%ifnarch ia64
+%post BOOT
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade
+[ -x /sbin/mkkerneldoth ] && /sbin/mkkerneldoth
+if [ -x /sbin/new-kernel-pkg ] ; then
+        /sbin/new-kernel-pkg --mkinitrd --depmod --install %{KVERREL}BOOT
+fi
+
+%endif
+
+# Allow clean removal of modules directory
+%preun 
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+#rm -f /lib/modules/%{KVERREL}/modules.*
+if [ -x /sbin/new-kernel-pkg ] ; then
+ /sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}
+fi
+
+
+%preun smp
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+rm -f /lib/modules/%{KVERREL}smp/modules.*
+if [ -x /sbin/new-kernel-pkg ] ; then
+ /sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}smp
+fi
+
+
+%preun bigmem
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+rm -f /lib/modules/%{KVERREL}bigmem/modules.*
+if [ -x /sbin/new-kernel-pkg ] ; then
+ /sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}bigmem
+fi
+
+
+%preun BOOT
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+#rm -f /lib/modules/%{KVERREL}BOOT/modules.*
+if [ -x /sbin/new-kernel-pkg ] ; then
+ /sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}BOOT
+fi
+
+
+%preun jensen
+/sbin/modprobe loop 2> /dev/null > /dev/null  || :
+#rm -f /lib/modules/%{KVERREL}jensen/modules.*
+
+
+# We need this here because we don't prereq kudzu; it could be
+# installed after the kernel
+%triggerin -- kudzu
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade || :
+
+%triggerin smp -- kudzu
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade || :
+
+%triggerin bigmem -- kudzu
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade || :
+
+%triggerin BOOT -- kudzu
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade || :
+
+%triggerin jensen -- kudzu
+[ -x /usr/sbin/module_upgrade ] && /usr/sbin/module_upgrade || :
+
+
+# Old kernel-headers packages owned include symlinks; new
+# ones just make them so that we can have multiple kernel-headers
+# packages installed.
+
+%triggerpostun source -- kernel-headers < 2.2.16
+cd /usr/src
+rm -f %{kslnk}
+ln -snf linux-%{KVERREL} %{kslnk}
+exit 0
+
+%post source
+cd /usr/src
+rm -f %{kslnk}
+ln -snf linux-%{KVERREL} %{kslnk}
+
+%postun source
+if [ -L /usr/src/%{kslnk} ]; then 
+    if [ -L /usr/src/%{kslnk} -a `ls -ld /usr/src/%{kslnk} 2>/dev/null| awk '{ print $11 }'` = "linux-%{KVERREL}" ]; then
+	[ $1 = 0 ] && rm -f /usr/src/%{kslnk}
+    fi
+fi
+exit 0
+
+###
+### file lists
+###
+
+%if %{buildup}
+%files
+%defattr(-, root, root)
+/boot/%{kernel_glob}
+%ifarch ia64
+/boot/efi/redhat/%{kernel_glob}
+%endif
+/boot/System.map-%{KVERREL}
+/boot/config-%{KVERREL}
+%dir /lib/modules
+%dir /dev/shm
+/lib/modules/%{KVERREL}
+%endif
+
+%if %{buildsmp}
+%files smp
+%defattr(-, root, root)
+/boot/%{kernel_glob}smp
+%ifarch ia64
+/boot/efi/redhat/%{kernel_glob}smp
+%endif
+/boot/System.map-%{KVERREL}smp
+/boot/config-%{KVERREL}smp
+%dir /lib/modules
+%dir /dev/shm
+/lib/modules/%{KVERREL}smp
+%endif
+
+%if %{buildbigmem}
+%files bigmem
+%defattr(-, root, root)
+/boot/%{kernel_glob}bigmem
+%ifarch ia64
+/boot/efi/redhat/%{kernel_glob}bigmem
+%endif
+/boot/System.map-%{KVERREL}bigmem
+/boot/config-%{KVERREL}bigmem
+%dir /lib/modules
+%dir /dev/shm
+/lib/modules/%{KVERREL}bigmem
+%endif
+
+%if %{buildBOOT}
+%files BOOT
+%defattr(-, root, root)
+/boot/%{kernel_glob}BOOT
+%ifarch ia64
+/boot/efi/redhat/%{kernel_glob}BOOT
+%endif
+/boot/System.map-%{KVERREL}BOOT
+/boot/config-%{KVERREL}BOOT
+%dir /lib/modules
+%dir /dev/shm
+/lib/modules/%{KVERREL}BOOT
+%endif
+
+%if %{buildbase}
+
+%if 1
+%files source
+%defattr(-,root,root)
+%dir /usr/src/linux-%{KVERREL}
+/usr/src/linux-%{KVERREL}/COPYING*
+/usr/src/linux-%{KVERREL}/CREDITS
+/usr/src/linux-%{KVERREL}/Documentation
+/usr/src/linux-%{KVERREL}/MAINTAINERS
+/usr/src/linux-%{KVERREL}/Makefile
+/usr/src/linux-%{KVERREL}/README
+/usr/src/linux-%{KVERREL}/REPORTING-BUGS
+/usr/src/linux-%{KVERREL}/Rules.make
+/usr/src/linux-%{KVERREL}/arch
+%ifarch sparc
+/usr/src/linux-%{KVERREL}/arch/sparc64
+%endif
+/usr/src/linux-%{KVERREL}/drivers
+/usr/src/linux-%{KVERREL}/crypto
+/usr/src/linux-%{KVERREL}/fs
+/usr/src/linux-%{KVERREL}/init
+/usr/src/linux-%{KVERREL}/ipc
+/usr/src/linux-%{KVERREL}/kernel
+/usr/src/linux-%{KVERREL}/lib
+/usr/src/linux-%{KVERREL}/mm
+/usr/src/linux-%{KVERREL}/net
+/usr/src/linux-%{KVERREL}/scripts
+%ifarch %{all_x86}
+%{?ibcs_1:/usr/src/linux-%{KVERREL}/abi}
+%endif
+/usr/src/linux-%{KVERREL}/configs
+/usr/src/linux-%{KVERREL}/include
+/usr/src/linux-%{KVERREL}/include/asm
+%ifarch %{all_x86}
+%{?ibcs_1:/usr/src/linux-%{KVERREL}/include/abi}
+%endif
+/usr/src/linux-%{KVERREL}/include/linux
+/usr/src/linux-%{KVERREL}/include/rxrpc
+/usr/src/linux-%{KVERREL}/include/net
+/usr/src/linux-%{KVERREL}/include/pcmcia
+/usr/src/linux-%{KVERREL}/include/scsi
+/usr/src/linux-%{KVERREL}/include/video
+/usr/src/linux-%{KVERREL}/tmp_include_depends
+%dir /usr/src/linux-%{KVERREL}/include
+%dir /usr/src/linux-%{KVERREL}/arch
+%ifarch alpha sparc
+/usr/src/linux-%{KVERREL}/include/math-emu
+%endif
+%endif
+
+%files doc
+%defattr(-,root,root)
+%doc lustre/linux/Documentation/*
+
+%files -n lustre-lite-utils
+%defattr(-, root, root)
+%doc lustre/COPYING lustre/BUGS lustre/ChangeLog lustre/README lustre/doc/lustre.pdf
+%{_sbindir}/*
+%{_bindir}/*
+%{_libdir}/lustre/python
+%{_sysconfdir}/init.d/lustre
+/usr/include/lustre
+/lib/lib*.a
+
+#%files -n lustre-doc
+#%defattr(-, root, root)
+#/usr/share/doc/lustre/COPYING
+#/usr/share/doc/lustre/lustre.pdf
+#/usr/share/doc/lustre/COPYING
+
+/usr/lib/lustre/examples
+
+%files -n lustre-ldap
+%defattr(-, root, root)
+/etc/openldap/slapd-lustre.conf
+/etc/openldap/schema/lustre.schema
+/usr/lib/lustre/lustre2ldif.xsl
+/usr/lib/lustre/top.ldif
+
+%endif # %{buildbase}
diff --git a/lustre/scripts/lustre.spec.in b/lustre/scripts/lustre.spec.in
index cd5fb58e1c89b5dd884059f3e77a11c45ec6bd58..907a0b3778c393518fbf14b1985ef52834c972c6 100644
--- a/lustre/scripts/lustre.spec.in
+++ b/lustre/scripts/lustre.spec.in
@@ -1,5 +1,5 @@
 # lustre.spec
-%define version HEAD
+%define version b_devel
 %define kversion @LINUXRELEASE@
 %define linuxdir @LINUX@
 
@@ -96,11 +96,16 @@ make distdir distdir=lustre-source/lustre-%{version}
 mkdir -p $RPM_BUILD_ROOT/var/lib/ldap/lustre
 
 %files
+%attr(-, root, root) /sbin/mount.lustre
 %attr(-, root, root) /usr/sbin/lmc
 %attr(-, root, root) /usr/sbin/lctl
 %attr(-, root, root) /usr/sbin/lconf
+%attr(-, root, root) /usr/sbin/lwizard
+%attr(-, root, root) /usr/sbin/wiretest
 %attr(-, root, root) /usr/sbin/lactive
 %attr(-, root, root) /usr/sbin/llanalyze
+%attr(-, root, root) /usr/sbin/lfs
+%attr(-, root, root) /usr/sbin/gmnalnid
 %attr(-, root, root) /usr/bin/lfind
 %attr(-, root, root) /usr/bin/lstripe
 %attr(-, root, root) /usr/bin/mcreate
@@ -126,6 +131,7 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/ldap/lustre
 %attr(-, root, root) /lib/libportals.a
 %attr(-, root, root) /lib/libptlctl.a
 %attr(-, root, root) /lib/libtcpnal.a
+%attr(-, root, root) /lib/liblustreapi.a
 %attr(-, root, root) /usr/include/lustre/*.h
 %attr(-, root, root) /usr/sbin/lload
 %attr(-, root, root) /usr/sbin/obdbarrier
@@ -150,29 +156,9 @@ mkdir -p $RPM_BUILD_ROOT/var/lib/ldap/lustre
 
 %files -n lustre-modules
 %attr(-, root, root) %doc COPYING
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ldlm.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/llite.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mdc.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mds.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/fsfilt_ext3.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/fsfilt_reiserfs.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdclass.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdecho.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdfilter.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/lov.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/osc.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ost.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ptlrpc.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ptlbd.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/cobd.o
+%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/*.o
 #portals modules
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/kptlrouter.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/*nal.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/portals.o
-%ifarch alpha
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/p3mod.o
-%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/rtscts.o
-%endif
+%attr(-, root, root) /lib/modules/%{kversion}/kernel/net/lustre/*.o
 
 %files -n lustre-source
 %attr(-, root, root) /usr/src/lustre-%{version}
diff --git a/lustre/tests/.cvsignore b/lustre/tests/.cvsignore
index 21575d042fa97f408c9902dfee2058799785cdf0..9e4374f49473797107911df03c690926a93e100c 100644
--- a/lustre/tests/.cvsignore
+++ b/lustre/tests/.cvsignore
@@ -47,3 +47,10 @@ o_directory
 mkdirdeep
 utime
 small_write
+multiop
+sleeptest
+write_append_truncate
+ll_sparseness_verify
+ll_sparseness_write
+mrename
+cmknod
diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am
index 31e33a361f05c961c17e4c02521ad64e810194cc..3a91b5a3585c4b6f14d80ce7329585a4e4dfb3b8 100644
--- a/lustre/tests/Makefile.am
+++ b/lustre/tests/Makefile.am
@@ -1,11 +1,11 @@
 # Lustre test Makefile
 DEFS=
-CPPFLAGS = -I. -I$(top_srcdir)/portals/include/ -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE
+CPPFLAGS = -I. -I$(top_srcdir)/portals/include/ -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 CFLAGS := -g -Wall
 # LDADD = -lldap
 # LDADD := -lreadline -ltermcap # -lefence
 EXTRA_DIST = $(pkgexample_SCRIPTS) $(noinst_SCRIPTS) $(noinst_DATA) \
-	sanity.sh          rundbench    mcreate
+	sanity.sh rundbench
 pkgexample_SCRIPTS = llmount.sh llmountcleanup.sh llecho.sh llechocleanup.sh
 pkgexample_SCRIPTS += local.sh echo.sh uml.sh lov.sh
 noinst_DATA =
@@ -15,10 +15,11 @@ noinst_SCRIPTS += runfailure-ost runiozone runregression-net.sh runtests
 noinst_SCRIPTS += sanity.sh rundbench
 noinst_PROGRAMS = openunlink testreq truncate directio openme writeme open_delay
 noinst_PROGRAMS += tchmod toexcl fsx test_brw openclose createdestroy
-noinst_PROGRAMS += stat createmany statmany multifstat createtest mlink utime
+noinst_PROGRAMS += stat createmany statmany multifstat createtest mlink utime cmknod
 noinst_PROGRAMS += opendirunlink opendevunlink unlinkmany fchdir_test checkstat
 noinst_PROGRAMS += wantedi statone runas openfile getdents mkdirdeep o_directory
-noinst_PROGRAMS += small_write
+noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify
+noinst_PROGRAMS += ll_sparseness_write mrename
 # noinst_PROGRAMS += ldaptest
 bin_PROGRAMS = mcreate munlink mkdirmany
 
@@ -38,7 +39,7 @@ fsx_SOURCES = fsx.c
 test_brw_SOURCES = test_brw.c
 openclose_SOURCES = openclose.c
 createdestroy_SOURCES = createdestroy.c
-stat_SOURCES = stat.c
+stat_SOURCES = stat.c stat_fs.h
 createmany_SOURCES = createmany.c
 statmany_SOURCES = statmany.c
 unlinkmany_SOURCES = unlinkmany.c
@@ -52,14 +53,24 @@ wantedi_SOURCES = wantedi.c
 createtest_SOURCES = createtest.c
 open_delay_SOURCES = open_delay.c
 opendirunlink_SOURCES = opendirunlink.c
-opendevunlink_SOURCES = opendevunlink.c
+opendevunlink_SOURCES = opendirunlink.c
 fchdir_test_SOURCES = fchdir_test.c
 getdents_SOURCES=getdents.c
 o_directory_SOURCES = o_directory.c
 utime_SOURCES = utime.c
+cmknod_SOURCES = cmknod.c
 mkdirdeep_SOURCES = mkdirdeep.c
 mkdirdeep_LDADD=-L$(top_builddir)/portals/utils -lptlctl
 mkdirdeep_CPPFLAGS=-I$(top_srcdir)/portals/include
 small_write_SOURCES = small_write.c
+sleeptest_SOURCES = sleeptest.c
+#write_append_truncate_SOURCES=write_append_truncate.c
+#write_append_truncate_CC=mpicc
+#createmany_mpi_SOURCES=createmany_mpi.c
+#createmany_mpi_CC=mpicc
+
+#sanity test 
+ll_sparseness_verify_SOURCES = ll_sparseness_verify.c
+ll_sparseness_write_SOURCES = ll_sparseness_write.c
 
 include $(top_srcdir)/Rules
diff --git a/lustre/tests/Makefile.mk b/lustre/tests/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..b0106ac4b5adc3bac4f413c50f92225521a8b009
--- /dev/null
+++ b/lustre/tests/Makefile.mk
@@ -0,0 +1,53 @@
+include $(src)/../portals/Kernelenv
+
+HOSTCFLAGS += -Iinclude -D_LARGEFILE64_SOURCE
+
+OURPTLCTL := $(addprefix $(src)/../portals/utils/, $(PTLCTLOBJS))
+OURPTLCTLNOPARSER := $(addprefix $(src)/../portals/utils/, \
+			$(filter-out parser.o,$(PTLCTLOBJS)))
+
+host-progs := openunlink testreq truncate directio openme writeme open_delay \
+	 	munlink tchmod toexcl fsx test_brw openclose createdestroy \
+		stat createmany statmany multifstat createtest mlink \
+		opendirunlink opendevunlink unlinkmany fchdir_test \
+		checkstat wantedi statone runas openfile \
+		mcreate mkdirmany utime o_directory small_write multiop
+
+always := $(host-progs) 
+
+
+tchmod-objs  := tchmod.o
+toexcl-objs  := toexcl.o
+testreq-objs  := testreq.o
+mcreate-objs  := mcreate.o
+munlink-objs  := munlink.o
+mlink-objs  := mlink.o
+truncate-objs  := truncate.o
+directio-objs  := directio.o
+openunlink-objs  := openunlink.o
+openme-objs  := openme.o
+writeme-objs  := writeme.o
+fsx-objs  := fsx.o
+test_brw-objs  := test_brw.o
+openclose-objs  := openclose.o
+createdestroy-objs  := createdestroy.o
+stat-objs  := stat.o
+createmany-objs  := createmany.o
+statmany-objs  := statmany.o
+unlinkmany-objs  := unlinkmany.o
+statone-objs  := statone.o
+mkdirmany-objs  := mkdirmany.o
+multifstat-objs  := multifstat.o
+checkstat-objs  := checkstat.o
+runas-objs  := runas.o
+openfile-objs  := openfile.o
+wantedi-objs  := wantedi.o
+createtest-objs  := createtest.o
+open_delay-objs  := open_delay.o
+opendirunlink-objs :=opendirunlink.o
+opendevunlink-objs :=opendirunlink.o
+fchdir_test-objs :=fchdir_test.o
+utime-objs :=utime.o
+o_directory-objs :=o_directory.o
+small_write-objs :=small_write.o
+multiop-objs :=multiop.o
diff --git a/lustre/tests/acceptance-metadata-double.sh b/lustre/tests/acceptance-metadata-double.sh
index 496f3b4539f0ff83337b55dd1ad390eeb9bc5976..c8d5dd858de0f924d14479e9d3c182e650fe7bef 100644
--- a/lustre/tests/acceptance-metadata-double.sh
+++ b/lustre/tests/acceptance-metadata-double.sh
@@ -10,6 +10,20 @@ SRCDIR="`dirname $0`"
 CREATE=$SRCDIR/create.pl
 RENAME=$SRCDIR/rename.pl
 
+TIME=${TIME:-/usr/bin/time}
+
+display_elapsed_time() {
+    PREVIOUS_TS=$CURRENT_TS
+    CURRENT_TS=`date +%s`
+    BLOCK_ELAPSED=`expr $CURRENT_TS - $PREVIOUS_TS`
+    TOTAL_ELAPSED=`expr $CURRENT_TS - $START_TS`
+
+    echo " "
+    echo "Elapsed time (block): ${BLOCK_ELAPSED} seconds"
+    echo "Elapsed time (TOTAL): ${TOTAL_ELAPSED} seconds"
+    echo " "
+}    
+
 debug_client_on()
 {
 	echo -1 > /proc/sys/portals/debug
@@ -22,73 +36,93 @@ debug_client_off()
 
 MNT=${MNT:-/mnt/lustre}
 
+# Get our initial timestamps.
+START_TS=`date +%s`
+CURRENT_TS=$START_TS
+PREVIOUS_TS=$START_TS
+
 debug_client_on
 echo "create.pl, 2 mounts, 1 thread, 10 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=10
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=10
 echo "create.pl, 2 mounts, 1 thread, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 1 thread, 10 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=10 --use_mcreate=0
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=10 --use_mcreate=0
 echo "create.pl --use_mcreate=0, 2 mounts, 1 thread, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 1 thread, 10 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=10
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=10
 echo "rename.pl, 2 mounts, 1 thread, 100 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=100 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=100 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 2 mounts, 1 thread, 1000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=1000 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=1000 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 1 thread, 1000 ops, debug off"
-perl $CREATE --silent --use_mcreate=0 -- $MNT 2 1000
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=1000 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=1000 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 1 thread, 1000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=1000 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=1000 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 2 mounts, 2 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=2 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=2 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 2 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=2 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=2 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 2 thread, 1000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=1000 --num_threads=2 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=1000 --num_threads=2 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 2 mounts, 2 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 2 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 2 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=2 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 2 mounts, 4 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=4 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=4 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 4 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=4 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=100 --num_threads=4 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 2 mounts, 4 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 4 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 4 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=4 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 2 mounts, 8 threads, 500 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=500 --num_threads=8 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=500 --num_threads=8 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 8 threads, 500 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=500 --num_threads=8 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=500 --num_threads=8 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 2 mounts, 8 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
 echo "create.pl --use_mcreate=0, 2 mounts, 8 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --use_mcreate=0 --silent
 echo "rename.pl, 2 mounts, 8 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=2 --iterations=2000 --num_threads=8 --silent
+
+display_elapsed_time
diff --git a/lustre/tests/acceptance-metadata-single.sh b/lustre/tests/acceptance-metadata-single.sh
index 2bf0a53398a8f6c3a55fe5001af543852825a048..3366d9c7c04575cbef01ab53a1eefb2ab7bd8a57 100644
--- a/lustre/tests/acceptance-metadata-single.sh
+++ b/lustre/tests/acceptance-metadata-single.sh
@@ -10,6 +10,20 @@ SRCDIR="`dirname $0`"
 CREATE=$SRCDIR/create.pl
 RENAME=$SRCDIR/rename.pl
 
+TIME=${TIME:-/usr/bin/time}
+
+display_elapsed_time() {
+    PREVIOUS_TS=$CURRENT_TS
+    CURRENT_TS=`date +%s`
+    BLOCK_ELAPSED=`expr $CURRENT_TS - $PREVIOUS_TS`
+    TOTAL_ELAPSED=`expr $CURRENT_TS - $START_TS`
+
+    echo " "
+    echo "Elapsed time (block): ${BLOCK_ELAPSED} seconds"
+    echo "Elapsed time (TOTAL): ${TOTAL_ELAPSED} seconds"
+    echo " "
+}    
+
 debug_client_on()
 {
 	echo -1 > /proc/sys/portals/debug
@@ -22,80 +36,118 @@ debug_client_off()
 
 MNT=${MNT:-/mnt/lustre}
 
+# Get our initial timestamps.
+START_TS=`date +%s`
+CURRENT_TS=$START_TS
+PREVIOUS_TS=$START_TS
+
 debug_client_on
 echo "create.pl, 1 mount, 1 thread, 10 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=10
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=10
 echo "create.pl, 1 mount, 1 thread, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --silent
 echo "create.pl --mcreate=0, 1 mount, 1 thread, 10 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=10 --use_mcreate=0
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=10 --use_mcreate=0
 echo "create.pl --mcreate=0, 1 mount, 1 thread, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 1 thread, 10 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=10
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=10
 echo "rename.pl, 1 mount, 1 thread, 100 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=100 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=100 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 1 mount, 1 thread, 1000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --silent
 echo "create.pl --mcreate=0, 1 mount, 1 thread, 1000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 1 thread, 1000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 1 mount, 2 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=2 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=2 --silent
 echo "create.pl --mcreate=0, 1 mount, 2 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=2 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=2 --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 2 thread, 1000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --num_threads=2 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=1000 --num_threads=2 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 1 mount, 2 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --silent
 echo "create.pl --mcreate=0, 1 mount, 2 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --use_mcreate=0  --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --use_mcreate=0  --silent
 wait
 echo "rename.pl, 1 mount, 2 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=2 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 1 mount, 4 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=4 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=4 --silent
 echo "create.pl --mcreate=0, 1 mount, 4 threads, 100 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=4 --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=100 --num_threads=4 --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 1 mount, 4 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4  --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4  --silent
 echo "create.pl --mcreate=0, 1 mount, 4 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4  --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4  --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 4 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=4 --silent
+
+display_elapsed_time
 
 debug_client_on
 echo "create.pl, 1 mount, 8 threads, 500 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=500 --num_threads=8  --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=500 --num_threads=8  --silent
 echo "create.pl --mcreate=0, 1 mount, 8 threads, 500 ops, debug on"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=500 --num_threads=8  --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=500 --num_threads=8  --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug on"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8 --silent
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8 --silent
+
+display_elapsed_time
 
 debug_client_off
 echo "create.pl, 1 mount, 8 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8  --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8  --silent
 echo "create.pl --mcreate=0, 1 mount, 8 threads, 2000 ops, debug off"
-perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8  --use_mcreate=0 --silent
+$TIME perl $CREATE --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8  --use_mcreate=0 --silent
 echo "rename.pl, 1 mount, 8 threads, 2000 ops, debug off"
-perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8 --silent
-
-sh rundbench 1
-sh rundbench 2
-sh rundbench 4
-sh rundbench 8
-sh rundbench 16
-sh rundbench 32
+$TIME perl $RENAME --mountpt=${MNT} --num_mounts=-1 --iterations=2000 --num_threads=8 --silent
+
+display_elapsed_time
+
+$TIME sh rundbench 1
+
+display_elapsed_time
+
+$TIME sh rundbench 2
+
+display_elapsed_time
+
+$TIME sh rundbench 4
+
+display_elapsed_time
+
+$TIME sh rundbench 8
+
+display_elapsed_time
+
+$TIME sh rundbench 16
+
+display_elapsed_time
+
+$TIME sh rundbench 32
+
+display_elapsed_time
diff --git a/lustre/tests/acceptance-small.sh b/lustre/tests/acceptance-small.sh
index 919ea1fb409b3271fbcd8e5f00479cc8523c04fc..4d0efbb0fd94cb282c7497fe4d609ef497e651f0 100755
--- a/lustre/tests/acceptance-small.sh
+++ b/lustre/tests/acceptance-small.sh
@@ -4,7 +4,7 @@
 set -vxe
 
 [ "$CONFIGS" -a -z "$SANITYN" ] && SANITYN=no
-[ "$CONFIGS" ] || CONFIGS="local lov"
+[ "$CONFIGS" ] || CONFIGS="local-large-inode local lov"
 [ "$MAX_THREADS" ] || MAX_THREADS=10
 if [ -z "$THREADS" ]; then
 	KB=`awk '/MemTotal:/ { print $2 }' /proc/meminfo`
@@ -14,14 +14,16 @@ fi
 [ "$SIZE" ] || SIZE=20480
 [ "$RSIZE" ] || RSIZE=64
 [ "$UID" ] || UID=1000
-[ "$MNT" ] || MNT=/mnt/lustre
+[ "$MOUNT" ] || MOUNT=/mnt/lustre
 [ "$TMP" ] || TMP=/tmp
 [ "$COUNT" ] || COUNT=1000
-[ "$DEBUG_OFF" ] || DEBUG_OFF="eval echo 0 > /proc/sys/portals/debug"
+#[ "$DEBUG_LVL" ] || DEBUG_LVL=0x370200
+[ "$DEBUG_LVL" ] || DEBUG_LVL=0
+[ "$DEBUG_OFF" ] || DEBUG_OFF="eval echo $DEBUG_LVL > /proc/sys/portals/debug"
 [ "$DEBUG_ON" ] || DEBUG_ON="eval echo -1 > /proc/sys/portals/debug"
 
 for NAME in $CONFIGS; do
-	export NAME
+	export NAME MOUNT
 	[ -e $NAME.sh ] && sh $NAME.sh
 	[ ! -e $NAME.xml ] && [ -z "$LDAPURL" ] && echo "no config '$NAME.xml'" 1>&2 && exit 1
 
@@ -31,12 +33,12 @@ for NAME in $CONFIGS; do
 
 	#[ "$SANITY" != "no" ] && sh sanity.sh
 	if [ "$SANITY" != "no" ]; then
-		START=: CLEAN=: sh sanity.sh
+		SANITYLOG=/tmp/sanity.log START=: CLEAN=: sh sanity.sh
 	fi
 
 	if [ "$DBENCH" != "no" ]; then
-		mount | grep $MNT || sh llmount.sh
-		SPACE=`df $MNT | tail -1 | awk '{ print $4 }'`
+		mount | grep $MOUNT || sh llmount.sh
+		SPACE=`df $MOUNT | tail -1 | awk '{ print $4 }'`
 		DB_THREADS=`expr $SPACE / 50000`
 		[ $THREADS -lt $DB_THREADS ] && DB_THREADS=$THREADS
 
@@ -52,21 +54,21 @@ for NAME in $CONFIGS; do
 			sh llmountcleanup.sh
 			sh llrmount.sh
 		fi
-		rm -f /mnt/lustre/client.txt
+		rm -f /mnt/lustre/`hostname`/client.txt
 	fi
-	chown $UID $MNT && chmod 700 $MNT
+	chown $UID $MOUNT && chmod 700 $MOUNT
 	if [ "$BONNIE" != "no" ]; then
-		mount | grep $MNT || sh llmount.sh
+		mount | grep $MOUNT || sh llmount.sh
 		$DEBUG_OFF
-		bonnie++ -s 0 -n 10 -u $UID -d $MNT
+		bonnie++ -s 0 -n 10 -u $UID -d $MOUNT
 		$DEBUG_ON
 		sh llmountcleanup.sh
 		sh llrmount.sh
 	fi
 	IOZONE_OPTS="-i 0 -i 1 -i 2 -+d -r $RSIZE -s $SIZE"
-	IOZONE_FILE="-f $MNT/iozone"
+	IOZONE_FILE="-f $MOUNT/iozone"
 	if [ "$IOZONE" != "no" ]; then
-		mount | grep $MNT || sh llmount.sh
+		mount | grep $MOUNT || sh llmount.sh
 		$DEBUG_OFF
 		iozone $IOZONE_OPTS $IOZONE_FILE
 		$DEBUG_ON
@@ -74,8 +76,8 @@ for NAME in $CONFIGS; do
 		sh llrmount.sh
 	fi
 	if [ "$IOZONE_DIR" != "no" ]; then
-		mount | grep $MNT || sh llmount.sh
-		SPACE=`df $MNT | tail -1 | awk '{ print $4 }'`
+		mount | grep $MOUNT || sh llmount.sh
+		SPACE=`df $MOUNT | tail -1 | awk '{ print $4 }'`
 		IOZ_THREADS=`expr $SPACE / \( $SIZE + $SIZE / 1000 \)`
 		[ $THREADS -lt $IOZ_THREADS ] && IOZ_THREADS=$THREADS
 
@@ -90,7 +92,7 @@ for NAME in $CONFIGS; do
 			THREAD=1
 			IOZONE_FILE="-F "
 			while [ $THREAD -le $IOZ_THREADS ]; do
-				IOZONE_FILE="$IOZONE_FILE $MNT/iozone.$THREAD"
+				IOZONE_FILE="$IOZONE_FILE $MOUNT/iozone.$THREAD"
 				THREAD=`expr $THREAD + 1`
 			done
 			iozone -I $IOZONE_OPTS -t $IOZ_THREADS $IOZONE_FILE
@@ -103,19 +105,22 @@ for NAME in $CONFIGS; do
 		fi
 	fi
 	if [ "$FSX" != "no" ]; then
-		mount | grep $MNT || sh llmount.sh
+		mount | grep $MOUNT || sh llmount.sh
 		$DEBUG_OFF
-		./fsx -W -c 50 -p 1000 -P $TMP -l 1024000 -N $(($COUNT * 100)) $MNT/fsxfile
+		./fsx -W -c 50 -p 1000 -P $TMP -l 1024000 -N $(($COUNT * 100)) $MOUNT/fsxfile
 		$DEBUG_ON
 		sh llmountcleanup.sh
 		#sh llrmount.sh
 	fi	
-	mount | grep $MNT && sh llmountcleanup.sh
+	mount | grep $MOUNT && sh llmountcleanup.sh
 done
 
+if [ "$REPLAY_SINGLE" != "no" ]; then
+	sh replay-single.sh
+fi
 if [ "$SANITYN" != "no" ]; then
 	export NAME=mount2
-	mount | grep $MNT || sh llmount.sh
+	mount | grep $MOUNT || sh llmount.sh
 	sh sanityN.sh
-	mount | grep $MNT && sh llmountcleanup.sh
+	mount | grep $MOUNT && sh llmountcleanup.sh
 fi
diff --git a/lustre/tests/cfg/insanity-local.sh b/lustre/tests/cfg/insanity-local.sh
new file mode 100644
index 0000000000000000000000000000000000000000..4ce742f7ec49e8abd603a1a161cf078182a5baae
--- /dev/null
+++ b/lustre/tests/cfg/insanity-local.sh
@@ -0,0 +1,30 @@
+mds_HOST=${mds_HOST:-`hostname`}
+mdsfailover_HOST=${mdsfailover_HOST:-""}
+ost1_HOST=${ost1_HOST:-"`hostname`"}
+ost2_HOST=${ost2_HOST:-"`hostname`"}
+client_HOST="'*'"
+LIVE_CLIENT=${LIVE_CLIENT:-"`hostname`"}
+# This should always be a list, not a regexp
+FAIL_CLIENTS=${FAIL_CLIENTS:-""}
+
+NETTYPE=${NETTYPE:-tcp}
+TIMEOUT=${TIMEOUT:-30}
+PTLDEBUG=${PTLDEBUG:-'"ha|info|ioctl|malloc"'}
+MOUNT=${MOUNT:-"/mnt/lustre"}
+#CLIENT_UPCALL=${CLIENT_UPCALL:-`pwd`/client-upcall-mdev.sh}
+UPCALL=${CLIENT_UPCALL:-`pwd`/replay-single-upcall.sh}
+
+MDSDEV=${MDSDEV:-$ROOT/tmp/mds-`hostname`}
+MDSSIZE=${MDSSIZE:-10000} #50000000
+
+OSTDEV=${OSTDEV:-$ROOT/tmp/ost-`hostname`}
+OSTSIZE=${OSTSIZE:=10000} #50000000
+FSTYPE=${FSTYPE:-ext3}
+STRIPE_BYTES=${STRIPE_BYTES:-65536} #1048576
+STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-0}
+
+FAILURE_MODE=${FAILURE_MODE:-SOFT} # or HARD
+POWER_DOWN=${POWER_DOWN:-"powerman --off"}
+POWER_UP=${POWER_UP:-"powerman --on"}
+
+PDSH=no_dsh
diff --git a/lustre/tests/cfg/insanity-mdev.sh b/lustre/tests/cfg/insanity-mdev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5e69356535721b8226698a17b2eabf4de0b6a319
--- /dev/null
+++ b/lustre/tests/cfg/insanity-mdev.sh
@@ -0,0 +1,31 @@
+mds_HOST=${mds_HOST:-mdev4}
+mdsfailover_HOST=${mdsfailover_HOST:-mdev5}
+ost1_HOST=${ost1_HOST:-mdev2}
+ost2_HOST=${ost2_HOST:-mdev3}
+client_HOST=client
+LIVE_CLIENT=${LIVE_CLIENT:-mdev6}
+# This should always be a list, not a regexp
+FAIL_CLIENTS=${FAIL_CLIENTS:-mdev7}
+
+NETTYPE=${NETTYPE:-tcp}
+
+TIMEOUT=${TIMEOUT:-30}
+#PTLDEBUG=${PTLDEBUG:-'"ha|info|ioctl|malloc"'}
+PTLDEBUG=${PTLDEBUG:-0}
+MOUNT=${MOUNT:-"/mnt/lustre"}
+UPCALL=${CLIENT_UPCALL:-`pwd`/replay-single-upcall.sh}
+
+MDSDEV=${MDSDEV:-/dev/sda1}
+MDSSIZE=${MDSSIZE:-50000}
+
+OSTDEV=${OSTDEV:-/tmp/ost-`hostname`}
+OSTSIZE=${OSTSIZE:=50000}
+FSTYPE=${FSTYPE:-ext3}
+STRIPE_BYTES=${STRIPE_BYTES:-1048576} 
+STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-0}
+
+FAILURE_MODE=${FAILURE_MODE:-HARD} # or HARD
+POWER_DOWN=${POWER_DOWN:-"powerman --off"}
+POWER_UP=${POWER_UP:-"powerman --on"}
+
+PDSH="pdsh -S -w "
diff --git a/lustre/tests/cfg/local.sh b/lustre/tests/cfg/local.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f9c5198873cafb6c3edd04689246ebff80859bb9
--- /dev/null
+++ b/lustre/tests/cfg/local.sh
@@ -0,0 +1,33 @@
+# oldstyle
+MDSNODE=${MDSNODE:-`hostname`}
+OSTNODE=${OSTNODE:-`hostname`}
+
+mds_HOST=${mds_HOST:-$MDSNODE}
+mdsfailover_HOST=${mdsfailover_HOST}
+ost_HOST=${ost_HOST:-$OSTNODE}
+ost2_HOST=${ost2_HOST:-$ost_HOST}
+client_HOST=${client_HOST:-"'*'"}
+NETTYPE=${NETTYPE:-tcp}
+
+MOUNT=${MOUNT:-"/mnt/lustre"}
+MOUNT1=${MOUNT1:-$MOUNT}
+MOUNT2=${MOUNT2:-"/mnt/lustre2"}
+DIR=${DIR:-$MOUNT}
+DIR2=${DIR2:-$MOUNT1}
+PTLDEBUG=${PTLDEBUG:-0}
+PDSH=${PDSH:-no_dsh}
+
+MDSDEV=${MDSDEV:-$ROOT/tmp/mds-`hostname`}
+MDSSIZE=${MDSSIZE:-10000}
+OSTDEV=${OSTDEV:-$ROOT/tmp/ost-`hostname`}
+OSTSIZE=${OSTSIZE:-10000}
+FSTYPE=${FSTYPE:-ext3}
+TIMEOUT=${TIMEOUT:-10}
+UPCALL=${UPCALL:-$PWD/replay-single-upcall.sh}
+
+STRIPE_BYTES=${STRIPE_BYTES:-65536}
+STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-0}
+
+FAILURE_MODE=${FAILURE_MODE:-SOFT} # or HARD
+POWER_DOWN=${POWER_DOWN:-"powerman --off"}
+POWER_UP=${POWER_UP:-"powerman --on"}
diff --git a/lustre/tests/cfg/mdev.sh b/lustre/tests/cfg/mdev.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ec8edf2f9bb7deb997f181570a65e43d8295ac66
--- /dev/null
+++ b/lustre/tests/cfg/mdev.sh
@@ -0,0 +1,30 @@
+
+mds_HOST=${mds_HOST:-mdev4}
+mdsfailover_HOST=${mdsfailover_HOST:-mdev5}
+ost_HOST=${ost_HOST:-mdev2}
+ost2_HOST=${ost2_HOST:-mdev3}
+client_HOST=${client_HOST:-client}
+NETTYPE=${NETTYPE:-tcp}
+
+MOUNT=${MOUNT:-"/mnt/lustre"}
+MOUNT1=${MOUNT1:-$MOUNT}
+MOUNT2=${MOUNT2:-"/mnt/lustre2"}
+DIR=${DIR:-$MOUNT}
+DIR2=${DIR2:-$MOUNT1}
+PTLDEBUG=${PTLDEBUG:-0}
+PDSH=${PDSH:-pdsh -S -w}
+
+MDSDEV=${MDSDEV:-/dev/sda1}
+MDSSIZE=${MDSSIZE:-50000}
+OSTDEV=${OSTDEV:-/tmp/ost-`hostname`}
+OSTSIZE=${OSTSIZE:-20000}
+FSTYPE=${FSTYPE:-ext3}
+TIMEOUT=${TIMEOUT:-10}
+UPCALL=${UPCALL:-$PWD/replay-single-upcall.sh}
+
+STRIPE_BYTES=${STRIPE_BYTES:-65536}
+STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-0}
+
+FAILURE_MODE=${FAILURE_MODE:-SOFT} # or HARD
+POWER_DOWN=${POWER_DOWN:-"powerman --off"}
+POWER_UP=${POWER_UP:-"powerman --on"}
diff --git a/lustre/tests/checkstack.pl b/lustre/tests/checkstack.pl
index 9c0d0978ee51a643d4d05ff68c49ae879b76e47c..3504e96ac63cedf1cd5c439dec4483e44c660a0c 100644
--- a/lustre/tests/checkstack.pl
+++ b/lustre/tests/checkstack.pl
@@ -1,21 +1,21 @@
 #!/usr/bin/perl
-
 #	Check the stack usage of functions
 #
 #	Copyright Joern Engel <joern@wh.fh-wedel.de>
 #	Inspired by Linus Torvalds
 #	Original idea maybe from Keith Owens
+#	s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
+#	Modified to have simpler output format by Dan Kegel
 #
 #	Usage:
-#	objdump -d vmlinux | checkstack.pl <arch>
+#	objdump -d vmlinux | stackcheck.pl [arch]
 #
 #	find <moduledir> -name "*.o" | while read M; do
 #		objdump -d $M | perl ~/checkstack.pl <arch> | \
 #			sed "s/^/`basename $M`: /" ; done | \
 #	awk '/esp/ { print $5, $2, $4 }' | sort -nr
-#
+
 #	TODO :	Port to all architectures (one regex per arch)
-#		Speed this puppy up
 
 # check for arch
 # 
@@ -27,66 +27,57 @@
 # use anything else and feel the pain ;)
 {
 	my $arch = shift;
-	$x	= "[0-9a-f]";	# hex character
-	$xs	= "[0-9a-f ]";	# hex character or space
+	$x	= "[0-9a-f]{3,5}";		# hex number     >= 256
+	$d	= "([0-9]{2}|[2-9])[0-9]{2}";	# decimal number >= 200
+	if ($arch eq "") {
+		$arch = `uname -m`;
+	}
 	if ($arch =~ /^i[3456]86$/) {
 		#c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
-		$re = qr/^.*(sub/s\$(0x$x{3,5}),\%esp)$/o;
+		$re = qr/^.*(sub    \$(0x$x),\%esp)$/o;
+		$todec = sub { return hex($_[0]); };
 	} elsif ($arch =~ /^ia64$/) {
-		#                                        adds r12=-384,r12
-		$re = qr/.*(adds/sr12=-($x{3,5}),r12)/o;
+		#e0000000044011fc:       01 0f fc 8c     adds r12=-384,r12
+		$re = qr/.*(adds.*r12=-($d),r12)/o;
+		$todec = sub { return $_[0]; };
+	} elsif ($arch =~ /^mips64$/) {
+		#8800402c:       67bdfff0        daddiu  sp,sp,-16
+		$re = qr/.*(daddiu.*sp,sp,-($d))/o;
+		$todec = sub { return $_[0]; };
+	} elsif ($arch =~ /^mips$/) {
+		#88003254:       27bdffe0        addiu   sp,sp,-32
+		$re = qr/.*(addiu.*sp,sp,-($d))/o;
+		$todec = sub { return $_[0]; };
 	} elsif ($arch =~ /^ppc$/) {
 		#c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
-		$re = qr/.*(stwu/sr1,-($x{3,5})\(r1\))/o;
+		$re = qr/.*(stwu.*r1,-($x)\(r1\))/o;
+		$todec = sub { return hex($_[0]); };
 	} elsif ($arch =~ /^s390x?$/) {
 		#   11160:       a7 fb ff 60             aghi   %r15,-160
-		$re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
+		$re = qr/.*(ag?hi.*\%r15,-($d))/o;
+		$todec = sub { return $_[0]; };
 	} else {
-		print("wrong or unknown architecture\n");
-		exit
+		print "Usage:  objdump -d vmlinux | checkstack.pl [arch]\n";
+		print "where arch is i386, ia64, mips, mips64, ppc, or s390\n";
+		print "Each output line gives a function's stack usage, name\n";
+		print "Lines are output in order of decreasing stack usage\n";
+		die("wrong or unknown architecture\n");
 	}
 }
 
-sub bysize($) {
-	($asize = $a) =~ s/$re/\2/;
-	($bsize = $b) =~ s/$re/\2/;
-	$bsize <=> $asize
-}
-
-#
-# main()
-#
-$funcre = qr/^$x* \<(.*)\>:$/;
+$funcre = qr/^[0-9a-f]* \<(.*)\>:$/;
 while ($line = <STDIN>) {
 	if ($line =~ m/$funcre/) {
 		($func = $line) =~ s/$funcre/\1/;
 		chomp($func);
 	}
-
 	if ($line =~ m/$re/) {
-		(my $addr = $line) =~ s/^($xs{8}).*/0x\1/o;
-		chomp($addr);
-
-		my $intro = "$addr $func:";
-		my $padlen = 56 - length($intro);
-		while ($padlen > 0) {
-			$intro .= '	';
-			$padlen -= 8;
-		}
-		(my $code = $line) =~ s/$re/\1/;
-
-		$stack[@stack] = "$intro $code";
+		push(@stack, &$todec($2)." ".$func);
+		# don't expect more than one stack allocation per function
+		$func .= " ** bug **";
 	}
 }
 
-@sortedstack = sort bysize @stack;
-
-foreach $i (@sortedstack) {
-	print("$i");
+foreach (sort { $b - $a } (@stack)) {
+	print $_."\n";
 }
---
-Andreas Dilger
-http://sourceforge.net/projects/ext2resize/
-http://www-mddsp.enel.ucalgary.ca/People/adilger/
-
-
diff --git a/lustre/tests/cmknod.c b/lustre/tests/cmknod.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa42e2be04bf34c16f17bb573be70c796bd312a5
--- /dev/null
+++ b/lustre/tests/cmknod.c
@@ -0,0 +1,94 @@
+/* Simple test to check that device nodes are correctly created and visible */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#define TEST_MINOR 120
+#define TEST_MAJOR 25
+
+void usage(char *prog)
+{
+	fprintf(stderr, "usage: %s <filename>\n", prog);
+	exit(1);
+}
+
+int main( int argc, char **argv)
+{
+	char *prog = argv[0];
+	char *filename = argv[1];
+	int rc;
+	struct stat st;
+	dev_t device = makedev(TEST_MAJOR, TEST_MINOR);
+
+	if (argc != 2) 
+		usage(prog);
+
+	unlink(filename);
+	/* First try block devices */
+	rc = mknod(filename, 0700 | S_IFBLK, device);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 2;
+	}
+
+	rc = stat(filename, &st);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 3;
+	}
+	if ( st.st_rdev != device) {
+		fprintf(stderr, "%s: created device other than requested: (%d,%d) instead of (%d,%d)\n", prog, major(st.st_rdev),minor(st.st_rdev),major(device),minor(device));
+		return 4;
+	}
+	if ( ! (st.st_mode | S_IFBLK) ) {
+		fprintf(stderr, "%s: created device of different type. Requested block device, got mode %o\n", prog, st.st_mode);
+		return 5;
+	}
+
+	rc = unlink(filename);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 6;
+	}
+
+	/* Second try char devices */
+	rc = mknod(filename, 0700 | S_IFCHR, device);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 7;
+	}
+
+	rc = stat(filename, &st);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 8;
+	}
+	if ( st.st_rdev != device) {
+		fprintf(stderr, "%s: created device other than requested: (%d,%d) instead of (%d,%d)\n", prog, major(st.st_rdev),minor(st.st_rdev),major(device),minor(device));
+		return 9;
+	}
+	if ( ! (st.st_mode | S_IFCHR) ) {
+		fprintf(stderr, "%s: created device of different type. Requested char device, got mode %o\n", prog, st.st_mode);
+		return 10;
+	}
+
+	rc = unlink(filename);
+	if ( rc < 0 ) {
+		fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n",
+			prog, filename, errno, strerror(errno));
+		return 11;
+	}
+
+	printf("%s: device nodes created correctly\n", prog);
+
+	return 0;
+}
diff --git a/lustre/tests/compile.sh b/lustre/tests/compile.sh
index 13c142e28392058c39a99a1a8b1629e61d644d94..6b5ccd980fee5c02d6938ea38cbc131605fab4ca 100644
--- a/lustre/tests/compile.sh
+++ b/lustre/tests/compile.sh
@@ -5,7 +5,7 @@ MNT=${MNT:-/mnt/lustre}
 DIR=${DIR:-$MNT}
 SRC=${SRC:-`dirname $0`/../..}
 while date; do
-	for i in portals lustre; do
+	for i in lustre; do
 		TGT=$DIR/$i
 		[ -d $TGT ] || cp -av $SRC/$i/ $TGT
 		make -C $TGT clean
diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f71e39e4c814ef92c0ce1b41ff81d5a804694ca4
--- /dev/null
+++ b/lustre/tests/conf-sanity.sh
@@ -0,0 +1,216 @@
+#!/bin/bash
+# requirement:
+#	add uml1 uml2 uml3 in your /etc/hosts
+
+set -e
+
+SRCDIR=`dirname $0`
+PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$PATH
+
+LUSTRE=${LUSTRE:-`dirname $0`/..}
+RLUSTRE=${RLUSTRE:-$LUSTRE}
+
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
+
+. ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
+
+FORCE=${FORCE:-" --force"}
+
+gen_config() {
+	rm -f $XMLCONFIG
+
+	add_mds mds --dev $MDSDEV --size $MDSSIZE
+	add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
+	    --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+	add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE
+	add_client client mds --lov lov1 --path $MOUNT
+}
+
+gen_second_config() {
+	rm -f $XMLCONFIG
+
+	add_mds mds2 --dev $MDSDEV --size $MDSSIZE
+	add_lov lov2 mds2 --stripe_sz $STRIPE_BYTES\
+	    --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+	add_ost ost2 --lov lov2 --dev $OSTDEV --size $OSTSIZE
+	add_client client mds2 --lov lov2 --path $MOUNT2
+}
+
+start_mds() {
+	echo "start mds service on `facet_active_host mds`"
+	start mds --reformat $MDSLCONFARGS > /dev/null || return 94
+}
+stop_mds() {
+	echo "stop mds service on `facet_active_host mds`"
+	stop mds $@ > /dev/null || return 97 
+}
+
+start_ost() {
+	echo "start ost service on `facet_active_host ost`"
+	start ost --reformat $OSTLCONFARGS > /dev/null || return 95
+}
+
+stop_ost() {
+	echo "stop ost service on `facet_active_host ost`"
+	stop ost $@ > /dev/null || return 98 
+}
+
+mount_client() {
+	local MOUNTPATH=$1
+	echo "mount lustre on ${MOUNTPATH}....."
+	zconf_mount $MOUNTPATH > /dev/null || return 96
+}
+
+umount_client() {
+	local MOUNTPATH=$1
+	echo "umount lustre on ${MOUNTPATH}....."
+	zconf_umount $MOUNTPATH > /dev/null || return 97
+}
+
+manual_umount_client(){
+	echo "manual umount lustre on ${MOUNTPATH}...."
+	do_facet  client "umount $MOUNT"
+}
+
+setup() {
+	start_ost
+	start_mds
+	mount_client $MOUNT 
+}
+
+cleanup() {
+ 	umount_client $MOUNT || return -200
+	stop_mds  || return -201
+	stop_ost || return -202
+}
+
+check_mount() {
+	do_facet client "touch $DIR/a" || return 71	
+	do_facet client "rm $DIR/a" || return 72	
+	echo "setup single mount lustre success"
+}
+
+check_mount2() {
+	do_facet client "touch $DIR/a" || return 71	
+	do_facet client "rm $DIR/a" || return 72	
+	do_facet client "touch $DIR2/a" || return 73	
+	do_facet client "rm $DIR2/a" || return 74	
+	echo "setup double mount lustre success"
+}
+
+build_test_filter
+
+#create single point mountpoint
+
+gen_config
+
+
+test_0() {
+	start_ost
+	start_mds	
+	mount_client $MOUNT  
+	check_mount || return 41
+	cleanup  
+}
+run_test 0 "single mount setup"
+
+test_1() {
+	start_ost
+	echo "start ost second time..."
+	start ost --reformat $OSTLCONFARGS > /dev/null 
+	start_mds	
+	mount_client $MOUNT
+	check_mount || return 42
+	cleanup 
+}
+run_test 1 "start up ost twice"
+
+test_2() {
+	start_ost
+	start_mds	
+	echo "start mds second time.."
+	start mds --reformat $MDSLCONFARGS > /dev/null 
+	
+	mount_client $MOUNT  
+	check_mount || return 43
+	cleanup 
+}
+run_test 2 "start up mds twice"
+
+test_3() {
+        setup
+	mount_client $MOUNT
+
+	check_mount || return 44
+	
+ 	umount_client $MOUNT 	
+	cleanup  
+}
+run_test 3 "mount client twice"
+
+test_4() {
+	setup
+	touch $DIR/$tfile || return 85
+	stop_ost ${FORCE}
+
+	# cleanup may return an error from the failed 
+	# disconnects; for now I'll consider this successful 
+	# if all the modules have unloaded.
+	if ! cleanup ; then
+	    lsmod | grep -q portals && return 1
+        fi
+	return 0
+}
+run_test 4 "force cleanup ost, then cleanup"
+
+test_5() {
+	setup
+	touch $DIR/$tfile || return 86
+	stop_mds ${FORCE} || return 98
+
+	# cleanup may return an error from the failed 
+	# disconnects; for now I'll consider this successful 
+	# if all the modules have unloaded.
+	if ! cleanup ; then
+	    lsmod | grep -q portals && return 1
+        fi
+	return 0
+}
+run_test 5 "force cleanup mds, then cleanup"
+
+test_6() {
+	setup
+	manual_umount_client
+	mount_client ${MOUNT} || return 87
+	touch $DIR/a || return 86
+	cleanup 
+}
+run_test 6 "manual umount, then mount again"
+
+test_7() {
+	setup
+	manual_umount_client
+	cleanup 
+}
+run_test 7 "manual umount, then cleanup"
+
+test_8() {
+	start_ost
+	start_mds
+
+	mount_client $MOUNT  
+	mount_client $MOUNT2 
+
+	check_mount2 || return 45
+	umount $MOUNT
+	umount_client $MOUNT2  
+	
+	stop_mds
+	stop_ost
+}
+run_test 8 "double mount setup"
+
+
+equals_msg "Done"
diff --git a/lustre/tests/create.pl b/lustre/tests/create.pl
index c5f3f12129ca049196d15a3e83e272988ae28bce..848b4cc0446b9d46eaa3522f78108314d1d97548 100644
--- a/lustre/tests/create.pl
+++ b/lustre/tests/create.pl
@@ -12,11 +12,14 @@ use Getopt::Long;
 
 use vars qw(
 	    $MAX_THREADS
+	    $SCRIPT_NAME
 	    );
 
 # Don't try to run more than this many threads concurrently.
 $MAX_THREADS = 16;
 
+$SCRIPT_NAME = "create.pl";
+
 # Initialize variables
 my $silent = 0;
 my $use_mcreate = 1; # should we use mcreate or open?
@@ -113,15 +116,15 @@ sub fork_and_create ($) {
 		  }
 		  $d = int(rand() * $num_files);
 		  my $path = "${mountpt}${which}/thread${thread_num}.${d}";
-		  print  "Thread $thread_num: Unlink $path start [" . $$."]...\n" if !$silent;
+		  print  "$SCRIPT_NAME - Thread $thread_num: Unlink $path start [" . $$."]...\n" if !$silent;
 		  if (unlink($path)) {
-		      print "Thread $thread_num: Unlink done [$$] $path: Success\n" if !$silent;
+		      print "$SCRIPT_NAME - Thread $thread_num: Unlink done [$$] $path: Success\n" if !$silent;
 		  } else {
-		      print "Thread $thread_num: Unlink done [$$] $path: $!\n"if !$silent;
+		      print "$SCRIPT_NAME - Thread $thread_num: Unlink done [$$] $path: $!\n"if !$silent;
 		  }
 	      }
 	      if (($current_iteration) % 100 == 0) {
-		  print STDERR "Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
+		  print "$SCRIPT_NAME - Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
 	      }
 	      $current_iteration++;
 	  }
@@ -135,7 +138,7 @@ sub fork_and_create ($) {
 	      unlink("$path") if (-e $path);
 	  }
 	  
-	  print "Thread $thread_num: Done.\n";
+	  print "$SCRIPT_NAME - Thread $thread_num: Done.\n";
 	  
 	  exit 0;
 
@@ -159,16 +162,16 @@ sub do_open ($) {
     if ($use_mcreate) {
         my $tmp = `./mcreate $path`;
         if ($tmp) {
-            print  "Creating $path [" . $$."]...\n" if !$silent;
+            print  "$SCRIPT_NAME - Creating $path [" . $$."]...\n" if !$silent;
             $tmp =~ /.*error: (.*)\n/;
-            print  "Create done [$$] $path: $!\n" if !$silent;
+            print  "$SCRIPT_NAME - Create done [$$] $path: $!\n" if !$silent;
         } else {
-            print  "Create done [$$] $path: Success\n"if !$silent;
+            print  "$SCRIPT_NAME - Create done [$$] $path: Success\n"if !$silent;
         }
     } else {
-        print  "Opening $path [" . $$."]...\n"if !$silent;
+        print  "$SCRIPT_NAME - Opening $path [" . $$."]...\n"if !$silent;
         open(FH, ">$path") || die "open($path: $!";
-        print  "Open done [$$] $path: Success\n"if !$silent;
+        print  "$SCRIPT_NAME - Open done [$$] $path: Success\n"if !$silent;
         close(FH) || die;
     }
 }
diff --git a/lustre/tests/createmany-mpi.c b/lustre/tests/createmany-mpi.c
new file mode 100644
index 0000000000000000000000000000000000000000..1474b7ba6df0bfce24ad141c579da263f406eb00
--- /dev/null
+++ b/lustre/tests/createmany-mpi.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "mpi.h"
+
+void usage(char *prog)
+{
+	printf("usage: %s {-o|-m} filenamefmt count\n", prog);
+	printf("       %s {-o|-m} filenamefmt -seconds\n", prog);
+	printf("       %s {-o|-m} filenamefmt start count\n", prog);
+}
+
+/* Print process rank, loop count, message, and exit (i.e. a fatal error) */
+int rprintf(int rank, int loop, const char *fmt, ...)
+{
+        va_list       ap;
+
+        printf("rank %d, loop %d: ", rank, loop);
+
+        va_start(ap, fmt);
+
+        printf(fmt, ap);
+
+        MPI_Finalize();
+        exit(1);
+}
+
+int main(int argc, char ** argv)
+{
+        int i, rc = 0, do_open, rank;
+        char format[4096], *fmt;
+        char filename[4096];
+        long start, last, end;
+	long begin = 0, count;
+
+        rc = MPI_Init(&argc, &argv);
+        if (rc != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Init failed: %d\n", rc);
+
+        if (argc < 4 || argc > 5) {
+		usage(argv[0]);
+                return 1;
+        }
+
+        if (strcmp(argv[1], "-o") == 0) {
+                do_open = 1;
+        } else if (strcmp(argv[1], "-m") == 0) {
+                do_open = 0;
+        } else {
+		usage(argv[0]);
+                return 1;
+        }
+
+        if (strlen(argv[2]) > 4080) {
+                printf("name too long\n");
+                return 1;
+        }
+
+        rc = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+        if (rc != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Comm_rank failed: %d\n", rc);
+
+        rc = MPI_Barrier(MPI_COMM_WORLD);
+        if (rc != MPI_SUCCESS)
+                rprintf(rank, -1, "prep MPI_Barrier failed: %d\n", rc);
+
+        start = last = time(0);
+
+	if (argc == 4) {
+		end = strtol(argv[3], NULL, 0);
+		if (end > 0) {
+			count = end;
+			end = -1UL >> 1;
+		} else {
+			end = start - end;
+			count = -1UL >> 1;
+		}
+	} else {
+		end = -1UL >> 1;
+		begin = strtol(argv[3], NULL, 0);
+		count = strtol(argv[4], NULL, 0);
+	}
+
+	if (strchr(argv[2], '%'))
+		fmt = argv[2];
+	else {
+		sprintf(format, "%s%%d", argv[2]);
+		fmt = format;
+	}
+	printf("starting at %s", ctime(&start));
+        for (i = 0; i < count && time(0) < end; i++, begin++) {
+                sprintf(filename, fmt, begin);
+                if (do_open) {
+                        int fd = open(filename, O_CREAT|O_RDWR, 0644);
+                        if (fd < 0) {
+                                printf("open(%s) error: %s\n", filename,
+                                       strerror(errno));
+                                rc = errno;
+                                break;
+                        }
+                        close(fd);
+                } else {
+                        rc = mknod(filename, S_IFREG| 0444, 0);
+                        if (rc) {
+                                printf("mknod(%s) error: %s\n",
+                                       filename, strerror(errno));
+                                rc = errno;
+                                break;
+                        }
+                }
+                if ((i % 10000) == 0) {
+                        printf(" - created %d (time %ld ; total %ld ; last %ld)\n",
+                               i, time(0), time(0) - start, time(0) - last);
+                        last = time(0);
+                }
+        }
+        printf("total: %d creates in %ld seconds: %f creates/second\n", i,
+               time(0) - start, ((float)i / (time(0) - start)));
+	start = time(0);
+	printf("finish at %s", ctime(&start));
+
+        return rc;
+}
diff --git a/lustre/tests/directio.c b/lustre/tests/directio.c
index cc92c80254299ad8866b877b41ba6ab6a53da686..51315bc5c113114b36172ba21c77428baa3c259a 100644
--- a/lustre/tests/directio.c
+++ b/lustre/tests/directio.c
@@ -1,3 +1,7 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#define  _GNU_SOURCE
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -8,35 +12,33 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 
-// not correctly in the headers yet!!
-#ifndef O_DIRECT
-#define O_DIRECT         040000 /* direct disk access hint */
-#endif
-
 int main(int argc, char **argv)
 {
         int fd;
-        char *buf;
+        char *rbuf, *wbuf;
         int blocks, seek_blocks;
         long len;
         off64_t seek;
         struct stat64 st;
         int rc;
 
-        if (argc != 4) {
-                printf("Usage: %s file seek nr_blocks\n", argv[0]);
+        if (argc < 4 || argc > 5) {
+                printf("Usage: %s file seek nr_blocks [blocksize]\n", argv[0]);
                 return 1;
         }
 
         seek_blocks = strtoul(argv[2], 0, 0);
         blocks = strtoul(argv[3], 0, 0);
+
         fd = open(argv[1], O_LARGEFILE | O_DIRECT | O_RDWR | O_CREAT, 0644);
         if (fd == -1) {
                 printf("Cannot open %s:  %s\n", argv[1], strerror(errno));
                 return 1;
         }
 
-        if (fstat64(fd, &st) < 0) {
+        if (argc == 5)
+                st.st_blksize = strtoul(argv[4], 0, 0);
+        else if (fstat64(fd, &st) < 0) {
                 printf("Cannot stat %s:  %s\n", argv[1], strerror(errno));
                 return 1;
         }
@@ -51,14 +53,20 @@ int main(int argc, char **argv)
         }
 
         len = blocks * st.st_blksize;
-        buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
-        if (!buf) {
+        wbuf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+        if (wbuf == MAP_FAILED) {
                 printf("No memory %s\n", strerror(errno));
                 return 1;
         }
 
-        memset(buf, 0xba, len);
-        rc = write(fd, buf, len);
+        rbuf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+        if (rbuf == MAP_FAILED) {
+                printf("No memory %s\n", strerror(errno));
+                return 1;
+        }
+
+        memset(wbuf, 0xba, len);
+        rc = write(fd, wbuf, len);
         if (rc != len) {
                 printf("Write error %s (rc = %d)\n", strerror(errno), rc);
                 return 1;
@@ -69,12 +77,17 @@ int main(int argc, char **argv)
                 return 1;
         }
 
-        rc = read(fd, buf, len);
+        rc = read(fd, rbuf, len);
         if (rc != len) {
                 printf("Read error: %s (rc = %d)\n", strerror(errno), rc);
                 return 1;
         }
 
-	printf("PASS\n");
+        if (memcmp(wbuf, rbuf, len)) {
+                printf("Data mismatch\n");
+                return 1;
+        }
+
+        printf("PASS\n");
         return 0;
 }
diff --git a/lustre/tests/echo.sh b/lustre/tests/echo.sh
index b4fe5a49f814d37f76fc6054b1f7fc4e70773163..67dd27ea525a7afc30bcfa9df4e24a7f73be2277 100755
--- a/lustre/tests/echo.sh
+++ b/lustre/tests/echo.sh
@@ -16,10 +16,22 @@ TMP=${TMP:-/tmp}
 SERVER=${SERVER:-localhost}
 CLIENT=${CLIENT:-localhost}
 NET=${NET:-tcp}
-SERVERNID=${SERVERNID:-$SERVER}
-CLIENTNID=${CLIENTNID:-$CLIENT}
 
+h2tcp () {
+	case $1 in
+	client) echo '\*' ;;
+	*) echo $1 ;;
+	esac
+}
 
+h2gm () {
+	echo `gmnalnid -n $1`
+}
+
+h2elan () {
+    echo $1 | sed 's/[^0-9]*//g'
+}
+        
 # FIXME: make LMC not require MDS for obdecho LOV
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
 MDSSIZE=10000
@@ -31,7 +43,7 @@ STRIPES_PER_OBJ=2	# 0 means stripe over all OSTs
 rm -f $config
 # create nodes
 $LMC --add node --node $SERVER  || exit 1
-$LMC --add net --node $SERVER --nid $SERVERNID --nettype $NET || exit 2
+$LMC --add net --node $SERVER --nid `h2$NET $SERVER` --nettype $NET || exit 2
 
 if (($LOV)); then
     $LMC --add mds --node $SERVER --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 10
@@ -46,7 +58,7 @@ fi
 
 if [ "$SERVER" != "$CLIENT" ]; then
    $LMC --add node --node $CLIENT  || exit 1
-   $LMC --add net --node $CLIENT --nid $CLIENTNID --nettype $NET || exit 2
+   $LMC --add net --node $CLIENT --nid `h2$NET $CLIENT` --nettype $NET || exit 2
 fi
 
 $LMC --add echo_client --node $CLIENT --ost ${OBD_NAME} || exit 3
diff --git a/lustre/tests/filter_survey.sh b/lustre/tests/filter_survey.sh
new file mode 100644
index 0000000000000000000000000000000000000000..bc1b82d3f92b67efdad67dbb9b75f25967697815
--- /dev/null
+++ b/lustre/tests/filter_survey.sh
@@ -0,0 +1,263 @@
+#!/bin/sh
+#
+# this runs prep/commit against filters and generates a
+# table of their write timings.  it needs the names
+# of the filters it will run against and needs the
+# obdecho module loaded.  it spews a lot of junk
+# as it goes, only the last bit is really interesting; 
+# tee it to a log file.
+#
+# ex: FILTER_NAMES="ost1 ost2" sh ./filter_survey.sh
+#
+SRCDIR="`dirname $0`/"
+export PATH=$SRCDIR/../utils:/sbin:/usr/sbin::$PATH
+
+tmp_dir=""
+echo_base="f_s_$$"
+echo_objs=""
+
+die() {
+	echo $* 1>&2
+	exit 1
+}
+
+cleanup() {
+	[ ! -z "$tmp_dir" ] && [ -d $tmp_dir ] && rm -rf $tmp_dir
+	[ -z "$echo_objs" ] && exit 0
+	for obj in $echo_objs; do
+		echo cleaning up $obj
+# I can't believe leading whitespace matters here.
+lctl << EOF
+device $obj
+cleanup
+detach
+quit
+EOF
+	done
+}
+trap cleanup EXIT
+
+not_a_filter() {
+	lctl device_list | awk "/obdfilter $1/ {exit 1}"
+	return $?
+}
+
+# holy crap are these confusing
+sep1="||||"
+sep2="||"
+sep3=""
+sep4="||||"
+
+#
+# build up echo_clients attached to the given filters and record
+# their names and obj numbers for later use and teardown
+#
+last_filter="-1"
+[ -z "$FILTER_NAMES" ] && die "please specify filter names to run against"
+for fn in $FILTER_NAMES; do
+	if not_a_filter $fn; then
+		die "'$fn' isn't the name of an obdfilter device"
+	fi
+	en="${echo_base}_$fn"
+lctl << EOF
+	newdev
+	attach echo_client $en ${en}_uuid
+	setup $fn
+	probe
+	quit
+EOF
+	[ $? -eq 0 ] || die "error setting up echo_client (is obdecho loaded?)"
+
+	obj=`lctl device_list | awk "/echo_client $en/ {print "'$1}'`
+	[ -z "$obj" ] && die "couldn't find my echo_client's object number"
+	echo setup echo_client name $en as object $obj
+	echo_objs="$echo_objs $obj"
+
+	last_filter=$(($last_filter + 1))
+	echo_names[$last_filter]=$en
+
+	# build up the seperators we'll use in generating the wiki
+	sep1="$sep1||||"
+	sep2="$sep2||"
+	sep3="$sep3||"
+	sep4="$sep4||"
+done
+
+
+doit() {
+        $*
+}
+nop() {
+        local nothing;
+}
+if which opcontrol; then
+        echo generating oprofile results
+        oprofile=doit
+else
+        echo not using oprofile
+        oprofile=nop
+fi
+ 
+tmp_dir=`mktemp -d /tmp/echo_client_survey_XXXXXX` || die "mktemp failed"
+
+TOT_PAGES=${TOT_PAGES:-524288}
+
+throughput() {
+	local threads="$1"
+	local pages="$2"
+	local time="$3"
+	local tp=`echo 'scale=2; '$threads' * '$pages' * 4096 / ('$time' * 1024 * 1024)' | bc`
+	echo $tp
+}
+
+wait_for_idle_io() {
+	echo "waiting idle io via vmstat"
+	vmstat 1 | awk '
+        ($10 == 0 && $11 == 0) {
+                idle++;
+                if (idle == 3) {
+                        print "idle for 3 seconds, must be done"
+                        exit
+                }
+        }
+        (NR == 13) {
+                "deletion took longer than 10s, bailing";
+                exit
+        } '
+}
+
+#
+# sorry for the wild indenting.  get a wide terminal, its 2003.
+#
+num_rows="0"
+num_summary_rows="0"
+for order_threads in `seq 0 3`; do 
+	nthreads=$(echo "2^$order_threads" | bc)
+
+	for stride in 16 64 128; do 
+		span="<|$(($nthreads +1))>"
+		row="||$span $nthreads||$span $stride||"
+		sum_row="||$nthreads||$stride||"
+
+		for t in `seq 1 $nthreads`; do
+			thread_row[$t]="||"
+		done
+
+		for obj_per_thread in y n; do
+			if [ $obj_per_thread == "y" ]; then
+				offset_prefix=""
+				objid_prefix="t";
+			else 
+				offset_prefix="t"
+				objid_prefix="";
+			fi
+
+			# create the objects that this write/rewrite run
+			# will be using
+			for i in `seq 0 $last_filter`; do
+				oid=`lctl --device "\$"${echo_names[$i]} create $nthreads | \
+					awk '/1 is object id/ { print $6 }'`
+				[ -z "$oid" ] && die "error creating object"
+				oids[$i]=$oid
+			done
+
+			# iterate through write and rewrite
+			for a in 1 2; do
+				total_maxtime="0.0"
+				pids=""
+
+				$oprofile opcontrol --start				
+
+				echo 'nice -19 vmstat 5' > $tmp_dir/vmstat-log
+				nice -19 vmstat 5 >> $tmp_dir/vmstat-log &
+				vmstat_pid="$!"
+
+				$oprofile opcontrol --reset
+
+				# start a test_brw thread in the background
+				# for each given filter
+				for i in `seq 0 $last_filter`; do
+					lctl --threads $nthreads v "\$"${echo_names[$i]} \
+						test_brw ${offset_prefix}1 w v \
+						$TOT_PAGES ${objid_prefix}${oids[$i]} p$stride | \
+							tee $tmp_dir/$i &
+					pids="$pids $!"
+				done
+				echo ------ waiting for $nthreads obj per thread $obj_per_thread rw: $a ----
+				for p in $pids; do 
+					wait $p
+				done
+				$oprofile opcontrol --shutdown
+				echo ------ finished $nthreads obj per thread $obj_per_thread rw: $a ----
+				kill $vmstat_pid
+				cat $tmp_dir/vmstat-log
+				rm $tmp_dir/vmstat-log
+
+			        $oprofile opreport
+				$oprofile opreport -c -l
+
+				for t in `seq 1 $nthreads`; do
+					thread_row[$t]="${thread_row[$t]} ||"
+				done
+				row_tmp=""
+				for i in `seq 0 $last_filter`; do
+					maxtime="0.0"
+					for t in `seq 1 $nthreads`; do
+						f="$tmp_dir/$i"
+						MS=`grep "test_brw-$t" $f | \
+						   awk '($8=="MB/s):"){print $6, substr($7,2);}'`
+						thread_row[$t]="${thread_row[$t]}$MS||"
+						time=`echo $MS | cut -d s -f 1`
+						if [ `echo "$time > $maxtime" | bc` -eq "1" ]; then
+							maxtime=$time;
+						fi
+					done
+					tp=`throughput $nthreads $TOT_PAGES $maxtime`
+					row_tmp="${row_tmp}<#ffffe0>$tp $maxtime||"
+					sum_row="${sum_row}$tp||"
+
+					if [ `echo "$maxtime > $total_maxtime" | bc` -eq "1" ]; then
+						total_maxtime=$maxtime;
+					fi
+				done
+				tp=`throughput $(($nthreads * $(($last_filter +1)))) $TOT_PAGES $total_maxtime`
+				row="${row}<#ffffe0>${tp} $total_maxtime||${row_tmp}"
+			done
+
+			# destroy the objects from this run and wait for
+			# their destruction to complete 
+			for i in `seq 0 $last_filter`; do
+				lctl --device "\$"${echo_names[$i]} destroy ${oids[$i]} $nthreads
+			done
+			wait_for_idle_io
+		done
+
+		num_rows=$(($num_rows + 1))
+		rows[$num_rows]="$row"
+
+		num_summary_rows=$(($num_summary_rows + 1))
+		summary[$num_summary_rows]="$sum_row"
+
+		for t in `seq 1 $nthreads`; do
+			num_rows=$(($num_rows + 1))
+			rows[$num_rows]="${thread_row[$t]}"
+		done
+	done
+done
+
+echo done.
+
+bg='<rowbgcolor="#eoeoff"'
+echo "||$bg|2>threads writing $TOT_PAGES pages||<|2>pages per prep/commit${sep1}oid per thread${sep1}shared oid||"
+echo "$sep2$bg>write${sep2}re-write${sep2}write${sep2}re-write||"
+for r in `seq 1 $num_rows`; do
+	echo ${rows[$r]}
+done
+
+echo summary table
+
+echo "||$bg|2>threads||<|2>pages ${sep4}oid/thread${sep4}shared oid||"
+echo "$sep3$bg>write${sep3}re-write${sep3}write${sep3}re-write||"
+for r in `seq 1 $num_summary_rows`; do
+	echo ${summary[$r]}
+done
diff --git a/lustre/tests/fsx.c b/lustre/tests/fsx.c
index 92a23426863b5c68c9760235878ebe6ab046d317..8524c91f173f48f7167dcef7763ce8e0dc1135b9 100644
--- a/lustre/tests/fsx.c
+++ b/lustre/tests/fsx.c
@@ -524,8 +524,8 @@ domapread(unsigned offset, unsigned size)
 	pg_offset = offset & page_mask;
 	map_size  = pg_offset + size;
 
-	if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd,
-			      (off_t)(offset - pg_offset))) == (char *)-1) {
+	if ((p = mmap(0, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd,
+		      (off_t)(offset - pg_offset))) == MAP_FAILED) {
 	        prterr("domapread: mmap");
 		report_failure(190);
 	}
@@ -698,9 +698,8 @@ domapwrite(unsigned offset, unsigned size)
 	pg_offset = offset & page_mask;
 	map_size  = pg_offset + size;
 
-	if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE,
-			      MAP_FILE | MAP_SHARED, fd,
-			      (off_t)(offset - pg_offset))) == (char *)-1) {
+	if ((p = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_FILE|MAP_SHARED,
+		      fd, (off_t)(offset - pg_offset))) == MAP_FAILED) {
 	        prterr("domapwrite: mmap");
 		report_failure(202);
 	}
diff --git a/lustre/tests/insanity.sh b/lustre/tests/insanity.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7a9b58f40e7901973fd86e4e5fe828af19e50c06
--- /dev/null
+++ b/lustre/tests/insanity.sh
@@ -0,0 +1,541 @@
+#!/bin/sh
+# Test multiple failures, AKA Test 17
+
+set -e
+
+LUSTRE=${LUSTRE:-`dirname $0`/..}
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
+
+. ${CONFIG:=$LUSTRE/tests/cfg/insanity-local.sh}
+
+ALWAYS_EXCEPT=""
+
+build_test_filter
+
+assert_env mds_HOST ost1_HOST ost2_HOST client_HOST LIVE_CLIENT 
+
+# This can be a regexp, to allow more clients
+CLIENTS=${CLIENTS:-"`comma_list $LIVE_CLIENT $FAIL_CLIENTS`"}
+
+CLIENTLIST="$LIVE_CLIENT $FAIL_CLIENTS"
+
+DIR=${DIR:-$MOUNT}
+
+#####
+# fail clients round robin
+
+# list of failable clients
+FAIL_LIST=($FAIL_CLIENTS)
+FAIL_NUM=${#FAIL_LIST[*]}
+FAIL_NEXT=0
+DOWN_NUM=0   # number of nodes currently down
+
+# return next client to fail
+fail_client() {
+    ret=${FAIL_LIST[$FAIL_NEXT]}
+    FAIL_NEXT=$(( (FAIL_NEXT+1) % FAIL_NUM ))
+    echo $ret
+}
+
+shutdown_client() {
+    client=$1
+    if [ "$FAILURE_MODE" = HARD ]; then
+       $POWER_DOWN $client
+    elif [ "$FAILURE_MODE" = SOFT ]; then
+       $PDSH $client $LCONF --clenaup --force --nomod $XMLCONFIG
+    fi
+}
+
+reboot_node() {
+    NODE=$1
+    if [ "$FAILURE_MODE" = HARD ]; then
+       $POWER_UP $NODE
+    fi
+}
+
+fail_clients() {
+    num=$1
+    if [ -z "$num" -o $num -gt $((FAIL_NUM - DOWN_NUM)) ]; then
+	num=$((FAIL_NUM - DOWN_NUM)) 
+    fi
+    
+    if [ -z "$num"  -o $num -le 0 ]; then
+        return
+    fi
+
+    for i in `seq $num`; do
+       client=`fail_client`
+       DOWN_CLIENTS="$DOWN_CLIENTS $client"
+       client_mkdirs
+       shutdown_client $client
+    done
+
+    for client in $DOWN_CLIENTS; do
+	reboot_node $client
+    done
+    DOWN_NUM=`echo $DOWN_CLIENTS | wc -w`
+    $PDSH $LIVE_CLIENT "cd $MOUNT && rmdir $CLIENTLIST"
+}
+
+reintegrate_clients() {
+    for client in $DOWN_CLIENTS; do
+	wait_for_host $client
+	$PDSH $client "$LCONF --node client --select mds_svc=`facet_active mds` $CLIENTOPTS $XMLCONFIG"
+    done
+    DOWN_CLIENTS=""
+    DOWN_NUM=0
+}
+
+gen_config() {
+    rm -f $XMLCONFIG
+    add_mds mds --dev $MDSDEV --size $MDSSIZE
+
+    if [ ! -z "$mdsfailover_HOST" ]; then
+	 add_mdsfailover mds --dev $MDSDEV --size $MDSSIZE
+    fi
+
+    add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
+	--stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+    add_ost ost1 --lov lov1 --dev $OSTDEV --size $OSTSIZE
+    add_ost ost2 --lov lov1 --dev ${OSTDEV}-2 --size $OSTSIZE
+    add_client client mds --lov lov1 --path $MOUNT
+}
+
+setup() {
+    wait_for ost1
+    start ost1 ${REFORMAT} $OSTLCONFARGS 
+    wait_for ost2
+    start ost2 ${REFORMAT} $OSTLCONFARGS 
+    [ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+    wait_for mds
+    start mds $MDSLCONFARGS ${REFORMAT}
+    while ! $PDSH $HOST "ls -ld $LUSTRE"; do sleep 5; done
+    do_node $CLIENTS lconf --node client_facet \
+	--select mds_service=$ACTIVEMDS $XMLCONFIG
+}
+
+cleanup() {
+    # make sure we are using the primary MDS, so the config log will
+    # be able to clean up properly.
+    activemds=`facet_active mds`
+#    if [ $activemds != "mds" ]; then
+#        fail mds
+#    fi
+    for node in $CLIENTS; do
+	do_node $node lconf ${FORCE} --select mds_svc=${activemds}_facet --cleanup --node client_facet $XMLCONFIG || true
+    done
+
+    stop mds ${FORCE} $MDSLCONFARGS
+    stop ost1 ${FORCE}
+    stop ost2 ${FORCE} --dump cleanup.log
+}
+
+trap exit INT
+
+client_mkdirs() {
+   $PDSH $CLIENTS "mkdir $MOUNT/\`hostname\`; ls $MOUNT/\`hostname\` > /dev/null"
+}
+
+clients_recover_osts() {
+    facet=$1
+    $PDSH $CLIENTS "$LCTL "'--device %OSC_`hostname`_OST_'"${facet}_svc_MNT_client recover"
+}
+
+if [ "$ONLY" == "cleanup" ]; then
+    cleanup
+    exit
+fi
+
+gen_config
+setup
+
+if [ "$ONLY" == "setup" ]; then
+    exit 0
+fi
+
+# 9 Different Failure Modes Combinations
+echo "Starting Test 17 at `date`"
+
+test_0() {
+    echo "Failover MDS"
+    facet_failover mds
+    wait $DFPID || return 1
+
+    echo "Failing OST1"
+    facet_failover ost1
+    wait $DFPID || return 2
+
+    echo "Failing OST2"
+    facet_failover ost2
+    wait $DFPID || return 3
+    return 0
+}
+run_test 0 "Fail all nodes, independently"
+
+############### First Failure Mode ###############
+test_1() {
+echo "Don't do a MDS - MDS Failure Case"
+echo "This makes no sense"
+# FIXME every test makes sense
+}
+run_test 1 "MDS/MDS failure"
+###################################################
+
+############### Second Failure Mode ###############
+test_2() {
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+
+    echo "Failing MDS"
+    shutdown_facet mds
+    reboot_facet mds
+
+    # prepare for MDS failover
+    change_active mds
+    reboot_facet mds
+
+    client_df &
+    DFPID=$!
+    sleep 5
+
+    echo "Failing OST"
+    shutdown_facet ost1
+
+    echo "Reintegrating OST"
+    reboot_facet ost1
+    wait_for ost1
+    start ost1
+
+    echo "Failover MDS"
+    wait_for mds
+    start mds
+
+    #Check FS
+    wait $DFPID
+    clients_recover_osts ost1
+    echo "Verify reintegration"
+    client_df
+
+}
+run_test 2 "Second Failure Mode: MDS/OST `date`"
+###################################################
+
+
+############### Third Failure Mode ###############
+test_3() {
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    
+    #MDS Portion
+    facet_failover mds
+    wait $DFPID || echo df failed: $?
+    #Check FS
+
+    echo "Test Lustre stability after MDS failover"
+    client_df
+
+    #CLIENT Portion
+    echo "Failing 2 CLIENTS"
+    fail_clients 2
+    
+    #Check FS
+    echo "Test Lustre stability after CLIENT failure"
+    client_df
+    
+    #Reintegration
+    echo "Reintegrating CLIENTS"
+    reintegrate_clients
+
+    client_df
+}
+run_test 3  "Thirdb Failure Mode: MDS/CLIENT `date`"
+###################################################
+
+############### Fourth Failure Mode ###############
+test_4() {
+    echo "Fourth Failure Mode: OST/MDS `date`"
+
+    #OST Portion
+    echo "Failing OST ost1"
+    shutdown_facet ost1
+ 
+    #Check FS
+    echo "Test Lustre stability after OST failure"
+    client_df
+
+    #MDS Portion
+    echo "Failing MDS"
+    shutdown_facet mds
+    reboot_facet mds
+
+    # prepare for MDS failover
+    change_active mds
+    reboot_facet mds
+
+    client_df &
+    DFPID=$!
+    sleep 5
+
+    #Reintegration
+    echo "Reintegrating OST"
+    reboot_facet ost1
+    wait_for ost1
+    start ost1
+    
+    echo "Failover MDS"
+    wait_for mds
+    start mds
+    #Check FS
+    
+    wait $DFPID
+    clients_recover_osts ost1
+    echo "Test Lustre stability after MDS failover"
+    client_df
+}
+run_test 4 "Fourth Failure Mode: OST/MDS `date`"
+###################################################
+
+############### Fifth Failure Mode ###############
+test_5() {
+    echo "Fifth Failure Mode: OST/OST `date`"
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    
+    #OST Portion
+    echo "Failing OST"
+    shutdown_facet ost1
+    reboot_facet ost1
+    
+    #Check FS
+    echo "Test Lustre stability after OST failure"
+    client_df
+    
+    #OST Portion
+    echo "Failing OST"
+    shutdown_node ost2
+    reboot_facet ost2
+
+    #Check FS
+    echo "Test Lustre stability after OST failure"
+    client_df
+
+    #Reintegration
+    echo "Reintegrating OSTs"
+    wait_for ost1
+    wait_for ost1
+    start ost1
+    start ost2
+    
+    clients_recover_osts ost1
+    clients_recover_osts ost2
+    client_df
+}
+run_test 5 "Fifth Failure Mode: OST/OST `date`"
+###################################################
+
+############### Sixth Failure Mode ###############
+test_6() {
+    echo "Sixth Failure Mode: OST/CLIENT `date`"
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+	
+    #OST Portion
+    echo "Failing OST"
+    shutdown_node ost1
+    reboot_facet ost1
+
+    #Check FS
+    echo "Test Lustre stability after OST failure"
+    client_df
+
+    #CLIENT Portion
+    echo "Failing CLIENTs"
+    fail_clients
+    
+    #Check FS
+    echo "Test Lustre stability after CLIENTs failure"
+    client_df
+    
+    #Reintegration
+    echo "Reintegrating OST/CLIENTs"
+    wait_for ost1
+    start ost1
+    reintegrate_clients
+    
+    echo "Verifying mount"
+    client_df
+}
+run_test 6 "Sixth Failure Mode: OST/CLIENT `date`"
+###################################################
+
+
+############### Seventh Failure Mode ###############
+test_7() {
+    echo "Seventh Failure Mode: CLIENT/MDS `date`"
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+
+    #CLIENT Portion
+    echo "Part 1: Failing CLIENT"
+    fail_clients 2
+    
+    #Check FS
+    echo "Test Lustre stability after CLIENTs failure"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+    
+    #Sleep
+    echo "Wait 1 minutes"
+    sleep 60
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+
+    #MDS Portion
+    echo "Failing MDS"
+    facet_failover mds
+
+    #Check FS
+    echo "Test Lustre stability after MDS failover"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+
+    #Reintegration
+    echo "Reintegrating CLIENTs"
+    reintegrate_clients
+    client_df
+    
+    #Sleep
+    echo "wait 1 minutes"
+    sleep 60
+}
+run_test 7 "Seventh Failure Mode: CLIENT/MDS `date`"
+###################################################
+
+
+############### Eighth Failure Mode ###############
+test_8() {
+    echo "Eighth Failure Mode: CLIENT/OST `date`"
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+	
+    #CLIENT Portion
+    echo "Failing CLIENTs"
+    fail_clients 2
+
+    #Check FS
+    echo "Test Lustre stability after CLIENTs failure"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+
+    #Sleep
+    echo "Wait 1 minutes"
+    sleep 60
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+
+    #OST Portion
+    echo "Failing OST"
+    shutdown_node ost1
+    reboot_facet ost1
+
+    #Check FS
+    echo "Test Lustre stability after OST failure"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+    
+    #Reintegration
+    echo "Reintegrating CLIENTs/OST"
+    reintegrate_clients
+    start ost1
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/CLIENT_OST_2\`hostname\`_testfile"
+
+    #Sleep
+    echo "Wait 1 minutes"
+    sleep 60
+}
+run_test 8 "Eighth Failure Mode: CLIENT/OST `date`"
+###################################################
+
+
+############### Ninth Failure Mode ###############
+test_9() {
+    echo 
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+	
+    #CLIENT Portion
+    echo "Failing CLIENTs"
+    fail_clients 2
+
+    #Check FS
+    echo "Test Lustre stability after CLIENTs failure"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+
+    #Sleep
+    echo "Wait 1 minutes"
+    sleep 60
+
+    #Create files
+    echo "Verify Lustre filesystem is up and running"
+    client_df
+    $PDSH $CLIENTS "/bin/touch $MOUNT/\`hostname\`_testfile"
+
+    #CLIENT Portion
+    echo "Failing CLIENTs"
+    fail_clients 2
+    
+    #Check FS
+    echo "Test Lustre stability after CLIENTs failure"
+    client_df
+    $PDSH $LIVE_CLIENT "ls -l $MOUNT"
+    $PDSH $LIVE_CLIENT "rm -f $MOUNT/*_testfile"
+
+    #Reintegration
+    echo "Reintegrating  CLIENTs/CLIENTs"
+    reintegrate_clients
+    client_df
+    
+    #Sleep
+    echo "Wait 1 minutes"
+    sleep 60
+}
+run_test 9 "Ninth Failure Mode: CLIENT/CLIENT `date`"
+###################################################
+
+test_10() {
+    #Run availability after all failures
+    ./availability.sh  21600
+}
+run_test 10 "Running Availability for 6 hours..."
+
+equals_msg "Done, cleaning up"
+cleanup
diff --git a/lustre/tests/leak_finder.pl b/lustre/tests/leak_finder.pl
index 745f11350c5019eea80947b36015bc3ebf9906a1..5219996d2515113fd7e61796fc32ccad0849a57b 100644
--- a/lustre/tests/leak_finder.pl
+++ b/lustre/tests/leak_finder.pl
@@ -14,15 +14,15 @@ my $max = 0;
 while ($line = <>) {
     $debug_line++;
     my ($file, $func, $lno, $name, $size, $addr, $type);
-    if ($line =~ m/^.*\((.*):(\d+):(.*)\(\) (\d+ \| )?\d+\+\d+\): (k|v|slab-)(.*) '(.*)': (\d+) at (.*) \(tot (.*)\).*$/) {
-        $file = $1;
-        $lno = $2;
-        $func = $3;
+    if ($line =~ m/^.*(\.).*\((.*):(\d+):(.*)\(\)\) (k|v|slab-)(.*) '(.*)': (\d+) at (.*) \(tot (.*)\).*$/){
+        $file = $2;
+        $lno  = $3;
+        $func = $4;
         $type = $6;
         $name = $7;
         $size = $8;
         $addr = $9;
-        $tot = $10;
+        $tot  = $10;
 
 	# we can't dump the log after portals has exited, so skip "leaks"
 	# from memory freed in the portals module unloading.
@@ -86,4 +86,4 @@ foreach $key (@sorted) {
     print STDERR "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n";
 }
 
-print "maximum used: $max, amount leaked: $total\n";
+print STDERR "maximum used: $max, amount leaked: $total\n";
diff --git a/lustre/tests/liblustre_sanity_uml.sh b/lustre/tests/liblustre_sanity_uml.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9ba1798e21510d8fd7ac4742a21ac49684ecdcfa
--- /dev/null
+++ b/lustre/tests/liblustre_sanity_uml.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+# liblustre sanity test. specially written for UML for now
+
+LCONF=${LCONF:-../utils/lconf}
+
+LLIP=127.0.0.1
+
+LTREE_KERNEL=${LTREE_KERNEL:-../../lustre}
+LTREE_USER=${LTREE_USER:-../../lustre-lib}
+
+# checking
+if [ ! -e $LTREE_KERNEL ]; then
+	echo "$LTREE_KERNEL dosen't exits"
+	exit 1
+fi
+
+if [ ! -e $LTREE_USER ]; then
+	echo "$LTREE_USER dosen't exits"
+	exit 1
+fi
+
+if [ ! -e $LTREE_USER/liblustre/lltest ]; then
+	echo "$LTREE_USER/liblustre/lltest dosen't exits"
+	exit 1
+fi
+
+workdir=`pwd`
+
+cleanup()
+{
+	curdir=`pwd`
+	cd $LTREE_KERNEL/tests
+	$LCONF --node localhost --cleanup --force $LTREE_USER/tests/$configfile 2>&1 > /dev/null
+	cd $curdir
+}
+
+configfile=liblustre_sanity_uml.xml
+
+# generate config file
+rm -f $configfile
+MDSNODE=localhost OSTNODES=localhost CLIENTS=$LLIP sh uml.sh $configfile
+if [ ! -e $configfile ]; then
+	echo "fail to generate config file $configfile"
+	exit 1
+fi
+
+# generate dump file
+rm -f /tmp/DUMP_FILE
+$LCONF --lctl_dump /tmp/DUMP_FILE --node $LLIP $configfile
+if [ ! -e /tmp/DUMP_FILE ]; then
+	echo "error creating dumpfile"
+	exit 1
+fi
+
+#setup lustre server
+cd $LTREE_KERNEL/tests
+$LCONF --node localhost --reformat $LTREE_USER/tests/$configfile
+rc=$?
+if [ $rc -ne 0 ]; then
+	echo "setup lustre server: error $rc"
+	cleanup
+	exit 1
+fi
+cd $workdir
+
+#do liblustre testing
+$LTREE_USER/liblustre/lltest
+rc=$?
+if [ $rc -ne 0 ]; then
+	echo "liblustre test error $rc"
+	cleanup
+	exit 1
+fi
+
+echo "===== liblustre sanity test complete sucessfully ====="
+
+echo -n "===== cleanup... "; cleanup; echo "done ====="
+
+cd $workdir
+
+exit 0
diff --git a/lustre/tests/ll_sparseness_verify.c b/lustre/tests/ll_sparseness_verify.c
new file mode 100644
index 0000000000000000000000000000000000000000..574f06449ed65ef9f0705ab3fa292bd356025ef6
--- /dev/null
+++ b/lustre/tests/ll_sparseness_verify.c
@@ -0,0 +1,102 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * The companion to ll_sparseness_write; walk all the bytes in the file.
+ * the bytes at the offsets specified on the command line must be '+', as
+ * previously written by ll_sparseness_write.  All other bytes must be
+ * 0.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#define BUFSIZE (1024*1024)    
+
+void error(char *fmt, ...)
+{
+        va_list ap;
+        va_start(ap, fmt);
+        vfprintf(stderr, fmt, ap);
+        va_end(ap);
+        exit(1);
+}
+
+int compare_offsets(const void *a, const void *b)
+{
+        off_t *A = (off_t *)a;
+        off_t *B = (off_t *)b;
+        return *A - *B;
+}
+
+int main(int argc, char **argv)
+{
+        unsigned int num_offsets, cur_off = 0, i;
+        off_t *offsets, pos = 0, end_of_buf = 0;
+        char *end, *buf;
+        struct stat st;
+        ssize_t ret;
+        int fd;
+
+        if (argc < 3)
+                error("Usage: %s <filename> <offset> [ offset ... ]\n", 
+                       argv[0]);
+
+        fd = open(argv[1], O_RDONLY);
+        if (fd < 0)
+                error("couldn't open %s: %s\n", argv[1], strerror(errno));
+
+        buf = malloc(BUFSIZE);
+        if (buf == NULL)
+                error("can't allocate buffer\n");
+
+        num_offsets = argc - 2;
+        offsets = calloc(sizeof(offsets[0]), num_offsets);
+        for (i = 0; i < num_offsets; i++) {
+                offsets[i] = strtoul(argv[i + 2], &end, 10);
+                if (*end) 
+                        error("couldn't parse offset '%s'\n", argv[i + 2]);
+        }
+        qsort(offsets, num_offsets, sizeof(offsets[0]), compare_offsets);
+
+        if (fstat(fd, &st) < 0)
+                error("stat: %s\n", strerror(errno));
+
+        for (i = 0; pos < st.st_size; i++, pos++) {
+                if (pos == end_of_buf) {
+                        ret = read(fd, buf, BUFSIZE);
+                        if (ret < 0)
+                                error("read(): %s\n", strerror(errno));
+                        end_of_buf = pos + ret;
+                        if (end_of_buf > st.st_size)
+                                error("read %d bytes past file size?\n",
+                                      end_of_buf - st.st_size);
+                        i = 0;
+                }
+
+                /* check for 0 when we aren't at a given offset */
+                if (cur_off >= num_offsets || pos != offsets[cur_off]) {
+                        if (buf[i] != 0) 
+                                error("found char 0x%x at pos %lu instead of "
+                                       "0x0\n", buf[i], (long)pos);
+                        continue;
+                }
+
+                /* the command line asks us to check for + at this offset */
+                if (buf[i] != '+') 
+                        error("found char 0x%x at pos %lu instead of "
+                               "'.'\n", buf[i], (long)pos);
+
+                /* skip over duplicate offset arguments */
+                while (cur_off < num_offsets && offsets[cur_off] == pos)
+                        cur_off++;
+        }
+        /* don't bother freeing or closing.. */
+        return 0;
+}
diff --git a/lustre/tests/ll_sparseness_write.c b/lustre/tests/ll_sparseness_write.c
new file mode 100644
index 0000000000000000000000000000000000000000..c53ca7e2da96daeceab543b062661d1befc5adae
--- /dev/null
+++ b/lustre/tests/ll_sparseness_write.c
@@ -0,0 +1,59 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define BUFSIZE (1024*1024)   
+
+/* Function: pwrite character '+' to <filename> at <offset> (man pwrite)
+ * Return:   0 success
+ *           1 failure */
+int main(int argc, char**argv)
+{
+        int p_size;
+        unsigned int offset;
+        char *filename;
+        int fd;
+        char buf[] = "+++";
+        char *end;
+
+        if(argc != 3) {
+                fprintf(stderr, "Usage: %s <filename> <offset>(KB)\n", argv[0]);
+                exit(1);
+        }
+
+        filename = argv[1];
+        offset = strtoul(argv[2], &end, 10);
+        if (*end) {
+                fprintf(stderr, "<offset> parameter should be integer\n");
+                exit(1);
+        }
+
+        fd = open(filename, O_CREAT|O_RDWR, 0644);
+        if (fd == -1) {
+                fprintf(stderr, "Opening %s fails (%s)\n", 
+                        filename, strerror(errno));
+                return 1;
+        }
+
+        /* write the character '+' at offset */
+        p_size = pwrite(fd, buf, 1, offset);
+        if (p_size != 1) {
+                fprintf(stderr, "pwrite %s fails (%s)\n", 
+                        filename, strerror(errno));
+                close(fd);
+                return 1;
+        }
+                
+        close(fd);
+        return 0;
+}
diff --git a/lustre/tests/llecho.sh b/lustre/tests/llecho.sh
index 3e3e03bd4e089bea72ec7c98a49a8f56b470b0fb..a30a6b65a5280d1ddc158a4e53478b6fb8c664f0 100644
--- a/lustre/tests/llecho.sh
+++ b/lustre/tests/llecho.sh
@@ -14,7 +14,7 @@ fi
 
 sh -x $mkconfig $config || exit 1
 
-$LCONF $lustre_opt --reformat --gdb $OPTS $config || exit 4
+$LCONF $lustre_opt --reformat $@ $OPTS $config || exit 4
 
 cat <<EOF
 
diff --git a/lustre/tests/llmount.sh b/lustre/tests/llmount.sh
index d8f37c5faa5ff4ce8060d38bd31d1d5c61ab3ef7..29dfec9afdb00b2152213dfeca7b17cbc7ce4f63 100755
--- a/lustre/tests/llmount.sh
+++ b/lustre/tests/llmount.sh
@@ -26,9 +26,5 @@ fi
 
 [ "$NODE" ] && node_opt="--node $NODE"
 
-if [ "$1" = "-v" ]; then
-  verbose="-v"
-fi
-
-${LCONF} $portals_opt $lustre_opt $node_opt ${REFORMAT:---reformat} \
-    ${GDB:---gdb} $verbose $conf_opt  || exit 2
+${LCONF}  $portals_opt $lustre_opt $node_opt ${REFORMAT:---reformat} $@ \
+	$conf_opt  || exit 2
diff --git a/lustre/tests/llmountcleanup.sh b/lustre/tests/llmountcleanup.sh
index 572cd65030f082a678c344de85e3fa219ac4ca40..bc864a731d4a2e7da2083ae8383fa6d0fba311f7 100755
--- a/lustre/tests/llmountcleanup.sh
+++ b/lustre/tests/llmountcleanup.sh
@@ -17,14 +17,10 @@ if [ "$LUSTRE" ]; then
   lustre_opt="--lustre=$LUSTRE"
 fi
 
-if [ "$1" = "--force" ]; then
-  force="--force"
-fi
-
 if [ "$LDAPURL" ]; then
     conf_opt="--ldapurl $LDAPURL --config $NAME"
 else
-    if [ ! -f $config -o $mkconfig -nt $config ]; then
+    if [ ! -f $config ]; then
 	sh $mkconfig $config || exit 1
     fi
     conf_opt="$config"
@@ -33,7 +29,7 @@ fi
 [ "$NODE" ] && node_opt="--node $NODE"
 
 sync; sleep 2; sync
-${LCONF} $portals_opt $lustre_opt $node_opt --cleanup $force \
+${LCONF} $portals_opt $lustre_opt $node_opt --cleanup $@ \
     --dump $TMP/debug $conf_opt
 rc=$?
 BUSY=`dmesg | grep -i destruct`
diff --git a/lustre/tests/llrmount.sh b/lustre/tests/llrmount.sh
index b12c1aebe562e46e2b84945bf4b4a34a2d4c4656..1877666195c2a05959f02cbb1ea1af8160debb81 100755
--- a/lustre/tests/llrmount.sh
+++ b/lustre/tests/llrmount.sh
@@ -25,4 +25,4 @@ fi
 
 [ "$NODE" ] && node_opt="--node $NODE"
 
-${LCONF} $portals_opt $lustre_opt $node_opt --gdb $conf_opt || exit 2
+${LCONF} $portals_opt $lustre_opt $node_opt $@ $conf_opt || exit 2
diff --git a/lustre/tests/local-large-inode.sh b/lustre/tests/local-large-inode.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7e401b06ffed4d8d667195ddf5be4f50931ed9de
--- /dev/null
+++ b/lustre/tests/local-large-inode.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+#set -vx
+JSIZE=32 MDSISIZE=256 sh `dirname $0`/local.sh `basename $0 .sh`.xml
diff --git a/lustre/tests/local.sh b/lustre/tests/local.sh
index 00f2391142803fbf0ba87b222a7ed9fbdfdecf79..95dd2768fc871637cf0ce459a4cfa0ce3fa59c05 100755
--- a/lustre/tests/local.sh
+++ b/lustre/tests/local.sh
@@ -8,23 +8,36 @@ LMC="${LMC:-lmc} -m $config"
 TMP=${TMP:-/tmp}
 
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
-MDSSIZE=${MDSSIZE:-50000}
+MDSSIZE=${MDSSIZE:-100000}
 FSTYPE=${FSTYPE:-ext3}
+MOUNT=${MOUNT:-/mnt/lustre}
+#MOUNT2=${MOUNT2:-${MOUNT}2}
+NETWORKTYPE=${NETWORKTYPE:-tcp}
 
 OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`}
 OSTSIZE=${OSTSIZE:-200000}
 
+# specific journal size for the ost, in MB
+JSIZE=${JSIZE:-0}
+[ "$JSIZE" -gt 0 ] && JARG="--journal_size $JSIZE"
+MDSISIZE=${MDSISIZE:-128}
+
+STRIPE_BYTES=65536
+STRIPES_PER_OBJ=0	# 0 means stripe over all OSTs
+
 rm -f $config
 
 # create nodes
 ${LMC} --add node --node localhost || exit 10
-${LMC} --add net --node  localhost --nid localhost --nettype tcp || exit 11
+${LMC} --add net --node  localhost --nid `hostname` --nettype $NETWORKTYPE || exit 11
 
 # configure mds server
-${LMC} --add mds --nspath /mnt/mds_ns  --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 20
+${LMC} --add mds --nspath /mnt/mds_ns  --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE $JARG --mkfsoptions "-I $MDSISIZE" || exit 20
 
 # configure ost
-${LMC} --add ost --nspath /mnt/ost_ns --node localhost --ost ost1  --fstype $FSTYPE --dev $OSTDEV --size  $OSTSIZE || exit 30
+${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20
+${LMC} --add ost --nspath /mnt/ost_ns --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV --size $OSTSIZE $JARG || exit 30
 
 # create client config
-${LMC} --add mtpt --node localhost --path /mnt/lustre --mds mds1 --ost ost1 || exit 40
+${LMC} --add mtpt --node localhost --path $MOUNT --mds mds1 --lov lov1 || exit 40
+#${LMC} --add mtpt --node localhost --path $MOUNT2 --mds mds1 --lov lov1 || exit 40
diff --git a/lustre/tests/lov-sanity.sh b/lustre/tests/lov-sanity.sh
new file mode 100644
index 0000000000000000000000000000000000000000..05ceae665e551575d95da8a394344f8719314677
--- /dev/null
+++ b/lustre/tests/lov-sanity.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+export OSTCOUNT=6
+export OSTSIZE=81919
+export NAME=lov
+export MOUNTPT=${MOUNTPT:-"/mnt/lustre"}
+export LCONF=${LCONF:-"../utils/lconf"}
+export CONFIG=${CONFIG:-"$NAME.xml"}
+export MCREATE=${MCREATE:-"mcreate"}
+export LFS=${LFS:-"/usr/sbin/lfs"}
+export SETSTRIPE_SIZE=${SETSTRIPE_SIZE:-"131072"}
+export OPENFILE=${OPENFILE:-"./openfile"}
+fail()
+{
+    echo "ERROR $@"
+    exit 1
+}
+lustre_mount()
+{
+    . ./llmount.sh || fail "Mount lustre failed"
+}
+test_0()
+{
+    echo "test 0 IO after open file"
+    mkdir $MOUNTPT/d0 
+    $OPENFILE -f O_RDWR:O_CREAT -m 0755  $MOUNTPT/d0/f       || fail "open file failed."
+    ls -lR >> $MOUNTPT/d0/f                                  || fail "IO after open failed."
+    rm -fr  $MOUNTPT/d0                                      || fail "Unable to ereas dir."
+    echo "test 0 success."
+}
+test_1()
+{
+    echo "test 1 IO after mcreate "
+    mkdir $MOUNTPT/d1
+    $MCREATE $MOUNTPT/d1/f    || fail "mcreate file failed."
+    ls -lR >> $MOUNTPT/d1/f   || fail "IO after mcreate failed."
+    rm -fr  $MOUNTPT/d1       || fail "Unable to ereas the file."
+    echo "test 1 success."
+}
+test_2()
+{
+    echo "test 2 IO after mcreate with strip 1 "
+    mkdir $MOUNTPT/d2
+    $MCREATE $MOUNTPT/d2/f                             || fail "mcreate file failed."
+    $LFS setstripe $MOUNTPT/d2/f $SETSTRIPE_SIZE 0 1   || fail "setstipe to stripe 1 failed"
+    ls -lR >> $MOUNTPT/d2/f                            || fail "IO after mcreate failed."
+    rm -fr  $MOUNTPT/d2                                || fail "Unable to ereas the file."
+    echo "test 2 success."
+}
+
+test_3()
+{
+    echo "test 2 IO after mcreate with strip 4 "
+    mkdir $MOUNTPT/d3
+    $MCREATE $MOUNTPT/d3/f                             || fail "mcreate file failed."
+    $LFS setstripe $MOUNTPT/d3/f $SETSTRIPE_SIZE 0 4   || fail "setstipe to stripe 4 failed"
+    ls -lR >> $MOUNTPT/d3/f                            || fail "IO after mcreate failed."
+    rm -fr  $MOUNTPT/d3                                || fail "Unable to ereas the file."
+    echo "test 3 success."
+}
+test_4()
+{
+    echo "test 4 IO after mcreate with strip 6 "
+    mkdir $MOUNTPT/d3
+    $MCREATE $MOUNTPT/d3/f                             || fail "mcreate file failed."
+    $LFS setstripe $MOUNTPT/d3/f $SETSTRIPE_SIZE 0 6   || fail "setstipe to stripe 6 failed"
+    ls -lR >> $MOUNTPT/d3/f                            || fail "IO after mcreate failed."
+    rm -fr  $MOUNTPT/d3                                || fail "Unable to ereas the file."
+    echo "test 4 success."
+}
+
+lustre_clean()
+{
+    echo "clean up lustre"
+    cd $CURRENT
+    $LCONF --cleanup  $CONFIG  || fail "Unable to clean up lustre."
+    echo "clean up lustre success"
+}
+run_all()
+{
+    lustre_mount 
+    test_0	 
+    test_1
+    test_2
+    test_3
+    test_4
+    lustre_clean 
+}
+run_all 
+
diff --git a/lustre/tests/lov.sh b/lustre/tests/lov.sh
index 79e95902516d4e31cfa214dcf1fd8b2d22533811..60c579f94d85ac95caa4600ee562b54202301a8a 100755
--- a/lustre/tests/lov.sh
+++ b/lustre/tests/lov.sh
@@ -1,5 +1,7 @@
 #!/bin/bash
 
+set -e
+
 export PATH=`dirname $0`/../utils:$PATH
 
 config=${1:-lov.xml}
@@ -8,34 +10,44 @@ LMC=${LMC:-lmc}
 TMP=${TMP:-/tmp}
 
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
-MDSSIZE=${MDSSIZE:-50000}
+MDSSIZE=${MDSSIZE:-100000}
 FSTYPE=${FSTYPE:-ext3}
 
-OSTDEV1=${OSTDEV1:-$TMP/ost1-`hostname`}
-OSTDEV2=${OSTDEV2:-$TMP/ost2-`hostname`}
-OSTDEV3=${OSTDEV3:-$TMP/ost3-`hostname`}
+OSTCOUNT=${OSTCOUNT:-3}
+# OSTDEVN will still override the device for OST N
+
 OSTSIZE=${OSTSIZE:-100000}
 # 1 to config an echo client instead of llite
 ECHO_CLIENT=${ECHO_CLIENT:-}
 
 STRIPE_BYTES=65536
-STRIPES_PER_OBJ=2	# 0 means stripe over all OSTs
+STRIPES_PER_OBJ=${STRIPES_PER_OBJ:-$((OSTCOUNT -1))}
+
+# specific journal size for the ost, in MB
+JSIZE=${JSIZE:-0}
+JARG=""
+[ "$JSIZE" -gt 0 ] && JARG="--journal_size $JSIZE"
 
 # create nodes
-${LMC} -o $config --add net --node localhost --nid localhost --nettype tcp || exit 1
+${LMC} -o $config --add net --node localhost --nid localhost --nettype tcp
 
 # configure mds server
-${LMC} -m $config --format --add mds --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 10
+${LMC} -m $config --format --add mds --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE
 
 # configure ost
-${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20
-${LMC} -m $config --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV1 --size $OSTSIZE || exit 21
-${LMC} -m $config --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV2 --size $OSTSIZE || exit 22
-${LMC} -m $config --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV3 --size $OSTSIZE || exit 23
+${LMC} -m $config --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+
+for num in `seq $OSTCOUNT`; do
+    OST=ost$num
+    DEVPTR=OSTDEV$num
+    eval $DEVPTR=${!DEVPTR:=$TMP/$OST-`hostname`}
+    ${LMC} -m $config --add ost --node localhost --lov lov1 --ost $OST --fstype $FSTYPE --dev ${!DEVPTR} --size $OSTSIZE $JARG
+done
+
 
 if [ -z "$ECHO_CLIENT" ]; then
 	# create client config
-	${LMC} -m $config  --add mtpt --node localhost --path /mnt/lustre --mds mds1 --lov lov1 || exit 30
+	${LMC} -m $config  --add mtpt --node localhost --path /mnt/lustre --mds mds1 --lov lov1
 else
-	${LMC} -m $config  --add echo_client --node localhost --ost lov1 || exit 31
+	${LMC} -m $config  --add echo_client --node localhost --ost lov1
 fi
diff --git a/lustre/tests/mkdirdeep.c b/lustre/tests/mkdirdeep.c
index 38c0cea5dac5a3fa35c2282b0d343281da8176c4..1326c1e96bd60a09ec0cd8c40fb6a68eb130ceb4 100644
--- a/lustre/tests/mkdirdeep.c
+++ b/lustre/tests/mkdirdeep.c
@@ -86,11 +86,12 @@ int do_stat(char *path)
                 exit(1);
         }
         if (opt_verbose)
-                printf("stat %s = inode %lu\n", path, mystat.st_ino);
+                printf("stat %s = inode %lu\n", path,
+                       (unsigned long)mystat.st_ino);
 
         if (opt_trace) {
                 snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu",
-                         path, mystat.st_ino);
+                         path, (unsigned long)mystat.st_ino);
                 ltrace_mark(0, mark_buf);
         }
 
diff --git a/lustre/tests/mount2.sh b/lustre/tests/mount2.sh
index 40ef46a83f70800eed53a5f1163fbd0a2744cfb9..eaed7e33169f32e662484c4b803b216ef25db76f 100644
--- a/lustre/tests/mount2.sh
+++ b/lustre/tests/mount2.sh
@@ -9,6 +9,9 @@ TMP=${TMP:-/tmp}
 
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
 MDSSIZE=${MDSSIZE:-50000}
+MOUNT=${MOUNT:-/mnt/lustre}
+MOUNT1=${MOUNT1:-${MOUNT}1}
+MOUNT2=${MOUNT2:-${MOUNT}2}
 FSTYPE=${FSTYPE:-ext3}
 
 OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`}
@@ -27,5 +30,5 @@ ${LMC} --add mds  --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --s
 ${LMC} --add ost --node localhost --ost ost1 --fstype $FSTYPE --dev $OSTDEV --size  $OSTSIZE || exit 30
 
 # create client config
-${LMC} --add mtpt --node localhost --path /mnt/lustre1 --mds mds1 --ost ost1 || exit 40
-${LMC} --add mtpt --node localhost --path /mnt/lustre2 --mds mds1 --ost ost1 || exit 40
+${LMC} --add mtpt --node localhost --path $MOUNT1 --mds mds1 --ost ost1 || exit 40
+${LMC} --add mtpt --node localhost --path $MOUNT2 --mds mds1 --ost ost1 || exit 40
diff --git a/lustre/tests/mount2fs.sh b/lustre/tests/mount2fs.sh
index 6535ef43bbdfd2043cbce06b0edd3cb92853192a..28df665e09e5501cd8c3db05582a65817de72275 100644
--- a/lustre/tests/mount2fs.sh
+++ b/lustre/tests/mount2fs.sh
@@ -8,7 +8,10 @@ LMC=${LMC-../utils/lmc}
 TMP=${TMP:-/tmp}
 
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
-MDSDEV2=${MDSDEV2:-$TMP/mds2-`hostname`}
+MDSDEV2=${MDSDEV:-$TMP/mds2-`hostname`}
+MOUNT=${MOUNT:-/mnt/lustre}
+MOUNT1=${MOUNT1:-$MOUNT}
+MOUNT2=${MOUNT2:-${MOUNT}2}
 MDSSIZE=50000
 FSTYPE=${FSTYPE:-ext3}
 
@@ -36,5 +39,5 @@ ${LMC} -m $config --add ost --node $OSTNODE --lov lov1 --fstype $FSTYPE --dev $O
 ${LMC} -m $config --add ost --node $OSTNODE --lov lov2 --fstype $FSTYPE --dev $OSTDEV2 --size $OSTSIZE || exit 22
 
 # create client config
-${LMC} -m $config --add mtpt --node $CLIENT --path /mnt/lustre --mds mds1 --lov lov1 || exit 30
-${LMC} -m $config --add mtpt --node $CLIENT --path /mnt/lustre2 --mds mds2 --lov lov2 || exit 30
+${LMC} -m $config --add mtpt --node $CLIENT --path ${MOUNT1} --mds mds1 --lov lov1 || exit 30
+${LMC} -m $config --add mtpt --node $CLIENT --path ${MOUNT2} --mds mds2 --lov lov2 || exit 30
diff --git a/lustre/tests/mount2lov.sh b/lustre/tests/mount2lov.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1840d197c337864698df63c916ec0372851551d7
--- /dev/null
+++ b/lustre/tests/mount2lov.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+config=${1:-mount2.xml}
+
+SRCDIR=`dirname $0`
+PATH=$SRCDIR:$SRCDIR/../utils:$PATH
+LMC="${LMC:-lmc} -m $config"
+TMP=${TMP:-/tmp}
+
+MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
+MDSSIZE=${MDSSIZE:-50000}
+FSTYPE=${FSTYPE:-ext3}
+
+OSTDEV1=${OSTDEV1:-$TMP/ost1-`hostname`}
+OSTDEV2=${OSTDEV2:-$TMP/ost2-`hostname`}
+OSTDEV3=${OSTDEV3:-$TMP/ost3-`hostname`}
+OSTSIZE=${OSTSIZE:-100000}
+
+STRIPE_BYTES=65536
+STRIPES_PER_OBJ=2	# 0 means stripe over all OSTs
+
+rm -f $config
+
+# create nodes
+${LMC} --add net --node  localhost --nid localhost --nettype tcp || exit 1
+
+# configure MDS server
+${LMC} --add mds  --node localhost --mds mds1 --fstype $FSTYPE --dev $MDSDEV --size $MDSSIZE || exit 10
+
+# configure OSTs
+${LMC} --add lov --lov lov1 --mds mds1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20
+${LMC} --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV1 --size $OSTSIZE || exit 21
+${LMC} --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV2 --size $OSTSIZE || exit 22
+${LMC} --add ost --node localhost --lov lov1 --fstype $FSTYPE --dev $OSTDEV3 --size $OSTSIZE || exit 23
+
+# create client config
+${LMC} --add mtpt --node localhost --path /mnt/lustre1 --mds mds1 --ost lov1 || exit 40
+${LMC} --add mtpt --node localhost --path /mnt/lustre2 --mds mds1 --ost lov1 || exit 41
diff --git a/lustre/tests/mrename.c b/lustre/tests/mrename.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c188806293403ff6f4becc072e8af553aa3fe6b
--- /dev/null
+++ b/lustre/tests/mrename.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s from to\n", argv[0]);
+		exit(1);
+	}
+
+	rc = rename(argv[1], argv[2]);
+	printf("rename returned %d: %s\n", rc, strerror(errno));
+
+	return rc;
+}
diff --git a/lustre/tests/multifstat.c b/lustre/tests/multifstat.c
index fa510bce90293e2305a00f2eb8e1ec73c4a8b00d..b3d6479b1c961a2ed441828838b7eeb02a877039 100644
--- a/lustre/tests/multifstat.c
+++ b/lustre/tests/multifstat.c
@@ -47,8 +47,9 @@ int main(int argc, char **argv)
         }
 
         if ( st1.st_size != st2.st_size ) {
-                printf("Sizes don't match %ld, %ld\n",
-                       st1.st_size, st2.st_size);
+                printf("Sizes don't match %lu, %lu\n",
+                       (unsigned long)st1.st_size, 
+		       (unsigned long)st2.st_size);
                 return 1;
         }
 
diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c
new file mode 100755
index 0000000000000000000000000000000000000000..07605bebe6b8f7b5ee6f41fc8948011cd39c1245
--- /dev/null
+++ b/lustre/tests/multiop.c
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define T1 "write data before unlink\n"
+#define T2 "write data after unlink\n"
+char buf[128];
+
+char usage[] = 
+"Usage: %s filename command-sequence\n"
+"    command-sequence items:\n"
+"        d  mkdir\n"
+"        o  open(O_RDONLY)\n"
+"        O  open(O_CREAT|O_RDWR)\n"
+"        u  unlink\n"
+"        U  munmap\n"
+"        m  mknod\n"
+"        M  rw mmap to EOF (must open and stat prior)\n"
+"        c  close\n"
+"        _  wait for signal\n"
+"        R  reference entire mmap-ed region\n"
+"        r  read\n"
+"        s  stat\n"
+"        S  fstat\n"
+"        t  fchmod\n"
+"        T  ftruncate to zero\n"
+"        w  write\n"
+"        W  write entire mmap-ed region\n"
+"        y  fsync\n"
+"        Y  fdatasync\n"
+"        z  seek to zero\n";
+
+void null_handler(int unused) { }
+
+int main(int argc, char **argv)
+{
+        char *fname, *commands;
+        struct stat st;
+	size_t mmap_len, i;
+	unsigned char *mmap_ptr = NULL, junk = 0;
+        int fd = -1;
+
+        if (argc != 3) {
+                fprintf(stderr, usage, argv[0]);
+                exit(1);
+        }
+
+        signal(SIGUSR1, null_handler);
+
+        fname = argv[1];
+
+        for (commands = argv[2]; *commands; commands++) {
+                switch (*commands) {
+                case '_':
+                        pause();
+                        break;
+                case 'c':
+                        if (close(fd) == -1) {
+                                perror("close");
+                                exit(1);
+                        }
+			fd = -1;
+                        break;
+                case 'd':
+                        if (mkdir(fname, 0755) == -1) {
+                                perror("mkdir(0755)");
+                                exit(1);
+                        }
+                        break;
+                case 'm':
+                        if (mknod(fname, S_IFREG | 0644, 0) == -1) {
+                                perror("mknod(S_IFREG|0644, 0)");
+                                exit(1);
+                        }
+                        break;
+		case 'M':
+			mmap_len = st.st_size;
+			mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
+					MAP_SHARED, fd, 0);
+			if (mmap_ptr == MAP_FAILED) {
+				perror("mmap");
+				exit(1);
+			}
+			break;
+                case 'O':
+                        fd = open(fname, O_CREAT|O_RDWR, 0644);
+                        if (fd == -1) {
+                                perror("open(O_RDWR|O_CREAT)");
+                                exit(1);
+                        }
+                        break;
+                case 'o':
+                        fd = open(fname, O_RDONLY);
+                        if (fd == -1) {
+                                perror("open(O_RDONLY)");
+                                exit(1);
+                        }
+                        break;
+		case 'r': {
+			char buf;
+			if (read(fd, &buf, 1) == -1) {
+				perror("read");
+				exit(1);
+			}
+		}
+                case 'S':
+                        if (fstat(fd, &st) == -1) {
+                                perror("fstat");
+                                exit(1);
+                        }
+                        break;
+		case 'R':
+			for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
+				junk += mmap_ptr[i];
+			break;
+                case 's':
+                        if (stat(fname, &st) == -1) {
+                                perror("stat");
+                                exit(1);
+                        }
+                        break;
+                case 't':
+                        if (fchmod(fd, 0) == -1) {
+                                perror("fchmod");
+                                exit(1);
+                        }
+                        break;
+                case 'T':
+                        if (ftruncate(fd, 0) == -1) {
+                                perror("ftruncate");
+                                exit(1);
+                        }
+                        break;
+                case 'u':
+                        if (unlink(fname) == -1) {
+                                perror("unlink");
+                                exit(1);
+                        }
+                        break;
+		case 'U':
+			if (munmap(mmap_ptr, mmap_len)) {
+				perror("munmap");
+				exit(1);
+			}
+			break;
+		case 'w':
+			if (write(fd, "w", 1) == -1) {
+				perror("write");
+				exit(1);
+			}
+			break;
+		case 'W':
+			for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
+				mmap_ptr[i] += junk++;
+			break;
+		case 'y':
+			if (fsync(fd) == -1) {
+				perror("fsync");
+				exit(1);
+			}
+			break;
+		case 'Y':
+			if (fdatasync(fd) == -1) {
+				perror("fdatasync");
+				exit(1);
+			}
+		case 'z':
+			if (lseek(fd, 0, SEEK_SET) == -1) {
+				perror("lseek");
+				exit(1);
+			}
+			break;
+                default:
+                        fprintf(stderr, "unknown command \"%c\"\n", *commands);
+                        fprintf(stderr, usage, argv[0]);
+                        exit(1);
+                }
+        }
+
+        return 0;
+}
diff --git a/lustre/tests/munlink.c b/lustre/tests/munlink.c
index a3c18c58e521e26fe11141c42a7780c83557cd2f..0f424348635c9ad387419d8717ec186967035aa0 100755
--- a/lustre/tests/munlink.c
+++ b/lustre/tests/munlink.c
@@ -1,3 +1,6 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -8,16 +11,18 @@
 
 int main(int argc, char ** argv)
 {
-        int rc;
+        int rc, i;
 
         if (argc < 2) { 
                 printf("Usage %s filename\n", argv[0]);
                 return 1;
         }
 
-        rc = unlink(argv[1]);
-        if (rc) { 
-                printf("unlink(%s) error: %s\n", argv[1], strerror(errno));
+        for (i = 1; i < argc; i++) {
+        	rc = unlink(argv[i]);
+        	if (rc)
+                	printf("unlink(%s) error: %s\n", argv[i],
+                               strerror(errno));
         }
         return rc;
 } 
diff --git a/lustre/tests/open_delay.c b/lustre/tests/open_delay.c
index de4815c44e7898ae5a3f2aed3b02c9416187af99..7200c3f16f3f4b7caed62f42bb503ea9d9bb97a2 100644
--- a/lustre/tests/open_delay.c
+++ b/lustre/tests/open_delay.c
@@ -2,23 +2,19 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <liblustre.h>
-#include <linux/obd.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_lite.h>
-#include <linux/obd_lov.h>
+#include <linux/lustre_user.h>
 
 int main(int argc, char **argv)
 {
-        int fd; 
+        int fd;
 
-        if (argc != 2) { 
-                printf("Usage %s <filename>\n", argv[0]); 
+        if (argc != 2) {
+                printf("Usage %s <filename>\n", argv[0]);
                 exit(1);
         }
 
         fd = open(argv[1], O_RDONLY | O_LOV_DELAY_CREATE);
-        if (fd == -1) { 
+        if (fd == -1) {
                 printf("Error opening %s\n", argv[1]);
                 exit(1);
         }
diff --git a/lustre/tests/openclose.c b/lustre/tests/openclose.c
index 1294b136167a46a3d8d9b6e927fd06188d705254..ca10134b9944e439407d64b4a4991c668f1780b2 100644
--- a/lustre/tests/openclose.c
+++ b/lustre/tests/openclose.c
@@ -2,6 +2,9 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  */
 
+/* for O_DIRECT */
+#define _GNU_SOURCE
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -13,11 +16,7 @@
 #include <sys/wait.h>
 #include <sys/ioctl.h>
 
-#include <linux/lustre_lite.h>
-
-#ifndef O_DIRECT
-# define O_DIRECT         040000 /* direct disk access hint */
-#endif
+#include <linux/lustre_user.h>
 
 int main(int argc, char *argv[])
 {
diff --git a/lustre/tests/opendirunlink.c b/lustre/tests/opendirunlink.c
index 2664618d2763d08a96a69ec8ab05a62e1463f026..5e70f7d41e46989538a2cd07da1bff5a357a249d 100644
--- a/lustre/tests/opendirunlink.c
+++ b/lustre/tests/opendirunlink.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  */
 
+/* for O_DIRECTORY */
 #define _GNU_SOURCE
 
 #include <stdio.h>
diff --git a/lustre/tests/openfile.c b/lustre/tests/openfile.c
index 7b97309915b0bf67aff33afa4d7bd52a6d5204a2..a6e44c60a8ee4c3d8e1c8b7b970c4523d4733ff4 100644
--- a/lustre/tests/openfile.c
+++ b/lustre/tests/openfile.c
@@ -6,6 +6,7 @@
 #define DEBUG
 #endif
 
+/* for O_DIRECTORY and O_DIRECT */
 #define _GNU_SOURCE
 
 #include <stdio.h>
@@ -34,9 +35,10 @@ FLAG_MAPPING flag_table[] = {
        {"O_NONBLOCK", O_NONBLOCK},
        {"O_NDELAY", O_NDELAY},
        {"O_SYNC", O_SYNC},
-       {"O_NOFOLLOW", O_NOFOLLOW},
-       {"O_DIRECTORY", O_DIRECTORY},
+       {"O_DIRECT", O_DIRECT},
        {"O_LARGEFILE", O_LARGEFILE},
+       {"O_DIRECTORY", O_DIRECTORY},
+       {"O_NOFOLLOW", O_NOFOLLOW},
        {"", -1}
 };
 
diff --git a/lustre/tests/openunlink.c b/lustre/tests/openunlink.c
index 96632a9224ecfbc7ebb895f927b484c787f9b9e2..4a0d8c3a67dd3fdeca7bc1f65acf16c0d070b815 100644
--- a/lustre/tests/openunlink.c
+++ b/lustre/tests/openunlink.c
@@ -1,3 +1,6 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
 #include <stdio.h>
 #include <fcntl.h>
 #include <string.h>
@@ -44,49 +47,35 @@ int main(int argc, char **argv)
         }
 
         if (argc == 3) {
-                fprintf(stderr, "closing %s\n", fname);
-                rc = close(fd);
-                if (rc) {
-                        fprintf(stderr, "close (normal) %s\n", strerror(errno));
-                        exit(1);
-                }
-
-                fprintf(stderr, "opening %s\n", fname2);
-                fd = open(fname2, O_RDWR);
-                if (fd == -1) {
-                        fprintf(stderr, "open (unlink) %s\n", strerror(errno));
-                        exit(1);
-                }
-
                 fprintf (stderr, "unlinking %s\n", fname2);
                 rc = unlink(fname2);
                 if (rc) {
                         fprintf(stderr, "unlink %s\n", strerror(errno));
                         exit(1);
                 }
-
-                if (access(fname2, F_OK) == 0) {
-                        fprintf(stderr, "%s still exists\n", fname2);
-                        exit(1);
-                }
         } else {
-                fprintf(stderr, "resetting fd offset\n");
-                rc = lseek(fd, 0, SEEK_SET);
-                if (rc) {
-                        fprintf(stderr, "seek %s\n", strerror(errno));
-                        exit(1);
-                }
-
                 printf("unlink %s and press enter\n", fname);
                 getc(stdin);
         }
 
+        if (access(fname, F_OK) == 0) {
+                fprintf(stderr, "%s still exists\n", fname2);
+                exit(1);
+        }
+
+        fprintf(stderr, "resetting fd offset\n");
+        rc = lseek(fd, 0, SEEK_SET);
+        if (rc) {
+                fprintf(stderr, "seek %s\n", strerror(errno));
+                exit(1);
+        }
+
         if (access(fname, F_OK) == 0) {
                 fprintf(stderr, "%s still exists\n", fname);
                 exit(1);
         }
 
-        fprintf(stderr, "fstating\n");
+        fprintf(stderr, "fstat...\n");
         rc = fstat(fd, &st);
         if (rc) {
                 fprintf(stderr, "fstat (unlink) %s\n", strerror(errno));
diff --git a/lustre/tests/recovery-cleanup.sh b/lustre/tests/recovery-cleanup.sh
index fefd2d64f2336360c52613bd64bdaa77f4e4a91d..ce4a4a698893ebb724c43034221da2ce096920e1 100755
--- a/lustre/tests/recovery-cleanup.sh
+++ b/lustre/tests/recovery-cleanup.sh
@@ -29,15 +29,15 @@ OSTDEV=${OSTDEV:-/tmp/ost-`hostname`}
 OSTSIZE=${OSTSIZE:-100000}
 
 do_mds() {
-    $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
+    $PDSH $MDSNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" || exit $?
 }
 
 do_client() {
-    $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
+    $PDSH $CLIENT "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" || exit $?
 }
 
 do_ost() {
-    $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@"
+    $PDSH $OSTNODE "PATH=\$PATH:$LUSTRE/utils:$LUSTRE/tests; cd $PWD; $@" || exit $?
 }
 
 drop_request() {
@@ -54,10 +54,12 @@ make_config() {
     done
     lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --fstype $FSTYPE \
     	--dev $MDSDEV --size $MDSSIZE || exit 5
-    lmc -m $CONFIG --add ost --node $OSTNODE --ost ost1 --fstype $FSTYPE \
-    	--dev $OSTDEV --size $OSTSIZE || exit 6
+    lmc -m $CONFIG --add lov --lov lov1 --mds mds1 --stripe_sz 65536 \
+        --stripe_cnt 0 --stripe_pattern 0 || exit 6
+    lmc -m $CONFIG --add ost --nspath /mnt/ost_ns --node $OSTNODE \
+        --lov lov1 --dev $OSTDEV --size $OSTSIZE --fstype $FSTYPE || exit 7
     lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \
-        --ost ost1 || exit 7
+        --lov lov1 || exit 8
 }
 
 start_mds() {
@@ -88,14 +90,14 @@ setup() {
     make_config
     start_mds ${REFORMAT:---reformat}
     start_ost ${REFORMAT:---reformat}
-    mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true
+    mount_client --timeout=${TIMEOUT:-5} --lustre_upcall=/bin/true
 }
 
 cleanup() {
     do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-    unmount_client $@ || true
-    shutdown_mds $@ || true
-    shutdown_ost $@ || true
+    unmount_client $@ || exit 97
+    shutdown_mds $@ || exit 98
+    shutdown_ost $@ || exit 99
 }
 
 wait_for_timeout() {
@@ -107,7 +109,7 @@ wait_for_timeout() {
 try_to_cleanup() {
     kill -INT $!
     unmount_client --force --dump /tmp/client-cleanup-`date +%s`.log
-    mount_client --timeout=${TIMEOUT:-5} --recovery_upcall=/bin/true
+    mount_client --timeout=${TIMEOUT:-5} --lustre_upcall=/bin/true
 }
 
 if [ ! -z "$ONLY" ]; then
diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh
index c3010e8c11ab692dcbb64daaccba78bda87b36c9..cdd599f38737736d82a9ecfbef0521732d11ef0b 100755
--- a/lustre/tests/recovery-small.sh
+++ b/lustre/tests/recovery-small.sh
@@ -9,7 +9,7 @@ PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests
 RLUSTRE=${RLUSTRE:-$LUSTRE}
 RPWD=${RPWD:-$PWD}
 
-. $LTESTDIR/functional/llite/common/common.sh
+. $LUSTRE/tests/test-framework.sh
 
 # Allow us to override the setup if we already have a mounted system by
 # setting SETUP=" " and CLEANUP=" "
@@ -73,10 +73,12 @@ make_config() {
     done
     lmc -m $CONFIG --add mds --node $MDSNODE --mds mds1 --dev $MDSDEV \
         --size $MDSSIZE --fstype $FSTYPE || exit 5
-    lmc -m $CONFIG --add ost --node $OSTNODE --ost ost1 --dev $OSTDEV \
-        --size $OSTSIZE --fstype $FSTYPE || exit 6
+    lmc -m $CONFIG --add lov --lov lov1 --mds mds1 --stripe_sz 65536 \
+	--stripe_cnt 0 --stripe_pattern 0 || exit 6 
+    lmc -m $CONFIG --add ost --nspath /mnt/ost_ns --node $OSTNODE \
+	--lov lov1 --dev $OSTDEV --size $OSTSIZE --fstype $FSTYPE || exit 7
     lmc -m $CONFIG --add mtpt --node $CLIENT --path $MOUNTPT --mds mds1 \
-        --ost ost1 || exit 7
+        --lov lov1 || exit 8
 }
 
 start_mds() {
@@ -104,8 +106,8 @@ unmount_client() {
 }
 
 setup() {
-    start_mds --timeout=$TIMEOUT ${REFORMAT}
     start_ost --timeout=$TIMEOUT ${REFORMAT}
+    start_mds --timeout=$TIMEOUT ${REFORMAT}
     # XXX we should write our own upcall, when we move this somewhere better.
     mount_client --timeout=${TIMEOUT} \
         --lustre_upcall=$UPCALL
@@ -113,9 +115,9 @@ setup() {
 
 cleanup() {
     do_mds "echo 0 > /proc/sys/lustre/fail_loc"
-    unmount_client $@ || true
-    shutdown_mds $@ || true
-    shutdown_ost $@ || true
+    unmount_client $@ || exit 97
+    shutdown_mds $@ || exit 98
+    shutdown_ost $@ || exit 99
 }
 
 replay() {
diff --git a/lustre/tests/rename.pl b/lustre/tests/rename.pl
index 4ea020f2c0a9b796d7cbc0f8481616b6974fcce0..ee9bb4d228428a6c9be4b425db82eb354442d2b6 100644
--- a/lustre/tests/rename.pl
+++ b/lustre/tests/rename.pl
@@ -12,11 +12,14 @@ use POSIX ":sys_wait_h";
 
 use vars qw(
             $MAX_THREADS
+	    $SCRIPT_NAME
             );
  
 # Don't try to run more than this many threads concurrently.
 $MAX_THREADS = 16;
 
+$SCRIPT_NAME = "rename.pl";
+
 # Initialize variables
 my $silent = 0;
 my $create_files = 1; # should we create files or not?
@@ -104,7 +107,7 @@ if ($create_files) {
 		unlink("$filepath") if (-e $filepath);
 	    }
 	    my $rc = rmdir $path;
-	    print "rmdir $path failed: $!\n" if !$rc;	    
+	    print "$SCRIPT_NAME - rmdir $path failed: $!\n" if !$rc;	    
 	}
     }
 }
@@ -137,6 +140,11 @@ sub usage () {
 sub create_file ($) {
     my ($path) = @_;;
     
+    if (-e $path) {
+	warn "$path already exists!\n";
+	return 1;
+    }
+
     if ($use_mcreate) {
         my $tmp = `./mcreate $path`;
 	if ($tmp =~ /.*error: (.*)\n/) {
@@ -174,18 +182,18 @@ sub fork_and_rename ($) {
 		  my $path_f1 = "${mountpt}${which}/${thread_num}.${d}/${f1}";
 		  my $path_f2 = "${mountpt}${which}/${thread_num}.${d}/${f2}";
 		  
-		  print "Thread $thread_num: [$$] $path_f1 $path_f2 ...\n" if !$silent;
+		  print "$SCRIPT_NAME - Thread $thread_num: [$$] $path_f1 $path_f2 ...\n" if !$silent;
 		  my $rc = rename $path_f1, $path_f2;
-		  print "Thread $thread_num: [$$] done: $rc\n" if !$silent;
+		  print "$SCRIPT_NAME - Thread $thread_num: [$$] done: $rc\n" if !$silent;
 	      }
 	      if (($current_iteration) % 100 == 0) {
-		  print STDERR "Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
+		  print "$SCRIPT_NAME - Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
 		  
 	      }
 	      $current_iteration++;
 	  }
 
-	  print "Thread $thread_num: Done.\n";
+	  print "$SCRIPT_NAME - Thread $thread_num: Done.\n";
 
 	  exit 0;
 
diff --git a/lustre/tests/replay-dual.sh b/lustre/tests/replay-dual.sh
new file mode 100755
index 0000000000000000000000000000000000000000..62bd1ca26fa2423ea40b87dc8e45100fc6e4035f
--- /dev/null
+++ b/lustre/tests/replay-dual.sh
@@ -0,0 +1,180 @@
+#!/bin/sh
+
+set -e
+
+LUSTRE=${LUSTRE:-`dirname $0`/..}
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
+
+. ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
+
+gen_config() {
+    rm -f $XMLCONFIG
+    add_mds mds --dev $MDSDEV --size $MDSSIZE
+    if [ ! -z "$mdsfailover_HOST" ]; then
+	 add_mdsfailover mds --dev $MDSDEV --size $MDSSIZE
+    fi
+    
+    add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
+	--stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+    add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE
+    add_ost ost2 --lov lov1 --dev ${OSTDEV}-2 --size $OSTSIZE
+    add_client client mds --lov lov1 --path $MOUNT
+}
+
+
+
+build_test_filter
+
+cleanup() {
+    # make sure we are using the primary MDS, so the config log will
+    # be able to clean up properly.
+    activemds=`facet_active mds`
+    if [ $activemds != "mds" ]; then
+        fail mds
+    fi
+
+    umount $MOUNT2
+    umount $MOUNT
+    rmmod llite
+    stop mds ${FORCE}
+    stop ost2 ${FORCE}
+    stop ost ${FORCE}  --dump cleanup-dual.log
+}
+
+if [ "$ONLY" == "cleanup" ]; then
+    sysctl -w portals.debug=0
+    cleanup
+    exit
+fi
+
+gen_config
+start ost --reformat $OSTLCONFARGS 
+PINGER=`cat /proc/fs/lustre/pinger`
+
+if [ "$PINGER" != "on" ]; then
+    echo "ERROR: Lustre must be built with --enable-pinger for replay-dual"
+    stop mds
+    exit 1
+fi
+
+start ost2 --reformat $OSTLCONFARGS 
+[ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+start mds $MDSLCONFARGS --reformat
+zconf_mount $MOUNT
+zconf_mount $MOUNT2
+
+echo $TIMEOUT > /proc/sys/lustre/timeout
+echo $UPCALL > /proc/sys/lustre/upcall
+
+[ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+
+test_1() {
+    touch $MOUNT1/a
+    replay_barrier mds
+    touch $MOUNT2/b
+
+    fail mds
+    checkstat $MOUNT2/a || return 1
+    checkstat $MOUNT1/b || return 2
+    rm $MOUNT2/a $MOUNT1/b
+    checkstat $MOUNT1/a && return 3
+    checkstat $MOUNT2/b && return 4
+    return 0
+}
+
+run_test 1 "|X| simple create"
+
+
+test_2() {
+    replay_barrier mds
+    mkdir $MOUNT1/adir
+
+    fail mds
+    checkstat $MOUNT2/adir || return 1
+    rmdir $MOUNT2/adir
+    checkstat $MOUNT2/adir && return 2
+    return 0
+}
+
+run_test 2 "|X| mkdir adir"
+
+test_3() {
+    replay_barrier mds
+    mkdir $MOUNT1/adir
+    mkdir $MOUNT2/adir/bdir
+
+    fail mds
+    checkstat $MOUNT2/adir      || return 1
+    checkstat $MOUNT1/adir/bdir || return 2
+    rmdir $MOUNT2/adir/bdir $MOUNT1/adir
+    checkstat $MOUNT1/adir      && return 3
+    checkstat $MOUNT2/adir/bdir && return 4
+    return 0
+}
+
+run_test 3 "|X| mkdir adir, mkdir adir/bdir "
+
+test_4() {
+    mkdir $MOUNT1/adir
+    replay_barrier mds
+    mkdir $MOUNT1/adir  && return 1
+    mkdir $MOUNT2/adir/bdir
+
+    fail mds
+    checkstat $MOUNT2/adir      || return 2
+    checkstat $MOUNT1/adir/bdir || return 3
+
+    rmdir $MOUNT2/adir/bdir $MOUNT1/adir
+    checkstat $MOUNT1/adir      && return 4
+    checkstat $MOUNT2/adir/bdir && return 5
+    return 0
+}
+
+run_test 4 "|X| mkdir adir (-EEXIST), mkdir adir/bdir "
+
+
+test_5() {
+    # multiclient version of replay_single.sh/test_8
+    mcreate $MOUNT1/a
+    multiop $MOUNT2/a o_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $MOUNT1/a
+    replay_barrier mds
+    kill -USR1 $pid
+    wait $pid || return 1
+
+    fail mds
+    [ -e $MOUNT2/a ] && return 2
+    return 0
+}
+run_test 5 "open, unlink |X| close"
+
+
+test_6() {
+    mcreate $MOUNT1/a
+    multiop $MOUNT2/a o_c &
+    pid1=$!
+    multiop $MOUNT1/a o_c &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $MOUNT1/a
+    replay_barrier mds
+    kill -USR1 $pid1
+    wait $pid1 || return 1
+
+    fail mds
+    kill -USR1 $pid2
+    wait $pid2 || return 1
+    [ -e $MOUNT2/a ] && return 2
+    return 0
+}
+run_test 6 "open1, open2, unlink |X| close1 [fail mds] close2"
+
+
+equals_msg test complete, cleaning up
+cleanup
diff --git a/lustre/tests/replay-ost-single.sh b/lustre/tests/replay-ost-single.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2fd4f42c0c85dc02d84d7668cb03410bf96ab7c6
--- /dev/null
+++ b/lustre/tests/replay-ost-single.sh
@@ -0,0 +1,124 @@
+#!/bin/sh
+
+set -e
+
+LUSTRE=${LUSTRE:-`dirname $0`/..}
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
+
+. ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
+
+ostfailover_HOST=${ostfailover_HOST:-$ost_HOST}
+
+# Skip these tests
+ALWAYS_EXCEPT=""
+
+gen_config() {
+    rm -f $XMLCONFIG
+    add_mds mds --dev $MDSDEV --size $MDSSIZE
+    add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
+	--stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+    add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE --failover
+    if [ ! -z "$ostfailover_HOST" ]; then
+	 add_ostfailover ost --dev $OSTDEV --size $OSTSIZE
+    fi
+    add_client client mds --lov lov1 --path $MOUNT
+}
+
+cleanup() {
+    # make sure we are using the primary MDS, so the config log will
+    # be able to clean up properly.
+    activeost=`facet_active ost`
+    if [ $activeost != "ost" ]; then
+        fail ost
+    fi
+    zconf_umount $MOUNT
+    stop mds ${FORCE} $MDSLCONFARGS
+    stop ost ${FORCE} --dump cleanup.log
+}
+
+if [ "$ONLY" == "cleanup" ]; then
+    sysctl -w portals.debug=0
+    cleanup
+    exit
+fi
+
+build_test_filter
+
+rm -f ostactive
+
+gen_config
+
+start ost --reformat $OSTLCONFARGS
+PINGER=`cat /proc/fs/lustre/pinger`
+
+if [ "$PINGER" != "on" ]; then
+    echo "ERROR: Lustre must be built with --enable-pinger for this test."
+    stop ost
+    exit 1
+fi
+[ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+start mds --reformat $MDSLCONFARGS
+zconf_mount $MOUNT
+
+mkdir -p $DIR
+
+test_0() {
+    replay_barrier ost
+    fail ost
+    cp /etc/profile  $DIR/$tfile
+    sync
+    diff /etc/profile $DIR/$tfile
+}
+run_test 0 "empty replay"
+
+test_1() {
+    replay_barrier ost
+    date > $DIR/$tfile
+    fail ost
+    $CHECKSTAT -t file $DIR/$tfile || return 1
+}
+run_test 1 "touch"
+
+test_2() {
+    replay_barrier ost
+    for i in `seq 10`; do
+        echo "tag-$i" > $DIR/$tfile-$i
+    done 
+    fail ost
+    for i in `seq 10`; do
+      grep -q "tag-$i" $DIR/$tfile-$i || error "f1c-$i"
+    done 
+}
+run_test 2 "|x| 10 open(O_CREAT)s"
+
+test_3() {
+    verify=$ROOT/tmp/verify-$$
+    dd if=/dev/urandom bs=1024 count=5120 | tee $verify > $DIR/$tfile &
+    ddpid=$!
+    sync &
+    fail ost
+    wait $ddpid || return 1
+    cmp $verify $DIR/$tfile || return 2
+    rm $verify
+}
+run_test 3 "Fail OST during write, with verification"
+
+test_4() {
+    verify=$ROOT/tmp/verify-$$
+    dd if=/dev/urandom bs=1024 count=5120 | tee $verify > $DIR/$tfile
+    # invalidate cache, so that we're reading over the wire
+    for i in /proc/fs/lustre/ldlm/namespaces/OSC_*MNT*; do
+        echo -n clear > $i/lru_size
+    done
+    cmp $verify $DIR/$tfile &
+    cmppid=$!
+    fail ost
+    wait $cmppid || return 1
+    rm $verify
+}
+run_test 4 "Fail OST during read, with verification"
+
+equals_msg test complete, cleaning up
+cleanup
diff --git a/lustre/tests/replay-ost-upcall.sh b/lustre/tests/replay-ost-upcall.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9f9efbfc07d66a03931f39658eb5a70c6f7cb051
--- /dev/null
+++ b/lustre/tests/replay-ost-upcall.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+
+TESTDIR=`dirname $0`
+LUSTRE=$TESTDIR/..
+
+exec >> $TESTDIR/recovery-`hostname`.log
+exec 2>&1
+
+set -xv
+
+failed_import() {
+#    $LUSTRE/utils/lctl --device %$3 recover ||
+#        logger -p kern.info recovery failed: $@
+
+    if [ -f $LUSTRE/tests/ostactive ] ; then
+	source $LUSTRE/tests/ostactive
+    else
+        ostactive=ost
+    fi
+
+    $LUSTRE/utils/lconf --verbose --recover --node client_facet  \
+      --select ost1=${ostactive}_facet\
+     --tgt_uuid $2 --client_uuid $3 --conn_uuid $4 $TESTDIR/replay-ost-single.xml
+
+}
+
+recovery_over() {
+    logger -p kern.info upcall: $@
+}
+
+
+case "$1" in
+FAILED_IMPORT) failed_import $@
+               ;;
+RECOVERY_OVER) recovery_over $@
+               ;;
+esac
diff --git a/lustre/tests/replay-single-upcall.sh b/lustre/tests/replay-single-upcall.sh
new file mode 100755
index 0000000000000000000000000000000000000000..17e04c903749ae72e946c24534d08e0303b9a069
--- /dev/null
+++ b/lustre/tests/replay-single-upcall.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+
+TESTDIR=`dirname $0`
+LUSTRE=$TESTDIR/..
+
+mkdir -p $TESTDIR/logs
+
+exec >> $TESTDIR/logs/recovery-`hostname`.log
+exec 2>&1
+
+set -xv
+
+failed_import() {
+    if [ -f $TESTDIR/XMLCONFIG ] ; then
+	source $TESTDIR/XMLCONFIG
+	if [ ! -f $TESTDIR/XMLCONFIG ]; then
+	    echo "config file not found: $XMLCONFIG"
+	    exit 1
+	 fi
+    else
+	echo "$TESTDIR/XMLCONFIG: not found"
+	exit 1
+    fi
+	
+    if [ -f $TESTDIR/mdsactive ] ; then
+        source $TESTDIR/mdsactive
+	MDSSELECT="--select mds_svc=${mdsactive}_facet"
+    fi
+
+    if [ -f $TESTDIR/ostactive ] ; then
+        source $TESTDIR/ostactive
+	OSTSELECT="--select ost_svc=${ostactive}_facet"
+    fi
+
+    $LUSTRE/utils/lconf --verbose --recover --node client_facet  \
+      $MDSSELECT $OSTSELECT \
+     --tgt_uuid $2 --client_uuid $3 --conn_uuid $4 $XMLCONFIG
+
+}
+
+recovery_over() {
+    logger -p kern.info upcall: $@
+}
+
+
+case "$1" in
+FAILED_IMPORT) failed_import $@
+               ;;
+RECOVERY_OVER) recovery_over $@
+               ;;
+esac
diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh
index 3203044b55dbaa0bed697e4348a0418dee1a06ef..20aecdf3362fb93ec561776dc7ab1a6f9c882f94 100755
--- a/lustre/tests/replay-single.sh
+++ b/lustre/tests/replay-single.sh
@@ -2,80 +2,668 @@
 
 set -e
 
+#
+# This test needs to be run on the client
+#
+
 LUSTRE=${LUSTRE:-`dirname $0`/..}
-LTESTDIR=${LTESTDIR:-$LUSTRE/../ltest}
-PATH=$PATH:$LUSTRE/utils:$LUSTRE/tests
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
 
-RLUSTRE=${RLUSTRE:-$LUSTRE}
-RPWD=${RPWD:-$PWD}
+. ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
 
-. $LTESTDIR/functional/llite/common/common.sh
+# Skip these tests
+ALWAYS_EXCEPT="35"
 
-# XXX I wish all this stuff was in some default-config.sh somewhere
-MOUNTPT=${MOUNTPT:-/mnt/lustre}
-MDSDEV=${MDSDEV:-/tmp/mds-`hostname`}
-MDSSIZE=${MDSSIZE:-100000}
-OSTDEV=${OSTDEV:-/tmp/ost-`hostname`}
-OSTSIZE=${OSTSIZE:-100000}
-UPCALL=${UPCALL:-$PWD/replay-single-upcall.sh}
-FSTYPE=${FSTYPE:-ext3}
-TIMEOUT=${TIMEOUT:-5}
 
-start() {
-    facet=$1
-    shift
-    lconf --node ${facet}_facet $@ replay-single.xml
+gen_config() {
+    rm -f $XMLCONFIG
+    add_mds mds --dev $MDSDEV --size $MDSSIZE
+    if [ ! -z "$mdsfailover_HOST" ]; then
+	 add_mdsfailover mds --dev $MDSDEV --size $MDSSIZE
+    fi
+    
+    add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
+	--stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+    add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE
+    add_ost ost2 --lov lov1 --dev ${OSTDEV}-2 --size $OSTSIZE
+    add_client client mds --lov lov1 --path $MOUNT
 }
 
-stop() {
-    facet=$1
-    shift
-    lconf --node ${facet}_facet $@ -d replay-single.xml
+build_test_filter
+
+cleanup() {
+    # make sure we are using the primary MDS, so the config log will
+    # be able to clean up properly.
+    activemds=`facet_active mds`
+    if [ $activemds != "mds" ]; then
+        fail mds
+    fi
+    zconf_umount $MOUNT
+    stop mds ${FORCE} $MDSLCONFARGS
+    stop ost2 ${FORCE} --dump cleanup.log
+    stop ost ${FORCE} --dump cleanup.log
 }
 
-replay_barrier() {
-    local dev=$1
-    sync
-    lctl --device %${dev}1 readonly
-    lctl --device %${dev}1 notransno
+if [ "$ONLY" == "cleanup" ]; then
+    sysctl -w portals.debug=0 || true
+    cleanup
+    exit
+fi
+
+gen_config
+
+start ost --reformat $OSTLCONFARGS 
+start ost2 --reformat $OSTLCONFARGS 
+[ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+start mds $MDSLCONFARGS --reformat
+zconf_mount $MOUNT
+
+if [ "$ONLY" == "setup" ]; then
+    exit 0
+fi
+
+mkdir -p $DIR
+
+test_0() {
+    replay_barrier mds
+    fail mds
 }
+run_test 0 "empty replay"
 
-fail() {
-    stop mds
-    start mds
-    df $MOUNTPT
+test_1() {
+    replay_barrier mds
+    mcreate $DIR/$tfile
+    fail mds
+    $CHECKSTAT -t file $DIR/$tfile || return 1
+    rm $DIR/$tfile
 }
+run_test 1 "simple create"
 
-do_lmc() {
-    lmc -m replay-single.xml $@
+test_2a() {
+    replay_barrier mds
+    touch $DIR/$tfile
+    fail mds
+    $CHECKSTAT -t file $DIR/$tfile || return 1
+    rm $DIR/$tfile
 }
+run_test 2a "touch"
 
-add_facet() {
-    local facet=$1
-    shift
-    do_lmc --add node --node ${facet}_facet $@ --timeout $TIMEOUT
-    do_lmc --add net --node ${facet}_facet --nid localhost --nettype tcp
+test_2b() {
+    ./mcreate $DIR/$tfile
+    replay_barrier mds
+    touch $DIR/$tfile
+    fail mds
+    $CHECKSTAT -t file $DIR/$tfile || return 1
+    rm $DIR/$tfile
 }
+run_test 2b "touch"
 
-gen_config() {
-    rm -f replay-single.xml
-    add_facet mds
-    add_facet ost
-    add_facet client --lustre_upcall $UPCALL
-    do_lmc --add mds --node mds_facet --mds mds1 --dev $MDSDEV --size $MDSSIZE
-    do_lmc --add ost --node ost_facet --ost ost1 --dev $OSTDEV --size $OSTSIZE
-    do_lmc --add mtpt --node client_facet --path $MOUNTPT --mds mds1 --ost ost1
+test_3() {
+    replay_barrier mds
+    mcreate $DIR/$tfile
+    o_directory $DIR/$tfile
+    fail mds
+    $CHECKSTAT -t file $DIR/$tfile || return 2
+    rm $DIR/$tfile
 }
+run_test 3 "replay failed open"
 
-gen_config
-start mds
-start ost
-start client
+test_4() {
+    replay_barrier mds
+    for i in `seq 10`; do
+        echo "tag-$i" > $DIR/$tfile-$i
+    done 
+    fail mds
+    for i in `seq 10`; do
+      grep -q "tag-$i" $DIR/$tfile-$i || error "f1c-$i"
+    done 
+}
+run_test 4 "|x| 10 open(O_CREAT)s"
+
+test_4b() {
+    replay_barrier mds
+    rm -rf $DIR/$tfile-*
+    fail mds
+    $CHECKSTAT -t file $DIR/$tfile-* && return 1 || true
+}
+run_test 4b "|x| rm 10 files"
+
+# The idea is to get past the first block of precreated files on both 
+# osts, and then replay.
+test_5() {
+    replay_barrier mds
+    for i in `seq 220`; do
+        echo "tag-$i" > $DIR/$tfile-$i
+    done 
+    fail mds
+    for i in `seq 220`; do
+      grep -q "tag-$i" $DIR/$tfile-$i || error "f1c-$i"
+    done 
+    rm -rf $DIR/$tfile-*
+    sleep 3
+    # waiting for commitment of removal
+}
+run_test 5 "|x| 220 open(O_CREAT)"
+
+
+test_6() {
+    replay_barrier mds
+    mkdir $DIR/$tdir
+    mcreate $DIR/$tdir/$tfile
+    fail mds
+    $CHECKSTAT -t dir $DIR/$tdir || return 1
+    $CHECKSTAT -t file $DIR/$tdir/$tfile || return 2
+    sleep 2
+    # waiting for log process thread
+}
+run_test 6 "mkdir + contained create"
+
+test_6b() {
+    replay_barrier mds
+    rm -rf $DIR/$tdir
+    fail mds
+    $CHECKSTAT -t dir $DIR/$tdir && return 1 || true 
+}
+run_test 6b "|X| rmdir"
+
+test_7() {
+    mkdir $DIR/$tdir
+    replay_barrier mds
+    mcreate $DIR/$tdir/$tfile
+    fail mds
+    $CHECKSTAT -t dir $DIR/$tdir || return 1
+    $CHECKSTAT -t file $DIR/$tdir/$tfile || return 2
+    rm -fr $DIR/$tdir
+}
+run_test 7 "mkdir |X| contained create"
+
+test_8() {
+    replay_barrier mds
+    multiop $DIR/$tfile mo_c &
+    MULTIPID=$!
+    sleep 1
+    fail mds
+    ls $DIR/$tfile
+    $CHECKSTAT -t file $DIR/$tfile || return 1
+    kill -USR1 $MULTIPID || return 2
+    wait $MULTIPID || return 3
+    rm $DIR/$tfile
+}
+run_test 8 "creat open |X| close"
+
+test_9() {
+    replay_barrier mds
+    mcreate $DIR/$tfile
+    local old_inum=`ls -i $DIR/$tfile | awk '{print $1}'`
+    fail mds
+    local new_inum=`ls -i $DIR/$tfile | awk '{print $1}'`
+
+    echo " old_inum == $old_inum, new_inum == $new_inum"
+    if [ $old_inum -eq $new_inum  ] ;
+    then
+        echo " old_inum and new_inum match"
+    else
+        echo "!!!! old_inum and new_inum NOT match"
+        return 1
+    fi
+    rm $DIR/$tfile
+}
+run_test 9  "|X| create (same inum/gen)"
+
+test_10() {
+    mcreate $DIR/$tfile
+    replay_barrier mds
+    mv $DIR/$tfile $DIR/$tfile-2
+    rm -f $DIR/$tfile
+    fail mds
+    $CHECKSTAT $DIR/$tfile && return 1
+    $CHECKSTAT $DIR/$tfile-2 ||return 2
+    rm $DIR/$tfile-2
+    return 0
+}
+run_test 10 "create |X| rename unlink"
+
+test_11() {
+    mcreate $DIR/$tfile
+    echo "old" > $DIR/$tfile
+    mv $DIR/$tfile $DIR/$tfile-2
+    replay_barrier mds
+    echo "new" > $DIR/$tfile
+    grep new $DIR/$tfile 
+    grep old $DIR/$tfile-2
+    fail mds
+    grep new $DIR/$tfile || return 1
+    grep old $DIR/$tfile-2 || return 2
+}
+run_test 11 "create open write rename |X| create-old-name read"
+
+test_12() {
+    mcreate $DIR/$tfile 
+    multiop $DIR/$tfile o_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1
+    rm -f $DIR/$tfile
+    replay_barrier mds
+    kill -USR1 $pid
+    wait $pid || return 1
+
+    fail mds
+    [ -e $DIR/$tfile ] && return 2
+    return 0
+}
+run_test 12 "open, unlink |X| close"
+
+
+# 1777 - replay open after committed chmod that would make
+#        a regular open a failure    
+test_13() {
+    mcreate $DIR/$tfile 
+    multiop $DIR/$tfile O_wc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    chmod 0 $DIR/$tfile
+    $CHECKSTAT -p 0 $DIR/$tfile
+    replay_barrier mds
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 1
+
+    $CHECKSTAT -s 1 -p 0 $DIR/$tfile || return 2
+    return 0
+}
+run_test 13 "open chmod 0 |x| write close"
+
+test_14() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+    replay_barrier mds
+    kill -USR1 $pid || return 1
+    wait $pid || return 2
+
+    fail mds
+    [ -e $DIR/$tfile ] && return 3
+    return 0
+}
+run_test 14 "open(O_CREAT), unlink |X| close"
+
+test_15() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+    replay_barrier mds
+    touch $DIR/g11 || return 1
+    kill -USR1 $pid
+    wait $pid || return 2
+
+    fail mds
+    [ -e $DIR/$tfile ] && return 3
+    touch $DIR/h11 || return 4
+    return 0
+}
+run_test 15 "open(O_CREAT), unlink |X|  touch new, close"
+
+
+test_16() {
+    replay_barrier mds
+    mcreate $DIR/$tfile
+    munlink $DIR/$tfile
+    mcreate $DIR/$tfile-2
+    fail mds
+    [ -e $DIR/$tfile ] && return 1
+    [ -e $DIR/$tfile-2 ] || return 2
+    munlink $DIR/$tfile-2 || return 3
+}
+run_test 16 "|X| open(O_CREAT), unlink, touch new,  unlink new"
+
+test_17() {
+    replay_barrier mds
+    multiop $DIR/$tfile O_c &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    fail mds
+    kill -USR1 $pid || return 1
+    wait $pid || return 2
+    $CHECKSTAT -t file $DIR/$tfile || return 3
+    rm $DIR/$tfile
+}
+run_test 17 "|X| open(O_CREAT), |replay| close"
+
+test_18() {
+    replay_barrier mds
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+    touch $DIR/$tfile-2 || return 1
+    kill -USR1 $pid
+    wait $pid || return 2
 
-touch $MOUNTPT/lustre-works
-replay_barrier mds
-touch $MOUNTPT/lustre-does-not-work
+    fail mds
+    [ -e $DIR/$tfile ] && return 3
+    [ -e $DIR/$tfile-2 ] || return 4
+    # this touch frequently fails
+    touch $DIR/$tfile-3 || return 5
+    munlink $DIR/$tfile-2 || return 6
+    munlink $DIR/$tfile-3 || return 7
+    return 0
+}
+run_test 18 "|X| open(O_CREAT), unlink, touch new, close, touch, unlink"
+
+# bug 1855 (a simpler form of test_11 above)
+test_19() {
+    replay_barrier mds
+    mcreate $DIR/$tfile
+    echo "old" > $DIR/$tfile
+    mv $DIR/$tfile $DIR/$tfile-2
+    grep old $DIR/$tfile-2
+    fail mds
+    grep old $DIR/$tfile-2 || return 2
+}
+run_test 19 "|X| mcreate, open, write, rename "
+
+test_20() {
+    replay_barrier mds
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 1
+    [ -e $DIR/$tfile ] && return 2
+    return 0
+}
+run_test 20 "|X| open(O_CREAT), unlink, replay, close (test mds_cleanup_orphans)"
+
+test_21() {
+    replay_barrier mds
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+    touch $DIR/g11 || return 1
+
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 2
+    [ -e $DIR/$tfile ] && return 3
+    touch $DIR/h11 || return 4
+    return 0
+}
+run_test 21 "|X| open(O_CREAT), unlink touch new, replay, close (test mds_cleanup_orphans)"
+
+test_22() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+
+    replay_barrier mds
+    rm -f $DIR/$tfile
+
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 1
+    [ -e $DIR/$tfile ] && return 2
+    return 0
+}
+run_test 22 "open(O_CREAT), |X| unlink, replay, close (test mds_cleanup_orphans)"
+
+test_23() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+
+    replay_barrier mds
+    rm -f $DIR/$tfile
+    touch $DIR/g11 || return 1
+
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 2
+    [ -e $DIR/$tfile ] && return 3
+    touch $DIR/h11 || return 4
+    return 0
+}
+run_test 23 "open(O_CREAT), |X| unlink touch new, replay, close (test mds_cleanup_orphans)"
+
+test_24() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+
+    replay_barrier mds
+    fail mds
+    rm -f $DIR/$tfile
+    kill -USR1 $pid
+    wait $pid || return 1
+    [ -e $DIR/$tfile ] && return 2
+    return 0
+}
+run_test 24 "open(O_CREAT), replay, unlink, close (test mds_cleanup_orphans)"
+
+test_25() {
+    multiop $DIR/$tfile O_tSc &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+
+    replay_barrier mds
+    fail mds
+    kill -USR1 $pid
+    wait $pid || return 1
+    [ -e $DIR/$tfile ] && return 2
+    return 0
+}
+run_test 25 "open(O_CREAT), unlink, replay, close (test mds_cleanup_orphans)"
+
+test_26() {
+    replay_barrier mds
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile-1
+    rm -f $DIR/$tfile-2
+    kill -USR1 $pid2
+    wait $pid2 || return 1
+
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 26 "|X| open(O_CREAT), unlink two, close one, replay, close one (test mds_cleanup_orphans)"
+
+test_27() {
+    replay_barrier mds
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile-1
+    rm -f $DIR/$tfile-2
+
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 1
+    kill -USR1 $pid2
+    wait $pid2 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 27 "|X| open(O_CREAT), unlink two, replay, close two (test mds_cleanup_orphans)"
+
+test_28() {
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    replay_barrier mds
+    rm -f $DIR/$tfile-1
+    rm -f $DIR/$tfile-2
+    kill -USR1 $pid2
+    wait $pid2 || return 1
+
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 28 "open(O_CREAT), |X| unlink two, close one, replay, close one (test mds_cleanup_orphans)"
+
+test_29() {
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    replay_barrier mds
+    rm -f $DIR/$tfile-1
+    rm -f $DIR/$tfile-2
+
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 1
+    kill -USR1 $pid2
+    wait $pid2 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 29 "open(O_CREAT), |X| unlink two, replay, close two (test mds_cleanup_orphans)"
+
+test_30() {
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile-1
+    rm -f $DIR/$tfile-2
+
+    replay_barrier mds
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 1
+    kill -USR1 $pid2
+    wait $pid2 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 30 "open(O_CREAT) two, unlink two, replay, close two (test mds_cleanup_orphans)"
+
+test_31() {
+    multiop $DIR/$tfile-1 O_tSc &
+    pid1=$!
+    multiop $DIR/$tfile-2 O_tSc &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile-1
+
+    replay_barrier mds
+    rm -f $DIR/$tfile-2
+    fail mds
+    kill -USR1 $pid1
+    wait $pid1 || return 1
+    kill -USR1 $pid2
+    wait $pid2 || return 2
+    [ -e $DIR/$tfile-1 ] && return 3
+    [ -e $DIR/$tfile-2 ] && return 4
+    return 0
+}
+run_test 31 "open(O_CREAT) two, unlink one, |X| unlink one, close two (test mds_cleanup_orphans)"
+
+# tests for bug 2104; completion without crashing is success.  The close is
+# stale, but we always return 0 for close, so the app never sees it.
+test_32() {
+    multiop $DIR/$tfile O_c &
+    pid1=$!
+    multiop $DIR/$tfile O_c &
+    pid2=$!
+    # give multiop a chance to open
+    sleep 1
+    mds_evict_client
+    df $MOUNT || df $MOUNT || return 1
+    kill -USR1 $pid1
+    kill -USR1 $pid2
+    sleep 1
+    return 0
+}
+run_test 32 "close() notices client eviction; close() after client eviction"
+
+# Abort recovery before client complete
+test_33() {
+    replay_barrier mds
+    touch $DIR/$tfile
+    fail_abort mds
+    # this file should be gone, because the replay was aborted
+    $CHECKSTAT -t file $DIR/$tfile && return 1
+    return 0
+}
+run_test 33 "abort recovery before client does replay"
+
+test_34() {
+    multiop $DIR/$tfile O_c &
+    pid=$!
+    # give multiop a chance to open
+    sleep 1 
+    rm -f $DIR/$tfile
+
+    replay_barrier mds
+    fail_abort mds
+    kill -USR1 $pid
+    [ -e $DIR/$tfile ] && return 1
+    sleep 3
+    # wait for commitment of removal
+    return 0
+}
+run_test 34 "abort recovery before client does replay (test mds_cleanup_orphans)"
+
+# bug 2278 - generate one orphan on OST, then destroy it during recovery from llog 
+test_35() {
+    touch $DIR/$tfile
+
+    echo 0x80000119 > /proc/sys/lustre/fail_loc
+    rm -f $DIR/$tfile &
+    sleep 1
+    # give a chance to remove from MDS
+    fail_abort mds
+    $CHECKSTAT -t file $DIR/$tfile && return 1 || true
+}
+run_test 35 "test recovery from llog for unlink op"
 
-stop client
-stop ost
-stop mds
+equals_msg test complete, cleaning up
+cleanup
diff --git a/lustre/tests/run-llog.sh b/lustre/tests/run-llog.sh
new file mode 100644
index 0000000000000000000000000000000000000000..64d64038d0dfc66f800b6aefe997f99b3aa2cb83
--- /dev/null
+++ b/lustre/tests/run-llog.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+insmod ../obdclass/llog_test.o
+../utils/lctl modules > /r/tmp/ogdb-localhost.localdomain
+echo "NOW reload debugging syms.."
+
+# Using ignore_errors will allow lctl to cleanup even if the test
+# fails.
+../utils/lctl <<EOF
+ignore_errors
+newdev
+attach llog_test llt_name llt_uuid
+setup mds1
+cleanup
+detach
+EOF
+rmmod llog_test
diff --git a/lustre/tests/runregression-brw.sh b/lustre/tests/runregression-brw.sh
index 395ceb5423e000d7970a4d1962cb01ae6d0df659..34a55b001a5541dc5f16ac84809aea4ceebf26e1 100644
--- a/lustre/tests/runregression-brw.sh
+++ b/lustre/tests/runregression-brw.sh
@@ -3,7 +3,7 @@ SRCDIR="`dirname $0`/"
 export PATH=/sbin:/usr/sbin:$SRCDIR/../utils:$PATH
 
 LOOPS=${LOOPS:-1}
-COUNT=${COUNT:-1000000}
+COUNT=${COUNT:-100000}
 COUNT_10=`expr $COUNT / 10`
 COUNT_100=`expr $COUNT / 100`
 
diff --git a/lustre/tests/runregression-net.sh b/lustre/tests/runregression-net.sh
index 6de9a6c0f877be11d9fbbc20f142c6b4fc303ba8..73e81ca4f031c175b43edaed15f517a9c3c73d76 100644
--- a/lustre/tests/runregression-net.sh
+++ b/lustre/tests/runregression-net.sh
@@ -2,7 +2,7 @@
 SRCDIR="`dirname $0`/"
 export PATH=/sbin:/usr/sbin:$SRCDIR/../utils:$PATH
 
-COUNT=${COUNT:-1000000}
+COUNT=${COUNT:-100000}
 COUNT_10=`expr $COUNT / 10`
 COUNT_100=`expr $COUNT / 100`
 COUNT_1000=`expr $COUNT / 1000`
diff --git a/lustre/tests/runvmstat b/lustre/tests/runvmstat
index f414cccfb2794bc76644201ec1b9f65b94f1e748..1030930b8cf40161a4d488a2cac077c0a30a32a2 100755
--- a/lustre/tests/runvmstat
+++ b/lustre/tests/runvmstat
@@ -1,6 +1,18 @@
 #!/bin/sh
+null() {
+	:
+}
+
+if [ $1 == "-q" ]; then
+	echo "echo off"
+	ECHO="null"
+	shift
+else
+	echo "echo on"
+	ECHO=echo
+fi
 vmstat 1 | while read LINE ; do
 	LINE="`date +%s`: $LINE"
-	echo "$LINE"
+	$ECHO "$LINE"
 	[ "$1" ] && echo "$LINE" >> $1
 done
diff --git a/lustre/tests/sanity-buffalo.sh b/lustre/tests/sanity-buffalo.sh
new file mode 100755
index 0000000000000000000000000000000000000000..70e4a392dfce17e8c610af9c9a56be4134324a4e
--- /dev/null
+++ b/lustre/tests/sanity-buffalo.sh
@@ -0,0 +1,231 @@
+#!/bin/sh
+
+# sanity-buffalo.sh
+#
+# This script is used to report the results from a sanity run to buffalo.
+#
+# Assumptions: 
+# - the target host on which you are running the test (be it
+#   a real machine or a uml session) is accessible via DSH
+
+export TMP=${TMP:-"/tmp"}
+export LOG=${LOG:-"$TMP/sanity-buffalo.log"}
+export DMESGLOG=${DMESGLOG:-"$TMP/sanity-buffalo-dmesg.log"}
+export OUTPUT=${OUTPUT:-"$TMP/buffalo_mail"}
+export DSH=${DSH:-"pdsh -S -w"}
+export LUSTRE_SRC=${LUSTRE_SRC:-"$PWD/.."}
+export LTESTDIR=${LTESTDIR:-"$PWD/../../ltest"}
+export TARGET=${TARGET:-"uml"}
+export SCP=${SCP:-"scp"}
+#export NO_SHARED_FS=0
+
+# Changeable buffalo config variables.
+
+# The following RECIPIENTS string sends results to the buffalo-sandbox.
+RECIPIENTS=${RECIPIENTS:-"buffalo-sandbox@clusterfs.com"}
+# The following RECIPIENTS string sends results to buffalo proper.
+# RECIPIENTS=${RECIPIENTS:-"buffalo_results@clusterfs.com"}
+
+export TESTNAME=${TESTNAME:-"sanity-buffalo"}
+export TESTDESC=${TESTDESC:-"Local test in $TARGET for correctness"}
+export TESTGROUP=${TESTGROUP:-"correctness"}
+export LUSTRE_TAG=${LUSTRE_TAG:-`cat $PWD/CVS/Tag | cut -c 2-`}
+export TESTARCH=${TESTARCH:-`uname -r`}
+export NETWORKTYPE=${NETWORKTYPE:-"tcp"}
+export MACHINENAME=${MACHINENAME:-`hostname`}
+
+usage() {
+
+    echo "echo
+Usage: sanity-buffalo.sh --sender=email_address [--config=config_name] [--test=test_name] [--extra-params=extra_parameters] [--target=hostname] [--help]"
+    if [ x$1 = x-h ]
+        then
+        echo "
+
+--sender=email_address
+    Email address of the person running the test. (Required)
+
+--config=config_name
+    Config type to use for lustre setup. Any of the standard script names
+    from lustre/tests are allowable:
+    lov, local, mount2lov, local-large-inode (default)
+
+--test=test_script
+    Name of the test script to run. Default is \"sanity.sh\".   
+
+--target=hostname
+    The machine (or uml session) on which to run the test. 
+    Defaults to \"uml\"
+
+--extra-params=extra_parameters
+    Extra parameters to pass to the test script.
+    e.g. --extra-params=\"START=' ' CLEAN=' '\"
+    NOTE: NAME=lov should not be set here, use --config
+
+--help
+    Display this usage message
+
+"
+        exit 0
+    else
+        exit 1
+    fi
+}
+
+check_mail() {
+    if [ -z "$SENDER" ] ; then
+	echo "Please supply a valid email address for --sender"
+	usage
+    fi
+}
+
+check_config() {
+    if [ -z "$CONFIG_NAME" ] ; then
+        echo "Using default config: local-large-inode"
+        CONFIG_NAME="local-large-inode"
+    fi
+}
+
+check_test() {
+    if [ -z "$TESTSCRIPT" ] ; then
+	echo "Running default test: sanity.sh"
+	TESTSCRIPT="sanity.sh"
+    fi
+}
+
+
+do_prepare() {
+    if [ -e $LOG ] ; then
+	rm -fr $LOG
+    fi
+    dmesg -c > /dev/null
+    $DSH $TARGET "dmesg -c > /dev/null" || exit 1
+    return 0
+}
+
+run_test() {
+    $DSH $TARGET "cd $LUSTRE_SRC/tests && PATH=/sbin:/usr/sbin:\$PATH NAME=$CONFIG_NAME sh llmount.sh 2>&1" | dshbak -c >> $LOG
+    if ! [ $? = 0 ] ; then
+        echo "Can not mount lustre on remoute machine: $TARGET "
+        exit 2
+    fi
+    if [ $NO_SHARED_FS ]; then
+	$SCP $TARGET:$LUSTRE_SRC/tests/${CONFIG_NAME}.xml $PWD/config.xml
+	if ! [ $? = 0 ] ; then
+	    echo "Can not get the config file from remoute machine: $TARGET "
+	    exit 3
+	fi
+    fi
+
+    COMMAND="cd $LUSTRE_SRC/tests && NAME=$CONFIG_NAME PATH=/sbin:/usr/sbin:\$PATH $EXTRA_PARAMS sh $TESTSCRIPT"
+    echo >> $LOG;echo "COMMAND: $COMMAND" >> $LOG;echo >> $LOG
+
+    $DSH $TARGET "$COMMAND 2>&1" | dshbak -c >> $LOG
+    return $?
+}
+
+do_eval() {
+    RC=$1
+
+    if [ $RC -eq 0 ]; then
+	RESULT="pass"
+    else
+	RESULT="fail"
+    fi
+
+    if [ "$RESULT" = "fail" ] ; then   
+	$DSH $TARGET "dmesg" | dshbak -c >> $DMESGLOG
+    fi
+}
+
+send_report() {
+    . $LTESTDIR/acceptance/harness/config/common/buffalo.sh
+
+    if [ $NO_SHARED_FS ]; then
+	CONFIG="$PWD/config.xml"
+    else
+	CONFIG="${LUSTRE_SRC}/tests/${CONFIG_NAME}.xml"
+    fi    
+    CONFIGDESC=${CONFIGDESC:-"${TARGET}-${CONFIG_NAME}"}	   
+
+    ### send buffalo reports
+    echo "Sending buffalo report..."
+    rm -fr $OUTPUT
+    buffalo_format_result > $OUTPUT
+    buffalo_format_config $CONFIG >> $OUTPUT
+    buffalo_format_log $LOG >> $OUTPUT
+    buffalo_format_dmesg $DMESGLOG >> $OUTPUT
+    buffalo_send_report $OUTPUT
+    rm -f $OUTPUT
+    rm -f $DMESGLOG
+    rm -f $LOG
+    echo "done."
+}
+
+do_cleanup() {
+    $DSH $TARGET "cd $LUSTRE_SRC/tests && NAME=$CONFIG_NAME sh llmountcleanup.sh 2>&1" | dshbak -c >> $LOG
+    if ! [ $? = 0  ] ; then
+	echo "failed to clean up lustre"
+    fi	 
+}
+
+options=`getopt -o h --long extra-params:,target:,sender:,config:,test:,help -- "$@"`
+
+if [ $? -ne 0 ] ; then
+    usage
+fi
+eval set -- "$options"
+while true
+  do
+  case "$1" in
+      --config)
+          CONFIG_NAME=$2
+          shift 2         ;;
+      --sender)
+	  SENDER=$2
+	  shift 2         ;;
+      --target)
+	  TARGET=$2
+	  shift 2         ;; 
+      --extra-params)
+	  EXTRA_PARAMS=$2
+	  shift 2         ;;
+      --test)
+	  TESTSCRIPT=$2    
+          shift 2         ;; 
+      --help)
+          usage -h        ;;
+      -h)
+          usage -h        ;;
+      --)
+          shift
+          break           ;;
+  esac
+done
+
+if [ ! -d ${LUSTRE_SRC} ]; then
+    echo "LUSTRE_SRC dir $LUSTRE_SRC doesn't exist"
+    exit 1
+fi
+
+if [ ! -d ${LTESTDIR} ]; then
+    echo "LTESTDIR dir $LTESTDIR doesn't exist"
+    exit 2
+fi
+
+# Gather some buffalo variable before we run the test.
+export KERNEL=`$DSH $TARGET uname -r | sed "s/^.*\ //g"`
+export LUSTRE_BUILD=`${LUSTRE_SRC}/utils/lctl lustre_build_version 2>/dev/null|grep "^lctl" | awk '/^lctl/ {print $3}'`
+
+check_mail && check_config && check_test
+
+do_prepare
+run_test
+do_eval $?
+do_cleanup
+
+send_report
+
+exit 0    
+
+
diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh
index 09eb8e9dcda8a336a57cf305c7897e766951879e..c22504ba20cb3080ffa47f2120bdf6fecf43d126 100644
--- a/lustre/tests/sanity.sh
+++ b/lustre/tests/sanity.sh
@@ -7,7 +7,9 @@
 set -e
 
 ONLY=${ONLY:-"$*"}
-ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"35 32q 37 39"} # bugs 1360, 1504
+# bug number for skipped test: 1979
+ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"42b"}
+# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 SRCDIR=`dirname $0`
 PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$PATH
@@ -22,6 +24,9 @@ OPENFILE=${OPENFILE:-openfile}
 OPENUNLINK=${OPENUNLINK:-openunlink}
 TOEXCL=${TOEXCL:-toexcl}
 TRUNCATE=${TRUNCATE:-truncate}
+MUNLINK=${MUNLINK:-munlink}
+SOCKETSERVER=${SOCKETSERVER:-socketserver}
+SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
 
 if [ $UID -ne 0 ]; then
 	RUNAS_ID="$UID"
@@ -38,19 +43,21 @@ SAVE_PWD=$PWD
 clean() {
 	echo -n "cln.."
 	sh llmountcleanup.sh > /dev/null || exit 20
+	I_MOUNTED=no
 }
 CLEAN=${CLEAN:-clean}
 
 start() {
 	echo -n "mnt.."
 	sh llrmount.sh > /dev/null || exit 10
+	I_MOUNTED=yes
 	echo "done"
 }
 START=${START:-start}
 
 log() {
 	echo "$*"
-	lctl mark "$*" || true
+	lctl mark "$*" 2> /dev/null || true
 }
 
 run_one() {
@@ -58,37 +65,68 @@ run_one() {
 		$START
 	fi
 	log "== test $1: $2"
-	test_$1 || error
+	test_$1 || error "test_$1: $?"
 	pass
 	cd $SAVE_PWD
 	$CLEAN
 }
 
-run_test() {
-	for O in $ONLY; do
-		if [ "`echo $1 | grep '\<'$O'[a-z]*\>'`" ]; then
-			echo ""
-			run_one $1 "$2"
-			return $?
-		else
-			echo -n "."
-		fi
-	done
-	for X in $EXCEPT $ALWAYS_EXCEPT; do
-		if [ "`echo $1 | grep '\<'$X'[a-z]*\>'`" ]; then
-			echo "skipping excluded test $1"
-			return 0
-		fi
-	done
-	if [ -z "$ONLY" ]; then
-		run_one $1 "$2"
-		return $?
-	fi
+build_test_filter() {
+        for O in $ONLY; do
+            eval ONLY_${O}=true
+        done
+        for E in $EXCEPT $ALWAYS_EXCEPT; do
+            eval EXCEPT_${E}=true
+        done
+}
+
+_basetest() {
+    echo $*
+}
+
+basetest() {
+    IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
 }
 
+run_test() {
+         base=`basetest $1`
+         if [ "$ONLY" ]; then
+                 testname=ONLY_$1
+                 if [ ${!testname}x != x ]; then
+ 			run_one $1 "$2"
+ 			return $?
+                 fi
+                 testname=ONLY_$base
+                 if [ ${!testname}x != x ]; then
+                         run_one $1 "$2"
+                         return $?
+                 fi
+                 echo -n "."
+                 return 0
+ 	fi
+        testname=EXCEPT_$1
+        if [ ${!testname}x != x ]; then
+                 echo "skipping excluded test $1"
+                 return 0
+        fi
+        testname=EXCEPT_$base
+        if [ ${!testname}x != x ]; then
+                 echo "skipping excluded test $1 (base $base)"
+                 return 0
+        fi
+        run_one $1 "$2"
+ 	return $?
+}
+
+[ "$SANITYLOG" ] && rm -f $SANITYLOG || true
+
 error() { 
-	echo "FAIL: $@"
-	exit 1
+	log "FAIL: $@"
+	if [ "$SANITYLOG" ]; then
+		echo "FAIL: $@" >> $SANITYLOG
+	else
+		exit 1
+	fi
 }
 
 pass() { 
@@ -108,8 +146,15 @@ fi
 DIR=${DIR:-$MOUNT}
 [ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && exit 99
 
+LOVNAME=`cat /proc/fs/lustre/llite/fs0/lov/common_name`
+STRIPECOUNT=`cat /proc/fs/lustre/lov/$LOVNAME/numobd`
+
+[ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
+[ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
 rm -rf $DIR/[Rdfs][1-9]*
 
+build_test_filter
+
 echo preparing for tests involving mounts
 EXT2_DEV=${EXT2_DEV:-/tmp/SANITY.LOOP}
 touch $EXT2_DEV
@@ -117,7 +162,7 @@ mke2fs -F $EXT2_DEV 1000 > /dev/null
 
 test_0() {
 	touch $DIR/f
-	$CHECKSTAT -t file $DIR/f || error 
+	$CHECKSTAT -t file $DIR/f || error
 	rm $DIR/f
 	$CHECKSTAT -a $DIR/f || error
 }
@@ -148,7 +193,7 @@ test_2b() {
 	rm -r $DIR/d2
 	$CHECKSTAT -a $DIR/d2 || error
 }
-run_test 2b "rm -r .../d2; touch .../d2/f ======================"
+run_test 2b "rm -r .../d2; checkstat .../d2/f ======================"
 
 test_3a() {
 	mkdir $DIR/d3
@@ -157,6 +202,9 @@ test_3a() {
 run_test 3a "mkdir .../d3 ======================================"
 
 test_3b() {
+	if [ ! -d $DIR/d3 ]; then
+		mkdir $DIR/d3
+	fi
 	touch $DIR/d3/f
 	$CHECKSTAT -t file $DIR/d3/f || error
 }
@@ -175,6 +223,9 @@ test_4a() {
 run_test 4a "mkdir .../d4 ======================================"
 
 test_4b() {
+	if [ ! -d $DIR/d4 ]; then
+		mkdir $DIR/d4
+	fi
 	mkdir $DIR/d4/d2
 	$CHECKSTAT -t dir $DIR/d4/d2 || error
 }
@@ -197,6 +248,10 @@ run_test 6a "touch .../f6a; chmod .../f6a ======================"
 
 test_6b() {
 	[ $RUNAS_ID -eq $UID ] && echo "skipping test 6b" && return
+	if [ ! -f $DIR/f6a ]; then
+		touch $DIR/f6a
+		chmod 0666 $DIR/f6a
+	fi
 	$RUNAS chmod 0444 $DIR/f6a && error
 	$CHECKSTAT -t file -p 0666 -u \#$UID $DIR/f6a || error
 }
@@ -212,6 +267,10 @@ run_test 6c "touch .../f6c; chown .../f6c ======================"
 
 test_6d() {
 	[ $RUNAS_ID -eq $UID ] && echo "skipping test 6d" && return
+	if [ ! -f $DIR/f6c ]; then
+		touch $DIR/f6c
+		chown $RUNAS_ID $DIR/f6c
+	fi
 	$RUNAS chown $UID $DIR/f6c && error
 	$CHECKSTAT -t file -u \#$RUNAS_ID $DIR/f6c || error
 }
@@ -227,11 +286,26 @@ run_test 6e "touch .../f6e; chgrp .../f6e ======================"
 
 test_6f() {
 	[ $RUNAS_ID -eq $UID ] && echo "skipping test 6f" && return
+	if [ ! -f $DIR/f6e ]; then
+		touch $DIR/f6e
+		chgrp $RUNAS_ID $DIR/f6e
+	fi
 	$RUNAS chgrp $UID $DIR/f6e && error
 	$CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/f6e || error
 }
 run_test 6f "$RUNAS chgrp .../f6e (should return error) =="
 
+test_6g() {
+	[ $RUNAS_ID -eq $UID ] && echo "skipping test 6g" && return
+        mkdir $DIR/d6g || error
+        chmod 777 $DIR/d6g || error
+        $RUNAS mkdir $DIR/d6g/d || error
+        chmod g+s $DIR/d6g/d || error
+        mkdir $DIR/d6g/d/subdir
+	$CHECKSTAT -g \#$RUNAS_ID $DIR/d6g/d/subdir || error
+}
+run_test 6g "Is new dir in sgid dir inheriting group?"
+
 test_7a() {
 	mkdir $DIR/d7
 	$MCREATE $DIR/d7/f
@@ -241,6 +315,9 @@ test_7a() {
 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
 
 test_7b() {
+	if [ ! -d $DIR/d7 ]; then
+		mkdir $DIR/d7
+	fi
 	$MCREATE $DIR/d7/f2
 	echo -n foo > $DIR/d7/f2
 	[ "`cat $DIR/d7/f2`" = "foo" ] || error
@@ -335,6 +412,9 @@ test_17a() {
 run_test 17a "symlinks: create, remove (real) =================="
 
 test_17b() {
+	if [ ! -d $DIR/d17 ]; then
+		mkdir $DIR/d17
+	fi
 	ln -s no-such-file $DIR/d17/l-dangle
 	ls -l $DIR/d17
 	$CHECKSTAT -l no-such-file $DIR/d17/l-dangle || error
@@ -350,13 +430,29 @@ test_18() {
 }
 run_test 18 "touch .../f ; ls ... =============================="
 
-test_19() {
-	touch $DIR/f
+test_19a() {
+	touch $DIR/f19
 	ls -l $DIR
-	rm $DIR/f
-	$CHECKSTAT -a $DIR/f || error
+	rm $DIR/f19
+	$CHECKSTAT -a $DIR/f19 || error
+}
+run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
+
+test_19b() {
+	ls -l $DIR/f19 && error || true
+}
+run_test 19b "ls -l .../f19 (should return error) =============="
+
+test_19c() {
+	[ $RUNAS_ID -eq $UID ] && echo "skipping test 19c" && return
+	$RUNAS touch $DIR/f19 && error || true
+}
+run_test 19c "$RUNAS touch .../f19 (should return error) =="
+
+test_19d() {
+	cat $DIR/f19 && error || true
 }
-run_test 19 "touch .../f ; ls -l ... ==========================="
+run_test 19d "cat .../f19 (should return error) =============="
 
 test_20() {
 	touch $DIR/f
@@ -498,6 +594,15 @@ test_24j() {
 }
 run_test 24j "source does not exist ============================" 
 
+test_24k() {
+	mkdir $DIR/R11a $DIR/R11a/d
+	touch $DIR/R11a/f
+	mv $DIR/R11a/f $DIR/R11a/d
+	$CHECKSTAT -a $DIR/R11a/f || error
+	$CHECKSTAT -t file $DIR/R11a/d/f || error
+}
+run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
+
 test_25a() {
 	echo '== symlink sanity ============================================='
 	mkdir $DIR/d25
@@ -507,6 +612,9 @@ test_25a() {
 run_test 25a "create file in symlinked directory ==============="
 
 test_25b() {
+	if [ ! -d $DIR/d25 ]; then
+		run_one	25a
+	fi
 	$CHECKSTAT -t file $DIR/s25/foo || error
 }
 run_test 25b "lookup file in symlinked directory ==============="
@@ -543,6 +651,9 @@ test_26d() {
 run_test 26d "create multiple component recursive symlink ======"
 
 test_26e() {
+	if [ ! -h $DIR/d26-3 ]; then
+		run_one 26d
+	fi
 	rm $DIR/d26-3
 }
 run_test 26e "unlink multiple component recursive symlink ======"
@@ -550,52 +661,72 @@ run_test 26e "unlink multiple component recursive symlink ======"
 test_27a() {
 	echo '== stripe sanity =============================================='
 	mkdir $DIR/d27
-	$LSTRIPE $DIR/d27/f0 8192 0 1
-	$CHECKSTAT -t file $DIR/d27/f0
+	$LSTRIPE $DIR/d27/f0 8192 0 1 || error
+	$CHECKSTAT -t file $DIR/d27/f0 || error
 	pass
 	log "== test_27b: write to one stripe file ========================="
-	cp /etc/hosts $DIR/d27/f0
+	cp /etc/hosts $DIR/d27/f0 || error
 }
 run_test 27a "one stripe file =================================="
 
 test_27c() {
-	$LSTRIPE $DIR/d27/f01 8192 0 2
+	[ "$STRIPECOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
+	if [ ! -d $DIR/d27 ]; then
+		mkdir $DIR/d27
+	fi
+	$LSTRIPE $DIR/d27/f01 8192 0 2 || error
+	[ `$LFIND $DIR/d27/f01 | grep -A 10 obdidx | wc -l` -eq 4 ] ||
+		error "two-stripe file doesn't have two stripes"
 	pass
 	log "== test_27d: write to two stripe file file f01 ================"
-	dd if=/dev/zero of=$DIR/d27/f01 bs=4k count=4
+	dd if=/dev/zero of=$DIR/d27/f01 bs=4k count=4 || error
 }
 run_test 27c "create two stripe file f01 ======================="
 
 test_27d() {
-	$LSTRIPE $DIR/d27/fdef 0 -1 0
-	$CHECKSTAT -t file $DIR/d27/fdef
-	#dd if=/dev/zero of=$DIR/d27/fdef bs=4k count=4
+	if [ ! -d $DIR/d27 ]; then
+		mkdir $DIR/d27
+	fi
+	$LSTRIPE $DIR/d27/fdef 0 -1 0 || error
+	$CHECKSTAT -t file $DIR/d27/fdef || error
+	#dd if=/dev/zero of=$DIR/d27/fdef bs=4k count=4 || error
 }
 run_test 27d "create file with default settings ================"
 
 test_27e() {
-	$LSTRIPE $DIR/d27/f12 8192 1 2
+	if [ ! -d $DIR/d27 ]; then
+		mkdir $DIR/d27
+	fi
+	$LSTRIPE $DIR/d27/f12 8192 1 2 || error
 	$LSTRIPE $DIR/d27/f12 8192 1 2 && error
 	$CHECKSTAT -t file $DIR/d27/f12 || error
-	#dd if=/dev/zero of=$DIR/d27/f12 bs=4k count=4
 }
 run_test 27e "lstripe existing file (should return error) ======"
 
-
 test_27f() {
-	$LSTRIPE $DIR/d27/fbad 100 1 2 || true
-	dd if=/dev/zero of=$DIR/d27/f12 bs=4k count=4
-	$LFIND $DIR/d27/fbad
+	if [ ! -d $DIR/d27 ]; then
+		mkdir $DIR/d27
+	fi
+	$LSTRIPE $DIR/d27/fbad 100 1 1 && error
+	dd if=/dev/zero of=$DIR/d27/f12 bs=4k count=4 || error
+	$LFIND $DIR/d27/fbad || error
 }
-run_test 27f "lstripe with bad stripe size (should return error on LOV)"
+run_test 27f "lstripe with bad stripe size (should return error)"
 
 test_27g() {
+	if [ ! -d $DIR/d27 ]; then
+		mkdir $DIR/d27
+	fi
 	$MCREATE $DIR/d27/fnone || error
 	pass
-	log "== test 27h: lfind ============================================"
-	$LFIND $DIR/d27/fnone | grep -q "Has no stripe info" || error
+	log "== test 27h: lfind with no objects ============================"
+	$LFIND $DIR/d27/fnone 2>&1 | grep -q "no stripe info" || error
+	pass
+	log "== test 27i: lfind with some objects =========================="
+	touch $DIR/d27/fsome || error
+	$LFIND $DIR/d27/fsome | grep -q obdidx || error
 }
-run_test 27g "mcreate file without objects to test lfind ======="
+run_test 27g "test lfind ======================================="
 
 test_28() {
 	mkdir $DIR/d28
@@ -603,12 +734,20 @@ test_28() {
 }
 run_test 28 "create/mknod/mkdir with bad file types ============"
 
+cancel_lru_locks() {
+	for d in /proc/fs/lustre/ldlm/namespaces/$1*; do
+		echo clear > $d/lru_size
+	done
+	grep [0-9] /proc/fs/lustre/ldlm/namespaces/$1*/lock_unused_count /dev/null
+}
+
 test_29() {
+	cancel_lru_locks MDC
 	mkdir $DIR/d29
 	touch $DIR/d29/foo
 	log 'first d29'
 	ls -l $DIR/d29
-	MDCDIR=${MDCDIR:-/proc/fs/lustre/ldlm/ldlm/MDC_*}
+	MDCDIR=${MDCDIR:-/proc/fs/lustre/ldlm/namespaces/MDC_*}
 	LOCKCOUNTORIG=`cat $MDCDIR/lock_count`
 	LOCKUNUSEDCOUNTORIG=`cat $MDCDIR/lock_unused_count`
 	log 'second d29'
@@ -634,10 +773,37 @@ test_30() {
 }
 run_test 30 "run binary from Lustre (execve) ==================="
 
-test_31() {
+test_31a() {
 	$OPENUNLINK $DIR/f31 $DIR/f31 || error
+	$CHECKSTAT -a $DIR/f31 || error
+}
+run_test 31a "open-unlink file =================================="
+
+test_31b() {
+	touch $DIR/f31 || error
+	ln $DIR/f31 $DIR/f31b || error
+	multiop $DIR/f31b Ouc || error
+	$CHECKSTAT -t file $DIR/f31 || error
+}
+run_test 31b "unlink file with multiple links while open ======="
+
+test_31c() {
+	touch $DIR/f31 || error
+	ln $DIR/f31 $DIR/f31c || error
+	multiop $DIR/f31 O_uc &
+	MULTIPID=$!
+	multiop $DIR/f31c Ouc
+	usleep 500
+	kill -USR1 $MULTIPID
+	wait $MUTLIPID
 }
-run_test 31 "open-unlink file =================================="
+run_test 31c "open-unlink file with multiple links ============="
+
+test_31d() {
+	opendirunlink $DIR/d31d $DIR/d31d || error
+	$CHECKSTAT -a $DIR/d31d || error
+}
+run_test 31d "remove of open directory ========================="
 
 test_32a() {
 	echo "== more mountpoints and symlinks ================="
@@ -808,26 +974,47 @@ test_32o() {
 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/test_file"
 
 test_32p() {
+    log 32p_1
 	rm -fr $DIR/d32p
+    log 32p_2
 	rm -f $DIR/test_file
+    log 32p_3
 	touch $DIR/test_file 
+    log 32p_4
 	mkdir -p $DIR/d32p/tmp    
+    log 32p_5
 	TMP_DIR=$DIR/d32p/tmp       
+    log 32p_6
 	ln -s $DIR/test_file $TMP_DIR/symlink12 
+    log 32p_7
 	ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02 
+    log 32p_8
 	cat $DIR/d32p/tmp/symlink12 || error
-	cat $DIR/d32p/symlink02  || error
+    log 32p_9
+	cat $DIR/d32p/symlink02 || error
+    log 32p_10
 }
 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/test_file"
 
 test_32q() {
 	[ -e $DIR/d32q ] && rm -fr $DIR/d32q
 	mkdir -p $DIR/d32q
+        touch $DIR/d32q/under_the_mount
 	mount -t ext2 -o loop $EXT2_DEV $DIR/d32q
-	ls $DIR/d32q || error
+	ls $DIR/d32q/under_the_mount &&  error || true
 	umount $DIR/d32q || error
 }
-run_test 32q "ls a mounted file system ========================="
+run_test 32q "stat follows mountpoints in Lustre ========================="
+
+test_32r() {
+	[ -e $DIR/d32r ] && rm -fr $DIR/d32r
+	mkdir -p $DIR/d32r
+        touch $DIR/d32r/under_the_mount
+	mount -t ext2 -o loop $EXT2_DEV $DIR/d32r
+	ls $DIR/d32r | grep -q under_the_mount &&  error || true
+	umount $DIR/d32r || error
+}
+run_test 32r "opendir follows mountpoints in Lustre ========================="
 
 #   chmod 444 /mnt/lustre/somefile
 #   open(/mnt/lustre/somefile, O_RDWR)
@@ -837,7 +1024,9 @@ test_33() {
 	touch $DIR/test_33_file
 	chmod 444 $DIR/test_33_file
 	chown $RUNAS_ID $DIR/test_33_file
-	$RUNAS $OPENFILE -f O_RDWR $DIR/test_33_file && error || true
+        log 33_1
+        $RUNAS $OPENFILE -f O_RDWR $DIR/test_33_file && error || true
+        log 33_2
 }
 run_test 33 "write file with mode 444 (should return error) ===="
 
@@ -845,25 +1034,27 @@ TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
 test_34a() {
 	rm -f $DIR/test_34_file
 	$MCREATE $DIR/test_34_file || error
-	$LFIND $DIR/test_34_file | grep -q "Has no stripe information" || error
+	$LFIND $DIR/test_34_file 2>&1 | grep -q "no stripe info" || error
 	$TRUNCATE $DIR/test_34_file $TEST_34_SIZE || error
-	$LFIND $DIR/test_34_file | grep -q "Has no stripe information" || error
+	$LFIND $DIR/test_34_file 2>&1 | grep -q "no stripe info" || error
 	$CHECKSTAT -s $TEST_34_SIZE $DIR/test_34_file || error
 }
 run_test 34a "truncate file that has not been opened ==========="
 
 test_34b() {
+	[ ! -f $DIR/test_34_file ] && run_one 34a
 	$CHECKSTAT -s $TEST_34_SIZE $DIR/test_34_file || error
 	$OPENFILE -f O_RDONLY $DIR/test_34_file
-	$LFIND $DIR/test_34_file | grep -q "Has no stripe information" || error
+	$LFIND $DIR/test_34_file 2>&1 | grep -q "no stripe info" || error
 	$CHECKSTAT -s $TEST_34_SIZE $DIR/test_34_file || error
 }
 run_test 34b "O_RDONLY opening file doesn't create objects ====="
 
 test_34c() {
+	[ ! -f $DIR/test_34_file ] && run_one 34a 
 	$CHECKSTAT -s $TEST_34_SIZE $DIR/test_34_file || error
 	$OPENFILE -f O_RDWR $DIR/test_34_file
-	$LFIND $DIR/test_34_file | grep -q "Has no stripe information" && error
+	$LFIND $DIR/test_34_file 2>&1 | grep -q "no stripe info" && error
 	$CHECKSTAT -s $TEST_34_SIZE $DIR/test_34_file || error
 }
 run_test 34c "O_RDWR opening file-with-size works =============="
@@ -885,31 +1076,29 @@ test_34e() {
 }
 run_test 34e "create objects, some with size and some without =="
 
-test_35() {
-	cp /bin/sh $DIR/test_35_file
-	chmod 444 $DIR/test_35_file
-	chown $RUNAS_ID $DIR/test_35_file
-	$DIR/test_35_file && error || true
-	rm $DIR/test_35_file
+test_35a() {
+	cp /bin/sh $DIR/test_35a_file
+	chmod 444 $DIR/test_35a_file
+	chown $RUNAS_ID $DIR/test_35a_file
+	$RUNAS $DIR/test_35a_file && error || true
+	rm $DIR/test_35a_file
 }
-run_test 35 "exec file with mode 444 (should return error) ====="
+run_test 35a "exec file with mode 444 (should return and not leak) ====="
+
 
 test_36a() {
-	sleep 1		# we need a rest, or UMLs clock becomes skewed
 	rm -f $DIR/test_36_file
 	utime $DIR/test_36_file || error
 }
 run_test 36a "MDS utime check (mknod, utime) ==================="
 
 test_36b() {
-	sleep 1
 	echo "" > $DIR/test_36_file
 	utime $DIR/test_36_file || error
 }
 run_test 36b "OST utime check (open, utime) ===================="
 
 test_36c() {
-	sleep 1
 	rm -f $DIR/d36/test_36_file
 	mkdir $DIR/d36
 	chown $RUNAS_ID $DIR/d36
@@ -918,15 +1107,15 @@ test_36c() {
 run_test 36c "non-root MDS utime check (mknod, utime) =========="
 
 test_36d() {
-	sleep 1
+	[ ! -d $DIR/d36 ] && run_one 36c
 	echo "" > $DIR/d36/test_36_file
 	$RUNAS utime $DIR/d36/test_36_file || error
 }
 run_test 36d "non-root OST utime check (open, utime) ==========="
 
 test_36e() {
-	sleep 1
 	[ $RUNAS_ID -eq $UID ] && return
+	[ ! -d $DIR/d36 ] && mkdir $DIR/d36
 	touch $DIR/d36/test_36_file2
 	$RUNAS utime $DIR/d36/test_36_file2 && error || true
 }
@@ -942,7 +1131,6 @@ test_37() {
 }
 run_test 37 "ls a mounted file system to check old content ====="
 
-# open(file, O_DIRECTORY) will leak a request and not cleanup (bug 1501)
 test_38() {
 	o_directory $DIR/test38
 }
@@ -976,6 +1164,406 @@ test_41() {
 }
 run_test 41 "test small file write + fstat ====================="
 
+count_ost_writes() {
+        cat /proc/fs/lustre/osc/*/stats |
+            awk -vwrites=0 '/ost_write/ { writes += $2 } END { print writes; }'
+}
+start_kupdated() {
+	# in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs
+	kill -CONT `pidof kupdated`
+}
+stop_kupdated() {
+	# in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
+	kill -STOP `pidof kupdated`
+	trap start_kupdated EXIT
+}
+
+# Tests 42* verify that our behaviour is correct WRT caching, file closure,
+# file truncation, and file removal.
+test_42a() {
+	cancel_lru_locks OSC
+	stop_kupdated
+        sync # just to be safe
+        BEFOREWRITES=`count_ost_writes`
+        dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
+        AFTERWRITES=`count_ost_writes`
+        [ $BEFOREWRITES -eq $AFTERWRITES ] || \
+		error "$BEFOREWRITES < $AFTERWRITES"
+	start_kupdated
+}
+run_test 42a "ensure that we don't flush on close =============="
+
+test_42b() {
+	cancel_lru_locks OSC
+	stop_kupdated
+        sync
+        dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
+        BEFOREWRITES=`count_ost_writes`
+        $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
+        AFTERWRITES=`count_ost_writes`
+        [ $BEFOREWRITES -eq $AFTERWRITES ] ||
+            error "$BEFOREWRITES < $AFTERWRITES on unlink"
+        BEFOREWRITES=`count_ost_writes`
+        sync || error "sync: $?"
+        AFTERWRITES=`count_ost_writes`
+        [ $BEFOREWRITES -eq $AFTERWRITES ] ||
+            error "$BEFOREWRITES < $AFTERWRITES on sync"
+        dmesg | grep 'error from obd_brw_async' && error 'error writing back'
+	start_kupdated
+        return 0
+}
+run_test 42b "test destroy of file with cached dirty data ======"
+
+# if these tests just want to test the effect of truncation,
+# they have to be very careful.  consider:
+# - the first open gets a {0,EOF}PR lock
+# - the first write conflicts and gets a {0, count-1}PW
+# - the rest of the writes are under {count,EOF}PW
+# - the open for truncate tries to match a {0,EOF}PR
+#   for the filesize and cancels the PWs.
+# any number of fixes (don't get {0,EOF} on open, match
+# composite locks, do smarter file size management) fix
+# this, but for now we want these tests to verify that
+# the cancelation with truncate intent works, so we
+# start the file with a full-file pw lock to match against
+# until the truncate.
+trunc_test() {
+        test=$1
+        file=$DIR/$test
+        offset=$2
+	cancel_lru_locks OSC
+	stop_kupdated
+	# prime the file with 0,EOF PW to match
+	touch $file
+        $TRUNCATE $file 0
+        sync; sync
+	# now the real test..
+        dd if=/dev/zero of=$file bs=1024 count=100
+        BEFOREWRITES=`count_ost_writes`
+        $TRUNCATE $file $offset
+        cancel_lru_locks OSC
+        AFTERWRITES=`count_ost_writes`
+	start_kupdated
+}
+
+test_42c() {
+        trunc_test 42c 1024
+        [ $BEFOREWRITES -eq $AFTERWRITES ] && \
+            error "$BEFOREWRITES < $AFTERWRITES on truncate"
+        rm $file
+}
+run_test 42c "test partial truncate of file with cached dirty data ===="
+
+test_42d() {
+        trunc_test 42d 0
+        [ $BEFOREWRITES -eq $AFTERWRITES ] || \
+            error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
+        rm $file
+}
+run_test 42d "test complete truncate of file with cached dirty data ===="
+
+test_43() {
+	mkdir $DIR/d43
+	cp -p /bin/ls $DIR/d43/f
+	exec 100>> $DIR/d43/f	
+	$DIR/d43/f && error || true
+	exec 100<&-
+}
+run_test 43 "execution of file opened for write should return -ETXTBSY=="
+
+test_43a() {
+        mkdir -p $DIR/d43
+	cp -p `which multiop` $DIR/d43/multiop
+        touch $DIR/d43/g
+        $DIR/d43/multiop $DIR/d43/g o_c &
+        MULTIPID=$!
+        sleep 1
+        multiop $DIR/d43/multiop Oc && error "expected error, got success"
+        kill -USR1 $MULTIPID || return 2
+        wait $MULTIPID || return 3
+}
+run_test 43a "open(RDWR) of file being executed should return -ETXTBSY=="
+
+test_43b() {
+        mkdir -p $DIR/d43
+	cp -p `which multiop` $DIR/d43/multiop
+        touch $DIR/d43/g
+        $DIR/d43/multiop $DIR/d43/g o_c &
+        MULTIPID=$!
+        sleep 1
+        truncate $DIR/d43/multiop 0 && error "expected error, got success"
+        kill -USR1 $MULTIPID || return 2
+        wait $MULTIPID || return 3
+}
+run_test 43b "truncate of file being executed should return -ETXTBSY===="
+
+test_43c() {
+	local testdir="$DIR/43a"
+	mkdir -p $testdir
+	cp $SHELL $testdir/
+	( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |  \
+		( cd $testdir && md5sum -c)
+}
+run_test 43c "md5sum of copy into lustre================================"
+
+test_44() {
+	[  "$STRIPECOUNT" -lt "2" ] && echo "skipping 2-stripe test" && return
+	dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=127
+	dd if=$DIR/f1 bs=4k count=1
+}
+run_test 44 "zero length read from a sparse stripe ============="
+
+test_44a() {
+    local nstripe=`$LCTL lov_getconfig $DIR | grep default_stripe_count: | \
+                         awk '{print $2}'`
+    local stride=`$LCTL lov_getconfig $DIR | grep default_stripe_size: | \
+                      awk '{print $2}'`
+    if [ $nstripe -eq 0 ] ; then
+        nstripe=`$LCTL lov_getconfig $DIR | grep obd_count: | awk '{print $2}'`
+    fi
+
+    OFFSETS="0 $((stride/2)) $((stride-1))"
+    for offset in $OFFSETS ; do
+      for i in `seq 0 $((nstripe-1))`; do
+        rm -f $DIR/44a
+        local GLOBALOFFSETS=""
+        local size=$((((i + 2 * $nstripe )*$stride + $offset)))  # Bytes
+        ll_sparseness_write $DIR/44a $size  || error "ll_sparseness_write"
+        GLOBALOFFSETS="$GLOBALOFFSETS $size"
+        ll_sparseness_verify $DIR/44a $GLOBALOFFSETS \
+                            || error "ll_sparseness_verify $GLOBALOFFSETS"
+
+        for j in `seq 0 $((nstripe-1))`; do
+            size=$((((j + $nstripe )*$stride + $offset)))  # Bytes
+            ll_sparseness_write $DIR/44a $size || error "ll_sparseness_write"
+            GLOBALOFFSETS="$GLOBALOFFSETS $size"
+        done
+        ll_sparseness_verify $DIR/44a $GLOBALOFFSETS \
+                            || error "ll_sparseness_verify $GLOBALOFFSETS"
+      done
+    done
+}
+run_test 44a "test sparse pwrite ==============================="
+
+dirty_osc_total() {
+	tot=0
+	for d in /proc/fs/lustre/osc/*/cur_dirty_bytes; do
+		tot=$(($tot + `cat $d`))
+	done
+	echo $tot
+}
+do_dirty_record() {
+	before=`dirty_osc_total`
+	echo executing "\"$*\""
+	eval $*
+	after=`dirty_osc_total`
+	echo before $before, after $after
+}
+test_45() {
+	f="$DIR/45"
+	stop_kupdated
+	sync
+	do_dirty_record "echo blah > $f"
+	[ $before -eq $after ] && error "write wasn't cached"
+	do_dirty_record "> $f"
+	[ $before -gt $after ] || error "truncate didn't lower dirty count"
+	do_dirty_record "echo blah > $f"
+	[ $before -eq $after ] && error "write wasn't cached"
+	do_dirty_record "sync"
+	[ $before -gt $after ] || error "writeback didn't lower dirty count"
+	do_dirty_record "echo blah > $f"
+	[ $before -eq $after ] && error "write wasn't cached"
+	do_dirty_record "cancel_lru_locks OSC"
+	[ $before -gt $after ] || error "lock cancelation didn't lower dirty count"
+	start_kupdated
+}
+run_test 45 "osc io page accounting ============================"
+
+page_size() {
+	getconf PAGE_SIZE
+}
+
+# in a 2 stripe file (lov.sh), page 63 maps to page 31 in its object.  this
+# test tickles a bug where re-dirtying a page was failing to be mapped to the
+# objects offset and an assert hit when an rpc was built with 63's mapped 
+# offset 31 and 31's raw 31 offset. it also found general redirtying bugs.
+test_46() {
+	f="$DIR/46"
+	stop_kupdated
+	sync
+	dd if=/dev/zero of=$f bs=`page_size` seek=31 count=1
+	sync
+	dd conv=notrunc if=/dev/zero of=$f bs=`page_size` seek=63 count=1
+	dd conv=notrunc if=/dev/zero of=$f bs=`page_size` seek=31 count=1
+	sync
+	start_kupdated
+}
+run_test 46 "dirtying a previously written page ================"
+
+# Check that device nodes are created and then visible correctly (#2091)
+test_47() {
+	cmknod $DIR/test_47_node || error
+}
+run_test 47 "Device nodes check ================================"
+
+test_48() {
+        mkdir $DIR/d48
+        cd $DIR/d48
+        mv $DIR/d48 $DIR/d48.new || error "move directory failed"
+        mkdir $DIR/d48 || error "recreate diectory failed"
+        ls || error "can't list after recreate directory"
+}
+run_test 48 "Access renamed current working directory ========="
+
+test_50() {
+	# bug 1485
+	mkdir $DIR/d50
+	cd $DIR/d50
+	ls /proc/$$/cwd || error
+}
+run_test 50 "special situations: /proc symlinks  ==============="
+
+test_51() {
+	# bug 1516 - create an empty entry right after ".." then split dir
+	mkdir $DIR/d49
+	touch $DIR/d49/foo
+	$MCREATE $DIR/d49/bar
+	rm $DIR/d49/foo
+	createmany -m $DIR/d49/longfile 201
+	FNUM=202
+	while [ `ls -sd $DIR/d49 | awk '{ print $1 }'` -eq 4 ]; do
+		$MCREATE $DIR/d49/longfile$FNUM
+		FNUM=$(($FNUM + 1))
+		echo -n "+"
+	done
+	ls -l $DIR/d49 > /dev/null || error
+}
+run_test 51 "special situations: split htree with empty entry =="
+
+test_52a() {
+	[ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
+	mkdir -p $DIR/d52a
+	touch $DIR/d52a/foo
+	chattr =a $DIR/d52a/foo || error
+	echo bar >> $DIR/d52a/foo || error
+	cp /etc/hosts $DIR/d52a/foo && error
+	rm -f $DIR/d52a/foo 2>/dev/null && error
+	link $DIR/d52a/foo $DIR/d52a/foo_link 2>/dev/null && error
+	echo foo >> $DIR/d52a/foo || error
+	mrename $DIR/d52a/foo $DIR/d52a/foo_ren && error
+	lsattr $DIR/d52a/foo | egrep -q "^-+a-+ $DIR/d52a/foo" || error
+	chattr -a $DIR/d52a/foo || error
+
+	rm -fr $DIR/d52a || error
+}
+run_test 52a "append-only flag test ============================"
+
+test_52b() {
+	[ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
+	mkdir -p $DIR/d52b
+	touch $DIR/d52b/foo
+	chattr =i $DIR/d52b/foo || error
+	cat test > $DIR/d52b/foo && error
+	cp /etc/hosts $DIR/d52b/foo && error
+	rm -f $DIR/d52b/foo 2>/dev/null && error
+	link $DIR/d52b/foo $DIR/d52b/foo_link 2>/dev/null && error
+	echo foo >> $DIR/d52b/foo && error
+	mrename $DIR/d52b/foo $DIR/d52b/foo_ren && error
+	[ -f $DIR/d52b/foo ] || error
+	[ -f $DIR/d52b/foo_ren ] && error
+	lsattr $DIR/d52b/foo | egrep -q "^-+i-+ $DIR/d52b/foo" || error
+	chattr -i $DIR/d52b/foo || error
+
+	rm -fr $DIR/d52b || error
+}
+run_test 52b "immutable flag test =============================="
+
+test_53() {
+        for i in /proc/fs/lustre/osc/OSC*mds1 ; do
+                ostname=`echo $i | cut -d _ -f 3-4`
+                ost_last=`cat /proc/fs/lustre/obdfilter/$ostname/last_id`
+                mds_last=`cat $i/prealloc_last_id`
+                echo "$ostname.last_id=$ost_last ; MDS.last_id=$mds_last"
+                if [ $ost_last != $mds_last ]; then
+                    error "$ostname.last_id=$ost_last ; MDS.last_id=$mds_last"
+                fi
+        done
+}
+run_test 53 "verify that MDS and OSTs agree on pre-creation====="
+
+test_54a() {
+     	$SOCKETSERVER $DIR/socket &
+	sleep 1
+     	$SOCKETCLIENT $DIR/socket || error
+      	$MUNLINK $DIR/socket
+}
+run_test 54a "unix damain socket test ==========================="
+
+test_54b() {
+	f="$DIR/f54b"
+	mknod $f c 1 3
+	chmod 0666 $f
+	dd if=/dev/zero of=$f bs=`page_size` count=1 
+}
+run_test 54b "char device works in lustre"
+
+test_54c() {
+	f="$DIR/f54c"
+	dir="$DIR/dir54c"
+	loopdev="$DIR/loop54c"
+	
+	mknod $loopdev b 7 1
+	dd if=/dev/zero of=$f bs=`page_size` count=1024 > /dev/null
+	chmod 0666 $f
+	losetup $loopdev $f
+	echo "make a loop file system..."	
+	mkfs.ext2  -F $f > /dev/null
+	mkdir -p $dir
+	mount $loopdev $dir 
+	dd if=/dev/zero of=$dir/tmp bs=`page_size` count=30 || error
+	dd if=$dir/tmp of=/dev/zero bs=`page_size` count=30 || error
+	umount $dir
+}
+run_test 54c "loop device works in lustre"
+
+test_54d() {
+	f="$DIR/f54d"
+	string="aaaaaa"
+	mknod $f p
+	[ "$string" = `echo $string > $f | cat $f` ] || error
+}
+run_test 54d "fifo device works in lustre"
+
+test_59() {
+	echo "touch 130 files"
+	for i in `seq 1 130` ; do
+		touch $DIR/59-$i
+	done
+	echo "rm 130 files"
+	for i in `seq 1 130` ; do
+		rm -f $DIR/59-$i
+	done
+	sync
+	sleep 2
+        # wait for commitment of removal
+}
+run_test 59 "verify cancellation of llog records async=========="
+
+test_60() {
+	echo 60 "llog tests run from kernel mode"
+	sh run-llog.sh
+}
+run_test 60 "llog sanity tests run from kernel module =========="
+
+test_61() {
+	f="$DIR/f61"
+	dd if=/dev/zero of=$f bs=`page_size` count=1
+	cancel_lru_locks OSC
+	multiop $f OSMWUc || error
+	sync
+}
+run_test 61 "mmap() writes don't make sync hang =========="
+
 # on the LLNL clusters, runas will still pick up root's $TMP settings,
 # which will not be writable for the runas user, and then you get a CVS
 # error message with a corrupt path string (CVS bug) and panic.
@@ -996,12 +1584,14 @@ test_99a() {
 run_test 99a "cvs init ========================================="
 
 test_99b() {
+	[ ! -d $DIR/d99cvsroot ] && run_one 99a
 	cd /etc/init.d
 	$RUNAS cvs -d $DIR/d99cvsroot import -m "nomesg" d99reposname vtag rtag
 }
 run_test 99b "cvs import ======================================="
 
 test_99c() {
+	[ ! -d $DIR/d99cvsroot ] && run_one 99b
 	cd $DIR
 	mkdir -p $DIR/d99reposname
 	chown $RUNAS_ID $DIR/d99reposname
@@ -1010,6 +1600,7 @@ test_99c() {
 run_test 99c "cvs checkout ====================================="
 
 test_99d() {
+	[ ! -d $DIR/d99cvsroot ] && run_one 99c
 	cd $DIR/d99reposname
 	$RUNAS touch foo99
 	$RUNAS cvs add -m 'addmsg' foo99
@@ -1017,12 +1608,14 @@ test_99d() {
 run_test 99d "cvs add =========================================="
 
 test_99e() {
+	[ ! -d $DIR/d99cvsroot ] && run_one 99c
 	cd $DIR/d99reposname
 	$RUNAS cvs update
 }
 run_test 99e "cvs update ======================================="
 
 test_99f() {
+	[ ! -d $DIR/d99cvsroot ] && run_one 99d
 	cd $DIR/d99reposname
 	$RUNAS cvs commit -m 'nomsg' foo99
 }
@@ -1033,9 +1626,10 @@ TMP=$OLDTMP
 HOME=$OLDHOME
 
 log "cleanup: ======================================================"
-rm -rf $DIR/[Rdfs][1-9]*
-if [ "$I_MOUNTED" = "yes" ]; then
+if [ "$I_MOUNTED" = "yes" -a "`mount | grep ^$NAME`" ]; then
+	rm -rf $DIR/[Rdfs][1-9]*
 	sh llmountcleanup.sh || error
 fi
 
 echo '=========================== finished ==============================='
+[ -f "$SANITYLOG" ] && cat $SANITYLOG && exit 1 || true
diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh
index 33d2e69fbbc96da6f54b87ceae0903917a731a8f..14bd6b2820607f8be554c7a2271e645c1cbb3098 100644
--- a/lustre/tests/sanityN.sh
+++ b/lustre/tests/sanityN.sh
@@ -46,7 +46,7 @@ START=${START:-start}
 
 log() {
 	echo "$*"
-	lctl mark "$*" || true
+	lctl mark "$*" 2> /dev/null || true
 }
 
 run_one() {
@@ -54,7 +54,7 @@ run_one() {
 		$START
 	fi
 	log "== test $1: $2"
-	test_$1 || error
+	test_$1 || error "test_$1: $?"
 	pass
 	cd $SAVE_PWD
 	$CLEAN
@@ -83,7 +83,7 @@ run_test() {
 }
 
 error () {
-	echo "FAIL: $@"
+	log "FAIL: $@"
 	exit 1
 }
 
@@ -103,7 +103,7 @@ DIR2=${DIR2:-$MOUNT2}
 [ -z "`echo $DIR1 | grep $MOUNT1`" ] && echo "$DIR1 not in $MOUNT1" && exit 96
 [ -z "`echo $DIR2 | grep $MOUNT2`" ] && echo "$DIR2 not in $MOUNT2" && exit 95
 
-rm -f $DIR1/[df][0-9]* $DIR1/lnk
+rm -rf $DIR1/[df][0-9]* $DIR1/lnk
 
 test_1a() {
 	touch $DIR1/f1
@@ -145,6 +145,19 @@ test_2b() {
 }
 run_test 2b "check cached attribute updates on 2 mtpt's ========"
 
+# NEED TO SAVE ROOT DIR MODE
+test_2c() {
+	chmod 777 $DIR1
+	$CHECKSTAT -t dir -p 0777 $DIR2 || error
+}
+run_test 2c "check cached attribute updates on 2 mtpt's root ==="
+
+test_2d() {
+	chmod 755 $DIR1
+	$CHECKSTAT -t dir -p 0755 $DIR2 || error
+}
+run_test 2c "check cached attribute updates on 2 mtpt's root ==="
+
 test_3() {
 	( cd $DIR1 ; ln -s this/is/good lnk )
 	[ "this/is/good" = "`perl -e 'print readlink("'$DIR2/lnk'");'`" ] || \
@@ -205,4 +218,19 @@ test_10() {
 }
 run_test 10 "write of file with sub-page size on multiple mounts "
 
-rm -f $DIR1/f[0-9]* $DIR1/lnk
+test_11() {
+	mkdir $DIR1/d11
+	multiop $DIR1/d11/f O_c &
+	MULTIPID=$!
+	cp -p /bin/ls $DIR1/d11/f
+	$DIR2/d11/f
+	RC=$?
+	kill -USR1 $MULTIPID
+	wait $MULTIPID || error
+	[ $RC -eq 0 ] && error || true
+}
+run_test 11 "execution of file opened for write should return error ===="
+
+log "cleanup: ======================================================"
+rm -rf $DIR1/[df][0-9]* $DIR1/lnk || true
+echo '=========================== finished ==============================='
diff --git a/lustre/tests/set_dates.sh b/lustre/tests/set_dates.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b2a9979ac89312e8d541cd2ca41a2befe8bf2865
--- /dev/null
+++ b/lustre/tests/set_dates.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+[ `hostname` = "uml1" ] && date --set="Mar 14 20:21:41 MDT 1973" #101010101
+[ `hostname` = "uml2" ] && date --set="May 26 22:43:22 MDT 1976" #202020202
+[ `hostname` = "uml3" ] && date --set="Aug  9 01:05:03 MDT 1979" #303030303
diff --git a/lustre/tests/sleeptest.c b/lustre/tests/sleeptest.c
new file mode 100644
index 0000000000000000000000000000000000000000..d8beceb0ec8850ccca55c033e91edad2c1bc7b41
--- /dev/null
+++ b/lustre/tests/sleeptest.c
@@ -0,0 +1,115 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define BUFSIZE (4096)
+
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+int main(int argc, char *argv[])
+{
+
+	FILE *w_str;
+	int read_fd;
+	int rc, iter;
+	int line, delta, next;
+	int sleeptime = 0;
+	char *now_time;
+	const char ok_chars[] = "MonTueWedThuFriSatSun"
+				"JanFebMarAprMayJunJulAugSepOctNovDec"
+				"Line 0123456789 of file, written at:\n";
+
+	char buf_r[BUFSIZE];
+
+	char pathname[256] = "/mnt/lustre/linetest_";
+	char *host;
+
+	if (argc > 1) {
+		strncpy(pathname, argv[1], 255);
+		pathname[255] = '\0';
+	}
+
+	host = getenv("HOSTNAME");
+	if (host)
+		strcat(pathname, host);
+
+	if (argc > 2)
+		sleeptime = strtoul(argv[2], NULL, 0);
+
+	if (sleeptime == 0)
+		sleeptime = 30;
+
+	printf("Test file used is: %s at %ds intervals\n", pathname, sleeptime);
+
+	w_str = fopen(pathname, "wb");
+	if (w_str == NULL) {
+		perror("fopen");
+		exit(1);
+	}
+	read_fd = open(pathname, O_RDONLY);
+	if (read_fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	next = 1;
+	delta = 17;
+	iter = 1;
+	while (1) {
+		time_t now;
+		struct tm *t;
+		long offset;
+
+		now = time((time_t *)NULL);
+		t = localtime(&now);
+		now_time = asctime(t);
+
+		printf("iter: %d\n", iter);
+
+		for (line=next; line<(next+delta); line++) {
+			rc = fprintf(w_str, "Line %8d of file, written at: %s",
+				     line, now_time);
+			/* \n comes from ctime() result */
+			if (rc <= 0) {
+				perror("fprintf");
+				exit(4);
+			}
+			rc = fflush(w_str);
+			if (rc != 0) {
+				perror("fflush");
+				exit(5);
+			}
+		}
+		next += delta;
+
+		/* Check for corruption */
+		offset = ftell(w_str);
+		rc = lseek(read_fd, offset & ~4095, SEEK_SET);
+		if (rc != (offset & ~4095)) {
+			perror("lseek");
+			exit(7);
+		}
+
+		rc = read(read_fd, buf_r, min(100, offset & 4095));
+		if (rc != min(100, offset & 4095)) {
+			printf("rc: %d, off %lu buf: '%s'\n", rc,offset,buf_r);
+			exit(8);
+		}
+		buf_r[rc] = 0;
+		/* Chars from "C" days/months, and above Line */
+		if (strspn(buf_r, ok_chars) != rc) {
+			printf("Corruption detected at %lu on %s",
+			       offset & ~4095, now_time);
+			exit(9);
+		}
+
+		sleep(sleeptime);
+		iter++;
+	}
+
+}
diff --git a/lustre/tests/small_write.c b/lustre/tests/small_write.c
index 5bc2d950da954861ca81db702eb1e09dd9a32c03..ebbb2b31a18f493b0d8084c5797495308675aa16 100644
--- a/lustre/tests/small_write.c
+++ b/lustre/tests/small_write.c
@@ -72,7 +72,8 @@ int main (int argc, char **argv) {
 	rc = fstat(fd, &st);
 	if (rc < 0 || st.st_size != bytes) {
 		printf("bad file %lu size first write %lu != %lu: rc %d\n",
-		       st.st_ino, st.st_size, bytes, rc);
+		       (unsigned long)st.st_ino, (unsigned long)st.st_size,
+                       bytes, rc);
 		return 1;
 	}
 
@@ -91,7 +92,8 @@ int main (int argc, char **argv) {
 	rc = fstat(fd, &st);
 	if (rc < 0 || st.st_size != bytes + bytes / 2) {
 		printf("bad file %lu size second write %lu != %lu: rc %d\n",
-		       st.st_ino, st.st_size, bytes, rc);
+		       (unsigned long)st.st_ino, (unsigned long)st.st_size,
+                       bytes, rc);
 		return 1;
 	}
 
@@ -111,7 +113,8 @@ int main (int argc, char **argv) {
 		rc = fstat(fd, &st);
 		if (rc < 0 || st.st_size != bytes + bytes / 2) {
 			printf("bad file size after read %lu != %lu: rc %d\n",
-			       st.st_size, bytes + bytes / 2, rc);
+			       (unsigned long)st.st_size, bytes + bytes / 2,
+                               rc);
 			return 1;
 		}
 
diff --git a/lustre/tests/socketclient b/lustre/tests/socketclient
new file mode 100755
index 0000000000000000000000000000000000000000..5e6e65959a22b255a4b7c3488f3baa357360d0d2
--- /dev/null
+++ b/lustre/tests/socketclient
@@ -0,0 +1,12 @@
+#!/usr/bin/perl -w
+use Socket;
+use strict;
+my ($rendezvous, $line);
+
+$rendezvous = shift || <@ARGV>;
+socket(SOCK, AF_UNIX, SOCK_STREAM, 0)	|| die "socket: $!";
+connect(SOCK, sockaddr_un($rendezvous))	|| die "connect: $!";
+while (defined($line = <SOCK>)) {
+	print $line;
+}
+exit;  
diff --git a/lustre/tests/socketserver b/lustre/tests/socketserver
new file mode 100755
index 0000000000000000000000000000000000000000..25bbb6e50c6f9c8c4873eca0d3d77f258fdbb971
--- /dev/null
+++ b/lustre/tests/socketserver
@@ -0,0 +1,21 @@
+#! /usr/bin/perl -w
+use strict;
+use Socket;
+
+BEGIN { $ENV{PATH} = '/usr/ucb:/bin' }
+sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
+
+my $NAME = <@ARGV>;
+my $uaddr = sockaddr_un($NAME);
+
+socket(Server,AF_UNIX,SOCK_STREAM,0) 	|| die "socket: $!";
+unlink($NAME);
+bind  (Server, $uaddr) 			|| die "bind: $!";
+listen(Server,SOMAXCONN)			|| die "listen: $!";
+
+logmsg "server started on $NAME";
+
+accept(Client,Server);
+logmsg "connection on $NAME";
+print Client "from server\n";
+close Client;
diff --git a/lustre/tests/stat.c b/lustre/tests/stat.c
index b7199005fab43bf827a94b33317e8841088837f9..4ef6bbe34c89fb65274c96c3670de70a5ce7ef14 100644
--- a/lustre/tests/stat.c
+++ b/lustre/tests/stat.c
@@ -1,24 +1,893 @@
 #include <stdio.h>
-#include <sys/types.h>
 #include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
+#include <sys/sysmacros.h>
+#include <pwd.h>
+#include <grp.h>
 #include <unistd.h>
+#include <time.h>
+#include <sys/vfs.h>
+#include <string.h>
+#include <malloc.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#ifdef FLASK_LINUX
+#include <selinux/fs_secure.h>
+#include <linux/flask/security.h>
+#include <selinux/flask_util.h>           /* for is_flask_enabled() */
+#define SECURITY_ID_T security_id_t
+#else
+#define SECURITY_ID_T int
+#endif
+
+#include "stat_fs.h"
+
+void print_human_type(unsigned short mode)
+{
+  switch (mode & S_IFMT)
+    {
+    case S_IFDIR:
+      printf ("Directory");
+      break;
+    case S_IFCHR:
+      printf ("Character Device");
+      break;
+    case S_IFBLK:
+      printf ("Block Device");
+      break;
+    case S_IFREG:
+      printf ("Regular File");
+      break;
+    case S_IFLNK:
+      printf ("Symbolic Link");
+      break;
+    case S_IFSOCK:
+      printf ("Socket");
+      break;
+    case S_IFIFO:
+      printf ("Fifo File");
+      break;
+    default:
+      printf ("Unknown");
+    }
+}
+
+void print_human_fstype(struct statfs *statfsbuf)
+{
+  char *type;
+  
+  switch (statfsbuf->f_type)
+#if defined (__linux__)
+  {
+    	case S_MAGIC_AFFS:
+	  type = strdup("affs");
+	  break;
+	case S_MAGIC_EXT:
+	  type = strdup("ext");
+	  break;
+	case S_MAGIC_EXT2_OLD:
+	  type = strdup("ext2");
+	  break;
+	case S_MAGIC_EXT2:
+	  type = strdup("ext2/ext3");
+	  break;
+	case S_MAGIC_HPFS:
+	  type = strdup("hpfs");
+	  break;
+	case S_MAGIC_ISOFS:
+	  type = strdup("isofs");
+	  break;
+	case S_MAGIC_ISOFS_WIN:
+	  type = strdup("isofs");
+	  break;
+	case S_MAGIC_ISOFS_R_WIN:
+	  type = strdup("isofs");
+	  break;
+	case S_MAGIC_MINIX:
+	  type = strdup("minix");
+	case S_MAGIC_MINIX_30:
+	  type = strdup("minix (30 char.)");
+	  break;
+	case S_MAGIC_MINIX_V2:
+	  type = strdup("minix v2");
+	  break;
+	case S_MAGIC_MINIX_V2_30:
+	  type = strdup("minix v2 (30 char.)");
+	  break;
+	case S_MAGIC_MSDOS:
+	  type = strdup("msdos");
+	  break;
+	case S_MAGIC_FAT:
+	  type = strdup("fat");
+	  break;
+	case S_MAGIC_NCP:
+	  type = strdup("novell");
+	  break;
+	case S_MAGIC_NFS:
+	  type = strdup("nfs");
+	  break;
+	case S_MAGIC_PROC:
+	  type = strdup("proc");
+	  break;
+	case S_MAGIC_SMB:
+	  type = strdup("smb");
+	  break;
+	case S_MAGIC_XENIX:
+	  type = strdup("xenix");
+	  break;
+	case S_MAGIC_SYSV4:
+	  type = strdup("sysv4");
+	  break;
+	case S_MAGIC_SYSV2:
+	  type = strdup("sysv2");
+	  break;
+	case S_MAGIC_COH:
+	  type = strdup("coh");
+	  break;
+	case S_MAGIC_UFS:
+	  type = strdup("ufs");
+	  break;
+	case S_MAGIC_XIAFS:
+	  type = strdup("xia");
+	  break;
+	case S_MAGIC_NTFS:
+	  type = strdup("ntfs");
+	  break;
+	case S_MAGIC_TMPFS:
+	  type = strdup("tmpfs");
+	  break;
+	case S_MAGIC_REISERFS:
+	  type = strdup("reiserfs");
+	  break;
+	case S_MAGIC_CRAMFS:
+	  type = strdup("cramfs");
+	  break;
+	case S_MAGIC_ROMFS:
+	  type = strdup("romfs");
+	  break;
+#elif __GNU__
+        case FSTYPE_UFS:
+          type = strdup("ufs");
+          break;
+        case FSTYPE_NFS:
+          type = strdup("nfs");
+          break;
+        case FSTYPE_GFS:
+          type = strdup("gfs");
+          break;
+        case FSTYPE_LFS:
+          type = strdup("lfs");
+          break;
+        case FSTYPE_SYSV:
+          type = strdup("sysv");
+          break;
+        case FSTYPE_FTP:
+          type = strdup("ftp");
+          break;
+        case FSTYPE_TAR:
+          type = strdup("tar");
+          break;
+        case FSTYPE_AR:
+          type = strdup("ar");
+          break;
+        case FSTYPE_CPIO:
+          type = strdup("cpio");
+          break;
+        case FSTYPE_MSLOSS:
+          type = strdup("msloss");
+          break;
+        case FSTYPE_CPM:
+          type = strdup("cpm");
+          break;
+        case FSTYPE_HFS:
+          type = strdup("hfs");
+          break;
+        case FSTYPE_DTFS:
+          type = strdup("dtfs");
+          break;
+        case FSTYPE_GRFS:
+          type = strdup("grfs");
+          break;
+        case FSTYPE_TERM:
+          type = strdup("term");
+          break;
+        case FSTYPE_DEV:
+          type = strdup("dev");
+          break;
+        case FSTYPE_PROC:
+          type = strdup("proc");
+          break;
+        case FSTYPE_IFSOCK:
+          type = strdup("ifsock");
+          break;
+        case FSTYPE_AFS:
+          type = strdup("afs");
+          break;
+        case FSTYPE_DFS:
+          type = strdup("dfs");
+          break;
+        case FSTYPE_PROC9:
+          type = strdup("proc9");
+          break;
+        case FSTYPE_SOCKET:
+          type = strdup("socket");
+          break;
+        case FSTYPE_MISC:
+          type = strdup("misc");
+          break;
+        case FSTYPE_EXT2FS:
+          type = strdup("ext2/ext3");
+          break;
+        case FSTYPE_HTTP:
+          type = strdup("http");
+          break;
+        case FSTYPE_MEMFS:
+          type = strdup("memfs");
+          break;
+        case FSTYPE_ISO9660:
+          type = strdup("iso9660");
+          break;
+#endif
+	default:
+	  if ((type = (char*)malloc(30 * sizeof(char))) == NULL) {
+		perror("malloc error");
+		return;
+          }
+	  sprintf (type, "UNKNOWN (0x%x)\n", (int)statfsbuf->f_type);
+  }
+
+  printf("%s", type);
+  free(type);
+}
+
+void print_human_access(struct stat *statbuf)
+{
+  char access[11];
+
+  access[10] = 0;
+  access[9] = (statbuf->st_mode & S_IXOTH) ?
+    ((statbuf->st_mode & S_ISVTX) ? 't' : 'x') :
+    ((statbuf->st_mode & S_ISVTX) ? 'T' : '-');
+  access[8] = (statbuf->st_mode & S_IWOTH) ? 'w' : '-';
+  access[7] = (statbuf->st_mode & S_IROTH) ? 'r' : '-';
+  access[6] = (statbuf->st_mode & S_IXGRP) ?
+    ((statbuf->st_mode & S_ISGID) ? 's' : 'x') :
+    ((statbuf->st_mode & S_ISGID) ? 'S' : '-');
+  access[5] = (statbuf->st_mode & S_IWGRP) ? 'w' : '-';
+  access[4] = (statbuf->st_mode & S_IRGRP) ? 'r' : '-';
+  access[3] = (statbuf->st_mode & S_IXUSR) ?
+    ((statbuf->st_mode & S_ISUID) ? 's' : 'x') :
+    ((statbuf->st_mode & S_ISUID) ? 'S' : '-');
+  access[2] = (statbuf->st_mode & S_IWUSR) ? 'w' : '-';
+  access[1] = (statbuf->st_mode & S_IRUSR) ? 'r' : '-';
+
+  switch (statbuf->st_mode & S_IFMT)
+    {
+    case S_IFDIR:
+      access[0] = 'd';
+      break;
+    case S_IFCHR:
+      access[0] = 'c';
+      break;
+    case S_IFBLK:
+      access[0] = 'b';
+      break;
+    case S_IFREG:
+      access[0] = '-';
+      break;
+    case S_IFLNK:
+      access[0] = 'l';
+      break;
+    case S_IFSOCK:
+      access[0] = 's';
+      break;
+    case S_IFIFO:
+      access[0] = 'p';
+      break;
+    default:
+      access[0] = '?';
+    }
+    printf (access);
+}
+
+void print_human_time(time_t *t)
+{
+  char str[40];
+  
+  if (strftime(str, 40, "%c", localtime(t)) > 0) printf(str);
+  else printf("Cannot calculate human readable time, sorry");
+}
+
+/* print statfs info */
+void print_statfs(char *pformat, char m, char *filename, void *data, SECURITY_ID_T sid)
+{
+    struct statfs *statfsbuf = (struct statfs*)data;
+#ifdef FLASK_LINUX
+    char sbuf[256];
+    int rv;
+    unsigned int sbuflen = sizeof(sbuf);
+#endif
+    
+    switch(m) {
+	case 'n':
+	    strcat(pformat, "s");
+	    printf(pformat, filename);
+	    break;
+#if !defined(__linux__) && defined (__GNU__)
+	case 'i':
+	    strcat(pformat, "Lx");
+	    printf(pformat, statfsbuf->f_fsid);
+	    break;
+#else
+	case 'i':
+	    strcat(pformat, "x %-8x");
+	    printf(pformat, statfsbuf->f_fsid.__val[0], statfsbuf->f_fsid.__val[1]);
+	    break;
+#endif
+
+	case 'l':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lu");
+#else
+	    strcat(pformat, "d");
+#endif
+	    printf(pformat, statfsbuf->f_namelen);
+	    break;
+	case 't':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lx");
+#else
+	    strcat(pformat, "x");
+#endif
+	    printf(pformat, statfsbuf->f_type);
+	    break;
+	case 'T':
+/*	    print_human_fstype(statfsbuf, pformat);*/
+	    print_human_fstype(statfsbuf);
+	    break;
+	case 'b':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lld");
+#else
+#if !defined(__linux__) && defined (__GNU__)
+	    strcat(pformat, "d");
+#else
+	    strcat(pformat, "ld");
+#endif
+#endif
+	    printf(pformat, statfsbuf->f_blocks);
+	    break;
+	case 'f':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lld");
+#else
+#if !defined(__linux__) && defined (__GNU__)
+	    strcat(pformat, "d");
+#else
+	    strcat(pformat, "ld");
+#endif
+#endif
+	    printf(pformat, statfsbuf->f_bfree);
+	    break;
+	case 'a':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lld");
+#else
+#if !defined(__linux__) && defined (__GNU__)
+	    strcat(pformat, "d");
+#else
+	    strcat(pformat, "ld");
+#endif
+#endif
+	    printf(pformat, statfsbuf->f_bavail);
+	    break;
+	case 's':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "ld");
+#else
+	    strcat(pformat, "d");
+#endif
+	    printf(pformat, statfsbuf->f_bsize);
+	    break;
+	case 'c':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lld");
+#else
+#if !defined(__linux__) && defined (__GNU__)
+	    strcat(pformat, "d");
+#else
+	    strcat(pformat, "ld");
+#endif
+#endif
+	    printf(pformat, statfsbuf->f_files);
+	    break;
+	case 'd':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "lld");
+#else
+#if !defined(__linux__) && defined (__GNU__)
+	    strcat(pformat, "d");
+#else
+	    strcat(pformat, "ld");
+#endif
+#endif
+	    printf(pformat, statfsbuf->f_ffree);
+	    break;
+#ifdef FLASK_LINUX
+	case 'S':
+	    strcat(pformat, "d");
+	    printf(pformat, sid);
+	    break;
+	case 'C':
+	    rv = security_sid_to_context(sid, (security_context_t *) &sbuf, &sbuflen);
+	    if ( rv < 0 )
+	    	sprintf(sbuf, "<error finding security context %d>", sid);
+	    printf(sbuf);
+	    break;
+#endif
+	default:
+	    strcat(pformat, "c");
+	    printf(pformat, m);
+	    break;
+    }
+}
+
+/* print stat info */
+void print_stat(char *pformat, char m, char *filename, void *data, SECURITY_ID_T sid)
+{
+    char linkname[256];
+    int i;
+    struct stat *statbuf = (struct stat*)data;
+    struct passwd *pw_ent;
+    struct group *gw_ent;
+#ifdef FLASK_LINUX
+    char sbuf[256];
+    int rv;
+    unsigned int sbuflen = sizeof(sbuf);
+#endif
+
+    switch(m) {
+	case 'n':
+	    strcat(pformat, "s");
+	    printf(pformat, filename);
+	    break;
+	case 'N':
+	    strcat(pformat, "s");
+	    if ((statbuf->st_mode & S_IFMT) == S_IFLNK) {
+		if ((i = readlink(filename, linkname, 256)) == -1) {
+		    perror(filename);
+		    return;
+		}
+		linkname[(i >= 256) ? 255 : i] = '\0';
+		/*printf("\"%s\" -> \"%s\"", filename, linkname);*/
+		printf("\"");
+		printf(pformat, filename);
+		printf("\" -> \"");
+		printf(pformat, linkname);
+		printf("\"");
+	    } else {
+		printf("\"");
+		printf(pformat, filename);
+		printf("\"");
+	    }
+	    break;
+	case 'd':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_dev);
+	    break;
+	case 'D':
+	    strcat(pformat, "x");
+	    printf(pformat, (int)statbuf->st_dev);
+	    break;
+	case 'i':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_ino);
+	    break;
+	case 'a':
+	    strcat(pformat, "o");
+	    printf(pformat, statbuf->st_mode & 07777);
+	    break;
+	case 'A':
+	    print_human_access(statbuf);
+	    break;
+	case 'f':
+	    strcat(pformat, "x");
+	    printf(pformat, statbuf->st_mode);
+	    break;
+	case 'F':
+	    print_human_type(statbuf->st_mode);
+	    break;
+	case 'h':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_nlink);
+	    break;
+#ifdef FLASK_LINUX
+	case 'S':
+	    strcat(pformat, "d");
+	    printf(pformat, sid);
+	    break;
+	case 'C':
+	    rv = security_sid_to_context(sid, (security_context_t *) &sbuf, &sbuflen);
+	    if ( rv < 0 )
+	    	sprintf(sbuf, "<error finding security context %d>", sid);
+	    printf(sbuf);
+	    break;
+#endif
+	case 'u':
+	    strcat(pformat, "d");
+	    printf(pformat, statbuf->st_uid);
+	    break;
+	case 'U':
+	    strcat(pformat, "s");
+	    setpwent();
+	    pw_ent = getpwuid(statbuf->st_uid);
+	    printf(pformat,
+		(pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
+	    break;
+	case 'g':
+	    strcat(pformat, "d");
+	    printf(pformat, statbuf->st_gid);
+	    break;
+	case 'G':
+	    strcat(pformat, "s");
+	    setgrent();
+	    gw_ent = getgrgid(statbuf->st_gid);
+	    printf(pformat,
+		(gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
+	    break;
+	case 't':
+	    strcat(pformat, "x");
+	    printf(pformat, major(statbuf->st_rdev));
+	    break;
+	case 'T':
+	    strcat(pformat, "x");
+	    printf(pformat, minor(statbuf->st_rdev));
+	    break;
+	case 's':
+#ifdef __USE_FILE_OFFSET64
+	    strcat(pformat, "llu");
+	    printf(pformat, (unsigned long long)statbuf->st_size);
+#else
+	    strcat(pformat, "u");
+	    printf(pformat, (unsigned int)statbuf->st_size);
+#endif
+	    break;
+	case 'b':
+	    strcat(pformat, "u");
+	    printf(pformat, (unsigned int)statbuf->st_blocks);
+	    break;
+	case 'o':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_blksize);
+	    break;
+	case 'x':
+	    print_human_time(&(statbuf->st_atime));
+	    break;
+	case 'X':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_atime);
+	    break;
+	case 'y':
+	    print_human_time(&(statbuf->st_mtime));
+	    break;
+	case 'Y':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_mtime);
+	    break;
+	case 'z':
+	    print_human_time(&(statbuf->st_ctime));
+	    break;
+	case 'Z':
+	    strcat(pformat, "d");
+	    printf(pformat, (int)statbuf->st_ctime);
+	    break;
+	default:
+	    strcat(pformat, "c");
+	    printf(pformat, m);
+	    break;
+    }
+}
+
+void print_it(char *masterformat, char *filename,
+    void (*print_func)(char*, char, char*, void*, SECURITY_ID_T), void *data, SECURITY_ID_T sid)
+{
+    char *m, *b, *format;
+    char pformat[65];
+
+    /* create a working copy of the format string */
+    format = strdup(masterformat);
+    if (!format) {
+	perror(filename);
+	return;
+    }
+
+    b = format;
+    while (b)
+    {
+	if ((m = strchr(b, (int)'%')) != NULL)
+	{
+	    strcpy (pformat, "%");
+	    *m++ = '\0';
+	    printf(b);
+
+	    /* copy all format specifiers to our format string */
+	    while (isdigit(*m) || strchr("#0-+. I", *m))
+	    {
+	    	char copy[2]="a";
+
+		*copy = *m;
+		/* make sure the format specifier is not too long */
+		if (strlen (pformat) > 63)
+			fprintf(stderr, "Warning: Format specifier too long, truncating: %s\n", pformat);
+		else
+			strcat (pformat, copy);
+	    	m++;
+	    }
+
+	    switch(*m) {
+		case '\0':
+		case '%':
+		    printf("%%");
+		    break;
+		default:
+		    print_func(pformat, *m, filename, data, sid);
+		    break;
+	    }
+	    b = m + 1;
+	}
+	else
+	{
+	    printf(b);
+	    b = NULL;
+	}
+    }
+    free(format);
+    printf("\n");
+}
+
+/* stat the filesystem and print what we find */
+void
+do_statfs (char *filename, int terse, int secure, char *format)
+{
+  struct statfs statfsbuf;
+  SECURITY_ID_T sid = -1;
+  int i;
+
+#ifdef FLASK_LINUX
+  if(!is_flask_enabled())
+    secure = 0;
+  if(secure)
+    i = statfs_secure(filename, &statfsbuf, &sid);
+  else
+#endif
+    i = statfs(filename, &statfsbuf);
+  if(i == -1)
+    {
+      perror (filename);
+      return;
+    }
+
+  if (format == NULL)
+    {
+	if (terse != 0)
+	  {
+#ifdef FLASK_LINUX
+		if(secure)
+	      		format = "%n %i %l %t %b %f %a %s %c %d %S %C";
+		else
+#endif
+		      	format = "%n %i %l %t %b %f %a %s %c %d";
+	  }
+	else
+	  {
+#ifdef FLASK_LINUX
+		if(secure)
+		    format = "  File: \"%n\"\n"
+	                 "    ID: %-8i Namelen: %-7l Type: %T\n"
+	                 "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
+	                 "Inodes: Total: %-10c Free: %-10d\n"
+	                 "   SID: %-14S  S_Context: %C\n";
+		else
+#endif
+		    format = "  File: \"%n\"\n"
+	                 "    ID: %-8i Namelen: %-7l Type: %T\n"
+	                 "Blocks: Total: %-10b Free: %-10f Available: %-10a Size: %s\n"
+	                 "Inodes: Total: %-10c Free: %-10d";
+	  }
+    }
+
+    print_it(format, filename, print_statfs, &statfsbuf, sid);
+}
+
+/* stat the file and print what we find */
+void
+do_stat (char *filename, int link, int terse, int secure, char *format)
+{
+  struct stat statbuf;
+  int i;
+  SECURITY_ID_T sid = -1;
+  
+#ifdef FLASK_LINUX
+  if(!is_flask_enabled())
+    secure = 0;
+  if(secure)
+    i = (link == 1) ? stat_secure(filename, &statbuf, &sid) : lstat_secure(filename, &statbuf, &sid);
+  else
+#endif
+  i = (link == 1) ? stat(filename, &statbuf) : lstat(filename, &statbuf);
+
+  if (i == -1)
+    {
+      perror (filename);
+      return;
+    }
+
+   if (format == NULL)
+    {
+       if (terse != 0)
+       {
+#ifdef FLASK_LINUX
+	   if (secure)
+		  format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %S %C";
+	   else
+#endif
+	          format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
+       }
+       else
+       {
+           /* tmp hack to match orignal output until conditional implemented */
+          i = statbuf.st_mode & S_IFMT;
+          if (i == S_IFCHR || i == S_IFBLK) {
+#ifdef FLASK_LINUX
+          	if (secure)
+               		format =
+	                   "  File: %N\n"
+        	           "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+                	   "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
+	                   " Device type: %t,%T\n"
+        	           "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
+	                   "   SID: %-14S  S_Context: %C\n"
+	                   "Access: %x\n"
+        	           "Modify: %y\n"
+	                   "Change: %z\n";
+        	else
+#endif
+        		format =           
+	                   "  File: %N\n"
+        	           "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+                	   "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
+	                   " Device type: %t,%T\n"
+	                   "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
+	                   "Access: %x\n"
+        	           "Modify: %y\n"
+                	   "Change: %z\n";
+           }
+	   else
+	   {
+#ifdef FLASK_LINUX
+	   	if (secure)
+	               format =
+        	           "  File: %N\n"
+                	   "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+			   "Device: %Dh/%dd\tInode: %-10i  Links: %-5h\n"
+        	           "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
+                	   "   SID: %-14S  S_Context: %C\n"
+	                   "Access: %x\n"
+        	           "Modify: %y\n"
+                	   "Change: %z\n";
+                else
+#endif
+                      format =
+	                   "  File: %N\n"
+        	           "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
+			   "Device: %Dh/%dd\tInode: %-10i  Links: %-5h\n"
+	                   "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
+        	           "Access: %x\n"
+	                   "Modify: %y\n"
+        	           "Change: %z\n";
+          }
+       }
+    }
+    print_it(format, filename, print_stat, &statbuf, sid);
+}
+
+void
+usage (char *progname)
+{
+  fprintf (stderr, "Usage: %s [-l] [-f] [-s] [-v] [-h] [-t] [-c format] file1 [file2 ...]\n", progname);
+  exit (1);
+}
+
+void verbose_usage(char *progname)
+{
+    fprintf(stderr, "Usage: %s [-l] [-f] [-s] [-v] [-h] [-t] [-c format] file1 [file2 ...]\n", progname);
+    fprintf(stderr, "\tformat interpreted sequences for file stat are:\n");
+    fprintf(stderr, "\t\t%%n - File name\n");
+    fprintf(stderr, "\t\t%%N - Quoted File name with dereference if symbolic link\n");
+    fprintf(stderr, "\t\t%%d - Device number in decimal\n");
+    fprintf(stderr, "\t\t%%D - Device number in hex\n");
+    fprintf(stderr, "\t\t%%i - Inode number\n");
+    fprintf(stderr, "\t\t%%a - Access rights in octal\n");
+    fprintf(stderr, "\t\t%%A - Access rights in human readable form\n");
+    fprintf(stderr, "\t\t%%f - raw mode in hex\n");
+    fprintf(stderr, "\t\t%%F - File type\n");
+    fprintf(stderr, "\t\t%%h - Number of hard links\n");
+    fprintf(stderr, "\t\t%%u - User Id of owner\n");
+    fprintf(stderr, "\t\t%%U - User name of owner\n");
+    fprintf(stderr, "\t\t%%g - Group Id of owner\n");
+    fprintf(stderr, "\t\t%%G - Group name of owner\n");
+    fprintf(stderr, "\t\t%%t - Major device type in hex\n");
+    fprintf(stderr, "\t\t%%T - Minor device type in hex\n");
+    fprintf(stderr, "\t\t%%s - Total size, in bytes\n");
+    fprintf(stderr, "\t\t%%b - Number of blocks allocated\n");
+    fprintf(stderr, "\t\t%%o - IO block size\n");
+    fprintf(stderr, "\t\t%%x - Time of last access\n");
+    fprintf(stderr, "\t\t%%X - Time of last access as seconds since Epoch\n");
+    fprintf(stderr, "\t\t%%y - Time of last modification\n");
+    fprintf(stderr, "\t\t%%Y - Time of last modification as seconds since Epoch\n");
+    fprintf(stderr, "\t\t%%z - Time of last change\n");
+    fprintf(stderr, "\t\t%%Z - Time of last change as seconds since Epoch\n");
+    fprintf(stderr, "\t\t%%S - Security ID in SE-Linux\n");
+    fprintf(stderr, "\t\t%%C - Security context in SE-Linux\n");
+    fprintf(stderr, "\tformat interpreted sequences for filesystem stat are:\n");
+    fprintf(stderr, "\t\t%%n - File name\n");
+    fprintf(stderr, "\t\t%%i - File System id in hex\n");
+    fprintf(stderr, "\t\t%%l - Maximum length of filenames\n");
+    fprintf(stderr, "\t\t%%t - Type in hex\n");
+    fprintf(stderr, "\t\t%%T - Type in human readable form\n");
+    fprintf(stderr, "\t\t%%b - Total data blocks in file system\n");
+    fprintf(stderr, "\t\t%%f - Free blocks in file system\n");
+    fprintf(stderr, "\t\t%%a - Free blocks available to non-superuser\n");
+    fprintf(stderr, "\t\t%%s - Optimal transfer block size\n");
+    fprintf(stderr, "\t\t%%c - Total file nodes in file system\n");
+    fprintf(stderr, "\t\t%%S - Security ID in SE-Linux\n");
+    fprintf(stderr, "\t\t%%C - Security context in SE-Linux\n");
+    fprintf(stderr, "\t\t%%d - Free file nodes in file system\n");
+    exit(1);
+}
+  
 
-int main(int argc, char ** argv)
+int
+main (int argc, char *argv[])
 {
-        int rc;
-        struct stat buf;
+  int c, i, link = 0, fs = 0, terse = 0, secure = 0;
+  char *format = NULL;
+  
+  while ((c = getopt (argc, argv, "lsfvthc:")) != EOF)
+    {
+      switch (c)
+	{
+	case 'l':
+	  link = 1;
+	  break;
+	case 's':
+	  secure = 1;
+	  break;
+	case 'f':
+	  fs = 1;
+	  break;
+	case 't':
+	  terse = 1;
+	  break;
+	case 'c':
+	  format = optarg;
+	  break;
+	case 'h':
+	  printf ("stat version: 3.0\n");
+	  verbose_usage(argv[0]);
+	  break;
+	case 'v':
+          printf ("stat version: 3.0\n");
+	default:
+	  usage (argv[0]);
+	}
+    }
+  if (argc == optind)
+    usage (argv[0]);
 
-        if (argc < 2) { 
-                printf("Usage %s filename\n", argv[0]);
-                return 1;
-        }
+  for (i = optind; i < argc; i++)
+    (fs == 0) ? do_stat (argv[i], link, terse, secure, format) :
+     		do_statfs (argv[i], terse, secure, format);
 
-        rc = stat(argv[1], &buf); 
-        if (rc) { 
-                printf("stat(%s) error: %s\n", argv[1], strerror(errno));
-        }
-        return rc;
-} 
+  return (0);
+}
diff --git a/lustre/tests/stat_fs.h b/lustre/tests/stat_fs.h
new file mode 100644
index 0000000000000000000000000000000000000000..a07fc123b73ccf9b7280225809143fa7df3417b0
--- /dev/null
+++ b/lustre/tests/stat_fs.h
@@ -0,0 +1,36 @@
+/* define the magic numbers as given by statfs(2) */
+/* please send additions to meskes@debian.org     */
+
+#if defined(__linux__)
+#define	S_MAGIC_AFFS		0xADFF
+#define S_MAGIC_EXT		0x137D
+#define S_MAGIC_EXT2_OLD	0xEF51
+#define S_MAGIC_EXT2		0xEF53
+#define S_MAGIC_HPFS	  	0xF995E849
+#define S_MAGIC_ISOFS		0x9660
+#define S_MAGIC_ISOFS_WIN	0x4000
+#define S_MAGIC_ISOFS_R_WIN	0x4004
+#define S_MAGIC_MINIX		0x137F
+#define S_MAGIC_MINIX_30	0x138F
+#define S_MAGIC_MINIX_V2	0x2468
+#define S_MAGIC_MINIX_V2_30	0x2478
+#define S_MAGIC_MSDOS		0x4d44
+#define S_MAGIC_FAT		0x4006
+#define S_MAGIC_NCP		0x564c
+#define S_MAGIC_NFS		0x6969
+#define S_MAGIC_PROC		0x9fa0
+#define S_MAGIC_SMB		0x517B
+#define S_MAGIC_XENIX		0x012FF7B4
+#define S_MAGIC_SYSV4		0x012FF7B5
+#define S_MAGIC_SYSV2		0x012FF7B6
+#define S_MAGIC_COH		0x012FF7B7
+#define S_MAGIC_UFS		0x00011954
+#define S_MAGIC_XIAFS		0x012FD16D
+#define	S_MAGIC_NTFS 		0x5346544e
+#define S_MAGIC_TMPFS		0x1021994
+#define S_MAGIC_REISERFS        0x52654973
+#define S_MAGIC_CRAMFS          0x28cd3d45
+#define S_MAGIC_ROMFS           0x7275
+#elif defined (__GNU__)
+#include <hurd/hurd_types.h>
+#endif
diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh
new file mode 100644
index 0000000000000000000000000000000000000000..01150a075a4cca267d073c23b54701b5693fed8f
--- /dev/null
+++ b/lustre/tests/test-framework.sh
@@ -0,0 +1,430 @@
+#!/bin/sh
+
+set -e
+
+# eg, assert_env LUSTRE MDSNODES OSTNODES CLIENTS
+assert_env() {
+    local failed=""
+    for name in $@; do
+      if [ -z "${!name}" ]; then
+	  echo "$0: $name must be set"
+          failed=1
+      fi
+    done
+    [ $failed ] && exit 1 || true
+}
+
+usage() {
+    echo "usage: $0 [-r] [-f cfgfile]"
+    echo "       -r: reformat"
+
+    exit
+}
+
+init_test_env() {
+    export LUSTRE=`absolute_path $LUSTRE`
+    export TESTSUITE=`basename $0 .sh`
+    export XMLCONFIG="${TESTSUITE}.xml"
+    export LTESTDIR=${LTESTDIR:-$LUSTRE/../ltest}
+
+    [ -d /r ] && export ROOT=/r
+
+    export PATH=:$PATH:$LUSTRE/utils:$LUSTRE/tests
+    export LCONF=${LCONF:-"lconf"}
+    export LMC=${LMC:-"lmc"}
+    export LCTL=${LCTL:-"lctl"}
+    export CHECKSTAT="${CHECKSTAT:-checkstat} -v"
+
+    # Paths on remote nodes, if different 
+    export RLUSTRE=${RLUSTRE:-$LUSTRE}
+    export RPWD=${RPWD:-$PWD}
+
+    # command line
+    
+    while getopts "rf:" opt $*; do 
+	case $opt in
+	    f) CONFIG=$OPTARG;;
+	    r) REFORMAT=--reformat;;
+	    \?) usage;;
+	esac
+    done
+    
+    # save the name of the config file for the upcall
+    echo "XMLCONFIG=$LUSTRE/tests/$XMLCONFIG"  > $LUSTRE/tests/XMLCONFIG
+}
+
+# Facet functions
+start() {
+    facet=$1
+    shift
+    active=`facet_active $facet`
+    do_facet $facet $LCONF --select ${facet}_svc=${active}_facet --node ${active}_facet  --ptldebug $PTLDEBUG $@ $XMLCONFIG
+}
+
+stop() {
+    facet=$1
+    active=`facet_active $facet`
+    shift
+    do_facet $facet $LCONF --select ${facet}_svc=${active}_facet --node ${active}_facet  --ptldebug $PTLDEBUG $@ --cleanup $XMLCONFIG
+}
+
+zconf_mount() {
+    mnt=$1
+
+    [ -d $mnt ] || mkdir $mnt
+    
+    if [ -x /sbin/mount.lustre ] ; then
+	mount -t lustre -o nettype=$NETTYPE \
+	    `facet_host mds`:/mds_svc/client_facet $mnt
+    else
+       # this is so cheating
+       $LCONF --nosetup --node client_facet $XMLCONFIG
+       $LUSTRE/utils/llmount `facet_host mds`:/mds_svc/client_facet $mnt \
+            -o nettype=$NETTYPE 
+    fi
+
+    [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
+    return 0
+}
+
+zconf_umount() {
+    mnt=$1
+    umount  $mnt || :
+    $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG || :
+}
+
+shutdown_facet() {
+    facet=$1
+    if [ "$FAILURE_MODE" = HARD ]; then
+       $POWER_DOWN `facet_active_host $facet`
+    elif [ "$FAILURE_MODE" = SOFT ]; then
+       stop $facet --force --failover --nomod
+    fi
+}
+
+reboot_facet() {
+    facet=$1
+    if [ "$FAILURE_MODE" = HARD ]; then
+       $POWER_UP `facet_active_host $facet`
+    fi
+}
+
+wait_for_host() {
+   HOST=$1
+   check_network  $HOST 900
+   while ! $PDSH $HOST "ls -ld $LUSTRE"; do sleep 5; done
+}
+
+wait_for() {
+   facet=$1
+   HOST=`facet_active_host $facet`
+   wait_for_host $HOST
+}
+
+client_df() {
+    # not every config has many clients
+    if [ ! -z "$CLIENTS" ]; then
+	$PDSH $CLIENTS "df $MOUNT" | dshbak -c
+    fi
+}
+
+facet_failover() {
+    facet=$1
+    echo "Failing $facet node `facet_active_host $facet`"
+    shutdown_facet $facet
+    sleep 2
+    reboot_facet $facet
+    client_df &
+    DFPID=$!
+    change_active $facet
+    TO=`facet_active_host $facet`
+    echo "Failover MDS to $TO"
+    wait_for $facet
+    start $facet
+}
+
+replay_barrier() {
+    local facet=$1
+    do_facet $facet sync
+    df $MOUNT
+    do_facet $facet $LCTL --device %${facet}_svc readonly
+    do_facet $facet $LCTL --device %${facet}_svc notransno
+    do_facet $facet $LCTL mark "REPLAY BARRIER"
+    $LCTL mark "REPLAY BARRIER"
+}
+
+mds_evict_client() {
+    UUID=`cat /proc/fs/lustre/mdc/*_MNT_*/uuid`
+    do_facet mds "echo $UUID > /proc/fs/lustre/mds/mds_svc/evict_client"
+}
+
+fail() {
+    local facet=$1
+    facet_failover $facet
+    df $MOUNT || error "post-failover df: $?"
+}
+
+fail_abort() {
+    local facet=$1
+    stop $facet --force --failover --nomod
+    change_active $facet
+    start $facet
+    do_facet $facet lctl --device %${facet}_svc abort_recovery
+    df $MOUNT || echo "first df failed: $?"
+    df $MOUNT || error "post-failover df: $?"
+}
+
+do_lmc() {
+    $LMC -m ${XMLCONFIG} $@
+}
+
+h2tcp() {
+   if [ "$1" = "client" ]; then echo \'*\'; else
+   echo $1 
+   fi
+}
+declare -fx h2tcp
+
+h2elan() {
+   if [ "$1" = "client" ]; then echo \'*\'; else
+   echo $1 | sed 's/[^0-9]*//g'
+   fi
+}
+declare -fx h2elan
+
+facet_host() {
+   local facet=$1
+   varname=${facet}_HOST
+   echo -n ${!varname}
+}
+
+facet_nid() {
+   facet=$1
+   HOST=`facet_host $facet`
+   if [ -z "$HOST" ]; then
+	echo "The env variable ${facet}_HOST must be set."
+	exit 1
+   fi
+   echo `h2$NETTYPE $HOST`
+}
+
+facet_active() {
+    local facet=$1
+    local activevar=${facet}active
+    active=${!activevar}
+    if [ -z "$active" ] ; then 
+	echo -n ${facet}
+    else
+	echo -n ${active}
+    fi
+}
+
+facet_active_host() {
+    local facet=$1
+    local active=`facet_active $facet`
+    echo `facet_host $active`
+}
+
+change_active() {
+    local facet=$1
+    failover=${facet}failover 
+    host=`facet_host $failover`
+    [ -z "$host" ] && return
+    curactive=`facet_active $facet`
+    if [ -z "${curactive}" -o "$curactive" == "$failover" ] ; then
+        eval export ${facet}active=$facet
+    else
+        eval export ${facet}active=$failover
+    fi
+    # save the active host for this facet
+    activevar=${facet}active
+    echo "$activevar=${!activevar}" > ./$activevar
+}
+
+do_node() {
+    HOST=$1
+    shift
+    $PDSH $HOST "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests; cd $RPWD; sh -c \"$@\")"
+}
+do_facet() {
+    facet=$1
+    shift
+    HOST=`facet_active_host $facet`
+    do_node $HOST $@
+}
+
+add_facet() {
+    local facet=$1
+    shift
+    echo "add facet $facet: `facet_host $facet`"
+    do_lmc --add node --node ${facet}_facet $@ --timeout $TIMEOUT
+    do_lmc --add net --node ${facet}_facet --nid `facet_nid $facet` \
+	--nettype $NETTYPE
+}
+
+add_mds() {
+    facet=$1
+    shift
+    rm -f ${facet}active
+    add_facet $facet  --lustre_upcall $UPCALL
+    do_lmc --add mds --node ${facet}_facet --mds ${facet}_svc $*
+}
+
+add_mdsfailover() {
+    facet=$1
+    shift
+    add_facet ${facet}failover  --lustre_upcall $UPCALL
+    do_lmc --add mds  --node ${facet}failover_facet --mds ${facet}_svc $*
+}
+
+add_ost() {
+    facet=$1
+    shift
+    rm -f ${facet}active
+    add_facet $facet
+    do_lmc --add ost --node ${facet}_facet --ost ${facet}_svc $*
+}
+
+add_ostfailover() {
+    facet=$1
+    shift
+    add_facet ${facet}failover
+    do_lmc --add ost --failover --node ${facet}failover_facet --ost ${facet}_svc $*
+}
+
+add_lov() {
+    lov=$1
+    mds_facet=$2
+    shift; shift
+    do_lmc --add lov --mds ${mds_facet}_svc --lov $lov $*
+    
+}
+
+add_client() {
+    facet=$1
+    mds=$2
+    shift; shift
+    add_facet $facet --lustre_upcall $UPCALL
+    do_lmc --add mtpt --node ${facet}_facet --mds ${mds}_svc $*
+
+}
+
+
+####### 
+# General functions
+
+check_network() {
+   local NETWORK=0
+   local WAIT=0
+   local MAX=$2
+   while [ $NETWORK -eq 0 ]; do
+      ping -c 1 -w 3 $1 > /dev/null
+      if [ $? -eq 0 ]; then
+         NETWORK=1
+      else
+         WAIT=$((WAIT + 5))
+	 echo "waiting for $1, $((MAX - WAIT)) secs left"
+         sleep 5
+      fi
+      if [ $WAIT -gt $MAX ]; then
+         echo "Network not available"
+         exit 1
+      fi
+   done
+}
+check_port() {
+   while( !($DSH2 $1 "netstat -tna | grep -q $2") ) ; do
+      sleep 9
+   done
+}
+
+no_dsh() {
+   shift
+   eval $@
+}
+
+comma_list() {
+    # the sed converts spaces to commas, but leaves the last space
+    # alone, so the line doesn't end with a comma.
+    echo "$*" | tr -s " " "\n" | sort -b -u | tr "\n" " " | sed 's/ \([^$]\)/,\1/g'
+}
+
+absolute_path() {
+   (cd `dirname $1`; echo $PWD/`basename $1`)
+}
+
+##################################
+# Test interface 
+error() {
+    echo "${TESTSUITE}: **** FAIL:" $@
+    exit 1
+}
+
+build_test_filter() {
+        for O in $ONLY; do
+            eval ONLY_${O}=true
+        done
+        for E in $EXCEPT $ALWAYS_EXCEPT; do
+            eval EXCEPT_${E}=true
+        done
+}
+
+_basetest() {
+    echo $*
+}
+
+basetest() {
+    IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
+}
+
+run_test() {
+        export base=`basetest $1`
+        if [ ! -z "$ONLY" ]; then
+                 testname=ONLY_$1
+                 if [ ${!testname}x != x ]; then
+                     run_one $1 "$2"
+                     return $?
+                 fi
+                 testname=ONLY_$base
+                 if [ ${!testname}x != x ]; then
+                     run_one $1 "$2"
+                     return $?
+                 fi
+                 echo -n "."
+                 return 0
+        fi
+        testname=EXCEPT_$1
+        if [ ${!testname}x != x ]; then
+                 echo "skipping excluded test $1"
+                 return 0
+        fi
+        testname=EXCEPT_$base
+        if [ ${!testname}x != x ]; then
+                 echo "skipping excluded test $1 (base $base)"
+                 return 0
+        fi
+        run_one $1 "$2"
+
+        return $?
+}
+
+EQUALS="======================================================================"
+equals_msg() {
+   msg="$@"
+
+   local suffixlen=$((${#EQUALS} - ${#msg}))
+   [ $suffixlen -lt 5 ] && suffixlen=5
+   printf '===== %s %.*s\n' "$msg" $suffixlen $EQUALS
+}
+
+run_one() {
+    testnum=$1
+    message=$2
+    tfile=f$base
+    tdir=d$base
+
+    # Pretty tests run faster.
+    equals_msg $testnum: $message
+
+    test_${testnum} || error "test_$testnum failed with $?"
+}
diff --git a/lustre/tests/test_brw.c b/lustre/tests/test_brw.c
index 6cbfcb5002957a8c70486097dd33026de4d56f7e..f242eba856362ffbefab4290907e01d7c9dfad61 100644
--- a/lustre/tests/test_brw.c
+++ b/lustre/tests/test_brw.c
@@ -1,3 +1,10 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+/* for O_DIRECT */
+#define  _GNU_SOURCE
+
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -8,12 +15,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-// not correctly in the headers yet!!
-//#define O_DIRECT 0
-#ifndef O_DIRECT
-#define O_DIRECT	 040000	/* direct disk access hint */
-#endif
-
 #define CERROR(fmt, arg...) fprintf(stderr, fmt, ## arg)
 #ifndef __u64
 #define __u64 long long
@@ -80,142 +81,146 @@ int page_debug_check(char *who, void *addr, int size, __u64 off, __u64 id)
 
 void usage(char *prog)
 {
-	fprintf(stderr,
-		"usage: %s file count [[d]{r|w|rw} [pages_per_vec [objid]]]\n",
-		prog);
-	exit(1);
+        fprintf(stderr,
+                "usage: %s file count [[d]{r|w|rw} [pages_per_vec [objid]]]\n",
+                prog);
+        exit(1);
 }
 
 int main(int argc, char **argv)
 {
         int fd;
         char *buf;
-	long long count, last, offset;
-	long pg_vec, len;
-	long long objid = 3;
-	struct stat st;
-	int flags = 0;
-	int cmd = 0;
-	char *end;
+        long long count, last, offset;
+        long pg_vec, len;
+        long long objid;
+        struct stat st;
+        int flags = 0;
+        int cmd = 0;
+        char *end;
         int rc;
 
         if (argc < 3 || argc > 6)
-		usage(argv[0]);
+                usage(argv[0]);
 
         count = strtoull(argv[2], &end, 0);
-	if (*end) {
-		fprintf(stderr, "%s: invalid count '%s'\n", argv[0], argv[2]);
-		usage(argv[0]);
-	}
-	if (argc >= 4) {
-		if (strchr(argv[3], 'r')) {
-			cmd = READ;
-			flags = O_RDONLY;
-		}
-		if (strchr(argv[3], 'w')) {
-			cmd |= WRITE;
-			flags = O_RDWR | O_CREAT;
-		}
-		if (strchr(argv[3], 'd')) {
-			flags |= O_DIRECT;
-		}
-		if (!cmd)
-			usage(argv[0]);
-	} else {
-		cmd = READ | WRITE;
-		flags = O_RDWR | O_CREAT | O_DIRECT;
-	}
-
-	if (argc >= 5) {
-		pg_vec = strtoul(argv[4], &end, 0);
-		if (*end) {
-			fprintf(stderr, "%s: invalid pages_per_vec '%s'\n",
-				argv[0], argv[4]);
-			usage(argv[0]);
-		}
-	}
-
-	if (argc >= 6) {
-		objid = strtoull(argv[5], &end, 0);
-		if (*end) {
-			fprintf(stderr, "%s: invalid objid '%s'\n",
-				argv[0], argv[5]);
-			usage(argv[0]);
-		}
-	}
+        if (*end) {
+                fprintf(stderr, "%s: invalid count '%s'\n", argv[0], argv[2]);
+                usage(argv[0]);
+        }
+        if (argc >= 4) {
+                if (strchr(argv[3], 'r')) {
+                        cmd = READ;
+                        flags = O_RDONLY;
+                }
+                if (strchr(argv[3], 'w')) {
+                        cmd |= WRITE;
+                        flags = O_RDWR | O_CREAT;
+                }
+                if (strchr(argv[3], 'd')) {
+                        flags |= O_DIRECT;
+                }
+                if (!cmd)
+                        usage(argv[0]);
+        } else {
+                cmd = READ | WRITE;
+                flags = O_RDWR | O_CREAT | O_DIRECT;
+        }
+
+        if (argc >= 5) {
+                pg_vec = strtoul(argv[4], &end, 0);
+                if (*end) {
+                        fprintf(stderr, "%s: invalid pages_per_vec '%s'\n",
+                                argv[0], argv[4]);
+                        usage(argv[0]);
+                }
+        } else {
+                pg_vec = 16;
+        }
+
+        if (argc >= 6) {
+                objid = strtoull(argv[5], &end, 0);
+                if (*end) {
+                        fprintf(stderr, "%s: invalid objid '%s'\n",
+                                argv[0], argv[5]);
+                        usage(argv[0]);
+                }
+        } else {
+                objid = 3;
+        }
 
         printf("%s: %s on %s(objid "LPX64") for "LPU64"x%ld pages \n",
-	       argv[0], flags & O_DIRECT ? "directio" : "i/o",
-	       argv[1], objid, count, pg_vec);
+               argv[0], flags & O_DIRECT ? "directio" : "i/o",
+               argv[1], objid, count, pg_vec);
 
         fd = open(argv[1], flags | O_LARGEFILE);
         if (fd == -1) {
                 fprintf(stderr, "%s: cannot open %s:  %s\n", argv[0],
-			argv[1], strerror(errno));
+                        argv[1], strerror(errno));
                 return 3;
         }
 
-	rc = fstat(fd, &st);
-	if (rc < 0) {
-		fprintf(stderr, "%s: cannot stat %s: %s\n", argv[0],
-			argv[1], strerror(errno));
-		return 4;
-	}
+        rc = fstat(fd, &st);
+        if (rc < 0) {
+                fprintf(stderr, "%s: cannot stat %s: %s\n", argv[0],
+                        argv[1], strerror(errno));
+                return 4;
+        }
 
-	len = pg_vec * st.st_blksize;
-	last = (long long)count * len;
+        len = pg_vec * st.st_blksize;
+        last = (long long)count * len;
 
         buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
-        if (!buf) {
+        if (buf == MAP_FAILED) {
                 fprintf(stderr, "%s: no buffer memory %s\n",
-			argv[0], strerror(errno));
+                        argv[0], strerror(errno));
                 return 2;
         }
 
-	for (offset = 0; offset < last && cmd & WRITE; offset += len) {
-		int i;
+        for (offset = 0; offset < last && cmd & WRITE; offset += len) {
+                int i;
 
-		for (i = 0; i < len; i += st.st_blksize)
-			page_debug_setup(buf + i, st.st_blksize, offset + i,
-					 objid);
+                for (i = 0; i < len; i += st.st_blksize)
+                        page_debug_setup(buf + i, st.st_blksize, offset + i,
+                                         objid);
 
-		rc = write(fd, buf, len);
+                rc = write(fd, buf, len);
 
-		for (i = 0; i < len; i += st.st_blksize) {
-			if (page_debug_check("write", buf + i, st.st_blksize,
-					     offset + i, objid))
-				return 10;
-		}
+                for (i = 0; i < len; i += st.st_blksize) {
+                        if (page_debug_check("write", buf + i, st.st_blksize,
+                                             offset + i, objid))
+                                return 10;
+                }
 
-		if (rc != len) {
-			fprintf(stderr, "%s: write error: %s, rc %d != %ld\n",
-				argv[0], strerror(errno), rc, len);
-			return 4;
-		}
-	}
+                if (rc != len) {
+                        fprintf(stderr, "%s: write error: %s, rc %d != %ld\n",
+                                argv[0], strerror(errno), rc, len);
+                        return 4;
+                }
+        }
 
         if (lseek(fd, 0, SEEK_SET) != 0) {
                 fprintf(stderr, "%s: cannot seek %s\n",
-			argv[0], strerror(errno));
+                        argv[0], strerror(errno));
                 return 5;
         }
 
-	for (offset = 0; offset < last && cmd & READ; offset += len) {
-		int i;
-
-		rc = read(fd, buf, len);
-		if (rc != len) {
-			fprintf(stderr, "%s: read error: %s, rc %d != %ld\n",
-				argv[0], strerror(errno), rc, len);
-			return 6;
-		}
-
-		for (i = 0; i < len; i += st.st_blksize) {
-			if (page_debug_check("read", buf + i, st.st_blksize,
-					     offset + i, objid))
-				return 11;
-		}
-	}
+        for (offset = 0; offset < last && cmd & READ; offset += len) {
+                int i;
+
+                rc = read(fd, buf, len);
+                if (rc != len) {
+                        fprintf(stderr, "%s: read error: %s, rc %d != %ld\n",
+                                argv[0], strerror(errno), rc, len);
+                        return 6;
+                }
+
+                for (i = 0; i < len; i += st.st_blksize) {
+                        if (page_debug_check("read", buf + i, st.st_blksize,
+                                             offset + i, objid))
+                                return 11;
+                }
+        }
 
         return 0;
 }
diff --git a/lustre/tests/uml.sh b/lustre/tests/uml.sh
index f7a9241aa2938ac67b6bbfec24b448a9a3d8690f..9195e59358bb9a650cb7a1e922dffec8a43f8ea9 100644
--- a/lustre/tests/uml.sh
+++ b/lustre/tests/uml.sh
@@ -7,7 +7,7 @@ LMC=${LMC:-lmc}
 TMP=${TMP:-/tmp}
 
 MDSDEV=${MDSDEV:-$TMP/mds1-`hostname`}
-MDSSIZE=${MDSSIZE:-50000}
+MDSSIZE=${MDSSIZE:-100000}
 
 OSTDEVBASE=$TMP/ost
 #OSTDEV1=${OSTDEV1:-${OSTDEVBASE}1}
@@ -15,11 +15,13 @@ OSTDEVBASE=$TMP/ost
 #etc
 OSTSIZE=${OSTSIZE:-100000}
 STRIPECNT=${STRIPECNT:-1}
+OSDTYPE=${OSDTYPE:-obdfilter}
+OSTFAILOVER=${OSTFAILOVER:-}
 
 FSTYPE=${FSTYPE:-ext3}
 
 NETTYPE=${NETTYPE:-tcp}
-NIDTYPE=${NIDTYPE:-$NODETYPE}
+NIDTYPE=${NIDTYPE:-$NETTYPE}
 
 # NOTE - You can't have different MDS/OST nodes and also have clients on the
 #        MDS/OST nodes without using --endlevel and --startlevel during lconf.
@@ -69,6 +71,10 @@ h2elan () {
 	esac
 }
 
+h2gm () {
+	echo `gmnalnid -n$1`
+}
+
 # create nodes
 echo -n "adding NET for:"
 for NODE in `echo $MDSNODE $OSTNODES $CLIENTS | tr -s " " "\n" | sort -u`; do
@@ -88,7 +94,15 @@ for NODE in $OSTNODES; do
 	eval OSTDEV=\$OSTDEV$COUNT
 	echo -n " $NODE"
 	OSTDEV=${OSTDEV:-$OSTDEVBASE$COUNT-`hostname`}
-        ${LMC} -m $config --add ost --node $NODE --lov lov1 --fstype $FSTYPE --dev $OSTDEV --size $OSTSIZE || exit 21
+	case "$OSDTYPE" in
+		obdfilter)
+			OSTARGS="--fstype $FSTYPE --dev $OSTDEV --size $OSTSIZE"
+			;;
+		obdecho)
+			OSTARGS="--osdtype=obdecho"
+			;;
+	esac
+        ${LMC} -m $config --add ost --node $NODE --lov lov1 $OSTARGS $OSTFAILOVER || exit 21
 	COUNT=`expr $COUNT + 1`
 done
 
diff --git a/lustre/tests/utime.c b/lustre/tests/utime.c
index 9fe9f26bd09eea01ea4fdd6e958bc2c481c5f90e..43a50e62754aaffed2dd090ef742bacd71624877 100644
--- a/lustre/tests/utime.c
+++ b/lustre/tests/utime.c
@@ -21,12 +21,16 @@ void usage(char *prog)
 int main(int argc, char *argv[])
 {
 	long before_mknod, after_mknod;
-	long before_utime, after_utime;
 	const char *prog = argv[0];
 	const char *filename = argv[1];
+        struct utimbuf utb;
 	struct stat st;
 	int rc;
 
+        utb.actime = 0x47114711;
+        utb.modtime = 0x11471147;
+                
+
 	if (argc != 2)
 		usage(argv[0]);
 
@@ -63,13 +67,10 @@ int main(int argc, char *argv[])
 		       prog, before_mknod, before_mknod == st.st_mtime ? "*":"",
 		       st.st_mtime, after_mknod);
 
-		sleep(5);
 	}
 
 	/* See above */
-	before_utime = time(0) - 1;
-	rc = utime(filename, NULL);
-	after_utime = time(0);
+	rc = utime(filename, &utb);
 	if (rc) {
 		fprintf(stderr, "%s: utime(%s) failed: rc %d: %s\n",
 			prog, filename, errno, strerror(errno));
@@ -83,15 +84,20 @@ int main(int argc, char *argv[])
 		return 6;
 	}
 
-	if (st.st_mtime < before_utime || st.st_mtime > after_utime) {
-		fprintf(stderr, "%s: bad utime times %lu <= %lu <= %lu false\n",
-			prog, before_utime, st.st_mtime, after_utime);
+	if (st.st_mtime != utb.modtime ) {
+		fprintf(stderr, "%s: bad utime mtime %lu should be  %lu\n",
+			prog, st.st_mtime, utb.modtime);
+		return 7;
+	}
+
+	if (st.st_atime != utb.actime ) {
+		fprintf(stderr, "%s: bad utime mtime %lu should be  %lu\n",
+			prog, st.st_atime, utb.actime);
 		return 7;
 	}
 
-	printf("%s: good utime times %lu%s <= %lu <= %lu\n",
-	       prog, before_utime, before_utime == st.st_mtime ? "*" : "",
-	       st.st_mtime, after_utime);
+	printf("%s: good utime mtimes %lu, atime %lu\n",
+	       prog, utb.modtime, utb.actime);
 
 	return 0;
 }
diff --git a/lustre/tests/write_append_truncate.c b/lustre/tests/write_append_truncate.c
new file mode 100644
index 0000000000000000000000000000000000000000..30a95e544760a91e2cc17e6ee06fdc8c894bb13b
--- /dev/null
+++ b/lustre/tests/write_append_truncate.c
@@ -0,0 +1,287 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Each loop does 3 things:
+ *   - truncate file to zero (not via ftruncate though, to test O_APPEND)
+ *   - append a "chunk" of data (should be at file offset 0 after truncate)
+ *   - on each of two threads either append or truncate-up the file
+ *
+ * If the truncate happened first, we should have a hole in the file.
+ * If the append happened first, we should have truncated the file down.
+ *
+ * We pick the CHUNK_SIZE_MAX and APPEND_SIZE_MAX so that we cross a stripe.
+ *
+ * compile: mpicc -g -Wall -o write_append_truncate write_append_truncate.c
+ * run:     mpirun -np 2 -machlist <hostlist file> write_append_truncate <file>
+ *  or:     pdsh -w <two hosts> write_append_truncate <file>
+ *  or:     prun -n 2 [-N 2] write_append_truncate <file>
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include "mpi.h"
+
+#define DEFAULT_ITER     50000
+
+#define CHUNK_SIZE_MAX   123456
+#define CHUNK_CHAR   'C'
+
+#define APPEND_SIZE_MAX  123456
+#define APPEND_CHAR  'A'
+
+#define TRUNC_SIZE_MAX   (CHUNK_SIZE_MAX+APPEND_SIZE_MAX)
+
+#define HOSTNAME_SIZE 50
+
+void usage(char *prog)
+{
+        printf("usage: %s <filename> [nloops]\n", prog);
+        printf("%s must be run with at least 2 processes\n", prog);
+
+        MPI_Finalize();
+        exit(1);
+}
+
+/* Print process rank, loop count, message, and exit (i.e. a fatal error) */
+int rprintf(int rank, int loop, const char *fmt, ...)
+{
+        va_list       ap;
+
+        printf("rank %d, loop %d: ", rank, loop);
+
+        va_start(ap, fmt);
+
+        vprintf(fmt, ap);
+
+        MPI_Finalize();
+        exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+        int n, nloops = 0, fd;
+        int rank, size, ret;
+        int chunk_size, append_size, trunc_offset;
+        char append_buf[APPEND_SIZE_MAX];
+        char chunk_buf[CHUNK_SIZE_MAX];
+        char read_buf[TRUNC_SIZE_MAX+APPEND_SIZE_MAX];
+        char trunc_buf[TRUNC_SIZE_MAX];
+        int done;
+        int error;
+        char hostname[HOSTNAME_SIZE];
+        char *fname, *prog;
+
+        error = MPI_Init(&argc, &argv);
+        if (error != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Init failed: %d\n", error);
+
+        prog = strrchr(argv[0], '/');
+        if (prog == NULL)
+                prog = argv[0];
+        else
+                prog++;
+
+        if (argc < 2 || argc > 3)
+                usage(prog);
+
+        error = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+        if (error != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Comm_rank failed: %d\n", error);
+
+        error = MPI_Comm_size(MPI_COMM_WORLD, &size);
+        if (error != MPI_SUCCESS)
+                rprintf(rank, -1, "MPI_Comm_size failed: %d\n", error);
+
+        if (size < 2)
+                rprintf(rank, -1, "%s: must run with at least 2 processes\n",
+                        prog);
+
+        memset(append_buf, APPEND_CHAR, APPEND_SIZE_MAX);
+        memset(chunk_buf, CHUNK_CHAR, CHUNK_SIZE_MAX);
+        memset(trunc_buf, 0, TRUNC_SIZE_MAX);
+
+        if (gethostname(hostname, HOSTNAME_SIZE) < 0)
+                rprintf(rank, -1, "gethostname failed: %s\n", strerror(errno));
+
+        fname = argv[1];
+
+        if (argc == 3)
+                nloops = strtoul(argv[2], NULL, 0);
+        if (nloops == 0)
+                nloops = DEFAULT_ITER;
+
+        if (rank == 0) {
+                fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+                if (fd < 0)
+                        rprintf(0, -1, "create %s failed: %s\n", fname,
+                                strerror(errno));
+                printf("using %s\n", fname);
+        }
+        error = MPI_Barrier(MPI_COMM_WORLD);
+        if (error != MPI_SUCCESS)
+                rprintf(rank, -1, "prep MPI_Barrier failed: %d\n", error);
+
+        fd = open(fname, O_RDWR | O_APPEND);
+        if (fd < 0)
+                rprintf(rank, -1, "open %s failed: %s\n",fname,strerror(errno));
+
+        for (n = 0; n < nloops; n++) {
+                /* reset the environment */
+                chunk_size = (rand()%(CHUNK_SIZE_MAX-1))+1;
+                append_size = (rand()%(APPEND_SIZE_MAX-1))+1;
+                trunc_offset = chunk_size + rand()%append_size;
+                if (rank == 0) {
+                        if (n % 1000 == 0)
+                                printf("loop %5d: chunk %6d/%#07x, "
+                                       "append %6d/%#07x, trunc @ %6d/%#07x\n",
+                                       n, chunk_size, chunk_size, append_size,
+                                       append_size, trunc_offset, trunc_offset);
+
+                        ret = truncate(fname, (off_t)0);
+                        if (ret < 0)
+                                rprintf(0, n, "truncate @ 0: %s\n",
+                                        strerror(errno));
+                        done = 0;
+                        do {
+                                ret = write(fd, chunk_buf+done,chunk_size-done);
+                                if (ret <= 0) {
+                                        rprintf(0, n, "chunk @ %d: %s\n",
+                                                done, strerror(errno));
+                                        break;
+                                }
+                                done += ret;
+                        } while (done != chunk_size);
+                }
+
+                error = MPI_Barrier(MPI_COMM_WORLD);
+                if (error != MPI_SUCCESS)
+                        rprintf(rank, n, "start MPI_Barrier: %d\n",error);
+
+                /* Do the race */
+                if (rank == n % size) {
+                        //
+                        done = 0;
+                        do {
+                                ret = write(fd, append_buf + done,
+                                            append_size - done);
+                                if (ret < 0) {
+                                        rprintf(rank, n,
+                                                "loop %d: append @ %u: %s\n",
+                                                done, strerror(errno));
+                                        break;
+                                }
+                                done += ret;
+                        } while (done != append_size);
+                } else if (rank == (n + 1) % size) {
+                        ret = truncate(fname, (off_t)trunc_offset);
+                        if (ret != 0)
+                                rprintf(rank, n, "truncate @ %u: %s\n",
+                                        trunc_offset, strerror(errno) );
+                }
+
+                error = MPI_Barrier(MPI_COMM_WORLD);
+                if (error != MPI_SUCCESS)
+                        rprintf(rank, n, "end MPI_Barrier: %d\n", error);
+
+                error = 0;
+
+                /* Check the result */
+                if (rank == 0) {
+                        struct stat st;
+                        if (stat(fname, &st) < 0)
+                                rprintf(0, n, "loop %d: stat %s: %s\n",
+                                        fname, strerror(errno));
+
+                        if (lseek(fd, (off_t)0, SEEK_SET) != 0)
+                                rprintf(0, n, "lseek fname 0: %s\n", fname,
+                                        strerror(errno));
+
+                        done = 0;
+                        do {
+                                ret = read(fd, read_buf+done, st.st_size-done);
+                                if (ret < 0) {
+                                        rprintf(0, n, "read @ %u: %s\n",
+                                               done, strerror(errno));
+                                }
+                                done += ret;
+                        } while (done != st.st_size);
+
+                        if (memcmp(read_buf, chunk_buf, chunk_size)) {
+                                printf("loop %d: base chunk bad"
+                                       " [0-%d]/[0-%#x] != %c\n", n,
+                                       chunk_size - 1, chunk_size - 1,
+                                       CHUNK_CHAR);
+                                error = 1;
+                        }
+
+                        if (st.st_size == trunc_offset) {
+                                /* Check case 1: first append then truncate */
+                                error = memcmp(read_buf+chunk_size, append_buf,
+                                               trunc_offset - chunk_size);
+                                if (error) {
+                                        printf("loop %d: trunc-after-append bad"
+                                               " [%d-%d]/[%#x-%#x] != %c\n",
+                                               n, chunk_size, trunc_offset - 1,
+                                               chunk_size, trunc_offset - 1,
+                                               APPEND_CHAR);
+                                }
+                        } else {
+                                /* Check case 2: first truncate then append */
+                                if (memcmp(read_buf+chunk_size, trunc_buf,
+                                           trunc_offset-chunk_size)) {
+                                        printf("loop %d: append-after-TRUNC bad"
+                                               " [%d-%d]/[%#x-%#x] != 0\n",
+                                               n, chunk_size, trunc_offset - 1,
+                                               chunk_size, trunc_offset - 1);
+                                        error = 1;
+                                } else if (memcmp(read_buf+trunc_offset,
+                                                  append_buf, append_size)) {
+                                        printf("loop %d: APPEND-after-trunc bad"
+                                               " [%d-%d]/[%#x-%#x] != %c\n",
+                                               n, trunc_offset, append_size - 1,
+                                               trunc_offset, append_size - 1,
+                                               APPEND_CHAR);
+                                        error = 1;
+                                }
+                        }
+                }
+                ret = MPI_Bcast(&error, 1, MPI_INT, 0, MPI_COMM_WORLD);
+                if (ret != MPI_SUCCESS)
+                        rprintf(rank, n, "MPI_Bcast: %d\n");
+
+                if (error == 1) {
+                        if (rank == 0) {
+                                char command[4096];
+
+                                printf("loop %5d: chunk %6d/%#07x, "
+                                       "append %6d/%#07x, trunc @ %6d/%#07x\n",
+                                       n, chunk_size, chunk_size, append_size,
+                                       append_size, trunc_offset, trunc_offset);
+
+                                sprintf(command, "od -Ax -a %s", fname);
+                                system(command);
+                        }
+                        rprintf(rank, n, "on machine %s with pid %d\n",
+                                hostname, (int)getpid());
+                }
+        }
+
+        printf("rank %d, loop %d: finished\n", rank, n);
+        close(fd);
+
+        if (rank == 0) {
+                error = unlink(fname);
+                if (error < 0)
+                        rprintf(0, n, "unlink %s failed: %s\n",
+                                fname, strerror(errno));
+        }
+
+        MPI_Finalize();
+        return 0;
+}
diff --git a/lustre/tests/write_disjoint.c b/lustre/tests/write_disjoint.c
new file mode 100644
index 0000000000000000000000000000000000000000..16774c8966c9b5a94a85642d9d2c805ffba4c818
--- /dev/null
+++ b/lustre/tests/write_disjoint.c
@@ -0,0 +1,161 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Each loop does 3 things:
+ *   - rank 0 truncates to 0
+ *   - all ranks agree on a random chunk size
+ *   - all ranks race to write their pattern to their chunk of the file
+ *   - rank 0 makes sure that the resulting file size is ranks * chunk size
+ *   - rank 0 makes sure that everyone's patterns went to the right place
+ *
+ * compile: mpicc -g -Wall -o write_disjoint write_disjoint.c
+ * run:     mpirun -np N -machlist <hostlist file> write_disjoint
+ *  or:     pdsh -w <N hosts> write_disjoint 
+ *  or:     prun -n N [-N M] write_disjoint
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include "mpi.h"
+
+
+#define FILENAME "/mnt/lustre/write_disjoint"
+#define CHUNK_MAX_SIZE 123456
+
+int rprintf(int rank, int loop, const char *fmt, ...)
+{
+        va_list       ap;
+ 
+        printf("rank %d, loop %d: ", rank, loop);
+ 
+        va_start(ap, fmt);
+ 
+        vprintf(fmt, ap);
+ 
+        MPI_Finalize();
+        exit(1);
+}
+
+int main (int argc, char *argv[]) {
+         int i, n, fd, chunk_size, file_size;
+         int rank, noProcessors, done;
+         off_t offset;
+         char **chunk_buf;
+         char *read_buf;
+         struct stat stat_buf;
+         ssize_t ret;
+
+         MPI_Init(&argc, &argv);
+         MPI_Comm_size(MPI_COMM_WORLD, &noProcessors);
+         MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+                         
+         chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0]));
+         for (i=0; i < noProcessors; i++) {
+                chunk_buf[i] = malloc(CHUNK_MAX_SIZE);
+                memset(chunk_buf[i], 'A'+ i, CHUNK_MAX_SIZE);
+         }
+         read_buf = malloc(noProcessors * CHUNK_MAX_SIZE);
+         
+         if (rank == 0) {
+                fd = open(FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+                if (fd < 0) 
+                        rprintf(rank, -1, "open() returned %s\n", 
+                                strerror(errno));
+         }
+         MPI_Barrier(MPI_COMM_WORLD);
+
+         fd = open(FILENAME, O_RDWR);
+         if (fd < 0)
+                 rprintf(rank, -1, "open() returned %s\n", strerror(errno));
+         
+         for (n=0; n < 1000 ; n++) {
+                 /* reset the environment */
+                 if (rank == 0) {
+                         ret = truncate(FILENAME, 0);
+                         if (ret != 0)
+                                 rprintf(rank, n, "truncate() returned %s\n", 
+                                         strerror(errno) );
+                 }
+                 chunk_size = rand() % CHUNK_MAX_SIZE;
+
+                 if (n % 1000 == 0 && rank == 0)
+                         printf("loop %d: chunk_size %d\n", n, chunk_size);
+
+                 MPI_Barrier(MPI_COMM_WORLD);
+                 
+                 /* Do the race */
+                 offset = rank * chunk_size;
+                 lseek(fd, offset, SEEK_SET);
+
+                 done = 0;
+                 do {
+                        ret = write(fd, chunk_buf[rank]+done, chunk_size-done);
+                        if (ret < 0) 
+                                 rprintf(rank, n, "write() returned %s\n", 
+                                         strerror(errno));
+                        done += ret;
+                 } while (done != chunk_size);
+
+                 MPI_Barrier(MPI_COMM_WORLD);
+
+                 /* Check the result */
+                 if (rank == 0) {
+                         lseek(fd, 0, SEEK_SET);
+                         
+                         /* quick check */
+                         stat(FILENAME, &stat_buf);
+                         file_size = stat_buf.st_size;
+                         if (file_size != chunk_size * noProcessors)
+                                  rprintf(rank, n, "invalid file size %d"
+                                          " instead of %d\n", file_size, 
+                                          chunk_size * noProcessors);
+
+                        done = 0;
+                        do {
+                                ret = read(fd, read_buf + done, 
+                                           (chunk_size * noProcessors) - done);
+                                if (ret < 0) 
+                                        rprintf(rank, n, "read returned %s\n",
+                                                strerror(errno));
+
+                                done += ret;
+                        } while (done != chunk_size * noProcessors);
+
+                        for (i = 0; i < noProcessors; i++) {
+                                char command[4096]; 
+                                int j;
+                                if (!memcmp(read_buf + (i * chunk_size), 
+                                           chunk_buf[i], chunk_size))
+                                        continue;
+
+                                printf("rank %d, loop %d: chunk %d corrupted "
+                                       "with chunk_size %d\n", rank, n, i, 
+                                       chunk_size);
+                                printf("(ranks: page boundry, chunk boundry, "
+                                       "page boundry)\n");
+                                for (j = 1 ; j < noProcessors; j++) {
+                                        int b = j * chunk_size;
+                                        printf("\t%c -> %c: %d %d %d\n", 
+                                               'A' + j - 1, 'A' + j, 
+                                               b & ~(4096-1), b, 
+                                               (b + 4096) & ~(4096-1));
+                                }
+
+                                sprintf(command, "od -Ad -a %s", FILENAME);
+                                system(command);
+                                MPI_Finalize();
+                                exit(1);
+                        }
+                }
+        }
+
+        printf("Finished after %d loops\n", n);
+        MPI_Finalize();
+        return 0;
+}
diff --git a/lustre/utils/.cvsignore b/lustre/utils/.cvsignore
index 20f41858c7031d6e003d2ae7a849fe4b2f6191bb..59147ac7d0adc4984c3e49b6ce2bf2070ce44fca 100644
--- a/lustre/utils/.cvsignore
+++ b/lustre/utils/.cvsignore
@@ -9,12 +9,14 @@ tags
 TAGS
 obdctl
 lctl
-lfind
-lstripe
 obdstat
 obdio
 obdbarrier
 lload
 wirecheck
+lfs
+llmount
+mount.lustre
+wiretest
 .*.cmd
 .*.d
diff --git a/lustre/utils/Lustre/cmdline.py b/lustre/utils/Lustre/cmdline.py
index 53bb6e88dc6fc03deeac1f4943994d56c0053a91..d2a39f66091251c20a0e850a663b43419b903242 100644
--- a/lustre/utils/Lustre/cmdline.py
+++ b/lustre/utils/Lustre/cmdline.py
@@ -28,6 +28,7 @@ class Options:
     FLAG = 1
     PARAM = 2
     INTPARAM = 3
+    PARAMLIST = 4
     def __init__(self, cmd, remain_help, options):
         self.options = options
         shorts = ""
@@ -36,9 +37,13 @@ class Options:
         for opt in options:
             long = self.long(opt)
             short = self.short(opt)
-            if self.type(opt) in (Options.PARAM, Options.INTPARAM):
-                if short:  short = short + ':'
-                if long: long = long + '='
+            if self.type(opt) in (Options.PARAM, Options.INTPARAM,
+                                  Options.PARAMLIST):
+                if short: short = short + ':'
+                if long:
+                    long = long + '='
+            if string.find(long, '_') >= 0:
+                longs.append(string.replace(long, '_', '-'))
             shorts = shorts + short
             longs.append(long)
         self.short_opts = shorts
@@ -77,6 +82,8 @@ class Options:
     def default(self, option):
         if len(option) >= 4:
             return option[3]
+        if self.type(option) == Options.PARAMLIST:
+            return []
         return None
 
     def lookup_option(self, key, key_func):
@@ -88,6 +95,7 @@ class Options:
         return self.lookup_option(key, self.short)
 
     def lookup_long(self, key):
+        key = string.replace(key, '-', '_')
         return self.lookup_option(key, self.long)
 
     def handle_opts(self, opts):
@@ -104,6 +112,9 @@ class Options:
                     val = int(a)
                 except ValueError, e:
                     raise error.OptionError("option: '%s' expects integer value, got '%s' "  % (o,a))
+            elif self.type(option) == Options.PARAMLIST:
+                val = values[self.key(option)];
+                val.append(a)
             else:
                 val = 1
             values[self.key(option)] = val
@@ -118,6 +129,11 @@ class Options:
                 return self.values[name]
             else:
                 raise error.OptionError("bad option name: " + name)
+        def __getitem__(self, name):
+            if self.values.has_key(name):
+                return self.values[name]
+            else:
+                raise error.OptionError("bad option name: " + name)
         def __setattr__(self, name, value):
             self.values[name] = value
 
diff --git a/lustre/utils/Lustre/lustredb.py b/lustre/utils/Lustre/lustredb.py
index 82d487ce505179e986f7483959c0bf397b8d4def..4ba04db11ba90c3b46f25891c1f7298b21459c36 100644
--- a/lustre/utils/Lustre/lustredb.py
+++ b/lustre/utils/Lustre/lustredb.py
@@ -57,10 +57,12 @@ class LustreDB:
         uuids = self._get_all_refs()
         return uuids
 
-    def nid2server(self, nid, net_type):
+    def nid2server(self, nid, net_type, cluster_id):
         netlist = self.lookup_class('network')
         for net_db in netlist:
-            if net_db.get_val('nid') == nid and net_db.get_val('nettype') == net_type: 
+            if (net_db.get_val('nid') == nid and
+                net_db.get_val('nettype') == net_type and
+                net_db.get_val('clusterid') == cluster_id):
                 return net_db
         return None
     
@@ -298,7 +300,7 @@ class LustreDB_LDAP(LustreDB):
             # user and pw only needed if modifying db
             self.l.bind_s(self._user, self._pw, ldap.AUTH_SIMPLE);
         except ldap.LDAPError, e:
-            raise Lustre.LconfError('Unable to connection to ldap server')
+            raise Lustre.LconfError('Unable to connect to ldap server:' + self._url)
 
         try:
             self._name, self._attrs = self.l.search_s(self._base,
diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am
index d09ecc22849f9e17cf985dcaece7d6d7954010d7..c0612fc9fb5bfa7b937e3e6c17ea5d01f4a238ba 100644
--- a/lustre/utils/Makefile.am
+++ b/lustre/utils/Makefile.am
@@ -6,18 +6,33 @@ CFLAGS:=-g -O2 -I$(top_srcdir)/utils -I$(top_srcdir)/portals/include  -I$(srcdir
 KFLAGS:=
 CPPFLAGS = $(HAVE_LIBREADLINE)
 lctl_LDADD := $(LIBREADLINE) -lptlctl
+lfs_LDADD := $(LIBREADLINE) parser.o liblustreapi.a -lptlctl obd.o
 lload_LDADD := -lptlctl
-bin_PROGRAMS = lfind lstripe
-sbin_PROGRAMS = lctl obdio obdbarrier lload wirecheck
-sbin_SCRIPTS = lconf lmc llanalyze llstat.pl llobdstat.pl lactive load_ldap.sh
+rootsbin_SCRIPTS = mount.lustre
+sbin_PROGRAMS = lctl obdio obdbarrier lload wirecheck wiretest lfs llmount
+sbin_SCRIPTS = lconf lmc llanalyze llstat.pl llobdstat.pl lactive load_ldap.sh lrun
+sbin_SCRIPTS += lwizard
+bin_SCRIPTS = lfind lstripe
+lib_LIBRARIES = liblustreapi.a
+liblustreapi_a_SOURCES = liblustreapi.c
 wirecheck_SOURCES = wirecheck.c
-lctl_SOURCES = parser.c obd.c lctl.c parser.h obdctl.h
+wiretest_SOURCES = wiretest.c
+lctl_SOURCES = parser.c obd.c lustre_cfg.c lctl.c parser.h obdctl.h
 lload_SOURCES = lload.c 
 obdio_SOURCES = obdio.c obdiolib.c obdiolib.h
 obdbarrier_SOURCES = obdbarrier.c obdiolib.c obdiolib.h
-lfind_SOURCES = lfind.c
-lstripe_SOURCES = lstripe.c
-lfind_CPPFLAGS = -D_XOPEN_SOURCE=500
-EXTRA_DIST = $(sbin_SCRIPTS)
+lfs_SOURCES = lfs.c 
+llmount_SOURCES = llmount.c 
+llmount_LDADD = -lptlctl
+
+EXTRA_DIST = $(bin_SCRIPTS) $(sbin_SCRIPTS)
 
 include $(top_srcdir)/Rules
+
+# NOTE: this should only be run on i386.
+newwiretest: wirehdr.c wirecheck
+	cp wirehdr.c wiretest.c
+	./wirecheck >> wiretest.c
+
+mount.lustre$(EXEEXT): llmount
+	cp llmount mount.lustre
diff --git a/lustre/utils/Makefile.mk b/lustre/utils/Makefile.mk
new file mode 100644
index 0000000000000000000000000000000000000000..87bcf077bfe040109925dfee420ee6c3b4417ec2
--- /dev/null
+++ b/lustre/utils/Makefile.mk
@@ -0,0 +1,15 @@
+include $(src)/../portals/Kernelenv
+
+OURPTLCTL := $(addprefix $(src)/../portals/utils/, $(PTLCTLOBJS))
+OURPTLCTLNOPARSER := $(addprefix $(src)/../portals/utils/, \
+			$(filter-out parser.o,$(PTLCTLOBJS)))
+
+host-progs := lctl lfind lstripe obdio obdbarrier lload #lfs# obdstat
+always := $(host-progs) 
+
+lctl-objs := parser.o obd.o lctl.o lustre_cfg.o
+HOSTLOADLIBES_lctl += $(LIBREADLINE) $(OURPTLCTLNOPARSER)
+obdio-objs := obdio.o obdiolib.o
+obdbarrier-objs := obdbarrier.o obdiolib.o
+lload-objs := lload.o
+HOSTLOADLIBES_lload += $(OURPTLCTL)
diff --git a/lustre/utils/lconf b/lustre/utils/lconf
index 00ea58a1f9813ef1fe927666768f20e5bccda01e..2a0281534d1ff0c59376956241a3f37d186589d1 100755
--- a/lustre/utils/lconf
+++ b/lustre/utils/lconf
@@ -49,14 +49,17 @@ if not development_mode():
 import Lustre
 
 # Global parameters
-MAXTCPBUF = 1048576
-DEFAULT_TCPBUF = 1048576
+MAXTCPBUF = 16777216
+DEFAULT_TCPBUF = 8388608
+DEFAULT_PORT = 988
 #
 # Maximum number of devices to search for.
 # (the /dev/loop* nodes need to be created beforehand)
 MAX_LOOP_DEVICES = 256
 PORTALS_DIR = 'portals'
 
+# Needed to call lconf --record
+CONFIG_FILE = "" 
 
 # Please keep these in sync with the values in portals/kp30.h
 ptldebug_names = { 
@@ -246,7 +249,7 @@ class DaemonHandler:
             log(self.pidfile(), e)
             
 class AcceptorHandler(DaemonHandler):
-    def __init__(self, port, net_type, send_mem, recv_mem, irq_aff, nid_xchg):
+    def __init__(self, port, net_type, send_mem, recv_mem, irq_aff):
         DaemonHandler.__init__(self, "acceptor")
         self.port = port
         self.flags = ''
@@ -257,8 +260,6 @@ class AcceptorHandler(DaemonHandler):
             self.flags = self.flags + ' -N 4'
         if irq_aff:
             self.flags = self.flags + ' -i'
-        if nid_xchg:
-            self.flags = self.flags + ' -x'
 
     def pidfile(self):
         return "/var/run/%s-%d.pid" % (self.command, self.port)
@@ -270,12 +271,16 @@ acceptors = {}
 
 # start the acceptors
 def run_acceptors():
+    if config.lctl_dump or config.record:
+        return
     for port in acceptors.keys():
         daemon = acceptors[port]
         if not daemon.running():
             daemon.start()
 
 def run_one_acceptor(port):
+    if config.lctl_dump or config.record:
+        return
     if acceptors.has_key(port):
         daemon = acceptors[port]
         if not daemon.running():
@@ -303,6 +308,7 @@ class LCTLInterface:
         """
         self.lctl = find_prog(cmd)
         self.save_file = ''
+        self.record_device = ''
         if not self.lctl:
             if config.noexec:
                 debug('! lctl not found')
@@ -313,6 +319,16 @@ class LCTLInterface:
     def use_save_file(self, file):
         self.save_file = file
         
+    def record(self, dev_name, logname):
+        log("Recording log", logname, "on", dev_name)
+        self.record_device = dev_name
+        self.record_log = logname
+
+    def end_record(self):
+        log("End recording log", self.record_log, "on", self.record_device)
+        self.record_device = None
+        self.record_log = None
+
     def set_nonblock(self, fd):
         fl = fcntl.fcntl(fd, F_GETFL)
         fcntl.fcntl(fd, F_SETFL, fl | os.O_NDELAY)
@@ -328,8 +344,14 @@ class LCTLInterface:
         """
         cmd_line = self.lctl
         if self.save_file:
-            cmds = '\n  dump ' + self.save_file + cmds
-
+            cmds = '\n  dump ' + self.save_file + '\n' + cmds
+        elif self.record_device:
+            cmds = """
+    device $%s
+    probe
+    record %s
+    %s""" % (self.record_device, self.record_log, cmds)
+            
         debug("+", cmd_line, cmds)
         if config.noexec: return (0, [])
 
@@ -382,7 +404,7 @@ class LCTLInterface:
 
             
     def network(self, net, nid):
-        """ initialized network and add "self" """
+        """ set mynid """
         cmds =  """
   network %s
   mynid %s
@@ -390,25 +412,32 @@ class LCTLInterface:
         self.run(cmds)
 
     # create a new connection
+    def add_uuid(self, net_type, uuid, nid):
+        cmds = "\n  add_uuid %s %s %s" %(uuid, nid, net_type)
+        self.run(cmds)
+
+    def add_autoconn(self, net_type, send_mem, recv_mem, nid, hostaddr,
+                     port, flags):
+        if net_type  in ('tcp', 'toe') and not config.lctl_dump:
+            cmds =  """
+  network %s
+  send_mem %d
+  recv_mem %d
+  add_autoconn %s %s %d %s
+  quit""" % (net_type,
+             send_mem,
+             recv_mem,
+             nid, hostaddr, port, flags )
+            self.run(cmds)
+    
     def connect(self, srv):
-        cmds =  "\n  add_uuid %s %s %s" % (srv.uuid, srv.nid, srv.net_type)
+        self.add_uuid(srv.net_type, srv.nid_uuid, srv.nid)
         if srv.net_type  in ('tcp', 'toe') and not config.lctl_dump:
             flags = 's'
             if srv.irq_affinity:
                 flags = flags + 'i'
-            if srv.nid_exchange:
-                flags = flags + 'x'
-            cmds =  """%s          
-  network %s
-  send_mem %d
-  recv_mem %d
-  add_autoconn %s %s %d %s""" % (cmds, srv.net_type,
-             srv.send_mem,
-             srv.recv_mem,
-             srv.nid, srv.hostaddr, srv.port, flags )
-
-        cmds = cmds + "\n  quit"
-        self.run(cmds)
+            self.add_autoconn(srv.net_type, srv.send_mem, srv.recv_mem,
+                 srv.nid, srv.hostaddr, srv.port, flags)
 
     # Recover a device
     def recover(self, dev_name, new_conn):
@@ -441,12 +470,11 @@ class LCTLInterface:
 
     # add a route to a host
     def add_route_host(self, net, uuid, gw, tgt):
+        self.add_uuid(net, uuid, tgt)
         cmds =  """
   network %s
-  add_uuid %s %s %s
   add_route %s %s
   quit """ % (net,
-              uuid, tgt, net,
               gw, tgt)
         try:
             self.run(cmds)
@@ -456,32 +484,36 @@ class LCTLInterface:
 
     # add a route to a range
     def del_route_host(self, net, uuid, gw, tgt):
+        self.del_uuid(uuid)
         cmds =  """
   ignore_errors
   network %s
-  del_uuid %s
   del_route %s %s
-  quit  """ % (net, uuid, gw, tgt)
+  quit  """ % (net, gw, tgt)
         self.run(cmds)
 
+
+    def del_autoconn(self, net_type, nid, hostaddr):
+        if net_type  in ('tcp', 'toe') and not config.lctl_dump:
+                cmds =  """
+  ignore_errors
+  network %s
+  del_autoconn %s %s s
+  quit""" % (net_type,
+             nid, hostaddr)
+                self.run(cmds)
+        
     # disconnect one connection
     def disconnect(self, srv):
-        cmds =  "   ignore_errors\n  del_uuid %s" % (srv.uuid)
+        self.del_uuid(srv.nid_uuid)
         if srv.net_type  in ('tcp', 'toe') and not config.lctl_dump:
-                cmds =  """%s
-  network %s
-  del_autoconn %s %s s""" % (cmds,
-                                     srv.net_type,
-                                     srv.nid, srv.hostaddr)
-        cmds = cmds + "\n  quit"
-
-        self.run(cmds)
+            self.del_autoconn(srv.net_type, srv.nid, srv.hostaddr)
 
-    def del_uuid(self, servuuid):
+    def del_uuid(self, uuid):
         cmds =  """
   ignore_errors
   del_uuid %s
-  quit""" % (servuuid,)
+  quit""" % (uuid,)
         self.run(cmds)
 
     # disconnect all
@@ -493,33 +525,58 @@ class LCTLInterface:
   quit""" % (net)
         self.run(cmds)
 
-    # create a new device with lctl
-    def newdev(self, attach, setup = ""):
+    def attach(self, type, name, uuid):
         cmds = """
-  newdev
-  attach %s
+  attach %s %s %s
+  quit""" % (type, name, uuid)
+        self.run(cmds)
+        
+    def setup(self,  name, setup = ""):
+        cmds = """
+  cfg_device %s
   setup %s
-  quit""" % (attach, setup)
+  quit""" % (name, setup)
         self.run(cmds)
+        
+
+    # create a new device with lctl
+    def newdev(self, type, name, uuid, setup = ""):
+        self.attach(type, name, uuid);
+        try:
+            self.setup(name, setup)
+        except CommandError, e:
+            self.cleanup(name, uuid, 0)
+            raise e
+        
 
     # cleanup a device
     def cleanup(self, name, uuid, force, failover = 0):
         if failover: force = 1
         cmds = """
   ignore_errors
-  device $%s
+  cfg_device $%s
   cleanup %s %s
   detach
   quit""" % (name, ('', 'force')[force],
              ('', 'failover')[failover])
         self.run(cmds)
 
+    # create an lov
+    def lov_setup(self, name, uuid, desc_uuid, mdsuuid, stripe_cnt,
+                  stripe_sz, stripe_off,
+                      pattern, devlist):
+        cmds = """
+  attach lov %s %s
+  lov_setup %s %d %d %d %s %s
+  quit""" % (name, uuid, desc_uuid, stripe_cnt, stripe_sz, stripe_off,
+             pattern, devlist)
+        self.run(cmds)
+
     # create an lov
     def lov_setconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off,
                       pattern, devlist):
         cmds = """
-  device $%s
-  probe
+  cfg_device $%s
   lov_setconfig %s %d %d %d %s %s
   quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist)
         self.run(cmds)
@@ -533,14 +590,16 @@ class LCTLInterface:
 
     # get list of devices
     def device_list(self):
-        try:
-            rc, out = self.runcmd('device_list')
-        except CommandError, e:
-            if config.cleanup:
-                out = []
-            else:
-                raise e
-        return out
+        devices = '/proc/fs/lustre/devices'
+        ret = []
+        if os.access(devices, os.R_OK):
+            try:
+                fp = open(devices, 'r')
+                ret =  fp.readlines()
+                fp.close()
+            except IOError, e:
+                log(e)
+        return ret
 
     # get lustre version
     def lustre_version(self):
@@ -548,10 +607,30 @@ class LCTLInterface:
         return out
 
     # dump mount options
-    def mount_option(self, option):
+    def mount_option(self, profile, osc, mdc):
         cmds = """
-  mount_option %s
-  quit""" % (option)
+  mount_option %s %s %s
+  quit""" % (profile, osc, mdc)
+        self.run(cmds)
+
+    # delete mount options
+    def del_mount_option(self, profile):
+        cmds = """
+  del_mount_option %s
+  quit""" % (profile,)
+        self.run(cmds)
+
+    def set_timeout(self, timeout):
+        cmds = """
+  set_timeout %s
+  quit""" % (timeout,)
+        self.run(cmds)
+
+    # delete mount options
+    def set_lustre_upcall(self, upcall):
+        cmds = """
+  set_lustre_upcall %s
+  quit""" % (upcall,)
         self.run(cmds)
 # ============================================================
 # Various system-level functions
@@ -636,7 +715,7 @@ def is_block(path):
 
 # build fs according to type
 # fixme: dangerous
-def mkfs(dev, devsize, fstype,jsize):
+def mkfs(dev, devsize, fstype, jsize, mkfsoptions, isblock=1):
     block_cnt = ''
     jopt = ''
     if devsize:
@@ -649,14 +728,20 @@ def mkfs(dev, devsize, fstype,jsize):
     if fstype in ('ext3', 'extN'):
         # ext3 journal size is in megabytes
         if jsize:  jopt = "-J size=%d" %(jsize,)
-        mkfs = 'mkfs.ext2 -j -b 4096 -F '
+        mkfs = 'mkfs.ext2 -j -b 4096 '
+        if not isblock or config.force:
+            mkfs = mkfs + ' -F '
     elif fstype == 'reiserfs':
         # reiserfs journal size is in blocks
         if jsize:  jopt = "--journal_size %d" %(jsize,)
         mkfs = 'mkreiserfs -ff'
     else:
-        print 'unsupported fs type: ', fstype
+        panic('unsupported fs type: ', fstype)
 
+    if config.mkfsoptions != None:
+        mkfs = mkfs + ' ' + config.mkfsoptions
+    if mkfsoptions != None:
+        mkfs = mkfs + ' ' + mkfsoptions
     (ret, out) = run (mkfs, jopt, dev, block_cnt)
     if ret:
         panic("Unable to build fs:", dev, string.join(out))
@@ -693,19 +778,19 @@ def find_loop(file):
     return ''
 
 # create file if necessary and assign the first free loop device
-def init_loop(file, size, fstype, journal_size):
+def init_loop(file, size, fstype, journal_size, mkfsoptions, reformat):
     dev = find_loop(file)
     if dev:
         print 'WARNING file:', file, 'already mapped to', dev
         return dev
-    if config.reformat or not os.access(file, os.R_OK | os.W_OK):
+    if reformat or not os.access(file, os.R_OK | os.W_OK):
         if size < 8000:
             panic("size of loopback file '%s' must be larger than 8MB, but is set to %s" % (file,size))
         (ret, out) = run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size,
                                                                          file))
         if ret:
             panic("Unable to create backing store:", file)
-        mkfs(file, size, fstype, journal_size)
+        mkfs(file, size, fstype, journal_size, mkfsoptions, isblock=0)
 
     loop = loop_base()
     # find next free loop
@@ -737,12 +822,13 @@ def need_format(fstype, dev):
     return 0
 
 # initialize a block device if needed
-def block_dev(dev, size, fstype, format, journal_size):
+def block_dev(dev, size, fstype, reformat, autoformat, journal_size,
+              mkfsoptions):
     if config.noexec: return dev
     if not is_block(dev):
-        dev = init_loop(dev, size, fstype, journal_size)
-    elif config.reformat or (need_format(fstype, dev) and format == 'yes'):
-        mkfs(dev, size, fstype, journal_size)
+        dev = init_loop(dev, size, fstype, journal_size, mkfsoptions, reformat)
+    elif reformat or (need_format(fstype, dev) and autoformat == 'yes'):
+        mkfs(dev, size, fstype, journal_size, mkfsoptions, isblock=0)
 
 #    else:
 #        panic("device:", dev,
@@ -813,12 +899,25 @@ def sys_get_local_address(net_type, wildcard, cluster_id):
 
     return local
 
+def mod_loaded(modname):
+    """Check if a module is already loaded. Look in /proc/modules for it."""
+    try:
+        fp = open('/proc/modules')
+        lines = fp.readlines()
+        fp.close()
+        # please forgive my tired fingers for this one
+        ret = filter(lambda word, mod=modname: word == mod,
+                     map(lambda line: string.split(line)[0], lines))
+        return ret
+    except Exception, e:
+        return 0
+
 # XXX: instead of device_list, ask for $name and see what we get
 def is_prepared(name):
     """Return true if a device exists for the name"""
     if config.lctl_dump:
         return 0
-    if config.noexec and config.cleanup:
+    if (config.noexec or config.record) and config.cleanup:
         return 1
     try:
         # expect this format:
@@ -832,10 +931,11 @@ def is_prepared(name):
     return 0
 
 def is_network_prepared():
-    """If the LDLM device exists, then assume that all networking
+    """If the any device exists, then assume that all networking
        has been configured"""
-    return is_prepared('ldlm')
-    
+    out = lctl.device_list()
+    return len(out) > 0
+
 def fs_is_mounted(path):
     """Return true if path is a mounted lustre filesystem"""
     try:
@@ -851,6 +951,55 @@ def fs_is_mounted(path):
     return 0
         
 
+class kmod:
+    """Manage kernel modules"""
+    def __init__(self, lustre_dir, portals_dir):
+        self.lustre_dir = lustre_dir
+        self.portals_dir = portals_dir
+        self.kmodule_list = []
+
+    def add_portals_module(self, dev_dir, modname):
+        """Append a module to list of modules to load."""
+        self.kmodule_list.append((self.portals_dir, dev_dir, modname))
+
+    def add_lustre_module(self, dev_dir, modname):
+        """Append a module to list of modules to load."""
+        self.kmodule_list.append((self.lustre_dir, dev_dir, modname))
+
+    def load_module(self):
+        """Load all the modules in the list in the order they appear."""
+        for src_dir, dev_dir, mod in self.kmodule_list:
+            if mod_loaded(mod) and not config.noexec:
+                continue
+            log ('loading module:', mod, 'srcdir', src_dir, 'devdir', dev_dir)
+            if src_dir:
+                module = find_module(src_dir, dev_dir,  mod)
+                if not module:
+                    panic('module not found:', mod)
+                (rc, out)  = run('/sbin/insmod', module)
+                if rc:
+                    raise CommandError('insmod', out, rc)
+            else:
+                (rc, out) = run('/sbin/modprobe', mod)
+                if rc:
+                    raise CommandError('modprobe', out, rc)
+
+    def cleanup_module(self):
+        """Unload the modules in the list in reverse order."""
+        rev = self.kmodule_list
+        rev.reverse()
+        for src_dir, dev_dir, mod in rev:
+            if not mod_loaded(mod) and not config.noexec:
+                continue
+            # debug hack
+            if mod == 'portals' and config.dump:
+                lctl.dump(config.dump)
+            log('unloading module:', mod)
+            (rc, out) = run('/sbin/rmmod', mod)
+            if rc:
+                log('! unable to unload module:', mod)
+                logall(out)
+
 # ============================================================
 # Classes to prepare and cleanup the various objects
 #
@@ -863,9 +1012,9 @@ class Module:
         self.module_name = module_name
         self.name = self.db.getName()
         self.uuid = self.db.getUUID()
-        self.kmodule_list = []
         self._server = None
         self._connected = 0
+        self.kmod = kmod(config.lustre, config.portals)
         
     def info(self, *args):
         msg = string.join(map(str,args))
@@ -883,58 +1032,20 @@ class Module:
             
     def add_portals_module(self, dev_dir, modname):
         """Append a module to list of modules to load."""
-        self.kmodule_list.append((config.portals, dev_dir, modname))
+        self.kmod.add_portals_module(dev_dir, modname)
 
     def add_lustre_module(self, dev_dir, modname):
         """Append a module to list of modules to load."""
-        self.kmodule_list.append((config.lustre, dev_dir, modname))
-
-    def mod_loaded(self, modname):
-        """Check if a module is already loaded. Look in /proc/modules for it."""
-        fp = open('/proc/modules')
-        lines = fp.readlines()
-        fp.close()
-        # please forgive my tired fingers for this one
-        ret = filter(lambda word, mod=modname: word == mod,
-                     map(lambda line: string.split(line)[0], lines))
-        return ret
+        self.kmod.add_lustre_module(dev_dir, modname)
 
     def load_module(self):
         """Load all the modules in the list in the order they appear."""
-        for src_dir, dev_dir, mod in self.kmodule_list:
-            #  (rc, out) = run ('/sbin/lsmod | grep -s', mod)
-            if self.mod_loaded(mod) and not config.noexec:
-                continue
-            log ('loading module:', mod, 'srcdir', src_dir, 'devdir', dev_dir)
-            if src_dir:
-                module = find_module(src_dir, dev_dir,  mod)
-                if not module:
-                    panic('module not found:', mod)
-                (rc, out)  = run('/sbin/insmod', module)
-                if rc:
-                    raise CommandError('insmod', out, rc)
-            else:
-                (rc, out) = run('/sbin/modprobe', mod)
-                if rc:
-                    raise CommandError('modprobe', out, rc)
+        self.kmod.load_module()
             
     def cleanup_module(self):
         """Unload the modules in the list in reverse order."""
-        if not self.safe_to_clean():
-            return
-        rev = self.kmodule_list
-        rev.reverse()
-        for src_dir, dev_dir, mod in rev:
-            if not self.mod_loaded(mod) and not config.noexec:
-                continue
-            # debug hack
-            if mod == 'portals' and config.dump:
-                lctl.dump(config.dump)
-            log('unloading module:', mod)
-            (rc, out) = run('/sbin/rmmod', mod)
-            if rc:
-                log('! unable to unload module:', mod)
-                logall(out)
+        if self.safe_to_clean():
+            self.kmod.cleanup_module()
 
     def safe_to_clean(self):
         return 1
@@ -952,16 +1063,17 @@ class Network(Module):
         self.send_mem = self.db.get_val_int('sendmem', DEFAULT_TCPBUF)
         self.recv_mem = self.db.get_val_int('recvmem', DEFAULT_TCPBUF)
         self.irq_affinity = self.db.get_val_int('irqaffinity', 0)
-        self.nid_exchange = self.db.get_val_int('nidexchange', 0)
 
         if '*' in self.nid:
-            if self.nid_exchange:
-                self.nid = sys_get_local_nid(self.net_type, self.nid, self.cluster_id)
-            else:
-                self.nid = sys_get_local_address(self.net_type, self.nid, self.cluster_id)
+            self.nid = sys_get_local_nid(self.net_type, self.nid, self.cluster_id)
             if not self.nid:
                 panic("unable to set nid for", self.net_type, self.nid, cluster_id)
+            self.generic_nid = 1
             debug("nid:", self.nid)
+        else:
+            self.generic_nid = 0
+
+        self.nid_uuid = self.nid_to_uuid(self.nid)
 
         self.hostaddr = self.db.get_val('hostaddr', self.nid)
         if '*' in self.hostaddr:
@@ -984,11 +1096,19 @@ class Network(Module):
         if self.net_type == 'scimac':
             self.add_portals_module("knals/scimacnal", 'kscimacnal')
 
+    def nid_to_uuid(self, nid):
+        return "NID_%s_UUID" %(nid,)
+
     def prepare(self):
         if is_network_prepared():
             return
         self.info(self.net_type, self.nid, self.port)
-        lctl.network(self.net_type, self.nid)
+        if not (config.record and self.generic_nid):
+            lctl.network(self.net_type, self.nid)
+        if self.net_type == 'tcp':
+            sys_tweak_socknal()
+        if self.net_type == 'elan':
+            sys_optimize_elan()
         if self.port and  node_is_router():
             run_one_acceptor(self.port)
             self.connect_peer_gateways()
@@ -1030,18 +1150,12 @@ class Network(Module):
         if  node_is_router():
             self.disconnect_peer_gateways()
 
-        try:
-            lctl.disconnectAll(self.net_type)
-        except CommandError, e:
-            print "disconnectAll failed: ", self.name
-            e.dump()
-            cleanup_error(e.rc)
-
 class RouteTable(Module):
     def __init__(self,db):
         Module.__init__(self, 'ROUTES', db)
 
-    def server_for_route(self, net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
+    def server_for_route(self, net_type, gw, gw_cluster_id, tgt_cluster_id,
+                         lo, hi):
         # only setup connections for tcp NALs
         srvdb = None
         if not net_type in ('tcp', 'toe'):
@@ -1051,11 +1165,11 @@ class RouteTable(Module):
         if lo == hi and local_interface(net_type, gw_cluster_id, gw):
             if not local_cluster(net_type, tgt_cluster_id):
                 panic("target", lo, " not on the local cluster")
-            srvdb = self.db.nid2server(lo, net_type)
+            srvdb = self.db.nid2server(lo, net_type, gw_cluster_id)
         # connect to gateway if this node is not the gw
         elif (local_cluster(net_type, gw_cluster_id)
               and not local_interface(net_type, gw_cluster_id, gw)):
-            srvdb = self.db.nid2server(gw, net_type)
+            srvdb = self.db.nid2server(gw, net_type, gw_cluster_id)
         else:
             return None
 
@@ -1102,16 +1216,16 @@ class RouteTable(Module):
 class Management(Module):
     def __init__(self, db):
         Module.__init__(self, 'MGMT', db)
+        self.add_lustre_module('lvfs', 'lvfs')
         self.add_lustre_module('obdclass', 'obdclass')
         self.add_lustre_module('ptlrpc', 'ptlrpc')
-        self.add_lustre_module('ldlm', 'ldlm')
         self.add_lustre_module('mgmt', 'mgmt_svc')
 
     def prepare(self):
         if is_prepared(self.name):
             return
         self.info()
-        lctl.newdev(attach="mgmt %s %s" % (self.name, self.uuid))
+        lctl.newdev("mgmt", self.name, self.uuid)
 
     def safe_to_clean(self):
         return 1
@@ -1120,31 +1234,26 @@ class Management(Module):
         if is_prepared(self.name):
             Module.cleanup(self)
 
+# This is only needed to load the modules; the LDLM device
+# is now created automatically.
 class LDLM(Module):
     def __init__(self,db):
         Module.__init__(self, 'LDLM', db)
+        self.add_lustre_module('lvfs', 'lvfs')
         self.add_lustre_module('obdclass', 'obdclass')
         self.add_lustre_module('ptlrpc', 'ptlrpc')
-        self.add_lustre_module('ldlm', 'ldlm') 
 
     def prepare(self):
-        if is_prepared(self.name):
-            return
-        self.info()
-        lctl.newdev(attach="ldlm %s %s" % ('ldlm', 'ldlm_UUID'))
-
-    def safe_to_clean(self):
-        out = lctl.device_list()
-        return len(out) <= 1
+        return
 
     def cleanup(self):
-        if is_prepared(self.name):
-            Module.cleanup(self)
+        return
 
 class LOV(Module):
-    def __init__(self, db, uuid, fs_name):
+    def __init__(self, db, uuid, fs_name, name_override = None):
         Module.__init__(self, 'LOV', db)
-        self.add_lustre_module('mdc', 'mdc')
+        if name_override != None:
+            self.name = "lov_%s" % name_override
         self.add_lustre_module('lov', 'lov')
         self.mds_uuid = self.db.get_first_ref('mds')
         mds= self.db.lookup(self.mds_uuid)
@@ -1155,13 +1264,12 @@ class LOV(Module):
         self.devlist = self.db.get_refs('obd')
         self.stripe_cnt = self.db.get_val_int('stripecount', len(self.devlist))
         self.osclist = []
-        self.client_uuid = generate_client_uuid(self.name)
+        self.desc_uuid = self.uuid
+        self.uuid = generate_client_uuid(self.name)
         self.fs_name = fs_name
-        self.mdc_name = ''
-        self.mdc = get_mdc(db, self.client_uuid, fs_name, self.mds_uuid)
         for obd_uuid in self.devlist:
             obd = self.db.lookup(obd_uuid)
-            osc = get_osc(obd, self.client_uuid, fs_name)
+            osc = get_osc(obd, self.uuid, fs_name)
             if osc:
                 self.osclist.append(osc)
             else:
@@ -1178,20 +1286,18 @@ class LOV(Module):
             except CommandError, e:
                 print "Error preparing OSC %s\n" % osc.uuid
                 raise e
-        self.mdc.prepare()
-        self.mdc_name = self.mdc.name
         self.info(self.mds_uuid, self.stripe_cnt, self.stripe_sz,
                   self.stripe_off, self.pattern, self.devlist, self.mds_name)
-        lctl.newdev(attach="lov %s %s" % (self.name, self.uuid),
-                    setup ="%s" % (self.mdc_name))
+        lctl.lov_setup(self.name, self.uuid,
+                       self.desc_uuid, self.mds_name, self.stripe_cnt,
+                       self.stripe_sz, self.stripe_off, self.pattern,
+                       string.join(self.devlist))
 
     def cleanup(self):
         if is_prepared(self.name):
             Module.cleanup(self)
         for osc in self.osclist:
             osc.cleanup()
-        mdc = get_mdc(self.db, self.client_uuid, self.fs_name, self.mds_uuid)
-        mdc.cleanup()
 
     def load_module(self):
         for osc in self.osclist:
@@ -1205,26 +1311,6 @@ class LOV(Module):
             osc.cleanup_module()
             break
 
-class LOVConfig(Module):
-    def __init__(self, db):
-        Module.__init__(self, 'LOVConfig', db)
-
-        self.lov_uuid = self.db.get_first_ref('lov')
-        l = self.db.lookup(self.lov_uuid)
-        self.lov = LOV(l, "YOU_SHOULD_NEVER_SEE_THIS_UUID", '')
-        
-    def prepare(self):
-        lov = self.lov
-        self.info(lov.mds_uuid, lov.stripe_cnt, lov.stripe_sz, lov.stripe_off,
-                  lov.pattern, lov.devlist, lov.mds_name)
-        lctl.lov_setconfig(lov.uuid, lov.mds_name, lov.stripe_cnt,
-			   lov.stripe_sz, lov.stripe_off, lov.pattern,
-			   string.join(lov.devlist))
-
-    def cleanup(self):
-        #nothing to do here
-        pass
-
 class MDSDEV(Module):
     def __init__(self,db):
         Module.__init__(self, 'MDSDEV', db)
@@ -1233,11 +1319,11 @@ class MDSDEV(Module):
         self.journal_size = self.db.get_val_int('journalsize', 0)
         self.fstype = self.db.get_val('fstype', '')
         self.nspath = self.db.get_val('nspath', '')
+	self.mkfsoptions = self.db.get_val('mkfsoptions', '')
         # overwrite the orignal MDSDEV name and uuid with the MDS name and uuid
         target_uuid = self.db.get_first_ref('target')
         mds = self.db.lookup(target_uuid)
         self.name = mds.getName()
-        self.lovconfig_uuids = mds.get_refs('lovconfig')
         self.filesystem_uuids = mds.get_refs('filesystem')
         # FIXME: if fstype not set, then determine based on kernel version
         self.format = self.db.get_val('autoformat', "no")
@@ -1258,9 +1344,13 @@ class MDSDEV(Module):
         self.target_dev_uuid = self.uuid
         self.uuid = target_uuid
         # modules
+        self.add_lustre_module('mdc', 'mdc')
+        self.add_lustre_module('osc', 'osc')
+        self.add_lustre_module('lov', 'lov')
         self.add_lustre_module('mds', 'mds')
         if self.fstype:
-            self.add_lustre_module('obdclass', 'fsfilt_%s' % (self.fstype))
+            self.add_lustre_module('lvfs', 'fsfilt_%s' % (self.fstype))
+            
 
     def load_module(self):
         if self.active:
@@ -1272,31 +1362,104 @@ class MDSDEV(Module):
         if not self.active:
             debug(self.uuid, "not active")
             return
-        self.info(self.devpath, self.fstype, self.format)
+        if config.reformat:
+            # run write_conf automatically, if --reformat used
+            self.write_conf()
+        self.info(self.devpath, self.fstype, self.size, self.format)
         run_acceptors()
-        blkdev = block_dev(self.devpath, self.size, self.fstype, self.format,
-                           self.journal_size)
+        # never reformat here
+        blkdev = block_dev(self.devpath, self.size, self.fstype, 0,
+                           self.format, self.journal_size, self.mkfsoptions)
         if not is_prepared('MDT'):
-            lctl.newdev(attach="mdt %s %s" % ('MDT', 'MDT_UUID'),
-                        setup ="")
-        if self.nspath:
-            run ("mkdir", self.nspath)
-        lctl.newdev(attach="mds %s %s" % (self.name, self.uuid),
-                    setup ="%s %s %s" %(blkdev, self.fstype, self.nspath))
-        for uuid in self.lovconfig_uuids:
-            db = self.db.lookup(uuid)
-            lovconfig = LOVConfig(db)
-            lovconfig.prepare()
-        if config.mds_ost_conn:
-            for uuid in self.filesystem_uuids:
-                log("open clients for filesystem:", uuid)
-                fs = self.db.lookup(uuid)
-                obd_uuid = fs.get_first_ref('obd')
-                client_uuid = generate_client_uuid(self.name)
-                client = VOSC(client_uuid, self.db.lookup(obd_uuid), self.name)
-                client.prepare()
+            lctl.newdev("mdt", 'MDT', 'MDT_UUID', setup ="")
+        try: 
+            lctl.newdev("mds", self.name, self.uuid,
+                        setup ="%s %s %s" %(blkdev, self.fstype, self.name))
+        except CommandError, e:
+            if e.rc == 2:
+                panic("MDS is missing the config log. Need to run " +
+                       "lconf --write_conf.")
+            else:
+                raise e
+
+    def write_conf(self):
+        if is_prepared(self.name):
+            return
+        self.info(self.devpath, self.fstype, self.format)
+        blkdev = block_dev(self.devpath, self.size, self.fstype,
+                           config.reformat, self.format, self.journal_size,
+                           self.mkfsoptions)
+        lctl.newdev("mds", self.name, self.uuid,
+                    setup ="%s %s" %(blkdev, self.fstype))
                 
-            
+        # record logs for the MDS lov
+        for uuid in self.filesystem_uuids:
+            log("recording clients for filesystem:", uuid)
+            fs = self.db.lookup(uuid)
+            obd_uuid = fs.get_first_ref('obd')
+            client_uuid = generate_client_uuid(self.name)
+            client = VOSC(self.db.lookup(obd_uuid), client_uuid, self.name,
+                          self.name)
+            config.record = 1
+            lctl.record(self.name, self.name)
+            client.prepare()
+            lctl.mount_option(self.name, client.get_name(), "")
+            lctl.end_record()
+
+            config.cleanup = 1
+            lctl.record(self.name, self.name + '-clean')
+            client.cleanup()
+            lctl.del_mount_option(self.name)
+            lctl.end_record()
+            config.cleanup = 0
+            config.record = 0
+
+        # record logs for each client
+        if config.ldapurl:
+            config_options = "--ldapurl " + config.ldapurl + " --config " + config.config
+        else:
+            config_options = CONFIG_FILE
+
+        for node_db in self.db.lookup_class('node'):
+            client_name = node_db.getName()
+            for prof_uuid in node_db.get_refs('profile'):
+                prof_db = node_db.lookup(prof_uuid)
+                # refactor this into a funtion to test "clientness"
+                # of a node.
+                for ref_class, ref_uuid in prof_db.get_all_refs():
+                    if ref_class in ('mountpoint','echoclient'):
+                        debug("recording", client_name)
+                        old_noexec = config.noexec
+                        config.noexec = 0
+                        noexec_opt = ('', '-n')
+                        ret, out = run (sys.argv[0],
+                                        noexec_opt[old_noexec == 1],
+                                        " -v --record --nomod",
+                                        "--record_log", client_name,
+                                        "--record_device", self.name,
+                                        "--node", client_name,
+                                        config_options)
+                        if config.verbose:
+                            for s in out: log("record> ", string.strip(s))
+                        ret, out = run (sys.argv[0],
+                                        noexec_opt[old_noexec == 1],
+                                        "--cleanup -v --record --nomod",
+                                        "--record_log", client_name + "-clean",
+                                        "--record_device", self.name,
+                                        "--node", client_name,
+                                        config_options)
+                        if config.verbose:
+                            for s in out: log("record> ", string.strip(s))
+                        config.noexec = old_noexec
+        try:
+            lctl.cleanup(self.name, self.uuid, 0, 0)
+        except CommandError, e:
+            log(self.module_name, "cleanup failed: ", self.name)
+            e.dump()
+            cleanup_error(e.rc)
+            Module.cleanup(self)
+        clean_loop(self.devpath)
+ 
     def msd_remaining(self):
         out = lctl.device_list()
         for s in out:
@@ -1313,8 +1476,8 @@ class MDSDEV(Module):
         if not self.active:
             debug(self.uuid, "not active")
             return
+        self.info()
         if is_prepared(self.name):
-            self.info()
             try:
                 lctl.cleanup(self.name, self.uuid, config.force,
                              config.failover)
@@ -1323,14 +1486,6 @@ class MDSDEV(Module):
                 e.dump()
                 cleanup_error(e.rc)
                 Module.cleanup(self)
-        if config.mds_ost_conn:
-            for uuid in self.filesystem_uuids:
-                log("clean clients for filesystem:", uuid)
-                log("open clients for filesystem:", uuid)
-                fs = self.db.lookup(uuid)
-                obd_uuid = fs.get_first_ref('obd')
-                client = VOSC(self.db.lookup(obd_uuid), self.name)
-                client.cleanup()
         if not self.msd_remaining() and is_prepared('MDT'):
             try:
                 lctl.cleanup("MDT", "MDT_UUID", config.force,
@@ -1348,6 +1503,7 @@ class OSD(Module):
         self.devpath = self.db.get_val('devpath', '')
         self.size = self.db.get_val_int('devsize', 0)
         self.journal_size = self.db.get_val_int('journalsize', 0)
+        self.mkfsoptions = self.db.get_val_int('mkfsoptions', '')
         self.fstype = self.db.get_val('fstype', '')
         self.nspath = self.db.get_val('nspath', '')
         target_uuid = self.db.get_first_ref('target')
@@ -1375,7 +1531,7 @@ class OSD(Module):
         self.add_lustre_module('ost', 'ost')
 	# FIXME: should we default to ext3 here?
         if self.fstype:
-            self.add_lustre_module('obdclass' , 'fsfilt_%s' % (self.fstype))
+            self.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.fstype))
         self.add_lustre_module(self.osdtype, self.osdtype)
 
     def load_module(self):
@@ -1398,15 +1554,13 @@ class OSD(Module):
             blkdev = ''
         else:
             blkdev = block_dev(self.devpath, self.size, self.fstype,
-                               self.format, self.journal_size)
-        if self.nspath:
-            run ("mkdir", self.nspath)
-        lctl.newdev(attach="%s %s %s" % (self.osdtype, self.name, self.uuid),
-                    setup ="%s %s %s %s" %(blkdev, self.fstype,
-                                           self.failover_ost, self.nspath))
+                               config.reformat, self.format, self.journal_size,
+                               self.mkfsoptions)
+        lctl.newdev(self.osdtype, self.name, self.uuid,
+                    setup ="%s %s %s" %(blkdev, self.fstype,
+                                           self.failover_ost))
         if not is_prepared('OSS'):
-            lctl.newdev(attach="ost %s %s" % ('OSS', 'OSS_UUID'),
-                        setup ="")
+            lctl.newdev("ost", 'OSS', 'OSS_UUID', setup ="")
 
     def osd_remaining(self):
         out = lctl.device_list()
@@ -1466,7 +1620,7 @@ class Client(Module):
         if not self.tgt_dev_uuid:
             panic("No target device found for target:", self.target_name)
             
-        self.kmodule_list = []
+        self.kmod = kmod(config.lustre, config.portals)
         self._server = None
         self._connected = 0
 
@@ -1507,18 +1661,24 @@ class Client(Module):
             if srv:
                 lctl.connect(srv)
             else:
-                srv, r =  find_route(self.get_servers())
-                if srv:
-                    lctl.add_route_host(r[0], srv.uuid, r[1], r[3])
-                else:
+                routes = find_route(self.get_servers())
+                if len(routes) == 0:
                     panic ("no route to",  self.target_uuid)
+                for (srv, r) in routes:
+                    lctl.add_route_host(r[0], srv.nid_uuid, r[1], r[3])
         except CommandError, e:
             if not ignore_connect_failure:
                 raise e
         if srv:
-            lctl.newdev(attach="%s %s %s" % (self.module, self.name, self.uuid),
-                        setup ="%s %s %s" % (self.target_uuid, srv.uuid,
-                                             self.mgmt_name))
+            if self.target_uuid in config.inactive and self.permits_inactive():
+                debug("%s inactive" % self.target_uuid)
+                inactive_p = "inactive"
+            else:
+                debug("%s active" % self.target_uuid)
+                inactive_p = ""
+            lctl.newdev(self.module, self.name, self.uuid,
+                        setup ="%s %s %s %s" % (self.target_uuid, srv.nid_uuid,
+                                                inactive_p, self.mgmt_name))
 
     def cleanup(self):
         if is_prepared(self.name):
@@ -1528,9 +1688,8 @@ class Client(Module):
                 if srv:
                     lctl.disconnect(srv)
                 else:
-                    srv, r =  find_route(self.get_servers())
-                    if srv:
-                        lctl.del_route_host(r[0], srv.uuid, r[1], r[3])
+                    for (srv, r) in find_route(self.get_servers()):
+                        lctl.del_route_host(r[0], srv.nid_uuid, r[1], r[3])
             except CommandError, e:
                 log(self.module_name, "cleanup failed: ", self.name)
                 e.dump()
@@ -1541,11 +1700,16 @@ class MDC(Client):
     def __init__(self, db, uuid, fs_name):
          Client.__init__(self, db, uuid, 'mdc', fs_name)
 
+    def permits_inactive(self):
+    	return 0
 
 class OSC(Client):
     def __init__(self, db, uuid, fs_name):
          Client.__init__(self, db, uuid, 'osc', fs_name)
 
+    def permits_inactive(self):
+    	return 1
+
 def mgmtcli_name_for_uuid(uuid):
     return 'MGMTCLI_%s' % uuid
 
@@ -1569,16 +1733,16 @@ class COBD(Module):
         if is_prepared(self.name):
             return
         self.info(self.real_uuid, self.cache_uuid)
-        lctl.newdev(attach="cobd %s %s" % (self.name, self.uuid),
+        lctl.newdev("cobd", self.name, self.uuid,
                     setup ="%s %s" %(self.real_uuid, self.cache_uuid))
 
 
 # virtual interface for  OSC and LOV
 class VOSC(Module):
-    def __init__(self, db, uuid, fs_name):
+    def __init__(self, db, uuid, fs_name, name_override = None):
         Module.__init__(self, 'VOSC', db)
         if db.get_class() == 'lov':
-            self.osc = LOV(db, uuid, fs_name)
+            self.osc = LOV(db, uuid, fs_name, name_override)
         else:
             self.osc = get_osc(db, uuid, fs_name)
     def get_uuid(self):
@@ -1593,12 +1757,6 @@ class VOSC(Module):
         self.osc.load_module()
     def cleanup_module(self):
         self.osc.cleanup_module()
-    def need_mdc(self):
-        return self.db.get_class() != 'lov'
-    def get_mdc_name(self):
-        if self.db.get_class() == 'lov':
-            return self.osc.mdc_name
-        return ''
 
 
 class ECHO_CLIENT(Module):
@@ -1617,7 +1775,7 @@ class ECHO_CLIENT(Module):
         self.osc.prepare() # XXX This is so cheating. -p
         self.info(self.obd_uuid)
 
-        lctl.newdev(attach="echo_client %s %s" % (self.name, self.uuid),
+        lctl.newdev("echo_client", self.name, self.uuid,
                     setup = self.osc.get_name())
 
     def cleanup(self):
@@ -1654,9 +1812,9 @@ class Mountpoint(Module):
         obd = self.db.lookup(self.obd_uuid)
         client_uuid = generate_client_uuid(self.name)
         self.vosc = VOSC(obd, client_uuid, self.name)
-        if self.vosc.need_mdc():
-            self.add_lustre_module('mdc', 'mdc')
-            self.mdc = get_mdc(db, client_uuid, self.name, self.mds_uuid)
+        self.mdc = get_mdc(db, client_uuid, self.name, self.mds_uuid)
+
+        self.add_lustre_module('mdc', 'mdc')
         self.add_lustre_module('llite', 'llite')
         if self.mgmt_uuid:
             self.mgmtcli = ManagementClient(db.lookup(self.mgmt_uuid),
@@ -1672,45 +1830,41 @@ class Mountpoint(Module):
         if self.mgmtcli:
             self.mgmtcli.prepare()
         self.vosc.prepare()
-        if self.vosc.need_mdc():
-            self.mdc.prepare()
-            mdc_name = self.mdc.name
-        else:
-            mdc_name = self.vosc.get_mdc_name()
-        if not mdc_name:
-            self.vosc.cleanup()
-            panic("Unable to determine MDC name. Probably need to cleanup before re-mounting.")
+        self.mdc.prepare()
+        mdc_name = self.mdc.name
+
         self.info(self.path, self.mds_uuid, self.obd_uuid)
-        if config.lctl_dump:
-            cmd = "osc=%s,mdc=%s" % (self.vosc.get_name(), mdc_name)
-            lctl.mount_option(cmd)
+        if config.record or config.lctl_dump:
+            lctl.mount_option(local_node_name, self.vosc.get_name(), mdc_name)
             return
         cmd = "mount -t lustre_lite -o osc=%s,mdc=%s %s %s" % \
               (self.vosc.get_name(), mdc_name, config.config, self.path)
         run("mkdir", self.path)
         ret, val = run(cmd)
         if ret:
+            self.mdc.cleanup()            
             self.vosc.cleanup()
-            if self.vosc.need_mdc():
-                self.mdc.cleanup()
             panic("mount failed:", self.path, ":", string.join(val))
 
     def cleanup(self):
         self.info(self.path, self.mds_uuid,self.obd_uuid)
-        if fs_is_mounted(self.path):
-            if config.force:
-                (rc, out) = run("umount", "-f", self.path)
-            else:
-                (rc, out) = run("umount", self.path)
-            if rc:
-                raise CommandError('umount', out, rc)
 
-        if fs_is_mounted(self.path):
-            panic("fs is still mounted:", self.path)
+        if config.record or config.lctl_dump:
+            lctl.del_mount_option(local_node_name)
+        else:
+            if fs_is_mounted(self.path):
+                if config.force:
+                    (rc, out) = run("umount", "-f", self.path)
+                else:
+                    (rc, out) = run("umount", self.path)
+                if rc:
+                    raise CommandError('umount', out, rc)
 
+            if fs_is_mounted(self.path):
+                panic("fs is still mounted:", self.path)
+
+        self.mdc.cleanup()
         self.vosc.cleanup()
-        if self.vosc.need_mdc():
-            self.mdc.cleanup()
         if self.mgmtcli:
             self.mgmtcli.cleanup()
 
@@ -1824,8 +1978,7 @@ def find_local_clusters(node_db):
                 panic("duplicate port:", srv.port)
             acceptors[srv.port] = AcceptorHandler(srv.port, srv.net_type,
                                                   srv.send_mem, srv.recv_mem,
-                                                  srv.irq_affinity,
-                                                  srv.nid_exchange)
+                                                  srv.irq_affinity)
 
 # This node is a gateway.
 is_router = 0
@@ -1888,6 +2041,7 @@ def local_interface(net_type, cluster_id, nid):
     return 0
 
 def find_route(srv_list):
+    result = []
     frm_type = local_clusters[0][0]
     for srv in srv_list:
         debug("find_route: srv:", srv.nid, "type: ", srv.net_type)
@@ -1898,8 +2052,8 @@ def find_route(srv_list):
         for r in local_routes:
             debug("find_route: ", r)
             if  (r[3] <= to and to <= r[4]) and cluster_id == r[2]:
-                return srv, r
-    return None,None
+                result.append((srv, r))
+    return result
            
 def get_active_target(db):
     target_uuid = db.getUUID()
@@ -1911,6 +2065,12 @@ def get_active_target(db):
         tgt_dev_uuid = db.get_first_ref('active')
     return tgt_dev_uuid
 
+def get_server_by_nid_uuid(db,  nid_uuid):
+    for n in db.lookup_class("network"):
+        net = Network(n)
+        if net.nid_uuid == nid_uuid:
+            return net
+        
 
 ############################################################
 # lconf level logic
@@ -1994,7 +2154,7 @@ def doUnloadModules(services):
 #
 # Load profile for 
 def doHost(lustreDB, hosts):
-    global is_router 
+    global is_router, local_node_name
     node_db = None
     for h in hosts:
         node_db = lustreDB.lookup_name(h, 'node')
@@ -2004,11 +2164,12 @@ def doHost(lustreDB, hosts):
         print 'No host entry found.'
         return
 
+    local_node_name = node_db.get_val('name', 0)
     is_router = node_db.get_val_int('router', 0)
     lustre_upcall = node_db.get_val('lustreUpcall', '')
     portals_upcall = node_db.get_val('portalsUpcall', '')
     timeout = node_db.get_val_int('timeout', 0)
-
+    
     find_local_clusters(node_db)
     if not is_router:
         find_local_routes(lustreDB)
@@ -2017,7 +2178,15 @@ def doHost(lustreDB, hosts):
     # if not cleaning, load modules first.
     prof_list = node_db.get_refs('profile')
 
-    if config.recover:
+    if config.write_conf:
+        for_each_profile(node_db, prof_list, doModules)
+        sys_make_devices()
+        for node_db in lustreDB.lookup_class('mdsdev'):
+            mds = MDSDEV(node_db)
+            mds.write_conf()
+        for_each_profile(node_db, prof_list, doUnloadModules)
+
+    elif config.recover:
         if not (config.tgt_uuid and config.client_uuid and config.conn_uuid):
             raise Lustre.LconfError( "--recovery requires --tgt_uuid <UUID> " +
                                      "--client_uuid <UUID> --conn_uuid <UUID>")
@@ -2028,7 +2197,7 @@ def doHost(lustreDB, hosts):
             # the command line can override this value
             timeout = 5
         # ugly hack, only need to run lctl commands for --dump
-        if config.lctl_dump:
+        if config.lctl_dump or config.record:
             for_each_profile(node_db, prof_list, doCleanup)
             return
 
@@ -2043,7 +2212,9 @@ def doHost(lustreDB, hosts):
 
     else:
         # ugly hack, only need to run lctl commands for --dump
-        if config.lctl_dump:
+        if config.lctl_dump or config.record:
+            sys_set_timeout(timeout)
+            sys_set_lustre_upcall(lustre_upcall)
             for_each_profile(node_db, prof_list, doSetup)
             return
 
@@ -2069,7 +2240,7 @@ def doHost(lustreDB, hosts):
 
         for_each_profile(node_db, prof_list, doSetup)
 
-def doRecovery(db, lctl, tgt_uuid, client_uuid, conn_uuid):
+def doRecovery(db, lctl, tgt_uuid, client_uuid, nid_uuid):
     tgt = db.lookup(tgt_uuid)
     if not tgt:
         raise Lustre.LconfError("doRecovery: "+ tgt_uuid +" not found.")
@@ -2080,11 +2251,23 @@ def doRecovery(db, lctl, tgt_uuid, client_uuid, conn_uuid):
     net = choose_local_server(get_ost_net(db, new_uuid))
     if not net:
         raise Lustre.LconfError("Unable to find a connection to:" + new_uuid)
-    # XXX, better to do a full disconnect here
-    log("Reconnecting", tgt_uuid, " to ",  net.uuid);
-    lctl.del_uuid(conn_uuid)
-    lctl.connect(net)
-    lctl.recover(client_uuid, net.uuid)
+
+    log("Reconnecting", tgt_uuid, " to ",  net.nid_uuid);
+    try:
+        oldnet = get_server_by_nid_uuid(db, nid_uuid)
+        if oldnet:
+            lctl.disconnect(oldnet)
+    except CommandError, e:
+        log("recover: disconnect", nid_uuid, "failed: ")
+        e.dump()
+
+    try:
+        lctl.connect(net)
+    except CommandError, e:
+        log("recover: connect failed")
+        e.dump()
+
+    lctl.recover(client_uuid, net.nid_uuid)
 
 
 def setupModulePath(cmd, portals_dir = PORTALS_DIR):
@@ -2127,7 +2310,7 @@ def sys_set_lustre_upcall(upcall):
     elif config.upcall:
         upcall = config.upcall
     if upcall:
-        sysctl('lustre/upcall', upcall)
+        lctl.set_lustre_upcall(upcall)
 
 def sys_set_portals_upcall(upcall):
     # the command overrides the value in the node config
@@ -2140,10 +2323,17 @@ def sys_set_portals_upcall(upcall):
 
 def sys_set_timeout(timeout):
     # the command overrides the value in the node config
-    if config.timeout > 0:
+    if config.timeout and config.timeout > 0:
         timeout = config.timeout
     if timeout != None and timeout > 0:
-        sysctl('lustre/timeout', timeout)
+        lctl.set_timeout(timeout)
+
+def sys_tweak_socknal ():
+    if config.single_socket:
+        sysctl("socknal/typed", 0)
+
+def sys_optimize_elan ():
+        run ("echo 0 > /proc/elan/config/eventint_punt_loops")
 
 def sys_set_ptldebug():
     if config.ptldebug != None:
@@ -2169,7 +2359,7 @@ def sys_set_netmem_max(path, max):
         return
     fp = open(path)
     str = fp.readline()
-    fp.close
+    fp.close()
     cur = int(str)
     if max > cur:
         fp = open(path, 'w')
@@ -2214,10 +2404,10 @@ def sanitise_path():
 
 # global hack for the --select handling
 tgt_select = {}
-def init_select(arg):
-    # arg = "service=nodeA,service2=nodeB"
+def init_select(args):
+    # args = [service=nodeA,service2=nodeB service3=nodeC]
     global tgt_select
-    if arg:
+    for arg in args:
         list = string.split(arg, ',')
         for entry in list:
             srv, node = string.split(entry, '=')
@@ -2229,23 +2419,26 @@ def get_select(srv):
     return None
 
 
+FLAG = Lustre.Options.FLAG
 PARAM = Lustre.Options.PARAM
 INTPARAM = Lustre.Options.INTPARAM
+PARAMLIST = Lustre.Options.PARAMLIST
 lconf_options = [
     ('verbose,v', "Print system commands as they are run"),
     ('ldapurl',"LDAP server URL, eg. ldap://localhost", PARAM),
     ('config', "Cluster config name used for LDAP query", PARAM),
-    ('select', "service=nodeA,service2=nodeB ", PARAM),
+    ('select', "service=nodeA,service2=nodeB ", PARAMLIST),
     ('node',   "Load config for <nodename>", PARAM),
     ('cleanup,d', "Cleans up config. (Shutdown)"),
     ('force,f', "Forced unmounting and/or obd detach during cleanup",
-               Lustre.Options.FLAG, 0),
-    ('mds_ost_conn', "Open connections to OSTs on the MDS"),
+               FLAG, 0),
+    ('single_socket', "socknal option: only use one socket instead of bundle",
+               FLAG, 0),
     ('failover',"""Used to shut down without saving state.
                    This will allow this node to "give up" a service to a
                    another node for failover purposes. This will not
                    be a clean shutdown.""",
-               Lustre.Options.FLAG, 0),
+               FLAG, 0),
     ('gdb', """Prints message after creating gdb module script
                     and sleeps for 5 seconds."""),
     ('noexec,n', """Prints the commands and steps that will be run for a
@@ -2254,13 +2447,19 @@ lconf_options = [
     ('nomod', "Skip load/unload module step."),
     ('nosetup', "Skip device setup/cleanup step."),
     ('reformat', "Reformat all devices (without question)"),
+    ('mkfsoptions', "Additional options for the mk*fs command line", PARAM),
     ('dump',  "Dump the kernel debug log to file before portals is unloaded",
                PARAM),
+    ('write_conf', "Save all the client config information on mds."),
+    ('record', "Write config information on mds."),
+    ('record_log', "Name of config record log.", PARAM),
+    ('record_device', "MDS device name that will record the config commands",
+              PARAM),
     ('minlevel', "Minimum level of services to configure/cleanup",
                  INTPARAM, 0),
     ('maxlevel', """Maximum level of services to configure/cleanup 
                     Levels are aproximatly like:
-                            10 - network
+                            10 - netwrk
                             20 - device, ldlm
                             30 - osd, mdd
                             40 - mds, ost
@@ -2270,7 +2469,7 @@ lconf_options = [
                   cause lconf to load modules from a source tree.""", PARAM),
     ('portals', """Portals source directory.  If this is a relative path,
                    then it is assumed to be relative to lustre. """, PARAM),
-    ('timeout', "Set recovery timeout", PARAM),
+    ('timeout', "Set recovery timeout", INTPARAM),
     ('upcall',  "Set both portals and lustre upcall script", PARAM),
     ('lustre_upcall', "Set lustre upcall script", PARAM),
     ('portals_upcall', "Set portals upcall script", PARAM),
@@ -2285,10 +2484,14 @@ lconf_options = [
     ('tgt_uuid', "The failed target (required for recovery)", PARAM),
     ('client_uuid', "The failed client (required for recovery)", PARAM),
     ('conn_uuid', "The failed connection (required for recovery)", PARAM),
+
+    ('inactive', """The name of an inactive service, to be ignored during
+                    mounting (currently OST-only). Can be repeated.""",
+                PARAMLIST),
     ]      
 
 def main():
-    global lctl, config, toplevel
+    global lctl, config, toplevel, CONFIG_FILE
 
     # in the upcall this is set to SIG_IGN
     signal.signal(signal.SIGCHLD, signal.SIG_DFL)
@@ -2327,6 +2530,7 @@ def main():
         except Exception:
             panic("%s does not appear to be a config file." % (args[0]))
             sys.exit(1) # make sure to die here, even in debug mode.
+        CONFIG_FILE = args[0]
         db = Lustre.LustreDB_XML(dom.documentElement, dom.documentElement)
         if not config.config:
             config.config = os.path.basename(args[0])# use full path?
@@ -2370,8 +2574,16 @@ def main():
     if config.lctl_dump:
         lctl.use_save_file(config.lctl_dump)
 
+    if config.record:
+        if not (config.record_device and config.record_log):
+            panic("When recording, both --record_log and --record_device must be specified.")
+        lctl.record(config.record_device, config.record_log)
+
     doHost(db, node_list)
 
+    if config.record:
+        lctl.end_record()
+
 if __name__ == "__main__":
     try:
         main()
diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c
index 322ad63435829e8dcadb6efb52341cec7f32eab0..0e8c3a78349d2d378d2bcb86d67dc08789881881 100644
--- a/lustre/utils/lctl.c
+++ b/lustre/utils/lctl.c
@@ -24,6 +24,7 @@
  */
 
 
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <portals/api-support.h>
@@ -70,13 +71,13 @@ command_t cmdlist[] = {
         {"autoconn_list", jt_ptl_print_autoconnects, 0, "print autoconnect entries\n"
          "usage: print_autoconns"},
         {"add_autoconn", jt_ptl_add_autoconnect, 0, "add an autoconnect entry\n"
-         "usage: add_autoconn <nid> <host> <port> [ixse]"},
+         "usage: add_autoconn <nid> <host> <port> [ise]"},
         {"del_autoconn", jt_ptl_del_autoconnect, 0, "remove an autoconnect entry\n"
          "usage: del_autoconn [<nid>] [<host>] [ks]"},
         {"conn_list", jt_ptl_print_connections, 0, "connect to a remote nid\n"
          "usage: print_conns"},
         {"connect", jt_ptl_connect, 0, "connect to a remote nid\n"
-         "usage: connect <host> <port> [ix]"},
+         "usage: connect <host> <port> [iIOC]"},
         {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid\n"
          "usage: disconnect [<nid>]"},
         {"active_tx", jt_ptl_print_active_txs, 0, "print active transmits (no args)\n"
@@ -87,11 +88,11 @@ command_t cmdlist[] = {
          "usage: mynid [<nid>]"},
         {"shownid", jt_ptl_shownid, 0, "print the local NID\n"
          "usage: shownid"},
-        {"add_uuid", jt_obd_add_uuid, 0, "associate a UUID with a nid\n"
+        {"add_uuid", jt_lcfg_add_uuid, 0, "associate a UUID with a nid\n"
          "usage: add_uuid <uuid> <nid> <net_type>"},
         {"close_uuid", jt_obd_close_uuid, 0, "disconnect a UUID\n"
          "usage: close_uuid <uuid> <net-type>)"},
-        {"del_uuid", jt_obd_del_uuid, 0, "delete a UUID association\n"
+        {"del_uuid", jt_lcfg_del_uuid, 0, "delete a UUID association\n"
          "usage: del_uuid <uuid>"},
         {"add_route", jt_ptl_add_route, 0,
          "add an entry to the portals routing table\n"
@@ -120,23 +121,28 @@ command_t cmdlist[] = {
 
         /* Device selection commands */
         {"=== device selection ===", jt_noop, 0, "device selection"},
-        {"newdev", jt_obd_newdev, 0, "create a new device\n"
+        {"newdev", jt_lcfg_newdev, 0, "create a new device\n"
          "usage: newdev"},
         {"device", jt_obd_device, 0,
          "set current device to <%name|$name|devno>\n"
          "usage: device <%name|$name|devno>"},
+        {"cfg_device", jt_lcfg_device, 0,
+         "set current device being configured to <$name>\n"
+         "usage: device <name>"},
         {"device_list", jt_obd_list, 0, "show all devices\n"
          "usage: device_list"},
+        {"dl", jt_obd_list, 0, "show all devices\n"
+         "usage: dl"},
         {"lustre_build_version", jt_get_version, 0,
          "print the build version of lustre\n"
          "usage: lustre_build_version"},
 
         /* Device configuration commands */
         {"==== device config =====", jt_noop, 0, "device config"},
-        {"attach", jt_obd_attach, 0,
+        {"attach", jt_lcfg_attach, 0,
          "set the type of the current device (with <name> and <uuid>)\n"
          "usage: attach type [name [uuid]]"},
-        {"setup", jt_obd_setup, 0,
+        {"setup", jt_lcfg_setup, 0,
          "type specific device configuration information\n"
          "usage: setup <args...>"},
         {"cleanup", jt_obd_cleanup, 0, "cleanup previously setup device\n"
@@ -144,12 +150,20 @@ command_t cmdlist[] = {
         {"detach", jt_obd_detach, 0,
          "remove driver (and name and uuid) from current device\n"
          "usage: detach"},
-        {"lov_setconfig", jt_obd_lov_setconfig, 0,
-         "write lov configuration to an mds device\n"
+        {"lov_setup", jt_lcfg_lov_setup, 0,
+         "write setup an lov device\n"
          "usage: lov_setconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"},
         {"lov_getconfig", jt_obd_lov_getconfig, 0,
          "read lov configuration from an mds device\n"
          "usage: lov_getconfig lov-uuid"},
+        {"record", jt_cfg_record, 0, "record commands that follow in log\n"
+         "usage: record cfg-uuid-name"},
+        {"endrecord", jt_cfg_endrecord, 0, "stop recording\n"
+         "usage: endrecord"},
+        {"parse", jt_cfg_parse, 0, "parse the log of recorded commands for this config\n"
+         "usage: parse config-uuid-name"},
+        {"dump_log", jt_cfg_dump_log, 0, "print log of recorded commands for this config to kernel debug log\n"
+         "usage: dump_log config-uuid-name"},
 
         /* Device operations */
         {"=== device operations ==", jt_noop, 0, "device operations"},
@@ -209,8 +223,34 @@ command_t cmdlist[] = {
          "disable writes to the underlying device\n"},
         {"abort_recovery", jt_obd_abort_recovery, 0,
          "abort recovery on MDS device\n"},
-        {"mount_option", jt_obd_mount_option, 0,
-         "dump mount options to file\n"},
+        {"mount_option", jt_lcfg_mount_option, 0, 
+         "usage: mount_option profile osc_name [mdc_name] \n"},
+        {"del_mount_option", jt_lcfg_del_mount_option, 0,
+         "usage: del_mount_option profile\n"},
+        {"set_timeout", jt_lcfg_set_timeout, 0,
+         "usage: set_timeout <secs>\n"},
+        {"set_lustre_upcall", jt_lcfg_set_lustre_upcall, 0,
+         "usage: set_lustre_upcall </full/path/to/upcall> \n"},
+       
+        /* Llog operations */ 
+        {"llog_catlist", jt_llog_catlist, 0, 
+         "list all catalog logs on current device.\n"
+         "usage: llog_catlist"},
+        {"llog_info", jt_llog_info, 0,
+         "print log header information.\n"
+         "usage: llog_info <$logname|#oid#ogr#ogen>\n"
+         "       oid, ogr and ogen are hexadecimal."},
+        {"llog_print", jt_llog_print, 0,
+         "print log content information.\n"
+         "usage: llog_print <$logname|#oid#ogr#ogen> [from] [to]\n"
+         "       oid, ogr and ogen are hexadecimal.\n"
+         "       print all records from index 1 by default."},
+        {"llog_cancel", jt_llog_cancel, 0,
+         "cancel one record in log.\n"
+         "usage: llog_cancel <catlog id|catlog name> <log id> <index>"},
+        {"llog_remove", jt_llog_remove, 0,
+         "remove one log from catlog, erase it from disk.\n"
+         "usage: llog_remove <catlog id|catlog name> <log id>"},
 
         /* Debug commands */
         {"======== debug =========", jt_noop, 0, "debug"},
@@ -254,9 +294,7 @@ command_t cmdlist[] = {
         { 0, 0, 0, NULL }
 };
 
-
-
-int main(int argc, char **argv)
+int lctl_main(int argc, char **argv)
 {
         int rc;
 
@@ -276,7 +314,13 @@ int main(int argc, char **argv)
                 rc = Parser_commands();
         }
 
-        obd_cleanup(argc, argv);
+        obd_finalize(argc, argv);
         return rc;
 }
 
+#if !LIBLUSTRE_TEST
+int main (int argc, char **argv)
+{
+        return (lctl_main (argc, argv));
+}
+#endif
diff --git a/lustre/utils/lfind b/lustre/utils/lfind
new file mode 100755
index 0000000000000000000000000000000000000000..ae620175c6468aa2444298dffc04f12c5481600c
--- /dev/null
+++ b/lustre/utils/lfind
@@ -0,0 +1,3 @@
+#!/bin/bash
+PATH=`dirname $0`:$PATH
+lfs find "$@"
diff --git a/lustre/utils/lfind.c b/lustre/utils/lfind.c
deleted file mode 100644
index 45f837c0ff6c4ccf145efde25ca9bd3a778e98d8..0000000000000000000000000000000000000000
--- a/lustre/utils/lfind.c
+++ /dev/null
@@ -1,302 +0,0 @@
-#include <stdio.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <libgen.h>
-#include <ftw.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-
-
-#include <liblustre.h>
-#include <linux/obd.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_lite.h>
-#include <linux/obd_lov.h>
-
-/* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
-#define MAX_LOV_UUID_COUNT	1000
-#define OBD_NOT_FOUND		(-1)
-
-char		*cmd;
-struct option	 longOpts[] = {
-			{"help", 0, 0, 'h'},
-			{"obd", 1, 0, 'o'},
-			{"query", 0, 0, 'q'},
-			{"verbose", 0, 0, 'v'},
-			{0, 0, 0, 0}
-		 };
-int		 query;
-int		 verbose;
-char		 shortOpts[] = "ho:qv";
-char		 usageMsg[] = "[ --obd <obd uuid> | --query ] <dir|file> ...";
-
-int		 max_ost_count = MAX_LOV_UUID_COUNT;
-struct obd_uuid *obduuid;
-char		*buf;
-int		 buflen;
-struct obd_uuid *uuids;
-struct obd_ioctl_data data;
-struct lov_desc  desc;
-int		 uuidslen;
-int		 cfglen;
-struct lov_mds_md *lmm;
-int		 lmmlen;
-int		 printed_UUIDs;
-
-void	init();
-void	usage(FILE *stream);
-void	errMsg(char *fmt, ...);
-void	processPath(char *path);
-
-int main (int argc, char **argv) {
-	int c;
-
-	cmd = basename(argv[0]);
-
-	while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) {
-		switch (c) {
-		case 'o':
-			if (obduuid) {
-				printf("obd '%s' already specified: '%s'\n",
-					obduuid->uuid, optarg);
-				exit(1);
-			}
-
-			obduuid = (struct obd_uuid *)optarg;
-			break;
-		case 'h':
-			usage(stdout);
-			exit(0);
-		case 'q':
-			query++;
-			break;
-		case 'v':
-			verbose++;
-			break;
-		case '?':
-			usage(stderr);
-			exit(1);
-		default:
-			printf("Internal error. Valid '%s' unrecognized\n",
-				argv[optind - 1]);
-			usage(stderr);
-			exit(1);
-		}
-	}
-
-	if (optind >= argc) {
-		usage(stderr);
-		exit(1);
-	}
-
-	if (obduuid == NULL)
-		query++;
-
-	init();
-
-	do {
-		processPath(argv[optind]);
-	} while (++optind < argc);
-
-	exit (0);
-}
-
-void init()
-{
-	int datalen, desclen;
-
-	datalen = size_round(sizeof(data));
-	desclen = size_round(sizeof(desc));
-	uuidslen = size_round(max_ost_count * sizeof(*uuids));
-	cfglen = datalen + desclen + uuidslen;
-	lmmlen = lov_mds_md_size(max_ost_count);
-	if (cfglen > lmmlen)
-		buflen = cfglen;
-	else
-		buflen = lmmlen;
-
-	/* XXX max ioctl buffer size currently hardcoded to 8192 */
-	if (buflen > 8192) {
-		int nuuids, remaining, nluoinfos;
-
-		buflen = 8192;
-		nuuids = (buflen - datalen - desclen) / sizeof(*uuids);
-		uuidslen = size_round(nuuids * sizeof(*uuids));
-		remaining = nuuids * sizeof(*uuids);
-		if (uuidslen > remaining)
-			nuuids--;
-		nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects);
-		if (nuuids > nluoinfos)
-			max_ost_count = nluoinfos;
-		else
-			max_ost_count = nuuids;
-
-		cfglen = datalen + desclen + uuidslen;
-		lmmlen = lov_mds_md_size(max_ost_count);
-	}
-
-	if ((buf = malloc(buflen)) == NULL) {
-		errMsg("Unable to allocate %d bytes of memory for ioctl's");
-		exit(1);
-	}
-
-	lmm = (struct lov_mds_md *)buf;
-	uuids = (struct obd_uuid *)buf;
-}
-
-void usage(FILE *stream)
-{
-	fprintf(stream, "usage: %s %s\n", cmd, usageMsg);
-}
-
-void errMsg(char *fmt, ...)
-{
-	va_list args;
-	int tmp_errno = errno;
-
-	fprintf(stderr, "%s: ", cmd);
-	va_start(args, fmt);
-	vfprintf(stderr, fmt, args);
-	va_end(args);
-	fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
-}
-
-void processPath(char *path)
-{
-	int fd;
-	int rc;
-	int i;
-	int obdindex = OBD_NOT_FOUND;
-	int obdcount;
-	struct obd_uuid *uuidp;
-	char *fname, *dirname;
-
-	if ((query || verbose) && !obduuid) {
-		printf("%s\n", path);
-	}
-
-	fname = strrchr(path, '/');
-	if (fname != NULL && fname[1] != '\0') {
-		*fname = '\0';
-		fname++;
-		dirname = path;
-	} else if (fname != NULL && fname[1] == '\0') {
-		printf("need getdents support\n");
-		return;
-	} else {
-		dirname = ".";
-		fname = path;
-	}
-
-	if ((fd = open(dirname, O_RDONLY)) < 0) {
-		errMsg("open \"%.20s\" failed", dirname);
-		return;
-	}
-
-	if (!printed_UUIDs) {
-		memset(&data, 0, sizeof(data));
-		data.ioc_inllen1 = sizeof(desc);
-		data.ioc_inlbuf1 = (char *)&desc;
-		data.ioc_inllen2 = uuidslen;
-		data.ioc_inlbuf2 = (char *)uuids;
-
-		memset(&desc, 0, sizeof(desc));
-		desc.ld_tgt_count = max_ost_count;
-
-		if (obd_ioctl_pack(&data, &buf, buflen)) {
-			errMsg("internal buffering error");
-			exit(1);
-		}
-
-		rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
-		if (rc) {
-			if (errno == ENOTTY) {
-				if (!obduuid) {
-					errMsg("error getting LOV config");
-				}
-				return;
-			}
-			errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %s");
-			exit(1);
-		}
-
-		if (obd_ioctl_unpack(&data, buf, buflen)) {
-			errMsg("Invalid reply from ioctl");
-			exit(1);
-		}
-
-		obdcount = desc.ld_tgt_count;
-		if (obdcount == 0)
-			return;
-
-		obdindex = OBD_NOT_FOUND;
-
-		if (obduuid) {
-			for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
-				if (strncmp((char *)obduuid, (char *)uuidp,
-					sizeof(*uuidp)) == 0) {
-					obdindex = i;
-				}
-			}
-
-			if (obdindex == OBD_NOT_FOUND)
-				return;
-		} else if (query || verbose) {
-			printf("OBDS:\n");
-			for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++)
-				printf("%4d: %s\n", i, (char *)uuidp);
-		}
-		printed_UUIDs = 1;
-	}
-
-	strcpy((char *)lmm, fname);
-	rc = ioctl(fd, IOC_MDC_GETSTRIPE, (void *)lmm);
-	if (rc) {
-		if (errno == ENODATA) {
-			if (!obduuid)
-				printf("Has no stripe information.\n");
-		}
-		else {
-			errMsg("IOC_MDC_GETSTRIPE ioctl failed");
-		}
-		return;
-	}
-
-	close(fd);
-
-	if (obduuid && lmm->lmm_objects[obdindex].l_object_id)
-		printf("%s\n", path);
-
-	if (verbose) {
-		printf("lmm_magic:          0x%x\n", lmm->lmm_magic);
-		printf("lmm_object_id:      "LPX64"\n", lmm->lmm_object_id);
-		printf("lmm_stripe_offset:  %u\n", (int)lmm->lmm_stripe_offset);
-		printf("lmm_stripe_count:   %u\n", (int)lmm->lmm_stripe_count);
-		printf("lmm_stripe_size:    %u\n", (int)lmm->lmm_stripe_size);
-		printf("lmm_ost_count:      %u\n", lmm->lmm_ost_count);
-		printf("lmm_stripe_pattern: %d\n", lmm->lmm_magic & 0xf);
-	}
-
-	if (query || verbose) {
-		long long oid;
-		int ost = lmm->lmm_stripe_offset;
-		int header = 1;
-
-		for (i = 0; i < lmm->lmm_ost_count; i++, ost++) {
-			ost %= lmm->lmm_ost_count;
-			if ((oid = lmm->lmm_objects[ost].l_object_id)) {
-				if (header) {
-					printf("\tobdidx\t   objid\n");
-					header = 0;
-				}
-				printf("\t%6u\t%8llu%s\n",
-				       ost, oid, obdindex == ost ? " *" : "");
-			}
-		}
-		printf("\n");
-	}
-}
diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..f403706ed53f76d443c86e9ab533efd00e73a947
--- /dev/null
+++ b/lustre/utils/lfs.c
@@ -0,0 +1,309 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc.
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Robert Read <rread@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <mntent.h>
+#include <portals/api-support.h>
+#include <portals/ptlctl.h>
+
+#include <liblustre.h>
+#include <linux/lustre_idl.h>
+
+#include "parser.h"
+#include "obdctl.h"
+
+extern int op_create_file(char *name, long stripe_size, int stripe_offset,
+                int stripe_count);
+extern int op_find(char *path, struct obd_uuid *obduuid, int recursive,
+                int verbose, int quiet);
+extern int op_check(int type_num, char **obd_type_p, char *dir);
+
+/* all functions */
+static int lfs_setstripe(int argc, char **argv);
+static int lfs_find(int argc, char **argv);
+static int lfs_getstripe(int argc, char **argv);
+static int lfs_osts(int argc, char **argv);
+static int lfs_check(int argc, char **argv);
+
+/* all avaialable commands */
+command_t cmdlist[] = {
+        {"setstripe", lfs_setstripe, 0,
+         "blah...\n"
+         "usage: setstripe <filename> <stripe size> <stripe start> <stripe count>\n"
+         "\tstripe size:  Number of bytes in each stripe (0 default)\n"
+         "\tstripe start: OST index of first stripe (-1 default)\n"
+         "\tstripe count: Number of OSTs to stripe over (0 default)"},
+        {"find", lfs_find, 0,
+         "blah...\n"
+         "usage: find [--obd <uuid>] [--quiet | --verbose] [--recursive] <dir|file> ..."},
+        {"getstripe", lfs_getstripe, 0,
+         "blah...\n"
+         "usage:getstripe <filename>"},
+        {"check", lfs_check, 0, 
+         "blah...\n"
+         "usage: check <osts|mds|servers>"},
+        {"osts", lfs_osts, 0, "osts"},
+        {"help", Parser_help, 0, "help"},
+        {"exit", Parser_quit, 0, "quit"},
+        {"quit", Parser_quit, 0, "quit"},
+        { 0, 0, 0, NULL }
+};
+
+/* functions */
+static int lfs_setstripe(int argc, char **argv)
+{
+        int result;
+        long st_size;
+        int  st_offset, st_count;
+        char *end;
+
+        if (argc != 5)
+                return CMD_HELP;
+
+        // get the stripe size
+        st_size = strtoul(argv[2], &end, 0);
+        if (*end != '\0') {
+                fprintf(stderr, "error: %s: bad stripe size '%s'\n",
+                                argv[0], argv[2]);
+                return CMD_HELP;
+        }
+        // get the stripe offset
+        st_offset = strtoul(argv[3], &end, 0);
+        if (*end != '\0') {
+                fprintf(stderr, "error: %s: bad stripe offset '%s'\n",
+                                argv[0], argv[3]);
+                return CMD_HELP;
+        }
+        // get the stripe count
+        st_count = strtoul(argv[4], &end, 0);
+        if (*end != '\0') {
+                fprintf(stderr, "error: %s: bad stripe count '%s'\n",
+                                argv[0], argv[4]);
+                return CMD_HELP;
+        }
+
+        result = op_create_file(argv[1], st_size, st_offset, st_count);
+        if (result)
+                fprintf(stderr, "error: %s: create stripe file failed\n",
+                                argv[0]);
+
+        return result;
+}
+
+static int lfs_find(int argc, char **argv)
+{
+        struct option long_opts[] = {
+                {"obd", 1, 0, 'o'},
+                {"quiet", 0, 0, 'q'},
+                {"recursive", 0, 0, 'r'},
+                {"verbose", 0, 0, 'v'},
+                {0, 0, 0, 0}
+        };
+        char short_opts[] = "ho:qrv";
+        int quiet, verbose, recursive, c, rc;
+        struct obd_uuid *obduuid = NULL;
+
+        optind = 0;
+        quiet = verbose = recursive = 0;
+        while ((c = getopt_long(argc, argv, short_opts,
+                                        long_opts, NULL)) != -1) {
+                switch (c) {
+                case 'o':
+                        if (obduuid) {
+                                fprintf(stderr,
+                                        "error: %s: only one obduuid allowed",
+                                        argv[0]);
+                                return CMD_HELP;
+                        }
+                        obduuid = (struct obd_uuid *)optarg;
+                        break;
+                case 'q':
+                        quiet++;
+                        verbose = 0;
+                        break;
+                case 'r':
+                        recursive = 1;
+                        break;
+                case 'v':
+                        verbose++;
+                        quiet = 0;
+                        break;
+                case '?':
+                        return CMD_HELP;
+                        break;
+                default:
+                        fprintf(stderr, "error: %s: option '%s' unrecognized\n",
+                                argv[0], argv[optind - 1]);
+                        return CMD_HELP;
+                        break;
+                }
+        }
+
+        if (optind >= argc)
+                return CMD_HELP;
+
+        do {
+                rc = op_find(argv[optind], obduuid, recursive, verbose, quiet);
+        } while (++optind < argc && !rc);
+
+        if (rc)
+                fprintf(stderr, "error: %s: find failed\n", argv[0]);
+        return rc;
+}
+
+static int lfs_getstripe(int argc, char **argv)
+{
+        struct obd_uuid *obduuid = NULL;
+        int rc;
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        optind = 1;
+
+        do {
+                rc = op_find(argv[optind], obduuid, 0, 0, 0);
+        } while (++optind < argc && !rc);
+
+        if (rc)
+                fprintf(stderr, "error: %s: getstripe failed for %s\n",
+                        argv[0], argv[1]);
+
+        return rc;
+}
+
+static int lfs_osts(int argc, char **argv)
+{
+        FILE *fp;
+        struct mntent *mnt = NULL;
+        struct obd_uuid *obduuid = NULL;
+        int rc=0;
+                                                                                                                             
+        if (argc != 1)
+                return CMD_HELP;
+
+        fp = setmntent(MOUNTED, "r");
+
+        if (fp == NULL) {
+                 fprintf(stderr, "setmntent(%s): %s:", MOUNTED,
+                        strerror (errno));
+        } else {
+                mnt = getmntent(fp);
+                while (feof(fp) == 0 && ferror(fp) ==0) {
+                        if (strcmp(mnt->mnt_type, "lustre_lite") == 0) {
+                                rc = op_find(mnt->mnt_dir, obduuid, 0, 0, 0);
+                                if (rc)
+                                        fprintf(stderr, "error: lfs osts failed for %s\n",
+                                                mnt->mnt_dir);
+                        }
+                        mnt = getmntent(fp);
+                }
+                endmntent(fp);
+        }
+                                                                                                                             
+        return rc;
+}
+
+static int lfs_check(int argc, char **argv)
+{
+        int rc;
+        FILE *fp;
+        struct mntent *mnt = NULL;
+        int type_num = 1;
+        char *obd_type_p[2];
+        char obd_type1[4];
+        char obd_type2[4];
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        obd_type_p[1]=obd_type1;
+        obd_type_p[2]=obd_type2;
+
+        if (strcmp(argv[1],"osts")==0) {
+                strcpy(obd_type_p[0],"osc");
+        } else if (strcmp(argv[1],"mds")==0) {
+                strcpy(obd_type_p[0],"mdc");
+        } else if (strcmp(argv[1],"servers")==0) {
+                type_num=2;
+                strcpy(obd_type_p[0],"osc");
+                strcpy(obd_type_p[1],"mdc");
+        } else {
+                fprintf(stderr, "error: %s: option '%s' unrecognized\n",
+                                argv[0], argv[1]);
+                        return CMD_HELP;
+        }
+
+        fp = setmntent(MOUNTED, "r");
+        if (fp == NULL) {
+                 fprintf(stderr, "setmntent(%s): %s:", MOUNTED,
+                        strerror (errno));
+        } else {
+                mnt = getmntent(fp);
+                while (feof(fp) == 0 && ferror(fp) ==0) {
+                        if (strcmp(mnt->mnt_type, "lustre_lite") == 0) 
+                                break;
+                        mnt = getmntent(fp);
+                }
+                endmntent(fp);
+        }
+           
+        rc = op_check(type_num,obd_type_p,mnt->mnt_dir);
+
+        if (rc)
+                fprintf(stderr, "error: %s: %s status failed\n",
+                                argv[0],argv[1]);
+                                                                                                                             
+        return rc;
+
+}
+
+int main(int argc, char **argv)
+{
+        int rc;
+
+        setlinebuf(stdout);
+                                                                                                                             
+        ptl_initialize(argc, argv);
+        if (obd_initialize(argc, argv) < 0)
+                exit(2);
+        if (dbg_initialize(argc, argv) < 0)
+                exit(3);
+                                                                                                                             
+        Parser_init("lfs > ", cmdlist);
+
+        if (argc > 1) {
+                rc = Parser_execarg(argc - 1, argv + 1, cmdlist);
+        } else {
+                rc = Parser_commands();
+        }
+
+        obd_finalize(argc, argv);
+        return rc;
+}
diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c
new file mode 100644
index 0000000000000000000000000000000000000000..7ea801c46780fa830764c606997f1eba3a51828e
--- /dev/null
+++ b/lustre/utils/liblustreapi.c
@@ -0,0 +1,533 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc.
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Robert Read <rread@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+/* for O_DIRECTORY */
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+
+#include <liblustre.h>
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_user.h>
+#include <linux/obd_lov.h>
+
+#include <portals/ptlctl.h>
+
+static void err_msg(char *fmt, ...)
+{
+        va_list args;
+        int tmp_errno = errno;
+
+        va_start(args, fmt);
+        vfprintf(stderr, fmt, args);
+        va_end(args);
+        fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
+}
+
+int op_create_file(char *name, long stripe_size, int stripe_offset,
+                   int stripe_count)
+{
+        struct lov_user_md lum = { 0 };
+        int fd, rc = 0;
+
+        /*  Initialize IOCTL striping pattern structure  */
+        lum.lmm_magic = LOV_USER_MAGIC;
+        lum.lmm_stripe_size = stripe_size;
+        lum.lmm_stripe_offset = stripe_offset;
+        lum.lmm_stripe_count = stripe_count;
+
+        fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
+        if (fd < 0) {
+                err_msg("unable to open '%s'",name);
+                rc = -errno;
+                return rc;
+        }
+        if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum)) {
+                char *errmsg = "stripe already set";
+                if (errno != EEXIST && errno != EALREADY)
+                        errmsg = strerror(errno);
+
+                fprintf(stderr, "error on ioctl for '%s' (%d): %s\n",
+                        name, fd, errmsg);
+                rc = -errno;
+        }
+        if (close(fd) < 0) {
+                err_msg("error on close for '%s' (%d)", name, fd);
+                if (rc == 0)
+                        rc = -errno;
+        }
+        return rc;
+}
+
+
+struct find_param {
+        int     recursive;
+        int     verbose;
+        int     quiet;
+        struct  obd_uuid        *obduuid;
+        struct  obd_ioctl_data  data;
+        struct  lov_desc        desc;
+        int     uuidslen;
+        char    *buf;
+        int     buflen;
+        struct  obd_uuid        *uuids;
+        struct  lov_user_md     *lum;
+        int     got_uuids;
+        int     obdindex;
+        int     max_ost_count;
+};
+
+/* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */
+#define MAX_LOV_UUID_COUNT      1000
+#define OBD_NOT_FOUND           (-1)
+
+static int prepare_find(struct find_param *param)
+{
+        int datalen, desclen;
+        int cfglen, lumlen;
+        int max_ost_count = MAX_LOV_UUID_COUNT;
+
+        datalen = size_round(sizeof(param->data));
+        desclen = size_round(sizeof(param->desc));
+        param->uuidslen = size_round(max_ost_count * sizeof(*param->uuids));
+        cfglen = datalen + desclen + param->uuidslen;
+        lumlen = lov_mds_md_size(max_ost_count);
+        if (cfglen > lumlen)
+                param->buflen = cfglen;
+        else
+                param->buflen = lumlen;
+
+        /* XXX max ioctl buffer size currently hardcoded to 8192 */
+        if (param->buflen > 8192) {
+                int nuuids, remaining;
+
+                param->buflen = 8192;
+                nuuids = (param->buflen - datalen - desclen) /
+                        sizeof(*param->uuids);
+                param->uuidslen = size_round(nuuids * sizeof(*param->uuids));
+                remaining = nuuids * sizeof(*param->uuids);
+                if (param->uuidslen > remaining)
+                        nuuids--;
+                max_ost_count = nuuids;
+                while ((lumlen=lov_mds_md_size(max_ost_count)) > param->buflen)
+                        --max_ost_count;
+
+                cfglen = datalen + desclen + param->uuidslen;
+        }
+
+        if ((param->buf = malloc(param->buflen)) == NULL) {
+                err_msg("unable to allocate %d bytes of memory for ioctl's",
+                        param->buflen);
+                return ENOMEM;
+        }
+
+        param->lum = (struct lov_user_md *)param->buf;
+        param->uuids = (struct obd_uuid *)param->buf;
+        param->got_uuids = 0;
+        param->obdindex = OBD_NOT_FOUND;
+        param->max_ost_count = max_ost_count;
+
+        return 0;
+}
+
+static void cleanup_find(struct find_param *param)
+{
+        if (param->obduuid)
+                free(param->obduuid);
+        if (param->buf)
+                free(param->buf);
+}
+
+static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param)
+{
+        int obdcount;
+        struct obd_uuid *uuidp;
+        int rc, i;
+
+        param->got_uuids = 1;
+        memset(&param->data, 0, sizeof(param->data));
+        param->data.ioc_inllen1 = sizeof(struct lov_desc);
+        param->data.ioc_inlbuf1 = (char *)&param->desc;
+        param->data.ioc_inllen2 = param->uuidslen;
+        param->data.ioc_inlbuf2 = (char *)param->uuids;
+
+        memset(&param->desc, 0, sizeof(struct lov_desc));
+        param->desc.ld_tgt_count = param->max_ost_count;
+
+        if (obd_ioctl_pack(&param->data, &param->buf, param->buflen)) {
+                fprintf(stderr, "internal buffer error from %s\n", dname);
+                return (param->obduuid ? EINVAL : 0);
+        }
+
+        rc = ioctl(dirfd(dir), OBD_IOC_LOV_GET_CONFIG, param->buf);
+        if (rc) {
+                err_msg("error getting LOV config from %s", dname);
+                return (param->obduuid ? errno : 0);
+        }
+
+        if (obd_ioctl_unpack(&param->data, param->buf, param->buflen)) {
+                err_msg("invalid reply from ioctl from %s", dname);
+                return (param->obduuid ? EINVAL : 0);
+        }
+
+        obdcount = param->desc.ld_tgt_count;
+        if (obdcount == 0)
+                return 0;
+
+        if (param->obduuid) {
+                for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++) {
+                        if (strncmp(param->obduuid->uuid, uuidp->uuid,
+                                    sizeof(*uuidp)) == 0) {
+                                param->obdindex = i;
+                                break;
+                        }
+                }
+        } else if (!param->quiet) {
+                printf("OBDS:\n");
+                for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++)
+                        printf("%4d: %s\n", i, uuidp->uuid);
+        }
+
+        return 0;
+}
+
+void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname,
+                          int obdindex, int quiet, int header, int body)
+{
+        int i;
+
+        if (obdindex != OBD_NOT_FOUND) {
+                for (i = 0; i < lum->lmm_stripe_count; i++) {
+                        if (obdindex == lum->lmm_objects[i].l_ost_idx) {
+                                printf("%s/%s\n", dname, fname);
+                                break;
+                        }
+                }
+        } else if (!quiet) {
+                printf("%s/%s\n", dname, fname);
+        }
+
+        if (header) {
+                printf("lmm_magic:          0x%80X\n",  lum->lmm_magic);
+                printf("lmm_object_gr:      "LPX64"\n", lum->lmm_object_gr);
+                printf("lmm_object_id:      "LPX64"\n", lum->lmm_object_id);
+                printf("lmm_stripe_count:   %u\n", (int)lum->lmm_stripe_count);
+                printf("lmm_stripe_size:    %u\n",      lum->lmm_stripe_size);
+                printf("lmm_stripe_pattern: %x\n",      lum->lmm_pattern);
+        }
+
+        if (body) {
+                long long oid;
+
+                if (!quiet)
+                        printf("\tobdidx\t\t objid\t\tobjid\t\t group\n");
+
+                for (i = 0; i < lum->lmm_stripe_count; i++) {
+                        int idx = lum->lmm_objects[i].l_ost_idx;
+                        oid = lum->lmm_objects[i].l_object_id;
+                        printf("\t%6u\t%14llu\t%#13llx\t%14lld%s\n", idx, oid,
+                               oid, (long long)lum->lmm_objects[i].l_object_gr,
+                               obdindex == idx ? " *" : "");
+                }
+                printf("\n");
+        }
+}
+
+void lov_dump_user_lmm(struct find_param *param, char *dname, char *fname)
+{
+        switch(*(__u32 *)param->lum) { /* lum->lmm_magic */
+        case LOV_USER_MAGIC_V1:
+                lov_dump_user_lmm_v1(param->lum, dname, fname, param->obdindex,
+                                     param->quiet, param->verbose,
+                                     (param->verbose || !param->obduuid));
+                break;
+        default:
+                printf("unknown lmm_magic:  0x%08X\n", *(__u32 *)param->lum);
+                return;
+        }
+}
+
+static int process_file(DIR *dir, char *dname, char *fname,
+                         struct find_param *param)
+{
+        int rc;
+
+        strncpy((char *)param->lum, fname, param->buflen);
+
+        rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->lum);
+        if (rc) {
+                if (errno == ENODATA) {
+                        if (!param->obduuid && !param->quiet)
+                                fprintf(stderr,
+                                        "%s/%s has no stripe info\n",
+                                        dname, fname);
+                        rc = 0;
+                } else if (errno == EISDIR) {
+                        fprintf(stderr, "process_file on directory %s/%s!\n",
+                                dname, fname);
+                        /* add fname to directory list; */
+                        rc = errno;
+                } else {
+                        err_msg("IOC_MDC_GETSTRIPE ioctl failed");
+                        rc = errno;
+                }
+                return rc;
+        }
+
+        lov_dump_user_lmm(param, dname, fname);
+
+        return 0;
+}
+
+
+static int process_dir(DIR *dir, char *dname, struct find_param *param)
+{
+        struct dirent64 *dirp;
+        DIR *subdir;
+        char path[1024];
+        int rc;
+
+        if (!param->got_uuids) {
+                rc = get_obd_uuids(dir, dname, param);
+                if (rc)
+                        return rc;
+        }
+
+        /* Handle the contents of the directory */
+        while ((dirp = readdir64(dir)) != NULL) {
+                if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, ".."))
+                        continue;
+
+                switch (dirp->d_type) {
+                case DT_UNKNOWN:
+                        err_msg("\"%s\" is UNKNOWN type %d", dirp->d_name,
+                                dirp->d_type);
+                        /* If we cared we could stat the file to determine
+                         * type and continue on here, but we don't since we
+                         * know d_type should be valid for lustre and this
+                         * tool only makes sense for lustre filesystems. */
+                        return EINVAL;
+                        break;
+                case DT_DIR:
+                        if (!param->recursive)
+                                break;
+                        strcpy(path, dname);
+                        strcat(path, "/");
+                        strcat(path, dirp->d_name);
+                        subdir = opendir(path);
+                        if (subdir == NULL) {
+                                err_msg("\"%.40s\" opendir failed", path);
+                                return errno;
+                        }
+                        rc = process_dir(subdir, path, param);
+                        closedir(subdir);
+                        if (rc)
+                                return rc;
+                        break;
+                case DT_REG:
+                        rc = process_file(dir, dname, dirp->d_name, param);
+                        if (rc)
+                                return rc;
+                        break;
+                default:
+                        break;
+                }
+        }
+
+        return 0;
+}
+
+static int process_path(char *path, struct find_param *param)
+{
+        char *fname, *dname;
+        DIR *dir;
+        int rc = 0;
+
+        fname = strrchr(path, '/');
+        if (fname != NULL && fname[1] == '\0') {
+                /* Trailing '/', it must be a dir */
+                *fname = '\0';
+                dir = opendir(path);
+                if (dir == NULL) {
+                        err_msg("\"%.40s\" opendir failed", path);
+                        rc = errno;
+                } else {
+                        rc = process_dir(dir, path, param);
+                        closedir(dir);
+                }
+        } else if ((dir = opendir(path)) != NULL) {
+                /* No trailing '/', but it is still a dir */
+                rc = process_dir(dir, path, param);
+                closedir(dir);
+        } else {
+                /* It must be a file (or other non-directory) */
+                if (fname == NULL) {
+                        dname = ".";
+                        fname = path;
+                } else {
+                        *fname = '\0';
+                        fname++;
+                        dname = path;
+                }
+                dir = opendir(dname);
+                if (dir == NULL) {
+                        err_msg("\"%.40s\" opendir failed", dname);
+                        rc = errno;
+                } else {
+                        if (!param->got_uuids)
+                                rc = get_obd_uuids(dir, dname, param);
+                        if (rc == 0)
+                                rc = process_file(dir, dname, fname, param);
+                        closedir(dir);
+                }
+        }
+
+        return rc;
+}
+
+
+int op_find(char *path, struct obd_uuid *obduuid, int recursive,
+            int verbose, int quiet)
+{
+        struct find_param param;
+        int ret = 0;
+
+        memset(&param, 0, sizeof(param));
+        param.recursive = recursive;
+        param.verbose = verbose;
+        param.quiet = quiet;
+        if (obduuid) {
+                param.obduuid = malloc(sizeof(*obduuid));
+                if (param.obduuid == NULL) {
+                        ret = ENOMEM;
+                        goto out;
+                }
+                memcpy(param.obduuid, obduuid, sizeof(*obduuid));
+        }
+
+        ret = prepare_find(&param);
+        if (ret)
+                goto out;
+
+        process_path(path, &param);
+out:
+        cleanup_find(&param);
+        return ret;
+}
+
+#define MAX_STRING_SIZE 128
+
+int op_check(int type_num, char **obd_type, char *dir)
+{
+        int rc=0;
+        int i=0,j=0,k;
+        char buf[OBD_MAX_IOCTL_BUFFER];
+        char *buf2;
+        struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
+                                                                                                                     
+        memset(buf, 0, sizeof(buf));
+        data->ioc_version = OBD_IOCTL_VERSION;
+        data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
+        data->ioc_len = obd_ioctl_packlen(data);
+                                                                                                                             
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
+                   
+        buf2 = data->ioc_bulk;
+
+        if (!data->ioc_inlbuf1) {
+                err_msg("No buffer passed!\n");
+                rc = errno;
+        }
+
+        do {
+                char status[3];
+                char obd_type_name[sizeof(struct obd_type)];
+                char obd_name[MAX_STRING_SIZE];
+                char obd_uuid[sizeof(struct obd_uuid)];
+                int obd_type_refcnt;
+
+                char rawbuf[OBD_MAX_IOCTL_BUFFER];
+                char *bufl = rawbuf;
+                int max = sizeof(rawbuf);
+                struct obd_ioctl_data datal;
+                struct obd_statfs osfs_buffer;
+                                                                                
+                memset (&osfs_buffer, 0, sizeof (osfs_buffer));
+
+                memset(bufl, 0, sizeof(rawbuf));
+                datal.ioc_pbuf1 = (char *)&osfs_buffer;
+                datal.ioc_plen1 = sizeof (osfs_buffer);
+
+                j = sscanf(buf2,"%d %s %s %s %s %d",&j,
+                             status,obd_type_name,
+                             obd_name, obd_uuid,
+                             &obd_type_refcnt);
+
+                if (j != 6) break;
+
+                for (k=0;k<type_num;k++) 
+                        if (strcmp(obd_type_name, obd_type[k]) == 0) {
+                                datal.ioc_inlbuf1 = obd_name;
+                                datal.ioc_inllen1 = strlen(obd_name) + 1; 
+
+                                obd_ioctl_pack(&datal,&bufl,max);
+
+                                rc = ioctl(dirfd(opendir(dir)), OBD_IOC_PING,bufl);
+
+                                if (rc) {
+                                        fprintf(stderr, "error: check %s: %s\n", 
+                                                obd_name, strerror(rc = errno));
+                                } else {
+                                        printf("%s active.\n",obd_name);
+                                }
+                        }
+
+                if (j==6)
+                        for (i=0;buf2[i]!= '\n';i++);
+
+                buf2 +=(i+1);
+
+        } while (j==6);                                                                                                     
+
+        return rc;
+}
+
+#undef MAX_STRING_SIZE
+
diff --git a/lustre/utils/llanalyze b/lustre/utils/llanalyze
index 56e58c88dd752e31e9bd7106d3ecb96abfa43fe9..97c691a038498bc672460b2ed1f784d9d1934711 100644
--- a/lustre/utils/llanalyze
+++ b/lustre/utils/llanalyze
@@ -11,7 +11,6 @@ GetOptions("pid=i" => \$pid,
            "noclass!" => \$noclass,
            "nonet!" => \$nonet);
 
-print "pid: $pid, nodlm $nodlm nonet $nonet trace $trace\n";
 
 
 $subsys->{UNDEFINED} = 0;
@@ -35,6 +34,8 @@ $subsys->{LDLM} = 17;
 $subsys->{LOV} = 18;
 $subsys->{GMNAL} = 19;
 $subsys->{PTLROUTER} = 20;
+$subsys->{COBD} = 21;
+$subsys->{IBNAL} = 22;
 
 
 $masks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */
@@ -63,11 +64,8 @@ sub extractpid
 {
     $line = shift;
 #    print "$_\n";
-    if ($line =~ m/\(\) ([0-9]*)\+[0-9]*\):/) {
-	return $1;
-    }
-    if ($line =~ m/\(\) ([0-9]*) \| [0-9]*\+[0-9]*\):/) {
-	return $1;
+    if ($line =~ m/\d+:\d+:\d+:\d+\.\d+:\d+:\d+:*$/) {
+	return $6;
     }
 }
 
@@ -75,11 +73,32 @@ sub extracthostpid
 {
     $line = shift;
 #    print "$_\n";
-    if ($line =~ m/\(\) [0-9]* \| ([0-9]*)\+[0-9]*\):/) {
-	return $1;
+    if ($line =~ m/\d+:\d+:\d+:\d+\.\d+:\d+:\d+:\d+:*$/) {
+	return $7;
     }
 }
 
+sub entering_rpc
+{
+	$_ = shift;
+	$entering_rpc  = /Handling RPC/;
+	if($entering_rpc) {
+		$oldpid=$pid;
+		$pid = extractpid($_);
+		$leaving_rpc = 0;
+	}
+}
+
+sub leaving_rpc
+{
+	$_ = shift;
+	$leaving_rpc  = /Handled RPC/;
+	if($leaving_rpc) {
+		$pid = $oldpid; 
+		$entering_rpc = 0;
+	}
+}
+
 sub entering
 {
     $_ = shift;
@@ -107,8 +126,13 @@ sub getmask
 sub setcolor
 {
     my $linemask = shift;
+    my $line = shift;
     if ($linemask == $masks->{TRACE}) {
-        print color("yellow on_black");
+        if(leaving($line)){
+           print color("yellow on_black");
+        } else {
+           print color("green on_black");
+        }
     }
     if ($linemask == $masks->{DLMTRACE}) {
         print color("magenta on_black");
@@ -220,7 +244,27 @@ sub unmatched_intents {
     }
 }
 
-while (<STDIN>) {
+sub usage
+{
+   print "Usage : llanalyze LOGFILE\n";
+   exit;
+}
+
+if ($ARGV[0]) {
+    if(!open(LOG, "<$ARGV[0]")){
+      print "Cannot open $ARGV[0]\n";
+      exit;
+    }
+} else {
+    usage();
+}
+$width = 0;
+if ($ARGV[1]) {
+   $width = $ARGV[1];
+}
+
+print "pid: $pid, nodlm $nodlm nonet $nonet trace $trace\n";
+while (<LOG>) {
     $linepid = extractpid($_);
     $linehpid = extracthostpid($_);
     $linemask = getmask($_);
@@ -241,7 +285,7 @@ while (<STDIN>) {
     }
 
     if ( !$pid || $linepid == $pid || $linehpid == $pid) {
-        next if ($rpctrace && $linemask != $masks->{RPCTRACE});
+        next if (!$entering_rpc && $rpctrace && $linemask != $masks->{RPCTRACE});
         next if ($trace && $linemask != $masks->{TRACE});
 
 
@@ -256,13 +300,19 @@ while (<STDIN>) {
                     $linesubsys == $subsys->{PORTALS} ||
                     $linesubsys == $subsys->{SOCKNAL} ||
                     $linesubsys == $subsys->{QSWNAL} ||
+                    $linesubsys == $subsys->{IBNAL} ||
                     $linesubsys == $subsys->{GMNAL}));
-
+	if(!$entering_rpc) {entering_rpc($_);}
+	if(!$leaving_rpc) {leaving_rpc($_);}
 
 #        printf "sub/mask: %s - %s\n", getsubsys($_), getmask($_);
-        if (!$silent) { 
-            setcolor($linemask);
-            printf("%s%s", $prefix->{$linepid}, $_);
+        if (!$silent) {
+            setcolor($linemask, $_);
+            my $string = $prefix->{$linepid}.$_;
+            if($width){ 
+               $string = substr($string, 0, $width)."\n";
+            }
+            printf("%s", $string);
             print color("reset");
         }
             #        last if $count++ > 100;
diff --git a/lustre/utils/llmount.c b/lustre/utils/llmount.c
new file mode 100644
index 0000000000000000000000000000000000000000..d5994e73f160ef24485d136485219ed31534568b
--- /dev/null
+++ b/lustre/utils/llmount.c
@@ -0,0 +1,351 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc.
+ *   Author: Robert Read <rread@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <mntent.h>
+
+#include "obdctl.h"
+#include <portals/ptlctl.h>
+
+int debug = 0;
+int verbose = 0;
+int nomtab = 0;
+
+static void
+update_mtab_entry(char *spec, char *node, char *type, char *opts,
+		  int flags, int freq, int pass)
+{
+        FILE *fp;
+        struct mntent mnt;
+
+        mnt.mnt_fsname = spec;
+        mnt.mnt_dir = node;
+        mnt.mnt_type = type;
+        mnt.mnt_opts = opts ? opts : "";
+        mnt.mnt_freq = freq;
+        mnt.mnt_passno = pass;
+
+        if (!nomtab) {
+                fp = setmntent(MOUNTED, "a+");
+                if (fp == NULL) {
+                        fprintf(stderr, "setmntent(%s): %s:", MOUNTED,
+                                strerror (errno));
+                } else {
+                        if ((addmntent (fp, &mnt)) == 1) {
+                                fprintf(stderr, "addmntent: %s:",
+                                        strerror (errno));
+                        }
+                        endmntent(fp);
+                }
+        }
+}
+
+int
+init_options(struct lustre_mount_data *lmd)
+{
+        memset(lmd, 0, sizeof(lmd));
+        lmd->lmd_server_nid = PTL_NID_ANY;
+        lmd->lmd_local_nid = PTL_NID_ANY;
+        lmd->lmd_port = 988;    /* XXX define LUSTRE_DEFAULT_PORT */
+        lmd->lmd_nal = SOCKNAL;
+        return 0;
+}
+
+int
+print_options(struct lustre_mount_data *lmd)
+{
+        printf("mds:             %s\n", lmd->lmd_mds);
+        printf("profile:         %s\n", lmd->lmd_profile);
+        printf("server_nid:      "LPX64"\n", lmd->lmd_server_nid);
+        printf("local_nid:       "LPX64"\n", lmd->lmd_local_nid);
+        printf("nal:             %d\n", lmd->lmd_nal);
+        printf("server_ipaddr:   0x%x\n", lmd->lmd_server_ipaddr);
+        printf("port:            %d\n", lmd->lmd_port);
+
+        return 0;
+}
+
+int
+parse_options(char * options, struct lustre_mount_data *lmd)
+{
+        ptl_nid_t nid = 0;
+        int val;
+        char *opt;
+        char * opteq;
+        
+        /* parsing ideas here taken from util-linux/mount/nfsmount.c */
+        for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) {
+                if ((opteq = strchr(opt, '='))) {
+                        val = atoi(opteq + 1);
+                        *opteq = '\0';
+                        if (!strcmp(opt, "nettype")) {
+                                lmd->lmd_nal = ptl_name2nal(opteq+1);
+                        } else if(!strcmp(opt, "local_nid")) {
+                                if (ptl_parse_nid(&nid, opteq+1) != 0) {
+                                        fprintf (stderr, "mount: "
+                                                 "can't parse NID %s\n",
+                                                 opteq+1);
+                                        return (-1);
+                                }
+                                lmd->lmd_local_nid = nid;
+                        } else if(!strcmp(opt, "server_nid")) {
+                                if (ptl_parse_nid(&nid, opteq+1) != 0) {
+                                        fprintf (stderr, "mount: "
+                                                 "can't parse NID %s\n",
+                                                 opteq+1);
+                                        return (-1);
+                                }
+                                lmd->lmd_server_nid = nid;
+                        } else if (!strcmp(opt, "port")) {
+                                lmd->lmd_port = val;
+                        }
+                } else {
+                        val = 1;
+                        if (!strncmp(opt, "no", 2)) {
+                                val = 0;
+                                opt += 2;
+                        }
+                        if (!strcmp(opt, "debug")) {
+                                debug = val;
+                        }
+                }
+        }
+        return 0;
+}
+
+int
+set_local(struct lustre_mount_data *lmd)
+{
+        char buf[256];
+        ptl_nid_t nid;
+        int rc;
+
+        if (lmd->lmd_local_nid != PTL_NID_ANY)
+                return 0;
+
+        memset(buf, 0, sizeof(buf));
+
+        if (lmd->lmd_nal == SOCKNAL || lmd->lmd_nal == TCPNAL) {
+                rc = gethostname(buf, sizeof(buf) - 1);
+                if (rc) {
+                        fprintf (stderr, "mount: can't get local buf:"
+                                 "%d\n", rc);
+                        return rc;
+                }
+        } else if (lmd->lmd_nal == QSWNAL) {
+                FILE *fp;
+                fp = fopen("/proc/elan/device0/position", "r");
+                if (fp == NULL) {
+                        perror("mount: /proc/elan/device0/position");
+                        return -1;
+                }
+                rc = fscanf(fp, "%*s %255s", buf);
+                fclose(fp);
+                if (rc != 1) {
+                        fprintf(stderr, "mount: problem read elan NID");
+                        return -1;
+                }
+                
+        }
+
+        if (ptl_parse_nid (&nid, buf) != 0) {
+                fprintf (stderr, "mount: can't parse NID %s\n", 
+                         buf);
+                return (-1);
+        }
+
+        lmd->lmd_local_nid = nid;
+        return 0;
+}
+
+int
+set_peer(char *hostname, struct lustre_mount_data *lmd)
+{
+        ptl_nid_t nid = 0;
+        int rc;
+
+        if (lmd->lmd_nal == SOCKNAL || lmd->lmd_nal == TCPNAL) {
+                if (lmd->lmd_server_nid == PTL_NID_ANY) {
+                        if (ptl_parse_nid (&nid, hostname) != 0) {
+                                fprintf (stderr, "mount: can't parse NID %s\n",
+                                         hostname);
+                                return (-1);
+                        }
+                        lmd->lmd_server_nid = nid;
+                }
+
+                if (ptl_parse_ipaddr(&lmd->lmd_server_ipaddr, hostname) != 0) {
+                        fprintf (stderr, "mount: can't parse host %s\n",
+                                 hostname);
+                        return (-1);
+                }
+        } else if (lmd->lmd_nal == QSWNAL) {
+                char buf[64];
+                rc = sscanf(hostname, "%*[^0-9]%63[0-9]", buf);
+                if (rc != 1) {
+                        fprintf (stderr, "mount: can't get elan id from host %s\n",
+                                 hostname);
+                        return -1;
+                }
+                if (ptl_parse_nid (&nid, buf) != 0) {
+                        fprintf (stderr, "mount: can't parse NID %s\n",
+                                 hostname);
+                        return (-1);
+                }
+                lmd->lmd_server_nid = nid;
+        }
+
+
+        return 0;
+}
+
+int
+build_data(char *source, char *options, struct lustre_mount_data *lmd)
+{
+        char target[1024];
+        char *hostname = NULL;
+        char *mds = NULL;
+        char *profile = NULL;
+        char *s;
+        int rc;
+
+        if (strlen(source) > sizeof(target) + 1) {
+                fprintf(stderr, "mount: "
+                        "exessively long host:/mds/profile argument\n");
+                return -EINVAL;
+        }
+        strcpy(target, source);
+        if ((s = strchr(target, ':'))) {
+                hostname = target;
+                *s = '\0';
+
+                while (*++s == '/')
+                        ;
+                mds = s;
+                if ((s = strchr(mds, '/'))) {
+                        *s = '\0';
+                        profile = s + 1;
+                } else {
+                        fprintf(stderr, "mount: "
+                                "directory to mount not in "
+                                "host:/mds/profile format\n");
+                        return(-1);
+                }
+        } else {
+                fprintf(stderr, "mount: "
+                        "directory to mount not in host:/mds/profile format\n");
+                return(-1);
+        }
+        if (verbose)
+                printf("host: %s\nmds: %s\nprofile: %s\n", hostname, mds,
+                       profile);
+
+        rc = parse_options(options, lmd);
+        if (rc)
+                return rc;
+
+        rc = set_local(lmd);
+        if (rc)
+                return rc;
+
+        rc = set_peer(hostname, lmd);
+        if (rc)
+                return rc;
+        if (strlen(mds) > sizeof(lmd->lmd_mds) + 1) {
+                fprintf(stderr, "mount: mds name too long\n");
+                return(-1);
+        }
+        strcpy(lmd->lmd_mds, mds);
+
+        if (strlen(profile) > sizeof(lmd->lmd_profile) + 1) {
+                fprintf(stderr, "mount: profile name too long\n");
+                return(-1);
+        }
+        strcpy(lmd->lmd_profile, profile);
+
+        
+        if (verbose)
+                print_options(lmd);
+        return 0;
+}
+
+int
+main(int argc, char * const argv[])
+{
+        char * source = argv[1];
+        char * target = argv[2];
+        char * options = "";
+        int opt;
+        int i;
+        struct lustre_mount_data lmd;
+
+        int rc;
+
+        while ((opt = getopt(argc, argv, "vno:")) != EOF) {
+                switch (opt) {
+                case 'v':
+                        verbose = 1;
+                        printf("verbose: %d\n", verbose);
+                        break;
+                case 'n':
+                        nomtab = 1;
+                        printf("nomtab: %d\n", nomtab);
+                        break;
+                case 'o':
+                        options = optarg;
+                        break;
+                default:
+                        break;
+                }
+        }
+
+        if (verbose)
+                for (i = 0; i < argc; i++) {
+                        printf("arg[%d] = %s\n", i, argv[i]);
+                }
+
+        init_options(&lmd);
+        rc = build_data(source, options, &lmd);
+        if (rc) {
+                exit(1);
+        }
+
+        if (debug) {
+                printf("mount: debug mode, not mounting\n");
+                exit(0);
+        }
+
+        rc = mount(source, target, "lustre", 0, (void *)&lmd);
+        if (rc) {
+                perror(argv[0]);
+        } else {
+                update_mtab_entry(source, target, "lustre", options, 0, 0, 0);
+        }
+        return rc;
+}
diff --git a/lustre/utils/llobdstat.pl b/lustre/utils/llobdstat.pl
index cb39d3095a369eb4f0175f1e8dae92eef52ee43a..8a8e6c11384134ff596b1ac2ae89fc356c23638a 100755
--- a/lustre/utils/llobdstat.pl
+++ b/lustre/utils/llobdstat.pl
@@ -9,7 +9,7 @@ sub usage()
 {
     print STDERR "Usage: $pname <stats_file> [<interval>]\n";
     print STDERR "example: $pname help (to get help message)\n";
-    print STDERR "example: $pname ost1 1 (monitor /proc/fs/lustre/ost1/obd_stats once per second\n";
+    print STDERR "example: $pname ost1 1 (monitor /proc/fs/lustre/obdfilter/ost1/stats\n";
     exit 1;
 }
 
diff --git a/lustre/utils/lmc b/lustre/utils/lmc
index 1a1bbc99a51421a15550410a357ee39e69bd4690..f06a5bdd3cb620bdbbf2ed1aea1f63ebea92d65f 100755
--- a/lustre/utils/lmc
+++ b/lustre/utils/lmc
@@ -65,7 +65,6 @@ Object creation command summary:
   --port port
   --tcpbuf size
   --irq_affinity 0|1
-  --nid_exchange 0|1
   --router
 
 --add mds
@@ -75,6 +74,7 @@ Object creation command summary:
   --fstype extN|ext3
   --size size
   --nspath
+  --journal_size size
 
 --add lov
   --lov lov_name
@@ -83,22 +83,33 @@ Object creation command summary:
   --stripe_cnt num
   --stripe_pattern num
 
--add ost
+--add ost
   --node node_name
   --ost ost_name 
   --lov lov_name 
   --dev path
   --size size
   --fstype extN|ext3
+  --journal_size size
+  --obdtype obdecho|obdfilter
   --ostuuid uuid
-  --nspath
-  
+ 
 --add mtpt  - Mountpoint
   --node node_name
   --path /mnt/point
   --mds mds_name
   --ost ost_name OR --lov lov_name
 
+--add route
+  --node nodename
+  --gw nid
+  --tgt nid
+  --lo nid
+  --hi nid
+
+--add echo_client
+  --node nodename
+
 --add mgmt  - Management/monitoring service
   --node node_name
   --mgmt mgmt_service_name
@@ -129,7 +140,6 @@ lmc_options = [
     ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
     ('tcpbuf', "Optional argument to specify the TCP buffer size.", PARAM, "0"),
     ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
-    ('nid_exchange', "Optional argument to indicate if nid exchange should be done.", PARAM, 0),
     ('irq_affinity', "Optional argument.", PARAM, 0),
     ('hostaddr', "", PARAM,""),
     ('cluster_id', "Specify the cluster ID", PARAM, "0"),
@@ -153,6 +163,7 @@ lmc_options = [
     ('size', "Specify the size of the device if needed.", PARAM,"0"),
     ('journal_size', "Specify new journal size for underlying ext3 file system.", PARAM,"0"),
     ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
+    ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
     ('ostuuid', "", PARAM,""),
     ('nspath', "Local mount point of server namespace.", PARAM,""),
     ('format', ""),
@@ -274,7 +285,7 @@ class GenConfig:
         return new
 
     def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
-                port=0, tcpbuf=0, irq_aff=0, nid_xchg=0):
+                port=0, tcpbuf=0, irq_aff=0):
         """create <network> node"""
         network = self.newService("network", name, uuid)
         network.setAttribute("nettype", net);
@@ -289,8 +300,6 @@ class GenConfig:
             self.addElement(network, "recvmem", "%d" %(tcpbuf))
         if irq_aff:
             self.addElement(network, "irqaffinity", "%d" %(irq_aff))
-        if nid_xchg:
-            self.addElement(network, "nidexchange", "%d" %(nid_xchg))
             
         return network
 
@@ -384,7 +393,7 @@ class GenConfig:
         return mds
 
     def mdsdev(self, name, uuid, fs, devname, format, node_uuid,
-            mds_uuid, dev_size=0, journal_size=0, nspath=""):
+            mds_uuid, dev_size=0, journal_size=0, nspath="", mkfsoptions=""):
         mdd = self.newService("mdsdev", name, uuid)
         self.addElement(mdd, "fstype", fs)
         dev = self.addElement(mdd, "devpath", devname)
@@ -395,6 +404,8 @@ class GenConfig:
             self.addElement(mdd, "journalsize", "%s" % (journal_size))
         if nspath:
             self.addElement(mdd, "nspath", nspath)
+        if mkfsoptions:
+            self.addElement(mdd, "mkfsoptions", mkfsoptions)
         mdd.appendChild(self.ref("node", node_uuid))
         mdd.appendChild(self.ref("target", mds_uuid))
         return mdd
@@ -585,12 +596,10 @@ def add_net(gen, lustre, options):
         port = get_option_int(options, 'port')
         tcpbuf = get_option_int(options, 'tcpbuf')
         irq_aff = get_option_int(options, 'irq_affinity')
-        nid_xchg = get_option_int(options, 'nid_exchange')
     elif net_type in ('elan', 'gm', 'scimac'):
         port = 0
         tcpbuf = 0
         irq_aff = 0
-        nid_xchg = 0
     else:
         print "Unknown net_type: ", net_type
         sys.exit(2)
@@ -605,7 +614,7 @@ def add_net(gen, lustre, options):
     net_name = new_name('NET_'+ node_name +'_'+ net_type)
     net_uuid = new_uuid(net_name)
     node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
-                                 hostaddr, port, tcpbuf, irq_aff, nid_xchg))
+                                 hostaddr, port, tcpbuf, irq_aff))
     node_add_profile(gen, node, "network", net_uuid)
 
 
@@ -660,6 +669,7 @@ def add_mds(gen, lustre, options):
     fstype = get_option(options, 'fstype')
     journal_size = get_option(options, 'journal_size')
     nspath = get_option(options, 'nspath')
+    mkfsoptions = get_option(options, 'mkfsoptions')
 
     node_uuid = name2uuid(lustre, node_name, 'node')
 
@@ -671,7 +681,7 @@ def add_mds(gen, lustre, options):
 
     mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
                      get_format_flag(options), node_uuid, mds_uuid,
-                     size, journal_size, nspath)
+                     size, journal_size, nspath, mkfsoptions)
     lustre.appendChild(mdd)
                    
 
diff --git a/lustre/utils/lrun b/lustre/utils/lrun
new file mode 100755
index 0000000000000000000000000000000000000000..193a0621a3d43625d42c851e2e610aeb266d8efc
--- /dev/null
+++ b/lustre/utils/lrun
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+LIBLUSTRE_MOUNT_POINT=${LIBLUSTRE_MOUNT_POINT:-"/mnt/lustre"}
+LIBLUSTRE_MOUNT_TARGET=${LIBLUSTRE_MOUNT_TARGET:-""}
+LIBLUSTRE_DUMPFILE=${LIBLUSTRE_DUMPFILE:-"/tmp/DUMP_FILE"}
+LD_PRELOAD=${LD_PRELOAD:-"/usr/lib/liblustre.so"}
+
+export LIBLUSTRE_MOUNT_POINT
+export LIBLUSTRE_MOUNT_TARGET
+export LIBLUSTRE_DUMPFILE
+export LD_PRELOAD
+
+exec $@
diff --git a/lustre/utils/lstripe b/lustre/utils/lstripe
new file mode 100755
index 0000000000000000000000000000000000000000..51ebd795baa441c73605f2121c8f78c97afe9978
--- /dev/null
+++ b/lustre/utils/lstripe
@@ -0,0 +1,3 @@
+#!/bin/bash
+PATH=`dirname $0`:$PATH
+lfs setstripe "$@"
diff --git a/lustre/utils/lstripe.c b/lustre/utils/lstripe.c
deleted file mode 100644
index 2cdf5d251964aed0ac826ab33a3691f108a533f2..0000000000000000000000000000000000000000
--- a/lustre/utils/lstripe.c
+++ /dev/null
@@ -1,116 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-
-/****************** Custom includes ********************/
-#include <linux/lustre_lite.h>
-#include <linux/lustre_idl.h>
-
-
-/******************  Functions ******************/
-
-void usage(char *prog)
-{
-	fprintf(stderr, "usage: %s <filename> <stripe size> <stripe start> "
-			"<stripe count>\n", prog);
-
-	fprintf(stderr,
-		"\tstripe size: number of bytes in each stripe (0 default)\n");
-	fprintf(stderr,
-		"\tstripe start: OST index of first stripe (-1 default)\n");
-	fprintf(stderr,
-		"\tstripe count: number of OSTs to stripe over (0 default)\n");
-}
-
-int create_file(char *name, long stripe_size, int stripe_offset,
-		int stripe_count)
-{
-	struct lov_mds_md a_striping;
-	int fd, result = 0;
-
-	/*  Initialize IOCTL striping pattern structure  */
-	a_striping.lmm_magic = LOV_MAGIC;
-	a_striping.lmm_stripe_size = stripe_size;
-	a_striping.lmm_stripe_offset = stripe_offset;
-	a_striping.lmm_stripe_count = stripe_count;
-
-	fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
-	if (fd < 0) {
-		fprintf(stderr, "\nUnable to open '%s': %s\n",
-			name, strerror(errno));
-		result = -errno;
-	} else if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &a_striping)) {
-		char *errmsg = "stripe already set";
-
-		if (errno != EEXIST && errno != EALREADY)
-			errmsg = strerror(errno);
-
-		fprintf(stderr, "\nError on ioctl for '%s' (%d): %s\n",
-			name, fd, errmsg);
-		result = -errno;
-	} else if (close(fd) < 0) {
-		fprintf(stderr, "\nError on close for '%s' (%d): %s\n",
-			name, fd, strerror(errno));
-		result = -errno;
-	}
-
-	return result;
-}
-
-int main(int argc, char *argv[])
-{
-	int result;
-	long st_size;
-	int  st_offset,
-	     st_count;
-	char *end;
-
-	/*  Check to make sure we have enough parameters  */
-	if (argc != 5) {
-		usage(argv[0]);
-		return 1;
-	}
-
-	/* Get the stripe size */
-	st_size = strtoul(argv[2], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "bad stripe size '%s'\n", argv[2]);
-		usage(argv[0]);
-		return 2;
-	}
-
-	/*
-	if (st_size & 4095) {
-		fprintf(stderr, "stripe size must be multiple of page size\n");
-		usage(argv[0]);
-		return 3;
-	}
-	*/
-
-	/* Get the stripe offset*/
-	st_offset = strtoul(argv[3], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "bad stripe offset '%s'\n", argv[3]);
-		usage(argv[0]);
-		return 4;
-	}
-
-	/* Get the stripe count */
-	st_count = strtoul(argv[4], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "bad stripe count '%s'\n", argv[4]);
-		usage(argv[0]);
-		return 5;
-	}
-
-	/*  Create the file, as specified.  Return and display any errors.  */
-	result = create_file(argv[1], st_size, st_offset, st_count);
-
-	return result;
-}
diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c
new file mode 100644
index 0000000000000000000000000000000000000000..adbc384ffd62f7681ba21eb2a6ea0b2d7ff8b6b8
--- /dev/null
+++ b/lustre/utils/lustre_cfg.c
@@ -0,0 +1,536 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc.
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Robert Read <rread@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifndef __KERNEL__
+#include <liblustre.h>
+#endif
+#include <linux/lustre_lib.h>
+#include <linux/lustre_cfg.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_dlm.h>
+#include <linux/obd.h>          /* for struct lov_stripe_md */
+#include <linux/lustre_build_version.h>
+
+#include <unistd.h>
+#include <sys/un.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <string.h>
+
+
+#include "obdctl.h"
+#include <portals/ptlctl.h>
+#include "parser.h"
+#include <stdio.h>
+
+static char * lcfg_devname;
+
+void lcfg_set_devname(char *name)
+{
+	if (lcfg_devname)
+		free(lcfg_devname);
+	lcfg_devname = strdup(name);
+}
+
+
+int jt_lcfg_device(int argc, char **argv)
+{
+	char *name;
+
+        if (argc == 1) {
+		printf("current device is %s\n", lcfg_devname? : "not set");
+		return 0;
+	} else if (argc != 2) {
+                return CMD_HELP;
+	}
+
+	name = argv[1];
+
+	/* quietly strip the unnecessary '$' */
+	if (*name == '$')
+		name++;
+
+	lcfg_set_devname(name);
+
+        return 0;
+}
+
+/* NOOP */
+int jt_lcfg_newdev(int argc, char **argv)
+{
+        return 0;
+}
+
+int jt_lcfg_attach(int argc, char **argv)
+{
+        struct lustre_cfg lcfg;
+        int rc;
+
+        LCFG_INIT(lcfg, LCFG_ATTACH, lcfg_devname);
+
+        if (argc != 2 && argc != 3 && argc != 4)
+                return CMD_HELP;
+
+        lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+        lcfg.lcfg_inlbuf1 = argv[1];
+        if (argc >= 3) {
+                lcfg.lcfg_dev_namelen = strlen(argv[2]) + 1;
+                lcfg.lcfg_dev_name = argv[2];
+        } else {
+                fprintf(stderr, "error: %s: LCFG_ATTACH requires a name\n",
+                        jt_cmdname(argv[0])); 
+		return -EINVAL;
+	}
+
+        if (argc == 4) {
+                lcfg.lcfg_inllen2 = strlen(argv[3]) + 1;
+                lcfg.lcfg_inlbuf2 = argv[3];
+        }
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: LCFG_ATTACH %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+        } else if (argc == 3) {
+                char name[1024];
+
+		lcfg_set_devname(argv[2]);
+                if (strlen(argv[2]) > 128) {
+                        printf("Name too long to set environment\n");
+                        return -EINVAL;
+                }
+                snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
+                rc = setenv(name, argv[1], 1);
+                if (rc) {
+                        printf("error setting env variable %s\n", name);
+                }
+        } else {
+		lcfg_set_devname(argv[2]);
+	}
+
+        return rc;
+}
+
+int jt_lcfg_setup(int argc, char **argv)
+{
+        struct lustre_cfg lcfg;
+        int rc;
+
+        if (lcfg_devname == NULL) {
+                fprintf(stderr, "%s: please use 'cfg_device name' to set the "
+                        "device name for config commands.\n", 
+                        jt_cmdname(argv[0])); 
+		return -EINVAL;
+        }
+
+        LCFG_INIT(lcfg, LCFG_SETUP, lcfg_devname);
+
+        if (argc > 5)
+                return CMD_HELP;
+
+        if (argc > 1) {
+                lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+                lcfg.lcfg_inlbuf1 = argv[1];
+        }
+        if (argc > 2) {
+                lcfg.lcfg_inllen2 = strlen(argv[2]) + 1;
+                lcfg.lcfg_inlbuf2 = argv[2];
+        }
+        if (argc > 3) {
+                lcfg.lcfg_inllen3 = strlen(argv[3]) + 1;
+                lcfg.lcfg_inlbuf3 = argv[3];
+        }
+        if (argc > 4) {
+                lcfg.lcfg_inllen4 = strlen(argv[4]) + 1;
+                lcfg.lcfg_inlbuf4 = argv[4];
+        }
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0)
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+
+        return rc;
+}
+
+int jt_obd_detach(int argc, char **argv)
+{
+        struct lustre_cfg lcfg;
+        int rc;
+
+        if (lcfg_devname == NULL) {
+                fprintf(stderr, "%s: please use 'cfg_device name' to set the "
+                        "device name for config commands.\n", 
+                        jt_cmdname(argv[0])); 
+		return -EINVAL;
+        }
+
+        LCFG_INIT(lcfg, LCFG_DETACH, lcfg_devname);
+
+        if (argc != 1)
+                return CMD_HELP;
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0)
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+
+        return rc;
+}
+
+int jt_obd_cleanup(int argc, char **argv)
+{
+        struct lustre_cfg lcfg;
+        char force = 'F';
+        char failover = 'A';
+        char flags[3];
+        int flag_cnt = 0, n;
+        int rc;
+
+        if (lcfg_devname == NULL) {
+                fprintf(stderr, "%s: please use 'cfg_device name' to set the "
+                        "device name for config commands.\n", 
+                        jt_cmdname(argv[0])); 
+		return -EINVAL;
+        }
+
+        LCFG_INIT(lcfg, LCFG_CLEANUP, lcfg_devname);
+
+        if (argc < 1 || argc > 3)
+                return CMD_HELP;
+
+        for (n = 1; n < argc; n++) 
+                if (strcmp(argv[n], "force") == 0) {
+                        flags[flag_cnt++] = force;
+                } else if (strcmp(argv[n], "failover") == 0) {
+                        flags[flag_cnt++] = failover;
+                } else {
+                        fprintf(stderr, "unknown option: %s", argv[n]);
+                        return CMD_HELP;
+                }
+
+	lcfg.lcfg_inllen1 = flag_cnt;
+        if (flag_cnt)
+                lcfg.lcfg_inlbuf1 = flags;
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0)
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+
+        return rc;
+}
+
+static 
+int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal) 
+{
+        char tmp[64];
+        int rc;
+        struct lustre_cfg lcfg;
+
+        LCFG_INIT(lcfg, LCFG_ADD_UUID, lcfg_devname);
+        lcfg.lcfg_nid = nid;
+        lcfg.lcfg_inllen1 = strlen(uuid) + 1;
+        lcfg.lcfg_inlbuf1 = uuid;
+        lcfg.lcfg_nal = nal;
+
+        rc = lcfg_ioctl(func, OBD_DEV_ID, &lcfg);
+        if (rc) {
+                fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
+                        strerror(errno));
+                return -1;
+        }
+
+        printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid));
+        return 0;
+}
+
+int jt_lcfg_add_uuid(int argc, char **argv)
+{
+        ptl_nid_t nid = 0;
+        int nal;
+        
+        if (argc != 4) {                
+                return CMD_HELP;
+        }
+
+        if (ptl_parse_nid (&nid, argv[2]) != 0) {
+                fprintf (stderr, "Can't parse NID %s\n", argv[2]);
+                        return (-1);
+        }
+
+        nal = ptl_name2nal(argv[3]);
+
+        if (nal <= 0) {
+                fprintf (stderr, "Can't parse NAL %s\n", argv[3]);
+                return -1;
+        }
+
+        return do_add_uuid(argv[0], argv[1], nid, nal);
+}
+
+int obd_add_uuid(char *uuid, ptl_nid_t nid, int nal)
+{
+        return do_add_uuid("obd_add_uuid", uuid, nid, nal);
+}
+
+int jt_lcfg_del_uuid(int argc, char **argv)
+{
+        int rc;
+        struct lustre_cfg lcfg;
+
+        if (argc != 2) {
+                fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
+                return 0;
+        }
+
+        LCFG_INIT(lcfg, LCFG_DEL_UUID, lcfg_devname);
+
+        if (strcmp (argv[1], "_all_"))
+        {
+                lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+                lcfg.lcfg_inlbuf1 = argv[1];
+        }
+        
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc) {
+                fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
+                        strerror(errno));
+                return -1;
+        }
+        return 0;
+}
+
+int jt_lcfg_lov_setup(int argc, char **argv)
+{
+        struct lustre_cfg lcfg;
+        struct lov_desc desc;
+        struct obd_uuid *uuidarray, *ptr;
+        int rc, i;
+        char *end;
+
+        LCFG_INIT(lcfg, LCFG_SETUP, lcfg_devname);
+
+        if (argc <= 6)
+                return CMD_HELP;
+
+        if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
+                fprintf(stderr,
+                        "error: %s: LOV uuid '%s' longer than "LPSZ" chars\n",
+                        jt_cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
+                return -EINVAL;
+        }
+
+        memset(&desc, 0, sizeof(desc));
+        obd_str2uuid(&desc.ld_uuid, argv[1]);
+        desc.ld_tgt_count = argc - 6;
+        desc.ld_default_stripe_count = strtoul(argv[2], &end, 0);
+        if (*end) {
+                fprintf(stderr, "error: %s: bad default stripe count '%s'\n",
+                        jt_cmdname(argv[0]), argv[2]);
+                return CMD_HELP;
+        }
+        if (desc.ld_default_stripe_count > desc.ld_tgt_count) {
+                fprintf(stderr,
+                        "error: %s: default stripe count %u > OST count %u\n",
+                        jt_cmdname(argv[0]), desc.ld_default_stripe_count,
+                        desc.ld_tgt_count);
+                return -EINVAL;
+        }
+
+        desc.ld_default_stripe_size = strtoull(argv[3], &end, 0);
+        if (*end) {
+                fprintf(stderr, "error: %s: bad default stripe size '%s'\n",
+                        jt_cmdname(argv[0]), argv[3]);
+                return CMD_HELP;
+        }
+        if (desc.ld_default_stripe_size < 4096) {
+                fprintf(stderr,
+                        "error: %s: default stripe size "LPU64" too small\n",
+                        jt_cmdname(argv[0]), desc.ld_default_stripe_size);
+                return -EINVAL;
+        } else if ((long)desc.ld_default_stripe_size <
+                   desc.ld_default_stripe_size) {
+                fprintf(stderr,
+                        "error: %s: default stripe size "LPU64" too large\n",
+                        jt_cmdname(argv[0]), desc.ld_default_stripe_size);
+                return -EINVAL;
+        }
+        desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0);
+        if (*end) {
+                fprintf(stderr, "error: %s: bad default stripe offset '%s'\n",
+                        jt_cmdname(argv[0]), argv[4]);
+                return CMD_HELP;
+        }
+        desc.ld_pattern = strtoul(argv[5], &end, 0);
+        if (*end) {
+                fprintf(stderr, "error: %s: bad stripe pattern '%s'\n",
+                        jt_cmdname(argv[0]), argv[5]);
+                return CMD_HELP;
+        }
+
+        /* NOTE: it is possible to overwrite the default striping parameters,
+         *       but EXTREME care must be taken when saving the OST UUID list.
+         *       It must be EXACTLY the same, or have only additions at the
+         *       end of the list, or only overwrite individual OST entries
+         *       that are restored from backups of the previous OST.
+         */
+        uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
+        if (!uuidarray) {
+                fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
+                        jt_cmdname(argv[0]), desc.ld_tgt_count);
+                rc = -ENOMEM;
+                goto out;
+        }
+        for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) {
+                if (strlen(argv[i]) >= sizeof(*ptr)) {
+                        fprintf(stderr, "error: %s: arg %d (%s) too long\n",
+                                jt_cmdname(argv[0]), i, argv[i]);
+                        rc = -EINVAL;
+                        goto out;
+                }
+                strcpy((char *)ptr, argv[i]);
+        }
+
+        lcfg.lcfg_inllen1 = sizeof(desc);
+        lcfg.lcfg_inlbuf1 = (char *)&desc;
+        lcfg.lcfg_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
+        lcfg.lcfg_inlbuf2 = (char *)uuidarray;
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc)
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+out:
+        free(uuidarray);
+        return rc;
+}
+
+int jt_lcfg_mount_option(int argc, char **argv)
+{
+        int rc;
+        struct lustre_cfg lcfg;
+
+        LCFG_INIT(lcfg, LCFG_MOUNTOPT, lcfg_devname);
+
+        if (argc < 3 || argc > 4)
+                return CMD_HELP;
+
+        /* profile name */
+        lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+        lcfg.lcfg_inlbuf1 = argv[1];
+        /* osc name */
+        lcfg.lcfg_inllen2 = strlen(argv[2]) + 1;
+        lcfg.lcfg_inlbuf2 = argv[2];
+        if (argc == 4) {
+                /* mdc name */
+                lcfg.lcfg_inllen3 = strlen(argv[3]) + 1;
+                lcfg.lcfg_inlbuf3 = argv[3];
+        }
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+        }
+
+        return rc;
+}
+
+int jt_lcfg_del_mount_option(int argc, char **argv)
+{
+        int rc;
+        struct lustre_cfg lcfg;
+
+        LCFG_INIT(lcfg, LCFG_DEL_MOUNTOPT, lcfg_devname);
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        /* profile name */
+        lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+        lcfg.lcfg_inlbuf1 = argv[1];
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+        }
+
+        return rc;
+}
+
+int jt_lcfg_set_timeout(int argc, char **argv)
+{
+        int rc;
+        struct lustre_cfg lcfg;
+
+        LCFG_INIT(lcfg, LCFG_SET_TIMEOUT, lcfg_devname);
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        lcfg.lcfg_num = atoi(argv[1]);
+        
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+        }
+
+        return rc;
+}
+
+
+int jt_lcfg_set_lustre_upcall(int argc, char **argv)
+{
+        int rc;
+        struct lustre_cfg lcfg;
+
+        LCFG_INIT(lcfg, LCFG_SET_UPCALL, lcfg_devname);
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        /* profile name */
+        lcfg.lcfg_inllen1 = strlen(argv[1]) + 1;
+        lcfg.lcfg_inlbuf1 = argv[1];
+
+        rc = lcfg_ioctl(argv[0], OBD_DEV_ID, &lcfg);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+                        strerror(rc = errno));
+        }
+
+        return rc;
+}
+
diff --git a/lustre/utils/lwizard b/lustre/utils/lwizard
new file mode 100755
index 0000000000000000000000000000000000000000..4938f95e84ee09d1340a0f441a0f27f8ff11b39f
--- /dev/null
+++ b/lustre/utils/lwizard
@@ -0,0 +1,398 @@
+#!/bin/sh
+# Copyright (C) 2003  Cluster File Systems, Inc.
+# Create a Lustre configuration file
+#
+# Usage: lwizard
+#
+# Jerrifer <jerrifer@clusterfs.com>
+# wangdi <wangdi@clusterfs.com>
+
+# fatal error to exit
+fatal()
+{
+    if [ "$#" -gt "1" ]; then
+	echo
+	echo "$2"
+	exit 1
+    fi
+
+    exit 1
+}
+
+#print usage and exit 
+usage()
+{
+    cat <<EOF
+Usage: ${0##*/} [OPTIONS]...
+
+${0##*/} asks the user questions about their cluster configuration,
+and writes an appropriate configuration file to config.xml.
+
+Options:
+    --batch=FILE
+	save lmc batch commands to FILE
+    -o, --file=FILE
+	write Lustre configuration to FILE (default: lwizard.xml)
+    -f, --force
+	force existing files to be overwritten
+    --help
+	to get this help
+    --stripe_size=SIZE
+	size (in KB) of each stripe on an OST (default: 64)
+    --stripe_count=COUNT
+	the number of OSTs files are striped to (default: 1)
+EOF
+
+    exit 0     
+}
+
+# check if $1 is a number
+check_number()
+{
+    local num=$(expr "$1" : "[0-9]*$")
+    if [ $num -gt "0" ]; then 
+	return 0 
+    fi
+
+    return 1
+}
+
+# parse options of this shell
+LMC_BATCH_FILE=
+RM_BATCH_FILE=1
+FORCE=0
+get_option()
+{
+    local long_options="batch:,file:,force:,help,stripe_size:,stripe_count:"
+    local options
+
+    options=$(getopt -o o:hf --long "$long_options" -- "$@")
+
+    if [ $? -ne 0 ] ; then
+	usage
+    fi
+    eval set -- "$options"
+
+    while true ; do
+	case "$1" in
+	    --batch)
+		LMC_BATCH_FILE=$2
+		RM_BATCH_FILE=0
+		shift 2
+		;;
+	    -o | --file)
+		CONFIG_FILE=$2
+		shift 2
+		;;
+	    -f | --force)
+		FORCE=1
+		shift
+		;;
+	    --stripe_count)
+		STRIPE_CNT=$2
+		check_number $STRIPE_CNT || \
+		    fatal 1 "Stripe count should be a number."
+		shift 2
+		;;
+	    --stripe_size)
+		STRIPE_SIZE=$(($2 * 1024))
+		check_number $STRIPE_SIZE || \
+		    fatal 1 "Stripe size should be a number."
+		shift 2
+		;;
+	    -h | --help)
+		usage
+		;;
+	    --)
+		shift 1
+		break
+	esac
+    done 
+}
+
+# if $1 in $2
+in_list()
+{
+    local node
+
+    for node in $2 ; do
+	[ "$1" = "$node" ] && return 0
+	done
+	return 1
+    }
+
+# read device size from user and check devive size and convert device
+# size to *K
+
+get_device_size()
+{
+    local size 
+    local tail
+
+    read size 
+    if [ -z $size ]; then 
+	device_size="0"
+	return 0
+    fi 
+
+    device_size=$(echo $size | awk -F[a-z,A-Z] '{print $1; }')
+    [ -z $device_size ] && return 1
+    tail=$(echo $size | awk -F$device_size '{print $2; }')
+    [ -z $tail ] && return 0
+    case $tail in
+	k | K)
+	    ;;
+        m | M)
+	    (( device_size *= 1024 ))
+	    ;;
+	t | T)
+	    (( device_size *= (1024 * 1024) ))
+	    ;;
+	*)
+	    return 1
+	    ;;
+	esac
+
+    return 0
+}
+
+# ask user some questions to add a device 
+add_device()
+{
+    local hostnames
+    local device
+    local device_size
+
+    echo "Creating $1 \"$1$2\"..."
+    if [ "$2" -gt "1" ]; then 
+	echo -n "Please enter the hostname(s) for $1$2, or just hit enter to finish: "
+    else
+	echo -n "Please enter the hostname(s) for $1$2: "
+    fi
+    read hostnames
+
+    if [ -z "$hostnames" ] ; then
+	return 1
+    fi
+
+    for hostname in $hostnames ; do
+	device=
+	while [ -z "$device" ] ; do
+	    echo -n "Please enter the device or loop file name for $1$2 on ${hostname}: "
+	    read device
+	    echo -n "Please enter the device size or 0 to use entire device: "
+	    while ! get_device_size ; do
+	       echo -n "Please enter the device size or 0 to use entire device: "
+	    done
+	done
+	newdev="$hostname:$device:$2:$1$2:$CURRENT_MDS:$CURRENT_LOV:$device_size"
+	DEVICE_LIST="$DEVICE_LIST $newdev"
+    done
+
+    return 0 
+}
+
+cur_mds_id=1
+
+# get mds information
+add_mds()
+{
+    CURRENT_LOV=
+    CURRENT_MDS=
+    add_device "mds" "$cur_mds_id" || return 1 
+    CURRENT_LOV="lov$cur_mds_id"
+    CURRENT_MDS="mds$cur_mds_id"
+
+    DEVICE_LIST="$DEVICE_LIST *:*:lov:$CURRENT_LOV:$CURRENT_MDS:*:"
+
+    (( cur_mds_id++ ))
+    return 0
+}
+
+cur_ost_id=1
+
+# ask user to add ost 
+add_ost()
+{
+    # We have to add one...
+    while ! add_device "ost" "$cur_ost_id" ; do
+	true
+    done
+
+    (( cur_ost_id++ ))
+
+    # ...and maybe more
+    while add_device "ost" "$cur_ost_id" ; do
+	    (( cur_ost_id++ ))
+    done
+    return 0
+}
+
+cur_cli_id=1
+
+# ask user to add client to lustre
+add_client()
+{
+    echo -n "Please enter the clients' mountpoint (/mnt/lustre): "
+    read mtpt
+    [ -z "$mtpt" ] && mtpt="/mnt/lustre"
+    newdev="*:$mtpt:client:client:$CURRENT_MDS:$CURRENT_LOV"
+    DEVICE_LIST="$DEVICE_LIST $newdev"
+    (( cur_cli_id++ ))
+    return 0
+}
+
+# save node config into config file 
+add_node()
+{
+    local node=$1
+    local nettype=$DEFAULT_NETTYPE
+
+    in_list "$node" "$NODE_LIST" && return 0 
+    NODE_LIST="$NODE_LIST $node" 
+
+    run_lmc --add node --node "$node"
+    run_lmc --add net --node "$node" --nid "$node"  \
+	--nettype "$nettype"
+
+    return 0 
+} 
+
+# get hostname, device , device_id and device name 
+# from mds node 
+get_name_in_list()
+{
+    HOST_NAME=$(echo $1 | awk -F: '{ print $1 }')
+    DEVICE=$(echo $1 | awk -F: '{ print $2 }')
+    DEVICE_ID=$(echo $1 | awk -F: '{ print $3 }')
+    DEVICE_NAME=$(echo $1 | awk -F: '{ print $4 }')
+    DEVICE_MDS=$(echo $1 | awk -F: '{ print $5 }')
+    DEVICE_LOV=$(echo $1 | awk -F: '{ print $6 }')
+    DEVICE_SIZE=$(echo $1 | awk -F: '{ print $7 }')
+}
+
+# save command to file and do the command 
+run_lmc()
+{
+    echo "$@" >> "$LMC_BATCH_FILE"
+}
+
+# following user input to create xml config file 
+create_config()
+{
+    for device in $DEVICE_LIST ; do
+	get_name_in_list $device
+	echo -n " $DEVICE_NAME"
+	case $DEVICE_NAME in
+	    mds*)
+		add_node "$HOST_NAME"
+		run_lmc --add mds \
+		    --node "$HOST_NAME" \
+		    --mds "$DEVICE_NAME" \
+		    --fstype "$DEFAULT_FSTYPE" \
+		    --dev "$DEVICE" \
+		    --size "$DEVICE_SIZE"
+		;;
+	    lov*)
+		run_lmc --add lov \
+		    --lov "$DEVICE_NAME" \
+		    --mds "$DEVICE_MDS" \
+		    --stripe_sz "$STRIPE_SIZE" \
+		    --stripe_cnt "$STRIPE_CNT" \
+		    --stripe_pattern "$STRIPE_PATTERN"
+		;;
+	    ost*)
+		add_node "$HOST_NAME"
+		run_lmc --add ost \
+		    --node "$HOST_NAME" \
+		    --lov "$DEVICE_LOV" \
+		    --fstype "$DEFAULT_FSTYPE" \
+		    --dev "$DEVICE" \
+		    --size "$DEVICE_SIZE"
+		;;
+	    client*)
+		add_node "$DEVICE_NAME"
+		run_lmc --add mtpt \
+		    --node "$DEVICE_NAME" \
+		    --mds "$DEVICE_MDS" \
+		    --lov "$DEVICE_LOV" \
+		    --path "$DEVICE"
+		;;
+	esac
+    done
+    echo
+    return 0
+}
+
+maybe_clean()
+{
+    [ -f "$1" ] || return 0
+    if ! (( $FORCE )) ; then
+	echo -n "${0##*/}: overwrite existing $2 \"$1\"? "
+	read answer
+	if ! [ "${answer:0:1}" = "y" -o "${answer:0:1}" = "Y" ] ; then
+	    echo "(${0##*/}: (Exiting.)"
+	    exit 0
+	fi
+    fi
+    rm -f "$1"
+}
+
+# parse options 
+get_option "$@"
+
+# some default definitions
+LMC=${LMC:-"/usr/sbin/lmc"}
+
+CONFIG_FILE=${CONFIG_FILE:-"lwizard.xml"}
+
+# Remove exiting files.
+
+maybe_clean "$CONFIG_FILE" "Lustre configuration file"
+if [ "$LMC_BATCH_FILE" ] ; then
+    maybe_clean "$LMC_BATCH_FILE" "lmc batch file"
+else
+    LMC_BATCH_FILE=$(mktemp -q "/tmp/${CONFIG_FILE##*/}.XXXXXX")
+    [ $? -eq 0 ] || fatal 1 "Couldn't create temporary batch file."
+fi
+
+DEFAULT_FSTYPE=${DEFAULT_FSTYPE:-"ext3"}
+DEFAULT_NETTYPE=${DEFAULT_NETTYPE:-"tcp"}
+DEFAULT_MNTPT=${DEFAULT_MNTPT:-"/mnt/lustre"}
+
+STRIPE_SIZE=${STRIPE_SIZE:-$((1 * 1024 * 1024))}
+STRIPE_CNT=${STRIPE_CNT:-1}
+STRIPE_PATTERN=${STRIPE_PATTERN:-0}
+
+ANSWER="yes no"
+
+CURRENT_LOV=
+MDS_LIST=
+OST_LIST=
+CLIENT_LIST=
+
+# print program information
+cat <<EOF
+${0##*/} will help you create a Lustre configuration file.
+
+EOF
+while add_mds ; do
+    add_ost
+    add_client
+done
+
+create_config
+$LMC --batch "$LMC_BATCH_FILE" -o "$CONFIG_FILE"
+if [ $? -ne 0 ] ; then
+    fatal 1 "lmc returned an error; Please check above for more details."
+fi
+
+echo "The Lustre configuration has been written to $CONFIG_FILE."
+
+if (( $RM_BATCH_FILE )) ; then
+    rm -f "$LMC_BATCH_FILE"
+else
+    echo "The lmc batch file has been written to $LMC_BATCH_FILE."
+fi
+
+exit 0
diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c
index 754de0d634add0e13642f676aece7f2df2016708..4ff1326822fd73f1440405175b6fe2ff599a969a 100644
--- a/lustre/utils/obd.c
+++ b/lustre/utils/obd.c
@@ -36,12 +36,8 @@
 #include <stdarg.h>
 #include <signal.h>
 
-#ifndef __KERNEL__
-#include <liblustre.h>
-#endif
-#include <linux/lustre_lib.h>
-#include <linux/lustre_idl.h>
-#include <linux/lustre_dlm.h>
+#include "obdctl.h"
+
 #include <linux/obd.h>          /* for struct lov_stripe_md */
 #include <linux/lustre_build_version.h>
 
@@ -58,7 +54,6 @@
 #include <linux/list.h>
 #undef __KERNEL__
 
-#include "obdctl.h"
 #include <portals/ptlctl.h>
 #include "parser.h"
 #include <stdio.h>
@@ -74,10 +69,11 @@ static long long counter_snapshot[2][MAX_SHMEM_COUNT];
 struct timeval prev_time;
 #endif
 
-uint64_t conn_cookie = -1;
-char rawbuf[8192];
-char *buf = rawbuf;
-int max = sizeof(rawbuf);
+static int jt_recording;
+static uint64_t conn_cookie = -1;
+static char rawbuf[8192];
+static char *buf = rawbuf;
+static int max = sizeof(rawbuf);
 
 static int thread;
 
@@ -86,7 +82,15 @@ union lsm_buffer {
         struct lov_stripe_md lsm;
 } lsm_buffer;
 
-static char *cmdname(char *func);
+static int l2_ioctl(int dev_id, int opc, void *buf)
+{
+//        if (jt_recording) {
+//                struct obd_ioctl_data *data = buf;
+//                data->ioc_command = opc;
+//                opc = OBD_IOC_DORECORD;
+//        }
+        return l_ioctl(dev_id, opc, buf);
+}
 
 #define IOC_INIT(data)                                                  \
 do {                                                                    \
@@ -99,7 +103,7 @@ do {                                                                    \
         memset(buf, 0, sizeof(rawbuf));                                 \
         if (obd_ioctl_pack(&data, &buf, max)) {                         \
                 fprintf(stderr, "error: %s: invalid ioctl\n",           \
-                        cmdname(func));                                 \
+                        jt_cmdname(func));                                 \
                 return -2;                                              \
         }                                                               \
 } while (0)
@@ -108,11 +112,58 @@ do {                                                                    \
 do {                                                                    \
         if (obd_ioctl_unpack(&data, buf, max)) {                        \
                 fprintf(stderr, "error: %s: invalid reply\n",           \
-                        cmdname(func));                                 \
+                        jt_cmdname(func));                                 \
                 return -2;                                              \
         }                                                               \
 } while (0)
 
+int obd_record(enum cfg_record_type type, int len, void *ptr)
+{
+        struct obd_ioctl_data data;
+
+        IOC_INIT(data);
+        data.ioc_type = type;
+        data.ioc_plen1 = len;
+        data.ioc_pbuf1 = ptr;
+        IOC_PACK("obd_record", data);
+
+        return  l_ioctl(OBD_DEV_ID, OBD_IOC_DORECORD, &data);
+}
+
+int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg)
+{
+        int opc;
+        char lcfg_rawbuf[8192];
+        char * lcfg_buf= lcfg_rawbuf;
+        struct obd_ioctl_data data;
+        int len;
+        int rc;
+
+        memset(lcfg_buf, 0, sizeof(lcfg_rawbuf));
+        if (lustre_cfg_pack(lcfg, &lcfg_buf, sizeof(lcfg_rawbuf), &len)) {
+                fprintf(stderr, "error: %s: invalid ioctl\n",
+                        jt_cmdname(func));
+                return -2;
+        }
+
+        IOC_INIT(data);
+        data.ioc_type = LUSTRE_CFG_TYPE;
+        data.ioc_plen1 = len;
+        data.ioc_pbuf1 = lcfg_buf;
+        IOC_PACK(func, data);
+
+        if (jt_recording)
+                opc = OBD_IOC_DORECORD;
+        else
+                opc = OBD_IOC_PROCESS_CFG;
+
+        rc =  l_ioctl(dev_id, opc, buf);
+        if (rc == 0)
+                rc = lustre_cfg_unpack(lcfg, lcfg_buf, sizeof(lcfg_rawbuf));
+
+        return rc;
+}
+
 char *obdo_print(struct obdo *obd)
 {
         char buf[1024];
@@ -144,7 +195,7 @@ static int do_name2dev(char *func, char *name)
         data.ioc_inlbuf1 = name;
 
         IOC_PACK(func, data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NAME2DEV, buf);
         if (rc < 0)
                 return errno;
         IOC_UNPACK(func, data);
@@ -156,7 +207,7 @@ static int do_name2dev(char *func, char *name)
  * resolve a device name to a device number.
  * supports a number, $name or %uuid.
  */
-static int parse_devname(char *func, char *name)
+int parse_devname(char *func, char *name)
 {
         int rc;
         int ret = -1;
@@ -200,15 +251,15 @@ lsm_string (struct lov_stripe_md *lsm)
         space -= nob;
 
         if (lsm->lsm_stripe_count != 0) {
-                nob = snprintf (p, space, "=%u#%u@%d",
+                nob = snprintf (p, space, "=%u#%u",
                                 lsm->lsm_stripe_size,
-                                lsm->lsm_stripe_count,
-                                lsm->lsm_stripe_offset);
+                                lsm->lsm_stripe_count);
                 p += nob;
                 space -= nob;
 
                 for (i = 0; i < lsm->lsm_stripe_count; i++) {
-                        nob = snprintf (p, space, ":"LPX64,
+                        nob = snprintf (p, space, "@%u:"LPX64,
+                                        lsm->lsm_oinfo[i].loi_ost_idx,
                                         lsm->lsm_oinfo[i].loi_id);
                         p += nob;
                         space -= nob;
@@ -238,7 +289,7 @@ parse_lsm (union lsm_buffer *lsmb, char *string)
         int                   i;
 
         /*
-         * object_id[=size#count[@offset][:id]*]
+         * object_id[=size#count[@offset:id]*]
          */
 
         reset_lsmb (lsmb);
@@ -269,22 +320,18 @@ parse_lsm (union lsm_buffer *lsmb, char *string)
                 return (-1);
         string = end;
 
-        if (*string == '@') {
-                string++;
-                lsm->lsm_stripe_offset = strtol (string, &end, 0);
-                if (end == string)
-                        return (-1);
-                string = end;
-        }
-
         if (*string == 0)               /* don't have to specify obj ids */
                 return (0);
 
         for (i = 0; i < lsm->lsm_stripe_count; i++) {
-                if (*string != ':')
+                if (*string != '@')
                         return (-1);
                 string++;
-                lsm->lsm_oinfo[i].loi_id = strtoull (string, &end, 0);
+                lsm->lsm_oinfo[i].loi_ost_idx = strtoul(string, &end, 0);
+                if (*end != ':')
+                        return (-1);
+                string = end + 1;
+                lsm->lsm_oinfo[i].loi_id = strtoull(string, &end, 0);
                 string = end;
         }
 
@@ -294,7 +341,7 @@ parse_lsm (union lsm_buffer *lsmb, char *string)
         return (0);
 }
 
-static char *cmdname(char *func)
+char *jt_cmdname(char *func)
 {
         static char buf[512];
 
@@ -306,9 +353,9 @@ static char *cmdname(char *func)
         return func;
 }
 
-#define difftime(a, b)                                          \
-        ((double)(a)->tv_sec - (b)->tv_sec +                    \
-         ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
+#define difftime(a, b)                                  \
+        ((a)->tv_sec - (b)->tv_sec +                    \
+         ((a)->tv_usec - (b)->tv_usec) / 1000000.0)
 
 static int be_verbose(int verbose, struct timeval *next_time,
                       __u64 num, __u64 *next_num, int num_total)
@@ -333,7 +380,8 @@ static int be_verbose(int verbose, struct timeval *next_time,
         }
 
         /* A negative verbosity means to print at most each X seconds */
-        if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){
+        if (verbose < 0 && next_time != NULL &&
+            difftime(&now, next_time) >= 0.0){
                 next_time->tv_sec = now.tv_sec - verbose;
                 next_time->tv_usec = now.tv_usec;
                 if (next_num)
@@ -357,7 +405,7 @@ static int get_verbose(char *func, const char *arg)
                 verbose = (int)strtoul(arg, &end, 0);
                 if (*end) {
                         fprintf(stderr, "error: %s: bad verbose option '%s'\n",
-                                cmdname(func), arg);
+                                jt_cmdname(func), arg);
                         return BAD_VERBOSE;
                 }
         }
@@ -374,27 +422,7 @@ static int get_verbose(char *func, const char *arg)
 
 int do_disconnect(char *func, int verbose)
 {
-        int rc;
-        struct obd_ioctl_data data;
-
-        if (conn_cookie == -1)
-                return 0;
-
-        IOC_INIT(data);
-
-        IOC_PACK(func, data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DISCONNECT, buf);
-        if (rc < 0) {
-                fprintf(stderr, "error: %s: OPD_IOC_DISCONNECT %s\n",
-                        cmdname(func),strerror(errno));
-        } else {
-                if (verbose)
-                        printf("%s: disconnected conn "LPX64"\n", cmdname(func),
-                               conn_cookie);
-                conn_cookie = -1;
-        }
-
-        return rc;
+        return 0;
 }
 
 #if SHMEM_STATS
@@ -503,7 +531,7 @@ static int do_device(char *func, int dev)
         data.ioc_dev = dev;
 
         IOC_PACK(func, data);
-        return l_ioctl(OBD_DEV_ID, OBD_IOC_DEVICE, buf);
+        return l2_ioctl(OBD_DEV_ID, OBD_IOC_DEVICE, buf);
 }
 
 int jt_obd_device(int argc, char **argv)
@@ -520,7 +548,7 @@ int jt_obd_device(int argc, char **argv)
 
         rc = do_device(argv[0], dev);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
 
         return rc;
@@ -540,11 +568,11 @@ int jt_obd_connect(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CONNECT, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CONNECT, buf);
         IOC_UNPACK(argv[0], data);
         if (rc < 0)
                 fprintf(stderr, "error: %s: OBD_IOC_CONNECT %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         else
                 conn_cookie = data.ioc_cookie;
         return rc;
@@ -602,7 +630,7 @@ int jt_opt_threads(int argc, char **argv)
         threads = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid page count '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -696,62 +724,6 @@ int jt_opt_net(int argc, char **argv)
         return rc;
 }
 
-int jt_obd_detach(int argc, char **argv)
-{
-        struct obd_ioctl_data data;
-        int rc;
-
-        IOC_INIT(data);
-
-        if (argc != 1)
-                return CMD_HELP;
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DETACH, buf);
-        if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
-                        strerror(rc = errno));
-
-        return rc;
-}
-
-int jt_obd_cleanup(int argc, char **argv)
-{
-        struct obd_ioctl_data data;
-        char force = 'F';
-        char failover = 'A';
-        char flags[3];
-        int flag_cnt = 0, n;
-        int rc;
-
-        IOC_INIT(data);
-
-        if (argc < 1 || argc > 3)
-                return CMD_HELP;
-
-        for (n = 1; n < argc; n++) 
-                if (strcmp(argv[n], "force") == 0) {
-                        flags[flag_cnt++] = force;
-                } else if (strcmp(argv[n], "failover") == 0) {
-                        flags[flag_cnt++] = failover;
-                } else {
-                        fprintf(stderr, "unknown option: %s", argv[n]);
-                        return CMD_HELP;
-                }
-
-        data.ioc_inllen1 = flag_cnt;
-        if (flag_cnt)
-                data.ioc_inlbuf1 = flags;
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLEANUP, buf);
-        if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
-                        strerror(rc = errno));
-
-        return rc;
-}
-
 int jt_obd_no_transno(int argc, char **argv)
 {
         struct obd_ioctl_data data;
@@ -763,9 +735,9 @@ int jt_obd_no_transno(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_NO_TRANSNO, buf);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
 
         return rc;
@@ -782,9 +754,9 @@ int jt_obd_set_readonly(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SET_READONLY, buf);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
 
         return rc;
@@ -801,56 +773,10 @@ int jt_obd_abort_recovery(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf);
-        if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
-                        strerror(rc = errno));
-
-        return rc;
-}
-
-int jt_obd_newdev(int argc, char **argv)
-{
-        int rc;
-        struct obd_ioctl_data data;
-
-        IOC_INIT(data);
-
-        if (argc != 1)
-                return CMD_HELP;
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NEWDEV, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
-        else {
-                IOC_UNPACK(argv[0], data);
-                printf("Current device set to %d\n", data.ioc_dev);
-        }
-
-        return rc;
-}
-
-int jt_obd_mount_option(int argc, char **argv)
-{
-        int rc;
-        struct obd_ioctl_data data;
-
-        IOC_INIT(data);
-
-        if (argc != 2)
-                return CMD_HELP;
-
-        data.ioc_inllen1 = strlen(argv[1]) + 1;
-        data.ioc_inlbuf1 = argv[1];
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_MOUNTOPT, buf);
-        if (rc < 0) {
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
-                        strerror(rc = errno));
-        }
 
         return rc;
 }
@@ -870,9 +796,9 @@ int jt_get_version(int argc, char **argv)
         data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
         data->ioc_len = obd_ioctl_packlen(data);
 
-        rc = l_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_GET_VERSION, buf);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
         else {
                 printf("Lustre version: %s\n", data->ioc_bulk);
@@ -885,7 +811,7 @@ int jt_get_version(int argc, char **argv)
 int jt_obd_list(int argc, char **argv)
 {
         int rc;
-        char buf[8192];
+        char buf[OBD_MAX_IOCTL_BUFFER];
         struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
 
         if (argc != 1)
@@ -897,9 +823,9 @@ int jt_obd_list(int argc, char **argv)
         data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data));
         data->ioc_len = obd_ioctl_packlen(data);
 
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_LIST, data);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
         else {
                 printf("%s", data->ioc_bulk);
@@ -908,89 +834,6 @@ int jt_obd_list(int argc, char **argv)
         return rc;
 }
 
-int jt_obd_attach(int argc, char **argv)
-{
-        struct obd_ioctl_data data;
-        int rc;
-
-        IOC_INIT(data);
-
-        if (argc != 2 && argc != 3 && argc != 4)
-                return CMD_HELP;
-
-        data.ioc_inllen1 = strlen(argv[1]) + 1;
-        data.ioc_inlbuf1 = argv[1];
-        if (argc >= 3) {
-                data.ioc_inllen2 = strlen(argv[2]) + 1;
-                data.ioc_inlbuf2 = argv[2];
-        }
-
-        if (argc == 4) {
-                data.ioc_inllen3 = strlen(argv[3]) + 1;
-                data.ioc_inlbuf3 = argv[3];
-        }
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ATTACH, buf);
-        if (rc < 0)
-                fprintf(stderr, "error: %s: OBD_IOC_ATTACH %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
-        else if (argc == 3) {
-                char name[1024];
-                if (strlen(argv[2]) > 128) {
-                        printf("Name too long to set environment\n");
-                        return -EINVAL;
-                }
-                snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]);
-                rc = setenv(name, argv[1], 1);
-                if (rc) {
-                        printf("error setting env variable %s\n", name);
-                }
-        }
-
-        return rc;
-}
-
-int jt_obd_setup(int argc, char **argv)
-{
-        struct obd_ioctl_data data;
-        int rc;
-
-        IOC_INIT(data);
-
-        if (argc > 5)
-                return CMD_HELP;
-
-        data.ioc_dev = -1;
-        if (argc > 1) {
-                data.ioc_dev = parse_devname(argv[0], argv[1]);
-                if (data.ioc_dev < 0)
-                        return -1;
-                data.ioc_inllen1 = strlen(argv[1]) + 1;
-                data.ioc_inlbuf1 = argv[1];
-        }
-        if (argc > 2) {
-                data.ioc_inllen2 = strlen(argv[2]) + 1;
-                data.ioc_inlbuf2 = argv[2];
-        }
-        if (argc > 3) {
-                data.ioc_inllen3 = strlen(argv[3]) + 1;
-                data.ioc_inlbuf3 = argv[3];
-        }
-        if (argc > 4) {
-                data.ioc_inllen4 = strlen(argv[4]) + 1;
-                data.ioc_inlbuf4 = argv[4];
-        }
-
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETUP, buf);
-        if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
-                        strerror(rc = errno));
-
-        return rc;
-}
-
 /* Get echo client's stripe meta-data for the given object
  */
 int jt_obd_get_stripe (int argc, char **argv)
@@ -1006,7 +849,7 @@ int jt_obd_get_stripe (int argc, char **argv)
         id = strtoull (argv[1], &end, 0);
         if (*end) {
                 fprintf (stderr, "Error: %s: invalid object id '%s'\n",
-                         cmdname (argv[0]), argv[1]);
+                         jt_cmdname (argv[0]), argv[1]);
                 return (CMD_HELP);
         }
 
@@ -1020,12 +863,12 @@ int jt_obd_get_stripe (int argc, char **argv)
         data.ioc_plen1 = sizeof (lsm_buffer);
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf);
+        rc = l2_ioctl(OBD_DEV_ID, ECHO_IOC_GET_STRIPE, buf);
         IOC_UNPACK(argv[0], data);
 
         if (rc != 0) {
                 fprintf (stderr, "Error: %s: rc %d(%s)\n",
-                         cmdname (argv[0]), rc, strerror (errno));
+                         jt_cmdname (argv[0]), rc, strerror (errno));
                 return (rc);
         }
 
@@ -1051,7 +894,7 @@ int jt_obd_set_stripe (int argc, char **argv)
         rc = parse_lsm (&lsm_buffer, argv[1]);
         if (rc != 0) {
                 fprintf (stderr, "error: %s: invalid object '%s'\n",
-                         cmdname (argv[0]), argv[1]);
+                         jt_cmdname (argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -1059,7 +902,7 @@ int jt_obd_set_stripe (int argc, char **argv)
                 count = strtol (argv[2], &end, 0);
                 if (*end != 0) {
                         fprintf (stderr, "error: %s: invalid count '%s'\n",
-                                 cmdname (argv[0]), argv[1]);
+                                 jt_cmdname (argv[0]), argv[1]);
                         return CMD_HELP;
                 }
         }
@@ -1073,12 +916,12 @@ int jt_obd_set_stripe (int argc, char **argv)
                 data.ioc_plen1 = sizeof (lsm_buffer);
 
                 IOC_PACK (argv[0], data);
-                rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
+                rc = l2_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
                 IOC_UNPACK (argv[0], data);
 
                 if (rc != 0) {
                         fprintf (stderr, "Error: %s: rc %d(%s)\n",
-                                 cmdname (argv[0]), rc, strerror (errno));
+                                 jt_cmdname (argv[0]), rc, strerror (errno));
                         return (rc);
                 }
         }
@@ -1101,7 +944,7 @@ int jt_obd_unset_stripe (int argc, char **argv)
         id = strtoull (argv[1], &end, 0);
         if (*end != 0) {
                 fprintf (stderr, "error: %s: invalid object id '%s'\n",
-                         cmdname (argv[0]), argv[1]);
+                         jt_cmdname (argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -1111,12 +954,12 @@ int jt_obd_unset_stripe (int argc, char **argv)
         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
 
         IOC_PACK (argv[0], data);
-        rc = l_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
+        rc = l2_ioctl (OBD_DEV_ID, ECHO_IOC_SET_STRIPE, buf);
         IOC_UNPACK (argv[0], data);
 
         if (rc != 0)
                 fprintf (stderr, "Error: %s: rc %d(%s)\n",
-                         cmdname (argv[0]), rc, strerror (errno));
+                         jt_cmdname (argv[0]), rc, strerror (errno));
 
         return (0);
 }
@@ -1128,12 +971,10 @@ int jt_obd_unset_stripe (int argc, char **argv)
  */
 int jt_obd_create(int argc, char **argv)
 {
-        static __u64 base_id = 1;
-
         struct obd_ioctl_data data;
         struct timeval next_time;
-        __u64 count = 1, next_count;
-        int verbose = 1, mode = 0100644, rc = 0, i;
+        __u64 count = 1, next_count, base_id = 0;
+        int verbose = 1, mode = 0100644, rc = 0, i, valid_lsm = 0;
         char *end;
 
         IOC_INIT(data);
@@ -1143,7 +984,7 @@ int jt_obd_create(int argc, char **argv)
         count = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -1151,7 +992,7 @@ int jt_obd_create(int argc, char **argv)
                 mode = strtoul(argv[2], &end, 0);
                 if (*end) {
                         fprintf(stderr, "error: %s: invalid mode '%s'\n",
-                                cmdname(argv[0]), argv[2]);
+                                jt_cmdname(argv[0]), argv[2]);
                         return CMD_HELP;
                 }
                 if (!(mode & S_IFMT))
@@ -1170,46 +1011,49 @@ int jt_obd_create(int argc, char **argv)
                 rc = parse_lsm (&lsm_buffer, argv[4]);
                 if (rc != 0) {
                         fprintf(stderr, "error: %s: invalid lsm '%s'\n",
-                                cmdname(argv[0]), argv[4]);
+                                jt_cmdname(argv[0]), argv[4]);
                         return CMD_HELP;
                 }
                 base_id = lsm_buffer.lsm.lsm_object_id;
+                valid_lsm = 1;
         }
 
-        printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
+        printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count);
         gettimeofday(&next_time, NULL);
         next_time.tv_sec -= verbose;
 
         for (i = 1, next_count = verbose; i <= count; i++) {
                 data.ioc_obdo1.o_mode = mode;
-                data.ioc_obdo1.o_id = base_id++;
+                data.ioc_obdo1.o_id = base_id;
                 data.ioc_obdo1.o_uid = 0;
                 data.ioc_obdo1.o_gid = 0;
                 data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE |
-                                         OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;
+                        OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;
 
-                data.ioc_plen1 = sizeof (lsm_buffer);
-                data.ioc_pbuf1 = (char *)&lsm_buffer;
+                if (valid_lsm) {
+                        data.ioc_plen1 = sizeof lsm_buffer;
+                        data.ioc_pbuf1 = (char *)&lsm_buffer;
+                }
 
                 IOC_PACK(argv[0], data);
-                rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf);
+                rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CREATE, buf);
                 IOC_UNPACK(argv[0], data);
                 SHMEM_BUMP();
                 if (rc < 0) {
                         fprintf(stderr, "error: %s: #%d - %s\n",
-                                cmdname(argv[0]), i, strerror(rc = errno));
+                                jt_cmdname(argv[0]), i, strerror(rc = errno));
                         break;
                 }
                 if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) {
                         fprintf(stderr, "error: %s: objid not valid #%d:%08x\n",
-                                cmdname(argv[0]), i, data.ioc_obdo1.o_valid);
+                                jt_cmdname(argv[0]), i, data.ioc_obdo1.o_valid);
                         rc = EINVAL;
                         break;
                 }
 
                 if (be_verbose(verbose, &next_time, i, &next_count, count))
                         printf("%s: #%d is object id "LPX64"\n",
-                                cmdname(argv[0]), i, data.ioc_obdo1.o_id);
+                                jt_cmdname(argv[0]), i, data.ioc_obdo1.o_id);
         }
         return rc;
 }
@@ -1227,21 +1071,21 @@ int jt_obd_setattr(int argc, char **argv)
         data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
         data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid mode '%s'\n",
-                        cmdname(argv[0]), argv[2]);
+                        jt_cmdname(argv[0]), argv[2]);
                 return CMD_HELP;
         }
         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_SETATTR, buf);
         if (rc < 0)
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
 
         return rc;
@@ -1264,7 +1108,7 @@ int jt_obd_destroy(int argc, char **argv)
         id = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
         if (argc > 2) {
@@ -1272,7 +1116,7 @@ int jt_obd_destroy(int argc, char **argv)
                 if (*end) {
                         fprintf(stderr,
                                 "error: %s: invalid iteration count '%s'\n",
-                                cmdname(argv[0]), argv[2]);
+                                jt_cmdname(argv[0]), argv[2]);
                         return CMD_HELP;
                 }
         }
@@ -1283,7 +1127,7 @@ int jt_obd_destroy(int argc, char **argv)
                         return CMD_HELP;
         }
 
-        printf("%s: "LPD64" objects\n", cmdname(argv[0]), count);
+        printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count);
         gettimeofday(&next_time, NULL);
         next_time.tv_sec -= verbose;
 
@@ -1293,18 +1137,18 @@ int jt_obd_destroy(int argc, char **argv)
                 data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE;
 
                 IOC_PACK(argv[0], data);
-                rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf);
+                rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_DESTROY, buf);
                 IOC_UNPACK(argv[0], data);
                 SHMEM_BUMP();
                 if (rc < 0) {
                         fprintf(stderr, "error: %s: objid "LPX64": %s\n",
-                                cmdname(argv[0]), id, strerror(rc = errno));
+                                jt_cmdname(argv[0]), id, strerror(rc = errno));
                         break;
                 }
 
                 if (be_verbose(verbose, &next_time, i, &next_count, count))
                         printf("%s: #%d is object id "LPX64"\n",
-                               cmdname(argv[0]), i, id);
+                               jt_cmdname(argv[0]), i, id);
         }
 
         return rc;
@@ -1323,22 +1167,22 @@ int jt_obd_getattr(int argc, char **argv)
         data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid objid '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
         /* to help obd filter */
         data.ioc_obdo1.o_mode = 0100644;
         data.ioc_obdo1.o_valid = 0xffffffff;
-        printf("%s: object id "LPX64"\n", cmdname(argv[0]),data.ioc_obdo1.o_id);
+        printf("%s: object id "LPX64"\n", jt_cmdname(argv[0]),data.ioc_obdo1.o_id);
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, buf);
         IOC_UNPACK(argv[0], data);
         if (rc) {
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
         } else {
-                printf("%s: object id "LPX64", mode %o\n", cmdname(argv[0]),
+                printf("%s: object id "LPX64", mode %o\n", jt_cmdname(argv[0]),
                        data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode);
         }
         return rc;
@@ -1361,7 +1205,7 @@ int jt_obd_test_getattr(int argc, char **argv)
         count = strtoull(argv[1], &end, 0);
         if (*end) {
                 fprintf(stderr, "error: %s: invalid iteration count '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -1380,7 +1224,7 @@ int jt_obd_test_getattr(int argc, char **argv)
                         objid = strtoull(argv[3], &end, 0);
                 if (*end) {
                         fprintf(stderr, "error: %s: invalid objid '%s'\n",
-                                cmdname(argv[0]), argv[3]);
+                                jt_cmdname(argv[0]), argv[3]);
                         return CMD_HELP;
                 }
         }
@@ -1390,24 +1234,24 @@ int jt_obd_test_getattr(int argc, char **argv)
         next_time.tv_usec = start.tv_usec;
         if (verbose != 0)
                 printf("%s: getting "LPD64" attrs (objid "LPX64"): %s",
-                       cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
+                       jt_cmdname(argv[0]), count, objid, ctime(&start.tv_sec));
 
         for (i = 1, next_count = verbose; i <= count; i++) {
                 data.ioc_obdo1.o_id = objid;
                 data.ioc_obdo1.o_mode = S_IFREG;
                 data.ioc_obdo1.o_valid = 0xffffffff;
                 IOC_PACK(argv[0], data);
-                rc = l_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data);
+                rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_GETATTR, &data);
                 SHMEM_BUMP();
                 if (rc < 0) {
                         fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n",
-                                cmdname(argv[0]), i, errno, strerror(rc = errno));
+                                jt_cmdname(argv[0]), i, errno, strerror(rc = errno));
                         break;
                 } else {
                         if (be_verbose
                             (verbose, &next_time, i, &next_count, count))
                                 printf("%s: got attr #"LPD64"\n",
-                                       cmdname(argv[0]), i);
+                                       jt_cmdname(argv[0]), i);
                 }
         }
 
@@ -1421,8 +1265,8 @@ int jt_obd_test_getattr(int argc, char **argv)
 
                 --i;
                 if (verbose != 0)
-                        printf("%s: "LPD64" attrs in %.4gs (%.4g attr/s): %s",
-                               cmdname(argv[0]), i, diff, (double)i / diff,
+                        printf("%s: "LPD64" attrs in %.3fs (%.3f attr/s): %s",
+                               jt_cmdname(argv[0]), i, diff, i / diff,
                                ctime(&end.tv_sec));
         }
         return rc;
@@ -1432,19 +1276,13 @@ int jt_obd_test_brw(int argc, char **argv)
 {
         struct obd_ioctl_data data;
         struct timeval start, next_time;
-        int pages = 1;
-        __u64 count, next_count;
-        __u64 objid = 3;
-        int verbose = 1, write = 0, rw;
+        __u64 count, next_count, len, thr_offset = 0, objid = 3;
+        int write = 0, verbose = 1, cmd, i, rc = 0, pages = 1;
         char *end;
-        int thr_offset = 0;
-        int i;
-        int len;
-        int rc = 0;
 
-        if (argc < 2 || argc > 6) {
+        if (argc < 2 || argc > 7) {
                 fprintf(stderr, "error: %s: bad number of arguments: %d\n",
-                        cmdname(argv[0]), argc);
+                        jt_cmdname(argv[0]), argc);
                 return CMD_HELP;
         }
 
@@ -1458,7 +1296,7 @@ int jt_obd_test_brw(int argc, char **argv)
 
         if (*end) {
                 fprintf(stderr, "error: %s: bad iteration count '%s'\n",
-                        cmdname(argv[0]), argv[1]);
+                        jt_cmdname(argv[0]), argv[1]);
                 return CMD_HELP;
         }
 
@@ -1479,7 +1317,7 @@ int jt_obd_test_brw(int argc, char **argv)
                 pages = strtoul(argv[4], &end, 0);
                 if (*end) {
                         fprintf(stderr, "error: %s: bad page count '%s'\n",
-                                cmdname(argv[0]), argv[4]);
+                                jt_cmdname(argv[0]), argv[4]);
                         return CMD_HELP;
                 }
         }
@@ -1492,14 +1330,48 @@ int jt_obd_test_brw(int argc, char **argv)
                         objid = strtoull(argv[5], &end, 0);
                 if (*end) {
                         fprintf(stderr, "error: %s: bad objid '%s'\n",
-                                cmdname(argv[0]), argv[5]);
+                                jt_cmdname(argv[0]), argv[5]);
+                        return CMD_HELP;
+                }
+        }
+
+        IOC_INIT(data);
+
+        /* communicate the 'type' of brw test and batching to echo_client.
+         * don't start.  we'd love to refactor this lctl->echo_client
+         * interface */
+        data.ioc_pbuf1 = (void *)1;
+        data.ioc_plen1 = 1;
+
+        if (argc >= 7) {
+                switch(argv[6][0]) {
+                        case 'g': /* plug and unplug */
+                                data.ioc_pbuf1 = (void *)2;
+                                data.ioc_plen1 = strtoull(argv[6] + 1, &end,
+                                                          0);
+                                break;
+                        case 'p': /* prep and commit */
+                                data.ioc_pbuf1 = (void *)3;
+                                data.ioc_plen1 = strtoull(argv[6] + 1, &end,
+                                                          0);
+                                break;
+                        default:
+                                fprintf(stderr, "error: %s: batching '%s' "
+                                        "needs to specify 'p' or 'g'\n",
+                                        jt_cmdname(argv[0]), argv[6]);
+                                return CMD_HELP;
+                }
+
+                if (*end) {
+                        fprintf(stderr, "error: %s: bad batching '%s'\n",
+                                jt_cmdname(argv[0]), argv[6]);
                         return CMD_HELP;
                 }
+                data.ioc_plen1 *= PAGE_SIZE;
         }
 
         len = pages * PAGE_SIZE;
 
-        IOC_INIT(data);
         data.ioc_obdo1.o_id = objid;
         data.ioc_obdo1.o_mode = S_IFREG;
         data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
@@ -1512,28 +1384,22 @@ int jt_obd_test_brw(int argc, char **argv)
 
         if (verbose != 0)
                 printf("%s: %s "LPU64"x%d pages (obj "LPX64", off "LPU64"): %s",
-                       cmdname(argv[0]), write ? "writing" : "reading", count,
+                       jt_cmdname(argv[0]), write ? "writing" : "reading", count,
                        pages, objid, data.ioc_offset, ctime(&start.tv_sec));
 
-        IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_OPEN, buf);
-        IOC_UNPACK(argv[0], data);
-        if (rc) {
-                fprintf(stderr, "error: brw_open: %s\n", strerror(rc = errno));
-                return rc;
-        }
-
-        rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
+        cmd = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
         for (i = 1, next_count = verbose; i <= count; i++) {
-                rc = l_ioctl(OBD_DEV_ID, rw, buf);
+                data.ioc_obdo1.o_valid &= ~(OBD_MD_FLBLOCKS|OBD_MD_FLRDEV);
+                IOC_PACK(argv[0], data);
+                rc = l2_ioctl(OBD_DEV_ID, cmd, buf);
                 SHMEM_BUMP();
                 if (rc) {
                         fprintf(stderr, "error: %s: #%d - %s on %s\n",
-                                cmdname(argv[0]), i, strerror(rc = errno),
+                                jt_cmdname(argv[0]), i, strerror(rc = errno),
                                 write ? "write" : "read");
                         break;
                 } else if (be_verbose(verbose, &next_time,i, &next_count,count))
-                        printf("%s: %s number %dx%d\n", cmdname(argv[0]),
+                        printf("%s: %s number %dx%d\n", jt_cmdname(argv[0]),
                                write ? "write" : "read", i, pages);
 
                 data.ioc_offset += len;
@@ -1549,133 +1415,17 @@ int jt_obd_test_brw(int argc, char **argv)
 
                 --i;
                 if (verbose != 0)
-                        printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s",
-                               cmdname(argv[0]), write ? "wrote" : "read",
-                               i, pages, diff, (double)i * pages / diff,
+                        printf("%s: %s %dx%d pages in %.3fs (%.3f MB/s): %s",
+                               jt_cmdname(argv[0]), write ? "wrote" : "read",
+                               i, pages, diff,
+                               ((double)i * pages * getpagesize()) /
+                               (diff * 1048576.0),
                                ctime(&end.tv_sec));
         }
-        rw = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE, buf);
-        if (rw) {
-                fprintf(stderr, "error: brw_close: %s\n", strerror(rw = errno));
-                if (!rc)
-                        rc = rw;
-        }
 
         return rc;
 }
 
-int jt_obd_lov_setconfig(int argc, char **argv)
-{
-        struct obd_ioctl_data data;
-        struct lov_desc desc;
-        struct obd_uuid *uuidarray, *ptr;
-        int rc, i;
-        char *end;
-
-        IOC_INIT(data);
-
-        if (argc <= 6)
-                return CMD_HELP;
-
-        if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) {
-                fprintf(stderr,
-                        "error: %s: LOV uuid '%s' longer than "LPSZ" chars\n",
-                        cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1);
-                return -EINVAL;
-        }
-
-        memset(&desc, 0, sizeof(desc));
-        obd_str2uuid(&desc.ld_uuid, argv[1]);
-        desc.ld_tgt_count = argc - 6;
-        desc.ld_default_stripe_count = strtoul(argv[2], &end, 0);
-        if (*end) {
-                fprintf(stderr, "error: %s: bad default stripe count '%s'\n",
-                        cmdname(argv[0]), argv[2]);
-                return CMD_HELP;
-        }
-        if (desc.ld_default_stripe_count > desc.ld_tgt_count) {
-                fprintf(stderr,
-                        "error: %s: default stripe count %u > OST count %u\n",
-                        cmdname(argv[0]), desc.ld_default_stripe_count,
-                        desc.ld_tgt_count);
-                return -EINVAL;
-        }
-
-        desc.ld_default_stripe_size = strtoull(argv[3], &end, 0);
-        if (*end) {
-                fprintf(stderr, "error: %s: bad default stripe size '%s'\n",
-                        cmdname(argv[0]), argv[3]);
-                return CMD_HELP;
-        }
-        if (desc.ld_default_stripe_size < 4096) {
-                fprintf(stderr,
-                        "error: %s: default stripe size "LPU64" too small\n",
-                        cmdname(argv[0]), desc.ld_default_stripe_size);
-                return -EINVAL;
-        } else if ((long)desc.ld_default_stripe_size <
-                   desc.ld_default_stripe_size) {
-                fprintf(stderr,
-                        "error: %s: default stripe size "LPU64" too large\n",
-                        cmdname(argv[0]), desc.ld_default_stripe_size);
-                return -EINVAL;
-        }
-        desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0);
-        if (*end) {
-                fprintf(stderr, "error: %s: bad default stripe offset '%s'\n",
-                        cmdname(argv[0]), argv[4]);
-                return CMD_HELP;
-        }
-        desc.ld_pattern = strtoul(argv[5], &end, 0);
-        if (*end) {
-                fprintf(stderr, "error: %s: bad stripe pattern '%s'\n",
-                        cmdname(argv[0]), argv[5]);
-                return CMD_HELP;
-        }
-
-        /* NOTE: it is possible to overwrite the default striping parameters,
-         *       but EXTREME care must be taken when saving the OST UUID list.
-         *       It must be EXACTLY the same, or have only additions at the
-         *       end of the list, or only overwrite individual OST entries
-         *       that are restored from backups of the previous OST.
-         */
-        uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
-        if (!uuidarray) {
-                fprintf(stderr, "error: %s: no memory for %d UUIDs\n",
-                        cmdname(argv[0]), desc.ld_tgt_count);
-                rc = -ENOMEM;
-                goto out;
-        }
-        for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) {
-                if (strlen(argv[i]) >= sizeof(*ptr)) {
-                        fprintf(stderr, "error: %s: arg %d (%s) too long\n",
-                                cmdname(argv[0]), i, argv[i]);
-                        rc = -EINVAL;
-                        goto out;
-                }
-                strcpy((char *)ptr, argv[i]);
-        }
-
-        data.ioc_inllen1 = sizeof(desc);
-        data.ioc_inlbuf1 = (char *)&desc;
-        data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray);
-        data.ioc_inlbuf2 = (char *)uuidarray;
-
-        if (obd_ioctl_pack(&data, &buf, max)) {
-                fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
-                rc = -EINVAL;
-                goto out;
-        }
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LOV_SET_CONFIG, buf);
-        if (rc)
-                fprintf(stderr, "error: %s: ioctl error: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
-out:
-        free(uuidarray);
-        return rc;
-}
-
-#define DEF_UUID_ARRAY_LEN (8192 / 40)
-
 int jt_obd_lov_getconfig(int argc, char **argv)
 {
         struct obd_ioctl_data data;
@@ -1699,12 +1449,14 @@ int jt_obd_lov_getconfig(int argc, char **argv)
 
         memset(&desc, 0, sizeof(desc));
         obd_str2uuid(&desc.ld_uuid, argv[1]);
-        desc.ld_tgt_count = DEF_UUID_ARRAY_LEN;
+        desc.ld_tgt_count = ((OBD_MAX_IOCTL_BUFFER-sizeof(data)-sizeof(desc)) /
+                             sizeof(*uuidarray));
+
 repeat:
         uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray));
         if (!uuidarray) {
                 fprintf(stderr, "error: %s: no memory for %d uuid's\n",
-                        cmdname(argv[0]), desc.ld_tgt_count);
+                        jt_cmdname(argv[0]), desc.ld_tgt_count);
                 rc = -ENOMEM;
                 goto out;
         }
@@ -1715,7 +1467,8 @@ repeat:
         data.ioc_inlbuf2 = (char *)uuidarray;
 
         if (obd_ioctl_pack(&data, &buf, max)) {
-                fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
+                fprintf(stderr, "error: %s: invalid ioctl\n",
+                        jt_cmdname(argv[0]));
                 rc = -EINVAL;
                 goto out;
         }
@@ -1725,14 +1478,14 @@ repeat:
                 goto repeat;
         } else if (rc) {
                 fprintf(stderr, "error: %s: ioctl error: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         } else {
                 struct obd_uuid *ptr;
                 int i;
 
                 if (obd_ioctl_unpack(&data, buf, max)) {
                         fprintf(stderr, "error: %s: invalid reply\n",
-                                cmdname(argv[0]));
+                                jt_cmdname(argv[0]));
                         rc = -EINVAL;
                         goto out;
                 }
@@ -1763,10 +1516,10 @@ int jt_obd_test_ldlm(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf);
+        rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_TEST, buf);
         if (rc)
                 fprintf(stderr, "error: %s: test failed: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         return rc;
 }
 
@@ -1780,10 +1533,10 @@ int jt_obd_dump_ldlm(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf);
+        rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_DUMP, buf);
         if (rc)
                 fprintf(stderr, "error: %s failed: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         return rc;
 }
 
@@ -1812,10 +1565,10 @@ int jt_obd_ldlm_regress_start(int argc, char **argv)
         }
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
+        rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
         if (rc)
                 fprintf(stderr, "error: %s: test failed: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
 
         return rc;
 }
@@ -1830,11 +1583,11 @@ int jt_obd_ldlm_regress_stop(int argc, char **argv)
                 return CMD_HELP;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
+        rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
 
         if (rc)
                 fprintf(stderr, "error: %s: test failed: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         return rc;
 }
 
@@ -1851,10 +1604,10 @@ static int do_activate(int argc, char **argv, int flag)
         data.ioc_offset = flag;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, IOC_OSC_SET_ACTIVE, buf);
+        rc = l2_ioctl(OBD_DEV_ID, IOC_OSC_SET_ACTIVE, buf);
         if (rc)
                 fprintf(stderr, "error: %s: failed: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
 
         return rc;
 }
@@ -1884,9 +1637,9 @@ int jt_obd_recover(int argc, char **argv)
         }
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLIENT_RECOVER, buf);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CLIENT_RECOVER, buf);
         if (rc < 0) {
-                fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]),
+                fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
                         strerror(rc = errno));
         }
 
@@ -1924,7 +1677,7 @@ int jt_obd_mdc_lookup(int argc, char **argv)
         rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
         if (rc < 0) {
                 fprintf(stderr, "error: %s: ioctl error: %s\n",
-                        cmdname(argv[0]), strerror(rc = errno));
+                        jt_cmdname(argv[0]), strerror(rc = errno));
         }
         close(fd);
 
@@ -1938,114 +1691,276 @@ int jt_obd_mdc_lookup(int argc, char **argv)
         return rc;
 }
 
-static 
-int do_add_uuid(char * func, char *uuid, ptl_nid_t nid, int nal) 
+
+int jt_obd_close_uuid(int argc, char **argv)
 {
-        char tmp[64];
-        int rc;
+        int rc, nal;
         struct obd_ioctl_data data;
 
+        if (argc != 3) {
+                fprintf(stderr, "usage: %s <uuid> <net-type>\n", argv[0]);
+                return 0;
+        }
+
+        nal = ptl_name2nal(argv[2]);
+
+        if (nal <= 0) {
+                fprintf (stderr, "Can't parse NAL %s\n", argv[2]);
+                return -1;
+        }
+
         IOC_INIT(data);
-        data.ioc_nid = nid;
-        data.ioc_inllen1 = strlen(uuid) + 1;
-        data.ioc_inlbuf1 = uuid;
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
         data.ioc_nal = nal;
 
-        IOC_PACK(func, data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ADD_UUID, buf);
+        IOC_PACK(argv[0], data);
+        rc = l2_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf);
         if (rc) {
-                fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
+                fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n",
                         strerror(errno));
                 return -1;
         }
-
-        printf ("Added uuid %s: %s\n", uuid, ptl_nid2str (tmp, nid));
         return 0;
 }
 
-int jt_obd_add_uuid(int argc, char **argv)
+
+int jt_cfg_record(int argc, char **argv)
 {
-        ptl_nid_t nid = 0;
-        int nal;
-        
-        if (argc != 4) {                
-                return CMD_HELP;
-        }
+        struct obd_ioctl_data data;
+        int rc;
 
-        if (ptl_parse_nid (&nid, argv[2]) != 0) {
-                fprintf (stderr, "Can't parse NID %s\n", argv[2]);
-                        return (-1);
-        }
+        IOC_INIT(data);
 
-        nal = ptl_name2nal(argv[3]);
+        if (argc != 2)
+                return CMD_HELP;
 
-        if (nal <= 0) {
-                fprintf (stderr, "Can't parse NAL %s\n", argv[3]);
-                return -1;
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+
+        IOC_PACK(argv[0], data);
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_RECORD, buf);
+        if (rc == 0) {
+                jt_recording = 1;
+                ptl_set_cfg_record_cb(obd_record);
+        } else {
+                fprintf(stderr, "OBD_IOC_RECORD failed: %s\n",
+                        strerror(errno));
         }
 
-        return do_add_uuid(argv[0], argv[1], nid, nal);
+        return rc;
 }
 
-int jt_obd_close_uuid(int argc, char **argv)
+int jt_cfg_parse(int argc, char **argv)
 {
-        int rc, nal;
         struct obd_ioctl_data data;
+        int rc;
 
-        if (argc != 3) {
-                fprintf(stderr, "usage: %s <uuid> <net-type>\n", argv[0]);
-                return 0;
-        }
+        IOC_INIT(data);
 
-        nal = ptl_name2nal(argv[2]);
+        if (argc != 2)
+                return CMD_HELP;
+
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+
+        IOC_PACK(argv[0], data);
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_PARSE, buf);
+        if (rc < 0)
+                fprintf(stderr, "OBD_IOC_PARSE failed: %s\n",
+                        strerror(errno));
+
+        return rc;
+}
 
-        if (nal <= 0) {
-                fprintf (stderr, "Can't parse NAL %s\n", argv[2]);
-                return -1;
-        }
+
+int jt_cfg_dump_log(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
 
         IOC_INIT(data);
+
+        if (argc != 2)
+                return CMD_HELP;
+
         data.ioc_inllen1 = strlen(argv[1]) + 1;
         data.ioc_inlbuf1 = argv[1];
-        data.ioc_nal = nal;
 
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CLOSE_UUID, buf);
-        if (rc) {
-                fprintf(stderr, "IOC_PORTAL_CLOSE_UUID failed: %s\n",
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DUMP_LOG, buf);
+        if (rc < 0)
+                fprintf(stderr, "OBD_IOC_DUMP_LOG failed: %s\n",
                         strerror(errno));
-                return -1;
-        }
-        return 0;
+
+        return rc;
 }
 
 
-int jt_obd_del_uuid(int argc, char **argv)
+int jt_cfg_endrecord(int argc, char **argv)
 {
-        int rc;
         struct obd_ioctl_data data;
+        int rc;
 
-        if (argc != 2) {
-                fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
+        IOC_INIT(data);
+
+        if (argc != 1)
+                return CMD_HELP;
+
+        if (!jt_recording) {
+                fprintf(stderr, "Not recording, so endrecord doesn't make sense.\n");
                 return 0;
         }
 
-        IOC_INIT(data);
-
-        if (strcmp (argv[1], "_all_"))
-        {
-                data.ioc_inllen1 = strlen(argv[1]) + 1;
-                data.ioc_inlbuf1 = argv[1];
+        IOC_PACK(argv[0], data);
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ENDRECORD, buf);
+        if (rc == 0) {
+                jt_recording = 0;
+                ptl_set_cfg_record_cb(NULL);
+        } else {
+                fprintf(stderr, "OBD_IOC_ENDRECORD failed: %s\n",
+                        strerror(errno));
         }
+        return rc;
+}
+
+int jt_llog_catlist(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
+
+        if (argc != 1)
+                return CMD_HELP;
+
+        IOC_INIT(data);
+        data.ioc_inllen1 = max - size_round(sizeof(data));
+        IOC_PACK(argv[0], data);
+        
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf);
+        if (rc == 0) 
+                fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
+        else
+                fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", 
+                        strerror(errno));
         
+        return rc;
+}
+
+int jt_llog_info(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
+
+        if (argc != 2)
+                return CMD_HELP;
+
+        IOC_INIT(data);
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+        data.ioc_inllen2 = max - size_round(sizeof(data)) - 
+                size_round(data.ioc_inllen1);
         IOC_PACK(argv[0], data);
-        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_DEL_UUID, buf);
-        if (rc) {
-                fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
+
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_INFO, buf);
+        if (rc == 0)
+                fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
+        else
+                fprintf(stderr, "OBD_IOC_LLOG_INFO failed: %s\n",
                         strerror(errno));
-                return -1;
-        }
-        return 0;
+
+        return rc;
+}
+
+int jt_llog_print(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
+
+        if (argc != 2 && argc != 4)
+                return CMD_HELP;
+
+        IOC_INIT(data);
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+        if (argc == 4) {
+                data.ioc_inllen2 = strlen(argv[2]) + 1;
+                data.ioc_inlbuf2 = argv[2];
+                data.ioc_inllen3 = strlen(argv[3]) + 1;
+                data.ioc_inlbuf3 = argv[3];
+        } else {
+                char from[2] = "1", to[3] = "-1";
+                data.ioc_inllen2 = strlen(from) + 1;
+                data.ioc_inlbuf2 = from;
+                data.ioc_inllen3 = strlen(to) + 1;
+                data.ioc_inlbuf3 = to;
+        }
+        data.ioc_inllen4 = max - size_round(sizeof(data)) -
+                size_round(data.ioc_inllen1) -
+                size_round(data.ioc_inllen2) -
+                size_round(data.ioc_inllen3);
+        IOC_PACK(argv[0], data);
+
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_PRINT, buf);
+        if (rc == 0)
+                fprintf(stdout, "%s", ((struct obd_ioctl_data*)buf)->ioc_bulk);
+        else
+                fprintf(stderr, "OBD_IOC_LLOG_PRINT failed: %s\n",
+                        strerror(errno));
+
+        return rc;
+}
+
+int jt_llog_cancel(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
+
+        if (argc != 4)
+                return CMD_HELP;
+
+        IOC_INIT(data);
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+        data.ioc_inllen2 = strlen(argv[2]) + 1;
+        data.ioc_inlbuf2 = argv[2];
+        data.ioc_inllen3 = strlen(argv[3]) + 1;
+        data.ioc_inlbuf3 = argv[3];
+        IOC_PACK(argv[0], data);
+
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_CANCEL, buf);
+        if (rc == 0)
+                fprintf(stdout, "index %s be canceled.\n", argv[3]);
+        else
+                fprintf(stderr, "OBD_IOC_LLOG_CANCEL failed: %s\n",
+                        strerror(errno));
+
+        return rc;
+
+}
+
+int jt_llog_remove(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        int rc;
+
+        if (argc != 3)
+                return CMD_HELP;
+
+        IOC_INIT(data);
+        data.ioc_inllen1 = strlen(argv[1]) + 1;
+        data.ioc_inlbuf1 = argv[1];
+        data.ioc_inllen2 = strlen(argv[2]) + 1;
+        data.ioc_inlbuf2 = argv[2];
+        IOC_PACK(argv[0], data);
+
+        rc = l_ioctl(OBD_DEV_ID, OBD_IOC_LLOG_REMOVE, buf);
+        if (rc == 0)
+                fprintf(stdout, "log %s are removed.\n", argv[2]);
+        else
+                fprintf(stderr, "OBD_IOC_LLOG_REMOVE failed: %s\n",
+                        strerror(errno));
+
+        return rc;
 }
 
 static void signal_server(int sig)
@@ -2054,7 +1969,7 @@ static void signal_server(int sig)
                 do_disconnect("sigint", 1);
                 exit(1);
         } else
-                fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig);
+                fprintf(stderr, "%s: got signal %d\n", jt_cmdname("sigint"), sig);
 }
 
 int obd_initialize(int argc, char **argv)
@@ -2066,7 +1981,7 @@ int obd_initialize(int argc, char **argv)
 }
 
 
-void obd_cleanup(int argc, char **argv)
+void obd_finalize(int argc, char **argv)
 {
         struct sigaction sigact;
 
@@ -2075,5 +1990,10 @@ void obd_cleanup(int argc, char **argv)
         sigact.sa_flags = SA_RESTART;
         sigaction(SIGINT, &sigact, NULL);
 
+        if (jt_recording) {
+                printf("END RECORD\n");
+                jt_cfg_endrecord(argc, argv);
+        }
+
         do_disconnect(argv[0], 1);
 }
diff --git a/lustre/utils/obdctl.c b/lustre/utils/obdctl.c
index 8fd4f7c80c1981e4f5d8f52c302cb2d208fdff6a..b67f8f168c1d8fb79d33c06df2c936af464df793 100644
--- a/lustre/utils/obdctl.c
+++ b/lustre/utils/obdctl.c
@@ -99,6 +99,6 @@ int main(int argc, char **argv)
                 rc = Parser_commands();
         }
 
-        obd_cleanup(argc, argv);
+        obd_finalize(argc, argv);
         return rc;
 }
diff --git a/lustre/utils/obdctl.h b/lustre/utils/obdctl.h
index 40614309900aeea787cc3ec360bbd37308607b3a..7a44adddfa6f1ee55ed929172f484cfb5f548562 100644
--- a/lustre/utils/obdctl.h
+++ b/lustre/utils/obdctl.h
@@ -26,9 +26,20 @@
 #ifndef _OBDCTL_H_
 #define _OBDCTL_H_
 
+#ifndef __KERNEL__
+#include <liblustre.h>
+#endif
+
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lustre_cfg.h>
+
+/* obd.c */
 int do_disconnect(char *func, int verbose);
- int obd_initialize(int argc, char **argv);
-void obd_cleanup(int argc, char **argv);
+int obd_initialize(int argc, char **argv);
+void obd_finalize(int argc, char **argv);
+
 
 int jt_opt_device(int argc, char **argv);
 int jt_opt_threads(int argc, char **argv);
@@ -42,11 +53,7 @@ int jt_obd_cleanup(int argc, char **argv);
 int jt_obd_no_transno(int argc, char **argv);
 int jt_obd_set_readonly(int argc, char **argv);
 int jt_obd_abort_recovery(int argc, char **argv);
-int jt_obd_newdev(int argc, char **argv);
-int jt_obd_mount_option(int argc, char **argv);
 int jt_obd_list(int argc, char **argv);
-int jt_obd_attach(int argc, char **argv);
-int jt_obd_setup(int argc, char **argv);
 int jt_obd_create(int argc, char **argv);
 int jt_obd_setattr(int argc, char **argv);
 int jt_obd_destroy(int argc, char **argv);
@@ -56,7 +63,6 @@ int jt_obd_test_brw(int argc, char **argv);
 int jt_obd_get_stripe(int argc, char **argv);
 int jt_obd_set_stripe(int argc, char **argv);
 int jt_obd_unset_stripe(int argc, char **argv);
-int jt_obd_lov_setconfig(int argc, char **argv);
 int jt_obd_lov_getconfig(int argc, char **argv);
 int jt_obd_test_ldlm(int argc, char **argv);
 int jt_obd_ldlm_regress_start(int argc, char **argv);
@@ -67,8 +73,36 @@ int jt_obd_deactivate(int argc, char **argv);
 int jt_obd_recover(int argc, char **argv);
 int jt_obd_mdc_lookup(int argc, char **argv);
 int jt_get_version(int argc, char **argv);
-int jt_obd_add_uuid(int argc, char **argv);
 int jt_obd_close_uuid(int argc, char **argv);
-int jt_obd_del_uuid(int argc, char **argv);
+int jt_cfg_record(int argc, char **argv);
+int jt_cfg_endrecord(int argc, char **argv);
+int jt_cfg_parse(int argc, char **argv);
+int jt_cfg_dump_log(int argc, char **argv);
+
+int jt_llog_catlist(int argc, char **argv);
+int jt_llog_info(int argc, char **argv);
+int jt_llog_print(int argc, char **argv);
+int jt_llog_cancel(int argc, char **argv);
+int jt_llog_remove(int argc, char **argv);
+
+int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg);
+int parse_devname(char *func, char *name);
+char *jt_cmdname(char *func);
+
+
+/* lustre_cfg.h */
+int jt_lcfg_device(int argc, char **argv);
+int jt_lcfg_newdev(int argc, char **argv);
+int jt_lcfg_attach(int argc, char **argv);
+int jt_lcfg_setup(int argc, char **argv);
+int jt_lcfg_add_uuid(int argc, char **argv);
+int jt_lcfg_del_uuid(int argc, char **argv);
+int jt_lcfg_lov_setup(int argc, char **argv);
+int jt_lcfg_mount_option(int argc, char **argv);
+int jt_lcfg_del_mount_option(int argc, char **argv);
+int jt_lcfg_set_timeout(int argc, char **argv);
+int jt_lcfg_set_lustre_upcall(int argc, char **argv);
+
+int obd_add_uuid(char *uuid, ptl_nid_t nid, int nal);
 
 #endif
diff --git a/lustre/utils/obdio.c b/lustre/utils/obdio.c
index 24b9e2dca9633b2ac20adbbb6232d68647a10ccf..f10dff38cf928cc377c1ac1ee2fc2fd822890460 100644
--- a/lustre/utils/obdio.c
+++ b/lustre/utils/obdio.c
@@ -35,28 +35,18 @@ obdio_test_fixed_extent (struct obdio_conn *conn,
                          int reps, int locked, uint64_t oid,
                          uint64_t offset, uint32_t size)
 {
-        struct lustre_handle fh;
         struct lustre_handle lh;
         void                *space;
         void                *buffer;
         uint32_t            *ibuf;
         int                  i;
         int                  j;
-        int                  rc;
-        int                  rc2;
-
-        rc = obdio_open (conn, oid, &fh);
-        if (rc != 0) {
-                fprintf (stderr, "Failed to open object "LPX64": %s\n",
-                         oid, strerror (errno));
-                return (rc);
-        }
+        int                  rc = 0;
 
         buffer = obdio_alloc_aligned_buffer (&space, size);
         if (buffer == NULL) {
                 fprintf (stderr, "Can't allocate buffer size %d\n", size);
-                rc = -1;
-                goto out_0;
+                return (-1);
         }
 
         for (i = 0; i < reps; i++) {
@@ -70,43 +60,47 @@ obdio_test_fixed_extent (struct obdio_conn *conn,
                 }
 
                 if (locked) {
-                        rc = obdio_enqueue (conn, oid, LCK_PW, offset, size, &lh);
+                        rc = obdio_enqueue(conn, oid, LCK_PW, offset, size,&lh);
                         if (rc != 0) {
-                                fprintf (stderr, "Error on enqueue "LPX64" @ "LPU64" for %u: %s\n",
-                                         oid, offset, size, strerror (errno));
-                                goto out_1;
+                                fprintf(stderr, "Error on enqueue "LPX64" @ "
+                                        LPU64" for %u: %s\n",
+                                        oid, offset, size, strerror (errno));
+                                goto out;
                         }
                 }
 
                 rc = obdio_pwrite (conn, oid, buffer, size, offset);
                 if (rc != 0) {
-                        fprintf (stderr, "Error writing "LPX64" @ "LPU64" for %u: %s\n",
-                                 oid, offset, size, strerror (errno));
+                        fprintf(stderr, "Error writing "LPX64" @ "LPU64
+                                " for %u: %s\n",
+                                oid, offset, size, strerror (errno));
                         if (locked)
                                 obdio_cancel (conn, &lh);
                         rc = -1;
-                        goto out_1;
+                        goto out;
                 }
 
                 memset (buffer, 0xbb, size);
 
                 rc = obdio_pread (conn, oid, buffer, size, offset);
                 if (rc != 0) {
-                        fprintf (stderr, "Error reading "LPX64" @ "LPU64" for %u: %s\n",
-                                 oid, offset, size, strerror (errno));
+                        fprintf(stderr, "Error reading "LPX64" @ "LPU64
+                                " for %u: %s\n",
+                                oid, offset, size, strerror (errno));
                         if (locked)
                                 obdio_cancel (conn, &lh);
                         rc = -1;
-                        goto out_1;
+                        goto out;
                 }
 
                 if (locked) {
                         rc = obdio_cancel (conn, &lh);
                         if (rc != 0) {
-                                fprintf (stderr, "Error on cancel "LPX64" @ "LPU64" for %u: %s\n",
-                                         oid, offset, size, strerror (errno));
+                                fprintf(stderr, "Error on cancel "LPX64" @ "
+                                        LPU64" for %u: %s\n",
+                                        oid, offset, size, strerror (errno));
                                 rc = -1;
-                                goto out_1;
+                                goto out;
                         }
                 }
 
@@ -116,23 +110,21 @@ obdio_test_fixed_extent (struct obdio_conn *conn,
                             ibuf[1] != mypid ||
                             ibuf[2] != i ||
                             ibuf[3] != j) {
-                                fprintf (stderr, "Error checking "LPX64" @ "LPU64" for %u, chunk %d\n",
-                                         oid, offset, size, j);
-                                fprintf (stderr, "Expected [%x,%x,%x,%x], got [%x,%x,%x,%x]\n",
-                                         myhid, mypid, i, j, ibuf[0], ibuf[1], ibuf[2], ibuf[3]);
+                                fprintf(stderr, "Error checking "LPX64" @ "
+                                        LPU64" for %u, chunk %d\n",
+                                        oid, offset, size, j);
+                                fprintf(stderr, "Expected [%x,%x,%x,%x], "
+                                        "got [%x,%x,%x,%x]\n",
+                                        myhid, mypid, i, j,
+                                        ibuf[0], ibuf[1], ibuf[2], ibuf[3]);
                                 rc = -1;
-                                goto out_1;
+                                goto out;
                         }
                         ibuf += 4;
                 }
         }
- out_1:
+ out:
         free (space);
- out_0:
-        rc2 = obdio_close (conn, oid, &fh);
-        if (rc2 != 0)
-                fprintf (stderr, "Error closing object "LPX64": %s\n",
-                         oid, strerror (errno));
         return (rc);
 }
 
diff --git a/lustre/utils/obdiolib.c b/lustre/utils/obdiolib.c
index 04dae88d7f5803edbd71b3648473f4ee57ff8cf3..461a8c0e25ccdf210bba024156fb4ca405d22098 100644
--- a/lustre/utils/obdiolib.c
+++ b/lustre/utils/obdiolib.c
@@ -123,40 +123,6 @@ obdio_disconnect (struct obdio_conn *conn, int flags)
         free (conn);
 }
 
-int
-obdio_open (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh)
-{
-        int    rc;
-
-        obdio_iocinit (conn);
-
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE;
-
-        rc = obdio_ioctl (conn, OBD_IOC_OPEN);
-
-        if (rc == 0)
-                memcpy (fh, obdo_handle(&conn->oc_data.ioc_obdo1), sizeof (*fh));
-
-        return (rc);
-}
-
-int
-obdio_close (struct obdio_conn *conn, uint64_t oid, struct lustre_handle *fh)
-{
-        obdio_iocinit (conn);
-
-
-        conn->oc_data.ioc_obdo1.o_id = oid;
-        conn->oc_data.ioc_obdo1.o_mode = S_IFREG;
-        memcpy (obdo_handle (&conn->oc_data.ioc_obdo1), fh, sizeof (*fh));
-        conn->oc_data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE |
-                                          OBD_MD_FLMODE | OBD_MD_FLHANDLE;
-
-        return (obdio_ioctl (conn, OBD_IOC_CLOSE));
-}
-
 int
 obdio_pread (struct obdio_conn *conn, uint64_t oid,
              char *buffer, uint32_t count, uint64_t offset)
@@ -264,7 +230,6 @@ obdio_new_barrier (uint64_t oid, uint64_t id, int npeers)
 int
 obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
 {
-        struct lustre_handle    fh;
         struct lustre_handle    lh;
         int                     rc;
         int                     rc2;
@@ -277,19 +242,11 @@ obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
                 abort ();
         }
 
-        rc = obdio_open (conn, b->ob_oid, &fh);
-        if (rc != 0) {
-                fprintf (stderr, "obdio_setup_barrier "LPX64": Failed to open object: %s\n",
-                         b->ob_oid, strerror (errno));
-                return (rc);
-        }
-
         fileb = (struct obdio_barrier *) obdio_alloc_aligned_buffer (&space, getpagesize ());
         if (fileb == NULL) {
                 fprintf (stderr, "obdio_setup_barrier "LPX64": Can't allocate page buffer\n",
                          b->ob_oid);
-                rc = -1;
-                goto out_0;
+                return (-1);
         }
 
         memset (fileb, 0, getpagesize ());
@@ -299,7 +256,7 @@ obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
         if (rc != 0) {
                 fprintf (stderr, "obdio_setup_barrier "LPX64": Error on enqueue: %s\n",
                          b->ob_oid, strerror (errno));
-                goto out_1;
+                goto out;
         }
 
         rc = obdio_pwrite (conn, b->ob_oid, (void *)fileb, getpagesize (), 0);
@@ -313,23 +270,14 @@ obdio_setup_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
                          b->ob_oid, strerror (errno));
                 rc = rc2;
         }
- out_1:
+ out:
         free (space);
- out_0:
-        rc2 = obdio_close (conn, b->ob_oid, &fh);
-        if (rc == 0 && rc2 != 0) {
-                fprintf (stderr, "obdio_setup_barrier "LPX64": Error on close: %s\n",
-                         b->ob_oid, strerror (errno));
-                rc = rc2;
-        }
-
         return (rc);
 }
 
 int
 obdio_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
 {
-        struct lustre_handle   fh;
         struct lustre_handle   lh;
         int                    rc;
         int                    rc2;
@@ -337,19 +285,11 @@ obdio_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
         struct obdio_barrier  *fileb;
         char                  *mode;
 
-        rc = obdio_open (conn, b->ob_oid, &fh);
-        if (rc != 0) {
-                fprintf (stderr, "obdio_barrier "LPX64": Error on open: %s\n",
-                         b->ob_oid, strerror (errno));
-                return (rc);
-        }
-
         fileb = (struct obdio_barrier *) obdio_alloc_aligned_buffer (&space, getpagesize ());
         if (fileb == NULL) {
                 fprintf (stderr, "obdio_barrier "LPX64": Can't allocate page buffer\n",
                          b->ob_oid);
-                rc = -1;
-                goto out_0;
+                return (-1);
         }
 
         rc = obdio_enqueue (conn, b->ob_oid, LCK_PW, 0, getpagesize (), &lh);
@@ -450,14 +390,6 @@ obdio_barrier (struct obdio_conn *conn, struct obdio_barrier *b)
         }
  out_1:
         free (space);
- out_0:
-        rc2 = obdio_close (conn, b->ob_oid, &fh);
-        if (rc == 0 && rc2 != 0) {
-                fprintf (stderr, "obdio_barrier "LPX64": Error on close: %s\n",
-                         b->ob_oid, strerror (errno));
-                rc = rc2;
-        }
-
         return (rc);
 }
 
diff --git a/lustre/utils/parser.c b/lustre/utils/parser.c
index 38752f63c9bb1433944a531dc602be8252ceabea..a2bbe205396257e198956e9f5be8af682d05cb8f 100644
--- a/lustre/utils/parser.c
+++ b/lustre/utils/parser.c
@@ -61,7 +61,7 @@ static int process(char *s, char **next, command_t *lookup, command_t **result,
                    char **prev);
 static void print_commands(char *str, command_t *table);
 
-static char * skipwhitespace(char * s) 
+static char * skipwhitespace(char * s)
 {
         char * t;
         int    len;
@@ -72,7 +72,7 @@ static char * skipwhitespace(char * s)
 }
 
 
-static char * skiptowhitespace(char * s) 
+static char * skiptowhitespace(char * s)
 {
         char * t;
 
@@ -83,13 +83,13 @@ static char * skiptowhitespace(char * s)
 static int line2args(char *line, char **argv, int maxargs)
 {
         char *arg;
-        int i = 0; 
-    
+        int i = 0;
+
         arg = strtok(line, " \t");
         if ( arg ) {
                 argv[i] = arg;
                 i++;
-        } else 
+        } else
                 return 0;
 
         while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) {
@@ -111,7 +111,7 @@ static command_t *Parser_findargcmd(char *name, command_t cmds[])
         return NULL;
 }
 
-void Parser_ignore_errors(int ignore) 
+void Parser_ignore_errors(int ignore)
 {
         ignore_errors = ignore;
 }
@@ -122,9 +122,12 @@ int Parser_execarg(int argc, char **argv, command_t cmds[])
 
         cmd = Parser_findargcmd(argv[0], cmds);
         if ( cmd ) {
-                return (cmd->pc_func)(argc, argv);
+                int rc = (cmd->pc_func)(argc, argv);
+                if (rc == CMD_HELP)
+                        fprintf(stderr, "%s\n", cmd->pc_help);
+                return rc;
         } else {
-                printf("Try interactive use without arguments or use one of:\n");
+		printf("Try interactive use without arguments or use one of:\n");
                 for (cmd = cmds; cmd->pc_name; cmd++)
                         printf("\"%s\"\n", cmd->pc_name);
                 printf("as argument.\n");
@@ -135,20 +138,20 @@ int Parser_execarg(int argc, char **argv, command_t cmds[])
 /* returns the command_t * (NULL if not found) corresponding to a
    _partial_ match with the first token in name.  It sets *next to
    point to the following token. Does not modify *name. */
-static command_t * find_cmd(char * name, command_t cmds[], char ** next) 
+static command_t * find_cmd(char * name, command_t cmds[], char ** next)
 {
         int    i, len;
-    
-        if (!cmds || !name ) 
+
+        if (!cmds || !name )
                 return NULL;
-    
+
         /* This sets name to point to the first non-white space character,
            and next to the first whitespace after name, len to the length: do
            this with strtok*/
         name = skipwhitespace(name);
         *next = skiptowhitespace(name);
         len = *next - name;
-        if (len == 0) 
+        if (len == 0)
                 return NULL;
 
         for (i = 0; cmds[i].pc_name; i++) {
@@ -167,19 +170,37 @@ static int process(char *s, char ** next, command_t *lookup,
                    command_t **result, char **prev)
 {
         *result = find_cmd(s, lookup, next);
-        *prev = s; 
+        *prev = s;
 
         /* non existent */
-        if ( ! *result ) 
+        if (!*result)
                 return CMD_NONE;
 
         /* found entry: is it ambigous, i.e. not exact command name and
            more than one command in the list matches.  Note that find_cmd
            points to the first ambiguous entry */
-        if ( strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name)) &&
-             find_cmd(s, (*result) + 1, next)) 
-                return CMD_AMBIG;
+        if (strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name))) {
+                char *another_next;
+                command_t *another_result = find_cmd(s, (*result) + 1,
+                                                     &another_next);
+                int found_another = 0;
+
+                while (another_result) {
+                        if (strncasecmp(s, another_result->pc_name,
+                                        strlen(another_result->pc_name)) == 0){
+                                *result = another_result;
+                                *next = another_next;
+                                goto got_it;
+                        }
+                        another_result = find_cmd(s, another_result + 1,
+                                                  &another_next);
+                        found_another = 1;
+                }
+                if (found_another)
+                        return CMD_AMBIG;
+        }
 
+got_it:
         /* found a unique command: component or full? */
         if ( (*result)->pc_func ) {
                 return CMD_COMPLETE;
@@ -187,7 +208,8 @@ static int process(char *s, char ** next, command_t *lookup,
                 if ( *next == '\0' ) {
                         return CMD_INCOMPLETE;
                 } else {
-                        return process(*next, next, (*result)->pc_sub_cmd, result, prev);
+                        return process(*next, next, (*result)->pc_sub_cmd,
+                                       result, prev);
                 }
         }
 }
@@ -251,7 +273,7 @@ int execute_line(char * line)
         int         i;
         int rc = 0;
 
-        switch( process(line, &next, top_level, &cmd, &prev) ) {
+        switch (process(line, &next, top_level, &cmd, &prev)) {
         case CMD_AMBIG:
                 fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);
                 while( (ambig = find_cmd(prev, cmd, &tmp)) ) {
@@ -292,9 +314,9 @@ noop_fn ()
         return (0);
 }
 
-/* just in case you're ever in an airplane and discover you 
+/* just in case you're ever in an airplane and discover you
    forgot to install readline-dev. :) */
-int init_input() 
+int init_input()
 {
         int   interactive = isatty (fileno (stdin));
 
@@ -310,13 +332,13 @@ int init_input()
 
         rl_attempted_completion_function = (CPPFunction *)command_completion;
         rl_completion_entry_function = (void *)command_generator;
-#endif 
+#endif
         return interactive;
 }
 
 #ifndef HAVE_LIBREADLINE
 #define add_history(s)
-char * readline(char * prompt) 
+char * readline(char * prompt)
 {
         char line[2048];
         int n = 0;
@@ -337,7 +359,7 @@ int Parser_commands(void)
         char *line, *s;
         int rc = 0, save_error = 0;
         int interactive;
-        
+
         interactive = init_input();
 
         while(!done) {
@@ -368,7 +390,7 @@ int Parser_commands(void)
 
 
 /* sets the parser prompt */
-void Parser_init(char * prompt, command_t * cmds) 
+void Parser_init(char * prompt, command_t * cmds)
 {
         done = 0;
         top_level = cmds;
@@ -377,7 +399,7 @@ void Parser_init(char * prompt, command_t * cmds)
 }
 
 /* frees the parser prompt */
-void Parser_exit(int argc, char *argv[]) 
+void Parser_exit(int argc, char *argv[])
 {
         done = 1;
         free(parser_prompt);
@@ -410,7 +432,7 @@ void Parser_qhelp(int argc, char *argv[]) {
         printf("For more help type: help command-name\n");
 }
 
-int Parser_help(int argc, char **argv) 
+int Parser_help(int argc, char **argv)
 {
         char line[1024];
         char *next, *prev, *tmp;
@@ -454,21 +476,19 @@ int Parser_help(int argc, char **argv)
                 break;
         }
         return 0;
-}  
+}
 
 
 void Parser_printhelp(char *cmd)
 {
-        char *argv[] = { "help", cmd }; 
+        char *argv[] = { "help", cmd };
         Parser_help(2, argv);
 }
 
 
 /*************************************************************************
- * COMMANDS                                                                 *
- *************************************************************************/ 
-
-
+ * COMMANDS                                                              *
+ *************************************************************************/
 static void print_commands(char * str, command_t * table) {
         command_t * cmds;
         char         buf[80];
@@ -489,7 +509,7 @@ static void print_commands(char * str, command_t * table) {
         }
 }
 
-char *Parser_getstr(const char *prompt, const char *deft, char *res, 
+char *Parser_getstr(const char *prompt, const char *deft, char *res,
                     size_t len)
 {
         char *line = NULL;
@@ -573,9 +593,9 @@ int Parser_getbool(const char *prompt, int deft)
         assert(theprompt);
 
         fflush(stdout);
-    
+
         if ( deft != 0 && deft != 1 ) {
-                fprintf(stderr, "Error: Parser_getbool given bad default (%d).\n",
+                fprintf(stderr, "Error: Parser_getbool given bad default %d\n",
                         deft);
                 assert ( 0 );
         }
@@ -600,15 +620,15 @@ int Parser_getbool(const char *prompt, int deft)
                         result = 0;
                         break;
                 }
-                if ( line ) 
+                if ( line )
                         free(line);
                 fprintf(stdout, "Invalid string. Must start with yY or nN\n");
                 fflush(stdout);
         } while ( 1 );
 
-        if ( line ) 
+        if ( line )
                 free(line);
-        if ( theprompt ) 
+        if ( theprompt )
                 free(theprompt);
         return result;
 }
@@ -618,8 +638,8 @@ long Parser_intarg(const char *inp, const char *prompt, int deft,
                    int min, int max, int base)
 {
         long result;
-        int rc; 
-    
+        int rc;
+
         rc = Parser_arg2int(inp, &result, base);
 
         if ( rc == 0 ) {
@@ -635,7 +655,7 @@ char *Parser_strarg(char *inp, const char *prompt, const char *deft,
 {
         if ( inp == NULL || *inp == '\0' ) {
                 return Parser_getstr(prompt, deft, answer, len);
-        } else 
+        } else
                 return inp;
 }
 
@@ -652,7 +672,7 @@ int Parser_arg2int(const char *inp, long *result, int base)
 
         if ( *inp != '\0' && *endptr == '\0' )
                 return 0;
-        else 
+        else
                 return 1;
 }
 
@@ -704,7 +724,7 @@ int Parser_bool (int *b, char *str) {
                 *b = 0;
                 return (0);
         }
-        
+
         if (!strcasecmp (str, "yes") ||
             !strcasecmp (str, "y") ||
             !strcasecmp (str, "on") ||
@@ -714,7 +734,7 @@ int Parser_bool (int *b, char *str) {
                 *b = 1;
                 return (0);
         }
-        
+
         return (-1);
 }
 
diff --git a/lustre/utils/parser.h b/lustre/utils/parser.h
index 5aece60cc49e3b934f70147fa0db013069c7c848..a1f899bfc880e88f8a016743b1b4b9cb433f664a 100644
--- a/lustre/utils/parser.h
+++ b/lustre/utils/parser.h
@@ -2,7 +2,7 @@
 #define _PARSER_H_
 
 #define HISTORY	100		/* Don't let history grow unbounded    */
-#define MAXARGS 100
+#define MAXARGS 512
 
 #define CMD_COMPLETE	0
 #define CMD_INCOMPLETE	1
diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c
index 86ae507c61f7ec39b0dcf3cf93dda8583eb6ad9c..7397fcbf3584fea74f366cbeeb0b04f75c50da7e 100644
--- a/lustre/utils/wirecheck.c
+++ b/lustre/utils/wirecheck.c
@@ -1,588 +1,744 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
 #include <stdio.h>
 #include <liblustre.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
 
-#define BLANK_LINE()				\
-do {						\
-	printf ("\n");				\
-} while (0)
+#define BLANK_LINE()                                            \
+do {                                                            \
+        printf("\n");                                           \
+} while(0)
 
-#define COMMENT(c)				\
-do {						\
-	printf ("        /* "c" */\n");		\
-} while (0)
+#define COMMENT(c)                                              \
+do {                                                            \
+        printf("        /* "c" */\n");                          \
+} while(0)
 
 #define STRINGIFY(a) #a
 
-#define CHECK_DEFINE(a)						\
-do {								\
-	printf("        LASSERT ("#a" == "STRINGIFY(a)");\n");	\
-} while (0)
+#define CHECK_DEFINE(a)                                         \
+do {                                                            \
+        printf("        LASSERT("#a" == "STRINGIFY(a)");\n");   \
+} while(0)
 
-#define CHECK_VALUE(a)					\
-do {							\
-	printf("        LASSERT ("#a" == %d);\n", a);	\
-} while (0)
+#define CHECK_VALUE(a)                                          \
+do {                                                            \
+        printf("        LASSERT("#a" == %d);\n", a);            \
+} while(0)
 
-#define CHECK_MEMBER_OFFSET(s,m)		\
-do {						\
-	CHECK_VALUE(offsetof (struct s, m));	\
-} while (0)
+#define CHECK_MEMBER_OFFSET(s,m)                                \
+do {                                                            \
+        CHECK_VALUE(offsetof(struct s, m));                     \
+} while(0)
 
-#define CHECK_MEMBER_SIZEOF(s,m)			\
-do {							\
-	CHECK_VALUE((int)sizeof(((struct s *)0)->m));	\
-} while (0)
+#define CHECK_MEMBER_SIZEOF(s,m)                                \
+do {                                                            \
+        CHECK_VALUE((int)sizeof(((struct s *)0)->m));           \
+} while(0)
 
-#define CHECK_MEMBER(s,m)			\
-do {						\
-	CHECK_MEMBER_OFFSET(s, m);		\
-	CHECK_MEMBER_SIZEOF(s, m);		\
-} while (0)
+#define CHECK_MEMBER(s,m)                                       \
+do {                                                            \
+        CHECK_MEMBER_OFFSET(s, m);                              \
+                CHECK_MEMBER_SIZEOF(s, m);                      \
+} while(0)
 
-#define CHECK_STRUCT(s)				\
-do {						\
-        COMMENT("Checks for struct "#s);	\
-	CHECK_VALUE((int)sizeof(struct s));	\
-} while (0)
+#define CHECK_STRUCT(s)                                         \
+do {                                                            \
+        COMMENT("Checks for struct "#s);                        \
+                CHECK_VALUE((int)sizeof(struct s));             \
+} while(0)
 
 
 
-void check1 (void)
+void check1(void)
 {
 #define VALUE 1234567
 
-	CHECK_VALUE (VALUE);
-	CHECK_DEFINE (VALUE);
+        CHECK_VALUE(VALUE);
+        CHECK_DEFINE(VALUE);
 }
 
 void
-check_lustre_handle (void) 
+check_lustre_handle(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (lustre_handle);
-	CHECK_MEMBER (lustre_handle, cookie);
+        BLANK_LINE();
+        CHECK_STRUCT(lustre_handle);
+        CHECK_MEMBER(lustre_handle, cookie);
 }
 
 void
-check_lustre_msg (void)
+check_lustre_msg(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (lustre_msg);
-	CHECK_MEMBER (lustre_msg, handle);
-	CHECK_MEMBER (lustre_msg, magic);
-	CHECK_MEMBER (lustre_msg, type);
-	CHECK_MEMBER (lustre_msg, version);
-	CHECK_MEMBER (lustre_msg, opc);
-	CHECK_MEMBER (lustre_msg, last_xid);
-	CHECK_MEMBER (lustre_msg, last_committed);
-	CHECK_MEMBER (lustre_msg, transno);
-	CHECK_MEMBER (lustre_msg, status);
-	CHECK_MEMBER (lustre_msg, flags);
-	CHECK_MEMBER (lustre_msg, bufcount);
-	CHECK_MEMBER (lustre_msg, buflens[7]);
+        BLANK_LINE();
+        CHECK_STRUCT(lustre_msg);
+        CHECK_MEMBER(lustre_msg, handle);
+        CHECK_MEMBER(lustre_msg, magic);
+        CHECK_MEMBER(lustre_msg, type);
+        CHECK_MEMBER(lustre_msg, version);
+        CHECK_MEMBER(lustre_msg, opc);
+        CHECK_MEMBER(lustre_msg, last_xid);
+        CHECK_MEMBER(lustre_msg, last_committed);
+        CHECK_MEMBER(lustre_msg, transno);
+        CHECK_MEMBER(lustre_msg, status);
+        CHECK_MEMBER(lustre_msg, flags);
+        CHECK_MEMBER(lustre_msg, bufcount);
+        CHECK_MEMBER(lustre_msg, buflens[7]);
 }
 
 void
-check_obdo (void)
+check_obdo(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (obdo);
-	CHECK_MEMBER (obdo, o_id);
-	CHECK_MEMBER (obdo, o_gr);
-	CHECK_MEMBER (obdo, o_atime);
-	CHECK_MEMBER (obdo, o_mtime);
-	CHECK_MEMBER (obdo, o_ctime);
-	CHECK_MEMBER (obdo, o_size);
-	CHECK_MEMBER (obdo, o_blocks);
-	CHECK_MEMBER (obdo, o_rdev);
-	CHECK_MEMBER (obdo, o_blksize);
-	CHECK_MEMBER (obdo, o_mode);
-	CHECK_MEMBER (obdo, o_uid);
-	CHECK_MEMBER (obdo, o_gid);
-	CHECK_MEMBER (obdo, o_flags);
-	CHECK_MEMBER (obdo, o_nlink);
-	CHECK_MEMBER (obdo, o_generation);
-	CHECK_MEMBER (obdo, o_valid);
-	CHECK_MEMBER (obdo, o_obdflags);
-	CHECK_MEMBER (obdo, o_easize);
-	CHECK_MEMBER (obdo, o_inline);
+        BLANK_LINE();
+        CHECK_STRUCT(obdo);
+        CHECK_MEMBER(obdo, o_id);
+        CHECK_MEMBER(obdo, o_gr);
+        CHECK_MEMBER(obdo, o_atime);
+        CHECK_MEMBER(obdo, o_mtime);
+        CHECK_MEMBER(obdo, o_ctime);
+        CHECK_MEMBER(obdo, o_size);
+        CHECK_MEMBER(obdo, o_blocks);
+        CHECK_MEMBER(obdo, o_rdev);
+        CHECK_MEMBER(obdo, o_blksize);
+        CHECK_MEMBER(obdo, o_mode);
+        CHECK_MEMBER(obdo, o_uid);
+        CHECK_MEMBER(obdo, o_gid);
+        CHECK_MEMBER(obdo, o_flags);
+        CHECK_MEMBER(obdo, o_nlink);
+        CHECK_MEMBER(obdo, o_generation);
+        CHECK_MEMBER(obdo, o_valid);
+        CHECK_MEMBER(obdo, o_obdflags);
+        CHECK_MEMBER(obdo, o_easize);
+        CHECK_MEMBER(obdo, o_inline);
+
+        CHECK_VALUE(OBD_MD_FLID);
+        CHECK_VALUE(OBD_MD_FLATIME);
+        CHECK_VALUE(OBD_MD_FLMTIME);
+        CHECK_VALUE(OBD_MD_FLCTIME);
+        CHECK_VALUE(OBD_MD_FLSIZE);
+        CHECK_VALUE(OBD_MD_FLBLOCKS);
+        CHECK_VALUE(OBD_MD_FLBLKSZ);
+        CHECK_VALUE(OBD_MD_FLMODE);
+        CHECK_VALUE(OBD_MD_FLTYPE);
+        CHECK_VALUE(OBD_MD_FLUID);
+        CHECK_VALUE(OBD_MD_FLGID);
+        CHECK_VALUE(OBD_MD_FLFLAGS);
+        CHECK_VALUE(OBD_MD_FLOBDFLG);
+        CHECK_VALUE(OBD_MD_FLNLINK);
+        CHECK_VALUE(OBD_MD_FLGENER);
+        CHECK_VALUE(OBD_MD_FLINLINE);
+        CHECK_VALUE(OBD_MD_FLRDEV);
+        CHECK_VALUE(OBD_MD_FLEASIZE);
+        CHECK_VALUE(OBD_MD_LINKNAME);
+        CHECK_VALUE(OBD_MD_FLHANDLE);
+        CHECK_VALUE(OBD_MD_FLCKSUM);
+        CHECK_VALUE(OBD_MD_FLQOS);
+        CHECK_VALUE(OBD_MD_FLOSCOPQ);
+        CHECK_VALUE(OBD_MD_FLCOOKIE);
+        CHECK_VALUE(OBD_MD_FLGROUP);
 }
 
 void
-check_obd_statfs (void)
+check_lov_mds_md_v1(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (obd_statfs);
-	CHECK_MEMBER (obd_statfs, os_type);
-	CHECK_MEMBER (obd_statfs, os_blocks);
-	CHECK_MEMBER (obd_statfs, os_bfree);
-	CHECK_MEMBER (obd_statfs, os_bavail);
-	CHECK_MEMBER (obd_statfs, os_ffree);
-	CHECK_MEMBER (obd_statfs, os_fsid);
-	CHECK_MEMBER (obd_statfs, os_bsize);
-	CHECK_MEMBER (obd_statfs, os_namelen);
+        BLANK_LINE();
+        CHECK_STRUCT(lov_mds_md_v1);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_magic);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_pattern);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_object_id);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_object_gr);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_stripe_size);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_stripe_count);
+        CHECK_MEMBER(lov_mds_md_v1, lmm_objects);
+
+        BLANK_LINE();
+        CHECK_STRUCT(lov_ost_data_v1);
+        CHECK_MEMBER(lov_ost_data_v1, l_object_id);
+        CHECK_MEMBER(lov_ost_data_v1, l_object_gr);
+        CHECK_MEMBER(lov_ost_data_v1, l_ost_gen);
+        CHECK_MEMBER(lov_ost_data_v1, l_ost_idx);
+
+        CHECK_VALUE(LOV_MAGIC_V0);
+        CHECK_VALUE(LOV_MAGIC_V1);
+
+        CHECK_VALUE(LOV_PATTERN_RAID0);
+        CHECK_VALUE(LOV_PATTERN_RAID1);
 }
 
 void
-check_obd_ioobj (void)
+check_obd_statfs(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (obd_ioobj);
-	CHECK_MEMBER (obd_ioobj, ioo_id);
-	CHECK_MEMBER (obd_ioobj, ioo_gr);
-	CHECK_MEMBER (obd_ioobj, ioo_type);
-	CHECK_MEMBER (obd_ioobj, ioo_bufcnt);
+        BLANK_LINE();
+        CHECK_STRUCT(obd_statfs);
+        CHECK_MEMBER(obd_statfs, os_type);
+        CHECK_MEMBER(obd_statfs, os_blocks);
+        CHECK_MEMBER(obd_statfs, os_bfree);
+        CHECK_MEMBER(obd_statfs, os_bavail);
+        CHECK_MEMBER(obd_statfs, os_ffree);
+        CHECK_MEMBER(obd_statfs, os_fsid);
+        CHECK_MEMBER(obd_statfs, os_bsize);
+        CHECK_MEMBER(obd_statfs, os_namelen);
+        CHECK_MEMBER(obd_statfs, os_spare);
 }
 
 void
-check_niobuf_remote (void)
+check_obd_ioobj(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (niobuf_remote);
-	CHECK_MEMBER (niobuf_remote, offset);
-	CHECK_MEMBER (niobuf_remote, len);
-	CHECK_MEMBER (niobuf_remote, flags);
+        BLANK_LINE();
+        CHECK_STRUCT(obd_ioobj);
+        CHECK_MEMBER(obd_ioobj, ioo_id);
+        CHECK_MEMBER(obd_ioobj, ioo_gr);
+        CHECK_MEMBER(obd_ioobj, ioo_type);
+        CHECK_MEMBER(obd_ioobj, ioo_bufcnt);
 }
 
 void
-check_ost_body (void)
+check_niobuf_remote(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ost_body);
-	CHECK_MEMBER (ost_body, oa);
+        BLANK_LINE();
+        CHECK_STRUCT(niobuf_remote);
+        CHECK_MEMBER(niobuf_remote, offset);
+        CHECK_MEMBER(niobuf_remote, len);
+        CHECK_MEMBER(niobuf_remote, flags);
+
+        CHECK_VALUE(OBD_BRW_READ);
+        CHECK_VALUE(OBD_BRW_WRITE);
+        CHECK_VALUE(OBD_BRW_CREATE);
+        CHECK_VALUE(OBD_BRW_SYNC);
 }
 
 void
-check_ll_fid (void)
+check_ost_body(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ll_fid);
-	CHECK_MEMBER (ll_fid, id);
-	CHECK_MEMBER (ll_fid, generation);
-	CHECK_MEMBER (ll_fid, f_type);
+        BLANK_LINE();
+        CHECK_STRUCT(ost_body);
+        CHECK_MEMBER(ost_body, oa);
 }
 
 void
-check_mds_status_req (void)
+check_ll_fid(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_status_req);
-	CHECK_MEMBER (mds_status_req, flags);
-	CHECK_MEMBER (mds_status_req, repbuf);
+        BLANK_LINE();
+        CHECK_STRUCT(ll_fid);
+        CHECK_MEMBER(ll_fid, id);
+        CHECK_MEMBER(ll_fid, generation);
+        CHECK_MEMBER(ll_fid, f_type);
 }
 
 void
-check_mds_fileh_body (void)
+check_mds_status_req(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_fileh_body);
-	CHECK_MEMBER (mds_fileh_body, f_fid);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_status_req);
+        CHECK_MEMBER(mds_status_req, flags);
+        CHECK_MEMBER(mds_status_req, repbuf);
 }
 
 void
-check_mds_body (void)
+check_mds_body(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_body);
-	CHECK_MEMBER (mds_body, fid1);
-	CHECK_MEMBER (mds_body, fid2);
-	CHECK_MEMBER (mds_body, handle);
-	CHECK_MEMBER (mds_body, size);
-	CHECK_MEMBER (mds_body, blocks);
-	CHECK_MEMBER (mds_body, ino);
-	CHECK_MEMBER (mds_body, valid);
-	CHECK_MEMBER (mds_body, fsuid);
-	CHECK_MEMBER (mds_body, fsgid);
-	CHECK_MEMBER (mds_body, capability);
-	CHECK_MEMBER (mds_body, mode);
-	CHECK_MEMBER (mds_body, uid);
-	CHECK_MEMBER (mds_body, gid);
-	CHECK_MEMBER (mds_body, mtime);
-	CHECK_MEMBER (mds_body, ctime);
-	CHECK_MEMBER (mds_body, atime);
-	CHECK_MEMBER (mds_body, flags);
-	CHECK_MEMBER (mds_body, rdev);
-	CHECK_MEMBER (mds_body, nlink);
-	CHECK_MEMBER (mds_body, generation);
-	CHECK_MEMBER (mds_body, suppgid);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_body);
+        CHECK_MEMBER(mds_body, fid1);
+        CHECK_MEMBER(mds_body, fid2);
+        CHECK_MEMBER(mds_body, handle);
+        CHECK_MEMBER(mds_body, size);
+        CHECK_MEMBER(mds_body, blocks);
+        CHECK_MEMBER(mds_body, io_epoch);
+        CHECK_MEMBER(mds_body, ino);
+        CHECK_MEMBER(mds_body, valid);
+        CHECK_MEMBER(mds_body, fsuid);
+        CHECK_MEMBER(mds_body, fsgid);
+        CHECK_MEMBER(mds_body, capability);
+        CHECK_MEMBER(mds_body, mode);
+        CHECK_MEMBER(mds_body, uid);
+        CHECK_MEMBER(mds_body, gid);
+        CHECK_MEMBER(mds_body, mtime);
+        CHECK_MEMBER(mds_body, ctime);
+        CHECK_MEMBER(mds_body, atime);
+        CHECK_MEMBER(mds_body, flags);
+        CHECK_MEMBER(mds_body, rdev);
+        CHECK_MEMBER(mds_body, nlink);
+        CHECK_MEMBER(mds_body, generation);
+        CHECK_MEMBER(mds_body, suppgid);
+        CHECK_MEMBER(mds_body, eadatasize);
+
+        CHECK_VALUE(FMODE_READ);
+        CHECK_VALUE(FMODE_WRITE);
+        CHECK_VALUE(FMODE_EXEC);
+        CHECK_VALUE(MDS_OPEN_CREAT);
+        CHECK_VALUE(MDS_OPEN_EXCL);
+        CHECK_VALUE(MDS_OPEN_APPEND);
+        CHECK_VALUE(MDS_OPEN_SYNC);
+        CHECK_VALUE(MDS_OPEN_DIRECTORY);
+        CHECK_VALUE(MDS_OPEN_DELAY_CREATE);
+        CHECK_VALUE(MDS_OPEN_HAS_EA);
 }
 
 void
-check_mds_rec_setattr (void)
+check_mds_rec_setattr(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_rec_setattr);
-	CHECK_MEMBER (mds_rec_setattr, sa_opcode);
-	CHECK_MEMBER (mds_rec_setattr, sa_fsuid);
-	CHECK_MEMBER (mds_rec_setattr, sa_fsgid);
-	CHECK_MEMBER (mds_rec_setattr, sa_cap);
-	CHECK_MEMBER (mds_rec_setattr, sa_reserved);
-	CHECK_MEMBER (mds_rec_setattr, sa_valid);
-	CHECK_MEMBER (mds_rec_setattr, sa_fid);
-	CHECK_MEMBER (mds_rec_setattr, sa_mode);
-	CHECK_MEMBER (mds_rec_setattr, sa_uid);
-	CHECK_MEMBER (mds_rec_setattr, sa_gid);
-	CHECK_MEMBER (mds_rec_setattr, sa_attr_flags);
-	CHECK_MEMBER (mds_rec_setattr, sa_size);
-	CHECK_MEMBER (mds_rec_setattr, sa_atime);
-	CHECK_MEMBER (mds_rec_setattr, sa_mtime);
-	CHECK_MEMBER (mds_rec_setattr, sa_ctime);
-	CHECK_MEMBER (mds_rec_setattr, sa_suppgid);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_rec_setattr);
+        CHECK_MEMBER(mds_rec_setattr, sa_opcode);
+        CHECK_MEMBER(mds_rec_setattr, sa_fsuid);
+        CHECK_MEMBER(mds_rec_setattr, sa_fsgid);
+        CHECK_MEMBER(mds_rec_setattr, sa_cap);
+        CHECK_MEMBER(mds_rec_setattr, sa_suppgid);
+        CHECK_MEMBER(mds_rec_setattr, sa_valid);
+        CHECK_MEMBER(mds_rec_setattr, sa_fid);
+        CHECK_MEMBER(mds_rec_setattr, sa_mode);
+        CHECK_MEMBER(mds_rec_setattr, sa_uid);
+        CHECK_MEMBER(mds_rec_setattr, sa_gid);
+        CHECK_MEMBER(mds_rec_setattr, sa_attr_flags);
+        CHECK_MEMBER(mds_rec_setattr, sa_size);
+        CHECK_MEMBER(mds_rec_setattr, sa_atime);
+        CHECK_MEMBER(mds_rec_setattr, sa_mtime);
+        CHECK_MEMBER(mds_rec_setattr, sa_ctime);
 }
 
 void
-check_mds_rec_create (void)
+check_mds_rec_create(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_rec_create);
-	CHECK_MEMBER (mds_rec_create, cr_opcode);
-	CHECK_MEMBER (mds_rec_create, cr_fsuid);
-	CHECK_MEMBER (mds_rec_create, cr_fsgid);
-	CHECK_MEMBER (mds_rec_create, cr_cap);
-	CHECK_MEMBER (mds_rec_create, cr_flags);
-	CHECK_MEMBER (mds_rec_create, cr_mode);
-	CHECK_MEMBER (mds_rec_create, cr_fid);
-	CHECK_MEMBER (mds_rec_create, cr_replayfid);
-	CHECK_MEMBER (mds_rec_create, cr_uid);
-	CHECK_MEMBER (mds_rec_create, cr_gid);
-	CHECK_MEMBER (mds_rec_create, cr_time);
-	CHECK_MEMBER (mds_rec_create, cr_rdev);
-	CHECK_MEMBER (mds_rec_create, cr_suppgid);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_rec_create);
+        CHECK_MEMBER(mds_rec_create, cr_opcode);
+        CHECK_MEMBER(mds_rec_create, cr_fsuid);
+        CHECK_MEMBER(mds_rec_create, cr_fsgid);
+        CHECK_MEMBER(mds_rec_create, cr_cap);
+        CHECK_MEMBER(mds_rec_create, cr_flags);
+        CHECK_MEMBER(mds_rec_create, cr_mode);
+        CHECK_MEMBER(mds_rec_create, cr_fid);
+        CHECK_MEMBER(mds_rec_create, cr_replayfid);
+        CHECK_MEMBER(mds_rec_create, cr_time);
+        CHECK_MEMBER(mds_rec_create, cr_rdev);
+        CHECK_MEMBER(mds_rec_create, cr_suppgid);
 }
 
 void
-check_mds_rec_link (void)
+check_mds_rec_link(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_rec_link);
-	CHECK_MEMBER (mds_rec_link, lk_opcode);
-	CHECK_MEMBER (mds_rec_link, lk_fsuid);
-	CHECK_MEMBER (mds_rec_link, lk_fsgid);
-	CHECK_MEMBER (mds_rec_link, lk_cap);
-	CHECK_MEMBER (mds_rec_link, lk_suppgid1);
-	CHECK_MEMBER (mds_rec_link, lk_suppgid2);
-	CHECK_MEMBER (mds_rec_link, lk_fid1);
-	CHECK_MEMBER (mds_rec_link, lk_fid2);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_rec_link);
+        CHECK_MEMBER(mds_rec_link, lk_opcode);
+        CHECK_MEMBER(mds_rec_link, lk_fsuid);
+        CHECK_MEMBER(mds_rec_link, lk_fsgid);
+        CHECK_MEMBER(mds_rec_link, lk_cap);
+        CHECK_MEMBER(mds_rec_link, lk_suppgid1);
+        CHECK_MEMBER(mds_rec_link, lk_suppgid2);
+        CHECK_MEMBER(mds_rec_link, lk_fid1);
+        CHECK_MEMBER(mds_rec_link, lk_fid2);
+        CHECK_MEMBER(mds_rec_link, lk_time);
 }
 
 void
-check_mds_rec_unlink (void)
+check_mds_rec_unlink(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_rec_unlink);
-	CHECK_MEMBER (mds_rec_unlink, ul_opcode);
-	CHECK_MEMBER (mds_rec_unlink, ul_fsuid);
-	CHECK_MEMBER (mds_rec_unlink, ul_fsgid);
-	CHECK_MEMBER (mds_rec_unlink, ul_cap);
-	CHECK_MEMBER (mds_rec_unlink, ul_reserved);
-	CHECK_MEMBER (mds_rec_unlink, ul_mode);
-	CHECK_MEMBER (mds_rec_unlink, ul_suppgid);
-	CHECK_MEMBER (mds_rec_unlink, ul_fid1);
-	CHECK_MEMBER (mds_rec_unlink, ul_fid2);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_rec_unlink);
+        CHECK_MEMBER(mds_rec_unlink, ul_opcode);
+        CHECK_MEMBER(mds_rec_unlink, ul_fsuid);
+        CHECK_MEMBER(mds_rec_unlink, ul_fsgid);
+        CHECK_MEMBER(mds_rec_unlink, ul_cap);
+        CHECK_MEMBER(mds_rec_unlink, ul_suppgid);
+        CHECK_MEMBER(mds_rec_unlink, ul_mode);
+        CHECK_MEMBER(mds_rec_unlink, ul_fid1);
+        CHECK_MEMBER(mds_rec_unlink, ul_fid2);
+        CHECK_MEMBER(mds_rec_unlink, ul_time);
 }
 
 void
-check_mds_rec_rename (void)
+check_mds_rec_rename(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (mds_rec_rename);
-	CHECK_MEMBER (mds_rec_rename, rn_opcode);
-	CHECK_MEMBER (mds_rec_rename, rn_fsuid);
-	CHECK_MEMBER (mds_rec_rename, rn_fsgid);
-	CHECK_MEMBER (mds_rec_rename, rn_cap);
-	CHECK_MEMBER (mds_rec_rename, rn_suppgid1);
-	CHECK_MEMBER (mds_rec_rename, rn_suppgid2);
-	CHECK_MEMBER (mds_rec_rename, rn_fid1);
-	CHECK_MEMBER (mds_rec_rename, rn_fid2);
+        BLANK_LINE();
+        CHECK_STRUCT(mds_rec_rename);
+        CHECK_MEMBER(mds_rec_rename, rn_opcode);
+        CHECK_MEMBER(mds_rec_rename, rn_fsuid);
+        CHECK_MEMBER(mds_rec_rename, rn_fsgid);
+        CHECK_MEMBER(mds_rec_rename, rn_cap);
+        CHECK_MEMBER(mds_rec_rename, rn_suppgid1);
+        CHECK_MEMBER(mds_rec_rename, rn_suppgid2);
+        CHECK_MEMBER(mds_rec_rename, rn_fid1);
+        CHECK_MEMBER(mds_rec_rename, rn_fid2);
+        CHECK_MEMBER(mds_rec_rename, rn_time);
 }
 
 void
-check_lov_desc (void)
+check_lov_desc(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (lov_desc);
-	CHECK_MEMBER (lov_desc, ld_tgt_count);
-	CHECK_MEMBER (lov_desc, ld_active_tgt_count);
-	CHECK_MEMBER (lov_desc, ld_default_stripe_count);
-	CHECK_MEMBER (lov_desc, ld_default_stripe_size);
-	CHECK_MEMBER (lov_desc, ld_default_stripe_offset);
-	CHECK_MEMBER (lov_desc, ld_pattern);
-	CHECK_MEMBER (lov_desc, ld_uuid);
+        BLANK_LINE();
+        CHECK_STRUCT(lov_desc);
+        CHECK_MEMBER(lov_desc, ld_tgt_count);
+        CHECK_MEMBER(lov_desc, ld_active_tgt_count);
+        CHECK_MEMBER(lov_desc, ld_default_stripe_count);
+        CHECK_MEMBER(lov_desc, ld_pattern);
+        CHECK_MEMBER(lov_desc, ld_default_stripe_size);
+        CHECK_MEMBER(lov_desc, ld_default_stripe_offset);
+        CHECK_MEMBER(lov_desc, ld_uuid);
 }
 
 void
-check_ldlm_res_id (void)
+check_ldlm_res_id(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_res_id);
-	CHECK_MEMBER (ldlm_res_id, name[RES_NAME_SIZE]);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_res_id);
+        CHECK_MEMBER(ldlm_res_id, name[RES_NAME_SIZE]);
 }
 
 void
-check_ldlm_extent (void)
+check_ldlm_extent(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_extent);
-	CHECK_MEMBER (ldlm_extent, start);
-	CHECK_MEMBER (ldlm_extent, end);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_extent);
+        CHECK_MEMBER(ldlm_extent, start);
+        CHECK_MEMBER(ldlm_extent, end);
 }
 
 void
-check_ldlm_intent (void)
+check_ldlm_flock(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_intent);
-	CHECK_MEMBER (ldlm_intent, opc);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_flock);
+        CHECK_MEMBER(ldlm_flock, start);
+        CHECK_MEMBER(ldlm_flock, end);
+        CHECK_MEMBER(ldlm_flock, blocking_export);
+        CHECK_MEMBER(ldlm_flock, blocking_pid);
+        CHECK_MEMBER(ldlm_flock, pid);
 }
 
 void
-check_ldlm_resource_desc (void)
+check_ldlm_intent(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_resource_desc);
-	CHECK_MEMBER (ldlm_resource_desc, lr_type);
-	CHECK_MEMBER (ldlm_resource_desc, lr_name);
-	CHECK_MEMBER (ldlm_resource_desc, lr_version[RES_VERSION_SIZE]);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_intent);
+        CHECK_MEMBER(ldlm_intent, opc);
 }
 
 void
-check_ldlm_lock_desc (void)
+check_ldlm_resource_desc(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_lock_desc);
-	CHECK_MEMBER (ldlm_lock_desc, l_resource);
-	CHECK_MEMBER (ldlm_lock_desc, l_req_mode);
-	CHECK_MEMBER (ldlm_lock_desc, l_granted_mode);
-	CHECK_MEMBER (ldlm_lock_desc, l_extent);
-	CHECK_MEMBER (ldlm_lock_desc, l_version[RES_VERSION_SIZE]);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_resource_desc);
+        CHECK_MEMBER(ldlm_resource_desc, lr_type);
+        CHECK_MEMBER(ldlm_resource_desc, lr_name);
+        CHECK_MEMBER(ldlm_resource_desc, lr_version[RES_VERSION_SIZE]);
 }
 
 void
-check_ldlm_request (void)
+check_ldlm_lock_desc(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_request);
-	CHECK_MEMBER (ldlm_request, lock_flags);
-	CHECK_MEMBER (ldlm_request, lock_desc);
-	CHECK_MEMBER (ldlm_request, lock_handle1);
-	CHECK_MEMBER (ldlm_request, lock_handle2);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_lock_desc);
+        CHECK_MEMBER(ldlm_lock_desc, l_resource);
+        CHECK_MEMBER(ldlm_lock_desc, l_req_mode);
+        CHECK_MEMBER(ldlm_lock_desc, l_granted_mode);
+        CHECK_MEMBER(ldlm_lock_desc, l_policy_data);
+        CHECK_MEMBER(ldlm_lock_desc, l_version[RES_VERSION_SIZE]);
 }
 
 void
-check_ldlm_reply (void)
+check_ldlm_request(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ldlm_reply);
-	CHECK_MEMBER (ldlm_reply, lock_flags);
-	CHECK_MEMBER (ldlm_reply, lock_mode);
-	CHECK_MEMBER (ldlm_reply, lock_resource_name);
-	CHECK_MEMBER (ldlm_reply, lock_handle);
-	CHECK_MEMBER (ldlm_reply, lock_extent);
-	CHECK_MEMBER (ldlm_reply, lock_policy_res1);
-	CHECK_MEMBER (ldlm_reply, lock_policy_res2);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_request);
+        CHECK_MEMBER(ldlm_request, lock_flags);
+        CHECK_MEMBER(ldlm_request, lock_desc);
+        CHECK_MEMBER(ldlm_request, lock_handle1);
+        CHECK_MEMBER(ldlm_request, lock_handle2);
 }
 
 void
-check_ptlbd_op (void)
+check_ldlm_reply(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ptlbd_op);
-	CHECK_MEMBER (ptlbd_op, op_cmd);
-	CHECK_MEMBER (ptlbd_op, op_lun);
-	CHECK_MEMBER (ptlbd_op, op_niob_cnt);
-	CHECK_MEMBER (ptlbd_op, op__padding);
-	CHECK_MEMBER (ptlbd_op, op_block_cnt);
+        BLANK_LINE();
+        CHECK_STRUCT(ldlm_reply);
+        CHECK_MEMBER(ldlm_reply, lock_flags);
+        CHECK_MEMBER(ldlm_reply, lock_mode);
+        CHECK_MEMBER(ldlm_reply, lock_resource_name);
+        CHECK_MEMBER(ldlm_reply, lock_handle);
+        CHECK_MEMBER(ldlm_reply, lock_policy_data);
+        CHECK_MEMBER(ldlm_reply, lock_policy_res1);
+        CHECK_MEMBER(ldlm_reply, lock_policy_res2);
 }
 
 void
-check_ptlbd_niob (void)
+check_ptlbd_op(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ptlbd_niob);
-	CHECK_MEMBER (ptlbd_niob, n_xid);
-	CHECK_MEMBER (ptlbd_niob, n_block_nr);
-	CHECK_MEMBER (ptlbd_niob, n_offset);
-	CHECK_MEMBER (ptlbd_niob, n_length);
+        BLANK_LINE();
+        CHECK_STRUCT(ptlbd_op);
+        CHECK_MEMBER(ptlbd_op, op_cmd);
+        CHECK_MEMBER(ptlbd_op, op_lun);
+        CHECK_MEMBER(ptlbd_op, op_niob_cnt);
+        CHECK_MEMBER(ptlbd_op, op__padding);
+        CHECK_MEMBER(ptlbd_op, op_block_cnt);
 }
 
 void
-check_ptlbd_rsp (void)
+check_ptlbd_niob(void)
 {
-	BLANK_LINE ();
-	CHECK_STRUCT (ptlbd_rsp);
-	CHECK_MEMBER (ptlbd_rsp, r_status);
-	CHECK_MEMBER (ptlbd_rsp, r_error_cnt);
+        BLANK_LINE();
+        CHECK_STRUCT(ptlbd_niob);
+        CHECK_MEMBER(ptlbd_niob, n_xid);
+        CHECK_MEMBER(ptlbd_niob, n_block_nr);
+        CHECK_MEMBER(ptlbd_niob, n_offset);
+        CHECK_MEMBER(ptlbd_niob, n_length);
+}
+
+void
+check_ptlbd_rsp(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(ptlbd_rsp);
+        CHECK_MEMBER(ptlbd_rsp, r_status);
+        CHECK_MEMBER(ptlbd_rsp, r_error_cnt);
+}
+
+void
+check_llog_logid(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_logid);
+        CHECK_MEMBER(llog_logid, lgl_oid);
+        CHECK_MEMBER(llog_logid, lgl_ogr);
+        CHECK_MEMBER(llog_logid, lgl_ogen);
+
+        CHECK_VALUE(OST_SZ_REC);
+        CHECK_VALUE(OST_RAID1_REC);
+        CHECK_VALUE(MDS_UNLINK_REC);
+        CHECK_VALUE(OBD_CFG_REC);
+        CHECK_VALUE(PTL_CFG_REC);
+        CHECK_VALUE(LLOG_HDR_MAGIC);
+        CHECK_VALUE(LLOG_LOGID_MAGIC);
+}
+
+void
+check_llog_rec_hdr(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_rec_hdr);
+        CHECK_MEMBER(llog_rec_hdr, lrh_len);
+        CHECK_MEMBER(llog_rec_hdr, lrh_index);
+        CHECK_MEMBER(llog_rec_hdr, lrh_type);
+}
+
+void
+check_llog_rec_tail(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_rec_tail);
+        CHECK_MEMBER(llog_rec_tail, lrt_len);
+        CHECK_MEMBER(llog_rec_tail, lrt_index);
+}
+
+void
+check_llog_log_hdr(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_log_hdr);
+        CHECK_MEMBER(llog_log_hdr, llh_hdr);
+        CHECK_MEMBER(llog_log_hdr, llh_timestamp);
+        CHECK_MEMBER(llog_log_hdr, llh_count);
+        CHECK_MEMBER(llog_log_hdr, llh_bitmap_offset);
+        CHECK_MEMBER(llog_log_hdr, llh_size);
+        CHECK_MEMBER(llog_log_hdr, llh_flags);
+        CHECK_MEMBER(llog_log_hdr, llh_cat_idx);
+        CHECK_MEMBER(llog_log_hdr, llh_tgtuuid);
+        CHECK_MEMBER(llog_log_hdr, llh_reserved);
+        CHECK_MEMBER(llog_log_hdr, llh_bitmap);
+        CHECK_MEMBER(llog_log_hdr, llh_tail);
+}
+
+void
+check_llog_cookie(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_cookie);
+        CHECK_MEMBER(llog_cookie, lgc_lgl);
+        CHECK_MEMBER(llog_cookie, lgc_subsys);
+        CHECK_MEMBER(llog_cookie, lgc_index);
+}
+
+void
+check_llogd_body(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llogd_body);
+        CHECK_MEMBER(llogd_body, lgd_logid);
+        CHECK_MEMBER(llogd_body, lgd_ctxt_idx);
+        CHECK_MEMBER(llogd_body, lgd_llh_flags);
+        CHECK_MEMBER(llogd_body, lgd_index);
+        CHECK_MEMBER(llogd_body, lgd_saved_index);
+        CHECK_MEMBER(llogd_body, lgd_len);
+        CHECK_MEMBER(llogd_body, lgd_cur_offset);
+
+        CHECK_VALUE(LLOG_ORIGIN_HANDLE_CREATE);
+        CHECK_VALUE(LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
+        CHECK_VALUE(LLOG_ORIGIN_HANDLE_READ_HEADER);
+        CHECK_VALUE(LLOG_ORIGIN_HANDLE_WRITE_REC);
+        CHECK_VALUE(LLOG_ORIGIN_HANDLE_CLOSE);
+}
+
+void
+check_llog_ctxt_gen(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llog_ctxt_gen);
+        CHECK_MEMBER(llog_ctxt_gen, mnt_cnt);
+        CHECK_MEMBER(llog_ctxt_gen, conn_cnt);
+}
+
+void
+check_llogd_conn_body(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(llogd_conn_body);
+        CHECK_MEMBER(llogd_conn_body, lgdc_gen);
+        CHECK_MEMBER(llogd_conn_body, lgdc_logid);
+        CHECK_MEMBER(llogd_conn_body, lgdc_ctxt_idx);
 }
 
 int
-main (int argc, char **argv)
-{
-	printf ("void lustre_assert_wire_constants (void)\n"
-		"{\n");
-
-	COMMENT ("Wire protocol assertions generated by 'wirecheck'");
-	BLANK_LINE ();
-	
-	COMMENT ("Constants...");
-	CHECK_DEFINE (PTLRPC_MSG_MAGIC);
-	CHECK_DEFINE (PTLRPC_MSG_VERSION);
-
-	CHECK_VALUE (PTL_RPC_MSG_REQUEST);
-	CHECK_VALUE (PTL_RPC_MSG_ERR);
-	CHECK_VALUE (PTL_RPC_MSG_REPLY);
-
-	CHECK_VALUE (MSG_LAST_REPLAY);
-	CHECK_VALUE (MSG_RESENT);
-	
-	CHECK_VALUE (MSG_CONNECT_RECOVERING);
-	CHECK_VALUE (MSG_CONNECT_RECONNECT);
-	CHECK_VALUE (MSG_CONNECT_REPLAYABLE);
-	
-	CHECK_VALUE (OST_REPLY);
-	CHECK_VALUE (OST_GETATTR);
-	CHECK_VALUE (OST_SETATTR);
-	CHECK_VALUE (OST_READ);
-	CHECK_VALUE (OST_WRITE);
-	CHECK_VALUE (OST_CREATE);
-	CHECK_VALUE (OST_DESTROY);
-	CHECK_VALUE (OST_GET_INFO);
-	CHECK_VALUE (OST_CONNECT);
-	CHECK_VALUE (OST_DISCONNECT);
-	CHECK_VALUE (OST_PUNCH);
-	CHECK_VALUE (OST_OPEN);
-	CHECK_VALUE (OST_CLOSE);
-	CHECK_VALUE (OST_STATFS);
-	CHECK_VALUE (OST_SAN_READ);
-	CHECK_VALUE (OST_SAN_WRITE);
-	CHECK_VALUE (OST_SYNCFS);
-	CHECK_VALUE (OST_LAST_OPC);
-	CHECK_VALUE (OST_FIRST_OPC);
-
-	CHECK_VALUE (OBD_FL_INLINEDATA);
-	CHECK_VALUE (OBD_FL_OBDMDEXISTS);
-
-	CHECK_VALUE (LOV_MAGIC);
-
-	CHECK_VALUE (OBD_MD_FLALL);
-	CHECK_VALUE (OBD_MD_FLID);
-	CHECK_VALUE (OBD_MD_FLATIME);
-	CHECK_VALUE (OBD_MD_FLMTIME);
-	CHECK_VALUE (OBD_MD_FLCTIME);
-	CHECK_VALUE (OBD_MD_FLSIZE);
-	CHECK_VALUE (OBD_MD_FLBLOCKS);
-	CHECK_VALUE (OBD_MD_FLBLKSZ);
-	CHECK_VALUE (OBD_MD_FLMODE);
-	CHECK_VALUE (OBD_MD_FLTYPE);
-	CHECK_VALUE (OBD_MD_FLUID);
-	CHECK_VALUE (OBD_MD_FLGID);
-	CHECK_VALUE (OBD_MD_FLFLAGS);
-	CHECK_VALUE (OBD_MD_FLOBDFLG);
-	CHECK_VALUE (OBD_MD_FLNLINK);
-	CHECK_VALUE (OBD_MD_FLGENER);
-	CHECK_VALUE (OBD_MD_FLINLINE);
-	CHECK_VALUE (OBD_MD_FLRDEV);
-	CHECK_VALUE (OBD_MD_FLEASIZE);
-	CHECK_VALUE (OBD_MD_LINKNAME);
-	CHECK_VALUE (OBD_MD_FLHANDLE);
-	CHECK_VALUE (OBD_MD_FLCKSUM);
-
-	CHECK_VALUE (OBD_BRW_READ);
-	CHECK_VALUE (OBD_BRW_WRITE);
-	CHECK_VALUE (OBD_BRW_CREATE);
-	CHECK_VALUE (OBD_BRW_SYNC);
-
-	CHECK_DEFINE (OBD_OBJECT_EOF);
-
-	CHECK_VALUE (OST_REQ_HAS_OA1);
-
-	CHECK_VALUE (MDS_GETATTR);
-	CHECK_VALUE (MDS_GETATTR_NAME);
-	CHECK_VALUE (MDS_CLOSE);
-	CHECK_VALUE (MDS_REINT);
-	CHECK_VALUE (MDS_READPAGE);
-	CHECK_VALUE (MDS_CONNECT);
-	CHECK_VALUE (MDS_DISCONNECT);
-	CHECK_VALUE (MDS_GETSTATUS);
-	CHECK_VALUE (MDS_STATFS);
-	CHECK_VALUE (MDS_GETLOVINFO);
-	CHECK_VALUE (MDS_LAST_OPC);
-	CHECK_VALUE (MDS_FIRST_OPC);
-
-	CHECK_VALUE (REINT_SETATTR);
-	CHECK_VALUE (REINT_CREATE);
-	CHECK_VALUE (REINT_LINK);
-	CHECK_VALUE (REINT_UNLINK);
-	CHECK_VALUE (REINT_RENAME);
-	CHECK_VALUE (REINT_OPEN);
-	CHECK_VALUE (REINT_MAX);
-
-	CHECK_VALUE (DISP_IT_EXECD);
-	CHECK_VALUE (DISP_LOOKUP_EXECD);
-	CHECK_VALUE (DISP_LOOKUP_NEG);
-	CHECK_VALUE (DISP_LOOKUP_POS);
-	CHECK_VALUE (DISP_OPEN_CREATE);
-	CHECK_VALUE (DISP_OPEN_OPEN);
-
-	CHECK_VALUE (MDS_STATUS_CONN);
-	CHECK_VALUE (MDS_STATUS_LOV);
-
-	CHECK_VALUE (MDS_OPEN_HAS_EA);
-
-	CHECK_VALUE (LOV_RAID0);
-	CHECK_VALUE (LOV_RAIDRR);
-
-	CHECK_VALUE (LDLM_ENQUEUE);
-	CHECK_VALUE (LDLM_CONVERT);
-	CHECK_VALUE (LDLM_CANCEL);
-	CHECK_VALUE (LDLM_BL_CALLBACK);
-	CHECK_VALUE (LDLM_CP_CALLBACK);
-	CHECK_VALUE (LDLM_LAST_OPC);
-	CHECK_VALUE (LDLM_FIRST_OPC);
-
-        CHECK_VALUE (PTLBD_QUERY);
-        CHECK_VALUE (PTLBD_READ);
-        CHECK_VALUE (PTLBD_WRITE);
-        CHECK_VALUE (PTLBD_FLUSH);
-        CHECK_VALUE (PTLBD_CONNECT);
-        CHECK_VALUE (PTLBD_DISCONNECT);
-	CHECK_VALUE (PTLBD_LAST_OPC);
-	CHECK_VALUE (PTLBD_FIRST_OPC);
-
-	CHECK_VALUE (OBD_PING);
-
-	COMMENT ("Sizes and Offsets");
-	BLANK_LINE ();
-	check_lustre_handle ();
-	check_lustre_msg ();
-	check_obdo ();
-	check_obd_statfs ();
-	check_obd_ioobj ();
-	check_niobuf_remote ();
-	check_ost_body ();
-	check_ll_fid ();
-	check_mds_status_req ();
-	check_mds_fileh_body ();
-	check_mds_body ();
-	check_mds_rec_setattr ();
-	check_mds_rec_create ();
-	check_mds_rec_link ();
-	check_mds_rec_unlink ();
-	check_mds_rec_rename ();
-	check_lov_desc ();
-	check_ldlm_res_id ();
-	check_ldlm_extent ();
-	check_ldlm_intent ();
-	check_ldlm_resource_desc ();
-	check_ldlm_lock_desc ();
-	check_ldlm_request ();
-	check_ldlm_reply ();
-	check_ptlbd_op ();
-	check_ptlbd_niob ();
-	check_ptlbd_rsp ();
-
-	printf ("}\n\n");
-	
-	return (0);
+main(int argc, char **argv)
+{
+        printf("void lustre_assert_wire_constants(void)\n"
+               "{\n");
+
+        COMMENT("Wire protocol assertions generated by 'wirecheck'");
+        BLANK_LINE();
+
+        COMMENT("Constants...");
+        CHECK_DEFINE(PTLRPC_MSG_MAGIC);
+        CHECK_DEFINE(PTLRPC_MSG_VERSION);
+
+        CHECK_VALUE(PTL_RPC_MSG_REQUEST);
+        CHECK_VALUE(PTL_RPC_MSG_ERR);
+        CHECK_VALUE(PTL_RPC_MSG_REPLY);
+
+        CHECK_VALUE(MSG_LAST_REPLAY);
+        CHECK_VALUE(MSG_RESENT);
+
+        CHECK_VALUE(MSG_CONNECT_RECOVERING);
+        CHECK_VALUE(MSG_CONNECT_RECONNECT);
+        CHECK_VALUE(MSG_CONNECT_REPLAYABLE);
+
+        CHECK_VALUE(OST_REPLY);
+        CHECK_VALUE(OST_GETATTR);
+        CHECK_VALUE(OST_SETATTR);
+        CHECK_VALUE(OST_READ);
+        CHECK_VALUE(OST_WRITE);
+        CHECK_VALUE(OST_CREATE);
+        CHECK_VALUE(OST_DESTROY);
+        CHECK_VALUE(OST_GET_INFO);
+        CHECK_VALUE(OST_CONNECT);
+        CHECK_VALUE(OST_DISCONNECT);
+        CHECK_VALUE(OST_PUNCH);
+        CHECK_VALUE(OST_OPEN);
+        CHECK_VALUE(OST_CLOSE);
+        CHECK_VALUE(OST_STATFS);
+        CHECK_VALUE(OST_SAN_READ);
+        CHECK_VALUE(OST_SAN_WRITE);
+        CHECK_VALUE(OST_SYNC);
+        CHECK_VALUE(OST_LAST_OPC);
+        CHECK_VALUE(OST_FIRST_OPC);
+
+        CHECK_VALUE(OBD_FL_INLINEDATA);
+        CHECK_VALUE(OBD_FL_OBDMDEXISTS);
+
+        CHECK_DEFINE(OBD_OBJECT_EOF);
+
+        CHECK_VALUE(OST_REQ_HAS_OA1);
+
+        CHECK_VALUE(MDS_GETATTR);
+        CHECK_VALUE(MDS_GETATTR_NAME);
+        CHECK_VALUE(MDS_CLOSE);
+        CHECK_VALUE(MDS_REINT);
+        CHECK_VALUE(MDS_READPAGE);
+        CHECK_VALUE(MDS_CONNECT);
+        CHECK_VALUE(MDS_DISCONNECT);
+        CHECK_VALUE(MDS_GETSTATUS);
+        CHECK_VALUE(MDS_STATFS);
+        CHECK_VALUE(MDS_LAST_OPC);
+        CHECK_VALUE(MDS_FIRST_OPC);
+
+        CHECK_VALUE(REINT_SETATTR);
+        CHECK_VALUE(REINT_CREATE);
+        CHECK_VALUE(REINT_LINK);
+        CHECK_VALUE(REINT_UNLINK);
+        CHECK_VALUE(REINT_RENAME);
+        CHECK_VALUE(REINT_OPEN);
+        CHECK_VALUE(REINT_MAX);
+
+        CHECK_VALUE(DISP_IT_EXECD);
+        CHECK_VALUE(DISP_LOOKUP_EXECD);
+        CHECK_VALUE(DISP_LOOKUP_NEG);
+        CHECK_VALUE(DISP_LOOKUP_POS);
+        CHECK_VALUE(DISP_OPEN_CREATE);
+        CHECK_VALUE(DISP_OPEN_OPEN);
+
+        CHECK_VALUE(MDS_STATUS_CONN);
+        CHECK_VALUE(MDS_STATUS_LOV);
+
+        CHECK_VALUE(MDS_OPEN_HAS_EA);
+
+        CHECK_VALUE(LDLM_ENQUEUE);
+        CHECK_VALUE(LDLM_CONVERT);
+        CHECK_VALUE(LDLM_CANCEL);
+        CHECK_VALUE(LDLM_BL_CALLBACK);
+        CHECK_VALUE(LDLM_CP_CALLBACK);
+        CHECK_VALUE(LDLM_LAST_OPC);
+        CHECK_VALUE(LDLM_FIRST_OPC);
+
+        CHECK_VALUE(PTLBD_QUERY);
+        CHECK_VALUE(PTLBD_READ);
+        CHECK_VALUE(PTLBD_WRITE);
+        CHECK_VALUE(PTLBD_FLUSH);
+        CHECK_VALUE(PTLBD_CONNECT);
+        CHECK_VALUE(PTLBD_DISCONNECT);
+        CHECK_VALUE(PTLBD_LAST_OPC);
+        CHECK_VALUE(PTLBD_FIRST_OPC);
+
+        CHECK_VALUE(OBD_PING);
+
+        COMMENT("Sizes and Offsets");
+        BLANK_LINE();
+        check_lustre_handle();
+        check_lustre_msg();
+        check_obdo();
+        check_lov_mds_md_v1();
+        check_obd_statfs();
+        check_obd_ioobj();
+        check_niobuf_remote();
+        check_ost_body();
+        check_ll_fid();
+        check_mds_status_req();
+        check_mds_body();
+        check_mds_rec_setattr();
+        check_mds_rec_create();
+        check_mds_rec_link();
+        check_mds_rec_unlink();
+        check_mds_rec_rename();
+        check_lov_desc();
+        check_ldlm_res_id();
+        check_ldlm_extent();
+        check_ldlm_flock();
+        check_ldlm_intent();
+        check_ldlm_resource_desc();
+        check_ldlm_lock_desc();
+        check_ldlm_request();
+        check_ldlm_reply();
+        check_ptlbd_op();
+        check_ptlbd_niob();
+        check_ptlbd_rsp();
+        check_llog_logid();
+        check_llog_rec_hdr();
+        check_llog_rec_tail();
+        check_llog_log_hdr();
+        check_llog_cookie();
+        check_llogd_body();
+        check_llogd_conn_body();
+
+        printf("}\n\n");
+
+        return(0);
 }
diff --git a/lustre/utils/wirehdr.c b/lustre/utils/wirehdr.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b1b65f34eee906339bae1996a87433d938e1433
--- /dev/null
+++ b/lustre/utils/wirehdr.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <liblustre.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+
+#undef LASSERT
+#define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; }
+
+int ret;
+
+void lustre_assert_wire_constants(void);
+
+int main()
+{
+	lustre_assert_wire_constants();
+
+	return ret;
+}
diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a37aa43fc0dca7d89a6a329729c0f2526355df7
--- /dev/null
+++ b/lustre/utils/wiretest.c
@@ -0,0 +1,704 @@
+#include <stdio.h>
+#include <liblustre.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+
+#undef LASSERT
+#define LASSERT(cond) if (!(cond)) { printf("failed " #cond "\n"); ret = 1; }
+
+int ret;
+
+void lustre_assert_wire_constants(void);
+
+int main()
+{
+	lustre_assert_wire_constants();
+
+	return ret;
+}
+void lustre_assert_wire_constants(void)
+{
+        /* Wire protocol assertions generated by 'wirecheck' */
+
+        /* Constants... */
+        LASSERT(PTLRPC_MSG_MAGIC == 0x0BD00BD0);
+        LASSERT(PTLRPC_MSG_VERSION == 0x00000003);
+        LASSERT(PTL_RPC_MSG_REQUEST == 4711);
+        LASSERT(PTL_RPC_MSG_ERR == 4712);
+        LASSERT(PTL_RPC_MSG_REPLY == 4713);
+        LASSERT(MSG_LAST_REPLAY == 1);
+        LASSERT(MSG_RESENT == 2);
+        LASSERT(MSG_CONNECT_RECOVERING == 1);
+        LASSERT(MSG_CONNECT_RECONNECT == 2);
+        LASSERT(MSG_CONNECT_REPLAYABLE == 4);
+        LASSERT(OST_REPLY == 0);
+        LASSERT(OST_GETATTR == 1);
+        LASSERT(OST_SETATTR == 2);
+        LASSERT(OST_READ == 3);
+        LASSERT(OST_WRITE == 4);
+        LASSERT(OST_CREATE == 5);
+        LASSERT(OST_DESTROY == 6);
+        LASSERT(OST_GET_INFO == 7);
+        LASSERT(OST_CONNECT == 8);
+        LASSERT(OST_DISCONNECT == 9);
+        LASSERT(OST_PUNCH == 10);
+        LASSERT(OST_OPEN == 11);
+        LASSERT(OST_CLOSE == 12);
+        LASSERT(OST_STATFS == 13);
+        LASSERT(OST_SAN_READ == 14);
+        LASSERT(OST_SAN_WRITE == 15);
+        LASSERT(OST_SYNC == 16);
+        LASSERT(OST_LAST_OPC == 18);
+        LASSERT(OST_FIRST_OPC == 0);
+        LASSERT(OBD_FL_INLINEDATA == 1);
+        LASSERT(OBD_FL_OBDMDEXISTS == 2);
+        LASSERT(OBD_OBJECT_EOF == 0xffffffffffffffffULL);
+        LASSERT(OST_REQ_HAS_OA1 == 1);
+        LASSERT(MDS_GETATTR == 33);
+        LASSERT(MDS_GETATTR_NAME == 34);
+        LASSERT(MDS_CLOSE == 35);
+        LASSERT(MDS_REINT == 36);
+        LASSERT(MDS_READPAGE == 37);
+        LASSERT(MDS_CONNECT == 38);
+        LASSERT(MDS_DISCONNECT == 39);
+        LASSERT(MDS_GETSTATUS == 40);
+        LASSERT(MDS_STATFS == 41);
+        LASSERT(MDS_LAST_OPC == 45);
+        LASSERT(MDS_FIRST_OPC == 33);
+        LASSERT(REINT_SETATTR == 1);
+        LASSERT(REINT_CREATE == 2);
+        LASSERT(REINT_LINK == 3);
+        LASSERT(REINT_UNLINK == 4);
+        LASSERT(REINT_RENAME == 5);
+        LASSERT(REINT_OPEN == 6);
+        LASSERT(REINT_MAX == 6);
+        LASSERT(DISP_IT_EXECD == 1);
+        LASSERT(DISP_LOOKUP_EXECD == 2);
+        LASSERT(DISP_LOOKUP_NEG == 4);
+        LASSERT(DISP_LOOKUP_POS == 8);
+        LASSERT(DISP_OPEN_CREATE == 16);
+        LASSERT(DISP_OPEN_OPEN == 32);
+        LASSERT(MDS_STATUS_CONN == 1);
+        LASSERT(MDS_STATUS_LOV == 2);
+        LASSERT(MDS_OPEN_HAS_EA == 1073741824);
+        LASSERT(LDLM_ENQUEUE == 101);
+        LASSERT(LDLM_CONVERT == 102);
+        LASSERT(LDLM_CANCEL == 103);
+        LASSERT(LDLM_BL_CALLBACK == 104);
+        LASSERT(LDLM_CP_CALLBACK == 105);
+        LASSERT(LDLM_LAST_OPC == 106);
+        LASSERT(LDLM_FIRST_OPC == 101);
+        LASSERT(PTLBD_QUERY == 200);
+        LASSERT(PTLBD_READ == 201);
+        LASSERT(PTLBD_WRITE == 202);
+        LASSERT(PTLBD_FLUSH == 203);
+        LASSERT(PTLBD_CONNECT == 204);
+        LASSERT(PTLBD_DISCONNECT == 205);
+        LASSERT(PTLBD_LAST_OPC == 206);
+        LASSERT(PTLBD_FIRST_OPC == 200);
+        LASSERT(OBD_PING == 400);
+        /* Sizes and Offsets */
+
+
+        /* Checks for struct lustre_handle */
+        LASSERT((int)sizeof(struct lustre_handle) == 8);
+        LASSERT(offsetof(struct lustre_handle, cookie) == 0);
+        LASSERT((int)sizeof(((struct lustre_handle *)0)->cookie) == 8);
+
+        /* Checks for struct lustre_msg */
+        LASSERT((int)sizeof(struct lustre_msg) == 64);
+        LASSERT(offsetof(struct lustre_msg, handle) == 0);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->handle) == 8);
+        LASSERT(offsetof(struct lustre_msg, magic) == 8);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->magic) == 4);
+        LASSERT(offsetof(struct lustre_msg, type) == 12);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->type) == 4);
+        LASSERT(offsetof(struct lustre_msg, version) == 16);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->version) == 4);
+        LASSERT(offsetof(struct lustre_msg, opc) == 20);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->opc) == 4);
+        LASSERT(offsetof(struct lustre_msg, last_xid) == 24);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->last_xid) == 8);
+        LASSERT(offsetof(struct lustre_msg, last_committed) == 32);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->last_committed) == 8);
+        LASSERT(offsetof(struct lustre_msg, transno) == 40);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->transno) == 8);
+        LASSERT(offsetof(struct lustre_msg, status) == 48);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->status) == 4);
+        LASSERT(offsetof(struct lustre_msg, flags) == 52);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->flags) == 4);
+        LASSERT(offsetof(struct lustre_msg, bufcount) == 60);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->bufcount) == 4);
+        LASSERT(offsetof(struct lustre_msg, buflens[7]) == 92);
+        LASSERT((int)sizeof(((struct lustre_msg *)0)->buflens[7]) == 4);
+
+        /* Checks for struct obdo */
+        LASSERT((int)sizeof(struct obdo) == 168);
+        LASSERT(offsetof(struct obdo, o_id) == 0);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_id) == 8);
+        LASSERT(offsetof(struct obdo, o_gr) == 8);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_gr) == 8);
+        LASSERT(offsetof(struct obdo, o_atime) == 16);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_atime) == 8);
+        LASSERT(offsetof(struct obdo, o_mtime) == 24);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_mtime) == 8);
+        LASSERT(offsetof(struct obdo, o_ctime) == 32);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_ctime) == 8);
+        LASSERT(offsetof(struct obdo, o_size) == 40);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_size) == 8);
+        LASSERT(offsetof(struct obdo, o_blocks) == 48);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_blocks) == 8);
+        LASSERT(offsetof(struct obdo, o_rdev) == 56);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_rdev) == 8);
+        LASSERT(offsetof(struct obdo, o_blksize) == 64);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_blksize) == 4);
+        LASSERT(offsetof(struct obdo, o_mode) == 68);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_mode) == 4);
+        LASSERT(offsetof(struct obdo, o_uid) == 72);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_uid) == 4);
+        LASSERT(offsetof(struct obdo, o_gid) == 76);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_gid) == 4);
+        LASSERT(offsetof(struct obdo, o_flags) == 80);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_flags) == 4);
+        LASSERT(offsetof(struct obdo, o_nlink) == 84);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_nlink) == 4);
+        LASSERT(offsetof(struct obdo, o_generation) == 88);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_generation) == 4);
+        LASSERT(offsetof(struct obdo, o_valid) == 92);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_valid) == 4);
+        LASSERT(offsetof(struct obdo, o_obdflags) == 96);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_obdflags) == 4);
+        LASSERT(offsetof(struct obdo, o_easize) == 100);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_easize) == 4);
+        LASSERT(offsetof(struct obdo, o_inline) == 104);
+        LASSERT((int)sizeof(((struct obdo *)0)->o_inline) == 64);
+        LASSERT(OBD_MD_FLID == 1);
+        LASSERT(OBD_MD_FLATIME == 2);
+        LASSERT(OBD_MD_FLMTIME == 4);
+        LASSERT(OBD_MD_FLCTIME == 8);
+        LASSERT(OBD_MD_FLSIZE == 16);
+        LASSERT(OBD_MD_FLBLOCKS == 32);
+        LASSERT(OBD_MD_FLBLKSZ == 64);
+        LASSERT(OBD_MD_FLMODE == 128);
+        LASSERT(OBD_MD_FLTYPE == 256);
+        LASSERT(OBD_MD_FLUID == 512);
+        LASSERT(OBD_MD_FLGID == 1024);
+        LASSERT(OBD_MD_FLFLAGS == 2048);
+        LASSERT(OBD_MD_FLOBDFLG == 4096);
+        LASSERT(OBD_MD_FLNLINK == 8192);
+        LASSERT(OBD_MD_FLGENER == 16384);
+        LASSERT(OBD_MD_FLINLINE == 32768);
+        LASSERT(OBD_MD_FLRDEV == 65536);
+        LASSERT(OBD_MD_FLEASIZE == 131072);
+        LASSERT(OBD_MD_LINKNAME == 262144);
+        LASSERT(OBD_MD_FLHANDLE == 524288);
+        LASSERT(OBD_MD_FLCKSUM == 1048576);
+        LASSERT(OBD_MD_FLQOS == 2097152);
+        LASSERT(OBD_MD_FLOSCOPQ == 4194304);
+        LASSERT(OBD_MD_FLCOOKIE == 8388608);
+        LASSERT(OBD_MD_FLGROUP == 16777216);
+
+        /* Checks for struct lov_mds_md_v1 */
+        LASSERT((int)sizeof(struct lov_mds_md_v1) == 32);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_magic) == 0);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_magic) == 4);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_pattern) == 4);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_pattern) == 4);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_object_id) == 8);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_object_id) == 8);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_object_gr) == 16);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_object_gr) == 8);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_stripe_size) == 24);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_stripe_size) == 4);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_stripe_count) == 28);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_stripe_count) == 4);
+        LASSERT(offsetof(struct lov_mds_md_v1, lmm_objects) == 32);
+        LASSERT((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_objects) == 0);
+
+        /* Checks for struct lov_ost_data_v1 */
+        LASSERT((int)sizeof(struct lov_ost_data_v1) == 24);
+        LASSERT(offsetof(struct lov_ost_data_v1, l_object_id) == 0);
+        LASSERT((int)sizeof(((struct lov_ost_data_v1 *)0)->l_object_id) == 8);
+        LASSERT(offsetof(struct lov_ost_data_v1, l_object_gr) == 8);
+        LASSERT((int)sizeof(((struct lov_ost_data_v1 *)0)->l_object_gr) == 8);
+        LASSERT(offsetof(struct lov_ost_data_v1, l_ost_gen) == 16);
+        LASSERT((int)sizeof(((struct lov_ost_data_v1 *)0)->l_ost_gen) == 4);
+        LASSERT(offsetof(struct lov_ost_data_v1, l_ost_idx) == 20);
+        LASSERT((int)sizeof(((struct lov_ost_data_v1 *)0)->l_ost_idx) == 4);
+        LASSERT(LOV_MAGIC_V0 == 198183888);
+        LASSERT(LOV_MAGIC_V1 == 198249424);
+        LASSERT(LOV_PATTERN_RAID0 == 1);
+        LASSERT(LOV_PATTERN_RAID1 == 2);
+
+        /* Checks for struct obd_statfs */
+        LASSERT((int)sizeof(struct obd_statfs) == 144);
+        LASSERT(offsetof(struct obd_statfs, os_type) == 0);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_type) == 8);
+        LASSERT(offsetof(struct obd_statfs, os_blocks) == 8);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_blocks) == 8);
+        LASSERT(offsetof(struct obd_statfs, os_bfree) == 16);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_bfree) == 8);
+        LASSERT(offsetof(struct obd_statfs, os_bavail) == 24);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_bavail) == 8);
+        LASSERT(offsetof(struct obd_statfs, os_ffree) == 40);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_ffree) == 8);
+        LASSERT(offsetof(struct obd_statfs, os_fsid) == 48);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_fsid) == 40);
+        LASSERT(offsetof(struct obd_statfs, os_bsize) == 88);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_bsize) == 4);
+        LASSERT(offsetof(struct obd_statfs, os_namelen) == 92);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_namelen) == 4);
+        LASSERT(offsetof(struct obd_statfs, os_spare) == 104);
+        LASSERT((int)sizeof(((struct obd_statfs *)0)->os_spare) == 40);
+
+        /* Checks for struct obd_ioobj */
+        LASSERT((int)sizeof(struct obd_ioobj) == 24);
+        LASSERT(offsetof(struct obd_ioobj, ioo_id) == 0);
+        LASSERT((int)sizeof(((struct obd_ioobj *)0)->ioo_id) == 8);
+        LASSERT(offsetof(struct obd_ioobj, ioo_gr) == 8);
+        LASSERT((int)sizeof(((struct obd_ioobj *)0)->ioo_gr) == 8);
+        LASSERT(offsetof(struct obd_ioobj, ioo_type) == 16);
+        LASSERT((int)sizeof(((struct obd_ioobj *)0)->ioo_type) == 4);
+        LASSERT(offsetof(struct obd_ioobj, ioo_bufcnt) == 20);
+        LASSERT((int)sizeof(((struct obd_ioobj *)0)->ioo_bufcnt) == 4);
+
+        /* Checks for struct niobuf_remote */
+        LASSERT((int)sizeof(struct niobuf_remote) == 16);
+        LASSERT(offsetof(struct niobuf_remote, offset) == 0);
+        LASSERT((int)sizeof(((struct niobuf_remote *)0)->offset) == 8);
+        LASSERT(offsetof(struct niobuf_remote, len) == 8);
+        LASSERT((int)sizeof(((struct niobuf_remote *)0)->len) == 4);
+        LASSERT(offsetof(struct niobuf_remote, flags) == 12);
+        LASSERT((int)sizeof(((struct niobuf_remote *)0)->flags) == 4);
+        LASSERT(OBD_BRW_READ == 1);
+        LASSERT(OBD_BRW_WRITE == 2);
+        LASSERT(OBD_BRW_CREATE == 4);
+        LASSERT(OBD_BRW_SYNC == 8);
+
+        /* Checks for struct ost_body */
+        LASSERT((int)sizeof(struct ost_body) == 168);
+        LASSERT(offsetof(struct ost_body, oa) == 0);
+        LASSERT((int)sizeof(((struct ost_body *)0)->oa) == 168);
+
+        /* Checks for struct ll_fid */
+        LASSERT((int)sizeof(struct ll_fid) == 16);
+        LASSERT(offsetof(struct ll_fid, id) == 0);
+        LASSERT((int)sizeof(((struct ll_fid *)0)->id) == 8);
+        LASSERT(offsetof(struct ll_fid, generation) == 8);
+        LASSERT((int)sizeof(((struct ll_fid *)0)->generation) == 4);
+        LASSERT(offsetof(struct ll_fid, f_type) == 12);
+        LASSERT((int)sizeof(((struct ll_fid *)0)->f_type) == 4);
+
+        /* Checks for struct mds_status_req */
+        LASSERT((int)sizeof(struct mds_status_req) == 8);
+        LASSERT(offsetof(struct mds_status_req, flags) == 0);
+        LASSERT((int)sizeof(((struct mds_status_req *)0)->flags) == 4);
+        LASSERT(offsetof(struct mds_status_req, repbuf) == 4);
+        LASSERT((int)sizeof(((struct mds_status_req *)0)->repbuf) == 4);
+
+        /* Checks for struct mds_body */
+        LASSERT((int)sizeof(struct mds_body) == 136);
+        LASSERT(offsetof(struct mds_body, fid1) == 0);
+        LASSERT((int)sizeof(((struct mds_body *)0)->fid1) == 16);
+        LASSERT(offsetof(struct mds_body, fid2) == 16);
+        LASSERT((int)sizeof(((struct mds_body *)0)->fid2) == 16);
+        LASSERT(offsetof(struct mds_body, handle) == 32);
+        LASSERT((int)sizeof(((struct mds_body *)0)->handle) == 8);
+        LASSERT(offsetof(struct mds_body, size) == 40);
+        LASSERT((int)sizeof(((struct mds_body *)0)->size) == 8);
+        LASSERT(offsetof(struct mds_body, blocks) == 48);
+        LASSERT((int)sizeof(((struct mds_body *)0)->blocks) == 8);
+        LASSERT(offsetof(struct mds_body, io_epoch) == 56);
+        LASSERT((int)sizeof(((struct mds_body *)0)->io_epoch) == 8);
+        LASSERT(offsetof(struct mds_body, ino) == 64);
+        LASSERT((int)sizeof(((struct mds_body *)0)->ino) == 4);
+        LASSERT(offsetof(struct mds_body, valid) == 68);
+        LASSERT((int)sizeof(((struct mds_body *)0)->valid) == 4);
+        LASSERT(offsetof(struct mds_body, fsuid) == 72);
+        LASSERT((int)sizeof(((struct mds_body *)0)->fsuid) == 4);
+        LASSERT(offsetof(struct mds_body, fsgid) == 76);
+        LASSERT((int)sizeof(((struct mds_body *)0)->fsgid) == 4);
+        LASSERT(offsetof(struct mds_body, capability) == 80);
+        LASSERT((int)sizeof(((struct mds_body *)0)->capability) == 4);
+        LASSERT(offsetof(struct mds_body, mode) == 84);
+        LASSERT((int)sizeof(((struct mds_body *)0)->mode) == 4);
+        LASSERT(offsetof(struct mds_body, uid) == 88);
+        LASSERT((int)sizeof(((struct mds_body *)0)->uid) == 4);
+        LASSERT(offsetof(struct mds_body, gid) == 92);
+        LASSERT((int)sizeof(((struct mds_body *)0)->gid) == 4);
+        LASSERT(offsetof(struct mds_body, mtime) == 96);
+        LASSERT((int)sizeof(((struct mds_body *)0)->mtime) == 4);
+        LASSERT(offsetof(struct mds_body, ctime) == 100);
+        LASSERT((int)sizeof(((struct mds_body *)0)->ctime) == 4);
+        LASSERT(offsetof(struct mds_body, atime) == 104);
+        LASSERT((int)sizeof(((struct mds_body *)0)->atime) == 4);
+        LASSERT(offsetof(struct mds_body, flags) == 108);
+        LASSERT((int)sizeof(((struct mds_body *)0)->flags) == 4);
+        LASSERT(offsetof(struct mds_body, rdev) == 112);
+        LASSERT((int)sizeof(((struct mds_body *)0)->rdev) == 4);
+        LASSERT(offsetof(struct mds_body, nlink) == 116);
+        LASSERT((int)sizeof(((struct mds_body *)0)->nlink) == 4);
+        LASSERT(offsetof(struct mds_body, generation) == 120);
+        LASSERT((int)sizeof(((struct mds_body *)0)->generation) == 4);
+        LASSERT(offsetof(struct mds_body, suppgid) == 124);
+        LASSERT((int)sizeof(((struct mds_body *)0)->suppgid) == 4);
+        LASSERT(offsetof(struct mds_body, eadatasize) == 128);
+        LASSERT((int)sizeof(((struct mds_body *)0)->eadatasize) == 4);
+        LASSERT(FMODE_READ == 1);
+        LASSERT(FMODE_WRITE == 2);
+        LASSERT(FMODE_EXEC == 4);
+        LASSERT(MDS_OPEN_CREAT == 64);
+        LASSERT(MDS_OPEN_EXCL == 128);
+        LASSERT(MDS_OPEN_APPEND == 1024);
+        LASSERT(MDS_OPEN_SYNC == 4096);
+        LASSERT(MDS_OPEN_DIRECTORY == 65536);
+        LASSERT(MDS_OPEN_DELAY_CREATE == 16777216);
+        LASSERT(MDS_OPEN_HAS_EA == 1073741824);
+
+        /* Checks for struct mds_rec_setattr */
+        LASSERT((int)sizeof(struct mds_rec_setattr) == 88);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_opcode) == 0);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_opcode) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_fsuid) == 4);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_fsuid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_fsgid) == 8);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_fsgid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_cap) == 12);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_cap) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_suppgid) == 16);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_suppgid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_valid) == 20);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_valid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_fid) == 24);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_fid) == 16);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_mode) == 40);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_mode) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_uid) == 44);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_uid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_gid) == 48);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_gid) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_attr_flags) == 52);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_attr_flags) == 4);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_size) == 56);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_size) == 8);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_atime) == 64);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_atime) == 8);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_mtime) == 72);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_mtime) == 8);
+        LASSERT(offsetof(struct mds_rec_setattr, sa_ctime) == 80);
+        LASSERT((int)sizeof(((struct mds_rec_setattr *)0)->sa_ctime) == 8);
+
+        /* Checks for struct mds_rec_create */
+        LASSERT((int)sizeof(struct mds_rec_create) == 80);
+        LASSERT(offsetof(struct mds_rec_create, cr_opcode) == 0);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_opcode) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_fsuid) == 4);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_fsuid) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_fsgid) == 8);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_fsgid) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_cap) == 12);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_cap) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_flags) == 16);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_flags) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_mode) == 20);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_mode) == 4);
+        LASSERT(offsetof(struct mds_rec_create, cr_fid) == 24);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_fid) == 16);
+        LASSERT(offsetof(struct mds_rec_create, cr_replayfid) == 40);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_replayfid) == 16);
+        LASSERT(offsetof(struct mds_rec_create, cr_time) == 56);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_time) == 8);
+        LASSERT(offsetof(struct mds_rec_create, cr_rdev) == 64);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_rdev) == 8);
+        LASSERT(offsetof(struct mds_rec_create, cr_suppgid) == 72);
+        LASSERT((int)sizeof(((struct mds_rec_create *)0)->cr_suppgid) == 4);
+
+        /* Checks for struct mds_rec_link */
+        LASSERT((int)sizeof(struct mds_rec_link) == 64);
+        LASSERT(offsetof(struct mds_rec_link, lk_opcode) == 0);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_opcode) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_fsuid) == 4);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_fsuid) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_fsgid) == 8);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_fsgid) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_cap) == 12);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_cap) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_suppgid1) == 16);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_suppgid1) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_suppgid2) == 20);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_suppgid2) == 4);
+        LASSERT(offsetof(struct mds_rec_link, lk_fid1) == 24);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_fid1) == 16);
+        LASSERT(offsetof(struct mds_rec_link, lk_fid2) == 40);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_fid2) == 16);
+        LASSERT(offsetof(struct mds_rec_link, lk_time) == 56);
+        LASSERT((int)sizeof(((struct mds_rec_link *)0)->lk_time) == 8);
+
+        /* Checks for struct mds_rec_unlink */
+        LASSERT((int)sizeof(struct mds_rec_unlink) == 64);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_opcode) == 0);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_opcode) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_fsuid) == 4);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_fsuid) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_fsgid) == 8);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_fsgid) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_cap) == 12);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_cap) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_suppgid) == 16);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_suppgid) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_mode) == 20);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_mode) == 4);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_fid1) == 24);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_fid1) == 16);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_fid2) == 40);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_fid2) == 16);
+        LASSERT(offsetof(struct mds_rec_unlink, ul_time) == 56);
+        LASSERT((int)sizeof(((struct mds_rec_unlink *)0)->ul_time) == 8);
+
+        /* Checks for struct mds_rec_rename */
+        LASSERT((int)sizeof(struct mds_rec_rename) == 64);
+        LASSERT(offsetof(struct mds_rec_rename, rn_opcode) == 0);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_opcode) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_fsuid) == 4);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_fsuid) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_fsgid) == 8);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_fsgid) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_cap) == 12);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_cap) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_suppgid1) == 16);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_suppgid1) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_suppgid2) == 20);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_suppgid2) == 4);
+        LASSERT(offsetof(struct mds_rec_rename, rn_fid1) == 24);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_fid1) == 16);
+        LASSERT(offsetof(struct mds_rec_rename, rn_fid2) == 40);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_fid2) == 16);
+        LASSERT(offsetof(struct mds_rec_rename, rn_time) == 56);
+        LASSERT((int)sizeof(((struct mds_rec_rename *)0)->rn_time) == 8);
+
+        /* Checks for struct lov_desc */
+        LASSERT((int)sizeof(struct lov_desc) == 72);
+        LASSERT(offsetof(struct lov_desc, ld_tgt_count) == 0);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_tgt_count) == 4);
+        LASSERT(offsetof(struct lov_desc, ld_active_tgt_count) == 4);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_active_tgt_count) == 4);
+        LASSERT(offsetof(struct lov_desc, ld_default_stripe_count) == 8);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_default_stripe_count) == 4);
+        LASSERT(offsetof(struct lov_desc, ld_pattern) == 12);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_pattern) == 4);
+        LASSERT(offsetof(struct lov_desc, ld_default_stripe_size) == 16);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_default_stripe_size) == 8);
+        LASSERT(offsetof(struct lov_desc, ld_default_stripe_offset) == 24);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_default_stripe_offset) == 8);
+        LASSERT(offsetof(struct lov_desc, ld_uuid) == 32);
+        LASSERT((int)sizeof(((struct lov_desc *)0)->ld_uuid) == 40);
+
+        /* Checks for struct ldlm_res_id */
+        LASSERT((int)sizeof(struct ldlm_res_id) == 32);
+        LASSERT(offsetof(struct ldlm_res_id, name[4]) == 32);
+        LASSERT((int)sizeof(((struct ldlm_res_id *)0)->name[4]) == 8);
+
+        /* Checks for struct ldlm_extent */
+        LASSERT((int)sizeof(struct ldlm_extent) == 16);
+        LASSERT(offsetof(struct ldlm_extent, start) == 0);
+        LASSERT((int)sizeof(((struct ldlm_extent *)0)->start) == 8);
+        LASSERT(offsetof(struct ldlm_extent, end) == 8);
+        LASSERT((int)sizeof(((struct ldlm_extent *)0)->end) == 8);
+
+        /* Checks for struct ldlm_flock */
+        LASSERT((int)sizeof(struct ldlm_flock) == 32);
+        LASSERT(offsetof(struct ldlm_flock, start) == 0);
+        LASSERT((int)sizeof(((struct ldlm_flock *)0)->start) == 8);
+        LASSERT(offsetof(struct ldlm_flock, end) == 8);
+        LASSERT((int)sizeof(((struct ldlm_flock *)0)->end) == 8);
+        LASSERT(offsetof(struct ldlm_flock, blocking_export) == 16);
+        LASSERT((int)sizeof(((struct ldlm_flock *)0)->blocking_export) == 8);
+        LASSERT(offsetof(struct ldlm_flock, blocking_pid) == 24);
+        LASSERT((int)sizeof(((struct ldlm_flock *)0)->blocking_pid) == 4);
+        LASSERT(offsetof(struct ldlm_flock, pid) == 28);
+        LASSERT((int)sizeof(((struct ldlm_flock *)0)->pid) == 4);
+
+        /* Checks for struct ldlm_intent */
+        LASSERT((int)sizeof(struct ldlm_intent) == 8);
+        LASSERT(offsetof(struct ldlm_intent, opc) == 0);
+        LASSERT((int)sizeof(((struct ldlm_intent *)0)->opc) == 8);
+
+        /* Checks for struct ldlm_resource_desc */
+        LASSERT((int)sizeof(struct ldlm_resource_desc) == 52);
+        LASSERT(offsetof(struct ldlm_resource_desc, lr_type) == 0);
+        LASSERT((int)sizeof(((struct ldlm_resource_desc *)0)->lr_type) == 4);
+        LASSERT(offsetof(struct ldlm_resource_desc, lr_name) == 4);
+        LASSERT((int)sizeof(((struct ldlm_resource_desc *)0)->lr_name) == 32);
+        LASSERT(offsetof(struct ldlm_resource_desc, lr_version[4]) == 52);
+        LASSERT((int)sizeof(((struct ldlm_resource_desc *)0)->lr_version[4]) == 4);
+
+        /* Checks for struct ldlm_lock_desc */
+        LASSERT((int)sizeof(struct ldlm_lock_desc) == 108);
+        LASSERT(offsetof(struct ldlm_lock_desc, l_resource) == 0);
+        LASSERT((int)sizeof(((struct ldlm_lock_desc *)0)->l_resource) == 52);
+        LASSERT(offsetof(struct ldlm_lock_desc, l_req_mode) == 52);
+        LASSERT((int)sizeof(((struct ldlm_lock_desc *)0)->l_req_mode) == 4);
+        LASSERT(offsetof(struct ldlm_lock_desc, l_granted_mode) == 56);
+        LASSERT((int)sizeof(((struct ldlm_lock_desc *)0)->l_granted_mode) == 4);
+        LASSERT(offsetof(struct ldlm_lock_desc, l_policy_data) == 60);
+        LASSERT((int)sizeof(((struct ldlm_lock_desc *)0)->l_policy_data) == 32);
+        LASSERT(offsetof(struct ldlm_lock_desc, l_version[4]) == 108);
+        LASSERT((int)sizeof(((struct ldlm_lock_desc *)0)->l_version[4]) == 4);
+
+        /* Checks for struct ldlm_request */
+        LASSERT((int)sizeof(struct ldlm_request) == 128);
+        LASSERT(offsetof(struct ldlm_request, lock_flags) == 0);
+        LASSERT((int)sizeof(((struct ldlm_request *)0)->lock_flags) == 4);
+        LASSERT(offsetof(struct ldlm_request, lock_desc) == 4);
+        LASSERT((int)sizeof(((struct ldlm_request *)0)->lock_desc) == 108);
+        LASSERT(offsetof(struct ldlm_request, lock_handle1) == 112);
+        LASSERT((int)sizeof(((struct ldlm_request *)0)->lock_handle1) == 8);
+        LASSERT(offsetof(struct ldlm_request, lock_handle2) == 120);
+        LASSERT((int)sizeof(((struct ldlm_request *)0)->lock_handle2) == 8);
+
+        /* Checks for struct ldlm_reply */
+        LASSERT((int)sizeof(struct ldlm_reply) == 96);
+        LASSERT(offsetof(struct ldlm_reply, lock_flags) == 0);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_flags) == 4);
+        LASSERT(offsetof(struct ldlm_reply, lock_mode) == 4);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_mode) == 4);
+        LASSERT(offsetof(struct ldlm_reply, lock_resource_name) == 8);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_resource_name) == 32);
+        LASSERT(offsetof(struct ldlm_reply, lock_handle) == 40);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_handle) == 8);
+        LASSERT(offsetof(struct ldlm_reply, lock_policy_data) == 48);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_policy_data) == 32);
+        LASSERT(offsetof(struct ldlm_reply, lock_policy_res1) == 80);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_policy_res1) == 8);
+        LASSERT(offsetof(struct ldlm_reply, lock_policy_res2) == 88);
+        LASSERT((int)sizeof(((struct ldlm_reply *)0)->lock_policy_res2) == 8);
+
+        /* Checks for struct ptlbd_op */
+        LASSERT((int)sizeof(struct ptlbd_op) == 12);
+        LASSERT(offsetof(struct ptlbd_op, op_cmd) == 0);
+        LASSERT((int)sizeof(((struct ptlbd_op *)0)->op_cmd) == 2);
+        LASSERT(offsetof(struct ptlbd_op, op_lun) == 2);
+        LASSERT((int)sizeof(((struct ptlbd_op *)0)->op_lun) == 2);
+        LASSERT(offsetof(struct ptlbd_op, op_niob_cnt) == 4);
+        LASSERT((int)sizeof(((struct ptlbd_op *)0)->op_niob_cnt) == 2);
+        LASSERT(offsetof(struct ptlbd_op, op__padding) == 6);
+        LASSERT((int)sizeof(((struct ptlbd_op *)0)->op__padding) == 2);
+        LASSERT(offsetof(struct ptlbd_op, op_block_cnt) == 8);
+        LASSERT((int)sizeof(((struct ptlbd_op *)0)->op_block_cnt) == 4);
+
+        /* Checks for struct ptlbd_niob */
+        LASSERT((int)sizeof(struct ptlbd_niob) == 24);
+        LASSERT(offsetof(struct ptlbd_niob, n_xid) == 0);
+        LASSERT((int)sizeof(((struct ptlbd_niob *)0)->n_xid) == 8);
+        LASSERT(offsetof(struct ptlbd_niob, n_block_nr) == 8);
+        LASSERT((int)sizeof(((struct ptlbd_niob *)0)->n_block_nr) == 8);
+        LASSERT(offsetof(struct ptlbd_niob, n_offset) == 16);
+        LASSERT((int)sizeof(((struct ptlbd_niob *)0)->n_offset) == 4);
+        LASSERT(offsetof(struct ptlbd_niob, n_length) == 20);
+        LASSERT((int)sizeof(((struct ptlbd_niob *)0)->n_length) == 4);
+
+        /* Checks for struct ptlbd_rsp */
+        LASSERT((int)sizeof(struct ptlbd_rsp) == 4);
+        LASSERT(offsetof(struct ptlbd_rsp, r_status) == 0);
+        LASSERT((int)sizeof(((struct ptlbd_rsp *)0)->r_status) == 2);
+        LASSERT(offsetof(struct ptlbd_rsp, r_error_cnt) == 2);
+        LASSERT((int)sizeof(((struct ptlbd_rsp *)0)->r_error_cnt) == 2);
+
+        /* Checks for struct llog_logid */
+        LASSERT((int)sizeof(struct llog_logid) == 20);
+        LASSERT(offsetof(struct llog_logid, lgl_oid) == 0);
+        LASSERT((int)sizeof(((struct llog_logid *)0)->lgl_oid) == 8);
+        LASSERT(offsetof(struct llog_logid, lgl_ogr) == 8);
+        LASSERT((int)sizeof(((struct llog_logid *)0)->lgl_ogr) == 8);
+        LASSERT(offsetof(struct llog_logid, lgl_ogen) == 16);
+        LASSERT((int)sizeof(((struct llog_logid *)0)->lgl_ogen) == 4);
+        LASSERT(OST_SZ_REC == 274730752);
+        LASSERT(OST_RAID1_REC == 274731008);
+        LASSERT(MDS_UNLINK_REC == 274801668);
+        LASSERT(OBD_CFG_REC == 274857984);
+        LASSERT(PTL_CFG_REC == 274923520);
+        LASSERT(LLOG_HDR_MAGIC == 275010873);
+        LASSERT(LLOG_LOGID_MAGIC == 275010874);
+
+        /* Checks for struct llog_rec_hdr */
+        LASSERT((int)sizeof(struct llog_rec_hdr) == 16);
+        LASSERT(offsetof(struct llog_rec_hdr, lrh_len) == 0);
+        LASSERT((int)sizeof(((struct llog_rec_hdr *)0)->lrh_len) == 4);
+        LASSERT(offsetof(struct llog_rec_hdr, lrh_index) == 4);
+        LASSERT((int)sizeof(((struct llog_rec_hdr *)0)->lrh_index) == 4);
+        LASSERT(offsetof(struct llog_rec_hdr, lrh_type) == 8);
+        LASSERT((int)sizeof(((struct llog_rec_hdr *)0)->lrh_type) == 4);
+
+        /* Checks for struct llog_rec_tail */
+        LASSERT((int)sizeof(struct llog_rec_tail) == 8);
+        LASSERT(offsetof(struct llog_rec_tail, lrt_len) == 0);
+        LASSERT((int)sizeof(((struct llog_rec_tail *)0)->lrt_len) == 4);
+        LASSERT(offsetof(struct llog_rec_tail, lrt_index) == 4);
+        LASSERT((int)sizeof(((struct llog_rec_tail *)0)->lrt_index) == 4);
+
+        /* Checks for struct llog_log_hdr */
+        LASSERT((int)sizeof(struct llog_log_hdr) == 4096);
+        LASSERT(offsetof(struct llog_log_hdr, llh_hdr) == 0);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_hdr) == 16);
+        LASSERT(offsetof(struct llog_log_hdr, llh_timestamp) == 16);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_timestamp) == 8);
+        LASSERT(offsetof(struct llog_log_hdr, llh_count) == 24);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_count) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_bitmap_offset) == 28);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_bitmap_offset) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_size) == 32);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_size) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_flags) == 36);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_flags) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_cat_idx) == 40);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_cat_idx) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_tgtuuid) == 44);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_tgtuuid) == 40);
+        LASSERT(offsetof(struct llog_log_hdr, llh_reserved) == 84);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_reserved) == 4);
+        LASSERT(offsetof(struct llog_log_hdr, llh_bitmap) == 88);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_bitmap) == 4000);
+        LASSERT(offsetof(struct llog_log_hdr, llh_tail) == 4088);
+        LASSERT((int)sizeof(((struct llog_log_hdr *)0)->llh_tail) == 8);
+
+        /* Checks for struct llog_cookie */
+        LASSERT((int)sizeof(struct llog_cookie) == 32);
+        LASSERT(offsetof(struct llog_cookie, lgc_lgl) == 0);
+        LASSERT((int)sizeof(((struct llog_cookie *)0)->lgc_lgl) == 20);
+        LASSERT(offsetof(struct llog_cookie, lgc_subsys) == 20);
+        LASSERT((int)sizeof(((struct llog_cookie *)0)->lgc_subsys) == 4);
+        LASSERT(offsetof(struct llog_cookie, lgc_index) == 24);
+        LASSERT((int)sizeof(((struct llog_cookie *)0)->lgc_index) == 4);
+
+        /* Checks for struct llogd_body */
+        LASSERT((int)sizeof(struct llogd_body) == 48);
+        LASSERT(offsetof(struct llogd_body, lgd_logid) == 0);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_logid) == 20);
+        LASSERT(offsetof(struct llogd_body, lgd_ctxt_idx) == 20);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_ctxt_idx) == 4);
+        LASSERT(offsetof(struct llogd_body, lgd_llh_flags) == 24);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_llh_flags) == 4);
+        LASSERT(offsetof(struct llogd_body, lgd_index) == 28);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_index) == 4);
+        LASSERT(offsetof(struct llogd_body, lgd_saved_index) == 32);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_saved_index) == 4);
+        LASSERT(offsetof(struct llogd_body, lgd_len) == 36);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_len) == 4);
+        LASSERT(offsetof(struct llogd_body, lgd_cur_offset) == 40);
+        LASSERT((int)sizeof(((struct llogd_body *)0)->lgd_cur_offset) == 8);
+        LASSERT(LLOG_ORIGIN_HANDLE_CREATE == 501);
+        LASSERT(LLOG_ORIGIN_HANDLE_NEXT_BLOCK == 502);
+        LASSERT(LLOG_ORIGIN_HANDLE_READ_HEADER == 503);
+        LASSERT(LLOG_ORIGIN_HANDLE_WRITE_REC == 504);
+        LASSERT(LLOG_ORIGIN_HANDLE_CLOSE == 505);
+
+        /* Checks for struct llogd_conn_body */
+        LASSERT((int)sizeof(struct llogd_conn_body) == 40);
+        LASSERT(offsetof(struct llogd_conn_body, lgdc_gen) == 0);
+        LASSERT((int)sizeof(((struct llogd_conn_body *)0)->lgdc_gen) == 16);
+        LASSERT(offsetof(struct llogd_conn_body, lgdc_logid) == 16);
+        LASSERT((int)sizeof(((struct llogd_conn_body *)0)->lgdc_logid) == 20);
+        LASSERT(offsetof(struct llogd_conn_body, lgdc_ctxt_idx) == 36);
+        LASSERT((int)sizeof(((struct llogd_conn_body *)0)->lgdc_ctxt_idx) == 4);
+}
+